From fab7311f18c49be82e8e1681c8966e576525d3ed Mon Sep 17 00:00:00 2001 From: Palmer Dabbelt Date: Thu, 6 Apr 2017 15:24:17 -0700 Subject: [PATCH] archive branch --- .gitignore | 101 - .gitmodules | 9 - AUTHORS | 12 - AUTHORS.ChangeLog | 10 - BUGS | 74 - COPYING | 339 - ChangeLog | 1 - Doxyfile.in | 1517 - HACKING | 185 - Makefile.am | 112 - NEWS | 33 - NEWS-0.2.0 | 80 - NEWS-0.3.0 | 82 - NEWS-0.4.0 | 98 - NEWS-0.5.0 | 74 - NEWS-0.6.0 | 54 - NEWS-0.7.0 | 43 - NEWS-0.8.0 | 111 - NEWS-0.9.0 | 110 - NEWTAPS | 145 - README | 372 - README.OSX | 49 - README.Windows | 60 - TODO | 380 - bootstrap | 43 - common.mk | 12 - config_subdir.m4 | 26 - configure.ac | 1343 - contrib/99-openocd.rules | 134 - contrib/coresight-trace.txt | 68 - contrib/cross-build.sh | 119 - contrib/gen-stellaris-part-header.pl | 124 - contrib/itmdump.c | 459 - contrib/libdcc/README | 19 - contrib/libdcc/dcc_stdio.c | 157 - contrib/libdcc/dcc_stdio.h | 35 - contrib/libdcc/example.c | 58 - contrib/loaders/Makefile | 33 - contrib/loaders/README | 33 - contrib/loaders/checksum/Makefile | 30 - contrib/loaders/checksum/armv4_5_crc.inc | 7 - contrib/loaders/checksum/armv4_5_crc.s | 58 - contrib/loaders/checksum/armv7m_crc.inc | 5 - contrib/loaders/checksum/armv7m_crc.s | 71 - contrib/loaders/checksum/mips32.s | 72 - contrib/loaders/erase_check/Makefile | 30 - .../erase_check/armv4_5_erase_check.inc | 3 - .../loaders/erase_check/armv4_5_erase_check.s | 39 - .../erase_check/armv7m_0_erase_check.inc | 2 - .../erase_check/armv7m_0_erase_check.s | 45 - .../erase_check/armv7m_erase_check.inc | 2 - .../loaders/erase_check/armv7m_erase_check.s | 45 - contrib/loaders/flash/armv4_5_cfi_intel_16.s | 57 - contrib/loaders/flash/armv4_5_cfi_intel_32.s | 57 - contrib/loaders/flash/armv4_5_cfi_intel_8.s | 57 - contrib/loaders/flash/armv4_5_cfi_span_16.s | 75 - .../loaders/flash/armv4_5_cfi_span_16_dq7.s | 66 - contrib/loaders/flash/armv4_5_cfi_span_32.s | 75 - contrib/loaders/flash/armv4_5_cfi_span_8.s | 75 - contrib/loaders/flash/armv7m_cfi_span_16.s | 81 - .../loaders/flash/armv7m_cfi_span_16_dq7.s | 72 - contrib/loaders/flash/armv7m_io.s | 60 - .../at91sam7x/at91sam7x_ocl_flash.script | 4 - .../loaders/flash/at91sam7x/at91sam7x_ram.ld | 132 - contrib/loaders/flash/at91sam7x/crt.s | 223 - contrib/loaders/flash/at91sam7x/dcc.c | 51 - contrib/loaders/flash/at91sam7x/dcc.h | 31 - contrib/loaders/flash/at91sam7x/main.c | 107 - contrib/loaders/flash/at91sam7x/makefile | 130 - contrib/loaders/flash/at91sam7x/ocl.h | 40 - contrib/loaders/flash/at91sam7x/platform.h | 46 - contrib/loaders/flash/at91sam7x/samflash.c | 196 - contrib/loaders/flash/at91sam7x/samflash.h | 48 - contrib/loaders/flash/at91sam7x/samregs.h | 83 - contrib/loaders/flash/cortex-m0.S | 72 - contrib/loaders/flash/efm32.S | 114 - contrib/loaders/flash/fm4/Makefile | 32 - contrib/loaders/flash/fm4/erase.S | 77 - contrib/loaders/flash/fm4/erase.inc | 7 - contrib/loaders/flash/fm4/fm4.h | 19 - contrib/loaders/flash/fm4/write.S | 85 - contrib/loaders/flash/fm4/write.inc | 7 - .../loaders/flash/fpga/xilinx_bscan_spi.py | 317 - contrib/loaders/flash/k1921vk01t.S | 112 - contrib/loaders/flash/kinetis_ke/Makefile | 21 - .../flash/kinetis_ke/kinetis_ke_flash.inc | 15 - .../flash/kinetis_ke/kinetis_ke_flash.s | 184 - .../flash/kinetis_ke/kinetis_ke_watchdog.inc | 4 - .../flash/kinetis_ke/kinetis_ke_watchdog.s | 47 - contrib/loaders/flash/lpcspifi_erase.S | 176 - contrib/loaders/flash/lpcspifi_init.S | 102 - contrib/loaders/flash/lpcspifi_write.S | 222 - contrib/loaders/flash/mdr32fx.S | 125 - contrib/loaders/flash/mrvlqspi_write.S | 232 - contrib/loaders/flash/pic32mx.s | 132 - contrib/loaders/flash/sim3x.s | 81 - contrib/loaders/flash/stellaris.s | 78 - contrib/loaders/flash/stm32f1x.S | 76 - contrib/loaders/flash/stm32f2x.S | 81 - contrib/loaders/flash/stm32l4x.S | 100 - contrib/loaders/flash/stm32lx.S | 63 - contrib/loaders/flash/str7x.s | 59 - contrib/loaders/flash/str9x.s | 56 - contrib/loaders/flash/xmc1xxx/Makefile | 32 - contrib/loaders/flash/xmc1xxx/erase.S | 53 - contrib/loaders/flash/xmc1xxx/erase.inc | 4 - contrib/loaders/flash/xmc1xxx/erase_check.S | 67 - contrib/loaders/flash/xmc1xxx/erase_check.inc | 5 - contrib/loaders/flash/xmc1xxx/write.S | 58 - contrib/loaders/flash/xmc1xxx/write.inc | 4 - contrib/loaders/flash/xmc1xxx/xmc1xxx.S | 46 - contrib/loaders/watchdog/Makefile | 21 - .../loaders/watchdog/armv7m_kinetis_wdog.inc | 4 - .../loaders/watchdog/armv7m_kinetis_wdog.s | 64 - .../remote_bitbang/remote_bitbang_sysfsgpio.c | 408 - contrib/rpc_examples/ocd_rpc_example.py | 145 - contrib/rpc_examples/ocdrpc.hs | 56 - contrib/rtos-helpers/FreeRTOS-openocd.c | 20 - contrib/xsvf_tools/svf2xsvf.py | 729 - contrib/xsvf_tools/xsvfdump.py | 268 - doc/INSTALL.txt | 204 - doc/Makefile.am | 13 - doc/fdl.texi | 452 - doc/manual/app.txt | 9 - doc/manual/flash.txt | 35 - doc/manual/helper.txt | 136 - .../images/jtag-state-machine-large.png | Bin 11416 -> 0 bytes doc/manual/jtag.txt | 73 - doc/manual/jtag/drivers/remote_bitbang.txt | 53 - doc/manual/main.txt | 105 - doc/manual/primer/autotools.txt | 147 - doc/manual/primer/commands.txt | 138 - doc/manual/primer/docs.txt | 124 - doc/manual/primer/jtag.txt | 169 - doc/manual/primer/tcl.txt | 440 - doc/manual/release.txt | 465 - doc/manual/scripting.txt | 80 - doc/manual/server.txt | 316 - doc/manual/style.txt | 422 - doc/manual/target.txt | 46 - doc/manual/target/mips.txt | 536 - doc/manual/target/notarm.txt | 71 - doc/openocd.1 | 103 - doc/openocd.texi | 9812 ------ guess-rev.sh | 83 - jimtcl | 1 - src/Makefile.am | 116 - src/flash/Makefile.am | 23 - src/flash/common.c | 47 - src/flash/common.h | 48 - src/flash/mflash.c | 1449 - src/flash/mflash.h | 289 - src/flash/nand/Makefile.am | 46 - src/flash/nand/arm_io.c | 299 - src/flash/nand/arm_io.h | 55 - src/flash/nand/at91sam9.c | 722 - src/flash/nand/core.c | 876 - src/flash/nand/core.h | 232 - src/flash/nand/davinci.c | 793 - src/flash/nand/driver.c | 82 - src/flash/nand/driver.h | 103 - src/flash/nand/ecc.c | 182 - src/flash/nand/ecc_kw.c | 174 - src/flash/nand/fileio.c | 226 - src/flash/nand/fileio.h | 56 - src/flash/nand/imp.h | 38 - src/flash/nand/lpc3180.c | 1359 - src/flash/nand/lpc3180.h | 37 - src/flash/nand/lpc32xx.c | 1821 -- src/flash/nand/lpc32xx.h | 36 - src/flash/nand/mx3.c | 719 - src/flash/nand/mx3.h | 112 - src/flash/nand/mxc.c | 960 - src/flash/nand/mxc.h | 168 - src/flash/nand/nonce.c | 73 - src/flash/nand/nuc910.c | 227 - src/flash/nand/nuc910.h | 57 - src/flash/nand/orion.c | 161 - src/flash/nand/s3c2410.c | 116 - src/flash/nand/s3c2412.c | 75 - src/flash/nand/s3c2440.c | 166 - src/flash/nand/s3c2443.c | 75 - src/flash/nand/s3c24xx.c | 117 - src/flash/nand/s3c24xx.h | 78 - src/flash/nand/s3c24xx_regs.h | 129 - src/flash/nand/s3c6400.c | 72 - src/flash/nand/tcl.c | 626 - src/flash/nor/Makefile.am | 70 - src/flash/nor/aduc702x.c | 404 - src/flash/nor/aducm360.c | 582 - src/flash/nor/ambiqmicro.c | 904 - src/flash/nor/at91sam3.c | 3774 --- src/flash/nor/at91sam4.c | 2678 -- src/flash/nor/at91sam4l.c | 707 - src/flash/nor/at91sam7.c | 1203 - src/flash/nor/at91samd.c | 1124 - src/flash/nor/atsamv.c | 739 - src/flash/nor/avrf.c | 489 - src/flash/nor/cfi.c | 3131 -- src/flash/nor/cfi.h | 163 - src/flash/nor/core.c | 797 - src/flash/nor/core.h | 232 - src/flash/nor/driver.h | 224 - src/flash/nor/drivers.c | 133 - src/flash/nor/dsp5680xx_flash.c | 270 - src/flash/nor/efm32.c | 1069 - src/flash/nor/em357.c | 939 - src/flash/nor/faux.c | 140 - src/flash/nor/fespi.c | 1127 - src/flash/nor/fm3.c | 1000 - src/flash/nor/fm4.c | 722 - src/flash/nor/imp.h | 49 - src/flash/nor/jtagspi.c | 413 - src/flash/nor/kinetis.c | 2423 -- src/flash/nor/kinetis_ke.c | 1314 - src/flash/nor/lpc2000.c | 1573 - src/flash/nor/lpc288x.c | 436 - src/flash/nor/lpc2900.c | 1601 - src/flash/nor/lpcspifi.c | 945 - src/flash/nor/mdr.c | 635 - src/flash/nor/mrvlqspi.c | 958 - src/flash/nor/niietcm4.c | 1744 -- src/flash/nor/non_cfi.c | 560 - src/flash/nor/non_cfi.h | 36 - src/flash/nor/nrf51.c | 1334 - src/flash/nor/numicro.c | 1883 -- src/flash/nor/ocl.c | 343 - src/flash/nor/ocl.h | 39 - src/flash/nor/pic32mx.c | 984 - src/flash/nor/psoc4.c | 812 - src/flash/nor/sim3x.c | 1126 - src/flash/nor/spi.c | 83 - src/flash/nor/spi.h | 61 - src/flash/nor/stellaris.c | 1455 - src/flash/nor/stm32f1x.c | 1650 -- src/flash/nor/stm32f2x.c | 1463 - src/flash/nor/stm32l4x.c | 930 - src/flash/nor/stm32lx.c | 1421 - src/flash/nor/stmsmi.c | 657 - src/flash/nor/str7x.c | 815 - src/flash/nor/str9x.c | 682 - src/flash/nor/str9xpec.c | 1210 - src/flash/nor/tcl.c | 1146 - src/flash/nor/tms470.c | 1189 - src/flash/nor/virtual.c | 233 - src/flash/nor/xmc1xxx.c | 549 - src/flash/nor/xmc4xxx.c | 1444 - src/flash/startup.tcl | 110 - src/hello.c | 112 - src/hello.h | 29 - src/helper/Makefile.am | 56 - src/helper/bin2char.sh | 14 - src/helper/binarybuffer.c | 418 - src/helper/binarybuffer.h | 241 - src/helper/command.c | 1466 - src/helper/command.h | 418 - src/helper/configuration.c | 170 - src/helper/configuration.h | 43 - src/helper/fileio.c | 269 - src/helper/fileio.h | 69 - src/helper/ioutil.c | 534 - src/helper/ioutil.h | 25 - src/helper/ioutil_stubs.c | 28 - src/helper/jep106.c | 44 - src/helper/jep106.h | 32 - src/helper/jep106.inc | 1119 - src/helper/jim-nvp.c | 341 - src/helper/jim-nvp.h | 329 - src/helper/list.h | 737 - src/helper/log.c | 467 - src/helper/log.h | 142 - src/helper/options.c | 230 - src/helper/replacements.c | 318 - src/helper/replacements.h | 283 - src/helper/startup.tcl | 66 - src/helper/system.h | 89 - src/helper/time_support.c | 89 - src/helper/time_support.h | 60 - src/helper/time_support_common.c | 41 - src/helper/types.h | 340 - src/helper/update_jep106.pl | 35 - src/helper/util.c | 59 - src/helper/util.h | 25 - src/jtag/Makefile.am | 86 - src/jtag/adapter.c | 535 - src/jtag/aice/Makefile.am | 27 - src/jtag/aice/aice_interface.c | 507 - src/jtag/aice/aice_interface.h | 35 - src/jtag/aice/aice_pipe.c | 893 - src/jtag/aice/aice_pipe.h | 31 - src/jtag/aice/aice_port.c | 45 - src/jtag/aice/aice_port.h | 237 - src/jtag/aice/aice_transport.c | 385 - src/jtag/aice/aice_transport.h | 24 - src/jtag/aice/aice_usb.c | 4123 --- src/jtag/aice/aice_usb.h | 132 - src/jtag/commands.c | 253 - src/jtag/commands.h | 176 - src/jtag/core.c | 1966 -- src/jtag/driver.h | 26 - src/jtag/drivers/Makefile.am | 173 - src/jtag/drivers/Makefile.rlink | 71 - src/jtag/drivers/OpenULINK/Makefile | 87 - src/jtag/drivers/OpenULINK/README | 34 - src/jtag/drivers/OpenULINK/include/common.h | 24 - src/jtag/drivers/OpenULINK/include/delay.h | 32 - src/jtag/drivers/OpenULINK/include/io.h | 122 - src/jtag/drivers/OpenULINK/include/jtag.h | 46 - src/jtag/drivers/OpenULINK/include/main.h | 24 - src/jtag/drivers/OpenULINK/include/msgtypes.h | 189 - src/jtag/drivers/OpenULINK/include/protocol.h | 30 - .../drivers/OpenULINK/include/reg_ezusb.h | 741 - src/jtag/drivers/OpenULINK/include/usb.h | 265 - src/jtag/drivers/OpenULINK/src/USBJmpTb.a51 | 81 - src/jtag/drivers/OpenULINK/src/delay.c | 49 - src/jtag/drivers/OpenULINK/src/jtag.c | 721 - src/jtag/drivers/OpenULINK/src/main.c | 89 - src/jtag/drivers/OpenULINK/src/protocol.c | 238 - src/jtag/drivers/OpenULINK/src/usb.c | 562 - src/jtag/drivers/OpenULINK/ulink_firmware.hex | 347 - src/jtag/drivers/amt_jtagaccel.c | 605 - src/jtag/drivers/arm-jtag-ew.c | 793 - src/jtag/drivers/at91rm9200.c | 266 - src/jtag/drivers/bcm2835gpio.c | 531 - src/jtag/drivers/bitbang.c | 548 - src/jtag/drivers/bitbang.h | 48 - src/jtag/drivers/bitq.c | 315 - src/jtag/drivers/bitq.h | 45 - src/jtag/drivers/buspirate.c | 1126 - src/jtag/drivers/cmsis_dap_usb.c | 1630 - src/jtag/drivers/driver.c | 421 - src/jtag/drivers/dummy.c | 160 - src/jtag/drivers/ep93xx.c | 212 - src/jtag/drivers/ft2232.c | 4308 --- src/jtag/drivers/ftd2xx_common.h | 55 - src/jtag/drivers/ftdi.c | 1297 - src/jtag/drivers/gw16012.c | 543 - src/jtag/drivers/jlink.c | 1979 -- src/jtag/drivers/jtag_vpi.c | 466 - src/jtag/drivers/libjaylink | 1 - src/jtag/drivers/libusb0_common.c | 188 - src/jtag/drivers/libusb0_common.h | 73 - src/jtag/drivers/libusb1_common.c | 248 - src/jtag/drivers/libusb1_common.h | 80 - src/jtag/drivers/libusb_common.h | 27 - src/jtag/drivers/minidriver_imp.h | 41 - src/jtag/drivers/mpsse.c | 930 - src/jtag/drivers/mpsse.h | 78 - src/jtag/drivers/opendous.c | 825 - src/jtag/drivers/openjtag.c | 843 - src/jtag/drivers/osbdm.c | 699 - src/jtag/drivers/parport.c | 518 - src/jtag/drivers/presto.c | 794 - src/jtag/drivers/remote_bitbang.c | 280 - src/jtag/drivers/rlink.c | 1683 -- src/jtag/drivers/rlink.h | 32 - src/jtag/drivers/rlink_call.m4 | 483 - src/jtag/drivers/rlink_dtc_cmd.h | 76 - src/jtag/drivers/rlink_ep1_cmd.h | 60 - src/jtag/drivers/rlink_init.m4 | 72 - src/jtag/drivers/rlink_speed_table.c | 101 - src/jtag/drivers/rlink_st7.h | 117 - src/jtag/drivers/stlink_usb.c | 1890 -- src/jtag/drivers/sysfsgpio.c | 681 - src/jtag/drivers/ti_icdi_usb.c | 782 - src/jtag/drivers/ulink.c | 2316 -- src/jtag/drivers/usb_blaster/Makefile.am | 24 - .../drivers/usb_blaster/README.CheapClone | 71 - .../usb_blaster/ublast2_access_libusb.c | 253 - src/jtag/drivers/usb_blaster/ublast_access.h | 74 - .../usb_blaster/ublast_access_ftd2xx.c | 180 - .../drivers/usb_blaster/ublast_access_ftdi.c | 138 - src/jtag/drivers/usb_blaster/usb_blaster.c | 1079 - src/jtag/drivers/usb_common.c | 54 - src/jtag/drivers/usb_common.h | 26 - src/jtag/drivers/usbprog.c | 619 - .../drivers/versaloon/usbtoxxx/usbtogpio.c | 95 - .../drivers/versaloon/usbtoxxx/usbtojtagraw.c | 78 - .../drivers/versaloon/usbtoxxx/usbtopwr.c | 63 - .../drivers/versaloon/usbtoxxx/usbtoswd.c | 156 - .../drivers/versaloon/usbtoxxx/usbtoxxx.c | 553 - .../drivers/versaloon/usbtoxxx/usbtoxxx.h | 237 - .../versaloon/usbtoxxx/usbtoxxx_internal.h | 161 - src/jtag/drivers/versaloon/versaloon.c | 359 - src/jtag/drivers/versaloon/versaloon.h | 112 - .../drivers/versaloon/versaloon_include.h | 102 - .../drivers/versaloon/versaloon_internal.h | 110 - src/jtag/drivers/vsllink.c | 975 - src/jtag/hla/Makefile.am | 23 - src/jtag/hla/hla_interface.c | 347 - src/jtag/hla/hla_interface.h | 68 - src/jtag/hla/hla_layout.c | 90 - src/jtag/hla/hla_layout.h | 128 - src/jtag/hla/hla_tcl.c | 157 - src/jtag/hla/hla_tcl.h | 28 - src/jtag/hla/hla_transport.c | 235 - src/jtag/hla/hla_transport.h | 32 - src/jtag/interface.c | 468 - src/jtag/interface.h | 335 - src/jtag/interfaces.c | 238 - src/jtag/interfaces.h | 44 - src/jtag/jtag.h | 649 - src/jtag/minidriver.h | 90 - src/jtag/minidriver/minidriver_imp.h | 30 - src/jtag/minidummy/jtag_minidriver.h | 21 - src/jtag/minidummy/minidummy.c | 169 - src/jtag/startup.tcl | 163 - src/jtag/swd.h | 216 - src/jtag/tcl.c | 1387 - src/jtag/tcl.h | 37 - src/jtag/zy1000/jtag_minidriver.h | 182 - src/jtag/zy1000/zy1000.c | 1252 - src/main.c | 40 - src/openocd.c | 351 - src/openocd.h | 32 - src/pld/Makefile.am | 8 - src/pld/pld.c | 239 - src/pld/pld.h | 52 - src/pld/virtex2.c | 250 - src/pld/virtex2.h | 29 - src/pld/xilinx_bit.c | 128 - src/pld/xilinx_bit.h | 34 - src/rtos/ChibiOS.c | 547 - src/rtos/FreeRTOS.c | 555 - src/rtos/Makefile.am | 32 - src/rtos/ThreadX.c | 617 - src/rtos/eCos.c | 392 - src/rtos/embKernel.c | 342 - src/rtos/linux.c | 1594 - src/rtos/linux_header.h | 37 - src/rtos/mqx.c | 561 - src/rtos/riscv_debug.c | 280 - src/rtos/riscv_debug.h | 9 - src/rtos/rtos.c | 549 - src/rtos/rtos.h | 111 - src/rtos/rtos_chibios_stackings.c | 83 - src/rtos/rtos_chibios_stackings.h | 31 - src/rtos/rtos_ecos_stackings.c | 51 - src/rtos/rtos_ecos_stackings.h | 28 - src/rtos/rtos_embkernel_stackings.c | 55 - src/rtos/rtos_embkernel_stackings.h | 30 - src/rtos/rtos_mqx_stackings.c | 80 - src/rtos/rtos_mqx_stackings.h | 30 - src/rtos/rtos_standard_stackings.c | 270 - src/rtos/rtos_standard_stackings.h | 40 - src/server/Makefile.am | 23 - src/server/gdb_server.c | 3197 -- src/server/gdb_server.h | 51 - src/server/server.c | 751 - src/server/server.h | 112 - src/server/server_stubs.c | 30 - src/server/startup.tcl | 10 - src/server/tcl_server.c | 361 - src/server/tcl_server.h | 26 - src/server/telnet_server.c | 682 - src/server/telnet_server.h | 70 - src/svf/Makefile.am | 8 - src/svf/svf.c | 1578 - src/svf/svf.h | 47 - src/target/Makefile.am | 219 - src/target/adi_v5_jtag.c | 756 - src/target/adi_v5_swd.c | 451 - src/target/algorithm.c | 52 - src/target/algorithm.h | 50 - src/target/arm.h | 243 - src/target/arm11.c | 1382 - src/target/arm11.h | 114 - src/target/arm11_dbgtap.c | 1195 - src/target/arm11_dbgtap.h | 83 - src/target/arm720t.c | 587 - src/target/arm720t.h | 41 - src/target/arm7_9_common.c | 2903 -- src/target/arm7_9_common.h | 195 - src/target/arm7tdmi.c | 721 - src/target/arm7tdmi.h | 32 - src/target/arm920t.c | 1720 -- src/target/arm920t.h | 71 - src/target/arm926ejs.c | 832 - src/target/arm926ejs.h | 55 - src/target/arm946e.c | 784 - src/target/arm946e.h | 51 - src/target/arm966e.c | 282 - src/target/arm966e.h | 48 - src/target/arm9tdmi.c | 923 - src/target/arm9tdmi.h | 56 - src/target/arm_adi_v5.c | 1700 -- src/target/arm_adi_v5.h | 507 - src/target/arm_disassembler.c | 4465 --- src/target/arm_disassembler.h | 204 - src/target/arm_dpm.c | 1042 - src/target/arm_dpm.h | 201 - src/target/arm_jtag.c | 94 - src/target/arm_jtag.h | 78 - src/target/arm_opcodes.h | 313 - src/target/arm_semihosting.c | 556 - src/target/arm_semihosting.h | 24 - src/target/arm_simulator.c | 722 - src/target/arm_simulator.h | 39 - src/target/armv4_5.c | 1612 - src/target/armv4_5.h | 49 - src/target/armv4_5_cache.c | 102 - src/target/armv4_5_cache.h | 55 - src/target/armv4_5_mmu.c | 169 - src/target/armv4_5_mmu.h | 56 - src/target/armv7a.c | 769 - src/target/armv7a.h | 187 - src/target/armv7a_cache.c | 610 - src/target/armv7a_cache.h | 46 - src/target/armv7a_cache_l2x.c | 378 - src/target/armv7a_cache_l2x.h | 158 - src/target/armv7m.c | 829 - src/target/armv7m.h | 234 - src/target/armv7m_trace.c | 351 - src/target/armv7m_trace.h | 91 - src/target/avr32_ap7k.c | 624 - src/target/avr32_ap7k.h | 43 - src/target/avr32_jtag.c | 376 - src/target/avr32_jtag.h | 103 - src/target/avr32_mem.c | 317 - src/target/avr32_mem.h | 35 - src/target/avr32_regs.c | 114 - src/target/avr32_regs.h | 44 - src/target/avrt.c | 223 - src/target/avrt.h | 37 - src/target/breakpoints.c | 519 - src/target/breakpoints.h | 76 - src/target/cortex_a.c | 3591 --- src/target/cortex_a.h | 117 - src/target/cortex_m.c | 2429 -- src/target/cortex_m.h | 214 - src/target/dsp563xx.c | 2339 -- src/target/dsp563xx.h | 73 - src/target/dsp563xx_once.c | 293 - src/target/dsp563xx_once.h | 89 - src/target/dsp5680xx.c | 2297 -- src/target/dsp5680xx.h | 382 - src/target/embeddedice.c | 648 - src/target/embeddedice.h | 128 - src/target/etb.c | 703 - src/target/etb.h | 58 - src/target/etm.c | 2115 -- src/target/etm.h | 224 - src/target/etm_dummy.c | 106 - src/target/etm_dummy.h | 26 - src/target/fa526.c | 387 - src/target/feroceon.c | 769 - src/target/hla_target.c | 815 - src/target/image.c | 1044 - src/target/image.h | 110 - src/target/lakemont.c | 1125 - src/target/lakemont.h | 106 - src/target/ls1_sap.c | 243 - src/target/mips32.c | 952 - src/target/mips32.h | 252 - src/target/mips32_dmaacc.c | 462 - src/target/mips32_dmaacc.h | 41 - src/target/mips32_pracc.c | 1117 - src/target/mips32_pracc.h | 102 - src/target/mips_ejtag.c | 480 - src/target/mips_ejtag.h | 235 - src/target/mips_m4k.c | 1437 - src/target/mips_m4k.h | 46 - src/target/nds32.c | 2628 -- src/target/nds32.h | 457 - src/target/nds32_aice.c | 158 - src/target/nds32_aice.h | 161 - src/target/nds32_cmd.c | 1126 - src/target/nds32_cmd.h | 26 - src/target/nds32_disassembler.c | 3858 --- src/target/nds32_disassembler.h | 56 - src/target/nds32_edm.h | 115 - src/target/nds32_insn.h | 78 - src/target/nds32_reg.c | 380 - src/target/nds32_reg.h | 325 - src/target/nds32_tlb.c | 78 - src/target/nds32_tlb.h | 47 - src/target/nds32_v2.c | 785 - src/target/nds32_v2.h | 42 - src/target/nds32_v3.c | 521 - src/target/nds32_v3.h | 45 - src/target/nds32_v3_common.c | 675 - src/target/nds32_v3_common.h | 61 - src/target/nds32_v3m.c | 506 - src/target/nds32_v3m.h | 51 - src/target/oocd_trace.c | 417 - src/target/oocd_trace.h | 53 - src/target/openrisc/Makefile.am | 18 - src/target/openrisc/jsp_server.c | 245 - src/target/openrisc/jsp_server.h | 17 - src/target/openrisc/or1k.c | 1462 - src/target/openrisc/or1k.h | 158 - src/target/openrisc/or1k_du.h | 78 - src/target/openrisc/or1k_du_adv.c | 1098 - src/target/openrisc/or1k_tap.h | 42 - src/target/openrisc/or1k_tap_mohor.c | 63 - src/target/openrisc/or1k_tap_vjtag.c | 309 - src/target/openrisc/or1k_tap_xilinx_bscan.c | 63 - src/target/quark_d20xx.c | 115 - src/target/quark_x10xx.c | 98 - src/target/register.c | 113 - src/target/register.h | 167 - src/target/riscv/asm.h | 36 - src/target/riscv/debug_defines.h | 1501 - src/target/riscv/encoding.h | 1313 - src/target/riscv/gdb_regs.h | 25 - src/target/riscv/opcodes.h | 279 - src/target/riscv/riscv-011.c | 2603 -- src/target/riscv/riscv-013.c | 1634 - src/target/riscv/riscv.c | 1007 - src/target/riscv/riscv.h | 177 - src/target/smp.c | 97 - src/target/smp.h | 29 - src/target/startup.tcl | 210 - src/target/target.c | 6228 ---- src/target/target.h | 686 - src/target/target_request.c | 315 - src/target/target_request.h | 55 - src/target/target_type.h | 280 - src/target/testee.c | 73 - src/target/trace.c | 175 - src/target/trace.h | 59 - src/target/x86_32_common.c | 1497 - src/target/x86_32_common.h | 330 - src/target/xscale.c | 3728 --- src/target/xscale.h | 188 - src/target/xscale/build.sh | 7 - src/target/xscale/debug_handler.S | 716 - src/target/xscale/debug_handler.bin | Bin 1592 -> 0 bytes src/target/xscale/debug_handler.cmd | 49 - src/target/xscale/protocol.h | 68 - src/transport/Makefile.am | 11 - src/transport/transport.c | 380 - src/transport/transport.h | 93 - src/xsvf/Makefile.am | 8 - src/xsvf/xsvf.c | 1113 - src/xsvf/xsvf.h | 29 - tcl/bitsbytes.tcl | 61 - tcl/board/actux3.cfg | 69 - tcl/board/adapteva_parallella1.cfg | 7 - tcl/board/alphascale_asm9260_ek.cfg | 69 - tcl/board/altera_sockit.cfg | 19 - tcl/board/am3517evm.cfg | 21 - tcl/board/arm_evaluator7t.cfg | 10 - tcl/board/asus-rt-n16.cfg | 15 - tcl/board/asus-rt-n66u.cfg | 19 - tcl/board/at91cap7a-stk-sdram.cfg | 165 - tcl/board/at91eb40a.cfg | 67 - tcl/board/at91rm9200-dk.cfg | 82 - tcl/board/at91rm9200-ek.cfg | 114 - tcl/board/at91sam9261-ek.cfg | 63 - tcl/board/at91sam9263-ek.cfg | 63 - tcl/board/at91sam9g20-ek.cfg | 219 - tcl/board/atmel_at91sam7s-ek.cfg | 8 - tcl/board/atmel_at91sam9260-ek.cfg | 81 - tcl/board/atmel_at91sam9rl-ek.cfg | 75 - tcl/board/atmel_sam3n_ek.cfg | 12 - tcl/board/atmel_sam3s_ek.cfg | 3 - tcl/board/atmel_sam3u_ek.cfg | 4 - tcl/board/atmel_sam3x_ek.cfg | 3 - tcl/board/atmel_sam4e_ek.cfg | 7 - tcl/board/atmel_sam4l8_xplained_pro.cfg | 11 - tcl/board/atmel_sam4s_ek.cfg | 3 - tcl/board/atmel_sam4s_xplained_pro.cfg | 11 - tcl/board/atmel_samc20_xplained_pro.cfg | 10 - tcl/board/atmel_samc21_xplained_pro.cfg | 11 - tcl/board/atmel_samd20_xplained_pro.cfg | 11 - tcl/board/atmel_samd21_xplained_pro.cfg | 10 - tcl/board/atmel_same70_xplained.cfg | 12 - tcl/board/atmel_samg53_xplained_pro.cfg | 11 - tcl/board/atmel_saml21_xplained_pro.cfg | 10 - tcl/board/atmel_samr21_xplained_pro.cfg | 10 - tcl/board/atmel_samv71_xplained_ultra.cfg | 12 - tcl/board/balloon3-cpu.cfg | 14 - tcl/board/bcm28155_ap.cfg | 9 - tcl/board/bt-homehubv1.cfg | 15 - tcl/board/colibri.cfg | 13 - tcl/board/crossbow_tech_imote2.cfg | 13 - tcl/board/csb337.cfg | 117 - tcl/board/csb732.cfg | 71 - tcl/board/da850evm.cfg | 10 - tcl/board/digi_connectcore_wi-9c.cfg | 130 - tcl/board/digilent_analog_discovery.cfg | 18 - tcl/board/digilent_atlys.cfg | 17 - tcl/board/digilent_zedboard.cfg | 11 - tcl/board/diolan_lpc4350-db1.cfg | 9 - tcl/board/diolan_lpc4357-db1.cfg | 9 - tcl/board/dk-tm4c129.cfg | 14 - tcl/board/dm355evm.cfg | 201 - tcl/board/dm365evm.cfg | 147 - tcl/board/dm6446evm.cfg | 75 - tcl/board/dp_busblaster_v3.cfg | 13 - tcl/board/efikamx.cfg | 10 - tcl/board/efm32.cfg | 11 - tcl/board/eir.cfg | 94 - tcl/board/ek-lm3s1968.cfg | 19 - tcl/board/ek-lm3s3748.cfg | 14 - tcl/board/ek-lm3s6965.cfg | 15 - tcl/board/ek-lm3s811-revb.cfg | 14 - tcl/board/ek-lm3s811.cfg | 15 - tcl/board/ek-lm3s8962.cfg | 15 - tcl/board/ek-lm3s9b9x.cfg | 14 - tcl/board/ek-lm3s9d92.cfg | 14 - tcl/board/ek-lm4f120xl.cfg | 17 - tcl/board/ek-lm4f232.cfg | 17 - tcl/board/ek-tm4c123gxl.cfg | 13 - tcl/board/ek-tm4c1294xl.cfg | 14 - tcl/board/embedded-artists_lpc2478-32.cfg | 154 - tcl/board/emcraft_twr-vf6-som-bsb.cfg | 9 - tcl/board/emcraft_vf6-som.cfg | 8 - tcl/board/ethernut3.cfg | 86 - tcl/board/frdm-kl25z.cfg | 15 - tcl/board/frdm-kl46z.cfg | 15 - tcl/board/fsl_imx6q_sabresd.cfg | 149 - tcl/board/glyn_tonga2.cfg | 200 - tcl/board/gumstix-aerocore.cfg | 10 - tcl/board/hammer.cfg | 37 - tcl/board/hilscher_nxdb500sys.cfg | 40 - tcl/board/hilscher_nxeb500hmi.cfg | 40 - tcl/board/hilscher_nxhx10.cfg | 82 - tcl/board/hilscher_nxhx50.cfg | 40 - tcl/board/hilscher_nxhx500.cfg | 42 - tcl/board/hilscher_nxsb100.cfg | 29 - tcl/board/hitex_lpc1768stick.cfg | 15 - tcl/board/hitex_lpc2929.cfg | 106 - tcl/board/hitex_stm32-performancestick.cfg | 16 - tcl/board/hitex_str9-comstick.cfg | 79 - tcl/board/iar_lpc1768.cfg | 17 - tcl/board/iar_str912_sk.cfg | 3 - tcl/board/icnova_imx53_sodimm.cfg | 448 - tcl/board/icnova_sam9g45_sodimm.cfg | 278 - tcl/board/imx27ads.cfg | 76 - tcl/board/imx27lnst.cfg | 59 - tcl/board/imx28evk.cfg | 168 - tcl/board/imx31pdk.cfg | 99 - tcl/board/imx35pdk.cfg | 252 - tcl/board/imx53-m53evk.cfg | 318 - tcl/board/imx53loco.cfg | 315 - tcl/board/insignal_arndale.cfg | 8 - tcl/board/kc705.cfg | 15 - tcl/board/keil_mcb1700.cfg | 8 - tcl/board/keil_mcb2140.cfg | 8 - tcl/board/kwikstik.cfg | 12 - tcl/board/la_fonera-fon2200.cfg | 3 - tcl/board/linksys-wrt54gl.cfg | 15 - tcl/board/linksys_nslu2.cfg | 8 - tcl/board/lisa-l.cfg | 7 - tcl/board/logicpd_imx27.cfg | 13 - tcl/board/lpc1850_spifi_generic.cfg | 18 - tcl/board/lpc4350_spifi_generic.cfg | 13 - tcl/board/lubbock.cfg | 112 - tcl/board/marsohod.cfg | 13 - tcl/board/marsohod2.cfg | 13 - tcl/board/marsohod3.cfg | 13 - tcl/board/mbed-lpc11u24.cfg | 10 - tcl/board/mbed-lpc1768.cfg | 7 - tcl/board/mcb1700.cfg | 75 - tcl/board/microchip_explorer16.cfg | 10 - tcl/board/mini2440.cfg | 320 - tcl/board/mini6410.cfg | 112 - tcl/board/minispartan6.cfg | 24 - tcl/board/nds32_xc5.cfg | 5 - tcl/board/netgear-dg834v3.cfg | 20 - tcl/board/netgear-wg102.cfg | 35 - tcl/board/nordic_nrf51822_mkit.cfg | 6 - tcl/board/numato_opsis.cfg | 10 - tcl/board/nxp_lpc-link2.cfg | 12 - tcl/board/olimex_LPC2378STK.cfg | 11 - tcl/board/olimex_lpc_h2148.cfg | 8 - tcl/board/olimex_sam7_ex256.cfg | 4 - tcl/board/olimex_sam7_la2.cfg | 76 - tcl/board/olimex_sam9_l9260.cfg | 141 - tcl/board/olimex_stm32_h103.cfg | 7 - tcl/board/olimex_stm32_h107.cfg | 10 - tcl/board/olimex_stm32_p107.cfg | 10 - tcl/board/omap2420_h4.cfg | 12 - tcl/board/open-bldc.cfg | 7 - tcl/board/openrd.cfg | 123 - tcl/board/or1k_generic.cfg | 51 - tcl/board/osk5912.cfg | 34 - tcl/board/phone_se_j100i.cfg | 12 - tcl/board/phytec_lpc3250.cfg | 88 - tcl/board/pic-p32mx.cfg | 4 - tcl/board/pipistrello.cfg | 14 - tcl/board/propox_mmnet1001.cfg | 83 - tcl/board/pxa255_sst.cfg | 99 - tcl/board/quark_d2000_refboard.cfg | 15 - tcl/board/quark_x10xx_board.cfg | 9 - tcl/board/redbee.cfg | 1 - tcl/board/renesas_dk-s7g2.cfg | 13 - tcl/board/rsc-w910.cfg | 66 - tcl/board/sheevaplug.cfg | 136 - tcl/board/smdk6410.cfg | 9 - tcl/board/spansion_sk-fm4-176l-s6e2cc.cfg | 20 - tcl/board/spansion_sk-fm4-u120-9b560.cfg | 18 - tcl/board/spear300evb.cfg | 44 - tcl/board/spear300evb_mod.cfg | 26 - tcl/board/spear310evb20.cfg | 51 - tcl/board/spear310evb20_mod.cfg | 25 - tcl/board/spear320cpu.cfg | 51 - tcl/board/spear320cpu_mod.cfg | 25 - tcl/board/st_nucleo_f0.cfg | 15 - tcl/board/st_nucleo_f103rb.cfg | 10 - tcl/board/st_nucleo_f3.cfg | 10 - tcl/board/st_nucleo_f4.cfg | 13 - tcl/board/st_nucleo_l1.cfg | 10 - tcl/board/st_nucleo_l476rg.cfg | 12 - tcl/board/steval_pcc010.cfg | 9 - tcl/board/stm320518_eval.cfg | 12 - tcl/board/stm320518_eval_stlink.cfg | 19 - tcl/board/stm32100b_eval.cfg | 7 - tcl/board/stm3210b_eval.cfg | 7 - tcl/board/stm3210c_eval.cfg | 7 - tcl/board/stm3210e_eval.cfg | 63 - tcl/board/stm3220g_eval.cfg | 11 - tcl/board/stm3220g_eval_stlink.cfg | 19 - tcl/board/stm3241g_eval.cfg | 11 - tcl/board/stm3241g_eval_stlink.cfg | 19 - tcl/board/stm32429i_eval.cfg | 11 - tcl/board/stm32429i_eval_stlink.cfg | 19 - tcl/board/stm32439i_eval.cfg | 11 - tcl/board/stm32439i_eval_stlink.cfg | 19 - tcl/board/stm327x6g_eval.cfg | 10 - tcl/board/stm32f0discovery.cfg | 11 - tcl/board/stm32f334discovery.cfg | 6 - tcl/board/stm32f3discovery.cfg | 10 - tcl/board/stm32f429disc1.cfg | 12 - tcl/board/stm32f429discovery.cfg | 15 - tcl/board/stm32f469discovery.cfg | 15 - tcl/board/stm32f4discovery.cfg | 13 - tcl/board/stm32f7discovery.cfg | 12 - tcl/board/stm32l0discovery.cfg | 11 - tcl/board/stm32l4discovery.cfg | 13 - tcl/board/stm32ldiscovery.cfg | 11 - tcl/board/stm32vldiscovery.cfg | 11 - tcl/board/str910-eval.cfg | 64 - tcl/board/telo.cfg | 61 - tcl/board/ti-cc3200-launchxl.cfg | 18 - tcl/board/ti_am335xevm.cfg | 10 - tcl/board/ti_am437x_idk.cfg | 12 - tcl/board/ti_am43xx_evm.cfg | 7 - tcl/board/ti_beagleboard.cfg | 12 - tcl/board/ti_beagleboard_xm.cfg | 12 - tcl/board/ti_beaglebone.cfg | 13 - tcl/board/ti_blaze.cfg | 6 - tcl/board/ti_pandaboard.cfg | 6 - tcl/board/ti_pandaboard_es.cfg | 6 - tcl/board/ti_tmdx570ls20susb.cfg | 16 - tcl/board/ti_tmdx570ls31usb.cfg | 6 - tcl/board/topas910.cfg | 119 - tcl/board/topasa900.cfg | 126 - tcl/board/tp-link_tl-mr3020.cfg | 44 - tcl/board/twr-k60f120m.cfg | 17 - tcl/board/twr-k60n512.cfg | 15 - tcl/board/tx25_stk5.cfg | 158 - tcl/board/tx27_stk5.cfg | 64 - tcl/board/unknown_at91sam9260.cfg | 97 - tcl/board/uptech_2410.cfg | 65 - tcl/board/verdex.cfg | 17 - tcl/board/voipac.cfg | 12 - tcl/board/voltcraft_dso-3062c.cfg | 31 - tcl/board/x300t.cfg | 31 - tcl/board/xmc-2go.cfg | 15 - tcl/board/xmc1100-boot-kit.cfg | 15 - .../xmc4200-application-kit-actuator.cfg | 12 - tcl/board/xmc4500-application-kit-general.cfg | 8 - tcl/board/xmc4500-application-kit-sdram.cfg | 10 - tcl/board/xmc4500-relax.cfg | 14 - tcl/board/xmc4700-relax.cfg | 16 - tcl/board/xmc4800-relax.cfg | 16 - tcl/board/xmos_xk-xac-xa8_arm.cfg | 16 - tcl/board/zy1000.cfg | 117 - tcl/chip/atmel/at91/aic.tcl | 101 - tcl/chip/atmel/at91/at91_pio.cfg | 29 - tcl/chip/atmel/at91/at91_pmc.cfg | 113 - tcl/chip/atmel/at91/at91_rstc.cfg | 21 - tcl/chip/atmel/at91/at91_wdt.cfg | 17 - tcl/chip/atmel/at91/at91sam7x128.tcl | 128 - tcl/chip/atmel/at91/at91sam7x256.tcl | 126 - tcl/chip/atmel/at91/at91sam9261.cfg | 90 - tcl/chip/atmel/at91/at91sam9261_matrix.cfg | 46 - tcl/chip/atmel/at91/at91sam9263.cfg | 113 - tcl/chip/atmel/at91/at91sam9263_matrix.cfg | 112 - tcl/chip/atmel/at91/at91sam9_init.cfg | 95 - tcl/chip/atmel/at91/at91sam9_sdramc.cfg | 66 - tcl/chip/atmel/at91/at91sam9_smc.cfg | 20 - tcl/chip/atmel/at91/hardware.cfg | 9 - tcl/chip/atmel/at91/pmc.tcl | 17 - tcl/chip/atmel/at91/rtt.tcl | 56 - tcl/chip/atmel/at91/sam9_smc.cfg | 55 - tcl/chip/atmel/at91/usarts.tcl | 135 - tcl/chip/st/spear/quirk_no_srst.tcl | 75 - tcl/chip/st/spear/spear3xx.tcl | 129 - tcl/chip/st/spear/spear3xx_ddr.tcl | 127 - tcl/chip/st/stm32/stm32.tcl | 7 - tcl/chip/st/stm32/stm32_rcc.tcl | 290 - tcl/chip/st/stm32/stm32_regs.tcl | 95 - tcl/chip/ti/lm3s/lm3s.tcl | 1 - tcl/chip/ti/lm3s/lm3s_regs.tcl | 84 - tcl/cpld/altera-epm240.cfg | 6 - tcl/cpld/jtagspi.cfg | 43 - tcl/cpld/lattice-lc4032ze.cfg | 3 - tcl/cpld/xilinx-xc6s.cfg | 90 - tcl/cpld/xilinx-xc7.cfg | 57 - tcl/cpld/xilinx-xcr3256.cfg | 3 - tcl/cpu/arm/arm7tdmi.tcl | 6 - tcl/cpu/arm/arm920.tcl | 6 - tcl/cpu/arm/arm946.tcl | 6 - tcl/cpu/arm/arm966.tcl | 6 - tcl/cpu/arm/cortex_m3.tcl | 6 - tcl/fpga/altera-10m50.cfg | 6 - tcl/fpga/altera-ep3c10.cfg | 4 - tcl/interface/altera-usb-blaster.cfg | 10 - tcl/interface/altera-usb-blaster2.cfg | 8 - tcl/interface/arm-jtag-ew.cfg | 8 - tcl/interface/at91rm9200.cfg | 9 - tcl/interface/axm0432.cfg | 11 - tcl/interface/busblaster.cfg | 14 - tcl/interface/buspirate.cfg | 26 - tcl/interface/calao-usb-a9260-c01.cfg | 13 - tcl/interface/calao-usb-a9260-c02.cfg | 13 - tcl/interface/calao-usb-a9260.cfg | 11 - tcl/interface/chameleon.cfg | 9 - tcl/interface/cmsis-dap.cfg | 10 - tcl/interface/cortino.cfg | 11 - tcl/interface/digilent-hs1.cfg | 15 - tcl/interface/dlp-usb1232h.cfg | 14 - tcl/interface/dummy.cfg | 6 - tcl/interface/estick.cfg | 7 - tcl/interface/flashlink.cfg | 16 - tcl/interface/flossjtag-noeeprom.cfg | 19 - tcl/interface/flossjtag.cfg | 20 - tcl/interface/flyswatter.cfg | 10 - tcl/interface/flyswatter2.cfg | 10 - tcl/interface/ftdi/100ask-openjtag.cfg | 16 - tcl/interface/ftdi/axm0432.cfg | 18 - tcl/interface/ftdi/calao-usb-a9260-c01.cfg | 22 - tcl/interface/ftdi/calao-usb-a9260-c02.cfg | 22 - tcl/interface/ftdi/cortino.cfg | 13 - tcl/interface/ftdi/digilent-hs1.cfg | 11 - tcl/interface/ftdi/digilent-hs2.cfg | 10 - tcl/interface/ftdi/digilent_jtag_hs3.cfg | 13 - tcl/interface/ftdi/digilent_jtag_smt2.cfg | 17 - tcl/interface/ftdi/dlp-usb1232h.cfg | 21 - tcl/interface/ftdi/dp_busblaster.cfg | 20 - tcl/interface/ftdi/dp_busblaster_kt-link.cfg | 21 - tcl/interface/ftdi/flossjtag-noeeprom.cfg | 26 - tcl/interface/ftdi/flossjtag.cfg | 29 - tcl/interface/ftdi/flyswatter.cfg | 14 - tcl/interface/ftdi/flyswatter2.cfg | 14 - tcl/interface/ftdi/gw16042.cfg | 26 - tcl/interface/ftdi/hilscher_nxhx10_etm.cfg | 18 - tcl/interface/ftdi/hilscher_nxhx500_etm.cfg | 18 - tcl/interface/ftdi/hilscher_nxhx500_re.cfg | 18 - tcl/interface/ftdi/hilscher_nxhx50_etm.cfg | 18 - tcl/interface/ftdi/hilscher_nxhx50_re.cfg | 18 - tcl/interface/ftdi/hitex_lpc1768stick.cfg | 15 - tcl/interface/ftdi/hitex_str9-comstick.cfg | 13 - tcl/interface/ftdi/icebear.cfg | 18 - tcl/interface/ftdi/iotlab-usb.cfg | 11 - tcl/interface/ftdi/jtag-lock-pick_tiny_2.cfg | 16 - tcl/interface/ftdi/jtagkey.cfg | 13 - tcl/interface/ftdi/jtagkey2.cfg | 13 - tcl/interface/ftdi/jtagkey2p.cfg | 13 - tcl/interface/ftdi/kt-link.cfg | 16 - tcl/interface/ftdi/lisa-l.cfg | 20 - tcl/interface/ftdi/luminary-icdi.cfg | 25 - tcl/interface/ftdi/luminary-lm3s811.cfg | 21 - tcl/interface/ftdi/luminary.cfg | 34 - tcl/interface/ftdi/m53evk.cfg | 14 - tcl/interface/ftdi/mbftdi.cfg | 16 - tcl/interface/ftdi/minimodule.cfg | 17 - tcl/interface/ftdi/minispartan6.cfg | 15 - tcl/interface/ftdi/neodb.cfg | 14 - tcl/interface/ftdi/ngxtech.cfg | 19 - tcl/interface/ftdi/olimex-arm-jtag-swd.cfg | 9 - tcl/interface/ftdi/olimex-arm-usb-ocd-h.cfg | 14 - tcl/interface/ftdi/olimex-arm-usb-ocd.cfg | 14 - tcl/interface/ftdi/olimex-arm-usb-tiny-h.cfg | 14 - tcl/interface/ftdi/olimex-jtag-tiny.cfg | 14 - tcl/interface/ftdi/oocdlink.cfg | 19 - tcl/interface/ftdi/opendous_ftdi.cfg | 17 - tcl/interface/ftdi/openocd-usb-hs.cfg | 13 - tcl/interface/ftdi/openocd-usb.cfg | 13 - tcl/interface/ftdi/openrd.cfg | 19 - tcl/interface/ftdi/pipistrello.cfg | 13 - tcl/interface/ftdi/redbee-econotag.cfg | 21 - tcl/interface/ftdi/redbee-usb.cfg | 22 - tcl/interface/ftdi/rowley-cc-arm-swd.cfg | 10 - tcl/interface/ftdi/sheevaplug.cfg | 14 - tcl/interface/ftdi/signalyzer-lite.cfg | 18 - tcl/interface/ftdi/signalyzer.cfg | 18 - tcl/interface/ftdi/stm32-stick.cfg | 13 - tcl/interface/ftdi/swd-resistor-hack.cfg | 26 - tcl/interface/ftdi/ti-icdi.cfg | 15 - tcl/interface/ftdi/tumpa-lite.cfg | 12 - tcl/interface/ftdi/tumpa.cfg | 14 - tcl/interface/ftdi/turtelizer2-revB.cfg | 18 - tcl/interface/ftdi/turtelizer2-revC.cfg | 14 - tcl/interface/ftdi/um232h.cfg | 35 - tcl/interface/ftdi/vpaclink.cfg | 19 - tcl/interface/ftdi/xds100v2.cfg | 58 - tcl/interface/ftdi/xds100v3.cfg | 11 - tcl/interface/hilscher_nxhx10_etm.cfg | 11 - tcl/interface/hilscher_nxhx500_etm.cfg | 11 - tcl/interface/hilscher_nxhx500_re.cfg | 11 - tcl/interface/hilscher_nxhx50_etm.cfg | 11 - tcl/interface/hilscher_nxhx50_re.cfg | 11 - tcl/interface/hitex_str9-comstick.cfg | 11 - tcl/interface/icebear.cfg | 11 - tcl/interface/jlink.cfg | 14 - tcl/interface/jtag-lock-pick_tiny_2.cfg | 10 - tcl/interface/jtag_vpi.cfg | 18 - tcl/interface/jtagkey-tiny.cfg | 9 - tcl/interface/jtagkey.cfg | 11 - tcl/interface/jtagkey2.cfg | 11 - tcl/interface/jtagkey2p.cfg | 11 - tcl/interface/kt-link.cfg | 10 - tcl/interface/lisa-l.cfg | 11 - tcl/interface/luminary-icdi.cfg | 21 - tcl/interface/luminary-lm3s811.cfg | 18 - tcl/interface/luminary.cfg | 31 - tcl/interface/minimodule.cfg | 10 - tcl/interface/nds32-aice.cfg | 15 - tcl/interface/neodb.cfg | 10 - tcl/interface/ngxtech.cfg | 10 - tcl/interface/olimex-arm-usb-ocd-h.cfg | 11 - tcl/interface/olimex-arm-usb-ocd.cfg | 11 - tcl/interface/olimex-arm-usb-tiny-h.cfg | 11 - tcl/interface/olimex-jtag-tiny.cfg | 11 - tcl/interface/oocdlink.cfg | 12 - tcl/interface/opendous.cfg | 7 - tcl/interface/opendous_ftdi.cfg | 15 - tcl/interface/openjtag.cfg | 8 - tcl/interface/openocd-usb-hs.cfg | 11 - tcl/interface/openocd-usb.cfg | 11 - tcl/interface/openrd.cfg | 12 - tcl/interface/osbdm.cfg | 7 - tcl/interface/parport.cfg | 19 - tcl/interface/parport_dlc5.cfg | 16 - tcl/interface/raspberrypi-native.cfg | 35 - tcl/interface/raspberrypi2-native.cfg | 42 - tcl/interface/redbee-econotag.cfg | 13 - tcl/interface/redbee-usb.cfg | 13 - tcl/interface/rlink.cfg | 8 - tcl/interface/sheevaplug.cfg | 12 - tcl/interface/signalyzer-h2.cfg | 11 - tcl/interface/signalyzer-h4.cfg | 11 - tcl/interface/signalyzer-lite.cfg | 11 - tcl/interface/signalyzer.cfg | 11 - tcl/interface/stlink-v1.cfg | 9 - tcl/interface/stlink-v2-1.cfg | 16 - tcl/interface/stlink-v2.cfg | 16 - tcl/interface/stm32-stick.cfg | 11 - tcl/interface/sysfsgpio-raspberrypi.cfg | 21 - tcl/interface/ti-icdi.cfg | 13 - tcl/interface/turtelizer2.cfg | 15 - tcl/interface/ulink.cfg | 8 - tcl/interface/usb-jtag.cfg | 37 - tcl/interface/usbprog.cfg | 10 - tcl/interface/vpaclink.cfg | 10 - tcl/interface/vsllink.cfg | 8 - tcl/interface/xds100v2.cfg | 10 - tcl/mem_helper.tcl | 31 - tcl/memory.tcl | 187 - tcl/mmr_helpers.tcl | 72 - tcl/target/1986ве1т.cfg | 63 - tcl/target/aduc702x.cfg | 53 - tcl/target/aducm360.cfg | 55 - tcl/target/alphascale_asm9260t.cfg | 25 - tcl/target/altera_fpgasoc.cfg | 64 - tcl/target/am335x.cfg | 78 - tcl/target/am437x.cfg | 999 - tcl/target/amdm37x.cfg | 211 - tcl/target/ar71xx.cfg | 57 - tcl/target/armada370.cfg | 33 - tcl/target/at32ap7000.cfg | 16 - tcl/target/at91r40008.cfg | 29 - tcl/target/at91rm9200.cfg | 47 - tcl/target/at91sam3XXX.cfg | 87 - tcl/target/at91sam3ax_4x.cfg | 9 - tcl/target/at91sam3ax_8x.cfg | 11 - tcl/target/at91sam3ax_xx.cfg | 11 - tcl/target/at91sam3nXX.cfg | 32 - tcl/target/at91sam3sXX.cfg | 16 - tcl/target/at91sam3u1c.cfg | 8 - tcl/target/at91sam3u1e.cfg | 8 - tcl/target/at91sam3u2c.cfg | 8 - tcl/target/at91sam3u2e.cfg | 8 - tcl/target/at91sam3u4c.cfg | 11 - tcl/target/at91sam3u4e.cfg | 11 - tcl/target/at91sam3uxx.cfg | 11 - tcl/target/at91sam4XXX.cfg | 63 - tcl/target/at91sam4lXX.cfg | 27 - tcl/target/at91sam4sXX.cfg | 7 - tcl/target/at91sam4sd32x.cfg | 9 - tcl/target/at91sam7a2.cfg | 23 - tcl/target/at91sam7se512.cfg | 39 - tcl/target/at91sam7sx.cfg | 53 - tcl/target/at91sam7x256.cfg | 50 - tcl/target/at91sam7x512.cfg | 51 - tcl/target/at91sam9.cfg | 37 - tcl/target/at91sam9260.cfg | 19 - tcl/target/at91sam9260_ext_RAM_ext_flash.cfg | 89 - tcl/target/at91sam9261.cfg | 14 - tcl/target/at91sam9263.cfg | 20 - tcl/target/at91sam9g10.cfg | 16 - tcl/target/at91sam9g20.cfg | 22 - tcl/target/at91sam9g45.cfg | 16 - tcl/target/at91sam9rl.cfg | 14 - tcl/target/at91samdXX.cfg | 87 - tcl/target/at91samg5x.cfg | 7 - tcl/target/atheros_ar2313.cfg | 16 - tcl/target/atheros_ar2315.cfg | 16 - tcl/target/atheros_ar9331.cfg | 16 - tcl/target/atmega128.cfg | 40 - tcl/target/atsamv.cfg | 51 - tcl/target/avr32.cfg | 17 - tcl/target/bcm281xx.cfg | 33 - tcl/target/bcm4706.cfg | 7 - tcl/target/bcm4718.cfg | 5 - tcl/target/bcm47xx.cfg | 21 - tcl/target/bcm5352e.cfg | 7 - tcl/target/bcm6348.cfg | 9 - tcl/target/c100.cfg | 42 - tcl/target/c100config.tcl | 412 - tcl/target/c100helper.tcl | 506 - tcl/target/c100regs.tcl | 493 - tcl/target/cc2538.cfg | 16 - tcl/target/cc26xx.cfg | 43 - tcl/target/cc32xx.cfg | 53 - tcl/target/cs351x.cfg | 31 - tcl/target/davinci.cfg | 377 - tcl/target/dragonite.cfg | 31 - tcl/target/dsp56321.cfg | 37 - tcl/target/dsp568013.cfg | 76 - tcl/target/dsp568037.cfg | 72 - tcl/target/efm32.cfg | 43 - tcl/target/efm32_stlink.cfg | 2 - tcl/target/em357.cfg | 76 - tcl/target/em358.cfg | 17 - tcl/target/epc9301.cfg | 32 - tcl/target/exynos5250.cfg | 23 - tcl/target/faux.cfg | 30 - tcl/target/feroceon.cfg | 31 - tcl/target/fm3.cfg | 53 - tcl/target/fm4.cfg | 30 - tcl/target/fm4_mb9bf.cfg | 18 - tcl/target/fm4_s6e2cc.cfg | 19 - tcl/target/gp326xxxa.cfg | 94 - tcl/target/hilscher_netx10.cfg | 31 - tcl/target/hilscher_netx50.cfg | 50 - tcl/target/hilscher_netx500.cfg | 47 - tcl/target/icepick.cfg | 142 - tcl/target/imx.cfg | 30 - tcl/target/imx21.cfg | 34 - tcl/target/imx25.cfg | 46 - tcl/target/imx27.cfg | 53 - tcl/target/imx28.cfg | 38 - tcl/target/imx31.cfg | 68 - tcl/target/imx35.cfg | 55 - tcl/target/imx51.cfg | 47 - tcl/target/imx53.cfg | 47 - tcl/target/imx6.cfg | 59 - tcl/target/is5114.cfg | 46 - tcl/target/ixp42x.cfg | 107 - tcl/target/k1921vk01t.cfg | 55 - tcl/target/k40.cfg | 6 - tcl/target/k60.cfg | 6 - tcl/target/ke02.cfg | 6 - tcl/target/ke04.cfg | 6 - tcl/target/ke06.cfg | 6 - tcl/target/kex.cfg | 58 - tcl/target/kl25.cfg | 6 - tcl/target/kl25z_hla.cfg | 2 - tcl/target/kl46.cfg | 6 - tcl/target/klx.cfg | 60 - tcl/target/ks869x.cfg | 34 - tcl/target/kx.cfg | 54 - tcl/target/lpc11xx.cfg | 8 - tcl/target/lpc12xx.cfg | 8 - tcl/target/lpc13xx.cfg | 8 - tcl/target/lpc17xx.cfg | 8 - tcl/target/lpc1850.cfg | 34 - tcl/target/lpc1xxx.cfg | 159 - tcl/target/lpc2103.cfg | 21 - tcl/target/lpc2124.cfg | 21 - tcl/target/lpc2129.cfg | 21 - tcl/target/lpc2148.cfg | 21 - tcl/target/lpc2294.cfg | 23 - tcl/target/lpc2378.cfg | 21 - tcl/target/lpc2460.cfg | 21 - tcl/target/lpc2478.cfg | 21 - tcl/target/lpc2900.cfg | 66 - tcl/target/lpc2xxx.cfg | 44 - tcl/target/lpc3131.cfg | 76 - tcl/target/lpc3250.cfg | 43 - tcl/target/lpc40xx.cfg | 8 - tcl/target/lpc4350.cfg | 70 - tcl/target/lpc4357.cfg | 12 - tcl/target/lpc4370.cfg | 85 - tcl/target/lpc8xx.cfg | 10 - tcl/target/mc13224v.cfg | 54 - tcl/target/mdr32f9q2i.cfg | 62 - tcl/target/nds32v2.cfg | 10 - tcl/target/nds32v3.cfg | 10 - tcl/target/nds32v3m.cfg | 10 - tcl/target/nrf51.cfg | 60 - tcl/target/nrf51_stlink.tcl | 2 - tcl/target/nrf52.cfg | 28 - tcl/target/nuc910.cfg | 27 - tcl/target/numicro.cfg | 60 - tcl/target/omap2420.cfg | 61 - tcl/target/omap3530.cfg | 74 - tcl/target/omap4430.cfg | 127 - tcl/target/omap4460.cfg | 126 - tcl/target/omap5912.cfg | 52 - tcl/target/omapl138.cfg | 66 - tcl/target/or1k.cfg | 72 - tcl/target/pic32mx.cfg | 90 - tcl/target/psoc4.cfg | 152 - tcl/target/psoc5lp.cfg | 32 - tcl/target/pxa255.cfg | 59 - tcl/target/pxa270.cfg | 50 - tcl/target/pxa3xx.cfg | 86 - tcl/target/quark_d20xx.cfg | 50 - tcl/target/quark_x10xx.cfg | 52 - tcl/target/readme.txt | 41 - tcl/target/renesas_s7g2.cfg | 50 - tcl/target/samsung_s3c2410.cfg | 36 - tcl/target/samsung_s3c2440.cfg | 35 - tcl/target/samsung_s3c2450.cfg | 48 - tcl/target/samsung_s3c4510.cfg | 24 - tcl/target/samsung_s3c6410.cfg | 51 - tcl/target/sharp_lh79532.cfg | 26 - tcl/target/sim3x.cfg | 55 - tcl/target/smp8634.cfg | 31 - tcl/target/spear3xx.cfg | 41 - tcl/target/stellaris.cfg | 176 - tcl/target/stellaris_icdi.cfg | 2 - tcl/target/stm32_stlink.cfg | 1 - tcl/target/stm32f0x.cfg | 86 - tcl/target/stm32f0x_stlink.cfg | 2 - tcl/target/stm32f1x.cfg | 109 - tcl/target/stm32f1x_stlink.cfg | 2 - tcl/target/stm32f2x.cfg | 96 - tcl/target/stm32f2x_stlink.cfg | 2 - tcl/target/stm32f3x.cfg | 127 - tcl/target/stm32f3x_stlink.cfg | 2 - tcl/target/stm32f4x.cfg | 137 - tcl/target/stm32f4x_stlink.cfg | 2 - tcl/target/stm32f7x.cfg | 92 - tcl/target/stm32l0.cfg | 77 - tcl/target/stm32l1.cfg | 126 - tcl/target/stm32l1x_dual_bank.cfg | 8 - tcl/target/stm32l4x.cfg | 111 - tcl/target/stm32lx_stlink.cfg | 2 - tcl/target/stm32w108_stlink.cfg | 2 - tcl/target/stm32w108xx.cfg | 70 - tcl/target/stm32xl.cfg | 6 - tcl/target/str710.cfg | 53 - tcl/target/str730.cfg | 54 - tcl/target/str750.cfg | 72 - tcl/target/str912.cfg | 71 - tcl/target/swj-dp.tcl | 34 - tcl/target/test_reset_syntax_error.cfg | 17 - tcl/target/test_syntax_error.cfg | 4 - tcl/target/ti-ar7.cfg | 30 - tcl/target/ti-cjtag.cfg | 32 - tcl/target/ti_calypso.cfg | 57 - tcl/target/ti_dm355.cfg | 109 - tcl/target/ti_dm365.cfg | 101 - tcl/target/ti_dm6446.cfg | 81 - tcl/target/ti_msp432p4xx.cfg | 52 - tcl/target/ti_rm4x.cfg | 1 - tcl/target/ti_tms570.cfg | 74 - tcl/target/ti_tms570ls20xxx.cfg | 6 - tcl/target/ti_tms570ls3137.cfg | 5 - tcl/target/tmpa900.cfg | 46 - tcl/target/tmpa910.cfg | 47 - tcl/target/u8500.cfg | 332 - tcl/target/vybrid_vf6xx.cfg | 36 - tcl/target/xmc1xxx.cfg | 40 - tcl/target/xmc4xxx.cfg | 59 - tcl/target/xmos_xs1-xau8a-10_arm.cfg | 16 - tcl/target/zynq_7000.cfg | 26 - tcl/target/к1879xб1я.cfg | 35 - tcl/test/selftest.cfg | 17 - tcl/test/syntax1.cfg | 30 - tcl/tools/firmware-recovery.tcl | 112 - tcl/tools/memtest.tcl | 189 - testing/build.test1/Makefile | 98 - testing/build.test1/Makefile.confuse | 46 - testing/build.test1/Makefile.ftd2xx | 88 - testing/build.test1/Makefile.libftdi | 51 - testing/build.test1/Makefile.libusb | 55 - testing/build.test1/Makefile.openocd | 193 - testing/build.test1/README.TXT | 39 - testing/build.test1/local.uses | 39 - .../build.test1/mingw32_help/include/elf.h | 38 - .../mingw32_help/include/sys/cdefs.h | 23 - .../mingw32_help/include/sys/elf32.h | 156 - .../mingw32_help/include/sys/elf64.h | 172 - .../mingw32_help/include/sys/elf_common.h | 299 - .../mingw32_help/include/sys/elf_generic.h | 91 - testing/build.test2/Makefile | 193 - testing/build.test2/README.txt | 59 - testing/build.test2/local.uses | 161 - .../examples/AT91R40008Test/inc/typedefs.h | 50 - testing/examples/AT91R40008Test/makefile | 137 - .../prj/at91r40008_reset.script | 7 - .../AT91R40008Test/prj/at91r40008_turtle.cfg | 37 - .../AT91R40008Test/prj/eclipse_ram.gdb | 14 - .../AT91R40008Test/prj/ethernut3_ram.ld | 140 - testing/examples/AT91R40008Test/src/crt.s | 172 - testing/examples/AT91R40008Test/src/main.c | 93 - testing/examples/AT91R40008Test/test_ram.elf | Bin 36586 -> 0 bytes testing/examples/AT91R40008Test/test_ram.hex | 23 - testing/examples/AT91R40008Test/test_ram.map | 170 - testing/examples/LPC2148Test/inc/typedefs.h | 50 - testing/examples/LPC2148Test/makefile | 147 - .../examples/LPC2148Test/prj/eclipse_ram.gdb | 11 - .../examples/LPC2148Test/prj/eclipse_rom.gdb | 11 - .../LPC2148Test/prj/lpc2148_jtagkey.cfg | 34 - .../examples/LPC2148Test/prj/lpc2148_ram.ld | 140 - .../examples/LPC2148Test/prj/lpc2148_rom.ld | 141 - testing/examples/LPC2148Test/src/crt.s | 189 - testing/examples/LPC2148Test/src/main.c | 93 - testing/examples/LPC2148Test/test_ram.elf | Bin 36650 -> 0 bytes testing/examples/LPC2148Test/test_ram.hex | 26 - testing/examples/LPC2148Test/test_ram.map | 170 - testing/examples/LPC2148Test/test_rom.elf | Bin 36650 -> 0 bytes testing/examples/LPC2148Test/test_rom.hex | 25 - testing/examples/LPC2148Test/test_rom.map | 170 - testing/examples/LPC2294Test/inc/typedefs.h | 50 - testing/examples/LPC2294Test/makefile | 147 - .../examples/LPC2294Test/prj/eclipse_ram.gdb | 11 - .../examples/LPC2294Test/prj/eclipse_rom.gdb | 11 - .../LPC2294Test/prj/lpc2294_jtagkey.cfg | 35 - .../examples/LPC2294Test/prj/lpc2294_ram.ld | 140 - .../examples/LPC2294Test/prj/lpc2294_rom.ld | 141 - testing/examples/LPC2294Test/src/crt.s | 189 - testing/examples/LPC2294Test/src/main.c | 93 - testing/examples/LPC2294Test/test_ram.elf | Bin 36618 -> 0 bytes testing/examples/LPC2294Test/test_ram.hex | 26 - testing/examples/LPC2294Test/test_ram.map | 170 - testing/examples/LPC2294Test/test_rom.elf | Bin 36618 -> 0 bytes testing/examples/LPC2294Test/test_rom.hex | 25 - testing/examples/LPC2294Test/test_rom.map | 170 - testing/examples/PIC32/BlinkingLeds.c | 23 - testing/examples/PIC32/BlinkingLeds.elf | Bin 770014 -> 0 bytes testing/examples/PIC32/readme.txt | 3 - testing/examples/SAM7S256Test/inc/typedefs.h | 50 - testing/examples/SAM7S256Test/makefile | 146 - .../examples/SAM7S256Test/prj/eclipse_ram.gdb | 32 - .../examples/SAM7S256Test/prj/eclipse_rom.gdb | 32 - .../SAM7S256Test/prj/sam7s256_jtagkey.cfg | 39 - .../examples/SAM7S256Test/prj/sam7s256_ram.ld | 132 - .../SAM7S256Test/prj/sam7s256_reset.script | 17 - .../examples/SAM7S256Test/prj/sam7s256_rom.ld | 133 - .../examples/SAM7S256Test/results/607.html | 698 - testing/examples/SAM7S256Test/src/crt.s | 225 - testing/examples/SAM7S256Test/src/main.c | 91 - testing/examples/SAM7S256Test/test_ram.elf | Bin 36888 -> 0 bytes testing/examples/SAM7S256Test/test_ram.hex | 29 - testing/examples/SAM7S256Test/test_ram.map | 170 - testing/examples/SAM7S256Test/test_rom.elf | Bin 36888 -> 0 bytes testing/examples/SAM7S256Test/test_rom.hex | 29 - testing/examples/SAM7S256Test/test_rom.map | 170 - testing/examples/SAM7X256Test/inc/typedefs.h | 50 - testing/examples/SAM7X256Test/makefile | 146 - .../examples/SAM7X256Test/prj/eclipse_ram.gdb | 32 - .../examples/SAM7X256Test/prj/eclipse_rom.gdb | 32 - .../SAM7X256Test/prj/sam7x256_jtagkey.cfg | 39 - .../examples/SAM7X256Test/prj/sam7x256_ram.ld | 132 - .../SAM7X256Test/prj/sam7x256_reset.script | 17 - .../examples/SAM7X256Test/prj/sam7x256_rom.ld | 133 - testing/examples/SAM7X256Test/src/crt.s | 225 - testing/examples/SAM7X256Test/src/main.c | 91 - testing/examples/SAM7X256Test/test_ram.elf | Bin 36888 -> 0 bytes testing/examples/SAM7X256Test/test_ram.hex | 29 - testing/examples/SAM7X256Test/test_ram.map | 170 - testing/examples/SAM7X256Test/test_rom.elf | Bin 36888 -> 0 bytes testing/examples/SAM7X256Test/test_rom.hex | 29 - testing/examples/SAM7X256Test/test_rom.map | 170 - testing/examples/STM32-103/main.elf | Bin 144604 -> 0 bytes testing/examples/STM32-103/readme.txt | 6 - .../examples/STR710JtagSpeed/inc/typedefs.h | 50 - testing/examples/STR710JtagSpeed/makefile | 134 - .../prj/eclipse_ft2232_ram.gdb | 33 - .../STR710JtagSpeed/prj/str710_jtagkey.cfg | 34 - .../examples/STR710JtagSpeed/prj/str7_ram.ld | 140 - testing/examples/STR710JtagSpeed/src/crt.s | 263 - testing/examples/STR710JtagSpeed/src/main.c | 90 - testing/examples/STR710JtagSpeed/test.elf | Bin 430217 -> 0 bytes testing/examples/STR710JtagSpeed/test.hex | 24611 ---------------- testing/examples/STR710JtagSpeed/test.map | 170 - testing/examples/STR710Test/.gitignore | 2 - testing/examples/STR710Test/inc/typedefs.h | 50 - testing/examples/STR710Test/makefile | 146 - .../examples/STR710Test/prj/eclipse_ram.gdb | 11 - .../examples/STR710Test/prj/eclipse_rom.gdb | 11 - .../examples/STR710Test/prj/hitex_str7_ram.ld | 255 - .../examples/STR710Test/prj/hitex_str7_rom.ld | 259 - .../STR710Test/prj/str710_jtagkey.cfg | 36 - .../STR710Test/prj/str710_program.script | 8 - testing/examples/STR710Test/src/crt.s | 299 - testing/examples/STR710Test/src/main.c | 105 - testing/examples/STR710Test/test_ram.elf | Bin 41263 -> 0 bytes testing/examples/STR710Test/test_ram.hex | 37 - testing/examples/STR710Test/test_ram.map | 297 - testing/examples/STR710Test/test_rom.elf | Bin 41263 -> 0 bytes testing/examples/STR710Test/test_rom.hex | 37 - testing/examples/STR710Test/test_rom.map | 300 - testing/examples/STR912Test/inc/typedefs.h | 50 - testing/examples/STR912Test/makefile | 146 - .../examples/STR912Test/prj/eclipse_ram.gdb | 21 - .../examples/STR912Test/prj/eclipse_rom.gdb | 21 - .../STR912Test/prj/str912_jtagkey.cfg | 41 - .../STR912Test/prj/str912_program.script | 9 - testing/examples/STR912Test/prj/str912_ram.ld | 218 - testing/examples/STR912Test/prj/str912_rom.ld | 249 - testing/examples/STR912Test/src/main.c | 91 - testing/examples/STR912Test/src/startup.s | 222 - testing/examples/STR912Test/test_ram.elf | Bin 40512 -> 0 bytes testing/examples/STR912Test/test_ram.hex | 30 - testing/examples/STR912Test/test_ram.map | 255 - testing/examples/STR912Test/test_rom.elf | Bin 40570 -> 0 bytes testing/examples/STR912Test/test_rom.hex | 28 - testing/examples/STR912Test/test_rom.map | 280 - testing/examples/cortex/cm3-ftest.cfg | 143 - testing/examples/cortex/fault.c | 152 - testing/examples/cortex/lm3s3748.elf | Bin 10122 -> 0 bytes testing/examples/cortex/test.c | 27 - testing/examples/cortex/test.ld | 220 - testing/examples/ledtest-imx27ads/Makefile | 42 - testing/examples/ledtest-imx27ads/crt0.S | 47 - .../ledtest-imx27ads/gdbinit-imx27ads | 36 - testing/examples/ledtest-imx27ads/ldscript | 18 - testing/examples/ledtest-imx27ads/test.c | 60 - testing/examples/ledtest-imx27ads/test.elf | Bin 35762 -> 0 bytes testing/examples/ledtest-imx31pdk/Makefile | 42 - testing/examples/ledtest-imx31pdk/crt0.S | 47 - .../ledtest-imx31pdk/gdbinit-imx31pdk | 36 - testing/examples/ledtest-imx31pdk/ldscript | 18 - testing/examples/ledtest-imx31pdk/test.c | 58 - testing/examples/ledtest-imx31pdk/test.elf | Bin 3250 -> 0 bytes testing/index.html | 43 - testing/profile_stm32.txt | 52 - testing/results/template.html | 18 - testing/results/v0.4.0-rc1/AT91FR40162.html | 856 - testing/results/v0.4.0-rc1/LPC2148.html | 933 - testing/results/v0.4.0-rc1/SAM7.html | 853 - testing/results/v0.4.0-rc1/STR710.html | 907 - testing/results/v0.4.0-rc1/STR912.html | 1008 - testing/smoketests.html | 334 - testing/tcl_server.tcl | 15 - testing/tcl_test.tcl | 65 - testing/testcases.html | 566 - tools/checkpatch.sh | 5 - tools/git2cl | 1 - tools/initial.sh | 37 - tools/logger.pl | 40 - tools/release.sh | 361 - tools/release/helpers.sh | 60 - tools/release/test.sh | 121 - tools/release/version.sh | 149 - .../rlink_make_speed_table | 2 - .../rlink_make_speed_table.pl | 75 - tools/scripts/checkpatch.pl | 3350 --- tools/st7_dtc_as/st7_dtc_as | 2 - tools/st7_dtc_as/st7_dtc_as.pl | 709 - tools/uncrustify1.sh | 30 - uncrustify.cfg | 142 - 1473 files changed, 350937 deletions(-) delete mode 100644 .gitignore delete mode 100644 .gitmodules delete mode 100644 AUTHORS delete mode 100644 AUTHORS.ChangeLog delete mode 100644 BUGS delete mode 100644 COPYING delete mode 100644 ChangeLog delete mode 100644 Doxyfile.in delete mode 100644 HACKING delete mode 100644 Makefile.am delete mode 100644 NEWS delete mode 100644 NEWS-0.2.0 delete mode 100644 NEWS-0.3.0 delete mode 100644 NEWS-0.4.0 delete mode 100644 NEWS-0.5.0 delete mode 100644 NEWS-0.6.0 delete mode 100644 NEWS-0.7.0 delete mode 100644 NEWS-0.8.0 delete mode 100644 NEWS-0.9.0 delete mode 100644 NEWTAPS delete mode 100644 README delete mode 100644 README.OSX delete mode 100644 README.Windows delete mode 100644 TODO delete mode 100755 bootstrap delete mode 100644 common.mk delete mode 100644 config_subdir.m4 delete mode 100644 configure.ac delete mode 100644 contrib/99-openocd.rules delete mode 100644 contrib/coresight-trace.txt delete mode 100755 contrib/cross-build.sh delete mode 100755 contrib/gen-stellaris-part-header.pl delete mode 100644 contrib/itmdump.c delete mode 100644 contrib/libdcc/README delete mode 100644 contrib/libdcc/dcc_stdio.c delete mode 100644 contrib/libdcc/dcc_stdio.h delete mode 100644 contrib/libdcc/example.c delete mode 100644 contrib/loaders/Makefile delete mode 100644 contrib/loaders/README delete mode 100644 contrib/loaders/checksum/Makefile delete mode 100644 contrib/loaders/checksum/armv4_5_crc.inc delete mode 100644 contrib/loaders/checksum/armv4_5_crc.s delete mode 100644 contrib/loaders/checksum/armv7m_crc.inc delete mode 100644 contrib/loaders/checksum/armv7m_crc.s delete mode 100644 contrib/loaders/checksum/mips32.s delete mode 100644 contrib/loaders/erase_check/Makefile delete mode 100644 contrib/loaders/erase_check/armv4_5_erase_check.inc delete mode 100644 contrib/loaders/erase_check/armv4_5_erase_check.s delete mode 100644 contrib/loaders/erase_check/armv7m_0_erase_check.inc delete mode 100644 contrib/loaders/erase_check/armv7m_0_erase_check.s delete mode 100644 contrib/loaders/erase_check/armv7m_erase_check.inc delete mode 100644 contrib/loaders/erase_check/armv7m_erase_check.s delete mode 100644 contrib/loaders/flash/armv4_5_cfi_intel_16.s delete mode 100644 contrib/loaders/flash/armv4_5_cfi_intel_32.s delete mode 100644 contrib/loaders/flash/armv4_5_cfi_intel_8.s delete mode 100644 contrib/loaders/flash/armv4_5_cfi_span_16.s delete mode 100644 contrib/loaders/flash/armv4_5_cfi_span_16_dq7.s delete mode 100644 contrib/loaders/flash/armv4_5_cfi_span_32.s delete mode 100644 contrib/loaders/flash/armv4_5_cfi_span_8.s delete mode 100644 contrib/loaders/flash/armv7m_cfi_span_16.s delete mode 100644 contrib/loaders/flash/armv7m_cfi_span_16_dq7.s delete mode 100644 contrib/loaders/flash/armv7m_io.s delete mode 100644 contrib/loaders/flash/at91sam7x/at91sam7x_ocl_flash.script delete mode 100644 contrib/loaders/flash/at91sam7x/at91sam7x_ram.ld delete mode 100644 contrib/loaders/flash/at91sam7x/crt.s delete mode 100644 contrib/loaders/flash/at91sam7x/dcc.c delete mode 100644 contrib/loaders/flash/at91sam7x/dcc.h delete mode 100644 contrib/loaders/flash/at91sam7x/main.c delete mode 100644 contrib/loaders/flash/at91sam7x/makefile delete mode 100644 contrib/loaders/flash/at91sam7x/ocl.h delete mode 100644 contrib/loaders/flash/at91sam7x/platform.h delete mode 100644 contrib/loaders/flash/at91sam7x/samflash.c delete mode 100644 contrib/loaders/flash/at91sam7x/samflash.h delete mode 100644 contrib/loaders/flash/at91sam7x/samregs.h delete mode 100644 contrib/loaders/flash/cortex-m0.S delete mode 100644 contrib/loaders/flash/efm32.S delete mode 100644 contrib/loaders/flash/fm4/Makefile delete mode 100644 contrib/loaders/flash/fm4/erase.S delete mode 100644 contrib/loaders/flash/fm4/erase.inc delete mode 100644 contrib/loaders/flash/fm4/fm4.h delete mode 100644 contrib/loaders/flash/fm4/write.S delete mode 100644 contrib/loaders/flash/fm4/write.inc delete mode 100755 contrib/loaders/flash/fpga/xilinx_bscan_spi.py delete mode 100644 contrib/loaders/flash/k1921vk01t.S delete mode 100644 contrib/loaders/flash/kinetis_ke/Makefile delete mode 100644 contrib/loaders/flash/kinetis_ke/kinetis_ke_flash.inc delete mode 100644 contrib/loaders/flash/kinetis_ke/kinetis_ke_flash.s delete mode 100644 contrib/loaders/flash/kinetis_ke/kinetis_ke_watchdog.inc delete mode 100644 contrib/loaders/flash/kinetis_ke/kinetis_ke_watchdog.s delete mode 100644 contrib/loaders/flash/lpcspifi_erase.S delete mode 100644 contrib/loaders/flash/lpcspifi_init.S delete mode 100644 contrib/loaders/flash/lpcspifi_write.S delete mode 100644 contrib/loaders/flash/mdr32fx.S delete mode 100644 contrib/loaders/flash/mrvlqspi_write.S delete mode 100644 contrib/loaders/flash/pic32mx.s delete mode 100644 contrib/loaders/flash/sim3x.s delete mode 100644 contrib/loaders/flash/stellaris.s delete mode 100644 contrib/loaders/flash/stm32f1x.S delete mode 100644 contrib/loaders/flash/stm32f2x.S delete mode 100644 contrib/loaders/flash/stm32l4x.S delete mode 100644 contrib/loaders/flash/stm32lx.S delete mode 100644 contrib/loaders/flash/str7x.s delete mode 100644 contrib/loaders/flash/str9x.s delete mode 100644 contrib/loaders/flash/xmc1xxx/Makefile delete mode 100644 contrib/loaders/flash/xmc1xxx/erase.S delete mode 100644 contrib/loaders/flash/xmc1xxx/erase.inc delete mode 100644 contrib/loaders/flash/xmc1xxx/erase_check.S delete mode 100644 contrib/loaders/flash/xmc1xxx/erase_check.inc delete mode 100644 contrib/loaders/flash/xmc1xxx/write.S delete mode 100644 contrib/loaders/flash/xmc1xxx/write.inc delete mode 100644 contrib/loaders/flash/xmc1xxx/xmc1xxx.S delete mode 100644 contrib/loaders/watchdog/Makefile delete mode 100644 contrib/loaders/watchdog/armv7m_kinetis_wdog.inc delete mode 100644 contrib/loaders/watchdog/armv7m_kinetis_wdog.s delete mode 100644 contrib/remote_bitbang/remote_bitbang_sysfsgpio.c delete mode 100755 contrib/rpc_examples/ocd_rpc_example.py delete mode 100644 contrib/rpc_examples/ocdrpc.hs delete mode 100644 contrib/rtos-helpers/FreeRTOS-openocd.c delete mode 100644 contrib/xsvf_tools/svf2xsvf.py delete mode 100644 contrib/xsvf_tools/xsvfdump.py delete mode 100644 doc/INSTALL.txt delete mode 100644 doc/Makefile.am delete mode 100644 doc/fdl.texi delete mode 100644 doc/manual/app.txt delete mode 100644 doc/manual/flash.txt delete mode 100644 doc/manual/helper.txt delete mode 100644 doc/manual/images/jtag-state-machine-large.png delete mode 100644 doc/manual/jtag.txt delete mode 100644 doc/manual/jtag/drivers/remote_bitbang.txt delete mode 100644 doc/manual/main.txt delete mode 100644 doc/manual/primer/autotools.txt delete mode 100644 doc/manual/primer/commands.txt delete mode 100644 doc/manual/primer/docs.txt delete mode 100644 doc/manual/primer/jtag.txt delete mode 100644 doc/manual/primer/tcl.txt delete mode 100644 doc/manual/release.txt delete mode 100644 doc/manual/scripting.txt delete mode 100644 doc/manual/server.txt delete mode 100644 doc/manual/style.txt delete mode 100644 doc/manual/target.txt delete mode 100644 doc/manual/target/mips.txt delete mode 100644 doc/manual/target/notarm.txt delete mode 100644 doc/openocd.1 delete mode 100644 doc/openocd.texi delete mode 100755 guess-rev.sh delete mode 160000 jimtcl delete mode 100644 src/Makefile.am delete mode 100644 src/flash/Makefile.am delete mode 100644 src/flash/common.c delete mode 100644 src/flash/common.h delete mode 100644 src/flash/mflash.c delete mode 100644 src/flash/mflash.h delete mode 100644 src/flash/nand/Makefile.am delete mode 100644 src/flash/nand/arm_io.c delete mode 100644 src/flash/nand/arm_io.h delete mode 100644 src/flash/nand/at91sam9.c delete mode 100644 src/flash/nand/core.c delete mode 100644 src/flash/nand/core.h delete mode 100644 src/flash/nand/davinci.c delete mode 100644 src/flash/nand/driver.c delete mode 100644 src/flash/nand/driver.h delete mode 100644 src/flash/nand/ecc.c delete mode 100644 src/flash/nand/ecc_kw.c delete mode 100644 src/flash/nand/fileio.c delete mode 100644 src/flash/nand/fileio.h delete mode 100644 src/flash/nand/imp.h delete mode 100644 src/flash/nand/lpc3180.c delete mode 100644 src/flash/nand/lpc3180.h delete mode 100644 src/flash/nand/lpc32xx.c delete mode 100644 src/flash/nand/lpc32xx.h delete mode 100644 src/flash/nand/mx3.c delete mode 100644 src/flash/nand/mx3.h delete mode 100644 src/flash/nand/mxc.c delete mode 100644 src/flash/nand/mxc.h delete mode 100644 src/flash/nand/nonce.c delete mode 100644 src/flash/nand/nuc910.c delete mode 100644 src/flash/nand/nuc910.h delete mode 100644 src/flash/nand/orion.c delete mode 100644 src/flash/nand/s3c2410.c delete mode 100644 src/flash/nand/s3c2412.c delete mode 100644 src/flash/nand/s3c2440.c delete mode 100644 src/flash/nand/s3c2443.c delete mode 100644 src/flash/nand/s3c24xx.c delete mode 100644 src/flash/nand/s3c24xx.h delete mode 100644 src/flash/nand/s3c24xx_regs.h delete mode 100644 src/flash/nand/s3c6400.c delete mode 100644 src/flash/nand/tcl.c delete mode 100644 src/flash/nor/Makefile.am delete mode 100644 src/flash/nor/aduc702x.c delete mode 100644 src/flash/nor/aducm360.c delete mode 100644 src/flash/nor/ambiqmicro.c delete mode 100644 src/flash/nor/at91sam3.c delete mode 100644 src/flash/nor/at91sam4.c delete mode 100644 src/flash/nor/at91sam4l.c delete mode 100644 src/flash/nor/at91sam7.c delete mode 100644 src/flash/nor/at91samd.c delete mode 100644 src/flash/nor/atsamv.c delete mode 100644 src/flash/nor/avrf.c delete mode 100644 src/flash/nor/cfi.c delete mode 100644 src/flash/nor/cfi.h delete mode 100644 src/flash/nor/core.c delete mode 100644 src/flash/nor/core.h delete mode 100644 src/flash/nor/driver.h delete mode 100644 src/flash/nor/drivers.c delete mode 100644 src/flash/nor/dsp5680xx_flash.c delete mode 100644 src/flash/nor/efm32.c delete mode 100644 src/flash/nor/em357.c delete mode 100644 src/flash/nor/faux.c delete mode 100644 src/flash/nor/fespi.c delete mode 100644 src/flash/nor/fm3.c delete mode 100644 src/flash/nor/fm4.c delete mode 100644 src/flash/nor/imp.h delete mode 100644 src/flash/nor/jtagspi.c delete mode 100644 src/flash/nor/kinetis.c delete mode 100644 src/flash/nor/kinetis_ke.c delete mode 100644 src/flash/nor/lpc2000.c delete mode 100644 src/flash/nor/lpc288x.c delete mode 100644 src/flash/nor/lpc2900.c delete mode 100644 src/flash/nor/lpcspifi.c delete mode 100644 src/flash/nor/mdr.c delete mode 100644 src/flash/nor/mrvlqspi.c delete mode 100644 src/flash/nor/niietcm4.c delete mode 100644 src/flash/nor/non_cfi.c delete mode 100644 src/flash/nor/non_cfi.h delete mode 100644 src/flash/nor/nrf51.c delete mode 100644 src/flash/nor/numicro.c delete mode 100644 src/flash/nor/ocl.c delete mode 100644 src/flash/nor/ocl.h delete mode 100644 src/flash/nor/pic32mx.c delete mode 100644 src/flash/nor/psoc4.c delete mode 100644 src/flash/nor/sim3x.c delete mode 100644 src/flash/nor/spi.c delete mode 100644 src/flash/nor/spi.h delete mode 100644 src/flash/nor/stellaris.c delete mode 100644 src/flash/nor/stm32f1x.c delete mode 100644 src/flash/nor/stm32f2x.c delete mode 100644 src/flash/nor/stm32l4x.c delete mode 100644 src/flash/nor/stm32lx.c delete mode 100644 src/flash/nor/stmsmi.c delete mode 100644 src/flash/nor/str7x.c delete mode 100644 src/flash/nor/str9x.c delete mode 100644 src/flash/nor/str9xpec.c delete mode 100644 src/flash/nor/tcl.c delete mode 100644 src/flash/nor/tms470.c delete mode 100644 src/flash/nor/virtual.c delete mode 100644 src/flash/nor/xmc1xxx.c delete mode 100644 src/flash/nor/xmc4xxx.c delete mode 100644 src/flash/startup.tcl delete mode 100644 src/hello.c delete mode 100644 src/hello.h delete mode 100644 src/helper/Makefile.am delete mode 100755 src/helper/bin2char.sh delete mode 100644 src/helper/binarybuffer.c delete mode 100644 src/helper/binarybuffer.h delete mode 100644 src/helper/command.c delete mode 100644 src/helper/command.h delete mode 100644 src/helper/configuration.c delete mode 100644 src/helper/configuration.h delete mode 100644 src/helper/fileio.c delete mode 100644 src/helper/fileio.h delete mode 100644 src/helper/ioutil.c delete mode 100644 src/helper/ioutil.h delete mode 100644 src/helper/ioutil_stubs.c delete mode 100644 src/helper/jep106.c delete mode 100644 src/helper/jep106.h delete mode 100644 src/helper/jep106.inc delete mode 100644 src/helper/jim-nvp.c delete mode 100644 src/helper/jim-nvp.h delete mode 100644 src/helper/list.h delete mode 100644 src/helper/log.c delete mode 100644 src/helper/log.h delete mode 100644 src/helper/options.c delete mode 100644 src/helper/replacements.c delete mode 100644 src/helper/replacements.h delete mode 100644 src/helper/startup.tcl delete mode 100644 src/helper/system.h delete mode 100644 src/helper/time_support.c delete mode 100644 src/helper/time_support.h delete mode 100644 src/helper/time_support_common.c delete mode 100644 src/helper/types.h delete mode 100755 src/helper/update_jep106.pl delete mode 100644 src/helper/util.c delete mode 100644 src/helper/util.h delete mode 100644 src/jtag/Makefile.am delete mode 100644 src/jtag/adapter.c delete mode 100644 src/jtag/aice/Makefile.am delete mode 100644 src/jtag/aice/aice_interface.c delete mode 100644 src/jtag/aice/aice_interface.h delete mode 100644 src/jtag/aice/aice_pipe.c delete mode 100644 src/jtag/aice/aice_pipe.h delete mode 100644 src/jtag/aice/aice_port.c delete mode 100644 src/jtag/aice/aice_port.h delete mode 100644 src/jtag/aice/aice_transport.c delete mode 100644 src/jtag/aice/aice_transport.h delete mode 100644 src/jtag/aice/aice_usb.c delete mode 100644 src/jtag/aice/aice_usb.h delete mode 100644 src/jtag/commands.c delete mode 100644 src/jtag/commands.h delete mode 100644 src/jtag/core.c delete mode 100644 src/jtag/driver.h delete mode 100644 src/jtag/drivers/Makefile.am delete mode 100644 src/jtag/drivers/Makefile.rlink delete mode 100644 src/jtag/drivers/OpenULINK/Makefile delete mode 100644 src/jtag/drivers/OpenULINK/README delete mode 100644 src/jtag/drivers/OpenULINK/include/common.h delete mode 100644 src/jtag/drivers/OpenULINK/include/delay.h delete mode 100644 src/jtag/drivers/OpenULINK/include/io.h delete mode 100644 src/jtag/drivers/OpenULINK/include/jtag.h delete mode 100644 src/jtag/drivers/OpenULINK/include/main.h delete mode 100644 src/jtag/drivers/OpenULINK/include/msgtypes.h delete mode 100644 src/jtag/drivers/OpenULINK/include/protocol.h delete mode 100644 src/jtag/drivers/OpenULINK/include/reg_ezusb.h delete mode 100644 src/jtag/drivers/OpenULINK/include/usb.h delete mode 100644 src/jtag/drivers/OpenULINK/src/USBJmpTb.a51 delete mode 100644 src/jtag/drivers/OpenULINK/src/delay.c delete mode 100644 src/jtag/drivers/OpenULINK/src/jtag.c delete mode 100644 src/jtag/drivers/OpenULINK/src/main.c delete mode 100644 src/jtag/drivers/OpenULINK/src/protocol.c delete mode 100644 src/jtag/drivers/OpenULINK/src/usb.c delete mode 100644 src/jtag/drivers/OpenULINK/ulink_firmware.hex delete mode 100644 src/jtag/drivers/amt_jtagaccel.c delete mode 100644 src/jtag/drivers/arm-jtag-ew.c delete mode 100644 src/jtag/drivers/at91rm9200.c delete mode 100644 src/jtag/drivers/bcm2835gpio.c delete mode 100644 src/jtag/drivers/bitbang.c delete mode 100644 src/jtag/drivers/bitbang.h delete mode 100644 src/jtag/drivers/bitq.c delete mode 100644 src/jtag/drivers/bitq.h delete mode 100644 src/jtag/drivers/buspirate.c delete mode 100644 src/jtag/drivers/cmsis_dap_usb.c delete mode 100644 src/jtag/drivers/driver.c delete mode 100644 src/jtag/drivers/dummy.c delete mode 100644 src/jtag/drivers/ep93xx.c delete mode 100644 src/jtag/drivers/ft2232.c delete mode 100644 src/jtag/drivers/ftd2xx_common.h delete mode 100644 src/jtag/drivers/ftdi.c delete mode 100644 src/jtag/drivers/gw16012.c delete mode 100644 src/jtag/drivers/jlink.c delete mode 100644 src/jtag/drivers/jtag_vpi.c delete mode 160000 src/jtag/drivers/libjaylink delete mode 100644 src/jtag/drivers/libusb0_common.c delete mode 100644 src/jtag/drivers/libusb0_common.h delete mode 100644 src/jtag/drivers/libusb1_common.c delete mode 100644 src/jtag/drivers/libusb1_common.h delete mode 100644 src/jtag/drivers/libusb_common.h delete mode 100644 src/jtag/drivers/minidriver_imp.h delete mode 100644 src/jtag/drivers/mpsse.c delete mode 100644 src/jtag/drivers/mpsse.h delete mode 100644 src/jtag/drivers/opendous.c delete mode 100644 src/jtag/drivers/openjtag.c delete mode 100644 src/jtag/drivers/osbdm.c delete mode 100644 src/jtag/drivers/parport.c delete mode 100644 src/jtag/drivers/presto.c delete mode 100644 src/jtag/drivers/remote_bitbang.c delete mode 100644 src/jtag/drivers/rlink.c delete mode 100644 src/jtag/drivers/rlink.h delete mode 100644 src/jtag/drivers/rlink_call.m4 delete mode 100644 src/jtag/drivers/rlink_dtc_cmd.h delete mode 100644 src/jtag/drivers/rlink_ep1_cmd.h delete mode 100644 src/jtag/drivers/rlink_init.m4 delete mode 100644 src/jtag/drivers/rlink_speed_table.c delete mode 100644 src/jtag/drivers/rlink_st7.h delete mode 100644 src/jtag/drivers/stlink_usb.c delete mode 100644 src/jtag/drivers/sysfsgpio.c delete mode 100644 src/jtag/drivers/ti_icdi_usb.c delete mode 100644 src/jtag/drivers/ulink.c delete mode 100644 src/jtag/drivers/usb_blaster/Makefile.am delete mode 100644 src/jtag/drivers/usb_blaster/README.CheapClone delete mode 100644 src/jtag/drivers/usb_blaster/ublast2_access_libusb.c delete mode 100644 src/jtag/drivers/usb_blaster/ublast_access.h delete mode 100644 src/jtag/drivers/usb_blaster/ublast_access_ftd2xx.c delete mode 100644 src/jtag/drivers/usb_blaster/ublast_access_ftdi.c delete mode 100644 src/jtag/drivers/usb_blaster/usb_blaster.c delete mode 100644 src/jtag/drivers/usb_common.c delete mode 100644 src/jtag/drivers/usb_common.h delete mode 100644 src/jtag/drivers/usbprog.c delete mode 100644 src/jtag/drivers/versaloon/usbtoxxx/usbtogpio.c delete mode 100644 src/jtag/drivers/versaloon/usbtoxxx/usbtojtagraw.c delete mode 100644 src/jtag/drivers/versaloon/usbtoxxx/usbtopwr.c delete mode 100644 src/jtag/drivers/versaloon/usbtoxxx/usbtoswd.c delete mode 100644 src/jtag/drivers/versaloon/usbtoxxx/usbtoxxx.c delete mode 100644 src/jtag/drivers/versaloon/usbtoxxx/usbtoxxx.h delete mode 100644 src/jtag/drivers/versaloon/usbtoxxx/usbtoxxx_internal.h delete mode 100644 src/jtag/drivers/versaloon/versaloon.c delete mode 100644 src/jtag/drivers/versaloon/versaloon.h delete mode 100644 src/jtag/drivers/versaloon/versaloon_include.h delete mode 100644 src/jtag/drivers/versaloon/versaloon_internal.h delete mode 100644 src/jtag/drivers/vsllink.c delete mode 100644 src/jtag/hla/Makefile.am delete mode 100644 src/jtag/hla/hla_interface.c delete mode 100644 src/jtag/hla/hla_interface.h delete mode 100644 src/jtag/hla/hla_layout.c delete mode 100644 src/jtag/hla/hla_layout.h delete mode 100644 src/jtag/hla/hla_tcl.c delete mode 100644 src/jtag/hla/hla_tcl.h delete mode 100644 src/jtag/hla/hla_transport.c delete mode 100644 src/jtag/hla/hla_transport.h delete mode 100644 src/jtag/interface.c delete mode 100644 src/jtag/interface.h delete mode 100644 src/jtag/interfaces.c delete mode 100644 src/jtag/interfaces.h delete mode 100644 src/jtag/jtag.h delete mode 100644 src/jtag/minidriver.h delete mode 100644 src/jtag/minidriver/minidriver_imp.h delete mode 100644 src/jtag/minidummy/jtag_minidriver.h delete mode 100644 src/jtag/minidummy/minidummy.c delete mode 100644 src/jtag/startup.tcl delete mode 100644 src/jtag/swd.h delete mode 100644 src/jtag/tcl.c delete mode 100644 src/jtag/tcl.h delete mode 100644 src/jtag/zy1000/jtag_minidriver.h delete mode 100644 src/jtag/zy1000/zy1000.c delete mode 100644 src/main.c delete mode 100644 src/openocd.c delete mode 100644 src/openocd.h delete mode 100644 src/pld/Makefile.am delete mode 100644 src/pld/pld.c delete mode 100644 src/pld/pld.h delete mode 100644 src/pld/virtex2.c delete mode 100644 src/pld/virtex2.h delete mode 100644 src/pld/xilinx_bit.c delete mode 100644 src/pld/xilinx_bit.h delete mode 100644 src/rtos/ChibiOS.c delete mode 100644 src/rtos/FreeRTOS.c delete mode 100644 src/rtos/Makefile.am delete mode 100644 src/rtos/ThreadX.c delete mode 100644 src/rtos/eCos.c delete mode 100644 src/rtos/embKernel.c delete mode 100644 src/rtos/linux.c delete mode 100644 src/rtos/linux_header.h delete mode 100644 src/rtos/mqx.c delete mode 100644 src/rtos/riscv_debug.c delete mode 100644 src/rtos/riscv_debug.h delete mode 100644 src/rtos/rtos.c delete mode 100644 src/rtos/rtos.h delete mode 100644 src/rtos/rtos_chibios_stackings.c delete mode 100644 src/rtos/rtos_chibios_stackings.h delete mode 100644 src/rtos/rtos_ecos_stackings.c delete mode 100644 src/rtos/rtos_ecos_stackings.h delete mode 100644 src/rtos/rtos_embkernel_stackings.c delete mode 100644 src/rtos/rtos_embkernel_stackings.h delete mode 100644 src/rtos/rtos_mqx_stackings.c delete mode 100644 src/rtos/rtos_mqx_stackings.h delete mode 100644 src/rtos/rtos_standard_stackings.c delete mode 100644 src/rtos/rtos_standard_stackings.h delete mode 100644 src/server/Makefile.am delete mode 100644 src/server/gdb_server.c delete mode 100644 src/server/gdb_server.h delete mode 100644 src/server/server.c delete mode 100644 src/server/server.h delete mode 100644 src/server/server_stubs.c delete mode 100644 src/server/startup.tcl delete mode 100644 src/server/tcl_server.c delete mode 100644 src/server/tcl_server.h delete mode 100644 src/server/telnet_server.c delete mode 100644 src/server/telnet_server.h delete mode 100644 src/svf/Makefile.am delete mode 100644 src/svf/svf.c delete mode 100644 src/svf/svf.h delete mode 100644 src/target/Makefile.am delete mode 100644 src/target/adi_v5_jtag.c delete mode 100644 src/target/adi_v5_swd.c delete mode 100644 src/target/algorithm.c delete mode 100644 src/target/algorithm.h delete mode 100644 src/target/arm.h delete mode 100644 src/target/arm11.c delete mode 100644 src/target/arm11.h delete mode 100644 src/target/arm11_dbgtap.c delete mode 100644 src/target/arm11_dbgtap.h delete mode 100644 src/target/arm720t.c delete mode 100644 src/target/arm720t.h delete mode 100644 src/target/arm7_9_common.c delete mode 100644 src/target/arm7_9_common.h delete mode 100644 src/target/arm7tdmi.c delete mode 100644 src/target/arm7tdmi.h delete mode 100644 src/target/arm920t.c delete mode 100644 src/target/arm920t.h delete mode 100644 src/target/arm926ejs.c delete mode 100644 src/target/arm926ejs.h delete mode 100644 src/target/arm946e.c delete mode 100644 src/target/arm946e.h delete mode 100644 src/target/arm966e.c delete mode 100644 src/target/arm966e.h delete mode 100644 src/target/arm9tdmi.c delete mode 100644 src/target/arm9tdmi.h delete mode 100644 src/target/arm_adi_v5.c delete mode 100644 src/target/arm_adi_v5.h delete mode 100644 src/target/arm_disassembler.c delete mode 100644 src/target/arm_disassembler.h delete mode 100644 src/target/arm_dpm.c delete mode 100644 src/target/arm_dpm.h delete mode 100644 src/target/arm_jtag.c delete mode 100644 src/target/arm_jtag.h delete mode 100644 src/target/arm_opcodes.h delete mode 100644 src/target/arm_semihosting.c delete mode 100644 src/target/arm_semihosting.h delete mode 100644 src/target/arm_simulator.c delete mode 100644 src/target/arm_simulator.h delete mode 100644 src/target/armv4_5.c delete mode 100644 src/target/armv4_5.h delete mode 100644 src/target/armv4_5_cache.c delete mode 100644 src/target/armv4_5_cache.h delete mode 100644 src/target/armv4_5_mmu.c delete mode 100644 src/target/armv4_5_mmu.h delete mode 100644 src/target/armv7a.c delete mode 100644 src/target/armv7a.h delete mode 100644 src/target/armv7a_cache.c delete mode 100644 src/target/armv7a_cache.h delete mode 100644 src/target/armv7a_cache_l2x.c delete mode 100644 src/target/armv7a_cache_l2x.h delete mode 100644 src/target/armv7m.c delete mode 100644 src/target/armv7m.h delete mode 100644 src/target/armv7m_trace.c delete mode 100644 src/target/armv7m_trace.h delete mode 100644 src/target/avr32_ap7k.c delete mode 100644 src/target/avr32_ap7k.h delete mode 100644 src/target/avr32_jtag.c delete mode 100644 src/target/avr32_jtag.h delete mode 100644 src/target/avr32_mem.c delete mode 100644 src/target/avr32_mem.h delete mode 100644 src/target/avr32_regs.c delete mode 100644 src/target/avr32_regs.h delete mode 100644 src/target/avrt.c delete mode 100644 src/target/avrt.h delete mode 100644 src/target/breakpoints.c delete mode 100644 src/target/breakpoints.h delete mode 100644 src/target/cortex_a.c delete mode 100644 src/target/cortex_a.h delete mode 100644 src/target/cortex_m.c delete mode 100644 src/target/cortex_m.h delete mode 100644 src/target/dsp563xx.c delete mode 100644 src/target/dsp563xx.h delete mode 100644 src/target/dsp563xx_once.c delete mode 100644 src/target/dsp563xx_once.h delete mode 100644 src/target/dsp5680xx.c delete mode 100644 src/target/dsp5680xx.h delete mode 100644 src/target/embeddedice.c delete mode 100644 src/target/embeddedice.h delete mode 100644 src/target/etb.c delete mode 100644 src/target/etb.h delete mode 100644 src/target/etm.c delete mode 100644 src/target/etm.h delete mode 100644 src/target/etm_dummy.c delete mode 100644 src/target/etm_dummy.h delete mode 100644 src/target/fa526.c delete mode 100644 src/target/feroceon.c delete mode 100644 src/target/hla_target.c delete mode 100644 src/target/image.c delete mode 100644 src/target/image.h delete mode 100644 src/target/lakemont.c delete mode 100644 src/target/lakemont.h delete mode 100644 src/target/ls1_sap.c delete mode 100644 src/target/mips32.c delete mode 100644 src/target/mips32.h delete mode 100644 src/target/mips32_dmaacc.c delete mode 100644 src/target/mips32_dmaacc.h delete mode 100644 src/target/mips32_pracc.c delete mode 100644 src/target/mips32_pracc.h delete mode 100644 src/target/mips_ejtag.c delete mode 100644 src/target/mips_ejtag.h delete mode 100644 src/target/mips_m4k.c delete mode 100644 src/target/mips_m4k.h delete mode 100644 src/target/nds32.c delete mode 100644 src/target/nds32.h delete mode 100644 src/target/nds32_aice.c delete mode 100644 src/target/nds32_aice.h delete mode 100644 src/target/nds32_cmd.c delete mode 100644 src/target/nds32_cmd.h delete mode 100644 src/target/nds32_disassembler.c delete mode 100644 src/target/nds32_disassembler.h delete mode 100644 src/target/nds32_edm.h delete mode 100644 src/target/nds32_insn.h delete mode 100644 src/target/nds32_reg.c delete mode 100644 src/target/nds32_reg.h delete mode 100644 src/target/nds32_tlb.c delete mode 100644 src/target/nds32_tlb.h delete mode 100644 src/target/nds32_v2.c delete mode 100644 src/target/nds32_v2.h delete mode 100644 src/target/nds32_v3.c delete mode 100644 src/target/nds32_v3.h delete mode 100644 src/target/nds32_v3_common.c delete mode 100644 src/target/nds32_v3_common.h delete mode 100644 src/target/nds32_v3m.c delete mode 100644 src/target/nds32_v3m.h delete mode 100644 src/target/oocd_trace.c delete mode 100644 src/target/oocd_trace.h delete mode 100644 src/target/openrisc/Makefile.am delete mode 100644 src/target/openrisc/jsp_server.c delete mode 100644 src/target/openrisc/jsp_server.h delete mode 100644 src/target/openrisc/or1k.c delete mode 100644 src/target/openrisc/or1k.h delete mode 100644 src/target/openrisc/or1k_du.h delete mode 100644 src/target/openrisc/or1k_du_adv.c delete mode 100644 src/target/openrisc/or1k_tap.h delete mode 100644 src/target/openrisc/or1k_tap_mohor.c delete mode 100644 src/target/openrisc/or1k_tap_vjtag.c delete mode 100644 src/target/openrisc/or1k_tap_xilinx_bscan.c delete mode 100644 src/target/quark_d20xx.c delete mode 100644 src/target/quark_x10xx.c delete mode 100644 src/target/register.c delete mode 100644 src/target/register.h delete mode 100644 src/target/riscv/asm.h delete mode 100644 src/target/riscv/debug_defines.h delete mode 100644 src/target/riscv/encoding.h delete mode 100644 src/target/riscv/gdb_regs.h delete mode 100644 src/target/riscv/opcodes.h delete mode 100644 src/target/riscv/riscv-011.c delete mode 100644 src/target/riscv/riscv-013.c delete mode 100644 src/target/riscv/riscv.c delete mode 100644 src/target/riscv/riscv.h delete mode 100644 src/target/smp.c delete mode 100644 src/target/smp.h delete mode 100644 src/target/startup.tcl delete mode 100644 src/target/target.c delete mode 100644 src/target/target.h delete mode 100644 src/target/target_request.c delete mode 100644 src/target/target_request.h delete mode 100644 src/target/target_type.h delete mode 100644 src/target/testee.c delete mode 100644 src/target/trace.c delete mode 100644 src/target/trace.h delete mode 100644 src/target/x86_32_common.c delete mode 100644 src/target/x86_32_common.h delete mode 100644 src/target/xscale.c delete mode 100644 src/target/xscale.h delete mode 100755 src/target/xscale/build.sh delete mode 100644 src/target/xscale/debug_handler.S delete mode 100755 src/target/xscale/debug_handler.bin delete mode 100644 src/target/xscale/debug_handler.cmd delete mode 100644 src/target/xscale/protocol.h delete mode 100644 src/transport/Makefile.am delete mode 100644 src/transport/transport.c delete mode 100644 src/transport/transport.h delete mode 100644 src/xsvf/Makefile.am delete mode 100644 src/xsvf/xsvf.c delete mode 100644 src/xsvf/xsvf.h delete mode 100644 tcl/bitsbytes.tcl delete mode 100644 tcl/board/actux3.cfg delete mode 100644 tcl/board/adapteva_parallella1.cfg delete mode 100644 tcl/board/alphascale_asm9260_ek.cfg delete mode 100644 tcl/board/altera_sockit.cfg delete mode 100644 tcl/board/am3517evm.cfg delete mode 100644 tcl/board/arm_evaluator7t.cfg delete mode 100644 tcl/board/asus-rt-n16.cfg delete mode 100644 tcl/board/asus-rt-n66u.cfg delete mode 100644 tcl/board/at91cap7a-stk-sdram.cfg delete mode 100644 tcl/board/at91eb40a.cfg delete mode 100644 tcl/board/at91rm9200-dk.cfg delete mode 100644 tcl/board/at91rm9200-ek.cfg delete mode 100644 tcl/board/at91sam9261-ek.cfg delete mode 100644 tcl/board/at91sam9263-ek.cfg delete mode 100644 tcl/board/at91sam9g20-ek.cfg delete mode 100644 tcl/board/atmel_at91sam7s-ek.cfg delete mode 100644 tcl/board/atmel_at91sam9260-ek.cfg delete mode 100644 tcl/board/atmel_at91sam9rl-ek.cfg delete mode 100644 tcl/board/atmel_sam3n_ek.cfg delete mode 100644 tcl/board/atmel_sam3s_ek.cfg delete mode 100644 tcl/board/atmel_sam3u_ek.cfg delete mode 100644 tcl/board/atmel_sam3x_ek.cfg delete mode 100644 tcl/board/atmel_sam4e_ek.cfg delete mode 100644 tcl/board/atmel_sam4l8_xplained_pro.cfg delete mode 100644 tcl/board/atmel_sam4s_ek.cfg delete mode 100644 tcl/board/atmel_sam4s_xplained_pro.cfg delete mode 100644 tcl/board/atmel_samc20_xplained_pro.cfg delete mode 100644 tcl/board/atmel_samc21_xplained_pro.cfg delete mode 100644 tcl/board/atmel_samd20_xplained_pro.cfg delete mode 100644 tcl/board/atmel_samd21_xplained_pro.cfg delete mode 100644 tcl/board/atmel_same70_xplained.cfg delete mode 100644 tcl/board/atmel_samg53_xplained_pro.cfg delete mode 100644 tcl/board/atmel_saml21_xplained_pro.cfg delete mode 100644 tcl/board/atmel_samr21_xplained_pro.cfg delete mode 100644 tcl/board/atmel_samv71_xplained_ultra.cfg delete mode 100644 tcl/board/balloon3-cpu.cfg delete mode 100644 tcl/board/bcm28155_ap.cfg delete mode 100644 tcl/board/bt-homehubv1.cfg delete mode 100644 tcl/board/colibri.cfg delete mode 100644 tcl/board/crossbow_tech_imote2.cfg delete mode 100644 tcl/board/csb337.cfg delete mode 100644 tcl/board/csb732.cfg delete mode 100644 tcl/board/da850evm.cfg delete mode 100644 tcl/board/digi_connectcore_wi-9c.cfg delete mode 100644 tcl/board/digilent_analog_discovery.cfg delete mode 100644 tcl/board/digilent_atlys.cfg delete mode 100644 tcl/board/digilent_zedboard.cfg delete mode 100644 tcl/board/diolan_lpc4350-db1.cfg delete mode 100644 tcl/board/diolan_lpc4357-db1.cfg delete mode 100755 tcl/board/dk-tm4c129.cfg delete mode 100644 tcl/board/dm355evm.cfg delete mode 100644 tcl/board/dm365evm.cfg delete mode 100644 tcl/board/dm6446evm.cfg delete mode 100644 tcl/board/dp_busblaster_v3.cfg delete mode 100644 tcl/board/efikamx.cfg delete mode 100644 tcl/board/efm32.cfg delete mode 100644 tcl/board/eir.cfg delete mode 100644 tcl/board/ek-lm3s1968.cfg delete mode 100644 tcl/board/ek-lm3s3748.cfg delete mode 100644 tcl/board/ek-lm3s6965.cfg delete mode 100644 tcl/board/ek-lm3s811-revb.cfg delete mode 100644 tcl/board/ek-lm3s811.cfg delete mode 100644 tcl/board/ek-lm3s8962.cfg delete mode 100644 tcl/board/ek-lm3s9b9x.cfg delete mode 100644 tcl/board/ek-lm3s9d92.cfg delete mode 100644 tcl/board/ek-lm4f120xl.cfg delete mode 100644 tcl/board/ek-lm4f232.cfg delete mode 100644 tcl/board/ek-tm4c123gxl.cfg delete mode 100644 tcl/board/ek-tm4c1294xl.cfg delete mode 100644 tcl/board/embedded-artists_lpc2478-32.cfg delete mode 100644 tcl/board/emcraft_twr-vf6-som-bsb.cfg delete mode 100644 tcl/board/emcraft_vf6-som.cfg delete mode 100644 tcl/board/ethernut3.cfg delete mode 100644 tcl/board/frdm-kl25z.cfg delete mode 100644 tcl/board/frdm-kl46z.cfg delete mode 100644 tcl/board/fsl_imx6q_sabresd.cfg delete mode 100644 tcl/board/glyn_tonga2.cfg delete mode 100644 tcl/board/gumstix-aerocore.cfg delete mode 100644 tcl/board/hammer.cfg delete mode 100644 tcl/board/hilscher_nxdb500sys.cfg delete mode 100644 tcl/board/hilscher_nxeb500hmi.cfg delete mode 100644 tcl/board/hilscher_nxhx10.cfg delete mode 100644 tcl/board/hilscher_nxhx50.cfg delete mode 100644 tcl/board/hilscher_nxhx500.cfg delete mode 100644 tcl/board/hilscher_nxsb100.cfg delete mode 100644 tcl/board/hitex_lpc1768stick.cfg delete mode 100644 tcl/board/hitex_lpc2929.cfg delete mode 100644 tcl/board/hitex_stm32-performancestick.cfg delete mode 100644 tcl/board/hitex_str9-comstick.cfg delete mode 100644 tcl/board/iar_lpc1768.cfg delete mode 100644 tcl/board/iar_str912_sk.cfg delete mode 100644 tcl/board/icnova_imx53_sodimm.cfg delete mode 100644 tcl/board/icnova_sam9g45_sodimm.cfg delete mode 100644 tcl/board/imx27ads.cfg delete mode 100644 tcl/board/imx27lnst.cfg delete mode 100644 tcl/board/imx28evk.cfg delete mode 100644 tcl/board/imx31pdk.cfg delete mode 100644 tcl/board/imx35pdk.cfg delete mode 100644 tcl/board/imx53-m53evk.cfg delete mode 100644 tcl/board/imx53loco.cfg delete mode 100644 tcl/board/insignal_arndale.cfg delete mode 100644 tcl/board/kc705.cfg delete mode 100644 tcl/board/keil_mcb1700.cfg delete mode 100644 tcl/board/keil_mcb2140.cfg delete mode 100644 tcl/board/kwikstik.cfg delete mode 100644 tcl/board/la_fonera-fon2200.cfg delete mode 100644 tcl/board/linksys-wrt54gl.cfg delete mode 100644 tcl/board/linksys_nslu2.cfg delete mode 100644 tcl/board/lisa-l.cfg delete mode 100644 tcl/board/logicpd_imx27.cfg delete mode 100644 tcl/board/lpc1850_spifi_generic.cfg delete mode 100644 tcl/board/lpc4350_spifi_generic.cfg delete mode 100644 tcl/board/lubbock.cfg delete mode 100644 tcl/board/marsohod.cfg delete mode 100644 tcl/board/marsohod2.cfg delete mode 100644 tcl/board/marsohod3.cfg delete mode 100644 tcl/board/mbed-lpc11u24.cfg delete mode 100644 tcl/board/mbed-lpc1768.cfg delete mode 100644 tcl/board/mcb1700.cfg delete mode 100644 tcl/board/microchip_explorer16.cfg delete mode 100644 tcl/board/mini2440.cfg delete mode 100644 tcl/board/mini6410.cfg delete mode 100644 tcl/board/minispartan6.cfg delete mode 100644 tcl/board/nds32_xc5.cfg delete mode 100644 tcl/board/netgear-dg834v3.cfg delete mode 100644 tcl/board/netgear-wg102.cfg delete mode 100644 tcl/board/nordic_nrf51822_mkit.cfg delete mode 100644 tcl/board/numato_opsis.cfg delete mode 100644 tcl/board/nxp_lpc-link2.cfg delete mode 100644 tcl/board/olimex_LPC2378STK.cfg delete mode 100644 tcl/board/olimex_lpc_h2148.cfg delete mode 100644 tcl/board/olimex_sam7_ex256.cfg delete mode 100644 tcl/board/olimex_sam7_la2.cfg delete mode 100644 tcl/board/olimex_sam9_l9260.cfg delete mode 100644 tcl/board/olimex_stm32_h103.cfg delete mode 100644 tcl/board/olimex_stm32_h107.cfg delete mode 100644 tcl/board/olimex_stm32_p107.cfg delete mode 100644 tcl/board/omap2420_h4.cfg delete mode 100644 tcl/board/open-bldc.cfg delete mode 100644 tcl/board/openrd.cfg delete mode 100644 tcl/board/or1k_generic.cfg delete mode 100644 tcl/board/osk5912.cfg delete mode 100644 tcl/board/phone_se_j100i.cfg delete mode 100644 tcl/board/phytec_lpc3250.cfg delete mode 100644 tcl/board/pic-p32mx.cfg delete mode 100644 tcl/board/pipistrello.cfg delete mode 100644 tcl/board/propox_mmnet1001.cfg delete mode 100644 tcl/board/pxa255_sst.cfg delete mode 100644 tcl/board/quark_d2000_refboard.cfg delete mode 100644 tcl/board/quark_x10xx_board.cfg delete mode 100644 tcl/board/redbee.cfg delete mode 100644 tcl/board/renesas_dk-s7g2.cfg delete mode 100644 tcl/board/rsc-w910.cfg delete mode 100644 tcl/board/sheevaplug.cfg delete mode 100644 tcl/board/smdk6410.cfg delete mode 100644 tcl/board/spansion_sk-fm4-176l-s6e2cc.cfg delete mode 100644 tcl/board/spansion_sk-fm4-u120-9b560.cfg delete mode 100644 tcl/board/spear300evb.cfg delete mode 100644 tcl/board/spear300evb_mod.cfg delete mode 100644 tcl/board/spear310evb20.cfg delete mode 100644 tcl/board/spear310evb20_mod.cfg delete mode 100644 tcl/board/spear320cpu.cfg delete mode 100644 tcl/board/spear320cpu_mod.cfg delete mode 100644 tcl/board/st_nucleo_f0.cfg delete mode 100644 tcl/board/st_nucleo_f103rb.cfg delete mode 100644 tcl/board/st_nucleo_f3.cfg delete mode 100644 tcl/board/st_nucleo_f4.cfg delete mode 100644 tcl/board/st_nucleo_l1.cfg delete mode 100644 tcl/board/st_nucleo_l476rg.cfg delete mode 100644 tcl/board/steval_pcc010.cfg delete mode 100644 tcl/board/stm320518_eval.cfg delete mode 100644 tcl/board/stm320518_eval_stlink.cfg delete mode 100644 tcl/board/stm32100b_eval.cfg delete mode 100644 tcl/board/stm3210b_eval.cfg delete mode 100644 tcl/board/stm3210c_eval.cfg delete mode 100644 tcl/board/stm3210e_eval.cfg delete mode 100644 tcl/board/stm3220g_eval.cfg delete mode 100644 tcl/board/stm3220g_eval_stlink.cfg delete mode 100644 tcl/board/stm3241g_eval.cfg delete mode 100644 tcl/board/stm3241g_eval_stlink.cfg delete mode 100644 tcl/board/stm32429i_eval.cfg delete mode 100644 tcl/board/stm32429i_eval_stlink.cfg delete mode 100644 tcl/board/stm32439i_eval.cfg delete mode 100644 tcl/board/stm32439i_eval_stlink.cfg delete mode 100644 tcl/board/stm327x6g_eval.cfg delete mode 100644 tcl/board/stm32f0discovery.cfg delete mode 100644 tcl/board/stm32f334discovery.cfg delete mode 100644 tcl/board/stm32f3discovery.cfg delete mode 100644 tcl/board/stm32f429disc1.cfg delete mode 100644 tcl/board/stm32f429discovery.cfg delete mode 100644 tcl/board/stm32f469discovery.cfg delete mode 100644 tcl/board/stm32f4discovery.cfg delete mode 100755 tcl/board/stm32f7discovery.cfg delete mode 100644 tcl/board/stm32l0discovery.cfg delete mode 100644 tcl/board/stm32l4discovery.cfg delete mode 100644 tcl/board/stm32ldiscovery.cfg delete mode 100644 tcl/board/stm32vldiscovery.cfg delete mode 100644 tcl/board/str910-eval.cfg delete mode 100644 tcl/board/telo.cfg delete mode 100644 tcl/board/ti-cc3200-launchxl.cfg delete mode 100644 tcl/board/ti_am335xevm.cfg delete mode 100644 tcl/board/ti_am437x_idk.cfg delete mode 100644 tcl/board/ti_am43xx_evm.cfg delete mode 100644 tcl/board/ti_beagleboard.cfg delete mode 100644 tcl/board/ti_beagleboard_xm.cfg delete mode 100644 tcl/board/ti_beaglebone.cfg delete mode 100644 tcl/board/ti_blaze.cfg delete mode 100644 tcl/board/ti_pandaboard.cfg delete mode 100644 tcl/board/ti_pandaboard_es.cfg delete mode 100644 tcl/board/ti_tmdx570ls20susb.cfg delete mode 100644 tcl/board/ti_tmdx570ls31usb.cfg delete mode 100644 tcl/board/topas910.cfg delete mode 100644 tcl/board/topasa900.cfg delete mode 100644 tcl/board/tp-link_tl-mr3020.cfg delete mode 100644 tcl/board/twr-k60f120m.cfg delete mode 100644 tcl/board/twr-k60n512.cfg delete mode 100644 tcl/board/tx25_stk5.cfg delete mode 100644 tcl/board/tx27_stk5.cfg delete mode 100644 tcl/board/unknown_at91sam9260.cfg delete mode 100644 tcl/board/uptech_2410.cfg delete mode 100644 tcl/board/verdex.cfg delete mode 100644 tcl/board/voipac.cfg delete mode 100644 tcl/board/voltcraft_dso-3062c.cfg delete mode 100644 tcl/board/x300t.cfg delete mode 100644 tcl/board/xmc-2go.cfg delete mode 100644 tcl/board/xmc1100-boot-kit.cfg delete mode 100644 tcl/board/xmc4200-application-kit-actuator.cfg delete mode 100644 tcl/board/xmc4500-application-kit-general.cfg delete mode 100644 tcl/board/xmc4500-application-kit-sdram.cfg delete mode 100644 tcl/board/xmc4500-relax.cfg delete mode 100644 tcl/board/xmc4700-relax.cfg delete mode 100644 tcl/board/xmc4800-relax.cfg delete mode 100644 tcl/board/xmos_xk-xac-xa8_arm.cfg delete mode 100644 tcl/board/zy1000.cfg delete mode 100644 tcl/chip/atmel/at91/aic.tcl delete mode 100644 tcl/chip/atmel/at91/at91_pio.cfg delete mode 100644 tcl/chip/atmel/at91/at91_pmc.cfg delete mode 100644 tcl/chip/atmel/at91/at91_rstc.cfg delete mode 100644 tcl/chip/atmel/at91/at91_wdt.cfg delete mode 100644 tcl/chip/atmel/at91/at91sam7x128.tcl delete mode 100644 tcl/chip/atmel/at91/at91sam7x256.tcl delete mode 100644 tcl/chip/atmel/at91/at91sam9261.cfg delete mode 100644 tcl/chip/atmel/at91/at91sam9261_matrix.cfg delete mode 100644 tcl/chip/atmel/at91/at91sam9263.cfg delete mode 100644 tcl/chip/atmel/at91/at91sam9263_matrix.cfg delete mode 100644 tcl/chip/atmel/at91/at91sam9_init.cfg delete mode 100644 tcl/chip/atmel/at91/at91sam9_sdramc.cfg delete mode 100644 tcl/chip/atmel/at91/at91sam9_smc.cfg delete mode 100644 tcl/chip/atmel/at91/hardware.cfg delete mode 100644 tcl/chip/atmel/at91/pmc.tcl delete mode 100644 tcl/chip/atmel/at91/rtt.tcl delete mode 100644 tcl/chip/atmel/at91/sam9_smc.cfg delete mode 100644 tcl/chip/atmel/at91/usarts.tcl delete mode 100644 tcl/chip/st/spear/quirk_no_srst.tcl delete mode 100644 tcl/chip/st/spear/spear3xx.tcl delete mode 100644 tcl/chip/st/spear/spear3xx_ddr.tcl delete mode 100644 tcl/chip/st/stm32/stm32.tcl delete mode 100644 tcl/chip/st/stm32/stm32_rcc.tcl delete mode 100644 tcl/chip/st/stm32/stm32_regs.tcl delete mode 100644 tcl/chip/ti/lm3s/lm3s.tcl delete mode 100644 tcl/chip/ti/lm3s/lm3s_regs.tcl delete mode 100644 tcl/cpld/altera-epm240.cfg delete mode 100644 tcl/cpld/jtagspi.cfg delete mode 100644 tcl/cpld/lattice-lc4032ze.cfg delete mode 100644 tcl/cpld/xilinx-xc6s.cfg delete mode 100644 tcl/cpld/xilinx-xc7.cfg delete mode 100644 tcl/cpld/xilinx-xcr3256.cfg delete mode 100644 tcl/cpu/arm/arm7tdmi.tcl delete mode 100644 tcl/cpu/arm/arm920.tcl delete mode 100644 tcl/cpu/arm/arm946.tcl delete mode 100644 tcl/cpu/arm/arm966.tcl delete mode 100644 tcl/cpu/arm/cortex_m3.tcl delete mode 100644 tcl/fpga/altera-10m50.cfg delete mode 100644 tcl/fpga/altera-ep3c10.cfg delete mode 100644 tcl/interface/altera-usb-blaster.cfg delete mode 100644 tcl/interface/altera-usb-blaster2.cfg delete mode 100644 tcl/interface/arm-jtag-ew.cfg delete mode 100644 tcl/interface/at91rm9200.cfg delete mode 100644 tcl/interface/axm0432.cfg delete mode 100644 tcl/interface/busblaster.cfg delete mode 100644 tcl/interface/buspirate.cfg delete mode 100644 tcl/interface/calao-usb-a9260-c01.cfg delete mode 100644 tcl/interface/calao-usb-a9260-c02.cfg delete mode 100644 tcl/interface/calao-usb-a9260.cfg delete mode 100644 tcl/interface/chameleon.cfg delete mode 100644 tcl/interface/cmsis-dap.cfg delete mode 100644 tcl/interface/cortino.cfg delete mode 100644 tcl/interface/digilent-hs1.cfg delete mode 100644 tcl/interface/dlp-usb1232h.cfg delete mode 100644 tcl/interface/dummy.cfg delete mode 100644 tcl/interface/estick.cfg delete mode 100644 tcl/interface/flashlink.cfg delete mode 100644 tcl/interface/flossjtag-noeeprom.cfg delete mode 100644 tcl/interface/flossjtag.cfg delete mode 100644 tcl/interface/flyswatter.cfg delete mode 100644 tcl/interface/flyswatter2.cfg delete mode 100644 tcl/interface/ftdi/100ask-openjtag.cfg delete mode 100644 tcl/interface/ftdi/axm0432.cfg delete mode 100644 tcl/interface/ftdi/calao-usb-a9260-c01.cfg delete mode 100644 tcl/interface/ftdi/calao-usb-a9260-c02.cfg delete mode 100644 tcl/interface/ftdi/cortino.cfg delete mode 100644 tcl/interface/ftdi/digilent-hs1.cfg delete mode 100644 tcl/interface/ftdi/digilent-hs2.cfg delete mode 100644 tcl/interface/ftdi/digilent_jtag_hs3.cfg delete mode 100644 tcl/interface/ftdi/digilent_jtag_smt2.cfg delete mode 100644 tcl/interface/ftdi/dlp-usb1232h.cfg delete mode 100644 tcl/interface/ftdi/dp_busblaster.cfg delete mode 100644 tcl/interface/ftdi/dp_busblaster_kt-link.cfg delete mode 100644 tcl/interface/ftdi/flossjtag-noeeprom.cfg delete mode 100644 tcl/interface/ftdi/flossjtag.cfg delete mode 100644 tcl/interface/ftdi/flyswatter.cfg delete mode 100644 tcl/interface/ftdi/flyswatter2.cfg delete mode 100644 tcl/interface/ftdi/gw16042.cfg delete mode 100644 tcl/interface/ftdi/hilscher_nxhx10_etm.cfg delete mode 100644 tcl/interface/ftdi/hilscher_nxhx500_etm.cfg delete mode 100644 tcl/interface/ftdi/hilscher_nxhx500_re.cfg delete mode 100644 tcl/interface/ftdi/hilscher_nxhx50_etm.cfg delete mode 100644 tcl/interface/ftdi/hilscher_nxhx50_re.cfg delete mode 100644 tcl/interface/ftdi/hitex_lpc1768stick.cfg delete mode 100644 tcl/interface/ftdi/hitex_str9-comstick.cfg delete mode 100644 tcl/interface/ftdi/icebear.cfg delete mode 100644 tcl/interface/ftdi/iotlab-usb.cfg delete mode 100644 tcl/interface/ftdi/jtag-lock-pick_tiny_2.cfg delete mode 100644 tcl/interface/ftdi/jtagkey.cfg delete mode 100644 tcl/interface/ftdi/jtagkey2.cfg delete mode 100644 tcl/interface/ftdi/jtagkey2p.cfg delete mode 100644 tcl/interface/ftdi/kt-link.cfg delete mode 100644 tcl/interface/ftdi/lisa-l.cfg delete mode 100644 tcl/interface/ftdi/luminary-icdi.cfg delete mode 100644 tcl/interface/ftdi/luminary-lm3s811.cfg delete mode 100644 tcl/interface/ftdi/luminary.cfg delete mode 100644 tcl/interface/ftdi/m53evk.cfg delete mode 100644 tcl/interface/ftdi/mbftdi.cfg delete mode 100644 tcl/interface/ftdi/minimodule.cfg delete mode 100644 tcl/interface/ftdi/minispartan6.cfg delete mode 100644 tcl/interface/ftdi/neodb.cfg delete mode 100644 tcl/interface/ftdi/ngxtech.cfg delete mode 100644 tcl/interface/ftdi/olimex-arm-jtag-swd.cfg delete mode 100644 tcl/interface/ftdi/olimex-arm-usb-ocd-h.cfg delete mode 100644 tcl/interface/ftdi/olimex-arm-usb-ocd.cfg delete mode 100644 tcl/interface/ftdi/olimex-arm-usb-tiny-h.cfg delete mode 100644 tcl/interface/ftdi/olimex-jtag-tiny.cfg delete mode 100644 tcl/interface/ftdi/oocdlink.cfg delete mode 100644 tcl/interface/ftdi/opendous_ftdi.cfg delete mode 100644 tcl/interface/ftdi/openocd-usb-hs.cfg delete mode 100644 tcl/interface/ftdi/openocd-usb.cfg delete mode 100644 tcl/interface/ftdi/openrd.cfg delete mode 100644 tcl/interface/ftdi/pipistrello.cfg delete mode 100644 tcl/interface/ftdi/redbee-econotag.cfg delete mode 100644 tcl/interface/ftdi/redbee-usb.cfg delete mode 100644 tcl/interface/ftdi/rowley-cc-arm-swd.cfg delete mode 100644 tcl/interface/ftdi/sheevaplug.cfg delete mode 100644 tcl/interface/ftdi/signalyzer-lite.cfg delete mode 100644 tcl/interface/ftdi/signalyzer.cfg delete mode 100644 tcl/interface/ftdi/stm32-stick.cfg delete mode 100644 tcl/interface/ftdi/swd-resistor-hack.cfg delete mode 100644 tcl/interface/ftdi/ti-icdi.cfg delete mode 100644 tcl/interface/ftdi/tumpa-lite.cfg delete mode 100644 tcl/interface/ftdi/tumpa.cfg delete mode 100644 tcl/interface/ftdi/turtelizer2-revB.cfg delete mode 100644 tcl/interface/ftdi/turtelizer2-revC.cfg delete mode 100644 tcl/interface/ftdi/um232h.cfg delete mode 100644 tcl/interface/ftdi/vpaclink.cfg delete mode 100644 tcl/interface/ftdi/xds100v2.cfg delete mode 100644 tcl/interface/ftdi/xds100v3.cfg delete mode 100644 tcl/interface/hilscher_nxhx10_etm.cfg delete mode 100644 tcl/interface/hilscher_nxhx500_etm.cfg delete mode 100644 tcl/interface/hilscher_nxhx500_re.cfg delete mode 100644 tcl/interface/hilscher_nxhx50_etm.cfg delete mode 100644 tcl/interface/hilscher_nxhx50_re.cfg delete mode 100644 tcl/interface/hitex_str9-comstick.cfg delete mode 100644 tcl/interface/icebear.cfg delete mode 100644 tcl/interface/jlink.cfg delete mode 100644 tcl/interface/jtag-lock-pick_tiny_2.cfg delete mode 100644 tcl/interface/jtag_vpi.cfg delete mode 100644 tcl/interface/jtagkey-tiny.cfg delete mode 100644 tcl/interface/jtagkey.cfg delete mode 100644 tcl/interface/jtagkey2.cfg delete mode 100644 tcl/interface/jtagkey2p.cfg delete mode 100644 tcl/interface/kt-link.cfg delete mode 100644 tcl/interface/lisa-l.cfg delete mode 100644 tcl/interface/luminary-icdi.cfg delete mode 100644 tcl/interface/luminary-lm3s811.cfg delete mode 100644 tcl/interface/luminary.cfg delete mode 100644 tcl/interface/minimodule.cfg delete mode 100644 tcl/interface/nds32-aice.cfg delete mode 100644 tcl/interface/neodb.cfg delete mode 100644 tcl/interface/ngxtech.cfg delete mode 100644 tcl/interface/olimex-arm-usb-ocd-h.cfg delete mode 100644 tcl/interface/olimex-arm-usb-ocd.cfg delete mode 100644 tcl/interface/olimex-arm-usb-tiny-h.cfg delete mode 100644 tcl/interface/olimex-jtag-tiny.cfg delete mode 100644 tcl/interface/oocdlink.cfg delete mode 100644 tcl/interface/opendous.cfg delete mode 100644 tcl/interface/opendous_ftdi.cfg delete mode 100644 tcl/interface/openjtag.cfg delete mode 100644 tcl/interface/openocd-usb-hs.cfg delete mode 100644 tcl/interface/openocd-usb.cfg delete mode 100644 tcl/interface/openrd.cfg delete mode 100644 tcl/interface/osbdm.cfg delete mode 100644 tcl/interface/parport.cfg delete mode 100644 tcl/interface/parport_dlc5.cfg delete mode 100644 tcl/interface/raspberrypi-native.cfg delete mode 100644 tcl/interface/raspberrypi2-native.cfg delete mode 100644 tcl/interface/redbee-econotag.cfg delete mode 100644 tcl/interface/redbee-usb.cfg delete mode 100644 tcl/interface/rlink.cfg delete mode 100644 tcl/interface/sheevaplug.cfg delete mode 100644 tcl/interface/signalyzer-h2.cfg delete mode 100644 tcl/interface/signalyzer-h4.cfg delete mode 100644 tcl/interface/signalyzer-lite.cfg delete mode 100644 tcl/interface/signalyzer.cfg delete mode 100644 tcl/interface/stlink-v1.cfg delete mode 100644 tcl/interface/stlink-v2-1.cfg delete mode 100644 tcl/interface/stlink-v2.cfg delete mode 100644 tcl/interface/stm32-stick.cfg delete mode 100644 tcl/interface/sysfsgpio-raspberrypi.cfg delete mode 100644 tcl/interface/ti-icdi.cfg delete mode 100644 tcl/interface/turtelizer2.cfg delete mode 100644 tcl/interface/ulink.cfg delete mode 100644 tcl/interface/usb-jtag.cfg delete mode 100644 tcl/interface/usbprog.cfg delete mode 100644 tcl/interface/vpaclink.cfg delete mode 100644 tcl/interface/vsllink.cfg delete mode 100644 tcl/interface/xds100v2.cfg delete mode 100644 tcl/mem_helper.tcl delete mode 100644 tcl/memory.tcl delete mode 100644 tcl/mmr_helpers.tcl delete mode 100644 tcl/target/1986ве1т.cfg delete mode 100644 tcl/target/aduc702x.cfg delete mode 100755 tcl/target/aducm360.cfg delete mode 100644 tcl/target/alphascale_asm9260t.cfg delete mode 100644 tcl/target/altera_fpgasoc.cfg delete mode 100644 tcl/target/am335x.cfg delete mode 100644 tcl/target/am437x.cfg delete mode 100644 tcl/target/amdm37x.cfg delete mode 100644 tcl/target/ar71xx.cfg delete mode 100644 tcl/target/armada370.cfg delete mode 100644 tcl/target/at32ap7000.cfg delete mode 100644 tcl/target/at91r40008.cfg delete mode 100644 tcl/target/at91rm9200.cfg delete mode 100644 tcl/target/at91sam3XXX.cfg delete mode 100644 tcl/target/at91sam3ax_4x.cfg delete mode 100644 tcl/target/at91sam3ax_8x.cfg delete mode 100644 tcl/target/at91sam3ax_xx.cfg delete mode 100644 tcl/target/at91sam3nXX.cfg delete mode 100644 tcl/target/at91sam3sXX.cfg delete mode 100644 tcl/target/at91sam3u1c.cfg delete mode 100644 tcl/target/at91sam3u1e.cfg delete mode 100644 tcl/target/at91sam3u2c.cfg delete mode 100644 tcl/target/at91sam3u2e.cfg delete mode 100644 tcl/target/at91sam3u4c.cfg delete mode 100644 tcl/target/at91sam3u4e.cfg delete mode 100644 tcl/target/at91sam3uxx.cfg delete mode 100644 tcl/target/at91sam4XXX.cfg delete mode 100644 tcl/target/at91sam4lXX.cfg delete mode 100644 tcl/target/at91sam4sXX.cfg delete mode 100644 tcl/target/at91sam4sd32x.cfg delete mode 100644 tcl/target/at91sam7a2.cfg delete mode 100644 tcl/target/at91sam7se512.cfg delete mode 100644 tcl/target/at91sam7sx.cfg delete mode 100644 tcl/target/at91sam7x256.cfg delete mode 100644 tcl/target/at91sam7x512.cfg delete mode 100644 tcl/target/at91sam9.cfg delete mode 100644 tcl/target/at91sam9260.cfg delete mode 100644 tcl/target/at91sam9260_ext_RAM_ext_flash.cfg delete mode 100644 tcl/target/at91sam9261.cfg delete mode 100644 tcl/target/at91sam9263.cfg delete mode 100644 tcl/target/at91sam9g10.cfg delete mode 100644 tcl/target/at91sam9g20.cfg delete mode 100644 tcl/target/at91sam9g45.cfg delete mode 100644 tcl/target/at91sam9rl.cfg delete mode 100644 tcl/target/at91samdXX.cfg delete mode 100644 tcl/target/at91samg5x.cfg delete mode 100644 tcl/target/atheros_ar2313.cfg delete mode 100644 tcl/target/atheros_ar2315.cfg delete mode 100644 tcl/target/atheros_ar9331.cfg delete mode 100644 tcl/target/atmega128.cfg delete mode 100644 tcl/target/atsamv.cfg delete mode 100644 tcl/target/avr32.cfg delete mode 100644 tcl/target/bcm281xx.cfg delete mode 100644 tcl/target/bcm4706.cfg delete mode 100644 tcl/target/bcm4718.cfg delete mode 100644 tcl/target/bcm47xx.cfg delete mode 100644 tcl/target/bcm5352e.cfg delete mode 100644 tcl/target/bcm6348.cfg delete mode 100644 tcl/target/c100.cfg delete mode 100644 tcl/target/c100config.tcl delete mode 100644 tcl/target/c100helper.tcl delete mode 100644 tcl/target/c100regs.tcl delete mode 100755 tcl/target/cc2538.cfg delete mode 100755 tcl/target/cc26xx.cfg delete mode 100755 tcl/target/cc32xx.cfg delete mode 100644 tcl/target/cs351x.cfg delete mode 100644 tcl/target/davinci.cfg delete mode 100644 tcl/target/dragonite.cfg delete mode 100644 tcl/target/dsp56321.cfg delete mode 100644 tcl/target/dsp568013.cfg delete mode 100644 tcl/target/dsp568037.cfg delete mode 100644 tcl/target/efm32.cfg delete mode 100644 tcl/target/efm32_stlink.cfg delete mode 100644 tcl/target/em357.cfg delete mode 100644 tcl/target/em358.cfg delete mode 100644 tcl/target/epc9301.cfg delete mode 100644 tcl/target/exynos5250.cfg delete mode 100644 tcl/target/faux.cfg delete mode 100644 tcl/target/feroceon.cfg delete mode 100644 tcl/target/fm3.cfg delete mode 100644 tcl/target/fm4.cfg delete mode 100644 tcl/target/fm4_mb9bf.cfg delete mode 100644 tcl/target/fm4_s6e2cc.cfg delete mode 100644 tcl/target/gp326xxxa.cfg delete mode 100644 tcl/target/hilscher_netx10.cfg delete mode 100644 tcl/target/hilscher_netx50.cfg delete mode 100644 tcl/target/hilscher_netx500.cfg delete mode 100644 tcl/target/icepick.cfg delete mode 100644 tcl/target/imx.cfg delete mode 100644 tcl/target/imx21.cfg delete mode 100644 tcl/target/imx25.cfg delete mode 100644 tcl/target/imx27.cfg delete mode 100644 tcl/target/imx28.cfg delete mode 100644 tcl/target/imx31.cfg delete mode 100644 tcl/target/imx35.cfg delete mode 100644 tcl/target/imx51.cfg delete mode 100644 tcl/target/imx53.cfg delete mode 100644 tcl/target/imx6.cfg delete mode 100644 tcl/target/is5114.cfg delete mode 100644 tcl/target/ixp42x.cfg delete mode 100755 tcl/target/k1921vk01t.cfg delete mode 100644 tcl/target/k40.cfg delete mode 100644 tcl/target/k60.cfg delete mode 100644 tcl/target/ke02.cfg delete mode 100644 tcl/target/ke04.cfg delete mode 100644 tcl/target/ke06.cfg delete mode 100644 tcl/target/kex.cfg delete mode 100644 tcl/target/kl25.cfg delete mode 100644 tcl/target/kl25z_hla.cfg delete mode 100644 tcl/target/kl46.cfg delete mode 100644 tcl/target/klx.cfg delete mode 100644 tcl/target/ks869x.cfg delete mode 100644 tcl/target/kx.cfg delete mode 100644 tcl/target/lpc11xx.cfg delete mode 100644 tcl/target/lpc12xx.cfg delete mode 100644 tcl/target/lpc13xx.cfg delete mode 100644 tcl/target/lpc17xx.cfg delete mode 100644 tcl/target/lpc1850.cfg delete mode 100644 tcl/target/lpc1xxx.cfg delete mode 100644 tcl/target/lpc2103.cfg delete mode 100644 tcl/target/lpc2124.cfg delete mode 100644 tcl/target/lpc2129.cfg delete mode 100644 tcl/target/lpc2148.cfg delete mode 100644 tcl/target/lpc2294.cfg delete mode 100644 tcl/target/lpc2378.cfg delete mode 100644 tcl/target/lpc2460.cfg delete mode 100644 tcl/target/lpc2478.cfg delete mode 100644 tcl/target/lpc2900.cfg delete mode 100644 tcl/target/lpc2xxx.cfg delete mode 100644 tcl/target/lpc3131.cfg delete mode 100644 tcl/target/lpc3250.cfg delete mode 100644 tcl/target/lpc40xx.cfg delete mode 100644 tcl/target/lpc4350.cfg delete mode 100644 tcl/target/lpc4357.cfg delete mode 100644 tcl/target/lpc4370.cfg delete mode 100644 tcl/target/lpc8xx.cfg delete mode 100644 tcl/target/mc13224v.cfg delete mode 100644 tcl/target/mdr32f9q2i.cfg delete mode 100644 tcl/target/nds32v2.cfg delete mode 100644 tcl/target/nds32v3.cfg delete mode 100644 tcl/target/nds32v3m.cfg delete mode 100644 tcl/target/nrf51.cfg delete mode 100644 tcl/target/nrf51_stlink.tcl delete mode 100644 tcl/target/nrf52.cfg delete mode 100644 tcl/target/nuc910.cfg delete mode 100644 tcl/target/numicro.cfg delete mode 100644 tcl/target/omap2420.cfg delete mode 100644 tcl/target/omap3530.cfg delete mode 100644 tcl/target/omap4430.cfg delete mode 100644 tcl/target/omap4460.cfg delete mode 100644 tcl/target/omap5912.cfg delete mode 100644 tcl/target/omapl138.cfg delete mode 100644 tcl/target/or1k.cfg delete mode 100644 tcl/target/pic32mx.cfg delete mode 100644 tcl/target/psoc4.cfg delete mode 100644 tcl/target/psoc5lp.cfg delete mode 100644 tcl/target/pxa255.cfg delete mode 100644 tcl/target/pxa270.cfg delete mode 100644 tcl/target/pxa3xx.cfg delete mode 100644 tcl/target/quark_d20xx.cfg delete mode 100644 tcl/target/quark_x10xx.cfg delete mode 100644 tcl/target/readme.txt delete mode 100644 tcl/target/renesas_s7g2.cfg delete mode 100644 tcl/target/samsung_s3c2410.cfg delete mode 100644 tcl/target/samsung_s3c2440.cfg delete mode 100644 tcl/target/samsung_s3c2450.cfg delete mode 100644 tcl/target/samsung_s3c4510.cfg delete mode 100644 tcl/target/samsung_s3c6410.cfg delete mode 100644 tcl/target/sharp_lh79532.cfg delete mode 100755 tcl/target/sim3x.cfg delete mode 100644 tcl/target/smp8634.cfg delete mode 100644 tcl/target/spear3xx.cfg delete mode 100644 tcl/target/stellaris.cfg delete mode 100644 tcl/target/stellaris_icdi.cfg delete mode 100644 tcl/target/stm32_stlink.cfg delete mode 100644 tcl/target/stm32f0x.cfg delete mode 100644 tcl/target/stm32f0x_stlink.cfg delete mode 100644 tcl/target/stm32f1x.cfg delete mode 100644 tcl/target/stm32f1x_stlink.cfg delete mode 100644 tcl/target/stm32f2x.cfg delete mode 100644 tcl/target/stm32f2x_stlink.cfg delete mode 100644 tcl/target/stm32f3x.cfg delete mode 100644 tcl/target/stm32f3x_stlink.cfg delete mode 100644 tcl/target/stm32f4x.cfg delete mode 100644 tcl/target/stm32f4x_stlink.cfg delete mode 100755 tcl/target/stm32f7x.cfg delete mode 100644 tcl/target/stm32l0.cfg delete mode 100644 tcl/target/stm32l1.cfg delete mode 100644 tcl/target/stm32l1x_dual_bank.cfg delete mode 100644 tcl/target/stm32l4x.cfg delete mode 100644 tcl/target/stm32lx_stlink.cfg delete mode 100644 tcl/target/stm32w108_stlink.cfg delete mode 100644 tcl/target/stm32w108xx.cfg delete mode 100644 tcl/target/stm32xl.cfg delete mode 100644 tcl/target/str710.cfg delete mode 100644 tcl/target/str730.cfg delete mode 100644 tcl/target/str750.cfg delete mode 100644 tcl/target/str912.cfg delete mode 100644 tcl/target/swj-dp.tcl delete mode 100644 tcl/target/test_reset_syntax_error.cfg delete mode 100644 tcl/target/test_syntax_error.cfg delete mode 100644 tcl/target/ti-ar7.cfg delete mode 100755 tcl/target/ti-cjtag.cfg delete mode 100644 tcl/target/ti_calypso.cfg delete mode 100644 tcl/target/ti_dm355.cfg delete mode 100644 tcl/target/ti_dm365.cfg delete mode 100644 tcl/target/ti_dm6446.cfg delete mode 100644 tcl/target/ti_msp432p4xx.cfg delete mode 100644 tcl/target/ti_rm4x.cfg delete mode 100644 tcl/target/ti_tms570.cfg delete mode 100644 tcl/target/ti_tms570ls20xxx.cfg delete mode 100644 tcl/target/ti_tms570ls3137.cfg delete mode 100644 tcl/target/tmpa900.cfg delete mode 100644 tcl/target/tmpa910.cfg delete mode 100644 tcl/target/u8500.cfg delete mode 100644 tcl/target/vybrid_vf6xx.cfg delete mode 100644 tcl/target/xmc1xxx.cfg delete mode 100644 tcl/target/xmc4xxx.cfg delete mode 100644 tcl/target/xmos_xs1-xau8a-10_arm.cfg delete mode 100644 tcl/target/zynq_7000.cfg delete mode 100644 tcl/target/к1879xб1я.cfg delete mode 100755 tcl/test/selftest.cfg delete mode 100644 tcl/test/syntax1.cfg delete mode 100644 tcl/tools/firmware-recovery.tcl delete mode 100644 tcl/tools/memtest.tcl delete mode 100644 testing/build.test1/Makefile delete mode 100644 testing/build.test1/Makefile.confuse delete mode 100644 testing/build.test1/Makefile.ftd2xx delete mode 100644 testing/build.test1/Makefile.libftdi delete mode 100644 testing/build.test1/Makefile.libusb delete mode 100644 testing/build.test1/Makefile.openocd delete mode 100644 testing/build.test1/README.TXT delete mode 100644 testing/build.test1/local.uses delete mode 100644 testing/build.test1/mingw32_help/include/elf.h delete mode 100644 testing/build.test1/mingw32_help/include/sys/cdefs.h delete mode 100644 testing/build.test1/mingw32_help/include/sys/elf32.h delete mode 100644 testing/build.test1/mingw32_help/include/sys/elf64.h delete mode 100644 testing/build.test1/mingw32_help/include/sys/elf_common.h delete mode 100644 testing/build.test1/mingw32_help/include/sys/elf_generic.h delete mode 100644 testing/build.test2/Makefile delete mode 100644 testing/build.test2/README.txt delete mode 100644 testing/build.test2/local.uses delete mode 100644 testing/examples/AT91R40008Test/inc/typedefs.h delete mode 100644 testing/examples/AT91R40008Test/makefile delete mode 100644 testing/examples/AT91R40008Test/prj/at91r40008_reset.script delete mode 100644 testing/examples/AT91R40008Test/prj/at91r40008_turtle.cfg delete mode 100644 testing/examples/AT91R40008Test/prj/eclipse_ram.gdb delete mode 100644 testing/examples/AT91R40008Test/prj/ethernut3_ram.ld delete mode 100644 testing/examples/AT91R40008Test/src/crt.s delete mode 100644 testing/examples/AT91R40008Test/src/main.c delete mode 100644 testing/examples/AT91R40008Test/test_ram.elf delete mode 100644 testing/examples/AT91R40008Test/test_ram.hex delete mode 100644 testing/examples/AT91R40008Test/test_ram.map delete mode 100644 testing/examples/LPC2148Test/inc/typedefs.h delete mode 100644 testing/examples/LPC2148Test/makefile delete mode 100644 testing/examples/LPC2148Test/prj/eclipse_ram.gdb delete mode 100644 testing/examples/LPC2148Test/prj/eclipse_rom.gdb delete mode 100644 testing/examples/LPC2148Test/prj/lpc2148_jtagkey.cfg delete mode 100644 testing/examples/LPC2148Test/prj/lpc2148_ram.ld delete mode 100644 testing/examples/LPC2148Test/prj/lpc2148_rom.ld delete mode 100644 testing/examples/LPC2148Test/src/crt.s delete mode 100644 testing/examples/LPC2148Test/src/main.c delete mode 100644 testing/examples/LPC2148Test/test_ram.elf delete mode 100644 testing/examples/LPC2148Test/test_ram.hex delete mode 100644 testing/examples/LPC2148Test/test_ram.map delete mode 100644 testing/examples/LPC2148Test/test_rom.elf delete mode 100644 testing/examples/LPC2148Test/test_rom.hex delete mode 100644 testing/examples/LPC2148Test/test_rom.map delete mode 100644 testing/examples/LPC2294Test/inc/typedefs.h delete mode 100644 testing/examples/LPC2294Test/makefile delete mode 100644 testing/examples/LPC2294Test/prj/eclipse_ram.gdb delete mode 100644 testing/examples/LPC2294Test/prj/eclipse_rom.gdb delete mode 100644 testing/examples/LPC2294Test/prj/lpc2294_jtagkey.cfg delete mode 100644 testing/examples/LPC2294Test/prj/lpc2294_ram.ld delete mode 100644 testing/examples/LPC2294Test/prj/lpc2294_rom.ld delete mode 100644 testing/examples/LPC2294Test/src/crt.s delete mode 100644 testing/examples/LPC2294Test/src/main.c delete mode 100644 testing/examples/LPC2294Test/test_ram.elf delete mode 100644 testing/examples/LPC2294Test/test_ram.hex delete mode 100644 testing/examples/LPC2294Test/test_ram.map delete mode 100644 testing/examples/LPC2294Test/test_rom.elf delete mode 100644 testing/examples/LPC2294Test/test_rom.hex delete mode 100644 testing/examples/LPC2294Test/test_rom.map delete mode 100644 testing/examples/PIC32/BlinkingLeds.c delete mode 100644 testing/examples/PIC32/BlinkingLeds.elf delete mode 100644 testing/examples/PIC32/readme.txt delete mode 100644 testing/examples/SAM7S256Test/inc/typedefs.h delete mode 100644 testing/examples/SAM7S256Test/makefile delete mode 100644 testing/examples/SAM7S256Test/prj/eclipse_ram.gdb delete mode 100644 testing/examples/SAM7S256Test/prj/eclipse_rom.gdb delete mode 100644 testing/examples/SAM7S256Test/prj/sam7s256_jtagkey.cfg delete mode 100644 testing/examples/SAM7S256Test/prj/sam7s256_ram.ld delete mode 100644 testing/examples/SAM7S256Test/prj/sam7s256_reset.script delete mode 100644 testing/examples/SAM7S256Test/prj/sam7s256_rom.ld delete mode 100644 testing/examples/SAM7S256Test/results/607.html delete mode 100644 testing/examples/SAM7S256Test/src/crt.s delete mode 100644 testing/examples/SAM7S256Test/src/main.c delete mode 100644 testing/examples/SAM7S256Test/test_ram.elf delete mode 100644 testing/examples/SAM7S256Test/test_ram.hex delete mode 100644 testing/examples/SAM7S256Test/test_ram.map delete mode 100644 testing/examples/SAM7S256Test/test_rom.elf delete mode 100644 testing/examples/SAM7S256Test/test_rom.hex delete mode 100644 testing/examples/SAM7S256Test/test_rom.map delete mode 100644 testing/examples/SAM7X256Test/inc/typedefs.h delete mode 100644 testing/examples/SAM7X256Test/makefile delete mode 100644 testing/examples/SAM7X256Test/prj/eclipse_ram.gdb delete mode 100644 testing/examples/SAM7X256Test/prj/eclipse_rom.gdb delete mode 100644 testing/examples/SAM7X256Test/prj/sam7x256_jtagkey.cfg delete mode 100644 testing/examples/SAM7X256Test/prj/sam7x256_ram.ld delete mode 100644 testing/examples/SAM7X256Test/prj/sam7x256_reset.script delete mode 100644 testing/examples/SAM7X256Test/prj/sam7x256_rom.ld delete mode 100644 testing/examples/SAM7X256Test/src/crt.s delete mode 100644 testing/examples/SAM7X256Test/src/main.c delete mode 100644 testing/examples/SAM7X256Test/test_ram.elf delete mode 100644 testing/examples/SAM7X256Test/test_ram.hex delete mode 100644 testing/examples/SAM7X256Test/test_ram.map delete mode 100644 testing/examples/SAM7X256Test/test_rom.elf delete mode 100644 testing/examples/SAM7X256Test/test_rom.hex delete mode 100644 testing/examples/SAM7X256Test/test_rom.map delete mode 100644 testing/examples/STM32-103/main.elf delete mode 100644 testing/examples/STM32-103/readme.txt delete mode 100644 testing/examples/STR710JtagSpeed/inc/typedefs.h delete mode 100644 testing/examples/STR710JtagSpeed/makefile delete mode 100644 testing/examples/STR710JtagSpeed/prj/eclipse_ft2232_ram.gdb delete mode 100644 testing/examples/STR710JtagSpeed/prj/str710_jtagkey.cfg delete mode 100644 testing/examples/STR710JtagSpeed/prj/str7_ram.ld delete mode 100644 testing/examples/STR710JtagSpeed/src/crt.s delete mode 100644 testing/examples/STR710JtagSpeed/src/main.c delete mode 100644 testing/examples/STR710JtagSpeed/test.elf delete mode 100644 testing/examples/STR710JtagSpeed/test.hex delete mode 100644 testing/examples/STR710JtagSpeed/test.map delete mode 100644 testing/examples/STR710Test/.gitignore delete mode 100644 testing/examples/STR710Test/inc/typedefs.h delete mode 100644 testing/examples/STR710Test/makefile delete mode 100644 testing/examples/STR710Test/prj/eclipse_ram.gdb delete mode 100644 testing/examples/STR710Test/prj/eclipse_rom.gdb delete mode 100644 testing/examples/STR710Test/prj/hitex_str7_ram.ld delete mode 100644 testing/examples/STR710Test/prj/hitex_str7_rom.ld delete mode 100644 testing/examples/STR710Test/prj/str710_jtagkey.cfg delete mode 100644 testing/examples/STR710Test/prj/str710_program.script delete mode 100644 testing/examples/STR710Test/src/crt.s delete mode 100644 testing/examples/STR710Test/src/main.c delete mode 100644 testing/examples/STR710Test/test_ram.elf delete mode 100644 testing/examples/STR710Test/test_ram.hex delete mode 100644 testing/examples/STR710Test/test_ram.map delete mode 100644 testing/examples/STR710Test/test_rom.elf delete mode 100644 testing/examples/STR710Test/test_rom.hex delete mode 100644 testing/examples/STR710Test/test_rom.map delete mode 100644 testing/examples/STR912Test/inc/typedefs.h delete mode 100644 testing/examples/STR912Test/makefile delete mode 100644 testing/examples/STR912Test/prj/eclipse_ram.gdb delete mode 100644 testing/examples/STR912Test/prj/eclipse_rom.gdb delete mode 100644 testing/examples/STR912Test/prj/str912_jtagkey.cfg delete mode 100644 testing/examples/STR912Test/prj/str912_program.script delete mode 100644 testing/examples/STR912Test/prj/str912_ram.ld delete mode 100644 testing/examples/STR912Test/prj/str912_rom.ld delete mode 100644 testing/examples/STR912Test/src/main.c delete mode 100644 testing/examples/STR912Test/src/startup.s delete mode 100644 testing/examples/STR912Test/test_ram.elf delete mode 100644 testing/examples/STR912Test/test_ram.hex delete mode 100644 testing/examples/STR912Test/test_ram.map delete mode 100644 testing/examples/STR912Test/test_rom.elf delete mode 100644 testing/examples/STR912Test/test_rom.hex delete mode 100644 testing/examples/STR912Test/test_rom.map delete mode 100644 testing/examples/cortex/cm3-ftest.cfg delete mode 100644 testing/examples/cortex/fault.c delete mode 100644 testing/examples/cortex/lm3s3748.elf delete mode 100644 testing/examples/cortex/test.c delete mode 100644 testing/examples/cortex/test.ld delete mode 100644 testing/examples/ledtest-imx27ads/Makefile delete mode 100644 testing/examples/ledtest-imx27ads/crt0.S delete mode 100644 testing/examples/ledtest-imx27ads/gdbinit-imx27ads delete mode 100644 testing/examples/ledtest-imx27ads/ldscript delete mode 100644 testing/examples/ledtest-imx27ads/test.c delete mode 100644 testing/examples/ledtest-imx27ads/test.elf delete mode 100644 testing/examples/ledtest-imx31pdk/Makefile delete mode 100644 testing/examples/ledtest-imx31pdk/crt0.S delete mode 100644 testing/examples/ledtest-imx31pdk/gdbinit-imx31pdk delete mode 100644 testing/examples/ledtest-imx31pdk/ldscript delete mode 100644 testing/examples/ledtest-imx31pdk/test.c delete mode 100644 testing/examples/ledtest-imx31pdk/test.elf delete mode 100644 testing/index.html delete mode 100644 testing/profile_stm32.txt delete mode 100644 testing/results/template.html delete mode 100755 testing/results/v0.4.0-rc1/AT91FR40162.html delete mode 100755 testing/results/v0.4.0-rc1/LPC2148.html delete mode 100755 testing/results/v0.4.0-rc1/SAM7.html delete mode 100755 testing/results/v0.4.0-rc1/STR710.html delete mode 100755 testing/results/v0.4.0-rc1/STR912.html delete mode 100644 testing/smoketests.html delete mode 100644 testing/tcl_server.tcl delete mode 100644 testing/tcl_test.tcl delete mode 100644 testing/testcases.html delete mode 100755 tools/checkpatch.sh delete mode 160000 tools/git2cl delete mode 100755 tools/initial.sh delete mode 100644 tools/logger.pl delete mode 100755 tools/release.sh delete mode 100644 tools/release/helpers.sh delete mode 100755 tools/release/test.sh delete mode 100755 tools/release/version.sh delete mode 100755 tools/rlink_make_speed_table/rlink_make_speed_table delete mode 100755 tools/rlink_make_speed_table/rlink_make_speed_table.pl delete mode 100755 tools/scripts/checkpatch.pl delete mode 100755 tools/st7_dtc_as/st7_dtc_as delete mode 100755 tools/st7_dtc_as/st7_dtc_as.pl delete mode 100755 tools/uncrustify1.sh delete mode 100644 uncrustify.cfg diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 0f217a980..000000000 --- a/.gitignore +++ /dev/null @@ -1,101 +0,0 @@ -# stuff "git status" should ignore - -# build output -.libs -.deps -.dirstamp -*.o -*.o.?????? -*.a -*.lo -*.la -*.in - -# generated source files -src/jtag/minidriver_imp.h -src/jtag/jtag_minidriver.h - -# OpenULINK driver files generated by SDCC -src/jtag/drivers/OpenULINK/*.rel -src/jtag/drivers/OpenULINK/*.asm -src/jtag/drivers/OpenULINK/*.lst -src/jtag/drivers/OpenULINK/*.sym -src/jtag/drivers/OpenULINK/*.map -src/jtag/drivers/OpenULINK/*.mem -src/jtag/drivers/OpenULINK/*.lk -src/jtag/drivers/OpenULINK/*.ihx -src/jtag/drivers/OpenULINK/*.rst - -# editor files -*.swp - -src/startup.tcl -startup_tcl.inc -xscale_debug.inc - -bin2char -bin2char.exe - -doc/openocd.aux -doc/openocd.cp -doc/openocd.cps -doc/openocd.fn -doc/openocd.fns -doc/openocd.html -doc/openocd.info -doc/openocd.info-1 -doc/openocd.info-2 -doc/openocd.ky -doc/openocd.log -doc/openocd.pdf -doc/openocd.pg -doc/openocd.toc -doc/openocd.tp -doc/openocd.vr -doc/texinfo.tex -doc/version.texi -src/openocd -src/openocd.exe - -# configure/autotools output -aclocal.m4 -autom4te.cache -compile -config.* -configure -depcomp -doxygen -doxygen.log -Doxyfile -install-sh -libtool -ltmain.sh -Makefile -!contrib/loaders/**/Makefile -mdate-sh -missing -stamp-h1 -stamp-vti -INSTALL -NOTES - -# coexist with quilt -patches -*.patch - -# Eclipse stuff -.project -.cproject -.settings - -# Emacs temp files -*~ - -# Emacs TAGS file -TAGS - -# CScope database files -*cscope.out - -# ctags tag files -tags diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index 5865ff92a..000000000 --- a/.gitmodules +++ /dev/null @@ -1,9 +0,0 @@ -[submodule "tools/git2cl"] - path = tools/git2cl - url = http://repo.or.cz/r/git2cl.git -[submodule "jimtcl"] - path = jimtcl - url = http://repo.or.cz/r/jimtcl.git -[submodule "src/jtag/drivers/libjaylink"] - path = src/jtag/drivers/libjaylink - url = http://repo.or.cz/r/libjaylink.git diff --git a/AUTHORS b/AUTHORS deleted file mode 100644 index 2a989f37e..000000000 --- a/AUTHORS +++ /dev/null @@ -1,12 +0,0 @@ -Dominic Rath -Magnus Lundin -Michael Fischer -Spencer Oliver -Carsten Schlote -Øyvind Harboe -Duane Ellis -Michael Schwingen -Rick Altherr -David Brownell -Vincint Palatin -Zachary T Welch diff --git a/AUTHORS.ChangeLog b/AUTHORS.ChangeLog deleted file mode 100644 index b2b5e6b63..000000000 --- a/AUTHORS.ChangeLog +++ /dev/null @@ -1,10 +0,0 @@ -drath:Dominic Rath -mlu:Magnus Lundin -mifi:Michael Fischer -ntfreak:Spencer Oliver -duane:Duane Ellis -oharboe:Øyvind Harboe -kc8apf:Rick Altherr -zwelch:Zachary T Welch -vpalatin:Vincent Palatin -bodylove:Carsten Schlote diff --git a/BUGS b/BUGS deleted file mode 100644 index 17a7b30e2..000000000 --- a/BUGS +++ /dev/null @@ -1,74 +0,0 @@ -// This file is part of the Doxygen Developer Manual -/** @page bugs Bug Reporting - -Please report bugs by subscribing to the OpenOCD mailing list and -posting a message with your report: - - openocd-devel@lists.sourceforge.net - -Also, please check the bug database to see if a ticket for -the bug has already been opened. You might be asked to open -such a ticket, or to update an existing ticket with more data. - - http://bugs.openocd.org/ - -To minimize work for OpenOCD developers, you should try to include -all of the information listed below. If you feel that some of the -items below are unnecessary for a clear bug report, you may leave -them out; likewise, feel free to include additional information -that may be important. - -- Target PCB/board description -- Configuration scripts -- OpenOCD command line -- List of commands issued or GDB operations performed -- Expected result -- Actual result -- Logs using debug_level 3 (or with '-d 3' on the command line) -- If the report is for a regression: - - Include logs for both working and broken versions. - - Find the precise version that caused the regression by binary search. - You can use "git bisect" to expedite this binary search: - http://www.kernel.org/pub/software/scm/git/docs/git-bisect.html - -If possible, please develop and attach a patch that helps to expose or -solve the reported problem. See the HACKING file for information -about that process. - -Attach all files directly to your posting. The mailing list knows to -transform attachments to links, but attachments must be less than 300KB -in total. - -@section bugscrashdump Obtaining Crash Backtraces - -If OpenOCD is crashing, there are two very effective things you can do to -improve your chances of getting help on the development mailing list. - -Try to reproduce the problem using the dummy JTAG interface to allow other developers to replicate -your problem robustly and use GDB to get a trace:@par -@code -% OPENOCDSRC/configure --enable-dummy ... -% openocd -f interface/dummy.cfg -f target/xxx.cfg -=> SEGFAULT -% gdb --args openocd .... -(gdb) run -(gdb) bt -=> here a stack trace is dumped. -@endcode - -@section bugsintreedebug Running and Debugging In-Tree - -To run or debug the in-tree executable (not recommended), you must -use libtool to set up the correct shared library paths: -@code - libtool gdb --args openocd .... -@endcode -or the more pedantic (and forward-compatible): -@code - libtool --mode=execute gdb --args openocd .... -@endcode - - */ -/** @file -This file contains the @ref bugs page. -*/ diff --git a/COPYING b/COPYING deleted file mode 100644 index d159169d1..000000000 --- a/COPYING +++ /dev/null @@ -1,339 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Lesser General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. diff --git a/ChangeLog b/ChangeLog deleted file mode 100644 index a8df5d0f6..000000000 --- a/ChangeLog +++ /dev/null @@ -1 +0,0 @@ -Retired in favor of git log. diff --git a/Doxyfile.in b/Doxyfile.in deleted file mode 100644 index 13b0c24f6..000000000 --- a/Doxyfile.in +++ /dev/null @@ -1,1517 +0,0 @@ -# Doxyfile 1.5.8 - -# This file describes the settings to be used by the documentation system -# doxygen (www.doxygen.org) for a project -# -# All text after a hash (#) is considered a comment and will be ignored -# The format is: -# TAG = value [value, ...] -# For lists items can also be appended using: -# TAG += value [value, ...] -# Values that contain spaces should be placed between quotes (" ") - -#--------------------------------------------------------------------------- -# Project related configuration options -#--------------------------------------------------------------------------- - -# This tag specifies the encoding used for all characters in the config file -# that follow. The default is UTF-8 which is also the encoding used for all -# text before the first occurrence of this tag. Doxygen uses libiconv (or the -# iconv built into libc) for the transcoding. See -# http://www.gnu.org/software/libiconv for the list of possible encodings. - -DOXYFILE_ENCODING = UTF-8 - -# The PROJECT_NAME tag is a single word (or a sequence of words surrounded -# by quotes) that should identify the project. - -PROJECT_NAME = OpenOCD - -# The PROJECT_NUMBER tag can be used to enter a project or revision number. -# This could be handy for archiving the generated documentation or -# if some version control system is used. - -PROJECT_NUMBER = - -# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) -# base path where the generated documentation will be put. -# If a relative path is entered, it will be relative to the location -# where doxygen was started. If left blank the current directory will be used. - -OUTPUT_DIRECTORY = doxygen - -# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create -# 4096 sub-directories (in 2 levels) under the output directory of each output -# format and will distribute the generated files over these directories. -# Enabling this option can be useful when feeding doxygen a huge amount of -# source files, where putting all generated files in the same directory would -# otherwise cause performance problems for the file system. - -CREATE_SUBDIRS = NO - -# The OUTPUT_LANGUAGE tag is used to specify the language in which all -# documentation generated by doxygen is written. Doxygen will use this -# information to generate all constant output in the proper language. -# The default language is English, other supported languages are: -# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, -# Croatian, Czech, Danish, Dutch, Farsi, Finnish, French, German, Greek, -# Hungarian, Italian, Japanese, Japanese-en (Japanese with English messages), -# Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, Polish, -# Portuguese, Romanian, Russian, Serbian, Serbian-Cyrilic, Slovak, Slovene, -# Spanish, Swedish, and Ukrainian. - -OUTPUT_LANGUAGE = English - -# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will -# include brief member descriptions after the members that are listed in -# the file and class documentation (similar to JavaDoc). -# Set to NO to disable this. - -BRIEF_MEMBER_DESC = YES - -# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend -# the brief description of a member or function before the detailed description. -# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the -# brief descriptions will be completely suppressed. - -REPEAT_BRIEF = YES - -# This tag implements a quasi-intelligent brief description abbreviator -# that is used to form the text in various listings. Each string -# in this list, if found as the leading text of the brief description, will be -# stripped from the text and the result after processing the whole list, is -# used as the annotated text. Otherwise, the brief description is used as-is. -# If left blank, the following values are used ("$name" is automatically -# replaced with the name of the entity): "The $name class" "The $name widget" -# "The $name file" "is" "provides" "specifies" "contains" -# "represents" "a" "an" "the" - -ABBREVIATE_BRIEF = - -# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then -# Doxygen will generate a detailed section even if there is only a brief -# description. - -ALWAYS_DETAILED_SEC = NO - -# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all -# inherited members of a class in the documentation of that class as if those -# members were ordinary class members. Constructors, destructors and assignment -# operators of the base classes will not be shown. - -INLINE_INHERITED_MEMB = YES - -# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full -# path before files name in the file list and in the header files. If set -# to NO the shortest path that makes the file name unique will be used. - -FULL_PATH_NAMES = NO - -# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag -# can be used to strip a user-defined part of the path. Stripping is -# only done if one of the specified strings matches the left-hand part of -# the path. The tag can be used to show relative paths in the file list. -# If left blank the directory from which doxygen is run is used as the -# path to strip. - -STRIP_FROM_PATH = - -# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of -# the path mentioned in the documentation of a class, which tells -# the reader which header file to include in order to use a class. -# If left blank only the name of the header file containing the class -# definition is used. Otherwise one should specify the include paths that -# are normally passed to the compiler using the -I flag. - -STRIP_FROM_INC_PATH = - -# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter -# (but less readable) file names. This can be useful is your file systems -# doesn't support long names like on DOS, Mac, or CD-ROM. - -SHORT_NAMES = NO - -# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen -# will interpret the first line (until the first dot) of a JavaDoc-style -# comment as the brief description. If set to NO, the JavaDoc -# comments will behave just like regular Qt-style comments -# (thus requiring an explicit @brief command for a brief description.) - -JAVADOC_AUTOBRIEF = YES - -# If the QT_AUTOBRIEF tag is set to YES then Doxygen will -# interpret the first line (until the first dot) of a Qt-style -# comment as the brief description. If set to NO, the comments -# will behave just like regular Qt-style comments (thus requiring -# an explicit \brief command for a brief description.) - -QT_AUTOBRIEF = NO - -# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen -# treat a multi-line C++ special comment block (i.e. a block of //! or /// -# comments) as a brief description. This used to be the default behaviour. -# The new default is to treat a multi-line C++ comment block as a detailed -# description. Set this tag to YES if you prefer the old behaviour instead. - -MULTILINE_CPP_IS_BRIEF = NO - -# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented -# member inherits the documentation from any documented member that it -# re-implements. - -INHERIT_DOCS = YES - -# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce -# a new page for each member. If set to NO, the documentation of a member will -# be part of the file/class/namespace that contains it. - -SEPARATE_MEMBER_PAGES = NO - -# The TAB_SIZE tag can be used to set the number of spaces in a tab. -# Doxygen uses this value to replace tabs by spaces in code fragments. - -TAB_SIZE = 4 - -# This tag can be used to specify a number of aliases that acts -# as commands in the documentation. An alias has the form "name=value". -# For example adding "sideeffect=\par Side Effects:\n" will allow you to -# put the command \sideeffect (or @sideeffect) in the documentation, which -# will result in a user-defined paragraph with heading "Side Effects:". -# You can put \n's in the value part of an alias to insert newlines. - -ALIASES = - -# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C -# sources only. Doxygen will then generate output that is more tailored for C. -# For instance, some of the names that are used will be different. The list -# of all members will be omitted, etc. - -OPTIMIZE_OUTPUT_FOR_C = YES - -# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java -# sources only. Doxygen will then generate output that is more tailored for -# Java. For instance, namespaces will be presented as packages, qualified -# scopes will look different, etc. - -OPTIMIZE_OUTPUT_JAVA = NO - -# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran -# sources only. Doxygen will then generate output that is more tailored for -# Fortran. - -OPTIMIZE_FOR_FORTRAN = NO - -# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL -# sources. Doxygen will then generate output that is tailored for -# VHDL. - -OPTIMIZE_OUTPUT_VHDL = NO - -# Doxygen selects the parser to use depending on the extension of the files it parses. -# With this tag you can assign which parser to use for a given extension. -# Doxygen has a built-in mapping, but you can override or extend it using this tag. -# The format is ext=language, where ext is a file extension, and language is one of -# the parsers supported by doxygen: IDL, Java, Javascript, C#, C, C++, D, PHP, -# Objective-C, Python, Fortran, VHDL, C, C++. For instance to make doxygen treat -# .inc files as Fortran files (default is PHP), and .f files as C (default is Fortran), -# use: inc=Fortran f=C - -EXTENSION_MAPPING = - -# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want -# to include (a tag file for) the STL sources as input, then you should -# set this tag to YES in order to let doxygen match functions declarations and -# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. -# func(std::string) {}). This also make the inheritance and collaboration -# diagrams that involve STL classes more complete and accurate. - -BUILTIN_STL_SUPPORT = NO - -# If you use Microsoft's C++/CLI language, you should set this option to YES to -# enable parsing support. - -CPP_CLI_SUPPORT = NO - -# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. -# Doxygen will parse them like normal C++ but will assume all classes use public -# instead of private inheritance when no explicit protection keyword is present. - -SIP_SUPPORT = NO - -# For Microsoft's IDL there are propget and propput attributes to indicate getter -# and setter methods for a property. Setting this option to YES (the default) -# will make doxygen to replace the get and set methods by a property in the -# documentation. This will only work if the methods are indeed getting or -# setting a simple type. If this is not the case, or you want to show the -# methods anyway, you should set this option to NO. - -IDL_PROPERTY_SUPPORT = NO - -# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC -# tag is set to YES, then doxygen will reuse the documentation of the first -# member in the group (if any) for the other members of the group. By default -# all members of a group must be documented explicitly. - -DISTRIBUTE_GROUP_DOC = NO - -# Set the SUBGROUPING tag to YES (the default) to allow class member groups of -# the same type (for instance a group of public functions) to be put as a -# subgroup of that type (e.g. under the Public Functions section). Set it to -# NO to prevent subgrouping. Alternatively, this can be done per class using -# the \nosubgrouping command. - -SUBGROUPING = YES - -# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum -# is documented as struct, union, or enum with the name of the typedef. So -# typedef struct TypeS {} TypeT, will appear in the documentation as a struct -# with name TypeT. When disabled the typedef will appear as a member of a file, -# namespace, or class. And the struct will be named TypeS. This can typically -# be useful for C code in case the coding convention dictates that all compound -# types are typedef'ed and only the typedef is referenced, never the tag name. - -TYPEDEF_HIDES_STRUCT = NO - -# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to -# determine which symbols to keep in memory and which to flush to disk. -# When the cache is full, less often used symbols will be written to disk. -# For small to medium size projects (<1000 input files) the default value is -# probably good enough. For larger projects a too small cache size can cause -# doxygen to be busy swapping symbols to and from disk most of the time -# causing a significant performance penality. -# If the system has enough physical memory increasing the cache will improve the -# performance by keeping more symbols in memory. Note that the value works on -# a logarithmic scale so increasing the size by one will rougly double the -# memory usage. The cache size is given by this formula: -# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, -# corresponding to a cache size of 2^16 = 65536 symbols - -SYMBOL_CACHE_SIZE = 0 - -#--------------------------------------------------------------------------- -# Build related configuration options -#--------------------------------------------------------------------------- - -# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in -# documentation are documented, even if no documentation was available. -# Private class members and static file members will be hidden unless -# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES - -EXTRACT_ALL = YES - -# If the EXTRACT_PRIVATE tag is set to YES all private members of a class -# will be included in the documentation. - -EXTRACT_PRIVATE = NO - -# If the EXTRACT_STATIC tag is set to YES all static members of a file -# will be included in the documentation. - -EXTRACT_STATIC = YES - -# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) -# defined locally in source files will be included in the documentation. -# If set to NO only classes defined in header files are included. - -EXTRACT_LOCAL_CLASSES = YES - -# This flag is only useful for Objective-C code. When set to YES local -# methods, which are defined in the implementation section but not in -# the interface are included in the documentation. -# If set to NO (the default) only methods in the interface are included. - -EXTRACT_LOCAL_METHODS = NO - -# If this flag is set to YES, the members of anonymous namespaces will be -# extracted and appear in the documentation as a namespace called -# 'anonymous_namespace{file}', where file will be replaced with the base -# name of the file that contains the anonymous namespace. By default -# anonymous namespace are hidden. - -EXTRACT_ANON_NSPACES = NO - -# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all -# undocumented members of documented classes, files or namespaces. -# If set to NO (the default) these members will be included in the -# various overviews, but no documentation section is generated. -# This option has no effect if EXTRACT_ALL is enabled. - -HIDE_UNDOC_MEMBERS = NO - -# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all -# undocumented classes that are normally visible in the class hierarchy. -# If set to NO (the default) these classes will be included in the various -# overviews. This option has no effect if EXTRACT_ALL is enabled. - -HIDE_UNDOC_CLASSES = NO - -# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all -# friend (class|struct|union) declarations. -# If set to NO (the default) these declarations will be included in the -# documentation. - -HIDE_FRIEND_COMPOUNDS = NO - -# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any -# documentation blocks found inside the body of a function. -# If set to NO (the default) these blocks will be appended to the -# function's detailed documentation block. - -HIDE_IN_BODY_DOCS = NO - -# The INTERNAL_DOCS tag determines if documentation -# that is typed after a \internal command is included. If the tag is set -# to NO (the default) then the documentation will be excluded. -# Set it to YES to include the internal documentation. - -INTERNAL_DOCS = NO - -# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate -# file names in lower-case letters. If set to YES upper-case letters are also -# allowed. This is useful if you have classes or files whose names only differ -# in case and if your file system supports case sensitive file names. Windows -# and Mac users are advised to set this option to NO. - -CASE_SENSE_NAMES = YES - -# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen -# will show members with their full class and namespace scopes in the -# documentation. If set to YES the scope will be hidden. - -HIDE_SCOPE_NAMES = NO - -# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen -# will put a list of the files that are included by a file in the documentation -# of that file. - -SHOW_INCLUDE_FILES = NO - -# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] -# is inserted in the documentation for inline members. - -INLINE_INFO = YES - -# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen -# will sort the (detailed) documentation of file and class members -# alphabetically by member name. If set to NO the members will appear in -# declaration order. - -SORT_MEMBER_DOCS = YES - -# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the -# brief documentation of file, namespace and class members alphabetically -# by member name. If set to NO (the default) the members will appear in -# declaration order. - -SORT_BRIEF_DOCS = YES - -# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the -# hierarchy of group names into alphabetical order. If set to NO (the default) -# the group names will appear in their defined order. - -SORT_GROUP_NAMES = NO - -# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be -# sorted by fully-qualified names, including namespaces. If set to -# NO (the default), the class list will be sorted only by class name, -# not including the namespace part. -# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. -# Note: This option applies only to the class list, not to the -# alphabetical list. - -SORT_BY_SCOPE_NAME = NO - -# The GENERATE_TODOLIST tag can be used to enable (YES) or -# disable (NO) the todo list. This list is created by putting \todo -# commands in the documentation. - -GENERATE_TODOLIST = YES - -# The GENERATE_TESTLIST tag can be used to enable (YES) or -# disable (NO) the test list. This list is created by putting \test -# commands in the documentation. - -GENERATE_TESTLIST = YES - -# The GENERATE_BUGLIST tag can be used to enable (YES) or -# disable (NO) the bug list. This list is created by putting \bug -# commands in the documentation. - -GENERATE_BUGLIST = YES - -# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or -# disable (NO) the deprecated list. This list is created by putting -# \deprecated commands in the documentation. - -GENERATE_DEPRECATEDLIST= YES - -# The ENABLED_SECTIONS tag can be used to enable conditional -# documentation sections, marked by \if sectionname ... \endif. - -ENABLED_SECTIONS = - -# The MAX_INITIALIZER_LINES tag determines the maximum number of lines -# the initial value of a variable or define consists of for it to appear in -# the documentation. If the initializer consists of more lines than specified -# here it will be hidden. Use a value of 0 to hide initializers completely. -# The appearance of the initializer of individual variables and defines in the -# documentation can be controlled using \showinitializer or \hideinitializer -# command in the documentation regardless of this setting. - -MAX_INITIALIZER_LINES = 30 - -# Set the SHOW_USED_FILES tag to NO to disable the list of files generated -# at the bottom of the documentation of classes and structs. If set to YES the -# list will mention the files that were used to generate the documentation. - -SHOW_USED_FILES = YES - -# If the sources in your project are distributed over multiple directories -# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy -# in the documentation. The default is NO. - -SHOW_DIRECTORIES = YES - -# Set the SHOW_FILES tag to NO to disable the generation of the Files page. -# This will remove the Files entry from the Quick Index and from the -# Folder Tree View (if specified). The default is YES. - -SHOW_FILES = YES - -# Set the SHOW_NAMESPACES tag to NO to disable the generation of the -# Namespaces page. -# This will remove the Namespaces entry from the Quick Index -# and from the Folder Tree View (if specified). The default is YES. - -SHOW_NAMESPACES = YES - -# The FILE_VERSION_FILTER tag can be used to specify a program or script that -# doxygen should invoke to get the current version for each file (typically from -# the version control system). Doxygen will invoke the program by executing (via -# popen()) the command , where is the value of -# the FILE_VERSION_FILTER tag, and is the name of an input file -# provided by doxygen. Whatever the program writes to standard output -# is used as the file version. See the manual for examples. - -FILE_VERSION_FILTER = - -# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed by -# doxygen. The layout file controls the global structure of the generated output files -# in an output format independent way. The create the layout file that represents -# doxygen's defaults, run doxygen with the -l option. You can optionally specify a -# file name after the option, if omitted DoxygenLayout.xml will be used as the name -# of the layout file. - -LAYOUT_FILE = - -#--------------------------------------------------------------------------- -# configuration options related to warning and progress messages -#--------------------------------------------------------------------------- - -# The QUIET tag can be used to turn on/off the messages that are generated -# by doxygen. Possible values are YES and NO. If left blank NO is used. - -QUIET = NO - -# The WARNINGS tag can be used to turn on/off the warning messages that are -# generated by doxygen. Possible values are YES and NO. If left blank -# NO is used. - -WARNINGS = YES - -# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings -# for undocumented members. If EXTRACT_ALL is set to YES then this flag will -# automatically be disabled. - -WARN_IF_UNDOCUMENTED = YES - -# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for -# potential errors in the documentation, such as not documenting some -# parameters in a documented function, or documenting parameters that -# don't exist or using markup commands wrongly. - -WARN_IF_DOC_ERROR = YES - -# This WARN_NO_PARAMDOC option can be abled to get warnings for -# functions that are documented, but have no documentation for their parameters -# or return value. If set to NO (the default) doxygen will only warn about -# wrong or incomplete parameter documentation, but not about the absence of -# documentation. - -WARN_NO_PARAMDOC = NO - -# The WARN_FORMAT tag determines the format of the warning messages that -# doxygen can produce. The string should contain the $file, $line, and $text -# tags, which will be replaced by the file and line number from which the -# warning originated and the warning text. Optionally the format may contain -# $version, which will be replaced by the version of the file (if it could -# be obtained via FILE_VERSION_FILTER) - -WARN_FORMAT = "$file:$line: $text " - -# The WARN_LOGFILE tag can be used to specify a file to which warning -# and error messages should be written. If left blank the output is written -# to stderr. - -WARN_LOGFILE = - -#--------------------------------------------------------------------------- -# configuration options related to the input files -#--------------------------------------------------------------------------- - -# The INPUT tag can be used to specify the files and/or directories that contain -# documented source files. You may enter file names like "myfile.cpp" or -# directories like "/usr/src/myproject". Separate the files or directories -# with spaces. - -INPUT = @srcdir@/doc/manual \ - @srcdir@/TODO \ - @srcdir@/BUGS \ - @srcdir@/HACKING \ - @srcdir@/src \ - @builddir@/config.h - -# This tag can be used to specify the character encoding of the source files -# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is -# also the default input encoding. Doxygen uses libiconv (or the iconv built -# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for -# the list of possible encodings. - -INPUT_ENCODING = UTF-8 - -# If the value of the INPUT tag contains directories, you can use the -# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank the following patterns are tested: -# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx -# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90 - -FILE_PATTERNS = *.h \ - *.c \ - *.txt - -# The RECURSIVE tag can be used to turn specify whether or not subdirectories -# should be searched for input files as well. Possible values are YES and NO. -# If left blank NO is used. - -RECURSIVE = YES - -# The EXCLUDE tag can be used to specify files and/or directories that should -# excluded from the INPUT source files. This way you can easily exclude a -# subdirectory from a directory tree whose root is specified with the INPUT tag. - -EXCLUDE = - -# The EXCLUDE_SYMLINKS tag can be used select whether or not files or -# directories that are symbolic links (a Unix filesystem feature) are excluded -# from the input. - -EXCLUDE_SYMLINKS = NO - -# If the value of the INPUT tag contains directories, you can use the -# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude -# certain files from those directories. Note that the wildcards are matched -# against the file with absolute path, so to exclude all test directories -# for example use the pattern */test/* - -EXCLUDE_PATTERNS = - -# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names -# (namespaces, classes, functions, etc.) that should be excluded from the -# output. The symbol name can be a fully qualified name, a word, or if the -# wildcard * is used, a substring. Examples: ANamespace, AClass, -# AClass::ANamespace, ANamespace::*Test - -EXCLUDE_SYMBOLS = - -# The EXAMPLE_PATH tag can be used to specify one or more files or -# directories that contain example code fragments that are included (see -# the \include command). - -EXAMPLE_PATH = - -# If the value of the EXAMPLE_PATH tag contains directories, you can use the -# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank all files are included. - -EXAMPLE_PATTERNS = - -# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be -# searched for input files to be used with the \include or \dontinclude -# commands irrespective of the value of the RECURSIVE tag. -# Possible values are YES and NO. If left blank NO is used. - -EXAMPLE_RECURSIVE = NO - -# The IMAGE_PATH tag can be used to specify one or more files or -# directories that contain image that are included in the documentation (see -# the \image command). - -IMAGE_PATH = @srcdir@/doc/manual/images - -# The INPUT_FILTER tag can be used to specify a program that doxygen should -# invoke to filter for each input file. Doxygen will invoke the filter program -# by executing (via popen()) the command , where -# is the value of the INPUT_FILTER tag, and is the name of an -# input file. Doxygen will then use the output that the filter program writes -# to standard output. -# If FILTER_PATTERNS is specified, this tag will be -# ignored. - -INPUT_FILTER = - -# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern -# basis. -# Doxygen will compare the file name with each pattern and apply the -# filter if there is a match. -# The filters are a list of the form: -# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further -# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER -# is applied to all files. - -FILTER_PATTERNS = - -# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using -# INPUT_FILTER) will be used to filter the input files when producing source -# files to browse (i.e. when SOURCE_BROWSER is set to YES). - -FILTER_SOURCE_FILES = NO - -#--------------------------------------------------------------------------- -# configuration options related to source browsing -#--------------------------------------------------------------------------- - -# If the SOURCE_BROWSER tag is set to YES then a list of source files will -# be generated. Documented entities will be cross-referenced with these sources. -# Note: To get rid of all source code in the generated output, make sure also -# VERBATIM_HEADERS is set to NO. - -SOURCE_BROWSER = YES - -# Setting the INLINE_SOURCES tag to YES will include the body -# of functions and classes directly in the documentation. - -INLINE_SOURCES = NO - -# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct -# doxygen to hide any special comment blocks from generated source code -# fragments. Normal C and C++ comments will always remain visible. - -STRIP_CODE_COMMENTS = YES - -# If the REFERENCED_BY_RELATION tag is set to YES -# then for each documented function all documented -# functions referencing it will be listed. - -REFERENCED_BY_RELATION = YES - -# If the REFERENCES_RELATION tag is set to YES -# then for each documented function all documented entities -# called/used by that function will be listed. - -REFERENCES_RELATION = YES - -# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) -# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from -# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will -# link to the source code. -# Otherwise they will link to the documentation. - -REFERENCES_LINK_SOURCE = YES - -# If the USE_HTAGS tag is set to YES then the references to source code -# will point to the HTML generated by the htags(1) tool instead of doxygen -# built-in source browser. The htags tool is part of GNU's global source -# tagging system (see http://www.gnu.org/software/global/global.html). You -# will need version 4.8.6 or higher. - -USE_HTAGS = NO - -# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen -# will generate a verbatim copy of the header file for each class for -# which an include is specified. Set to NO to disable this. - -VERBATIM_HEADERS = YES - -#--------------------------------------------------------------------------- -# configuration options related to the alphabetical class index -#--------------------------------------------------------------------------- - -# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index -# of all compounds will be generated. Enable this if the project -# contains a lot of classes, structs, unions or interfaces. - -ALPHABETICAL_INDEX = YES - -# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then -# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns -# in which this list will be split (can be a number in the range [1..20]) - -COLS_IN_ALPHA_INDEX = 5 - -# In case all classes in a project start with a common prefix, all -# classes will be put under the same header in the alphabetical index. -# The IGNORE_PREFIX tag can be used to specify one or more prefixes that -# should be ignored while generating the index headers. - -IGNORE_PREFIX = - -#--------------------------------------------------------------------------- -# configuration options related to the HTML output -#--------------------------------------------------------------------------- - -# If the GENERATE_HTML tag is set to YES (the default) Doxygen will -# generate HTML output. - -GENERATE_HTML = @doxygen_as_html@ - -# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `html' will be used as the default path. - -HTML_OUTPUT = html - -# The HTML_FILE_EXTENSION tag can be used to specify the file extension for -# each generated HTML page (for example: .htm,.php,.asp). If it is left blank -# doxygen will generate files with .html extension. - -HTML_FILE_EXTENSION = .html - -# The HTML_HEADER tag can be used to specify a personal HTML header for -# each generated HTML page. If it is left blank doxygen will generate a -# standard header. - -HTML_HEADER = - -# The HTML_FOOTER tag can be used to specify a personal HTML footer for -# each generated HTML page. If it is left blank doxygen will generate a -# standard footer. - -HTML_FOOTER = - -# The HTML_STYLESHEET tag can be used to specify a user-defined cascading -# style sheet that is used by each HTML page. It can be used to -# fine-tune the look of the HTML output. If the tag is left blank doxygen -# will generate a default style sheet. Note that doxygen will try to copy -# the style sheet file to the HTML output directory, so don't put your own -# stylesheet in the HTML output directory as well, or it will be erased! - -HTML_STYLESHEET = - -# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, -# files or namespaces will be aligned in HTML using tables. If set to -# NO a bullet list will be used. - -HTML_ALIGN_MEMBERS = YES - -# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML -# documentation will contain sections that can be hidden and shown after the -# page has loaded. For this to work a browser that supports -# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox -# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). - -HTML_DYNAMIC_SECTIONS = NO - -# If the GENERATE_DOCSET tag is set to YES, additional index files -# will be generated that can be used as input for Apple's Xcode 3 -# integrated development environment, introduced with OSX 10.5 (Leopard). -# To create a documentation set, doxygen will generate a Makefile in the -# HTML output directory. Running make will produce the docset in that -# directory and running "make install" will install the docset in -# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find -# it at startup. -# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html for more information. - -GENERATE_DOCSET = NO - -# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the -# feed. A documentation feed provides an umbrella under which multiple -# documentation sets from a single provider (such as a company or product suite) -# can be grouped. - -DOCSET_FEEDNAME = "Doxygen generated docs" - -# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that -# should uniquely identify the documentation set bundle. This should be a -# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen -# will append .docset to the name. - -DOCSET_BUNDLE_ID = org.doxygen.Project - -# If the GENERATE_HTMLHELP tag is set to YES, additional index files -# will be generated that can be used as input for tools like the -# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) -# of the generated HTML documentation. - -GENERATE_HTMLHELP = NO - -# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can -# be used to specify the file name of the resulting .chm file. You -# can add a path in front of the file if the result should not be -# written to the html output directory. - -CHM_FILE = - -# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can -# be used to specify the location (absolute path including file name) of -# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run -# the HTML help compiler on the generated index.hhp. - -HHC_LOCATION = - -# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag -# controls if a separate .chi index file is generated (YES) or that -# it should be included in the master .chm file (NO). - -GENERATE_CHI = NO - -# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING -# is used to encode HtmlHelp index (hhk), content (hhc) and project file -# content. - -CHM_INDEX_ENCODING = - -# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag -# controls whether a binary table of contents is generated (YES) or a -# normal table of contents (NO) in the .chm file. - -BINARY_TOC = NO - -# The TOC_EXPAND flag can be set to YES to add extra items for group members -# to the contents of the HTML help documentation and to the tree view. - -TOC_EXPAND = NO - -# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and QHP_VIRTUAL_FOLDER -# are set, an additional index file will be generated that can be used as input for -# Qt's qhelpgenerator to generate a Qt Compressed Help (.qch) of the generated -# HTML documentation. - -GENERATE_QHP = NO - -# If the QHG_LOCATION tag is specified, the QCH_FILE tag can -# be used to specify the file name of the resulting .qch file. -# The path specified is relative to the HTML output folder. - -QCH_FILE = - -# The QHP_NAMESPACE tag specifies the namespace to use when generating -# Qt Help Project output. For more information please see -# http://doc.trolltech.com/qthelpproject.html#namespace - -QHP_NAMESPACE = - -# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating -# Qt Help Project output. For more information please see -# http://doc.trolltech.com/qthelpproject.html#virtual-folders - -QHP_VIRTUAL_FOLDER = doc - -# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to add. -# For more information please see -# http://doc.trolltech.com/qthelpproject.html#custom-filters - -QHP_CUST_FILTER_NAME = - -# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the custom filter to add.For more information please see -# Qt Help Project / Custom Filters. - -QHP_CUST_FILTER_ATTRS = - -# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this project's -# filter section matches. -# Qt Help Project / Filter Attributes. - -QHP_SECT_FILTER_ATTRS = - -# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can -# be used to specify the location of Qt's qhelpgenerator. -# If non-empty doxygen will try to run qhelpgenerator on the generated -# .qhp file. - -QHG_LOCATION = - -# The DISABLE_INDEX tag can be used to turn on/off the condensed index at -# top of each HTML page. The value NO (the default) enables the index and -# the value YES disables it. - -DISABLE_INDEX = NO - -# This tag can be used to set the number of enum values (range [1..20]) -# that doxygen will group on one line in the generated HTML documentation. - -ENUM_VALUES_PER_LINE = 4 - -# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index -# structure should be generated to display hierarchical information. -# If the tag value is set to FRAME, a side panel will be generated -# containing a tree-like index structure (just like the one that -# is generated for HTML Help). For this to work a browser that supports -# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, -# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are -# probably better off using the HTML help feature. Other possible values -# for this tag are: HIERARCHIES, which will generate the Groups, Directories, -# and Class Hierarchy pages using a tree view instead of an ordered list; -# ALL, which combines the behavior of FRAME and HIERARCHIES; and NONE, which -# disables this behavior completely. For backwards compatibility with previous -# releases of Doxygen, the values YES and NO are equivalent to FRAME and NONE -# respectively. - -GENERATE_TREEVIEW = YES - -# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be -# used to set the initial width (in pixels) of the frame in which the tree -# is shown. - -TREEVIEW_WIDTH = 250 - -# Use this tag to change the font size of Latex formulas included -# as images in the HTML documentation. The default is 10. Note that -# when you change the font size after a successful doxygen run you need -# to manually remove any form_*.png images from the HTML output directory -# to force them to be regenerated. - -FORMULA_FONTSIZE = 10 - -#--------------------------------------------------------------------------- -# configuration options related to the LaTeX output -#--------------------------------------------------------------------------- - -# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will -# generate Latex output. - -GENERATE_LATEX = @doxygen_as_pdf@ - -# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `latex' will be used as the default path. - -LATEX_OUTPUT = latex - -# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be -# invoked. If left blank `latex' will be used as the default command name. - -LATEX_CMD_NAME = pdflatex - -# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to -# generate index for LaTeX. If left blank `makeindex' will be used as the -# default command name. - -MAKEINDEX_CMD_NAME = makeindex - -# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact -# LaTeX documents. This may be useful for small projects and may help to -# save some trees in general. - -COMPACT_LATEX = YES - -# The PAPER_TYPE tag can be used to set the paper type that is used -# by the printer. Possible values are: a4, a4wide, letter, legal and -# executive. If left blank a4wide will be used. - -PAPER_TYPE = a4wide - -# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX -# packages that should be included in the LaTeX output. - -EXTRA_PACKAGES = - -# The LATEX_HEADER tag can be used to specify a personal LaTeX header for -# the generated latex document. The header should contain everything until -# the first chapter. If it is left blank doxygen will generate a -# standard header. Notice: only use this tag if you know what you are doing! - -LATEX_HEADER = - -# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated -# is prepared for conversion to pdf (using ps2pdf). The pdf file will -# contain links (just like the HTML output) instead of page references -# This makes the output suitable for online browsing using a pdf viewer. - -PDF_HYPERLINKS = YES - -# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of -# plain latex in the generated Makefile. Set this option to YES to get a -# higher quality PDF documentation. - -USE_PDFLATEX = YES - -# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. -# command to the generated LaTeX files. This will instruct LaTeX to keep -# running if errors occur, instead of asking the user for help. -# This option is also used when generating formulas in HTML. - -LATEX_BATCHMODE = YES - -# If LATEX_HIDE_INDICES is set to YES then doxygen will not -# include the index chapters (such as File Index, Compound Index, etc.) -# in the output. - -LATEX_HIDE_INDICES = NO - -#--------------------------------------------------------------------------- -# configuration options related to the RTF output -#--------------------------------------------------------------------------- - -# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output -# The RTF output is optimized for Word 97 and may not look very pretty with -# other RTF readers or editors. - -GENERATE_RTF = NO - -# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `rtf' will be used as the default path. - -RTF_OUTPUT = rtf - -# If the COMPACT_RTF tag is set to YES Doxygen generates more compact -# RTF documents. This may be useful for small projects and may help to -# save some trees in general. - -COMPACT_RTF = NO - -# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated -# will contain hyperlink fields. The RTF file will -# contain links (just like the HTML output) instead of page references. -# This makes the output suitable for online browsing using WORD or other -# programs which support those fields. -# Note: wordpad (write) and others do not support links. - -RTF_HYPERLINKS = NO - -# Load stylesheet definitions from file. Syntax is similar to doxygen's -# config file, i.e. a series of assignments. You only have to provide -# replacements, missing definitions are set to their default value. - -RTF_STYLESHEET_FILE = - -# Set optional variables used in the generation of an rtf document. -# Syntax is similar to doxygen's config file. - -RTF_EXTENSIONS_FILE = - -#--------------------------------------------------------------------------- -# configuration options related to the man page output -#--------------------------------------------------------------------------- - -# If the GENERATE_MAN tag is set to YES (the default) Doxygen will -# generate man pages - -GENERATE_MAN = NO - -# The MAN_OUTPUT tag is used to specify where the man pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `man' will be used as the default path. - -MAN_OUTPUT = man - -# The MAN_EXTENSION tag determines the extension that is added to -# the generated man pages (default is the subroutine's section .3) - -MAN_EXTENSION = .3 - -# If the MAN_LINKS tag is set to YES and Doxygen generates man output, -# then it will generate one additional man file for each entity -# documented in the real man page(s). These additional files -# only source the real man page, but without them the man command -# would be unable to find the correct page. The default is NO. - -MAN_LINKS = NO - -#--------------------------------------------------------------------------- -# configuration options related to the XML output -#--------------------------------------------------------------------------- - -# If the GENERATE_XML tag is set to YES Doxygen will -# generate an XML file that captures the structure of -# the code including all documentation. - -GENERATE_XML = NO - -# The XML_OUTPUT tag is used to specify where the XML pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `xml' will be used as the default path. - -XML_OUTPUT = xml - -# The XML_SCHEMA tag can be used to specify an XML schema, -# which can be used by a validating XML parser to check the -# syntax of the XML files. - -XML_SCHEMA = - -# The XML_DTD tag can be used to specify an XML DTD, -# which can be used by a validating XML parser to check the -# syntax of the XML files. - -XML_DTD = - -# If the XML_PROGRAMLISTING tag is set to YES Doxygen will -# dump the program listings (including syntax highlighting -# and cross-referencing information) to the XML output. Note that -# enabling this will significantly increase the size of the XML output. - -XML_PROGRAMLISTING = YES - -#--------------------------------------------------------------------------- -# configuration options for the AutoGen Definitions output -#--------------------------------------------------------------------------- - -# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will -# generate an AutoGen Definitions (see autogen.sf.net) file -# that captures the structure of the code including all -# documentation. Note that this feature is still experimental -# and incomplete at the moment. - -GENERATE_AUTOGEN_DEF = NO - -#--------------------------------------------------------------------------- -# configuration options related to the Perl module output -#--------------------------------------------------------------------------- - -# If the GENERATE_PERLMOD tag is set to YES Doxygen will -# generate a Perl module file that captures the structure of -# the code including all documentation. Note that this -# feature is still experimental and incomplete at the -# moment. - -GENERATE_PERLMOD = NO - -# If the PERLMOD_LATEX tag is set to YES Doxygen will generate -# the necessary Makefile rules, Perl scripts and LaTeX code to be able -# to generate PDF and DVI output from the Perl module output. - -PERLMOD_LATEX = NO - -# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be -# nicely formatted so it can be parsed by a human reader. -# This is useful -# if you want to understand what is going on. -# On the other hand, if this -# tag is set to NO the size of the Perl module output will be much smaller -# and Perl will parse it just the same. - -PERLMOD_PRETTY = YES - -# The names of the make variables in the generated doxyrules.make file -# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. -# This is useful so different doxyrules.make files included by the same -# Makefile don't overwrite each other's variables. - -PERLMOD_MAKEVAR_PREFIX = - -#--------------------------------------------------------------------------- -# Configuration options related to the preprocessor -#--------------------------------------------------------------------------- - -# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will -# evaluate all C-preprocessor directives found in the sources and include -# files. - -ENABLE_PREPROCESSING = YES - -# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro -# names in the source code. If set to NO (the default) only conditional -# compilation will be performed. Macro expansion can be done in a controlled -# way by setting EXPAND_ONLY_PREDEF to YES. - -MACRO_EXPANSION = NO - -# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES -# then the macro expansion is limited to the macros specified with the -# PREDEFINED and EXPAND_AS_DEFINED tags. - -EXPAND_ONLY_PREDEF = NO - -# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files -# in the INCLUDE_PATH (see below) will be search if a #include is found. - -SEARCH_INCLUDES = YES - -# The INCLUDE_PATH tag can be used to specify one or more directories that -# contain include files that are not input files but should be processed by -# the preprocessor. - -INCLUDE_PATH = - -# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard -# patterns (like *.h and *.hpp) to filter out the header-files in the -# directories. If left blank, the patterns specified with FILE_PATTERNS will -# be used. - -INCLUDE_FILE_PATTERNS = *.h - -# The PREDEFINED tag can be used to specify one or more macro names that -# are defined before the preprocessor is started (similar to the -D option of -# gcc). The argument of the tag is a list of macros of the form: name -# or name=definition (no spaces). If the definition and the = are -# omitted =1 is assumed. To prevent a macro definition from being -# undefined via #undef or recursively expanded use the := operator -# instead of the = operator. - -PREDEFINED = HAVE_CONFIG_H - -# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then -# this tag can be used to specify a list of macro names that should be expanded. -# The macro definition that is found in the sources will be used. -# Use the PREDEFINED tag if you want to use a different macro definition. - -EXPAND_AS_DEFINED = - -# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then -# doxygen's preprocessor will remove all function-like macros that are alone -# on a line, have an all uppercase name, and do not end with a semicolon. Such -# function macros are typically used for boiler-plate code, and will confuse -# the parser if not removed. - -SKIP_FUNCTION_MACROS = YES - -#--------------------------------------------------------------------------- -# Configuration::additions related to external references -#--------------------------------------------------------------------------- - -# The TAGFILES option can be used to specify one or more tagfiles. -# Optionally an initial location of the external documentation -# can be added for each tagfile. The format of a tag file without -# this location is as follows: -# -# TAGFILES = file1 file2 ... -# Adding location for the tag files is done as follows: -# -# TAGFILES = file1=loc1 "file2 = loc2" ... -# where "loc1" and "loc2" can be relative or absolute paths or -# URLs. If a location is present for each tag, the installdox tool -# does not have to be run to correct the links. -# Note that each tag file must have a unique name -# (where the name does NOT include the path) -# If a tag file is not located in the directory in which doxygen -# is run, you must also specify the path to the tagfile here. - -TAGFILES = - -# When a file name is specified after GENERATE_TAGFILE, doxygen will create -# a tag file that is based on the input files it reads. - -GENERATE_TAGFILE = - -# If the ALLEXTERNALS tag is set to YES all external classes will be listed -# in the class index. If set to NO only the inherited external classes -# will be listed. - -ALLEXTERNALS = NO - -# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed -# in the modules index. If set to NO, only the current project's groups will -# be listed. - -EXTERNAL_GROUPS = YES - -# The PERL_PATH should be the absolute path and name of the perl script -# interpreter (i.e. the result of `which perl'). - -PERL_PATH = /usr/bin/perl - -#--------------------------------------------------------------------------- -# Configuration options related to the dot tool -#--------------------------------------------------------------------------- - -# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will -# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base -# or super classes. Setting the tag to NO turns the diagrams off. Note that -# this option is superseded by the HAVE_DOT option below. This is only a -# fallback. It is recommended to install and use dot, since it yields more -# powerful graphs. - -CLASS_DIAGRAMS = YES - -# You can define message sequence charts within doxygen comments using the \msc -# command. Doxygen will then run the mscgen tool (see -# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the -# documentation. The MSCGEN_PATH tag allows you to specify the directory where -# the mscgen tool resides. If left empty the tool is assumed to be found in the -# default search path. - -MSCGEN_PATH = - -# If set to YES, the inheritance and collaboration graphs will hide -# inheritance and usage relations if the target is undocumented -# or is not a class. - -HIDE_UNDOC_RELATIONS = YES - -# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is -# available from the path. This tool is part of Graphviz, a graph visualization -# toolkit from AT&T and Lucent Bell Labs. The other options in this section -# have no effect if this option is set to NO (the default) - -HAVE_DOT = YES - -# By default doxygen will write a font called FreeSans.ttf to the output -# directory and reference it in all dot files that doxygen generates. This -# font does not include all possible unicode characters however, so when you need -# these (or just want a differently looking font) you can specify the font name -# using DOT_FONTNAME. You need need to make sure dot is able to find the font, -# which can be done by putting it in a standard location or by setting the -# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory -# containing the font. - -DOT_FONTNAME = FreeSans - -# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. -# The default size is 10pt. - -DOT_FONTSIZE = 10 - -# By default doxygen will tell dot to use the output directory to look for the -# FreeSans.ttf font (which doxygen will put there itself). If you specify a -# different font using DOT_FONTNAME you can set the path where dot -# can find it using this tag. - -DOT_FONTPATH = - -# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for each documented class showing the direct and -# indirect inheritance relations. Setting this tag to YES will force the -# the CLASS_DIAGRAMS tag to NO. - -CLASS_GRAPH = YES - -# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for each documented class showing the direct and -# indirect implementation dependencies (inheritance, containment, and -# class references variables) of the class with other documented classes. - -COLLABORATION_GRAPH = YES - -# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for groups, showing the direct groups dependencies - -GROUP_GRAPHS = YES - -# If the UML_LOOK tag is set to YES doxygen will generate inheritance and -# collaboration diagrams in a style similar to the OMG's Unified Modeling -# Language. - -UML_LOOK = NO - -# If set to YES, the inheritance and collaboration graphs will show the -# relations between templates and their instances. - -TEMPLATE_RELATIONS = YES - -# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT -# tags are set to YES then doxygen will generate a graph for each documented -# file showing the direct and indirect include dependencies of the file with -# other documented files. - -INCLUDE_GRAPH = YES - -# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and -# HAVE_DOT tags are set to YES then doxygen will generate a graph for each -# documented header file showing the documented files that directly or -# indirectly include this file. - -INCLUDED_BY_GRAPH = YES - -# If the CALL_GRAPH and HAVE_DOT options are set to YES then -# doxygen will generate a call dependency graph for every global function -# or class method. Note that enabling this option will significantly increase -# the time of a run. So in most cases it will be better to enable call graphs -# for selected functions only using the \callgraph command. - -CALL_GRAPH = NO - -# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then -# doxygen will generate a caller dependency graph for every global function -# or class method. Note that enabling this option will significantly increase -# the time of a run. So in most cases it will be better to enable caller -# graphs for selected functions only using the \callergraph command. - -CALLER_GRAPH = NO - -# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen -# will graphical hierarchy of all classes instead of a textual one. - -GRAPHICAL_HIERARCHY = YES - -# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES -# then doxygen will show the dependencies a directory has on other directories -# in a graphical way. The dependency relations are determined by the #include -# relations between the files in the directories. - -DIRECTORY_GRAPH = YES - -# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images -# generated by dot. Possible values are png, jpg, or gif -# If left blank png will be used. - -DOT_IMAGE_FORMAT = png - -# The tag DOT_PATH can be used to specify the path where the dot tool can be -# found. If left blank, it is assumed the dot tool can be found in the path. - -DOT_PATH = - -# The DOTFILE_DIRS tag can be used to specify one or more directories that -# contain dot files that are included in the documentation (see the -# \dotfile command). - -DOTFILE_DIRS = - -# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of -# nodes that will be shown in the graph. If the number of nodes in a graph -# becomes larger than this value, doxygen will truncate the graph, which is -# visualized by representing a node as a red box. Note that doxygen if the -# number of direct children of the root node in a graph is already larger than -# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note -# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. - -DOT_GRAPH_MAX_NODES = 50 - -# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the -# graphs generated by dot. A depth value of 3 means that only nodes reachable -# from the root by following a path via at most 3 edges will be shown. Nodes -# that lay further from the root node will be omitted. Note that setting this -# option to 1 or 2 may greatly reduce the computation time needed for large -# code bases. Also note that the size of a graph can be further restricted by -# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. - -MAX_DOT_GRAPH_DEPTH = 0 - -# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent -# background. This is disabled by default, because dot on Windows does not -# seem to support this out of the box. Warning: Depending on the platform used, -# enabling this option may lead to badly anti-aliased labels on the edges of -# a graph (i.e. they become hard to read). - -DOT_TRANSPARENT = NO - -# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output -# files in one run (i.e. multiple -o and -T options on the command line). This -# makes dot run faster, but since only newer versions of dot (>1.8.10) -# support this, this feature is disabled by default. - -DOT_MULTI_TARGETS = NO - -# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will -# generate a legend page explaining the meaning of the various boxes and -# arrows in the dot generated graphs. - -GENERATE_LEGEND = YES - -# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will -# remove the intermediate dot files that are used to generate -# the various graphs. - -DOT_CLEANUP = YES - -#--------------------------------------------------------------------------- -# Options related to the search engine -#--------------------------------------------------------------------------- - -# The SEARCHENGINE tag specifies whether or not a search engine should be -# used. If set to NO the values of all tags below this one will be ignored. - -SEARCHENGINE = NO diff --git a/HACKING b/HACKING deleted file mode 100644 index 162da8698..000000000 --- a/HACKING +++ /dev/null @@ -1,185 +0,0 @@ -// This file is part of the Doxygen Developer Manual -/** @page patchguide Patch Guidelines - -\attention If you're behind a corporate wall with http only access to the -world, you can still use these instructions! - -\attention You can't send patches to the mailing list anymore at all. Nowadays -you are expected to send patches to the OpenOCD Gerrit GIT server for a -review. - -@section gerrit Submitting patches to the OpenOCD Gerrit server - -OpenOCD is to some extent a "self service" open source project, so to -contribute, you must follow the standard procedures to have the best -possible chance to get your changes accepted. - -The procedure to create a patch is essentially: - -- make the changes -- create a commit -- send the changes to the Gerrit server for review -- correct the patch and re-send it according to review feedback - -Your patch (or commit) should be a "good patch": focus it on a single -issue, and make it be easily reviewable. Don't make -it so large that it's hard to review; split large -patches into smaller ones. (That can also help -track down bugs later on.) All patches should -be "clean", which includes preserving the existing -coding style and updating documentation as needed. - -Say in the commit message if it's a bugfix (describe the bug) or a new -feature. Don't expect patches to merge immediately -for the next release. Be ready to rework patches -in response to feedback. - -Add yourself to the GPL copyright for non-trivial changes. - -@section stepbystep Step by step procedure - --# Create a Gerrit account at: http://openocd.zylin.com - - On subsequent sign ins, use the full URL prefaced with 'http://' - For example: http://user_identifier.open_id_provider.com - -# Add a username to your profile. - After creating the Gerrit account and signing in, you will need to - add a username to your profile. To do this, go to 'Settings', and - add a username of your choice. - Your username will be required in step 3 and substituted wherever - the string 'USERNAME' is found. - -# Create an SSH public key following the directions on github: - https://help.github.com/articles/generating-ssh-keys . You can skip step 3 - (adding key to Github account) and 4 (testing) - these are useful only if - you actually use Github or want to test whether the new key works fine. - -# Add this new SSH key to your Gerrit account: - go to 'Settings' > 'SSH Public Keys', paste the contents of - ~/.ssh/id_rsa.pub into the text field (if it's not visible click on - 'Add Key ...' button) and confirm by clicking 'Add' button. --# Clone the git repository, rather than just download the source: - @code - git clone git://git.code.sf.net/p/openocd/code openocd - @endcode - or if you have problems with the "git:" protocol, use - the slower http protocol: - @code - git clone http://git.code.sf.net/p/openocd/code openocd - @endcode --# Set up Gerrit with your local repository. All this does it -to instruct git locally how to send off the changes. - -# Add a new remote to git using Gerrit username: -@code -git remote add review ssh://USERNAME@openocd.zylin.com:29418/openocd.git -git config remote.review.push HEAD:refs/publish/master -@endcode - Or with http only: -@code -git remote add review http://USERNAME@openocd.zylin.com/p/openocd.git -git config remote.review.push HEAD:refs/publish/master -@endcode - The http password is configured from your gerrit settings - http://openocd.zylin.com/#/settings/http-password. - \note If you want to simplify http access you can also add your http password to the url as follows: -@code -git remote add review http://USERNAME:PASSWORD@openocd.zylin.com/p/openocd.git -@endcode - -# You will need to install this hook, we will look into a better solution: -@code -scp -p -P 29418 USERNAME@openocd.zylin.com:hooks/commit-msg .git/hooks/ -@endcode - Or with http only: -@code -wget http://openocd.zylin.com/tools/hooks/commit-msg -mv commit-msg .git/hooks -chmod +x .git/hooks/commit-msg -@endcode - \note A script exists to simplify the two items above. execute: -@code -tools/initial.sh -@endcode -With @ being your Gerrit username. --# Set up git with your name and email: -@code -git config --global user.name "John Smith" -git config --global user.email "john@smith.org" -@endcode --# Work on your patches. Split the work into - multiple small patches that can be reviewed and - applied seperately and safely to the OpenOCD - repository. -@code -while(!done) { - work - edit files using your favorite editor. - run "git commit -s -a" to commit all changes. - run tools/checkpatch.sh to verify your patch style is ok. -} -@endcode - \note use "git add ." before commit to add new files. - - Comment template, notice the short first line w/topic. The topic field - should identify the main part or subsystem the patch touches. Check - git log for examples. -@code -topic: Short comment - -Longer comments over several lines, explaining (where applicable) the -reason for the patch and the general idea the solution is based on, -any major design decisions, etc... - -Signed-off-by: ... -@endcode --# Next you need to make sure that your patches - are on top of the latest stuff on the server and - that there are no conflicts: -@code -git pull --rebase origin master -@endcode --# Send the patches to the Gerrit server for review: -@code -git push review -@endcode --# Forgot something, want to add more? Just make the changes and do: -@code -git commit --amend -git push review -@endcode - -Further reading: http://www.coreboot.org/Git - -@section timeline When can I expect my contribution to be committed? - -The code review is intended to take as long as a week or two to allow -maintainers and contributors who work on OpenOCD only in their spare -time oportunity to perform a review and raise objections. - -With Gerrit much of the urgency of getting things committed has been -removed as the work in progress is safely stored in Gerrit and -available if someone needs to build on your work before it is -submitted to the official repository. - -Another factor that contributes to the desire for longer cool-off -times (the time a patch lies around without any further changes or -comments), it means that the chances of quality regression on the -master branch will be much reduced. - -If a contributor pushes a patch, it is considered good form if another -contributor actually approves and submits that patch. - -It should be noted that a negative review in Gerrit ("-1" or "-2") may (but does -not have to) be disregarded if all conditions listed below are met: - -- the concerns raised in the review have been addressed (or explained), -- reviewer does not re-examine the change in a month, -- reviewer does not answer e-mails for another month. - -@section browsing Browsing Patches -All OpenOCD patches can be reviewed here. - -@section reviewing Reviewing Patches -From the main Review -page select the patch you want to review and click on that patch. On the -appearing page select the download method (top right). Apply the -patch. After building and testing you can leave a note with the "Reply" -button and mark the patch with -1, 0 and +1. -*/ -/** @file -This file contains the @ref patchguide page. -*/ diff --git a/Makefile.am b/Makefile.am deleted file mode 100644 index 2ddc96d3d..000000000 --- a/Makefile.am +++ /dev/null @@ -1,112 +0,0 @@ -# not a GNU package. You can remove this line, if -# have all needed files, that a GNU package needs -AUTOMAKE_OPTIONS = gnu 1.6 - -# make sure we pass the correct jimtcl flags to distcheck -DISTCHECK_CONFIGURE_FLAGS = --disable-install-jim - -nobase_dist_pkgdata_DATA = \ - contrib/libdcc/dcc_stdio.c \ - contrib/libdcc/dcc_stdio.h \ - contrib/libdcc/example.c \ - contrib/libdcc/README \ - contrib/99-openocd.rules - -if INTERNAL_JIMTCL -SUBDIRS = jimtcl -else -SUBDIRS = -endif - -SUBDIRS += src doc - -EXTRA_DIST = \ - BUGS \ - HACKING \ - NEWTAPS \ - README.Windows \ - README.OSX \ - $(wildcard $(srcdir)/NEWS*) \ - Doxyfile.in \ - tools/logger.pl \ - tools/rlink_make_speed_table \ - tools/st7_dtc_as \ - contrib - -libtool: $(LIBTOOL_DEPS) - $(SHELL) ./config.status --recheck - -docs: pdf html doxygen - -Doxyfile: $(srcdir)/Doxyfile.in - @echo "Creating $@ from $<..." - @( \ - echo "### @@@ -= DO NOT EDIT THIS FILE =- @@@ ###" && \ - echo "### @@@ Make changes to Doxyfile.in @@@ ###" && \ - sed -e 's,@srcdir\@,$(srcdir),' \ - -e 's,@builddir\@,$(builddir),' \ - -e 's,@doxygen_as_html\@,$(doxygen_as_html),' \ - -e 's,@doxygen_as_pdf\@,$(doxygen_as_pdf),' $< \ - ) > $@ - -THE_MANUAL = doxygen/latex/refman.pdf - -doxygen:: - $(MAKE) Doxyfile - doxygen Doxyfile 2>&1 | perl $(srcdir)/tools/logger.pl > doxygen.log - @if [ -f doxygen/latex/refman.tex ]; then \ - echo "Creating $(THE_MANUAL)..."; \ - $(MAKE) $(THE_MANUAL); \ - else \ - echo "Skipping Doxygen PDF..."; \ - fi - -$(THE_MANUAL): %.pdf: %.tex - -cd $$(dirname $*) && pdflatex $$(basename $*) - -cd $$(dirname $*) && pdflatex $$(basename $*) - -TCL_PATH = tcl -# command to find paths of script files, relative to TCL_PATH -TCL_FILES = find $(srcdir)/$(TCL_PATH) -name '*.cfg' -o -name '*.tcl' -o -name '*.txt' | \ - sed -e 's,^$(srcdir)/$(TCL_PATH),,' - -dist-hook: - if test -d $(srcdir)/.git -a \( ! -e $(distdir)/ChangeLog -o -w $(distdir)/ChangeLog \) ; then \ - git --git-dir $(srcdir)/.git log | $(srcdir)/tools/git2cl/git2cl > $(distdir)/ChangeLog ; \ - fi - for i in $$($(TCL_FILES)); do \ - j="$(distdir)/$(TCL_PATH)/$$i" && \ - mkdir -p "$$(dirname $$j)" && \ - $(INSTALL_DATA) $(srcdir)/$(TCL_PATH)/$$i $$j; \ - done - -install-data-hook: - for i in $$($(TCL_FILES)); do \ - j="$(DESTDIR)$(pkgdatadir)/scripts/$$i" && \ - mkdir -p "$$(dirname $$j)" && \ - $(INSTALL_DATA) $(srcdir)/$(TCL_PATH)/$$i $$j; \ - done - -uninstall-hook: - rm -rf $(DESTDIR)$(pkgdatadir)/scripts - -distclean-local: - rm -rf Doxyfile doxygen - rm -f $(srcdir)/jimtcl/configure.gnu - -DISTCLEANFILES = doxygen.log - -MAINTAINERCLEANFILES = \ - $(srcdir)/INSTALL \ - $(srcdir)/configure \ - $(srcdir)/Makefile.in \ - $(srcdir)/depcomp \ - $(srcdir)/config.guess \ - $(srcdir)/config.sub \ - $(srcdir)/config.h.in \ - $(srcdir)/config.h.in~ \ - $(srcdir)/compile \ - $(srcdir)/ltmain.sh \ - $(srcdir)/missing \ - $(srcdir)/aclocal.m4 \ - $(srcdir)/install-sh diff --git a/NEWS b/NEWS deleted file mode 100644 index 9df165004..000000000 --- a/NEWS +++ /dev/null @@ -1,33 +0,0 @@ -This file includes highlights of the changes made in the OpenOCD -source archive release. - -JTAG Layer: - -Boundary Scan: - -Target Layer: - -Flash Layer: - -Board, Target, and Interface Configuration Scripts: - -Server Layer: - -Documentation: - -Build and Release: - - -This release also contains a number of other important functional and -cosmetic bugfixes. For more details about what has changed since the -last release, see the git repository history: - -http://sourceforge.net/p/openocd/code/ci/v0.x.0/log/?path= - - -For older NEWS, see the NEWS files associated with each release -(i.e. NEWS-). - -For more information about contributing test reports, bug fixes, or new -features and device support, please read the new Developer Manual (or -the BUGS and PATCHES.txt files in the source archive). diff --git a/NEWS-0.2.0 b/NEWS-0.2.0 deleted file mode 100644 index 742692684..000000000 --- a/NEWS-0.2.0 +++ /dev/null @@ -1,80 +0,0 @@ -The OpenOCD 0.2.0 source archive release includes numerous improvements -that were made since the initial 0.1.0 source archive release. Many -contributors helped make this release a great success, and the community -of developers and maintainers look forward to any response. - -In addition to the list of changes below, countless bug fixing and -cleaning was performed across the tree. Various TCL command parameters -must past stricter value checks, and many more error conditions have -been handled correctly. These efforts helped to make the 0.2.0 release -more stable and robust, though some changes may expose latent bugs in -your existing configuration scripts. - -This release does not maintain backward compatibility in all respects, -so some target or configuration scripts may need to be updated. In some -cases, you may also see warnings; resolve those, because they indicate -commands that will be removed in the future. - -The following areas of OpenOCD functionality changed in this release: - -JTAG Layer: -- Improves modularity: core, TCL, driver commands, and interface have - been separated, encapsulated, and documented for developers. Mostly. -- Improves JTAG TAP transition tables: - * Makes TAP paths variable length, rather than being fixed at 7 steps. - * Fixes problems with some targets that did not like longer paths. -- Improves JTAG driver/minidriver modularity and encapsulation. -- New drivers: - * Adds stub minidriver for developing new embedded JTAG interfaces. -- Improves drivers: - * ft2232+ftd2xx: - + Adds initial high-speed device support: --enable-ftd2xx-highspeed - + Supports more types of FTDI-based devices. - * jlink: - + Works with more versions of the firmware (v3 and newer) - + Supports dynamically detects device capabilities and limits - * vsllink: - + Supports very long scan chains - * amtjtagaccel: - + Fixes broken ID code detection problems. - -Target Layer: -- New devices: AVR, FA526 -- Improved support: ARM ADI, ARM11, MIPS -- Numerous other bug fixes and improvements - -Flash Layer: -- Improved drivers: mflash -- New drivers: AT91SAM3, AVR, Davinci NAND - -Board, Interface, and Target Configuration Scripts: -- Many new and improved targets and boards are now available. -- Better separation of "board" and "target" configuration -- Moved all TCL files to top-level "tcl" directory in the source tree -- Installation moved from '$pkglibdir/' to '$pkgdatadir/scripts/'. -- Site-specific files should be installed under '$pkgdatadir/site/'; - files that exist this tree will be used in preference to default - distribution configurations in '$pkgdatadir/scripts/'. - -Documentation: -- Updated User Guide: http://openocd.berlios.de/doc/html/index.html - * Partially re-written and re-organized. - * Standardized presentation for all commands. - * Covers many drivers and commands that were previously omitted. - * New index for commands and drivers. -- Added Developer Manual: http://openocd.berlios.de/doc/doxygen/index.html - * Now includes architecture, technical primers, style guides, and more. - * Available in-tree and on-line. - -Build and Release: -- Increased configuration and compilation warning coverage. - * Use --disable-werror to work around build errors caused by warnings. -- Use libtool to produce helper libraries as a step toward "libopenocd". -- New processes and scripting to facilitate future source releases. - -For more details about what has changed since 0.1.0, see the ChangeLog -associated with this release. - -For more information about contributing test reports, bug fixes, or new -features and device support, please read the new Developer Manual (or -the BUGS and PATCHES files in the source archive). diff --git a/NEWS-0.3.0 b/NEWS-0.3.0 deleted file mode 100644 index 80e8823c4..000000000 --- a/NEWS-0.3.0 +++ /dev/null @@ -1,82 +0,0 @@ -This file should include highlights of the changes made in the -OpenOCD openocd-0.3.0 source archive release. See the repository -history for details about what changed, including bugfixes and -other issues not mentioned here. - -JTAG Layer: - FT2232H (high speed USB) support doesn't need separate configuration - New FT2232H JTAG adapters: Amontec, Olimex, Signalyzer - New reset_config options for SRST gating the JTAG clock (or not) - TAP declaration no longer requires ircapture and mask attributes - Scan chain setup should be more robust, with better diagnostics - New TAP events: - "post-reset" for TAP-invariant setup code (TAPs not usable yet) - "setup" for use once TAPs are addressable (e.g. with ICEpick) - Overridable Tcl "init_reset" and "jtag_init" procedures - Simple "autoprobe" mechanism to help simplify server setup - -Boundary Scan: - SVF bugfixes ... parsing fixes, better STATE switch conformance - XSVF bugfixes ... be more correct, handle Xilinx tool output - -Target Layer: - Warn on use of obsolete numeric target IDs - New commands for use with Cortex-M3 processors: - "cortex_m3 disassemble" ... Thumb2 disassembly (UAL format) - "cortex_m3 vector_catch" ... traps certain hardware faults - without tying up breakpoint resources - If you're willing to help debug it - VERY EARLY Cortex-A8 and ARMv7A support - Updated BeagleBoard.org hardware support - you may need to explicitly "reset" after connect-to-Beagle - New commands for use with XScale processors: "xscale vector_table" - ARM - bugfixes to single-stepping Thumb code - ETM: unavailable registers are not listed - ETB, ETM: report actual hardware status - ARM9 - name change: "arm9 vector_catch" not "arm9tdmi vector_catch" - ARM11 - single stepping support for i.MX31 - bugfix for missing "arm11" prefix on "arm11 memwrite ..." - GDB support - gdb_attach command is gone - -Flash Layer: - The lpc2000 driver handles the new NXP LPC1700 (Cortex-M3) chips - New drivers: - lpc2900, for NXP LPC2900 chips (ARM968 based) - mx3_nand, for imx31 - New "last" flag for NOR "flash erase_sector" and "flash protect" - The "nand erase N" command now erases all of bank N - Speed up davinci_nand by about 3x - -Board, Target, and Interface Configuration Scripts: - Amontec JTAGkey2 support - Cleanup and additions for the TI/Luminary Stellaris scripts - LPC1768 target (and flash) support - Keil MCB1700 eval board - Samsung s3c2450 - Mini2440 board - Numeric TAP and Target identifiers now trigger warnings - PXA255 partially enumerates - -Documentation: - Capture more debugging and setup advice - Notes on target source code changes that may help debugging - -Build and Release: - Repository moved from SVN at Berlios to GIT at SourceForge - Clean builds on (32-bit) Cygwin - Clean builds on 64-bit MinGW - -For more details about what has changed since the last release, -see the git repository history. With gitweb, you can browse that -in various levels of detail. - -For older NEWS, see the NEWS files associated with each release -(i.e. NEWS-). - -For more information about contributing test reports, bug fixes, or new -features and device support, please read the new Developer Manual (or -the BUGS and PATCHES files in the source archive). diff --git a/NEWS-0.4.0 b/NEWS-0.4.0 deleted file mode 100644 index cbd552617..000000000 --- a/NEWS-0.4.0 +++ /dev/null @@ -1,98 +0,0 @@ -This file includes highlights of the changes made in the -OpenOCD 0.4.0 source archive release. See the repository -history for details about what changed, including bugfixes -and other issues not mentioned here. - -JTAG Layer: - Support KT-Link JTAG adapter. - Support USB-JTAG, Altera USB-Blaster and compatibles. - -Boundary Scan: - -Target Layer: - General - - Removed commands which have been obsolete for at least - a year (from both documentation and, sometimes, code). - - new "reset-assert" event, for systems without SRST - ARM - - supports "reset-assert" event (except on Cortex-M3) - - renamed "armv4_5" command prefix as "arm" - - recognize TrustZone "Secure Monitor" mode - - "arm regs" command output changed - - register names use "sp" not "r13" - - add top-level "mcr" and "mrc" commands, replacing - various core-specific operations - - basic semihosting support (ARM7/ARM9 only, for now) - ARM11 - - Should act much more like other ARM cores: - * Preliminary ETM and ETB hookup - * accelerated "flash erase_check" - * accelerated GDB memory checksum - * support "arm regs" command - * can access all core modes and registers - * watchpoint support - - Shares some core debug code with Cortex-A8 - Cortex-A8 - - Should act much more like other ARM cores: - * support "arm regs" command - * can access all core modes and registers - * watchpoint support - - Shares some core debug code with ARM11 - Cortex-M3 - - Exposed DWT registers like cycle counter - - vector_catch settings not clobbered by resets - - no longer interferes with firmware's fault handling - ETM, ETB - - "trigger_percent" command moved ETM --> ETB - - "etm trigger_debug" command added - MIPS - - use fastdata writes - Freescale DSP563xx cores (partial support) - -Flash Layer: - 'flash bank' and 'nand device' take as first argument. - With this, flash/NAND commands allow referencing banks by name: - - : reference the bank with its defined name - - [.N]: reference the driver's Nth bank - New 'nand verify' command to check bank against an image file. - The "flash erase_address" command now rejects partial sectors; - previously it would silently erase extra data. If you - want to erase the rest of the first and/or last sectors - instead of failing, you must pass an explicit "pad" flag. - New at91sam9 NAND controller driver. - New s3c64xx NAND controller driver. - -Board, Target, and Interface Configuration Scripts: - ARM9 - - ETM and ETB hookup for iMX2* targets - Add $HOME/.openocd to the search path. - Handle Rev C of LM3S811 eval boards. - - use "luminary-lm3s811.cfg" for older boards - - use "luminary.cfg" for RevC and newer - -Core Jim/TCL Scripting: - New 'usage' command to provide terse command help. - Improved command 'help' command output (sorted and indented). - Improved command handling: - - Most boolean settings now accept any of the following: - on/off, enable/disable, true/false, yes/no, 1/0 - - More error checking and reporting. - -Documentation: - New built-in command development documentation and primer. - -Build and Release: - Use --enable-doxygen-pdf to build PDF developer documentation. - Consider upgrading to libftdi 0.17 if you use that library; it - includes bugfixes which improve FT2232H support. - -For more details about what has changed since the last release, -see the git repository history. With gitweb, you can browse that -in various levels of detail. - -For older NEWS, see the NEWS files associated with each release -(i.e. NEWS-). - -For more information about contributing test reports, bug fixes, or new -features and device support, please read the new Developer Manual (or -the BUGS and PATCHES.txt files in the source archive). diff --git a/NEWS-0.5.0 b/NEWS-0.5.0 deleted file mode 100644 index add6c1e90..000000000 --- a/NEWS-0.5.0 +++ /dev/null @@ -1,74 +0,0 @@ -This file includes highlights of the changes made in the -OpenOCD 0.5.0 source archive release. See the repository -history for details about what changed, including bugfixes -and other issues not mentioned here. - -JTAG Layer: - New driver for "Bus Pirate" - Rename various commands so they're not JTAG-specific - There are migration procedures for most of these, but you should - convert your scripts to the new names, since those procedures - will not be around forever. - jtag jinterface ... is now adapter_name - jtag_khz ... is now adapter_khz - jtag_nsrst_delay ... is now adapter_nsrst_delay - jtag_nsrst_assert_width ... is now adapter_nsrst_assert_width - Support Voipac VPACLink JTAG Adapter. - -Boundary Scan: - -Transport framework core ... supporting future work for SWD, SPI, and other -non-JTAG ways to debug targets or program flash. - -Target Layer: - ARM: - - basic semihosting support for ARMv7M. - - renamed "armv7m" command prefix as "arm" - MIPS: - - "ejtag_srst" variant removed. The same functionality is - obtained by using "reset_config none". - - added PIC32MX software reset support, this means srst is not - required to be connected anymore. - OTHER: - - preliminary AVR32 AP7000 support. - -Flash Layer: - New "stellaris recover" command, implements the procedure - to recover locked devices (restoring non-volatile - state to the factory defaults, including erasing - the flash and its protection bits, and possibly - re-enabling hardware debugging). - PIC32MX now uses algorithm for flash programming, this - has increased the performance by approx 96%. - New 'pic32mx unlock' cmd to remove readout protection. - New STM32 Value Line Support. - New 'virtual' flash driver, used to associate other addresses - with a flash bank. See pic32mx.cfg for usage. - New iMX27 NAND flash controller driver. - -Board, Target, and Interface Configuration Scripts: - Support IAR LPC1768 kickstart board (by Olimex) - Support Voipac PXA270/PXA270M module. - New $PARPORTADDR tcl variable used to change default - parallel port address used. - Remove lm3s811.cfg; use "stellaris.cfg" instead - -Core Jim/TCL Scripting: - New "add_script_search_dir" command, behaviour is the same - as the "-s" cmd line option. - -Documentation: - -Build and Release: - -For more details about what has changed since the last release, -see the git repository history. With gitweb, you can browse that -in various levels of detail. - -For older NEWS, see the NEWS files associated with each release -(i.e. NEWS-). - -For more information about contributing test reports, bug fixes, or new -features and device support, please read the new Developer Manual (or -the BUGS and PATCHES.txt files in the source archive). - diff --git a/NEWS-0.6.0 b/NEWS-0.6.0 deleted file mode 100644 index 0acd24208..000000000 --- a/NEWS-0.6.0 +++ /dev/null @@ -1,54 +0,0 @@ -This file includes highlights of the changes made in the -OpenOCD source archive release. See the -repository history for details about what changed, including -bugfixes and other issues not mentioned here. - -JTAG Layer: - New STLINK V1/V2 JTAG/SWD adapter support. - New OSJTAG adapter support. - New Tincantools Flyswatter2 support. - Improved ULINK driver. - Improved RLINK driver. - Support for adapters based on FT232H chips. - New experimental driver for FTDI based adapters, using libusb-1.0 in asynchronous mode. - -Boundary Scan: - -Target Layer: - New Cortex-M0 support. - New Cortex-M4 support. - Improved Working area algorithm. - New RTOS support. Currently linux, FreeRTOS, ThreadX and eCos. - Connecting under reset to Cortex-Mx and MIPS chips. - -Flash Layer: - New SST39WF1601 support. - New EN29LV800BB support. - New async algorithm support for selected targets, stm32, stellaris and pic32. - New Atmel SAM3S, SAM3N support. - New ST STM32L support. - New Microchip PIC32MX1xx/2xx support. - New Freescale Kinetis K40 support. - -Board, Target, and Interface Configuration Scripts: - Support Dangerous Prototypes Bus Blaster. - Support ST SPEAr Family. - Support Gumstix Verdex boards. - Support TI Beaglebone. - -Documentation: - Improved HACKING info for submitting patches. - Fixed numerous broken links. - -Build and Release: - -For more details about what has changed since the last release, -see the git repository history. With gitweb, you can browse that -in various levels of detail. - -For older NEWS, see the NEWS files associated with each release -(i.e. NEWS-). - -For more information about contributing test reports, bug fixes, or new -features and device support, please read the new Developer Manual (or -the BUGS and PATCHES.txt files in the source archive). diff --git a/NEWS-0.7.0 b/NEWS-0.7.0 deleted file mode 100644 index 47a8fa662..000000000 --- a/NEWS-0.7.0 +++ /dev/null @@ -1,43 +0,0 @@ -This file includes highlights of the changes made in the -OpenOCD source archive release. See the -repository history for details about what changed, including -bugfixes and other issues not mentioned here. - -JTAG Layer: - New TI ICDI adapter support. - Support Latest OSBDM firmware. - Improved MIPS EJTAG Support. - -Boundary Scan: - -Target Layer: - New ARMv7R and Cortex-R4 support. - Added ChibiOS/RT support. - -Flash Layer: - New NXP LPC1850 support. - New NXP LPC4300 support. - New NXP SPIFI support. - New Energy Micro EFM32 support. - New ST STM32W support. - New ST STM32f2 write protection and lock/unlock support. - Ability to override STM32 flash bank size. - -Board, Target, and Interface Configuration Scripts: - Support Freescale i.MX6 series targets. - -Documentation: - New MIPS debugging info. - -Build and Release: - -For more details about what has changed since the last release, -see the git repository history. With gitweb, you can browse that -in various levels of detail. - -For older NEWS, see the NEWS files associated with each release -(i.e. NEWS-). - -For more information about contributing test reports, bug fixes, or new -features and device support, please read the new Developer Manual (or -the BUGS and PATCHES.txt files in the source archive). diff --git a/NEWS-0.8.0 b/NEWS-0.8.0 deleted file mode 100644 index 33b3af401..000000000 --- a/NEWS-0.8.0 +++ /dev/null @@ -1,111 +0,0 @@ -This file includes highlights of the changes made in the OpenOCD -source archive release. - -JTAG Layer: - * New CMSIS-DAP driver - * Andes AICE debug adapter support - * New OpenJTAG driver - * New BCM2835 (RaspberryPi) driver - * JTAG VPI client driver (for OpenRISC Reference Platform SoC) - * Xilinx BSCAN_* for OpenRISC support - * ST-LINKv2-1 support - * ST-LINKv2 SWO tracing support (UART emulation) - * JLink-OB (onboard) support - * Altera USB Blaster driver rewrite, initial Blaster II - support - * ULINK driver ported to libusb-1.0, OpenULINK build fixes - * Support up to 64 bit IR lengths - * SVF playback (FPGA programming) fixes - * "ftdi" interface driver got extensive testing and is now - recommended over the old ft2232 implementation - -Boundary Scan: - -Target Layer: - * New target: Andes nds32 - * New target: OpenRISC OR1K - * New target: Intel Quark X10xx - * MIPS EJTAG 1.5/2.0 support - * MIPS speed improvements - * Cortex-M, Cortex-A (MEM-AP, APB-AP) targets working with BE - hosts now - * XScale vector_catch support, reset fixes - * dsp563xx ad-hoc breakpoint/watchpoint support - * RTOS support for embKernel - * Target profiling improvements - * Memory access functions testbench - -Flash Layer: - * STM32 family sync with reference manuals, other bugfixes - * STM32F401, STM32F07x support - * Atmel SAM4L, SAMG5x support - * at91sam3sd8{a,b}, at91sam3s8{a,b,c}, at91sam4s, - at91sam3n0{a,b,0a,0b} support, bugfixes - * Atmel SAMD support - * Milandr 1986ВЕ* support - * Kinetis KL, K21 support - * Nuvoton NuMicro MINI5{1,2,4} support - * Nuvoton NUC910 series support - * NXP LPC43xx, LPC2000 fixes - * NXP LPC800, LPC810 support - * More ATmega parts supported - * Fujitsu MB9Ax family support - * EFM32 Wonder Gecko family support - * Nordic nRF51 support - -Board, Target, and Interface Configuration Scripts: - * STM32W108xx generic target config - * STM32F429 discovery board config - * STM32 Nucleo boards configs - * DENX M53EVK board config - * Altera Cyclone V SoC, SoCkit config - * New TI Launchpads board configs - * TI am43xx devices, AM437x GP EVM, AM438x ePOS EVM board - configs - * Marvell Armada 370 family initial support - * TI TMDX570LS31USB (TMS570, Cortex-R4) support scripts - * Freescale FRDM-KL25Z, KL46Z board configs - * Digilent Zedboard config - * Asus RT-N16, Linksys WRT54GL, BT HomeHub board configs - * Atmel Xplained initial support - * Broadcom bcm28155_ap board config - * TUMPA, TUMPA Lite interface configs - * Digilent JTAG-SMT2 interface config - * New RAM testing functions - * Easy-to-use firmware recovery helpers targetting ordinary - users with common equipment - -Server Layer: - * Auto-generation of GDB target description for ARMv7-M, - ARM4, nds32, OR1K, Quark - * GDB File-I/O Remote Protocol extension support - * Default GDB flashing events handlers to initialise and reset - the target automatically when "load" is used - -Documentation: - * Extensive README* changes - * The official User's Guide was proofread - * Example cross-build script - * RTOS documentation improvements - * Tcl RPC documentation and examples added - -Build and Release: - * *BSD, OS X, clang, ARM, windows build fixes - * New pkg-config support changes the way libusb (and other - dependencies) are handled. Many adapter drivers are now - selected automatically during the configure stage. - - -This release also contains a number of other important functional and -cosmetic bugfixes. For more details about what has changed since the -last release, see the git repository history: - -http://sourceforge.net/p/openocd/code/ci/v0.8.0/log/?path= - - -For older NEWS, see the NEWS files associated with each release -(i.e. NEWS-). - -For more information about contributing test reports, bug fixes, or new -features and device support, please read the new Developer Manual (or -the BUGS and PATCHES.txt files in the source archive). diff --git a/NEWS-0.9.0 b/NEWS-0.9.0 deleted file mode 100644 index 77ae4b070..000000000 --- a/NEWS-0.9.0 +++ /dev/null @@ -1,110 +0,0 @@ -This file includes highlights of the changes made in the OpenOCD -source archive release. - -JTAG Layer: - * SWD support with FTDI, Versaloon, J-Link, sysfsgpio - * CMSIS-DAP massive speed and stability improvements - * Versaloon driver ported to libusb-1.0 - * STLink can reestablish communication with a target that was - disconnected or rebooted - * STLink FAULT and WAIT SWD handling improved - * New hla_serial command to distinguish between several HLA - adapters attached to a single machine - * Serial number support for CMSIS-DAP and J-Link adapters - * Support for more J-Link adapters - * TAP autoprobing improvements - * Big speedup for SVF playback with USB Blaster - -Boundary Scan: - -Target Layer: - * Stability improvements for targets that get disconnected or - rebooted during a debug session - * MIPS speed and reliability improvements - * MIPS 1.5/2.0 fixes - * ARMv7-R improvements - * Cortex-A improvements, A7, A15 MPCores support - * FPU support for ARMv7-M (Cortex-M4F) - * TPIU/ITM support (including SWO/SWV tracing), can be - captured with external tools or STLink - * JTAG Serial Port (Advanced Debug System softcore) support - * Profiling support for OpenRISC - * ChibiOS/RT 3.0 support (with and without FPU) - * FreeRTOS current versions support - * Freescale MQX RTOS support - * GDB target description support for MIPS - * The last created target is auto-selected as the current - -Flash Layer: - * nRF51 async loader to improve flashing performance and stability - * Cypress PSoC 41xx/42xx and CCG1 families flash driver - * Silabs SiM3 family flash driver - * Marvell Wireless Microcontroller SPI flash driver - * Kinetis mass erase (part unsecuring) implemented - * lpcspifi stability fixes - * STM32 family sync with reference manuals, L0 support, bugfixes - * LPC2000 driver automatically determines part and flash size - * NXP LPC11(x)xx, LPC13xx, LPC15xx, LPC8xx, LPC5410x, LPC407x support - * Atmel SAMD, SAMR, SAML21 devices support - * Atmel SAM4E16 support - * ZeroGecko family support - * TI Tiva C Blizzard and Snowflake families support - * Nuvoton NuMicro M051 support - * EZR32 support in EFM32 driver - -Board, Target, and Interface Configuration Scripts: - * Normal target configs can work with HLA (STLink, ICDI) adapters - * STM32 discovery and Nucleo boards configs - * Gumstix AeroCore board config - * General Plus GP326XXXA target config - * Micrel KS869x target config - * ASUS RT-N66U board config - * Atmel SAM4E-EK board config - * Atmel AT91SAM4L proper reset handling implemented - * TI OMAP/AM 3505, 3517 target configs - * nRF51822-mKIT board config - * RC Module К1879ХБ1Я target config - * TI TMDX570LS20SUSB board config - * TI TMS570 USB Kit board config - * TI CC2538, CC26xx target configs - * TI AM437x major config improvements, DDR support - * TI AM437X IDK board config - * TI SimpleLink Wi-Fi CC3200 LaunchPad configs - * Silicon Labs EM357, EM358 target configs - * Infineon XMC1000, XMC4000 family targets and boards configs - * Atheros AR9331 target config - * TP-LINK TL-MR3020 board config - * Alphascale asm9260t target and eval kit configs - * Olimex SAM7-LA2 (AT91SAM7A2) board config - * EFM32 Gecko boards configs - * Spansion FM4 target and SK-FM4-176L-S6E2CC board configs - * LPC1xxx target configs were restructured - * IoT-LAB debug adapter config - * DP BusBlaster KT-Link compatible config - -Server Layer: - * Polling period can be configured - * "shutdown" command has an immediate effect - * The "program" command doesn't lead to a shutdown by - default, use optional "exit" parameter for the old behaviour - * Proper OS signal handling was implemented - * Async target notifications for the Tcl RPC - -Documentation: - -Build and Release: - - -This release also contains a number of other important functional and -cosmetic bugfixes. For more details about what has changed since the -last release, see the git repository history: - -http://sourceforge.net/p/openocd/code/ci/v0.9.0/log/?path= - - -For older NEWS, see the NEWS files associated with each release -(i.e. NEWS-). - -For more information about contributing test reports, bug fixes, or new -features and device support, please read the new Developer Manual (or -the BUGS and PATCHES.txt files in the source archive). diff --git a/NEWTAPS b/NEWTAPS deleted file mode 100644 index 10f300632..000000000 --- a/NEWTAPS +++ /dev/null @@ -1,145 +0,0 @@ -Reporting Unknown JTAG TAP IDS ------------------------------- - -If OpenOCD reports an UNKNOWN or Unexpected Tap ID please report it to -the development mailing list - However - keep reading. - -openocd-devel@lists.sourceforge.net. - -======================================== - -About "UNEXPECTED" tap ids. - - Before reporting an "UNEXPECTED TAP ID" - take a closer look. - Perhaps you have your OpenOCD configured the wrong way, maybe you - have the tap configured the wrong way? Or something else is wrong. - (Remember: OpenOCD does not stop if the tap is not present) - - This "tap id check" is there for a purpose. - The goal is to help get the *right* configuration. - -The idea is this: - - Every JTAG tap is suppose to have "a unique 32bit tap id" number. - They are suppose to be "sort of unique" but they are not. There are - no guarantees. - -Version Number Changes: - - Sometimes, the tap ID only differs by VERSION number. If so - it's - not a big deal. Please do report this information. We'd like to - know about it. - - For example - -Error: ERROR: Tap: s3c4510.cpu - Expected id: 0x3f0f0f0f, Got: 0x1f0f0f0f -Error: ERROR: expected: mfg: 0x787, part: 0xf0f0, ver: 0x3 -Error: ERROR: got: mfg: 0x787, part: 0xf0f0, ver: 0x1 - -======================================== - -Updating the Tap ID number your self - - Why do this? You just want the warning to go away. And don't want - to update your version/instance of OpenOCD. - - On simple systems, to fix this problem, in your "openocd.cfg" file, - override the tap id. Depending on the tap, add one of these 3 - commands: - - set CPUTAPID newvalue - or set BSTAPID newvalue - or set FLASHTAPID newvalue - or set ETMTAPID newvalue - - Where "newvalue" is the new value you are seeing. - - On complex systems, (with many taps and chips) you probably have a - custom configuration file. Its is more complicated, you're going to - have to read through the configuration files - -======================================== - -What to send: - -Cut & paste the output of OpenOCD that pointed you at this file. - -Please include the VERSION number of OpenOCD you are using. - -And please include the information below. - -======================================== - -A) The JTAG TAP ID code. - -This is always a 32bit hex number. - -Examples: - 0x1f0f0f0f - is an old ARM7TDMI - 0x3f0f0f0f - is a newer ARM7TDMI - 0x3ba00477 - is an ARM Cortex-M3 - -Some chips have multiple JTAG taps - be sure to list -each one individually - ORDER is important! - -======================================== -B) The maker of the part - -Examples: - Xilinx, Atmel, ST Micro Systems, Freescale - -======================================== -C) The family of parts it belongs to - -Examples: - "NXP LPC Series" - "Atmel SAM7 Series" - -======================================== - -D) The actual part number on the package - - For example: "S3C45101x01" - -======================================== - -E) What type of board it is. - -ie: a "commercial off the self eval board" that one can purchase (as -opposed to your private internal custom board) - -For example: ST Micro systems has Eval boards, so does Analog Devices - -Or - if it is inside something "hackers like to hack" that information -is helpful too. - -For example: A consumer GPS unit or a cellphone - -======================================== - -(F) The maker of the board - ie: Olimex, LogicPD, Freescale(eval board) - -======================================== - -(G) Identifying information on the board. - - Not good: "iar red ST eval board" - - Really good: "IAR STR912-SK evaluation board" - -======================================== - -(H) Are there other interesting (JTAG) chips on the board? - - ie: An FPGA or CPLD ... - -======================================== - -(I) What target config files need updating? - - In fact it's best if you submit a patch with those - updates. Most of the other information listed here - is just to help create a good patch. - -======================================== diff --git a/README b/README deleted file mode 100644 index df4bc3b0c..000000000 --- a/README +++ /dev/null @@ -1,372 +0,0 @@ -Welcome to OpenOCD! -=================== - -OpenOCD provides on-chip programming and debugging support with a -layered architecture of JTAG interface and TAP support including: - -- (X)SVF playback to faciliate automated boundary scan and FPGA/CPLD - programming; -- debug target support (e.g. ARM, MIPS): single-stepping, - breakpoints/watchpoints, gprof profiling, etc; -- flash chip drivers (e.g. CFI, NAND, internal flash); -- embedded TCL interpreter for easy scripting. - -Several network interfaces are available for interacting with OpenOCD: -telnet, TCL, and GDB. The GDB server enables OpenOCD to function as a -"remote target" for source-level debugging of embedded systems using -the GNU GDB program (and the others who talk GDB protocol, e.g. IDA -Pro). - -This README file contains an overview of the following topics: - -- quickstart instructions, -- how to find and build more OpenOCD documentation, -- list of the supported hardware, -- the installation and build process, -- packaging tips. - - -============================ -Quickstart for the impatient -============================ - -If you have a popular board then just start OpenOCD with its config, -e.g.: - - openocd -f board/stm32f4discovery.cfg - -If you are connecting a particular adapter with some specific target, -you need to source both the jtag interface and the target configs, -e.g.: - - openocd -f interface/ftdi/jtagkey2.cfg -c "transport select jtag" \ - -f target/ti_calypso.cfg - - openocd -f interface/stlink-v2-1.cfg -c "transport select hla_swd" \ - -f target/stm32l0.cfg - -NB: when using an FTDI-based adapter you should prefer configs in the -ftdi directory; the old configs for the ft2232 are deprecated. - -After OpenOCD startup, connect GDB with - - (gdb) target extended-remote localhost:3333 - - -===================== -OpenOCD Documentation -===================== - -In addition to the in-tree documentation, the latest manuals may be -viewed online at the following URLs: - - OpenOCD User's Guide: - http://openocd.org/doc/html/index.html - - OpenOCD Developer's Manual: - http://openocd.org/doc/doxygen/html/index.html - -These reflect the latest development versions, so the following section -introduces how to build the complete documentation from the package. - -For more information, refer to these documents or contact the developers -by subscribing to the OpenOCD developer mailing list: - - openocd-devel@lists.sourceforge.net - -Building the OpenOCD Documentation ----------------------------------- - -By default the OpenOCD build process prepares documentation in the -"Info format" and installs it the standard way, so that "info openocd" -can access it. - -Additionally, the OpenOCD User's Guide can be produced in the -following different formats: - - # If PDFVIEWER is set, this creates and views the PDF User Guide. - make pdf && ${PDFVIEWER} doc/openocd.pdf - - # If HTMLVIEWER is set, this creates and views the HTML User Guide. - make html && ${HTMLVIEWER} doc/openocd.html/index.html - -The OpenOCD Developer Manual contains information about the internal -architecture and other details about the code: - - # NB! make sure doxygen is installed, type doxygen --version - make doxygen && ${HTMLVIEWER} doxygen/index.html - - -================== -Supported hardware -================== - -JTAG adapters -------------- - -AICE, ARM-JTAG-EW, ARM-USB-OCD, ARM-USB-TINY, AT91RM9200, axm0432, -BCM2835, Bus Blaster, Buspirate, Chameleon, CMSIS-DAP, Cortino, DENX, -Digilent JTAG-SMT2, DLC 5, DLP-USB1232H, embedded projects, eStick, -FlashLINK, FlossJTAG, Flyswatter, Flyswatter2, Gateworks, Hoegl, ICDI, -ICEBear, J-Link, JTAG VPI, JTAGkey, JTAGkey2, JTAG-lock-pick, KT-Link, -Lisa/L, LPC1768-Stick, MiniModule, NGX, NXHX, OOCDLink, Opendous, -OpenJTAG, Openmoko, OpenRD, OSBDM, Presto, Redbee, RLink, SheevaPlug -devkit, Stellaris evkits, ST-LINK (SWO tracing supported), -STM32-PerformanceStick, STR9-comStick, sysfsgpio, TUMPA, Turtelizer, -ULINK, USB-A9260, USB-Blaster, USB-JTAG, USBprog, VPACLink, VSLLink, -Wiggler, XDS100v2, Xverve. - -Debug targets -------------- - -ARM11, ARM7, ARM9, AVR32, Cortex-A, Cortex-R, Cortex-M, LS102x-SAP, -Feroceon/Dragonite, DSP563xx, DSP5680xx, FA526, MIPS EJTAG, NDS32, -XScale, Intel Quark. - -Flash drivers -------------- - -ADUC702x, AT91SAM, AVR, CFI, DSP5680xx, EFM32, EM357, FM3, FM4, Kinetis, -LPC8xx/LPC1xxx/LPC2xxx/LPC541xx, LPC2900, LPCSPIFI, Marvell QSPI, -Milandr, NIIET, NuMicro, PIC32mx, PSoC4, SiM3x, Stellaris, STM32, STMSMI, -STR7x, STR9x, nRF51; NAND controllers of AT91SAM9, LPC3180, LPC32xx, -i.MX31, MXC, NUC910, Orion/Kirkwood, S3C24xx, S3C6400, XMC1xxx, XMC4xxx. - - -================== -Installing OpenOCD -================== - -A Note to OpenOCD Users ------------------------ - -If you would rather be working "with" OpenOCD rather than "on" it, your -operating system or JTAG interface supplier may provide binaries for -you in a convenient-enough package. - -Such packages may be more stable than git mainline, where -bleeding-edge development takes place. These "Packagers" produce -binary releases of OpenOCD after the developers produces new "release" -versions of the source code. Previous versions of OpenOCD cannot be -used to diagnose problems with the current release, so users are -encouraged to keep in contact with their distribution package -maintainers or interface vendors to ensure suitable upgrades appear -regularly. - -Users of these binary versions of OpenOCD must contact their Packager to -ask for support or newer versions of the binaries; the OpenOCD -developers do not support packages directly. - -A Note to OpenOCD Packagers ---------------------------- - -You are a PACKAGER of OpenOCD if you: - -- Sell dongles and include pre-built binaries; -- Supply tools or IDEs (a development solution integrating OpenOCD); -- Build packages (e.g. RPM or DEB files for a GNU/Linux distribution). - -As a PACKAGER, you will experience first reports of most issues. -When you fix those problems for your users, your solution may help -prevent hundreds (if not thousands) of other questions from other users. - -If something does not work for you, please work to inform the OpenOCD -developers know how to improve the system or documentation to avoid -future problems, and follow-up to help us ensure the issue will be fully -resolved in our future releases. - -That said, the OpenOCD developers would also like you to follow a few -suggestions: - -- Send patches, including config files, upstream, participate in the - discussions; -- Enable all the options OpenOCD supports, even those unrelated to your - particular hardware; -- Use "ftdi" interface adapter driver for the FTDI-based devices. - -As a PACKAGER, never link against the FTD2XX library, as the resulting -binaries can't be legally distributed, due to the restrictions of the -GPL. - - -================ -Building OpenOCD -================ - -The INSTALL file contains generic instructions for running 'configure' -and compiling the OpenOCD source code. That file is provided by -default for all GNU autotools packages. If you are not familiar with -the GNU autotools, then you should read those instructions first. - -The remainder of this document tries to provide some instructions for -those looking for a quick-install. - -OpenOCD Dependencies --------------------- - -GCC or Clang is currently required to build OpenOCD. The developers -have begun to enforce strict code warnings (-Wall, -Werror, -Wextra, -and more) and use C99-specific features: inline functions, named -initializers, mixing declarations with code, and other tricks. While -it may be possible to use other compilers, they must be somewhat -modern and could require extending support to conditionally remove -GCC-specific extensions. - -You'll also need: - -- make -- libtool -- pkg-config >= 0.23 (or compatible) - -Additionally, for building from git: - -- autoconf >= 2.64 -- automake >= 1.9 -- texinfo - -USB-based adapters depend on libusb-1.0 and some older drivers require -libusb-0.1 or libusb-compat-0.1. A compatible implementation, such as -FreeBSD's, additionally needs the corresponding .pc files. - -USB-Blaster, ASIX Presto, OpenJTAG and ft2232 interface adapter -drivers need either one of: - - libftdi: http://www.intra2net.com/en/developer/libftdi/index.php - - ftd2xx: http://www.ftdichip.com/Drivers/D2XX.htm (proprietary, - GPL-incompatible) - -CMSIS-DAP support needs HIDAPI library. - -Permissions delegation ----------------------- - -Running OpenOCD with root/administrative permissions is strongly -discouraged for security reasons. - -For USB devices on GNU/Linux you should use the contrib/99-openocd.rules -file. It probably belongs somewhere in /etc/udev/rules.d, but -consult your operating system documentation to be sure. Do not forget -to add yourself to the "plugdev" group. - -For parallel port adapters on GNU/Linux and FreeBSD please change your -"ppdev" (parport* or ppi*) device node permissions accordingly. - -For parport adapters on Windows you need to run install_giveio.bat -(it's also possible to use "ioperm" with Cygwin instead) to give -ordinary users permissions for accessing the "LPT" registers directly. - -Compiling OpenOCD ------------------ - -To build OpenOCD, use the following sequence of commands: - - ./bootstrap (when building from the git repository) - ./configure [options] - make - sudo make install - -The 'configure' step generates the Makefiles required to build -OpenOCD, usually with one or more options provided to it. The first -'make' step will build OpenOCD and place the final executable in -'./src/'. The final (optional) step, ``make install'', places all of -the files in the required location. - -To see the list of all the supported options, run - ./configure --help - -Cross-compiling Options ------------------------ - -Cross-compiling is supported the standard autotools way, you just need -to specify the cross-compiling target triplet in the --host option, -e.g. for cross-building for Windows 32-bit with MinGW on Debian: - - ./configure --host=i686-w64-mingw32 [options] - -To make pkg-config work nicely for cross-compiling, you might need an -additional wrapper script as described at - - http://www.flameeyes.eu/autotools-mythbuster/pkgconfig/cross-compiling.html - -This is needed to tell pkg-config where to look for the target -libraries that OpenOCD depends on. Alternatively, you can specify -*_CFLAGS and *_LIBS environment variables directly, see "./configure ---help" for the details. - -Parallel Port Dongles ---------------------- - -If you want to access the parallel port using the PPDEV interface you -have to specify both --enable-parport AND --enable-parport-ppdev, since the -the later option is an option to the parport driver. - -The same is true for the --enable-parport-giveio option, you have to -use both the --enable-parport AND the --enable-parport-giveio option -if you want to use giveio instead of ioperm parallel port access -method. - -Using FTDI's FTD2XX -------------------- - -The (closed source) FTDICHIP.COM solution is faster than libftdi on -Windows. That is the motivation for supporting it even though its -licensing restricts it to non-redistributable OpenOCD binaries, and it -is not available for all operating systems used with OpenOCD. You may, -however, build such copies for personal use. - -The FTDICHIP drivers come as either a (win32) ZIP file, or a (Linux) -TAR.GZ file. You must unpack them ``some where'' convenient. As of this -writing FTDICHIP does not supply means to install these files "in an -appropriate place." - -You should use the following ./configure options to make use of -FTD2XX: - - --with-ftd2xx-win32-zipdir - Where (CYGWIN/MINGW) the zip file from ftdichip.com - was unpacked - --with-ftd2xx-linux-tardir - Where (Linux/Unix) the tar file from ftdichip.com - was unpacked - --with-ftd2xx-lib=(static|shared) - Use static or shared ftd2xx libs (default is static) - -Remember, this library is binary-only, while OpenOCD is licenced -according to GNU GPLv2 without any exceptions. That means that -_distributing_ copies of OpenOCD built with the FTDI code would -violate the OpenOCD licensing terms. - -Note that on Linux there is no good reason to use these FTDI binaries; -they are no faster (on Linux) than libftdi, and cause licensing issues. - - -========================== -Obtaining OpenOCD From GIT -========================== - -You can download the current GIT version with a GIT client of your -choice from the main repository: - - git://git.code.sf.net/p/openocd/code - -You may prefer to use a mirror: - - http://repo.or.cz/r/openocd.git - git://repo.or.cz/openocd.git - -Using the GIT command line client, you might use the following command -to set up a local copy of the current repository (make sure there is no -directory called "openocd" in the current directory): - - git clone git://git.code.sf.net/p/openocd/code openocd - -Then you can update that at your convenience using - - git pull - -There is also a gitweb interface, which you can use either to browse -the repository or to download arbitrary snapshots using HTTP: - - http://repo.or.cz/w/openocd.git - -Snapshots are compressed tarballs of the source tree, about 1.3 MBytes -each at this writing. diff --git a/README.OSX b/README.OSX deleted file mode 100644 index 979c64ba6..000000000 --- a/README.OSX +++ /dev/null @@ -1,49 +0,0 @@ -Building OpenOCD for OSX ------------------------- - -There are a few prerequisites you will need first: - -- Xcode 5 (install from the AppStore) -- Command Line Tools (install from Xcode 5 -> Preferences -> Downloads) -- Gentoo Prefix (http://www.gentoo.org/proj/en/gentoo-alt/prefix/bootstrap.xml) - or -- Homebrew (http://mxcl.github.io/homebrew/) - or -- MacPorts (http://www.macports.org/install.php) - - -With Gentoo Prefix you can build the release version or the latest -devel version (-9999) the usual way described in the Gentoo -documentation. Alternatively, install the prerequisites and build -manually from the sources. - - -With Homebrew you can either run: - brew install [--HEAD] openocd (where optional --HEAD asks brew to - install the current git version) - or - brew install libtool automake libusb [libusb-compat] [hidapi] [libftdi] - (to install the needed dependencies and then proceed with the - manual building procedure) - - -For building with MacPorts you need to run: - sudo port install libtool automake autoconf pkgconfig \ - libusb [libusb-compat] [libftdi1] - -You should also specify LDFLAGS and CPPFLAGS to allow configure to use -MacPorts' libraries, so run configure like this: - LDFLAGS=-L/opt/local/lib CPPFLAGS=-I/opt/local/include ./configure [options] - - -See README for the generic building instructions. - -If you're using a USB adapter and have a driver kext matched to it, -you will need to unload it prior to running OpenOCD. E.g. with Apple -driver (OS X 10.9 or later) for FTDI run: - sudo kextunload -b com.apple.driver.AppleUSBFTDI -for FTDI vendor driver use: - sudo kextunload FTDIUSBSerialDriver.kext - -To learn more on the topic please refer to the official libusb FAQ: -https://github.com/libusb/libusb/wiki/FAQ diff --git a/README.Windows b/README.Windows deleted file mode 100644 index 6c616f38a..000000000 --- a/README.Windows +++ /dev/null @@ -1,60 +0,0 @@ -Building OpenOCD for Windows ----------------------------- - -You can build OpenOCD for Windows natively with either MinGW-w64/MSYS -or Cygwin (plain MinGW might work with --disable-werror but is not -recommended as it doesn't provide enough C99 compatibility). -Alternatively, one can cross-compile it using MinGW-w64 on a *nix -host. See README for the generic instructions. - -Also, the MSYS2 project provides both ready-made binaries and an easy -way to self-compile from their software repository out of the box. - -Native MinGW-w64/MSYS compilation ------------------------------ - -As MSYS doesn't come with pkg-config pre-installed, you need to add it -manually. The easiest way to do that is to download pkg-config-lite -from: - - http://sourceforge.net/projects/pkgconfiglite/ - -Then simply unzip the archive to the root directory of your MinGW-w64 -installation. - -USB adapters ------------- - -For the adapters that use a HID-based protocol, e.g. CMSIS-DAP, you do -not need to perform any additional configuration. - -For all the others you usually need to have WinUSB.sys (or -libusbK.sys) driver installed. Some vendor software (e.g. for -ST-LINKv2) does it on its own. For the other cases the easiest way to -assign WinUSB to a device is to use the latest Zadig installer: - - http://zadig.akeo.ie - -When using a composite USB device, it's often necessary to assign -WinUSB.sys to the composite parent instead of the specific -interface. To do that one needs to activate an advanced option in the -Zadig installer. - -For the old drivers that use libusb-0.1 API you might need to link -against libusb-win32 headers and install the corresponding driver with -Zadig. - -If you need to use the same adapter with other applications that may -require another driver, a solution for Windows Vista and above is to -activate the IgnoreHWSerNum registry setting for the USB device. - -That setting forces Windows to associate the driver per port instead of -per serial number, the same behaviour as when the device does not contain -a serial number. So different drivers can be installed for the adapter on -different ports and you just need to plug the adapter into the correct -port depending on which application to use. - -For more information, see: - - http://msdn.microsoft.com/en-us/library/windows/hardware/jj649944(v=vs.85).aspx - http://www.ftdichip.com/Support/Knowledgebase/index.html?ignorehardwareserialnumber.htm diff --git a/TODO b/TODO deleted file mode 100644 index f50af3ec5..000000000 --- a/TODO +++ /dev/null @@ -1,380 +0,0 @@ -// This file is part of the Doxygen Developer Manual -/** @page tasks Pending and Open Tasks - -This page lists pending and open tasks being considered or worked upon -by the OpenOCD community. - -@section thelist The List - -Most items are open for the taking, but please post to the mailing list -before spending much time working on anything lists here. The community -may have evolved an idea since it was added here. - -Feel free to send patches to add or clarify items on this list, too. - -@section thelisttcl TCL - -This section provides possible things to improve with OpenOCD's TCL support. - -- Fix problem with incorrect line numbers reported for a syntax - error in a reset init event. - -- organize the TCL configurations: - - provide more directory structure for boards/targets? - - factor configurations into layers (encapsulation and re-use) - -- Fix handling of variables between multiple command line "-c" and "-f" - parameters. Currently variables assigned through one such parameter - command/script are unset before the next one is invoked. - -- Isolate all TCL command support: - - Pure C CLI implementations using --disable-builtin-tcl. - - Allow developers to build new dongles using OpenOCD's JTAG core. - - At first, provide only low-level JTAG support; target layer and - above rely heavily on scripting event mechanisms. - - Allow full TCL support? add --with-tcl=/path/to/installed/tcl - - Move TCL support out of foo.[ch] and into foo_tcl.[ch] (other ideas?) - - See src/jtag/core.c and src/jtag/tcl.c for an example. - - allow some of these TCL command modules to be dynamically loadable? - -@section thelistjtag JTAG - -This section list issues that need to be resolved in the JTAG layer. - -@subsection thelistjtagcore JTAG Core - -The following tasks have been suggested for cleaning up the JTAG layer: - -- use tap_set_state everywhere to allow logging TAP state transitions -- Encapsulate cmd_queue_cur_state and related variable handling. -- add slick 32 bit versions of jtag_add_xxx_scan() that avoids -buf_set_u32() calls and other evidence of poor impedance match between -API and calling code. New API should cut down # of lines in calling -code by 100's and make things clearer. Also potentially be supported -directly in minidriver API for better embedded host performance. - -The following tasks have been suggested for adding new core JTAG support: - -- Improve autodetection of TAPs by supporting tcl escape procedures that - can configure discovered TAPs based on IDCODE value ... they could: - - Remove guessing for irlen - - Allow non-default irmask/ircapture values -- SPI/UART emulation: - - (ab)use bit-banging JTAG interfaces to emulate SPI/UART - - allow SPI to program flash, MCUs, etc. - -@subsection thelistjtaginterfaces JTAG Interfaces - -There are some known bugs to fix in JTAG adapter drivers: - -- For JTAG_STATEMOVE to TAP_RESET, all drivers must ignore the current - recorded state. The tap_get_state() call won't necessarily return - the correct value, especially at server startup. Fix is easy: in - that case, always issue five clocks with TMS high. - - amt_jtagaccel.c - - arm-jtag-ew.c - - bitbang.c - - bitq.c - - gw16012.c - - jlink.c - - usbprog.c - - vsllink.c - - rlink/rlink.c -- bug: USBprog is broken with new tms sequence; it needs 7-clock cycles. - Fix promised from Peter Denison openwrt at marshadder.org - Workaround: use "tms_sequence long" @par - https://lists.berlios.de/pipermail/openocd-development/2009-July/009426.html - -The following tasks have been suggested for improving OpenOCD's JTAG -interface support: - -- rework USB communication to be more robust. Two possible options are: - -# use libusb-1.0.1 with libusb-compat-0.1.1 (non-blocking I/O wrapper) - -# rewrite implementation to use non-blocking I/O -- J-Link driver: - - fix to work with long scan chains, such as R.Doss's svf test. -- FT2232 (libftdi): - - make performance comparable to alternatives (on Win32, D2XX is faster) - - make usability comparable to alternatives -- Autodetect USB based adapters; this should be easy on Linux. If there's - more than one, list the options; otherwise, just select that one. - -The following tasks have been suggested for adding new JTAG interfaces: - -- TCP driver: allow client/server for remote JTAG interface control. -This requires a client and a server. The server is built into the -normal OpenOCD and takes commands from the client and executes -them on the interface returning the result of TCP/IP. The client -is an OpenOCD which is built with a TCP/IP minidriver. The use -of a minidriver is required to capture all the jtag_add_xxx() -fn's at a high enough level and repackage these cmd's as -TCP/IP packets handled by the server. - -@section thelistswd Serial Wire Debug - -- implement Serial Wire Debug interface - -@section thelistbs Boundary Scan Support - -- add STAPL support? -- add BSDL support? - -A few possible options for the above: - -# Fake a TCL equivalent? - -# Integrate an existing library? - -# Write a new C implementation a la Jim? - -Once the above are completed: -- add support for programming flash using boundary scan techniques -- add integration with a modified gerber view program: - - provide means to view the PCB and select pins and traces - - allow use-cases such as the following: - - @b Stimulus - -# Double-click on a pin (or trace) with the mouse. - - @b Effects - -# The trace starts blinking, and - -# OpenOCD toggles the pin(s) 0/1. - -@section thelisttargets Target Support - -- Many common ARM cores could be autodetected using IDCODE -- general layer cleanup: @par - https://lists.berlios.de/pipermail/openocd-development/2009-May/006590.html -- regression: "reset halt" between 729(works) and 788(fails): @par -https://lists.berlios.de/pipermail/openocd-development/2009-July/009206.html -- registers - - add flush-value operation, call them all on resume/reset -- mcr/mrc target->type support - - missing from ARM920t, ARM966e, XScale. - It's possible that the current syntax is unable to support read-modify-write - operations(see arm966e). - - mcr/mrc - retire cp15 commands when there the mrc/mrc commands have been - tested from: arm926ejs, arm720t, cortex_a8 -- ARM7/9: - - clean up "arm9tdmi vector_catch". Available for some arm7 cores? @par -https://lists.berlios.de/pipermail/openocd-development/2009-October/011488.html -https://lists.berlios.de/pipermail/openocd-development/2009-October/011506.html - - add reset option to allow programming embedded ice while srst is asserted. - Some CPUs will gate the JTAG clock when srst is asserted and in this case, - it is necessary to program embedded ice and then assert srst afterwards. -- ARM926EJS: - - reset run/halt/step is not robust; needs testing to map out problems. -- ARM11 improvements (MB?) - - add support for asserting srst to reset the core. - - Single stepping works, but should automatically - use hardware stepping if available. - - mdb can return garbage data if read byte operation fails for - a memory region(16 & 32 byte access modes may be supported). Is this - a bug in the .MX31 PDK init script? Try on i.MX31 PDK: - mdw 0xb80005f0 0x8, mdh 0xb80005f0 0x10, mdb 0xb80005f0 0x20. mdb returns - garabage. - - implement missing functionality (grep FNC_INFO_NOTIMPLEMENTED ...) -- Thumb2 single stepping: ARM1156T2 needs simulator support -- Cortex-A8 support (ML) - - add target implementation (ML) -- Cortex-M3 support - - when stepping, only write dirtied registers (be faster) - - when connecting to halted core, fetch registers (startup is quirky) -- Generic ARM run_algorithm() interface - - tagged struct wrapping ARM instructions and metadata - - not revision-specific (current: ARMv4+ARMv5 -or- ARMv6 -or- ARMv7) - - usable with at least arm_nandwrite() and generic CFI drivers -- ETM - - don't show FIFOFULL registers if they're not supported - - use comparators to get more breakpoints and watchpoints - - add "etm drivers" command - - trace driver init() via examine() paths only, not setup()/reset -- MC1322x support (JW/DE?) - - integrate and test support from JW (and DE?) - - get working with a known good interface (i.e. not today's jlink) -- AT91SAM92xx: - - improvements for unknown-board-atmel-at91sam9260.cfg (RD) -- STR9x: (ZW) - - improvements to str912.cfg to be more general purpose -- AVR: (SQ) - - independently verify implementation - - incrementally improve working prototype in trunk. (SQ) - - work out how to debug this target - - AVR debugging protocol. -- FPGA: - - Altera Nios Soft-CPU support -- Coldfire (suggested by NC) - - can we draw from the BDM project? @par - http://bdm.sourceforge.net/ - - or the OSBDM package @par - http://forums.freescale.com/freescale/board/message?board.id=OSBDM08&thread.id=422 - -@section thelistsvf SVF/XSVF - -- develop SVF unit tests -- develop XSVF unit tests - -@section thelistflash Flash Support - -- finish documentation for the following flash drivers: - - avr - - pic32mx - - ocl - - str9xpec - -- Don't expect writing all-ones to be a safe way to write without - changing bit values. Minimally it loses on flash modules with - internal ECC, where it may change the ECC. - - NOR flash_write_unlock() does that between sectors - - there may be other cases too - -- Make sure all commands accept either a bank name or a bank number, - and be sure both identifiers show up in "flash banks" and "nand list". - Right now the user-friendly names are pretty much hidden... - -@subsection thelistflashcfi CFI - -- finish implementing bus width/chip width handling (suggested by NC) -- factor vendor-specific code into separate source files - - add new callback interface for vendor-specific code -- investigate/implement "thin wrapper" to use eCos CFI drivers (ØH) - -@section thelistdebug Debugger Support - -- add support for masks in watchpoints? @par - https://lists.berlios.de/pipermail/openocd-development/2009-October/011507.html -- breakpoints can get lost in some circumstances: @par - https://lists.berlios.de/pipermail/openocd-development/2009-June/008853.html -- add support for masks in watchpoints. The trick is that GDB does not - support a breakpoint mask in the remote protocol. One way to work around - this is to add a separate command "watchpoint_mask add/rem ", that - is run to register a list of masks that the gdb_server knows to use with - a particular watchpoint address. -- integrate Keil AGDI interface to OpenOCD? (submitted by Dario Vecchio) - -@section thelisttesting Testing Suite - -This section includes several related groups of ideas: -- @ref thelistunittests -- @ref thelistsmoketests -- @ref thelisttestreports -- @ref thelisttestgenerichw - -@subsection thelistunittests Unit Tests - -- add testing skeleton to provide frameworks for adding tests -- implement server unit tests -- implement JTAG core unit tests -- implement JTAG interface unit tests -- implement flash unit tests -- implement target unit tests - -@subsection thelistsmoketests Smoke Test Tools - --# extend 'make check' with a smoketest app - - checks for OOCD_TEST_CONFIG, etc. in environment (or config file) - - if properly set, runs the smoke test with specified parameters - - openocd -f ${OOCD_TEST_CONFIG} - - implies a modular test suite (see below) - - should be able to run some minimal tests with dummy interface: - - compare results of baseline sanity checks with expected results - --# builds a more complete test suite: - - existing testing/examples/ look like a great start - - all targets should be tested fully and for all capabilities - - we do NOT want a "lowest common denominator" test suite - - ... but can we start with one to get going? - - probably requires one test configuration file per board/target - - modularization can occur here, just like with targets/boards/chips - - coverage can increase over time, building up bundles of tests - --# add new 'smoketest' Makefile target: - - calls 'make check' (and the smoketest app) - - gather inputs and output into a report file - -@subsection thelisttestreports Test Feedback Tools - -These ideas were first introduced here: @par - https://lists.berlios.de/pipermail/openocd-development/2009-May/006358.html - -- provide report submission scripts for e-mail and web forms -- add new Makefile targets to post the report: - - 'checkreportsend' -- send to list via e-mail (via sendmail) - - 'checkreportpost' -- send web form (via curl or other script) - -@subsection thelisttestgenerichw Generic Hardware Tester - -- implement VHDL to use for FPGA-based JTAG TAP testing device -- develop test suite that utilizes this testing device - -@section thelistautotools Autotools Build System - -- make entire configure process require less user consideration: - - automatically detect the features that are available, unless - options were specifically provided to configure - - provide a report of the drivers that will be build at the end of - running configure, so the users can verify which drivers will be - built during 'make' (and their options) . -- eliminate sources of confusion in @c bootstrap script: - -# Make @c bootstrap call 'configure --enable-maintainer-mode \'? - -# Add @c buildstrap script to assist with bootstrap and configure steps. -- automatically build tool-chains required for cross-compiling - - produce mingw32, arm-elf, others using in-tree scripts - - build all required target code from sources -- make JTAG and USB debug output a run-time configuration option - -@section thelistarchitecture Architectural Tasks - -The following architectural tasks need to be accomplished and should be -fairly easy to complete: - - -- use dynamic allocations for working memory. Scan & fix code -for excessive stack allocations. take linux/scripts/checkstack.pl and -see what the worst offenders are. Dynamic stack allocations are found -at the bottom of the list below. Example, on amd64: - - $ objdump -d | checkstack.pl | head -10 - 0x004311e3 image_open [openocd]: 13464 - 0x00431301 image_open [openocd]: 13464 - 0x004237a4 target_array2mem [openocd]: 4376 - 0x0042382b target_array2mem [openocd]: 4376 - 0x00423e74 target_mem2array [openocd]: 4360 - 0x00423ef9 target_mem2array [openocd]: 4360 - 0x00404aed handle_svf_command [openocd]: 2248 - 0x00404b7e handle_svf_command [openocd]: 2248 - 0x00413581 handle_flash_fill_command [openocd]: 2200 - 0x004135fa handle_flash_fill_command [openocd]: 2200 -- clean-up code to match style guides -- factor code to eliminate duplicated functionality -- rewrite code that uses casts to access 16-bit and larger types - from unaligned memory addresses -- libopenocd support: @par - https://lists.berlios.de/pipermail/openocd-development/2009-May/006405.html -- review and clean up interface/target/flash APIs - -The following strategic tasks will require ambition, knowledge, and time -to complete: - -- overhaul use of types to improve 32/64-bit portability - - types for both host and target word sizes? - - can we use GDB's CORE_TYPE support? -- Allow N:M:P mapping of servers, targets, and interfaces -- loadable module support for interface/target/flash drivers and commands - - support both static and dynamic modules. - - should probably use libltdl for dynamic library handing. - -@section thelistadmin Documentation Tasks - -- Develop milestone and release guidelines, processes, and scripts. -- Develop "style" guidelines (and scripts) for maintainers: - - reviewing patches - - committing to git -- Review Users' Guide for documentation errors or omissions - - "capture" and "ocd_find" commands - - "ocd_" prefix on various stuff -- Update Developer's Manual (doxygen output) - - Add documentation describing the architecture of each module - - Provide more Technical Primers to bootstrap contributor knowledge - -*/ -/** @file -This file contains the @ref thelist page. -*/ - diff --git a/bootstrap b/bootstrap deleted file mode 100755 index 3b60fc6e5..000000000 --- a/bootstrap +++ /dev/null @@ -1,43 +0,0 @@ -#!/bin/sh -# Run the autotools bootstrap sequence to create the configure script - -# Abort execution on error -set -e - -if which libtoolize > /dev/null; then - libtoolize="libtoolize" -elif which glibtoolize >/dev/null; then - libtoolize="glibtoolize" -else - echo "$0: Error: libtool is required" >&2 - exit 1 -fi - -if [ "$1" = "nosubmodule" ]; then - SKIP_SUBMODULE=1 -elif [ -n "$1" ]; then - echo "$0: Illegal argument $1" - echo "USAGE: $0 [nosubmodule]" - exit 1 -fi - -# bootstrap the autotools -( -set -x -aclocal -${libtoolize} --automake --copy -autoconf -autoheader -automake --gnu --add-missing --copy -) - -if [ -n "$SKIP_SUBMODULE" ]; then - echo "Skipping submodule setup" -else - echo "Setting up submodules" - git submodule init - git submodule update -fi - -echo "Bootstrap complete. Quick build instructions:" -echo "./configure ...." diff --git a/common.mk b/common.mk deleted file mode 100644 index f301c3ace..000000000 --- a/common.mk +++ /dev/null @@ -1,12 +0,0 @@ - -# common flags used in openocd build -AM_CPPFLAGS = -I$(top_srcdir)/src \ - -I$(top_builddir)/src \ - -I$(top_srcdir)/src/helper \ - -DPKGDATADIR=\"$(pkgdatadir)\" \ - -DBINDIR=\"$(bindir)\" - -if INTERNAL_JIMTCL -AM_CPPFLAGS += -I$(top_srcdir)/jimtcl \ - -I$(top_builddir)/jimtcl -endif diff --git a/config_subdir.m4 b/config_subdir.m4 deleted file mode 100644 index 1c7909853..000000000 --- a/config_subdir.m4 +++ /dev/null @@ -1,26 +0,0 @@ -dnl -dnl If needed, define the m4_ifblank and m4_ifnblank macros from autoconf 2.64 -dnl This allows us to run with earlier Autoconfs as well. -ifdef([m4_ifblank],[],[ -m4_define([m4_ifblank], -[m4_if(m4_translit([[$1]], [ ][ ][ -]), [], [$2], [$3])])]) -dnl -ifdef([m4_ifnblank],[],[ -m4_define([m4_ifnblank], -[m4_if(m4_translit([[$1]], [ ][ ][ -]), [], [$3], [$2])])]) -dnl - -dnl AC_CONFIG_SUBDIRS does not allow configure options to be passed -dnl to subdirs, this function allows that by creating a configure.gnu -dnl script that prepends configure options and then calls the real -dnl configure script -AC_DEFUN([AX_CONFIG_SUBDIR_OPTION], -[ -AC_CONFIG_SUBDIRS([$1]) - -m4_ifblank([$2], [rm -f $srcdir/$1/configure.gnu], -[echo -e '#!/bin/sh\nexec "`dirname "'\$'0"`/configure" $2 "'\$'@"' > "$srcdir/$1/configure.gnu" -]) -]) diff --git a/configure.ac b/configure.ac deleted file mode 100644 index fb5514ee6..000000000 --- a/configure.ac +++ /dev/null @@ -1,1343 +0,0 @@ -AC_PREREQ(2.64) -AC_INIT([openocd], [0.10.0-dev], - [OpenOCD Mailing List ]) -AC_CONFIG_SRCDIR([src/openocd.c]) - -m4_include([config_subdir.m4])dnl - -# check for makeinfo before calling AM_INIT_AUTOMAKE -AC_CHECK_PROG([MAKEINFO], [makeinfo], [makeinfo]) -if test "x$MAKEINFO" = "x"; then - MAKEINFO='echo makeinfo missing; true' - AC_MSG_WARN([Info documentation will not be built.]) -fi -AC_SUBST([MAKEINFO]) - -AM_INIT_AUTOMAKE([-Wall -Wno-portability dist-bzip2 dist-zip subdir-objects]) - -AC_CONFIG_HEADERS([config.h]) -AH_BOTTOM([ -#include -#include -#include -]) - -AC_LANG_C -AC_PROG_CC -AC_PROG_CC_C99 -AM_PROG_CC_C_O -AC_PROG_RANLIB -PKG_PROG_PKG_CONFIG([0.23]) - -dnl disable checks for C++, Fortran and GNU Java Compiler -m4_defun([_LT_AC_LANG_CXX_CONFIG], [:]) -m4_defun([_LT_AC_LANG_F77_CONFIG], [:]) -m4_defun([_LT_AC_LANG_GCJ_CONFIG], [:]) -AC_DISABLE_SHARED -AC_PROG_LIBTOOL -AC_SUBST([LIBTOOL_DEPS]) - -dnl configure checks required for Jim files (these are obsolete w/ C99) -AC_C_CONST -AC_TYPE_LONG_LONG_INT - -AC_SEARCH_LIBS([ioperm], [ioperm]) -AC_SEARCH_LIBS([dlopen], [dl]) - -AC_CHECK_HEADERS([sys/socket.h]) -AC_CHECK_HEADERS([arpa/inet.h], [], [], [dnl -#include -#ifdef STDC_HEADERS -# include -# include -#else -# ifdef HAVE_STDLIB_H -# include -# endif -#endif -#ifdef HAVE_SYS_SOCKET_H -# include -#endif -]) -AC_CHECK_HEADERS([elf.h]) -AC_CHECK_HEADERS([dirent.h]) -AC_CHECK_HEADERS([fcntl.h]) -AC_CHECK_HEADERS([ifaddrs.h], [], [], [dnl -#include -#ifdef STDC_HEADERS -# include -# include -#else -# ifdef HAVE_STDLIB_H -# include -# endif -#endif -#ifdef HAVE_SYS_SOCKET_H -# include -#endif -]) -AC_CHECK_HEADERS([malloc.h]) -AC_CHECK_HEADERS([netdb.h]) -AC_CHECK_HEADERS([netinet/in.h], [], [], [dnl -#include -#ifdef STDC_HEADERS -# include -# include -#else -# ifdef HAVE_STDLIB_H -# include -# endif -#endif -#ifdef HAVE_SYS_SOCKET_H -# include -#endif -]) -AC_CHECK_HEADERS([netinet/tcp.h], [], [], [dnl -#include -#ifdef STDC_HEADERS -# include -# include -#else -# ifdef HAVE_STDLIB_H -# include -# endif -#endif -#ifdef HAVE_SYS_SOCKET_H -# include -#endif -]) -AC_CHECK_HEADERS([poll.h]) -AC_CHECK_HEADERS([pthread.h]) -AC_CHECK_HEADERS([strings.h]) -AC_CHECK_HEADERS([sys/ioctl.h]) -AC_CHECK_HEADERS([sys/param.h]) -AC_CHECK_HEADERS([sys/select.h]) -AC_CHECK_HEADERS([sys/stat.h]) -AC_CHECK_HEADERS([sys/time.h]) -AC_CHECK_HEADERS([sys/types.h]) -AC_CHECK_HEADERS([unistd.h]) -AC_CHECK_HEADERS([net/if.h], [], [], [dnl -#include -#ifdef STDC_HEADERS -# include -# include -#else -# ifdef HAVE_STDLIB_H -# include -# endif -#endif -#ifdef HAVE_SYS_SOCKET_H -# include -#endif -]) - -AC_HEADER_ASSERT -AC_HEADER_STDBOOL -AC_HEADER_TIME - -AC_C_BIGENDIAN - -AC_CHECK_FUNCS([strndup]) -AC_CHECK_FUNCS([strnlen]) -AC_CHECK_FUNCS([gettimeofday]) -AC_CHECK_FUNCS([usleep]) -AC_CHECK_FUNCS([vasprintf]) - -build_bitbang=no -build_bitq=no -is_cygwin=no -is_mingw=no -is_win32=no -is_darwin=no - -# guess-rev.sh only exists in the repository, not in the released archives -AC_MSG_CHECKING([whether to build a release]) -if test -x $srcdir/guess-rev.sh ; then - build_release=no -else - build_release=yes -fi -AC_MSG_RESULT([$build_release]) - -AC_ARG_WITH(ftd2xx, - AS_HELP_STRING([--with-ftd2xx=],[This option has been removed.]), - [ -# Option Given. -cat << __EOF__ - -The option: --with-ftd2xx= has been removed. -On Linux, the new option is: - - --with-ftd2xx-linux-tardir=/path/to/files - -Where is the path the the directory where the "tar.gz" file -from FTDICHIP.COM was unpacked, for example: - - --with-ftd2xx-linux-tardir=${HOME}/libftd2xx0.4.16 - -On Cygwin/MingW32, the new option is: - - --with-ftd2xx-win32-zipdir=/path/to/files - -Where is the path to the directory where the "zip" file from -FTDICHIP.COM was unpacked, for example: - - --with-ftd2xx-win32-zipdir=${HOME}/ftd2xx.cdm.files - -__EOF__ - - AC_MSG_ERROR([Sorry Cannot continue]) - ], [true]) - -# Adapter drivers -# 1st column -- configure option -# 2nd column -- description -# 3rd column -- symbol used for both config.h and automake -m4_define([ADAPTER_ARG], [m4_argn([1], $1)]) -m4_define([ADAPTER_DESC], [m4_argn([2], $1)]) -m4_define([ADAPTER_SYM], [m4_argn([3], $1)]) -m4_define([ADAPTER_VAR], [enable_[]ADAPTER_ARG($1)]) -m4_define([ADAPTER_OPT], [m4_translit(ADAPTER_ARG($1), [_], [-])]) - -m4_define([USB1_ADAPTERS], - [[[ftdi], [MPSSE mode of FTDI based devices], [FTDI]], - [[jlink], [Segger J-Link JTAG Programmer], [JLINK]], - [[stlink], [ST-Link JTAG Programmer], [HLADAPTER_STLINK]], - [[ti_icdi], [TI ICDI JTAG Programmer], [HLADAPTER_ICDI]], - [[ulink], [Keil ULINK JTAG Programmer], [ULINK]], - [[usb_blaster_2], [Altera USB-Blaster II Compatible], [USB_BLASTER_2]], - [[vsllink], [Versaloon-Link JTAG Programmer], [VSLLINK]]]) - -m4_define([USB_ADAPTERS], - [[[osbdm], [OSBDM (JTAG only) Programmer], [OSBDM]], - [[opendous], [eStick/opendous JTAG Programmer], [OPENDOUS]], - [[aice], [Andes JTAG Programmer], [AICE]]]) - -m4_define([USB0_ADAPTERS], - [[[usbprog], [USBProg JTAG Programmer], [USBPROG]], - [[rlink], [Raisonance RLink JTAG Programmer], [RLINK]], - [[armjtagew], [Olimex ARM-JTAG-EW Programmer], [ARMJTAGEW]]]) - -m4_define([HIDAPI_ADAPTERS], - [[[cmsis_dap], [CMSIS-DAP Compliant Debugger], [CMSIS_DAP]]]) - -#======================================== -# FTD2XXX support comes in 4 forms. -# (1) win32 - via a zip file -# (2) linux - via a tar file -# (3) linux/cygwin/mingw - via libftdi -# (4) darwin - installed under /usr/local -# -# In case (1) and (2) we need to know where the package was unpacked. - -AC_ARG_WITH(ftd2xx-win32-zipdir, - AS_HELP_STRING([--with-ftd2xx-win32-zipdir],[Where (CYGWIN/MINGW) the zip file from ftdichip.com was unpacked (default=search)]), - [ - # option present - if test -d $with_ftd2xx_win32_zipdir - then - with_ftd2xx_win32_zipdir=`cd $with_ftd2xx_win32_zipdir && pwd` - AC_MSG_NOTICE([Using: ftdichip.com library: $with_ftd2xx_win32_zipdir]) - else - AC_MSG_ERROR([Parameter to --with-ftd2xx-win32-zipdir is not a dir: $with_ftd2xx_win32_zipdir]) - fi - ], [true]) - -AC_ARG_WITH(ftd2xx-linux-tardir, - AS_HELP_STRING([--with-ftd2xx-linux-tardir], [Where (Linux/Unix) the tar file from ftdichip.com was unpacked (default=search)]), - [ - # Option present - if test $is_win32 = yes ; then - AC_MSG_ERROR([The option: --with-ftd2xx-linux-tardir is only usable on linux]) - fi - if test -d $with_ftd2xx_linux_tardir - then - with_ftd2xx_linux_tardir=`cd $with_ftd2xx_linux_tardir && pwd` - AC_MSG_NOTICE([Using: ftdichip.com library: $with_ftd2xx_linux_tardir]) - else - AC_MSG_ERROR([Parameter to --with-ftd2xx-linux-tardir is not a dir: $with_ftd2xx_linux_tardir]) - fi - ], [true]) - -AC_ARG_WITH(ftd2xx-lib, - AS_HELP_STRING([--with-ftd2xx-lib], - [Use static or shared ftd2xx libs (default=static)]), - [ - case "$withval" in - static) - with_ftd2xx_lib=$withval - ;; - shared) - with_ftd2xx_lib=$withval - ;; - *) - AC_MSG_ERROR([Option: --with-ftd2xx-lib=static or --with-ftd2xx-lib=shared not, $withval]) - ;; - esac - ], [ - # Default is static - it is simpler :-( - with_ftd2xx_lib=static - ]) - -AC_ARG_ENABLE([doxygen-html], - AS_HELP_STRING([--disable-doxygen-html], - [Disable building Doxygen manual as HTML.]), - [doxygen_as_html=$enableval], [doxygen_as_html=yes]) -AC_SUBST([doxygen_as_html]) -AC_MSG_CHECKING([whether to build Doxygen as HTML]) -AC_MSG_RESULT([$doxygen_as_html]) - -AC_ARG_ENABLE([doxygen-pdf], - AS_HELP_STRING([--enable-doxygen-pdf], - [Enable building Doxygen manual as PDF.]), - [doxygen_as_pdf=$enableval], [doxygen_as_pdf=no]) -AC_SUBST([doxygen_as_pdf]) -AC_MSG_CHECKING([whether to build Doxygen as PDF]) -AC_MSG_RESULT([$doxygen_as_pdf]) - -AC_ARG_ENABLE([gccwarnings], - AS_HELP_STRING([--disable-gccwarnings], [Disable compiler warnings]), - [gcc_warnings=$enableval], [gcc_warnings=yes]) - -AC_ARG_ENABLE([wextra], - AS_HELP_STRING([--disable-wextra], [Disable extra compiler warnings]), - [gcc_wextra=$enableval], [gcc_wextra=$gcc_warnings]) - -AC_ARG_ENABLE([werror], - AS_HELP_STRING([--disable-werror], [Do not treat warnings as errors]), - [gcc_werror=$enableval], [gcc_werror=$gcc_warnings]) - -# set default verbose options, overridden by following options -debug_jtag_io=no -debug_usb_io=no -debug_usb_comms=no - -AC_ARG_ENABLE([verbose], - AS_HELP_STRING([--enable-verbose], - [Enable verbose JTAG I/O messages (for debugging).]), - [ - debug_jtag_io=$enableval - debug_usb_io=$enableval - debug_usb_comms=$enableval - ], []) - -AC_ARG_ENABLE([verbose_jtag_io], - AS_HELP_STRING([--enable-verbose-jtag-io], - [Enable verbose JTAG I/O messages (for debugging).]), - [debug_jtag_io=$enableval], []) - -AC_ARG_ENABLE([verbose_usb_io], - AS_HELP_STRING([--enable-verbose-usb-io], - [Enable verbose USB I/O messages (for debugging)]), - [debug_usb_io=$enableval], []) - -AC_ARG_ENABLE([verbose_usb_comms], - AS_HELP_STRING([--enable-verbose-usb-comms], - [Enable verbose USB communication messages (for debugging)]), - [debug_usb_comms=$enableval], []) - -AC_MSG_CHECKING([whether to enable verbose JTAG I/O messages]); -AC_MSG_RESULT([$debug_jtag_io]) -if test $debug_jtag_io = yes; then - AC_DEFINE([_DEBUG_JTAG_IO_],[1], [Print verbose JTAG I/O messages]) -fi - -AC_MSG_CHECKING([whether to enable verbose USB I/O messages]); -AC_MSG_RESULT([$debug_usb_io]) -if test $debug_usb_io = yes; then - AC_DEFINE([_DEBUG_USB_IO_],[1], [Print verbose USB I/O messages]) -fi - -AC_MSG_CHECKING([whether to enable verbose USB communication messages]); -AC_MSG_RESULT([$debug_usb_comms]) -if test $debug_usb_comms = yes; then - AC_DEFINE([_DEBUG_USB_COMMS_],[1], [Print verbose USB communication messages]) -fi - -debug_malloc=no -AC_ARG_ENABLE([malloc_logging], - AS_HELP_STRING([--enable-malloc-logging], - [Include free space in logging messages (requires malloc.h).]), - [debug_malloc=$enableval], []) - -AC_MSG_CHECKING([whether to enable malloc free space logging]); -AC_MSG_RESULT([$debug_malloc]) -if test $debug_malloc = yes; then - AC_DEFINE([_DEBUG_FREE_SPACE_],[1], [Include malloc free space in logging]) -fi - -AC_ARG_ENABLE([dummy], - AS_HELP_STRING([--enable-dummy], [Enable building the dummy port driver]), - [build_dummy=$enableval], [build_dummy=no]) - -m4_define([AC_ARG_ADAPTERS], [ - m4_foreach([adapter], [$1], - [AC_ARG_ENABLE(ADAPTER_OPT([adapter]), - AS_HELP_STRING([--enable-ADAPTER_OPT([adapter])], - [Enable building support for the ]ADAPTER_DESC([adapter])[ (default is $2)]), - [], [ADAPTER_VAR([adapter])=$2]) - ]) -]) - -AC_ARG_ADAPTERS([USB1_ADAPTERS, USB_ADAPTERS, USB0_ADAPTERS, HIDAPI_ADAPTERS], [auto]) - -AC_ARG_ENABLE([parport], - AS_HELP_STRING([--enable-parport], [Enable building the pc parallel port driver]), - [build_parport=$enableval], [build_parport=no]) - -AC_ARG_ENABLE([parport_ppdev], - AS_HELP_STRING([--disable-parport-ppdev], - [Disable use of ppdev (/dev/parportN) for parport (for x86 only)]), - [parport_use_ppdev=$enableval], [parport_use_ppdev=yes]) - -AC_ARG_ENABLE([parport_giveio], - AS_HELP_STRING([--enable-parport-giveio], - [Enable use of giveio for parport (for CygWin only)]), - [parport_use_giveio=$enableval], [parport_use_giveio=]) - -AC_ARG_ENABLE([ft2232_libftdi], [], [ -if test $enableval = yes; then - AC_MSG_ERROR([The ft2232 driver is deprecated, use --enable-ftdi to build its replacement, or force the old driver with --enable-legacy-ft2232_libftdi]) -fi -]) - -AC_ARG_ENABLE([ft2232_ftd2xx], [], [ -if test $enableval = yes; then - AC_MSG_ERROR([The ft2232 driver is deprecated, use --enable-ftdi to build its replacement, or force the old driver with --enable-legacy-ft2232_ftd2xx]) -fi -]) - -AC_ARG_ENABLE([legacy-ft2232_libftdi], - AS_HELP_STRING([--enable-legacy-ft2232_libftdi], [(DEPRECATED) Enable building support for FT2232 based devices using the libftdi library]), - [build_ft2232_libftdi=$enableval], [build_ft2232_libftdi=no]) - -AC_ARG_ENABLE([legacy-ft2232_ftd2xx], - AS_HELP_STRING([--enable-legacy-ft2232_ftd2xx], [(DEPRECATED) Enable building support for FT2232 based devices using the D2XX library from ftdichip.com]), - [build_ft2232_ftd2xx=$enableval], [build_ft2232_ftd2xx=no]) - -AC_ARG_ENABLE([jtag_vpi], - AS_HELP_STRING([--enable-jtag_vpi], [Enable building support for JTAG VPI]), - [build_jtag_vpi=$enableval], [build_jtag_vpi=no]) - -AC_ARG_ENABLE([usb_blaster_libftdi], - AS_HELP_STRING([--enable-usb_blaster_libftdi], [Enable building support for the Altera USB-Blaster using the libftdi driver, opensource alternate of FTD2XX]), - [build_usb_blaster_libftdi=$enableval], [build_usb_blaster_libftdi=no]) - -AC_ARG_ENABLE([usb_blaster_ftd2xx], - AS_HELP_STRING([--enable-usb_blaster_ftd2xx], [Enable building support for the Altera USB-Blaster using the FTD2XX driver from ftdichip.com]), - [build_usb_blaster_ftd2xx=$enableval], [build_usb_blaster_ftd2xx=no]) - -AC_ARG_ENABLE([amtjtagaccel], - AS_HELP_STRING([--enable-amtjtagaccel], [Enable building the Amontec JTAG-Accelerator driver]), - [build_amtjtagaccel=$enableval], [build_amtjtagaccel=no]) - -AC_ARG_ENABLE([zy1000_master], - AS_HELP_STRING([--enable-zy1000-master], [Use ZY1000 JTAG master registers]), - [build_zy1000_master=$enableval], [build_zy1000_master=no]) - -AC_ARG_ENABLE([zy1000], - AS_HELP_STRING([--enable-zy1000], [Enable ZY1000 interface]), - [build_zy1000=$enableval], [build_zy1000=no]) - -AC_ARG_ENABLE([ioutil], - AS_HELP_STRING([--enable-ioutil], [Enable ioutil functions - useful for standalone OpenOCD implementations]), - [build_ioutil=$enableval], [build_ioutil=no]) - -case "${host_cpu}" in - arm*) - AC_ARG_ENABLE([ep93xx], - AS_HELP_STRING([--enable-ep93xx], [Enable building support for EP93xx based SBCs]), - [build_ep93xx=$enableval], [build_ep93xx=no]) - - AC_ARG_ENABLE([at91rm9200], - AS_HELP_STRING([--enable-at91rm9200], [Enable building support for AT91RM9200 based SBCs]), - [build_at91rm9200=$enableval], [build_at91rm9200=no]) - - AC_ARG_ENABLE([bcm2835gpio], - AS_HELP_STRING([--enable-bcm2835gpio], [Enable building support for bitbanging on BCM2835 (as found in Raspberry Pi)]), - [build_bcm2835gpio=$enableval], [build_bcm2835gpio=no]) - ;; - - *) - build_ep93xx=no - build_at91rm9200=no - build_bcm2835gpio=no - ;; -esac - -AC_ARG_ENABLE([gw16012], - AS_HELP_STRING([--enable-gw16012], [Enable building support for the Gateworks GW16012 JTAG Programmer]), - [build_gw16012=$enableval], [build_gw16012=no]) - -AC_ARG_ENABLE([presto_libftdi], - AS_HELP_STRING([--enable-presto_libftdi], [Enable building support for ASIX Presto Programmer using the libftdi driver]), - [build_presto_libftdi=$enableval], [build_presto_libftdi=no]) - -AC_ARG_ENABLE([presto_ftd2xx], - AS_HELP_STRING([--enable-presto_ftd2xx], [Enable building support for ASIX Presto Programmer using the FTD2XX driver]), - [build_presto_ftd2xx=$enableval], [build_presto_ftd2xx=no]) - -AC_ARG_ENABLE([openjtag_ftd2xx], - AS_HELP_STRING([--enable-openjtag_ftd2xx], [Enable building support for the OpenJTAG Programmer with ftd2xx driver]), - [build_openjtag_ftd2xx=$enableval], [build_openjtag_ftd2xx=no]) - -AC_ARG_ENABLE([openjtag_ftdi], - AS_HELP_STRING([--enable-openjtag_ftdi], [Enable building support for the OpenJTAG Programmer with ftdi driver]), - [build_openjtag_ftdi=$enableval], [build_openjtag_ftdi=no]) - -AC_ARG_ENABLE([oocd_trace], - AS_HELP_STRING([--enable-oocd_trace], - [Enable building support for some prototype OpenOCD+trace ETM capture hardware]), - [build_oocd_trace=$enableval], [build_oocd_trace=no]) - -AC_ARG_ENABLE([buspirate], - AS_HELP_STRING([--enable-buspirate], [Enable building support for the Buspirate]), - [build_buspirate=$enableval], [build_buspirate=no]) - -AC_ARG_ENABLE([sysfsgpio], - AS_HELP_STRING([--enable-sysfsgpio], [Enable building support for programming driven via sysfs gpios.]), - [build_sysfsgpio=$enableval], [build_sysfsgpio=no]) - -AC_ARG_ENABLE([minidriver_dummy], - AS_HELP_STRING([--enable-minidriver-dummy], [Enable the dummy minidriver.]), - [build_minidriver_dummy=$enableval], [build_minidriver_dummy=no]) - -AC_ARG_ENABLE([internal-jimtcl], - AS_HELP_STRING([--disable-internal-jimtcl], [Disable building internal jimtcl]), - [use_internal_jimtcl=$enableval], [use_internal_jimtcl=yes]) - -AC_ARG_ENABLE([internal-libjaylink], - AS_HELP_STRING([--disable-internal-libjaylink], - [Disable building internal libjaylink]), - [use_internal_libjaylink=$enableval], [use_internal_libjaylink=yes]) - -build_minidriver=no -AC_MSG_CHECKING([whether to enable ZY1000 minidriver]) -if test $build_zy1000 = yes; then - if test $build_minidriver = yes; then - AC_MSG_ERROR([Multiple minidriver options have been enabled.]) - fi - AC_DEFINE([HAVE_JTAG_MINIDRIVER_H], [1], - [Define to 1 if you have the header file.]) - build_minidriver=yes -fi -AC_MSG_RESULT([$build_zy1000]) - -AC_ARG_ENABLE([remote-bitbang], - AS_HELP_STRING([--enable-remote-bitbang], [Enable building support for the Remote Bitbang jtag driver]), - [build_remote_bitbang=$enableval], [build_remote_bitbang=no]) - -AC_MSG_CHECKING([whether to enable dummy minidriver]) -if test $build_minidriver_dummy = yes; then - if test $build_minidriver = yes; then - AC_MSG_ERROR([Multiple minidriver options have been enabled.]) - fi - build_minidriver=yes - AC_DEFINE([BUILD_MINIDRIVER_DUMMY], [1], [Use the dummy minidriver.]) - AC_DEFINE([HAVE_JTAG_MINIDRIVER_H], [1], - [Define to 1 if you have the header file.]) -fi -AC_MSG_RESULT([$build_minidriver_dummy]) - -AC_MSG_CHECKING([whether standard drivers can be built]) -if test "$build_minidriver" = yes; then - AC_MSG_RESULT([no]) - AC_MSG_WARN([Using the minidriver disables all other drivers.]) - sleep 2 -else - AC_MSG_RESULT([yes]) -fi - -case "${host_cpu}" in - i?86|x86*) - ;; - *) - if test x$parport_use_ppdev = xno; then - AC_MSG_WARN([--disable-parport-ppdev is not supported by the host CPU]) - fi - parport_use_ppdev=yes - ;; -esac - -case $host in - *-cygwin*) - is_win32=yes - parport_use_ppdev=no - - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [[return __MINGW32__;]])], - [is_mingw=yes],[is_mingw=no]) - if test $is_mingw = yes; then - AC_DEFINE([IS_MINGW], [1], [1 if building for MinGW.]) - if test x$parport_use_giveio = xno; then - AC_MSG_WARN([--disable-parport-giveio is not supported by MinGW32 hosts]) - fi - parport_use_giveio=yes - is_cygwin=no - else - is_cygwin=yes - AC_DEFINE([IS_CYGWIN], [1], [1 if building for Cygwin.]) - # sys/io.h needed under cygwin for parport access - if test $build_parport = yes; then - AC_CHECK_HEADERS([sys/io.h],[],AC_MSG_ERROR([Please install the cygwin ioperm package])) - fi - fi - - AC_DEFINE([IS_WIN32], [1], [1 if building for Win32.]) - AC_DEFINE([IS_DARWIN], [0], [0 if not building for Darwin.]) - ;; - *-mingw* | *-msys*) - is_mingw=yes - is_win32=yes - parport_use_ppdev=no - - if test x$parport_use_giveio = xno; then - AC_MSG_WARN([--disable-parport-giveio is not supported by MinGW32 hosts]) - fi - parport_use_giveio=yes - - if test x$build_buspirate = xyes; then - AC_MSG_ERROR([buspirate currently not supported by MinGW32 hosts]) - fi - - CFLAGS="$CFLAGS -D__USE_MINGW_ANSI_STDIO" - - AC_DEFINE([IS_MINGW], [1], [1 if building for MinGW.]) - AC_DEFINE([IS_WIN32], [1], [1 if building for Win32.]) - AC_DEFINE([IS_DARWIN], [0], [0 if not building for Darwin.]) - ;; - *darwin*) - is_darwin=yes - - if test x$parport_use_giveio = xyes; then - AC_MSG_WARN([--enable-parport-giveio cannot be used by Darwin hosts]) - fi - parport_use_giveio=no - - AC_DEFINE([IS_CYGWIN], [0], [0 if not building for Cygwin.]) - AC_DEFINE([IS_WIN32], [0], [0 if not building for Win32.]) - AC_DEFINE([IS_DARWIN], [1], [1 if building for Darwin.]) - ;; - *) - if test x$parport_use_giveio = xyes; then - AC_MSG_WARN([--enable-parport-giveio cannot be used by ]$host[ hosts]) - fi - parport_use_giveio=no - AC_DEFINE([IS_CYGWIN], [0], [0 if not building for Cygwin.]) - AC_DEFINE([IS_WIN32], [0], [0 if not building for Win32.]) - AC_DEFINE([IS_DARWIN], [0], [0 if not building for Darwin.]) - ;; -esac - -if test $is_win32 = yes; then - AC_DEFINE([WIN32_LEAN_AND_MEAN], [1], [1 to exclude old conflicting definitions when building on Windows]) -fi - -if test $build_parport = yes; then - build_bitbang=yes - AC_DEFINE([BUILD_PARPORT], [1], [1 if you want parport.]) -else - AC_DEFINE([BUILD_PARPORT], [0], [0 if you don't want parport.]) -fi - -if test $build_dummy = yes; then - build_bitbang=yes - AC_DEFINE([BUILD_DUMMY], [1], [1 if you want dummy driver.]) -else - AC_DEFINE([BUILD_DUMMY], [0], [0 if you don't want dummy driver.]) -fi - -if test $build_ep93xx = yes; then - build_bitbang=yes - AC_DEFINE([BUILD_EP93XX], [1], [1 if you want ep93xx.]) -else - AC_DEFINE([BUILD_EP93XX], [0], [0 if you don't want ep93xx.]) -fi - -if test $build_zy1000 = yes; then - AC_DEFINE([BUILD_ZY1000], [1], [1 if you want ZY1000.]) -else - AC_DEFINE([BUILD_ZY1000], [0], [0 if you don't want ZY1000.]) -fi - -if test $build_zy1000_master = yes; then - AC_DEFINE([BUILD_ZY1000_MASTER], [1], [1 if you want ZY1000 JTAG master registers.]) -else - AC_DEFINE([BUILD_ZY1000_MASTER], [0], [0 if you don't want ZY1000 JTAG master registers.]) -fi - -if test $build_at91rm9200 = yes; then - build_bitbang=yes - AC_DEFINE([BUILD_AT91RM9200], [1], [1 if you want at91rm9200.]) -else - AC_DEFINE([BUILD_AT91RM9200], [0], [0 if you don't want at91rm9200.]) -fi - -if test $build_bcm2835gpio = yes; then - build_bitbang=yes - AC_DEFINE([BUILD_BCM2835GPIO], [1], [1 if you want bcm2835gpio.]) -else - AC_DEFINE([BUILD_BCM2835GPIO], [0], [0 if you don't want bcm2835gpio.]) -fi - -if test x$parport_use_ppdev = xyes; then - AC_DEFINE([PARPORT_USE_PPDEV], [1], [1 if you want parport to use ppdev.]) -else - AC_DEFINE([PARPORT_USE_PPDEV], [0], [0 if you don't want parport to use ppdev.]) -fi - -if test x$parport_use_giveio = xyes; then - AC_DEFINE([PARPORT_USE_GIVEIO], [1], [1 if you want parport to use giveio.]) -else - AC_DEFINE([PARPORT_USE_GIVEIO], [0], [0 if you don't want parport to use giveio.]) -fi - -if test $build_bitbang = yes; then - AC_DEFINE([BUILD_BITBANG], [1], [1 if you want a bitbang interface.]) -else - AC_DEFINE([BUILD_BITBANG], [0], [0 if you don't want a bitbang interface.]) -fi - -if test $build_ft2232_libftdi = yes; then - AC_DEFINE([BUILD_FT2232_LIBFTDI], [1], [1 if you want libftdi ft2232.]) -else - AC_DEFINE([BUILD_FT2232_LIBFTDI], [0], [0 if you don't want libftdi ft2232.]) -fi - -if test $build_ft2232_ftd2xx = yes; then - AC_DEFINE([BUILD_FT2232_FTD2XX], [1], [1 if you want ftd2xx ft2232.]) -else - AC_DEFINE([BUILD_FT2232_FTD2XX], [0], [0 if you don't want ftd2xx ft2232.]) -fi - -if test $build_usb_blaster_libftdi = yes; then - AC_DEFINE([BUILD_USB_BLASTER_LIBFTDI], [1], [1 if you want libftdi usb_blaster.]) -else - AC_DEFINE([BUILD_USB_BLASTER_LIBFTDI], [0], [0 if you don't want libftdi usb_blaster.]) -fi - -if test $build_jtag_vpi = yes; then - AC_DEFINE([BUILD_JTAG_VPI], [1], [1 if you want JTAG VPI.]) -else - AC_DEFINE([BUILD_JTAG_VPI], [0], [0 if you don't want JTAG VPI.]) -fi - -if test $build_usb_blaster_ftd2xx = yes; then - AC_DEFINE([BUILD_USB_BLASTER_FTD2XX], [1], [1 if you want ftd2xx usb_blaster.]) -else - AC_DEFINE([BUILD_USB_BLASTER_FTD2XX], [0], [0 if you don't want ftd2xx usb_blaster.]) -fi - -if test $build_amtjtagaccel = yes; then - AC_DEFINE([BUILD_AMTJTAGACCEL], [1], [1 if you want the Amontec JTAG-Accelerator driver.]) -else - AC_DEFINE([BUILD_AMTJTAGACCEL], [0], [0 if you don't want the Amontec JTAG-Accelerator driver.]) -fi - -if test $build_gw16012 = yes; then - AC_DEFINE([BUILD_GW16012], [1], [1 if you want the Gateworks GW16012 driver.]) -else - AC_DEFINE([BUILD_GW16012], [0], [0 if you don't want the Gateworks GW16012 driver.]) -fi - -if test $build_presto_libftdi = yes; then - build_bitq=yes - AC_DEFINE([BUILD_PRESTO_LIBFTDI], [1], [1 if you want the ASIX PRESTO driver using libftdi.]) -else - AC_DEFINE([BUILD_PRESTO_LIBFTDI], [0], [0 if you don't want the ASIX PRESTO driver using libftdi.]) -fi - -if test $build_presto_ftd2xx = yes; then - build_bitq=yes - AC_DEFINE([BUILD_PRESTO_FTD2XX], [1], [1 if you want the ASIX PRESTO driver using FTD2XX.]) -else - AC_DEFINE([BUILD_PRESTO_FTD2XX], [0], [0 if you don't want the ASIX PRESTO driver using FTD2XX.]) -fi - -if test $build_bitq = yes; then - AC_DEFINE([BUILD_BITQ], [1], [1 if you want a bitq interface.]) -else - AC_DEFINE([BUILD_BITQ], [0], [0 if you don't want a bitq interface.]) -fi - -AC_DEFINE([BUILD_OPENJTAG], [0], [0 if you don't want the OpenJTAG driver.]) -AC_DEFINE([BUILD_OPENJTAG_FTD2XX], [0], [0 if you don't want the OpenJTAG driver with FTD2XX driver.]) -AC_DEFINE([BUILD_OPENJTAG_LIBFTDI], [0], [0 if you don't want to build OpenJTAG driver with libftdi.]) - -if test $build_openjtag_ftd2xx = yes; then - AC_DEFINE([BUILD_OPENJTAG], [1], [1 if you want the OpenJTAG driver.]) - AC_DEFINE([BUILD_OPENJTAG_FTD2XX], [1], [1 if you want the OpenJTAG driver with FTD2XX driver.]) -fi -if test $build_openjtag_ftdi = yes; then - AC_DEFINE([BUILD_OPENJTAG], [1], [1 if you want the OpenJTAG drvier.]) - AC_DEFINE([BUILD_OPENJTAG_LIBFTDI], [1], [1 if you want to build OpenJTAG with FTDI driver.]) -fi - -if test $build_oocd_trace = yes; then - AC_DEFINE([BUILD_OOCD_TRACE], [1], [1 if you want the OpenOCD+trace ETM capture driver.]) -else - AC_DEFINE([BUILD_OOCD_TRACE], [0], [0 if you don't want the OpenOCD+trace ETM capture driver.]) -fi - -if test $build_buspirate = yes; then - AC_DEFINE([BUILD_BUSPIRATE], [1], [1 if you want the Buspirate JTAG driver.]) -else - AC_DEFINE([BUILD_BUSPIRATE], [0], [0 if you don't want the Buspirate JTAG driver.]) -fi - -if test $use_internal_jimtcl = yes; then - if test -f "$srcdir/jimtcl/configure.ac"; then - AX_CONFIG_SUBDIR_OPTION([jimtcl], [--disable-install-jim]) - else - AC_MSG_ERROR([jimtcl not found, run git submodule init and git submodule update.]) - fi -fi - -if test $use_internal_libjaylink = yes; then - if test -f "$srcdir/src/jtag/drivers/libjaylink/configure.ac"; then - ( cd $srcdir/src/jtag/drivers/libjaylink/ && ./autogen.sh ) - AX_CONFIG_SUBDIR_OPTION([src/jtag/drivers/libjaylink], - [--enable-subproject-build]) - else - AC_MSG_ERROR([Internal libjaylink not found, run either 'git submodule init' and 'git submodule update' or disable internal libjaylink with --disable-internal-libjaylink.]) - fi -else - PKG_CHECK_MODULES([libjaylink], [libjaylink >= 0.1], - [CFLAGS="$CFLAGS $libjaylink_CFLAGS"; LIBS="$LIBS $libjaylink_LIBS"; HAVE_LIBJAYLINK=yes], [HAVE_LIBJAYLINK=no]) -fi - -if test $build_remote_bitbang = yes; then - build_bitbang=yes - AC_DEFINE([BUILD_REMOTE_BITBANG], [1], [1 if you want the Remote Bitbang JTAG driver.]) -else - AC_DEFINE([BUILD_REMOTE_BITBANG], [0], [0 if you don't want the Remote Bitbang JTAG driver.]) -fi - -if test $build_sysfsgpio = yes; then - build_bitbang=yes - AC_DEFINE([BUILD_SYSFSGPIO], [1], [1 if you want the SysfsGPIO driver.]) -else - AC_DEFINE([BUILD_SYSFSGPIO], [0], [0 if you don't want SysfsGPIO driver.]) -fi -#-- Deal with MingW/Cygwin FTD2XX issues - -if test $is_win32 = yes; then -if test "${with_ftd2xx_linux_tardir+set}" = set -then - AC_MSG_ERROR([The option: with_ftd2xx_linux_tardir is for LINUX only.]) -fi - -if test $build_ft2232_ftd2xx = yes -o $build_presto_ftd2xx = yes -o $build_usb_blaster_ftd2xx = yes -o $build_openjtag_ftd2xx = yes; then - AC_MSG_CHECKING([for ftd2xx.lib exists (win32)]) - - # if we are given a zipdir... - if test "${with_ftd2xx_win32_zipdir+set}" = set - then - # Set the CFLAGS for "ftd2xx.h" - f=$with_ftd2xx_win32_zipdir/ftd2xx.h - if test ! -f $f ; then - AC_MSG_ERROR([File: $f cannot be found]) - fi - CFLAGS="$CFLAGS -I$with_ftd2xx_win32_zipdir" - - # And calculate the LDFLAGS for the machine - case "$host_cpu" in - i?86|x86_32) - LDFLAGS="$LDFLAGS -L$with_ftd2xx_win32_zipdir/i386" - LIBS="$LIBS -lftd2xx" - f=$with_ftd2xx_win32_zipdir/i386/ftd2xx.lib - ;; - amd64|x86_64) - LDFLAGS="$LDFLAGS -L$with_ftd2xx_win32_zipdir/amd64" - LIBS="$LIBS -lftd2xx" - f=$with_ftd2xx_win32_zipdir/amd64/ftd2xx.lib - ;; - *) - AC_MSG_ERROR([Unknown Win32 host cpu: $host_cpu]) - ;; - esac - if test ! -f $f ; then - AC_MSG_ERROR([Library: $f not found]) - fi - else - LIBS="$LIBS -lftd2xx" - AC_MSG_WARN([ASSUMPTION: The (win32) FTDICHIP.COM files: ftd2xx.h and ftd2xx.lib are in a proper place]) - fi -fi -fi # win32 - -if test $is_darwin = yes ; then -if test "${with_ftd2xx_win32_zipdir+set}" = set -then - AC_MSG_ERROR([The option: --with-ftd2xx-win32-zipdir is for win32 only]) -fi -if test "${with_ftd2xx_linux_tardir+set}" = set -then - AC_MSG_ERROR([The option: with_ftd2xx_linux_tardir is for LINUX only.]) -fi - -if test $build_ft2232_ftd2xx = yes -o $build_presto_ftd2xx = yes -o $build_usb_blaster_ftd2xx = yes ; then - AC_MSG_CHECKING([for libftd2xx.a (darwin)]) - - if test ! -f /usr/local/include/ftd2xx.h ; then - AC_MSG_ERROR([ftd2xx library from FTDICHIP.com seems to be missing, cannot find: /usr/local/include/ftd2xx.h]) - fi - - CFLAGS="$CFLAGS -I/usr/local/include" - LDFLAGS="$LDFLAGS -L/usr/local/lib" - LIBS="$LIBS -lftd2xx" - AC_MSG_RESULT([-L/usr/local/lib -lftd2xx]) -fi -fi # darwin - -if test $is_win32 = no && test $is_darwin = no ; then - -if test "${with_ftd2xx_win32_zipdir+set}" = set -then - AC_MSG_ERROR([The option: --with-ftd2xx-win32-zipdir is for win32 only]) -fi - -if test $build_ft2232_ftd2xx = yes -o $build_presto_ftd2xx = yes -o $build_usb_blaster_ftd2xx = yes -o $build_openjtag_ftd2xx = yes; then - # Must be linux - if test $host_os != linux-gnu && test $host_os != linux ; then - AC_MSG_ERROR([The (linux) ftd2xx library from FTDICHIP.com is linux only. Try --enable-ft2232-libftdi instead]) - fi - # Are we given a TAR directory? - if test "${with_ftd2xx_linux_tardir+set}" = set - then - AC_MSG_CHECKING([uninstalled ftd2xx distribution]) - # The .H file is simple.. - FTD2XX_H=$with_ftd2xx_linux_tardir/ftd2xx.h - if test ! -f "${FTD2XX_H}"; then - AC_MSG_ERROR([Option: --with-ftd2xx-linux-tardir appears wrong, cannot find: ${FTD2XX_H}]) - fi - CFLAGS="$CFLAGS -I$with_ftd2xx_linux_tardir" - if test $with_ftd2xx_lib = shared; then - FTD2XX_LDFLAGS="-L$with_ftd2xx_linux_tardir" - FTD2XX_LIB="-lftd2xx" - else - # Test #1 - v1.0.x - case "$host_cpu" in - i?86|x86_32) - dir=build/i386;; - amd64|x86_64) - dir=build/x86_64;; - *) - dir=none;; - esac - if test -f "$with_ftd2xx_linux_tardir/$dir/libftd2xx.a"; then - FTD2XX_LDFLAGS="-L$with_ftd2xx_linux_tardir/$dir" - # Also needs -lrt - FTD2XX_LIB="-lftd2xx -lrt" - else - # Test Number2. - # Grr.. perhaps it exists as a version number? - FTD2XX_LIB="$with_ftd2xx_linux_tardir/static_lib/libftd2xx.a.*.*.*" - count=`ls ${FTD2XX_LIB} | wc -l` - if test $count -gt 1 ; then - AC_MSG_ERROR([Multiple libftd2xx.a files found in: $with_ftd2xx_linux_tardir/static_lib sorry cannot handle this yet]) - fi - if test $count -ne 1 ; then - AC_MSG_ERROR([Not found: $f, option: --with-ftd2xx-linux-tardir appears to be wrong]) - fi - # Because the "-l" rules do not understand version numbers... - # we will just stuff the absolute path onto the LIBS variable - FTD2XX_LIB="`ls ${FTD2XX_LIB}` -lpthread" - FTD2XX_LDFLAGS="" - fi - fi - LDFLAGS="${LDFLAGS} ${FTD2XX_LDFLAGS}" - LIBS="${FTD2XX_LIB} ${LIBS}" - AC_MSG_RESULT([${FTD2XX_LDFLAGS} ${FTD2XX_LIB}]) - else - AC_CHECK_HEADER([ftd2xx.h],[],[ - AC_MSG_ERROR([You seem to be missing the FTD2xx driver header file.]) - ]) - AC_SEARCH_LIBS([FT_GetLibraryVersion],[ftd2xx],,[ - AC_MSG_ERROR([You appear to be missing the FTD2xx driver library.]) - ],[-lrt -lusb-1.0]) - fi -fi -fi # linux - -if test $build_ft2232_ftd2xx = yes -o $build_presto_ftd2xx = yes -o $build_usb_blaster_ftd2xx = yes ; then - -# Before we go any further - make sure we can *BUILD* and *RUN* -# a simple app with the "ftd2xx.lib" file - in what ever form we where given -# We should be able to compile, link and run this test program now -AC_MSG_CHECKING([whether ftd2xx library works]) - -# -# Save the LDFLAGS for later.. -LDFLAGS_SAVE=$LDFLAGS -CFLAGS_SAVE=$CFLAGS -_LDFLAGS=`eval echo $LDFLAGS` -_CFLAGS=`eval echo $CFLAGS` -LDFLAGS=$_LDFLAGS -CFLAGS=$_CFLAGS - -AC_RUN_IFELSE([AC_LANG_PROGRAM([[ -#include "confdefs.h" -#if IS_WIN32 -#include "windows.h" -#endif -#include -#include - ]], [[ - DWORD x; - FT_GetLibraryVersion( &x ); - ]])], [ - AC_MSG_RESULT([Success!]) - ], [ - AC_MSG_ERROR([Cannot build & run test program using ftd2xx.lib]) - ], [ - AC_MSG_RESULT([Skipping as we are cross-compiling]) - ]) - -AC_MSG_CHECKING([for ftd2xx highspeed device support]) -AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ -#include "confdefs.h" -#if IS_WIN32 -#include "windows.h" -#endif -#include -#include - -DWORD x = FT_DEVICE_4232H; - ]], [])], [ - AC_DEFINE([BUILD_FT2232_HIGHSPEED], [1], - [Support FT2232H/FT4232HS with FTD2XX or libftdi.]) - build_ft2232_highspeed=yes - ], [ - build_ft2232_highspeed=no - ]) - AC_MSG_RESULT([$build_ft2232_highspeed]) - - if test $build_ft2232_highspeed = no; then - AC_MSG_WARN([You need a newer FTD2XX driver (version 2.04.16 or later).]) - fi - -AC_MSG_CHECKING([for ftd2xx FT232H device support]) -AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ -#include "confdefs.h" -#if IS_WIN32 -#include "windows.h" -#endif -#include -#include - -DWORD x = FT_DEVICE_232H; - ]], [])], [ - AC_DEFINE([HAS_ENUM_FT232H], [1], - [Support FT232H with FTD2XX or libftdi.]) - has_enum_ft232h=yes - ], [ - has_enum_ft232h=no - ]) - AC_MSG_RESULT([$has_enum_ft232h]) - - if test $has_enum_ft232h = no; then - AC_MSG_WARN([You need a newer FTD2XX driver (version 2.08.12 or later).]) - fi - -LDFLAGS=$LDFLAGS_SAVE -CFLAGS=$CFLAGS_SAVE -fi - -if test $build_ft2232_libftdi = yes -o $build_usb_blaster_libftdi = yes -o \ - $build_openjtag_ftdi = yes -o $build_presto_libftdi = yes; then - - # we can have libftdi or libftdi1, so check it and use the latest one - PKG_CHECK_MODULES([LIBFTDI], [libftdi1], [use_libftdi=yes], [use_libftdi=no]) - if test $use_libftdi = no; then - PKG_CHECK_MODULES([LIBFTDI], [libftdi], [use_libftdi=yes], [use_libftdi=no]) - fi - if test $use_libftdi = no; then - AC_MSG_ERROR([The libftdi driver is not present on your system.]) - fi - - # - # Try to build a small program. - AC_MSG_CHECKING([Build & Link with libftdi...]) - - LDFLAGS_SAVE=$LDFLAGS - CFLAGS_SAVE=$CFLAGS - LIBS_SAVE=$LIBS - _LDFLAGS=`eval echo $LDFLAGS` - _CFLAGS=`eval echo $CFLAGS` - _LIBS=`eval echo $LIBS` - LDFLAGS=$_LDFLAGS - CFLAGS="$_CFLAGS $LIBFTDI_CFLAGS" - LIBS="$_LIBS $LIBFTDI_LIBS" - - AC_RUN_IFELSE([AC_LANG_PROGRAM([[ -#include -#include - ]], [[ - struct ftdi_context *p; - p = ftdi_new(); - if( p != NULL ){ - return 0; - } else { - fprintf( stderr, "calling ftdi_new() failed\n"); - return 1; - } - ]])], [ - AC_MSG_RESULT([Success]) - ], [ - AC_MSG_ERROR([Cannot build & run test program using libftdi]) - ], [ - AC_MSG_RESULT([Skipping as we are cross-compiling, trying build only]) - AC_SEARCH_LIBS([ftdi_new], [], [], [AC_MSG_ERROR([Cannot link with libftdi])]) - ]) - -AC_MSG_CHECKING([for libftdi highspeed device support]) -AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ -#include -#include - ]], [[ -enum ftdi_chip_type x = TYPE_2232H; - ]])], [ - AC_DEFINE([BUILD_FT2232_HIGHSPEED], [1], - [Support FT2232H/FT4232HS with FTD2XX or libftdi.]) - build_ft2232_highspeed=yes - ], [ - build_ft2232_highspeed=no - ]) - AC_MSG_RESULT([$build_ft2232_highspeed]) - - if test $build_ft2232_highspeed = no; then - AC_MSG_WARN([You need a newer libftdi version (0.16 or later).]) - fi - -AC_MSG_CHECKING([for libftdi FT232H device support]) -AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ -#include -#include - ]], [[ -enum ftdi_chip_type x = TYPE_232H; - ]])], [ - AC_DEFINE([HAS_ENUM_FT232H], [1], - [Support FT232H with FTD2XX or libftdi.]) - has_enum_ft232h=yes - ], [ - has_enum_ft232h=no - ]) - AC_MSG_RESULT([$has_enum_ft232h]) - - if test $has_enum_ft232h = no; then - AC_MSG_WARN([You need a newer libftdi version (0.20 or later).]) - fi - - # Restore the 'unexpanded ldflags' - LDFLAGS=$LDFLAGS_SAVE - CFLAGS=$CFLAGS_SAVE - LIBS=$LIBS_SAVE -fi - -PKG_CHECK_MODULES([LIBUSB1], [libusb-1.0], [ - use_libusb1=yes - AC_DEFINE([HAVE_LIBUSB1], [1], [Define if you have libusb-1.x]) - PKG_CHECK_EXISTS([libusb-1.0 >= 1.0.9], - [AC_DEFINE([HAVE_LIBUSB_ERROR_NAME], [1], [Define if your libusb has libusb_error_name()])], - [AC_MSG_WARN([libusb-1.x older than 1.0.9 detected, consider updating])]) - LIBUSB1_CFLAGS=`echo $LIBUSB1_CFLAGS | sed 's/-I/-isystem /'` - AC_MSG_NOTICE([libusb-1.0 header bug workaround: LIBUSB1_CFLAGS changed to "$LIBUSB1_CFLAGS"]) - PKG_CHECK_EXISTS([libusb-1.0 >= 1.0.16], - [AC_DEFINE([HAVE_LIBUSB_GET_PORT_NUMBERS], [1], [Define if your libusb has libusb_get_port_numbers()])]) - ], [ - use_libusb1=no - AC_MSG_WARN([libusb-1.x not found, trying legacy libusb-0.1 as a fallback; consider installing libusb-1.x instead]) -]) - -PKG_CHECK_MODULES([LIBUSB0], [libusb], [use_libusb0=yes], [use_libusb0=no]) - -for hidapi_lib in hidapi hidapi-hidraw hidapi-libusb; do - PKG_CHECK_MODULES([HIDAPI],[$hidapi_lib],[ - use_hidapi=yes - break - ],[ - use_hidapi=no - ]) -done - -m4_define([PROCESS_ADAPTERS], [ - m4_foreach([adapter], [$1], [ - if test $2; then - if test $ADAPTER_VAR([adapter]) != no; then - AC_DEFINE([BUILD_]ADAPTER_SYM([adapter]), [1], [1 if you want the ]ADAPTER_DESC([adapter]).) - else - AC_DEFINE([BUILD_]ADAPTER_SYM([adapter]), [0], [0 if you do not want the ]ADAPTER_DESC([adapter]).) - fi - else - if test $ADAPTER_VAR([adapter]) = yes; then - AC_MSG_ERROR([$3 is required for the ADAPTER_DESC([adapter])]) - fi - ADAPTER_VAR([adapter])=no - fi - AM_CONDITIONAL(ADAPTER_SYM([adapter]), [test $ADAPTER_VAR([adapter]) != no]) - ]) -]) - -PROCESS_ADAPTERS([USB1_ADAPTERS], [$use_libusb1 = yes], [libusb-1.x]) -PROCESS_ADAPTERS([USB_ADAPTERS], [$use_libusb1 = yes -o $use_libusb0 = yes], [libusb-1.x or libusb-0.1]) -PROCESS_ADAPTERS([USB0_ADAPTERS], [$use_libusb0 = yes], [libusb-0.1]) -PROCESS_ADAPTERS([HIDAPI_ADAPTERS], [$use_hidapi = yes], [hidapi]) - -if test $enable_stlink != no -o $enable_ti_icdi != no; then - AC_DEFINE([BUILD_HLADAPTER], [1], [1 if you want the High Level JTAG driver.]) -else - AC_DEFINE([BUILD_HLADAPTER], [0], [0 if you want the High Level JTAG driver.]) -fi -AM_CONDITIONAL([HLADAPTER], [test $enable_stlink != no -o $enable_ti_icdi != no]) - -# Disable J-Link driver if internal libjaylink is disabled and libjaylink was -# not found by pkg-config. -if test $enable_jlink != no; then - if test $use_internal_libjaylink$HAVE_LIBJAYLINK = nono; then - enable_jlink=no - fi -fi - -AM_CONDITIONAL([RELEASE], [test $build_release = yes]) -AM_CONDITIONAL([PARPORT], [test $build_parport = yes]) -AM_CONDITIONAL([DUMMY], [test $build_dummy = yes]) -AM_CONDITIONAL([GIVEIO], [test x$parport_use_giveio = xyes]) -AM_CONDITIONAL([EP93XX], [test $build_ep93xx = yes]) -AM_CONDITIONAL([ZY1000], [test $build_zy1000 = yes]) -AM_CONDITIONAL([ZY1000_MASTER], [test $build_zy1000_master = yes]) -AM_CONDITIONAL([IOUTIL], [test $build_ioutil = yes]) -AM_CONDITIONAL([AT91RM9200], [test $build_at91rm9200 = yes]) -AM_CONDITIONAL([BCM2835GPIO], [test $build_bcm2835gpio = yes]) -AM_CONDITIONAL([BITBANG], [test $build_bitbang = yes]) -AM_CONDITIONAL([FT2232_LIBFTDI], [test $build_ft2232_libftdi = yes]) -AM_CONDITIONAL([FT2232_DRIVER], [test $build_ft2232_ftd2xx = yes -o $build_ft2232_libftdi = yes]) -AM_CONDITIONAL([USB_BLASTER_LIBFTDI], [test $build_usb_blaster_libftdi = yes]) -AM_CONDITIONAL([USB_BLASTER_FTD2XX], [test $build_usb_blaster_ftd2xx = yes]) -AM_CONDITIONAL([JTAG_VPI], [test $build_jtag_vpi = yes -o $build_jtag_vpi = yes]) -AM_CONDITIONAL([USB_BLASTER_DRIVER], [test $build_usb_blaster_ftd2xx = yes -o $build_usb_blaster_libftdi = yes -o $enable_usb_blaster_2 != no]) -AM_CONDITIONAL([AMTJTAGACCEL], [test $build_amtjtagaccel = yes]) -AM_CONDITIONAL([GW16012], [test $build_gw16012 = yes]) -AM_CONDITIONAL([PRESTO_LIBFTDI], [test $build_presto_libftdi = yes]) -AM_CONDITIONAL([PRESTO_DRIVER], [test $build_presto_ftd2xx = yes -o $build_presto_libftdi = yes]) -AM_CONDITIONAL([OPENJTAG], [test $build_openjtag_ftd2xx = yes -o $build_openjtag_ftdi = yes]) -AM_CONDITIONAL([OOCD_TRACE], [test $build_oocd_trace = yes]) -AM_CONDITIONAL([REMOTE_BITBANG], [test $build_remote_bitbang = yes]) -AM_CONDITIONAL([BUSPIRATE], [test $build_buspirate = yes]) -AM_CONDITIONAL([SYSFSGPIO], [test $build_sysfsgpio = yes]) -AM_CONDITIONAL([USE_LIBUSB0], [test $use_libusb0 = yes]) -AM_CONDITIONAL([USE_LIBUSB1], [test $use_libusb1 = yes]) -AM_CONDITIONAL([IS_CYGWIN], [test $is_cygwin = yes]) -AM_CONDITIONAL([IS_MINGW], [test $is_mingw = yes]) -AM_CONDITIONAL([IS_WIN32], [test $is_win32 = yes]) -AM_CONDITIONAL([IS_DARWIN], [test $is_darwin = yes]) -AM_CONDITIONAL([BITQ], [test $build_bitq = yes]) -AM_CONDITIONAL([CMSIS_DAP], [test $use_hidapi = yes]) - -AM_CONDITIONAL([MINIDRIVER], [test $build_minidriver = yes]) -AM_CONDITIONAL([MINIDRIVER_DUMMY], [test $build_minidriver_dummy = yes]) - -AM_CONDITIONAL([INTERNAL_JIMTCL], [test $use_internal_jimtcl = yes]) -AM_CONDITIONAL([INTERNAL_LIBJAYLINK], [test $use_internal_libjaylink = yes]) - -# Look for environ alternatives. Possibility #1: is environ in unistd.h or stdlib.h? -AC_MSG_CHECKING([for environ in unistd.h and stdlib.h]) -AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ -#define _GNU_SOURCE -#include -#include - ]], [[char **ep = environ;]] - )], [ - AC_MSG_RESULT([yes]) - has_environ=yes - ], [ - AC_MSG_RESULT([no]) - - # Possibility #2: can environ be found in an available library? - AC_MSG_CHECKING([for extern environ]) - AC_LINK_IFELSE([AC_LANG_PROGRAM([[ - extern char **environ; - ]], [[char **ep = environ;]] - )], [ - AC_DEFINE(NEED_ENVIRON_EXTERN, [1], [Must declare 'environ' to use it.]) - has_environ=yes - ], [ - has_environ=no - ]) - AC_MSG_RESULT([${has_environ}]) - ]) - -if test "${has_environ}" != "yes" ; then - AC_MSG_FAILURE([Could not find 'environ' in unistd.h or available libraries.]) -fi - -AC_DEFINE([_GNU_SOURCE],[1],[Use GNU C library extensions (e.g. stdndup).]) - -# set default gcc warnings -GCC_WARNINGS="-Wall -Wstrict-prototypes -Wformat-security -Wshadow" -if test "${gcc_wextra}" = yes; then - GCC_WARNINGS="${GCC_WARNINGS} -Wextra -Wno-unused-parameter" - GCC_WARNINGS="${GCC_WARNINGS} -Wbad-function-cast" - GCC_WARNINGS="${GCC_WARNINGS} -Wcast-align" - GCC_WARNINGS="${GCC_WARNINGS} -Wredundant-decls" -fi -if test "${gcc_werror}" = yes; then - GCC_WARNINGS="${GCC_WARNINGS} -Werror" -fi - -# overide default gcc cflags -if test $gcc_warnings = yes; then - CFLAGS="$CFLAGS $GCC_WARNINGS" -fi - -AC_CONFIG_FILES([ - Makefile - src/Makefile - src/helper/Makefile - src/jtag/Makefile - src/jtag/drivers/Makefile - src/jtag/drivers/usb_blaster/Makefile - src/jtag/hla/Makefile - src/jtag/aice/Makefile - src/transport/Makefile - src/target/openrisc/Makefile - src/xsvf/Makefile - src/svf/Makefile - src/target/Makefile - src/rtos/Makefile - src/server/Makefile - src/flash/Makefile - src/flash/nor/Makefile - src/flash/nand/Makefile - src/pld/Makefile - doc/Makefile -]) -AC_OUTPUT - -echo -echo -echo OpenOCD configuration summary -echo -------------------------------------------------- -m4_foreach([adapter], [USB1_ADAPTERS, USB_ADAPTERS, USB0_ADAPTERS, HIDAPI_ADAPTERS], - [s=m4_format(["%-40s"], ADAPTER_DESC([adapter])) - case $ADAPTER_VAR([adapter]) in - auto) - echo "$s"yes '(auto)' - ;; - yes) - echo "$s"yes - ;; - no) - echo "$s"no - ;; - esac -]) -echo - -if test $build_ft2232_libftdi = yes -o $build_ft2232_ftd2xx = yes; then - if test $enable_ftdi = no; then - AC_MSG_WARN([Building the deprecated 'ft2232' adapter driver but not its replacement!]) - AC_MSG_WARN([Please consider using --enable-ftdi instead.]) - else - AC_MSG_WARN([Building the deprecated 'ft2232' adapter driver.]) - fi -fi diff --git a/contrib/99-openocd.rules b/contrib/99-openocd.rules deleted file mode 100644 index 057c4b7a6..000000000 --- a/contrib/99-openocd.rules +++ /dev/null @@ -1,134 +0,0 @@ -# Copy this file to /etc/udev/rules.d/ - -ACTION!="add|change", GOTO="openocd_rules_end" -SUBSYSTEM!="usb|tty|hidraw", GOTO="openocd_rules_end" - -# Please keep this list sorted by VID:PID - -# opendous and estick -ATTRS{idVendor}=="03eb", ATTRS{idProduct}=="204f", MODE="664", GROUP="plugdev" - -# Original FT232/FT245 VID:PID -ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", MODE="664", GROUP="plugdev" - -# Original FT2232 VID:PID -ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6010", MODE="664", GROUP="plugdev" - -# Original FT4232 VID:PID -ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6011", MODE="664", GROUP="plugdev" - -# Original FT232H VID:PID -ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6014", MODE="664", GROUP="plugdev" - -# DISTORTEC JTAG-lock-pick Tiny 2 -ATTRS{idVendor}=="0403", ATTRS{idProduct}=="8220", MODE="664", GROUP="plugdev" - -# TUMPA, TUMPA Lite -ATTRS{idVendor}=="0403", ATTRS{idProduct}=="8a98", MODE="664", GROUP="plugdev" -ATTRS{idVendor}=="0403", ATTRS{idProduct}=="8a99", MODE="664", GROUP="plugdev" - -# XDS100v2 -ATTRS{idVendor}=="0403", ATTRS{idProduct}=="a6d0", MODE="664", GROUP="plugdev" - -# Xverve Signalyzer Tool (DT-USB-ST), Signalyzer LITE (DT-USB-SLITE) -ATTRS{idVendor}=="0403", ATTRS{idProduct}=="bca0", MODE="664", GROUP="plugdev" -ATTRS{idVendor}=="0403", ATTRS{idProduct}=="bca1", MODE="664", GROUP="plugdev" - -# TI/Luminary Stellaris Evaluation Board FTDI (several) -ATTRS{idVendor}=="0403", ATTRS{idProduct}=="bcd9", MODE="664", GROUP="plugdev" - -# TI/Luminary Stellaris In-Circuit Debug Interface FTDI (ICDI) Board -ATTRS{idVendor}=="0403", ATTRS{idProduct}=="bcda", MODE="664", GROUP="plugdev" - -# egnite Turtelizer 2 -ATTRS{idVendor}=="0403", ATTRS{idProduct}=="bdc8", MODE="664", GROUP="plugdev" - -# Section5 ICEbear -ATTRS{idVendor}=="0403", ATTRS{idProduct}=="c140", MODE="664", GROUP="plugdev" -ATTRS{idVendor}=="0403", ATTRS{idProduct}=="c141", MODE="664", GROUP="plugdev" - -# Amontec JTAGkey and JTAGkey-tiny -ATTRS{idVendor}=="0403", ATTRS{idProduct}=="cff8", MODE="664", GROUP="plugdev" - -# TI ICDI -ATTRS{idVendor}=="0451", ATTRS{idProduct}=="c32a", MODE="664", GROUP="plugdev" - -# STLink v1 -ATTRS{idVendor}=="0483", ATTRS{idProduct}=="3744", MODE="664", GROUP="plugdev" - -# STLink v2 -ATTRS{idVendor}=="0483", ATTRS{idProduct}=="3748", MODE="664", GROUP="plugdev" - -# STLink v2-1 -ATTRS{idVendor}=="0483", ATTRS{idProduct}=="374b", MODE="664", GROUP="plugdev" - -# Hilscher NXHX Boards -ATTRS{idVendor}=="0640", ATTRS{idProduct}=="0028", MODE="664", GROUP="plugdev" - -# Hitex STR9-comStick -ATTRS{idVendor}=="0640", ATTRS{idProduct}=="002c", MODE="664", GROUP="plugdev" - -# Hitex STM32-PerformanceStick -ATTRS{idVendor}=="0640", ATTRS{idProduct}=="002d", MODE="664", GROUP="plugdev" - -# Altera USB Blaster -ATTRS{idVendor}=="09fb", ATTRS{idProduct}=="6001", MODE="664", GROUP="plugdev" - -# Amontec JTAGkey-HiSpeed -ATTRS{idVendor}=="0fbb", ATTRS{idProduct}=="1000", MODE="664", GROUP="plugdev" - -# SEGGER J-Link -ATTRS{idVendor}=="1366", ATTRS{idProduct}=="0101", MODE="664", GROUP="plugdev" -ATTRS{idVendor}=="1366", ATTRS{idProduct}=="0102", MODE="664", GROUP="plugdev" -ATTRS{idVendor}=="1366", ATTRS{idProduct}=="0103", MODE="664", GROUP="plugdev" -ATTRS{idVendor}=="1366", ATTRS{idProduct}=="0104", MODE="664", GROUP="plugdev" -ATTRS{idVendor}=="1366", ATTRS{idProduct}=="0105", MODE="664", GROUP="plugdev" -ATTRS{idVendor}=="1366", ATTRS{idProduct}=="0107", MODE="664", GROUP="plugdev" -ATTRS{idVendor}=="1366", ATTRS{idProduct}=="0108", MODE="664", GROUP="plugdev" -ATTRS{idVendor}=="1366", ATTRS{idProduct}=="1010", MODE="664", GROUP="plugdev" -ATTRS{idVendor}=="1366", ATTRS{idProduct}=="1011", MODE="664", GROUP="plugdev" -ATTRS{idVendor}=="1366", ATTRS{idProduct}=="1012", MODE="664", GROUP="plugdev" -ATTRS{idVendor}=="1366", ATTRS{idProduct}=="1013", MODE="664", GROUP="plugdev" -ATTRS{idVendor}=="1366", ATTRS{idProduct}=="1014", MODE="664", GROUP="plugdev" -ATTRS{idVendor}=="1366", ATTRS{idProduct}=="1015", MODE="664", GROUP="plugdev" -ATTRS{idVendor}=="1366", ATTRS{idProduct}=="1016", MODE="664", GROUP="plugdev" -ATTRS{idVendor}=="1366", ATTRS{idProduct}=="1017", MODE="664", GROUP="plugdev" -ATTRS{idVendor}=="1366", ATTRS{idProduct}=="1018", MODE="664", GROUP="plugdev" - -# Raisonance RLink -ATTRS{idVendor}=="138e", ATTRS{idProduct}=="9000", MODE="664", GROUP="plugdev" - -# Debug Board for Neo1973 -ATTRS{idVendor}=="1457", ATTRS{idProduct}=="5118", MODE="664", GROUP="plugdev" - -# Olimex ARM-USB-OCD -ATTRS{idVendor}=="15ba", ATTRS{idProduct}=="0003", MODE="664", GROUP="plugdev" - -# Olimex ARM-USB-OCD-TINY -ATTRS{idVendor}=="15ba", ATTRS{idProduct}=="0004", MODE="664", GROUP="plugdev" - -# Olimex ARM-JTAG-EW -ATTRS{idVendor}=="15ba", ATTRS{idProduct}=="001e", MODE="664", GROUP="plugdev" - -# Olimex ARM-USB-OCD-TINY-H -ATTRS{idVendor}=="15ba", ATTRS{idProduct}=="002a", MODE="664", GROUP="plugdev" - -# Olimex ARM-USB-OCD-H -ATTRS{idVendor}=="15ba", ATTRS{idProduct}=="002b", MODE="664", GROUP="plugdev" - -# USBprog with OpenOCD firmware -ATTRS{idVendor}=="1781", ATTRS{idProduct}=="0c63", MODE="664", GROUP="plugdev" - -# TI/Luminary Stellaris In-Circuit Debug Interface (ICDI) Board -ATTRS{idVendor}=="1cbe", ATTRS{idProduct}=="00fd", MODE="664", GROUP="plugdev" - -# Marvell Sheevaplug -ATTRS{idVendor}=="9e88", ATTRS{idProduct}=="9e8f", MODE="664", GROUP="plugdev" - -# Keil Software, Inc. ULink -ATTRS{idVendor}=="c251", ATTRS{idProduct}=="2710", MODE="664", GROUP="plugdev" - -# CMSIS-DAP compatible adapters -ATTRS{product}=="*CMSIS-DAP*", MODE="664", GROUP="plugdev" - -LABEL="openocd_rules_end" diff --git a/contrib/coresight-trace.txt b/contrib/coresight-trace.txt deleted file mode 100644 index c093c205a..000000000 --- a/contrib/coresight-trace.txt +++ /dev/null @@ -1,68 +0,0 @@ -+OpenOCD and CoreSight Tracing -+ -Many recent ARM chips (Using e..g. Cortex-M3 and -Cortex-M4 cores) support CoreSight debug/trace. -This note sketches an approach currently planned for those cores -with OpenOCD. - - This tracing data can help debug and tune ARM software, but not -all cores support tracing. Some support more extensive tracing -other cores with trace support +should be able to use the same -approach and maybe some of the same analysis code. - -+the Cortex-M3 is assumed here to be the -+core in use, for simplicity and to reflect current OpenOCD users. - - -This note summarizes a software model to generate, collect, and -analyze such trace data . That is not fully implemented as of early -January 2011, +and thus is not *yet* usable. -+ -+ -+Some microcontroller cores support a low pin-count Single-wire trace, -with a mode where +trace data is emitted (usually to a UART. To use -this mode, +SWD must be in use. -+At this writing, OpenOCD SWD support is not yet complete either. - -(There are also multi-wire trace ports requiring more complex debug -adapters than OpenOCD currently supports, and offering richer data. -+ -+ -+* ENABLING involves activating SWD and (single wire) trace. -+ -+current expectations are that OpenOCD itself will handle enabling; -activating single wire trace involves a debug adapter interaction, and -collecting that trace data requires particular (re)wiring. -+ -+* CONFIGURATION involves setting up ITM and/or ETM modules to emit the -+desired data from the Cortex core. (This might include dumping -+event counters printf-style messages; code profiling; and more. Not all -+cores offer the same trace capabilities. -+ -+current expectations are that Tcl scripts will be used to configure these -+modules for the desired tracing, by direct writes to registers. In some -+cases (as with RTOS event tracking and similar messaging, this might -+be augmented or replaced by user code running on the ARM core. -+ -+COLLECTION involves reading that trace data, probably through UART, and -+saving it in a useful format to analyse For now, deferred analysis modes -are assumed, not than real-time or interactive ones. -+ -+ -+current expectations are to to dump data in text using contrib/itmdump.c -+or derived tools, and to post-process it into reports. Such reports might -+include program messaging (such as application data streams via ITM, maybe -+using printf type messaging; code coverage analysis or so forth. Recent -+versions of CMSIS software reserve some ITM codespace for RTOS event -tracing and include ITM messaging support. -Clearly some of that data would be valuable for interactive debugging. -+ -+Should someone get ambitious, GUI reports should be possible. GNU tools -+for simpler reports like gprof may be simpler to support at first. -+In any case, OpenOCD is not currently GUI-oriented. Accordingly, we now -+expect any such graphics to come from postprocessing. - - measurments for RTOS event timings should also be easy to collect. -+Examples include context and message switch times, as well as times -for application interactions. -+ diff --git a/contrib/cross-build.sh b/contrib/cross-build.sh deleted file mode 100755 index 74ab0f4f5..000000000 --- a/contrib/cross-build.sh +++ /dev/null @@ -1,119 +0,0 @@ -#!/bin/sh - -# This is an example of how to do a cross-build of OpenOCD using pkg-config. -# Cross-building with pkg-config is deceptively hard and most guides and -# tutorials are incomplete or give bad advice. Some of the traps that are easy -# to fall in but handled by this script are: -# -# * Polluting search paths and flags with values from the build system. -# * Faulty pkg-config wrappers shipped with distribution packaged cross- -# toolchains. -# * Build failing because pkg-config discards some paths even though they are -# correctly listed in the .pc file. -# * Getting successfully built binaries that cannot find runtime data because -# paths refer to the build file system. -# -# This script is probably more useful as a reference than as a complete build -# tool but for some configurations it may be usable as-is. It only cross- -# builds libusb-1.0 from source, but the script can be extended to build other -# prerequisities in a similar manner. -# -# Usage: -# export LIBUSB1_SRC=/path/to/libusb-1.0 -# export HIDAPI_SRC=/path/to/hidapi -# export OPENOCD_CONFIG="--enable-..." -# cd /work/dir -# /path/to/openocd/contrib/cross-build.sh -# -# For static linking, a workaround is to -# export LIBUSB1_CONFIG="--enable-static --disable-shared" -# -# All the paths must not contain any spaces. - -set -e -x - -WORK_DIR=$PWD - -## Source code paths, customize as necessary -: ${OPENOCD_SRC:="`dirname "$0"`/.."} -: ${LIBUSB1_SRC:=/path/to/libusb} -: ${HIDAPI_SRC:=/path/to/hidapi} - -OPENOCD_SRC=`readlink -m $OPENOCD_SRC` -LIBUSB1_SRC=`readlink -m $LIBUSB1_SRC` -HIDAPI_SRC=`readlink -m $HIDAPI_SRC` - -HOST_TRIPLET=$1 -BUILD_DIR=$WORK_DIR/$HOST_TRIPLET-build -LIBUSB1_BUILD_DIR=$BUILD_DIR/libusb1 -HIDAPI_BUILD_DIR=$BUILD_DIR/hidapi -OPENOCD_BUILD_DIR=$BUILD_DIR/openocd - -## Root of host file tree -SYSROOT=$WORK_DIR/$HOST_TRIPLET-root - -## Install location within host file tree -: ${PREFIX=/usr} - -## OpenOCD-only install dir for packaging -PACKAGE_DIR=$WORK_DIR/openocd_`git --git-dir=$OPENOCD_SRC/.git describe`_$HOST_TRIPLET - -####### - -# Create pkg-config wrapper and make sure it's used -export PKG_CONFIG=$WORK_DIR/$HOST_TRIPLET-pkg-config - -cat > $PKG_CONFIG < \n"; --d $ARGV[0] || die $ARGV[0]." is not a directory\n"; -$dir = $ARGV[0]; --f $ARGV[1] || die $ARGV[1]." is not a file\n"; -$file = $ARGV[1]; -print STDERR "Scanning $dir, Updating $file\n"; - -opendir(DIR, $dir) || die "can't open $dir: $!"; -@files = readdir(DIR); -closedir(DIR); - -@header_files = sort(grep(/lm.+\.h/, @files)); - -$ver = 0; -$new_struct = $struct_header; -process_file(@header_files); -$new_struct .= $struct_footer; - -$dump = "$comment $ver\n$new_struct"; -{ - local($/, *INPUT); - open(INPUT, $file) || die "can't open $file: $!"; - $contents = ; - close(INPUT); -} - -$old_struct = qr/((^\/\/.*?\n)*)\Q$struct_header\E.*?$struct_footer/sm; -$contents =~ s/$old_struct/$dump/; -open(OUTPUT, ">$file") || die "can't open file $file for writing: $!"; -print OUTPUT $contents; -close(OUTPUT); - -sub process_file { - foreach $h_file (@_) { - ($base) = ($h_file =~ m/lm..(.{3,7})\.h/ig); - $base = uc($base); - local($/, *FILE); - open(FILE, "$dir/$h_file"); - $content = ; - close(FILE); - $invalid = 0; - if ($content =~ /This is part of revision (\d+) of/) { - if ($ver != 0 and $ver != $1) { - print STDERR "File version mismatch: $ver != $1\n"; - $ver = max($ver, $1); - } else { - $ver = $1; - } - } - - if ($content =~ /SYSCTL_DID0_CLASS_[^M].+?0x(\S+)/s) { - $class = hex($1) >> 16; - } else { - # attempt another way to get class - if ($content =~ /\s(\S+)-class/) { - $class = getclass($1); - if ($class eq 0xFF) { - print STDERR "$h_file unknown class\n"; - $invalid = 1; - } - } else { - print STDERR "$h_file is missing SYSCTL_DID0_CLASS_\n"; - $class = 0; - $invalid = 1; - } - } - - if ($content =~ /SYSCTL_DID1_PRTNO_$base.+0x(\S+)/) { - $prtno = hex($1); - $base = "LM3S" . $base; - } else { - # LM4F have a changed header - if ($content =~ /SYSCTL_DID1_PRTNO_LM4F$base.+?0x(\S+)/s) { - $prtno = hex($1); - $base = "LM4F" . $base; - } else { - print STDERR "$h_file is missing SYSCTL_DID1_PRTNO\n"; - $prtno = 0; - $invalid = 1; - } - } - $new_member = sprintf "{0x%02X, 0x%02X, \"%s\"},", $class, $prtno >> 16, $base; - if ($invalid == 1) { - #$new_struct .= "\t//$new_member\t// Invalid\n"; - } else { - $new_struct .= "\t$new_member\n"; - } - } -} - -sub getclass { - $class = $_[0]; - if ($class =~ /Sandstorm/i) { - return 0; - } elsif ($class =~ /Fury/i) { - return 1; - } elsif ($class =~ /DustDevil/i) { - return 3; - } elsif ($class =~ /Tempest/i) { - return 4; - } elsif ($class =~ /Blizzard/i) { - return 5; - } elsif ($class =~ /Firestorm/i) { - return 6; - } - return 0xFF; -} diff --git a/contrib/itmdump.c b/contrib/itmdump.c deleted file mode 100644 index 896389416..000000000 --- a/contrib/itmdump.c +++ /dev/null @@ -1,459 +0,0 @@ -/* - * Copyright (C) 2010 by David Brownell - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/* - * Simple utility to parse and dump ARM Cortex-M3 SWO trace output. Once the - * mechanisms work right, this information can be used for various purposes - * including profiling (particularly easy for flat PC-sample profiles) and - * for debugging. - * - * SWO is the Single Wire Output found on some ARM cores, most notably on the - * Cortex-M3. It combines data from several sources: - * - * - Software trace (ITM): so-called "printf-style" application messaging - * using "ITM stimulus ports"; and differential timestamps. - * - Hardware trace (DWT): for profiling counters and comparator matches. - * - TPIU may issue sync packets. - * - * The trace data format is defined in Appendix E, "Debug ITM and DWT packet - * protocol", of the ARMv7-M Architecture Reference Manual (DDI 0403C). It - * is a superset of the ITM data format from the Coresight TRM. - * - * The trace data has two encodings. The working assumption is that data - * gets into this program using the UART encoding. - */ - -#include -#include -#include -#include -#include -#include - -unsigned int dump_swit; - -/* Example ITM trace word (0xWWXXYYZZ) parsing for task events, sent - * on port 31 (Reserved for "the" RTOS in CMSIS v1.30) - * WWXX: event code (0..3 pre-assigned, 4..15 reserved) - * YY: task priority - * ZZ: task number - * - * NOTE that this specific encoding could be space-optimized; and that - * trace data streams could also be history-sensitive. - */ -static void show_task(int port, unsigned data) -{ - unsigned code = data >> 16; - char buf[16]; - - if (dump_swit) - return; - - switch (code) { - case 0: - strcpy(buf, "run"); - break; - case 1: - strcpy(buf, "block"); - break; - case 2: - strcpy(buf, "create"); - break; - case 3: - strcpy(buf, "destroy"); - break; - /* 4..15 reserved for other infrastructure ops */ - default: - sprintf(buf, "code %d", code); - break; - } - printf("TASK %d, pri %d: %s", - (data >> 0) & 0xff, - (data >> 8) & 0xff, - buf); -} - -static void show_reserved(FILE *f, char *label, int c) -{ - unsigned i; - - if (dump_swit) - return; - - printf("%s - %#02x", label, c); - - for (i = 0; (c & 0x80) && i < 4; i++) { - c = fgetc(f); - if (c == EOF) { - printf("(ERROR %d - %s) ", errno, strerror(errno)); - break; - } - printf(" %#02x", c); - } - - printf("\n"); -} - -static bool read_varlen(FILE *f, int c, unsigned *value) -{ - unsigned size; - unsigned char buf[4]; - - *value = 0; - - switch (c & 3) { - case 3: - size = 4; - break; - case 2: - size = 2; - break; - case 1: - size = 1; - break; - default: - printf("INVALID SIZE\n"); - return false; - } - - memset(buf, 0, sizeof buf); - if (fread(buf, 1, size, f) != size) - goto err; - - *value = (buf[3] << 24) - + (buf[2] << 16) - + (buf[1] << 8) - + (buf[0] << 0); - return true; - -err: - printf("(ERROR %d - %s)\n", errno, strerror(errno)); - return false; -} - -static void show_hard(FILE *f, int c) -{ - unsigned type = c >> 3; - unsigned value; - char *label; - - if (dump_swit) - return; - - printf("DWT - "); - - if (!read_varlen(f, c, &value)) - return; - printf("%#x", value); - - switch (type) { - case 0: /* event counter wrapping */ - printf("overflow %s%s%s%s%s%s", - (value & (1 << 5)) ? "cyc " : "", - (value & (1 << 4)) ? "fold " : "", - (value & (1 << 3)) ? "lsu " : "", - (value & (1 << 2)) ? "slp " : "", - (value & (1 << 1)) ? "exc " : "", - (value & (1 << 0)) ? "cpi " : ""); - break; - case 1: /* exception tracing */ - switch (value >> 12) { - case 1: - label = "entry to"; - break; - case 2: - label = "exit from"; - break; - case 3: - label = "return to"; - break; - default: - label = "?"; - break; - } - printf("%s exception %d", label, value & 0x1ff); - break; - case 2: /* PC sampling */ - if (c == 0x15) - printf("PC - sleep"); - else - printf("PC - %#08x", value); - break; - case 8: /* data tracing, pc value */ - case 10: - case 12: - case 14: - printf("Data trace %d, PC %#08x", (c >> 4) & 3, value); - /* optionally followed by data value */ - break; - case 9: /* data tracing, address offset */ - case 11: - case 13: - case 15: - printf("Data trace %d, address offset %#04x", - (c >> 4) & 3, value); - /* always followed by data value */ - break; - case 16 ... 23: /* data tracing, data value */ - printf("Data trace %d, ", (c >> 4) & 3); - label = (c & 0x8) ? "write" : "read"; - switch (c & 3) { - case 3: - printf("word %s, value %#08x", label, value); - break; - case 2: - printf("halfword %s, value %#04x", label, value); - break; - case 1: - printf("byte %s, value %#02x", label, value); - break; - } - break; - default: - printf("UNDEFINED, rawtype: %x", type); - break; - } - - printf("\n"); - return; -} - -/* - * Table of SWIT (SoftWare InstrumentTation) message dump formats, for - * ITM port 0..31 application data. - * - * Eventually this should be customizable; all usage is application defined. - * - * REVISIT there can be up to 256 trace ports, via "ITM Extension" packets - */ -struct { - int port; - void (*show)(int port, unsigned data); -} format[] = { - { .port = 31, .show = show_task, }, -}; - -static void show_swit(FILE *f, int c) -{ - unsigned port = c >> 3; - unsigned value = 0; - unsigned i; - - if (port + 1 == dump_swit) { - if (!read_varlen(f, c, &value)) - return; - printf("%c", value); - return; - } - - if (!read_varlen(f, c, &value)) - return; - - if (dump_swit) - return; - - printf("SWIT %u - ", port); - - printf("%#08x", value); - - for (i = 0; i < sizeof(format) / sizeof(format[0]); i++) { - if (format[i].port == port) { - printf(", "); - format[i].show(port, value); - break; - } - } - - printf("\n"); - return; -} - -static void show_timestamp(FILE *f, int c) -{ - unsigned counter = 0; - char *label = ""; - bool delayed = false; - - if (dump_swit) - return; - - printf("TIMESTAMP - "); - - /* Format 2: header only */ - if (!(c & 0x80)) { - switch (c) { - case 0: /* sync packet -- coding error! */ - case 0x70: /* overflow -- ditto! */ - printf("ERROR - %#02x\n", c); - break; - default: - /* synchronous to ITM */ - counter = c >> 4; - goto done; - } - return; - } - - /* Format 1: one to four bytes of data too */ - switch (c >> 4) { - default: - label = ", reserved control\n"; - break; - case 0xc: - /* synchronous to ITM */ - break; - case 0xd: - label = ", timestamp delayed"; - delayed = true; - break; - case 0xe: - label = ", packet delayed"; - delayed = true; - break; - case 0xf: - label = ", packet and timetamp delayed"; - delayed = true; - break; - } - - c = fgetc(f); - if (c == EOF) - goto err; - counter = c & 0x7f; - if (!(c & 0x80)) - goto done; - - c = fgetc(f); - if (c == EOF) - goto err; - counter |= (c & 0x7f) << 7; - if (!(c & 0x80)) - goto done; - - c = fgetc(f); - if (c == EOF) - goto err; - counter |= (c & 0x7f) << 14; - if (!(c & 0x80)) - goto done; - - c = fgetc(f); - if (c == EOF) - goto err; - counter |= (c & 0x7f) << 21; - -done: - /* REVISIT should we try to convert from delta values? */ - printf("+%u%s\n", counter, label); - return; - -err: - printf("(ERROR %d - %s) ", errno, strerror(errno)); - goto done; -} - -int main(int argc, char **argv) -{ - FILE *f = stdin; - int c; - - /* parse arguments */ - while ((c = getopt(argc, argv, "f:d:")) != EOF) { - switch (c) { - case 'f': - /* e.g. from UART connected to /dev/ttyUSB0 */ - f = fopen(optarg, "r"); - if (!f) { - perror(optarg); - return 1; - } - break; - case 'd': - dump_swit = atoi(optarg); - break; - default: - fprintf(stderr, "usage: %s [-f input]", - basename(argv[0])); - return 1; - } - } - - /* Parse data ... records have a header then data bytes. - * NOTE: we assume getc() deals in 8-bit bytes. - */ - bool overflow = false; - - while ((c = getc(f)) != EOF) { - - /* Sync packet ... 7 zeroes, 0x80 */ - if (c == 0) { - int i; - - for (i = 0; i < 6; i++) { - c = fgetc(f); - if (c == EOF) - break; - if (c != 0) - goto bad_sync; - } - c = fgetc(f); - if (c == 0x80) { - printf("SYNC\n"); - continue; - } -bad_sync: - printf("BAD SYNC\n"); - continue; - } - - /* Overflow packet */ - if (c == 0x70) { - /* REVISIT later, report just what overflowed! - * Timestamp and SWIT can happen. Non-ITM too? - */ - overflow = true; - printf("OVERFLOW ...\n"); - continue; - } - overflow = false; - - switch (c & 0x0f) { - case 0x00: /* Timestamp */ - show_timestamp(f, c); - break; - case 0x04: /* "Reserved" */ - show_reserved(f, "RESERVED", c); - break; - case 0x08: /* ITM Extension */ - /* FIXME someday, handle these ... */ - show_reserved(f, "ITM EXT", c); - break; - case 0x0c: /* DWT Extension */ - show_reserved(f, "DWT EXT", c); - break; - default: - if (c & 4) - show_hard(f, c); - else - show_swit(f, c); - break; - } - - } - - return 0; -} diff --git a/contrib/libdcc/README b/contrib/libdcc/README deleted file mode 100644 index d67ccce3f..000000000 --- a/contrib/libdcc/README +++ /dev/null @@ -1,19 +0,0 @@ -This code is an example of using the openocd debug message system. - -Before the message output is seen in the debug window, the functionality -will need enabling: - -From the gdb prompt: -monitor target_request debugmsgs enable -monitor trace point 1 - -From the Telnet prompt: -target_request debugmsgs enable -trace point 1 - -To see how many times the trace point was hit: -(monitor) trace point 1 - -Spen -spen@spen-soft.co.uk - diff --git a/contrib/libdcc/dcc_stdio.c b/contrib/libdcc/dcc_stdio.c deleted file mode 100644 index 5a457e7f6..000000000 --- a/contrib/libdcc/dcc_stdio.c +++ /dev/null @@ -1,157 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2008 by Dominic Rath * - * Dominic.Rath@gmx.de * - * Copyright (C) 2008 by Spencer Oliver * - * spen@spen-soft.co.uk * - * Copyright (C) 2008 by Frederik Kriewtz * - * frederik@kriewitz.eu * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - ***************************************************************************/ - -#include "dcc_stdio.h" - -#define TARGET_REQ_TRACEMSG 0x00 -#define TARGET_REQ_DEBUGMSG_ASCII 0x01 -#define TARGET_REQ_DEBUGMSG_HEXMSG(size) (0x01 | ((size & 0xff) << 8)) -#define TARGET_REQ_DEBUGCHAR 0x02 - -#if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) || defined(__ARM_ARCH_6SM__) - -/* we use the System Control Block DCRDR reg to simulate a arm7_9 dcc channel - * DCRDR[7:0] is used by target for status - * DCRDR[15:8] is used by target for write buffer - * DCRDR[23:16] is used for by host for status - * DCRDR[31:24] is used for by host for write buffer */ - -#define NVIC_DBG_DATA_R (*((volatile unsigned short *)0xE000EDF8)) - -#define BUSY 1 - -void dbg_write(unsigned long dcc_data) -{ - int len = 4; - - while (len--) - { - /* wait for data ready */ - while (NVIC_DBG_DATA_R & BUSY); - - /* write our data and set write flag - tell host there is data*/ - NVIC_DBG_DATA_R = (unsigned short)(((dcc_data & 0xff) << 8) | BUSY); - dcc_data >>= 8; - } -} - -#elif defined(__ARM_ARCH_4T__) || defined(__ARM_ARCH_5TE__) || defined(__ARM_ARCH_5T__) - -void dbg_write(unsigned long dcc_data) -{ - unsigned long dcc_status; - - do { - asm volatile("mrc p14, 0, %0, c0, c0" : "=r" (dcc_status)); - } while (dcc_status & 0x2); - - asm volatile("mcr p14, 0, %0, c1, c0" : : "r" (dcc_data)); -} - -#else - #error unsupported target -#endif - -void dbg_trace_point(unsigned long number) -{ - dbg_write(TARGET_REQ_TRACEMSG | (number << 8)); -} - -void dbg_write_u32(const unsigned long *val, long len) -{ - dbg_write(TARGET_REQ_DEBUGMSG_HEXMSG(4) | ((len & 0xffff) << 16)); - - while (len > 0) - { - dbg_write(*val); - - val++; - len--; - } -} - -void dbg_write_u16(const unsigned short *val, long len) -{ - unsigned long dcc_data; - - dbg_write(TARGET_REQ_DEBUGMSG_HEXMSG(2) | ((len & 0xffff) << 16)); - - while (len > 0) - { - dcc_data = val[0] - | ((len > 1) ? val[1] << 16: 0x0000); - - dbg_write(dcc_data); - - val += 2; - len -= 2; - } -} - -void dbg_write_u8(const unsigned char *val, long len) -{ - unsigned long dcc_data; - - dbg_write(TARGET_REQ_DEBUGMSG_HEXMSG(1) | ((len & 0xffff) << 16)); - - while (len > 0) - { - dcc_data = val[0] - | ((len > 1) ? val[1] << 8 : 0x00) - | ((len > 2) ? val[2] << 16 : 0x00) - | ((len > 3) ? val[3] << 24 : 0x00); - - dbg_write(dcc_data); - - val += 4; - len -= 4; - } -} - -void dbg_write_str(const char *msg) -{ - long len; - unsigned long dcc_data; - - for (len = 0; msg[len] && (len < 65536); len++); - - dbg_write(TARGET_REQ_DEBUGMSG_ASCII | ((len & 0xffff) << 16)); - - while (len > 0) - { - dcc_data = msg[0] - | ((len > 1) ? msg[1] << 8 : 0x00) - | ((len > 2) ? msg[2] << 16 : 0x00) - | ((len > 3) ? msg[3] << 24 : 0x00); - dbg_write(dcc_data); - - msg += 4; - len -= 4; - } -} - -void dbg_write_char(char msg) -{ - dbg_write(TARGET_REQ_DEBUGCHAR | ((msg & 0xff) << 16)); -} diff --git a/contrib/libdcc/dcc_stdio.h b/contrib/libdcc/dcc_stdio.h deleted file mode 100644 index cb87ab358..000000000 --- a/contrib/libdcc/dcc_stdio.h +++ /dev/null @@ -1,35 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2008 by Dominic Rath * - * Dominic.Rath@gmx.de * - * Copyright (C) 2008 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - ***************************************************************************/ - -#ifndef DCC_STDIO_H -#define DCC_STDIO_H - -void dbg_trace_point(unsigned long number); - -void dbg_write_u32(const unsigned long *val, long len); -void dbg_write_u16(const unsigned short *val, long len); -void dbg_write_u8(const unsigned char *val, long len); - -void dbg_write_str(const char *msg); -void dbg_write_char(char msg); - -#endif /* DCC_STDIO_H */ diff --git a/contrib/libdcc/example.c b/contrib/libdcc/example.c deleted file mode 100644 index 2cbef2053..000000000 --- a/contrib/libdcc/example.c +++ /dev/null @@ -1,58 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2008 by Spencer Oliver * - * spen@spen-soft.co.uk * - * Copyright (C) 2008 by Frederik Kriewtz * - * frederik@kriewitz.eu * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - ***************************************************************************/ - -#include "dcc_stdio.h" - -/* enable openocd debugmsg at the gdb prompt: - * monitor target_request debugmsgs enable - * - * create a trace point: - * monitor trace point 1 - * - * to show how often the trace point was hit: - * monitor trace point -*/ - -int main(void) -{ - dbg_write_str("hello world"); - - dbg_write_char('t'); - dbg_write_char('e'); - dbg_write_char('s'); - dbg_write_char('t'); - dbg_write_char('\n'); - - unsigned long test_u32 = 0x01234567; - dbg_write_u32(&test_u32, 1); - - static const unsigned short test_u16[] = {0x0123, 0x4567, 0x89AB, 0xCDEF, 0x0123, 0x4567, 0x89AB, 0xCDEF}; - dbg_write_u16(test_u16, 8); - - static const unsigned char test_u8[] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0XDD, 0xEE, 0xFF}; - dbg_write_u8(test_u8, 16); - - while(1) - { - dbg_trace_point(0); - } -} diff --git a/contrib/loaders/Makefile b/contrib/loaders/Makefile deleted file mode 100644 index 2e5eba8c2..000000000 --- a/contrib/loaders/Makefile +++ /dev/null @@ -1,33 +0,0 @@ -.PHONY: arm clean-arm - -all: arm - -common_dirs = \ - checksum \ - erase_check \ - watchdog - -ARM_CROSS_COMPILE ?= arm-none-eabi- - -arm_dirs = \ - flash/fm4 \ - flash/kinetis_ke \ - flash/xmc1xxx - -arm: - for d in $(common_dirs); do \ - $(MAKE) -C $$d arm; \ - done - for d in $(arm_dirs); do \ - $(MAKE) -C $$d all CROSS_COMPILE=$(ARM_CROSS_COMPILE); \ - done - -clean-arm: - for d in $(arm_dirs); do \ - $(MAKE) -C $$d clean; \ - done - -clean: clean-arm - for d in $(common_dirs); do \ - $(MAKE) -C $$d clean; \ - done diff --git a/contrib/loaders/README b/contrib/loaders/README deleted file mode 100644 index 41236ef4e..000000000 --- a/contrib/loaders/README +++ /dev/null @@ -1,33 +0,0 @@ -Included in these directories are the src to the various ram loaders used -within openocd. - -** target checksum loaders ** - -checksum/armv4_5_crc.s : - - ARMv4 and ARMv5 checksum loader : see target/arm_crc_code.c:arm_crc_code - -checksum/armv7m_crc.s : - - ARMv7m checksum loader : see target/armv7m.c:cortex_m_crc_code - -checksum/mips32.s : - - MIPS32 checksum loader : see target/mips32.c:mips_crc_code - -** target flash loaders ** - -flash/pic32mx.s : - - Microchip PIC32 flash loader : see flash/nor/pic32mx.c:pic32mx_flash_write_code - -flash/stellaris.s : - - TI Stellaris flash loader : see flash/nor/stellaris.c:stellaris_write_code - -flash/stm32x.s : - - ST STM32 flash loader : see flash/nor/stm32x.c:stm32x_flash_write_code - -flash/str7x.s : - - ST STR7 flash loader : see flash/nor/str7x.c:str7x_flash_write_code - -flash/str9x.s : - - ST STR9 flash loader : see flash/nor/str9x.c:str9x_flash_write_code - -Spencer Oliver -spen@spen-soft.co.uk diff --git a/contrib/loaders/checksum/Makefile b/contrib/loaders/checksum/Makefile deleted file mode 100644 index b9f59b8d8..000000000 --- a/contrib/loaders/checksum/Makefile +++ /dev/null @@ -1,30 +0,0 @@ -BIN2C = ../../../src/helper/bin2char.sh - -ARM_CROSS_COMPILE ?= arm-none-eabi- -ARM_AS ?= $(ARM_CROSS_COMPILE)as -ARM_OBJCOPY ?= $(ARM_CROSS_COMPILE)objcopy - -ARM_AFLAGS = -EL - -arm: armv4_5_crc.inc armv7m_crc.inc - -armv4_5_%.elf: armv4_5_%.s - $(ARM_AS) $(ARM_AFLAGS) $< -o $@ - -armv4_5_%.bin: armv4_5_%.elf - $(ARM_OBJCOPY) -Obinary $< $@ - -armv4_5_%.inc: armv4_5_%.bin - $(BIN2C) < $< > $@ - -armv7m_%.elf: armv7m_%.s - $(ARM_AS) $(ARM_AFLAGS) $< -o $@ - -armv7m_%.bin: armv7m_%.elf - $(ARM_OBJCOPY) -Obinary $< $@ - -armv7m_%.inc: armv7m_%.bin - $(BIN2C) < $< > $@ - -clean: - -rm -f *.elf *.bin *.inc diff --git a/contrib/loaders/checksum/armv4_5_crc.inc b/contrib/loaders/checksum/armv4_5_crc.inc deleted file mode 100644 index 216f6028b..000000000 --- a/contrib/loaders/checksum/armv4_5_crc.inc +++ /dev/null @@ -1,7 +0,0 @@ -/* Autogenerated with ../../../src/helper/bin2char.sh */ -0x00,0x20,0xa0,0xe1,0x00,0x00,0xe0,0xe3,0x01,0x30,0xa0,0xe1,0x00,0x40,0xa0,0xe3, -0x0b,0x00,0x00,0xea,0x04,0x10,0xd2,0xe7,0x30,0x70,0x9f,0xe5,0x01,0x0c,0x20,0xe0, -0x00,0x50,0xa0,0xe3,0x00,0x00,0x50,0xe3,0x80,0x60,0xa0,0xe1,0x01,0x50,0x85,0xe2, -0x06,0x00,0xa0,0xe1,0x07,0x00,0x26,0xb0,0x08,0x00,0x55,0xe3,0xf8,0xff,0xff,0x1a, -0x01,0x40,0x84,0xe2,0x03,0x00,0x54,0xe1,0xf1,0xff,0xff,0x1a,0x70,0x00,0x20,0xe1, -0xb7,0x1d,0xc1,0x04, diff --git a/contrib/loaders/checksum/armv4_5_crc.s b/contrib/loaders/checksum/armv4_5_crc.s deleted file mode 100644 index 8f62dc89f..000000000 --- a/contrib/loaders/checksum/armv4_5_crc.s +++ /dev/null @@ -1,58 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2010 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - ***************************************************************************/ - -/* - r0 - address in - crc out - r1 - char count -*/ - - .text - .arm - -_start: -main: - mov r2, r0 - mov r0, #0xffffffff /* crc */ - mov r3, r1 - mov r4, #0 - b ncomp -nbyte: - ldrb r1, [r2, r4] - ldr r7, CRC32XOR - eor r0, r0, r1, asl #24 - mov r5, #0 -loop: - cmp r0, #0 - mov r6, r0, asl #1 - add r5, r5, #1 - mov r0, r6 - eorlt r0, r6, r7 - cmp r5, #8 - bne loop - add r4, r4, #1 -ncomp: - cmp r4, r3 - bne nbyte -end: - bkpt #0 - -CRC32XOR: .word 0x04c11db7 - - .end diff --git a/contrib/loaders/checksum/armv7m_crc.inc b/contrib/loaders/checksum/armv7m_crc.inc deleted file mode 100644 index 1b013fd9e..000000000 --- a/contrib/loaders/checksum/armv7m_crc.inc +++ /dev/null @@ -1,5 +0,0 @@ -/* Autogenerated with ../../../src/helper/bin2char.sh */ -0x02,0x46,0x00,0x20,0xc0,0x43,0x0a,0x4e,0x0b,0x46,0x00,0x24,0x0d,0xe0,0x11,0x5d, -0x09,0x06,0x48,0x40,0x00,0x25,0x00,0x28,0x02,0xda,0x40,0x00,0x70,0x40,0x00,0xe0, -0x40,0x00,0x01,0x35,0x08,0x2d,0xf6,0xd1,0x01,0x34,0x9c,0x42,0xef,0xd1,0x00,0xbe, -0xb7,0x1d,0xc1,0x04, diff --git a/contrib/loaders/checksum/armv7m_crc.s b/contrib/loaders/checksum/armv7m_crc.s deleted file mode 100644 index 923875a08..000000000 --- a/contrib/loaders/checksum/armv7m_crc.s +++ /dev/null @@ -1,71 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2010 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - ***************************************************************************/ - -/* - parameters: - r0 - address in - crc out - r1 - char count -*/ - - .text - .syntax unified - .cpu cortex-m0 - .thumb - .thumb_func - - .align 2 - -_start: -main: - mov r2, r0 - movs r0, #0 - mvns r0, r0 - ldr r6, CRC32XOR - mov r3, r1 - movs r4, #0 - b ncomp -nbyte: - ldrb r1, [r2, r4] - lsls r1, r1, #24 - eors r0, r0, r1 - movs r5, #0 -loop: - cmp r0, #0 - bge notset - lsls r0, r0, #1 - eors r0, r0, r6 - b cont -notset: - lsls r0, r0, #1 -cont: - adds r5, r5, #1 - cmp r5, #8 - bne loop - adds r4, r4, #1 -ncomp: - cmp r4, r3 - bne nbyte - bkpt #0 - - .align 2 - -CRC32XOR: .word 0x04c11db7 - - .end diff --git a/contrib/loaders/checksum/mips32.s b/contrib/loaders/checksum/mips32.s deleted file mode 100644 index 3073d87a3..000000000 --- a/contrib/loaders/checksum/mips32.s +++ /dev/null @@ -1,72 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2010 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - ***************************************************************************/ - - .global main - .text - .set noreorder - -/* params: - * $a0 address in - * $a1 byte count - * vars - * $a0 crc - * $a1 crc data byte - * temps: - * t3 v0 a3 a2 t0 v1 - */ - -.ent main -main: - addiu $t4, $a0, 0 /* address in */ - addiu $t2, $a1, 0 /* count */ - - addiu $a0, $zero, 0xffffffff /* a0 crc - result */ - - beq $zero, $zero, ncomp - addiu $t3, $zero, 0 /* clear bytes read */ - -nbyte: - lb $a1, ($t4) /* load byte from source address */ - addi $t4, $t4, 1 /* inc byte count */ - -crc: - sll $a1, $a1, 24 - lui $v0, 0x04c1 - xor $a0, $a0, $a1 - ori $a3, $v0, 0x1db7 - addu $a2, $zero, $zero /* clear bit count */ -loop: - sll $t0, $a0, 1 - addiu $a2, $a2, 1 /* inc bit count */ - slti $a0, $a0, 0 - xor $t1, $t0, $a3 - movn $t0, $t1, $a0 - slti $v1, $a2, 8 /* 8bits processed */ - bne $v1, $zero, loop - addu $a0, $t0, $zero - -ncomp: - bne $t2, $t3, nbyte /* all bytes processed */ - addiu $t3, $t3, 1 - -wait: - sdbbp - -.end main diff --git a/contrib/loaders/erase_check/Makefile b/contrib/loaders/erase_check/Makefile deleted file mode 100644 index 01e62dead..000000000 --- a/contrib/loaders/erase_check/Makefile +++ /dev/null @@ -1,30 +0,0 @@ -BIN2C = ../../../src/helper/bin2char.sh - -ARM_CROSS_COMPILE ?= arm-none-eabi- -ARM_AS ?= $(ARM_CROSS_COMPILE)as -ARM_OBJCOPY ?= $(ARM_CROSS_COMPILE)objcopy - -ARM_AFLAGS = -EL - -arm: armv4_5_erase_check.inc armv7m_erase_check.inc armv7m_0_erase_check.inc - -armv4_5_%.elf: armv4_5_%.s - $(ARM_AS) $(ARM_AFLAGS) $< -o $@ - -armv4_5_%.bin: armv4_5_%.elf - $(ARM_OBJCOPY) -Obinary $< $@ - -armv4_5_%.inc: armv4_5_%.bin - $(BIN2C) < $< > $@ - -armv7m_%.elf: armv7m_%.s - $(ARM_AS) $(ARM_AFLAGS) $< -o $@ - -armv7m_%.bin: armv7m_%.elf - $(ARM_OBJCOPY) -Obinary $< $@ - -armv7m_%.inc: armv7m_%.bin - $(BIN2C) < $< > $@ - -clean: - -rm -f *.elf *.bin *.inc diff --git a/contrib/loaders/erase_check/armv4_5_erase_check.inc b/contrib/loaders/erase_check/armv4_5_erase_check.inc deleted file mode 100644 index f7f8ddf12..000000000 --- a/contrib/loaders/erase_check/armv4_5_erase_check.inc +++ /dev/null @@ -1,3 +0,0 @@ -/* Autogenerated with ../../../src/helper/bin2char.sh */ -0x01,0x30,0xd0,0xe4,0x03,0x20,0x02,0xe0,0x01,0x10,0x51,0xe2,0xfb,0xff,0xff,0x1a, -0x70,0x00,0x20,0xe1, diff --git a/contrib/loaders/erase_check/armv4_5_erase_check.s b/contrib/loaders/erase_check/armv4_5_erase_check.s deleted file mode 100644 index 6c7d27f05..000000000 --- a/contrib/loaders/erase_check/armv4_5_erase_check.s +++ /dev/null @@ -1,39 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2010 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - ***************************************************************************/ - -/* - parameters: - r0 - address in - r1 - byte count - r2 - mask - result out -*/ - - .text - .arm - -loop: - ldrb r3, [r0], #1 - and r2, r2, r3 - subs r1, r1, #1 - bne loop -end: - bkpt #0 - - .end diff --git a/contrib/loaders/erase_check/armv7m_0_erase_check.inc b/contrib/loaders/erase_check/armv7m_0_erase_check.inc deleted file mode 100644 index 76115ec17..000000000 --- a/contrib/loaders/erase_check/armv7m_0_erase_check.inc +++ /dev/null @@ -1,2 +0,0 @@ -/* Autogenerated with ../../../src/helper/bin2char.sh */ -0x03,0x78,0x01,0x30,0x1a,0x43,0x01,0x39,0xfa,0xd1,0x00,0xbe, diff --git a/contrib/loaders/erase_check/armv7m_0_erase_check.s b/contrib/loaders/erase_check/armv7m_0_erase_check.s deleted file mode 100644 index 6b1e92a85..000000000 --- a/contrib/loaders/erase_check/armv7m_0_erase_check.s +++ /dev/null @@ -1,45 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2014 by Jeff Ciesielski * - * jeffciesielski@gmail.com * - * * - * Based on the armv7m erase checker by: * - * Copyright (C) 2010 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - ***************************************************************************/ - -/* - parameters: - r0 - address in - r1 - byte count - r2 - mask - result out -*/ - - .text - .syntax unified - .cpu cortex-m0 - .thumb - .thumb_func - - .align 2 - -loop: - ldrb r3, [r0] - adds r0, #1 - orrs r2, r2, r3 - subs r1, r1, #1 - bne loop -end: - bkpt #0 - - .end diff --git a/contrib/loaders/erase_check/armv7m_erase_check.inc b/contrib/loaders/erase_check/armv7m_erase_check.inc deleted file mode 100644 index 1fe25cd51..000000000 --- a/contrib/loaders/erase_check/armv7m_erase_check.inc +++ /dev/null @@ -1,2 +0,0 @@ -/* Autogenerated with ../../../src/helper/bin2char.sh */ -0x03,0x78,0x01,0x30,0x1a,0x40,0x01,0x39,0xfa,0xd1,0x00,0xbe, diff --git a/contrib/loaders/erase_check/armv7m_erase_check.s b/contrib/loaders/erase_check/armv7m_erase_check.s deleted file mode 100644 index 886e3e280..000000000 --- a/contrib/loaders/erase_check/armv7m_erase_check.s +++ /dev/null @@ -1,45 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2010 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - ***************************************************************************/ - -/* - parameters: - r0 - address in - r1 - byte count - r2 - mask - result out -*/ - - .text - .syntax unified - .cpu cortex-m0 - .thumb - .thumb_func - - .align 2 - -loop: - ldrb r3, [r0] - adds r0, #1 - ands r2, r2, r3 - subs r1, r1, #1 - bne loop -end: - bkpt #0 - - .end diff --git a/contrib/loaders/flash/armv4_5_cfi_intel_16.s b/contrib/loaders/flash/armv4_5_cfi_intel_16.s deleted file mode 100644 index c35b6515f..000000000 --- a/contrib/loaders/flash/armv4_5_cfi_intel_16.s +++ /dev/null @@ -1,57 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005, 2007 by Dominic Rath * - * Dominic.Rath@gmx.de * - * Copyright (C) 2010 Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - ***************************************************************************/ - - .text - .arm - .arch armv4 - - .section .init - -/* algorithm register usage: - * r0: source address (in RAM) - * r1: target address (in Flash) - * r2: count - * r3: flash write command - * r4: status byte (returned to host) - * r5: busy test pattern - * r6: error test pattern - */ - -loop: - ldrh r4, [r0], #2 - strh r3, [r1] - strh r4, [r1] -busy: - ldrh r4, [r1] - and r7, r4, r5 - cmp r7, r5 - bne busy - tst r4, r6 - bne done - subs r2, r2, #1 - beq done - add r1, r1, #2 - b loop -done: - b done - - .end diff --git a/contrib/loaders/flash/armv4_5_cfi_intel_32.s b/contrib/loaders/flash/armv4_5_cfi_intel_32.s deleted file mode 100644 index db477178a..000000000 --- a/contrib/loaders/flash/armv4_5_cfi_intel_32.s +++ /dev/null @@ -1,57 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005, 2007 by Dominic Rath * - * Dominic.Rath@gmx.de * - * Copyright (C) 2010 Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - ***************************************************************************/ - - .text - .arm - .arch armv4 - - .section .init - -/* algorithm register usage: - * r0: source address (in RAM) - * r1: target address (in Flash) - * r2: count - * r3: flash write command - * r4: status byte (returned to host) - * r5: busy test pattern - * r6: error test pattern - */ - -loop: - ldr r4, [r0], #4 - str r3, [r1] - str r4, [r1] -busy: - ldr r4, [r1] - and r7, r4, r5 - cmp r7, r5 - bne busy - tst r4, r6 - bne done - subs r2, r2, #1 - beq done - add r1, r1, #4 - b loop -done: - b done - - .end diff --git a/contrib/loaders/flash/armv4_5_cfi_intel_8.s b/contrib/loaders/flash/armv4_5_cfi_intel_8.s deleted file mode 100644 index d50acd2ad..000000000 --- a/contrib/loaders/flash/armv4_5_cfi_intel_8.s +++ /dev/null @@ -1,57 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005, 2007 by Dominic Rath * - * Dominic.Rath@gmx.de * - * Copyright (C) 2010 Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - ***************************************************************************/ - - .text - .arm - .arch armv4 - - .section .init - -/* algorithm register usage: - * r0: source address (in RAM) - * r1: target address (in Flash) - * r2: count - * r3: flash write command - * r4: status byte (returned to host) - * r5: busy test pattern - * r6: error test pattern - */ - -loop: - ldrb r4, [r0], #1 - strb r3, [r1] - strb r4, [r1] -busy: - ldrb r4, [r1] - and r7, r4, r5 - cmp r7, r5 - bne busy - tst r4, r6 - bne done - subs r2, r2, #1 - beq done - add r1, r1, #1 - b loop -done: - b done - - .end diff --git a/contrib/loaders/flash/armv4_5_cfi_span_16.s b/contrib/loaders/flash/armv4_5_cfi_span_16.s deleted file mode 100644 index 532727140..000000000 --- a/contrib/loaders/flash/armv4_5_cfi_span_16.s +++ /dev/null @@ -1,75 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005, 2007 by Dominic Rath * - * Dominic.Rath@gmx.de * - * Copyright (C) 2010 Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - ***************************************************************************/ - - .text - .arm - .arch armv4 - - .section .init - -/* input parameters - */ -/* R0 = source address */ -/* R1 = destination address */ -/* R2 = number of writes */ -/* R3 = flash write command */ -/* R4 = constant to mask DQ7 bits (also used for Dq5 with shift) */ -/* output parameters - */ -/* R5 = 0x80 ok 0x00 bad */ -/* temp registers - */ -/* R6 = value read from flash to test status */ -/* R7 = holding register */ -/* unlock registers - */ -/* R8 = unlock1_addr */ -/* R9 = unlock1_cmd */ -/* R10 = unlock2_addr */ -/* R11 = unlock2_cmd */ - -code: - ldrh r5, [r0], #2 - strh r9, [r8] - strh r11, [r10] - strh r3, [r8] - strh r5, [r1] - nop -busy: - ldrh r6, [r1] - eor r7, r5, r6 - ands r7, r4, r7 - beq cont /* b if DQ7 == Data7 */ - ands r6, r6, r4, lsr #2 - beq busy /* b if DQ5 low */ - ldrh r6, [r1] - eor r7, r5, r6 - ands r7, r4, r7 - beq cont /* b if DQ7 == Data7 */ - mov r5, #0 /* 0x0 - return 0x00, error */ - bne done -cont: - subs r2, r2, #1 /* 0x1 */ - moveq r5, #128 /* 0x80 */ - beq done - add r1, r1, #2 /* 0x2 */ - b code -done: - b done - - .end diff --git a/contrib/loaders/flash/armv4_5_cfi_span_16_dq7.s b/contrib/loaders/flash/armv4_5_cfi_span_16_dq7.s deleted file mode 100644 index 919f6e164..000000000 --- a/contrib/loaders/flash/armv4_5_cfi_span_16_dq7.s +++ /dev/null @@ -1,66 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005, 2007 by Dominic Rath * - * Dominic.Rath@gmx.de * - * Copyright (C) 2010 Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - ***************************************************************************/ - - .text - .arm - .arch armv4 - - .section .init - -/* input parameters - */ -/* R0 = source address */ -/* R1 = destination address */ -/* R2 = number of writes */ -/* R3 = flash write command */ -/* R4 = constant to mask DQ7 bits (also used for Dq5 with shift) */ -/* output parameters - */ -/* R5 = 0x80 ok 0x00 bad */ -/* temp registers - */ -/* R6 = value read from flash to test status */ -/* R7 = holding register */ -/* unlock registers - */ -/* R8 = unlock1_addr */ -/* R9 = unlock1_cmd */ -/* R10 = unlock2_addr */ -/* R11 = unlock2_cmd */ - -code: - ldrh r5, [r0], #2 - strh r9, [r8] - strh r11, [r10] - strh r3, [r8] - strh r5, [r1] - nop -busy: - ldrh r6, [r1] - eor r7, r5, r6 - ands r7, #0x80 - bne busy - subs r2, r2, #1 /* 0x1 */ - moveq r5, #128 /* 0x80 */ - beq done - add r1, r1, #2 /* 0x2 */ - b code -done: - b done - - .end diff --git a/contrib/loaders/flash/armv4_5_cfi_span_32.s b/contrib/loaders/flash/armv4_5_cfi_span_32.s deleted file mode 100644 index c8f87b12b..000000000 --- a/contrib/loaders/flash/armv4_5_cfi_span_32.s +++ /dev/null @@ -1,75 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005, 2007 by Dominic Rath * - * Dominic.Rath@gmx.de * - * Copyright (C) 2010 Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - ***************************************************************************/ - - .text - .arm - .arch armv4 - - .section .init - -/* input parameters - */ -/* R0 = source address */ -/* R1 = destination address */ -/* R2 = number of writes */ -/* R3 = flash write command */ -/* R4 = constant to mask DQ7 bits (also used for Dq5 with shift) */ -/* output parameters - */ -/* R5 = 0x80 ok 0x00 bad */ -/* temp registers - */ -/* R6 = value read from flash to test status */ -/* R7 = holding register */ -/* unlock registers - */ -/* R8 = unlock1_addr */ -/* R9 = unlock1_cmd */ -/* R10 = unlock2_addr */ -/* R11 = unlock2_cmd */ - -code: - ldr r5, [r0], #4 - str r9, [r8] - str r11, [r10] - str r3, [r8] - str r5, [r1] - nop -busy: - ldr r6, [r1] - eor r7, r5, r6 - ands r7, r4, r7 - beq cont /* b if DQ7 == Data7 */ - ands r6, r6, r4, lsr #2 - beq busy /* b if DQ5 low */ - ldr r6, [r1] - eor r7, r5, r6 - ands r7, r4, r7 - beq cont /* b if DQ7 == Data7 */ - mov r5, #0 /* 0x0 - return 0x00, error */ - bne done -cont: - subs r2, r2, #1 /* 0x1 */ - moveq r5, #128 /* 0x80 */ - beq done - add r1, r1, #4 /* 0x4 */ - b code -done: - b done - - .end diff --git a/contrib/loaders/flash/armv4_5_cfi_span_8.s b/contrib/loaders/flash/armv4_5_cfi_span_8.s deleted file mode 100644 index 46018e18b..000000000 --- a/contrib/loaders/flash/armv4_5_cfi_span_8.s +++ /dev/null @@ -1,75 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005, 2007 by Dominic Rath * - * Dominic.Rath@gmx.de * - * Copyright (C) 2010 Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - ***************************************************************************/ - - .text - .arm - .arch armv4 - - .section .init - -/* input parameters - */ -/* R0 = source address */ -/* R1 = destination address */ -/* R2 = number of writes */ -/* R3 = flash write command */ -/* R4 = constant to mask DQ7 bits (also used for Dq5 with shift) */ -/* output parameters - */ -/* R5 = 0x80 ok 0x00 bad */ -/* temp registers - */ -/* R6 = value read from flash to test status */ -/* R7 = holding register */ -/* unlock registers - */ -/* R8 = unlock1_addr */ -/* R9 = unlock1_cmd */ -/* R10 = unlock2_addr */ -/* R11 = unlock2_cmd */ - -code: - ldrb r5, [r0], #1 - strb r9, [r8] - strb r11, [r10] - strb r3, [r8] - strb r5, [r1] - nop -busy: - ldrb r6, [r1] - eor r7, r5, r6 - ands r7, r4, r7 - beq cont /* b if DQ7 == Data7 */ - ands r6, r6, r4, lsr #2 - beq busy /* b if DQ5 low */ - ldrb r6, [r1] - eor r7, r5, r6 - ands r7, r4, r7 - beq cont /* b if DQ7 == Data7 */ - mov r5, #0 /* 0x0 - return 0x00, error */ - bne done -cont: - subs r2, r2, #1 /* 0x1 */ - moveq r5, #128 /* 0x80 */ - beq done - add r1, r1, #1 /* 0x1 */ - b code -done: - b done - - .end diff --git a/contrib/loaders/flash/armv7m_cfi_span_16.s b/contrib/loaders/flash/armv7m_cfi_span_16.s deleted file mode 100644 index d4915a78c..000000000 --- a/contrib/loaders/flash/armv7m_cfi_span_16.s +++ /dev/null @@ -1,81 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005, 2007 by Dominic Rath * - * Dominic.Rath@gmx.de * - * Copyright (C) 2010 Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - ***************************************************************************/ - - .text - .syntax unified - .arch armv7-m - .thumb - .thumb_func - - .align 2 - -/* input parameters - */ -/* R0 = source address */ -/* R1 = destination address */ -/* R2 = number of writes */ -/* R3 = flash write command */ -/* R4 = constant to mask DQ7 bits (also used for Dq5 with shift) */ -/* output parameters - */ -/* R5 = 0x80 ok 0x00 bad */ -/* temp registers - */ -/* R6 = value read from flash to test status */ -/* R7 = holding register */ -/* unlock registers - */ -/* R8 = unlock1_addr */ -/* R9 = unlock1_cmd */ -/* R10 = unlock2_addr */ -/* R11 = unlock2_cmd */ - -code: - ldrh r5, [r0], #2 - strh r9, [r8] - strh r11, [r10] - strh r3, [r8] - strh r5, [r1] - nop -busy: - ldrh r6, [r1] - eor r7, r5, r6 - ands r7, r4, r7 - beq cont /* b if DQ7 == Data7 */ - ands r6, r6, r4, lsr #2 - beq busy /* b if DQ5 low */ - ldrh r6, [r1] - eor r7, r5, r6 - ands r7, r4, r7 - beq cont /* b if DQ7 == Data7 */ - mov r5, #0 /* 0x0 - return 0x00, error */ - bne done -cont: - subs r2, r2, #1 /* 0x1 */ - beq success - add r1, r1, #2 /* 0x2 */ - b code - -success: - mov r5, #128 /* 0x80 */ - b done - -done: - bkpt #0 - - .end diff --git a/contrib/loaders/flash/armv7m_cfi_span_16_dq7.s b/contrib/loaders/flash/armv7m_cfi_span_16_dq7.s deleted file mode 100644 index 5b29a3bda..000000000 --- a/contrib/loaders/flash/armv7m_cfi_span_16_dq7.s +++ /dev/null @@ -1,72 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005, 2007 by Dominic Rath * - * Dominic.Rath@gmx.de * - * Copyright (C) 2010 Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - ***************************************************************************/ - - .text - .syntax unified - .arch armv7-m - .thumb - .thumb_func - - .align 2 - -/* input parameters - */ -/* R0 = source address */ -/* R1 = destination address */ -/* R2 = number of writes */ -/* R3 = flash write command */ -/* R4 = constant to mask DQ7 bits */ -/* output parameters - */ -/* R5 = 0x80 ok 0x00 bad */ -/* temp registers - */ -/* R6 = value read from flash to test status */ -/* R7 = holding register */ -/* unlock registers - */ -/* R8 = unlock1_addr */ -/* R9 = unlock1_cmd */ -/* R10 = unlock2_addr */ -/* R11 = unlock2_cmd */ - -code: - ldrh r5, [r0], #2 - strh r9, [r8] - strh r11, [r10] - strh r3, [r8] - strh r5, [r1] - nop -busy: - ldrh r6, [r1] - eor r7, r5, r6 - ands r7, r4, r7 - bne busy - subs r2, r2, #1 /* 0x1 */ - beq success - add r1, r1, #2 /* 0x2 */ - b code - -success: - mov r5, #128 /* 0x80 */ - b done - -done: - bkpt #0 - - .end diff --git a/contrib/loaders/flash/armv7m_io.s b/contrib/loaders/flash/armv7m_io.s deleted file mode 100644 index 797981c53..000000000 --- a/contrib/loaders/flash/armv7m_io.s +++ /dev/null @@ -1,60 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2013 by Henrik Nilsson * - * henrik.nilsson@bytequest.se * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - ***************************************************************************/ - - .text - .syntax unified - .arch armv7-m - .thumb - .thumb_func - - .align 4 - -/* Inputs: - * r0 buffer address - * r1 NAND data address (byte wide) - * r2 buffer length - */ -read: - ldrb r3, [r1] - strb r3, [r0], #1 - subs r2, r2, #1 - bne read - -done_read: - bkpt #0 - - .align 4 - -/* Inputs: - * r0 NAND data address (byte wide) - * r1 buffer address - * r2 buffer length - */ -write: - ldrb r3, [r1], #1 - strb r3, [r0] - subs r2, r2, #1 - bne write - -done_write: - bkpt #0 - - .end - diff --git a/contrib/loaders/flash/at91sam7x/at91sam7x_ocl_flash.script b/contrib/loaders/flash/at91sam7x/at91sam7x_ocl_flash.script deleted file mode 100644 index 85450c14c..000000000 --- a/contrib/loaders/flash/at91sam7x/at91sam7x_ocl_flash.script +++ /dev/null @@ -1,4 +0,0 @@ -soft_reset_halt -load_image at91sam7x_ocl.bin 0x200000 -resume 0x200000 -flash probe 0 diff --git a/contrib/loaders/flash/at91sam7x/at91sam7x_ram.ld b/contrib/loaders/flash/at91sam7x/at91sam7x_ram.ld deleted file mode 100644 index ea06931d0..000000000 --- a/contrib/loaders/flash/at91sam7x/at91sam7x_ram.ld +++ /dev/null @@ -1,132 +0,0 @@ -/**************************************************************************** -* Copyright (c) 2006 by Michael Fischer. All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* 1. Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the author nor the names of its contributors may -* be used to endorse or promote products derived from this software -* without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -* THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS -* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED -* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF -* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -* SUCH DAMAGE. -* -**************************************************************************** -* -* History: -* -* 30.03.06 mifi First Version -****************************************************************************/ - - -ENTRY(ResetHandler) -SEARCH_DIR(.) - -/* - * Define stack size here - */ -FIQ_STACK_SIZE = 0x0100; -IRQ_STACK_SIZE = 0x0100; -ABT_STACK_SIZE = 0x0100; -UND_STACK_SIZE = 0x0100; -SVC_STACK_SIZE = 0x0100; - - -MEMORY -{ - ram : org = 0x00200000, len = 64k -} - -/* - * Do not change the next code - */ -SECTIONS -{ - .text : - { - *(.vectors); - . = ALIGN(4); - *(.init); - . = ALIGN(4); - *(.text); - . = ALIGN(4); - *(.rodata); - . = ALIGN(4); - *(.rodata*); - . = ALIGN(4); - *(.glue_7t); - . = ALIGN(4); - *(.glue_7); - . = ALIGN(4); - etext = .; - } > ram - - .data : - { - PROVIDE (__data_start = .); - *(.data) - . = ALIGN(4); - edata = .; - _edata = .; - PROVIDE (__data_end = .); - } > ram - - .bss : - { - PROVIDE (__bss_start = .); - *(.bss) - *(COMMON) - . = ALIGN(4); - PROVIDE (__bss_end = .); - - . = ALIGN(256); - - PROVIDE (__stack_start = .); - - PROVIDE (__stack_fiq_start = .); - . += FIQ_STACK_SIZE; - . = ALIGN(4); - PROVIDE (__stack_fiq_end = .); - - PROVIDE (__stack_irq_start = .); - . += IRQ_STACK_SIZE; - . = ALIGN(4); - PROVIDE (__stack_irq_end = .); - - PROVIDE (__stack_abt_start = .); - . += ABT_STACK_SIZE; - . = ALIGN(4); - PROVIDE (__stack_abt_end = .); - - PROVIDE (__stack_und_start = .); - . += UND_STACK_SIZE; - . = ALIGN(4); - PROVIDE (__stack_und_end = .); - - PROVIDE (__stack_svc_start = .); - . += SVC_STACK_SIZE; - . = ALIGN(4); - PROVIDE (__stack_svc_end = .); - PROVIDE (__stack_end = .); - PROVIDE (__heap_start = .); - } > ram - -} -/*** EOF ***/ - diff --git a/contrib/loaders/flash/at91sam7x/crt.s b/contrib/loaders/flash/at91sam7x/crt.s deleted file mode 100644 index 2e434bbe7..000000000 --- a/contrib/loaders/flash/at91sam7x/crt.s +++ /dev/null @@ -1,223 +0,0 @@ -/**************************************************************************** -* Copyright (c) 2006 by Michael Fischer. All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* 1. Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the author nor the names of its contributors may -* be used to endorse or promote products derived from this software -* without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -* THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS -* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED -* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF -* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -* SUCH DAMAGE. -* -**************************************************************************** -* -* History: -* -* 18.12.06 mifi First Version -* The hardware initialization is based on the startup file -* crtat91sam7x256_rom.S from NutOS 4.2.1. -* Therefore partial copyright by egnite Software GmbH. -****************************************************************************/ - -/* - * Some defines for the program status registers - */ - ARM_MODE_USER = 0x10 /* Normal User Mode */ - ARM_MODE_FIQ = 0x11 /* FIQ Fast Interrupts Mode */ - ARM_MODE_IRQ = 0x12 /* IRQ Standard Interrupts Mode */ - ARM_MODE_SVC = 0x13 /* Supervisor Interrupts Mode */ - ARM_MODE_ABORT = 0x17 /* Abort Processing memory Faults Mode */ - ARM_MODE_UNDEF = 0x1B /* Undefined Instructions Mode */ - ARM_MODE_SYS = 0x1F /* System Running in Priviledged Operating Mode */ - ARM_MODE_MASK = 0x1F - - I_BIT = 0x80 /* disable IRQ when I bit is set */ - F_BIT = 0x40 /* disable IRQ when I bit is set */ - -/* - * Register Base Address - */ - AIC_BASE = 0xFFFFF000 - AIC_EOICR_OFF = 0x130 - AIC_IDCR_OFF = 0x124 - - RSTC_MR = 0xFFFFFD08 - RSTC_KEY = 0xA5000000 - RSTC_URSTEN = 0x00000001 - - WDT_BASE = 0xFFFFFD40 - WDT_MR_OFF = 0x00000004 - WDT_WDDIS = 0x00008000 - - MC_BASE = 0xFFFFFF00 - MC_FMR_OFF = 0x00000060 - MC_FWS_1FWS = 0x00480100 - - .section .vectors,"ax" - .code 32 - -/****************************************************************************/ -/* Vector table and reset entry */ -/****************************************************************************/ -_vectors: - ldr pc, ResetAddr /* Reset */ - ldr pc, UndefAddr /* Undefined instruction */ - ldr pc, SWIAddr /* Software interrupt */ - ldr pc, PAbortAddr /* Prefetch abort */ - ldr pc, DAbortAddr /* Data abort */ - ldr pc, ReservedAddr /* Reserved */ - ldr pc, IRQAddr /* IRQ interrupt */ - ldr pc, FIQAddr /* FIQ interrupt */ - - -ResetAddr: .word ResetHandler -UndefAddr: .word UndefHandler -SWIAddr: .word SWIHandler -PAbortAddr: .word PAbortHandler -DAbortAddr: .word DAbortHandler -ReservedAddr: .word 0 -IRQAddr: .word IRQHandler -FIQAddr: .word FIQHandler - - .ltorg - - .section .init, "ax" - .code 32 - - .global ResetHandler - .global ExitFunction - .extern main -/****************************************************************************/ -/* Reset handler */ -/****************************************************************************/ -ResetHandler: - /* - * The watchdog is enabled after processor reset. Disable it. - */ - ldr r1, =WDT_BASE - ldr r0, =WDT_WDDIS - str r0, [r1, #WDT_MR_OFF] - - - /* - * Enable user reset: assertion length programmed to 1ms - */ - ldr r0, =(RSTC_KEY | RSTC_URSTEN | (4 << 8)) - ldr r1, =RSTC_MR - str r0, [r1, #0] - - - /* - * Use 2 cycles for flash access. - */ - ldr r1, =MC_BASE - ldr r0, =MC_FWS_1FWS - str r0, [r1, #MC_FMR_OFF] - - - /* - * Disable all interrupts. Useful for debugging w/o target reset. - */ - ldr r1, =AIC_BASE - mvn r0, #0 - str r0, [r1, #AIC_EOICR_OFF] - str r0, [r1, #AIC_IDCR_OFF] - - - /* - * Setup a stack for each mode - */ - msr CPSR_c, #ARM_MODE_UNDEF | I_BIT | F_BIT /* Undefined Instruction Mode */ - ldr sp, =__stack_und_end - - msr CPSR_c, #ARM_MODE_ABORT | I_BIT | F_BIT /* Abort Mode */ - ldr sp, =__stack_abt_end - - msr CPSR_c, #ARM_MODE_FIQ | I_BIT | F_BIT /* FIQ Mode */ - ldr sp, =__stack_fiq_end - - msr CPSR_c, #ARM_MODE_IRQ | I_BIT | F_BIT /* IRQ Mode */ - ldr sp, =__stack_irq_end - - msr CPSR_c, #ARM_MODE_SVC | I_BIT | F_BIT /* Supervisor Mode */ - ldr sp, =__stack_svc_end - - - /* - * Clear .bss section - */ - ldr r1, =__bss_start - ldr r2, =__bss_end - ldr r3, =0 -bss_clear_loop: - cmp r1, r2 - strne r3, [r1], #+4 - bne bss_clear_loop - - - /* - * Jump to main - */ - mrs r0, cpsr - bic r0, r0, #I_BIT | F_BIT /* Enable FIQ and IRQ interrupt */ - msr cpsr, r0 - - mov r0, #0 /* No arguments */ - mov r1, #0 /* No arguments */ - ldr r2, =main - mov lr, pc - bx r2 /* And jump... */ - -ExitFunction: - nop - nop - nop - b ExitFunction - - -/****************************************************************************/ -/* Default interrupt handler */ -/****************************************************************************/ - -UndefHandler: - b UndefHandler - -SWIHandler: - b SWIHandler - -PAbortHandler: - b PAbortHandler - -DAbortHandler: - b DAbortHandler - -IRQHandler: - b IRQHandler - -FIQHandler: - b FIQHandler - - .weak ExitFunction - .weak UndefHandler, PAbortHandler, DAbortHandler - .weak IRQHandler, FIQHandler - - .ltorg -/*** EOF ***/ diff --git a/contrib/loaders/flash/at91sam7x/dcc.c b/contrib/loaders/flash/at91sam7x/dcc.c deleted file mode 100644 index 6ab2417b2..000000000 --- a/contrib/loaders/flash/at91sam7x/dcc.c +++ /dev/null @@ -1,51 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Pavel Chromy * - * chromy@asix.cz * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - ***************************************************************************/ -#include "dcc.h" - - -/* debug channel read (debugger->MCU) */ -uint32 dcc_rd(void) -{ - volatile uint32 dcc_reg; - - do { - asm volatile ("mrc p14, 0, %0, C0, C0" : "=r" (dcc_reg) :); - } while ((dcc_reg&1) == 0); - - asm volatile ("mrc p14, 0, %0, C1, C0" : "=r" (dcc_reg) :); - return dcc_reg; -} - - -/* debug channel write (MCU->debugger) */ -int dcc_wr(uint32 data) -{ - volatile uint32 dcc_reg; - - do { - asm volatile ("mrc p14, 0, %0, C0, C0" : "=r" (dcc_reg) :); - /* operation controled by master, cancel operation - upon reception of data for immediate response */ - if (dcc_reg&1) return -1; - } while (dcc_reg&2); - - asm volatile ("mcr p14, 0, %0, C1, C0" : : "r" (data)); - return 0; -} diff --git a/contrib/loaders/flash/at91sam7x/dcc.h b/contrib/loaders/flash/at91sam7x/dcc.h deleted file mode 100644 index a3c13938b..000000000 --- a/contrib/loaders/flash/at91sam7x/dcc.h +++ /dev/null @@ -1,31 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Pavel Chromy * - * chromy@asix.cz * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - ***************************************************************************/ -#ifndef dccH -#define dccH - -#include "platform.h" - -/* debug channel read (debugger->MCU) */ -uint32 dcc_rd(void); - -/* debug channel write (MCU->debugger) */ -int dcc_wr(uint32 data); - -#endif diff --git a/contrib/loaders/flash/at91sam7x/main.c b/contrib/loaders/flash/at91sam7x/main.c deleted file mode 100644 index c4b4dcf2f..000000000 --- a/contrib/loaders/flash/at91sam7x/main.c +++ /dev/null @@ -1,107 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Pavel Chromy * - * chromy@asix.cz * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - ***************************************************************************/ -#include "platform.h" - -#include -#include "dcc.h" -#include "samflash.h" - - -#define BUFSIZE 1024 /* words, i.e. 4 KiB */ -uint32 buffer[1024]; - -void cmd_flash(uint32 cmd) -{ - unsigned int len; - uint32 adr; - uint32 chksum; - unsigned int bi; /* buffer index */ - unsigned int bi_start; /* receive start mark */ - unsigned int bi_end; /* receive end mark */ - unsigned int ofs; - int pagenum; - int result; - - adr = dcc_rd(); - len = cmd&0xffff; - ofs = adr%flash_page_size; - bi_start = ofs/4; - bi_end = (ofs + len + 3)/4; - - if (bi_end > BUFSIZE) { - dcc_wr(OCL_BUFF_OVER); - return; - } - - chksum = OCL_CHKS_INIT; - for (bi = 0; bi < bi_end; bi++) chksum^=buffer[bi]=dcc_rd(); - - if (dcc_rd() != chksum) { - dcc_wr(OCL_CHKS_FAIL); - return; - } - - /* fill in unused positions with unprogrammed values */ - for (bi = 0; bi < bi_start; bi++) buffer[bi]=0xffffffff; - for (bi = bi_end; bi%flash_page_size; bi++) buffer[bi]=0xffffffff; - - result = 0; - pagenum = adr/flash_page_size; - for (bi = 0; bi < bi_end; bi += flash_page_size/4) { - result = flash_page_program(buffer + bi, pagenum++); - if (result) break; - } - - /* verify written data */ - if (!result) result = flash_verify(adr, len, ((uint8 *)buffer) + ofs); - - dcc_wr(OCL_CMD_DONE | result); -} - - -int main (void) -{ - uint32 cmd; - - for (;;) { - cmd = dcc_rd(); - switch (cmd&OCL_CMD_MASK) { - case OCL_PROBE: - dcc_wr(OCL_CMD_DONE | flash_init()); - dcc_wr(0x100000); /* base */ - dcc_wr(flash_page_count*flash_page_size); /* size */ - dcc_wr(1); /* num_sectors */ - dcc_wr(4096 | ((unsigned long) flash_page_size << 16)); /* buflen and bufalign */ - break; - case OCL_ERASE_ALL: - dcc_wr(OCL_CMD_DONE | flash_erase_all()); - break; - case OCL_FLASH_BLOCK: - cmd_flash(cmd); - break; - default: - /* unknown command */ - dcc_wr(OCL_CMD_ERR); - break; - } - } - - return(0); /* we shall never get here, just to supress compiler warning */ -} diff --git a/contrib/loaders/flash/at91sam7x/makefile b/contrib/loaders/flash/at91sam7x/makefile deleted file mode 100644 index c3eaf126b..000000000 --- a/contrib/loaders/flash/at91sam7x/makefile +++ /dev/null @@ -1,130 +0,0 @@ -############################################################################################## -# Start of default section -# - -TRGT = arm-elf- -CC = $(TRGT)gcc -CP = $(TRGT)objcopy -AS = $(TRGT)gcc -x assembler-with-cpp -HEX = $(CP) -O ihex -BIN = $(CP) -O binary -OBJDUMP = $(TRGT)objdump - -MCU = arm7tdmi - -# List all default C defines here, like -D_DEBUG=1 -DDEFS = - -# List all default ASM defines here, like -D_DEBUG=1 -DADEFS = - -# List all default directories to look for include files here -DINCDIR = - -# List the default directory to look for the libraries here -DLIBDIR = - -# List all default libraries here -DLIBS = - -# -# End of default section -############################################################################################## - -############################################################################################## -# Start of user section -# - -# Define project name here -PROJECT = at91sam7x_ocl - -# Define linker script file here -LDSCRIPT= at91sam7x_ram.ld - -# List all user C define here, like -D_DEBUG=1 -UDEFS = - -# Define ASM defines here -UADEFS = - -# List C source files here -SRC = main.c dcc.c samflash.c - -# List ASM source files here -ASRC = crt.s - -# List all user directories here -UINCDIR = - -# List the user directory to look for the libraries here -ULIBDIR = - -# List all user libraries here -ULIBS = - -# Define optimisation level here -OPT = -O2 - -# -# End of user defines -############################################################################################## - - -INCDIR = $(patsubst %,-I%,$(DINCDIR) $(UINCDIR)) -LIBDIR = $(patsubst %,-L%,$(DLIBDIR) $(ULIBDIR)) -DEFS = $(DDEFS) $(UDEFS) -ADEFS = $(DADEFS) $(UADEFS) -OBJS = $(ASRC:.s=.o) $(SRC:.c=.o) -LIBS = $(DLIBS) $(ULIBS) -MCFLAGS = -mcpu=$(MCU) - -ASFLAGS = $(MCFLAGS) -g -gdwarf-2 -Wa,-amhls=$(<:.s=.lst) $(ADEFS) -CPFLAGS = $(MCFLAGS) $(OPT) -gdwarf-2 -mthumb-interwork -fomit-frame-pointer -Wall -Wstrict-prototypes -fverbose-asm -Wa,-ahlms=$(<:.c=.lst) $(DEFS) -LDFLAGS = $(MCFLAGS) -nostartfiles -T$(LDSCRIPT) -Wl,-Map=$(PROJECT).map,--cref,--no-warn-mismatch $(LIBDIR) - -# Generate dependency information -#CPFLAGS += -MD -MP -MF .dep/$(@F).d - -# -# makefile rules -# - -all: $(OBJS) $(PROJECT).elf $(PROJECT).hex $(PROJECT).bin $(PROJECT).lst - -%o : %c - $(CC) -c $(CPFLAGS) -I . $(INCDIR) $< -o $@ - -%o : %s - $(AS) -c $(ASFLAGS) $< -o $@ - -%elf: $(OBJS) - $(CC) $(OBJS) $(LDFLAGS) $(LIBS) -o $@ - -%hex: %elf - $(HEX) $< $@ - -%bin: %elf - $(BIN) $< $@ - -%.lst: %.elf - $(OBJDUMP) -h -S $< > $@ - -clean: - -rm -f $(OBJS) - -rm -f $(PROJECT).elf - -rm -f $(PROJECT).map - -rm -f $(PROJECT).hex - -rm -f $(PROJECT).bin - -rm -f $(PROJECT).lst - -rm -f $(SRC:.c=.c.bak) - -rm -f $(SRC:.c=.lst) - -rm -f $(ASRC:.s=.s.bak) - -rm -f $(ASRC:.s=.lst) - -rm -fR .dep - -# -# Include the dependency files, should be the last of the makefile -# -#-include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*) - -# *** EOF *** \ No newline at end of file diff --git a/contrib/loaders/flash/at91sam7x/ocl.h b/contrib/loaders/flash/at91sam7x/ocl.h deleted file mode 100644 index 1fe459669..000000000 --- a/contrib/loaders/flash/at91sam7x/ocl.h +++ /dev/null @@ -1,40 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Pavel Chromy * - * chromy@asix.cz * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - ***************************************************************************/ -#ifndef OCL_H -#define OCL_H - -/* command/response mask */ -#define OCL_CMD_MASK 0xFFFF0000L - -/* commads */ -#define OCL_FLASH_BLOCK 0x0CFB0000L -#define OCL_ERASE_BLOCK 0x0CEB0000L -#define OCL_ERASE_ALL 0x0CEA0000L -#define OCL_PROBE 0x0CBE0000L - -/* responses */ -#define OCL_CMD_DONE 0x0ACD0000L -#define OCL_CMD_ERR 0x0ACE0000L -#define OCL_CHKS_FAIL 0x0ACF0000L -#define OCL_BUFF_OVER 0x0AB00000L - -#define OCL_CHKS_INIT 0xC100CD0CL - -#endif /* OCL_H */ diff --git a/contrib/loaders/flash/at91sam7x/platform.h b/contrib/loaders/flash/at91sam7x/platform.h deleted file mode 100644 index 2b26e4bd5..000000000 --- a/contrib/loaders/flash/at91sam7x/platform.h +++ /dev/null @@ -1,46 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Pavel Chromy * - * chromy@asix.cz * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - ***************************************************************************/ -#ifndef platformH -#define platformH - -#include "samregs.h" - - -#define outb(_reg, _val) (*((volatile unsigned char *)(_reg)) = (_val)) -#define outw(_reg, _val) (*((volatile unsigned short *)(_reg)) = (_val)) -#define outr(_reg, _val) (*((volatile unsigned int *)(_reg)) = (_val)) - -#define inb(_reg) (*((volatile unsigned char *)(_reg))) -#define inw(_reg) (*((volatile unsigned short *)(_reg))) -#define inr(_reg) (*((volatile unsigned int *)(_reg))) - -#define _BV(bit) (1 << (bit)) - - -typedef signed char int8; -typedef unsigned char uint8; - -typedef signed short int16; -typedef unsigned short uint16; - -typedef signed int int32; -typedef unsigned int uint32; - -#endif diff --git a/contrib/loaders/flash/at91sam7x/samflash.c b/contrib/loaders/flash/at91sam7x/samflash.c deleted file mode 100644 index 49c84c812..000000000 --- a/contrib/loaders/flash/at91sam7x/samflash.c +++ /dev/null @@ -1,196 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Pavel Chromy * - * chromy@asix.cz * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - ***************************************************************************/ -#include "samflash.h" - - -unsigned int flash_page_count = 1024; -unsigned int flash_page_size = 256; - -/* pages per lock bit */ -unsigned int flash_lock_pages = 1024/16; - - -/* detect chip and set loader parameters */ -int flash_init(void) -{ - unsigned int nvpsiz; - - nvpsiz = (inr(DBGU_CIDR) >> 8)&0xf; - - switch (nvpsiz) { - case 3: - /* AT91SAM7x32 */ - flash_page_count = 256; - flash_page_size = 128; - flash_lock_pages = 256/8; - break; - case 5: - /* AT91SAM7x64 */ - flash_page_count = 512; - flash_page_size = 128; - flash_lock_pages = 512/16; - break; - case 7: - /* AT91SAM7x128*/ - flash_page_count = 512; - flash_page_size = 256; - flash_lock_pages = 512/8; - break; - case 9: - /* AT91SAM7x256 */ - flash_page_count = 1024; - flash_page_size = 256; - flash_lock_pages = 1024/16; - break; - case 10: - /* AT91SAM7x512 */ - flash_page_count = 2048; - flash_page_size = 256; - flash_lock_pages = 2048/32; - break; - default: - return FLASH_STAT_INITE; - } - return FLASH_STAT_OK; -} - - -/* program single flash page */ -int flash_page_program(uint32 *data, int page_num) -{ - int i; - int efc_ofs; - - uint32 *flash_ptr; - uint32 *data_ptr; - - /* select proper controller */ - if (page_num >= 1024) efc_ofs = 0x10; - else efc_ofs = 0; - - /* wait until FLASH is ready, just for sure */ - while ((inr(MC_FSR + efc_ofs)&MC_FRDY) == 0); - - /* calculate page address, only lower 8 bits are used to address the latch, - but the upper part of address is needed for writing to proper EFC */ - flash_ptr = (uint32 *)(FLASH_AREA_ADDR + (page_num*flash_page_size)); - data_ptr = data; - - /* copy data to latch */ - for (i = flash_page_size/4; i; i--) { - /* we do not use memcpy to be sure that only 32 bit access is used */ - *(flash_ptr++)=*(data_ptr++); - } - - /* page number and page write command to FCR */ - outr(MC_FCR + efc_ofs, ((page_num&0x3ff) << 8) | MC_KEY | MC_FCMD_WP); - - /* wait until it's done */ - while ((inr(MC_FSR + efc_ofs)&MC_FRDY) == 0); - - /* check for errors */ - if ((inr(MC_FSR + efc_ofs)&MC_PROGE)) return FLASH_STAT_PROGE; - if ((inr(MC_FSR + efc_ofs)&MC_LOCKE)) return FLASH_STAT_LOCKE; - -#if 0 - /* verify written data */ - flash_ptr = (uint32 *)(FLASH_AREA_ADDR + (page_num*flash_page_size)); - data_ptr = data; - - for (i = flash_page_size/4; i; i--) { - if (*(flash_ptr++)!=*(data_ptr++)) return FLASH_STAT_VERIFE; - } -#endif - - return FLASH_STAT_OK; -} - - -int flash_erase_plane(int efc_ofs) -{ - unsigned int lockbits; - int page_num; - - page_num = 0; - lockbits = inr(MC_FSR + efc_ofs) >> 16; - while (lockbits) { - if (lockbits&1) { - - /* wait until FLASH is ready, just for sure */ - while ((inr(MC_FSR + efc_ofs)&MC_FRDY) == 0); - - outr(MC_FCR + efc_ofs, ((page_num&0x3ff) << 8) | 0x5a000004); - - /* wait until it's done */ - while ((inr(MC_FSR + efc_ofs)&MC_FRDY) == 0); - - /* check for errors */ - if ((inr(MC_FSR + efc_ofs)&MC_PROGE)) return FLASH_STAT_PROGE; - if ((inr(MC_FSR + efc_ofs)&MC_LOCKE)) return FLASH_STAT_LOCKE; - - } - if ((page_num += flash_lock_pages) > flash_page_count) break; - lockbits>>=1; - } - - /* wait until FLASH is ready, just for sure */ - while ((inr(MC_FSR + efc_ofs)&MC_FRDY) == 0); - - /* erase all command to FCR */ - outr(MC_FCR + efc_ofs, 0x5a000008); - - /* wait until it's done */ - while ((inr(MC_FSR + efc_ofs)&MC_FRDY) == 0); - - /* check for errors */ - if ((inr(MC_FSR + efc_ofs)&MC_PROGE)) return FLASH_STAT_PROGE; - if ((inr(MC_FSR + efc_ofs)&MC_LOCKE)) return FLASH_STAT_LOCKE; - - /* set no erase before programming */ - outr(MC_FMR + efc_ofs, inr(MC_FMR + efc_ofs) | 0x80); - - return FLASH_STAT_OK; -} - - -/* erase whole chip */ -int flash_erase_all(void) -{ - int result; - - if ((result = flash_erase_plane(0)) != FLASH_STAT_OK) return result; - - /* the second flash controller, if any */ - if (flash_page_count > 1024) result = flash_erase_plane(0x10); - - return result; -} - - -int flash_verify(uint32 adr, unsigned int len, uint8 *src) -{ - unsigned char *flash_ptr; - - flash_ptr = (uint8 *)FLASH_AREA_ADDR + adr; - for (;len; len--) { - if (*(flash_ptr++)!=*(src++)) return FLASH_STAT_VERIFE; - } - return FLASH_STAT_OK; -} diff --git a/contrib/loaders/flash/at91sam7x/samflash.h b/contrib/loaders/flash/at91sam7x/samflash.h deleted file mode 100644 index 1de02ae54..000000000 --- a/contrib/loaders/flash/at91sam7x/samflash.h +++ /dev/null @@ -1,48 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Pavel Chromy * - * chromy@asix.cz * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - ***************************************************************************/ -#ifndef samflashH -#define samflashH - -#include "platform.h" - -#define FLASH_AREA_ADDR 0x100000 - -#define FLASH_STAT_OK 0 -#define FLASH_STAT_PROGE 1 -#define FLASH_STAT_LOCKE 2 -#define FLASH_STAT_VERIFE 3 -#define FLASH_STAT_INITE 4 - -extern unsigned int flash_page_count; -extern unsigned int flash_page_size; /* words */ - -/* detect chip and set loader parameters */ -int flash_init(void); - -/* program single flash page */ -int flash_page_program(uint32 *data, int page_num); - -/* erase whole chip */ -int flash_erase_all(void); - -/* verify written data */ -int flash_verify(uint32 adr, unsigned int len, uint8 *src); - -#endif diff --git a/contrib/loaders/flash/at91sam7x/samregs.h b/contrib/loaders/flash/at91sam7x/samregs.h deleted file mode 100644 index b206fd28e..000000000 --- a/contrib/loaders/flash/at91sam7x/samregs.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (C) 2005-2006 by egnite Software GmbH. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY EGNITE SOFTWARE GMBH AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL EGNITE - * SOFTWARE GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF - * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * For additional information see http://www.ethernut.de/ - */ - - -#ifndef samregsH -#define samregsH - - -/* - * Register definitions below copied from NutOS - */ - -#define DBGU_BASE 0xFFFFF200 /*!< \brief DBGU base address. */ - -#define DBGU_CIDR_OFF 0x00000040 /*!< \brief DBGU chip ID register offset. */ -#define DBGU_CIDR (DBGU_BASE + DBGU_CIDR_OFF) /*!< \brief DBGU chip ID register. */ - - -#define MC_BASE 0xFFFFFF00 /*!< \brief Memory controller base. */ - -#define MC_FMR_OFF 0x00000060 /*!< \brief MC flash mode register offset. */ -#define MC_FMR (MC_BASE + MC_FMR_OFF) /*!< \brief MC flash mode register address. */ -#define MC_FRDY 0x00000001 /*!< \brief Flash ready. */ -#define MC_LOCKE 0x00000004 /*!< \brief Lock error. */ -#define MC_PROGE 0x00000008 /*!< \brief Programming error. */ -#define MC_NEBP 0x00000080 /*!< \brief No erase before programming. */ -#define MC_FWS_MASK 0x00000300 /*!< \brief Flash wait state mask. */ -#define MC_FWS_1R2W 0x00000000 /*!< \brief 1 cycle for read, 2 for write operations. */ -#define MC_FWS_2R3W 0x00000100 /*!< \brief 2 cycles for read, 3 for write operations. */ -#define MC_FWS_3R4W 0x00000200 /*!< \brief 3 cycles for read, 4 for write operations. */ -#define MC_FWS_4R4W 0x00000300 /*!< \brief 4 cycles for read and write operations. */ -#define MC_FMCN_MASK 0x00FF0000 /*!< \brief Flash microsecond cycle number mask. */ - -#define MC_FCR_OFF 0x00000064 /*!< \brief MC flash command register offset. */ -#define MC_FCR (MC_BASE + MC_FCR_OFF) /*!< \brief MC flash command register address. */ -#define MC_FCMD_MASK 0x0000000F /*!< \brief Flash command mask. */ -#define MC_FCMD_NOP 0x00000000 /*!< \brief No command. */ -#define MC_FCMD_WP 0x00000001 /*!< \brief Write page. */ -#define MC_FCMD_SLB 0x00000002 /*!< \brief Set lock bit. */ -#define MC_FCMD_WPL 0x00000003 /*!< \brief Write page and lock. */ -#define MC_FCMD_CLB 0x00000004 /*!< \brief Clear lock bit. */ -#define MC_FCMD_EA 0x00000008 /*!< \brief Erase all. */ -#define MC_FCMD_SGPB 0x0000000B /*!< \brief Set general purpose NVM bit. */ -#define MC_FCMD_CGPB 0x0000000D /*!< \brief Clear general purpose NVM bit. */ -#define MC_FCMD_SSB 0x0000000F /*!< \brief Set security bit. */ -#define MC_PAGEN_MASK 0x0003FF00 /*!< \brief Page number mask. */ -#define MC_KEY 0x5A000000 /*!< \brief Writing protect key. */ - -#define MC_FSR_OFF 0x00000068 /*!< \brief MC flash status register offset. */ -#define MC_FSR (MC_BASE + MC_FSR_OFF) /*!< \brief MC flash status register address. */ -#define MC_SECURITY 0x00000010 /*!< \brief Security bit status. */ - - -#endif diff --git a/contrib/loaders/flash/cortex-m0.S b/contrib/loaders/flash/cortex-m0.S deleted file mode 100644 index b4416e783..000000000 --- a/contrib/loaders/flash/cortex-m0.S +++ /dev/null @@ -1,72 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2014 by Angus Gratton * - * Derived from stm32f1x.S: - * Copyright (C) 2011 by Andreas Fritiofson * - * andreas.fritiofson@gmail.com * - * Copyright (C) 2013 by Roman Dmitrienko * - * me@iamroman.org * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - .text - .syntax unified - .cpu cortex-m0 - .thumb - .thumb_func - -/* Written for NRF51822 (src/flash/nor/nrf51.c) however the NRF NVMC is - * very generic (CPU blocks during flash writes), so this is actually - * just a generic word-oriented copy routine for Cortex-M0 (also - * suitable for Cortex-M0+/M3/M4.) - * - * To assemble: - * arm-none-eabi-gcc -c cortex-m0.S - * - * To disassemble: - * arm-none-eabi-objdump -o cortex-m0.o - * - * Thanks to Jens Bauer for providing advice on some of the tweaks. - */ - - /* Params: - * r0 - byte count (in) - * r1 - workarea start - * r2 - workarea end - * r3 - target address - * Clobbered: - * r4 - rp - * r5 - wp, tmp - */ - -wait_fifo: - ldr r5, [r1, #0] /* read wp */ - cmp r5, #0 /* abort if wp == 0 */ - beq exit - ldr r4, [r1, #4] /* read rp */ - cmp r4, r5 /* wait until rp != wp */ - beq wait_fifo - - ldmia r4!, {r5} /* "*target_address++ = *rp++" */ - stmia r3!, {r5} - - cmp r4, r2 /* wrap rp at end of work area buffer */ - bcc no_wrap - mov r4, r1 - adds r4, #8 /* skip rp,wp at start of work area */ -no_wrap: - str r4, [r1, #4] /* write back rp */ - subs r0, #4 /* decrement byte count */ - bne wait_fifo /* loop if not done */ -exit: - bkpt #0 diff --git a/contrib/loaders/flash/efm32.S b/contrib/loaders/flash/efm32.S deleted file mode 100644 index 25d63010a..000000000 --- a/contrib/loaders/flash/efm32.S +++ /dev/null @@ -1,114 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2011 by Andreas Fritiofson * - * andreas.fritiofson@gmail.com * - * Copyright (C) 2013 by Roman Dmitrienko * - * me@iamroman.org * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - ***************************************************************************/ - - .text - .syntax unified - .cpu cortex-m0 - .thumb - .thumb_func - - /* Params: - * r0 - flash base (in), status (out) - * r1 - count (word-32bit) - * r2 - workarea start - * r3 - workarea end - * r4 - target address - * Clobbered: - * r5 - rp - * r6 - wp, tmp - * r7 - tmp - */ - -/* offsets of registers from flash reg base */ -#define EFM32_MSC_WRITECTRL_OFFSET 0x008 -#define EFM32_MSC_WRITECMD_OFFSET 0x00c -#define EFM32_MSC_ADDRB_OFFSET 0x010 -#define EFM32_MSC_WDATA_OFFSET 0x018 -#define EFM32_MSC_STATUS_OFFSET 0x01c -#define EFM32_MSC_LOCK_OFFSET 0x03c - - /* unlock MSC */ - ldr r6, =#0x1b71 - str r6, [r0, #EFM32_MSC_LOCK_OFFSET] - /* set WREN to 1 */ - movs r6, #1 - str r6, [r0, #EFM32_MSC_WRITECTRL_OFFSET] - -wait_fifo: - ldr r6, [r2, #0] /* read wp */ - cmp r6, #0 /* abort if wp == 0 */ - beq exit - ldr r5, [r2, #4] /* read rp */ - cmp r5, r6 /* wait until rp != wp */ - beq wait_fifo - - /* store address in MSC_ADDRB */ - str r4, [r0, #EFM32_MSC_ADDRB_OFFSET] - /* set LADDRIM bit */ - movs r6, #1 - str r6, [r0, #EFM32_MSC_WRITECMD_OFFSET] - /* check status for INVADDR and/or LOCKED */ - ldr r6, [r0, #EFM32_MSC_STATUS_OFFSET] - movs r7, #6 - tst r6, r7 - bne error - - /* wait for WDATAREADY */ -wait_wdataready: - ldr r6, [r0, #EFM32_MSC_STATUS_OFFSET] - movs r7, #8 - tst r6, r7 - beq wait_wdataready - - /* load data to WDATA */ - ldr r6, [r5] - str r6, [r0, #EFM32_MSC_WDATA_OFFSET] - /* set WRITEONCE bit */ - movs r6, #8 - str r6, [r0, #EFM32_MSC_WRITECMD_OFFSET] - - adds r5, #4 /* rp++ */ - adds r4, #4 /* target_address++ */ - - /* wait until BUSY flag is reset */ -busy: - ldr r6, [r0, #EFM32_MSC_STATUS_OFFSET] - movs r7, #1 - tst r6, r7 - bne busy - - cmp r5, r3 /* wrap rp at end of buffer */ - bcc no_wrap - mov r5, r2 - adds r5, #8 -no_wrap: - str r5, [r2, #4] /* store rp */ - subs r1, r1, #1 /* decrement word count */ - cmp r1, #0 - beq exit /* loop if not done */ - b wait_fifo -error: - movs r0, #0 - str r0, [r2, #4] /* set rp = 0 on error */ -exit: - mov r0, r6 /* return status in r0 */ - bkpt #0 diff --git a/contrib/loaders/flash/fm4/Makefile b/contrib/loaders/flash/fm4/Makefile deleted file mode 100644 index 207b9d0fa..000000000 --- a/contrib/loaders/flash/fm4/Makefile +++ /dev/null @@ -1,32 +0,0 @@ -BIN2C = ../../../../src/helper/bin2char.sh - -CROSS_COMPILE ?= arm-none-eabi- - -CC=$(CROSS_COMPILE)gcc -OBJCOPY=$(CROSS_COMPILE)objcopy -OBJDUMP=$(CROSS_COMPILE)objdump - -CFLAGS = -static -nostartfiles -mlittle-endian -Wa,-EL - -all: erase.inc write.inc - -.PHONY: clean - -.INTERMEDIATE: erase.elf write.elf - -erase.elf write.elf: fm4.h - -%.elf: %.S - $(CC) $(CFLAGS) $< -o $@ - -%.lst: %.elf - $(OBJDUMP) -S $< > $@ - -%.bin: %.elf - $(OBJCOPY) -Obinary $< $@ - -%.inc: %.bin - $(BIN2C) < $< > $@ - -clean: - -rm -f *.elf *.lst *.bin *.inc diff --git a/contrib/loaders/flash/fm4/erase.S b/contrib/loaders/flash/fm4/erase.S deleted file mode 100644 index 6fdf81dc2..000000000 --- a/contrib/loaders/flash/fm4/erase.S +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Spansion FM4 flash sector erase algorithm - * - * Copyright (c) 2015 Andreas Färber - * - * Based on S6E2CC_MN709-00007 for S6E2CC/C5/C4/C3/C2/C1 series - */ - -#include "fm4.h" - -#define RESULT_OKAY 0 -#define RESULT_NONE 1 -#define RESULT_TIMEOUT 2 - - .macro busy_wait, res, addr, tmp1, tmp2, tmp3 - - ldrb \tmp1, [\addr] /* ignore */ -1001: - ldrb \tmp1, [\addr] - ldrb \tmp2, [\addr] - - and \tmp3, \tmp1, #FLASH_TOGG - and \tmp2, \tmp2, #FLASH_TOGG - cmp \tmp3, \tmp2 - beq 1010f - - and \tmp2, \tmp1, #FLASH_TLOV - cmp \tmp2, #0 - beq 1001b - - ldrb \tmp1, [\addr] - ldrb \tmp2, [\addr] - - and \tmp3, \tmp1, #FLASH_TOGG - and \tmp2, \tmp2, #FLASH_TOGG - cmp \tmp3, \tmp2 - beq 1010f - - mov \res, #RESULT_TIMEOUT - bkpt #0 -1010: - mov \res, #RESULT_OKAY - - .endm - - - .macro erase, cmdseqaddr1, cmdseqaddr2, sa, res, tmp1, tmp2, tmp3 - - mov \res, #RESULT_NONE - - mov \tmp1, #0xAA - strh \tmp1, [\cmdseqaddr1] - mov \tmp2, #0x55 - strh \tmp2, [\cmdseqaddr2] - mov \tmp3, #0x80 - strh \tmp3, [\cmdseqaddr1] - strh \tmp1, [\cmdseqaddr1] - strh \tmp2, [\cmdseqaddr2] - mov \tmp3, #0x30 - strh \tmp3, [\sa] - - busy_wait \res, \sa, \tmp1, \tmp2, \tmp3 - - .endm - - - /* r0 = 0xAA8 - * r1 = 0x554 - * r2 = SA - * r3 = result - */ -erase: - erase r0, r1, r2, r3, r4, r5, r6 - - bkpt #0 - -data: diff --git a/contrib/loaders/flash/fm4/erase.inc b/contrib/loaders/flash/fm4/erase.inc deleted file mode 100644 index 9f380674b..000000000 --- a/contrib/loaders/flash/fm4/erase.inc +++ /dev/null @@ -1,7 +0,0 @@ -/* Autogenerated with ../../../../src/helper/bin2char.sh */ -0x4f,0xf0,0x01,0x03,0x4f,0xf0,0xaa,0x04,0x04,0x80,0x4f,0xf0,0x55,0x05,0x0d,0x80, -0x4f,0xf0,0x80,0x06,0x06,0x80,0x04,0x80,0x0d,0x80,0x4f,0xf0,0x30,0x06,0x16,0x80, -0x14,0x78,0x14,0x78,0x15,0x78,0x04,0xf0,0x40,0x06,0x05,0xf0,0x40,0x05,0xae,0x42, -0x0e,0xd0,0x04,0xf0,0x20,0x05,0x00,0x2d,0xf3,0xd0,0x14,0x78,0x15,0x78,0x04,0xf0, -0x40,0x06,0x05,0xf0,0x40,0x05,0xae,0x42,0x02,0xd0,0x4f,0xf0,0x02,0x03,0x00,0xbe, -0x4f,0xf0,0x00,0x03,0x00,0xbe, diff --git a/contrib/loaders/flash/fm4/fm4.h b/contrib/loaders/flash/fm4/fm4.h deleted file mode 100644 index 603aac876..000000000 --- a/contrib/loaders/flash/fm4/fm4.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Spansion FM4 flash macros - * - * Copyright (c) 2015 Andreas Färber - * - * Based on S6E2CC_MN709-00007 for S6E2CC/C5/C4/C3/C2/C1 series - */ - - .text - .syntax unified - .cpu cortex-m4 - .thumb - .thumb_func - - -#define FLASH_DPOL (1 << 7) -#define FLASH_TOGG (1 << 6) -#define FLASH_TLOV (1 << 5) -#define FLASH_TOGG2 (1 << 2) diff --git a/contrib/loaders/flash/fm4/write.S b/contrib/loaders/flash/fm4/write.S deleted file mode 100644 index a8d01cde2..000000000 --- a/contrib/loaders/flash/fm4/write.S +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Spansion FM4 flash write algorithm - * - * Copyright (c) 2015 Andreas Färber - * - * Based on S6E2CC_MN709-00007 for S6E2CC/C5/C4/C3/C2/C1 series - */ - -#include "fm4.h" - -#define RESULT_OKAY 0 -#define RESULT_NONE 1 -#define RESULT_TIMEOUT 2 - - .macro busy_wait, res, addr, data, tmp1, tmp2, tmp3 - - ldrb \tmp1, [\addr] /* ignore */ - and \tmp2, \data, #FLASH_DPOL -1001: - ldrb \tmp1, [\addr] - and \tmp3, \tmp1, #FLASH_DPOL - cmp \tmp3, \tmp2 - beq 1010f - - and \tmp3, \tmp1, #FLASH_TLOV - cmp \tmp3, #0 - beq 1001b - - ldrb \tmp1, [\addr] - and \tmp3, \tmp1, #FLASH_DPOL - cmp \tmp3, \tmp2 - beq 1010f - - mov \res, #RESULT_TIMEOUT - bkpt #0 -1010: - .endm - - - .macro write_one, res, cmdseqaddr1, cmdseqaddr2, pa, pd, tmp1, tmp2, tmp3 - - mov \tmp1, #0xAA - strh \tmp1, [\cmdseqaddr1] - mov \tmp1, #0x55 - strh \tmp1, [\cmdseqaddr2] - mov \tmp1, #0xA0 - strh \tmp1, [\cmdseqaddr1] - strh \pd, [\pa] - - busy_wait \res, \pa, \pd, \tmp1, \tmp2, \tmp3 - - .endm - - - .macro write, cmdseqaddr1, cmdseqaddr2, dest, src, cnt, res, tmp1, tmp2, tmp3, tmp4 - - mov \res, #RESULT_NONE -2001: - cbz \cnt, 2010f - - ldrh \tmp1, [\src] - write_one \res, \cmdseqaddr1, \cmdseqaddr2, \dest, \tmp1, \tmp2, \tmp3, \tmp4 - - sub \cnt, \cnt, #1 - add \dest, \dest, #2 - add \src, \src, #2 - b 2001b -2010: - mov \res, #RESULT_OKAY - .endm - - - /* r0 = 0xAA8 - * r1 = 0x554 - * r2 = dest - * r3 = src - * r4 = cnt - * r5 = result - */ -write: - write r0, r1, r2, r3, r4, r5, r6, r7, r8, r9 - - bkpt #0 - -data: diff --git a/contrib/loaders/flash/fm4/write.inc b/contrib/loaders/flash/fm4/write.inc deleted file mode 100644 index 3d8472ba4..000000000 --- a/contrib/loaders/flash/fm4/write.inc +++ /dev/null @@ -1,7 +0,0 @@ -/* Autogenerated with ../../../../src/helper/bin2char.sh */ -0x4f,0xf0,0x01,0x05,0x34,0xb3,0x1e,0x88,0x4f,0xf0,0xaa,0x07,0x07,0x80,0x4f,0xf0, -0x55,0x07,0x0f,0x80,0x4f,0xf0,0xa0,0x07,0x07,0x80,0x16,0x80,0x17,0x78,0x06,0xf0, -0x80,0x08,0x17,0x78,0x07,0xf0,0x80,0x09,0xc1,0x45,0x0c,0xd0,0x07,0xf0,0x20,0x09, -0xb9,0xf1,0x00,0x0f,0xf5,0xd0,0x17,0x78,0x07,0xf0,0x80,0x09,0xc1,0x45,0x02,0xd0, -0x4f,0xf0,0x02,0x05,0x00,0xbe,0xa4,0xf1,0x01,0x04,0x02,0xf1,0x02,0x02,0x03,0xf1, -0x02,0x03,0xd7,0xe7,0x4f,0xf0,0x00,0x05,0x00,0xbe, diff --git a/contrib/loaders/flash/fpga/xilinx_bscan_spi.py b/contrib/loaders/flash/fpga/xilinx_bscan_spi.py deleted file mode 100755 index a107a6ac7..000000000 --- a/contrib/loaders/flash/fpga/xilinx_bscan_spi.py +++ /dev/null @@ -1,317 +0,0 @@ -#!/usr/bin/python3 -# -# Copyright (C) 2015 Robert Jordens -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# - -from migen.fhdl.std import * -from mibuild.generic_platform import * -from mibuild.xilinx import XilinxPlatform -from mibuild.xilinx.vivado import XilinxVivadoToolchain -from mibuild.xilinx.ise import XilinxISEToolchain - - -""" -This migen script produces proxy bitstreams to allow programming SPI flashes -behind FPGAs. JTAG signalling is connected directly to SPI signalling. CS_N is -asserted when the JTAG IR contains the USER1 instruction and the state is -SHIFT-DR. - -Xilinx bscan cells sample TDO on falling TCK and forward it. -MISO requires sampling on rising CLK and leads to one cycle of latency. - -https://github.com/m-labs/migen -""" - - -class Spartan3(Module): - macro = "BSCAN_SPARTAN3" - - def __init__(self, platform): - self.clock_domains.cd_jtag = ClockDomain(reset_less=True) - spi = platform.request("spiflash") - shift = Signal() - tdo = Signal() - sel1 = Signal() - self.comb += [ - self.cd_jtag.clk.eq(spi.clk), - spi.cs_n.eq(~shift | ~sel1), - ] - self.sync.jtag += tdo.eq(spi.miso) - self.specials += Instance(self.macro, - o_DRCK1=spi.clk, o_SHIFT=shift, - o_TDI=spi.mosi, i_TDO1=tdo, i_TDO2=0, - o_SEL1=sel1) - - -class Spartan3A(Spartan3): - macro = "BSCAN_SPARTAN3A" - - -class Spartan6(Module): - def __init__(self, platform): - self.clock_domains.cd_jtag = ClockDomain(reset_less=True) - spi = platform.request("spiflash") - shift = Signal() - tdo = Signal() - sel = Signal() - self.comb += self.cd_jtag.clk.eq(spi.clk), spi.cs_n.eq(~shift | ~sel) - self.sync.jtag += tdo.eq(spi.miso) - self.specials += Instance("BSCAN_SPARTAN6", p_JTAG_CHAIN=1, - o_TCK=spi.clk, o_SHIFT=shift, o_SEL=sel, - o_TDI=spi.mosi, i_TDO=tdo) - - -class Series7(Module): - def __init__(self, platform): - self.clock_domains.cd_jtag = ClockDomain(reset_less=True) - spi = platform.request("spiflash") - clk = Signal() - shift = Signal() - tdo = Signal() - sel = Signal() - self.comb += self.cd_jtag.clk.eq(clk), spi.cs_n.eq(~shift | ~sel) - self.sync.jtag += tdo.eq(spi.miso) - self.specials += Instance("BSCANE2", p_JTAG_CHAIN=1, - o_SHIFT=shift, o_TCK=clk, o_SEL=sel, - o_TDI=spi.mosi, i_TDO=tdo) - self.specials += Instance("STARTUPE2", i_CLK=0, i_GSR=0, i_GTS=0, - i_KEYCLEARB=0, i_PACK=1, i_USRCCLKO=clk, - i_USRCCLKTS=0, i_USRDONEO=1, i_USRDONETS=1) - - -class XilinxBscanSpi(XilinxPlatform): - pinouts = { - # bitstreams are named by die, package does not matter, speed grade - # should not matter. - # cs_n, clk, mosi, miso, *pullups - "xc3s100e": ("cp132", - ["M2", "N12", "N2", "N8"], - "LVCMOS33", Spartan3), - "xc3s1200e": ("fg320", - ["U3", "U16", "T4", "N10"], - "LVCMOS33", Spartan3), - "xc3s1400a": ("fg484", - ["Y4", "AA20", "AB14", "AB20"], - "LVCMOS33", Spartan3A), - "xc3s1400an": ("fgg484", - ["Y4", "AA20", "AB14", "AB20"], - "LVCMOS33", Spartan3A), - "xc3s1600e": ("fg320", - ["U3", "U16", "T4", "N10"], - "LVCMOS33", Spartan3), - "xc3s200a": ("fg320", - ["V3", "U16", "T11", "V16"], - "LVCMOS33", Spartan3A), - "xc3s200an": ("ftg256", - ["T2", "R14", "P10", "T14"], - "LVCMOS33", Spartan3A), - "xc3s250e": ("cp132", - ["M2", "N12", "N2", "N8"], - "LVCMOS33", Spartan3), - "xc3s400a": ("fg320", - ["V3", "U16", "T11", "V16"], - "LVCMOS33", Spartan3A), - "xc3s400an": ("fgg400", - ["Y2", "Y19", "W12", "W18"], - "LVCMOS33", Spartan3A), - "xc3s500e": ("cp132", - ["M2", "N12", "N2", "N8"], - "LVCMOS33", Spartan3), - "xc3s50a": ("ft256", - ["T2", "R14", "P10", "T14"], - "LVCMOS33", Spartan3A), - "xc3s50an": ("ftg256", - ["T2", "R14", "P10", "T14"], - "LVCMOS33", Spartan3A), - "xc3s700a": ("fg400", - ["Y2", "Y19", "W12", "W18"], - "LVCMOS33", Spartan3A), - "xc3s700an": ("fgg484", - ["Y4", "AA20", "AB14", "AB20"], - "LVCMOS33", Spartan3A), - "xc3sd1800a": ("cs484", - ["U7", "V17", "V13", "W17"], - "LVCMOS33", Spartan3A), - "xc3sd3400a": ("cs484", - ["U7", "V17", "V13", "W17"], - "LVCMOS33", Spartan3A), - - "xc6slx100": ("csg484-2", - ["AB5", "W17", "AB17", "Y17", "V13", "W13"], - "LVCMOS33", Spartan6), - "xc6slx100t": ("csg484-2", - ["AB5", "W17", "AB17", "Y17", "V13", "W13"], - "LVCMOS33", Spartan6), - "xc6slx150": ("csg484-2", - ["AB5", "W17", "AB17", "Y17", "V13", "W13"], - "LVCMOS33", Spartan6), - "xc6slx150t": ("csg484-2", - ["AB5", "W17", "AB17", "Y17", "V13", "W13"], - "LVCMOS33", Spartan6), - "xc6slx16": ("cpg196-2", - ["P2", "N13", "P11", "N11", "N10", "P10"], - "LVCMOS33", Spartan6), - "xc6slx25": ("csg324-2", - ["V3", "R15", "T13", "R13", "T14", "V14"], - "LVCMOS33", Spartan6), - "xc6slx25t": ("csg324-2", - ["V3", "R15", "T13", "R13", "T14", "V14"], - "LVCMOS33", Spartan6), - "xc6slx45": ("csg324-2", - ["V3", "R15", "T13", "R13", "T14", "V14"], - "LVCMOS33", Spartan6), - "xc6slx45t": ("csg324-2", - ["V3", "R15", "T13", "R13", "T14", "V14"], - "LVCMOS33", Spartan6), - "xc6slx4": ("cpg196-2", - ["P2", "N13", "P11", "N11", "N10", "P10"], - "LVCMOS33", Spartan6), - "xc6slx4t": ("qg144-2", - ["P38", "P70", "P64", "P65", "P62", "P61"], - "LVCMOS33", Spartan6), - "xc6slx75": ("csg484-2", - ["AB5", "W17", "AB17", "Y17", "V13", "W13"], - "LVCMOS33", Spartan6), - "xc6slx75t": ("csg484-2", - ["AB5", "W17", "AB17", "Y17", "V13", "W13"], - "LVCMOS33", Spartan6), - "xc6slx9": ("cpg196-2", - ["P2", "N13", "P11", "N11", "N10", "P10"], - "LVCMOS33", Spartan6), - "xc6slx9t": ("qg144-2", - ["P38", "P70", "P64", "P65", "P62", "P61"], - "LVCMOS33", Spartan6), - - "xc7a100t": ("csg324-1", - ["L13", None, "K17", "K18", "L14", "M14"], - "LVCMOS25", Series7), - "xc7a15t": ("cpg236-1", - ["K19", None, "D18", "D19", "G18", "F18"], - "LVCMOS25", Series7), - "xc7a200t": ("fbg484-1", - ["T19", None, "P22", "R22", "P21", "R21"], - "LVCMOS25", Series7), - "xc7a35t": ("cpg236-1", - ["K19", None, "D18", "D19", "G18", "F18"], - "LVCMOS25", Series7), - "xc7a50t": ("cpg236-1", - ["K19", None, "D18", "D19", "G18", "F18"], - "LVCMOS25", Series7), - "xc7a75t": ("csg324-1", - ["L13", None, "K17", "K18", "L14", "M14"], - "LVCMOS25", Series7), - "xc7k160t": ("fbg484-1", - ["L16", None, "H18", "H19", "G18", "F19"], - "LVCMOS25", Series7), - "xc7k325t": ("fbg676-1", - ["C23", None, "B24", "A25", "B22", "A22"], - "LVCMOS25", Series7), - "xc7k355t": ("ffg901-1", - ["V26", None, "R30", "T30", "R28", "T28"], - "LVCMOS25", Series7), - "xc7k410t": ("fbg676-1", - ["C23", None, "B24", "A25", "B22", "A22"], - "LVCMOS25", Series7), - "xc7k420t": ("ffg1156-1", - ["V30", None, "AA33", "AA34", "Y33", "Y34"], - "LVCMOS25", Series7), - "xc7k480t": ("ffg1156-1", - ["V30", None, "AA33", "AA34", "Y33", "Y34"], - "LVCMOS25", Series7), - "xc7k70t": ("fbg484-1", - ["L16", None, "H18", "H19", "G18", "F19"], - "LVCMOS25", Series7), - "xc7v2000t": ("fhg1761-1", - ["AL36", None, "AM36", "AN36", "AJ36", "AJ37"], - "LVCMOS18", Series7), - "xc7v585t": ("ffg1157-1", - ["AL33", None, "AN33", "AN34", "AK34", "AL34"], - "LVCMOS18", Series7), - "xc7vh580t": ("flg1155-1", - ["AL28", None, "AE28", "AF28", "AJ29", "AJ30"], - "LVCMOS18", Series7), - "xc7vh870t": ("flg1932-1", - ["V32", None, "T33", "R33", "U31", "T31"], - "LVCMOS18", Series7), - "xc7vx1140t": ("flg1926-1", - ["AK33", None, "AN34", "AN35", "AJ34", "AK34"], - "LVCMOS18", Series7), - "xc7vx330t": ("ffg1157-1", - ["AL33", None, "AN33", "AN34", "AK34", "AL34"], - "LVCMOS18", Series7), - "xc7vx415t": ("ffg1157-1", - ["AL33", None, "AN33", "AN34", "AK34", "AL34"], - "LVCMOS18", Series7), - "xc7vx485t": ("ffg1157-1", - ["AL33", None, "AN33", "AN34", "AK34", "AL34"], - "LVCMOS18", Series7), - "xc7vx550t": ("ffg1158-1", - ["C24", None, "A23", "A24", "B26", "A26"], - "LVCMOS18", Series7), - "xc7vx690t": ("ffg1157-1", - ["AL33", None, "AN33", "AN34", "AK34", "AL34"], - "LVCMOS18", Series7), - "xc7vx980t": ("ffg1926-1", - ["AK33", None, "AN34", "AN35", "AJ34", "AK34"], - "LVCMOS18", Series7), - } - - def __init__(self, device, pins, std): - cs_n, clk, mosi, miso = pins[:4] - io = ["spiflash", 0, - Subsignal("cs_n", Pins(cs_n)), - Subsignal("mosi", Pins(mosi)), - Subsignal("miso", Pins(miso), Misc("PULLUP")), - IOStandard(std), - ] - if clk: - io.append(Subsignal("clk", Pins(clk))) - for i, p in enumerate(pins[4:]): - io.append(Subsignal("pullup{}".format(i), Pins(p), Misc("PULLUP"))) - - XilinxPlatform.__init__(self, device, [io]) - if isinstance(self.toolchain, XilinxVivadoToolchain): - self.toolchain.bitstream_commands.append( - "set_property BITSTREAM.GENERAL.COMPRESS True [current_design]" - ) - elif isinstance(self.toolchain, XilinxISEToolchain): - self.toolchain.bitgen_opt += " -g compress" - - @classmethod - def make(cls, device, errors=False): - pkg, pins, std, Top = cls.pinouts[device] - platform = cls("{}-{}".format(device, pkg), pins, std) - top = Top(platform) - name = "bscan_spi_{}".format(device) - dir = "build_{}".format(device) - try: - platform.build(top, build_name=name, build_dir=dir) - except Exception as e: - print("ERROR: build failed for {}: {}".format(device, e)) - if errors: - raise - - -if __name__ == "__main__": - import argparse - import multiprocessing - p = argparse.ArgumentParser(description="build bscan_spi bitstreams " - "for openocd jtagspi flash driver") - p.add_argument("device", nargs="*", - default=sorted(list(XilinxBscanSpi.pinouts)), - help="build for these devices (default: %(default)s)") - p.add_argument("-p", "--parallel", default=1, type=int, - help="number of parallel builds (default: %(default)s)") - args = p.parse_args() - pool = multiprocessing.Pool(args.parallel) - pool.map(XilinxBscanSpi.make, args.device, chunksize=1) diff --git a/contrib/loaders/flash/k1921vk01t.S b/contrib/loaders/flash/k1921vk01t.S deleted file mode 100644 index b8f0b53d5..000000000 --- a/contrib/loaders/flash/k1921vk01t.S +++ /dev/null @@ -1,112 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2015 by Bogdan Kolbov * - * kolbov@niiet.ru * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc. * - ***************************************************************************/ - - .text - .syntax unified - .cpu cortex-m4 - .thumb - .thumb_func - -/* K1921VK01T has 128-bitwidth flash, so it`s able to load 4x32-bit words at the time. - * And only after all words loaded we can start write - */ - -/* Registers addresses */ -#define FLASH_FMA 0x00 /* Address reg */ -#define FLASH_FMD1 0x04 /* Data1 reg */ -#define FLASH_FMC 0x08 /* Command reg */ -#define FLASH_FCIS 0x0C /* Operation Status reg */ -#define FLASH_FCIC 0x14 /* Operation Status Clear reg */ -#define FLASH_FMD2 0x50 /* Data2 reg */ -#define FLASH_FMD3 0x54 /* Data3 reg */ -#define FLASH_FMD4 0x58 /* Data4 reg*/ - - /* Params: - * r0 - write cmd (in), status (out) - * r1 - count - * r2 - workarea start - * r3 - workarea end - * r4 - target address - * Clobbered: - * r5 - rp - * r6 - wp, tmp - * r7 - flash base - */ - -ldr r7, =#0xA001C000 /* Flash reg base*/ - -wait_fifo: - ldr r6, [r2, #0] /* read wp */ - cmp r6, #0 /* abort if wp == 0 */ - beq exit - ldr r5, [r2, #4] /* read rp */ - cmp r5, r6 /* wait until rp != wp */ - beq wait_fifo - - -load_data: - ldr r6, [r5] /* read data1 */ - str r6, [r7, #FLASH_FMD1] - adds r5, #4 - - ldr r6, [r5] /* read data2 */ - str r6, [r7, #FLASH_FMD2] - adds r5, #4 - - ldr r6, [r5] /* read data3 */ - str r6, [r7, #FLASH_FMD3] - adds r5, #4 - - ldr r6, [r5] /* read data4 */ - str r6, [r7, #FLASH_FMD4] - adds r5, #4 - -start_write: - str r4, [r7, #FLASH_FMA] /* set addr */ - adds r4, #16 - str r0, [r7, #FLASH_FMC] /* write cmd */ - -busy: - ldr r6, [r7, #FLASH_FCIS] /* wait until flag set */ - cmp r6, #0x0 - beq busy - - cmp r6, #2 /* check the error bit */ - beq error - - movs r6, #1 /* clear flags */ - str r6, [r7, #FLASH_FCIC] - - cmp r5, r3 /* wrap rp at end of buffer */ - bcc no_wrap - mov r5, r2 - adds r5, #8 -no_wrap: - str r5, [r2, #4] /* store rp */ - subs r1, r1, #1 /* decrement 16-byte block count */ - cmp r1, #0 - beq exit /* loop if not done */ - b wait_fifo - -error: - movs r0, #0 - str r0, [r2, #4] /* set rp = 0 on error */ -exit: - mov r0, r6 /* return status in r0 */ - bkpt #0 diff --git a/contrib/loaders/flash/kinetis_ke/Makefile b/contrib/loaders/flash/kinetis_ke/Makefile deleted file mode 100644 index 7d8dba8c7..000000000 --- a/contrib/loaders/flash/kinetis_ke/Makefile +++ /dev/null @@ -1,21 +0,0 @@ -BIN2C = ../../../../src/helper/bin2char.sh - -CROSS_COMPILE ?= arm-none-eabi- -AS = $(CROSS_COMPILE)as -OBJCOPY = $(CROSS_COMPILE)objcopy - -AFLAGS = -EL - -all: kinetis_ke_flash.inc kinetis_ke_watchdog.inc - -%.elf: %.s - $(AS) $(AFLAGS) $< -o $@ - -%.bin: %.elf - $(OBJCOPY) -Obinary $< $@ - -%.inc: %.bin - $(BIN2C) < $< > $@ - -clean: - -rm -f *.elf *.bin *.inc diff --git a/contrib/loaders/flash/kinetis_ke/kinetis_ke_flash.inc b/contrib/loaders/flash/kinetis_ke/kinetis_ke_flash.inc deleted file mode 100644 index 9bb0fa895..000000000 --- a/contrib/loaders/flash/kinetis_ke/kinetis_ke_flash.inc +++ /dev/null @@ -1,15 +0,0 @@ -/* Autogenerated with ../../../../src/helper/bin2char.sh */ -0x16,0x68,0x00,0x2e,0xfe,0xd0,0x55,0x68,0xb5,0x42,0xf9,0xd0,0x2f,0x4e,0x30,0x27, -0x37,0x70,0x2f,0x4e,0x00,0x27,0x37,0x70,0x2e,0x4e,0x06,0x27,0x37,0x70,0x07,0x0c, -0x2d,0x4e,0x37,0x70,0x2a,0x4e,0x01,0x27,0x37,0x70,0xc7,0xb2,0x2a,0x4e,0x37,0x70, -0x07,0x0a,0x28,0x4e,0x37,0x70,0x26,0x4e,0x02,0x27,0x37,0x70,0x6f,0x78,0x25,0x4e, -0x37,0x70,0x2f,0x78,0x24,0x4e,0x37,0x70,0x21,0x4e,0x03,0x27,0x37,0x70,0xef,0x78, -0x20,0x4e,0x37,0x70,0xaf,0x78,0x20,0x4e,0x37,0x70,0x01,0x39,0x04,0x30,0x04,0x35, -0x9d,0x42,0x01,0xd3,0x15,0x1c,0x08,0x35,0x00,0x29,0x1b,0xd0,0x16,0x68,0xae,0x42, -0x18,0xd0,0x17,0x4e,0x04,0x27,0x37,0x70,0x6f,0x78,0x16,0x4e,0x37,0x70,0x2f,0x78, -0x15,0x4e,0x37,0x70,0x12,0x4e,0x05,0x27,0x37,0x70,0xef,0x78,0x11,0x4e,0x37,0x70, -0xaf,0x78,0x11,0x4e,0x37,0x70,0x01,0x39,0x04,0x30,0x04,0x35,0x9d,0x42,0x01,0xd3, -0x15,0x1c,0x08,0x35,0x09,0x4e,0x80,0x27,0x37,0x70,0x08,0x4e,0x36,0x78,0x3e,0x42, -0xfb,0xd0,0x30,0x27,0x3e,0x42,0x04,0xd1,0x00,0x26,0x55,0x60,0x00,0x29,0x02,0xd0, -0x9e,0xe7,0x00,0x20,0x50,0x60,0x30,0x1c,0x00,0xbe,0xc0,0x46,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, diff --git a/contrib/loaders/flash/kinetis_ke/kinetis_ke_flash.s b/contrib/loaders/flash/kinetis_ke/kinetis_ke_flash.s deleted file mode 100644 index 1fa761336..000000000 --- a/contrib/loaders/flash/kinetis_ke/kinetis_ke_flash.s +++ /dev/null @@ -1,184 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2015 by Ivan Meleca * - * ivan@artekit.eu * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - ***************************************************************************/ - - /* Params: - * r0 = flash destination address, status - * r1 = longword count - * r2 = workarea start address - * r3 = workarea end address - */ - - .text - .cpu cortex-m0plus - .code 16 - .thumb_func - - .align 2 - - /* r5 = rp - * r6 = wp, tmp - * r7 = tmp - */ - -wait_fifo: - ldr r6, [r2, #0] /* read wp */ - cmp r6, #0 /* abort if wp == 0 */ - beq exit - ldr r5, [r2, #4] /* read rp */ - cmp r5, r6 /* wait until rp != wp */ - beq wait_fifo - - ldr r6, fstat /* Clear error flags */ - mov r7, #48 - strb r7, [r6] - - ldr r6, fccobix /* FCCOBIX = 0 */ - mov r7, #0 - strb r7, [r6] - - ldr r6, fccobhi /* Program FLASH command */ - mov r7, #6 /* FCCOBHI = 6 */ - strb r7, [r6] - - lsr r7, r0, #16 /* FCCOBLO = flash destination address >> 16 */ - ldr r6, fccoblo - strb r7, [r6] - - ldr r6, fccobix /* Index for lower byte address bits[15:0] */ - mov r7, #1 - strb r7, [r6] /* FCCOBIX = 1*/ - - uxtb r7, r0 /* Memory address bits[15:0] */ - ldr r6, fccoblo - strb r7, [r6] /* FCCOBLO = flash destination address */ - - lsr r7, r0, #8 - ldr r6, fccobhi - strb r7, [r6] /* FCCOBHI = flash destination address >> 8 */ - - ldr r6, fccobix /* FCCOBIX = 2 */ - mov r7, #2 - strb r7, [r6] - - ldrb r7, [r5, #1] /* FCCOBHI = rp >> 8 */ - ldr r6, fccobhi - strb r7, [r6] - - ldrb r7, [r5] /* FCCOBLO = rp */ - ldr r6, fccoblo - strb r7, [r6] - - ldr r6, fccobix /* FCCOBIX = 3 */ - mov r7, #3 - strb r7, [r6] - - ldrb r7, [r5, #3] /* FCCOBHI = rp >> 24 */ - ldr r6, fccobhi - strb r7, [r6] - - ldrb r7, [r5, #2] /* FCCOBLO = rp >> 16 */ - ldr r6, fccoblo - strb r7, [r6] - - sub r1, r1, #1 /* Two words (4 bytes) queued, decrement counter */ - add r0, r0, #4 /* flash address += 4 */ - add r5, r5, #4 /* rp += 4 */ - - cmp r5, r3 /* Wrap? */ - bcc no_wrap - mov r5, r2 - add r5, r5, #8 - -no_wrap: - cmp r1, #0 /* Done? */ - beq execute - - ldr r6, [r2, #0] /* read wp */ - cmp r6, r5 - beq execute /* execute if rp == wp */ - - ldr r6, fccobix /* FCCOBIX = 4 */ - mov r7, #4 - strb r7, [r6] - - ldrb r7, [r5, #1] /* FCCOBHI = rp >> 8 */ - ldr r6, fccobhi - strb r7, [r6] - - ldrb r7, [r5] /* FCCOBLO = rp */ - ldr r6, fccoblo - strb r7, [r6] - - ldr r6, fccobix /* FCCOBIX = 5 */ - mov r7, #5 - strb r7, [r6] - - ldrb r7, [r5, #3] /* FCCOBHI = rp >> 24 */ - ldr r6, fccobhi - strb r7, [r6] - - ldrb r7, [r5, #2] /* FCCOBLO = rp >> 16 */ - ldr r6, fccoblo - strb r7, [r6] - - sub r1, r1, #1 /* Two words (4 bytes) queued, decrement counter */ - add r0, r0, #4 /* flash address += 4 */ - add r5, r5, #4 /* rp += 4 */ - - cmp r5, r3 /* Wrap? */ - bcc execute - mov r5, r2 - add r5, r5, #8 - -execute: - ldr r6, fstat /* Launch the command */ - mov r7, #128 - strb r7, [r6] - -wait_busy: - ldr r6, fstat - ldrb r6, [r6] /* Wait until finished */ - tst r6, r7 - beq wait_busy - - mov r7, #48 /* Check error */ - tst r6, r7 - bne error - - mov r6, #0 /* Clear error */ - - str r5, [r2, #4] /* Store rp */ - - cmp r1, #0 /* Done? */ - beq done - b wait_fifo - -error: - mov r0, #0 - str r0, [r2, #4] /* set rp = 0 on error */ - -done: - mov r0, r6 /* Set result code */ - bkpt #0 - - .align 2 -fstat: - .word 0 -fccobix: - .word 0 -fccobhi: - .word 0 -fccoblo: - .word 0 diff --git a/contrib/loaders/flash/kinetis_ke/kinetis_ke_watchdog.inc b/contrib/loaders/flash/kinetis_ke/kinetis_ke_watchdog.inc deleted file mode 100644 index 44a9d5e5b..000000000 --- a/contrib/loaders/flash/kinetis_ke/kinetis_ke_watchdog.inc +++ /dev/null @@ -1,4 +0,0 @@ -/* Autogenerated with ../../../../src/helper/bin2char.sh */ -0x07,0x4b,0x7f,0x22,0x1d,0x78,0x5c,0x78,0x2a,0x40,0x06,0x4d,0x98,0x88,0xd9,0x88, -0x5d,0x80,0x05,0x4d,0x5d,0x80,0x5c,0x70,0x98,0x80,0xd9,0x80,0x1a,0x70,0x00,0xbe, -0x00,0x20,0x05,0x40,0xc5,0x20,0x00,0x00,0xd9,0x28,0x00,0x00, diff --git a/contrib/loaders/flash/kinetis_ke/kinetis_ke_watchdog.s b/contrib/loaders/flash/kinetis_ke/kinetis_ke_watchdog.s deleted file mode 100644 index 289662d07..000000000 --- a/contrib/loaders/flash/kinetis_ke/kinetis_ke_watchdog.s +++ /dev/null @@ -1,47 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2015 by Ivan Meleca * - * ivan@artekit.eu * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - ***************************************************************************/ - - .text - .cpu cortex-m0plus - .code 16 - .thumb_func - - .align 2 - - ldr r3, wdog_cs1 - mov r2, #127 - ldrb r5, [r3] - ldrb r4, [r3, #1] - and r2, r5 - ldr r5, unlock1 - ldrh r0, [r3, #4] - ldrh r1, [r3, #6] - strh r5, [r3, #2] - ldr r5, unlock2 - strh r5, [r3, #2] - strb r4, [r3, #1] - strh r0, [r3, #4] - strh r1, [r3, #6] - strb r2, [r3] - bkpt #0 - - .align 2 - -wdog_cs1: - .word 0x40052000 // Watchdog Control and Status Register 1 -unlock1: - .word 0x20C5 // 1st unlock word -unlock2: - .word 0x28D9 // 2nd unlock word diff --git a/contrib/loaders/flash/lpcspifi_erase.S b/contrib/loaders/flash/lpcspifi_erase.S deleted file mode 100644 index 350aa93cb..000000000 --- a/contrib/loaders/flash/lpcspifi_erase.S +++ /dev/null @@ -1,176 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2012 by George Harris * - * george@luminairecoffee.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - ***************************************************************************/ - - .text - .syntax unified - .cpu cortex-m3 - .thumb - .thumb_func - -/* - * Params : - * r0 = start address, status (out) - * r1 = count - * r2 = erase command - * r3 = block size - */ - -#define SSP_BASE_HIGH 0x4008 -#define SSP_BASE_LOW 0x3000 -#define SSP_CR0_OFFSET 0x00 -#define SSP_CR1_OFFSET 0x04 -#define SSP_DATA_OFFSET 0x08 -#define SSP_CPSR_OFFSET 0x10 -#define SSP_SR_OFFSET 0x0c - -#define SSP_CLOCK_BASE_HIGH 0x4005 -#define SSP_CLOCK_BASE_LOW 0x0000 -#define SSP_BRANCH_CLOCK_BASE_HIGH 0x4005 -#define SSP_BRANCH_CLOCK_BASE_LOW 0x2000 -#define SSP_BASE_CLOCK_OFFSET 0x94 -#define SSP_BRANCH_CLOCK_OFFSET 0x700 - -#define IOCONFIG_BASE_HIGH 0x4008 -#define IOCONFIG_BASE_LOW 0x6000 -#define IOCONFIG_SCK_OFFSET 0x18c -#define IOCONFIG_HOLD_OFFSET 0x190 -#define IOCONFIG_WP_OFFSET 0x194 -#define IOCONFIG_MISO_OFFSET 0x198 -#define IOCONFIG_MOSI_OFFSET 0x19c -#define IOCONFIG_CS_OFFSET 0x1a0 - -#define IO_BASE_HIGH 0x400f -#define IO_BASE_LOW 0x4000 -#define IO_CS_OFFSET 0xab -#define IODIR_BASE_HIGH 0x400f -#define IODIR_BASE_LOW 0x6000 -#define IO_CS_DIR_OFFSET 0x14 - - -setup: /* Initialize SSP pins and module */ - mov.w r10, #IOCONFIG_BASE_LOW - movt r10, #IOCONFIG_BASE_HIGH - mov.w r8, #0xea - str.w r8, [r10, #IOCONFIG_SCK_OFFSET] /* Configure SCK pin function */ - mov.w r8, #0x40 - str.w r8, [r10, #IOCONFIG_HOLD_OFFSET] /* Configure /HOLD pin function */ - mov.w r8, #0x40 - str.w r8, [r10, #IOCONFIG_WP_OFFSET] /* Configure /WP pin function */ - mov.w r8, #0xed - str.w r8, [r10, #IOCONFIG_MISO_OFFSET] /* Configure MISO pin function */ - mov.w r8, #0xed - str.w r8, [r10, #IOCONFIG_MOSI_OFFSET] /* Configure MOSI pin function */ - mov.w r8, #0x44 - str.w r8, [r10, #IOCONFIG_CS_OFFSET] /* Configure CS pin function */ - - mov.w r10, #IODIR_BASE_LOW - movt r10, #IODIR_BASE_HIGH - mov.w r8, #0x800 - str r8, [r10, #IO_CS_DIR_OFFSET] /* Set CS as output */ - mov.w r10, #IO_BASE_LOW - movt r10, #IO_BASE_HIGH - mov.w r8, #0xff - str.w r8, [r10, #IO_CS_OFFSET] /* Set CS high */ - - mov.w r10, #SSP_CLOCK_BASE_LOW - movt r10, #SSP_CLOCK_BASE_HIGH - mov.w r8, #0x0000 - movt r8, #0x0100 - str.w r8, [r10, #SSP_BASE_CLOCK_OFFSET] /* Configure SSP0 base clock (use 12 MHz IRC) */ - - mov.w r10, #SSP_BRANCH_CLOCK_BASE_LOW - movt r10, #SSP_BRANCH_CLOCK_BASE_HIGH - mov.w r8, #0x01 - str.w r8, [r10, #SSP_BRANCH_CLOCK_OFFSET] /* Configure (enable) SSP0 branch clock */ - - mov.w r10, #SSP_BASE_LOW - movt r10, #SSP_BASE_HIGH - mov.w r8, #0x07 - str.w r8, [r10, #SSP_CR0_OFFSET] /* Set clock postscale */ - mov.w r8, #0x02 - str.w r8, [r10, #SSP_CPSR_OFFSET] /* Set clock prescale */ - str.w r8, [r10, #SSP_CR1_OFFSET] /* Enable SSP in SPI mode */ -write_enable: - bl cs_down - mov.w r9, #0x06 /* Send the write enable command */ - bl write_data - bl cs_up - - bl cs_down - mov.w r9, #0x05 /* Get status register */ - bl write_data - mov.w r9, #0x00 /* Dummy data to clock in status */ - bl write_data - bl cs_up - - tst r9, #0x02 /* If the WE bit isn't set, we have a problem. */ - beq error -erase: - bl cs_down - mov.w r9, r2 /* Send the erase command */ - bl write_data -write_address: - lsr r9, r0, #16 /* Send the current 24-bit write address, MSB first */ - bl write_data - lsr r9, r0, #8 - bl write_data - mov.w r9, r0 - bl write_data - bl cs_up -wait_flash_busy: /* Wait for the flash to finish the previous erase */ - bl cs_down - mov.w r9, #0x05 /* Get status register */ - bl write_data - mov.w r9, #0x00 /* Dummy data to clock in status */ - bl write_data - bl cs_up - tst r9, #0x01 /* If it isn't done, keep waiting */ - bne wait_flash_busy - - subs r1, r1, #1 /* decrement count */ - cbz r1, exit /* Exit if we have written everything */ - add r0, r3 /* Move the address up by the block size */ - b write_enable /* Start a new block erase */ -write_data: /* Send/receive 1 byte of data over SSP */ - mov.w r10, #SSP_BASE_LOW - movt r10, #SSP_BASE_HIGH - str.w r9, [r10, #SSP_DATA_OFFSET] /* Write supplied data to the SSP data reg */ -wait_transmit: - ldr r9, [r10, #SSP_SR_OFFSET] /* Check SSP status */ - tst r9, #0x0010 /* Check if BSY bit is set */ - bne wait_transmit /* If still transmitting, keep waiting */ - ldr r9, [r10, #SSP_DATA_OFFSET] /* Load received data */ - bx lr /* Exit subroutine */ -cs_up: - mov.w r8, #0xff - b cs_write -cs_down: - mov.w r8, #0x0000 -cs_write: - mov.w r10, #IO_BASE_LOW - movt r10, #IO_BASE_HIGH - str.w r8, [r10, #IO_CS_OFFSET] - bx lr -error: - movs r0, #0 -exit: - bkpt #0x00 - - .end diff --git a/contrib/loaders/flash/lpcspifi_init.S b/contrib/loaders/flash/lpcspifi_init.S deleted file mode 100644 index 9872892f5..000000000 --- a/contrib/loaders/flash/lpcspifi_init.S +++ /dev/null @@ -1,102 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2012 by George Harris * - * george@luminairecoffee.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - ***************************************************************************/ - -/*************************************************************************** -* This is an algorithm for the LPC43xx family (and probably the LPC18xx * -* family as well, though they have not been tested) that will initialize * -* memory-mapped SPI flash accesses. Unfortunately NXP has published * -* neither the ROM source code that performs this initialization nor the * -* register descriptions necessary to do so, so this code is necessary to * -* call into the ROM SPIFI API. * -***************************************************************************/ - - .text - .syntax unified - .arch armv7-m - .thumb - .thumb_func - - .align 2 - -/* - * Params : - * r0 = spifi clock speed - */ - -#define IOCONFIG_BASE_HIGH 0x4008 -#define IOCONFIG_BASE_LOW 0x6000 -#define IOCONFIG_SCK_OFFSET 0x18c -#define IOCONFIG_HOLD_OFFSET 0x190 -#define IOCONFIG_WP_OFFSET 0x194 -#define IOCONFIG_MISO_OFFSET 0x198 -#define IOCONFIG_MOSI_OFFSET 0x19c -#define IOCONFIG_CS_OFFSET 0x1a0 - -#define SPIFI_ROM_TABLE_BASE_HIGH 0x1040 -#define SPIFI_ROM_TABLE_BASE_LOW 0x0118 - -code: - mov.w r8, r0 - sub sp, #0x84 - add r7, sp, #0x0 - /* Initialize SPIFI pins */ - mov.w r3, #IOCONFIG_BASE_LOW - movt r3, #IOCONFIG_BASE_HIGH - mov.w r2, #0xf3 - str.w r2, [r3, #IOCONFIG_SCK_OFFSET] - mov.w r3, #IOCONFIG_BASE_LOW - movt r3, #IOCONFIG_BASE_HIGH - mov.w r2, #IOCONFIG_BASE_LOW - movt r2, #IOCONFIG_BASE_HIGH - mov.w r1, #IOCONFIG_BASE_LOW - movt r1, #IOCONFIG_BASE_HIGH - mov.w r0, #IOCONFIG_BASE_LOW - movt r0, #IOCONFIG_BASE_HIGH - mov.w r4, #0xd3 - str.w r4, [r0, #IOCONFIG_MOSI_OFFSET] - mov r0, r4 - str.w r0, [r1, #IOCONFIG_MISO_OFFSET] - mov r1, r0 - str.w r1, [r2, #IOCONFIG_WP_OFFSET] - str.w r1, [r3, #IOCONFIG_HOLD_OFFSET] - mov.w r3, #IOCONFIG_BASE_LOW - movt r3, #IOCONFIG_BASE_HIGH - mov.w r2, #0x13 - str.w r2, [r3, #IOCONFIG_CS_OFFSET] - - /* Perform SPIFI init. See spifi_rom_api.h (in NXP lpc43xx driver package) for details */ - /* on initialization arguments. */ - movw r3, #SPIFI_ROM_TABLE_BASE_LOW /* The ROM API table is located @ 0x10400118, and */ - movt r3, #SPIFI_ROM_TABLE_BASE_HIGH /* the first pointer in the struct is to the init function. */ - ldr r3, [r3, #0x0] - ldr r4, [r3, #0x0] /* Grab the init function pointer from the table */ - /* Set up function arguments */ - movw r0, #0x3b4 - movt r0, #0x1000 /* Pointer to a SPIFI data struct that we don't care about */ - mov.w r1, #0x3 /* "csHigh". Not 100% sure what this does. */ - mov.w r2, #0xc0 /* The configuration word: S_RCVCLOCK | S_FULLCLK */ - mov.w r3, r8 /* SPIFI clock speed (12MHz) */ - blx r4 /* Call the init function */ - b done - -done: - bkpt #0 - - .end diff --git a/contrib/loaders/flash/lpcspifi_write.S b/contrib/loaders/flash/lpcspifi_write.S deleted file mode 100644 index 8435a2045..000000000 --- a/contrib/loaders/flash/lpcspifi_write.S +++ /dev/null @@ -1,222 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2012 by George Harris * - * george@luminairecoffee.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - ***************************************************************************/ - - .text - .syntax unified - .cpu cortex-m3 - .thumb - .thumb_func - -/* - * Params : - * r0 = workarea start, status (out) - * r1 = workarea end - * r2 = target address (offset from flash base) - * r3 = count (bytes) - * r4 = page size - * Clobbered: - * r7 - rp - * r8 - wp, tmp - * r9 - send/receive data - * r10 - temp - * r11 - current page end address - */ - -/* - * This code is embedded within: src/flash/nor/lpcspifi.c as a "C" array. - * - * To rebuild: - * arm-none-eabi-gcc -c lpcspifi_write.S - * arm-none-eabi-objcopy -O binary lpcspifi_write.o lpcspifi_write.bin - * xxd -c 8 -i lpcspifi_write.bin > lpcspifi_write.txt - * - * Then read and edit this result into the "C" source. - */ - -#define SSP_BASE_HIGH 0x4008 -#define SSP_BASE_LOW 0x3000 -#define SSP_CR0_OFFSET 0x00 -#define SSP_CR1_OFFSET 0x04 -#define SSP_DATA_OFFSET 0x08 -#define SSP_CPSR_OFFSET 0x10 -#define SSP_SR_OFFSET 0x0c - -#define SSP_CLOCK_BASE_HIGH 0x4005 -#define SSP_CLOCK_BASE_LOW 0x0000 -#define SSP_BRANCH_CLOCK_BASE_HIGH 0x4005 -#define SSP_BRANCH_CLOCK_BASE_LOW 0x2000 -#define SSP_BASE_CLOCK_OFFSET 0x94 -#define SSP_BRANCH_CLOCK_OFFSET 0x700 - -#define IOCONFIG_BASE_HIGH 0x4008 -#define IOCONFIG_BASE_LOW 0x6000 -#define IOCONFIG_SCK_OFFSET 0x18c -#define IOCONFIG_HOLD_OFFSET 0x190 -#define IOCONFIG_WP_OFFSET 0x194 -#define IOCONFIG_MISO_OFFSET 0x198 -#define IOCONFIG_MOSI_OFFSET 0x19c -#define IOCONFIG_CS_OFFSET 0x1a0 - -#define IO_BASE_HIGH 0x400f -#define IO_BASE_LOW 0x4000 -#define IO_CS_OFFSET 0xab -#define IODIR_BASE_HIGH 0x400f -#define IODIR_BASE_LOW 0x6000 -#define IO_CS_DIR_OFFSET 0x14 - - -setup: /* Initialize SSP pins and module */ - mov.w r10, #IOCONFIG_BASE_LOW - movt r10, #IOCONFIG_BASE_HIGH - mov.w r8, #0xea - str.w r8, [r10, #IOCONFIG_SCK_OFFSET] /* Configure SCK pin function */ - mov.w r8, #0x40 - str.w r8, [r10, #IOCONFIG_HOLD_OFFSET] /* Configure /HOLD pin function */ - mov.w r8, #0x40 - str.w r8, [r10, #IOCONFIG_WP_OFFSET] /* Configure /WP pin function */ - mov.w r8, #0xed - str.w r8, [r10, #IOCONFIG_MISO_OFFSET] /* Configure MISO pin function */ - mov.w r8, #0xed - str.w r8, [r10, #IOCONFIG_MOSI_OFFSET] /* Configure MOSI pin function */ - mov.w r8, #0x44 - str.w r8, [r10, #IOCONFIG_CS_OFFSET] /* Configure CS pin function */ - - mov.w r10, #IODIR_BASE_LOW - movt r10, #IODIR_BASE_HIGH - mov.w r8, #0x800 - str r8, [r10, #IO_CS_DIR_OFFSET] /* Set CS as output */ - mov.w r10, #IO_BASE_LOW - movt r10, #IO_BASE_HIGH - mov.w r8, #0xff - str.w r8, [r10, #IO_CS_OFFSET] /* Set CS high */ - - mov.w r10, #SSP_CLOCK_BASE_LOW - movt r10, #SSP_CLOCK_BASE_HIGH - mov.w r8, #0x0000 - movt r8, #0x0100 - str.w r8, [r10, #SSP_BASE_CLOCK_OFFSET] /* Configure SSP0 base clock (use 12 MHz IRC) */ - - mov.w r10, #SSP_BRANCH_CLOCK_BASE_LOW - movt r10, #SSP_BRANCH_CLOCK_BASE_HIGH - mov.w r8, #0x01 - str.w r8, [r10, #SSP_BRANCH_CLOCK_OFFSET] /* Configure (enable) SSP0 branch clock */ - - mov.w r10, #SSP_BASE_LOW - movt r10, #SSP_BASE_HIGH - mov.w r8, #0x07 - str.w r8, [r10, #SSP_CR0_OFFSET] /* Set clock postscale */ - mov.w r8, #0x02 - str.w r8, [r10, #SSP_CPSR_OFFSET] /* Set clock prescale */ - str.w r8, [r10, #SSP_CR1_OFFSET] /* Enable SSP in SPI mode */ - - mov.w r11, #0x00 -find_next_page_boundary: - add r11, r4 /* Increment to the next page */ - cmp r11, r2 - /* If we have not reached the next page boundary after the target address, keep going */ - bls find_next_page_boundary -write_enable: - bl cs_down - mov.w r9, #0x06 /* Send the write enable command */ - bl write_data - bl cs_up - - bl cs_down - mov.w r9, #0x05 /* Get status register */ - bl write_data - mov.w r9, #0x00 /* Dummy data to clock in status */ - bl write_data - bl cs_up - - tst r9, #0x02 /* If the WE bit isn't set, we have a problem. */ - beq error -page_program: - bl cs_down - mov.w r9, #0x02 /* Send the page program command */ - bl write_data -write_address: - lsr r9, r2, #16 /* Send the current 24-bit write address, MSB first */ - bl write_data - lsr r9, r2, #8 - bl write_data - mov.w r9, r2 - bl write_data -wait_fifo: - ldr r8, [r0] /* read the write pointer */ - cmp r8, #0 /* if it's zero, we're gonzo */ - beq exit - ldr r7, [r0, #4] /* read the read pointer */ - cmp r7, r8 /* wait until they are not equal */ - beq wait_fifo -write: - ldrb r9, [r7], #0x01 /* Load one byte from the FIFO, increment the read pointer by 1 */ - bl write_data /* send the byte to the flash chip */ - - cmp r7, r1 /* wrap the read pointer if it is at the end */ - it cs - addcs r7, r0, #8 /* skip loader args */ - str r7, [r0, #4] /* store the new read pointer */ - subs r3, r3, #1 /* decrement count */ - cbz r3, exit /* Exit if we have written everything */ - - add r2, #1 /* Increment flash address by 1 */ - cmp r11, r2 /* See if we have reached the end of a page */ - bne wait_fifo /* If not, keep writing bytes */ - bl cs_up /* Otherwise, end the command and keep going w/ the next page */ - add r11, r4 /* Move up the end-of-page address by the page size*/ -wait_flash_busy: /* Wait for the flash to finish the previous page write */ - bl cs_down - mov.w r9, #0x05 /* Get status register */ - bl write_data - mov.w r9, #0x00 /* Dummy data to clock in status */ - bl write_data - bl cs_up - tst r9, #0x01 /* If it isn't done, keep waiting */ - bne wait_flash_busy - b write_enable /* If it is done, start a new page write */ -write_data: /* Send/receive 1 byte of data over SSP */ - mov.w r10, #SSP_BASE_LOW - movt r10, #SSP_BASE_HIGH - str.w r9, [r10, #SSP_DATA_OFFSET] /* Write supplied data to the SSP data reg */ -wait_transmit: - ldr r9, [r10, #SSP_SR_OFFSET] /* Check SSP status */ - tst r9, #0x0010 /* Check if BSY bit is set */ - bne wait_transmit /* If still transmitting, keep waiting */ - ldr r9, [r10, #SSP_DATA_OFFSET] /* Load received data */ - bx lr /* Exit subroutine */ -cs_up: - mov.w r8, #0xff - b cs_write -cs_down: - mov.w r8, #0x0000 -cs_write: - mov.w r10, #IO_BASE_LOW - movt r10, #IO_BASE_HIGH - str.w r8, [r10, #IO_CS_OFFSET] - bx lr -error: - movs r0, #0 - str r0, [r2, #4] /* set rp = 0 on error */ -exit: - bl cs_up /* end the command before returning */ - mov r0, r6 - bkpt #0x00 - - .end diff --git a/contrib/loaders/flash/mdr32fx.S b/contrib/loaders/flash/mdr32fx.S deleted file mode 100644 index 73f4b6fde..000000000 --- a/contrib/loaders/flash/mdr32fx.S +++ /dev/null @@ -1,125 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2011 by Andreas Fritiofson * - * andreas.fritiofson@gmail.com * - * * - * Copyright (C) 2013 by Paul Fertser * - * fercerpav@gmail.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - ***************************************************************************/ - - .text - .syntax unified - .cpu cortex-m0 - .thumb - .thumb_func - .global write - - /* Params: - * r0 - flash base (in), status (out) - * r1 - count (32bit) - * r2 - workarea start - * r3 - workarea end - * r4 - target address - * Clobbered: - * r5 - rp - * r6 - wp, tmp - * r7 - current FLASH_CMD - */ - -#define FLASH_CMD 0x00 -#define FLASH_ADR 0x04 -#define FLASH_DI 0x08 - -#define FLASH_NVSTR (1 << 13) -#define FLASH_PROG (1 << 12) -#define FLASH_MAS1 (1 << 11) -#define FLASH_ERASE (1 << 10) -#define FLASH_SE (1 << 8) -#define FLASH_YE (1 << 7) -#define FLASH_XE (1 << 6) - - ldr r7, [r0, #FLASH_CMD] -wait_fifo: - ldr r6, [r2, #0] /* read wp */ - cmp r6, #0 /* abort if wp == 0 */ - beq exit - ldr r5, [r2, #4] /* read rp */ - cmp r5, r6 /* wait until rp != wp */ - beq wait_fifo - - ldr r6, [r5] /* "*target_address++ = *rp++" */ - str r4, [r0, #FLASH_ADR] - str r6, [r0, #FLASH_DI] - - ldr r6, =(FLASH_XE | FLASH_PROG) - orrs r7, r7, r6 - str r7, [r0, #FLASH_CMD] - # wait 5us - movs r6, #5 - bl delay - ldr r6, =#FLASH_NVSTR - orrs r7, r7, r6 - str r7, [r0, #FLASH_CMD] - # wait 10us - movs r6, #13 - bl delay - movs r6, #FLASH_YE - orrs r7, r7, r6 - str r7, [r0, #FLASH_CMD] - # wait 40us - movs r6, #61 - bl delay - movs r6, #FLASH_YE - bics r7, r7, r6 - str r7, [r0, #FLASH_CMD] - ldr r6, =#FLASH_PROG - bics r7, r7, r6 - str r7, [r0, #FLASH_CMD] - # wait 5us - movs r6, #5 - bl delay - ldr r6, =#(FLASH_XE | FLASH_NVSTR) - bics r7, r7, r6 - str r7, [r0, #FLASH_CMD] - - adds r5, #4 - adds r4, #4 - - cmp r5, r3 /* wrap rp at end of buffer */ - bcc no_wrap - mov r5, r2 - adds r5, #8 -no_wrap: - str r5, [r2, #4] /* store rp */ - subs r1, r1, #1 /* decrement word count */ - cmp r1, #0 - beq exit /* loop if not done */ - b wait_fifo -exit: - mov r0, r6 /* return status in r0 */ - bkpt #0 - - /* r6 - in - * for r6 == 1 it'll take: - * 1 (prepare operand) + 4 (bl) + 2 (subs+cmp) + 1 (bne) + 3 (b) -> - * 11 tacts == 1.4us with 8MHz - * every extra iteration will take 5 tacts == 0.6us */ -delay: - subs r6, r6, #1 - cmp r6, #0 - bne delay - bx lr diff --git a/contrib/loaders/flash/mrvlqspi_write.S b/contrib/loaders/flash/mrvlqspi_write.S deleted file mode 100644 index 064192c9c..000000000 --- a/contrib/loaders/flash/mrvlqspi_write.S +++ /dev/null @@ -1,232 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2014 by Mahavir Jain * - * * - * Adapted from (contrib/loaders/flash/lpcspifi_write.S): * - * Copyright (C) 2012 by George Harris * - * george@luminairecoffee.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - ***************************************************************************/ - - .text - .syntax unified - .cpu cortex-m3 - .thumb - .thumb_func - -/* - * For compilation: - * arm-none-eabi-gcc -mcpu=cortex-m3 -mthumb -c contrib/loaders/flash/mrvlqspi_write.S - * arm-none-eabi-objcopy -O binary mrvlqspi_write.o code.bin - * Copy code.bin into mrvlqspi flash driver - */ - -/* - * Params : - * r0 = workarea start, status (out) - * r1 = workarea end - * r2 = target address (offset from flash base) - * r3 = count (bytes) - * r4 = page size - * r5 = qspi base address - * Clobbered: - * r7 - rp - * r8 - wp, tmp - * r9 - send/receive data - * r10 - current page end address - */ - -#define CNTL 0x0 -#define CONF 0x4 -#define DOUT 0x8 -#define DIN 0xc -#define INSTR 0x10 -#define ADDR 0x14 -#define RDMODE 0x18 -#define HDRCNT 0x1c -#define DINCNT 0x20 - -#define SS_EN (1 << 0) -#define XFER_RDY (1 << 1) -#define RFIFO_EMPTY (1 << 4) -#define WFIFO_EMPTY (1 << 6) -#define WFIFO_FULL (1 << 7) -#define FIFO_FLUSH (1 << 9) -#define RW_EN (1 << 13) -#define XFER_STOP (1 << 14) -#define XFER_START (1 << 15) - -#define INS_WRITE_ENABLE 0x06 -#define INS_READ_STATUS 0x05 -#define INS_PAGE_PROGRAM 0x02 - -init: - mov.w r10, #0x00 -find_next_page_boundary: - add r10, r4 /* Increment to the next page */ - cmp r10, r2 - /* If we have not reached the next page boundary after the target address, keep going */ - bls find_next_page_boundary -write_enable: - /* Flush read/write fifo's */ - bl flush_fifo - - /* Instruction byte 1 */ - movs r8, #0x1 - str r8, [r5, #HDRCNT] - - /* Set write enable instruction */ - movs r8, #INS_WRITE_ENABLE - str r8, [r5, #INSTR] - - movs r9, #0x1 - bl start_tx - bl stop_tx -page_program: - /* Instruction byte 1, Addr byte 3 */ - movs r8, #0x31 - str r8, [r5, #HDRCNT] - /* Todo: set addr and data pin to single */ -write_address: - mov r8, r2 - str r8, [r5, #ADDR] - /* Set page program instruction */ - movs r8, #INS_PAGE_PROGRAM - str r8, [r5, #INSTR] - /* Start write transfer */ - movs r9, #0x1 - bl start_tx -wait_fifo: - ldr r8, [r0] /* read the write pointer */ - cmp r8, #0 /* if it's zero, we're gonzo */ - beq exit - ldr r7, [r0, #4] /* read the read pointer */ - cmp r7, r8 /* wait until they are not equal */ - beq wait_fifo -write: - ldrb r9, [r7], #0x01 /* Load one byte from the FIFO, increment the read pointer by 1 */ - bl write_data /* send the byte to the flash chip */ - - cmp r7, r1 /* wrap the read pointer if it is at the end */ - it cs - addcs r7, r0, #8 /* skip loader args */ - str r7, [r0, #4] /* store the new read pointer */ - subs r3, r3, #1 /* decrement count */ - cmp r3, #0 /* Exit if we have written everything */ - beq write_wait - add r2, #1 /* Increment flash address by 1 */ - cmp r10, r2 /* See if we have reached the end of a page */ - bne wait_fifo /* If not, keep writing bytes */ -write_wait: - bl stop_tx /* Otherwise, end the command and keep going w/ the next page */ - add r10, r4 /* Move up the end-of-page address by the page size*/ -check_flash_busy: /* Wait for the flash to finish the previous page write */ - /* Flush read/write fifo's */ - bl flush_fifo - /* Instruction byte 1 */ - movs r8, #0x1 - str r8, [r5, #HDRCNT] - /* Continuous data in of status register */ - movs r8, #0x0 - str r8, [r5, #DINCNT] - /* Set write enable instruction */ - movs r8, #INS_READ_STATUS - str r8, [r5, #INSTR] - /* Start read transfer */ - movs r9, #0x0 - bl start_tx -wait_flash_busy: - bl read_data - and.w r9, r9, #0x1 - cmp r9, #0x0 - bne.n wait_flash_busy - bl stop_tx - cmp r3, #0 - bne.n write_enable /* If it is done, start a new page write */ - b exit /* All data written, exit */ - -write_data: /* Send/receive 1 byte of data over QSPI */ - ldr r8, [r5, #CNTL] - lsls r8, r8, #24 - bmi.n write_data - str r9, [r5, #DOUT] - bx lr - -read_data: /* Read 1 byte of data over QSPI */ - ldr r8, [r5, #CNTL] - lsls r8, r8, #27 - bmi.n read_data - ldr r9, [r5, #DIN] - bx lr - -flush_fifo: /* Flush read write fifos */ - ldr r8, [r5, #CONF] - orr.w r8, r8, #FIFO_FLUSH - str r8, [r5, #CONF] -flush_reset: - ldr r8, [r5, #CONF] - lsls r8, r8, #22 - bmi.n flush_reset - bx lr - -start_tx: - ldr r8, [r5, #CNTL] - orr.w r8, r8, #SS_EN - str r8, [r5, #CNTL] -xfer_rdy: - ldr r8, [r5, #CNTL] - lsls r8, r8, #30 - bpl.n xfer_rdy - ldr r8, [r5, #CONF] - bfi r8, r9, #13, #1 - orr.w r8, r8, #XFER_START - str r8, [r5, #CONF] - bx lr - -stop_tx: - ldr r8, [r5, #CNTL] - lsls r8, r8, #30 - bpl.n stop_tx -wfifo_wait: - ldr r8, [r5, #CNTL] - lsls r8, r8, #25 - bpl.n wfifo_wait - ldr r8, [r5, #CONF] - orr.w r8, r8, #XFER_STOP - str r8, [r5, #CONF] -xfer_start: - ldr r8, [r5, #CONF] - lsls r8, r8, #16 - bmi.n xfer_start -ss_disable: - # Disable SS_EN - ldr r8, [r5, #CNTL] - bic.w r8, r8, #SS_EN - str r8, [r5, #CNTL] -wait: - ldr r8, [r5, #CNTL] - lsls r8, r8, #30 - bpl.n wait - bx lr - -error: - movs r0, #0 - str r0, [r2, #4] /* set rp = 0 on error */ -exit: - mov r0, r6 - bkpt #0x00 - - .end diff --git a/contrib/loaders/flash/pic32mx.s b/contrib/loaders/flash/pic32mx.s deleted file mode 100644 index 9f41965c7..000000000 --- a/contrib/loaders/flash/pic32mx.s +++ /dev/null @@ -1,132 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2010 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - ***************************************************************************/ - - .text - .arch m4k - .set noreorder - .set noat - -/* params: - * $a0 src adr - ram + result - * $a1 dest adr - flash - * $a2 count (32bit words) - * vars - * - * temps: - * $t0, $t1, $t2, $t3, $t4, $t5 - * $s0, $s1, $s3, $s4, $s5 - */ - - .type main, @function - .global main - -.ent main -main: - /* setup constants */ - lui $t0, 0xaa99 - ori $t0, 0x6655 /* NVMKEY1 */ - lui $t1, 0x5566 - ori $t1, 0x99AA /* NVMKEY2 */ - lui $t2, 0xBF80 - ori $t2, 0xF400 /* NVMCON */ - ori $t3, $zero, 0x4003 /* NVMCON row write cmd */ - ori $t4, $zero, 0x8000 /* NVMCON start cmd */ - -write_row: - /* can we perform a row write: 128 32bit words */ - sltiu $s3, $a2, 128 - bne $s3, $zero, write_word - ori $t5, $zero, 0x4000 /* NVMCON clear cmd */ - - /* perform row write 512 bytes */ - sw $a1, 32($t2) /* set NVMADDR with dest addr - real addr */ - sw $a0, 64($t2) /* set NVMSRCADDR with src addr - real addr */ - - bal progflash - addiu $a0, $a0, 512 - addiu $a1, $a1, 512 - beq $zero, $zero, write_row - addiu $a2, $a2, -128 - -write_word: - /* write 32bit words */ - lui $s5, 0xa000 - ori $s5, 0x0000 - or $a0, $a0, $s5 /* convert to virtual addr */ - - beq $zero, $zero, next_word - ori $t3, $zero, 0x4001 /* NVMCON word write cmd */ - -prog_word: - lw $s4, 0($a0) /* load data - from virtual addr */ - sw $s4, 48($t2) /* set NVMDATA with data */ - sw $a1, 32($t2) /* set NVMADDR with dest addr - real addr */ - - bal progflash - addiu $a0, $a0, 4 - addiu $a1, $a1, 4 - addiu $a2, $a2, -1 -next_word: - bne $a2, $zero, prog_word - nop - -done: - beq $zero, $zero, exit - addiu $a0, $zero, 0 - -error: - /* save result to $a0 */ - addiu $a0, $s1, 0 - -exit: - sdbbp -.end main - - .type progflash, @function - .global progflash - -.ent progflash -progflash: - sw $t3, 0($t2) /* set NVMWREN */ - sw $t0, 16($t2) /* write NVMKEY1 */ - sw $t1, 16($t2) /* write NVMKEY2 */ - sw $t4, 8($t2) /* start operation */ - -waitflash: - lw $s0, 0($t2) - and $s0, $s0, $t4 - bne $s0, $zero, waitflash - nop - - /* following is to comply with errata #34 - * 500ns delay required */ - nop - nop - nop - nop - /* check for errors */ - lw $s1, 0($t2) - andi $s1, $zero, 0x3000 - bne $s1, $zero, error - sw $t5, 4($t2) /* clear NVMWREN */ - jr $ra - nop - -.end progflash diff --git a/contrib/loaders/flash/sim3x.s b/contrib/loaders/flash/sim3x.s deleted file mode 100644 index cdb3ef681..000000000 --- a/contrib/loaders/flash/sim3x.s +++ /dev/null @@ -1,81 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2014 by Ladislav Bábel * - * ladababel@seznam.cz * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - ***************************************************************************/ - -#define INITIAL_UNLOCK 0x5A -#define MULTIPLE_UNLOCK 0xF2 - -#define FLASHCTRL_KEY 0x4002E0C0 -#define FLASHCTRL_CONFIG 0x4002E000 -#define FLASHCTRL_WRADDR 0x4002E0A0 -#define FLASHCTRL_WRDATA 0x4002E0B0 -#define BUSYF 0x00100000 - - - /* Write the initial unlock value to KEY (0xA5) */ - movs r6, #INITIAL_UNLOCK - str r6, [r0, #FLASHCTRL_KEY] - - /* Write the multiple unlock value to KEY (0xF2) */ - movs r6, #MULTIPLE_UNLOCK - str r6, [r0, #FLASHCTRL_KEY] - -wait_fifo: - ldr r6, [r2, #0] - cmp r6, #0 - beq exit - ldr r5, [r2, #4] - cmp r5, r6 - beq wait_fifo - - /* wait for BUSYF flag */ -wait_busy1: - ldr r6, [r0, #FLASHCTRL_CONFIG] - tst r6, #BUSYF - bne wait_busy1 - - /* Write the destination address to WRADDR */ - str r4, [r0, #FLASHCTRL_WRADDR] - - /* Write the data half-word to WRDATA in right-justified format */ - ldrh r6, [r5] - str r6, [r0, #FLASHCTRL_WRDATA] - - adds r5, #2 - adds r4, #2 - - /* wrap rp at end of buffer */ - cmp r5, r3 - bcc no_wrap - mov r5, r2 - adds r5, #8 - -no_wrap: - str r5, [r2, #4] - subs r1, r1, #1 - cmp r1, #0 - beq exit - b wait_fifo - -exit: - movs r6, #MULTIPLE_LOCK - str r6, [r0, #FLASHCTRL_KEY] - - /* wait for BUSYF flag */ -wait_busy2: - ldr r6, [r0, #FLASHCTRL_CONFIG] - tst r6, #BUSYF - bne wait_busy2 - - bkpt #0 diff --git a/contrib/loaders/flash/stellaris.s b/contrib/loaders/flash/stellaris.s deleted file mode 100644 index 6e1ed69cd..000000000 --- a/contrib/loaders/flash/stellaris.s +++ /dev/null @@ -1,78 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2006 by Magnus Lundin * - * lundin@mlu.mine.nu * - * * - * Copyright (C) 2008 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - ***************************************************************************/ - - .text - .syntax unified - .cpu cortex-m3 - .thumb - .thumb_func - -/* - * Params : - * r0 = workarea start - * r1 = workarea end - * r2 = target address - * r3 = count (32bit words) - * - * Clobbered: - * r4 = pFLASH_CTRL_BASE - * r5 = FLASHWRITECMD - * r7 - rp - * r8 - wp, tmp - */ - -write: - ldr r4, pFLASH_CTRL_BASE - ldr r5, FLASHWRITECMD - -wait_fifo: - ldr r8, [r0, #0] /* read wp */ - cmp r8, #0 /* abort if wp == 0 */ - beq exit - ldr r7, [r0, #4] /* read rp */ - cmp r7, r8 /* wait until rp != wp */ - beq wait_fifo - -mainloop: - str r2, [r4, #0] /* FMA - write address */ - add r2, r2, #4 /* increment target address */ - ldr r8, [r7], #4 - str r8, [r4, #4] /* FMD - write data */ - str r5, [r4, #8] /* FMC - enable write */ -busy: - ldr r8, [r4, #8] - tst r8, #1 - bne busy - - cmp r7, r1 /* wrap rp at end of buffer */ - it cs - addcs r7, r0, #8 /* skip loader args */ - str r7, [r0, #4] /* store rp */ - subs r3, r3, #1 /* decrement word count */ - cbz r3, exit /* loop if not done */ - b wait_fifo -exit: - bkpt #0 - -pFLASH_CTRL_BASE: .word 0x400FD000 -FLASHWRITECMD: .word 0xA4420001 diff --git a/contrib/loaders/flash/stm32f1x.S b/contrib/loaders/flash/stm32f1x.S deleted file mode 100644 index 5ce463d1b..000000000 --- a/contrib/loaders/flash/stm32f1x.S +++ /dev/null @@ -1,76 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2011 by Andreas Fritiofson * - * andreas.fritiofson@gmail.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - ***************************************************************************/ - - .text - .syntax unified - .cpu cortex-m0 - .thumb - .thumb_func - .global write - - /* Params: - * r0 - flash base (in), status (out) - * r1 - count (halfword-16bit) - * r2 - workarea start - * r3 - workarea end - * r4 - target address - * Clobbered: - * r5 - rp - * r6 - wp, tmp - * r7 - tmp - */ - -#define STM32_FLASH_SR_OFFSET 0x0c /* offset of SR register from flash reg base */ - -wait_fifo: - ldr r6, [r2, #0] /* read wp */ - cmp r6, #0 /* abort if wp == 0 */ - beq exit - ldr r5, [r2, #4] /* read rp */ - cmp r5, r6 /* wait until rp != wp */ - beq wait_fifo - ldrh r6, [r5] /* "*target_address++ = *rp++" */ - strh r6, [r4] - adds r5, #2 - adds r4, #2 -busy: - ldr r6, [r0, #STM32_FLASH_SR_OFFSET] /* wait until BSY flag is reset */ - movs r7, #1 - tst r6, r7 - bne busy - movs r7, #0x14 /* check the error bits */ - tst r6, r7 - bne error - cmp r5, r3 /* wrap rp at end of buffer */ - bcc no_wrap - mov r5, r2 - adds r5, #8 -no_wrap: - str r5, [r2, #4] /* store rp */ - subs r1, r1, #1 /* decrement halfword count */ - cmp r1, #0 - beq exit /* loop if not done */ - b wait_fifo -error: - movs r0, #0 - str r0, [r2, #4] /* set rp = 0 on error */ -exit: - mov r0, r6 /* return status in r0 */ - bkpt #0 diff --git a/contrib/loaders/flash/stm32f2x.S b/contrib/loaders/flash/stm32f2x.S deleted file mode 100644 index 0dd122319..000000000 --- a/contrib/loaders/flash/stm32f2x.S +++ /dev/null @@ -1,81 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2010 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * Copyright (C) 2011 Øyvind Harboe * - * oyvind.harboe@zylin.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - ***************************************************************************/ - - .text - .syntax unified - .cpu cortex-m3 - .thumb - .thumb_func - -/* - * Params : - * r0 = workarea start, status (out) - * r1 = workarea end - * r2 = target address - * r3 = count (16bit words) - * r4 = flash base - * - * Clobbered: - * r6 - temp - * r7 - rp - * r8 - wp, tmp - */ - -#define STM32_FLASH_CR_OFFSET 0x10 /* offset of CR register in FLASH struct */ -#define STM32_FLASH_SR_OFFSET 0x0c /* offset of SR register in FLASH struct */ - -wait_fifo: - ldr r8, [r0, #0] /* read wp */ - cmp r8, #0 /* abort if wp == 0 */ - beq exit - ldr r7, [r0, #4] /* read rp */ - cmp r7, r8 /* wait until rp != wp */ - beq wait_fifo - - ldr r6, STM32_PROG16 - str r6, [r4, #STM32_FLASH_CR_OFFSET] - ldrh r6, [r7], #0x02 /* read one half-word from src, increment ptr */ - strh r6, [r2], #0x02 /* write one half-word from src, increment ptr */ - dsb -busy: - ldr r6, [r4, #STM32_FLASH_SR_OFFSET] - tst r6, #0x10000 /* BSY (bit16) == 1 => operation in progress */ - bne busy /* wait more... */ - tst r6, #0xf0 /* PGSERR | PGPERR | PGAERR | WRPERR */ - bne error /* fail... */ - - cmp r7, r1 /* wrap rp at end of buffer */ - it cs - addcs r7, r0, #8 /* skip loader args */ - str r7, [r0, #4] /* store rp */ - subs r3, r3, #1 /* decrement halfword count */ - cbz r3, exit /* loop if not done */ - b wait_fifo -error: - movs r1, #0 - str r1, [r0, #4] /* set rp = 0 on error */ -exit: - mov r0, r6 /* return status in r0 */ - bkpt #0x00 - -STM32_PROG16: .word 0x101 /* PG | PSIZE_16*/ diff --git a/contrib/loaders/flash/stm32l4x.S b/contrib/loaders/flash/stm32l4x.S deleted file mode 100644 index 799dec527..000000000 --- a/contrib/loaders/flash/stm32l4x.S +++ /dev/null @@ -1,100 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2010 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * Copyright (C) 2011 Øyvind Harboe * - * oyvind.harboe@zylin.com * - * * - * Copyright (C) 2015 Uwe Bonnes * - * bon@elektron.ikp.physik.tu-darmstadt.de * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc. * - ***************************************************************************/ - - .text - .syntax unified - .cpu cortex-m4 - .thumb - .thumb_func - -/* To assemble: - * arm-none-eabi-gcc -c stm32l4x.S - * - * To disassemble: - * arm-none-eabi-objdump -o stm32l4x.o - * - * To generate binary file: - * arm-none-eabi-objcopy -O binary stm32l4x.o stm32l4_flash_write_code.bin - * - * To generate include file: - * xxd -i stm32l4_flash_write_code.bin - */ - -/* - * Params : - * r0 = workarea start, status (out) - * r1 = workarea end - * r2 = target address - * r3 = count (64bit words) - * r4 = flash base - * - * Clobbered: - * r5 - rp - * r6/7 - temp (64-bit) - * r8 - wp, tmp - */ - -#define STM32_FLASH_CR_OFFSET 0x14 /* offset of CR register in FLASH struct */ -#define STM32_FLASH_SR_OFFSET 0x10 /* offset of SR register in FLASH struct */ - -wait_fifo: - ldr r8, [r0, #0] /* read wp */ - cmp r8, #0 /* abort if wp == 0 */ - beq exit - ldr r5, [r0, #4] /* read rp */ - subs r6, r8, r5 /* number of bytes available for read in r6*/ - itt mi /* if wrapped around*/ - addmi r6, r1 /* add size of buffer */ - submi r6, r0 - cmp r6, #8 /* wait until 8 bytes are available */ - bcc wait_fifo - - ldr r6, STM32_PROG - str r6, [r4, #STM32_FLASH_CR_OFFSET] - ldrd r6, [r5], #0x08 /* read one word from src, increment ptr */ - strd r6, [r2], #0x08 /* write one word to dst, increment ptr */ - dsb -busy: - ldr r6, [r4, #STM32_FLASH_SR_OFFSET] - tst r6, #0x10000 /* BSY (bit16) == 1 => operation in progress */ - bne busy /* wait more... */ - tst r6, #0xfa /* PGSERR | PGPERR | PGAERR | WRPERR | PROGERR*/ - bne error /* fail... */ - - cmp r5, r1 /* wrap rp at end of buffer */ - it cs - addcs r5, r0, #8 /* skip loader args */ - str r5, [r0, #4] /* store rp */ - subs r3, r3, #1 /* decrement dword count */ - cbz r3, exit /* loop if not done */ - b wait_fifo -error: - movs r1, #0 - str r1, [r0, #4] /* set rp = 0 on error */ -exit: - mov r0, r6 /* return status in r0 */ - bkpt #0x00 - -STM32_PROG: .word 0x1 /* PG */ diff --git a/contrib/loaders/flash/stm32lx.S b/contrib/loaders/flash/stm32lx.S deleted file mode 100644 index 88deed32e..000000000 --- a/contrib/loaders/flash/stm32lx.S +++ /dev/null @@ -1,63 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2010 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * Copyright (C) 2011 Øyvind Harboe * - * oyvind.harboe@zylin.com * - * * - * Copyright (C) 2011 Clement Burin des Roziers * - * clement.burin-des-roziers@hikob.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - ***************************************************************************/ - - -// Build : arm-eabi-gcc -c stm32lx.S - .text - .syntax unified - .cpu cortex-m3 - .thumb - .thumb_func - .global write - -/* - r0 - destination address - r1 - source address - r2 - count -*/ - - // Set 0 to r3 - movs r3, #0 - // Go to compare - b.n test_done - -write_word: - // Load one word from address in r0, increment by 4 - ldr.w ip, [r1], #4 - // Store the word to address in r1, increment by 4 - str.w ip, [r0], #4 - // Increment r3 - adds r3, #1 - -test_done: - // Compare r3 and r2 - cmp r3, r2 - // Loop if not zero - bcc.n write_word - - // Set breakpoint to exit - bkpt #0x00 - diff --git a/contrib/loaders/flash/str7x.s b/contrib/loaders/flash/str7x.s deleted file mode 100644 index a163ee674..000000000 --- a/contrib/loaders/flash/str7x.s +++ /dev/null @@ -1,59 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2010 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - ***************************************************************************/ - - .text - .arm - .arch armv4t - - .section .init -/* - r0 source address - r1 address - r2 FLASH_CR0 - r3 dword count - r4 result - r5 busy mask -*/ - -write: - mov r4, #0x10000000 /* set DWPG bit */ - str r4, [r2, #0x0] /* FLASH_CR0 */ - str r1, [r2, #0x10] /* FLASH_AR */ - ldr r4, [r0], #4 /* load data */ - str r4, [r2, #0x8] /* FLASH_DR0 */ - ldr r4, [r0], #4 /* load data */ - str r4, [r2, #0xc] /* FLASH_DR1 */ - mov r4, #0x90000000 /* set DWPG and WMS bits */ - str r4, [r2, #0x0] /* FLASH_CR0 */ -busy: - ldr r4, [r2, #0x0] /* FLASH_CR0 */ - tst r4, r5 - bne busy - ldr r4, [r2, #0x14] /* FLASH_ER */ - tst r4, #0xff /* do we have errors */ - tsteq r4, #0x100 /* write protection set */ - bne exit - add r1, r1, #0x8 /* next 8 bytes */ - subs r3, r3, #1 /* decremment dword count */ - bne write -exit: - b exit - - .end diff --git a/contrib/loaders/flash/str9x.s b/contrib/loaders/flash/str9x.s deleted file mode 100644 index 4daac7731..000000000 --- a/contrib/loaders/flash/str9x.s +++ /dev/null @@ -1,56 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2010 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - ***************************************************************************/ - - .text - .arm - .arch armv5t - - .section .init -/* - r0 source address (in) - r1 target address (in) - r2 word count (in) - r3 result (out) -*/ - -write: - bic r4, r1, #3 /* word address */ - mov r3, #0x40 /* write command */ - strh r3, [r4, #0] - ldrh r3, [r0], #2 /* read data */ - strh r3, [r1], #2 /* write data */ - mov r3, #0x70 /* status command */ - strh r3, [r4, #0] -busy: - ldrb r3, [r4, #0] /* status */ - tst r3, #0x80 - beq busy - mov r5, #0x50 /* clear status command */ - strh r5, [r4, #0] - mov r5, #0xFF /* read array */ - strh r5, [r4, #0] - tst r3, #0x12 - bne exit - subs r2, r2, #1 /* decremment word count */ - bne write -exit: - bkpt #0 - - .end diff --git a/contrib/loaders/flash/xmc1xxx/Makefile b/contrib/loaders/flash/xmc1xxx/Makefile deleted file mode 100644 index b97c602d0..000000000 --- a/contrib/loaders/flash/xmc1xxx/Makefile +++ /dev/null @@ -1,32 +0,0 @@ -BIN2C = ../../../../src/helper/bin2char.sh - -CROSS_COMPILE ?= arm-none-eabi- - -CC=$(CROSS_COMPILE)gcc -OBJCOPY=$(CROSS_COMPILE)objcopy -OBJDUMP=$(CROSS_COMPILE)objdump - -CFLAGS = -static -nostartfiles -mlittle-endian -Wa,-EL - -all: erase.inc erase_check.inc write.inc - -.PHONY: clean - -.INTERMEDIATE: erase.elf erase_check.elf write.elf - -erase.elf erase_check.elf write.elf: xmc1xxx.S - -%.elf: %.S - $(CC) $(CFLAGS) $< -o $@ - -%.lst: %.elf - $(OBJDUMP) -S $< > $@ - -%.bin: %.elf - $(OBJCOPY) -Obinary $< $@ - -%.inc: %.bin - $(BIN2C) < $< > $@ - -clean: - -rm -f *.elf *.lst *.bin *.inc diff --git a/contrib/loaders/flash/xmc1xxx/erase.S b/contrib/loaders/flash/xmc1xxx/erase.S deleted file mode 100644 index e5a4808fc..000000000 --- a/contrib/loaders/flash/xmc1xxx/erase.S +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Infineon XMC1000 flash sectors erase - * - * Copyright (c) 2016 Andreas Färber - * - * Based on XMC1100 AA-Step Reference Manual - * - * License: GPL-2.0+ - */ - -#include "xmc1xxx.S" - -#define DUMMY_VALUE 0x42 - - .macro erase_page, nvmbase, addr, tmp, tmp2 - - movs \tmp, #DUMMY_VALUE - str \tmp, [\addr] - - busy_wait \nvmbase, \tmp, \tmp2 - - .endm - - - .macro erase, nvmbase, addr, end, tmp, tmp2 - - movs \tmp, #NVMPROG_ACTION_PAGE_ERASE_CONTINUOUS - strh \tmp, [\nvmbase, #NVMPROG] -2001: - erase_page \nvmbase, \addr, \tmp, \tmp2 - - movs \tmp, #(NVM_PAGE_SIZE - 1) - adds \tmp, \tmp, #1 - add \addr, \addr, \tmp - cmp \addr, \end - blt 2001b - - movs \tmp, #NVMPROG_ACTION_IDLE - strh \tmp, [\nvmbase, #NVMPROG] - - .endm - - - /* - * r0 = 0x40050000 - * r1 = e.g. 0x10001000 - * r2 = e.g. 0x10011000 - * NVMPROG.ACTION = 0x00 - */ -erase: - erase r0, r1, r2, r3, r4 - - bkpt #0 diff --git a/contrib/loaders/flash/xmc1xxx/erase.inc b/contrib/loaders/flash/xmc1xxx/erase.inc deleted file mode 100644 index b33e57d1f..000000000 --- a/contrib/loaders/flash/xmc1xxx/erase.inc +++ /dev/null @@ -1,4 +0,0 @@ -/* Autogenerated with ../../../../src/helper/bin2char.sh */ -0xa2,0x23,0x83,0x80,0x42,0x23,0x0b,0x60,0x03,0x88,0x01,0x24,0x23,0x40,0xa3,0x42, -0xfa,0xd0,0xff,0x23,0x01,0x33,0x19,0x44,0x91,0x42,0xf3,0xdb,0x00,0x23,0x83,0x80, -0x00,0xbe, diff --git a/contrib/loaders/flash/xmc1xxx/erase_check.S b/contrib/loaders/flash/xmc1xxx/erase_check.S deleted file mode 100644 index 6c993443a..000000000 --- a/contrib/loaders/flash/xmc1xxx/erase_check.S +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Infineon XMC1000 flash sector erase check - * - * Copyright (c) 2016 Andreas Färber - * - * Based on XMC1100 AA-Step Reference Manual - * - * License: GPL-2.0+ - */ - -#include "xmc1xxx.S" - - .macro verify_block, nvmbase, addr, tmp, tmp2 - - movs \tmp, #0x00 - mvns \tmp, \tmp - str \tmp, [\addr, #0x0] - str \tmp, [\addr, #0x4] - str \tmp, [\addr, #0x8] - str \tmp, [\addr, #0xC] - - busy_wait \nvmbase, \tmp, \tmp2 - - .endm - - - .macro erase_check, nvmbase, addr, end, tmp, tmp2 - - ldrh \tmp, [\nvmbase, #NVMCONF] - movs \tmp2, #NVMCONF_HRLEV_MASK - mvns \tmp2, \tmp2 - ands \tmp, \tmp, \tmp2 - movs \tmp2, #NVMCONF_HRLEV_HRE - orrs \tmp, \tmp, \tmp2 - strh \tmp, [\nvmbase, #NVMCONF] - - movs \tmp, #NVMPROG_ACTION_VERIFY_CONTINUOUS - strh \tmp, [\nvmbase, #NVMPROG] -2001: - verify_block \nvmbase, \addr, \tmp, \tmp2 - - ldrh \tmp, [\nvmbase, #NVMSTATUS] - movs \tmp2, #NVMSTATUS_VERR_MASK - ands \tmp, \tmp, \tmp2 - cmp \tmp, #NVMSTATUS_VERR_NOFAIL - bne 2010f - - adds \addr, \addr, #NVM_BLOCK_SIZE - cmp \addr, \end - blt 2001b -2010: - movs \tmp, #NVMPROG_ACTION_IDLE - strh \tmp, [\nvmbase, #NVMPROG] - - .endm - - - /* - * r0 = 0x40050000 - * r1 = e.g. 0x10001000 - * r2 = e.g. 0x10002000 - * NVMPROG.ACTION = 0x00 - */ -erase_check: - erase_check r0, r1, r2, r3, r4 - - bkpt #0 diff --git a/contrib/loaders/flash/xmc1xxx/erase_check.inc b/contrib/loaders/flash/xmc1xxx/erase_check.inc deleted file mode 100644 index 8fc8e0b5d..000000000 --- a/contrib/loaders/flash/xmc1xxx/erase_check.inc +++ /dev/null @@ -1,5 +0,0 @@ -/* Autogenerated with ../../../../src/helper/bin2char.sh */ -0x03,0x89,0x06,0x24,0xe4,0x43,0x23,0x40,0x04,0x24,0x23,0x43,0x03,0x81,0xe0,0x23, -0x83,0x80,0x00,0x23,0xdb,0x43,0x0b,0x60,0x4b,0x60,0x8b,0x60,0xcb,0x60,0x03,0x88, -0x01,0x24,0x23,0x40,0xa3,0x42,0xfa,0xd0,0x03,0x88,0x0c,0x24,0x23,0x40,0x00,0x2b, -0x02,0xd1,0x10,0x31,0x91,0x42,0xec,0xdb,0x00,0x23,0x83,0x80,0x00,0xbe, diff --git a/contrib/loaders/flash/xmc1xxx/write.S b/contrib/loaders/flash/xmc1xxx/write.S deleted file mode 100644 index 640f6ca96..000000000 --- a/contrib/loaders/flash/xmc1xxx/write.S +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Infineon XMC1000 flash write - * - * Copyright (c) 2016 Andreas Färber - * - * Based on XMC1100 AA-Step Reference Manual - * - * License: GPL-2.0+ - */ - -#include "xmc1xxx.S" - - .macro write_block, nvmbase, dest, src, tmp, tmp2 - - ldr \tmp, [\src, #0x0] - str \tmp, [\dest, #0x0] - ldr \tmp, [\src, #0x4] - str \tmp, [\dest, #0x4] - ldr \tmp, [\src, #0x8] - str \tmp, [\dest, #0x8] - ldr \tmp, [\src, #0xc] - str \tmp, [\dest, #0xc] - - busy_wait \nvmbase, \tmp, \tmp2 - - .endm - - - .macro write, nvmbase, dest, src, count, tmp, tmp2 - - movs \tmp, #NVMPROG_ACTION_WRITE_CONTINUOUS - strh \tmp, [\nvmbase, #NVMPROG] -1001: - write_block \nvmbase, \dest, \src, \tmp, \tmp2 - - adds \dest, \dest, #NVM_BLOCK_SIZE - adds \src, \src, #NVM_BLOCK_SIZE - subs \count, \count, #1 - cmp \count, #0 - bgt 1001b - - movs \tmp, #NVMPROG_ACTION_IDLE - strh \tmp, [\nvmbase, #NVMPROG] - - .endm - - - /* - * r0 = 0x40050000 - * r1 = e.g. 0x10001000 - * r2 = e.g. 0x20000000 - * r3 = e.g. 1 - * NVMPROG.ACTION = 0x00 - */ -write: - write r0, r1, r2, r3, r4, r5 - - bkpt #0 diff --git a/contrib/loaders/flash/xmc1xxx/write.inc b/contrib/loaders/flash/xmc1xxx/write.inc deleted file mode 100644 index 8272bb7e7..000000000 --- a/contrib/loaders/flash/xmc1xxx/write.inc +++ /dev/null @@ -1,4 +0,0 @@ -/* Autogenerated with ../../../../src/helper/bin2char.sh */ -0xa1,0x24,0x84,0x80,0x14,0x68,0x0c,0x60,0x54,0x68,0x4c,0x60,0x94,0x68,0x8c,0x60, -0xd4,0x68,0xcc,0x60,0x04,0x88,0x01,0x25,0x2c,0x40,0xac,0x42,0xfa,0xd0,0x10,0x31, -0x10,0x32,0x01,0x3b,0x00,0x2b,0xed,0xdc,0x00,0x24,0x84,0x80,0x00,0xbe, diff --git a/contrib/loaders/flash/xmc1xxx/xmc1xxx.S b/contrib/loaders/flash/xmc1xxx/xmc1xxx.S deleted file mode 100644 index dfe7d3f41..000000000 --- a/contrib/loaders/flash/xmc1xxx/xmc1xxx.S +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Infineon XMC1000 flash - * - * Copyright (c) 2016 Andreas Färber - * - * Based on XMC1100 AA-Step Reference Manual - * - * License: GPL-2.0+ - */ - - .text - .syntax unified - .cpu cortex-m0 - .thumb - .thumb_func - -#define NVMSTATUS 0x00 -#define NVMPROG 0x04 -#define NVMCONF 0x08 - -#define NVMSTATUS_BUSY (1 << 0) -#define NVMSTATUS_VERR_NOFAIL (0x0 << 2) -#define NVMSTATUS_VERR_MASK (0x3 << 2) - -#define NVMPROG_ACTION_IDLE 0x00 -#define NVMPROG_ACTION_WRITE_CONTINUOUS 0xA1 -#define NVMPROG_ACTION_PAGE_ERASE_CONTINUOUS 0xA2 -#define NVMPROG_ACTION_VERIFY_CONTINUOUS 0xE0 - -#define NVMCONF_HRLEV_NR (0x0 << 1) -#define NVMCONF_HRLEV_HRE (0x2 << 1) -#define NVMCONF_HRLEV_MASK (0x3 << 1) - -#define NVM_WORD_SIZE 4 -#define NVM_BLOCK_SIZE (4 * NVM_WORD_SIZE) -#define NVM_PAGE_SIZE (16 * NVM_BLOCK_SIZE) - - .macro busy_wait, nvmbase, tmp, tmp2 -1: - ldrh \tmp, [\nvmbase, #NVMSTATUS] - movs \tmp2, #NVMSTATUS_BUSY - ands \tmp, \tmp, \tmp2 - cmp \tmp, \tmp2 - beq 1b - - .endm diff --git a/contrib/loaders/watchdog/Makefile b/contrib/loaders/watchdog/Makefile deleted file mode 100644 index 623e74407..000000000 --- a/contrib/loaders/watchdog/Makefile +++ /dev/null @@ -1,21 +0,0 @@ -BIN2C = ../../../src/helper/bin2char.sh - -ARM_CROSS_COMPILE ?= arm-none-eabi- -ARM_AS ?= $(ARM_CROSS_COMPILE)as -ARM_OBJCOPY ?= $(ARM_CROSS_COMPILE)objcopy - -ARM_AFLAGS = -EL -mthumb - -arm: armv7m_kinetis_wdog.inc - -armv7m_%.elf: armv7m_%.s - $(ARM_AS) $(ARM_AFLAGS) $< -o $@ - -armv7m_%.bin: armv7m_%.elf - $(ARM_OBJCOPY) -Obinary $< $@ - -armv7m_%.inc: armv7m_%.bin - $(BIN2C) < $< > $@ - -clean: - -rm -f *.elf *.bin *.inc diff --git a/contrib/loaders/watchdog/armv7m_kinetis_wdog.inc b/contrib/loaders/watchdog/armv7m_kinetis_wdog.inc deleted file mode 100644 index 4b6579e0c..000000000 --- a/contrib/loaders/watchdog/armv7m_kinetis_wdog.inc +++ /dev/null @@ -1,4 +0,0 @@ -/* Autogenerated with ../../../src/helper/bin2char.sh */ -0x04,0x4b,0x05,0x4a,0xda,0x81,0x05,0x4a,0xda,0x81,0x01,0x24,0x1a,0x88,0xa2,0x43, -0x1a,0x80,0x06,0xe0,0x00,0x20,0x05,0x40,0x20,0xc5,0x00,0x00,0x28,0xd9,0x00,0x00, -0x00,0x00,0x00,0xbe, diff --git a/contrib/loaders/watchdog/armv7m_kinetis_wdog.s b/contrib/loaders/watchdog/armv7m_kinetis_wdog.s deleted file mode 100644 index bac924ab8..000000000 --- a/contrib/loaders/watchdog/armv7m_kinetis_wdog.s +++ /dev/null @@ -1,64 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2015 Tomas Vanek * - * vanekt@fbl.cz * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc. * - ***************************************************************************/ - -/* - Disable watchdog for Kinetis Kx and KVx - Parameters: none - Used instruction set should work on both Cortex-M4 and M0+ -*/ - - .text - .syntax unified - .cpu cortex-m0 - .thumb - -WDOG_ADDR = 0x40052000 -/* WDOG registers offsets */ -WDOG_STCTRLH = 0 -WDOG_UNLOCK = 0x0e - -WDOG_KEY1 = 0xc520 -WDOG_KEY2 = 0xd928 - - .thumb_func -start: -/* WDOG_UNLOCK = 0xC520 */ - ldr r3, =WDOG_ADDR - ldr r2, =WDOG_KEY1 - strh r2, [r3, WDOG_UNLOCK] -/* WDOG_UNLOCK = 0xD928 */ - ldr r2, =WDOG_KEY2 - strh r2, [r3, WDOG_UNLOCK] -/* WDOG_STCTRLH clear bit 0 */ - movs r4, #1 - ldrh r2, [r3, WDOG_STCTRLH] - bics r2, r4 - strh r2, [r3, WDOG_STCTRLH] -/* OpenOCD checks exit point address. Jump to the very end. */ - b done - - .pool - -/* Avoid padding at .text segment end. Otherwise exit point check fails. */ - .skip ( . - start + 2) & 2, 0 -done: - bkpt #0 - - .end - diff --git a/contrib/remote_bitbang/remote_bitbang_sysfsgpio.c b/contrib/remote_bitbang/remote_bitbang_sysfsgpio.c deleted file mode 100644 index e59a1bdeb..000000000 --- a/contrib/remote_bitbang/remote_bitbang_sysfsgpio.c +++ /dev/null @@ -1,408 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2013 Paul Fertser * - * Copyright (C) 2012 by Creative Product Design, marc @ cpdesign.com.au * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - ***************************************************************************/ - -/* - This is a test application to be used as a remote bitbang server for - the OpenOCD remote_bitbang interface driver. - - To compile run: - gcc -Wall -ansi -pedantic -std=c99 -o remote_bitbang_sysfsgpio remote_bitbang_sysfsgpio.c - - - Usage example: - - On Raspberry Pi run: - socat TCP6-LISTEN:7777,fork EXEC:"sudo ./remote_bitbang_sysfsgpio tck 11 tms 25 tdo 9 tdi 10" - - On host run: - openocd -c "interface remote_bitbang; remote_bitbang_host raspberrypi; remote_bitbang_port 7777" \ - -f target/stm32f1x.cfg - - Or if you want to test UNIX sockets, run both on Raspberry Pi: - socat UNIX-LISTEN:/tmp/remotebitbang-socket,fork EXEC:"sudo ./remote_bitbang_sysfsgpio tck 11 tms 25 tdo 9 tdi 10" - openocd -c "interface remote_bitbang; remote_bitbang_host /tmp/remotebitbang-socket" -f target/stm32f1x.cfg -*/ - -#include -#include -#include -#include -#include -#include -#include -#include - -#define LOG_ERROR(...) do { \ - fprintf(stderr, __VA_ARGS__); \ - fputc('\n', stderr); \ - } while (0) -#define LOG_WARNING(...) LOG_ERROR(__VA_ARGS__) - -#define ERROR_OK (-1) -#define ERROR_FAIL (-2) -#define ERROR_JTAG_INIT_FAILED ERROR_FAIL - -/* - * Helper func to determine if gpio number valid - * - * Assume here that there will be less than 1000 gpios on a system - */ -static int is_gpio_valid(int gpio) -{ - return gpio >= 0 && gpio < 1000; -} - -/* - * Helper func to open, write to and close a file - * name and valstr must be null terminated. - * - * Returns negative on failure. - */ -static int open_write_close(const char *name, const char *valstr) -{ - int ret; - int fd = open(name, O_WRONLY); - if (fd < 0) - return fd; - - ret = write(fd, valstr, strlen(valstr)); - close(fd); - - return ret; -} - -/* - * Helper func to unexport gpio from sysfs - */ -static void unexport_sysfs_gpio(int gpio) -{ - char gpiostr[4]; - - if (!is_gpio_valid(gpio)) - return; - - snprintf(gpiostr, sizeof(gpiostr), "%d", gpio); - if (open_write_close("/sys/class/gpio/unexport", gpiostr) < 0) - LOG_ERROR("Couldn't unexport gpio %d", gpio); - - return; -} - -/* - * Exports and sets up direction for gpio. - * If the gpio is an output, it is initialized according to init_high, - * otherwise it is ignored. - * - * If the gpio is already exported we just show a warning and continue; if - * openocd happened to crash (or was killed by user) then the gpios will not - * have been cleaned up. - */ -static int setup_sysfs_gpio(int gpio, int is_output, int init_high) -{ - char buf[40]; - char gpiostr[4]; - int ret; - - if (!is_gpio_valid(gpio)) - return ERROR_OK; - - snprintf(gpiostr, sizeof(gpiostr), "%d", gpio); - ret = open_write_close("/sys/class/gpio/export", gpiostr); - if (ret < 0) { - if (errno == EBUSY) { - LOG_WARNING("gpio %d is already exported", gpio); - } else { - LOG_ERROR("Couldn't export gpio %d", gpio); - perror("sysfsgpio: "); - return ERROR_FAIL; - } - } - - snprintf(buf, sizeof(buf), "/sys/class/gpio/gpio%d/direction", gpio); - ret = open_write_close(buf, is_output ? (init_high ? "high" : "low") : "in"); - if (ret < 0) { - LOG_ERROR("Couldn't set direction for gpio %d", gpio); - perror("sysfsgpio: "); - unexport_sysfs_gpio(gpio); - return ERROR_FAIL; - } - - snprintf(buf, sizeof(buf), "/sys/class/gpio/gpio%d/value", gpio); - if (is_output) - ret = open(buf, O_WRONLY | O_NONBLOCK | O_SYNC); - else - ret = open(buf, O_RDONLY | O_NONBLOCK | O_SYNC); - - if (ret < 0) - unexport_sysfs_gpio(gpio); - - return ret; -} - -/* - * file descriptors for /sys/class/gpio/gpioXX/value - * Set up during init. - */ -static int tck_fd = -1; -static int tms_fd = -1; -static int tdi_fd = -1; -static int tdo_fd = -1; -static int trst_fd = -1; -static int srst_fd = -1; - -/* - * Bitbang interface read of TDO - * - * The sysfs value will read back either '0' or '1'. The trick here is to call - * lseek to bypass buffering in the sysfs kernel driver. - */ -static int sysfsgpio_read(void) -{ - char buf[1]; - - /* important to seek to signal sysfs of new read */ - lseek(tdo_fd, 0, SEEK_SET); - int ret = read(tdo_fd, &buf, sizeof(buf)); - - if (ret < 0) { - LOG_WARNING("reading tdo failed"); - return 0; - } - - return buf[0]; -} - -/* - * Bitbang interface write of TCK, TMS, TDI - * - * Seeing as this is the only function where the outputs are changed, - * we can cache the old value to avoid needlessly writing it. - */ -static void sysfsgpio_write(int tck, int tms, int tdi) -{ - const char one[] = "1"; - const char zero[] = "0"; - - static int last_tck; - static int last_tms; - static int last_tdi; - - static int first_time; - size_t bytes_written; - - if (!first_time) { - last_tck = !tck; - last_tms = !tms; - last_tdi = !tdi; - first_time = 1; - } - - if (tdi != last_tdi) { - bytes_written = write(tdi_fd, tdi ? &one : &zero, 1); - if (bytes_written != 1) - LOG_WARNING("writing tdi failed"); - } - - if (tms != last_tms) { - bytes_written = write(tms_fd, tms ? &one : &zero, 1); - if (bytes_written != 1) - LOG_WARNING("writing tms failed"); - } - - /* write clk last */ - if (tck != last_tck) { - bytes_written = write(tck_fd, tck ? &one : &zero, 1); - if (bytes_written != 1) - LOG_WARNING("writing tck failed"); - } - - last_tdi = tdi; - last_tms = tms; - last_tck = tck; -} - -/* - * Bitbang interface to manipulate reset lines SRST and TRST - * - * (1) assert or (0) deassert reset lines - */ -static void sysfsgpio_reset(int trst, int srst) -{ - const char one[] = "1"; - const char zero[] = "0"; - size_t bytes_written; - - /* assume active low */ - if (srst_fd >= 0) { - bytes_written = write(srst_fd, srst ? &zero : &one, 1); - if (bytes_written != 1) - LOG_WARNING("writing srst failed"); - } - - /* assume active low */ - if (trst_fd >= 0) { - bytes_written = write(trst_fd, trst ? &zero : &one, 1); - if (bytes_written != 1) - LOG_WARNING("writing trst failed"); - } -} - -/* gpio numbers for each gpio. Negative values are invalid */ -static int tck_gpio = -1; -static int tms_gpio = -1; -static int tdi_gpio = -1; -static int tdo_gpio = -1; -static int trst_gpio = -1; -static int srst_gpio = -1; - -/* helper func to close and cleanup files only if they were valid/ used */ -static void cleanup_fd(int fd, int gpio) -{ - if (gpio >= 0) { - if (fd >= 0) - close(fd); - - unexport_sysfs_gpio(gpio); - } -} - -static void cleanup_all_fds(void) -{ - cleanup_fd(tck_fd, tck_gpio); - cleanup_fd(tms_fd, tms_gpio); - cleanup_fd(tdi_fd, tdi_gpio); - cleanup_fd(tdo_fd, tdo_gpio); - cleanup_fd(trst_fd, trst_gpio); - cleanup_fd(srst_fd, srst_gpio); -} - -static void process_remote_protocol(void) -{ - int c; - while (1) { - c = getchar(); - if (c == EOF || c == 'Q') /* Quit */ - break; - else if (c == 'b' || c == 'B') /* Blink */ - continue; - else if (c >= 'r' && c <= 'r' + 2) { /* Reset */ - char d = c - 'r'; - sysfsgpio_reset(!!(d & 2), - (d & 1)); - } else if (c >= '0' && c <= '0' + 7) {/* Write */ - char d = c - '0'; - sysfsgpio_write(!!(d & 4), - !!(d & 2), - (d & 1)); - } else if (c == 'R') - putchar(sysfsgpio_read()); - else - LOG_ERROR("Unknown command '%c' received", c); - } -} - -int main(int argc, char *argv[]) -{ - LOG_WARNING("SysfsGPIO remote_bitbang JTAG driver\n"); - - for (int i = 1; i < argc; i++) { - if (!strcmp(argv[i], "tck")) - tck_gpio = atoi(argv[++i]); - else if (!strcmp(argv[i], "tms")) - tms_gpio = atoi(argv[++i]); - else if (!strcmp(argv[i], "tdo")) - tdo_gpio = atoi(argv[++i]); - else if (!strcmp(argv[i], "tdi")) - tdi_gpio = atoi(argv[++i]); - else if (!strcmp(argv[i], "trst")) - trst_gpio = atoi(argv[++i]); - else if (!strcmp(argv[i], "srst")) - srst_gpio = atoi(argv[++i]); - else { - LOG_ERROR("Usage:\n%s ((tck|tms|tdo|tdi|trst|srst) num)*", argv[0]); - return -1; - } - } - - if (!(is_gpio_valid(tck_gpio) - && is_gpio_valid(tms_gpio) - && is_gpio_valid(tdi_gpio) - && is_gpio_valid(tdo_gpio))) { - if (!is_gpio_valid(tck_gpio)) - LOG_ERROR("gpio num for tck is invalid"); - if (!is_gpio_valid(tms_gpio)) - LOG_ERROR("gpio num for tms is invalid"); - if (!is_gpio_valid(tdo_gpio)) - LOG_ERROR("gpio num for tdo is invalid"); - if (!is_gpio_valid(tdi_gpio)) - LOG_ERROR("gpio num for tdi is invalid"); - - LOG_ERROR("Require tck, tms, tdi and tdo gpios to all be specified"); - return ERROR_JTAG_INIT_FAILED; - } - - /* - * Configure TDO as an input, and TDI, TCK, TMS, TRST, SRST - * as outputs. Drive TDI and TCK low, and TMS/TRST/SRST high. - */ - tck_fd = setup_sysfs_gpio(tck_gpio, 1, 0); - if (tck_fd < 0) - goto out_error; - - tms_fd = setup_sysfs_gpio(tms_gpio, 1, 1); - if (tms_fd < 0) - goto out_error; - - tdi_fd = setup_sysfs_gpio(tdi_gpio, 1, 0); - if (tdi_fd < 0) - goto out_error; - - tdo_fd = setup_sysfs_gpio(tdo_gpio, 0, 0); - if (tdo_fd < 0) - goto out_error; - - /* assume active low */ - if (trst_gpio > 0) { - trst_fd = setup_sysfs_gpio(trst_gpio, 1, 1); - if (trst_fd < 0) - goto out_error; - } - - /* assume active low */ - if (srst_gpio > 0) { - srst_fd = setup_sysfs_gpio(srst_gpio, 1, 1); - if (srst_fd < 0) - goto out_error; - } - - LOG_WARNING("SysfsGPIO nums: tck = %d, tms = %d, tdi = %d, tdo = %d", - tck_gpio, tms_gpio, tdi_gpio, tdo_gpio); - LOG_WARNING("SysfsGPIO num: srst = %d", srst_gpio); - LOG_WARNING("SysfsGPIO num: trst = %d", trst_gpio); - - setvbuf(stdout, NULL, _IONBF, 0); - process_remote_protocol(); - - cleanup_all_fds(); - return 0; -out_error: - cleanup_all_fds(); - return ERROR_JTAG_INIT_FAILED; -} diff --git a/contrib/rpc_examples/ocd_rpc_example.py b/contrib/rpc_examples/ocd_rpc_example.py deleted file mode 100755 index 6c8529cdc..000000000 --- a/contrib/rpc_examples/ocd_rpc_example.py +++ /dev/null @@ -1,145 +0,0 @@ -#!/usr/bin/env python3 -""" -OpenOCD RPC example, covered by GNU GPLv3 or later -Copyright (C) 2014 Andreas Ortmann (ortmann@finf.uni-hannover.de) - - -Example output: -./ocd_rpc_example.py -echo says hi! - -target state: halted -target halted due to debug-request, current mode: Thread -xPSR: 0x01000000 pc: 0x00000188 msp: 0x10000fd8 - -variable @ 0x10000000: 0x01c9c380 - -variable @ 0x10000000: 0xdeadc0de - -memory (before): ['0xdeadc0de', '0x00000011', '0xaaaaaaaa', '0x00000023', -'0x00000042', '0x0000ffff'] - -memory (after): ['0x00000001', '0x00000000', '0xaaaaaaaa', '0x00000023', -'0x00000042', '0x0000ffff'] -""" - -import socket -import itertools - -def strToHex(data): - return map(strToHex, data) if isinstance(data, list) else int(data, 16) - -def hexify(data): - return "" if data is None else ("0x%08x" % data) - -def compareData(a, b): - for i, j, num in zip(a, b, itertools.count(0)): - if i != j: - print("difference at %d: %s != %s" % (num, hexify(i), hexify(j))) - - -class OpenOcd: - COMMAND_TOKEN = '\x1a' - def __init__(self, verbose=False): - self.verbose = verbose - self.tclRpcIp = "127.0.0.1" - self.tclRpcPort = 6666 - self.bufferSize = 4096 - - self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - - def __enter__(self): - self.sock.connect((self.tclRpcIp, self.tclRpcPort)) - return self - - def __exit__(self, type, value, traceback): - try: - self.send("exit") - finally: - self.sock.close() - - def send(self, cmd): - """Send a command string to TCL RPC. Return the result that was read.""" - data = (cmd + OpenOcd.COMMAND_TOKEN).encode("utf-8") - if self.verbose: - print("<- ", data) - - self.sock.send(data) - return self._recv() - - def _recv(self): - """Read from the stream until the token (\x1a) was received.""" - data = bytes() - while True: - chunk = self.sock.recv(self.bufferSize) - data += chunk - if bytes(OpenOcd.COMMAND_TOKEN, encoding="utf-8") in chunk: - break - - if self.verbose: - print("-> ", data) - - data = data.decode("utf-8").strip() - data = data[:-1] # strip trailing \x1a - - return data - - def readVariable(self, address): - raw = self.send("ocd_mdw 0x%x" % address).split(": ") - return None if (len(raw) < 2) else strToHex(raw[1]) - - def readMemory(self, wordLen, address, n): - self.send("array unset output") # better to clear the array before - self.send("mem2array output %d 0x%x %d" % (wordLen, address, n)) - - output = self.send("ocd_echo $output").split(" ") - - return [int(output[2*i+1]) for i in range(len(output)//2)] - - def writeVariable(self, address, value): - assert value is not None - self.send("mww 0x%x 0x%x" % (address, value)) - - def writeMemory(self, wordLen, address, n, data): - array = " ".join(["%d 0x%x" % (a, b) for a, b in enumerate(data)]) - - self.send("array unset 1986ве1т") # better to clear the array before - self.send("array set 1986ве1т { %s }" % array) - self.send("array2mem 1986ве1т 0x%x %s %d" % (wordLen, address, n)) - -if __name__ == "__main__": - - def show(*args): - print(*args, end="\n\n") - - with OpenOcd() as ocd: - ocd.send("reset") - - show(ocd.send("ocd_echo \"echo says hi!\"")[:-1]) - show(ocd.send("capture \"ocd_halt\"")[:-1]) - - # Read the first few words at the RAM region (put starting adress of RAM - # region into 'addr') - addr = 0x10000000 - - value = ocd.readVariable(addr) - show("variable @ %s: %s" % (hexify(addr), hexify(value))) - - ocd.writeVariable(addr, 0xdeadc0de) - show("variable @ %s: %s" % (hexify(addr), hexify(ocd.readVariable(addr)))) - - data = [1, 0, 0xaaaaaaaa, 0x23, 0x42, 0xffff] - wordlen = 32 - n = len(data) - - read = ocd.readMemory(wordlen, addr, n) - show("memory (before):", list(map(hexify, read))) - - ocd.writeMemory(wordlen, addr, n, data) - - read = ocd.readMemory(wordlen, addr, n) - show("memory (after):", list(map(hexify, read))) - - compareData(read, data) - - ocd.send("resume") diff --git a/contrib/rpc_examples/ocdrpc.hs b/contrib/rpc_examples/ocdrpc.hs deleted file mode 100644 index 27fb1ae60..000000000 --- a/contrib/rpc_examples/ocdrpc.hs +++ /dev/null @@ -1,56 +0,0 @@ --- OpenOCD RPC example, covered by GNU GPLv3 or later --- Copyright (C) 2014 Paul Fertser --- --- Example output: --- $ ./ocdrpc --- Halting the target, full log output captured: --- target state: halted --- target halted due to debug-request, current mode: Thread --- xPSR: 0x21000000 pc: 0x00003352 msp: 0x20000fe8 --- --- Read memory, parse the result and show as a list of strings: --- ["0x20001000","0x0000334d","0x00002abb","0x0000118f","0x00002707","0x00002707","0x00002707","0x00000000","0x00000000","0x00000000","0x00000000","0x00002707","0x00002707","0x00000000","0x00002707","0x00002781"] --- Resuming - -{-# LANGUAGE OverloadedStrings #-} -module Main where - -import Prelude -import Control.Applicative -import Network.Socket -import System.IO.Streams.Core hiding (connect) -import System.IO.Streams.Network -import System.IO.Streams.Attoparsec -import Data.Attoparsec.ByteString.Char8 -import Data.Attoparsec.Combinator -import Data.ByteString.Char8 hiding (putStrLn, concat, map) -import Text.Printf - -ocdReply = manyTill anyChar (char '\x1a') - -ocdExec (oistream, oostream) command = do - write (Just $ pack $ command ++ "\x1a") oostream - parseFromStream ocdReply oistream - --- For each line: dispose of address, then match hex values -mdwParser = (manyTill anyChar (string ": ") *> - hexadecimal `sepBy` char ' ') - `sepBy` string " \n" - -ocdMdw :: (InputStream ByteString, OutputStream ByteString) -> Integer -> Integer -> IO [Integer] -ocdMdw s start count = do - s <- ocdExec s $ "ocd_mdw " ++ show start ++ " " ++ show count - case parseOnly mdwParser (pack s) of - Right r -> return $ concat r - -main = do - osock <- socket AF_INET Stream defaultProtocol - haddr <- inet_addr "127.0.0.1" - connect osock (SockAddrInet 6666 haddr) - ostreams <- socketToStreams osock - putStrLn "Halting the target, full log output captured:" - ocdExec ostreams "capture \"halt\"" >>= putStrLn - putStrLn "Read memory, parse the result and show as a list of strings:" - ocdMdw ostreams 0 16 >>= putStrLn . (show :: [String] -> String) . map (printf "0x%08x") - putStrLn "Resuming" - ocdExec ostreams "resume" diff --git a/contrib/rtos-helpers/FreeRTOS-openocd.c b/contrib/rtos-helpers/FreeRTOS-openocd.c deleted file mode 100644 index 81a3ab77a..000000000 --- a/contrib/rtos-helpers/FreeRTOS-openocd.c +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Since at least FreeRTOS V7.5.3 uxTopUsedPriority is no longer - * present in the kernel, so it has to be supplied by other means for - * OpenOCD's threads awareness. - * - * Add this file to your project, and, if you're using --gc-sections, - * ``--undefined=uxTopUsedPriority'' (or - * ``-Wl,--undefined=uxTopUsedPriority'' when using gcc for final - * linking) to your LDFLAGS; same with all the other symbols you need. - */ - -#include "FreeRTOS.h" - -#ifdef __GNUC__ -#define USED __attribute__((used)) -#else -#define USED -#endif - -const int USED uxTopUsedPriority = configMAX_PRIORITIES - 1; diff --git a/contrib/xsvf_tools/svf2xsvf.py b/contrib/xsvf_tools/svf2xsvf.py deleted file mode 100644 index 113e0a61a..000000000 --- a/contrib/xsvf_tools/svf2xsvf.py +++ /dev/null @@ -1,729 +0,0 @@ -#!/usr/bin/python3.0 - -# Copyright 2008, SoftPLC Corporation http://softplc.com -# Dick Hollenbeck dick@softplc.com - - -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, you may find one here: -# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html -# or you may search the http://www.gnu.org website for the version 2 license, -# or you may write to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - - -# A python program to convert an SVF file to an XSVF file. There is an -# option to include comments containing the source file line number from the origin -# SVF file before each outputted XSVF statement. -# -# We deviate from the XSVF spec in that we introduce a new command called -# XWAITSTATE which directly flows from the SVF RUNTEST command. Unfortunately -# XRUNSTATE was ill conceived and is not used here. We also add support for the -# three Lattice extensions to SVF: LCOUNT, LDELAY, and LSDR. The xsvf file -# generated from this program is suitable for use with the xsvf player in -# OpenOCD with my modifications to xsvf.c. -# -# This program is written for python 3.0, and it is not easy to change this -# back to 2.x. You may find it easier to use python 3.x even if that means -# building it. - - -import re -import sys -import struct - - -# There are both ------ and ------ sections to this program - - -if len( sys.argv ) < 3: - print("usage %s " % sys.argv[0]) - exit(1) - - -inputFilename = sys.argv[1] -outputFilename = sys.argv[2] - -doCOMMENTs = True # Save XCOMMENTs in the output xsvf file -#doCOMMENTs = False # Save XCOMMENTs in the output xsvf file - -# pick your file encoding -file_encoding = 'ISO-8859-1' -#file_encoding = 'utf-8' - - -xrepeat = 0 # argument to XREPEAT, gives retry count for masked compares - - -#-----< Lexer >--------------------------------------------------------------- - -StateBin = (RESET,IDLE, - DRSELECT,DRCAPTURE,DRSHIFT,DREXIT1,DRPAUSE,DREXIT2,DRUPDATE, - IRSELECT,IRCAPTURE,IRSHIFT,IREXIT1,IRPAUSE,IREXIT2,IRUPDATE) = range(16) - -# Any integer index into this tuple will be equal to its corresponding StateBin value -StateTxt = ("RESET","IDLE", - "DRSELECT","DRCAPTURE","DRSHIFT","DREXIT1","DRPAUSE","DREXIT2","DRUPDATE", - "IRSELECT","IRCAPTURE","IRSHIFT","IREXIT1","IRPAUSE","IREXIT2","IRUPDATE") - - -(XCOMPLETE,XTDOMASK,XSIR,XSDR,XRUNTEST,hole0,hole1,XREPEAT,XSDRSIZE,XSDRTDO, - XSETSDRMASKS,XSDRINC,XSDRB,XSDRC,XSDRE,XSDRTDOB,XSDRTDOC, - XSDRTDOE,XSTATE,XENDIR,XENDDR,XSIR2,XCOMMENT,XWAIT,XWAITSTATE, - LCOUNT,LDELAY,LSDR,XTRST) = range(29) - -#Note: LCOUNT, LDELAY, and LSDR are Lattice extensions to SVF and provide a way to loop back -# and check a completion status, essentially waiting on a part until it signals that it is done. -# For example below: loop 25 times, each time through the loop do a LDELAY (same as a true RUNTEST) -# and exit loop when LSDR compares match. -""" -LCOUNT 25; -! Step to DRPAUSE give 5 clocks and wait for 1.00e+000 SEC. -LDELAY DRPAUSE 5 TCK 1.00E-003 SEC; -! Test for the completed status. Match means pass. -! Loop back to LDELAY line if not match and loop count less than 25. -LSDR 1 TDI (0) - TDO (1); -""" - -#XTRST is an opcode Xilinx seemed to have missed and it comes from the SVF TRST statement. - -LineNumber = 1 - -def s_ident(scanner, token): return ("ident", token.upper(), LineNumber) - -def s_hex(scanner, token): - global LineNumber - LineNumber = LineNumber + token.count('\n') - token = ''.join(token.split()) - return ("hex", token[1:-1], LineNumber) - -def s_int(scanner, token): return ("int", int(token), LineNumber) -def s_float(scanner, token): return ("float", float(token), LineNumber) -#def s_comment(scanner, token): return ("comment", token, LineNumber) -def s_semicolon(scanner, token): return ("semi", token, LineNumber) - -def s_nl(scanner,token): - global LineNumber - LineNumber = LineNumber + 1 - #print( 'LineNumber=', LineNumber, file=sys.stderr ) - return None - -#2.00E-002 - -scanner = re.Scanner([ - (r"[a-zA-Z]\w*", s_ident), -# (r"[-+]?[0-9]+[.]?[0-9]*([eE][-+]?[0-9]+)?", s_float), - (r"[-+]?[0-9]+(([.][0-9eE+-]*)|([eE]+[-+]?[0-9]+))", s_float), - (r"\d+", s_int), - (r"\(([0-9a-fA-F]|\s)*\)", s_hex), - (r"(!|//).*$", None), - (r";", s_semicolon), - (r"\n",s_nl), - (r"\s*", None), - ], - re.MULTILINE - ) - -# open the file using the given encoding -file = open( sys.argv[1], encoding=file_encoding ) - -# read all svf file input into string "input" -input = file.read() - -file.close() - -# Lexer: -# create a list of tuples containing (tokenType, tokenValue, LineNumber) -tokens = scanner.scan( input )[0] - -input = None # allow gc to reclaim memory holding file - -#for tokenType, tokenValue, ln in tokens: print( "line %d: %s" % (ln, tokenType), tokenValue ) - - -#---------------------------------------------------------------------- - -tokVal = tokType = tokLn = None - -tup = iter( tokens ) - -def nextTok(): - """ - Function to read the next token from tup into tokType, tokVal, tokLn (linenumber) - which are globals. - """ - global tokType, tokVal, tokLn, tup - tokType, tokVal, tokLn = tup.__next__() - - -class ParseError(Exception): - """A class to hold a parsing error message""" - def __init__(self, linenumber, token, message): - self.linenumber = linenumber - self.token = token - self.message = message - def __str__(self): - global inputFilename - return "Error in file \'%s\' at line %d near token %s\n %s" % ( - inputFilename, self.linenumber, repr(self.token), self.message) - - -class MASKSET(object): - """ - Class MASKSET holds a set of bit vectors, all of which are related, will all - have the same length, and are associated with one of the seven shiftOps: - HIR, HDR, TIR, TDR, SIR, SDR, LSDR. One of these holds a mask, smask, tdi, tdo, and a - size. - """ - def __init__(self, name): - self.empty() - self.name = name - - def empty(self): - self.mask = bytearray() - self.smask = bytearray() - self.tdi = bytearray() - self.tdo = bytearray() - self.size = 0 - - def syncLengths( self, sawTDI, sawTDO, sawMASK, sawSMASK, newSize ): - """ - Set all the lengths equal in the event some of the masks were - not seen as part of the last change set. - """ - if self.size == newSize: - return - - if newSize == 0: - self.empty() - return - - # If an SIR was given without a MASK(), then use a mask of all zeros. - # this is not consistent with the SVF spec, but it makes sense because - # it would be odd to be testing an instruction register read out of a - # tap without giving a mask for it. Also, lattice seems to agree and is - # generating SVF files that comply with this philosophy. - if self.name == 'SIR' and not sawMASK: - self.mask = bytearray( newSize ) - - if newSize != len(self.mask): - self.mask = bytearray( newSize ) - if self.name == 'SDR': # leave mask for HIR,HDR,TIR,TDR,SIR zeros - for i in range( newSize ): - self.mask[i] = 1 - - if newSize != len(self.tdo): - self.tdo = bytearray( newSize ) - - if newSize != len(self.tdi): - self.tdi = bytearray( newSize ) - - if newSize != len(self.smask): - self.smask = bytearray( newSize ) - - self.size = newSize -#---------- - - -def makeBitArray( hexString, bitCount ): - """ - Converts a packed sequence of hex ascii characters into a bytearray where - each element in the array holds exactly one bit. Only "bitCount" bits are - scanned and these must be the least significant bits in the hex number. That - is, it is legal to have some unused bits in the must significant hex nibble - of the input "hexString". The string is scanned starting from the backend, - then just before returning we reverse the array. This way the append() - method can be used, which I assume is faster than an insert. - """ - global tokLn - a = bytearray() - length = bitCount - hexString = list(hexString) - hexString.reverse() - #print(hexString) - for c in hexString: - if length <= 0: - break; - c = int(c, 16) - for mask in [1,2,4,8]: - if length <= 0: - break; - length = length - 1 - a.append( (c & mask) != 0 ) - if length > 0: - raise ParseError( tokLn, hexString, "Insufficient hex characters for given length of %d" % bitCount ) - a.reverse() - #print(a) - return a - - -def makeXSVFbytes( bitarray ): - """ - Make a bytearray which is contains the XSVF bits which will be written - directly to disk. The number of bytes needed is calculated from the size - of the argument bitarray. - """ - bitCount = len(bitarray) - byteCount = (bitCount+7)//8 - ba = bytearray( byteCount ) - firstBit = (bitCount % 8) - 1 - if firstBit == -1: - firstBit = 7 - bitNdx = 0 - for byteNdx in range(byteCount): - mask = 1<> 1 - bitNdx = bitNdx + 1 - ba[byteNdx] = byte - firstBit = 7 - return ba - - -def writeComment( outputFile, shiftOp_linenum, shiftOp ): - """ - Write an XCOMMENT record to outputFile - """ - comment = "%s @%d\0" % (shiftOp, shiftOp_linenum) # \0 is terminating nul - ba = bytearray(1) - ba[0] = XCOMMENT - ba += comment.encode() - outputFile.write( ba ) - - -def combineBitVectors( trailer, meat, header ): - """ - Combine the 3 bit vectors comprizing a transmission. Since the least - significant bits are sent first, the header is put onto the list last so - they are sent first from that least significant position. - """ - ret = bytearray() - ret.extend( trailer ) - ret.extend( meat ) - ret.extend( header ) - return ret - - -def writeRUNTEST( outputFile, run_state, end_state, run_count, min_time, tokenTxt ): - """ - Write the output for the SVF RUNTEST command. - run_count - the number of clocks - min_time - the number of seconds - tokenTxt - either RUNTEST or LDELAY - """ - # convert from secs to usecs - min_time = int( min_time * 1000000) - - # the SVF RUNTEST command does NOT map to the XSVF XRUNTEST command. Check the SVF spec, then - # read the XSVF command. They are not the same. Use an XSVF XWAITSTATE to - # implement the required behavior of the SVF RUNTEST command. - if doCOMMENTs: - writeComment( output, tokLn, tokenTxt ) - - if tokenTxt == 'RUNTEST': - obuf = bytearray(11) - obuf[0] = XWAITSTATE - obuf[1] = run_state - obuf[2] = end_state - struct.pack_into(">i", obuf, 3, run_count ) # big endian 4 byte int to obuf - struct.pack_into(">i", obuf, 7, min_time ) # big endian 4 byte int to obuf - outputFile.write( obuf ) - else: # == 'LDELAY' - obuf = bytearray(10) - obuf[0] = LDELAY - obuf[1] = run_state - # LDELAY has no end_state - struct.pack_into(">i", obuf, 2, run_count ) # big endian 4 byte int to obuf - struct.pack_into(">i", obuf, 6, min_time ) # big endian 4 byte int to obuf - outputFile.write( obuf ) - - -output = open( outputFilename, mode='wb' ) - -hir = MASKSET('HIR') -hdr = MASKSET('HDR') -tir = MASKSET('TIR') -tdr = MASKSET('TDR') -sir = MASKSET('SIR') -sdr = MASKSET('SDR') - - -expecting_eof = True - - -# one of the commands that take the shiftParts after the length, the parse -# template for all of these commands is identical -shiftOps = ('SDR', 'SIR', 'LSDR', 'HDR', 'HIR', 'TDR', 'TIR') - -# the order must correspond to shiftOps, this holds the MASKSETS. 'LSDR' shares sdr with 'SDR' -shiftSets = (sdr, sir, sdr, hdr, hir, tdr, tir ) - -# what to expect as parameters to a shiftOp, i.e. after a SDR length or SIR length -shiftParts = ('TDI', 'TDO', 'MASK', 'SMASK') - -# the set of legal states which can trail the RUNTEST command -run_state_allowed = ('IRPAUSE', 'DRPAUSE', 'RESET', 'IDLE') - -enddr_state_allowed = ('DRPAUSE', 'IDLE') -endir_state_allowed = ('IRPAUSE', 'IDLE') - -trst_mode_allowed = ('ON', 'OFF', 'Z', 'ABSENT') - -enddr_state = IDLE -endir_state = IDLE - -frequency = 1.00e+006 # HZ; - -# change detection for xsdrsize and xtdomask -xsdrsize = -1 # the last one sent, send only on change -xtdomask = bytearray() # the last one sent, send only on change - - -# we use a number of single byte writes for the XSVF command below -cmdbuf = bytearray(1) - - -# Save the XREPEAT setting into the file as first thing. -obuf = bytearray(2) -obuf[0] = XREPEAT -obuf[1] = xrepeat -output.write( obuf ) - - -try: - while 1: - expecting_eof = True - nextTok() - expecting_eof = False - # print( tokType, tokVal, tokLn ) - - if tokVal in shiftOps: - shiftOp_linenum = tokLn - shiftOp = tokVal - - set = shiftSets[shiftOps.index(shiftOp)] - - # set flags false, if we see one later, set that one true later - sawTDI = sawTDO = sawMASK = sawSMASK = False - - nextTok() - if tokType != 'int': - raise ParseError( tokLn, tokVal, "Expecting 'int' giving %s length, got '%s'" % (shiftOp, tokType) ) - length = tokVal - - nextTok() - - while tokVal != ';': - if tokVal not in shiftParts: - raise ParseError( tokLn, tokVal, "Expecting TDI, TDO, MASK, SMASK, or ';'") - shiftPart = tokVal - - nextTok() - - if tokType != 'hex': - raise ParseError( tokLn, tokVal, "Expecting hex bits" ) - bits = makeBitArray( tokVal, length ) - - if shiftPart == 'TDI': - sawTDI = True - set.tdi = bits - - elif shiftPart == 'TDO': - sawTDO = True - set.tdo = bits - - elif shiftPart == 'MASK': - sawMASK = True - set.mask = bits - - elif shiftPart == 'SMASK': - sawSMASK = True - set.smask = bits - - nextTok() - - set.syncLengths( sawTDI, sawTDO, sawMASK, sawSMASK, length ) - - # process all the gathered parameters and generate outputs here - if shiftOp == 'SIR': - if doCOMMENTs: - writeComment( output, shiftOp_linenum, 'SIR' ) - - tdi = combineBitVectors( tir.tdi, sir.tdi, hir.tdi ) - if len(tdi) > 255: - obuf = bytearray(3) - obuf[0] = XSIR2 - struct.pack_into( ">h", obuf, 1, len(tdi) ) - else: - obuf = bytearray(2) - obuf[0] = XSIR - obuf[1] = len(tdi) - output.write( obuf ) - obuf = makeXSVFbytes( tdi ) - output.write( obuf ) - - elif shiftOp == 'SDR': - if doCOMMENTs: - writeComment( output, shiftOp_linenum, shiftOp ) - - if not sawTDO: - # pass a zero filled bit vector for the sdr.mask - mask = combineBitVectors( tdr.mask, bytearray(sdr.size), hdr.mask ) - tdi = combineBitVectors( tdr.tdi, sdr.tdi, hdr.tdi ) - - if xsdrsize != len(tdi): - xsdrsize = len(tdi) - cmdbuf[0] = XSDRSIZE - output.write( cmdbuf ) - obuf = bytearray(4) - struct.pack_into( ">i", obuf, 0, xsdrsize ) # big endian 4 byte int to obuf - output.write( obuf ) - - if xtdomask != mask: - xtdomask = mask - cmdbuf[0] = XTDOMASK - output.write( cmdbuf ) - obuf = makeXSVFbytes( mask ) - output.write( obuf ) - - cmdbuf[0] = XSDR - output.write( cmdbuf ) - obuf = makeXSVFbytes( tdi ) - output.write( obuf ) - - else: - mask = combineBitVectors( tdr.mask, sdr.mask, hdr.mask ) - tdi = combineBitVectors( tdr.tdi, sdr.tdi, hdr.tdi ) - tdo = combineBitVectors( tdr.tdo, sdr.tdo, hdr.tdo ) - - if xsdrsize != len(tdi): - xsdrsize = len(tdi) - cmdbuf[0] = XSDRSIZE - output.write( cmdbuf ) - obuf = bytearray(4) - struct.pack_into(">i", obuf, 0, xsdrsize ) # big endian 4 byte int to obuf - output.write( obuf ) - - if xtdomask != mask: - xtdomask = mask - cmdbuf[0] = XTDOMASK - output.write( cmdbuf ) - obuf = makeXSVFbytes( mask ) - output.write( obuf ) - - cmdbuf[0] = XSDRTDO - output.write( cmdbuf ) - obuf = makeXSVFbytes( tdi ) - output.write( obuf ) - obuf = makeXSVFbytes( tdo ) - output.write( obuf ) - #print( "len(tdo)=", len(tdo), "len(tdr.tdo)=", len(tdr.tdo), "len(sdr.tdo)=", len(sdr.tdo), "len(hdr.tdo)=", len(hdr.tdo) ) - - elif shiftOp == 'LSDR': - if doCOMMENTs: - writeComment( output, shiftOp_linenum, shiftOp ) - - mask = combineBitVectors( tdr.mask, sdr.mask, hdr.mask ) - tdi = combineBitVectors( tdr.tdi, sdr.tdi, hdr.tdi ) - tdo = combineBitVectors( tdr.tdo, sdr.tdo, hdr.tdo ) - - if xsdrsize != len(tdi): - xsdrsize = len(tdi) - cmdbuf[0] = XSDRSIZE - output.write( cmdbuf ) - obuf = bytearray(4) - struct.pack_into(">i", obuf, 0, xsdrsize ) # big endian 4 byte int to obuf - output.write( obuf ) - - if xtdomask != mask: - xtdomask = mask - cmdbuf[0] = XTDOMASK - output.write( cmdbuf ) - obuf = makeXSVFbytes( mask ) - output.write( obuf ) - - cmdbuf[0] = LSDR - output.write( cmdbuf ) - obuf = makeXSVFbytes( tdi ) - output.write( obuf ) - obuf = makeXSVFbytes( tdo ) - output.write( obuf ) - #print( "len(tdo)=", len(tdo), "len(tdr.tdo)=", len(tdr.tdo), "len(sdr.tdo)=", len(sdr.tdo), "len(hdr.tdo)=", len(hdr.tdo) ) - - elif tokVal == 'RUNTEST' or tokVal == 'LDELAY': - # e.g. from lattice tools: - # "RUNTEST IDLE 5 TCK 1.00E-003 SEC;" - saveTok = tokVal - nextTok() - min_time = 0 - run_count = 0 - max_time = 600 # ten minutes - if tokVal in run_state_allowed: - run_state = StateTxt.index(tokVal) - end_state = run_state # bottom of page 17 of SVF spec - nextTok() - if tokType != 'int' and tokType != 'float': - raise ParseError( tokLn, tokVal, "Expecting 'int' or 'float' after RUNTEST [run_state]") - timeval = tokVal; - nextTok() - if tokVal != 'TCK' and tokVal != 'SEC' and tokVal != 'SCK': - raise ParseError( tokLn, tokVal, "Expecting 'TCK' or 'SEC' or 'SCK' after RUNTEST [run_state] (run_count|min_time)") - if tokVal == 'TCK' or tokVal == 'SCK': - run_count = int( timeval ) - else: - min_time = timeval - nextTok() - if tokType == 'int' or tokType == 'float': - min_time = tokVal - nextTok() - if tokVal != 'SEC': - raise ParseError( tokLn, tokVal, "Expecting 'SEC' after RUNTEST [run_state] run_count min_time") - nextTok() - if tokVal == 'MAXIMUM': - nextTok() - if tokType != 'int' and tokType != 'float': - raise ParseError( tokLn, tokVal, "Expecting 'max_time' after RUNTEST [run_state] min_time SEC MAXIMUM") - max_time = tokVal - nextTok() - if tokVal != 'SEC': - raise ParseError( tokLn, tokVal, "Expecting 'max_time' after RUNTEST [run_state] min_time SEC MAXIMUM max_time") - nextTok() - if tokVal == 'ENDSTATE': - nextTok() - if tokVal not in run_state_allowed: - raise ParseError( tokLn, tokVal, "Expecting 'run_state' after RUNTEST .... ENDSTATE") - end_state = StateTxt.index(tokVal) - nextTok() - if tokVal != ';': - raise ParseError( tokLn, tokVal, "Expecting ';' after RUNTEST ....") - # print( "run_count=", run_count, "min_time=", min_time, - # "max_time=", max_time, "run_state=", State[run_state], "end_state=", State[end_state] ) - writeRUNTEST( output, run_state, end_state, run_count, min_time, saveTok ) - - elif tokVal == 'LCOUNT': - nextTok() - if tokType != 'int': - raise ParseError( tokLn, tokVal, "Expecting integer 'count' after LCOUNT") - loopCount = tokVal - nextTok() - if tokVal != ';': - raise ParseError( tokLn, tokVal, "Expecting ';' after LCOUNT count") - if doCOMMENTs: - writeComment( output, tokLn, 'LCOUNT' ) - obuf = bytearray(5) - obuf[0] = LCOUNT - struct.pack_into(">i", obuf, 1, loopCount ) # big endian 4 byte int to obuf - output.write( obuf ) - - elif tokVal == 'ENDDR': - nextTok() - if tokVal not in enddr_state_allowed: - raise ParseError( tokLn, tokVal, "Expecting 'stable_state' after ENDDR. (one of: DRPAUSE, IDLE)") - enddr_state = StateTxt.index(tokVal) - nextTok() - if tokVal != ';': - raise ParseError( tokLn, tokVal, "Expecting ';' after ENDDR stable_state") - if doCOMMENTs: - writeComment( output, tokLn, 'ENDDR' ) - obuf = bytearray(2) - obuf[0] = XENDDR - # Page 10 of the March 1999 SVF spec shows that RESET is also allowed here. - # Yet the XSVF spec has no provision for that, and uses a non-standard, i.e. - # boolean argument to XENDDR which only handles two of the 3 intended states. - obuf[1] = 1 if enddr_state == DRPAUSE else 0 - output.write( obuf ) - - elif tokVal == 'ENDIR': - nextTok() - if tokVal not in endir_state_allowed: - raise ParseError( tokLn, tokVal, "Expecting 'stable_state' after ENDIR. (one of: IRPAUSE, IDLE)") - endir_state = StateTxt.index(tokVal) - nextTok() - if tokVal != ';': - raise ParseError( tokLn, tokVal, "Expecting ';' after ENDIR stable_state") - if doCOMMENTs: - writeComment( output, tokLn, 'ENDIR' ) - obuf = bytearray(2) - obuf[0] = XENDIR - # Page 10 of the March 1999 SVF spec shows that RESET is also allowed here. - # Yet the XSVF spec has no provision for that, and uses a non-standard, i.e. - # boolean argument to XENDDR which only handles two of the 3 intended states. - obuf[1] = 1 if endir_state == IRPAUSE else 0 - output.write( obuf ) - - elif tokVal == 'STATE': - nextTok() - ln = tokLn - while tokVal != ';': - if tokVal not in StateTxt: - raise ParseError( tokLn, tokVal, "Expecting 'stable_state' after STATE") - stable_state = StateTxt.index( tokVal ) - - if doCOMMENTs and ln != -1: - writeComment( output, ln, 'STATE' ) - ln = -1 # save comment only once - - obuf = bytearray(2) - obuf[0] = XSTATE - obuf[1] = stable_state - output.write( obuf ) - nextTok() - - elif tokVal == 'FREQUENCY': - nextTok() - if tokVal != ';': - if tokType != 'int' and tokType != 'float': - raise ParseError( tokLn, tokVal, "Expecting 'cycles HZ' after FREQUENCY") - frequency = tokVal - nextTok() - if tokVal != 'HZ': - raise ParseError( tokLn, tokVal, "Expecting 'HZ' after FREQUENCY cycles") - nextTok() - if tokVal != ';': - raise ParseError( tokLn, tokVal, "Expecting ';' after FREQUENCY cycles HZ") - - elif tokVal == 'TRST': - nextTok() - if tokVal not in trst_mode_allowed: - raise ParseError( tokLn, tokVal, "Expecting 'ON|OFF|Z|ABSENT' after TRST") - trst_mode = tokVal - nextTok() - if tokVal != ';': - raise ParseError( tokLn, tokVal, "Expecting ';' after TRST trst_mode") - if doCOMMENTs: - writeComment( output, tokLn, 'TRST %s' % trst_mode ) - obuf = bytearray( 2 ) - obuf[0] = XTRST - obuf[1] = trst_mode_allowed.index( trst_mode ) # use the index as the binary argument to XTRST opcode - output.write( obuf ) - - else: - raise ParseError( tokLn, tokVal, "Unknown token '%s'" % tokVal) - -except StopIteration: - if not expecting_eof: - print( "Unexpected End of File at line ", tokLn ) - -except ParseError as pe: - print( "\n", pe ) - -finally: - # print( "closing file" ) - cmdbuf[0] = XCOMPLETE - output.write( cmdbuf ) - output.close() - diff --git a/contrib/xsvf_tools/xsvfdump.py b/contrib/xsvf_tools/xsvfdump.py deleted file mode 100644 index e65f8d5b2..000000000 --- a/contrib/xsvf_tools/xsvfdump.py +++ /dev/null @@ -1,268 +0,0 @@ -#!/usr/bin/python3.0 - -# Copyright 2008, SoftPLC Corporation http://softplc.com -# Dick Hollenbeck dick@softplc.com - -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, you may find one here: -# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html -# or you may search the http://www.gnu.org website for the version 2 license, -# or you may write to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - -# Dump an Xilinx XSVF file to stdout - -# This program is written for python 3.0, and it is not easy to change this -# back to 2.x. You may find it easier to use python 3.x even if that means -# building it. - - -import sys -import struct - - -LABEL = "A script to dump an XSVF file to stdout" - - -Xsdrsize = 0 - - -(XCOMPLETE,XTDOMASK,XSIR,XSDR,XRUNTEST,hole0,hole1,XREPEAT,XSDRSIZE,XSDRTDO, - XSETSDRMASKS,XSDRINC,XSDRB,XSDRC,XSDRE,XSDRTDOB,XSDRTDOC, - XSDRTDOE,XSTATE,XENDIR,XENDDR,XSIR2,XCOMMENT,XWAIT,XWAITSTATE, - LCOUNT,LDELAY,LSDR,XTRST) = range(29) - - -(RESET,IDLE, - DRSELECT,DRCAPTURE,DRSHIFT,DREXIT1,DRPAUSE,DREXIT2,DRUPDATE, - IRSELECT,IRCAPTURE,IRSHIFT,IREXIT1,IRPAUSE,IREXIT2,IRUPDATE) = range(16) - - -State = ("RESET","IDLE", - "DRSELECT","DRCAPTURE","DRSHIFT","DREXIT1","DRPAUSE","DREXIT2","DRUPDATE", - "IRSELECT","IRCAPTURE","IRSHIFT","IREXIT1","IRPAUSE","IREXIT2","IRUPDATE") - - -trst_mode_allowed = ('ON', 'OFF', 'Z', 'ABSENT') - - -Setsdrmasks = 0 -SetsdrmasksOnesCount = 0 - -def ReadSDRMASKS( f, len ): - global Setsdrmasks, SetsdrmasksOnesCount - byteCount = (len+7)//8 - Setsdrmasks = f.read( byteCount ) - ls = [] - SetsdrmasksOnesCount = 0 - for b in Setsdrmasks: - ls.append( "%x" % ((b & 0xf0) >> 4) ) - ls.append( "%x" % ( b & 0x0f ) ) - for i in range(8): - if b & (1<> 4) ) - ls.append( "%x" % ( b & 0x0f ) ) - return ''.join(ls) - - -def ReadByte( f ): - """Read a byte from a file and return it as an int in least significant 8 bits""" - b = f.read(1) - if b: - return 0xff & b[0]; - else: - return -1 - - -def ShowState( state ): - """return the given state int as a state string""" - #return "0x%02x" % state # comment this out to get textual state form - global State - if 0 <= state <= IRUPDATE: - return State[state] - else: - return "Unknown state 0x%02x" % state - - -def ShowOpcode( op, f ): - """return the given byte as an opcode string""" - global Xsdrsize - if op == XCOMPLETE: - print("XCOMPLETE") - - elif op == XTDOMASK: - buf = bytes2hexString( f, Xsdrsize ) - print("XTDOMASK 0x%s" % buf) - - elif op == XSIR: - len = ReadByte( f ) - buf = bytes2hexString( f, len ) - print("XSIR 0x%02X 0x%s" % (len, buf)) - - elif op == XSDR: - tdi = bytes2hexString( f, Xsdrsize ) - print("XSDR 0x%s" % tdi) - - elif op == XRUNTEST: - len = struct.unpack( '>i', f.read(4) )[0] - print("XRUNTEST 0x%08X" % len) - - elif op == XREPEAT: - len = ReadByte( f ) - print("XREPEAT 0x%02X" % len) - - elif op == XSDRSIZE: - Xsdrsize = struct.unpack( '>i', f.read(4) )[0] - #print("XSDRSIZE 0x%08X" % Xsdrsize, file=sys.stderr ) - print("XSDRSIZE 0x%08X %d" % (Xsdrsize, Xsdrsize) ) - - elif op == XSDRTDO: - tdi = bytes2hexString( f, Xsdrsize ) - tdo = bytes2hexString( f, Xsdrsize ) - print("XSDRTDO 0x%s 0x%s" % (tdi, tdo) ) - - elif op == XSETSDRMASKS: - addrmask = bytes2hexString( f, Xsdrsize ) - datamask = ReadSDRMASKS( f, Xsdrsize ) - print("XSETSDRMASKS 0x%s 0x%s" % (addrmask, datamask) ) - - elif op == XSDRINC: - startaddr = bytes2hexString( f, Xsdrsize ) - len = ReadByte(f) - print("XSDRINC 0x%s 0x%02X" % (startaddr, len), end='' ) - for numTimes in range(len): - data = bytes2hexString( f, SetsdrmasksOnesCount) - print(" 0x%s" % data ) - print() # newline - - elif op == XSDRB: - tdi = bytes2hexString( f, Xsdrsize ) - print("XSDRB 0x%s" % tdi ) - - elif op == XSDRC: - tdi = bytes2hexString( f, Xsdrsize ) - print("XSDRC 0x%s" % tdi ) - - elif op == XSDRE: - tdi = bytes2hexString( f, Xsdrsize ) - print("XSDRE 0x%s" % tdi ) - - elif op == XSDRTDOB: - tdo = bytes2hexString( f, Xsdrsize ) - print("XSDRTDOB 0x%s" % tdo ) - - elif op == XSDRTDOC: - tdi = bytes2hexString( f, Xsdrsize ) - tdo = bytes2hexString( f, Xsdrsize ) - print("XSDRTDOC 0x%s 0x%s" % (tdi, tdo) ) - - elif op == XSDRTDOE: - tdi = bytes2hexString( f, Xsdrsize ) - tdo = bytes2hexString( f, Xsdrsize ) - print("XSDRTDOE 0x%s 0x%s" % (tdi, tdo) ) - - elif op == XSTATE: - b = ReadByte(f) - print("XSTATE %s" % ShowState(b)) - - elif op == XENDIR: - b = ReadByte( f ) - print("XENDIR %s" % 'IRPAUSE' if b==1 else 'IDLE') - - elif op == XENDDR: - b = ReadByte( f ) - print("XENDDR %s" % 'DRPAUSE' if b==1 else 'IDLE') - - elif op == XSIR2: - len = struct.unpack( '>H', f.read(2) )[0] - buf = bytes2hexString( f, len ) - print("XSIR2 0x%04X 0x%s" % (len, buf)) - - elif op == XCOMMENT: - cmt = [] - while 1: - b = ReadByte(f) - if b == 0: # terminating nul - break; - cmt.append( chr(b) ) - print("XCOMMENT \"%s\"" % ''.join(cmt) ) - - elif op == XWAIT: - run_state = ReadByte(f) - end_state = ReadByte(f) - useconds = struct.unpack( '>i', f.read(4) )[0] - print("XWAIT %s %s" % (ShowState(run_state), ShowState(end_state)), useconds) - - elif op == XWAITSTATE: - run_state = ReadByte(f) - end_state = ReadByte(f) - clocks = struct.unpack( '>i', f.read(4) )[0] - useconds = struct.unpack( '>i', f.read(4) )[0] - print("XWAITSTATE %s %s CLOCKS=%d USECS=%d" % (ShowState(run_state), ShowState(end_state), clocks, useconds) ) - - elif op == LCOUNT: - loop_count = struct.unpack( '>i', f.read(4) )[0] - print("LCOUNT", loop_count ) - - elif op == LDELAY: - run_state = ReadByte(f) - clocks = struct.unpack( '>i', f.read(4) )[0] - useconds = struct.unpack( '>i', f.read(4) )[0] - print("LDELAY %s CLOCKS=%d USECS=%d" % (ShowState(run_state), clocks, useconds) ) - - elif op == LSDR: - tdi = bytes2hexString( f, Xsdrsize ) - tdo = bytes2hexString( f, Xsdrsize ) - print("LSDR 0x%s 0x%s" % (tdi, tdo) ) - - elif op == XTRST: - # the argument is a single byte and it is the index into "trst_mode_allowed" - trst_mode = ReadByte(f) - if trst_mode <= 3: - print("TRST %s" % trst_mode_allowed[trst_mode] ) - else: - print("TRST 0x%02X" % trst_mode ); - - else: - print("UNKNOWN op 0x%02X %d" % (op, op)) - exit(1) - - -def main(): - - if len( sys.argv ) < 2: - print("usage %s " % sys.argv[0]) - exit(1) - - f = open( sys.argv[1], 'rb' ) - - opcode = ReadByte( f ) - while opcode != -1: - # print the position within the file, then the command - print( "%d: " % f.tell(), end='' ) - ShowOpcode( opcode, f ) - opcode = ReadByte(f) - - -if __name__ == "__main__": - main() - diff --git a/doc/INSTALL.txt b/doc/INSTALL.txt deleted file mode 100644 index c329be2c7..000000000 --- a/doc/INSTALL.txt +++ /dev/null @@ -1,204 +0,0 @@ -TODO!!! this should be merged into openocd.texi!!! - - -Prerequisites -============= - -When building with support for FTDI FT2232 based devices, you need at least -one of the following libraries: - -- libftdi (http://www.intra2net.com/opensource/ftdi/) -- libftd2xx (http://www.ftdichip.com/Drivers/D2XX.htm) - -On Windows, you need either Cygwin or MinGW, but compilation for MinGW is also -possible using a Cygwin host. - -Basic Installation -================== - - OpenOCD is distributed without autotools generated files, i.e. without a -configure script. Run ./bootstrap in the openocd directory to have all -necessary files generated. - - You have to explicitly enable desired JTAG interfaces during configure: - -./configure --enable-parport --enable-ft2232-libftdi (OR --enable-ft2232-ftd2xx) \ - --enable-amtjtagaccel - - Under Windows/Cygwin, only the ftd2xx driver is supported for FT2232 based -devices. You have to specify the location of the FTDI driver package with the ---with-ftd2xx=/full/path/name option. - -Under Linux you can choose to build the parport driver with support for -/dev/parportN instead of the default access with direct port I/O using ---enable-parport_ppdev. This has the advantage of running OpenOCD without root -privileges at the expense of a slight performance decrease. This is also -available on FreeBSD using PPI, but the naming of the devices is different. - -Generic installation instructions -================================= - - These are generic installation instructions. - - The `configure' shell script attempts to guess correct values for -various system-dependent variables used during compilation. It uses -those values to create a `Makefile' in each directory of the package. -It may also create one or more `.h' files containing system-dependent -definitions. Finally, it creates a shell script `config.status' that -you can run in the future to recreate the current configuration, a file -`config.cache' that saves the results of its tests to speed up -reconfiguring, and a file `config.log' containing compiler output -(useful mainly for debugging `configure'). - - If you need to do unusual things to compile the package, please try -to figure out how `configure' could check whether to do them, and mail -diffs or instructions to the address given in the `README' so they can -be considered for the next release. If at some point `config.cache' -contains results you don't want to keep, you may remove or edit it. - - The file `configure.in' is used to create `configure' by a program -called `autoconf'. You only need `configure.in' if you want to change -it or regenerate `configure' using a newer version of `autoconf'. - -The simplest way to compile this package is: - - 1. `cd' to the directory containing the package's source code and type - `./configure' to configure the package for your system. If you're - using `csh' on an old version of System V, you might need to type - `sh ./configure' instead to prevent `csh' from trying to execute - `configure' itself. - - Running `configure' takes a while. While running, it prints some - messages telling which features it is checking for. - - 2. Type `make' to compile the package. - - 3. Type `make install' to install the programs and any data files and - documentation. - - 4. You can remove the program binaries and object files from the - source code directory by typing `make clean'. - -Compilers and Options -===================== - - Some systems require unusual options for compilation or linking that -the `configure' script does not know about. You can give `configure' -initial values for variables by setting them in the environment. Using -a Bourne-compatible shell, you can do that on the command line like -this: - CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure - -Or on systems that have the `env' program, you can do it like this: - env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure - -Compiling For Multiple Architectures -==================================== - - You can compile the package for more than one kind of computer at the -same time, by placing the object files for each architecture in their -own directory. To do this, you must use a version of `make' that -supports the `VPATH' variable, such as GNU `make'. `cd' to the -directory where you want the object files and executables to go and run -the `configure' script. `configure' automatically checks for the -source code in the directory that `configure' is in and in `..'. - - If you have to use a `make' that does not supports the `VPATH' -variable, you have to compile the package for one architecture at a time -in the source code directory. After you have installed the package for -one architecture, use `make distclean' before reconfiguring for another -architecture. - -Installation Names -================== - - By default, `make install' will install the package's files in -`/usr/local/bin', `/usr/local/man', etc. You can specify an -installation prefix other than `/usr/local' by giving `configure' the -option `--prefix=PATH'. - - You can specify separate installation prefixes for -architecture-specific files and architecture-independent files. If you -give `configure' the option `--exec-prefix=PATH', the package will use -PATH as the prefix for installing programs and libraries. -Documentation and other data files will still use the regular prefix. - - If the package supports it, you can cause programs to be installed -with an extra prefix or suffix on their names by giving `configure' the -option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. - -Optional Features -================= - - Some packages pay attention to `--enable-FEATURE' options to -`configure', where FEATURE indicates an optional part of the package. -They may also pay attention to `--with-PACKAGE' options, where PACKAGE -is something like `gnu-as' or `x' (for the X Window System). The -`README' should mention any `--enable-' and `--with-' options that the -package recognizes. - - For packages that use the X Window System, `configure' can usually -find the X include and library files automatically, but if it doesn't, -you can use the `configure' options `--x-includes=DIR' and -`--x-libraries=DIR' to specify their locations. - -Specifying the System Type -========================== - - There may be some features `configure' can not figure out -automatically, but needs to determine by the type of host the package -will run on. Usually `configure' can figure that out, but if it prints -a message saying it can not guess the host type, give it the -`--host=TYPE' option. TYPE can either be a short name for the system -type, such as `sun4', or a canonical name with three fields: - CPU-COMPANY-SYSTEM - -See the file `config.sub' for the possible values of each field. If -`config.sub' isn't included in this package, then this package doesn't -need to know the host type. - - If you are building compiler tools for cross-compiling, you can also -use the `--target=TYPE' option to select the type of system they will -produce code for and the `--build=TYPE' option to select the type of -system on which you are compiling the package. - -Sharing Defaults -================ - - If you want to set default values for `configure' scripts to share, -you can create a site shell script called `config.site' that gives -default values for variables like `CC', `cache_file', and `prefix'. -`configure' looks for `PREFIX/share/config.site' if it exists, then -`PREFIX/etc/config.site' if it exists. Or, you can set the -`CONFIG_SITE' environment variable to the location of the site script. -A warning: not all `configure' scripts look for a site script. - -Operation Controls -================== - - `configure' recognizes the following options to control how it -operates. - -`--cache-file=FILE' - Use and save the results of the tests in FILE instead of - `./config.cache'. Set FILE to `/dev/null' to disable caching, for - debugging `configure'. - -`--help' - Print a summary of the options to `configure', and exit. - -`--quiet' -`--silent' -`-q' - Do not print messages saying which checks are being made. - -`--srcdir=DIR' - Look for the package's source code in directory DIR. Usually - `configure' can determine that directory automatically. - -`--version' - Print the version of Autoconf used to generate the `configure' - script, and exit. - -`configure' also accepts some other, not widely useful, options. - diff --git a/doc/Makefile.am b/doc/Makefile.am deleted file mode 100644 index 935c8f9d2..000000000 --- a/doc/Makefile.am +++ /dev/null @@ -1,13 +0,0 @@ -info_TEXINFOS = openocd.texi -openocd_TEXINFOS = fdl.texi -man_MANS = openocd.1 -EXTRA_DIST = openocd.1 \ - manual \ - INSTALL.txt - -MAINTAINERCLEANFILES = \ - $(srcdir)/Makefile.in \ - $(srcdir)/mdate-sh \ - $(srcdir)/stamp-vti \ - $(srcdir)/version.texi \ - $(srcdir)/texinfo.tex diff --git a/doc/fdl.texi b/doc/fdl.texi deleted file mode 100644 index a18c33ea0..000000000 --- a/doc/fdl.texi +++ /dev/null @@ -1,452 +0,0 @@ -@c -*-texinfo-*- -@node License -@appendix The GNU Free Documentation License. -@center Version 1.2, November 2002 - -@c This file is intended to be included within another document, -@c hence no sectioning command or @node. - -@display -Copyright @copyright{} 2000,2001,2002 Free Software Foundation, Inc. -51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - -Everyone is permitted to copy and distribute verbatim copies -of this license document, but changing it is not allowed. -@end display - -@enumerate 0 -@item -PREAMBLE - -The purpose of this License is to make a manual, textbook, or other -functional and useful document @dfn{free} in the sense of freedom: to -assure everyone the effective freedom to copy and redistribute it, -with or without modifying it, either commercially or noncommercially. -Secondarily, this License preserves for the author and publisher a way -to get credit for their work, while not being considered responsible -for modifications made by others. - -This License is a kind of ``copyleft'', which means that derivative -works of the document must themselves be free in the same sense. It -complements the GNU General Public License, which is a copyleft -license designed for free software. - -We have designed this License in order to use it for manuals for free -software, because free software needs free documentation: a free -program should come with manuals providing the same freedoms that the -software does. But this License is not limited to software manuals; -it can be used for any textual work, regardless of subject matter or -whether it is published as a printed book. We recommend this License -principally for works whose purpose is instruction or reference. - -@item -APPLICABILITY AND DEFINITIONS - -This License applies to any manual or other work, in any medium, that -contains a notice placed by the copyright holder saying it can be -distributed under the terms of this License. Such a notice grants a -world-wide, royalty-free license, unlimited in duration, to use that -work under the conditions stated herein. The ``Document'', below, -refers to any such manual or work. Any member of the public is a -licensee, and is addressed as ``you''. You accept the license if you -copy, modify or distribute the work in a way requiring permission -under copyright law. - -A ``Modified Version'' of the Document means any work containing the -Document or a portion of it, either copied verbatim, or with -modifications and/or translated into another language. - -A ``Secondary Section'' is a named appendix or a front-matter section -of the Document that deals exclusively with the relationship of the -publishers or authors of the Document to the Document's overall -subject (or to related matters) and contains nothing that could fall -directly within that overall subject. (Thus, if the Document is in -part a textbook of mathematics, a Secondary Section may not explain -any mathematics.) The relationship could be a matter of historical -connection with the subject or with related matters, or of legal, -commercial, philosophical, ethical or political position regarding -them. - -The ``Invariant Sections'' are certain Secondary Sections whose titles -are designated, as being those of Invariant Sections, in the notice -that says that the Document is released under this License. If a -section does not fit the above definition of Secondary then it is not -allowed to be designated as Invariant. The Document may contain zero -Invariant Sections. If the Document does not identify any Invariant -Sections then there are none. - -The ``Cover Texts'' are certain short passages of text that are listed, -as Front-Cover Texts or Back-Cover Texts, in the notice that says that -the Document is released under this License. A Front-Cover Text may -be at most 5 words, and a Back-Cover Text may be at most 25 words. - -A ``Transparent'' copy of the Document means a machine-readable copy, -represented in a format whose specification is available to the -general public, that is suitable for revising the document -straightforwardly with generic text editors or (for images composed of -pixels) generic paint programs or (for drawings) some widely available -drawing editor, and that is suitable for input to text formatters or -for automatic translation to a variety of formats suitable for input -to text formatters. A copy made in an otherwise Transparent file -format whose markup, or absence of markup, has been arranged to thwart -or discourage subsequent modification by readers is not Transparent. -An image format is not Transparent if used for any substantial amount -of text. A copy that is not ``Transparent'' is called ``Opaque''. - -Examples of suitable formats for Transparent copies include plain -@sc{ascii} without markup, Texinfo input format, La@TeX{} input -format, @acronym{SGML} or @acronym{XML} using a publicly available -@acronym{DTD}, and standard-conforming simple @acronym{HTML}, -PostScript or @acronym{PDF} designed for human modification. Examples -of transparent image formats include @acronym{PNG}, @acronym{XCF} and -@acronym{JPG}. Opaque formats include proprietary formats that can be -read and edited only by proprietary word processors, @acronym{SGML} or -@acronym{XML} for which the @acronym{DTD} and/or processing tools are -not generally available, and the machine-generated @acronym{HTML}, -PostScript or @acronym{PDF} produced by some word processors for -output purposes only. - -The ``Title Page'' means, for a printed book, the title page itself, -plus such following pages as are needed to hold, legibly, the material -this License requires to appear in the title page. For works in -formats which do not have any title page as such, ``Title Page'' means -the text near the most prominent appearance of the work's title, -preceding the beginning of the body of the text. - -A section ``Entitled XYZ'' means a named subunit of the Document whose -title either is precisely XYZ or contains XYZ in parentheses following -text that translates XYZ in another language. (Here XYZ stands for a -specific section name mentioned below, such as ``Acknowledgements'', -``Dedications'', ``Endorsements'', or ``History''.) To ``Preserve the Title'' -of such a section when you modify the Document means that it remains a -section ``Entitled XYZ'' according to this definition. - -The Document may include Warranty Disclaimers next to the notice which -states that this License applies to the Document. These Warranty -Disclaimers are considered to be included by reference in this -License, but only as regards disclaiming warranties: any other -implication that these Warranty Disclaimers may have is void and has -no effect on the meaning of this License. - -@item -VERBATIM COPYING - -You may copy and distribute the Document in any medium, either -commercially or noncommercially, provided that this License, the -copyright notices, and the license notice saying this License applies -to the Document are reproduced in all copies, and that you add no other -conditions whatsoever to those of this License. You may not use -technical measures to obstruct or control the reading or further -copying of the copies you make or distribute. However, you may accept -compensation in exchange for copies. If you distribute a large enough -number of copies you must also follow the conditions in section 3. - -You may also lend copies, under the same conditions stated above, and -you may publicly display copies. - -@item -COPYING IN QUANTITY - -If you publish printed copies (or copies in media that commonly have -printed covers) of the Document, numbering more than 100, and the -Document's license notice requires Cover Texts, you must enclose the -copies in covers that carry, clearly and legibly, all these Cover -Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on -the back cover. Both covers must also clearly and legibly identify -you as the publisher of these copies. The front cover must present -the full title with all words of the title equally prominent and -visible. You may add other material on the covers in addition. -Copying with changes limited to the covers, as long as they preserve -the title of the Document and satisfy these conditions, can be treated -as verbatim copying in other respects. - -If the required texts for either cover are too voluminous to fit -legibly, you should put the first ones listed (as many as fit -reasonably) on the actual cover, and continue the rest onto adjacent -pages. - -If you publish or distribute Opaque copies of the Document numbering -more than 100, you must either include a machine-readable Transparent -copy along with each Opaque copy, or state in or with each Opaque copy -a computer-network location from which the general network-using -public has access to download using public-standard network protocols -a complete Transparent copy of the Document, free of added material. -If you use the latter option, you must take reasonably prudent steps, -when you begin distribution of Opaque copies in quantity, to ensure -that this Transparent copy will remain thus accessible at the stated -location until at least one year after the last time you distribute an -Opaque copy (directly or through your agents or retailers) of that -edition to the public. - -It is requested, but not required, that you contact the authors of the -Document well before redistributing any large number of copies, to give -them a chance to provide you with an updated version of the Document. - -@item -MODIFICATIONS - -You may copy and distribute a Modified Version of the Document under -the conditions of sections 2 and 3 above, provided that you release -the Modified Version under precisely this License, with the Modified -Version filling the role of the Document, thus licensing distribution -and modification of the Modified Version to whoever possesses a copy -of it. In addition, you must do these things in the Modified Version: - -@enumerate A -@item -Use in the Title Page (and on the covers, if any) a title distinct -from that of the Document, and from those of previous versions -(which should, if there were any, be listed in the History section -of the Document). You may use the same title as a previous version -if the original publisher of that version gives permission. - -@item -List on the Title Page, as authors, one or more persons or entities -responsible for authorship of the modifications in the Modified -Version, together with at least five of the principal authors of the -Document (all of its principal authors, if it has fewer than five), -unless they release you from this requirement. - -@item -State on the Title page the name of the publisher of the -Modified Version, as the publisher. - -@item -Preserve all the copyright notices of the Document. - -@item -Add an appropriate copyright notice for your modifications -adjacent to the other copyright notices. - -@item -Include, immediately after the copyright notices, a license notice -giving the public permission to use the Modified Version under the -terms of this License, in the form shown in the Addendum below. - -@item -Preserve in that license notice the full lists of Invariant Sections -and required Cover Texts given in the Document's license notice. - -@item -Include an unaltered copy of this License. - -@item -Preserve the section Entitled ``History'', Preserve its Title, and add -to it an item stating at least the title, year, new authors, and -publisher of the Modified Version as given on the Title Page. If -there is no section Entitled ``History'' in the Document, create one -stating the title, year, authors, and publisher of the Document as -given on its Title Page, then add an item describing the Modified -Version as stated in the previous sentence. - -@item -Preserve the network location, if any, given in the Document for -public access to a Transparent copy of the Document, and likewise -the network locations given in the Document for previous versions -it was based on. These may be placed in the ``History'' section. -You may omit a network location for a work that was published at -least four years before the Document itself, or if the original -publisher of the version it refers to gives permission. - -@item -For any section Entitled ``Acknowledgements'' or ``Dedications'', Preserve -the Title of the section, and preserve in the section all the -substance and tone of each of the contributor acknowledgements and/or -dedications given therein. - -@item -Preserve all the Invariant Sections of the Document, -unaltered in their text and in their titles. Section numbers -or the equivalent are not considered part of the section titles. - -@item -Delete any section Entitled ``Endorsements''. Such a section -may not be included in the Modified Version. - -@item -Do not retitle any existing section to be Entitled ``Endorsements'' or -to conflict in title with any Invariant Section. - -@item -Preserve any Warranty Disclaimers. -@end enumerate - -If the Modified Version includes new front-matter sections or -appendices that qualify as Secondary Sections and contain no material -copied from the Document, you may at your option designate some or all -of these sections as invariant. To do this, add their titles to the -list of Invariant Sections in the Modified Version's license notice. -These titles must be distinct from any other section titles. - -You may add a section Entitled ``Endorsements'', provided it contains -nothing but endorsements of your Modified Version by various -parties---for example, statements of peer review or that the text has -been approved by an organization as the authoritative definition of a -standard. - -You may add a passage of up to five words as a Front-Cover Text, and a -passage of up to 25 words as a Back-Cover Text, to the end of the list -of Cover Texts in the Modified Version. Only one passage of -Front-Cover Text and one of Back-Cover Text may be added by (or -through arrangements made by) any one entity. If the Document already -includes a cover text for the same cover, previously added by you or -by arrangement made by the same entity you are acting on behalf of, -you may not add another; but you may replace the old one, on explicit -permission from the previous publisher that added the old one. - -The author(s) and publisher(s) of the Document do not by this License -give permission to use their names for publicity for or to assert or -imply endorsement of any Modified Version. - -@item -COMBINING DOCUMENTS - -You may combine the Document with other documents released under this -License, under the terms defined in section 4 above for modified -versions, provided that you include in the combination all of the -Invariant Sections of all of the original documents, unmodified, and -list them all as Invariant Sections of your combined work in its -license notice, and that you preserve all their Warranty Disclaimers. - -The combined work need only contain one copy of this License, and -multiple identical Invariant Sections may be replaced with a single -copy. If there are multiple Invariant Sections with the same name but -different contents, make the title of each such section unique by -adding at the end of it, in parentheses, the name of the original -author or publisher of that section if known, or else a unique number. -Make the same adjustment to the section titles in the list of -Invariant Sections in the license notice of the combined work. - -In the combination, you must combine any sections Entitled ``History'' -in the various original documents, forming one section Entitled -``History''; likewise combine any sections Entitled ``Acknowledgements'', -and any sections Entitled ``Dedications''. You must delete all -sections Entitled ``Endorsements.'' - -@item -COLLECTIONS OF DOCUMENTS - -You may make a collection consisting of the Document and other documents -released under this License, and replace the individual copies of this -License in the various documents with a single copy that is included in -the collection, provided that you follow the rules of this License for -verbatim copying of each of the documents in all other respects. - -You may extract a single document from such a collection, and distribute -it individually under this License, provided you insert a copy of this -License into the extracted document, and follow this License in all -other respects regarding verbatim copying of that document. - -@item -AGGREGATION WITH INDEPENDENT WORKS - -A compilation of the Document or its derivatives with other separate -and independent documents or works, in or on a volume of a storage or -distribution medium, is called an ``aggregate'' if the copyright -resulting from the compilation is not used to limit the legal rights -of the compilation's users beyond what the individual works permit. -When the Document is included in an aggregate, this License does not -apply to the other works in the aggregate which are not themselves -derivative works of the Document. - -If the Cover Text requirement of section 3 is applicable to these -copies of the Document, then if the Document is less than one half of -the entire aggregate, the Document's Cover Texts may be placed on -covers that bracket the Document within the aggregate, or the -electronic equivalent of covers if the Document is in electronic form. -Otherwise they must appear on printed covers that bracket the whole -aggregate. - -@item -TRANSLATION - -Translation is considered a kind of modification, so you may -distribute translations of the Document under the terms of section 4. -Replacing Invariant Sections with translations requires special -permission from their copyright holders, but you may include -translations of some or all Invariant Sections in addition to the -original versions of these Invariant Sections. You may include a -translation of this License, and all the license notices in the -Document, and any Warranty Disclaimers, provided that you also include -the original English version of this License and the original versions -of those notices and disclaimers. In case of a disagreement between -the translation and the original version of this License or a notice -or disclaimer, the original version will prevail. - -If a section in the Document is Entitled ``Acknowledgements'', -``Dedications'', or ``History'', the requirement (section 4) to Preserve -its Title (section 1) will typically require changing the actual -title. - -@item -TERMINATION - -You may not copy, modify, sublicense, or distribute the Document except -as expressly provided for under this License. Any other attempt to -copy, modify, sublicense or distribute the Document is void, and will -automatically terminate your rights under this License. However, -parties who have received copies, or rights, from you under this -License will not have their licenses terminated so long as such -parties remain in full compliance. - -@item -FUTURE REVISIONS OF THIS LICENSE - -The Free Software Foundation may publish new, revised versions -of the GNU Free Documentation License from time to time. Such new -versions will be similar in spirit to the present version, but may -differ in detail to address new problems or concerns. See -@uref{http://www.gnu.org/copyleft/}. - -Each version of the License is given a distinguishing version number. -If the Document specifies that a particular numbered version of this -License ``or any later version'' applies to it, you have the option of -following the terms and conditions either of that specified version or -of any later version that has been published (not as a draft) by the -Free Software Foundation. If the Document does not specify a version -number of this License, you may choose any version ever published (not -as a draft) by the Free Software Foundation. -@end enumerate - -@unnumberedsec ADDENDUM: How to use this License for your documents - -To use this License in a document you have written, include a copy of -the License in the document and put the following copyright and -license notices just after the title page: - -@smallexample -@group - Copyright (C) @var{year} @var{your name}. - Permission is granted to copy, distribute and/or modify this document - under the terms of the GNU Free Documentation License, Version 1.2 - or any later version published by the Free Software Foundation; - with no Invariant Sections, no Front-Cover Texts, and no Back-Cover - Texts. A copy of the license is included in the section entitled ``GNU - Free Documentation License''. -@end group -@end smallexample - -If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts, -replace the ``with@dots{}Texts.'' line with this: - -@smallexample -@group - with the Invariant Sections being @var{list their titles}, with - the Front-Cover Texts being @var{list}, and with the Back-Cover Texts - being @var{list}. -@end group -@end smallexample - -If you have Invariant Sections without Cover Texts, or some other -combination of the three, merge those two alternatives to suit the -situation. - -If your document contains nontrivial examples of program code, we -recommend releasing these examples in parallel under your choice of -free software license, such as the GNU General Public License, -to permit their use in free software. - -@c Local Variables: -@c ispell-local-pdict: "ispell-dict" -@c End: - diff --git a/doc/manual/app.txt b/doc/manual/app.txt deleted file mode 100644 index 989e6e67d..000000000 --- a/doc/manual/app.txt +++ /dev/null @@ -1,9 +0,0 @@ -/** @page appdocs OpenOCD Application APIs - -The top-level APIs in the OpenOCD library allow applications to integrate -all of the low-level functionality using a set of simple function calls. - -These function calls do not exist in a re-usable form, but -contributions to create and document them will be welcome. - - */ diff --git a/doc/manual/flash.txt b/doc/manual/flash.txt deleted file mode 100644 index a9f6c2a55..000000000 --- a/doc/manual/flash.txt +++ /dev/null @@ -1,35 +0,0 @@ -/** @page flashdocs OpenOCD Flash APIs - -OpenOCD provides its Flash APIs for developers to support different -types of flash devices, some of which are built-in to target devices -while others may be connected via standard memory interface (e.g. CFI, -FMI, etc.). - -The Flash module provides the following APIs: - - - @subpage flashcfi - - @subpage flashnand - - @subpage flashtarget - -This section needs to be expanded. - -*/ - - -/** @page flashcfi OpenOCD CFI Flash API - -This section needs to be expanded to describe OpenOCD's CFI Flash API. - -*/ - -/** @page flashnand OpenOCD NAND Flash API - -This section needs to be expanded to describe OpenOCD's NAND Flash API. - -*/ - -/** @page flashtarget OpenOCD Target Flash API - -This section needs to be expanded to describe OpenOCD's Target Flash API. - -*/ diff --git a/doc/manual/helper.txt b/doc/manual/helper.txt deleted file mode 100644 index 1b01b2e6b..000000000 --- a/doc/manual/helper.txt +++ /dev/null @@ -1,136 +0,0 @@ -/** @page helperdocs OpenOCD Helper APIs - -OpenOCD uses several low-level APIs as the foundation for high-level APIs: - - - @subpage helperporting - - @subpage helperjim - - @subpage helpercommand - - @subpage helperlogging - - @subpage helperbuffers - -This section needs to be expanded. - - */ - -/** @page helperporting OpenOCD Types/Portability APIs - -This section needs to be expanded to describe OpenOCD's type and -portability API. - - */ - -/** @page helperjim OpenOCD Jim API - -The Jim API provides access to a small-footprint TCL implementation. - -Visit http://jim.tcl.tk/ for more information on Jim. - -This section needs to be expanded to describe OpenOCD's Jim API. - - */ - -/** @page helpercommand OpenOCD Command API - -OpenOCD's command API allows modules to register callbacks that are then -available to the scripting services. It provides the mechanism for -these commands to be dispatched to the module using a standard -interface. It provides macros for defining functions that use and -extend this interface. - -@section helpercmdhandler Command Handlers - -Command handlers are functions with a particular signature, which can -be extended by modules for passing additional parameters to helpers or -another layer of handlers. - -@subsection helpercmdhandlerdef Defining and Calling Command Handlers - -These functions should be defined using the @c COMMAND_HANDLER macro. -These methods must be defined as static, as their principal entry point -should be the run_command dispatch mechanism. - -Command helper functions that require access to the full set of -parameters should be defined using the @c COMMAND_HELPER. These must be -declared static by you, as sometimes you might want to share a helper -among several files (e.g. @c s3c24xx_nand.h). - -Both types of routines must be called using the @c CALL_COMMAND_HANDLER macro. -Calls using this macro to normal handlers require the name of the command -handler (which can be a name or function pointer). Calls to helpers and -derived handlers must pass those extra parameters specified by their -definitions; however, lexical capture is used for the core parameters. -This dirty trick is being used as a stop-gap measure while the API is -migrated to one that passes a pointer to a structure containing the -same ingredients. At that point, this macro will be removed and callers -will be able to use direct invocations. - -Thus, the following macros can be used to define and call command -handlers or helpers: - -- @c COMMAND_HANDLER - declare or define a command handler. -- @c COMMAND_HELPER - declare or define a derived command handler or helper. -- @c CALL_COMMAND_HANDLER - call a command handler/helper. - -@subsection helpercmdhandlermacros Command Handler Macros - -In addition, the following macros may be used in the context of -command handlers and helpers: -- @c CMD_CTX - the current @c command_context -- @c CMD_NAME - invoked command name -- @c CMD_ARGC - the number of command arguments -- @c CMD_ARGV - array of command argument strings - -@section helpercmdregister Command Registration - -In order to use a command handler, it must be registered with the -command subsystem. All commands are registered with command_registration -structures, specifying the name of the command, its handler, its allowed -mode(s) of execution, and strings that provide usage and help text. -A single handler may be registered using multiple names, but any name -may have only one handler associated with it. - -The @c register_commands() and @c register_commands() functions provide -registration, while the @c unregister_command() and -@c unregister_all_commands() functions will remove existing commands. -These may be called at any time, allowing the command set to change in -response to system actions. - -@subsection helpercmdjim Jim Command Registration - -The command_registration structure provides support for registering -native Jim command handlers (@c jim_handler) too. For these handlers, -the module can provide help and usage support; however, this mechanism -allows Jim handlers to be called as sub-commands of other commands. -These commands may be registered with a private data value (@c -jim_handler_data) that will be available when called, as with low-level -Jim command registration. - -A command may have a normal @c handler or a @c jim_handler, but not both. - -@subsection helpercmdregisterchains Command Chaining - -When using register_commands(), the array of commands may reference -other arrays. When the @c chain field is filled in a -command_registration record, the commands on in the chained list will -added in one of two places. If the record defines a new command, then -the chained commands are added under it; otherwise, the commands are -added in the same context as the other commands in the array. - -@section helpercmdprimer Command Development Primer - -This @ref primercommand provides details about the @c hello module, -showing how the pieces described on this page fit together. - - */ - -/** @page helperlogging OpenOCD Logging API - -This section needs to be expanded to describe OpenOCD's Logging API. - - */ - -/** @page helperbuffers OpenOCD Byte Buffer API - -This section needs to be expanded to describe OpenOCD's Byte Buffer API. - - */ diff --git a/doc/manual/images/jtag-state-machine-large.png b/doc/manual/images/jtag-state-machine-large.png deleted file mode 100644 index c91fcf4b802a00652b1d8116700b1de7af67b0ba..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11416 zcmd6N2T)U6)NVwuAjlO90wMuI3xWy)h87Tkgc1}8NVkM8AfZM|6crmK91sjGDop~2 zG!bc01U*O(!0?=HDKZ*HCd0@K7?}g3!(enYj82Bp88A8r#)QF`Xc&_W zV=`b&4%8WpgNAX)Fb)I8;cRydLnC2iB#eQCagazD5{X74$w(vviR2*hFeDz0#FLSD z1`^NN9-oXxlF3Li14-r}=`bW6jii&2bOw^nK{8=TCK|~kBbf{&lLM)Vgl;csc`5=ir$zJQIy)lJQIip2>j>fajp`95SB6z;mF9LH0mHwjje8&?KRW zk&$RfV=|HfsR9j8#-pKr$#@3T01_gT(d6wPgG}a-=`b=KO{SB{bOxEuAv0lQCYsD7 zlbH-MlLMKS%t1p^WDbMO;cS~3hTd)gW6)t7Iub@lqUlI79m$|0IdnXXjz`n+WICQf z$8)y5K}K(POlHu@96B9Fr=#g~GM&z#(>Zh|jLt;UnPfVXL1%Ixr_niRXnZ<{LFaI` z9SB2j>jGmiVH_qB#zdl-NHP=2U?Mq8JdBA)Gx205p25U(w*5>-Z>vmZFv%Py9mb@i znRGIf&S26xOeT!UL^GLWCX>Nra-eWva?sGsm>dR^!`TiE7@YnR0r~H~Iu zq5!X#TrTb>%K^T`=QW8E)c5iiqJk_^2>Y|)!oAoT#7-A?S!wL(Y0rKhVU;XT(RVm` zfZF~v&&%Z*-(jX6dwPQBLKN?$t!$g&J~@3-c|!Fqg=c&&Oj9;5T~|2~AIb8z0pY?; zQ*yv<fAH?b_h(op_gQsQ zk`Y2i8%`qKt<`fID?h_G&+J*-+KjL6`fy2TSLDmYSXt5asu$yP$#pojS@N}w#${iR zuI{XplW-x$)0=wE@y9`d%XLg-_}E;tw8HtXYD=(DKo!amx;N|4$MnN)qR7kk=`%2dGB ziJ}u+i#+o2%@3rUE0^1R_1M8#21M2NM^vQl7G;!jolpDFX*2k$zJ(M@^x?6#bdw|d zZNiLiBF2upo12@Ord_=?5{Hdv5nhk;r8YgpMrGALtIswju0;v(yk?^Dli3BfbH_+js(iY&r+p?xk65RxY;_P5HTxIzwA&)8 z7LLE)?-KA*V9c;KrylcWF5EmS1EyZqF=UbUYU^pMvBM7po=SuWPo4KPmZ9L4IG{7^-B$@*^P={!#qD81rg{E@ccjX(g=l0s=?K9M4 zuVkUBe$&pMr4j^OC>z@Ra8z;6oC#H`XXd-MvqZB}ZGH#hzRLHcL>{2fsHA%joNOY6 zQM$gIY7w>jd%ya}>ZxBJsRt+<@@8<<`AYwEK0SGU32GX3kK1cSc|B#TZaJXPoM>YV zO+6b^LJFSk=T-|8b*|?-g3wn@4}K#OY0*m~Xuaq9=}rbl?$_yFDDcN*WC&>(@1_(i z{1zG~is`dA%Gxh-f$d@%w+RmCcQ94&5@s^_VZwCdbb|5gBe&sDiptu9659n02w6VQ zeI74liCAj*+R^YhFv)(?YuFeivmc1a$$UIixhs3-O_~0%-P=h`|4*_Tw*;qlB!mgt zylX9QNVd!IUecyrnGJrZX;mzn5YmwN$N9AXoSAdS$C0NY6uqC592UX@bC1XGpzHOe z0cP#k1!*mQc;&IrR`$^s(oWCAcMd+7yAbx=`+ELkmRLVqYa+qnap|bjn4HVc<++cG z>MO;qPePQQt%OBw*S5%#T5!><5sA(cZt&WaDLsJ|JEn4dIB5)<&bs+jwQ8ip=8y2j zgm6Kd7u_kvPfWcM-lWjlUf;9Nko5*o7ZY`k_o%;E839jHpZNgx|J3B}!>A?c2QH8J z2`K;ZF1K?N>Jb^Yu9@N1-3hiPNmKDqLFukpifiWul_=yemP)Yx>(@yQUw32ixFxL8 zB2uO);rc+e(%@H>F2j-~qZ;YUm5$2;!2|7gm9M=N%vhF1d5Q_UH1LUNIkUvySC)Sc z9hY^+WuID)_~8?-9Lq{91d8l5gu%HXG3$}nrslJ4Oaz*<+){OaEgHQ_L|6BW#jTvI z=shU?3%PQ-W7FO4&S@FB#kt^9)e$Ro&y6cD3_fC7-HLQMYoOfiiOeet^VsbTa8g^* zqOrl(d}#)4>OjN-R&!xX-na?x8s$;_u~DJx?i4|t$2>^AR-)l&LsMHWDQZX+cZYf2 z!f*BK{=ER{G;xZsesz7zm&X6d-m&jTCrQJ4`P3PVT0q&>5qo8VFF#B3&zq81*0U;` zYp>5|hZHOOD0aV=LXBg%eie)!F>Xo@dWvOtHu{SL4mf%?99cM;Cw_*m+h*y$4gkT96pkc!ty$}+022mdsNhJmwH5zXU+mBUybuDNRf3k2*JIHz2J#Z#`X9#T=S{4-jNZz z7R6)o-oS(pSI-&Y3L8^$t@vRN=byzi*7>xGXDd^N$#2gMd1uTws*mGZ_C4yhX)Jtl z)TcZJqv6nm5U`G65iiQjd%kc@s7B7e$TEs|;Gx=g1vLyMlXe3ngX_C@Vg}`xHWFJ9 zzAN(&Vh5(JHv;p_B}oy*e3Ty58T>{dDD-v)P8v`$WjhYfFBU$kQ{3dOXz7+U>GgOJ zx*R9|xJZ&dG-VIJ&38PW4ZioWi~s65wz$2X=)pqQt;Jh^D|5o&VFkqS0{J` z$K4`}@^k&tUUeB0C)T>4I_}IwrP^1fZOzT|Yh_p7B6v-h-B{*9o%m$s`)0tZDB*5P zjl-)y>K1bv_GWW4U*fNqR8-9cODU2jNhRmy za#Lb{KE0z9445v5e2AGfLujU=lh<37`cEfc-0k>Ex@Qd$8WYQnGAmiazR79{G8&Hb zps@9lQ!x=X28&hV;-|&^xx=eJJII$*CV$}tukC-=f1dqI<5S)(Ld_i|`0CO0kupOz z<=>>0VaZoLAxc7!n9CiZy9-Yy@FCi(k>{P1=j$cmY1t{MG5gJunn1)x$0 zpacSdwobi11h1nJ<+Vk-`F%XS;{+u(lf_#4lF#`*xGIkJ7AXGk1bh z^zmkll2`FTOooqY054FkDX_PTGGAGz;%9<;cgJGT@uL7BAl6&t+YVc(+Ha)OBl6T_Zy1t0AVV=z+MV7%dfw3 z8L0a8Fst#cPh((Qo6yU&styO)x_qXcOKoRwcmOX>kLcDHED-g|2@lY*Ps^^~8uPzx zNjavtVl6qSfe6GTZs<@5p37s)!9lCk-P{V7DbpTqzyR)HF+msPaAqQ_(r?5OmbFN9 zHdebd&R+dqTyw3;zAY_MiY_r|qRLBquqlc zMlfEUCNFX065nr8yJGgX*j2pNi2Irk$WpYVY(lGx5mRHH0=odC#vNd$|D+4&6d0`= zOljul0vdWF35M|WJC}iI5l6dB_jisz7V8n_=#U}6R}xI&0y8xQ_NgLMEgm+BCLie0 zCE65tNcE>+eU(&Wei`8Epx0*qu{bM#(kGO6;Za0Ud$ovlmG&ojj1Lr-p|}W2^|`U= zIn=5in>Sshc8s+fR0wGOlaU|}iT;-b7P}~KiH&bVwQ7#%7v1x+Vs-7ZuJGdp>m)7v|9? zg#iMW>ylV@rOP5gQmdM{$M2r7Zsw0l28j-NCO9RgR(&A`E_0N?bh(P4q)`j^j`eKs z8O3I1561#n&rQyb)r{W|%RM}REfJZaW^_i`cucn6BYHV|&|9~}Wh%YG?5iGG2G*YR zcry7mt~2Eo!gk`fVeN>{h~}WDm$_d~>z1=j<+U(-O;0zGxkHHLvVCAuTCr&1X`i~0 zGP-YqmTydFit%ICNV;{P6o|BO9ryZ(uc~(wGW)Ou8mF%u8+;R{(QVZn)C>HDP`^*p zsa_jd7t0L{PiC#w_W=tR0A~6(9>C3$A5=eExDV0R6^u!eD%&6-}He|iKnN+_!<&lvqv@~t9TrnXKCj1DljaLHA5#FpSh^*@zjl*yS2 zwMs-mu(szI7zy61?M#_P*t#{Cxg9|PL)tnx{NNupGM_wj6f1l$JNM!N5U4R~)#yPu ztL;T3r&?i>X7?74f+ea?3?Dly><2eUhulVafWvmoF|h5k@S4DZr@<~8(ZB(|Vs+_Z zE47D&wgOF}Y0IN9<@89_mMf4hq+OYI6EQcDXy;PS1@gC?uj--$zUFJoR2*&sy(X_*8Ml|7)$yWnFfNnIx**F2^V;N8tAV;ta9U8F z{&Ia>2OiI2RswRpt@V_P4z7kBjx~;PtXECg=pKOL-1TWlnbYJAoaE>ja2BFEAMt~MLYbgq_K9p6rB~zReRn0>kvZ4PFwVQ zo#t{_t9xqge0j6*DjyJ@U!P{}%7WWg`bV*T0FHgAT12N0LcpIFc<8!~J0JL8A;AV= zRMqrZjZD(@r7tHPuU(``8?7$Uh9k=+a*DlsLw-_s9Z&;YexK?HQC!46WYr(Z`qui>K1~#>=0jb-`MS*~FX4JPkf7a%l@V2|sDIBV z>CFR>O@`Wf-`y#EXg;_(aEV)@=bhI4newlxeR8w9wK}bndvcx3pPN&(-uas!(~qz# z$uy|o>d!Jbj+`PC+g;^$oruDHb}!b(9C!X$N)NrrpG)&GGBG8(NNLjuZPO}4Z+H>i zIZ|*^$bq?(Z|_zshFYX-PnjZpiDy25+TcQ6|bK^T>#7 zryf2)ztjb&#G;@XUd?l8K00H%K}a+ zz_;D6)b5NSfPe?Bl20(BIYMnpH+cY+xfHjxKl_~l!f-}=QJWLuzN-R4W$a>|58U>< zEsb^m^0g1-`;79CZ{PbRWSsBRU~*i+E7#fz7_wMi;9hz;_P7){S)hV3-_4(Q>B*kI z*O}3_obp9Sz=rR)2(SVn82((VxO4ij_Isqd1jc$VDm3g#ln_F8$pw%VIHj4Y15Pgp zYy5QE2^veRx1EUjeC8I5dcs8cHlc>XE~T4I27mVs1T4++1;aB44I(lIG|h`=WwbEg z@~>C~P|^a9wW6>k$i7qX%2+ic%Or>0iUlRQJ|A}$*NXA}0lbgPb1yS0*H*GxG9AC38ptK{|CkDX+S`)9yA73Ou6{dwY&b?`-P&8ADK5E z{=SyBX1xyK^61xQqh9of!OxXq;v;jgRn#Xyt1ZvB98zFZu_bq66NV3_XLT6#QESp8 z3E#f{#9cPpN*dGntc)2t&g$A9%nP7QzF^lb`UqSwgNKEdSyIxNe1I3K*XxpY^>E*A zO=wlfUOLobkY-3!Z)zD3-n)1XqAIvVdrkkJj|Y#>9zu+%W)N^uni!p4dCV(C7wPfd zakZ6Scay8NzagP5mH<%ISW&K^Q2k@36nZ6^EL=AnKiTLiSH$kmFVrRtFP#ggvSR1G zXI>r;5#>N)j>Z$Bt!Zwl6#uD2awe`9A2|nG6*q-kkHA$ygn|0 z|MDua^c8WZ@^_}}Y-3kdMY(B+>5DsMe_$beryz=!ykDoWSK>(%4o=c@fs=B+QL2k9 zDGp9I*ZvIZvNyi!vaN~%h&113#TxfNgw4wDZ~^c?=NHG~$dfw}>On~~;STufkibGH zDE!kO8==Jxi)4+qe!&DuHKQbM>;$V1io+|5OO?R61xn0mAMQeX*8$pc_$BZ;BGgsi z3FJMB_|!{dxnXFW4Ctdt<&*ij6>xztbp1!-jmIQn!6r6{fBetZXoHMC(apj~su+)} z?w&RwUQVJkWA*~6nxclH5eMdeh!`tV-M){t4bA;X&&ldHtjDM&vc3cAE8}KJ&xWt* z2!G`pnB|H}AH(akx(w&p%BUG^Wz0usI~j0mTJns-!ggO%3CG%w*W6o{=$YYG{62E+ z9^s=@?dO%Glx#$POQtR{++*mEPNyCRx2Gby>_yd|C5b_R&~{?gCC_$Bv2c_dEKJYL z{&nn$m{5bjTZvcEgk3KkCq#GvQB4!ft0AADL*TvT0?{d5VwEc;t%v&^_(2Gd>|%<)Q6T=6)2+)!+fA zDU~~{U+NbeSg}q{dgb3_z8mO~xZ~~idfyrUTdS45%k3X*BYguW7nHgRi~}^mZ)m5< zi1?M!m)#O0-jj5wrT{$5?iz<`C$ZYQEvi^Axp&p!}Te7Le5 z*-@hJ0iih|e8!xu>Ds1~KJ_D}Fc7f-ARUDBa76bcis^CyEvi3D#9EpQoKWACKp;|I z@1@=fka6*Zf$tR#QnN$DG_Xt_pwsuAYLPinYtpB)KQ%GW4{?8rkN~Hq9*4lynkJk2 zHlD-XVr8FlD-kO zMghakEDl;;7Zau&K(c^W_$r-EsGxn|WU+Cv)GL6CO!y-uME2k{te>(zQC=QpiqY7Z@*+fWuytU90?~{=zB69gkE< zGFNBM>q%p#6W#EVlmeSOXD|_AHLCsTh|Zpp(|}jC3Kw`&6>~>R^ism+O7lsnp5Ug} z$O8~9(i6$jsSQqWsQ5R>8kiuh1Vy9{*t-b@)G4JI+$O|OjG?BK`EnhwEavOQw}vsq zrqX}JkB$udTJ;WTDUCHQ`-*G*CYP%PMHit)#K*L@D-Q#&%#HdezoVp4*y@KMFmd-y zSVZ{Y4XAXNdYvMT@o4KSM#rGIvuQPu(%(ZGn2z*Es;!wQtlntA=_z-_AcV{tdh;<# z>CVs=vvdJsp1D`?`}!ZTp5qL-z#7#XxQ5;;j8fV^)j^2+JHt+bBWaJgfl#j>X^-%V zH+BM<3sX-WUj`1|AxtHtO}$7Cds~9Ak7GF`KjZ?_RZp2W|_V--A?g=c?-w;{)Gy+1g(>f$=kavI7$CDD@ibE z|J?M+nU4Wbb4BT}hpdM^@3;YbW2jYl98U@o@@Rbws7Jgg8hZ|)+0tv`zu63yQ&^6)9l{<0*N+h^mw z{Q<+_lGze-Aqpcya|5FwU#^<+`dhPQ;i-j>H%JU$GMLSj?>6hf0TGPU2jB%D1%E`&u!P=MYr?@_hgY0F*GTv zxEteA^D(E}maeIdiwTRT0cpSevbIV1s*+V`KmGgsHGO0@4`|jK$+COK?#MqNeE*?e zmR{cp%<+EGg)GN|N+#8eiDYcX2C1l$w3WO*8NgZe0EEO$E=g$3U48IIqH?&|xAe@H z!M+KRd~sP@^-fQ_)Gqr)r5wGIt2vIl@CZu31f@D&mv~>7ZO8?Rae<&H8AkxCc?i|OCa=O z(w8}*XJg9o7ZO7#^8)c3MGHe?8We)hk^1VsS_7w_wg~@&amriJg$nxtT1$k6(Mho3 zM6-Qj>f){Q``Z1f(I3pUn$BXDM~kBdZHkPEPhHeNfr}qUj{$DN96699<2Abz-#;?q zN70lQRrE&M}(GvazT z0D7CCY+n@E-K;oKwk@LO_w)3&$Pd#6W6Q)*4N|u5f627}lg(Qtsbnfc=?=7b%(i0@ zvahP;gU_15EA>B7rX97Fk8uiLDN?b{Xq z-A@XZU6*TW&=ztg;?4^Hay>k|ZGG6V#mYEIRmbD=QO&jDm8kWQ&AsKOU%LX?WZL%y z&cb}W`TYI+^P;7VFS28=)>&k~3RP&Di@SI=;kq92@s`A8X9D?)9NdT0bxPbyYyXyw zp+nwOts)raZDClKlVD1=Uvv0!DBk0H^w9Y@!oiv*tF^6yTwM9fgzF__t18~q+pHtm z7@V2Pi~T1J+e}l>NbDF?8}?;?xwmO1n9;p;O#1}YmIIkXap?(ignA$HQ0f z>}4H%UY%30|Ktt!e2|1{H9}OdrTv88p0yf@)AfyK?)k-JmPEG2)?RZriwF}6L@UZr zqs={&^t#VAuJ@0?=H#^MYIHj258%H#u5JoV7=vr^8_HK0M`gvIKKl!3chgSq@>;0= zUAw-Of9pn(+*%#>F2B?COC};g->xHdFK=dfk8FTZ_a|%-9kaoD zi&wX^A8!Ue3SMjqsfmt}yma!$bBm%-R&1Df45!}w;E}OUq|~?i&b2#4rh=QBfuAqB zuGkKa&A5~XJh!>y*Kl3VK`-%;e_4git pull. Here, the make maintainer-clean -should be used to remove all of the files generated by the @c bootstrap -script and subsequent build processes. - -In this particular case, one may also need to remove stray files by hand -after running this command to ensure everything is rebuilt properly. -This step should be necessary only if the @c maintainer-clean was run -@b after altering the build system files with git. If it is run -@b before any updates, the build system should never leave artifacts -in the tree. - -Without such precautions, changes can be introduced that leave the tree -timestamps in an inconsistent state, producing strange compile errors -that are resolve after such diligence. - -@subsection primermaintainerclean Autotools Cleaning - -Normally, all files generated by the bootstrap script, configure -process, and build system should be removed after running make -maintainer-clean. Automatically generated files that remain -after this should be listed in @c MAINTAINERCLEANFILES, -@c DISTCLEANFILES, or @c CLEANFILES, depending on which stage of the -build process they are produced. - -@section primerautoconf Autoconf Configuration Script - -The @c autoconf program generates the @c configure script from -@c configure.in, using serious Perl voodoo. The resulting script is -included in the project distribution packages and run by users to -configure the build process for their system. - -@section primerautomake Automake Makefiles - -The @c automake program generates @c Makefile.in files (from @c -Makefile.am files). These files are later processed by the configure -script produced by @c autoconf. - -@subsection primerautomakenewfiles Creating Makefile.am Files - -This section shows how to add a @c Makefile.am in a new directory (or -one that lacks one). --# The new directory must be listed in the @c SUBDIRS variable in the -parent directory's Makefile.am: -@code -$ echo 'SUBDIRS += directory' >>../Makefile.am -@endcode --# Create an bare-bones Makefile.am file in directory that needs it: -@code -$ echo "MAINTAINERCLEANFILES = Makefile.in" >Makefile.am -@endcode --# The @c configure.in script must be updated, so it generates the required -Makefile when the @a configure script is run by the user: -@verbatim -AC_OUTPUT([ - ... - path/to/new/Makefile - ]) -@endverbatim - -Note: these instructions are @b not meant to be used literally, rather -they are shown for demonstration purposes. - -The default MAINTAINERCLEANFILES rule ensures that the -automake-generated @c Makefile.in file will be removed when developers -run make maintainer-clean. Additional rules may be added -after this; however, the project should bootstrap and tear down cleanly -after taking these minimal steps, with the new directory being visited -during the @c make sequence. - -@subsection primerautomaketweaks Updating Makefile.am Files - -Adding, removing, and renaming files from the project tree usually -requires updating the autotools inputs. This section will help describe -how to do this as questions arise. - -@section primerlibtool Libtool and Libraries - -The @c libtool program provides the means of generating libraries in a -portable and painless manner (relatively speaking). - -This section will contain an answer to "what does libtool give OpenOCD?" -and "what do developers need to consider in new code?" - -@section primerautotoolsmation Autotools Automation - -This section outlines three ways the autotools provides automation to -assist with testing and distribution: -- @ref primerautocheck -- automatic unit and smoke tests -- @ref primerautodistcheck -- automatic distribution and packaging tests - -@subsection primerautocheck make check - -The make check command will run the OpenOCD test suite, -once it has been integrated as such. This section will contain -information about how to extend the testing build system components to -implement new checks. - -@subsection primerautodistcheck make distcheck - -The make distcheck command produces an archive of the -project deliverables (using make dist) and verifies its -integrity for distribution by attemptng to use the package in the same -manner as a user. - -These checks includes the following steps: --# Unpack the project archive into its expected directory. --# Configure and build the project in a temporary out-of-tree directory. --# Run make check to ensure the distributed code passes all tests. --# Run make install into a temporary installation directory. --# Check that make uninstall removes all files that were installed. --# Check that make distclean removes all files created -during all other steps (except the first). - -If all of these steps complete successfully, the @c make process will -output a friendly message indicating the archive is ready to be -distributed. - - */ -/** @file - -This file contains the @ref primerautotools page. - - */ diff --git a/doc/manual/primer/commands.txt b/doc/manual/primer/commands.txt deleted file mode 100644 index 5f89d5062..000000000 --- a/doc/manual/primer/commands.txt +++ /dev/null @@ -1,138 +0,0 @@ -/** @page primercommand Command Development Primer - -This page provides a primer for writing commands by introducing @c hello -module. The full source code used in this example can be found in -hello.c, and the @ref primercmdcode section shows how to use it. - -A summary of this information can be found in @ref helpercommand . - -@section primercmdhandler Command Handlers - -Defining new commands and their helpers is easy. The following code -defines a simple command handler that delegates its argument parsing: -@code -COMMAND_HANDLER(handle_hello_command) -{ - const char *sep, *name; - int retval = CALL_COMMAND_HANDLER(handle_hello_args); - if (ERROR_OK == retval) - command_print(CMD_CTX, "Greetings%s%s!", sep, name); - return retval; -} -@endcode - -Here, the @c COMMAND_HANDLER macro establishes the function signature, -see in command.h by the @c __COMMAND_HANDLER macro. - -The COMMAND_HELPER macro function allows defining functions with an -extended version of the base signature. These helper functions can be -called (with the appropriate parameters), the @c CALL_COMMAND_HANDLER -macro to pass any e as parameters to the following helper function: - -The subsequent blocks of code are a normal C function that can do -anything, so only complex commands deserve should use comamnd helper -functions. In this respect, this example uses one to demonstrate how -- -not when -- they should be used. - -@code -static COMMAND_HELPER(handle_hello_args, const char **sep, const char **name) -{ - if (argc > 1) - { - LOG_ERROR("%s: too many arguments", CMD_NAME); - return ERROR_COMMAND_SYNTAX_ERROR; - } - if (1 == CMD_ARGC) - { - *sep = ", "; - *name = CMD_ARGV[0]; - } - else - *sep = *name = ""; - - return ERROR_OK; -} -@endcode - -Of course, you may also call other macros or functions, but that extends -beyond the scope of this tutorial on writing commands. - -@section primercmdreg Command Registration - -Before this new function can be used, it must be registered somehow. -For a new module, registering should be done in a new function for -the purpose, which must be called from @c openocd.c: -@code - -static const struct command_registration hello_command_handlers[] = { - { - .name = "hello", - .mode = COMMAND_ANY, - .handler = handle_hello_command, - .help = "print a warm greeting", - .usage = "[name]", - }, - { - .chain = foo_command_handlers, - } - COMMAND_REGISTRATION_DONE -}; - -int hello_register_commands(struct command_context_s *cmd_ctx) -{ - return register_commands(cmd_ctx, NULL, handle_command_handlers); -} -@endcode - -Note that the "usage" text should use the same EBNF that's found -in the User's Guide: literals in 'single quotes', sequences of -optional parameters in [square brackets], and alternatives in -(parentheses|with|vertical bars), and so forth. No angle brackets. - -That's it! The command should now be registered and available to scripts. - -@section primercmdchain Command Chaining - -This example also shows how to chain command handler registration, so -your modules can "inherit" commands provided by other (sub)modules. -Here, the hello module includes the foo commands in the same context -that the 'hello' command will be registered. - -If the @c chain field had been put in the 'hello' command, then the -@c foo module commands would be registered under it. Indeed, that -technique is used to define the 'foo bar' and 'foo baz' commands, -as well as for the example drivers that use these modules. - -The code for the 'foo' command handlers can be found in @c hello.c. - -@section primercmdcode Trying These Example Commands - -These commands have been inherited by the dummy interface, faux flash, -and testee target drivers. The easiest way to test these is by using the -dummy interface. - -Once OpenOCD has been built with this example code, the following command -demonstrates the abilities that the @c hello module provides: -@code -openocd -c 'interface dummy' \ - -c 'dummy hello' \ - -c 'dummy hello World' \ - -c 'dummy hello {John Doe}' \ - -c 'dummy hello John Doe' # error: too many arguments -@endcode - -If saved in @c hello.cfg, then running openocd -f hello.cfg -should produce the following output before displaying the help text and -exiting: -@code -Greetings! -Greetings, World! -Greetings, John Doe! -Error: hello: too many arguments -Runtime error, file "openocd.cfg", line 14: - hello: too many arguments -dummy hello [] - prints a warm welcome -@endcode - - */ diff --git a/doc/manual/primer/docs.txt b/doc/manual/primer/docs.txt deleted file mode 100644 index 504da7907..000000000 --- a/doc/manual/primer/docs.txt +++ /dev/null @@ -1,124 +0,0 @@ -/** @page primerdocs OpenOCD Documentation Primers - -This page provides an introduction to OpenOCD's documentation processes. - -OpenOCD presently produces several kinds of documentation: -- The User's Guide: - - Focuses on using the OpenOCD software. - - Details the installation, usage, and customization. - - Provides descriptions of public Jim/TCL script commands. - - Written using GNU texinfo. - - Created with 'make pdf' or 'make html'. - - See @subpage primertexinfo and @ref styletexinfo. -- The References: (as proposed) - - Focuses on using specific hardware with OpenOCD. - - Details the supported interfaces, chips, boards, and targets. - - Provides overview, usage, reference, and FAQ for each device. - - Written using LaTeX language with custom macros. - - Created with 'make references'. - - See @subpage primerlatex and @ref stylelatex. -- The Manual: - - Focuses on developing the OpenOCD software. - - Details the architecutre, driver interfaces, and processes. - - Provides "full" coverage of C source code (work-in-progress). - - Written using Doxygen C language conventions (i.e. in comments). - - Created with 'make doxygen'. - - See @subpage primerdoxygen and @ref styledoxygen. - -The following sections provide more information for anyone that wants to -contribute new or updated documentation to the OpenOCD project. - - */ -/** @page primertexinfo Texinfo Primer - -The OpenOCD User's Guide presently exists entirely within the -doc/openocd.texi document. That file contains documentation with -mark-up suitable for being parsed by the GNU Texinfo utilities -(http://www.gnu.org/software/texinfo/). - -When you add a new command, driver, or driver option, it needs to be -documented in the User's Guide. Use the existing documentation for -models, but feel free to make better use of Texinfo mechanisms. See -the Texinfo web site for the Texinfo manual and more information. - -OpenOCD style guidelines for Texinfo documentation can be found on the -@ref styletexinfo page. - - */ -/** @page primerlatex LaTeX Primer - -The OpenOCD project provides a number of reference guides using the -LaTeX typesetting language. - -- OpenOCD Quick Reference Sheets -- OpenOCD Hardware Reference Guides - -These documents have not yet been produced, so this Primer serves as -a placeholder to describe how they are created and can be extended. -The same holds true for the @ref stylelatex page. - - */ -/** @page primerdoxygen Doxygen Primer - -Doxygen-style comments are used to provide documentation in-line with -the OpenOCD source code. These comments are used to document functions, -variables, structs, enums, fields, and everything else that might need -to be documented for developers. Additional files containing comments -that supplement the code comments in order to provide complete developer -documentation. - -Even if you already know Doxygen, please read this Primer to learn -how OpenOCD developers already use Doxygen features in the project tree. -For more information about OpenOCD's required style for using Doxygen, -see the @ref styledoxygen page and look at existing documentation in the -@c doc/manual tree. - -@section primerdoxytext Doxygen Input Files - -Doxygen has been configured parse all of the C source code files (*.c -and *.h) in @c src/ in order to produce a complete reference of all -OpenOCD project symbols. In addition to the source code files, other -files will also be scanned for comment blocks; some are referenced -explicitly by the @c INPUT variable in the Doxygen configuration file. - -By default, the Doxygen configuration enables a "full" set of features, -including generation of dependency graphs (using the GraphViz package). -These features may be disabled by editing the @c Doxyfile.in file at the -top of the project tree; the configuration file includes comments that -provide detailed documentation for each option. - -To support out-of-tree building of the documentation, the @c Doxyfile.in -@c INPUT values will have all instances of the string @c "@srcdir@" -replaced with the current value of the make variable -$(srcdir). The Makefile uses a rule to convert -@c Doxyfile.in into the @c Doxyfile used by make doxygen. - -@section primerdoxyoocd OpenOCD Input Files - -OpenOCD uses the @c INPUT mechanism to include additional documentation to -provide The Manual for OpenOCD Developers. These extra files contain -high-level information intended to supplement the relatively low-level -documentation that gets extracted from the source code comments. - -OpenOCD's Doxygen configuration file will search for all @c .txt files -that can be found under the @c doc/manual directory in the project tree. -New files containing valid Doxygen markup that are placed in or under -that directory will be detected and included in The Manual automatically. - -@section primerdoxyman Doxygen Reference Manual - -The full documentation for Doxygen can be referenced on-line at the project -home page: http://www.doxygen.org/index.html. In HTML versions of this -document, an image with a link to this site appears in the page footer. - -*/ -/** @file - -This file contains the Doxygen source code for the @ref primerdocs. -The @ref primerdocs page also contains the following sections: - -- @ref primertexinfo -- @ref primerlatex -- @ref primerdoxygen - - */ diff --git a/doc/manual/primer/jtag.txt b/doc/manual/primer/jtag.txt deleted file mode 100644 index 41eef723d..000000000 --- a/doc/manual/primer/jtag.txt +++ /dev/null @@ -1,169 +0,0 @@ -/** @page primerjtag OpenOCD JTAG Primer - -JTAG is unnecessarily confusing, because JTAG is often confused with -boundary scan, which is just one of its possible functions. - -JTAG is simply a communication interface designed to allow communication -to functions contained on devices, for the designed purposes of -initialisation, programming, testing, debugging, and anything else you -want to use it for (as a chip designer). - -Think of JTAG as I2C for testing. It doesn't define what it can do, -just a logical interface that allows a uniform channel for communication. - -See @par - http://en.wikipedia.org/wiki/Joint_Test_Action_Group - -@image html jtag-state-machine-large.png - -The first page (among other things) shows a logical representation -describing how multiple devices are wired up using JTAG. JTAG does not -specify, data rates or interface levels (3.3V/1.8V, etc) each device can -support different data rates/interface logic levels. How to wire them -in a compatible way is an exercise for an engineer. - -Basically TMS controls which shift register is placed on the device, -between TDI and TDO. The second diagram shows the state transitions on -TMS which will select different shift registers. - -The first thing you need to do is reset the state machine, because when -you connect to a chip you do not know what state the controller is in,you need -to clock TMS as 1, at least 5 times. This will put you into "Test Logic -Reset" State. Knowing this, you can, once reset, then track what each -transition on TMS will do, and hence know what state the JTAG state -machine is in. - -There are 2 "types" of shift registers. The Instruction shift register -and the data shift register. The sizes of these are undefined, and can -change from chip to chip. The Instruction register is used to select -which Data register/data register function is used, and the data -register is used to read data from that function or write data to it. - -Each of the states control what happens to either the data register or -instruction register. - -For example, one of the data registers will be known as "bypass" this is -(usually) a single bit which has no function and is used to bypass the -chip. Assume we have 3 identical chips, wired up like the picture(wikipedia) -and each has a 3 bits instruction register, and there are 2 known -instructions (110 = bypass, 010 = "some other function") if we want to use -"some other function", on the second chip in the line, and not change -the other chips we would do the following transitions. - -From Test Logic Reset, TMS goes: - - 0 1 1 0 0 - -which puts every chip in the chain into the "Shift IR state" -Then (while holding TMS as 0) TDI goes: - - 0 1 1 0 1 0 0 1 1 - -which puts the following values in the instruction shift register for -each chip [110] [010] [110] - -The order is reversed, because we shift out the least significant bit -first. Then we transition TMS: - - 1 1 1 0 0 - -which puts us in the "Shift DR state". - -Now when we clock data onto TDI (again while holding TMS to 0) , the -data shifts through the data registers, and because of the instruction -registers we selected ("some other function" has 8 bits in its data -register), our total data register in the chain looks like this: - - 0 00000000 0 - -The first and last bit are in the "bypassed" chips, so values read from -them are irrelevant and data written to them is ignored. But we need to -write bits for those registers, because they are in the chain. - -If we wanted to write 0xF5 to the data register we would clock out of -TDI (holding TMS to 0): - - 0 1 0 1 0 1 1 1 1 0 - -Again, we are clocking the least-significant bit first. Then we would -clock TMS: - - 1 1 0 - -which updates the selected data register with the value 0xF5 and returns -us to run test idle. - -If we needed to read the data register before over-writing it with F5, -no sweat, that's already done, because the TDI/TDO are set up as a -circular shift register, so if you write enough bits to fill the shift -register, you will receive the "captured" contents of the data registers -simultaneously on TDO. - -That's JTAG in a nutshell. On top of this, you need to get specs for -target chips and work out what the various instruction registers/data -registers do, so you can actually do something useful. That's where it -gets interesting. But in and of itself, JTAG is actually very simple. - -@section primerjtag More Reading - -A separate primer contains information about @subpage primerjtagbs for -developers that want to extend OpenOCD for such purposes. - - */ -/** @page primerjtagbs JTAG Boundary Scan Primer - -The following page provides an introduction on JTAG that focuses on its -boundary scan capabilities: @par -http://www.engr.udayton.edu/faculty/jloomis/ece446/notes/jtag/jtag1.html - -OpenOCD does not presently have clear means of using JTAG for boundary -scan testing purposes; however, some developers have explored the -possibilities. The page contains information that may be useful to -those wishing to implement boundary scan capabilities in OpenOCD. - -@section primerbsdl The BSDL Language - -For more information on the Boundary Scan Description Language (BSDL), -the following page provides a good introduction: @par -http://www.radio-electronics.com/info/t_and_m/boundaryscan/bsdl.php - -@section primerbsdlvendors Vendor BSDL Files - -NXP LPC: @par -http://www.standardics.nxp.com/support/models/lpc2000/ - -Freescale PowerPC: @par -http://www.freescale.com/webapp/sps/site/overview.jsp?code=DRPPCBSDLFLS - -Freescale i.MX1 (too old): @par -http://www.freescale.com/webapp/sps/site/prod_summary.jsp?code=i.MX1&nodeId=0162468rH311432973ZrDR&fpsp=1&tab=Design_Tools_Tab - -Renesas R32C/117: @par -http://sg.renesas.com/fmwk.jsp?cnt=r32c116_7_8_root.jsp&fp=/products/mpumcu/m16c_family/r32c100_series/r32c116_7_8_group/ -- The device page does not come with BSDL file; you have to register to - download them. @par - http://www.corelis.com/support/BSDL.htm - -TI links theirs right off the generic page for each chip; -this may be the case for other vendors as well. For example: - -- DaVinci DM355 -- http://www.ti.com/litv/zip/sprm262b -- DaVinci DM6446 - - 2.1 silicon -- http://www.ti.com/litv/zip/sprm325a - - older silicon -- http://www.ti.com/litv/zip/sprm203 -- OMAP 3530 - - CBB package -- http://www.ti.com/litv/zip/sprm315b - - 515 ball s-PGBA, POP, 0.4mm pitch - - CUS package -- http://www.ti.com/litv/zip/sprm314a - - 515 ball s-PGBA, POP, 0.5mm pitch - - CBC package -- http://www.ti.com/litv/zip/sprm346 - - 423 ball s-PGBA, 0.65mm pitch - -Many other files are available in the "Semiconductor Manufacturer's BSDL -files" section of the following site: @par -http://www.freelabs.com/~whitis/electronics/jtag/ - - */ -/** @file -This file contains the @ref primerjtag and @ref primerjtagbs page. - */ diff --git a/doc/manual/primer/tcl.txt b/doc/manual/primer/tcl.txt deleted file mode 100644 index 9be4a05e0..000000000 --- a/doc/manual/primer/tcl.txt +++ /dev/null @@ -1,440 +0,0 @@ -/** @page primertcl OpenOCD TCL Primer - -The @subpage scripting page provides additional TCL Primer material. - -@verbatim - -**************************************** -**************************************** - -This is a short introduction to 'un-scare' you about the language -known as TCL. It is structured as a guided tour through the files -written by me [Duane Ellis] - in early July 2008 for OpenOCD. - -Which uses the "JIM" embedded Tcl clone-ish language. - -Thing described here are *totally* TCL generic... not Jim specific. - -The goal of this document is to encourage you to add your own set of -chips to the TCL package - and most importantly you should know where -you should put them - so they end up in an organized way. - ---Duane Ellis. - duane@duaneellis.com - -**************************************** -**************************************** - -Adding "chip" support - Duane Ellis July 5 - 2008. - -The concept is this: - In your "openocd.cfg" file add something like this: - - source [find tcl/chip/VENDOR/FAMILY/NAME.tcl] - - For example... - source [find tcl/chip/atmel/at91/at91sam7x256.tcl] - - You'll notice that it makes use of: - - tcl/cpu/arm/.tcl. - - Yes, that is where you should put "core" specific things. - Be careful and learn the difference: - - THE "CORE" - is not the entire chip! - -Definition: - That "file" listed above is called a "CHIP FILE". - - It may be standalone, or may need to "source" other "helper" files. - - The reference [7/5/2008] is the at91sam7x256.tcl file. - -**************************************** -**************************************** -=== TCL TOUR === -Open: at91sam7x256.tcl -=== TCL TOUR === - -A walk through --- For those who are new to TCL. - -Examine the file: at91sam7x256.tcl - -It starts with: - source [find path/filename.tcl] - -In TCL - this is very important. - - Rule #1 Everything is a string. - Rule #2 If you think other wise See #1. -Reminds you of: - Rule #1: The wife is correct. - Rule #2: If you think otherwise, See #1 - -Any text contained inside of [square-brackets] -is just like `back-ticks` in BASH. - -Hence, the [find FILENAME] executes the command find with a single -parameter the filename. - -======================================== - -Next you see a series of: - -set NAME VALUE - -It is mostly "obvious" what is going on. - -Exception: The arrays. - - You would *THINK* Tcl supports arrays. - In fact, multi-dim arrays. That is false. - - For the index for"FLASH(0,CHIPSELECT)" is actually the string - "0,CHIPSELECT". This is problematic. In the normal world, you think - of array indexes as integers. - - For example these are different: - - set foo(0x0c) 123 - set foo(12) 444 - - Why? Because 0x0c {lowercase} is a string. - Don't forget UPPER CASE. - - You must be careful - always... always... use simple decimal - numbers. When in doubt use 'expr' the evaluator. These are all the - same. - - set x 0x0c - set foo([expr $x]) "twelve" - - set x 12 - set foo([expr $x]) "twelve" - - set x "2 * 6" - set foo([expr $x]) "twelve" - -************************************************** -*************************************************** -=== TCL TOUR === -Open the file: "bitsbytes.tcl" - -There is some tricky things going on. -=============== - -First, there is a "for" loop - at level 0 -{level 0 means: out side of a proc/function} - -This means it is evaluated when the file is parsed. - -== SIDEBAR: About The FOR command == -In TCL, "FOR" is a funny thing, it is not what you think it is. - -Syntactically - FOR is a just a command, it is not language -construct like for(;;) in C... - -The "for" command takes 4 parameters. - (1) The "initial command" to execute. - (2) the test "expression" - (3) the "next command" - (4) the "body command" of the FOR loop. - -Notice I used the words "command" and "expression" above. - -The FOR command: -1) executes the "initial command" -2) evaluates the expression if 0 it stops. -3) executes the "body command" -4) executes the "next command" -5) Goto Step 2. - -As show, each of these items are in {curly-braces}. This means they -are passed as they are - KEY-POINT: un evaluated to the FOR -command. Think of it like escaping the backticks in Bash so that the -"under-lying" command can evaluate the contents. In this case, the FOR -COMMAND. - -== END: SIDEBAR: About The FOR command == - -You'll see two lines: - -LINE1: - set vn [format "BIT%d" $x] - -Format is like "sprintf". Because of the [brackets], it becomes what -you think. But here's how: - -First - the line is parsed - for {braces}. In this case, there are -none. The, the parser looks for [brackets] and finds them. The, -parser then evaluates the contents of the [brackets], and replaces -them. It is alot this bash statement. - - EXPORT vn=`date` - -LINE 2 & 3 - set $vn [expr (1024 * $x)] - global $vn - -In line 1, we dynamically created a variable name. Here, we are -assigning it a value. Lastly Line 3 we force the variable to be -global, not "local" the the "for command body" - -=============== -The PROCS - -proc create_mask { MSB LSB } { - ... body .... -} - -Like "for" - PROC is really just a command that takes 3 parameters. -The (1) NAME of the function, a (2) LIST of parameters, and a (3) BODY - -Again, this is at "level 0" so it is a global function. (Yes, TCL -supports local functions, you put them inside of a function} - -You'll see in some cases, I nest [brackets] alot and in others I'm -lazy or wanted it to be more clear... it is a matter of choice. -=============== - - -************************************************** -*************************************************** -=== TCL TOUR === -Open the file: "memory.tcl" -=============== - -Here is where I setup some 'memory definitions' that various targets can use. - -For example - there is an "unknown" memory region. - -All memory regions must have 2 things: - - (1) N_ - (2) NAME( array ) - And the array must have some specific names: - ( , THING ) - Where: THING is one of: - CHIPSELECT - BASE - LEN - HUMAN - TYPE - RWX - the access ability. - WIDTH - the accessible width. - - ie: Some regions of memory are not 'word' - accessible. - -The function "address_info" - given an address should -tell you about the address. - - [as of this writing: 7/5/2008 I have done - only a little bit with this -Duane] - -=== -MAJOR FUNCTION: -== - -proc memread32 { ADDR } -proc memread16 { ADDR } -proc memread8 { ADDR } - -All read memory - and return the contents. - -[ FIXME: 7/5/2008 - I need to create "memwrite" functions] - -************************************************** -*************************************************** -=== TCL TOUR === -Open the file: "mmr_helpers.tcl" -=============== - -This file is used to display and work with "memory mapped registers" - -For example - 'show_mmr32_reg' is given the NAME of the register to -display. The assumption is - the NAME is a global variable holding the -address of that MMR. - -The code does some tricks. The [set [set NAME]] is the TCL way -of doing double variable interpolation - like makefiles... - -In a makefile or shell script you may have seen this: - - FOO_linux = "Penguins rule" - FOO_winXP = "Broken Glass" - FOO_mac = "I like cat names" - - # Pick one - BUILD = linux - #BUILD = winXP - #BUILD = mac - FOO = ${FOO_${BUILD}} - -The "double [set] square bracket" thing is the TCL way, nothing more. - ----- - -The IF statement - and "CATCH" . - -Notice this IF COMMAND - (not statement) is like this: -[7/5/2008 it is this way] - - if ![catch { command } msg ] { - ...something... - } else { - error [format string...] - } - -The "IF" command expects either 2 params, or 4 params. - - === Sidebar: About "commands" === - - Take a look at the internals of "jim.c" - Look for the function: Jim_IfCoreCommand() - And all those other "CoreCommands" - - You'll notice - they all have "argc" and "argv" - - Yea, the entire thing is done that way. - - IF is a command. SO is "FOR" and "WHILE" and "DO" and the - others. That is why I keep using the phase it is a "command" - - === END: Sidebar: About "commands" === - -Parameter 1 to the IF command is expected to be an expression. - -As such, I do not need to wrap it in {braces}. - -In this case, the "expression" is the result of the "CATCH" command. - -CATCH - is an error catcher. - -You give CATCH 1 or 2 parameters. - The first 1st parameter is the "code to execute" - The 2nd (optional) is where to put the error message. - - CATCH returns 0 on success, 1 for failure. - The "![catch command]" is self explaintory. - - -The 3rd parameter to IF must be exactly "else" or "elseif" [I lied -above, the IF command can take many parameters they just have to -be joined by exactly the words "else" or "elseif". - -The 4th parameter contains: - - "error [format STRING....]" - -This lets me modify the previous lower level error by tacking more -text onto the end of it. In this case, i want to add the MMR register -name to make my error message look better. - ---------- -Back to something inside show_mmr32_reg{}. - -You'll see something 'set fn show_${NAME}_helper' Here I am -constructing a 'function name' Then - I look it up to see if it -exists. {the function: "proc_exists" does this} - -And - if it does - I call the function. - -In "C" it is alot like using: 'sprintf()' to construct a function name -string, then using "dlopen()" and "dlsym()" to look it up - and get a -function pointer - and calling the function pointer. - -In this case - I execute a dynamic command. You can do some cool -tricks with interpretors. - ----------- - -Function: show_mmr32_bits() - -In this case, we use the special TCL command "upvar" which tcl's way -of passing things by reference. In this case, we want to reach up into -the callers lexical scope and find the array named "NAMES" - -The rest of the function is pretty straight forward. - -First - we figure out the longest name. -Then print 4 rows of 8bits - with names. - - -************************************************** -*************************************************** -=== TCL TOUR === -Open the file: "chips/atmel/at91/usarts.tcl" -=============== - -First - about the AT91SAM series - all of the usarts -are basically identical... - -Second - there can be many of them. - -In this case - I do some more TCL tricks to dynamically -create functions out of thin air. - -Some assumptions: - -The "CHIP" file has defined some variables in a proper form. - -ie: AT91C_BASE_US0 - for usart0, - AT91C_BASE_US1 - for usart1 - ... And so on ... - -Near the end of the file - look for a large "foreach" loop that -looks like this: - - foreach WHO { US0 US1 US2 US3 US4 .... } { - - } - -In this case, I'm trying to figure out what USARTs exist. - -Step 1 - is to determine if the NAME has been defined. -ie: Does AT91C_BASE_USx - where X is some number exist? - -The "info exists VARNAME" tells you if the variable exists. Then - -inside the IF statement... There is another loop. This loop is the -name of various "sub-registers" within the USART. - -Some more trick are played with the [set VAR] backtick evaluation stuff. -And we create two variables - -We calculate and create the global variable name for every subregister in the USART. -And - declare that variable as GLOBAL so the world can find it. - -Then - we dynamically create a function - based on the register name. - -Look carefully at how that is done. You'll notice the FUNCTION BODY is -a string - not something in {braces}. Why? This is because we need TCL -to evaluate the contents of that string "*NOW*" - when $vn exists not -later, when the function "show_FOO" is invoked. - -Lastly - we build a "str" of commands - and create a single function - -with the generated list of commands for the entire USART. - -With that little bit of code - I now have a bunch of functions like: - - show_US0, show_US1, show_US2, .... etc ... - - And show_US0_MR, show_US0_IMR ... etc... - -And - I have this for every USART... without having to create tons of -boiler plate yucky code. - -**************************************** -**************************************** -END of the Tcl Intro and Walk Through -**************************************** -**************************************** - -FUTURE PLANS - - Some "GPIO" functions... - -@endverbatim - - */ diff --git a/doc/manual/release.txt b/doc/manual/release.txt deleted file mode 100644 index d14475692..000000000 --- a/doc/manual/release.txt +++ /dev/null @@ -1,465 +0,0 @@ -/** @page releases Release Processes - -This page provides an introduction to the OpenOCD Release Processes: - -- @ref releasewhy - Explain the motivations for producing - releases on a regular basis. -- @ref releasewho - Describes the responsibilities and - authority required to produce official OpenOCD releases. -- @ref releasewhen - Provides guidelines for scheduling - activities for each release cycle. -- @ref releasehow - Outlines all of the steps for the - processes used to produce and release the package source archives. -- @ref releasescriptcmds - Introduces the automated @c release.sh script. - -@section releasewhy Why Produce Releases? - -The OpenOCD maintainers produce releases periodically for many -reasons. This section provides the key reasons for making releases on a -regular basis and why a set of release processes should be used -to produce them. - -At any time, source archives can be produced by running -make dist in the OpenOCD project tree. With the 0.2.0 -release, this command will package the tree into several popular archive -formats: openocd-\.{tar.gz,tar.bz2,zip}. If -produced properly, these files are suitable for release to the public. - -When properly versioned and released for users, these archives present -several important advantages compared to using the source repository -(including snapshots downloaded from that repository using gitweb): - --# They allow others to package and distribute the code using - consistent version labels. Users won't normally need to care - whose package they use, just the version of OpenOCD. --# They contain a working configure script and makefiles, which - were produced as part of creating the archive. --# Because they have been formally released by the project, users - don't need to try a random work-in-process revision. Releasing - involves spending some time specifically on quality improvments, - including bugfixing source code and documentation. --# They provide developers with the flexibility needed to address - larger issues, which sometimes involves temporary breakage. - -Hopefully, this shows several good reasons to produce regular releases, -but the release processes were developed with some additional design -goals in mind. Specifically, the releases processes should have the -following properties: - --# Produce successive sets of archives cleanly and consistently. --# Implementable as a script that automates the critical steps. --# Prevent human operators from producing broken packages, when possible. --# Allow scheduling and automation of building and publishing milestones. - -The current release processes are documented in the following sections. -They attempt to meet these design goals, but improvements may still -need to be made. - -@subsection version_labels Version Labels - -Users can display the OpenOCD version string in at least two -ways. The command line openocd -v invocation -displays it; as does the Tcl version command. - -Labels for released versions look like 0.3.0, or -0.3.0-rc1 for a preliminary release. -Non-released (developer) versions look like 0.3.0-dev, -or 0.3.0-rc1-dev. -In all cases, additional tags may be appended to those base -release version labels. - -The tools/release/version.sh script is used to -manipulate version IDs found in the source tree. - -@subsubsection releaseversions Release Versions and Tags - -The OpenOCD version string is composed of three numeric components -separated by two decimal points: @c x.y.z, where @c x is the @a major -version number, @c y is the @a minor number, and @c z is the @a micro. -For any bug-fix release, the micro version number will be non-zero -(z > 0). For a minor release, the micro version -number will be zero (z = 0). For a major releases, -the minor version will @a also be zero (y = 0, z = 0). - -After these required numeric components, release version strings -may contain tags such as as -rc1 or -rc2. -These 'rc' tags indicate "release candidate" versions of the package. -Like major/minor/micro numbers, these are updated -as part of the release process. - -The release process includes version number manipulations to the tree -being released, ensuring that all numbers are incremented (or rolled -over) at the right time and in the proper locations of the repository. -One of those manipulations creates a repository tag matching that -release's version label. - -@subsubsection releaseversionsdist Packager Versions - -Distributors of patched versions of OpenOCD are encouraged to extend the -version string with a unique version tag when producing external -releases, as this helps to identify your particular distribution series. -Knowing that a release has such patches can be essential to tracking -down and fixing bugs. - -Packager version tags should always be suffixes to the version -code from the OpenOCD project, signifying modifications to the -original code base. Each packager release should have a unique -version. - -For example, the following command will add a 'foo' tag to the -configure.ac script of a local copy of the source tree, giving -a version label like 0.3.0-foo: - -@code -tools/release/version.sh tag add foo -@endcode - -This command will modify the configure.ac script in your working copy -only. After running the @c bootstrap sequence, the tree can be patched -and used to produce your own derived versions. You might check that -change into a private branch of your git tree, along with the other -patches you are providing. - -You can also "bump" those tags (so "foo1" becomes "foo2" etc) -each time a derived package is released, incrementing the tag's -version to facilitate tracking the changes you have distributed. - -@code -tools/release/version.sh bump tag foo -@endcode - -Of course, any patches in your branches must be provided to -your customers, and be in conformance with the GPL. In most -cases you should also work to merge your improvements to the -mainline tree. - -@subsubsection version_tags Development Versions and Tags - -Everything except formal releases should have the tag -dev -in their version number. This helps developers identify reports -created from non-release versions, and it can be detected and -manipulated by the release script. Specifically, this tag will be -removed and re-added during the release process; it should never be -manipulated by developers in submitted patches. - -Versions built from developer trees may have additional tags. -Trees built from git snapshots have snapshot tags. -When built from a "live" git tree, tags specify -specific git revisions: - -0.3.0-rc1-dev-00015-gf37c9b8-dirty - -indicates a development tree based on git revison f37c9b8 -(a truncated version of a SHA1 hash) with some non-git -patches applied (the dirty tag). This information -can be useful when tracking down bugs. -(Note that at this writing, the tags do not directly -correspond to git describe output. The -hash ID can be used with git show, but -the relevant repository tag isn't 0.3.0-rc1-dev; -this might change in the future.) - -@section releasewho Release Manager - -OpenOCD archive releases will be produced by an individual filling the -role of Release Manager, hereafter abbreviated as RM. This -individual determines the schedule and executes the release processes -for the community. - -@subsection releasewhohow RM Authority - -Each release requires one individual to fulfill the RM role; however, -graceful transitions of this authority may take place at any time. The -current RM may transfer their authority to another contributor in a post -to the OpenOCD development mailing list. Such delegation of authority -must be approved by the individual that will receive it and the -community of maintainers. Initial arrangements with the new RM should -be made off-list, as not every contributor wants these responsibilities. - -@subsection releasewhowhat RM Responsibilities - -In addition to the actual process of producing the releases, the RM is -responsible for keeping the community informed of all progress through -the release cycle(s) being managed. The RM is responsible for managing -the changes to the package version, though the release tools should -manage the tasks of adding or removing any required development branch -tags and incrementing the version. - -These responsibilities matter most towards the end of the release -cycle, when the RM creates the first RC and all contributors enter -a quality-improvement mode. The RM works with other contributors -to make sure everyone knows what kinds of fixes should merge, the -status of major issues, and the release timetable. - -In particular, the RM has the final decision on whether a given -bug should block the release. - -@section releasewhen Release Schedule - -The OpenOCD release process must be carried out on a periodic basis, so -the project can realize the benefits presented in answer to the question, -@ref releasewhy. - -Starting with the 0.2.0 release, the OpenOCD project expects to produce -new releases every few months. -Bug fix releases could be provided more frequently. These release -schedule goals may be adjusted in the future, after the project -maintainers and distributors receive feedback and experience. - -More importantly, the statements made in this section do not create an -obligation by any member of the OpenOCD community to produce new -releases on regular schedule, now or in the future. - -@subsection releasewhenexample Sample Schedule - -The RM must pro-actively communicate with the community from the -beginning of the development cycle through the delivery of the new -release. This section presents guidelines for scheduling key points -where the community must be informed of changing conditions. - -If Tn is the time of release n, then the following schedule -might describe some key T0-to-T1 release cycle milestones. - -- T0 ... End of T0 release cycle. T1 cycle starts, with merge - window opening. Developers begin to merge queued work. -- ... several weeks of merge window ... -- RC1 ... Close mainline to new work. Produce RC1 - release, begin testing phase; developers are in "bugfix mode", - all other work is queued; send out planned endgame schedule. -- RC2 ... Produce RC2 and send schedule update to - mailing list, listing priorities for remaining fixes -- ... more RC milestones, until ready ... -- T1: End of T1 release cycle. T2 cycle starts, with merge - window opening. Developers begin to merge queued work. - -Note that until it happens, any date for T1 is just a goal. -Critical bugs prevent releases from happening. We are just -beginning to use this window-plus-RCs process, so the lengths -of the merge windows versus the RC phase is subject to change. -Most projects have RC phases of a month or more. - -Some additional supplemental communication will be desirable. The above -list omits the step-by-step instructions to daily release management. -Individuals performing release management need to have the ability to -interact proactively with the community as a whole, anticipating when -such interaction will be required and giving ample notification. - -The next section explains why the OpenOCD project allows significant -flexibility in the part of the development that precedes the release -process. - -@subsection releasewhenflex Schedule Flexibility - -The Release Manager should attempt to follow the guidelines in this -document, but the process of scheduling each release milestone should be -community driven at the start. Features that don't complete before -the merge window closes can be held (perhaps in some branch) until -the next merge window opens, rather than delaying the release cycle. - -The Release -Manager cannot schedule the work that will be done on the project, -when it will be submitted, reviewed, and deemed suitable to be committed. -That is, the RM cannot act as a priest in a cathedral; OpenOCD uses -the bazaar development model. The release schedule must adapt -continuously in response to changes in the rate of work. -Fewer releases may be -required if developers contribute less patches, and more releases may be -desirable if the project continues to grow and experience high rates of -community contribution. During each cycle, the RM should be tracking -the situation and gathering feedback from the community. - -@section releasehow Release Process: Step-by-Step - -The release process is not final; it may need more iterations -to work out bugs. -While there are release scripts, key steps require community -support; the Release Manager isn't the only participant. - -The following steps should be followed to produce each release: - --# Produce final patches using a local clone of mainline. Nobody - except the RM should be committing anything. Everyone with commit - privileges needs to know and agree to this in advance! Even the RM - only commits a handful of updates as part of the release process - itself ... to files which are part of the version identification scheme - or release process; and to create the version tag; and then to open the - merge window for the next release cycle. - -# Finalize @c the NEWS file to describe the changes in the release - - This file is used to automatically post "blurbs" about the project. - - This material should have been produced during the development cycle, - by adding items for each @c NEWS-worthy contribution, when committed - during the merge window. (One part of closing the merge window, by - opening the RC phase of the release, is the commitment to hold all - further such contributions until the next merge window opens.) - - The RM should make sure nothing important was omitted, as part of - the RC1 cycle. From then on, no more updates to NEWS content should - be needed (except to seed the process for the next release, or maybe - if a significant and longstanding bug is fixed late in the RC phase). - -# Bump library version if our API changed (not yet required) - -# Update and commit the final package version in @c configure.ac: - (The tools/release/version.sh script might help ensure - the versions are named properly.): - -# Remove @c -dev tag. - -# Update any @c -rc tag: - - If producing the final release from an -rc series, remove it - - If producing the first RC in a series, add rc1 - - If producing the next RC in a series, bump the rc number - -# Commit that version change, with a good descriptive comment. - -# Create a git tag for the final commit, with a tag name matching - the version string in configure.ac (including -rcN - where relevant): -@verbatim -PACKAGE_VERSION="x.y.z" -PACKAGE_TAG="v${PACKAGE_VERSION}" -git tag -m "The openocd-${PACKAGE_VERSION} release." "${PACKAGE_TAG}" -@endverbatim - -# Do not push those changes to mainline yet; only builds using the - source archives you will be creating should ever be labeled as - official releases (with no "-dev" suffix). Since mainline is a - development tree, these will be pushed later, as part of opening - the merge window for the next release cycle (restoring the "-dev" - suffix for that next release.) Those version and tag updates are - the last ones to be included in the release being made. --# Produce the release files, using the local clone of the source - tree which holds the release's tag and updated version in - @c configure.ac ... this is used only to produce the release, and - all files should already be properly checked out. - -# Run tools/release.sh package to produce the - source archives. This automatically bootstraps and - configures the process. - -# Run tools/release.sh stage to create an @c archives - directory with the release data, including MD5 and SHA1 - checksum files. - -# Sanity check at least one of those archives, by extracting and - configuring its contents, using them to build a copy of OpenOCD, - and verifying that the result prints the correct release version - in its startup banner. (For example, - "configure --enable-ft2232_libftdi --enable-parport" - then "make" and run "src/openocd -v" as a sanity check.) - -# Run make docs to create the - documentation which will be published. --# Upload packages and post announcements of their availability: - -# Release packages into files section of project sites: - - SF.net: - -# Under "Project Admin", use the "File Manager" - -# Create a new folder under "openocd" named "${PACKAGE_VERSION}" - -# Upload the @c NEWS file and mark it as the release notes. - -# Upload the three source archive files, using the Web interface, - into that folder. Verify the upload worked OK by checking the - MD5 and SHA1 checksums computed by SourceForge against the - versions created as part of staging the release. - -# Also upload doc/openocd.pdf (the User's Guide) so the version - matching each release will be easily available. - -# Select each file in the release, and use the property panel - to set its type and select the right release notes. - - .tar.bz2: Linux, Mac - - .tar.gz: BSD, Solaris, Others - - .zip: Windows - - For openocd.pdf just associate it with the right release notes. - -# Create an SF.net project news update. - -# Depending on how paranoid you're feeling today, verify the images by - downloading them from the websites and making sure there are no - differences between the downloaded copies and your originals. - -# Publish User's and Developer's Guides to the project web sites: - -# Use SCP to update the SF.net web site with PDF and HTML for the - User's Guide, and HTML for the developer's guide ... you can - instantiate a shell.sourceforge.net instance and set up symlinks - from your home directory, to simplify this process. - -# Post announcement e-mail to the openocd-development list. - -# optionally: - -# Post an update on the OpenOCD blog. - -# Announce updates on freshmeat.net and other trackers. - -# Submit updates to news feeds (e.g. Digg, Reddit, etc.). --# Resume normal development on mainline, by opening the merge window for - the next major or minor release cycle. (You might want to do this - before all the release bits are fully published.) - - Update the version label in the @c configure.ac file: - - Restore @c -dev version tag. - - For a new minor release cycle, increment the release's minor number - - For a new major release cycle, increment the release's major number - and zero its minor number - - Archive @c NEWS file as "doc/news/NEWS-${PACKAGE_VERSION}". - - Create a new @c NEWS file for the next release - - Commit those changes. - - Push all the updates to mainline. - - Last updates for the release, including the release tag (you - will need to "git push --tags"). - - Updates opening the merge window - - At this point, it's OK for commiters to start pushing changes - which have been held off until the next release. (Any bugfixes to - this release will be against a bug-fix release branch starting from - the commit you tagged as this release, not mainline.) - - Announce to the openocd-development list. Ideally, you will also - be able to say who is managing the next release cycle. - -To start a bug-fix release branch: --# Create a new branch, starting from a major or - minor release tag --# Restore @c -dev version tag. --# Bump micro version number in configure.ac --# Backport bugfix patches from mainline into that branch. - (Always be sure mainline has the fix first, so it's hard - to just lose a bugfix.) --# Commit and push those patches. --# When desired, release as above ... except note that the next - release of a bugfix branch is never a new major or minor release - -@subsection releasescriptcmds Release Script Commands - -The @c release.sh script automates some of the steps involved -in making releases, simplifying the Release Manager's work. - -The release script can be used for two tasks: -- Creating releases and starting a new release cycle: -@code -git checkout master -tools/release.sh --type=minor --final --start-rc release -@endcode -- Creating a development branch from a tagged release: -@code -git checkout 'v0.2.0' -tools/release.sh --type=micro branch -@endcode - -Both of these variations make automatic commits and tags in your -repository, so you should be sure to run it on a cloned copy before -proceding with a live release. - -@subsection releasescriptopts Release Script Options - -The @c release.sh script recognizes some command-line options that -affect its behavior: - -- The @c --start-rc indicates that the new development release cycle - should start with @c -rc0. Without this, the @c -rc tag will be omitted, - leading to non-monotonic versioning of the in-tree version numbers. -- The @c --final indicates that the release should drop the @c -rc tag, - to going from @c x.y.z-rcN-dev to x.y.z. - -@subsection releasescriptenv Release Script Environment - -The @c release.sh script recognizes some environment variables which -affect its behavior: - -- @c CONFIG_OPTS : Passed as options to the configure script. -- @c MAKE_OPTS : Passed as options to the 'make' processes. - -@section releasetutorial Release Tutorials - -This section should contain a brief tutorial for using the Release -Script to perform release tasks, but the new script needs to be -used for 0.3.0. - -@section releasetodo Release Script Shortcomings - -Improved automated packaging and distribution of OpenOCD requires more -patching of the configure script. The final release script should be -able to manage most steps of the processes. The steps requiring user -input could be guided by an "assistant" that walks the Release Manager -through the process from beginning to end, performing basic sanity -checks on their various inputs (e.g. the @c NEWS blurb). - - */ -/** @file -This file contains the @ref releases page. - */ diff --git a/doc/manual/scripting.txt b/doc/manual/scripting.txt deleted file mode 100644 index 783541caf..000000000 --- a/doc/manual/scripting.txt +++ /dev/null @@ -1,80 +0,0 @@ -/** @page scripting Scripting Overview - -@section scriptingisnt What scripting will not do - -The scripting support is intended for developers of OpenOCD. -It is not the intention that normal OpenOCD users will -use tcl scripting extensively, write lots of clever scripts, -or contribute back to OpenOCD. - -Target scripts can contain new procedures that end users may -tinker to their needs without really understanding tcl. - -Since end users are not expected to mess with the scripting -language, the choice of language is not terribly important -to those same end users. - -Jim Tcl was chosen as it was easy to integrate, works -great in an embedded environment and Øyvind Harboe -had experience with it. - -@section scriptinguses Uses of scripting - -Default implementation of procedures in tcl/procedures.tcl. - -- Polymorphic commands for target scripts. - - there will be added some commands in Tcl that the target - scripts can replace. - - produce \ \. Default implementation - is to ignore serial number and write a raw binary file - to beginning of first flash. Target script can dictate - file format and structure of serialnumber. Tcl allows - an argument to consist of e.g. a list so the structure of - the serial number is not limited to a single string. - - reset handling. Precise control of how srst, trst & - tms is handled. -- replace some parts of the current command line handler. - This is only to simplify the implementation of OpenOCD - and will have no externally visible consequences. - Tcl has an advantage in that it's syntax is backwards - compatible with the current OpenOCD syntax. -- external scripting. Low level tcl functions will be defined - that return machine readable output. These low level tcl - functions constitute the tcl api. flash_banks is such - a low level tcl proc. "flash banks" is an example of - a command that has human readable output. The human - readable output is expected to change inbetween versions - of OpenOCD. The output from flash_banks may not be - in the preferred form for the client. The client then - has two choices a) parse the output from flash_banks - or b) write a small piece of tcl to output the - flash_banks output to a more suitable form. The latter may - be simpler. - - -@section scriptingexternal External scripting - -The embedded Jim Tcl interpreter in OpenOCD is very limited -compared to any full scale PC hosted scripting language. - -The goal is to keep the internal Jim Tcl interpreter as -small as possible and allow any advanced scripting, -especially scripting that interacts with the host, -run on the host and talk to OpenOCD via the TCP/IP -scripting connection. - -Another problem with Jim Tcl is that there is no debugger -for it. - -With a bit of trickery it should be possible to run Jim -Tcl scripts under a Tcl interpreter on a PC. The advantage -would be that the Jim Tcl scripts could be debugged using -a standard PC Tcl debugger. - -The rough idea is to write an unknown proc that sends -unknown commands to OpenOCD. - -Basically a PC version of startup.tcl. Patches most -gratefully accepted! :-) - - */ diff --git a/doc/manual/server.txt b/doc/manual/server.txt deleted file mode 100644 index 3c2fbd0e3..000000000 --- a/doc/manual/server.txt +++ /dev/null @@ -1,316 +0,0 @@ -/** @page serverdocs OpenOCD Server APIs - -OpenOCD provides support for implementing different types of servers. -Presently, the following servers have APIs that can be used. - - - @subpage servergdb - - @subpage servertelnet - - @subpage serverhttp - -@section serverdocsoverview Overview - -What follows is a development history, and describes some of the intent -of why certain features exist within OpenOCD along with the reasoning -behind them. - -This roadmap section was written May 2009 - about 9 to 12 months -after some of this work had started, it attempts to document some of -the reasons why certain features exist within OpenOCD at that time. - -@section serverdocsbg Background - -In early 2008, Oyvind Harboe and Duane Ellis had talked about how to -create a reasonable GUI for OpenOCD - something that is non-invasive, -simple to use and maintain, and does not tie OpenOCD to many other -packages. It would be wrong to "spider web" requirements into other -external external packages. That makes it difficult for developers to -write new code and creates a support nightmare. - -In many ways, people had talked about the need for some type of -high-level interface to OpenOCD, because they only had two choices: -- the ability to script: via an external program the actions of OpenOCD. -- the ablity to write a complex internal commands: native 'commands' - inside of OpenOCD was complicated. - -Fundamentally, the basic problem with both of those would be solved -with a script language: - --# Internal: simple, small, and self-contained. --# Cross Language: script friendly front-end --# Cross Host: GUI Host interface --# Cross Debugger: GUI-like interface - -What follows hopefully shows how the plans to solve these problems -materialized and help to explain the grand roadmap plan. - -@subsection serverdocsjim Why JimTCL? The Internal Script Language - -At the time, the existing "command context schema" was proving itself -insufficient. However, the problem was also considered from another -direction: should OpenOCD be first class and the script second class? -Which one rules? - -In the end, OpenOCD won, the conclusion was that simpler will be better. -Let the script language be "good enough"; it would not need numerous -features. Imagine debugging an embedded Perl module while debugging -OpenOCD. Yuck. OpenOCD already has a complex enough build system, why -make it worse? - -The goal was to add a simple language that would be moderately easy to -work with and be self-contained. JimTCL is a single C and single H -file, allowing OpenOCD to avoid the spider web of dependent packages. - -@section serverdocstcl TCL Server Port - -The TCL Server port was added in mid-2008. With embedded TCL, we can -write scripts internally to help things, or we can write "C" code that -interfaces well with TCL. - -From there, the developers wanted to create an external front-end that -would be @a very usable and that that @a any language could utilize, -allowing simple front-ends to be (a) cross-platform (b) languag -agnostic, and (c) easy to develop and use. - -Simple ASCII protocols are easy. For example, HTTP, FTP (control), and -SMTP are all text-based. All of these examples are widely and -well-known, and they do not require high-speed or high-volume. They -also support a high degree of interoperability with multiple systems. -They are not human-centric protocols; more correctly, they are rigid, -terse, simple ASCII protocols that are emensely parsable by a script. - -Thus, the TCL server -- a 'machine' type socket interface -- was added -with the hope was it would output simple "name-value" pair type -data. At the time, simple name/value pairs seemed reasonably easier to -do at the time, though Maybe it should output JSON; - -See here: - - http://www.mail-archive.com/openocd-development%40lists.berlios.de/msg00248.html - -The hope was that one could write a script in what ever language you want -and do things with it! - -@section serverdocsgui GUI Like Interfaces - -A lot has been said about various "widigit-foo-gui-library is so -wonderful". Please refer back to the domino and spider web problem of -dependencies. Sure, you may well know the WhatEver-GUI library, but -most others will not (including the next contributer to OpenOCD). -How do we solve that problem? - -For example, Cygwin can be painful, Cygwin GUI packages want X11 -to be present, crossing the barrier between MinGW and Cygwin is -painful, let alone getting the GUI front end to work on MacOS, and -Linux, yuck yuck yuck. Painful. very very painful. - -What works easier and is less work is what is already present in every -platform? The answer: A web browser. In other words, OpenOCD could -serve out embedded web pages via "localhost" to your browser. - -Long before OpenOCD had a TCL command line, Zylin AS built their ZY1000 -devince with a built-in HTTP server. Later, they were willing to both -contribute and integrate most of that work into the main tree. - -@subsection serverdocsother Other Options Considered - -What if a web browser is not acceptable ie: You want to write your own -front gadget in Eclipse, or KDevelop, or PerlTK, Ruby, or what ever -the latest and greatest Script De Jour is. - -- Option 1: Can we transport this extra data through the GDB server -protocol? In other words, can we extend the GDB server protocol? -No, Eclipse wants to talk to GDB directly and control the GDB port. - -- Option 2: SWIG front end (libopenocd): Would that work? - -That's painful - unless you design your api to be very simplistic - -every language has it's own set of wack-ness, parameter marshaling is -painful. - -What about "callbacks" and structures, and other mess. Imagine -debugging that system. When JimTCL was introduced Spencer Oliver had -quite a few well-put concerns (Summer 2008) about the idea of "TCL" -taking over OpenOCD. His concern is and was: how do you debug -something written in 2 different languages? A "SWIG" front-end is -unlikely to help that situation. - -@subsection serverdoccombined Combined: Socket & WebServer Benifits - -Seriously think about this question: What script language (or compiled -language) today cannot talk directly to a socket? Every thing in the -OpenOCD world can work a socket interface. Any host side tool can talk -to Localhost or remote host, however one might want to make it work. - -A socket interface is very simple. One could write a Java application -and serve it out via the embedded web server, could it - or something -like it talk to the built in TCL server? Yes, absolutely! We are on to -something here. - -@subsection serverdocplatforms Platform Permuntations - -Look at some permutations where OpenOCD can run; these "just work" if -the Socket Approach is used. - - -- Linux/Cygwin/MinGw/MacOSx/FreeBSD development Host Locally -- OpenOCD with some dongle on that host - - -- Linux/Cygwin/MingW/MacOS/FreeBSD development host -- DONGLE: tcpip based ARM-Linux perhaps at91rm9200 or ep93xx.c, running openocd. - - -- Windows cygwin/X desktop environment. -- Linux development host (via remote X11) -- Dongle: "eb93xx.c" based linux board - - -@subsection serverdocfuture Development Scale Out - -During 2008, Duane Ellis created some TCL scripts to display peripheral -register contents. For example, look at the sam7 TCL scripts, and the -stm32 TCL scripts. The hope was others would create more. - - -A good example of this is display/view the peripheral registers on -your embedded target. Lots of commercial embedded debug tools have -this, some can show the TIMER registers, the interrupt controller. - -What if the chip companies behind STM32, or PIC32, AT91SAM chips - -wanted to write something that makes working with their chip better, -easier, faster, etc. - -@a Question: How can we (the OpenOCD group) make that really fancy -stuff across multiple different host platforms? - -Remember: OpenOCD runs on: --# Linux via USB, --# ARM Linux - bit-banging GPIO pins --# MacOSX --# FreeBSD --# Cygwin --# MinGW32 --# Ecos - -How can we get that to work? - -@subsection serverdocdebug What about Debugger Plugins? - -Really GDB is nice, it works, but it is not a good embedded debug tool. -OpenOCD cannot work in a GUI when one cannot get to its command line. -Some GDB front-end developers have pedantic designs that refuse any and -all access to the GDB command line (e.g. http://www.kdbg.org/todo.php). - -The TELNET interface to OpenOCD works, but the intent of that interface -is human interaction. It must remain available, developers depend -upon it, sometimes that is the only scheme available. - -As a small group of developers, supporting all the platforms and -targets in the debugger will be difficult, as there are enough problem -with the plethora of Adapters, Chips, and different target boards. -Yes, the TCL interface might be suitable, but it has not received much -love or attention. Perhaps it will after you read and understand this. - -One reason might be, this adds one more host side requirement to make -use of the feature. In other words, one could write a Python/TK -front-end, but it is only useable if you have Python/TK installed. -Maybe this can be done via Ecllipse, but not all developers use Ecplise. -Many devlopers use Emacs (possibly with GUD mode) or vim and will not -accept such an interface. The next developer reading this might be -using Insight (GDB-TK) - and somebody else - DDD.. - -There is no common host-side GDB front-end method. - -@section serverdocschallenge Front-End Scaling - -Maybe we are wrong - ie: OpenOCD + some TK tool - -Remember: OpenOCD is often (maybe 99.9%) of the time used with -GDB-REMOTE. There is always some front-end package - be it command-line -GDB under DDD, Eclipse, KDevelop, Emacs, or some other package -(e.g. IAR tools can talk to GDB servers). How can the OpenOCD -developers make that fancy target display GUI visible under 5 to 10 -different host-side GDB.. - -Sure - a man on a mission can make that work. The GUI might be -libopenocd + Perl/TK, or maybe an Eclipse Plug-in. -That is a development support nightmare for reasons described -above. We have enough support problems as it is with targets, adapters, -etc. - -@section serverdocshttpbg HTTP Server Background - -OpenOCD includes an HTTP server because most development environments -are likely contain a web browser. The web browser can talk to OpenOCD's -HTTP server and provide a high-level interfaces to the program. -Altogether, it provides a universally accessible GUI for OpenOCD. - -@section serverdocshtml Simple HTML Pages - -There is (or could be) a simple "Jim TCL" function to read a memory -location. If that can be tied into a TCL script that can modify the -HTTP text, then we have a simple script-based web server with a JTAG -engine under the hood. - -Imagine a web page - served from a small board with two buttons: -"LED_ON" and "LED_OFF", each click - turns the LED on or OFF, a very -simplistic idea. Little boards with web servers are great examples of -this: Ethernut is a good example and Contiki (not a board, an embedded -OS) is another example. - -One could create a simple: Click here to display memory or maybe -click here to display the UART REGISTER BLOCK; click again and see -each register explained in exquisit detail. - -For an STM32, one could create a simple HTML page, with simple -substitution text that the simple web server use to substitute the -HTML text JIMTCL_PEEK32( 0x12345678 ) with the value read from -memory. We end up with an HTML page that could list the contents of -every peripheral register on the target platform. - -That also is transportable, regardless of the OpenOCD host -platform: Linux/X86, Linux/ARM, FreeBSD, Cygwin, MingW, or MacOSX. -You could even port OpenOCD to an Android system and use it as a -bit-banging JTAG Adapter serving web pages. - -@subsection serverdocshtmladv Advanced HTML Pages - -Java or JavaScript could be used to talk back to the TCL port. One -could write a Java, AJAX, FLASH, or some other developer friendly -toolbox and get a real cross-platform GUI interface. Sure, the interface -is not native - but it is 100% cross-platform! - -OpenOCD current uses simple HTML pages; others might be an Adobe FLASH -expert, or a Java Expert. These possibilities could allow the pages -remain cross-platform but still provide a rich user-interface -experience. - -Don't forget it can also be very simple, exactly what one developer -can contribute, a set of very simple web pages. - -@subsection serverdocshtmlstatus HTTP/HTML Status - -As of May 2009, much of the HTML pages were contributed by Zylin AS, -hence they continue to retain some resemblance to the ZY1000 interface. - -Patches would be welcome to move these parts of the system forward. - - */ - -/** @page servergdb OpenOCD GDB Server API - -This section needs to be expanded. - - */ - -/** @page servertelnet OpenOCD Telnet Server API - -This section needs to be expanded. - - */ - -/** @page serverhttp OpenOCD http Server API - -This section needs to be expanded. - - */ diff --git a/doc/manual/style.txt b/doc/manual/style.txt deleted file mode 100644 index 2ff2a29ee..000000000 --- a/doc/manual/style.txt +++ /dev/null @@ -1,422 +0,0 @@ -/** @page styleguide Style Guides - -The goals for each of these guides are: -- to produce correct code that appears clean, consistent, and readable, -- to allow developers to create patches that conform to a standard, and -- to eliminate these issues as points of future contention. - -Some of these rules may be ignored in the spirit of these stated goals; -however, such exceptions should be fairly rare. - -The following style guides describe a formatting, naming, and other -conventions that should be followed when writing or changing the OpenOCD -code: - -- @subpage styletcl -- @subpage stylec -- @subpage styleperl -- @subpage styleautotools - -In addition, the following style guides provide information for -providing documentation, either as part of the C code or stand-alone. - -- @subpage styledoxygen -- @subpage styletexinfo -- @subpage stylelatex - -Feedback would be welcome to improve the OpenOCD guidelines. - - */ -/** @page styletcl TCL Style Guide - -OpenOCD needs to expand its Jim/TCL Style Guide. - -Many of the guidelines listed on the @ref stylec page should apply to -OpenOCD's Jim/TCL code as well. - - */ -/** @page stylec C Style Guide - -This page contains guidelines for writing new C source code for the -OpenOCD project. - -@section styleformat Formatting Guide - -- remove any trailing white space at the end of lines. -- use TAB characters for indentation; do NOT use spaces. -- displayed TAB width is 4 characters. -- use Unix line endings ('\\n'); do NOT use DOS endings ('\\r\\n') -- limit adjacent empty lines to at most two (2). -- remove any trailing empty lines at the end of source files -- do not "comment out" code from the tree; instead, one should either: - -# remove it entirely (git can retrieve the old version), or - -# use an @c \#if/\#endif block. - -Finally, try to avoid lines of code that are longer than than 72-80 columns: - -- long lines frequently indicate other style problems: - - insufficient use of static functions, macros, or temporary variables - - poor flow-control structure; "inverted" logical tests -- a few lines may be wider than this limit (typically format strings), but: - - all C compilers will concatenate series of string constants. - - all long string constants should be split across multiple lines. - -@section stylenames Naming Rules - -- most identifiers must use lower-case letters (and digits) only. - - macros must use upper-case letters (and digits) only. - - OpenOCD identifiers should NEVER use @c MixedCaps. -- @c typedef names must end with the '_t' suffix. - - This should be reserved for types that should be passed by value. - - Do @b not mix the typedef keyword with @c struct. -- use underline characters between consecutive words in identifiers - (e.g. @c more_than_one_word). - -@section style_include_guards Include Guards - -Every header file should have a unique include guard to prevent multiple -inclusion. -To guarantee uniqueness, an include guard should be based on the filename and -the full path in the project source tree. - -For the header file src/helper/jim-nvp.h, the include guard would look like -this: - -@code -#ifndef OPENOCD_HELPER_JIM_NVP_H -#define OPENOCD_HELPER_JIM_NVP_H - -/* Your code here. */ - -#endif /* OPENOCD_HELPER_JIM_NVP_H */ -@endcode - -@section stylec99 C99 Rules - -- inline functions -- @c // comments -- in new code, prefer these for single-line comments -- trailing comma allowed in enum declarations -- designated initializers ( .field = value ) -- variables declarations should occur at the point of first use -- new block scopes for selection and iteration statements -- use malloc() to create dynamic arrays. Do @b not use @c alloca -or variable length arrays on the stack. non-MMU hosts(uClinux) and -pthreads require modest and predictable stack usage. - -@section styletypes Type Guidelines -- use native types (@c int or @c unsigned) if the type is not important - - if size matters, use the types from \ or \: - - @c int8_t, @c int16_t, @c int32_t, or @c int64_t: signed types of specified size - - @c uint8_t, @c uint16_t, @c uint32_t, or @c uint64_t: unsigned types of specified size - - do @b NOT redefine @c uN types from "types.h" - -@section stylefunc Functions - -- static inline functions should be prefered over macros: -@code -/** do NOT define macro-like functions like this... */ -#define CUBE(x) ((x) * (x) * (x)) -/** instead, define the same expression using a C99 inline function */ -static inline int cube(int x) { return x * x * x; } -@endcode -- Functions should be declared static unless required by other modules - - define static functions before first usage to avoid forward declarations. -- Functions should have no space between its name and its parameter list: -@code -int f(int x1, int x2) -{ - ... - int y = f(x1, x2 - x1); - ... -} -@endcode -- Separate assignment and logical test statements. In other words, you -should write statements like the following: -@code -// separate statements should be preferred -result = foo(); -if (ERROR_OK != result) - ... -@endcode -More directly, do @b not combine these kinds of statements: -@code -// Combined statements should be avoided -if (ERROR_OK != (result = foo())) - return result; -@endcode - - */ -/** @page styledoxygen Doxygen Style Guide - -The following sections provide guidelines for OpenOCD developers -who wish to write Doxygen comments in the code or this manual. -For an introduction to Doxygen documentation, -see the @ref primerdoxygen. - -@section styledoxyblocks Doxygen Block Selection - -Several different types of Doxygen comments can be used; often, -one style will be the most appropriate for a specific context. -The following guidelines provide developers with heuristics for -selecting an appropriate form and writing consistent documentation -comments. - --# use @c /// to for one-line documentation of instances. --# for documentation requiring multiple lines, use a "block" style: -@verbatim -/** - * @brief First sentence is short description. Remaining text becomes - * the full description block, where "empty" lines start new paragraphs. - * - * One can make text appear in @a italics, @b bold, @c monospace, or - * in blocks such as the one in which this example appears in the Style - * Guide. See the Doxygen Manual for the full list of commands. - * - * @param foo For a function, describe the parameters (e.g. @a foo). - * @returns The value(s) returned, or possible error conditions. - */ -@endverbatim - -# The block should start on the line following the opening @c /**. - -# The end of the block, \f$*/\f$, should also be on its own line. - -# Every line in the block should have a @c '*' in-line with its start: - - A leading space is required to align the @c '*' with the @c /** line. - - A single "empty" line should separate the function documentation - from the block of parameter and return value descriptions. - - Except to separate paragraphs of documentation, other extra - "empty" lines should be removed from the block. - -# Only single spaces should be used; do @b not add mid-line indentation. --# If the total line length will be less than 72-80 columns, then - - The @c /**< form can be used on the same line. - - This style should be used sparingly; the best use is for fields: - @code int field; /**< field description */ @endcode - -@section styledoxyall Doxygen Style Guide - -The following guidelines apply to all Doxygen comment blocks: - --# Use the @c '\@cmd' form for all doxygen commands (do @b not use @c '\\cmd'). --# Use symbol names such that Doxygen automatically creates links: - -# @c function_name() can be used to reference functions - (e.g. flash_set_dirty()). - -# @c struct_name::member_name should be used to reference structure - fields in the documentation (e.g. @c flash_driver::name). - -# URLS get converted to markup automatically, without any extra effort. - -# new pages can be linked into the heirarchy by using the @c \@subpage - command somewhere the page(s) under which they should be linked: - -# use @c \@ref in other contexts to create links to pages and sections. --# Use good Doxygen mark-up: - -# '\@a' (italics) should be used to reference parameters (e.g. foo). - -# '\@b' (bold) should be used to emphasizing single words. - -# '\@c' (monospace) should be used with file names and - code symbols, so they appear visually distinct from - surrounding text. - -# To mark-up multiple words, the HTML alternatives must be used. --# Two spaces should be used when nesting lists; do @b not use '\\t' in lists. --# Code examples provided in documentation must conform to the Style Guide. - -@section styledoxytext Doxygen Text Inputs - -In addition to the guidelines in the preceding sections, the following -additional style guidelines should be considered when writing -documentation as part of standalone text files: - --# Text files must contain Doxygen at least one comment block: - -# Documentation should begin in the first column (except for nested lists). - -# Do NOT use the @c '*' convention that must be used in the source code. --# Each file should contain at least one @c \@page block. - -# Each new page should be listed as a \@subpage in the \@page block - of the page that should serve as its parent. - -# Large pages should be structure in parts using meaningful \@section - and \@subsection commands. --# Include a @c \@file block at the end of each Doxygen @c .txt file to - document its contents: - - Doxygen creates such pages for files automatically, but no content - will appear on them for those that only contain manual pages. - - The \@file block should provide useful meta-documentation to assist - techincal writers; typically, a list of the pages that it contains. - - For example, the @ref styleguide exists in @c doc/manual/style.txt, - which contains a reference back to itself. --# The \@file and \@page commands should begin on the same line as - the start of the Doxygen comment: -@verbatim -/** @page pagename Page Title - -Documentation for the page. - - */ -/** @file - -This file contains the @ref pagename page. - - */ -@endverbatim - -For an example, the Doxygen source for this Style Guide can be found in -@c doc/manual/style.txt, alongside other parts of The Manual. - - */ -/** @page styletexinfo Texinfo Style Guide - -The User's Guide is there to provide two basic kinds of information. It -is a guide for how and why to use each feature or mechanism of OpenOCD. -It is also the reference manual for all commands and options involved -in using them, including interface, flash, target, and other drivers. -At this time, it is the only user-targetted documentation; everything -else is addressing OpenOCD developers. - -There are two key audiences for the User's Guide, both developer based. -The primary audience is developers using OpenOCD as a tool in their -work, or who may be starting to use it that way. A secondary audience -includes developers who are supporting those users by packaging or -customizing it for their hardware, installing it as part of some software -distribution, or by evolving OpenOCD itself. There is some crossover -between those audiences. We encourage contributions from users as the -fundamental way to evolve and improve OpenOCD. In particular, creating -a board or target specific configuration file is something that many -users will end up doing at some point, and we like to see such files -become part of the mainline release. - -General documentation rules to remember include: - -- Be concise and clear. It's work to remove those extra words and - sentences, but such "noise" doesn't help readers. -- Make it easy to skim and browse. "Tell what you're going to say, - then say it". Help readers decide whether to dig in now, or - leave it for later. -- Make sure the chapters flow well. Presentations should not jump - around, and should move easily from overview down to details. -- Avoid using the passive voice. -- Address the reader to clarify roles ("your config file", "the board you - are debugging", etc.); "the user" (etc) is artificial. -- Use good English grammar and spelling. Remember also that English - will not be the first language for many readers. Avoid complex or - idiomatic usage that could create needless barriers. -- Use examples to highlight fundamental ideas and common idioms. -- Don't overuse list constructs. This is not a slide presentation; - prefer paragraphs. - -When presenting features and mechanisms of OpenOCD: - -- Explain key concepts before presenting commands using them. -- Tie examples to common developer tasks. -- When giving instructions, you can \@enumerate each step both - to clearly delineate the steps, and to highlight that this is - not explanatory text. -- When you provide "how to use it" advice or tutorials, keep it - in separate sections from the reference material. -- Good indexing is something of a black art. Use \@cindex for important - concepts, but don't overuse it. In particular, rely on the \@deffn - indexing, and use \@cindex primarily with significant blocks of text - such as \@subsection. The \@dfn of a key term may merit indexing. -- Use \@xref (and \@anchor) with care. Hardcopy versions, from the PDF, - must make sense without clickable links (which don't work all that well - with Texinfo in any case). If you find you're using many links, - read that as a symptom that the presentation may be disjointed and - confusing. -- Avoid font tricks like \@b, but use \@option, \@file, \@dfn, \@emph - and related mechanisms where appropriate. - -For technical reference material: - -- It's OK to start sections with explanations and end them with - detailed lists of the relevant commands. -- Use the \@deffn style declarations to define all commands and drivers. - These will automatically appear in the relevant index, and those - declarations help promote consistent presentation and style. - - It's a "Command" if it can be used interactively. - - Else it's a "Config Command" if it must be used before the - configuration stage completes. - - For a "Driver", list its name. - - Use EBNF style regular expressions to define parameters: - brackets around zero-or-one choices, parentheses around - exactly-one choices. - - Use \@option, \@file, \@var and other mechanisms where appropriate. - - Say what output it displays, and what value it returns to callers. - - Explain clearly what the command does. Sometimes you will find - that it can't be explained clearly. That usually means the command - is poorly designed; replace it with something better, if you can. - - Be complete: document all commands, except as part of a strategy - to phase something in or out. - - Be correct: review the documentation against the code, and - vice versa. -- Alphabetize the \@defn declarations for all commands in each - section. -- Keep the per-command documentation focussed on exactly what that - command does, not motivation, advice, suggestions, or big examples. - When commands deserve such expanded text, it belongs elsewhere. - Solutions might be using a \@section explaining a cluster of related - commands, or acting as a mini-tutorial. -- Details for any given driver should be grouped together. - -The User's Guide is the first place most users will start reading, -after they begin using OpenOCD. Make that investment of their time -be as productive as possible. Needing to look at OpenOCD source code, -to figure out how to use it is a bad sign, though it's OK to need to -look at the User's guide to figure out what a config script is doing. - - */ -/** @page stylelatex LaTeX Style Guide - -This page needs to provide style guidelines for using LaTeX, the -typesetting language used by The References for OpenOCD Hardware. -Likewise, the @ref primerlatex for using this guide needs to be completed. - - */ -/** @page styleperl Perl Style Guide - -This page provides some style guidelines for using Perl, a scripting -language used by several small tools in the tree: - --# Ensure all Perl scripts use the proper suffix (@c .pl for scripts, and - @c .pm for modules) --# Pass files as script parameters or piped as input: - - Do NOT code paths to files in the tree, as this breaks out-of-tree builds. - - If you must, then you must also use an automake rule to create the script. --# use @c '#!/usr/bin/perl' as the first line of Perl scripts. --# always use strict and use warnings --# invoke scripts indirectly in Makefiles or other scripts: -@code -perl script.pl -@endcode - -Maintainers must also be sure to follow additional guidelines: --# Ensure that Perl scripts are committed as executables: - Use "chmod +x script.pl" - @a before using "git add script.pl" - - */ -/** @page styleautotools Autotools Style Guide - -This page contains style guidelines for the OpenOCD autotools scripts. - -The following guidelines apply to the @c configure.ac file: -- Better guidelines need to be developed, but until then... -- Use good judgement. - -The following guidelines apply to @c Makefile.am files: --# When assigning variables with long lists of items: - -# Separate the values on each line to make the files "patch friendly": -@code -VAR = \ - value1 \ - value2 \ - ... - value9 \ - value10 -@endcode - */ -/** @file - -This file contains the @ref styleguide pages. The @ref styleguide pages -include the following Style Guides for their respective code and -documentation languages: - -- @ref styletcl -- @ref stylec -- @ref styledoxygen -- @ref styletexinfo -- @ref stylelatex -- @ref styleperl -- @ref styleautotools - - */ diff --git a/doc/manual/target.txt b/doc/manual/target.txt deleted file mode 100644 index 7e9767f8f..000000000 --- a/doc/manual/target.txt +++ /dev/null @@ -1,46 +0,0 @@ -/** @page targetdocs OpenOCD Target APIs - -OpenOCD provides its Target APIs to allow developers to provide trace and -debugging support for specific device targets. These primarily consist of -ARM cores, but other types have been supported. New targets should be -developed by following or using these APIs. - -The Target Support module contains APIs that cover several functional areas: - - - @subpage targetarm - - @subpage targetnotarm - - @subpage targetmips - - @subpage targetregister - - @subpage targetimage - - @subpage targettrace - -This section needs to be expanded. - -*/ - -/** @page targetarm OpenOCD ARM Targets - -This section needs to describe OpenOCD's ARM target support. - - */ - -/** @page targetregister OpenOCD Target Register API - -This section needs to describe OpenOCD's Target Register API, as -provided by 'src/target/register.h'. - - */ - -/** @page targetimage OpenOCD Target Image API - -This section needs to describe OpenOCD's Target Image API, as provided -by 'src/target/image.h'. - - */ - -/** @page targettrace OpenOCD Target Trace API - -This section needs to describe OpenOCD's Target Trace API, as provided -by 'src/target/trace.h'. - - */ diff --git a/doc/manual/target/mips.txt b/doc/manual/target/mips.txt deleted file mode 100644 index 32c40b986..000000000 --- a/doc/manual/target/mips.txt +++ /dev/null @@ -1,536 +0,0 @@ -/** @page targetmips OpenOCD MIPS Targets - -@section ejatgmem EJTAG Memory Addresses - -An optional uncached and unmapped debug segment dseg (EJTAG area) appears in the address range -0xFFFF FFFF FF20 0000 to 0xFFFF FFFF FF3F FFFF. The dseg segment thereby appears in the kseg part of the -compatibility segment, and access to kseg is possible with the dseg segment. - -The dseg segment is subdivided into dmseg (EJTAG memory) segment and the drseg (EJTAG registers) segment. The -dmseg segment is used when the probe services the memory segment. The drseg segment is used when the -memory-mapped debug registers are accessed. Table 5-2 shows the subdivision and attributes for the segments. - -dseg is divided in : - - - dmseg (0xFFFF FFFF FF20 0000 to 0xFFFF FFFF FF2F FFFF) - - drseg (0xFFFF FFFF FF30 0000 to 0xFFFF FFFF FF3F FFFF) - -Because the dseg segment is serviced exclusively by the EJTAG features, there -are no physical address per se. Instead the lower 21 bits of the virtual address select -the appropriate reference in either EJTAG memory or registers. References are not mapped through the -TLB, nor do the accesses appear on the external system memory interface. - -Both of this memory segments are Uncached. - -On debug exception (break) CPU jumps to the beginning of dmseg. This some kind of memory shared -between CPU and EJTAG dongle. - -There CPU stops (correct terminology is : stalls, because it stops it's pipeline), and is waiting for some action of dongle. - -If the dongle gives it instruction, CPU executes it, augments it's PC to 0xFFFF FFFF FF20 0001 - but it again points to dmseg area, -so it stops waiting for next instruction. - -This will all become clear later, after reading following prerequisite chapters. - -@section impflags Important flags - -@subsection pnnw PNnW - -Indicates read or write of a pending processor access: - - - 0 : Read processor access, for a fetch/load access - - 1 : Write processor access, for a store access - -This value is defined only when a processor access is pending. - -Processor will do the action for us : it can for example read internal state (register values), -and send us back the information via EJTAG memory (dmseg), or it can take some data from dmseg and write it into the registers or RAM. - -Every time when it sees address (i.e. when this address is the part of the opcode it is executing, wether it is instruction or data fetch) -that falls into dmseg, processor stalls. That acutally meand that CPU stops it's pipeline and it is waitning for dongle to take some action. - -CPU is now either waiting for dongle to take some data from dmseg (if we requested for CPU do give us internal state, for example), -or it will wait for some data from dongle (if it needs following instruction because it did previous, or if the operand address of the currently executed opcode -falls somewhere (anywhere) in dmseg (0xff..ff20000 - 0xff..ff2fffff)). - -Bit PNnW describes character of CPU access to EJTAG memory (the memry where dongle puts/takes data) - CPU can either READ for it (PNnW == 0) or -WRITE to it (PNnW == 1). - -By reading PNnW bit OpenOCD will know if it has to send (PNnW == 0) or to take (PNnW == 1) data (from dmseg, via dongle). - -@subsection pracc PrAcc - -Indicates a pending processor access and controls finishing of a pending processor access. - -When read: - - - 0 : No pending processor access - - 1 : Pending processor access - -A write of 0 finishes a processor access if pending; -otherwise operation of the processor is UNDEFINED -if the bit is written to 0 when no processor access is -pending. A write of 1 is ignored. - -A successful FASTDATA access will clear this bit. - -As noted above, on any access to dmseg, processor will stall. It waits for dongle to do some action - either to take or put some data. -OpenOCD can figure out which action has to be taken by reading PrAcc bit. - -Once action from dongle has been done, i.e. after the data is taken/put, OpenOCD can signal to CPU to proceed with executing the instruction. -This can be the next instruction (if previous was finished before pending), or the same instruction - if for example CPU was waiting on dongle -to give it an operand, because it saw in the instruction opcode that operand address is somewhere in dmseg. That prowoked the CPU to stall (it tried operand fetch to dmseg and stopped), -and PNnW bit is 0 (CPU does read from dmseg), and PrAcc is 1 (CPU is pending on dmseg access). - -@subsection spracc SPrAcc - -Shifting in a zero value requests completion of the Fastdata access. - -The PrAcc bit in the EJTAG Control register is overwritten with zero when the access -succeeds. (The access succeeds if PrAcc is one and the operation address is in the legal dmseg segment -Fastdata area.) - -When successful, a one is shifted out. Shifting out a zero indicates a Fastdata access failure. -Shifting in a one does not complete the Fastdata access and the PrAcc bit is unchanged. Shifting out a -one indicates that the access would have been successful if allowed to complete and a zero indicates -the access would not have successfully completed. - -@section fdreg Fastdata Register (TAP Instruction FASTDATA) - -The width of the Fastdata register is 1 bit. - -During a Fastdata access, the Fastdata register is written and read, i.e., a bit is -shifted in and a bit is shifted out. - -Also during a Fastdata access, the Fastdata register value shifted in specifies whether the Fastdata -access should be completed or not. The value shifted out is a flag that indicates whether the Fastdata access was -successful or not (if completion was requested). - -@section ejtagacc EJTAG Access Implementation - -OpenOCD reads/writes data to JTAG via mips_m4k_read_memory() and mips_m4k_write_memory() functions defined in src/target/mips_m4k.c. -Internally, these functions call mips32_pracc_read_mem() and mips32_pracc_write_mem() defined in src/target/mips32_pracc.c - -Let's take for example function mips32_pracc_read_mem32() which describes CPU reads (fetches) from dmseg (EJTAG memory) : - -@code -static const uint32_t code[] = { - /* start: */ - MIPS32_MTC0(15,31,0), /* move $15 to COP0 DeSave */ - MIPS32_LUI(15,UPPER16(MIPS32_PRACC_STACK)), /* $15 = MIPS32_PRACC_STACK */ - MIPS32_ORI(15,15,LOWER16(MIPS32_PRACC_STACK)), - MIPS32_SW(8,0,15), /* sw $8,($15) */ - MIPS32_SW(9,0,15), /* sw $9,($15) */ - MIPS32_SW(10,0,15), /* sw $10,($15) */ - MIPS32_SW(11,0,15), /* sw $11,($15) */ - - MIPS32_LUI(8,UPPER16(MIPS32_PRACC_PARAM_IN)), /* $8 = MIPS32_PRACC_PARAM_IN */ - MIPS32_ORI(8,8,LOWER16(MIPS32_PRACC_PARAM_IN)), - MIPS32_LW(9,0,8), /* $9 = mem[$8]; read addr */ - MIPS32_LW(10,4,8), /* $10 = mem[$8 + 4]; read count */ - MIPS32_LUI(11,UPPER16(MIPS32_PRACC_PARAM_OUT)), /* $11 = MIPS32_PRACC_PARAM_OUT */ - MIPS32_ORI(11,11,LOWER16(MIPS32_PRACC_PARAM_OUT)), - /* loop: */ - MIPS32_BEQ(0,10,8), /* beq 0, $10, end */ - MIPS32_NOP, - - MIPS32_LW(8,0,9), /* lw $8,0($9), Load $8 with the word @mem[$9] */ - MIPS32_SW(8,0,11), /* sw $8,0($11) */ - - MIPS32_ADDI(10,10,NEG16(1)), /* $10-- */ - MIPS32_ADDI(9,9,4), /* $1 += 4 */ - MIPS32_ADDI(11,11,4), /* $11 += 4 */ - - MIPS32_B(NEG16(8)), /* b loop */ - MIPS32_NOP, - /* end: */ - MIPS32_LW(11,0,15), /* lw $11,($15) */ - MIPS32_LW(10,0,15), /* lw $10,($15) */ - MIPS32_LW(9,0,15), /* lw $9,($15) */ - MIPS32_LW(8,0,15), /* lw $8,($15) */ - MIPS32_B(NEG16(27)), /* b start */ - MIPS32_MFC0(15,31,0), /* move COP0 DeSave to $15 */ -}; -@endcode - -We have to pass this code to CPU via dongle via dmseg. - -After debug exception CPU will find itself stalling at the begining of the dmseg. It waits for the first instruction from dongle. -This is MIPS32_MTC0(15,31,0), so CPU saves C0 and continues to addr 0xFF20 0001, which falls also to dmseg, so it stalls. -Dongle proceeds giving to CPU one by one instruction in this manner. - -However, things are not so simple. If you take a look at the program, you will see that some instructions take operands. If it has to take -operand from the address in dmseg, CPU will stall witing for the dongle to do the action of passing the operand and signal this by putting PrAcc to 0. -If this operand is somewhere in RAM, CPU will not stall (it stalls only on dmseg), but it will just take it and proceed to nex instruction. But since PC for next instruction -points to dmseg, it will stall, so that dongle can pass next instruction. - -Some instuctions are jumps (if these are jumps in dmseg addr, CPU will jump and then stall. If this is jump to some address in RAM, CPU will jump and just proceed - -will not stall on addresses in RAM). - -To have information about CPU is currently (does it stalls wanting on operand or it jumped somewhere waiting for next instruction), -OpenOCD has to call TAP ADDRESS instruction, which will ask CPU to give us his address within EJTAG memory : - -@code -address = data = 0; -mips_ejtag_set_instr(ejtag_info, EJTAG_INST_ADDRESS); -mips_ejtag_drscan_32(ejtag_info, &address); -@endcode - -And then, upon the results, we can conclude where it is in our code so far, so we can give it what it wants next : - -@code -if ((address >= MIPS32_PRACC_PARAM_IN) - && (address <= MIPS32_PRACC_PARAM_IN + ctx->num_iparam * 4)) -{ - offset = (address - MIPS32_PRACC_PARAM_IN) / 4; - data = ctx->local_iparam[offset]; -} -else if ((address >= MIPS32_PRACC_PARAM_OUT) - && (address <= MIPS32_PRACC_PARAM_OUT + ctx->num_oparam * 4)) -{ - offset = (address - MIPS32_PRACC_PARAM_OUT) / 4; - data = ctx->local_oparam[offset]; -} -else if ((address >= MIPS32_PRACC_TEXT) - && (address <= MIPS32_PRACC_TEXT + ctx->code_len * 4)) -{ - offset = (address - MIPS32_PRACC_TEXT) / 4; - data = ctx->code[offset]; -} -else if (address == MIPS32_PRACC_STACK) -{ - /* save to our debug stack */ - data = ctx->stack[--ctx->stack_offset]; -} -else -{ - /* TODO: send JMP 0xFF200000 instruction. - Hopefully processor jump back to start of debug vector */ - data = 0; - LOG_ERROR("Error reading unexpected address 0x%8.8" PRIx32 "", address); - return ERROR_JTAG_DEVICE_ERROR; -} -@endcode - -i.e. if CPU is stalling on addresses in dmseg that are reserved for input parameters, we can conclude that it actually tried to take (read) -parametar from there, and saw that address of param falls in dmseg, so it stopped. Obviously, now dongle have to give to it operand. - -Similarly, mips32_pracc_exec_write() describes CPU writes into EJTAG memory (dmseg). -Obvioulsy, code is RO, and CPU can change only parameters : - -@code -mips_ejtag_set_instr(ctx->ejtag_info, EJTAG_INST_DATA); -mips_ejtag_drscan_32(ctx->ejtag_info, &data); - -/* Clear access pending bit */ -ejtag_ctrl = ejtag_info->ejtag_ctrl & ~EJTAG_CTRL_PRACC; -mips_ejtag_set_instr(ctx->ejtag_info, EJTAG_INST_CONTROL); -mips_ejtag_drscan_32(ctx->ejtag_info, &ejtag_ctrl); - -//jtag_add_clocks(5); -jtag_execute_queue(); - -if ((address >= MIPS32_PRACC_PARAM_IN) - && (address <= MIPS32_PRACC_PARAM_IN + ctx->num_iparam * 4)) -{ - offset = (address - MIPS32_PRACC_PARAM_IN) / 4; - ctx->local_iparam[offset] = data; -} -else if ((address >= MIPS32_PRACC_PARAM_OUT) - && (address <= MIPS32_PRACC_PARAM_OUT + ctx->num_oparam * 4)) -{ - offset = (address - MIPS32_PRACC_PARAM_OUT) / 4; - ctx->local_oparam[offset] = data; -} -else if (address == MIPS32_PRACC_STACK) -{ - /* save data onto our stack */ - ctx->stack[ctx->stack_offset++] = data; -} -else -{ - LOG_ERROR("Error writing unexpected address 0x%8.8" PRIx32 "", address); - return ERROR_JTAG_DEVICE_ERROR; -} -@endcode - -CPU loops here : - -@code -while (1) -{ - if ((retval = wait_for_pracc_rw(ejtag_info, &ejtag_ctrl)) != ERROR_OK) - return retval; - - address = data = 0; - mips_ejtag_set_instr(ejtag_info, EJTAG_INST_ADDRESS); - mips_ejtag_drscan_32(ejtag_info, &address); - - /* Check for read or write */ - if (ejtag_ctrl & EJTAG_CTRL_PRNW) - { - if ((retval = mips32_pracc_exec_write(&ctx, address)) != ERROR_OK) - return retval; - } - else - { - /* Check to see if its reading at the debug vector. The first pass through - * the module is always read at the vector, so the first one we allow. When - * the second read from the vector occurs we are done and just exit. */ - if ((address == MIPS32_PRACC_TEXT) && (pass++)) - { - break; - } - - if ((retval = mips32_pracc_exec_read(&ctx, address)) != ERROR_OK) - return retval; - } - - if (cycle == 0) - break; -} -@endcode - -and using presented R (mips32_pracc_exec_read()) and W (mips32_pracc_exec_write()) functions it reads in the code (RO) and reads and writes operands (RW). - -@section fdimpl OpenOCD FASTDATA Implementation - -OpenOCD FASTDATA write function, mips32_pracc_fastdata_xfer() is called from bulk_write_memory callback, which writes a count items of 4 bytes -to the memory of a target at the an address given. Because it operates only on whole words, this should be faster than target_write_memory(). - -In order to implement FASTDATA write, mips32_pracc_fastdata_xfer() uses the following handler : - -@code -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), - /* 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 */ -}; -@endcode - -In the begining and the end of the handler we have fuction prologue (save the regs that will be clobbered) and epilogue (restore regs), -and in the very end, after all the xfer have been done, we do jump to the MIPS32_PRACC_TEXT address, i.e. Debug Exception Vector location. -We will use this fact (that we came back to MIPS32_PRACC_TEXT) to verify later if all the handler is executed (because when in RAM, -processor do not stall - it executes all instructions untill one of them do not demand access to dmseg (if one of it's opernads is there)). - -This handler is put into the RAM and executed from there, and not instruction by instruction, like in previous simple write -(mips_m4k_write_memory()) and read (mips_m4k_read_memory()) functions. - -N.B. When it is executing this code in RAM, CPU will not stall on instructions, but execute all until it comes to the : - -@code -MIPS32_LW(9,0,8) /* start addr in t1 */ -@endcode - -and there it will stall - because it will see that one of the operands have to be fetched from dmseg (EJTAG memory, in this case FASTDATA memory segment). - -This handler is loaded in the RAM, ath the reserved location "work_area". This work_area is configured in OpenOCD configuration script and should be selected -in that way that it is not clobbered (overwritten) by data we want to write-in using FASTDATA. - -What is executed instruction by instruction which is passed by dongle (via EJATG memory) is small jump code, which jumps at the handler in RAM. -CPU stalls on dmseg when receiving these jmp_code instructions, but once it jumps in RAM, CPU do not stall anymore and executes bunch of handler instructions. -Untill it comes to the first instruction which has an operand in FASTDATA area. There it stalls and waits on action from probe. -It happens actually when CPU comes to this loop : - -@code -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 */ -@endcode - -and then it stalls because operand in r8 points to FASTDATA area. - -OpenOCD first verifies that CPU came to this place by : - -@code -/* next fetch to dmseg should be in FASTDATA_AREA, check */ -address = 0; -mips_ejtag_set_instr(ejtag_info, EJTAG_INST_ADDRESS); -mips_ejtag_drscan_32(ejtag_info, &address); - -if (address != MIPS32_PRACC_FASTDATA_AREA) - return ERROR_FAIL; -@endcode - -and then passes to CPU start and end address of the loop region for handler in RAM. - -In the loop in handler, CPU sees that it has to take and operand from FSTDATA area (to write it to the dst in RAM after), and so it stalls, putting PrAcc to "1". -OpenOCD fills the data via this loop : - -@code -for (i = 0; i < count; i++) -{ - /* Send the data out using fastdata (clears the access pending bit) */ - mips_ejtag_set_instr(ejtag_info, EJTAG_INST_FASTDATA); - if ((retval = mips_ejtag_fastdata_scan(ejtag_info, write_t, buf++)) != ERROR_OK) - return retval; -} -@endcode - -Each time when OpenOCD fills data to CPU (via dongle, via dmseg), CPU takes it and proceeds in executing the endler. However, since handler is in a assembly loop, -CPU comes to next instruction which also fetches data from FASTDATA area. So it stalls. -Then OpenOCD fills the data again, from it's (OpenOCD's) loop. And this game continues untill all the data has been filled. - -After the last data has beend given to CPU it sees that it reached the end address, so it proceeds with next instruction. However, rhis instruction do not point into dmseg, so -CPU executes bunch of handler instructions (all prologue) and in the end jumps to MIPS32_PRACC_TEXT address. - -On it's side, OpenOCD checks in CPU has jumped back to MIPS32_PRACC_TEXT, which is the confirmation that it correclty executed all the rest of the handler in RAM, -and that is not stuck somewhere in the RAM, or stalling on some acces in dmseg - that would be an error : - -@code -address = 0; -mips_ejtag_set_instr(ejtag_info, EJTAG_INST_ADDRESS); -mips_ejtag_drscan_32(ejtag_info, &address); - -if (address != MIPS32_PRACC_TEXT) - LOG_ERROR("mini program did not return to start"); -@endcode - -@section fdejtagspec EJTAG spec on FASTDATA access - -The width of the Fastdata register is 1 bit. During a Fastdata access, the Fastdata register is written and read, i.e., a bit -is shifted in and a bit is shifted out. During a Fastdata access, the Fastdata register value shifted in specifies whether -the Fastdata access should be completed or not. The value shifted out is a flag that indicates whether the Fastdata -access was successful or not (if completion was requested). - -The FASTDATA access is used for efficient block transfers between dmseg (on the probe) and target memory (on the -processor). An "upload" is defined as a sequence of processor loads from target memory and stores to dmseg. A -"download" is a sequence of processor loads from dmseg and stores to target memory. The "Fastdata area" specifies -the legal range of dmseg addresses (0xFF20.0000 - 0xFF20.000F) that can be used for uploads and downloads. The -Data + Fastdata registers (selected with the FASTDATA instruction) allow efficient completion of pending Fastdata -area accesses. -During Fastdata uploads and downloads, the processor will stall on accesses to the Fastdata area. The PrAcc (processor -access pending bit) will be 1 indicating the probe is required to complete the access. Both upload and download -accesses are attempted by shifting in a zero SPrAcc value (to request access completion) and shifting out SPrAcc to -see if the attempt will be successful (i.e., there was an access pending and a legal Fastdata area address was used). -Downloads will also shift in the data to be used to satisfy the load from dmseg’s Fastdata area, while uploads will -shift out the data being stored to dmseg’s Fastdata area. -As noted above, two conditions must be true for the Fastdata access to succeed. These are: - - - PrAcc must be 1, i.e., there must be a pending processor access. - - The Fastdata operation must use a valid Fastdata area address in dmseg (0xFF20.0000 to 0xFF20.000F). - -Basically, because FASTDATA area in dmseg is 16 bytes, we transfer (0xFF20.0000 - 0xFF20.000F) -FASTDATA scan TAP instruction selects the Data and the Fastdata registers at once. - -They come in order : -TDI -> | Data register| -> | Fastdata register | -> TDO - -FASTDATA register is 1-bit width register. It takes in SPrAcc bit which should be shifted first, -followed by 32 bit of data. - -Scan width of FASTDTA is 33 bits in total : 33 bits are shifted in and 33 bits are shifted out. - -First bit that is shifted out is SPrAcc that comes out of Fastdata register and should give us status on FATSDATA write we want to do. - -@section fdcheck OpenOCD misses FASTDATA check - -Download flow (probe -> target block transfer) : - -1) Probe transfer target execution to a loop in target memory doing a fixed number of "loads" to fastdata area of dmseg (and stores to the target download destination.) - -2) Probe loops attempting to satisfy the loads "expected" from the target. - On FASTDATA access "successful" move on to next "load". - On FASTDATA access "failure" repeat until "successful" or timeout. - (A "failure" is an attempt to satisfy an access when none are pending.) - -Note: A failure may have a recoverable (and even expected) cause like slow target execution of the load loop. Other failures may be due to unexpected more troublesome causes like an exception while in debug mode or a target hang on a bad target memory access. - -Shifted out SPrAcc bit inform us that there was CPU access pendingand that it can be complete. - -Basically, we should do following procedure : - - - Download (dongle -> CPU) : -You shift "download" DATA and FASTDATA[SPrAcc] = 0 (33 bit scan) into the target. If the value of FASTDATA[SPrAcc] shifted out is "1" then an access was pending when you started the scan and it is now complete. - -If SPrAcc is 0 then no access was pending to the fastdata area. (Repeat attempt to complete the access you expect for this data word. Timeout if you think the access is "long overdue" as something unexpected has happened.) - - - Upload (CPU -> dongle) : -You shift "dummy" DATA and FASTDATA[SPrAcc] = 0 (33 bit scan) into the target. If the value of FASTDATA[SPrAcc] shifted out is "1" then an access was pending when you started the scan and it is now complete. The "upload" is the DATA shifted out of the target. - -If SPrAcc is 0 then no access was pending to the fastdata area. (Repeat attempt to complete the access you expect for this data word. Timeout if you think the access is "long overdue" as something unexpected has happened.) - -Basically, if checking first (before scan) if CPU is pending on FASTDATA access (PrAcc is "1"), like this - -@code -wait(ready); -do_scan(); -@endcode - -which is inefficient, we should do it like this : - -@code -BEGIN : - do_scan(); - if (!was_ready) - goto BEGIN; -@endcode - -by checking SPrAcc that we shifted out. - -If some FASTDATA write fails, OpenOCD will continue with it's loop (on the host side), but CPU will rest pending (on the target side) -waiting for correct FASTDATA write. - -Since OpenOCD goes ahead, it will eventually finish it's loop, and proceede to check if CPU took all the data. But since CPU did not took all the data, -it is still turns in handler's loop in RAM, stalling on Fastdata area so this check : - -@code -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_TEXT) - LOG_ERROR("mini program did not return to start"); -@endcode - -fails, and that gives us enough information of the failure. - -In this case, we can lower the JTAG frquency and try again, bacuse most probable reason of this failure is that we tried FASTDATA upload before CPU arrived to rise PrAcc (i.e. before it was pending on access). -However, the reasons for failure might be numerous : reset, exceptions which can occur in debug mode, bus hangs, etc. - -If lowering the JTAG freq does not work either, we can fall back to more robust solution with patch posted below. - -To summarize, FASTDATA communication goes as following : - --# CPU jumps to Debug Exception Vector Location 0xFF200200 in dmseg and it stalls, pending and waiting for EJTAG to give it first debug instruction and signall it by putting PrAcc to "0" --# When PrAcc goes to "0" CPU execute one opcode sent by EJTAG via DATA reg. Then it pends on next access, waiting for PrAcc to be put to "0" again --# Following this game, OpenOCD first loads handler code in RAM, and then sends the jmp_code - instruction by instruction via DATA reg, which redirects CPU to handler previously set up in RAM --# Once in RAM CPU does not pend on any instruction, but it executes all handler instructions untill first "fetch" to Fastdata area - then it stops and pends. --# So - when it comes to any instruction (opcode) in this handler in RAM which reads (or writes) to Fastdata area (0xF..F20.0000 to 0xF..F20.000F), CPU stops (i.e. stalls access). - I.e. it stops on this lw opcode and waits to FASTDATA TAP command from the probe. --# CPU continues only if OpenOCD shifted in SPrAcc "0" (and if the PrAcc was "1"). It shifts-out "1" to tell us that it was OK (processor was stalled, so it can complete the access), - and that it continued execution of the handler in RAM. --# If PrAcc was not "1" CPU will not continue (go to next instruction), but will shift-out "0" and keep stalling on the same instruction of my handler in RAM. --# When Fastdata loop is finished, CPU executes all following hadler instructions in RAM (prologue). --# In the end of my handler in RAM, I jumps back to begining of Debug Exception Vector Location 0xFF200200 in dmseg. --# When it jumps back to 0xFF200200 in dmseg processor stops and pends, waiting for OpenOCD to send it instruction via DATA reg and signal it by putting PrAcc to "0". - -*/ diff --git a/doc/manual/target/notarm.txt b/doc/manual/target/notarm.txt deleted file mode 100644 index 5d5be78c0..000000000 --- a/doc/manual/target/notarm.txt +++ /dev/null @@ -1,71 +0,0 @@ -/** @page targetnotarm OpenOCD Non-ARM Targets - -This page describes outstanding issues w.r.t. non-ARM targets. - -@section targetnotarmflash Flash drivers - -The flash drivers contain ARM32 code that is used -to execute code on the target. - -This needs to be handled in some CPU independent -manner. - -The ocl and ecos flash drivers compile the flash -driver code to run on the target on the developer -machine. - -The ocl and ecos flash drivers should be unified -and instructions should be written on how to -compile the target flash drivers. Perhaps -using automake? - - -eCos has CFI driver that could probably be compiled -for all targets. The trick is to figure out a -way to make the compiled flash drivers work -on all target memory maps + sort out all the -little details - -@section targetnotarm32v64 32 vs. 64 bit - -Currently OpenOCD only supports 32 bit targets. - -Adding 64 bit support would be nice but there -hasn't been any call for it in the openocd development -mailing list - -@section targetnotarmsupport Target Support - -target.h is relatively CPU agnostic and -the intention is to move in the direction of less -instruction set specific. - -Non-CPU targets are also supported, but there isn't -a lot of activity on it in the mailing list currently. -An example is FPGA programming support via JTAG, -but also flash chips can be programmed directly -using JTAG. - -@section targetnotarmphy non-JTAG physical layer - -JTAG is not the only physical protocol used to talk to -CPUs. - -OpenOCD does not today have targets that use non-JTAG. - -The actual physical layer is a relatively modest part -of the total OpenOCD system. - - -@section targetnotarmppc PowerPC - -there exists open source implementations of powerpc -target manipulation, but there hasn't been a lot -of activity in the mailing list. - -@section targetnotarmmips MIPS - -Currently OpenOCD has a MIPS target defined. This is the -first non-ARM example of a CPU target - - */ diff --git a/doc/openocd.1 b/doc/openocd.1 deleted file mode 100644 index 4278486e5..000000000 --- a/doc/openocd.1 +++ /dev/null @@ -1,103 +0,0 @@ -.TH "OPENOCD" "1" "November 24, 2009" -.SH "NAME" -openocd \- A free and open on\-chip debugging, in\-system programming and -boundary\-scan testing tool for ARM and MIPS systems -.SH "SYNOPSIS" -.B openocd \fR[\fB\-fsdlcphv\fR] [\fB\-\-file\fR ] [\fB\-\-search\fR ] [\fB\-\-debug\fR ] [\fB\-\-log_output\fR ] [\fB\-\-command\fR ] [\fB\-\-pipe\fR] [\fB\-\-help\fR] [\fB\-\-version\fR] -.SH "DESCRIPTION" -.B OpenOCD -is an on\-chip debugging, in\-system programming and boundary\-scan -testing tool for various ARM and MIPS systems. -.PP -The debugger uses an IEEE 1149\-1 compliant JTAG TAP bus master to access -on\-chip debug functionality available on ARM based microcontrollers or -system-on-chip solutions. For MIPS systems the EJTAG interface is supported. -.PP -User interaction is realized through a telnet command line interface, -a gdb (the GNU debugger) remote protocol server, and a simplified RPC -connection that can be used to interface with OpenOCD's Jim Tcl engine. -.PP -OpenOCD supports various different types of JTAG interfaces/programmers, -please check the \fIopenocd\fR info page for the complete list. -.SH "OPTIONS" -.TP -.B "\-f, \-\-file " -This is a shortcut for a \fB\-c "[script \fI\fB]"\fR -command, using a search path to load the configuration file -.IR . -In order to specify multiple config files, you can use multiple -.B \-\-file -arguments. If no such \fB\-c\fR -options are included, the first config file -.B openocd.cfg -in the search path will be used. -.TP -.B "\-s, \-\-search " -Add -.I -to the search path used for config files and scripts. -The search path begins with the current directory, -then includes these additional directories before other -components such as the standard OpenOCD script libraries. -.TP -.B "\-d, \-\-debug " -Set debug level. Possible values are: -.br -.RB " * " 0 " (errors)" -.br -.RB " * " 1 " (warnings)" -.br -.RB " * " 2 " (informational messages)" -.br -.RB " * " 3 " (debug messages)" -.br -The default level is -.BR 2 . -.TP -.B "\-l, \-\-log_output " -Redirect log output to the file -.IR . -Per default the log output is printed on -.BR stderr . -.TP -.B "\-c, \-\-command " -Add the command -.I -to a list of commands executed on server startup. -Note that you will need to explicitly invoke -.I init -if the command requires access to a target or flash. -.TP -.B "\-p, \-\-pipe" -Use pipes when talking to gdb. -.TP -.B "\-h, \-\-help" -Show a help text and exit. -.TP -.B "\-v, \-\-version" -Show version information and exit. -.SH "BUGS" -Please report any bugs on the mailing list at -.BR openocd\-devel@lists.sourceforge.net . -.SH "LICENCE" -.B OpenOCD -is covered by the GNU General Public License (GPL), version 2 or later. -.SH "SEE ALSO" -.BR jtag (1) -.PP -The full documentation for -.B openocd -is maintained as a Texinfo manual. If the -.BR info -(or -.BR pinfo ) -and -.BR openocd -programs are properly installed at your site, the command -.B info openocd -should give you access to the complete manual. -.SH "AUTHORS" -Please see the file AUTHORS. -.PP -This manual page was written by Uwe Hermann . -It is licensed under the terms of the GNU GPL (version 2 or later). diff --git a/doc/openocd.texi b/doc/openocd.texi deleted file mode 100644 index 81466546c..000000000 --- a/doc/openocd.texi +++ /dev/null @@ -1,9812 +0,0 @@ -\input texinfo @c -*-texinfo-*- -@c %**start of header -@setfilename openocd.info -@settitle OpenOCD User's Guide -@dircategory Development -@direntry -* OpenOCD: (openocd). OpenOCD User's Guide -@end direntry -@paragraphindent 0 -@c %**end of header - -@include version.texi - -@copying - -This User's Guide documents -release @value{VERSION}, -dated @value{UPDATED}, -of the Open On-Chip Debugger (OpenOCD). - -@itemize @bullet -@item Copyright @copyright{} 2008 The OpenOCD Project -@item Copyright @copyright{} 2007-2008 Spencer Oliver @email{spen@@spen-soft.co.uk} -@item Copyright @copyright{} 2008-2010 Oyvind Harboe @email{oyvind.harboe@@zylin.com} -@item Copyright @copyright{} 2008 Duane Ellis @email{openocd@@duaneellis.com} -@item Copyright @copyright{} 2009-2010 David Brownell -@end itemize - -@quotation -Permission is granted to copy, distribute and/or modify this document -under the terms of the GNU Free Documentation License, Version 1.2 or -any later version published by the Free Software Foundation; with no -Invariant Sections, with no Front-Cover Texts, and with no Back-Cover -Texts. A copy of the license is included in the section entitled ``GNU -Free Documentation License''. -@end quotation -@end copying - -@titlepage -@titlefont{@emph{Open On-Chip Debugger:}} -@sp 1 -@title OpenOCD User's Guide -@subtitle for release @value{VERSION} -@subtitle @value{UPDATED} - -@page -@vskip 0pt plus 1filll -@insertcopying -@end titlepage - -@summarycontents -@contents - -@ifnottex -@node Top -@top OpenOCD User's Guide - -@insertcopying -@end ifnottex - -@menu -* About:: About OpenOCD -* Developers:: OpenOCD Developer Resources -* Debug Adapter Hardware:: Debug Adapter Hardware -* About Jim-Tcl:: About Jim-Tcl -* Running:: Running OpenOCD -* OpenOCD Project Setup:: OpenOCD Project Setup -* Config File Guidelines:: Config File Guidelines -* Daemon Configuration:: Daemon Configuration -* Debug Adapter Configuration:: Debug Adapter Configuration -* Reset Configuration:: Reset Configuration -* TAP Declaration:: TAP Declaration -* CPU Configuration:: CPU Configuration -* Flash Commands:: Flash Commands -* Flash Programming:: Flash Programming -* PLD/FPGA Commands:: PLD/FPGA Commands -* General Commands:: General Commands -* Architecture and Core Commands:: Architecture and Core Commands -* JTAG Commands:: JTAG Commands -* Boundary Scan Commands:: Boundary Scan Commands -* Utility Commands:: Utility Commands -* TFTP:: TFTP -* GDB and OpenOCD:: Using GDB and OpenOCD -* Tcl Scripting API:: Tcl Scripting API -* FAQ:: Frequently Asked Questions -* Tcl Crash Course:: Tcl Crash Course -* License:: GNU Free Documentation License - -@comment DO NOT use the plain word ``Index'', reason: CYGWIN filename -@comment case issue with ``Index.html'' and ``index.html'' -@comment Occurs when creating ``--html --no-split'' output -@comment This fix is based on: http://sourceware.org/ml/binutils/2006-05/msg00215.html -* OpenOCD Concept Index:: Concept Index -* Command and Driver Index:: Command and Driver Index -@end menu - -@node About -@unnumbered About -@cindex about - -OpenOCD was created by Dominic Rath as part of a 2005 diploma thesis written -at the University of Applied Sciences Augsburg (@uref{http://www.hs-augsburg.de}). -Since that time, the project has grown into an active open-source project, -supported by a diverse community of software and hardware developers from -around the world. - -@section What is OpenOCD? -@cindex TAP -@cindex JTAG - -The Open On-Chip Debugger (OpenOCD) aims to provide debugging, -in-system programming and boundary-scan testing for embedded target -devices. - -It does so with the assistance of a @dfn{debug adapter}, which is -a small hardware module which helps provide the right kind of -electrical signaling to the target being debugged. These are -required since the debug host (on which OpenOCD runs) won't -usually have native support for such signaling, or the connector -needed to hook up to the target. - -Such debug adapters support one or more @dfn{transport} protocols, -each of which involves different electrical signaling (and uses -different messaging protocols on top of that signaling). There -are many types of debug adapter, and little uniformity in what -they are called. (There are also product naming differences.) - -These adapters are sometimes packaged as discrete dongles, which -may generically be called @dfn{hardware interface dongles}. -Some development boards also integrate them directly, which may -let the development board connect directly to the debug -host over USB (and sometimes also to power it over USB). - -For example, a @dfn{JTAG Adapter} supports JTAG -signaling, and is used to communicate -with JTAG (IEEE 1149.1) compliant TAPs on your target board. -A @dfn{TAP} is a ``Test Access Port'', a module which processes -special instructions and data. TAPs are daisy-chained within and -between chips and boards. JTAG supports debugging and boundary -scan operations. - -There are also @dfn{SWD Adapters} that support Serial Wire Debug (SWD) -signaling to communicate with some newer ARM cores, as well as debug -adapters which support both JTAG and SWD transports. SWD supports only -debugging, whereas JTAG also supports boundary scan operations. - -For some chips, there are also @dfn{Programming Adapters} supporting -special transports used only to write code to flash memory, without -support for on-chip debugging or boundary scan. -(At this writing, OpenOCD does not support such non-debug adapters.) - - -@b{Dongles:} OpenOCD currently supports many types of hardware dongles: -USB-based, parallel port-based, and other standalone boxes that run -OpenOCD internally. @xref{Debug Adapter Hardware}. - -@b{GDB Debug:} It allows ARM7 (ARM7TDMI and ARM720t), ARM9 (ARM920T, -ARM922T, ARM926EJ--S, ARM966E--S), XScale (PXA25x, IXP42x), Cortex-M3 -(Stellaris LM3, ST STM32 and Energy Micro EFM32) and Intel Quark (x10xx) -based cores to be debugged via the GDB protocol. - -@b{Flash Programming:} Flash writing is supported for external -CFI-compatible NOR flashes (Intel and AMD/Spansion command set) and several -internal flashes (LPC1700, LPC1800, LPC2000, LPC4300, AT91SAM7, AT91SAM3U, -STR7x, STR9x, LM3, STM32x and EFM32). Preliminary support for various NAND flash -controllers (LPC3180, Orion, S3C24xx, more) is included. - -@section OpenOCD Web Site - -The OpenOCD web site provides the latest public news from the community: - -@uref{http://openocd.org/} - -@section Latest User's Guide: - -The user's guide you are now reading may not be the latest one -available. A version for more recent code may be available. -Its HTML form is published regularly at: - -@uref{http://openocd.org/doc/html/index.html} - -PDF form is likewise published at: - -@uref{http://openocd.org/doc/pdf/openocd.pdf} - -@section OpenOCD User's Forum - -There is an OpenOCD forum (phpBB) hosted by SparkFun, -which might be helpful to you. Note that if you want -anything to come to the attention of developers, you -should post it to the OpenOCD Developer Mailing List -instead of this forum. - -@uref{http://forum.sparkfun.com/viewforum.php?f=18} - -@section OpenOCD User's Mailing List - -The OpenOCD User Mailing List provides the primary means of -communication between users: - -@uref{https://lists.sourceforge.net/mailman/listinfo/openocd-user} - -@section OpenOCD IRC - -Support can also be found on irc: -@uref{irc://irc.freenode.net/openocd} - -@node Developers -@chapter OpenOCD Developer Resources -@cindex developers - -If you are interested in improving the state of OpenOCD's debugging and -testing support, new contributions will be welcome. Motivated developers -can produce new target, flash or interface drivers, improve the -documentation, as well as more conventional bug fixes and enhancements. - -The resources in this chapter are available for developers wishing to explore -or expand the OpenOCD source code. - -@section OpenOCD Git Repository - -During the 0.3.x release cycle, OpenOCD switched from Subversion to -a Git repository hosted at SourceForge. The repository URL is: - -@uref{git://git.code.sf.net/p/openocd/code} - -or via http - -@uref{http://git.code.sf.net/p/openocd/code} - -You may prefer to use a mirror and the HTTP protocol: - -@uref{http://repo.or.cz/r/openocd.git} - -With standard Git tools, use @command{git clone} to initialize -a local repository, and @command{git pull} to update it. -There are also gitweb pages letting you browse the repository -with a web browser, or download arbitrary snapshots without -needing a Git client: - -@uref{http://repo.or.cz/w/openocd.git} - -The @file{README} file contains the instructions for building the project -from the repository or a snapshot. - -Developers that want to contribute patches to the OpenOCD system are -@b{strongly} encouraged to work against mainline. -Patches created against older versions may require additional -work from their submitter in order to be updated for newer releases. - -@section Doxygen Developer Manual - -During the 0.2.x release cycle, the OpenOCD project began -providing a Doxygen reference manual. This document contains more -technical information about the software internals, development -processes, and similar documentation: - -@uref{http://openocd.org/doc/doxygen/html/index.html} - -This document is a work-in-progress, but contributions would be welcome -to fill in the gaps. All of the source files are provided in-tree, -listed in the Doxyfile configuration at the top of the source tree. - -@section Gerrit Review System - -All changes in the OpenOCD Git repository go through the web-based Gerrit -Code Review System: - -@uref{http://openocd.zylin.com/} - -After a one-time registration and repository setup, anyone can push commits -from their local Git repository directly into Gerrit. -All users and developers are encouraged to review, test, discuss and vote -for changes in Gerrit. The feedback provides the basis for a maintainer to -eventually submit the change to the main Git repository. - -The @file{HACKING} file, also available as the Patch Guide in the Doxygen -Developer Manual, contains basic information about how to connect a -repository to Gerrit, prepare and push patches. Patch authors are expected to -maintain their changes while they're in Gerrit, respond to feedback and if -necessary rework and push improved versions of the change. - -@section OpenOCD Developer Mailing List - -The OpenOCD Developer Mailing List provides the primary means of -communication between developers: - -@uref{https://lists.sourceforge.net/mailman/listinfo/openocd-devel} - -@section OpenOCD Bug Tracker - -The OpenOCD Bug Tracker is hosted on SourceForge: - -@uref{http://bugs.openocd.org/} - - -@node Debug Adapter Hardware -@chapter Debug Adapter Hardware -@cindex dongles -@cindex FTDI -@cindex wiggler -@cindex zy1000 -@cindex printer port -@cindex USB Adapter -@cindex RTCK - -Defined: @b{dongle}: A small device that plugs into a computer and serves as -an adapter .... [snip] - -In the OpenOCD case, this generally refers to @b{a small adapter} that -attaches to your computer via USB or the parallel port. One -exception is the Ultimate Solutions ZY1000, packaged as a small box you -attach via an ethernet cable. The ZY1000 has the advantage that it does not -require any drivers to be installed on the developer PC. It also has -a built in web interface. It supports RTCK/RCLK or adaptive clocking -and has a built-in relay to power cycle targets remotely. - - -@section Choosing a Dongle - -There are several things you should keep in mind when choosing a dongle. - -@enumerate -@item @b{Transport} Does it support the kind of communication that you need? -OpenOCD focusses mostly on JTAG. Your version may also support -other ways to communicate with target devices. -@item @b{Voltage} What voltage is your target - 1.8, 2.8, 3.3, or 5V? -Does your dongle support it? You might need a level converter. -@item @b{Pinout} What pinout does your target board use? -Does your dongle support it? You may be able to use jumper -wires, or an "octopus" connector, to convert pinouts. -@item @b{Connection} Does your computer have the USB, parallel, or -Ethernet port needed? -@item @b{RTCK} Do you expect to use it with ARM chips and boards with -RTCK support (also known as ``adaptive clocking'')? -@end enumerate - -@section Stand-alone JTAG Probe - -The ZY1000 from Ultimate Solutions is technically not a dongle but a -stand-alone JTAG probe that, unlike most dongles, doesn't require any drivers -running on the developer's host computer. -Once installed on a network using DHCP or a static IP assignment, users can -access the ZY1000 probe locally or remotely from any host with access to the -IP address assigned to the probe. -The ZY1000 provides an intuitive web interface with direct access to the -OpenOCD debugger. -Users may also run a GDBSERVER directly on the ZY1000 to take full advantage -of GCC & GDB to debug any distribution of embedded Linux or NetBSD running on -the target. -The ZY1000 supports RTCK & RCLK or adaptive clocking and has a built-in relay -to power cycle the target remotely. - -For more information, visit: - -@b{ZY1000} See: @url{http://www.ultsol.com/index.php/component/content/article/8/210-zylin-zy1000-main} - -@section USB FT2232 Based - -There are many USB JTAG dongles on the market, many of them based -on a chip from ``Future Technology Devices International'' (FTDI) -known as the FTDI FT2232; this is a USB full speed (12 Mbps) chip. -See: @url{http://www.ftdichip.com} for more information. -In summer 2009, USB high speed (480 Mbps) versions of these FTDI -chips started to become available in JTAG adapters. Around 2012, a new -variant appeared - FT232H - this is a single-channel version of FT2232H. -(Adapters using those high speed FT2232H or FT232H chips may support adaptive -clocking.) - -The FT2232 chips are flexible enough to support some other -transport options, such as SWD or the SPI variants used to -program some chips. They have two communications channels, -and one can be used for a UART adapter at the same time the -other one is used to provide a debug adapter. - -Also, some development boards integrate an FT2232 chip to serve as -a built-in low-cost debug adapter and USB-to-serial solution. - -@itemize @bullet -@item @b{usbjtag} -@* Link @url{http://elk.informatik.fh-augsburg.de/hhweb/doc/openocd/usbjtag/usbjtag.html} -@item @b{jtagkey} -@* See: @url{http://www.amontec.com/jtagkey.shtml} -@item @b{jtagkey2} -@* See: @url{http://www.amontec.com/jtagkey2.shtml} -@item @b{oocdlink} -@* See: @url{http://www.oocdlink.com} By Joern Kaipf -@item @b{signalyzer} -@* See: @url{http://www.signalyzer.com} -@item @b{Stellaris Eval Boards} -@* See: @url{http://www.ti.com} - The Stellaris eval boards -bundle FT2232-based JTAG and SWD support, which can be used to debug -the Stellaris chips. Using separate JTAG adapters is optional. -These boards can also be used in a "pass through" mode as JTAG adapters -to other target boards, disabling the Stellaris chip. -@item @b{TI/Luminary ICDI} -@* See: @url{http://www.ti.com} - TI/Luminary In-Circuit Debug -Interface (ICDI) Boards are included in Stellaris LM3S9B9x -Evaluation Kits. Like the non-detachable FT2232 support on the other -Stellaris eval boards, they can be used to debug other target boards. -@item @b{olimex-jtag} -@* See: @url{http://www.olimex.com} -@item @b{Flyswatter/Flyswatter2} -@* See: @url{http://www.tincantools.com} -@item @b{turtelizer2} -@* See: -@uref{http://www.ethernut.de/en/hardware/turtelizer/index.html, Turtelizer 2}, or -@url{http://www.ethernut.de} -@item @b{comstick} -@* Link: @url{http://www.hitex.com/index.php?id=383} -@item @b{stm32stick} -@* Link @url{http://www.hitex.com/stm32-stick} -@item @b{axm0432_jtag} -@* Axiom AXM-0432 Link @url{http://www.axman.com} - NOTE: This JTAG does not appear -to be available anymore as of April 2012. -@item @b{cortino} -@* Link @url{http://www.hitex.com/index.php?id=cortino} -@item @b{dlp-usb1232h} -@* Link @url{http://www.dlpdesign.com/usb/usb1232h.shtml} -@item @b{digilent-hs1} -@* Link @url{http://www.digilentinc.com/Products/Detail.cfm?Prod=JTAG-HS1} -@item @b{opendous} -@* Link @url{http://code.google.com/p/opendous/wiki/JTAG} FT2232H-based -(OpenHardware). -@item @b{JTAG-lock-pick Tiny 2} -@* Link @url{http://www.distortec.com/jtag-lock-pick-tiny-2} FT232H-based - -@item @b{GW16042} -@* Link: @url{http://shop.gateworks.com/index.php?route=product/product&path=70_80&product_id=64} -FT2232H-based - -@end itemize -@section USB-JTAG / Altera USB-Blaster compatibles - -These devices also show up as FTDI devices, but are not -protocol-compatible with the FT2232 devices. They are, however, -protocol-compatible among themselves. USB-JTAG devices typically consist -of a FT245 followed by a CPLD that understands a particular protocol, -or emulates this protocol using some other hardware. - -They may appear under different USB VID/PID depending on the particular -product. The driver can be configured to search for any VID/PID pair -(see the section on driver commands). - -@itemize -@item @b{USB-JTAG} Kolja Waschk's USB Blaster-compatible adapter -@* Link: @url{http://ixo-jtag.sourceforge.net/} -@item @b{Altera USB-Blaster} -@* Link: @url{http://www.altera.com/literature/ug/ug_usb_blstr.pdf} -@end itemize - -@section USB J-Link based -There are several OEM versions of the SEGGER @b{J-Link} adapter. It is -an example of a microcontroller based JTAG adapter, it uses an -AT91SAM764 internally. - -@itemize @bullet -@item @b{SEGGER J-Link} -@* Link: @url{http://www.segger.com/jlink.html} -@item @b{Atmel SAM-ICE} (Only works with Atmel chips!) -@* Link: @url{http://www.atmel.com/tools/atmelsam-ice.aspx} -@item @b{IAR J-Link} -@end itemize - -@section USB RLINK based -Raisonance has an adapter called @b{RLink}. It exists in a stripped-down form on the STM32 Primer, -permanently attached to the JTAG lines. It also exists on the STM32 Primer2, but that is wired for -SWD and not JTAG, thus not supported. - -@itemize @bullet -@item @b{Raisonance RLink} -@* Link: @url{http://www.mcu-raisonance.com/~rlink-debugger-programmer__@/microcontrollers__tool~tool__T018:4cn9ziz4bnx6.html} -@item @b{STM32 Primer} -@* Link: @url{http://www.stm32circle.com/resources/stm32primer.php} -@item @b{STM32 Primer2} -@* Link: @url{http://www.stm32circle.com/resources/stm32primer2.php} -@end itemize - -@section USB ST-LINK based -ST Micro has an adapter called @b{ST-LINK}. -They only work with ST Micro chips, notably STM32 and STM8. - -@itemize @bullet -@item @b{ST-LINK} -@* This is available standalone and as part of some kits, eg. STM32VLDISCOVERY. -@* Link: @url{http://www.st.com/internet/evalboard/product/219866.jsp} -@item @b{ST-LINK/V2} -@* This is available standalone and as part of some kits, eg. STM32F4DISCOVERY. -@* Link: @url{http://www.st.com/internet/evalboard/product/251168.jsp} -@end itemize - -For info the original ST-LINK enumerates using the mass storage usb class; however, -its implementation is completely broken. The result is this causes issues under Linux. -The simplest solution is to get Linux to ignore the ST-LINK using one of the following methods: -@itemize @bullet -@item modprobe -r usb-storage && modprobe usb-storage quirks=483:3744:i -@item add "options usb-storage quirks=483:3744:i" to /etc/modprobe.conf -@end itemize - -@section USB TI/Stellaris ICDI based -Texas Instruments has an adapter called @b{ICDI}. -It is not to be confused with the FTDI based adapters that were originally fitted to their -evaluation boards. This is the adapter fitted to the Stellaris LaunchPad. - -@section USB CMSIS-DAP based -ARM has released a interface standard called CMSIS-DAP that simplifies connecting -debuggers to ARM Cortex based targets @url{http://www.keil.com/support/man/docs/dapdebug/dapdebug_introduction.htm}. - -@section USB Other -@itemize @bullet -@item @b{USBprog} -@* Link: @url{http://shop.embedded-projects.net/} - which uses an Atmel MEGA32 and a UBN9604 - -@item @b{USB - Presto} -@* Link: @url{http://tools.asix.net/prg_presto.htm} - -@item @b{Versaloon-Link} -@* Link: @url{http://www.versaloon.com} - -@item @b{ARM-JTAG-EW} -@* Link: @url{http://www.olimex.com/dev/arm-jtag-ew.html} - -@item @b{Buspirate} -@* Link: @url{http://dangerousprototypes.com/bus-pirate-manual/} - -@item @b{opendous} -@* Link: @url{http://code.google.com/p/opendous-jtag/} - which uses an AT90USB162 - -@item @b{estick} -@* Link: @url{http://code.google.com/p/estick-jtag/} - -@item @b{Keil ULINK v1} -@* Link: @url{http://www.keil.com/ulink1/} -@end itemize - -@section IBM PC Parallel Printer Port Based - -The two well-known ``JTAG Parallel Ports'' cables are the Xilinx DLC5 -and the Macraigor Wiggler. There are many clones and variations of -these on the market. - -Note that parallel ports are becoming much less common, so if you -have the choice you should probably avoid these adapters in favor -of USB-based ones. - -@itemize @bullet - -@item @b{Wiggler} - There are many clones of this. -@* Link: @url{http://www.macraigor.com/wiggler.htm} - -@item @b{DLC5} - From XILINX - There are many clones of this -@* Link: Search the web for: ``XILINX DLC5'' - it is no longer -produced, PDF schematics are easily found and it is easy to make. - -@item @b{Amontec - JTAG Accelerator} -@* Link: @url{http://www.amontec.com/jtag_accelerator.shtml} - -@item @b{Wiggler2} -@* Link: @url{http://www.ccac.rwth-aachen.de/~michaels/index.php/hardware/armjtag} - -@item @b{Wiggler_ntrst_inverted} -@* Yet another variation - See the source code, src/jtag/parport.c - -@item @b{old_amt_wiggler} -@* Unknown - probably not on the market today - -@item @b{arm-jtag} -@* Link: Most likely @url{http://www.olimex.com/dev/arm-jtag.html} [another wiggler clone] - -@item @b{chameleon} -@* Link: @url{http://www.amontec.com/chameleon.shtml} - -@item @b{Triton} -@* Unknown. - -@item @b{Lattice} -@* ispDownload from Lattice Semiconductor -@url{http://www.latticesemi.com/lit/docs/@/devtools/dlcable.pdf} - -@item @b{flashlink} -@* From ST Microsystems; -@* Link: @url{http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/DATA_BRIEF/DM00039500.pdf} - -@end itemize - -@section Other... -@itemize @bullet - -@item @b{ep93xx} -@* An EP93xx based Linux machine using the GPIO pins directly. - -@item @b{at91rm9200} -@* Like the EP93xx - but an ATMEL AT91RM9200 based solution using the GPIO pins on the chip. - -@item @b{bcm2835gpio} -@* A BCM2835-based board (e.g. Raspberry Pi) using the GPIO pins of the expansion header. - -@item @b{jtag_vpi} -@* A JTAG driver acting as a client for the JTAG VPI server interface. -@* Link: @url{http://github.com/fjullien/jtag_vpi} - -@end itemize - -@node About Jim-Tcl -@chapter About Jim-Tcl -@cindex Jim-Tcl -@cindex tcl - -OpenOCD uses a small ``Tcl Interpreter'' known as Jim-Tcl. -This programming language provides a simple and extensible -command interpreter. - -All commands presented in this Guide are extensions to Jim-Tcl. -You can use them as simple commands, without needing to learn -much of anything about Tcl. -Alternatively, you can write Tcl programs with them. - -You can learn more about Jim at its website, @url{http://jim.tcl.tk}. -There is an active and responsive community, get on the mailing list -if you have any questions. Jim-Tcl maintainers also lurk on the -OpenOCD mailing list. - -@itemize @bullet -@item @b{Jim vs. Tcl} -@* Jim-Tcl is a stripped down version of the well known Tcl language, -which can be found here: @url{http://www.tcl.tk}. Jim-Tcl has far -fewer features. Jim-Tcl is several dozens of .C files and .H files and -implements the basic Tcl command set. In contrast: Tcl 8.6 is a -4.2 MB .zip file containing 1540 files. - -@item @b{Missing Features} -@* Our practice has been: Add/clone the real Tcl feature if/when -needed. We welcome Jim-Tcl improvements, not bloat. Also there -are a large number of optional Jim-Tcl features that are not -enabled in OpenOCD. - -@item @b{Scripts} -@* OpenOCD configuration scripts are Jim-Tcl Scripts. OpenOCD's -command interpreter today is a mixture of (newer) -Jim-Tcl commands, and the (older) original command interpreter. - -@item @b{Commands} -@* At the OpenOCD telnet command line (or via the GDB monitor command) one -can type a Tcl for() loop, set variables, etc. -Some of the commands documented in this guide are implemented -as Tcl scripts, from a @file{startup.tcl} file internal to the server. - -@item @b{Historical Note} -@* Jim-Tcl was introduced to OpenOCD in spring 2008. Fall 2010, -before OpenOCD 0.5 release, OpenOCD switched to using Jim-Tcl -as a Git submodule, which greatly simplified upgrading Jim-Tcl -to benefit from new features and bugfixes in Jim-Tcl. - -@item @b{Need a crash course in Tcl?} -@*@xref{Tcl Crash Course}. -@end itemize - -@node Running -@chapter Running -@cindex command line options -@cindex logfile -@cindex directory search - -Properly installing OpenOCD sets up your operating system to grant it access -to the debug adapters. On Linux, this usually involves installing a file -in @file{/etc/udev/rules.d,} so OpenOCD has permissions. An example rules file -that works for many common adapters is shipped with OpenOCD in the -@file{contrib} directory. MS-Windows needs -complex and confusing driver configuration for every peripheral. Such issues -are unique to each operating system, and are not detailed in this User's Guide. - -Then later you will invoke the OpenOCD server, with various options to -tell it how each debug session should work. -The @option{--help} option shows: -@verbatim -bash$ openocd --help - ---help | -h display this help ---version | -v display OpenOCD version ---file | -f use configuration file ---search | -s dir to search for config files and scripts ---debug | -d set debug level <0-3> ---log_output | -l redirect log output to file ---command | -c run -@end verbatim - -If you don't give any @option{-f} or @option{-c} options, -OpenOCD tries to read the configuration file @file{openocd.cfg}. -To specify one or more different -configuration files, use @option{-f} options. For example: - -@example -openocd -f config1.cfg -f config2.cfg -f config3.cfg -@end example - -Configuration files and scripts are searched for in -@enumerate -@item the current directory, -@item any search dir specified on the command line using the @option{-s} option, -@item any search dir specified using the @command{add_script_search_dir} command, -@item @file{$HOME/.openocd} (not on Windows), -@item a directory in the @env{OPENOCD_SCRIPTS} environment variable (if set), -@item the site wide script library @file{$pkgdatadir/site} and -@item the OpenOCD-supplied script library @file{$pkgdatadir/scripts}. -@end enumerate -The first found file with a matching file name will be used. - -@quotation Note -Don't try to use configuration script names or paths which -include the "#" character. That character begins Tcl comments. -@end quotation - -@section Simple setup, no customization - -In the best case, you can use two scripts from one of the script -libraries, hook up your JTAG adapter, and start the server ... and -your JTAG setup will just work "out of the box". Always try to -start by reusing those scripts, but assume you'll need more -customization even if this works. @xref{OpenOCD Project Setup}. - -If you find a script for your JTAG adapter, and for your board or -target, you may be able to hook up your JTAG adapter then start -the server with some variation of one of the following: - -@example -openocd -f interface/ADAPTER.cfg -f board/MYBOARD.cfg -openocd -f interface/ftdi/ADAPTER.cfg -f board/MYBOARD.cfg -@end example - -You might also need to configure which reset signals are present, -using @option{-c 'reset_config trst_and_srst'} or something similar. -If all goes well you'll see output something like - -@example -Open On-Chip Debugger 0.4.0 (2010-01-14-15:06) -For bug reports, read - http://openocd.org/doc/doxygen/bugs.html -Info : JTAG tap: lm3s.cpu tap/device found: 0x3ba00477 - (mfg: 0x23b, part: 0xba00, ver: 0x3) -@end example - -Seeing that "tap/device found" message, and no warnings, means -the JTAG communication is working. That's a key milestone, but -you'll probably need more project-specific setup. - -@section What OpenOCD does as it starts - -OpenOCD starts by processing the configuration commands provided -on the command line or, if there were no @option{-c command} or -@option{-f file.cfg} options given, in @file{openocd.cfg}. -@xref{configurationstage,,Configuration Stage}. -At the end of the configuration stage it verifies the JTAG scan -chain defined using those commands; your configuration should -ensure that this always succeeds. -Normally, OpenOCD then starts running as a daemon. -Alternatively, commands may be used to terminate the configuration -stage early, perform work (such as updating some flash memory), -and then shut down without acting as a daemon. - -Once OpenOCD starts running as a daemon, it waits for connections from -clients (Telnet, GDB, Other) and processes the commands issued through -those channels. - -If you are having problems, you can enable internal debug messages via -the @option{-d} option. - -Also it is possible to interleave Jim-Tcl commands w/config scripts using the -@option{-c} command line switch. - -To enable debug output (when reporting problems or working on OpenOCD -itself), use the @option{-d} command line switch. This sets the -@option{debug_level} to "3", outputting the most information, -including debug messages. The default setting is "2", outputting only -informational messages, warnings and errors. You can also change this -setting from within a telnet or gdb session using @command{debug_level} -(@pxref{debuglevel,,debug_level}). - -You can redirect all output from the daemon to a file using the -@option{-l } switch. - -Note! OpenOCD will launch the GDB & telnet server even if it can not -establish a connection with the target. In general, it is possible for -the JTAG controller to be unresponsive until the target is set up -correctly via e.g. GDB monitor commands in a GDB init script. - -@node OpenOCD Project Setup -@chapter OpenOCD Project Setup - -To use OpenOCD with your development projects, you need to do more than -just connect the JTAG adapter hardware (dongle) to your development board -and start the OpenOCD server. -You also need to configure your OpenOCD server so that it knows -about your adapter and board, and helps your work. -You may also want to connect OpenOCD to GDB, possibly -using Eclipse or some other GUI. - -@section Hooking up the JTAG Adapter - -Today's most common case is a dongle with a JTAG cable on one side -(such as a ribbon cable with a 10-pin or 20-pin IDC connector) -and a USB cable on the other. -Instead of USB, some cables use Ethernet; -older ones may use a PC parallel port, or even a serial port. - -@enumerate -@item @emph{Start with power to your target board turned off}, -and nothing connected to your JTAG adapter. -If you're particularly paranoid, unplug power to the board. -It's important to have the ground signal properly set up, -unless you are using a JTAG adapter which provides -galvanic isolation between the target board and the -debugging host. - -@item @emph{Be sure it's the right kind of JTAG connector.} -If your dongle has a 20-pin ARM connector, you need some kind -of adapter (or octopus, see below) to hook it up to -boards using 14-pin or 10-pin connectors ... or to 20-pin -connectors which don't use ARM's pinout. - -In the same vein, make sure the voltage levels are compatible. -Not all JTAG adapters have the level shifters needed to work -with 1.2 Volt boards. - -@item @emph{Be certain the cable is properly oriented} or you might -damage your board. In most cases there are only two possible -ways to connect the cable. -Connect the JTAG cable from your adapter to the board. -Be sure it's firmly connected. - -In the best case, the connector is keyed to physically -prevent you from inserting it wrong. -This is most often done using a slot on the board's male connector -housing, which must match a key on the JTAG cable's female connector. -If there's no housing, then you must look carefully and -make sure pin 1 on the cable hooks up to pin 1 on the board. -Ribbon cables are frequently all grey except for a wire on one -edge, which is red. The red wire is pin 1. - -Sometimes dongles provide cables where one end is an ``octopus'' of -color coded single-wire connectors, instead of a connector block. -These are great when converting from one JTAG pinout to another, -but are tedious to set up. -Use these with connector pinout diagrams to help you match up the -adapter signals to the right board pins. - -@item @emph{Connect the adapter's other end} once the JTAG cable is connected. -A USB, parallel, or serial port connector will go to the host which -you are using to run OpenOCD. -For Ethernet, consult the documentation and your network administrator. - -For USB-based JTAG adapters you have an easy sanity check at this point: -does the host operating system see the JTAG adapter? If you're running -Linux, try the @command{lsusb} command. If that host is an -MS-Windows host, you'll need to install a driver before OpenOCD works. - -@item @emph{Connect the adapter's power supply, if needed.} -This step is primarily for non-USB adapters, -but sometimes USB adapters need extra power. - -@item @emph{Power up the target board.} -Unless you just let the magic smoke escape, -you're now ready to set up the OpenOCD server -so you can use JTAG to work with that board. - -@end enumerate - -Talk with the OpenOCD server using -telnet (@code{telnet localhost 4444} on many systems) or GDB. -@xref{GDB and OpenOCD}. - -@section Project Directory - -There are many ways you can configure OpenOCD and start it up. - -A simple way to organize them all involves keeping a -single directory for your work with a given board. -When you start OpenOCD from that directory, -it searches there first for configuration files, scripts, -files accessed through semihosting, -and for code you upload to the target board. -It is also the natural place to write files, -such as log files and data you download from the board. - -@section Configuration Basics - -There are two basic ways of configuring OpenOCD, and -a variety of ways you can mix them. -Think of the difference as just being how you start the server: - -@itemize -@item Many @option{-f file} or @option{-c command} options on the command line -@item No options, but a @dfn{user config file} -in the current directory named @file{openocd.cfg} -@end itemize - -Here is an example @file{openocd.cfg} file for a setup -using a Signalyzer FT2232-based JTAG adapter to talk to -a board with an Atmel AT91SAM7X256 microcontroller: - -@example -source [find interface/signalyzer.cfg] - -# GDB can also flash my flash! -gdb_memory_map enable -gdb_flash_program enable - -source [find target/sam7x256.cfg] -@end example - -Here is the command line equivalent of that configuration: - -@example -openocd -f interface/signalyzer.cfg \ - -c "gdb_memory_map enable" \ - -c "gdb_flash_program enable" \ - -f target/sam7x256.cfg -@end example - -You could wrap such long command lines in shell scripts, -each supporting a different development task. -One might re-flash the board with a specific firmware version. -Another might set up a particular debugging or run-time environment. - -@quotation Important -At this writing (October 2009) the command line method has -problems with how it treats variables. -For example, after @option{-c "set VAR value"}, or doing the -same in a script, the variable @var{VAR} will have no value -that can be tested in a later script. -@end quotation - -Here we will focus on the simpler solution: one user config -file, including basic configuration plus any TCL procedures -to simplify your work. - -@section User Config Files -@cindex config file, user -@cindex user config file -@cindex config file, overview - -A user configuration file ties together all the parts of a project -in one place. -One of the following will match your situation best: - -@itemize -@item Ideally almost everything comes from configuration files -provided by someone else. -For example, OpenOCD distributes a @file{scripts} directory -(probably in @file{/usr/share/openocd/scripts} on Linux). -Board and tool vendors can provide these too, as can individual -user sites; the @option{-s} command line option lets you say -where to find these files. (@xref{Running}.) -The AT91SAM7X256 example above works this way. - -Three main types of non-user configuration file each have their -own subdirectory in the @file{scripts} directory: - -@enumerate -@item @b{interface} -- one for each different debug adapter; -@item @b{board} -- one for each different board -@item @b{target} -- the chips which integrate CPUs and other JTAG TAPs -@end enumerate - -Best case: include just two files, and they handle everything else. -The first is an interface config file. -The second is board-specific, and it sets up the JTAG TAPs and -their GDB targets (by deferring to some @file{target.cfg} file), -declares all flash memory, and leaves you nothing to do except -meet your deadline: - -@example -source [find interface/olimex-jtag-tiny.cfg] -source [find board/csb337.cfg] -@end example - -Boards with a single microcontroller often won't need more -than the target config file, as in the AT91SAM7X256 example. -That's because there is no external memory (flash, DDR RAM), and -the board differences are encapsulated by application code. - -@item Maybe you don't know yet what your board looks like to JTAG. -Once you know the @file{interface.cfg} file to use, you may -need help from OpenOCD to discover what's on the board. -Once you find the JTAG TAPs, you can just search for appropriate -target and board -configuration files ... or write your own, from the bottom up. -@xref{autoprobing,,Autoprobing}. - -@item You can often reuse some standard config files but -need to write a few new ones, probably a @file{board.cfg} file. -You will be using commands described later in this User's Guide, -and working with the guidelines in the next chapter. - -For example, there may be configuration files for your JTAG adapter -and target chip, but you need a new board-specific config file -giving access to your particular flash chips. -Or you might need to write another target chip configuration file -for a new chip built around the Cortex-M3 core. - -@quotation Note -When you write new configuration files, please submit -them for inclusion in the next OpenOCD release. -For example, a @file{board/newboard.cfg} file will help the -next users of that board, and a @file{target/newcpu.cfg} -will help support users of any board using that chip. -@end quotation - -@item -You may may need to write some C code. -It may be as simple as supporting a new FT2232 or parport -based adapter; a bit more involved, like a NAND or NOR flash -controller driver; or a big piece of work like supporting -a new chip architecture. -@end itemize - -Reuse the existing config files when you can. -Look first in the @file{scripts/boards} area, then @file{scripts/targets}. -You may find a board configuration that's a good example to follow. - -When you write config files, separate the reusable parts -(things every user of that interface, chip, or board needs) -from ones specific to your environment and debugging approach. -@itemize - -@item -For example, a @code{gdb-attach} event handler that invokes -the @command{reset init} command will interfere with debugging -early boot code, which performs some of the same actions -that the @code{reset-init} event handler does. - -@item -Likewise, the @command{arm9 vector_catch} command (or -@cindex vector_catch -its siblings @command{xscale vector_catch} -and @command{cortex_m vector_catch}) can be a timesaver -during some debug sessions, but don't make everyone use that either. -Keep those kinds of debugging aids in your user config file, -along with messaging and tracing setup. -(@xref{softwaredebugmessagesandtracing,,Software Debug Messages and Tracing}.) - -@item -You might need to override some defaults. -For example, you might need to move, shrink, or back up the target's -work area if your application needs much SRAM. - -@item -TCP/IP port configuration is another example of something which -is environment-specific, and should only appear in -a user config file. @xref{tcpipports,,TCP/IP Ports}. -@end itemize - -@section Project-Specific Utilities - -A few project-specific utility -routines may well speed up your work. -Write them, and keep them in your project's user config file. - -For example, if you are making a boot loader work on a -board, it's nice to be able to debug the ``after it's -loaded to RAM'' parts separately from the finicky early -code which sets up the DDR RAM controller and clocks. -A script like this one, or a more GDB-aware sibling, -may help: - -@example -proc ramboot @{ @} @{ - # Reset, running the target's "reset-init" scripts - # to initialize clocks and the DDR RAM controller. - # Leave the CPU halted. - reset init - - # Load CONFIG_SKIP_LOWLEVEL_INIT version into DDR RAM. - load_image u-boot.bin 0x20000000 - - # Start running. - resume 0x20000000 -@} -@end example - -Then once that code is working you will need to make it -boot from NOR flash; a different utility would help. -Alternatively, some developers write to flash using GDB. -(You might use a similar script if you're working with a flash -based microcontroller application instead of a boot loader.) - -@example -proc newboot @{ @} @{ - # Reset, leaving the CPU halted. The "reset-init" event - # proc gives faster access to the CPU and to NOR flash; - # "reset halt" would be slower. - reset init - - # Write standard version of U-Boot into the first two - # sectors of NOR flash ... the standard version should - # do the same lowlevel init as "reset-init". - flash protect 0 0 1 off - flash erase_sector 0 0 1 - flash write_bank 0 u-boot.bin 0x0 - flash protect 0 0 1 on - - # Reboot from scratch using that new boot loader. - reset run -@} -@end example - -You may need more complicated utility procedures when booting -from NAND. -That often involves an extra bootloader stage, -running from on-chip SRAM to perform DDR RAM setup so it can load -the main bootloader code (which won't fit into that SRAM). - -Other helper scripts might be used to write production system images, -involving considerably more than just a three stage bootloader. - -@section Target Software Changes - -Sometimes you may want to make some small changes to the software -you're developing, to help make JTAG debugging work better. -For example, in C or assembly language code you might -use @code{#ifdef JTAG_DEBUG} (or its converse) around code -handling issues like: - -@itemize @bullet - -@item @b{Watchdog Timers}... -Watchog timers are typically used to automatically reset systems if -some application task doesn't periodically reset the timer. (The -assumption is that the system has locked up if the task can't run.) -When a JTAG debugger halts the system, that task won't be able to run -and reset the timer ... potentially causing resets in the middle of -your debug sessions. - -It's rarely a good idea to disable such watchdogs, since their usage -needs to be debugged just like all other parts of your firmware. -That might however be your only option. - -Look instead for chip-specific ways to stop the watchdog from counting -while the system is in a debug halt state. It may be simplest to set -that non-counting mode in your debugger startup scripts. You may however -need a different approach when, for example, a motor could be physically -damaged by firmware remaining inactive in a debug halt state. That might -involve a type of firmware mode where that "non-counting" mode is disabled -at the beginning then re-enabled at the end; a watchdog reset might fire -and complicate the debug session, but hardware (or people) would be -protected.@footnote{Note that many systems support a "monitor mode" debug -that is a somewhat cleaner way to address such issues. You can think of -it as only halting part of the system, maybe just one task, -instead of the whole thing. -At this writing, January 2010, OpenOCD based debugging does not support -monitor mode debug, only "halt mode" debug.} - -@item @b{ARM Semihosting}... -@cindex ARM semihosting -When linked with a special runtime library provided with many -toolchains@footnote{See chapter 8 "Semihosting" in -@uref{http://infocenter.arm.com/help/topic/com.arm.doc.dui0203i/DUI0203I_rvct_developer_guide.pdf, -ARM DUI 0203I}, the "RealView Compilation Tools Developer Guide". -The CodeSourcery EABI toolchain also includes a semihosting library.}, -your target code can use I/O facilities on the debug host. That library -provides a small set of system calls which are handled by OpenOCD. -It can let the debugger provide your system console and a file system, -helping with early debugging or providing a more capable environment -for sometimes-complex tasks like installing system firmware onto -NAND or SPI flash. - -@item @b{ARM Wait-For-Interrupt}... -Many ARM chips synchronize the JTAG clock using the core clock. -Low power states which stop that core clock thus prevent JTAG access. -Idle loops in tasking environments often enter those low power states -via the @code{WFI} instruction (or its coprocessor equivalent, before ARMv7). - -You may want to @emph{disable that instruction} in source code, -or otherwise prevent using that state, -to ensure you can get JTAG access at any time.@footnote{As a more -polite alternative, some processors have special debug-oriented -registers which can be used to change various features including -how the low power states are clocked while debugging. -The STM32 DBGMCU_CR register is an example; at the cost of extra -power consumption, JTAG can be used during low power states.} -For example, the OpenOCD @command{halt} command may not -work for an idle processor otherwise. - -@item @b{Delay after reset}... -Not all chips have good support for debugger access -right after reset; many LPC2xxx chips have issues here. -Similarly, applications that reconfigure pins used for -JTAG access as they start will also block debugger access. - -To work with boards like this, @emph{enable a short delay loop} -the first thing after reset, before "real" startup activities. -For example, one second's delay is usually more than enough -time for a JTAG debugger to attach, so that -early code execution can be debugged -or firmware can be replaced. - -@item @b{Debug Communications Channel (DCC)}... -Some processors include mechanisms to send messages over JTAG. -Many ARM cores support these, as do some cores from other vendors. -(OpenOCD may be able to use this DCC internally, speeding up some -operations like writing to memory.) - -Your application may want to deliver various debugging messages -over JTAG, by @emph{linking with a small library of code} -provided with OpenOCD and using the utilities there to send -various kinds of message. -@xref{softwaredebugmessagesandtracing,,Software Debug Messages and Tracing}. - -@end itemize - -@section Target Hardware Setup - -Chip vendors often provide software development boards which -are highly configurable, so that they can support all options -that product boards may require. @emph{Make sure that any -jumpers or switches match the system configuration you are -working with.} - -Common issues include: - -@itemize @bullet - -@item @b{JTAG setup} ... -Boards may support more than one JTAG configuration. -Examples include jumpers controlling pullups versus pulldowns -on the nTRST and/or nSRST signals, and choice of connectors -(e.g. which of two headers on the base board, -or one from a daughtercard). -For some Texas Instruments boards, you may need to jumper the -EMU0 and EMU1 signals (which OpenOCD won't currently control). - -@item @b{Boot Modes} ... -Complex chips often support multiple boot modes, controlled -by external jumpers. Make sure this is set up correctly. -For example many i.MX boards from NXP need to be jumpered -to "ATX mode" to start booting using the on-chip ROM, when -using second stage bootloader code stored in a NAND flash chip. - -Such explicit configuration is common, and not limited to -booting from NAND. You might also need to set jumpers to -start booting using code loaded from an MMC/SD card; external -SPI flash; Ethernet, UART, or USB links; NOR flash; OneNAND -flash; some external host; or various other sources. - - -@item @b{Memory Addressing} ... -Boards which support multiple boot modes may also have jumpers -to configure memory addressing. One board, for example, jumpers -external chipselect 0 (used for booting) to address either -a large SRAM (which must be pre-loaded via JTAG), NOR flash, -or NAND flash. When it's jumpered to address NAND flash, that -board must also be told to start booting from on-chip ROM. - -Your @file{board.cfg} file may also need to be told this jumper -configuration, so that it can know whether to declare NOR flash -using @command{flash bank} or instead declare NAND flash with -@command{nand device}; and likewise which probe to perform in -its @code{reset-init} handler. - -A closely related issue is bus width. Jumpers might need to -distinguish between 8 bit or 16 bit bus access for the flash -used to start booting. - -@item @b{Peripheral Access} ... -Development boards generally provide access to every peripheral -on the chip, sometimes in multiple modes (such as by providing -multiple audio codec chips). -This interacts with software -configuration of pin multiplexing, where for example a -given pin may be routed either to the MMC/SD controller -or the GPIO controller. It also often interacts with -configuration jumpers. One jumper may be used to route -signals to an MMC/SD card slot or an expansion bus (which -might in turn affect booting); others might control which -audio or video codecs are used. - -@end itemize - -Plus you should of course have @code{reset-init} event handlers -which set up the hardware to match that jumper configuration. -That includes in particular any oscillator or PLL used to clock -the CPU, and any memory controllers needed to access external -memory and peripherals. Without such handlers, you won't be -able to access those resources without working target firmware -which can do that setup ... this can be awkward when you're -trying to debug that target firmware. Even if there's a ROM -bootloader which handles a few issues, it rarely provides full -access to all board-specific capabilities. - - -@node Config File Guidelines -@chapter Config File Guidelines - -This chapter is aimed at any user who needs to write a config file, -including developers and integrators of OpenOCD and any user who -needs to get a new board working smoothly. -It provides guidelines for creating those files. - -You should find the following directories under -@t{$(INSTALLDIR)/scripts}, with config files maintained upstream. Use -them as-is where you can; or as models for new files. -@itemize @bullet -@item @file{interface} ... -These are for debug adapters. Files that specify configuration to use -specific JTAG, SWD and other adapters go here. -@item @file{board} ... -Think Circuit Board, PWA, PCB, they go by many names. Board files -contain initialization items that are specific to a board. - -They reuse target configuration files, since the same -microprocessor chips are used on many boards, -but support for external parts varies widely. For -example, the SDRAM initialization sequence for the board, or the type -of external flash and what address it uses. Any initialization -sequence to enable that external flash or SDRAM should be found in the -board file. Boards may also contain multiple targets: two CPUs; or -a CPU and an FPGA. -@item @file{target} ... -Think chip. The ``target'' directory represents the JTAG TAPs -on a chip -which OpenOCD should control, not a board. Two common types of targets -are ARM chips and FPGA or CPLD chips. -When a chip has multiple TAPs (maybe it has both ARM and DSP cores), -the target config file defines all of them. -@item @emph{more} ... browse for other library files which may be useful. -For example, there are various generic and CPU-specific utilities. -@end itemize - -The @file{openocd.cfg} user config -file may override features in any of the above files by -setting variables before sourcing the target file, or by adding -commands specific to their situation. - -@section Interface Config Files - -The user config file -should be able to source one of these files with a command like this: - -@example -source [find interface/FOOBAR.cfg] -@end example - -A preconfigured interface file should exist for every debug adapter -in use today with OpenOCD. -That said, perhaps some of these config files -have only been used by the developer who created it. - -A separate chapter gives information about how to set these up. -@xref{Debug Adapter Configuration}. -Read the OpenOCD source code (and Developer's Guide) -if you have a new kind of hardware interface -and need to provide a driver for it. - -@section Board Config Files -@cindex config file, board -@cindex board config file - -The user config file -should be able to source one of these files with a command like this: - -@example -source [find board/FOOBAR.cfg] -@end example - -The point of a board config file is to package everything -about a given board that user config files need to know. -In summary the board files should contain (if present) - -@enumerate -@item One or more @command{source [find target/...cfg]} statements -@item NOR flash configuration (@pxref{norconfiguration,,NOR Configuration}) -@item NAND flash configuration (@pxref{nandconfiguration,,NAND Configuration}) -@item Target @code{reset} handlers for SDRAM and I/O configuration -@item JTAG adapter reset configuration (@pxref{Reset Configuration}) -@item All things that are not ``inside a chip'' -@end enumerate - -Generic things inside target chips belong in target config files, -not board config files. So for example a @code{reset-init} event -handler should know board-specific oscillator and PLL parameters, -which it passes to target-specific utility code. - -The most complex task of a board config file is creating such a -@code{reset-init} event handler. -Define those handlers last, after you verify the rest of the board -configuration works. - -@subsection Communication Between Config files - -In addition to target-specific utility code, another way that -board and target config files communicate is by following a -convention on how to use certain variables. - -The full Tcl/Tk language supports ``namespaces'', but Jim-Tcl does not. -Thus the rule we follow in OpenOCD is this: Variables that begin with -a leading underscore are temporary in nature, and can be modified and -used at will within a target configuration file. - -Complex board config files can do the things like this, -for a board with three chips: - -@example -# Chip #1: PXA270 for network side, big endian -set CHIPNAME network -set ENDIAN big -source [find target/pxa270.cfg] -# on return: _TARGETNAME = network.cpu -# other commands can refer to the "network.cpu" target. -$_TARGETNAME configure .... events for this CPU.. - -# Chip #2: PXA270 for video side, little endian -set CHIPNAME video -set ENDIAN little -source [find target/pxa270.cfg] -# on return: _TARGETNAME = video.cpu -# other commands can refer to the "video.cpu" target. -$_TARGETNAME configure .... events for this CPU.. - -# Chip #3: Xilinx FPGA for glue logic -set CHIPNAME xilinx -unset ENDIAN -source [find target/spartan3.cfg] -@end example - -That example is oversimplified because it doesn't show any flash memory, -or the @code{reset-init} event handlers to initialize external DRAM -or (assuming it needs it) load a configuration into the FPGA. -Such features are usually needed for low-level work with many boards, -where ``low level'' implies that the board initialization software may -not be working. (That's a common reason to need JTAG tools. Another -is to enable working with microcontroller-based systems, which often -have no debugging support except a JTAG connector.) - -Target config files may also export utility functions to board and user -config files. Such functions should use name prefixes, to help avoid -naming collisions. - -Board files could also accept input variables from user config files. -For example, there might be a @code{J4_JUMPER} setting used to identify -what kind of flash memory a development board is using, or how to set -up other clocks and peripherals. - -@subsection Variable Naming Convention -@cindex variable names - -Most boards have only one instance of a chip. -However, it should be easy to create a board with more than -one such chip (as shown above). -Accordingly, we encourage these conventions for naming -variables associated with different @file{target.cfg} files, -to promote consistency and -so that board files can override target defaults. - -Inputs to target config files include: - -@itemize @bullet -@item @code{CHIPNAME} ... -This gives a name to the overall chip, and is used as part of -tap identifier dotted names. -While the default is normally provided by the chip manufacturer, -board files may need to distinguish between instances of a chip. -@item @code{ENDIAN} ... -By default @option{little} - although chips may hard-wire @option{big}. -Chips that can't change endianness don't need to use this variable. -@item @code{CPUTAPID} ... -When OpenOCD examines the JTAG chain, it can be told verify the -chips against the JTAG IDCODE register. -The target file will hold one or more defaults, but sometimes the -chip in a board will use a different ID (perhaps a newer revision). -@end itemize - -Outputs from target config files include: - -@itemize @bullet -@item @code{_TARGETNAME} ... -By convention, this variable is created by the target configuration -script. The board configuration file may make use of this variable to -configure things like a ``reset init'' script, or other things -specific to that board and that target. -If the chip has 2 targets, the names are @code{_TARGETNAME0}, -@code{_TARGETNAME1}, ... etc. -@end itemize - -@subsection The reset-init Event Handler -@cindex event, reset-init -@cindex reset-init handler - -Board config files run in the OpenOCD configuration stage; -they can't use TAPs or targets, since they haven't been -fully set up yet. -This means you can't write memory or access chip registers; -you can't even verify that a flash chip is present. -That's done later in event handlers, of which the target @code{reset-init} -handler is one of the most important. - -Except on microcontrollers, the basic job of @code{reset-init} event -handlers is setting up flash and DRAM, as normally handled by boot loaders. -Microcontrollers rarely use boot loaders; they run right out of their -on-chip flash and SRAM memory. But they may want to use one of these -handlers too, if just for developer convenience. - -@quotation Note -Because this is so very board-specific, and chip-specific, no examples -are included here. -Instead, look at the board config files distributed with OpenOCD. -If you have a boot loader, its source code will help; so will -configuration files for other JTAG tools -(@pxref{translatingconfigurationfiles,,Translating Configuration Files}). -@end quotation - -Some of this code could probably be shared between different boards. -For example, setting up a DRAM controller often doesn't differ by -much except the bus width (16 bits or 32?) and memory timings, so a -reusable TCL procedure loaded by the @file{target.cfg} file might take -those as parameters. -Similarly with oscillator, PLL, and clock setup; -and disabling the watchdog. -Structure the code cleanly, and provide comments to help -the next developer doing such work. -(@emph{You might be that next person} trying to reuse init code!) - -The last thing normally done in a @code{reset-init} handler is probing -whatever flash memory was configured. For most chips that needs to be -done while the associated target is halted, either because JTAG memory -access uses the CPU or to prevent conflicting CPU access. - -@subsection JTAG Clock Rate - -Before your @code{reset-init} handler has set up -the PLLs and clocking, you may need to run with -a low JTAG clock rate. -@xref{jtagspeed,,JTAG Speed}. -Then you'd increase that rate after your handler has -made it possible to use the faster JTAG clock. -When the initial low speed is board-specific, for example -because it depends on a board-specific oscillator speed, then -you should probably set it up in the board config file; -if it's target-specific, it belongs in the target config file. - -For most ARM-based processors the fastest JTAG clock@footnote{A FAQ -@uref{http://www.arm.com/support/faqdev/4170.html} gives details.} -is one sixth of the CPU clock; or one eighth for ARM11 cores. -Consult chip documentation to determine the peak JTAG clock rate, -which might be less than that. - -@quotation Warning -On most ARMs, JTAG clock detection is coupled to the core clock, so -software using a @option{wait for interrupt} operation blocks JTAG access. -Adaptive clocking provides a partial workaround, but a more complete -solution just avoids using that instruction with JTAG debuggers. -@end quotation - -If both the chip and the board support adaptive clocking, -use the @command{jtag_rclk} -command, in case your board is used with JTAG adapter which -also supports it. Otherwise use @command{adapter_khz}. -Set the slow rate at the beginning of the reset sequence, -and the faster rate as soon as the clocks are at full speed. - -@anchor{theinitboardprocedure} -@subsection The init_board procedure -@cindex init_board procedure - -The concept of @code{init_board} procedure is very similar to @code{init_targets} -(@xref{theinittargetsprocedure,,The init_targets procedure}.) - it's a replacement of ``linear'' -configuration scripts. This procedure is meant to be executed when OpenOCD enters run stage -(@xref{enteringtherunstage,,Entering the Run Stage},) after @code{init_targets}. The idea to have -separate @code{init_targets} and @code{init_board} procedures is to allow the first one to configure -everything target specific (internal flash, internal RAM, etc.) and the second one to configure -everything board specific (reset signals, chip frequency, reset-init event handler, external memory, etc.). -Additionally ``linear'' board config file will most likely fail when target config file uses -@code{init_targets} scheme (``linear'' script is executed before @code{init} and @code{init_targets} - after), -so separating these two configuration stages is very convenient, as the easiest way to overcome this -problem is to convert board config file to use @code{init_board} procedure. Board config scripts don't -need to override @code{init_targets} defined in target config files when they only need to add some specifics. - -Just as @code{init_targets}, the @code{init_board} procedure can be overridden by ``next level'' script (which sources -the original), allowing greater code reuse. - -@example -### board_file.cfg ### - -# source target file that does most of the config in init_targets -source [find target/target.cfg] - -proc enable_fast_clock @{@} @{ - # enables fast on-board clock source - # configures the chip to use it -@} - -# initialize only board specifics - reset, clock, adapter frequency -proc init_board @{@} @{ - reset_config trst_and_srst trst_pulls_srst - - $_TARGETNAME configure -event reset-init @{ - adapter_khz 1 - enable_fast_clock - adapter_khz 10000 - @} -@} -@end example - -@section Target Config Files -@cindex config file, target -@cindex target config file - -Board config files communicate with target config files using -naming conventions as described above, and may source one or -more target config files like this: - -@example -source [find target/FOOBAR.cfg] -@end example - -The point of a target config file is to package everything -about a given chip that board config files need to know. -In summary the target files should contain - -@enumerate -@item Set defaults -@item Add TAPs to the scan chain -@item Add CPU targets (includes GDB support) -@item CPU/Chip/CPU-Core specific features -@item On-Chip flash -@end enumerate - -As a rule of thumb, a target file sets up only one chip. -For a microcontroller, that will often include a single TAP, -which is a CPU needing a GDB target, and its on-chip flash. - -More complex chips may include multiple TAPs, and the target -config file may need to define them all before OpenOCD -can talk to the chip. -For example, some phone chips have JTAG scan chains that include -an ARM core for operating system use, a DSP, -another ARM core embedded in an image processing engine, -and other processing engines. - -@subsection Default Value Boiler Plate Code - -All target configuration files should start with code like this, -letting board config files express environment-specific -differences in how things should be set up. - -@example -# Boards may override chip names, perhaps based on role, -# but the default should match what the vendor uses -if @{ [info exists CHIPNAME] @} @{ - set _CHIPNAME $CHIPNAME -@} else @{ - set _CHIPNAME sam7x256 -@} - -# ONLY use ENDIAN with targets that can change it. -if @{ [info exists ENDIAN] @} @{ - set _ENDIAN $ENDIAN -@} else @{ - set _ENDIAN little -@} - -# TAP identifiers may change as chips mature, for example with -# new revision fields (the "3" here). Pick a good default; you -# can pass several such identifiers to the "jtag newtap" command. -if @{ [info exists CPUTAPID ] @} @{ - set _CPUTAPID $CPUTAPID -@} else @{ - set _CPUTAPID 0x3f0f0f0f -@} -@end example -@c but 0x3f0f0f0f is for an str73x part ... - -@emph{Remember:} Board config files may include multiple target -config files, or the same target file multiple times -(changing at least @code{CHIPNAME}). - -Likewise, the target configuration file should define -@code{_TARGETNAME} (or @code{_TARGETNAME0} etc) and -use it later on when defining debug targets: - -@example -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME arm7tdmi -chain-position $_TARGETNAME -@end example - -@subsection Adding TAPs to the Scan Chain -After the ``defaults'' are set up, -add the TAPs on each chip to the JTAG scan chain. -@xref{TAP Declaration}, and the naming convention -for taps. - -In the simplest case the chip has only one TAP, -probably for a CPU or FPGA. -The config file for the Atmel AT91SAM7X256 -looks (in part) like this: - -@example -jtag newtap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID -@end example - -A board with two such at91sam7 chips would be able -to source such a config file twice, with different -values for @code{CHIPNAME}, so -it adds a different TAP each time. - -If there are nonzero @option{-expected-id} values, -OpenOCD attempts to verify the actual tap id against those values. -It will issue error messages if there is mismatch, which -can help to pinpoint problems in OpenOCD configurations. - -@example -JTAG tap: sam7x256.cpu tap/device found: 0x3f0f0f0f - (Manufacturer: 0x787, Part: 0xf0f0, Version: 0x3) -ERROR: Tap: sam7x256.cpu - Expected id: 0x12345678, Got: 0x3f0f0f0f -ERROR: expected: mfg: 0x33c, part: 0x2345, ver: 0x1 -ERROR: got: mfg: 0x787, part: 0xf0f0, ver: 0x3 -@end example - -There are more complex examples too, with chips that have -multiple TAPs. Ones worth looking at include: - -@itemize -@item @file{target/omap3530.cfg} -- with disabled ARM and DSP, -plus a JRC to enable them -@item @file{target/str912.cfg} -- with flash, CPU, and boundary scan -@item @file{target/ti_dm355.cfg} -- with ETM, ARM, and JRC (this JRC -is not currently used) -@end itemize - -@subsection Add CPU targets - -After adding a TAP for a CPU, you should set it up so that -GDB and other commands can use it. -@xref{CPU Configuration}. -For the at91sam7 example above, the command can look like this; -note that @code{$_ENDIAN} is not needed, since OpenOCD defaults -to little endian, and this chip doesn't support changing that. - -@example -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME arm7tdmi -chain-position $_TARGETNAME -@end example - -Work areas are small RAM areas associated with CPU targets. -They are used by OpenOCD to speed up downloads, -and to download small snippets of code to program flash chips. -If the chip includes a form of ``on-chip-ram'' - and many do - define -a work area if you can. -Again using the at91sam7 as an example, this can look like: - -@example -$_TARGETNAME configure -work-area-phys 0x00200000 \ - -work-area-size 0x4000 -work-area-backup 0 -@end example - -@anchor{definecputargetsworkinginsmp} -@subsection Define CPU targets working in SMP -@cindex SMP -After setting targets, you can define a list of targets working in SMP. - -@example -set _TARGETNAME_1 $_CHIPNAME.cpu1 -set _TARGETNAME_2 $_CHIPNAME.cpu2 -target create $_TARGETNAME_1 cortex_a -chain-position $_CHIPNAME.dap \ --coreid 0 -dbgbase $_DAP_DBG1 -target create $_TARGETNAME_2 cortex_a -chain-position $_CHIPNAME.dap \ --coreid 1 -dbgbase $_DAP_DBG2 -#define 2 targets working in smp. -target smp $_CHIPNAME.cpu2 $_CHIPNAME.cpu1 -@end example -In the above example on cortex_a, 2 cpus are working in SMP. -In SMP only one GDB instance is created and : -@itemize @bullet -@item a set of hardware breakpoint sets the same breakpoint on all targets in the list. -@item halt command triggers the halt of all targets in the list. -@item resume command triggers the write context and the restart of all targets in the list. -@item following a breakpoint: the target stopped by the breakpoint is displayed to the GDB session. -@item dedicated GDB serial protocol packets are implemented for switching/retrieving the target -displayed by the GDB session @pxref{usingopenocdsmpwithgdb,,Using OpenOCD SMP with GDB}. -@end itemize - -The SMP behaviour can be disabled/enabled dynamically. On cortex_a following -command have been implemented. -@itemize @bullet -@item cortex_a smp_on : enable SMP mode, behaviour is as described above. -@item cortex_a smp_off : disable SMP mode, the current target is the one -displayed in the GDB session, only this target is now controlled by GDB -session. This behaviour is useful during system boot up. -@item cortex_a smp_gdb : display/fix the core id displayed in GDB session see -following example. -@end itemize - -@example ->cortex_a smp_gdb -gdb coreid 0 -> -1 -#0 : coreid 0 is displayed to GDB , -#-> -1 : next resume triggers a real resume -> cortex_a smp_gdb 1 -gdb coreid 0 -> 1 -#0 :coreid 0 is displayed to GDB , -#->1 : next resume displays coreid 1 to GDB -> resume -> cortex_a smp_gdb -gdb coreid 1 -> 1 -#1 :coreid 1 is displayed to GDB , -#->1 : next resume displays coreid 1 to GDB -> cortex_a smp_gdb -1 -gdb coreid 1 -> -1 -#1 :coreid 1 is displayed to GDB, -#->-1 : next resume triggers a real resume -@end example - - -@subsection Chip Reset Setup - -As a rule, you should put the @command{reset_config} command -into the board file. Most things you think you know about a -chip can be tweaked by the board. - -Some chips have specific ways the TRST and SRST signals are -managed. In the unusual case that these are @emph{chip specific} -and can never be changed by board wiring, they could go here. -For example, some chips can't support JTAG debugging without -both signals. - -Provide a @code{reset-assert} event handler if you can. -Such a handler uses JTAG operations to reset the target, -letting this target config be used in systems which don't -provide the optional SRST signal, or on systems where you -don't want to reset all targets at once. -Such a handler might write to chip registers to force a reset, -use a JRC to do that (preferable -- the target may be wedged!), -or force a watchdog timer to trigger. -(For Cortex-M targets, this is not necessary. The target -driver knows how to use trigger an NVIC reset when SRST is -not available.) - -Some chips need special attention during reset handling if -they're going to be used with JTAG. -An example might be needing to send some commands right -after the target's TAP has been reset, providing a -@code{reset-deassert-post} event handler that writes a chip -register to report that JTAG debugging is being done. -Another would be reconfiguring the watchdog so that it stops -counting while the core is halted in the debugger. - -JTAG clocking constraints often change during reset, and in -some cases target config files (rather than board config files) -are the right places to handle some of those issues. -For example, immediately after reset most chips run using a -slower clock than they will use later. -That means that after reset (and potentially, as OpenOCD -first starts up) they must use a slower JTAG clock rate -than they will use later. -@xref{jtagspeed,,JTAG Speed}. - -@quotation Important -When you are debugging code that runs right after chip -reset, getting these issues right is critical. -In particular, if you see intermittent failures when -OpenOCD verifies the scan chain after reset, -look at how you are setting up JTAG clocking. -@end quotation - -@anchor{theinittargetsprocedure} -@subsection The init_targets procedure -@cindex init_targets procedure - -Target config files can either be ``linear'' (script executed line-by-line when parsed in -configuration stage, @xref{configurationstage,,Configuration Stage},) or they can contain a special -procedure called @code{init_targets}, which will be executed when entering run stage -(after parsing all config files or after @code{init} command, @xref{enteringtherunstage,,Entering the Run Stage}.) -Such procedure can be overriden by ``next level'' script (which sources the original). -This concept faciliates code reuse when basic target config files provide generic configuration -procedures and @code{init_targets} procedure, which can then be sourced and enchanced or changed in -a ``more specific'' target config file. This is not possible with ``linear'' config scripts, -because sourcing them executes every initialization commands they provide. - -@example -### generic_file.cfg ### - -proc setup_my_chip @{chip_name flash_size ram_size@} @{ - # basic initialization procedure ... -@} - -proc init_targets @{@} @{ - # initializes generic chip with 4kB of flash and 1kB of RAM - setup_my_chip MY_GENERIC_CHIP 4096 1024 -@} - -### specific_file.cfg ### - -source [find target/generic_file.cfg] - -proc init_targets @{@} @{ - # initializes specific chip with 128kB of flash and 64kB of RAM - setup_my_chip MY_CHIP_WITH_128K_FLASH_64KB_RAM 131072 65536 -@} -@end example - -The easiest way to convert ``linear'' config files to @code{init_targets} version is to -enclose every line of ``code'' (i.e. not @code{source} commands, procedures, etc.) in this procedure. - -For an example of this scheme see LPC2000 target config files. - -The @code{init_boards} procedure is a similar concept concerning board config files -(@xref{theinitboardprocedure,,The init_board procedure}.) - -@anchor{theinittargeteventsprocedure} -@subsection The init_target_events procedure -@cindex init_target_events procedure - -A special procedure called @code{init_target_events} is run just after -@code{init_targets} (@xref{theinittargetsprocedure,,The init_targets -procedure}.) and before @code{init_board} -(@xref{theinitboardprocedure,,The init_board procedure}.) It is used -to set up default target events for the targets that do not have those -events already assigned. - -@subsection ARM Core Specific Hacks - -If the chip has a DCC, enable it. If the chip is an ARM9 with some -special high speed download features - enable it. - -If present, the MMU, the MPU and the CACHE should be disabled. - -Some ARM cores are equipped with trace support, which permits -examination of the instruction and data bus activity. Trace -activity is controlled through an ``Embedded Trace Module'' (ETM) -on one of the core's scan chains. The ETM emits voluminous data -through a ``trace port''. (@xref{armhardwaretracing,,ARM Hardware Tracing}.) -If you are using an external trace port, -configure it in your board config file. -If you are using an on-chip ``Embedded Trace Buffer'' (ETB), -configure it in your target config file. - -@example -etm config $_TARGETNAME 16 normal full etb -etb config $_TARGETNAME $_CHIPNAME.etb -@end example - -@subsection Internal Flash Configuration - -This applies @b{ONLY TO MICROCONTROLLERS} that have flash built in. - -@b{Never ever} in the ``target configuration file'' define any type of -flash that is external to the chip. (For example a BOOT flash on -Chip Select 0.) Such flash information goes in a board file - not -the TARGET (chip) file. - -Examples: -@itemize @bullet -@item at91sam7x256 - has 256K flash YES enable it. -@item str912 - has flash internal YES enable it. -@item imx27 - uses boot flash on CS0 - it goes in the board file. -@item pxa270 - again - CS0 flash - it goes in the board file. -@end itemize - -@anchor{translatingconfigurationfiles} -@section Translating Configuration Files -@cindex translation -If you have a configuration file for another hardware debugger -or toolset (Abatron, BDI2000, BDI3000, CCS, -Lauterbach, SEGGER, Macraigor, etc.), translating -it into OpenOCD syntax is often quite straightforward. The most tricky -part of creating a configuration script is oftentimes the reset init -sequence where e.g. PLLs, DRAM and the like is set up. - -One trick that you can use when translating is to write small -Tcl procedures to translate the syntax into OpenOCD syntax. This -can avoid manual translation errors and make it easier to -convert other scripts later on. - -Example of transforming quirky arguments to a simple search and -replace job: - -@example -# Lauterbach syntax(?) -# -# Data.Set c15:0x042f %long 0x40000015 -# -# OpenOCD syntax when using procedure below. -# -# setc15 0x01 0x00050078 - -proc setc15 @{regs value@} @{ - global TARGETNAME - - echo [format "set p15 0x%04x, 0x%08x" $regs $value] - - arm mcr 15 [expr ($regs>>12)&0x7] \ - [expr ($regs>>0)&0xf] [expr ($regs>>4)&0xf] \ - [expr ($regs>>8)&0x7] $value -@} -@end example - - - -@node Daemon Configuration -@chapter Daemon Configuration -@cindex initialization -The commands here are commonly found in the openocd.cfg file and are -used to specify what TCP/IP ports are used, and how GDB should be -supported. - -@anchor{configurationstage} -@section Configuration Stage -@cindex configuration stage -@cindex config command - -When the OpenOCD server process starts up, it enters a -@emph{configuration stage} which is the only time that -certain commands, @emph{configuration commands}, may be issued. -Normally, configuration commands are only available -inside startup scripts. - -In this manual, the definition of a configuration command is -presented as a @emph{Config Command}, not as a @emph{Command} -which may be issued interactively. -The runtime @command{help} command also highlights configuration -commands, and those which may be issued at any time. - -Those configuration commands include declaration of TAPs, -flash banks, -the interface used for JTAG communication, -and other basic setup. -The server must leave the configuration stage before it -may access or activate TAPs. -After it leaves this stage, configuration commands may no -longer be issued. - -@anchor{enteringtherunstage} -@section Entering the Run Stage - -The first thing OpenOCD does after leaving the configuration -stage is to verify that it can talk to the scan chain -(list of TAPs) which has been configured. -It will warn if it doesn't find TAPs it expects to find, -or finds TAPs that aren't supposed to be there. -You should see no errors at this point. -If you see errors, resolve them by correcting the -commands you used to configure the server. -Common errors include using an initial JTAG speed that's too -fast, and not providing the right IDCODE values for the TAPs -on the scan chain. - -Once OpenOCD has entered the run stage, a number of commands -become available. -A number of these relate to the debug targets you may have declared. -For example, the @command{mww} command will not be available until -a target has been successfuly instantiated. -If you want to use those commands, you may need to force -entry to the run stage. - -@deffn {Config Command} init -This command terminates the configuration stage and -enters the run stage. This helps when you need to have -the startup scripts manage tasks such as resetting the target, -programming flash, etc. To reset the CPU upon startup, add "init" and -"reset" at the end of the config script or at the end of the OpenOCD -command line using the @option{-c} command line switch. - -If this command does not appear in any startup/configuration file -OpenOCD executes the command for you after processing all -configuration files and/or command line options. - -@b{NOTE:} This command normally occurs at or near the end of your -openocd.cfg file to force OpenOCD to ``initialize'' and make the -targets ready. For example: If your openocd.cfg file needs to -read/write memory on your target, @command{init} must occur before -the memory read/write commands. This includes @command{nand probe}. -@end deffn - -@deffn {Overridable Procedure} jtag_init -This is invoked at server startup to verify that it can talk -to the scan chain (list of TAPs) which has been configured. - -The default implementation first tries @command{jtag arp_init}, -which uses only a lightweight JTAG reset before examining the -scan chain. -If that fails, it tries again, using a harder reset -from the overridable procedure @command{init_reset}. - -Implementations must have verified the JTAG scan chain before -they return. -This is done by calling @command{jtag arp_init} -(or @command{jtag arp_init-reset}). -@end deffn - -@anchor{tcpipports} -@section TCP/IP Ports -@cindex TCP port -@cindex server -@cindex port -@cindex security -The OpenOCD server accepts remote commands in several syntaxes. -Each syntax uses a different TCP/IP port, which you may specify -only during configuration (before those ports are opened). - -For reasons including security, you may wish to prevent remote -access using one or more of these ports. -In such cases, just specify the relevant port number as "disabled". -If you disable all access through TCP/IP, you will need to -use the command line @option{-pipe} option. - -@deffn {Command} gdb_port [number] -@cindex GDB server -Normally gdb listens to a TCP/IP port, but GDB can also -communicate via pipes(stdin/out or named pipes). The name -"gdb_port" stuck because it covers probably more than 90% of -the normal use cases. - -No arguments reports GDB port. "pipe" means listen to stdin -output to stdout, an integer is base port number, "disable" -disables the gdb server. - -When using "pipe", also use log_output to redirect the log -output to a file so as not to flood the stdin/out pipes. - -The -p/--pipe option is deprecated and a warning is printed -as it is equivalent to passing in -c "gdb_port pipe; log_output openocd.log". - -Any other string is interpreted as named pipe to listen to. -Output pipe is the same name as input pipe, but with 'o' appended, -e.g. /var/gdb, /var/gdbo. - -The GDB port for the first target will be the base port, the -second target will listen on gdb_port + 1, and so on. -When not specified during the configuration stage, -the port @var{number} defaults to 3333. - -Note: when using "gdb_port pipe", increasing the default remote timeout in -gdb (with 'set remotetimeout') is recommended. An insufficient timeout may -cause initialization to fail with "Unknown remote qXfer reply: OK". - -@end deffn - -@deffn {Command} tcl_port [number] -Specify or query the port used for a simplified RPC -connection that can be used by clients to issue TCL commands and get the -output from the Tcl engine. -Intended as a machine interface. -When not specified during the configuration stage, -the port @var{number} defaults to 6666. -When specified as "disabled", this service is not activated. -@end deffn - -@deffn {Command} telnet_port [number] -Specify or query the -port on which to listen for incoming telnet connections. -This port is intended for interaction with one human through TCL commands. -When not specified during the configuration stage, -the port @var{number} defaults to 4444. -When specified as "disabled", this service is not activated. -@end deffn - -@anchor{gdbconfiguration} -@section GDB Configuration -@cindex GDB -@cindex GDB configuration -You can reconfigure some GDB behaviors if needed. -The ones listed here are static and global. -@xref{targetconfiguration,,Target Configuration}, about configuring individual targets. -@xref{targetevents,,Target Events}, about configuring target-specific event handling. - -@anchor{gdbbreakpointoverride} -@deffn {Command} gdb_breakpoint_override [@option{hard}|@option{soft}|@option{disable}] -Force breakpoint type for gdb @command{break} commands. -This option supports GDB GUIs which don't -distinguish hard versus soft breakpoints, if the default OpenOCD and -GDB behaviour is not sufficient. GDB normally uses hardware -breakpoints if the memory map has been set up for flash regions. -@end deffn - -@anchor{gdbflashprogram} -@deffn {Config Command} gdb_flash_program (@option{enable}|@option{disable}) -Set to @option{enable} to cause OpenOCD to program the flash memory when a -vFlash packet is received. -The default behaviour is @option{enable}. -@end deffn - -@deffn {Config Command} gdb_memory_map (@option{enable}|@option{disable}) -Set to @option{enable} to cause OpenOCD to send the memory configuration to GDB when -requested. GDB will then know when to set hardware breakpoints, and program flash -using the GDB load command. @command{gdb_flash_program enable} must also be enabled -for flash programming to work. -Default behaviour is @option{enable}. -@xref{gdbflashprogram,,gdb_flash_program}. -@end deffn - -@deffn {Config Command} gdb_report_data_abort (@option{enable}|@option{disable}) -Specifies whether data aborts cause an error to be reported -by GDB memory read packets. -The default behaviour is @option{disable}; -use @option{enable} see these errors reported. -@end deffn - -@deffn {Config Command} gdb_target_description (@option{enable}|@option{disable}) -Set to @option{enable} to cause OpenOCD to send the target descriptions to gdb via qXfer:features:read packet. -The default behaviour is @option{enable}. -@end deffn - -@deffn {Command} gdb_save_tdesc -Saves the target descripton file to the local file system. - -The file name is @i{target_name}.xml. -@end deffn - -@anchor{eventpolling} -@section Event Polling - -Hardware debuggers are parts of asynchronous systems, -where significant events can happen at any time. -The OpenOCD server needs to detect some of these events, -so it can report them to through TCL command line -or to GDB. - -Examples of such events include: - -@itemize -@item One of the targets can stop running ... maybe it triggers -a code breakpoint or data watchpoint, or halts itself. -@item Messages may be sent over ``debug message'' channels ... many -targets support such messages sent over JTAG, -for receipt by the person debugging or tools. -@item Loss of power ... some adapters can detect these events. -@item Resets not issued through JTAG ... such reset sources -can include button presses or other system hardware, sometimes -including the target itself (perhaps through a watchdog). -@item Debug instrumentation sometimes supports event triggering -such as ``trace buffer full'' (so it can quickly be emptied) -or other signals (to correlate with code behavior). -@end itemize - -None of those events are signaled through standard JTAG signals. -However, most conventions for JTAG connectors include voltage -level and system reset (SRST) signal detection. -Some connectors also include instrumentation signals, which -can imply events when those signals are inputs. - -In general, OpenOCD needs to periodically check for those events, -either by looking at the status of signals on the JTAG connector -or by sending synchronous ``tell me your status'' JTAG requests -to the various active targets. -There is a command to manage and monitor that polling, -which is normally done in the background. - -@deffn Command poll [@option{on}|@option{off}] -Poll the current target for its current state. -(Also, @pxref{targetcurstate,,target curstate}.) -If that target is in debug mode, architecture -specific information about the current state is printed. -An optional parameter -allows background polling to be enabled and disabled. - -You could use this from the TCL command shell, or -from GDB using @command{monitor poll} command. -Leave background polling enabled while you're using GDB. -@example -> poll -background polling: on -target state: halted -target halted in ARM state due to debug-request, \ - current mode: Supervisor -cpsr: 0x800000d3 pc: 0x11081bfc -MMU: disabled, D-Cache: disabled, I-Cache: enabled -> -@end example -@end deffn - -@node Debug Adapter Configuration -@chapter Debug Adapter Configuration -@cindex config file, interface -@cindex interface config file - -Correctly installing OpenOCD includes making your operating system give -OpenOCD access to debug adapters. Once that has been done, Tcl commands -are used to select which one is used, and to configure how it is used. - -@quotation Note -Because OpenOCD started out with a focus purely on JTAG, you may find -places where it wrongly presumes JTAG is the only transport protocol -in use. Be aware that recent versions of OpenOCD are removing that -limitation. JTAG remains more functional than most other transports. -Other transports do not support boundary scan operations, or may be -specific to a given chip vendor. Some might be usable only for -programming flash memory, instead of also for debugging. -@end quotation - -Debug Adapters/Interfaces/Dongles are normally configured -through commands in an interface configuration -file which is sourced by your @file{openocd.cfg} file, or -through a command line @option{-f interface/....cfg} option. - -@example -source [find interface/olimex-jtag-tiny.cfg] -@end example - -These commands tell -OpenOCD what type of JTAG adapter you have, and how to talk to it. -A few cases are so simple that you only need to say what driver to use: - -@example -# jlink interface -interface jlink -@end example - -Most adapters need a bit more configuration than that. - - -@section Interface Configuration - -The interface command tells OpenOCD what type of debug adapter you are -using. Depending on the type of adapter, you may need to use one or -more additional commands to further identify or configure the adapter. - -@deffn {Config Command} {interface} name -Use the interface driver @var{name} to connect to the -target. -@end deffn - -@deffn Command {interface_list} -List the debug adapter drivers that have been built into -the running copy of OpenOCD. -@end deffn -@deffn Command {interface transports} transport_name+ -Specifies the transports supported by this debug adapter. -The adapter driver builds-in similar knowledge; use this only -when external configuration (such as jumpering) changes what -the hardware can support. -@end deffn - - - -@deffn Command {adapter_name} -Returns the name of the debug adapter driver being used. -@end deffn - -@section Interface Drivers - -Each of the interface drivers listed here must be explicitly -enabled when OpenOCD is configured, in order to be made -available at run time. - -@deffn {Interface Driver} {amt_jtagaccel} -Amontec Chameleon in its JTAG Accelerator configuration, -connected to a PC's EPP mode parallel port. -This defines some driver-specific commands: - -@deffn {Config Command} {parport_port} number -Specifies either the address of the I/O port (default: 0x378 for LPT1) or -the number of the @file{/dev/parport} device. -@end deffn - -@deffn {Config Command} rtck [@option{enable}|@option{disable}] -Displays status of RTCK option. -Optionally sets that option first. -@end deffn -@end deffn - -@deffn {Interface Driver} {arm-jtag-ew} -Olimex ARM-JTAG-EW USB adapter -This has one driver-specific command: - -@deffn Command {armjtagew_info} -Logs some status -@end deffn -@end deffn - -@deffn {Interface Driver} {at91rm9200} -Supports bitbanged JTAG from the local system, -presuming that system is an Atmel AT91rm9200 -and a specific set of GPIOs is used. -@c command: at91rm9200_device NAME -@c chooses among list of bit configs ... only one option -@end deffn - -@deffn {Interface Driver} {cmsis-dap} -ARM CMSIS-DAP compliant based adapter. - -@deffn {Config Command} {cmsis_dap_vid_pid} [vid pid]+ -The vendor ID and product ID of the CMSIS-DAP device. If not specified -the driver will attempt to auto detect the CMSIS-DAP device. -Currently, up to eight [@var{vid}, @var{pid}] pairs may be given, e.g. -@example -cmsis_dap_vid_pid 0xc251 0xf001 0x0d28 0x0204 -@end example -@end deffn - -@deffn {Config Command} {cmsis_dap_serial} [serial] -Specifies the @var{serial} of the CMSIS-DAP device to use. -If not specified, serial numbers are not considered. -@end deffn - -@deffn {Command} {cmsis-dap info} -Display various device information, like hardware version, firmware version, current bus status. -@end deffn -@end deffn - -@deffn {Interface Driver} {dummy} -A dummy software-only driver for debugging. -@end deffn - -@deffn {Interface Driver} {ep93xx} -Cirrus Logic EP93xx based single-board computer bit-banging (in development) -@end deffn - -@deffn {Interface Driver} {ft2232} -FTDI FT2232 (USB) based devices over one of the userspace libraries. - -Note that this driver has several flaws and the @command{ftdi} driver is -recommended as its replacement. - -These interfaces have several commands, used to configure the driver -before initializing the JTAG scan chain: - -@deffn {Config Command} {ft2232_device_desc} description -Provides the USB device description (the @emph{iProduct string}) -of the FTDI FT2232 device. If not -specified, the FTDI default value is used. This setting is only valid -if compiled with FTD2XX support. -@end deffn - -@deffn {Config Command} {ft2232_serial} serial-number -Specifies the @var{serial-number} of the FTDI FT2232 device to use, -in case the vendor provides unique IDs and more than one FT2232 device -is connected to the host. -If not specified, serial numbers are not considered. -(Note that USB serial numbers can be arbitrary Unicode strings, -and are not restricted to containing only decimal digits.) -@end deffn - -@deffn {Config Command} {ft2232_layout} name -Each vendor's FT2232 device can use different GPIO signals -to control output-enables, reset signals, and LEDs. -Currently valid layout @var{name} values include: -@itemize @minus -@item @b{axm0432_jtag} Axiom AXM-0432 -@item @b{comstick} Hitex STR9 comstick -@item @b{cortino} Hitex Cortino JTAG interface -@item @b{evb_lm3s811} TI/Luminary Micro EVB_LM3S811 as a JTAG interface, -either for the local Cortex-M3 (SRST only) -or in a passthrough mode (neither SRST nor TRST) -This layout can not support the SWO trace mechanism, and should be -used only for older boards (before rev C). -@item @b{luminary_icdi} This layout should be used with most TI/Luminary -eval boards, including Rev C LM3S811 eval boards and the eponymous -ICDI boards, to debug either the local Cortex-M3 or in passthrough mode -to debug some other target. It can support the SWO trace mechanism. -@item @b{flyswatter} Tin Can Tools Flyswatter -@item @b{icebear} ICEbear JTAG adapter from Section 5 -@item @b{jtagkey} Amontec JTAGkey and JTAGkey-Tiny (and compatibles) -@item @b{jtagkey2} Amontec JTAGkey2 (and compatibles) -@item @b{m5960} American Microsystems M5960 -@item @b{olimex-jtag} Olimex ARM-USB-OCD and ARM-USB-Tiny -@item @b{oocdlink} OOCDLink -@c oocdlink ~= jtagkey_prototype_v1 -@item @b{redbee-econotag} Integrated with a Redbee development board. -@item @b{redbee-usb} Integrated with a Redbee USB-stick development board. -@item @b{sheevaplug} Marvell Sheevaplug development kit -@item @b{signalyzer} Xverve Signalyzer -@item @b{stm32stick} Hitex STM32 Performance Stick -@item @b{turtelizer2} egnite Software turtelizer2 -@item @b{usbjtag} "USBJTAG-1" layout described in the OpenOCD diploma thesis -@end itemize -@end deffn - -@deffn {Config Command} {ft2232_vid_pid} [vid pid]+ -The vendor ID and product ID of the FTDI FT2232 device. If not specified, the FTDI -default values are used. -Currently, up to eight [@var{vid}, @var{pid}] pairs may be given, e.g. -@example -ft2232_vid_pid 0x0403 0xcff8 0x15ba 0x0003 -@end example -@end deffn - -@deffn {Config Command} {ft2232_latency} ms -On some systems using FT2232 based JTAG interfaces the FT_Read function call in -ft2232_read() fails to return the expected number of bytes. This can be caused by -USB communication delays and has proved hard to reproduce and debug. Setting the -FT2232 latency timer to a larger value increases delays for short USB packets but it -also reduces the risk of timeouts before receiving the expected number of bytes. -The OpenOCD default value is 2 and for some systems a value of 10 has proved useful. -@end deffn - -@deffn {Config Command} {ft2232_channel} channel -Used to select the channel of the ft2232 chip to use (between 1 and 4). -The default value is 1. -@end deffn - -For example, the interface config file for a -Turtelizer JTAG Adapter looks something like this: - -@example -interface ft2232 -ft2232_device_desc "Turtelizer JTAG/RS232 Adapter" -ft2232_layout turtelizer2 -ft2232_vid_pid 0x0403 0xbdc8 -@end example -@end deffn - -@deffn {Interface Driver} {ftdi} -This driver is for adapters using the MPSSE (Multi-Protocol Synchronous Serial -Engine) mode built into many FTDI chips, such as the FT2232, FT4232 and FT232H. -It is a complete rewrite to address a large number of problems with the ft2232 -interface driver. - -The driver is using libusb-1.0 in asynchronous mode to talk to the FTDI device, -bypassing intermediate libraries like libftdi of D2XX. Performance-wise it is -consistently faster than the ft2232 driver, sometimes several times faster. - -A major improvement of this driver is that support for new FTDI based adapters -can be added competely through configuration files, without the need to patch -and rebuild OpenOCD. - -The driver uses a signal abstraction to enable Tcl configuration files to -define outputs for one or several FTDI GPIO. These outputs can then be -controlled using the @command{ftdi_set_signal} command. Special signal names -are reserved for nTRST, nSRST and LED (for blink) so that they, if defined, -will be used for their customary purpose. Inputs can be read using the -@command{ftdi_get_signal} command. - -Depending on the type of buffer attached to the FTDI GPIO, the outputs have to -be controlled differently. In order to support tristateable signals such as -nSRST, both a data GPIO and an output-enable GPIO can be specified for each -signal. The following output buffer configurations are supported: - -@itemize @minus -@item Push-pull with one FTDI output as (non-)inverted data line -@item Open drain with one FTDI output as (non-)inverted output-enable -@item Tristate with one FTDI output as (non-)inverted data line and another - FTDI output as (non-)inverted output-enable -@item Unbuffered, using the FTDI GPIO as a tristate output directly by - switching data and direction as necessary -@end itemize - -These interfaces have several commands, used to configure the driver -before initializing the JTAG scan chain: - -@deffn {Config Command} {ftdi_vid_pid} [vid pid]+ -The vendor ID and product ID of the adapter. If not specified, the FTDI -default values are used. -Currently, up to eight [@var{vid}, @var{pid}] pairs may be given, e.g. -@example -ftdi_vid_pid 0x0403 0xcff8 0x15ba 0x0003 -@end example -@end deffn - -@deffn {Config Command} {ftdi_device_desc} description -Provides the USB device description (the @emph{iProduct string}) -of the adapter. If not specified, the device description is ignored -during device selection. -@end deffn - -@deffn {Config Command} {ftdi_serial} serial-number -Specifies the @var{serial-number} of the adapter to use, -in case the vendor provides unique IDs and more than one adapter -is connected to the host. -If not specified, serial numbers are not considered. -(Note that USB serial numbers can be arbitrary Unicode strings, -and are not restricted to containing only decimal digits.) -@end deffn - -@deffn {Config Command} {ftdi_location} :[,]... -Specifies the physical USB port of the adapter to use. The path -roots at @var{bus} and walks down the physical ports, with each -@var{port} option specifying a deeper level in the bus topology, the last -@var{port} denoting where the target adapter is actually plugged. -The USB bus topology can be queried with the command @emph{lsusb -t}. - -This command is only available if your libusb1 is at least version 1.0.16. -@end deffn - -@deffn {Config Command} {ftdi_channel} channel -Selects the channel of the FTDI device to use for MPSSE operations. Most -adapters use the default, channel 0, but there are exceptions. -@end deffn - -@deffn {Config Command} {ftdi_layout_init} data direction -Specifies the initial values of the FTDI GPIO data and direction registers. -Each value is a 16-bit number corresponding to the concatenation of the high -and low FTDI GPIO registers. The values should be selected based on the -schematics of the adapter, such that all signals are set to safe levels with -minimal impact on the target system. Avoid floating inputs, conflicting outputs -and initially asserted reset signals. -@end deffn - -@deffn {Config Command} {ftdi_layout_signal} name [@option{-data}|@option{-ndata} data_mask] [@option{-input}|@option{-ninput} input_mask] [@option{-oe}|@option{-noe} oe_mask] [@option{-alias}|@option{-nalias} name] -Creates a signal with the specified @var{name}, controlled by one or more FTDI -GPIO pins via a range of possible buffer connections. The masks are FTDI GPIO -register bitmasks to tell the driver the connection and type of the output -buffer driving the respective signal. @var{data_mask} is the bitmask for the -pin(s) connected to the data input of the output buffer. @option{-ndata} is -used with inverting data inputs and @option{-data} with non-inverting inputs. -The @option{-oe} (or @option{-noe}) option tells where the output-enable (or -not-output-enable) input to the output buffer is connected. The options -@option{-input} and @option{-ninput} specify the bitmask for pins to be read -with the method @command{ftdi_get_signal}. - -Both @var{data_mask} and @var{oe_mask} need not be specified. For example, a -simple open-collector transistor driver would be specified with @option{-oe} -only. In that case the signal can only be set to drive low or to Hi-Z and the -driver will complain if the signal is set to drive high. Which means that if -it's a reset signal, @command{reset_config} must be specified as -@option{srst_open_drain}, not @option{srst_push_pull}. - -A special case is provided when @option{-data} and @option{-oe} is set to the -same bitmask. Then the FTDI pin is considered being connected straight to the -target without any buffer. The FTDI pin is then switched between output and -input as necessary to provide the full set of low, high and Hi-Z -characteristics. In all other cases, the pins specified in a signal definition -are always driven by the FTDI. - -If @option{-alias} or @option{-nalias} is used, the signal is created -identical (or with data inverted) to an already specified signal -@var{name}. -@end deffn - -@deffn {Command} {ftdi_set_signal} name @option{0}|@option{1}|@option{z} -Set a previously defined signal to the specified level. -@itemize @minus -@item @option{0}, drive low -@item @option{1}, drive high -@item @option{z}, set to high-impedance -@end itemize -@end deffn - -@deffn {Command} {ftdi_get_signal} name -Get the value of a previously defined signal. -@end deffn - -@deffn {Command} {ftdi_tdo_sample_edge} @option{rising}|@option{falling} -Configure TCK edge at which the adapter samples the value of the TDO signal - -Due to signal propagation delays, sampling TDO on rising TCK can become quite -peculiar at high JTAG clock speeds. However, FTDI chips offer a possiblity to sample -TDO on falling edge of TCK. With some board/adapter configurations, this may increase -stability at higher JTAG clocks. -@itemize @minus -@item @option{rising}, sample TDO on rising edge of TCK - this is the default -@item @option{falling}, sample TDO on falling edge of TCK -@end itemize -@end deffn - -For example adapter definitions, see the configuration files shipped in the -@file{interface/ftdi} directory. - -@end deffn - -@deffn {Interface Driver} {remote_bitbang} -Drive JTAG from a remote process. This sets up a UNIX or TCP socket connection -with a remote process and sends ASCII encoded bitbang requests to that process -instead of directly driving JTAG. - -The remote_bitbang driver is useful for debugging software running on -processors which are being simulated. - -@deffn {Config Command} {remote_bitbang_port} number -Specifies the TCP port of the remote process to connect to or 0 to use UNIX -sockets instead of TCP. -@end deffn - -@deffn {Config Command} {remote_bitbang_host} hostname -Specifies the hostname of the remote process to connect to using TCP, or the -name of the UNIX socket to use if remote_bitbang_port is 0. -@end deffn - -For example, to connect remotely via TCP to the host foobar you might have -something like: - -@example -interface remote_bitbang -remote_bitbang_port 3335 -remote_bitbang_host foobar -@end example - -To connect to another process running locally via UNIX sockets with socket -named mysocket: - -@example -interface remote_bitbang -remote_bitbang_port 0 -remote_bitbang_host mysocket -@end example -@end deffn - -@deffn {Interface Driver} {usb_blaster} -USB JTAG/USB-Blaster compatibles over one of the userspace libraries -for FTDI chips. These interfaces have several commands, used to -configure the driver before initializing the JTAG scan chain: - -@deffn {Config Command} {usb_blaster_device_desc} description -Provides the USB device description (the @emph{iProduct string}) -of the FTDI FT245 device. If not -specified, the FTDI default value is used. This setting is only valid -if compiled with FTD2XX support. -@end deffn - -@deffn {Config Command} {usb_blaster_vid_pid} vid pid -The vendor ID and product ID of the FTDI FT245 device. If not specified, -default values are used. -Currently, only one @var{vid}, @var{pid} pair may be given, e.g. for -Altera USB-Blaster (default): -@example -usb_blaster_vid_pid 0x09FB 0x6001 -@end example -The following VID/PID is for Kolja Waschk's USB JTAG: -@example -usb_blaster_vid_pid 0x16C0 0x06AD -@end example -@end deffn - -@deffn {Command} {usb_blaster_pin} (@option{pin6}|@option{pin8}) (@option{0}|@option{1}|@option{s}|@option{t}) -Sets the state or function of the unused GPIO pins on USB-Blasters -(pins 6 and 8 on the female JTAG header). These pins can be used as -SRST and/or TRST provided the appropriate connections are made on the -target board. - -For example, to use pin 6 as SRST: -@example -usb_blaster_pin pin6 s -reset_config srst_only -@end example -@end deffn - -@deffn {Command} {usb_blaster_lowlevel_driver} (@option{ftdi}|@option{ftd2xx}|@option{ublast2}) -Chooses the low level access method for the adapter. If not specified, -@option{ftdi} is selected unless it wasn't enabled during the -configure stage. USB-Blaster II needs @option{ublast2}. -@end deffn - -@deffn {Command} {usb_blaster_firmware} @var{path} -This command specifies @var{path} to access USB-Blaster II firmware -image. To be used with USB-Blaster II only. -@end deffn - -@end deffn - -@deffn {Interface Driver} {gw16012} -Gateworks GW16012 JTAG programmer. -This has one driver-specific command: - -@deffn {Config Command} {parport_port} [port_number] -Display either the address of the I/O port -(default: 0x378 for LPT1) or the number of the @file{/dev/parport} device. -If a parameter is provided, first switch to use that port. -This is a write-once setting. -@end deffn -@end deffn - -@deffn {Interface Driver} {jlink} -SEGGER J-Link family of USB adapters. It currently supports JTAG and SWD -transports. - -@quotation Compatibility Note -SEGGER released many firmware versions for the many harware versions they -produced. OpenOCD was extensively tested and intended to run on all of them, -but some combinations were reported as incompatible. As a general -recommendation, it is advisable to use the latest firmware version -available for each hardware version. However the current V8 is a moving -target, and SEGGER firmware versions released after the OpenOCD was -released may not be compatible. In such cases it is recommended to -revert to the last known functional version. For 0.5.0, this is from -"Feb 8 2012 14:30:39", packed with 4.42c. For 0.6.0, the last known -version is from "May 3 2012 18:36:22", packed with 4.46f. -@end quotation - -@deffn {Command} {jlink hwstatus} -Display various hardware related information, for example target voltage and pin -states. -@end deffn -@deffn {Command} {jlink freemem} -Display free device internal memory. -@end deffn -@deffn {Command} {jlink jtag} [@option{2}|@option{3}] -Set the JTAG command version to be used. Without argument, show the actual JTAG -command version. -@end deffn -@deffn {Command} {jlink config} -Display the device configuration. -@end deffn -@deffn {Command} {jlink config targetpower} [@option{on}|@option{off}] -Set the target power state on JTAG-pin 19. Without argument, show the target -power state. -@end deffn -@deffn {Command} {jlink config mac} [@option{ff:ff:ff:ff:ff:ff}] -Set the MAC address of the device. Without argument, show the MAC address. -@end deffn -@deffn {Command} {jlink config ip} [@option{A.B.C.D}(@option{/E}|@option{F.G.H.I})] -Set the IP configuration of the device, where A.B.C.D is the IP address, E the -bit of the subnet mask and F.G.H.I the subnet mask. Without arguments, show the -IP configuration. -@end deffn -@deffn {Command} {jlink config usb} [@option{0} to @option{3}] -Set the USB address of the device. This will also change the USB Product ID -(PID) of the device. Without argument, show the USB address. -@end deffn -@deffn {Command} {jlink config reset} -Reset the current configuration. -@end deffn -@deffn {Command} {jlink config write} -Write the current configuration to the internal persistent storage. -@end deffn -@deffn {Config} {jlink usb} <@option{0} to @option{3}> -Set the USB address of the interface, in case more than one adapter is connected -to the host. If not specified, USB addresses are not considered. Device -selection via USB address is deprecated and the serial number should be used -instead. - -As a configuration command, it can be used only before 'init'. -@end deffn -@deffn {Config} {jlink serial} -Set the serial number of the interface, in case more than one adapter is -connected to the host. If not specified, serial numbers are not considered. - -As a configuration command, it can be used only before 'init'. -@end deffn -@end deffn - -@deffn {Interface Driver} {parport} -Supports PC parallel port bit-banging cables: -Wigglers, PLD download cable, and more. -These interfaces have several commands, used to configure the driver -before initializing the JTAG scan chain: - -@deffn {Config Command} {parport_cable} name -Set the layout of the parallel port cable used to connect to the target. -This is a write-once setting. -Currently valid cable @var{name} values include: - -@itemize @minus -@item @b{altium} Altium Universal JTAG cable. -@item @b{arm-jtag} Same as original wiggler except SRST and -TRST connections reversed and TRST is also inverted. -@item @b{chameleon} The Amontec Chameleon's CPLD when operated -in configuration mode. This is only used to -program the Chameleon itself, not a connected target. -@item @b{dlc5} The Xilinx Parallel cable III. -@item @b{flashlink} The ST Parallel cable. -@item @b{lattice} Lattice ispDOWNLOAD Cable -@item @b{old_amt_wiggler} The Wiggler configuration that comes with -some versions of -Amontec's Chameleon Programmer. The new version available from -the website uses the original Wiggler layout ('@var{wiggler}') -@item @b{triton} The parallel port adapter found on the -``Karo Triton 1 Development Board''. -This is also the layout used by the HollyGates design -(see @uref{http://www.lartmaker.nl/projects/jtag/}). -@item @b{wiggler} The original Wiggler layout, also supported by -several clones, such as the Olimex ARM-JTAG -@item @b{wiggler2} Same as original wiggler except an led is fitted on D5. -@item @b{wiggler_ntrst_inverted} Same as original wiggler except TRST is inverted. -@end itemize -@end deffn - -@deffn {Config Command} {parport_port} [port_number] -Display either the address of the I/O port -(default: 0x378 for LPT1) or the number of the @file{/dev/parport} device. -If a parameter is provided, first switch to use that port. -This is a write-once setting. - -When using PPDEV to access the parallel port, use the number of the parallel port: -@option{parport_port 0} (the default). If @option{parport_port 0x378} is specified -you may encounter a problem. -@end deffn - -@deffn Command {parport_toggling_time} [nanoseconds] -Displays how many nanoseconds the hardware needs to toggle TCK; -the parport driver uses this value to obey the -@command{adapter_khz} configuration. -When the optional @var{nanoseconds} parameter is given, -that setting is changed before displaying the current value. - -The default setting should work reasonably well on commodity PC hardware. -However, you may want to calibrate for your specific hardware. -@quotation Tip -To measure the toggling time with a logic analyzer or a digital storage -oscilloscope, follow the procedure below: -@example -> parport_toggling_time 1000 -> adapter_khz 500 -@end example -This sets the maximum JTAG clock speed of the hardware, but -the actual speed probably deviates from the requested 500 kHz. -Now, measure the time between the two closest spaced TCK transitions. -You can use @command{runtest 1000} or something similar to generate a -large set of samples. -Update the setting to match your measurement: -@example -> parport_toggling_time -@end example -Now the clock speed will be a better match for @command{adapter_khz rate} -commands given in OpenOCD scripts and event handlers. - -You can do something similar with many digital multimeters, but note -that you'll probably need to run the clock continuously for several -seconds before it decides what clock rate to show. Adjust the -toggling time up or down until the measured clock rate is a good -match for the adapter_khz rate you specified; be conservative. -@end quotation -@end deffn - -@deffn {Config Command} {parport_write_on_exit} (@option{on}|@option{off}) -This will configure the parallel driver to write a known -cable-specific value to the parallel interface on exiting OpenOCD. -@end deffn - -For example, the interface configuration file for a -classic ``Wiggler'' cable on LPT2 might look something like this: - -@example -interface parport -parport_port 0x278 -parport_cable wiggler -@end example -@end deffn - -@deffn {Interface Driver} {presto} -ASIX PRESTO USB JTAG programmer. -@deffn {Config Command} {presto_serial} serial_string -Configures the USB serial number of the Presto device to use. -@end deffn -@end deffn - -@deffn {Interface Driver} {rlink} -Raisonance RLink USB adapter -@end deffn - -@deffn {Interface Driver} {usbprog} -usbprog is a freely programmable USB adapter. -@end deffn - -@deffn {Interface Driver} {vsllink} -vsllink is part of Versaloon which is a versatile USB programmer. - -@quotation Note -This defines quite a few driver-specific commands, -which are not currently documented here. -@end quotation -@end deffn - -@anchor{hla_interface} -@deffn {Interface Driver} {hla} -This is a driver that supports multiple High Level Adapters. -This type of adapter does not expose some of the lower level api's -that OpenOCD would normally use to access the target. - -Currently supported adapters include the ST STLINK and TI ICDI. -STLINK firmware version >= V2.J21.S4 recommended due to issues with earlier -versions of firmware where serial number is reset after first use. Suggest -using ST firmware update utility to upgrade STLINK firmware even if current -version reported is V2.J21.S4. - -@deffn {Config Command} {hla_device_desc} description -Currently Not Supported. -@end deffn - -@deffn {Config Command} {hla_serial} serial -Specifies the serial number of the adapter. -@end deffn - -@deffn {Config Command} {hla_layout} (@option{stlink}|@option{icdi}) -Specifies the adapter layout to use. -@end deffn - -@deffn {Config Command} {hla_vid_pid} vid pid -The vendor ID and product ID of the device. -@end deffn - -@deffn {Command} {hla_command} command -Execute a custom adapter-specific command. The @var{command} string is -passed as is to the underlying adapter layout handler. -@end deffn -@end deffn - -@deffn {Interface Driver} {opendous} -opendous-jtag is a freely programmable USB adapter. -@end deffn - -@deffn {Interface Driver} {ulink} -This is the Keil ULINK v1 JTAG debugger. -@end deffn - -@deffn {Interface Driver} {ZY1000} -This is the Zylin ZY1000 JTAG debugger. -@end deffn - -@quotation Note -This defines some driver-specific commands, -which are not currently documented here. -@end quotation - -@deffn Command power [@option{on}|@option{off}] -Turn power switch to target on/off. -No arguments: print status. -@end deffn - -@deffn {Interface Driver} {bcm2835gpio} -This SoC is present in Raspberry Pi which is a cheap single-board computer -exposing some GPIOs on its expansion header. - -The driver accesses memory-mapped GPIO peripheral registers directly -for maximum performance, but the only possible race condition is for -the pins' modes/muxing (which is highly unlikely), so it should be -able to coexist nicely with both sysfs bitbanging and various -peripherals' kernel drivers. The driver restores the previous -configuration on exit. - -See @file{interface/raspberrypi-native.cfg} for a sample config and -pinout. - -@end deffn - -@section Transport Configuration -@cindex Transport -As noted earlier, depending on the version of OpenOCD you use, -and the debug adapter you are using, -several transports may be available to -communicate with debug targets (or perhaps to program flash memory). -@deffn Command {transport list} -displays the names of the transports supported by this -version of OpenOCD. -@end deffn - -@deffn Command {transport select} @option{transport_name} -Select which of the supported transports to use in this OpenOCD session. - -When invoked with @option{transport_name}, attempts to select the named -transport. The transport must be supported by the debug adapter -hardware and by the version of OpenOCD you are using (including the -adapter's driver). - -If no transport has been selected and no @option{transport_name} is -provided, @command{transport select} auto-selects the first transport -supported by the debug adapter. - -@command{transport select} always returns the name of the session's selected -transport, if any. -@end deffn - -@subsection JTAG Transport -@cindex JTAG -JTAG is the original transport supported by OpenOCD, and most -of the OpenOCD commands support it. -JTAG transports expose a chain of one or more Test Access Points (TAPs), -each of which must be explicitly declared. -JTAG supports both debugging and boundary scan testing. -Flash programming support is built on top of debug support. - -JTAG transport is selected with the command @command{transport select -jtag}. Unless your adapter uses @ref{hla_interface,the hla interface -driver}, in which case the command is @command{transport select -hla_jtag}. - -@subsection SWD Transport -@cindex SWD -@cindex Serial Wire Debug -SWD (Serial Wire Debug) is an ARM-specific transport which exposes one -Debug Access Point (DAP, which must be explicitly declared. -(SWD uses fewer signal wires than JTAG.) -SWD is debug-oriented, and does not support boundary scan testing. -Flash programming support is built on top of debug support. -(Some processors support both JTAG and SWD.) - -SWD transport is selected with the command @command{transport select -swd}. Unless your adapter uses @ref{hla_interface,the hla interface -driver}, in which case the command is @command{transport select -hla_swd}. - -@deffn Command {swd newdap} ... -Declares a single DAP which uses SWD transport. -Parameters are currently the same as "jtag newtap" but this is -expected to change. -@end deffn -@deffn Command {swd wcr trn prescale} -Updates TRN (turnaraound delay) and prescaling.fields of the -Wire Control Register (WCR). -No parameters: displays current settings. -@end deffn - -@subsection SPI Transport -@cindex SPI -@cindex Serial Peripheral Interface -The Serial Peripheral Interface (SPI) is a general purpose transport -which uses four wire signaling. Some processors use it as part of a -solution for flash programming. - -@anchor{jtagspeed} -@section JTAG Speed -JTAG clock setup is part of system setup. -It @emph{does not belong with interface setup} since any interface -only knows a few of the constraints for the JTAG clock speed. -Sometimes the JTAG speed is -changed during the target initialization process: (1) slow at -reset, (2) program the CPU clocks, (3) run fast. -Both the "slow" and "fast" clock rates are functions of the -oscillators used, the chip, the board design, and sometimes -power management software that may be active. - -The speed used during reset, and the scan chain verification which -follows reset, can be adjusted using a @code{reset-start} -target event handler. -It can then be reconfigured to a faster speed by a -@code{reset-init} target event handler after it reprograms those -CPU clocks, or manually (if something else, such as a boot loader, -sets up those clocks). -@xref{targetevents,,Target Events}. -When the initial low JTAG speed is a chip characteristic, perhaps -because of a required oscillator speed, provide such a handler -in the target config file. -When that speed is a function of a board-specific characteristic -such as which speed oscillator is used, it belongs in the board -config file instead. -In both cases it's safest to also set the initial JTAG clock rate -to that same slow speed, so that OpenOCD never starts up using a -clock speed that's faster than the scan chain can support. - -@example -jtag_rclk 3000 -$_TARGET.cpu configure -event reset-start @{ jtag_rclk 3000 @} -@end example - -If your system supports adaptive clocking (RTCK), configuring -JTAG to use that is probably the most robust approach. -However, it introduces delays to synchronize clocks; so it -may not be the fastest solution. - -@b{NOTE:} Script writers should consider using @command{jtag_rclk} -instead of @command{adapter_khz}, but only for (ARM) cores and boards -which support adaptive clocking. - -@deffn {Command} adapter_khz max_speed_kHz -A non-zero speed is in KHZ. Hence: 3000 is 3mhz. -JTAG interfaces usually support a limited number of -speeds. The speed actually used won't be faster -than the speed specified. - -Chip data sheets generally include a top JTAG clock rate. -The actual rate is often a function of a CPU core clock, -and is normally less than that peak rate. -For example, most ARM cores accept at most one sixth of the CPU clock. - -Speed 0 (khz) selects RTCK method. -@xref{faqrtck,,FAQ RTCK}. -If your system uses RTCK, you won't need to change the -JTAG clocking after setup. -Not all interfaces, boards, or targets support ``rtck''. -If the interface device can not -support it, an error is returned when you try to use RTCK. -@end deffn - -@defun jtag_rclk fallback_speed_kHz -@cindex adaptive clocking -@cindex RTCK -This Tcl proc (defined in @file{startup.tcl}) attempts to enable RTCK/RCLK. -If that fails (maybe the interface, board, or target doesn't -support it), falls back to the specified frequency. -@example -# Fall back to 3mhz if RTCK is not supported -jtag_rclk 3000 -@end example -@end defun - -@node Reset Configuration -@chapter Reset Configuration -@cindex Reset Configuration - -Every system configuration may require a different reset -configuration. This can also be quite confusing. -Resets also interact with @var{reset-init} event handlers, -which do things like setting up clocks and DRAM, and -JTAG clock rates. (@xref{jtagspeed,,JTAG Speed}.) -They can also interact with JTAG routers. -Please see the various board files for examples. - -@quotation Note -To maintainers and integrators: -Reset configuration touches several things at once. -Normally the board configuration file -should define it and assume that the JTAG adapter supports -everything that's wired up to the board's JTAG connector. - -However, the target configuration file could also make note -of something the silicon vendor has done inside the chip, -which will be true for most (or all) boards using that chip. -And when the JTAG adapter doesn't support everything, the -user configuration file will need to override parts of -the reset configuration provided by other files. -@end quotation - -@section Types of Reset - -There are many kinds of reset possible through JTAG, but -they may not all work with a given board and adapter. -That's part of why reset configuration can be error prone. - -@itemize @bullet -@item -@emph{System Reset} ... the @emph{SRST} hardware signal -resets all chips connected to the JTAG adapter, such as processors, -power management chips, and I/O controllers. Normally resets triggered -with this signal behave exactly like pressing a RESET button. -@item -@emph{JTAG TAP Reset} ... the @emph{TRST} hardware signal resets -just the TAP controllers connected to the JTAG adapter. -Such resets should not be visible to the rest of the system; resetting a -device's TAP controller just puts that controller into a known state. -@item -@emph{Emulation Reset} ... many devices can be reset through JTAG -commands. These resets are often distinguishable from system -resets, either explicitly (a "reset reason" register says so) -or implicitly (not all parts of the chip get reset). -@item -@emph{Other Resets} ... system-on-chip devices often support -several other types of reset. -You may need to arrange that a watchdog timer stops -while debugging, preventing a watchdog reset. -There may be individual module resets. -@end itemize - -In the best case, OpenOCD can hold SRST, then reset -the TAPs via TRST and send commands through JTAG to halt the -CPU at the reset vector before the 1st instruction is executed. -Then when it finally releases the SRST signal, the system is -halted under debugger control before any code has executed. -This is the behavior required to support the @command{reset halt} -and @command{reset init} commands; after @command{reset init} a -board-specific script might do things like setting up DRAM. -(@xref{resetcommand,,Reset Command}.) - -@anchor{srstandtrstissues} -@section SRST and TRST Issues - -Because SRST and TRST are hardware signals, they can have a -variety of system-specific constraints. Some of the most -common issues are: - -@itemize @bullet - -@item @emph{Signal not available} ... Some boards don't wire -SRST or TRST to the JTAG connector. Some JTAG adapters don't -support such signals even if they are wired up. -Use the @command{reset_config} @var{signals} options to say -when either of those signals is not connected. -When SRST is not available, your code might not be able to rely -on controllers having been fully reset during code startup. -Missing TRST is not a problem, since JTAG-level resets can -be triggered using with TMS signaling. - -@item @emph{Signals shorted} ... Sometimes a chip, board, or -adapter will connect SRST to TRST, instead of keeping them separate. -Use the @command{reset_config} @var{combination} options to say -when those signals aren't properly independent. - -@item @emph{Timing} ... Reset circuitry like a resistor/capacitor -delay circuit, reset supervisor, or on-chip features can extend -the effect of a JTAG adapter's reset for some time after the adapter -stops issuing the reset. For example, there may be chip or board -requirements that all reset pulses last for at least a -certain amount of time; and reset buttons commonly have -hardware debouncing. -Use the @command{adapter_nsrst_delay} and @command{jtag_ntrst_delay} -commands to say when extra delays are needed. - -@item @emph{Drive type} ... Reset lines often have a pullup -resistor, letting the JTAG interface treat them as open-drain -signals. But that's not a requirement, so the adapter may need -to use push/pull output drivers. -Also, with weak pullups it may be advisable to drive -signals to both levels (push/pull) to minimize rise times. -Use the @command{reset_config} @var{trst_type} and -@var{srst_type} parameters to say how to drive reset signals. - -@item @emph{Special initialization} ... Targets sometimes need -special JTAG initialization sequences to handle chip-specific -issues (not limited to errata). -For example, certain JTAG commands might need to be issued while -the system as a whole is in a reset state (SRST active) -but the JTAG scan chain is usable (TRST inactive). -Many systems treat combined assertion of SRST and TRST as a -trigger for a harder reset than SRST alone. -Such custom reset handling is discussed later in this chapter. -@end itemize - -There can also be other issues. -Some devices don't fully conform to the JTAG specifications. -Trivial system-specific differences are common, such as -SRST and TRST using slightly different names. -There are also vendors who distribute key JTAG documentation for -their chips only to developers who have signed a Non-Disclosure -Agreement (NDA). - -Sometimes there are chip-specific extensions like a requirement to use -the normally-optional TRST signal (precluding use of JTAG adapters which -don't pass TRST through), or needing extra steps to complete a TAP reset. - -In short, SRST and especially TRST handling may be very finicky, -needing to cope with both architecture and board specific constraints. - -@section Commands for Handling Resets - -@deffn {Command} adapter_nsrst_assert_width milliseconds -Minimum amount of time (in milliseconds) OpenOCD should wait -after asserting nSRST (active-low system reset) before -allowing it to be deasserted. -@end deffn - -@deffn {Command} adapter_nsrst_delay milliseconds -How long (in milliseconds) OpenOCD should wait after deasserting -nSRST (active-low system reset) before starting new JTAG operations. -When a board has a reset button connected to SRST line it will -probably have hardware debouncing, implying you should use this. -@end deffn - -@deffn {Command} jtag_ntrst_assert_width milliseconds -Minimum amount of time (in milliseconds) OpenOCD should wait -after asserting nTRST (active-low JTAG TAP reset) before -allowing it to be deasserted. -@end deffn - -@deffn {Command} jtag_ntrst_delay milliseconds -How long (in milliseconds) OpenOCD should wait after deasserting -nTRST (active-low JTAG TAP reset) before starting new JTAG operations. -@end deffn - -@deffn {Command} reset_config mode_flag ... -This command displays or modifies the reset configuration -of your combination of JTAG board and target in target -configuration scripts. - -Information earlier in this section describes the kind of problems -the command is intended to address (@pxref{srstandtrstissues,,SRST and TRST Issues}). -As a rule this command belongs only in board config files, -describing issues like @emph{board doesn't connect TRST}; -or in user config files, addressing limitations derived -from a particular combination of interface and board. -(An unlikely example would be using a TRST-only adapter -with a board that only wires up SRST.) - -The @var{mode_flag} options can be specified in any order, but only one -of each type -- @var{signals}, @var{combination}, @var{gates}, -@var{trst_type}, @var{srst_type} and @var{connect_type} --- may be specified at a time. -If you don't provide a new value for a given type, its previous -value (perhaps the default) is unchanged. -For example, this means that you don't need to say anything at all about -TRST just to declare that if the JTAG adapter should want to drive SRST, -it must explicitly be driven high (@option{srst_push_pull}). - -@itemize -@item -@var{signals} can specify which of the reset signals are connected. -For example, If the JTAG interface provides SRST, but the board doesn't -connect that signal properly, then OpenOCD can't use it. -Possible values are @option{none} (the default), @option{trst_only}, -@option{srst_only} and @option{trst_and_srst}. - -@quotation Tip -If your board provides SRST and/or TRST through the JTAG connector, -you must declare that so those signals can be used. -@end quotation - -@item -The @var{combination} is an optional value specifying broken reset -signal implementations. -The default behaviour if no option given is @option{separate}, -indicating everything behaves normally. -@option{srst_pulls_trst} states that the -test logic is reset together with the reset of the system (e.g. NXP -LPC2000, "broken" board layout), @option{trst_pulls_srst} says that -the system is reset together with the test logic (only hypothetical, I -haven't seen hardware with such a bug, and can be worked around). -@option{combined} implies both @option{srst_pulls_trst} and -@option{trst_pulls_srst}. - -@item -The @var{gates} tokens control flags that describe some cases where -JTAG may be unvailable during reset. -@option{srst_gates_jtag} (default) -indicates that asserting SRST gates the -JTAG clock. This means that no communication can happen on JTAG -while SRST is asserted. -Its converse is @option{srst_nogate}, indicating that JTAG commands -can safely be issued while SRST is active. - -@item -The @var{connect_type} tokens control flags that describe some cases where -SRST is asserted while connecting to the target. @option{srst_nogate} -is required to use this option. -@option{connect_deassert_srst} (default) -indicates that SRST will not be asserted while connecting to the target. -Its converse is @option{connect_assert_srst}, indicating that SRST will -be asserted before any target connection. -Only some targets support this feature, STM32 and STR9 are examples. -This feature is useful if you are unable to connect to your target due -to incorrect options byte config or illegal program execution. -@end itemize - -The optional @var{trst_type} and @var{srst_type} parameters allow the -driver mode of each reset line to be specified. These values only affect -JTAG interfaces with support for different driver modes, like the Amontec -JTAGkey and JTAG Accelerator. Also, they are necessarily ignored if the -relevant signal (TRST or SRST) is not connected. - -@itemize -@item -Possible @var{trst_type} driver modes for the test reset signal (TRST) -are the default @option{trst_push_pull}, and @option{trst_open_drain}. -Most boards connect this signal to a pulldown, so the JTAG TAPs -never leave reset unless they are hooked up to a JTAG adapter. - -@item -Possible @var{srst_type} driver modes for the system reset signal (SRST) -are the default @option{srst_open_drain}, and @option{srst_push_pull}. -Most boards connect this signal to a pullup, and allow the -signal to be pulled low by various events including system -powerup and pressing a reset button. -@end itemize -@end deffn - -@section Custom Reset Handling -@cindex events - -OpenOCD has several ways to help support the various reset -mechanisms provided by chip and board vendors. -The commands shown in the previous section give standard parameters. -There are also @emph{event handlers} associated with TAPs or Targets. -Those handlers are Tcl procedures you can provide, which are invoked -at particular points in the reset sequence. - -@emph{When SRST is not an option} you must set -up a @code{reset-assert} event handler for your target. -For example, some JTAG adapters don't include the SRST signal; -and some boards have multiple targets, and you won't always -want to reset everything at once. - -After configuring those mechanisms, you might still -find your board doesn't start up or reset correctly. -For example, maybe it needs a slightly different sequence -of SRST and/or TRST manipulations, because of quirks that -the @command{reset_config} mechanism doesn't address; -or asserting both might trigger a stronger reset, which -needs special attention. - -Experiment with lower level operations, such as @command{jtag_reset} -and the @command{jtag arp_*} operations shown here, -to find a sequence of operations that works. -@xref{JTAG Commands}. -When you find a working sequence, it can be used to override -@command{jtag_init}, which fires during OpenOCD startup -(@pxref{configurationstage,,Configuration Stage}); -or @command{init_reset}, which fires during reset processing. - -You might also want to provide some project-specific reset -schemes. For example, on a multi-target board the standard -@command{reset} command would reset all targets, but you -may need the ability to reset only one target at time and -thus want to avoid using the board-wide SRST signal. - -@deffn {Overridable Procedure} init_reset mode -This is invoked near the beginning of the @command{reset} command, -usually to provide as much of a cold (power-up) reset as practical. -By default it is also invoked from @command{jtag_init} if -the scan chain does not respond to pure JTAG operations. -The @var{mode} parameter is the parameter given to the -low level reset command (@option{halt}, -@option{init}, or @option{run}), @option{setup}, -or potentially some other value. - -The default implementation just invokes @command{jtag arp_init-reset}. -Replacements will normally build on low level JTAG -operations such as @command{jtag_reset}. -Operations here must not address individual TAPs -(or their associated targets) -until the JTAG scan chain has first been verified to work. - -Implementations must have verified the JTAG scan chain before -they return. -This is done by calling @command{jtag arp_init} -(or @command{jtag arp_init-reset}). -@end deffn - -@deffn Command {jtag arp_init} -This validates the scan chain using just the four -standard JTAG signals (TMS, TCK, TDI, TDO). -It starts by issuing a JTAG-only reset. -Then it performs checks to verify that the scan chain configuration -matches the TAPs it can observe. -Those checks include checking IDCODE values for each active TAP, -and verifying the length of their instruction registers using -TAP @code{-ircapture} and @code{-irmask} values. -If these tests all pass, TAP @code{setup} events are -issued to all TAPs with handlers for that event. -@end deffn - -@deffn Command {jtag arp_init-reset} -This uses TRST and SRST to try resetting -everything on the JTAG scan chain -(and anything else connected to SRST). -It then invokes the logic of @command{jtag arp_init}. -@end deffn - - -@node TAP Declaration -@chapter TAP Declaration -@cindex TAP declaration -@cindex TAP configuration - -@emph{Test Access Ports} (TAPs) are the core of JTAG. -TAPs serve many roles, including: - -@itemize @bullet -@item @b{Debug Target} A CPU TAP can be used as a GDB debug target. -@item @b{Flash Programming} Some chips program the flash directly via JTAG. -Others do it indirectly, making a CPU do it. -@item @b{Program Download} Using the same CPU support GDB uses, -you can initialize a DRAM controller, download code to DRAM, and then -start running that code. -@item @b{Boundary Scan} Most chips support boundary scan, which -helps test for board assembly problems like solder bridges -and missing connections. -@end itemize - -OpenOCD must know about the active TAPs on your board(s). -Setting up the TAPs is the core task of your configuration files. -Once those TAPs are set up, you can pass their names to code -which sets up CPUs and exports them as GDB targets, -probes flash memory, performs low-level JTAG operations, and more. - -@section Scan Chains -@cindex scan chain - -TAPs are part of a hardware @dfn{scan chain}, -which is a daisy chain of TAPs. -They also need to be added to -OpenOCD's software mirror of that hardware list, -giving each member a name and associating other data with it. -Simple scan chains, with a single TAP, are common in -systems with a single microcontroller or microprocessor. -More complex chips may have several TAPs internally. -Very complex scan chains might have a dozen or more TAPs: -several in one chip, more in the next, and connecting -to other boards with their own chips and TAPs. - -You can display the list with the @command{scan_chain} command. -(Don't confuse this with the list displayed by the @command{targets} -command, presented in the next chapter. -That only displays TAPs for CPUs which are configured as -debugging targets.) -Here's what the scan chain might look like for a chip more than one TAP: - -@verbatim - TapName Enabled IdCode Expected IrLen IrCap IrMask --- ------------------ ------- ---------- ---------- ----- ----- ------ - 0 omap5912.dsp Y 0x03df1d81 0x03df1d81 38 0x01 0x03 - 1 omap5912.arm Y 0x0692602f 0x0692602f 4 0x01 0x0f - 2 omap5912.unknown Y 0x00000000 0x00000000 8 0x01 0x03 -@end verbatim - -OpenOCD can detect some of that information, but not all -of it. @xref{autoprobing,,Autoprobing}. -Unfortunately, those TAPs can't always be autoconfigured, -because not all devices provide good support for that. -JTAG doesn't require supporting IDCODE instructions, and -chips with JTAG routers may not link TAPs into the chain -until they are told to do so. - -The configuration mechanism currently supported by OpenOCD -requires explicit configuration of all TAP devices using -@command{jtag newtap} commands, as detailed later in this chapter. -A command like this would declare one tap and name it @code{chip1.cpu}: - -@example -jtag newtap chip1 cpu -irlen 4 -expected-id 0x3ba00477 -@end example - -Each target configuration file lists the TAPs provided -by a given chip. -Board configuration files combine all the targets on a board, -and so forth. -Note that @emph{the order in which TAPs are declared is very important.} -That declaration order must match the order in the JTAG scan chain, -both inside a single chip and between them. -@xref{faqtaporder,,FAQ TAP Order}. - -For example, the ST Microsystems STR912 chip has -three separate TAPs@footnote{See the ST -document titled: @emph{STR91xFAxxx, Section 3.15 Jtag Interface, Page: -28/102, Figure 3: JTAG chaining inside the STR91xFA}. -@url{http://eu.st.com/stonline/products/literature/ds/13495.pdf}}. -To configure those taps, @file{target/str912.cfg} -includes commands something like this: - -@example -jtag newtap str912 flash ... params ... -jtag newtap str912 cpu ... params ... -jtag newtap str912 bs ... params ... -@end example - -Actual config files typically use a variable such as @code{$_CHIPNAME} -instead of literals like @option{str912}, to support more than one chip -of each type. @xref{Config File Guidelines}. - -@deffn Command {jtag names} -Returns the names of all current TAPs in the scan chain. -Use @command{jtag cget} or @command{jtag tapisenabled} -to examine attributes and state of each TAP. -@example -foreach t [jtag names] @{ - puts [format "TAP: %s\n" $t] -@} -@end example -@end deffn - -@deffn Command {scan_chain} -Displays the TAPs in the scan chain configuration, -and their status. -The set of TAPs listed by this command is fixed by -exiting the OpenOCD configuration stage, -but systems with a JTAG router can -enable or disable TAPs dynamically. -@end deffn - -@c FIXME! "jtag cget" should be able to return all TAP -@c attributes, like "$target_name cget" does for targets. - -@c Probably want "jtag eventlist", and a "tap-reset" event -@c (on entry to RESET state). - -@section TAP Names -@cindex dotted name - -When TAP objects are declared with @command{jtag newtap}, -a @dfn{dotted.name} is created for the TAP, combining the -name of a module (usually a chip) and a label for the TAP. -For example: @code{xilinx.tap}, @code{str912.flash}, -@code{omap3530.jrc}, @code{dm6446.dsp}, or @code{stm32.cpu}. -Many other commands use that dotted.name to manipulate or -refer to the TAP. For example, CPU configuration uses the -name, as does declaration of NAND or NOR flash banks. - -The components of a dotted name should follow ``C'' symbol -name rules: start with an alphabetic character, then numbers -and underscores are OK; while others (including dots!) are not. - -@section TAP Declaration Commands - -@c shouldn't this be(come) a {Config Command}? -@deffn Command {jtag newtap} chipname tapname configparams... -Declares a new TAP with the dotted name @var{chipname}.@var{tapname}, -and configured according to the various @var{configparams}. - -The @var{chipname} is a symbolic name for the chip. -Conventionally target config files use @code{$_CHIPNAME}, -defaulting to the model name given by the chip vendor but -overridable. - -@cindex TAP naming convention -The @var{tapname} reflects the role of that TAP, -and should follow this convention: - -@itemize @bullet -@item @code{bs} -- For boundary scan if this is a separate TAP; -@item @code{cpu} -- The main CPU of the chip, alternatively -@code{arm} and @code{dsp} on chips with both ARM and DSP CPUs, -@code{arm1} and @code{arm2} on chips with two ARMs, and so forth; -@item @code{etb} -- For an embedded trace buffer (example: an ARM ETB11); -@item @code{flash} -- If the chip has a flash TAP, like the str912; -@item @code{jrc} -- For JTAG route controller (example: the ICEPick modules -on many Texas Instruments chips, like the OMAP3530 on Beagleboards); -@item @code{tap} -- Should be used only for FPGA- or CPLD-like devices -with a single TAP; -@item @code{unknownN} -- If you have no idea what the TAP is for (N is a number); -@item @emph{when in doubt} -- Use the chip maker's name in their data sheet. -For example, the Freescale i.MX31 has a SDMA (Smart DMA) with -a JTAG TAP; that TAP should be named @code{sdma}. -@end itemize - -Every TAP requires at least the following @var{configparams}: - -@itemize @bullet -@item @code{-irlen} @var{NUMBER} -@*The length in bits of the -instruction register, such as 4 or 5 bits. -@end itemize - -A TAP may also provide optional @var{configparams}: - -@itemize @bullet -@item @code{-disable} (or @code{-enable}) -@*Use the @code{-disable} parameter to flag a TAP which is not -linked into the scan chain after a reset using either TRST -or the JTAG state machine's @sc{reset} state. -You may use @code{-enable} to highlight the default state -(the TAP is linked in). -@xref{enablinganddisablingtaps,,Enabling and Disabling TAPs}. -@item @code{-expected-id} @var{NUMBER} -@*A non-zero @var{number} represents a 32-bit IDCODE -which you expect to find when the scan chain is examined. -These codes are not required by all JTAG devices. -@emph{Repeat the option} as many times as required if more than one -ID code could appear (for example, multiple versions). -Specify @var{number} as zero to suppress warnings about IDCODE -values that were found but not included in the list. - -Provide this value if at all possible, since it lets OpenOCD -tell when the scan chain it sees isn't right. These values -are provided in vendors' chip documentation, usually a technical -reference manual. Sometimes you may need to probe the JTAG -hardware to find these values. -@xref{autoprobing,,Autoprobing}. -@item @code{-ignore-version} -@*Specify this to ignore the JTAG version field in the @code{-expected-id} -option. When vendors put out multiple versions of a chip, or use the same -JTAG-level ID for several largely-compatible chips, it may be more practical -to ignore the version field than to update config files to handle all of -the various chip IDs. The version field is defined as bit 28-31 of the IDCODE. -@item @code{-ircapture} @var{NUMBER} -@*The bit pattern loaded by the TAP into the JTAG shift register -on entry to the @sc{ircapture} state, such as 0x01. -JTAG requires the two LSBs of this value to be 01. -By default, @code{-ircapture} and @code{-irmask} are set -up to verify that two-bit value. You may provide -additional bits if you know them, or indicate that -a TAP doesn't conform to the JTAG specification. -@item @code{-irmask} @var{NUMBER} -@*A mask used with @code{-ircapture} -to verify that instruction scans work correctly. -Such scans are not used by OpenOCD except to verify that -there seems to be no problems with JTAG scan chain operations. -@end itemize -@end deffn - -@section Other TAP commands - -@deffn Command {jtag cget} dotted.name @option{-event} event_name -@deffnx Command {jtag configure} dotted.name @option{-event} event_name handler -At this writing this TAP attribute -mechanism is used only for event handling. -(It is not a direct analogue of the @code{cget}/@code{configure} -mechanism for debugger targets.) -See the next section for information about the available events. - -The @code{configure} subcommand assigns an event handler, -a TCL string which is evaluated when the event is triggered. -The @code{cget} subcommand returns that handler. -@end deffn - -@section TAP Events -@cindex events -@cindex TAP events - -OpenOCD includes two event mechanisms. -The one presented here applies to all JTAG TAPs. -The other applies to debugger targets, -which are associated with certain TAPs. - -The TAP events currently defined are: - -@itemize @bullet -@item @b{post-reset} -@* The TAP has just completed a JTAG reset. -The tap may still be in the JTAG @sc{reset} state. -Handlers for these events might perform initialization sequences -such as issuing TCK cycles, TMS sequences to ensure -exit from the ARM SWD mode, and more. - -Because the scan chain has not yet been verified, handlers for these events -@emph{should not issue commands which scan the JTAG IR or DR registers} -of any particular target. -@b{NOTE:} As this is written (September 2009), nothing prevents such access. -@item @b{setup} -@* The scan chain has been reset and verified. -This handler may enable TAPs as needed. -@item @b{tap-disable} -@* The TAP needs to be disabled. This handler should -implement @command{jtag tapdisable} -by issuing the relevant JTAG commands. -@item @b{tap-enable} -@* The TAP needs to be enabled. This handler should -implement @command{jtag tapenable} -by issuing the relevant JTAG commands. -@end itemize - -If you need some action after each JTAG reset which isn't actually -specific to any TAP (since you can't yet trust the scan chain's -contents to be accurate), you might: - -@example -jtag configure CHIP.jrc -event post-reset @{ - echo "JTAG Reset done" - ... non-scan jtag operations to be done after reset -@} -@end example - - -@anchor{enablinganddisablingtaps} -@section Enabling and Disabling TAPs -@cindex JTAG Route Controller -@cindex jrc - -In some systems, a @dfn{JTAG Route Controller} (JRC) -is used to enable and/or disable specific JTAG TAPs. -Many ARM-based chips from Texas Instruments include -an ``ICEPick'' module, which is a JRC. -Such chips include DaVinci and OMAP3 processors. - -A given TAP may not be visible until the JRC has been -told to link it into the scan chain; and if the JRC -has been told to unlink that TAP, it will no longer -be visible. -Such routers address problems that JTAG ``bypass mode'' -ignores, such as: - -@itemize -@item The scan chain can only go as fast as its slowest TAP. -@item Having many TAPs slows instruction scans, since all -TAPs receive new instructions. -@item TAPs in the scan chain must be powered up, which wastes -power and prevents debugging some power management mechanisms. -@end itemize - -The IEEE 1149.1 JTAG standard has no concept of a ``disabled'' tap, -as implied by the existence of JTAG routers. -However, the upcoming IEEE 1149.7 framework (layered on top of JTAG) -does include a kind of JTAG router functionality. - -@c (a) currently the event handlers don't seem to be able to -@c fail in a way that could lead to no-change-of-state. - -In OpenOCD, tap enabling/disabling is invoked by the Tcl commands -shown below, and is implemented using TAP event handlers. -So for example, when defining a TAP for a CPU connected to -a JTAG router, your @file{target.cfg} file -should define TAP event handlers using -code that looks something like this: - -@example -jtag configure CHIP.cpu -event tap-enable @{ - ... jtag operations using CHIP.jrc -@} -jtag configure CHIP.cpu -event tap-disable @{ - ... jtag operations using CHIP.jrc -@} -@end example - -Then you might want that CPU's TAP enabled almost all the time: - -@example -jtag configure $CHIP.jrc -event setup "jtag tapenable $CHIP.cpu" -@end example - -Note how that particular setup event handler declaration -uses quotes to evaluate @code{$CHIP} when the event is configured. -Using brackets @{ @} would cause it to be evaluated later, -at runtime, when it might have a different value. - -@deffn Command {jtag tapdisable} dotted.name -If necessary, disables the tap -by sending it a @option{tap-disable} event. -Returns the string "1" if the tap -specified by @var{dotted.name} is enabled, -and "0" if it is disabled. -@end deffn - -@deffn Command {jtag tapenable} dotted.name -If necessary, enables the tap -by sending it a @option{tap-enable} event. -Returns the string "1" if the tap -specified by @var{dotted.name} is enabled, -and "0" if it is disabled. -@end deffn - -@deffn Command {jtag tapisenabled} dotted.name -Returns the string "1" if the tap -specified by @var{dotted.name} is enabled, -and "0" if it is disabled. - -@quotation Note -Humans will find the @command{scan_chain} command more helpful -for querying the state of the JTAG taps. -@end quotation -@end deffn - -@anchor{autoprobing} -@section Autoprobing -@cindex autoprobe -@cindex JTAG autoprobe - -TAP configuration is the first thing that needs to be done -after interface and reset configuration. Sometimes it's -hard finding out what TAPs exist, or how they are identified. -Vendor documentation is not always easy to find and use. - -To help you get past such problems, OpenOCD has a limited -@emph{autoprobing} ability to look at the scan chain, doing -a @dfn{blind interrogation} and then reporting the TAPs it finds. -To use this mechanism, start the OpenOCD server with only data -that configures your JTAG interface, and arranges to come up -with a slow clock (many devices don't support fast JTAG clocks -right when they come out of reset). - -For example, your @file{openocd.cfg} file might have: - -@example -source [find interface/olimex-arm-usb-tiny-h.cfg] -reset_config trst_and_srst -jtag_rclk 8 -@end example - -When you start the server without any TAPs configured, it will -attempt to autoconfigure the TAPs. There are two parts to this: - -@enumerate -@item @emph{TAP discovery} ... -After a JTAG reset (sometimes a system reset may be needed too), -each TAP's data registers will hold the contents of either the -IDCODE or BYPASS register. -If JTAG communication is working, OpenOCD will see each TAP, -and report what @option{-expected-id} to use with it. -@item @emph{IR Length discovery} ... -Unfortunately JTAG does not provide a reliable way to find out -the value of the @option{-irlen} parameter to use with a TAP -that is discovered. -If OpenOCD can discover the length of a TAP's instruction -register, it will report it. -Otherwise you may need to consult vendor documentation, such -as chip data sheets or BSDL files. -@end enumerate - -In many cases your board will have a simple scan chain with just -a single device. Here's what OpenOCD reported with one board -that's a bit more complex: - -@example -clock speed 8 kHz -There are no enabled taps. AUTO PROBING MIGHT NOT WORK!! -AUTO auto0.tap - use "jtag newtap auto0 tap -expected-id 0x2b900f0f ..." -AUTO auto1.tap - use "jtag newtap auto1 tap -expected-id 0x07926001 ..." -AUTO auto2.tap - use "jtag newtap auto2 tap -expected-id 0x0b73b02f ..." -AUTO auto0.tap - use "... -irlen 4" -AUTO auto1.tap - use "... -irlen 4" -AUTO auto2.tap - use "... -irlen 6" -no gdb ports allocated as no target has been specified -@end example - -Given that information, you should be able to either find some existing -config files to use, or create your own. If you create your own, you -would configure from the bottom up: first a @file{target.cfg} file -with these TAPs, any targets associated with them, and any on-chip -resources; then a @file{board.cfg} with off-chip resources, clocking, -and so forth. - -@node CPU Configuration -@chapter CPU Configuration -@cindex GDB target - -This chapter discusses how to set up GDB debug targets for CPUs. -You can also access these targets without GDB -(@pxref{Architecture and Core Commands}, -and @ref{targetstatehandling,,Target State handling}) and -through various kinds of NAND and NOR flash commands. -If you have multiple CPUs you can have multiple such targets. - -We'll start by looking at how to examine the targets you have, -then look at how to add one more target and how to configure it. - -@section Target List -@cindex target, current -@cindex target, list - -All targets that have been set up are part of a list, -where each member has a name. -That name should normally be the same as the TAP name. -You can display the list with the @command{targets} -(plural!) command. -This display often has only one CPU; here's what it might -look like with more than one: -@verbatim - TargetName Type Endian TapName State --- ------------------ ---------- ------ ------------------ ------------ - 0* at91rm9200.cpu arm920t little at91rm9200.cpu running - 1 MyTarget cortex_m little mychip.foo tap-disabled -@end verbatim - -One member of that list is the @dfn{current target}, which -is implicitly referenced by many commands. -It's the one marked with a @code{*} near the target name. -In particular, memory addresses often refer to the address -space seen by that current target. -Commands like @command{mdw} (memory display words) -and @command{flash erase_address} (erase NOR flash blocks) -are examples; and there are many more. - -Several commands let you examine the list of targets: - -@deffn Command {target current} -Returns the name of the current target. -@end deffn - -@deffn Command {target names} -Lists the names of all current targets in the list. -@example -foreach t [target names] @{ - puts [format "Target: %s\n" $t] -@} -@end example -@end deffn - -@c yep, "target list" would have been better. -@c plus maybe "target setdefault". - -@deffn Command targets [name] -@emph{Note: the name of this command is plural. Other target -command names are singular.} - -With no parameter, this command displays a table of all known -targets in a user friendly form. - -With a parameter, this command sets the current target to -the given target with the given @var{name}; this is -only relevant on boards which have more than one target. -@end deffn - -@section Target CPU Types -@cindex target type -@cindex CPU type - -Each target has a @dfn{CPU type}, as shown in the output of -the @command{targets} command. You need to specify that type -when calling @command{target create}. -The CPU type indicates more than just the instruction set. -It also indicates how that instruction set is implemented, -what kind of debug support it integrates, -whether it has an MMU (and if so, what kind), -what core-specific commands may be available -(@pxref{Architecture and Core Commands}), -and more. - -It's easy to see what target types are supported, -since there's a command to list them. - -@anchor{targettypes} -@deffn Command {target types} -Lists all supported target types. -At this writing, the supported CPU types are: - -@itemize @bullet -@item @code{arm11} -- this is a generation of ARMv6 cores -@item @code{arm720t} -- this is an ARMv4 core with an MMU -@item @code{arm7tdmi} -- this is an ARMv4 core -@item @code{arm920t} -- this is an ARMv4 core with an MMU -@item @code{arm926ejs} -- this is an ARMv5 core with an MMU -@item @code{arm966e} -- this is an ARMv5 core -@item @code{arm9tdmi} -- this is an ARMv4 core -@item @code{avr} -- implements Atmel's 8-bit AVR instruction set. -(Support for this is preliminary and incomplete.) -@item @code{cortex_a} -- this is an ARMv7 core with an MMU -@item @code{cortex_m} -- this is an ARMv7 core, supporting only the -compact Thumb2 instruction set. -@item @code{dragonite} -- resembles arm966e -@item @code{dsp563xx} -- implements Freescale's 24-bit DSP. -(Support for this is still incomplete.) -@item @code{fa526} -- resembles arm920 (w/o Thumb) -@item @code{feroceon} -- resembles arm926 -@item @code{mips_m4k} -- a MIPS core -@item @code{xscale} -- this is actually an architecture, -not a CPU type. It is based on the ARMv5 architecture. -@item @code{openrisc} -- this is an OpenRISC 1000 core. -The current implementation supports three JTAG TAP cores: -@item @code{ls1_sap} -- this is the SAP on NXP LS102x CPUs, -allowing access to physical memory addresses independently of CPU cores. -@itemize @minus -@item @code{OpenCores TAP} (See: @url{http://opencores.org/project,jtag}) -@item @code{Altera Virtual JTAG TAP} (See: @url{http://www.altera.com/literature/ug/ug_virtualjtag.pdf}) -@item @code{Xilinx BSCAN_* virtual JTAG interface} (See: @url{http://www.xilinx.com/support/documentation/sw_manuals/xilinx14_2/spartan6_hdl.pdf}) -@end itemize -And two debug interfaces cores: -@itemize @minus -@item @code{Advanced debug interface} (See: @url{http://opencores.org/project,adv_debug_sys}) -@item @code{SoC Debug Interface} (See: @url{http://opencores.org/project,dbg_interface}) -@end itemize -@end itemize -@end deffn - -To avoid being confused by the variety of ARM based cores, remember -this key point: @emph{ARM is a technology licencing company}. -(See: @url{http://www.arm.com}.) -The CPU name used by OpenOCD will reflect the CPU design that was -licenced, not a vendor brand which incorporates that design. -Name prefixes like arm7, arm9, arm11, and cortex -reflect design generations; -while names like ARMv4, ARMv5, ARMv6, and ARMv7 -reflect an architecture version implemented by a CPU design. - -@anchor{targetconfiguration} -@section Target Configuration - -Before creating a ``target'', you must have added its TAP to the scan chain. -When you've added that TAP, you will have a @code{dotted.name} -which is used to set up the CPU support. -The chip-specific configuration file will normally configure its CPU(s) -right after it adds all of the chip's TAPs to the scan chain. - -Although you can set up a target in one step, it's often clearer if you -use shorter commands and do it in two steps: create it, then configure -optional parts. -All operations on the target after it's created will use a new -command, created as part of target creation. - -The two main things to configure after target creation are -a work area, which usually has target-specific defaults even -if the board setup code overrides them later; -and event handlers (@pxref{targetevents,,Target Events}), which tend -to be much more board-specific. -The key steps you use might look something like this - -@example -target create MyTarget cortex_m -chain-position mychip.cpu -$MyTarget configure -work-area-phys 0x08000 -work-area-size 8096 -$MyTarget configure -event reset-deassert-pre @{ jtag_rclk 5 @} -$MyTarget configure -event reset-init @{ myboard_reinit @} -@end example - -You should specify a working area if you can; typically it uses some -on-chip SRAM. -Such a working area can speed up many things, including bulk -writes to target memory; -flash operations like checking to see if memory needs to be erased; -GDB memory checksumming; -and more. - -@quotation Warning -On more complex chips, the work area can become -inaccessible when application code -(such as an operating system) -enables or disables the MMU. -For example, the particular MMU context used to acess the virtual -address will probably matter ... and that context might not have -easy access to other addresses needed. -At this writing, OpenOCD doesn't have much MMU intelligence. -@end quotation - -It's often very useful to define a @code{reset-init} event handler. -For systems that are normally used with a boot loader, -common tasks include updating clocks and initializing memory -controllers. -That may be needed to let you write the boot loader into flash, -in order to ``de-brick'' your board; or to load programs into -external DDR memory without having run the boot loader. - -@deffn Command {target create} target_name type configparams... -This command creates a GDB debug target that refers to a specific JTAG tap. -It enters that target into a list, and creates a new -command (@command{@var{target_name}}) which is used for various -purposes including additional configuration. - -@itemize @bullet -@item @var{target_name} ... is the name of the debug target. -By convention this should be the same as the @emph{dotted.name} -of the TAP associated with this target, which must be specified here -using the @code{-chain-position @var{dotted.name}} configparam. - -This name is also used to create the target object command, -referred to here as @command{$target_name}, -and in other places the target needs to be identified. -@item @var{type} ... specifies the target type. @xref{targettypes,,target types}. -@item @var{configparams} ... all parameters accepted by -@command{$target_name configure} are permitted. -If the target is big-endian, set it here with @code{-endian big}. - -You @emph{must} set the @code{-chain-position @var{dotted.name}} here. -@end itemize -@end deffn - -@deffn Command {$target_name configure} configparams... -The options accepted by this command may also be -specified as parameters to @command{target create}. -Their values can later be queried one at a time by -using the @command{$target_name cget} command. - -@emph{Warning:} changing some of these after setup is dangerous. -For example, moving a target from one TAP to another; -and changing its endianness. - -@itemize @bullet - -@item @code{-chain-position} @var{dotted.name} -- names the TAP -used to access this target. - -@item @code{-endian} (@option{big}|@option{little}) -- specifies -whether the CPU uses big or little endian conventions - -@item @code{-event} @var{event_name} @var{event_body} -- -@xref{targetevents,,Target Events}. -Note that this updates a list of named event handlers. -Calling this twice with two different event names assigns -two different handlers, but calling it twice with the -same event name assigns only one handler. - -@item @code{-work-area-backup} (@option{0}|@option{1}) -- says -whether the work area gets backed up; by default, -@emph{it is not backed up.} -When possible, use a working_area that doesn't need to be backed up, -since performing a backup slows down operations. -For example, the beginning of an SRAM block is likely to -be used by most build systems, but the end is often unused. - -@item @code{-work-area-size} @var{size} -- specify work are size, -in bytes. The same size applies regardless of whether its physical -or virtual address is being used. - -@item @code{-work-area-phys} @var{address} -- set the work area -base @var{address} to be used when no MMU is active. - -@item @code{-work-area-virt} @var{address} -- set the work area -base @var{address} to be used when an MMU is active. -@emph{Do not specify a value for this except on targets with an MMU.} -The value should normally correspond to a static mapping for the -@code{-work-area-phys} address, set up by the current operating system. - -@anchor{rtostype} -@item @code{-rtos} @var{rtos_type} -- enable rtos support for target, -@var{rtos_type} can be one of @option{auto}|@option{eCos}|@option{ThreadX}| -@option{FreeRTOS}|@option{linux}|@option{ChibiOS}|@option{embKernel}|@option{mqx} -@xref{gdbrtossupport,,RTOS Support}. - -@end itemize -@end deffn - -@section Other $target_name Commands -@cindex object command - -The Tcl/Tk language has the concept of object commands, -and OpenOCD adopts that same model for targets. - -A good Tk example is a on screen button. -Once a button is created a button -has a name (a path in Tk terms) and that name is useable as a first -class command. For example in Tk, one can create a button and later -configure it like this: - -@example -# Create -button .foobar -background red -command @{ foo @} -# Modify -.foobar configure -foreground blue -# Query -set x [.foobar cget -background] -# Report -puts [format "The button is %s" $x] -@end example - -In OpenOCD's terms, the ``target'' is an object just like a Tcl/Tk -button, and its object commands are invoked the same way. - -@example -str912.cpu mww 0x1234 0x42 -omap3530.cpu mww 0x5555 123 -@end example - -The commands supported by OpenOCD target objects are: - -@deffn Command {$target_name arp_examine} -@deffnx Command {$target_name arp_halt} -@deffnx Command {$target_name arp_poll} -@deffnx Command {$target_name arp_reset} -@deffnx Command {$target_name arp_waitstate} -Internal OpenOCD scripts (most notably @file{startup.tcl}) -use these to deal with specific reset cases. -They are not otherwise documented here. -@end deffn - -@deffn Command {$target_name array2mem} arrayname width address count -@deffnx Command {$target_name mem2array} arrayname width address count -These provide an efficient script-oriented interface to memory. -The @code{array2mem} primitive writes bytes, halfwords, or words; -while @code{mem2array} reads them. -In both cases, the TCL side uses an array, and -the target side uses raw memory. - -The efficiency comes from enabling the use of -bulk JTAG data transfer operations. -The script orientation comes from working with data -values that are packaged for use by TCL scripts; -@command{mdw} type primitives only print data they retrieve, -and neither store nor return those values. - -@itemize -@item @var{arrayname} ... is the name of an array variable -@item @var{width} ... is 8/16/32 - indicating the memory access size -@item @var{address} ... is the target memory address -@item @var{count} ... is the number of elements to process -@end itemize -@end deffn - -@deffn Command {$target_name cget} queryparm -Each configuration parameter accepted by -@command{$target_name configure} -can be individually queried, to return its current value. -The @var{queryparm} is a parameter name -accepted by that command, such as @code{-work-area-phys}. -There are a few special cases: - -@itemize @bullet -@item @code{-event} @var{event_name} -- returns the handler for the -event named @var{event_name}. -This is a special case because setting a handler requires -two parameters. -@item @code{-type} -- returns the target type. -This is a special case because this is set using -@command{target create} and can't be changed -using @command{$target_name configure}. -@end itemize - -For example, if you wanted to summarize information about -all the targets you might use something like this: - -@example -foreach name [target names] @{ - set y [$name cget -endian] - set z [$name cget -type] - puts [format "Chip %d is %s, Endian: %s, type: %s" \ - $x $name $y $z] -@} -@end example -@end deffn - -@anchor{targetcurstate} -@deffn Command {$target_name curstate} -Displays the current target state: -@code{debug-running}, -@code{halted}, -@code{reset}, -@code{running}, or @code{unknown}. -(Also, @pxref{eventpolling,,Event Polling}.) -@end deffn - -@deffn Command {$target_name eventlist} -Displays a table listing all event handlers -currently associated with this target. -@xref{targetevents,,Target Events}. -@end deffn - -@deffn Command {$target_name invoke-event} event_name -Invokes the handler for the event named @var{event_name}. -(This is primarily intended for use by OpenOCD framework -code, for example by the reset code in @file{startup.tcl}.) -@end deffn - -@deffn Command {$target_name mdw} addr [count] -@deffnx Command {$target_name mdh} addr [count] -@deffnx Command {$target_name mdb} addr [count] -Display contents of address @var{addr}, as -32-bit words (@command{mdw}), 16-bit halfwords (@command{mdh}), -or 8-bit bytes (@command{mdb}). -If @var{count} is specified, displays that many units. -(If you want to manipulate the data instead of displaying it, -see the @code{mem2array} primitives.) -@end deffn - -@deffn Command {$target_name mww} addr word -@deffnx Command {$target_name mwh} addr halfword -@deffnx Command {$target_name mwb} addr byte -Writes the specified @var{word} (32 bits), -@var{halfword} (16 bits), or @var{byte} (8-bit) pattern, -at the specified address @var{addr}. -@end deffn - -@anchor{targetevents} -@section Target Events -@cindex target events -@cindex events -At various times, certain things can happen, or you want them to happen. -For example: -@itemize @bullet -@item What should happen when GDB connects? Should your target reset? -@item When GDB tries to flash the target, do you need to enable the flash via a special command? -@item Is using SRST appropriate (and possible) on your system? -Or instead of that, do you need to issue JTAG commands to trigger reset? -SRST usually resets everything on the scan chain, which can be inappropriate. -@item During reset, do you need to write to certain memory locations -to set up system clocks or -to reconfigure the SDRAM? -How about configuring the watchdog timer, or other peripherals, -to stop running while you hold the core stopped for debugging? -@end itemize - -All of the above items can be addressed by target event handlers. -These are set up by @command{$target_name configure -event} or -@command{target create ... -event}. - -The programmer's model matches the @code{-command} option used in Tcl/Tk -buttons and events. The two examples below act the same, but one creates -and invokes a small procedure while the other inlines it. - -@example -proc my_attach_proc @{ @} @{ - echo "Reset..." - reset halt -@} -mychip.cpu configure -event gdb-attach my_attach_proc -mychip.cpu configure -event gdb-attach @{ - echo "Reset..." - # To make flash probe and gdb load to flash work - # we need a reset init. - reset init -@} -@end example - -The following target events are defined: - -@itemize @bullet -@item @b{debug-halted} -@* The target has halted for debug reasons (i.e.: breakpoint) -@item @b{debug-resumed} -@* The target has resumed (i.e.: gdb said run) -@item @b{early-halted} -@* Occurs early in the halt process -@item @b{examine-start} -@* Before target examine is called. -@item @b{examine-end} -@* After target examine is called with no errors. -@item @b{gdb-attach} -@* When GDB connects. This is before any communication with the target, so this -can be used to set up the target so it is possible to probe flash. Probing flash -is necessary during gdb connect if gdb load is to write the image to flash. Another -use of the flash memory map is for GDB to automatically hardware/software breakpoints -depending on whether the breakpoint is in RAM or read only memory. -@item @b{gdb-detach} -@* When GDB disconnects -@item @b{gdb-end} -@* When the target has halted and GDB is not doing anything (see early halt) -@item @b{gdb-flash-erase-start} -@* Before the GDB flash process tries to erase the flash (default is -@code{reset init}) -@item @b{gdb-flash-erase-end} -@* After the GDB flash process has finished erasing the flash -@item @b{gdb-flash-write-start} -@* Before GDB writes to the flash -@item @b{gdb-flash-write-end} -@* After GDB writes to the flash (default is @code{reset halt}) -@item @b{gdb-start} -@* Before the target steps, gdb is trying to start/resume the target -@item @b{halted} -@* The target has halted -@item @b{reset-assert-pre} -@* Issued as part of @command{reset} processing -after @command{reset_init} was triggered -but before either SRST alone is re-asserted on the scan chain, -or @code{reset-assert} is triggered. -@item @b{reset-assert} -@* Issued as part of @command{reset} processing -after @command{reset-assert-pre} was triggered. -When such a handler is present, cores which support this event will use -it instead of asserting SRST. -This support is essential for debugging with JTAG interfaces which -don't include an SRST line (JTAG doesn't require SRST), and for -selective reset on scan chains that have multiple targets. -@item @b{reset-assert-post} -@* Issued as part of @command{reset} processing -after @code{reset-assert} has been triggered. -or the target asserted SRST on the entire scan chain. -@item @b{reset-deassert-pre} -@* Issued as part of @command{reset} processing -after @code{reset-assert-post} has been triggered. -@item @b{reset-deassert-post} -@* Issued as part of @command{reset} processing -after @code{reset-deassert-pre} has been triggered -and (if the target is using it) after SRST has been -released on the scan chain. -@item @b{reset-end} -@* Issued as the final step in @command{reset} processing. -@ignore -@item @b{reset-halt-post} -@* Currently not used -@item @b{reset-halt-pre} -@* Currently not used -@end ignore -@item @b{reset-init} -@* Used by @b{reset init} command for board-specific initialization. -This event fires after @emph{reset-deassert-post}. - -This is where you would configure PLLs and clocking, set up DRAM so -you can download programs that don't fit in on-chip SRAM, set up pin -multiplexing, and so on. -(You may be able to switch to a fast JTAG clock rate here, after -the target clocks are fully set up.) -@item @b{reset-start} -@* Issued as part of @command{reset} processing -before @command{reset_init} is called. - -This is the most robust place to use @command{jtag_rclk} -or @command{adapter_khz} to switch to a low JTAG clock rate, -when reset disables PLLs needed to use a fast clock. -@ignore -@item @b{reset-wait-pos} -@* Currently not used -@item @b{reset-wait-pre} -@* Currently not used -@end ignore -@item @b{resume-start} -@* Before any target is resumed -@item @b{resume-end} -@* After all targets have resumed -@item @b{resumed} -@* Target has resumed -@item @b{trace-config} -@* After target hardware trace configuration was changed -@end itemize - -@node Flash Commands -@chapter Flash Commands - -OpenOCD has different commands for NOR and NAND flash; -the ``flash'' command works with NOR flash, while -the ``nand'' command works with NAND flash. -This partially reflects different hardware technologies: -NOR flash usually supports direct CPU instruction and data bus access, -while data from a NAND flash must be copied to memory before it can be -used. (SPI flash must also be copied to memory before use.) -However, the documentation also uses ``flash'' as a generic term; -for example, ``Put flash configuration in board-specific files''. - -Flash Steps: -@enumerate -@item Configure via the command @command{flash bank} -@* Do this in a board-specific configuration file, -passing parameters as needed by the driver. -@item Operate on the flash via @command{flash subcommand} -@* Often commands to manipulate the flash are typed by a human, or run -via a script in some automated way. Common tasks include writing a -boot loader, operating system, or other data. -@item GDB Flashing -@* Flashing via GDB requires the flash be configured via ``flash -bank'', and the GDB flash features be enabled. -@xref{gdbconfiguration,,GDB Configuration}. -@end enumerate - -Many CPUs have the ablity to ``boot'' from the first flash bank. -This means that misprogramming that bank can ``brick'' a system, -so that it can't boot. -JTAG tools, like OpenOCD, are often then used to ``de-brick'' the -board by (re)installing working boot firmware. - -@anchor{norconfiguration} -@section Flash Configuration Commands -@cindex flash configuration - -@deffn {Config Command} {flash bank} name driver base size chip_width bus_width target [driver_options] -Configures a flash bank which provides persistent storage -for addresses from @math{base} to @math{base + size - 1}. -These banks will often be visible to GDB through the target's memory map. -In some cases, configuring a flash bank will activate extra commands; -see the driver-specific documentation. - -@itemize @bullet -@item @var{name} ... may be used to reference the flash bank -in other flash commands. A number is also available. -@item @var{driver} ... identifies the controller driver -associated with the flash bank being declared. -This is usually @code{cfi} for external flash, or else -the name of a microcontroller with embedded flash memory. -@xref{flashdriverlist,,Flash Driver List}. -@item @var{base} ... Base address of the flash chip. -@item @var{size} ... Size of the chip, in bytes. -For some drivers, this value is detected from the hardware. -@item @var{chip_width} ... Width of the flash chip, in bytes; -ignored for most microcontroller drivers. -@item @var{bus_width} ... Width of the data bus used to access the -chip, in bytes; ignored for most microcontroller drivers. -@item @var{target} ... Names the target used to issue -commands to the flash controller. -@comment Actually, it's currently a controller-specific parameter... -@item @var{driver_options} ... drivers may support, or require, -additional parameters. See the driver-specific documentation -for more information. -@end itemize -@quotation Note -This command is not available after OpenOCD initialization has completed. -Use it in board specific configuration files, not interactively. -@end quotation -@end deffn - -@comment the REAL name for this command is "ocd_flash_banks" -@comment less confusing would be: "flash list" (like "nand list") -@deffn Command {flash banks} -Prints a one-line summary of each device that was -declared using @command{flash bank}, numbered from zero. -Note that this is the @emph{plural} form; -the @emph{singular} form is a very different command. -@end deffn - -@deffn Command {flash list} -Retrieves a list of associative arrays for each device that was -declared using @command{flash bank}, numbered from zero. -This returned list can be manipulated easily from within scripts. -@end deffn - -@deffn Command {flash probe} num -Identify the flash, or validate the parameters of the configured flash. Operation -depends on the flash type. -The @var{num} parameter is a value shown by @command{flash banks}. -Most flash commands will implicitly @emph{autoprobe} the bank; -flash drivers can distinguish between probing and autoprobing, -but most don't bother. -@end deffn - -@section Erasing, Reading, Writing to Flash -@cindex flash erasing -@cindex flash reading -@cindex flash writing -@cindex flash programming -@anchor{flashprogrammingcommands} - -One feature distinguishing NOR flash from NAND or serial flash technologies -is that for read access, it acts exactly like any other addressible memory. -This means you can use normal memory read commands like @command{mdw} or -@command{dump_image} with it, with no special @command{flash} subcommands. -@xref{memoryaccess,,Memory access}, and @ref{imageaccess,,Image access}. - -Write access works differently. Flash memory normally needs to be erased -before it's written. Erasing a sector turns all of its bits to ones, and -writing can turn ones into zeroes. This is why there are special commands -for interactive erasing and writing, and why GDB needs to know which parts -of the address space hold NOR flash memory. - -@quotation Note -Most of these erase and write commands leverage the fact that NOR flash -chips consume target address space. They implicitly refer to the current -JTAG target, and map from an address in that target's address space -back to a flash bank. -@comment In May 2009, those mappings may fail if any bank associated -@comment with that target doesn't succesfuly autoprobe ... bug worth fixing? -A few commands use abstract addressing based on bank and sector numbers, -and don't depend on searching the current target and its address space. -Avoid confusing the two command models. -@end quotation - -Some flash chips implement software protection against accidental writes, -since such buggy writes could in some cases ``brick'' a system. -For such systems, erasing and writing may require sector protection to be -disabled first. -Examples include CFI flash such as ``Intel Advanced Bootblock flash'', -and AT91SAM7 on-chip flash. -@xref{flashprotect,,flash protect}. - -@deffn Command {flash erase_sector} num first last -Erase sectors in bank @var{num}, starting at sector @var{first} -up to and including @var{last}. -Sector numbering starts at 0. -Providing a @var{last} sector of @option{last} -specifies "to the end of the flash bank". -The @var{num} parameter is a value shown by @command{flash banks}. -@end deffn - -@deffn Command {flash erase_address} [@option{pad}] [@option{unlock}] address length -Erase sectors starting at @var{address} for @var{length} bytes. -Unless @option{pad} is specified, @math{address} must begin a -flash sector, and @math{address + length - 1} must end a sector. -Specifying @option{pad} erases extra data at the beginning and/or -end of the specified region, as needed to erase only full sectors. -The flash bank to use is inferred from the @var{address}, and -the specified length must stay within that bank. -As a special case, when @var{length} is zero and @var{address} is -the start of the bank, the whole flash is erased. -If @option{unlock} is specified, then the flash is unprotected -before erase starts. -@end deffn - -@deffn Command {flash fillw} address word length -@deffnx Command {flash fillh} address halfword length -@deffnx Command {flash fillb} address byte length -Fills flash memory with the specified @var{word} (32 bits), -@var{halfword} (16 bits), or @var{byte} (8-bit) pattern, -starting at @var{address} and continuing -for @var{length} units (word/halfword/byte). -No erasure is done before writing; when needed, that must be done -before issuing this command. -Writes are done in blocks of up to 1024 bytes, and each write is -verified by reading back the data and comparing it to what was written. -The flash bank to use is inferred from the @var{address} of -each block, and the specified length must stay within that bank. -@end deffn -@comment no current checks for errors if fill blocks touch multiple banks! - -@deffn Command {flash write_bank} num filename offset -Write the binary @file{filename} to flash bank @var{num}, -starting at @var{offset} bytes from the beginning of the bank. -The @var{num} parameter is a value shown by @command{flash banks}. -@end deffn - -@deffn Command {flash read_bank} num filename offset length -Read @var{length} bytes from the flash bank @var{num} starting at @var{offset} -and write the contents to the binary @file{filename}. -The @var{num} parameter is a value shown by @command{flash banks}. -@end deffn - -@deffn Command {flash verify_bank} num filename offset -Compare the contents of the binary file @var{filename} with the contents of the -flash @var{num} starting at @var{offset}. Fails if the contents do not match. -The @var{num} parameter is a value shown by @command{flash banks}. -@end deffn - -@deffn Command {flash write_image} [erase] [unlock] filename [offset] [type] -Write the image @file{filename} to the current target's flash bank(s). -Only loadable sections from the image are written. -A relocation @var{offset} may be specified, in which case it is added -to the base address for each section in the image. -The file [@var{type}] can be specified -explicitly as @option{bin} (binary), @option{ihex} (Intel hex), -@option{elf} (ELF file), @option{s19} (Motorola s19). -@option{mem}, or @option{builder}. -The relevant flash sectors will be erased prior to programming -if the @option{erase} parameter is given. If @option{unlock} is -provided, then the flash banks are unlocked before erase and -program. The flash bank to use is inferred from the address of -each image section. - -@quotation Warning -Be careful using the @option{erase} flag when the flash is holding -data you want to preserve. -Portions of the flash outside those described in the image's -sections might be erased with no notice. -@itemize -@item -When a section of the image being written does not fill out all the -sectors it uses, the unwritten parts of those sectors are necessarily -also erased, because sectors can't be partially erased. -@item -Data stored in sector "holes" between image sections are also affected. -For example, "@command{flash write_image erase ...}" of an image with -one byte at the beginning of a flash bank and one byte at the end -erases the entire bank -- not just the two sectors being written. -@end itemize -Also, when flash protection is important, you must re-apply it after -it has been removed by the @option{unlock} flag. -@end quotation - -@end deffn - -@section Other Flash commands -@cindex flash protection - -@deffn Command {flash erase_check} num -Check erase state of sectors in flash bank @var{num}, -and display that status. -The @var{num} parameter is a value shown by @command{flash banks}. -@end deffn - -@deffn Command {flash info} num [sectors] -Print info about flash bank @var{num}, a list of protection blocks -and their status. Use @option{sectors} to show a list of sectors instead. - -The @var{num} parameter is a value shown by @command{flash banks}. -This command will first query the hardware, it does not print cached -and possibly stale information. -@end deffn - -@anchor{flashprotect} -@deffn Command {flash protect} num first last (@option{on}|@option{off}) -Enable (@option{on}) or disable (@option{off}) protection of flash sectors -in flash bank @var{num}, starting at sector @var{first} -and continuing up to and including @var{last}. -Providing a @var{last} sector of @option{last} -specifies "to the end of the flash bank". -The @var{num} parameter is a value shown by @command{flash banks}. -@end deffn - -@deffn Command {flash padded_value} num value -Sets the default value used for padding any image sections, This should -normally match the flash bank erased value. If not specified by this -comamnd or the flash driver then it defaults to 0xff. -@end deffn - -@anchor{program} -@deffn Command {program} filename [verify] [reset] [exit] [offset] -This is a helper script that simplifies using OpenOCD as a standalone -programmer. The only required parameter is @option{filename}, the others are optional. -@xref{Flash Programming}. -@end deffn - -@anchor{flashdriverlist} -@section Flash Driver List -As noted above, the @command{flash bank} command requires a driver name, -and allows driver-specific options and behaviors. -Some drivers also activate driver-specific commands. - -@deffn {Flash Driver} virtual -This is a special driver that maps a previously defined bank to another -address. All bank settings will be copied from the master physical bank. - -The @var{virtual} driver defines one mandatory parameters, - -@itemize -@item @var{master_bank} The bank that this virtual address refers to. -@end itemize - -So in the following example addresses 0xbfc00000 and 0x9fc00000 refer to -the flash bank defined at address 0x1fc00000. Any cmds executed on -the virtual banks are actually performed on the physical banks. -@example -flash bank $_FLASHNAME pic32mx 0x1fc00000 0 0 0 $_TARGETNAME -flash bank vbank0 virtual 0xbfc00000 0 0 0 $_TARGETNAME $_FLASHNAME -flash bank vbank1 virtual 0x9fc00000 0 0 0 $_TARGETNAME $_FLASHNAME -@end example -@end deffn - -@subsection External Flash - -@deffn {Flash Driver} cfi -@cindex Common Flash Interface -@cindex CFI -The ``Common Flash Interface'' (CFI) is the main standard for -external NOR flash chips, each of which connects to a -specific external chip select on the CPU. -Frequently the first such chip is used to boot the system. -Your board's @code{reset-init} handler might need to -configure additional chip selects using other commands (like: @command{mww} to -configure a bus and its timings), or -perhaps configure a GPIO pin that controls the ``write protect'' pin -on the flash chip. -The CFI driver can use a target-specific working area to significantly -speed up operation. - -The CFI driver can accept the following optional parameters, in any order: - -@itemize -@item @var{jedec_probe} ... is used to detect certain non-CFI flash ROMs, -like AM29LV010 and similar types. -@item @var{x16_as_x8} ... when a 16-bit flash is hooked up to an 8-bit bus. -@item @var{bus_swap} ... when data bytes in a 16-bit flash needs to be swapped. -@item @var{data_swap} ... when data bytes in a 16-bit flash needs to be -swapped when writing data values (ie. not CFI commands). -@end itemize - -To configure two adjacent banks of 16 MBytes each, both sixteen bits (two bytes) -wide on a sixteen bit bus: - -@example -flash bank $_FLASHNAME cfi 0x00000000 0x01000000 2 2 $_TARGETNAME -flash bank $_FLASHNAME cfi 0x01000000 0x01000000 2 2 $_TARGETNAME -@end example - -To configure one bank of 32 MBytes -built from two sixteen bit (two byte) wide parts wired in parallel -to create a thirty-two bit (four byte) bus with doubled throughput: - -@example -flash bank $_FLASHNAME cfi 0x00000000 0x02000000 2 4 $_TARGETNAME -@end example - -@c "cfi part_id" disabled -@end deffn - -@deffn {Flash Driver} jtagspi -@cindex Generic JTAG2SPI driver -@cindex SPI -@cindex jtagspi -@cindex bscan_spi -Several FPGAs and CPLDs can retrieve their configuration (bitstream) from a -SPI flash connected to them. To access this flash from the host, the device -is first programmed with a special proxy bitstream that -exposes the SPI flash on the device's JTAG interface. The flash can then be -accessed through JTAG. - -Since signaling between JTAG and SPI is compatible, all that is required for -a proxy bitstream is to connect TDI-MOSI, TDO-MISO, TCK-CLK and activate -the flash chip select when the JTAG state machine is in SHIFT-DR. Such -a bitstream for several Xilinx FPGAs can be found in -@file{contrib/loaders/flash/fpga/xilinx_bscan_spi.py}. It requires migen -(@url{http://github.com/m-labs/migen}) and a Xilinx toolchain to build. - -This flash bank driver requires a target on a JTAG tap and will access that -tap directly. Since no support from the target is needed, the target can be a -"testee" dummy. Since the target does not expose the flash memory -mapping, target commands that would otherwise be expected to access the flash -will not work. These include all @command{*_image} and -@command{$target_name m*} commands as well as @command{program}. Equivalent -functionality is available through the @command{flash write_bank}, -@command{flash read_bank}, and @command{flash verify_bank} commands. - -@itemize -@item @var{ir} ... is loaded into the JTAG IR to map the flash as the JTAG DR. -For the bitstreams generated from @file{xilinx_bscan_spi.py} this is the -@var{USER1} instruction. -@item @var{dr_length} ... is the length of the DR register. This will be 1 for -@file{xilinx_bscan_spi.py} bitstreams and most other cases. -@end itemize - -@example -target create $_TARGETNAME testee -chain-position $_CHIPNAME.fpga -set _XILINX_USER1 0x02 -set _DR_LENGTH 1 -flash bank $_FLASHNAME spi 0x0 0 0 0 $_TARGETNAME $_XILINX_USER1 $_DR_LENGTH -@end example -@end deffn - -@deffn {Flash Driver} lpcspifi -@cindex NXP SPI Flash Interface -@cindex SPIFI -@cindex lpcspifi -NXP's LPC43xx and LPC18xx families include a proprietary SPI -Flash Interface (SPIFI) peripheral that can drive and provide -memory mapped access to external SPI flash devices. - -The lpcspifi driver initializes this interface and provides -program and erase functionality for these serial flash devices. -Use of this driver @b{requires} a working area of at least 1kB -to be configured on the target device; more than this will -significantly reduce flash programming times. - -The setup command only requires the @var{base} parameter. All -other parameters are ignored, and the flash size and layout -are configured by the driver. - -@example -flash bank $_FLASHNAME lpcspifi 0x14000000 0 0 0 $_TARGETNAME -@end example - -@end deffn - -@deffn {Flash Driver} stmsmi -@cindex STMicroelectronics Serial Memory Interface -@cindex SMI -@cindex stmsmi -Some devices form STMicroelectronics (e.g. STR75x MCU family, -SPEAr MPU family) include a proprietary -``Serial Memory Interface'' (SMI) controller able to drive external -SPI flash devices. -Depending on specific device and board configuration, up to 4 external -flash devices can be connected. - -SMI makes the flash content directly accessible in the CPU address -space; each external device is mapped in a memory bank. -CPU can directly read data, execute code and boot from SMI banks. -Normal OpenOCD commands like @command{mdw} can be used to display -the flash content. - -The setup command only requires the @var{base} parameter in order -to identify the memory bank. -All other parameters are ignored. Additional information, like -flash size, are detected automatically. - -@example -flash bank $_FLASHNAME stmsmi 0xf8000000 0 0 0 $_TARGETNAME -@end example - -@end deffn - -@deffn {Flash Driver} mrvlqspi -This driver supports QSPI flash controller of Marvell's Wireless -Microcontroller platform. - -The flash size is autodetected based on the table of known JEDEC IDs -hardcoded in the OpenOCD sources. - -@example -flash bank $_FLASHNAME mrvlqspi 0x0 0 0 0 $_TARGETNAME 0x46010000 -@end example - -@end deffn - -@subsection Internal Flash (Microcontrollers) - -@deffn {Flash Driver} aduc702x -The ADUC702x analog microcontrollers from Analog Devices -include internal flash and use ARM7TDMI cores. -The aduc702x flash driver works with models ADUC7019 through ADUC7028. -The setup command only requires the @var{target} argument -since all devices in this family have the same memory layout. - -@example -flash bank $_FLASHNAME aduc702x 0 0 0 0 $_TARGETNAME -@end example -@end deffn - -@deffn {Flash Driver} ambiqmicro -@cindex ambiqmicro -@cindex apollo -All members of the Apollo microcontroller family from -Ambiq Micro include internal flash and use ARM's Cortex-M4 core. -The host connects over USB to an FTDI interface that communicates -with the target using SWD. - -The @var{ambiqmicro} driver reads the Chip Information Register detect -the device class of the MCU. -The Flash and Sram sizes directly follow device class, and are used -to set up the flash banks. -If this fails, the driver will use default values set to the minimum -sizes of an Apollo chip. - -All Apollo chips have two flash banks of the same size. -In all cases the first flash bank starts at location 0, -and the second bank starts after the first. - -@example -# Flash bank 0 -flash bank $_FLASHNAME ambiqmicro 0 0x00040000 0 0 $_TARGETNAME -# Flash bank 1 - same size as bank0, starts after bank 0. -flash bank $_FLASHNAME ambiqmicro 0x00040000 0x00040000 0 0 $_TARGETNAME -@end example - -Flash is programmed using custom entry points into the bootloader. -This is the only way to program the flash as no flash control registers -are available to the user. - -The @var{ambiqmicro} driver adds some additional commands: - -@deffn Command {ambiqmicro mass_erase} -Erase entire bank. -@end deffn -@deffn Command {ambiqmicro page_erase} -Erase device pages. -@end deffn -@deffn Command {ambiqmicro program_otp} -Program OTP is a one time operation to create write protected flash. -The user writes sectors to sram starting at 0x10000010. -Program OTP will write these sectors from sram to flash, and write protect -the flash. -@end deffn -@end deffn - -@anchor{at91samd} -@deffn {Flash Driver} at91samd -@cindex at91samd -All members of the ATSAMD, ATSAMR, ATSAML and ATSAMC microcontroller -families from Atmel include internal flash and use ARM's Cortex-M0+ core. -This driver uses the same cmd names/syntax as @xref{at91sam3}. - -@deffn Command {at91samd chip-erase} -Issues a complete Flash erase via the Device Service Unit (DSU). This can be -used to erase a chip back to its factory state and does not require the -processor to be halted. -@end deffn - -@deffn Command {at91samd set-security} -Secures the Flash via the Set Security Bit (SSB) command. This prevents access -to the Flash and can only be undone by using the chip-erase command which -erases the Flash contents and turns off the security bit. Warning: at this -time, openocd will not be able to communicate with a secured chip and it is -therefore not possible to chip-erase it without using another tool. - -@example -at91samd set-security enable -@end example -@end deffn - -@deffn Command {at91samd eeprom} -Shows or sets the EEPROM emulation size configuration, stored in the User Row -of the Flash. When setting, the EEPROM size must be specified in bytes and it -must be one of the permitted sizes according to the datasheet. Settings are -written immediately but only take effect on MCU reset. EEPROM emulation -requires additional firmware support and the minumum EEPROM size may not be -the same as the minimum that the hardware supports. Set the EEPROM size to 0 -in order to disable this feature. - -@example -at91samd eeprom -at91samd eeprom 1024 -@end example -@end deffn - -@deffn Command {at91samd bootloader} -Shows or sets the bootloader size configuration, stored in the User Row of the -Flash. This is called the BOOTPROT region. When setting, the bootloader size -must be specified in bytes and it must be one of the permitted sizes according -to the datasheet. Settings are written immediately but only take effect on -MCU reset. Setting the bootloader size to 0 disables bootloader protection. - -@example -at91samd bootloader -at91samd bootloader 16384 -@end example -@end deffn - -@deffn Command {at91samd dsu_reset_deassert} -This command releases internal reset held by DSU -and prepares reset vector catch in case of reset halt. -Command is used internally in event event reset-deassert-post. -@end deffn - -@end deffn - -@anchor{at91sam3} -@deffn {Flash Driver} at91sam3 -@cindex at91sam3 -All members of the AT91SAM3 microcontroller family from -Atmel include internal flash and use ARM's Cortex-M3 core. The driver -currently (6/22/09) recognizes the AT91SAM3U[1/2/4][C/E] chips. Note -that the driver was orginaly developed and tested using the -AT91SAM3U4E, using a SAM3U-EK eval board. Support for other chips in -the family was cribbed from the data sheet. @emph{Note to future -readers/updaters: Please remove this worrysome comment after other -chips are confirmed.} - -The AT91SAM3U4[E/C] (256K) chips have two flash banks; most other chips -have one flash bank. In all cases the flash banks are at -the following fixed locations: - -@example -# Flash bank 0 - all chips -flash bank $_FLASHNAME at91sam3 0x00080000 0 1 1 $_TARGETNAME -# Flash bank 1 - only 256K chips -flash bank $_FLASHNAME at91sam3 0x00100000 0 1 1 $_TARGETNAME -@end example - -Internally, the AT91SAM3 flash memory is organized as follows. -Unlike the AT91SAM7 chips, these are not used as parameters -to the @command{flash bank} command: - -@itemize -@item @emph{N-Banks:} 256K chips have 2 banks, others have 1 bank. -@item @emph{Bank Size:} 128K/64K Per flash bank -@item @emph{Sectors:} 16 or 8 per bank -@item @emph{SectorSize:} 8K Per Sector -@item @emph{PageSize:} 256 bytes per page. Note that OpenOCD operates on 'sector' sizes, not page sizes. -@end itemize - -The AT91SAM3 driver adds some additional commands: - -@deffn Command {at91sam3 gpnvm} -@deffnx Command {at91sam3 gpnvm clear} number -@deffnx Command {at91sam3 gpnvm set} number -@deffnx Command {at91sam3 gpnvm show} [@option{all}|number] -With no parameters, @command{show} or @command{show all}, -shows the status of all GPNVM bits. -With @command{show} @var{number}, displays that bit. - -With @command{set} @var{number} or @command{clear} @var{number}, -modifies that GPNVM bit. -@end deffn - -@deffn Command {at91sam3 info} -This command attempts to display information about the AT91SAM3 -chip. @emph{First} it read the @code{CHIPID_CIDR} [address 0x400e0740, see -Section 28.2.1, page 505 of the AT91SAM3U 29/may/2009 datasheet, -document id: doc6430A] and decodes the values. @emph{Second} it reads the -various clock configuration registers and attempts to display how it -believes the chip is configured. By default, the SLOWCLK is assumed to -be 32768 Hz, see the command @command{at91sam3 slowclk}. -@end deffn - -@deffn Command {at91sam3 slowclk} [value] -This command shows/sets the slow clock frequency used in the -@command{at91sam3 info} command calculations above. -@end deffn -@end deffn - -@deffn {Flash Driver} at91sam4 -@cindex at91sam4 -All members of the AT91SAM4 microcontroller family from -Atmel include internal flash and use ARM's Cortex-M4 core. -This driver uses the same cmd names/syntax as @xref{at91sam3}. -@end deffn - -@deffn {Flash Driver} at91sam4l -@cindex at91sam4l -All members of the AT91SAM4L microcontroller family from -Atmel include internal flash and use ARM's Cortex-M4 core. -This driver uses the same cmd names/syntax as @xref{at91sam3}. - -The AT91SAM4L driver adds some additional commands: -@deffn Command {at91sam4l smap_reset_deassert} -This command releases internal reset held by SMAP -and prepares reset vector catch in case of reset halt. -Command is used internally in event event reset-deassert-post. -@end deffn -@end deffn - -@deffn {Flash Driver} atsamv -@cindex atsamv -All members of the ATSAMV, ATSAMS, and ATSAME families from -Atmel include internal flash and use ARM's Cortex-M7 core. -This driver uses the same cmd names/syntax as @xref{at91sam3}. -@end deffn - -@deffn {Flash Driver} at91sam7 -All members of the AT91SAM7 microcontroller family from Atmel include -internal flash and use ARM7TDMI cores. The driver automatically -recognizes a number of these chips using the chip identification -register, and autoconfigures itself. - -@example -flash bank $_FLASHNAME at91sam7 0 0 0 0 $_TARGETNAME -@end example - -For chips which are not recognized by the controller driver, you must -provide additional parameters in the following order: - -@itemize -@item @var{chip_model} ... label used with @command{flash info} -@item @var{banks} -@item @var{sectors_per_bank} -@item @var{pages_per_sector} -@item @var{pages_size} -@item @var{num_nvm_bits} -@item @var{freq_khz} ... required if an external clock is provided, -optional (but recommended) when the oscillator frequency is known -@end itemize - -It is recommended that you provide zeroes for all of those values -except the clock frequency, so that everything except that frequency -will be autoconfigured. -Knowing the frequency helps ensure correct timings for flash access. - -The flash controller handles erases automatically on a page (128/256 byte) -basis, so explicit erase commands are not necessary for flash programming. -However, there is an ``EraseAll`` command that can erase an entire flash -plane (of up to 256KB), and it will be used automatically when you issue -@command{flash erase_sector} or @command{flash erase_address} commands. - -@deffn Command {at91sam7 gpnvm} bitnum (@option{set}|@option{clear}) -Set or clear a ``General Purpose Non-Volatile Memory'' (GPNVM) -bit for the processor. Each processor has a number of such bits, -used for controlling features such as brownout detection (so they -are not truly general purpose). -@quotation Note -This assumes that the first flash bank (number 0) is associated with -the appropriate at91sam7 target. -@end quotation -@end deffn -@end deffn - -@deffn {Flash Driver} avr -The AVR 8-bit microcontrollers from Atmel integrate flash memory. -@emph{The current implementation is incomplete.} -@comment - defines mass_erase ... pointless given flash_erase_address -@end deffn - -@deffn {Flash Driver} efm32 -All members of the EFM32 microcontroller family from Energy Micro include -internal flash and use ARM Cortex-M3 cores. The driver automatically recognizes -a number of these chips using the chip identification register, and -autoconfigures itself. -@example -flash bank $_FLASHNAME efm32 0 0 0 0 $_TARGETNAME -@end example -A special feature of efm32 controllers is that it is possible to completely disable the -debug interface by writing the correct values to the 'Debug Lock Word'. OpenOCD supports -this via the following command: -@example -efm32 debuglock num -@end example -The @var{num} parameter is a value shown by @command{flash banks}. -Note that in order for this command to take effect, the target needs to be reset. -@emph{The current implementation is incomplete. Unprotecting flash pages is not -supported.} -@end deffn - -@deffn {Flash Driver} fm3 -All members of the FM3 microcontroller family from Fujitsu -include internal flash and use ARM Cortex-M3 cores. -The @var{fm3} driver uses the @var{target} parameter to select the -correct bank config, it can currently be one of the following: -@code{mb9bfxx1.cpu}, @code{mb9bfxx2.cpu}, @code{mb9bfxx3.cpu}, -@code{mb9bfxx4.cpu}, @code{mb9bfxx5.cpu} or @code{mb9bfxx6.cpu}. - -@example -flash bank $_FLASHNAME fm3 0 0 0 0 $_TARGETNAME -@end example -@end deffn - -@deffn {Flash Driver} fm4 -All members of the FM4 microcontroller family from Spansion (formerly Fujitsu) -include internal flash and use ARM Cortex-M4 cores. -The @var{fm4} driver uses a @var{family} parameter to select the -correct bank config, it can currently be one of the following: -@code{MB9BFx64}, @code{MB9BFx65}, @code{MB9BFx66}, @code{MB9BFx67}, @code{MB9BFx68}, -@code{S6E2Cx8}, @code{S6E2Cx9}, @code{S6E2CxA} or @code{S6E2Dx}, -with @code{x} treated as wildcard and otherwise case (and any trailing -characters) ignored. - -@example -flash bank $@{_FLASHNAME@}0 fm4 0x00000000 0 0 0 $_TARGETNAME S6E2CCAJ0A -flash bank $@{_FLASHNAME@}1 fm4 0x00100000 0 0 0 $_TARGETNAME S6E2CCAJ0A -@end example -@emph{The current implementation is incomplete. Protection is not supported, -nor is Chip Erase (only Sector Erase is implemented).} -@end deffn - -@deffn {Flash Driver} kinetis -@cindex kinetis -Kx and KLx members of the Kinetis microcontroller family from Freescale include -internal flash and use ARM Cortex-M0+ or M4 cores. The driver automatically -recognizes flash size and a number of flash banks (1-4) using the chip -identification register, and autoconfigures itself. - -@example -flash bank $_FLASHNAME kinetis 0 0 0 0 $_TARGETNAME -@end example - -@deffn Command {kinetis fcf_source} [protection|write] -Select what source is used when writing to a Flash Configuration Field. -@option{protection} mode builds FCF content from protection bits previously -set by 'flash protect' command. -This mode is default. MCU is protected from unwanted locking by immediate -writing FCF after erase of relevant sector. -@option{write} mode enables direct write to FCF. -Protection cannot be set by 'flash protect' command. FCF is written along -with the rest of a flash image. -@emph{BEWARE: Incorrect flash configuration may permanently lock the device!} -@end deffn - -@deffn Command {kinetis fopt} [num] -Set value to write to FOPT byte of Flash Configuration Field. -Used in kinetis 'fcf_source protection' mode only. -@end deffn - -@deffn Command {kinetis mdm check_security} -Checks status of device security lock. Used internally in examine-end event. -@end deffn - -@deffn Command {kinetis mdm halt} -Issues a halt via the MDM-AP. This command can be used to break a watchdog reset -loop when connecting to an unsecured target. -@end deffn - -@deffn Command {kinetis mdm mass_erase} -Issues a complete flash erase via the MDM-AP. This can be used to erase a chip -back to its factory state, removing security. It does not require the processor -to be halted, however the target will remain in a halted state after this -command completes. -@end deffn - -@deffn Command {kinetis nvm_partition} -For FlexNVM devices only (KxxDX and KxxFX). -Command shows or sets data flash or EEPROM backup size in kilobytes, -sets two EEPROM blocks sizes in bytes and enables/disables loading -of EEPROM contents to FlexRAM during reset. - -For details see device reference manual, Flash Memory Module, -Program Partition command. - -Setting is possible only once after mass_erase. -Reset the device after partition setting. - -Show partition size: -@example -kinetis nvm_partition info -@end example - -Set 32 KB data flash, rest of FlexNVM is EEPROM backup. EEPROM has two blocks -of 512 and 1536 bytes and its contents is loaded to FlexRAM during reset: -@example -kinetis nvm_partition dataflash 32 512 1536 on -@end example - -Set 16 KB EEPROM backup, rest of FlexNVM is a data flash. EEPROM has two blocks -of 1024 bytes and its contents is not loaded to FlexRAM during reset: -@example -kinetis nvm_partition eebkp 16 1024 1024 off -@end example -@end deffn - -@deffn Command {kinetis mdm reset} -Issues a reset via the MDM-AP. This causes the MCU to output a low pulse on the -RESET pin, which can be used to reset other hardware on board. -@end deffn - -@deffn Command {kinetis disable_wdog} -For Kx devices only (KLx has different COP watchdog, it is not supported). -Command disables watchdog timer. -@end deffn -@end deffn - -@deffn {Flash Driver} kinetis_ke -@cindex kinetis_ke -KE members of the Kinetis microcontroller family from Freescale include -internal flash and use ARM Cortex-M0+. The driver automatically recognizes -the KE family and sub-family using the chip identification register, and -autoconfigures itself. - -@example -flash bank $_FLASHNAME kinetis_ke 0 0 0 0 $_TARGETNAME -@end example - -@deffn Command {kinetis_ke mdm check_security} -Checks status of device security lock. Used internally in examine-end event. -@end deffn - -@deffn Command {kinetis_ke mdm mass_erase} -Issues a complete Flash erase via the MDM-AP. -This can be used to erase a chip back to its factory state. -Command removes security lock from a device (use of SRST highly recommended). -It does not require the processor to be halted. -@end deffn - -@deffn Command {kinetis_ke disable_wdog} -Command disables watchdog timer. -@end deffn -@end deffn - -@deffn {Flash Driver} lpc2000 -This is the driver to support internal flash of all members of the -LPC11(x)00 and LPC1300 microcontroller families and most members of -the LPC800, LPC1500, LPC1700, LPC1800, LPC2000, LPC4000 and LPC54100 -microcontroller families from NXP. - -@quotation Note -There are LPC2000 devices which are not supported by the @var{lpc2000} -driver: -The LPC2888 is supported by the @var{lpc288x} driver. -The LPC29xx family is supported by the @var{lpc2900} driver. -@end quotation - -The @var{lpc2000} driver defines two mandatory and one optional parameters, -which must appear in the following order: - -@itemize -@item @var{variant} ... required, may be -@option{lpc2000_v1} (older LPC21xx and LPC22xx) -@option{lpc2000_v2} (LPC213x, LPC214x, LPC210[123], LPC23xx and LPC24xx) -@option{lpc1700} (LPC175x and LPC176x and LPC177x/8x) -@option{lpc4300} - available also as @option{lpc1800} alias (LPC18x[2357] and -LPC43x[2357]) -@option{lpc800} (LPC8xx) -@option{lpc1100} (LPC11(x)xx and LPC13xx) -@option{lpc1500} (LPC15xx) -@option{lpc54100} (LPC541xx) -@option{lpc4000} (LPC40xx) -or @option{auto} - automatically detects flash variant and size for LPC11(x)00, -LPC8xx, LPC13xx, LPC17xx and LPC40xx -@item @var{clock_kHz} ... the frequency, in kiloHertz, -at which the core is running -@item @option{calc_checksum} ... optional (but you probably want to provide this!), -telling the driver to calculate a valid checksum for the exception vector table. -@quotation Note -If you don't provide @option{calc_checksum} when you're writing the vector -table, the boot ROM will almost certainly ignore your flash image. -However, if you do provide it, -with most tool chains @command{verify_image} will fail. -@end quotation -@end itemize - -LPC flashes don't require the chip and bus width to be specified. - -@example -flash bank $_FLASHNAME lpc2000 0x0 0x7d000 0 0 $_TARGETNAME \ - lpc2000_v2 14765 calc_checksum -@end example - -@deffn {Command} {lpc2000 part_id} bank -Displays the four byte part identifier associated with -the specified flash @var{bank}. -@end deffn -@end deffn - -@deffn {Flash Driver} lpc288x -The LPC2888 microcontroller from NXP needs slightly different flash -support from its lpc2000 siblings. -The @var{lpc288x} driver defines one mandatory parameter, -the programming clock rate in Hz. -LPC flashes don't require the chip and bus width to be specified. - -@example -flash bank $_FLASHNAME lpc288x 0 0 0 0 $_TARGETNAME 12000000 -@end example -@end deffn - -@deffn {Flash Driver} lpc2900 -This driver supports the LPC29xx ARM968E based microcontroller family -from NXP. - -The predefined parameters @var{base}, @var{size}, @var{chip_width} and -@var{bus_width} of the @code{flash bank} command are ignored. Flash size and -sector layout are auto-configured by the driver. -The driver has one additional mandatory parameter: The CPU clock rate -(in kHz) at the time the flash operations will take place. Most of the time this -will not be the crystal frequency, but a higher PLL frequency. The -@code{reset-init} event handler in the board script is usually the place where -you start the PLL. - -The driver rejects flashless devices (currently the LPC2930). - -The EEPROM in LPC2900 devices is not mapped directly into the address space. -It must be handled much more like NAND flash memory, and will therefore be -handled by a separate @code{lpc2900_eeprom} driver (not yet available). - -Sector protection in terms of the LPC2900 is handled transparently. Every time a -sector needs to be erased or programmed, it is automatically unprotected. -What is shown as protection status in the @code{flash info} command, is -actually the LPC2900 @emph{sector security}. This is a mechanism to prevent a -sector from ever being erased or programmed again. As this is an irreversible -mechanism, it is handled by a special command (@code{lpc2900 secure_sector}), -and not by the standard @code{flash protect} command. - -Example for a 125 MHz clock frequency: -@example -flash bank $_FLASHNAME lpc2900 0 0 0 0 $_TARGETNAME 125000 -@end example - -Some @code{lpc2900}-specific commands are defined. In the following command list, -the @var{bank} parameter is the bank number as obtained by the -@code{flash banks} command. - -@deffn Command {lpc2900 signature} bank -Calculates a 128-bit hash value, the @emph{signature}, from the whole flash -content. This is a hardware feature of the flash block, hence the calculation is -very fast. You may use this to verify the content of a programmed device against -a known signature. -Example: -@example -lpc2900 signature 0 - signature: 0x5f40cdc8:0xc64e592e:0x10490f89:0x32a0f317 -@end example -@end deffn - -@deffn Command {lpc2900 read_custom} bank filename -Reads the 912 bytes of customer information from the flash index sector, and -saves it to a file in binary format. -Example: -@example -lpc2900 read_custom 0 /path_to/customer_info.bin -@end example -@end deffn - -The index sector of the flash is a @emph{write-only} sector. It cannot be -erased! In order to guard against unintentional write access, all following -commands need to be preceeded by a successful call to the @code{password} -command: - -@deffn Command {lpc2900 password} bank password -You need to use this command right before each of the following commands: -@code{lpc2900 write_custom}, @code{lpc2900 secure_sector}, -@code{lpc2900 secure_jtag}. - -The password string is fixed to "I_know_what_I_am_doing". -Example: -@example -lpc2900 password 0 I_know_what_I_am_doing - Potentially dangerous operation allowed in next command! -@end example -@end deffn - -@deffn Command {lpc2900 write_custom} bank filename type -Writes the content of the file into the customer info space of the flash index -sector. The filetype can be specified with the @var{type} field. Possible values -for @var{type} are: @var{bin} (binary), @var{ihex} (Intel hex format), -@var{elf} (ELF binary) or @var{s19} (Motorola S-records). The file must -contain a single section, and the contained data length must be exactly -912 bytes. -@quotation Attention -This cannot be reverted! Be careful! -@end quotation -Example: -@example -lpc2900 write_custom 0 /path_to/customer_info.bin bin -@end example -@end deffn - -@deffn Command {lpc2900 secure_sector} bank first last -Secures the sector range from @var{first} to @var{last} (including) against -further program and erase operations. The sector security will be effective -after the next power cycle. -@quotation Attention -This cannot be reverted! Be careful! -@end quotation -Secured sectors appear as @emph{protected} in the @code{flash info} command. -Example: -@example -lpc2900 secure_sector 0 1 1 -flash info 0 - #0 : lpc2900 at 0x20000000, size 0x000c0000, (...) - # 0: 0x00000000 (0x2000 8kB) not protected - # 1: 0x00002000 (0x2000 8kB) protected - # 2: 0x00004000 (0x2000 8kB) not protected -@end example -@end deffn - -@deffn Command {lpc2900 secure_jtag} bank -Irreversibly disable the JTAG port. The new JTAG security setting will be -effective after the next power cycle. -@quotation Attention -This cannot be reverted! Be careful! -@end quotation -Examples: -@example -lpc2900 secure_jtag 0 -@end example -@end deffn -@end deffn - -@deffn {Flash Driver} mdr -This drivers handles the integrated NOR flash on Milandr Cortex-M -based controllers. A known limitation is that the Info memory can't be -read or verified as it's not memory mapped. - -@example -flash bank mdr \ - 0 0 @var{type} @var{page_count} @var{sec_count} -@end example - -@itemize @bullet -@item @var{type} - 0 for main memory, 1 for info memory -@item @var{page_count} - total number of pages -@item @var{sec_count} - number of sector per page count -@end itemize - -Example usage: -@example -if @{ [info exists IMEMORY] && [string equal $IMEMORY true] @} @{ - flash bank $@{_CHIPNAME@}_info.flash mdr 0x00000000 0x01000 \ - 0 0 $_TARGETNAME 1 1 4 -@} else @{ - flash bank $_CHIPNAME.flash mdr 0x00000000 0x20000 \ - 0 0 $_TARGETNAME 0 32 4 -@} -@end example -@end deffn - -@deffn {Flash Driver} niietcm4 -This drivers handles the integrated NOR flash on NIIET Cortex-M4 -based controllers. Flash size and sector layout are auto-configured by the driver. -Main flash memory is called "Bootflash" and has main region and info region. -Info region is NOT memory mapped by default, -but it can replace first part of main region if needed. -Full erase, single and block writes are supported for both main and info regions. -There is additional not memory mapped flash called "Userflash", which -also have division into regions: main and info. -Purpose of userflash - to store system and user settings. -Driver has special commands to perform operations with this memmory. - -@example -flash bank $_FLASHNAME niietcm4 0 0 0 0 $_TARGETNAME -@end example - -Some niietcm4-specific commands are defined: - -@deffn Command {niietcm4 uflash_read_byte} bank ('main'|'info') address -Read byte from main or info userflash region. -@end deffn - -@deffn Command {niietcm4 uflash_write_byte} bank ('main'|'info') address value -Write byte to main or info userflash region. -@end deffn - -@deffn Command {niietcm4 uflash_full_erase} bank -Erase all userflash including info region. -@end deffn - -@deffn Command {niietcm4 uflash_erase} bank ('main'|'info') first_sector last_sector -Erase sectors of main or info userflash region, starting at sector first up to and including last. -@end deffn - -@deffn Command {niietcm4 uflash_protect_check} bank ('main'|'info') -Check sectors protect. -@end deffn - -@deffn Command {niietcm4 uflash_protect} bank ('main'|'info') first_sector last_sector ('on'|'off') -Protect sectors of main or info userflash region, starting at sector first up to and including last. -@end deffn - -@deffn Command {niietcm4 bflash_info_remap} bank ('on'|'off') -Enable remapping bootflash info region to 0x00000000 (or 0x40000000 if external memory boot used). -@end deffn - -@deffn Command {niietcm4 extmem_cfg} bank ('gpioa'|'gpiob'|'gpioc'|'gpiod'|'gpioe'|'gpiof'|'gpiog'|'gpioh') pin_num ('func1'|'func3') -Configure external memory interface for boot. -@end deffn - -@deffn Command {niietcm4 service_mode_erase} bank -Perform emergency erase of all flash (bootflash and userflash). -@end deffn - -@deffn Command {niietcm4 driver_info} bank -Show information about flash driver. -@end deffn - -@end deffn - -@deffn {Flash Driver} nrf51 -All members of the nRF51 microcontroller families from Nordic Semiconductor -include internal flash and use ARM Cortex-M0 core. - -@example -flash bank $_FLASHNAME nrf51 0 0x00000000 0 0 $_TARGETNAME -@end example - -Some nrf51-specific commands are defined: - -@deffn Command {nrf51 mass_erase} -Erases the contents of the code memory and user information -configuration registers as well. It must be noted that this command -works only for chips that do not have factory pre-programmed region 0 -code. -@end deffn - -@end deffn - -@deffn {Flash Driver} ocl -This driver is an implementation of the ``on chip flash loader'' -protocol proposed by Pavel Chromy. - -It is a minimalistic command-response protocol intended to be used -over a DCC when communicating with an internal or external flash -loader running from RAM. An example implementation for AT91SAM7x is -available in @file{contrib/loaders/flash/at91sam7x/}. - -@example -flash bank $_FLASHNAME ocl 0 0 0 0 $_TARGETNAME -@end example -@end deffn - -@deffn {Flash Driver} pic32mx -The PIC32MX microcontrollers are based on the MIPS 4K cores, -and integrate flash memory. - -@example -flash bank $_FLASHNAME pix32mx 0x1fc00000 0 0 0 $_TARGETNAME -flash bank $_FLASHNAME pix32mx 0x1d000000 0 0 0 $_TARGETNAME -@end example - -@comment numerous *disabled* commands are defined: -@comment - chip_erase ... pointless given flash_erase_address -@comment - lock, unlock ... pointless given protect on/off (yes?) -@comment - pgm_word ... shouldn't bank be deduced from address?? -Some pic32mx-specific commands are defined: -@deffn Command {pic32mx pgm_word} address value bank -Programs the specified 32-bit @var{value} at the given @var{address} -in the specified chip @var{bank}. -@end deffn -@deffn Command {pic32mx unlock} bank -Unlock and erase specified chip @var{bank}. -This will remove any Code Protection. -@end deffn -@end deffn - -@deffn {Flash Driver} psoc4 -All members of the PSoC 41xx/42xx microcontroller family from Cypress -include internal flash and use ARM Cortex-M0 cores. -The driver automatically recognizes a number of these chips using -the chip identification register, and autoconfigures itself. - -Note: Erased internal flash reads as 00. -System ROM of PSoC 4 does not implement erase of a flash sector. - -@example -flash bank $_FLASHNAME psoc4 0 0 0 0 $_TARGETNAME -@end example - -psoc4-specific commands -@deffn Command {psoc4 flash_autoerase} num (on|off) -Enables or disables autoerase mode for a flash bank. - -If flash_autoerase is off, use mass_erase before flash programming. -Flash erase command fails if region to erase is not whole flash memory. - -If flash_autoerase is on, a sector is both erased and programmed in one -system ROM call. Flash erase command is ignored. -This mode is suitable for gdb load. - -The @var{num} parameter is a value shown by @command{flash banks}. -@end deffn - -@deffn Command {psoc4 mass_erase} num -Erases the contents of the flash memory, protection and security lock. - -The @var{num} parameter is a value shown by @command{flash banks}. -@end deffn -@end deffn - -@deffn {Flash Driver} sim3x -All members of the SiM3 microcontroller family from Silicon Laboratories -include internal flash and use ARM Cortex-M3 cores. It supports both JTAG -and SWD interface. -The @var{sim3x} driver tries to probe the device to auto detect the MCU. -If this failes, it will use the @var{size} parameter as the size of flash bank. - -@example -flash bank $_FLASHNAME sim3x 0 $_CPUROMSIZE 0 0 $_TARGETNAME -@end example - -There are 2 commands defined in the @var{sim3x} driver: - -@deffn Command {sim3x mass_erase} -Erases the complete flash. This is used to unlock the flash. -And this command is only possible when using the SWD interface. -@end deffn - -@deffn Command {sim3x lock} -Lock the flash. To unlock use the @command{sim3x mass_erase} command. -@end deffn -@end deffn - -@deffn {Flash Driver} stellaris -All members of the Stellaris LM3Sxxx, LM4x and Tiva C microcontroller -families from Texas Instruments include internal flash. The driver -automatically recognizes a number of these chips using the chip -identification register, and autoconfigures itself. -@footnote{Currently there is a @command{stellaris mass_erase} command. -That seems pointless since the same effect can be had using the -standard @command{flash erase_address} command.} - -@example -flash bank $_FLASHNAME stellaris 0 0 0 0 $_TARGETNAME -@end example - -@deffn Command {stellaris recover} -Performs the @emph{Recovering a "Locked" Device} procedure to restore -the flash and its associated nonvolatile registers to their factory -default values (erased). This is the only way to remove flash -protection or re-enable debugging if that capability has been -disabled. - -Note that the final "power cycle the chip" step in this procedure -must be performed by hand, since OpenOCD can't do it. -@quotation Warning -if more than one Stellaris chip is connected, the procedure is -applied to all of them. -@end quotation -@end deffn -@end deffn - -@deffn {Flash Driver} stm32f1x -All members of the STM32F0, STM32F1 and STM32F3 microcontroller families -from ST Microelectronics include internal flash and use ARM Cortex-M0/M3/M4 cores. -The driver automatically recognizes a number of these chips using -the chip identification register, and autoconfigures itself. - -@example -flash bank $_FLASHNAME stm32f1x 0 0 0 0 $_TARGETNAME -@end example - -Note that some devices have been found that have a flash size register that contains -an invalid value, to workaround this issue you can override the probed value used by -the flash driver. - -@example -flash bank $_FLASHNAME stm32f1x 0 0x20000 0 0 $_TARGETNAME -@end example - -If you have a target with dual flash banks then define the second bank -as per the following example. -@example -flash bank $_FLASHNAME stm32f1x 0x08080000 0 0 0 $_TARGETNAME -@end example - -Some stm32f1x-specific commands -@footnote{Currently there is a @command{stm32f1x mass_erase} command. -That seems pointless since the same effect can be had using the -standard @command{flash erase_address} command.} -are defined: - -@deffn Command {stm32f1x lock} num -Locks the entire stm32 device. -The @var{num} parameter is a value shown by @command{flash banks}. -@end deffn - -@deffn Command {stm32f1x unlock} num -Unlocks the entire stm32 device. -The @var{num} parameter is a value shown by @command{flash banks}. -@end deffn - -@deffn Command {stm32f1x options_read} num -Read and display the stm32 option bytes written by -the @command{stm32f1x options_write} command. -The @var{num} parameter is a value shown by @command{flash banks}. -@end deffn - -@deffn Command {stm32f1x options_write} num (@option{SWWDG}|@option{HWWDG}) (@option{RSTSTNDBY}|@option{NORSTSTNDBY}) (@option{RSTSTOP}|@option{NORSTSTOP}) -Writes the stm32 option byte with the specified values. -The @var{num} parameter is a value shown by @command{flash banks}. -@end deffn -@end deffn - -@deffn {Flash Driver} stm32f2x -All members of the STM32F2, STM32F4 and STM32F7 microcontroller families from ST Microelectronics -include internal flash and use ARM Cortex-M3/M4/M7 cores. -The driver automatically recognizes a number of these chips using -the chip identification register, and autoconfigures itself. - -Note that some devices have been found that have a flash size register that contains -an invalid value, to workaround this issue you can override the probed value used by -the flash driver. - -@example -flash bank $_FLASHNAME stm32f2x 0 0x20000 0 0 $_TARGETNAME -@end example - -Some stm32f2x-specific commands are defined: - -@deffn Command {stm32f2x lock} num -Locks the entire stm32 device. -The @var{num} parameter is a value shown by @command{flash banks}. -@end deffn - -@deffn Command {stm32f2x unlock} num -Unlocks the entire stm32 device. -The @var{num} parameter is a value shown by @command{flash banks}. -@end deffn - -@deffn Command {stm32f2x options_read} num -Reads and displays user options and (where implemented) boot_addr0 and boot_addr1. -The @var{num} parameter is a value shown by @command{flash banks}. -@end deffn - -@deffn Command {stm32f2x options_write} num user_options boot_addr0 boot_addr1 -Writes user options and (where implemented) boot_addr0 and boot_addr1 in raw format. -Warning: The meaning of the various bits depends on the device, always check datasheet! -The @var{num} parameter is a value shown by @command{flash banks}, user_options a -12 bit value, consisting of bits 31-28 and 7-0 of FLASH_OPTCR, boot_addr0 and boot_addr1 -two halfwords (of FLASH_OPTCR1). -@end deffn -@end deffn - -@deffn {Flash Driver} stm32lx -All members of the STM32L microcontroller families from ST Microelectronics -include internal flash and use ARM Cortex-M3 and Cortex-M0+ cores. -The driver automatically recognizes a number of these chips using -the chip identification register, and autoconfigures itself. - -Note that some devices have been found that have a flash size register that contains -an invalid value, to workaround this issue you can override the probed value used by -the flash driver. If you use 0 as the bank base address, it tells the -driver to autodetect the bank location assuming you're configuring the -second bank. - -@example -flash bank $_FLASHNAME stm32lx 0x08000000 0x20000 0 0 $_TARGETNAME -@end example - -Some stm32lx-specific commands are defined: - -@deffn Command {stm32lx mass_erase} num -Mass erases the entire stm32lx device (all flash banks and EEPROM -data). This is the only way to unlock a protected flash (unless RDP -Level is 2 which can't be unlocked at all). -The @var{num} parameter is a value shown by @command{flash banks}. -@end deffn -@end deffn - -@deffn {Flash Driver} str7x -All members of the STR7 microcontroller family from ST Microelectronics -include internal flash and use ARM7TDMI cores. -The @var{str7x} driver defines one mandatory parameter, @var{variant}, -which is either @code{STR71x}, @code{STR73x} or @code{STR75x}. - -@example -flash bank $_FLASHNAME str7x \ - 0x40000000 0x00040000 0 0 $_TARGETNAME STR71x -@end example - -@deffn Command {str7x disable_jtag} bank -Activate the Debug/Readout protection mechanism -for the specified flash bank. -@end deffn -@end deffn - -@deffn {Flash Driver} str9x -Most members of the STR9 microcontroller family from ST Microelectronics -include internal flash and use ARM966E cores. -The str9 needs the flash controller to be configured using -the @command{str9x flash_config} command prior to Flash programming. - -@example -flash bank $_FLASHNAME str9x 0x40000000 0x00040000 0 0 $_TARGETNAME -str9x flash_config 0 4 2 0 0x80000 -@end example - -@deffn Command {str9x flash_config} num bbsr nbbsr bbadr nbbadr -Configures the str9 flash controller. -The @var{num} parameter is a value shown by @command{flash banks}. - -@itemize @bullet -@item @var{bbsr} - Boot Bank Size register -@item @var{nbbsr} - Non Boot Bank Size register -@item @var{bbadr} - Boot Bank Start Address register -@item @var{nbbadr} - Boot Bank Start Address register -@end itemize -@end deffn - -@end deffn - -@deffn {Flash Driver} str9xpec -@cindex str9xpec - -Only use this driver for locking/unlocking the device or configuring the option bytes. -Use the standard str9 driver for programming. -Before using the flash commands the turbo mode must be enabled using the -@command{str9xpec enable_turbo} command. - -Here is some background info to help -you better understand how this driver works. OpenOCD has two flash drivers for -the str9: -@enumerate -@item -Standard driver @option{str9x} programmed via the str9 core. Normally used for -flash programming as it is faster than the @option{str9xpec} driver. -@item -Direct programming @option{str9xpec} using the flash controller. This is an -ISC compilant (IEEE 1532) tap connected in series with the str9 core. The str9 -core does not need to be running to program using this flash driver. Typical use -for this driver is locking/unlocking the target and programming the option bytes. -@end enumerate - -Before we run any commands using the @option{str9xpec} driver we must first disable -the str9 core. This example assumes the @option{str9xpec} driver has been -configured for flash bank 0. -@example -# assert srst, we do not want core running -# while accessing str9xpec flash driver -jtag_reset 0 1 -# turn off target polling -poll off -# disable str9 core -str9xpec enable_turbo 0 -# read option bytes -str9xpec options_read 0 -# re-enable str9 core -str9xpec disable_turbo 0 -poll on -reset halt -@end example -The above example will read the str9 option bytes. -When performing a unlock remember that you will not be able to halt the str9 - it -has been locked. Halting the core is not required for the @option{str9xpec} driver -as mentioned above, just issue the commands above manually or from a telnet prompt. - -Several str9xpec-specific commands are defined: - -@deffn Command {str9xpec disable_turbo} num -Restore the str9 into JTAG chain. -@end deffn - -@deffn Command {str9xpec enable_turbo} num -Enable turbo mode, will simply remove the str9 from the chain and talk -directly to the embedded flash controller. -@end deffn - -@deffn Command {str9xpec lock} num -Lock str9 device. The str9 will only respond to an unlock command that will -erase the device. -@end deffn - -@deffn Command {str9xpec part_id} num -Prints the part identifier for bank @var{num}. -@end deffn - -@deffn Command {str9xpec options_cmap} num (@option{bank0}|@option{bank1}) -Configure str9 boot bank. -@end deffn - -@deffn Command {str9xpec options_lvdsel} num (@option{vdd}|@option{vdd_vddq}) -Configure str9 lvd source. -@end deffn - -@deffn Command {str9xpec options_lvdthd} num (@option{2.4v}|@option{2.7v}) -Configure str9 lvd threshold. -@end deffn - -@deffn Command {str9xpec options_lvdwarn} bank (@option{vdd}|@option{vdd_vddq}) -Configure str9 lvd reset warning source. -@end deffn - -@deffn Command {str9xpec options_read} num -Read str9 option bytes. -@end deffn - -@deffn Command {str9xpec options_write} num -Write str9 option bytes. -@end deffn - -@deffn Command {str9xpec unlock} num -unlock str9 device. -@end deffn - -@end deffn - -@deffn {Flash Driver} tms470 -Most members of the TMS470 microcontroller family from Texas Instruments -include internal flash and use ARM7TDMI cores. -This driver doesn't require the chip and bus width to be specified. - -Some tms470-specific commands are defined: - -@deffn Command {tms470 flash_keyset} key0 key1 key2 key3 -Saves programming keys in a register, to enable flash erase and write commands. -@end deffn - -@deffn Command {tms470 osc_mhz} clock_mhz -Reports the clock speed, which is used to calculate timings. -@end deffn - -@deffn Command {tms470 plldis} (0|1) -Disables (@var{1}) or enables (@var{0}) use of the PLL to speed up -the flash clock. -@end deffn -@end deffn - -@deffn {Flash Driver} xmc1xxx -All members of the XMC1xxx microcontroller family from Infineon. -This driver does not require the chip and bus width to be specified. -@end deffn - -@deffn {Flash Driver} xmc4xxx -All members of the XMC4xxx microcontroller family from Infineon. -This driver does not require the chip and bus width to be specified. - -Some xmc4xxx-specific commands are defined: - -@deffn Command {xmc4xxx flash_password} bank_id passwd1 passwd2 -Saves flash protection passwords which are used to lock the user flash -@end deffn - -@deffn Command {xmc4xxx flash_unprotect} bank_id user_level[0-1] -Removes Flash write protection from the selected user bank -@end deffn - -@end deffn - -@section NAND Flash Commands -@cindex NAND - -Compared to NOR or SPI flash, NAND devices are inexpensive -and high density. Today's NAND chips, and multi-chip modules, -commonly hold multiple GigaBytes of data. - -NAND chips consist of a number of ``erase blocks'' of a given -size (such as 128 KBytes), each of which is divided into a -number of pages (of perhaps 512 or 2048 bytes each). Each -page of a NAND flash has an ``out of band'' (OOB) area to hold -Error Correcting Code (ECC) and other metadata, usually 16 bytes -of OOB for every 512 bytes of page data. - -One key characteristic of NAND flash is that its error rate -is higher than that of NOR flash. In normal operation, that -ECC is used to correct and detect errors. However, NAND -blocks can also wear out and become unusable; those blocks -are then marked "bad". NAND chips are even shipped from the -manufacturer with a few bad blocks. The highest density chips -use a technology (MLC) that wears out more quickly, so ECC -support is increasingly important as a way to detect blocks -that have begun to fail, and help to preserve data integrity -with techniques such as wear leveling. - -Software is used to manage the ECC. Some controllers don't -support ECC directly; in those cases, software ECC is used. -Other controllers speed up the ECC calculations with hardware. -Single-bit error correction hardware is routine. Controllers -geared for newer MLC chips may correct 4 or more errors for -every 512 bytes of data. - -You will need to make sure that any data you write using -OpenOCD includes the apppropriate kind of ECC. For example, -that may mean passing the @code{oob_softecc} flag when -writing NAND data, or ensuring that the correct hardware -ECC mode is used. - -The basic steps for using NAND devices include: -@enumerate -@item Declare via the command @command{nand device} -@* Do this in a board-specific configuration file, -passing parameters as needed by the controller. -@item Configure each device using @command{nand probe}. -@* Do this only after the associated target is set up, -such as in its reset-init script or in procures defined -to access that device. -@item Operate on the flash via @command{nand subcommand} -@* Often commands to manipulate the flash are typed by a human, or run -via a script in some automated way. Common task include writing a -boot loader, operating system, or other data needed to initialize or -de-brick a board. -@end enumerate - -@b{NOTE:} At the time this text was written, the largest NAND -flash fully supported by OpenOCD is 2 GiBytes (16 GiBits). -This is because the variables used to hold offsets and lengths -are only 32 bits wide. -(Larger chips may work in some cases, unless an offset or length -is larger than 0xffffffff, the largest 32-bit unsigned integer.) -Some larger devices will work, since they are actually multi-chip -modules with two smaller chips and individual chipselect lines. - -@anchor{nandconfiguration} -@subsection NAND Configuration Commands -@cindex NAND configuration - -NAND chips must be declared in configuration scripts, -plus some additional configuration that's done after -OpenOCD has initialized. - -@deffn {Config Command} {nand device} name driver target [configparams...] -Declares a NAND device, which can be read and written to -after it has been configured through @command{nand probe}. -In OpenOCD, devices are single chips; this is unlike some -operating systems, which may manage multiple chips as if -they were a single (larger) device. -In some cases, configuring a device will activate extra -commands; see the controller-specific documentation. - -@b{NOTE:} This command is not available after OpenOCD -initialization has completed. Use it in board specific -configuration files, not interactively. - -@itemize @bullet -@item @var{name} ... may be used to reference the NAND bank -in most other NAND commands. A number is also available. -@item @var{driver} ... identifies the NAND controller driver -associated with the NAND device being declared. -@xref{nanddriverlist,,NAND Driver List}. -@item @var{target} ... names the target used when issuing -commands to the NAND controller. -@comment Actually, it's currently a controller-specific parameter... -@item @var{configparams} ... controllers may support, or require, -additional parameters. See the controller-specific documentation -for more information. -@end itemize -@end deffn - -@deffn Command {nand list} -Prints a summary of each device declared -using @command{nand device}, numbered from zero. -Note that un-probed devices show no details. -@example -> nand list -#0: NAND 1GiB 3,3V 8-bit (Micron) pagesize: 2048, buswidth: 8, - blocksize: 131072, blocks: 8192 -#1: NAND 1GiB 3,3V 8-bit (Micron) pagesize: 2048, buswidth: 8, - blocksize: 131072, blocks: 8192 -> -@end example -@end deffn - -@deffn Command {nand probe} num -Probes the specified device to determine key characteristics -like its page and block sizes, and how many blocks it has. -The @var{num} parameter is the value shown by @command{nand list}. -You must (successfully) probe a device before you can use -it with most other NAND commands. -@end deffn - -@subsection Erasing, Reading, Writing to NAND Flash - -@deffn Command {nand dump} num filename offset length [oob_option] -@cindex NAND reading -Reads binary data from the NAND device and writes it to the file, -starting at the specified offset. -The @var{num} parameter is the value shown by @command{nand list}. - -Use a complete path name for @var{filename}, so you don't depend -on the directory used to start the OpenOCD server. - -The @var{offset} and @var{length} must be exact multiples of the -device's page size. They describe a data region; the OOB data -associated with each such page may also be accessed. - -@b{NOTE:} At the time this text was written, no error correction -was done on the data that's read, unless raw access was disabled -and the underlying NAND controller driver had a @code{read_page} -method which handled that error correction. - -By default, only page data is saved to the specified file. -Use an @var{oob_option} parameter to save OOB data: -@itemize @bullet -@item no oob_* parameter -@*Output file holds only page data; OOB is discarded. -@item @code{oob_raw} -@*Output file interleaves page data and OOB data; -the file will be longer than "length" by the size of the -spare areas associated with each data page. -Note that this kind of "raw" access is different from -what's implied by @command{nand raw_access}, which just -controls whether a hardware-aware access method is used. -@item @code{oob_only} -@*Output file has only raw OOB data, and will -be smaller than "length" since it will contain only the -spare areas associated with each data page. -@end itemize -@end deffn - -@deffn Command {nand erase} num [offset length] -@cindex NAND erasing -@cindex NAND programming -Erases blocks on the specified NAND device, starting at the -specified @var{offset} and continuing for @var{length} bytes. -Both of those values must be exact multiples of the device's -block size, and the region they specify must fit entirely in the chip. -If those parameters are not specified, -the whole NAND chip will be erased. -The @var{num} parameter is the value shown by @command{nand list}. - -@b{NOTE:} This command will try to erase bad blocks, when told -to do so, which will probably invalidate the manufacturer's bad -block marker. -For the remainder of the current server session, @command{nand info} -will still report that the block ``is'' bad. -@end deffn - -@deffn Command {nand write} num filename offset [option...] -@cindex NAND writing -@cindex NAND programming -Writes binary data from the file into the specified NAND device, -starting at the specified offset. Those pages should already -have been erased; you can't change zero bits to one bits. -The @var{num} parameter is the value shown by @command{nand list}. - -Use a complete path name for @var{filename}, so you don't depend -on the directory used to start the OpenOCD server. - -The @var{offset} must be an exact multiple of the device's page size. -All data in the file will be written, assuming it doesn't run -past the end of the device. -Only full pages are written, and any extra space in the last -page will be filled with 0xff bytes. (That includes OOB data, -if that's being written.) - -@b{NOTE:} At the time this text was written, bad blocks are -ignored. That is, this routine will not skip bad blocks, -but will instead try to write them. This can cause problems. - -Provide at most one @var{option} parameter. With some -NAND drivers, the meanings of these parameters may change -if @command{nand raw_access} was used to disable hardware ECC. -@itemize @bullet -@item no oob_* parameter -@*File has only page data, which is written. -If raw acccess is in use, the OOB area will not be written. -Otherwise, if the underlying NAND controller driver has -a @code{write_page} routine, that routine may write the OOB -with hardware-computed ECC data. -@item @code{oob_only} -@*File has only raw OOB data, which is written to the OOB area. -Each page's data area stays untouched. @i{This can be a dangerous -option}, since it can invalidate the ECC data. -You may need to force raw access to use this mode. -@item @code{oob_raw} -@*File interleaves data and OOB data, both of which are written -If raw access is enabled, the data is written first, then the -un-altered OOB. -Otherwise, if the underlying NAND controller driver has -a @code{write_page} routine, that routine may modify the OOB -before it's written, to include hardware-computed ECC data. -@item @code{oob_softecc} -@*File has only page data, which is written. -The OOB area is filled with 0xff, except for a standard 1-bit -software ECC code stored in conventional locations. -You might need to force raw access to use this mode, to prevent -the underlying driver from applying hardware ECC. -@item @code{oob_softecc_kw} -@*File has only page data, which is written. -The OOB area is filled with 0xff, except for a 4-bit software ECC -specific to the boot ROM in Marvell Kirkwood SoCs. -You might need to force raw access to use this mode, to prevent -the underlying driver from applying hardware ECC. -@end itemize -@end deffn - -@deffn Command {nand verify} num filename offset [option...] -@cindex NAND verification -@cindex NAND programming -Verify the binary data in the file has been programmed to the -specified NAND device, starting at the specified offset. -The @var{num} parameter is the value shown by @command{nand list}. - -Use a complete path name for @var{filename}, so you don't depend -on the directory used to start the OpenOCD server. - -The @var{offset} must be an exact multiple of the device's page size. -All data in the file will be read and compared to the contents of the -flash, assuming it doesn't run past the end of the device. -As with @command{nand write}, only full pages are verified, so any extra -space in the last page will be filled with 0xff bytes. - -The same @var{options} accepted by @command{nand write}, -and the file will be processed similarly to produce the buffers that -can be compared against the contents produced from @command{nand dump}. - -@b{NOTE:} This will not work when the underlying NAND controller -driver's @code{write_page} routine must update the OOB with a -hardward-computed ECC before the data is written. This limitation may -be removed in a future release. -@end deffn - -@subsection Other NAND commands -@cindex NAND other commands - -@deffn Command {nand check_bad_blocks} num [offset length] -Checks for manufacturer bad block markers on the specified NAND -device. If no parameters are provided, checks the whole -device; otherwise, starts at the specified @var{offset} and -continues for @var{length} bytes. -Both of those values must be exact multiples of the device's -block size, and the region they specify must fit entirely in the chip. -The @var{num} parameter is the value shown by @command{nand list}. - -@b{NOTE:} Before using this command you should force raw access -with @command{nand raw_access enable} to ensure that the underlying -driver will not try to apply hardware ECC. -@end deffn - -@deffn Command {nand info} num -The @var{num} parameter is the value shown by @command{nand list}. -This prints the one-line summary from "nand list", plus for -devices which have been probed this also prints any known -status for each block. -@end deffn - -@deffn Command {nand raw_access} num (@option{enable}|@option{disable}) -Sets or clears an flag affecting how page I/O is done. -The @var{num} parameter is the value shown by @command{nand list}. - -This flag is cleared (disabled) by default, but changing that -value won't affect all NAND devices. The key factor is whether -the underlying driver provides @code{read_page} or @code{write_page} -methods. If it doesn't provide those methods, the setting of -this flag is irrelevant; all access is effectively ``raw''. - -When those methods exist, they are normally used when reading -data (@command{nand dump} or reading bad block markers) or -writing it (@command{nand write}). However, enabling -raw access (setting the flag) prevents use of those methods, -bypassing hardware ECC logic. -@i{This can be a dangerous option}, since writing blocks -with the wrong ECC data can cause them to be marked as bad. -@end deffn - -@anchor{nanddriverlist} -@subsection NAND Driver List -As noted above, the @command{nand device} command allows -driver-specific options and behaviors. -Some controllers also activate controller-specific commands. - -@deffn {NAND Driver} at91sam9 -This driver handles the NAND controllers found on AT91SAM9 family chips from -Atmel. It takes two extra parameters: address of the NAND chip; -address of the ECC controller. -@example -nand device $NANDFLASH at91sam9 $CHIPNAME 0x40000000 0xfffffe800 -@end example -AT91SAM9 chips support single-bit ECC hardware. The @code{write_page} and -@code{read_page} methods are used to utilize the ECC hardware unless they are -disabled by using the @command{nand raw_access} command. There are four -additional commands that are needed to fully configure the AT91SAM9 NAND -controller. Two are optional; most boards use the same wiring for ALE/CLE: -@deffn Command {at91sam9 cle} num addr_line -Configure the address line used for latching commands. The @var{num} -parameter is the value shown by @command{nand list}. -@end deffn -@deffn Command {at91sam9 ale} num addr_line -Configure the address line used for latching addresses. The @var{num} -parameter is the value shown by @command{nand list}. -@end deffn - -For the next two commands, it is assumed that the pins have already been -properly configured for input or output. -@deffn Command {at91sam9 rdy_busy} num pio_base_addr pin -Configure the RDY/nBUSY input from the NAND device. The @var{num} -parameter is the value shown by @command{nand list}. @var{pio_base_addr} -is the base address of the PIO controller and @var{pin} is the pin number. -@end deffn -@deffn Command {at91sam9 ce} num pio_base_addr pin -Configure the chip enable input to the NAND device. The @var{num} -parameter is the value shown by @command{nand list}. @var{pio_base_addr} -is the base address of the PIO controller and @var{pin} is the pin number. -@end deffn -@end deffn - -@deffn {NAND Driver} davinci -This driver handles the NAND controllers found on DaVinci family -chips from Texas Instruments. -It takes three extra parameters: -address of the NAND chip; -hardware ECC mode to use (@option{hwecc1}, -@option{hwecc4}, @option{hwecc4_infix}); -address of the AEMIF controller on this processor. -@example -nand device davinci dm355.arm 0x02000000 hwecc4 0x01e10000 -@end example -All DaVinci processors support the single-bit ECC hardware, -and newer ones also support the four-bit ECC hardware. -The @code{write_page} and @code{read_page} methods are used -to implement those ECC modes, unless they are disabled using -the @command{nand raw_access} command. -@end deffn - -@deffn {NAND Driver} lpc3180 -These controllers require an extra @command{nand device} -parameter: the clock rate used by the controller. -@deffn Command {lpc3180 select} num [mlc|slc] -Configures use of the MLC or SLC controller mode. -MLC implies use of hardware ECC. -The @var{num} parameter is the value shown by @command{nand list}. -@end deffn - -At this writing, this driver includes @code{write_page} -and @code{read_page} methods. Using @command{nand raw_access} -to disable those methods will prevent use of hardware ECC -in the MLC controller mode, but won't change SLC behavior. -@end deffn -@comment current lpc3180 code won't issue 5-byte address cycles - -@deffn {NAND Driver} mx3 -This driver handles the NAND controller in i.MX31. The mxc driver -should work for this chip aswell. -@end deffn - -@deffn {NAND Driver} mxc -This driver handles the NAND controller found in Freescale i.MX -chips. It has support for v1 (i.MX27 and i.MX31) and v2 (i.MX35). -The driver takes 3 extra arguments, chip (@option{mx27}, -@option{mx31}, @option{mx35}), ecc (@option{noecc}, @option{hwecc}) -and optionally if bad block information should be swapped between -main area and spare area (@option{biswap}), defaults to off. -@example -nand device mx35.nand mxc imx35.cpu mx35 hwecc biswap -@end example -@deffn Command {mxc biswap} bank_num [enable|disable] -Turns on/off bad block information swaping from main area, -without parameter query status. -@end deffn -@end deffn - -@deffn {NAND Driver} orion -These controllers require an extra @command{nand device} -parameter: the address of the controller. -@example -nand device orion 0xd8000000 -@end example -These controllers don't define any specialized commands. -At this writing, their drivers don't include @code{write_page} -or @code{read_page} methods, so @command{nand raw_access} won't -change any behavior. -@end deffn - -@deffn {NAND Driver} s3c2410 -@deffnx {NAND Driver} s3c2412 -@deffnx {NAND Driver} s3c2440 -@deffnx {NAND Driver} s3c2443 -@deffnx {NAND Driver} s3c6400 -These S3C family controllers don't have any special -@command{nand device} options, and don't define any -specialized commands. -At this writing, their drivers don't include @code{write_page} -or @code{read_page} methods, so @command{nand raw_access} won't -change any behavior. -@end deffn - -@section mFlash - -@subsection mFlash Configuration -@cindex mFlash Configuration - -@deffn {Config Command} {mflash bank} soc base RST_pin target -Configures a mflash for @var{soc} host bank at -address @var{base}. -The pin number format depends on the host GPIO naming convention. -Currently, the mflash driver supports s3c2440 and pxa270. - -Example for s3c2440 mflash where @var{RST pin} is GPIO B1: - -@example -mflash bank $_FLASHNAME s3c2440 0x10000000 1b 0 -@end example - -Example for pxa270 mflash where @var{RST pin} is GPIO 43: - -@example -mflash bank $_FLASHNAME pxa270 0x08000000 43 0 -@end example -@end deffn - -@subsection mFlash commands -@cindex mFlash commands - -@deffn Command {mflash config pll} frequency -Configure mflash PLL. -The @var{frequency} is the mflash input frequency, in Hz. -Issuing this command will erase mflash's whole internal nand and write new pll. -After this command, mflash needs power-on-reset for normal operation. -If pll was newly configured, storage and boot(optional) info also need to be update. -@end deffn - -@deffn Command {mflash config boot} -Configure bootable option. -If bootable option is set, mflash offer the first 8 sectors -(4kB) for boot. -@end deffn - -@deffn Command {mflash config storage} -Configure storage information. -For the normal storage operation, this information must be -written. -@end deffn - -@deffn Command {mflash dump} num filename offset size -Dump @var{size} bytes, starting at @var{offset} bytes from the -beginning of the bank @var{num}, to the file named @var{filename}. -@end deffn - -@deffn Command {mflash probe} -Probe mflash. -@end deffn - -@deffn Command {mflash write} num filename offset -Write the binary file @var{filename} to mflash bank @var{num}, starting at -@var{offset} bytes from the beginning of the bank. -@end deffn - -@node Flash Programming -@chapter Flash Programming - -OpenOCD implements numerous ways to program the target flash, whether internal or external. -Programming can be acheived by either using GDB @ref{programmingusinggdb,,Programming using GDB}, -or using the cmds given in @ref{flashprogrammingcommands,,Flash Programming Commands}. - -@*To simplify using the flash cmds directly a jimtcl script is available that handles the programming and verify stage. -OpenOCD will program/verify/reset the target and optionally shutdown. - -The script is executed as follows and by default the following actions will be peformed. -@enumerate -@item 'init' is executed. -@item 'reset init' is called to reset and halt the target, any 'reset init' scripts are executed. -@item @code{flash write_image} is called to erase and write any flash using the filename given. -@item @code{verify_image} is called if @option{verify} parameter is given. -@item @code{reset run} is called if @option{reset} parameter is given. -@item OpenOCD is shutdown if @option{exit} parameter is given. -@end enumerate - -An example of usage is given below. @xref{program}. - -@example -# program and verify using elf/hex/s19. verify and reset -# are optional parameters -openocd -f board/stm32f3discovery.cfg \ - -c "program filename.elf verify reset exit" - -# binary files need the flash address passing -openocd -f board/stm32f3discovery.cfg \ - -c "program filename.bin exit 0x08000000" -@end example - -@node PLD/FPGA Commands -@chapter PLD/FPGA Commands -@cindex PLD -@cindex FPGA - -Programmable Logic Devices (PLDs) and the more flexible -Field Programmable Gate Arrays (FPGAs) are both types of programmable hardware. -OpenOCD can support programming them. -Although PLDs are generally restrictive (cells are less functional, and -there are no special purpose cells for memory or computational tasks), -they share the same OpenOCD infrastructure. -Accordingly, both are called PLDs here. - -@section PLD/FPGA Configuration and Commands - -As it does for JTAG TAPs, debug targets, and flash chips (both NOR and NAND), -OpenOCD maintains a list of PLDs available for use in various commands. -Also, each such PLD requires a driver. - -They are referenced by the number shown by the @command{pld devices} command, -and new PLDs are defined by @command{pld device driver_name}. - -@deffn {Config Command} {pld device} driver_name tap_name [driver_options] -Defines a new PLD device, supported by driver @var{driver_name}, -using the TAP named @var{tap_name}. -The driver may make use of any @var{driver_options} to configure its -behavior. -@end deffn - -@deffn {Command} {pld devices} -Lists the PLDs and their numbers. -@end deffn - -@deffn {Command} {pld load} num filename -Loads the file @file{filename} into the PLD identified by @var{num}. -The file format must be inferred by the driver. -@end deffn - -@section PLD/FPGA Drivers, Options, and Commands - -Drivers may support PLD-specific options to the @command{pld device} -definition command, and may also define commands usable only with -that particular type of PLD. - -@deffn {FPGA Driver} virtex2 [no_jstart] -Virtex-II is a family of FPGAs sold by Xilinx. -It supports the IEEE 1532 standard for In-System Configuration (ISC). - -If @var{no_jstart} is non-zero, the JSTART instruction is not used after -loading the bitstream. While required for Series2, Series3, and Series6, it -breaks bitstream loading on Series7. - -@deffn {Command} {virtex2 read_stat} num -Reads and displays the Virtex-II status register (STAT) -for FPGA @var{num}. -@end deffn -@end deffn - -@node General Commands -@chapter General Commands -@cindex commands - -The commands documented in this chapter here are common commands that -you, as a human, may want to type and see the output of. Configuration type -commands are documented elsewhere. - -Intent: -@itemize @bullet -@item @b{Source Of Commands} -@* OpenOCD commands can occur in a configuration script (discussed -elsewhere) or typed manually by a human or supplied programatically, -or via one of several TCP/IP Ports. - -@item @b{From the human} -@* A human should interact with the telnet interface (default port: 4444) -or via GDB (default port 3333). - -To issue commands from within a GDB session, use the @option{monitor} -command, e.g. use @option{monitor poll} to issue the @option{poll} -command. All output is relayed through the GDB session. - -@item @b{Machine Interface} -The Tcl interface's intent is to be a machine interface. The default Tcl -port is 5555. -@end itemize - - -@section Daemon Commands - -@deffn {Command} exit -Exits the current telnet session. -@end deffn - -@deffn {Command} help [string] -With no parameters, prints help text for all commands. -Otherwise, prints each helptext containing @var{string}. -Not every command provides helptext. - -Configuration commands, and commands valid at any time, are -explicitly noted in parenthesis. -In most cases, no such restriction is listed; this indicates commands -which are only available after the configuration stage has completed. -@end deffn - -@deffn Command sleep msec [@option{busy}] -Wait for at least @var{msec} milliseconds before resuming. -If @option{busy} is passed, busy-wait instead of sleeping. -(This option is strongly discouraged.) -Useful in connection with script files -(@command{script} command and @command{target_name} configuration). -@end deffn - -@deffn Command shutdown [@option{error}] -Close the OpenOCD daemon, disconnecting all clients (GDB, telnet, -other). If option @option{error} is used, OpenOCD will return a -non-zero exit code to the parent process. -@end deffn - -@anchor{debuglevel} -@deffn Command debug_level [n] -@cindex message level -Display debug level. -If @var{n} (from 0..3) is provided, then set it to that level. -This affects the kind of messages sent to the server log. -Level 0 is error messages only; -level 1 adds warnings; -level 2 adds informational messages; -and level 3 adds debugging messages. -The default is level 2, but that can be overridden on -the command line along with the location of that log -file (which is normally the server's standard output). -@xref{Running}. -@end deffn - -@deffn Command echo [-n] message -Logs a message at "user" priority. -Output @var{message} to stdout. -Option "-n" suppresses trailing newline. -@example -echo "Downloading kernel -- please wait" -@end example -@end deffn - -@deffn Command log_output [filename] -Redirect logging to @var{filename}; -the initial log output channel is stderr. -@end deffn - -@deffn Command add_script_search_dir [directory] -Add @var{directory} to the file/script search path. -@end deffn - -@deffn Command bindto [name] -Specify address by name on which to listen for incoming TCP/IP connections. -By default, OpenOCD will listen on all available interfaces. -@end deffn - -@anchor{targetstatehandling} -@section Target State handling -@cindex reset -@cindex halt -@cindex target initialization - -In this section ``target'' refers to a CPU configured as -shown earlier (@pxref{CPU Configuration}). -These commands, like many, implicitly refer to -a current target which is used to perform the -various operations. The current target may be changed -by using @command{targets} command with the name of the -target which should become current. - -@deffn Command reg [(number|name) [(value|'force')]] -Access a single register by @var{number} or by its @var{name}. -The target must generally be halted before access to CPU core -registers is allowed. Depending on the hardware, some other -registers may be accessible while the target is running. - -@emph{With no arguments}: -list all available registers for the current target, -showing number, name, size, value, and cache status. -For valid entries, a value is shown; valid entries -which are also dirty (and will be written back later) -are flagged as such. - -@emph{With number/name}: display that register's value. -Use @var{force} argument to read directly from the target, -bypassing any internal cache. - -@emph{With both number/name and value}: set register's value. -Writes may be held in a writeback cache internal to OpenOCD, -so that setting the value marks the register as dirty instead -of immediately flushing that value. Resuming CPU execution -(including by single stepping) or otherwise activating the -relevant module will flush such values. - -Cores may have surprisingly many registers in their -Debug and trace infrastructure: - -@example -> reg -===== ARM registers -(0) r0 (/32): 0x0000D3C2 (dirty) -(1) r1 (/32): 0xFD61F31C -(2) r2 (/32) -... -(164) ETM_contextid_comparator_mask (/32) -> -@end example -@end deffn - -@deffn Command halt [ms] -@deffnx Command wait_halt [ms] -The @command{halt} command first sends a halt request to the target, -which @command{wait_halt} doesn't. -Otherwise these behave the same: wait up to @var{ms} milliseconds, -or 5 seconds if there is no parameter, for the target to halt -(and enter debug mode). -Using 0 as the @var{ms} parameter prevents OpenOCD from waiting. - -@quotation Warning -On ARM cores, software using the @emph{wait for interrupt} operation -often blocks the JTAG access needed by a @command{halt} command. -This is because that operation also puts the core into a low -power mode by gating the core clock; -but the core clock is needed to detect JTAG clock transitions. - -One partial workaround uses adaptive clocking: when the core is -interrupted the operation completes, then JTAG clocks are accepted -at least until the interrupt handler completes. -However, this workaround is often unusable since the processor, board, -and JTAG adapter must all support adaptive JTAG clocking. -Also, it can't work until an interrupt is issued. - -A more complete workaround is to not use that operation while you -work with a JTAG debugger. -Tasking environments generaly have idle loops where the body is the -@emph{wait for interrupt} operation. -(On older cores, it is a coprocessor action; -newer cores have a @option{wfi} instruction.) -Such loops can just remove that operation, at the cost of higher -power consumption (because the CPU is needlessly clocked). -@end quotation - -@end deffn - -@deffn Command resume [address] -Resume the target at its current code position, -or the optional @var{address} if it is provided. -OpenOCD will wait 5 seconds for the target to resume. -@end deffn - -@deffn Command step [address] -Single-step the target at its current code position, -or the optional @var{address} if it is provided. -@end deffn - -@anchor{resetcommand} -@deffn Command reset -@deffnx Command {reset run} -@deffnx Command {reset halt} -@deffnx Command {reset init} -Perform as hard a reset as possible, using SRST if possible. -@emph{All defined targets will be reset, and target -events will fire during the reset sequence.} - -The optional parameter specifies what should -happen after the reset. -If there is no parameter, a @command{reset run} is executed. -The other options will not work on all systems. -@xref{Reset Configuration}. - -@itemize @minus -@item @b{run} Let the target run -@item @b{halt} Immediately halt the target -@item @b{init} Immediately halt the target, and execute the reset-init script -@end itemize -@end deffn - -@deffn Command soft_reset_halt -Requesting target halt and executing a soft reset. This is often used -when a target cannot be reset and halted. The target, after reset is -released begins to execute code. OpenOCD attempts to stop the CPU and -then sets the program counter back to the reset vector. Unfortunately -the code that was executed may have left the hardware in an unknown -state. -@end deffn - -@section I/O Utilities - -These commands are available when -OpenOCD is built with @option{--enable-ioutil}. -They are mainly useful on embedded targets, -notably the ZY1000. -Hosts with operating systems have complementary tools. - -@emph{Note:} there are several more such commands. - -@deffn Command append_file filename [string]* -Appends the @var{string} parameters to -the text file @file{filename}. -Each string except the last one is followed by one space. -The last string is followed by a newline. -@end deffn - -@deffn Command cat filename -Reads and displays the text file @file{filename}. -@end deffn - -@deffn Command cp src_filename dest_filename -Copies contents from the file @file{src_filename} -into @file{dest_filename}. -@end deffn - -@deffn Command ip -@emph{No description provided.} -@end deffn - -@deffn Command ls -@emph{No description provided.} -@end deffn - -@deffn Command mac -@emph{No description provided.} -@end deffn - -@deffn Command meminfo -Display available RAM memory on OpenOCD host. -Used in OpenOCD regression testing scripts. -@end deffn - -@deffn Command peek -@emph{No description provided.} -@end deffn - -@deffn Command poke -@emph{No description provided.} -@end deffn - -@deffn Command rm filename -@c "rm" has both normal and Jim-level versions?? -Unlinks the file @file{filename}. -@end deffn - -@deffn Command trunc filename -Removes all data in the file @file{filename}. -@end deffn - -@anchor{memoryaccess} -@section Memory access commands -@cindex memory access - -These commands allow accesses of a specific size to the memory -system. Often these are used to configure the current target in some -special way. For example - one may need to write certain values to the -SDRAM controller to enable SDRAM. - -@enumerate -@item Use the @command{targets} (plural) command -to change the current target. -@item In system level scripts these commands are deprecated. -Please use their TARGET object siblings to avoid making assumptions -about what TAP is the current target, or about MMU configuration. -@end enumerate - -@deffn Command mdw [phys] addr [count] -@deffnx Command mdh [phys] addr [count] -@deffnx Command mdb [phys] addr [count] -Display contents of address @var{addr}, as -32-bit words (@command{mdw}), 16-bit halfwords (@command{mdh}), -or 8-bit bytes (@command{mdb}). -When the current target has an MMU which is present and active, -@var{addr} is interpreted as a virtual address. -Otherwise, or if the optional @var{phys} flag is specified, -@var{addr} is interpreted as a physical address. -If @var{count} is specified, displays that many units. -(If you want to manipulate the data instead of displaying it, -see the @code{mem2array} primitives.) -@end deffn - -@deffn Command mww [phys] addr word -@deffnx Command mwh [phys] addr halfword -@deffnx Command mwb [phys] addr byte -Writes the specified @var{word} (32 bits), -@var{halfword} (16 bits), or @var{byte} (8-bit) value, -at the specified address @var{addr}. -When the current target has an MMU which is present and active, -@var{addr} is interpreted as a virtual address. -Otherwise, or if the optional @var{phys} flag is specified, -@var{addr} is interpreted as a physical address. -@end deffn - -@anchor{imageaccess} -@section Image loading commands -@cindex image loading -@cindex image dumping - -@deffn Command {dump_image} filename address size -Dump @var{size} bytes of target memory starting at @var{address} to the -binary file named @var{filename}. -@end deffn - -@deffn Command {fast_load} -Loads an image stored in memory by @command{fast_load_image} to the -current target. Must be preceeded by fast_load_image. -@end deffn - -@deffn Command {fast_load_image} filename address [@option{bin}|@option{ihex}|@option{elf}|@option{s19}] -Normally you should be using @command{load_image} or GDB load. However, for -testing purposes or when I/O overhead is significant(OpenOCD running on an embedded -host), storing the image in memory and uploading the image to the target -can be a way to upload e.g. multiple debug sessions when the binary does not change. -Arguments are the same as @command{load_image}, but the image is stored in OpenOCD host -memory, i.e. does not affect target. This approach is also useful when profiling -target programming performance as I/O and target programming can easily be profiled -separately. -@end deffn - -@deffn Command {load_image} filename address [[@option{bin}|@option{ihex}|@option{elf}|@option{s19}] @option{min_addr} @option{max_length}] -Load image from file @var{filename} to target memory offset by @var{address} from its load address. -The file format may optionally be specified -(@option{bin}, @option{ihex}, @option{elf}, or @option{s19}). -In addition the following arguments may be specifed: -@var{min_addr} - ignore data below @var{min_addr} (this is w.r.t. to the target's load address + @var{address}) -@var{max_length} - maximum number of bytes to load. -@example -proc load_image_bin @{fname foffset address length @} @{ - # Load data from fname filename at foffset offset to - # target at address. Load at most length bytes. - load_image $fname [expr $address - $foffset] bin \ - $address $length -@} -@end example -@end deffn - -@deffn Command {test_image} filename [address [@option{bin}|@option{ihex}|@option{elf}]] -Displays image section sizes and addresses -as if @var{filename} were loaded into target memory -starting at @var{address} (defaults to zero). -The file format may optionally be specified -(@option{bin}, @option{ihex}, or @option{elf}) -@end deffn - -@deffn Command {verify_image} filename address [@option{bin}|@option{ihex}|@option{elf}] -Verify @var{filename} against target memory starting at @var{address}. -The file format may optionally be specified -(@option{bin}, @option{ihex}, or @option{elf}) -This will first attempt a comparison using a CRC checksum, if this fails it will try a binary compare. -@end deffn - - -@section Breakpoint and Watchpoint commands -@cindex breakpoint -@cindex watchpoint - -CPUs often make debug modules accessible through JTAG, with -hardware support for a handful of code breakpoints and data -watchpoints. -In addition, CPUs almost always support software breakpoints. - -@deffn Command {bp} [address len [@option{hw}]] -With no parameters, lists all active breakpoints. -Else sets a breakpoint on code execution starting -at @var{address} for @var{length} bytes. -This is a software breakpoint, unless @option{hw} is specified -in which case it will be a hardware breakpoint. - -(@xref{arm9vectorcatch,,arm9 vector_catch}, or @pxref{xscalevectorcatch,,xscale vector_catch}, -for similar mechanisms that do not consume hardware breakpoints.) -@end deffn - -@deffn Command {rbp} address -Remove the breakpoint at @var{address}. -@end deffn - -@deffn Command {rwp} address -Remove data watchpoint on @var{address} -@end deffn - -@deffn Command {wp} [address len [(@option{r}|@option{w}|@option{a}) [value [mask]]]] -With no parameters, lists all active watchpoints. -Else sets a data watchpoint on data from @var{address} for @var{length} bytes. -The watch point is an "access" watchpoint unless -the @option{r} or @option{w} parameter is provided, -defining it as respectively a read or write watchpoint. -If a @var{value} is provided, that value is used when determining if -the watchpoint should trigger. The value may be first be masked -using @var{mask} to mark ``don't care'' fields. -@end deffn - -@section Misc Commands - -@cindex profiling -@deffn Command {profile} seconds filename [start end] -Profiling samples the CPU's program counter as quickly as possible, -which is useful for non-intrusive stochastic profiling. -Saves up to 10000 samples in @file{filename} using ``gmon.out'' -format. Optional @option{start} and @option{end} parameters allow to -limit the address range. -@end deffn - -@deffn Command {version} -Displays a string identifying the version of this OpenOCD server. -@end deffn - -@deffn Command {virt2phys} virtual_address -Requests the current target to map the specified @var{virtual_address} -to its corresponding physical address, and displays the result. -@end deffn - -@node Architecture and Core Commands -@chapter Architecture and Core Commands -@cindex Architecture Specific Commands -@cindex Core Specific Commands - -Most CPUs have specialized JTAG operations to support debugging. -OpenOCD packages most such operations in its standard command framework. -Some of those operations don't fit well in that framework, so they are -exposed here as architecture or implementation (core) specific commands. - -@anchor{armhardwaretracing} -@section ARM Hardware Tracing -@cindex tracing -@cindex ETM -@cindex ETB - -CPUs based on ARM cores may include standard tracing interfaces, -based on an ``Embedded Trace Module'' (ETM) which sends voluminous -address and data bus trace records to a ``Trace Port''. - -@itemize -@item -Development-oriented boards will sometimes provide a high speed -trace connector for collecting that data, when the particular CPU -supports such an interface. -(The standard connector is a 38-pin Mictor, with both JTAG -and trace port support.) -Those trace connectors are supported by higher end JTAG adapters -and some logic analyzer modules; frequently those modules can -buffer several megabytes of trace data. -Configuring an ETM coupled to such an external trace port belongs -in the board-specific configuration file. -@item -If the CPU doesn't provide an external interface, it probably -has an ``Embedded Trace Buffer'' (ETB) on the chip, which is a -dedicated SRAM. 4KBytes is one common ETB size. -Configuring an ETM coupled only to an ETB belongs in the CPU-specific -(target) configuration file, since it works the same on all boards. -@end itemize - -ETM support in OpenOCD doesn't seem to be widely used yet. - -@quotation Issues -ETM support may be buggy, and at least some @command{etm config} -parameters should be detected by asking the ETM for them. - -ETM trigger events could also implement a kind of complex -hardware breakpoint, much more powerful than the simple -watchpoint hardware exported by EmbeddedICE modules. -@emph{Such breakpoints can be triggered even when using the -dummy trace port driver}. - -It seems like a GDB hookup should be possible, -as well as tracing only during specific states -(perhaps @emph{handling IRQ 23} or @emph{calls foo()}). - -There should be GUI tools to manipulate saved trace data and help -analyse it in conjunction with the source code. -It's unclear how much of a common interface is shared -with the current XScale trace support, or should be -shared with eventual Nexus-style trace module support. - -At this writing (November 2009) only ARM7, ARM9, and ARM11 support -for ETM modules is available. The code should be able to -work with some newer cores; but not all of them support -this original style of JTAG access. -@end quotation - -@subsection ETM Configuration -ETM setup is coupled with the trace port driver configuration. - -@deffn {Config Command} {etm config} target width mode clocking driver -Declares the ETM associated with @var{target}, and associates it -with a given trace port @var{driver}. @xref{traceportdrivers,,Trace Port Drivers}. - -Several of the parameters must reflect the trace port capabilities, -which are a function of silicon capabilties (exposed later -using @command{etm info}) and of what hardware is connected to -that port (such as an external pod, or ETB). -The @var{width} must be either 4, 8, or 16, -except with ETMv3.0 and newer modules which may also -support 1, 2, 24, 32, 48, and 64 bit widths. -(With those versions, @command{etm info} also shows whether -the selected port width and mode are supported.) - -The @var{mode} must be @option{normal}, @option{multiplexed}, -or @option{demultiplexed}. -The @var{clocking} must be @option{half} or @option{full}. - -@quotation Warning -With ETMv3.0 and newer, the bits set with the @var{mode} and -@var{clocking} parameters both control the mode. -This modified mode does not map to the values supported by -previous ETM modules, so this syntax is subject to change. -@end quotation - -@quotation Note -You can see the ETM registers using the @command{reg} command. -Not all possible registers are present in every ETM. -Most of the registers are write-only, and are used to configure -what CPU activities are traced. -@end quotation -@end deffn - -@deffn Command {etm info} -Displays information about the current target's ETM. -This includes resource counts from the @code{ETM_CONFIG} register, -as well as silicon capabilities (except on rather old modules). -from the @code{ETM_SYS_CONFIG} register. -@end deffn - -@deffn Command {etm status} -Displays status of the current target's ETM and trace port driver: -is the ETM idle, or is it collecting data? -Did trace data overflow? -Was it triggered? -@end deffn - -@deffn Command {etm tracemode} [type context_id_bits cycle_accurate branch_output] -Displays what data that ETM will collect. -If arguments are provided, first configures that data. -When the configuration changes, tracing is stopped -and any buffered trace data is invalidated. - -@itemize -@item @var{type} ... describing how data accesses are traced, -when they pass any ViewData filtering that that was set up. -The value is one of -@option{none} (save nothing), -@option{data} (save data), -@option{address} (save addresses), -@option{all} (save data and addresses) -@item @var{context_id_bits} ... 0, 8, 16, or 32 -@item @var{cycle_accurate} ... @option{enable} or @option{disable} -cycle-accurate instruction tracing. -Before ETMv3, enabling this causes much extra data to be recorded. -@item @var{branch_output} ... @option{enable} or @option{disable}. -Disable this unless you need to try reconstructing the instruction -trace stream without an image of the code. -@end itemize -@end deffn - -@deffn Command {etm trigger_debug} (@option{enable}|@option{disable}) -Displays whether ETM triggering debug entry (like a breakpoint) is -enabled or disabled, after optionally modifying that configuration. -The default behaviour is @option{disable}. -Any change takes effect after the next @command{etm start}. - -By using script commands to configure ETM registers, you can make the -processor enter debug state automatically when certain conditions, -more complex than supported by the breakpoint hardware, happen. -@end deffn - -@subsection ETM Trace Operation - -After setting up the ETM, you can use it to collect data. -That data can be exported to files for later analysis. -It can also be parsed with OpenOCD, for basic sanity checking. - -To configure what is being traced, you will need to write -various trace registers using @command{reg ETM_*} commands. -For the definitions of these registers, read ARM publication -@emph{IHI 0014, ``Embedded Trace Macrocell, Architecture Specification''}. -Be aware that most of the relevant registers are write-only, -and that ETM resources are limited. There are only a handful -of address comparators, data comparators, counters, and so on. - -Examples of scenarios you might arrange to trace include: - -@itemize -@item Code flow within a function, @emph{excluding} subroutines -it calls. Use address range comparators to enable tracing -for instruction access within that function's body. -@item Code flow within a function, @emph{including} subroutines -it calls. Use the sequencer and address comparators to activate -tracing on an ``entered function'' state, then deactivate it by -exiting that state when the function's exit code is invoked. -@item Code flow starting at the fifth invocation of a function, -combining one of the above models with a counter. -@item CPU data accesses to the registers for a particular device, -using address range comparators and the ViewData logic. -@item Such data accesses only during IRQ handling, combining the above -model with sequencer triggers which on entry and exit to the IRQ handler. -@item @emph{... more} -@end itemize - -At this writing, September 2009, there are no Tcl utility -procedures to help set up any common tracing scenarios. - -@deffn Command {etm analyze} -Reads trace data into memory, if it wasn't already present. -Decodes and prints the data that was collected. -@end deffn - -@deffn Command {etm dump} filename -Stores the captured trace data in @file{filename}. -@end deffn - -@deffn Command {etm image} filename [base_address] [type] -Opens an image file. -@end deffn - -@deffn Command {etm load} filename -Loads captured trace data from @file{filename}. -@end deffn - -@deffn Command {etm start} -Starts trace data collection. -@end deffn - -@deffn Command {etm stop} -Stops trace data collection. -@end deffn - -@anchor{traceportdrivers} -@subsection Trace Port Drivers - -To use an ETM trace port it must be associated with a driver. - -@deffn {Trace Port Driver} dummy -Use the @option{dummy} driver if you are configuring an ETM that's -not connected to anything (on-chip ETB or off-chip trace connector). -@emph{This driver lets OpenOCD talk to the ETM, but it does not expose -any trace data collection.} -@deffn {Config Command} {etm_dummy config} target -Associates the ETM for @var{target} with a dummy driver. -@end deffn -@end deffn - -@deffn {Trace Port Driver} etb -Use the @option{etb} driver if you are configuring an ETM -to use on-chip ETB memory. -@deffn {Config Command} {etb config} target etb_tap -Associates the ETM for @var{target} with the ETB at @var{etb_tap}. -You can see the ETB registers using the @command{reg} command. -@end deffn -@deffn Command {etb trigger_percent} [percent] -This displays, or optionally changes, ETB behavior after the -ETM's configured @emph{trigger} event fires. -It controls how much more trace data is saved after the (single) -trace trigger becomes active. - -@itemize -@item The default corresponds to @emph{trace around} usage, -recording 50 percent data before the event and the rest -afterwards. -@item The minimum value of @var{percent} is 2 percent, -recording almost exclusively data before the trigger. -Such extreme @emph{trace before} usage can help figure out -what caused that event to happen. -@item The maximum value of @var{percent} is 100 percent, -recording data almost exclusively after the event. -This extreme @emph{trace after} usage might help sort out -how the event caused trouble. -@end itemize -@c REVISIT allow "break" too -- enter debug mode. -@end deffn - -@end deffn - -@deffn {Trace Port Driver} oocd_trace -This driver isn't available unless OpenOCD was explicitly configured -with the @option{--enable-oocd_trace} option. You probably don't want -to configure it unless you've built the appropriate prototype hardware; -it's @emph{proof-of-concept} software. - -Use the @option{oocd_trace} driver if you are configuring an ETM that's -connected to an off-chip trace connector. - -@deffn {Config Command} {oocd_trace config} target tty -Associates the ETM for @var{target} with a trace driver which -collects data through the serial port @var{tty}. -@end deffn - -@deffn Command {oocd_trace resync} -Re-synchronizes with the capture clock. -@end deffn - -@deffn Command {oocd_trace status} -Reports whether the capture clock is locked or not. -@end deffn -@end deffn - - -@section Generic ARM -@cindex ARM - -These commands should be available on all ARM processors. -They are available in addition to other core-specific -commands that may be available. - -@deffn Command {arm core_state} [@option{arm}|@option{thumb}] -Displays the core_state, optionally changing it to process -either @option{arm} or @option{thumb} instructions. -The target may later be resumed in the currently set core_state. -(Processors may also support the Jazelle state, but -that is not currently supported in OpenOCD.) -@end deffn - -@deffn Command {arm disassemble} address [count [@option{thumb}]] -@cindex disassemble -Disassembles @var{count} instructions starting at @var{address}. -If @var{count} is not specified, a single instruction is disassembled. -If @option{thumb} is specified, or the low bit of the address is set, -Thumb2 (mixed 16/32-bit) instructions are used; -else ARM (32-bit) instructions are used. -(Processors may also support the Jazelle state, but -those instructions are not currently understood by OpenOCD.) - -Note that all Thumb instructions are Thumb2 instructions, -so older processors (without Thumb2 support) will still -see correct disassembly of Thumb code. -Also, ThumbEE opcodes are the same as Thumb2, -with a handful of exceptions. -ThumbEE disassembly currently has no explicit support. -@end deffn - -@deffn Command {arm mcr} pX op1 CRn CRm op2 value -Write @var{value} to a coprocessor @var{pX} register -passing parameters @var{CRn}, -@var{CRm}, opcodes @var{opc1} and @var{opc2}, -and using the MCR instruction. -(Parameter sequence matches the ARM instruction, but omits -an ARM register.) -@end deffn - -@deffn Command {arm mrc} pX coproc op1 CRn CRm op2 -Read a coprocessor @var{pX} register passing parameters @var{CRn}, -@var{CRm}, opcodes @var{opc1} and @var{opc2}, -and the MRC instruction. -Returns the result so it can be manipulated by Jim scripts. -(Parameter sequence matches the ARM instruction, but omits -an ARM register.) -@end deffn - -@deffn Command {arm reg} -Display a table of all banked core registers, fetching the current value from every -core mode if necessary. -@end deffn - -@deffn Command {arm semihosting} [@option{enable}|@option{disable}] -@cindex ARM semihosting -Display status of semihosting, after optionally changing that status. - -Semihosting allows for code executing on an ARM target to use the -I/O facilities on the host computer i.e. the system where OpenOCD -is running. The target application must be linked against a library -implementing the ARM semihosting convention that forwards operation -requests by using a special SVC instruction that is trapped at the -Supervisor Call vector by OpenOCD. -@end deffn - -@section ARMv4 and ARMv5 Architecture -@cindex ARMv4 -@cindex ARMv5 - -The ARMv4 and ARMv5 architectures are widely used in embedded systems, -and introduced core parts of the instruction set in use today. -That includes the Thumb instruction set, introduced in the ARMv4T -variant. - -@subsection ARM7 and ARM9 specific commands -@cindex ARM7 -@cindex ARM9 - -These commands are specific to ARM7 and ARM9 cores, like ARM7TDMI, ARM720T, -ARM9TDMI, ARM920T or ARM926EJ-S. -They are available in addition to the ARM commands, -and any other core-specific commands that may be available. - -@deffn Command {arm7_9 dbgrq} [@option{enable}|@option{disable}] -Displays the value of the flag controlling use of the -the EmbeddedIce DBGRQ signal to force entry into debug mode, -instead of breakpoints. -If a boolean parameter is provided, first assigns that flag. - -This should be -safe for all but ARM7TDMI-S cores (like NXP LPC). -This feature is enabled by default on most ARM9 cores, -including ARM9TDMI, ARM920T, and ARM926EJ-S. -@end deffn - -@deffn Command {arm7_9 dcc_downloads} [@option{enable}|@option{disable}] -@cindex DCC -Displays the value of the flag controlling use of the debug communications -channel (DCC) to write larger (>128 byte) amounts of memory. -If a boolean parameter is provided, first assigns that flag. - -DCC downloads offer a huge speed increase, but might be -unsafe, especially with targets running at very low speeds. This command was introduced -with OpenOCD rev. 60, and requires a few bytes of working area. -@end deffn - -@deffn Command {arm7_9 fast_memory_access} [@option{enable}|@option{disable}] -Displays the value of the flag controlling use of memory writes and reads -that don't check completion of the operation. -If a boolean parameter is provided, first assigns that flag. - -This provides a huge speed increase, especially with USB JTAG -cables (FT2232), but might be unsafe if used with targets running at very low -speeds, like the 32kHz startup clock of an AT91RM9200. -@end deffn - -@subsection ARM720T specific commands -@cindex ARM720T - -These commands are available to ARM720T based CPUs, -which are implementations of the ARMv4T architecture -based on the ARM7TDMI-S integer core. -They are available in addition to the ARM and ARM7/ARM9 commands. - -@deffn Command {arm720t cp15} opcode [value] -@emph{DEPRECATED -- avoid using this. -Use the @command{arm mrc} or @command{arm mcr} commands instead.} - -Display cp15 register returned by the ARM instruction @var{opcode}; -else if a @var{value} is provided, that value is written to that register. -The @var{opcode} should be the value of either an MRC or MCR instruction. -@end deffn - -@subsection ARM9 specific commands -@cindex ARM9 - -ARM9-family cores are built around ARM9TDMI or ARM9E (including ARM9EJS) -integer processors. -Such cores include the ARM920T, ARM926EJ-S, and ARM966. - -@c 9-june-2009: tried this on arm920t, it didn't work. -@c no-params always lists nothing caught, and that's how it acts. -@c 23-oct-2009: doesn't work _consistently_ ... as if the ICE -@c versions have different rules about when they commit writes. - -@anchor{arm9vectorcatch} -@deffn Command {arm9 vector_catch} [@option{all}|@option{none}|list] -@cindex vector_catch -Vector Catch hardware provides a sort of dedicated breakpoint -for hardware events such as reset, interrupt, and abort. -You can use this to conserve normal breakpoint resources, -so long as you're not concerned with code that branches directly -to those hardware vectors. - -This always finishes by listing the current configuration. -If parameters are provided, it first reconfigures the -vector catch hardware to intercept -@option{all} of the hardware vectors, -@option{none} of them, -or a list with one or more of the following: -@option{reset} @option{undef} @option{swi} @option{pabt} @option{dabt} -@option{irq} @option{fiq}. -@end deffn - -@subsection ARM920T specific commands -@cindex ARM920T - -These commands are available to ARM920T based CPUs, -which are implementations of the ARMv4T architecture -built using the ARM9TDMI integer core. -They are available in addition to the ARM, ARM7/ARM9, -and ARM9 commands. - -@deffn Command {arm920t cache_info} -Print information about the caches found. This allows to see whether your target -is an ARM920T (2x16kByte cache) or ARM922T (2x8kByte cache). -@end deffn - -@deffn Command {arm920t cp15} regnum [value] -Display cp15 register @var{regnum}; -else if a @var{value} is provided, that value is written to that register. -This uses "physical access" and the register number is as -shown in bits 38..33 of table 9-9 in the ARM920T TRM. -(Not all registers can be written.) -@end deffn - -@deffn Command {arm920t cp15i} opcode [value [address]] -@emph{DEPRECATED -- avoid using this. -Use the @command{arm mrc} or @command{arm mcr} commands instead.} - -Interpreted access using ARM instruction @var{opcode}, which should -be the value of either an MRC or MCR instruction -(as shown tables 9-11, 9-12, and 9-13 in the ARM920T TRM). -If no @var{value} is provided, the result is displayed. -Else if that value is written using the specified @var{address}, -or using zero if no other address is provided. -@end deffn - -@deffn Command {arm920t read_cache} filename -Dump the content of ICache and DCache to a file named @file{filename}. -@end deffn - -@deffn Command {arm920t read_mmu} filename -Dump the content of the ITLB and DTLB to a file named @file{filename}. -@end deffn - -@subsection ARM926ej-s specific commands -@cindex ARM926ej-s - -These commands are available to ARM926ej-s based CPUs, -which are implementations of the ARMv5TEJ architecture -based on the ARM9EJ-S integer core. -They are available in addition to the ARM, ARM7/ARM9, -and ARM9 commands. - -The Feroceon cores also support these commands, although -they are not built from ARM926ej-s designs. - -@deffn Command {arm926ejs cache_info} -Print information about the caches found. -@end deffn - -@subsection ARM966E specific commands -@cindex ARM966E - -These commands are available to ARM966 based CPUs, -which are implementations of the ARMv5TE architecture. -They are available in addition to the ARM, ARM7/ARM9, -and ARM9 commands. - -@deffn Command {arm966e cp15} regnum [value] -Display cp15 register @var{regnum}; -else if a @var{value} is provided, that value is written to that register. -The six bit @var{regnum} values are bits 37..32 from table 7-2 of the -ARM966E-S TRM. -There is no current control over bits 31..30 from that table, -as required for BIST support. -@end deffn - -@subsection XScale specific commands -@cindex XScale - -Some notes about the debug implementation on the XScale CPUs: - -The XScale CPU provides a special debug-only mini-instruction cache -(mini-IC) in which exception vectors and target-resident debug handler -code are placed by OpenOCD. In order to get access to the CPU, OpenOCD -must point vector 0 (the reset vector) to the entry of the debug -handler. However, this means that the complete first cacheline in the -mini-IC is marked valid, which makes the CPU fetch all exception -handlers from the mini-IC, ignoring the code in RAM. - -To address this situation, OpenOCD provides the @code{xscale -vector_table} command, which allows the user to explicity write -individual entries to either the high or low vector table stored in -the mini-IC. - -It is recommended to place a pc-relative indirect branch in the vector -table, and put the branch destination somewhere in memory. Doing so -makes sure the code in the vector table stays constant regardless of -code layout in memory: -@example -_vectors: - ldr pc,[pc,#0x100-8] - ldr pc,[pc,#0x100-8] - ldr pc,[pc,#0x100-8] - ldr pc,[pc,#0x100-8] - ldr pc,[pc,#0x100-8] - ldr pc,[pc,#0x100-8] - ldr pc,[pc,#0x100-8] - ldr pc,[pc,#0x100-8] - .org 0x100 - .long real_reset_vector - .long real_ui_handler - .long real_swi_handler - .long real_pf_abort - .long real_data_abort - .long 0 /* unused */ - .long real_irq_handler - .long real_fiq_handler -@end example - -Alternatively, you may choose to keep some or all of the mini-IC -vector table entries synced with those written to memory by your -system software. The mini-IC can not be modified while the processor -is executing, but for each vector table entry not previously defined -using the @code{xscale vector_table} command, OpenOCD will copy the -value from memory to the mini-IC every time execution resumes from a -halt. This is done for both high and low vector tables (although the -table not in use may not be mapped to valid memory, and in this case -that copy operation will silently fail). This means that you will -need to briefly halt execution at some strategic point during system -start-up; e.g., after the software has initialized the vector table, -but before exceptions are enabled. A breakpoint can be used to -accomplish this once the appropriate location in the start-up code has -been identified. A watchpoint over the vector table region is helpful -in finding the location if you're not sure. Note that the same -situation exists any time the vector table is modified by the system -software. - -The debug handler must be placed somewhere in the address space using -the @code{xscale debug_handler} command. The allowed locations for the -debug handler are either (0x800 - 0x1fef800) or (0xfe000800 - -0xfffff800). The default value is 0xfe000800. - -XScale has resources to support two hardware breakpoints and two -watchpoints. However, the following restrictions on watchpoint -functionality apply: (1) the value and mask arguments to the @code{wp} -command are not supported, (2) the watchpoint length must be a -power of two and not less than four, and can not be greater than the -watchpoint address, and (3) a watchpoint with a length greater than -four consumes all the watchpoint hardware resources. This means that -at any one time, you can have enabled either two watchpoints with a -length of four, or one watchpoint with a length greater than four. - -These commands are available to XScale based CPUs, -which are implementations of the ARMv5TE architecture. - -@deffn Command {xscale analyze_trace} -Displays the contents of the trace buffer. -@end deffn - -@deffn Command {xscale cache_clean_address} address -Changes the address used when cleaning the data cache. -@end deffn - -@deffn Command {xscale cache_info} -Displays information about the CPU caches. -@end deffn - -@deffn Command {xscale cp15} regnum [value] -Display cp15 register @var{regnum}; -else if a @var{value} is provided, that value is written to that register. -@end deffn - -@deffn Command {xscale debug_handler} target address -Changes the address used for the specified target's debug handler. -@end deffn - -@deffn Command {xscale dcache} [@option{enable}|@option{disable}] -Enables or disable the CPU's data cache. -@end deffn - -@deffn Command {xscale dump_trace} filename -Dumps the raw contents of the trace buffer to @file{filename}. -@end deffn - -@deffn Command {xscale icache} [@option{enable}|@option{disable}] -Enables or disable the CPU's instruction cache. -@end deffn - -@deffn Command {xscale mmu} [@option{enable}|@option{disable}] -Enables or disable the CPU's memory management unit. -@end deffn - -@deffn Command {xscale trace_buffer} [@option{enable}|@option{disable} [@option{fill} [n] | @option{wrap}]] -Displays the trace buffer status, after optionally -enabling or disabling the trace buffer -and modifying how it is emptied. -@end deffn - -@deffn Command {xscale trace_image} filename [offset [type]] -Opens a trace image from @file{filename}, optionally rebasing -its segment addresses by @var{offset}. -The image @var{type} may be one of -@option{bin} (binary), @option{ihex} (Intel hex), -@option{elf} (ELF file), @option{s19} (Motorola s19), -@option{mem}, or @option{builder}. -@end deffn - -@anchor{xscalevectorcatch} -@deffn Command {xscale vector_catch} [mask] -@cindex vector_catch -Display a bitmask showing the hardware vectors to catch. -If the optional parameter is provided, first set the bitmask to that value. - -The mask bits correspond with bit 16..23 in the DCSR: -@example -0x01 Trap Reset -0x02 Trap Undefined Instructions -0x04 Trap Software Interrupt -0x08 Trap Prefetch Abort -0x10 Trap Data Abort -0x20 reserved -0x40 Trap IRQ -0x80 Trap FIQ -@end example -@end deffn - -@deffn Command {xscale vector_table} [(@option{low}|@option{high}) index value] -@cindex vector_table - -Set an entry in the mini-IC vector table. There are two tables: one for -low vectors (at 0x00000000), and one for high vectors (0xFFFF0000), each -holding the 8 exception vectors. @var{index} can be 1-7, because vector 0 -points to the debug handler entry and can not be overwritten. -@var{value} holds the 32-bit opcode that is placed in the mini-IC. - -Without arguments, the current settings are displayed. - -@end deffn - -@section ARMv6 Architecture -@cindex ARMv6 - -@subsection ARM11 specific commands -@cindex ARM11 - -@deffn Command {arm11 memwrite burst} [@option{enable}|@option{disable}] -Displays the value of the memwrite burst-enable flag, -which is enabled by default. -If a boolean parameter is provided, first assigns that flag. -Burst writes are only used for memory writes larger than 1 word. -They improve performance by assuming that the CPU has read each data -word over JTAG and completed its write before the next word arrives, -instead of polling for a status flag to verify that completion. -This is usually safe, because JTAG runs much slower than the CPU. -@end deffn - -@deffn Command {arm11 memwrite error_fatal} [@option{enable}|@option{disable}] -Displays the value of the memwrite error_fatal flag, -which is enabled by default. -If a boolean parameter is provided, first assigns that flag. -When set, certain memory write errors cause earlier transfer termination. -@end deffn - -@deffn Command {arm11 step_irq_enable} [@option{enable}|@option{disable}] -Displays the value of the flag controlling whether -IRQs are enabled during single stepping; -they are disabled by default. -If a boolean parameter is provided, first assigns that. -@end deffn - -@deffn Command {arm11 vcr} [value] -@cindex vector_catch -Displays the value of the @emph{Vector Catch Register (VCR)}, -coprocessor 14 register 7. -If @var{value} is defined, first assigns that. - -Vector Catch hardware provides dedicated breakpoints -for certain hardware events. -The specific bit values are core-specific (as in fact is using -coprocessor 14 register 7 itself) but all current ARM11 -cores @emph{except the ARM1176} use the same six bits. -@end deffn - -@section ARMv7 Architecture -@cindex ARMv7 - -@subsection ARMv7 Debug Access Port (DAP) specific commands -@cindex Debug Access Port -@cindex DAP -These commands are specific to ARM architecture v7 Debug Access Port (DAP), -included on Cortex-M and Cortex-A systems. -They are available in addition to other core-specific commands that may be available. - -@deffn Command {dap apid} [num] -Displays ID register from AP @var{num}, -defaulting to the currently selected AP. -@end deffn - -@deffn Command {dap apreg} ap_num reg [value] -Displays content of a register @var{reg} from AP @var{ap_num} -or set a new value @var{value}. -@var{reg} is byte address of a word register, 0, 4, 8 ... 0xfc. -@end deffn - -@deffn Command {dap apsel} [num] -Select AP @var{num}, defaulting to 0. -@end deffn - -@deffn Command {dap baseaddr} [num] -Displays debug base address from MEM-AP @var{num}, -defaulting to the currently selected AP. -@end deffn - -@deffn Command {dap info} [num] -Displays the ROM table for MEM-AP @var{num}, -defaulting to the currently selected AP. -@end deffn - -@deffn Command {dap memaccess} [value] -Displays the number of extra tck cycles in the JTAG idle to use for MEM-AP -memory bus access [0-255], giving additional time to respond to reads. -If @var{value} is defined, first assigns that. -@end deffn - -@deffn Command {dap apcsw} [0 / 1] -fix CSW_SPROT from register AP_REG_CSW on selected dap. -Defaulting to 0. -@end deffn - -@deffn Command {dap ti_be_32_quirks} [@option{enable}] -Set/get quirks mode for TI TMS450/TMS570 processors -Disabled by default -@end deffn - - -@subsection ARMv7-A specific commands -@cindex Cortex-A - -@deffn Command {cortex_a cache_info} -display information about target caches -@end deffn - -@deffn Command {cortex_a dacrfixup [@option{on}|@option{off}]} -Work around issues with software breakpoints when the program text is -mapped read-only by the operating system. This option sets the CP15 DACR -to "all-manager" to bypass MMU permission checks on memory access. -Defaults to 'off'. -@end deffn - -@deffn Command {cortex_a dbginit} -Initialize core debug -Enables debug by unlocking the Software Lock and clearing sticky powerdown indications -@end deffn - -@deffn Command {cortex_a smp_off} -Disable SMP mode -@end deffn - -@deffn Command {cortex_a smp_on} -Enable SMP mode -@end deffn - -@deffn Command {cortex_a smp_gdb} [core_id] -Display/set the current core displayed in GDB -@end deffn - -@deffn Command {cortex_a maskisr} [@option{on}|@option{off}] -Selects whether interrupts will be processed when single stepping -@end deffn - -@deffn Command {cache_config l2x} [base way] -configure l2x cache -@end deffn - - -@subsection ARMv7-R specific commands -@cindex Cortex-R - -@deffn Command {cortex_r dbginit} -Initialize core debug -Enables debug by unlocking the Software Lock and clearing sticky powerdown indications -@end deffn - -@deffn Command {cortex_r maskisr} [@option{on}|@option{off}] -Selects whether interrupts will be processed when single stepping -@end deffn - - -@subsection ARMv7-M specific commands -@cindex tracing -@cindex SWO -@cindex SWV -@cindex TPIU -@cindex ITM -@cindex ETM - -@deffn Command {tpiu config} (@option{disable} | ((@option{external} | @option{internal (@var{filename} | -)}) @ - (@option{sync @var{port_width}} | ((@option{manchester} | @option{uart}) @var{formatter_enable})) @ - @var{TRACECLKIN_freq} [@var{trace_freq}])) - -ARMv7-M architecture provides several modules to generate debugging -information internally (ITM, DWT and ETM). Their output is directed -through TPIU to be captured externally either on an SWO pin (this -configuration is called SWV) or on a synchronous parallel trace port. - -This command configures the TPIU module of the target and, if internal -capture mode is selected, starts to capture trace output by using the -debugger adapter features. - -Some targets require additional actions to be performed in the -@b{trace-config} handler for trace port to be activated. - -Command options: -@itemize @minus -@item @option{disable} disable TPIU handling; -@item @option{external} configure TPIU to let user capture trace -output externally (with an additional UART or logic analyzer hardware); -@item @option{internal @var{filename}} configure TPIU and debug adapter to -gather trace data and append it to @var{filename} (which can be -either a regular file or a named pipe); -@item @option{internal -} configure TPIU and debug adapter to -gather trace data, but not write to any file. Useful in conjunction with the @command{tcl_trace} command; -@item @option{sync @var{port_width}} use synchronous parallel trace output -mode, and set port width to @var{port_width}; -@item @option{manchester} use asynchronous SWO mode with Manchester -coding; -@item @option{uart} use asynchronous SWO mode with NRZ (same as -regular UART 8N1) coding; -@item @var{formatter_enable} is @option{on} or @option{off} to enable -or disable TPIU formatter which needs to be used when both ITM and ETM -data is to be output via SWO; -@item @var{TRACECLKIN_freq} this should be specified to match target's -current TRACECLKIN frequency (usually the same as HCLK); -@item @var{trace_freq} trace port frequency. Can be omitted in -internal mode to let the adapter driver select the maximum supported -rate automatically. -@end itemize - -Example usage: -@enumerate -@item STM32L152 board is programmed with an application that configures -PLL to provide core clock with 24MHz frequency; to use ITM output it's -enough to: -@example -#include - ... - ITM_STIM8(0) = c; - ... -@end example -(the most obvious way is to use the first stimulus port for printf, -for that this ITM_STIM8 assignment can be used inside _write(); to make it -blocking to avoid data loss, add @code{while (!(ITM_STIM8(0) & -ITM_STIM_FIFOREADY));}); -@item An FT2232H UART is connected to the SWO pin of the board; -@item Commands to configure UART for 12MHz baud rate: -@example -$ setserial /dev/ttyUSB1 spd_cust divisor 5 -$ stty -F /dev/ttyUSB1 38400 -@end example -(FT2232H's base frequency is 60MHz, spd_cust allows to alias 38400 -baud with our custom divisor to get 12MHz) -@item @code{itmdump -f /dev/ttyUSB1 -d1} -@item OpenOCD invocation line: -@example -openocd -f interface/stlink-v2-1.cfg \ - -c "transport select hla_swd" \ - -f target/stm32l1.cfg \ - -c "tpiu config external uart off 24000000 12000000" -@end example -@end enumerate -@end deffn - -@deffn Command {itm port} @var{port} (@option{0}|@option{1}|@option{on}|@option{off}) -Enable or disable trace output for ITM stimulus @var{port} (counting -from 0). Port 0 is enabled on target creation automatically. -@end deffn - -@deffn Command {itm ports} (@option{0}|@option{1}|@option{on}|@option{off}) -Enable or disable trace output for all ITM stimulus ports. -@end deffn - -@subsection Cortex-M specific commands -@cindex Cortex-M - -@deffn Command {cortex_m maskisr} (@option{auto}|@option{on}|@option{off}) -Control masking (disabling) interrupts during target step/resume. - -The @option{auto} option handles interrupts during stepping a way they get -served but don't disturb the program flow. The step command first allows -pending interrupt handlers to execute, then disables interrupts and steps over -the next instruction where the core was halted. After the step interrupts -are enabled again. If the interrupt handlers don't complete within 500ms, -the step command leaves with the core running. - -Note that a free breakpoint is required for the @option{auto} option. If no -breakpoint is available at the time of the step, then the step is taken -with interrupts enabled, i.e. the same way the @option{off} option does. - -Default is @option{auto}. -@end deffn - -@deffn Command {cortex_m vector_catch} [@option{all}|@option{none}|list] -@cindex vector_catch -Vector Catch hardware provides dedicated breakpoints -for certain hardware events. - -Parameters request interception of -@option{all} of these hardware event vectors, -@option{none} of them, -or one or more of the following: -@option{hard_err} for a HardFault exception; -@option{mm_err} for a MemManage exception; -@option{bus_err} for a BusFault exception; -@option{irq_err}, -@option{state_err}, -@option{chk_err}, or -@option{nocp_err} for various UsageFault exceptions; or -@option{reset}. -If NVIC setup code does not enable them, -MemManage, BusFault, and UsageFault exceptions -are mapped to HardFault. -UsageFault checks for -divide-by-zero and unaligned access -must also be explicitly enabled. - -This finishes by listing the current vector catch configuration. -@end deffn - -@deffn Command {cortex_m reset_config} (@option{srst}|@option{sysresetreq}|@option{vectreset}) -Control reset handling. The default @option{srst} is to use srst if fitted, -otherwise fallback to @option{vectreset}. -@itemize @minus -@item @option{srst} use hardware srst if fitted otherwise fallback to @option{vectreset}. -@item @option{sysresetreq} use NVIC SYSRESETREQ to reset system. -@item @option{vectreset} use NVIC VECTRESET to reset system. -@end itemize -Using @option{vectreset} is a safe option for all current Cortex-M cores. -This however has the disadvantage of only resetting the core, all peripherals -are uneffected. A solution would be to use a @code{reset-init} event handler to manually reset -the peripherals. -@xref{targetevents,,Target Events}. -@end deffn - -@section Intel Architecture - -Intel Quark X10xx is the first product in the Quark family of SoCs. It is an IA-32 -(Pentium x86 ISA) compatible SoC. The core CPU in the X10xx is codenamed Lakemont. -Lakemont version 1 (LMT1) is used in X10xx. The CPU TAP (Lakemont TAP) is used for -software debug and the CLTAP is used for SoC level operations. -Useful docs are here: https://communities.intel.com/community/makers/documentation -@itemize -@item Intel Quark SoC X1000 OpenOCD/GDB/Eclipse App Note (web search for doc num 330015) -@item Intel Quark SoC X1000 Debug Operations User Guide (web search for doc num 329866) -@item Intel Quark SoC X1000 Datasheet (web search for doc num 329676) -@end itemize - -@subsection x86 32-bit specific commands -The three main address spaces for x86 are memory, I/O and configuration space. -These commands allow a user to read and write to the 64Kbyte I/O address space. - -@deffn Command {x86_32 idw} address -Display the contents of a 32-bit I/O port from address range 0x0000 - 0xffff. -@end deffn - -@deffn Command {x86_32 idh} address -Display the contents of a 16-bit I/O port from address range 0x0000 - 0xffff. -@end deffn - -@deffn Command {x86_32 idb} address -Display the contents of a 8-bit I/O port from address range 0x0000 - 0xffff. -@end deffn - -@deffn Command {x86_32 iww} address -Write the contents of a 32-bit I/O port to address range 0x0000 - 0xffff. -@end deffn - -@deffn Command {x86_32 iwh} address -Write the contents of a 16-bit I/O port to address range 0x0000 - 0xffff. -@end deffn - -@deffn Command {x86_32 iwb} address -Write the contents of a 8-bit I/O port to address range 0x0000 - 0xffff. -@end deffn - -@section OpenRISC Architecture - -The OpenRISC CPU is a soft core. It is used in a programmable SoC which can be -configured with any of the TAP / Debug Unit available. - -@subsection TAP and Debug Unit selection commands -@deffn Command {tap_select} (@option{vjtag}|@option{mohor}|@option{xilinx_bscan}) -Select between the Altera Virtual JTAG , Xilinx Virtual JTAG and Mohor TAP. -@end deffn -@deffn Command {du_select} (@option{adv}|@option{mohor}) [option] -Select between the Advanced Debug Interface and the classic one. - -An option can be passed as a second argument to the debug unit. - -When using the Advanced Debug Interface, option = 1 means the RTL core is -configured with ADBG_USE_HISPEED = 1. This configuration skips status checking -between bytes while doing read or write bursts. -@end deffn - -@subsection Registers commands -@deffn Command {addreg} [name] [address] [feature] [reg_group] -Add a new register in the cpu register list. This register will be -included in the generated target descriptor file. - -@strong{[feature]} must be "org.gnu.gdb.or1k.group[0..10]". - -@strong{[reg_group]} can be anything. The default register list defines "system", - "dmmu", "immu", "dcache", "icache", "mac", "debug", "perf", "power", "pic" - and "timer" groups. - -@emph{example:} -@example -addreg rtest 0x1234 org.gnu.gdb.or1k.group0 system -@end example - - -@end deffn -@deffn Command {readgroup} (@option{group}) -Display all registers in @emph{group}. - -@emph{group} can be "system", - "dmmu", "immu", "dcache", "icache", "mac", "debug", "perf", "power", "pic", - "timer" or any new group created with addreg command. -@end deffn - -@anchor{softwaredebugmessagesandtracing} -@section Software Debug Messages and Tracing -@cindex Linux-ARM DCC support -@cindex tracing -@cindex libdcc -@cindex DCC -OpenOCD can process certain requests from target software, when -the target uses appropriate libraries. -The most powerful mechanism is semihosting, but there is also -a lighter weight mechanism using only the DCC channel. - -Currently @command{target_request debugmsgs} -is supported only for @option{arm7_9} and @option{cortex_m} cores. -These messages are received as part of target polling, so -you need to have @command{poll on} active to receive them. -They are intrusive in that they will affect program execution -times. If that is a problem, @pxref{armhardwaretracing,,ARM Hardware Tracing}. - -See @file{libdcc} in the contrib dir for more details. -In addition to sending strings, characters, and -arrays of various size integers from the target, -@file{libdcc} also exports a software trace point mechanism. -The target being debugged may -issue trace messages which include a 24-bit @dfn{trace point} number. -Trace point support includes two distinct mechanisms, -each supported by a command: - -@itemize -@item @emph{History} ... A circular buffer of trace points -can be set up, and then displayed at any time. -This tracks where code has been, which can be invaluable in -finding out how some fault was triggered. - -The buffer may overflow, since it collects records continuously. -It may be useful to use some of the 24 bits to represent a -particular event, and other bits to hold data. - -@item @emph{Counting} ... An array of counters can be set up, -and then displayed at any time. -This can help establish code coverage and identify hot spots. - -The array of counters is directly indexed by the trace point -number, so trace points with higher numbers are not counted. -@end itemize - -Linux-ARM kernels have a ``Kernel low-level debugging -via EmbeddedICE DCC channel'' option (CONFIG_DEBUG_ICEDCC, -depends on CONFIG_DEBUG_LL) which uses this mechanism to -deliver messages before a serial console can be activated. -This is not the same format used by @file{libdcc}. -Other software, such as the U-Boot boot loader, sometimes -does the same thing. - -@deffn Command {target_request debugmsgs} [@option{enable}|@option{disable}|@option{charmsg}] -Displays current handling of target DCC message requests. -These messages may be sent to the debugger while the target is running. -The optional @option{enable} and @option{charmsg} parameters -both enable the messages, while @option{disable} disables them. - -With @option{charmsg} the DCC words each contain one character, -as used by Linux with CONFIG_DEBUG_ICEDCC; -otherwise the libdcc format is used. -@end deffn - -@deffn Command {trace history} [@option{clear}|count] -With no parameter, displays all the trace points that have triggered -in the order they triggered. -With the parameter @option{clear}, erases all current trace history records. -With a @var{count} parameter, allocates space for that many -history records. -@end deffn - -@deffn Command {trace point} [@option{clear}|identifier] -With no parameter, displays all trace point identifiers and how many times -they have been triggered. -With the parameter @option{clear}, erases all current trace point counters. -With a numeric @var{identifier} parameter, creates a new a trace point counter -and associates it with that identifier. - -@emph{Important:} The identifier and the trace point number -are not related except by this command. -These trace point numbers always start at zero (from server startup, -or after @command{trace point clear}) and count up from there. -@end deffn - - -@node JTAG Commands -@chapter JTAG Commands -@cindex JTAG Commands -Most general purpose JTAG commands have been presented earlier. -(@xref{jtagspeed,,JTAG Speed}, @ref{Reset Configuration}, and @ref{TAP Declaration}.) -Lower level JTAG commands, as presented here, -may be needed to work with targets which require special -attention during operations such as reset or initialization. - -To use these commands you will need to understand some -of the basics of JTAG, including: - -@itemize @bullet -@item A JTAG scan chain consists of a sequence of individual TAP -devices such as a CPUs. -@item Control operations involve moving each TAP through the same -standard state machine (in parallel) -using their shared TMS and clock signals. -@item Data transfer involves shifting data through the chain of -instruction or data registers of each TAP, writing new register values -while the reading previous ones. -@item Data register sizes are a function of the instruction active in -a given TAP, while instruction register sizes are fixed for each TAP. -All TAPs support a BYPASS instruction with a single bit data register. -@item The way OpenOCD differentiates between TAP devices is by -shifting different instructions into (and out of) their instruction -registers. -@end itemize - -@section Low Level JTAG Commands - -These commands are used by developers who need to access -JTAG instruction or data registers, possibly controlling -the order of TAP state transitions. -If you're not debugging OpenOCD internals, or bringing up a -new JTAG adapter or a new type of TAP device (like a CPU or -JTAG router), you probably won't need to use these commands. -In a debug session that doesn't use JTAG for its transport protocol, -these commands are not available. - -@deffn Command {drscan} tap [numbits value]+ [@option{-endstate} tap_state] -Loads the data register of @var{tap} with a series of bit fields -that specify the entire register. -Each field is @var{numbits} bits long with -a numeric @var{value} (hexadecimal encouraged). -The return value holds the original value of each -of those fields. - -For example, a 38 bit number might be specified as one -field of 32 bits then one of 6 bits. -@emph{For portability, never pass fields which are more -than 32 bits long. Many OpenOCD implementations do not -support 64-bit (or larger) integer values.} - -All TAPs other than @var{tap} must be in BYPASS mode. -The single bit in their data registers does not matter. - -When @var{tap_state} is specified, the JTAG state machine is left -in that state. -For example @sc{drpause} might be specified, so that more -instructions can be issued before re-entering the @sc{run/idle} state. -If the end state is not specified, the @sc{run/idle} state is entered. - -@quotation Warning -OpenOCD does not record information about data register lengths, -so @emph{it is important that you get the bit field lengths right}. -Remember that different JTAG instructions refer to different -data registers, which may have different lengths. -Moreover, those lengths may not be fixed; -the SCAN_N instruction can change the length of -the register accessed by the INTEST instruction -(by connecting a different scan chain). -@end quotation -@end deffn - -@deffn Command {flush_count} -Returns the number of times the JTAG queue has been flushed. -This may be used for performance tuning. - -For example, flushing a queue over USB involves a -minimum latency, often several milliseconds, which does -not change with the amount of data which is written. -You may be able to identify performance problems by finding -tasks which waste bandwidth by flushing small transfers too often, -instead of batching them into larger operations. -@end deffn - -@deffn Command {irscan} [tap instruction]+ [@option{-endstate} tap_state] -For each @var{tap} listed, loads the instruction register -with its associated numeric @var{instruction}. -(The number of bits in that instruction may be displayed -using the @command{scan_chain} command.) -For other TAPs, a BYPASS instruction is loaded. - -When @var{tap_state} is specified, the JTAG state machine is left -in that state. -For example @sc{irpause} might be specified, so the data register -can be loaded before re-entering the @sc{run/idle} state. -If the end state is not specified, the @sc{run/idle} state is entered. - -@quotation Note -OpenOCD currently supports only a single field for instruction -register values, unlike data register values. -For TAPs where the instruction register length is more than 32 bits, -portable scripts currently must issue only BYPASS instructions. -@end quotation -@end deffn - -@deffn Command {jtag_reset} trst srst -Set values of reset signals. -The @var{trst} and @var{srst} parameter values may be -@option{0}, indicating that reset is inactive (pulled or driven high), -or @option{1}, indicating it is active (pulled or driven low). -The @command{reset_config} command should already have been used -to configure how the board and JTAG adapter treat these two -signals, and to say if either signal is even present. -@xref{Reset Configuration}. - -Note that TRST is specially handled. -It actually signifies JTAG's @sc{reset} state. -So if the board doesn't support the optional TRST signal, -or it doesn't support it along with the specified SRST value, -JTAG reset is triggered with TMS and TCK signals -instead of the TRST signal. -And no matter how that JTAG reset is triggered, once -the scan chain enters @sc{reset} with TRST inactive, -TAP @code{post-reset} events are delivered to all TAPs -with handlers for that event. -@end deffn - -@deffn Command {pathmove} start_state [next_state ...] -Start by moving to @var{start_state}, which -must be one of the @emph{stable} states. -Unless it is the only state given, this will often be the -current state, so that no TCK transitions are needed. -Then, in a series of single state transitions -(conforming to the JTAG state machine) shift to -each @var{next_state} in sequence, one per TCK cycle. -The final state must also be stable. -@end deffn - -@deffn Command {runtest} @var{num_cycles} -Move to the @sc{run/idle} state, and execute at least -@var{num_cycles} of the JTAG clock (TCK). -Instructions often need some time -to execute before they take effect. -@end deffn - -@c tms_sequence (short|long) -@c ... temporary, debug-only, other than USBprog bug workaround... - -@deffn Command {verify_ircapture} (@option{enable}|@option{disable}) -Verify values captured during @sc{ircapture} and returned -during IR scans. Default is enabled, but this can be -overridden by @command{verify_jtag}. -This flag is ignored when validating JTAG chain configuration. -@end deffn - -@deffn Command {verify_jtag} (@option{enable}|@option{disable}) -Enables verification of DR and IR scans, to help detect -programming errors. For IR scans, @command{verify_ircapture} -must also be enabled. -Default is enabled. -@end deffn - -@section TAP state names -@cindex TAP state names - -The @var{tap_state} names used by OpenOCD in the @command{drscan}, -@command{irscan}, and @command{pathmove} commands are the same -as those used in SVF boundary scan documents, except that -SVF uses @sc{idle} instead of @sc{run/idle}. - -@itemize @bullet -@item @b{RESET} ... @emph{stable} (with TMS high); -acts as if TRST were pulsed -@item @b{RUN/IDLE} ... @emph{stable}; don't assume this always means IDLE -@item @b{DRSELECT} -@item @b{DRCAPTURE} -@item @b{DRSHIFT} ... @emph{stable}; TDI/TDO shifting -through the data register -@item @b{DREXIT1} -@item @b{DRPAUSE} ... @emph{stable}; data register ready -for update or more shifting -@item @b{DREXIT2} -@item @b{DRUPDATE} -@item @b{IRSELECT} -@item @b{IRCAPTURE} -@item @b{IRSHIFT} ... @emph{stable}; TDI/TDO shifting -through the instruction register -@item @b{IREXIT1} -@item @b{IRPAUSE} ... @emph{stable}; instruction register ready -for update or more shifting -@item @b{IREXIT2} -@item @b{IRUPDATE} -@end itemize - -Note that only six of those states are fully ``stable'' in the -face of TMS fixed (low except for @sc{reset}) -and a free-running JTAG clock. For all the -others, the next TCK transition changes to a new state. - -@itemize @bullet -@item From @sc{drshift} and @sc{irshift}, clock transitions will -produce side effects by changing register contents. The values -to be latched in upcoming @sc{drupdate} or @sc{irupdate} states -may not be as expected. -@item @sc{run/idle}, @sc{drpause}, and @sc{irpause} are reasonable -choices after @command{drscan} or @command{irscan} commands, -since they are free of JTAG side effects. -@item @sc{run/idle} may have side effects that appear at non-JTAG -levels, such as advancing the ARM9E-S instruction pipeline. -Consult the documentation for the TAP(s) you are working with. -@end itemize - -@node Boundary Scan Commands -@chapter Boundary Scan Commands - -One of the original purposes of JTAG was to support -boundary scan based hardware testing. -Although its primary focus is to support On-Chip Debugging, -OpenOCD also includes some boundary scan commands. - -@section SVF: Serial Vector Format -@cindex Serial Vector Format -@cindex SVF - -The Serial Vector Format, better known as @dfn{SVF}, is a -way to represent JTAG test patterns in text files. -In a debug session using JTAG for its transport protocol, -OpenOCD supports running such test files. - -@deffn Command {svf} filename [@option{quiet}] -This issues a JTAG reset (Test-Logic-Reset) and then -runs the SVF script from @file{filename}. -Unless the @option{quiet} option is specified, -each command is logged before it is executed. -@end deffn - -@section XSVF: Xilinx Serial Vector Format -@cindex Xilinx Serial Vector Format -@cindex XSVF - -The Xilinx Serial Vector Format, better known as @dfn{XSVF}, is a -binary representation of SVF which is optimized for use with -Xilinx devices. -In a debug session using JTAG for its transport protocol, -OpenOCD supports running such test files. - -@quotation Important -Not all XSVF commands are supported. -@end quotation - -@deffn Command {xsvf} (tapname|@option{plain}) filename [@option{virt2}] [@option{quiet}] -This issues a JTAG reset (Test-Logic-Reset) and then -runs the XSVF script from @file{filename}. -When a @var{tapname} is specified, the commands are directed at -that TAP. -When @option{virt2} is specified, the @sc{xruntest} command counts -are interpreted as TCK cycles instead of microseconds. -Unless the @option{quiet} option is specified, -messages are logged for comments and some retries. -@end deffn - -The OpenOCD sources also include two utility scripts -for working with XSVF; they are not currently installed -after building the software. -You may find them useful: - -@itemize -@item @emph{svf2xsvf} ... converts SVF files into the extended XSVF -syntax understood by the @command{xsvf} command; see notes below. -@item @emph{xsvfdump} ... converts XSVF files into a text output format; -understands the OpenOCD extensions. -@end itemize - -The input format accepts a handful of non-standard extensions. -These include three opcodes corresponding to SVF extensions -from Lattice Semiconductor (LCOUNT, LDELAY, LDSR), and -two opcodes supporting a more accurate translation of SVF -(XTRST, XWAITSTATE). -If @emph{xsvfdump} shows a file is using those opcodes, it -probably will not be usable with other XSVF tools. - - -@node Utility Commands -@chapter Utility Commands -@cindex Utility Commands - -@section RAM testing -@cindex RAM testing - -There is often a need to stress-test random access memory (RAM) for -errors. OpenOCD comes with a Tcl implementation of well-known memory -testing procedures allowing the detection of all sorts of issues with -electrical wiring, defective chips, PCB layout and other common -hardware problems. - -To use them, you usually need to initialise your RAM controller first; -consult your SoC's documentation to get the recommended list of -register operations and translate them to the corresponding -@command{mww}/@command{mwb} commands. - -Load the memory testing functions with - -@example -source [find tools/memtest.tcl] -@end example - -to get access to the following facilities: - -@deffn Command {memTestDataBus} address -Test the data bus wiring in a memory region by performing a walking -1's test at a fixed address within that region. -@end deffn - -@deffn Command {memTestAddressBus} baseaddress size -Perform a walking 1's test on the relevant bits of the address and -check for aliasing. This test will find single-bit address failures -such as stuck-high, stuck-low, and shorted pins. -@end deffn - -@deffn Command {memTestDevice} baseaddress size -Test the integrity of a physical memory device by performing an -increment/decrement test over the entire region. In the process every -storage bit in the device is tested as zero and as one. -@end deffn - -@deffn Command {runAllMemTests} baseaddress size -Run all of the above tests over a specified memory region. -@end deffn - -@section Firmware recovery helpers -@cindex Firmware recovery - -OpenOCD includes an easy-to-use script to facilitate mass-market -devices recovery with JTAG. - -For quickstart instructions run: -@example -openocd -f tools/firmware-recovery.tcl -c firmware_help -@end example - -@node TFTP -@chapter TFTP -@cindex TFTP -If OpenOCD runs on an embedded host (as ZY1000 does), then TFTP can -be used to access files on PCs (either the developer's PC or some other PC). - -The way this works on the ZY1000 is to prefix a filename by -"/tftp/ip/" and append the TFTP path on the TFTP -server (tftpd). For example, - -@example -load_image /tftp/10.0.0.96/c:\temp\abc.elf -@end example - -will load c:\temp\abc.elf from the developer pc (10.0.0.96) into memory as -if the file was hosted on the embedded host. - -In order to achieve decent performance, you must choose a TFTP server -that supports a packet size bigger than the default packet size (512 bytes). There -are numerous TFTP servers out there (free and commercial) and you will have to do -a bit of googling to find something that fits your requirements. - -@node GDB and OpenOCD -@chapter GDB and OpenOCD -@cindex GDB -OpenOCD complies with the remote gdbserver protocol and, as such, can be used -to debug remote targets. -Setting up GDB to work with OpenOCD can involve several components: - -@itemize -@item The OpenOCD server support for GDB may need to be configured. -@xref{gdbconfiguration,,GDB Configuration}. -@item GDB's support for OpenOCD may need configuration, -as shown in this chapter. -@item If you have a GUI environment like Eclipse, -that also will probably need to be configured. -@end itemize - -Of course, the version of GDB you use will need to be one which has -been built to know about the target CPU you're using. It's probably -part of the tool chain you're using. For example, if you are doing -cross-development for ARM on an x86 PC, instead of using the native -x86 @command{gdb} command you might use @command{arm-none-eabi-gdb} -if that's the tool chain used to compile your code. - -@section Connecting to GDB -@cindex Connecting to GDB -Use GDB 6.7 or newer with OpenOCD if you run into trouble. For -instance GDB 6.3 has a known bug that produces bogus memory access -errors, which has since been fixed; see -@url{http://osdir.com/ml/gdb.bugs.discuss/2004-12/msg00018.html} - -OpenOCD can communicate with GDB in two ways: - -@enumerate -@item -A socket (TCP/IP) connection is typically started as follows: -@example -target remote localhost:3333 -@end example -This would cause GDB to connect to the gdbserver on the local pc using port 3333. - -It is also possible to use the GDB extended remote protocol as follows: -@example -target extended-remote localhost:3333 -@end example -@item -A pipe connection is typically started as follows: -@example -target remote | openocd -c "gdb_port pipe; log_output openocd.log" -@end example -This would cause GDB to run OpenOCD and communicate using pipes (stdin/stdout). -Using this method has the advantage of GDB starting/stopping OpenOCD for the debug -session. log_output sends the log output to a file to ensure that the pipe is -not saturated when using higher debug level outputs. -@end enumerate - -To list the available OpenOCD commands type @command{monitor help} on the -GDB command line. - -@section Sample GDB session startup - -With the remote protocol, GDB sessions start a little differently -than they do when you're debugging locally. -Here's an example showing how to start a debug session with a -small ARM program. -In this case the program was linked to be loaded into SRAM on a Cortex-M3. -Most programs would be written into flash (address 0) and run from there. - -@example -$ arm-none-eabi-gdb example.elf -(gdb) target remote localhost:3333 -Remote debugging using localhost:3333 -... -(gdb) monitor reset halt -... -(gdb) load -Loading section .vectors, size 0x100 lma 0x20000000 -Loading section .text, size 0x5a0 lma 0x20000100 -Loading section .data, size 0x18 lma 0x200006a0 -Start address 0x2000061c, load size 1720 -Transfer rate: 22 KB/sec, 573 bytes/write. -(gdb) continue -Continuing. -... -@end example - -You could then interrupt the GDB session to make the program break, -type @command{where} to show the stack, @command{list} to show the -code around the program counter, @command{step} through code, -set breakpoints or watchpoints, and so on. - -@section Configuring GDB for OpenOCD - -OpenOCD supports the gdb @option{qSupported} packet, this enables information -to be sent by the GDB remote server (i.e. OpenOCD) to GDB. Typical information includes -packet size and the device's memory map. -You do not need to configure the packet size by hand, -and the relevant parts of the memory map should be automatically -set up when you declare (NOR) flash banks. - -However, there are other things which GDB can't currently query. -You may need to set those up by hand. -As OpenOCD starts up, you will often see a line reporting -something like: - -@example -Info : lm3s.cpu: hardware has 6 breakpoints, 4 watchpoints -@end example - -You can pass that information to GDB with these commands: - -@example -set remote hardware-breakpoint-limit 6 -set remote hardware-watchpoint-limit 4 -@end example - -With that particular hardware (Cortex-M3) the hardware breakpoints -only work for code running from flash memory. Most other ARM systems -do not have such restrictions. - -Another example of useful GDB configuration came from a user who -found that single stepping his Cortex-M3 didn't work well with IRQs -and an RTOS until he told GDB to disable the IRQs while stepping: - -@example -define hook-step -mon cortex_m maskisr on -end -define hookpost-step -mon cortex_m maskisr off -end -@end example - -Rather than typing such commands interactively, you may prefer to -save them in a file and have GDB execute them as it starts, perhaps -using a @file{.gdbinit} in your project directory or starting GDB -using @command{gdb -x filename}. - -@section Programming using GDB -@cindex Programming using GDB -@anchor{programmingusinggdb} - -By default the target memory map is sent to GDB. This can be disabled by -the following OpenOCD configuration option: -@example -gdb_memory_map disable -@end example -For this to function correctly a valid flash configuration must also be set -in OpenOCD. For faster performance you should also configure a valid -working area. - -Informing GDB of the memory map of the target will enable GDB to protect any -flash areas of the target and use hardware breakpoints by default. This means -that the OpenOCD option @command{gdb_breakpoint_override} is not required when -using a memory map. @xref{gdbbreakpointoverride,,gdb_breakpoint_override}. - -To view the configured memory map in GDB, use the GDB command @option{info mem}. -All other unassigned addresses within GDB are treated as RAM. - -GDB 6.8 and higher set any memory area not in the memory map as inaccessible. -This can be changed to the old behaviour by using the following GDB command -@example -set mem inaccessible-by-default off -@end example - -If @command{gdb_flash_program enable} is also used, GDB will be able to -program any flash memory using the vFlash interface. - -GDB will look at the target memory map when a load command is given, if any -areas to be programmed lie within the target flash area the vFlash packets -will be used. - -If the target needs configuring before GDB programming, an event -script can be executed: -@example -$_TARGETNAME configure -event EVENTNAME BODY -@end example - -To verify any flash programming the GDB command @option{compare-sections} -can be used. -@anchor{usingopenocdsmpwithgdb} -@section Using OpenOCD SMP with GDB -@cindex SMP -For SMP support following GDB serial protocol packet have been defined : -@itemize @bullet -@item j - smp status request -@item J - smp set request -@end itemize - -OpenOCD implements : -@itemize @bullet -@item @option{jc} packet for reading core id displayed by -GDB connection. Reply is @option{XXXXXXXX} (8 hex digits giving core id) or - @option{E01} for target not smp. -@item @option{JcXXXXXXXX} (8 hex digits) packet for setting core id displayed at next GDB continue -(core id -1 is reserved for returning to normal resume mode). Reply @option{E01} -for target not smp or @option{OK} on success. -@end itemize - -Handling of this packet within GDB can be done : -@itemize @bullet -@item by the creation of an internal variable (i.e @option{_core}) by mean -of function allocate_computed_value allowing following GDB command. -@example -set $_core 1 -#Jc01 packet is sent -print $_core -#jc packet is sent and result is affected in $ -@end example - -@item by the usage of GDB maintenance command as described in following example (2 cpus in SMP with -core id 0 and 1 @pxref{definecputargetsworkinginsmp,,Define CPU targets working in SMP}). - -@example -# toggle0 : force display of coreid 0 -define toggle0 -maint packet Jc0 -continue -main packet Jc-1 -end -# toggle1 : force display of coreid 1 -define toggle1 -maint packet Jc1 -continue -main packet Jc-1 -end -@end example -@end itemize - -@section RTOS Support -@cindex RTOS Support -@anchor{gdbrtossupport} - -OpenOCD includes RTOS support, this will however need enabling as it defaults to disabled. -It can be enabled by passing @option{-rtos} arg to the target @xref{rtostype,,RTOS Type}. - -@* An example setup is below: - -@example -$_TARGETNAME configure -rtos auto -@end example - -This will attempt to auto detect the RTOS within your application. - -Currently supported rtos's include: -@itemize @bullet -@item @option{eCos} -@item @option{ThreadX} -@item @option{FreeRTOS} -@item @option{linux} -@item @option{ChibiOS} -@item @option{embKernel} -@item @option{mqx} -@end itemize - -@quotation Note -Before an RTOS can be detected, it must export certain symbols; otherwise, it cannot -be used by OpenOCD. Below is a list of the required symbols for each supported RTOS. -@end quotation - -@table @code -@item eCos symbols -Cyg_Thread::thread_list, Cyg_Scheduler_Base::current_thread. -@item ThreadX symbols -_tx_thread_current_ptr, _tx_thread_created_ptr, _tx_thread_created_count. -@item FreeRTOS symbols -@c The following is taken from recent texinfo to provide compatibility -@c with ancient versions that do not support @raggedright -@tex -\begingroup -\rightskip0pt plus2em \spaceskip.3333em \xspaceskip.5em\relax -pxCurrentTCB, pxReadyTasksLists, xDelayedTaskList1, xDelayedTaskList2, -pxDelayedTaskList, pxOverflowDelayedTaskList, xPendingReadyList, -uxCurrentNumberOfTasks, uxTopUsedPriority. -\par -\endgroup -@end tex -@item linux symbols -init_task. -@item ChibiOS symbols -rlist, ch_debug, chSysInit. -@item embKernel symbols -Rtos::sCurrentTask, Rtos::sListReady, Rtos::sListSleep, -Rtos::sListSuspended, Rtos::sMaxPriorities, Rtos::sCurrentTaskCount. -@item mqx symbols -_mqx_kernel_data, MQX_init_struct. -@end table - -For most RTOS supported the above symbols will be exported by default. However for -some, eg. FreeRTOS, extra steps must be taken. - -These RTOSes may require additional OpenOCD-specific file to be linked -along with the project: - -@table @code -@item FreeRTOS -contrib/rtos-helpers/FreeRTOS-openocd.c -@end table - -@node Tcl Scripting API -@chapter Tcl Scripting API -@cindex Tcl Scripting API -@cindex Tcl scripts -@section API rules - -Tcl commands are stateless; e.g. the @command{telnet} command has -a concept of currently active target, the Tcl API proc's take this sort -of state information as an argument to each proc. - -There are three main types of return values: single value, name value -pair list and lists. - -Name value pair. The proc 'foo' below returns a name/value pair -list. - -@example -> set foo(me) Duane -> set foo(you) Oyvind -> set foo(mouse) Micky -> set foo(duck) Donald -@end example - -If one does this: - -@example -> set foo -@end example - -The result is: - -@example -me Duane you Oyvind mouse Micky duck Donald -@end example - -Thus, to get the names of the associative array is easy: - -@verbatim -foreach { name value } [set foo] { - puts "Name: $name, Value: $value" -} -@end verbatim - -Lists returned should be relatively small. Otherwise, a range -should be passed in to the proc in question. - -@section Internal low-level Commands - -By "low-level," we mean commands that a human would typically not -invoke directly. - -Some low-level commands need to be prefixed with "ocd_"; e.g. -@command{ocd_flash_banks} -is the low-level API upon which @command{flash banks} is implemented. - -@itemize @bullet -@item @b{mem2array} <@var{varname}> <@var{width}> <@var{addr}> <@var{nelems}> - -Read memory and return as a Tcl array for script processing -@item @b{array2mem} <@var{varname}> <@var{width}> <@var{addr}> <@var{nelems}> - -Convert a Tcl array to memory locations and write the values -@item @b{ocd_flash_banks} <@var{driver}> <@var{base}> <@var{size}> <@var{chip_width}> <@var{bus_width}> <@var{target}> [@option{driver options} ...] - -Return information about the flash banks - -@item @b{capture} <@var{command}> - -Run <@var{command}> and return full log output that was produced during -its execution. Example: - -@example -> capture "reset init" -@end example - -@end itemize - -OpenOCD commands can consist of two words, e.g. "flash banks". The -@file{startup.tcl} "unknown" proc will translate this into a Tcl proc -called "flash_banks". - -@section OpenOCD specific Global Variables - -Real Tcl has ::tcl_platform(), and platform::identify, and many other -variables. JimTCL, as implemented in OpenOCD creates $ocd_HOSTOS which -holds one of the following values: - -@itemize @bullet -@item @b{cygwin} Running under Cygwin -@item @b{darwin} Darwin (Mac-OS) is the underlying operating sytem. -@item @b{freebsd} Running under FreeBSD -@item @b{openbsd} Running under OpenBSD -@item @b{netbsd} Running under NetBSD -@item @b{linux} Linux is the underlying operating sytem -@item @b{mingw32} Running under MingW32 -@item @b{winxx} Built using Microsoft Visual Studio -@item @b{ecos} Running under eCos -@item @b{other} Unknown, none of the above. -@end itemize - -Note: 'winxx' was choosen because today (March-2009) no distinction is made between Win32 and Win64. - -@quotation Note -We should add support for a variable like Tcl variable -@code{tcl_platform(platform)}, it should be called -@code{jim_platform} (because it -is jim, not real tcl). -@end quotation - -@section Tcl RPC server -@cindex RPC - -OpenOCD provides a simple RPC server that allows to run arbitrary Tcl -commands and receive the results. - -To access it, your application needs to connect to a configured TCP port -(see @command{tcl_port}). Then it can pass any string to the -interpreter terminating it with @code{0x1a} and wait for the return -value (it will be terminated with @code{0x1a} as well). This can be -repeated as many times as desired without reopening the connection. - -Remember that most of the OpenOCD commands need to be prefixed with -@code{ocd_} to get the results back. Sometimes you might also need the -@command{capture} command. - -See @file{contrib/rpc_examples/} for specific client implementations. - -@section Tcl RPC server notifications -@cindex RPC Notifications - -Notifications are sent asynchronously to other commands being executed over -the RPC server, so the port must be polled continuously. - -Target event, state and reset notifications are emitted as Tcl associative arrays -in the following format. - -@verbatim -type target_event event [event-name] -type target_state state [state-name] -type target_reset mode [reset-mode] -@end verbatim - -@deffn {Command} tcl_notifications [on/off] -Toggle output of target notifications to the current Tcl RPC server. -Only available from the Tcl RPC server. -Defaults to off. - -@end deffn - -@section Tcl RPC server trace output -@cindex RPC trace output - -Trace data is sent asynchronously to other commands being executed over -the RPC server, so the port must be polled continuously. - -Target trace data is emitted as a Tcl associative array in the following format. - -@verbatim -type target_trace data [trace-data-hex-encoded] -@end verbatim - -@deffn {Command} tcl_trace [on/off] -Toggle output of target trace data to the current Tcl RPC server. -Only available from the Tcl RPC server. -Defaults to off. - -See an example application here: -@url{https://github.com/apmorton/OpenOcdTraceUtil} [OpenOcdTraceUtil] - -@end deffn - -@node FAQ -@chapter FAQ -@cindex faq -@enumerate -@anchor{faqrtck} -@item @b{RTCK, also known as: Adaptive Clocking - What is it?} -@cindex RTCK -@cindex adaptive clocking -@* - -In digital circuit design it is often refered to as ``clock -synchronisation'' the JTAG interface uses one clock (TCK or TCLK) -operating at some speed, your CPU target is operating at another. -The two clocks are not synchronised, they are ``asynchronous'' - -In order for the two to work together they must be synchronised -well enough to work; JTAG can't go ten times faster than the CPU, -for example. There are 2 basic options: -@enumerate -@item -Use a special "adaptive clocking" circuit to change the JTAG -clock rate to match what the CPU currently supports. -@item -The JTAG clock must be fixed at some speed that's enough slower than -the CPU clock that all TMS and TDI transitions can be detected. -@end enumerate - -@b{Does this really matter?} For some chips and some situations, this -is a non-issue, like a 500MHz ARM926 with a 5 MHz JTAG link; -the CPU has no difficulty keeping up with JTAG. -Startup sequences are often problematic though, as are other -situations where the CPU clock rate changes (perhaps to save -power). - -For example, Atmel AT91SAM chips start operation from reset with -a 32kHz system clock. Boot firmware may activate the main oscillator -and PLL before switching to a faster clock (perhaps that 500 MHz -ARM926 scenario). -If you're using JTAG to debug that startup sequence, you must slow -the JTAG clock to sometimes 1 to 4kHz. After startup completes, -JTAG can use a faster clock. - -Consider also debugging a 500MHz ARM926 hand held battery powered -device that enters a low power ``deep sleep'' mode, at 32kHz CPU -clock, between keystrokes unless it has work to do. When would -that 5 MHz JTAG clock be usable? - -@b{Solution #1 - A special circuit} - -In order to make use of this, -your CPU, board, and JTAG adapter must all support the RTCK -feature. Not all of them support this; keep reading! - -The RTCK ("Return TCK") signal in some ARM chips is used to help with -this problem. ARM has a good description of the problem described at -this link: @url{http://www.arm.com/support/faqdev/4170.html} [checked -28/nov/2008]. Link title: ``How does the JTAG synchronisation logic -work? / how does adaptive clocking work?''. - -The nice thing about adaptive clocking is that ``battery powered hand -held device example'' - the adaptiveness works perfectly all the -time. One can set a break point or halt the system in the deep power -down code, slow step out until the system speeds up. - -Note that adaptive clocking may also need to work at the board level, -when a board-level scan chain has multiple chips. -Parallel clock voting schemes are good way to implement this, -both within and between chips, and can easily be implemented -with a CPLD. -It's not difficult to have logic fan a module's input TCK signal out -to each TAP in the scan chain, and then wait until each TAP's RTCK comes -back with the right polarity before changing the output RTCK signal. -Texas Instruments makes some clock voting logic available -for free (with no support) in VHDL form; see -@url{http://tiexpressdsp.com/index.php/Adaptive_Clocking} - -@b{Solution #2 - Always works - but may be slower} - -Often this is a perfectly acceptable solution. - -In most simple terms: Often the JTAG clock must be 1/10 to 1/12 of -the target clock speed. But what that ``magic division'' is varies -depending on the chips on your board. -@b{ARM rule of thumb} Most ARM based systems require an 6:1 division; -ARM11 cores use an 8:1 division. -@b{Xilinx rule of thumb} is 1/12 the clock speed. - -Note: most full speed FT2232 based JTAG adapters are limited to a -maximum of 6MHz. The ones using USB high speed chips (FT2232H) -often support faster clock rates (and adaptive clocking). - -You can still debug the 'low power' situations - you just need to -either use a fixed and very slow JTAG clock rate ... or else -manually adjust the clock speed at every step. (Adjusting is painful -and tedious, and is not always practical.) - -It is however easy to ``code your way around it'' - i.e.: Cheat a little, -have a special debug mode in your application that does a ``high power -sleep''. If you are careful - 98% of your problems can be debugged -this way. - -Note that on ARM you may need to avoid using the @emph{wait for interrupt} -operation in your idle loops even if you don't otherwise change the CPU -clock rate. -That operation gates the CPU clock, and thus the JTAG clock; which -prevents JTAG access. One consequence is not being able to @command{halt} -cores which are executing that @emph{wait for interrupt} operation. - -To set the JTAG frequency use the command: - -@example -# Example: 1.234MHz -adapter_khz 1234 -@end example - - -@item @b{Win32 Pathnames} Why don't backslashes work in Windows paths? - -OpenOCD uses Tcl and a backslash is an escape char. Use @{ and @} -around Windows filenames. - -@example -> echo \a - -> echo @{\a@} -\a -> echo "\a" - -> -@end example - - -@item @b{Missing: cygwin1.dll} OpenOCD complains about a missing cygwin1.dll. - -Make sure you have Cygwin installed, or at least a version of OpenOCD that -claims to come with all the necessary DLLs. When using Cygwin, try launching -OpenOCD from the Cygwin shell. - -@item @b{Breakpoint Issue} I'm trying to set a breakpoint using GDB (or a frontend like Insight or -Eclipse), but OpenOCD complains that "Info: arm7_9_common.c:213 -arm7_9_add_breakpoint(): sw breakpoint requested, but software breakpoints not enabled". - -GDB issues software breakpoints when a normal breakpoint is requested, or to implement -source-line single-stepping. On ARMv4T systems, like ARM7TDMI, ARM720T or ARM920T, -software breakpoints consume one of the two available hardware breakpoints. - -@item @b{LPC2000 Flash} When erasing or writing LPC2000 on-chip flash, the operation fails at random. - -Make sure the core frequency specified in the @option{flash lpc2000} line matches the -clock at the time you're programming the flash. If you've specified the crystal's -frequency, make sure the PLL is disabled. If you've specified the full core speed -(e.g. 60MHz), make sure the PLL is enabled. - -@item @b{Amontec Chameleon} When debugging using an Amontec Chameleon in its JTAG Accelerator configuration, -I keep getting "Error: amt_jtagaccel.c:184 amt_wait_scan_busy(): amt_jtagaccel timed -out while waiting for end of scan, rtck was disabled". - -Make sure your PC's parallel port operates in EPP mode. You might have to try several -settings in your PC BIOS (ECP, EPP, and different versions of those). - -@item @b{Data Aborts} When debugging with OpenOCD and GDB (plain GDB, Insight, or Eclipse), -I get lots of "Error: arm7_9_common.c:1771 arm7_9_read_memory(): -memory read caused data abort". - -The errors are non-fatal, and are the result of GDB trying to trace stack frames -beyond the last valid frame. It might be possible to prevent this by setting up -a proper "initial" stack frame, if you happen to know what exactly has to -be done, feel free to add this here. - -@b{Simple:} In your startup code - push 8 registers of zeros onto the -stack before calling main(). What GDB is doing is ``climbing'' the run -time stack by reading various values on the stack using the standard -call frame for the target. GDB keeps going - until one of 2 things -happen @b{#1} an invalid frame is found, or @b{#2} some huge number of -stackframes have been processed. By pushing zeros on the stack, GDB -gracefully stops. - -@b{Debugging Interrupt Service Routines} - In your ISR before you call -your C code, do the same - artifically push some zeros onto the stack, -remember to pop them off when the ISR is done. - -@b{Also note:} If you have a multi-threaded operating system, they -often do not @b{in the intrest of saving memory} waste these few -bytes. Painful... - - -@item @b{JTAG Reset Config} I get the following message in the OpenOCD console (or log file): -"Warning: arm7_9_common.c:679 arm7_9_assert_reset(): srst resets test logic, too". - -This warning doesn't indicate any serious problem, as long as you don't want to -debug your core right out of reset. Your .cfg file specified @option{jtag_reset -trst_and_srst srst_pulls_trst} to tell OpenOCD that either your board, -your debugger or your target uC (e.g. LPC2000) can't assert the two reset signals -independently. With this setup, it's not possible to halt the core right out of -reset, everything else should work fine. - -@item @b{USB Power} When using OpenOCD in conjunction with Amontec JTAGkey and the Yagarto -toolchain (Eclipse, arm-elf-gcc, arm-elf-gdb), the debugging seems to be -unstable. When single-stepping over large blocks of code, GDB and OpenOCD -quit with an error message. Is there a stability issue with OpenOCD? - -No, this is not a stability issue concerning OpenOCD. Most users have solved -this issue by simply using a self-powered USB hub, which they connect their -Amontec JTAGkey to. Apparently, some computers do not provide a USB power -supply stable enough for the Amontec JTAGkey to be operated. - -@b{Laptops running on battery have this problem too...} - -@item @b{USB Power} When using the Amontec JTAGkey, sometimes OpenOCD crashes with the -following error messages: "Error: ft2232.c:201 ft2232_read(): FT_Read returned: -4" and "Error: ft2232.c:365 ft2232_send_and_recv(): couldn't read from FT2232". -What does that mean and what might be the reason for this? - -First of all, the reason might be the USB power supply. Try using a self-powered -hub instead of a direct connection to your computer. Secondly, the error code 4 -corresponds to an FT_IO_ERROR, which means that the driver for the FTDI USB -chip ran into some sort of error - this points us to a USB problem. - -@item @b{GDB Disconnects} When using the Amontec JTAGkey, sometimes OpenOCD crashes with the following -error message: "Error: gdb_server.c:101 gdb_get_char(): read: 10054". -What does that mean and what might be the reason for this? - -Error code 10054 corresponds to WSAECONNRESET, which means that the debugger (GDB) -has closed the connection to OpenOCD. This might be a GDB issue. - -@item @b{LPC2000 Flash} In the configuration file in the section where flash device configurations -are described, there is a parameter for specifying the clock frequency -for LPC2000 internal flash devices (e.g. @option{flash bank $_FLASHNAME lpc2000 -0x0 0x40000 0 0 $_TARGETNAME lpc2000_v1 14746 calc_checksum}), which must be -specified in kilohertz. However, I do have a quartz crystal of a -frequency that contains fractions of kilohertz (e.g. 14,745,600 Hz, -i.e. 14,745.600 kHz). Is it possible to specify real numbers for the -clock frequency? - -No. The clock frequency specified here must be given as an integral number. -However, this clock frequency is used by the In-Application-Programming (IAP) -routines of the LPC2000 family only, which seems to be very tolerant concerning -the given clock frequency, so a slight difference between the specified clock -frequency and the actual clock frequency will not cause any trouble. - -@item @b{Command Order} Do I have to keep a specific order for the commands in the configuration file? - -Well, yes and no. Commands can be given in arbitrary order, yet the -devices listed for the JTAG scan chain must be given in the right -order (jtag newdevice), with the device closest to the TDO-Pin being -listed first. In general, whenever objects of the same type exist -which require an index number, then these objects must be given in the -right order (jtag newtap, targets and flash banks - a target -references a jtag newtap and a flash bank references a target). - -You can use the ``scan_chain'' command to verify and display the tap order. - -Also, some commands can't execute until after @command{init} has been -processed. Such commands include @command{nand probe} and everything -else that needs to write to controller registers, perhaps for setting -up DRAM and loading it with code. - -@anchor{faqtaporder} -@item @b{JTAG TAP Order} Do I have to declare the TAPS in some -particular order? - -Yes; whenever you have more than one, you must declare them in -the same order used by the hardware. - -Many newer devices have multiple JTAG TAPs. For example: ST -Microsystems STM32 chips have two TAPs, a ``boundary scan TAP'' and -``Cortex-M3'' TAP. Example: The STM32 reference manual, Document ID: -RM0008, Section 26.5, Figure 259, page 651/681, the ``TDI'' pin is -connected to the boundary scan TAP, which then connects to the -Cortex-M3 TAP, which then connects to the TDO pin. - -Thus, the proper order for the STM32 chip is: (1) The Cortex-M3, then -(2) The boundary scan TAP. If your board includes an additional JTAG -chip in the scan chain (for example a Xilinx CPLD or FPGA) you could -place it before or after the STM32 chip in the chain. For example: - -@itemize @bullet -@item OpenOCD_TDI(output) -> STM32 TDI Pin (BS Input) -@item STM32 BS TDO (output) -> STM32 Cortex-M3 TDI (input) -@item STM32 Cortex-M3 TDO (output) -> SM32 TDO Pin -@item STM32 TDO Pin (output) -> Xilinx TDI Pin (input) -@item Xilinx TDO Pin -> OpenOCD TDO (input) -@end itemize - -The ``jtag device'' commands would thus be in the order shown below. Note: - -@itemize @bullet -@item jtag newtap Xilinx tap -irlen ... -@item jtag newtap stm32 cpu -irlen ... -@item jtag newtap stm32 bs -irlen ... -@item # Create the debug target and say where it is -@item target create stm32.cpu -chain-position stm32.cpu ... -@end itemize - - -@item @b{SYSCOMP} Sometimes my debugging session terminates with an error. When I look into the -log file, I can see these error messages: Error: arm7_9_common.c:561 -arm7_9_execute_sys_speed(): timeout waiting for SYSCOMP - -TODO. - -@end enumerate - -@node Tcl Crash Course -@chapter Tcl Crash Course -@cindex Tcl - -Not everyone knows Tcl - this is not intended to be a replacement for -learning Tcl, the intent of this chapter is to give you some idea of -how the Tcl scripts work. - -This chapter is written with two audiences in mind. (1) OpenOCD users -who need to understand a bit more of how Jim-Tcl works so they can do -something useful, and (2) those that want to add a new command to -OpenOCD. - -@section Tcl Rule #1 -There is a famous joke, it goes like this: -@enumerate -@item Rule #1: The wife is always correct -@item Rule #2: If you think otherwise, See Rule #1 -@end enumerate - -The Tcl equal is this: - -@enumerate -@item Rule #1: Everything is a string -@item Rule #2: If you think otherwise, See Rule #1 -@end enumerate - -As in the famous joke, the consequences of Rule #1 are profound. Once -you understand Rule #1, you will understand Tcl. - -@section Tcl Rule #1b -There is a second pair of rules. -@enumerate -@item Rule #1: Control flow does not exist. Only commands -@* For example: the classic FOR loop or IF statement is not a control -flow item, they are commands, there is no such thing as control flow -in Tcl. -@item Rule #2: If you think otherwise, See Rule #1 -@* Actually what happens is this: There are commands that by -convention, act like control flow key words in other languages. One of -those commands is the word ``for'', another command is ``if''. -@end enumerate - -@section Per Rule #1 - All Results are strings -Every Tcl command results in a string. The word ``result'' is used -deliberatly. No result is just an empty string. Remember: @i{Rule #1 - -Everything is a string} - -@section Tcl Quoting Operators -In life of a Tcl script, there are two important periods of time, the -difference is subtle. -@enumerate -@item Parse Time -@item Evaluation Time -@end enumerate - -The two key items here are how ``quoted things'' work in Tcl. Tcl has -three primary quoting constructs, the [square-brackets] the -@{curly-braces@} and ``double-quotes'' - -By now you should know $VARIABLES always start with a $DOLLAR -sign. BTW: To set a variable, you actually use the command ``set'', as -in ``set VARNAME VALUE'' much like the ancient BASIC langauge ``let x -= 1'' statement, but without the equal sign. - -@itemize @bullet -@item @b{[square-brackets]} -@* @b{[square-brackets]} are command substitutions. It operates much -like Unix Shell `back-ticks`. The result of a [square-bracket] -operation is exactly 1 string. @i{Remember Rule #1 - Everything is a -string}. These two statements are roughly identical: -@example - # bash example - X=`date` - echo "The Date is: $X" - # Tcl example - set X [date] - puts "The Date is: $X" -@end example -@item @b{``double-quoted-things''} -@* @b{``double-quoted-things''} are just simply quoted -text. $VARIABLES and [square-brackets] are expanded in place - the -result however is exactly 1 string. @i{Remember Rule #1 - Everything -is a string} -@example - set x "Dinner" - puts "It is now \"[date]\", $x is in 1 hour" -@end example -@item @b{@{Curly-Braces@}} -@*@b{@{Curly-Braces@}} are magic: $VARIABLES and [square-brackets] are -parsed, but are NOT expanded or executed. @{Curly-Braces@} are like -'single-quote' operators in BASH shell scripts, with the added -feature: @{curly-braces@} can be nested, single quotes can not. @{@{@{this is -nested 3 times@}@}@} NOTE: [date] is a bad example; -at this writing, Jim/OpenOCD does not have a date command. -@end itemize - -@section Consequences of Rule 1/2/3/4 - -The consequences of Rule 1 are profound. - -@subsection Tokenisation & Execution. - -Of course, whitespace, blank lines and #comment lines are handled in -the normal way. - -As a script is parsed, each (multi) line in the script file is -tokenised and according to the quoting rules. After tokenisation, that -line is immedatly executed. - -Multi line statements end with one or more ``still-open'' -@{curly-braces@} which - eventually - closes a few lines later. - -@subsection Command Execution - -Remember earlier: There are no ``control flow'' -statements in Tcl. Instead there are COMMANDS that simply act like -control flow operators. - -Commands are executed like this: - -@enumerate -@item Parse the next line into (argc) and (argv[]). -@item Look up (argv[0]) in a table and call its function. -@item Repeat until End Of File. -@end enumerate - -It sort of works like this: -@example - for(;;)@{ - ReadAndParse( &argc, &argv ); - - cmdPtr = LookupCommand( argv[0] ); - - (*cmdPtr->Execute)( argc, argv ); - @} -@end example - -When the command ``proc'' is parsed (which creates a procedure -function) it gets 3 parameters on the command line. @b{1} the name of -the proc (function), @b{2} the list of parameters, and @b{3} the body -of the function. Not the choice of words: LIST and BODY. The PROC -command stores these items in a table somewhere so it can be found by -``LookupCommand()'' - -@subsection The FOR command - -The most interesting command to look at is the FOR command. In Tcl, -the FOR command is normally implemented in C. Remember, FOR is a -command just like any other command. - -When the ascii text containing the FOR command is parsed, the parser -produces 5 parameter strings, @i{(If in doubt: Refer to Rule #1)} they -are: - -@enumerate 0 -@item The ascii text 'for' -@item The start text -@item The test expression -@item The next text -@item The body text -@end enumerate - -Sort of reminds you of ``main( int argc, char **argv )'' does it not? -Remember @i{Rule #1 - Everything is a string.} The key point is this: -Often many of those parameters are in @{curly-braces@} - thus the -variables inside are not expanded or replaced until later. - -Remember that every Tcl command looks like the classic ``main( argc, -argv )'' function in C. In JimTCL - they actually look like this: - -@example -int -MyCommand( Jim_Interp *interp, - int *argc, - Jim_Obj * const *argvs ); -@end example - -Real Tcl is nearly identical. Although the newer versions have -introduced a byte-code parser and intepreter, but at the core, it -still operates in the same basic way. - -@subsection FOR command implementation - -To understand Tcl it is perhaps most helpful to see the FOR -command. Remember, it is a COMMAND not a control flow structure. - -In Tcl there are two underlying C helper functions. - -Remember Rule #1 - You are a string. - -The @b{first} helper parses and executes commands found in an ascii -string. Commands can be seperated by semicolons, or newlines. While -parsing, variables are expanded via the quoting rules. - -The @b{second} helper evaluates an ascii string as a numerical -expression and returns a value. - -Here is an example of how the @b{FOR} command could be -implemented. The pseudo code below does not show error handling. -@example -void Execute_AsciiString( void *interp, const char *string ); - -int Evaluate_AsciiExpression( void *interp, const char *string ); - -int -MyForCommand( void *interp, - int argc, - char **argv ) -@{ - if( argc != 5 )@{ - SetResult( interp, "WRONG number of parameters"); - return ERROR; - @} - - // argv[0] = the ascii string just like C - - // Execute the start statement. - Execute_AsciiString( interp, argv[1] ); - - // Top of loop test - for(;;)@{ - i = Evaluate_AsciiExpression(interp, argv[2]); - if( i == 0 ) - break; - - // Execute the body - Execute_AsciiString( interp, argv[3] ); - - // Execute the LOOP part - Execute_AsciiString( interp, argv[4] ); - @} - - // Return no error - SetResult( interp, "" ); - return SUCCESS; -@} -@end example - -Every other command IF, WHILE, FORMAT, PUTS, EXPR, everything works -in the same basic way. - -@section OpenOCD Tcl Usage - -@subsection source and find commands -@b{Where:} In many configuration files -@* Example: @b{ source [find FILENAME] } -@*Remember the parsing rules -@enumerate -@item The @command{find} command is in square brackets, -and is executed with the parameter FILENAME. It should find and return -the full path to a file with that name; it uses an internal search path. -The RESULT is a string, which is substituted into the command line in -place of the bracketed @command{find} command. -(Don't try to use a FILENAME which includes the "#" character. -That character begins Tcl comments.) -@item The @command{source} command is executed with the resulting filename; -it reads a file and executes as a script. -@end enumerate -@subsection format command -@b{Where:} Generally occurs in numerous places. -@* Tcl has no command like @b{printf()}, instead it has @b{format}, which is really more like -@b{sprintf()}. -@b{Example} -@example - set x 6 - set y 7 - puts [format "The answer: %d" [expr $x * $y]] -@end example -@enumerate -@item The SET command creates 2 variables, X and Y. -@item The double [nested] EXPR command performs math -@* The EXPR command produces numerical result as a string. -@* Refer to Rule #1 -@item The format command is executed, producing a single string -@* Refer to Rule #1. -@item The PUTS command outputs the text. -@end enumerate -@subsection Body or Inlined Text -@b{Where:} Various TARGET scripts. -@example -#1 Good - proc someproc @{@} @{ - ... multiple lines of stuff ... - @} - $_TARGETNAME configure -event FOO someproc -#2 Good - no variables - $_TARGETNAME confgure -event foo "this ; that;" -#3 Good Curly Braces - $_TARGETNAME configure -event FOO @{ - puts "Time: [date]" - @} -#4 DANGER DANGER DANGER - $_TARGETNAME configure -event foo "puts \"Time: [date]\"" -@end example -@enumerate -@item The $_TARGETNAME is an OpenOCD variable convention. -@*@b{$_TARGETNAME} represents the last target created, the value changes -each time a new target is created. Remember the parsing rules. When -the ascii text is parsed, the @b{$_TARGETNAME} becomes a simple string, -the name of the target which happens to be a TARGET (object) -command. -@item The 2nd parameter to the @option{-event} parameter is a TCBODY -@*There are 4 examples: -@enumerate -@item The TCLBODY is a simple string that happens to be a proc name -@item The TCLBODY is several simple commands seperated by semicolons -@item The TCLBODY is a multi-line @{curly-brace@} quoted string -@item The TCLBODY is a string with variables that get expanded. -@end enumerate - -In the end, when the target event FOO occurs the TCLBODY is -evaluated. Method @b{#1} and @b{#2} are functionally identical. For -Method @b{#3} and @b{#4} it is more interesting. What is the TCLBODY? - -Remember the parsing rules. In case #3, @{curly-braces@} mean the -$VARS and [square-brackets] are expanded later, when the EVENT occurs, -and the text is evaluated. In case #4, they are replaced before the -``Target Object Command'' is executed. This occurs at the same time -$_TARGETNAME is replaced. In case #4 the date will never -change. @{BTW: [date] is a bad example; at this writing, -Jim/OpenOCD does not have a date command@} -@end enumerate -@subsection Global Variables -@b{Where:} You might discover this when writing your own procs @* In -simple terms: Inside a PROC, if you need to access a global variable -you must say so. See also ``upvar''. Example: -@example -proc myproc @{ @} @{ - set y 0 #Local variable Y - global x #Global variable X - puts [format "X=%d, Y=%d" $x $y] -@} -@end example -@section Other Tcl Hacks -@b{Dynamic variable creation} -@example -# Dynamically create a bunch of variables. -for @{ set x 0 @} @{ $x < 32 @} @{ set x [expr $x + 1]@} @{ - # Create var name - set vn [format "BIT%d" $x] - # Make it a global - global $vn - # Set it. - set $vn [expr (1 << $x)] -@} -@end example -@b{Dynamic proc/command creation} -@example -# One "X" function - 5 uart functions. -foreach who @{A B C D E@} - proc [format "show_uart%c" $who] @{ @} "show_UARTx $who" -@} -@end example - -@include fdl.texi - -@node OpenOCD Concept Index -@comment DO NOT use the plain word ``Index'', reason: CYGWIN filename -@comment case issue with ``Index.html'' and ``index.html'' -@comment Occurs when creating ``--html --no-split'' output -@comment This fix is based on: http://sourceware.org/ml/binutils/2006-05/msg00215.html -@unnumbered OpenOCD Concept Index - -@printindex cp - -@node Command and Driver Index -@unnumbered Command and Driver Index -@printindex fn - -@bye diff --git a/guess-rev.sh b/guess-rev.sh deleted file mode 100755 index 7adbe2817..000000000 --- a/guess-rev.sh +++ /dev/null @@ -1,83 +0,0 @@ -#!/bin/sh -# -# This scripts adds local version information from the version -# control systems git, mercurial (hg) and subversion (svn). -# -# Copied from Linux 2.6.32 scripts/setlocalversion and modified -# slightly to work better for OpenOCD. -# - -usage() { - echo "Usage: $0 [srctree]" >&2 - exit 1 -} - -cd "${1:-.}" || usage - -# Check for git and a git repo. -if head=`git rev-parse --verify --short HEAD 2>/dev/null`; then - - # If we are at a tagged commit (like "v2.6.30-rc6"), we ignore it, - # because this version is defined in the top level Makefile. - if [ -z "`git describe --exact-match 2>/dev/null`" ]; then - - # If we are past a tagged commit (like "v2.6.30-rc5-302-g72357d5"), - # we pretty print it. - if atag="`git describe 2>/dev/null`"; then - echo "$atag" | awk -F- '{printf("-%05d-%s", $(NF-1),$(NF))}' - - # If we don't have a tag at all we print -g{commitish}. - else - printf '%s%s' -g $head - fi - fi - - # Is this git on svn? - if git config --get svn-remote.svn.url >/dev/null; then - printf -- '-svn%s' "`git svn find-rev $head`" - fi - - # Update index only on r/w media - [ -w . ] && git update-index --refresh --unmerged > /dev/null - - # Check for uncommitted changes - if git diff-index --name-only HEAD | grep -v "^scripts/package" \ - | read dummy; then - printf '%s' -dirty - fi - - # All done with git - exit -fi - -# Check for mercurial and a mercurial repo. -if hgid=`hg id 2>/dev/null`; then - tag=`printf '%s' "$hgid" | cut -d' ' -f2` - - # Do we have an untagged version? - if [ -z "$tag" -o "$tag" = tip ]; then - id=`printf '%s' "$hgid" | sed 's/[+ ].*//'` - printf '%s%s' -hg "$id" - fi - - # Are there uncommitted changes? - # These are represented by + after the changeset id. - case "$hgid" in - *+|*+\ *) printf '%s' -dirty ;; - esac - - # All done with mercurial - exit -fi - -# Check for svn and a svn repo. -if rev=`svn info 2>/dev/null | grep '^Last Changed Rev'`; then - rev=`echo $rev | awk '{print $NF}'` - printf -- '-svn%s' "$rev" - - # All done with svn - exit -fi - -# There's no reecognized repository; we must be a snapshot. -printf -- '-snapshot' diff --git a/jimtcl b/jimtcl deleted file mode 160000 index 51f65c6d3..000000000 --- a/jimtcl +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 51f65c6d38fbf86e1f0b036ad336761fd2ab7fa0 diff --git a/src/Makefile.am b/src/Makefile.am deleted file mode 100644 index 26e02d085..000000000 --- a/src/Makefile.am +++ /dev/null @@ -1,116 +0,0 @@ -include $(top_srcdir)/common.mk - -SUBDIRS = \ - jtag \ - helper \ - target \ - transport \ - flash \ - svf \ - xsvf \ - pld \ - server \ - rtos - -noinst_LTLIBRARIES = libopenocd.la -bin_PROGRAMS = openocd - -MAINFILE = main.c - -openocd_SOURCES = $(MAINFILE) -openocd_LDADD = libopenocd.la - -if INTERNAL_JIMTCL -openocd_LDADD += $(top_builddir)/jimtcl/libjim.a -else -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`\" - -# 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=\"\" -else -libopenocd_la_CPPFLAGS += -DRELSTR=\"`$(top_srcdir)/guess-rev.sh $(top_srcdir)`\" -libopenocd_la_CPPFLAGS += -DGITVERSION=\"`cd $(top_srcdir) && git describe`\" -endif - -# add default CPPFLAGS -libopenocd_la_CPPFLAGS += $(AM_CPPFLAGS) $(CPPFLAGS) - -# the library search path. -libopenocd_la_LDFLAGS = $(all_libraries) - -if IS_MINGW -MINGWLDADD = -lws2_32 -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 - -EXTRA_DIST = $(STARTUP_TCL_SRCS) - -BUILT_SOURCES = startup_tcl.inc - -startup.tcl: $(STARTUP_TCL_SRCS) - cat $^ > $@ - -BIN2C = $(top_srcdir)/src/helper/bin2char.sh - -# Convert .tcl to c-array -startup_tcl.inc: startup.tcl $(BIN2C) - $(BIN2C) < $< > $@ || { rm -f $@; false; } - -# add generated files to make clean list -CLEANFILES = startup.tcl 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 - diff --git a/src/flash/Makefile.am b/src/flash/Makefile.am deleted file mode 100644 index ece401837..000000000 --- a/src/flash/Makefile.am +++ /dev/null @@ -1,23 +0,0 @@ -include $(top_srcdir)/common.mk - -SUBDIRS = \ - nor \ - nand - -METASOURCES = AUTO -noinst_LTLIBRARIES = libflash.la -libflash_la_SOURCES = \ - common.c \ - mflash.c - -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 diff --git a/src/flash/common.c b/src/flash/common.c deleted file mode 100644 index 3e2551192..000000000 --- a/src/flash/common.c +++ /dev/null @@ -1,47 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2009 by Zachary T Welch * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 -#include "config.h" -#endif - -#include "common.h" -#include - -unsigned get_flash_name_index(const char *name) -{ - const char *name_index = strrchr(name, '.'); - if (NULL == name_index) - return 0; - if (name_index[1] < '0' || name_index[1] > '9') - return ~0U; - unsigned requested; - int retval = parse_uint(name_index + 1, &requested); - /* detect parsing error by forcing past end of bank list */ - return (ERROR_OK == retval) ? requested : ~0U; -} - -bool flash_driver_name_matches(const char *name, const char *expected) -{ - unsigned blen = strlen(name); - /* only match up to the length of the driver name... */ - if (strncmp(name, expected, blen) != 0) - return false; - - /* ...then check that name terminates at this spot. */ - return expected[blen] == '.' || expected[blen] == '\0'; -} diff --git a/src/flash/common.h b/src/flash/common.h deleted file mode 100644 index ce26fccd7..000000000 --- a/src/flash/common.h +++ /dev/null @@ -1,48 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2009 by Zachary T Welch * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 OPENOCD_FLASH_COMMON_H -#define OPENOCD_FLASH_COMMON_H - -#include - -/** - * Parses the optional '.index' portion of a flash bank identifier. - * @param name The desired driver name, passed by the user. - * @returns The parsed index request, or 0 if not present. If the - * name provides a suffix but it does not parse as an unsigned integer, - * the routine returns ~0U. This will prevent further matching. - */ -unsigned get_flash_name_index(const char *name); -/** - * Attempt to match the @c expected name with the @c name of a driver. - * @param name The name of the driver (from the bank's device structure). - * @param expected The expected driver name, passed by the user. - */ -bool flash_driver_name_matches(const char *name, const char *expected); - -#define ERROR_FLASH_BANK_INVALID (-900) -#define ERROR_FLASH_SECTOR_INVALID (-901) -#define ERROR_FLASH_OPERATION_FAILED (-902) -#define ERROR_FLASH_DST_OUT_OF_BANK (-903) -#define ERROR_FLASH_DST_BREAKS_ALIGNMENT (-904) -#define ERROR_FLASH_BUSY (-905) -#define ERROR_FLASH_SECTOR_NOT_ERASED (-906) -#define ERROR_FLASH_BANK_NOT_PROBED (-907) -#define ERROR_FLASH_OPER_UNSUPPORTED (-908) - -#endif /* OPENOCD_FLASH_COMMON_H */ diff --git a/src/flash/mflash.c b/src/flash/mflash.c deleted file mode 100644 index b69995542..000000000 --- a/src/flash/mflash.c +++ /dev/null @@ -1,1449 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007-2008 by unsik Kim * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 -#include "config.h" -#endif - -#include "mflash.h" -#include -#include -#include -#include - -static int s3c2440_set_gpio_to_output(struct mflash_gpio_num gpio); -static int s3c2440_set_gpio_output_val(struct mflash_gpio_num gpio, uint8_t val); -static int pxa270_set_gpio_to_output(struct mflash_gpio_num gpio); -static int pxa270_set_gpio_output_val(struct mflash_gpio_num gpio, uint8_t val); - -static struct mflash_bank *mflash_bank; - -static struct mflash_gpio_drv pxa270_gpio = { - .name = "pxa270", - .set_gpio_to_output = pxa270_set_gpio_to_output, - .set_gpio_output_val = pxa270_set_gpio_output_val -}; - -static struct mflash_gpio_drv s3c2440_gpio = { - .name = "s3c2440", - .set_gpio_to_output = s3c2440_set_gpio_to_output, - .set_gpio_output_val = s3c2440_set_gpio_output_val -}; - -static struct mflash_gpio_drv *mflash_gpio[] = { - &pxa270_gpio, - &s3c2440_gpio, - NULL -}; - -#define PXA270_GAFR0_L 0x40E00054 -#define PXA270_GAFR3_U 0x40E00070 -#define PXA270_GAFR3_U_RESERVED_BITS 0xfffc0000u -#define PXA270_GPDR0 0x40E0000C -#define PXA270_GPDR3 0x40E0010C -#define PXA270_GPDR3_RESERVED_BITS 0xfe000000u -#define PXA270_GPSR0 0x40E00018 -#define PXA270_GPCR0 0x40E00024 - -static int pxa270_set_gpio_to_output(struct mflash_gpio_num gpio) -{ - uint32_t addr, value, mask; - struct target *target = mflash_bank->target; - int ret; - - /* remove alternate function. */ - mask = 0x3u << (gpio.num & 0xF)*2; - - addr = PXA270_GAFR0_L + (gpio.num >> 4) * 4; - - ret = target_read_u32(target, addr, &value); - if (ret != ERROR_OK) - return ret; - - value &= ~mask; - if (addr == PXA270_GAFR3_U) - value &= ~PXA270_GAFR3_U_RESERVED_BITS; - - ret = target_write_u32(target, addr, value); - if (ret != ERROR_OK) - return ret; - - /* set direction to output */ - mask = 0x1u << (gpio.num & 0x1F); - - addr = PXA270_GPDR0 + (gpio.num >> 5) * 4; - - ret = target_read_u32(target, addr, &value); - if (ret != ERROR_OK) - return ret; - - value |= mask; - if (addr == PXA270_GPDR3) - value &= ~PXA270_GPDR3_RESERVED_BITS; - - ret = target_write_u32(target, addr, value); - return ret; -} - -static int pxa270_set_gpio_output_val(struct mflash_gpio_num gpio, uint8_t val) -{ - uint32_t addr, value, mask; - struct target *target = mflash_bank->target; - int ret; - - mask = 0x1u << (gpio.num & 0x1F); - - if (val) - addr = PXA270_GPSR0 + (gpio.num >> 5) * 4; - else - addr = PXA270_GPCR0 + (gpio.num >> 5) * 4; - - ret = target_read_u32(target, addr, &value); - if (ret != ERROR_OK) - return ret; - - value |= mask; - - ret = target_write_u32(target, addr, value); - - return ret; -} - -#define S3C2440_GPACON 0x56000000 -#define S3C2440_GPADAT 0x56000004 -#define S3C2440_GPJCON 0x560000d0 -#define S3C2440_GPJDAT 0x560000d4 - -static int s3c2440_set_gpio_to_output(struct mflash_gpio_num gpio) -{ - uint32_t data, mask, gpio_con; - struct target *target = mflash_bank->target; - int ret; - - if (gpio.port[0] >= 'a' && gpio.port[0] <= 'h') - gpio_con = S3C2440_GPACON + (gpio.port[0] - 'a') * 0x10; - else if (gpio.port[0] == 'j') - gpio_con = S3C2440_GPJCON; - else { - LOG_ERROR("mflash: invalid port %d%s", gpio.num, gpio.port); - return ERROR_COMMAND_SYNTAX_ERROR; - } - - ret = target_read_u32(target, gpio_con, &data); - - if (ret == ERROR_OK) { - if (gpio.port[0] == 'a') { - mask = 1 << gpio.num; - data &= ~mask; - } else { - mask = 3 << gpio.num * 2; - data &= ~mask; - data |= (1 << gpio.num * 2); - } - - ret = target_write_u32(target, gpio_con, data); - } - return ret; -} - -static int s3c2440_set_gpio_output_val(struct mflash_gpio_num gpio, uint8_t val) -{ - uint32_t data, mask, gpio_dat; - struct target *target = mflash_bank->target; - int ret; - - if (gpio.port[0] >= 'a' && gpio.port[0] <= 'h') - gpio_dat = S3C2440_GPADAT + (gpio.port[0] - 'a') * 0x10; - else if (gpio.port[0] == 'j') - gpio_dat = S3C2440_GPJDAT; - else { - LOG_ERROR("mflash: invalid port %d%s", gpio.num, gpio.port); - return ERROR_COMMAND_SYNTAX_ERROR; - } - - ret = target_read_u32(target, gpio_dat, &data); - - if (ret == ERROR_OK) { - mask = 1 << gpio.num; - if (val) - data |= mask; - else - data &= ~mask; - - ret = target_write_u32(target, gpio_dat, data); - } - return ret; -} - -static int mg_hdrst(uint8_t level) -{ - return mflash_bank->gpio_drv->set_gpio_output_val(mflash_bank->rst_pin, level); -} - -static int mg_init_gpio(void) -{ - int ret; - struct mflash_gpio_drv *gpio_drv = mflash_bank->gpio_drv; - - ret = gpio_drv->set_gpio_to_output(mflash_bank->rst_pin); - if (ret != ERROR_OK) - return ret; - - ret = gpio_drv->set_gpio_output_val(mflash_bank->rst_pin, 1); - - return ret; -} - -static int mg_dsk_wait(mg_io_type_wait wait_local, uint32_t time_var) -{ - uint8_t status, error; - struct target *target = mflash_bank->target; - uint32_t mg_task_reg = mflash_bank->base + MG_REG_OFFSET; - int ret; - long long t = 0; - - struct duration bench; - duration_start(&bench); - - while (time_var) { - - ret = target_read_u8(target, mg_task_reg + MG_REG_STATUS, &status); - if (ret != ERROR_OK) - return ret; - - if (status & mg_io_rbit_status_busy) { - if (wait_local == mg_io_wait_bsy) - return ERROR_OK; - } else { - switch (wait_local) { - case mg_io_wait_not_bsy: - return ERROR_OK; - case mg_io_wait_rdy_noerr: - if (status & mg_io_rbit_status_ready) - return ERROR_OK; - break; - case mg_io_wait_drq_noerr: - if (status & mg_io_rbit_status_data_req) - return ERROR_OK; - break; - default: - break; - } - - /* Now we check the error condition! */ - if (status & mg_io_rbit_status_error) { - ret = target_read_u8(target, mg_task_reg + MG_REG_ERROR, &error); - if (ret != ERROR_OK) - return ret; - - LOG_ERROR("mflash: io error 0x%02x", error); - - return ERROR_MG_IO; - } - - switch (wait_local) { - case mg_io_wait_rdy: - if (status & mg_io_rbit_status_ready) - return ERROR_OK; - - case mg_io_wait_drq: - if (status & mg_io_rbit_status_data_req) - return ERROR_OK; - - default: - break; - } - } - - ret = duration_measure(&bench); - if (ERROR_OK == ret) - t = duration_elapsed(&bench) * 1000.0; - else - LOG_ERROR("mflash: duration measurement failed: %d", ret); - - if (t > time_var) - break; - } - - LOG_ERROR("mflash: timeout occured"); - return ERROR_MG_TIMEOUT; -} - -static int mg_dsk_srst(uint8_t on) -{ - struct target *target = mflash_bank->target; - uint32_t mg_task_reg = mflash_bank->base + MG_REG_OFFSET; - uint8_t value; - int ret; - - ret = target_read_u8(target, mg_task_reg + MG_REG_DRV_CTRL, &value); - if (ret != ERROR_OK) - return ret; - - if (on) - value |= (mg_io_rbit_devc_srst); - else - value &= ~mg_io_rbit_devc_srst; - - ret = target_write_u8(target, mg_task_reg + MG_REG_DRV_CTRL, value); - return ret; -} - -static int mg_dsk_io_cmd(uint32_t sect_num, uint32_t cnt, uint8_t cmd) -{ - struct target *target = mflash_bank->target; - uint32_t mg_task_reg = mflash_bank->base + MG_REG_OFFSET; - uint8_t value; - int ret; - - ret = mg_dsk_wait(mg_io_wait_rdy_noerr, MG_OEM_DISK_WAIT_TIME_NORMAL); - if (ret != ERROR_OK) - return ret; - - value = mg_io_rval_dev_drv_master | mg_io_rval_dev_lba_mode | ((sect_num >> 24) & 0xf); - - ret = target_write_u8(target, mg_task_reg + MG_REG_DRV_HEAD, value); - ret |= target_write_u8(target, mg_task_reg + MG_REG_SECT_CNT, (uint8_t)cnt); - ret |= target_write_u8(target, mg_task_reg + MG_REG_SECT_NUM, (uint8_t)sect_num); - ret |= target_write_u8(target, mg_task_reg + MG_REG_CYL_LOW, (uint8_t)(sect_num >> 8)); - ret |= target_write_u8(target, mg_task_reg + MG_REG_CYL_HIGH, (uint8_t)(sect_num >> 16)); - - if (ret != ERROR_OK) - return ret; - - return target_write_u8(target, mg_task_reg + MG_REG_COMMAND, cmd); -} - -static int mg_dsk_drv_info(void) -{ - struct target *target = mflash_bank->target; - uint32_t mg_buff = mflash_bank->base + MG_BUFFER_OFFSET; - int ret; - - ret = mg_dsk_io_cmd(0, 1, mg_io_cmd_identify); - if (ret != ERROR_OK) - return ret; - - ret = mg_dsk_wait(mg_io_wait_drq, MG_OEM_DISK_WAIT_TIME_NORMAL); - if (ret != ERROR_OK) - return ret; - - LOG_INFO("mflash: read drive info"); - - if (!mflash_bank->drv_info) - mflash_bank->drv_info = malloc(sizeof(struct mg_drv_info)); - - ret = target_read_memory(target, mg_buff, 2, - sizeof(mg_io_type_drv_info) >> 1, - (uint8_t *)&mflash_bank->drv_info->drv_id); - if (ret != ERROR_OK) - return ret; - - mflash_bank->drv_info->tot_sects = - (uint32_t)(mflash_bank->drv_info->drv_id.total_user_addressable_sectors_hi << 16) - + mflash_bank->drv_info->drv_id.total_user_addressable_sectors_lo; - - return target_write_u8(target, - mflash_bank->base + MG_REG_OFFSET + MG_REG_COMMAND, - mg_io_cmd_confirm_read); -} - -static int mg_mflash_rst(void) -{ - int ret; - - ret = mg_init_gpio(); - if (ret != ERROR_OK) - return ret; - - ret = mg_hdrst(0); - if (ret != ERROR_OK) - return ret; - - ret = mg_dsk_wait(mg_io_wait_bsy, MG_OEM_DISK_WAIT_TIME_LONG); - if (ret != ERROR_OK) - return ret; - - ret = mg_hdrst(1); - if (ret != ERROR_OK) - return ret; - - ret = mg_dsk_wait(mg_io_wait_not_bsy, MG_OEM_DISK_WAIT_TIME_LONG); - if (ret != ERROR_OK) - return ret; - - ret = mg_dsk_srst(1); - if (ret != ERROR_OK) - return ret; - - ret = mg_dsk_wait(mg_io_wait_bsy, MG_OEM_DISK_WAIT_TIME_LONG); - if (ret != ERROR_OK) - return ret; - - ret = mg_dsk_srst(0); - if (ret != ERROR_OK) - return ret; - - ret = mg_dsk_wait(mg_io_wait_not_bsy, MG_OEM_DISK_WAIT_TIME_LONG); - if (ret != ERROR_OK) - return ret; - - LOG_INFO("mflash: reset ok"); - - return ERROR_OK; -} - -static int mg_mflash_probe(void) -{ - int ret = mg_mflash_rst(); - if (ret != ERROR_OK) - return ret; - - return mg_dsk_drv_info(); -} - -COMMAND_HANDLER(mg_probe_cmd) -{ - int ret; - - ret = mg_mflash_probe(); - - if (ret == ERROR_OK) { - command_print(CMD_CTX, - "mflash (total %" PRIu32 " sectors) found at 0x%8.8" PRIx32 "", - mflash_bank->drv_info->tot_sects, - mflash_bank->base); - } - - return ret; -} - -static int mg_mflash_do_read_sects(void *buff, uint32_t sect_num, uint32_t sect_cnt) -{ - uint32_t i, address; - int ret; - struct target *target = mflash_bank->target; - uint8_t *buff_ptr = buff; - - ret = mg_dsk_io_cmd(sect_num, sect_cnt, mg_io_cmd_read); - if (ret != ERROR_OK) - return ret; - - address = mflash_bank->base + MG_BUFFER_OFFSET; - - struct duration bench; - duration_start(&bench); - - for (i = 0; i < sect_cnt; i++) { - ret = mg_dsk_wait(mg_io_wait_drq, MG_OEM_DISK_WAIT_TIME_NORMAL); - if (ret != ERROR_OK) - return ret; - - ret = target_read_memory(target, address, 2, MG_MFLASH_SECTOR_SIZE / 2, buff_ptr); - if (ret != ERROR_OK) - return ret; - - buff_ptr += MG_MFLASH_SECTOR_SIZE; - - ret = target_write_u8(target, - mflash_bank->base + MG_REG_OFFSET + MG_REG_COMMAND, - mg_io_cmd_confirm_read); - if (ret != ERROR_OK) - return ret; - - LOG_DEBUG("mflash: %" PRIu32 " (0x%8.8" PRIx32 ") sector read", sect_num + i, - (sect_num + i) * MG_MFLASH_SECTOR_SIZE); - - ret = duration_measure(&bench); - if ((ERROR_OK == ret) && (duration_elapsed(&bench) > 3)) { - LOG_INFO("mflash: read %" PRIu32 "'th sectors", sect_num + i); - duration_start(&bench); - } - } - - return mg_dsk_wait(mg_io_wait_rdy, MG_OEM_DISK_WAIT_TIME_NORMAL); -} - -static int mg_mflash_read_sects(void *buff, uint32_t sect_num, uint32_t sect_cnt) -{ - uint32_t quotient, residue, i; - uint8_t *buff_ptr = buff; - int ret = ERROR_OK; - - quotient = sect_cnt >> 8; - residue = sect_cnt % 256; - - for (i = 0; i < quotient; i++) { - LOG_DEBUG("mflash: sect num : %" PRIu32 " buff : %p", - sect_num, buff_ptr); - ret = mg_mflash_do_read_sects(buff_ptr, sect_num, 256); - if (ret != ERROR_OK) - return ret; - - sect_num += 256; - buff_ptr += 256 * MG_MFLASH_SECTOR_SIZE; - } - - if (residue) { - LOG_DEBUG("mflash: sect num : %" PRIx32 " buff : %p", - sect_num, buff_ptr); - return mg_mflash_do_read_sects(buff_ptr, sect_num, residue); - } - - return ret; -} - -static int mg_mflash_do_write_sects(void *buff, uint32_t sect_num, uint32_t sect_cnt, - uint8_t cmd) -{ - uint32_t i, address; - int ret; - struct target *target = mflash_bank->target; - uint8_t *buff_ptr = buff; - - ret = mg_dsk_io_cmd(sect_num, sect_cnt, cmd); - if (ret != ERROR_OK) - return ret; - - address = mflash_bank->base + MG_BUFFER_OFFSET; - - struct duration bench; - duration_start(&bench); - - for (i = 0; i < sect_cnt; i++) { - ret = mg_dsk_wait(mg_io_wait_drq, MG_OEM_DISK_WAIT_TIME_NORMAL); - if (ret != ERROR_OK) - return ret; - - ret = target_write_memory(target, address, 2, MG_MFLASH_SECTOR_SIZE / 2, buff_ptr); - if (ret != ERROR_OK) - return ret; - - buff_ptr += MG_MFLASH_SECTOR_SIZE; - - ret = target_write_u8(target, - mflash_bank->base + MG_REG_OFFSET + MG_REG_COMMAND, - mg_io_cmd_confirm_write); - if (ret != ERROR_OK) - return ret; - - LOG_DEBUG("mflash: %" PRIu32 " (0x%8.8" PRIx32 ") sector write", sect_num + i, - (sect_num + i) * MG_MFLASH_SECTOR_SIZE); - - ret = duration_measure(&bench); - if ((ERROR_OK == ret) && (duration_elapsed(&bench) > 3)) { - LOG_INFO("mflash: wrote %" PRIu32 "'th sectors", sect_num + i); - duration_start(&bench); - } - } - - if (cmd == mg_io_cmd_write) - ret = mg_dsk_wait(mg_io_wait_rdy, MG_OEM_DISK_WAIT_TIME_NORMAL); - else - ret = mg_dsk_wait(mg_io_wait_rdy, MG_OEM_DISK_WAIT_TIME_LONG); - - return ret; -} - -static int mg_mflash_write_sects(void *buff, uint32_t sect_num, uint32_t sect_cnt) -{ - uint32_t quotient, residue, i; - uint8_t *buff_ptr = buff; - int ret = ERROR_OK; - - quotient = sect_cnt >> 8; - residue = sect_cnt % 256; - - for (i = 0; i < quotient; i++) { - LOG_DEBUG("mflash: sect num : %" PRIu32 "buff : %p", sect_num, - buff_ptr); - ret = mg_mflash_do_write_sects(buff_ptr, sect_num, 256, mg_io_cmd_write); - if (ret != ERROR_OK) - return ret; - - sect_num += 256; - buff_ptr += 256 * MG_MFLASH_SECTOR_SIZE; - } - - if (residue) { - LOG_DEBUG("mflash: sect num : %" PRIu32 " buff : %p", sect_num, - buff_ptr); - return mg_mflash_do_write_sects(buff_ptr, sect_num, residue, mg_io_cmd_write); - } - - return ret; -} - -static int mg_mflash_read(uint32_t addr, uint8_t *buff, uint32_t len) -{ - uint8_t *buff_ptr = buff; - uint8_t sect_buff[MG_MFLASH_SECTOR_SIZE]; - uint32_t cur_addr, next_sec_addr, end_addr, cnt, sect_num; - int ret = ERROR_OK; - - cnt = 0; - cur_addr = addr; - end_addr = addr + len; - - if (cur_addr & MG_MFLASH_SECTOR_SIZE_MASK) { - - next_sec_addr = (cur_addr + MG_MFLASH_SECTOR_SIZE) & ~MG_MFLASH_SECTOR_SIZE_MASK; - sect_num = cur_addr >> MG_MFLASH_SECTOR_SIZE_SHIFT; - ret = mg_mflash_read_sects(sect_buff, sect_num, 1); - if (ret != ERROR_OK) - return ret; - - if (end_addr < next_sec_addr) { - memcpy(buff_ptr, - sect_buff + (cur_addr & MG_MFLASH_SECTOR_SIZE_MASK), - end_addr - cur_addr); - LOG_DEBUG( - "mflash: copies %" PRIu32 " byte from sector offset 0x%8.8" PRIx32 "", - end_addr - cur_addr, - cur_addr); - cur_addr = end_addr; - } else { - memcpy(buff_ptr, - sect_buff + (cur_addr & MG_MFLASH_SECTOR_SIZE_MASK), - next_sec_addr - cur_addr); - LOG_DEBUG( - "mflash: copies %" PRIu32 " byte from sector offset 0x%8.8" PRIx32 "", - next_sec_addr - cur_addr, - cur_addr); - buff_ptr += (next_sec_addr - cur_addr); - cur_addr = next_sec_addr; - } - } - - if (cur_addr < end_addr) { - - sect_num = cur_addr >> MG_MFLASH_SECTOR_SIZE_SHIFT; - next_sec_addr = cur_addr + MG_MFLASH_SECTOR_SIZE; - - while (next_sec_addr <= end_addr) { - cnt++; - next_sec_addr += MG_MFLASH_SECTOR_SIZE; - } - - if (cnt) { - ret = mg_mflash_read_sects(buff_ptr, sect_num, cnt); - if (ret != ERROR_OK) - return ret; - } - - buff_ptr += cnt * MG_MFLASH_SECTOR_SIZE; - cur_addr += cnt * MG_MFLASH_SECTOR_SIZE; - - if (cur_addr < end_addr) { - - sect_num = cur_addr >> MG_MFLASH_SECTOR_SIZE_SHIFT; - ret = mg_mflash_read_sects(sect_buff, sect_num, 1); - if (ret != ERROR_OK) - return ret; - - memcpy(buff_ptr, sect_buff, end_addr - cur_addr); - LOG_DEBUG("mflash: copies %u byte", (unsigned)(end_addr - cur_addr)); - } - } - - return ret; -} - -static int mg_mflash_write(uint32_t addr, uint8_t *buff, uint32_t len) -{ - uint8_t *buff_ptr = buff; - uint8_t sect_buff[MG_MFLASH_SECTOR_SIZE]; - uint32_t cur_addr, next_sec_addr, end_addr, cnt, sect_num; - int ret = ERROR_OK; - - cnt = 0; - cur_addr = addr; - end_addr = addr + len; - - if (cur_addr & MG_MFLASH_SECTOR_SIZE_MASK) { - - next_sec_addr = (cur_addr + MG_MFLASH_SECTOR_SIZE) & ~MG_MFLASH_SECTOR_SIZE_MASK; - sect_num = cur_addr >> MG_MFLASH_SECTOR_SIZE_SHIFT; - ret = mg_mflash_read_sects(sect_buff, sect_num, 1); - if (ret != ERROR_OK) - return ret; - - if (end_addr < next_sec_addr) { - memcpy(sect_buff + (cur_addr & MG_MFLASH_SECTOR_SIZE_MASK), - buff_ptr, - end_addr - cur_addr); - LOG_DEBUG( - "mflash: copies %" PRIu32 " byte to sector offset 0x%8.8" PRIx32 "", - end_addr - cur_addr, - cur_addr); - cur_addr = end_addr; - } else { - memcpy(sect_buff + (cur_addr & MG_MFLASH_SECTOR_SIZE_MASK), - buff_ptr, - next_sec_addr - cur_addr); - LOG_DEBUG( - "mflash: copies %" PRIu32 " byte to sector offset 0x%8.8" PRIx32 "", - next_sec_addr - cur_addr, - cur_addr); - buff_ptr += (next_sec_addr - cur_addr); - cur_addr = next_sec_addr; - } - - ret = mg_mflash_write_sects(sect_buff, sect_num, 1); - if (ret != ERROR_OK) - return ret; - } - - if (cur_addr < end_addr) { - - sect_num = cur_addr >> MG_MFLASH_SECTOR_SIZE_SHIFT; - next_sec_addr = cur_addr + MG_MFLASH_SECTOR_SIZE; - - while (next_sec_addr <= end_addr) { - cnt++; - next_sec_addr += MG_MFLASH_SECTOR_SIZE; - } - - if (cnt) { - ret = mg_mflash_write_sects(buff_ptr, sect_num, cnt); - if (ret != ERROR_OK) - return ret; - } - - buff_ptr += cnt * MG_MFLASH_SECTOR_SIZE; - cur_addr += cnt * MG_MFLASH_SECTOR_SIZE; - - if (cur_addr < end_addr) { - - sect_num = cur_addr >> MG_MFLASH_SECTOR_SIZE_SHIFT; - ret = mg_mflash_read_sects(sect_buff, sect_num, 1); - if (ret != ERROR_OK) - return ret; - - memcpy(sect_buff, buff_ptr, end_addr - cur_addr); - LOG_DEBUG("mflash: copies %" PRIu32 " byte", end_addr - cur_addr); - ret = mg_mflash_write_sects(sect_buff, sect_num, 1); - } - } - - return ret; -} - -COMMAND_HANDLER(mg_write_cmd) -{ - uint32_t address, cnt, res, i; - uint8_t *buffer; - struct fileio *fileio; - int ret; - - if (CMD_ARGC != 3) - return ERROR_COMMAND_SYNTAX_ERROR; - - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], address); - - ret = fileio_open(&fileio, CMD_ARGV[1], FILEIO_READ, FILEIO_BINARY); - if (ret != ERROR_OK) - return ret; - - size_t filesize; - buffer = malloc(MG_FILEIO_CHUNK); - if (!buffer) { - fileio_close(fileio); - return ERROR_FAIL; - } - int retval = fileio_size(fileio, &filesize); - if (retval != ERROR_OK) { - fileio_close(fileio); - free(buffer); - return retval; - } - - cnt = filesize / MG_FILEIO_CHUNK; - res = filesize % MG_FILEIO_CHUNK; - - struct duration bench; - duration_start(&bench); - - size_t buf_cnt; - for (i = 0; i < cnt; i++) { - 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); - if (ret != ERROR_OK) - goto mg_write_cmd_err; - address += MG_FILEIO_CHUNK; - } - - if (res) { - ret = fileio_read(fileio, res, buffer, &buf_cnt); - if (ret != ERROR_OK) - goto mg_write_cmd_err; - ret = mg_mflash_write(address, buffer, res); - if (ret != ERROR_OK) - goto mg_write_cmd_err; - } - - if (duration_measure(&bench) == ERROR_OK) { - command_print(CMD_CTX, "wrote %zu bytes from file %s " - "in %fs (%0.3f kB/s)", filesize, CMD_ARGV[1], - duration_elapsed(&bench), duration_kbps(&bench, filesize)); - } - - free(buffer); - fileio_close(fileio); - - return ERROR_OK; - -mg_write_cmd_err: - free(buffer); - fileio_close(fileio); - - return ret; -} - -COMMAND_HANDLER(mg_dump_cmd) -{ - uint32_t address, size, cnt, res, i; - uint8_t *buffer; - struct fileio *fileio; - int ret; - - if (CMD_ARGC != 4) - return ERROR_COMMAND_SYNTAX_ERROR; - - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], address); - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[3], size); - - ret = fileio_open(&fileio, CMD_ARGV[1], FILEIO_WRITE, FILEIO_BINARY); - if (ret != ERROR_OK) - return ret; - - buffer = malloc(MG_FILEIO_CHUNK); - if (!buffer) { - fileio_close(fileio); - return ERROR_FAIL; - } - - cnt = size / MG_FILEIO_CHUNK; - res = size % MG_FILEIO_CHUNK; - - struct duration bench; - duration_start(&bench); - - size_t size_written; - for (i = 0; i < cnt; i++) { - 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); - if (ret != ERROR_OK) - goto mg_dump_cmd_err; - address += MG_FILEIO_CHUNK; - } - - if (res) { - ret = mg_mflash_read(address, buffer, res); - if (ret != ERROR_OK) - goto mg_dump_cmd_err; - ret = fileio_write(fileio, res, buffer, &size_written); - if (ret != ERROR_OK) - goto mg_dump_cmd_err; - } - - if (duration_measure(&bench) == ERROR_OK) { - command_print(CMD_CTX, "dump image (address 0x%8.8" PRIx32 " " - "size %" PRIu32 ") to file %s in %fs (%0.3f kB/s)", - address, size, CMD_ARGV[1], - duration_elapsed(&bench), duration_kbps(&bench, size)); - } - - free(buffer); - fileio_close(fileio); - - return ERROR_OK; - -mg_dump_cmd_err: - free(buffer); - fileio_close(fileio); - - return ret; -} - -static int mg_set_feature(mg_feature_id feature, mg_feature_val config) -{ - struct target *target = mflash_bank->target; - uint32_t mg_task_reg = mflash_bank->base + MG_REG_OFFSET; - int ret; - - ret = mg_dsk_wait(mg_io_wait_rdy_noerr, MG_OEM_DISK_WAIT_TIME_NORMAL); - if (ret != ERROR_OK) - return ret; - - ret = target_write_u8(target, mg_task_reg + MG_REG_FEATURE, feature); - ret |= target_write_u8(target, mg_task_reg + MG_REG_SECT_CNT, config); - ret |= target_write_u8(target, mg_task_reg + MG_REG_COMMAND, - mg_io_cmd_set_feature); - - return ret; -} - -static int mg_is_valid_pll(double XIN, int N, double CLK_OUT, int NO) -{ - double v1 = XIN / N; - double v2 = CLK_OUT * NO; - - if (v1 < 1000000 || v1 > 15000000 || v2 < 100000000 || v2 > 500000000) - return ERROR_MG_INVALID_PLL; - - return ERROR_OK; -} - -static int mg_pll_get_M(unsigned short feedback_div) -{ - int i, M; - - for (i = 1, M = 0; i < 512; i <<= 1, feedback_div >>= 1) - M += (feedback_div & 1) * i; - - return M + 2; -} - -static int mg_pll_get_N(unsigned char input_div) -{ - int i, N; - - for (i = 1, N = 0; i < 32; i <<= 1, input_div >>= 1) - N += (input_div & 1) * i; - - return N + 2; -} - -static int mg_pll_get_NO(unsigned char output_div) -{ - int i, NO; - - for (i = 0, NO = 1; i < 2; ++i, output_div >>= 1) - if (output_div & 1) - NO = NO << 1; - - return NO; -} - -static double mg_do_calc_pll(double XIN, mg_pll_t *p_pll_val, int is_approximate) -{ - unsigned short i; - unsigned char j, k; - int M, N, NO; - double CLK_OUT; - double DIV = 1; - double ROUND = 0; - - if (is_approximate) { - DIV = 1000000; - ROUND = 500000; - } - - for (i = 0; i < MG_PLL_MAX_FEEDBACKDIV_VAL; ++i) { - M = mg_pll_get_M(i); - - for (j = 0; j < MG_PLL_MAX_INPUTDIV_VAL; ++j) { - N = mg_pll_get_N(j); - - for (k = 0; k < MG_PLL_MAX_OUTPUTDIV_VAL; ++k) { - NO = mg_pll_get_NO(k); - - CLK_OUT = XIN * ((double)M / N) / NO; - - if ((int)((CLK_OUT + ROUND) / DIV) - == (int)(MG_PLL_CLK_OUT / DIV)) { - if (mg_is_valid_pll(XIN, N, CLK_OUT, NO) == ERROR_OK) { - p_pll_val->lock_cyc = - (int)(XIN * MG_PLL_STD_LOCKCYCLE / - MG_PLL_STD_INPUTCLK); - p_pll_val->feedback_div = i; - p_pll_val->input_div = j; - p_pll_val->output_div = k; - - return CLK_OUT; - } - } - } - } - } - - return 0; -} - -static double mg_calc_pll(double XIN, mg_pll_t *p_pll_val) -{ - double CLK_OUT; - - CLK_OUT = mg_do_calc_pll(XIN, p_pll_val, 0); - - if (!CLK_OUT) - return mg_do_calc_pll(XIN, p_pll_val, 1); - else - return CLK_OUT; -} - -static int mg_verify_interface(void) -{ - uint16_t buff[MG_MFLASH_SECTOR_SIZE >> 1]; - uint16_t i, j; - uint32_t address = mflash_bank->base + MG_BUFFER_OFFSET; - struct target *target = mflash_bank->target; - int ret; - - for (j = 0; j < 10; j++) { - for (i = 0; i < MG_MFLASH_SECTOR_SIZE >> 1; i++) - buff[i] = i; - - ret = target_write_memory(target, address, 2, - MG_MFLASH_SECTOR_SIZE / 2, (uint8_t *)buff); - if (ret != ERROR_OK) - return ret; - - memset(buff, 0xff, MG_MFLASH_SECTOR_SIZE); - - ret = target_read_memory(target, address, 2, - MG_MFLASH_SECTOR_SIZE / 2, (uint8_t *)buff); - if (ret != ERROR_OK) - return ret; - - for (i = 0; i < MG_MFLASH_SECTOR_SIZE >> 1; i++) { - if (buff[i] != i) { - LOG_ERROR("mflash: verify interface fail"); - return ERROR_MG_INTERFACE; - } - } - } - - LOG_INFO("mflash: verify interface ok"); - return ret; -} - -static const char g_strSEG_SerialNum[20] = { - 'G', 'm', 'n', 'i', '-', 'e', 'e', 'S', 'g', 'a', 'e', 'l', - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 -}; - -static const char g_strSEG_FWRev[8] = { - 'F', 'X', 'L', 'T', '2', 'v', '0', '.' -}; - -static const char g_strSEG_ModelNum[40] = { - 'F', 'X', 'A', 'L', 'H', 'S', '2', 0x20, '0', '0', 's', '7', - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 -}; - -static void mg_gen_ataid(mg_io_type_drv_info *pSegIdDrvInfo) -{ - /* b15 is ATA device(0) , b7 is Removable Media Device */ - pSegIdDrvInfo->general_configuration = 0x045A; - /* 128MB : Cylinder=> 977 , Heads=> 8 , Sectors=> 32 - * 256MB : Cylinder=> 980 , Heads=> 16 , Sectors=> 32 - * 384MB : Cylinder=> 745 , Heads=> 16 , Sectors=> 63 - */ - pSegIdDrvInfo->number_of_cylinders = 0x02E9; - pSegIdDrvInfo->reserved1 = 0x0; - pSegIdDrvInfo->number_of_heads = 0x10; - pSegIdDrvInfo->unformatted_bytes_per_track = 0x0; - pSegIdDrvInfo->unformatted_bytes_per_sector = 0x0; - pSegIdDrvInfo->sectors_per_track = 0x3F; - pSegIdDrvInfo->vendor_unique1[0] = 0x000B; - pSegIdDrvInfo->vendor_unique1[1] = 0x7570; - pSegIdDrvInfo->vendor_unique1[2] = 0x8888; - - memcpy(pSegIdDrvInfo->serial_number, g_strSEG_SerialNum, 20); - /* 0x2 : dual buffer */ - pSegIdDrvInfo->buffer_type = 0x2; - /* buffer size : 2KB */ - pSegIdDrvInfo->buffer_sector_size = 0x800; - pSegIdDrvInfo->number_of_ecc_bytes = 0; - - memcpy(pSegIdDrvInfo->firmware_revision, g_strSEG_FWRev, 8); - - memcpy(pSegIdDrvInfo->model_number, g_strSEG_ModelNum, 40); - - pSegIdDrvInfo->maximum_block_transfer = 0x4; - pSegIdDrvInfo->vendor_unique2 = 0x0; - pSegIdDrvInfo->dword_io = 0x00; - /* b11 : IORDY support(PIO Mode 4), b10 : Disable/Enbale IORDY - * b9 : LBA support, b8 : DMA mode support - */ - pSegIdDrvInfo->capabilities = 0x1 << 9; - - pSegIdDrvInfo->reserved2 = 0x4000; - pSegIdDrvInfo->vendor_unique3 = 0x00; - /* PIOMode-2 support */ - pSegIdDrvInfo->pio_cycle_timing_mode = 0x02; - pSegIdDrvInfo->vendor_unique4 = 0x00; - /* MultiWord-2 support */ - pSegIdDrvInfo->dma_cycle_timing_mode = 0x00; - /* b1 : word64~70 is valid - * b0 : word54~58 are valid and reflect the current numofcyls,heads,sectors - * b2 : If device supports Ultra DMA , set to one to vaildate word88 - */ - pSegIdDrvInfo->translation_fields_valid = (0x1 << 1) | (0x1 << 0); - pSegIdDrvInfo->number_of_current_cylinders = 0x02E9; - pSegIdDrvInfo->number_of_current_heads = 0x10; - pSegIdDrvInfo->current_sectors_per_track = 0x3F; - pSegIdDrvInfo->current_sector_capacity_lo = 0x7570; - pSegIdDrvInfo->current_sector_capacity_hi = 0x000B; - - pSegIdDrvInfo->multi_sector_count = 0x04; - /* b8 : Multiple secotr setting valid , b[7:0] num of secotrs per block */ - pSegIdDrvInfo->multi_sector_setting_valid = 0x01; - pSegIdDrvInfo->total_user_addressable_sectors_lo = 0x7570; - pSegIdDrvInfo->total_user_addressable_sectors_hi = 0x000B; - pSegIdDrvInfo->single_dma_modes_supported = 0x00; - pSegIdDrvInfo->single_dma_transfer_active = 0x00; - /* b2 :Multi-word DMA mode 2, b1 : Multi-word DMA mode 1 */ - pSegIdDrvInfo->multi_dma_modes_supported = (0x1 << 0); - /* b2 :Multi-word DMA mode 2, b1 : Multi-word DMA mode 1 */ - pSegIdDrvInfo->multi_dma_transfer_active = (0x1 << 0); - /* b0 : PIO Mode-3 support, b1 : PIO Mode-4 support */ - pSegIdDrvInfo->adv_pio_mode = 0x00; - /* 480(0x1E0)nsec for Multi-word DMA mode0 - * 150(0x96) nsec for Multi-word DMA mode1 - * 120(0x78) nsec for Multi-word DMA mode2 - */ - pSegIdDrvInfo->min_dma_cyc = 0x1E0; - pSegIdDrvInfo->recommend_dma_cyc = 0x1E0; - pSegIdDrvInfo->min_pio_cyc_no_iordy = 0x1E0; - pSegIdDrvInfo->min_pio_cyc_with_iordy = 0x1E0; - memset(pSegIdDrvInfo->reserved3, 0x00, 22); - /* b7 : ATA/ATAPI-7 ,b6 : ATA/ATAPI-6 ,b5 : ATA/ATAPI-5,b4 : ATA/ATAPI-4 */ - pSegIdDrvInfo->major_ver_num = 0x7E; - /* 0x1C : ATA/ATAPI-6 T13 1532D revision1 */ - pSegIdDrvInfo->minor_ver_num = 0x19; - /* NOP/READ BUFFER/WRITE BUFFER/Power management feature set support */ - pSegIdDrvInfo->feature_cmd_set_suprt0 = 0x7068; - /* Features/command set is valid/Advanced Pwr management/CFA feature set - * not support - */ - pSegIdDrvInfo->feature_cmd_set_suprt1 = 0x400C; - pSegIdDrvInfo->feature_cmd_set_suprt2 = 0x4000; - /* READ/WRITE BUFFER/PWR Management enable */ - pSegIdDrvInfo->feature_cmd_set_en0 = 0x7000; - /* CFA feature is disabled / Advancde power management disable */ - pSegIdDrvInfo->feature_cmd_set_en1 = 0x0; - pSegIdDrvInfo->feature_cmd_set_en2 = 0x4000; - pSegIdDrvInfo->reserved4 = 0x0; - /* 0x1 * 2minutes */ - pSegIdDrvInfo->req_time_for_security_er_done = 0x19; - pSegIdDrvInfo->req_time_for_enhan_security_er_done = 0x19; - /* Advanced power management level 1 */ - pSegIdDrvInfo->adv_pwr_mgm_lvl_val = 0x0; - pSegIdDrvInfo->reserved5 = 0x0; - memset(pSegIdDrvInfo->reserved6, 0x00, 68); - /* Security mode feature is disabled */ - pSegIdDrvInfo->security_stas = 0x0; - memset(pSegIdDrvInfo->vendor_uniq_bytes, 0x00, 62); - /* CFA power mode 1 support in maximum 200mA */ - pSegIdDrvInfo->cfa_pwr_mode = 0x0100; - memset(pSegIdDrvInfo->reserved7, 0x00, 190); -} - -static int mg_storage_config(void) -{ - uint8_t buff[512]; - int ret; - - ret = mg_set_feature(mg_feature_id_transmode, mg_feature_val_trans_vcmd); - if (ret != ERROR_OK) - return ret; - - mg_gen_ataid((mg_io_type_drv_info *)(void *)buff); - - ret = mg_mflash_do_write_sects(buff, 0, 1, mg_vcmd_update_stgdrvinfo); - if (ret != ERROR_OK) - return ret; - - ret = mg_set_feature(mg_feature_id_transmode, mg_feature_val_trans_default); - if (ret != ERROR_OK) - return ret; - - LOG_INFO("mflash: storage config ok"); - return ret; -} - -static int mg_boot_config(void) -{ - uint8_t buff[512]; - int ret; - - ret = mg_set_feature(mg_feature_id_transmode, mg_feature_val_trans_vcmd); - if (ret != ERROR_OK) - return ret; - - memset(buff, 0xff, 512); - - buff[0] = mg_op_mode_snd; /* operation mode */ - buff[1] = MG_UNLOCK_OTP_AREA; - buff[2] = 4; /* boot size */ - *((uint32_t *)(void *)(buff + 4)) = 0; /* XIP size */ - - ret = mg_mflash_do_write_sects(buff, 0, 1, mg_vcmd_update_xipinfo); - if (ret != ERROR_OK) - return ret; - - ret = mg_set_feature(mg_feature_id_transmode, mg_feature_val_trans_default); - if (ret != ERROR_OK) - return ret; - - LOG_INFO("mflash: boot config ok"); - return ret; -} - -static int mg_set_pll(mg_pll_t *pll) -{ - uint8_t buff[512]; - int ret; - - memset(buff, 0xff, 512); - /* PLL Lock cycle and Feedback 9bit Divider */ - memcpy(buff, &pll->lock_cyc, sizeof(uint32_t)); - memcpy(buff + 4, &pll->feedback_div, sizeof(uint16_t)); - buff[6] = pll->input_div; /* PLL Input 5bit Divider */ - buff[7] = pll->output_div; /* PLL Output Divider */ - - ret = mg_set_feature(mg_feature_id_transmode, mg_feature_val_trans_vcmd); - if (ret != ERROR_OK) - return ret; - - ret = mg_mflash_do_write_sects(buff, 0, 1, mg_vcmd_wr_pll); - if (ret != ERROR_OK) - return ret; - - ret = mg_set_feature(mg_feature_id_transmode, mg_feature_val_trans_default); - if (ret != ERROR_OK) - return ret; - - LOG_INFO("mflash: set pll ok"); - return ret; -} - -static int mg_erase_nand(void) -{ - int ret; - - ret = mg_set_feature(mg_feature_id_transmode, mg_feature_val_trans_vcmd); - if (ret != ERROR_OK) - return ret; - - ret = mg_mflash_do_write_sects(NULL, 0, 0, mg_vcmd_purge_nand); - if (ret != ERROR_OK) - return ret; - - ret = mg_set_feature(mg_feature_id_transmode, mg_feature_val_trans_default); - if (ret != ERROR_OK) - return ret; - - LOG_INFO("mflash: erase nand ok"); - return ret; -} - -COMMAND_HANDLER(mg_config_cmd) -{ - double fin, fout; - mg_pll_t pll; - int ret; - - ret = mg_verify_interface(); - if (ret != ERROR_OK) - return ret; - - ret = mg_mflash_rst(); - if (ret != ERROR_OK) - return ret; - - switch (CMD_ARGC) { - case 2: - if (!strcmp(CMD_ARGV[1], "boot")) - return mg_boot_config(); - else if (!strcmp(CMD_ARGV[1], "storage")) - return mg_storage_config(); - else - return ERROR_COMMAND_NOTFOUND; - break; - case 3: - if (!strcmp(CMD_ARGV[1], "pll")) { - unsigned long freq; - COMMAND_PARSE_NUMBER(ulong, CMD_ARGV[2], freq); - fin = freq; - - if (fin > MG_PLL_CLK_OUT) { - LOG_ERROR("mflash: input freq. is too large"); - return ERROR_MG_INVALID_OSC; - } - - fout = mg_calc_pll(fin, &pll); - - if (!fout) { - LOG_ERROR("mflash: cannot generate valid pll"); - return ERROR_MG_INVALID_PLL; - } - - LOG_INFO("mflash: Fout=%" PRIu32 " Hz, feedback=%u," - "indiv=%u, outdiv=%u, lock=%u", - (uint32_t)fout, pll.feedback_div, - pll.input_div, pll.output_div, - pll.lock_cyc); - - ret = mg_erase_nand(); - if (ret != ERROR_OK) - return ret; - - return mg_set_pll(&pll); - } else - return ERROR_COMMAND_NOTFOUND; - break; - default: - return ERROR_COMMAND_SYNTAX_ERROR; - } -} - -static const struct command_registration mflash_exec_command_handlers[] = { - { - .name = "probe", - .handler = mg_probe_cmd, - .mode = COMMAND_EXEC, - .help = "Detect bank configuration information", - }, - { - .name = "write", - .handler = mg_write_cmd, - .mode = COMMAND_EXEC, - /* FIXME bank_num is unused */ - .usage = "bank_num filename address", - .help = "Write binary file at the specified address.", - }, - { - .name = "dump", - .handler = mg_dump_cmd, - .mode = COMMAND_EXEC, - /* FIXME bank_num is unused */ - .usage = "bank_num filename address size", - .help = "Write specified number of bytes from a binary file " - "to the specified, address.", - }, - { - .name = "config", - .handler = mg_config_cmd, - .mode = COMMAND_EXEC, - .help = "Configure MFLASH options.", - .usage = "('boot'|'storage'|'pll' frequency)", - }, - COMMAND_REGISTRATION_DONE -}; - -static int mflash_init_drivers(struct command_context *cmd_ctx) -{ - if (!mflash_bank) - return ERROR_OK; - return register_commands(cmd_ctx, NULL, mflash_exec_command_handlers); -} - -COMMAND_HANDLER(handle_mflash_init_command) -{ - if (CMD_ARGC != 0) - return ERROR_COMMAND_SYNTAX_ERROR; - - static bool mflash_initialized; - if (mflash_initialized) { - LOG_INFO("'mflash init' has already been called"); - return ERROR_OK; - } - mflash_initialized = true; - - LOG_DEBUG("Initializing mflash devices..."); - return mflash_init_drivers(CMD_CTX); -} - -COMMAND_HANDLER(mg_bank_cmd) -{ - struct target *target; - int i; - - if (CMD_ARGC < 4) - return ERROR_COMMAND_SYNTAX_ERROR; - - target = get_target(CMD_ARGV[3]); - if (target == NULL) { - LOG_ERROR("target '%s' not defined", CMD_ARGV[3]); - return ERROR_FAIL; - } - - mflash_bank = calloc(sizeof(struct mflash_bank), 1); - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], mflash_bank->base); - /** @todo Verify how this parsing should work, then document it. */ - char *str; - mflash_bank->rst_pin.num = strtoul(CMD_ARGV[2], &str, 0); - if (*str) - mflash_bank->rst_pin.port[0] = (uint16_t) - tolower((unsigned)str[0]); - - mflash_bank->target = target; - - for (i = 0; mflash_gpio[i]; i++) { - if (!strcmp(mflash_gpio[i]->name, CMD_ARGV[0])) - mflash_bank->gpio_drv = mflash_gpio[i]; - } - - if (!mflash_bank->gpio_drv) { - LOG_ERROR("%s is unsupported soc", CMD_ARGV[0]); - return ERROR_MG_UNSUPPORTED_SOC; - } - - return ERROR_OK; -} - -static const struct command_registration mflash_config_command_handlers[] = { - { - .name = "bank", - .handler = mg_bank_cmd, - .mode = COMMAND_CONFIG, - .help = "configure a mflash device bank", - .usage = "soc_type base_addr pin_id target", - }, - { - .name = "init", - .mode = COMMAND_CONFIG, - .handler = handle_mflash_init_command, - .help = "initialize mflash devices", - .usage = "" - }, - COMMAND_REGISTRATION_DONE -}; -static const struct command_registration mflash_command_handler[] = { - { - .name = "mflash", - .mode = COMMAND_ANY, - .help = "mflash command group", - .usage = "", - .chain = mflash_config_command_handlers, - }, - COMMAND_REGISTRATION_DONE -}; -int mflash_register_commands(struct command_context *cmd_ctx) -{ - return register_commands(cmd_ctx, NULL, mflash_command_handler); -} diff --git a/src/flash/mflash.h b/src/flash/mflash.h deleted file mode 100644 index 18da40361..000000000 --- a/src/flash/mflash.h +++ /dev/null @@ -1,289 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007-2008 by unsik Kim * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 OPENOCD_FLASH_MFLASH_H -#define OPENOCD_FLASH_MFLASH_H - -struct command_context; - -typedef unsigned long mg_io_uint32; -typedef unsigned short mg_io_uint16; -typedef unsigned char mg_io_uint8; - -struct mflash_gpio_num { - char port[2]; - signed short num; -}; - -struct mflash_gpio_drv { - const char *name; - int (*set_gpio_to_output)(struct mflash_gpio_num gpio); - int (*set_gpio_output_val)(struct mflash_gpio_num gpio, uint8_t val); -}; - -typedef struct _mg_io_type_drv_info { - - mg_io_uint16 general_configuration; /* 00 */ - mg_io_uint16 number_of_cylinders; /* 01 */ - mg_io_uint16 reserved1; /* 02 */ - mg_io_uint16 number_of_heads; /* 03 */ - mg_io_uint16 unformatted_bytes_per_track; /* 04 */ - mg_io_uint16 unformatted_bytes_per_sector; /* 05 */ - mg_io_uint16 sectors_per_track; /* 06 */ - mg_io_uint16 vendor_unique1[3]; /* 07/08/09 */ - - mg_io_uint8 serial_number[20]; /* 10~19 */ - - mg_io_uint16 buffer_type; /* 20 */ - mg_io_uint16 buffer_sector_size; /* 21 */ - mg_io_uint16 number_of_ecc_bytes; /* 22 */ - - mg_io_uint8 firmware_revision[8]; /* 23~26 */ - mg_io_uint8 model_number[40]; /* 27 */ - - mg_io_uint8 maximum_block_transfer; /* 47 low byte */ - mg_io_uint8 vendor_unique2; /* 47 high byte */ - mg_io_uint16 dword_io; /* 48 */ - - mg_io_uint16 capabilities; /* 49 */ - mg_io_uint16 reserved2; /* 50 */ - - mg_io_uint8 vendor_unique3; /* 51 low byte */ - mg_io_uint8 pio_cycle_timing_mode; /* 51 high byte */ - mg_io_uint8 vendor_unique4; /* 52 low byte */ - mg_io_uint8 dma_cycle_timing_mode; /* 52 high byte */ - mg_io_uint16 translation_fields_valid; /* 53 (low bit) */ - mg_io_uint16 number_of_current_cylinders; /* 54 */ - mg_io_uint16 number_of_current_heads; /* 55 */ - mg_io_uint16 current_sectors_per_track; /* 56 */ - mg_io_uint16 current_sector_capacity_lo; /* 57 & 58 */ - mg_io_uint16 current_sector_capacity_hi; /* 57 & 58 */ - mg_io_uint8 multi_sector_count; /* 59 low */ - mg_io_uint8 multi_sector_setting_valid; /* 59 high (low bit) */ - - mg_io_uint16 total_user_addressable_sectors_lo; /* 60 & 61 */ - mg_io_uint16 total_user_addressable_sectors_hi; /* 60 & 61 */ - - mg_io_uint8 single_dma_modes_supported; /* 62 low byte */ - mg_io_uint8 single_dma_transfer_active; /* 62 high byte */ - mg_io_uint8 multi_dma_modes_supported; /* 63 low byte */ - mg_io_uint8 multi_dma_transfer_active; /* 63 high byte */ - mg_io_uint16 adv_pio_mode; - mg_io_uint16 min_dma_cyc; - mg_io_uint16 recommend_dma_cyc; - mg_io_uint16 min_pio_cyc_no_iordy; - mg_io_uint16 min_pio_cyc_with_iordy; - mg_io_uint8 reserved3[22]; - mg_io_uint16 major_ver_num; - mg_io_uint16 minor_ver_num; - mg_io_uint16 feature_cmd_set_suprt0; - mg_io_uint16 feature_cmd_set_suprt1; - mg_io_uint16 feature_cmd_set_suprt2; - mg_io_uint16 feature_cmd_set_en0; - mg_io_uint16 feature_cmd_set_en1; - mg_io_uint16 feature_cmd_set_en2; - mg_io_uint16 reserved4; - mg_io_uint16 req_time_for_security_er_done; - mg_io_uint16 req_time_for_enhan_security_er_done; - mg_io_uint16 adv_pwr_mgm_lvl_val; - mg_io_uint16 reserved5; - mg_io_uint16 re_of_hw_rst; - mg_io_uint8 reserved6[68]; - mg_io_uint16 security_stas; - mg_io_uint8 vendor_uniq_bytes[62]; - mg_io_uint16 cfa_pwr_mode; - mg_io_uint8 reserved7[186]; - - mg_io_uint16 scts_per_secure_data_unit; - mg_io_uint16 integrity_word; - -} mg_io_type_drv_info; - -typedef struct _mg_pll_t { - unsigned int lock_cyc; - unsigned short feedback_div; /* 9bit divider */ - unsigned char input_div; /* 5bit divider */ - unsigned char output_div; /* 2bit divider */ -} mg_pll_t; - -struct mg_drv_info { - mg_io_type_drv_info drv_id; - uint32_t tot_sects; -}; - -struct mflash_bank { - uint32_t base; - - struct mflash_gpio_num rst_pin; - - struct mflash_gpio_drv *gpio_drv; - struct target *target; - struct mg_drv_info *drv_info; -}; - -int mflash_register_commands(struct command_context *cmd_ctx); - -#define MG_MFLASH_SECTOR_SIZE (0x200) /* 512Bytes = 2^9 */ -#define MG_MFLASH_SECTOR_SIZE_MASK (0x200-1) -#define MG_MFLASH_SECTOR_SIZE_SHIFT (9) - -#define MG_BUFFER_OFFSET 0x8000 -#define MG_REG_OFFSET 0xC000 -#define MG_REG_FEATURE 0x2 /* write case */ -#define MG_REG_ERROR 0x2 /* read case */ -#define MG_REG_SECT_CNT 0x4 -#define MG_REG_SECT_NUM 0x6 -#define MG_REG_CYL_LOW 0x8 -#define MG_REG_CYL_HIGH 0xA -#define MG_REG_DRV_HEAD 0xC -#define MG_REG_COMMAND 0xE /* write case */ -#define MG_REG_STATUS 0xE /* read case */ -#define MG_REG_DRV_CTRL 0x10 -#define MG_REG_BURST_CTRL 0x12 - -#define MG_OEM_DISK_WAIT_TIME_LONG 15000 /* msec */ -#define MG_OEM_DISK_WAIT_TIME_NORMAL 3000 /* msec */ -#define MG_OEM_DISK_WAIT_TIME_SHORT 1000 /* msec */ - -#define MG_PLL_CLK_OUT 66000000.0 /* 66Mhz */ -#define MG_PLL_MAX_FEEDBACKDIV_VAL 512 -#define MG_PLL_MAX_INPUTDIV_VAL 32 -#define MG_PLL_MAX_OUTPUTDIV_VAL 4 - -#define MG_PLL_STD_INPUTCLK 12000000.0 /* 12Mhz */ -#define MG_PLL_STD_LOCKCYCLE 10000 - -#define MG_UNLOCK_OTP_AREA 0xFF - -#define MG_FILEIO_CHUNK 1048576 - -#define ERROR_MG_IO (-1600) -#define ERROR_MG_TIMEOUT (-1601) -#define ERROR_MG_INVALID_PLL (-1603) -#define ERROR_MG_INTERFACE (-1604) -#define ERROR_MG_INVALID_OSC (-1605) -#define ERROR_MG_UNSUPPORTED_SOC (-1606) - -typedef enum _mg_io_type_wait { - - mg_io_wait_bsy = 1, - mg_io_wait_not_bsy = 2, - mg_io_wait_rdy = 3, - mg_io_wait_drq = 4, /* wait for data request */ - mg_io_wait_drq_noerr = 5, /* wait for DRQ but ignore the error status bit */ - mg_io_wait_rdy_noerr = 6 /* wait for ready, but ignore error status bit */ - -} mg_io_type_wait; - -/*= "Status Register" bit masks. */ -typedef enum _mg_io_type_rbit_status { - - mg_io_rbit_status_error = 0x01, /* error bit in status register */ - mg_io_rbit_status_corrected_error = 0x04, /* corrected error in status register */ - mg_io_rbit_status_data_req = 0x08, /* data request bit in status register */ - mg_io_rbit_status_seek_done = 0x10, /* DSC - Drive Seek Complete */ - mg_io_rbit_status_write_fault = 0x20, /* DWF - Drive Write Fault */ - mg_io_rbit_status_ready = 0x40, - mg_io_rbit_status_busy = 0x80 - -} mg_io_type_rbit_status; - -/*= "Error Register" bit masks. */ -typedef enum _mg_io_type_rbit_error { - - mg_io_rbit_err_general = 0x01, - mg_io_rbit_err_aborted = 0x04, - mg_io_rbit_err_bad_sect_num = 0x10, - mg_io_rbit_err_uncorrectable = 0x40, - mg_io_rbit_err_bad_block = 0x80 - -} mg_io_type_rbit_error; - -/* = "Device Control Register" bit. */ -typedef enum _mg_io_type_rbit_devc { - - mg_io_rbit_devc_intr = 0x02, /* interrupt enable bit (1:disable, 0:enable) */ - mg_io_rbit_devc_srst = 0x04 /* softwrae reset bit (1:assert, 0:de-assert) */ - -} mg_io_type_rbit_devc; - -/* "Drive Select/Head Register" values. */ -typedef enum _mg_io_type_rval_dev { - - mg_io_rval_dev_must_be_on = 0x80, /* These 1 bits are always on */ - mg_io_rval_dev_drv_master = (0x00 | mg_io_rval_dev_must_be_on), /* Master */ - mg_io_rval_dev_drv_slave0 = (0x10 | mg_io_rval_dev_must_be_on), /* Slave0 */ - mg_io_rval_dev_drv_slave1 = (0x20 | mg_io_rval_dev_must_be_on), /* Slave1 */ - mg_io_rval_dev_drv_slave2 = (0x30 | mg_io_rval_dev_must_be_on), /* Slave2 */ - mg_io_rval_dev_lba_mode = (0x40 | mg_io_rval_dev_must_be_on) - -} mg_io_type_rval_dev; - -typedef enum _mg_io_type_cmd { - mg_io_cmd_read = 0x20, - mg_io_cmd_write = 0x30, - - mg_io_cmd_setmul = 0xC6, - mg_io_cmd_readmul = 0xC4, - mg_io_cmd_writemul = 0xC5, - - mg_io_cmd_idle = 0x97, /* 0xE3 */ - mg_io_cmd_idle_immediate = 0x95, /* 0xE1 */ - - mg_io_cmd_setsleep = 0x99, /* 0xE6 */ - mg_io_cmd_stdby = 0x96, /* 0xE2 */ - mg_io_cmd_stdby_immediate = 0x94, /* 0xE0 */ - - mg_io_cmd_identify = 0xEC, - mg_io_cmd_set_feature = 0xEF, - - mg_io_cmd_confirm_write = 0x3C, - mg_io_cmd_confirm_read = 0x40, - mg_io_cmd_wakeup = 0xC3 - -} mg_io_type_cmd; - -typedef enum _mg_feature_id { - mg_feature_id_transmode = 0x3 -} mg_feature_id; - -typedef enum _mg_feature_val { - mg_feature_val_trans_default = 0x0, - mg_feature_val_trans_vcmd = 0x3, - mg_feature_val_trand_vcmds = 0x2 -} mg_feature_val; - -typedef enum _mg_vcmd { - mg_vcmd_update_xipinfo = 0xFA, /* FWPATCH commmand through IOM I/O */ - mg_vcmd_verify_fwpatch = 0xFB, /* FWPATCH commmand through IOM I/O */ - mg_vcmd_update_stgdrvinfo = 0xFC, /* IOM identificatin info program command */ - mg_vcmd_prep_fwpatch = 0xFD, /* FWPATCH commmand through IOM I/O */ - mg_vcmd_exe_fwpatch = 0xFE, /* FWPATCH commmand through IOM I/O */ - mg_vcmd_wr_pll = 0x8B, - mg_vcmd_purge_nand = 0x8C, /* Only for Seagle */ - mg_vcmd_lock_otp = 0x8D, - mg_vcmd_rd_otp = 0x8E, - mg_vcmd_wr_otp = 0x8F -} mg_vcmd; - -typedef enum _mg_opmode { - mg_op_mode_xip = 1, /* TRUE XIP */ - mg_op_mode_snd = 2, /* BOOT + Storage */ - mg_op_mode_stg = 0 /* Only Storage */ -} mg_opmode; - -#endif /* OPENOCD_FLASH_MFLASH_H */ diff --git a/src/flash/nand/Makefile.am b/src/flash/nand/Makefile.am deleted file mode 100644 index 2ddd096ae..000000000 --- a/src/flash/nand/Makefile.am +++ /dev/null @@ -1,46 +0,0 @@ -include $(top_srcdir)/common.mk - -noinst_LTLIBRARIES = libocdflashnand.la - -libocdflashnand_la_SOURCES = \ - ecc.c \ - ecc_kw.c \ - core.c \ - fileio.c \ - tcl.c \ - arm_io.c \ - $(NAND_DRIVERS) \ - driver.c - -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 - -MAINTAINERCLEANFILES = $(srcdir)/Makefile.in diff --git a/src/flash/nand/arm_io.c b/src/flash/nand/arm_io.c deleted file mode 100644 index e319f9585..000000000 --- a/src/flash/nand/arm_io.c +++ /dev/null @@ -1,299 +0,0 @@ -/* - * Copyright (C) 2009 by Marvell Semiconductors, Inc. - * Written by Nicolas Pitre - * - * Copyright (C) 2009 by David Brownell - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "core.h" -#include "arm_io.h" -#include -#include -#include -#include - -/** - * Copies code to a working area. This will allocate room for the code plus the - * additional amount requested if the working area pointer is null. - * - * @param target Pointer to the target to copy code to - * @param code Pointer to the code area to be copied - * @param code_size Size of the code being copied - * @param additional Size of the additional area to be allocated in addition to - * code - * @param area Pointer to a pointer to a working area to copy code to - * @return Success or failure of the operation - */ -static int arm_code_to_working_area(struct target *target, - const uint32_t *code, unsigned code_size, - unsigned additional, struct working_area **area) -{ - uint8_t code_buf[code_size]; - int retval; - unsigned size = code_size + additional; - - /* REVISIT this assumes size doesn't ever change. - * That's usually correct; but there are boards with - * both large and small page chips, where it won't be... - */ - - /* make sure we have a working area */ - if (NULL == *area) { - retval = target_alloc_working_area(target, size, area); - if (retval != ERROR_OK) { - LOG_DEBUG("%s: no %d byte buffer", __func__, (int) size); - return ERROR_NAND_NO_BUFFER; - } - } - - /* buffer code in target endianness */ - target_buffer_set_u32_array(target, code_buf, code_size / 4, code); - - /* copy code to work area */ - retval = target_write_memory(target, (*area)->address, - 4, code_size / 4, code_buf); - - return retval; -} - -/** - * ARM-specific bulk write from buffer to address of 8-bit wide NAND. - * For now this supports ARMv4,ARMv5 and ARMv7-M cores. - * - * Enhancements to target_run_algorithm() could enable: - * - ARMv6 and ARMv7 cores in ARM mode - * - * Different code fragments could handle: - * - 16-bit wide data (needs different setup) - * - * @param nand Pointer to the arm_nand_data struct that defines the I/O - * @param data Pointer to the data to be copied to flash - * @param size Size of the data being copied - * @return Success or failure of the operation - */ -int arm_nandwrite(struct arm_nand_data *nand, uint8_t *data, int size) -{ - struct target *target = nand->target; - struct arm_algorithm armv4_5_algo; - struct armv7m_algorithm armv7m_algo; - void *arm_algo; - struct arm *arm = target->arch_info; - struct reg_param reg_params[3]; - uint32_t target_buf; - uint32_t exit_var = 0; - int retval; - - /* Inputs: - * r0 NAND data address (byte wide) - * r1 buffer address - * r2 buffer length - */ - static const uint32_t code_armv4_5[] = { - 0xe4d13001, /* s: ldrb r3, [r1], #1 */ - 0xe5c03000, /* strb r3, [r0] */ - 0xe2522001, /* subs r2, r2, #1 */ - 0x1afffffb, /* bne s */ - - /* exit: ARMv4 needs hardware breakpoint */ - 0xe1200070, /* e: bkpt #0 */ - }; - - /* Inputs: - * r0 NAND data address (byte wide) - * r1 buffer address - * r2 buffer length - * - * see contrib/loaders/flash/armv7m_io.s for src - */ - static const uint32_t code_armv7m[] = { - 0x3b01f811, - 0x3a017003, - 0xaffaf47f, - 0xbf00be00, - }; - - int target_code_size = 0; - const uint32_t *target_code_src = NULL; - - /* set up algorithm */ - if (is_armv7m(target_to_armv7m(target))) { /* armv7m target */ - armv7m_algo.common_magic = ARMV7M_COMMON_MAGIC; - armv7m_algo.core_mode = ARM_MODE_THREAD; - arm_algo = &armv7m_algo; - target_code_size = sizeof(code_armv7m); - target_code_src = code_armv7m; - } else { - armv4_5_algo.common_magic = ARM_COMMON_MAGIC; - armv4_5_algo.core_mode = ARM_MODE_SVC; - armv4_5_algo.core_state = ARM_STATE_ARM; - arm_algo = &armv4_5_algo; - target_code_size = sizeof(code_armv4_5); - target_code_src = code_armv4_5; - } - - if (nand->op != ARM_NAND_WRITE || !nand->copy_area) { - retval = arm_code_to_working_area(target, target_code_src, target_code_size, - nand->chunk_size, &nand->copy_area); - if (retval != ERROR_OK) - return retval; - } - - nand->op = ARM_NAND_WRITE; - - /* copy data to work area */ - target_buf = nand->copy_area->address + target_code_size; - retval = target_write_buffer(target, target_buf, size, data); - if (retval != ERROR_OK) - return retval; - - /* set up parameters */ - init_reg_param(®_params[0], "r0", 32, PARAM_IN); - init_reg_param(®_params[1], "r1", 32, PARAM_IN); - init_reg_param(®_params[2], "r2", 32, PARAM_IN); - - buf_set_u32(reg_params[0].value, 0, 32, nand->data); - buf_set_u32(reg_params[1].value, 0, 32, target_buf); - buf_set_u32(reg_params[2].value, 0, 32, size); - - /* armv4 must exit using a hardware breakpoint */ - if (arm->is_armv4) - exit_var = nand->copy_area->address + target_code_size - 4; - - /* use alg to write data from work area to NAND chip */ - retval = target_run_algorithm(target, 0, NULL, 3, reg_params, - nand->copy_area->address, exit_var, 1000, arm_algo); - if (retval != ERROR_OK) - LOG_ERROR("error executing hosted NAND write"); - - destroy_reg_param(®_params[0]); - destroy_reg_param(®_params[1]); - destroy_reg_param(®_params[2]); - - return retval; -} - -/** - * Uses an on-chip algorithm for an ARM device to read from a NAND device and - * store the data into the host machine's memory. - * - * @param nand Pointer to the arm_nand_data struct that defines the I/O - * @param data Pointer to the data buffer to store the read data - * @param size Amount of data to be stored to the buffer. - * @return Success or failure of the operation - */ -int arm_nandread(struct arm_nand_data *nand, uint8_t *data, uint32_t size) -{ - struct target *target = nand->target; - struct arm_algorithm armv4_5_algo; - struct armv7m_algorithm armv7m_algo; - void *arm_algo; - struct arm *arm = target->arch_info; - struct reg_param reg_params[3]; - uint32_t target_buf; - uint32_t exit_var = 0; - int retval; - - /* Inputs: - * r0 buffer address - * r1 NAND data address (byte wide) - * r2 buffer length - */ - static const uint32_t code_armv4_5[] = { - 0xe5d13000, /* s: ldrb r3, [r1] */ - 0xe4c03001, /* strb r3, [r0], #1 */ - 0xe2522001, /* subs r2, r2, #1 */ - 0x1afffffb, /* bne s */ - - /* exit: ARMv4 needs hardware breakpoint */ - 0xe1200070, /* e: bkpt #0 */ - }; - - /* Inputs: - * r0 buffer address - * r1 NAND data address (byte wide) - * r2 buffer length - * - * see contrib/loaders/flash/armv7m_io.s for src - */ - static const uint32_t code_armv7m[] = { - 0xf800780b, - 0x3a013b01, - 0xaffaf47f, - 0xbf00be00, - }; - - int target_code_size = 0; - const uint32_t *target_code_src = NULL; - - /* set up algorithm */ - if (is_armv7m(target_to_armv7m(target))) { /* armv7m target */ - armv7m_algo.common_magic = ARMV7M_COMMON_MAGIC; - armv7m_algo.core_mode = ARM_MODE_THREAD; - arm_algo = &armv7m_algo; - target_code_size = sizeof(code_armv7m); - target_code_src = code_armv7m; - } else { - armv4_5_algo.common_magic = ARM_COMMON_MAGIC; - armv4_5_algo.core_mode = ARM_MODE_SVC; - armv4_5_algo.core_state = ARM_STATE_ARM; - arm_algo = &armv4_5_algo; - target_code_size = sizeof(code_armv4_5); - target_code_src = code_armv4_5; - } - - /* create the copy area if not yet available */ - if (nand->op != ARM_NAND_READ || !nand->copy_area) { - retval = arm_code_to_working_area(target, target_code_src, target_code_size, - nand->chunk_size, &nand->copy_area); - if (retval != ERROR_OK) - return retval; - } - - nand->op = ARM_NAND_READ; - target_buf = nand->copy_area->address + target_code_size; - - /* set up parameters */ - init_reg_param(®_params[0], "r0", 32, PARAM_IN); - init_reg_param(®_params[1], "r1", 32, PARAM_IN); - init_reg_param(®_params[2], "r2", 32, PARAM_IN); - - buf_set_u32(reg_params[0].value, 0, 32, target_buf); - buf_set_u32(reg_params[1].value, 0, 32, nand->data); - buf_set_u32(reg_params[2].value, 0, 32, size); - - /* armv4 must exit using a hardware breakpoint */ - if (arm->is_armv4) - exit_var = nand->copy_area->address + target_code_size - 4; - - /* use alg to write data from NAND chip to work area */ - retval = target_run_algorithm(target, 0, NULL, 3, reg_params, - nand->copy_area->address, exit_var, 1000, arm_algo); - if (retval != ERROR_OK) - LOG_ERROR("error executing hosted NAND read"); - - destroy_reg_param(®_params[0]); - destroy_reg_param(®_params[1]); - destroy_reg_param(®_params[2]); - - /* read from work area to the host's memory */ - retval = target_read_buffer(target, target_buf, size, data); - - return retval; -} diff --git a/src/flash/nand/arm_io.h b/src/flash/nand/arm_io.h deleted file mode 100644 index 8bb311458..000000000 --- a/src/flash/nand/arm_io.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (C) 2009 by David Brownell - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -#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. - */ -enum arm_nand_op { - ARM_NAND_NONE, /**< No operation performed. */ - ARM_NAND_READ, /**< Read operation performed. */ - ARM_NAND_WRITE, /**< Write operation performed. */ -}; - -/** - * The arm_nand_data struct is used for defining NAND I/O operations on an ARM - * core. - */ -struct arm_nand_data { - /** Target is proxy for some ARM core. */ - struct target *target; - - /** The copy area holds code loop and data for I/O operations. */ - struct working_area *copy_area; - - /** The chunk size is the page size or ECC chunk. */ - unsigned chunk_size; - - /** Where data is read from or written to. */ - uint32_t data; - - /** Last operation executed using this struct. */ - enum arm_nand_op op; - - /* currently implicit: data width == 8 bits (not 16) */ -}; - -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 /* OPENOCD_FLASH_NAND_ARM_IO_H */ diff --git a/src/flash/nand/at91sam9.c b/src/flash/nand/at91sam9.c deleted file mode 100644 index 0af12b20c..000000000 --- a/src/flash/nand/at91sam9.c +++ /dev/null @@ -1,722 +0,0 @@ -/* - * Copyright (C) 2009 by Dean Glazeski - * dnglaze@gmail.com - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include "imp.h" -#include "arm_io.h" - -#define AT91C_PIOx_SODR (0x30) /**< Offset to PIO SODR. */ -#define AT91C_PIOx_CODR (0x34) /**< Offset to PIO CODR. */ -#define AT91C_PIOx_PDSR (0x3C) /**< Offset to PIO PDSR. */ -#define AT91C_ECCx_CR (0x00) /**< Offset to ECC CR. */ -#define AT91C_ECCx_SR (0x08) /**< Offset to ECC SR. */ -#define AT91C_ECCx_PR (0x0C) /**< Offset to ECC PR. */ -#define AT91C_ECCx_NPR (0x10) /**< Offset to ECC NPR. */ - -/** - * Representation of a pin on an AT91SAM9 chip. - */ -struct at91sam9_pin { - /** Address of the PIO controller. */ - uint32_t pioc; - - /** Pin number. */ - uint32_t num; -}; - -/** - * Private data for the controller that is stored in the NAND device structure. - */ -struct at91sam9_nand { - /** Address of the ECC controller for NAND. */ - uint32_t ecc; - - /** Address data is written to. */ - uint32_t data; - - /** Address commands are written to. */ - uint32_t cmd; - - /** Address addresses are written to. */ - uint32_t addr; - - /** I/O structure for hosted reads/writes. */ - struct arm_nand_data io; - - /** Pin representing the ready/~busy line. */ - struct at91sam9_pin busy; - - /** Pin representing the chip enable. */ - struct at91sam9_pin ce; -}; - -/** - * Checks if the target is halted and prints an error message if it isn't. - * - * @param target Target to be checked. - * @param label String label for where function is called from. - * @return True if the target is halted. - */ -static int at91sam9_halted(struct target *target, const char *label) -{ - if (target->state == TARGET_HALTED) - return true; - - LOG_ERROR("Target must be halted to use NAND controller (%s)", label); - return false; -} - -/** - * Initialize the AT91SAM9 NAND controller. - * - * @param nand NAND device the controller is attached to. - * @return Success or failure of initialization. - */ -static int at91sam9_init(struct nand_device *nand) -{ - struct target *target = nand->target; - - if (!at91sam9_halted(target, "init")) - return ERROR_NAND_OPERATION_FAILED; - - return ERROR_OK; -} - -/** - * Enable NAND device attached to a controller. - * - * @param info NAND controller information for controlling NAND device. - * @return Success or failure of the enabling. - */ -static int at91sam9_enable(struct nand_device *nand) -{ - struct at91sam9_nand *info = nand->controller_priv; - struct target *target = nand->target; - - return target_write_u32(target, info->ce.pioc + AT91C_PIOx_CODR, 1 << info->ce.num); -} - -/** - * Disable NAND device attached to a controller. - * - * @param info NAND controller information for controlling NAND device. - * @return Success or failure of the disabling. - */ -static int at91sam9_disable(struct nand_device *nand) -{ - struct at91sam9_nand *info = nand->controller_priv; - struct target *target = nand->target; - - return target_write_u32(target, info->ce.pioc + AT91C_PIOx_SODR, 1 << info->ce.num); -} - -/** - * Send a command to the NAND device. - * - * @param nand NAND device to write the command to. - * @param command Command to be written. - * @return Success or failure of writing the command. - */ -static int at91sam9_command(struct nand_device *nand, uint8_t command) -{ - struct at91sam9_nand *info = nand->controller_priv; - struct target *target = nand->target; - - if (!at91sam9_halted(target, "command")) - return ERROR_NAND_OPERATION_FAILED; - - at91sam9_enable(nand); - - return target_write_u8(target, info->cmd, command); -} - -/** - * Reset the AT91SAM9 NAND controller. - * - * @param nand NAND device to be reset. - * @return Success or failure of reset. - */ -static int at91sam9_reset(struct nand_device *nand) -{ - if (!at91sam9_halted(nand->target, "reset")) - return ERROR_NAND_OPERATION_FAILED; - - return at91sam9_disable(nand); -} - -/** - * Send an address to the NAND device attached to an AT91SAM9 NAND controller. - * - * @param nand NAND device to send the address to. - * @param address Address to be sent. - * @return Success or failure of sending the address. - */ -static int at91sam9_address(struct nand_device *nand, uint8_t address) -{ - struct at91sam9_nand *info = nand->controller_priv; - struct target *target = nand->target; - - if (!at91sam9_halted(nand->target, "address")) - return ERROR_NAND_OPERATION_FAILED; - - return target_write_u8(target, info->addr, address); -} - -/** - * Read data directly from the NAND device attached to an AT91SAM9 NAND - * controller. - * - * @param nand NAND device to read from. - * @param data Pointer to where the data should be put. - * @return Success or failure of reading the data. - */ -static int at91sam9_read_data(struct nand_device *nand, void *data) -{ - struct at91sam9_nand *info = nand->controller_priv; - struct target *target = nand->target; - - if (!at91sam9_halted(nand->target, "read data")) - return ERROR_NAND_OPERATION_FAILED; - - return target_read_u8(target, info->data, data); -} - -/** - * Write data directly to the NAND device attached to an AT91SAM9 NAND - * controller. - * - * @param nand NAND device to be written to. - * @param data Data to be written. - * @return Success or failure of the data write. - */ -static int at91sam9_write_data(struct nand_device *nand, uint16_t data) -{ - struct at91sam9_nand *info = nand->controller_priv; - struct target *target = nand->target; - - if (!at91sam9_halted(target, "write data")) - return ERROR_NAND_OPERATION_FAILED; - - return target_write_u8(target, info->data, data); -} - -/** - * Determine if the NAND device is ready by looking at the ready/~busy pin. - * - * @param nand NAND device to check. - * @param timeout Time in milliseconds to wait for NAND to be ready. - * @return True if the NAND is ready in the timeout period. - */ -static int at91sam9_nand_ready(struct nand_device *nand, int timeout) -{ - struct at91sam9_nand *info = nand->controller_priv; - struct target *target = nand->target; - uint32_t status; - - if (!at91sam9_halted(target, "nand ready")) - return 0; - - do { - target_read_u32(target, info->busy.pioc + AT91C_PIOx_PDSR, &status); - - if (status & (1 << info->busy.num)) - return 1; - - alive_sleep(1); - } while (timeout-- > 0); - - return 0; -} - -/** - * Read a block of data from the NAND device attached to an AT91SAM9. This - * utilizes the ARM hosted NAND read function. - * - * @param nand NAND device to read from. - * @param data Pointer to where the read data should be placed. - * @param size Size of the data being read. - * @return Success or failure of the hosted read. - */ -static int at91sam9_read_block_data(struct nand_device *nand, uint8_t *data, int size) -{ - struct at91sam9_nand *info = nand->controller_priv; - struct arm_nand_data *io = &info->io; - int status; - - if (!at91sam9_halted(nand->target, "read block")) - return ERROR_NAND_OPERATION_FAILED; - - io->chunk_size = nand->page_size; - status = arm_nandread(io, data, size); - - return status; -} - -/** - * Write a block of data to a NAND device attached to an AT91SAM9. This uses - * the ARM hosted write function to write the data. - * - * @param nand NAND device to write to. - * @param data Data to be written to device. - * @param size Size of the data being written. - * @return Success or failure of the hosted write. - */ -static int at91sam9_write_block_data(struct nand_device *nand, uint8_t *data, int size) -{ - struct at91sam9_nand *info = nand->controller_priv; - struct arm_nand_data *io = &info->io; - int status; - - if (!at91sam9_halted(nand->target, "write block")) - return ERROR_NAND_OPERATION_FAILED; - - io->chunk_size = nand->page_size; - status = arm_nandwrite(io, data, size); - - return status; -} - -/** - * Initialize the ECC controller on the AT91SAM9. - * - * @param target Target to configure ECC on. - * @param info NAND controller information for where the ECC is. - * @return Success or failure of initialization. - */ -static int at91sam9_ecc_init(struct target *target, struct at91sam9_nand *info) -{ - if (!info->ecc) { - LOG_ERROR("ECC controller address must be set when not reading raw NAND data"); - return ERROR_NAND_OPERATION_FAILED; - } - - /* reset ECC parity registers */ - return target_write_u32(target, info->ecc + AT91C_ECCx_CR, 1); -} - -/** - * Initialize an area for the OOB based on whether a user is requesting the OOB - * data. This determines the size of the OOB and allocates the space in case - * the user has not requested the OOB data. - * - * @param nand NAND device we are creating an OOB for. - * @param oob Pointer to the user supplied OOB area. - * @param size Size of the OOB. - * @return Pointer to an area to store OOB data. - */ -static uint8_t *at91sam9_oob_init(struct nand_device *nand, uint8_t *oob, uint32_t *size) -{ - if (!oob) { - /* user doesn't want OOB, allocate it */ - if (nand->page_size == 512) - *size = 16; - else if (nand->page_size == 2048) - *size = 64; - - oob = malloc(*size); - if (!oob) { - LOG_ERROR("Unable to allocate space for OOB"); - return NULL; - } - - memset(oob, 0xFF, *size); - } - - return oob; -} - -/** - * Reads a page from an AT91SAM9 NAND controller and verifies using 1-bit ECC - * controller on chip. This makes an attempt to correct any errors that are - * encountered while reading the page of data. - * - * @param nand NAND device to read from - * @param page Page to be read. - * @param data Pointer to where data should be read to. - * @param data_size Size of the data to be read. - * @param oob Pointer to where OOB data should be read to. - * @param oob_size Size of the OOB data to be read. - * @return Success or failure of reading the NAND page. - */ -static int at91sam9_read_page(struct nand_device *nand, uint32_t page, - uint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size) -{ - int retval; - struct at91sam9_nand *info = nand->controller_priv; - struct target *target = nand->target; - uint8_t *oob_data; - uint32_t status; - - retval = at91sam9_ecc_init(target, info); - if (ERROR_OK != retval) - return retval; - - retval = nand_page_command(nand, page, NAND_CMD_READ0, !data); - if (ERROR_OK != retval) - return retval; - - if (data) { - retval = nand_read_data_page(nand, data, data_size); - if (ERROR_OK != retval) - return retval; - } - - oob_data = at91sam9_oob_init(nand, oob, &oob_size); - retval = nand_read_data_page(nand, oob_data, oob_size); - if (ERROR_OK == retval && data) { - target_read_u32(target, info->ecc + AT91C_ECCx_SR, &status); - if (status & 1) { - LOG_ERROR("Error detected!"); - if (status & 4) - LOG_ERROR("Multiple errors encountered; unrecoverable!"); - else { - /* attempt recovery */ - uint32_t parity; - - target_read_u32(target, - info->ecc + AT91C_ECCx_PR, - &parity); - uint32_t word = (parity & 0x0000FFF0) >> 4; - uint32_t bit = parity & 0x0F; - - data[word] ^= (0x1) << bit; - LOG_INFO("Data word %d, bit %d corrected.", - (unsigned) word, - (unsigned) bit); - } - } - - if (status & 2) { - /* we could write back correct ECC data */ - LOG_ERROR("Error in ECC bytes detected"); - } - } - - if (!oob) { - /* if it wasn't asked for, free it */ - free(oob_data); - } - - return retval; -} - -/** - * Write a page of data including 1-bit ECC information to a NAND device - * attached to an AT91SAM9 controller. If there is OOB data to be written, - * this will ignore the computed ECC from the ECC controller. - * - * @param nand NAND device to write to. - * @param page Page to write. - * @param data Pointer to data being written. - * @param data_size Size of the data being written. - * @param oob Pointer to OOB data being written. - * @param oob_size Size of the OOB data. - * @return Success or failure of the page write. - */ -static int at91sam9_write_page(struct nand_device *nand, uint32_t page, - uint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size) -{ - struct at91sam9_nand *info = nand->controller_priv; - struct target *target = nand->target; - int retval; - uint8_t *oob_data = oob; - uint32_t parity, nparity; - - retval = at91sam9_ecc_init(target, info); - if (ERROR_OK != retval) - return retval; - - retval = nand_page_command(nand, page, NAND_CMD_SEQIN, !data); - if (ERROR_OK != retval) - return retval; - - if (data) { - retval = nand_write_data_page(nand, data, data_size); - if (ERROR_OK != retval) { - LOG_ERROR("Unable to write data to NAND device"); - return retval; - } - } - - oob_data = at91sam9_oob_init(nand, oob, &oob_size); - - if (!oob) { - /* no OOB given, so read in the ECC parity from the ECC controller */ - target_read_u32(target, info->ecc + AT91C_ECCx_PR, &parity); - target_read_u32(target, info->ecc + AT91C_ECCx_NPR, &nparity); - - oob_data[0] = (uint8_t) parity; - oob_data[1] = (uint8_t) (parity >> 8); - oob_data[2] = (uint8_t) nparity; - oob_data[3] = (uint8_t) (nparity >> 8); - } - - retval = nand_write_data_page(nand, oob_data, oob_size); - - if (!oob) - free(oob_data); - - if (ERROR_OK != retval) { - LOG_ERROR("Unable to write OOB data to NAND"); - return retval; - } - - retval = nand_write_finish(nand); - - return retval; -} - -/** - * Handle the initial NAND device command for AT91SAM9 controllers. This - * initializes much of the controller information struct to be ready for future - * reads and writes. - */ -NAND_DEVICE_COMMAND_HANDLER(at91sam9_nand_device_command) -{ - unsigned long chip = 0, ecc = 0; - struct at91sam9_nand *info = NULL; - - LOG_DEBUG("AT91SAM9 NAND Device Command"); - - if (CMD_ARGC < 3 || CMD_ARGC > 4) { - LOG_ERROR("parameters: %s target chip_addr", CMD_ARGV[0]); - return ERROR_NAND_OPERATION_FAILED; - } - - COMMAND_PARSE_NUMBER(ulong, CMD_ARGV[2], chip); - if (chip == 0) { - LOG_ERROR("invalid NAND chip address: %s", CMD_ARGV[2]); - return ERROR_NAND_OPERATION_FAILED; - } - - if (CMD_ARGC == 4) { - COMMAND_PARSE_NUMBER(ulong, CMD_ARGV[3], ecc); - if (ecc == 0) { - LOG_ERROR("invalid ECC controller address: %s", CMD_ARGV[3]); - return ERROR_NAND_OPERATION_FAILED; - } - } - - info = calloc(1, sizeof(*info)); - if (!info) { - LOG_ERROR("unable to allocate space for controller private data"); - return ERROR_NAND_OPERATION_FAILED; - } - - info->data = chip; - info->cmd = chip | (1 << 22); - info->addr = chip | (1 << 21); - info->ecc = ecc; - - nand->controller_priv = info; - info->io.target = nand->target; - info->io.data = info->data; - info->io.op = ARM_NAND_NONE; - - return ERROR_OK; -} - -/** - * Handle the AT91SAM9 CLE command for specifying the address line to use for - * writing commands to a NAND device. - */ -COMMAND_HANDLER(handle_at91sam9_cle_command) -{ - struct nand_device *nand = NULL; - struct at91sam9_nand *info = NULL; - unsigned num, address_line; - - if (CMD_ARGC != 2) { - command_print(CMD_CTX, "incorrect number of arguments for 'at91sam9 cle' command"); - return ERROR_OK; - } - - COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], num); - nand = get_nand_device_by_num(num); - if (!nand) { - command_print(CMD_CTX, "invalid nand device number: %s", CMD_ARGV[0]); - return ERROR_OK; - } - - info = nand->controller_priv; - - COMMAND_PARSE_NUMBER(uint, CMD_ARGV[1], address_line); - info->cmd = info->data | (1 << address_line); - - return ERROR_OK; -} - -/** - * Handle the AT91SAM9 ALE command for specifying the address line to use for - * writing addresses to the NAND device. - */ -COMMAND_HANDLER(handle_at91sam9_ale_command) -{ - struct nand_device *nand = NULL; - struct at91sam9_nand *info = NULL; - unsigned num, address_line; - - if (CMD_ARGC != 2) - return ERROR_COMMAND_SYNTAX_ERROR; - - COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], num); - nand = get_nand_device_by_num(num); - if (!nand) { - command_print(CMD_CTX, "invalid nand device number: %s", CMD_ARGV[0]); - return ERROR_COMMAND_ARGUMENT_INVALID; - } - - info = nand->controller_priv; - - COMMAND_PARSE_NUMBER(uint, CMD_ARGV[1], address_line); - info->addr = info->data | (1 << address_line); - - return ERROR_OK; -} - -/** - * Handle the AT91SAM9 RDY/~BUSY command for specifying the pin that watches the - * RDY/~BUSY line from the NAND device. - */ -COMMAND_HANDLER(handle_at91sam9_rdy_busy_command) -{ - struct nand_device *nand = NULL; - struct at91sam9_nand *info = NULL; - unsigned num, base_pioc, pin_num; - - if (CMD_ARGC != 3) - return ERROR_COMMAND_SYNTAX_ERROR; - - COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], num); - nand = get_nand_device_by_num(num); - if (!nand) { - command_print(CMD_CTX, "invalid nand device number: %s", CMD_ARGV[0]); - return ERROR_COMMAND_ARGUMENT_INVALID; - } - - info = nand->controller_priv; - - COMMAND_PARSE_NUMBER(uint, CMD_ARGV[1], base_pioc); - info->busy.pioc = base_pioc; - - COMMAND_PARSE_NUMBER(uint, CMD_ARGV[2], pin_num); - info->busy.num = pin_num; - - return ERROR_OK; -} - -/** - * Handle the AT91SAM9 CE command for specifying the pin that is used to enable - * or disable the NAND device. - */ -COMMAND_HANDLER(handle_at91sam9_ce_command) -{ - struct nand_device *nand = NULL; - struct at91sam9_nand *info = NULL; - unsigned num, base_pioc, pin_num; - - if (CMD_ARGC != 3) - return ERROR_COMMAND_SYNTAX_ERROR; - - COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], num); - nand = get_nand_device_by_num(num); - if (!nand) { - command_print(CMD_CTX, "invalid nand device number: %s", CMD_ARGV[0]); - return ERROR_COMMAND_ARGUMENT_INVALID; - } - - info = nand->controller_priv; - - COMMAND_PARSE_NUMBER(uint, CMD_ARGV[1], base_pioc); - info->ce.pioc = base_pioc; - - COMMAND_PARSE_NUMBER(uint, CMD_ARGV[2], pin_num); - info->ce.num = pin_num; - - return ERROR_OK; -} - -static const struct command_registration at91sam9_sub_command_handlers[] = { - { - .name = "cle", - .handler = handle_at91sam9_cle_command, - .mode = COMMAND_CONFIG, - .help = "set command latch enable address line (default is 22)", - .usage = "bank_id address_line", - }, - { - .name = "ale", - .handler = handle_at91sam9_ale_command, - .mode = COMMAND_CONFIG, - .help = "set address latch enable address line (default is 21)", - .usage = "bank_id address_line", - }, - { - .name = "rdy_busy", - .handler = handle_at91sam9_rdy_busy_command, - .mode = COMMAND_CONFIG, - .help = "set the GPIO input pin connected to " - "the RDY/~BUSY signal (no default)", - .usage = "bank_id pio_base_addr pin_num", - }, - { - .name = "ce", - .handler = handle_at91sam9_ce_command, - .mode = COMMAND_CONFIG, - .help = "set the GPIO output pin connected to " - "the chip enable signal (no default)", - .usage = "bank_id pio_base_addr pin_num", - }, - COMMAND_REGISTRATION_DONE -}; - -static const struct command_registration at91sam9_command_handler[] = { - { - .name = "at91sam9", - .mode = COMMAND_ANY, - .help = "AT91SAM9 NAND flash controller commands", - .usage = "", - .chain = at91sam9_sub_command_handlers, - }, - COMMAND_REGISTRATION_DONE -}; - -/** - * Structure representing the AT91SAM9 NAND controller. - */ -struct nand_flash_controller at91sam9_nand_controller = { - .name = "at91sam9", - .nand_device_command = at91sam9_nand_device_command, - .commands = at91sam9_command_handler, - .init = at91sam9_init, - .command = at91sam9_command, - .reset = at91sam9_reset, - .address = at91sam9_address, - .read_data = at91sam9_read_data, - .write_data = at91sam9_write_data, - .nand_ready = at91sam9_nand_ready, - .read_block_data = at91sam9_read_block_data, - .write_block_data = at91sam9_write_block_data, - .read_page = at91sam9_read_page, - .write_page = at91sam9_write_page, -}; diff --git a/src/flash/nand/core.c b/src/flash/nand/core.c deleted file mode 100644 index 7428d2253..000000000 --- a/src/flash/nand/core.c +++ /dev/null @@ -1,876 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Dominic Rath * - * Copyright (C) 2002 Thomas Gleixner * - * Copyright (C) 2009 Zachary T Welch * - * * - * Partially based on drivers/mtd/nand_ids.c from Linux. * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "imp.h" - -/* configured NAND devices and NAND Flash command handler */ -struct nand_device *nand_devices; - -void nand_device_add(struct nand_device *c) -{ - if (nand_devices) { - struct nand_device *p = nand_devices; - while (p && p->next) - p = p->next; - p->next = c; - } else - nand_devices = c; -} - - -/* Chip ID list - * - * Manufacturer, ID code, pagesize, chipsize in MegaByte, eraseblock size, - * options, name - * - * Pagesize; 0, 256, 512 - * 0 get this information from the extended chip ID - * 256 256 Byte page size - * 512 512 Byte page size - */ -static struct nand_info nand_flash_ids[] = { - /* Vendor Specific Entries */ - { NAND_MFR_SAMSUNG, 0xD5, 8192, 2048, 0x100000, LP_OPTIONS, - "K9GAG08 2GB NAND 3.3V x8 MLC 2b/cell"}, - { NAND_MFR_SAMSUNG, 0xD7, 8192, 4096, 0x100000, LP_OPTIONS, - "K9LBG08 4GB NAND 3.3V x8 MLC 2b/cell"}, - - /* start "museum" IDs */ - { 0x0, 0x6e, 256, 1, 0x1000, 0, "NAND 1MiB 5V 8-bit"}, - { 0x0, 0x64, 256, 2, 0x1000, 0, "NAND 2MiB 5V 8-bit"}, - { 0x0, 0x6b, 512, 4, 0x2000, 0, "NAND 4MiB 5V 8-bit"}, - { 0x0, 0xe8, 256, 1, 0x1000, 0, "NAND 1MiB 3.3V 8-bit"}, - { 0x0, 0xec, 256, 1, 0x1000, 0, "NAND 1MiB 3.3V 8-bit"}, - { 0x0, 0xea, 256, 2, 0x1000, 0, "NAND 2MiB 3.3V 8-bit"}, - { 0x0, 0xd5, 512, 4, 0x2000, 0, "NAND 4MiB 3.3V 8-bit"}, - { 0x0, 0xe3, 512, 4, 0x2000, 0, "NAND 4MiB 3.3V 8-bit"}, - { 0x0, 0xe5, 512, 4, 0x2000, 0, "NAND 4MiB 3.3V 8-bit"}, - { 0x0, 0xd6, 512, 8, 0x2000, 0, "NAND 8MiB 3.3V 8-bit"}, - - { 0x0, 0x39, 512, 8, 0x2000, 0, "NAND 8MiB 1.8V 8-bit"}, - { 0x0, 0xe6, 512, 8, 0x2000, 0, "NAND 8MiB 3.3V 8-bit"}, - { 0x0, 0x49, 512, 8, 0x2000, NAND_BUSWIDTH_16, "NAND 8MiB 1.8V 16-bit"}, - { 0x0, 0x59, 512, 8, 0x2000, NAND_BUSWIDTH_16, "NAND 8MiB 3.3V 16-bit"}, - /* end "museum" IDs */ - - { 0x0, 0x33, 512, 16, 0x4000, 0, "NAND 16MiB 1.8V 8-bit"}, - { 0x0, 0x73, 512, 16, 0x4000, 0, "NAND 16MiB 3.3V 8-bit"}, - { 0x0, 0x43, 512, 16, 0x4000, NAND_BUSWIDTH_16, "NAND 16MiB 1.8V 16-bit"}, - { 0x0, 0x53, 512, 16, 0x4000, NAND_BUSWIDTH_16, "NAND 16MiB 3.3V 16-bit"}, - - { 0x0, 0x35, 512, 32, 0x4000, 0, "NAND 32MiB 1.8V 8-bit"}, - { 0x0, 0x75, 512, 32, 0x4000, 0, "NAND 32MiB 3.3V 8-bit"}, - { 0x0, 0x45, 512, 32, 0x4000, NAND_BUSWIDTH_16, "NAND 32MiB 1.8V 16-bit"}, - { 0x0, 0x55, 512, 32, 0x4000, NAND_BUSWIDTH_16, "NAND 32MiB 3.3V 16-bit"}, - - { 0x0, 0x36, 512, 64, 0x4000, 0, "NAND 64MiB 1.8V 8-bit"}, - { 0x0, 0x76, 512, 64, 0x4000, 0, "NAND 64MiB 3.3V 8-bit"}, - { 0x0, 0x46, 512, 64, 0x4000, NAND_BUSWIDTH_16, "NAND 64MiB 1.8V 16-bit"}, - { 0x0, 0x56, 512, 64, 0x4000, NAND_BUSWIDTH_16, "NAND 64MiB 3.3V 16-bit"}, - - { 0x0, 0x78, 512, 128, 0x4000, 0, "NAND 128MiB 1.8V 8-bit"}, - { 0x0, 0x39, 512, 128, 0x4000, 0, "NAND 128MiB 1.8V 8-bit"}, - { 0x0, 0x79, 512, 128, 0x4000, 0, "NAND 128MiB 3.3V 8-bit"}, - { 0x0, 0x72, 512, 128, 0x4000, NAND_BUSWIDTH_16, "NAND 128MiB 1.8V 16-bit"}, - { 0x0, 0x49, 512, 128, 0x4000, NAND_BUSWIDTH_16, "NAND 128MiB 1.8V 16-bit"}, - { 0x0, 0x74, 512, 128, 0x4000, NAND_BUSWIDTH_16, "NAND 128MiB 3.3V 16-bit"}, - { 0x0, 0x59, 512, 128, 0x4000, NAND_BUSWIDTH_16, "NAND 128MiB 3.3V 16-bit"}, - - { 0x0, 0x71, 512, 256, 0x4000, 0, "NAND 256MiB 3.3V 8-bit"}, - - { 0x0, 0xA2, 0, 64, 0, LP_OPTIONS, "NAND 64MiB 1.8V 8-bit"}, - { 0x0, 0xF2, 0, 64, 0, LP_OPTIONS, "NAND 64MiB 3.3V 8-bit"}, - { 0x0, 0xB2, 0, 64, 0, LP_OPTIONS16, "NAND 64MiB 1.8V 16-bit"}, - { 0x0, 0xC2, 0, 64, 0, LP_OPTIONS16, "NAND 64MiB 3.3V 16-bit"}, - - { 0x0, 0xA1, 0, 128, 0, LP_OPTIONS, "NAND 128MiB 1.8V 8-bit"}, - { 0x0, 0xF1, 0, 128, 0, LP_OPTIONS, "NAND 128MiB 3.3V 8-bit"}, - { 0x0, 0xB1, 0, 128, 0, LP_OPTIONS16, "NAND 128MiB 1.8V 16-bit"}, - { 0x0, 0xC1, 0, 128, 0, LP_OPTIONS16, "NAND 128MiB 3.3V 16-bit"}, - - { 0x0, 0xAA, 0, 256, 0, LP_OPTIONS, "NAND 256MiB 1.8V 8-bit"}, - { 0x0, 0xDA, 0, 256, 0, LP_OPTIONS, "NAND 256MiB 3.3V 8-bit"}, - { 0x0, 0xBA, 0, 256, 0, LP_OPTIONS16, "NAND 256MiB 1.8V 16-bit"}, - { 0x0, 0xCA, 0, 256, 0, LP_OPTIONS16, "NAND 256MiB 3.3V 16-bit"}, - - { 0x0, 0xAC, 0, 512, 0, LP_OPTIONS, "NAND 512MiB 1.8V 8-bit"}, - { 0x0, 0xDC, 0, 512, 0, LP_OPTIONS, "NAND 512MiB 3.3V 8-bit"}, - { 0x0, 0xBC, 0, 512, 0, LP_OPTIONS16, "NAND 512MiB 1.8V 16-bit"}, - { 0x0, 0xCC, 0, 512, 0, LP_OPTIONS16, "NAND 512MiB 3.3V 16-bit"}, - - { 0x0, 0xA3, 0, 1024, 0, LP_OPTIONS, "NAND 1GiB 1.8V 8-bit"}, - { 0x0, 0xD3, 0, 1024, 0, LP_OPTIONS, "NAND 1GiB 3.3V 8-bit"}, - { 0x0, 0xB3, 0, 1024, 0, LP_OPTIONS16, "NAND 1GiB 1.8V 16-bit"}, - { 0x0, 0xC3, 0, 1024, 0, LP_OPTIONS16, "NAND 1GiB 3.3V 16-bit"}, - - { 0x0, 0xA5, 0, 2048, 0, LP_OPTIONS, "NAND 2GiB 1.8V 8-bit"}, - { 0x0, 0xD5, 0, 8192, 0, LP_OPTIONS, "NAND 2GiB 3.3V 8-bit"}, - { 0x0, 0xB5, 0, 2048, 0, LP_OPTIONS16, "NAND 2GiB 1.8V 16-bit"}, - { 0x0, 0xC5, 0, 2048, 0, LP_OPTIONS16, "NAND 2GiB 3.3V 16-bit"}, - - { 0x0, 0x48, 0, 2048, 0, LP_OPTIONS, "NAND 2GiB 3.3V 8-bit"}, - - {0, 0, 0, 0, 0, 0, NULL} -}; - -/* Manufacturer ID list - */ -static struct nand_manufacturer nand_manuf_ids[] = { - {0x0, "unknown"}, - {NAND_MFR_TOSHIBA, "Toshiba"}, - {NAND_MFR_SAMSUNG, "Samsung"}, - {NAND_MFR_FUJITSU, "Fujitsu"}, - {NAND_MFR_NATIONAL, "National"}, - {NAND_MFR_RENESAS, "Renesas"}, - {NAND_MFR_STMICRO, "ST Micro"}, - {NAND_MFR_HYNIX, "Hynix"}, - {NAND_MFR_MICRON, "Micron"}, - {0x0, NULL}, -}; - -/* - * Define default oob placement schemes for large and small page devices - */ - -#if 0 -static struct nand_ecclayout nand_oob_8 = { - .eccbytes = 3, - .eccpos = {0, 1, 2}, - .oobfree = { - {.offset = 3, - .length = 2}, - {.offset = 6, - .length = 2} - } -}; -#endif - -/** - * Returns the flash bank specified by @a name, which matches the - * driver name and a suffix (option) specify the driver-specific - * bank number. The suffix consists of the '.' and the driver-specific - * bank number: when two davinci banks are defined, then 'davinci.1' refers - * to the second (e.g. DM355EVM). - */ -static struct nand_device *get_nand_device_by_name(const char *name) -{ - unsigned requested = get_flash_name_index(name); - unsigned found = 0; - - struct nand_device *nand; - for (nand = nand_devices; NULL != nand; nand = nand->next) { - if (strcmp(nand->name, name) == 0) - return nand; - if (!flash_driver_name_matches(nand->controller->name, name)) - continue; - if (++found < requested) - continue; - return nand; - } - return NULL; -} - -struct nand_device *get_nand_device_by_num(int num) -{ - struct nand_device *p; - int i = 0; - - for (p = nand_devices; p; p = p->next) { - if (i++ == num) - return p; - } - - return NULL; -} - -COMMAND_HELPER(nand_command_get_device, unsigned name_index, - struct nand_device **nand) -{ - const char *str = CMD_ARGV[name_index]; - *nand = get_nand_device_by_name(str); - if (*nand) - return ERROR_OK; - - unsigned num; - COMMAND_PARSE_NUMBER(uint, str, num); - *nand = get_nand_device_by_num(num); - if (!*nand) { - command_print(CMD_CTX, "NAND flash device '%s' not found", str); - return ERROR_COMMAND_SYNTAX_ERROR; - } - return ERROR_OK; -} - -int nand_build_bbt(struct nand_device *nand, int first, int last) -{ - uint32_t page; - int i; - int pages_per_block = (nand->erase_size / nand->page_size); - uint8_t oob[6]; - int ret; - - if ((first < 0) || (first >= nand->num_blocks)) - first = 0; - - if ((last >= nand->num_blocks) || (last == -1)) - last = nand->num_blocks - 1; - - page = first * pages_per_block; - for (i = first; i <= last; i++) { - ret = nand_read_page(nand, page, NULL, 0, oob, 6); - if (ret != ERROR_OK) - return ret; - - if (((nand->device->options & NAND_BUSWIDTH_16) && ((oob[0] & oob[1]) != 0xff)) - || (((nand->page_size == 512) && (oob[5] != 0xff)) || - ((nand->page_size == 2048) && (oob[0] != 0xff)))) { - LOG_WARNING("bad block: %i", i); - nand->blocks[i].is_bad = 1; - } else - nand->blocks[i].is_bad = 0; - - page += pages_per_block; - } - - return ERROR_OK; -} - -int nand_read_status(struct nand_device *nand, uint8_t *status) -{ - if (!nand->device) - return ERROR_NAND_DEVICE_NOT_PROBED; - - /* Send read status command */ - nand->controller->command(nand, NAND_CMD_STATUS); - - alive_sleep(1); - - /* read status */ - if (nand->device->options & NAND_BUSWIDTH_16) { - uint16_t data; - nand->controller->read_data(nand, &data); - *status = data & 0xff; - } else - nand->controller->read_data(nand, status); - - return ERROR_OK; -} - -static int nand_poll_ready(struct nand_device *nand, int timeout) -{ - uint8_t status; - - nand->controller->command(nand, NAND_CMD_STATUS); - do { - if (nand->device->options & NAND_BUSWIDTH_16) { - uint16_t data; - nand->controller->read_data(nand, &data); - status = data & 0xff; - } else - nand->controller->read_data(nand, &status); - if (status & NAND_STATUS_READY) - break; - alive_sleep(1); - } while (timeout--); - - return (status & NAND_STATUS_READY) != 0; -} - -int nand_probe(struct nand_device *nand) -{ - uint8_t manufacturer_id, device_id; - uint8_t id_buff[6]; - int retval; - int i; - - /* clear device data */ - nand->device = NULL; - nand->manufacturer = NULL; - - /* clear device parameters */ - nand->bus_width = 0; - nand->address_cycles = 0; - nand->page_size = 0; - nand->erase_size = 0; - - /* initialize controller (device parameters are zero, use controller default) */ - retval = nand->controller->init(nand); - if (retval != ERROR_OK) { - switch (retval) { - case ERROR_NAND_OPERATION_FAILED: - LOG_DEBUG("controller initialization failed"); - return ERROR_NAND_OPERATION_FAILED; - case ERROR_NAND_OPERATION_NOT_SUPPORTED: - LOG_ERROR( - "BUG: controller reported that it doesn't support default parameters"); - return ERROR_NAND_OPERATION_FAILED; - default: - LOG_ERROR("BUG: unknown controller initialization failure"); - return ERROR_NAND_OPERATION_FAILED; - } - } - - nand->controller->command(nand, NAND_CMD_RESET); - nand->controller->reset(nand); - - nand->controller->command(nand, NAND_CMD_READID); - nand->controller->address(nand, 0x0); - - if (nand->bus_width == 8) { - nand->controller->read_data(nand, &manufacturer_id); - nand->controller->read_data(nand, &device_id); - } else { - uint16_t data_buf; - nand->controller->read_data(nand, &data_buf); - manufacturer_id = data_buf & 0xff; - nand->controller->read_data(nand, &data_buf); - device_id = data_buf & 0xff; - } - - for (i = 0; nand_flash_ids[i].name; i++) { - if (nand_flash_ids[i].id == device_id && - (nand_flash_ids[i].mfr_id == manufacturer_id || - nand_flash_ids[i].mfr_id == 0)) { - nand->device = &nand_flash_ids[i]; - break; - } - } - - for (i = 0; nand_manuf_ids[i].name; i++) { - if (nand_manuf_ids[i].id == manufacturer_id) { - nand->manufacturer = &nand_manuf_ids[i]; - break; - } - } - - if (!nand->manufacturer) { - nand->manufacturer = &nand_manuf_ids[0]; - nand->manufacturer->id = manufacturer_id; - } - - if (!nand->device) { - LOG_ERROR( - "unknown NAND flash device found, manufacturer id: 0x%2.2x device id: 0x%2.2x", - manufacturer_id, - device_id); - return ERROR_NAND_OPERATION_FAILED; - } - - LOG_DEBUG("found %s (%s)", nand->device->name, nand->manufacturer->name); - - /* initialize device parameters */ - - /* bus width */ - if (nand->device->options & NAND_BUSWIDTH_16) - nand->bus_width = 16; - else - nand->bus_width = 8; - - /* Do we need extended device probe information? */ - if (nand->device->page_size == 0 || - nand->device->erase_size == 0) { - if (nand->bus_width == 8) { - nand->controller->read_data(nand, id_buff + 3); - nand->controller->read_data(nand, id_buff + 4); - nand->controller->read_data(nand, id_buff + 5); - } else { - uint16_t data_buf; - - nand->controller->read_data(nand, &data_buf); - id_buff[3] = data_buf; - - nand->controller->read_data(nand, &data_buf); - id_buff[4] = data_buf; - - nand->controller->read_data(nand, &data_buf); - id_buff[5] = data_buf >> 8; - } - } - - /* page size */ - if (nand->device->page_size == 0) - nand->page_size = 1 << (10 + (id_buff[4] & 3)); - else if (nand->device->page_size == 256) { - LOG_ERROR("NAND flashes with 256 byte pagesize are not supported"); - return ERROR_NAND_OPERATION_FAILED; - } else - nand->page_size = nand->device->page_size; - - /* number of address cycles */ - if (nand->page_size <= 512) { - /* small page devices */ - if (nand->device->chip_size <= 32) - nand->address_cycles = 3; - else if (nand->device->chip_size <= 8*1024) - nand->address_cycles = 4; - else { - LOG_ERROR("BUG: small page NAND device with more than 8 GiB encountered"); - nand->address_cycles = 5; - } - } else { - /* large page devices */ - if (nand->device->chip_size <= 128) - nand->address_cycles = 4; - else if (nand->device->chip_size <= 32*1024) - nand->address_cycles = 5; - else { - LOG_ERROR("BUG: large page NAND device with more than 32 GiB encountered"); - nand->address_cycles = 6; - } - } - - /* erase size */ - if (nand->device->erase_size == 0) { - switch ((id_buff[4] >> 4) & 3) { - case 0: - nand->erase_size = 64 << 10; - break; - case 1: - nand->erase_size = 128 << 10; - break; - case 2: - nand->erase_size = 256 << 10; - break; - case 3: - nand->erase_size = 512 << 10; - break; - } - } else - nand->erase_size = nand->device->erase_size; - - /* initialize controller, but leave parameters at the controllers default */ - retval = nand->controller->init(nand); - if (retval != ERROR_OK) { - switch (retval) { - case ERROR_NAND_OPERATION_FAILED: - LOG_DEBUG("controller initialization failed"); - return ERROR_NAND_OPERATION_FAILED; - case ERROR_NAND_OPERATION_NOT_SUPPORTED: - LOG_ERROR( - "controller doesn't support requested parameters (buswidth: %i, address cycles: %i, page size: %i)", - nand->bus_width, - nand->address_cycles, - nand->page_size); - return ERROR_NAND_OPERATION_FAILED; - default: - LOG_ERROR("BUG: unknown controller initialization failure"); - return ERROR_NAND_OPERATION_FAILED; - } - } - - nand->num_blocks = (nand->device->chip_size * 1024) / (nand->erase_size / 1024); - nand->blocks = malloc(sizeof(struct nand_block) * nand->num_blocks); - - for (i = 0; i < nand->num_blocks; i++) { - nand->blocks[i].size = nand->erase_size; - nand->blocks[i].offset = i * nand->erase_size; - nand->blocks[i].is_erased = -1; - nand->blocks[i].is_bad = -1; - } - - return ERROR_OK; -} - -int nand_erase(struct nand_device *nand, int first_block, int last_block) -{ - int i; - uint32_t page; - uint8_t status; - int retval; - - if (!nand->device) - return ERROR_NAND_DEVICE_NOT_PROBED; - - if ((first_block < 0) || (last_block >= nand->num_blocks)) - return ERROR_COMMAND_SYNTAX_ERROR; - - /* make sure we know if a block is bad before erasing it */ - for (i = first_block; i <= last_block; i++) { - if (nand->blocks[i].is_bad == -1) { - nand_build_bbt(nand, i, last_block); - break; - } - } - - for (i = first_block; i <= last_block; i++) { - /* Send erase setup command */ - nand->controller->command(nand, NAND_CMD_ERASE1); - - page = i * (nand->erase_size / nand->page_size); - - /* Send page address */ - if (nand->page_size <= 512) { - /* row */ - nand->controller->address(nand, page & 0xff); - nand->controller->address(nand, (page >> 8) & 0xff); - - /* 3rd cycle only on devices with more than 32 MiB */ - if (nand->address_cycles >= 4) - nand->controller->address(nand, (page >> 16) & 0xff); - - /* 4th cycle only on devices with more than 8 GiB */ - if (nand->address_cycles >= 5) - nand->controller->address(nand, (page >> 24) & 0xff); - } else { - /* row */ - nand->controller->address(nand, page & 0xff); - nand->controller->address(nand, (page >> 8) & 0xff); - - /* 3rd cycle only on devices with more than 128 MiB */ - if (nand->address_cycles >= 5) - nand->controller->address(nand, (page >> 16) & 0xff); - } - - /* Send erase confirm command */ - nand->controller->command(nand, NAND_CMD_ERASE2); - - retval = nand->controller->nand_ready ? - nand->controller->nand_ready(nand, 1000) : - nand_poll_ready(nand, 1000); - if (!retval) { - LOG_ERROR("timeout waiting for NAND flash block erase to complete"); - return ERROR_NAND_OPERATION_TIMEOUT; - } - - retval = nand_read_status(nand, &status); - if (retval != ERROR_OK) { - LOG_ERROR("couldn't read status"); - return ERROR_NAND_OPERATION_FAILED; - } - - if (status & 0x1) { - LOG_ERROR("didn't erase %sblock %d; status: 0x%2.2x", - (nand->blocks[i].is_bad == 1) - ? "bad " : "", - i, status); - /* continue; other blocks might still be erasable */ - } - - nand->blocks[i].is_erased = 1; - } - - return ERROR_OK; -} - -#if 0 -static int nand_read_plain(struct nand_device *nand, - uint32_t address, - uint8_t *data, - uint32_t data_size) -{ - uint8_t *page; - - if (!nand->device) - return ERROR_NAND_DEVICE_NOT_PROBED; - - if (address % nand->page_size) { - LOG_ERROR("reads need to be page aligned"); - return ERROR_NAND_OPERATION_FAILED; - } - - page = malloc(nand->page_size); - - while (data_size > 0) { - uint32_t thisrun_size = (data_size > nand->page_size) ? nand->page_size : data_size; - uint32_t page_address; - - - page_address = address / nand->page_size; - - nand_read_page(nand, page_address, page, nand->page_size, NULL, 0); - - memcpy(data, page, thisrun_size); - - address += thisrun_size; - data += thisrun_size; - data_size -= thisrun_size; - } - - free(page); - - return ERROR_OK; -} - -static int nand_write_plain(struct nand_device *nand, - uint32_t address, - uint8_t *data, - uint32_t data_size) -{ - uint8_t *page; - - if (!nand->device) - return ERROR_NAND_DEVICE_NOT_PROBED; - - if (address % nand->page_size) { - LOG_ERROR("writes need to be page aligned"); - return ERROR_NAND_OPERATION_FAILED; - } - - page = malloc(nand->page_size); - - while (data_size > 0) { - uint32_t thisrun_size = (data_size > nand->page_size) ? nand->page_size : data_size; - uint32_t page_address; - - memset(page, 0xff, nand->page_size); - memcpy(page, data, thisrun_size); - - page_address = address / nand->page_size; - - nand_write_page(nand, page_address, page, nand->page_size, NULL, 0); - - address += thisrun_size; - data += thisrun_size; - data_size -= thisrun_size; - } - - free(page); - - return ERROR_OK; -} -#endif - -int nand_write_page(struct nand_device *nand, uint32_t page, - uint8_t *data, uint32_t data_size, - uint8_t *oob, uint32_t oob_size) -{ - uint32_t block; - - if (!nand->device) - return ERROR_NAND_DEVICE_NOT_PROBED; - - block = page / (nand->erase_size / nand->page_size); - if (nand->blocks[block].is_erased == 1) - nand->blocks[block].is_erased = 0; - - if (nand->use_raw || nand->controller->write_page == NULL) - return nand_write_page_raw(nand, page, data, data_size, oob, oob_size); - else - return nand->controller->write_page(nand, page, data, data_size, oob, oob_size); -} - -int nand_read_page(struct nand_device *nand, uint32_t page, - uint8_t *data, uint32_t data_size, - uint8_t *oob, uint32_t oob_size) -{ - if (!nand->device) - return ERROR_NAND_DEVICE_NOT_PROBED; - - if (nand->use_raw || nand->controller->read_page == NULL) - return nand_read_page_raw(nand, page, data, data_size, oob, oob_size); - else - return nand->controller->read_page(nand, page, data, data_size, oob, oob_size); -} - -int nand_page_command(struct nand_device *nand, uint32_t page, - uint8_t cmd, bool oob_only) -{ - if (!nand->device) - return ERROR_NAND_DEVICE_NOT_PROBED; - - if (oob_only && NAND_CMD_READ0 == cmd && nand->page_size <= 512) - cmd = NAND_CMD_READOOB; - - nand->controller->command(nand, cmd); - - if (nand->page_size <= 512) { - /* small page device */ - - /* column (always 0, we start at the beginning of a page/OOB area) */ - nand->controller->address(nand, 0x0); - - /* row */ - nand->controller->address(nand, page & 0xff); - nand->controller->address(nand, (page >> 8) & 0xff); - - /* 4th cycle only on devices with more than 32 MiB */ - if (nand->address_cycles >= 4) - nand->controller->address(nand, (page >> 16) & 0xff); - - /* 5th cycle only on devices with more than 8 GiB */ - if (nand->address_cycles >= 5) - nand->controller->address(nand, (page >> 24) & 0xff); - } else { - /* large page device */ - - /* column (0 when we start at the beginning of a page, - * or 2048 for the beginning of OOB area) - */ - nand->controller->address(nand, 0x0); - if (oob_only) - nand->controller->address(nand, 0x8); - else - nand->controller->address(nand, 0x0); - - /* row */ - nand->controller->address(nand, page & 0xff); - nand->controller->address(nand, (page >> 8) & 0xff); - - /* 5th cycle only on devices with more than 128 MiB */ - if (nand->address_cycles >= 5) - nand->controller->address(nand, (page >> 16) & 0xff); - - /* large page devices need a start command if reading */ - if (NAND_CMD_READ0 == cmd) - nand->controller->command(nand, NAND_CMD_READSTART); - } - - if (nand->controller->nand_ready) { - if (!nand->controller->nand_ready(nand, 100)) - return ERROR_NAND_OPERATION_TIMEOUT; - } else { - /* nand_poll_read() cannot be used during nand read */ - alive_sleep(1); - } - - return ERROR_OK; -} - -int nand_read_data_page(struct nand_device *nand, uint8_t *data, uint32_t size) -{ - int retval = ERROR_NAND_NO_BUFFER; - - if (nand->controller->read_block_data != NULL) - retval = (nand->controller->read_block_data)(nand, data, size); - - if (ERROR_NAND_NO_BUFFER == retval) { - uint32_t i; - int incr = (nand->device->options & NAND_BUSWIDTH_16) ? 2 : 1; - - retval = ERROR_OK; - for (i = 0; retval == ERROR_OK && i < size; i += incr) { - retval = nand->controller->read_data(nand, data); - data += incr; - } - } - - return retval; -} - -int nand_read_page_raw(struct nand_device *nand, uint32_t page, - uint8_t *data, uint32_t data_size, - uint8_t *oob, uint32_t oob_size) -{ - int retval; - - retval = nand_page_command(nand, page, NAND_CMD_READ0, !data); - if (ERROR_OK != retval) - return retval; - - if (data) - nand_read_data_page(nand, data, data_size); - - if (oob) - nand_read_data_page(nand, oob, oob_size); - - return ERROR_OK; -} - -int nand_write_data_page(struct nand_device *nand, uint8_t *data, uint32_t size) -{ - int retval = ERROR_NAND_NO_BUFFER; - - if (nand->controller->write_block_data != NULL) - retval = (nand->controller->write_block_data)(nand, data, size); - - if (ERROR_NAND_NO_BUFFER == retval) { - bool is16bit = nand->device->options & NAND_BUSWIDTH_16; - uint32_t incr = is16bit ? 2 : 1; - uint16_t write_data; - uint32_t i; - - for (i = 0; i < size; i += incr) { - if (is16bit) - write_data = le_to_h_u16(data); - else - write_data = *data; - - retval = nand->controller->write_data(nand, write_data); - if (ERROR_OK != retval) - break; - - data += incr; - } - } - - return retval; -} - -int nand_write_finish(struct nand_device *nand) -{ - int retval; - uint8_t status; - - nand->controller->command(nand, NAND_CMD_PAGEPROG); - - retval = nand->controller->nand_ready ? - nand->controller->nand_ready(nand, 100) : - nand_poll_ready(nand, 100); - if (!retval) - return ERROR_NAND_OPERATION_TIMEOUT; - - retval = nand_read_status(nand, &status); - if (ERROR_OK != retval) { - LOG_ERROR("couldn't read status"); - return ERROR_NAND_OPERATION_FAILED; - } - - if (status & NAND_STATUS_FAIL) { - LOG_ERROR("write operation didn't pass, status: 0x%2.2x", - status); - return ERROR_NAND_OPERATION_FAILED; - } - - return ERROR_OK; -} - -int nand_write_page_raw(struct nand_device *nand, uint32_t page, - uint8_t *data, uint32_t data_size, - uint8_t *oob, uint32_t oob_size) -{ - int retval; - - retval = nand_page_command(nand, page, NAND_CMD_SEQIN, !data); - if (ERROR_OK != retval) - return retval; - - if (data) { - retval = nand_write_data_page(nand, data, data_size); - if (ERROR_OK != retval) { - LOG_ERROR("Unable to write data to NAND device"); - return retval; - } - } - - if (oob) { - retval = nand_write_data_page(nand, oob, oob_size); - if (ERROR_OK != retval) { - LOG_ERROR("Unable to write OOB data to NAND device"); - return retval; - } - } - - return nand_write_finish(nand); -} diff --git a/src/flash/nand/core.h b/src/flash/nand/core.h deleted file mode 100644 index 5bf9fb3d1..000000000 --- a/src/flash/nand/core.h +++ /dev/null @@ -1,232 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Dominic Rath * - * Copyright (C) 2009 Zachary T Welch * - * * - * Partially based on linux/include/linux/mtd/nand.h * - * Copyright (C) 2000 David Woodhouse * - * Copyright (C) 2000 Steven J. Hill * - * Copyright (C) 2000 Thomas Gleixner * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 OPENOCD_FLASH_NAND_CORE_H -#define OPENOCD_FLASH_NAND_CORE_H - -#include - -/** - * Representation of a single NAND block in a NAND device. - */ -struct nand_block { - /** Offset to the block. */ - uint32_t offset; - - /** Size of the block. */ - uint32_t size; - - /** True if the block has been erased. */ - int is_erased; - - /** True if the block is bad. */ - int is_bad; -}; - -struct nand_oobfree { - int offset; - int length; -}; - -struct nand_ecclayout { - int eccbytes; - int eccpos[64]; - int oobavail; - struct nand_oobfree oobfree[2]; -}; - -struct nand_device { - const char *name; - struct target *target; - struct nand_flash_controller *controller; - void *controller_priv; - struct nand_manufacturer *manufacturer; - struct nand_info *device; - int bus_width; - int address_cycles; - int page_size; - int erase_size; - bool use_raw; - int num_blocks; - struct nand_block *blocks; - struct nand_device *next; -}; - -/* NAND Flash Manufacturer ID Codes - */ -enum { - NAND_MFR_TOSHIBA = 0x98, - NAND_MFR_SAMSUNG = 0xec, - NAND_MFR_FUJITSU = 0x04, - NAND_MFR_NATIONAL = 0x8f, - NAND_MFR_RENESAS = 0x07, - NAND_MFR_STMICRO = 0x20, - NAND_MFR_HYNIX = 0xad, - NAND_MFR_MICRON = 0x2c, -}; - -struct nand_manufacturer { - int id; - const char *name; -}; - -struct nand_info { - int mfr_id; - int id; - int page_size; - int chip_size; - int erase_size; - int options; - const char *name; -}; - -/* Option constants for bizarre disfunctionality and real features - */ -enum { - /* Chip can not auto increment pages */ - NAND_NO_AUTOINCR = 0x00000001, - - /* Buswitdh is 16 bit */ - NAND_BUSWIDTH_16 = 0x00000002, - - /* Device supports partial programming without padding */ - NAND_NO_PADDING = 0x00000004, - - /* Chip has cache program function */ - NAND_CACHEPRG = 0x00000008, - - /* Chip has copy back function */ - NAND_COPYBACK = 0x00000010, - - /* AND Chip which has 4 banks and a confusing page / block - * assignment. See Renesas datasheet for further information */ - NAND_IS_AND = 0x00000020, - - /* Chip has a array of 4 pages which can be read without - * additional ready /busy waits */ - NAND_4PAGE_ARRAY = 0x00000040, - - /* Chip requires that BBT is periodically rewritten to prevent - * bits from adjacent blocks from 'leaking' in altering data. - * This happens with the Renesas AG-AND chips, possibly others. */ - BBT_AUTO_REFRESH = 0x00000080, - - /* Chip does not require ready check on read. True - * for all large page devices, as they do not support - * autoincrement.*/ - NAND_NO_READRDY = 0x00000100, - - /* Options valid for Samsung large page devices */ - NAND_SAMSUNG_LP_OPTIONS = (NAND_NO_PADDING | NAND_CACHEPRG | NAND_COPYBACK), - - /* Options for new chips with large page size. The pagesize and the - * erasesize is determined from the extended id bytes - */ - LP_OPTIONS = (NAND_SAMSUNG_LP_OPTIONS | NAND_NO_READRDY | NAND_NO_AUTOINCR), - LP_OPTIONS16 = (LP_OPTIONS | NAND_BUSWIDTH_16), -}; - -enum { - /* Standard NAND flash commands */ - NAND_CMD_READ0 = 0x0, - NAND_CMD_READ1 = 0x1, - NAND_CMD_RNDOUT = 0x5, - NAND_CMD_PAGEPROG = 0x10, - NAND_CMD_READOOB = 0x50, - NAND_CMD_ERASE1 = 0x60, - NAND_CMD_STATUS = 0x70, - NAND_CMD_STATUS_MULTI = 0x71, - NAND_CMD_SEQIN = 0x80, - NAND_CMD_RNDIN = 0x85, - NAND_CMD_READID = 0x90, - NAND_CMD_ERASE2 = 0xd0, - NAND_CMD_RESET = 0xff, - - /* Extended commands for large page devices */ - NAND_CMD_READSTART = 0x30, - NAND_CMD_RNDOUTSTART = 0xE0, - NAND_CMD_CACHEDPROG = 0x15, -}; - -/* Status bits */ -enum { - NAND_STATUS_FAIL = 0x01, - NAND_STATUS_FAIL_N1 = 0x02, - NAND_STATUS_TRUE_READY = 0x20, - NAND_STATUS_READY = 0x40, - NAND_STATUS_WP = 0x80, -}; - -/* OOB (spare) data formats */ -enum oob_formats { - NAND_OOB_NONE = 0x0, /* no OOB data at all */ - NAND_OOB_RAW = 0x1, /* raw OOB data (16 bytes for 512b page sizes, 64 bytes for - *2048b page sizes) */ - NAND_OOB_ONLY = 0x2, /* only OOB data */ - NAND_OOB_SW_ECC = 0x10, /* when writing, use SW ECC (as opposed to no ECC) */ - NAND_OOB_HW_ECC = 0x20, /* when writing, use HW ECC (as opposed to no ECC) */ - NAND_OOB_SW_ECC_KW = 0x40, /* when writing, use Marvell's Kirkwood bootrom format */ - NAND_OOB_JFFS2 = 0x100, /* when writing, use JFFS2 OOB layout */ - NAND_OOB_YAFFS2 = 0x100,/* when writing, use YAFFS2 OOB layout */ -}; - - -struct nand_device *get_nand_device_by_num(int num); - -int nand_page_command(struct nand_device *nand, uint32_t page, - uint8_t cmd, bool oob_only); - -int nand_read_data_page(struct nand_device *nand, uint8_t *data, uint32_t size); -int nand_write_data_page(struct nand_device *nand, - uint8_t *data, uint32_t size); - -int nand_write_finish(struct nand_device *nand); - -int nand_read_page_raw(struct nand_device *nand, uint32_t page, - uint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size); -int nand_write_page_raw(struct nand_device *nand, uint32_t page, - uint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size); - -int nand_read_status(struct nand_device *nand, uint8_t *status); - -int nand_calculate_ecc(struct nand_device *nand, - const uint8_t *dat, uint8_t *ecc_code); -int nand_calculate_ecc_kw(struct nand_device *nand, - const uint8_t *dat, uint8_t *ecc_code); - -int nand_register_commands(struct command_context *cmd_ctx); - -/** helper for parsing a nand device command argument string */ -COMMAND_HELPER(nand_command_get_device, unsigned name_index, - struct nand_device **nand); - - -#define ERROR_NAND_DEVICE_INVALID (-1100) -#define ERROR_NAND_OPERATION_FAILED (-1101) -#define ERROR_NAND_OPERATION_TIMEOUT (-1102) -#define ERROR_NAND_OPERATION_NOT_SUPPORTED (-1103) -#define ERROR_NAND_DEVICE_NOT_PROBED (-1104) -#define ERROR_NAND_ERROR_CORRECTION_FAILED (-1105) -#define ERROR_NAND_NO_BUFFER (-1106) - -#endif /* OPENOCD_FLASH_NAND_CORE_H */ diff --git a/src/flash/nand/davinci.c b/src/flash/nand/davinci.c deleted file mode 100644 index 17e6f680d..000000000 --- a/src/flash/nand/davinci.c +++ /dev/null @@ -1,793 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2009 by David Brownell * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -/* - * DaVinci family NAND controller support for OpenOCD. - * - * This driver uses hardware ECC (1-bit or 4-bit) unless - * the chip is accessed in "raw" mode. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "imp.h" -#include "arm_io.h" -#include - -enum ecc { - HWECC1, /* all controllers support 1-bit ECC */ - HWECC4, /* newer chips also have 4-bit ECC hardware */ - HWECC4_INFIX, /* avoid this layout, except maybe for boot code */ -}; - -struct davinci_nand { - uint8_t chipsel; /* chipselect 0..3 == CS2..CS5 */ - uint8_t eccmode; - - /* Async EMIF controller base */ - uint32_t aemif; - - /* NAND chip addresses */ - uint32_t data; /* without CLE or ALE */ - uint32_t cmd; /* with CLE */ - uint32_t addr; /* with ALE */ - - /* write acceleration */ - struct arm_nand_data io; - - /* page i/o for the relevant flavor of hardware ECC */ - int (*read_page)(struct nand_device *nand, uint32_t page, - uint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size); - int (*write_page)(struct nand_device *nand, uint32_t page, - uint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size); -}; - -#define NANDFCR 0x60 /* flash control register */ -#define NANDFSR 0x64 /* flash status register */ -#define NANDFECC 0x70 /* 1-bit ECC data, CS0, 1st of 4 */ -#define NAND4BITECCLOAD 0xbc /* 4-bit ECC, load saved values */ -#define NAND4BITECC 0xc0 /* 4-bit ECC data, 1st of 4 */ -#define NANDERRADDR 0xd0 /* 4-bit ECC err addr, 1st of 2 */ -#define NANDERRVAL 0xd8 /* 4-bit ECC err value, 1st of 2 */ - -static int halted(struct target *target, const char *label) -{ - if (target->state == TARGET_HALTED) - return true; - - LOG_ERROR("Target must be halted to use NAND controller (%s)", label); - return false; -} - -static int davinci_init(struct nand_device *nand) -{ - struct davinci_nand *info = nand->controller_priv; - struct target *target = nand->target; - uint32_t nandfcr; - - if (!halted(target, "init")) - return ERROR_NAND_OPERATION_FAILED; - - /* We require something else to have configured AEMIF to talk - * to NAND chip in this range (including timings and width). - */ - target_read_u32(target, info->aemif + NANDFCR, &nandfcr); - if (!(nandfcr & (1 << info->chipsel))) { - LOG_ERROR("chip address %08" PRIx32 " not NAND-enabled?", info->data); - return ERROR_NAND_OPERATION_FAILED; - } - - /* REVISIT verify: AxCR must be in 8-bit mode, since that's all we - * tested. 16 bit support should work too; but not with 4-bit ECC. - */ - - return ERROR_OK; -} - -static int davinci_reset(struct nand_device *nand) -{ - return ERROR_OK; -} - -static int davinci_nand_ready(struct nand_device *nand, int timeout) -{ - struct davinci_nand *info = nand->controller_priv; - struct target *target = nand->target; - uint32_t nandfsr; - - /* NOTE: return code is zero/error, else success; not ERROR_* */ - - if (!halted(target, "ready")) - return 0; - - do { - target_read_u32(target, info->aemif + NANDFSR, &nandfsr); - - if (nandfsr & 0x01) - return 1; - - alive_sleep(1); - } while (timeout-- > 0); - - return 0; -} - -static int davinci_command(struct nand_device *nand, uint8_t command) -{ - struct davinci_nand *info = nand->controller_priv; - struct target *target = nand->target; - - if (!halted(target, "command")) - return ERROR_NAND_OPERATION_FAILED; - - target_write_u8(target, info->cmd, command); - return ERROR_OK; -} - -static int davinci_address(struct nand_device *nand, uint8_t address) -{ - struct davinci_nand *info = nand->controller_priv; - struct target *target = nand->target; - - if (!halted(target, "address")) - return ERROR_NAND_OPERATION_FAILED; - - target_write_u8(target, info->addr, address); - return ERROR_OK; -} - -static int davinci_write_data(struct nand_device *nand, uint16_t data) -{ - struct davinci_nand *info = nand->controller_priv; - struct target *target = nand->target; - - if (!halted(target, "write_data")) - return ERROR_NAND_OPERATION_FAILED; - - target_write_u8(target, info->data, data); - return ERROR_OK; -} - -static int davinci_read_data(struct nand_device *nand, void *data) -{ - struct davinci_nand *info = nand->controller_priv; - struct target *target = nand->target; - - if (!halted(target, "read_data")) - return ERROR_NAND_OPERATION_FAILED; - - target_read_u8(target, info->data, data); - return ERROR_OK; -} - -/* REVISIT a bit of native code should let block reads be MUCH faster */ - -static int davinci_read_block_data(struct nand_device *nand, - uint8_t *data, int data_size) -{ - struct davinci_nand *info = nand->controller_priv; - struct target *target = nand->target; - uint32_t nfdata = info->data; - uint32_t tmp; - - if (!halted(target, "read_block")) - return ERROR_NAND_OPERATION_FAILED; - - while (data_size >= 4) { - target_read_u32(target, nfdata, &tmp); - - data[0] = tmp; - data[1] = tmp >> 8; - data[2] = tmp >> 16; - data[3] = tmp >> 24; - - data_size -= 4; - data += 4; - } - - while (data_size > 0) { - target_read_u8(target, nfdata, data); - - data_size -= 1; - data += 1; - } - - return ERROR_OK; -} - -static int davinci_write_block_data(struct nand_device *nand, - uint8_t *data, int data_size) -{ - struct davinci_nand *info = nand->controller_priv; - struct target *target = nand->target; - uint32_t nfdata = info->data; - uint32_t tmp; - int status; - - if (!halted(target, "write_block")) - return ERROR_NAND_OPERATION_FAILED; - - /* try the fast way first */ - status = arm_nandwrite(&info->io, data, data_size); - if (status != ERROR_NAND_NO_BUFFER) - return status; - - /* else do it slowly */ - while (data_size >= 4) { - tmp = le_to_h_u32(data); - target_write_u32(target, nfdata, tmp); - - data_size -= 4; - data += 4; - } - - while (data_size > 0) { - target_write_u8(target, nfdata, *data); - - data_size -= 1; - data += 1; - } - - return ERROR_OK; -} - -static int davinci_write_page(struct nand_device *nand, uint32_t page, - uint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size) -{ - struct davinci_nand *info = nand->controller_priv; - uint8_t *ooballoc = NULL; - int status; - - if (!nand->device) - return ERROR_NAND_DEVICE_NOT_PROBED; - if (!halted(nand->target, "write_page")) - return ERROR_NAND_OPERATION_FAILED; - - /* Always write both data and OOB ... we are not "raw" I/O! */ - if (!data) { - LOG_ERROR("Missing NAND data; try 'nand raw_access enable'"); - return ERROR_NAND_OPERATION_FAILED; - } - - /* If we're not given OOB, write 0xff where we don't write ECC codes. */ - switch (nand->page_size) { - case 512: - oob_size = 16; - break; - case 2048: - oob_size = 64; - break; - case 4096: - oob_size = 128; - break; - default: - return ERROR_NAND_OPERATION_FAILED; - } - if (!oob) { - ooballoc = malloc(oob_size); - if (!ooballoc) - return ERROR_NAND_OPERATION_FAILED; - oob = ooballoc; - memset(oob, 0x0ff, oob_size); - } - - /* REVISIT avoid wasting SRAM: unless nand->use_raw is set, - * use 512 byte chunks. Read side support will often want - * to include oob_size ... - */ - info->io.chunk_size = nand->page_size; - - status = info->write_page(nand, page, data, data_size, oob, oob_size); - free(ooballoc); - return status; -} - -static int davinci_read_page(struct nand_device *nand, uint32_t page, - uint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size) -{ - struct davinci_nand *info = nand->controller_priv; - - if (!nand->device) - return ERROR_NAND_DEVICE_NOT_PROBED; - if (!halted(nand->target, "read_page")) - return ERROR_NAND_OPERATION_FAILED; - - return info->read_page(nand, page, data, data_size, oob, oob_size); -} - -static void davinci_write_pagecmd(struct nand_device *nand, uint8_t cmd, uint32_t page) -{ - struct davinci_nand *info = nand->controller_priv; - struct target *target = nand->target; - int page3 = nand->address_cycles - (nand->page_size == 512); - - /* write command ({page,otp}x{read,program} */ - target_write_u8(target, info->cmd, cmd); - - /* column address (beginning-of-page) */ - target_write_u8(target, info->addr, 0); - if (nand->page_size > 512) - target_write_u8(target, info->addr, 0); - - /* page address */ - target_write_u8(target, info->addr, page); - target_write_u8(target, info->addr, page >> 8); - if (page3) - target_write_u8(target, info->addr, page >> 16); - if (page3 == 2) - target_write_u8(target, info->addr, page >> 24); -} - -static int davinci_seek_column(struct nand_device *nand, uint16_t column) -{ - struct davinci_nand *info = nand->controller_priv; - struct target *target = nand->target; - - /* Random read, we must have issued a page read already */ - target_write_u8(target, info->cmd, NAND_CMD_RNDOUT); - - target_write_u8(target, info->addr, column); - - if (nand->page_size > 512) { - target_write_u8(target, info->addr, column >> 8); - target_write_u8(target, info->cmd, NAND_CMD_RNDOUTSTART); - } - - if (!davinci_nand_ready(nand, 100)) - return ERROR_NAND_OPERATION_TIMEOUT; - - return ERROR_OK; -} - -static int davinci_writepage_tail(struct nand_device *nand, - uint8_t *oob, uint32_t oob_size) -{ - struct davinci_nand *info = nand->controller_priv; - struct target *target = nand->target; - uint8_t status; - - if (oob_size) - davinci_write_block_data(nand, oob, oob_size); - - /* non-cachemode page program */ - target_write_u8(target, info->cmd, NAND_CMD_PAGEPROG); - - if (!davinci_nand_ready(nand, 100)) - return ERROR_NAND_OPERATION_TIMEOUT; - - if (nand_read_status(nand, &status) != ERROR_OK) { - LOG_ERROR("couldn't read status"); - return ERROR_NAND_OPERATION_FAILED; - } - - if (status & NAND_STATUS_FAIL) { - LOG_ERROR("write operation failed, status: 0x%02x", status); - return ERROR_NAND_OPERATION_FAILED; - } - - return ERROR_OK; -} - -/* - * All DaVinci family chips support 1-bit ECC on a per-chipselect basis. - */ -static int davinci_write_page_ecc1(struct nand_device *nand, uint32_t page, - uint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size) -{ - unsigned oob_offset; - struct davinci_nand *info = nand->controller_priv; - struct target *target = nand->target; - const uint32_t fcr_addr = info->aemif + NANDFCR; - const uint32_t ecc1_addr = info->aemif + NANDFECC + (4 * info->chipsel); - uint32_t fcr, ecc1; - - /* Write contiguous ECC bytes starting at specified offset. - * NOTE: Linux reserves twice as many bytes as we need; and - * for 16-bit OOB, those extra bytes are discontiguous. - */ - switch (nand->page_size) { - case 512: - oob_offset = 0; - break; - case 2048: - oob_offset = 40; - break; - default: - oob_offset = 80; - break; - } - - davinci_write_pagecmd(nand, NAND_CMD_SEQIN, page); - - /* scrub any old ECC state */ - target_read_u32(target, ecc1_addr, &ecc1); - - target_read_u32(target, fcr_addr, &fcr); - fcr |= 1 << (8 + info->chipsel); - - do { - /* set "start csX 1bit ecc" bit */ - target_write_u32(target, fcr_addr, fcr); - - /* write 512 bytes */ - davinci_write_block_data(nand, data, 512); - data += 512; - data_size -= 512; - - /* read the ecc, pack to 3 bytes, and invert so the ecc - * in an erased block is correct - */ - target_read_u32(target, ecc1_addr, &ecc1); - ecc1 = (ecc1 & 0x0fff) | ((ecc1 & 0x0fff0000) >> 4); - ecc1 = ~ecc1; - - /* save correct ECC code into oob data */ - oob[oob_offset++] = (uint8_t)(ecc1); - oob[oob_offset++] = (uint8_t)(ecc1 >> 8); - oob[oob_offset++] = (uint8_t)(ecc1 >> 16); - - } while (data_size); - - /* write OOB into spare area */ - return davinci_writepage_tail(nand, oob, oob_size); -} - -/* - * Preferred "new style" ECC layout for use with 4-bit ECC. This somewhat - * slows down large page reads done with error correction (since the OOB - * is read first, so its ECC data can be used incrementally), but the - * manufacturer bad block markers are safe. Contrast: old "infix" style. - */ -static int davinci_write_page_ecc4(struct nand_device *nand, uint32_t page, - uint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size) -{ - static const uint8_t ecc512[] = { - 0, 1, 2, 3, 4, /* 5== mfr badblock */ - 6, 7, /* 8..12 for BBT or JFFS2 */ 13, 14, 15, - }; - static const uint8_t ecc2048[] = { - 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, - 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, - 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, - 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, - }; - static const uint8_t ecc4096[] = { - 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, - 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, - 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, - 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, - 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, - 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, - 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, - 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, - }; - - struct davinci_nand *info = nand->controller_priv; - const uint8_t *l; - struct target *target = nand->target; - const uint32_t fcr_addr = info->aemif + NANDFCR; - const uint32_t ecc4_addr = info->aemif + NAND4BITECC; - uint32_t fcr, ecc4; - - /* Use the same ECC layout Linux uses. For small page chips - * it's a bit cramped. - * - * NOTE: at this writing, 4KB pages have issues in Linux - * because they need more than 64 bytes of ECC data, which - * the standard ECC logic can't handle. - */ - switch (nand->page_size) { - case 512: - l = ecc512; - break; - case 2048: - l = ecc2048; - break; - default: - l = ecc4096; - break; - } - - davinci_write_pagecmd(nand, NAND_CMD_SEQIN, page); - - /* scrub any old ECC state */ - target_read_u32(target, info->aemif + NANDERRVAL, &ecc4); - - target_read_u32(target, fcr_addr, &fcr); - fcr &= ~(0x03 << 4); - fcr |= (1 << 12) | (info->chipsel << 4); - - do { - uint32_t raw_ecc[4], *p; - int i; - - /* start 4bit ecc on csX */ - target_write_u32(target, fcr_addr, fcr); - - /* write 512 bytes */ - davinci_write_block_data(nand, data, 512); - data += 512; - data_size -= 512; - - /* read the ecc, then save it into 10 bytes in the oob */ - for (i = 0; i < 4; i++) { - target_read_u32(target, ecc4_addr + 4 * i, &raw_ecc[i]); - raw_ecc[i] &= 0x03ff03ff; - } - for (i = 0, p = raw_ecc; i < 2; i++, p += 2) { - oob[*l++] = p[0] & 0xff; - oob[*l++] = ((p[0] >> 8) & 0x03) | ((p[0] >> 14) & 0xfc); - oob[*l++] = ((p[0] >> 22) & 0x0f) | ((p[1] << 4) & 0xf0); - oob[*l++] = ((p[1] >> 4) & 0x3f) | ((p[1] >> 10) & 0xc0); - oob[*l++] = (p[1] >> 18) & 0xff; - } - - } while (data_size); - - /* write OOB into spare area */ - return davinci_writepage_tail(nand, oob, oob_size); -} - -/* - * "Infix" OOB ... like Linux ECC_HW_SYNDROME. Avoided because it trashes - * manufacturer bad block markers, except on small page chips. Once you - * write to a page using this scheme, you need specialized code to update - * it (code which ignores now-invalid bad block markers). - * - * This is needed *only* to support older firmware. Older ROM Boot Loaders - * need it to read their second stage loader (UBL) into SRAM, but from then - * on the whole system can use the cleaner non-infix layouts. Systems with - * older second stage loaders (ABL/U-Boot, etc) or other system software - * (MVL 4.x/5.x kernels, filesystems, etc) may need it more generally. - */ -static int davinci_write_page_ecc4infix(struct nand_device *nand, uint32_t page, - uint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size) -{ - struct davinci_nand *info = nand->controller_priv; - struct target *target = nand->target; - const uint32_t fcr_addr = info->aemif + NANDFCR; - const uint32_t ecc4_addr = info->aemif + NAND4BITECC; - uint32_t fcr, ecc4; - - davinci_write_pagecmd(nand, NAND_CMD_SEQIN, page); - - /* scrub any old ECC state */ - target_read_u32(target, info->aemif + NANDERRVAL, &ecc4); - - target_read_u32(target, fcr_addr, &fcr); - fcr &= ~(0x03 << 4); - fcr |= (1 << 12) | (info->chipsel << 4); - - do { - uint32_t raw_ecc[4], *p; - uint8_t *l; - int i; - - /* start 4bit ecc on csX */ - target_write_u32(target, fcr_addr, fcr); - - /* write 512 bytes */ - davinci_write_block_data(nand, data, 512); - data += 512; - data_size -= 512; - - /* read the ecc */ - for (i = 0; i < 4; i++) { - target_read_u32(target, ecc4_addr + 4 * i, &raw_ecc[i]); - raw_ecc[i] &= 0x03ff03ff; - } - - /* skip 6 bytes of prepad, then pack 10 packed ecc bytes */ - for (i = 0, l = oob + 6, p = raw_ecc; i < 2; i++, p += 2) { - *l++ = p[0] & 0xff; - *l++ = ((p[0] >> 8) & 0x03) | ((p[0] >> 14) & 0xfc); - *l++ = ((p[0] >> 22) & 0x0f) | ((p[1] << 4) & 0xf0); - *l++ = ((p[1] >> 4) & 0x3f) | ((p[1] >> 10) & 0xc0); - *l++ = (p[1] >> 18) & 0xff; - } - - /* write this "out-of-band" data -- infix */ - davinci_write_block_data(nand, oob, 16); - oob += 16; - oob_size -= 16; - - } while (data_size); - - /* the last data and OOB writes included the spare area */ - return davinci_writepage_tail(nand, NULL, 0); -} - -static int davinci_read_page_ecc4infix(struct nand_device *nand, uint32_t page, - uint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size) -{ - int read_size; - int want_col, at_col; - int ret; - - davinci_write_pagecmd(nand, NAND_CMD_READ0, page); - - /* large page devices need a start command */ - if (nand->page_size > 512) - davinci_command(nand, NAND_CMD_READSTART); - - if (!davinci_nand_ready(nand, 100)) - return ERROR_NAND_OPERATION_TIMEOUT; - - /* NOTE: not bothering to compute and use ECC data for now */ - - want_col = 0; - at_col = 0; - while ((data && data_size) || (oob && oob_size)) { - - if (data && data_size) { - if (want_col != at_col) { - /* Reads are slow, so seek past them when we can */ - ret = davinci_seek_column(nand, want_col); - if (ret != ERROR_OK) - return ret; - at_col = want_col; - } - /* read 512 bytes or data_size, whichever is smaller*/ - read_size = data_size > 512 ? 512 : data_size; - davinci_read_block_data(nand, data, read_size); - data += read_size; - data_size -= read_size; - at_col += read_size; - } - want_col += 512; - - if (oob && oob_size) { - if (want_col != at_col) { - ret = davinci_seek_column(nand, want_col); - if (ret != ERROR_OK) - return ret; - at_col = want_col; - } - /* read this "out-of-band" data -- infix */ - read_size = oob_size > 16 ? 16 : oob_size; - davinci_read_block_data(nand, oob, read_size); - oob += read_size; - oob_size -= read_size; - at_col += read_size; - } - want_col += 16; - } - return ERROR_OK; -} - -NAND_DEVICE_COMMAND_HANDLER(davinci_nand_device_command) -{ - struct davinci_nand *info; - unsigned long chip, aemif; - enum ecc eccmode; - int chipsel; - - /* arguments: - * - "davinci" - * - target - * - nand chip address - * - ecc mode - * - aemif address - * Plus someday, optionally, ALE and CLE masks. - */ - if (CMD_ARGC < 5) - return ERROR_COMMAND_SYNTAX_ERROR; - - COMMAND_PARSE_NUMBER(ulong, CMD_ARGV[2], chip); - if (chip == 0) { - LOG_ERROR("Invalid NAND chip address %s", CMD_ARGV[2]); - goto fail; - } - - if (strcmp(CMD_ARGV[3], "hwecc1") == 0) - eccmode = HWECC1; - else if (strcmp(CMD_ARGV[3], "hwecc4") == 0) - eccmode = HWECC4; - else if (strcmp(CMD_ARGV[3], "hwecc4_infix") == 0) - eccmode = HWECC4_INFIX; - else { - LOG_ERROR("Invalid ecc mode %s", CMD_ARGV[3]); - goto fail; - } - - COMMAND_PARSE_NUMBER(ulong, CMD_ARGV[4], aemif); - if (aemif == 0) { - LOG_ERROR("Invalid AEMIF controller address %s", CMD_ARGV[4]); - goto fail; - } - - /* REVISIT what we'd *like* to do is look up valid ranges using - * target-specific declarations, and not even need to pass the - * AEMIF controller address. - */ - if (aemif == 0x01e00000 /* dm6446, dm357 */ - || aemif == 0x01e10000 /* dm335, dm355 */ - || aemif == 0x01d10000 /* dm365 */ - ) { - if (chip < 0x02000000 || chip >= 0x0a000000) { - LOG_ERROR("NAND address %08lx out of range?", chip); - goto fail; - } - chipsel = (chip - 0x02000000) >> 25; - } else { - LOG_ERROR("unrecognized AEMIF controller address %08lx", aemif); - goto fail; - } - - info = calloc(1, sizeof *info); - if (info == NULL) - goto fail; - - info->eccmode = eccmode; - info->chipsel = chipsel; - info->aemif = aemif; - info->data = chip; - info->cmd = chip | 0x10; - info->addr = chip | 0x08; - - nand->controller_priv = info; - - info->io.target = nand->target; - info->io.data = info->data; - info->io.op = ARM_NAND_NONE; - - /* NOTE: for now we don't do any error correction on read. - * Nothing else in OpenOCD currently corrects read errors, - * and in any case it's *writing* that we care most about. - */ - info->read_page = nand_read_page_raw; - - switch (eccmode) { - case HWECC1: - /* ECC_HW, 1-bit corrections, 3 bytes ECC per 512 data bytes */ - info->write_page = davinci_write_page_ecc1; - break; - case HWECC4: - /* ECC_HW, 4-bit corrections, 10 bytes ECC per 512 data bytes */ - info->write_page = davinci_write_page_ecc4; - break; - case HWECC4_INFIX: - /* Same 4-bit ECC HW, with problematic page/ecc layout */ - info->read_page = davinci_read_page_ecc4infix; - info->write_page = davinci_write_page_ecc4infix; - break; - } - - return ERROR_OK; - -fail: - return ERROR_NAND_OPERATION_FAILED; -} - -struct nand_flash_controller davinci_nand_controller = { - .name = "davinci", - .usage = "chip_addr hwecc_mode aemif_addr", - .nand_device_command = davinci_nand_device_command, - .init = davinci_init, - .reset = davinci_reset, - .command = davinci_command, - .address = davinci_address, - .write_data = davinci_write_data, - .read_data = davinci_read_data, - .write_page = davinci_write_page, - .read_page = davinci_read_page, - .write_block_data = davinci_write_block_data, - .read_block_data = davinci_read_block_data, - .nand_ready = davinci_nand_ready, -}; diff --git a/src/flash/nand/driver.c b/src/flash/nand/driver.c deleted file mode 100644 index f7665603f..000000000 --- a/src/flash/nand/driver.c +++ /dev/null @@ -1,82 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005 by Dominic Rath * - * Copyright (C) 2007,2008 Øyvind Harboe * - * Copyright (C) 2008 by Spencer Oliver * - * Copyright (C) 2009 Zachary T Welch * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 -#include -#endif -#include "core.h" -#include "driver.h" - -/* NAND flash controller - */ -extern struct nand_flash_controller nonce_nand_controller; -extern struct nand_flash_controller davinci_nand_controller; -extern struct nand_flash_controller lpc3180_nand_controller; -extern struct nand_flash_controller lpc32xx_nand_controller; -extern struct nand_flash_controller orion_nand_controller; -extern struct nand_flash_controller s3c2410_nand_controller; -extern struct nand_flash_controller s3c2412_nand_controller; -extern struct nand_flash_controller s3c2440_nand_controller; -extern struct nand_flash_controller s3c2443_nand_controller; -extern struct nand_flash_controller s3c6400_nand_controller; -extern struct nand_flash_controller mxc_nand_flash_controller; -extern struct nand_flash_controller imx31_nand_flash_controller; -extern struct nand_flash_controller at91sam9_nand_controller; -extern struct nand_flash_controller nuc910_nand_controller; - -/* extern struct nand_flash_controller boundary_scan_nand_controller; */ - -static struct nand_flash_controller *nand_flash_controllers[] = { - &nonce_nand_controller, - &davinci_nand_controller, - &lpc3180_nand_controller, - &lpc32xx_nand_controller, - &orion_nand_controller, - &s3c2410_nand_controller, - &s3c2412_nand_controller, - &s3c2440_nand_controller, - &s3c2443_nand_controller, - &s3c6400_nand_controller, - &mxc_nand_flash_controller, - &imx31_nand_flash_controller, - &at91sam9_nand_controller, - &nuc910_nand_controller, -/* &boundary_scan_nand_controller, */ - NULL -}; - -struct nand_flash_controller *nand_driver_find_by_name(const char *name) -{ - for (unsigned i = 0; nand_flash_controllers[i]; i++) { - struct nand_flash_controller *controller = nand_flash_controllers[i]; - if (strcmp(name, controller->name) == 0) - return controller; - } - return NULL; -} -int nand_driver_walk(nand_driver_walker_t f, void *x) -{ - for (unsigned i = 0; nand_flash_controllers[i]; i++) { - int retval = (*f)(nand_flash_controllers[i], x); - if (ERROR_OK != retval) - return retval; - } - return ERROR_OK; -} diff --git a/src/flash/nand/driver.h b/src/flash/nand/driver.h deleted file mode 100644 index 2182a7727..000000000 --- a/src/flash/nand/driver.h +++ /dev/null @@ -1,103 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005 by Dominic Rath * - * Copyright (C) 2007,2008 Øyvind Harboe * - * Copyright (C) 2008 by Spencer Oliver * - * Copyright (C) 2009 Zachary T Welch * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 OPENOCD_FLASH_NAND_DRIVER_H -#define OPENOCD_FLASH_NAND_DRIVER_H - -struct nand_device; - -#define __NAND_DEVICE_COMMAND(name) \ - COMMAND_HELPER(name, struct nand_device *nand) - -/** - * Interface for NAND flash controllers. Not all of these functions are - * required for full functionality of the NAND driver, but better performance - * can be achieved by implementing each function. - */ -struct nand_flash_controller { - /** Driver name that is used to select it from configuration files. */ - const char *name; - - /** Usage of flash command registration. */ - const char *usage; - - const struct command_registration *commands; - - /** NAND device command called when driver is instantiated during configuration. */ - __NAND_DEVICE_COMMAND((*nand_device_command)); - - /** Initialize the NAND device. */ - int (*init)(struct nand_device *nand); - - /** Reset the NAND device. */ - int (*reset)(struct nand_device *nand); - - /** Issue a command to the NAND device. */ - int (*command)(struct nand_device *nand, uint8_t command); - - /** Write an address to the NAND device. */ - int (*address)(struct nand_device *nand, uint8_t address); - - /** Write word of data to the NAND device. */ - int (*write_data)(struct nand_device *nand, uint16_t data); - - /** Read word of data from the NAND device. */ - int (*read_data)(struct nand_device *nand, void *data); - - /** Write a block of data to the NAND device. */ - int (*write_block_data)(struct nand_device *nand, uint8_t *data, int size); - - /** Read a block of data from the NAND device. */ - int (*read_block_data)(struct nand_device *nand, uint8_t *data, int size); - - /** Write a page to the NAND device. */ - int (*write_page)(struct nand_device *nand, uint32_t page, uint8_t *data, - uint32_t data_size, uint8_t *oob, uint32_t oob_size); - - /** Read a page from the NAND device. */ - int (*read_page)(struct nand_device *nand, uint32_t page, uint8_t *data, uint32_t data_size, - uint8_t *oob, uint32_t oob_size); - - /** Check if the NAND device is ready for more instructions with timeout. */ - int (*nand_ready)(struct nand_device *nand, int timeout); -}; - -#define NAND_DEVICE_COMMAND_HANDLER(name) static __NAND_DEVICE_COMMAND(name) - -/** - * Find a NAND flash controller by name. - * @param name Identifies the NAND controller to find. - * @returns The nand_flash_controller named @c name, or NULL if not found. - */ -struct nand_flash_controller *nand_driver_find_by_name(const char *name); - -/** Signature for callback functions passed to nand_driver_walk */ -typedef int (*nand_driver_walker_t)(struct nand_flash_controller *c, void *); -/** - * Walk the list of drivers, encapsulating the data structure type. - * Application state/context can be passed through the @c x pointer. - * @param f The callback function to invoke for each function. - * @param x For use as private data storate, passed directly to @c f. - * @returns ERROR_OK if successful, or the non-zero return value of @c f. - * This allows a walker to terminate the loop early. - */ -int nand_driver_walk(nand_driver_walker_t f, void *x); - -#endif /* OPENOCD_FLASH_NAND_DRIVER_H */ diff --git a/src/flash/nand/ecc.c b/src/flash/nand/ecc.c deleted file mode 100644 index 25b2eb10e..000000000 --- a/src/flash/nand/ecc.c +++ /dev/null @@ -1,182 +0,0 @@ -/* - * This file contains an ECC algorithm from Toshiba that allows for detection - * and correction of 1-bit errors in a 256 byte block of data. - * - * [ Extracted from the initial code found in some early Linux versions. - * The current Linux code is bigger while being faster, but this is of - * no real benefit when the bottleneck largely remains the JTAG link. ] - * - * Copyright (C) 2000-2004 Steven J. Hill (sjhill at realitydiluted.com) - * Toshiba America Electronics Components, Inc. - * - * Copyright (C) 2006 Thomas Gleixner - * - * This file is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 or (at your option) any - * later version. - * - * This file is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - * As a special exception, if other files instantiate templates or use - * macros or inline functions from these files, or you compile these - * files and link them with other works to produce a work based on these - * files, these files do not by themselves cause the resulting work to be - * covered by the GNU General Public License. However the source code for - * these files must still be made available in accordance with section (3) - * of the GNU General Public License. - * - * This exception does not invalidate any other reasons why a work based on - * this file might be covered by the GNU General Public License. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "core.h" - -/* - * Pre-calculated 256-way 1 byte column parity - */ -static const uint8_t nand_ecc_precalc_table[] = { - 0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a, 0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00, - 0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f, 0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65, - 0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c, 0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66, - 0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59, 0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03, - 0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33, 0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69, - 0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56, 0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c, - 0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55, 0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f, - 0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30, 0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a, - 0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30, 0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a, - 0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55, 0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f, - 0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56, 0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c, - 0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33, 0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69, - 0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59, 0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03, - 0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c, 0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66, - 0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f, 0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65, - 0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a, 0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00 -}; - -/* - * nand_calculate_ecc - Calculate 3-byte ECC for 256-byte block - */ -int nand_calculate_ecc(struct nand_device *nand, const uint8_t *dat, uint8_t *ecc_code) -{ - uint8_t idx, reg1, reg2, reg3, tmp1, tmp2; - int i; - - /* Initialize variables */ - reg1 = reg2 = reg3 = 0; - - /* Build up column parity */ - for (i = 0; i < 256; i++) { - /* Get CP0 - CP5 from table */ - idx = nand_ecc_precalc_table[*dat++]; - reg1 ^= (idx & 0x3f); - - /* All bit XOR = 1 ? */ - if (idx & 0x40) { - reg3 ^= (uint8_t) i; - reg2 ^= ~((uint8_t) i); - } - } - - /* Create non-inverted ECC code from line parity */ - tmp1 = (reg3 & 0x80) >> 0; /* B7 -> B7 */ - tmp1 |= (reg2 & 0x80) >> 1; /* B7 -> B6 */ - tmp1 |= (reg3 & 0x40) >> 1; /* B6 -> B5 */ - tmp1 |= (reg2 & 0x40) >> 2; /* B6 -> B4 */ - tmp1 |= (reg3 & 0x20) >> 2; /* B5 -> B3 */ - tmp1 |= (reg2 & 0x20) >> 3; /* B5 -> B2 */ - tmp1 |= (reg3 & 0x10) >> 3; /* B4 -> B1 */ - tmp1 |= (reg2 & 0x10) >> 4; /* B4 -> B0 */ - - tmp2 = (reg3 & 0x08) << 4; /* B3 -> B7 */ - tmp2 |= (reg2 & 0x08) << 3; /* B3 -> B6 */ - tmp2 |= (reg3 & 0x04) << 3; /* B2 -> B5 */ - tmp2 |= (reg2 & 0x04) << 2; /* B2 -> B4 */ - tmp2 |= (reg3 & 0x02) << 2; /* B1 -> B3 */ - tmp2 |= (reg2 & 0x02) << 1; /* B1 -> B2 */ - tmp2 |= (reg3 & 0x01) << 1; /* B0 -> B1 */ - tmp2 |= (reg2 & 0x01) << 0; /* B7 -> B0 */ - - /* Calculate final ECC code */ -#ifdef NAND_ECC_SMC - ecc_code[0] = ~tmp2; - ecc_code[1] = ~tmp1; -#else - ecc_code[0] = ~tmp1; - ecc_code[1] = ~tmp2; -#endif - ecc_code[2] = ((~reg1) << 2) | 0x03; - - return 0; -} - -static inline int countbits(uint32_t b) -{ - int res = 0; - - for (; b; b >>= 1) - res += b & 0x01; - return res; -} - -/** - * nand_correct_data - Detect and correct a 1 bit error for 256 byte block - */ -int nand_correct_data(struct nand_device *nand, u_char *dat, - u_char *read_ecc, u_char *calc_ecc) -{ - uint8_t s0, s1, s2; - -#ifdef NAND_ECC_SMC - s0 = calc_ecc[0] ^ read_ecc[0]; - s1 = calc_ecc[1] ^ read_ecc[1]; - s2 = calc_ecc[2] ^ read_ecc[2]; -#else - s1 = calc_ecc[0] ^ read_ecc[0]; - s0 = calc_ecc[1] ^ read_ecc[1]; - s2 = calc_ecc[2] ^ read_ecc[2]; -#endif - if ((s0 | s1 | s2) == 0) - return 0; - - /* Check for a single bit error */ - if (((s0 ^ (s0 >> 1)) & 0x55) == 0x55 && - ((s1 ^ (s1 >> 1)) & 0x55) == 0x55 && - ((s2 ^ (s2 >> 1)) & 0x54) == 0x54) { - - uint32_t byteoffs, bitnum; - - byteoffs = (s1 << 0) & 0x80; - byteoffs |= (s1 << 1) & 0x40; - byteoffs |= (s1 << 2) & 0x20; - byteoffs |= (s1 << 3) & 0x10; - - byteoffs |= (s0 >> 4) & 0x08; - byteoffs |= (s0 >> 3) & 0x04; - byteoffs |= (s0 >> 2) & 0x02; - byteoffs |= (s0 >> 1) & 0x01; - - bitnum = (s2 >> 5) & 0x04; - bitnum |= (s2 >> 4) & 0x02; - bitnum |= (s2 >> 3) & 0x01; - - dat[byteoffs] ^= (1 << bitnum); - - return 1; - } - - if (countbits(s0 | ((uint32_t)s1 << 8) | ((uint32_t)s2 << 16)) == 1) - return 1; - - return -1; -} diff --git a/src/flash/nand/ecc_kw.c b/src/flash/nand/ecc_kw.c deleted file mode 100644 index fb3481d00..000000000 --- a/src/flash/nand/ecc_kw.c +++ /dev/null @@ -1,174 +0,0 @@ -/* - * Reed-Solomon ECC handling for the Marvell Kirkwood SOC - * Copyright (C) 2009 Marvell Semiconductor, Inc. - * - * Authors: Lennert Buytenhek - * Nicolas Pitre - * - * This file is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 or (at your option) any - * later version. - * - * This file is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "core.h" - -/***************************************************************************** - * Arithmetic in GF(2^10) ("F") modulo x^10 + x^3 + 1. - * - * For multiplication, a discrete log/exponent table is used, with - * primitive element x (F is a primitive field, so x is primitive). - */ -#define MODPOLY 0x409 /* x^10 + x^3 + 1 in binary */ - -/* - * Maps an integer a [0..1022] to a polynomial b = gf_exp[a] in - * GF(2^10) mod x^10 + x^3 + 1 such that b = x ^ a. There's two - * identical copies of this array back-to-back so that we can save - * the mod 1023 operation when doing a GF multiplication. - */ -static uint16_t gf_exp[1023 + 1023]; - -/* - * Maps a polynomial b in GF(2^10) mod x^10 + x^3 + 1 to an index - * a = gf_log[b] in [0..1022] such that b = x ^ a. - */ -static uint16_t gf_log[1024]; - -static void gf_build_log_exp_table(void) -{ - int i; - int p_i; - - /* - * p_i = x ^ i - * - * Initialise to 1 for i = 0. - */ - p_i = 1; - - for (i = 0; i < 1023; i++) { - gf_exp[i] = p_i; - gf_exp[i + 1023] = p_i; - gf_log[p_i] = i; - - /* - * p_i = p_i * x - */ - p_i <<= 1; - if (p_i & (1 << 10)) - p_i ^= MODPOLY; - } -} - - -/***************************************************************************** - * Reed-Solomon code - * - * This implements a (1023,1015) Reed-Solomon ECC code over GF(2^10) - * mod x^10 + x^3 + 1, shortened to (520,512). The ECC data consists - * of 8 10-bit symbols, or 10 8-bit bytes. - * - * Given 512 bytes of data, computes 10 bytes of ECC. - * - * This is done by converting the 512 bytes to 512 10-bit symbols - * (elements of F), interpreting those symbols as a polynomial in F[X] - * by taking symbol 0 as the coefficient of X^8 and symbol 511 as the - * coefficient of X^519, and calculating the residue of that polynomial - * divided by the generator polynomial, which gives us the 8 ECC symbols - * as the remainder. Finally, we convert the 8 10-bit ECC symbols to 10 - * 8-bit bytes. - * - * The generator polynomial is hardcoded, as that is faster, but it - * can be computed by taking the primitive element a = x (in F), and - * constructing a polynomial in F[X] with roots a, a^2, a^3, ..., a^8 - * by multiplying the minimal polynomials for those roots (which are - * just 'x - a^i' for each i). - * - * Note: due to unfortunate circumstances, the bootrom in the Kirkwood SOC - * expects the ECC to be computed backward, i.e. from the last byte down - * to the first one. - */ -int nand_calculate_ecc_kw(struct nand_device *nand, const uint8_t *data, uint8_t *ecc) -{ - unsigned int r7, r6, r5, r4, r3, r2, r1, r0; - int i; - static int tables_initialized; - - if (!tables_initialized) { - gf_build_log_exp_table(); - tables_initialized = 1; - } - - /* - * Load bytes 504..511 of the data into r. - */ - r0 = data[504]; - r1 = data[505]; - r2 = data[506]; - r3 = data[507]; - r4 = data[508]; - r5 = data[509]; - r6 = data[510]; - r7 = data[511]; - - /* - * Shift bytes 503..0 (in that order) into r0, followed - * by eight zero bytes, while reducing the polynomial by the - * generator polynomial in every step. - */ - for (i = 503; i >= -8; i--) { - unsigned int d; - - d = 0; - if (i >= 0) - d = data[i]; - - if (r7) { - uint16_t *t = gf_exp + gf_log[r7]; - - r7 = r6 ^ t[0x21c]; - r6 = r5 ^ t[0x181]; - r5 = r4 ^ t[0x18e]; - r4 = r3 ^ t[0x25f]; - r3 = r2 ^ t[0x197]; - r2 = r1 ^ t[0x193]; - r1 = r0 ^ t[0x237]; - r0 = d ^ t[0x024]; - } else { - r7 = r6; - r6 = r5; - r5 = r4; - r4 = r3; - r3 = r2; - r2 = r1; - r1 = r0; - r0 = d; - } - } - - ecc[0] = r0; - ecc[1] = (r0 >> 8) | (r1 << 2); - ecc[2] = (r1 >> 6) | (r2 << 4); - ecc[3] = (r2 >> 4) | (r3 << 6); - ecc[4] = (r3 >> 2); - ecc[5] = r4; - ecc[6] = (r4 >> 8) | (r5 << 2); - ecc[7] = (r5 >> 6) | (r6 << 4); - ecc[8] = (r6 >> 4) | (r7 << 6); - ecc[9] = (r7 >> 2); - - return 0; -} diff --git a/src/flash/nand/fileio.c b/src/flash/nand/fileio.c deleted file mode 100644 index 64c32c0a8..000000000 --- a/src/flash/nand/fileio.c +++ /dev/null @@ -1,226 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Dominic Rath * - * Copyright (C) 2002 Thomas Gleixner * - * Copyright (C) 2009 Zachary T Welch * - * * - * Partially based on drivers/mtd/nand_ids.c from Linux. * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "core.h" -#include "fileio.h" - -static struct nand_ecclayout nand_oob_16 = { - .eccbytes = 6, - .eccpos = {0, 1, 2, 3, 6, 7}, - .oobfree = { - {.offset = 8, - .length = 8} - } -}; - -static struct nand_ecclayout nand_oob_64 = { - .eccbytes = 24, - .eccpos = { - 40, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, - 56, 57, 58, 59, 60, 61, 62, 63 - }, - .oobfree = { - {.offset = 2, - .length = 38} - } -}; - -void nand_fileio_init(struct nand_fileio_state *state) -{ - memset(state, 0, sizeof(*state)); - state->oob_format = NAND_OOB_NONE; -} - -int nand_fileio_start(struct command_context *cmd_ctx, - struct nand_device *nand, const char *filename, int filemode, - struct nand_fileio_state *state) -{ - if (state->address % nand->page_size) { - command_print(cmd_ctx, "only page-aligned addresses are supported"); - return ERROR_COMMAND_SYNTAX_ERROR; - } - - duration_start(&state->bench); - - if (NULL != filename) { - int retval = fileio_open(&state->fileio, filename, filemode, FILEIO_BINARY); - if (ERROR_OK != retval) { - const char *msg = (FILEIO_READ == filemode) ? "read" : "write"; - command_print(cmd_ctx, "failed to open '%s' for %s access", - filename, msg); - return retval; - } - state->file_opened = true; - } - - if (!(state->oob_format & NAND_OOB_ONLY)) { - state->page_size = nand->page_size; - state->page = malloc(nand->page_size); - } - - if (state->oob_format & (NAND_OOB_RAW | NAND_OOB_SW_ECC | NAND_OOB_SW_ECC_KW)) { - if (nand->page_size == 512) { - state->oob_size = 16; - state->eccpos = nand_oob_16.eccpos; - } else if (nand->page_size == 2048) { - state->oob_size = 64; - state->eccpos = nand_oob_64.eccpos; - } - state->oob = malloc(state->oob_size); - } - - return ERROR_OK; -} -int nand_fileio_cleanup(struct nand_fileio_state *state) -{ - if (state->file_opened) - fileio_close(state->fileio); - - if (state->oob) { - free(state->oob); - state->oob = NULL; - } - if (state->page) { - free(state->page); - state->page = NULL; - } - return ERROR_OK; -} -int nand_fileio_finish(struct nand_fileio_state *state) -{ - nand_fileio_cleanup(state); - return duration_measure(&state->bench); -} - -COMMAND_HELPER(nand_fileio_parse_args, struct nand_fileio_state *state, - struct nand_device **dev, enum fileio_access filemode, - bool need_size, bool sw_ecc) -{ - nand_fileio_init(state); - - unsigned minargs = need_size ? 4 : 3; - if (CMD_ARGC < minargs) - return ERROR_COMMAND_SYNTAX_ERROR; - - struct nand_device *nand; - int retval = CALL_COMMAND_HANDLER(nand_command_get_device, 0, &nand); - if (ERROR_OK != retval) - return retval; - - if (NULL == nand->device) { - command_print(CMD_CTX, "#%s: not probed", CMD_ARGV[0]); - return ERROR_NAND_DEVICE_NOT_PROBED; - } - - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], state->address); - if (need_size) { - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[3], state->size); - if (state->size % nand->page_size) { - command_print(CMD_CTX, "only page-aligned sizes are supported"); - return ERROR_COMMAND_SYNTAX_ERROR; - } - } - - if (CMD_ARGC > minargs) { - for (unsigned i = minargs; i < CMD_ARGC; i++) { - if (!strcmp(CMD_ARGV[i], "oob_raw")) - state->oob_format |= NAND_OOB_RAW; - else if (!strcmp(CMD_ARGV[i], "oob_only")) - state->oob_format |= NAND_OOB_RAW | NAND_OOB_ONLY; - else if (sw_ecc && !strcmp(CMD_ARGV[i], "oob_softecc")) - state->oob_format |= NAND_OOB_SW_ECC; - else if (sw_ecc && !strcmp(CMD_ARGV[i], "oob_softecc_kw")) - state->oob_format |= NAND_OOB_SW_ECC_KW; - else { - command_print(CMD_CTX, "unknown option: %s", CMD_ARGV[i]); - return ERROR_COMMAND_SYNTAX_ERROR; - } - } - } - - retval = nand_fileio_start(CMD_CTX, nand, CMD_ARGV[1], filemode, state); - if (ERROR_OK != retval) - return retval; - - if (!need_size) { - size_t filesize; - retval = fileio_size(state->fileio, &filesize); - if (retval != ERROR_OK) - return retval; - state->size = filesize; - } - - *dev = nand; - - return ERROR_OK; -} - -/** - * @returns If no error occurred, returns number of bytes consumed; - * otherwise, returns a negative error code.) - */ -int nand_fileio_read(struct nand_device *nand, struct nand_fileio_state *s) -{ - size_t total_read = 0; - size_t one_read; - - if (NULL != s->page) { - 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; - } - - if (s->oob_format & NAND_OOB_SW_ECC) { - uint8_t ecc[3]; - memset(s->oob, 0xff, s->oob_size); - for (uint32_t i = 0, j = 0; i < s->page_size; i += 256) { - nand_calculate_ecc(nand, s->page + i, ecc); - s->oob[s->eccpos[j++]] = ecc[0]; - s->oob[s->eccpos[j++]] = ecc[1]; - s->oob[s->eccpos[j++]] = ecc[2]; - } - } else if (s->oob_format & NAND_OOB_SW_ECC_KW) { - /* - * In this case eccpos is not used as - * the ECC data is always stored contigously - * at the end of the OOB area. It consists - * of 10 bytes per 512-byte data block. - */ - uint8_t *ecc = s->oob + s->oob_size - s->page_size / 512 * 10; - memset(s->oob, 0xff, s->oob_size); - for (uint32_t i = 0; i < s->page_size; i += 512) { - nand_calculate_ecc_kw(nand, s->page + i, ecc); - ecc += 10; - } - } else if (NULL != s->oob) { - 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; - } - return total_read; -} diff --git a/src/flash/nand/fileio.h b/src/flash/nand/fileio.h deleted file mode 100644 index af6c7666e..000000000 --- a/src/flash/nand/fileio.h +++ /dev/null @@ -1,56 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2009 Zachary T Welch * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 OPENOCD_FLASH_NAND_FILEIO_H -#define OPENOCD_FLASH_NAND_FILEIO_H - -#include -#include - -struct nand_fileio_state { - uint32_t address; - uint32_t size; - - uint8_t *page; - uint32_t page_size; - - enum oob_formats oob_format; - uint8_t *oob; - uint32_t oob_size; - - const int *eccpos; - - bool file_opened; - struct fileio *fileio; - - struct duration bench; -}; - -void nand_fileio_init(struct nand_fileio_state *state); -int nand_fileio_start(struct command_context *cmd_ctx, - struct nand_device *nand, const char *filename, int filemode, - struct nand_fileio_state *state); -int nand_fileio_cleanup(struct nand_fileio_state *state); -int nand_fileio_finish(struct nand_fileio_state *state); - -COMMAND_HELPER(nand_fileio_parse_args, struct nand_fileio_state *state, - struct nand_device **dev, enum fileio_access filemode, - bool need_size, bool sw_ecc); - -int nand_fileio_read(struct nand_device *nand, struct nand_fileio_state *s); - -#endif /* OPENOCD_FLASH_NAND_FILEIO_H */ diff --git a/src/flash/nand/imp.h b/src/flash/nand/imp.h deleted file mode 100644 index c8a4ed9c5..000000000 --- a/src/flash/nand/imp.h +++ /dev/null @@ -1,38 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2009 Zachary T Welch * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 OPENOCD_FLASH_NAND_IMP_H -#define OPENOCD_FLASH_NAND_IMP_H - -#include "core.h" -#include "driver.h" - -void nand_device_add(struct nand_device *c); - -int nand_write_page(struct nand_device *nand, - uint32_t page, uint8_t *data, uint32_t data_size, - uint8_t *oob, uint32_t oob_size); - -int nand_read_page(struct nand_device *nand, uint32_t page, - uint8_t *data, uint32_t data_size, - uint8_t *oob, uint32_t oob_size); - -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 /* OPENOCD_FLASH_NAND_IMP_H */ diff --git a/src/flash/nand/lpc3180.c b/src/flash/nand/lpc3180.c deleted file mode 100644 index d15fdce38..000000000 --- a/src/flash/nand/lpc3180.c +++ /dev/null @@ -1,1359 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Dominic Rath * - * Dominic.Rath@gmx.de * - * - * Copyright (C) 2010 richard vegh * - * Copyright (C) 2010 Oyvind Harboe * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "imp.h" -#include "lpc3180.h" -#include - -static int lpc3180_reset(struct nand_device *nand); -static int lpc3180_controller_ready(struct nand_device *nand, int timeout); -static int lpc3180_tc_ready(struct nand_device *nand, int timeout); - -#define ECC_OFFS 0x120 -#define SPARE_OFFS 0x140 -#define DATA_OFFS 0x200 - -/* nand device lpc3180 - */ -NAND_DEVICE_COMMAND_HANDLER(lpc3180_nand_device_command) -{ - if (CMD_ARGC < 3) - return ERROR_COMMAND_SYNTAX_ERROR; - - uint32_t osc_freq; - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], osc_freq); - - struct lpc3180_nand_controller *lpc3180_info; - lpc3180_info = malloc(sizeof(struct lpc3180_nand_controller)); - nand->controller_priv = lpc3180_info; - - lpc3180_info->osc_freq = osc_freq; - - if ((lpc3180_info->osc_freq < 1000) || (lpc3180_info->osc_freq > 20000)) - LOG_WARNING( - "LPC3180 oscillator frequency should be between 1000 and 20000 kHz, was %i", - lpc3180_info->osc_freq); - lpc3180_info->selected_controller = LPC3180_NO_CONTROLLER; - lpc3180_info->sw_write_protection = 0; - lpc3180_info->sw_wp_lower_bound = 0x0; - lpc3180_info->sw_wp_upper_bound = 0x0; - - return ERROR_OK; -} - -static int lpc3180_pll(int fclkin, uint32_t pll_ctrl) -{ - int bypass = (pll_ctrl & 0x8000) >> 15; - int direct = (pll_ctrl & 0x4000) >> 14; - int feedback = (pll_ctrl & 0x2000) >> 13; - int p = (1 << ((pll_ctrl & 0x1800) >> 11) * 2); - int n = ((pll_ctrl & 0x0600) >> 9) + 1; - int m = ((pll_ctrl & 0x01fe) >> 1) + 1; - int lock = (pll_ctrl & 0x1); - - if (!lock) - LOG_WARNING("PLL is not locked"); - - if (!bypass && direct) /* direct mode */ - return (m * fclkin) / n; - - if (bypass && !direct) /* bypass mode */ - return fclkin / (2 * p); - - if (bypass & direct) /* direct bypass mode */ - return fclkin; - - if (feedback) /* integer mode */ - return m * (fclkin / n); - else /* non-integer mode */ - return (m / (2 * p)) * (fclkin / n); -} - -static float lpc3180_cycle_time(struct nand_device *nand) -{ - struct lpc3180_nand_controller *lpc3180_info = nand->controller_priv; - struct target *target = nand->target; - uint32_t sysclk_ctrl, pwr_ctrl, hclkdiv_ctrl, hclkpll_ctrl; - int sysclk; - int hclk; - int hclk_pll; - float cycle; - - /* calculate timings */ - - /* determine current SYSCLK (13'MHz or main oscillator) */ - target_read_u32(target, 0x40004050, &sysclk_ctrl); - - if ((sysclk_ctrl & 1) == 0) - sysclk = lpc3180_info->osc_freq; - else - sysclk = 13000; - - /* determine selected HCLK source */ - target_read_u32(target, 0x40004044, &pwr_ctrl); - - if ((pwr_ctrl & (1 << 2)) == 0) /* DIRECT RUN mode */ - hclk = sysclk; - else { - target_read_u32(target, 0x40004058, &hclkpll_ctrl); - hclk_pll = lpc3180_pll(sysclk, hclkpll_ctrl); - - target_read_u32(target, 0x40004040, &hclkdiv_ctrl); - - if (pwr_ctrl & (1 << 10)) /* ARM_CLK and HCLK use PERIPH_CLK */ - hclk = hclk_pll / (((hclkdiv_ctrl & 0x7c) >> 2) + 1); - else /* HCLK uses HCLK_PLL */ - hclk = hclk_pll / (1 << (hclkdiv_ctrl & 0x3)); - } - - LOG_DEBUG("LPC3180 HCLK currently clocked at %i kHz", hclk); - - cycle = (1.0 / hclk) * 1000000.0; - - return cycle; -} - -static int lpc3180_init(struct nand_device *nand) -{ - struct lpc3180_nand_controller *lpc3180_info = nand->controller_priv; - struct target *target = nand->target; - int bus_width = nand->bus_width ? : 8; - int address_cycles = nand->address_cycles ? : 3; - int page_size = nand->page_size ? : 512; - - if (target->state != TARGET_HALTED) { - LOG_ERROR("target must be halted to use LPC3180 NAND flash controller"); - return ERROR_NAND_OPERATION_FAILED; - } - - /* sanitize arguments */ - if ((bus_width != 8) && (bus_width != 16)) { - LOG_ERROR("LPC3180 only supports 8 or 16 bit bus width, not %i", bus_width); - return ERROR_NAND_OPERATION_NOT_SUPPORTED; - } - - /* The LPC3180 only brings out 8 bit NAND data bus, but the controller - * would support 16 bit, too, so we just warn about this for now - */ - if (bus_width == 16) - LOG_WARNING("LPC3180 only supports 8 bit bus width"); - - /* inform calling code about selected bus width */ - nand->bus_width = bus_width; - - if ((address_cycles != 3) && (address_cycles != 4)) { - LOG_ERROR("LPC3180 only supports 3 or 4 address cycles, not %i", address_cycles); - return ERROR_NAND_OPERATION_NOT_SUPPORTED; - } - - if ((page_size != 512) && (page_size != 2048)) { - LOG_ERROR("LPC3180 only supports 512 or 2048 byte pages, not %i", page_size); - return ERROR_NAND_OPERATION_NOT_SUPPORTED; - } - - /* select MLC controller if none is currently selected */ - if (lpc3180_info->selected_controller == LPC3180_NO_CONTROLLER) { - LOG_DEBUG("no LPC3180 NAND flash controller selected, using default 'mlc'"); - lpc3180_info->selected_controller = LPC3180_MLC_CONTROLLER; - } - - if (lpc3180_info->selected_controller == LPC3180_MLC_CONTROLLER) { - uint32_t mlc_icr_value = 0x0; - float cycle; - int twp, twh, trp, treh, trhz, trbwb, tcea; - - /* FLASHCLK_CTRL = 0x22 (enable clock for MLC flash controller) */ - target_write_u32(target, 0x400040c8, 0x22); - - /* MLC_CEH = 0x0 (Force nCE assert) */ - target_write_u32(target, 0x200b804c, 0x0); - - /* MLC_LOCK = 0xa25e (unlock protected registers) */ - target_write_u32(target, 0x200b8044, 0xa25e); - - /* MLC_ICR = configuration */ - if (lpc3180_info->sw_write_protection) - mlc_icr_value |= 0x8; - if (page_size == 2048) - mlc_icr_value |= 0x4; - if (address_cycles == 4) - mlc_icr_value |= 0x2; - if (bus_width == 16) - mlc_icr_value |= 0x1; - target_write_u32(target, 0x200b8030, mlc_icr_value); - - /* calculate NAND controller timings */ - cycle = lpc3180_cycle_time(nand); - - twp = ((40 / cycle) + 1); - twh = ((20 / cycle) + 1); - trp = ((30 / cycle) + 1); - treh = ((15 / cycle) + 1); - trhz = ((30 / cycle) + 1); - trbwb = ((100 / cycle) + 1); - tcea = ((45 / cycle) + 1); - - /* MLC_LOCK = 0xa25e (unlock protected registers) */ - target_write_u32(target, 0x200b8044, 0xa25e); - - /* MLC_TIME_REG */ - target_write_u32(target, 0x200b8034, (twp & 0xf) | ((twh & 0xf) << 4) | - ((trp & 0xf) << 8) | ((treh & 0xf) << 12) | ((trhz & 0x7) << 16) | - ((trbwb & 0x1f) << 19) | ((tcea & 0x3) << 24)); - - lpc3180_reset(nand); - } else if (lpc3180_info->selected_controller == LPC3180_SLC_CONTROLLER) { - float cycle; - int r_setup, r_hold, r_width, r_rdy; - int w_setup, w_hold, w_width, w_rdy; - - /* FLASHCLK_CTRL = 0x05 (enable clock for SLC flash controller) */ - target_write_u32(target, 0x400040c8, 0x05); - - /* after reset set other registers of SLC so reset calling is here at the begining*/ - lpc3180_reset(nand); - - /* SLC_CFG = 0x (Force nCE assert, DMA ECC enabled, ECC enabled, DMA burst enabled, - *DMA read from SLC, WIDTH = bus_width) */ - target_write_u32(target, 0x20020014, 0x3e | (bus_width == 16) ? 1 : 0); - - /* SLC_IEN = 3 (INT_RDY_EN = 1) ,(INT_TC_STAT = 1) */ - target_write_u32(target, 0x20020020, 0x03); - - /* DMA configuration - * DMACLK_CTRL = 0x01 (enable clock for DMA controller) */ - target_write_u32(target, 0x400040e8, 0x01); - /* DMACConfig = DMA enabled*/ - target_write_u32(target, 0x31000030, 0x01); - - - /* calculate NAND controller timings */ - cycle = lpc3180_cycle_time(nand); - - r_setup = w_setup = 0; - r_hold = w_hold = 10 / cycle; - r_width = 30 / cycle; - w_width = 40 / cycle; - r_rdy = w_rdy = 100 / cycle; - - /* SLC_TAC: SLC timing arcs register */ - target_write_u32(target, 0x2002002c, (r_setup & 0xf) | ((r_hold & 0xf) << 4) | - ((r_width & 0xf) << 8) | ((r_rdy & 0xf) << 12) | ((w_setup & 0xf) << 16) | - ((w_hold & 0xf) << 20) | ((w_width & 0xf) << 24) | ((w_rdy & 0xf) << 28)); - - } - - return ERROR_OK; -} - -static int lpc3180_reset(struct nand_device *nand) -{ - struct lpc3180_nand_controller *lpc3180_info = nand->controller_priv; - struct target *target = nand->target; - - if (target->state != TARGET_HALTED) { - LOG_ERROR("target must be halted to use LPC3180 NAND flash controller"); - return ERROR_NAND_OPERATION_FAILED; - } - - if (lpc3180_info->selected_controller == LPC3180_NO_CONTROLLER) { - LOG_ERROR("BUG: no LPC3180 NAND flash controller selected"); - return ERROR_NAND_OPERATION_FAILED; - } else if (lpc3180_info->selected_controller == LPC3180_MLC_CONTROLLER) { - /* MLC_CMD = 0xff (reset controller and NAND device) */ - target_write_u32(target, 0x200b8000, 0xff); - - if (!lpc3180_controller_ready(nand, 100)) { - LOG_ERROR("LPC3180 NAND controller timed out after reset"); - return ERROR_NAND_OPERATION_TIMEOUT; - } - } else if (lpc3180_info->selected_controller == LPC3180_SLC_CONTROLLER) { - /* SLC_CTRL = 0x6 (ECC_CLEAR, SW_RESET) */ - target_write_u32(target, 0x20020010, 0x6); - - if (!lpc3180_controller_ready(nand, 100)) { - LOG_ERROR("LPC3180 NAND controller timed out after reset"); - return ERROR_NAND_OPERATION_TIMEOUT; - } - } - - return ERROR_OK; -} - -static int lpc3180_command(struct nand_device *nand, uint8_t command) -{ - struct lpc3180_nand_controller *lpc3180_info = nand->controller_priv; - struct target *target = nand->target; - - if (target->state != TARGET_HALTED) { - LOG_ERROR("target must be halted to use LPC3180 NAND flash controller"); - return ERROR_NAND_OPERATION_FAILED; - } - - if (lpc3180_info->selected_controller == LPC3180_NO_CONTROLLER) { - LOG_ERROR("BUG: no LPC3180 NAND flash controller selected"); - return ERROR_NAND_OPERATION_FAILED; - } else if (lpc3180_info->selected_controller == LPC3180_MLC_CONTROLLER) { - /* MLC_CMD = command */ - target_write_u32(target, 0x200b8000, command); - } else if (lpc3180_info->selected_controller == LPC3180_SLC_CONTROLLER) { - /* SLC_CMD = command */ - target_write_u32(target, 0x20020008, command); - } - - return ERROR_OK; -} - -static int lpc3180_address(struct nand_device *nand, uint8_t address) -{ - struct lpc3180_nand_controller *lpc3180_info = nand->controller_priv; - struct target *target = nand->target; - - if (target->state != TARGET_HALTED) { - LOG_ERROR("target must be halted to use LPC3180 NAND flash controller"); - return ERROR_NAND_OPERATION_FAILED; - } - - if (lpc3180_info->selected_controller == LPC3180_NO_CONTROLLER) { - LOG_ERROR("BUG: no LPC3180 NAND flash controller selected"); - return ERROR_NAND_OPERATION_FAILED; - } else if (lpc3180_info->selected_controller == LPC3180_MLC_CONTROLLER) { - /* MLC_ADDR = address */ - target_write_u32(target, 0x200b8004, address); - } else if (lpc3180_info->selected_controller == LPC3180_SLC_CONTROLLER) { - /* SLC_ADDR = address */ - target_write_u32(target, 0x20020004, address); - } - - return ERROR_OK; -} - -static int lpc3180_write_data(struct nand_device *nand, uint16_t data) -{ - struct lpc3180_nand_controller *lpc3180_info = nand->controller_priv; - struct target *target = nand->target; - - if (target->state != TARGET_HALTED) { - LOG_ERROR("target must be halted to use LPC3180 NAND flash controller"); - return ERROR_NAND_OPERATION_FAILED; - } - - if (lpc3180_info->selected_controller == LPC3180_NO_CONTROLLER) { - LOG_ERROR("BUG: no LPC3180 NAND flash controller selected"); - return ERROR_NAND_OPERATION_FAILED; - } else if (lpc3180_info->selected_controller == LPC3180_MLC_CONTROLLER) { - /* MLC_DATA = data */ - target_write_u32(target, 0x200b0000, data); - } else if (lpc3180_info->selected_controller == LPC3180_SLC_CONTROLLER) { - /* SLC_DATA = data */ - target_write_u32(target, 0x20020000, data); - } - - return ERROR_OK; -} - -static int lpc3180_read_data(struct nand_device *nand, void *data) -{ - struct lpc3180_nand_controller *lpc3180_info = nand->controller_priv; - struct target *target = nand->target; - - if (target->state != TARGET_HALTED) { - LOG_ERROR("target must be halted to use LPC3180 NAND flash controller"); - return ERROR_NAND_OPERATION_FAILED; - } - - if (lpc3180_info->selected_controller == LPC3180_NO_CONTROLLER) { - LOG_ERROR("BUG: no LPC3180 NAND flash controller selected"); - return ERROR_NAND_OPERATION_FAILED; - } else if (lpc3180_info->selected_controller == LPC3180_MLC_CONTROLLER) { - /* data = MLC_DATA, use sized access */ - if (nand->bus_width == 8) { - uint8_t *data8 = data; - target_read_u8(target, 0x200b0000, data8); - } else if (nand->bus_width == 16) { - uint16_t *data16 = data; - target_read_u16(target, 0x200b0000, data16); - } else { - LOG_ERROR("BUG: bus_width neither 8 nor 16 bit"); - return ERROR_NAND_OPERATION_FAILED; - } - } else if (lpc3180_info->selected_controller == LPC3180_SLC_CONTROLLER) { - uint32_t data32; - - /* data = SLC_DATA, must use 32-bit access */ - target_read_u32(target, 0x20020000, &data32); - - if (nand->bus_width == 8) { - uint8_t *data8 = data; - *data8 = data32 & 0xff; - } else if (nand->bus_width == 16) { - uint16_t *data16 = data; - *data16 = data32 & 0xffff; - } else { - LOG_ERROR("BUG: bus_width neither 8 nor 16 bit"); - return ERROR_NAND_OPERATION_FAILED; - } - } - - return ERROR_OK; -} - -static int lpc3180_write_page(struct nand_device *nand, - uint32_t page, - uint8_t *data, - uint32_t data_size, - uint8_t *oob, - uint32_t oob_size) -{ - struct lpc3180_nand_controller *lpc3180_info = nand->controller_priv; - struct target *target = nand->target; - int retval; - uint8_t status; - uint8_t *page_buffer; - - if (target->state != TARGET_HALTED) { - LOG_ERROR("target must be halted to use LPC3180 NAND flash controller"); - return ERROR_NAND_OPERATION_FAILED; - } - - if (lpc3180_info->selected_controller == LPC3180_NO_CONTROLLER) { - LOG_ERROR("BUG: no LPC3180 NAND flash controller selected"); - return ERROR_NAND_OPERATION_FAILED; - } else if (lpc3180_info->selected_controller == LPC3180_MLC_CONTROLLER) { - uint8_t *oob_buffer; - int quarter, num_quarters; - - if (!data && oob) { - LOG_ERROR("LPC3180 MLC controller can't write OOB data only"); - return ERROR_NAND_OPERATION_NOT_SUPPORTED; - } - - if (oob && (oob_size > 24)) { - LOG_ERROR("LPC3180 MLC controller can't write more " - "than 6 bytes for each quarter's OOB data"); - return ERROR_NAND_OPERATION_NOT_SUPPORTED; - } - - if (data_size > (uint32_t)nand->page_size) { - LOG_ERROR("data size exceeds page size"); - return ERROR_NAND_OPERATION_NOT_SUPPORTED; - } - - /* MLC_CMD = sequential input */ - target_write_u32(target, 0x200b8000, NAND_CMD_SEQIN); - - page_buffer = malloc(512); - oob_buffer = malloc(6); - - if (nand->page_size == 512) { - /* MLC_ADDR = 0x0 (one column cycle) */ - target_write_u32(target, 0x200b8004, 0x0); - - /* MLC_ADDR = row */ - target_write_u32(target, 0x200b8004, page & 0xff); - target_write_u32(target, 0x200b8004, (page >> 8) & 0xff); - - if (nand->address_cycles == 4) - target_write_u32(target, 0x200b8004, (page >> 16) & 0xff); - } else { - /* MLC_ADDR = 0x0 (two column cycles) */ - target_write_u32(target, 0x200b8004, 0x0); - target_write_u32(target, 0x200b8004, 0x0); - - /* MLC_ADDR = row */ - target_write_u32(target, 0x200b8004, page & 0xff); - target_write_u32(target, 0x200b8004, (page >> 8) & 0xff); - } - - /* when using the MLC controller, we have to treat a large page device - * as being made out of four quarters, each the size of a small page device - */ - num_quarters = (nand->page_size == 2048) ? 4 : 1; - - for (quarter = 0; quarter < num_quarters; quarter++) { - int thisrun_data_size = (data_size > 512) ? 512 : data_size; - int thisrun_oob_size = (oob_size > 6) ? 6 : oob_size; - - memset(page_buffer, 0xff, 512); - if (data) { - memcpy(page_buffer, data, thisrun_data_size); - data_size -= thisrun_data_size; - data += thisrun_data_size; - } - - memset(oob_buffer, 0xff, 6); - if (oob) { - memcpy(oob_buffer, oob, thisrun_oob_size); - oob_size -= thisrun_oob_size; - oob += thisrun_oob_size; - } - - /* write MLC_ECC_ENC_REG to start encode cycle */ - target_write_u32(target, 0x200b8008, 0x0); - - target_write_memory(target, 0x200a8000, - 4, 128, page_buffer); - target_write_memory(target, 0x200a8000, - 1, 6, oob_buffer); - - /* write MLC_ECC_AUTO_ENC_REG to start auto encode */ - target_write_u32(target, 0x200b8010, 0x0); - - if (!lpc3180_controller_ready(nand, 1000)) { - LOG_ERROR("timeout while waiting for completion of auto encode cycle"); - free(page_buffer); - free(oob_buffer); - return ERROR_NAND_OPERATION_FAILED; - } - } - - /* MLC_CMD = auto program command */ - target_write_u32(target, 0x200b8000, NAND_CMD_PAGEPROG); - - retval = nand_read_status(nand, &status); - if (retval != ERROR_OK) { - LOG_ERROR("couldn't read status"); - free(page_buffer); - free(oob_buffer); - return ERROR_NAND_OPERATION_FAILED; - } - - if (status & NAND_STATUS_FAIL) { - LOG_ERROR("write operation didn't pass, status: 0x%2.2x", status); - free(page_buffer); - free(oob_buffer); - return ERROR_NAND_OPERATION_FAILED; - } - - free(page_buffer); - free(oob_buffer); - } else if (lpc3180_info->selected_controller == LPC3180_SLC_CONTROLLER) { - - /********************************************************************** - * Write both SLC NAND flash page main area and spare area. - * Small page - - * ------------------------------------------ - * | 512 bytes main | 16 bytes spare | - * ------------------------------------------ - * Large page - - * ------------------------------------------ - * | 2048 bytes main | 64 bytes spare | - * ------------------------------------------ - * If DMA & ECC enabled, then the ECC generated for the 1st 256-byte - * data is written to the 3rd word of the spare area. The ECC - * generated for the 2nd 256-byte data is written to the 4th word - * of the spare area. The ECC generated for the 3rd 256-byte data is - * written to the 7th word of the spare area. The ECC generated - * for the 4th 256-byte data is written to the 8th word of the - * spare area and so on. - * - **********************************************************************/ - - int i = 0, target_mem_base; - uint8_t *ecc_flash_buffer; - struct working_area *pworking_area; - - if (lpc3180_info->is_bulk) { - - if (!data && oob) { - /*if oob only mode is active original method is used as SLC - *controller hangs during DMA interworking. Anyway the code supports - *the oob only mode below. */ - return nand_write_page_raw(nand, - page, - data, - data_size, - oob, - oob_size); - } - retval = nand_page_command(nand, page, NAND_CMD_SEQIN, !data); - if (ERROR_OK != retval) - return retval; - - /* allocate a working area */ - if (target->working_area_size < (uint32_t) nand->page_size + 0x200) { - LOG_ERROR("Reserve at least 0x%x physical target working area", - nand->page_size + 0x200); - return ERROR_FLASH_OPERATION_FAILED; - } - if (target->working_area_phys%4) { - LOG_ERROR( - "Reserve the physical target working area at word boundary"); - return ERROR_FLASH_OPERATION_FAILED; - } - if (target_alloc_working_area(target, target->working_area_size, - &pworking_area) != ERROR_OK) { - LOG_ERROR("no working area specified, can't read LPC internal flash"); - return ERROR_FLASH_OPERATION_FAILED; - } - target_mem_base = target->working_area_phys; - - if (nand->page_size == 2048) - page_buffer = malloc(2048); - else - page_buffer = malloc(512); - - ecc_flash_buffer = malloc(64); - - /* SLC_CFG = 0x (Force nCE assert, DMA ECC enabled, ECC enabled, DMA burst - *enabled, DMA write to SLC, WIDTH = bus_width) */ - target_write_u32(target, 0x20020014, 0x3c); - - if (data && !oob) { - /* set DMA LLI-s in target memory and in DMA*/ - for (i = 0; i < nand->page_size/0x100; i++) { - - int tmp; - /* -------LLI for 256 byte block--------- - * DMACC0SrcAddr = SRAM */ - target_write_u32(target, - target_mem_base+0+i*32, - target_mem_base+DATA_OFFS+i*256); - if (i == 0) - target_write_u32(target, - 0x31000100, - target_mem_base+DATA_OFFS); - /* DMACCxDestAddr = SLC_DMA_DATA */ - target_write_u32(target, target_mem_base+4+i*32, 0x20020038); - if (i == 0) - target_write_u32(target, 0x31000104, 0x20020038); - /* DMACCxLLI = next element */ - tmp = (target_mem_base+(1+i*2)*16)&0xfffffffc; - target_write_u32(target, target_mem_base+8+i*32, tmp); - if (i == 0) - target_write_u32(target, 0x31000108, tmp); - /* DMACCxControl = TransferSize =64, Source burst size =16, - * Destination burst size = 16, Source transfer width = 32 bit, - * Destination transfer width = 32 bit, Source AHB master select = M0, - * Destination AHB master select = M0, Source increment = 1, - * Destination increment = 0, Terminal count interrupt enable bit = 0*/ - target_write_u32(target, - target_mem_base+12+i*32, - 0x40 | 3<<12 | 3<<15 | 2<<18 | 2<<21 | 0<<24 | 0<<25 | 1<<26 | - 0<<27 | 0<<31); - if (i == 0) - target_write_u32(target, - 0x3100010c, - 0x40 | 3<<12 | 3<<15 | 2<<18 | 2<<21 | 0<<24 | 0<<25 | 1<<26 | - 0<<27 | 0<<31); - - /* -------LLI for 3 byte ECC--------- - * DMACC0SrcAddr = SLC_ECC*/ - target_write_u32(target, target_mem_base+16+i*32, 0x20020034); - /* DMACCxDestAddr = SRAM */ - target_write_u32(target, - target_mem_base+20+i*32, - target_mem_base+SPARE_OFFS+8+16*(i>>1)+(i%2)*4); - /* DMACCxLLI = next element */ - tmp = (target_mem_base+(2+i*2)*16)&0xfffffffc; - target_write_u32(target, target_mem_base+24+i*32, tmp); - /* DMACCxControl = TransferSize =1, Source burst size =4, - * Destination burst size = 4, Source transfer width = 32 bit, - * Destination transfer width = 32 bit, Source AHB master select = M0, - * Destination AHB master select = M0, Source increment = 0, - * Destination increment = 1, Terminal count interrupt enable bit = 0*/ - target_write_u32(target, - target_mem_base+28+i*32, - 0x01 | 1<<12 | 1<<15 | 2<<18 | 2<<21 | 0<<24 | 0<<25 | 0<<26 | 1<<27 | 0<< - 31); - } - } else if (data && oob) { - /* -------LLI for 512 or 2048 bytes page--------- - * DMACC0SrcAddr = SRAM */ - target_write_u32(target, target_mem_base, target_mem_base+DATA_OFFS); - target_write_u32(target, 0x31000100, target_mem_base+DATA_OFFS); - /* DMACCxDestAddr = SLC_DMA_DATA */ - target_write_u32(target, target_mem_base+4, 0x20020038); - target_write_u32(target, 0x31000104, 0x20020038); - /* DMACCxLLI = next element */ - target_write_u32(target, - target_mem_base+8, - (target_mem_base+32)&0xfffffffc); - target_write_u32(target, 0x31000108, - (target_mem_base+32)&0xfffffffc); - /* DMACCxControl = TransferSize =512 or 128, Source burst size =16, - * Destination burst size = 16, Source transfer width = 32 bit, - * Destination transfer width = 32 bit, Source AHB master select = M0, - * Destination AHB master select = M0, Source increment = 1, - * Destination increment = 0, Terminal count interrupt enable bit = 0*/ - target_write_u32(target, - target_mem_base+12, - (nand->page_size == - 2048 ? 512 : 128) | 3<<12 | 3<<15 | 2<<18 | 2<<21 | 0<<24 | 0<<25 | - 1<<26 | 0<<27 | 0<<31); - target_write_u32(target, - 0x3100010c, - (nand->page_size == - 2048 ? 512 : 128) | 3<<12 | 3<<15 | 2<<18 | 2<<21 | 0<<24 | 0<<25 | - 1<<26 | 0<<27 | 0<<31); - i = 1; - } else if (!data && oob) - i = 0; - - /* -------LLI for spare area--------- - * DMACC0SrcAddr = SRAM*/ - target_write_u32(target, target_mem_base+0+i*32, target_mem_base+SPARE_OFFS); - if (i == 0) - target_write_u32(target, 0x31000100, target_mem_base+SPARE_OFFS); - /* DMACCxDestAddr = SLC_DMA_DATA */ - target_write_u32(target, target_mem_base+4+i*32, 0x20020038); - if (i == 0) - target_write_u32(target, 0x31000104, 0x20020038); - /* DMACCxLLI = next element = NULL */ - target_write_u32(target, target_mem_base+8+i*32, 0); - if (i == 0) - target_write_u32(target, 0x31000108, 0); - /* DMACCxControl = TransferSize =16 for large page or 4 for small page, - * Source burst size =16, Destination burst size = 16, Source transfer width = 32 bit, - * Destination transfer width = 32 bit, Source AHB master select = M0, - * Destination AHB master select = M0, Source increment = 1, - * Destination increment = 0, Terminal count interrupt enable bit = 0*/ - target_write_u32(target, - target_mem_base+12+i*32, - (nand->page_size == - 2048 ? 0x10 : 0x04) | 3<<12 | 3<<15 | 2<<18 | 2<<21 | 0<<24 | 0<<25 | 1<<26 | - 0<<27 | 0<<31); - if (i == 0) - target_write_u32(target, 0x3100010c, - (nand->page_size == 2048 ? - 0x10 : 0x04) | 3<<12 | 3<<15 | 2<<18 | 2<<21 | 0<<24 | - 0<<25 | 1<<26 | 0<<27 | 0<<31); - - memset(ecc_flash_buffer, 0xff, 64); - if (oob) - memcpy(ecc_flash_buffer, oob, oob_size); - target_write_memory(target, - target_mem_base+SPARE_OFFS, - 4, - 16, - ecc_flash_buffer); - - if (data) { - memset(page_buffer, 0xff, nand->page_size == 2048 ? 2048 : 512); - memcpy(page_buffer, data, data_size); - target_write_memory(target, - target_mem_base+DATA_OFFS, - 4, - nand->page_size == 2048 ? 512 : 128, - page_buffer); - } - - free(page_buffer); - free(ecc_flash_buffer); - - /* Enable DMA after channel set up ! - LLI only works when DMA is the flow controller! - */ - /* DMACCxConfig= E=1, SrcPeripheral = 1 (SLC), DestPeripheral = 1 (SLC), - *FlowCntrl = 2 (Pher -> Mem, DMA), IE = 0, ITC = 0, L= 0, H=0*/ - target_write_u32(target, - 0x31000110, - 1 | 1<<1 | 1<<6 | 2<<11 | 0<<14 | 0<<15 | 0<<16 | 0<<18); - - /* SLC_CTRL = 3 (START DMA), ECC_CLEAR */ - target_write_u32(target, 0x20020010, 0x3); - - /* SLC_ICR = 2, INT_TC_CLR, clear pending TC*/ - target_write_u32(target, 0x20020028, 2); - - /* SLC_TC */ - if (!data && oob) - target_write_u32(target, 0x20020030, - (nand->page_size == 2048 ? 0x10 : 0x04)); - else - target_write_u32(target, 0x20020030, - (nand->page_size == 2048 ? 0x840 : 0x210)); - - nand_write_finish(nand); - - if (!lpc3180_tc_ready(nand, 1000)) { - LOG_ERROR("timeout while waiting for completion of DMA"); - return ERROR_NAND_OPERATION_FAILED; - } - - target_free_working_area(target, pworking_area); - - LOG_INFO("Page = 0x%" PRIx32 " was written.", page); - - } else - return nand_write_page_raw(nand, page, data, data_size, oob, oob_size); - } - - return ERROR_OK; -} - -static int lpc3180_read_page(struct nand_device *nand, - uint32_t page, - uint8_t *data, - uint32_t data_size, - uint8_t *oob, - uint32_t oob_size) -{ - struct lpc3180_nand_controller *lpc3180_info = nand->controller_priv; - struct target *target = nand->target; - uint8_t *page_buffer; - - if (target->state != TARGET_HALTED) { - LOG_ERROR("target must be halted to use LPC3180 NAND flash controller"); - return ERROR_NAND_OPERATION_FAILED; - } - - if (lpc3180_info->selected_controller == LPC3180_NO_CONTROLLER) { - LOG_ERROR("BUG: no LPC3180 NAND flash controller selected"); - return ERROR_NAND_OPERATION_FAILED; - } else if (lpc3180_info->selected_controller == LPC3180_MLC_CONTROLLER) { - uint8_t *oob_buffer; - uint32_t page_bytes_done = 0; - uint32_t oob_bytes_done = 0; - uint32_t mlc_isr; - -#if 0 - if (oob && (oob_size > 6)) { - LOG_ERROR("LPC3180 MLC controller can't read more than 6 bytes of OOB data"); - return ERROR_NAND_OPERATION_NOT_SUPPORTED; - } -#endif - - if (data_size > (uint32_t)nand->page_size) { - LOG_ERROR("data size exceeds page size"); - return ERROR_NAND_OPERATION_NOT_SUPPORTED; - } - - if (nand->page_size == 2048) { - page_buffer = malloc(2048); - oob_buffer = malloc(64); - } else { - page_buffer = malloc(512); - oob_buffer = malloc(16); - } - - if (!data && oob) { - /* MLC_CMD = Read OOB - * we can use the READOOB command on both small and large page devices, - * as the controller translates the 0x50 command to a 0x0 with appropriate - * positioning of the serial buffer read pointer - */ - target_write_u32(target, 0x200b8000, NAND_CMD_READOOB); - } else { - /* MLC_CMD = Read0 */ - target_write_u32(target, 0x200b8000, NAND_CMD_READ0); - } - - if (nand->page_size == 512) { - /* small page device - * MLC_ADDR = 0x0 (one column cycle) */ - target_write_u32(target, 0x200b8004, 0x0); - - /* MLC_ADDR = row */ - target_write_u32(target, 0x200b8004, page & 0xff); - target_write_u32(target, 0x200b8004, (page >> 8) & 0xff); - - if (nand->address_cycles == 4) - target_write_u32(target, 0x200b8004, (page >> 16) & 0xff); - } else { - /* large page device - * MLC_ADDR = 0x0 (two column cycles) */ - target_write_u32(target, 0x200b8004, 0x0); - target_write_u32(target, 0x200b8004, 0x0); - - /* MLC_ADDR = row */ - target_write_u32(target, 0x200b8004, page & 0xff); - target_write_u32(target, 0x200b8004, (page >> 8) & 0xff); - - /* MLC_CMD = Read Start */ - target_write_u32(target, 0x200b8000, NAND_CMD_READSTART); - } - - while (page_bytes_done < (uint32_t)nand->page_size) { - /* MLC_ECC_AUTO_DEC_REG = dummy */ - target_write_u32(target, 0x200b8014, 0xaa55aa55); - - if (!lpc3180_controller_ready(nand, 1000)) { - LOG_ERROR("timeout while waiting for completion of auto decode cycle"); - free(page_buffer); - free(oob_buffer); - return ERROR_NAND_OPERATION_FAILED; - } - - target_read_u32(target, 0x200b8048, &mlc_isr); - - if (mlc_isr & 0x8) { - if (mlc_isr & 0x40) { - LOG_ERROR("uncorrectable error detected: 0x%2.2x", - (unsigned)mlc_isr); - free(page_buffer); - free(oob_buffer); - return ERROR_NAND_OPERATION_FAILED; - } - - LOG_WARNING("%i symbol error detected and corrected", - ((int)(((mlc_isr & 0x30) >> 4) + 1))); - } - - if (data) - target_read_memory(target, - 0x200a8000, - 4, - 128, - page_buffer + page_bytes_done); - - if (oob) - target_read_memory(target, - 0x200a8000, - 4, - 4, - oob_buffer + oob_bytes_done); - - page_bytes_done += 512; - oob_bytes_done += 16; - } - - if (data) - memcpy(data, page_buffer, data_size); - - if (oob) - memcpy(oob, oob_buffer, oob_size); - - free(page_buffer); - free(oob_buffer); - } else if (lpc3180_info->selected_controller == LPC3180_SLC_CONTROLLER) { - - /********************************************************************** - * Read both SLC NAND flash page main area and spare area. - * Small page - - * ------------------------------------------ - * | 512 bytes main | 16 bytes spare | - * ------------------------------------------ - * Large page - - * ------------------------------------------ - * | 2048 bytes main | 64 bytes spare | - * ------------------------------------------ - * If DMA & ECC enabled, then the ECC generated for the 1st 256-byte - * data is compared with the 3rd word of the spare area. The ECC - * generated for the 2nd 256-byte data is compared with the 4th word - * of the spare area. The ECC generated for the 3rd 256-byte data is - * compared with the 7th word of the spare area. The ECC generated - * for the 4th 256-byte data is compared with the 8th word of the - * spare area and so on. - * - **********************************************************************/ - - int retval, i, target_mem_base; - uint8_t *ecc_hw_buffer; - uint8_t *ecc_flash_buffer; - struct working_area *pworking_area; - - if (lpc3180_info->is_bulk) { - - /* read always the data and also oob areas*/ - - retval = nand_page_command(nand, page, NAND_CMD_READ0, 0); - if (ERROR_OK != retval) - return retval; - - /* allocate a working area */ - if (target->working_area_size < (uint32_t) nand->page_size + 0x200) { - LOG_ERROR("Reserve at least 0x%x physical target working area", - nand->page_size + 0x200); - return ERROR_FLASH_OPERATION_FAILED; - } - if (target->working_area_phys%4) { - LOG_ERROR( - "Reserve the physical target working area at word boundary"); - return ERROR_FLASH_OPERATION_FAILED; - } - if (target_alloc_working_area(target, target->working_area_size, - &pworking_area) != ERROR_OK) { - LOG_ERROR("no working area specified, can't read LPC internal flash"); - return ERROR_FLASH_OPERATION_FAILED; - } - target_mem_base = target->working_area_phys; - - if (nand->page_size == 2048) - page_buffer = malloc(2048); - else - page_buffer = malloc(512); - - ecc_hw_buffer = malloc(32); - ecc_flash_buffer = malloc(64); - - /* SLC_CFG = 0x (Force nCE assert, DMA ECC enabled, ECC enabled, DMA burst - *enabled, DMA read from SLC, WIDTH = bus_width) */ - target_write_u32(target, 0x20020014, 0x3e); - - /* set DMA LLI-s in target memory and in DMA*/ - for (i = 0; i < nand->page_size/0x100; i++) { - int tmp; - /* -------LLI for 256 byte block--------- - * DMACC0SrcAddr = SLC_DMA_DATA*/ - target_write_u32(target, target_mem_base+0+i*32, 0x20020038); - if (i == 0) - target_write_u32(target, 0x31000100, 0x20020038); - /* DMACCxDestAddr = SRAM */ - target_write_u32(target, - target_mem_base+4+i*32, - target_mem_base+DATA_OFFS+i*256); - if (i == 0) - target_write_u32(target, - 0x31000104, - target_mem_base+DATA_OFFS); - /* DMACCxLLI = next element */ - tmp = (target_mem_base+(1+i*2)*16)&0xfffffffc; - target_write_u32(target, target_mem_base+8+i*32, tmp); - if (i == 0) - target_write_u32(target, 0x31000108, tmp); - /* DMACCxControl = TransferSize =64, Source burst size =16, - * Destination burst size = 16, Source transfer width = 32 bit, - * Destination transfer width = 32 bit, Source AHB master select = M0, - * Destination AHB master select = M0, Source increment = 0, - * Destination increment = 1, Terminal count interrupt enable bit = 0*/ - target_write_u32(target, - target_mem_base+12+i*32, - 0x40 | 3<<12 | 3<<15 | 2<<18 | 2<<21 | 0<<24 | 0<<25 | 0<<26 | 1<<27 | 0<< - 31); - if (i == 0) - target_write_u32(target, - 0x3100010c, - 0x40 | 3<<12 | 3<<15 | 2<<18 | 2<<21 | 0<<24 | 0<<25 | 0<<26 | 1<<27 | 0<< - 31); - - /* -------LLI for 3 byte ECC--------- - * DMACC0SrcAddr = SLC_ECC*/ - target_write_u32(target, target_mem_base+16+i*32, 0x20020034); - /* DMACCxDestAddr = SRAM */ - target_write_u32(target, - target_mem_base+20+i*32, - target_mem_base+ECC_OFFS+i*4); - /* DMACCxLLI = next element */ - tmp = (target_mem_base+(2+i*2)*16)&0xfffffffc; - target_write_u32(target, target_mem_base+24+i*32, tmp); - /* DMACCxControl = TransferSize =1, Source burst size =4, - * Destination burst size = 4, Source transfer width = 32 bit, - * Destination transfer width = 32 bit, Source AHB master select = M0, - * Destination AHB master select = M0, Source increment = 0, - * Destination increment = 1, Terminal count interrupt enable bit = 0*/ - target_write_u32(target, - target_mem_base+28+i*32, - 0x01 | 1<<12 | 1<<15 | 2<<18 | 2<<21 | 0<<24 | 0<<25 | 0<<26 | 1<<27 | 0<< - 31); - } - - /* -------LLI for spare area--------- - * DMACC0SrcAddr = SLC_DMA_DATA*/ - target_write_u32(target, target_mem_base+0+i*32, 0x20020038); - /* DMACCxDestAddr = SRAM */ - target_write_u32(target, target_mem_base+4+i*32, target_mem_base+SPARE_OFFS); - /* DMACCxLLI = next element = NULL */ - target_write_u32(target, target_mem_base+8+i*32, 0); - /* DMACCxControl = TransferSize =16 for large page or 4 for small page, - * Source burst size =16, Destination burst size = 16, Source transfer width = 32 bit, - * Destination transfer width = 32 bit, Source AHB master select = M0, - * Destination AHB master select = M0, Source increment = 0, - * Destination increment = 1, Terminal count interrupt enable bit = 0*/ - target_write_u32(target, - target_mem_base + 12 + i * 32, - (nand->page_size == 2048 ? 0x10 : 0x04) | 3<<12 | 3<<15 | 2<<18 | 2<<21 | - 0<<24 | 0<<25 | 0<<26 | 1<<27 | 0<<31); - - /* Enable DMA after channel set up ! - LLI only works when DMA is the flow controller! - */ - /* DMACCxConfig= E=1, SrcPeripheral = 1 (SLC), DestPeripheral = 1 (SLC), - *FlowCntrl = 2 (Pher-> Mem, DMA), IE = 0, ITC = 0, L= 0, H=0*/ - target_write_u32(target, - 0x31000110, - 1 | 1<<1 | 1<<6 | 2<<11 | 0<<14 | 0<<15 | 0<<16 | 0<<18); - - /* SLC_CTRL = 3 (START DMA), ECC_CLEAR */ - target_write_u32(target, 0x20020010, 0x3); - - /* SLC_ICR = 2, INT_TC_CLR, clear pending TC*/ - target_write_u32(target, 0x20020028, 2); - - /* SLC_TC */ - target_write_u32(target, 0x20020030, - (nand->page_size == 2048 ? 0x840 : 0x210)); - - if (!lpc3180_tc_ready(nand, 1000)) { - LOG_ERROR("timeout while waiting for completion of DMA"); - free(page_buffer); - free(ecc_hw_buffer); - free(ecc_flash_buffer); - target_free_working_area(target, pworking_area); - return ERROR_NAND_OPERATION_FAILED; - } - - if (data) { - target_read_memory(target, - target_mem_base+DATA_OFFS, - 4, - nand->page_size == 2048 ? 512 : 128, - page_buffer); - memcpy(data, page_buffer, data_size); - - LOG_INFO("Page = 0x%" PRIx32 " was read.", page); - - /* check hw generated ECC for each 256 bytes block with the saved - *ECC in flash spare area*/ - int idx = nand->page_size/0x200; - target_read_memory(target, - target_mem_base+SPARE_OFFS, - 4, - 16, - ecc_flash_buffer); - target_read_memory(target, - target_mem_base+ECC_OFFS, - 4, - 8, - ecc_hw_buffer); - for (i = 0; i < idx; i++) { - if ((0x00ffffff & *(uint32_t *)(void *)(ecc_hw_buffer+i*8)) != - (0x00ffffff & *(uint32_t *)(void *)(ecc_flash_buffer+8+i*16))) - LOG_WARNING( - "ECC mismatch at 256 bytes size block= %d at page= 0x%" PRIx32, - i * 2 + 1, page); - if ((0x00ffffff & *(uint32_t *)(void *)(ecc_hw_buffer+4+i*8)) != - (0x00ffffff & *(uint32_t *)(void *)(ecc_flash_buffer+12+i*16))) - LOG_WARNING( - "ECC mismatch at 256 bytes size block= %d at page= 0x%" PRIx32, - i * 2 + 2, page); - } - } - - if (oob) - memcpy(oob, ecc_flash_buffer, oob_size); - - free(page_buffer); - free(ecc_hw_buffer); - free(ecc_flash_buffer); - - target_free_working_area(target, pworking_area); - - } else - return nand_read_page_raw(nand, page, data, data_size, oob, oob_size); - } - - return ERROR_OK; -} - -static int lpc3180_controller_ready(struct nand_device *nand, int timeout) -{ - struct lpc3180_nand_controller *lpc3180_info = nand->controller_priv; - struct target *target = nand->target; - - if (target->state != TARGET_HALTED) { - LOG_ERROR("target must be halted to use LPC3180 NAND flash controller"); - return ERROR_NAND_OPERATION_FAILED; - } - - LOG_DEBUG("lpc3180_controller_ready count start=%d", timeout); - - do { - if (lpc3180_info->selected_controller == LPC3180_MLC_CONTROLLER) { - uint8_t status; - - /* Read MLC_ISR, wait for controller to become ready */ - target_read_u8(target, 0x200b8048, &status); - - if (status & 2) { - LOG_DEBUG("lpc3180_controller_ready count=%d", - timeout); - return 1; - } - } else if (lpc3180_info->selected_controller == LPC3180_SLC_CONTROLLER) { - uint32_t status; - - /* Read SLC_STAT and check READY bit */ - target_read_u32(target, 0x20020018, &status); - - if (status & 1) { - LOG_DEBUG("lpc3180_controller_ready count=%d", - timeout); - return 1; - } - } - - alive_sleep(1); - } while (timeout-- > 0); - - return 0; -} - -static int lpc3180_nand_ready(struct nand_device *nand, int timeout) -{ - struct lpc3180_nand_controller *lpc3180_info = nand->controller_priv; - struct target *target = nand->target; - - if (target->state != TARGET_HALTED) { - LOG_ERROR("target must be halted to use LPC3180 NAND flash controller"); - return ERROR_NAND_OPERATION_FAILED; - } - - LOG_DEBUG("lpc3180_nand_ready count start=%d", timeout); - - do { - if (lpc3180_info->selected_controller == LPC3180_MLC_CONTROLLER) { - uint8_t status = 0x0; - - /* Read MLC_ISR, wait for NAND flash device to become ready */ - target_read_u8(target, 0x200b8048, &status); - - if (status & 1) { - LOG_DEBUG("lpc3180_nand_ready count end=%d", - timeout); - return 1; - } - } else if (lpc3180_info->selected_controller == LPC3180_SLC_CONTROLLER) { - uint32_t status = 0x0; - - /* Read SLC_STAT and check READY bit */ - target_read_u32(target, 0x20020018, &status); - - if (status & 1) { - LOG_DEBUG("lpc3180_nand_ready count end=%d", - timeout); - return 1; - } - } - - alive_sleep(1); - } while (timeout-- > 0); - - return 0; -} - -static int lpc3180_tc_ready(struct nand_device *nand, int timeout) -{ - struct lpc3180_nand_controller *lpc3180_info = nand->controller_priv; - struct target *target = nand->target; - - if (target->state != TARGET_HALTED) { - LOG_ERROR("target must be halted to use LPC3180 NAND flash controller"); - return ERROR_NAND_OPERATION_FAILED; - } - - LOG_DEBUG("lpc3180_tc_ready count start=%d", - timeout); - - do { - if (lpc3180_info->selected_controller == LPC3180_SLC_CONTROLLER) { - uint32_t status = 0x0; - /* Read SLC_INT_STAT and check INT_TC_STAT bit */ - target_read_u32(target, 0x2002001c, &status); - - if (status & 2) { - LOG_DEBUG("lpc3180_tc_ready count=%d", - timeout); - return 1; - } - } - - alive_sleep(1); - } while (timeout-- > 0); - - return 0; -} - -COMMAND_HANDLER(handle_lpc3180_select_command) -{ - struct lpc3180_nand_controller *lpc3180_info = NULL; - char *selected[] = { - "no", "mlc", "slc" - }; - - if ((CMD_ARGC < 1) || (CMD_ARGC > 3)) - return ERROR_COMMAND_SYNTAX_ERROR; - - unsigned num; - COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], num); - struct nand_device *nand = get_nand_device_by_num(num); - if (!nand) { - command_print(CMD_CTX, "nand device '#%s' is out of bounds", CMD_ARGV[0]); - return ERROR_OK; - } - - lpc3180_info = nand->controller_priv; - - if (CMD_ARGC >= 2) { - if (strcmp(CMD_ARGV[1], "mlc") == 0) - lpc3180_info->selected_controller = LPC3180_MLC_CONTROLLER; - else if (strcmp(CMD_ARGV[1], "slc") == 0) { - lpc3180_info->selected_controller = LPC3180_SLC_CONTROLLER; - if (CMD_ARGC == 3 && strcmp(CMD_ARGV[2], "bulk") == 0) - lpc3180_info->is_bulk = 1; - else - lpc3180_info->is_bulk = 0; - } else - return ERROR_COMMAND_SYNTAX_ERROR; - } - - if (lpc3180_info->selected_controller == LPC3180_MLC_CONTROLLER) - command_print(CMD_CTX, "%s controller selected", - selected[lpc3180_info->selected_controller]); - else - command_print(CMD_CTX, - lpc3180_info->is_bulk ? "%s controller selected bulk mode is available" : - "%s controller selected bulk mode is not available", - selected[lpc3180_info->selected_controller]); - - return ERROR_OK; -} - -static const struct command_registration lpc3180_exec_command_handlers[] = { - { - .name = "select", - .handler = handle_lpc3180_select_command, - .mode = COMMAND_EXEC, - .help = - "select MLC or SLC controller (default is MLC), SLC can be set to bulk mode", - .usage = "bank_id ['mlc'|'slc' ['bulk'] ]", - }, - COMMAND_REGISTRATION_DONE -}; -static const struct command_registration lpc3180_command_handler[] = { - { - .name = "lpc3180", - .mode = COMMAND_ANY, - .help = "LPC3180 NAND flash controller commands", - .usage = "", - .chain = lpc3180_exec_command_handlers, - }, - COMMAND_REGISTRATION_DONE -}; - -struct nand_flash_controller lpc3180_nand_controller = { - .name = "lpc3180", - .commands = lpc3180_command_handler, - .nand_device_command = lpc3180_nand_device_command, - .init = lpc3180_init, - .reset = lpc3180_reset, - .command = lpc3180_command, - .address = lpc3180_address, - .write_data = lpc3180_write_data, - .read_data = lpc3180_read_data, - .write_page = lpc3180_write_page, - .read_page = lpc3180_read_page, - .nand_ready = lpc3180_nand_ready, -}; diff --git a/src/flash/nand/lpc3180.h b/src/flash/nand/lpc3180.h deleted file mode 100644 index c02ee5b27..000000000 --- a/src/flash/nand/lpc3180.h +++ /dev/null @@ -1,37 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifndef OPENOCD_FLASH_NAND_LPC3180_H -#define OPENOCD_FLASH_NAND_LPC3180_H - -enum lpc3180_selected_controller { - LPC3180_NO_CONTROLLER, - LPC3180_MLC_CONTROLLER, - LPC3180_SLC_CONTROLLER, -}; - -struct lpc3180_nand_controller { - int osc_freq; - enum lpc3180_selected_controller selected_controller; - int is_bulk; - int sw_write_protection; - uint32_t sw_wp_lower_bound; - uint32_t sw_wp_upper_bound; -}; - -#endif /* OPENOCD_FLASH_NAND_LPC3180_H */ diff --git a/src/flash/nand/lpc32xx.c b/src/flash/nand/lpc32xx.c deleted file mode 100644 index 1ed16dfd0..000000000 --- a/src/flash/nand/lpc32xx.c +++ /dev/null @@ -1,1821 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * Copyright (C) 2011 Bjarne Steinsbo * - * Copyright (C) 2010 richard vegh * - * Copyright (C) 2010 Oyvind Harboe * - * * - * Based on a combination of the lpc3180 driver and code from * - * uboot-2009.03-lpc32xx by Kevin Wells. * - * Any bugs are mine. --BSt * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "imp.h" -#include "lpc32xx.h" -#include - -static int lpc32xx_reset(struct nand_device *nand); -static int lpc32xx_controller_ready(struct nand_device *nand, int timeout); -static int lpc32xx_tc_ready(struct nand_device *nand, int timeout); -extern int nand_correct_data(struct nand_device *nand, u_char *dat, - u_char *read_ecc, u_char *calc_ecc); - -/* These are offset with the working area in IRAM when using DMA to - * read/write data to the SLC controller. - * - DMA descriptors will be put at start of working area, - * - Hardware generated ECC will be stored at ECC_OFFS - * - OOB wil be read/written from/to SPARE_OFFS - * - Actual page data will be read from/to DATA_OFFS - * There are unused holes between the used areas. - */ -#define ECC_OFFS 0x120 -#define SPARE_OFFS 0x140 -#define DATA_OFFS 0x200 - -static const int sp_ooblayout[] = { - 10, 11, 12, 13, 14, 15 -}; -static const int lp_ooblayout[] = { - 40, 41, 42, 43, 44, 45, - 46, 47, 48, 49, 50, 51, - 52, 53, 54, 55, 56, 57, - 58, 59, 60, 61, 62, 63 -}; - -typedef struct { - volatile uint32_t dma_src; - volatile uint32_t dma_dest; - volatile uint32_t next_lli; - volatile uint32_t next_ctrl; -} dmac_ll_t; - -static dmac_ll_t dmalist[(2048/256) * 2 + 1]; - -/* nand device lpc32xx - */ -NAND_DEVICE_COMMAND_HANDLER(lpc32xx_nand_device_command) -{ - if (CMD_ARGC < 3) - return ERROR_COMMAND_SYNTAX_ERROR; - - uint32_t osc_freq; - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], osc_freq); - - struct lpc32xx_nand_controller *lpc32xx_info; - lpc32xx_info = malloc(sizeof(struct lpc32xx_nand_controller)); - nand->controller_priv = lpc32xx_info; - - lpc32xx_info->osc_freq = osc_freq; - - if ((lpc32xx_info->osc_freq < 1000) || (lpc32xx_info->osc_freq > 20000)) - LOG_WARNING("LPC32xx oscillator frequency should be between " - "1000 and 20000 kHz, was %i", - lpc32xx_info->osc_freq); - - lpc32xx_info->selected_controller = LPC32xx_NO_CONTROLLER; - lpc32xx_info->sw_write_protection = 0; - lpc32xx_info->sw_wp_lower_bound = 0x0; - lpc32xx_info->sw_wp_upper_bound = 0x0; - - return ERROR_OK; -} - -static int lpc32xx_pll(int fclkin, uint32_t pll_ctrl) -{ - int bypass = (pll_ctrl & 0x8000) >> 15; - int direct = (pll_ctrl & 0x4000) >> 14; - int feedback = (pll_ctrl & 0x2000) >> 13; - int p = (1 << ((pll_ctrl & 0x1800) >> 11) * 2); - int n = ((pll_ctrl & 0x0600) >> 9) + 1; - int m = ((pll_ctrl & 0x01fe) >> 1) + 1; - int lock = (pll_ctrl & 0x1); - - if (!lock) - LOG_WARNING("PLL is not locked"); - - if (!bypass && direct) /* direct mode */ - return (m * fclkin) / n; - - if (bypass && !direct) /* bypass mode */ - return fclkin / (2 * p); - - if (bypass & direct) /* direct bypass mode */ - return fclkin; - - if (feedback) /* integer mode */ - return m * (fclkin / n); - else /* non-integer mode */ - return (m / (2 * p)) * (fclkin / n); -} - -static float lpc32xx_cycle_time(struct nand_device *nand) -{ - struct lpc32xx_nand_controller *lpc32xx_info = nand->controller_priv; - struct target *target = nand->target; - uint32_t sysclk_ctrl, pwr_ctrl, hclkdiv_ctrl, hclkpll_ctrl; - int sysclk; - int hclk; - int hclk_pll; - float cycle; - int retval; - - /* calculate timings */ - - /* determine current SYSCLK (13'MHz or main oscillator) */ - retval = target_read_u32(target, 0x40004050, &sysclk_ctrl); - if (ERROR_OK != retval) { - LOG_ERROR("could not read SYSCLK_CTRL"); - return ERROR_NAND_OPERATION_FAILED; - } - - if ((sysclk_ctrl & 1) == 0) - sysclk = lpc32xx_info->osc_freq; - else - sysclk = 13000; - - /* determine selected HCLK source */ - retval = target_read_u32(target, 0x40004044, &pwr_ctrl); - if (ERROR_OK != retval) { - LOG_ERROR("could not read HCLK_CTRL"); - return ERROR_NAND_OPERATION_FAILED; - } - - if ((pwr_ctrl & (1 << 2)) == 0) /* DIRECT RUN mode */ - hclk = sysclk; - else { - retval = target_read_u32(target, 0x40004058, &hclkpll_ctrl); - if (ERROR_OK != retval) { - LOG_ERROR("could not read HCLKPLL_CTRL"); - return ERROR_NAND_OPERATION_FAILED; - } - hclk_pll = lpc32xx_pll(sysclk, hclkpll_ctrl); - - retval = target_read_u32(target, 0x40004040, &hclkdiv_ctrl); - if (ERROR_OK != retval) { - LOG_ERROR("could not read CLKDIV_CTRL"); - return ERROR_NAND_OPERATION_FAILED; - } - - if (pwr_ctrl & (1 << 10)) /* ARM_CLK and HCLK use PERIPH_CLK */ - hclk = hclk_pll / (((hclkdiv_ctrl & 0x7c) >> 2) + 1); - else /* HCLK uses HCLK_PLL */ - hclk = hclk_pll / (1 << (hclkdiv_ctrl & 0x3)); - } - - LOG_DEBUG("LPC32xx HCLK currently clocked at %i kHz", hclk); - - cycle = (1.0 / hclk) * 1000000.0; - - return cycle; -} - -static int lpc32xx_init(struct nand_device *nand) -{ - struct lpc32xx_nand_controller *lpc32xx_info = nand->controller_priv; - struct target *target = nand->target; - int bus_width = nand->bus_width ? : 8; - int address_cycles = nand->address_cycles ? : 3; - int page_size = nand->page_size ? : 512; - int retval; - - if (target->state != TARGET_HALTED) { - LOG_ERROR("target must be halted to use LPC32xx " - "NAND flash controller"); - return ERROR_NAND_OPERATION_FAILED; - } - - /* sanitize arguments */ - if (bus_width != 8) { - LOG_ERROR("LPC32xx doesn't support %i", bus_width); - return ERROR_NAND_OPERATION_NOT_SUPPORTED; - } - - /* inform calling code about selected bus width */ - nand->bus_width = bus_width; - - if ((address_cycles < 3) || (address_cycles > 5)) { - LOG_ERROR("LPC32xx driver doesn't support %i address cycles", address_cycles); - return ERROR_NAND_OPERATION_NOT_SUPPORTED; - } - - if ((page_size != 512) && (page_size != 2048)) { - LOG_ERROR("LPC32xx doesn't support page size %i", page_size); - return ERROR_NAND_OPERATION_NOT_SUPPORTED; - } - - /* select MLC controller if none is currently selected */ - if (lpc32xx_info->selected_controller == LPC32xx_NO_CONTROLLER) { - LOG_DEBUG("no LPC32xx NAND flash controller selected, " - "using default 'slc'"); - lpc32xx_info->selected_controller = LPC32xx_SLC_CONTROLLER; - } - - if (lpc32xx_info->selected_controller == LPC32xx_MLC_CONTROLLER) { - uint32_t mlc_icr_value = 0x0; - float cycle; - int twp, twh, trp, treh, trhz, trbwb, tcea; - - /* FLASHCLK_CTRL = 0x22 (enable clk for MLC) */ - retval = target_write_u32(target, 0x400040c8, 0x22); - if (ERROR_OK != retval) { - LOG_ERROR("could not set FLASHCLK_CTRL"); - return ERROR_NAND_OPERATION_FAILED; - } - - /* MLC_CEH = 0x0 (Force nCE assert) */ - retval = target_write_u32(target, 0x200b804c, 0x0); - if (ERROR_OK != retval) { - LOG_ERROR("could not set MLC_CEH"); - return ERROR_NAND_OPERATION_FAILED; - } - - /* MLC_LOCK = 0xa25e (unlock protected registers) */ - retval = target_write_u32(target, 0x200b8044, 0xa25e); - if (ERROR_OK != retval) { - LOG_ERROR("could not set MLC_LOCK"); - return ERROR_NAND_OPERATION_FAILED; - } - - /* MLC_ICR = configuration */ - if (lpc32xx_info->sw_write_protection) - mlc_icr_value |= 0x8; - if (page_size == 2048) - mlc_icr_value |= 0x4; - if (address_cycles == 4) - mlc_icr_value |= 0x2; - if (bus_width == 16) - mlc_icr_value |= 0x1; - retval = target_write_u32(target, 0x200b8030, mlc_icr_value); - if (ERROR_OK != retval) { - LOG_ERROR("could not set MLC_ICR"); - return ERROR_NAND_OPERATION_FAILED; - } - - /* calculate NAND controller timings */ - cycle = lpc32xx_cycle_time(nand); - - twp = ((40 / cycle) + 1); - twh = ((20 / cycle) + 1); - trp = ((30 / cycle) + 1); - treh = ((15 / cycle) + 1); - trhz = ((30 / cycle) + 1); - trbwb = ((100 / cycle) + 1); - tcea = ((45 / cycle) + 1); - - /* MLC_LOCK = 0xa25e (unlock protected registers) */ - retval = target_write_u32(target, 0x200b8044, 0xa25e); - if (ERROR_OK != retval) { - LOG_ERROR("could not set MLC_LOCK"); - return ERROR_NAND_OPERATION_FAILED; - } - - /* MLC_TIME_REG */ - retval = target_write_u32(target, 0x200b8034, - (twp & 0xf) - | ((twh & 0xf) << 4) - | ((trp & 0xf) << 8) - | ((treh & 0xf) << 12) - | ((trhz & 0x7) << 16) - | ((trbwb & 0x1f) << 19) - | ((tcea & 0x3) << 24)); - if (ERROR_OK != retval) { - LOG_ERROR("could not set MLC_TIME_REG"); - return ERROR_NAND_OPERATION_FAILED; - } - - retval = lpc32xx_reset(nand); - if (ERROR_OK != retval) - return ERROR_NAND_OPERATION_FAILED; - } else if (lpc32xx_info->selected_controller == LPC32xx_SLC_CONTROLLER) { - float cycle; - int r_setup, r_hold, r_width, r_rdy; - int w_setup, w_hold, w_width, w_rdy; - - /* FLASHCLK_CTRL = 0x05 (enable clk for SLC) */ - retval = target_write_u32(target, 0x400040c8, 0x05); - if (ERROR_OK != retval) { - LOG_ERROR("could not set FLASHCLK_CTRL"); - return ERROR_NAND_OPERATION_FAILED; - } - - /* after reset set other registers of SLC, - * so reset calling is here at the begining - */ - retval = lpc32xx_reset(nand); - if (ERROR_OK != retval) - return ERROR_NAND_OPERATION_FAILED; - - /* SLC_CFG = - Force nCE assert, - DMA ECC enabled, - ECC enabled, - DMA burst enabled, - DMA read from SLC, - WIDTH = bus_width) - */ - retval = target_write_u32(target, 0x20020014, - 0x3e | (bus_width == 16) ? 1 : 0); - if (ERROR_OK != retval) { - LOG_ERROR("could not set SLC_CFG"); - return ERROR_NAND_OPERATION_FAILED; - } - - /* SLC_IEN = 3 (INT_RDY_EN = 1) ,(INT_TC_STAT = 1) */ - retval = target_write_u32(target, 0x20020020, 0x03); - if (ERROR_OK != retval) { - LOG_ERROR("could not set SLC_IEN"); - return ERROR_NAND_OPERATION_FAILED; - } - - /* DMA configuration */ - - /* DMACLK_CTRL = 0x01 (enable clock for DMA controller) */ - retval = target_write_u32(target, 0x400040e8, 0x01); - if (ERROR_OK != retval) { - LOG_ERROR("could not set DMACLK_CTRL"); - return ERROR_NAND_OPERATION_FAILED; - } - - /* DMACConfig = DMA enabled*/ - retval = target_write_u32(target, 0x31000030, 0x01); - if (ERROR_OK != retval) { - LOG_ERROR("could not set DMACConfig"); - return ERROR_NAND_OPERATION_FAILED; - } - - /* calculate NAND controller timings */ - cycle = lpc32xx_cycle_time(nand); - - r_setup = w_setup = 0; - r_hold = w_hold = 10 / cycle; - r_width = 30 / cycle; - w_width = 40 / cycle; - r_rdy = w_rdy = 100 / cycle; - - /* SLC_TAC: SLC timing arcs register */ - retval = target_write_u32(target, 0x2002002c, - (r_setup & 0xf) - | ((r_hold & 0xf) << 4) - | ((r_width & 0xf) << 8) - | ((r_rdy & 0xf) << 12) - | ((w_setup & 0xf) << 16) - | ((w_hold & 0xf) << 20) - | ((w_width & 0xf) << 24) - | ((w_rdy & 0xf) << 28)); - if (ERROR_OK != retval) { - LOG_ERROR("could not set SLC_TAC"); - return ERROR_NAND_OPERATION_FAILED; - } - } - - return ERROR_OK; -} - -static int lpc32xx_reset(struct nand_device *nand) -{ - struct lpc32xx_nand_controller *lpc32xx_info = nand->controller_priv; - struct target *target = nand->target; - int retval; - - if (target->state != TARGET_HALTED) { - LOG_ERROR("target must be halted to use " - "LPC32xx NAND flash controller"); - return ERROR_NAND_OPERATION_FAILED; - } - - if (lpc32xx_info->selected_controller == LPC32xx_NO_CONTROLLER) { - LOG_ERROR("BUG: no LPC32xx NAND flash controller selected"); - return ERROR_NAND_OPERATION_FAILED; - } else if (lpc32xx_info->selected_controller == LPC32xx_MLC_CONTROLLER) { - /* MLC_CMD = 0xff (reset controller and NAND device) */ - retval = target_write_u32(target, 0x200b8000, 0xff); - if (ERROR_OK != retval) { - LOG_ERROR("could not set MLC_CMD"); - return ERROR_NAND_OPERATION_FAILED; - } - - if (!lpc32xx_controller_ready(nand, 100)) { - LOG_ERROR("LPC32xx MLC NAND controller timed out " - "after reset"); - return ERROR_NAND_OPERATION_TIMEOUT; - } - } else if (lpc32xx_info->selected_controller == LPC32xx_SLC_CONTROLLER) { - /* SLC_CTRL = 0x6 (ECC_CLEAR, SW_RESET) */ - retval = target_write_u32(target, 0x20020010, 0x6); - if (ERROR_OK != retval) { - LOG_ERROR("could not set SLC_CTRL"); - return ERROR_NAND_OPERATION_FAILED; - } - - if (!lpc32xx_controller_ready(nand, 100)) { - LOG_ERROR("LPC32xx SLC NAND controller timed out " - "after reset"); - return ERROR_NAND_OPERATION_TIMEOUT; - } - } - - return ERROR_OK; -} - -static int lpc32xx_command(struct nand_device *nand, uint8_t command) -{ - struct lpc32xx_nand_controller *lpc32xx_info = nand->controller_priv; - struct target *target = nand->target; - int retval; - - if (target->state != TARGET_HALTED) { - LOG_ERROR("target must be halted to use " - "LPC32xx NAND flash controller"); - return ERROR_NAND_OPERATION_FAILED; - } - - if (lpc32xx_info->selected_controller == LPC32xx_NO_CONTROLLER) { - LOG_ERROR("BUG: no LPC32xx NAND flash controller selected"); - return ERROR_NAND_OPERATION_FAILED; - } else if (lpc32xx_info->selected_controller == LPC32xx_MLC_CONTROLLER) { - /* MLC_CMD = command */ - retval = target_write_u32(target, 0x200b8000, command); - if (ERROR_OK != retval) { - LOG_ERROR("could not set MLC_CMD"); - return ERROR_NAND_OPERATION_FAILED; - } - } else if (lpc32xx_info->selected_controller == LPC32xx_SLC_CONTROLLER) { - /* SLC_CMD = command */ - retval = target_write_u32(target, 0x20020008, command); - if (ERROR_OK != retval) { - LOG_ERROR("could not set SLC_CMD"); - return ERROR_NAND_OPERATION_FAILED; - } - } - - return ERROR_OK; -} - -static int lpc32xx_address(struct nand_device *nand, uint8_t address) -{ - struct lpc32xx_nand_controller *lpc32xx_info = nand->controller_priv; - struct target *target = nand->target; - int retval; - - if (target->state != TARGET_HALTED) { - LOG_ERROR("target must be halted to use " - "LPC32xx NAND flash controller"); - return ERROR_NAND_OPERATION_FAILED; - } - - if (lpc32xx_info->selected_controller == LPC32xx_NO_CONTROLLER) { - LOG_ERROR("BUG: no LPC32xx NAND flash controller selected"); - return ERROR_NAND_OPERATION_FAILED; - } else if (lpc32xx_info->selected_controller == LPC32xx_MLC_CONTROLLER) { - /* MLC_ADDR = address */ - retval = target_write_u32(target, 0x200b8004, address); - if (ERROR_OK != retval) { - LOG_ERROR("could not set MLC_ADDR"); - return ERROR_NAND_OPERATION_FAILED; - } - } else if (lpc32xx_info->selected_controller == LPC32xx_SLC_CONTROLLER) { - /* SLC_ADDR = address */ - retval = target_write_u32(target, 0x20020004, address); - if (ERROR_OK != retval) { - LOG_ERROR("could not set SLC_ADDR"); - return ERROR_NAND_OPERATION_FAILED; - } - } - - return ERROR_OK; -} - -static int lpc32xx_write_data(struct nand_device *nand, uint16_t data) -{ - struct lpc32xx_nand_controller *lpc32xx_info = nand->controller_priv; - struct target *target = nand->target; - int retval; - - if (target->state != TARGET_HALTED) { - LOG_ERROR("target must be halted to use " - "LPC32xx NAND flash controller"); - return ERROR_NAND_OPERATION_FAILED; - } - - if (lpc32xx_info->selected_controller == LPC32xx_NO_CONTROLLER) { - LOG_ERROR("BUG: no LPC32xx NAND flash controller selected"); - return ERROR_NAND_OPERATION_FAILED; - } else if (lpc32xx_info->selected_controller == LPC32xx_MLC_CONTROLLER) { - /* MLC_DATA = data */ - retval = target_write_u32(target, 0x200b0000, data); - if (ERROR_OK != retval) { - LOG_ERROR("could not set MLC_DATA"); - return ERROR_NAND_OPERATION_FAILED; - } - } else if (lpc32xx_info->selected_controller == LPC32xx_SLC_CONTROLLER) { - /* SLC_DATA = data */ - retval = target_write_u32(target, 0x20020000, data); - if (ERROR_OK != retval) { - LOG_ERROR("could not set SLC_DATA"); - return ERROR_NAND_OPERATION_FAILED; - } - } - - return ERROR_OK; -} - -static int lpc32xx_read_data(struct nand_device *nand, void *data) -{ - struct lpc32xx_nand_controller *lpc32xx_info = nand->controller_priv; - struct target *target = nand->target; - int retval; - - if (target->state != TARGET_HALTED) { - LOG_ERROR("target must be halted to use LPC32xx " - "NAND flash controller"); - return ERROR_NAND_OPERATION_FAILED; - } - - if (lpc32xx_info->selected_controller == LPC32xx_NO_CONTROLLER) { - LOG_ERROR("BUG: no LPC32xx NAND flash controller selected"); - return ERROR_NAND_OPERATION_FAILED; - } else if (lpc32xx_info->selected_controller == LPC32xx_MLC_CONTROLLER) { - /* data = MLC_DATA, use sized access */ - if (nand->bus_width == 8) { - uint8_t *data8 = data; - retval = target_read_u8(target, 0x200b0000, data8); - } else { - LOG_ERROR("BUG: bus_width neither 8 nor 16 bit"); - return ERROR_NAND_OPERATION_FAILED; - } - if (ERROR_OK != retval) { - LOG_ERROR("could not read MLC_DATA"); - return ERROR_NAND_OPERATION_FAILED; - } - } else if (lpc32xx_info->selected_controller == LPC32xx_SLC_CONTROLLER) { - uint32_t data32; - - /* data = SLC_DATA, must use 32-bit access */ - retval = target_read_u32(target, 0x20020000, &data32); - if (ERROR_OK != retval) { - LOG_ERROR("could not read SLC_DATA"); - return ERROR_NAND_OPERATION_FAILED; - } - - if (nand->bus_width == 8) { - uint8_t *data8 = data; - *data8 = data32 & 0xff; - } else { - LOG_ERROR("BUG: bus_width neither 8 nor 16 bit"); - return ERROR_NAND_OPERATION_FAILED; - } - } - - return ERROR_OK; -} - -static int lpc32xx_write_page_mlc(struct nand_device *nand, uint32_t page, - uint8_t *data, uint32_t data_size, - uint8_t *oob, uint32_t oob_size) -{ - struct target *target = nand->target; - int retval; - uint8_t status; - static uint8_t page_buffer[512]; - static uint8_t oob_buffer[6]; - int quarter, num_quarters; - - /* MLC_CMD = sequential input */ - retval = target_write_u32(target, 0x200b8000, NAND_CMD_SEQIN); - if (ERROR_OK != retval) { - LOG_ERROR("could not set MLC_CMD"); - return ERROR_NAND_OPERATION_FAILED; - } - - if (nand->page_size == 512) { - /* MLC_ADDR = 0x0 (one column cycle) */ - retval = target_write_u32(target, 0x200b8004, 0x0); - if (ERROR_OK != retval) { - LOG_ERROR("could not set MLC_ADDR"); - return ERROR_NAND_OPERATION_FAILED; - } - - /* MLC_ADDR = row */ - retval = target_write_u32(target, 0x200b8004, page & 0xff); - if (ERROR_OK != retval) { - LOG_ERROR("could not set MLC_ADDR"); - return ERROR_NAND_OPERATION_FAILED; - } - retval = target_write_u32(target, 0x200b8004, - (page >> 8) & 0xff); - if (ERROR_OK != retval) { - LOG_ERROR("could not set MLC_ADDR"); - return ERROR_NAND_OPERATION_FAILED; - } - - if (nand->address_cycles == 4) { - retval = target_write_u32(target, 0x200b8004, - (page >> 16) & 0xff); - if (ERROR_OK != retval) { - LOG_ERROR("could not set MLC_ADDR"); - return ERROR_NAND_OPERATION_FAILED; - } - } - } else { - /* MLC_ADDR = 0x0 (two column cycles) */ - retval = target_write_u32(target, 0x200b8004, 0x0); - if (ERROR_OK != retval) { - LOG_ERROR("could not set MLC_ADDR"); - return ERROR_NAND_OPERATION_FAILED; - } - retval = target_write_u32(target, 0x200b8004, 0x0); - if (ERROR_OK != retval) { - LOG_ERROR("could not set MLC_ADDR"); - return ERROR_NAND_OPERATION_FAILED; - } - - /* MLC_ADDR = row */ - retval = target_write_u32(target, 0x200b8004, page & 0xff); - if (ERROR_OK != retval) { - LOG_ERROR("could not set MLC_ADDR"); - return ERROR_NAND_OPERATION_FAILED; - } - retval = target_write_u32(target, 0x200b8004, - (page >> 8) & 0xff); - if (ERROR_OK != retval) { - LOG_ERROR("could not set MLC_ADDR"); - return ERROR_NAND_OPERATION_FAILED; - } - } - - /* when using the MLC controller, we have to treat a large page device - * as being made out of four quarters, each the size of a small page - * device - */ - num_quarters = (nand->page_size == 2048) ? 4 : 1; - - for (quarter = 0; quarter < num_quarters; quarter++) { - int thisrun_data_size = (data_size > 512) ? 512 : data_size; - int thisrun_oob_size = (oob_size > 6) ? 6 : oob_size; - - memset(page_buffer, 0xff, 512); - if (data) { - memcpy(page_buffer, data, thisrun_data_size); - data_size -= thisrun_data_size; - data += thisrun_data_size; - } - - memset(oob_buffer, 0xff, 6); - if (oob) { - memcpy(oob_buffer, oob, thisrun_oob_size); - oob_size -= thisrun_oob_size; - oob += thisrun_oob_size; - } - - /* write MLC_ECC_ENC_REG to start encode cycle */ - retval = target_write_u32(target, 0x200b8008, 0x0); - if (ERROR_OK != retval) { - LOG_ERROR("could not set MLC_ECC_ENC_REG"); - return ERROR_NAND_OPERATION_FAILED; - } - - retval = target_write_memory(target, 0x200a8000, - 4, 128, page_buffer); - if (ERROR_OK != retval) { - LOG_ERROR("could not set MLC_BUF (data)"); - return ERROR_NAND_OPERATION_FAILED; - } - retval = target_write_memory(target, 0x200a8000, - 1, 6, oob_buffer); - if (ERROR_OK != retval) { - LOG_ERROR("could not set MLC_BUF (oob)"); - return ERROR_NAND_OPERATION_FAILED; - } - - /* write MLC_ECC_AUTO_ENC_REG to start auto encode */ - retval = target_write_u32(target, 0x200b8010, 0x0); - if (ERROR_OK != retval) { - LOG_ERROR("could not set MLC_ECC_AUTO_ENC_REG"); - return ERROR_NAND_OPERATION_FAILED; - } - - if (!lpc32xx_controller_ready(nand, 1000)) { - LOG_ERROR("timeout while waiting for " - "completion of auto encode cycle"); - return ERROR_NAND_OPERATION_FAILED; - } - } - - /* MLC_CMD = auto program command */ - retval = target_write_u32(target, 0x200b8000, NAND_CMD_PAGEPROG); - if (ERROR_OK != retval) { - LOG_ERROR("could not set MLC_CMD"); - return ERROR_NAND_OPERATION_FAILED; - } - - retval = nand_read_status(nand, &status); - if (retval != ERROR_OK) { - LOG_ERROR("couldn't read status"); - return ERROR_NAND_OPERATION_FAILED; - } - - if (status & NAND_STATUS_FAIL) { - LOG_ERROR("write operation didn't pass, status: 0x%2.2x", - status); - return ERROR_NAND_OPERATION_FAILED; - } - - return ERROR_OK; -} - -/* SLC controller in !raw mode will use target cpu to read/write nand from/to - * target internal memory. The transfer to/from flash is done by DMA. This - * function sets up the dma linked list in host memory for later transfer to - * target. - */ -static int lpc32xx_make_dma_list(uint32_t target_mem_base, uint32_t page_size, - int do_read) -{ - uint32_t i, dmasrc, ctrl, ecc_ctrl, oob_ctrl, dmadst; - - /* DMACCxControl = - TransferSize =64, - Source burst size =16, - Destination burst size = 16, - Source transfer width = 32 bit, - Destination transfer width = 32 bit, - Source AHB master select = M0, - Destination AHB master select = M0, - Source increment = 0, // set later - Destination increment = 0, // set later - Terminal count interrupt enable bit = 0 // set on last - */ /* - * Write Operation Sequence for Small Block NAND - * ---------------------------------------------------------- - * 1. X'fer 256 bytes of data from Memory to Flash. - * 2. Copy generated ECC data from Register to Spare Area - * 3. X'fer next 256 bytes of data from Memory to Flash. - * 4. Copy generated ECC data from Register to Spare Area. - * 5. X'fer 16 byets of Spare area from Memory to Flash. - * Read Operation Sequence for Small Block NAND - * ---------------------------------------------------------- - * 1. X'fer 256 bytes of data from Flash to Memory. - * 2. Copy generated ECC data from Register to ECC calc Buffer. - * 3. X'fer next 256 bytes of data from Flash to Memory. - * 4. Copy generated ECC data from Register to ECC calc Buffer. - * 5. X'fer 16 bytes of Spare area from Flash to Memory. - * Write Operation Sequence for Large Block NAND - * ---------------------------------------------------------- - * 1. Steps(1-4) of Write Operations repeate for four times - * which generates 16 DMA descriptors to X'fer 2048 bytes of - * data & 32 bytes of ECC data. - * 2. X'fer 64 bytes of Spare area from Memory to Flash. - * Read Operation Sequence for Large Block NAND - * ---------------------------------------------------------- - * 1. Steps(1-4) of Read Operations repeate for four times - * which generates 16 DMA descriptors to X'fer 2048 bytes of - * data & 32 bytes of ECC data. - * 2. X'fer 64 bytes of Spare area from Flash to Memory. - */ - - ctrl = (0x40 | 3 << 12 | 3 << 15 | 2 << 18 | 2 << 21 | 0 << 24 - | 0 << 25 | 0 << 26 | 0 << 27 | 0 << 31); - - /* DMACCxControl = - TransferSize =1, - Source burst size =4, - Destination burst size = 4, - Source transfer width = 32 bit, - Destination transfer width = 32 bit, - Source AHB master select = M0, - Destination AHB master select = M0, - Source increment = 0, - Destination increment = 1, - Terminal count interrupt enable bit = 0 - */ - ecc_ctrl = 0x01 | 1 << 12 | 1 << 15 | 2 << 18 | 2 << 21 | 0 << 24 - | 0 << 25 | 0 << 26 | 1 << 27 | 0 << 31; - - /* DMACCxControl = - TransferSize =16 for lp or 4 for sp, - Source burst size =16, - Destination burst size = 16, - Source transfer width = 32 bit, - Destination transfer width = 32 bit, - Source AHB master select = M0, - Destination AHB master select = M0, - Source increment = 0, // set later - Destination increment = 0, // set later - Terminal count interrupt enable bit = 1 // set on last - */ - oob_ctrl = (page_size == 2048 ? 0x10 : 0x04) - | 3 << 12 | 3 << 15 | 2 << 18 | 2 << 21 | 0 << 24 - | 0 << 25 | 0 << 26 | 0 << 27 | 1 << 31; - if (do_read) { - ctrl |= 1 << 27;/* Destination increment = 1 */ - oob_ctrl |= 1 << 27; /* Destination increment = 1 */ - dmasrc = 0x20020038; /* SLC_DMA_DATA */ - dmadst = target_mem_base + DATA_OFFS; - } else { - ctrl |= 1 << 26;/* Source increment = 1 */ - oob_ctrl |= 1 << 26; /* Source increment = 1 */ - dmasrc = target_mem_base + DATA_OFFS; - dmadst = 0x20020038; /* SLC_DMA_DATA */ - } - /* - * Write Operation Sequence for Small Block NAND - * ---------------------------------------------------------- - * 1. X'fer 256 bytes of data from Memory to Flash. - * 2. Copy generated ECC data from Register to Spare Area - * 3. X'fer next 256 bytes of data from Memory to Flash. - * 4. Copy generated ECC data from Register to Spare Area. - * 5. X'fer 16 byets of Spare area from Memory to Flash. - * Read Operation Sequence for Small Block NAND - * ---------------------------------------------------------- - * 1. X'fer 256 bytes of data from Flash to Memory. - * 2. Copy generated ECC data from Register to ECC calc Buffer. - * 3. X'fer next 256 bytes of data from Flash to Memory. - * 4. Copy generated ECC data from Register to ECC calc Buffer. - * 5. X'fer 16 bytes of Spare area from Flash to Memory. - * Write Operation Sequence for Large Block NAND - * ---------------------------------------------------------- - * 1. Steps(1-4) of Write Operations repeate for four times - * which generates 16 DMA descriptors to X'fer 2048 bytes of - * data & 32 bytes of ECC data. - * 2. X'fer 64 bytes of Spare area from Memory to Flash. - * Read Operation Sequence for Large Block NAND - * ---------------------------------------------------------- - * 1. Steps(1-4) of Read Operations repeate for four times - * which generates 16 DMA descriptors to X'fer 2048 bytes of - * data & 32 bytes of ECC data. - * 2. X'fer 64 bytes of Spare area from Flash to Memory. - */ - for (i = 0; i < page_size/0x100; i++) { - dmalist[i*2].dma_src = (do_read ? dmasrc : (dmasrc + i * 256)); - dmalist[i*2].dma_dest = (do_read ? (dmadst + i * 256) : dmadst); - dmalist[i*2].next_lli = - target_mem_base + (i*2 + 1) * sizeof(dmac_ll_t); - dmalist[i*2].next_ctrl = ctrl; - - dmalist[(i*2) + 1].dma_src = 0x20020034;/* SLC_ECC */ - dmalist[(i*2) + 1].dma_dest = - target_mem_base + ECC_OFFS + i * 4; - dmalist[(i*2) + 1].next_lli = - target_mem_base + (i*2 + 2) * sizeof(dmac_ll_t); - dmalist[(i*2) + 1].next_ctrl = ecc_ctrl; - - } - if (do_read) - dmadst = target_mem_base + SPARE_OFFS; - else { - dmasrc = target_mem_base + SPARE_OFFS; - dmalist[(i*2) - 1].next_lli = 0;/* last link = null on write */ - dmalist[(i*2) - 1].next_ctrl |= (1 << 31); /* Set TC enable */ - } - dmalist[i*2].dma_src = dmasrc; - dmalist[i*2].dma_dest = dmadst; - dmalist[i*2].next_lli = 0; - dmalist[i*2].next_ctrl = oob_ctrl; - - return i * 2 + 1; /* Number of descriptors */ -} - -static int lpc32xx_start_slc_dma(struct nand_device *nand, uint32_t count, - int do_wait) -{ - struct target *target = nand->target; - int retval; - - /* DMACIntTCClear = ch0 */ - retval = target_write_u32(target, 0x31000008, 1); - if (ERROR_OK != retval) { - LOG_ERROR("Could not set DMACIntTCClear"); - return retval; - } - - /* DMACIntErrClear = ch0 */ - retval = target_write_u32(target, 0x31000010, 1); - if (ERROR_OK != retval) { - LOG_ERROR("Could not set DMACIntErrClear"); - return retval; - } - - /* DMACCxConfig= - E=1, - SrcPeripheral = 1 (SLC), - DestPeripheral = 1 (SLC), - FlowCntrl = 2 (Pher -> Mem, DMA), - IE = 0, - ITC = 0, - L= 0, - H=0 - */ - retval = target_write_u32(target, 0x31000110, - 1 | 1<<1 | 1<<6 | 2<<11 | 0<<14 - | 0<<15 | 0<<16 | 0<<18); - if (ERROR_OK != retval) { - LOG_ERROR("Could not set DMACC0Config"); - return retval; - } - - /* SLC_CTRL = 3 (START DMA), ECC_CLEAR */ - retval = target_write_u32(target, 0x20020010, 0x3); - if (ERROR_OK != retval) { - LOG_ERROR("Could not set SLC_CTRL"); - return retval; - } - - /* SLC_ICR = 2, INT_TC_CLR, clear pending TC*/ - retval = target_write_u32(target, 0x20020028, 2); - if (ERROR_OK != retval) { - LOG_ERROR("Could not set SLC_ICR"); - return retval; - } - - /* SLC_TC */ - retval = target_write_u32(target, 0x20020030, count); - if (ERROR_OK != retval) { - LOG_ERROR("lpc32xx_start_slc_dma: Could not set SLC_TC"); - return retval; - } - - /* Wait finish */ - if (do_wait && !lpc32xx_tc_ready(nand, 100)) { - LOG_ERROR("timeout while waiting for completion of DMA"); - return ERROR_NAND_OPERATION_FAILED; - } - - return retval; -} - -static int lpc32xx_dma_ready(struct nand_device *nand, int timeout) -{ - struct target *target = nand->target; - - LOG_DEBUG("lpc32xx_dma_ready count start=%d", timeout); - - do { - uint32_t tc_stat; - uint32_t err_stat; - int retval; - - /* Read DMACRawIntTCStat */ - retval = target_read_u32(target, 0x31000014, &tc_stat); - if (ERROR_OK != retval) { - LOG_ERROR("Could not read DMACRawIntTCStat"); - return 0; - } - /* Read DMACRawIntErrStat */ - retval = target_read_u32(target, 0x31000018, &err_stat); - if (ERROR_OK != retval) { - LOG_ERROR("Could not read DMACRawIntErrStat"); - return 0; - } - if ((tc_stat | err_stat) & 1) { - LOG_DEBUG("lpc32xx_dma_ready count=%d", - timeout); - if (err_stat & 1) { - LOG_ERROR("lpc32xx_dma_ready " - "DMA error, aborted"); - return 0; - } else - return 1; - } - - alive_sleep(1); - } while (timeout-- > 0); - - return 0; -} - -static uint32_t slc_ecc_copy_to_buffer(uint8_t *spare, - const uint32_t *ecc, int count) -{ - int i; - for (i = 0; i < (count * 3); i += 3) { - uint32_t ce = ecc[i/3]; - ce = ~(ce << 2) & 0xFFFFFF; - spare[i+2] = (uint8_t)(ce & 0xFF); ce >>= 8; - spare[i+1] = (uint8_t)(ce & 0xFF); ce >>= 8; - spare[i] = (uint8_t)(ce & 0xFF); - } - return 0; -} - -static void lpc32xx_dump_oob(uint8_t *oob, uint32_t oob_size) -{ - int addr = 0; - while (oob_size > 0) { - LOG_DEBUG("%02x: %02x %02x %02x %02x %02x %02x %02x %02x", addr, - oob[0], oob[1], oob[2], oob[3], - oob[4], oob[5], oob[6], oob[7]); - oob += 8; - addr += 8; - oob_size -= 8; - } -} - -static int lpc32xx_write_page_slc(struct nand_device *nand, - struct working_area *pworking_area, - uint32_t page, uint8_t *data, - uint32_t data_size, uint8_t *oob, - uint32_t oob_size) -{ - struct target *target = nand->target; - int retval; - uint32_t target_mem_base; - - LOG_DEBUG("SLC write page %" PRIx32 " data=%d, oob=%d, " - "data_size=%" PRIu32 ", oob_size=%" PRIu32, - page, data != 0, oob != 0, data_size, oob_size); - - target_mem_base = pworking_area->address; - /* - * Skip writting page which has all 0xFF data as this will - * generate 0x0 value. - */ - if (data && !oob) { - uint32_t i, all_ff = 1; - for (i = 0; i < data_size; i++) - if (data[i] != 0xFF) { - all_ff = 0; - break; - } - if (all_ff) - return ERROR_OK; - } - /* Make the dma descriptors in local memory */ - int nll = lpc32xx_make_dma_list(target_mem_base, nand->page_size, 0); - /* Write them to target. - XXX: Assumes host and target have same byte sex. - */ - retval = target_write_memory(target, target_mem_base, 4, - nll * sizeof(dmac_ll_t) / 4, - (uint8_t *)dmalist); - if (ERROR_OK != retval) { - LOG_ERROR("Could not write DMA descriptors to IRAM"); - return retval; - } - - retval = nand_page_command(nand, page, NAND_CMD_SEQIN, !data); - if (ERROR_OK != retval) { - LOG_ERROR("NAND_CMD_SEQIN failed"); - return retval; - } - - /* SLC_CFG = - Force nCE assert, - DMA ECC enabled, - ECC enabled, - DMA burst enabled, - DMA write to SLC, - WIDTH = bus_width - */ - retval = target_write_u32(target, 0x20020014, 0x3c); - if (ERROR_OK != retval) { - LOG_ERROR("Could not set SLC_CFG"); - return retval; - } - if (data) { - /* Write data to target */ - static uint8_t fdata[2048]; - memset(fdata, 0xFF, nand->page_size); - memcpy(fdata, data, data_size); - retval = target_write_memory(target, - target_mem_base + DATA_OFFS, - 4, nand->page_size/4, fdata); - if (ERROR_OK != retval) { - LOG_ERROR("Could not write data to IRAM"); - return retval; - } - - /* Write first decriptor to DMA controller */ - retval = target_write_memory(target, 0x31000100, 4, - sizeof(dmac_ll_t) / 4, - (uint8_t *)dmalist); - if (ERROR_OK != retval) { - LOG_ERROR("Could not write DMA descriptor to DMAC"); - return retval; - } - - /* Start xfer of data from iram to flash using DMA */ - int tot_size = nand->page_size; - tot_size += tot_size == 2048 ? 64 : 16; - retval = lpc32xx_start_slc_dma(nand, tot_size, 0); - if (ERROR_OK != retval) { - LOG_ERROR("DMA failed"); - return retval; - } - - /* Wait for DMA to finish. SLC is not finished at this stage */ - if (!lpc32xx_dma_ready(nand, 100)) { - LOG_ERROR("Data DMA failed during write"); - return ERROR_FLASH_OPERATION_FAILED; - } - } /* data xfer */ - - /* Copy OOB to iram */ - static uint8_t foob[64]; - int foob_size = nand->page_size == 2048 ? 64 : 16; - memset(foob, 0xFF, foob_size); - if (oob) /* Raw mode */ - memcpy(foob, oob, oob_size); - else { - /* Get HW generated ECC, made while writing data */ - int ecc_count = nand->page_size == 2048 ? 8 : 2; - static uint32_t hw_ecc[8]; - retval = target_read_memory(target, target_mem_base + ECC_OFFS, - 4, ecc_count, (uint8_t *)hw_ecc); - if (ERROR_OK != retval) { - LOG_ERROR("Reading hw generated ECC from IRAM failed"); - return retval; - } - /* Copy to oob, at correct offsets */ - static uint8_t ecc[24]; - slc_ecc_copy_to_buffer(ecc, hw_ecc, ecc_count); - const int *layout = nand->page_size == 2048 ? lp_ooblayout : sp_ooblayout; - int i; - for (i = 0; i < ecc_count * 3; i++) - foob[layout[i]] = ecc[i]; - lpc32xx_dump_oob(foob, foob_size); - } - retval = target_write_memory(target, target_mem_base + SPARE_OFFS, 4, - foob_size / 4, foob); - if (ERROR_OK != retval) { - LOG_ERROR("Writing OOB to IRAM failed"); - return retval; - } - - /* Write OOB decriptor to DMA controller */ - retval = target_write_memory(target, 0x31000100, 4, - sizeof(dmac_ll_t) / 4, - (uint8_t *)(&dmalist[nll-1])); - if (ERROR_OK != retval) { - LOG_ERROR("Could not write OOB DMA descriptor to DMAC"); - return retval; - } - if (data) { - /* Only restart DMA with last descriptor, - * don't setup SLC again */ - - /* DMACIntTCClear = ch0 */ - retval = target_write_u32(target, 0x31000008, 1); - if (ERROR_OK != retval) { - LOG_ERROR("Could not set DMACIntTCClear"); - return retval; - } - /* DMACCxConfig= - * E=1, - * SrcPeripheral = 1 (SLC), - * DestPeripheral = 1 (SLC), - * FlowCntrl = 2 (Pher -> Mem, DMA), - * IE = 0, - * ITC = 0, - * L= 0, - * H=0 - */ - retval = target_write_u32(target, 0x31000110, - 1 | 1<<1 | 1<<6 | 2<<11 | 0<<14 - | 0<<15 | 0<<16 | 0<<18); - if (ERROR_OK != retval) { - LOG_ERROR("Could not set DMACC0Config"); - return retval; - } - /* Wait finish */ - if (!lpc32xx_tc_ready(nand, 100)) { - LOG_ERROR("timeout while waiting for " - "completion of DMA"); - return ERROR_NAND_OPERATION_FAILED; - } - } else { - /* Start xfer of data from iram to flash using DMA */ - retval = lpc32xx_start_slc_dma(nand, foob_size, 1); - if (ERROR_OK != retval) { - LOG_ERROR("DMA OOB failed"); - return retval; - } - } - - /* Let NAND start actual writing */ - retval = nand_write_finish(nand); - if (ERROR_OK != retval) { - LOG_ERROR("nand_write_finish failed"); - return retval; - } - - return ERROR_OK; -} - -static int lpc32xx_write_page(struct nand_device *nand, uint32_t page, - uint8_t *data, uint32_t data_size, - uint8_t *oob, uint32_t oob_size) -{ - struct lpc32xx_nand_controller *lpc32xx_info = nand->controller_priv; - struct target *target = nand->target; - int retval = ERROR_OK; - - if (target->state != TARGET_HALTED) { - LOG_ERROR("target must be halted to use LPC32xx " - "NAND flash controller"); - return ERROR_NAND_OPERATION_FAILED; - } - - if (lpc32xx_info->selected_controller == LPC32xx_NO_CONTROLLER) { - LOG_ERROR("BUG: no LPC32xx NAND flash controller selected"); - return ERROR_NAND_OPERATION_FAILED; - } else if (lpc32xx_info->selected_controller == LPC32xx_MLC_CONTROLLER) { - if (!data && oob) { - LOG_ERROR("LPC32xx MLC controller can't write " - "OOB data only"); - return ERROR_NAND_OPERATION_NOT_SUPPORTED; - } - - if (oob && (oob_size > 24)) { - LOG_ERROR("LPC32xx MLC controller can't write more " - "than 6 bytes for each quarter's OOB data"); - return ERROR_NAND_OPERATION_NOT_SUPPORTED; - } - - if (data_size > (uint32_t)nand->page_size) { - LOG_ERROR("data size exceeds page size"); - return ERROR_NAND_OPERATION_NOT_SUPPORTED; - } - - retval = lpc32xx_write_page_mlc(nand, page, data, data_size, - oob, oob_size); - } else if (lpc32xx_info->selected_controller == LPC32xx_SLC_CONTROLLER) { - struct working_area *pworking_area; - if (!data && oob) { - /* - * if oob only mode is active original method is used - * as SLC controller hangs during DMA interworking. (?) - * Anyway the code supports the oob only mode below. - */ - return nand_write_page_raw(nand, page, data, - data_size, oob, oob_size); - } - retval = target_alloc_working_area(target, - nand->page_size + DATA_OFFS, - &pworking_area); - if (retval != ERROR_OK) { - LOG_ERROR("Can't allocate working area in " - "LPC internal RAM"); - return ERROR_FLASH_OPERATION_FAILED; - } - retval = lpc32xx_write_page_slc(nand, pworking_area, page, - data, data_size, oob, oob_size); - target_free_working_area(target, pworking_area); - } - - return retval; -} - -static int lpc32xx_read_page_mlc(struct nand_device *nand, uint32_t page, - uint8_t *data, uint32_t data_size, - uint8_t *oob, uint32_t oob_size) -{ - struct target *target = nand->target; - static uint8_t page_buffer[2048]; - static uint8_t oob_buffer[64]; - uint32_t page_bytes_done = 0; - uint32_t oob_bytes_done = 0; - uint32_t mlc_isr; - int retval; - - if (!data && oob) { - /* MLC_CMD = Read OOB - * we can use the READOOB command on both small and large page - * devices, as the controller translates the 0x50 command to - * a 0x0 with appropriate positioning of the serial buffer - * read pointer - */ - retval = target_write_u32(target, 0x200b8000, NAND_CMD_READOOB); - } else { - /* MLC_CMD = Read0 */ - retval = target_write_u32(target, 0x200b8000, NAND_CMD_READ0); - } - if (ERROR_OK != retval) { - LOG_ERROR("could not set MLC_CMD"); - return ERROR_NAND_OPERATION_FAILED; - } - if (nand->page_size == 512) { - /* small page device - * MLC_ADDR = 0x0 (one column cycle) */ - retval = target_write_u32(target, 0x200b8004, 0x0); - if (ERROR_OK != retval) { - LOG_ERROR("could not set MLC_ADDR"); - return ERROR_NAND_OPERATION_FAILED; - } - - /* MLC_ADDR = row */ - retval = target_write_u32(target, 0x200b8004, page & 0xff); - if (ERROR_OK != retval) { - LOG_ERROR("could not set MLC_ADDR"); - return ERROR_NAND_OPERATION_FAILED; - } - retval = target_write_u32(target, 0x200b8004, - (page >> 8) & 0xff); - if (ERROR_OK != retval) { - LOG_ERROR("could not set MLC_ADDR"); - return ERROR_NAND_OPERATION_FAILED; - } - - if (nand->address_cycles == 4) { - retval = target_write_u32(target, 0x200b8004, - (page >> 16) & 0xff); - if (ERROR_OK != retval) { - LOG_ERROR("could not set MLC_ADDR"); - return ERROR_NAND_OPERATION_FAILED; - } - } - } else { - /* large page device - * MLC_ADDR = 0x0 (two column cycles) */ - retval = target_write_u32(target, 0x200b8004, 0x0); - if (ERROR_OK != retval) { - LOG_ERROR("could not set MLC_ADDR"); - return ERROR_NAND_OPERATION_FAILED; - } - retval = target_write_u32(target, 0x200b8004, 0x0); - if (ERROR_OK != retval) { - LOG_ERROR("could not set MLC_ADDR"); - return ERROR_NAND_OPERATION_FAILED; - } - - /* MLC_ADDR = row */ - retval = target_write_u32(target, 0x200b8004, page & 0xff); - if (ERROR_OK != retval) { - LOG_ERROR("could not set MLC_ADDR"); - return ERROR_NAND_OPERATION_FAILED; - } - retval = target_write_u32(target, 0x200b8004, - (page >> 8) & 0xff); - if (ERROR_OK != retval) { - LOG_ERROR("could not set MLC_ADDR"); - return ERROR_NAND_OPERATION_FAILED; - } - - /* MLC_CMD = Read Start */ - retval = target_write_u32(target, 0x200b8000, - NAND_CMD_READSTART); - if (ERROR_OK != retval) { - LOG_ERROR("could not set MLC_CMD"); - return ERROR_NAND_OPERATION_FAILED; - } - } - - while (page_bytes_done < (uint32_t)nand->page_size) { - /* MLC_ECC_AUTO_DEC_REG = dummy */ - retval = target_write_u32(target, 0x200b8014, 0xaa55aa55); - if (ERROR_OK != retval) { - LOG_ERROR("could not set MLC_ECC_AUTO_DEC_REG"); - return ERROR_NAND_OPERATION_FAILED; - } - - if (!lpc32xx_controller_ready(nand, 1000)) { - LOG_ERROR("timeout while waiting for " - "completion of auto decode cycle"); - return ERROR_NAND_OPERATION_FAILED; - } - - retval = target_read_u32(target, 0x200b8048, &mlc_isr); - if (ERROR_OK != retval) { - LOG_ERROR("could not read MLC_ISR"); - return ERROR_NAND_OPERATION_FAILED; - } - - if (mlc_isr & 0x8) { - if (mlc_isr & 0x40) { - LOG_ERROR("uncorrectable error detected: " - "0x%2.2x", (unsigned)mlc_isr); - return ERROR_NAND_OPERATION_FAILED; - } - - LOG_WARNING("%i symbol error detected and corrected", - ((int)(((mlc_isr & 0x30) >> 4) + 1))); - } - - if (data) { - retval = target_read_memory(target, 0x200a8000, 4, 128, - page_buffer + page_bytes_done); - if (ERROR_OK != retval) { - LOG_ERROR("could not read MLC_BUF (data)"); - return ERROR_NAND_OPERATION_FAILED; - } - } - - if (oob) { - retval = target_read_memory(target, 0x200a8000, 4, 4, - oob_buffer + oob_bytes_done); - if (ERROR_OK != retval) { - LOG_ERROR("could not read MLC_BUF (oob)"); - return ERROR_NAND_OPERATION_FAILED; - } - } - - page_bytes_done += 512; - oob_bytes_done += 16; - } - - if (data) - memcpy(data, page_buffer, data_size); - - if (oob) - memcpy(oob, oob_buffer, oob_size); - - return ERROR_OK; -} - -static int lpc32xx_read_page_slc(struct nand_device *nand, - struct working_area *pworking_area, - uint32_t page, uint8_t *data, - uint32_t data_size, uint8_t *oob, - uint32_t oob_size) -{ - struct target *target = nand->target; - int retval; - uint32_t target_mem_base; - - LOG_DEBUG("SLC read page %" PRIx32 " data=%" PRIu32 ", oob=%" PRIu32, - page, data_size, oob_size); - - target_mem_base = pworking_area->address; - - /* Make the dma descriptors in local memory */ - int nll = lpc32xx_make_dma_list(target_mem_base, nand->page_size, 1); - /* Write them to target. - XXX: Assumes host and target have same byte sex. - */ - retval = target_write_memory(target, target_mem_base, 4, - nll * sizeof(dmac_ll_t) / 4, - (uint8_t *)dmalist); - if (ERROR_OK != retval) { - LOG_ERROR("Could not write DMA descriptors to IRAM"); - return retval; - } - - retval = nand_page_command(nand, page, NAND_CMD_READ0, 0); - if (ERROR_OK != retval) { - LOG_ERROR("lpc32xx_read_page_slc: NAND_CMD_READ0 failed"); - return retval; - } - - /* SLC_CFG = - Force nCE assert, - DMA ECC enabled, - ECC enabled, - DMA burst enabled, - DMA read from SLC, - WIDTH = bus_width - */ - retval = target_write_u32(target, 0x20020014, 0x3e); - if (ERROR_OK != retval) { - LOG_ERROR("lpc32xx_read_page_slc: Could not set SLC_CFG"); - return retval; - } - - /* Write first decriptor to DMA controller */ - retval = target_write_memory(target, 0x31000100, 4, - sizeof(dmac_ll_t) / 4, (uint8_t *)dmalist); - if (ERROR_OK != retval) { - LOG_ERROR("Could not write DMA descriptor to DMAC"); - return retval; - } - - /* Start xfer of data from flash to iram using DMA */ - int tot_size = nand->page_size; - tot_size += nand->page_size == 2048 ? 64 : 16; - retval = lpc32xx_start_slc_dma(nand, tot_size, 1); - if (ERROR_OK != retval) { - LOG_ERROR("lpc32xx_read_page_slc: DMA read failed"); - return retval; - } - - /* Copy data from iram */ - if (data) { - retval = target_read_memory(target, target_mem_base + DATA_OFFS, - 4, data_size/4, data); - if (ERROR_OK != retval) { - LOG_ERROR("Could not read data from IRAM"); - return retval; - } - } - if (oob) { - /* No error correction, just return data as read from flash */ - retval = target_read_memory(target, - target_mem_base + SPARE_OFFS, 4, - oob_size/4, oob); - if (ERROR_OK != retval) { - LOG_ERROR("Could not read OOB from IRAM"); - return retval; - } - return ERROR_OK; - } - - /* Copy OOB from flash, stored in IRAM */ - static uint8_t foob[64]; - retval = target_read_memory(target, target_mem_base + SPARE_OFFS, - 4, nand->page_size == 2048 ? 16 : 4, foob); - lpc32xx_dump_oob(foob, nand->page_size == 2048 ? 64 : 16); - if (ERROR_OK != retval) { - LOG_ERROR("Could not read OOB from IRAM"); - return retval; - } - /* Copy ECC from HW, generated while reading */ - int ecc_count = nand->page_size == 2048 ? 8 : 2; - static uint32_t hw_ecc[8]; /* max size */ - retval = target_read_memory(target, target_mem_base + ECC_OFFS, 4, - ecc_count, (uint8_t *)hw_ecc); - if (ERROR_OK != retval) { - LOG_ERROR("Could not read hw generated ECC from IRAM"); - return retval; - } - static uint8_t ecc[24]; - slc_ecc_copy_to_buffer(ecc, hw_ecc, ecc_count); - /* Copy ECC from flash using correct layout */ - static uint8_t fecc[24];/* max size */ - const int *layout = nand->page_size == 2048 ? lp_ooblayout : sp_ooblayout; - int i; - for (i = 0; i < ecc_count * 3; i++) - fecc[i] = foob[layout[i]]; - /* Compare ECC and possibly correct data */ - for (i = 0; i < ecc_count; i++) { - retval = nand_correct_data(nand, data + 256*i, &fecc[i * 3], - &ecc[i * 3]); - if (retval > 0) - LOG_WARNING("error detected and corrected: %" PRIu32 "/%d", - page, i); - if (retval < 0) - break; - } - if (i == ecc_count) - retval = ERROR_OK; - else { - LOG_ERROR("uncorrectable error detected: %" PRIu32 "/%d", page, i); - retval = ERROR_NAND_OPERATION_FAILED; - } - return retval; -} - -static int lpc32xx_read_page(struct nand_device *nand, uint32_t page, - uint8_t *data, uint32_t data_size, - uint8_t *oob, uint32_t oob_size) -{ - struct lpc32xx_nand_controller *lpc32xx_info = nand->controller_priv; - struct target *target = nand->target; - int retval = ERROR_OK; - - if (target->state != TARGET_HALTED) { - LOG_ERROR("target must be halted to use LPC32xx " - "NAND flash controller"); - return ERROR_NAND_OPERATION_FAILED; - } - - if (lpc32xx_info->selected_controller == LPC32xx_NO_CONTROLLER) { - LOG_ERROR("BUG: no LPC32xx NAND flash controller selected"); - return ERROR_NAND_OPERATION_FAILED; - } else if (lpc32xx_info->selected_controller == LPC32xx_MLC_CONTROLLER) { - if (data_size > (uint32_t)nand->page_size) { - LOG_ERROR("data size exceeds page size"); - return ERROR_NAND_OPERATION_NOT_SUPPORTED; - } - retval = lpc32xx_read_page_mlc(nand, page, data, data_size, - oob, oob_size); - } else if (lpc32xx_info->selected_controller == LPC32xx_SLC_CONTROLLER) { - struct working_area *pworking_area; - - retval = target_alloc_working_area(target, - nand->page_size + 0x200, - &pworking_area); - if (retval != ERROR_OK) { - LOG_ERROR("Can't allocate working area in " - "LPC internal RAM"); - return ERROR_FLASH_OPERATION_FAILED; - } - retval = lpc32xx_read_page_slc(nand, pworking_area, page, - data, data_size, oob, oob_size); - target_free_working_area(target, pworking_area); - } - - return retval; -} - -static int lpc32xx_controller_ready(struct nand_device *nand, int timeout) -{ - struct lpc32xx_nand_controller *lpc32xx_info = nand->controller_priv; - struct target *target = nand->target; - int retval; - - if (target->state != TARGET_HALTED) { - LOG_ERROR("target must be halted to use LPC32xx " - "NAND flash controller"); - return ERROR_NAND_OPERATION_FAILED; - } - - LOG_DEBUG("lpc32xx_controller_ready count start=%d", timeout); - - do { - if (lpc32xx_info->selected_controller == LPC32xx_MLC_CONTROLLER) { - uint8_t status; - - /* Read MLC_ISR, wait for controller to become ready */ - retval = target_read_u8(target, 0x200b8048, &status); - if (ERROR_OK != retval) { - LOG_ERROR("could not set MLC_STAT"); - return ERROR_NAND_OPERATION_FAILED; - } - - if (status & 2) { - LOG_DEBUG("lpc32xx_controller_ready count=%d", - timeout); - return 1; - } - } else if (lpc32xx_info->selected_controller == LPC32xx_SLC_CONTROLLER) { - uint32_t status; - - /* Read SLC_STAT and check READY bit */ - retval = target_read_u32(target, 0x20020018, &status); - if (ERROR_OK != retval) { - LOG_ERROR("could not set SLC_STAT"); - return ERROR_NAND_OPERATION_FAILED; - } - - if (status & 1) { - LOG_DEBUG("lpc32xx_controller_ready count=%d", - timeout); - return 1; - } - } - - alive_sleep(1); - } while (timeout-- > 0); - - return 0; -} - -static int lpc32xx_nand_ready(struct nand_device *nand, int timeout) -{ - struct lpc32xx_nand_controller *lpc32xx_info = nand->controller_priv; - struct target *target = nand->target; - int retval; - - if (target->state != TARGET_HALTED) { - LOG_ERROR("target must be halted to use LPC32xx " - "NAND flash controller"); - return ERROR_NAND_OPERATION_FAILED; - } - - LOG_DEBUG("lpc32xx_nand_ready count start=%d", timeout); - - do { - if (lpc32xx_info->selected_controller == LPC32xx_MLC_CONTROLLER) { - uint8_t status = 0x0; - - /* Read MLC_ISR, wait for NAND flash device to - * become ready */ - retval = target_read_u8(target, 0x200b8048, &status); - if (ERROR_OK != retval) { - LOG_ERROR("could not read MLC_ISR"); - return ERROR_NAND_OPERATION_FAILED; - } - - if (status & 1) { - LOG_DEBUG("lpc32xx_nand_ready count end=%d", - timeout); - return 1; - } - } else if (lpc32xx_info->selected_controller == LPC32xx_SLC_CONTROLLER) { - uint32_t status = 0x0; - - /* Read SLC_STAT and check READY bit */ - retval = target_read_u32(target, 0x20020018, &status); - if (ERROR_OK != retval) { - LOG_ERROR("could not read SLC_STAT"); - return ERROR_NAND_OPERATION_FAILED; - } - - if (status & 1) { - LOG_DEBUG("lpc32xx_nand_ready count end=%d", - timeout); - return 1; - } - } - - alive_sleep(1); - } while (timeout-- > 0); - - return 0; -} - -static int lpc32xx_tc_ready(struct nand_device *nand, int timeout) -{ - struct target *target = nand->target; - - LOG_DEBUG("lpc32xx_tc_ready count start=%d", timeout); - - do { - uint32_t status = 0x0; - int retval; - /* Read SLC_INT_STAT and check INT_TC_STAT bit */ - retval = target_read_u32(target, 0x2002001c, &status); - if (ERROR_OK != retval) { - LOG_ERROR("Could not read SLC_INT_STAT"); - return 0; - } - if (status & 2) { - LOG_DEBUG("lpc32xx_tc_ready count=%d", timeout); - return 1; - } - - alive_sleep(1); - } while (timeout-- > 0); - - return 0; -} - -COMMAND_HANDLER(handle_lpc32xx_select_command) -{ - struct lpc32xx_nand_controller *lpc32xx_info = NULL; - char *selected[] = { - "no", "mlc", "slc" - }; - - if ((CMD_ARGC < 1) || (CMD_ARGC > 3)) - return ERROR_COMMAND_SYNTAX_ERROR; - - unsigned num; - COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], num); - struct nand_device *nand = get_nand_device_by_num(num); - if (!nand) { - command_print(CMD_CTX, "nand device '#%s' is out of bounds", - CMD_ARGV[0]); - return ERROR_OK; - } - - lpc32xx_info = nand->controller_priv; - - if (CMD_ARGC >= 2) { - if (strcmp(CMD_ARGV[1], "mlc") == 0) { - lpc32xx_info->selected_controller = - LPC32xx_MLC_CONTROLLER; - } else if (strcmp(CMD_ARGV[1], "slc") == 0) { - lpc32xx_info->selected_controller = - LPC32xx_SLC_CONTROLLER; - } else - return ERROR_COMMAND_SYNTAX_ERROR; - } - - command_print(CMD_CTX, "%s controller selected", - selected[lpc32xx_info->selected_controller]); - - return ERROR_OK; -} - -static const struct command_registration lpc32xx_exec_command_handlers[] = { - { - .name = "select", - .handler = handle_lpc32xx_select_command, - .mode = COMMAND_EXEC, - .help = "select MLC or SLC controller (default is MLC)", - .usage = "bank_id ['mlc'|'slc' ]", - }, - COMMAND_REGISTRATION_DONE -}; -static const struct command_registration lpc32xx_command_handler[] = { - { - .name = "lpc32xx", - .mode = COMMAND_ANY, - .help = "LPC32xx NAND flash controller commands", - .usage = "", - .chain = lpc32xx_exec_command_handlers, - }, - COMMAND_REGISTRATION_DONE -}; - -struct nand_flash_controller lpc32xx_nand_controller = { - .name = "lpc32xx", - .commands = lpc32xx_command_handler, - .nand_device_command = lpc32xx_nand_device_command, - .init = lpc32xx_init, - .reset = lpc32xx_reset, - .command = lpc32xx_command, - .address = lpc32xx_address, - .write_data = lpc32xx_write_data, - .read_data = lpc32xx_read_data, - .write_page = lpc32xx_write_page, - .read_page = lpc32xx_read_page, - .nand_ready = lpc32xx_nand_ready, -}; diff --git a/src/flash/nand/lpc32xx.h b/src/flash/nand/lpc32xx.h deleted file mode 100644 index 90b20b247..000000000 --- a/src/flash/nand/lpc32xx.h +++ /dev/null @@ -1,36 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifndef OPENOCD_FLASH_NAND_LPC32XX_H -#define OPENOCD_FLASH_NAND_LPC32XX_H - -enum lpc32xx_selected_controller { - LPC32xx_NO_CONTROLLER, - LPC32xx_MLC_CONTROLLER, - LPC32xx_SLC_CONTROLLER, -}; - -struct lpc32xx_nand_controller { - int osc_freq; - enum lpc32xx_selected_controller selected_controller; - int sw_write_protection; - uint32_t sw_wp_lower_bound; - uint32_t sw_wp_upper_bound; -}; - -#endif /* OPENOCD_FLASH_NAND_LPC32XX_H */ diff --git a/src/flash/nand/mx3.c b/src/flash/nand/mx3.c deleted file mode 100644 index b61e47535..000000000 --- a/src/flash/nand/mx3.c +++ /dev/null @@ -1,719 +0,0 @@ - -/*************************************************************************** - * Copyright (C) 2009 by Alexei Babich * - * Rezonans plc., Chelyabinsk, Russia * - * impatt@mail.ru * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -/* - * Freescale iMX3* OpenOCD NAND Flash controller support. - * - * Many thanks to Ben Dooks for writing s3c24xx driver. - */ - -/* -driver tested with STMicro NAND512W3A @imx31 -tested "nand probe #", "nand erase # 0 #", "nand dump # file 0 #", "nand write # file 0" -get_next_halfword_from_sram_buffer() not tested -*/ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "imp.h" -#include "mx3.h" -#include - -static const char target_not_halted_err_msg[] = - "target must be halted to use mx3 NAND flash controller"; -static const char data_block_size_err_msg[] = - "minimal granularity is one half-word, %" PRId32 " is incorrect"; -static const char sram_buffer_bounds_err_msg[] = - "trying to access out of SRAM buffer bound (addr=0x%" PRIx32 ")"; -static const char get_status_register_err_msg[] = "can't get NAND status"; -static uint32_t in_sram_address; -static unsigned char sign_of_sequental_byte_read; - -static int test_iomux_settings(struct target *target, uint32_t value, - uint32_t mask, const char *text); -static int initialize_nf_controller(struct nand_device *nand); -static int get_next_byte_from_sram_buffer(struct target *target, uint8_t *value); -static int get_next_halfword_from_sram_buffer(struct target *target, - uint16_t *value); -static int poll_for_complete_op(struct target *target, const char *text); -static int validate_target_state(struct nand_device *nand); -static int do_data_output(struct nand_device *nand); - -static int imx31_command(struct nand_device *nand, uint8_t command); -static int imx31_address(struct nand_device *nand, uint8_t address); - -NAND_DEVICE_COMMAND_HANDLER(imx31_nand_device_command) -{ - struct mx3_nf_controller *mx3_nf_info; - mx3_nf_info = malloc(sizeof(struct mx3_nf_controller)); - if (mx3_nf_info == NULL) { - LOG_ERROR("no memory for nand controller"); - return ERROR_FAIL; - } - - nand->controller_priv = mx3_nf_info; - - if (CMD_ARGC < 3) - return ERROR_COMMAND_SYNTAX_ERROR; - /* - * check hwecc requirements - */ - { - int hwecc_needed; - hwecc_needed = strcmp(CMD_ARGV[2], "hwecc"); - if (hwecc_needed == 0) - mx3_nf_info->flags.hw_ecc_enabled = 1; - else - mx3_nf_info->flags.hw_ecc_enabled = 0; - } - - mx3_nf_info->optype = MX3_NF_DATAOUT_PAGE; - mx3_nf_info->fin = MX3_NF_FIN_NONE; - mx3_nf_info->flags.target_little_endian = - (nand->target->endianness == TARGET_LITTLE_ENDIAN); - - return ERROR_OK; -} - -static int imx31_init(struct nand_device *nand) -{ - struct mx3_nf_controller *mx3_nf_info = nand->controller_priv; - struct target *target = nand->target; - - { - /* - * validate target state - */ - int validate_target_result; - validate_target_result = validate_target_state(nand); - if (validate_target_result != ERROR_OK) - return validate_target_result; - } - - { - uint16_t buffsize_register_content; - target_read_u16(target, MX3_NF_BUFSIZ, &buffsize_register_content); - mx3_nf_info->flags.one_kb_sram = !(buffsize_register_content & 0x000f); - } - - { - uint32_t pcsr_register_content; - target_read_u32(target, MX3_PCSR, &pcsr_register_content); - if (!nand->bus_width) { - nand->bus_width = (pcsr_register_content & 0x80000000) ? 16 : 8; - } else { - pcsr_register_content |= ((nand->bus_width == 16) ? 0x80000000 : 0x00000000); - target_write_u32(target, MX3_PCSR, pcsr_register_content); - } - - if (!nand->page_size) { - nand->page_size = (pcsr_register_content & 0x40000000) ? 2048 : 512; - } else { - pcsr_register_content |= ((nand->page_size == 2048) ? 0x40000000 : 0x00000000); - target_write_u32(target, MX3_PCSR, pcsr_register_content); - } - if (mx3_nf_info->flags.one_kb_sram && (nand->page_size == 2048)) { - LOG_ERROR("NAND controller have only 1 kb SRAM, " - "so pagesize 2048 is incompatible with it"); - } - } - - { - uint32_t cgr_register_content; - target_read_u32(target, MX3_CCM_CGR2, &cgr_register_content); - if (!(cgr_register_content & 0x00000300)) { - LOG_ERROR("clock gating to EMI disabled"); - return ERROR_FAIL; - } - } - - { - uint32_t gpr_register_content; - target_read_u32(target, MX3_GPR, &gpr_register_content); - if (gpr_register_content & 0x00000060) { - LOG_ERROR("pins mode overrided by GPR"); - return ERROR_FAIL; - } - } - - { - /* - * testing IOMUX settings; must be in "functional-mode output and - * functional-mode input" mode - */ - int test_iomux; - test_iomux = ERROR_OK; - test_iomux |= test_iomux_settings(target, 0x43fac0c0, 0x7f7f7f00, "d0,d1,d2"); - test_iomux |= test_iomux_settings(target, 0x43fac0c4, 0x7f7f7f7f, "d3,d4,d5,d6"); - test_iomux |= test_iomux_settings(target, 0x43fac0c8, 0x0000007f, "d7"); - if (nand->bus_width == 16) { - test_iomux |= test_iomux_settings(target, 0x43fac0c8, 0x7f7f7f00, "d8,d9,d10"); - test_iomux |= test_iomux_settings(target, 0x43fac0cc, 0x7f7f7f7f, "d11,d12,d13,d14"); - test_iomux |= test_iomux_settings(target, 0x43fac0d0, 0x0000007f, "d15"); - } - test_iomux |= test_iomux_settings(target, 0x43fac0d0, 0x7f7f7f00, "nfwp,nfce,nfrb"); - test_iomux |= test_iomux_settings(target, 0x43fac0d4, 0x7f7f7f7f, - "nfwe,nfre,nfale,nfcle"); - if (test_iomux != ERROR_OK) - return ERROR_FAIL; - } - - initialize_nf_controller(nand); - - { - int retval; - uint16_t nand_status_content; - retval = ERROR_OK; - retval |= imx31_command(nand, NAND_CMD_STATUS); - retval |= imx31_address(nand, 0x00); - retval |= do_data_output(nand); - if (retval != ERROR_OK) { - LOG_ERROR(get_status_register_err_msg); - return ERROR_FAIL; - } - target_read_u16(target, MX3_NF_MAIN_BUFFER0, &nand_status_content); - if (!(nand_status_content & 0x0080)) { - /* - * is host-big-endian correctly ?? - */ - LOG_INFO("NAND read-only"); - mx3_nf_info->flags.nand_readonly = 1; - } else - mx3_nf_info->flags.nand_readonly = 0; - } - return ERROR_OK; -} - -static int imx31_read_data(struct nand_device *nand, void *data) -{ - struct target *target = nand->target; - { - /* - * validate target state - */ - int validate_target_result; - validate_target_result = validate_target_state(nand); - if (validate_target_result != ERROR_OK) - return validate_target_result; - } - - { - /* - * get data from nand chip - */ - int try_data_output_from_nand_chip; - try_data_output_from_nand_chip = do_data_output(nand); - if (try_data_output_from_nand_chip != ERROR_OK) - return try_data_output_from_nand_chip; - } - - if (nand->bus_width == 16) - get_next_halfword_from_sram_buffer(target, data); - else - get_next_byte_from_sram_buffer(target, data); - - return ERROR_OK; -} - -static int imx31_write_data(struct nand_device *nand, uint16_t data) -{ - LOG_ERROR("write_data() not implemented"); - return ERROR_NAND_OPERATION_FAILED; -} - -static int imx31_reset(struct nand_device *nand) -{ - /* - * validate target state - */ - int validate_target_result; - validate_target_result = validate_target_state(nand); - if (validate_target_result != ERROR_OK) - return validate_target_result; - initialize_nf_controller(nand); - return ERROR_OK; -} - -static int imx31_command(struct nand_device *nand, uint8_t command) -{ - struct mx3_nf_controller *mx3_nf_info = nand->controller_priv; - struct target *target = nand->target; - { - /* - * validate target state - */ - int validate_target_result; - validate_target_result = validate_target_state(nand); - if (validate_target_result != ERROR_OK) - return validate_target_result; - } - - switch (command) { - case NAND_CMD_READOOB: - command = NAND_CMD_READ0; - in_sram_address = MX3_NF_SPARE_BUFFER0; /* set read point for - * data_read() and - * read_block_data() to - * spare area in SRAM - * buffer */ - break; - case NAND_CMD_READ1: - command = NAND_CMD_READ0; - /* - * offset == one half of page size - */ - in_sram_address = MX3_NF_MAIN_BUFFER0 + (nand->page_size >> 1); - default: - in_sram_address = MX3_NF_MAIN_BUFFER0; - } - - target_write_u16(target, MX3_NF_FCMD, command); - /* - * start command input operation (set MX3_NF_BIT_OP_DONE==0) - */ - target_write_u16(target, MX3_NF_CFG2, MX3_NF_BIT_OP_FCI); - { - int poll_result; - poll_result = poll_for_complete_op(target, "command"); - if (poll_result != ERROR_OK) - return poll_result; - } - /* - * reset cursor to begin of the buffer - */ - sign_of_sequental_byte_read = 0; - switch (command) { - case NAND_CMD_READID: - mx3_nf_info->optype = MX3_NF_DATAOUT_NANDID; - mx3_nf_info->fin = MX3_NF_FIN_DATAOUT; - break; - case NAND_CMD_STATUS: - mx3_nf_info->optype = MX3_NF_DATAOUT_NANDSTATUS; - mx3_nf_info->fin = MX3_NF_FIN_DATAOUT; - break; - case NAND_CMD_READ0: - mx3_nf_info->fin = MX3_NF_FIN_DATAOUT; - mx3_nf_info->optype = MX3_NF_DATAOUT_PAGE; - break; - default: - mx3_nf_info->optype = MX3_NF_DATAOUT_PAGE; - } - return ERROR_OK; -} - -static int imx31_address(struct nand_device *nand, uint8_t address) -{ - struct target *target = nand->target; - { - /* - * validate target state - */ - int validate_target_result; - validate_target_result = validate_target_state(nand); - if (validate_target_result != ERROR_OK) - return validate_target_result; - } - - target_write_u16(target, MX3_NF_FADDR, address); - /* - * start address input operation (set MX3_NF_BIT_OP_DONE==0) - */ - target_write_u16(target, MX3_NF_CFG2, MX3_NF_BIT_OP_FAI); - { - int poll_result; - poll_result = poll_for_complete_op(target, "address"); - if (poll_result != ERROR_OK) - return poll_result; - } - return ERROR_OK; -} - -static int imx31_nand_ready(struct nand_device *nand, int tout) -{ - uint16_t poll_complete_status; - struct target *target = nand->target; - - { - /* - * validate target state - */ - int validate_target_result; - validate_target_result = validate_target_state(nand); - if (validate_target_result != ERROR_OK) - return validate_target_result; - } - - do { - target_read_u16(target, MX3_NF_CFG2, &poll_complete_status); - if (poll_complete_status & MX3_NF_BIT_OP_DONE) - return tout; - alive_sleep(1); - } while (tout-- > 0); - return tout; -} - -static int imx31_write_page(struct nand_device *nand, uint32_t page, - uint8_t *data, uint32_t data_size, uint8_t *oob, - uint32_t oob_size) -{ - struct mx3_nf_controller *mx3_nf_info = nand->controller_priv; - struct target *target = nand->target; - - if (data_size % 2) { - LOG_ERROR(data_block_size_err_msg, data_size); - return ERROR_NAND_OPERATION_FAILED; - } - if (oob_size % 2) { - LOG_ERROR(data_block_size_err_msg, oob_size); - return ERROR_NAND_OPERATION_FAILED; - } - if (!data) { - LOG_ERROR("nothing to program"); - return ERROR_NAND_OPERATION_FAILED; - } - { - /* - * validate target state - */ - int retval; - retval = validate_target_state(nand); - if (retval != ERROR_OK) - return retval; - } - { - int retval = ERROR_OK; - retval |= imx31_command(nand, NAND_CMD_SEQIN); - retval |= imx31_address(nand, 0x00); - retval |= imx31_address(nand, page & 0xff); - retval |= imx31_address(nand, (page >> 8) & 0xff); - if (nand->address_cycles >= 4) { - retval |= imx31_address(nand, (page >> 16) & 0xff); - if (nand->address_cycles >= 5) - retval |= imx31_address(nand, (page >> 24) & 0xff); - } - target_write_buffer(target, MX3_NF_MAIN_BUFFER0, data_size, data); - if (oob) { - if (mx3_nf_info->flags.hw_ecc_enabled) { - /* - * part of spare block will be overrided by hardware - * ECC generator - */ - LOG_DEBUG("part of spare block will be overrided by hardware ECC generator"); - } - target_write_buffer(target, MX3_NF_SPARE_BUFFER0, oob_size, oob); - } - /* - * start data input operation (set MX3_NF_BIT_OP_DONE==0) - */ - target_write_u16(target, MX3_NF_CFG2, MX3_NF_BIT_OP_FDI); - { - int poll_result; - poll_result = poll_for_complete_op(target, "data input"); - if (poll_result != ERROR_OK) - return poll_result; - } - retval |= imx31_command(nand, NAND_CMD_PAGEPROG); - if (retval != ERROR_OK) - return retval; - - /* - * check status register - */ - { - uint16_t nand_status_content; - retval = ERROR_OK; - retval |= imx31_command(nand, NAND_CMD_STATUS); - retval |= imx31_address(nand, 0x00); - retval |= do_data_output(nand); - if (retval != ERROR_OK) { - LOG_ERROR(get_status_register_err_msg); - return retval; - } - target_read_u16(target, MX3_NF_MAIN_BUFFER0, &nand_status_content); - if (nand_status_content & 0x0001) { - /* - * is host-big-endian correctly ?? - */ - return ERROR_NAND_OPERATION_FAILED; - } - } - } - return ERROR_OK; -} - -static int imx31_read_page(struct nand_device *nand, uint32_t page, - uint8_t *data, uint32_t data_size, uint8_t *oob, - uint32_t oob_size) -{ - struct target *target = nand->target; - - if (data_size % 2) { - LOG_ERROR(data_block_size_err_msg, data_size); - return ERROR_NAND_OPERATION_FAILED; - } - if (oob_size % 2) { - LOG_ERROR(data_block_size_err_msg, oob_size); - return ERROR_NAND_OPERATION_FAILED; - } - - { - /* - * validate target state - */ - int retval; - retval = validate_target_state(nand); - if (retval != ERROR_OK) - return retval; - } - { - int retval = ERROR_OK; - retval |= imx31_command(nand, NAND_CMD_READ0); - retval |= imx31_address(nand, 0x00); - retval |= imx31_address(nand, page & 0xff); - retval |= imx31_address(nand, (page >> 8) & 0xff); - if (nand->address_cycles >= 4) { - retval |= imx31_address(nand, (page >> 16) & 0xff); - if (nand->address_cycles >= 5) { - retval |= imx31_address(nand, (page >> 24) & 0xff); - retval |= imx31_command(nand, NAND_CMD_READSTART); - } - } - retval |= do_data_output(nand); - if (retval != ERROR_OK) - return retval; - - if (data) { - target_read_buffer(target, MX3_NF_MAIN_BUFFER0, data_size, - data); - } - if (oob) { - target_read_buffer(target, MX3_NF_SPARE_BUFFER0, oob_size, - oob); - } - } - return ERROR_OK; -} - -static int test_iomux_settings(struct target *target, uint32_t address, - uint32_t mask, const char *text) -{ - uint32_t register_content; - target_read_u32(target, address, ®ister_content); - if ((register_content & mask) != (0x12121212 & mask)) { - LOG_ERROR("IOMUX for {%s} is bad", text); - return ERROR_FAIL; - } - return ERROR_OK; -} - -static int initialize_nf_controller(struct nand_device *nand) -{ - struct mx3_nf_controller *mx3_nf_info = nand->controller_priv; - struct target *target = nand->target; - /* - * resets NAND flash controller in zero time ? I dont know. - */ - target_write_u16(target, MX3_NF_CFG1, MX3_NF_BIT_RESET_EN); - { - uint16_t work_mode; - work_mode = MX3_NF_BIT_INT_DIS; /* disable interrupt */ - if (target->endianness == TARGET_BIG_ENDIAN) - work_mode |= MX3_NF_BIT_BE_EN; - if (mx3_nf_info->flags.hw_ecc_enabled) - work_mode |= MX3_NF_BIT_ECC_EN; - target_write_u16(target, MX3_NF_CFG1, work_mode); - } - /* - * unlock SRAM buffer for write; 2 mean "Unlock", other values means "Lock" - */ - target_write_u16(target, MX3_NF_BUFCFG, 2); - { - uint16_t temp; - target_read_u16(target, MX3_NF_FWP, &temp); - if ((temp & 0x0007) == 1) { - LOG_ERROR("NAND flash is tight-locked, reset needed"); - return ERROR_FAIL; - } - - } - /* - * unlock NAND flash for write - */ - target_write_u16(target, MX3_NF_FWP, 4); - target_write_u16(target, MX3_NF_LOCKSTART, 0x0000); - target_write_u16(target, MX3_NF_LOCKEND, 0xFFFF); - /* - * 0x0000 means that first SRAM buffer @0xB800_0000 will be used - */ - target_write_u16(target, MX3_NF_BUFADDR, 0x0000); - /* - * address of SRAM buffer - */ - in_sram_address = MX3_NF_MAIN_BUFFER0; - sign_of_sequental_byte_read = 0; - return ERROR_OK; -} - -static int get_next_byte_from_sram_buffer(struct target *target, uint8_t *value) -{ - static uint8_t even_byte; - /* - * host-big_endian ?? - */ - if (sign_of_sequental_byte_read == 0) - even_byte = 0; - if (in_sram_address > MX3_NF_LAST_BUFFER_ADDR) { - LOG_ERROR(sram_buffer_bounds_err_msg, in_sram_address); - *value = 0; - sign_of_sequental_byte_read = 0; - even_byte = 0; - return ERROR_NAND_OPERATION_FAILED; - } else { - uint16_t temp; - target_read_u16(target, in_sram_address, &temp); - if (even_byte) { - *value = temp >> 8; - even_byte = 0; - in_sram_address += 2; - } else { - *value = temp & 0xff; - even_byte = 1; - } - } - sign_of_sequental_byte_read = 1; - return ERROR_OK; -} - -static int get_next_halfword_from_sram_buffer(struct target *target, - uint16_t *value) -{ - if (in_sram_address > MX3_NF_LAST_BUFFER_ADDR) { - LOG_ERROR(sram_buffer_bounds_err_msg, in_sram_address); - *value = 0; - return ERROR_NAND_OPERATION_FAILED; - } else { - target_read_u16(target, in_sram_address, value); - in_sram_address += 2; - } - return ERROR_OK; -} - -static int poll_for_complete_op(struct target *target, const char *text) -{ - uint16_t poll_complete_status; - for (int poll_cycle_count = 0; poll_cycle_count < 100; poll_cycle_count++) { - usleep(25); - target_read_u16(target, MX3_NF_CFG2, &poll_complete_status); - if (poll_complete_status & MX3_NF_BIT_OP_DONE) - break; - } - if (!(poll_complete_status & MX3_NF_BIT_OP_DONE)) { - LOG_ERROR("%s sending timeout", text); - return ERROR_NAND_OPERATION_FAILED; - } - return ERROR_OK; -} - -static int validate_target_state(struct nand_device *nand) -{ - struct mx3_nf_controller *mx3_nf_info = nand->controller_priv; - struct target *target = nand->target; - - if (target->state != TARGET_HALTED) { - LOG_ERROR(target_not_halted_err_msg); - return ERROR_NAND_OPERATION_FAILED; - } - - if (mx3_nf_info->flags.target_little_endian != - (target->endianness == TARGET_LITTLE_ENDIAN)) { - /* - * endianness changed after NAND controller probed - */ - return ERROR_NAND_OPERATION_FAILED; - } - return ERROR_OK; -} - -static int do_data_output(struct nand_device *nand) -{ - struct mx3_nf_controller *mx3_nf_info = nand->controller_priv; - struct target *target = nand->target; - switch (mx3_nf_info->fin) { - case MX3_NF_FIN_DATAOUT: - /* - * start data output operation (set MX3_NF_BIT_OP_DONE==0) - */ - target_write_u16 (target, MX3_NF_CFG2, - MX3_NF_BIT_DATAOUT_TYPE(mx3_nf_info->optype)); - { - int poll_result; - poll_result = poll_for_complete_op(target, "data output"); - if (poll_result != ERROR_OK) - return poll_result; - } - mx3_nf_info->fin = MX3_NF_FIN_NONE; - /* - * ECC stuff - */ - if ((mx3_nf_info->optype == MX3_NF_DATAOUT_PAGE) - && mx3_nf_info->flags.hw_ecc_enabled) { - uint16_t ecc_status; - target_read_u16 (target, MX3_NF_ECCSTATUS, &ecc_status); - switch (ecc_status & 0x000c) { - case 1 << 2: - LOG_DEBUG("main area readed with 1 (correctable) error"); - break; - case 2 << 2: - LOG_DEBUG("main area readed with more than 1 (incorrectable) error"); - return ERROR_NAND_OPERATION_FAILED; - break; - } - switch (ecc_status & 0x0003) { - case 1: - LOG_DEBUG("spare area readed with 1 (correctable) error"); - break; - case 2: - LOG_DEBUG("main area readed with more than 1 (incorrectable) error"); - return ERROR_NAND_OPERATION_FAILED; - break; - } - } - break; - case MX3_NF_FIN_NONE: - break; - } - return ERROR_OK; -} - -struct nand_flash_controller imx31_nand_flash_controller = { - .name = "imx31", - .usage = "nand device imx31 target noecc|hwecc", - .nand_device_command = &imx31_nand_device_command, - .init = &imx31_init, - .reset = &imx31_reset, - .command = &imx31_command, - .address = &imx31_address, - .write_data = &imx31_write_data, - .read_data = &imx31_read_data, - .write_page = &imx31_write_page, - .read_page = &imx31_read_page, - .nand_ready = &imx31_nand_ready, -}; diff --git a/src/flash/nand/mx3.h b/src/flash/nand/mx3.h deleted file mode 100644 index 00664d866..000000000 --- a/src/flash/nand/mx3.h +++ /dev/null @@ -1,112 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2009 by Alexei Babich * - * Rezonans plc., Chelyabinsk, Russia * - * impatt@mail.ru * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifndef OPENOCD_FLASH_NAND_MX3_H -#define OPENOCD_FLASH_NAND_MX3_H - -/* - * Freescale iMX3* OpenOCD NAND Flash controller support. - * - * Many thanks to Ben Dooks for writing s3c24xx driver. - */ - -#define MX3_NF_BASE_ADDR 0xb8000000 -#define MX3_NF_BUFSIZ (MX3_NF_BASE_ADDR + 0xe00) -#define MX3_NF_BUFADDR (MX3_NF_BASE_ADDR + 0xe04) -#define MX3_NF_FADDR (MX3_NF_BASE_ADDR + 0xe06) -#define MX3_NF_FCMD (MX3_NF_BASE_ADDR + 0xe08) -#define MX3_NF_BUFCFG (MX3_NF_BASE_ADDR + 0xe0a) -#define MX3_NF_ECCSTATUS (MX3_NF_BASE_ADDR + 0xe0c) -#define MX3_NF_ECCMAINPOS (MX3_NF_BASE_ADDR + 0xe0e) -#define MX3_NF_ECCSPAREPOS (MX3_NF_BASE_ADDR + 0xe10) -#define MX3_NF_FWP (MX3_NF_BASE_ADDR + 0xe12) -#define MX3_NF_LOCKSTART (MX3_NF_BASE_ADDR + 0xe14) -#define MX3_NF_LOCKEND (MX3_NF_BASE_ADDR + 0xe16) -#define MX3_NF_FWPSTATUS (MX3_NF_BASE_ADDR + 0xe18) -/* - * all bits not marked as self-clearing bit - */ -#define MX3_NF_CFG1 (MX3_NF_BASE_ADDR + 0xe1a) -#define MX3_NF_CFG2 (MX3_NF_BASE_ADDR + 0xe1c) - -#define MX3_NF_MAIN_BUFFER0 (MX3_NF_BASE_ADDR + 0x0000) -#define MX3_NF_MAIN_BUFFER1 (MX3_NF_BASE_ADDR + 0x0200) -#define MX3_NF_MAIN_BUFFER2 (MX3_NF_BASE_ADDR + 0x0400) -#define MX3_NF_MAIN_BUFFER3 (MX3_NF_BASE_ADDR + 0x0600) -#define MX3_NF_SPARE_BUFFER0 (MX3_NF_BASE_ADDR + 0x0800) -#define MX3_NF_SPARE_BUFFER1 (MX3_NF_BASE_ADDR + 0x0810) -#define MX3_NF_SPARE_BUFFER2 (MX3_NF_BASE_ADDR + 0x0820) -#define MX3_NF_SPARE_BUFFER3 (MX3_NF_BASE_ADDR + 0x0830) -#define MX3_NF_MAIN_BUFFER_LEN 512 -#define MX3_NF_SPARE_BUFFER_LEN 16 -#define MX3_NF_LAST_BUFFER_ADDR ((MX3_NF_SPARE_BUFFER3) + MX3_NF_SPARE_BUFFER_LEN - 2) - -/* bits in MX3_NF_CFG1 register */ -#define MX3_NF_BIT_SPARE_ONLY_EN (1<<2) -#define MX3_NF_BIT_ECC_EN (1<<3) -#define MX3_NF_BIT_INT_DIS (1<<4) -#define MX3_NF_BIT_BE_EN (1<<5) -#define MX3_NF_BIT_RESET_EN (1<<6) -#define MX3_NF_BIT_FORCE_CE (1<<7) - -/* bits in MX3_NF_CFG2 register */ - -/*Flash Command Input*/ -#define MX3_NF_BIT_OP_FCI (1<<0) -/* - * Flash Address Input - */ -#define MX3_NF_BIT_OP_FAI (1<<1) -/* - * Flash Data Input - */ -#define MX3_NF_BIT_OP_FDI (1<<2) - -/* see "enum mx_dataout_type" below */ -#define MX3_NF_BIT_DATAOUT_TYPE(x) ((x)<<3) -#define MX3_NF_BIT_OP_DONE (1<<15) - -#define MX3_CCM_CGR2 0x53f80028 -#define MX3_GPR 0x43fac008 -#define MX3_PCSR 0x53f8000c - -enum mx_dataout_type { - MX3_NF_DATAOUT_PAGE = 1, - MX3_NF_DATAOUT_NANDID = 2, - MX3_NF_DATAOUT_NANDSTATUS = 4, -}; -enum mx_nf_finalize_action { - MX3_NF_FIN_NONE, - MX3_NF_FIN_DATAOUT, -}; - -struct mx3_nf_flags { - unsigned target_little_endian:1; - unsigned nand_readonly:1; - unsigned one_kb_sram:1; - unsigned hw_ecc_enabled:1; -}; - -struct mx3_nf_controller { - enum mx_dataout_type optype; - 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 deleted file mode 100644 index 5e59b9a6c..000000000 --- a/src/flash/nand/mxc.c +++ /dev/null @@ -1,960 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2009 by Alexei Babich * - * Rezonans plc., Chelyabinsk, Russia * - * impatt@mail.ru * - * * - * Copyright (C) 2010 by Gaetan CARLIER * - * Trump s.a., Belgium * - * * - * Copyright (C) 2011 by Erik Ahlen * - * Avalon Innovation, Sweden * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -/* - * Freescale iMX OpenOCD NAND Flash controller support. - * based on Freescale iMX2* and iMX3* OpenOCD NAND Flash controller support. - */ - -/* - * driver tested with Samsung K9F2G08UXA and Numonyx/ST NAND02G-B2D @mxc - * tested "nand probe #", "nand erase # 0 #", "nand dump # file 0 #", - * "nand write # file 0", "nand verify" - * - * get_next_halfword_from_sram_buffer() not tested - * !! all function only tested with 2k page nand device; mxc_write_page - * writes the 4 MAIN_BUFFER's and is not compatible with < 2k page - * !! oob must be be used due to NFS bug - * !! oob must be 64 bytes per 2KiB page -*/ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "imp.h" -#include "mxc.h" -#include - -#define OOB_SIZE 64 - -#define nfc_is_v1() (mxc_nf_info->mxc_version == MXC_VERSION_MX27 || \ - mxc_nf_info->mxc_version == MXC_VERSION_MX31) -#define nfc_is_v2() (mxc_nf_info->mxc_version == MXC_VERSION_MX25 || \ - mxc_nf_info->mxc_version == MXC_VERSION_MX35) - -/* This permits to print (in LOG_INFO) how much bytes - * has been written after a page read or write. - * This is useful when OpenOCD is used with a graphical - * front-end to estimate progression of the global read/write - */ -#undef _MXC_PRINT_STAT -/* #define _MXC_PRINT_STAT */ - -static const char target_not_halted_err_msg[] = - "target must be halted to use mxc NAND flash controller"; -static const char data_block_size_err_msg[] = - "minimal granularity is one half-word, %" PRId32 " is incorrect"; -static const char sram_buffer_bounds_err_msg[] = - "trying to access out of SRAM buffer bound (addr=0x%" PRIx32 ")"; -static const char get_status_register_err_msg[] = "can't get NAND status"; -static uint32_t in_sram_address; -static unsigned char sign_of_sequental_byte_read; - -static uint32_t align_address_v2(struct nand_device *nand, uint32_t addr); -static int initialize_nf_controller(struct nand_device *nand); -static int get_next_byte_from_sram_buffer(struct nand_device *nand, uint8_t *value); -static int get_next_halfword_from_sram_buffer(struct nand_device *nand, uint16_t *value); -static int poll_for_complete_op(struct nand_device *nand, const char *text); -static int validate_target_state(struct nand_device *nand); -static int do_data_output(struct nand_device *nand); - -static int mxc_command(struct nand_device *nand, uint8_t command); -static int mxc_address(struct nand_device *nand, uint8_t address); - -NAND_DEVICE_COMMAND_HANDLER(mxc_nand_device_command) -{ - struct mxc_nf_controller *mxc_nf_info; - int hwecc_needed; - - mxc_nf_info = malloc(sizeof(struct mxc_nf_controller)); - if (mxc_nf_info == NULL) { - LOG_ERROR("no memory for nand controller"); - return ERROR_FAIL; - } - nand->controller_priv = mxc_nf_info; - - if (CMD_ARGC < 4) { - LOG_ERROR("use \"nand device mxc target mx25|mx27|mx31|mx35 noecc|hwecc [biswap]\""); - return ERROR_FAIL; - } - - /* - * check board type - */ - if (strcmp(CMD_ARGV[2], "mx25") == 0) { - mxc_nf_info->mxc_version = MXC_VERSION_MX25; - mxc_nf_info->mxc_base_addr = 0xBB000000; - mxc_nf_info->mxc_regs_addr = mxc_nf_info->mxc_base_addr + 0x1E00; - } else if (strcmp(CMD_ARGV[2], "mx27") == 0) { - mxc_nf_info->mxc_version = MXC_VERSION_MX27; - mxc_nf_info->mxc_base_addr = 0xD8000000; - mxc_nf_info->mxc_regs_addr = mxc_nf_info->mxc_base_addr + 0x0E00; - } else if (strcmp(CMD_ARGV[2], "mx31") == 0) { - mxc_nf_info->mxc_version = MXC_VERSION_MX31; - mxc_nf_info->mxc_base_addr = 0xB8000000; - mxc_nf_info->mxc_regs_addr = mxc_nf_info->mxc_base_addr + 0x0E00; - } else if (strcmp(CMD_ARGV[2], "mx35") == 0) { - mxc_nf_info->mxc_version = MXC_VERSION_MX35; - mxc_nf_info->mxc_base_addr = 0xBB000000; - mxc_nf_info->mxc_regs_addr = mxc_nf_info->mxc_base_addr + 0x1E00; - } - - /* - * check hwecc requirements - */ - hwecc_needed = strcmp(CMD_ARGV[3], "hwecc"); - if (hwecc_needed == 0) - mxc_nf_info->flags.hw_ecc_enabled = 1; - else - mxc_nf_info->flags.hw_ecc_enabled = 0; - - mxc_nf_info->optype = MXC_NF_DATAOUT_PAGE; - mxc_nf_info->fin = MXC_NF_FIN_NONE; - mxc_nf_info->flags.target_little_endian = - (nand->target->endianness == TARGET_LITTLE_ENDIAN); - - /* - * should factory bad block indicator be swaped - * as a workaround for how the nfc handles pages. - */ - if (CMD_ARGC > 4 && strcmp(CMD_ARGV[4], "biswap") == 0) { - LOG_DEBUG("BI-swap enabled"); - mxc_nf_info->flags.biswap_enabled = 1; - } - - return ERROR_OK; -} - -COMMAND_HANDLER(handle_mxc_biswap_command) -{ - struct nand_device *nand = NULL; - struct mxc_nf_controller *mxc_nf_info = NULL; - - if (CMD_ARGC < 1 || CMD_ARGC > 2) - return ERROR_COMMAND_SYNTAX_ERROR; - - int retval = CALL_COMMAND_HANDLER(nand_command_get_device, 0, &nand); - if (retval != ERROR_OK) { - command_print(CMD_CTX, "invalid nand device number or name: %s", CMD_ARGV[0]); - return ERROR_COMMAND_ARGUMENT_INVALID; - } - - mxc_nf_info = nand->controller_priv; - if (CMD_ARGC == 2) { - if (strcmp(CMD_ARGV[1], "enable") == 0) - mxc_nf_info->flags.biswap_enabled = true; - else - mxc_nf_info->flags.biswap_enabled = false; - } - if (mxc_nf_info->flags.biswap_enabled) - command_print(CMD_CTX, "BI-swapping enabled on %s", nand->name); - else - command_print(CMD_CTX, "BI-swapping disabled on %s", nand->name); - - return ERROR_OK; -} - -static const struct command_registration mxc_sub_command_handlers[] = { - { - .name = "biswap", - .handler = handle_mxc_biswap_command, - .help = "Turns on/off bad block information swaping from main area, " - "without parameter query status.", - .usage = "bank_id ['enable'|'disable']", - }, - COMMAND_REGISTRATION_DONE -}; - -static const struct command_registration mxc_nand_command_handler[] = { - { - .name = "mxc", - .mode = COMMAND_ANY, - .help = "MXC NAND flash controller commands", - .chain = mxc_sub_command_handlers - }, - COMMAND_REGISTRATION_DONE -}; - -static int mxc_init(struct nand_device *nand) -{ - struct mxc_nf_controller *mxc_nf_info = nand->controller_priv; - struct target *target = nand->target; - - int validate_target_result; - uint16_t buffsize_register_content; - uint32_t sreg_content; - uint32_t SREG = MX2_FMCR; - uint32_t SEL_16BIT = MX2_FMCR_NF_16BIT_SEL; - uint32_t SEL_FMS = MX2_FMCR_NF_FMS; - int retval; - uint16_t nand_status_content; - /* - * validate target state - */ - validate_target_result = validate_target_state(nand); - if (validate_target_result != ERROR_OK) - return validate_target_result; - - if (nfc_is_v1()) { - target_read_u16(target, MXC_NF_BUFSIZ, &buffsize_register_content); - mxc_nf_info->flags.one_kb_sram = !(buffsize_register_content & 0x000f); - } else - mxc_nf_info->flags.one_kb_sram = 0; - - if (mxc_nf_info->mxc_version == MXC_VERSION_MX31) { - SREG = MX3_PCSR; - SEL_16BIT = MX3_PCSR_NF_16BIT_SEL; - SEL_FMS = MX3_PCSR_NF_FMS; - } else if (mxc_nf_info->mxc_version == MXC_VERSION_MX25) { - SREG = MX25_RCSR; - SEL_16BIT = MX25_RCSR_NF_16BIT_SEL; - SEL_FMS = MX25_RCSR_NF_FMS; - } else if (mxc_nf_info->mxc_version == MXC_VERSION_MX35) { - SREG = MX35_RCSR; - SEL_16BIT = MX35_RCSR_NF_16BIT_SEL; - SEL_FMS = MX35_RCSR_NF_FMS; - } - - target_read_u32(target, SREG, &sreg_content); - if (!nand->bus_width) { - /* bus_width not yet defined. Read it from MXC_FMCR */ - nand->bus_width = (sreg_content & SEL_16BIT) ? 16 : 8; - } else { - /* bus_width forced in soft. Sync it to MXC_FMCR */ - sreg_content |= ((nand->bus_width == 16) ? SEL_16BIT : 0x00000000); - target_write_u32(target, SREG, sreg_content); - } - if (nand->bus_width == 16) - LOG_DEBUG("MXC_NF : bus is 16-bit width"); - else - LOG_DEBUG("MXC_NF : bus is 8-bit width"); - - if (!nand->page_size) - nand->page_size = (sreg_content & SEL_FMS) ? 2048 : 512; - else { - sreg_content |= ((nand->page_size == 2048) ? SEL_FMS : 0x00000000); - target_write_u32(target, SREG, sreg_content); - } - if (mxc_nf_info->flags.one_kb_sram && (nand->page_size == 2048)) { - LOG_ERROR("NAND controller have only 1 kb SRAM, so " - "pagesize 2048 is incompatible with it"); - } else - LOG_DEBUG("MXC_NF : NAND controller can handle pagesize of 2048"); - - if (nfc_is_v2() && sreg_content & MX35_RCSR_NF_4K) - LOG_ERROR("MXC driver does not have support for 4k pagesize."); - - initialize_nf_controller(nand); - - retval = ERROR_OK; - retval |= mxc_command(nand, NAND_CMD_STATUS); - retval |= mxc_address(nand, 0x00); - retval |= do_data_output(nand); - if (retval != ERROR_OK) { - LOG_ERROR(get_status_register_err_msg); - return ERROR_FAIL; - } - target_read_u16(target, MXC_NF_MAIN_BUFFER0, &nand_status_content); - if (!(nand_status_content & 0x0080)) { - LOG_INFO("NAND read-only"); - mxc_nf_info->flags.nand_readonly = 1; - } else - mxc_nf_info->flags.nand_readonly = 0; - return ERROR_OK; -} - -static int mxc_read_data(struct nand_device *nand, void *data) -{ - int validate_target_result; - int try_data_output_from_nand_chip; - /* - * validate target state - */ - validate_target_result = validate_target_state(nand); - if (validate_target_result != ERROR_OK) - return validate_target_result; - - /* - * get data from nand chip - */ - try_data_output_from_nand_chip = do_data_output(nand); - if (try_data_output_from_nand_chip != ERROR_OK) { - LOG_ERROR("mxc_read_data : read data failed : '%x'", - try_data_output_from_nand_chip); - return try_data_output_from_nand_chip; - } - - if (nand->bus_width == 16) - get_next_halfword_from_sram_buffer(nand, data); - else - get_next_byte_from_sram_buffer(nand, data); - - return ERROR_OK; -} - -static int mxc_write_data(struct nand_device *nand, uint16_t data) -{ - LOG_ERROR("write_data() not implemented"); - return ERROR_NAND_OPERATION_FAILED; -} - -static int mxc_reset(struct nand_device *nand) -{ - /* - * validate target state - */ - int validate_target_result; - validate_target_result = validate_target_state(nand); - if (validate_target_result != ERROR_OK) - return validate_target_result; - initialize_nf_controller(nand); - return ERROR_OK; -} - -static int mxc_command(struct nand_device *nand, uint8_t command) -{ - struct mxc_nf_controller *mxc_nf_info = nand->controller_priv; - struct target *target = nand->target; - int validate_target_result; - int poll_result; - /* - * validate target state - */ - validate_target_result = validate_target_state(nand); - if (validate_target_result != ERROR_OK) - return validate_target_result; - - switch (command) { - case NAND_CMD_READOOB: - command = NAND_CMD_READ0; - /* set read point for data_read() and read_block_data() to - * spare area in SRAM buffer - */ - if (nfc_is_v1()) - in_sram_address = MXC_NF_V1_SPARE_BUFFER0; - else - in_sram_address = MXC_NF_V2_SPARE_BUFFER0; - break; - case NAND_CMD_READ1: - command = NAND_CMD_READ0; - /* - * offset == one half of page size - */ - in_sram_address = MXC_NF_MAIN_BUFFER0 + (nand->page_size >> 1); - break; - default: - in_sram_address = MXC_NF_MAIN_BUFFER0; - break; - } - - target_write_u16(target, MXC_NF_FCMD, command); - /* - * start command input operation (set MXC_NF_BIT_OP_DONE==0) - */ - target_write_u16(target, MXC_NF_CFG2, MXC_NF_BIT_OP_FCI); - poll_result = poll_for_complete_op(nand, "command"); - if (poll_result != ERROR_OK) - return poll_result; - /* - * reset cursor to begin of the buffer - */ - sign_of_sequental_byte_read = 0; - /* Handle special read command and adjust NF_CFG2(FDO) */ - switch (command) { - case NAND_CMD_READID: - mxc_nf_info->optype = MXC_NF_DATAOUT_NANDID; - mxc_nf_info->fin = MXC_NF_FIN_DATAOUT; - break; - case NAND_CMD_STATUS: - mxc_nf_info->optype = MXC_NF_DATAOUT_NANDSTATUS; - mxc_nf_info->fin = MXC_NF_FIN_DATAOUT; - target_write_u16 (target, MXC_NF_BUFADDR, 0); - in_sram_address = 0; - break; - case NAND_CMD_READ0: - mxc_nf_info->fin = MXC_NF_FIN_DATAOUT; - mxc_nf_info->optype = MXC_NF_DATAOUT_PAGE; - break; - default: - /* Ohter command use the default 'One page data out' FDO */ - mxc_nf_info->optype = MXC_NF_DATAOUT_PAGE; - break; - } - return ERROR_OK; -} - -static int mxc_address(struct nand_device *nand, uint8_t address) -{ - struct mxc_nf_controller *mxc_nf_info = nand->controller_priv; - struct target *target = nand->target; - int validate_target_result; - int poll_result; - /* - * validate target state - */ - validate_target_result = validate_target_state(nand); - if (validate_target_result != ERROR_OK) - return validate_target_result; - - target_write_u16(target, MXC_NF_FADDR, address); - /* - * start address input operation (set MXC_NF_BIT_OP_DONE==0) - */ - target_write_u16(target, MXC_NF_CFG2, MXC_NF_BIT_OP_FAI); - poll_result = poll_for_complete_op(nand, "address"); - if (poll_result != ERROR_OK) - return poll_result; - - return ERROR_OK; -} - -static int mxc_nand_ready(struct nand_device *nand, int tout) -{ - struct mxc_nf_controller *mxc_nf_info = nand->controller_priv; - struct target *target = nand->target; - uint16_t poll_complete_status; - int validate_target_result; - - /* - * validate target state - */ - validate_target_result = validate_target_state(nand); - if (validate_target_result != ERROR_OK) - return validate_target_result; - - do { - target_read_u16(target, MXC_NF_CFG2, &poll_complete_status); - if (poll_complete_status & MXC_NF_BIT_OP_DONE) - return tout; - - alive_sleep(1); - } while (tout-- > 0); - return tout; -} - -static int mxc_write_page(struct nand_device *nand, uint32_t page, - uint8_t *data, uint32_t data_size, - uint8_t *oob, uint32_t oob_size) -{ - struct mxc_nf_controller *mxc_nf_info = nand->controller_priv; - struct target *target = nand->target; - int retval; - uint16_t nand_status_content; - uint16_t swap1, swap2, new_swap1; - uint8_t bufs; - int poll_result; - - if (data_size % 2) { - LOG_ERROR(data_block_size_err_msg, data_size); - return ERROR_NAND_OPERATION_FAILED; - } - if (oob_size % 2) { - LOG_ERROR(data_block_size_err_msg, oob_size); - return ERROR_NAND_OPERATION_FAILED; - } - if (!data) { - LOG_ERROR("nothing to program"); - return ERROR_NAND_OPERATION_FAILED; - } - - /* - * validate target state - */ - retval = validate_target_state(nand); - if (retval != ERROR_OK) - return retval; - - in_sram_address = MXC_NF_MAIN_BUFFER0; - sign_of_sequental_byte_read = 0; - retval = ERROR_OK; - retval |= mxc_command(nand, NAND_CMD_SEQIN); - retval |= mxc_address(nand, 0); /* col */ - retval |= mxc_address(nand, 0); /* col */ - retval |= mxc_address(nand, page & 0xff); /* page address */ - retval |= mxc_address(nand, (page >> 8) & 0xff);/* page address */ - retval |= mxc_address(nand, (page >> 16) & 0xff); /* page address */ - - target_write_buffer(target, MXC_NF_MAIN_BUFFER0, data_size, data); - if (oob) { - if (mxc_nf_info->flags.hw_ecc_enabled) { - /* - * part of spare block will be overrided by hardware - * ECC generator - */ - LOG_DEBUG("part of spare block will be overrided " - "by hardware ECC generator"); - } - if (nfc_is_v1()) - target_write_buffer(target, MXC_NF_V1_SPARE_BUFFER0, oob_size, oob); - else { - uint32_t addr = MXC_NF_V2_SPARE_BUFFER0; - while (oob_size > 0) { - uint8_t len = MIN(oob_size, MXC_NF_SPARE_BUFFER_LEN); - target_write_buffer(target, addr, len, oob); - addr = align_address_v2(nand, addr + len); - oob += len; - oob_size -= len; - } - } - } - - if (nand->page_size > 512 && mxc_nf_info->flags.biswap_enabled) { - /* BI-swap - work-around of i.MX NFC for NAND device with page == 2kb*/ - target_read_u16(target, MXC_NF_MAIN_BUFFER3 + 464, &swap1); - if (oob) { - LOG_ERROR("Due to NFC Bug, oob is not correctly implemented in mxc driver"); - return ERROR_NAND_OPERATION_FAILED; - } - swap2 = 0xffff; /* Spare buffer unused forced to 0xffff */ - new_swap1 = (swap1 & 0xFF00) | (swap2 >> 8); - swap2 = (swap1 << 8) | (swap2 & 0xFF); - target_write_u16(target, MXC_NF_MAIN_BUFFER3 + 464, new_swap1); - if (nfc_is_v1()) - target_write_u16(target, MXC_NF_V1_SPARE_BUFFER3 + 4, swap2); - else - target_write_u16(target, MXC_NF_V2_SPARE_BUFFER3, swap2); - } - - /* - * start data input operation (set MXC_NF_BIT_OP_DONE==0) - */ - if (nfc_is_v1() && nand->page_size > 512) - bufs = 4; - else - bufs = 1; - - for (uint8_t i = 0; i < bufs; ++i) { - target_write_u16(target, MXC_NF_BUFADDR, i); - target_write_u16(target, MXC_NF_CFG2, MXC_NF_BIT_OP_FDI); - poll_result = poll_for_complete_op(nand, "data input"); - if (poll_result != ERROR_OK) - return poll_result; - } - - retval |= mxc_command(nand, NAND_CMD_PAGEPROG); - if (retval != ERROR_OK) - return retval; - - /* - * check status register - */ - retval = ERROR_OK; - retval |= mxc_command(nand, NAND_CMD_STATUS); - target_write_u16 (target, MXC_NF_BUFADDR, 0); - mxc_nf_info->optype = MXC_NF_DATAOUT_NANDSTATUS; - mxc_nf_info->fin = MXC_NF_FIN_DATAOUT; - retval |= do_data_output(nand); - if (retval != ERROR_OK) { - LOG_ERROR(get_status_register_err_msg); - return retval; - } - target_read_u16(target, MXC_NF_MAIN_BUFFER0, &nand_status_content); - if (nand_status_content & 0x0001) { - /* - * page not correctly written - */ - return ERROR_NAND_OPERATION_FAILED; - } -#ifdef _MXC_PRINT_STAT - LOG_INFO("%d bytes newly written", data_size); -#endif - return ERROR_OK; -} - -static int mxc_read_page(struct nand_device *nand, uint32_t page, - uint8_t *data, uint32_t data_size, - uint8_t *oob, uint32_t oob_size) -{ - struct mxc_nf_controller *mxc_nf_info = nand->controller_priv; - struct target *target = nand->target; - int retval; - uint8_t bufs; - uint16_t swap1, swap2, new_swap1; - - if (data_size % 2) { - LOG_ERROR(data_block_size_err_msg, data_size); - return ERROR_NAND_OPERATION_FAILED; - } - if (oob_size % 2) { - LOG_ERROR(data_block_size_err_msg, oob_size); - return ERROR_NAND_OPERATION_FAILED; - } - - /* - * validate target state - */ - retval = validate_target_state(nand); - if (retval != ERROR_OK) - return retval; - /* Reset address_cycles before mxc_command ?? */ - retval = mxc_command(nand, NAND_CMD_READ0); - if (retval != ERROR_OK) - return retval; - retval = mxc_address(nand, 0); /* col */ - if (retval != ERROR_OK) - return retval; - retval = mxc_address(nand, 0); /* col */ - if (retval != ERROR_OK) - return retval; - retval = mxc_address(nand, page & 0xff);/* page address */ - if (retval != ERROR_OK) - return retval; - retval = mxc_address(nand, (page >> 8) & 0xff); /* page address */ - if (retval != ERROR_OK) - return retval; - retval = mxc_address(nand, (page >> 16) & 0xff);/* page address */ - if (retval != ERROR_OK) - return retval; - retval = mxc_command(nand, NAND_CMD_READSTART); - if (retval != ERROR_OK) - return retval; - - if (nfc_is_v1() && nand->page_size > 512) - bufs = 4; - else - bufs = 1; - - for (uint8_t i = 0; i < bufs; ++i) { - target_write_u16(target, MXC_NF_BUFADDR, i); - mxc_nf_info->fin = MXC_NF_FIN_DATAOUT; - retval = do_data_output(nand); - if (retval != ERROR_OK) { - LOG_ERROR("MXC_NF : Error reading page %d", i); - return retval; - } - } - - if (nand->page_size > 512 && mxc_nf_info->flags.biswap_enabled) { - uint32_t SPARE_BUFFER3; - /* BI-swap - work-around of mxc NFC for NAND device with page == 2k */ - target_read_u16(target, MXC_NF_MAIN_BUFFER3 + 464, &swap1); - if (nfc_is_v1()) - SPARE_BUFFER3 = MXC_NF_V1_SPARE_BUFFER3 + 4; - else - SPARE_BUFFER3 = MXC_NF_V2_SPARE_BUFFER3; - target_read_u16(target, SPARE_BUFFER3, &swap2); - new_swap1 = (swap1 & 0xFF00) | (swap2 >> 8); - swap2 = (swap1 << 8) | (swap2 & 0xFF); - target_write_u16(target, MXC_NF_MAIN_BUFFER3 + 464, new_swap1); - target_write_u16(target, SPARE_BUFFER3, swap2); - } - - if (data) - target_read_buffer(target, MXC_NF_MAIN_BUFFER0, data_size, data); - if (oob) { - if (nfc_is_v1()) - target_read_buffer(target, MXC_NF_V1_SPARE_BUFFER0, oob_size, oob); - else { - uint32_t addr = MXC_NF_V2_SPARE_BUFFER0; - while (oob_size > 0) { - uint8_t len = MIN(oob_size, MXC_NF_SPARE_BUFFER_LEN); - target_read_buffer(target, addr, len, oob); - addr = align_address_v2(nand, addr + len); - oob += len; - oob_size -= len; - } - } - } - -#ifdef _MXC_PRINT_STAT - if (data_size > 0) { - /* When Operation Status is read (when page is erased), - * this function is used but data_size is null. - */ - LOG_INFO("%d bytes newly read", data_size); - } -#endif - return ERROR_OK; -} - -static uint32_t align_address_v2(struct nand_device *nand, uint32_t addr) -{ - struct mxc_nf_controller *mxc_nf_info = nand->controller_priv; - uint32_t ret = addr; - if (addr > MXC_NF_V2_SPARE_BUFFER0 && - (addr & 0x1F) == MXC_NF_SPARE_BUFFER_LEN) - ret += MXC_NF_SPARE_BUFFER_MAX - MXC_NF_SPARE_BUFFER_LEN; - else if (addr >= (mxc_nf_info->mxc_base_addr + (uint32_t)nand->page_size)) - ret = MXC_NF_V2_SPARE_BUFFER0; - return ret; -} - -static int initialize_nf_controller(struct nand_device *nand) -{ - struct mxc_nf_controller *mxc_nf_info = nand->controller_priv; - struct target *target = nand->target; - uint16_t work_mode = 0; - uint16_t temp; - /* - * resets NAND flash controller in zero time ? I dont know. - */ - target_write_u16(target, MXC_NF_CFG1, MXC_NF_BIT_RESET_EN); - if (mxc_nf_info->mxc_version == MXC_VERSION_MX27) - work_mode = MXC_NF_BIT_INT_DIS; /* disable interrupt */ - - if (target->endianness == TARGET_BIG_ENDIAN) { - LOG_DEBUG("MXC_NF : work in Big Endian mode"); - work_mode |= MXC_NF_BIT_BE_EN; - } else - LOG_DEBUG("MXC_NF : work in Little Endian mode"); - if (mxc_nf_info->flags.hw_ecc_enabled) { - LOG_DEBUG("MXC_NF : work with ECC mode"); - work_mode |= MXC_NF_BIT_ECC_EN; - } else - LOG_DEBUG("MXC_NF : work without ECC mode"); - if (nfc_is_v2()) { - target_write_u16(target, MXC_NF_V2_SPAS, OOB_SIZE / 2); - if (nand->page_size) { - uint16_t pages_per_block = nand->erase_size / nand->page_size; - work_mode |= MXC_NF_V2_CFG1_PPB(ffs(pages_per_block) - 6); - } - work_mode |= MXC_NF_BIT_ECC_4BIT; - } - target_write_u16(target, MXC_NF_CFG1, work_mode); - - /* - * unlock SRAM buffer for write; 2 mean "Unlock", other values means "Lock" - */ - target_write_u16(target, MXC_NF_BUFCFG, 2); - target_read_u16(target, MXC_NF_FWP, &temp); - if ((temp & 0x0007) == 1) { - LOG_ERROR("NAND flash is tight-locked, reset needed"); - return ERROR_FAIL; - } - - /* - * unlock NAND flash for write - */ - if (nfc_is_v1()) { - target_write_u16(target, MXC_NF_V1_UNLOCKSTART, 0x0000); - target_write_u16(target, MXC_NF_V1_UNLOCKEND, 0xFFFF); - } else { - target_write_u16(target, MXC_NF_V2_UNLOCKSTART0, 0x0000); - target_write_u16(target, MXC_NF_V2_UNLOCKSTART1, 0x0000); - target_write_u16(target, MXC_NF_V2_UNLOCKSTART2, 0x0000); - target_write_u16(target, MXC_NF_V2_UNLOCKSTART3, 0x0000); - target_write_u16(target, MXC_NF_V2_UNLOCKEND0, 0xFFFF); - target_write_u16(target, MXC_NF_V2_UNLOCKEND1, 0xFFFF); - target_write_u16(target, MXC_NF_V2_UNLOCKEND2, 0xFFFF); - target_write_u16(target, MXC_NF_V2_UNLOCKEND3, 0xFFFF); - } - target_write_u16(target, MXC_NF_FWP, 4); - - /* - * 0x0000 means that first SRAM buffer @base_addr will be used - */ - target_write_u16(target, MXC_NF_BUFADDR, 0x0000); - /* - * address of SRAM buffer - */ - in_sram_address = MXC_NF_MAIN_BUFFER0; - sign_of_sequental_byte_read = 0; - return ERROR_OK; -} - -static int get_next_byte_from_sram_buffer(struct nand_device *nand, uint8_t *value) -{ - struct mxc_nf_controller *mxc_nf_info = nand->controller_priv; - struct target *target = nand->target; - static uint8_t even_byte; - uint16_t temp; - /* - * host-big_endian ?? - */ - if (sign_of_sequental_byte_read == 0) - even_byte = 0; - - if (in_sram_address > (nfc_is_v1() ? MXC_NF_V1_LAST_BUFFADDR : MXC_NF_V2_LAST_BUFFADDR)) { - LOG_ERROR(sram_buffer_bounds_err_msg, in_sram_address); - *value = 0; - sign_of_sequental_byte_read = 0; - even_byte = 0; - return ERROR_NAND_OPERATION_FAILED; - } else { - if (nfc_is_v2()) - in_sram_address = align_address_v2(nand, in_sram_address); - - target_read_u16(target, in_sram_address, &temp); - if (even_byte) { - *value = temp >> 8; - even_byte = 0; - in_sram_address += 2; - } else { - *value = temp & 0xff; - even_byte = 1; - } - } - sign_of_sequental_byte_read = 1; - return ERROR_OK; -} - -static int get_next_halfword_from_sram_buffer(struct nand_device *nand, uint16_t *value) -{ - struct mxc_nf_controller *mxc_nf_info = nand->controller_priv; - struct target *target = nand->target; - - if (in_sram_address > (nfc_is_v1() ? MXC_NF_V1_LAST_BUFFADDR : MXC_NF_V2_LAST_BUFFADDR)) { - LOG_ERROR(sram_buffer_bounds_err_msg, in_sram_address); - *value = 0; - return ERROR_NAND_OPERATION_FAILED; - } else { - if (nfc_is_v2()) - in_sram_address = align_address_v2(nand, in_sram_address); - - target_read_u16(target, in_sram_address, value); - in_sram_address += 2; - } - return ERROR_OK; -} - -static int poll_for_complete_op(struct nand_device *nand, const char *text) -{ - if (mxc_nand_ready(nand, 1000) == -1) { - LOG_ERROR("%s sending timeout", text); - return ERROR_NAND_OPERATION_FAILED; - } - return ERROR_OK; -} - -static int validate_target_state(struct nand_device *nand) -{ - struct mxc_nf_controller *mxc_nf_info = nand->controller_priv; - struct target *target = nand->target; - - if (target->state != TARGET_HALTED) { - LOG_ERROR(target_not_halted_err_msg); - return ERROR_NAND_OPERATION_FAILED; - } - - if (mxc_nf_info->flags.target_little_endian != - (target->endianness == TARGET_LITTLE_ENDIAN)) { - /* - * endianness changed after NAND controller probed - */ - return ERROR_NAND_OPERATION_FAILED; - } - return ERROR_OK; -} - -int ecc_status_v1(struct nand_device *nand) -{ - struct mxc_nf_controller *mxc_nf_info = nand->controller_priv; - struct target *target = nand->target; - uint16_t ecc_status; - - target_read_u16(target, MXC_NF_ECCSTATUS, &ecc_status); - switch (ecc_status & 0x000c) { - case 1 << 2: - LOG_INFO("main area read with 1 (correctable) error"); - break; - case 2 << 2: - LOG_INFO("main area read with more than 1 (incorrectable) error"); - return ERROR_NAND_OPERATION_FAILED; - break; - } - switch (ecc_status & 0x0003) { - case 1: - LOG_INFO("spare area read with 1 (correctable) error"); - break; - case 2: - LOG_INFO("main area read with more than 1 (incorrectable) error"); - return ERROR_NAND_OPERATION_FAILED; - break; - } - return ERROR_OK; -} - -int ecc_status_v2(struct nand_device *nand) -{ - struct mxc_nf_controller *mxc_nf_info = nand->controller_priv; - struct target *target = nand->target; - uint16_t ecc_status; - uint8_t no_subpages; - uint8_t err; - - no_subpages = nand->page_size >> 9; - - target_read_u16(target, MXC_NF_ECCSTATUS, &ecc_status); - do { - err = ecc_status & 0xF; - if (err > 4) { - LOG_INFO("UnCorrectable RS-ECC Error"); - return ERROR_NAND_OPERATION_FAILED; - } else if (err > 0) - LOG_INFO("%d Symbol Correctable RS-ECC Error", err); - ecc_status >>= 4; - } while (--no_subpages); - return ERROR_OK; -} - -static int do_data_output(struct nand_device *nand) -{ - struct mxc_nf_controller *mxc_nf_info = nand->controller_priv; - struct target *target = nand->target; - int poll_result; - switch (mxc_nf_info->fin) { - case MXC_NF_FIN_DATAOUT: - /* - * start data output operation (set MXC_NF_BIT_OP_DONE==0) - */ - target_write_u16(target, MXC_NF_CFG2, MXC_NF_BIT_DATAOUT_TYPE(mxc_nf_info->optype)); - poll_result = poll_for_complete_op(nand, "data output"); - if (poll_result != ERROR_OK) - return poll_result; - - mxc_nf_info->fin = MXC_NF_FIN_NONE; - /* - * ECC stuff - */ - if (mxc_nf_info->optype == MXC_NF_DATAOUT_PAGE && mxc_nf_info->flags.hw_ecc_enabled) { - int ecc_status; - if (nfc_is_v1()) - ecc_status = ecc_status_v1(nand); - else - ecc_status = ecc_status_v2(nand); - if (ecc_status != ERROR_OK) - return ecc_status; - } - break; - case MXC_NF_FIN_NONE: - break; - } - return ERROR_OK; -} - -struct nand_flash_controller mxc_nand_flash_controller = { - .name = "mxc", - .nand_device_command = &mxc_nand_device_command, - .commands = mxc_nand_command_handler, - .init = &mxc_init, - .reset = &mxc_reset, - .command = &mxc_command, - .address = &mxc_address, - .write_data = &mxc_write_data, - .read_data = &mxc_read_data, - .write_page = &mxc_write_page, - .read_page = &mxc_read_page, - .nand_ready = &mxc_nand_ready, -}; diff --git a/src/flash/nand/mxc.h b/src/flash/nand/mxc.h deleted file mode 100644 index a1887288b..000000000 --- a/src/flash/nand/mxc.h +++ /dev/null @@ -1,168 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2009 by Alexei Babich * - * Rezonans plc., Chelyabinsk, Russia * - * impatt@mail.ru * - * * - * Copyright (C) 2011 by Erik Ahlen * - * Avalon Innovation, Sweden * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#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. - * - * Many thanks to Ben Dooks for writing s3c24xx driver. - */ - -#define MXC_NF_BUFSIZ (mxc_nf_info->mxc_regs_addr + 0x00) -#define MXC_NF_BUFADDR (mxc_nf_info->mxc_regs_addr + 0x04) -#define MXC_NF_FADDR (mxc_nf_info->mxc_regs_addr + 0x06) -#define MXC_NF_FCMD (mxc_nf_info->mxc_regs_addr + 0x08) -#define MXC_NF_BUFCFG (mxc_nf_info->mxc_regs_addr + 0x0a) -#define MXC_NF_ECCSTATUS (mxc_nf_info->mxc_regs_addr + 0x0c) -#define MXC_NF_ECCMAINPOS (mxc_nf_info->mxc_regs_addr + 0x0e) -#define MXC_NF_V1_ECCSPAREPOS (mxc_nf_info->mxc_regs_addr + 0x10) -#define MXC_NF_V2_SPAS (mxc_nf_info->mxc_regs_addr + 0x10) -#define MXC_NF_FWP (mxc_nf_info->mxc_regs_addr + 0x12) -#define MXC_NF_V1_UNLOCKSTART (mxc_nf_info->mxc_regs_addr + 0x14) -#define MXC_NF_V1_UNLOCKEND (mxc_nf_info->mxc_regs_addr + 0x16) -#define MXC_NF_V2_UNLOCKSTART0 (mxc_nf_info->mxc_regs_addr + 0x20) -#define MXC_NF_V2_UNLOCKSTART1 (mxc_nf_info->mxc_regs_addr + 0x24) -#define MXC_NF_V2_UNLOCKSTART2 (mxc_nf_info->mxc_regs_addr + 0x28) -#define MXC_NF_V2_UNLOCKSTART3 (mxc_nf_info->mxc_regs_addr + 0x2c) -#define MXC_NF_V2_UNLOCKEND0 (mxc_nf_info->mxc_regs_addr + 0x22) -#define MXC_NF_V2_UNLOCKEND1 (mxc_nf_info->mxc_regs_addr + 0x26) -#define MXC_NF_V2_UNLOCKEND2 (mxc_nf_info->mxc_regs_addr + 0x2a) -#define MXC_NF_V2_UNLOCKEND3 (mxc_nf_info->mxc_regs_addr + 0x2e) -#define MXC_NF_FWPSTATUS (mxc_nf_info->mxc_regs_addr + 0x18) - /* - * all bits not marked as self-clearing bit - */ -#define MXC_NF_CFG1 (mxc_nf_info->mxc_regs_addr + 0x1a) -#define MXC_NF_CFG2 (mxc_nf_info->mxc_regs_addr + 0x1c) - -#define MXC_NF_MAIN_BUFFER0 (mxc_nf_info->mxc_base_addr + 0x0000) -#define MXC_NF_MAIN_BUFFER1 (mxc_nf_info->mxc_base_addr + 0x0200) -#define MXC_NF_MAIN_BUFFER2 (mxc_nf_info->mxc_base_addr + 0x0400) -#define MXC_NF_MAIN_BUFFER3 (mxc_nf_info->mxc_base_addr + 0x0600) -#define MXC_NF_V1_SPARE_BUFFER0 (mxc_nf_info->mxc_base_addr + 0x0800) -#define MXC_NF_V1_SPARE_BUFFER1 (mxc_nf_info->mxc_base_addr + 0x0810) -#define MXC_NF_V1_SPARE_BUFFER2 (mxc_nf_info->mxc_base_addr + 0x0820) -#define MXC_NF_V1_SPARE_BUFFER3 (mxc_nf_info->mxc_base_addr + 0x0830) -#define MXC_NF_V2_MAIN_BUFFER4 (mxc_nf_info->mxc_base_addr + 0x0800) -#define MXC_NF_V2_MAIN_BUFFER5 (mxc_nf_info->mxc_base_addr + 0x0a00) -#define MXC_NF_V2_MAIN_BUFFER6 (mxc_nf_info->mxc_base_addr + 0x0c00) -#define MXC_NF_V2_MAIN_BUFFER7 (mxc_nf_info->mxc_base_addr + 0x0e00) -#define MXC_NF_V2_SPARE_BUFFER0 (mxc_nf_info->mxc_base_addr + 0x1000) -#define MXC_NF_V2_SPARE_BUFFER1 (mxc_nf_info->mxc_base_addr + 0x1040) -#define MXC_NF_V2_SPARE_BUFFER2 (mxc_nf_info->mxc_base_addr + 0x1080) -#define MXC_NF_V2_SPARE_BUFFER3 (mxc_nf_info->mxc_base_addr + 0x10c0) -#define MXC_NF_V2_SPARE_BUFFER4 (mxc_nf_info->mxc_base_addr + 0x1100) -#define MXC_NF_V2_SPARE_BUFFER5 (mxc_nf_info->mxc_base_addr + 0x1140) -#define MXC_NF_V2_SPARE_BUFFER6 (mxc_nf_info->mxc_base_addr + 0x1180) -#define MXC_NF_V2_SPARE_BUFFER7 (mxc_nf_info->mxc_base_addr + 0x11c0) -#define MXC_NF_MAIN_BUFFER_LEN 512 -#define MXC_NF_SPARE_BUFFER_LEN 16 -#define MXC_NF_SPARE_BUFFER_MAX 64 -#define MXC_NF_V1_LAST_BUFFADDR ((MXC_NF_V1_SPARE_BUFFER3) + \ - MXC_NF_SPARE_BUFFER_LEN - 2) -#define MXC_NF_V2_LAST_BUFFADDR ((MXC_NF_V2_SPARE_BUFFER7) + \ - MXC_NF_SPARE_BUFFER_LEN - 2) - -/* bits in MXC_NF_CFG1 register */ -#define MXC_NF_BIT_ECC_4BIT (1<<0) -#define MXC_NF_BIT_SPARE_ONLY_EN (1<<2) -#define MXC_NF_BIT_ECC_EN (1<<3) -#define MXC_NF_BIT_INT_DIS (1<<4) -#define MXC_NF_BIT_BE_EN (1<<5) -#define MXC_NF_BIT_RESET_EN (1<<6) -#define MXC_NF_BIT_FORCE_CE (1<<7) -#define MXC_NF_V2_CFG1_PPB(x) (((x) & 0x3) << 9) - -/* bits in MXC_NF_CFG2 register */ - -/*Flash Command Input*/ -#define MXC_NF_BIT_OP_FCI (1<<0) - /* - * Flash Address Input - */ -#define MXC_NF_BIT_OP_FAI (1<<1) - /* - * Flash Data Input - */ -#define MXC_NF_BIT_OP_FDI (1<<2) - -/* see "enum mx_dataout_type" below */ -#define MXC_NF_BIT_DATAOUT_TYPE(x) ((x)<<3) -#define MXC_NF_BIT_OP_DONE (1<<15) - -#define MXC_CCM_CGR2 0x53f80028 -#define MXC_GPR 0x43fac008 -#define MX2_FMCR 0x10027814 -#define MX2_FMCR_NF_16BIT_SEL (1<<4) -#define MX2_FMCR_NF_FMS (1<<5) -#define MX25_RCSR 0x53f80018 -#define MX25_RCSR_NF_16BIT_SEL (1<<14) -#define MX25_RCSR_NF_FMS (1<<8) -#define MX25_RCSR_NF_4K (1<<9) -#define MX3_PCSR 0x53f8000c -#define MX3_PCSR_NF_16BIT_SEL (1<<31) -#define MX3_PCSR_NF_FMS (1<<30) -#define MX35_RCSR 0x53f80018 -#define MX35_RCSR_NF_16BIT_SEL (1<<14) -#define MX35_RCSR_NF_FMS (1<<8) -#define MX35_RCSR_NF_4K (1<<9) - -enum mxc_version { - MXC_VERSION_UKWN = 0, - MXC_VERSION_MX25 = 1, - MXC_VERSION_MX27 = 2, - MXC_VERSION_MX31 = 3, - MXC_VERSION_MX35 = 4 -}; - -enum mxc_dataout_type { - MXC_NF_DATAOUT_PAGE = 1, - MXC_NF_DATAOUT_NANDID = 2, - MXC_NF_DATAOUT_NANDSTATUS = 4, -}; - -enum mxc_nf_finalize_action { - MXC_NF_FIN_NONE, - MXC_NF_FIN_DATAOUT, -}; - -struct mxc_nf_flags { - unsigned target_little_endian:1; - unsigned nand_readonly:1; - unsigned one_kb_sram:1; - unsigned hw_ecc_enabled:1; - unsigned biswap_enabled:1; -}; - -struct mxc_nf_controller { - enum mxc_version mxc_version; - uint32_t mxc_base_addr; - uint32_t mxc_regs_addr; - enum mxc_dataout_type optype; - 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 deleted file mode 100644 index 6fda2618e..000000000 --- a/src/flash/nand/nonce.c +++ /dev/null @@ -1,73 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2009 Zachary T Welch * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 -#include "config.h" -#endif - -#include "imp.h" -#include "hello.h" - -static int nonce_nand_command(struct nand_device *nand, uint8_t command) -{ - return ERROR_OK; -} -static int nonce_nand_address(struct nand_device *nand, uint8_t address) -{ - return ERROR_OK; -} -static int nonce_nand_read(struct nand_device *nand, void *data) -{ - return ERROR_OK; -} -static int nonce_nand_write(struct nand_device *nand, uint16_t data) -{ - return ERROR_OK; -} -static int nonce_nand_fast_block_write(struct nand_device *nand, - uint8_t *data, int size) -{ - return ERROR_OK; -} - -static int nonce_nand_reset(struct nand_device *nand) -{ - return nonce_nand_command(nand, NAND_CMD_RESET); -} - -NAND_DEVICE_COMMAND_HANDLER(nonce_nand_device_command) -{ - return ERROR_OK; -} - -static int nonce_nand_init(struct nand_device *nand) -{ - return ERROR_OK; -} - -struct nand_flash_controller nonce_nand_controller = { - .name = "nonce", - .commands = hello_command_handlers, - .nand_device_command = &nonce_nand_device_command, - .init = &nonce_nand_init, - .reset = &nonce_nand_reset, - .command = &nonce_nand_command, - .address = &nonce_nand_address, - .read_data = &nonce_nand_read, - .write_data = &nonce_nand_write, - .write_block_data = &nonce_nand_fast_block_write, -}; diff --git a/src/flash/nand/nuc910.c b/src/flash/nand/nuc910.c deleted file mode 100644 index 1a2dd5968..000000000 --- a/src/flash/nand/nuc910.c +++ /dev/null @@ -1,227 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2010 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -/* - * NAND controller interface for Nuvoton NUC910 - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "imp.h" -#include "nuc910.h" -#include "arm_io.h" -#include - -struct nuc910_nand_controller { - struct arm_nand_data io; -}; - -static int validate_target_state(struct nand_device *nand) -{ - struct target *target = nand->target; - - if (target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_NAND_OPERATION_FAILED; - } - - return ERROR_OK; -} - -static int nuc910_nand_command(struct nand_device *nand, uint8_t command) -{ - struct target *target = nand->target; - int result; - - result = validate_target_state(nand); - if (result != ERROR_OK) - return result; - - target_write_u8(target, NUC910_SMCMD, command); - return ERROR_OK; -} - -static int nuc910_nand_address(struct nand_device *nand, uint8_t address) -{ - struct target *target = nand->target; - int result; - - result = validate_target_state(nand); - if (result != ERROR_OK) - return result; - - target_write_u32(target, NUC910_SMADDR, ((address & 0xff) | NUC910_SMADDR_EOA)); - return ERROR_OK; -} - -static int nuc910_nand_read(struct nand_device *nand, void *data) -{ - struct target *target = nand->target; - int result; - - result = validate_target_state(nand); - if (result != ERROR_OK) - return result; - - target_read_u8(target, NUC910_SMDATA, data); - return ERROR_OK; -} - -static int nuc910_nand_write(struct nand_device *nand, uint16_t data) -{ - struct target *target = nand->target; - int result; - - result = validate_target_state(nand); - if (result != ERROR_OK) - return result; - - target_write_u8(target, NUC910_SMDATA, data); - return ERROR_OK; -} - -static int nuc910_nand_read_block_data(struct nand_device *nand, - uint8_t *data, int data_size) -{ - struct nuc910_nand_controller *nuc910_nand = nand->controller_priv; - int result; - - result = validate_target_state(nand); - if (result != ERROR_OK) - return result; - - nuc910_nand->io.chunk_size = nand->page_size; - - /* try the fast way first */ - result = arm_nandread(&nuc910_nand->io, data, data_size); - if (result != ERROR_NAND_NO_BUFFER) - return result; - - /* else do it slowly */ - while (data_size--) - nuc910_nand_read(nand, data++); - - return ERROR_OK; -} - -static int nuc910_nand_write_block_data(struct nand_device *nand, - uint8_t *data, int data_size) -{ - struct nuc910_nand_controller *nuc910_nand = nand->controller_priv; - int result; - - result = validate_target_state(nand); - if (result != ERROR_OK) - return result; - - nuc910_nand->io.chunk_size = nand->page_size; - - /* try the fast way first */ - result = arm_nandwrite(&nuc910_nand->io, data, data_size); - if (result != ERROR_NAND_NO_BUFFER) - return result; - - /* else do it slowly */ - while (data_size--) - nuc910_nand_write(nand, *data++); - - return ERROR_OK; -} - -static int nuc910_nand_reset(struct nand_device *nand) -{ - return nuc910_nand_command(nand, NAND_CMD_RESET); -} - -static int nuc910_nand_ready(struct nand_device *nand, int timeout) -{ - struct target *target = nand->target; - uint32_t status; - - do { - target_read_u32(target, NUC910_SMISR, &status); - if (status & NUC910_SMISR_RB_) - return 1; - alive_sleep(1); - } while (timeout-- > 0); - - return 0; -} - -NAND_DEVICE_COMMAND_HANDLER(nuc910_nand_device_command) -{ - struct nuc910_nand_controller *nuc910_nand; - - nuc910_nand = calloc(1, sizeof(struct nuc910_nand_controller)); - if (!nuc910_nand) { - LOG_ERROR("no memory for nand controller"); - return ERROR_NAND_DEVICE_INVALID; - } - - nand->controller_priv = nuc910_nand; - return ERROR_OK; -} - -static int nuc910_nand_init(struct nand_device *nand) -{ - struct nuc910_nand_controller *nuc910_nand = nand->controller_priv; - struct target *target = nand->target; - int bus_width = nand->bus_width ? : 8; - int result; - - result = validate_target_state(nand); - if (result != ERROR_OK) - return result; - - /* nuc910 only supports 8bit */ - if (bus_width != 8) { - LOG_ERROR("nuc910 only supports 8 bit bus width, not %i", bus_width); - return ERROR_NAND_OPERATION_NOT_SUPPORTED; - } - - /* inform calling code about selected bus width */ - nand->bus_width = bus_width; - - nuc910_nand->io.target = target; - nuc910_nand->io.data = NUC910_SMDATA; - nuc910_nand->io.op = ARM_NAND_NONE; - - /* configure nand controller */ - target_write_u32(target, NUC910_FMICSR, NUC910_FMICSR_SM_EN); - target_write_u32(target, NUC910_SMCSR, 0x010000a8); /* 2048 page size */ - target_write_u32(target, NUC910_SMTCR, 0x00010204); - target_write_u32(target, NUC910_SMIER, 0x00000000); - - return ERROR_OK; -} - -struct nand_flash_controller nuc910_nand_controller = { - .name = "nuc910", - .command = nuc910_nand_command, - .address = nuc910_nand_address, - .read_data = nuc910_nand_read, - .write_data = nuc910_nand_write, - .write_block_data = nuc910_nand_write_block_data, - .read_block_data = nuc910_nand_read_block_data, - .nand_ready = nuc910_nand_ready, - .reset = nuc910_nand_reset, - .nand_device_command = nuc910_nand_device_command, - .init = nuc910_nand_init, -}; diff --git a/src/flash/nand/nuc910.h b/src/flash/nand/nuc910.h deleted file mode 100644 index 8877cf633..000000000 --- a/src/flash/nand/nuc910.h +++ /dev/null @@ -1,57 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2010 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -/* - * NAND controller interface for Nuvoton NUC910 - */ - -#ifndef OPENOCD_FLASH_NAND_NUC910_H -#define OPENOCD_FLASH_NAND_NUC910_H - -#define NUC910_FMICSR 0xB000D000 -#define NUC910_SMCSR 0xB000D0A0 -#define NUC910_SMTCR 0xB000D0A4 -#define NUC910_SMIER 0xB000D0A8 -#define NUC910_SMISR 0xB000D0AC -#define NUC910_SMCMD 0xB000D0B0 -#define NUC910_SMADDR 0xB000D0B4 -#define NUC910_SMDATA 0xB000D0B8 - -#define NUC910_SMECC0 0xB000D0BC -#define NUC910_SMECC1 0xB000D0C0 -#define NUC910_SMECC2 0xB000D0C4 -#define NUC910_SMECC3 0xB000D0C8 -#define NUC910_ECC4ST 0xB000D114 - -/* Global Control and Status Register (FMICSR) */ -#define NUC910_FMICSR_SM_EN (1<<3) - -/* NAND Flash Address Port Register (SMADDR) */ -#define NUC910_SMADDR_EOA (1<<31) - -/* NAND Flash Control and Status Register (SMCSR) */ -#define NUC910_SMCSR_PSIZE (1<<3) -#define NUC910_SMCSR_DBW (1<<4) - -/* NAND Flash Interrupt Status Register (SMISR) */ -#define NUC910_SMISR_ECC_IF (1<<2) -#define NUC910_SMISR_RB_ (1<<18) - -/* ECC4 Correction Status (ECC4ST) */ - -#endif /* OPENOCD_FLASH_NAND_NUC910_H */ diff --git a/src/flash/nand/orion.c b/src/flash/nand/orion.c deleted file mode 100644 index 69814eca3..000000000 --- a/src/flash/nand/orion.c +++ /dev/null @@ -1,161 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2009 by Marvell Semiconductors, Inc. * - * Written by Nicolas Pitre * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -/* - * NAND controller interface for Marvell Orion/Kirkwood SoCs. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "imp.h" -#include "arm_io.h" -#include - -struct orion_nand_controller { - struct arm_nand_data io; - - uint32_t cmd; - uint32_t addr; - uint32_t data; -}; - -#define CHECK_HALTED \ - do { \ - if (target->state != TARGET_HALTED) { \ - LOG_ERROR("NAND flash access requires halted target"); \ - return ERROR_NAND_OPERATION_FAILED; \ - } \ - } while (0) - -static int orion_nand_command(struct nand_device *nand, uint8_t command) -{ - struct orion_nand_controller *hw = nand->controller_priv; - struct target *target = nand->target; - - CHECK_HALTED; - target_write_u8(target, hw->cmd, command); - return ERROR_OK; -} - -static int orion_nand_address(struct nand_device *nand, uint8_t address) -{ - struct orion_nand_controller *hw = nand->controller_priv; - struct target *target = nand->target; - - CHECK_HALTED; - target_write_u8(target, hw->addr, address); - return ERROR_OK; -} - -static int orion_nand_read(struct nand_device *nand, void *data) -{ - struct orion_nand_controller *hw = nand->controller_priv; - struct target *target = nand->target; - - CHECK_HALTED; - target_read_u8(target, hw->data, data); - return ERROR_OK; -} - -static int orion_nand_write(struct nand_device *nand, uint16_t data) -{ - struct orion_nand_controller *hw = nand->controller_priv; - struct target *target = nand->target; - - CHECK_HALTED; - target_write_u8(target, hw->data, data); - return ERROR_OK; -} - -static int orion_nand_slow_block_write(struct nand_device *nand, uint8_t *data, int size) -{ - while (size--) - orion_nand_write(nand, *data++); - return ERROR_OK; -} - -static int orion_nand_fast_block_write(struct nand_device *nand, uint8_t *data, int size) -{ - struct orion_nand_controller *hw = nand->controller_priv; - int retval; - - hw->io.chunk_size = nand->page_size; - - retval = arm_nandwrite(&hw->io, data, size); - if (retval == ERROR_NAND_NO_BUFFER) - retval = orion_nand_slow_block_write(nand, data, size); - - return retval; -} - -static int orion_nand_reset(struct nand_device *nand) -{ - return orion_nand_command(nand, NAND_CMD_RESET); -} - -NAND_DEVICE_COMMAND_HANDLER(orion_nand_device_command) -{ - struct orion_nand_controller *hw; - uint32_t base; - uint8_t ale, cle; - - if (CMD_ARGC != 3) - return ERROR_COMMAND_SYNTAX_ERROR; - - hw = calloc(1, sizeof(*hw)); - if (!hw) { - LOG_ERROR("no memory for nand controller"); - return ERROR_NAND_DEVICE_INVALID; - } - - nand->controller_priv = hw; - - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], base); - cle = 0; - ale = 1; - - hw->data = base; - hw->cmd = base + (1 << cle); - hw->addr = base + (1 << ale); - - hw->io.target = nand->target; - hw->io.data = hw->data; - hw->io.op = ARM_NAND_NONE; - - return ERROR_OK; -} - -static int orion_nand_init(struct nand_device *nand) -{ - return ERROR_OK; -} - -struct nand_flash_controller orion_nand_controller = { - .name = "orion", - .usage = " ", - .command = orion_nand_command, - .address = orion_nand_address, - .read_data = orion_nand_read, - .write_data = orion_nand_write, - .write_block_data = orion_nand_fast_block_write, - .reset = orion_nand_reset, - .nand_device_command = orion_nand_device_command, - .init = orion_nand_init, -}; diff --git a/src/flash/nand/s3c2410.c b/src/flash/nand/s3c2410.c deleted file mode 100644 index 57b51b48c..000000000 --- a/src/flash/nand/s3c2410.c +++ /dev/null @@ -1,116 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007, 2008 by Ben Dooks * - * ben@fluff.org * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -/* - * S3C2410 OpenOCD NAND Flash controller support. - * - * Many thanks to Simtec Electronics for sponsoring this work. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "s3c24xx.h" - -NAND_DEVICE_COMMAND_HANDLER(s3c2410_nand_device_command) -{ - struct s3c24xx_nand_controller *info; - CALL_S3C24XX_DEVICE_COMMAND(nand, &info); - - /* fill in the address fields for the core device */ - info->cmd = S3C2410_NFCMD; - info->addr = S3C2410_NFADDR; - info->data = S3C2410_NFDATA; - info->nfstat = S3C2410_NFSTAT; - - return ERROR_OK; -} - -static int s3c2410_init(struct nand_device *nand) -{ - struct target *target = nand->target; - - target_write_u32(target, S3C2410_NFCONF, - S3C2410_NFCONF_EN | S3C2410_NFCONF_TACLS(3) | - S3C2410_NFCONF_TWRPH0(5) | S3C2410_NFCONF_TWRPH1(3)); - - return ERROR_OK; -} - -static int s3c2410_write_data(struct nand_device *nand, uint16_t data) -{ - struct target *target = nand->target; - - if (target->state != TARGET_HALTED) { - LOG_ERROR("target must be halted to use S3C24XX NAND flash controller"); - return ERROR_NAND_OPERATION_FAILED; - } - - target_write_u32(target, S3C2410_NFDATA, data); - return ERROR_OK; -} - -static int s3c2410_read_data(struct nand_device *nand, void *data) -{ - struct target *target = nand->target; - - if (target->state != TARGET_HALTED) { - LOG_ERROR("target must be halted to use S3C24XX NAND flash controller"); - return ERROR_NAND_OPERATION_FAILED; - } - - target_read_u8(target, S3C2410_NFDATA, data); - return ERROR_OK; -} - -static int s3c2410_nand_ready(struct nand_device *nand, int timeout) -{ - struct target *target = nand->target; - uint8_t status; - - if (target->state != TARGET_HALTED) { - LOG_ERROR("target must be halted to use S3C24XX NAND flash controller"); - return ERROR_NAND_OPERATION_FAILED; - } - - do { - target_read_u8(target, S3C2410_NFSTAT, &status); - - if (status & S3C2410_NFSTAT_BUSY) - return 1; - - alive_sleep(1); - } while (timeout-- > 0); - - return 0; -} - -struct nand_flash_controller s3c2410_nand_controller = { - .name = "s3c2410", - .nand_device_command = &s3c2410_nand_device_command, - .init = &s3c2410_init, - .reset = &s3c24xx_reset, - .command = &s3c24xx_command, - .address = &s3c24xx_address, - .write_data = &s3c2410_write_data, - .read_data = &s3c2410_read_data, - .write_page = s3c24xx_write_page, - .read_page = s3c24xx_read_page, - .nand_ready = &s3c2410_nand_ready, -}; diff --git a/src/flash/nand/s3c2412.c b/src/flash/nand/s3c2412.c deleted file mode 100644 index 002378a16..000000000 --- a/src/flash/nand/s3c2412.c +++ /dev/null @@ -1,75 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007, 2008 by Ben Dooks * - * ben@fluff.org * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -/* - * S3C2412 OpenOCD NAND Flash controller support. - * - * Many thanks to Simtec Electronics for sponsoring this work. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "s3c24xx.h" - -NAND_DEVICE_COMMAND_HANDLER(s3c2412_nand_device_command) -{ - struct s3c24xx_nand_controller *info; - CALL_S3C24XX_DEVICE_COMMAND(nand, &info); - - /* fill in the address fields for the core device */ - info->cmd = S3C2440_NFCMD; - info->addr = S3C2440_NFADDR; - info->data = S3C2440_NFDATA; - info->nfstat = S3C2412_NFSTAT; - - return ERROR_OK; -} - -static int s3c2412_init(struct nand_device *nand) -{ - struct target *target = nand->target; - - target_write_u32(target, S3C2410_NFCONF, - S3C2440_NFCONF_TACLS(3) | - S3C2440_NFCONF_TWRPH0(7) | - S3C2440_NFCONF_TWRPH1(7)); - - target_write_u32(target, S3C2440_NFCONT, - S3C2412_NFCONT_INIT_MAIN_ECC | - S3C2440_NFCONT_ENABLE); - - return ERROR_OK; -} - -struct nand_flash_controller s3c2412_nand_controller = { - .name = "s3c2412", - .nand_device_command = &s3c2412_nand_device_command, - .init = &s3c2412_init, - .reset = &s3c24xx_reset, - .command = &s3c24xx_command, - .address = &s3c24xx_address, - .write_data = &s3c24xx_write_data, - .read_data = &s3c24xx_read_data, - .write_page = s3c24xx_write_page, - .read_page = s3c24xx_read_page, - .write_block_data = &s3c2440_write_block_data, - .read_block_data = &s3c2440_read_block_data, - .nand_ready = &s3c2440_nand_ready, -}; diff --git a/src/flash/nand/s3c2440.c b/src/flash/nand/s3c2440.c deleted file mode 100644 index 44670e6f2..000000000 --- a/src/flash/nand/s3c2440.c +++ /dev/null @@ -1,166 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007, 2008 by Ben Dooks * - * ben@fluff.org * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -/* - * S3C2440 OpenOCD NAND Flash controller support. - * - * Many thanks to Simtec Electronics for sponsoring this work. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "s3c24xx.h" - -NAND_DEVICE_COMMAND_HANDLER(s3c2440_nand_device_command) -{ - struct s3c24xx_nand_controller *info; - CALL_S3C24XX_DEVICE_COMMAND(nand, &info); - - /* fill in the address fields for the core device */ - info->cmd = S3C2440_NFCMD; - info->addr = S3C2440_NFADDR; - info->data = S3C2440_NFDATA; - info->nfstat = S3C2440_NFSTAT; - - return ERROR_OK; -} - -static int s3c2440_init(struct nand_device *nand) -{ - struct target *target = nand->target; - - target_write_u32(target, S3C2410_NFCONF, - S3C2440_NFCONF_TACLS(3) | - S3C2440_NFCONF_TWRPH0(7) | - S3C2440_NFCONF_TWRPH1(7)); - - target_write_u32(target, S3C2440_NFCONT, - S3C2440_NFCONT_INITECC | S3C2440_NFCONT_ENABLE); - - return ERROR_OK; -} - -int s3c2440_nand_ready(struct nand_device *nand, int timeout) -{ - struct s3c24xx_nand_controller *s3c24xx_info = nand->controller_priv; - struct target *target = nand->target; - uint8_t status; - - if (target->state != TARGET_HALTED) { - LOG_ERROR("target must be halted to use S3C24XX NAND flash controller"); - return ERROR_NAND_OPERATION_FAILED; - } - - do { - target_read_u8(target, s3c24xx_info->nfstat, &status); - - if (status & S3C2440_NFSTAT_READY) - return 1; - - alive_sleep(1); - } while (timeout-- > 0); - - - return 0; -} - -/* use the fact we can read/write 4 bytes in one go via a single 32bit op */ - -int s3c2440_read_block_data(struct nand_device *nand, uint8_t *data, int data_size) -{ - struct s3c24xx_nand_controller *s3c24xx_info = nand->controller_priv; - struct target *target = nand->target; - uint32_t nfdata = s3c24xx_info->data; - uint32_t tmp; - - LOG_INFO("%s: reading data: %p, %p, %d", __func__, nand, data, data_size); - - if (target->state != TARGET_HALTED) { - LOG_ERROR("target must be halted to use S3C24XX NAND flash controller"); - return ERROR_NAND_OPERATION_FAILED; - } - - while (data_size >= 4) { - target_read_u32(target, nfdata, &tmp); - - data[0] = tmp; - data[1] = tmp >> 8; - data[2] = tmp >> 16; - data[3] = tmp >> 24; - - data_size -= 4; - data += 4; - } - - while (data_size > 0) { - target_read_u8(target, nfdata, data); - - data_size -= 1; - data += 1; - } - - return ERROR_OK; -} - -int s3c2440_write_block_data(struct nand_device *nand, uint8_t *data, int data_size) -{ - struct s3c24xx_nand_controller *s3c24xx_info = nand->controller_priv; - struct target *target = nand->target; - uint32_t nfdata = s3c24xx_info->data; - uint32_t tmp; - - if (target->state != TARGET_HALTED) { - LOG_ERROR("target must be halted to use S3C24XX NAND flash controller"); - return ERROR_NAND_OPERATION_FAILED; - } - - while (data_size >= 4) { - tmp = le_to_h_u32(data); - target_write_u32(target, nfdata, tmp); - - data_size -= 4; - data += 4; - } - - while (data_size > 0) { - target_write_u8(target, nfdata, *data); - - data_size -= 1; - data += 1; - } - - return ERROR_OK; -} - -struct nand_flash_controller s3c2440_nand_controller = { - .name = "s3c2440", - .nand_device_command = &s3c2440_nand_device_command, - .init = &s3c2440_init, - .reset = &s3c24xx_reset, - .command = &s3c24xx_command, - .address = &s3c24xx_address, - .write_data = &s3c24xx_write_data, - .read_data = &s3c24xx_read_data, - .write_page = s3c24xx_write_page, - .read_page = s3c24xx_read_page, - .write_block_data = &s3c2440_write_block_data, - .read_block_data = &s3c2440_read_block_data, - .nand_ready = &s3c2440_nand_ready, -}; diff --git a/src/flash/nand/s3c2443.c b/src/flash/nand/s3c2443.c deleted file mode 100644 index ffd3864bf..000000000 --- a/src/flash/nand/s3c2443.c +++ /dev/null @@ -1,75 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007, 2008 by Ben Dooks * - * ben@fluff.org * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -/* - * S3C2443 OpenOCD NAND Flash controller support. - * - * Many thanks to Simtec Electronics for sponsoring this work. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "s3c24xx.h" - -NAND_DEVICE_COMMAND_HANDLER(s3c2443_nand_device_command) -{ - struct s3c24xx_nand_controller *info; - CALL_S3C24XX_DEVICE_COMMAND(nand, &info); - - /* fill in the address fields for the core device */ - info->cmd = S3C2440_NFCMD; - info->addr = S3C2440_NFADDR; - info->data = S3C2440_NFDATA; - info->nfstat = S3C2412_NFSTAT; - - return ERROR_OK; -} - -static int s3c2443_init(struct nand_device *nand) -{ - struct target *target = nand->target; - - target_write_u32(target, S3C2410_NFCONF, - S3C2440_NFCONF_TACLS(3) | - S3C2440_NFCONF_TWRPH0(7) | - S3C2440_NFCONF_TWRPH1(7)); - - target_write_u32(target, S3C2440_NFCONT, - S3C2412_NFCONT_INIT_MAIN_ECC | - S3C2440_NFCONT_ENABLE); - - return ERROR_OK; -} - -struct nand_flash_controller s3c2443_nand_controller = { - .name = "s3c2443", - .nand_device_command = &s3c2443_nand_device_command, - .init = &s3c2443_init, - .reset = &s3c24xx_reset, - .command = &s3c24xx_command, - .address = &s3c24xx_address, - .write_data = &s3c24xx_write_data, - .read_data = &s3c24xx_read_data, - .write_page = s3c24xx_write_page, - .read_page = s3c24xx_read_page, - .write_block_data = &s3c2440_write_block_data, - .read_block_data = &s3c2440_read_block_data, - .nand_ready = &s3c2440_nand_ready, -}; diff --git a/src/flash/nand/s3c24xx.c b/src/flash/nand/s3c24xx.c deleted file mode 100644 index ae3f13737..000000000 --- a/src/flash/nand/s3c24xx.c +++ /dev/null @@ -1,117 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007, 2008 by Ben Dooks * - * ben@fluff.org * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -/* - * S3C24XX Series OpenOCD NAND Flash controller support. - * - * Many thanks to Simtec Electronics for sponsoring this work. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "s3c24xx.h" - -S3C24XX_DEVICE_COMMAND() -{ - *info = NULL; - - struct s3c24xx_nand_controller *s3c24xx_info; - s3c24xx_info = malloc(sizeof(struct s3c24xx_nand_controller)); - if (s3c24xx_info == NULL) { - LOG_ERROR("no memory for nand controller"); - return -ENOMEM; - } - - nand->controller_priv = s3c24xx_info; - *info = s3c24xx_info; - - return ERROR_OK; -} - -int s3c24xx_reset(struct nand_device *nand) -{ - struct s3c24xx_nand_controller *s3c24xx_info = nand->controller_priv; - struct target *target = nand->target; - - if (target->state != TARGET_HALTED) { - LOG_ERROR("target must be halted to use S3C24XX NAND flash controller"); - return ERROR_NAND_OPERATION_FAILED; - } - - target_write_u32(target, s3c24xx_info->cmd, 0xff); - - return ERROR_OK; -} - -int s3c24xx_command(struct nand_device *nand, uint8_t command) -{ - struct s3c24xx_nand_controller *s3c24xx_info = nand->controller_priv; - struct target *target = nand->target; - - if (target->state != TARGET_HALTED) { - LOG_ERROR("target must be halted to use S3C24XX NAND flash controller"); - return ERROR_NAND_OPERATION_FAILED; - } - - target_write_u16(target, s3c24xx_info->cmd, command); - return ERROR_OK; -} - -int s3c24xx_address(struct nand_device *nand, uint8_t address) -{ - struct s3c24xx_nand_controller *s3c24xx_info = nand->controller_priv; - struct target *target = nand->target; - - if (target->state != TARGET_HALTED) { - LOG_ERROR("target must be halted to use S3C24XX NAND flash controller"); - return ERROR_NAND_OPERATION_FAILED; - } - - target_write_u16(target, s3c24xx_info->addr, address); - return ERROR_OK; -} - -int s3c24xx_write_data(struct nand_device *nand, uint16_t data) -{ - struct s3c24xx_nand_controller *s3c24xx_info = nand->controller_priv; - struct target *target = nand->target; - - if (target->state != TARGET_HALTED) { - LOG_ERROR("target must be halted to use S3C24XX NAND flash controller"); - return ERROR_NAND_OPERATION_FAILED; - } - - target_write_u8(target, s3c24xx_info->data, data); - return ERROR_OK; -} - -int s3c24xx_read_data(struct nand_device *nand, void *data) -{ - struct s3c24xx_nand_controller *s3c24xx_info = nand->controller_priv; - struct target *target = nand->target; - - if (target->state != TARGET_HALTED) { - LOG_ERROR("target must be halted to use S3C24XX NAND flash controller"); - return ERROR_NAND_OPERATION_FAILED; - } - - target_read_u8(target, s3c24xx_info->data, data); - return ERROR_OK; -} diff --git a/src/flash/nand/s3c24xx.h b/src/flash/nand/s3c24xx.h deleted file mode 100644 index 5c7782dab..000000000 --- a/src/flash/nand/s3c24xx.h +++ /dev/null @@ -1,78 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007, 2008 by Ben Dooks * - * ben@fluff.org * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifndef OPENOCD_FLASH_NAND_S3C24XX_H -#define OPENOCD_FLASH_NAND_S3C24XX_H - -/* - * S3C24XX Series OpenOCD NAND Flash controller support. - * - * Many thanks to Simtec Electronics for sponsoring this work. - */ - -#include "imp.h" -#include "s3c24xx_regs.h" -#include - -struct s3c24xx_nand_controller { - /* register addresses */ - uint32_t cmd; - uint32_t addr; - uint32_t data; - uint32_t nfstat; -}; - -/* Default to using the un-translated NAND register based address */ -#undef S3C2410_NFREG -#define S3C2410_NFREG(x) ((x) + 0x4e000000) - -#define S3C24XX_DEVICE_COMMAND() \ - COMMAND_HELPER(s3c24xx_nand_device_command, \ - struct nand_device *nand, \ - struct s3c24xx_nand_controller **info) - -S3C24XX_DEVICE_COMMAND(); - -#define CALL_S3C24XX_DEVICE_COMMAND(d, i) \ - do { \ - int retval = CALL_COMMAND_HANDLER(s3c24xx_nand_device_command, d, i); \ - if (ERROR_OK != retval) \ - return retval; \ - } while (0) - -int s3c24xx_reset(struct nand_device *nand); - -int s3c24xx_command(struct nand_device *nand, uint8_t command); -int s3c24xx_address(struct nand_device *nand, uint8_t address); - -int s3c24xx_write_data(struct nand_device *nand, uint16_t data); -int s3c24xx_read_data(struct nand_device *nand, void *data); - -#define s3c24xx_write_page NULL -#define s3c24xx_read_page NULL - -/* code shared between different controllers */ - -int s3c2440_nand_ready(struct nand_device *nand, int timeout); - -int s3c2440_read_block_data(struct nand_device *nand, - uint8_t *data, int data_size); -int s3c2440_write_block_data(struct nand_device *nand, - uint8_t *data, int data_size); - -#endif /* OPENOCD_FLASH_NAND_S3C24XX_H */ diff --git a/src/flash/nand/s3c24xx_regs.h b/src/flash/nand/s3c24xx_regs.h deleted file mode 100644 index 88bc66567..000000000 --- a/src/flash/nand/s3c24xx_regs.h +++ /dev/null @@ -1,129 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2004, 2005 by Simtec Electronics * - * linux@simtec.co.uk * - * http://www.simtec.co.uk/products/SWLINUX/ * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; version 2 of the License. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -/* - * S3C2410 NAND register definitions - */ - -#ifndef OPENOCD_FLASH_NAND_S3C24XX_REGS_H -#define OPENOCD_FLASH_NAND_S3C24XX_REGS_H - -#define S3C2410_NFREG(x) (x) - -#define S3C2410_NFCONF S3C2410_NFREG(0x00) -#define S3C2410_NFCMD S3C2410_NFREG(0x04) -#define S3C2410_NFADDR S3C2410_NFREG(0x08) -#define S3C2410_NFDATA S3C2410_NFREG(0x0C) -#define S3C2410_NFSTAT S3C2410_NFREG(0x10) -#define S3C2410_NFECC S3C2410_NFREG(0x14) - -#define S3C2440_NFCONT S3C2410_NFREG(0x04) -#define S3C2440_NFCMD S3C2410_NFREG(0x08) -#define S3C2440_NFADDR S3C2410_NFREG(0x0C) -#define S3C2440_NFDATA S3C2410_NFREG(0x10) -#define S3C2440_NFECCD0 S3C2410_NFREG(0x14) -#define S3C2440_NFECCD1 S3C2410_NFREG(0x18) -#define S3C2440_NFECCD S3C2410_NFREG(0x1C) -#define S3C2440_NFSTAT S3C2410_NFREG(0x20) -#define S3C2440_NFESTAT0 S3C2410_NFREG(0x24) -#define S3C2440_NFESTAT1 S3C2410_NFREG(0x28) -#define S3C2440_NFMECC0 S3C2410_NFREG(0x2C) -#define S3C2440_NFMECC1 S3C2410_NFREG(0x30) -#define S3C2440_NFSECC S3C2410_NFREG(0x34) -#define S3C2440_NFSBLK S3C2410_NFREG(0x38) -#define S3C2440_NFEBLK S3C2410_NFREG(0x3C) - -#define S3C2412_NFSBLK S3C2410_NFREG(0x20) -#define S3C2412_NFEBLK S3C2410_NFREG(0x24) -#define S3C2412_NFSTAT S3C2410_NFREG(0x28) -#define S3C2412_NFMECC_ERR0 S3C2410_NFREG(0x2C) -#define S3C2412_NFMECC_ERR1 S3C2410_NFREG(0x30) -#define S3C2412_NFMECC0 S3C2410_NFREG(0x34) -#define S3C2412_NFMECC1 S3C2410_NFREG(0x38) -#define S3C2412_NFSECC S3C2410_NFREG(0x3C) - -#define S3C2410_NFCONF_EN (1 << 15) -#define S3C2410_NFCONF_512BYTE (1 << 14) -#define S3C2410_NFCONF_4STEP (1 << 13) -#define S3C2410_NFCONF_INITECC (1 << 12) -#define S3C2410_NFCONF_nFCE (1 << 11) -#define S3C2410_NFCONF_TACLS(x) ((x) << 8) -#define S3C2410_NFCONF_TWRPH0(x) ((x) << 4) -#define S3C2410_NFCONF_TWRPH1(x) ((x) << 0) - -#define S3C2410_NFSTAT_BUSY (1 << 0) - -#define S3C2440_NFCONF_BUSWIDTH_8 (0 << 0) -#define S3C2440_NFCONF_BUSWIDTH_16 (1 << 0) -#define S3C2440_NFCONF_ADVFLASH (1 << 3) -#define S3C2440_NFCONF_TACLS(x) ((x) << 12) -#define S3C2440_NFCONF_TWRPH0(x) ((x) << 8) -#define S3C2440_NFCONF_TWRPH1(x) ((x) << 4) - -#define S3C2440_NFCONT_LOCKTIGHT (1 << 13) -#define S3C2440_NFCONT_SOFTLOCK (1 << 12) -#define S3C2440_NFCONT_ILLEGALACC_EN (1 << 10) -#define S3C2440_NFCONT_RNBINT_EN (1 << 9) -#define S3C2440_NFCONT_RN_FALLING (1 << 8) -#define S3C2440_NFCONT_SPARE_ECCLOCK (1 << 6) -#define S3C2440_NFCONT_MAIN_ECCLOCK (1 << 5) -#define S3C2440_NFCONT_INITECC (1 << 4) -#define S3C2440_NFCONT_nFCE (1 << 1) -#define S3C2440_NFCONT_ENABLE (1 << 0) - -#define S3C2440_NFSTAT_READY (1 << 0) -#define S3C2440_NFSTAT_nCE (1 << 1) -#define S3C2440_NFSTAT_RnB_CHANGE (1 << 2) -#define S3C2440_NFSTAT_ILLEGAL_ACCESS (1 << 3) - -#define S3C2412_NFCONF_NANDBOOT (1 << 31) -#define S3C2412_NFCONF_ECCCLKCON (1 << 30) -#define S3C2412_NFCONF_ECC_MLC (1 << 24) -#define S3C2412_NFCONF_TACLS_MASK (7 << 12) /* 1 extra bit of Tacls */ - -#define S3C2412_NFCONT_ECC4_DIRWR (1 << 18) -#define S3C2412_NFCONT_LOCKTIGHT (1 << 17) -#define S3C2412_NFCONT_SOFTLOCK (1 << 16) -#define S3C2412_NFCONT_ECC4_ENCINT (1 << 13) -#define S3C2412_NFCONT_ECC4_DECINT (1 << 12) -#define S3C2412_NFCONT_MAIN_ECC_LOCK (1 << 7) -#define S3C2412_NFCONT_INIT_MAIN_ECC (1 << 5) -#define S3C2412_NFCONT_nFCE1 (1 << 2) -#define S3C2412_NFCONT_nFCE0 (1 << 1) - -#define S3C2412_NFSTAT_ECC_ENCDONE (1 << 7) -#define S3C2412_NFSTAT_ECC_DECDONE (1 << 6) -#define S3C2412_NFSTAT_ILLEGAL_ACCESS (1 << 5) -#define S3C2412_NFSTAT_RnB_CHANGE (1 << 4) -#define S3C2412_NFSTAT_nFCE1 (1 << 3) -#define S3C2412_NFSTAT_nFCE0 (1 << 2) -#define S3C2412_NFSTAT_Res1 (1 << 1) -#define S3C2412_NFSTAT_READY (1 << 0) - -#define S3C2412_NFECCERR_SERRDATA(x) (((x) >> 21) & 0xf) -#define S3C2412_NFECCERR_SERRBIT(x) (((x) >> 18) & 0x7) -#define S3C2412_NFECCERR_MERRDATA(x) (((x) >> 7) & 0x3ff) -#define S3C2412_NFECCERR_MERRBIT(x) (((x) >> 4) & 0x7) -#define S3C2412_NFECCERR_SPARE_ERR(x) (((x) >> 2) & 0x3) -#define S3C2412_NFECCERR_MAIN_ERR(x) (((x) >> 2) & 0x3) -#define S3C2412_NFECCERR_NONE (0) -#define S3C2412_NFECCERR_1BIT (1) -#define S3C2412_NFECCERR_MULTIBIT (2) -#define S3C2412_NFECCERR_ECCAREA (3) - -#endif /* OPENOCD_FLASH_NAND_S3C24XX_REGS_H */ diff --git a/src/flash/nand/s3c6400.c b/src/flash/nand/s3c6400.c deleted file mode 100644 index 7058133bc..000000000 --- a/src/flash/nand/s3c6400.c +++ /dev/null @@ -1,72 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2010 by Peter Korsgaard * - * Heavily based on s3c2412.c by Ben Dooks * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 -#include "config.h" -#endif - -#include "s3c24xx.h" -/* s3c64xx uses another base address for the nand controller than 24xx */ -#undef S3C2410_NFREG -#define S3C2410_NFREG(x) ((x) + 0x70200000) - -NAND_DEVICE_COMMAND_HANDLER(s3c6400_nand_device_command) -{ - struct s3c24xx_nand_controller *info; - CALL_S3C24XX_DEVICE_COMMAND(nand, &info); - - /* fill in the address fields for the core device */ - info->cmd = S3C2440_NFCMD; - info->addr = S3C2440_NFADDR; - info->data = S3C2440_NFDATA; - info->nfstat = S3C2412_NFSTAT; - - return ERROR_OK; -} - -static int s3c6400_init(struct nand_device *nand) -{ - struct target *target = nand->target; - - target_write_u32(target, S3C2410_NFCONF, - S3C2440_NFCONF_TACLS(3) | - S3C2440_NFCONF_TWRPH0(7) | - S3C2440_NFCONF_TWRPH1(7) | 4); - - target_write_u32(target, S3C2440_NFCONT, - S3C2412_NFCONT_INIT_MAIN_ECC | - S3C2440_NFCONT_ENABLE); - - return ERROR_OK; -} - -struct nand_flash_controller s3c6400_nand_controller = { - .name = "s3c6400", - .nand_device_command = &s3c6400_nand_device_command, - .init = &s3c6400_init, - .reset = &s3c24xx_reset, - .command = &s3c24xx_command, - .address = &s3c24xx_address, - .write_data = &s3c24xx_write_data, - .read_data = &s3c24xx_read_data, - .write_page = s3c24xx_write_page, - .read_page = s3c24xx_read_page, - .write_block_data = &s3c2440_write_block_data, - .read_block_data = &s3c2440_read_block_data, - .nand_ready = &s3c2440_nand_ready, -}; diff --git a/src/flash/nand/tcl.c b/src/flash/nand/tcl.c deleted file mode 100644 index cbdeda5bc..000000000 --- a/src/flash/nand/tcl.c +++ /dev/null @@ -1,626 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Dominic Rath * - * Copyright (C) 2002 Thomas Gleixner * - * Copyright (C) 2009 Zachary T Welch * - * * - * Partially based on drivers/mtd/nand_ids.c from Linux. * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "core.h" -#include "imp.h" -#include "fileio.h" -#include - -/* to be removed */ -extern struct nand_device *nand_devices; - -COMMAND_HANDLER(handle_nand_list_command) -{ - struct nand_device *p; - int i; - - if (!nand_devices) { - command_print(CMD_CTX, "no NAND flash devices configured"); - return ERROR_OK; - } - - for (p = nand_devices, i = 0; p; p = p->next, i++) { - if (p->device) - command_print(CMD_CTX, "#%i: %s (%s) " - "pagesize: %i, buswidth: %i,\n\t" - "blocksize: %i, blocks: %i", - i, p->device->name, p->manufacturer->name, - p->page_size, p->bus_width, - p->erase_size, p->num_blocks); - else - command_print(CMD_CTX, "#%i: not probed", i); - } - - return ERROR_OK; -} - -COMMAND_HANDLER(handle_nand_info_command) -{ - int i = 0; - int j = 0; - int first = -1; - int last = -1; - - switch (CMD_ARGC) { - default: - return ERROR_COMMAND_SYNTAX_ERROR; - case 1: - first = 0; - last = INT32_MAX; - break; - case 2: - COMMAND_PARSE_NUMBER(int, CMD_ARGV[1], i); - first = last = i; - i = 0; - break; - case 3: - COMMAND_PARSE_NUMBER(int, CMD_ARGV[1], first); - COMMAND_PARSE_NUMBER(int, CMD_ARGV[2], last); - break; - } - - struct nand_device *p; - int retval = CALL_COMMAND_HANDLER(nand_command_get_device, 0, &p); - if (ERROR_OK != retval) - return retval; - - if (NULL == p->device) { - command_print(CMD_CTX, "#%s: not probed", CMD_ARGV[0]); - return ERROR_OK; - } - - if (first >= p->num_blocks) - first = p->num_blocks - 1; - - if (last >= p->num_blocks) - last = p->num_blocks - 1; - - command_print(CMD_CTX, - "#%i: %s (%s) pagesize: %i, buswidth: %i, erasesize: %i", - i++, - p->device->name, - p->manufacturer->name, - p->page_size, - p->bus_width, - p->erase_size); - - for (j = first; j <= last; j++) { - char *erase_state, *bad_state; - - if (p->blocks[j].is_erased == 0) - erase_state = "not erased"; - else if (p->blocks[j].is_erased == 1) - erase_state = "erased"; - else - erase_state = "erase state unknown"; - - if (p->blocks[j].is_bad == 0) - bad_state = ""; - else if (p->blocks[j].is_bad == 1) - bad_state = " (marked bad)"; - else - bad_state = " (block condition unknown)"; - - command_print(CMD_CTX, - "\t#%i: 0x%8.8" PRIx32 " (%" PRId32 "kB) %s%s", - j, - p->blocks[j].offset, - p->blocks[j].size / 1024, - erase_state, - bad_state); - } - - return ERROR_OK; -} - -COMMAND_HANDLER(handle_nand_probe_command) -{ - if (CMD_ARGC != 1) - return ERROR_COMMAND_SYNTAX_ERROR; - - struct nand_device *p; - int retval = CALL_COMMAND_HANDLER(nand_command_get_device, 0, &p); - if (ERROR_OK != retval) - return retval; - - retval = nand_probe(p); - if (retval == ERROR_OK) { - command_print(CMD_CTX, "NAND flash device '%s (%s)' found", - p->device->name, p->manufacturer->name); - } - - return retval; -} - -COMMAND_HANDLER(handle_nand_erase_command) -{ - if (CMD_ARGC != 1 && CMD_ARGC != 3) - return ERROR_COMMAND_SYNTAX_ERROR; - - struct nand_device *p; - int retval = CALL_COMMAND_HANDLER(nand_command_get_device, 0, &p); - if (ERROR_OK != retval) - return retval; - - unsigned long offset; - unsigned long length; - - /* erase specified part of the chip; or else everything */ - if (CMD_ARGC == 3) { - unsigned long size = p->erase_size * p->num_blocks; - - COMMAND_PARSE_NUMBER(ulong, CMD_ARGV[1], offset); - if ((offset % p->erase_size) != 0 || offset >= size) - return ERROR_COMMAND_SYNTAX_ERROR; - - COMMAND_PARSE_NUMBER(ulong, CMD_ARGV[2], length); - if ((length == 0) || (length % p->erase_size) != 0 - || (length + offset) > size) - return ERROR_COMMAND_SYNTAX_ERROR; - - offset /= p->erase_size; - length /= p->erase_size; - } else { - offset = 0; - length = p->num_blocks; - } - - retval = nand_erase(p, offset, offset + length - 1); - if (retval == ERROR_OK) { - command_print(CMD_CTX, "erased blocks %lu to %lu " - "on NAND flash device #%s '%s'", - offset, offset + length - 1, - CMD_ARGV[0], p->device->name); - } - - return retval; -} - -COMMAND_HANDLER(handle_nand_check_bad_blocks_command) -{ - int first = -1; - int last = -1; - - if ((CMD_ARGC < 1) || (CMD_ARGC > 3) || (CMD_ARGC == 2)) - return ERROR_COMMAND_SYNTAX_ERROR; - - struct nand_device *p; - int retval = CALL_COMMAND_HANDLER(nand_command_get_device, 0, &p); - if (ERROR_OK != retval) - return retval; - - if (CMD_ARGC == 3) { - unsigned long offset; - unsigned long length; - - COMMAND_PARSE_NUMBER(ulong, CMD_ARGV[1], offset); - if (offset % p->erase_size) - return ERROR_COMMAND_SYNTAX_ERROR; - offset /= p->erase_size; - - COMMAND_PARSE_NUMBER(ulong, CMD_ARGV[2], length); - if (length % p->erase_size) - return ERROR_COMMAND_SYNTAX_ERROR; - - length -= 1; - length /= p->erase_size; - - first = offset; - last = offset + length; - } - - retval = nand_build_bbt(p, first, last); - if (retval == ERROR_OK) { - command_print(CMD_CTX, "checked NAND flash device for bad blocks, " - "use \"nand info\" command to list blocks"); - } - - return retval; -} - -COMMAND_HANDLER(handle_nand_write_command) -{ - struct nand_device *nand = NULL; - struct nand_fileio_state s; - int retval = CALL_COMMAND_HANDLER(nand_fileio_parse_args, - &s, &nand, FILEIO_READ, false, true); - if (ERROR_OK != retval) - return retval; - - uint32_t total_bytes = s.size; - while (s.size > 0) { - 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); - } - s.size -= bytes_read; - - retval = nand_write_page(nand, s.address / nand->page_size, - s.page, s.page_size, s.oob, s.oob_size); - if (ERROR_OK != retval) { - 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); - } - s.address += s.page_size; - } - - if (nand_fileio_finish(&s) == ERROR_OK) { - command_print(CMD_CTX, "wrote file %s to NAND flash %s up to " - "offset 0x%8.8" PRIx32 " in %fs (%0.3f KiB/s)", - CMD_ARGV[1], CMD_ARGV[0], s.address, duration_elapsed(&s.bench), - duration_kbps(&s.bench, total_bytes)); - } - return ERROR_OK; -} - -COMMAND_HANDLER(handle_nand_verify_command) -{ - struct nand_device *nand = NULL; - struct nand_fileio_state file; - int retval = CALL_COMMAND_HANDLER(nand_fileio_parse_args, - &file, &nand, FILEIO_READ, false, true); - if (ERROR_OK != retval) - return retval; - - struct nand_fileio_state dev; - nand_fileio_init(&dev); - dev.address = file.address; - dev.size = file.size; - dev.oob_format = file.oob_format; - retval = nand_fileio_start(CMD_CTX, nand, NULL, FILEIO_NONE, &dev); - if (ERROR_OK != retval) - return retval; - - while (file.size > 0) { - retval = nand_read_page(nand, dev.address / dev.page_size, - dev.page, dev.page_size, dev.oob, dev.oob_size); - if (ERROR_OK != retval) { - command_print(CMD_CTX, "reading NAND flash page failed"); - nand_fileio_cleanup(&dev); - nand_fileio_cleanup(&file); - return retval; - } - - int bytes_read = nand_fileio_read(nand, &file); - if (bytes_read <= 0) { - command_print(CMD_CTX, "error while reading file"); - nand_fileio_cleanup(&dev); - nand_fileio_cleanup(&file); - return ERROR_FAIL; - } - - if ((dev.page && memcmp(dev.page, file.page, dev.page_size)) || - (dev.oob && memcmp(dev.oob, file.oob, dev.oob_size))) { - command_print(CMD_CTX, "NAND flash contents differ " - "at 0x%8.8" PRIx32, dev.address); - nand_fileio_cleanup(&dev); - nand_fileio_cleanup(&file); - return ERROR_FAIL; - } - - file.size -= bytes_read; - dev.address += nand->page_size; - } - - if (nand_fileio_finish(&file) == ERROR_OK) { - command_print(CMD_CTX, "verified file %s in NAND flash %s " - "up to offset 0x%8.8" PRIx32 " in %fs (%0.3f KiB/s)", - CMD_ARGV[1], CMD_ARGV[0], dev.address, duration_elapsed(&file.bench), - duration_kbps(&file.bench, dev.size)); - } - - return nand_fileio_cleanup(&dev); -} - -COMMAND_HANDLER(handle_nand_dump_command) -{ - size_t filesize; - struct nand_device *nand = NULL; - struct nand_fileio_state s; - int retval = CALL_COMMAND_HANDLER(nand_fileio_parse_args, - &s, &nand, FILEIO_WRITE, true, false); - if (ERROR_OK != retval) - return retval; - - while (s.size > 0) { - size_t size_written; - retval = nand_read_page(nand, s.address / nand->page_size, - s.page, s.page_size, s.oob, s.oob_size); - if (ERROR_OK != retval) { - command_print(CMD_CTX, "reading NAND flash page failed"); - nand_fileio_cleanup(&s); - return retval; - } - - if (NULL != s.page) - 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); - - s.size -= nand->page_size; - s.address += nand->page_size; - } - - retval = fileio_size(s.fileio, &filesize); - if (retval != ERROR_OK) - return retval; - - if (nand_fileio_finish(&s) == ERROR_OK) { - command_print(CMD_CTX, "dumped %zu bytes in %fs (%0.3f KiB/s)", - filesize, duration_elapsed(&s.bench), - duration_kbps(&s.bench, filesize)); - } - return ERROR_OK; -} - -COMMAND_HANDLER(handle_nand_raw_access_command) -{ - if ((CMD_ARGC < 1) || (CMD_ARGC > 2)) - return ERROR_COMMAND_SYNTAX_ERROR; - - struct nand_device *p; - int retval = CALL_COMMAND_HANDLER(nand_command_get_device, 0, &p); - if (ERROR_OK != retval) - return retval; - - if (NULL == p->device) { - command_print(CMD_CTX, "#%s: not probed", CMD_ARGV[0]); - return ERROR_OK; - } - - if (CMD_ARGC == 2) - COMMAND_PARSE_ENABLE(CMD_ARGV[1], p->use_raw); - - const char *msg = p->use_raw ? "enabled" : "disabled"; - command_print(CMD_CTX, "raw access is %s", msg); - - return ERROR_OK; -} - -static const struct command_registration nand_exec_command_handlers[] = { - { - .name = "list", - .handler = handle_nand_list_command, - .mode = COMMAND_EXEC, - .help = "list configured NAND flash devices", - }, - { - .name = "info", - .handler = handle_nand_info_command, - .mode = COMMAND_EXEC, - .usage = "[banknum | first_bank_num last_bank_num]", - .help = "print info about one or more NAND flash devices", - }, - { - .name = "probe", - .handler = handle_nand_probe_command, - .mode = COMMAND_EXEC, - .usage = "bank_id", - .help = "identify NAND flash device", - }, - { - .name = "check_bad_blocks", - .handler = handle_nand_check_bad_blocks_command, - .mode = COMMAND_EXEC, - .usage = "bank_id [offset length]", - .help = "check all or part of NAND flash device for bad blocks", - }, - { - .name = "erase", - .handler = handle_nand_erase_command, - .mode = COMMAND_EXEC, - .usage = "bank_id [offset length]", - .help = "erase all or subset of blocks on NAND flash device", - }, - { - .name = "dump", - .handler = handle_nand_dump_command, - .mode = COMMAND_EXEC, - .usage = "bank_id filename offset length " - "['oob_raw'|'oob_only']", - .help = "dump from NAND flash device", - }, - { - .name = "verify", - .handler = handle_nand_verify_command, - .mode = COMMAND_EXEC, - .usage = "bank_id filename offset " - "['oob_raw'|'oob_only'|'oob_softecc'|'oob_softecc_kw']", - .help = "verify NAND flash device", - }, - { - .name = "write", - .handler = handle_nand_write_command, - .mode = COMMAND_EXEC, - .usage = "bank_id filename offset " - "['oob_raw'|'oob_only'|'oob_softecc'|'oob_softecc_kw']", - .help = "write to NAND flash device", - }, - { - .name = "raw_access", - .handler = handle_nand_raw_access_command, - .mode = COMMAND_EXEC, - .usage = "bank_id ['enable'|'disable']", - .help = "raw access to NAND flash device", - }, - COMMAND_REGISTRATION_DONE -}; - -static int nand_init(struct command_context *cmd_ctx) -{ - if (!nand_devices) - return ERROR_OK; - struct command *parent = command_find_in_context(cmd_ctx, "nand"); - return register_commands(cmd_ctx, parent, nand_exec_command_handlers); -} - -COMMAND_HANDLER(handle_nand_init_command) -{ - if (CMD_ARGC != 0) - return ERROR_COMMAND_SYNTAX_ERROR; - - static bool nand_initialized; - if (nand_initialized) { - LOG_INFO("'nand init' has already been called"); - return ERROR_OK; - } - nand_initialized = true; - - LOG_DEBUG("Initializing NAND devices..."); - return nand_init(CMD_CTX); -} - -static int nand_list_walker(struct nand_flash_controller *c, void *x) -{ - struct command_context *cmd_ctx = x; - command_print(cmd_ctx, " %s", c->name); - return ERROR_OK; -} - -COMMAND_HANDLER(handle_nand_list_drivers) -{ - command_print(CMD_CTX, "Available NAND flash controller drivers:"); - return nand_driver_walk(&nand_list_walker, CMD_CTX); -} - -static COMMAND_HELPER(create_nand_device, const char *bank_name, - struct nand_flash_controller *controller) -{ - struct nand_device *c; - struct target *target; - int retval; - - if (CMD_ARGC < 2) - return ERROR_COMMAND_SYNTAX_ERROR; - target = get_target(CMD_ARGV[1]); - if (!target) { - LOG_ERROR("invalid target %s", CMD_ARGV[1]); - return ERROR_COMMAND_ARGUMENT_INVALID; - } - - if (NULL != controller->commands) { - retval = register_commands(CMD_CTX, NULL, - controller->commands); - if (ERROR_OK != retval) - return retval; - } - c = malloc(sizeof(struct nand_device)); - if (c == NULL) { - LOG_ERROR("End of memory"); - return ERROR_FAIL; - } - - c->name = strdup(bank_name); - c->target = target; - c->controller = controller; - c->controller_priv = NULL; - c->manufacturer = NULL; - c->device = NULL; - c->bus_width = 0; - c->address_cycles = 0; - c->page_size = 0; - c->use_raw = false; - c->next = NULL; - - retval = CALL_COMMAND_HANDLER(controller->nand_device_command, c); - if (ERROR_OK != retval) { - LOG_ERROR("'%s' driver rejected nand flash. Usage: %s", - controller->name, - controller->usage); - free(c); - return retval; - } - - if (controller->usage == NULL) - LOG_DEBUG("'%s' driver usage field missing", controller->name); - - nand_device_add(c); - - return ERROR_OK; -} - -COMMAND_HANDLER(handle_nand_device_command) -{ - if (CMD_ARGC < 2) - return ERROR_COMMAND_SYNTAX_ERROR; - - /* save name and increment (for compatibility) with drivers */ - const char *bank_name = *CMD_ARGV++; - CMD_ARGC--; - - const char *driver_name = CMD_ARGV[0]; - struct nand_flash_controller *controller; - controller = nand_driver_find_by_name(CMD_ARGV[0]); - if (NULL == controller) { - LOG_ERROR("No valid NAND flash driver found (%s)", driver_name); - return CALL_COMMAND_HANDLER(handle_nand_list_drivers); - } - return CALL_COMMAND_HANDLER(create_nand_device, bank_name, controller); -} - -static const struct command_registration nand_config_command_handlers[] = { - { - .name = "device", - .handler = &handle_nand_device_command, - .mode = COMMAND_CONFIG, - .help = "defines a new NAND bank", - .usage = "bank_id driver target [driver_options ...]", - }, - { - .name = "drivers", - .handler = &handle_nand_list_drivers, - .mode = COMMAND_ANY, - .help = "lists available NAND drivers", - .usage = "" - }, - { - .name = "init", - .mode = COMMAND_CONFIG, - .handler = &handle_nand_init_command, - .help = "initialize NAND devices", - .usage = "" - }, - COMMAND_REGISTRATION_DONE -}; - -static const struct command_registration nand_command_handlers[] = { - { - .name = "nand", - .mode = COMMAND_ANY, - .help = "NAND flash command group", - .usage = "", - .chain = nand_config_command_handlers, - }, - COMMAND_REGISTRATION_DONE -}; - -int nand_register_commands(struct command_context *cmd_ctx) -{ - return register_commands(cmd_ctx, NULL, nand_command_handlers); -} diff --git a/src/flash/nor/Makefile.am b/src/flash/nor/Makefile.am deleted file mode 100644 index 084e6b61c..000000000 --- a/src/flash/nor/Makefile.am +++ /dev/null @@ -1,70 +0,0 @@ -include $(top_srcdir)/common.mk - -noinst_LTLIBRARIES = libocdflashnor.la -libocdflashnor_la_SOURCES = \ - core.c \ - tcl.c \ - $(NOR_DRIVERS) \ - drivers.c - -NOR_DRIVERS = \ - aduc702x.c \ - aducm360.c \ - ambiqmicro.c \ - at91sam4.c \ - at91sam4l.c \ - at91samd.c \ - at91sam3.c \ - at91sam7.c \ - atsamv.c \ - avrf.c \ - cfi.c \ - dsp5680xx_flash.c \ - efm32.c \ - em357.c \ - fespi.c \ - faux.c \ - fm3.c \ - fm4.c \ - jtagspi.c \ - kinetis.c \ - kinetis_ke.c \ - lpc2000.c \ - lpc288x.c \ - lpc2900.c \ - lpcspifi.c \ - mdr.c \ - mrvlqspi.c \ - niietcm4.c \ - non_cfi.c \ - nrf51.c \ - numicro.c \ - ocl.c \ - pic32mx.c \ - psoc4.c \ - sim3x.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 \ - xmc1xxx.c \ - xmc4xxx.c - -noinst_HEADERS = \ - core.h \ - cfi.h \ - driver.h \ - imp.h \ - non_cfi.h \ - ocl.h \ - spi.h - -MAINTAINERCLEANFILES = $(srcdir)/Makefile.in diff --git a/src/flash/nor/aduc702x.c b/src/flash/nor/aduc702x.c deleted file mode 100644 index 34cc362eb..000000000 --- a/src/flash/nor/aduc702x.c +++ /dev/null @@ -1,404 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2008 by Kevin McGuire * - * Copyright (C) 2008 by Marcel Wijlaars * - * Copyright (C) 2009 by Michael Ashton * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "imp.h" -#include -#include -#include -#include - -static int aduc702x_build_sector_list(struct flash_bank *bank); -static int aduc702x_check_flash_completion(struct target *target, unsigned int timeout_ms); -static int aduc702x_set_write_enable(struct target *target, int enable); - -#define ADUC702x_FLASH 0xfffff800 -#define ADUC702x_FLASH_FEESTA (0*4) -#define ADUC702x_FLASH_FEEMOD (1*4) -#define ADUC702x_FLASH_FEECON (2*4) -#define ADUC702x_FLASH_FEEDAT (3*4) -#define ADUC702x_FLASH_FEEADR (4*4) -#define ADUC702x_FLASH_FEESIGN (5*4) -#define ADUC702x_FLASH_FEEPRO (6*4) -#define ADUC702x_FLASH_FEEHIDE (7*4) - -/* flash bank aduc702x 0 0 0 0 - * The ADC7019-28 devices all have the same flash layout */ -FLASH_BANK_COMMAND_HANDLER(aduc702x_flash_bank_command) -{ - bank->base = 0x80000; - bank->size = 0xF800; /* top 4k not accessible */ - - aduc702x_build_sector_list(bank); - - return ERROR_OK; -} - -static int aduc702x_build_sector_list(struct flash_bank *bank) -{ - /* aduc7026_struct flash_bank *aduc7026_info = bank->driver_priv; */ - - int i = 0; - uint32_t offset = 0; - - /* sector size is 512 */ - bank->num_sectors = bank->size / 512; - 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 = 512; - offset += bank->sectors[i].size; - bank->sectors[i].is_erased = -1; - bank->sectors[i].is_protected = 0; - } - - return ERROR_OK; -} - -static int aduc702x_protect_check(struct flash_bank *bank) -{ - printf("aduc702x_protect_check not implemented yet.\n"); - return ERROR_OK; -} - -static int aduc702x_erase(struct flash_bank *bank, int first, int last) -{ - /* int res; */ - int x; - int count; - /* uint32_t v; */ - struct target *target = bank->target; - - aduc702x_set_write_enable(target, 1); - - /* mass erase */ - if (((first | last) == 0) || ((first == 0) && (last >= bank->num_sectors))) { - LOG_DEBUG("performing mass erase."); - target_write_u16(target, ADUC702x_FLASH + ADUC702x_FLASH_FEEDAT, 0x3cff); - target_write_u16(target, ADUC702x_FLASH + ADUC702x_FLASH_FEEADR, 0xffc3); - target_write_u8(target, ADUC702x_FLASH + ADUC702x_FLASH_FEECON, 0x06); - - if (aduc702x_check_flash_completion(target, 3500) != ERROR_OK) { - LOG_ERROR("mass erase failed"); - aduc702x_set_write_enable(target, 0); - return ERROR_FLASH_OPERATION_FAILED; - } - - LOG_DEBUG("mass erase successful."); - return ERROR_OK; - } else { - unsigned long adr; - - count = last - first + 1; - for (x = 0; x < count; ++x) { - adr = bank->base + ((first + x) * 512); - - target_write_u16(target, ADUC702x_FLASH + ADUC702x_FLASH_FEEADR, adr); - target_write_u8(target, ADUC702x_FLASH + ADUC702x_FLASH_FEECON, 0x05); - - if (aduc702x_check_flash_completion(target, 50) != ERROR_OK) { - LOG_ERROR("failed to erase sector at address 0x%08lX", adr); - aduc702x_set_write_enable(target, 0); - return ERROR_FLASH_SECTOR_NOT_ERASED; - } - - LOG_DEBUG("erased sector at address 0x%08lX", adr); - } - } - - aduc702x_set_write_enable(target, 0); - - return ERROR_OK; -} - -static int aduc702x_protect(struct flash_bank *bank, int set, int first, int last) -{ - printf("aduc702x_protect not implemented yet.\n"); - return ERROR_FLASH_OPERATION_FAILED; -} - -/* If this fn returns ERROR_TARGET_RESOURCE_NOT_AVAILABLE, then the caller can fall - * back to another mechanism that does not require onboard RAM - * - * Caller should not check for other return values specifically - */ -static int aduc702x_write_block(struct flash_bank *bank, - const uint8_t *buffer, - uint32_t offset, - uint32_t count) -{ - struct target *target = bank->target; - uint32_t buffer_size = 7000; - struct working_area *write_algorithm; - struct working_area *source; - uint32_t address = bank->base + offset; - struct reg_param reg_params[6]; - struct arm_algorithm arm_algo; - int retval = ERROR_OK; - - if (((count%2) != 0) || ((offset%2) != 0)) { - LOG_ERROR("write block must be multiple of two bytes in offset & length"); - return ERROR_FAIL; - } - - /* parameters: - - r0 - address of source data (absolute) - r1 - number of halfwords to be copied - r2 - start address in flash (offset from beginning of flash memory) - r3 - exit code - r4 - base address of flash controller (0xFFFFF800) - - registers: - - r5 - scratch - r6 - set to 2, used to write flash command - - */ - static const uint32_t aduc702x_flash_write_code[] = { - /* <_start>: */ - 0xe3a05008, /* mov r5, #8 ; 0x8 */ - 0xe5845004, /* str r5, [r4, #4] */ - 0xe3a06002, /* mov r6, #2 ; 0x2 */ - /* : */ - 0xe1c421b0, /* strh r2, [r4, #16] */ - 0xe0d050b2, /* ldrh r5, [r0], #2 */ - 0xe1c450bc, /* strh r5, [r4, #12] */ - 0xe5c46008, /* strb r6, [r4, #8] */ - /* : */ - 0xe1d430b0, /* ldrh r3, [r4] */ - 0xe3130004, /* tst r3, #4 ; 0x4 */ - 0x1afffffc, /* bne 1001c */ - 0xe2822002, /* add r2, r2, #2 ; 0x2 */ - 0xe2511001, /* subs r1, r1, #1 ; 0x1 */ - 0x0a000001, /* beq 1003c */ - 0xe3130001, /* tst r3, #1 ; 0x1 */ - 0x1afffff3, /* bne 1000c */ - /* : */ - 0xeafffffe /* b 1003c */ - }; - - /* flash write code */ - if (target_alloc_working_area(target, sizeof(aduc702x_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; - } - - uint8_t code[sizeof(aduc702x_flash_write_code)]; - target_buffer_set_u32_array(target, code, ARRAY_SIZE(aduc702x_flash_write_code), - aduc702x_flash_write_code); - retval = target_write_buffer(target, write_algorithm->address, sizeof(code), code); - if (retval != ERROR_OK) - return retval; - - /* memory buffer */ - while (target_alloc_working_area_try(target, buffer_size, &source) != ERROR_OK) { - buffer_size /= 2; - if (buffer_size <= 256) { - /* we already allocated the writing code, but failed to get a buffer, - *free the algorithm */ - target_free_working_area(target, write_algorithm); - - LOG_WARNING("no large enough working area available, can't do block memory writes"); - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - } - } - - arm_algo.common_magic = ARM_COMMON_MAGIC; - arm_algo.core_mode = ARM_MODE_SVC; - arm_algo.core_state = ARM_STATE_ARM; - - init_reg_param(®_params[0], "r0", 32, PARAM_OUT); - init_reg_param(®_params[1], "r1", 32, PARAM_OUT); - init_reg_param(®_params[2], "r2", 32, PARAM_OUT); - init_reg_param(®_params[3], "r3", 32, PARAM_IN); - init_reg_param(®_params[4], "r4", 32, PARAM_OUT); - - while (count > 0) { - uint32_t thisrun_count = (count > buffer_size) ? buffer_size : count; - - retval = target_write_buffer(target, source->address, thisrun_count, buffer); - if (retval != ERROR_OK) - break; - - buf_set_u32(reg_params[0].value, 0, 32, source->address); - buf_set_u32(reg_params[1].value, 0, 32, thisrun_count/2); - buf_set_u32(reg_params[2].value, 0, 32, address); - buf_set_u32(reg_params[4].value, 0, 32, 0xFFFFF800); - - retval = target_run_algorithm(target, 0, NULL, 5, - reg_params, write_algorithm->address, - write_algorithm->address + - sizeof(aduc702x_flash_write_code) - 4, - 10000, &arm_algo); - if (retval != ERROR_OK) { - LOG_ERROR("error executing aduc702x flash write algorithm"); - break; - } - - if ((buf_get_u32(reg_params[3].value, 0, 32) & 1) != 1) { - /* FIX!!!! what does this mean??? replace w/sensible error message */ - LOG_ERROR("aduc702x detected error writing flash"); - retval = ERROR_FAIL; - break; - } - - buffer += thisrun_count; - address += thisrun_count; - count -= thisrun_count; - } - - target_free_working_area(target, source); - target_free_working_area(target, write_algorithm); - - 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; -} - -/* All-JTAG, single-access method. Very slow. Used only if there is no - * working area available. */ -static int aduc702x_write_single(struct flash_bank *bank, - const uint8_t *buffer, - uint32_t offset, - uint32_t count) -{ - uint32_t x; - uint8_t b; - struct target *target = bank->target; - - aduc702x_set_write_enable(target, 1); - - for (x = 0; x < count; x += 2) { - /* FEEADR = address */ - target_write_u16(target, ADUC702x_FLASH + ADUC702x_FLASH_FEEADR, offset + x); - - /* set up data */ - if ((x + 1) == count) { - /* last byte */ - target_read_u8(target, offset + x + 1, &b); - } else - b = buffer[x + 1]; - - target_write_u16(target, ADUC702x_FLASH + ADUC702x_FLASH_FEEDAT, buffer[x] | (b << 8)); - - /* do single-write command */ - target_write_u8(target, ADUC702x_FLASH + ADUC702x_FLASH_FEECON, 0x02); - - if (aduc702x_check_flash_completion(target, 1) != ERROR_OK) { - LOG_ERROR("single write failed for address 0x%08lX", - (unsigned long)(offset + x)); - aduc702x_set_write_enable(target, 0); - return ERROR_FLASH_OPERATION_FAILED; - } - - } - LOG_DEBUG("wrote %d bytes at address 0x%08lX", (int)count, (unsigned long)(offset + x)); - - aduc702x_set_write_enable(target, 0); - - return ERROR_OK; -} - -static int aduc702x_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count) -{ - int retval; - - /* try using a block write */ - retval = aduc702x_write_block(bank, buffer, offset, count); - if (retval != ERROR_OK) { - if (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE) { - /* if block write failed (no sufficient working area), - * use normal (slow) JTAG method */ - LOG_WARNING("couldn't use block writes, falling back to single memory accesses"); - - retval = aduc702x_write_single(bank, buffer, offset, count); - if (retval != ERROR_OK) { - LOG_ERROR("slow write failed"); - return ERROR_FLASH_OPERATION_FAILED; - } - } - } - - return retval; -} - -static int aduc702x_probe(struct flash_bank *bank) -{ - return ERROR_OK; -} - -/* sets FEEMOD bit 3 - * enable = 1 enables writes & erases, 0 disables them */ -static int aduc702x_set_write_enable(struct target *target, int enable) -{ - /* don't bother to preserve int enable bit here */ - target_write_u16(target, ADUC702x_FLASH + ADUC702x_FLASH_FEEMOD, enable ? 8 : 0); - - return ERROR_OK; -} - -/* wait up to timeout_ms for controller to not be busy, - * then check whether the command passed or failed. - * - * this function sleeps 1ms between checks (after the first one), - * so in some cases may slow things down without a usleep after the first read */ -static int aduc702x_check_flash_completion(struct target *target, unsigned int timeout_ms) -{ - uint8_t v = 4; - - int64_t endtime = timeval_ms() + timeout_ms; - while (1) { - target_read_u8(target, ADUC702x_FLASH + ADUC702x_FLASH_FEESTA, &v); - if ((v & 4) == 0) - break; - alive_sleep(1); - if (timeval_ms() >= endtime) - break; - } - - if (v & 2) - return ERROR_FAIL; - /* if a command is ignored, both the success and fail bits may be 0 */ - else if ((v & 3) == 0) - return ERROR_FAIL; - else - return ERROR_OK; -} - -struct flash_driver aduc702x_flash = { - .name = "aduc702x", - .flash_bank_command = aduc702x_flash_bank_command, - .erase = aduc702x_erase, - .protect = aduc702x_protect, - .write = aduc702x_write, - .read = default_flash_read, - .probe = aduc702x_probe, - .auto_probe = aduc702x_probe, - .erase_check = default_flash_blank_check, - .protect_check = aduc702x_protect_check, -}; diff --git a/src/flash/nor/aducm360.c b/src/flash/nor/aducm360.c deleted file mode 100644 index 8681a25af..000000000 --- a/src/flash/nor/aducm360.c +++ /dev/null @@ -1,582 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2015 by Ivan Buliev * - * i.buliev@mikrosistemi.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -/*************************************************************************** - * This version for ADuCM360 is largely based on the following flash * - * drivers: * - * - aduc702x.c * - * Copyright (C) 2008 by Kevin McGuire * - * Copyright (C) 2008 by Marcel Wijlaars * - * Copyright (C) 2009 by Michael Ashton * - * and * - * - stm32f1x.c * - * Copyright (C) 2005 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * Copyright (C) 2008 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * Copyright (C) 2011 by Andreas Fritiofson * - * andreas.fritiofson@gmail.com * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "imp.h" -#include -#include -#include -#include - -static int aducm360_build_sector_list(struct flash_bank *bank); -static int aducm360_check_flash_completion(struct target *target, unsigned int timeout_ms); -static int aducm360_set_write_enable(struct target *target, int enable); - -#define ADUCM360_FLASH_BASE 0x40002800 -#define ADUCM360_FLASH_FEESTA 0x0000 -#define ADUCM360_FLASH_FEECON0 0x0004 -#define ADUCM360_FLASH_FEECMD 0x0008 -#define ADUCM360_FLASH_FEEADR0L 0x0010 -#define ADUCM360_FLASH_FEEADR0H 0x0014 -#define ADUCM360_FLASH_FEEADR1L 0x0018 -#define ADUCM360_FLASH_FEEADR1H 0x001C -#define ADUCM360_FLASH_FEEKEY 0x0020 -#define ADUCM360_FLASH_FEEPROL 0x0028 -#define ADUCM360_FLASH_FEEPROH 0x002C -#define ADUCM360_FLASH_FEESIGL 0x0030 -#define ADUCM360_FLASH_FEESIGH 0x0034 -#define ADUCM360_FLASH_FEECON1 0x0038 -#define ADUCM360_FLASH_FEEADRAL 0x0048 -#define ADUCM360_FLASH_FEEADRAH 0x004C -#define ADUCM360_FLASH_FEEAEN0 0x0078 -#define ADUCM360_FLASH_FEEAEN1 0x007C -#define ADUCM360_FLASH_FEEAEN2 0x0080 - -/* flash bank aducm360 0 0 0 0 */ -FLASH_BANK_COMMAND_HANDLER(aducm360_flash_bank_command) -{ - bank->base = 0x00000000; - bank->size = 0x00020000; - - aducm360_build_sector_list(bank); - - return ERROR_OK; -} - -#define FLASH_SECTOR_SIZE 512 - -/* ----------------------------------------------------------------------- */ -static int aducm360_build_sector_list(struct flash_bank *bank) -{ - int i = 0; - uint32_t offset = 0; - - /* sector size is 512 */ - bank->num_sectors = bank->size / FLASH_SECTOR_SIZE; - 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 = FLASH_SECTOR_SIZE; - offset += bank->sectors[i].size; - bank->sectors[i].is_erased = -1; - bank->sectors[i].is_protected = 0; - } - - return ERROR_OK; -} - -/* ----------------------------------------------------------------------- */ -static int aducm360_protect_check(struct flash_bank *bank) -{ - LOG_WARNING("aducm360_protect_check not implemented."); - return ERROR_OK; -} - -/* ----------------------------------------------------------------------- */ -static int aducm360_mass_erase(struct target *target) -{ - uint32_t value; - int res = ERROR_OK; - - /* Clear any old status */ - target_read_u32(target, ADUCM360_FLASH_BASE + ADUCM360_FLASH_FEESTA, &value); - - /* Enable the writing to the flash*/ - aducm360_set_write_enable(target, 1); - - /* Unlock for writing */ - target_write_u32(target, ADUCM360_FLASH_BASE+ADUCM360_FLASH_FEEKEY, 0x0000F456); - target_write_u32(target, ADUCM360_FLASH_BASE+ADUCM360_FLASH_FEEKEY, 0x0000F123); - /* Issue the 'MASSERASE' command */ - target_write_u32(target, ADUCM360_FLASH_BASE+ADUCM360_FLASH_FEECMD, 0x00000003); - - /* Check the result */ - res = aducm360_check_flash_completion(target, 3500); - if (res != ERROR_OK) { - LOG_ERROR("mass erase failed."); - aducm360_set_write_enable(target, 0); - res = ERROR_FLASH_OPERATION_FAILED; - } - - return res; -} - -/* ----------------------------------------------------------------------- */ -static int aducm360_page_erase(struct target *target, uint32_t padd) -{ - uint32_t value; - int res = ERROR_OK; - - /* Clear any old status */ - target_read_u32(target, ADUCM360_FLASH_BASE + ADUCM360_FLASH_FEESTA, &value); - - /* Enable the writing to the flash*/ - aducm360_set_write_enable(target, 1); - - /* Unlock for writing */ - target_write_u32(target, ADUCM360_FLASH_BASE+ADUCM360_FLASH_FEEKEY, 0x0000F456); - target_write_u32(target, ADUCM360_FLASH_BASE+ADUCM360_FLASH_FEEKEY, 0x0000F123); - /* Write the sector address */ - target_write_u32(target, ADUCM360_FLASH_BASE+ADUCM360_FLASH_FEEADR0L, padd & 0xFFFF); - target_write_u32(target, ADUCM360_FLASH_BASE+ADUCM360_FLASH_FEEADR0H, (padd>>16) & 0xFFFF); - /* Issue the 'ERASEPAGE' command */ - target_write_u32(target, ADUCM360_FLASH_BASE+ADUCM360_FLASH_FEECMD, 0x00000001); - - /* Check the result */ - res = aducm360_check_flash_completion(target, 50); - if (res != ERROR_OK) { - LOG_ERROR("page erase failed at 0x%08" PRIx32, padd); - aducm360_set_write_enable(target, 0); - res = ERROR_FLASH_OPERATION_FAILED; - } - - return res; -} - -/* ----------------------------------------------------------------------- */ -static int aducm360_erase(struct flash_bank *bank, int first, int last) -{ - int res = ERROR_OK; - int i; - int count; - struct target *target = bank->target; - uint32_t padd; - - if (((first | last) == 0) || ((first == 0) && (last >= bank->num_sectors))) { - res = aducm360_mass_erase(target); - } else { - count = last - first + 1; - for (i = 0; i < count; ++i) { - padd = bank->base + ((first+i)*FLASH_SECTOR_SIZE); - res = aducm360_page_erase(target, padd); - if (res != ERROR_OK) - break; - } - } - - return res; -} - -/* ----------------------------------------------------------------------- */ -static int aducm360_protect(struct flash_bank *bank, int set, int first, int last) -{ - LOG_ERROR("aducm360_protect not implemented."); - return ERROR_FLASH_OPERATION_FAILED; -} - -/* ----------------------------------------------------------------------- */ -static int aducm360_write_block_sync( - struct flash_bank *bank, - const uint8_t *buffer, - uint32_t offset, - uint32_t count) -{ - struct target *target = bank->target; - uint32_t target_buffer_size = 8192; - struct working_area *helper; - struct working_area *target_buffer; - uint32_t address = bank->base + offset; - struct reg_param reg_params[8]; - int retval = ERROR_OK; - uint32_t entry_point = 0, exit_point = 0; - uint32_t res; - struct armv7m_algorithm armv7m_algo; - - static const uint32_t aducm360_flash_write_code[] = { - /* helper.code */ - 0x88AF4D10, 0x0704F047, 0x682F80AF, 0x600E6806, - 0xF017882F, 0xF43F0F08, 0xF851AFFB, 0x42B77B04, - 0x800DF040, 0x0004F100, 0xF47F3A04, 0x686FAFEF, - 0x0704F027, 0xF04F80AF, 0xF0000400, 0xF04FB802, - 0xBE000480, 0x40002800, 0x00015000, 0x20000000, - 0x00013000 - }; - - LOG_DEBUG("'aducm360_write_block_sync' requested, dst:0x%08" PRIx32 ", count:0x%08" PRIx32 "bytes.", - address, count); - - /* ----- Check the destination area for a Long Word alignment ----- */ - if (((count%4) != 0) || ((offset%4) != 0)) { - LOG_ERROR("write block must be multiple of four bytes in offset & length"); - return ERROR_FAIL; - } - - /* ----- Allocate space in the target's RAM for the helper code ----- */ - if (target_alloc_working_area(target, sizeof(aducm360_flash_write_code), - &helper) != ERROR_OK) { - LOG_WARNING("no working area available, can't do block memory writes"); - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - } - - /* ----- Upload the helper code to the space in the target's RAM ----- */ - uint8_t code[sizeof(aducm360_flash_write_code)]; - target_buffer_set_u32_array(target, code, ARRAY_SIZE(aducm360_flash_write_code), - aducm360_flash_write_code); - retval = target_write_buffer(target, helper->address, sizeof(code), code); - if (retval != ERROR_OK) - return retval; - entry_point = helper->address; - - /* ----- Allocate space in the target's RAM for the user application's object code ----- */ - while (target_alloc_working_area_try(target, target_buffer_size, &target_buffer) != ERROR_OK) { - LOG_WARNING("couldn't allocate a buffer space of 0x%08" PRIx32 "bytes in the target's SRAM.", - target_buffer_size); - target_buffer_size /= 2; - if (target_buffer_size <= 256) { /* No room available */ - LOG_WARNING("no large enough working area available, can't do block memory writes"); - target_free_working_area(target, helper); - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - } - } - - /* ----- Prepare the target for the helper ----- */ - armv7m_algo.common_magic = ARMV7M_COMMON_MAGIC; - armv7m_algo.core_mode = ARM_MODE_THREAD; - - init_reg_param(®_params[0], "r0", 32, PARAM_OUT); /*SRC */ - init_reg_param(®_params[1], "r1", 32, PARAM_OUT); /*DST */ - init_reg_param(®_params[2], "r2", 32, PARAM_OUT); /*COUNT */ - init_reg_param(®_params[3], "r3", 32, PARAM_OUT); /*not used */ - init_reg_param(®_params[4], "r4", 32, PARAM_IN); /*RESULT */ - - /* ===== Execute the Main Programming Loop! ===== */ - while (count > 0) { - uint32_t thisrun_count = (count > target_buffer_size) ? target_buffer_size : count; - - /* ----- Upload the chunk ----- */ - retval = target_write_buffer(target, target_buffer->address, thisrun_count, buffer); - if (retval != ERROR_OK) - break; - /* Set the arguments for the helper */ - buf_set_u32(reg_params[0].value, 0, 32, target_buffer->address); /*SRC */ - buf_set_u32(reg_params[1].value, 0, 32, address); /*DST */ - buf_set_u32(reg_params[2].value, 0, 32, thisrun_count); /*COUNT */ - buf_set_u32(reg_params[3].value, 0, 32, 0); /*NOT USED*/ - - retval = target_run_algorithm(target, 0, NULL, 5, - reg_params, entry_point, exit_point, 10000, &armv7m_algo); - if (retval != ERROR_OK) { - LOG_ERROR("error executing aducm360 flash write algorithm"); - break; - } - - res = buf_get_u32(reg_params[4].value, 0, 32); - if (res) { - LOG_ERROR("aducm360 fast sync algorithm reports an error (%02X)", res); - retval = ERROR_FAIL; - break; - } - - buffer += thisrun_count; - address += thisrun_count; - count -= thisrun_count; - } - - target_free_working_area(target, target_buffer); - target_free_working_area(target, helper); - - 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 aducm360_write_block_async( - struct flash_bank *bank, - const uint8_t *buffer, - uint32_t offset, - uint32_t count) -{ - struct target *target = bank->target; - uint32_t target_buffer_size = 1024; - struct working_area *helper; - struct working_area *target_buffer; - uint32_t address = bank->base + offset; - struct reg_param reg_params[9]; - int retval = ERROR_OK; - uint32_t entry_point = 0, exit_point = 0; - uint32_t res; - uint32_t wcount; - struct armv7m_algorithm armv7m_algo; - - static const uint32_t aducm360_flash_write_code[] = { - /* helper.code */ - 0x4050F8DF, 0xF04588A5, 0x80A50504, 0x8000F8D0, - 0x0F00F1B8, 0x8016F000, 0x45476847, 0xAFF6F43F, - 0x6B04F857, 0x6B04F842, 0xF0158825, 0xF43F0F08, - 0x428FAFFB, 0xF100BF28, 0x60470708, 0xB10B3B01, - 0xBFE4F7FF, 0xF02588A5, 0x80A50504, 0x0900F04F, - 0xBE00BF00, 0x40002800, 0x20000000, 0x20000100, - 0x00013000 - }; - - LOG_DEBUG("'aducm360_write_block_async' requested, dst:0x%08" PRIx32 ", count:0x%08" PRIx32 "bytes.", - address, count); - - /* ----- Check the destination area for a Long Word alignment ----- */ - if (((count%4) != 0) || ((offset%4) != 0)) { - LOG_ERROR("write block must be multiple of four bytes in offset & length"); - return ERROR_FAIL; - } - wcount = count/4; - - /* ----- Allocate space in the target's RAM for the helper code ----- */ - if (target_alloc_working_area(target, sizeof(aducm360_flash_write_code), - &helper) != ERROR_OK) { - LOG_WARNING("no working area available, can't do block memory writes"); - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - } - - /* ----- Upload the helper code to the space in the target's RAM ----- */ - uint8_t code[sizeof(aducm360_flash_write_code)]; - target_buffer_set_u32_array(target, code, ARRAY_SIZE(aducm360_flash_write_code), - aducm360_flash_write_code); - retval = target_write_buffer(target, helper->address, sizeof(code), code); - if (retval != ERROR_OK) - return retval; - entry_point = helper->address; - - /* ----- Allocate space in the target's RAM for the user application's object code ----- */ - while (target_alloc_working_area_try(target, target_buffer_size, &target_buffer) != ERROR_OK) { - LOG_WARNING("couldn't allocate a buffer space of 0x%08" PRIx32 "bytes in the target's SRAM.", - target_buffer_size); - target_buffer_size /= 2; - if (target_buffer_size <= 256) { /* No room available */ - LOG_WARNING("no large enough working area available, can't do block memory writes"); - target_free_working_area(target, helper); - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - } - } - - /* ----- Prepare the target for the helper ----- */ - armv7m_algo.common_magic = ARMV7M_COMMON_MAGIC; - armv7m_algo.core_mode = ARM_MODE_THREAD; - - init_reg_param(®_params[0], "r0", 32, PARAM_OUT); /*SRCBEG */ - init_reg_param(®_params[1], "r1", 32, PARAM_OUT); /*SRCEND */ - init_reg_param(®_params[2], "r2", 32, PARAM_OUT); /*DST */ - init_reg_param(®_params[3], "r3", 32, PARAM_OUT); /*COUNT (LWs)*/ - init_reg_param(®_params[4], "r9", 32, PARAM_IN); /*RESULT */ - - buf_set_u32(reg_params[0].value, 0, 32, target_buffer->address); - buf_set_u32(reg_params[1].value, 0, 32, target_buffer->address + target_buffer->size); - buf_set_u32(reg_params[2].value, 0, 32, address); - buf_set_u32(reg_params[3].value, 0, 32, wcount); - - retval = target_run_flash_async_algorithm(target, buffer, wcount, 4, - 0, NULL, - 5, reg_params, - target_buffer->address, target_buffer->size, - entry_point, exit_point, - &armv7m_algo); - if (retval != ERROR_OK) { - LOG_ERROR("error executing aducm360 flash write algorithm"); - } else { - res = buf_get_u32(reg_params[4].value, 0, 32); /*RESULT*/ - if (res) { - LOG_ERROR("aducm360 fast async algorithm reports an error (%02X)", res); - retval = ERROR_FAIL; - } - } - - target_free_working_area(target, target_buffer); - target_free_working_area(target, helper); - - 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; -} - -/* ----------------------------------------------------------------------- */ -/* If this fn returns ERROR_TARGET_RESOURCE_NOT_AVAILABLE, then the caller can fall - * back to another mechanism that does not require onboard RAM - * - * Caller should not check for other return values specifically - */ -static int aducm360_write_block(struct flash_bank *bank, - const uint8_t *buffer, - uint32_t offset, - uint32_t count) -{ - int choice = 0; - - switch (choice) { - case 0: - return aducm360_write_block_sync(bank, buffer, offset, count); - break; - case 1: - return aducm360_write_block_async(bank, buffer, offset, count); - break; - default: - LOG_ERROR("aducm360_write_block was cancelled (no writing method was chosen)!"); - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - } -} - -/* ----------------------------------------------------------------------- */ -#define FEESTA_WRDONE 0x00000008 - -static int aducm360_write_modified(struct flash_bank *bank, - const uint8_t *buffer, - uint32_t offset, - uint32_t count) -{ - uint32_t value; - int res = ERROR_OK; - uint32_t i, j, a, d; - struct target *target = bank->target; - - LOG_DEBUG("performing slow write (offset=0x%08" PRIx32 ", count=0x%08" PRIx32 ")...", - offset, count); - - /* Enable the writing to the flash */ - aducm360_set_write_enable(target, 1); - - /* Clear any old status */ - target_read_u32(target, ADUCM360_FLASH_BASE + ADUCM360_FLASH_FEESTA, &value); - - for (i = 0; i < count; i += 4) { - a = offset+i; - for (j = 0; i < 4; i += 1) - *((uint8_t *)(&d) + j) = buffer[i+j]; - target_write_u32(target, a, d); - do { - target_read_u32(target, ADUCM360_FLASH_BASE + ADUCM360_FLASH_FEESTA, &value); - } while (!(value & FEESTA_WRDONE)); - } - aducm360_set_write_enable(target, 0); - - return res; -} - -/* ----------------------------------------------------------------------- */ -static int aducm360_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count) -{ - int retval; - - /* try using a block write */ - retval = aducm360_write_block(bank, buffer, offset, count); - if (retval != ERROR_OK) { - if (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE) { - /* if block write failed (no sufficient working area), - * use normal (slow) JTAG method */ - LOG_WARNING("couldn't use block writes, falling back to single memory accesses"); - - retval = aducm360_write_modified(bank, buffer, offset, count); - if (retval != ERROR_OK) { - LOG_ERROR("slow write failed"); - return ERROR_FLASH_OPERATION_FAILED; - } - } - } - return retval; -} - -/* ----------------------------------------------------------------------- */ -static int aducm360_probe(struct flash_bank *bank) -{ - return ERROR_OK; -} - -/* ----------------------------------------------------------------------- */ -/* sets FEECON0 bit 2 - * enable = 1 enables writes & erases, 0 disables them */ -static int aducm360_set_write_enable(struct target *target, int enable) -{ - /* don't bother to preserve int enable bit here */ - uint32_t value; - - target_read_u32(target, ADUCM360_FLASH_BASE + ADUCM360_FLASH_FEECON0, &value); - if (enable) - value |= 0x00000004; - else - value &= ~0x00000004; - target_write_u32(target, ADUCM360_FLASH_BASE + ADUCM360_FLASH_FEECON0, value); - - return ERROR_OK; -} - -/* ----------------------------------------------------------------------- */ -/* wait up to timeout_ms for controller to not be busy, - * then check whether the command passed or failed. - * - * this function sleeps 1ms between checks (after the first one), - * so in some cases may slow things down without a usleep after the first read */ -static int aducm360_check_flash_completion(struct target *target, unsigned int timeout_ms) -{ - uint32_t v = 1; - - int64_t endtime = timeval_ms() + timeout_ms; - while (1) { - target_read_u32(target, ADUCM360_FLASH_BASE+ADUCM360_FLASH_FEESTA, &v); - if ((v & 0x00000001) == 0) - break; - alive_sleep(1); - if (timeval_ms() >= endtime) - break; - } - - if (!(v & 0x00000004)) /* b2 */ - return ERROR_FAIL; - - return ERROR_OK; -} - -/* ----------------------------------------------------------------------- */ -struct flash_driver aducm360_flash = { - .name = "aducm360", - .flash_bank_command = aducm360_flash_bank_command, - .erase = aducm360_erase, - .protect = aducm360_protect, - .write = aducm360_write, - .read = default_flash_read, - .probe = aducm360_probe, - .auto_probe = aducm360_probe, - .erase_check = default_flash_blank_check, - .protect_check = aducm360_protect_check, -}; diff --git a/src/flash/nor/ambiqmicro.c b/src/flash/nor/ambiqmicro.c deleted file mode 100644 index b2c30e6f4..000000000 --- a/src/flash/nor/ambiqmicro.c +++ /dev/null @@ -1,904 +0,0 @@ -/****************************************************************************** - * - * @file ambiqmicro.c - * - * @brief Ambiq Micro flash driver. - * - *****************************************************************************/ - -/****************************************************************************** - * Copyright (c) 2015, David Racine - * - * Copyright (c) 2016, Rick Foos - * - * Copyright (c) 2015-2016, Ambiq Micro, Inc. - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its - * contributors may be used to endorse or promote products derived from this - * software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - *****************************************************************************/ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "jtag/interface.h" -#include "imp.h" -#include "target/algorithm.h" -#include "target/armv7m.h" -#include "target/cortex_m.h" - -/** Check error, log error. */ -#define CHECK_STATUS(rc, msg) { \ - if (rc != ERROR_OK) { \ - LOG_ERROR("status(%d):%s\n", rc, msg); } } - -/* - * Address and Key defines. - */ -#define PROGRAM_KEY (0x12344321) -#define OTP_PROGRAM_KEY (0x87655678) - -#define FLASH_PROGRAM_MAIN_FROM_SRAM 0x0800005d -#define FLASH_PROGRAM_OTP_FROM_SRAM 0x08000061 -#define FLASH_ERASE_LIST_MAIN_PAGES_FROM_SRAM 0x08000065 -#define FLASH_MASS_ERASE_MAIN_PAGES_FROM_SRAM 0x08000069 - - -static const uint32_t apollo_flash_size[] = { - 1 << 15, - 1 << 16, - 1 << 17, - 1 << 18, - 1 << 19, - 1 << 20, - 1 << 21 -}; - -static const uint32_t apollo_sram_size[] = { - 1 << 15, - 1 << 16, - 1 << 17, - 1 << 18, - 1 << 19, - 1 << 20, - 1 << 21 -}; - -struct ambiqmicro_flash_bank { - /* chip id register */ - - uint32_t probed; - - const char *target_name; - uint8_t target_class; - - uint32_t sramsiz; - uint32_t flshsiz; - - /* flash geometry */ - uint32_t num_pages; - uint32_t pagesize; - uint32_t pages_in_lockregion; - - /* nv memory bits */ - uint16_t num_lockbits; - - /* main clock status */ - uint32_t rcc; - uint32_t rcc2; - uint8_t mck_valid; - uint8_t xtal_mask; - uint32_t iosc_freq; - uint32_t mck_freq; - const char *iosc_desc; - const char *mck_desc; -}; - -static struct { - uint8_t class; - uint8_t partno; - const char *partname; -} ambiqmicroParts[6] = { - {0xFF, 0x00, "Unknown"}, - {0x01, 0x00, "Apollo"}, - {0x02, 0x00, "Apollo2"}, - {0x03, 0x00, "Unknown"}, - {0x04, 0x00, "Unknown"}, - {0x05, 0x00, "Apollo"}, -}; - -static char *ambiqmicroClassname[6] = { - "Unknown", "Apollo", "Apollo2", "Unknown", "Unknown", "Apollo" -}; - -/*************************************************************************** -* openocd command interface * -***************************************************************************/ - -/* flash_bank ambiqmicro 0 0 - */ -FLASH_BANK_COMMAND_HANDLER(ambiqmicro_flash_bank_command) -{ - struct ambiqmicro_flash_bank *ambiqmicro_info; - - if (CMD_ARGC < 6) - return ERROR_COMMAND_SYNTAX_ERROR; - - ambiqmicro_info = calloc(sizeof(struct ambiqmicro_flash_bank), 1); - - bank->driver_priv = ambiqmicro_info; - - ambiqmicro_info->target_name = "Unknown target"; - - /* part wasn't probed yet */ - ambiqmicro_info->probed = 0; - - return ERROR_OK; -} - -static int get_ambiqmicro_info(struct flash_bank *bank, char *buf, int buf_size) -{ - struct ambiqmicro_flash_bank *ambiqmicro_info = bank->driver_priv; - int printed; - char *classname; - - if (ambiqmicro_info->probed == 0) { - LOG_ERROR("Target not probed"); - return ERROR_FLASH_BANK_NOT_PROBED; - } - - /* Check class name in range. */ - if (ambiqmicro_info->target_class < sizeof(ambiqmicroClassname)) - classname = ambiqmicroClassname[ambiqmicro_info->target_class]; - else - classname = ambiqmicroClassname[0]; - - printed = snprintf(buf, - buf_size, - "\nAmbiq Micro information: Chip is " - "class %d (%s) %s\n", - ambiqmicro_info->target_class, - classname, - ambiqmicro_info->target_name); - - if ((printed < 0)) - return ERROR_BUF_TOO_SMALL; - return ERROR_OK; -} - -/*************************************************************************** -* chip identification and status * -***************************************************************************/ - -/* Fill in driver info structure */ -static int ambiqmicro_read_part_info(struct flash_bank *bank) -{ - struct ambiqmicro_flash_bank *ambiqmicro_info = bank->driver_priv; - struct target *target = bank->target; - uint32_t PartNum = 0; - int retval; - - /* - * Read Part Number. - */ - retval = target_read_u32(target, 0x40020000, &PartNum); - if (retval != ERROR_OK) { - LOG_ERROR("status(0x%x):Could not read PartNum.\n", retval); - /* Set PartNum to default device */ - PartNum = 0; - } - LOG_DEBUG("Part number: 0x%x", PartNum); - - /* - * Determine device class. - */ - ambiqmicro_info->target_class = (PartNum & 0xFF000000) >> 24; - - switch (ambiqmicro_info->target_class) { - case 1: /* 1 - Apollo */ - case 5: /* 5 - Apollo Bootloader */ - bank->base = bank->bank_number * 0x40000; - ambiqmicro_info->pagesize = 2048; - ambiqmicro_info->flshsiz = - apollo_flash_size[(PartNum & 0x00F00000) >> 20]; - ambiqmicro_info->sramsiz = - apollo_sram_size[(PartNum & 0x000F0000) >> 16]; - ambiqmicro_info->num_pages = ambiqmicro_info->flshsiz / - ambiqmicro_info->pagesize; - if (ambiqmicro_info->num_pages > 128) { - ambiqmicro_info->num_pages = 128; - ambiqmicro_info->flshsiz = 1024 * 256; - } - break; - - default: - LOG_INFO("Unknown Class. Using Apollo-64 as default."); - - bank->base = bank->bank_number * 0x40000; - ambiqmicro_info->pagesize = 2048; - ambiqmicro_info->flshsiz = apollo_flash_size[1]; - ambiqmicro_info->sramsiz = apollo_sram_size[0]; - ambiqmicro_info->num_pages = ambiqmicro_info->flshsiz / - ambiqmicro_info->pagesize; - if (ambiqmicro_info->num_pages > 128) { - ambiqmicro_info->num_pages = 128; - ambiqmicro_info->flshsiz = 1024 * 256; - } - break; - - } - - if (ambiqmicro_info->target_class < - (sizeof(ambiqmicroParts)/sizeof(ambiqmicroParts[0]))) - ambiqmicro_info->target_name = - ambiqmicroParts[ambiqmicro_info->target_class].partname; - else - ambiqmicro_info->target_name = - ambiqmicroParts[0].partname; - - LOG_DEBUG("num_pages: %d, pagesize: %d, flash: %d, sram: %d", - ambiqmicro_info->num_pages, - ambiqmicro_info->pagesize, - ambiqmicro_info->flshsiz, - ambiqmicro_info->sramsiz); - - return ERROR_OK; -} - -/*************************************************************************** -* flash operations * -***************************************************************************/ - -static int ambiqmicro_protect_check(struct flash_bank *bank) -{ - struct ambiqmicro_flash_bank *ambiqmicro = bank->driver_priv; - int status = ERROR_OK; - uint32_t i; - - - if (ambiqmicro->probed == 0) { - LOG_ERROR("Target not probed"); - return ERROR_FLASH_BANK_NOT_PROBED; - } - - for (i = 0; i < (unsigned) bank->num_sectors; i++) - bank->sectors[i].is_protected = -1; - - return status; -} -/** Read flash status from bootloader. */ -static int check_flash_status(struct target *target, uint32_t address) -{ - uint32_t retflash; - int rc; - rc = target_read_u32(target, address, &retflash); - /* target connection failed. */ - if (rc != ERROR_OK) { - LOG_DEBUG("%s:%d:%s(): status(0x%x)\n", - __FILE__, __LINE__, __func__, rc); - return rc; - } - /* target flash failed, unknown cause. */ - if (retflash != 0) { - LOG_ERROR("Flash not happy: status(0x%x)", retflash); - return ERROR_FLASH_OPERATION_FAILED; - } - return ERROR_OK; -} - -static int ambiqmicro_exec_command(struct target *target, - uint32_t command, - uint32_t flash_return_address) -{ - int retval, retflash; - - retval = target_resume( - target, - false, - command, - true, - true); - - CHECK_STATUS(retval, "error executing ambiqmicro command"); - - /* - * Wait for halt. - */ - for (;; ) { - target_poll(target); - if (target->state == TARGET_HALTED) - break; - else if (target->state == TARGET_RUNNING || - target->state == TARGET_DEBUG_RUNNING) { - /* - * Keep polling until target halts. - */ - target_poll(target); - alive_sleep(100); - LOG_DEBUG("state = %d", target->state); - } else { - LOG_ERROR("Target not halted or running %d", target->state); - break; - } - } - - /* - * Read return value, flash error takes precedence. - */ - retflash = check_flash_status(target, flash_return_address); - if (retflash != ERROR_OK) - retval = retflash; - - /* Return code from target_resume OR flash. */ - return retval; -} - -static int ambiqmicro_mass_erase(struct flash_bank *bank) -{ - struct target *target = NULL; - struct ambiqmicro_flash_bank *ambiqmicro_info = NULL; - int retval = ERROR_OK; - - ambiqmicro_info = bank->driver_priv; - target = bank->target; - - if (target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - if (ambiqmicro_info->probed == 0) { - LOG_ERROR("Target not probed"); - return ERROR_FLASH_BANK_NOT_PROBED; - } - - /* - * Clear Bootloader bit. - */ - retval = target_write_u32(target, 0x400201a0, 0x0); - CHECK_STATUS(retval, "error clearing bootloader bit."); - - /* - * Set up the SRAM. - */ - - /* - * Bank. - */ - retval = target_write_u32(target, 0x10000000, bank->bank_number); - CHECK_STATUS(retval, "error writing target SRAM parameters."); - - /* - * Write Key. - */ - retval = target_write_u32(target, 0x10000004, PROGRAM_KEY); - CHECK_STATUS(retval, "error writing target SRAM parameters."); - - /* - * Breakpoint. - */ - retval = target_write_u32(target, 0x10000008, 0xfffffffe); - CHECK_STATUS(retval, "error writing target SRAM parameters."); - - /* - * Erase the main array. - */ - LOG_INFO("Mass erase on bank %d.", bank->bank_number); - - /* - * passed pc, addr = ROM function, handle breakpoints, not debugging. - */ - retval = ambiqmicro_exec_command(target, FLASH_MASS_ERASE_MAIN_PAGES_FROM_SRAM, 0x10000008); - CHECK_STATUS(retval, "error executing ambiqmicro flash mass erase."); - if (retval != ERROR_OK) - return retval; - - /* - * Set Bootloader bit, regardless of command execution. - */ - retval = target_write_u32(target, 0x400201a0, 0x1); - CHECK_STATUS(retval, "error setting bootloader bit."); - - return retval; -} - - -static int ambiqmicro_erase(struct flash_bank *bank, int first, int last) -{ - struct ambiqmicro_flash_bank *ambiqmicro_info = bank->driver_priv; - struct target *target = bank->target; - uint32_t retval = ERROR_OK; - - if (bank->target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - if (ambiqmicro_info->probed == 0) { - LOG_ERROR("Target not probed"); - return ERROR_FLASH_BANK_NOT_PROBED; - } - - /* - * Check pages. - * Fix num_pages for the device. - */ - if ((first < 0) || (last < first) || (last >= (int)ambiqmicro_info->num_pages)) - return ERROR_FLASH_SECTOR_INVALID; - - /* - * Just Mass Erase if all pages are given. - * TODO: Fix num_pages for the device - */ - if ((first == 0) && (last == ((int)ambiqmicro_info->num_pages-1))) - return ambiqmicro_mass_erase(bank); - - /* - * Clear Bootloader bit. - */ - retval = target_write_u32(target, 0x400201a0, 0x0); - CHECK_STATUS(retval, "error clearing bootloader bit."); - - /* - * Set up the SRAM. - */ - - /* - * Bank. - */ - retval = target_write_u32(target, 0x10000000, bank->bank_number); - CHECK_STATUS(retval, "error writing target SRAM parameters."); - - /* - * Number of pages to erase. - */ - retval = target_write_u32(target, 0x10000004, 1 + (last-first)); - CHECK_STATUS(retval, "error writing target SRAM parameters."); - - /* - * Write Key. - */ - retval = target_write_u32(target, 0x10000008, PROGRAM_KEY); - CHECK_STATUS(retval, "error writing target SRAM parameters."); - - /* - * Breakpoint. - */ - retval = target_write_u32(target, 0x1000000c, 0xfffffffe); - CHECK_STATUS(retval, "error writing target SRAM parameters."); - - /* - * Pointer to flash address. - */ - retval = target_write_u32(target, 0x10000010, first); - CHECK_STATUS(retval, "error writing target SRAM parameters."); - if (retval != ERROR_OK) - return retval; - - /* - * Erase the pages. - */ - LOG_INFO("Erasing pages %d to %d on bank %d", first, last, bank->bank_number); - - /* - * passed pc, addr = ROM function, handle breakpoints, not debugging. - */ - retval = ambiqmicro_exec_command(target, FLASH_ERASE_LIST_MAIN_PAGES_FROM_SRAM, 0x1000000C); - CHECK_STATUS(retval, "error executing flash page erase"); - if (retval != ERROR_OK) - return retval; - - LOG_INFO("%d pages erased!", 1+(last-first)); - - if (first == 0) { - /* - * Set Bootloader bit. - */ - retval = target_write_u32(target, 0x400201a0, 0x1); - CHECK_STATUS(retval, "error setting bootloader bit."); - if (retval != ERROR_OK) - return retval; - } - - return retval; -} - -static int ambiqmicro_protect(struct flash_bank *bank, int set, int first, int last) -{ - /* struct ambiqmicro_flash_bank *ambiqmicro_info = bank->driver_priv; - * struct target *target = bank->target; */ - - /* - * TODO - */ - LOG_INFO("Not yet implemented"); - - if (bank->target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - return ERROR_OK; -} - -static int ambiqmicro_write_block(struct flash_bank *bank, - const uint8_t *buffer, uint32_t offset, uint32_t count) -{ - /* struct ambiqmicro_flash_bank *ambiqmicro_info = bank->driver_priv; */ - struct target *target = bank->target; - uint32_t address = bank->base + offset; - uint32_t buffer_pointer = 0x10000010; - uint32_t maxbuffer; - uint32_t thisrun_count; - int retval = ERROR_OK; - - if (((count%4) != 0) || ((offset%4) != 0)) { - LOG_ERROR("write block must be multiple of 4 bytes in offset & length"); - return ERROR_FAIL; - } - - /* - * Max buffer size for this device. - * Hard code 6kB for the buffer. - */ - maxbuffer = 0x1800; - - LOG_INFO("Flashing main array"); - - while (count > 0) { - if (count > maxbuffer) - thisrun_count = maxbuffer; - else - thisrun_count = count; - - /* - * Set up the SRAM. - */ - - /* - * Pointer to flash. - */ - retval = target_write_u32(target, 0x10000000, address); - CHECK_STATUS(retval, "error writing target SRAM parameters."); - - /* - * Number of 32-bit words to program. - */ - retval = target_write_u32(target, 0x10000004, thisrun_count/4); - CHECK_STATUS(retval, "error writing target SRAM parameters."); - - /* - * Write Key. - */ - retval = target_write_u32(target, 0x10000008, PROGRAM_KEY); - CHECK_STATUS(retval, "error writing target SRAM parameters."); - - /* - * Breakpoint. - */ - retval = target_write_u32(target, 0x1000000c, 0xfffffffe); - CHECK_STATUS(retval, "error writing target SRAM parameters."); - - /* - * Write Buffer. - */ - retval = target_write_buffer(target, buffer_pointer, thisrun_count, buffer); - - if (retval != ERROR_OK) { - CHECK_STATUS(retval, "error writing target SRAM parameters."); - break; - } - - LOG_DEBUG("address = 0x%08x", address); - - retval = ambiqmicro_exec_command(target, FLASH_PROGRAM_MAIN_FROM_SRAM, 0x1000000c); - CHECK_STATUS(retval, "error executing ambiqmicro flash write algorithm"); - if (retval != ERROR_OK) - break; - buffer += thisrun_count; - address += thisrun_count; - count -= thisrun_count; - } - - - LOG_INFO("Main array flashed"); - - /* - * Clear Bootloader bit. - */ - retval = target_write_u32(target, 0x400201a0, 0x0); - CHECK_STATUS(retval, "error clearing bootloader bit"); - - return retval; -} - -static int ambiqmicro_write(struct flash_bank *bank, const uint8_t *buffer, - uint32_t offset, uint32_t count) -{ - uint32_t retval; - - /* try using a block write */ - retval = ambiqmicro_write_block(bank, buffer, offset, count); - if (retval != ERROR_OK) - LOG_ERROR("write failed"); - - return retval; -} - -static int ambiqmicro_probe(struct flash_bank *bank) -{ - struct ambiqmicro_flash_bank *ambiqmicro_info = bank->driver_priv; - uint32_t retval; - - /* If this is a ambiqmicro chip, it has flash; probe() is just - * to figure out how much is present. Only do it once. - */ - if (ambiqmicro_info->probed == 1) { - LOG_INFO("Target already probed"); - return ERROR_OK; - } - - /* ambiqmicro_read_part_info() already handled error checking and - * reporting. Note that it doesn't write, so we don't care about - * whether the target is halted or not. - */ - retval = ambiqmicro_read_part_info(bank); - if (retval != ERROR_OK) - return retval; - - if (bank->sectors) { - free(bank->sectors); - bank->sectors = NULL; - } - - /* provide this for the benefit of the NOR flash framework */ - bank->size = ambiqmicro_info->pagesize * ambiqmicro_info->num_pages; - bank->num_sectors = ambiqmicro_info->num_pages; - bank->sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors); - for (int i = 0; i < bank->num_sectors; i++) { - bank->sectors[i].offset = i * ambiqmicro_info->pagesize; - bank->sectors[i].size = ambiqmicro_info->pagesize; - bank->sectors[i].is_erased = -1; - bank->sectors[i].is_protected = -1; - } - - /* - * Part has been probed. - */ - ambiqmicro_info->probed = 1; - - return retval; -} - -static int ambiqmicro_otp_program(struct flash_bank *bank, - uint32_t offset, uint32_t count) -{ - struct target *target = NULL; - struct ambiqmicro_flash_bank *ambiqmicro_info = NULL; - uint32_t retval = ERROR_OK; - - ambiqmicro_info = bank->driver_priv; - target = bank->target; - - if (target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - if (ambiqmicro_info->probed == 0) { - LOG_ERROR("Target not probed"); - return ERROR_FLASH_BANK_NOT_PROBED; - } - - if (count > 256) { - LOG_ERROR("Count must be < 256"); - return ERROR_FLASH_DST_BREAKS_ALIGNMENT; - } - - /* - * Clear Bootloader bit. - */ - retval = target_write_u32(target, 0x400201a0, 0x0); - CHECK_STATUS(retval, "error clearing bootloader bit."); - - /* - * Set up the SRAM. - */ - - /* - * Bank. - */ - retval = target_write_u32(target, 0x10000000, offset); - CHECK_STATUS(retval, "error setting target SRAM parameters."); - - /* - * Num of words to program. - */ - retval = target_write_u32(target, 0x10000004, count); - CHECK_STATUS(retval, "error setting target SRAM parameters."); - - /* - * Write Key. - */ - retval = target_write_u32(target, 0x10000008, OTP_PROGRAM_KEY); - CHECK_STATUS(retval, "error setting target SRAM parameters."); - - /* - * Breakpoint. - */ - retval = target_write_u32(target, 0x1000000c, 0xfffffffe); - CHECK_STATUS(retval, "error setting target SRAM parameters."); - if (retval != ERROR_OK) - return retval; - - /* - * Program OTP. - */ - LOG_INFO("Programming OTP offset 0x%08x", offset); - - /* - * passed pc, addr = ROM function, handle breakpoints, not debugging. - */ - retval = ambiqmicro_exec_command(target, FLASH_PROGRAM_OTP_FROM_SRAM, 0x1000000C); - CHECK_STATUS(retval, "error executing ambiqmicro otp program algorithm"); - - LOG_INFO("Programming OTP finished."); - - return retval; -} - - - -COMMAND_HANDLER(ambiqmicro_handle_mass_erase_command) -{ - int i; - - if (CMD_ARGC < 1) - return ERROR_COMMAND_SYNTAX_ERROR; - - struct flash_bank *bank; - uint32_t retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank); - if (ERROR_OK != retval) - return retval; - - if (ambiqmicro_mass_erase(bank) == ERROR_OK) { - /* set all sectors as erased */ - for (i = 0; i < bank->num_sectors; i++) - bank->sectors[i].is_erased = 1; - - command_print(CMD_CTX, "ambiqmicro mass erase complete"); - } else - command_print(CMD_CTX, "ambiqmicro mass erase failed"); - - return ERROR_OK; -} - -COMMAND_HANDLER(ambiqmicro_handle_page_erase_command) -{ - struct flash_bank *bank; - uint32_t first, last; - uint32_t retval; - - if (CMD_ARGC < 3) - return ERROR_COMMAND_SYNTAX_ERROR; - - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], first); - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], last); - - retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank); - if (ERROR_OK != retval) - return retval; - - if (ambiqmicro_erase(bank, first, last) == ERROR_OK) - command_print(CMD_CTX, "ambiqmicro page erase complete"); - else - command_print(CMD_CTX, "ambiqmicro page erase failed"); - - return ERROR_OK; -} - - -/** - * Program the otp block. - */ -COMMAND_HANDLER(ambiqmicro_handle_program_otp_command) -{ - struct flash_bank *bank; - uint32_t offset, count; - uint32_t retval; - - if (CMD_ARGC < 3) - return ERROR_COMMAND_SYNTAX_ERROR; - - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], offset); - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], count); - - command_print(CMD_CTX, "offset=0x%08x count=%d", offset, count); - - CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank); - - retval = ambiqmicro_otp_program(bank, offset, count); - - if (retval != ERROR_OK) - LOG_ERROR("error check log"); - - return ERROR_OK; -} - - - -static const struct command_registration ambiqmicro_exec_command_handlers[] = { - { - .name = "mass_erase", - .usage = "", - .handler = ambiqmicro_handle_mass_erase_command, - .mode = COMMAND_EXEC, - .help = "Erase entire device", - }, - { - .name = "page_erase", - .usage = " ", - .handler = ambiqmicro_handle_page_erase_command, - .mode = COMMAND_EXEC, - .help = "Erase device pages", - }, - { - .name = "program_otp", - .handler = ambiqmicro_handle_program_otp_command, - .mode = COMMAND_EXEC, - .usage = " ", - .help = - "Program OTP (assumes you have already written array starting at 0x10000010)", - }, - COMMAND_REGISTRATION_DONE -}; -static const struct command_registration ambiqmicro_command_handlers[] = { - { - .name = "ambiqmicro", - .mode = COMMAND_EXEC, - .help = "ambiqmicro flash command group", - .usage = "Support for Ambiq Micro parts.", - .chain = ambiqmicro_exec_command_handlers, - }, - COMMAND_REGISTRATION_DONE -}; - -struct flash_driver ambiqmicro_flash = { - .name = "ambiqmicro", - .commands = ambiqmicro_command_handlers, - .flash_bank_command = ambiqmicro_flash_bank_command, - .erase = ambiqmicro_erase, - .protect = ambiqmicro_protect, - .write = ambiqmicro_write, - .read = default_flash_read, - .probe = ambiqmicro_probe, - .auto_probe = ambiqmicro_probe, - .erase_check = default_flash_blank_check, - .protect_check = ambiqmicro_protect_check, - .info = get_ambiqmicro_info, -}; diff --git a/src/flash/nor/at91sam3.c b/src/flash/nor/at91sam3.c deleted file mode 100644 index 1536378df..000000000 --- a/src/flash/nor/at91sam3.c +++ /dev/null @@ -1,3774 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2009 by Duane Ellis * - * openocd@duaneellis.com * - * * - * Copyright (C) 2010 by Olaf Lüke (at91sam3s* support) * - * olaf@uni-paderborn.de * - * * - * Copyright (C) 2011 by Olivier Schonken (at91sam3x* support) * * - * and Jim Norris * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * -****************************************************************************/ - -/* Some of the the lower level code was based on code supplied by - * ATMEL under this copyright. */ - -/* BEGIN ATMEL COPYRIGHT */ -/* ---------------------------------------------------------------------------- - * ATMEL Microcontroller Software Support - * ---------------------------------------------------------------------------- - * Copyright (c) 2009, Atmel Corporation - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * - Redistributions of source code must retain the above copyright notice, - * this list of conditions and the disclaimer below. - * - * Atmel's name may not be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE - * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, - * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * ---------------------------------------------------------------------------- - */ -/* END ATMEL COPYRIGHT */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "imp.h" -#include - -#define REG_NAME_WIDTH (12) - -/* at91sam3u series (has one or two flash banks) */ -#define FLASH_BANK0_BASE_U 0x00080000 -#define FLASH_BANK1_BASE_U 0x00100000 - -/* at91sam3s series (has always one flash bank) */ -#define FLASH_BANK_BASE_S 0x00400000 - -/* at91sam3sd series (has always two flash banks) */ -#define FLASH_BANK0_BASE_SD FLASH_BANK_BASE_S -#define FLASH_BANK1_BASE_512K_SD (FLASH_BANK0_BASE_SD+(512*1024/2)) - - -/* at91sam3n series (has always one flash bank) */ -#define FLASH_BANK_BASE_N 0x00400000 - -/* at91sam3a/x series has two flash banks*/ -#define FLASH_BANK0_BASE_AX 0x00080000 -/*Bank 1 of the at91sam3a/x series starts at 0x00080000 + half flash size*/ -#define FLASH_BANK1_BASE_256K_AX 0x000A0000 -#define FLASH_BANK1_BASE_512K_AX 0x000C0000 - -#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 */ -#define AT91C_EFC_FCMD_EWP (0x3) /* (EFC) Erase Page and Write Page */ -#define AT91C_EFC_FCMD_EWPL (0x4) /* (EFC) Erase Page and Write Page then Lock */ -#define AT91C_EFC_FCMD_EA (0x5) /* (EFC) Erase All */ -/* cmd6 is not present in the at91sam3u4/2/1 data sheet table 17-2 */ -/* #define AT91C_EFC_FCMD_EPL (0x6) // (EFC) Erase plane? */ -/* cmd7 is not present in the at91sam3u4/2/1 data sheet table 17-2 */ -/* #define AT91C_EFC_FCMD_EPA (0x7) // (EFC) Erase pages? */ -#define AT91C_EFC_FCMD_SLB (0x8) /* (EFC) Set Lock Bit */ -#define AT91C_EFC_FCMD_CLB (0x9) /* (EFC) Clear Lock Bit */ -#define AT91C_EFC_FCMD_GLB (0xA) /* (EFC) Get Lock Bit */ -#define AT91C_EFC_FCMD_SFB (0xB) /* (EFC) Set Fuse Bit */ -#define AT91C_EFC_FCMD_CFB (0xC) /* (EFC) Clear Fuse Bit */ -#define AT91C_EFC_FCMD_GFB (0xD) /* (EFC) Get Fuse Bit */ -#define AT91C_EFC_FCMD_STUI (0xE) /* (EFC) Start Read Unique ID */ -#define AT91C_EFC_FCMD_SPUI (0xF) /* (EFC) Stop Read Unique ID */ - -#define offset_EFC_FMR 0 -#define offset_EFC_FCR 4 -#define offset_EFC_FSR 8 -#define offset_EFC_FRR 12 - -extern struct flash_driver at91sam3_flash; - -static float _tomhz(uint32_t freq_hz) -{ - float f; - - f = ((float)(freq_hz)) / 1000000.0; - return f; -} - -/* How the chip is configured. */ -struct sam3_cfg { - uint32_t unique_id[4]; - - uint32_t slow_freq; - uint32_t rc_freq; - uint32_t mainosc_freq; - uint32_t plla_freq; - uint32_t mclk_freq; - uint32_t cpu_freq; - uint32_t fclk_freq; - uint32_t pclk0_freq; - uint32_t pclk1_freq; - uint32_t pclk2_freq; - - -#define SAM3_CHIPID_CIDR (0x400E0740) - uint32_t CHIPID_CIDR; -#define SAM3_CHIPID_CIDR2 (0x400E0940) /*SAM3X and SAM3A cidr at this address*/ - uint32_t CHIPID_CIDR2; -#define SAM3_CHIPID_EXID (0x400E0744) - uint32_t CHIPID_EXID; -#define SAM3_CHIPID_EXID2 (0x400E0944) /*SAM3X and SAM3A cidr at this address*/ - uint32_t CHIPID_EXID2; - - -#define SAM3_PMC_BASE (0x400E0400) -#define SAM3_PMC_SCSR (SAM3_PMC_BASE + 0x0008) - uint32_t PMC_SCSR; -#define SAM3_PMC_PCSR (SAM3_PMC_BASE + 0x0018) - uint32_t PMC_PCSR; -#define SAM3_CKGR_UCKR (SAM3_PMC_BASE + 0x001c) - uint32_t CKGR_UCKR; -#define SAM3_CKGR_MOR (SAM3_PMC_BASE + 0x0020) - uint32_t CKGR_MOR; -#define SAM3_CKGR_MCFR (SAM3_PMC_BASE + 0x0024) - uint32_t CKGR_MCFR; -#define SAM3_CKGR_PLLAR (SAM3_PMC_BASE + 0x0028) - uint32_t CKGR_PLLAR; -#define SAM3_PMC_MCKR (SAM3_PMC_BASE + 0x0030) - uint32_t PMC_MCKR; -#define SAM3_PMC_PCK0 (SAM3_PMC_BASE + 0x0040) - uint32_t PMC_PCK0; -#define SAM3_PMC_PCK1 (SAM3_PMC_BASE + 0x0044) - uint32_t PMC_PCK1; -#define SAM3_PMC_PCK2 (SAM3_PMC_BASE + 0x0048) - uint32_t PMC_PCK2; -#define SAM3_PMC_SR (SAM3_PMC_BASE + 0x0068) - uint32_t PMC_SR; -#define SAM3_PMC_IMR (SAM3_PMC_BASE + 0x006c) - uint32_t PMC_IMR; -#define SAM3_PMC_FSMR (SAM3_PMC_BASE + 0x0070) - uint32_t PMC_FSMR; -#define SAM3_PMC_FSPR (SAM3_PMC_BASE + 0x0074) - uint32_t PMC_FSPR; -}; - -/* - * The AT91SAM3N data sheet 04-Oct-2010, AT91SAM3U data sheet 22-Aug-2011 - * and AT91SAM3S data sheet 09-Feb-2011 state that for flash writes - * the flash wait state (FWS) should be set to 6. It seems like that the - * cause of the problem is not the flash itself, but the flash write - * buffer. Ie the wait states have to be set before writing into the - * buffer. - * Tested and confirmed with SAM3N and SAM3U - */ - -struct sam3_bank_private { - int probed; - /* DANGER: THERE ARE DRAGONS HERE.. */ - /* NOTE: If you add more 'ghost' pointers */ - /* be aware that you must *manually* update */ - /* these pointers in the function sam3_GetDetails() */ - /* See the comment "Here there be dragons" */ - - /* so we can find the chip we belong to */ - struct sam3_chip *pChip; - /* so we can find the original bank pointer */ - struct flash_bank *pBank; - unsigned bank_number; - uint32_t controller_address; - uint32_t base_address; - uint32_t flash_wait_states; - bool present; - unsigned size_bytes; - unsigned nsectors; - unsigned sector_size; - unsigned page_size; -}; - -struct sam3_chip_details { - /* THERE ARE DRAGONS HERE.. */ - /* note: If you add pointers here */ - /* be careful about them as they */ - /* may need to be updated inside */ - /* the function: "sam3_GetDetails() */ - /* which copy/overwrites the */ - /* 'runtime' copy of this structure */ - uint32_t chipid_cidr; - const char *name; - - unsigned n_gpnvms; -#define SAM3_N_NVM_BITS 3 - unsigned gpnvm[SAM3_N_NVM_BITS]; - unsigned total_flash_size; - unsigned total_sram_size; - unsigned n_banks; -#define SAM3_MAX_FLASH_BANKS 2 - /* these are "initialized" from the global const data */ - struct sam3_bank_private bank[SAM3_MAX_FLASH_BANKS]; -}; - -struct sam3_chip { - struct sam3_chip *next; - int probed; - - /* this is "initialized" from the global const structure */ - struct sam3_chip_details details; - struct target *target; - struct sam3_cfg cfg; -}; - - -struct sam3_reg_list { - uint32_t address; size_t struct_offset; const char *name; - void (*explain_func)(struct sam3_chip *pInfo); -}; - -static struct sam3_chip *all_sam3_chips; - -static struct sam3_chip *get_current_sam3(struct command_context *cmd_ctx) -{ - struct target *t; - static struct sam3_chip *p; - - t = get_current_target(cmd_ctx); - if (!t) { - command_print(cmd_ctx, "No current target?"); - return NULL; - } - - p = all_sam3_chips; - if (!p) { - /* this should not happen */ - /* the command is not registered until the chip is created? */ - command_print(cmd_ctx, "No SAM3 chips exist?"); - return NULL; - } - - while (p) { - if (p->target == t) - return p; - p = p->next; - } - command_print(cmd_ctx, "Cannot find SAM3 chip?"); - return NULL; -} - -/* these are used to *initialize* the "pChip->details" structure. */ -static const struct sam3_chip_details all_sam3_details[] = { - /* Start at91sam3u* series */ - { - .chipid_cidr = 0x28100960, - .name = "at91sam3u4e", - .total_flash_size = 256 * 1024, - .total_sram_size = 52 * 1024, - .n_gpnvms = 3, - .n_banks = 2, - - /* System boots at address 0x0 */ - /* gpnvm[1] = selects boot code */ - /* if gpnvm[1] == 0 */ - /* boot is via "SAMBA" (rom) */ - /* else */ - /* boot is via FLASH */ - /* Selection is via gpnvm[2] */ - /* endif */ - /* */ - /* NOTE: banks 0 & 1 switch places */ - /* if gpnvm[2] == 0 */ - /* Bank0 is the boot rom */ - /* else */ - /* Bank1 is the boot rom */ - /* endif */ -/* .bank[0] = { */ - { - { - .probed = 0, - .pChip = NULL, - .pBank = NULL, - .bank_number = 0, - .base_address = FLASH_BANK0_BASE_U, - .controller_address = 0x400e0800, - .flash_wait_states = 6, /* workaround silicon bug */ - .present = 1, - .size_bytes = 128 * 1024, - .nsectors = 16, - .sector_size = 8192, - .page_size = 256, - }, - -/* .bank[1] = { */ - { - .probed = 0, - .pChip = NULL, - .pBank = NULL, - .bank_number = 1, - .base_address = FLASH_BANK1_BASE_U, - .controller_address = 0x400e0a00, - .flash_wait_states = 6, /* workaround silicon bug */ - .present = 1, - .size_bytes = 128 * 1024, - .nsectors = 16, - .sector_size = 8192, - .page_size = 256, - }, - }, - }, - - { - .chipid_cidr = 0x281a0760, - .name = "at91sam3u2e", - .total_flash_size = 128 * 1024, - .total_sram_size = 36 * 1024, - .n_gpnvms = 2, - .n_banks = 1, - - /* System boots at address 0x0 */ - /* gpnvm[1] = selects boot code */ - /* if gpnvm[1] == 0 */ - /* boot is via "SAMBA" (rom) */ - /* else */ - /* boot is via FLASH */ - /* Selection is via gpnvm[2] */ - /* endif */ -/* .bank[0] = { */ - { - { - .probed = 0, - .pChip = NULL, - .pBank = NULL, - .bank_number = 0, - .base_address = FLASH_BANK0_BASE_U, - .controller_address = 0x400e0800, - .flash_wait_states = 6, /* workaround silicon bug */ - .present = 1, - .size_bytes = 128 * 1024, - .nsectors = 16, - .sector_size = 8192, - .page_size = 256, - }, -/* .bank[1] = { */ - { - .present = 0, - .probed = 0, - .bank_number = 1, - }, - }, - }, - { - .chipid_cidr = 0x28190560, - .name = "at91sam3u1e", - .total_flash_size = 64 * 1024, - .total_sram_size = 20 * 1024, - .n_gpnvms = 2, - .n_banks = 1, - - /* System boots at address 0x0 */ - /* gpnvm[1] = selects boot code */ - /* if gpnvm[1] == 0 */ - /* boot is via "SAMBA" (rom) */ - /* else */ - /* boot is via FLASH */ - /* Selection is via gpnvm[2] */ - /* endif */ - /* */ - -/* .bank[0] = { */ - { - { - .probed = 0, - .pChip = NULL, - .pBank = NULL, - .bank_number = 0, - .base_address = FLASH_BANK0_BASE_U, - .controller_address = 0x400e0800, - .flash_wait_states = 6, /* workaround silicon bug */ - .present = 1, - .size_bytes = 64 * 1024, - .nsectors = 8, - .sector_size = 8192, - .page_size = 256, - }, - -/* .bank[1] = { */ - { - .present = 0, - .probed = 0, - .bank_number = 1, - }, - }, - }, - - { - .chipid_cidr = 0x28000960, - .name = "at91sam3u4c", - .total_flash_size = 256 * 1024, - .total_sram_size = 52 * 1024, - .n_gpnvms = 3, - .n_banks = 2, - - /* System boots at address 0x0 */ - /* gpnvm[1] = selects boot code */ - /* if gpnvm[1] == 0 */ - /* boot is via "SAMBA" (rom) */ - /* else */ - /* boot is via FLASH */ - /* Selection is via gpnvm[2] */ - /* endif */ - /* */ - /* NOTE: banks 0 & 1 switch places */ - /* if gpnvm[2] == 0 */ - /* Bank0 is the boot rom */ - /* else */ - /* Bank1 is the boot rom */ - /* endif */ - { - { -/* .bank[0] = { */ - .probed = 0, - .pChip = NULL, - .pBank = NULL, - .bank_number = 0, - .base_address = FLASH_BANK0_BASE_U, - .controller_address = 0x400e0800, - .flash_wait_states = 6, /* workaround silicon bug */ - .present = 1, - .size_bytes = 128 * 1024, - .nsectors = 16, - .sector_size = 8192, - .page_size = 256, - }, -/* .bank[1] = { */ - { - .probed = 0, - .pChip = NULL, - .pBank = NULL, - .bank_number = 1, - .base_address = FLASH_BANK1_BASE_U, - .controller_address = 0x400e0a00, - .flash_wait_states = 6, /* workaround silicon bug */ - .present = 1, - .size_bytes = 128 * 1024, - .nsectors = 16, - .sector_size = 8192, - .page_size = 256, - }, - }, - }, - - { - .chipid_cidr = 0x280a0760, - .name = "at91sam3u2c", - .total_flash_size = 128 * 1024, - .total_sram_size = 36 * 1024, - .n_gpnvms = 2, - .n_banks = 1, - - /* System boots at address 0x0 */ - /* gpnvm[1] = selects boot code */ - /* if gpnvm[1] == 0 */ - /* boot is via "SAMBA" (rom) */ - /* else */ - /* boot is via FLASH */ - /* Selection is via gpnvm[2] */ - /* endif */ - { -/* .bank[0] = { */ - { - .probed = 0, - .pChip = NULL, - .pBank = NULL, - .bank_number = 0, - .base_address = FLASH_BANK0_BASE_U, - .controller_address = 0x400e0800, - .flash_wait_states = 6, /* workaround silicon bug */ - .present = 1, - .size_bytes = 128 * 1024, - .nsectors = 16, - .sector_size = 8192, - .page_size = 256, - }, -/* .bank[1] = { */ - { - .present = 0, - .probed = 0, - .bank_number = 1, - }, - }, - }, - { - .chipid_cidr = 0x28090560, - .name = "at91sam3u1c", - .total_flash_size = 64 * 1024, - .total_sram_size = 20 * 1024, - .n_gpnvms = 2, - .n_banks = 1, - - /* System boots at address 0x0 */ - /* gpnvm[1] = selects boot code */ - /* if gpnvm[1] == 0 */ - /* boot is via "SAMBA" (rom) */ - /* else */ - /* boot is via FLASH */ - /* Selection is via gpnvm[2] */ - /* endif */ - /* */ - - { -/* .bank[0] = { */ - { - .probed = 0, - .pChip = NULL, - .pBank = NULL, - .bank_number = 0, - .base_address = FLASH_BANK0_BASE_U, - .controller_address = 0x400e0800, - .flash_wait_states = 6, /* workaround silicon bug */ - .present = 1, - .size_bytes = 64 * 1024, - .nsectors = 8, - .sector_size = 8192, - .page_size = 256, - }, -/* .bank[1] = { */ - { - .present = 0, - .probed = 0, - .bank_number = 1, - - }, - }, - }, - - /* Start at91sam3s* series */ - - /* Note: The preliminary at91sam3s datasheet says on page 302 */ - /* that the flash controller is at address 0x400E0800. */ - /* This is _not_ the case, the controller resides at address 0x400e0a00. */ - { - .chipid_cidr = 0x28A00960, - .name = "at91sam3s4c", - .total_flash_size = 256 * 1024, - .total_sram_size = 48 * 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 = 6, /* workaround silicon bug */ - .present = 1, - .size_bytes = 256 * 1024, - .nsectors = 16, - .sector_size = 16384, - .page_size = 256, - }, -/* .bank[1] = { */ - { - .present = 0, - .probed = 0, - .bank_number = 1, - - }, - }, - }, - - { - .chipid_cidr = 0x28900960, - .name = "at91sam3s4b", - .total_flash_size = 256 * 1024, - .total_sram_size = 48 * 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 = 6, /* workaround silicon bug */ - .present = 1, - .size_bytes = 256 * 1024, - .nsectors = 16, - .sector_size = 16384, - .page_size = 256, - }, -/* .bank[1] = { */ - { - .present = 0, - .probed = 0, - .bank_number = 1, - - }, - }, - }, - { - .chipid_cidr = 0x28800960, - .name = "at91sam3s4a", - .total_flash_size = 256 * 1024, - .total_sram_size = 48 * 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 = 6, /* workaround silicon bug */ - .present = 1, - .size_bytes = 256 * 1024, - .nsectors = 16, - .sector_size = 16384, - .page_size = 256, - }, -/* .bank[1] = { */ - { - .present = 0, - .probed = 0, - .bank_number = 1, - - }, - }, - }, - { - .chipid_cidr = 0x28AA0760, - .name = "at91sam3s2c", - .total_flash_size = 128 * 1024, - .total_sram_size = 32 * 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 = 6, /* workaround silicon bug */ - .present = 1, - .size_bytes = 128 * 1024, - .nsectors = 8, - .sector_size = 16384, - .page_size = 256, - }, -/* .bank[1] = { */ - { - .present = 0, - .probed = 0, - .bank_number = 1, - - }, - }, - }, - { - .chipid_cidr = 0x289A0760, - .name = "at91sam3s2b", - .total_flash_size = 128 * 1024, - .total_sram_size = 32 * 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 = 6, /* workaround silicon bug */ - .present = 1, - .size_bytes = 128 * 1024, - .nsectors = 8, - .sector_size = 16384, - .page_size = 256, - }, -/* .bank[1] = { */ - { - .present = 0, - .probed = 0, - .bank_number = 1, - - }, - }, - }, - { - .chipid_cidr = 0x298B0A60, - .name = "at91sam3sd8a", - .total_flash_size = 512 * 1024, - .total_sram_size = 64 * 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 */ - .present = 1, - .size_bytes = 256 * 1024, - .nsectors = 16, - .sector_size = 32768, - .page_size = 256, - }, -/* .bank[1] = { */ - { - .probed = 0, - .pChip = NULL, - .pBank = NULL, - .bank_number = 1, - .base_address = FLASH_BANK1_BASE_512K_SD, - .controller_address = 0x400e0a00, - .flash_wait_states = 6, /* workaround silicon bug */ - .present = 1, - .size_bytes = 256 * 1024, - .nsectors = 16, - .sector_size = 32768, - .page_size = 256, - }, - }, - }, - { - .chipid_cidr = 0x299B0A60, - .name = "at91sam3sd8b", - .total_flash_size = 512 * 1024, - .total_sram_size = 64 * 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 */ - .present = 1, - .size_bytes = 256 * 1024, - .nsectors = 16, - .sector_size = 32768, - .page_size = 256, - }, -/* .bank[1] = { */ - { - .probed = 0, - .pChip = NULL, - .pBank = NULL, - .bank_number = 1, - .base_address = FLASH_BANK1_BASE_512K_SD, - .controller_address = 0x400e0a00, - .flash_wait_states = 6, /* workaround silicon bug */ - .present = 1, - .size_bytes = 256 * 1024, - .nsectors = 16, - .sector_size = 32768, - .page_size = 256, - }, - }, - }, - { - .chipid_cidr = 0x29ab0a60, - .name = "at91sam3sd8c", - .total_flash_size = 512 * 1024, - .total_sram_size = 64 * 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 */ - .present = 1, - .size_bytes = 256 * 1024, - .nsectors = 16, - .sector_size = 32768, - .page_size = 256, - }, -/* .bank[1] = { */ - { - .probed = 0, - .pChip = NULL, - .pBank = NULL, - .bank_number = 1, - .base_address = FLASH_BANK1_BASE_512K_SD, - .controller_address = 0x400e0a00, - .flash_wait_states = 6, /* workaround silicon bug */ - .present = 1, - .size_bytes = 256 * 1024, - .nsectors = 16, - .sector_size = 32768, - .page_size = 256, - }, - }, - }, - { - .chipid_cidr = 0x288A0760, - .name = "at91sam3s2a", - .total_flash_size = 128 * 1024, - .total_sram_size = 32 * 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 = 6, /* workaround silicon bug */ - .present = 1, - .size_bytes = 128 * 1024, - .nsectors = 8, - .sector_size = 16384, - .page_size = 256, - }, -/* .bank[1] = { */ - { - .present = 0, - .probed = 0, - .bank_number = 1, - - }, - }, - }, - { - .chipid_cidr = 0x28A90560, - .name = "at91sam3s1c", - .total_flash_size = 64 * 1024, - .total_sram_size = 16 * 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 = 6, /* workaround silicon bug */ - .present = 1, - .size_bytes = 64 * 1024, - .nsectors = 4, - .sector_size = 16384, - .page_size = 256, - }, -/* .bank[1] = { */ - { - .present = 0, - .probed = 0, - .bank_number = 1, - - }, - }, - }, - { - .chipid_cidr = 0x28990560, - .name = "at91sam3s1b", - .total_flash_size = 64 * 1024, - .total_sram_size = 16 * 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 = 6, /* workaround silicon bug */ - .present = 1, - .size_bytes = 64 * 1024, - .nsectors = 4, - .sector_size = 16384, - .page_size = 256, - }, -/* .bank[1] = { */ - { - .present = 0, - .probed = 0, - .bank_number = 1, - - }, - }, - }, - { - .chipid_cidr = 0x28890560, - .name = "at91sam3s1a", - .total_flash_size = 64 * 1024, - .total_sram_size = 16 * 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 = 6, /* workaround silicon bug */ - .present = 1, - .size_bytes = 64 * 1024, - .nsectors = 4, - .sector_size = 16384, - .page_size = 256, - }, -/* .bank[1] = { */ - { - .present = 0, - .probed = 0, - .bank_number = 1, - - }, - }, - }, - { - .chipid_cidr = 0x288B0A60, - .name = "at91sam3s8a", - .total_flash_size = 256 * 2048, - .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 = 6, /* workaround silicon bug */ - .present = 1, - .size_bytes = 256 * 2048, - .nsectors = 16, - .sector_size = 32768, - .page_size = 256, - }, -/* .bank[1] = { */ - { - .present = 0, - .probed = 0, - .bank_number = 1, - - }, - }, - }, - { - .chipid_cidr = 0x289B0A60, - .name = "at91sam3s8b", - .total_flash_size = 256 * 2048, - .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 = 6, /* workaround silicon bug */ - .present = 1, - .size_bytes = 256 * 2048, - .nsectors = 16, - .sector_size = 32768, - .page_size = 256, - }, -/* .bank[1] = { */ - { - .present = 0, - .probed = 0, - .bank_number = 1, - - }, - }, - }, - { - .chipid_cidr = 0x28AB0A60, - .name = "at91sam3s8c", - .total_flash_size = 256 * 2048, - .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 = 6, /* workaround silicon bug */ - .present = 1, - .size_bytes = 256 * 2048, - .nsectors = 16, - .sector_size = 32768, - .page_size = 256, - }, -/* .bank[1] = { */ - { - .present = 0, - .probed = 0, - .bank_number = 1, - - }, - }, - }, - - /* Start at91sam3n* series */ - { - .chipid_cidr = 0x29540960, - .name = "at91sam3n4c", - .total_flash_size = 256 * 1024, - .total_sram_size = 24 * 1024, - .n_gpnvms = 3, - .n_banks = 1, - - /* System boots at address 0x0 */ - /* gpnvm[1] = selects boot code */ - /* if gpnvm[1] == 0 */ - /* boot is via "SAMBA" (rom) */ - /* else */ - /* boot is via FLASH */ - /* Selection is via gpnvm[2] */ - /* endif */ - /* */ - /* NOTE: banks 0 & 1 switch places */ - /* if gpnvm[2] == 0 */ - /* Bank0 is the boot rom */ - /* else */ - /* Bank1 is the boot rom */ - /* endif */ -/* .bank[0] = { */ - { - { - .probed = 0, - .pChip = NULL, - .pBank = NULL, - .bank_number = 0, - .base_address = FLASH_BANK_BASE_N, - .controller_address = 0x400e0A00, - .flash_wait_states = 6, /* workaround silicon bug */ - .present = 1, - .size_bytes = 256 * 1024, - .nsectors = 16, - .sector_size = 16384, - .page_size = 256, - }, - -/* .bank[1] = { */ - { - .present = 0, - .probed = 0, - .bank_number = 1, - }, - }, - }, - - { - .chipid_cidr = 0x29440960, - .name = "at91sam3n4b", - .total_flash_size = 256 * 1024, - .total_sram_size = 24 * 1024, - .n_gpnvms = 3, - .n_banks = 1, - - /* System boots at address 0x0 */ - /* gpnvm[1] = selects boot code */ - /* if gpnvm[1] == 0 */ - /* boot is via "SAMBA" (rom) */ - /* else */ - /* boot is via FLASH */ - /* Selection is via gpnvm[2] */ - /* endif */ - /* */ - /* NOTE: banks 0 & 1 switch places */ - /* if gpnvm[2] == 0 */ - /* Bank0 is the boot rom */ - /* else */ - /* Bank1 is the boot rom */ - /* endif */ -/* .bank[0] = { */ - { - { - .probed = 0, - .pChip = NULL, - .pBank = NULL, - .bank_number = 0, - .base_address = FLASH_BANK_BASE_N, - .controller_address = 0x400e0A00, - .flash_wait_states = 6, /* workaround silicon bug */ - .present = 1, - .size_bytes = 256 * 1024, - .nsectors = 16, - .sector_size = 16384, - .page_size = 256, - }, - -/* .bank[1] = { */ - { - .present = 0, - .probed = 0, - .bank_number = 1, - }, - }, - }, - - { - .chipid_cidr = 0x29340960, - .name = "at91sam3n4a", - .total_flash_size = 256 * 1024, - .total_sram_size = 24 * 1024, - .n_gpnvms = 3, - .n_banks = 1, - - /* System boots at address 0x0 */ - /* gpnvm[1] = selects boot code */ - /* if gpnvm[1] == 0 */ - /* boot is via "SAMBA" (rom) */ - /* else */ - /* boot is via FLASH */ - /* Selection is via gpnvm[2] */ - /* endif */ - /* */ - /* NOTE: banks 0 & 1 switch places */ - /* if gpnvm[2] == 0 */ - /* Bank0 is the boot rom */ - /* else */ - /* Bank1 is the boot rom */ - /* endif */ -/* .bank[0] = { */ - { - { - .probed = 0, - .pChip = NULL, - .pBank = NULL, - .bank_number = 0, - .base_address = FLASH_BANK_BASE_N, - .controller_address = 0x400e0A00, - .flash_wait_states = 6, /* workaround silicon bug */ - .present = 1, - .size_bytes = 256 * 1024, - .nsectors = 16, - .sector_size = 16384, - .page_size = 256, - }, - -/* .bank[1] = { */ - { - .present = 0, - .probed = 0, - .bank_number = 1, - }, - }, - }, - - { - .chipid_cidr = 0x29590760, - .name = "at91sam3n2c", - .total_flash_size = 128 * 1024, - .total_sram_size = 16 * 1024, - .n_gpnvms = 3, - .n_banks = 1, - - /* System boots at address 0x0 */ - /* gpnvm[1] = selects boot code */ - /* if gpnvm[1] == 0 */ - /* boot is via "SAMBA" (rom) */ - /* else */ - /* boot is via FLASH */ - /* Selection is via gpnvm[2] */ - /* endif */ - /* */ - /* NOTE: banks 0 & 1 switch places */ - /* if gpnvm[2] == 0 */ - /* Bank0 is the boot rom */ - /* else */ - /* Bank1 is the boot rom */ - /* endif */ -/* .bank[0] = { */ - { - { - .probed = 0, - .pChip = NULL, - .pBank = NULL, - .bank_number = 0, - .base_address = FLASH_BANK_BASE_N, - .controller_address = 0x400e0A00, - .flash_wait_states = 6, /* workaround silicon bug */ - .present = 1, - .size_bytes = 128 * 1024, - .nsectors = 8, - .sector_size = 16384, - .page_size = 256, - }, - -/* .bank[1] = { */ - { - .present = 0, - .probed = 0, - .bank_number = 1, - }, - }, - }, - - { - .chipid_cidr = 0x29490760, - .name = "at91sam3n2b", - .total_flash_size = 128 * 1024, - .total_sram_size = 16 * 1024, - .n_gpnvms = 3, - .n_banks = 1, - - /* System boots at address 0x0 */ - /* gpnvm[1] = selects boot code */ - /* if gpnvm[1] == 0 */ - /* boot is via "SAMBA" (rom) */ - /* else */ - /* boot is via FLASH */ - /* Selection is via gpnvm[2] */ - /* endif */ - /* */ - /* NOTE: banks 0 & 1 switch places */ - /* if gpnvm[2] == 0 */ - /* Bank0 is the boot rom */ - /* else */ - /* Bank1 is the boot rom */ - /* endif */ -/* .bank[0] = { */ - { - { - .probed = 0, - .pChip = NULL, - .pBank = NULL, - .bank_number = 0, - .base_address = FLASH_BANK_BASE_N, - .controller_address = 0x400e0A00, - .flash_wait_states = 6, /* workaround silicon bug */ - .present = 1, - .size_bytes = 128 * 1024, - .nsectors = 8, - .sector_size = 16384, - .page_size = 256, - }, - -/* .bank[1] = { */ - { - .present = 0, - .probed = 0, - .bank_number = 1, - }, - }, - }, - - { - .chipid_cidr = 0x29390760, - .name = "at91sam3n2a", - .total_flash_size = 128 * 1024, - .total_sram_size = 16 * 1024, - .n_gpnvms = 3, - .n_banks = 1, - - /* System boots at address 0x0 */ - /* gpnvm[1] = selects boot code */ - /* if gpnvm[1] == 0 */ - /* boot is via "SAMBA" (rom) */ - /* else */ - /* boot is via FLASH */ - /* Selection is via gpnvm[2] */ - /* endif */ - /* */ - /* NOTE: banks 0 & 1 switch places */ - /* if gpnvm[2] == 0 */ - /* Bank0 is the boot rom */ - /* else */ - /* Bank1 is the boot rom */ - /* endif */ -/* .bank[0] = { */ - { - { - .probed = 0, - .pChip = NULL, - .pBank = NULL, - .bank_number = 0, - .base_address = FLASH_BANK_BASE_N, - .controller_address = 0x400e0A00, - .flash_wait_states = 6, /* workaround silicon bug */ - .present = 1, - .size_bytes = 128 * 1024, - .nsectors = 8, - .sector_size = 16384, - .page_size = 256, - }, - -/* .bank[1] = { */ - { - .present = 0, - .probed = 0, - .bank_number = 1, - }, - }, - }, - - { - .chipid_cidr = 0x29580560, - .name = "at91sam3n1c", - .total_flash_size = 64 * 1024, - .total_sram_size = 8 * 1024, - .n_gpnvms = 3, - .n_banks = 1, - - /* System boots at address 0x0 */ - /* gpnvm[1] = selects boot code */ - /* if gpnvm[1] == 0 */ - /* boot is via "SAMBA" (rom) */ - /* else */ - /* boot is via FLASH */ - /* Selection is via gpnvm[2] */ - /* endif */ - /* */ - /* NOTE: banks 0 & 1 switch places */ - /* if gpnvm[2] == 0 */ - /* Bank0 is the boot rom */ - /* else */ - /* Bank1 is the boot rom */ - /* endif */ -/* .bank[0] = { */ - { - { - .probed = 0, - .pChip = NULL, - .pBank = NULL, - .bank_number = 0, - .base_address = FLASH_BANK_BASE_N, - .controller_address = 0x400e0A00, - .flash_wait_states = 6, /* workaround silicon bug */ - .present = 1, - .size_bytes = 64 * 1024, - .nsectors = 4, - .sector_size = 16384, - .page_size = 256, - }, - -/* .bank[1] = { */ - { - .present = 0, - .probed = 0, - .bank_number = 1, - }, - }, - }, - - { - .chipid_cidr = 0x29480560, - .name = "at91sam3n1b", - .total_flash_size = 64 * 1024, - .total_sram_size = 8 * 1024, - .n_gpnvms = 3, - .n_banks = 1, - - /* System boots at address 0x0 */ - /* gpnvm[1] = selects boot code */ - /* if gpnvm[1] == 0 */ - /* boot is via "SAMBA" (rom) */ - /* else */ - /* boot is via FLASH */ - /* Selection is via gpnvm[2] */ - /* endif */ - /* */ - /* NOTE: banks 0 & 1 switch places */ - /* if gpnvm[2] == 0 */ - /* Bank0 is the boot rom */ - /* else */ - /* Bank1 is the boot rom */ - /* endif */ -/* .bank[0] = { */ - { - { - .probed = 0, - .pChip = NULL, - .pBank = NULL, - .bank_number = 0, - .base_address = FLASH_BANK_BASE_N, - .controller_address = 0x400e0A00, - .flash_wait_states = 6, /* workaround silicon bug */ - .present = 1, - .size_bytes = 64 * 1024, - .nsectors = 4, - .sector_size = 16384, - .page_size = 256, - }, - -/* .bank[1] = { */ - { - .present = 0, - .probed = 0, - .bank_number = 1, - }, - }, - }, - - { - .chipid_cidr = 0x29380560, - .name = "at91sam3n1a", - .total_flash_size = 64 * 1024, - .total_sram_size = 8 * 1024, - .n_gpnvms = 3, - .n_banks = 1, - - /* System boots at address 0x0 */ - /* gpnvm[1] = selects boot code */ - /* if gpnvm[1] == 0 */ - /* boot is via "SAMBA" (rom) */ - /* else */ - /* boot is via FLASH */ - /* Selection is via gpnvm[2] */ - /* endif */ - /* */ - /* NOTE: banks 0 & 1 switch places */ - /* if gpnvm[2] == 0 */ - /* Bank0 is the boot rom */ - /* else */ - /* Bank1 is the boot rom */ - /* endif */ -/* .bank[0] = { */ - { - { - .probed = 0, - .pChip = NULL, - .pBank = NULL, - .bank_number = 0, - .base_address = FLASH_BANK_BASE_N, - .controller_address = 0x400e0A00, - .flash_wait_states = 6, /* workaround silicon bug */ - .present = 1, - .size_bytes = 64 * 1024, - .nsectors = 4, - .sector_size = 16384, - .page_size = 256, - }, - -/* .bank[1] = { */ - { - .present = 0, - .probed = 0, - .bank_number = 1, - }, - }, - }, - - { - .chipid_cidr = 0x29480360, - .name = "at91sam3n0b", - .total_flash_size = 32 * 1024, - .total_sram_size = 8 * 1024, - .n_gpnvms = 3, - .n_banks = 1, - -/* .bank[0] = { */ - { - { - .probed = 0, - .pChip = NULL, - .pBank = NULL, - .bank_number = 0, - .base_address = FLASH_BANK_BASE_N, - .controller_address = 0x400e0A00, - .flash_wait_states = 6, /* workaround silicon bug */ - .present = 1, - .size_bytes = 32 * 1024, - .nsectors = 2, - .sector_size = 16384, - .page_size = 256, - }, - -/* .bank[1] = { */ - { - .present = 0, - .probed = 0, - .bank_number = 1, - }, - }, - }, - - { - .chipid_cidr = 0x29380360, - .name = "at91sam3n0a", - .total_flash_size = 32 * 1024, - .total_sram_size = 8 * 1024, - .n_gpnvms = 3, - .n_banks = 1, - -/* .bank[0] = { */ - { - { - .probed = 0, - .pChip = NULL, - .pBank = NULL, - .bank_number = 0, - .base_address = FLASH_BANK_BASE_N, - .controller_address = 0x400e0A00, - .flash_wait_states = 6, /* workaround silicon bug */ - .present = 1, - .size_bytes = 32 * 1024, - .nsectors = 2, - .sector_size = 16384, - .page_size = 256, - }, - -/* .bank[1] = { */ - { - .present = 0, - .probed = 0, - .bank_number = 1, - }, - }, - }, - - { - .chipid_cidr = 0x29450260, - .name = "at91sam3n00b", - .total_flash_size = 16 * 1024, - .total_sram_size = 4 * 1024, - .n_gpnvms = 3, - .n_banks = 1, - -/* .bank[0] = { */ - { - { - .probed = 0, - .pChip = NULL, - .pBank = NULL, - .bank_number = 0, - .base_address = FLASH_BANK_BASE_N, - .controller_address = 0x400e0A00, - .flash_wait_states = 6, /* workaround silicon bug */ - .present = 1, - .size_bytes = 16 * 1024, - .nsectors = 1, - .sector_size = 16384, - .page_size = 256, - }, - -/* .bank[1] = { */ - { - .present = 0, - .probed = 0, - .bank_number = 1, - }, - }, - }, - - { - .chipid_cidr = 0x29350260, - .name = "at91sam3n00a", - .total_flash_size = 16 * 1024, - .total_sram_size = 4 * 1024, - .n_gpnvms = 3, - .n_banks = 1, - -/* .bank[0] = { */ - { - { - .probed = 0, - .pChip = NULL, - .pBank = NULL, - .bank_number = 0, - .base_address = FLASH_BANK_BASE_N, - .controller_address = 0x400e0A00, - .flash_wait_states = 6, /* workaround silicon bug */ - .present = 1, - .size_bytes = 16 * 1024, - .nsectors = 1, - .sector_size = 16384, - .page_size = 256, - }, - -/* .bank[1] = { */ - { - .present = 0, - .probed = 0, - .bank_number = 1, - }, - }, - }, - - - /* Start at91sam3a series*/ - /* System boots at address 0x0 */ - /* gpnvm[1] = selects boot code */ - /* if gpnvm[1] == 0 */ - /* boot is via "SAMBA" (rom) */ - /* else */ - /* boot is via FLASH */ - /* Selection is via gpnvm[2] */ - /* endif */ - /* */ - /* NOTE: banks 0 & 1 switch places */ - /* if gpnvm[2] == 0 */ - /* Bank0 is the boot rom */ - /* else */ - /* Bank1 is the boot rom */ - /* endif */ - - { - .chipid_cidr = 0x283E0A60, - .name = "at91sam3a8c", - .total_flash_size = 512 * 1024, - .total_sram_size = 96 * 1024, - .n_gpnvms = 3, - .n_banks = 2, - { -/* .bank[0] = { */ - { - .probed = 0, - .pChip = NULL, - .pBank = NULL, - .bank_number = 0, - .base_address = FLASH_BANK0_BASE_AX, - .controller_address = 0x400e0a00, - .flash_wait_states = 6, /* workaround silicon bug */ - .present = 1, - .size_bytes = 256 * 1024, - .nsectors = 16, - .sector_size = 16384, - .page_size = 256, - }, -/* .bank[1] = { */ - { - .probed = 0, - .pChip = NULL, - .pBank = NULL, - .bank_number = 1, - .base_address = FLASH_BANK1_BASE_512K_AX, - .controller_address = 0x400e0c00, - .flash_wait_states = 6, /* workaround silicon bug */ - .present = 1, - .size_bytes = 256 * 1024, - .nsectors = 16, - .sector_size = 16384, - .page_size = 256, - - }, - }, - }, - { - .chipid_cidr = 0x283B0960, - .name = "at91sam3a4c", - .total_flash_size = 256 * 1024, - .total_sram_size = 64 * 1024, - .n_gpnvms = 3, - .n_banks = 2, - { -/* .bank[0] = { */ - { - .probed = 0, - .pChip = NULL, - .pBank = NULL, - .bank_number = 0, - .base_address = FLASH_BANK0_BASE_AX, - .controller_address = 0x400e0a00, - .flash_wait_states = 6, /* workaround silicon bug */ - .present = 1, - .size_bytes = 128 * 1024, - .nsectors = 8, - .sector_size = 16384, - .page_size = 256, - }, -/* .bank[1] = { */ - { - .probed = 0, - .pChip = NULL, - .pBank = NULL, - .bank_number = 1, - .base_address = FLASH_BANK1_BASE_256K_AX, - .controller_address = 0x400e0c00, - .flash_wait_states = 6, /* workaround silicon bug */ - .present = 1, - .size_bytes = 128 * 1024, - .nsectors = 8, - .sector_size = 16384, - .page_size = 256, - - }, - }, - }, - - /* Start at91sam3x* series */ - /* System boots at address 0x0 */ - /* gpnvm[1] = selects boot code */ - /* if gpnvm[1] == 0 */ - /* boot is via "SAMBA" (rom) */ - /* else */ - /* boot is via FLASH */ - /* Selection is via gpnvm[2] */ - /* endif */ - /* */ - /* NOTE: banks 0 & 1 switch places */ - /* if gpnvm[2] == 0 */ - /* Bank0 is the boot rom */ - /* else */ - /* Bank1 is the boot rom */ - /* endif */ - /*at91sam3x8h - ES has an incorrect CIDR of 0x286E0A20*/ - { - .chipid_cidr = 0x286E0A20, - .name = "at91sam3x8h - ES", - .total_flash_size = 512 * 1024, - .total_sram_size = 96 * 1024, - .n_gpnvms = 3, - .n_banks = 2, - { -/* .bank[0] = { */ - { - .probed = 0, - .pChip = NULL, - .pBank = NULL, - .bank_number = 0, - .base_address = FLASH_BANK0_BASE_AX, - .controller_address = 0x400e0a00, - .flash_wait_states = 6, /* workaround silicon bug */ - .present = 1, - .size_bytes = 256 * 1024, - .nsectors = 16, - .sector_size = 16384, - .page_size = 256, - }, -/* .bank[1] = { */ - { - .probed = 0, - .pChip = NULL, - .pBank = NULL, - .bank_number = 1, - .base_address = FLASH_BANK1_BASE_512K_AX, - .controller_address = 0x400e0c00, - .flash_wait_states = 6, /* workaround silicon bug */ - .present = 1, - .size_bytes = 256 * 1024, - .nsectors = 16, - .sector_size = 16384, - .page_size = 256, - - }, - }, - }, - /*at91sam3x8h - ES2 and up uses the correct CIDR of 0x286E0A60*/ - { - .chipid_cidr = 0x286E0A60, - .name = "at91sam3x8h", - .total_flash_size = 512 * 1024, - .total_sram_size = 96 * 1024, - .n_gpnvms = 3, - .n_banks = 2, - { -/* .bank[0] = { */ - { - .probed = 0, - .pChip = NULL, - .pBank = NULL, - .bank_number = 0, - .base_address = FLASH_BANK0_BASE_AX, - .controller_address = 0x400e0a00, - .flash_wait_states = 6, /* workaround silicon bug */ - .present = 1, - .size_bytes = 256 * 1024, - .nsectors = 16, - .sector_size = 16384, - .page_size = 256, - }, -/* .bank[1] = { */ - { - .probed = 0, - .pChip = NULL, - .pBank = NULL, - .bank_number = 1, - .base_address = FLASH_BANK1_BASE_512K_AX, - .controller_address = 0x400e0c00, - .flash_wait_states = 6, /* workaround silicon bug */ - .present = 1, - .size_bytes = 256 * 1024, - .nsectors = 16, - .sector_size = 16384, - .page_size = 256, - - }, - }, - }, - { - .chipid_cidr = 0x285E0A60, - .name = "at91sam3x8e", - .total_flash_size = 512 * 1024, - .total_sram_size = 96 * 1024, - .n_gpnvms = 3, - .n_banks = 2, - { -/* .bank[0] = { */ - { - .probed = 0, - .pChip = NULL, - .pBank = NULL, - .bank_number = 0, - .base_address = FLASH_BANK0_BASE_AX, - .controller_address = 0x400e0a00, - .flash_wait_states = 6, /* workaround silicon bug */ - .present = 1, - .size_bytes = 256 * 1024, - .nsectors = 16, - .sector_size = 16384, - .page_size = 256, - }, -/* .bank[1] = { */ - { - .probed = 0, - .pChip = NULL, - .pBank = NULL, - .bank_number = 1, - .base_address = FLASH_BANK1_BASE_512K_AX, - .controller_address = 0x400e0c00, - .flash_wait_states = 6, /* workaround silicon bug */ - .present = 1, - .size_bytes = 256 * 1024, - .nsectors = 16, - .sector_size = 16384, - .page_size = 256, - - }, - }, - }, - { - .chipid_cidr = 0x284E0A60, - .name = "at91sam3x8c", - .total_flash_size = 512 * 1024, - .total_sram_size = 96 * 1024, - .n_gpnvms = 3, - .n_banks = 2, - { -/* .bank[0] = { */ - { - .probed = 0, - .pChip = NULL, - .pBank = NULL, - .bank_number = 0, - .base_address = FLASH_BANK0_BASE_AX, - .controller_address = 0x400e0a00, - .flash_wait_states = 6, /* workaround silicon bug */ - .present = 1, - .size_bytes = 256 * 1024, - .nsectors = 16, - .sector_size = 16384, - .page_size = 256, - }, -/* .bank[1] = { */ - { - .probed = 0, - .pChip = NULL, - .pBank = NULL, - .bank_number = 1, - .base_address = FLASH_BANK1_BASE_512K_AX , - .controller_address = 0x400e0c00, - .flash_wait_states = 6, /* workaround silicon bug */ - .present = 1, - .size_bytes = 256 * 1024, - .nsectors = 16, - .sector_size = 16384, - .page_size = 256, - - }, - }, - }, - { - .chipid_cidr = 0x285B0960, - .name = "at91sam3x4e", - .total_flash_size = 256 * 1024, - .total_sram_size = 64 * 1024, - .n_gpnvms = 3, - .n_banks = 2, - { -/* .bank[0] = { */ - { - .probed = 0, - .pChip = NULL, - .pBank = NULL, - .bank_number = 0, - .base_address = FLASH_BANK0_BASE_AX, - .controller_address = 0x400e0a00, - .flash_wait_states = 6, /* workaround silicon bug */ - .present = 1, - .size_bytes = 128 * 1024, - .nsectors = 8, - .sector_size = 16384, - .page_size = 256, - }, -/* .bank[1] = { */ - { - .probed = 0, - .pChip = NULL, - .pBank = NULL, - .bank_number = 1, - .base_address = FLASH_BANK1_BASE_256K_AX, - .controller_address = 0x400e0c00, - .flash_wait_states = 6, /* workaround silicon bug */ - .present = 1, - .size_bytes = 128 * 1024, - .nsectors = 8, - .sector_size = 16384, - .page_size = 256, - - }, - }, - }, - { - .chipid_cidr = 0x284B0960, - .name = "at91sam3x4c", - .total_flash_size = 256 * 1024, - .total_sram_size = 64 * 1024, - .n_gpnvms = 3, - .n_banks = 2, - { -/* .bank[0] = { */ - { - .probed = 0, - .pChip = NULL, - .pBank = NULL, - .bank_number = 0, - .base_address = FLASH_BANK0_BASE_AX, - .controller_address = 0x400e0a00, - .flash_wait_states = 6, /* workaround silicon bug */ - .present = 1, - .size_bytes = 128 * 1024, - .nsectors = 8, - .sector_size = 16384, - .page_size = 256, - }, -/* .bank[1] = { */ - { - .probed = 0, - .pChip = NULL, - .pBank = NULL, - .bank_number = 1, - .base_address = FLASH_BANK1_BASE_256K_AX, - .controller_address = 0x400e0c00, - .flash_wait_states = 6, /* workaround silicon bug */ - .present = 1, - .size_bytes = 128 * 1024, - .nsectors = 8, - .sector_size = 16384, - .page_size = 256, - - }, - }, - }, - /* terminate */ - { - .chipid_cidr = 0, - .name = NULL, - } -}; - -/* Globals above */ -/*********************************************************************** - ********************************************************************** - ********************************************************************** - ********************************************************************** - ********************************************************************** - **********************************************************************/ -/* *ATMEL* style code - from the SAM3 driver code */ - -/** - * Get the current status of the EEFC and - * the value of some status bits (LOCKE, PROGE). - * @param pPrivate - info about the bank - * @param v - result goes here - */ -static int EFC_GetStatus(struct sam3_bank_private *pPrivate, uint32_t *v) -{ - int r; - r = target_read_u32(pPrivate->pChip->target, - pPrivate->controller_address + offset_EFC_FSR, - v); - LOG_DEBUG("Status: 0x%08x (lockerror: %d, cmderror: %d, ready: %d)", - (unsigned int)(*v), - ((unsigned int)((*v >> 2) & 1)), - ((unsigned int)((*v >> 1) & 1)), - ((unsigned int)((*v >> 0) & 1))); - - return r; -} - -/** - * Get the result of the last executed command. - * @param pPrivate - info about the bank - * @param v - result goes here - */ -static int EFC_GetResult(struct sam3_bank_private *pPrivate, uint32_t *v) -{ - int r; - uint32_t rv; - r = target_read_u32(pPrivate->pChip->target, - pPrivate->controller_address + offset_EFC_FRR, - &rv); - if (v) - *v = rv; - LOG_DEBUG("Result: 0x%08x", ((unsigned int)(rv))); - return r; -} - -static int EFC_StartCommand(struct sam3_bank_private *pPrivate, - unsigned command, unsigned argument) -{ - uint32_t n, v; - int r; - int retry; - - retry = 0; -do_retry: - - /* Check command & argument */ - switch (command) { - - case AT91C_EFC_FCMD_WP: - case AT91C_EFC_FCMD_WPL: - case AT91C_EFC_FCMD_EWP: - case AT91C_EFC_FCMD_EWPL: - /* case AT91C_EFC_FCMD_EPL: */ - /* case AT91C_EFC_FCMD_EPA: */ - case AT91C_EFC_FCMD_SLB: - case AT91C_EFC_FCMD_CLB: - n = (pPrivate->size_bytes / pPrivate->page_size); - if (argument >= n) - LOG_ERROR("*BUG*: Embedded flash has only %u pages", (unsigned)(n)); - break; - - case AT91C_EFC_FCMD_SFB: - case AT91C_EFC_FCMD_CFB: - if (argument >= pPrivate->pChip->details.n_gpnvms) { - LOG_ERROR("*BUG*: Embedded flash has only %d GPNVMs", - pPrivate->pChip->details.n_gpnvms); - } - break; - - case AT91C_EFC_FCMD_GETD: - case AT91C_EFC_FCMD_EA: - case AT91C_EFC_FCMD_GLB: - case AT91C_EFC_FCMD_GFB: - case AT91C_EFC_FCMD_STUI: - case AT91C_EFC_FCMD_SPUI: - if (argument != 0) - LOG_ERROR("Argument is meaningless for cmd: %d", command); - break; - default: - LOG_ERROR("Unknown command %d", command); - break; - } - - if (command == AT91C_EFC_FCMD_SPUI) { - /* this is a very special situation. */ - /* Situation (1) - error/retry - see below */ - /* And we are being called recursively */ - /* Situation (2) - normal, finished reading unique id */ - } else { - /* it should be "ready" */ - EFC_GetStatus(pPrivate, &v); - if (v & 1) { - /* then it is ready */ - /* we go on */ - } else { - if (retry) { - /* we have done this before */ - /* the controller is not responding. */ - LOG_ERROR("flash controller(%d) is not ready! Error", - pPrivate->bank_number); - return ERROR_FAIL; - } else { - retry++; - LOG_ERROR("Flash controller(%d) is not ready, attempting reset", - pPrivate->bank_number); - /* we do that by issuing the *STOP* command */ - EFC_StartCommand(pPrivate, AT91C_EFC_FCMD_SPUI, 0); - /* above is recursive, and further recursion is blocked by */ - /* if (command == AT91C_EFC_FCMD_SPUI) above */ - goto do_retry; - } - } - } - - v = (0x5A << 24) | (argument << 8) | command; - LOG_DEBUG("Command: 0x%08x", ((unsigned int)(v))); - r = target_write_u32(pPrivate->pBank->target, - pPrivate->controller_address + offset_EFC_FCR, v); - if (r != ERROR_OK) - LOG_DEBUG("Error Write failed"); - return r; -} - -/** - * Performs the given command and wait until its completion (or an error). - * @param pPrivate - info about the bank - * @param command - Command to perform. - * @param argument - Optional command argument. - * @param status - put command status bits here - */ -static int EFC_PerformCommand(struct sam3_bank_private *pPrivate, - unsigned command, - unsigned argument, - uint32_t *status) -{ - - int r; - uint32_t v; - int64_t ms_now, ms_end; - - /* default */ - if (status) - *status = 0; - - r = EFC_StartCommand(pPrivate, command, argument); - if (r != ERROR_OK) - return r; - - ms_end = 500 + timeval_ms(); - - do { - r = EFC_GetStatus(pPrivate, &v); - if (r != ERROR_OK) - return r; - ms_now = timeval_ms(); - if (ms_now > ms_end) { - /* error */ - LOG_ERROR("Command timeout"); - return ERROR_FAIL; - } - } while ((v & 1) == 0); - - /* error bits.. */ - if (status) - *status = (v & 0x6); - return ERROR_OK; - -} - -/** - * Read the unique ID. - * @param pPrivate - info about the bank - * The unique ID is stored in the 'pPrivate' structure. - */ -static int FLASHD_ReadUniqueID(struct sam3_bank_private *pPrivate) -{ - int r; - uint32_t v; - int x; - /* assume 0 */ - pPrivate->pChip->cfg.unique_id[0] = 0; - pPrivate->pChip->cfg.unique_id[1] = 0; - pPrivate->pChip->cfg.unique_id[2] = 0; - pPrivate->pChip->cfg.unique_id[3] = 0; - - LOG_DEBUG("Begin"); - r = EFC_StartCommand(pPrivate, AT91C_EFC_FCMD_STUI, 0); - if (r < 0) - return r; - - for (x = 0; x < 4; x++) { - r = target_read_u32(pPrivate->pChip->target, - pPrivate->pBank->base + (x * 4), - &v); - if (r < 0) - return r; - pPrivate->pChip->cfg.unique_id[x] = v; - } - - r = EFC_PerformCommand(pPrivate, AT91C_EFC_FCMD_SPUI, 0, NULL); - LOG_DEBUG("End: R=%d, id = 0x%08x, 0x%08x, 0x%08x, 0x%08x", - r, - (unsigned int)(pPrivate->pChip->cfg.unique_id[0]), - (unsigned int)(pPrivate->pChip->cfg.unique_id[1]), - (unsigned int)(pPrivate->pChip->cfg.unique_id[2]), - (unsigned int)(pPrivate->pChip->cfg.unique_id[3])); - return r; - -} - -/** - * Erases the entire flash. - * @param pPrivate - the info about the bank. - */ -static int FLASHD_EraseEntireBank(struct sam3_bank_private *pPrivate) -{ - LOG_DEBUG("Here"); - return EFC_PerformCommand(pPrivate, AT91C_EFC_FCMD_EA, 0, NULL); -} - -/** - * Gets current GPNVM state. - * @param pPrivate - info about the bank. - * @param gpnvm - GPNVM bit index. - * @param puthere - result stored here. - */ -/* ------------------------------------------------------------------------------ */ -static int FLASHD_GetGPNVM(struct sam3_bank_private *pPrivate, unsigned gpnvm, unsigned *puthere) -{ - uint32_t v; - int r; - - LOG_DEBUG("Here"); - if (pPrivate->bank_number != 0) { - LOG_ERROR("GPNVM only works with Bank0"); - return ERROR_FAIL; - } - - if (gpnvm >= pPrivate->pChip->details.n_gpnvms) { - LOG_ERROR("Invalid GPNVM %d, max: %d, ignored", - gpnvm, pPrivate->pChip->details.n_gpnvms); - return ERROR_FAIL; - } - - /* Get GPNVMs status */ - r = EFC_PerformCommand(pPrivate, AT91C_EFC_FCMD_GFB, 0, NULL); - if (r != ERROR_OK) { - LOG_ERROR("Failed"); - return r; - } - - r = EFC_GetResult(pPrivate, &v); - - if (puthere) { - /* Check if GPNVM is set */ - /* get the bit and make it a 0/1 */ - *puthere = (v >> gpnvm) & 1; - } - - return r; -} - -/** - * Clears the selected GPNVM bit. - * @param pPrivate info about the bank - * @param gpnvm GPNVM index. - * @returns 0 if successful; otherwise returns an error code. - */ -static int FLASHD_ClrGPNVM(struct sam3_bank_private *pPrivate, unsigned gpnvm) -{ - int r; - unsigned v; - - LOG_DEBUG("Here"); - if (pPrivate->bank_number != 0) { - LOG_ERROR("GPNVM only works with Bank0"); - return ERROR_FAIL; - } - - if (gpnvm >= pPrivate->pChip->details.n_gpnvms) { - LOG_ERROR("Invalid GPNVM %d, max: %d, ignored", - gpnvm, pPrivate->pChip->details.n_gpnvms); - return ERROR_FAIL; - } - - r = FLASHD_GetGPNVM(pPrivate, gpnvm, &v); - if (r != ERROR_OK) { - LOG_DEBUG("Failed: %d", r); - return r; - } - r = EFC_PerformCommand(pPrivate, AT91C_EFC_FCMD_CFB, gpnvm, NULL); - LOG_DEBUG("End: %d", r); - return r; -} - -/** - * Sets the selected GPNVM bit. - * @param pPrivate info about the bank - * @param gpnvm GPNVM index. - */ -static int FLASHD_SetGPNVM(struct sam3_bank_private *pPrivate, unsigned gpnvm) -{ - int r; - unsigned v; - - if (pPrivate->bank_number != 0) { - LOG_ERROR("GPNVM only works with Bank0"); - return ERROR_FAIL; - } - - if (gpnvm >= pPrivate->pChip->details.n_gpnvms) { - LOG_ERROR("Invalid GPNVM %d, max: %d, ignored", - gpnvm, pPrivate->pChip->details.n_gpnvms); - return ERROR_FAIL; - } - - r = FLASHD_GetGPNVM(pPrivate, gpnvm, &v); - if (r != ERROR_OK) - return r; - if (v) { - /* already set */ - r = ERROR_OK; - } else { - /* set it */ - r = EFC_PerformCommand(pPrivate, AT91C_EFC_FCMD_SFB, gpnvm, NULL); - } - return r; -} - -/** - * Returns a bit field (at most 64) of locked regions within a page. - * @param pPrivate info about the bank - * @param v where to store locked bits - */ -static int FLASHD_GetLockBits(struct sam3_bank_private *pPrivate, uint32_t *v) -{ - int r; - LOG_DEBUG("Here"); - r = EFC_PerformCommand(pPrivate, AT91C_EFC_FCMD_GLB, 0, NULL); - if (r == ERROR_OK) - r = EFC_GetResult(pPrivate, v); - LOG_DEBUG("End: %d", r); - return r; -} - -/** - * Unlocks all the regions in the given address range. - * @param pPrivate info about the bank - * @param start_sector first sector to unlock - * @param end_sector last (inclusive) to unlock - */ - -static int FLASHD_Unlock(struct sam3_bank_private *pPrivate, - unsigned start_sector, - unsigned end_sector) -{ - int r; - uint32_t status; - uint32_t pg; - uint32_t pages_per_sector; - - pages_per_sector = pPrivate->sector_size / pPrivate->page_size; - - /* Unlock all pages */ - while (start_sector <= end_sector) { - pg = start_sector * pages_per_sector; - - r = EFC_PerformCommand(pPrivate, AT91C_EFC_FCMD_CLB, pg, &status); - if (r != ERROR_OK) - return r; - start_sector++; - } - - return ERROR_OK; -} - -/** - * Locks regions - * @param pPrivate - info about the bank - * @param start_sector - first sector to lock - * @param end_sector - last sector (inclusive) to lock - */ -static int FLASHD_Lock(struct sam3_bank_private *pPrivate, - unsigned start_sector, - unsigned end_sector) -{ - uint32_t status; - uint32_t pg; - uint32_t pages_per_sector; - int r; - - pages_per_sector = pPrivate->sector_size / pPrivate->page_size; - - /* Lock all pages */ - while (start_sector <= end_sector) { - pg = start_sector * pages_per_sector; - - r = EFC_PerformCommand(pPrivate, AT91C_EFC_FCMD_SLB, pg, &status); - if (r != ERROR_OK) - return r; - start_sector++; - } - return ERROR_OK; -} - -/****** END SAM3 CODE ********/ - -/* begin helpful debug code */ -/* print the fieldname, the field value, in dec & hex, and return field value */ -static uint32_t sam3_reg_fieldname(struct sam3_chip *pChip, - const char *regname, - uint32_t value, - unsigned shift, - unsigned width) -{ - uint32_t v; - int hwidth, dwidth; - - - /* extract the field */ - v = value >> shift; - v = v & ((1 << width)-1); - if (width <= 16) { - hwidth = 4; - dwidth = 5; - } else { - hwidth = 8; - dwidth = 12; - } - - /* show the basics */ - LOG_USER_N("\t%*s: %*" PRIu32 " [0x%0*" PRIx32 "] ", - REG_NAME_WIDTH, regname, - dwidth, v, - hwidth, v); - return v; -} - -static const char _unknown[] = "unknown"; -static const char *const eproc_names[] = { - _unknown, /* 0 */ - "arm946es", /* 1 */ - "arm7tdmi", /* 2 */ - "Cortex-M3", /* 3 */ - "arm920t", /* 4 */ - "arm926ejs", /* 5 */ - _unknown, /* 6 */ - _unknown, /* 7 */ - _unknown, /* 8 */ - _unknown, /* 9 */ - _unknown, /* 10 */ - _unknown, /* 11 */ - _unknown, /* 12 */ - _unknown, /* 13 */ - _unknown, /* 14 */ - _unknown, /* 15 */ -}; - -#define nvpsize2 nvpsize /* these two tables are identical */ -static const char *const nvpsize[] = { - "none", /* 0 */ - "8K bytes", /* 1 */ - "16K bytes", /* 2 */ - "32K bytes", /* 3 */ - _unknown, /* 4 */ - "64K bytes", /* 5 */ - _unknown, /* 6 */ - "128K bytes", /* 7 */ - _unknown, /* 8 */ - "256K bytes", /* 9 */ - "512K bytes", /* 10 */ - _unknown, /* 11 */ - "1024K bytes", /* 12 */ - _unknown, /* 13 */ - "2048K bytes", /* 14 */ - _unknown, /* 15 */ -}; - -static const char *const sramsize[] = { - "48K Bytes", /* 0 */ - "1K Bytes", /* 1 */ - "2K Bytes", /* 2 */ - "6K Bytes", /* 3 */ - "112K Bytes", /* 4 */ - "4K Bytes", /* 5 */ - "80K Bytes", /* 6 */ - "160K Bytes", /* 7 */ - "8K Bytes", /* 8 */ - "16K Bytes", /* 9 */ - "32K Bytes", /* 10 */ - "64K Bytes", /* 11 */ - "128K Bytes", /* 12 */ - "256K Bytes", /* 13 */ - "96K Bytes", /* 14 */ - "512K Bytes", /* 15 */ - -}; - -static const struct archnames { unsigned value; const char *name; } archnames[] = { - { 0x19, "AT91SAM9xx Series" }, - { 0x29, "AT91SAM9XExx Series" }, - { 0x34, "AT91x34 Series" }, - { 0x37, "CAP7 Series" }, - { 0x39, "CAP9 Series" }, - { 0x3B, "CAP11 Series" }, - { 0x40, "AT91x40 Series" }, - { 0x42, "AT91x42 Series" }, - { 0x55, "AT91x55 Series" }, - { 0x60, "AT91SAM7Axx Series" }, - { 0x61, "AT91SAM7AQxx Series" }, - { 0x63, "AT91x63 Series" }, - { 0x70, "AT91SAM7Sxx Series" }, - { 0x71, "AT91SAM7XCxx Series" }, - { 0x72, "AT91SAM7SExx Series" }, - { 0x73, "AT91SAM7Lxx Series" }, - { 0x75, "AT91SAM7Xxx Series" }, - { 0x76, "AT91SAM7SLxx Series" }, - { 0x80, "ATSAM3UxC Series (100-pin version)" }, - { 0x81, "ATSAM3UxE Series (144-pin version)" }, - { 0x83, "ATSAM3AxC Series (100-pin version)" }, - { 0x84, "ATSAM3XxC Series (100-pin version)" }, - { 0x85, "ATSAM3XxE Series (144-pin version)" }, - { 0x86, "ATSAM3XxG Series (208/217-pin version)" }, - { 0x88, "ATSAM3SxA Series (48-pin version)" }, - { 0x89, "ATSAM3SxB Series (64-pin version)" }, - { 0x8A, "ATSAM3SxC Series (100-pin version)" }, - { 0x92, "AT91x92 Series" }, - { 0x93, "ATSAM3NxA Series (48-pin version)" }, - { 0x94, "ATSAM3NxB Series (64-pin version)" }, - { 0x95, "ATSAM3NxC Series (100-pin version)" }, - { 0x98, "ATSAM3SDxA Series (48-pin version)" }, - { 0x99, "ATSAM3SDxB Series (64-pin version)" }, - { 0x9A, "ATSAM3SDxC Series (100-pin version)" }, - { 0xA5, "ATSAM5A" }, - { 0xF0, "AT75Cxx Series" }, - { -1, NULL }, -}; - -static const char *const nvptype[] = { - "rom", /* 0 */ - "romless or onchip flash", /* 1 */ - "embedded flash memory",/* 2 */ - "rom(nvpsiz) + embedded flash (nvpsiz2)", /* 3 */ - "sram emulating flash", /* 4 */ - _unknown, /* 5 */ - _unknown, /* 6 */ - _unknown, /* 7 */ -}; - -static const char *_yes_or_no(uint32_t v) -{ - if (v) - return "YES"; - else - return "NO"; -} - -static const char *const _rc_freq[] = { - "4 MHz", "8 MHz", "12 MHz", "reserved" -}; - -static void sam3_explain_ckgr_mor(struct sam3_chip *pChip) -{ - uint32_t v; - uint32_t rcen; - - v = sam3_reg_fieldname(pChip, "MOSCXTEN", pChip->cfg.CKGR_MOR, 0, 1); - LOG_USER("(main xtal enabled: %s)", _yes_or_no(v)); - v = sam3_reg_fieldname(pChip, "MOSCXTBY", pChip->cfg.CKGR_MOR, 1, 1); - LOG_USER("(main osc bypass: %s)", _yes_or_no(v)); - rcen = sam3_reg_fieldname(pChip, "MOSCRCEN", pChip->cfg.CKGR_MOR, 3, 1); - LOG_USER("(onchip RC-OSC enabled: %s)", _yes_or_no(rcen)); - v = sam3_reg_fieldname(pChip, "MOSCRCF", pChip->cfg.CKGR_MOR, 4, 3); - LOG_USER("(onchip RC-OSC freq: %s)", _rc_freq[v]); - - pChip->cfg.rc_freq = 0; - if (rcen) { - switch (v) { - default: - pChip->cfg.rc_freq = 0; - break; - case 0: - pChip->cfg.rc_freq = 4 * 1000 * 1000; - break; - case 1: - pChip->cfg.rc_freq = 8 * 1000 * 1000; - break; - case 2: - pChip->cfg.rc_freq = 12 * 1000 * 1000; - break; - } - } - - v = sam3_reg_fieldname(pChip, "MOSCXTST", pChip->cfg.CKGR_MOR, 8, 8); - LOG_USER("(startup clks, time= %f uSecs)", - ((float)(v * 1000000)) / ((float)(pChip->cfg.slow_freq))); - v = sam3_reg_fieldname(pChip, "MOSCSEL", pChip->cfg.CKGR_MOR, 24, 1); - LOG_USER("(mainosc source: %s)", - v ? "external xtal" : "internal RC"); - - v = sam3_reg_fieldname(pChip, "CFDEN", pChip->cfg.CKGR_MOR, 25, 1); - LOG_USER("(clock failure enabled: %s)", - _yes_or_no(v)); -} - -static void sam3_explain_chipid_cidr(struct sam3_chip *pChip) -{ - int x; - uint32_t v; - const char *cp; - - sam3_reg_fieldname(pChip, "Version", pChip->cfg.CHIPID_CIDR, 0, 5); - LOG_USER_N("\n"); - - v = sam3_reg_fieldname(pChip, "EPROC", pChip->cfg.CHIPID_CIDR, 5, 3); - LOG_USER("%s", eproc_names[v]); - - v = sam3_reg_fieldname(pChip, "NVPSIZE", pChip->cfg.CHIPID_CIDR, 8, 4); - LOG_USER("%s", nvpsize[v]); - - v = sam3_reg_fieldname(pChip, "NVPSIZE2", pChip->cfg.CHIPID_CIDR, 12, 4); - LOG_USER("%s", nvpsize2[v]); - - v = sam3_reg_fieldname(pChip, "SRAMSIZE", pChip->cfg.CHIPID_CIDR, 16, 4); - LOG_USER("%s", sramsize[v]); - - v = sam3_reg_fieldname(pChip, "ARCH", pChip->cfg.CHIPID_CIDR, 20, 8); - cp = _unknown; - for (x = 0; archnames[x].name; x++) { - if (v == archnames[x].value) { - cp = archnames[x].name; - break; - } - } - - LOG_USER("%s", cp); - - v = sam3_reg_fieldname(pChip, "NVPTYP", pChip->cfg.CHIPID_CIDR, 28, 3); - LOG_USER("%s", nvptype[v]); - - v = sam3_reg_fieldname(pChip, "EXTID", pChip->cfg.CHIPID_CIDR, 31, 1); - LOG_USER("(exists: %s)", _yes_or_no(v)); -} - -static void sam3_explain_ckgr_mcfr(struct sam3_chip *pChip) -{ - uint32_t v; - - v = sam3_reg_fieldname(pChip, "MAINFRDY", pChip->cfg.CKGR_MCFR, 16, 1); - LOG_USER("(main ready: %s)", _yes_or_no(v)); - - v = sam3_reg_fieldname(pChip, "MAINF", pChip->cfg.CKGR_MCFR, 0, 16); - - v = (v * pChip->cfg.slow_freq) / 16; - pChip->cfg.mainosc_freq = v; - - LOG_USER("(%3.03f Mhz (%" PRIu32 ".%03" PRIu32 "khz slowclk)", - _tomhz(v), - (uint32_t)(pChip->cfg.slow_freq / 1000), - (uint32_t)(pChip->cfg.slow_freq % 1000)); -} - -static void sam3_explain_ckgr_plla(struct sam3_chip *pChip) -{ - uint32_t mula, diva; - - diva = sam3_reg_fieldname(pChip, "DIVA", pChip->cfg.CKGR_PLLAR, 0, 8); - LOG_USER_N("\n"); - mula = sam3_reg_fieldname(pChip, "MULA", pChip->cfg.CKGR_PLLAR, 16, 11); - LOG_USER_N("\n"); - pChip->cfg.plla_freq = 0; - if (mula == 0) - LOG_USER("\tPLLA Freq: (Disabled,mula = 0)"); - else if (diva == 0) - LOG_USER("\tPLLA Freq: (Disabled,diva = 0)"); - else if (diva >= 1) { - pChip->cfg.plla_freq = (pChip->cfg.mainosc_freq * (mula + 1) / diva); - LOG_USER("\tPLLA Freq: %3.03f MHz", - _tomhz(pChip->cfg.plla_freq)); - } -} - -static void sam3_explain_mckr(struct sam3_chip *pChip) -{ - uint32_t css, pres, fin = 0; - int pdiv = 0; - const char *cp = NULL; - - css = sam3_reg_fieldname(pChip, "CSS", pChip->cfg.PMC_MCKR, 0, 2); - switch (css & 3) { - case 0: - fin = pChip->cfg.slow_freq; - cp = "slowclk"; - break; - case 1: - fin = pChip->cfg.mainosc_freq; - cp = "mainosc"; - break; - case 2: - fin = pChip->cfg.plla_freq; - cp = "plla"; - break; - case 3: - if (pChip->cfg.CKGR_UCKR & (1 << 16)) { - fin = 480 * 1000 * 1000; - cp = "upll"; - } else { - fin = 0; - cp = "upll (*ERROR* UPLL is disabled)"; - } - break; - default: - assert(0); - break; - } - - LOG_USER("%s (%3.03f Mhz)", - cp, - _tomhz(fin)); - pres = sam3_reg_fieldname(pChip, "PRES", pChip->cfg.PMC_MCKR, 4, 3); - switch (pres & 0x07) { - case 0: - pdiv = 1; - cp = "selected clock"; - break; - case 1: - pdiv = 2; - cp = "clock/2"; - break; - case 2: - pdiv = 4; - cp = "clock/4"; - break; - case 3: - pdiv = 8; - cp = "clock/8"; - break; - case 4: - pdiv = 16; - cp = "clock/16"; - break; - case 5: - pdiv = 32; - cp = "clock/32"; - break; - case 6: - pdiv = 64; - cp = "clock/64"; - break; - case 7: - pdiv = 6; - cp = "clock/6"; - break; - default: - assert(0); - break; - } - LOG_USER("(%s)", cp); - fin = fin / pdiv; - /* sam3 has a *SINGLE* clock - */ - /* other at91 series parts have divisors for these. */ - pChip->cfg.cpu_freq = fin; - pChip->cfg.mclk_freq = fin; - pChip->cfg.fclk_freq = fin; - LOG_USER("\t\tResult CPU Freq: %3.03f", - _tomhz(fin)); -} - -#if 0 -static struct sam3_chip *target2sam3(struct target *pTarget) -{ - struct sam3_chip *pChip; - - if (pTarget == NULL) - return NULL; - - pChip = all_sam3_chips; - while (pChip) { - if (pChip->target == pTarget) - break; /* return below */ - else - pChip = pChip->next; - } - return pChip; -} -#endif - -static uint32_t *sam3_get_reg_ptr(struct sam3_cfg *pCfg, const struct sam3_reg_list *pList) -{ - /* this function exists to help */ - /* keep funky offsetof() errors */ - /* and casting from causing bugs */ - - /* By using prototypes - we can detect what would */ - /* be casting errors. */ - - return (uint32_t *)(void *)(((char *)(pCfg)) + pList->struct_offset); -} - - -#define SAM3_ENTRY(NAME, FUNC) { .address = SAM3_ ## NAME, .struct_offset = offsetof( \ - struct sam3_cfg, \ - NAME), # NAME, FUNC } -static const struct sam3_reg_list sam3_all_regs[] = { - SAM3_ENTRY(CKGR_MOR, sam3_explain_ckgr_mor), - SAM3_ENTRY(CKGR_MCFR, sam3_explain_ckgr_mcfr), - SAM3_ENTRY(CKGR_PLLAR, sam3_explain_ckgr_plla), - SAM3_ENTRY(CKGR_UCKR, NULL), - SAM3_ENTRY(PMC_FSMR, NULL), - SAM3_ENTRY(PMC_FSPR, NULL), - SAM3_ENTRY(PMC_IMR, NULL), - SAM3_ENTRY(PMC_MCKR, sam3_explain_mckr), - SAM3_ENTRY(PMC_PCK0, NULL), - SAM3_ENTRY(PMC_PCK1, NULL), - SAM3_ENTRY(PMC_PCK2, NULL), - SAM3_ENTRY(PMC_PCSR, NULL), - SAM3_ENTRY(PMC_SCSR, NULL), - SAM3_ENTRY(PMC_SR, NULL), - SAM3_ENTRY(CHIPID_CIDR, sam3_explain_chipid_cidr), - SAM3_ENTRY(CHIPID_CIDR2, sam3_explain_chipid_cidr), - SAM3_ENTRY(CHIPID_EXID, NULL), - SAM3_ENTRY(CHIPID_EXID2, NULL), - /* TERMINATE THE LIST */ - { .name = NULL } -}; -#undef SAM3_ENTRY - -static struct sam3_bank_private *get_sam3_bank_private(struct flash_bank *bank) -{ - return bank->driver_priv; -} - -/** - * Given a pointer to where it goes in the structure, - * determine the register name, address from the all registers table. - */ -static const struct sam3_reg_list *sam3_GetReg(struct sam3_chip *pChip, uint32_t *goes_here) -{ - const struct sam3_reg_list *pReg; - - pReg = &(sam3_all_regs[0]); - while (pReg->name) { - uint32_t *pPossible; - - /* calculate where this one go.. */ - /* it is "possibly" this register. */ - - pPossible = ((uint32_t *)(void *)(((char *)(&(pChip->cfg))) + pReg->struct_offset)); - - /* well? Is it this register */ - if (pPossible == goes_here) { - /* Jump for joy! */ - return pReg; - } - - /* next... */ - pReg++; - } - /* This is *TOTAL*PANIC* - we are totally screwed. */ - LOG_ERROR("INVALID SAM3 REGISTER"); - return NULL; -} - -static int sam3_ReadThisReg(struct sam3_chip *pChip, uint32_t *goes_here) -{ - const struct sam3_reg_list *pReg; - int r; - - pReg = sam3_GetReg(pChip, goes_here); - if (!pReg) - return ERROR_FAIL; - - r = target_read_u32(pChip->target, pReg->address, goes_here); - if (r != ERROR_OK) { - LOG_ERROR("Cannot read SAM3 register: %s @ 0x%08x, Err: %d", - pReg->name, (unsigned)(pReg->address), r); - } - return r; -} - -static int sam3_ReadAllRegs(struct sam3_chip *pChip) -{ - int r; - const struct sam3_reg_list *pReg; - - pReg = &(sam3_all_regs[0]); - while (pReg->name) { - r = sam3_ReadThisReg(pChip, - sam3_get_reg_ptr(&(pChip->cfg), pReg)); - if (r != ERROR_OK) { - LOG_ERROR("Cannot read SAM3 register: %s @ 0x%08x, Error: %d", - pReg->name, ((unsigned)(pReg->address)), r); - return r; - } - pReg++; - } - - /* Chip identification register - * - * Unfortunately, the chip identification register is not at - * a constant address across all of the SAM3 series'. As a - * consequence, a simple heuristic is used to find where it's - * at... - * - * If the contents at the first address is zero, then we know - * that the second address is where the chip id register is. - * We can deduce this because for those SAM's that have the - * chip id @ 0x400e0940, the first address, 0x400e0740, is - * located in the memory map of the Power Management Controller - * (PMC). Furthermore, the address is not used by the PMC. - * So when read, the memory controller returns zero.*/ - if (pChip->cfg.CHIPID_CIDR == 0) { - /*Put the correct CIDR and EXID values in the pChip structure */ - pChip->cfg.CHIPID_CIDR = pChip->cfg.CHIPID_CIDR2; - pChip->cfg.CHIPID_EXID = pChip->cfg.CHIPID_EXID2; - } - return ERROR_OK; -} - -static int sam3_GetInfo(struct sam3_chip *pChip) -{ - const struct sam3_reg_list *pReg; - uint32_t regval; - - pReg = &(sam3_all_regs[0]); - while (pReg->name) { - /* display all regs */ - LOG_DEBUG("Start: %s", pReg->name); - regval = *sam3_get_reg_ptr(&(pChip->cfg), pReg); - LOG_USER("%*s: [0x%08" PRIx32 "] -> 0x%08" PRIx32, - REG_NAME_WIDTH, - pReg->name, - pReg->address, - regval); - if (pReg->explain_func) - (*(pReg->explain_func))(pChip); - LOG_DEBUG("End: %s", pReg->name); - pReg++; - } - LOG_USER(" rc-osc: %3.03f MHz", _tomhz(pChip->cfg.rc_freq)); - LOG_USER(" mainosc: %3.03f MHz", _tomhz(pChip->cfg.mainosc_freq)); - LOG_USER(" plla: %3.03f MHz", _tomhz(pChip->cfg.plla_freq)); - LOG_USER(" cpu-freq: %3.03f MHz", _tomhz(pChip->cfg.cpu_freq)); - LOG_USER("mclk-freq: %3.03f MHz", _tomhz(pChip->cfg.mclk_freq)); - - LOG_USER(" UniqueId: 0x%08" PRIx32 " 0x%08" PRIx32 " 0x%08" PRIx32 " 0x%08" PRIx32, - pChip->cfg.unique_id[0], - pChip->cfg.unique_id[1], - pChip->cfg.unique_id[2], - pChip->cfg.unique_id[3]); - - return ERROR_OK; -} - -static int sam3_erase_check(struct flash_bank *bank) -{ - int x; - - LOG_DEBUG("Here"); - if (bank->target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - if (0 == bank->num_sectors) { - LOG_ERROR("Target: not supported/not probed"); - return ERROR_FAIL; - } - - LOG_INFO("sam3 - supports auto-erase, erase_check ignored"); - for (x = 0; x < bank->num_sectors; x++) - bank->sectors[x].is_erased = 1; - - LOG_DEBUG("Done"); - return ERROR_OK; -} - -static int sam3_protect_check(struct flash_bank *bank) -{ - int r; - uint32_t v = 0; - unsigned x; - struct sam3_bank_private *pPrivate; - - LOG_DEBUG("Begin"); - if (bank->target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - pPrivate = get_sam3_bank_private(bank); - if (!pPrivate) { - LOG_ERROR("no private for this bank?"); - return ERROR_FAIL; - } - if (!(pPrivate->probed)) - return ERROR_FLASH_BANK_NOT_PROBED; - - r = FLASHD_GetLockBits(pPrivate, &v); - if (r != ERROR_OK) { - LOG_DEBUG("Failed: %d", r); - return r; - } - - for (x = 0; x < pPrivate->nsectors; x++) - bank->sectors[x].is_protected = (!!(v & (1 << x))); - LOG_DEBUG("Done"); - return ERROR_OK; -} - -FLASH_BANK_COMMAND_HANDLER(sam3_flash_bank_command) -{ - struct sam3_chip *pChip; - - pChip = all_sam3_chips; - - /* is this an existing chip? */ - while (pChip) { - if (pChip->target == bank->target) - break; - pChip = pChip->next; - } - - if (!pChip) { - /* this is a *NEW* chip */ - pChip = calloc(1, sizeof(struct sam3_chip)); - if (!pChip) { - LOG_ERROR("NO RAM!"); - return ERROR_FAIL; - } - pChip->target = bank->target; - /* insert at head */ - pChip->next = all_sam3_chips; - all_sam3_chips = pChip; - pChip->target = bank->target; - /* assumption is this runs at 32khz */ - pChip->cfg.slow_freq = 32768; - pChip->probed = 0; - } - - switch (bank->base) { - default: - LOG_ERROR("Address 0x%08x invalid bank address (try 0x%08x or 0x%08x " - "[at91sam3u series] or 0x%08x [at91sam3s series] or " - "0x%08x [at91sam3n series] or 0x%08x or 0x%08x or 0x%08x[at91sam3ax series] )", - ((unsigned int)(bank->base)), - ((unsigned int)(FLASH_BANK0_BASE_U)), - ((unsigned int)(FLASH_BANK1_BASE_U)), - ((unsigned int)(FLASH_BANK_BASE_S)), - ((unsigned int)(FLASH_BANK_BASE_N)), - ((unsigned int)(FLASH_BANK0_BASE_AX)), - ((unsigned int)(FLASH_BANK1_BASE_256K_AX)), - ((unsigned int)(FLASH_BANK1_BASE_512K_AX))); - return ERROR_FAIL; - break; - - /* at91sam3s and at91sam3n series only has bank 0*/ - /* at91sam3u and at91sam3ax series has the same address for bank 0*/ - case FLASH_BANK_BASE_S: - case FLASH_BANK0_BASE_U: - 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 at91sam3u or at91sam3ax series */ - case FLASH_BANK1_BASE_U: - case FLASH_BANK1_BASE_256K_AX: - case FLASH_BANK1_BASE_512K_AX: - bank->driver_priv = &(pChip->details.bank[1]); - bank->bank_number = 1; - pChip->details.bank[1].pChip = pChip; - pChip->details.bank[1].pBank = bank; - break; - } - - /* we initialize after probing. */ - return ERROR_OK; -} - -static int sam3_GetDetails(struct sam3_bank_private *pPrivate) -{ - const struct sam3_chip_details *pDetails; - struct sam3_chip *pChip; - struct flash_bank *saved_banks[SAM3_MAX_FLASH_BANKS]; - unsigned x; - - LOG_DEBUG("Begin"); - pDetails = all_sam3_details; - while (pDetails->name) { - /* Compare cidr without version bits */ - if (((pDetails->chipid_cidr ^ pPrivate->pChip->cfg.CHIPID_CIDR) & 0xFFFFFFE0) == 0) - break; - else - pDetails++; - } - if (pDetails->name == NULL) { - LOG_ERROR("SAM3 ChipID 0x%08x not found in table (perhaps you can ID this chip?)", - (unsigned int)(pPrivate->pChip->cfg.CHIPID_CIDR)); - /* Help the victim, print details about the chip */ - LOG_INFO("SAM3 CHIPID_CIDR: 0x%08" PRIx32 " decodes as follows", - pPrivate->pChip->cfg.CHIPID_CIDR); - sam3_explain_chipid_cidr(pPrivate->pChip); - return ERROR_FAIL; - } - - /* DANGER: THERE ARE DRAGONS HERE */ - - /* get our pChip - it is going */ - /* to be over-written shortly */ - pChip = pPrivate->pChip; - - /* Note that, in reality: */ - /* */ - /* pPrivate = &(pChip->details.bank[0]) */ - /* or pPrivate = &(pChip->details.bank[1]) */ - /* */ - - /* save the "bank" pointers */ - for (x = 0; x < SAM3_MAX_FLASH_BANKS; x++) - saved_banks[x] = pChip->details.bank[x].pBank; - - /* Overwrite the "details" structure. */ - memcpy(&(pPrivate->pChip->details), - pDetails, - sizeof(pPrivate->pChip->details)); - - /* now fix the ghosted pointers */ - for (x = 0; x < SAM3_MAX_FLASH_BANKS; x++) { - pChip->details.bank[x].pChip = pChip; - pChip->details.bank[x].pBank = saved_banks[x]; - } - - /* update the *BANK*SIZE* */ - - LOG_DEBUG("End"); - return ERROR_OK; -} - -static int _sam3_probe(struct flash_bank *bank, int noise) -{ - unsigned x; - int r; - struct sam3_bank_private *pPrivate; - - - LOG_DEBUG("Begin: Bank: %d, Noise: %d", bank->bank_number, noise); - if (bank->target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - pPrivate = get_sam3_bank_private(bank); - if (!pPrivate) { - LOG_ERROR("Invalid/unknown bank number"); - return ERROR_FAIL; - } - - r = sam3_ReadAllRegs(pPrivate->pChip); - if (r != ERROR_OK) - return r; - - LOG_DEBUG("Here"); - if (pPrivate->pChip->probed) - r = sam3_GetInfo(pPrivate->pChip); - else - r = sam3_GetDetails(pPrivate); - if (r != ERROR_OK) - return r; - - /* update the flash bank size */ - for (x = 0; x < SAM3_MAX_FLASH_BANKS; x++) { - if (bank->base == pPrivate->pChip->details.bank[x].base_address) { - bank->size = pPrivate->pChip->details.bank[x].size_bytes; - break; - } - } - - if (bank->sectors == NULL) { - bank->sectors = calloc(pPrivate->nsectors, (sizeof((bank->sectors)[0]))); - if (bank->sectors == NULL) { - LOG_ERROR("No memory!"); - return ERROR_FAIL; - } - bank->num_sectors = pPrivate->nsectors; - - for (x = 0; ((int)(x)) < bank->num_sectors; x++) { - bank->sectors[x].size = pPrivate->sector_size; - bank->sectors[x].offset = x * (pPrivate->sector_size); - /* mark as unknown */ - bank->sectors[x].is_erased = -1; - bank->sectors[x].is_protected = -1; - } - } - - pPrivate->probed = 1; - - r = sam3_protect_check(bank); - if (r != ERROR_OK) - return r; - - LOG_DEBUG("Bank = %d, nbanks = %d", - pPrivate->bank_number, pPrivate->pChip->details.n_banks); - if ((pPrivate->bank_number + 1) == pPrivate->pChip->details.n_banks) { - /* read unique id, */ - /* it appears to be associated with the *last* flash bank. */ - FLASHD_ReadUniqueID(pPrivate); - } - - return r; -} - -static int sam3_probe(struct flash_bank *bank) -{ - return _sam3_probe(bank, 1); -} - -static int sam3_auto_probe(struct flash_bank *bank) -{ - return _sam3_probe(bank, 0); -} - -static int sam3_erase(struct flash_bank *bank, int first, int last) -{ - struct sam3_bank_private *pPrivate; - int r; - - LOG_DEBUG("Here"); - if (bank->target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - r = sam3_auto_probe(bank); - if (r != ERROR_OK) { - LOG_DEBUG("Here,r=%d", r); - return r; - } - - pPrivate = get_sam3_bank_private(bank); - if (!(pPrivate->probed)) - return ERROR_FLASH_BANK_NOT_PROBED; - - if ((first == 0) && ((last + 1) == ((int)(pPrivate->nsectors)))) { - /* whole chip */ - LOG_DEBUG("Here"); - return FLASHD_EraseEntireBank(pPrivate); - } - LOG_INFO("sam3 auto-erases while programming (request ignored)"); - return ERROR_OK; -} - -static int sam3_protect(struct flash_bank *bank, int set, int first, int last) -{ - struct sam3_bank_private *pPrivate; - int r; - - LOG_DEBUG("Here"); - if (bank->target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - pPrivate = get_sam3_bank_private(bank); - if (!(pPrivate->probed)) - return ERROR_FLASH_BANK_NOT_PROBED; - - if (set) - r = FLASHD_Lock(pPrivate, (unsigned)(first), (unsigned)(last)); - else - r = FLASHD_Unlock(pPrivate, (unsigned)(first), (unsigned)(last)); - LOG_DEBUG("End: r=%d", r); - - return r; - -} - -static int sam3_page_read(struct sam3_bank_private *pPrivate, unsigned pagenum, uint8_t *buf) -{ - uint32_t adr; - int r; - - adr = pagenum * pPrivate->page_size; - adr += pPrivate->base_address; - - r = target_read_memory(pPrivate->pChip->target, - adr, - 4, /* THIS*MUST*BE* in 32bit values */ - pPrivate->page_size / 4, - buf); - if (r != ERROR_OK) - LOG_ERROR("SAM3: Flash program failed to read page phys address: 0x%08x", - (unsigned int)(adr)); - return r; -} - -static int sam3_page_write(struct sam3_bank_private *pPrivate, unsigned pagenum, const uint8_t *buf) -{ - uint32_t adr; - uint32_t status; - uint32_t fmr; /* EEFC Flash Mode Register */ - int r; - - adr = pagenum * pPrivate->page_size; - adr += pPrivate->base_address; - - /* Get flash mode register value */ - r = target_read_u32(pPrivate->pChip->target, pPrivate->controller_address, &fmr); - if (r != ERROR_OK) - LOG_DEBUG("Error Read failed: read flash mode register"); - - /* Clear flash wait state field */ - fmr &= 0xfffff0ff; - - /* set FWS (flash wait states) field in the FMR (flash mode register) */ - fmr |= (pPrivate->flash_wait_states << 8); - - LOG_DEBUG("Flash Mode: 0x%08x", ((unsigned int)(fmr))); - r = target_write_u32(pPrivate->pBank->target, pPrivate->controller_address, fmr); - if (r != ERROR_OK) - LOG_DEBUG("Error Write failed: set flash mode register"); - - LOG_DEBUG("Wr Page %u @ phys address: 0x%08x", pagenum, (unsigned int)(adr)); - r = target_write_memory(pPrivate->pChip->target, - adr, - 4, /* THIS*MUST*BE* in 32bit values */ - pPrivate->page_size / 4, - buf); - if (r != ERROR_OK) { - LOG_ERROR("SAM3: Failed to write (buffer) page at phys address 0x%08x", - (unsigned int)(adr)); - return r; - } - - r = EFC_PerformCommand(pPrivate, - /* send Erase & Write Page */ - AT91C_EFC_FCMD_EWP, - pagenum, - &status); - - if (r != ERROR_OK) - LOG_ERROR("SAM3: Error performing Erase & Write page @ phys address 0x%08x", - (unsigned int)(adr)); - if (status & (1 << 2)) { - LOG_ERROR("SAM3: Page @ Phys address 0x%08x is locked", (unsigned int)(adr)); - return ERROR_FAIL; - } - if (status & (1 << 1)) { - LOG_ERROR("SAM3: Flash Command error @phys address 0x%08x", (unsigned int)(adr)); - return ERROR_FAIL; - } - return ERROR_OK; -} - -static int sam3_write(struct flash_bank *bank, - const uint8_t *buffer, - uint32_t offset, - uint32_t count) -{ - int n; - unsigned page_cur; - unsigned page_end; - int r; - unsigned page_offset; - struct sam3_bank_private *pPrivate; - uint8_t *pagebuffer; - - /* incase we bail further below, set this to null */ - pagebuffer = NULL; - - /* ignore dumb requests */ - if (count == 0) { - r = ERROR_OK; - goto done; - } - - if (bank->target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - r = ERROR_TARGET_NOT_HALTED; - goto done; - } - - pPrivate = get_sam3_bank_private(bank); - if (!(pPrivate->probed)) { - r = ERROR_FLASH_BANK_NOT_PROBED; - goto done; - } - - if ((offset + count) > pPrivate->size_bytes) { - LOG_ERROR("Flash write error - past end of bank"); - LOG_ERROR(" offset: 0x%08x, count 0x%08x, BankEnd: 0x%08x", - (unsigned int)(offset), - (unsigned int)(count), - (unsigned int)(pPrivate->size_bytes)); - r = ERROR_FAIL; - goto done; - } - - pagebuffer = malloc(pPrivate->page_size); - if (!pagebuffer) { - LOG_ERROR("No memory for %d Byte page buffer", (int)(pPrivate->page_size)); - r = ERROR_FAIL; - goto done; - } - - /* what page do we start & end in? */ - page_cur = offset / pPrivate->page_size; - page_end = (offset + count - 1) / pPrivate->page_size; - - LOG_DEBUG("Offset: 0x%08x, Count: 0x%08x", (unsigned int)(offset), (unsigned int)(count)); - LOG_DEBUG("Page start: %d, Page End: %d", (int)(page_cur), (int)(page_end)); - - /* Special case: all one page */ - /* */ - /* Otherwise: */ - /* (1) non-aligned start */ - /* (2) body pages */ - /* (3) non-aligned end. */ - - /* Handle special case - all one page. */ - if (page_cur == page_end) { - LOG_DEBUG("Special case, all in one page"); - r = sam3_page_read(pPrivate, page_cur, pagebuffer); - if (r != ERROR_OK) - goto done; - - page_offset = (offset & (pPrivate->page_size-1)); - memcpy(pagebuffer + page_offset, - buffer, - count); - - r = sam3_page_write(pPrivate, page_cur, pagebuffer); - if (r != ERROR_OK) - goto done; - r = ERROR_OK; - goto done; - } - - /* non-aligned start */ - page_offset = offset & (pPrivate->page_size - 1); - if (page_offset) { - LOG_DEBUG("Not-Aligned start"); - /* read the partial */ - r = sam3_page_read(pPrivate, page_cur, pagebuffer); - if (r != ERROR_OK) - goto done; - - /* over-write with new data */ - n = (pPrivate->page_size - page_offset); - memcpy(pagebuffer + page_offset, - buffer, - n); - - r = sam3_page_write(pPrivate, page_cur, pagebuffer); - if (r != ERROR_OK) - goto done; - - count -= n; - offset += n; - buffer += n; - page_cur++; - } - - /* By checking that offset is correct here, we also - fix a clang warning */ - assert(offset % pPrivate->page_size == 0); - - /* intermediate large pages */ - /* also - the final *terminal* */ - /* if that terminal page is a full page */ - LOG_DEBUG("Full Page Loop: cur=%d, end=%d, count = 0x%08x", - (int)page_cur, (int)page_end, (unsigned int)(count)); - - while ((page_cur < page_end) && - (count >= pPrivate->page_size)) { - r = sam3_page_write(pPrivate, page_cur, buffer); - if (r != ERROR_OK) - goto done; - count -= pPrivate->page_size; - buffer += pPrivate->page_size; - page_cur += 1; - } - - /* terminal partial page? */ - if (count) { - LOG_DEBUG("Terminal partial page, count = 0x%08x", (unsigned int)(count)); - /* we have a partial page */ - r = sam3_page_read(pPrivate, page_cur, pagebuffer); - if (r != ERROR_OK) - goto done; - /* data goes at start */ - memcpy(pagebuffer, buffer, count); - r = sam3_page_write(pPrivate, page_cur, pagebuffer); - if (r != ERROR_OK) - goto done; - } - LOG_DEBUG("Done!"); - r = ERROR_OK; -done: - if (pagebuffer) - free(pagebuffer); - return r; -} - -COMMAND_HANDLER(sam3_handle_info_command) -{ - struct sam3_chip *pChip; - pChip = get_current_sam3(CMD_CTX); - if (!pChip) - return ERROR_OK; - - unsigned x; - int r; - - /* bank0 must exist before we can do anything */ - if (pChip->details.bank[0].pBank == NULL) { - x = 0; -need_define: - command_print(CMD_CTX, - "Please define bank %d via command: flash bank %s ... ", - x, - at91sam3_flash.name); - return ERROR_FAIL; - } - - /* if bank 0 is not probed, then probe it */ - if (!(pChip->details.bank[0].probed)) { - r = sam3_auto_probe(pChip->details.bank[0].pBank); - if (r != ERROR_OK) - return ERROR_FAIL; - } - /* above guarantees the "chip details" structure is valid */ - /* and thus, bank private areas are valid */ - /* and we have a SAM3 chip, what a concept! */ - - /* auto-probe other banks, 0 done above */ - for (x = 1; x < SAM3_MAX_FLASH_BANKS; x++) { - /* skip banks not present */ - if (!(pChip->details.bank[x].present)) - continue; - - if (pChip->details.bank[x].pBank == NULL) - goto need_define; - - if (pChip->details.bank[x].probed) - continue; - - r = sam3_auto_probe(pChip->details.bank[x].pBank); - if (r != ERROR_OK) - return r; - } - - r = sam3_GetInfo(pChip); - if (r != ERROR_OK) { - LOG_DEBUG("Sam3Info, Failed %d", r); - return r; - } - - return ERROR_OK; -} - -COMMAND_HANDLER(sam3_handle_gpnvm_command) -{ - unsigned x, v; - int r, who; - struct sam3_chip *pChip; - - pChip = get_current_sam3(CMD_CTX); - if (!pChip) - return ERROR_OK; - - if (pChip->target->state != TARGET_HALTED) { - LOG_ERROR("sam3 - target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - if (pChip->details.bank[0].pBank == NULL) { - command_print(CMD_CTX, "Bank0 must be defined first via: flash bank %s ...", - at91sam3_flash.name); - return ERROR_FAIL; - } - if (!pChip->details.bank[0].probed) { - r = sam3_auto_probe(pChip->details.bank[0].pBank); - if (r != ERROR_OK) - return r; - } - - switch (CMD_ARGC) { - default: - return ERROR_COMMAND_SYNTAX_ERROR; - break; - case 0: - goto showall; - break; - case 1: - who = -1; - break; - case 2: - if ((0 == strcmp(CMD_ARGV[0], "show")) && (0 == strcmp(CMD_ARGV[1], "all"))) - who = -1; - else { - uint32_t v32; - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], v32); - who = v32; - } - break; - } - - if (0 == strcmp("show", CMD_ARGV[0])) { - if (who == -1) { -showall: - r = ERROR_OK; - for (x = 0; x < pChip->details.n_gpnvms; x++) { - r = FLASHD_GetGPNVM(&(pChip->details.bank[0]), x, &v); - if (r != ERROR_OK) - break; - command_print(CMD_CTX, "sam3-gpnvm%u: %u", x, v); - } - return r; - } - if ((who >= 0) && (((unsigned)(who)) < pChip->details.n_gpnvms)) { - r = FLASHD_GetGPNVM(&(pChip->details.bank[0]), who, &v); - command_print(CMD_CTX, "sam3-gpnvm%u: %u", who, v); - return r; - } else { - command_print(CMD_CTX, "sam3-gpnvm invalid GPNVM: %u", who); - return ERROR_COMMAND_SYNTAX_ERROR; - } - } - - if (who == -1) { - command_print(CMD_CTX, "Missing GPNVM number"); - return ERROR_COMMAND_SYNTAX_ERROR; - } - - if (0 == strcmp("set", CMD_ARGV[0])) - r = FLASHD_SetGPNVM(&(pChip->details.bank[0]), who); - else if ((0 == strcmp("clr", CMD_ARGV[0])) || - (0 == strcmp("clear", CMD_ARGV[0]))) /* quietly accept both */ - r = FLASHD_ClrGPNVM(&(pChip->details.bank[0]), who); - else { - command_print(CMD_CTX, "Unknown command: %s", CMD_ARGV[0]); - r = ERROR_COMMAND_SYNTAX_ERROR; - } - return r; -} - -COMMAND_HANDLER(sam3_handle_slowclk_command) -{ - struct sam3_chip *pChip; - - pChip = get_current_sam3(CMD_CTX); - if (!pChip) - return ERROR_OK; - - switch (CMD_ARGC) { - case 0: - /* show */ - break; - case 1: - { - /* set */ - uint32_t v; - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], v); - if (v > 200000) { - /* absurd slow clock of 200Khz? */ - command_print(CMD_CTX, "Absurd/illegal slow clock freq: %d\n", (int)(v)); - return ERROR_COMMAND_SYNTAX_ERROR; - } - pChip->cfg.slow_freq = v; - break; - } - default: - /* error */ - command_print(CMD_CTX, "Too many parameters"); - return ERROR_COMMAND_SYNTAX_ERROR; - break; - } - command_print(CMD_CTX, "Slowclk freq: %d.%03dkhz", - (int)(pChip->cfg.slow_freq / 1000), - (int)(pChip->cfg.slow_freq % 1000)); - return ERROR_OK; -} - -static const struct command_registration at91sam3_exec_command_handlers[] = { - { - .name = "gpnvm", - .handler = sam3_handle_gpnvm_command, - .mode = COMMAND_EXEC, - .usage = "[('clr'|'set'|'show') bitnum]", - .help = "Without arguments, shows all bits in the gpnvm " - "register. Otherwise, clears, sets, or shows one " - "General Purpose Non-Volatile Memory (gpnvm) bit.", - }, - { - .name = "info", - .handler = sam3_handle_info_command, - .mode = COMMAND_EXEC, - .help = "Print information about the current at91sam3 chip" - "and its flash configuration.", - }, - { - .name = "slowclk", - .handler = sam3_handle_slowclk_command, - .mode = COMMAND_EXEC, - .usage = "[clock_hz]", - .help = "Display or set the slowclock frequency " - "(default 32768 Hz).", - }, - COMMAND_REGISTRATION_DONE -}; -static const struct command_registration at91sam3_command_handlers[] = { - { - .name = "at91sam3", - .mode = COMMAND_ANY, - .help = "at91sam3 flash command group", - .usage = "", - .chain = at91sam3_exec_command_handlers, - }, - COMMAND_REGISTRATION_DONE -}; - -struct flash_driver at91sam3_flash = { - .name = "at91sam3", - .commands = at91sam3_command_handlers, - .flash_bank_command = sam3_flash_bank_command, - .erase = sam3_erase, - .protect = sam3_protect, - .write = sam3_write, - .read = default_flash_read, - .probe = sam3_probe, - .auto_probe = sam3_auto_probe, - .erase_check = sam3_erase_check, - .protect_check = sam3_protect_check, -}; diff --git a/src/flash/nor/at91sam4.c b/src/flash/nor/at91sam4.c deleted file mode 100644 index 50aa98b89..000000000 --- a/src/flash/nor/at91sam4.c +++ /dev/null @@ -1,2678 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2009 by Duane Ellis * - * openocd@duaneellis.com * - * * - * Copyright (C) 2010 by Olaf Lüke (at91sam3s* support) * - * olaf@uni-paderborn.de * - * * - * Copyright (C) 2011 by Olivier Schonken, Jim Norris * - * (at91sam3x* & at91sam4 support)* * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * -****************************************************************************/ - -/* Some of the the lower level code was based on code supplied by - * ATMEL under this copyright. */ - -/* BEGIN ATMEL COPYRIGHT */ -/* ---------------------------------------------------------------------------- - * ATMEL Microcontroller Software Support - * ---------------------------------------------------------------------------- - * Copyright (c) 2009, Atmel Corporation - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * - Redistributions of source code must retain the above copyright notice, - * this list of conditions and the disclaimer below. - * - * Atmel's name may not be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE - * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, - * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * ---------------------------------------------------------------------------- - */ -/* END ATMEL COPYRIGHT */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "imp.h" -#include - -#define REG_NAME_WIDTH (12) - -/* at91sam4s/at91sam4e series (has always one flash bank)*/ -#define FLASH_BANK_BASE_S 0x00400000 - -/* at91sam4sd series (two one flash banks), first bank address */ -#define FLASH_BANK0_BASE_SD FLASH_BANK_BASE_S -/* at91sam4sd16x, second bank address */ -#define FLASH_BANK1_BASE_1024K_SD (FLASH_BANK0_BASE_SD+(1024*1024/2)) -/* at91sam4sd32x, second bank address */ -#define FLASH_BANK1_BASE_2048K_SD (FLASH_BANK0_BASE_SD+(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 */ -#define AT91C_EFC_FCMD_EWP (0x3) /* (EFC) Erase Page and Write Page */ -#define AT91C_EFC_FCMD_EWPL (0x4) /* (EFC) Erase Page and Write Page then Lock */ -#define AT91C_EFC_FCMD_EA (0x5) /* (EFC) Erase All */ -/* cmd6 is not present in the at91sam4u4/2/1 data sheet table 19-2 */ -/* #define AT91C_EFC_FCMD_EPL (0x6) // (EFC) Erase plane? */ -#define AT91C_EFC_FCMD_EPA (0x7) /* (EFC) Erase pages */ -#define AT91C_EFC_FCMD_SLB (0x8) /* (EFC) Set Lock Bit */ -#define AT91C_EFC_FCMD_CLB (0x9) /* (EFC) Clear Lock Bit */ -#define AT91C_EFC_FCMD_GLB (0xA) /* (EFC) Get Lock Bit */ -#define AT91C_EFC_FCMD_SFB (0xB) /* (EFC) Set Fuse Bit */ -#define AT91C_EFC_FCMD_CFB (0xC) /* (EFC) Clear Fuse Bit */ -#define AT91C_EFC_FCMD_GFB (0xD) /* (EFC) Get Fuse Bit */ -#define AT91C_EFC_FCMD_STUI (0xE) /* (EFC) Start Read Unique ID */ -#define AT91C_EFC_FCMD_SPUI (0xF) /* (EFC) Stop Read Unique ID */ - -#define offset_EFC_FMR 0 -#define offset_EFC_FCR 4 -#define offset_EFC_FSR 8 -#define offset_EFC_FRR 12 - -extern struct flash_driver at91sam4_flash; - -static float _tomhz(uint32_t freq_hz) -{ - float f; - - f = ((float)(freq_hz)) / 1000000.0; - return f; -} - -/* How the chip is configured. */ -struct sam4_cfg { - uint32_t unique_id[4]; - - uint32_t slow_freq; - uint32_t rc_freq; - uint32_t mainosc_freq; - uint32_t plla_freq; - uint32_t mclk_freq; - uint32_t cpu_freq; - uint32_t fclk_freq; - uint32_t pclk0_freq; - uint32_t pclk1_freq; - uint32_t pclk2_freq; - - -#define SAM4_CHIPID_CIDR (0x400E0740) - uint32_t CHIPID_CIDR; -#define SAM4_CHIPID_EXID (0x400E0744) - uint32_t CHIPID_EXID; - -#define SAM4_PMC_BASE (0x400E0400) -#define SAM4_PMC_SCSR (SAM4_PMC_BASE + 0x0008) - uint32_t PMC_SCSR; -#define SAM4_PMC_PCSR (SAM4_PMC_BASE + 0x0018) - uint32_t PMC_PCSR; -#define SAM4_CKGR_UCKR (SAM4_PMC_BASE + 0x001c) - uint32_t CKGR_UCKR; -#define SAM4_CKGR_MOR (SAM4_PMC_BASE + 0x0020) - uint32_t CKGR_MOR; -#define SAM4_CKGR_MCFR (SAM4_PMC_BASE + 0x0024) - uint32_t CKGR_MCFR; -#define SAM4_CKGR_PLLAR (SAM4_PMC_BASE + 0x0028) - uint32_t CKGR_PLLAR; -#define SAM4_PMC_MCKR (SAM4_PMC_BASE + 0x0030) - uint32_t PMC_MCKR; -#define SAM4_PMC_PCK0 (SAM4_PMC_BASE + 0x0040) - uint32_t PMC_PCK0; -#define SAM4_PMC_PCK1 (SAM4_PMC_BASE + 0x0044) - uint32_t PMC_PCK1; -#define SAM4_PMC_PCK2 (SAM4_PMC_BASE + 0x0048) - uint32_t PMC_PCK2; -#define SAM4_PMC_SR (SAM4_PMC_BASE + 0x0068) - uint32_t PMC_SR; -#define SAM4_PMC_IMR (SAM4_PMC_BASE + 0x006c) - uint32_t PMC_IMR; -#define SAM4_PMC_FSMR (SAM4_PMC_BASE + 0x0070) - uint32_t PMC_FSMR; -#define SAM4_PMC_FSPR (SAM4_PMC_BASE + 0x0074) - uint32_t PMC_FSPR; -}; - -struct sam4_bank_private { - int probed; - /* DANGER: THERE ARE DRAGONS HERE.. */ - /* NOTE: If you add more 'ghost' pointers */ - /* be aware that you must *manually* update */ - /* these pointers in the function sam4_GetDetails() */ - /* See the comment "Here there be dragons" */ - - /* so we can find the chip we belong to */ - struct sam4_chip *pChip; - /* so we can find the original bank pointer */ - struct flash_bank *pBank; - unsigned bank_number; - uint32_t controller_address; - uint32_t base_address; - uint32_t flash_wait_states; - bool present; - unsigned size_bytes; - unsigned nsectors; - unsigned sector_size; - unsigned page_size; -}; - -struct sam4_chip_details { - /* THERE ARE DRAGONS HERE.. */ - /* note: If you add pointers here */ - /* be careful about them as they */ - /* may need to be updated inside */ - /* the function: "sam4_GetDetails() */ - /* which copy/overwrites the */ - /* 'runtime' copy of this structure */ - uint32_t chipid_cidr; - const char *name; - - unsigned n_gpnvms; -#define SAM4_N_NVM_BITS 3 - unsigned gpnvm[SAM4_N_NVM_BITS]; - unsigned total_flash_size; - unsigned total_sram_size; - unsigned n_banks; -#define SAM4_MAX_FLASH_BANKS 2 - /* these are "initialized" from the global const data */ - struct sam4_bank_private bank[SAM4_MAX_FLASH_BANKS]; -}; - -struct sam4_chip { - struct sam4_chip *next; - int probed; - - /* this is "initialized" from the global const structure */ - struct sam4_chip_details details; - struct target *target; - struct sam4_cfg cfg; -}; - - -struct sam4_reg_list { - uint32_t address; size_t struct_offset; const char *name; - void (*explain_func)(struct sam4_chip *pInfo); -}; - -static struct sam4_chip *all_sam4_chips; - -static struct sam4_chip *get_current_sam4(struct command_context *cmd_ctx) -{ - struct target *t; - static struct sam4_chip *p; - - t = get_current_target(cmd_ctx); - if (!t) { - command_print(cmd_ctx, "No current target?"); - return NULL; - } - - p = all_sam4_chips; - if (!p) { - /* this should not happen */ - /* the command is not registered until the chip is created? */ - command_print(cmd_ctx, "No SAM4 chips exist?"); - return NULL; - } - - while (p) { - if (p->target == t) - return p; - p = p->next; - } - command_print(cmd_ctx, "Cannot find SAM4 chip?"); - return NULL; -} - -/*The actual sector size of the SAM4S flash memory is 65536 bytes. 16 sectors for a 1024KB device*/ -/*The lockregions are 8KB per lock region, with a 1024KB device having 128 lock regions. */ -/*For the best results, nsectors are thus set to the amount of lock regions, and the sector_size*/ -/*set to the lock region size. Page erases are used to erase 8KB sections when programming*/ - -/* these are used to *initialize* the "pChip->details" structure. */ -static const struct sam4_chip_details all_sam4_details[] = { - - /* Start at91sam4e* series */ - /*atsam4e16e - LQFP144/LFBGA144*/ - { - .chipid_cidr = 0xA3CC0CE0, - .name = "at91sam4e16e", - .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 = 6, /* workaround silicon bug */ - .present = 1, - .size_bytes = 1024 * 1024, - .nsectors = 128, - .sector_size = 8192, - .page_size = 512, - }, -/* .bank[1] = {*/ - { - .present = 0, - .probed = 0, - .bank_number = 1, - - }, - }, - }, - - /* Start at91sam4n* series */ - /*atsam4n8a - LQFP48/QFN48*/ - { - .chipid_cidr = 0x293B0AE0, - .name = "at91sam4n8a", - .total_flash_size = 512 * 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 = 6, /* workaround silicon bug */ - .present = 1, - .size_bytes = 512 * 1024, - .nsectors = 64, - .sector_size = 8192, - .page_size = 512, - }, -/* .bank[1] = {*/ - { - .present = 0, - .probed = 0, - .bank_number = 1, - - }, - }, - }, - /*atsam4n8b - LQFP64/QFN64*/ - { - .chipid_cidr = 0x294B0AE0, - .name = "at91sam4n8b", - .total_flash_size = 512 * 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 = 6, /* workaround silicon bug */ - .present = 1, - .size_bytes = 512 * 1024, - .nsectors = 64, - .sector_size = 8192, - .page_size = 512, - }, -/* .bank[1] = {*/ - { - .present = 0, - .probed = 0, - .bank_number = 1, - - }, - }, - }, - /*atsam4n8c - LQFP100/TFBGA100/VFBGA100*/ - { - .chipid_cidr = 0x295B0AE0, - .name = "at91sam4n8c", - .total_flash_size = 512 * 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 = 6, /* workaround silicon bug */ - .present = 1, - .size_bytes = 512 * 1024, - .nsectors = 64, - .sector_size = 8192, - .page_size = 512, - }, -/* .bank[1] = {*/ - { - .present = 0, - .probed = 0, - .bank_number = 1, - - }, - }, - }, - /*atsam4n16b - LQFP64/QFN64*/ - { - .chipid_cidr = 0x29460CE0, - .name = "at91sam4n16b", - .total_flash_size = 1024 * 1024, - .total_sram_size = 80 * 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 = 6, /* workaround silicon bug */ - .present = 1, - .size_bytes = 1024 * 1024, - .nsectors = 128, - .sector_size = 8192, - .page_size = 512, - }, -/* .bank[1] = {*/ - { - .present = 0, - .probed = 0, - .bank_number = 1, - - }, - }, - }, - /*atsam4n16c - LQFP100/TFBGA100/VFBGA100*/ - { - .chipid_cidr = 0x29560CE0, - .name = "at91sam4n16c", - .total_flash_size = 1024 * 1024, - .total_sram_size = 80 * 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 = 6, /* workaround silicon bug */ - .present = 1, - .size_bytes = 1024 * 1024, - .nsectors = 128, - .sector_size = 8192, - .page_size = 512, - }, -/* .bank[1] = {*/ - { - .present = 0, - .probed = 0, - .bank_number = 1, - - }, - }, - }, - - /* Start at91sam4s* series */ - /*atsam4s16c - LQFP100/BGA100*/ - { - .chipid_cidr = 0x28AC0CE0, - .name = "at91sam4s16c", - .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 = 6, /* workaround silicon bug */ - .present = 1, - .size_bytes = 1024 * 1024, - .nsectors = 128, - .sector_size = 8192, - .page_size = 512, - }, -/* .bank[1] = {*/ - { - .present = 0, - .probed = 0, - .bank_number = 1, - - }, - }, - }, - /*atsam4s16b - LQFP64/QFN64*/ - { - .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 = 6, /* workaround silicon bug */ - .present = 1, - .size_bytes = 1024 * 1024, - .nsectors = 128, - .sector_size = 8192, - .page_size = 512, - }, -/* .bank[1] = {*/ - { - .present = 0, - .probed = 0, - .bank_number = 1, - - }, - }, - }, - /*atsam4sa16b - LQFP64/QFN64*/ - { - .chipid_cidr = 0x28970CE0, - .name = "at91sam4sa16b", - .total_flash_size = 1024 * 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 = 6, /* workaround silicon bug */ - .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 = 6, /* workaround silicon bug */ - .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 = 6, /* workaround silicon bug */ - .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/BGA64*/ - { - .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 = 6, /* workaround silicon bug */ - .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 = 6, /* workaround silicon bug */ - .present = 1, - .size_bytes = 512 * 1024, - .nsectors = 64, - .sector_size = 8192, - .page_size = 512, - }, -/* .bank[1] = {*/ - { - .present = 0, - .probed = 0, - .bank_number = 1, - - }, - }, - }, - - /*atsam4s4a - LQFP48/BGA48*/ - { - .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 = 6, /* workaround silicon bug */ - .present = 1, - .size_bytes = 256 * 1024, - .nsectors = 32, - .sector_size = 8192, - .page_size = 512, - }, -/* .bank[1] = {*/ - { - .present = 0, - .probed = 0, - .bank_number = 1, - - }, - }, - }, - - /*at91sam4sd32c*/ - { - .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 */ - .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 = 6, /* workaround silicon bug */ - .present = 1, - .size_bytes = 1024 * 1024, - .nsectors = 128, - .sector_size = 8192, - .page_size = 512, - }, - }, - }, - - /*at91sam4sd16c*/ - { - .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 = 6, /* workaround silicon bug */ - .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 = 6, /* workaround silicon bug */ - .present = 1, - .size_bytes = 512 * 1024, - .nsectors = 64, - .sector_size = 8192, - .page_size = 512, - }, - }, - }, - - /*at91sam4sa16c*/ - { - .chipid_cidr = 0x28a70ce0, - .name = "at91sam4sa16c", - .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 = 6, /* workaround silicon bug */ - .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 = 6, /* workaround silicon bug */ - .present = 1, - .size_bytes = 512 * 1024, - .nsectors = 64, - .sector_size = 8192, - .page_size = 512, - }, - }, - }, - - /* at91samg53n19 */ - { - .chipid_cidr = 0x247e0ae0, - .name = "at91samg53n19", - .total_flash_size = 512 * 1024, - .total_sram_size = 96 * 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 = 6, /* workaround silicon bug */ - .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, - .name = NULL, - } -}; - -/* Globals above */ -/*********************************************************************** - ********************************************************************** - ********************************************************************** - ********************************************************************** - ********************************************************************** - **********************************************************************/ -/* *ATMEL* style code - from the SAM4 driver code */ - -/** - * Get the current status of the EEFC and - * the value of some status bits (LOCKE, PROGE). - * @param pPrivate - info about the bank - * @param v - result goes here - */ -static int EFC_GetStatus(struct sam4_bank_private *pPrivate, uint32_t *v) -{ - int r; - r = target_read_u32(pPrivate->pChip->target, - pPrivate->controller_address + offset_EFC_FSR, - v); - LOG_DEBUG("Status: 0x%08x (lockerror: %d, cmderror: %d, ready: %d)", - (unsigned int)(*v), - ((unsigned int)((*v >> 2) & 1)), - ((unsigned int)((*v >> 1) & 1)), - ((unsigned int)((*v >> 0) & 1))); - - return r; -} - -/** - * Get the result of the last executed command. - * @param pPrivate - info about the bank - * @param v - result goes here - */ -static int EFC_GetResult(struct sam4_bank_private *pPrivate, uint32_t *v) -{ - int r; - uint32_t rv; - r = target_read_u32(pPrivate->pChip->target, - pPrivate->controller_address + offset_EFC_FRR, - &rv); - if (v) - *v = rv; - LOG_DEBUG("Result: 0x%08x", ((unsigned int)(rv))); - return r; -} - -static int EFC_StartCommand(struct sam4_bank_private *pPrivate, - unsigned command, unsigned argument) -{ - uint32_t n, v; - int r; - int retry; - - retry = 0; -do_retry: - - /* Check command & argument */ - switch (command) { - - case AT91C_EFC_FCMD_WP: - case AT91C_EFC_FCMD_WPL: - case AT91C_EFC_FCMD_EWP: - case AT91C_EFC_FCMD_EWPL: - /* case AT91C_EFC_FCMD_EPL: */ - case AT91C_EFC_FCMD_EPA: - case AT91C_EFC_FCMD_SLB: - case AT91C_EFC_FCMD_CLB: - n = (pPrivate->size_bytes / pPrivate->page_size); - if (argument >= n) - LOG_ERROR("*BUG*: Embedded flash has only %u pages", (unsigned)(n)); - break; - - case AT91C_EFC_FCMD_SFB: - case AT91C_EFC_FCMD_CFB: - if (argument >= pPrivate->pChip->details.n_gpnvms) { - LOG_ERROR("*BUG*: Embedded flash has only %d GPNVMs", - pPrivate->pChip->details.n_gpnvms); - } - break; - - case AT91C_EFC_FCMD_GETD: - case AT91C_EFC_FCMD_EA: - case AT91C_EFC_FCMD_GLB: - case AT91C_EFC_FCMD_GFB: - case AT91C_EFC_FCMD_STUI: - case AT91C_EFC_FCMD_SPUI: - if (argument != 0) - LOG_ERROR("Argument is meaningless for cmd: %d", command); - break; - default: - LOG_ERROR("Unknown command %d", command); - break; - } - - if (command == AT91C_EFC_FCMD_SPUI) { - /* this is a very special situation. */ - /* Situation (1) - error/retry - see below */ - /* And we are being called recursively */ - /* Situation (2) - normal, finished reading unique id */ - } else { - /* it should be "ready" */ - EFC_GetStatus(pPrivate, &v); - if (v & 1) { - /* then it is ready */ - /* we go on */ - } else { - if (retry) { - /* we have done this before */ - /* the controller is not responding. */ - LOG_ERROR("flash controller(%d) is not ready! Error", - pPrivate->bank_number); - return ERROR_FAIL; - } else { - retry++; - LOG_ERROR("Flash controller(%d) is not ready, attempting reset", - pPrivate->bank_number); - /* we do that by issuing the *STOP* command */ - EFC_StartCommand(pPrivate, AT91C_EFC_FCMD_SPUI, 0); - /* above is recursive, and further recursion is blocked by */ - /* if (command == AT91C_EFC_FCMD_SPUI) above */ - goto do_retry; - } - } - } - - v = (0x5A << 24) | (argument << 8) | command; - LOG_DEBUG("Command: 0x%08x", ((unsigned int)(v))); - r = target_write_u32(pPrivate->pBank->target, - pPrivate->controller_address + offset_EFC_FCR, v); - if (r != ERROR_OK) - LOG_DEBUG("Error Write failed"); - return r; -} - -/** - * Performs the given command and wait until its completion (or an error). - * @param pPrivate - info about the bank - * @param command - Command to perform. - * @param argument - Optional command argument. - * @param status - put command status bits here - */ -static int EFC_PerformCommand(struct sam4_bank_private *pPrivate, - unsigned command, - unsigned argument, - uint32_t *status) -{ - - int r; - uint32_t v; - int64_t ms_now, ms_end; - - /* default */ - if (status) - *status = 0; - - r = EFC_StartCommand(pPrivate, command, argument); - if (r != ERROR_OK) - return r; - - ms_end = 10000 + timeval_ms(); - - do { - r = EFC_GetStatus(pPrivate, &v); - if (r != ERROR_OK) - return r; - ms_now = timeval_ms(); - if (ms_now > ms_end) { - /* error */ - LOG_ERROR("Command timeout"); - return ERROR_FAIL; - } - } while ((v & 1) == 0); - - /* error bits.. */ - if (status) - *status = (v & 0x6); - return ERROR_OK; - -} - -/** - * Read the unique ID. - * @param pPrivate - info about the bank - * The unique ID is stored in the 'pPrivate' structure. - */ -static int FLASHD_ReadUniqueID(struct sam4_bank_private *pPrivate) -{ - int r; - uint32_t v; - int x; - /* assume 0 */ - pPrivate->pChip->cfg.unique_id[0] = 0; - pPrivate->pChip->cfg.unique_id[1] = 0; - pPrivate->pChip->cfg.unique_id[2] = 0; - pPrivate->pChip->cfg.unique_id[3] = 0; - - LOG_DEBUG("Begin"); - r = EFC_StartCommand(pPrivate, AT91C_EFC_FCMD_STUI, 0); - if (r < 0) - return r; - - for (x = 0; x < 4; x++) { - r = target_read_u32(pPrivate->pChip->target, - pPrivate->pBank->base + (x * 4), - &v); - if (r < 0) - return r; - pPrivate->pChip->cfg.unique_id[x] = v; - } - - r = EFC_PerformCommand(pPrivate, AT91C_EFC_FCMD_SPUI, 0, NULL); - LOG_DEBUG("End: R=%d, id = 0x%08x, 0x%08x, 0x%08x, 0x%08x", - r, - (unsigned int)(pPrivate->pChip->cfg.unique_id[0]), - (unsigned int)(pPrivate->pChip->cfg.unique_id[1]), - (unsigned int)(pPrivate->pChip->cfg.unique_id[2]), - (unsigned int)(pPrivate->pChip->cfg.unique_id[3])); - return r; - -} - -/** - * Erases the entire flash. - * @param pPrivate - the info about the bank. - */ -static int FLASHD_EraseEntireBank(struct sam4_bank_private *pPrivate) -{ - LOG_DEBUG("Here"); - return EFC_PerformCommand(pPrivate, AT91C_EFC_FCMD_EA, 0, NULL); -} - -/** - * Erases the entire flash. - * @param pPrivate - the info about the bank. - */ -static int FLASHD_ErasePages(struct sam4_bank_private *pPrivate, - int firstPage, - int numPages, - uint32_t *status) -{ - LOG_DEBUG("Here"); - uint8_t erasePages; - switch (numPages) { - case 4: - erasePages = 0x00; - break; - case 8: - erasePages = 0x01; - break; - case 16: - erasePages = 0x02; - break; - case 32: - erasePages = 0x03; - break; - default: - erasePages = 0x00; - break; - } - - /* AT91C_EFC_FCMD_EPA - * According to the datasheet FARG[15:2] defines the page from which - * the erase will start.This page must be modulo 4, 8, 16 or 32 - * according to the number of pages to erase. FARG[1:0] defines the - * number of pages to be erased. Previously (firstpage << 2) was used - * to conform to this, seems it should not be shifted... - */ - return EFC_PerformCommand(pPrivate, - /* send Erase Page */ - AT91C_EFC_FCMD_EPA, - (firstPage) | erasePages, - status); -} - -/** - * Gets current GPNVM state. - * @param pPrivate - info about the bank. - * @param gpnvm - GPNVM bit index. - * @param puthere - result stored here. - */ -/* ------------------------------------------------------------------------------ */ -static int FLASHD_GetGPNVM(struct sam4_bank_private *pPrivate, unsigned gpnvm, unsigned *puthere) -{ - uint32_t v; - int r; - - LOG_DEBUG("Here"); - if (pPrivate->bank_number != 0) { - LOG_ERROR("GPNVM only works with Bank0"); - return ERROR_FAIL; - } - - if (gpnvm >= pPrivate->pChip->details.n_gpnvms) { - LOG_ERROR("Invalid GPNVM %d, max: %d, ignored", - gpnvm, pPrivate->pChip->details.n_gpnvms); - return ERROR_FAIL; - } - - /* Get GPNVMs status */ - r = EFC_PerformCommand(pPrivate, AT91C_EFC_FCMD_GFB, 0, NULL); - if (r != ERROR_OK) { - LOG_ERROR("Failed"); - return r; - } - - r = EFC_GetResult(pPrivate, &v); - - if (puthere) { - /* Check if GPNVM is set */ - /* get the bit and make it a 0/1 */ - *puthere = (v >> gpnvm) & 1; - } - - return r; -} - -/** - * Clears the selected GPNVM bit. - * @param pPrivate info about the bank - * @param gpnvm GPNVM index. - * @returns 0 if successful; otherwise returns an error code. - */ -static int FLASHD_ClrGPNVM(struct sam4_bank_private *pPrivate, unsigned gpnvm) -{ - int r; - unsigned v; - - LOG_DEBUG("Here"); - if (pPrivate->bank_number != 0) { - LOG_ERROR("GPNVM only works with Bank0"); - return ERROR_FAIL; - } - - if (gpnvm >= pPrivate->pChip->details.n_gpnvms) { - LOG_ERROR("Invalid GPNVM %d, max: %d, ignored", - gpnvm, pPrivate->pChip->details.n_gpnvms); - return ERROR_FAIL; - } - - r = FLASHD_GetGPNVM(pPrivate, gpnvm, &v); - if (r != ERROR_OK) { - LOG_DEBUG("Failed: %d", r); - return r; - } - r = EFC_PerformCommand(pPrivate, AT91C_EFC_FCMD_CFB, gpnvm, NULL); - LOG_DEBUG("End: %d", r); - return r; -} - -/** - * Sets the selected GPNVM bit. - * @param pPrivate info about the bank - * @param gpnvm GPNVM index. - */ -static int FLASHD_SetGPNVM(struct sam4_bank_private *pPrivate, unsigned gpnvm) -{ - int r; - unsigned v; - - if (pPrivate->bank_number != 0) { - LOG_ERROR("GPNVM only works with Bank0"); - return ERROR_FAIL; - } - - if (gpnvm >= pPrivate->pChip->details.n_gpnvms) { - LOG_ERROR("Invalid GPNVM %d, max: %d, ignored", - gpnvm, pPrivate->pChip->details.n_gpnvms); - return ERROR_FAIL; - } - - r = FLASHD_GetGPNVM(pPrivate, gpnvm, &v); - if (r != ERROR_OK) - return r; - if (v) { - /* already set */ - r = ERROR_OK; - } else { - /* set it */ - r = EFC_PerformCommand(pPrivate, AT91C_EFC_FCMD_SFB, gpnvm, NULL); - } - return r; -} - -/** - * Returns a bit field (at most 64) of locked regions within a page. - * @param pPrivate info about the bank - * @param v where to store locked bits - */ -static int FLASHD_GetLockBits(struct sam4_bank_private *pPrivate, uint32_t *v) -{ - int r; - LOG_DEBUG("Here"); - r = EFC_PerformCommand(pPrivate, AT91C_EFC_FCMD_GLB, 0, NULL); - if (r == ERROR_OK) { - EFC_GetResult(pPrivate, v); - EFC_GetResult(pPrivate, v); - EFC_GetResult(pPrivate, v); - r = EFC_GetResult(pPrivate, v); - } - LOG_DEBUG("End: %d", r); - return r; -} - -/** - * Unlocks all the regions in the given address range. - * @param pPrivate info about the bank - * @param start_sector first sector to unlock - * @param end_sector last (inclusive) to unlock - */ - -static int FLASHD_Unlock(struct sam4_bank_private *pPrivate, - unsigned start_sector, - unsigned end_sector) -{ - int r; - uint32_t status; - uint32_t pg; - uint32_t pages_per_sector; - - pages_per_sector = pPrivate->sector_size / pPrivate->page_size; - - /* Unlock all pages */ - while (start_sector <= end_sector) { - pg = start_sector * pages_per_sector; - - r = EFC_PerformCommand(pPrivate, AT91C_EFC_FCMD_CLB, pg, &status); - if (r != ERROR_OK) - return r; - start_sector++; - } - - return ERROR_OK; -} - -/** - * Locks regions - * @param pPrivate - info about the bank - * @param start_sector - first sector to lock - * @param end_sector - last sector (inclusive) to lock - */ -static int FLASHD_Lock(struct sam4_bank_private *pPrivate, - unsigned start_sector, - unsigned end_sector) -{ - uint32_t status; - uint32_t pg; - uint32_t pages_per_sector; - int r; - - pages_per_sector = pPrivate->sector_size / pPrivate->page_size; - - /* Lock all pages */ - while (start_sector <= end_sector) { - pg = start_sector * pages_per_sector; - - r = EFC_PerformCommand(pPrivate, AT91C_EFC_FCMD_SLB, pg, &status); - if (r != ERROR_OK) - return r; - start_sector++; - } - return ERROR_OK; -} - -/****** END SAM4 CODE ********/ - -/* begin helpful debug code */ -/* print the fieldname, the field value, in dec & hex, and return field value */ -static uint32_t sam4_reg_fieldname(struct sam4_chip *pChip, - const char *regname, - uint32_t value, - unsigned shift, - unsigned width) -{ - uint32_t v; - int hwidth, dwidth; - - - /* extract the field */ - v = value >> shift; - v = v & ((1 << width)-1); - if (width <= 16) { - hwidth = 4; - dwidth = 5; - } else { - hwidth = 8; - dwidth = 12; - } - - /* show the basics */ - LOG_USER_N("\t%*s: %*" PRId32 " [0x%0*" PRIx32 "] ", - REG_NAME_WIDTH, regname, - dwidth, v, - hwidth, v); - return v; -} - -static const char _unknown[] = "unknown"; -static const char *const eproc_names[] = { - _unknown, /* 0 */ - "arm946es", /* 1 */ - "arm7tdmi", /* 2 */ - "Cortex-M3", /* 3 */ - "arm920t", /* 4 */ - "arm926ejs", /* 5 */ - "Cortex-A5", /* 6 */ - "Cortex-M4", /* 7 */ - _unknown, /* 8 */ - _unknown, /* 9 */ - _unknown, /* 10 */ - _unknown, /* 11 */ - _unknown, /* 12 */ - _unknown, /* 13 */ - _unknown, /* 14 */ - _unknown, /* 15 */ -}; - -#define nvpsize2 nvpsize /* these two tables are identical */ -static const char *const nvpsize[] = { - "none", /* 0 */ - "8K bytes", /* 1 */ - "16K bytes", /* 2 */ - "32K bytes", /* 3 */ - _unknown, /* 4 */ - "64K bytes", /* 5 */ - _unknown, /* 6 */ - "128K bytes", /* 7 */ - _unknown, /* 8 */ - "256K bytes", /* 9 */ - "512K bytes", /* 10 */ - _unknown, /* 11 */ - "1024K bytes", /* 12 */ - _unknown, /* 13 */ - "2048K bytes", /* 14 */ - _unknown, /* 15 */ -}; - -static const char *const sramsize[] = { - "48K Bytes", /* 0 */ - "1K Bytes", /* 1 */ - "2K Bytes", /* 2 */ - "6K Bytes", /* 3 */ - "112K Bytes", /* 4 */ - "4K Bytes", /* 5 */ - "80K Bytes", /* 6 */ - "160K Bytes", /* 7 */ - "8K Bytes", /* 8 */ - "16K Bytes", /* 9 */ - "32K Bytes", /* 10 */ - "64K Bytes", /* 11 */ - "128K Bytes", /* 12 */ - "256K Bytes", /* 13 */ - "96K Bytes", /* 14 */ - "512K Bytes", /* 15 */ - -}; - -static const struct archnames { unsigned value; const char *name; } archnames[] = { - { 0x19, "AT91SAM9xx Series" }, - { 0x29, "AT91SAM9XExx Series" }, - { 0x34, "AT91x34 Series" }, - { 0x37, "CAP7 Series" }, - { 0x39, "CAP9 Series" }, - { 0x3B, "CAP11 Series" }, - { 0x3C, "ATSAM4E" }, - { 0x40, "AT91x40 Series" }, - { 0x42, "AT91x42 Series" }, - { 0x43, "SAMG51 Series" - }, - { 0x47, "SAMG53 Series" - }, - { 0x55, "AT91x55 Series" }, - { 0x60, "AT91SAM7Axx Series" }, - { 0x61, "AT91SAM7AQxx Series" }, - { 0x63, "AT91x63 Series" }, - { 0x70, "AT91SAM7Sxx Series" }, - { 0x71, "AT91SAM7XCxx Series" }, - { 0x72, "AT91SAM7SExx Series" }, - { 0x73, "AT91SAM7Lxx Series" }, - { 0x75, "AT91SAM7Xxx Series" }, - { 0x76, "AT91SAM7SLxx Series" }, - { 0x80, "ATSAM3UxC Series (100-pin version)" }, - { 0x81, "ATSAM3UxE Series (144-pin version)" }, - { 0x83, "ATSAM3A/SAM4A xC Series (100-pin version)"}, - { 0x84, "ATSAM3X/SAM4X xC Series (100-pin version)"}, - { 0x85, "ATSAM3X/SAM4X xE Series (144-pin version)"}, - { 0x86, "ATSAM3X/SAM4X xG Series (208/217-pin version)" }, - { 0x88, "ATSAM3S/SAM4S xA Series (48-pin version)" }, - { 0x89, "ATSAM3S/SAM4S xB Series (64-pin version)" }, - { 0x8A, "ATSAM3S/SAM4S xC Series (100-pin version)"}, - { 0x92, "AT91x92 Series" }, - { 0x93, "ATSAM3NxA Series (48-pin version)" }, - { 0x94, "ATSAM3NxB Series (64-pin version)" }, - { 0x95, "ATSAM3NxC Series (100-pin version)" }, - { 0x98, "ATSAM3SDxA Series (48-pin version)" }, - { 0x99, "ATSAM3SDxB Series (64-pin version)" }, - { 0x9A, "ATSAM3SDxC Series (100-pin version)" }, - { 0xA5, "ATSAM5A" }, - { 0xF0, "AT75Cxx Series" }, - { -1, NULL }, -}; - -static const char *const nvptype[] = { - "rom", /* 0 */ - "romless or onchip flash", /* 1 */ - "embedded flash memory",/* 2 */ - "rom(nvpsiz) + embedded flash (nvpsiz2)", /* 3 */ - "sram emulating flash", /* 4 */ - _unknown, /* 5 */ - _unknown, /* 6 */ - _unknown, /* 7 */ -}; - -static const char *_yes_or_no(uint32_t v) -{ - if (v) - return "YES"; - else - return "NO"; -} - -static const char *const _rc_freq[] = { - "4 MHz", "8 MHz", "12 MHz", "reserved" -}; - -static void sam4_explain_ckgr_mor(struct sam4_chip *pChip) -{ - uint32_t v; - uint32_t rcen; - - v = sam4_reg_fieldname(pChip, "MOSCXTEN", pChip->cfg.CKGR_MOR, 0, 1); - LOG_USER("(main xtal enabled: %s)", _yes_or_no(v)); - v = sam4_reg_fieldname(pChip, "MOSCXTBY", pChip->cfg.CKGR_MOR, 1, 1); - LOG_USER("(main osc bypass: %s)", _yes_or_no(v)); - rcen = sam4_reg_fieldname(pChip, "MOSCRCEN", pChip->cfg.CKGR_MOR, 3, 1); - LOG_USER("(onchip RC-OSC enabled: %s)", _yes_or_no(rcen)); - v = sam4_reg_fieldname(pChip, "MOSCRCF", pChip->cfg.CKGR_MOR, 4, 3); - LOG_USER("(onchip RC-OSC freq: %s)", _rc_freq[v]); - - pChip->cfg.rc_freq = 0; - if (rcen) { - switch (v) { - default: - pChip->cfg.rc_freq = 0; - break; - case 0: - pChip->cfg.rc_freq = 4 * 1000 * 1000; - break; - case 1: - pChip->cfg.rc_freq = 8 * 1000 * 1000; - break; - case 2: - pChip->cfg.rc_freq = 12 * 1000 * 1000; - break; - } - } - - v = sam4_reg_fieldname(pChip, "MOSCXTST", pChip->cfg.CKGR_MOR, 8, 8); - LOG_USER("(startup clks, time= %f uSecs)", - ((float)(v * 1000000)) / ((float)(pChip->cfg.slow_freq))); - v = sam4_reg_fieldname(pChip, "MOSCSEL", pChip->cfg.CKGR_MOR, 24, 1); - LOG_USER("(mainosc source: %s)", - v ? "external xtal" : "internal RC"); - - v = sam4_reg_fieldname(pChip, "CFDEN", pChip->cfg.CKGR_MOR, 25, 1); - LOG_USER("(clock failure enabled: %s)", - _yes_or_no(v)); -} - -static void sam4_explain_chipid_cidr(struct sam4_chip *pChip) -{ - int x; - uint32_t v; - const char *cp; - - sam4_reg_fieldname(pChip, "Version", pChip->cfg.CHIPID_CIDR, 0, 5); - LOG_USER_N("\n"); - - v = sam4_reg_fieldname(pChip, "EPROC", pChip->cfg.CHIPID_CIDR, 5, 3); - LOG_USER("%s", eproc_names[v]); - - v = sam4_reg_fieldname(pChip, "NVPSIZE", pChip->cfg.CHIPID_CIDR, 8, 4); - LOG_USER("%s", nvpsize[v]); - - v = sam4_reg_fieldname(pChip, "NVPSIZE2", pChip->cfg.CHIPID_CIDR, 12, 4); - LOG_USER("%s", nvpsize2[v]); - - v = sam4_reg_fieldname(pChip, "SRAMSIZE", pChip->cfg.CHIPID_CIDR, 16, 4); - LOG_USER("%s", sramsize[v]); - - v = sam4_reg_fieldname(pChip, "ARCH", pChip->cfg.CHIPID_CIDR, 20, 8); - cp = _unknown; - for (x = 0; archnames[x].name; x++) { - if (v == archnames[x].value) { - cp = archnames[x].name; - break; - } - } - - LOG_USER("%s", cp); - - v = sam4_reg_fieldname(pChip, "NVPTYP", pChip->cfg.CHIPID_CIDR, 28, 3); - LOG_USER("%s", nvptype[v]); - - v = sam4_reg_fieldname(pChip, "EXTID", pChip->cfg.CHIPID_CIDR, 31, 1); - LOG_USER("(exists: %s)", _yes_or_no(v)); -} - -static void sam4_explain_ckgr_mcfr(struct sam4_chip *pChip) -{ - uint32_t v; - - v = sam4_reg_fieldname(pChip, "MAINFRDY", pChip->cfg.CKGR_MCFR, 16, 1); - LOG_USER("(main ready: %s)", _yes_or_no(v)); - - v = sam4_reg_fieldname(pChip, "MAINF", pChip->cfg.CKGR_MCFR, 0, 16); - - v = (v * pChip->cfg.slow_freq) / 16; - pChip->cfg.mainosc_freq = v; - - LOG_USER("(%3.03f Mhz (%" PRIu32 ".%03" PRIu32 "khz slowclk)", - _tomhz(v), - (uint32_t)(pChip->cfg.slow_freq / 1000), - (uint32_t)(pChip->cfg.slow_freq % 1000)); -} - -static void sam4_explain_ckgr_plla(struct sam4_chip *pChip) -{ - uint32_t mula, diva; - - diva = sam4_reg_fieldname(pChip, "DIVA", pChip->cfg.CKGR_PLLAR, 0, 8); - LOG_USER_N("\n"); - mula = sam4_reg_fieldname(pChip, "MULA", pChip->cfg.CKGR_PLLAR, 16, 11); - LOG_USER_N("\n"); - pChip->cfg.plla_freq = 0; - if (mula == 0) - LOG_USER("\tPLLA Freq: (Disabled,mula = 0)"); - else if (diva == 0) - LOG_USER("\tPLLA Freq: (Disabled,diva = 0)"); - else if (diva >= 1) { - pChip->cfg.plla_freq = (pChip->cfg.mainosc_freq * (mula + 1) / diva); - LOG_USER("\tPLLA Freq: %3.03f MHz", - _tomhz(pChip->cfg.plla_freq)); - } -} - -static void sam4_explain_mckr(struct sam4_chip *pChip) -{ - uint32_t css, pres, fin = 0; - int pdiv = 0; - const char *cp = NULL; - - css = sam4_reg_fieldname(pChip, "CSS", pChip->cfg.PMC_MCKR, 0, 2); - switch (css & 3) { - case 0: - fin = pChip->cfg.slow_freq; - cp = "slowclk"; - break; - case 1: - fin = pChip->cfg.mainosc_freq; - cp = "mainosc"; - break; - case 2: - fin = pChip->cfg.plla_freq; - cp = "plla"; - break; - case 3: - if (pChip->cfg.CKGR_UCKR & (1 << 16)) { - fin = 480 * 1000 * 1000; - cp = "upll"; - } else { - fin = 0; - cp = "upll (*ERROR* UPLL is disabled)"; - } - break; - default: - assert(0); - break; - } - - LOG_USER("%s (%3.03f Mhz)", - cp, - _tomhz(fin)); - pres = sam4_reg_fieldname(pChip, "PRES", pChip->cfg.PMC_MCKR, 4, 3); - switch (pres & 0x07) { - case 0: - pdiv = 1; - cp = "selected clock"; - break; - case 1: - pdiv = 2; - cp = "clock/2"; - break; - case 2: - pdiv = 4; - cp = "clock/4"; - break; - case 3: - pdiv = 8; - cp = "clock/8"; - break; - case 4: - pdiv = 16; - cp = "clock/16"; - break; - case 5: - pdiv = 32; - cp = "clock/32"; - break; - case 6: - pdiv = 64; - cp = "clock/64"; - break; - case 7: - pdiv = 6; - cp = "clock/6"; - break; - default: - assert(0); - break; - } - LOG_USER("(%s)", cp); - fin = fin / pdiv; - /* sam4 has a *SINGLE* clock - */ - /* other at91 series parts have divisors for these. */ - pChip->cfg.cpu_freq = fin; - pChip->cfg.mclk_freq = fin; - pChip->cfg.fclk_freq = fin; - LOG_USER("\t\tResult CPU Freq: %3.03f", - _tomhz(fin)); -} - -#if 0 -static struct sam4_chip *target2sam4(struct target *pTarget) -{ - struct sam4_chip *pChip; - - if (pTarget == NULL) - return NULL; - - pChip = all_sam4_chips; - while (pChip) { - if (pChip->target == pTarget) - break; /* return below */ - else - pChip = pChip->next; - } - return pChip; -} -#endif - -static uint32_t *sam4_get_reg_ptr(struct sam4_cfg *pCfg, const struct sam4_reg_list *pList) -{ - /* this function exists to help */ - /* keep funky offsetof() errors */ - /* and casting from causing bugs */ - - /* By using prototypes - we can detect what would */ - /* be casting errors. */ - - return (uint32_t *)(void *)(((char *)(pCfg)) + pList->struct_offset); -} - - -#define SAM4_ENTRY(NAME, FUNC) { .address = SAM4_ ## NAME, .struct_offset = offsetof( \ - struct sam4_cfg, \ - NAME), # NAME, FUNC } -static const struct sam4_reg_list sam4_all_regs[] = { - SAM4_ENTRY(CKGR_MOR, sam4_explain_ckgr_mor), - SAM4_ENTRY(CKGR_MCFR, sam4_explain_ckgr_mcfr), - SAM4_ENTRY(CKGR_PLLAR, sam4_explain_ckgr_plla), - SAM4_ENTRY(CKGR_UCKR, NULL), - SAM4_ENTRY(PMC_FSMR, NULL), - SAM4_ENTRY(PMC_FSPR, NULL), - SAM4_ENTRY(PMC_IMR, NULL), - SAM4_ENTRY(PMC_MCKR, sam4_explain_mckr), - SAM4_ENTRY(PMC_PCK0, NULL), - SAM4_ENTRY(PMC_PCK1, NULL), - SAM4_ENTRY(PMC_PCK2, NULL), - SAM4_ENTRY(PMC_PCSR, NULL), - SAM4_ENTRY(PMC_SCSR, NULL), - SAM4_ENTRY(PMC_SR, NULL), - SAM4_ENTRY(CHIPID_CIDR, sam4_explain_chipid_cidr), - SAM4_ENTRY(CHIPID_EXID, NULL), - /* TERMINATE THE LIST */ - { .name = NULL } -}; -#undef SAM4_ENTRY - -static struct sam4_bank_private *get_sam4_bank_private(struct flash_bank *bank) -{ - return bank->driver_priv; -} - -/** - * Given a pointer to where it goes in the structure, - * determine the register name, address from the all registers table. - */ -static const struct sam4_reg_list *sam4_GetReg(struct sam4_chip *pChip, uint32_t *goes_here) -{ - const struct sam4_reg_list *pReg; - - pReg = &(sam4_all_regs[0]); - while (pReg->name) { - uint32_t *pPossible; - - /* calculate where this one go.. */ - /* it is "possibly" this register. */ - - pPossible = ((uint32_t *)(void *)(((char *)(&(pChip->cfg))) + pReg->struct_offset)); - - /* well? Is it this register */ - if (pPossible == goes_here) { - /* Jump for joy! */ - return pReg; - } - - /* next... */ - pReg++; - } - /* This is *TOTAL*PANIC* - we are totally screwed. */ - LOG_ERROR("INVALID SAM4 REGISTER"); - return NULL; -} - -static int sam4_ReadThisReg(struct sam4_chip *pChip, uint32_t *goes_here) -{ - const struct sam4_reg_list *pReg; - int r; - - pReg = sam4_GetReg(pChip, goes_here); - if (!pReg) - return ERROR_FAIL; - - r = target_read_u32(pChip->target, pReg->address, goes_here); - if (r != ERROR_OK) { - LOG_ERROR("Cannot read SAM4 register: %s @ 0x%08x, Err: %d", - pReg->name, (unsigned)(pReg->address), r); - } - return r; -} - -static int sam4_ReadAllRegs(struct sam4_chip *pChip) -{ - int r; - const struct sam4_reg_list *pReg; - - pReg = &(sam4_all_regs[0]); - while (pReg->name) { - r = sam4_ReadThisReg(pChip, - sam4_get_reg_ptr(&(pChip->cfg), pReg)); - if (r != ERROR_OK) { - LOG_ERROR("Cannot read SAM4 register: %s @ 0x%08x, Error: %d", - pReg->name, ((unsigned)(pReg->address)), r); - return r; - } - pReg++; - } - - return ERROR_OK; -} - -static int sam4_GetInfo(struct sam4_chip *pChip) -{ - const struct sam4_reg_list *pReg; - uint32_t regval; - - pReg = &(sam4_all_regs[0]); - while (pReg->name) { - /* display all regs */ - LOG_DEBUG("Start: %s", pReg->name); - regval = *sam4_get_reg_ptr(&(pChip->cfg), pReg); - LOG_USER("%*s: [0x%08" PRIx32 "] -> 0x%08" PRIx32, - REG_NAME_WIDTH, - pReg->name, - pReg->address, - regval); - if (pReg->explain_func) - (*(pReg->explain_func))(pChip); - LOG_DEBUG("End: %s", pReg->name); - pReg++; - } - LOG_USER(" rc-osc: %3.03f MHz", _tomhz(pChip->cfg.rc_freq)); - LOG_USER(" mainosc: %3.03f MHz", _tomhz(pChip->cfg.mainosc_freq)); - LOG_USER(" plla: %3.03f MHz", _tomhz(pChip->cfg.plla_freq)); - LOG_USER(" cpu-freq: %3.03f MHz", _tomhz(pChip->cfg.cpu_freq)); - LOG_USER("mclk-freq: %3.03f MHz", _tomhz(pChip->cfg.mclk_freq)); - - LOG_USER(" UniqueId: 0x%08" PRIx32 " 0x%08" PRIx32 " 0x%08" PRIx32 " 0x%08"PRIx32, - pChip->cfg.unique_id[0], - pChip->cfg.unique_id[1], - pChip->cfg.unique_id[2], - pChip->cfg.unique_id[3]); - - return ERROR_OK; -} - -static int sam4_protect_check(struct flash_bank *bank) -{ - int r; - uint32_t v[4] = {0}; - unsigned x; - struct sam4_bank_private *pPrivate; - - LOG_DEBUG("Begin"); - if (bank->target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - pPrivate = get_sam4_bank_private(bank); - if (!pPrivate) { - LOG_ERROR("no private for this bank?"); - return ERROR_FAIL; - } - if (!(pPrivate->probed)) - return ERROR_FLASH_BANK_NOT_PROBED; - - r = FLASHD_GetLockBits(pPrivate, v); - if (r != ERROR_OK) { - LOG_DEBUG("Failed: %d", r); - return r; - } - - for (x = 0; x < pPrivate->nsectors; x++) - bank->sectors[x].is_protected = (!!(v[x >> 5] & (1 << (x % 32)))); - LOG_DEBUG("Done"); - return ERROR_OK; -} - -FLASH_BANK_COMMAND_HANDLER(sam4_flash_bank_command) -{ - struct sam4_chip *pChip; - - pChip = all_sam4_chips; - - /* is this an existing chip? */ - while (pChip) { - if (pChip->target == bank->target) - break; - pChip = pChip->next; - } - - if (!pChip) { - /* this is a *NEW* chip */ - pChip = calloc(1, sizeof(struct sam4_chip)); - if (!pChip) { - LOG_ERROR("NO RAM!"); - return ERROR_FAIL; - } - pChip->target = bank->target; - /* insert at head */ - pChip->next = all_sam4_chips; - all_sam4_chips = pChip; - pChip->target = bank->target; - /* assumption is this runs at 32khz */ - pChip->cfg.slow_freq = 32768; - pChip->probed = 0; - } - - switch (bank->base) { - default: - LOG_ERROR("Address 0x%08x invalid bank address (try 0x%08x" - "[at91sam4s series] )", - ((unsigned int)(bank->base)), - ((unsigned int)(FLASH_BANK_BASE_S))); - return ERROR_FAIL; - break; - - /* at91sam4s series only has bank 0*/ - /* at91sam4sd series has the same address for bank 0 (FLASH_BANK0_BASE_SD)*/ - case FLASH_BANK_BASE_S: - 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 */ - case FLASH_BANK1_BASE_1024K_SD: - case FLASH_BANK1_BASE_2048K_SD: - bank->driver_priv = &(pChip->details.bank[1]); - bank->bank_number = 1; - pChip->details.bank[1].pChip = pChip; - pChip->details.bank[1].pBank = bank; - break; - } - - /* we initialize after probing. */ - return ERROR_OK; -} - -static int sam4_GetDetails(struct sam4_bank_private *pPrivate) -{ - const struct sam4_chip_details *pDetails; - struct sam4_chip *pChip; - struct flash_bank *saved_banks[SAM4_MAX_FLASH_BANKS]; - unsigned x; - - LOG_DEBUG("Begin"); - pDetails = all_sam4_details; - while (pDetails->name) { - /* Compare cidr without version bits */ - if (pDetails->chipid_cidr == (pPrivate->pChip->cfg.CHIPID_CIDR & 0xFFFFFFE0)) - break; - else - pDetails++; - } - if (pDetails->name == NULL) { - LOG_ERROR("SAM4 ChipID 0x%08x not found in table (perhaps you can ID this chip?)", - (unsigned int)(pPrivate->pChip->cfg.CHIPID_CIDR)); - /* Help the victim, print details about the chip */ - LOG_INFO("SAM4 CHIPID_CIDR: 0x%08" PRIx32 " decodes as follows", - pPrivate->pChip->cfg.CHIPID_CIDR); - sam4_explain_chipid_cidr(pPrivate->pChip); - return ERROR_FAIL; - } - - /* DANGER: THERE ARE DRAGONS HERE */ - - /* get our pChip - it is going */ - /* to be over-written shortly */ - pChip = pPrivate->pChip; - - /* Note that, in reality: */ - /* */ - /* pPrivate = &(pChip->details.bank[0]) */ - /* or pPrivate = &(pChip->details.bank[1]) */ - /* */ - - /* save the "bank" pointers */ - for (x = 0; x < SAM4_MAX_FLASH_BANKS; x++) - saved_banks[x] = pChip->details.bank[x].pBank; - - /* Overwrite the "details" structure. */ - memcpy(&(pPrivate->pChip->details), - pDetails, - sizeof(pPrivate->pChip->details)); - - /* now fix the ghosted pointers */ - for (x = 0; x < SAM4_MAX_FLASH_BANKS; x++) { - pChip->details.bank[x].pChip = pChip; - pChip->details.bank[x].pBank = saved_banks[x]; - } - - /* update the *BANK*SIZE* */ - - LOG_DEBUG("End"); - return ERROR_OK; -} - -static int _sam4_probe(struct flash_bank *bank, int noise) -{ - unsigned x; - int r; - struct sam4_bank_private *pPrivate; - - - LOG_DEBUG("Begin: Bank: %d, Noise: %d", bank->bank_number, noise); - if (bank->target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - pPrivate = get_sam4_bank_private(bank); - if (!pPrivate) { - LOG_ERROR("Invalid/unknown bank number"); - return ERROR_FAIL; - } - - r = sam4_ReadAllRegs(pPrivate->pChip); - if (r != ERROR_OK) - return r; - - LOG_DEBUG("Here"); - if (pPrivate->pChip->probed) - r = sam4_GetInfo(pPrivate->pChip); - else - r = sam4_GetDetails(pPrivate); - if (r != ERROR_OK) - return r; - - /* update the flash bank size */ - for (x = 0; x < SAM4_MAX_FLASH_BANKS; x++) { - if (bank->base == pPrivate->pChip->details.bank[x].base_address) { - bank->size = pPrivate->pChip->details.bank[x].size_bytes; - break; - } - } - - if (bank->sectors == NULL) { - bank->sectors = calloc(pPrivate->nsectors, (sizeof((bank->sectors)[0]))); - if (bank->sectors == NULL) { - LOG_ERROR("No memory!"); - return ERROR_FAIL; - } - bank->num_sectors = pPrivate->nsectors; - - for (x = 0; ((int)(x)) < bank->num_sectors; x++) { - bank->sectors[x].size = pPrivate->sector_size; - bank->sectors[x].offset = x * (pPrivate->sector_size); - /* mark as unknown */ - bank->sectors[x].is_erased = -1; - bank->sectors[x].is_protected = -1; - } - } - - pPrivate->probed = 1; - - r = sam4_protect_check(bank); - if (r != ERROR_OK) - return r; - - LOG_DEBUG("Bank = %d, nbanks = %d", - pPrivate->bank_number, pPrivate->pChip->details.n_banks); - if ((pPrivate->bank_number + 1) == pPrivate->pChip->details.n_banks) { - /* read unique id, */ - /* it appears to be associated with the *last* flash bank. */ - FLASHD_ReadUniqueID(pPrivate); - } - - return r; -} - -static int sam4_probe(struct flash_bank *bank) -{ - return _sam4_probe(bank, 1); -} - -static int sam4_auto_probe(struct flash_bank *bank) -{ - return _sam4_probe(bank, 0); -} - -static int sam4_erase(struct flash_bank *bank, int first, int last) -{ - struct sam4_bank_private *pPrivate; - int r; - int i; - int pageCount; - /*16 pages equals 8KB - Same size as a lock region*/ - pageCount = 16; - uint32_t status; - - LOG_DEBUG("Here"); - if (bank->target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - r = sam4_auto_probe(bank); - if (r != ERROR_OK) { - LOG_DEBUG("Here,r=%d", r); - return r; - } - - pPrivate = get_sam4_bank_private(bank); - if (!(pPrivate->probed)) - return ERROR_FLASH_BANK_NOT_PROBED; - - if ((first == 0) && ((last + 1) == ((int)(pPrivate->nsectors)))) { - /* whole chip */ - LOG_DEBUG("Here"); - return FLASHD_EraseEntireBank(pPrivate); - } - LOG_INFO("sam4 does not auto-erase while programming (Erasing relevant sectors)"); - LOG_INFO("sam4 First: 0x%08x Last: 0x%08x", (unsigned int)(first), (unsigned int)(last)); - for (i = first; i <= last; i++) { - /*16 pages equals 8KB - Same size as a lock region*/ - r = FLASHD_ErasePages(pPrivate, (i * pageCount), pageCount, &status); - LOG_INFO("Erasing sector: 0x%08x", (unsigned int)(i)); - if (r != ERROR_OK) - LOG_ERROR("SAM4: Error performing Erase page @ lock region number %d", - (unsigned int)(i)); - if (status & (1 << 2)) { - LOG_ERROR("SAM4: Lock Region %d is locked", (unsigned int)(i)); - return ERROR_FAIL; - } - if (status & (1 << 1)) { - LOG_ERROR("SAM4: Flash Command error @lock region %d", (unsigned int)(i)); - return ERROR_FAIL; - } - } - - return ERROR_OK; -} - -static int sam4_protect(struct flash_bank *bank, int set, int first, int last) -{ - struct sam4_bank_private *pPrivate; - int r; - - LOG_DEBUG("Here"); - if (bank->target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - pPrivate = get_sam4_bank_private(bank); - if (!(pPrivate->probed)) - return ERROR_FLASH_BANK_NOT_PROBED; - - if (set) - r = FLASHD_Lock(pPrivate, (unsigned)(first), (unsigned)(last)); - else - r = FLASHD_Unlock(pPrivate, (unsigned)(first), (unsigned)(last)); - LOG_DEBUG("End: r=%d", r); - - return r; - -} - -static int sam4_page_read(struct sam4_bank_private *pPrivate, unsigned pagenum, uint8_t *buf) -{ - uint32_t adr; - int r; - - adr = pagenum * pPrivate->page_size; - adr = adr + pPrivate->base_address; - - r = target_read_memory(pPrivate->pChip->target, - adr, - 4, /* THIS*MUST*BE* in 32bit values */ - pPrivate->page_size / 4, - buf); - if (r != ERROR_OK) - LOG_ERROR("SAM4: Flash program failed to read page phys address: 0x%08x", - (unsigned int)(adr)); - return r; -} - -static int sam4_page_write(struct sam4_bank_private *pPrivate, unsigned pagenum, const uint8_t *buf) -{ - uint32_t adr; - uint32_t status; - uint32_t fmr; /* EEFC Flash Mode Register */ - int r; - - adr = pagenum * pPrivate->page_size; - adr = (adr + pPrivate->base_address); - - /* Get flash mode register value */ - r = target_read_u32(pPrivate->pChip->target, pPrivate->controller_address, &fmr); - if (r != ERROR_OK) - LOG_DEBUG("Error Read failed: read flash mode register"); - - /* Clear flash wait state field */ - fmr &= 0xfffff0ff; - - /* set FWS (flash wait states) field in the FMR (flash mode register) */ - fmr |= (pPrivate->flash_wait_states << 8); - - LOG_DEBUG("Flash Mode: 0x%08x", ((unsigned int)(fmr))); - r = target_write_u32(pPrivate->pBank->target, pPrivate->controller_address, fmr); - if (r != ERROR_OK) - LOG_DEBUG("Error Write failed: set flash mode register"); - - /* 1st sector 8kBytes - page 0 - 15*/ - /* 2nd sector 8kBytes - page 16 - 30*/ - /* 3rd sector 48kBytes - page 31 - 127*/ - LOG_DEBUG("Wr Page %u @ phys address: 0x%08x", pagenum, (unsigned int)(adr)); - r = target_write_memory(pPrivate->pChip->target, - adr, - 4, /* THIS*MUST*BE* in 32bit values */ - pPrivate->page_size / 4, - buf); - if (r != ERROR_OK) { - LOG_ERROR("SAM4: Failed to write (buffer) page at phys address 0x%08x", - (unsigned int)(adr)); - return r; - } - - r = EFC_PerformCommand(pPrivate, - /* send Erase & Write Page */ - AT91C_EFC_FCMD_WP, /*AT91C_EFC_FCMD_EWP only works on first two 8kb sectors*/ - pagenum, - &status); - - if (r != ERROR_OK) - LOG_ERROR("SAM4: Error performing Write page @ phys address 0x%08x", - (unsigned int)(adr)); - if (status & (1 << 2)) { - LOG_ERROR("SAM4: Page @ Phys address 0x%08x is locked", (unsigned int)(adr)); - return ERROR_FAIL; - } - if (status & (1 << 1)) { - LOG_ERROR("SAM4: Flash Command error @phys address 0x%08x", (unsigned int)(adr)); - return ERROR_FAIL; - } - return ERROR_OK; -} - -static int sam4_write(struct flash_bank *bank, - const uint8_t *buffer, - uint32_t offset, - uint32_t count) -{ - int n; - unsigned page_cur; - unsigned page_end; - int r; - unsigned page_offset; - struct sam4_bank_private *pPrivate; - uint8_t *pagebuffer; - - /* incase we bail further below, set this to null */ - pagebuffer = NULL; - - /* ignore dumb requests */ - if (count == 0) { - r = ERROR_OK; - goto done; - } - - if (bank->target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - r = ERROR_TARGET_NOT_HALTED; - goto done; - } - - pPrivate = get_sam4_bank_private(bank); - if (!(pPrivate->probed)) { - r = ERROR_FLASH_BANK_NOT_PROBED; - goto done; - } - - if ((offset + count) > pPrivate->size_bytes) { - LOG_ERROR("Flash write error - past end of bank"); - LOG_ERROR(" offset: 0x%08x, count 0x%08x, BankEnd: 0x%08x", - (unsigned int)(offset), - (unsigned int)(count), - (unsigned int)(pPrivate->size_bytes)); - r = ERROR_FAIL; - goto done; - } - - pagebuffer = malloc(pPrivate->page_size); - if (!pagebuffer) { - LOG_ERROR("No memory for %d Byte page buffer", (int)(pPrivate->page_size)); - r = ERROR_FAIL; - goto done; - } - - /* what page do we start & end in? */ - page_cur = offset / pPrivate->page_size; - page_end = (offset + count - 1) / pPrivate->page_size; - - LOG_DEBUG("Offset: 0x%08x, Count: 0x%08x", (unsigned int)(offset), (unsigned int)(count)); - LOG_DEBUG("Page start: %d, Page End: %d", (int)(page_cur), (int)(page_end)); - - /* Special case: all one page */ - /* */ - /* Otherwise: */ - /* (1) non-aligned start */ - /* (2) body pages */ - /* (3) non-aligned end. */ - - /* Handle special case - all one page. */ - if (page_cur == page_end) { - LOG_DEBUG("Special case, all in one page"); - r = sam4_page_read(pPrivate, page_cur, pagebuffer); - if (r != ERROR_OK) - goto done; - - page_offset = (offset & (pPrivate->page_size-1)); - memcpy(pagebuffer + page_offset, - buffer, - count); - - r = sam4_page_write(pPrivate, page_cur, pagebuffer); - if (r != ERROR_OK) - goto done; - r = ERROR_OK; - goto done; - } - - /* non-aligned start */ - page_offset = offset & (pPrivate->page_size - 1); - if (page_offset) { - LOG_DEBUG("Not-Aligned start"); - /* read the partial */ - r = sam4_page_read(pPrivate, page_cur, pagebuffer); - if (r != ERROR_OK) - goto done; - - /* over-write with new data */ - n = (pPrivate->page_size - page_offset); - memcpy(pagebuffer + page_offset, - buffer, - n); - - r = sam4_page_write(pPrivate, page_cur, pagebuffer); - if (r != ERROR_OK) - goto done; - - count -= n; - offset += n; - buffer += n; - page_cur++; - } - - /* By checking that offset is correct here, we also - fix a clang warning */ - assert(offset % pPrivate->page_size == 0); - - /* intermediate large pages */ - /* also - the final *terminal* */ - /* if that terminal page is a full page */ - LOG_DEBUG("Full Page Loop: cur=%d, end=%d, count = 0x%08x", - (int)page_cur, (int)page_end, (unsigned int)(count)); - - while ((page_cur < page_end) && - (count >= pPrivate->page_size)) { - r = sam4_page_write(pPrivate, page_cur, buffer); - if (r != ERROR_OK) - goto done; - count -= pPrivate->page_size; - buffer += pPrivate->page_size; - page_cur += 1; - } - - /* terminal partial page? */ - if (count) { - LOG_DEBUG("Terminal partial page, count = 0x%08x", (unsigned int)(count)); - /* we have a partial page */ - r = sam4_page_read(pPrivate, page_cur, pagebuffer); - if (r != ERROR_OK) - goto done; - /* data goes at start */ - memcpy(pagebuffer, buffer, count); - r = sam4_page_write(pPrivate, page_cur, pagebuffer); - if (r != ERROR_OK) - goto done; - } - LOG_DEBUG("Done!"); - r = ERROR_OK; -done: - if (pagebuffer) - free(pagebuffer); - return r; -} - -COMMAND_HANDLER(sam4_handle_info_command) -{ - struct sam4_chip *pChip; - pChip = get_current_sam4(CMD_CTX); - if (!pChip) - return ERROR_OK; - - unsigned x; - int r; - - /* bank0 must exist before we can do anything */ - if (pChip->details.bank[0].pBank == NULL) { - x = 0; -need_define: - command_print(CMD_CTX, - "Please define bank %d via command: flash bank %s ... ", - x, - at91sam4_flash.name); - return ERROR_FAIL; - } - - /* if bank 0 is not probed, then probe it */ - if (!(pChip->details.bank[0].probed)) { - r = sam4_auto_probe(pChip->details.bank[0].pBank); - if (r != ERROR_OK) - return ERROR_FAIL; - } - /* above guarantees the "chip details" structure is valid */ - /* and thus, bank private areas are valid */ - /* and we have a SAM4 chip, what a concept! */ - - /* auto-probe other banks, 0 done above */ - for (x = 1; x < SAM4_MAX_FLASH_BANKS; x++) { - /* skip banks not present */ - if (!(pChip->details.bank[x].present)) - continue; - - if (pChip->details.bank[x].pBank == NULL) - goto need_define; - - if (pChip->details.bank[x].probed) - continue; - - r = sam4_auto_probe(pChip->details.bank[x].pBank); - if (r != ERROR_OK) - return r; - } - - r = sam4_GetInfo(pChip); - if (r != ERROR_OK) { - LOG_DEBUG("Sam4Info, Failed %d", r); - return r; - } - - return ERROR_OK; -} - -COMMAND_HANDLER(sam4_handle_gpnvm_command) -{ - unsigned x, v; - int r, who; - struct sam4_chip *pChip; - - pChip = get_current_sam4(CMD_CTX); - if (!pChip) - return ERROR_OK; - - if (pChip->target->state != TARGET_HALTED) { - LOG_ERROR("sam4 - target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - if (pChip->details.bank[0].pBank == NULL) { - command_print(CMD_CTX, "Bank0 must be defined first via: flash bank %s ...", - at91sam4_flash.name); - return ERROR_FAIL; - } - if (!pChip->details.bank[0].probed) { - r = sam4_auto_probe(pChip->details.bank[0].pBank); - if (r != ERROR_OK) - return r; - } - - switch (CMD_ARGC) { - default: - return ERROR_COMMAND_SYNTAX_ERROR; - break; - case 0: - goto showall; - break; - case 1: - who = -1; - break; - case 2: - if ((0 == strcmp(CMD_ARGV[0], "show")) && (0 == strcmp(CMD_ARGV[1], "all"))) - who = -1; - else { - uint32_t v32; - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], v32); - who = v32; - } - break; - } - - if (0 == strcmp("show", CMD_ARGV[0])) { - if (who == -1) { -showall: - r = ERROR_OK; - for (x = 0; x < pChip->details.n_gpnvms; x++) { - r = FLASHD_GetGPNVM(&(pChip->details.bank[0]), x, &v); - if (r != ERROR_OK) - break; - command_print(CMD_CTX, "sam4-gpnvm%u: %u", x, v); - } - return r; - } - if ((who >= 0) && (((unsigned)(who)) < pChip->details.n_gpnvms)) { - r = FLASHD_GetGPNVM(&(pChip->details.bank[0]), who, &v); - command_print(CMD_CTX, "sam4-gpnvm%u: %u", who, v); - return r; - } else { - command_print(CMD_CTX, "sam4-gpnvm invalid GPNVM: %u", who); - return ERROR_COMMAND_SYNTAX_ERROR; - } - } - - if (who == -1) { - command_print(CMD_CTX, "Missing GPNVM number"); - return ERROR_COMMAND_SYNTAX_ERROR; - } - - if (0 == strcmp("set", CMD_ARGV[0])) - r = FLASHD_SetGPNVM(&(pChip->details.bank[0]), who); - else if ((0 == strcmp("clr", CMD_ARGV[0])) || - (0 == strcmp("clear", CMD_ARGV[0]))) /* quietly accept both */ - r = FLASHD_ClrGPNVM(&(pChip->details.bank[0]), who); - else { - command_print(CMD_CTX, "Unknown command: %s", CMD_ARGV[0]); - r = ERROR_COMMAND_SYNTAX_ERROR; - } - return r; -} - -COMMAND_HANDLER(sam4_handle_slowclk_command) -{ - struct sam4_chip *pChip; - - pChip = get_current_sam4(CMD_CTX); - if (!pChip) - return ERROR_OK; - - switch (CMD_ARGC) { - case 0: - /* show */ - break; - case 1: - { - /* set */ - uint32_t v; - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], v); - if (v > 200000) { - /* absurd slow clock of 200Khz? */ - command_print(CMD_CTX, "Absurd/illegal slow clock freq: %d\n", (int)(v)); - return ERROR_COMMAND_SYNTAX_ERROR; - } - pChip->cfg.slow_freq = v; - break; - } - default: - /* error */ - command_print(CMD_CTX, "Too many parameters"); - return ERROR_COMMAND_SYNTAX_ERROR; - break; - } - command_print(CMD_CTX, "Slowclk freq: %d.%03dkhz", - (int)(pChip->cfg.slow_freq / 1000), - (int)(pChip->cfg.slow_freq % 1000)); - return ERROR_OK; -} - -static const struct command_registration at91sam4_exec_command_handlers[] = { - { - .name = "gpnvm", - .handler = sam4_handle_gpnvm_command, - .mode = COMMAND_EXEC, - .usage = "[('clr'|'set'|'show') bitnum]", - .help = "Without arguments, shows all bits in the gpnvm " - "register. Otherwise, clears, sets, or shows one " - "General Purpose Non-Volatile Memory (gpnvm) bit.", - }, - { - .name = "info", - .handler = sam4_handle_info_command, - .mode = COMMAND_EXEC, - .help = "Print information about the current at91sam4 chip" - "and its flash configuration.", - }, - { - .name = "slowclk", - .handler = sam4_handle_slowclk_command, - .mode = COMMAND_EXEC, - .usage = "[clock_hz]", - .help = "Display or set the slowclock frequency " - "(default 32768 Hz).", - }, - COMMAND_REGISTRATION_DONE -}; -static const struct command_registration at91sam4_command_handlers[] = { - { - .name = "at91sam4", - .mode = COMMAND_ANY, - .help = "at91sam4 flash command group", - .usage = "", - .chain = at91sam4_exec_command_handlers, - }, - COMMAND_REGISTRATION_DONE -}; - -struct flash_driver at91sam4_flash = { - .name = "at91sam4", - .commands = at91sam4_command_handlers, - .flash_bank_command = sam4_flash_bank_command, - .erase = sam4_erase, - .protect = sam4_protect, - .write = sam4_write, - .read = default_flash_read, - .probe = sam4_probe, - .auto_probe = sam4_auto_probe, - .erase_check = default_flash_blank_check, - .protect_check = sam4_protect_check, -}; diff --git a/src/flash/nor/at91sam4l.c b/src/flash/nor/at91sam4l.c deleted file mode 100644 index 4710512ab..000000000 --- a/src/flash/nor/at91sam4l.c +++ /dev/null @@ -1,707 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2013 by Andrey Yurovsky * - * Andrey Yurovsky * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 -#include "config.h" -#endif - -#include "imp.h" - -#include - -/* At this time, the SAM4L Flash is available in these capacities: - * ATSAM4Lx4xx: 256KB (512 pages) - * ATSAM4Lx2xx: 128KB (256 pages) - * ATSAM4Lx8xx: 512KB (1024 pages) - */ - -/* There are 16 lockable regions regardless of overall capacity. The number - * of pages per sector is therefore dependant on capacity. */ -#define SAM4L_NUM_SECTORS 16 - -/* Locations in memory map */ -#define SAM4L_FLASH ((uint32_t)0x00000000) /* Flash region */ -#define SAM4L_FLASH_USER 0x00800000 /* Flash user page region */ -#define SAM4L_FLASHCALW 0x400A0000 /* Flash controller */ -#define SAM4L_CHIPID 0x400E0740 /* Chip Identification */ - -/* Offsets from SAM4L_FLASHCALW */ -#define SAM4L_FCR 0x00 /* Flash Control Register (RW) */ -#define SAM4L_FCMD 0x04 /* Flash Command Register (RW) */ -#define SAM4L_FSR 0x08 /* Flash Status Register (RO) */ -#define SAM4L_FPR 0x0C /* Flash Parameter Register (RO) */ -#define SAM4L_FVR 0x10 /* Flash Version Register (RO) */ -#define SAM4L_FGPFRHI 0x14 /* Flash General Purpose Register High (RO) */ -#define SAM4L_FGPFRLO 0x18 /* Flash General Purpose Register Low (RO) */ - -/* Offsets from SAM4L_CHIPID */ -#define SAM4L_CIDR 0x00 /* Chip ID Register (RO) */ -#define SAM4L_EXID 0x04 /* Chip ID Extension Register (RO) */ - -/* Flash commands (for SAM4L_FCMD), see Table 14-5 */ -#define SAM4L_FCMD_NOP 0 /* No Operation */ -#define SAM4L_FCMD_WP 1 /* Write Page */ -#define SAM4L_FCMD_EP 2 /* Erase Page */ -#define SAM4L_FCMD_CPB 3 /* Clear Page Buffer */ -#define SAM4L_FCMD_LP 4 /* Lock region containing given page */ -#define SAM4L_FCMD_UP 5 /* Unlock region containing given page */ -#define SAM4L_FCMD_EA 6 /* Erase All */ -#define SAM4L_FCMD_WGPB 7 /* Write general-purpose fuse bit */ -#define SAM4L_FCMD_EGPB 8 /* Erase general-purpose fuse bit */ -#define SAM4L_FCMD_SSB 9 /* Set security fuses */ -#define SAM4L_FCMD_PGPFB 10 /* Program general-purpose fuse byte */ -#define SAM4L_FCMD_EAGPF 11 /* Erase all general-purpose fuse bits */ -#define SAM4L_FCMD_QPR 12 /* Quick page read */ -#define SAM4L_FCMD_WUP 13 /* Write user page */ -#define SAM4L_FCMD_EUP 14 /* Erase user page */ -#define SAM4L_FCMD_QPRUP 15 /* Quick page read (user page) */ -#define SAM4L_FCMD_HSEN 16 /* High speed mode enable */ -#define SAM4L_FCMD_HSDIS 17 /* High speed mode disable */ - -#define SAM4L_FMCD_CMDKEY 0xA5UL /* 'key' to issue commands, see 14.10.2 */ - - -/* SMAP registers and bits */ -#define SMAP_BASE 0x400A3000 - -#define SMAP_SCR (SMAP_BASE + 8) -#define SMAP_SCR_HCR (1 << 1) - - -struct sam4l_chip_info { - uint32_t id; - uint32_t exid; - const char *name; -}; - -/* These are taken from Table 9-1 in 42023E-SAM-07/2013 */ -static const struct sam4l_chip_info sam4l_known_chips[] = { - { 0xAB0B0AE0, 0x1400000F, "ATSAM4LC8C" }, - { 0xAB0A09E0, 0x0400000F, "ATSAM4LC4C" }, - { 0xAB0A07E0, 0x0400000F, "ATSAM4LC2C" }, - { 0xAB0B0AE0, 0x1300000F, "ATSAM4LC8B" }, - { 0xAB0A09E0, 0x0300000F, "ATSAM4LC4B" }, - { 0xAB0A07E0, 0x0300000F, "ATSAM4LC2B" }, - { 0xAB0B0AE0, 0x1200000F, "ATSAM4LC8A" }, - { 0xAB0A09E0, 0x0200000F, "ATSAM4LC4A" }, - { 0xAB0A07E0, 0x0200000F, "ATSAM4LC2A" }, - { 0xAB0B0AE0, 0x14000002, "ATSAM4LS8C" }, - { 0xAB0A09E0, 0x04000002, "ATSAM4LS4C" }, - { 0xAB0A07E0, 0x04000002, "ATSAM4LS2C" }, - { 0xAB0B0AE0, 0x13000002, "ATSAM4LS8B" }, - { 0xAB0A09E0, 0x03000002, "ATSAM4LS4B" }, - { 0xAB0A07E0, 0x03000002, "ATSAM4LS2B" }, - { 0xAB0B0AE0, 0x12000002, "ATSAM4LS8A" }, - { 0xAB0A09E0, 0x02000002, "ATSAM4LS4A" }, - { 0xAB0A07E0, 0x02000002, "ATSAM4LS2A" }, -}; - -/* Meaning of SRAMSIZ field in CHIPID, see 9.3.1 in 42023E-SAM-07/2013 */ -static const uint16_t sam4l_ram_sizes[16] = { 48, 1, 2, 6, 24, 4, 80, 160, 8, 16, 32, 64, 128, 256, 96, 512 }; - -/* Meaning of PSZ field in FPR, see 14.10.4 in 42023E-SAM-07/2013 */ -static const uint16_t sam4l_page_sizes[8] = { 32, 64, 128, 256, 512, 1024, 2048, 4096 }; - -struct sam4l_info { - const struct sam4l_chip_info *details; - - uint32_t flash_kb; - uint32_t ram_kb; - uint32_t page_size; - int num_pages; - int sector_size; - int pages_per_sector; - - bool probed; - struct target *target; - struct sam4l_info *next; -}; - -static struct sam4l_info *sam4l_chips; - -static int sam4l_flash_wait_until_ready(struct target *target) -{ - volatile unsigned int t = 0; - uint32_t st; - int res; - - /* Poll the status register until the FRDY bit is set */ - do { - res = target_read_u32(target, SAM4L_FLASHCALW + SAM4L_FSR, &st); - } while (res == ERROR_OK && !(st & (1<<0)) && ++t < 10); - - return res; -} - -static int sam4l_flash_check_error(struct target *target, uint32_t *err) -{ - uint32_t st; - int res; - - res = target_read_u32(target, SAM4L_FLASHCALW + SAM4L_FSR, &st); - - if (res == ERROR_OK) - *err = st & ((1<<3) | (1<<2)); /* grab PROGE and LOCKE bits */ - - return res; -} - -static int sam4l_flash_command(struct target *target, uint8_t cmd, int page) -{ - int res; - uint32_t fcmd; - uint32_t err; - - res = sam4l_flash_wait_until_ready(target); - if (res != ERROR_OK) - return res; - - if (page >= 0) { - /* Set the page number. For some commands, the page number is just an - * argument (ex: fuse bit number). */ - fcmd = (SAM4L_FMCD_CMDKEY << 24) | ((page & 0xFFFF) << 8) | (cmd & 0x3F); - } else { - /* Reuse the page number that was read from the flash command register. */ - res = target_read_u32(target, SAM4L_FLASHCALW + SAM4L_FCMD, &fcmd); - if (res != ERROR_OK) - return res; - - fcmd &= ~0x3F; /* clear out the command code */ - fcmd |= (SAM4L_FMCD_CMDKEY << 24) | (cmd & 0x3F); - } - - /* Send the command */ - res = target_write_u32(target, SAM4L_FLASHCALW + SAM4L_FCMD, fcmd); - if (res != ERROR_OK) - return res; - - res = sam4l_flash_check_error(target, &err); - if (res != ERROR_OK) - return res; - - if (err != 0) - LOG_ERROR("%s got error status 0x%08" PRIx32, __func__, err); - - res = sam4l_flash_wait_until_ready(target); - - return res; -} - -FLASH_BANK_COMMAND_HANDLER(sam4l_flash_bank_command) -{ - struct sam4l_info *chip = sam4l_chips; - - while (chip) { - if (chip->target == bank->target) - break; - chip = chip->next; - } - - if (!chip) { - /* Create a new chip */ - chip = calloc(1, sizeof(*chip)); - if (!chip) - return ERROR_FAIL; - - chip->target = bank->target; - chip->probed = false; - - bank->driver_priv = chip; - - /* Insert it into the chips list (at head) */ - chip->next = sam4l_chips; - sam4l_chips = chip; - } - - if (bank->base != SAM4L_FLASH) { - LOG_ERROR("Address 0x%08" PRIx32 " invalid bank address (try 0x%08" PRIx32 - "[at91sam4l series] )", - bank->base, SAM4L_FLASH); - return ERROR_FAIL; - } - - return ERROR_OK; -} - -static const struct sam4l_chip_info *sam4l_find_chip_name(uint32_t id, uint32_t exid) -{ - unsigned int i; - - id &= ~0xF; - - for (i = 0; i < ARRAY_SIZE(sam4l_known_chips); i++) { - if (sam4l_known_chips[i].id == id && sam4l_known_chips[i].exid == exid) - return &sam4l_known_chips[i]; - } - - return NULL; -} - -static int sam4l_check_page_erased(struct flash_bank *bank, uint32_t pn, - bool *is_erased_p) -{ - int res; - uint32_t st; - - /* Issue a quick page read to verify that we've erased this page */ - res = sam4l_flash_command(bank->target, SAM4L_FCMD_QPR, pn); - if (res != ERROR_OK) { - LOG_ERROR("Quick page read %" PRIu32 " failed", pn); - return res; - } - - /* Retrieve the flash status */ - res = target_read_u32(bank->target, SAM4L_FLASHCALW + SAM4L_FSR, &st); - if (res != ERROR_OK) { - LOG_ERROR("Couldn't read erase status"); - return res; - } - - /* Is the page in question really erased? */ - *is_erased_p = !!(st & (1<<5)); - - return ERROR_OK; -} - -static int sam4l_probe(struct flash_bank *bank) -{ - uint32_t id, exid, param; - int res; - struct sam4l_info *chip = (struct sam4l_info *)bank->driver_priv; - - if (chip->probed) - return ERROR_OK; - - res = target_read_u32(bank->target, SAM4L_CHIPID + SAM4L_CIDR, &id); - if (res != ERROR_OK) { - LOG_ERROR("Couldn't read chip ID"); - return res; - } - - res = target_read_u32(bank->target, SAM4L_CHIPID + SAM4L_EXID, &exid); - if (res != ERROR_OK) { - LOG_ERROR("Couldn't read extended chip ID"); - return res; - } - - chip->details = sam4l_find_chip_name(id, exid); - - /* The RAM capacity is in a lookup table. */ - chip->ram_kb = sam4l_ram_sizes[0xF & (id >> 16)]; - - switch (0xF & (id >> 8)) { - case 0x07: - chip->flash_kb = 128; - break; - case 0x09: - chip->flash_kb = 256; - break; - case 0x0A: - chip->flash_kb = 512; - break; - default: - LOG_ERROR("Unknown flash size (chip ID is %08" PRIx32 "), assuming 128K", id); - chip->flash_kb = 128; - break; - } - - /* Retrieve the Flash parameters */ - res = target_read_u32(bank->target, SAM4L_FLASHCALW + SAM4L_FPR, ¶m); - if (res != ERROR_OK) { - LOG_ERROR("Couldn't read Flash parameters"); - return res; - } - - /* Fetch the page size from the parameter register. Technically the flash - * capacity is there too though the manual mentions that not all parts will - * have it set so we use the Chip ID capacity information instead. */ - chip->page_size = sam4l_page_sizes[0x7 & (param >> 8)]; - assert(chip->page_size); - chip->num_pages = chip->flash_kb * 1024 / chip->page_size; - - chip->sector_size = (chip->flash_kb * 1024) / SAM4L_NUM_SECTORS; - chip->pages_per_sector = chip->sector_size / chip->page_size; - - /* Make sure the bank size is correct */ - bank->size = chip->flash_kb * 1024; - - /* Allocate the sector table. */ - bank->num_sectors = SAM4L_NUM_SECTORS; - bank->sectors = calloc(bank->num_sectors, (sizeof((bank->sectors)[0]))); - if (!bank->sectors) - return ERROR_FAIL; - - /* Fill out the sector information: all SAM4L sectors are the same size and - * there is always a fixed number of them. */ - for (int i = 0; i < bank->num_sectors; i++) { - bank->sectors[i].size = chip->sector_size; - bank->sectors[i].offset = i * chip->sector_size; - /* mark as unknown */ - bank->sectors[i].is_erased = -1; - bank->sectors[i].is_protected = -1; - } - - /* Done */ - chip->probed = true; - - LOG_INFO("SAM4L MCU: %s (Rev %c) (%" PRIu32 "KB Flash with %d %" PRId32 "B pages, %" PRIu32 "KB RAM)", - chip->details ? chip->details->name : "unknown", (char)('A' + (id & 0xF)), - chip->flash_kb, chip->num_pages, chip->page_size, chip->ram_kb); - - return ERROR_OK; -} - -static int sam4l_protect_check(struct flash_bank *bank) -{ - int res; - uint32_t st; - struct sam4l_info *chip = (struct sam4l_info *)bank->driver_priv; - - if (bank->target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - - return ERROR_TARGET_NOT_HALTED; - } - - if (!chip->probed) { - if (sam4l_probe(bank) != ERROR_OK) - return ERROR_FLASH_BANK_NOT_PROBED; - } - - res = target_read_u32(bank->target, SAM4L_FLASHCALW + SAM4L_FSR, &st); - if (res != ERROR_OK) - return res; - - st >>= 16; /* There are 16 lock region bits in the upper half word */ - for (int i = 0; i < bank->num_sectors; i++) - bank->sectors[i].is_protected = !!(st & (1<target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - - return ERROR_TARGET_NOT_HALTED; - } - - if (!chip->probed) { - if (sam4l_probe(bank) != ERROR_OK) - return ERROR_FLASH_BANK_NOT_PROBED; - } - - /* Make sure the pages make sense. */ - if (first >= bank->num_sectors || last >= bank->num_sectors) { - LOG_ERROR("Protect range %d - %d not valid (%d sectors total)", first, last, - bank->num_sectors); - return ERROR_FAIL; - } - - /* Try to lock or unlock each sector in the range. This is done by locking - * a region containing one page in that sector, we arbitrarily choose the 0th - * page in the sector. */ - for (int i = first; i <= last; i++) { - int res; - - res = sam4l_flash_command(bank->target, - set ? SAM4L_FCMD_LP : SAM4L_FCMD_UP, i * chip->pages_per_sector); - if (res != ERROR_OK) { - LOG_ERROR("Can't %slock region containing page %d", set ? "" : "un", i); - return res; - } - } - - return ERROR_OK; -} - -static int sam4l_erase(struct flash_bank *bank, int first, int last) -{ - int ret; - struct sam4l_info *chip = (struct sam4l_info *)bank->driver_priv; - - if (bank->target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - - return ERROR_TARGET_NOT_HALTED; - } - - if (!chip->probed) { - if (sam4l_probe(bank) != ERROR_OK) - return ERROR_FLASH_BANK_NOT_PROBED; - } - - /* Make sure the pages make sense. */ - if (first >= bank->num_sectors || last >= bank->num_sectors) { - LOG_ERROR("Erase range %d - %d not valid (%d sectors total)", first, last, - bank->num_sectors); - return ERROR_FAIL; - } - - /* Erase */ - if ((first == 0) && ((last + 1) == bank->num_sectors)) { - LOG_DEBUG("Erasing the whole chip"); - - ret = sam4l_flash_command(bank->target, SAM4L_FCMD_EA, -1); - if (ret != ERROR_OK) { - LOG_ERROR("Erase All failed"); - return ret; - } - } else { - LOG_DEBUG("Erasing sectors %d through %d...\n", first, last); - - /* For each sector... */ - for (int i = first; i <= last; i++) { - /* For each page in that sector... */ - for (int j = 0; j < chip->pages_per_sector; j++) { - int pn = i * chip->pages_per_sector + j; - bool is_erased = false; - - /* Issue the page erase */ - ret = sam4l_flash_command(bank->target, SAM4L_FCMD_EP, pn); - if (ret != ERROR_OK) { - LOG_ERROR("Erasing page %d failed", pn); - return ret; - } - - ret = sam4l_check_page_erased(bank, pn, &is_erased); - if (ret != ERROR_OK) - return ret; - - if (!is_erased) { - LOG_DEBUG("Page %d was not erased.", pn); - return ERROR_FAIL; - } - } - - /* This sector is definitely erased. */ - bank->sectors[i].is_erased = 1; - } - } - - return ERROR_OK; -} - -/* Write an entire page from host buffer 'buf' to page-aligned 'address' in the - * Flash. */ -static int sam4l_write_page(struct sam4l_info *chip, struct target *target, - uint32_t address, const uint8_t *buf) -{ - int res; - - LOG_DEBUG("sam4l_write_page address=%08" PRIx32, address); - - /* Clear the page buffer before we write to it */ - res = sam4l_flash_command(target, SAM4L_FCMD_CPB, -1); - if (res != ERROR_OK) { - LOG_ERROR("%s: can't clear page buffer", __func__); - return res; - } - - /* Write the modified page back to the target's page buffer */ - res = target_write_memory(target, address, 4, chip->page_size / 4, buf); - - if (res != ERROR_OK) { - LOG_ERROR("%s: %d", __func__, __LINE__); - return res; - } - - /* Commit the page contents to Flash: erase the current page and then - * write it out. */ - res = sam4l_flash_command(target, SAM4L_FCMD_EP, -1); - if (res != ERROR_OK) - return res; - res = sam4l_flash_command(target, SAM4L_FCMD_WP, -1); - - return res; -} - -/* Write partial contents into page-aligned 'address' on the Flash from host - * buffer 'buf' by writing 'nb' of 'buf' at 'offset' into the Flash page. */ -static int sam4l_write_page_partial(struct sam4l_info *chip, - struct flash_bank *bank, uint32_t address, const uint8_t *buf, - uint32_t page_offset, uint32_t nb) -{ - int res; - uint8_t *pg = malloc(chip->page_size); - if (!pg) - return ERROR_FAIL; - - LOG_DEBUG("sam4l_write_page_partial address=%08" PRIx32 " nb=%08" PRIx32, address, nb); - - assert(page_offset + nb < chip->page_size); - assert((address % chip->page_size) == 0); - - /* Retrieve the full page contents from Flash */ - res = target_read_memory(bank->target, address, 4, - chip->page_size / 4, pg); - if (res != ERROR_OK) { - free(pg); - return res; - } - - /* Insert our partial page over the data from Flash */ - memcpy(pg + (page_offset % chip->page_size), buf, nb); - - /* Write the page back out */ - res = sam4l_write_page(chip, bank->target, address, pg); - free(pg); - - return res; -} - -static int sam4l_write(struct flash_bank *bank, const uint8_t *buffer, - uint32_t offset, uint32_t count) -{ - int res; - uint32_t nb = 0; - struct sam4l_info *chip = (struct sam4l_info *)bank->driver_priv; - - LOG_DEBUG("sam4l_write offset=%08" PRIx32 " count=%08" PRIx32, offset, count); - - if (bank->target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - - return ERROR_TARGET_NOT_HALTED; - } - - if (!chip->probed) { - if (sam4l_probe(bank) != ERROR_OK) - return ERROR_FLASH_BANK_NOT_PROBED; - } - - if (offset % chip->page_size) { - /* We're starting at an unaligned offset so we'll write a partial page - * comprising that offset and up to the end of that page. */ - nb = chip->page_size - (offset % chip->page_size); - if (nb > count) - nb = count; - } else if (count < chip->page_size) { - /* We're writing an aligned but partial page. */ - nb = count; - } - - if (nb > 0) { - res = sam4l_write_page_partial(chip, bank, - (offset / chip->page_size) * chip->page_size + bank->base, - buffer, - offset % chip->page_size, nb); - if (res != ERROR_OK) - return res; - - /* We're done with the page contents */ - count -= nb; - offset += nb; - } - - /* There's at least one aligned page to write out. */ - if (count >= chip->page_size) { - int np = count / chip->page_size + ((count % chip->page_size) ? 1 : 0); - - for (int i = 0; i < np; i++) { - if (count >= chip->page_size) { - res = sam4l_write_page(chip, bank->target, - bank->base + offset, - buffer + (i * chip->page_size)); - /* Advance one page */ - offset += chip->page_size; - count -= chip->page_size; - } else { - res = sam4l_write_page_partial(chip, bank, - bank->base + offset, - buffer + (i * chip->page_size), 0, count); - /* We're done after this. */ - offset += count; - count = 0; - } - - if (res != ERROR_OK) - return res; - } - } - - return ERROR_OK; -} - - -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(); - - /* In case of sysresetreq, debug retains state set in cortex_m_assert_reset() - * so we just release reset held by SMAP - * - * n_RESET (srst) clears the DP, so reenable debug and set vector catch here - * - * 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); - if (retval == ERROR_OK) - retval = mem_ap_write_atomic_u32(armv7m->debug_ap, 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); - if (retval2 != ERROR_OK) - return retval2; - - return retval; -} - -static const struct command_registration at91sam4l_exec_command_handlers[] = { - { - .name = "smap_reset_deassert", - .handler = sam4l_handle_reset_deassert, - .mode = COMMAND_EXEC, - .help = "deasert internal reset held by SMAP" - }, - COMMAND_REGISTRATION_DONE -}; - -static const struct command_registration at91sam4l_command_handlers[] = { - { - .name = "at91sam4l", - .mode = COMMAND_ANY, - .help = "at91sam4l flash command group", - .usage = "", - .chain = at91sam4l_exec_command_handlers, - }, - COMMAND_REGISTRATION_DONE -}; - -struct flash_driver at91sam4l_flash = { - .name = "at91sam4l", - .commands = at91sam4l_command_handlers, - .flash_bank_command = sam4l_flash_bank_command, - .erase = sam4l_erase, - .protect = sam4l_protect, - .write = sam4l_write, - .read = default_flash_read, - .probe = sam4l_probe, - .auto_probe = sam4l_probe, - .erase_check = default_flash_blank_check, - .protect_check = sam4l_protect_check, -}; diff --git a/src/flash/nor/at91sam7.c b/src/flash/nor/at91sam7.c deleted file mode 100644 index ccb1a74aa..000000000 --- a/src/flash/nor/at91sam7.c +++ /dev/null @@ -1,1203 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2006 by Magnus Lundin * - * lundin@mlu.mine.nu * - * * - * Copyright (C) 2008 by Gheorghe Guran (atlas) * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * -****************************************************************************/ - -/*************************************************************************** -* -* New flash setup command: -* -* flash bank -* [ -* -* -* ] -* -* - MUST be used if clock is from external source, -* CAN be used if main oscillator frequency is known (recommended) -* Examples: -* ==== RECOMMENDED (covers clock speed) ============ -* flash bank at91sam7 0x00100000 0 0 4 $_TARGETNAME AT91SAM7XC256 1 16 64 256 3 25000 -* (if auto-detect fails; provides clock spec) -* flash bank at91sam7 0 0 0 0 $_TARGETNAME 0 0 0 0 0 0 25000 -* (auto-detect everything except the clock) -* ==== NOT RECOMMENDED !!! (clock speed is not configured) ==== -* flash bank at91sam7 0x00100000 0 0 4 $_TARGETNAME AT91SAM7XC256 1 16 64 256 3 0 -* (if auto-detect fails) -* flash bank at91sam7 0 0 0 0 $_TARGETNAME -* (old style, auto-detect everything) -****************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "imp.h" -#include - -/* AT91SAM7 control registers */ -#define DBGU_CIDR 0xFFFFF240 -#define CKGR_MCFR 0xFFFFFC24 -#define CKGR_MOR 0xFFFFFC20 -#define CKGR_MCFR_MAINRDY 0x10000 -#define CKGR_PLLR 0xFFFFFC2c -#define CKGR_PLLR_DIV 0xff -#define CKGR_PLLR_MUL 0x07ff0000 -#define PMC_MCKR 0xFFFFFC30 -#define PMC_MCKR_CSS 0x03 -#define PMC_MCKR_PRES 0x1c - -/* Flash Controller Commands */ -#define WP 0x01 -#define SLB 0x02 -#define WPL 0x03 -#define CLB 0x04 -#define EA 0x08 -#define SGPB 0x0B -#define CGPB 0x0D -#define SSB 0x0F - -/* MC_FSR bit definitions */ -#define MC_FSR_FRDY 1 -#define MC_FSR_EOL 2 - -/* AT91SAM7 constants */ -#define RC_FREQ 32000 - -/* Flash timing modes */ -#define FMR_TIMING_NONE 0 -#define FMR_TIMING_NVBITS 1 -#define FMR_TIMING_FLASH 2 - -/* Flash size constants */ -#define FLASH_SIZE_8KB 1 -#define FLASH_SIZE_16KB 2 -#define FLASH_SIZE_32KB 3 -#define FLASH_SIZE_64KB 5 -#define FLASH_SIZE_128KB 7 -#define FLASH_SIZE_256KB 9 -#define FLASH_SIZE_512KB 10 -#define FLASH_SIZE_1024KB 12 -#define FLASH_SIZE_2048KB 14 - -static int at91sam7_protect_check(struct flash_bank *bank); -static int at91sam7_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, - uint32_t count); - -static uint32_t at91sam7_get_flash_status(struct target *target, int bank_number); -static void at91sam7_set_flash_mode(struct flash_bank *bank, int mode); -static uint32_t at91sam7_wait_status_busy(struct flash_bank *bank, uint32_t waitbits, int timeout); -static int at91sam7_flash_command(struct flash_bank *bank, uint8_t cmd, uint16_t pagen); - -static const uint32_t MC_FMR[4] = { 0xFFFFFF60, 0xFFFFFF70, 0xFFFFFF80, 0xFFFFFF90 }; -static const uint32_t MC_FCR[4] = { 0xFFFFFF64, 0xFFFFFF74, 0xFFFFFF84, 0xFFFFFF94 }; -static const uint32_t MC_FSR[4] = { 0xFFFFFF68, 0xFFFFFF78, 0xFFFFFF88, 0xFFFFFF98 }; - -static const char *EPROC[8] = { - "Unknown", "ARM946-E", "ARM7TDMI", "Unknown", "ARM920T", "ARM926EJ-S", "Unknown", "Unknown" -}; - -struct at91sam7_flash_bank { - /* chip id register */ - uint32_t cidr; - uint16_t cidr_ext; - uint16_t cidr_nvptyp; - uint16_t cidr_arch; - uint16_t cidr_sramsiz; - uint16_t cidr_nvpsiz; - uint16_t cidr_nvpsiz2; - uint16_t cidr_eproc; - uint16_t cidr_version; - const char *target_name; - - /* flash auto-detection */ - uint8_t flash_autodetection; - - /* flash geometry */ - uint16_t pages_per_sector; - uint16_t pagesize; - uint16_t pages_in_lockregion; - - /* nv memory bits */ - uint16_t num_lockbits_on; - uint16_t lockbits; - uint16_t num_nvmbits; - uint16_t num_nvmbits_on; - uint16_t nvmbits; - uint8_t securitybit; - - /* 0: not init - * 1: fmcn for nvbits (1uS) - * 2: fmcn for flash (1.5uS) */ - uint8_t flashmode; - - /* main clock status */ - uint8_t mck_valid; - uint32_t mck_freq; - - /* external clock frequency */ - uint32_t ext_freq; - -}; - -#if 0 -static long SRAMSIZ[16] = { - -1, - 0x0400, /* 1K */ - 0x0800, /* 2K */ - -1, - 0x1c000, /* 112K */ - 0x1000, /* 4K */ - 0x14000, /* 80K */ - 0x28000, /* 160K */ - 0x2000, /* 8K */ - 0x4000, /* 16K */ - 0x8000, /* 32K */ - 0x10000, /* 64K */ - 0x20000, /* 128K */ - 0x40000, /* 256K */ - 0x18000, /* 96K */ - 0x80000, /* 512K */ -}; -#endif - -static uint32_t at91sam7_get_flash_status(struct target *target, int bank_number) -{ - uint32_t fsr; - target_read_u32(target, MC_FSR[bank_number], &fsr); - - return fsr; -} - -/* Read clock configuration and set at91sam7_info->mck_freq */ -static void at91sam7_read_clock_info(struct flash_bank *bank) -{ - struct at91sam7_flash_bank *at91sam7_info = bank->driver_priv; - struct target *target = bank->target; - uint32_t mckr, mcfr, pllr, mor; - unsigned long tmp = 0, mainfreq; - - /* Read Clock Generator Main Oscillator Register */ - target_read_u32(target, CKGR_MOR, &mor); - /* Read Clock Generator Main Clock Frequency Register */ - target_read_u32(target, CKGR_MCFR, &mcfr); - /* Read Master Clock Register*/ - target_read_u32(target, PMC_MCKR, &mckr); - /* Read Clock Generator PLL Register */ - target_read_u32(target, CKGR_PLLR, &pllr); - - at91sam7_info->mck_valid = 0; - at91sam7_info->mck_freq = 0; - switch (mckr & PMC_MCKR_CSS) { - case 0: /* Slow Clock */ - at91sam7_info->mck_valid = 1; - tmp = RC_FREQ; - break; - - case 1: /* Main Clock */ - if ((mcfr & CKGR_MCFR_MAINRDY) && - (at91sam7_info->ext_freq == 0)) { - at91sam7_info->mck_valid = 1; - tmp = RC_FREQ / 16ul * (mcfr & 0xffff); - } else if (at91sam7_info->ext_freq != 0) { - at91sam7_info->mck_valid = 1; - tmp = at91sam7_info->ext_freq; - } - break; - - case 2: /* Reserved */ - break; - - case 3: /* PLL Clock */ - if ((mcfr & CKGR_MCFR_MAINRDY) && - (at91sam7_info->ext_freq == 0)) { - target_read_u32(target, CKGR_PLLR, &pllr); - if (!(pllr & CKGR_PLLR_DIV)) - break; /* 0 Hz */ - at91sam7_info->mck_valid = 1; - mainfreq = RC_FREQ / 16ul * (mcfr & 0xffff); - /* Integer arithmetic should have sufficient precision - * as long as PLL is properly configured. */ - tmp = mainfreq / (pllr & CKGR_PLLR_DIV)* - (((pllr & CKGR_PLLR_MUL) >> 16) + 1); - } else if ((at91sam7_info->ext_freq != 0) && - ((pllr&CKGR_PLLR_DIV) != 0)) { - at91sam7_info->mck_valid = 1; - tmp = at91sam7_info->ext_freq / (pllr&CKGR_PLLR_DIV)* - (((pllr & CKGR_PLLR_MUL) >> 16) + 1); - } - break; - } - - /* Prescaler adjust */ - if ((((mckr & PMC_MCKR_PRES) >> 2) == 7) || (tmp == 0)) { - at91sam7_info->mck_valid = 0; - at91sam7_info->mck_freq = 0; - } else if (((mckr & PMC_MCKR_PRES) >> 2) != 0) - at91sam7_info->mck_freq = tmp >> ((mckr & PMC_MCKR_PRES) >> 2); - else - at91sam7_info->mck_freq = tmp; -} - -/* Setup the timimg registers for nvbits or normal flash */ -static void at91sam7_set_flash_mode(struct flash_bank *bank, int mode) -{ - uint32_t fmr, fmcn = 0, fws = 0; - struct at91sam7_flash_bank *at91sam7_info = bank->driver_priv; - struct target *target = bank->target; - - if (mode && (mode != at91sam7_info->flashmode)) { - /* Always round up (ceil) */ - if (mode == FMR_TIMING_NVBITS) { - if (at91sam7_info->cidr_arch == 0x60) { - /* AT91SAM7A3 uses master clocks in 100 ns */ - fmcn = (at91sam7_info->mck_freq/10000000ul) + 1; - } else { - /* master clocks in 1uS for ARCH 0x7 types */ - fmcn = (at91sam7_info->mck_freq/1000000ul) + 1; - } - } else if (mode == FMR_TIMING_FLASH) { - /* main clocks in 1.5uS */ - fmcn = (at91sam7_info->mck_freq/1000000ul)+ - (at91sam7_info->mck_freq/2000000ul) + 1; - } - - /* hard overclocking */ - if (fmcn > 0xFF) - fmcn = 0xFF; - - /* Only allow fmcn = 0 if clock period is > 30 us = 33kHz. */ - if (at91sam7_info->mck_freq <= 33333ul) - fmcn = 0; - /* Only allow fws = 0 if clock frequency is < 30 MHz. */ - if (at91sam7_info->mck_freq > 30000000ul) - fws = 1; - - LOG_DEBUG("fmcn[%i]: %i", bank->bank_number, (int)(fmcn)); - fmr = fmcn << 16 | fws << 8; - target_write_u32(target, MC_FMR[bank->bank_number], fmr); - } - - at91sam7_info->flashmode = mode; -} - -static uint32_t at91sam7_wait_status_busy(struct flash_bank *bank, uint32_t waitbits, int timeout) -{ - uint32_t status; - - while ((!((status = at91sam7_get_flash_status(bank->target, - bank->bank_number)) & waitbits)) && (timeout-- > 0)) { - LOG_DEBUG("status[%i]: 0x%" PRIx32 "", (int)bank->bank_number, status); - alive_sleep(1); - } - - LOG_DEBUG("status[%i]: 0x%" PRIx32 "", bank->bank_number, status); - - if (status & 0x0C) { - LOG_ERROR("status register: 0x%" PRIx32 "", status); - if (status & 0x4) - LOG_ERROR("Lock Error Bit Detected, Operation Abort"); - if (status & 0x8) - LOG_ERROR("Invalid command and/or bad keyword, Operation Abort"); - if (status & 0x10) - LOG_ERROR("Security Bit Set, Operation Abort"); - } - - return status; -} - -/* Send one command to the AT91SAM flash controller */ -static int at91sam7_flash_command(struct flash_bank *bank, uint8_t cmd, uint16_t pagen) -{ - uint32_t fcr; - struct at91sam7_flash_bank *at91sam7_info = bank->driver_priv; - struct target *target = bank->target; - - fcr = (0x5A << 24) | ((pagen&0x3FF) << 8) | cmd; - target_write_u32(target, MC_FCR[bank->bank_number], fcr); - LOG_DEBUG("Flash command: 0x%" PRIx32 ", flash bank: %i, page number: %u", - fcr, - bank->bank_number + 1, - pagen); - - if ((at91sam7_info->cidr_arch == 0x60) && ((cmd == SLB) | (cmd == CLB))) { - /* Lock bit manipulation on AT91SAM7A3 waits for FC_FSR bit 1, EOL */ - if (at91sam7_wait_status_busy(bank, MC_FSR_EOL, 10)&0x0C) - return ERROR_FLASH_OPERATION_FAILED; - return ERROR_OK; - } - - if (at91sam7_wait_status_busy(bank, MC_FSR_FRDY, 10)&0x0C) - return ERROR_FLASH_OPERATION_FAILED; - - return ERROR_OK; -} - -/* Read device id register, main clock frequency register and fill in driver info structure */ -static int at91sam7_read_part_info(struct flash_bank *bank) -{ - struct at91sam7_flash_bank *at91sam7_info; - struct target *target = bank->target; - - uint16_t bnk, sec; - uint16_t arch; - uint32_t cidr; - uint8_t banks_num = 0; - uint16_t num_nvmbits = 0; - uint16_t sectors_num = 0; - uint16_t pages_per_sector = 0; - uint16_t page_size = 0; - uint32_t ext_freq; - uint32_t bank_size; - uint32_t base_address = 0; - char *target_name_t = "Unknown"; - - at91sam7_info = bank->driver_priv; - - if (at91sam7_info->cidr != 0) { - /* flash already configured, update clock and check for protected sectors */ - 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); - - /* no timming */ - at91sam7_set_flash_mode(t_bank, FMR_TIMING_NONE); - - /* check protect state */ - at91sam7_protect_check(t_bank); - } - - return ERROR_OK; - } - - /* Read and parse chip identification register */ - target_read_u32(target, DBGU_CIDR, &cidr); - if (cidr == 0) { - LOG_WARNING("Cannot identify target as an AT91SAM"); - return ERROR_FLASH_OPERATION_FAILED; - } - - if (at91sam7_info->flash_autodetection == 0) { - /* banks and sectors are already created, based on data from input file */ - 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; - at91sam7_info->cidr_ext = (cidr >> 31)&0x0001; - at91sam7_info->cidr_nvptyp = (cidr >> 28)&0x0007; - at91sam7_info->cidr_arch = (cidr >> 20)&0x00FF; - at91sam7_info->cidr_sramsiz = (cidr >> 16)&0x000F; - at91sam7_info->cidr_nvpsiz2 = (cidr >> 12)&0x000F; - at91sam7_info->cidr_nvpsiz = (cidr >> 8)&0x000F; - at91sam7_info->cidr_eproc = (cidr >> 5)&0x0007; - at91sam7_info->cidr_version = cidr&0x001F; - - /* calculate master clock frequency */ - at91sam7_read_clock_info(t_bank); - - /* no timming */ - at91sam7_set_flash_mode(t_bank, FMR_TIMING_NONE); - - /* check protect state */ - at91sam7_protect_check(t_bank); - } - - return ERROR_OK; - } - - arch = (cidr >> 20)&0x00FF; - - /* check flash size */ - switch ((cidr >> 8)&0x000F) { - case FLASH_SIZE_8KB: - break; - - case FLASH_SIZE_16KB: - banks_num = 1; - sectors_num = 8; - pages_per_sector = 32; - page_size = 64; - base_address = 0x00100000; - if (arch == 0x70) { - num_nvmbits = 2; - target_name_t = "AT91SAM7S161/16"; - } - break; - - case FLASH_SIZE_32KB: - banks_num = 1; - sectors_num = 8; - pages_per_sector = 32; - page_size = 128; - base_address = 0x00100000; - if (arch == 0x70) { - num_nvmbits = 2; - target_name_t = "AT91SAM7S321/32"; - } - if (arch == 0x72) { - num_nvmbits = 3; - target_name_t = "AT91SAM7SE32"; - } - break; - - case FLASH_SIZE_64KB: - banks_num = 1; - sectors_num = 16; - pages_per_sector = 32; - page_size = 128; - base_address = 0x00100000; - if (arch == 0x70) { - num_nvmbits = 2; - target_name_t = "AT91SAM7S64"; - } - break; - - case FLASH_SIZE_128KB: - banks_num = 1; - sectors_num = 8; - pages_per_sector = 64; - page_size = 256; - base_address = 0x00100000; - if (arch == 0x70) { - num_nvmbits = 2; - target_name_t = "AT91SAM7S128"; - } - if (arch == 0x71) { - num_nvmbits = 3; - target_name_t = "AT91SAM7XC128"; - } - if (arch == 0x72) { - num_nvmbits = 3; - target_name_t = "AT91SAM7SE128"; - } - if (arch == 0x75) { - num_nvmbits = 3; - target_name_t = "AT91SAM7X128"; - } - break; - - case FLASH_SIZE_256KB: - banks_num = 1; - sectors_num = 16; - pages_per_sector = 64; - page_size = 256; - base_address = 0x00100000; - if (arch == 0x60) { - num_nvmbits = 3; - target_name_t = "AT91SAM7A3"; - } - if (arch == 0x70) { - num_nvmbits = 2; - target_name_t = "AT91SAM7S256"; - } - if (arch == 0x71) { - num_nvmbits = 3; - target_name_t = "AT91SAM7XC256"; - } - if (arch == 0x72) { - num_nvmbits = 3; - target_name_t = "AT91SAM7SE256"; - } - if (arch == 0x75) { - num_nvmbits = 3; - target_name_t = "AT91SAM7X256"; - } - break; - - case FLASH_SIZE_512KB: - banks_num = 2; - sectors_num = 16; - pages_per_sector = 64; - page_size = 256; - base_address = 0x00100000; - if (arch == 0x70) { - num_nvmbits = 2; - target_name_t = "AT91SAM7S512"; - } - if (arch == 0x71) { - num_nvmbits = 3; - target_name_t = "AT91SAM7XC512"; - } - if (arch == 0x72) { - num_nvmbits = 3; - target_name_t = "AT91SAM7SE512"; - } - if (arch == 0x75) { - num_nvmbits = 3; - target_name_t = "AT91SAM7X512"; - } - break; - - case FLASH_SIZE_1024KB: - break; - - case FLASH_SIZE_2048KB: - break; - } - - if (strcmp(target_name_t, "Unknown") == 0) { - LOG_ERROR( - "Target autodetection failed! Please specify target parameters in configuration file"); - return ERROR_FLASH_OPERATION_FAILED; - } - - ext_freq = at91sam7_info->ext_freq; - - /* calculate bank size */ - bank_size = sectors_num * pages_per_sector * page_size; - - for (bnk = 0; bnk < banks_num; bnk++) { - struct flash_bank *t_bank = bank; - if (bnk > 0) { - if (!t_bank->next) { - /* create a new flash bank element */ - struct flash_bank *fb = malloc(sizeof(struct flash_bank)); - fb->target = target; - fb->driver = bank->driver; - fb->driver_priv = malloc(sizeof(struct at91sam7_flash_bank)); - fb->name = "sam7_probed"; - fb->next = NULL; - - /* link created bank in 'flash_banks' list */ - t_bank->next = fb; - } - t_bank = t_bank->next; - } - - t_bank->bank_number = bnk; - t_bank->base = base_address + bnk * bank_size; - t_bank->size = bank_size; - t_bank->chip_width = 0; - t_bank->bus_width = 4; - t_bank->num_sectors = sectors_num; - - /* allocate sectors */ - t_bank->sectors = malloc(sectors_num * sizeof(struct flash_sector)); - for (sec = 0; sec < sectors_num; sec++) { - t_bank->sectors[sec].offset = sec * pages_per_sector * page_size; - t_bank->sectors[sec].size = pages_per_sector * page_size; - t_bank->sectors[sec].is_erased = -1; - t_bank->sectors[sec].is_protected = -1; - } - - at91sam7_info = t_bank->driver_priv; - - at91sam7_info->cidr = cidr; - at91sam7_info->cidr_ext = (cidr >> 31)&0x0001; - at91sam7_info->cidr_nvptyp = (cidr >> 28)&0x0007; - at91sam7_info->cidr_arch = (cidr >> 20)&0x00FF; - at91sam7_info->cidr_sramsiz = (cidr >> 16)&0x000F; - at91sam7_info->cidr_nvpsiz2 = (cidr >> 12)&0x000F; - at91sam7_info->cidr_nvpsiz = (cidr >> 8)&0x000F; - at91sam7_info->cidr_eproc = (cidr >> 5)&0x0007; - at91sam7_info->cidr_version = cidr&0x001F; - - at91sam7_info->target_name = target_name_t; - at91sam7_info->flashmode = 0; - at91sam7_info->ext_freq = ext_freq; - at91sam7_info->num_nvmbits = num_nvmbits; - at91sam7_info->num_nvmbits_on = 0; - at91sam7_info->pagesize = page_size; - at91sam7_info->pages_per_sector = pages_per_sector; - - /* calculate master clock frequency */ - at91sam7_read_clock_info(t_bank); - - /* no timming */ - at91sam7_set_flash_mode(t_bank, FMR_TIMING_NONE); - - /* check protect state */ - at91sam7_protect_check(t_bank); - } - - LOG_DEBUG("nvptyp: 0x%3.3x, arch: 0x%4.4x", - at91sam7_info->cidr_nvptyp, - at91sam7_info->cidr_arch); - - return ERROR_OK; -} - -static int at91sam7_erase_check(struct flash_bank *bank) -{ - struct target *target = bank->target; - uint16_t retval; - uint32_t blank; - uint16_t fast_check; - uint8_t *buffer; - uint16_t nSector; - uint16_t nByte; - - if (bank->target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - /* Configure the flash controller timing */ - at91sam7_read_clock_info(bank); - at91sam7_set_flash_mode(bank, FMR_TIMING_FLASH); - - fast_check = 1; - for (nSector = 0; nSector < bank->num_sectors; nSector++) { - retval = target_blank_check_memory(target, - bank->base + bank->sectors[nSector].offset, - bank->sectors[nSector].size, - &blank); - if (retval != ERROR_OK) { - fast_check = 0; - break; - } - if (blank == 0xFF) - bank->sectors[nSector].is_erased = 1; - else - bank->sectors[nSector].is_erased = 0; - } - - if (fast_check) - return ERROR_OK; - - LOG_USER("Running slow fallback erase check - add working memory"); - - buffer = malloc(bank->sectors[0].size); - for (nSector = 0; nSector < bank->num_sectors; nSector++) { - bank->sectors[nSector].is_erased = 1; - retval = target_read_memory(target, bank->base + bank->sectors[nSector].offset, 4, - bank->sectors[nSector].size/4, buffer); - if (retval != ERROR_OK) - return retval; - - for (nByte = 0; nByte < bank->sectors[nSector].size; nByte++) { - if (buffer[nByte] != 0xFF) { - bank->sectors[nSector].is_erased = 0; - break; - } - } - } - free(buffer); - - return ERROR_OK; -} - -static int at91sam7_protect_check(struct flash_bank *bank) -{ - uint8_t lock_pos, gpnvm_pos; - uint32_t status; - - struct at91sam7_flash_bank *at91sam7_info = bank->driver_priv; - - if (at91sam7_info->cidr == 0) - return ERROR_FLASH_BANK_NOT_PROBED; - if (bank->target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - status = at91sam7_get_flash_status(bank->target, bank->bank_number); - at91sam7_info->lockbits = (status >> 16); - - at91sam7_info->num_lockbits_on = 0; - for (lock_pos = 0; lock_pos < bank->num_sectors; lock_pos++) { - if (((status >> (16 + lock_pos))&(0x0001)) == 1) { - at91sam7_info->num_lockbits_on++; - bank->sectors[lock_pos].is_protected = 1; - } else - bank->sectors[lock_pos].is_protected = 0; - } - - /* GPNVM and SECURITY bits apply only for MC_FSR of EFC0 */ - status = at91sam7_get_flash_status(bank->target, 0); - - at91sam7_info->securitybit = (status >> 4)&0x01; - at91sam7_info->nvmbits = (status >> 8)&0xFF; - - at91sam7_info->num_nvmbits_on = 0; - for (gpnvm_pos = 0; gpnvm_pos < at91sam7_info->num_nvmbits; gpnvm_pos++) { - if (((status >> (8 + gpnvm_pos))&(0x01)) == 1) - at91sam7_info->num_nvmbits_on++; - } - - return ERROR_OK; -} - -FLASH_BANK_COMMAND_HANDLER(at91sam7_flash_bank_command) -{ - struct flash_bank *t_bank = bank; - struct at91sam7_flash_bank *at91sam7_info; - struct target *target = t_bank->target; - - uint32_t base_address; - uint32_t bank_size; - uint32_t ext_freq = 0; - - int chip_width; - int bus_width; - int banks_num; - int num_sectors; - - uint16_t pages_per_sector; - uint16_t page_size; - uint16_t num_nvmbits; - - char *target_name_t; - - int bnk, sec; - - at91sam7_info = malloc(sizeof(struct at91sam7_flash_bank)); - t_bank->driver_priv = at91sam7_info; - - /* part wasn't probed for info yet */ - at91sam7_info->cidr = 0; - at91sam7_info->flashmode = 0; - at91sam7_info->ext_freq = 0; - at91sam7_info->flash_autodetection = 0; - - if (CMD_ARGC < 13) { - at91sam7_info->flash_autodetection = 1; - return ERROR_OK; - } - - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], base_address); - - COMMAND_PARSE_NUMBER(int, CMD_ARGV[3], chip_width); - COMMAND_PARSE_NUMBER(int, CMD_ARGV[4], bus_width); - - COMMAND_PARSE_NUMBER(int, CMD_ARGV[8], banks_num); - COMMAND_PARSE_NUMBER(int, CMD_ARGV[9], num_sectors); - COMMAND_PARSE_NUMBER(u16, CMD_ARGV[10], pages_per_sector); - COMMAND_PARSE_NUMBER(u16, CMD_ARGV[11], page_size); - COMMAND_PARSE_NUMBER(u16, CMD_ARGV[12], num_nvmbits); - - if (CMD_ARGC == 14) { - unsigned long freq; - COMMAND_PARSE_NUMBER(ulong, CMD_ARGV[13], freq); - ext_freq = freq * 1000; - at91sam7_info->ext_freq = ext_freq; - } - - if ((bus_width == 0) || (banks_num == 0) || (num_sectors == 0) || - (pages_per_sector == 0) || (page_size == 0) || (num_nvmbits == 0)) { - at91sam7_info->flash_autodetection = 1; - return ERROR_OK; - } - - target_name_t = calloc(strlen(CMD_ARGV[7]) + 1, sizeof(char)); - strcpy(target_name_t, CMD_ARGV[7]); - - /* calculate bank size */ - bank_size = num_sectors * pages_per_sector * page_size; - - for (bnk = 0; bnk < banks_num; bnk++) { - if (bnk > 0) { - if (!t_bank->next) { - /* create a new bank element */ - struct flash_bank *fb = malloc(sizeof(struct flash_bank)); - fb->target = target; - fb->driver = bank->driver; - fb->driver_priv = malloc(sizeof(struct at91sam7_flash_bank)); - fb->name = "sam7_probed"; - fb->next = NULL; - - /* link created bank in 'flash_banks' list */ - t_bank->next = fb; - } - t_bank = t_bank->next; - } - - t_bank->bank_number = bnk; - t_bank->base = base_address + bnk * bank_size; - t_bank->size = bank_size; - t_bank->chip_width = chip_width; - t_bank->bus_width = bus_width; - t_bank->num_sectors = num_sectors; - - /* allocate sectors */ - t_bank->sectors = malloc(num_sectors * sizeof(struct flash_sector)); - for (sec = 0; sec < num_sectors; sec++) { - t_bank->sectors[sec].offset = sec * pages_per_sector * page_size; - t_bank->sectors[sec].size = pages_per_sector * page_size; - t_bank->sectors[sec].is_erased = -1; - t_bank->sectors[sec].is_protected = -1; - } - - at91sam7_info = t_bank->driver_priv; - - at91sam7_info->target_name = target_name_t; - at91sam7_info->flashmode = 0; - at91sam7_info->ext_freq = ext_freq; - at91sam7_info->num_nvmbits = num_nvmbits; - at91sam7_info->num_nvmbits_on = 0; - at91sam7_info->pagesize = page_size; - at91sam7_info->pages_per_sector = pages_per_sector; - } - - return ERROR_OK; -} - -static int at91sam7_erase(struct flash_bank *bank, int first, int last) -{ - struct at91sam7_flash_bank *at91sam7_info = bank->driver_priv; - int sec; - uint32_t nbytes, pos; - uint8_t *buffer; - uint8_t erase_all; - - if (at91sam7_info->cidr == 0) - return ERROR_FLASH_BANK_NOT_PROBED; - - if (bank->target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - if ((first < 0) || (last < first) || (last >= bank->num_sectors)) - return ERROR_FLASH_SECTOR_INVALID; - - erase_all = 0; - if ((first == 0) && (last == (bank->num_sectors-1))) - erase_all = 1; - - /* Configure the flash controller timing */ - at91sam7_read_clock_info(bank); - at91sam7_set_flash_mode(bank, FMR_TIMING_FLASH); - - if (erase_all) { - if (at91sam7_flash_command(bank, EA, 0) != ERROR_OK) - return ERROR_FLASH_OPERATION_FAILED; - } else { - /* allocate and clean buffer */ - nbytes = (last - first + 1) * bank->sectors[first].size; - buffer = malloc(nbytes * sizeof(uint8_t)); - for (pos = 0; pos < nbytes; pos++) - buffer[pos] = 0xFF; - - if (at91sam7_write(bank, buffer, bank->sectors[first].offset, nbytes) != ERROR_OK) { - free(buffer); - return ERROR_FLASH_OPERATION_FAILED; - } - - free(buffer); - } - - /* mark erased sectors */ - for (sec = first; sec <= last; sec++) - bank->sectors[sec].is_erased = 1; - - return ERROR_OK; -} - -static int at91sam7_protect(struct flash_bank *bank, int set, int first, int last) -{ - uint32_t cmd; - int sector; - uint32_t pagen; - - struct at91sam7_flash_bank *at91sam7_info = bank->driver_priv; - - if (at91sam7_info->cidr == 0) - return ERROR_FLASH_BANK_NOT_PROBED; - - if (bank->target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - if ((first < 0) || (last < first) || (last >= bank->num_sectors)) - return ERROR_FLASH_SECTOR_INVALID; - - /* Configure the flash controller timing */ - at91sam7_read_clock_info(bank); - at91sam7_set_flash_mode(bank, FMR_TIMING_NVBITS); - - for (sector = first; sector <= last; sector++) { - if (set) - cmd = SLB; - else - cmd = CLB; - - /* if we lock a page from one sector then entire sector will be locked, also, - * if we unlock a page from a locked sector, entire sector will be unlocked */ - pagen = sector * at91sam7_info->pages_per_sector; - - if (at91sam7_flash_command(bank, cmd, pagen) != ERROR_OK) - return ERROR_FLASH_OPERATION_FAILED; - } - - at91sam7_protect_check(bank); - - return ERROR_OK; -} - -static int at91sam7_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count) -{ - int retval; - struct at91sam7_flash_bank *at91sam7_info = bank->driver_priv; - struct target *target = bank->target; - uint32_t dst_min_alignment, wcount, bytes_remaining = count; - uint32_t first_page, last_page, pagen, buffer_pos; - - if (at91sam7_info->cidr == 0) - return ERROR_FLASH_BANK_NOT_PROBED; - - if (bank->target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - if (offset + count > bank->size) - return ERROR_FLASH_DST_OUT_OF_BANK; - - dst_min_alignment = at91sam7_info->pagesize; - - if (offset % dst_min_alignment) { - LOG_WARNING("offset 0x%" PRIx32 " breaks required alignment 0x%" PRIx32 "", - offset, - dst_min_alignment); - return ERROR_FLASH_DST_BREAKS_ALIGNMENT; - } - - if (at91sam7_info->cidr_arch == 0) - return ERROR_FLASH_BANK_NOT_PROBED; - - first_page = offset/dst_min_alignment; - last_page = DIV_ROUND_UP(offset + count, dst_min_alignment); - - LOG_DEBUG("first_page: %i, last_page: %i, count %i", - (int)first_page, - (int)last_page, - (int)count); - - /* Configure the flash controller timing */ - at91sam7_read_clock_info(bank); - at91sam7_set_flash_mode(bank, FMR_TIMING_FLASH); - - for (pagen = first_page; pagen < last_page; pagen++) { - if (bytes_remaining < dst_min_alignment) - count = bytes_remaining; - else - count = dst_min_alignment; - bytes_remaining -= count; - - /* Write one block to the PageWriteBuffer */ - buffer_pos = (pagen-first_page)*dst_min_alignment; - wcount = DIV_ROUND_UP(count, 4); - retval = target_write_memory(target, bank->base + pagen*dst_min_alignment, 4, - wcount, buffer + buffer_pos); - if (retval != ERROR_OK) - return retval; - - /* Send Write Page command to Flash Controller */ - if (at91sam7_flash_command(bank, WP, pagen) != ERROR_OK) - return ERROR_FLASH_OPERATION_FAILED; - LOG_DEBUG("Write flash bank:%i page number:%" PRIi32 "", bank->bank_number, pagen); - } - - return ERROR_OK; -} - -static int at91sam7_probe(struct flash_bank *bank) -{ - /* we can't probe on an at91sam7 - * if this is an at91sam7, it has the configured flash */ - int retval; - - if (bank->target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - retval = at91sam7_read_part_info(bank); - if (retval != ERROR_OK) - return retval; - - return ERROR_OK; -} - -static int get_at91sam7_info(struct flash_bank *bank, char *buf, int buf_size) -{ - int printed; - struct at91sam7_flash_bank *at91sam7_info = bank->driver_priv; - - if (at91sam7_info->cidr == 0) - return ERROR_FLASH_BANK_NOT_PROBED; - - printed = snprintf(buf, buf_size, - "\n at91sam7 driver information: Chip is %s\n", - at91sam7_info->target_name); - - buf += printed; - buf_size -= printed; - - printed = snprintf(buf, - buf_size, - " Cidr: 0x%8.8" PRIx32 " | Arch: 0x%4.4x | Eproc: %s | Version: 0x%3.3x | " - "Flashsize: 0x%8.8" PRIx32 "\n", - at91sam7_info->cidr, - at91sam7_info->cidr_arch, - EPROC[at91sam7_info->cidr_eproc], - at91sam7_info->cidr_version, - bank->size); - - buf += printed; - buf_size -= printed; - - printed = snprintf(buf, buf_size, - " Master clock (estimated): %u KHz | External clock: %u KHz\n", - (unsigned)(at91sam7_info->mck_freq / 1000), - (unsigned)(at91sam7_info->ext_freq / 1000)); - - buf += printed; - buf_size -= printed; - - printed = snprintf(buf, - buf_size, - " Pagesize: %i bytes | Lockbits(%i): %i 0x%4.4x | Pages in lock region: %i\n", - at91sam7_info->pagesize, - bank->num_sectors, - at91sam7_info->num_lockbits_on, - at91sam7_info->lockbits, - at91sam7_info->pages_per_sector*at91sam7_info->num_lockbits_on); - - buf += printed; - buf_size -= printed; - - snprintf(buf, buf_size, - " Securitybit: %i | Nvmbits(%i): %i 0x%1.1x\n", - at91sam7_info->securitybit, at91sam7_info->num_nvmbits, - at91sam7_info->num_nvmbits_on, at91sam7_info->nvmbits); - - return ERROR_OK; -} - -/* -* On AT91SAM7S: When the gpnvm bits are set with -* > at91sam7 gpnvm bitnr set -* the changes are not visible in the flash controller status register MC_FSR -* until the processor has been reset. -* On the Olimex board this requires a power cycle. -* Note that the AT91SAM7S has the following errata (doc6175.pdf sec 14.1.3): -* The maximum number of write/erase cycles for Non volatile Memory bits is 100. this includes -* Lock Bits (LOCKx), General Purpose NVM bits (GPNVMx) and the Security Bit. -*/ -COMMAND_HANDLER(at91sam7_handle_gpnvm_command) -{ - struct flash_bank *bank; - int bit; - uint8_t flashcmd; - uint32_t status; - struct at91sam7_flash_bank *at91sam7_info; - int retval; - - if (CMD_ARGC != 2) - return ERROR_COMMAND_SYNTAX_ERROR; - - bank = get_flash_bank_by_num_noprobe(0); - if (bank == NULL) - return ERROR_FLASH_BANK_INVALID; - if (strcmp(bank->driver->name, "at91sam7")) { - command_print(CMD_CTX, "not an at91sam7 flash bank '%s'", CMD_ARGV[0]); - return ERROR_FLASH_BANK_INVALID; - } - if (bank->target->state != TARGET_HALTED) { - LOG_ERROR("target has to be halted to perform flash operation"); - return ERROR_TARGET_NOT_HALTED; - } - - if (strcmp(CMD_ARGV[1], "set") == 0) - flashcmd = SGPB; - else if (strcmp(CMD_ARGV[1], "clear") == 0) - flashcmd = CGPB; - else - return ERROR_COMMAND_SYNTAX_ERROR; - - at91sam7_info = bank->driver_priv; - if (at91sam7_info->cidr == 0) { - retval = at91sam7_read_part_info(bank); - if (retval != ERROR_OK) - return retval; - } - - COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], bit); - if ((bit < 0) || (bit >= at91sam7_info->num_nvmbits)) { - command_print(CMD_CTX, - "gpnvm bit '#%s' is out of bounds for target %s", - CMD_ARGV[0], - at91sam7_info->target_name); - return ERROR_OK; - } - - /* Configure the flash controller timing */ - at91sam7_read_clock_info(bank); - at91sam7_set_flash_mode(bank, FMR_TIMING_NVBITS); - - if (at91sam7_flash_command(bank, flashcmd, bit) != ERROR_OK) - return ERROR_FLASH_OPERATION_FAILED; - - /* GPNVM and SECURITY bits apply only for MC_FSR of EFC0 */ - status = at91sam7_get_flash_status(bank->target, 0); - LOG_DEBUG("at91sam7_handle_gpnvm_command: cmd 0x%x, value %d, status 0x%" PRIx32, - flashcmd, - bit, - status); - - /* check protect state */ - at91sam7_protect_check(bank); - - return ERROR_OK; -} - -static const struct command_registration at91sam7_exec_command_handlers[] = { - { - .name = "gpnvm", - .handler = at91sam7_handle_gpnvm_command, - .mode = COMMAND_EXEC, - .help = "set or clear one General Purpose Non-Volatile Memory " - "(gpnvm) bit", - .usage = "bitnum ('set'|'clear')", - }, - COMMAND_REGISTRATION_DONE -}; -static const struct command_registration at91sam7_command_handlers[] = { - { - .name = "at91sam7", - .mode = COMMAND_ANY, - .help = "at91sam7 flash command group", - .usage = "", - .chain = at91sam7_exec_command_handlers, - }, - COMMAND_REGISTRATION_DONE -}; - -struct flash_driver at91sam7_flash = { - .name = "at91sam7", - .usage = "gpnvm ", - .commands = at91sam7_command_handlers, - .flash_bank_command = at91sam7_flash_bank_command, - .erase = at91sam7_erase, - .protect = at91sam7_protect, - .write = at91sam7_write, - .read = default_flash_read, - .probe = at91sam7_probe, - .auto_probe = at91sam7_probe, - .erase_check = at91sam7_erase_check, - .protect_check = at91sam7_protect_check, - .info = get_at91sam7_info, -}; diff --git a/src/flash/nor/at91samd.c b/src/flash/nor/at91samd.c deleted file mode 100644 index 58b367ab1..000000000 --- a/src/flash/nor/at91samd.c +++ /dev/null @@ -1,1124 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2013 by Andrey Yurovsky * - * Andrey Yurovsky * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 -#include "config.h" -#endif - -#include "imp.h" -#include "helper/binarybuffer.h" - -#include - -#define SAMD_NUM_SECTORS 16 -#define SAMD_PAGE_SIZE_MAX 1024 - -#define SAMD_FLASH ((uint32_t)0x00000000) /* physical Flash memory */ -#define SAMD_USER_ROW ((uint32_t)0x00804000) /* User Row of Flash */ -#define SAMD_PAC1 0x41000000 /* Peripheral Access Control 1 */ -#define SAMD_DSU 0x41002000 /* Device Service Unit */ -#define SAMD_NVMCTRL 0x41004000 /* Non-volatile memory controller */ - -#define SAMD_DSU_STATUSA 1 /* DSU status register */ -#define SAMD_DSU_DID 0x18 /* Device ID register */ - -#define SAMD_NVMCTRL_CTRLA 0x00 /* NVM control A register */ -#define SAMD_NVMCTRL_CTRLB 0x04 /* NVM control B register */ -#define SAMD_NVMCTRL_PARAM 0x08 /* NVM parameters register */ -#define SAMD_NVMCTRL_INTFLAG 0x18 /* NVM Interupt Flag Status & Clear */ -#define SAMD_NVMCTRL_STATUS 0x18 /* NVM status register */ -#define SAMD_NVMCTRL_ADDR 0x1C /* NVM address register */ -#define SAMD_NVMCTRL_LOCK 0x20 /* NVM Lock section register */ - -#define SAMD_CMDEX_KEY 0xA5UL -#define SAMD_NVM_CMD(n) ((SAMD_CMDEX_KEY << 8) | (n & 0x7F)) - -/* NVMCTRL commands. See Table 20-4 in 42129F–SAM–10/2013 */ -#define SAMD_NVM_CMD_ER 0x02 /* Erase Row */ -#define SAMD_NVM_CMD_WP 0x04 /* Write Page */ -#define SAMD_NVM_CMD_EAR 0x05 /* Erase Auxilary Row */ -#define SAMD_NVM_CMD_WAP 0x06 /* Write Auxilary Page */ -#define SAMD_NVM_CMD_LR 0x40 /* Lock Region */ -#define SAMD_NVM_CMD_UR 0x41 /* Unlock Region */ -#define SAMD_NVM_CMD_SPRM 0x42 /* Set Power Reduction Mode */ -#define SAMD_NVM_CMD_CPRM 0x43 /* Clear Power Reduction Mode */ -#define SAMD_NVM_CMD_PBC 0x44 /* Page Buffer Clear */ -#define SAMD_NVM_CMD_SSB 0x45 /* Set Security Bit */ -#define SAMD_NVM_CMD_INVALL 0x46 /* Invalidate all caches */ - -/* NVMCTRL bits */ -#define SAMD_NVM_CTRLB_MANW 0x80 - -/* Known identifiers */ -#define SAMD_PROCESSOR_M0 0x01 -#define SAMD_FAMILY_D 0x00 -#define SAMD_FAMILY_L 0x01 -#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) -#define SAMD_GET_FAMILY(id) (((id >> 23) & 0x1F)) -#define SAMD_GET_SERIES(id) (((id >> 16) & 0x3F)) -#define SAMD_GET_DEVSEL(id) (id & 0xFF) - -struct samd_part { - uint8_t id; - const char *name; - uint32_t flash_kb; - 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 }, - { 0x1, "SAMD10D13AMU", 8, 4 }, - { 0x2, "SAMD10D12AMU", 4, 4 }, - { 0x3, "SAMD10D14ASU", 16, 4 }, - { 0x4, "SAMD10D13ASU", 8, 4 }, - { 0x5, "SAMD10D12ASU", 4, 4 }, - { 0x6, "SAMD10C14A", 16, 4 }, - { 0x7, "SAMD10C13A", 8, 4 }, - { 0x8, "SAMD10C12A", 4, 4 }, -}; - -/* Known SAMD11 parts */ -static const struct samd_part samd11_parts[] = { - { 0x0, "SAMD11D14AMU", 16, 4 }, - { 0x1, "SAMD11D13AMU", 8, 4 }, - { 0x2, "SAMD11D12AMU", 4, 4 }, - { 0x3, "SAMD11D14ASU", 16, 4 }, - { 0x4, "SAMD11D13ASU", 8, 4 }, - { 0x5, "SAMD11D12ASU", 4, 4 }, - { 0x6, "SAMD11C14A", 16, 4 }, - { 0x7, "SAMD11C13A", 8, 4 }, - { 0x8, "SAMD11C12A", 4, 4 }, -}; - -/* Known SAMD20 parts. See Table 12-8 in 42129F–SAM–10/2013 */ -static const struct samd_part samd20_parts[] = { - { 0x0, "SAMD20J18A", 256, 32 }, - { 0x1, "SAMD20J17A", 128, 16 }, - { 0x2, "SAMD20J16A", 64, 8 }, - { 0x3, "SAMD20J15A", 32, 4 }, - { 0x4, "SAMD20J14A", 16, 2 }, - { 0x5, "SAMD20G18A", 256, 32 }, - { 0x6, "SAMD20G17A", 128, 16 }, - { 0x7, "SAMD20G16A", 64, 8 }, - { 0x8, "SAMD20G15A", 32, 4 }, - { 0x9, "SAMD20G14A", 16, 2 }, - { 0xA, "SAMD20E18A", 256, 32 }, - { 0xB, "SAMD20E17A", 128, 16 }, - { 0xC, "SAMD20E16A", 64, 8 }, - { 0xD, "SAMD20E15A", 32, 4 }, - { 0xE, "SAMD20E14A", 16, 2 }, -}; - -/* Known SAMD21 parts. */ -static const struct samd_part samd21_parts[] = { - { 0x0, "SAMD21J18A", 256, 32 }, - { 0x1, "SAMD21J17A", 128, 16 }, - { 0x2, "SAMD21J16A", 64, 8 }, - { 0x3, "SAMD21J15A", 32, 4 }, - { 0x4, "SAMD21J14A", 16, 2 }, - { 0x5, "SAMD21G18A", 256, 32 }, - { 0x6, "SAMD21G17A", 128, 16 }, - { 0x7, "SAMD21G16A", 64, 8 }, - { 0x8, "SAMD21G15A", 32, 4 }, - { 0x9, "SAMD21G14A", 16, 2 }, - { 0xA, "SAMD21E18A", 256, 32 }, - { 0xB, "SAMD21E17A", 128, 16 }, - { 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. */ -static const struct samd_part samr21_parts[] = { - { 0x19, "SAMR21G18A", 256, 32 }, - { 0x1A, "SAMR21G17A", 128, 32 }, - { 0x1B, "SAMR21G16A", 64, 32 }, - { 0x1C, "SAMR21E18A", 256, 32 }, - { 0x1D, "SAMR21E17A", 128, 32 }, - { 0x1E, "SAMR21E16A", 64, 32 }, -}; - -/* Known SAML21 parts. */ -static const struct samd_part saml21_parts[] = { - { 0x00, "SAML21J18A", 256, 32 }, - { 0x01, "SAML21J17A", 128, 16 }, - { 0x02, "SAML21J16A", 64, 8 }, - { 0x05, "SAML21G18A", 256, 32 }, - { 0x06, "SAML21G17A", 128, 16 }, - { 0x07, "SAML21G16A", 64, 8 }, - { 0x0A, "SAML21E18A", 256, 32 }, - { 0x0B, "SAML21E17A", 128, 16 }, - { 0x0C, "SAML21E16A", 64, 8 }, - { 0x0D, "SAML21E15A", 32, 4 }, - { 0x0F, "SAML21J18B", 256, 32 }, - { 0x10, "SAML21J17B", 128, 16 }, - { 0x11, "SAML21J16B", 64, 8 }, - { 0x14, "SAML21G18B", 256, 32 }, - { 0x15, "SAML21G17B", 128, 16 }, - { 0x16, "SAML21G16B", 64, 8 }, - { 0x19, "SAML21E18B", 256, 32 }, - { 0x1A, "SAML21E17B", 128, 16 }, - { 0x1B, "SAML21E16B", 64, 8 }, - { 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 }, - { 0x01, "SAMC20J17A", 128, 16 }, - { 0x02, "SAMC20J16A", 64, 8 }, - { 0x03, "SAMC20J15A", 32, 4 }, - { 0x05, "SAMC20G18A", 256, 32 }, - { 0x06, "SAMC20G17A", 128, 16 }, - { 0x07, "SAMC20G16A", 64, 8 }, - { 0x08, "SAMC20G15A", 32, 4 }, - { 0x0A, "SAMC20E18A", 256, 32 }, - { 0x0B, "SAMC20E17A", 128, 16 }, - { 0x0C, "SAMC20E16A", 64, 8 }, - { 0x0D, "SAMC20E15A", 32, 4 }, -}; - -/* Known SAMC21 parts. */ -static const struct samd_part samc21_parts[] = { - { 0x00, "SAMC21J18A", 256, 32 }, - { 0x01, "SAMC21J17A", 128, 16 }, - { 0x02, "SAMC21J16A", 64, 8 }, - { 0x03, "SAMC21J15A", 32, 4 }, - { 0x05, "SAMC21G18A", 256, 32 }, - { 0x06, "SAMC21G17A", 128, 16 }, - { 0x07, "SAMC21G16A", 64, 8 }, - { 0x08, "SAMC21G15A", 32, 4 }, - { 0x0A, "SAMC21E18A", 256, 32 }, - { 0x0B, "SAMC21E17A", 128, 16 }, - { 0x0C, "SAMC21E16A", 64, 8 }, - { 0x0D, "SAMC21E15A", 32, 4 }, -}; - -/* Each family of parts contains a parts table in the DEVSEL field of DID. The - * processor ID, family ID, and series ID are used to determine which exact - * family this is and then we can use the corresponding table. */ -struct samd_family { - uint8_t processor; - uint8_t family; - uint8_t series; - const struct samd_part *parts; - size_t num_parts; -}; - -/* Known SAMD families */ -static const struct samd_family samd_families[] = { - { SAMD_PROCESSOR_M0, SAMD_FAMILY_D, SAMD_SERIES_20, - samd20_parts, ARRAY_SIZE(samd20_parts) }, - { SAMD_PROCESSOR_M0, SAMD_FAMILY_D, SAMD_SERIES_21, - 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, - samc21_parts, ARRAY_SIZE(samc21_parts) }, -}; - -struct samd_info { - uint32_t page_size; - int num_pages; - int sector_size; - - bool probed; - struct target *target; - struct samd_info *next; -}; - -static struct samd_info *samd_chips; - - - -static const struct samd_part *samd_find_part(uint32_t id) -{ - uint8_t processor = SAMD_GET_PROCESSOR(id); - uint8_t family = SAMD_GET_FAMILY(id); - uint8_t series = SAMD_GET_SERIES(id); - uint8_t devsel = SAMD_GET_DEVSEL(id); - - for (unsigned i = 0; i < ARRAY_SIZE(samd_families); i++) { - if (samd_families[i].processor == processor && - samd_families[i].series == series && - samd_families[i].family == family) { - for (unsigned j = 0; j < samd_families[i].num_parts; j++) { - if (samd_families[i].parts[j].id == devsel) - return &samd_families[i].parts[j]; - } - } - } - - return NULL; -} - -static int samd_protect_check(struct flash_bank *bank) -{ - int res; - uint16_t lock; - - res = target_read_u16(bank->target, - SAMD_NVMCTRL + SAMD_NVMCTRL_LOCK, &lock); - if (res != ERROR_OK) - return res; - - /* Lock bits are active-low */ - for (int i = 0; i < bank->num_sectors; i++) - bank->sectors[i].is_protected = !(lock & (1<> 16) & 0x7)); - /* The NVMP field (bits 15:0) indicates the total number of pages */ - if (nump) - *nump = param & 0xFFFF; - } else { - LOG_ERROR("Couldn't read NVM Parameters register"); - } - - return res; -} - -static int samd_probe(struct flash_bank *bank) -{ - uint32_t id; - int res; - struct samd_info *chip = (struct samd_info *)bank->driver_priv; - const struct samd_part *part; - - if (chip->probed) - return ERROR_OK; - - res = target_read_u32(bank->target, SAMD_DSU + SAMD_DSU_DID, &id); - if (res != ERROR_OK) { - LOG_ERROR("Couldn't read Device ID register"); - return res; - } - - part = samd_find_part(id); - if (part == NULL) { - LOG_ERROR("Couldn't find part corresponding to DID %08" PRIx32, id); - return ERROR_FAIL; - } - - bank->size = part->flash_kb * 1024; - - chip->sector_size = bank->size / SAMD_NUM_SECTORS; - - res = samd_get_flash_page_info(bank->target, &chip->page_size, - &chip->num_pages); - if (res != ERROR_OK) { - LOG_ERROR("Couldn't determine Flash page size"); - return res; - } - - /* Sanity check: the total flash size in the DSU should match the page size - * multiplied by the number of pages. */ - if (bank->size != chip->num_pages * chip->page_size) { - LOG_WARNING("SAMD: bank size doesn't match NVM parameters. " - "Identified %" PRIu32 "KB Flash but NVMCTRL reports %u %" PRIu32 "B pages", - part->flash_kb, chip->num_pages, chip->page_size); - } - - /* Allocate the sector table */ - bank->num_sectors = SAMD_NUM_SECTORS; - bank->sectors = calloc(bank->num_sectors, sizeof((bank->sectors)[0])); - if (!bank->sectors) - return ERROR_FAIL; - - /* Fill out the sector information: all SAMD sectors are the same size and - * there is always a fixed number of them. */ - for (int i = 0; i < bank->num_sectors; i++) { - bank->sectors[i].size = chip->sector_size; - bank->sectors[i].offset = i * chip->sector_size; - /* mark as unknown */ - bank->sectors[i].is_erased = -1; - bank->sectors[i].is_protected = -1; - } - - samd_protect_check(bank); - - /* Done */ - chip->probed = true; - - LOG_INFO("SAMD MCU: %s (%" PRIu32 "KB Flash, %" PRIu32 "KB RAM)", part->name, - part->flash_kb, part->ram_kb); - - return ERROR_OK; -} - -static bool samd_check_error(struct target *target) -{ - int ret; - bool error; - 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; - } - - 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"); - - error = true; - } else { - error = false; - } - - /* Clear the error conditions by writing a one to them */ - ret = target_write_u16(target, - SAMD_NVMCTRL + SAMD_NVMCTRL_STATUS, status); - if (ret != ERROR_OK) - LOG_ERROR("Can't clear NVM error conditions"); - - return error; -} - -static int samd_issue_nvmctrl_command(struct target *target, uint16_t cmd) -{ - int res; - - if (target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - /* Issue the NVM command */ - res = target_write_u16(target, - SAMD_NVMCTRL + SAMD_NVMCTRL_CTRLA, SAMD_NVM_CMD(cmd)); - if (res != ERROR_OK) - 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; -} - -static int samd_erase_row(struct target *target, uint32_t address) -{ - int res; - - /* Set an address contained in the row to be erased */ - res = target_write_u32(target, - SAMD_NVMCTRL + SAMD_NVMCTRL_ADDR, address >> 1); - - /* Issue the Erase Row command to erase that row. */ - if (res == ERROR_OK) - res = samd_issue_nvmctrl_command(target, - address == SAMD_USER_ROW ? SAMD_NVM_CMD_EAR : SAMD_NVM_CMD_ER); - - if (res != ERROR_OK) { - LOG_ERROR("Failed to erase row containing %08" PRIx32, address); - return ERROR_FAIL; - } - - return ERROR_OK; -} - -static bool is_user_row_reserved_bit(uint8_t bit) -{ - /* See Table 9-3 in the SAMD20 datasheet for more information. */ - switch (bit) { - /* Reserved bits */ - case 3: - case 7: - /* Voltage regulator internal configuration with default value of 0x70, - * may not be changed. */ - case 17 ... 24: - /* 41 is voltage regulator internal configuration and must not be - * changed. 42 through 47 are reserved. */ - case 41 ... 47: - return true; - default: - break; - } - - return false; -} - -/* Modify the contents of the User Row in Flash. These are described in Table - * 9-3 of the SAMD20 datasheet. The User Row itself has a size of one page - * and contains a combination of "fuses" and calibration data in bits 24:17. - * We therefore try not to erase the row's contents unless we absolutely have - * to and we don't permit modifying reserved bits. */ -static int samd_modify_user_row(struct target *target, uint32_t value, - uint8_t startb, uint8_t endb) -{ - int res; - - 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; - } - - /* Retrieve the MCU's page size, in bytes. This is also the size of the - * entire User Row. */ - uint32_t page_size; - res = samd_get_flash_page_info(target, &page_size, NULL); - if (res != ERROR_OK) { - LOG_ERROR("Couldn't determine Flash page size"); - return res; - } - - /* Make sure the size is sane before we allocate. */ - assert(page_size > 0 && page_size <= SAMD_PAGE_SIZE_MAX); - - /* Make sure we're within the single page that comprises the User Row. */ - if (startb >= (page_size * 8) || endb >= (page_size * 8)) { - LOG_ERROR("Can't modify bits outside the User Row page range"); - return ERROR_FAIL; - } - - uint8_t *buf = malloc(page_size); - 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); - if (res != ERROR_OK) - goto out_user_row; - - /* We will need to erase before writing if the new value needs a '1' in any - * position for which the current value had a '0'. Otherwise we can avoid - * erasing. */ - uint32_t cur = buf_get_u32(buf, startb, endb - startb + 1); - if ((~cur) & value) { - res = samd_erase_row(target, SAMD_USER_ROW); - if (res != ERROR_OK) { - LOG_ERROR("Couldn't erase user row"); - goto out_user_row; - } - } - - /* 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. */ - 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; - } - - /* Success */ - res = ERROR_OK; - -out_user_row: - free(buf); - - return res; -} - -static int samd_protect(struct flash_bank *bank, int set, int first, int last) -{ - struct samd_info *chip = (struct samd_info *)bank->driver_priv; - - /* We can issue lock/unlock region commands with the target running but - * the settings won't persist unless we're able to modify the LOCK regions - * and that requires the target to be halted. */ - if (bank->target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - int res = ERROR_OK; - - for (int s = first; s <= last; s++) { - if (set != bank->sectors[s].is_protected) { - /* Load an address that is within this sector (we use offset 0) */ - res = target_write_u32(bank->target, - SAMD_NVMCTRL + SAMD_NVMCTRL_ADDR, - ((s * chip->sector_size) >> 1)); - if (res != ERROR_OK) - goto exit; - - /* Tell the controller to lock that sector */ - res = samd_issue_nvmctrl_command(bank->target, - set ? SAMD_NVM_CMD_LR : SAMD_NVM_CMD_UR); - if (res != ERROR_OK) - goto exit; - } - } - - /* 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, 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. */ - - res = samd_modify_user_row(bank->target, set ? 0x0000 : 0xFFFF, - 48 + first, 48 + last); - if (res != ERROR_OK) - LOG_WARNING("SAMD: protect settings were not made persistent!"); - - res = ERROR_OK; - -exit: - samd_protect_check(bank); - - return res; -} - -static int samd_erase(struct flash_bank *bank, int first, int last) -{ - int res; - int rows_in_sector; - struct samd_info *chip = (struct samd_info *)bank->driver_priv; - - if (bank->target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - - return ERROR_TARGET_NOT_HALTED; - } - - if (!chip->probed) { - if (samd_probe(bank) != ERROR_OK) - return ERROR_FLASH_BANK_NOT_PROBED; - } - - /* The SAMD NVM has row erase granularity. There are four pages in a row - * and the number of rows in a sector depends on the sector size, which in - * turn depends on the Flash capacity as there is a fixed number of - * sectors. */ - rows_in_sector = chip->sector_size / (chip->page_size * 4); - - /* For each sector to be erased */ - for (int s = first; s <= last; s++) { - if (bank->sectors[s].is_protected) { - LOG_ERROR("SAMD: failed to erase sector %d. That sector is write-protected", s); - return ERROR_FLASH_OPERATION_FAILED; - } - - /* For each row in that sector */ - for (int r = s * rows_in_sector; r < (s + 1) * rows_in_sector; r++) { - res = samd_erase_row(bank->target, r * chip->page_size * 4); - if (res != ERROR_OK) { - LOG_ERROR("SAMD: failed to erase sector %d", s); - return res; - } - } - } - - return ERROR_OK; -} - - -static int samd_write(struct flash_bank *bank, const uint8_t *buffer, - uint32_t offset, uint32_t count) -{ - int res; - uint32_t nvm_ctrlb; - uint32_t address; - uint32_t pg_offset; - uint32_t nb; - uint32_t nw; - struct samd_info *chip = (struct samd_info *)bank->driver_priv; - uint8_t *pb = NULL; - bool manual_wp; - - if (bank->target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - if (!chip->probed) { - if (samd_probe(bank) != ERROR_OK) - return ERROR_FLASH_BANK_NOT_PROBED; - } - - /* Check if we need to do manual page write commands */ - res = target_read_u32(bank->target, SAMD_NVMCTRL + SAMD_NVMCTRL_CTRLB, &nvm_ctrlb); - - if (res != ERROR_OK) - return res; - - if (nvm_ctrlb & SAMD_NVM_CTRLB_MANW) - manual_wp = true; - else - manual_wp = false; - - res = samd_issue_nvmctrl_command(bank->target, SAMD_NVM_CMD_PBC); - if (res != ERROR_OK) { - LOG_ERROR("%s: %d", __func__, __LINE__); - return res; - } - - while (count) { - nb = chip->page_size - offset % chip->page_size; - if (count < nb) - nb = count; - - address = bank->base + offset; - pg_offset = offset % chip->page_size; - - if (offset % 4 || (offset + nb) % 4) { - /* Either start or end of write is not word aligned */ - if (!pb) { - pb = malloc(chip->page_size); - if (!pb) - return ERROR_FAIL; - } - - /* Set temporary page buffer to 0xff and overwrite the relevant part */ - memset(pb, 0xff, chip->page_size); - memcpy(pb + pg_offset, buffer, nb); - - /* Align start address to a word boundary */ - address -= offset % 4; - pg_offset -= offset % 4; - assert(pg_offset % 4 == 0); - - /* Extend length to whole words */ - nw = (nb + offset % 4 + 3) / 4; - assert(pg_offset + 4 * nw <= chip->page_size); - - /* Now we have original data extended by 0xff bytes - * to the nearest word boundary on both start and end */ - res = target_write_memory(bank->target, address, 4, nw, pb + pg_offset); - } else { - assert(nb % 4 == 0); - nw = nb / 4; - assert(pg_offset + 4 * nw <= chip->page_size); - - /* Word aligned data, use direct write from buffer */ - res = target_write_memory(bank->target, address, 4, nw, buffer); - } - if (res != ERROR_OK) { - LOG_ERROR("%s: %d", __func__, __LINE__); - goto free_pb; - } - - /* Devices with errata 13134 have automatic page write enabled by default - * For other devices issue a write page CMD to the NVM - * If the page has not been written up to the last word - * 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; - } - } - - /* Access through AHB is stalled while flash is being programmed */ - usleep(200); - - if (samd_check_error(bank->target)) { - LOG_ERROR("%s: write failed at address 0x%08" PRIx32, __func__, address); - res = ERROR_FAIL; - goto free_pb; - } - - /* We're done with the page contents */ - count -= nb; - offset += nb; - buffer += nb; - } - -free_pb: - if (pb) - free(pb); - - return res; -} - -FLASH_BANK_COMMAND_HANDLER(samd_flash_bank_command) -{ - struct samd_info *chip = samd_chips; - - while (chip) { - if (chip->target == bank->target) - break; - chip = chip->next; - } - - if (!chip) { - /* Create a new chip */ - chip = calloc(1, sizeof(*chip)); - if (!chip) - return ERROR_FAIL; - - chip->target = bank->target; - chip->probed = false; - - bank->driver_priv = chip; - - /* Insert it into the chips list (at head) */ - chip->next = samd_chips; - samd_chips = chip; - } - - if (bank->base != SAMD_FLASH) { - LOG_ERROR("Address 0x%08" PRIx32 " invalid bank address (try 0x%08" PRIx32 - "[at91samd series] )", - bank->base, SAMD_FLASH); - return ERROR_FAIL; - } - - return ERROR_OK; -} - -COMMAND_HANDLER(samd_handle_info_command) -{ - return ERROR_OK; -} - -COMMAND_HANDLER(samd_handle_chip_erase_command) -{ - struct target *target = get_current_target(CMD_CTX); - - if (target) { - /* Enable access to the DSU by disabling the write protect bit */ - target_write_u32(target, SAMD_PAC1, (1<<1)); - /* 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"); - } - - return ERROR_OK; -} - -COMMAND_HANDLER(samd_handle_set_security_command) -{ - int res = ERROR_OK; - struct target *target = get_current_target(CMD_CTX); - - if (CMD_ARGC < 1 || (CMD_ARGC >= 1 && (strcmp(CMD_ARGV[0], "enable")))) { - command_print(CMD_CTX, "supply the \"enable\" argument to proceed."); - return ERROR_COMMAND_SYNTAX_ERROR; - } - - if (target) { - if (target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - res = samd_issue_nvmctrl_command(target, SAMD_NVM_CMD_SSB); - - /* Check (and clear) error conditions */ - if (res == ERROR_OK) - command_print(CMD_CTX, "chip secured on next power-cycle"); - else - command_print(CMD_CTX, "failed to secure chip"); - } - - return res; -} - -COMMAND_HANDLER(samd_handle_eeprom_command) -{ - int res = ERROR_OK; - struct target *target = get_current_target(CMD_CTX); - - if (target) { - if (target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - if (CMD_ARGC >= 1) { - int val = atoi(CMD_ARGV[0]); - uint32_t code; - - if (val == 0) - code = 7; - else { - /* Try to match size in bytes with corresponding size code */ - for (code = 0; code <= 6; code++) { - if (val == (2 << (13 - code))) - break; - } - - if (code > 6) { - command_print(CMD_CTX, "Invalid EEPROM size. Please see " - "datasheet for a list valid sizes."); - return ERROR_COMMAND_SYNTAX_ERROR; - } - } - - res = samd_modify_user_row(target, code, 4, 6); - } else { - uint16_t val; - res = target_read_u16(target, SAMD_USER_ROW, &val); - if (res == ERROR_OK) { - uint32_t size = ((val >> 4) & 0x7); /* grab size code */ - - if (size == 0x7) - command_print(CMD_CTX, "EEPROM is disabled"); - else { - /* Otherwise, 6 is 256B, 0 is 16KB */ - command_print(CMD_CTX, "EEPROM size is %u bytes", - (2 << (13 - size))); - } - } - } - } - - return res; -} - -COMMAND_HANDLER(samd_handle_bootloader_command) -{ - int res = ERROR_OK; - struct target *target = get_current_target(CMD_CTX); - - if (target) { - if (target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - /* Retrieve the MCU's page size, in bytes. */ - uint32_t page_size; - res = samd_get_flash_page_info(target, &page_size, NULL); - if (res != ERROR_OK) { - LOG_ERROR("Couldn't determine Flash page size"); - return res; - } - - if (CMD_ARGC >= 1) { - int val = atoi(CMD_ARGV[0]); - uint32_t code; - - if (val == 0) - code = 7; - else { - /* Try to match size in bytes with corresponding size code */ - for (code = 0; code <= 6; code++) { - if ((unsigned int)val == (2UL << (8UL - code)) * page_size) - break; - } - - if (code > 6) { - command_print(CMD_CTX, "Invalid bootloader size. Please " - "see datasheet for a list valid sizes."); - return ERROR_COMMAND_SYNTAX_ERROR; - } - - } - - res = samd_modify_user_row(target, code, 0, 2); - } else { - uint16_t val; - res = target_read_u16(target, SAMD_USER_ROW, &val); - if (res == ERROR_OK) { - uint32_t size = (val & 0x7); /* grab size code */ - uint32_t nb; - - if (size == 0x7) - nb = 0; - else - nb = (2 << (8 - size)) * page_size; - - /* There are 4 pages per row */ - command_print(CMD_CTX, "Bootloader size is %" PRIu32 " bytes (%" PRIu32 " rows)", - nb, (uint32_t)(nb / (page_size * 4))); - } - } - } - - return res; -} - - - -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(); - - /* In case of sysresetreq, debug retains state set in cortex_m_assert_reset() - * so we just release reset held by DSU - * - * n_RESET (srst) clears the DP, so reenable debug and set vector catch here - * - * 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); - if (retval == ERROR_OK) - retval = mem_ap_write_u32(armv7m->debug_ap, DCB_DEMCR, - TRCENA | VC_HARDERR | VC_BUSERR | VC_CORERESET); - /* do not return on error here, releasing DSU reset is more important */ - } - - /* clear CPU Reset Phase Extension bit */ - int retval2 = target_write_u8(target, SAMD_DSU + SAMD_DSU_STATUSA, (1<<1)); - if (retval2 != ERROR_OK) - return retval2; - - return retval; -} - -static const struct command_registration at91samd_exec_command_handlers[] = { - { - .name = "dsu_reset_deassert", - .handler = samd_handle_reset_deassert, - .mode = COMMAND_EXEC, - .help = "deasert internal reset held by DSU" - }, - { - .name = "info", - .handler = samd_handle_info_command, - .mode = COMMAND_EXEC, - .help = "Print information about the current at91samd chip" - "and its flash configuration.", - }, - { - .name = "chip-erase", - .handler = samd_handle_chip_erase_command, - .mode = COMMAND_EXEC, - .help = "Erase the entire Flash by using the Chip" - "Erase feature in the Device Service Unit (DSU).", - }, - { - .name = "set-security", - .handler = samd_handle_set_security_command, - .mode = COMMAND_EXEC, - .help = "Secure the chip's Flash by setting the Security Bit." - "This makes it impossible to read the Flash contents." - "The only way to undo this is to issue the chip-erase" - "command.", - }, - { - .name = "eeprom", - .usage = "[size_in_bytes]", - .handler = samd_handle_eeprom_command, - .mode = COMMAND_EXEC, - .help = "Show or set the EEPROM size setting, stored in the User Row." - "Please see Table 20-3 of the SAMD20 datasheet for allowed values." - "Changes are stored immediately but take affect after the MCU is" - "reset.", - }, - { - .name = "bootloader", - .usage = "[size_in_bytes]", - .handler = samd_handle_bootloader_command, - .mode = COMMAND_EXEC, - .help = "Show or set the bootloader size, stored in the User Row." - "Please see Table 20-2 of the SAMD20 datasheet for allowed values." - "Changes are stored immediately but take affect after the MCU is" - "reset.", - }, - COMMAND_REGISTRATION_DONE -}; - -static const struct command_registration at91samd_command_handlers[] = { - { - .name = "at91samd", - .mode = COMMAND_ANY, - .help = "at91samd flash command group", - .usage = "", - .chain = at91samd_exec_command_handlers, - }, - COMMAND_REGISTRATION_DONE -}; - -struct flash_driver at91samd_flash = { - .name = "at91samd", - .commands = at91samd_command_handlers, - .flash_bank_command = samd_flash_bank_command, - .erase = samd_erase, - .protect = samd_protect, - .write = samd_write, - .read = default_flash_read, - .probe = samd_probe, - .auto_probe = samd_probe, - .erase_check = default_flash_blank_check, - .protect_check = samd_protect_check, -}; diff --git a/src/flash/nor/atsamv.c b/src/flash/nor/atsamv.c deleted file mode 100644 index d21419d09..000000000 --- a/src/flash/nor/atsamv.c +++ /dev/null @@ -1,739 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2009 by Duane Ellis * - * openocd@duaneellis.com * - * * - * Copyright (C) 2010 by Olaf Lüke (at91sam3s* support) * - * olaf@uni-paderborn.de * - * * - * Copyright (C) 2011 by Olivier Schonken, Jim Norris * - * (at91sam3x* & at91sam4 support)* * - * * - * Copyright (C) 2015 Morgan Quigley * - * (atsamv, atsams, and atsame support) * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -/* Some of the the lower level code was based on code supplied by - * ATMEL under this copyright. */ - -/* BEGIN ATMEL COPYRIGHT */ -/* ---------------------------------------------------------------------------- - * ATMEL Microcontroller Software Support - * ---------------------------------------------------------------------------- - * Copyright (c) 2009, Atmel Corporation - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * - Redistributions of source code must retain the above copyright notice, - * this list of conditions and the disclaimer below. - * - * Atmel's name may not be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE - * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, - * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * ---------------------------------------------------------------------------- - */ -/* END ATMEL COPYRIGHT */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "imp.h" -#include - -#define REG_NAME_WIDTH (12) - -#define SAMV_EFC_FCMD_GETD (0x0) /* (EFC) Get Flash Descriptor */ -#define SAMV_EFC_FCMD_WP (0x1) /* (EFC) Write Page */ -#define SAMV_EFC_FCMD_WPL (0x2) /* (EFC) Write Page and Lock */ -#define SAMV_EFC_FCMD_EWP (0x3) /* (EFC) Erase Page and Write Page */ -#define SAMV_EFC_FCMD_EWPL (0x4) /* (EFC) Erase Page, Write Page then Lock*/ -#define SAMV_EFC_FCMD_EA (0x5) /* (EFC) Erase All */ -#define SAMV_EFC_FCMD_EPA (0x7) /* (EFC) Erase pages */ -#define SAMV_EFC_FCMD_SLB (0x8) /* (EFC) Set Lock Bit */ -#define SAMV_EFC_FCMD_CLB (0x9) /* (EFC) Clear Lock Bit */ -#define SAMV_EFC_FCMD_GLB (0xA) /* (EFC) Get Lock Bit */ -#define SAMV_EFC_FCMD_SFB (0xB) /* (EFC) Set Fuse Bit */ -#define SAMV_EFC_FCMD_CFB (0xC) /* (EFC) Clear Fuse Bit */ -#define SAMV_EFC_FCMD_GFB (0xD) /* (EFC) Get Fuse Bit */ - -#define OFFSET_EFC_FMR 0 -#define OFFSET_EFC_FCR 4 -#define OFFSET_EFC_FSR 8 -#define OFFSET_EFC_FRR 12 - -#define SAMV_CHIPID_CIDR (0x400E0940) -#define SAMV_NUM_GPNVM_BITS 9 -#define SAMV_CONTROLLER_ADDR (0x400e0c00) -#define SAMV_SECTOR_SIZE 16384 -#define SAMV_PAGE_SIZE 512 -#define SAMV_FLASH_BASE 0x00400000 - -extern struct flash_driver atsamv_flash; - -struct samv_flash_bank { - int probed; - unsigned size_bytes; - unsigned gpnvm[SAMV_NUM_GPNVM_BITS]; -}; - -/* The actual sector size of the SAMV7 flash memory is 128K bytes. - * 16 sectors for a 2048KB device. The lock regions are 16KB per lock - * region, with a 2048KB device having 128 lock regions. - * For the best results, num_sectors is thus set to the number of lock - * regions, and the sector_size set to the lock region size. Page - * erases are used to erase 16KB sections when programming */ - -static int samv_efc_get_status(struct target *target, uint32_t *v) -{ - int r = target_read_u32(target, SAMV_CONTROLLER_ADDR + OFFSET_EFC_FSR, v); - return r; -} - -static int samv_efc_get_result(struct target *target, uint32_t *v) -{ - uint32_t rv; - int r = target_read_u32(target, SAMV_CONTROLLER_ADDR + OFFSET_EFC_FRR, &rv); - if (v) - *v = rv; - return r; -} - -static int samv_efc_start_command(struct target *target, - unsigned command, unsigned argument) -{ - uint32_t v; - samv_efc_get_status(target, &v); - if (!(v & 1)) { - LOG_ERROR("flash controller is not ready"); - return ERROR_FAIL; - } - - v = (0x5A << 24) | (argument << 8) | command; - LOG_DEBUG("starting flash command: 0x%08x", (unsigned int)(v)); - int r = target_write_u32(target, SAMV_CONTROLLER_ADDR + OFFSET_EFC_FCR, v); - if (r != ERROR_OK) - LOG_DEBUG("write failed"); - return r; -} - -static int samv_efc_perform_command(struct target *target, - unsigned command, unsigned argument, uint32_t *status) -{ - int r; - uint32_t v; - int64_t ms_now, ms_end; - - if (status) - *status = 0; - - r = samv_efc_start_command(target, command, argument); - if (r != ERROR_OK) - return r; - - ms_end = 10000 + timeval_ms(); - - do { - r = samv_efc_get_status(target, &v); - if (r != ERROR_OK) - return r; - ms_now = timeval_ms(); - if (ms_now > ms_end) { - /* error */ - LOG_ERROR("Command timeout"); - return ERROR_FAIL; - } - } while ((v & 1) == 0); - - /* if requested, copy the flash controller error bits back to the caller */ - if (status) - *status = (v & 0x6); - return ERROR_OK; -} - -static int samv_erase_pages(struct target *target, - int first_page, int num_pages, uint32_t *status) -{ - uint8_t erase_pages; - switch (num_pages) { - case 4: - erase_pages = 0x00; - break; - case 8: - erase_pages = 0x01; - break; - case 16: - erase_pages = 0x02; - break; - case 32: - erase_pages = 0x03; - break; - default: - erase_pages = 0x00; - break; - } - - /* SAMV_EFC_FCMD_EPA - * According to the datasheet FARG[15:2] defines the page from which - * the erase will start.This page must be modulo 4, 8, 16 or 32 - * according to the number of pages to erase. FARG[1:0] defines the - * number of pages to be erased. Previously (firstpage << 2) was used - * to conform to this, seems it should not be shifted... - */ - return samv_efc_perform_command(target, SAMV_EFC_FCMD_EPA, - first_page | erase_pages, status); -} - -static int samv_get_gpnvm(struct target *target, unsigned gpnvm, unsigned *out) -{ - uint32_t v; - int r; - - if (gpnvm >= SAMV_NUM_GPNVM_BITS) { - LOG_ERROR("invalid gpnvm %d, max: %d", gpnvm, SAMV_NUM_GPNVM_BITS); - return ERROR_FAIL; - } - - r = samv_efc_perform_command(target, SAMV_EFC_FCMD_GFB, 0, NULL); - if (r != ERROR_OK) { - LOG_ERROR("samv_get_gpnvm failed"); - return r; - } - - r = samv_efc_get_result(target, &v); - - if (out) - *out = (v >> gpnvm) & 1; - - return r; -} - -static int samv_clear_gpnvm(struct target *target, unsigned gpnvm) -{ - int r; - unsigned v; - - if (gpnvm >= SAMV_NUM_GPNVM_BITS) { - LOG_ERROR("invalid gpnvm %d, max: %d", gpnvm, SAMV_NUM_GPNVM_BITS); - return ERROR_FAIL; - } - r = samv_get_gpnvm(target, gpnvm, &v); - if (r != ERROR_OK) { - LOG_DEBUG("get gpnvm failed: %d", r); - return r; - } - r = samv_efc_perform_command(target, SAMV_EFC_FCMD_CFB, gpnvm, NULL); - LOG_DEBUG("clear gpnvm result: %d", r); - return r; -} - -static int samv_set_gpnvm(struct target *target, unsigned gpnvm) -{ - int r; - unsigned v; - if (gpnvm >= SAMV_NUM_GPNVM_BITS) { - LOG_ERROR("invalid gpnvm %d, max: %d", gpnvm, SAMV_NUM_GPNVM_BITS); - return ERROR_FAIL; - } - - r = samv_get_gpnvm(target, gpnvm, &v); - if (r != ERROR_OK) - return r; - if (v) { - r = ERROR_OK; /* the gpnvm bit is already set */ - } else { - /* we need to set it */ - r = samv_efc_perform_command(target, SAMV_EFC_FCMD_SFB, gpnvm, NULL); - } - return r; -} - -static int samv_flash_unlock(struct target *target, - unsigned start_sector, unsigned end_sector) -{ - int r; - uint32_t status; - uint32_t pg; - uint32_t pages_per_sector; - - /* todo: look into this... i think this should be done on lock regions */ - pages_per_sector = SAMV_SECTOR_SIZE / SAMV_PAGE_SIZE; - while (start_sector <= end_sector) { - pg = start_sector * pages_per_sector; - r = samv_efc_perform_command(target, SAMV_EFC_FCMD_CLB, pg, &status); - if (r != ERROR_OK) - return r; - start_sector++; - } - return ERROR_OK; -} - -static int samv_flash_lock(struct target *target, - unsigned start_sector, unsigned end_sector) -{ - uint32_t status; - uint32_t pg; - uint32_t pages_per_sector; - int r; - - /* todo: look into this... i think this should be done on lock regions */ - pages_per_sector = SAMV_SECTOR_SIZE / SAMV_PAGE_SIZE; - while (start_sector <= end_sector) { - pg = start_sector * pages_per_sector; - r = samv_efc_perform_command(target, SAMV_EFC_FCMD_SLB, pg, &status); - if (r != ERROR_OK) - return r; - start_sector++; - } - return ERROR_OK; -} - -static int samv_protect_check(struct flash_bank *bank) -{ - int r; - uint32_t v[4] = {0}; - - r = samv_efc_perform_command(bank->target, SAMV_EFC_FCMD_GLB, 0, NULL); - if (r == ERROR_OK) { - samv_efc_get_result(bank->target, &v[0]); - samv_efc_get_result(bank->target, &v[1]); - samv_efc_get_result(bank->target, &v[2]); - r = samv_efc_get_result(bank->target, &v[3]); - } - if (r != ERROR_OK) - return r; - - for (int x = 0; x < bank->num_sectors; x++) - bank->sectors[x].is_protected = (!!(v[x >> 5] & (1 << (x % 32)))); - return ERROR_OK; -} - -FLASH_BANK_COMMAND_HANDLER(samv_flash_bank_command) -{ - LOG_INFO("flash bank command"); - struct samv_flash_bank *samv_info; - samv_info = calloc(1, sizeof(struct samv_flash_bank)); - bank->driver_priv = samv_info; - return ERROR_OK; -} - -static int samv_get_device_id(struct flash_bank *bank, uint32_t *device_id) -{ - return target_read_u32(bank->target, SAMV_CHIPID_CIDR, device_id); -} - -static int samv_probe(struct flash_bank *bank) -{ - uint32_t device_id; - int r = samv_get_device_id(bank, &device_id); - if (r != ERROR_OK) - return r; - LOG_INFO("device id = 0x%08" PRIx32 "", device_id); - - uint8_t eproc = (device_id >> 5) & 0x7; - if (eproc != 0) { - 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 12: - bank->size = 1024 * 1024; - break; - case 14: - bank->size = 2048 * 1024; - break; - default: - LOG_ERROR("unrecognized flash size code: %d", nvm_size_code); - return ERROR_FAIL; - break; - } - - struct samv_flash_bank *samv_info = bank->driver_priv; - samv_info->size_bytes = bank->size; - samv_info->probed = 1; - - bank->base = SAMV_FLASH_BASE; - bank->num_sectors = bank->size / SAMV_SECTOR_SIZE; - bank->sectors = calloc(bank->num_sectors, sizeof(struct flash_sector)); - for (int s = 0; s < (int)bank->num_sectors; s++) { - bank->sectors[s].size = SAMV_SECTOR_SIZE; - bank->sectors[s].offset = s * SAMV_SECTOR_SIZE; - bank->sectors[s].is_erased = -1; - bank->sectors[s].is_protected = -1; - } - - r = samv_protect_check(bank); - if (r != ERROR_OK) - return r; - - return ERROR_OK; -} - -static int samv_auto_probe(struct flash_bank *bank) -{ - struct samv_flash_bank *samv_info = bank->driver_priv; - if (samv_info->probed) - return ERROR_OK; - return samv_probe(bank); -} - -static int samv_erase(struct flash_bank *bank, int first, int last) -{ - const int page_count = 32; /* 32 pages equals 16 KB lock region */ - - if (bank->target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - int r = samv_auto_probe(bank); - if (r != ERROR_OK) - return r; - - /* easy case: we've been requested to erase the entire flash */ - if ((first == 0) && ((last + 1) == (int)(bank->num_sectors))) - return samv_efc_perform_command(bank->target, SAMV_EFC_FCMD_EA, 0, NULL); - - LOG_INFO("erasing lock regions %d-%d...", first, last); - - for (int i = first; i <= last; i++) { - uint32_t status; - r = samv_erase_pages(bank->target, (i * page_count), page_count, &status); - LOG_INFO("erasing lock region %d", i); - if (r != ERROR_OK) - LOG_ERROR("error performing erase page @ lock region number %d", - (unsigned int)(i)); - if (status & (1 << 2)) { - LOG_ERROR("lock region %d is locked", (unsigned int)(i)); - return ERROR_FAIL; - } - if (status & (1 << 1)) { - LOG_ERROR("flash command error @lock region %d", (unsigned int)(i)); - return ERROR_FAIL; - } - } - return ERROR_OK; -} - -static int samv_protect(struct flash_bank *bank, int set, int first, int last) -{ - if (bank->target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - int r; - if (set) - r = samv_flash_lock(bank->target, (unsigned)(first), (unsigned)(last)); - else - r = samv_flash_unlock(bank->target, (unsigned)(first), (unsigned)(last)); - - return r; -} - -static int samv_page_read(struct target *target, - unsigned page_num, uint8_t *buf) -{ - uint32_t addr = SAMV_FLASH_BASE + page_num * SAMV_PAGE_SIZE; - int r = target_read_memory(target, addr, 4, SAMV_PAGE_SIZE / 4, buf); - if (r != ERROR_OK) - LOG_ERROR("flash program failed to read page @ 0x%08x", - (unsigned int)(addr)); - return r; -} - -static int samv_page_write(struct target *target, - unsigned pagenum, const uint8_t *buf) -{ - uint32_t status; - const uint32_t addr = SAMV_FLASH_BASE + pagenum * SAMV_PAGE_SIZE; - int r; - - LOG_DEBUG("write page %u at address 0x%08x", pagenum, (unsigned int)addr); - r = target_write_memory(target, addr, 4, SAMV_PAGE_SIZE / 4, buf); - if (r != ERROR_OK) { - LOG_ERROR("failed to buffer page at 0x%08x", (unsigned int)addr); - return r; - } - - r = samv_efc_perform_command(target, SAMV_EFC_FCMD_WP, pagenum, &status); - if (r != ERROR_OK) - LOG_ERROR("error performing write page at 0x%08x", (unsigned int)addr); - if (status & (1 << 2)) { - LOG_ERROR("page at 0x%08x is locked", (unsigned int)addr); - return ERROR_FAIL; - } - if (status & (1 << 1)) { - LOG_ERROR("flash command error at 0x%08x", (unsigned int)addr); - return ERROR_FAIL; - } - return ERROR_OK; -} - -static int samv_write(struct flash_bank *bank, const uint8_t *buffer, - uint32_t offset, uint32_t count) -{ - if (bank->target->state != TARGET_HALTED) { - LOG_ERROR("target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - if (count == 0) - return ERROR_OK; - - if ((offset + count) > bank->size) { - LOG_ERROR("flash write error - past end of bank"); - LOG_ERROR(" offset: 0x%08x, count 0x%08x, bank end: 0x%08x", - (unsigned int)(offset), - (unsigned int)(count), - (unsigned int)(bank->size)); - return ERROR_FAIL; - } - - uint8_t pagebuffer[SAMV_PAGE_SIZE] = {0}; - uint32_t page_cur = offset / SAMV_PAGE_SIZE; - uint32_t page_end = (offset + count - 1) / SAMV_PAGE_SIZE; - - LOG_DEBUG("offset: 0x%08x, count: 0x%08x", - (unsigned int)(offset), (unsigned int)(count)); - LOG_DEBUG("page start: %d, page end: %d", (int)(page_cur), (int)(page_end)); - - /* Special case: all one page */ - /* Otherwise: */ - /* (1) non-aligned start */ - /* (2) body pages */ - /* (3) non-aligned end. */ - - int r; - uint32_t page_offset; - - /* handle special case - all one page. */ - if (page_cur == page_end) { - LOG_DEBUG("special case, all in one page"); - r = samv_page_read(bank->target, page_cur, pagebuffer); - if (r != ERROR_OK) - return r; - - page_offset = offset & (SAMV_PAGE_SIZE-1); - memcpy(pagebuffer + page_offset, buffer, count); - - r = samv_page_write(bank->target, page_cur, pagebuffer); - if (r != ERROR_OK) - return r; - return ERROR_OK; - } - - /* step 1) handle the non-aligned starting address */ - page_offset = offset & (SAMV_PAGE_SIZE - 1); - if (page_offset) { - LOG_DEBUG("non-aligned start"); - /* read the partial page */ - r = samv_page_read(bank->target, page_cur, pagebuffer); - if (r != ERROR_OK) - return r; - - /* over-write with new data */ - uint32_t n = SAMV_PAGE_SIZE - page_offset; - memcpy(pagebuffer + page_offset, buffer, n); - - r = samv_page_write(bank->target, page_cur, pagebuffer); - if (r != ERROR_OK) - return r; - - count -= n; - offset += n; - buffer += n; - page_cur++; - } - - /* By checking that offset is correct here, we also fix a clang warning */ - assert(offset % SAMV_PAGE_SIZE == 0); - - /* step 2) handle the full pages */ - LOG_DEBUG("full page loop: cur=%d, end=%d, count = 0x%08x", - (int)page_cur, (int)page_end, (unsigned int)(count)); - - while ((page_cur < page_end) && (count >= SAMV_PAGE_SIZE)) { - r = samv_page_write(bank->target, page_cur, buffer); - if (r != ERROR_OK) - return r; - count -= SAMV_PAGE_SIZE; - buffer += SAMV_PAGE_SIZE; - page_cur += 1; - } - - /* step 3) write final page, if it's partial (otherwise it's already done) */ - if (count) { - LOG_DEBUG("final partial page, count = 0x%08x", (unsigned int)(count)); - /* we have a partial page */ - r = samv_page_read(bank->target, page_cur, pagebuffer); - if (r != ERROR_OK) - return r; - memcpy(pagebuffer, buffer, count); /* data goes at start of page */ - r = samv_page_write(bank->target, page_cur, pagebuffer); - if (r != ERROR_OK) - return r; - } - return ERROR_OK; -} - -static int samv_get_info(struct flash_bank *bank, char *buf, int buf_size) -{ - struct samv_flash_bank *samv_info = bank->driver_priv; - if (!samv_info->probed) { - int r = samv_probe(bank); - if (ERROR_OK != r) - return r; - } - snprintf(buf, buf_size, "Cortex-M7 detected with %d kB flash", - bank->size / 1024); - return ERROR_OK; -} - -COMMAND_HANDLER(samv_handle_gpnvm_command) -{ - struct flash_bank *bank = get_flash_bank_by_num_noprobe(0); - if (!bank) - return ERROR_FAIL; - struct samv_flash_bank *samv_info = bank->driver_priv; - struct target *target = bank->target; - - if (target->state != TARGET_HALTED) { - LOG_ERROR("target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - int r; - if (!samv_info->probed) { - r = samv_auto_probe(bank); - if (r != ERROR_OK) - return r; - } - - int who = 0; - - switch (CMD_ARGC) { - case 0: - goto showall; - break; - case 1: - who = -1; - break; - case 2: - if (!strcmp(CMD_ARGV[0], "show") && !strcmp(CMD_ARGV[1], "all")) - who = -1; - else { - uint32_t v32; - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], v32); - who = v32; - } - break; - default: - return ERROR_COMMAND_SYNTAX_ERROR; - break; - } - - uint32_t v; - if (!strcmp("show", CMD_ARGV[0])) { - if (who == -1) { -showall: - r = ERROR_OK; - for (int x = 0; x < SAMV_NUM_GPNVM_BITS; x++) { - r = samv_get_gpnvm(target, x, &v); - if (r != ERROR_OK) - break; - command_print(CMD_CTX, "samv-gpnvm%u: %u", x, v); - } - return r; - } - if ((who >= 0) && (((unsigned)who) < SAMV_NUM_GPNVM_BITS)) { - r = samv_get_gpnvm(target, who, &v); - command_print(CMD_CTX, "samv-gpnvm%u: %u", who, v); - return r; - } else { - command_print(CMD_CTX, "invalid gpnvm: %u", who); - return ERROR_COMMAND_SYNTAX_ERROR; - } - } - - if (who == -1) { - command_print(CMD_CTX, "missing gpnvm number"); - return ERROR_COMMAND_SYNTAX_ERROR; - } - - if (!strcmp("set", CMD_ARGV[0])) - r = samv_set_gpnvm(target, who); - else if (!strcmp("clr", CMD_ARGV[0]) || !strcmp("clear", CMD_ARGV[0])) - r = samv_clear_gpnvm(target, who); - else { - command_print(CMD_CTX, "unknown command: %s", CMD_ARGV[0]); - r = ERROR_COMMAND_SYNTAX_ERROR; - } - return r; -} - -static const struct command_registration atsamv_exec_command_handlers[] = { - { - .name = "gpnvm", - .handler = samv_handle_gpnvm_command, - .mode = COMMAND_EXEC, - .usage = "[('clr'|'set'|'show') bitnum]", - .help = "Without arguments, shows all bits in the gpnvm " - "register. Otherwise, clears, sets, or shows one " - "General Purpose Non-Volatile Memory (gpnvm) bit.", - }, - COMMAND_REGISTRATION_DONE -}; - -static const struct command_registration atsamv_command_handlers[] = { - { - .name = "atsamv", - .mode = COMMAND_ANY, - .help = "atsamv flash command group", - .usage = "", - .chain = atsamv_exec_command_handlers, - }, - COMMAND_REGISTRATION_DONE -}; - -struct flash_driver atsamv_flash = { - .name = "atsamv", - .commands = atsamv_command_handlers, - .flash_bank_command = samv_flash_bank_command, - .erase = samv_erase, - .protect = samv_protect, - .write = samv_write, - .read = default_flash_read, - .probe = samv_probe, - .auto_probe = samv_auto_probe, - .erase_check = default_flash_blank_check, - .protect_check = samv_protect_check, - .info = samv_get_info, -}; diff --git a/src/flash/nor/avrf.c b/src/flash/nor/avrf.c deleted file mode 100644 index 627418c63..000000000 --- a/src/flash/nor/avrf.c +++ /dev/null @@ -1,489 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2009 by Simon Qian * - * SimonQian@SimonQian.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "imp.h" -#include - -/* AVR_JTAG_Instructions */ -#define AVR_JTAG_INS_LEN 4 -/* Public Instructions: */ -#define AVR_JTAG_INS_EXTEST 0x00 -#define AVR_JTAG_INS_IDCODE 0x01 -#define AVR_JTAG_INS_SAMPLE_PRELOAD 0x02 -#define AVR_JTAG_INS_BYPASS 0x0F -/* AVR Specified Public Instructions: */ -#define AVR_JTAG_INS_AVR_RESET 0x0C -#define AVR_JTAG_INS_PROG_ENABLE 0x04 -#define AVR_JTAG_INS_PROG_COMMANDS 0x05 -#define AVR_JTAG_INS_PROG_PAGELOAD 0x06 -#define AVR_JTAG_INS_PROG_PAGEREAD 0x07 - -/* Data Registers: */ -#define AVR_JTAG_REG_Bypass_Len 1 -#define AVR_JTAG_REG_DeviceID_Len 32 - -#define AVR_JTAG_REG_Reset_Len 1 -#define AVR_JTAG_REG_JTAGID_Len 32 -#define AVR_JTAG_REG_ProgrammingEnable_Len 16 -#define AVR_JTAG_REG_ProgrammingCommand_Len 15 -#define AVR_JTAG_REG_FlashDataByte_Len 16 - -struct avrf_type { - char name[15]; - uint16_t chip_id; - int flash_page_size; - int flash_page_num; - int eeprom_page_size; - int eeprom_page_num; -}; - -struct avrf_flash_bank { - int ppage_size; - int probed; -}; - -static const struct avrf_type avft_chips_info[] = { -/* name, chip_id, flash_page_size, flash_page_num, - * eeprom_page_size, eeprom_page_num - */ - {"atmega128", 0x9702, 256, 512, 8, 512}, - {"at90can128", 0x9781, 256, 512, 8, 512}, - {"at90usb128", 0x9782, 256, 512, 8, 512}, - {"atmega164p", 0x940a, 128, 128, 4, 128}, - {"atmega324p", 0x9508, 128, 256, 4, 256}, - {"atmega324pa", 0x9511, 128, 256, 4, 256}, - {"atmega644p", 0x960a, 256, 256, 8, 256}, - {"atmega1284p", 0x9705, 256, 512, 8, 512}, -}; - -/* avr program functions */ -static int avr_jtag_reset(struct avr_common *avr, uint32_t reset) -{ - avr_jtag_sendinstr(avr->jtag_info.tap, NULL, AVR_JTAG_INS_AVR_RESET); - avr_jtag_senddat(avr->jtag_info.tap, NULL, reset, AVR_JTAG_REG_Reset_Len); - - return ERROR_OK; -} - -static int avr_jtag_read_jtagid(struct avr_common *avr, uint32_t *id) -{ - avr_jtag_sendinstr(avr->jtag_info.tap, NULL, AVR_JTAG_INS_IDCODE); - avr_jtag_senddat(avr->jtag_info.tap, id, 0, AVR_JTAG_REG_JTAGID_Len); - - return ERROR_OK; -} - -static int avr_jtagprg_enterprogmode(struct avr_common *avr) -{ - avr_jtag_reset(avr, 1); - - avr_jtag_sendinstr(avr->jtag_info.tap, NULL, AVR_JTAG_INS_PROG_ENABLE); - avr_jtag_senddat(avr->jtag_info.tap, NULL, 0xA370, AVR_JTAG_REG_ProgrammingEnable_Len); - - return ERROR_OK; -} - -static int avr_jtagprg_leaveprogmode(struct avr_common *avr) -{ - avr_jtag_sendinstr(avr->jtag_info.tap, NULL, AVR_JTAG_INS_PROG_COMMANDS); - avr_jtag_senddat(avr->jtag_info.tap, NULL, 0x2300, AVR_JTAG_REG_ProgrammingCommand_Len); - avr_jtag_senddat(avr->jtag_info.tap, NULL, 0x3300, AVR_JTAG_REG_ProgrammingCommand_Len); - - avr_jtag_sendinstr(avr->jtag_info.tap, NULL, AVR_JTAG_INS_PROG_ENABLE); - avr_jtag_senddat(avr->jtag_info.tap, NULL, 0, AVR_JTAG_REG_ProgrammingEnable_Len); - - avr_jtag_reset(avr, 0); - - return ERROR_OK; -} - -static int avr_jtagprg_chiperase(struct avr_common *avr) -{ - uint32_t poll_value; - - avr_jtag_sendinstr(avr->jtag_info.tap, NULL, AVR_JTAG_INS_PROG_COMMANDS); - avr_jtag_senddat(avr->jtag_info.tap, NULL, 0x2380, AVR_JTAG_REG_ProgrammingCommand_Len); - avr_jtag_senddat(avr->jtag_info.tap, NULL, 0x3180, AVR_JTAG_REG_ProgrammingCommand_Len); - avr_jtag_senddat(avr->jtag_info.tap, NULL, 0x3380, AVR_JTAG_REG_ProgrammingCommand_Len); - avr_jtag_senddat(avr->jtag_info.tap, NULL, 0x3380, AVR_JTAG_REG_ProgrammingCommand_Len); - - do { - poll_value = 0; - avr_jtag_senddat(avr->jtag_info.tap, - &poll_value, - 0x3380, - AVR_JTAG_REG_ProgrammingCommand_Len); - if (ERROR_OK != mcu_execute_queue()) - return ERROR_FAIL; - LOG_DEBUG("poll_value = 0x%04" PRIx32 "", poll_value); - } while (!(poll_value & 0x0200)); - - return ERROR_OK; -} - -static int avr_jtagprg_writeflashpage(struct avr_common *avr, - const uint8_t *page_buf, - uint32_t buf_size, - uint32_t addr, - uint32_t page_size) -{ - uint32_t i, poll_value; - - avr_jtag_sendinstr(avr->jtag_info.tap, NULL, AVR_JTAG_INS_PROG_COMMANDS); - avr_jtag_senddat(avr->jtag_info.tap, NULL, 0x2310, AVR_JTAG_REG_ProgrammingCommand_Len); - - /* load addr high byte */ - avr_jtag_senddat(avr->jtag_info.tap, - NULL, - 0x0700 | ((addr >> 9) & 0xFF), - AVR_JTAG_REG_ProgrammingCommand_Len); - - /* load addr low byte */ - avr_jtag_senddat(avr->jtag_info.tap, - NULL, - 0x0300 | ((addr >> 1) & 0xFF), - AVR_JTAG_REG_ProgrammingCommand_Len); - - avr_jtag_sendinstr(avr->jtag_info.tap, NULL, AVR_JTAG_INS_PROG_PAGELOAD); - - for (i = 0; i < page_size; i++) { - if (i < buf_size) - avr_jtag_senddat(avr->jtag_info.tap, NULL, page_buf[i], 8); - else - avr_jtag_senddat(avr->jtag_info.tap, NULL, 0xFF, 8); - } - - avr_jtag_sendinstr(avr->jtag_info.tap, NULL, AVR_JTAG_INS_PROG_COMMANDS); - - avr_jtag_senddat(avr->jtag_info.tap, NULL, 0x3700, AVR_JTAG_REG_ProgrammingCommand_Len); - avr_jtag_senddat(avr->jtag_info.tap, NULL, 0x3500, AVR_JTAG_REG_ProgrammingCommand_Len); - avr_jtag_senddat(avr->jtag_info.tap, NULL, 0x3700, AVR_JTAG_REG_ProgrammingCommand_Len); - avr_jtag_senddat(avr->jtag_info.tap, NULL, 0x3700, AVR_JTAG_REG_ProgrammingCommand_Len); - - do { - poll_value = 0; - avr_jtag_senddat(avr->jtag_info.tap, - &poll_value, - 0x3700, - AVR_JTAG_REG_ProgrammingCommand_Len); - if (ERROR_OK != mcu_execute_queue()) - return ERROR_FAIL; - LOG_DEBUG("poll_value = 0x%04" PRIx32 "", poll_value); - } while (!(poll_value & 0x0200)); - - return ERROR_OK; -} - -FLASH_BANK_COMMAND_HANDLER(avrf_flash_bank_command) -{ - struct avrf_flash_bank *avrf_info; - - if (CMD_ARGC < 6) - return ERROR_COMMAND_SYNTAX_ERROR; - - avrf_info = malloc(sizeof(struct avrf_flash_bank)); - bank->driver_priv = avrf_info; - - avrf_info->probed = 0; - - return ERROR_OK; -} - -static int avrf_erase(struct flash_bank *bank, int first, int last) -{ - struct target *target = bank->target; - struct avr_common *avr = target->arch_info; - int status; - - LOG_DEBUG("%s", __func__); - - if (target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - status = avr_jtagprg_enterprogmode(avr); - if (status != ERROR_OK) - return status; - - status = avr_jtagprg_chiperase(avr); - if (status != ERROR_OK) - return status; - - return avr_jtagprg_leaveprogmode(avr); -} - -static int avrf_protect(struct flash_bank *bank, int set, int first, int last) -{ - LOG_INFO("%s", __func__); - return ERROR_OK; -} - -static int avrf_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count) -{ - struct target *target = bank->target; - struct avr_common *avr = target->arch_info; - uint32_t cur_size, cur_buffer_size, page_size; - - if (bank->target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - page_size = bank->sectors[0].size; - if ((offset % page_size) != 0) { - LOG_WARNING("offset 0x%" PRIx32 " breaks required %" PRIu32 "-byte alignment", - offset, - page_size); - return ERROR_FLASH_DST_BREAKS_ALIGNMENT; - } - - LOG_DEBUG("offset is 0x%08" PRIx32 "", offset); - LOG_DEBUG("count is %" PRId32 "", count); - - if (ERROR_OK != avr_jtagprg_enterprogmode(avr)) - return ERROR_FAIL; - - cur_size = 0; - while (count > 0) { - if (count > page_size) - cur_buffer_size = page_size; - else - cur_buffer_size = count; - avr_jtagprg_writeflashpage(avr, - buffer + cur_size, - cur_buffer_size, - offset + cur_size, - page_size); - count -= cur_buffer_size; - cur_size += cur_buffer_size; - - keep_alive(); - } - - return avr_jtagprg_leaveprogmode(avr); -} - -#define EXTRACT_MFG(X) (((X) & 0xffe) >> 1) -#define EXTRACT_PART(X) (((X) & 0xffff000) >> 12) -#define EXTRACT_VER(X) (((X) & 0xf0000000) >> 28) - -static int avrf_probe(struct flash_bank *bank) -{ - struct target *target = bank->target; - struct avrf_flash_bank *avrf_info = bank->driver_priv; - struct avr_common *avr = target->arch_info; - const struct avrf_type *avr_info = NULL; - int i; - uint32_t device_id; - - if (bank->target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - avrf_info->probed = 0; - - avr_jtag_read_jtagid(avr, &device_id); - if (ERROR_OK != mcu_execute_queue()) - return ERROR_FAIL; - - LOG_INFO("device id = 0x%08" PRIx32 "", device_id); - if (EXTRACT_MFG(device_id) != 0x1F) - LOG_ERROR("0x%" PRIx32 " is invalid Manufacturer for avr, 0x%X is expected", - EXTRACT_MFG(device_id), - 0x1F); - - for (i = 0; i < (int)ARRAY_SIZE(avft_chips_info); i++) { - if (avft_chips_info[i].chip_id == EXTRACT_PART(device_id)) { - avr_info = &avft_chips_info[i]; - LOG_INFO("target device is %s", avr_info->name); - break; - } - } - - if (avr_info != NULL) { - if (bank->sectors) { - free(bank->sectors); - bank->sectors = NULL; - } - - /* chip found */ - bank->base = 0x00000000; - bank->size = (avr_info->flash_page_size * avr_info->flash_page_num); - bank->num_sectors = avr_info->flash_page_num; - bank->sectors = malloc(sizeof(struct flash_sector) * avr_info->flash_page_num); - - for (i = 0; i < avr_info->flash_page_num; i++) { - bank->sectors[i].offset = i * avr_info->flash_page_size; - bank->sectors[i].size = avr_info->flash_page_size; - bank->sectors[i].is_erased = -1; - bank->sectors[i].is_protected = 1; - } - - avrf_info->probed = 1; - return ERROR_OK; - } else { - /* chip not supported */ - LOG_ERROR("0x%" PRIx32 " is not support for avr", EXTRACT_PART(device_id)); - - avrf_info->probed = 1; - return ERROR_FAIL; - } -} - -static int avrf_auto_probe(struct flash_bank *bank) -{ - struct avrf_flash_bank *avrf_info = bank->driver_priv; - if (avrf_info->probed) - return ERROR_OK; - return avrf_probe(bank); -} - -static int avrf_protect_check(struct flash_bank *bank) -{ - LOG_INFO("%s", __func__); - return ERROR_OK; -} - -static int avrf_info(struct flash_bank *bank, char *buf, int buf_size) -{ - struct target *target = bank->target; - struct avr_common *avr = target->arch_info; - const struct avrf_type *avr_info = NULL; - int i; - uint32_t device_id; - - if (bank->target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - avr_jtag_read_jtagid(avr, &device_id); - if (ERROR_OK != mcu_execute_queue()) - return ERROR_FAIL; - - LOG_INFO("device id = 0x%08" PRIx32 "", device_id); - if (EXTRACT_MFG(device_id) != 0x1F) - LOG_ERROR("0x%" PRIx32 " is invalid Manufacturer for avr, 0x%X is expected", - EXTRACT_MFG(device_id), - 0x1F); - - for (i = 0; i < (int)ARRAY_SIZE(avft_chips_info); i++) { - if (avft_chips_info[i].chip_id == EXTRACT_PART(device_id)) { - avr_info = &avft_chips_info[i]; - LOG_INFO("target device is %s", avr_info->name); - - break; - } - } - - if (avr_info != NULL) { - /* chip found */ - snprintf(buf, buf_size, "%s - Rev: 0x%" PRIx32 "", avr_info->name, - EXTRACT_VER(device_id)); - return ERROR_OK; - } else { - /* chip not supported */ - snprintf(buf, buf_size, "Cannot identify target as a avr\n"); - return ERROR_FLASH_OPERATION_FAILED; - } -} - -static int avrf_mass_erase(struct flash_bank *bank) -{ - struct target *target = bank->target; - struct avr_common *avr = target->arch_info; - - if (target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - if ((ERROR_OK != avr_jtagprg_enterprogmode(avr)) - || (ERROR_OK != avr_jtagprg_chiperase(avr)) - || (ERROR_OK != avr_jtagprg_leaveprogmode(avr))) - return ERROR_FAIL; - - return ERROR_OK; -} - -COMMAND_HANDLER(avrf_handle_mass_erase_command) -{ - int i; - - 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; - - if (avrf_mass_erase(bank) == ERROR_OK) { - /* set all sectors as erased */ - for (i = 0; i < bank->num_sectors; i++) - bank->sectors[i].is_erased = 1; - - command_print(CMD_CTX, "avr mass erase complete"); - } else - command_print(CMD_CTX, "avr mass erase failed"); - - LOG_DEBUG("%s", __func__); - return ERROR_OK; -} - -static const struct command_registration avrf_exec_command_handlers[] = { - { - .name = "mass_erase", - .usage = "", - .handler = avrf_handle_mass_erase_command, - .mode = COMMAND_EXEC, - .help = "erase entire device", - }, - COMMAND_REGISTRATION_DONE -}; -static const struct command_registration avrf_command_handlers[] = { - { - .name = "avrf", - .mode = COMMAND_ANY, - .help = "AVR flash command group", - .usage = "", - .chain = avrf_exec_command_handlers, - }, - COMMAND_REGISTRATION_DONE -}; - -struct flash_driver avr_flash = { - .name = "avr", - .commands = avrf_command_handlers, - .flash_bank_command = avrf_flash_bank_command, - .erase = avrf_erase, - .protect = avrf_protect, - .write = avrf_write, - .read = default_flash_read, - .probe = avrf_probe, - .auto_probe = avrf_auto_probe, - .erase_check = default_flash_blank_check, - .protect_check = avrf_protect_check, - .info = avrf_info, -}; diff --git a/src/flash/nor/cfi.c b/src/flash/nor/cfi.c deleted file mode 100644 index f7d8a90f1..000000000 --- a/src/flash/nor/cfi.c +++ /dev/null @@ -1,3131 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005, 2007 by Dominic Rath * - * Dominic.Rath@gmx.de * - * Copyright (C) 2009 Michael Schwingen * - * michael@schwingen.org * - * Copyright (C) 2010 Øyvind Harboe * - * Copyright (C) 2010 by Antonio Borneo * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 -#include "config.h" -#endif - -#include "imp.h" -#include "cfi.h" -#include "non_cfi.h" -#include -#include -#include -#include -#include -#include - -#define CFI_MAX_BUS_WIDTH 4 -#define CFI_MAX_CHIP_WIDTH 4 - -/* defines internal maximum size for code fragment in cfi_intel_write_block() */ -#define CFI_MAX_INTEL_CODESIZE 256 - -/* some id-types with specific handling */ -#define AT49BV6416 0x00d6 -#define AT49BV6416T 0x00d2 - -static const struct cfi_unlock_addresses cfi_unlock_addresses[] = { - [CFI_UNLOCK_555_2AA] = { .unlock1 = 0x555, .unlock2 = 0x2aa }, - [CFI_UNLOCK_5555_2AAA] = { .unlock1 = 0x5555, .unlock2 = 0x2aaa }, -}; - -static const int cfi_status_poll_mask_dq6_dq7 = CFI_STATUS_POLL_MASK_DQ6_DQ7; - -/* CFI fixups forward declarations */ -static void cfi_fixup_0002_erase_regions(struct flash_bank *bank, const void *param); -static void cfi_fixup_0002_unlock_addresses(struct flash_bank *bank, const void *param); -static void cfi_fixup_reversed_erase_regions(struct flash_bank *bank, const void *param); -static void cfi_fixup_0002_write_buffer(struct flash_bank *bank, const void *param); -static void cfi_fixup_0002_polling_bits(struct flash_bank *bank, const void *param); - -/* fixup after reading cmdset 0002 primary query table */ -static const struct cfi_fixup cfi_0002_fixups[] = { - {CFI_MFR_SST, 0x00D4, cfi_fixup_0002_unlock_addresses, - &cfi_unlock_addresses[CFI_UNLOCK_5555_2AAA]}, - {CFI_MFR_SST, 0x00D5, cfi_fixup_0002_unlock_addresses, - &cfi_unlock_addresses[CFI_UNLOCK_5555_2AAA]}, - {CFI_MFR_SST, 0x00D6, cfi_fixup_0002_unlock_addresses, - &cfi_unlock_addresses[CFI_UNLOCK_5555_2AAA]}, - {CFI_MFR_SST, 0x00D7, cfi_fixup_0002_unlock_addresses, - &cfi_unlock_addresses[CFI_UNLOCK_5555_2AAA]}, - {CFI_MFR_SST, 0x2780, cfi_fixup_0002_unlock_addresses, - &cfi_unlock_addresses[CFI_UNLOCK_5555_2AAA]}, - {CFI_MFR_SST, 0x274b, cfi_fixup_0002_unlock_addresses, - &cfi_unlock_addresses[CFI_UNLOCK_5555_2AAA]}, - {CFI_MFR_SST, 0x235f, cfi_fixup_0002_polling_bits, /* 39VF3201C */ - &cfi_status_poll_mask_dq6_dq7}, - {CFI_MFR_SST, 0x236d, cfi_fixup_0002_unlock_addresses, - &cfi_unlock_addresses[CFI_UNLOCK_555_2AA]}, - {CFI_MFR_ATMEL, 0x00C8, cfi_fixup_reversed_erase_regions, NULL}, - {CFI_MFR_ST, 0x22C4, cfi_fixup_reversed_erase_regions, NULL}, /* M29W160ET */ - {CFI_MFR_FUJITSU, 0x22ea, cfi_fixup_0002_unlock_addresses, - &cfi_unlock_addresses[CFI_UNLOCK_555_2AA]}, - {CFI_MFR_FUJITSU, 0x226b, cfi_fixup_0002_unlock_addresses, - &cfi_unlock_addresses[CFI_UNLOCK_5555_2AAA]}, - {CFI_MFR_AMIC, 0xb31a, cfi_fixup_0002_unlock_addresses, - &cfi_unlock_addresses[CFI_UNLOCK_555_2AA]}, - {CFI_MFR_MX, 0x225b, cfi_fixup_0002_unlock_addresses, - &cfi_unlock_addresses[CFI_UNLOCK_555_2AA]}, - {CFI_MFR_EON, 0x225b, cfi_fixup_0002_unlock_addresses, - &cfi_unlock_addresses[CFI_UNLOCK_555_2AA]}, - {CFI_MFR_AMD, 0x225b, cfi_fixup_0002_unlock_addresses, - &cfi_unlock_addresses[CFI_UNLOCK_555_2AA]}, - {CFI_MFR_ANY, CFI_ID_ANY, cfi_fixup_0002_erase_regions, NULL}, - {CFI_MFR_ST, 0x227E, cfi_fixup_0002_write_buffer, NULL},/* M29W128G */ - {0, 0, NULL, NULL} -}; - -/* fixup after reading cmdset 0001 primary query table */ -static const struct cfi_fixup cfi_0001_fixups[] = { - {0, 0, NULL, NULL} -}; - -static void cfi_fixup(struct flash_bank *bank, const struct cfi_fixup *fixups) -{ - struct cfi_flash_bank *cfi_info = bank->driver_priv; - const struct cfi_fixup *f; - - for (f = fixups; f->fixup; f++) { - if (((f->mfr == CFI_MFR_ANY) || (f->mfr == cfi_info->manufacturer)) && - ((f->id == CFI_ID_ANY) || (f->id == cfi_info->device_id))) - f->fixup(bank, f->param); - } -} - -static inline uint32_t flash_address(struct flash_bank *bank, int sector, uint32_t offset) -{ - struct cfi_flash_bank *cfi_info = bank->driver_priv; - - if (cfi_info->x16_as_x8) - offset *= 2; - - /* while the sector list isn't built, only accesses to sector 0 work */ - if (sector == 0) - return bank->base + offset * bank->bus_width; - else { - if (!bank->sectors) { - LOG_ERROR("BUG: sector list not yet built"); - exit(-1); - } - return bank->base + bank->sectors[sector].offset + offset * bank->bus_width; - } -} - -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 - */ - for (i = 0; i < CFI_MAX_BUS_WIDTH; i++) - cmd_buf[i] = 0; - - 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 { - for (i = 1; i <= bank->bus_width; i++) - *cmd_buf++ = (i & (bank->chip_width - 1)) ? 0x0 : cmd; - } -} - -static int cfi_send_command(struct flash_bank *bank, uint8_t cmd, uint32_t address) -{ - uint8_t command[CFI_MAX_BUS_WIDTH]; - - cfi_command(bank, cmd, command); - return target_write_memory(bank->target, address, bank->bus_width, 1, command); -} - -/* read unsigned 8-bit value from the bank - * flash banks are expected to be made of similar chips - * the query result should be the same for all - */ -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; - retval = target_read_memory(target, flash_address(bank, sector, offset), - bank->bus_width, 1, data); - if (retval != ERROR_OK) - return retval; - - if (cfi_info->endianness == TARGET_LITTLE_ENDIAN) - *val = data[0]; - else - *val = data[bank->bus_width - 1]; - - return ERROR_OK; -} - -/* read unsigned 8-bit value from the bank - * in case of a bank made of multiple chips, - * the individual values are ORed - */ -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; - - int retval; - retval = target_read_memory(target, flash_address(bank, sector, offset), - bank->bus_width, 1, data); - if (retval != ERROR_OK) - return retval; - - if (cfi_info->endianness == TARGET_LITTLE_ENDIAN) { - for (i = 0; i < bank->bus_width / bank->chip_width; i++) - data[0] |= data[i]; - - *val = data[0]; - } else { - uint8_t value = 0; - for (i = 0; i < bank->bus_width / bank->chip_width; i++) - value |= data[bank->bus_width - 1 - i]; - - *val = value; - } - return ERROR_OK; -} - -static int cfi_query_u16(struct flash_bank *bank, int sector, uint32_t offset, uint16_t *val) -{ - struct target *target = bank->target; - struct cfi_flash_bank *cfi_info = bank->driver_priv; - uint8_t data[CFI_MAX_BUS_WIDTH * 2]; - int retval; - - if (cfi_info->x16_as_x8) { - uint8_t i; - for (i = 0; i < 2; i++) { - retval = target_read_memory(target, flash_address(bank, sector, offset + i), - bank->bus_width, 1, &data[i * bank->bus_width]); - if (retval != ERROR_OK) - return retval; - } - } else { - retval = target_read_memory(target, flash_address(bank, sector, offset), - bank->bus_width, 2, data); - if (retval != ERROR_OK) - return retval; - } - - 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; - - return ERROR_OK; -} - -static int cfi_query_u32(struct flash_bank *bank, int sector, uint32_t offset, uint32_t *val) -{ - struct target *target = bank->target; - struct cfi_flash_bank *cfi_info = bank->driver_priv; - uint8_t data[CFI_MAX_BUS_WIDTH * 4]; - int retval; - - if (cfi_info->x16_as_x8) { - uint8_t i; - for (i = 0; i < 4; i++) { - retval = target_read_memory(target, flash_address(bank, sector, offset + i), - bank->bus_width, 1, &data[i * bank->bus_width]); - if (retval != ERROR_OK) - return retval; - } - } else { - retval = target_read_memory(target, flash_address(bank, sector, offset), - bank->bus_width, 4, data); - if (retval != ERROR_OK) - return retval; - } - - 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 - *val = data[bank->bus_width - 1] | data[(2 * bank->bus_width) - 1] << 8 | - data[(3 * bank->bus_width) - 1] << 16 | - data[(4 * bank->bus_width) - 1] << 24; - - return ERROR_OK; -} - -static int cfi_reset(struct flash_bank *bank) -{ - struct cfi_flash_bank *cfi_info = bank->driver_priv; - int retval = ERROR_OK; - - retval = cfi_send_command(bank, 0xf0, flash_address(bank, 0, 0x0)); - if (retval != ERROR_OK) - return retval; - - retval = cfi_send_command(bank, 0xff, flash_address(bank, 0, 0x0)); - if (retval != ERROR_OK) - return retval; - - if (cfi_info->manufacturer == 0x20 && - (cfi_info->device_id == 0x227E || cfi_info->device_id == 0x7E)) { - /* Numonix M29W128G is cmd 0xFF intolerant - causes internal undefined state - * so we send an extra 0xF0 reset to fix the bug */ - retval = cfi_send_command(bank, 0xf0, flash_address(bank, 0, 0x00)); - if (retval != ERROR_OK) - return retval; - } - - return retval; -} - -static void cfi_intel_clear_status_register(struct flash_bank *bank) -{ - cfi_send_command(bank, 0x50, flash_address(bank, 0, 0x0)); -} - -static int cfi_intel_wait_status_busy(struct flash_bank *bank, int timeout, uint8_t *val) -{ - uint8_t status; - - int retval = ERROR_OK; - - for (;; ) { - if (timeout-- < 0) { - LOG_ERROR("timeout while waiting for WSM to become ready"); - return ERROR_FAIL; - } - - retval = cfi_get_u8(bank, 0, 0x0, &status); - if (retval != ERROR_OK) - return retval; - - if (status & 0x80) - break; - - alive_sleep(1); - } - - /* mask out bit 0 (reserved) */ - status = status & 0xfe; - - LOG_DEBUG("status: 0x%x", status); - - if (status != 0x80) { - LOG_ERROR("status register: 0x%x", status); - if (status & 0x2) - LOG_ERROR("Block Lock-Bit Detected, Operation Abort"); - if (status & 0x4) - LOG_ERROR("Program suspended"); - if (status & 0x8) - LOG_ERROR("Low Programming Voltage Detected, Operation Aborted"); - if (status & 0x10) - LOG_ERROR("Program Error / Error in Setting Lock-Bit"); - if (status & 0x20) - LOG_ERROR("Error in Block Erasure or Clear Lock-Bits"); - if (status & 0x40) - LOG_ERROR("Block Erase Suspended"); - - cfi_intel_clear_status_register(bank); - - retval = ERROR_FAIL; - } - - *val = status; - return retval; -} - -static int cfi_spansion_wait_status_busy(struct flash_bank *bank, int timeout) -{ - uint8_t status, oldstatus; - struct cfi_flash_bank *cfi_info = bank->driver_priv; - int retval; - - retval = cfi_get_u8(bank, 0, 0x0, &oldstatus); - if (retval != ERROR_OK) - return retval; - - do { - retval = cfi_get_u8(bank, 0, 0x0, &status); - - if (retval != ERROR_OK) - return retval; - - if ((status ^ oldstatus) & 0x40) { - if (status & cfi_info->status_poll_mask & 0x20) { - retval = cfi_get_u8(bank, 0, 0x0, &oldstatus); - if (retval != ERROR_OK) - return retval; - retval = cfi_get_u8(bank, 0, 0x0, &status); - if (retval != ERROR_OK) - return retval; - if ((status ^ oldstatus) & 0x40) { - LOG_ERROR("dq5 timeout, status: 0x%x", status); - return ERROR_FLASH_OPERATION_FAILED; - } else { - LOG_DEBUG("status: 0x%x", status); - return ERROR_OK; - } - } - } else {/* no toggle: finished, OK */ - LOG_DEBUG("status: 0x%x", status); - return ERROR_OK; - } - - oldstatus = status; - alive_sleep(1); - } while (timeout-- > 0); - - LOG_ERROR("timeout, status: 0x%x", status); - - return ERROR_FLASH_BUSY; -} - -static int cfi_read_intel_pri_ext(struct flash_bank *bank) -{ - int retval; - struct cfi_flash_bank *cfi_info = bank->driver_priv; - struct cfi_intel_pri_ext *pri_ext; - - if (cfi_info->pri_ext) - free(cfi_info->pri_ext); - - pri_ext = malloc(sizeof(struct cfi_intel_pri_ext)); - if (pri_ext == NULL) { - LOG_ERROR("Out of memory"); - return ERROR_FAIL; - } - cfi_info->pri_ext = pri_ext; - - retval = cfi_query_u8(bank, 0, cfi_info->pri_addr + 0, &pri_ext->pri[0]); - if (retval != ERROR_OK) - return retval; - retval = cfi_query_u8(bank, 0, cfi_info->pri_addr + 1, &pri_ext->pri[1]); - if (retval != ERROR_OK) - return retval; - retval = cfi_query_u8(bank, 0, cfi_info->pri_addr + 2, &pri_ext->pri[2]); - if (retval != ERROR_OK) - return retval; - - if ((pri_ext->pri[0] != 'P') || (pri_ext->pri[1] != 'R') || (pri_ext->pri[2] != 'I')) { - retval = cfi_reset(bank); - if (retval != ERROR_OK) - return retval; - LOG_ERROR("Could not read bank flash bank information"); - return ERROR_FLASH_BANK_INVALID; - } - - retval = cfi_query_u8(bank, 0, cfi_info->pri_addr + 3, &pri_ext->major_version); - if (retval != ERROR_OK) - return retval; - retval = cfi_query_u8(bank, 0, cfi_info->pri_addr + 4, &pri_ext->minor_version); - if (retval != ERROR_OK) - return retval; - - LOG_DEBUG("pri: '%c%c%c', version: %c.%c", pri_ext->pri[0], pri_ext->pri[1], - pri_ext->pri[2], pri_ext->major_version, pri_ext->minor_version); - - retval = cfi_query_u32(bank, 0, cfi_info->pri_addr + 5, &pri_ext->feature_support); - if (retval != ERROR_OK) - return retval; - retval = cfi_query_u8(bank, 0, cfi_info->pri_addr + 9, &pri_ext->suspend_cmd_support); - if (retval != ERROR_OK) - return retval; - retval = cfi_query_u16(bank, 0, cfi_info->pri_addr + 0xa, &pri_ext->blk_status_reg_mask); - if (retval != ERROR_OK) - return retval; - - LOG_DEBUG("feature_support: 0x%" PRIx32 ", suspend_cmd_support: " - "0x%x, blk_status_reg_mask: 0x%x", - pri_ext->feature_support, - pri_ext->suspend_cmd_support, - pri_ext->blk_status_reg_mask); - - retval = cfi_query_u8(bank, 0, cfi_info->pri_addr + 0xc, &pri_ext->vcc_optimal); - if (retval != ERROR_OK) - return retval; - retval = cfi_query_u8(bank, 0, cfi_info->pri_addr + 0xd, &pri_ext->vpp_optimal); - if (retval != ERROR_OK) - return retval; - - LOG_DEBUG("Vcc opt: %x.%x, Vpp opt: %u.%x", - (pri_ext->vcc_optimal & 0xf0) >> 4, pri_ext->vcc_optimal & 0x0f, - (pri_ext->vpp_optimal & 0xf0) >> 4, pri_ext->vpp_optimal & 0x0f); - - retval = cfi_query_u8(bank, 0, cfi_info->pri_addr + 0xe, &pri_ext->num_protection_fields); - if (retval != ERROR_OK) - return retval; - if (pri_ext->num_protection_fields != 1) { - LOG_WARNING("expected one protection register field, but found %i", - pri_ext->num_protection_fields); - } - - retval = cfi_query_u16(bank, 0, cfi_info->pri_addr + 0xf, &pri_ext->prot_reg_addr); - if (retval != ERROR_OK) - return retval; - retval = cfi_query_u8(bank, 0, cfi_info->pri_addr + 0x11, &pri_ext->fact_prot_reg_size); - if (retval != ERROR_OK) - return retval; - retval = cfi_query_u8(bank, 0, cfi_info->pri_addr + 0x12, &pri_ext->user_prot_reg_size); - if (retval != ERROR_OK) - return retval; - - LOG_DEBUG("protection_fields: %i, prot_reg_addr: 0x%x, " - "factory pre-programmed: %i, user programmable: %i", - pri_ext->num_protection_fields, pri_ext->prot_reg_addr, - 1 << pri_ext->fact_prot_reg_size, 1 << pri_ext->user_prot_reg_size); - - return ERROR_OK; -} - -static int cfi_read_spansion_pri_ext(struct flash_bank *bank) -{ - int retval; - struct cfi_flash_bank *cfi_info = bank->driver_priv; - struct cfi_spansion_pri_ext *pri_ext; - - if (cfi_info->pri_ext) - free(cfi_info->pri_ext); - - pri_ext = malloc(sizeof(struct cfi_spansion_pri_ext)); - if (pri_ext == NULL) { - LOG_ERROR("Out of memory"); - return ERROR_FAIL; - } - cfi_info->pri_ext = pri_ext; - - retval = cfi_query_u8(bank, 0, cfi_info->pri_addr + 0, &pri_ext->pri[0]); - if (retval != ERROR_OK) - return retval; - retval = cfi_query_u8(bank, 0, cfi_info->pri_addr + 1, &pri_ext->pri[1]); - if (retval != ERROR_OK) - return retval; - retval = cfi_query_u8(bank, 0, cfi_info->pri_addr + 2, &pri_ext->pri[2]); - if (retval != ERROR_OK) - return retval; - - /* default values for implementation specific workarounds */ - pri_ext->_unlock1 = cfi_unlock_addresses[CFI_UNLOCK_555_2AA].unlock1; - pri_ext->_unlock2 = cfi_unlock_addresses[CFI_UNLOCK_555_2AA].unlock2; - pri_ext->_reversed_geometry = 0; - - if ((pri_ext->pri[0] != 'P') || (pri_ext->pri[1] != 'R') || (pri_ext->pri[2] != 'I')) { - retval = cfi_send_command(bank, 0xf0, flash_address(bank, 0, 0x0)); - if (retval != ERROR_OK) - return retval; - LOG_ERROR("Could not read spansion bank information"); - return ERROR_FLASH_BANK_INVALID; - } - - retval = cfi_query_u8(bank, 0, cfi_info->pri_addr + 3, &pri_ext->major_version); - if (retval != ERROR_OK) - return retval; - retval = cfi_query_u8(bank, 0, cfi_info->pri_addr + 4, &pri_ext->minor_version); - if (retval != ERROR_OK) - return retval; - - LOG_DEBUG("pri: '%c%c%c', version: %c.%c", pri_ext->pri[0], pri_ext->pri[1], - pri_ext->pri[2], pri_ext->major_version, pri_ext->minor_version); - - retval = cfi_query_u8(bank, 0, cfi_info->pri_addr + 5, &pri_ext->SiliconRevision); - if (retval != ERROR_OK) - return retval; - retval = cfi_query_u8(bank, 0, cfi_info->pri_addr + 6, &pri_ext->EraseSuspend); - if (retval != ERROR_OK) - return retval; - retval = cfi_query_u8(bank, 0, cfi_info->pri_addr + 7, &pri_ext->BlkProt); - if (retval != ERROR_OK) - return retval; - retval = cfi_query_u8(bank, 0, cfi_info->pri_addr + 8, &pri_ext->TmpBlkUnprotect); - if (retval != ERROR_OK) - return retval; - retval = cfi_query_u8(bank, 0, cfi_info->pri_addr + 9, &pri_ext->BlkProtUnprot); - if (retval != ERROR_OK) - return retval; - retval = cfi_query_u8(bank, 0, cfi_info->pri_addr + 10, &pri_ext->SimultaneousOps); - if (retval != ERROR_OK) - return retval; - retval = cfi_query_u8(bank, 0, cfi_info->pri_addr + 11, &pri_ext->BurstMode); - if (retval != ERROR_OK) - return retval; - retval = cfi_query_u8(bank, 0, cfi_info->pri_addr + 12, &pri_ext->PageMode); - if (retval != ERROR_OK) - return retval; - retval = cfi_query_u8(bank, 0, cfi_info->pri_addr + 13, &pri_ext->VppMin); - if (retval != ERROR_OK) - return retval; - retval = cfi_query_u8(bank, 0, cfi_info->pri_addr + 14, &pri_ext->VppMax); - if (retval != ERROR_OK) - return retval; - retval = cfi_query_u8(bank, 0, cfi_info->pri_addr + 15, &pri_ext->TopBottom); - if (retval != ERROR_OK) - return retval; - - LOG_DEBUG("Silicon Revision: 0x%x, Erase Suspend: 0x%x, Block protect: 0x%x", - pri_ext->SiliconRevision, pri_ext->EraseSuspend, pri_ext->BlkProt); - - LOG_DEBUG("Temporary Unprotect: 0x%x, Block Protect Scheme: 0x%x, " - "Simultaneous Ops: 0x%x", pri_ext->TmpBlkUnprotect, - pri_ext->BlkProtUnprot, pri_ext->SimultaneousOps); - - LOG_DEBUG("Burst Mode: 0x%x, Page Mode: 0x%x, ", pri_ext->BurstMode, pri_ext->PageMode); - - - LOG_DEBUG("Vpp min: %u.%x, Vpp max: %u.%x", - (pri_ext->VppMin & 0xf0) >> 4, pri_ext->VppMin & 0x0f, - (pri_ext->VppMax & 0xf0) >> 4, pri_ext->VppMax & 0x0f); - - LOG_DEBUG("WP# protection 0x%x", pri_ext->TopBottom); - - return ERROR_OK; -} - -static int cfi_read_atmel_pri_ext(struct flash_bank *bank) -{ - int retval; - struct cfi_atmel_pri_ext atmel_pri_ext; - struct cfi_flash_bank *cfi_info = bank->driver_priv; - struct cfi_spansion_pri_ext *pri_ext; - - if (cfi_info->pri_ext) - free(cfi_info->pri_ext); - - pri_ext = malloc(sizeof(struct cfi_spansion_pri_ext)); - if (pri_ext == NULL) { - LOG_ERROR("Out of memory"); - return ERROR_FAIL; - } - - /* ATMEL devices use the same CFI primary command set (0x2) as AMD/Spansion, - * but a different primary extended query table. - * We read the atmel table, and prepare a valid AMD/Spansion query table. - */ - - memset(pri_ext, 0, sizeof(struct cfi_spansion_pri_ext)); - - cfi_info->pri_ext = pri_ext; - - retval = cfi_query_u8(bank, 0, cfi_info->pri_addr + 0, &atmel_pri_ext.pri[0]); - if (retval != ERROR_OK) - return retval; - retval = cfi_query_u8(bank, 0, cfi_info->pri_addr + 1, &atmel_pri_ext.pri[1]); - if (retval != ERROR_OK) - return retval; - retval = cfi_query_u8(bank, 0, cfi_info->pri_addr + 2, &atmel_pri_ext.pri[2]); - if (retval != ERROR_OK) - return retval; - - if ((atmel_pri_ext.pri[0] != 'P') || (atmel_pri_ext.pri[1] != 'R') - || (atmel_pri_ext.pri[2] != 'I')) { - retval = cfi_send_command(bank, 0xf0, flash_address(bank, 0, 0x0)); - if (retval != ERROR_OK) - return retval; - LOG_ERROR("Could not read atmel bank information"); - return ERROR_FLASH_BANK_INVALID; - } - - pri_ext->pri[0] = atmel_pri_ext.pri[0]; - pri_ext->pri[1] = atmel_pri_ext.pri[1]; - pri_ext->pri[2] = atmel_pri_ext.pri[2]; - - retval = cfi_query_u8(bank, 0, cfi_info->pri_addr + 3, &atmel_pri_ext.major_version); - if (retval != ERROR_OK) - return retval; - retval = cfi_query_u8(bank, 0, cfi_info->pri_addr + 4, &atmel_pri_ext.minor_version); - if (retval != ERROR_OK) - return retval; - - LOG_DEBUG("pri: '%c%c%c', version: %c.%c", atmel_pri_ext.pri[0], - atmel_pri_ext.pri[1], atmel_pri_ext.pri[2], - atmel_pri_ext.major_version, atmel_pri_ext.minor_version); - - pri_ext->major_version = atmel_pri_ext.major_version; - pri_ext->minor_version = atmel_pri_ext.minor_version; - - retval = cfi_query_u8(bank, 0, cfi_info->pri_addr + 5, &atmel_pri_ext.features); - if (retval != ERROR_OK) - return retval; - retval = cfi_query_u8(bank, 0, cfi_info->pri_addr + 6, &atmel_pri_ext.bottom_boot); - if (retval != ERROR_OK) - return retval; - retval = cfi_query_u8(bank, 0, cfi_info->pri_addr + 7, &atmel_pri_ext.burst_mode); - if (retval != ERROR_OK) - return retval; - retval = cfi_query_u8(bank, 0, cfi_info->pri_addr + 8, &atmel_pri_ext.page_mode); - if (retval != ERROR_OK) - return retval; - - LOG_DEBUG( - "features: 0x%2.2x, bottom_boot: 0x%2.2x, burst_mode: 0x%2.2x, page_mode: 0x%2.2x", - atmel_pri_ext.features, - atmel_pri_ext.bottom_boot, - atmel_pri_ext.burst_mode, - atmel_pri_ext.page_mode); - - if (atmel_pri_ext.features & 0x02) - pri_ext->EraseSuspend = 2; - - /* some chips got it backwards... */ - if (cfi_info->device_id == AT49BV6416 || - cfi_info->device_id == AT49BV6416T) { - if (atmel_pri_ext.bottom_boot) - pri_ext->TopBottom = 3; - else - pri_ext->TopBottom = 2; - } else { - if (atmel_pri_ext.bottom_boot) - pri_ext->TopBottom = 2; - else - pri_ext->TopBottom = 3; - } - - pri_ext->_unlock1 = cfi_unlock_addresses[CFI_UNLOCK_555_2AA].unlock1; - pri_ext->_unlock2 = cfi_unlock_addresses[CFI_UNLOCK_555_2AA].unlock2; - - return ERROR_OK; -} - -static int cfi_read_0002_pri_ext(struct flash_bank *bank) -{ - struct cfi_flash_bank *cfi_info = bank->driver_priv; - - if (cfi_info->manufacturer == CFI_MFR_ATMEL) - return cfi_read_atmel_pri_ext(bank); - else - return cfi_read_spansion_pri_ext(bank); -} - -static int cfi_spansion_info(struct flash_bank *bank, char *buf, int buf_size) -{ - int printed; - struct cfi_flash_bank *cfi_info = bank->driver_priv; - struct cfi_spansion_pri_ext *pri_ext = cfi_info->pri_ext; - - printed = snprintf(buf, buf_size, "\nSpansion primary algorithm extend information:\n"); - buf += printed; - buf_size -= printed; - - printed = snprintf(buf, buf_size, "pri: '%c%c%c', version: %c.%c\n", pri_ext->pri[0], - pri_ext->pri[1], pri_ext->pri[2], - pri_ext->major_version, pri_ext->minor_version); - buf += printed; - buf_size -= printed; - - printed = snprintf(buf, buf_size, "Silicon Rev.: 0x%x, Address Sensitive unlock: 0x%x\n", - (pri_ext->SiliconRevision) >> 2, - (pri_ext->SiliconRevision) & 0x03); - buf += printed; - buf_size -= printed; - - printed = snprintf(buf, buf_size, "Erase Suspend: 0x%x, Sector Protect: 0x%x\n", - pri_ext->EraseSuspend, - pri_ext->BlkProt); - buf += printed; - buf_size -= printed; - - snprintf(buf, buf_size, "VppMin: %u.%x, VppMax: %u.%x\n", - (pri_ext->VppMin & 0xf0) >> 4, pri_ext->VppMin & 0x0f, - (pri_ext->VppMax & 0xf0) >> 4, pri_ext->VppMax & 0x0f); - - return ERROR_OK; -} - -static int cfi_intel_info(struct flash_bank *bank, char *buf, int buf_size) -{ - int printed; - struct cfi_flash_bank *cfi_info = bank->driver_priv; - struct cfi_intel_pri_ext *pri_ext = cfi_info->pri_ext; - - printed = snprintf(buf, buf_size, "\nintel primary algorithm extend information:\n"); - buf += printed; - buf_size -= printed; - - printed = snprintf(buf, - buf_size, - "pri: '%c%c%c', version: %c.%c\n", - pri_ext->pri[0], - pri_ext->pri[1], - pri_ext->pri[2], - pri_ext->major_version, - pri_ext->minor_version); - buf += printed; - buf_size -= printed; - - printed = snprintf(buf, - buf_size, - "feature_support: 0x%" PRIx32 ", " - "suspend_cmd_support: 0x%x, blk_status_reg_mask: 0x%x\n", - pri_ext->feature_support, - pri_ext->suspend_cmd_support, - pri_ext->blk_status_reg_mask); - buf += printed; - buf_size -= printed; - - printed = snprintf(buf, buf_size, "Vcc opt: %x.%x, Vpp opt: %u.%x\n", - (pri_ext->vcc_optimal & 0xf0) >> 4, pri_ext->vcc_optimal & 0x0f, - (pri_ext->vpp_optimal & 0xf0) >> 4, pri_ext->vpp_optimal & 0x0f); - buf += printed; - buf_size -= printed; - - snprintf(buf, buf_size, "protection_fields: %i, prot_reg_addr: 0x%x, " - "factory pre-programmed: %i, user programmable: %i\n", - pri_ext->num_protection_fields, pri_ext->prot_reg_addr, - 1 << pri_ext->fact_prot_reg_size, 1 << pri_ext->user_prot_reg_size); - - return ERROR_OK; -} - -/* flash_bank cfi [options] - */ -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; - - /* both widths must: - * - not exceed max value; - * - not be null; - * - be equal to a power of 2. - * bus must be wide enough to hold one chip */ - if ((bank->chip_width > CFI_MAX_CHIP_WIDTH) - || (bank->bus_width > CFI_MAX_BUS_WIDTH) - || (bank->chip_width == 0) - || (bank->bus_width == 0) - || (bank->chip_width & (bank->chip_width - 1)) - || (bank->bus_width & (bank->bus_width - 1)) - || (bank->chip_width > bank->bus_width)) { - LOG_ERROR("chip and bus width have to specified in bytes"); - return ERROR_FLASH_BANK_INVALID; - } - - cfi_info = malloc(sizeof(struct cfi_flash_bank)); - cfi_info->probed = 0; - cfi_info->erase_region_info = NULL; - cfi_info->pri_ext = NULL; - bank->driver_priv = cfi_info; - - 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; - - return ERROR_OK; -} - -static int cfi_intel_erase(struct flash_bank *bank, int first, int last) -{ - int retval; - struct cfi_flash_bank *cfi_info = bank->driver_priv; - int i; - - cfi_intel_clear_status_register(bank); - - for (i = first; i <= last; i++) { - retval = cfi_send_command(bank, 0x20, flash_address(bank, i, 0x0)); - if (retval != ERROR_OK) - return retval; - - retval = cfi_send_command(bank, 0xd0, flash_address(bank, i, 0x0)); - if (retval != ERROR_OK) - return retval; - - uint8_t status; - retval = cfi_intel_wait_status_busy(bank, cfi_info->block_erase_timeout, &status); - if (retval != ERROR_OK) - return retval; - - if (status == 0x80) - bank->sectors[i].is_erased = 1; - else { - retval = cfi_send_command(bank, 0xff, flash_address(bank, 0, 0x0)); - if (retval != ERROR_OK) - return retval; - - LOG_ERROR("couldn't erase block %i of flash bank at base 0x%" - PRIx32, i, bank->base); - return ERROR_FLASH_OPERATION_FAILED; - } - } - - return cfi_send_command(bank, 0xff, flash_address(bank, 0, 0x0)); -} - -static int cfi_spansion_erase(struct flash_bank *bank, int first, int last) -{ - int retval; - struct cfi_flash_bank *cfi_info = bank->driver_priv; - struct cfi_spansion_pri_ext *pri_ext = cfi_info->pri_ext; - int i; - - for (i = first; i <= last; i++) { - retval = cfi_send_command(bank, 0xaa, flash_address(bank, 0, pri_ext->_unlock1)); - if (retval != ERROR_OK) - return retval; - - retval = cfi_send_command(bank, 0x55, flash_address(bank, 0, pri_ext->_unlock2)); - if (retval != ERROR_OK) - return retval; - - retval = cfi_send_command(bank, 0x80, flash_address(bank, 0, pri_ext->_unlock1)); - if (retval != ERROR_OK) - return retval; - - retval = cfi_send_command(bank, 0xaa, flash_address(bank, 0, pri_ext->_unlock1)); - if (retval != ERROR_OK) - return retval; - - retval = cfi_send_command(bank, 0x55, flash_address(bank, 0, pri_ext->_unlock2)); - if (retval != ERROR_OK) - return retval; - - retval = cfi_send_command(bank, 0x30, flash_address(bank, i, 0x0)); - if (retval != ERROR_OK) - return retval; - - if (cfi_spansion_wait_status_busy(bank, cfi_info->block_erase_timeout) == ERROR_OK) - bank->sectors[i].is_erased = 1; - else { - retval = cfi_send_command(bank, 0xf0, flash_address(bank, 0, 0x0)); - if (retval != ERROR_OK) - return retval; - - LOG_ERROR("couldn't erase block %i of flash bank at base 0x%" - PRIx32, i, bank->base); - return ERROR_FLASH_OPERATION_FAILED; - } - } - - return cfi_send_command(bank, 0xf0, flash_address(bank, 0, 0x0)); -} - -static int cfi_erase(struct flash_bank *bank, int first, int last) -{ - struct cfi_flash_bank *cfi_info = bank->driver_priv; - - if (bank->target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - if ((first < 0) || (last < first) || (last >= bank->num_sectors)) - return ERROR_FLASH_SECTOR_INVALID; - - if (cfi_info->qry[0] != 'Q') - return ERROR_FLASH_BANK_NOT_PROBED; - - switch (cfi_info->pri_id) { - case 1: - case 3: - return cfi_intel_erase(bank, first, last); - break; - case 2: - return cfi_spansion_erase(bank, first, last); - break; - default: - LOG_ERROR("cfi primary command set %i unsupported", cfi_info->pri_id); - break; - } - - return ERROR_OK; -} - -static int cfi_intel_protect(struct flash_bank *bank, int set, int first, int last) -{ - int retval; - struct cfi_flash_bank *cfi_info = bank->driver_priv; - struct cfi_intel_pri_ext *pri_ext = cfi_info->pri_ext; - int retry = 0; - int i; - - /* if the device supports neither legacy lock/unlock (bit 3) nor - * instant individual block locking (bit 5). - */ - if (!(pri_ext->feature_support & 0x28)) { - LOG_ERROR("lock/unlock not supported on flash"); - return ERROR_FLASH_OPERATION_FAILED; - } - - cfi_intel_clear_status_register(bank); - - for (i = first; i <= last; i++) { - retval = cfi_send_command(bank, 0x60, flash_address(bank, i, 0x0)); - if (retval != ERROR_OK) - return retval; - if (set) { - retval = cfi_send_command(bank, 0x01, flash_address(bank, i, 0x0)); - if (retval != ERROR_OK) - return retval; - bank->sectors[i].is_protected = 1; - } else { - retval = cfi_send_command(bank, 0xd0, flash_address(bank, i, 0x0)); - if (retval != ERROR_OK) - return retval; - bank->sectors[i].is_protected = 0; - } - - /* instant individual block locking doesn't require reading of the status register - **/ - if (!(pri_ext->feature_support & 0x20)) { - /* Clear lock bits operation may take up to 1.4s */ - uint8_t status; - retval = cfi_intel_wait_status_busy(bank, 1400, &status); - if (retval != ERROR_OK) - return retval; - } else { - uint8_t block_status; - /* read block lock bit, to verify status */ - retval = cfi_send_command(bank, 0x90, flash_address(bank, 0, 0x55)); - if (retval != ERROR_OK) - return retval; - retval = cfi_get_u8(bank, i, 0x2, &block_status); - if (retval != ERROR_OK) - return retval; - - if ((block_status & 0x1) != set) { - LOG_ERROR( - "couldn't change block lock status (set = %i, block_status = 0x%2.2x)", - set, block_status); - retval = cfi_send_command(bank, 0x70, flash_address(bank, 0, 0x55)); - if (retval != ERROR_OK) - return retval; - uint8_t status; - retval = cfi_intel_wait_status_busy(bank, 10, &status); - if (retval != ERROR_OK) - return retval; - - if (retry > 10) - return ERROR_FLASH_OPERATION_FAILED; - else { - i--; - retry++; - } - } - } - } - - /* if the device doesn't support individual block lock bits set/clear, - * all blocks have been unlocked in parallel, so we set those that should be protected - */ - if ((!set) && (!(pri_ext->feature_support & 0x20))) { - /* FIX!!! this code path is broken!!! - * - * The correct approach is: - * - * 1. read out current protection status - * - * 2. override read out protection status w/unprotected. - * - * 3. re-protect what should be protected. - * - */ - for (i = 0; i < bank->num_sectors; i++) { - if (bank->sectors[i].is_protected == 1) { - cfi_intel_clear_status_register(bank); - - retval = cfi_send_command(bank, 0x60, flash_address(bank, i, 0x0)); - if (retval != ERROR_OK) - return retval; - - retval = cfi_send_command(bank, 0x01, flash_address(bank, i, 0x0)); - if (retval != ERROR_OK) - return retval; - - uint8_t status; - retval = cfi_intel_wait_status_busy(bank, 100, &status); - if (retval != ERROR_OK) - return retval; - } - } - } - - return cfi_send_command(bank, 0xff, flash_address(bank, 0, 0x0)); -} - -static int cfi_protect(struct flash_bank *bank, int set, int first, int last) -{ - struct cfi_flash_bank *cfi_info = bank->driver_priv; - - if (bank->target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - if ((first < 0) || (last < first) || (last >= bank->num_sectors)) { - LOG_ERROR("Invalid sector range"); - return ERROR_FLASH_SECTOR_INVALID; - } - - if (cfi_info->qry[0] != 'Q') - return ERROR_FLASH_BANK_NOT_PROBED; - - switch (cfi_info->pri_id) { - case 1: - case 3: - return cfi_intel_protect(bank, set, first, last); - break; - default: - LOG_WARNING("protect: cfi primary command set %i unsupported", cfi_info->pri_id); - return ERROR_OK; - } -} - -static uint32_t cfi_command_val(struct flash_bank *bank, uint8_t cmd) -{ - struct target *target = bank->target; - - uint8_t buf[CFI_MAX_BUS_WIDTH]; - cfi_command(bank, cmd, buf); - switch (bank->bus_width) { - case 1: - return buf[0]; - break; - case 2: - return target_buffer_get_u16(target, buf); - break; - case 4: - return target_buffer_get_u32(target, buf); - break; - default: - LOG_ERROR("Unsupported bank buswidth %d, can't do block memory writes", - bank->bus_width); - return 0; - } -} - -static int cfi_intel_write_block(struct flash_bank *bank, const uint8_t *buffer, - uint32_t address, uint32_t count) -{ - struct target *target = bank->target; - struct reg_param reg_params[7]; - struct arm_algorithm arm_algo; - struct working_area *write_algorithm; - struct working_area *source = NULL; - uint32_t buffer_size = 32768; - uint32_t write_command_val, busy_pattern_val, error_pattern_val; - - /* algorithm register usage: - * r0: source address (in RAM) - * r1: target address (in Flash) - * r2: count - * r3: flash write command - * r4: status byte (returned to host) - * r5: busy test pattern - * r6: error test pattern - */ - - /* see contib/loaders/flash/armv4_5_cfi_intel_32.s for src */ - static const uint32_t word_32_code[] = { - 0xe4904004, /* loop: ldr r4, [r0], #4 */ - 0xe5813000, /* str r3, [r1] */ - 0xe5814000, /* str r4, [r1] */ - 0xe5914000, /* busy: ldr r4, [r1] */ - 0xe0047005, /* and r7, r4, r5 */ - 0xe1570005, /* cmp r7, r5 */ - 0x1afffffb, /* bne busy */ - 0xe1140006, /* tst r4, r6 */ - 0x1a000003, /* bne done */ - 0xe2522001, /* subs r2, r2, #1 */ - 0x0a000001, /* beq done */ - 0xe2811004, /* add r1, r1 #4 */ - 0xeafffff2, /* b loop */ - 0xeafffffe /* done: b -2 */ - }; - - /* see contib/loaders/flash/armv4_5_cfi_intel_16.s for src */ - static const uint32_t word_16_code[] = { - 0xe0d040b2, /* loop: ldrh r4, [r0], #2 */ - 0xe1c130b0, /* strh r3, [r1] */ - 0xe1c140b0, /* strh r4, [r1] */ - 0xe1d140b0, /* busy ldrh r4, [r1] */ - 0xe0047005, /* and r7, r4, r5 */ - 0xe1570005, /* cmp r7, r5 */ - 0x1afffffb, /* bne busy */ - 0xe1140006, /* tst r4, r6 */ - 0x1a000003, /* bne done */ - 0xe2522001, /* subs r2, r2, #1 */ - 0x0a000001, /* beq done */ - 0xe2811002, /* add r1, r1 #2 */ - 0xeafffff2, /* b loop */ - 0xeafffffe /* done: b -2 */ - }; - - /* see contib/loaders/flash/armv4_5_cfi_intel_8.s for src */ - static const uint32_t word_8_code[] = { - 0xe4d04001, /* loop: ldrb r4, [r0], #1 */ - 0xe5c13000, /* strb r3, [r1] */ - 0xe5c14000, /* strb r4, [r1] */ - 0xe5d14000, /* busy ldrb r4, [r1] */ - 0xe0047005, /* and r7, r4, r5 */ - 0xe1570005, /* cmp r7, r5 */ - 0x1afffffb, /* bne busy */ - 0xe1140006, /* tst r4, r6 */ - 0x1a000003, /* bne done */ - 0xe2522001, /* subs r2, r2, #1 */ - 0x0a000001, /* beq done */ - 0xe2811001, /* add r1, r1 #1 */ - 0xeafffff2, /* b loop */ - 0xeafffffe /* done: b -2 */ - }; - uint8_t target_code[4*CFI_MAX_INTEL_CODESIZE]; - const uint32_t *target_code_src; - uint32_t target_code_size; - int retval = ERROR_OK; - - /* check we have a supported arch */ - if (is_arm(target_to_arm(target))) { - /* All other ARM CPUs have 32 bit instructions */ - arm_algo.common_magic = ARM_COMMON_MAGIC; - arm_algo.core_mode = ARM_MODE_SVC; - arm_algo.core_state = ARM_STATE_ARM; - } else { - LOG_ERROR("Unknown architecture"); - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - } - - cfi_intel_clear_status_register(bank); - - /* If we are setting up the write_algorith, we need target_code_src - * if not we only need target_code_size. */ - - /* However, we don't want to create multiple code paths, so we - * do the unnecessary evaluation of target_code_src, which the - * compiler will probably nicely optimize away if not needed */ - - /* prepare algorithm code for target endian */ - switch (bank->bus_width) { - case 1: - target_code_src = word_8_code; - target_code_size = sizeof(word_8_code); - break; - case 2: - target_code_src = word_16_code; - target_code_size = sizeof(word_16_code); - break; - case 4: - target_code_src = word_32_code; - target_code_size = sizeof(word_32_code); - break; - default: - LOG_ERROR("Unsupported bank buswidth %d, can't do block memory writes", - bank->bus_width); - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - } - - /* flash write code */ - if (target_code_size > sizeof(target_code)) { - LOG_WARNING("Internal error - target code buffer to small. " - "Increase CFI_MAX_INTEL_CODESIZE and recompile."); - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - } - - target_buffer_set_u32_array(target, target_code, target_code_size / 4, target_code_src); - - /* Get memory for block write handler */ - retval = target_alloc_working_area(target, - target_code_size, - &write_algorithm); - if (retval != ERROR_OK) { - 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, - target_code_size, target_code); - if (retval != ERROR_OK) { - LOG_ERROR("Unable to write block write code to target"); - goto cleanup; - } - - /* Get a workspace buffer for the data to flash starting with 32k size. - * Half size until buffer would be smaller 256 Bytes then fail back */ - /* FIXME Why 256 bytes, why not 32 bytes (smallest flash write page */ - while (target_alloc_working_area_try(target, buffer_size, &source) != ERROR_OK) { - buffer_size /= 2; - if (buffer_size <= 256) { - LOG_WARNING( - "no large enough working area available, can't do block memory writes"); - retval = ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - goto cleanup; - } - } - - /* setup algo registers */ - init_reg_param(®_params[0], "r0", 32, PARAM_OUT); - init_reg_param(®_params[1], "r1", 32, PARAM_OUT); - 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_IN); - init_reg_param(®_params[5], "r5", 32, PARAM_OUT); - init_reg_param(®_params[6], "r6", 32, PARAM_OUT); - - /* prepare command and status register patterns */ - write_command_val = cfi_command_val(bank, 0x40); - 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, - source->address, buffer_size); - - /* Programming main loop */ - while (count > 0) { - uint32_t thisrun_count = (count > buffer_size) ? buffer_size : count; - uint32_t wsm_error; - - retval = target_write_buffer(target, source->address, thisrun_count, buffer); - if (retval != ERROR_OK) - goto cleanup; - - 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 / bank->bus_width); - - buf_set_u32(reg_params[3].value, 0, 32, write_command_val); - buf_set_u32(reg_params[5].value, 0, 32, busy_pattern_val); - buf_set_u32(reg_params[6].value, 0, 32, error_pattern_val); - - LOG_DEBUG("Write 0x%04" PRIx32 " bytes to flash at 0x%08" PRIx32, - thisrun_count, address); - - /* Execute algorithm, assume breakpoint for last instruction */ - retval = target_run_algorithm(target, 0, NULL, 7, reg_params, - write_algorithm->address, - write_algorithm->address + target_code_size - - sizeof(uint32_t), - 10000, /* 10s should be enough for max. 32k of data */ - &arm_algo); - - /* On failure try a fall back to direct word writes */ - if (retval != ERROR_OK) { - cfi_intel_clear_status_register(bank); - LOG_ERROR( - "Execution of flash algorythm failed. Can't fall back. Please report."); - retval = ERROR_FLASH_OPERATION_FAILED; - /* retval = ERROR_TARGET_RESOURCE_NOT_AVAILABLE; */ - /* FIXME To allow fall back or recovery, we must save the actual status - * somewhere, so that a higher level code can start recovery. */ - goto cleanup; - } - - /* Check return value from algo code */ - wsm_error = buf_get_u32(reg_params[4].value, 0, 32) & error_pattern_val; - if (wsm_error) { - /* read status register (outputs debug information) */ - uint8_t status; - cfi_intel_wait_status_busy(bank, 100, &status); - cfi_intel_clear_status_register(bank); - retval = ERROR_FLASH_OPERATION_FAILED; - goto cleanup; - } - - buffer += thisrun_count; - address += thisrun_count; - count -= thisrun_count; - - keep_alive(); - } - - /* free up resources */ -cleanup: - if (source) - target_free_working_area(target, source); - - target_free_working_area(target, write_algorithm); - - 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]); - destroy_reg_param(®_params[5]); - destroy_reg_param(®_params[6]); - - return retval; -} - -static int cfi_spansion_write_block_mips(struct flash_bank *bank, const uint8_t *buffer, - uint32_t address, uint32_t count) -{ - struct cfi_flash_bank *cfi_info = bank->driver_priv; - struct cfi_spansion_pri_ext *pri_ext = cfi_info->pri_ext; - struct target *target = bank->target; - struct reg_param reg_params[10]; - struct mips32_algorithm mips32_info; - struct working_area *write_algorithm; - struct working_area *source; - uint32_t buffer_size = 32768; - uint32_t status; - int retval = ERROR_OK; - - /* input parameters - - * 4 A0 = source address - * 5 A1 = destination address - * 6 A2 = number of writes - * 7 A3 = flash write command - * 8 T0 = constant to mask DQ7 bits (also used for Dq5 with shift) - * output parameters - - * 9 T1 = 0x80 ok 0x00 bad - * temp registers - - * 10 T2 = value read from flash to test status - * 11 T3 = holding register - * unlock registers - - * 12 T4 = unlock1_addr - * 13 T5 = unlock1_cmd - * 14 T6 = unlock2_addr - * 15 T7 = unlock2_cmd */ - - 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_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_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_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_NOP, /* nop */ - - MIPS32_LUI(9, 0), /* lui $t1, 0 */ - MIPS32_ORI(9, 9, 0x80), /* ori $t1, $t1, 0x80 ; out = 0x80 */ - - MIPS32_B(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_NOP, /* nop */ - /* done: */ - MIPS32_SDBBP, /* sdbbp ; break(); */ - }; - - mips32_info.common_magic = MIPS32_COMMON_MAGIC; - mips32_info.isa_mode = MIPS32_ISA_MIPS32; - - int target_code_size = 0; - const uint32_t *target_code_src = NULL; - - switch (bank->bus_width) { - case 2: - /* Check for DQ5 support */ - if (cfi_info->status_poll_mask & (1 << 5)) { - target_code_src = mips_word_16_code; - target_code_size = sizeof(mips_word_16_code); - } else { - LOG_ERROR("Need DQ5 support"); - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - /* target_code_src = mips_word_16_code_dq7only; */ - /* target_code_size = sizeof(mips_word_16_code_dq7only); */ - } - break; - default: - LOG_ERROR("Unsupported bank buswidth %d, can't do block memory writes", - bank->bus_width); - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - } - - /* flash write code */ - uint8_t *target_code; - - /* convert bus-width dependent algorithm code to correct endianness */ - target_code = malloc(target_code_size); - if (target_code == NULL) { - LOG_ERROR("Out of memory"); - return ERROR_FAIL; - } - - target_buffer_set_u32_array(target, target_code, target_code_size / 4, target_code_src); - - /* allocate working area */ - retval = target_alloc_working_area(target, target_code_size, - &write_algorithm); - if (retval != ERROR_OK) { - free(target_code); - return retval; - } - - /* write algorithm code to working area */ - retval = target_write_buffer(target, write_algorithm->address, - target_code_size, target_code); - if (retval != ERROR_OK) { - free(target_code); - return retval; - } - - free(target_code); - - /* the following code still assumes target code is fixed 24*4 bytes */ - - while (target_alloc_working_area_try(target, buffer_size, &source) != ERROR_OK) { - buffer_size /= 2; - if (buffer_size <= 256) { - /* we already allocated the writing code, but failed to get a - * buffer, free the algorithm */ - target_free_working_area(target, write_algorithm); - - LOG_WARNING( - "not enough working area available, can't do block memory writes"); - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - } - } - - 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; - - retval = target_write_buffer(target, source->address, thisrun_count, buffer); - if (retval != ERROR_OK) - break; - - 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 / bank->bus_width); - buf_set_u32(reg_params[3].value, 0, 32, cfi_command_val(bank, 0xA0)); - buf_set_u32(reg_params[4].value, 0, 32, cfi_command_val(bank, 0x80)); - buf_set_u32(reg_params[6].value, 0, 32, flash_address(bank, 0, pri_ext->_unlock1)); - buf_set_u32(reg_params[7].value, 0, 32, 0xaaaaaaaa); - buf_set_u32(reg_params[8].value, 0, 32, flash_address(bank, 0, pri_ext->_unlock2)); - buf_set_u32(reg_params[9].value, 0, 32, 0x55555555); - - retval = target_run_algorithm(target, 0, NULL, 10, reg_params, - write_algorithm->address, - write_algorithm->address + ((target_code_size) - 4), - 10000, &mips32_info); - if (retval != ERROR_OK) - break; - - status = buf_get_u32(reg_params[5].value, 0, 32); - if (status != 0x80) { - LOG_ERROR("flash write block failed status: 0x%" PRIx32, status); - retval = ERROR_FLASH_OPERATION_FAILED; - break; - } - - buffer += thisrun_count; - address += thisrun_count; - count -= thisrun_count; - } - - target_free_all_working_areas(target); - - 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]); - destroy_reg_param(®_params[5]); - destroy_reg_param(®_params[6]); - destroy_reg_param(®_params[7]); - destroy_reg_param(®_params[8]); - destroy_reg_param(®_params[9]); - - return retval; -} - -static int cfi_spansion_write_block(struct flash_bank *bank, const uint8_t *buffer, - uint32_t address, uint32_t count) -{ - struct cfi_flash_bank *cfi_info = bank->driver_priv; - struct cfi_spansion_pri_ext *pri_ext = cfi_info->pri_ext; - struct target *target = bank->target; - struct reg_param reg_params[10]; - void *arm_algo; - struct arm_algorithm armv4_5_algo; - struct armv7m_algorithm armv7m_algo; - struct working_area *write_algorithm; - struct working_area *source; - uint32_t buffer_size = 32768; - uint32_t status; - int retval = ERROR_OK; - - /* input parameters - - * R0 = source address - * R1 = destination address - * R2 = number of writes - * R3 = flash write command - * R4 = constant to mask DQ7 bits (also used for Dq5 with shift) - * output parameters - - * R5 = 0x80 ok 0x00 bad - * temp registers - - * R6 = value read from flash to test status - * R7 = holding register - * unlock registers - - * R8 = unlock1_addr - * R9 = unlock1_cmd - * R10 = unlock2_addr - * R11 = unlock2_cmd */ - - /* see contib/loaders/flash/armv4_5_cfi_span_32.s for src */ - static const uint32_t armv4_5_word_32_code[] = { - /* 00008100 : */ - 0xe4905004, /* ldr r5, [r0], #4 */ - 0xe5889000, /* str r9, [r8] */ - 0xe58ab000, /* str r11, [r10] */ - 0xe5883000, /* str r3, [r8] */ - 0xe5815000, /* str r5, [r1] */ - 0xe1a00000, /* nop */ - /* 00008110 : */ - 0xe5916000, /* ldr r6, [r1] */ - 0xe0257006, /* eor r7, r5, r6 */ - 0xe0147007, /* ands r7, r4, r7 */ - 0x0a000007, /* beq 8140 ; b if DQ7 == Data7 */ - 0xe0166124, /* ands r6, r6, r4, lsr #2 */ - 0x0afffff9, /* beq 8110 ; b if DQ5 low */ - 0xe5916000, /* ldr r6, [r1] */ - 0xe0257006, /* eor r7, r5, r6 */ - 0xe0147007, /* ands r7, r4, r7 */ - 0x0a000001, /* beq 8140 ; b if DQ7 == Data7 */ - 0xe3a05000, /* mov r5, #0 ; 0x0 - return 0x00, error */ - 0x1a000004, /* bne 8154 */ - /* 00008140 : */ - 0xe2522001, /* subs r2, r2, #1 ; 0x1 */ - 0x03a05080, /* moveq r5, #128 ; 0x80 */ - 0x0a000001, /* beq 8154 */ - 0xe2811004, /* add r1, r1, #4 ; 0x4 */ - 0xeaffffe8, /* b 8100 */ - /* 00008154 : */ - 0xeafffffe /* b 8154 */ - }; - - /* see contib/loaders/flash/armv4_5_cfi_span_16.s for src */ - static const uint32_t armv4_5_word_16_code[] = { - /* 00008158 : */ - 0xe0d050b2, /* ldrh r5, [r0], #2 */ - 0xe1c890b0, /* strh r9, [r8] */ - 0xe1cab0b0, /* strh r11, [r10] */ - 0xe1c830b0, /* strh r3, [r8] */ - 0xe1c150b0, /* strh r5, [r1] */ - 0xe1a00000, /* nop (mov r0,r0) */ - /* 00008168 : */ - 0xe1d160b0, /* ldrh r6, [r1] */ - 0xe0257006, /* eor r7, r5, r6 */ - 0xe0147007, /* ands r7, r4, r7 */ - 0x0a000007, /* beq 8198 */ - 0xe0166124, /* ands r6, r6, r4, lsr #2 */ - 0x0afffff9, /* beq 8168 */ - 0xe1d160b0, /* ldrh r6, [r1] */ - 0xe0257006, /* eor r7, r5, r6 */ - 0xe0147007, /* ands r7, r4, r7 */ - 0x0a000001, /* beq 8198 */ - 0xe3a05000, /* mov r5, #0 ; 0x0 */ - 0x1a000004, /* bne 81ac */ - /* 00008198 : */ - 0xe2522001, /* subs r2, r2, #1 ; 0x1 */ - 0x03a05080, /* moveq r5, #128 ; 0x80 */ - 0x0a000001, /* beq 81ac */ - 0xe2811002, /* add r1, r1, #2 ; 0x2 */ - 0xeaffffe8, /* b 8158 */ - /* 000081ac : */ - 0xeafffffe /* b 81ac */ - }; - - /* see contrib/loaders/flash/armv7m_cfi_span_16.s for src */ - static const uint32_t armv7m_word_16_code[] = { - 0x5B02F830, - 0x9000F8A8, - 0xB000F8AA, - 0x3000F8A8, - 0xBF00800D, - 0xEA85880E, - 0x40270706, - 0xEA16D00A, - 0xD0F70694, - 0xEA85880E, - 0x40270706, - 0xF04FD002, - 0xD1070500, - 0xD0023A01, - 0x0102F101, - 0xF04FE7E0, - 0xE7FF0580, - 0x0000BE00 - }; - - /* see contrib/loaders/flash/armv7m_cfi_span_16_dq7.s for src */ - static const uint32_t armv7m_word_16_code_dq7only[] = { - /* 00000000 : */ - 0x5B02F830, /* ldrh.w r5, [r0], #2 */ - 0x9000F8A8, /* strh.w r9, [r8] */ - 0xB000F8AA, /* strh.w fp, [sl] */ - 0x3000F8A8, /* strh.w r3, [r8] */ - 0xBF00800D, /* strh r5, [r1, #0] */ - /* nop */ - - /* 00000014 : */ - 0xEA85880E, /* ldrh r6, [r1, #0] */ - /* eor.w r7, r5, r6 */ - 0x40270706, /* ands r7, r4 */ - 0x3A01D1FA, /* bne.n 14 */ - /* subs r2, #1 */ - 0xF101D002, /* beq.n 28 */ - 0xE7EB0102, /* add.w r1, r1, #2 */ - /* b.n 0 */ - - /* 00000028 : */ - 0x0580F04F, /* mov.w r5, #128 */ - 0xBF00E7FF, /* b.n 30 */ - /* nop (for alignment purposes) */ - - /* 00000030 : */ - 0x0000BE00 /* bkpt 0x0000 */ - }; - - /* see contrib/loaders/flash/armv4_5_cfi_span_16_dq7.s for src */ - static const uint32_t armv4_5_word_16_code_dq7only[] = { - /* : */ - 0xe0d050b2, /* ldrh r5, [r0], #2 */ - 0xe1c890b0, /* strh r9, [r8] */ - 0xe1cab0b0, /* strh r11, [r10] */ - 0xe1c830b0, /* strh r3, [r8] */ - 0xe1c150b0, /* strh r5, [r1] */ - 0xe1a00000, /* nop (mov r0,r0) */ - /* : */ - 0xe1d160b0, /* ldrh r6, [r1] */ - 0xe0257006, /* eor r7, r5, r6 */ - 0xe2177080, /* ands r7, #0x80 */ - 0x1afffffb, /* bne 8168 */ - /* */ - 0xe2522001, /* subs r2, r2, #1 ; 0x1 */ - 0x03a05080, /* moveq r5, #128 ; 0x80 */ - 0x0a000001, /* beq 81ac */ - 0xe2811002, /* add r1, r1, #2 ; 0x2 */ - 0xeafffff0, /* b 8158 */ - /* 000081ac : */ - 0xeafffffe /* b 81ac */ - }; - - /* see contrib/loaders/flash/armv4_5_cfi_span_8.s for src */ - static const uint32_t armv4_5_word_8_code[] = { - /* 000081b0 : */ - 0xe4d05001, /* ldrb r5, [r0], #1 */ - 0xe5c89000, /* strb r9, [r8] */ - 0xe5cab000, /* strb r11, [r10] */ - 0xe5c83000, /* strb r3, [r8] */ - 0xe5c15000, /* strb r5, [r1] */ - 0xe1a00000, /* nop (mov r0,r0) */ - /* 000081c0 : */ - 0xe5d16000, /* ldrb r6, [r1] */ - 0xe0257006, /* eor r7, r5, r6 */ - 0xe0147007, /* ands r7, r4, r7 */ - 0x0a000007, /* beq 81f0 */ - 0xe0166124, /* ands r6, r6, r4, lsr #2 */ - 0x0afffff9, /* beq 81c0 */ - 0xe5d16000, /* ldrb r6, [r1] */ - 0xe0257006, /* eor r7, r5, r6 */ - 0xe0147007, /* ands r7, r4, r7 */ - 0x0a000001, /* beq 81f0 */ - 0xe3a05000, /* mov r5, #0 ; 0x0 */ - 0x1a000004, /* bne 8204 */ - /* 000081f0 : */ - 0xe2522001, /* subs r2, r2, #1 ; 0x1 */ - 0x03a05080, /* moveq r5, #128 ; 0x80 */ - 0x0a000001, /* beq 8204 */ - 0xe2811001, /* add r1, r1, #1 ; 0x1 */ - 0xeaffffe8, /* b 81b0 */ - /* 00008204 : */ - 0xeafffffe /* b 8204 */ - }; - - if (strncmp(target_type_name(target), "mips_m4k", 8) == 0) - return cfi_spansion_write_block_mips(bank, buffer, address, count); - - if (is_armv7m(target_to_armv7m(target))) { /* armv7m target */ - armv7m_algo.common_magic = ARMV7M_COMMON_MAGIC; - armv7m_algo.core_mode = ARM_MODE_THREAD; - arm_algo = &armv7m_algo; - } else if (is_arm(target_to_arm(target))) { - /* All other ARM CPUs have 32 bit instructions */ - armv4_5_algo.common_magic = ARM_COMMON_MAGIC; - armv4_5_algo.core_mode = ARM_MODE_SVC; - armv4_5_algo.core_state = ARM_STATE_ARM; - arm_algo = &armv4_5_algo; - } else { - LOG_ERROR("Unknown architecture"); - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - } - - int target_code_size = 0; - const uint32_t *target_code_src = NULL; - - switch (bank->bus_width) { - case 1: - if (is_armv7m(target_to_armv7m(target))) { - LOG_ERROR("Unknown ARM architecture"); - return ERROR_FAIL; - } - target_code_src = armv4_5_word_8_code; - target_code_size = sizeof(armv4_5_word_8_code); - break; - case 2: - /* Check for DQ5 support */ - if (cfi_info->status_poll_mask & (1 << 5)) { - if (is_armv7m(target_to_armv7m(target))) { - /* armv7m target */ - target_code_src = armv7m_word_16_code; - target_code_size = sizeof(armv7m_word_16_code); - } else { /* armv4_5 target */ - target_code_src = armv4_5_word_16_code; - target_code_size = sizeof(armv4_5_word_16_code); - } - } else { - /* No DQ5 support. Use DQ7 DATA# polling only. */ - if (is_armv7m(target_to_armv7m(target))) { - /* armv7m target */ - target_code_src = armv7m_word_16_code_dq7only; - target_code_size = sizeof(armv7m_word_16_code_dq7only); - } else { /* armv4_5 target */ - target_code_src = armv4_5_word_16_code_dq7only; - target_code_size = sizeof(armv4_5_word_16_code_dq7only); - } - } - break; - case 4: - if (is_armv7m(target_to_armv7m(target))) { - LOG_ERROR("Unknown ARM architecture"); - return ERROR_FAIL; - } - target_code_src = armv4_5_word_32_code; - target_code_size = sizeof(armv4_5_word_32_code); - break; - default: - LOG_ERROR("Unsupported bank buswidth %d, can't do block memory writes", - bank->bus_width); - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - } - - /* flash write code */ - uint8_t *target_code; - - /* convert bus-width dependent algorithm code to correct endianness */ - target_code = malloc(target_code_size); - if (target_code == NULL) { - LOG_ERROR("Out of memory"); - return ERROR_FAIL; - } - - target_buffer_set_u32_array(target, target_code, target_code_size / 4, target_code_src); - - /* allocate working area */ - retval = target_alloc_working_area(target, target_code_size, - &write_algorithm); - if (retval != ERROR_OK) { - free(target_code); - return retval; - } - - /* write algorithm code to working area */ - retval = target_write_buffer(target, write_algorithm->address, - target_code_size, target_code); - if (retval != ERROR_OK) { - free(target_code); - return retval; - } - - free(target_code); - - /* the following code still assumes target code is fixed 24*4 bytes */ - - while (target_alloc_working_area_try(target, buffer_size, &source) != ERROR_OK) { - buffer_size /= 2; - if (buffer_size <= 256) { - /* we already allocated the writing code, but failed to get a - * buffer, free the algorithm */ - target_free_working_area(target, write_algorithm); - - LOG_WARNING( - "not enough working area available, can't do block memory writes"); - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - } - } - - init_reg_param(®_params[0], "r0", 32, PARAM_OUT); - init_reg_param(®_params[1], "r1", 32, PARAM_OUT); - 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); - init_reg_param(®_params[5], "r5", 32, PARAM_IN); - init_reg_param(®_params[6], "r8", 32, PARAM_OUT); - init_reg_param(®_params[7], "r9", 32, PARAM_OUT); - init_reg_param(®_params[8], "r10", 32, PARAM_OUT); - init_reg_param(®_params[9], "r11", 32, PARAM_OUT); - - while (count > 0) { - uint32_t thisrun_count = (count > buffer_size) ? buffer_size : count; - - retval = target_write_buffer(target, source->address, thisrun_count, buffer); - if (retval != ERROR_OK) - break; - - 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 / bank->bus_width); - buf_set_u32(reg_params[3].value, 0, 32, cfi_command_val(bank, 0xA0)); - buf_set_u32(reg_params[4].value, 0, 32, cfi_command_val(bank, 0x80)); - buf_set_u32(reg_params[6].value, 0, 32, flash_address(bank, 0, pri_ext->_unlock1)); - buf_set_u32(reg_params[7].value, 0, 32, 0xaaaaaaaa); - buf_set_u32(reg_params[8].value, 0, 32, flash_address(bank, 0, pri_ext->_unlock2)); - buf_set_u32(reg_params[9].value, 0, 32, 0x55555555); - - retval = target_run_algorithm(target, 0, NULL, 10, reg_params, - write_algorithm->address, - write_algorithm->address + ((target_code_size) - 4), - 10000, arm_algo); - if (retval != ERROR_OK) - break; - - status = buf_get_u32(reg_params[5].value, 0, 32); - if (status != 0x80) { - LOG_ERROR("flash write block failed status: 0x%" PRIx32, status); - retval = ERROR_FLASH_OPERATION_FAILED; - break; - } - - buffer += thisrun_count; - address += thisrun_count; - count -= thisrun_count; - } - - target_free_all_working_areas(target); - - 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]); - destroy_reg_param(®_params[5]); - destroy_reg_param(®_params[6]); - destroy_reg_param(®_params[7]); - destroy_reg_param(®_params[8]); - destroy_reg_param(®_params[9]); - - return retval; -} - -static int cfi_intel_write_word(struct flash_bank *bank, uint8_t *word, uint32_t address) -{ - int retval; - struct cfi_flash_bank *cfi_info = bank->driver_priv; - struct target *target = bank->target; - - cfi_intel_clear_status_register(bank); - retval = cfi_send_command(bank, 0x40, address); - if (retval != ERROR_OK) - return retval; - - retval = target_write_memory(target, address, bank->bus_width, 1, word); - if (retval != ERROR_OK) - return retval; - - uint8_t status; - retval = cfi_intel_wait_status_busy(bank, cfi_info->word_write_timeout, &status); - 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; - - LOG_ERROR("couldn't write word at base 0x%" PRIx32 ", address 0x%" PRIx32, - bank->base, address); - return ERROR_FLASH_OPERATION_FAILED; - } - - return ERROR_OK; -} - -static int cfi_intel_write_words(struct flash_bank *bank, const uint8_t *word, - uint32_t wordcount, uint32_t address) -{ - int retval; - struct cfi_flash_bank *cfi_info = bank->driver_priv; - struct target *target = bank->target; - - /* Calculate buffer size and boundary mask - * buffersize is (buffer size per chip) * (number of chips) - * bufferwsize is buffersize in words */ - uint32_t buffersize = - (1UL << cfi_info->max_buf_write_size) * (bank->bus_width / bank->chip_width); - uint32_t buffermask = buffersize-1; - uint32_t bufferwsize = buffersize / bank->bus_width; - - /* Check for valid range */ - if (address & buffermask) { - LOG_ERROR("Write address at base 0x%" PRIx32 ", address 0x%" PRIx32 - " not aligned to 2^%d boundary", - bank->base, address, cfi_info->max_buf_write_size); - return ERROR_FLASH_OPERATION_FAILED; - } - - /* Check for valid size */ - if (wordcount > bufferwsize) { - LOG_ERROR("Number of data words %" PRId32 " exceeds available buffersize %" PRId32, - wordcount, buffersize); - return ERROR_FLASH_OPERATION_FAILED; - } - - /* Write to flash buffer */ - cfi_intel_clear_status_register(bank); - - /* Initiate buffer operation _*/ - retval = cfi_send_command(bank, 0xe8, address); - if (retval != ERROR_OK) - return retval; - uint8_t status; - retval = cfi_intel_wait_status_busy(bank, cfi_info->buf_write_timeout, &status); - 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; - - LOG_ERROR( - "couldn't start buffer write operation at base 0x%" PRIx32 ", address 0x%" PRIx32, - bank->base, - address); - return ERROR_FLASH_OPERATION_FAILED; - } - - /* Write buffer wordcount-1 and data words */ - retval = cfi_send_command(bank, bufferwsize-1, address); - if (retval != ERROR_OK) - return retval; - - retval = target_write_memory(target, address, bank->bus_width, bufferwsize, word); - if (retval != ERROR_OK) - return retval; - - /* Commit write operation */ - retval = cfi_send_command(bank, 0xd0, address); - if (retval != ERROR_OK) - return retval; - - retval = cfi_intel_wait_status_busy(bank, cfi_info->buf_write_timeout, &status); - 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; - - LOG_ERROR("Buffer write at base 0x%" PRIx32 - ", address 0x%" PRIx32 " failed.", bank->base, address); - return ERROR_FLASH_OPERATION_FAILED; - } - - return ERROR_OK; -} - -static int cfi_spansion_write_word(struct flash_bank *bank, uint8_t *word, uint32_t address) -{ - int retval; - struct cfi_flash_bank *cfi_info = bank->driver_priv; - struct cfi_spansion_pri_ext *pri_ext = cfi_info->pri_ext; - struct target *target = bank->target; - - retval = cfi_send_command(bank, 0xaa, flash_address(bank, 0, pri_ext->_unlock1)); - if (retval != ERROR_OK) - return retval; - - retval = cfi_send_command(bank, 0x55, flash_address(bank, 0, pri_ext->_unlock2)); - if (retval != ERROR_OK) - return retval; - - retval = cfi_send_command(bank, 0xa0, flash_address(bank, 0, pri_ext->_unlock1)); - if (retval != ERROR_OK) - return retval; - - retval = target_write_memory(target, address, bank->bus_width, 1, word); - if (retval != ERROR_OK) - return retval; - - if (cfi_spansion_wait_status_busy(bank, cfi_info->word_write_timeout) != ERROR_OK) { - retval = cfi_send_command(bank, 0xf0, flash_address(bank, 0, 0x0)); - if (retval != ERROR_OK) - return retval; - - LOG_ERROR("couldn't write word at base 0x%" PRIx32 - ", address 0x%" PRIx32, bank->base, address); - return ERROR_FLASH_OPERATION_FAILED; - } - - return ERROR_OK; -} - -static int cfi_spansion_write_words(struct flash_bank *bank, const uint8_t *word, - uint32_t wordcount, uint32_t address) -{ - int retval; - struct cfi_flash_bank *cfi_info = bank->driver_priv; - struct target *target = bank->target; - struct cfi_spansion_pri_ext *pri_ext = cfi_info->pri_ext; - - /* Calculate buffer size and boundary mask - * buffersize is (buffer size per chip) * (number of chips) - * bufferwsize is buffersize in words */ - uint32_t buffersize = - (1UL << cfi_info->max_buf_write_size) * (bank->bus_width / bank->chip_width); - uint32_t buffermask = buffersize-1; - uint32_t bufferwsize = buffersize / bank->bus_width; - - /* Check for valid range */ - if (address & buffermask) { - LOG_ERROR("Write address at base 0x%" PRIx32 - ", address 0x%" PRIx32 " not aligned to 2^%d boundary", - bank->base, address, cfi_info->max_buf_write_size); - return ERROR_FLASH_OPERATION_FAILED; - } - - /* Check for valid size */ - if (wordcount > bufferwsize) { - LOG_ERROR("Number of data words %" PRId32 " exceeds available buffersize %" - PRId32, wordcount, buffersize); - return ERROR_FLASH_OPERATION_FAILED; - } - - /* Unlock */ - retval = cfi_send_command(bank, 0xaa, flash_address(bank, 0, pri_ext->_unlock1)); - if (retval != ERROR_OK) - return retval; - - retval = cfi_send_command(bank, 0x55, flash_address(bank, 0, pri_ext->_unlock2)); - if (retval != ERROR_OK) - return retval; - - /* Buffer load command */ - retval = cfi_send_command(bank, 0x25, address); - if (retval != ERROR_OK) - return retval; - - /* Write buffer wordcount-1 and data words */ - retval = cfi_send_command(bank, bufferwsize-1, address); - if (retval != ERROR_OK) - return retval; - - retval = target_write_memory(target, address, bank->bus_width, bufferwsize, word); - if (retval != ERROR_OK) - return retval; - - /* Commit write operation */ - retval = cfi_send_command(bank, 0x29, address); - if (retval != ERROR_OK) - return retval; - - if (cfi_spansion_wait_status_busy(bank, cfi_info->buf_write_timeout) != ERROR_OK) { - retval = cfi_send_command(bank, 0xf0, flash_address(bank, 0, 0x0)); - if (retval != ERROR_OK) - return retval; - - LOG_ERROR("couldn't write block at base 0x%" PRIx32 - ", address 0x%" PRIx32 ", size 0x%" PRIx32, bank->base, address, - bufferwsize); - return ERROR_FLASH_OPERATION_FAILED; - } - - return ERROR_OK; -} - -static int cfi_write_word(struct flash_bank *bank, uint8_t *word, uint32_t address) -{ - struct cfi_flash_bank *cfi_info = bank->driver_priv; - - switch (cfi_info->pri_id) { - case 1: - case 3: - return cfi_intel_write_word(bank, word, address); - break; - case 2: - return cfi_spansion_write_word(bank, word, address); - break; - default: - LOG_ERROR("cfi primary command set %i unsupported", cfi_info->pri_id); - break; - } - - return ERROR_FLASH_OPERATION_FAILED; -} - -static int cfi_write_words(struct flash_bank *bank, const uint8_t *word, - uint32_t wordcount, uint32_t address) -{ - struct cfi_flash_bank *cfi_info = bank->driver_priv; - - if (cfi_info->buf_write_timeout_typ == 0) { - /* buffer writes are not supported */ - LOG_DEBUG("Buffer Writes Not Supported"); - return ERROR_FLASH_OPER_UNSUPPORTED; - } - - switch (cfi_info->pri_id) { - case 1: - case 3: - return cfi_intel_write_words(bank, word, wordcount, address); - break; - case 2: - return cfi_spansion_write_words(bank, word, wordcount, address); - break; - default: - LOG_ERROR("cfi primary command set %i unsupported", cfi_info->pri_id); - break; - } - - return ERROR_FLASH_OPERATION_FAILED; -} - -static int cfi_read(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, uint32_t count) -{ - struct cfi_flash_bank *cfi_info = bank->driver_priv; - struct target *target = bank->target; - uint32_t address = bank->base + offset; - uint32_t read_p; - int align; /* number of unaligned bytes */ - uint8_t current_word[CFI_MAX_BUS_WIDTH]; - int i; - int retval; - - LOG_DEBUG("reading buffer of %i byte at 0x%8.8x", - (int)count, (unsigned)offset); - - if (bank->target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - if (offset + count > bank->size) - return ERROR_FLASH_DST_OUT_OF_BANK; - - if (cfi_info->qry[0] != 'Q') - return ERROR_FLASH_BANK_NOT_PROBED; - - /* start at the first byte of the first word (bus_width size) */ - read_p = address & ~(bank->bus_width - 1); - align = address - read_p; - if (align != 0) { - LOG_INFO("Fixup %d unaligned read head bytes", align); - - /* read a complete word from flash */ - retval = target_read_memory(target, read_p, bank->bus_width, 1, current_word); - if (retval != ERROR_OK) - return retval; - - /* take only bytes we need */ - for (i = align; (i < bank->bus_width) && (count > 0); i++, count--) - *buffer++ = current_word[i]; - - read_p += bank->bus_width; - } - - align = count / bank->bus_width; - if (align) { - retval = target_read_memory(target, read_p, bank->bus_width, align, buffer); - if (retval != ERROR_OK) - return retval; - - read_p += align * bank->bus_width; - buffer += align * bank->bus_width; - count -= align * bank->bus_width; - } - - if (count) { - LOG_INFO("Fixup %" PRIu32 " unaligned read tail bytes", count); - - /* read a complete word from flash */ - retval = target_read_memory(target, read_p, bank->bus_width, 1, current_word); - if (retval != ERROR_OK) - return retval; - - /* take only bytes we need */ - for (i = 0; (i < bank->bus_width) && (count > 0); i++, count--) - *buffer++ = current_word[i]; - } - - return ERROR_OK; -} - -static int cfi_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count) -{ - struct cfi_flash_bank *cfi_info = bank->driver_priv; - struct target *target = bank->target; - uint32_t address = bank->base + offset; /* address of first byte to be programmed */ - uint32_t write_p; - int align; /* number of unaligned bytes */ - 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; - - if (bank->target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - if (offset + count > bank->size) - return ERROR_FLASH_DST_OUT_OF_BANK; - - if (cfi_info->qry[0] != 'Q') - return ERROR_FLASH_BANK_NOT_PROBED; - - /* start at the first byte of the first word (bus_width size) */ - write_p = address & ~(bank->bus_width - 1); - align = address - write_p; - if (align != 0) { - LOG_INFO("Fixup %d unaligned head bytes", align); - - /* read a complete word from flash */ - retval = target_read_memory(target, write_p, bank->bus_width, 1, current_word); - if (retval != ERROR_OK) - return retval; - - /* replace only bytes that must be written */ - 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) - return retval; - 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) { - /* try block writes (fails without working area) */ - case 1: - case 3: - retval = cfi_intel_write_block(bank, buffer, write_p, blk_count); - break; - case 2: - retval = cfi_spansion_write_block(bank, buffer, write_p, blk_count); - break; - default: - LOG_ERROR("cfi primary command set %i unsupported", cfi_info->pri_id); - retval = ERROR_FLASH_OPERATION_FAILED; - break; - } - if (retval == ERROR_OK) { - /* Increment pointers and decrease count on succesful block write */ - buffer += blk_count; - write_p += blk_count; - count -= blk_count; - } else { - if (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE) { - /* Calculate buffer size and boundary mask - * buffersize is (buffer size per chip) * (number of chips) - * bufferwsize is buffersize in words */ - uint32_t buffersize = - (1UL << - cfi_info->max_buf_write_size) * - (bank->bus_width / bank->chip_width); - uint32_t buffermask = buffersize-1; - uint32_t bufferwsize = buffersize / bank->bus_width; - - /* fall back to memory writes */ - while (count >= (uint32_t)bank->bus_width) { - int fallback; - if ((write_p & 0xff) == 0) { - LOG_INFO("Programming at 0x%08" PRIx32 ", count 0x%08" - PRIx32 " bytes remaining", write_p, count); - } - fallback = 1; - if ((bufferwsize > 0) && (count >= buffersize) && - !(write_p & buffermask)) { - retval = cfi_write_words(bank, buffer, bufferwsize, write_p); - if (retval == ERROR_OK) { - buffer += buffersize; - write_p += buffersize; - count -= buffersize; - fallback = 0; - } else if (retval != ERROR_FLASH_OPER_UNSUPPORTED) - return retval; - } - /* try the slow way? */ - if (fallback) { - for (i = 0; i < bank->bus_width; i++) - current_word[i] = *buffer++; - - retval = cfi_write_word(bank, current_word, write_p); - if (retval != ERROR_OK) - return retval; - - write_p += bank->bus_width; - count -= bank->bus_width; - } - } - } else - 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) - return retval; - - /* handle unaligned tail bytes */ - if (count > 0) { - LOG_INFO("Fixup %" PRId32 " unaligned tail bytes", count); - - /* read a complete word from flash */ - retval = target_read_memory(target, write_p, bank->bus_width, 1, current_word); - if (retval != ERROR_OK) - return retval; - - /* replace only bytes that must be written */ - for (i = 0; (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) - return retval; - } - - /* return to read array mode */ - return cfi_reset(bank); -} - -static void cfi_fixup_reversed_erase_regions(struct flash_bank *bank, const void *param) -{ - (void) param; - struct cfi_flash_bank *cfi_info = bank->driver_priv; - struct cfi_spansion_pri_ext *pri_ext = cfi_info->pri_ext; - - pri_ext->_reversed_geometry = 1; -} - -static void cfi_fixup_0002_erase_regions(struct flash_bank *bank, const void *param) -{ - int i; - struct cfi_flash_bank *cfi_info = bank->driver_priv; - struct cfi_spansion_pri_ext *pri_ext = cfi_info->pri_ext; - (void) param; - - if ((pri_ext->_reversed_geometry) || (pri_ext->TopBottom == 3)) { - LOG_DEBUG("swapping reversed erase region information on cmdset 0002 device"); - - for (i = 0; i < cfi_info->num_erase_regions / 2; i++) { - int j = (cfi_info->num_erase_regions - 1) - i; - uint32_t swap; - - swap = cfi_info->erase_region_info[i]; - cfi_info->erase_region_info[i] = cfi_info->erase_region_info[j]; - cfi_info->erase_region_info[j] = swap; - } - } -} - -static void cfi_fixup_0002_unlock_addresses(struct flash_bank *bank, const void *param) -{ - struct cfi_flash_bank *cfi_info = bank->driver_priv; - struct cfi_spansion_pri_ext *pri_ext = cfi_info->pri_ext; - const struct cfi_unlock_addresses *unlock_addresses = param; - - pri_ext->_unlock1 = unlock_addresses->unlock1; - pri_ext->_unlock2 = unlock_addresses->unlock2; -} - -static void cfi_fixup_0002_polling_bits(struct flash_bank *bank, const void *param) -{ - struct cfi_flash_bank *cfi_info = bank->driver_priv; - const int *status_poll_mask = param; - - cfi_info->status_poll_mask = *status_poll_mask; -} - - -static int cfi_query_string(struct flash_bank *bank, int address) -{ - struct cfi_flash_bank *cfi_info = bank->driver_priv; - int retval; - - retval = cfi_send_command(bank, 0x98, flash_address(bank, 0, address)); - if (retval != ERROR_OK) - return retval; - - retval = cfi_query_u8(bank, 0, 0x10, &cfi_info->qry[0]); - if (retval != ERROR_OK) - return retval; - retval = cfi_query_u8(bank, 0, 0x11, &cfi_info->qry[1]); - if (retval != ERROR_OK) - return retval; - retval = cfi_query_u8(bank, 0, 0x12, &cfi_info->qry[2]); - if (retval != ERROR_OK) - return retval; - - LOG_DEBUG("CFI qry returned: 0x%2.2x 0x%2.2x 0x%2.2x", - cfi_info->qry[0], cfi_info->qry[1], cfi_info->qry[2]); - - if ((cfi_info->qry[0] != 'Q') || (cfi_info->qry[1] != 'R') || (cfi_info->qry[2] != 'Y')) { - retval = cfi_reset(bank); - if (retval != ERROR_OK) - return retval; - LOG_ERROR("Could not probe bank: no QRY"); - return ERROR_FLASH_BANK_INVALID; - } - - return ERROR_OK; -} - -static int cfi_probe(struct flash_bank *bank) -{ - struct cfi_flash_bank *cfi_info = bank->driver_priv; - struct target *target = bank->target; - int num_sectors = 0; - int i; - int sector = 0; - uint32_t unlock1 = 0x555; - uint32_t unlock2 = 0x2aa; - int retval; - uint8_t value_buf0[CFI_MAX_BUS_WIDTH], value_buf1[CFI_MAX_BUS_WIDTH]; - - if (bank->target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - cfi_info->probed = 0; - cfi_info->num_erase_regions = 0; - if (bank->sectors) { - free(bank->sectors); - bank->sectors = NULL; - } - if (cfi_info->erase_region_info) { - free(cfi_info->erase_region_info); - cfi_info->erase_region_info = NULL; - } - - /* JEDEC standard JESD21C uses 0x5555 and 0x2aaa as unlock addresses, - * while CFI compatible AMD/Spansion flashes use 0x555 and 0x2aa - */ - if (cfi_info->jedec_probe) { - unlock1 = 0x5555; - unlock2 = 0x2aaa; - } - - /* switch to read identifier codes mode ("AUTOSELECT") */ - retval = cfi_send_command(bank, 0xaa, flash_address(bank, 0, unlock1)); - if (retval != ERROR_OK) - return retval; - retval = cfi_send_command(bank, 0x55, flash_address(bank, 0, unlock2)); - if (retval != ERROR_OK) - return retval; - retval = cfi_send_command(bank, 0x90, flash_address(bank, 0, unlock1)); - if (retval != ERROR_OK) - return retval; - - retval = target_read_memory(target, flash_address(bank, 0, 0x00), - bank->bus_width, 1, value_buf0); - if (retval != ERROR_OK) - return retval; - retval = target_read_memory(target, flash_address(bank, 0, 0x01), - bank->bus_width, 1, value_buf1); - if (retval != ERROR_OK) - return retval; - switch (bank->chip_width) { - case 1: - cfi_info->manufacturer = *value_buf0; - cfi_info->device_id = *value_buf1; - break; - case 2: - cfi_info->manufacturer = target_buffer_get_u16(target, value_buf0); - cfi_info->device_id = target_buffer_get_u16(target, value_buf1); - break; - case 4: - cfi_info->manufacturer = target_buffer_get_u32(target, value_buf0); - cfi_info->device_id = target_buffer_get_u32(target, value_buf1); - break; - default: - LOG_ERROR("Unsupported bank chipwidth %d, can't probe memory", - bank->chip_width); - return ERROR_FLASH_OPERATION_FAILED; - } - - LOG_INFO("Flash Manufacturer/Device: 0x%04x 0x%04x", - cfi_info->manufacturer, cfi_info->device_id); - /* switch back to read array mode */ - retval = cfi_reset(bank); - if (retval != ERROR_OK) - return retval; - - /* check device/manufacturer ID for known non-CFI flashes. */ - cfi_fixup_non_cfi(bank); - - /* query only if this is a CFI compatible flash, - * otherwise the relevant info has already been filled in - */ - if (cfi_info->not_cfi == 0) { - /* enter CFI query mode - * according to JEDEC Standard No. 68.01, - * a single bus sequence with address = 0x55, data = 0x98 should put - * the device into CFI query mode. - * - * SST flashes clearly violate this, and we will consider them incompatible for now - */ - - retval = cfi_query_string(bank, 0x55); - if (retval != ERROR_OK) { - /* - * Spansion S29WS-N CFI query fix is to try 0x555 if 0x55 fails. Should - * be harmless enough: - * - * http://www.infradead.org/pipermail/linux-mtd/2005-September/013618.html - */ - LOG_USER("Try workaround w/0x555 instead of 0x55 to get QRY."); - retval = cfi_query_string(bank, 0x555); - } - if (retval != ERROR_OK) - return retval; - - retval = cfi_query_u16(bank, 0, 0x13, &cfi_info->pri_id); - if (retval != ERROR_OK) - return retval; - retval = cfi_query_u16(bank, 0, 0x15, &cfi_info->pri_addr); - if (retval != ERROR_OK) - return retval; - retval = cfi_query_u16(bank, 0, 0x17, &cfi_info->alt_id); - if (retval != ERROR_OK) - return retval; - retval = cfi_query_u16(bank, 0, 0x19, &cfi_info->alt_addr); - if (retval != ERROR_OK) - return retval; - - LOG_DEBUG("qry: '%c%c%c', pri_id: 0x%4.4x, pri_addr: 0x%4.4x, alt_id: " - "0x%4.4x, alt_addr: 0x%4.4x", cfi_info->qry[0], cfi_info->qry[1], - cfi_info->qry[2], cfi_info->pri_id, cfi_info->pri_addr, - cfi_info->alt_id, cfi_info->alt_addr); - - retval = cfi_query_u8(bank, 0, 0x1b, &cfi_info->vcc_min); - if (retval != ERROR_OK) - return retval; - retval = cfi_query_u8(bank, 0, 0x1c, &cfi_info->vcc_max); - if (retval != ERROR_OK) - return retval; - retval = cfi_query_u8(bank, 0, 0x1d, &cfi_info->vpp_min); - if (retval != ERROR_OK) - return retval; - retval = cfi_query_u8(bank, 0, 0x1e, &cfi_info->vpp_max); - if (retval != ERROR_OK) - return retval; - - retval = cfi_query_u8(bank, 0, 0x1f, &cfi_info->word_write_timeout_typ); - if (retval != ERROR_OK) - return retval; - retval = cfi_query_u8(bank, 0, 0x20, &cfi_info->buf_write_timeout_typ); - if (retval != ERROR_OK) - return retval; - retval = cfi_query_u8(bank, 0, 0x21, &cfi_info->block_erase_timeout_typ); - if (retval != ERROR_OK) - return retval; - retval = cfi_query_u8(bank, 0, 0x22, &cfi_info->chip_erase_timeout_typ); - if (retval != ERROR_OK) - return retval; - retval = cfi_query_u8(bank, 0, 0x23, &cfi_info->word_write_timeout_max); - if (retval != ERROR_OK) - return retval; - retval = cfi_query_u8(bank, 0, 0x24, &cfi_info->buf_write_timeout_max); - if (retval != ERROR_OK) - return retval; - retval = cfi_query_u8(bank, 0, 0x25, &cfi_info->block_erase_timeout_max); - if (retval != ERROR_OK) - return retval; - retval = cfi_query_u8(bank, 0, 0x26, &cfi_info->chip_erase_timeout_max); - if (retval != ERROR_OK) - return retval; - - uint8_t data; - retval = cfi_query_u8(bank, 0, 0x27, &data); - if (retval != ERROR_OK) - return retval; - cfi_info->dev_size = 1 << data; - - retval = cfi_query_u16(bank, 0, 0x28, &cfi_info->interface_desc); - if (retval != ERROR_OK) - return retval; - retval = cfi_query_u16(bank, 0, 0x2a, &cfi_info->max_buf_write_size); - if (retval != ERROR_OK) - return retval; - retval = cfi_query_u8(bank, 0, 0x2c, &cfi_info->num_erase_regions); - if (retval != ERROR_OK) - return retval; - - LOG_DEBUG("size: 0x%" PRIx32 ", interface desc: %i, max buffer write size: 0x%x", - cfi_info->dev_size, cfi_info->interface_desc, - (1 << cfi_info->max_buf_write_size)); - - if (cfi_info->num_erase_regions) { - cfi_info->erase_region_info = malloc(sizeof(*cfi_info->erase_region_info) - * cfi_info->num_erase_regions); - for (i = 0; i < cfi_info->num_erase_regions; i++) { - retval = cfi_query_u32(bank, - 0, - 0x2d + (4 * i), - &cfi_info->erase_region_info[i]); - if (retval != ERROR_OK) - return retval; - LOG_DEBUG( - "erase region[%i]: %" PRIu32 " blocks of size 0x%" PRIx32 "", - i, - (cfi_info->erase_region_info[i] & 0xffff) + 1, - (cfi_info->erase_region_info[i] >> 16) * 256); - } - } else - cfi_info->erase_region_info = NULL; - - /* We need to read the primary algorithm extended query table before calculating - * the sector layout to be able to apply fixups - */ - switch (cfi_info->pri_id) { - /* Intel command set (standard and extended) */ - case 0x0001: - case 0x0003: - cfi_read_intel_pri_ext(bank); - break; - /* AMD/Spansion, Atmel, ... command set */ - case 0x0002: - cfi_info->status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7; /* - *default - *for - *all - *CFI - *flashs - **/ - cfi_read_0002_pri_ext(bank); - break; - default: - LOG_ERROR("cfi primary command set %i unsupported", cfi_info->pri_id); - break; - } - - /* return to read array mode - * we use both reset commands, as some Intel flashes fail to recognize the 0xF0 command - */ - retval = cfi_reset(bank); - if (retval != ERROR_OK) - return retval; - } /* end CFI case */ - - LOG_DEBUG("Vcc min: %x.%x, Vcc max: %x.%x, Vpp min: %u.%x, Vpp max: %u.%x", - (cfi_info->vcc_min & 0xf0) >> 4, cfi_info->vcc_min & 0x0f, - (cfi_info->vcc_max & 0xf0) >> 4, cfi_info->vcc_max & 0x0f, - (cfi_info->vpp_min & 0xf0) >> 4, cfi_info->vpp_min & 0x0f, - (cfi_info->vpp_max & 0xf0) >> 4, cfi_info->vpp_max & 0x0f); - - LOG_DEBUG("typ. word write timeout: %u us, typ. buf write timeout: %u us, " - "typ. block erase timeout: %u ms, typ. chip erase timeout: %u ms", - 1 << cfi_info->word_write_timeout_typ, 1 << cfi_info->buf_write_timeout_typ, - 1 << cfi_info->block_erase_timeout_typ, 1 << cfi_info->chip_erase_timeout_typ); - - LOG_DEBUG("max. word write timeout: %u us, max. buf write timeout: %u us, " - "max. block erase timeout: %u ms, max. chip erase timeout: %u ms", - (1 << cfi_info->word_write_timeout_max) * (1 << cfi_info->word_write_timeout_typ), - (1 << cfi_info->buf_write_timeout_max) * (1 << cfi_info->buf_write_timeout_typ), - (1 << cfi_info->block_erase_timeout_max) * (1 << cfi_info->block_erase_timeout_typ), - (1 << cfi_info->chip_erase_timeout_max) * (1 << cfi_info->chip_erase_timeout_typ)); - - /* convert timeouts to real values in ms */ - cfi_info->word_write_timeout = DIV_ROUND_UP((1L << cfi_info->word_write_timeout_typ) * - (1L << cfi_info->word_write_timeout_max), 1000); - cfi_info->buf_write_timeout = DIV_ROUND_UP((1L << cfi_info->buf_write_timeout_typ) * - (1L << cfi_info->buf_write_timeout_max), 1000); - cfi_info->block_erase_timeout = (1L << cfi_info->block_erase_timeout_typ) * - (1L << cfi_info->block_erase_timeout_max); - cfi_info->chip_erase_timeout = (1L << cfi_info->chip_erase_timeout_typ) * - (1L << cfi_info->chip_erase_timeout_max); - - LOG_DEBUG("calculated word write timeout: %u ms, buf write timeout: %u ms, " - "block erase timeout: %u ms, chip erase timeout: %u ms", - cfi_info->word_write_timeout, cfi_info->buf_write_timeout, - cfi_info->block_erase_timeout, cfi_info->chip_erase_timeout); - - /* apply fixups depending on the primary command set */ - switch (cfi_info->pri_id) { - /* Intel command set (standard and extended) */ - case 0x0001: - case 0x0003: - cfi_fixup(bank, cfi_0001_fixups); - break; - /* AMD/Spansion, Atmel, ... command set */ - case 0x0002: - cfi_fixup(bank, cfi_0002_fixups); - break; - default: - LOG_ERROR("cfi primary command set %i unsupported", cfi_info->pri_id); - break; - } - - if ((cfi_info->dev_size * bank->bus_width / bank->chip_width) != bank->size) { - LOG_WARNING("configuration specifies 0x%" PRIx32 " size, but a 0x%" PRIx32 - " size flash was found", bank->size, cfi_info->dev_size); - } - - if (cfi_info->num_erase_regions == 0) { - /* a device might have only one erase block, spanning the whole device */ - bank->num_sectors = 1; - bank->sectors = malloc(sizeof(struct flash_sector)); - - bank->sectors[sector].offset = 0x0; - bank->sectors[sector].size = bank->size; - bank->sectors[sector].is_erased = -1; - bank->sectors[sector].is_protected = -1; - } else { - uint32_t offset = 0; - - for (i = 0; i < cfi_info->num_erase_regions; i++) - num_sectors += (cfi_info->erase_region_info[i] & 0xffff) + 1; - - bank->num_sectors = num_sectors; - bank->sectors = malloc(sizeof(struct flash_sector) * num_sectors); - - for (i = 0; i < cfi_info->num_erase_regions; i++) { - uint32_t j; - for (j = 0; j < (cfi_info->erase_region_info[i] & 0xffff) + 1; j++) { - bank->sectors[sector].offset = offset; - bank->sectors[sector].size = - ((cfi_info->erase_region_info[i] >> 16) * 256) - * bank->bus_width / bank->chip_width; - offset += bank->sectors[sector].size; - bank->sectors[sector].is_erased = -1; - bank->sectors[sector].is_protected = -1; - sector++; - } - } - if (offset != (cfi_info->dev_size * bank->bus_width / bank->chip_width)) { - LOG_WARNING( - "CFI size is 0x%" PRIx32 ", but total sector size is 0x%" PRIx32 "", \ - (cfi_info->dev_size * bank->bus_width / bank->chip_width), - offset); - } - } - - cfi_info->probed = 1; - - return ERROR_OK; -} - -static int cfi_auto_probe(struct flash_bank *bank) -{ - struct cfi_flash_bank *cfi_info = bank->driver_priv; - if (cfi_info->probed) - return ERROR_OK; - return cfi_probe(bank); -} - -static int cfi_intel_protect_check(struct flash_bank *bank) -{ - int retval; - struct cfi_flash_bank *cfi_info = bank->driver_priv; - struct cfi_intel_pri_ext *pri_ext = cfi_info->pri_ext; - int i; - - /* check if block lock bits are supported on this device */ - if (!(pri_ext->blk_status_reg_mask & 0x1)) - return ERROR_FLASH_OPERATION_FAILED; - - retval = cfi_send_command(bank, 0x90, flash_address(bank, 0, 0x55)); - if (retval != ERROR_OK) - return retval; - - for (i = 0; i < bank->num_sectors; i++) { - uint8_t block_status; - retval = cfi_get_u8(bank, i, 0x2, &block_status); - if (retval != ERROR_OK) - return retval; - - if (block_status & 1) - bank->sectors[i].is_protected = 1; - else - bank->sectors[i].is_protected = 0; - } - - return cfi_send_command(bank, 0xff, flash_address(bank, 0, 0x0)); -} - -static int cfi_spansion_protect_check(struct flash_bank *bank) -{ - int retval; - struct cfi_flash_bank *cfi_info = bank->driver_priv; - struct cfi_spansion_pri_ext *pri_ext = cfi_info->pri_ext; - int i; - - retval = cfi_send_command(bank, 0xaa, flash_address(bank, 0, pri_ext->_unlock1)); - if (retval != ERROR_OK) - return retval; - - retval = cfi_send_command(bank, 0x55, flash_address(bank, 0, pri_ext->_unlock2)); - if (retval != ERROR_OK) - return retval; - - retval = cfi_send_command(bank, 0x90, flash_address(bank, 0, pri_ext->_unlock1)); - if (retval != ERROR_OK) - return retval; - - for (i = 0; i < bank->num_sectors; i++) { - uint8_t block_status; - retval = cfi_get_u8(bank, i, 0x2, &block_status); - if (retval != ERROR_OK) - return retval; - - if (block_status & 1) - bank->sectors[i].is_protected = 1; - else - bank->sectors[i].is_protected = 0; - } - - return cfi_send_command(bank, 0xf0, flash_address(bank, 0, 0x0)); -} - -static int cfi_protect_check(struct flash_bank *bank) -{ - struct cfi_flash_bank *cfi_info = bank->driver_priv; - - if (bank->target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - if (cfi_info->qry[0] != 'Q') - return ERROR_FLASH_BANK_NOT_PROBED; - - switch (cfi_info->pri_id) { - case 1: - case 3: - return cfi_intel_protect_check(bank); - break; - case 2: - return cfi_spansion_protect_check(bank); - break; - default: - LOG_ERROR("cfi primary command set %i unsupported", cfi_info->pri_id); - break; - } - - return ERROR_OK; -} - -static int get_cfi_info(struct flash_bank *bank, char *buf, int buf_size) -{ - int printed; - struct cfi_flash_bank *cfi_info = bank->driver_priv; - - if (cfi_info->qry[0] == 0xff) { - snprintf(buf, buf_size, "\ncfi flash bank not probed yet\n"); - return ERROR_OK; - } - - if (cfi_info->not_cfi == 0) - printed = snprintf(buf, buf_size, "\nCFI flash: "); - else - printed = snprintf(buf, buf_size, "\nnon-CFI flash: "); - buf += printed; - buf_size -= printed; - - printed = snprintf(buf, buf_size, "mfr: 0x%4.4x, id:0x%4.4x\n\n", - cfi_info->manufacturer, cfi_info->device_id); - buf += printed; - buf_size -= printed; - - printed = snprintf(buf, buf_size, "qry: '%c%c%c', pri_id: 0x%4.4x, pri_addr: " - "0x%4.4x, alt_id: 0x%4.4x, alt_addr: 0x%4.4x\n", - cfi_info->qry[0], cfi_info->qry[1], cfi_info->qry[2], - cfi_info->pri_id, cfi_info->pri_addr, cfi_info->alt_id, cfi_info->alt_addr); - buf += printed; - buf_size -= printed; - - printed = snprintf(buf, buf_size, "Vcc min: %x.%x, Vcc max: %x.%x, " - "Vpp min: %u.%x, Vpp max: %u.%x\n", - (cfi_info->vcc_min & 0xf0) >> 4, cfi_info->vcc_min & 0x0f, - (cfi_info->vcc_max & 0xf0) >> 4, cfi_info->vcc_max & 0x0f, - (cfi_info->vpp_min & 0xf0) >> 4, cfi_info->vpp_min & 0x0f, - (cfi_info->vpp_max & 0xf0) >> 4, cfi_info->vpp_max & 0x0f); - buf += printed; - buf_size -= printed; - - printed = snprintf(buf, buf_size, "typ. word write timeout: %u us, " - "typ. buf write timeout: %u us, " - "typ. block erase timeout: %u ms, " - "typ. chip erase timeout: %u ms\n", - 1 << cfi_info->word_write_timeout_typ, - 1 << cfi_info->buf_write_timeout_typ, - 1 << cfi_info->block_erase_timeout_typ, - 1 << cfi_info->chip_erase_timeout_typ); - buf += printed; - buf_size -= printed; - - printed = snprintf(buf, - buf_size, - "max. word write timeout: %u us, " - "max. buf write timeout: %u us, max. " - "block erase timeout: %u ms, max. chip erase timeout: %u ms\n", - (1 << - cfi_info->word_write_timeout_max) * (1 << cfi_info->word_write_timeout_typ), - (1 << - cfi_info->buf_write_timeout_max) * (1 << cfi_info->buf_write_timeout_typ), - (1 << - cfi_info->block_erase_timeout_max) * - (1 << cfi_info->block_erase_timeout_typ), - (1 << - cfi_info->chip_erase_timeout_max) * - (1 << cfi_info->chip_erase_timeout_typ)); - buf += printed; - buf_size -= printed; - - printed = snprintf(buf, buf_size, "size: 0x%" PRIx32 ", interface desc: %i, " - "max buffer write size: 0x%x\n", - cfi_info->dev_size, - cfi_info->interface_desc, - 1 << cfi_info->max_buf_write_size); - buf += printed; - buf_size -= printed; - - switch (cfi_info->pri_id) { - case 1: - case 3: - cfi_intel_info(bank, buf, buf_size); - break; - case 2: - cfi_spansion_info(bank, buf, buf_size); - break; - default: - LOG_ERROR("cfi primary command set %i unsupported", cfi_info->pri_id); - break; - } - - return ERROR_OK; -} - -static void cfi_fixup_0002_write_buffer(struct flash_bank *bank, const void *param) -{ - struct cfi_flash_bank *cfi_info = bank->driver_priv; - - /* disable write buffer for M29W128G */ - cfi_info->buf_write_timeout_typ = 0; -} - -struct flash_driver cfi_flash = { - .name = "cfi", - .flash_bank_command = cfi_flash_bank_command, - .erase = cfi_erase, - .protect = cfi_protect, - .write = cfi_write, - .read = cfi_read, - .probe = cfi_probe, - .auto_probe = cfi_auto_probe, - /* FIXME: access flash at bus_width size */ - .erase_check = default_flash_blank_check, - .protect_check = cfi_protect_check, - .info = get_cfi_info, -}; diff --git a/src/flash/nor/cfi.h b/src/flash/nor/cfi.h deleted file mode 100644 index ed858a9de..000000000 --- a/src/flash/nor/cfi.h +++ /dev/null @@ -1,163 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#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 */ - -struct cfi_flash_bank { - int x16_as_x8; - int jedec_probe; - int not_cfi; - int probed; - - enum target_endianness endianness; - int data_swap; - - uint16_t manufacturer; - uint16_t device_id; - - uint8_t qry[3]; - - /* identification string */ - uint16_t pri_id; - uint16_t pri_addr; - uint16_t alt_id; - uint16_t alt_addr; - - /* device-system interface */ - uint8_t vcc_min; - uint8_t vcc_max; - uint8_t vpp_min; - uint8_t vpp_max; - uint8_t word_write_timeout_typ; - uint8_t buf_write_timeout_typ; - uint8_t block_erase_timeout_typ; - uint8_t chip_erase_timeout_typ; - uint8_t word_write_timeout_max; - uint8_t buf_write_timeout_max; - uint8_t block_erase_timeout_max; - uint8_t chip_erase_timeout_max; - - uint8_t status_poll_mask; - - /* flash geometry */ - uint32_t dev_size; - uint16_t interface_desc; - uint16_t max_buf_write_size; - uint8_t num_erase_regions; - uint32_t *erase_region_info; - - void *pri_ext; - void *alt_ext; - - /* calculated timeouts */ - unsigned word_write_timeout; - unsigned buf_write_timeout; - unsigned block_erase_timeout; - unsigned chip_erase_timeout; -}; - -/* Intel primary extended query table - * as defined for the Advanced+ Boot Block Flash Memory (C3) - * and used by the linux kernel cfi driver (as of 2.6.14) - */ -struct cfi_intel_pri_ext { - uint8_t pri[3]; - uint8_t major_version; - uint8_t minor_version; - uint32_t feature_support; - uint8_t suspend_cmd_support; - uint16_t blk_status_reg_mask; - uint8_t vcc_optimal; - uint8_t vpp_optimal; - uint8_t num_protection_fields; - uint16_t prot_reg_addr; - uint8_t fact_prot_reg_size; - uint8_t user_prot_reg_size; - uint8_t extra[0]; -}; - -/* Spansion primary extended query table as defined for and used by - * the linux kernel cfi driver (as of 2.6.15) - */ -struct cfi_spansion_pri_ext { - uint8_t pri[3]; - uint8_t major_version; - uint8_t minor_version; - uint8_t SiliconRevision; /* bits 1-0: Address Sensitive Unlock */ - uint8_t EraseSuspend; - uint8_t BlkProt; - uint8_t TmpBlkUnprotect; - uint8_t BlkProtUnprot; - uint8_t SimultaneousOps; - uint8_t BurstMode; - uint8_t PageMode; - uint8_t VppMin; - uint8_t VppMax; - uint8_t TopBottom; - int _reversed_geometry; - uint32_t _unlock1; - uint32_t _unlock2; -}; - -/* Atmel primary extended query table as defined for and used by - * the linux kernel cfi driver (as of 2.6.20+) - */ -struct cfi_atmel_pri_ext { - uint8_t pri[3]; - uint8_t major_version; - uint8_t minor_version; - uint8_t features; - uint8_t bottom_boot; - uint8_t burst_mode; - uint8_t page_mode; -}; - -enum { - CFI_UNLOCK_555_2AA, - CFI_UNLOCK_5555_2AAA, -}; - -struct cfi_unlock_addresses { - uint32_t unlock1; - uint32_t unlock2; -}; - -struct cfi_fixup { - uint16_t mfr; - uint16_t id; - void (*fixup)(struct flash_bank *bank, const void *param); - const void *param; -}; - -#define CFI_MFR_AMD 0x0001 -#define CFI_MFR_FUJITSU 0x0004 -#define CFI_MFR_ATMEL 0x001F -#define CFI_MFR_ST 0x0020 /* STMicroelectronics */ -#define CFI_MFR_AMIC 0x0037 -#define CFI_MFR_SST 0x00BF -#define CFI_MFR_MX 0x00C2 -#define CFI_MFR_EON 0x007F - -#define CFI_MFR_ANY 0xffff -#define CFI_ID_ANY 0xffff - -#endif /* OPENOCD_FLASH_NOR_CFI_H */ diff --git a/src/flash/nor/core.c b/src/flash/nor/core.c deleted file mode 100644 index 7a62ba1c7..000000000 --- a/src/flash/nor/core.c +++ /dev/null @@ -1,797 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005 by Dominic Rath * - * Copyright (C) 2007-2010 Øyvind Harboe * - * Copyright (C) 2008 by Spencer Oliver * - * Copyright (C) 2009 Zachary T Welch * - * Copyright (C) 2010 by Antonio Borneo * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 -#include -#endif -#include -#include -#include -#include - -/** - * @file - * Upper level of NOR flash framework. - * The lower level interfaces are to drivers. These upper level ones - * primarily support access from Tcl scripts or from GDB. - */ - -static struct flash_bank *flash_banks; - -int flash_driver_erase(struct flash_bank *bank, int first, int last) -{ - int retval; - - retval = bank->driver->erase(bank, first, last); - if (retval != ERROR_OK) - LOG_ERROR("failed erasing sectors %d to %d", first, last); - - return retval; -} - -int flash_driver_protect(struct flash_bank *bank, int set, int first, int last) -{ - int retval; - - /* callers may not supply illegal parameters ... */ - if (first < 0 || first > last || last >= bank->num_sectors) { - LOG_ERROR("illegal sector range"); - return ERROR_FAIL; - } - - /* force "set" to 0/1 */ - set = !!set; - - /* DANGER! - * - * We must not use any cached information about protection state!!!! - * - * There are a million things that could change the protect state: - * - * the target could have reset, power cycled, been hot plugged, - * the application could have run, etc. - * - * Drivers only receive valid sector 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); - - return retval; -} - -int flash_driver_write(struct flash_bank *bank, - uint8_t *buffer, uint32_t offset, uint32_t count) -{ - int retval; - - retval = bank->driver->write(bank, buffer, offset, count); - if (retval != ERROR_OK) { - LOG_ERROR( - "error writing to flash at address 0x%08" PRIx32 " at offset 0x%8.8" PRIx32, - bank->base, - offset); - } - - return retval; -} - -int flash_driver_read(struct flash_bank *bank, - uint8_t *buffer, uint32_t offset, uint32_t count) -{ - int retval; - - LOG_DEBUG("call flash_driver_read()"); - - retval = bank->driver->read(bank, buffer, offset, count); - if (retval != ERROR_OK) { - LOG_ERROR( - "error reading to flash at address 0x%08" PRIx32 " at offset 0x%8.8" PRIx32, - bank->base, - offset); - } - - return retval; -} - -int default_flash_read(struct flash_bank *bank, - uint8_t *buffer, uint32_t offset, uint32_t count) -{ - return target_read_buffer(bank->target, offset + bank->base, count, buffer); -} - -void flash_bank_add(struct flash_bank *bank) -{ - /* put flash bank in linked list */ - unsigned bank_num = 0; - if (flash_banks) { - /* find last flash bank */ - struct flash_bank *p = flash_banks; - while (NULL != p->next) { - bank_num += 1; - p = p->next; - } - p->next = bank; - bank_num += 1; - } else - flash_banks = bank; - - bank->bank_number = bank_num; -} - -struct flash_bank *flash_bank_list(void) -{ - return flash_banks; -} - -struct flash_bank *get_flash_bank_by_num_noprobe(int num) -{ - struct flash_bank *p; - int i = 0; - - for (p = flash_banks; p; p = p->next) { - if (i++ == num) - return p; - } - LOG_ERROR("flash bank %d does not exist", num); - return NULL; -} - -int flash_get_bank_count(void) -{ - struct flash_bank *p; - int i = 0; - for (p = flash_banks; p; p = p->next) - i++; - return i; -} - -struct flash_bank *get_flash_bank_by_name_noprobe(const char *name) -{ - unsigned requested = get_flash_name_index(name); - unsigned found = 0; - - struct flash_bank *bank; - for (bank = flash_banks; NULL != bank; bank = bank->next) { - if (strcmp(bank->name, name) == 0) - return bank; - if (!flash_driver_name_matches(bank->driver->name, name)) - continue; - if (++found < requested) - continue; - return bank; - } - return NULL; -} - -int get_flash_bank_by_name(const char *name, struct flash_bank **bank_result) -{ - struct flash_bank *bank; - int retval; - - bank = get_flash_bank_by_name_noprobe(name); - if (bank != NULL) { - retval = bank->driver->auto_probe(bank); - - if (retval != ERROR_OK) { - LOG_ERROR("auto_probe failed"); - return retval; - } - } - - *bank_result = bank; - return ERROR_OK; -} - -int get_flash_bank_by_num(int num, struct flash_bank **bank) -{ - struct flash_bank *p = get_flash_bank_by_num_noprobe(num); - int retval; - - if (p == NULL) - return ERROR_FAIL; - - retval = p->driver->auto_probe(p); - - if (retval != ERROR_OK) { - LOG_ERROR("auto_probe failed"); - return retval; - } - *bank = p; - return ERROR_OK; -} - -/* lookup flash bank by address, bank not found is success, but - * result_bank is set to NULL. */ -int get_flash_bank_by_addr(struct target *target, - uint32_t addr, - bool check, - struct flash_bank **result_bank) -{ - struct flash_bank *c; - - /* cycle through bank list */ - for (c = flash_banks; c; c = c->next) { - if (c->target != target) - continue; - - int retval; - retval = c->driver->auto_probe(c); - - if (retval != ERROR_OK) { - LOG_ERROR("auto_probe failed"); - return retval; - } - /* check whether address belongs to this flash bank */ - if ((addr >= c->base) && (addr <= c->base + (c->size - 1))) { - *result_bank = c; - return ERROR_OK; - } - } - *result_bank = NULL; - if (check) { - LOG_ERROR("No flash at address 0x%08" PRIx32, addr); - return ERROR_FAIL; - } - return ERROR_OK; -} - -static int default_flash_mem_blank_check(struct flash_bank *bank) -{ - struct target *target = bank->target; - const int buffer_size = 1024; - 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); - - for (i = 0; i < bank->num_sectors; i++) { - uint32_t j; - bank->sectors[i].is_erased = 1; - - 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) - goto done; - - for (nBytes = 0; nBytes < chunk; nBytes++) { - if (buffer[nBytes] != 0xFF) { - bank->sectors[i].is_erased = 0; - break; - } - } - } - } - -done: - free(buffer); - - return retval; -} - -int default_flash_blank_check(struct flash_bank *bank) -{ - struct target *target = bank->target; - int i; - int retval; - int fast_check = 0; - 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; - - retval = target_blank_check_memory(target, address, size, &blank); - if (retval != ERROR_OK) { - fast_check = 0; - break; - } - if (blank == 0xFF) - bank->sectors[i].is_erased = 1; - else - bank->sectors[i].is_erased = 0; - fast_check = 1; - } - - if (!fast_check) { - LOG_USER("Running slow fallback erase check - add working memory"); - return default_flash_mem_blank_check(bank); - } - - return ERROR_OK; -} - -/* Manipulate given flash region, selecting the bank according to target - * 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. - * - * 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 - * erase data which the caller said to leave alone, for example. If it's - * non-NULL, rather than failing, extra data in the first and/or last - * sectors will be added to the range, and that reason string is used when - * warning about those additions. - */ -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) - return retval; - - if (c->size == 0 || c->num_sectors == 0) { - LOG_ERROR("Bank is invalid"); - return ERROR_FLASH_BANK_INVALID; - } - - if (length == 0) { - /* special case, erase whole bank when length is zero */ - if (addr != c->base) { - LOG_ERROR("Whole bank access must start at beginning of bank."); - return ERROR_FLASH_DST_BREAKS_ALIGNMENT; - } - - return callback(c, 0, c->num_sectors - 1); - } - - /* check whether it all fits in this bank */ - if (addr + length - 1 > c->base + c->size - 1) { - LOG_ERROR("Flash access does not fit into bank."); - return ERROR_FLASH_DST_BREAKS_ALIGNMENT; - } - - addr -= c->base; - last_addr -= c->base; - - 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 */ - if (first < 0) { - /* scanned past the first sector? */ - if (addr < f->offset) - break; - - /* is this the first sector? */ - if (addr == f->offset) - first = i; - - /* Does this need head-padding? If so, pad and warn; - * or else force an error. - * - * Such padding can make trouble, since *WE* can't - * ever know if that data was in use. The warning - * should help users sort out messes later. - */ - else if (addr < end && pad_reason) { - /* FIXME say how many bytes (e.g. 80 KB) */ - LOG_WARNING("Adding extra %s range, " - "%#8.8x to %#8.8x", - pad_reason, - (unsigned) f->offset, - (unsigned) addr - 1); - first = i; - } else - continue; - } - - /* is this (also?) the last sector? */ - if (last_addr == end) { - last = i; - break; - } - - /* Does this need tail-padding? If so, pad and warn; - * or else force an error. - */ - if (last_addr < end && pad_reason) { - /* FIXME say how many bytes (e.g. 80 KB) */ - LOG_WARNING("Adding extra %s range, " - "%#8.8x to %#8.8x", - pad_reason, - (unsigned) last_addr, - (unsigned) end - 1); - last = i; - break; - } - - /* MUST finish on a sector boundary */ - if (last_addr <= f->offset) - break; - } - - /* invalid start or end address? */ - if (first == -1 || last == -1) { - LOG_ERROR("address range 0x%8.8x .. 0x%8.8x " - "is not sector-aligned", - (unsigned) (c->base + addr), - (unsigned) (c->base + last_addr - 1)); - return ERROR_FLASH_DST_BREAKS_ALIGNMENT; - } - - /* The NOR driver may trim this range down, based on what - * sectors are already erased/unprotected. GDB currently - * blocks such optimizations. - */ - return callback(c, first, last); -} - -/* The inner fn only handles a single bank, we could be spanning - * multiple chips. - */ -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; - int retval = ERROR_OK; - - /* Danger! zero-length iterations means entire bank! */ - do { - retval = get_flash_bank_by_addr(target, addr, true, &c); - if (retval != ERROR_OK) - return retval; - - uint32_t cur_length = length; - /* check whether it all fits in this bank */ - if (addr + length - 1 > c->base + c->size - 1) { - LOG_DEBUG("iterating over more than one flash bank."); - cur_length = c->base + c->size - addr; - } - retval = flash_iterate_address_range_inner(target, - pad_reason, addr, cur_length, - iterate_protect_blocks, - callback); - if (retval != ERROR_OK) - break; - - length -= cur_length; - addr += cur_length; - } while (length > 0); - - return retval; -} - -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, false, &flash_driver_erase); -} - -static int flash_driver_unprotect(struct flash_bank *bank, int first, int last) -{ - return flash_driver_protect(bank, 0, first, last); -} - -int flash_unlock_address_range(struct target *target, uint32_t addr, uint32_t length) -{ - /* By default, pad to sector boundaries ... the real issue here - * is that our (only) caller *permanently* removes protection, - * and doesn't restore it. - */ - return flash_iterate_address_range(target, "unprotect", - addr, length, true, &flash_driver_unprotect); -} - -static int compare_section(const void *a, const void *b) -{ - struct imagesection *b1, *b2; - b1 = *((struct imagesection **)a); - b2 = *((struct imagesection **)b); - - if (b1->base_address == b2->base_address) - return 0; - else if (b1->base_address > b2->base_address) - return 1; - else - return -1; -} - -int flash_write_unlock(struct target *target, struct image *image, - uint32_t *written, int erase, bool unlock) -{ - int retval = ERROR_OK; - - int section; - uint32_t section_offset; - struct flash_bank *c; - int *padding; - - section = 0; - section_offset = 0; - - if (written) - *written = 0; - - if (erase) { - /* assume all sectors need erasing - stops any problems - * when flash_write is called multiple times */ - - flash_set_dirty(); - } - - /* allocate padding array */ - padding = calloc(image->num_sections, sizeof(*padding)); - - /* This fn requires all sections to be in ascending order of addresses, - * whereas an image can have sections out of order. */ - struct imagesection **sections = malloc(sizeof(struct imagesection *) * - image->num_sections); - int i; - for (i = 0; i < image->num_sections; i++) - sections[i] = &image->sections[i]; - - qsort(sections, image->num_sections, sizeof(struct imagesection *), - compare_section); - - /* loop until we reach end of the image */ - while (section < image->num_sections) { - uint32_t buffer_size; - uint8_t *buffer; - int section_last; - uint32_t run_address = sections[section]->base_address + section_offset; - uint32_t run_size = sections[section]->size - section_offset; - int pad_bytes = 0; - - if (sections[section]->size == 0) { - LOG_WARNING("empty section %d", section); - section++; - section_offset = 0; - continue; - } - - /* find the corresponding flash bank */ - retval = get_flash_bank_by_addr(target, run_address, false, &c); - if (retval != ERROR_OK) - goto done; - if (c == NULL) { - LOG_WARNING("no flash bank found for address %" PRIx32, run_address); - section++; /* and skip it */ - section_offset = 0; - continue; - } - - /* collect consecutive sections which fall into the same bank */ - section_last = section; - padding[section] = 0; - while ((run_address + run_size - 1 < c->base + c->size - 1) && - (section_last + 1 < image->num_sections)) { - /* sections are sorted */ - assert(sections[section_last + 1]->base_address >= c->base); - if (sections[section_last + 1]->base_address >= (c->base + c->size)) { - /* Done with this bank */ - break; - } - - /* FIXME This needlessly touches sectors BETWEEN the - * sections it's writing. Without auto erase, it just - * writes ones. That WILL INVALIDATE data in cases - * like Stellaris Tempest chips, corrupting internal - * ECC codes; and at least FreeScale suggests issues - * with that approach (in HC11 documentation). - * - * With auto erase enabled, data in those sectors will - * be needlessly destroyed; and some of the limited - * number of flash erase cycles will be wasted... - * - * In both cases, the extra writes slow things down. - */ - - /* if we have multiple sections within our image, - * flash programming could fail due to alignment issues - * attempt to rebuild a consecutive buffer for the flash loader */ - pad_bytes = (sections[section_last + 1]->base_address) - (run_address + run_size); - padding[section_last] = pad_bytes; - run_size += sections[++section_last]->size; - run_size += pad_bytes; - - if (pad_bytes > 0) - LOG_INFO("Padding image section %d with %d bytes", - section_last-1, - pad_bytes); - } - - if (run_address + run_size - 1 > c->base + c->size - 1) { - /* If we have more than one flash chip back to back, then we limit - * the current write operation to the current chip. - */ - LOG_DEBUG("Truncate flash run size to the current flash chip."); - - run_size = c->base + c->size - run_address; - assert(run_size > 0); - } - - /* If we're applying any sector automagic, then pad this - * (maybe-combined) segment to the end of its last sector. - */ - if (unlock || erase) { - int sector; - uint32_t offset_start = run_address - c->base; - uint32_t offset_end = offset_start + run_size; - uint32_t end = offset_end, delta; - - for (sector = 0; sector < c->num_sectors; sector++) { - end = c->sectors[sector].offset - + c->sectors[sector].size; - if (offset_end <= end) - break; - } - - delta = end - offset_end; - padding[section_last] += delta; - run_size += delta; - } - - /* allocate buffer */ - buffer = malloc(run_size); - if (buffer == NULL) { - LOG_ERROR("Out of memory for flash bank buffer"); - retval = ERROR_FAIL; - goto done; - } - buffer_size = 0; - - /* read sections to the buffer */ - while (buffer_size < run_size) { - size_t size_read; - - size_read = run_size - buffer_size; - if (size_read > sections[section]->size - section_offset) - size_read = sections[section]->size - section_offset; - - /* KLUDGE! - * - * #¤%#"%¤% we have to figure out the section # from the sorted - * list of pointers to sections to invoke image_read_section()... - */ - intptr_t diff = (intptr_t)sections[section] - (intptr_t)image->sections; - int t_section_num = diff / sizeof(struct imagesection); - - LOG_DEBUG("image_read_section: section = %d, t_section_num = %d, " - "section_offset = %d, buffer_size = %d, size_read = %d", - (int)section, (int)t_section_num, (int)section_offset, - (int)buffer_size, (int)size_read); - retval = image_read_section(image, t_section_num, section_offset, - size_read, buffer + buffer_size, &size_read); - if (retval != ERROR_OK || size_read == 0) { - free(buffer); - goto done; - } - - /* see if we need to pad the section */ - while (padding[section]--) - (buffer + buffer_size)[size_read++] = c->default_padded_value; - - buffer_size += size_read; - section_offset += size_read; - - if (section_offset >= sections[section]->size) { - section++; - section_offset = 0; - } - } - - retval = ERROR_OK; - - if (unlock) - retval = flash_unlock_address_range(target, run_address, run_size); - if (retval == ERROR_OK) { - if (erase) { - /* calculate and erase sectors */ - retval = flash_erase_address_range(target, - true, run_address, run_size); - } - } - - if (retval == ERROR_OK) { - /* write flash sectors */ - retval = flash_driver_write(c, buffer, run_address - c->base, run_size); - } - - free(buffer); - - if (retval != ERROR_OK) { - /* abort operation */ - goto done; - } - - if (written != NULL) - *written += run_size; /* add run size to total written counter */ - } - -done: - free(sections); - free(padding); - - return retval; -} - -int flash_write(struct target *target, struct image *image, - uint32_t *written, int erase) -{ - 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 deleted file mode 100644 index 60d4483ae..000000000 --- a/src/flash/nor/core.h +++ /dev/null @@ -1,232 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005 by Dominic Rath * - * Copyright (C) 2007,2008 Øyvind Harboe * - * Copyright (C) 2008 by Spencer Oliver * - * Copyright (C) 2009 Zachary T Welch * - * Copyright (C) 2010 by Antonio Borneo * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 OPENOCD_FLASH_NOR_CORE_H -#define OPENOCD_FLASH_NOR_CORE_H - -#include - -/** - * @file - * Upper level NOR flash interfaces. - */ - -struct image; - -#define FLASH_MAX_ERROR_STR (128) - -/** - * Describes the geometry and status of a single flash sector - * within a flash bank. A single bank typically consists of multiple - * sectors, each of which can be erased and protected independently. - */ -struct flash_sector { - /** Bus offset from start of the flash chip (in bytes). */ - uint32_t offset; - /** Number of bytes in this flash sector. */ - uint32_t size; - /** - * 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; - /** - * Indication of protection status: 0 = unprotected/unlocked, - * 1 = protected/locked, other = unknown. Set by - * @c flash_driver_s::protect_check. - * - * 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; -}; - -/** - * Provides details of a flash bank, available either on-chip or through - * a major interface. - * - * This structure will be passed as a parameter to the callbacks in the - * flash_driver_s structure, some of which may modify the contents of - * this structure of the area of flash that it defines. Driver writers - * may use the @c driver_priv member to store additional data on a - * per-bank basis, if required. - */ -struct flash_bank { - const char *name; - - struct target *target; /**< Target to which this bank belongs. */ - - struct flash_driver *driver; /**< Driver for this bank. */ - void *driver_priv; /**< Private driver storage pointer */ - - int bank_number; /**< The 'bank' (or chip number) of this instance. */ - uint32_t base; /**< The base address of this bank */ - uint32_t size; /**< The size of this chip bank, in bytes */ - - 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) */ - - /** Default padded value used, normally this matches the flash - * erased value. Defaults to 0xFF. */ - uint8_t default_padded_value; - - /** - * The number of sectors on this chip. This value will - * be set intially to 0, and the flash driver must set this to - * some non-zero value during "probe()" or "auto_probe()". - */ - int num_sectors; - /** 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 */ -}; - -/** Registers the 'flash' subsystem commands */ -int flash_register_commands(struct command_context *cmd_ctx); - -/** - * Erases @a length bytes in the @a target flash, starting at @a addr. - * The range @a addr to @a addr + @a length - 1 must be strictly - * sector aligned, unless @a pad is true. Setting @a pad true extends - * the range, at beginning and/or end, if needed for sector alignment. - * @returns ERROR_OK if successful; otherwise, an error code. - */ -int flash_erase_address_range(struct target *target, - bool pad, uint32_t addr, uint32_t length); - -int flash_unlock_address_range(struct target *target, uint32_t addr, - uint32_t length); - -/** - * Writes @a image into the @a target flash. The @a written parameter - * will contain the - * @param target The target with the flash to be programmed. - * @param image The image that will be programmed to flash. - * @param written On return, contains the number of bytes written. - * @param erase If non-zero, indicates the flash driver should first - * erase the corresponding banks or sectors before programming. - * @returns ERROR_OK if successful; otherwise, an error code. - */ -int flash_write(struct target *target, - struct image *image, uint32_t *written, int erase); - -/** - * Forces targets to re-examine their erase/protection state. - * This routine must be called when the system may modify the status. - */ -void flash_set_dirty(void); -/** @returns The number of flash banks currently defined. */ -int flash_get_bank_count(void); -/** - * Provides default read implementation for flash memory. - * @param bank The bank to read. - * @param buffer The data bytes read. - * @param offset The offset into the chip to read. - * @param count The number of bytes to read. - * @returns ERROR_OK if successful; otherwise, an error code. - */ -int default_flash_read(struct flash_bank *bank, - uint8_t *buffer, uint32_t offset, uint32_t count); -/** - * Provides default erased-bank check handling. Checks to see if - * the flash driver knows they are erased; if things look uncertain, - * this routine will call default_flash_mem_blank_check() to confirm. - * @returns ERROR_OK if successful; otherwise, an error code. - */ -int default_flash_blank_check(struct flash_bank *bank); - -/** - * Returns the flash bank specified by @a name, which matches the - * driver name and a suffix (option) specify the driver-specific - * bank number. The suffix consists of the '.' and the driver-specific - * bank number: when two str9x banks are defined, then 'str9x.1' refers - * to the second. - */ -int get_flash_bank_by_name(const char *name, struct flash_bank **bank_result); -/** - * Returns the flash bank specified by @a name, which matches the - * driver name and a suffix (option) specify the driver-specific - * bank number. The suffix consists of the '.' and the driver-specific - * bank number: when two str9x banks are defined, then 'str9x.1' refers - * to the second. - */ -struct flash_bank *get_flash_bank_by_name_noprobe(const char *name); -/** - * Returns the flash bank like get_flash_bank_by_name(), without probing. - * @param num The flash bank number. - * @param bank returned bank if fn returns ERROR_OK - * @returns ERROR_OK if successful - */ -int get_flash_bank_by_num(int num, struct flash_bank **bank); -/** - * Retreives @a bank from a command argument, reporting errors parsing - * the bank identifier or retreiving the specified bank. The bank - * may be identified by its bank number or by @c name.instance, where - * @a instance is driver-specific. - * @param name_index The index to the string in args containing the - * bank identifier. - * @param bank On output, contians a pointer to the bank or NULL. - * @returns ERROR_OK on success, or an error indicating the problem. - */ -COMMAND_HELPER(flash_command_get_bank, unsigned name_index, - struct flash_bank **bank); -/** - * Returns the flash bank like get_flash_bank_by_num(), without probing. - * @param num The flash bank number. - * @returns A struct flash_bank for flash bank @a num, or NULL. - */ -struct flash_bank *get_flash_bank_by_num_noprobe(int num); -/** - * Returns the flash bank located at a specified address. - * @param target The target, presumed to contain one or more banks. - * @param addr An address that is within the range of the bank. - * @param check return ERROR_OK and result_bank NULL if the bank does not exist - * @returns The struct flash_bank located at @a addr, or NULL. - */ -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 /* OPENOCD_FLASH_NOR_CORE_H */ diff --git a/src/flash/nor/driver.h b/src/flash/nor/driver.h deleted file mode 100644 index 0ae4d8e20..000000000 --- a/src/flash/nor/driver.h +++ /dev/null @@ -1,224 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005 by Dominic Rath * - * Copyright (C) 2007,2008 Øyvind Harboe * - * Copyright (C) 2008 by Spencer Oliver * - * Copyright (C) 2009 Zachary T Welch * - * Copyright (C) 2010 by Antonio Borneo * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 OPENOCD_FLASH_NOR_DRIVER_H -#define OPENOCD_FLASH_NOR_DRIVER_H - -struct flash_bank; - -#define __FLASH_BANK_COMMAND(name) \ - COMMAND_HELPER(name, struct flash_bank *bank) - -/** - * @brief Provides the implementation-independent structure that defines - * all of the callbacks required by OpenOCD flash drivers. - * - * Driver authors must implement the routines defined here, providing an - * instance with the fields filled out. After that, the instance must - * be registered in flash.c, so it can be used by the driver lookup system. - * - * Specifically, the user can issue the command: @par - * @code - * flash bank DRIVERNAME ...parameters... - * @endcode - * - * OpenOCD will search for the driver with a @c flash_driver_s::name - * that matches @c DRIVERNAME. - * - * The flash subsystem calls some of the other drivers routines a using - * corresponding static flash_driver_callback() - * routine in flash.c. - */ -struct flash_driver { - /** - * Gives a human-readable name of this flash driver, - * This field is used to select and initialize the driver. - */ - const char *name; - - /** - * Gives a human-readable description of arguments. - */ - const char *usage; - - /** - * An array of driver-specific commands to register. When called - * during the "flash bank" command, the driver can register addition - * commands to support new flash chip functions. - */ - const struct command_registration *commands; - - /** - * Finish the "flash bank" command for @a bank. The - * @a bank parameter will have been filled in by the core flash - * layer when this routine is called, and the driver can store - * additional information in its struct flash_bank::driver_priv field. - * - * The CMD_ARGV are: @par - * @code - * CMD_ARGV[0] = bank - * CMD_ARGV[1] = drivername {name above} - * CMD_ARGV[2] = baseaddress - * CMD_ARGV[3] = lengthbytes - * CMD_ARGV[4] = chip_width_in bytes - * CMD_ARGV[5] = bus_width_in_bytes - * CMD_ARGV[6] = driver-specific parameters - * @endcode - * - * For example, CMD_ARGV[4] = 2 (for 16 bit flash), - * CMD_ARGV[5] = 4 (for 32 bit bus). - * - * If extra arguments are provided (@a CMD_ARGC > 6), they will - * start in @a CMD_ARGV[6]. These can be used to implement - * driver-specific extensions. - * - * @returns ERROR_OK if successful; otherwise, an error code. - */ - __FLASH_BANK_COMMAND((*flash_bank_command)); - - /** - * Bank/sector erase routine (target-specific). When - * called, the flash driver should erase the specified sectors - * using whatever means are at its disposal. - * - * @param bank The bank of flash to be erased. - * @param first The number of the first sector to erase, typically 0. - * @param last The number of the last sector to erase, typically N-1. - * @returns ERROR_OK if successful; otherwise, an error code. - */ - int (*erase)(struct flash_bank *bank, int first, int last); - - /** - * Bank/sector protection routine (target-specific). - * - * When called, the driver should enable/disable protection - * for MINIMUM the range covered by first..last sectors - * inclusive. Some chips have alignment requirements will - * cause the actual range to be protected / unprotected to - * be larger than the first..last range. - * - * @param bank The bank to protect or unprotect. - * @param set If non-zero, enable protection; if 0, disable it. - * @param first The first sector to (un)protect, typicaly 0. - * @param last The last sector to (un)project, typically N-1. - * @returns ERROR_OK if successful; otherwise, an error code. - */ - int (*protect)(struct flash_bank *bank, int set, int first, int last); - - /** - * Program data into the flash. Note CPU address will be - * "bank->base + offset", while the physical address is - * dependent upon current target MMU mappings. - * - * @param bank The bank to program - * @param buffer The data bytes to write. - * @param offset The offset into the chip to program. - * @param count The number of bytes to write. - * @returns ERROR_OK if successful; otherwise, an error code. - */ - int (*write)(struct flash_bank *bank, - const uint8_t *buffer, uint32_t offset, uint32_t count); - - /** - * Read data from the flash. Note CPU address will be - * "bank->base + offset", while the physical address is - * dependent upon current target MMU mappings. - * - * @param bank The bank to read. - * @param buffer The data bytes read. - * @param offset The offset into the chip to read. - * @param count The number of bytes to read. - * @returns ERROR_OK if successful; otherwise, an error code. - */ - int (*read)(struct flash_bank *bank, - uint8_t *buffer, uint32_t offset, uint32_t count); - - /** - * Probe to determine what kind of flash is present. - * This is invoked by the "probe" script command. - * - * @param bank The bank to probe - * @returns ERROR_OK if successful; otherwise, an error code. - */ - int (*probe)(struct flash_bank *bank); - - /** - * Check the erasure status of a flash bank. - * When called, the driver routine must perform the required - * checks and then set the @c flash_sector_s::is_erased field - * for each of the flash banks's sectors. - * - * @param bank The bank to check - * @returns ERROR_OK if successful; otherwise, an error code. - */ - int (*erase_check)(struct flash_bank *bank); - - /** - * Determine if the specific bank is "protected" or not. - * When called, the driver routine must must perform the - * required protection check(s) and then set the @c - * flash_sector_s::is_protected field for each of the flash - * bank's sectors. - * - * @param bank - the bank to check - * @returns ERROR_OK if successful; otherwise, an error code. - */ - int (*protect_check)(struct flash_bank *bank); - - /** - * Display human-readable information about the flash - * bank into the given buffer. Drivers must be careful to avoid - * overflowing the buffer. - * - * @param bank - the bank to get info about - * @param char - where to put the text for the human to read - * @param buf_size - the size of the human buffer. - * @returns ERROR_OK if successful; otherwise, an error code. - */ - int (*info)(struct flash_bank *bank, char *buf, int buf_size); - - /** - * A more gentle flavor of filash_driver_s::probe, performing - * setup with less noise. Generally, driver routines should test - * to see if the bank has already been probed; if it has, the - * driver probably should not perform its probe a second time. - * - * This callback is often called from the inside of other - * routines (e.g. GDB flash downloads) to autoprobe the flash as - * it is programing the flash. - * - * @param bank - the bank to probe - * @returns ERROR_OK if successful; otherwise, an error code. - */ - int (*auto_probe)(struct flash_bank *bank); -}; - -#define FLASH_BANK_COMMAND_HANDLER(name) \ - static __FLASH_BANK_COMMAND(name) - -/** - * Find a NOR flash driver by its name. - * @param name The name of the requested driver. - * @returns The flash_driver called @c name, or NULL if not found. - */ -struct flash_driver *flash_driver_find_by_name(const char *name); - -#endif /* OPENOCD_FLASH_NOR_DRIVER_H */ diff --git a/src/flash/nor/drivers.c b/src/flash/nor/drivers.c deleted file mode 100644 index e7b6a885a..000000000 --- a/src/flash/nor/drivers.c +++ /dev/null @@ -1,133 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2009 Zachary T Welch * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 -#include "config.h" -#endif -#include "imp.h" - -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 at91sam7_flash; -extern struct flash_driver at91samd_flash; -extern struct flash_driver atsamv_flash; -extern struct flash_driver avr_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; -extern struct flash_driver fespi_flash; -extern struct flash_driver jtagspi_flash; -extern struct flash_driver kinetis_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 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 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; - -/** - * The list of built-in flash drivers. - * @todo Make this dynamically extendable with loadable modules. - */ -static struct flash_driver *flash_drivers[] = { - &aduc702x_flash, - &aducm360_flash, - &ambiqmicro_flash, - &at91sam3_flash, - &at91sam4_flash, - &at91sam4l_flash, - &at91sam7_flash, - &at91samd_flash, - &atsamv_flash, - &avr_flash, - &cfi_flash, - &dsp5680xx_flash, - &efm32_flash, - &em357_flash, - &faux_flash, - &fm3_flash, - &fm4_flash, - &fespi_flash, - &jtagspi_flash, - &kinetis_flash, - &kinetis_ke_flash, - &lpc2000_flash, - &lpc288x_flash, - &lpc2900_flash, - &lpcspifi_flash, - &mdr_flash, - &mrvlqspi_flash, - &niietcm4_flash, - &nrf51_flash, - &numicro_flash, - &ocl_flash, - &pic32mx_flash, - &psoc4_flash, - &sim3x_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, - NULL, -}; - -struct flash_driver *flash_driver_find_by_name(const char *name) -{ - for (unsigned i = 0; flash_drivers[i]; i++) { - if (strcmp(name, flash_drivers[i]->name) == 0) - return flash_drivers[i]; - } - return NULL; -} diff --git a/src/flash/nor/dsp5680xx_flash.c b/src/flash/nor/dsp5680xx_flash.c deleted file mode 100644 index 38649ff04..000000000 --- a/src/flash/nor/dsp5680xx_flash.c +++ /dev/null @@ -1,270 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2011 by Rodrigo L. Rosa * - * rodrigorosa.LG@gmail.com * - * * - * Based on a file written by: * - * Kevin McGuire * - * Marcel Wijlaars * - * Michael Ashton * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -/** - * @file dsp5680xx_flash.c - * @author Rodrigo L. Rosa - * @date Thu Jun 9 18:21:58 2011 - * - * @brief This file implements the basic functions to run flashing commands - * from the TCL interface. - * It allows the user to flash the Freescale 5680xx DSP. - * - * - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "imp.h" -#include -#include -#include -#include - -static int dsp5680xx_build_sector_list(struct flash_bank *bank) -{ - uint32_t offset = HFM_FLASH_BASE_ADDR; - - bank->sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors); - int i; - - for (i = 0; i < bank->num_sectors; ++i) { - bank->sectors[i].offset = i * HFM_SECTOR_SIZE; - bank->sectors[i].size = HFM_SECTOR_SIZE; - offset += bank->sectors[i].size; - bank->sectors[i].is_erased = -1; - bank->sectors[i].is_protected = -1; - } - LOG_USER("%s not tested yet.", __func__); - return ERROR_OK; - -} - -/* flash bank dsp5680xx 0 0 0 0 */ -FLASH_BANK_COMMAND_HANDLER(dsp5680xx_flash_bank_command) -{ - bank->base = HFM_FLASH_BASE_ADDR; - bank->size = HFM_SIZE_BYTES; /* top 4k not accessible */ - bank->num_sectors = HFM_SECTOR_COUNT; - dsp5680xx_build_sector_list(bank); - - return ERROR_OK; -} - -/** - * A memory mapped register (PROT) holds information regarding sector protection. - * Protection refers to undesired core access. - * The value in this register is loaded from flash upon reset. - * - * @param bank - * - * @return - */ -static int dsp5680xx_flash_protect_check(struct flash_bank *bank) -{ - int retval = ERROR_OK; - - uint16_t protected = 0; - - retval = dsp5680xx_f_protect_check(bank->target, &protected); - if (retval != ERROR_OK) { - for (int i = 0; i < HFM_SECTOR_COUNT; i++) - bank->sectors[i].is_protected = -1; - return ERROR_OK; - } - for (int i = 0; i < HFM_SECTOR_COUNT / 2; i++) { - if (protected & 1) { - bank->sectors[2 * i].is_protected = 1; - bank->sectors[2 * i + 1].is_protected = 1; - } else { - bank->sectors[2 * i].is_protected = 0; - bank->sectors[2 * i + 1].is_protected = 0; - } - protected = (protected >> 1); - } - return retval; -} - -/** - * Protection funcionality is not implemented. - * The current implementation applies/removes security on the chip. - * The chip is effectively secured/unsecured after the first reset - * following the execution of this function. - * - * @param bank - * @param set Apply or remove security on the chip. - * @param first This parameter is ignored. - * @param last This parameter is ignored. - * - * @return - */ -static int dsp5680xx_flash_protect(struct flash_bank *bank, int set, int first, - int last) -{ -/** - * This applies security to flash module after next reset, it does - * not actually apply protection (protection refers to undesired access from the core) - */ - int retval; - - if (set) - retval = dsp5680xx_f_lock(bank->target); - else { - retval = dsp5680xx_f_unlock(bank->target); - if (retval == ERROR_OK) { - /* mark all as erased */ - for (int i = 0; i <= (HFM_SECTOR_COUNT - 1); i++) - /* FM does not recognize it as erased if erased via JTAG. */ - bank->sectors[i].is_erased = 1; - } - } - return retval; -} - -/** - * The dsp5680xx use word addressing. The "/2" that appear in the following code - * are a workaround for the fact that OpenOCD uses byte addressing. - * - * @param bank - * @param buffer Data to write to flash. - * @param offset - * @param count In bytes (2 bytes per address). - * - * @return - */ -static int dsp5680xx_flash_write(struct flash_bank *bank, const uint8_t* buffer, - uint32_t offset, uint32_t count) -{ - int retval; - - if ((offset + count / 2) > bank->size) { - LOG_ERROR("%s: Flash bank cannot fit data.", __func__); - return ERROR_FAIL; - } - if (offset % 2) { - /** - * Writing to odd addresses not supported. - * This chip uses word addressing, Openocd only supports byte addressing. - * The workaround results in disabling writing to odd byte addresses - */ - LOG_ERROR("%s: Writing to odd addresses not supported for this target", __func__); - return ERROR_FAIL; - } - retval = dsp5680xx_f_wr(bank->target, buffer, bank->base + offset / 2, count, 0); - uint32_t addr_word; - - for (addr_word = bank->base + offset / 2; addr_word < count / 2; - addr_word += (HFM_SECTOR_SIZE / 2)) { - if (retval == ERROR_OK) - bank->sectors[addr_word / (HFM_SECTOR_SIZE / 2)].is_erased = 0; - else - bank->sectors[addr_word / (HFM_SECTOR_SIZE / 2)].is_erased = -1; - } - return retval; -} - -static int dsp5680xx_probe(struct flash_bank *bank) -{ - LOG_DEBUG("%s not implemented", __func__); - return ERROR_OK; -} - -/** - * The flash module (FM) on the dsp5680xx supports both individual sector - * and mass erase of the flash memory. - * If this function is called with @first == @last == 0 or if @first is the - * first sector (#0) and @last is the last sector then the mass erase command - * is executed (much faster than erasing each sector individually). - * - * @param bank - * @param first - * @param last - * - * @return - */ -static int dsp5680xx_flash_erase(struct flash_bank *bank, int first, int last) -{ - int retval; - - retval = dsp5680xx_f_erase(bank->target, (uint32_t) first, (uint32_t) last); - if ((!(first | last)) || ((first == 0) && (last == (HFM_SECTOR_COUNT - 1)))) - last = HFM_SECTOR_COUNT - 1; - if (retval == ERROR_OK) - for (int i = first; i <= last; i++) - bank->sectors[i].is_erased = 1; - else - /** - * If an error occurred unknown status - *is set even though some sector could have been correctly erased. - */ - for (int i = first; i <= last; i++) - bank->sectors[i].is_erased = -1; - return retval; -} - -/** - * The flash module (FM) on the dsp5680xx support a blank check function. - * This function executes the FM's blank check functionality on each and every sector. - * - * @param bank - * - * @return - */ -static int dsp5680xx_flash_erase_check(struct flash_bank *bank) -{ - int retval = ERROR_OK; - - uint8_t erased = 0; - - uint32_t i; - - for (i = 0; i < HFM_SECTOR_COUNT; i++) { - if (bank->sectors[i].is_erased == -1) { - retval = dsp5680xx_f_erase_check(bank->target, &erased, i); - if (retval != ERROR_OK) { - bank->sectors[i].is_erased = -1; - } else { - if (erased) - bank->sectors[i].is_erased = 1; - else - bank->sectors[i].is_erased = 0; - } - } - } - return retval; -} - -struct flash_driver dsp5680xx_flash = { - .name = "dsp5680xx_flash", - .flash_bank_command = dsp5680xx_flash_bank_command, - .erase = dsp5680xx_flash_erase, - .protect = dsp5680xx_flash_protect, - .write = dsp5680xx_flash_write, - /* .read = default_flash_read, */ - .probe = dsp5680xx_probe, - .auto_probe = dsp5680xx_probe, - .erase_check = dsp5680xx_flash_erase_check, - .protect_check = dsp5680xx_flash_protect_check, -}; diff --git a/src/flash/nor/efm32.c b/src/flash/nor/efm32.c deleted file mode 100644 index 0b33829ba..000000000 --- a/src/flash/nor/efm32.c +++ /dev/null @@ -1,1069 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * Copyright (C) 2008 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * Copyright (C) 2011 by Andreas Fritiofson * - * andreas.fritiofson@gmail.com * - * * - * Copyright (C) 2013 by Roman Dmitrienko * - * me@iamroman.org * - * * - * Copyright (C) 2014 Nemui Trinomius * - * nemuisan_kawausogasuki@live.jp * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "imp.h" -#include -#include -#include -#include - -/* keep family IDs in decimal */ -#define EFM_FAMILY_ID_GECKO 71 -#define EFM_FAMILY_ID_GIANT_GECKO 72 -#define EFM_FAMILY_ID_TINY_GECKO 73 -#define EFM_FAMILY_ID_LEOPARD_GECKO 74 -#define EFM_FAMILY_ID_WONDER_GECKO 75 -#define EFM_FAMILY_ID_ZERO_GECKO 76 -#define EFM_FAMILY_ID_HAPPY_GECKO 77 -#define EZR_FAMILY_ID_WONDER_GECKO 120 -#define EZR_FAMILY_ID_LEOPARD_GECKO 121 - -#define EFM32_FLASH_ERASE_TMO 100 -#define EFM32_FLASH_WDATAREADY_TMO 100 -#define EFM32_FLASH_WRITE_TMO 100 - -/* size in bytes, not words; must fit all Gecko devices */ -#define LOCKBITS_PAGE_SZ 512 - -#define EFM32_MSC_INFO_BASE 0x0fe00000 - -#define EFM32_MSC_USER_DATA EFM32_MSC_INFO_BASE -#define EFM32_MSC_LOCK_BITS (EFM32_MSC_INFO_BASE+0x4000) -#define EFM32_MSC_DEV_INFO (EFM32_MSC_INFO_BASE+0x8000) - -/* PAGE_SIZE is only present in Leopard, Giant and Wonder Gecko MCUs */ -#define EFM32_MSC_DI_PAGE_SIZE (EFM32_MSC_DEV_INFO+0x1e7) -#define EFM32_MSC_DI_FLASH_SZ (EFM32_MSC_DEV_INFO+0x1f8) -#define EFM32_MSC_DI_RAM_SZ (EFM32_MSC_DEV_INFO+0x1fa) -#define EFM32_MSC_DI_PART_NUM (EFM32_MSC_DEV_INFO+0x1fc) -#define EFM32_MSC_DI_PART_FAMILY (EFM32_MSC_DEV_INFO+0x1fe) -#define EFM32_MSC_DI_PROD_REV (EFM32_MSC_DEV_INFO+0x1ff) - -#define EFM32_MSC_REGBASE 0x400c0000 -#define EFM32_MSC_WRITECTRL (EFM32_MSC_REGBASE+0x008) -#define EFM32_MSC_WRITECTRL_WREN_MASK 0x1 -#define EFM32_MSC_WRITECMD (EFM32_MSC_REGBASE+0x00c) -#define EFM32_MSC_WRITECMD_LADDRIM_MASK 0x1 -#define EFM32_MSC_WRITECMD_ERASEPAGE_MASK 0x2 -#define EFM32_MSC_WRITECMD_WRITEONCE_MASK 0x8 -#define EFM32_MSC_ADDRB (EFM32_MSC_REGBASE+0x010) -#define EFM32_MSC_WDATA (EFM32_MSC_REGBASE+0x018) -#define EFM32_MSC_STATUS (EFM32_MSC_REGBASE+0x01c) -#define EFM32_MSC_STATUS_BUSY_MASK 0x1 -#define EFM32_MSC_STATUS_LOCKED_MASK 0x2 -#define EFM32_MSC_STATUS_INVADDR_MASK 0x4 -#define EFM32_MSC_STATUS_WDATAREADY_MASK 0x8 -#define EFM32_MSC_STATUS_WORDTIMEOUT_MASK 0x10 -#define EFM32_MSC_STATUS_ERASEABORTED_MASK 0x20 -#define EFM32_MSC_LOCK (EFM32_MSC_REGBASE+0x03c) -#define EFM32_MSC_LOCK_LOCKKEY 0x1b71 - -struct efm32x_flash_bank { - int probed; - uint32_t lb_page[LOCKBITS_PAGE_SZ/4]; -}; - -struct efm32_info { - uint16_t flash_sz_kib; - uint16_t ram_sz_kib; - uint16_t part_num; - uint8_t part_family; - uint8_t prod_rev; - uint16_t page_size; -}; - -static int efm32x_write(struct flash_bank *bank, const uint8_t *buffer, - uint32_t offset, uint32_t count); - -static int efm32x_get_flash_size(struct flash_bank *bank, uint16_t *flash_sz) -{ - return target_read_u16(bank->target, EFM32_MSC_DI_FLASH_SZ, flash_sz); -} - -static int efm32x_get_ram_size(struct flash_bank *bank, uint16_t *ram_sz) -{ - return target_read_u16(bank->target, EFM32_MSC_DI_RAM_SZ, ram_sz); -} - -static int efm32x_get_part_num(struct flash_bank *bank, uint16_t *pnum) -{ - return target_read_u16(bank->target, EFM32_MSC_DI_PART_NUM, pnum); -} - -static int efm32x_get_part_family(struct flash_bank *bank, uint8_t *pfamily) -{ - return target_read_u8(bank->target, EFM32_MSC_DI_PART_FAMILY, pfamily); -} - -static int efm32x_get_prod_rev(struct flash_bank *bank, uint8_t *prev) -{ - return target_read_u8(bank->target, EFM32_MSC_DI_PROD_REV, prev); -} - -static int efm32x_read_info(struct flash_bank *bank, - struct efm32_info *efm32_info) -{ - int ret; - uint32_t cpuid = 0; - - memset(efm32_info, 0, sizeof(struct efm32_info)); - - ret = target_read_u32(bank->target, CPUID, &cpuid); - if (ERROR_OK != ret) - return ret; - - if (((cpuid >> 4) & 0xfff) == 0xc23) { - /* Cortex-M3 device */ - } else if (((cpuid >> 4) & 0xfff) == 0xc24) { - /* Cortex-M4 device (WONDER GECKO) */ - } else if (((cpuid >> 4) & 0xfff) == 0xc60) { - /* Cortex-M0+ device */ - } else { - LOG_ERROR("Target is not Cortex-Mx Device"); - return ERROR_FAIL; - } - - ret = efm32x_get_flash_size(bank, &(efm32_info->flash_sz_kib)); - if (ERROR_OK != ret) - return ret; - - ret = efm32x_get_ram_size(bank, &(efm32_info->ram_sz_kib)); - if (ERROR_OK != ret) - return ret; - - ret = efm32x_get_part_num(bank, &(efm32_info->part_num)); - if (ERROR_OK != ret) - return ret; - - ret = efm32x_get_part_family(bank, &(efm32_info->part_family)); - if (ERROR_OK != ret) - return ret; - - ret = efm32x_get_prod_rev(bank, &(efm32_info->prod_rev)); - if (ERROR_OK != ret) - return ret; - - if (EFM_FAMILY_ID_GECKO == efm32_info->part_family || - EFM_FAMILY_ID_TINY_GECKO == efm32_info->part_family) - efm32_info->page_size = 512; - else if (EFM_FAMILY_ID_ZERO_GECKO == efm32_info->part_family || - EFM_FAMILY_ID_HAPPY_GECKO == efm32_info->part_family) - efm32_info->page_size = 1024; - else if (EFM_FAMILY_ID_GIANT_GECKO == efm32_info->part_family || - EFM_FAMILY_ID_LEOPARD_GECKO == efm32_info->part_family) { - if (efm32_info->prod_rev >= 18) { - uint8_t pg_size = 0; - ret = target_read_u8(bank->target, EFM32_MSC_DI_PAGE_SIZE, - &pg_size); - if (ERROR_OK != ret) - return ret; - - efm32_info->page_size = (1 << ((pg_size+10) & 0xff)); - } else { - /* EFM32 GG/LG errata: MEM_INFO_PAGE_SIZE is invalid - for MCUs with PROD_REV < 18 */ - if (efm32_info->flash_sz_kib < 512) - efm32_info->page_size = 2048; - else - efm32_info->page_size = 4096; - } - - if ((2048 != efm32_info->page_size) && - (4096 != efm32_info->page_size)) { - LOG_ERROR("Invalid page size %u", efm32_info->page_size); - return ERROR_FAIL; - } - } else if (EFM_FAMILY_ID_WONDER_GECKO == efm32_info->part_family || - EZR_FAMILY_ID_WONDER_GECKO == efm32_info->part_family || - EZR_FAMILY_ID_LEOPARD_GECKO == efm32_info->part_family) { - uint8_t pg_size = 0; - ret = target_read_u8(bank->target, EFM32_MSC_DI_PAGE_SIZE, - &pg_size); - if (ERROR_OK != ret) - return ret; - - efm32_info->page_size = (1 << ((pg_size+10) & 0xff)); - if (2048 != efm32_info->page_size) { - LOG_ERROR("Invalid page size %u", efm32_info->page_size); - return ERROR_FAIL; - } - } else { - LOG_ERROR("Unknown MCU family %d", efm32_info->part_family); - return ERROR_FAIL; - } - - return ERROR_OK; -} - -/* - * Helper to create a human friendly string describing a part - */ -static int efm32x_decode_info(struct efm32_info *info, char *buf, int buf_size) -{ - int printed = 0; - - switch (info->part_family) { - case EZR_FAMILY_ID_WONDER_GECKO: - case EZR_FAMILY_ID_LEOPARD_GECKO: - printed = snprintf(buf, buf_size, "EZR32 "); - break; - default: - printed = snprintf(buf, buf_size, "EFM32 "); - } - - buf += printed; - buf_size -= printed; - - if (0 >= buf_size) - return ERROR_BUF_TOO_SMALL; - - switch (info->part_family) { - case EFM_FAMILY_ID_GECKO: - printed = snprintf(buf, buf_size, "Gecko"); - break; - case EFM_FAMILY_ID_GIANT_GECKO: - printed = snprintf(buf, buf_size, "Giant Gecko"); - break; - case EFM_FAMILY_ID_TINY_GECKO: - printed = snprintf(buf, buf_size, "Tiny Gecko"); - break; - case EFM_FAMILY_ID_LEOPARD_GECKO: - case EZR_FAMILY_ID_LEOPARD_GECKO: - printed = snprintf(buf, buf_size, "Leopard Gecko"); - break; - case EFM_FAMILY_ID_WONDER_GECKO: - case EZR_FAMILY_ID_WONDER_GECKO: - printed = snprintf(buf, buf_size, "Wonder Gecko"); - break; - case EFM_FAMILY_ID_ZERO_GECKO: - printed = snprintf(buf, buf_size, "Zero Gecko"); - break; - case EFM_FAMILY_ID_HAPPY_GECKO: - printed = snprintf(buf, buf_size, "Happy Gecko"); - break; - } - - buf += printed; - buf_size -= printed; - - if (0 >= buf_size) - return ERROR_BUF_TOO_SMALL; - - printed = snprintf(buf, buf_size, " - Rev: %d", info->prod_rev); - buf += printed; - buf_size -= printed; - - if (0 >= buf_size) - return ERROR_BUF_TOO_SMALL; - - return ERROR_OK; -} - -/* flash bank efm32 0 0 - */ -FLASH_BANK_COMMAND_HANDLER(efm32x_flash_bank_command) -{ - struct efm32x_flash_bank *efm32x_info; - - if (CMD_ARGC < 6) - return ERROR_COMMAND_SYNTAX_ERROR; - - efm32x_info = malloc(sizeof(struct efm32x_flash_bank)); - - bank->driver_priv = efm32x_info; - efm32x_info->probed = 0; - memset(efm32x_info->lb_page, 0xff, LOCKBITS_PAGE_SZ); - - return ERROR_OK; -} - -/* set or reset given bits in a register */ -static int efm32x_set_reg_bits(struct flash_bank *bank, uint32_t reg, - uint32_t bitmask, int set) -{ - int ret = 0; - uint32_t reg_val = 0; - - ret = target_read_u32(bank->target, reg, ®_val); - if (ERROR_OK != ret) - return ret; - - if (set) - reg_val |= bitmask; - else - reg_val &= ~bitmask; - - return target_write_u32(bank->target, reg, reg_val); -} - -static int efm32x_set_wren(struct flash_bank *bank, int write_enable) -{ - return efm32x_set_reg_bits(bank, EFM32_MSC_WRITECTRL, - EFM32_MSC_WRITECTRL_WREN_MASK, write_enable); -} - -static int efm32x_msc_lock(struct flash_bank *bank, int lock) -{ - return target_write_u32(bank->target, EFM32_MSC_LOCK, - (lock ? 0 : EFM32_MSC_LOCK_LOCKKEY)); -} - -static int efm32x_wait_status(struct flash_bank *bank, int timeout, - uint32_t wait_mask, int wait_for_set) -{ - int ret = 0; - uint32_t status = 0; - - while (1) { - ret = target_read_u32(bank->target, EFM32_MSC_STATUS, &status); - if (ERROR_OK != ret) - break; - - LOG_DEBUG("status: 0x%" PRIx32 "", status); - - if (((status & wait_mask) == 0) && (0 == wait_for_set)) - break; - else if (((status & wait_mask) != 0) && wait_for_set) - break; - - if (timeout-- <= 0) { - LOG_ERROR("timed out waiting for MSC status"); - return ERROR_FAIL; - } - - alive_sleep(1); - } - - if (status & EFM32_MSC_STATUS_ERASEABORTED_MASK) - LOG_WARNING("page erase was aborted"); - - return ret; -} - -static int efm32x_erase_page(struct flash_bank *bank, uint32_t addr) -{ - /* this function DOES NOT set WREN; must be set already */ - /* 1. write address to ADDRB - 2. write LADDRIM - 3. check status (INVADDR, LOCKED) - 4. write ERASEPAGE - 5. wait until !STATUS_BUSY - */ - int ret = 0; - uint32_t status = 0; - - LOG_DEBUG("erasing flash page at 0x%08" PRIx32, addr); - - ret = target_write_u32(bank->target, EFM32_MSC_ADDRB, addr); - if (ERROR_OK != ret) - return ret; - - ret = efm32x_set_reg_bits(bank, EFM32_MSC_WRITECMD, - EFM32_MSC_WRITECMD_LADDRIM_MASK, 1); - if (ERROR_OK != ret) - return ret; - - ret = target_read_u32(bank->target, EFM32_MSC_STATUS, &status); - if (ERROR_OK != ret) - return ret; - - LOG_DEBUG("status 0x%" PRIx32, status); - - if (status & EFM32_MSC_STATUS_LOCKED_MASK) { - LOG_ERROR("Page is locked"); - return ERROR_FAIL; - } else if (status & EFM32_MSC_STATUS_INVADDR_MASK) { - LOG_ERROR("Invalid address 0x%" PRIx32, addr); - return ERROR_FAIL; - } - - ret = efm32x_set_reg_bits(bank, EFM32_MSC_WRITECMD, - EFM32_MSC_WRITECMD_ERASEPAGE_MASK, 1); - if (ERROR_OK != ret) - return ret; - - return efm32x_wait_status(bank, EFM32_FLASH_ERASE_TMO, - EFM32_MSC_STATUS_BUSY_MASK, 0); -} - -static int efm32x_erase(struct flash_bank *bank, int first, int last) -{ - struct target *target = bank->target; - int i = 0; - int ret = 0; - - if (TARGET_HALTED != target->state) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - efm32x_msc_lock(bank, 0); - ret = efm32x_set_wren(bank, 1); - if (ERROR_OK != ret) { - LOG_ERROR("Failed to enable MSC write"); - return ret; - } - - for (i = first; i <= last; i++) { - ret = efm32x_erase_page(bank, bank->sectors[i].offset); - if (ERROR_OK != ret) - LOG_ERROR("Failed to erase page %d", i); - } - - ret = efm32x_set_wren(bank, 0); - efm32x_msc_lock(bank, 1); - - return ret; -} - -static int efm32x_read_lock_data(struct flash_bank *bank) -{ - struct efm32x_flash_bank *efm32x_info = bank->driver_priv; - struct target *target = bank->target; - int i = 0; - int data_size = 0; - uint32_t *ptr = NULL; - int ret = 0; - - assert(!(bank->num_sectors & 0x1f)); - - data_size = bank->num_sectors / 8; /* number of data bytes */ - data_size /= 4; /* ...and data dwords */ - - ptr = efm32x_info->lb_page; - - for (i = 0; i < data_size; i++, ptr++) { - ret = target_read_u32(target, EFM32_MSC_LOCK_BITS+i*4, ptr); - if (ERROR_OK != ret) { - LOG_ERROR("Failed to read PLW %d", i); - return ret; - } - } - - /* also, read ULW, DLW and MLW */ - - /* ULW, word 126 */ - ptr = efm32x_info->lb_page + 126; - ret = target_read_u32(target, EFM32_MSC_LOCK_BITS+126*4, ptr); - if (ERROR_OK != ret) { - LOG_ERROR("Failed to read ULW"); - return ret; - } - - /* DLW, word 127 */ - ptr = efm32x_info->lb_page + 127; - ret = target_read_u32(target, EFM32_MSC_LOCK_BITS+127*4, ptr); - if (ERROR_OK != ret) { - LOG_ERROR("Failed to read DLW"); - return ret; - } - - /* MLW, word 125, present in GG and LG */ - ptr = efm32x_info->lb_page + 125; - ret = target_read_u32(target, EFM32_MSC_LOCK_BITS+125*4, ptr); - if (ERROR_OK != ret) { - LOG_ERROR("Failed to read MLW"); - return ret; - } - - return ERROR_OK; -} - -static int efm32x_write_lock_data(struct flash_bank *bank) -{ - struct efm32x_flash_bank *efm32x_info = bank->driver_priv; - int ret = 0; - - ret = efm32x_erase_page(bank, EFM32_MSC_LOCK_BITS); - if (ERROR_OK != ret) { - LOG_ERROR("Failed to erase LB page"); - return ret; - } - - return efm32x_write(bank, (uint8_t *)efm32x_info->lb_page, EFM32_MSC_LOCK_BITS, - LOCKBITS_PAGE_SZ); -} - -static int efm32x_get_page_lock(struct flash_bank *bank, size_t page) -{ - struct efm32x_flash_bank *efm32x_info = bank->driver_priv; - uint32_t dw = efm32x_info->lb_page[page >> 5]; - uint32_t mask = 0; - - mask = 1 << (page & 0x1f); - - return (dw & mask) ? 0 : 1; -} - -static int efm32x_set_page_lock(struct flash_bank *bank, size_t page, int set) -{ - struct efm32x_flash_bank *efm32x_info = bank->driver_priv; - uint32_t *dw = &efm32x_info->lb_page[page >> 5]; - uint32_t mask = 0; - - mask = 1 << (page & 0x1f); - - if (!set) - *dw |= mask; - else - *dw &= ~mask; - - return ERROR_OK; -} - -static int efm32x_protect(struct flash_bank *bank, int set, int first, int last) -{ - struct target *target = bank->target; - int i = 0; - int ret = 0; - - if (!set) { - LOG_ERROR("Erase device data to reset page locks"); - return ERROR_FAIL; - } - - if (target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - for (i = first; i <= last; i++) { - ret = efm32x_set_page_lock(bank, i, set); - if (ERROR_OK != ret) { - LOG_ERROR("Failed to set lock on page %d", i); - return ret; - } - } - - ret = efm32x_write_lock_data(bank); - if (ERROR_OK != ret) { - LOG_ERROR("Failed to write LB page"); - return ret; - } - - return ERROR_OK; -} - -static int efm32x_write_block(struct flash_bank *bank, const uint8_t *buf, - uint32_t offset, uint32_t count) -{ - struct target *target = bank->target; - uint32_t buffer_size = 16384; - struct working_area *write_algorithm; - struct working_area *source; - uint32_t address = bank->base + offset; - struct reg_param reg_params[5]; - struct armv7m_algorithm armv7m_info; - int ret = ERROR_OK; - - /* see contrib/loaders/flash/efm32.S for src */ - static const uint8_t efm32x_flash_write_code[] = { - /* #define EFM32_MSC_WRITECTRL_OFFSET 0x008 */ - /* #define EFM32_MSC_WRITECMD_OFFSET 0x00c */ - /* #define EFM32_MSC_ADDRB_OFFSET 0x010 */ - /* #define EFM32_MSC_WDATA_OFFSET 0x018 */ - /* #define EFM32_MSC_STATUS_OFFSET 0x01c */ - /* #define EFM32_MSC_LOCK_OFFSET 0x03c */ - - 0x15, 0x4e, /* ldr r6, =#0x1b71 */ - 0xc6, 0x63, /* str r6, [r0, #EFM32_MSC_LOCK_OFFSET] */ - 0x01, 0x26, /* movs r6, #1 */ - 0x86, 0x60, /* str r6, [r0, #EFM32_MSC_WRITECTRL_OFFSET] */ - - /* wait_fifo: */ - 0x16, 0x68, /* ldr r6, [r2, #0] */ - 0x00, 0x2e, /* cmp r6, #0 */ - 0x22, 0xd0, /* beq exit */ - 0x55, 0x68, /* ldr r5, [r2, #4] */ - 0xb5, 0x42, /* cmp r5, r6 */ - 0xf9, 0xd0, /* beq wait_fifo */ - - 0x04, 0x61, /* str r4, [r0, #EFM32_MSC_ADDRB_OFFSET] */ - 0x01, 0x26, /* movs r6, #1 */ - 0xc6, 0x60, /* str r6, [r0, #EFM32_MSC_WRITECMD_OFFSET] */ - 0xc6, 0x69, /* ldr r6, [r0, #EFM32_MSC_STATUS_OFFSET] */ - 0x06, 0x27, /* movs r7, #6 */ - 0x3e, 0x42, /* tst r6, r7 */ - 0x16, 0xd1, /* bne error */ - - /* wait_wdataready: */ - 0xc6, 0x69, /* ldr r6, [r0, #EFM32_MSC_STATUS_OFFSET] */ - 0x08, 0x27, /* movs r7, #8 */ - 0x3e, 0x42, /* tst r6, r7 */ - 0xfb, 0xd0, /* beq wait_wdataready */ - - 0x2e, 0x68, /* ldr r6, [r5] */ - 0x86, 0x61, /* str r6, [r0, #EFM32_MSC_WDATA_OFFSET] */ - 0x08, 0x26, /* movs r6, #8 */ - 0xc6, 0x60, /* str r6, [r0, #EFM32_MSC_WRITECMD_OFFSET] */ - - 0x04, 0x35, /* adds r5, #4 */ - 0x04, 0x34, /* adds r4, #4 */ - - /* busy: */ - 0xc6, 0x69, /* ldr r6, [r0, #EFM32_MSC_STATUS_OFFSET] */ - 0x01, 0x27, /* movs r7, #1 */ - 0x3e, 0x42, /* tst r6, r7 */ - 0xfb, 0xd1, /* bne busy */ - - 0x9d, 0x42, /* cmp r5, r3 */ - 0x01, 0xd3, /* bcc no_wrap */ - 0x15, 0x46, /* mov r5, r2 */ - 0x08, 0x35, /* adds r5, #8 */ - - /* no_wrap: */ - 0x55, 0x60, /* str r5, [r2, #4] */ - 0x01, 0x39, /* subs r1, r1, #1 */ - 0x00, 0x29, /* cmp r1, #0 */ - 0x02, 0xd0, /* beq exit */ - 0xdb, 0xe7, /* b wait_fifo */ - - /* error: */ - 0x00, 0x20, /* movs r0, #0 */ - 0x50, 0x60, /* str r0, [r2, #4] */ - - /* exit: */ - 0x30, 0x46, /* mov r0, r6 */ - 0x00, 0xbe, /* bkpt #0 */ - - /* LOCKKEY */ - 0x71, 0x1b, 0x00, 0x00 - }; - - /* flash write code */ - if (target_alloc_working_area(target, sizeof(efm32x_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; - } - - ret = target_write_buffer(target, write_algorithm->address, - sizeof(efm32x_flash_write_code), efm32x_flash_write_code); - if (ret != ERROR_OK) - return ret; - - /* memory buffer */ - while (target_alloc_working_area_try(target, buffer_size, &source) != ERROR_OK) { - buffer_size /= 2; - buffer_size &= ~3UL; /* Make sure it's 4 byte aligned */ - if (buffer_size <= 256) { - /* we already allocated the writing code, but failed to get a - * buffer, free the algorithm */ - target_free_working_area(target, write_algorithm); - - 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) */ - init_reg_param(®_params[2], "r2", 32, PARAM_OUT); /* buffer start */ - init_reg_param(®_params[3], "r3", 32, PARAM_OUT); /* buffer end */ - init_reg_param(®_params[4], "r4", 32, PARAM_IN_OUT); /* target address */ - - buf_set_u32(reg_params[0].value, 0, 32, EFM32_MSC_REGBASE); - buf_set_u32(reg_params[1].value, 0, 32, count); - 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, address); - - armv7m_info.common_magic = ARMV7M_COMMON_MAGIC; - armv7m_info.core_mode = ARM_MODE_THREAD; - - ret = target_run_flash_async_algorithm(target, buf, count, 4, - 0, NULL, - 5, reg_params, - source->address, source->size, - write_algorithm->address, 0, - &armv7m_info); - - if (ret == ERROR_FLASH_OPERATION_FAILED) { - LOG_ERROR("flash write failed at address 0x%"PRIx32, - buf_get_u32(reg_params[4].value, 0, 32)); - - if (buf_get_u32(reg_params[0].value, 0, 32) & - EFM32_MSC_STATUS_LOCKED_MASK) { - LOG_ERROR("flash memory write protected"); - } - - if (buf_get_u32(reg_params[0].value, 0, 32) & - EFM32_MSC_STATUS_INVADDR_MASK) { - LOG_ERROR("invalid flash memory write address"); - } - } - - target_free_working_area(target, source); - target_free_working_area(target, write_algorithm); - - 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 ret; -} - -static int efm32x_write_word(struct flash_bank *bank, uint32_t addr, - uint32_t val) -{ - /* this function DOES NOT set WREN; must be set already */ - /* 1. write address to ADDRB - 2. write LADDRIM - 3. check status (INVADDR, LOCKED) - 4. wait for WDATAREADY - 5. write data to WDATA - 6. write WRITECMD_WRITEONCE to WRITECMD - 7. wait until !STATUS_BUSY - */ - - /* FIXME: EFM32G ref states (7.3.2) that writes should be - * performed twice per dword */ - - int ret = 0; - uint32_t status = 0; - - /* if not called, GDB errors will be reported during large writes */ - keep_alive(); - - ret = target_write_u32(bank->target, EFM32_MSC_ADDRB, addr); - if (ERROR_OK != ret) - return ret; - - ret = efm32x_set_reg_bits(bank, EFM32_MSC_WRITECMD, - EFM32_MSC_WRITECMD_LADDRIM_MASK, 1); - if (ERROR_OK != ret) - return ret; - - ret = target_read_u32(bank->target, EFM32_MSC_STATUS, &status); - if (ERROR_OK != ret) - return ret; - - LOG_DEBUG("status 0x%" PRIx32, status); - - if (status & EFM32_MSC_STATUS_LOCKED_MASK) { - LOG_ERROR("Page is locked"); - return ERROR_FAIL; - } else if (status & EFM32_MSC_STATUS_INVADDR_MASK) { - LOG_ERROR("Invalid address 0x%" PRIx32, addr); - return ERROR_FAIL; - } - - ret = efm32x_wait_status(bank, EFM32_FLASH_WDATAREADY_TMO, - EFM32_MSC_STATUS_WDATAREADY_MASK, 1); - if (ERROR_OK != ret) { - LOG_ERROR("Wait for WDATAREADY failed"); - return ret; - } - - ret = target_write_u32(bank->target, EFM32_MSC_WDATA, val); - if (ERROR_OK != ret) { - LOG_ERROR("WDATA write failed"); - return ret; - } - - ret = target_write_u32(bank->target, EFM32_MSC_WRITECMD, - EFM32_MSC_WRITECMD_WRITEONCE_MASK); - if (ERROR_OK != ret) { - LOG_ERROR("WRITECMD write failed"); - return ret; - } - - ret = efm32x_wait_status(bank, EFM32_FLASH_WRITE_TMO, - EFM32_MSC_STATUS_BUSY_MASK, 0); - if (ERROR_OK != ret) { - LOG_ERROR("Wait for BUSY failed"); - return ret; - } - - return ERROR_OK; -} - -static int efm32x_write(struct flash_bank *bank, const uint8_t *buffer, - uint32_t offset, uint32_t count) -{ - struct target *target = bank->target; - uint8_t *new_buffer = NULL; - - if (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) { - uint32_t old_count = count; - count = (old_count | 3) + 1; - new_buffer = malloc(count); - if (new_buffer == NULL) { - LOG_ERROR("odd number of bytes to write and no memory " - "for padding buffer"); - return ERROR_FAIL; - } - LOG_INFO("odd number of bytes to write (%" PRIu32 "), extending to %" PRIu32 " " - "and padding with 0xff", old_count, count); - memset(new_buffer, 0xff, count); - buffer = memcpy(new_buffer, buffer, old_count); - } - - uint32_t words_remaining = count / 4; - int retval, retval2; - - /* unlock flash registers */ - efm32x_msc_lock(bank, 0); - retval = efm32x_set_wren(bank, 1); - if (retval != ERROR_OK) - goto cleanup; - - /* try using a block write */ - retval = efm32x_write_block(bank, buffer, offset, words_remaining); - - if (retval == 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"); - - while (words_remaining > 0) { - uint32_t value; - memcpy(&value, buffer, sizeof(uint32_t)); - - retval = efm32x_write_word(bank, offset, value); - if (retval != ERROR_OK) - goto reset_pg_and_lock; - - words_remaining--; - buffer += 4; - offset += 4; - } - } - -reset_pg_and_lock: - retval2 = efm32x_set_wren(bank, 0); - efm32x_msc_lock(bank, 1); - if (retval == ERROR_OK) - retval = retval2; - -cleanup: - if (new_buffer) - free(new_buffer); - - return retval; -} - -static int efm32x_probe(struct flash_bank *bank) -{ - struct efm32x_flash_bank *efm32x_info = bank->driver_priv; - struct efm32_info efm32_mcu_info; - int ret; - int i; - uint32_t base_address = 0x00000000; - char buf[256]; - - efm32x_info->probed = 0; - memset(efm32x_info->lb_page, 0xff, LOCKBITS_PAGE_SZ); - - ret = efm32x_read_info(bank, &efm32_mcu_info); - if (ERROR_OK != ret) - return ret; - - ret = efm32x_decode_info(&efm32_mcu_info, buf, sizeof(buf)); - if (ERROR_OK != ret) - return ret; - - LOG_INFO("detected part: %s", buf); - LOG_INFO("flash size = %dkbytes", efm32_mcu_info.flash_sz_kib); - LOG_INFO("flash page size = %dbytes", efm32_mcu_info.page_size); - - assert(0 != efm32_mcu_info.page_size); - - int num_pages = efm32_mcu_info.flash_sz_kib * 1024 / - efm32_mcu_info.page_size; - - assert(num_pages > 0); - - if (bank->sectors) { - free(bank->sectors); - bank->sectors = NULL; - } - - bank->base = base_address; - bank->size = (num_pages * efm32_mcu_info.page_size); - bank->num_sectors = num_pages; - - ret = efm32x_read_lock_data(bank); - if (ERROR_OK != ret) { - LOG_ERROR("Failed to read LB data"); - return ret; - } - - bank->sectors = malloc(sizeof(struct flash_sector) * num_pages); - - for (i = 0; i < num_pages; i++) { - bank->sectors[i].offset = i * efm32_mcu_info.page_size; - bank->sectors[i].size = efm32_mcu_info.page_size; - bank->sectors[i].is_erased = -1; - bank->sectors[i].is_protected = 1; - } - - efm32x_info->probed = 1; - - return ERROR_OK; -} - -static int efm32x_auto_probe(struct flash_bank *bank) -{ - struct efm32x_flash_bank *efm32x_info = bank->driver_priv; - if (efm32x_info->probed) - return ERROR_OK; - return efm32x_probe(bank); -} - -static int efm32x_protect_check(struct flash_bank *bank) -{ - struct target *target = bank->target; - int ret = 0; - int i = 0; - - if (target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - ret = efm32x_read_lock_data(bank); - if (ERROR_OK != ret) { - LOG_ERROR("Failed to read LB data"); - return ret; - } - - assert(NULL != bank->sectors); - - for (i = 0; i < bank->num_sectors; i++) - bank->sectors[i].is_protected = efm32x_get_page_lock(bank, i); - - return ERROR_OK; -} - -static int get_efm32x_info(struct flash_bank *bank, char *buf, int buf_size) -{ - struct efm32_info info; - int ret = 0; - - ret = efm32x_read_info(bank, &info); - if (ERROR_OK != ret) { - LOG_ERROR("Failed to read EFM32 info"); - return ret; - } - - 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 -}; - -static const struct command_registration efm32x_command_handlers[] = { - { - .name = "efm32", - .mode = COMMAND_ANY, - .help = "efm32 flash command group", - .usage = "", - .chain = efm32x_exec_command_handlers, - }, - COMMAND_REGISTRATION_DONE -}; - -struct flash_driver efm32_flash = { - .name = "efm32", - .commands = efm32x_command_handlers, - .flash_bank_command = efm32x_flash_bank_command, - .erase = efm32x_erase, - .protect = efm32x_protect, - .write = efm32x_write, - .read = default_flash_read, - .probe = efm32x_probe, - .auto_probe = efm32x_auto_probe, - .erase_check = default_flash_blank_check, - .protect_check = efm32x_protect_check, - .info = get_efm32x_info, -}; diff --git a/src/flash/nor/em357.c b/src/flash/nor/em357.c deleted file mode 100644 index 150156269..000000000 --- a/src/flash/nor/em357.c +++ /dev/null @@ -1,939 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * Copyright (C) 2008 by Spencer Oliver * - * spen@spen-soft.co.uk * - * - * Copyright (C) 2011 by Erik Botö - * erik.boto@pelagicore.com - * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "imp.h" -#include -#include -#include - -/* em357 register locations */ - -#define EM357_FLASH_ACR 0x40008000 -#define EM357_FLASH_KEYR 0x40008004 -#define EM357_FLASH_OPTKEYR 0x40008008 -#define EM357_FLASH_SR 0x4000800C -#define EM357_FLASH_CR 0x40008010 -#define EM357_FLASH_AR 0x40008014 -#define EM357_FLASH_OBR 0x4000801C -#define EM357_FLASH_WRPR 0x40008020 - -#define EM357_FPEC_CLK 0x4000402c -/* option byte location */ - -#define EM357_OB_RDP 0x08040800 -#define EM357_OB_WRP0 0x08040808 -#define EM357_OB_WRP1 0x0804080A -#define EM357_OB_WRP2 0x0804080C - -/* FLASH_CR register bits */ - -#define FLASH_PG (1 << 0) -#define FLASH_PER (1 << 1) -#define FLASH_MER (1 << 2) -#define FLASH_OPTPG (1 << 4) -#define FLASH_OPTER (1 << 5) -#define FLASH_STRT (1 << 6) -#define FLASH_LOCK (1 << 7) -#define FLASH_OPTWRE (1 << 9) - -/* FLASH_SR register bits */ - -#define FLASH_BSY (1 << 0) -#define FLASH_PGERR (1 << 2) -#define FLASH_WRPRTERR (1 << 4) -#define FLASH_EOP (1 << 5) - -/* EM357_FLASH_OBR bit definitions (reading) */ - -#define OPT_ERROR 0 -#define OPT_READOUT 1 - -/* register unlock keys */ - -#define KEY1 0x45670123 -#define KEY2 0xCDEF89AB - -struct em357_options { - uint16_t RDP; - uint16_t user_options; - uint16_t protection[3]; -}; - -struct em357_flash_bank { - struct em357_options option_bytes; - int ppage_size; - int probed; -}; - -static int em357_mass_erase(struct flash_bank *bank); - -/* flash bank em357 0 0 - */ -FLASH_BANK_COMMAND_HANDLER(em357_flash_bank_command) -{ - struct em357_flash_bank *em357_info; - - if (CMD_ARGC < 6) - return ERROR_COMMAND_SYNTAX_ERROR; - - em357_info = malloc(sizeof(struct em357_flash_bank)); - bank->driver_priv = em357_info; - - em357_info->probed = 0; - - return ERROR_OK; -} - -static inline int em357_get_flash_status(struct flash_bank *bank, uint32_t *status) -{ - struct target *target = bank->target; - return target_read_u32(target, EM357_FLASH_SR, status); -} - -static int em357_wait_status_busy(struct flash_bank *bank, int timeout) -{ - struct target *target = bank->target; - uint32_t status; - int retval = ERROR_OK; - - /* wait for busy to clear */ - for (;; ) { - retval = em357_get_flash_status(bank, &status); - if (retval != ERROR_OK) - return retval; - LOG_DEBUG("status: 0x%" PRIx32 "", status); - if ((status & FLASH_BSY) == 0) - break; - if (timeout-- <= 0) { - LOG_ERROR("timed out waiting for flash"); - return ERROR_FAIL; - } - alive_sleep(1); - } - - if (status & FLASH_WRPRTERR) { - LOG_ERROR("em357 device protected"); - retval = ERROR_FAIL; - } - - if (status & FLASH_PGERR) { - LOG_ERROR("em357 device programming failed"); - retval = ERROR_FAIL; - } - - /* Clear but report errors */ - if (status & (FLASH_WRPRTERR | FLASH_PGERR)) { - /* If this operation fails, we ignore it and report the original - * retval - */ - target_write_u32(target, EM357_FLASH_SR, FLASH_WRPRTERR | FLASH_PGERR); - } - return retval; -} - -static int em357_read_options(struct flash_bank *bank) -{ - uint32_t optiondata; - struct em357_flash_bank *em357_info = NULL; - struct target *target = bank->target; - - em357_info = bank->driver_priv; - - /* read current option bytes */ - int retval = target_read_u32(target, EM357_FLASH_OBR, &optiondata); - if (retval != ERROR_OK) - return retval; - - em357_info->option_bytes.user_options = (uint16_t)0xFFFC | ((optiondata >> 2) & 0x03); - em357_info->option_bytes.RDP = (optiondata & (1 << OPT_READOUT)) ? 0xFFFF : 0x5AA5; - - if (optiondata & (1 << OPT_READOUT)) - LOG_INFO("Device Security Bit Set"); - - /* each bit refers to a 4bank protection */ - retval = target_read_u32(target, EM357_FLASH_WRPR, &optiondata); - if (retval != ERROR_OK) - return retval; - - em357_info->option_bytes.protection[0] = (uint16_t)optiondata; - em357_info->option_bytes.protection[1] = (uint16_t)(optiondata >> 8); - em357_info->option_bytes.protection[2] = (uint16_t)(optiondata >> 16); - - return ERROR_OK; -} - -static int em357_erase_options(struct flash_bank *bank) -{ - struct em357_flash_bank *em357_info = NULL; - struct target *target = bank->target; - - em357_info = bank->driver_priv; - - /* read current options */ - em357_read_options(bank); - - /* unlock flash registers */ - int retval = target_write_u32(target, EM357_FLASH_KEYR, KEY1); - if (retval != ERROR_OK) - return retval; - - retval = target_write_u32(target, EM357_FLASH_KEYR, KEY2); - if (retval != ERROR_OK) - return retval; - - /* unlock option flash registers */ - retval = target_write_u32(target, EM357_FLASH_OPTKEYR, KEY1); - if (retval != ERROR_OK) - return retval; - retval = target_write_u32(target, EM357_FLASH_OPTKEYR, KEY2); - if (retval != ERROR_OK) - return retval; - - /* erase option bytes */ - retval = target_write_u32(target, EM357_FLASH_CR, FLASH_OPTER | FLASH_OPTWRE); - if (retval != ERROR_OK) - return retval; - retval = target_write_u32(target, EM357_FLASH_CR, FLASH_OPTER | FLASH_STRT | FLASH_OPTWRE); - if (retval != ERROR_OK) - return retval; - - retval = em357_wait_status_busy(bank, 10); - if (retval != ERROR_OK) - return retval; - - /* clear readout protection and complementary option bytes - * this will also force a device unlock if set */ - em357_info->option_bytes.RDP = 0x5AA5; - - return ERROR_OK; -} - -static int em357_write_options(struct flash_bank *bank) -{ - struct em357_flash_bank *em357_info = NULL; - struct target *target = bank->target; - - em357_info = bank->driver_priv; - - /* unlock flash registers */ - int retval = target_write_u32(target, EM357_FLASH_KEYR, KEY1); - if (retval != ERROR_OK) - return retval; - retval = target_write_u32(target, EM357_FLASH_KEYR, KEY2); - if (retval != ERROR_OK) - return retval; - - /* unlock option flash registers */ - retval = target_write_u32(target, EM357_FLASH_OPTKEYR, KEY1); - if (retval != ERROR_OK) - return retval; - retval = target_write_u32(target, EM357_FLASH_OPTKEYR, KEY2); - if (retval != ERROR_OK) - return retval; - - /* program option bytes */ - retval = target_write_u32(target, EM357_FLASH_CR, FLASH_OPTPG | FLASH_OPTWRE); - if (retval != ERROR_OK) - return retval; - - retval = em357_wait_status_busy(bank, 10); - if (retval != ERROR_OK) - return retval; - - /* write protection byte 1 */ - retval = target_write_u16(target, EM357_OB_WRP0, em357_info->option_bytes.protection[0]); - if (retval != ERROR_OK) - return retval; - - retval = em357_wait_status_busy(bank, 10); - if (retval != ERROR_OK) - return retval; - - /* write protection byte 2 */ - retval = target_write_u16(target, EM357_OB_WRP1, em357_info->option_bytes.protection[1]); - if (retval != ERROR_OK) - return retval; - - retval = em357_wait_status_busy(bank, 10); - if (retval != ERROR_OK) - return retval; - - /* write protection byte 3 */ - retval = target_write_u16(target, EM357_OB_WRP2, em357_info->option_bytes.protection[2]); - if (retval != ERROR_OK) - return retval; - - retval = em357_wait_status_busy(bank, 10); - if (retval != ERROR_OK) - return retval; - - /* write readout protection bit */ - retval = target_write_u16(target, EM357_OB_RDP, em357_info->option_bytes.RDP); - if (retval != ERROR_OK) - return retval; - - retval = em357_wait_status_busy(bank, 10); - if (retval != ERROR_OK) - return retval; - - retval = target_write_u32(target, EM357_FLASH_CR, FLASH_LOCK); - if (retval != ERROR_OK) - return retval; - - return ERROR_OK; -} - -static int em357_protect_check(struct flash_bank *bank) -{ - struct target *target = bank->target; - struct em357_flash_bank *em357_info = bank->driver_priv; - - uint32_t protection; - int i, s; - int num_bits; - int set; - - if (target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - /* each bit refers to a 4bank protection (bit 0-23) */ - int retval = target_read_u32(target, EM357_FLASH_WRPR, &protection); - if (retval != ERROR_OK) - return retval; - - /* each protection bit is for 4 * 2K pages */ - num_bits = (bank->num_sectors / em357_info->ppage_size); - - for (i = 0; i < num_bits; i++) { - set = 1; - if (protection & (1 << i)) - set = 0; - - for (s = 0; s < em357_info->ppage_size; s++) - bank->sectors[(i * em357_info->ppage_size) + s].is_protected = set; - } - - return ERROR_OK; -} - -static int em357_erase(struct flash_bank *bank, int first, int last) -{ - struct target *target = bank->target; - int i; - - if (bank->target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - if ((first == 0) && (last == (bank->num_sectors - 1))) - return em357_mass_erase(bank); - - /* Enable FPEC clock */ - target_write_u32(target, EM357_FPEC_CLK, 0x00000001); - - /* unlock flash registers */ - int retval = target_write_u32(target, EM357_FLASH_KEYR, KEY1); - if (retval != ERROR_OK) - return retval; - retval = target_write_u32(target, EM357_FLASH_KEYR, KEY2); - if (retval != ERROR_OK) - return retval; - - for (i = first; i <= last; i++) { - retval = target_write_u32(target, EM357_FLASH_CR, FLASH_PER); - if (retval != ERROR_OK) - return retval; - retval = target_write_u32(target, EM357_FLASH_AR, - bank->base + bank->sectors[i].offset); - if (retval != ERROR_OK) - return retval; - retval = target_write_u32(target, EM357_FLASH_CR, FLASH_PER | FLASH_STRT); - if (retval != ERROR_OK) - return retval; - - retval = em357_wait_status_busy(bank, 100); - if (retval != ERROR_OK) - return retval; - - bank->sectors[i].is_erased = 1; - } - - retval = target_write_u32(target, EM357_FLASH_CR, FLASH_LOCK); - if (retval != ERROR_OK) - return retval; - - return ERROR_OK; -} - -static int em357_protect(struct flash_bank *bank, int set, int first, int last) -{ - struct em357_flash_bank *em357_info = NULL; - struct target *target = bank->target; - uint16_t prot_reg[4] = {0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF}; - int i, reg, bit; - int status; - uint32_t protection; - - em357_info = bank->driver_priv; - - if (target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - if ((first % em357_info->ppage_size) != 0) { - LOG_WARNING("aligned start protect sector to a %d sector boundary", - em357_info->ppage_size); - first = first - (first % em357_info->ppage_size); - } - if (((last + 1) % em357_info->ppage_size) != 0) { - LOG_WARNING("aligned end protect sector to a %d sector boundary", - em357_info->ppage_size); - last++; - last = last - (last % em357_info->ppage_size); - last--; - } - - /* each bit refers to a 4bank protection */ - int retval = target_read_u32(target, EM357_FLASH_WRPR, &protection); - if (retval != ERROR_OK) - return retval; - - prot_reg[0] = (uint16_t)protection; - prot_reg[1] = (uint16_t)(protection >> 8); - prot_reg[2] = (uint16_t)(protection >> 16); - - for (i = first; i <= last; i++) { - reg = (i / em357_info->ppage_size) / 8; - bit = (i / em357_info->ppage_size) - (reg * 8); - - LOG_WARNING("reg, bit: %d, %d", reg, bit); - if (set) - prot_reg[reg] &= ~(1 << bit); - else - prot_reg[reg] |= (1 << bit); - } - - status = em357_erase_options(bank); - if (retval != ERROR_OK) - return status; - - em357_info->option_bytes.protection[0] = prot_reg[0]; - em357_info->option_bytes.protection[1] = prot_reg[1]; - em357_info->option_bytes.protection[2] = prot_reg[2]; - - return em357_write_options(bank); -} - -static int em357_write_block(struct flash_bank *bank, const uint8_t *buffer, - uint32_t offset, uint32_t count) -{ - struct target *target = bank->target; - uint32_t buffer_size = 16384; - struct working_area *write_algorithm; - struct working_area *source; - uint32_t address = bank->base + offset; - struct reg_param reg_params[4]; - struct armv7m_algorithm armv7m_info; - int retval = ERROR_OK; - - /* see contib/loaders/flash/stm32x.s for src, the same is used here except for - * a modified *_FLASH_BASE */ - - static const uint8_t em357_flash_write_code[] = { - /* #define EM357_FLASH_CR_OFFSET 0x10 - * #define EM357_FLASH_SR_OFFSET 0x0C - * write: */ - 0x08, 0x4c, /* ldr r4, EM357_FLASH_BASE */ - 0x1c, 0x44, /* add r4, r3 */ - /* write_half_word: */ - 0x01, 0x23, /* movs r3, #0x01 */ - 0x23, 0x61, /* str r3, [r4, - *#EM357_FLASH_CR_OFFSET] */ - 0x30, 0xf8, 0x02, 0x3b, /* ldrh r3, [r0], #0x02 */ - 0x21, 0xf8, 0x02, 0x3b, /* strh r3, [r1], #0x02 */ - /* busy: */ - 0xe3, 0x68, /* ldr r3, [r4, - *#EM357_FLASH_SR_OFFSET] */ - 0x13, 0xf0, 0x01, 0x0f, /* tst r3, #0x01 */ - 0xfb, 0xd0, /* beq busy */ - 0x13, 0xf0, 0x14, 0x0f, /* tst r3, #0x14 */ - 0x01, 0xd1, /* bne exit */ - 0x01, 0x3a, /* subs r2, r2, #0x01 */ - 0xf0, 0xd1, /* bne write_half_word */ - /* exit: */ - 0x00, 0xbe, /* bkpt #0x00 */ - 0x00, 0x80, 0x00, 0x40, /* EM357_FLASH_BASE: .word 0x40008000 */ - }; - - /* flash write code */ - if (target_alloc_working_area(target, sizeof(em357_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(em357_flash_write_code), em357_flash_write_code); - if (retval != ERROR_OK) - return retval; - - /* memory buffer */ - while (target_alloc_working_area_try(target, buffer_size, &source) != ERROR_OK) { - buffer_size /= 2; - if (buffer_size <= 256) { - /* we already allocated the writing code, but failed to get a - * buffer, free the algorithm */ - target_free_working_area(target, write_algorithm); - - 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; - - init_reg_param(®_params[0], "r0", 32, PARAM_OUT); - init_reg_param(®_params[1], "r1", 32, PARAM_OUT); - init_reg_param(®_params[2], "r2", 32, PARAM_OUT); - init_reg_param(®_params[3], "r3", 32, PARAM_IN_OUT); - - while (count > 0) { - uint32_t thisrun_count = (count > (buffer_size / 2)) ? - (buffer_size / 2) : count; - - retval = target_write_buffer(target, source->address, thisrun_count * 2, buffer); - if (retval != ERROR_OK) - break; - - 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); - buf_set_u32(reg_params[3].value, 0, 32, 0); - - retval = target_run_algorithm(target, 0, NULL, 4, reg_params, - write_algorithm->address, 0, 10000, &armv7m_info); - if (retval != ERROR_OK) { - LOG_ERROR("error executing em357 flash write algorithm"); - break; - } - - if (buf_get_u32(reg_params[3].value, 0, 32) & FLASH_PGERR) { - LOG_ERROR("flash memory not erased before writing"); - /* Clear but report errors */ - target_write_u32(target, EM357_FLASH_SR, FLASH_PGERR); - retval = ERROR_FAIL; - break; - } - - if (buf_get_u32(reg_params[3].value, 0, 32) & FLASH_WRPRTERR) { - LOG_ERROR("flash memory write protected"); - /* Clear but report errors */ - target_write_u32(target, EM357_FLASH_SR, FLASH_WRPRTERR); - retval = ERROR_FAIL; - break; - } - - buffer += thisrun_count * 2; - address += thisrun_count * 2; - count -= thisrun_count; - } - - target_free_working_area(target, source); - target_free_working_area(target, write_algorithm); - - destroy_reg_param(®_params[0]); - destroy_reg_param(®_params[1]); - destroy_reg_param(®_params[2]); - destroy_reg_param(®_params[3]); - - return retval; -} - -static int em357_write(struct flash_bank *bank, const uint8_t *buffer, - uint32_t offset, uint32_t count) -{ - struct target *target = bank->target; - uint32_t words_remaining = (count / 2); - uint32_t bytes_remaining = (count & 0x00000001); - uint32_t address = bank->base + offset; - uint32_t bytes_written = 0; - int retval; - - if (bank->target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - if (offset & 0x1) { - LOG_WARNING("offset 0x%" PRIx32 " breaks required 2-byte alignment", offset); - return ERROR_FLASH_DST_BREAKS_ALIGNMENT; - } - - /* unlock flash registers */ - retval = target_write_u32(target, EM357_FLASH_KEYR, KEY1); - if (retval != ERROR_OK) - return retval; - retval = target_write_u32(target, EM357_FLASH_KEYR, KEY2); - if (retval != ERROR_OK) - return retval; - - target_write_u32(target, EM357_FPEC_CLK, 0x00000001); - - /* multiple half words (2-byte) to be programmed? */ - if (words_remaining > 0) { - /* try using a block write */ - retval = em357_write_block(bank, buffer, offset, words_remaining); - if (retval != ERROR_OK) { - if (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE) { - /* if block write failed (no sufficient working area), - * we use normal (slow) single dword accesses */ - LOG_WARNING( - "couldn't use block writes, falling back to single memory accesses"); - } - } else { - buffer += words_remaining * 2; - address += words_remaining * 2; - words_remaining = 0; - } - } - - if ((retval != ERROR_OK) && (retval != ERROR_TARGET_RESOURCE_NOT_AVAILABLE)) - return retval; - - while (words_remaining > 0) { - uint16_t value; - memcpy(&value, buffer + bytes_written, sizeof(uint16_t)); - - retval = target_write_u32(target, EM357_FLASH_CR, FLASH_PG); - if (retval != ERROR_OK) - return retval; - retval = target_write_u16(target, address, value); - if (retval != ERROR_OK) - return retval; - - retval = em357_wait_status_busy(bank, 5); - if (retval != ERROR_OK) - return retval; - - bytes_written += 2; - words_remaining--; - address += 2; - } - - if (bytes_remaining) { - uint16_t value = 0xffff; - memcpy(&value, buffer + bytes_written, bytes_remaining); - - retval = target_write_u32(target, EM357_FLASH_CR, FLASH_PG); - if (retval != ERROR_OK) - return retval; - retval = target_write_u16(target, address, value); - if (retval != ERROR_OK) - return retval; - - retval = em357_wait_status_busy(bank, 5); - if (retval != ERROR_OK) - return retval; - } - - return target_write_u32(target, EM357_FLASH_CR, FLASH_LOCK); -} - -static int em357_probe(struct flash_bank *bank) -{ - struct target *target = bank->target; - struct em357_flash_bank *em357_info = bank->driver_priv; - int i; - uint16_t num_pages; - int page_size; - uint32_t base_address = 0x08000000; - - em357_info->probed = 0; - - switch (bank->size) { - case 0x10000: - /* 64k -- 64 1k pages */ - num_pages = 64; - page_size = 1024; - break; - case 0x20000: - /* 128k -- 128 1k pages */ - num_pages = 128; - page_size = 1024; - break; - case 0x30000: - /* 192k -- 96 2k pages */ - num_pages = 96; - page_size = 2048; - break; - case 0x40000: - /* 256k -- 128 2k pages */ - num_pages = 128; - page_size = 2048; - break; - default: - LOG_WARNING("No size specified for em357 flash driver, assuming 192k!"); - num_pages = 96; - page_size = 2048; - break; - } - - /* Enable FPEC CLK */ - int retval = target_write_u32(target, EM357_FPEC_CLK, 0x00000001); - if (retval != ERROR_OK) - return retval; - - em357_info->ppage_size = 4; - - LOG_INFO("flash size = %dkbytes", num_pages*page_size/1024); - - if (bank->sectors) { - free(bank->sectors); - bank->sectors = NULL; - } - - bank->base = base_address; - bank->size = (num_pages * page_size); - bank->num_sectors = num_pages; - bank->sectors = malloc(sizeof(struct flash_sector) * num_pages); - - for (i = 0; i < num_pages; i++) { - bank->sectors[i].offset = i * page_size; - bank->sectors[i].size = page_size; - bank->sectors[i].is_erased = -1; - bank->sectors[i].is_protected = 1; - } - - em357_info->probed = 1; - - return ERROR_OK; -} - -static int em357_auto_probe(struct flash_bank *bank) -{ - struct em357_flash_bank *em357_info = bank->driver_priv; - if (em357_info->probed) - return ERROR_OK; - return em357_probe(bank); -} - -COMMAND_HANDLER(em357_handle_lock_command) -{ - struct target *target = NULL; - struct em357_flash_bank *em357_info = 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; - - em357_info = bank->driver_priv; - - target = bank->target; - - if (target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - if (em357_erase_options(bank) != ERROR_OK) { - command_print(CMD_CTX, "em357 failed to erase options"); - return ERROR_OK; - } - - /* set readout protection */ - em357_info->option_bytes.RDP = 0; - - if (em357_write_options(bank) != ERROR_OK) { - command_print(CMD_CTX, "em357 failed to lock device"); - return ERROR_OK; - } - - command_print(CMD_CTX, "em357 locked"); - - return ERROR_OK; -} - -COMMAND_HANDLER(em357_handle_unlock_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; - - target = bank->target; - - if (target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - if (em357_erase_options(bank) != ERROR_OK) { - command_print(CMD_CTX, "em357 failed to unlock device"); - return ERROR_OK; - } - - if (em357_write_options(bank) != ERROR_OK) { - command_print(CMD_CTX, "em357 failed to lock device"); - return ERROR_OK; - } - - command_print(CMD_CTX, "em357 unlocked.\n" - "INFO: a reset or power cycle is required " - "for the new settings to take effect."); - - return ERROR_OK; -} - -static int em357_mass_erase(struct flash_bank *bank) -{ - struct target *target = bank->target; - - if (target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - /* Make sure the flash clock is on */ - target_write_u32(target, EM357_FPEC_CLK, 0x00000001); - - /* unlock option flash registers */ - int retval = target_write_u32(target, EM357_FLASH_KEYR, KEY1); - if (retval != ERROR_OK) - return retval; - retval = target_write_u32(target, EM357_FLASH_KEYR, KEY2); - if (retval != ERROR_OK) - return retval; - - /* mass erase flash memory */ - retval = target_write_u32(target, EM357_FLASH_CR, FLASH_MER); - if (retval != ERROR_OK) - return retval; - retval = target_write_u32(target, EM357_FLASH_CR, FLASH_MER | FLASH_STRT); - if (retval != ERROR_OK) - return retval; - - retval = em357_wait_status_busy(bank, 100); - if (retval != ERROR_OK) - return retval; - - retval = target_write_u32(target, EM357_FLASH_CR, FLASH_LOCK); - if (retval != ERROR_OK) - return retval; - - return ERROR_OK; -} - -COMMAND_HANDLER(em357_handle_mass_erase_command) -{ - int i; - - 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 = em357_mass_erase(bank); - if (retval == ERROR_OK) { - /* set all sectors as erased */ - for (i = 0; i < bank->num_sectors; i++) - bank->sectors[i].is_erased = 1; - - command_print(CMD_CTX, "em357 mass erase complete"); - } else - command_print(CMD_CTX, "em357 mass erase failed"); - - return retval; -} - -static const struct command_registration em357_exec_command_handlers[] = { - { - .name = "lock", - .usage = "", - .handler = em357_handle_lock_command, - .mode = COMMAND_EXEC, - .help = "Lock entire flash device.", - }, - { - .name = "unlock", - .usage = "", - .handler = em357_handle_unlock_command, - .mode = COMMAND_EXEC, - .help = "Unlock entire protected flash device.", - }, - { - .name = "mass_erase", - .usage = "", - .handler = em357_handle_mass_erase_command, - .mode = COMMAND_EXEC, - .help = "Erase entire flash device.", - }, - COMMAND_REGISTRATION_DONE -}; - -static const struct command_registration em357_command_handlers[] = { - { - .name = "em357", - .mode = COMMAND_ANY, - .help = "em357 flash command group", - .usage = "", - .chain = em357_exec_command_handlers, - }, - COMMAND_REGISTRATION_DONE -}; - -struct flash_driver em357_flash = { - .name = "em357", - .commands = em357_command_handlers, - .flash_bank_command = em357_flash_bank_command, - .erase = em357_erase, - .protect = em357_protect, - .write = em357_write, - .read = default_flash_read, - .probe = em357_probe, - .auto_probe = em357_auto_probe, - .erase_check = default_flash_blank_check, - .protect_check = em357_protect_check, -}; diff --git a/src/flash/nor/faux.c b/src/flash/nor/faux.c deleted file mode 100644 index 203eb6fff..000000000 --- a/src/flash/nor/faux.c +++ /dev/null @@ -1,140 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2009 Øyvind Harboe * - * oyvind.harboe@zylin.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "imp.h" -#include -#include "hello.h" - -struct faux_flash_bank { - struct target *target; - uint8_t *memory; - uint32_t start_address; -}; - -static const int sectorSize = 0x10000; - - -/* flash bank faux - */ -FLASH_BANK_COMMAND_HANDLER(faux_flash_bank_command) -{ - struct faux_flash_bank *info; - - if (CMD_ARGC < 6) - return ERROR_COMMAND_SYNTAX_ERROR; - - info = malloc(sizeof(struct faux_flash_bank)); - if (info == NULL) { - LOG_ERROR("no memory for flash bank info"); - return ERROR_FAIL; - } - info->memory = malloc(bank->size); - if (info->memory == NULL) { - free(info); - LOG_ERROR("no memory for flash bank info"); - return ERROR_FAIL; - } - bank->driver_priv = info; - - /* Use 0x10000 as a fixed sector size. */ - int i = 0; - uint32_t offset = 0; - bank->num_sectors = bank->size/sectorSize; - 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 = sectorSize; - offset += bank->sectors[i].size; - bank->sectors[i].is_erased = -1; - bank->sectors[i].is_protected = 0; - } - - info->target = get_target(CMD_ARGV[5]); - if (info->target == NULL) { - LOG_ERROR("target '%s' not defined", CMD_ARGV[5]); - free(info->memory); - free(info); - return ERROR_FAIL; - } - return ERROR_OK; -} - -static int faux_erase(struct flash_bank *bank, int first, int last) -{ - struct faux_flash_bank *info = bank->driver_priv; - memset(info->memory + first*sectorSize, 0xff, sectorSize*(last-first + 1)); - return ERROR_OK; -} - -static int faux_protect(struct flash_bank *bank, int set, int first, int last) -{ - LOG_USER("set protection sector %d to %d to %s", first, last, set ? "on" : "off"); - return ERROR_OK; -} - -static int faux_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count) -{ - struct faux_flash_bank *info = bank->driver_priv; - memcpy(info->memory + offset, buffer, count); - return ERROR_OK; -} - -static int faux_protect_check(struct flash_bank *bank) -{ - return ERROR_OK; -} - -static int faux_info(struct flash_bank *bank, char *buf, int buf_size) -{ - snprintf(buf, buf_size, "faux flash driver"); - return ERROR_OK; -} - -static int faux_probe(struct flash_bank *bank) -{ - return ERROR_OK; -} - -static const struct command_registration faux_command_handlers[] = { - { - .name = "faux", - .mode = COMMAND_ANY, - .help = "faux flash command group", - .chain = hello_command_handlers, - }, - COMMAND_REGISTRATION_DONE -}; - -struct flash_driver faux_flash = { - .name = "faux", - .commands = faux_command_handlers, - .flash_bank_command = faux_flash_bank_command, - .erase = faux_erase, - .protect = faux_protect, - .write = faux_write, - .read = default_flash_read, - .probe = faux_probe, - .auto_probe = faux_probe, - .erase_check = default_flash_blank_check, - .protect_check = faux_protect_check, - .info = faux_info -}; diff --git a/src/flash/nor/fespi.c b/src/flash/nor/fespi.c deleted file mode 100644 index 55c292098..000000000 --- a/src/flash/nor/fespi.c +++ /dev/null @@ -1,1127 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2010 by Antonio Borneo * - * Modified by Megan Wachs from the original stmsmi.c * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -/* The Freedom E SPI controller is a SPI bus controller - * specifically designed for SPI Flash Memories on Freedom E platforms. - * - * Two working modes are available: - * - SW mode: the SPI is controlled by SW. Any custom commands can be sent - * on the bus. Writes are only possible in this mode. - * - HW mode: Memory content is directly - * accessible in CPU memory space. CPU can read, write and execute memory - * content. */ - -/* ATTENTION: - * To have flash memory mapped in CPU memory space, the controller - * must have "HW mode" enabled. - * 1) The command "reset init" has to initialize the controller and put - * it in HW mode (this is actually the default out of reset for Freedom E systems). - * 2) every command in this file have to return to prompt in HW mode. */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "imp.h" -#include "spi.h" -#include -#include -#include - -/* Register offsets */ - -#define FESPI_REG_SCKDIV 0x00 -#define FESPI_REG_SCKMODE 0x04 -#define FESPI_REG_CSID 0x10 -#define FESPI_REG_CSDEF 0x14 -#define FESPI_REG_CSMODE 0x18 - -#define FESPI_REG_DCSSCK 0x28 -#define FESPI_REG_DSCKCS 0x2a -#define FESPI_REG_DINTERCS 0x2c -#define FESPI_REG_DINTERXFR 0x2e - -#define FESPI_REG_FMT 0x40 -#define FESPI_REG_TXFIFO 0x48 -#define FESPI_REG_RXFIFO 0x4c -#define FESPI_REG_TXCTRL 0x50 -#define FESPI_REG_RXCTRL 0x54 - -#define FESPI_REG_FCTRL 0x60 -#define FESPI_REG_FFMT 0x64 - -#define FESPI_REG_IE 0x70 -#define FESPI_REG_IP 0x74 - -/* Fields */ - -#define FESPI_SCK_POL 0x1 -#define FESPI_SCK_PHA 0x2 - -#define FESPI_FMT_PROTO(x) ((x) & 0x3) -#define FESPI_FMT_ENDIAN(x) (((x) & 0x1) << 2) -#define FESPI_FMT_DIR(x) (((x) & 0x1) << 3) -#define FESPI_FMT_LEN(x) (((x) & 0xf) << 16) - -/* TXCTRL register */ -#define FESPI_TXWM(x) ((x) & 0xffff) -/* RXCTRL register */ -#define FESPI_RXWM(x) ((x) & 0xffff) - -#define FESPI_IP_TXWM 0x1 -#define FESPI_IP_RXWM 0x2 - -#define FESPI_FCTRL_EN 0x1 - -#define FESPI_INSN_CMD_EN 0x1 -#define FESPI_INSN_ADDR_LEN(x) (((x) & 0x7) << 1) -#define FESPI_INSN_PAD_CNT(x) (((x) & 0xf) << 4) -#define FESPI_INSN_CMD_PROTO(x) (((x) & 0x3) << 8) -#define FESPI_INSN_ADDR_PROTO(x) (((x) & 0x3) << 10) -#define FESPI_INSN_DATA_PROTO(x) (((x) & 0x3) << 12) -#define FESPI_INSN_CMD_CODE(x) (((x) & 0xff) << 16) -#define FESPI_INSN_PAD_CODE(x) (((x) & 0xff) << 24) - -/* Values */ - -#define FESPI_CSMODE_AUTO 0 -#define FESPI_CSMODE_HOLD 2 -#define FESPI_CSMODE_OFF 3 - -#define FESPI_DIR_RX 0 -#define FESPI_DIR_TX 1 - -#define FESPI_PROTO_S 0 -#define FESPI_PROTO_D 1 -#define FESPI_PROTO_Q 2 - -#define FESPI_ENDIAN_MSB 0 -#define FESPI_ENDIAN_LSB 1 - - -/* Timeout in ms */ -#define FESPI_CMD_TIMEOUT (100) -#define FESPI_PROBE_TIMEOUT (100) -#define FESPI_MAX_TIMEOUT (3000) - - -#define FESPI_READ_REG(a) (_FESPI_READ_REG(a)) -#define _FESPI_READ_REG(a) \ -{ \ - int __a; \ - uint32_t __v; \ - \ - __a = target_read_u32(target, ctrl_base + (a), &__v); \ - if (__a != ERROR_OK) \ - return __a; \ - __v; \ -} - -#define FESPI_WRITE_REG(a, v) \ -{ \ - int __r; \ - \ - __r = target_write_u32(target, ctrl_base + (a), (v)); \ - if (__r != ERROR_OK) \ - return __r; \ -} - -#define FESPI_DISABLE_HW_MODE() FESPI_WRITE_REG(FESPI_REG_FCTRL, \ - FESPI_READ_REG(FESPI_REG_FCTRL) & ~FESPI_FCTRL_EN) -#define FESPI_ENABLE_HW_MODE() FESPI_WRITE_REG(FESPI_REG_FCTRL, \ - FESPI_READ_REG(FESPI_REG_FCTRL) | FESPI_FCTRL_EN) - -struct fespi_flash_bank { - int probed; - uint32_t ctrl_base; - const struct flash_device *dev; -}; - -struct fespi_target { - char *name; - uint32_t tap_idcode; - uint32_t ctrl_base; -}; - -//TODO !!! What is the right naming convention here? -static const struct fespi_target target_devices[] = { - /* name, tap_idcode, ctrl_base */ - { "Freedom E300 SPI Flash", 0x10e31913 , 0x10014000 }, - { "whatever", 0x00000001, 0x10014000 }, - { NULL, 0, 0 } -}; - -FLASH_BANK_COMMAND_HANDLER(fespi_flash_bank_command) -{ - struct fespi_flash_bank *fespi_info; - - LOG_DEBUG("%s", __func__); - - if (CMD_ARGC < 6) - return ERROR_COMMAND_SYNTAX_ERROR; - - fespi_info = malloc(sizeof(struct fespi_flash_bank)); - if (fespi_info == NULL) { - LOG_ERROR("not enough memory"); - return ERROR_FAIL; - } - - bank->driver_priv = fespi_info; - fespi_info->probed = 0; - - return ERROR_OK; -} - -static int fespi_set_dir (struct flash_bank * bank, bool dir) { - struct target *target = bank->target; - struct fespi_flash_bank *fespi_info = bank->driver_priv; - uint32_t ctrl_base = fespi_info->ctrl_base; - - FESPI_WRITE_REG(FESPI_REG_FMT, - (FESPI_READ_REG(FESPI_REG_FMT) & ~(FESPI_FMT_DIR(0xFFFFFFFF))) | - FESPI_FMT_DIR(dir)); - - return ERROR_OK; - -} - -static int fespi_txwm_wait(struct flash_bank *bank) { - struct target *target = bank->target; - struct fespi_flash_bank *fespi_info = bank->driver_priv; - uint32_t ctrl_base = fespi_info->ctrl_base; - - int64_t start = timeval_ms(); - - while (1) { - if (FESPI_READ_REG(FESPI_REG_IP) & FESPI_IP_TXWM) { - break; - } - int64_t now = timeval_ms(); - if (now - start > 1000) { - LOG_ERROR("ip.txwm didn't get set."); - return ERROR_TARGET_TIMEOUT; - } - } - - return ERROR_OK; - -} - -static int fespi_tx(struct flash_bank *bank, uint8_t in){ - struct target *target = bank->target; - struct fespi_flash_bank *fespi_info = bank->driver_priv; - uint32_t ctrl_base = fespi_info->ctrl_base; - - int64_t start = timeval_ms(); - - while (1) { - if ((int32_t) FESPI_READ_REG(FESPI_REG_TXFIFO) >= 0) { - break; - } - int64_t now = timeval_ms(); - if (now - start > 1000) { - LOG_ERROR("txfifo stayed negative."); - return ERROR_TARGET_TIMEOUT; - } - } - - FESPI_WRITE_REG(FESPI_REG_TXFIFO, in); - - return ERROR_OK; -} - -static int fespi_rx(struct flash_bank *bank, uint8_t *out) -{ - struct target *target = bank->target; - struct fespi_flash_bank *fespi_info = bank->driver_priv; - uint32_t ctrl_base = fespi_info->ctrl_base; - - int64_t start = timeval_ms(); - int32_t value; - - while (1) { - value = (int32_t) FESPI_READ_REG(FESPI_REG_RXFIFO); - if (value >= 0) - break; - int64_t now = timeval_ms(); - if (now - start > 1000) { - LOG_ERROR("rxfifo didn't go positive (value=0x%x).", value); - return ERROR_TARGET_TIMEOUT; - } - } - - if (out) { - *out = value & 0xff; - } - return ERROR_OK; -} - -//TODO!!! Why don't we need to call this after writing? -static int fespi_wip (struct flash_bank * bank, int timeout) -{ - struct target *target = bank->target; - struct fespi_flash_bank *fespi_info = bank->driver_priv; - uint32_t ctrl_base = fespi_info->ctrl_base; - - int64_t endtime; - - fespi_set_dir(bank, FESPI_DIR_RX); - - FESPI_WRITE_REG(FESPI_REG_CSMODE, FESPI_CSMODE_HOLD); - endtime = timeval_ms() + timeout; - - fespi_tx(bank, SPIFLASH_READ_STATUS); - if (fespi_rx(bank, NULL) != ERROR_OK) - return ERROR_FAIL; - - do { - alive_sleep(1); - - fespi_tx(bank, 0); - uint8_t rx; - if (fespi_rx(bank, &rx) != ERROR_OK) - return ERROR_FAIL; - if ((rx & SPIFLASH_BSY_BIT) == 0) { - FESPI_WRITE_REG(FESPI_REG_CSMODE, FESPI_CSMODE_AUTO); - fespi_set_dir(bank, FESPI_DIR_TX); - return ERROR_OK; - } - } while (timeval_ms() < endtime); - - LOG_ERROR("timeout"); - return ERROR_FAIL; -} - -static int fespi_erase_sector(struct flash_bank *bank, int sector) -{ - struct target *target = bank->target; - struct fespi_flash_bank *fespi_info = bank->driver_priv; - uint32_t ctrl_base = fespi_info->ctrl_base; - int retval; - - fespi_tx(bank, SPIFLASH_WRITE_ENABLE); - fespi_txwm_wait(bank); - - FESPI_WRITE_REG(FESPI_REG_CSMODE, FESPI_CSMODE_HOLD); - fespi_tx(bank, fespi_info->dev->erase_cmd); - sector = bank->sectors[sector].offset; - fespi_tx(bank, sector >> 16); - fespi_tx(bank, sector >> 8); - fespi_tx(bank, sector); - fespi_txwm_wait(bank); - FESPI_WRITE_REG(FESPI_REG_CSMODE, FESPI_CSMODE_AUTO); - - retval = fespi_wip(bank, FESPI_MAX_TIMEOUT); - if (retval != ERROR_OK) - return retval; - - return ERROR_OK; -} - -static int fespi_erase(struct flash_bank *bank, int first, int last) -{ - struct target *target = bank->target; - struct fespi_flash_bank *fespi_info = bank->driver_priv; - uint32_t ctrl_base = fespi_info->ctrl_base; - int retval = ERROR_OK; - int sector; - - LOG_DEBUG("%s: from sector %d to sector %d", __func__, first, last); - - if (target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - if ((first < 0) || (last < first) || (last >= bank->num_sectors)) { - LOG_ERROR("Flash sector invalid"); - return ERROR_FLASH_SECTOR_INVALID; - } - - if (!(fespi_info->probed)) { - LOG_ERROR("Flash bank not probed"); - return ERROR_FLASH_BANK_NOT_PROBED; - } - - for (sector = first; sector <= last; sector++) { - if (bank->sectors[sector].is_protected) { - LOG_ERROR("Flash sector %d protected", sector); - return ERROR_FAIL; - } - } - - fespi_txwm_wait(bank); - - /* Disable Hardware accesses*/ - FESPI_DISABLE_HW_MODE(); - - /* poll WIP */ - retval = fespi_wip(bank, FESPI_PROBE_TIMEOUT); - if (retval != ERROR_OK) - return retval; - - for (sector = first; sector <= last; sector++) { - retval = fespi_erase_sector(bank, sector); - if (retval != ERROR_OK) - break; - keep_alive(); - } - - /* Switch to HW mode before return to prompt */ - FESPI_ENABLE_HW_MODE(); - return retval; -} - -static int fespi_protect(struct flash_bank *bank, int set, - int first, int last) -{ - int sector; - - for (sector = first; sector <= last; sector++) - bank->sectors[sector].is_protected = set; - return ERROR_OK; -} - -static int slow_fespi_write_buffer(struct flash_bank *bank, - const uint8_t *buffer, uint32_t offset, uint32_t len) -{ - struct target *target = bank->target; - struct fespi_flash_bank *fespi_info = bank->driver_priv; - uint32_t ctrl_base = fespi_info->ctrl_base; - uint32_t ii; - - //TODO!!! assert that len < page size - - fespi_tx(bank, SPIFLASH_WRITE_ENABLE); - fespi_txwm_wait(bank); - - FESPI_WRITE_REG(FESPI_REG_CSMODE, FESPI_CSMODE_HOLD); - - fespi_tx(bank, SPIFLASH_PAGE_PROGRAM); - - fespi_tx(bank, offset >> 16); - fespi_tx(bank, offset >> 8); - fespi_tx(bank, offset); - - for (ii = 0; ii < len; ii++) { - fespi_tx(bank, buffer[ii]); - } - - fespi_txwm_wait(bank); - - FESPI_WRITE_REG(FESPI_REG_CSMODE, FESPI_CSMODE_AUTO); - - keep_alive(); - - return ERROR_OK; -} - -/* - * Here's the source for the algorithm. - * You can turn it into the array below using: - sed -n '/ALGO_START$/,/ALGO_END/ p' fespi.c | \ - riscv32-unknown-elf-gcc -x assembler-with-cpp - -nostdlib -nostartfiles -o tmp.o && \ - riscv32-unknown-elf-objcopy -O binary tmp.o algorithm.bin && \ - xxd -i algorithm.bin - -// ALGO_START -#define SPIFLASH_READ_STATUS 0x05 // Read Status Register -#define SPIFLASH_BSY_BIT 0x00000001 // WIP Bit of SPI SR on SMI SR - -// Register offsets -#define FESPI_REG_FMT 0x40 -#define FESPI_REG_TXFIFO 0x48 -#define FESPI_REG_RXFIFO 0x4c -#define FESPI_REG_IP 0x74 - -// Fields -#define FESPI_IP_TXWM 0x1 -#define FESPI_FMT_DIR(x) (((x) & 0x1) << 3) - -// To enter, jump to the start of command_table (ie. offset 0). -// a0 - FESPI base address -// a1 - start address of buffer - -// The buffer contains a "program" in byte sequences. The first byte in a -// sequence determines the operation. Some operation will read more data from -// the program, while some will not. The operation byte is the offset into -// command_table, so eg. 4 means exit, 8 means transmit, and so on. - - .global _start -_start: -command_table: - j main // 0 - ebreak // 4 - j tx // 8 - j txwm_wait // 12 - j write_reg // 16 - j wip_wait // 20 - j set_dir // 24 - -// Execute the program. -main: - lbu t0, 0(a1) - addi a1, a1, 1 - la t1, command_table - add t0, t0, t1 - jr t0 - -// Read 1 byte the contains the number of bytes to transmit. Then read those -// bytes from the program and transmit them one by one. -tx: - lbu t1, 0(a1) // read number of bytes to transmit - addi a1, a1, 1 -1: lw t0, FESPI_REG_TXFIFO(a0) // wait for FIFO clear - bltz t0, 1b - lbu t0, 0(a1) // Load byte to write - sw t0, FESPI_REG_TXFIFO(a0) - addi a1, a1, 1 - addi t1, t1, -1 - bgtz t1, 1b - j main - -// Wait until TXWM is set. -txwm_wait: -1: lw t0, FESPI_REG_IP(a0) - andi t0, t0, FESPI_IP_TXWM - beqz t0, 1b - j main - -// Read 1 byte that contains the offset of the register to write, and 1 byte -// that contains the data to write. -write_reg: - lbu t0, 0(a1) // read register to write - add t0, t0, a0 - lbu t1, 1(a1) // read value to write - addi a1, a1, 2 - sw t1, 0(t0) - j main - -wip_wait: - li a2, SPIFLASH_READ_STATUS - jal txrx_byte - // discard first result -1: li a2, 0 - jal txrx_byte - andi t0, a2, SPIFLASH_BSY_BIT - bnez t0, 1b - j main - -txrx_byte: // transmit the byte in a2, receive a bit into a2 - lw t0, FESPI_REG_TXFIFO(a0) // wait for FIFO clear - bltz t0, txrx_byte - sw a2, FESPI_REG_TXFIFO(a0) -1: lw a2, FESPI_REG_RXFIFO(a0) - bltz a2, 1b - ret - -set_dir: - lw t0, FESPI_REG_FMT(a0) - li t1, ~(FESPI_FMT_DIR(0xFFFFFFFF)) - and t0, t0, t1 - lbu t1, 0(a1) // read value to OR in - addi a1, a1, 1 - or t0, t0, t1 - sw t0, FESPI_REG_FMT(a0) - j main - -// ALGO_END - */ -static const uint8_t algorithm_bin[] = { - 0x6f, 0x00, 0xc0, 0x01, 0x73, 0x00, 0x10, 0x00, 0x6f, 0x00, 0xc0, 0x02, - 0x6f, 0x00, 0x00, 0x05, 0x6f, 0x00, 0xc0, 0x05, 0x6f, 0x00, 0x00, 0x07, - 0x6f, 0x00, 0x00, 0x0a, 0x83, 0xc2, 0x05, 0x00, 0x93, 0x85, 0x15, 0x00, - 0x17, 0x03, 0x00, 0x00, 0x13, 0x03, 0xc3, 0xfd, 0xb3, 0x82, 0x62, 0x00, - 0x67, 0x80, 0x02, 0x00, 0x03, 0xc3, 0x05, 0x00, 0x93, 0x85, 0x15, 0x00, - 0x83, 0x22, 0x85, 0x04, 0xe3, 0xce, 0x02, 0xfe, 0x83, 0xc2, 0x05, 0x00, - 0x23, 0x24, 0x55, 0x04, 0x93, 0x85, 0x15, 0x00, 0x13, 0x03, 0xf3, 0xff, - 0xe3, 0x44, 0x60, 0xfe, 0x6f, 0xf0, 0x5f, 0xfc, 0x83, 0x22, 0x45, 0x07, - 0x93, 0xf2, 0x12, 0x00, 0xe3, 0x8c, 0x02, 0xfe, 0x6f, 0xf0, 0x5f, 0xfb, - 0x83, 0xc2, 0x05, 0x00, 0xb3, 0x82, 0xa2, 0x00, 0x03, 0xc3, 0x15, 0x00, - 0x93, 0x85, 0x25, 0x00, 0x23, 0xa0, 0x62, 0x00, 0x6f, 0xf0, 0xdf, 0xf9, - 0x13, 0x06, 0x50, 0x00, 0xef, 0x00, 0x80, 0x01, 0x13, 0x06, 0x00, 0x00, - 0xef, 0x00, 0x00, 0x01, 0x93, 0x72, 0x16, 0x00, 0xe3, 0x9a, 0x02, 0xfe, - 0x6f, 0xf0, 0x1f, 0xf8, 0x83, 0x22, 0x85, 0x04, 0xe3, 0xce, 0x02, 0xfe, - 0x23, 0x24, 0xc5, 0x04, 0x03, 0x26, 0xc5, 0x04, 0xe3, 0x4e, 0x06, 0xfe, - 0x67, 0x80, 0x00, 0x00, 0x83, 0x22, 0x05, 0x04, 0x13, 0x03, 0x70, 0xff, - 0xb3, 0xf2, 0x62, 0x00, 0x03, 0xc3, 0x05, 0x00, 0x93, 0x85, 0x15, 0x00, - 0xb3, 0xe2, 0x62, 0x00, 0x23, 0x20, 0x55, 0x04, 0x6f, 0xf0, 0x9f, 0xf4 -}; -#define STEP_EXIT 4 -#define STEP_TX 8 -#define STEP_TXWM_WAIT 12 -#define STEP_WRITE_REG 16 -#define STEP_WIP_WAIT 20 -#define STEP_SET_DIR 24 -#define STEP_NOP 0xff - -struct algorithm_steps { - unsigned size; - unsigned used; - uint8_t **steps; -}; - -struct algorithm_steps *as_new(unsigned size) -{ - struct algorithm_steps *as = calloc(1, sizeof(struct algorithm_steps)); - as->size = size; - as->steps = calloc(size, sizeof(as->steps[0])); - return as; -} - -struct algorithm_steps *as_delete(struct algorithm_steps *as) -{ - for (unsigned step = 0; step < as->used; step++) { - free(as->steps[step]); - as->steps[step] = NULL; - } - free(as); - return NULL; -} - -int as_empty(struct algorithm_steps *as) -{ - for (unsigned s = 0; s < as->used; s++) { - if (as->steps[s][0] != STEP_NOP) - return 0; - } - return 1; -} - -// Return size of compiled program. -unsigned as_compile(struct algorithm_steps *as, uint8_t *target, - unsigned target_size) -{ - unsigned offset = 0; - bool finish_early = false; - for (unsigned s = 0; s < as->used && !finish_early; s++) { - unsigned bytes_left = target_size - offset; - switch (as->steps[s][0]) { - case STEP_NOP: - break; - case STEP_TX: - { - unsigned size = as->steps[s][1]; - if (size + 3 > bytes_left) { - finish_early = true; - break; - } - memcpy(target + offset, as->steps[s], size + 2); - offset += size + 2; - break; - } - case STEP_WRITE_REG: - if (4 > bytes_left) { - finish_early = true; - break; - } - memcpy(target + offset, as->steps[s], 3); - offset += 3; - break; - case STEP_SET_DIR: - if (3 > bytes_left) { - finish_early = true; - break; - } - memcpy(target + offset, as->steps[s], 2); - offset += 2; - break; - case STEP_TXWM_WAIT: - case STEP_WIP_WAIT: - if (2 > bytes_left) { - finish_early = true; - break; - } - memcpy(target + offset, as->steps[s], 1); - offset += 1; - break; - default: - assert(0); - } - if (!finish_early) - as->steps[s][0] = STEP_NOP; - } - assert(offset + 1 <= target_size); - target[offset++] = STEP_EXIT; - - LOG_DEBUG("%d-byte program:", offset); - for (unsigned i = 0; i < offset;) { - char buf[80]; - for (unsigned x = 0; i < offset && x < 16; x++, i++) { - sprintf(buf + x*3, "%02x ", target[i]); - } - LOG_DEBUG("%s", buf); - } - - return offset; -} - -void as_add_tx(struct algorithm_steps *as, unsigned count, const uint8_t *data) -{ - LOG_DEBUG("count=%d", count); - while (count > 0) { - unsigned step_count = MIN(count, 255); - assert(as->used < as->size); - as->steps[as->used] = malloc(step_count + 2); - as->steps[as->used][0] = STEP_TX; - as->steps[as->used][1] = step_count; - memcpy(as->steps[as->used] + 2, data, step_count); - as->used++; - data += step_count; - count -= step_count; - } -} - -void as_add_tx1(struct algorithm_steps *as, uint8_t byte) -{ - uint8_t data[1]; - data[0] = byte; - as_add_tx(as, 1, data); -} - -void as_add_write_reg(struct algorithm_steps *as, uint8_t offset, uint8_t data) -{ - assert(as->used < as->size); - as->steps[as->used] = malloc(3); - as->steps[as->used][0] = STEP_WRITE_REG; - as->steps[as->used][1] = offset; - as->steps[as->used][2] = data; - as->used++; -} - -void as_add_txwm_wait(struct algorithm_steps *as) -{ - assert(as->used < as->size); - as->steps[as->used] = malloc(1); - as->steps[as->used][0] = STEP_TXWM_WAIT; - as->used++; -} - -void as_add_wip_wait(struct algorithm_steps *as) -{ - assert(as->used < as->size); - as->steps[as->used] = malloc(1); - as->steps[as->used][0] = STEP_WIP_WAIT; - as->used++; -} - -void as_add_set_dir(struct algorithm_steps *as, bool dir) -{ - assert(as->used < as->size); - as->steps[as->used] = malloc(2); - as->steps[as->used][0] = STEP_SET_DIR; - as->steps[as->used][1] = FESPI_FMT_DIR(dir); - as->used++; -} - -/* This should write something less than or equal to a page.*/ -static int steps_add_buffer_write(struct algorithm_steps *as, - const uint8_t *buffer, uint32_t chip_offset, uint32_t len) -{ - as_add_tx1(as, SPIFLASH_WRITE_ENABLE); - as_add_txwm_wait(as); - as_add_write_reg(as, FESPI_REG_CSMODE, FESPI_CSMODE_HOLD); - - uint8_t setup[] = { - SPIFLASH_PAGE_PROGRAM, - chip_offset >> 16, - chip_offset >> 8, - chip_offset, - }; - as_add_tx(as, sizeof(setup), setup); - - as_add_tx(as, len, buffer); - as_add_txwm_wait(as); - as_add_write_reg(as, FESPI_REG_CSMODE, FESPI_CSMODE_AUTO); - - // fespi_wip() - as_add_set_dir(as, FESPI_DIR_RX); - as_add_write_reg(as, FESPI_REG_CSMODE, FESPI_CSMODE_HOLD); - as_add_wip_wait(as); - as_add_write_reg(as, FESPI_REG_CSMODE, FESPI_CSMODE_AUTO); - as_add_set_dir(as, FESPI_DIR_TX); - - return ERROR_OK; -} - -static int steps_execute(struct algorithm_steps *as, - struct flash_bank *bank, struct working_area *algorithm_wa, - struct working_area *data_wa) -{ - struct target *target = bank->target; - struct fespi_flash_bank *fespi_info = bank->driver_priv; - uint32_t ctrl_base = fespi_info->ctrl_base; - uint8_t *data_buf = malloc(data_wa->size); - - struct reg_param reg_params[2]; - init_reg_param(®_params[0], "x10", 64, PARAM_OUT); - init_reg_param(®_params[1], "x11", 64, PARAM_OUT); - buf_set_u64(reg_params[0].value, 0, 64, ctrl_base); - buf_set_u64(reg_params[1].value, 0, 64, data_wa->address); - while (!as_empty(as)) { - keep_alive(); - unsigned bytes = as_compile(as, data_buf, data_wa->size); - int retval = target_write_buffer(target, data_wa->address, bytes, - data_buf); - if (retval != ERROR_OK) { - LOG_ERROR("Failed to write data to 0x%x: %d", data_wa->address, - retval); - return retval; - } - - retval = target_run_algorithm(target, 0, NULL, 2, reg_params, - algorithm_wa->address, algorithm_wa->address + 4, - 10000, NULL); - if (retval != ERROR_OK) { - LOG_ERROR("Failed to execute algorithm at 0x%x: %d", algorithm_wa->address, - retval); - return retval; - } - } - - return ERROR_OK; -} - -static int fespi_write(struct flash_bank *bank, const uint8_t *buffer, - uint32_t offset, uint32_t count) -{ - struct target *target = bank->target; - struct fespi_flash_bank *fespi_info = bank->driver_priv; - uint32_t ctrl_base = fespi_info->ctrl_base; - uint32_t cur_count, page_size, page_offset; - int sector; - int retval = ERROR_OK; - - LOG_DEBUG("%s: offset=0x%08" PRIx32 " count=0x%08" PRIx32, - __func__, offset, count); - - if (target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - if (offset + count > fespi_info->dev->size_in_bytes) { - LOG_WARNING("Write past end of flash. Extra data discarded."); - count = fespi_info->dev->size_in_bytes - offset; - } - - /* Check sector protection */ - for (sector = 0; sector < bank->num_sectors; sector++) { - /* Start offset in or before this sector? */ - /* End offset in or behind this sector? */ - if ((offset < - (bank->sectors[sector].offset + bank->sectors[sector].size)) - && ((offset + count - 1) >= bank->sectors[sector].offset) - && bank->sectors[sector].is_protected) { - LOG_ERROR("Flash sector %d protected", sector); - return ERROR_FAIL; - } - } - - struct working_area *algorithm_wa; - if (target_alloc_working_area(target, sizeof(algorithm_bin), - &algorithm_wa) != ERROR_OK) { - LOG_WARNING("Couldn't allocate %zd-byte working area.", - sizeof(algorithm_bin)); - algorithm_wa = NULL; - } else { - retval = target_write_buffer(target, algorithm_wa->address, - sizeof(algorithm_bin), algorithm_bin); - if (retval != ERROR_OK) { - LOG_ERROR("Failed to write code to 0x%x: %d", algorithm_wa->address, - retval); - target_free_working_area(target, algorithm_wa); - algorithm_wa = NULL; - } - } - - struct working_area *data_wa = NULL; - unsigned data_wa_size = 2 * count; - while (1) { - if (data_wa_size < 128) { - LOG_WARNING("Couldn't allocate data working area."); - target_free_working_area(target, algorithm_wa); - algorithm_wa = NULL; - } - if (target_alloc_working_area_try(target, data_wa_size, &data_wa) == - ERROR_OK) { - break; - } - - data_wa_size /= 2; - } - - page_size = fespi_info->dev->pagesize; - - fespi_txwm_wait(bank); - - /* Disable Hardware accesses*/ - FESPI_DISABLE_HW_MODE(); - - /* poll WIP */ - retval = fespi_wip(bank, FESPI_PROBE_TIMEOUT); - if (retval != ERROR_OK) - return retval; - - struct algorithm_steps *as = as_new(count / 4); - - /* unaligned buffer head */ - if (count > 0 && (offset & 3) != 0) { - cur_count = 4 - (offset & 3); - if (cur_count > count) - cur_count = count; - if (algorithm_wa) { - retval = steps_add_buffer_write(as, buffer, offset, cur_count); - } else { - retval = slow_fespi_write_buffer(bank, buffer, offset, cur_count); - } - if (retval != ERROR_OK) - goto err; - offset += cur_count; - buffer += cur_count; - count -= cur_count; - } - - page_offset = offset % page_size; - /* central part, aligned words */ - while (count >= 4) { - /* clip block at page boundary */ - if (page_offset + count > page_size) - cur_count = page_size - page_offset; - else - cur_count = count & ~3; - - if (algorithm_wa) { - retval = steps_add_buffer_write(as, buffer, offset, cur_count); - } else { - retval = slow_fespi_write_buffer(bank, buffer, offset, cur_count); - } - if (retval != ERROR_OK) - goto err; - - page_offset = 0; - buffer += cur_count; - offset += cur_count; - count -= cur_count; - } - - /* buffer tail */ - if (count > 0) { - if (algorithm_wa) { - retval = steps_add_buffer_write(as, buffer, offset, count); - } else { - retval = slow_fespi_write_buffer(bank, buffer, offset, count); - } - if (retval != ERROR_OK) - goto err; - } - - if (algorithm_wa) { - retval = steps_execute(as, bank, algorithm_wa, data_wa); - } - -err: - if (algorithm_wa) { - target_free_working_area(target, data_wa); - target_free_working_area(target, algorithm_wa); - } - - /* Switch to HW mode before return to prompt */ - FESPI_ENABLE_HW_MODE(); - return retval; -} - -/* Return ID of flash device */ -/* On exit, SW mode is kept */ -static int fespi_read_flash_id(struct flash_bank *bank, uint32_t *id) -{ - struct target *target = bank->target; - struct fespi_flash_bank *fespi_info = bank->driver_priv; - uint32_t ctrl_base = fespi_info->ctrl_base; - int retval; - - if (target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - fespi_txwm_wait(bank); - - /* Disable Hardware accesses*/ - FESPI_DISABLE_HW_MODE(); - - /* poll WIP */ - retval = fespi_wip(bank, FESPI_PROBE_TIMEOUT); - if (retval != ERROR_OK) - return retval; - - fespi_set_dir(bank, FESPI_DIR_RX); - - /* Send SPI command "read ID" */ - FESPI_WRITE_REG(FESPI_REG_CSMODE, FESPI_CSMODE_HOLD); - - fespi_tx(bank, SPIFLASH_READ_ID); - /* Send dummy bytes to actually read the ID.*/ - fespi_tx(bank, 0); - fespi_tx(bank, 0); - fespi_tx(bank, 0); - - /* read ID from Receive Register */ - *id = 0; - if (fespi_rx(bank, NULL) != ERROR_OK) - return ERROR_FAIL; - uint8_t rx; - if (fespi_rx(bank, &rx) != ERROR_OK) - return ERROR_FAIL; - *id = rx; - if (fespi_rx(bank, &rx) != ERROR_OK) - return ERROR_FAIL; - *id |= (rx << 8); - if (fespi_rx(bank, &rx) != ERROR_OK) - return ERROR_FAIL; - *id |= (rx << 16); - - FESPI_WRITE_REG(FESPI_REG_CSMODE, FESPI_CSMODE_AUTO); - - fespi_set_dir(bank, FESPI_DIR_TX); - - return ERROR_OK; -} - -static int fespi_probe(struct flash_bank *bank) -{ - struct target *target = bank->target; - struct fespi_flash_bank *fespi_info = bank->driver_priv; - uint32_t ctrl_base; - struct flash_sector *sectors; - uint32_t id = 0; /* silence uninitialized warning */ - const struct fespi_target *target_device; - int retval; - - if (fespi_info->probed) - free(bank->sectors); - fespi_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 FESPI capable", - target->tap->idcode); - return ERROR_FAIL; - } - - ctrl_base = target_device->ctrl_base; - fespi_info->ctrl_base = ctrl_base; - - LOG_DEBUG("Valid FESPI on device %s at address 0x%" PRIx32, - target_device->name, bank->base); - - /* read and decode flash ID; returns in SW mode */ - FESPI_WRITE_REG(FESPI_REG_TXCTRL, FESPI_TXWM(1)); - fespi_set_dir(bank, FESPI_DIR_TX); - - retval = fespi_read_flash_id(bank, &id); - - FESPI_ENABLE_HW_MODE(); - if (retval != ERROR_OK) - return retval; - - fespi_info->dev = NULL; - for (const struct flash_device *p = flash_devices; p->name ; p++) - if (p->device_id == id) { - fespi_info->dev = p; - break; - } - - if (!fespi_info->dev) { - LOG_ERROR("Unknown flash device (ID 0x%08" PRIx32 ")", id); - return ERROR_FAIL; - } - - LOG_INFO("Found flash device \'%s\' (ID 0x%08" PRIx32 ")", - fespi_info->dev->name, fespi_info->dev->device_id); - - /* Set correct size value */ - bank->size = fespi_info->dev->size_in_bytes; - - /* create and fill sectors array */ - bank->num_sectors = - fespi_info->dev->size_in_bytes / fespi_info->dev->sectorsize; - sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors); - if (sectors == NULL) { - LOG_ERROR("not enough memory"); - return ERROR_FAIL; - } - - for (int sector = 0; sector < bank->num_sectors; sector++) { - sectors[sector].offset = sector * fespi_info->dev->sectorsize; - sectors[sector].size = fespi_info->dev->sectorsize; - sectors[sector].is_erased = -1; - sectors[sector].is_protected = 1; - } - - bank->sectors = sectors; - fespi_info->probed = 1; - return ERROR_OK; -} - -static int fespi_auto_probe(struct flash_bank *bank) -{ - struct fespi_flash_bank *fespi_info = bank->driver_priv; - if (fespi_info->probed) - return ERROR_OK; - return fespi_probe(bank); -} - -static int fespi_protect_check(struct flash_bank *bank) -{ - /* Nothing to do. Protection is only handled in SW. */ - return ERROR_OK; -} - -static int get_fespi_info(struct flash_bank *bank, char *buf, int buf_size) -{ - struct fespi_flash_bank *fespi_info = bank->driver_priv; - - if (!(fespi_info->probed)) { - snprintf(buf, buf_size, - "\nFESPI flash bank not probed yet\n"); - return ERROR_OK; - } - - snprintf(buf, buf_size, "\nFESPI flash information:\n" - " Device \'%s\' (ID 0x%08" PRIx32 ")\n", - fespi_info->dev->name, fespi_info->dev->device_id); - - return ERROR_OK; -} - -struct flash_driver fespi_flash = { - .name = "fespi", - .flash_bank_command = fespi_flash_bank_command, - .erase = fespi_erase, - .protect = fespi_protect, - .write = fespi_write, - .read = default_flash_read, - .probe = fespi_probe, - .auto_probe = fespi_auto_probe, - .erase_check = default_flash_blank_check, - .protect_check = fespi_protect_check, - .info = get_fespi_info -}; diff --git a/src/flash/nor/fm3.c b/src/flash/nor/fm3.c deleted file mode 100644 index 6269a6536..000000000 --- a/src/flash/nor/fm3.c +++ /dev/null @@ -1,1000 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2011 by Marc Willam, Holger Wech * - * openOCD.fseu(AT)de.fujitsu.com * - * Copyright (C) 2011 Ronny Strutz * - * * - * Copyright (C) 2013 Nemui Trinomius * - * nemuisan_kawausogasuki@live.jp * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "imp.h" -#include -#include -#include - -#define FLASH_DQ6 0x40 /* Data toggle flag bit (TOGG) position */ -#define FLASH_DQ5 0x20 /* Time limit exceeding flag bit (TLOV) position */ - -enum fm3_variant { - mb9bfxx1, /* Flash Type '1' */ - mb9bfxx2, - mb9bfxx3, - mb9bfxx4, - mb9bfxx5, - mb9bfxx6, - mb9bfxx7, - mb9bfxx8, - - mb9afxx1, /* Flash Type '2' */ - mb9afxx2, - mb9afxx3, - mb9afxx4, - mb9afxx5, - mb9afxx6, - mb9afxx7, - mb9afxx8, -}; - -enum fm3_flash_type { - fm3_no_flash_type = 0, - fm3_flash_type1 = 1, - fm3_flash_type2 = 2 -}; - -struct fm3_flash_bank { - enum fm3_variant variant; - enum fm3_flash_type flashtype; - int probed; -}; - -FLASH_BANK_COMMAND_HANDLER(fm3_flash_bank_command) -{ - struct fm3_flash_bank *fm3_info; - - if (CMD_ARGC < 6) - return ERROR_COMMAND_SYNTAX_ERROR; - - fm3_info = malloc(sizeof(struct fm3_flash_bank)); - bank->driver_priv = fm3_info; - - /* Flash type '1' */ - if (strcmp(CMD_ARGV[5], "mb9bfxx1.cpu") == 0) { - fm3_info->variant = mb9bfxx1; - fm3_info->flashtype = fm3_flash_type1; - } else if (strcmp(CMD_ARGV[5], "mb9bfxx2.cpu") == 0) { - fm3_info->variant = mb9bfxx2; - fm3_info->flashtype = fm3_flash_type1; - } else if (strcmp(CMD_ARGV[5], "mb9bfxx3.cpu") == 0) { - fm3_info->variant = mb9bfxx3; - fm3_info->flashtype = fm3_flash_type1; - } else if (strcmp(CMD_ARGV[5], "mb9bfxx4.cpu") == 0) { - fm3_info->variant = mb9bfxx4; - fm3_info->flashtype = fm3_flash_type1; - } else if (strcmp(CMD_ARGV[5], "mb9bfxx5.cpu") == 0) { - fm3_info->variant = mb9bfxx5; - fm3_info->flashtype = fm3_flash_type1; - } else if (strcmp(CMD_ARGV[5], "mb9bfxx6.cpu") == 0) { - fm3_info->variant = mb9bfxx6; - fm3_info->flashtype = fm3_flash_type1; - } else if (strcmp(CMD_ARGV[5], "mb9bfxx7.cpu") == 0) { - fm3_info->variant = mb9bfxx7; - fm3_info->flashtype = fm3_flash_type1; - } else if (strcmp(CMD_ARGV[5], "mb9bfxx8.cpu") == 0) { - fm3_info->variant = mb9bfxx8; - fm3_info->flashtype = fm3_flash_type1; - } else if (strcmp(CMD_ARGV[5], "mb9afxx1.cpu") == 0) { /* Flash type '2' */ - fm3_info->variant = mb9afxx1; - fm3_info->flashtype = fm3_flash_type2; - } else if (strcmp(CMD_ARGV[5], "mb9afxx2.cpu") == 0) { - fm3_info->variant = mb9afxx2; - fm3_info->flashtype = fm3_flash_type2; - } else if (strcmp(CMD_ARGV[5], "mb9afxx3.cpu") == 0) { - fm3_info->variant = mb9afxx3; - fm3_info->flashtype = fm3_flash_type2; - } else if (strcmp(CMD_ARGV[5], "mb9afxx4.cpu") == 0) { - fm3_info->variant = mb9afxx4; - fm3_info->flashtype = fm3_flash_type2; - } else if (strcmp(CMD_ARGV[5], "mb9afxx5.cpu") == 0) { - fm3_info->variant = mb9afxx5; - fm3_info->flashtype = fm3_flash_type2; - } else if (strcmp(CMD_ARGV[5], "mb9afxx6.cpu") == 0) { - fm3_info->variant = mb9afxx6; - fm3_info->flashtype = fm3_flash_type2; - } else if (strcmp(CMD_ARGV[5], "mb9afxx7.cpu") == 0) { - fm3_info->variant = mb9afxx7; - fm3_info->flashtype = fm3_flash_type2; - } else if (strcmp(CMD_ARGV[5], "mb9afxx8.cpu") == 0) { - fm3_info->variant = mb9afxx8; - fm3_info->flashtype = fm3_flash_type2; - } - - /* unknown Flash type */ - else { - LOG_ERROR("unknown fm3 variant: %s", CMD_ARGV[5]); - free(fm3_info); - return ERROR_FLASH_BANK_INVALID; - } - - fm3_info->probed = 0; - - return ERROR_OK; -} - -/* Data polling algorithm */ -static int fm3_busy_wait(struct target *target, uint32_t offset, int timeout_ms) -{ - int retval = ERROR_OK; - uint8_t state1, state2; - int ms = 0; - - /* While(1) loop exit via "break" and "return" on error */ - while (1) { - /* dummy-read - see flash manual */ - retval = target_read_u8(target, offset, &state1); - if (retval != ERROR_OK) - return retval; - - /* Data polling 1 */ - retval = target_read_u8(target, offset, &state1); - if (retval != ERROR_OK) - return retval; - - /* Data polling 2 */ - retval = target_read_u8(target, offset, &state2); - if (retval != ERROR_OK) - return retval; - - /* Flash command finished via polled data equal? */ - if ((state1 & FLASH_DQ6) == (state2 & FLASH_DQ6)) - break; - /* Timeout Flag? */ - else if (state1 & FLASH_DQ5) { - /* Retry data polling */ - - /* Data polling 1 */ - retval = target_read_u8(target, offset, &state1); - if (retval != ERROR_OK) - return retval; - - /* Data polling 2 */ - retval = target_read_u8(target, offset, &state2); - if (retval != ERROR_OK) - return retval; - - /* Flash command finished via polled data equal? */ - if ((state1 & FLASH_DQ6) != (state2 & FLASH_DQ6)) - return ERROR_FLASH_OPERATION_FAILED; - - /* finish anyway */ - break; - } - usleep(1000); - ++ms; - - /* Polling time exceeded? */ - if (ms > timeout_ms) { - LOG_ERROR("Polling data reading timed out!"); - return ERROR_FLASH_OPERATION_FAILED; - } - } - - if (retval == ERROR_OK) - LOG_DEBUG("fm3_busy_wait(%" PRIx32 ") needs about %d ms", offset, ms); - - return retval; -} - -static int fm3_erase(struct flash_bank *bank, int first, int last) -{ - struct fm3_flash_bank *fm3_info = bank->driver_priv; - struct target *target = bank->target; - int retval = ERROR_OK; - uint32_t u32DummyRead; - int sector, odd; - uint32_t u32FlashType; - uint32_t u32FlashSeqAddress1; - uint32_t u32FlashSeqAddress2; - - struct working_area *write_algorithm; - struct reg_param reg_params[3]; - struct armv7m_algorithm armv7m_info; - - u32FlashType = (uint32_t) fm3_info->flashtype; - - if (u32FlashType == fm3_flash_type1) { - u32FlashSeqAddress1 = 0x00001550; - u32FlashSeqAddress2 = 0x00000AA8; - } else if (u32FlashType == fm3_flash_type2) { - u32FlashSeqAddress1 = 0x00000AA8; - u32FlashSeqAddress2 = 0x00000554; - } else { - LOG_ERROR("Flash/Device type unknown!"); - return ERROR_FLASH_OPERATION_FAILED; - } - - if (target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - /* RAMCODE used for fm3 Flash sector erase: */ - /* R0 keeps Flash Sequence address 1 (u32FlashSeq1) */ - /* R1 keeps Flash Sequence address 2 (u32FlashSeq2) */ - /* R2 keeps Flash Offset address (ofs) */ - static const uint8_t fm3_flash_erase_sector_code[] = { - /* *(uint16_t*)u32FlashSeq1 = 0xAA; */ - 0xAA, 0x24, /* MOVS R4, #0xAA */ - 0x04, 0x80, /* STRH R4, [R0, #0] */ - /* *(uint16_t*)u32FlashSeq2 = 0x55; */ - 0x55, 0x23, /* MOVS R3, #0x55 */ - 0x0B, 0x80, /* STRH R3, [R1, #0] */ - /* *(uint16_t*)u32FlashSeq1 = 0x80; */ - 0x80, 0x25, /* MOVS R5, #0x80 */ - 0x05, 0x80, /* STRH R5, [R0, #0] */ - /* *(uint16_t*)u32FlashSeq1 = 0xAA; */ - 0x04, 0x80, /* STRH R4, [R0, #0] */ - /* *(uint16_t*)u32FlashSeq2 = 0x55; */ - 0x0B, 0x80, /* STRH R3, [R1, #0] */ - /* Sector_Erase Command (0x30) */ - /* *(uint16_t*)ofs = 0x30; */ - 0x30, 0x20, /* MOVS R0, #0x30 */ - 0x10, 0x80, /* STRH R0, [R2, #0] */ - /* End Code */ - 0x00, 0xBE, /* BKPT #0 */ - }; - - LOG_INFO("Fujitsu MB9[A/B]FXXX: Sector Erase ... (%d to %d)", first, last); - - /* disable HW watchdog */ - retval = target_write_u32(target, 0x40011C00, 0x1ACCE551); - if (retval != ERROR_OK) - return retval; - - retval = target_write_u32(target, 0x40011C00, 0xE5331AAE); - if (retval != ERROR_OK) - return retval; - - retval = target_write_u32(target, 0x40011008, 0x00000000); - if (retval != ERROR_OK) - return retval; - - /* FASZR = 0x01, Enables CPU Programming Mode (16-bit Flash acccess) */ - retval = target_write_u32(target, 0x40000000, 0x0001); - if (retval != ERROR_OK) - return retval; - - /* dummy read of FASZR */ - retval = target_read_u32(target, 0x40000000, &u32DummyRead); - if (retval != ERROR_OK) - return retval; - - /* allocate working area with flash sector erase code */ - if (target_alloc_working_area(target, sizeof(fm3_flash_erase_sector_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(fm3_flash_erase_sector_code), fm3_flash_erase_sector_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); /* u32FlashSeqAddress1 */ - init_reg_param(®_params[1], "r1", 32, PARAM_OUT); /* u32FlashSeqAddress2 */ - init_reg_param(®_params[2], "r2", 32, PARAM_OUT); /* offset */ - - /* write code buffer and use Flash sector erase code within fm3 */ - for (sector = first ; sector <= last ; sector++) { - uint32_t offset = bank->sectors[sector].offset; - - for (odd = 0; odd < 2 ; odd++) { - if (odd) - offset += 4; - - buf_set_u32(reg_params[0].value, 0, 32, u32FlashSeqAddress1); - buf_set_u32(reg_params[1].value, 0, 32, u32FlashSeqAddress2); - buf_set_u32(reg_params[2].value, 0, 32, offset); - - 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 flash erase programming algorithm"); - retval = ERROR_FLASH_OPERATION_FAILED; - return retval; - } - - retval = fm3_busy_wait(target, offset, 500); - if (retval != ERROR_OK) - return retval; - } - bank->sectors[sector].is_erased = 1; - } - - target_free_working_area(target, write_algorithm); - destroy_reg_param(®_params[0]); - destroy_reg_param(®_params[1]); - destroy_reg_param(®_params[2]); - - /* FASZR = 0x02, Enables CPU Run Mode (32-bit Flash acccess) */ - retval = target_write_u32(target, 0x40000000, 0x0002); - if (retval != ERROR_OK) - return retval; - - retval = target_read_u32(target, 0x40000000, &u32DummyRead); /* dummy read of FASZR */ - - return retval; -} - -static int fm3_write_block(struct flash_bank *bank, const uint8_t *buffer, - uint32_t offset, uint32_t count) -{ - struct fm3_flash_bank *fm3_info = bank->driver_priv; - struct target *target = bank->target; - uint32_t buffer_size = 2048; /* Default minimum value */ - struct working_area *write_algorithm; - struct working_area *source; - uint32_t address = bank->base + offset; - struct reg_param reg_params[6]; - struct armv7m_algorithm armv7m_info; - int retval = ERROR_OK; - uint32_t u32FlashType; - uint32_t u32FlashSeqAddress1; - uint32_t u32FlashSeqAddress2; - - /* Increase buffer_size if needed */ - if (buffer_size < (target->working_area_size / 2)) - buffer_size = (target->working_area_size / 2); - - u32FlashType = (uint32_t) fm3_info->flashtype; - - if (u32FlashType == fm3_flash_type1) { - u32FlashSeqAddress1 = 0x00001550; - u32FlashSeqAddress2 = 0x00000AA8; - } else if (u32FlashType == fm3_flash_type2) { - u32FlashSeqAddress1 = 0x00000AA8; - u32FlashSeqAddress2 = 0x00000554; - } else { - LOG_ERROR("Flash/Device type unknown!"); - return ERROR_FLASH_OPERATION_FAILED; - } - - /* RAMCODE used for fm3 Flash programming: */ - /* R0 keeps source start address (u32Source) */ - /* R1 keeps target start address (u32Target) */ - /* R2 keeps number of halfwords to write (u32Count) */ - /* R3 keeps Flash Sequence address 1 (u32FlashSeq1) */ - /* R4 keeps Flash Sequence address 2 (u32FlashSeq2) */ - /* R5 returns result value (u32FlashResult) */ - - static const uint8_t fm3_flash_write_code[] = { - /* fm3_FLASH_IF->FASZ &= 0xFFFD; */ - 0x5F, 0xF0, 0x80, 0x45, /* MOVS.W R5, #(fm3_FLASH_IF->FASZ) */ - 0x2D, 0x68, /* LDR R5, [R5] */ - 0x4F, 0xF6, 0xFD, 0x76, /* MOVW R6, #0xFFFD */ - 0x35, 0x40, /* ANDS R5, R5, R6 */ - 0x5F, 0xF0, 0x80, 0x46, /* MOVS.W R6, #(fm3_FLASH_IF->FASZ) */ - 0x35, 0x60, /* STR R5, [R6] */ - /* fm3_FLASH_IF->FASZ |= 1; */ - 0x5F, 0xF0, 0x80, 0x45, /* MOVS.W R5, #(fm3_FLASH_IF->FASZ) */ - 0x2D, 0x68, /* LDR R5, [R3] */ - 0x55, 0xF0, 0x01, 0x05, /* ORRS.W R5, R5, #1 */ - 0x5F, 0xF0, 0x80, 0x46, /* MOVS.W R6, #(fm3_FLASH_IF->FASZ) */ - 0x35, 0x60, /* STR R5, [R6] */ - /* u32DummyRead = fm3_FLASH_IF->FASZ; */ - 0x28, 0x4D, /* LDR.N R5, ??u32DummyRead */ - 0x5F, 0xF0, 0x80, 0x46, /* MOVS.W R6, #(fm3_FLASH_IF->FASZ) */ - 0x36, 0x68, /* LDR R6, [R6] */ - 0x2E, 0x60, /* STR R6, [R5] */ - /* u32FlashResult = FLASH_WRITE_NO_RESULT */ - 0x26, 0x4D, /* LDR.N R5, ??u32FlashResult */ - 0x00, 0x26, /* MOVS R6, #0 */ - 0x2E, 0x60, /* STR R6, [R5] */ - /* while ((u32Count > 0 ) */ - /* && (u32FlashResult */ - /* == FLASH_WRITE_NO_RESULT)) */ - 0x01, 0x2A, /* L0: CMP R2, #1 */ - 0x2C, 0xDB, /* BLT.N L1 */ - 0x24, 0x4D, /* LDR.N R5, ??u32FlashResult */ - 0x2D, 0x68, /* LDR R5, [R5] */ - 0x00, 0x2D, /* CMP R5, #0 */ - 0x28, 0xD1, /* BNE.N L1 */ - /* *u32FlashSeq1 = FLASH_WRITE_1; */ - 0xAA, 0x25, /* MOVS R5, #0xAA */ - 0x1D, 0x60, /* STR R5, [R3] */ - /* *u32FlashSeq2 = FLASH_WRITE_2; */ - 0x55, 0x25, /* MOVS R5, #0x55 */ - 0x25, 0x60, /* STR R5, [R4] */ - /* *u32FlashSeq1 = FLASH_WRITE_3; */ - 0xA0, 0x25, /* MOVS R5, #0xA0 */ - 0x1D, 0x60, /* STRH R5, [R3] */ - /* *(volatile uint16_t*)u32Target */ - /* = *(volatile uint16_t*)u32Source; */ - 0x05, 0x88, /* LDRH R5, [R0] */ - 0x0D, 0x80, /* STRH R5, [R1] */ - /* while (u32FlashResult */ - /* == FLASH_WRITE_NO_RESTULT) */ - 0x1E, 0x4D, /* L2: LDR.N R5, ??u32FlashResult */ - 0x2D, 0x68, /* LDR R5, [R5] */ - 0x00, 0x2D, /* CMP R5, #0 */ - 0x11, 0xD1, /* BNE.N L3 */ - /* if ((*(volatile uint16_t*)u32Target */ - /* & FLASH_DQ5) == FLASH_DQ5) */ - 0x0D, 0x88, /* LDRH R5, [R1] */ - 0xAD, 0x06, /* LSLS R5, R5, #0x1A */ - 0x02, 0xD5, /* BPL.N L4 */ - /* u32FlashResult = FLASH_WRITE_TIMEOUT */ - 0x1A, 0x4D, /* LDR.N R5, ??u32FlashResult */ - 0x02, 0x26, /* MOVS R6, #2 */ - 0x2E, 0x60, /* STR R6, [R5] */ - /* if ((*(volatile uint16_t *)u32Target */ - /* & FLASH_DQ7) */ - /* == (*(volatile uint16_t*)u32Source */ - /* & FLASH_DQ7)) */ - 0x0D, 0x88, /* L4: LDRH R5, [R1] */ - 0x15, 0xF0, 0x80, 0x05, /* ANDS.W R5, R5, #0x80 */ - 0x06, 0x88, /* LDRH R6, [R0] */ - 0x16, 0xF0, 0x80, 0x06, /* ANDS.W R6, R6, #0x80 */ - 0xB5, 0x42, /* CMP R5, R6 */ - 0xED, 0xD1, /* BNE.N L2 */ - /* u32FlashResult = FLASH_WRITE_OKAY */ - 0x15, 0x4D, /* LDR.N R5, ??u32FlashResult */ - 0x01, 0x26, /* MOVS R6, #1 */ - 0x2E, 0x60, /* STR R6, [R5] */ - 0xE9, 0xE7, /* B.N L2 */ - /* if (u32FlashResult */ - /* != FLASH_WRITE_TIMEOUT) */ - 0x13, 0x4D, /* LDR.N R5, ??u32FlashResult */ - 0x2D, 0x68, /* LDR R5, [R5] */ - 0x02, 0x2D, /* CMP R5, #2 */ - 0x02, 0xD0, /* BEQ.N L5 */ - /* u32FlashResult = FLASH_WRITE_NO_RESULT */ - 0x11, 0x4D, /* LDR.N R5, ??u32FlashResult */ - 0x00, 0x26, /* MOVS R6, #0 */ - 0x2E, 0x60, /* STR R6, [R5] */ - /* u32Count--; */ - 0x52, 0x1E, /* L5: SUBS R2, R2, #1 */ - /* u32Source += 2; */ - 0x80, 0x1C, /* ADDS R0, R0, #2 */ - /* u32Target += 2; */ - 0x89, 0x1C, /* ADDS R1, R1, #2 */ - 0xD0, 0xE7, /* B.N L0 */ - /* fm3_FLASH_IF->FASZ &= 0xFFFE; */ - 0x5F, 0xF0, 0x80, 0x45, /* L1: MOVS.W R5, #(fm3_FLASH_IF->FASZ) */ - 0x2D, 0x68, /* LDR R5, [R5] */ - 0x4F, 0xF6, 0xFE, 0x76, /* MOVW R6, #0xFFFE */ - 0x35, 0x40, /* ANDS R5, R5, R6 */ - 0x5F, 0xF0, 0x80, 0x46, /* MOVS.W R6, #(fm3_FLASH_IF->FASZ) */ - 0x35, 0x60, /* STR R5, [R6] */ - /* fm3_FLASH_IF->FASZ |= 2; */ - 0x5F, 0xF0, 0x80, 0x45, /* MOVS.W R5, #(fm3_FLASH_IF->FASZ) */ - 0x2D, 0x68, /* LDR R5, [R5] */ - 0x55, 0xF0, 0x02, 0x05, /* ORRS.W R5, R5, #2 */ - 0x5F, 0xF0, 0x80, 0x46, /* MOVS.W R6, #(fm3_FLASH_IF->FASZ) */ - 0x35, 0x60, /* STR R5, [R6] */ - /* u32DummyRead = fm3_FLASH_IF->FASZ; */ - 0x04, 0x4D, /* LDR.N R5, ??u32DummyRead */ - 0x5F, 0xF0, 0x80, 0x46, /* MOVS.W R6, #(fm3_FLASH_IF->FASZ) */ - 0x36, 0x68, /* LDR R6, [R6] */ - 0x2E, 0x60, /* STR R6, [R5] */ - /* copy u32FlashResult to R3 for return */ - /* value */ - 0xDF, 0xF8, 0x08, 0x50, /* LDR.W R5, ??u32FlashResult */ - 0x2D, 0x68, /* LDR R5, [R5] */ - /* Breakpoint here */ - 0x00, 0xBE, /* BKPT #0 */ - - /* The following address pointers assume, that the code is running from */ - /* SRAM basic-address + 8.These address pointers will be patched, if a */ - /* different start address in RAM is used (e.g. for Flash type 2)! */ - /* Default SRAM basic-address is 0x20000000. */ - 0x00, 0x00, 0x00, 0x20, /* u32DummyRead address in RAM (0x20000000) */ - 0x04, 0x00, 0x00, 0x20 /* u32FlashResult address in RAM (0x20000004) */ - }; - - LOG_INFO("Fujitsu MB9[A/B]FXXX: FLASH Write ..."); - - /* disable HW watchdog */ - retval = target_write_u32(target, 0x40011C00, 0x1ACCE551); - if (retval != ERROR_OK) - return retval; - - retval = target_write_u32(target, 0x40011C00, 0xE5331AAE); - if (retval != ERROR_OK) - return retval; - - retval = target_write_u32(target, 0x40011008, 0x00000000); - if (retval != ERROR_OK) - return retval; - - count = count / 2; /* number bytes -> number halfwords */ - - /* 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 and variables with flash programming code */ - if (target_alloc_working_area(target, sizeof(fm3_flash_write_code) + 8, - &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 + 8, - sizeof(fm3_flash_write_code), fm3_flash_write_code); - if (retval != ERROR_OK) - return retval; - - /* Patching 'local variable address' */ - /* Algorithm: u32DummyRead: */ - retval = target_write_u32(target, (write_algorithm->address + 8) - + sizeof(fm3_flash_write_code) - 8, (write_algorithm->address)); - if (retval != ERROR_OK) - return retval; - /* Algorithm: u32FlashResult: */ - retval = target_write_u32(target, (write_algorithm->address + 8) - + sizeof(fm3_flash_write_code) - 4, (write_algorithm->address) + 4); - if (retval != ERROR_OK) - return retval; - - - - /* memory buffer */ - while (target_alloc_working_area(target, buffer_size, &source) != ERROR_OK) { - buffer_size /= 2; - if (buffer_size <= 256) { - /* free working area, write algorithm already allocated */ - target_free_working_area(target, write_algorithm); - - 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; - - init_reg_param(®_params[0], "r0", 32, PARAM_OUT); /* source start address */ - init_reg_param(®_params[1], "r1", 32, PARAM_OUT); /* target start address */ - init_reg_param(®_params[2], "r2", 32, PARAM_OUT); /* number of halfwords to program */ - init_reg_param(®_params[3], "r3", 32, PARAM_OUT); /* Flash Sequence address 1 */ - init_reg_param(®_params[4], "r4", 32, PARAM_OUT); /* Flash Sequence address 1 */ - init_reg_param(®_params[5], "r5", 32, PARAM_IN); /* result */ - - /* write code buffer and use Flash programming code within fm3 */ - /* Set breakpoint to 0 with time-out of 1000 ms */ - while (count > 0) { - uint32_t thisrun_count = (count > (buffer_size / 2)) ? (buffer_size / 2) : count; - - retval = target_write_buffer(target, source->address, thisrun_count * 2, buffer); - if (retval != ERROR_OK) - break; - - 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); - buf_set_u32(reg_params[3].value, 0, 32, u32FlashSeqAddress1); - buf_set_u32(reg_params[4].value, 0, 32, u32FlashSeqAddress2); - - retval = target_run_algorithm(target, 0, NULL, 6, reg_params, - (write_algorithm->address + 8), 0, 1000, &armv7m_info); - if (retval != ERROR_OK) { - LOG_ERROR("Error executing fm3 Flash programming algorithm"); - retval = ERROR_FLASH_OPERATION_FAILED; - break; - } - - if (buf_get_u32(reg_params[5].value, 0, 32) != ERROR_OK) { - LOG_ERROR("Fujitsu MB9[A/B]FXXX: Flash programming ERROR (Timeout) -> Reg R3: %" PRIx32, - buf_get_u32(reg_params[5].value, 0, 32)); - retval = ERROR_FLASH_OPERATION_FAILED; - break; - } - - buffer += thisrun_count * 2; - address += thisrun_count * 2; - count -= thisrun_count; - } - - target_free_working_area(target, source); - target_free_working_area(target, write_algorithm); - - 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]); - destroy_reg_param(®_params[5]); - - return retval; -} - -static int fm3_probe(struct flash_bank *bank) -{ - struct fm3_flash_bank *fm3_info = bank->driver_priv; - uint16_t num_pages; - - if (bank->target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - -/* - -- page-- start -- blocksize - mpu - totalFlash -- - page0 0x00000 16k - page1 0x04000 16k - page2 0x08000 96k ___ fxx3 128k Flash - page3 0x20000 128k ___ fxx4 256k Flash - page4 0x40000 128k ___ fxx5 384k Flash - page5 0x60000 128k ___ fxx6 512k Flash ------------------------ - page6 0x80000 128k - page7 0xa0000 128k ___ fxx7 256k Flash - page8 0xc0000 128k - page9 0xe0000 128k ___ fxx8 256k Flash - */ - - num_pages = 10; /* max number of Flash pages for malloc */ - fm3_info->probed = 0; - - bank->sectors = malloc(sizeof(struct flash_sector) * num_pages); - bank->base = 0x00000000; - bank->size = 32 * 1024; /* bytes */ - - bank->sectors[0].offset = 0; - bank->sectors[0].size = 16 * 1024; - bank->sectors[0].is_erased = -1; - bank->sectors[0].is_protected = -1; - - bank->sectors[1].offset = 0x4000; - bank->sectors[1].size = 16 * 1024; - bank->sectors[1].is_erased = -1; - bank->sectors[1].is_protected = -1; - - if ((fm3_info->variant == mb9bfxx1) - || (fm3_info->variant == mb9afxx1)) { - num_pages = 3; - bank->size = 64 * 1024; /* bytes */ - bank->num_sectors = num_pages; - - bank->sectors[2].offset = 0x8000; - bank->sectors[2].size = 32 * 1024; - bank->sectors[2].is_erased = -1; - bank->sectors[2].is_protected = -1; - } - - if ((fm3_info->variant == mb9bfxx2) - || (fm3_info->variant == mb9bfxx4) - || (fm3_info->variant == mb9bfxx5) - || (fm3_info->variant == mb9bfxx6) - || (fm3_info->variant == mb9bfxx7) - || (fm3_info->variant == mb9bfxx8) - || (fm3_info->variant == mb9afxx2) - || (fm3_info->variant == mb9afxx4) - || (fm3_info->variant == mb9afxx5) - || (fm3_info->variant == mb9afxx6) - || (fm3_info->variant == mb9afxx7) - || (fm3_info->variant == mb9afxx8)) { - num_pages = 3; - bank->size = 128 * 1024; /* bytes */ - bank->num_sectors = num_pages; - - bank->sectors[2].offset = 0x8000; - bank->sectors[2].size = 96 * 1024; - bank->sectors[2].is_erased = -1; - bank->sectors[2].is_protected = -1; - } - - if ((fm3_info->variant == mb9bfxx4) - || (fm3_info->variant == mb9bfxx5) - || (fm3_info->variant == mb9bfxx6) - || (fm3_info->variant == mb9bfxx7) - || (fm3_info->variant == mb9bfxx8) - || (fm3_info->variant == mb9afxx4) - || (fm3_info->variant == mb9afxx5) - || (fm3_info->variant == mb9afxx6) - || (fm3_info->variant == mb9afxx7) - || (fm3_info->variant == mb9afxx8)) { - num_pages = 4; - bank->size = 256 * 1024; /* bytes */ - bank->num_sectors = num_pages; - - bank->sectors[3].offset = 0x20000; - bank->sectors[3].size = 128 * 1024; - bank->sectors[3].is_erased = -1; - bank->sectors[3].is_protected = -1; - } - - if ((fm3_info->variant == mb9bfxx5) - || (fm3_info->variant == mb9bfxx6) - || (fm3_info->variant == mb9bfxx7) - || (fm3_info->variant == mb9bfxx8) - || (fm3_info->variant == mb9afxx5) - || (fm3_info->variant == mb9afxx6) - || (fm3_info->variant == mb9afxx7) - || (fm3_info->variant == mb9afxx8)) { - num_pages = 5; - bank->size = 384 * 1024; /* bytes */ - bank->num_sectors = num_pages; - - bank->sectors[4].offset = 0x40000; - bank->sectors[4].size = 128 * 1024; - bank->sectors[4].is_erased = -1; - bank->sectors[4].is_protected = -1; - } - - if ((fm3_info->variant == mb9bfxx6) - || (fm3_info->variant == mb9bfxx7) - || (fm3_info->variant == mb9bfxx8) - || (fm3_info->variant == mb9afxx6) - || (fm3_info->variant == mb9afxx7) - || (fm3_info->variant == mb9afxx8)) { - num_pages = 6; - bank->size = 512 * 1024; /* bytes */ - bank->num_sectors = num_pages; - - bank->sectors[5].offset = 0x60000; - bank->sectors[5].size = 128 * 1024; - bank->sectors[5].is_erased = -1; - bank->sectors[5].is_protected = -1; - } - - if ((fm3_info->variant == mb9bfxx7) - || (fm3_info->variant == mb9bfxx8) - || (fm3_info->variant == mb9afxx7) - || (fm3_info->variant == mb9afxx8)) { - num_pages = 8; - bank->size = 768 * 1024; /* bytes */ - bank->num_sectors = num_pages; - - bank->sectors[6].offset = 0x80000; - bank->sectors[6].size = 128 * 1024; - bank->sectors[6].is_erased = -1; - bank->sectors[6].is_protected = -1; - - bank->sectors[7].offset = 0xa0000; - bank->sectors[7].size = 128 * 1024; - bank->sectors[7].is_erased = -1; - bank->sectors[7].is_protected = -1; - } - - if ((fm3_info->variant == mb9bfxx8) - || (fm3_info->variant == mb9afxx8)) { - num_pages = 10; - bank->size = 1024 * 1024; /* bytes */ - bank->num_sectors = num_pages; - - bank->sectors[8].offset = 0xc0000; - bank->sectors[8].size = 128 * 1024; - bank->sectors[8].is_erased = -1; - bank->sectors[8].is_protected = -1; - - bank->sectors[9].offset = 0xe0000; - bank->sectors[9].size = 128 * 1024; - bank->sectors[9].is_erased = -1; - bank->sectors[9].is_protected = -1; - } - - fm3_info->probed = 1; - - return ERROR_OK; -} - -static int fm3_auto_probe(struct flash_bank *bank) -{ - struct fm3_flash_bank *fm3_info = bank->driver_priv; - if (fm3_info->probed) - return ERROR_OK; - return fm3_probe(bank); -} - -/* Chip erase */ -static int fm3_chip_erase(struct flash_bank *bank) -{ - struct target *target = bank->target; - struct fm3_flash_bank *fm3_info2 = bank->driver_priv; - int retval = ERROR_OK; - uint32_t u32DummyRead; - uint32_t u32FlashType; - uint32_t u32FlashSeqAddress1; - uint32_t u32FlashSeqAddress2; - - struct working_area *write_algorithm; - struct reg_param reg_params[3]; - struct armv7m_algorithm armv7m_info; - - u32FlashType = (uint32_t) fm3_info2->flashtype; - - if (u32FlashType == fm3_flash_type1) { - LOG_INFO("*** Erasing mb9bfxxx type"); - u32FlashSeqAddress1 = 0x00001550; - u32FlashSeqAddress2 = 0x00000AA8; - } else if (u32FlashType == fm3_flash_type2) { - LOG_INFO("*** Erasing mb9afxxx type"); - u32FlashSeqAddress1 = 0x00000AA8; - u32FlashSeqAddress2 = 0x00000554; - } else { - LOG_ERROR("Flash/Device type unknown!"); - return ERROR_FLASH_OPERATION_FAILED; - } - - if (target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - /* RAMCODE used for fm3 Flash chip erase: */ - /* R0 keeps Flash Sequence address 1 (u32FlashSeq1) */ - /* R1 keeps Flash Sequence address 2 (u32FlashSeq2) */ - static const uint8_t fm3_flash_erase_chip_code[] = { - /* *(uint16_t*)u32FlashSeq1 = 0xAA; */ - 0xAA, 0x22, /* MOVS R2, #0xAA */ - 0x02, 0x80, /* STRH R2, [R0, #0] */ - /* *(uint16_t*)u32FlashSeq2 = 0x55; */ - 0x55, 0x23, /* MOVS R3, #0x55 */ - 0x0B, 0x80, /* STRH R3, [R1, #0] */ - /* *(uint16_t*)u32FlashSeq1 = 0x80; */ - 0x80, 0x24, /* MOVS R4, #0x80 */ - 0x04, 0x80, /* STRH R4, [R0, #0] */ - /* *(uint16_t*)u32FlashSeq1 = 0xAA; */ - 0x02, 0x80, /* STRH R2, [R0, #0] */ - /* *(uint16_t*)u32FlashSeq2 = 0x55; */ - 0x0B, 0x80, /* STRH R3, [R1, #0] */ - /* Chip_Erase Command 0x10 */ - /* *(uint16_t*)u32FlashSeq1 = 0x10; */ - 0x10, 0x21, /* MOVS R1, #0x10 */ - 0x01, 0x80, /* STRH R1, [R0, #0] */ - /* End Code */ - 0x00, 0xBE, /* BKPT #0 */ - }; - - LOG_INFO("Fujitsu MB9[A/B]xxx: Chip Erase ... (may take several seconds)"); - - /* disable HW watchdog */ - retval = target_write_u32(target, 0x40011C00, 0x1ACCE551); - if (retval != ERROR_OK) - return retval; - - retval = target_write_u32(target, 0x40011C00, 0xE5331AAE); - if (retval != ERROR_OK) - return retval; - - retval = target_write_u32(target, 0x40011008, 0x00000000); - if (retval != ERROR_OK) - return retval; - - /* FASZR = 0x01, Enables CPU Programming Mode (16-bit Flash access) */ - retval = target_write_u32(target, 0x40000000, 0x0001); - if (retval != ERROR_OK) - return retval; - - /* dummy read of FASZR */ - retval = target_read_u32(target, 0x40000000, &u32DummyRead); - if (retval != ERROR_OK) - return retval; - - /* allocate working area with flash chip erase code */ - if (target_alloc_working_area(target, sizeof(fm3_flash_erase_chip_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(fm3_flash_erase_chip_code), fm3_flash_erase_chip_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); /* u32FlashSeqAddress1 */ - init_reg_param(®_params[1], "r1", 32, PARAM_OUT); /* u32FlashSeqAddress2 */ - - buf_set_u32(reg_params[0].value, 0, 32, u32FlashSeqAddress1); - buf_set_u32(reg_params[1].value, 0, 32, u32FlashSeqAddress2); - - retval = target_run_algorithm(target, 0, NULL, 2, reg_params, - write_algorithm->address, 0, 100000, &armv7m_info); - if (retval != ERROR_OK) { - LOG_ERROR("Error executing flash erase programming algorithm"); - retval = ERROR_FLASH_OPERATION_FAILED; - return retval; - } - - target_free_working_area(target, write_algorithm); - - destroy_reg_param(®_params[0]); - destroy_reg_param(®_params[1]); - - retval = fm3_busy_wait(target, u32FlashSeqAddress2, 20000); /* 20s timeout */ - if (retval != ERROR_OK) - return retval; - - /* FASZR = 0x02, Re-enables CPU Run Mode (32-bit Flash access) */ - retval = target_write_u32(target, 0x40000000, 0x0002); - if (retval != ERROR_OK) - return retval; - - retval = target_read_u32(target, 0x40000000, &u32DummyRead); /* dummy read of FASZR */ - - return retval; -} - -COMMAND_HANDLER(fm3_handle_chip_erase_command) -{ - int i; - - 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; - - if (fm3_chip_erase(bank) == ERROR_OK) { - /* set all sectors as erased */ - for (i = 0; i < bank->num_sectors; i++) - bank->sectors[i].is_erased = 1; - - command_print(CMD_CTX, "fm3 chip erase complete"); - } else { - command_print(CMD_CTX, "fm3 chip erase failed"); - } - - return ERROR_OK; -} - -static const struct command_registration fm3_exec_command_handlers[] = { - { - .name = "chip_erase", - .usage = "", - .handler = fm3_handle_chip_erase_command, - .mode = COMMAND_EXEC, - .help = "Erase entire Flash device.", - }, - COMMAND_REGISTRATION_DONE -}; - -static const struct command_registration fm3_command_handlers[] = { - { - .name = "fm3", - .mode = COMMAND_ANY, - .help = "fm3 Flash command group", - .usage = "", - .chain = fm3_exec_command_handlers, - }, - COMMAND_REGISTRATION_DONE -}; - -struct flash_driver fm3_flash = { - .name = "fm3", - .commands = fm3_command_handlers, - .flash_bank_command = fm3_flash_bank_command, - .erase = fm3_erase, - .write = fm3_write_block, - .probe = fm3_probe, - .auto_probe = fm3_auto_probe, - .erase_check = default_flash_blank_check, -}; diff --git a/src/flash/nor/fm4.c b/src/flash/nor/fm4.c deleted file mode 100644 index c348c1d61..000000000 --- a/src/flash/nor/fm4.c +++ /dev/null @@ -1,722 +0,0 @@ -/* - * Spansion FM4 flash - * - * Copyright (c) 2015 Andreas Färber - * - * Based on S6E2DH_MN709-00013 for S6E2DH/DF/D5/D3 series - * Based on S6E2CC_MN709-00007 for S6E2CC/C5/C4/C3/C2/C1 series - * Based on MB9B560R_MN709-00005 for MB9BFx66/x67/x68 series - * Based on MB9B560L_MN709-00006 for MB9BFx64/x65/x66 series - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "imp.h" -#include -#include -#include - -#define FLASH_BASE 0x40000000 -#define FASZR (FLASH_BASE + 0x000) -#define DFCTRLR (FLASH_BASE + 0x030) -#define DFCTRLR_DFE (1UL << 0) - -#define WDG_BASE 0x40011000 -#define WDG_CTL (WDG_BASE + 0x008) -#define WDG_LCK (WDG_BASE + 0xC00) - -enum fm4_variant { - mb9bfx64, - mb9bfx65, - mb9bfx66, - mb9bfx67, - mb9bfx68, - - s6e2cx8, - s6e2cx9, - s6e2cxa, - - s6e2dx, -}; - -struct fm4_flash_bank { - enum fm4_variant variant; - int macro_nr; - bool probed; -}; - -static int fm4_disable_hw_watchdog(struct target *target) -{ - int retval; - - retval = target_write_u32(target, WDG_LCK, 0x1ACCE551); - if (retval != ERROR_OK) - return retval; - - retval = target_write_u32(target, WDG_LCK, 0xE5331AAE); - if (retval != ERROR_OK) - return retval; - - retval = target_write_u32(target, WDG_CTL, 0); - if (retval != ERROR_OK) - return retval; - - return ERROR_OK; -} - -static int fm4_enter_flash_cpu_programming_mode(struct target *target) -{ - uint32_t u32_value; - int retval; - - /* FASZR ASZ = CPU programming mode */ - retval = target_write_u32(target, FASZR, 0x00000001); - if (retval != ERROR_OK) - return retval; - retval = target_read_u32(target, FASZR, &u32_value); - if (retval != ERROR_OK) - return retval; - - return ERROR_OK; -} - -static int fm4_enter_flash_cpu_rom_mode(struct target *target) -{ - uint32_t u32_value; - int retval; - - /* FASZR ASZ = CPU ROM mode */ - retval = target_write_u32(target, FASZR, 0x00000002); - if (retval != ERROR_OK) - return retval; - retval = target_read_u32(target, FASZR, &u32_value); - if (retval != ERROR_OK) - return retval; - - return ERROR_OK; -} - -static int fm4_flash_erase(struct flash_bank *bank, int first, int last) -{ - struct target *target = bank->target; - struct working_area *workarea; - struct reg_param reg_params[4]; - struct armv7m_algorithm armv7m_algo; - unsigned i; - int retval, sector; - const uint8_t erase_sector_code[] = { -#include "../../../contrib/loaders/flash/fm4/erase.inc" - }; - - if (target->state != TARGET_HALTED) { - LOG_WARNING("Cannot communicate... target not halted."); - return ERROR_TARGET_NOT_HALTED; - } - - LOG_DEBUG("Spansion FM4 erase sectors %d to %d", first, last); - - retval = fm4_disable_hw_watchdog(target); - if (retval != ERROR_OK) - return retval; - - retval = fm4_enter_flash_cpu_programming_mode(target); - if (retval != ERROR_OK) - return retval; - - retval = target_alloc_working_area(target, sizeof(erase_sector_code), - &workarea); - if (retval != ERROR_OK) { - LOG_ERROR("No working area available."); - retval = ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - goto err_alloc_code; - } - retval = target_write_buffer(target, workarea->address, - sizeof(erase_sector_code), erase_sector_code); - if (retval != ERROR_OK) - goto err_write_code; - - armv7m_algo.common_magic = ARMV7M_COMMON_MAGIC; - armv7m_algo.core_mode = ARM_MODE_THREAD; - - init_reg_param(®_params[0], "r0", 32, PARAM_OUT); - init_reg_param(®_params[1], "r1", 32, PARAM_OUT); - init_reg_param(®_params[2], "r2", 32, PARAM_OUT); - init_reg_param(®_params[3], "r3", 32, PARAM_IN); - - for (sector = first; sector <= last; sector++) { - uint32_t addr = bank->base + bank->sectors[sector].offset; - uint32_t result; - - buf_set_u32(reg_params[0].value, 0, 32, (addr & ~0xffff) | 0xAA8); - buf_set_u32(reg_params[1].value, 0, 32, (addr & ~0xffff) | 0x554); - buf_set_u32(reg_params[2].value, 0, 32, addr); - - retval = target_run_algorithm(target, - 0, NULL, - ARRAY_SIZE(reg_params), reg_params, - workarea->address, 0, - 1000, &armv7m_algo); - if (retval != ERROR_OK) { - LOG_ERROR("Error executing flash sector erase " - "programming algorithm"); - retval = ERROR_FLASH_OPERATION_FAILED; - goto err_run; - } - - result = buf_get_u32(reg_params[3].value, 0, 32); - if (result == 2) { - LOG_ERROR("Timeout error from flash sector erase programming algorithm"); - retval = ERROR_FLASH_OPERATION_FAILED; - goto err_run_ret; - } else if (result != 0) { - LOG_ERROR("Unexpected error %d from flash sector erase programming algorithm", result); - retval = ERROR_FLASH_OPERATION_FAILED; - goto err_run_ret; - } else - retval = ERROR_OK; - - bank->sectors[sector].is_erased = 1; - } - -err_run_ret: -err_run: - for (i = 0; i < ARRAY_SIZE(reg_params); i++) - destroy_reg_param(®_params[i]); - -err_write_code: - target_free_working_area(target, workarea); - -err_alloc_code: - if (retval != ERROR_OK) - fm4_enter_flash_cpu_rom_mode(target); - else - retval = fm4_enter_flash_cpu_rom_mode(target); - - return retval; -} - -static int fm4_flash_write(struct flash_bank *bank, const uint8_t *buffer, - uint32_t offset, uint32_t byte_count) -{ - struct target *target = bank->target; - struct working_area *code_workarea, *data_workarea; - struct reg_param reg_params[6]; - struct armv7m_algorithm armv7m_algo; - uint32_t halfword_count = DIV_ROUND_UP(byte_count, 2); - uint32_t result; - unsigned i; - int retval; - const uint8_t write_block_code[] = { -#include "../../../contrib/loaders/flash/fm4/write.inc" - }; - - LOG_DEBUG("Spansion FM4 write at 0x%08" PRIx32 " (%" PRId32 " bytes)", - offset, byte_count); - - if (offset & 0x1) { - LOG_ERROR("offset 0x%" PRIx32 " breaks required 2-byte alignment", - offset); - return ERROR_FLASH_DST_BREAKS_ALIGNMENT; - } - if (byte_count & 0x1) { - LOG_WARNING("length %" PRId32 " is not 2-byte aligned, rounding up", - byte_count); - } - - if (target->state != TARGET_HALTED) { - LOG_WARNING("Cannot communicate... target not halted."); - return ERROR_TARGET_NOT_HALTED; - } - - retval = fm4_disable_hw_watchdog(target); - if (retval != ERROR_OK) - return retval; - - retval = target_alloc_working_area(target, sizeof(write_block_code), - &code_workarea); - if (retval != ERROR_OK) { - LOG_ERROR("No working area available for write code."); - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - } - retval = target_write_buffer(target, code_workarea->address, - sizeof(write_block_code), write_block_code); - if (retval != ERROR_OK) - goto err_write_code; - - retval = target_alloc_working_area(target, - MIN(halfword_count * 2, target_get_working_area_avail(target)), - &data_workarea); - if (retval != ERROR_OK) { - LOG_ERROR("No working area available for write data."); - retval = ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - goto err_alloc_data; - } - - armv7m_algo.common_magic = ARMV7M_COMMON_MAGIC; - armv7m_algo.core_mode = ARM_MODE_THREAD; - - init_reg_param(®_params[0], "r0", 32, PARAM_OUT); - init_reg_param(®_params[1], "r1", 32, PARAM_OUT); - 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); - init_reg_param(®_params[5], "r5", 32, PARAM_IN); - - retval = fm4_enter_flash_cpu_programming_mode(target); - if (retval != ERROR_OK) - goto err_flash_mode; - - while (byte_count > 0) { - uint32_t halfwords = MIN(halfword_count, data_workarea->size / 2); - uint32_t addr = bank->base + offset; - - LOG_DEBUG("copying %" PRId32 " bytes to SRAM 0x%08" PRIx32, - MIN(halfwords * 2, byte_count), data_workarea->address); - - retval = target_write_buffer(target, data_workarea->address, - MIN(halfwords * 2, byte_count), buffer); - if (retval != ERROR_OK) { - LOG_ERROR("Error writing data buffer"); - retval = ERROR_FLASH_OPERATION_FAILED; - goto err_write_data; - } - - LOG_DEBUG("writing 0x%08" PRIx32 "-0x%08" PRIx32 " (%" PRId32 "x)", - addr, addr + halfwords * 2 - 1, halfwords); - - buf_set_u32(reg_params[0].value, 0, 32, (addr & ~0xffff) | 0xAA8); - buf_set_u32(reg_params[1].value, 0, 32, (addr & ~0xffff) | 0x554); - buf_set_u32(reg_params[2].value, 0, 32, addr); - buf_set_u32(reg_params[3].value, 0, 32, data_workarea->address); - buf_set_u32(reg_params[4].value, 0, 32, halfwords); - - retval = target_run_algorithm(target, - 0, NULL, - ARRAY_SIZE(reg_params), reg_params, - code_workarea->address, 0, - 5 * 60 * 1000, &armv7m_algo); - if (retval != ERROR_OK) { - LOG_ERROR("Error executing flash sector erase " - "programming algorithm"); - retval = ERROR_FLASH_OPERATION_FAILED; - goto err_run; - } - - result = buf_get_u32(reg_params[5].value, 0, 32); - if (result == 2) { - LOG_ERROR("Timeout error from flash write " - "programming algorithm"); - retval = ERROR_FLASH_OPERATION_FAILED; - goto err_run_ret; - } else if (result != 0) { - LOG_ERROR("Unexpected error %d from flash write " - "programming algorithm", result); - retval = ERROR_FLASH_OPERATION_FAILED; - goto err_run_ret; - } else - retval = ERROR_OK; - - halfword_count -= halfwords; - offset += halfwords * 2; - buffer += halfwords * 2; - byte_count -= MIN(halfwords * 2, byte_count); - } - -err_run_ret: -err_run: -err_write_data: - retval = fm4_enter_flash_cpu_rom_mode(target); - -err_flash_mode: - for (i = 0; i < ARRAY_SIZE(reg_params); i++) - destroy_reg_param(®_params[i]); - - target_free_working_area(target, data_workarea); -err_alloc_data: -err_write_code: - target_free_working_area(target, code_workarea); - - return retval; -} - -static int mb9bf_probe(struct flash_bank *bank) -{ - struct fm4_flash_bank *fm4_bank = bank->driver_priv; - uint32_t flash_addr = bank->base; - int i; - - switch (fm4_bank->variant) { - case mb9bfx64: - bank->num_sectors = 8; - break; - case mb9bfx65: - bank->num_sectors = 10; - break; - case mb9bfx66: - bank->num_sectors = 12; - break; - case mb9bfx67: - bank->num_sectors = 16; - break; - case mb9bfx68: - bank->num_sectors = 20; - break; - default: - return ERROR_FLASH_OPER_UNSUPPORTED; - } - - LOG_DEBUG("%d sectors", bank->num_sectors); - bank->sectors = calloc(bank->num_sectors, - sizeof(struct flash_sector)); - for (i = 0; i < bank->num_sectors; i++) { - if (i < 4) - bank->sectors[i].size = 8 * 1024; - else if (i == 4) - bank->sectors[i].size = 32 * 1024; - else - bank->sectors[i].size = 64 * 1024; - bank->sectors[i].offset = flash_addr - bank->base; - bank->sectors[i].is_erased = -1; - bank->sectors[i].is_protected = -1; - - bank->size += bank->sectors[i].size; - flash_addr += bank->sectors[i].size; - } - - return ERROR_OK; -} - -static void s6e2cc_init_sector(struct flash_sector *sector, int sa) -{ - if (sa < 8) - sector->size = 8 * 1024; - else if (sa == 8) - sector->size = 32 * 1024; - else - sector->size = 64 * 1024; - - sector->is_erased = -1; - sector->is_protected = -1; -} - -static int s6e2cc_probe(struct flash_bank *bank) -{ - struct target *target = bank->target; - struct fm4_flash_bank *fm4_bank = bank->driver_priv; - uint32_t u32_value; - uint32_t flash_addr = bank->base; - int i, retval, num_sectors, num_extra_sectors; - - retval = target_read_u32(target, DFCTRLR, &u32_value); - if (retval != ERROR_OK) - return retval; - if (u32_value & DFCTRLR_DFE) { - LOG_WARNING("Dual Flash mode is not implemented."); - return ERROR_FLASH_OPER_UNSUPPORTED; - } - - switch (fm4_bank->variant) { - case s6e2cx8: - num_sectors = (fm4_bank->macro_nr == 0) ? 20 : 0; - break; - case s6e2cx9: - num_sectors = (fm4_bank->macro_nr == 0) ? 20 : 12; - break; - case s6e2cxa: - num_sectors = 20; - break; - default: - return ERROR_FLASH_OPER_UNSUPPORTED; - } - num_extra_sectors = (fm4_bank->macro_nr == 0) ? 1 : 4; - bank->num_sectors = num_sectors + num_extra_sectors; - - LOG_DEBUG("%d sectors", bank->num_sectors); - bank->sectors = calloc(bank->num_sectors, - sizeof(struct flash_sector)); - for (i = 0; i < num_sectors; i++) { - int sa = 4 + i; - bank->sectors[i].offset = flash_addr - bank->base; - s6e2cc_init_sector(&bank->sectors[i], sa); - - bank->size += bank->sectors[i].size; - flash_addr += bank->sectors[i].size; - } - - flash_addr = (fm4_bank->macro_nr == 0) ? 0x00406000 : 0x00408000; - for (; i < bank->num_sectors; i++) { - int sa = 4 - num_extra_sectors + (i - num_sectors); - bank->sectors[i].offset = flash_addr - bank->base; - s6e2cc_init_sector(&bank->sectors[i], sa); - - /* - * Don't increase bank->size for these sectors - * to avoid an overlap between Flash Macros #0 and #1. - */ - flash_addr += bank->sectors[i].size; - } - - return ERROR_OK; -} - -static int s6e2dh_probe(struct flash_bank *bank) -{ - uint32_t flash_addr = bank->base; - int i; - - bank->num_sectors = 10; - bank->sectors = calloc(bank->num_sectors, - sizeof(struct flash_sector)); - for (i = 0; i < bank->num_sectors; i++) { - if (i < 4) - bank->sectors[i].size = 8 * 1024; - else if (i == 4) - bank->sectors[i].size = 32 * 1024; - else - bank->sectors[i].size = 64 * 1024; - bank->sectors[i].offset = flash_addr - bank->base; - bank->sectors[i].is_erased = -1; - bank->sectors[i].is_protected = -1; - - bank->size += bank->sectors[i].size; - flash_addr += bank->sectors[i].size; - } - - return ERROR_OK; -} - -static int fm4_probe(struct flash_bank *bank) -{ - struct fm4_flash_bank *fm4_bank = bank->driver_priv; - int retval; - - if (fm4_bank->probed) - return ERROR_OK; - - if (bank->target->state != TARGET_HALTED) { - LOG_WARNING("Cannot communicate... target not halted."); - return ERROR_TARGET_NOT_HALTED; - } - - switch (fm4_bank->variant) { - case mb9bfx64: - case mb9bfx65: - case mb9bfx66: - case mb9bfx67: - case mb9bfx68: - retval = mb9bf_probe(bank); - break; - case s6e2cx8: - case s6e2cx9: - case s6e2cxa: - retval = s6e2cc_probe(bank); - break; - case s6e2dx: - retval = s6e2dh_probe(bank); - break; - default: - return ERROR_FLASH_OPER_UNSUPPORTED; - } - if (retval != ERROR_OK) - return retval; - - fm4_bank->probed = true; - - return ERROR_OK; -} - -static int fm4_auto_probe(struct flash_bank *bank) -{ - struct fm4_flash_bank *fm4_bank = bank->driver_priv; - - if (fm4_bank->probed) - return ERROR_OK; - - return fm4_probe(bank); -} - -static int fm4_protect_check(struct flash_bank *bank) -{ - return ERROR_OK; -} - -static int fm4_get_info_command(struct flash_bank *bank, char *buf, int buf_size) -{ - struct fm4_flash_bank *fm4_bank = bank->driver_priv; - const char *name; - - if (bank->target->state != TARGET_HALTED) { - LOG_WARNING("Cannot communicate... target not halted."); - return ERROR_TARGET_NOT_HALTED; - } - - switch (fm4_bank->variant) { - case mb9bfx64: - name = "MB9BFx64"; - break; - case mb9bfx65: - name = "MB9BFx65"; - break; - case mb9bfx66: - name = "MB9BFx66"; - break; - case mb9bfx67: - name = "MB9BFx67"; - break; - case mb9bfx68: - name = "MB9BFx68"; - break; - case s6e2cx8: - name = "S6E2Cx8"; - break; - case s6e2cx9: - name = "S6E2Cx9"; - break; - case s6e2cxa: - name = "S6E2CxA"; - break; - case s6e2dx: - name = "S6E2Dx"; - break; - default: - name = "unknown"; - break; - } - - switch (fm4_bank->variant) { - case s6e2cx8: - case s6e2cx9: - case s6e2cxa: - snprintf(buf, buf_size, "%s MainFlash Macro #%i", - name, fm4_bank->macro_nr); - break; - default: - snprintf(buf, buf_size, "%s MainFlash", name); - break; - } - - return ERROR_OK; -} - -static bool fm4_name_match(const char *s, const char *pattern) -{ - int i = 0; - - while (s[i]) { - /* If the match string is shorter, ignore excess */ - if (!pattern[i]) - return true; - /* Use x as wildcard */ - if (pattern[i] != 'x' && tolower(s[i]) != tolower(pattern[i])) - return false; - i++; - } - return true; -} - -static int mb9bf_bank_setup(struct flash_bank *bank, const char *variant) -{ - struct fm4_flash_bank *fm4_bank = bank->driver_priv; - - if (fm4_name_match(variant, "MB9BFx64")) { - fm4_bank->variant = mb9bfx64; - } else if (fm4_name_match(variant, "MB9BFx65")) { - fm4_bank->variant = mb9bfx65; - } else if (fm4_name_match(variant, "MB9BFx66")) { - fm4_bank->variant = mb9bfx66; - } else if (fm4_name_match(variant, "MB9BFx67")) { - fm4_bank->variant = mb9bfx67; - } else if (fm4_name_match(variant, "MB9BFx68")) { - fm4_bank->variant = mb9bfx68; - } else { - LOG_WARNING("MB9BF variant %s not recognized.", variant); - return ERROR_FLASH_OPER_UNSUPPORTED; - } - - return ERROR_OK; -} - -static int s6e2cc_bank_setup(struct flash_bank *bank, const char *variant) -{ - struct fm4_flash_bank *fm4_bank = bank->driver_priv; - - if (fm4_name_match(variant, "S6E2Cx8")) { - fm4_bank->variant = s6e2cx8; - } else if (fm4_name_match(variant, "S6E2Cx9")) { - fm4_bank->variant = s6e2cx9; - } else if (fm4_name_match(variant, "S6E2CxA")) { - fm4_bank->variant = s6e2cxa; - } else { - LOG_WARNING("S6E2CC variant %s not recognized.", variant); - return ERROR_FLASH_OPER_UNSUPPORTED; - } - - return ERROR_OK; -} - -FLASH_BANK_COMMAND_HANDLER(fm4_flash_bank_command) -{ - struct fm4_flash_bank *fm4_bank; - const char *variant; - int ret; - - if (CMD_ARGC < 7) - return ERROR_COMMAND_SYNTAX_ERROR; - - variant = CMD_ARGV[6]; - - fm4_bank = malloc(sizeof(struct fm4_flash_bank)); - if (!fm4_bank) - return ERROR_FLASH_OPERATION_FAILED; - - fm4_bank->probed = false; - fm4_bank->macro_nr = (bank->base == 0x00000000) ? 0 : 1; - - bank->driver_priv = fm4_bank; - - if (fm4_name_match(variant, "MB9BF")) - ret = mb9bf_bank_setup(bank, variant); - else if (fm4_name_match(variant, "S6E2Cx")) - ret = s6e2cc_bank_setup(bank, variant); - else if (fm4_name_match(variant, "S6E2Dx")) { - fm4_bank->variant = s6e2dx; - ret = ERROR_OK; - } else { - LOG_WARNING("Family %s not recognized.", variant); - ret = ERROR_FLASH_OPER_UNSUPPORTED; - } - if (ret != ERROR_OK) - free(fm4_bank); - return ret; -} - -static const struct command_registration fm4_exec_command_handlers[] = { - COMMAND_REGISTRATION_DONE -}; - -static const struct command_registration fm4_command_handlers[] = { - { - .name = "fm4", - .mode = COMMAND_ANY, - .help = "fm4 flash command group", - .usage = "", - .chain = fm4_exec_command_handlers, - }, - COMMAND_REGISTRATION_DONE -}; - -struct flash_driver fm4_flash = { - .name = "fm4", - .commands = fm4_command_handlers, - .flash_bank_command = fm4_flash_bank_command, - .info = fm4_get_info_command, - .probe = fm4_probe, - .auto_probe = fm4_auto_probe, - .protect_check = fm4_protect_check, - .read = default_flash_read, - .erase = fm4_flash_erase, - .erase_check = default_flash_blank_check, - .write = fm4_flash_write, -}; diff --git a/src/flash/nor/imp.h b/src/flash/nor/imp.h deleted file mode 100644 index 87475a39c..000000000 --- a/src/flash/nor/imp.h +++ /dev/null @@ -1,49 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2009 Zachary T Welch * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 OPENOCD_FLASH_NOR_IMP_H -#define OPENOCD_FLASH_NOR_IMP_H - -/* this is an internal header */ -#include "core.h" -#include "driver.h" -/* almost all drivers will need this file */ -#include - -/** - * Adds a new NOR bank to the global list of banks. - * @param bank The bank that should be added. - */ -void flash_bank_add(struct flash_bank *bank); - -/** - * @return The first bank in the global list. - */ -struct flash_bank *flash_bank_list(void); - -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 flash_driver_write(struct flash_bank *bank, - uint8_t *buffer, uint32_t offset, uint32_t count); -int flash_driver_read(struct flash_bank *bank, - uint8_t *buffer, uint32_t offset, uint32_t count); - -/* write (optional verify) an image to flash memory of the given target */ -int flash_write_unlock(struct target *target, struct image *image, - uint32_t *written, int erase, bool unlock); - -#endif /* OPENOCD_FLASH_NOR_IMP_H */ diff --git a/src/flash/nor/jtagspi.c b/src/flash/nor/jtagspi.c deleted file mode 100644 index a995fc756..000000000 --- a/src/flash/nor/jtagspi.c +++ /dev/null @@ -1,413 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2015 Robert Jordens * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 -#include "config.h" -#endif - -#include "imp.h" -#include -#include -#include - -#define JTAGSPI_MAX_TIMEOUT 3000 - - -struct jtagspi_flash_bank { - struct jtag_tap *tap; - const struct flash_device *dev; - int probed; - uint32_t ir; - uint32_t dr_len; -}; - -FLASH_BANK_COMMAND_HANDLER(jtagspi_flash_bank_command) -{ - struct jtagspi_flash_bank *info; - - if (CMD_ARGC < 8) - return ERROR_COMMAND_SYNTAX_ERROR; - - info = malloc(sizeof(struct jtagspi_flash_bank)); - if (info == NULL) { - LOG_ERROR("no memory for flash bank info"); - return ERROR_FAIL; - } - bank->driver_priv = info; - - info->tap = NULL; - info->probed = 0; - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[6], info->ir); - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[7], info->dr_len); - - return ERROR_OK; -} - -static void jtagspi_set_ir(struct flash_bank *bank) -{ - struct jtagspi_flash_bank *info = bank->driver_priv; - struct scan_field field; - uint8_t buf[4]; - - if (buf_get_u32(info->tap->cur_instr, 0, info->tap->ir_length) == info->ir) - return; - - LOG_DEBUG("loading jtagspi ir"); - buf_set_u32(buf, 0, info->tap->ir_length, info->ir); - field.num_bits = info->tap->ir_length; - field.out_value = buf; - field.in_value = NULL; - jtag_add_ir_scan(info->tap, &field, TAP_IDLE); -} - -static void flip_u8(uint8_t *in, uint8_t *out, int len) -{ - for (int i = 0; i < len; i++) - out[i] = flip_u32(in[i], 8); -} - -static int jtagspi_cmd(struct flash_bank *bank, uint8_t cmd, - uint32_t *addr, uint8_t *data, int len) -{ - struct jtagspi_flash_bank *info = bank->driver_priv; - struct scan_field fields[3]; - uint8_t cmd_buf[4]; - uint8_t *data_buf; - int is_read, lenb, n; - - /* LOG_DEBUG("cmd=0x%02x len=%i", cmd, len); */ - - n = 0; - fields[n].num_bits = 8; - cmd_buf[0] = cmd; - if (addr) { - h_u24_to_be(cmd_buf + 1, *addr); - fields[n].num_bits += 24; - } - flip_u8(cmd_buf, cmd_buf, 4); - fields[n].out_value = cmd_buf; - fields[n].in_value = NULL; - n++; - - is_read = (len < 0); - if (is_read) - len = -len; - lenb = DIV_ROUND_UP(len, 8); - data_buf = malloc(lenb); - if (lenb > 0) { - if (data_buf == NULL) { - LOG_ERROR("no memory for spi buffer"); - return ERROR_FAIL; - } - if (is_read) { - fields[n].num_bits = info->dr_len; - fields[n].out_value = NULL; - fields[n].in_value = NULL; - n++; - fields[n].out_value = NULL; - fields[n].in_value = data_buf; - } else { - flip_u8(data, data_buf, lenb); - fields[n].out_value = data_buf; - fields[n].in_value = NULL; - } - fields[n].num_bits = len; - n++; - } - - jtagspi_set_ir(bank); - jtag_add_dr_scan(info->tap, n, fields, TAP_IDLE); - jtag_execute_queue(); - - if (is_read) - flip_u8(data_buf, data, lenb); - free(data_buf); - return ERROR_OK; -} - -static int jtagspi_probe(struct flash_bank *bank) -{ - struct jtagspi_flash_bank *info = bank->driver_priv; - struct flash_sector *sectors; - uint8_t in_buf[3]; - uint32_t id; - - if (info->probed) - free(bank->sectors); - info->probed = 0; - - if (bank->target->tap == NULL) { - LOG_ERROR("Target has no JTAG tap"); - return ERROR_FAIL; - } - info->tap = bank->target->tap; - - jtagspi_cmd(bank, SPIFLASH_READ_ID, NULL, in_buf, -24); - /* the table in spi.c has the manufacturer byte (first) as the lsb */ - id = le_to_h_u24(in_buf); - - info->dev = NULL; - for (const struct flash_device *p = flash_devices; p->name ; p++) - if (p->device_id == id) { - info->dev = p; - break; - } - - if (!(info->dev)) { - LOG_ERROR("Unknown flash device (ID 0x%08" PRIx32 ")", id); - return ERROR_FAIL; - } - - LOG_INFO("Found flash device \'%s\' (ID 0x%08" PRIx32 ")", - info->dev->name, info->dev->device_id); - - /* Set correct size value */ - bank->size = info->dev->size_in_bytes; - - /* create and fill sectors array */ - bank->num_sectors = - info->dev->size_in_bytes / info->dev->sectorsize; - sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors); - if (sectors == NULL) { - LOG_ERROR("not enough memory"); - return ERROR_FAIL; - } - - for (int sector = 0; sector < bank->num_sectors; sector++) { - sectors[sector].offset = sector * info->dev->sectorsize; - sectors[sector].size = info->dev->sectorsize; - sectors[sector].is_erased = -1; - sectors[sector].is_protected = 0; - } - - bank->sectors = sectors; - info->probed = 1; - return ERROR_OK; -} - -static void jtagspi_read_status(struct flash_bank *bank, uint32_t *status) -{ - uint8_t buf; - jtagspi_cmd(bank, SPIFLASH_READ_STATUS, NULL, &buf, -8); - *status = buf; - /* LOG_DEBUG("status=0x%08" PRIx32, *status); */ -} - -static int jtagspi_wait(struct flash_bank *bank, int timeout_ms) -{ - uint32_t status; - 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 %" PRId64 " ms", dt); - return ERROR_OK; - } - alive_sleep(1); - } while (dt <= timeout_ms); - - LOG_ERROR("timeout, device still busy"); - return ERROR_FAIL; -} - -static int jtagspi_write_enable(struct flash_bank *bank) -{ - uint32_t status; - - jtagspi_cmd(bank, SPIFLASH_WRITE_ENABLE, NULL, NULL, 0); - jtagspi_read_status(bank, &status); - if ((status & SPIFLASH_WE_BIT) == 0) { - LOG_ERROR("Cannot enable write to flash. Status=0x%08" PRIx32, status); - return ERROR_FAIL; - } - return ERROR_OK; -} - -static int jtagspi_bulk_erase(struct flash_bank *bank) -{ - struct jtagspi_flash_bank *info = bank->driver_priv; - int retval; - 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 %" PRId64 " ms", timeval_ms() - t0); - return retval; -} - -static int jtagspi_sector_erase(struct flash_bank *bank, int sector) -{ - struct jtagspi_flash_bank *info = bank->driver_priv; - int retval; - 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 %" PRId64 " ms", sector, timeval_ms() - t0); - return retval; -} - -static int jtagspi_erase(struct flash_bank *bank, int first, int last) -{ - int sector; - struct jtagspi_flash_bank *info = bank->driver_priv; - int retval = ERROR_OK; - - LOG_DEBUG("erase from sector %d to sector %d", first, last); - - if ((first < 0) || (last < first) || (last >= bank->num_sectors)) { - LOG_ERROR("Flash sector invalid"); - return ERROR_FLASH_SECTOR_INVALID; - } - - if (!(info->probed)) { - LOG_ERROR("Flash bank not probed"); - return ERROR_FLASH_BANK_NOT_PROBED; - } - - for (sector = first; sector <= last; sector++) { - if (bank->sectors[sector].is_protected) { - LOG_ERROR("Flash sector %d protected", sector); - return ERROR_FAIL; - } - } - - if (first == 0 && last == (bank->num_sectors - 1) - && info->dev->chip_erase_cmd != info->dev->erase_cmd) { - LOG_DEBUG("Trying bulk erase."); - retval = jtagspi_bulk_erase(bank); - if (retval == ERROR_OK) - return retval; - else - LOG_WARNING("Bulk flash erase failed. Falling back to sector erase."); - } - - for (sector = first; sector <= last; sector++) { - retval = jtagspi_sector_erase(bank, sector); - if (retval != ERROR_OK) { - LOG_ERROR("Sector erase failed."); - break; - } - } - - return retval; -} - -static int jtagspi_protect(struct flash_bank *bank, int set, int first, int last) -{ - int sector; - - if ((first < 0) || (last < first) || (last >= bank->num_sectors)) { - LOG_ERROR("Flash sector invalid"); - return ERROR_FLASH_SECTOR_INVALID; - } - - for (sector = first; sector <= last; sector++) - bank->sectors[sector].is_protected = set; - return ERROR_OK; -} - -static int jtagspi_protect_check(struct flash_bank *bank) -{ - return ERROR_OK; -} - -static int jtagspi_read(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, uint32_t count) -{ - struct jtagspi_flash_bank *info = bank->driver_priv; - - if (!(info->probed)) { - LOG_ERROR("Flash bank not yet probed."); - return ERROR_FLASH_BANK_NOT_PROBED; - } - - jtagspi_cmd(bank, SPIFLASH_READ, &offset, buffer, -count*8); - return ERROR_OK; -} - -static int jtagspi_page_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count) -{ - int retval; - - retval = jtagspi_write_enable(bank); - if (retval != ERROR_OK) - return retval; - jtagspi_cmd(bank, SPIFLASH_PAGE_PROGRAM, &offset, (uint8_t *) buffer, count*8); - return jtagspi_wait(bank, JTAGSPI_MAX_TIMEOUT); -} - -static int jtagspi_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count) -{ - struct jtagspi_flash_bank *info = bank->driver_priv; - int retval; - uint32_t n; - - if (!(info->probed)) { - LOG_ERROR("Flash bank not yet probed."); - return ERROR_FLASH_BANK_NOT_PROBED; - } - - for (n = 0; n < count; n += info->dev->pagesize) { - retval = jtagspi_page_write(bank, buffer + n, offset + n, - MIN(count - n, info->dev->pagesize)); - if (retval != ERROR_OK) { - LOG_ERROR("page write error"); - return retval; - } - LOG_DEBUG("wrote page at 0x%08" PRIx32, offset + n); - } - return ERROR_OK; -} - -static int jtagspi_info(struct flash_bank *bank, char *buf, int buf_size) -{ - struct jtagspi_flash_bank *info = bank->driver_priv; - - if (!(info->probed)) { - snprintf(buf, buf_size, "\nJTAGSPI flash bank not probed yet\n"); - return ERROR_OK; - } - - snprintf(buf, buf_size, "\nSPIFI flash information:\n" - " Device \'%s\' (ID 0x%08" PRIx32 ")\n", - info->dev->name, info->dev->device_id); - - return ERROR_OK; -} - -struct flash_driver jtagspi_flash = { - .name = "jtagspi", - .flash_bank_command = jtagspi_flash_bank_command, - .erase = jtagspi_erase, - .protect = jtagspi_protect, - .write = jtagspi_write, - .read = jtagspi_read, - .probe = jtagspi_probe, - .auto_probe = jtagspi_probe, - .erase_check = default_flash_blank_check, - .protect_check = jtagspi_protect_check, - .info = jtagspi_info -}; diff --git a/src/flash/nor/kinetis.c b/src/flash/nor/kinetis.c deleted file mode 100644 index e9cf8fa6b..000000000 --- a/src/flash/nor/kinetis.c +++ /dev/null @@ -1,2423 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2011 by Mathias Kuester * - * kesmtp@freenet.de * - * * - * Copyright (C) 2011 sleep(5) ltd * - * tomas@sleepfive.com * - * * - * Copyright (C) 2012 by Christopher D. Kilgour * - * techie at whiterocker.com * - * * - * 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 * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 -#include "config.h" -#endif - -#include "jtag/interface.h" -#include "imp.h" -#include -#include -#include -#include -#include -#include - -/* - * Implementation Notes - * - * The persistent memories in the Kinetis chip families K10 through - * K70 are all manipulated with the Flash Memory Module. Some - * variants call this module the FTFE, others call it the FTFL. To - * indicate that both are considered here, we use FTFX. - * - * Within the module, according to the chip variant, the persistent - * memory is divided into what Freescale terms Program Flash, FlexNVM, - * and FlexRAM. All chip variants have Program Flash. Some chip - * variants also have FlexNVM and FlexRAM, which always appear - * together. - * - * A given Kinetis chip may have 1, 2 or 4 blocks of flash. Here we map - * each block to a separate bank. Each block size varies by chip and - * may be determined by the read-only SIM_FCFG1 register. The sector - * size within each bank/block varies by chip, and may be 1, 2 or 4k. - * The sector size may be different for flash and FlexNVM. - * - * The first half of the flash (1 or 2 blocks) is always Program Flash - * and always starts at address 0x00000000. The "PFLSH" flag, bit 23 - * of the read-only SIM_FCFG2 register, determines whether the second - * half of the flash is also Program Flash or FlexNVM+FlexRAM. When - * PFLSH is set, the second from the first half. When PFLSH is clear, - * the second half of flash is FlexNVM and always starts at address - * 0x10000000. FlexRAM, which is also present when PFLSH is clear, - * always starts at address 0x14000000. - * - * The Flash Memory Module provides a register set where flash - * commands are loaded to perform flash operations like erase and - * program. Different commands are available depending on whether - * Program Flash or FlexNVM/FlexRAM is being manipulated. Although - * the commands used are quite consistent between flash blocks, the - * parameters they accept differ according to the flash sector size. - * - */ - -/* 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 - -/* Values */ -#define PM_STAT_RUN 0x01 -#define PM_STAT_VLPR 0x04 -#define PM_CTRL_RUNM_RUN 0x00 - -/* Commands */ -#define FTFx_CMD_BLOCKSTAT 0x00 -#define FTFx_CMD_SECTSTAT 0x01 -#define FTFx_CMD_LWORDPROG 0x06 -#define FTFx_CMD_SECTERASE 0x09 -#define FTFx_CMD_SECTWRITE 0x0b -#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 - * Bit 15-12 : REVID - * Bit 11-7 : DIEID - * Bit 6-4 : FAMID - * Bit 3-0 : PINID - * - * The newer Kinetis series uses the following SDID layout : - * Bit 31-28 : FAMID - * Bit 27-24 : SUBFAMID - * Bit 23-20 : SERIESID - * Bit 19-16 : SRAMSIZE - * Bit 15-12 : REVID - * Bit 6-4 : Reserved (0) - * Bit 3-0 : PINID - * - * We assume that if bits 31-16 are 0 then it's an older - * K-series MCU. - */ - -#define KINETIS_SOPT1_RAMSIZE_MASK 0x0000F000 -#define KINETIS_SOPT1_RAMSIZE_K24FN1M 0x0000B000 - -#define KINETIS_SDID_K_SERIES_MASK 0x0000FFFF - -#define KINETIS_SDID_DIEID_MASK 0x00000F80 - -#define KINETIS_SDID_DIEID_K22FN128 0x00000680 /* smaller pflash with FTFA */ -#define KINETIS_SDID_DIEID_K22FN256 0x00000A80 -#define KINETIS_SDID_DIEID_K22FN512 0x00000E80 -#define KINETIS_SDID_DIEID_K24FN256 0x00000700 - -#define KINETIS_SDID_DIEID_K24FN1M 0x00000300 /* Detect Errata 7534 */ - -/* We can't rely solely on the FAMID field to determine the MCU - * type since some FAMID values identify multiple MCUs with - * different flash sector sizes (K20 and K22 for instance). - * Therefore we combine it with the DIEID bits which may possibly - * break if Freescale bumps the DIEID for a particular MCU. */ -#define KINETIS_K_SDID_TYPE_MASK 0x00000FF0 -#define KINETIS_K_SDID_K10_M50 0x00000000 -#define KINETIS_K_SDID_K10_M72 0x00000080 -#define KINETIS_K_SDID_K10_M100 0x00000100 -#define KINETIS_K_SDID_K10_M120 0x00000180 -#define KINETIS_K_SDID_K11 0x00000220 -#define KINETIS_K_SDID_K12 0x00000200 -#define KINETIS_K_SDID_K20_M50 0x00000010 -#define KINETIS_K_SDID_K20_M72 0x00000090 -#define KINETIS_K_SDID_K20_M100 0x00000110 -#define KINETIS_K_SDID_K20_M120 0x00000190 -#define KINETIS_K_SDID_K21_M50 0x00000230 -#define KINETIS_K_SDID_K21_M120 0x00000330 -#define KINETIS_K_SDID_K22_M50 0x00000210 -#define KINETIS_K_SDID_K22_M120 0x00000310 -#define KINETIS_K_SDID_K30_M72 0x000000A0 -#define KINETIS_K_SDID_K30_M100 0x00000120 -#define KINETIS_K_SDID_K40_M72 0x000000B0 -#define KINETIS_K_SDID_K40_M100 0x00000130 -#define KINETIS_K_SDID_K50_M72 0x000000E0 -#define KINETIS_K_SDID_K51_M72 0x000000F0 -#define KINETIS_K_SDID_K53 0x00000170 -#define KINETIS_K_SDID_K60_M100 0x00000140 -#define KINETIS_K_SDID_K60_M150 0x000001C0 -#define KINETIS_K_SDID_K70_M150 0x000001D0 - -#define KINETIS_SDID_SERIESID_MASK 0x00F00000 -#define KINETIS_SDID_SERIESID_K 0x00000000 -#define KINETIS_SDID_SERIESID_KL 0x00100000 -#define KINETIS_SDID_SERIESID_KW 0x00500000 -#define KINETIS_SDID_SERIESID_KV 0x00600000 - -#define KINETIS_SDID_SUBFAMID_MASK 0x0F000000 -#define KINETIS_SDID_SUBFAMID_KX0 0x00000000 -#define KINETIS_SDID_SUBFAMID_KX1 0x01000000 -#define KINETIS_SDID_SUBFAMID_KX2 0x02000000 -#define KINETIS_SDID_SUBFAMID_KX3 0x03000000 -#define KINETIS_SDID_SUBFAMID_KX4 0x04000000 -#define KINETIS_SDID_SUBFAMID_KX5 0x05000000 -#define KINETIS_SDID_SUBFAMID_KX6 0x06000000 - -#define KINETIS_SDID_FAMILYID_MASK 0xF0000000 -#define KINETIS_SDID_FAMILYID_K0X 0x00000000 -#define KINETIS_SDID_FAMILYID_K1X 0x10000000 -#define KINETIS_SDID_FAMILYID_K2X 0x20000000 -#define KINETIS_SDID_FAMILYID_K3X 0x30000000 -#define KINETIS_SDID_FAMILYID_K4X 0x40000000 -#define KINETIS_SDID_FAMILYID_K6X 0x60000000 -#define KINETIS_SDID_FAMILYID_K7X 0x70000000 - -struct kinetis_flash_bank { - 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; - uint32_t sim_fcfg2; - - enum { - FC_AUTO = 0, - FC_PFLASH, - FC_FLEX_NVM, - FC_FLEX_RAM, - } flash_class; - - enum { - FS_PROGRAM_SECTOR = 1, - FS_PROGRAM_LONGWORD = 2, - FS_PROGRAM_PHRASE = 4, /* Unsupported */ - FS_INVALIDATE_CACHE = 8, - } flash_support; -}; - -#define MDM_AP 1 - -#define MDM_REG_STAT 0x00 -#define MDM_REG_CTRL 0x04 -#define MDM_REG_ID 0xfc - -#define MDM_STAT_FMEACK (1<<0) -#define MDM_STAT_FREADY (1<<1) -#define MDM_STAT_SYSSEC (1<<2) -#define MDM_STAT_SYSRES (1<<3) -#define MDM_STAT_FMEEN (1<<5) -#define MDM_STAT_BACKDOOREN (1<<6) -#define MDM_STAT_LPEN (1<<7) -#define MDM_STAT_VLPEN (1<<8) -#define MDM_STAT_LLSMODEXIT (1<<9) -#define MDM_STAT_VLLSXMODEXIT (1<<10) -#define MDM_STAT_CORE_HALTED (1<<16) -#define MDM_STAT_CORE_SLEEPDEEP (1<<17) -#define MDM_STAT_CORESLEEPING (1<<18) - -#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); - - -static int kinetis_mdm_write_register(struct adiv5_dap *dap, unsigned reg, uint32_t value) -{ - int retval; - LOG_DEBUG("MDM_REG[0x%02x] <- %08" PRIX32, reg, value); - - retval = dap_queue_ap_write(dap_ap(dap, MDM_AP), reg, value); - if (retval != ERROR_OK) { - LOG_DEBUG("MDM: failed to queue a write request"); - return retval; - } - - retval = dap_run(dap); - if (retval != ERROR_OK) { - LOG_DEBUG("MDM: dap_run failed"); - return retval; - } - - - return ERROR_OK; -} - -static int kinetis_mdm_read_register(struct adiv5_dap *dap, unsigned reg, uint32_t *result) -{ - int retval; - - 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; - } - - retval = dap_run(dap); - if (retval != ERROR_OK) { - LOG_DEBUG("MDM: dap_run failed"); - return retval; - } - - LOG_DEBUG("MDM_REG[0x%02x]: %08" PRIX32, reg, *result); - return ERROR_OK; -} - -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; - int64_t ms_timeout = timeval_ms() + timeout_ms; - - do { - retval = kinetis_mdm_read_register(dap, reg, &val); - if (retval != ERROR_OK || (val & mask) == value) - return retval; - - alive_sleep(1); - } 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. 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) -{ - 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; - - if (!dap) { - LOG_ERROR("Cannot perform mass erase with a high-level adapter"); - return ERROR_FAIL; - } - - int retval; - - /* - * ... Power on the processor, or if power has already been - * applied, assert the RESET pin to reset the processor. For - * devices that do not have a RESET pin, write the System - * Reset Request bit in the MDM-AP control register after - * establishing communication... - */ - - /* assert SRST if configured */ - bool has_srst = jtag_get_reset_config() & RESET_HAS_SRST; - if (has_srst) - adapter_assert_reset(); - - 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 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. - */ - 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, 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, 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. - */ - retval = kinetis_mdm_write_register(dap, MDM_REG_CTRL, 0); - if (retval != ERROR_OK) - LOG_ERROR("MDM: failed to clear MDM_REG_CTRL"); - - target->type->deassert_reset(target); - - 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[] = { - 0x001C0000, /* Kinetis-K Series */ - 0x001C0020, /* Kinetis-L/M/V/E Series */ -}; - -/* - * This function implements the procedure to connect to - * 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.1.1 - */ -COMMAND_HANDLER(kinetis_check_flash_security_status) -{ - 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; - - if (!dap) { - LOG_WARNING("Cannot check flash security status with a high-level adapter"); - return ERROR_OK; - } - - uint32_t val; - int retval; - - /* - * ... The MDM-AP ID register can be read to verify that the - * connection is working correctly... - */ - retval = kinetis_mdm_read_register(dap, MDM_REG_ID, &val); - if (retval != ERROR_OK) { - LOG_ERROR("MDM: failed to read ID register"); - return ERROR_OK; - } - - if (val == 0) - return ERROR_OK; - - bool found = false; - for (size_t i = 0; i < ARRAY_SIZE(kinetis_known_mdm_ids); i++) { - if (val == kinetis_known_mdm_ids[i]) { - found = true; - break; - } - } - - if (!found) - LOG_WARNING("MDM: unknown ID %08" PRIX32, val); - - /* - * ... Read the System Security bit to determine if security is enabled. - * If System Security = 0, then proceed. If System Security = 1, then - * communication with the internals of the processor, including the - * flash, will not be possible without issuing a mass erase command or - * unsecuring the part through other means (backdoor key unlock)... - */ - retval = kinetis_mdm_read_register(dap, MDM_REG_STAT, &val); - if (retval != ERROR_OK) { - LOG_ERROR("MDM: failed to read MDM_REG_STAT"); - return ERROR_OK; - } - - /* - * 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; - - if ((val & (MDM_STAT_SYSSEC | MDM_STAT_FREADY)) != MDM_STAT_FREADY) { - uint32_t stats[32]; - int i; - - 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]); - } - retval = dap_run(dap); - if (retval != ERROR_OK) { - 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 (flash_not_ready_score <= 8 && secured_score > 24) { - jtag_poll_set_enabled(false); - - LOG_WARNING("*********** ATTENTION! ATTENTION! ATTENTION! ATTENTION! **********"); - LOG_WARNING("**** ****"); - LOG_WARNING("**** Your Kinetis MCU is in secured state, which means that, ****"); - LOG_WARNING("**** with exception for very basic communication, JTAG/SWD ****"); - LOG_WARNING("**** interface will NOT work. In order to restore its ****"); - LOG_WARNING("**** functionality please issue 'kinetis mdm mass_erase' ****"); - 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; -} - -FLASH_BANK_COMMAND_HANDLER(kinetis_flash_bank_command) -{ - struct kinetis_flash_bank *bank_info; - - if (CMD_ARGC < 6) - return ERROR_COMMAND_SYNTAX_ERROR; - - LOG_INFO("add flash_bank kinetis %s", bank->name); - - bank_info = malloc(sizeof(struct kinetis_flash_bank)); - - memset(bank_info, 0, sizeof(struct kinetis_flash_bank)); - - bank->driver_priv = bank_info; - - return ERROR_OK; -} - -/* Disable the watchdog on Kinetis devices */ -int kinetis_disable_wdog(struct target *target, uint32_t sim_sdid) -{ - struct working_area *wdog_algorithm; - struct armv7m_algorithm armv7m_info; - uint16_t wdog; - int retval; - - static const uint8_t kinetis_unlock_wdog_code[] = { -#include "../../../contrib/loaders/watchdog/armv7m_kinetis_wdog.inc" - }; - - /* Decide whether the connected device needs watchdog disabling. - * 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; - - /* The connected device requires watchdog disabling. */ - retval = target_read_u16(target, WDOG_STCTRH, &wdog); - if (retval != ERROR_OK) - return retval; - - if ((wdog & 0x1) == 0) { - /* watchdog already disabled */ - return ERROR_OK; - } - LOG_INFO("Disabling Kinetis watchdog (initial WDOG_STCTRLH = 0x%x)", wdog); - - if (target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - retval = target_alloc_working_area(target, sizeof(kinetis_unlock_wdog_code), &wdog_algorithm); - if (retval != ERROR_OK) - return retval; - - retval = target_write_buffer(target, wdog_algorithm->address, - sizeof(kinetis_unlock_wdog_code), (uint8_t *)kinetis_unlock_wdog_code); - if (retval != ERROR_OK) { - target_free_working_area(target, wdog_algorithm); - return retval; - } - - armv7m_info.common_magic = ARMV7M_COMMON_MAGIC; - armv7m_info.core_mode = ARM_MODE_THREAD; - - retval = target_run_algorithm(target, 0, NULL, 0, NULL, wdog_algorithm->address, - wdog_algorithm->address + (sizeof(kinetis_unlock_wdog_code) - 2), - 10000, &armv7m_info); - - if (retval != ERROR_OK) - LOG_ERROR("error executing kinetis wdog unlock algorithm"); - - retval = target_read_u16(target, WDOG_STCTRH, &wdog); - if (retval != ERROR_OK) - return retval; - LOG_INFO("WDOG_STCTRLH = 0x%x", wdog); - - target_free_working_area(target, wdog_algorithm); - - return retval; -} - -COMMAND_HANDLER(kinetis_disable_wdog_handler) -{ - int result; - uint32_t sim_sdid; - struct target *target = get_current_target(CMD_CTX); - - if (CMD_ARGC > 0) - return ERROR_COMMAND_SYNTAX_ERROR; - - result = target_read_u32(target, SIM_SDID, &sim_sdid); - if (result != ERROR_OK) { - LOG_ERROR("Failed to read SIMSDID"); - return result; - } - - result = kinetis_disable_wdog(target, sim_sdid); - return result; -} - - -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;itarget; - uint32_t buffer_size = 2048; /* Default minimum value */ - struct working_area *write_algorithm; - struct working_area *source; - struct kinetis_flash_bank *kinfo = bank->driver_priv; - uint32_t address = kinfo->prog_base + offset; - struct reg_param reg_params[3]; - 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 - */ - - /* Increase buffer_size if needed */ - if (buffer_size < (target->working_area_size/2)) - buffer_size = (target->working_area_size/2); - - /* allocate working area with flash programming code */ - if (target_alloc_working_area(target, sizeof(kinetis_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(kinetis_flash_write_code), kinetis_flash_write_code); - if (retval != ERROR_OK) - return retval; - - /* memory buffer */ - while (target_alloc_working_area(target, buffer_size, &source) != ERROR_OK) { - buffer_size /= 4; - if (buffer_size <= 256) { - /* free working area, write algorithm already allocated */ - target_free_working_area(target, write_algorithm); - - 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; - - 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 */ - - /* 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; - - retval = target_write_buffer(target, source->address, thisrun_count * 4, buffer); - if (retval != ERROR_OK) - break; - - 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); - - 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; - } - - buffer += thisrun_count * 4; - address += thisrun_count * 4; - wcount -= thisrun_count; - } - - target_free_working_area(target, source); - target_free_working_area(target, write_algorithm); - - destroy_reg_param(®_params[0]); - destroy_reg_param(®_params[1]); - destroy_reg_param(®_params[2]); - - return retval; -} - -static int kinetis_protect(struct flash_bank *bank, int set, int first, int last) -{ - int i; - - 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; - } - - 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; - int result; - int i, b; - uint32_t fprot; - - if (kinfo->flash_class == FC_PFLASH) { - - /* read protection register */ - 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 = fdprot; - - } 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; - } - - } 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; - - dflash_bit <<= 1; - } - - } - } - - 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 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) -{ - uint8_t command[12] = {faddr & 0xff, (faddr >> 8) & 0xff, (faddr >> 16) & 0xff, fcmd, - fccob7, fccob6, fccob5, fccob4, - fccobb, fccoba, fccob9, fccob8}; - 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 */ - result = target_write_u8(target, FTFx_FSTAT, 0x80); - if (result != ERROR_OK) - return result; - - /* wait for done */ - do { - result = target_read_u8(target, FTFx_FSTAT, &fstat); - - if (result != ERROR_OK) - return result; - - if (fstat & 0x80) - break; - - } 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 kinetis_ftfx_decode_error(fstat); - } - - return ERROR_OK; -} - - -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; - } - - result = target_read_u8(target, SMC_PMSTAT, &pmstat); - if (result != ERROR_OK) - return result; - - if (pmstat == PM_STAT_RUN) - return ERROR_OK; - - 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; - uint8_t pfb01cr_byte2 = 0xf0; - - if (!(kinfo->flash_support & FS_INVALIDATE_CACHE)) - return; - - target_write_memory(bank->target, FMC_PFB01CR + 2, 1, 1, &pfb01cr_byte2); - 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; - - /* - * FIXME: TODO: use the 'Erase Flash Block' command if the - * requested erase is PFlash or NVM and encompasses the entire - * block. Should be quicker. - */ - for (i = first; i <= last; i++) { - /* set command and sector address */ - 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); - return ERROR_FLASH_OPERATION_FAILED; - } - - bank->sectors[i].is_erased = 1; - - 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_make_ram_ready(struct target *target) -{ - int result; - uint8_t ftfx_fcnfg; - - /* check if ram ready */ - 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 */ - - /* 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; - - if (size > count) - size = count; - - align_end = (align_begin + size) % prog_section_chunk_bytes; - if (align_end) - align_end = prog_section_chunk_bytes - align_end; - - size_aligned = align_begin + size + align_end; - chunk_count = size_aligned / prog_section_chunk_bytes; - - if (size != size_aligned) { - /* aligned section: the first, the last or the only */ - if (!buffer_aligned) - buffer_aligned = malloc(prog_size_bytes); - - memset(buffer_aligned, 0xff, size_aligned); - memcpy(buffer_aligned + align_begin, buffer, size); - - result = target_write_memory(bank->target, FLEXRAM, - 4, size_aligned / 4, buffer_aligned); - - 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); - - if (result != ERROR_OK) { - LOG_ERROR("target_write_memory failed"); - break; - } - - /* 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); - - if (result != ERROR_OK) { - LOG_ERROR("Error writing section at %08" PRIx32, bank->base + offset); - break; - } - - if (ftfx_fstat & 0x01) - LOG_ERROR("Flash write error at %08" PRIx32, bank->base + offset); - - buffer += size; - offset += size; - count -= size; - } - - free(buffer_aligned); - return result; -} - - -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_WARNING("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."); - } - } - - 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; - new_buffer = malloc(count); - if (new_buffer == NULL) { - LOG_ERROR("odd number of bytes to write and no memory " - "for padding buffer"); - return ERROR_FAIL; - } - LOG_INFO("odd number of bytes to write (%" PRIu32 "), extending to %" PRIu32 " " - "and padding with 0xff", old_count, count); - memset(new_buffer + old_count, 0xff, count - old_count); - buffer = memcpy(new_buffer, buffer, old_count); - } - - uint32_t words_remaining = count / 4; - - kinetis_disable_wdog(bank->target, kinfo->sim_sdid); - - /* try using a block write */ - result = kinetis_write_block(bank, buffer, offset, words_remaining); - - 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"); - - while (words_remaining) { - uint8_t ftfx_fstat; - - LOG_DEBUG("write longword @ %08" PRIx32, (uint32_t)(bank->base + offset)); - - 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) { - 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; - } - - kinetis_invalidate_flash_cache(bank); - return result; -} - - -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; - 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, - 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; - - if ((kinfo->sim_sdid & (~KINETIS_SDID_K_SERIES_MASK)) == 0) { - /* older K-series MCU */ - uint32_t mcu_type = kinfo->sim_sdid & KINETIS_K_SDID_TYPE_MASK; - - switch (mcu_type) { - case KINETIS_K_SDID_K10_M50: - case KINETIS_K_SDID_K20_M50: - /* 1kB sectors */ - pflash_sector_size_bytes = 1<<10; - nvm_sector_size_bytes = 1<<10; - num_blocks = 2; - kinfo->flash_support = FS_PROGRAM_LONGWORD | FS_PROGRAM_SECTOR | FS_INVALIDATE_CACHE; - break; - case KINETIS_K_SDID_K10_M72: - case KINETIS_K_SDID_K20_M72: - case KINETIS_K_SDID_K30_M72: - case KINETIS_K_SDID_K30_M100: - case KINETIS_K_SDID_K40_M72: - case KINETIS_K_SDID_K40_M100: - case KINETIS_K_SDID_K50_M72: - /* 2kB sectors, 1kB FlexNVM sectors */ - pflash_sector_size_bytes = 2<<10; - nvm_sector_size_bytes = 1<<10; - num_blocks = 2; - kinfo->flash_support = FS_PROGRAM_LONGWORD | FS_PROGRAM_SECTOR | FS_INVALIDATE_CACHE; - kinfo->max_flash_prog_size = 1<<10; - break; - case KINETIS_K_SDID_K10_M100: - case KINETIS_K_SDID_K20_M100: - case KINETIS_K_SDID_K11: - case KINETIS_K_SDID_K12: - case KINETIS_K_SDID_K21_M50: - case KINETIS_K_SDID_K22_M50: - case KINETIS_K_SDID_K51_M72: - case KINETIS_K_SDID_K53: - case KINETIS_K_SDID_K60_M100: - /* 2kB sectors */ - pflash_sector_size_bytes = 2<<10; - nvm_sector_size_bytes = 2<<10; - num_blocks = 2; - kinfo->flash_support = FS_PROGRAM_LONGWORD | FS_PROGRAM_SECTOR | FS_INVALIDATE_CACHE; - break; - case KINETIS_K_SDID_K21_M120: - case KINETIS_K_SDID_K22_M120: - /* 4kB sectors (MK21FN1M0, MK21FX512, MK22FN1M0, MK22FX512) */ - pflash_sector_size_bytes = 4<<10; - 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 | FS_INVALIDATE_CACHE; - break; - case KINETIS_K_SDID_K10_M120: - case KINETIS_K_SDID_K20_M120: - case KINETIS_K_SDID_K60_M150: - case KINETIS_K_SDID_K70_M150: - /* 4kB sectors */ - pflash_sector_size_bytes = 4<<10; - nvm_sector_size_bytes = 4<<10; - num_blocks = 4; - kinfo->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR | FS_INVALIDATE_CACHE; - break; - default: - LOG_ERROR("Unsupported K-family FAMID"); - } - } else { - /* Newer K-series or KL series MCU */ - switch (kinfo->sim_sdid & KINETIS_SDID_SERIESID_MASK) { - case KINETIS_SDID_SERIESID_K: - switch (kinfo->sim_sdid & (KINETIS_SDID_FAMILYID_MASK | KINETIS_SDID_SUBFAMID_MASK)) { - case KINETIS_SDID_FAMILYID_K0X | KINETIS_SDID_SUBFAMID_KX2: - /* K02FN64, K02FN128: FTFA, 2kB sectors */ - pflash_sector_size_bytes = 2<<10; - num_blocks = 1; - kinfo->flash_support = FS_PROGRAM_LONGWORD | FS_INVALIDATE_CACHE; - break; - - case KINETIS_SDID_FAMILYID_K2X | KINETIS_SDID_SUBFAMID_KX2: { - /* MK24FN1M reports as K22, this should detect it (according to errata note 1N83J) */ - uint32_t sopt1; - result = target_read_u32(target, SIM_SOPT1, &sopt1); - if (result != ERROR_OK) - return result; - - if (((kinfo->sim_sdid & (KINETIS_SDID_DIEID_MASK)) == KINETIS_SDID_DIEID_K24FN1M) && - ((sopt1 & KINETIS_SOPT1_RAMSIZE_MASK) == KINETIS_SOPT1_RAMSIZE_K24FN1M)) { - /* MK24FN1M */ - pflash_sector_size_bytes = 4<<10; - num_blocks = 2; - kinfo->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR | FS_INVALIDATE_CACHE; - kinfo->max_flash_prog_size = 1<<10; - break; - } - if ((kinfo->sim_sdid & (KINETIS_SDID_DIEID_MASK)) == KINETIS_SDID_DIEID_K22FN128 - || (kinfo->sim_sdid & (KINETIS_SDID_DIEID_MASK)) == KINETIS_SDID_DIEID_K22FN256 - || (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; - /* autodetect 1 or 2 blocks */ - kinfo->flash_support = FS_PROGRAM_LONGWORD | FS_INVALIDATE_CACHE; - break; - } - LOG_ERROR("Unsupported Kinetis K22 DIEID"); - break; - } - case KINETIS_SDID_FAMILYID_K2X | KINETIS_SDID_SUBFAMID_KX4: - pflash_sector_size_bytes = 4<<10; - 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 | FS_INVALIDATE_CACHE; - break; - } - /* K24FN1M without errata 7534 */ - num_blocks = 2; - kinfo->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR | FS_INVALIDATE_CACHE; - kinfo->max_flash_prog_size = 1<<10; - break; - - case KINETIS_SDID_FAMILYID_K6X | KINETIS_SDID_SUBFAMID_KX3: - case KINETIS_SDID_FAMILYID_K6X | KINETIS_SDID_SUBFAMID_KX1: /* errata 7534 - should be K63 */ - /* K63FN1M0 */ - case KINETIS_SDID_FAMILYID_K6X | KINETIS_SDID_SUBFAMID_KX4: - case KINETIS_SDID_FAMILYID_K6X | KINETIS_SDID_SUBFAMID_KX2: /* errata 7534 - should be K64 */ - /* K64FN1M0, K64FX512 */ - pflash_sector_size_bytes = 4<<10; - 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 | FS_INVALIDATE_CACHE; - break; - - case KINETIS_SDID_FAMILYID_K2X | KINETIS_SDID_SUBFAMID_KX6: - /* K26FN2M0 */ - case KINETIS_SDID_FAMILYID_K6X | KINETIS_SDID_SUBFAMID_KX6: - /* K66FN2M0, K66FX1M0 */ - pflash_sector_size_bytes = 4<<10; - 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 | FS_INVALIDATE_CACHE; - 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; - /* autodetect 1 or 2 blocks */ - kinfo->flash_support = FS_PROGRAM_LONGWORD; - 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; - 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; - 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; - 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; - break; - - default: - LOG_ERROR("Unsupported KV FAMILYID SUBFAMID"); - } - break; - - default: - LOG_ERROR("Unsupported K-series"); - } - } - - if (pflash_sector_size_bytes == 0) { - LOG_ERROR("MCU is unsupported, SDID 0x%08" PRIx32, kinfo->sim_sdid); - return ERROR_FLASH_OPER_UNSUPPORTED; - } - - result = target_read_u32(target, SIM_FCFG1, &kinfo->sim_fcfg1); - if (result != ERROR_OK) - return result; - - result = target_read_u32(target, SIM_FCFG2, &kinfo->sim_fcfg2); - if (result != ERROR_OK) - return result; - - LOG_DEBUG("SDID: 0x%08" PRIX32 " FCFG1: 0x%08" PRIX32 " FCFG2: 0x%08" PRIX32, kinfo->sim_sdid, - kinfo->sim_fcfg1, kinfo->sim_fcfg2); - - 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: - nvm_size = 1 << (14 + (fcfg1_nvmsize >> 1)); - break; - case 0x0f: - if (pflash_sector_size_bytes >= 4<<10) - nvm_size = 512<<10; - else - /* K20_100 */ - nvm_size = 256<<10; - break; - default: - nvm_size = 0; - break; - } - - switch (fcfg1_eesize) { - case 0x00: - case 0x01: - case 0x02: - case 0x03: - case 0x04: - case 0x05: - case 0x06: - case 0x07: - case 0x08: - case 0x09: - ee_size = (16 << (10 - fcfg1_eesize)); - break; - default: - 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) { - case 0x03: - case 0x05: - case 0x07: - case 0x09: - case 0x0b: - case 0x0d: - pf_size = 1 << (14 + (fcfg1_pfsize >> 1)); - break; - case 0x0f: - /* 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 = ((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; - break; - } - - LOG_DEBUG("FlexNVM: %" PRIu32 " PFlash: %" PRIu32 " FlexRAM: %" PRIu32 " PFLSH: %d", - nvm_size, pf_size, ee_size, fcfg2_pflsh); - - num_pflash_blocks = num_blocks / (2 - fcfg2_pflsh); - first_nvm_bank = num_pflash_blocks; - num_nvm_blocks = num_blocks - num_pflash_blocks; - - LOG_DEBUG("%d blocks total: %d PFlash, %d FlexNVM", - num_blocks, num_pflash_blocks, num_nvm_blocks); - - 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; - /* 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 * nvm_ord; - kinfo->prog_base = 0x00800000 + bank->size * nvm_ord; - kinfo->sector_size = nvm_sector_size_bytes; - 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; - } else { - LOG_ERROR("Cannot determine parameters for bank %d, only %d banks on device", - bank->bank_number, num_blocks); - 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); - return ERROR_FLASH_BANK_INVALID; - } - - if (kinfo->flash_support & FS_PROGRAM_SECTOR - && kinfo->max_flash_prog_size == 0) { - kinfo->max_flash_prog_size = kinfo->sector_size; - /* Program section size is equal to sector size by default */ - } - - bank->num_sectors = bank->size / kinfo->sector_size; - - 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; - - bank->prot_blocks = alloc_block_array(0, kinfo->protection_size, bank->num_prot_blocks); - if (!bank->prot_blocks) - return ERROR_FAIL; - - } else { - bank->num_prot_blocks = 0; - } - - 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 && kinfo->probed) - return ERROR_OK; - - return kinetis_probe(bank); -} - -static int kinetis_info(struct flash_bank *bank, char *buf, int buf_size) -{ - const char *bank_class_names[] = { - "(ANY)", "PFlash", "FlexNVM", "FlexRAM" - }; - - struct kinetis_flash_bank *kinfo = bank->driver_priv; - - (void) snprintf(buf, buf_size, - "%s driver for %s flash bank %s at 0x%8.8" PRIx32 "", - bank->driver->name, bank_class_names[kinfo->flash_class], - bank->name, bank->base); - - return ERROR_OK; -} - -static int kinetis_blank_check(struct flash_bank *bank) -{ - struct kinetis_flash_bank *kinfo = bank->driver_priv; - int result; - - /* suprisingly blank check does not work in VLPR and HSRUN modes */ - 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 (kinfo->flash_class == FC_PFLASH || kinfo->flash_class == FC_FLEX_NVM) { - bool block_dirty = false; - uint8_t 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 (!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 (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->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) { - bank->sectors[i].is_erased = !(ftfx_fstat & 0x01); - } else { - LOG_DEBUG("Ignoring errored PFlash sector blank-check"); - bank->sectors[i].is_erased = -1; - } - } - } else { - /* the whole bank is erased, update all sectors */ - int i; - for (i = 0; i < bank->num_sectors; i++) - bank->sectors[i].is_erased = 1; - } - } else { - LOG_WARNING("kinetis_blank_check not supported yet for FlexRAM"); - return ERROR_FLASH_OPERATION_FAILED; - } - - return ERROR_OK; -} - - -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 = "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 = "Issue a complete flash erase via the MDM-AP", - .usage = "", - .handler = kinetis_mdm_mass_erase, - }, - { .name = "reset", - .mode = COMMAND_EXEC, - .help = "Issue a reset via the MDM-AP", - .usage = "", - .handler = kinetis_mdm_reset, - }, - COMMAND_REGISTRATION_DONE -}; - -static const struct command_registration kinetis_exec_command_handlers[] = { - { - .name = "mdm", - .mode = COMMAND_ANY, - .help = "MDM-AP command group", - .usage = "", - .chain = kinetis_security_command_handlers, - }, - { - .name = "disable_wdog", - .mode = COMMAND_EXEC, - .help = "Disable the watchdog timer", - .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 -}; - -static const struct command_registration kinetis_command_handler[] = { - { - .name = "kinetis", - .mode = COMMAND_ANY, - .help = "Kinetis flash controller commands", - .usage = "", - .chain = kinetis_exec_command_handlers, - }, - COMMAND_REGISTRATION_DONE -}; - - - -struct flash_driver kinetis_flash = { - .name = "kinetis", - .commands = kinetis_command_handler, - .flash_bank_command = kinetis_flash_bank_command, - .erase = kinetis_erase, - .protect = kinetis_protect, - .write = kinetis_write, - .read = default_flash_read, - .probe = kinetis_probe, - .auto_probe = kinetis_auto_probe, - .erase_check = kinetis_blank_check, - .protect_check = kinetis_protect_check, - .info = kinetis_info, -}; diff --git a/src/flash/nor/kinetis_ke.c b/src/flash/nor/kinetis_ke.c deleted file mode 100644 index 636fcc2e9..000000000 --- a/src/flash/nor/kinetis_ke.c +++ /dev/null @@ -1,1314 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2015 by Ivan Meleca * - * ivan@artekit.eu * - * * - * Modified from kinetis.c * - * * - * Copyright (C) 2011 by Mathias Kuester * - * kesmtp@freenet.de * - * * - * Copyright (C) 2011 sleep(5) ltd * - * tomas@sleepfive.com * - * * - * Copyright (C) 2012 by Christopher D. Kilgour * - * techie at whiterocker.com * - * * - * 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 * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 -#include "config.h" -#endif - -#include "jtag/interface.h" -#include "imp.h" -#include -#include -#include -#include - -/* Addresses */ -#define SIM_SRSID 0x40048000 -#define ICS_C1 0x40064000 -#define ICS_C2 0x40064001 -#define ICS_C3 0x40064002 -#define ICS_C4 0x40064003 -#define ICS_S 0x40064004 -#define SIM_BUSDIV 0x40048018 -#define SIM_CLKDIV_KE06 0x40048024 -#define SIM_CLKDIV_KE04_44_64_80 0x40048024 -#define SIM_CLKDIV_KE04_16_20_24 0x4004801C -#define WDOG_CS1 0x40052000 - -#define ICS_C2_BDIV_MASK 0xE0 -#define ICS_C2_BDIV_SHIFT 5 -#define ICS_C2_BDIV(x) (((uint8_t)(((uint8_t)(x))<> 28) & 0x0F) -#define KINETIS_KE_SRSID_SUBFAMID(x) ((x >> 24) & 0x0F) -#define KINETIS_KE_SRSID_PINCOUNT(x) ((x >> 16) & 0x0F) - -#define KINETIS_KE_SRSID_KEX2 0x02 -#define KINETIS_KE_SRSID_KEX4 0x04 -#define KINETIS_KE_SRSID_KEX6 0x06 - -struct kinetis_ke_flash_bank { - uint32_t sector_size; - uint32_t protection_size; - - uint32_t sim_srsid; - uint32_t ftmrx_fclkdiv_addr; - uint32_t ftmrx_fccobix_addr; - uint32_t ftmrx_fstat_addr; - uint32_t ftmrx_fprot_addr; - uint32_t ftmrx_fccobhi_addr; - uint32_t ftmrx_fccoblo_addr; -}; - -#define MDM_REG_STAT 0x00 -#define MDM_REG_CTRL 0x04 -#define MDM_REG_ID 0xfc - -#define MDM_STAT_FMEACK (1<<0) -#define MDM_STAT_FREADY (1<<1) -#define MDM_STAT_SYSSEC (1<<2) -#define MDM_STAT_SYSRES (1<<3) -#define MDM_STAT_FMEEN (1<<5) -#define MDM_STAT_BACKDOOREN (1<<6) -#define MDM_STAT_LPEN (1<<7) -#define MDM_STAT_VLPEN (1<<8) -#define MDM_STAT_LLSMODEXIT (1<<9) -#define MDM_STAT_VLLSXMODEXIT (1<<10) -#define MDM_STAT_CORE_HALTED (1<<16) -#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_ACCESS_TIMEOUT 3000 /* iterations */ - -static int kinetis_ke_mdm_write_register(struct adiv5_dap *dap, unsigned reg, uint32_t value) -{ - int retval; - LOG_DEBUG("MDM_REG[0x%02x] <- %08" PRIX32, reg, value); - - retval = dap_queue_ap_write(dap_ap(dap, 1), reg, value); - if (retval != ERROR_OK) { - LOG_DEBUG("MDM: failed to queue a write request"); - return retval; - } - - retval = dap_run(dap); - if (retval != ERROR_OK) { - LOG_DEBUG("MDM: dap_run failed"); - return retval; - } - - return ERROR_OK; -} - -static int kinetis_ke_mdm_read_register(struct adiv5_dap *dap, unsigned reg, uint32_t *result) -{ - int retval; - retval = dap_queue_ap_read(dap_ap(dap, 1), reg, result); - if (retval != ERROR_OK) { - LOG_DEBUG("MDM: failed to queue a read request"); - return retval; - } - - retval = dap_run(dap); - if (retval != ERROR_OK) { - LOG_DEBUG("MDM: dap_run failed"); - return retval; - } - - LOG_DEBUG("MDM_REG[0x%02x]: %08" PRIX32, reg, *result); - return ERROR_OK; -} - -static int kinetis_ke_mdm_poll_register(struct adiv5_dap *dap, unsigned reg, uint32_t mask, uint32_t value) -{ - uint32_t val; - int retval; - int timeout = MDM_ACCESS_TIMEOUT; - - do { - retval = kinetis_ke_mdm_read_register(dap, reg, &val); - if (retval != ERROR_OK || (val & mask) == value) - return retval; - - alive_sleep(1); - } while (timeout--); - - LOG_DEBUG("MDM: polling timed out"); - return ERROR_FAIL; -} - -static int kinetis_ke_prepare_flash(struct flash_bank *bank) -{ - struct target *target = bank->target; - struct kinetis_ke_flash_bank *kinfo = bank->driver_priv; - uint8_t c2, c3, c4, s = 0; - uint16_t trim_value = 0; - uint16_t timeout = 0; - uint32_t bus_clock = 0; - uint32_t bus_reg_val = 0; - uint32_t bus_reg_addr = 0; - uint32_t flash_clk_div; - uint8_t fclkdiv; - int result; - - /* - * The RM states that the flash clock has to be set to 1MHz for writing and - * erasing operations (otherwise it can damage the flash). - * This function configures the entire clock tree to make sure we - * run at the specified clock. We'll set FEI mode running from the ~32KHz - * internal clock. So we need to: - * - Trim internal clock. - * - Configure the divider for ICSOUTCLK (ICS module). - * - Configure the divider to get a bus clock (SIM module). - * - Configure the flash clock that depends on the bus clock. - * - * For MKE02_40 and MKE02_20 we set ICSOUTCLK = 20MHz and bus clock = 20MHz. - * For MKE04 and MKE06 we run at ICSOUTCLK = 48MHz and bus clock = 24MHz. - */ - - /* - * Trim internal clock - */ - switch (KINETIS_KE_SRSID_SUBFAMID(kinfo->sim_srsid)) { - - case KINETIS_KE_SRSID_KEX2: - /* Both KE02_20 and KE02_40 should get the same trim value */ - trim_value = 0x4C; - break; - - case KINETIS_KE_SRSID_KEX4: - trim_value = 0x54; - break; - - case KINETIS_KE_SRSID_KEX6: - trim_value = 0x58; - break; - } - - result = target_read_u8(target, ICS_C4, &c4); - if (result != ERROR_OK) - return result; - - c3 = trim_value; - c4 = (c4 & ~(ICS_C4_SCFTRIM_MASK)) | ((trim_value >> 8) & 0x01); - - result = target_write_u8(target, ICS_C3, c3); - if (result != ERROR_OK) - return result; - - result = target_write_u8(target, ICS_C4, c4); - if (result != ERROR_OK) - return result; - - result = target_read_u8(target, ICS_S, &s); - if (result != ERROR_OK) - return result; - - /* Wait */ - while (!(s & ICS_S_LOCK_MASK)) { - - if (timeout <= 1000) { - timeout++; - alive_sleep(1); - } else { - return ERROR_FAIL; - } - - result = target_read_u8(target, ICS_S, &s); - if (result != ERROR_OK) - return result; - } - - /* ... trim done ... */ - - /* - * Configure SIM (bus clock) - */ - switch (KINETIS_KE_SRSID_SUBFAMID(kinfo->sim_srsid)) { - - /* KE02 sub-family operates on SIM_BUSDIV */ - case KINETIS_KE_SRSID_KEX2: - bus_reg_val = 0; - bus_reg_addr = SIM_BUSDIV; - bus_clock = 20000000; - break; - - /* KE04 and KE06 sub-family operates on SIM_CLKDIV - * Clocks are divided by: - * DIV1 = core clock = 48MHz - * DIV2 = bus clock = 24Mhz - * DIV3 = timer clocks - * So we need to configure SIM_CLKDIV, DIV1 and DIV2 value - */ - case KINETIS_KE_SRSID_KEX4: - /* KE04 devices have the SIM_CLKDIV register at a different offset - * depending on the pin count. */ - switch (KINETIS_KE_SRSID_PINCOUNT(kinfo->sim_srsid)) { - - /* 16, 20 and 24 pins */ - case 1: - case 2: - case 3: - bus_reg_addr = SIM_CLKDIV_KE04_16_20_24; - break; - - /* 44, 64 and 80 pins */ - case 5: - case 7: - case 8: - bus_reg_addr = SIM_CLKDIV_KE04_44_64_80; - break; - - default: - LOG_ERROR("KE04 - Unknown pin count"); - return ERROR_FAIL; - } - - bus_reg_val = SIM_CLKDIV_OUTDIV2_MASK; - bus_clock = 24000000; - break; - - case KINETIS_KE_SRSID_KEX6: - bus_reg_val = SIM_CLKDIV_OUTDIV2_MASK; - bus_reg_addr = SIM_CLKDIV_KE06; - bus_clock = 24000000; - break; - } - - result = target_write_u32(target, bus_reg_addr, bus_reg_val); - if (result != ERROR_OK) - return result; - - /* - * Configure ICS to FEI (internal source) - */ - result = target_read_u8(target, ICS_C2, &c2); - if (result != ERROR_OK) - return result; - - c2 &= ~ICS_C2_BDIV_MASK; - - switch (KINETIS_KE_SRSID_SUBFAMID(kinfo->sim_srsid)) { - - case KINETIS_KE_SRSID_KEX2: - /* Note: since there are two KE02 types, the KE02_40 @ 40MHz and the - * KE02_20 @ 20MHz, we divide here the ~40MHz ICSFLLCLK down to 20MHz, - * for compatibility. - */ - c2 |= ICS_C2_BDIV(1); - break; - - case KINETIS_KE_SRSID_KEX4: - case KINETIS_KE_SRSID_KEX6: - /* For KE04 and KE06, the ICSFLLCLK can be 48MHz. */ - c2 |= ICS_C2_BDIV(0); - break; - } - - result = target_write_u8(target, ICS_C2, c2); - if (result != ERROR_OK) - return result; - - /* Internal clock as reference (IREFS = 1) */ - result = target_write_u8(target, ICS_C1, 4); - if (result != ERROR_OK) - return result; - - /* Wait for FLL to lock */ - result = target_read_u8(target, ICS_S, &s); - if (result != ERROR_OK) - return result; - - while (!(s & ICS_S_LOCK_MASK)) { - - if (timeout <= 1000) { - timeout++; - alive_sleep(1); - } else { - return ERROR_FLASH_OPERATION_FAILED; - } - - result = target_read_u8(target, ICS_S, &s); - if (result != ERROR_OK) - return result; - } - - /* - * Configure flash clock to 1MHz. - */ - flash_clk_div = bus_clock / 1000000L - 1; - - /* Check if the FCLKDIV register is locked */ - result = target_read_u8(target, kinfo->ftmrx_fclkdiv_addr, &fclkdiv); - if (result != ERROR_OK) - return result; - - if (!(fclkdiv & FTMRX_FCLKDIV_FDIVLCK_MASK)) { - /* Unlocked. Check if the register was configured, and if so, if it has the right value */ - if ((fclkdiv & FTMRX_FCLKDIV_FDIVLD_MASK) && - ((fclkdiv & FTMRX_FCLKDIV_FDIV_MASK) != FTMRX_FCLKDIV_FDIV(flash_clk_div))) { - LOG_WARNING("Flash clock was already set and contains an invalid value."); - LOG_WARNING("Please reset the target."); - return ERROR_FAIL; - } - - /* Finally, configure the flash clock */ - fclkdiv = (fclkdiv & ~(FTMRX_FCLKDIV_FDIV_MASK)) | FTMRX_FCLKDIV_FDIV(flash_clk_div); - result = target_write_u8(target, kinfo->ftmrx_fclkdiv_addr, fclkdiv); - if (result != ERROR_OK) - return result; - } else { - /* Locked. Check if the current value is correct. */ - if ((fclkdiv & FTMRX_FCLKDIV_FDIV_MASK) != FTMRX_FCLKDIV_FDIV(flash_clk_div)) { - LOG_WARNING("Flash clock register is locked and contains an invalid value."); - LOG_WARNING("Please reset the target."); - return ERROR_FAIL; - } - } - - LOG_INFO("Flash clock ready"); - return ERROR_OK; -} - -int kinetis_ke_stop_watchdog(struct target *target) -{ - struct working_area *watchdog_algorithm; - struct armv7m_algorithm armv7m_info; - int retval; - uint8_t cs1; - - static const uint8_t watchdog_code[] = { -#include "../../../contrib/loaders/flash/kinetis_ke/kinetis_ke_watchdog.inc" - }; - - if (target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - /* Check if the watchdog is enabled */ - retval = target_read_u8(target, WDOG_CS1, &cs1); - if (retval != ERROR_OK) - return retval; - - if (!(cs1 & 0x80)) { - /* Already stopped */ - return ERROR_OK; - } - - /* allocate working area with watchdog code */ - if (target_alloc_working_area(target, sizeof(watchdog_code), &watchdog_algorithm) != ERROR_OK) { - LOG_WARNING("No working area available for watchdog algorithm"); - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - } - - retval = target_write_buffer(target, watchdog_algorithm->address, - sizeof(watchdog_code), watchdog_code); - if (retval != ERROR_OK) - return retval; - - armv7m_info.common_magic = ARMV7M_COMMON_MAGIC; - armv7m_info.core_mode = ARM_MODE_THREAD; - - retval = target_run_algorithm(target, 0, NULL, 0, NULL, - watchdog_algorithm->address, 0, 100000, &armv7m_info); - if (retval != ERROR_OK) { - LOG_ERROR("Error executing Kinetis KE watchdog algorithm"); - retval = ERROR_FAIL; - } else { - LOG_INFO("Watchdog stopped"); - } - - target_free_working_area(target, watchdog_algorithm); - - return ERROR_OK; -} - -COMMAND_HANDLER(kinetis_ke_disable_wdog_handler) -{ - struct target *target = get_current_target(CMD_CTX); - - if (CMD_ARGC > 0) - return ERROR_COMMAND_SYNTAX_ERROR; - - return kinetis_ke_stop_watchdog(target); -} - -COMMAND_HANDLER(kinetis_ke_mdm_mass_erase) -{ - 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; - - if (!dap) { - LOG_ERROR("Cannot perform mass erase with a high-level adapter"); - return ERROR_FAIL; - } - - int retval; - - /* According to chapter 18.3.7.2 of the KE02 reference manual */ - - /* assert SRST */ - if (jtag_get_reset_config() & RESET_HAS_SRST) - adapter_assert_reset(); - - /* - * 1. Reset the device by asserting RESET pin or DAP_CTRL[3] - */ - retval = kinetis_ke_mdm_write_register(dap, MDM_REG_CTRL, MEM_CTRL_SYS_RES_REQ); - if (retval != ERROR_OK) - return retval; - - /* - * ... Read the MDM-AP status register until the Flash Ready bit sets... - */ - retval = kinetis_ke_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; - } - - /* - * 2. Set DAP_CTRL[0] bit to invoke debug mass erase via SWD - * 3. Release reset by deasserting RESET pin or DAP_CTRL[3] bit via SWD. - */ - retval = kinetis_ke_mdm_write_register(dap, MDM_REG_CTRL, MEM_CTRL_FMEIP); - if (retval != ERROR_OK) - return retval; - - /* As a sanity check make sure that device started mass erase procedure */ - retval = kinetis_ke_mdm_poll_register(dap, MDM_REG_STAT, - MDM_STAT_FMEACK, MDM_STAT_FMEACK); - if (retval != ERROR_OK) - return retval; - - /* - * 4. Wait till DAP_CTRL[0] bit is cleared (after mass erase completes, - * DAP_CTRL[0] bit is cleared automatically). - */ - retval = kinetis_ke_mdm_poll_register(dap, MDM_REG_CTRL, - MEM_CTRL_FMEIP, - 0); - if (retval != ERROR_OK) - return retval; - - if (jtag_get_reset_config() & RESET_HAS_SRST) - adapter_deassert_reset(); - - return ERROR_OK; -} - -static const uint32_t kinetis_ke_known_mdm_ids[] = { - 0x001C0020, /* Kinetis-L/M/V/E/KE Series */ -}; - -/* - * This function implements the procedure to connect to - * 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.1.1 - */ -COMMAND_HANDLER(kinetis_ke_check_flash_security_status) -{ - 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; - - if (!dap) { - LOG_WARNING("Cannot check flash security status with a high-level adapter"); - return ERROR_OK; - } - - uint32_t val; - int retval; - - /* - * ... The MDM-AP ID register can be read to verify that the - * connection is working correctly... - */ - retval = kinetis_ke_mdm_read_register(dap, MDM_REG_ID, &val); - if (retval != ERROR_OK) { - LOG_ERROR("MDM: failed to read ID register"); - goto fail; - } - - bool found = false; - for (size_t i = 0; i < ARRAY_SIZE(kinetis_ke_known_mdm_ids); i++) { - if (val == kinetis_ke_known_mdm_ids[i]) { - found = true; - break; - } - } - - if (!found) - LOG_WARNING("MDM: unknown ID %08" PRIX32, val); - - /* - * ... Read the MDM-AP status register until the Flash Ready bit sets... - */ - retval = kinetis_ke_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 - * communication with the internals of the processor, including the - * flash, will not be possible without issuing a mass erase command or - * unsecuring the part through other means (backdoor key unlock)... - */ - retval = kinetis_ke_mdm_read_register(dap, MDM_REG_STAT, &val); - if (retval != ERROR_OK) { - LOG_ERROR("MDM: failed to read MDM_REG_STAT"); - goto fail; - } - - if (val & MDM_STAT_SYSSEC) { - jtag_poll_set_enabled(false); - - LOG_WARNING("*********** ATTENTION! ATTENTION! ATTENTION! ATTENTION! **********"); - LOG_WARNING("**** ****"); - LOG_WARNING("**** Your Kinetis MCU is in secured state, which means that, ****"); - LOG_WARNING("**** with exception for very basic communication, JTAG/SWD ****"); - LOG_WARNING("**** interface will NOT work. In order to restore its ****"); - LOG_WARNING("**** functionality please issue 'kinetis_ke mdm mass_erase' ****"); - LOG_WARNING("**** command, power cycle the MCU and restart OpenOCD. ****"); - LOG_WARNING("**** ****"); - LOG_WARNING("*********** ATTENTION! ATTENTION! ATTENTION! ATTENTION! **********"); - } 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_ke_flash_bank_command) -{ - struct kinetis_ke_flash_bank *bank_info; - - if (CMD_ARGC < 6) - return ERROR_COMMAND_SYNTAX_ERROR; - - LOG_INFO("add flash_bank kinetis_ke %s", bank->name); - - bank_info = malloc(sizeof(struct kinetis_ke_flash_bank)); - - memset(bank_info, 0, sizeof(struct kinetis_ke_flash_bank)); - - bank->driver_priv = bank_info; - - return ERROR_OK; -} - -/* Kinetis Program-LongWord Microcodes */ -static uint8_t kinetis_ke_flash_write_code[] = { -#include "../../../contrib/loaders/flash/kinetis_ke/kinetis_ke_flash.inc" -}; - -static int kinetis_ke_write_words(struct flash_bank *bank, const uint8_t *buffer, - uint32_t offset, uint32_t words) -{ - struct kinetis_ke_flash_bank *kinfo = bank->driver_priv; - struct target *target = bank->target; - uint32_t ram_buffer_size = 512 + 16; - struct working_area *write_algorithm; - struct working_area *source; - uint32_t address = bank->base + offset; - struct reg_param reg_params[4]; - struct armv7m_algorithm armv7m_info; - int retval = ERROR_OK; - uint32_t flash_code_size; - - LOG_INFO("Kinetis KE: FLASH Write ..."); - - /* allocate working area with flash programming code */ - if (target_alloc_working_area(target, sizeof(kinetis_ke_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; - } - - /* Patch the FTMRx registers addresses */ - flash_code_size = sizeof(kinetis_ke_flash_write_code); - buf_set_u32(&kinetis_ke_flash_write_code[flash_code_size-16], 0, 32, kinfo->ftmrx_fstat_addr); - buf_set_u32(&kinetis_ke_flash_write_code[flash_code_size-12], 0, 32, kinfo->ftmrx_fccobix_addr); - buf_set_u32(&kinetis_ke_flash_write_code[flash_code_size-8], 0, 32, kinfo->ftmrx_fccobhi_addr); - buf_set_u32(&kinetis_ke_flash_write_code[flash_code_size-4], 0, 32, kinfo->ftmrx_fccoblo_addr); - - retval = target_write_buffer(target, write_algorithm->address, - sizeof(kinetis_ke_flash_write_code), kinetis_ke_flash_write_code); - if (retval != ERROR_OK) - return retval; - - /* memory buffer */ - if (target_alloc_working_area(target, ram_buffer_size, &source) != ERROR_OK) { - /* free working area, write algorithm already allocated */ - target_free_working_area(target, write_algorithm); - - 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; - - init_reg_param(®_params[0], "r0", 32, PARAM_IN_OUT); - init_reg_param(®_params[1], "r1", 32, PARAM_OUT); - init_reg_param(®_params[2], "r2", 32, PARAM_OUT); - init_reg_param(®_params[3], "r3", 32, PARAM_OUT); - - buf_set_u32(reg_params[0].value, 0, 32, address); - buf_set_u32(reg_params[1].value, 0, 32, words); - buf_set_u32(reg_params[2].value, 0, 32, source->address); - buf_set_u32(reg_params[3].value, 0, 32, source->address + source->size); - - retval = target_run_flash_async_algorithm(target, buffer, words, 4, - 0, NULL, - 4, reg_params, - source->address, source->size, - write_algorithm->address, 0, - &armv7m_info); - - if (retval == ERROR_FLASH_OPERATION_FAILED) { - if (buf_get_u32(reg_params[0].value, 0, 32) & FTMRX_ERROR_ACCERR) - LOG_ERROR("flash access error"); - - if (buf_get_u32(reg_params[0].value, 0, 32) & FTMRX_ERROR_FPVIOL) - LOG_ERROR("flash protection violation"); - } - - target_free_working_area(target, source); - target_free_working_area(target, write_algorithm); - - destroy_reg_param(®_params[0]); - destroy_reg_param(®_params[1]); - destroy_reg_param(®_params[2]); - destroy_reg_param(®_params[3]); - - return retval; -} - -static int kinetis_ke_protect(struct flash_bank *bank, int set, int first, int last) -{ - LOG_WARNING("kinetis_ke_protect not supported yet"); - /* FIXME: TODO */ - - if (bank->target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - return ERROR_FLASH_BANK_INVALID; -} - -static int kinetis_ke_protect_check(struct flash_bank *bank) -{ - struct kinetis_ke_flash_bank *kinfo = bank->driver_priv; - - if (bank->target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - int result; - uint8_t fprot; - uint8_t fpopen, fpldis, fphdis; - uint8_t fphs, fpls; - uint32_t lprot_size = 0, hprot_size = 0; - uint32_t lprot_to = 0, hprot_from = 0; - - /* read protection register */ - result = target_read_u8(bank->target, kinfo->ftmrx_fprot_addr, &fprot); - - if (result != ERROR_OK) - return result; - - fpopen = fprot & 0x80; - fpldis = fprot & 0x04; - fphdis = fprot & 0x20; - fphs = (fprot >> 3) & 0x03; - fpls = fprot & 0x03; - - /* Fully unprotected? */ - if (fpopen && fpldis && fphdis) { - LOG_WARNING("No flash protection found."); - - for (uint32_t i = 0; i < (uint32_t) bank->num_sectors; i++) - bank->sectors[i].is_protected = 0; - - kinfo->protection_size = 0; - } else { - LOG_WARNING("Flash protected. FPOPEN=%i FPLDIS=%i FPHDIS=%i FPLS=%i FPHS=%i", \ - fpopen ? 1 : 0, fpldis ? 1 : 0, fphdis ? 1 : 0, fpls, fphs); - - /* Retrieve which region is protected and how much */ - if (fpopen) { - if (fpldis == 0) - lprot_size = (kinfo->sector_size * 4) << fpls; - - if (fphdis == 0) - hprot_size = (kinfo->sector_size * 2) << fphs; - } else { - if (fpldis == 1) - lprot_size = (kinfo->sector_size * 4) << fpls; - - if (fphdis == 1) - hprot_size = (kinfo->sector_size * 2) << fphs; - } - - kinfo->protection_size = lprot_size + hprot_size; - - /* lprot_to indicates up to where the lower region is protected */ - lprot_to = lprot_size / kinfo->sector_size; - - /* hprot_from indicates from where the upper region is protected */ - hprot_from = (0x8000 - hprot_size) / kinfo->sector_size; - - for (uint32_t i = 0; i < (uint32_t) bank->num_sectors; i++) { - - /* Check if the sector is in the lower region */ - if (bank->sectors[i].offset < 0x4000) { - /* Compare the sector start address against lprot_to */ - if (lprot_to && (i < lprot_to)) - bank->sectors[i].is_protected = 1; - else - bank->sectors[i].is_protected = 0; - - /* Check if the sector is between the lower and upper region - * OR after the upper region */ - } else if (bank->sectors[i].offset < 0x6000 || bank->sectors[i].offset >= 0x8000) { - /* If fpopen is 1 then these regions are protected */ - if (fpopen) - bank->sectors[i].is_protected = 0; - else - bank->sectors[i].is_protected = 1; - - /* Check if the sector is in the upper region */ - } else if (bank->sectors[i].offset < 0x8000) { - if (hprot_from && (i > hprot_from)) - bank->sectors[i].is_protected = 1; - else - bank->sectors[i].is_protected = 0; - } - } - } - - return ERROR_OK; -} - -static int kinetis_ke_ftmrx_command(struct flash_bank *bank, uint8_t count, - uint8_t *FCCOBIX, uint8_t *FCCOBHI, uint8_t *FCCOBLO, uint8_t *fstat) -{ - uint8_t i; - int result; - struct target *target = bank->target; - struct kinetis_ke_flash_bank *kinfo = bank->driver_priv; - uint32_t timeout = 0; - - /* Clear error flags */ - result = target_write_u8(target, kinfo->ftmrx_fstat_addr, 0x30); - if (result != ERROR_OK) - return result; - - for (i = 0; i < count; i++) { - /* Write index */ - result = target_write_u8(target, kinfo->ftmrx_fccobix_addr, FCCOBIX[i]); - if (result != ERROR_OK) - return result; - - /* Write high part */ - result = target_write_u8(target, kinfo->ftmrx_fccobhi_addr, FCCOBHI[i]); - if (result != ERROR_OK) - return result; - - /* Write low part (that is not always required) */ - if (FCCOBLO) { - result = target_write_u8(target, kinfo->ftmrx_fccoblo_addr, FCCOBLO[i]); - if (result != ERROR_OK) - return result; - } - } - - /* Launch the command */ - result = target_write_u8(target, kinfo->ftmrx_fstat_addr, 0x80); - if (result != ERROR_OK) - return result; - - /* Wait for it to finish */ - result = target_read_u8(target, kinfo->ftmrx_fstat_addr, fstat); - if (result != ERROR_OK) - return result; - - while (!(*fstat & FTMRX_FSTAT_CCIF_MASK)) { - if (timeout <= 1000) { - timeout++; - alive_sleep(1); - } else { - return ERROR_FLASH_OPERATION_FAILED; - } - - result = target_read_u8(target, kinfo->ftmrx_fstat_addr, fstat); - if (result != ERROR_OK) - return result; - } - - return ERROR_OK; -} - -COMMAND_HANDLER(kinetis_ke_securing_test) -{ - int result; - struct target *target = get_current_target(CMD_CTX); - struct flash_bank *bank = NULL; - uint32_t address; - - uint8_t FCCOBIX[2], FCCOBHI[2], FCCOBLO[2], fstat; - - result = get_flash_bank_by_addr(target, 0x00000000, true, &bank); - if (result != ERROR_OK) - return result; - - assert(bank != NULL); - - if (target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - address = bank->base + 0x00000400; - - FCCOBIX[0] = 0; - FCCOBHI[0] = FTMRX_CMD_ERASESECTOR; - FCCOBLO[0] = address >> 16; - - FCCOBIX[1] = 1; - FCCOBHI[1] = address >> 8; - FCCOBLO[1] = address; - - return kinetis_ke_ftmrx_command(bank, 2, FCCOBIX, FCCOBHI, FCCOBLO, &fstat); -} - -static int kinetis_ke_erase(struct flash_bank *bank, int first, int last) -{ - int result, i; - uint8_t FCCOBIX[2], FCCOBHI[2], FCCOBLO[2], fstat; - bool fcf_erased = false; - - if (bank->target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - if ((first > bank->num_sectors) || (last > bank->num_sectors)) - return ERROR_FLASH_OPERATION_FAILED; - - result = kinetis_ke_prepare_flash(bank); - if (result != ERROR_OK) - return result; - - for (i = first; i <= last; i++) { - FCCOBIX[0] = 0; - FCCOBHI[0] = FTMRX_CMD_ERASESECTOR; - FCCOBLO[0] = (bank->base + bank->sectors[i].offset) >> 16; - - FCCOBIX[1] = 1; - FCCOBHI[1] = (bank->base + bank->sectors[i].offset) >> 8; - FCCOBLO[1] = (bank->base + bank->sectors[i].offset); - - result = kinetis_ke_ftmrx_command(bank, 2, FCCOBIX, FCCOBHI, FCCOBLO, &fstat); - - if (result != ERROR_OK) { - LOG_WARNING("erase sector %d failed", i); - return ERROR_FLASH_OPERATION_FAILED; - } - - bank->sectors[i].is_erased = 1; - - if (i == 2) - fcf_erased = true; - } - - if (fcf_erased) { - LOG_WARNING - ("flash configuration field erased, please reset the device"); - } - - return ERROR_OK; -} - -static int kinetis_ke_write(struct flash_bank *bank, const uint8_t *buffer, - uint32_t offset, uint32_t count) -{ - int result; - uint8_t *new_buffer = NULL; - uint32_t words = count / 4; - - if (bank->target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - if (offset > bank->size) - return ERROR_FLASH_BANK_INVALID; - - if (offset & 0x3) { - LOG_WARNING("offset 0x%" PRIx32 " breaks the required alignment", offset); - return ERROR_FLASH_DST_BREAKS_ALIGNMENT; - } - - result = kinetis_ke_stop_watchdog(bank->target); - if (result != ERROR_OK) - return result; - - result = kinetis_ke_prepare_flash(bank); - if (result != ERROR_OK) - return result; - - if (count & 0x3) { - uint32_t old_count = count; - count = (old_count | 3) + 1; - new_buffer = malloc(count); - if (new_buffer == NULL) { - LOG_ERROR("odd number of bytes to write and no memory " - "for padding buffer"); - return ERROR_FAIL; - } - - LOG_INFO("odd number of bytes to write (%" PRIu32 "), extending to %" PRIu32 " " - "and padding with 0xff", old_count, count); - - memset(new_buffer, 0xff, count); - buffer = memcpy(new_buffer, buffer, old_count); - words++; - } - - result = kinetis_ke_write_words(bank, buffer, offset, words); - free(new_buffer); - - return result; -} - -static int kinetis_ke_probe(struct flash_bank *bank) -{ - int result, i; - uint32_t offset = 0; - struct target *target = bank->target; - struct kinetis_ke_flash_bank *kinfo = bank->driver_priv; - - result = target_read_u32(target, SIM_SRSID, &kinfo->sim_srsid); - if (result != ERROR_OK) - return result; - - if (KINETIS_KE_SRSID_FAMID(kinfo->sim_srsid) != 0x00) { - LOG_ERROR("Unsupported KE family"); - return ERROR_FLASH_OPER_UNSUPPORTED; - } - - switch (KINETIS_KE_SRSID_SUBFAMID(kinfo->sim_srsid)) { - case KINETIS_KE_SRSID_KEX2: - LOG_INFO("KE02 sub-family"); - break; - - case KINETIS_KE_SRSID_KEX4: - LOG_INFO("KE04 sub-family"); - break; - - case KINETIS_KE_SRSID_KEX6: - LOG_INFO("KE06 sub-family"); - break; - - default: - LOG_ERROR("Unsupported KE sub-family"); - return ERROR_FLASH_OPER_UNSUPPORTED; - } - - /* We can only retrieve the ke0x part, but there is no way to know - * the flash size, so assume the maximum flash size for the entire - * sub family. - */ - bank->base = 0x00000000; - kinfo->sector_size = 512; - - switch (KINETIS_KE_SRSID_SUBFAMID(kinfo->sim_srsid)) { - - case KINETIS_KE_SRSID_KEX2: - /* Max. 64KB */ - bank->size = 0x00010000; - bank->num_sectors = 128; - - /* KE02 uses the FTMRH flash controller, - * and registers have a different offset from the - * FTMRE flash controller. Sort this out here. - */ - kinfo->ftmrx_fclkdiv_addr = 0x40020000; - kinfo->ftmrx_fccobix_addr = 0x40020002; - kinfo->ftmrx_fstat_addr = 0x40020006; - kinfo->ftmrx_fprot_addr = 0x40020008; - kinfo->ftmrx_fccobhi_addr = 0x4002000A; - kinfo->ftmrx_fccoblo_addr = 0x4002000B; - break; - - case KINETIS_KE_SRSID_KEX6: - case KINETIS_KE_SRSID_KEX4: - /* Max. 128KB */ - bank->size = 0x00020000; - bank->num_sectors = 256; - - /* KE04 and KE06 use the FTMRE flash controller, - * and registers have a different offset from the - * FTMRH flash controller. Sort this out here. - */ - kinfo->ftmrx_fclkdiv_addr = 0x40020003; - kinfo->ftmrx_fccobix_addr = 0x40020001; - kinfo->ftmrx_fstat_addr = 0x40020005; - kinfo->ftmrx_fprot_addr = 0x4002000B; - kinfo->ftmrx_fccobhi_addr = 0x40020009; - kinfo->ftmrx_fccoblo_addr = 0x40020008; - break; - } - - if (bank->sectors) { - free(bank->sectors); - bank->sectors = NULL; - } - - 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; - } - - return ERROR_OK; -} - -static int kinetis_ke_auto_probe(struct flash_bank *bank) -{ - struct kinetis_ke_flash_bank *kinfo = bank->driver_priv; - - if (kinfo->sim_srsid) - return ERROR_OK; - - return kinetis_ke_probe(bank); -} - -static int kinetis_ke_info(struct flash_bank *bank, char *buf, int buf_size) -{ - (void) snprintf(buf, buf_size, - "%s driver for flash bank %s at 0x%8.8" PRIx32 "", - bank->driver->name, bank->name, bank->base); - - return ERROR_OK; -} - -static int kinetis_ke_blank_check(struct flash_bank *bank) -{ - uint8_t FCCOBIX[3], FCCOBHI[3], FCCOBLO[3], fstat; - uint16_t longwords = 0; - int result; - - if (bank->target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - result = kinetis_ke_prepare_flash(bank); - if (result != ERROR_OK) - return result; - - /* check if whole bank is blank */ - FCCOBIX[0] = 0; - FCCOBHI[0] = FTMRX_CMD_ALLERASED; - - result = kinetis_ke_ftmrx_command(bank, 1, FCCOBIX, FCCOBHI, NULL, &fstat); - - if (result != ERROR_OK) - return result; - - if (fstat & (FTMRX_FSTAT_MGSTAT0_MASK | FTMRX_FSTAT_MGSTAT1_MASK)) { - /* the whole bank is not erased, check sector-by-sector */ - int i; - - for (i = 0; i < bank->num_sectors; i++) { - FCCOBIX[0] = 0; - FCCOBHI[0] = FTMRX_CMD_SECTIONERASED; - FCCOBLO[0] = (bank->base + bank->sectors[i].offset) >> 16; - - FCCOBIX[1] = 1; - FCCOBHI[1] = (bank->base + bank->sectors[i].offset) >> 8; - FCCOBLO[1] = (bank->base + bank->sectors[i].offset); - - longwords = 128; - - FCCOBIX[2] = 2; - FCCOBHI[2] = longwords >> 8; - FCCOBLO[2] = longwords; - - result = kinetis_ke_ftmrx_command(bank, 3, FCCOBIX, FCCOBHI, FCCOBLO, &fstat); - - if (result == ERROR_OK) { - bank->sectors[i].is_erased = !(fstat & (FTMRX_FSTAT_MGSTAT0_MASK | FTMRX_FSTAT_MGSTAT1_MASK)); - } else { - LOG_DEBUG("Ignoring errored PFlash sector blank-check"); - bank->sectors[i].is_erased = -1; - } - } - } else { - /* the whole bank is erased, update all sectors */ - int i; - for (i = 0; i < bank->num_sectors; i++) - bank->sectors[i].is_erased = 1; - } - - return ERROR_OK; -} - -static const struct command_registration kinetis_ke_security_command_handlers[] = { - { - .name = "check_security", - .mode = COMMAND_EXEC, - .help = "", - .usage = "", - .handler = kinetis_ke_check_flash_security_status, - }, - { - .name = "mass_erase", - .mode = COMMAND_EXEC, - .help = "", - .usage = "", - .handler = kinetis_ke_mdm_mass_erase, - }, - { - .name = "test_securing", - .mode = COMMAND_EXEC, - .help = "", - .usage = "", - .handler = kinetis_ke_securing_test, - }, - COMMAND_REGISTRATION_DONE -}; - -static const struct command_registration kinetis_ke_exec_command_handlers[] = { - { - .name = "mdm", - .mode = COMMAND_ANY, - .help = "", - .usage = "", - .chain = kinetis_ke_security_command_handlers, - }, - { - .name = "disable_wdog", - .mode = COMMAND_EXEC, - .help = "Disable the watchdog timer", - .usage = "", - .handler = kinetis_ke_disable_wdog_handler, - }, - COMMAND_REGISTRATION_DONE -}; - -static const struct command_registration kinetis_ke_command_handler[] = { - { - .name = "kinetis_ke", - .mode = COMMAND_ANY, - .help = "Kinetis KE NAND flash controller commands", - .usage = "", - .chain = kinetis_ke_exec_command_handlers, - }, - COMMAND_REGISTRATION_DONE -}; - -struct flash_driver kinetis_ke_flash = { - .name = "kinetis_ke", - .commands = kinetis_ke_command_handler, - .flash_bank_command = kinetis_ke_flash_bank_command, - .erase = kinetis_ke_erase, - .protect = kinetis_ke_protect, - .write = kinetis_ke_write, - .read = default_flash_read, - .probe = kinetis_ke_probe, - .auto_probe = kinetis_ke_auto_probe, - .erase_check = kinetis_ke_blank_check, - .protect_check = kinetis_ke_protect_check, - .info = kinetis_ke_info, -}; diff --git a/src/flash/nor/lpc2000.c b/src/flash/nor/lpc2000.c deleted file mode 100644 index 76cd86b7f..000000000 --- a/src/flash/nor/lpc2000.c +++ /dev/null @@ -1,1573 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * LPC1700 support Copyright (C) 2009 by Audrius Urmanavicius * - * didele.deze@gmail.com * - * * - * LPC1100 variant and auto-probing support Copyright (C) 2014 * - * by Cosmin Gorgovan cosmin [at] linux-geek [dot] org * - * * - * LPC800/LPC1500/LPC54100 support Copyright (C) 2013/2014 * - * by Nemui Trinomius * - * nemuisan_kawausogasuki@live.jp * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "imp.h" -#include -#include -#include -#include - -/** - * @file - * flash programming support for NXP LPC8xx,LPC1xxx,LPC4xxx,LP5410x and LPC2xxx devices. - * - * @todo Provide a way to update CCLK after declaring the flash bank. The value which is correct after chip reset will - * rarely still work right after the clocks switch to use the PLL (e.g. 4MHz --> 100 MHz). - */ -/* - * currently supported devices: - * variant 1 (lpc2000_v1): - * - 2104 | 5 | 6 - * - 2114 | 9 - * - 2124 | 9 - * - 2194 - * - 2212 | 4 - * - 2292 | 4 - * - * variant 2 (lpc2000_v2): - * - 213x - * - 214x - * - 2101 | 2 | 3 - * - 2364 | 6 | 8 - * - 2378 - * - * lpc1700: - * - 175x - * - 176x (tested with LPC1768) - * - 177x - * - 178x (tested with LPC1788) - * - * lpc4000: (lpc1700's alias) - * - 407x - * - 408x (tested with LPC4088) - * - * lpc4300: (also available as lpc1800 - alias) - * - 43x2 | 3 | 5 | 7 (tested with LPC4337/LPC4357) - * - 18x2 | 3 | 5 | 7 - * - * lpc800: - * - 810 | 1 | 2 (tested with LPC810/LPC811/LPC812) - * - 822 | 4 (tested with LPC824) - * - * lpc1100: - * - 11xx - * - 11Axx - * - 11Cxx - * - 11Dxx - * - 11Exx - * - 11Uxx (tested with LPC11U34) - * - 131x - * - 134x - * - * lpc1500: - * - 15x7 | 8 | 9 (tested with LPC1549) - * - * lpc54100: - * - 54101 | 2 (tested with LPC54102) - * - * The auto variant auto-detects parts from the following series: - * - 11xx - * - 11Axx - * - 11Cxx - * - 11Dxx - * - 11Exx - * - 11Uxx - * - 131x - * - 134x - * - 175x - * - 176x - * - 177x - * - 178x - * - 407x - * - 408x - * - 81x - * - 82x - */ - -/* Part IDs for autodetection */ -/* A script which can automatically extract part ids from user manuals is available here: - * https://github.com/lgeek/lpc_part_ids - */ -#define LPC1110_1 0x0A07102B -#define LPC1110_2 0x1A07102B -#define LPC1111_002_1 0x0A16D02B -#define LPC1111_002_2 0x1A16D02B -#define LPC1111_101_1 0x041E502B -#define LPC1111_101_2 0x2516D02B -#define LPC1111_103_1 0x00010013 -#define LPC1111_201_1 0x0416502B -#define LPC1111_201_2 0x2516902B -#define LPC1111_203_1 0x00010012 -#define LPC1112_101_1 0x042D502B -#define LPC1112_101_2 0x2524D02B -#define LPC1112_102_1 0x0A24902B -#define LPC1112_102_2 0x1A24902B -#define LPC1112_103_1 0x00020023 -#define LPC1112_201_1 0x0425502B -#define LPC1112_201_2 0x2524902B -#define LPC1112_203_1 0x00020022 -#define LPC1113_201_1 0x0434502B -#define LPC1113_201_2 0x2532902B -#define LPC1113_203_1 0x00030032 -#define LPC1113_301_1 0x0434102B -#define LPC1113_301_2 0x2532102B -#define LPC1113_303_1 0x00030030 -#define LPC1114_102_1 0x0A40902B -#define LPC1114_102_2 0x1A40902B -#define LPC1114_201_1 0x0444502B -#define LPC1114_201_2 0x2540902B -#define LPC1114_203_1 0x00040042 -#define LPC1114_301_1 0x0444102B -#define LPC1114_301_2 0x2540102B -#define LPC1114_303_1 0x00040040 -#define LPC1114_323_1 0x00040060 -#define LPC1114_333_1 0x00040070 -#define LPC1115_303_1 0x00050080 - -#define LPC11A02_1 0x4D4C802B -#define LPC11A04_1 0x4D80002B -#define LPC11A11_001_1 0x455EC02B -#define LPC11A12_101_1 0x4574802B -#define LPC11A13_201_1 0x458A402B -#define LPC11A14_301_1 0x35A0002B -#define LPC11A14_301_2 0x45A0002B - -#define LPC11C12_301_1 0x1421102B -#define LPC11C14_301_1 0x1440102B -#define LPC11C22_301_1 0x1431102B -#define LPC11C24_301_1 0x1430102B - -#define LPC11E11_101 0x293E902B -#define LPC11E12_201 0x2954502B -#define LPC11E13_301 0x296A102B -#define LPC11E14_401 0x2980102B -#define LPC11E36_501 0x00009C41 -#define LPC11E37_401 0x00007C45 -#define LPC11E37_501 0x00007C41 - -#define LPC11U12_201_1 0x095C802B -#define LPC11U12_201_2 0x295C802B -#define LPC11U13_201_1 0x097A802B -#define LPC11U13_201_2 0x297A802B -#define LPC11U14_201_1 0x0998802B -#define LPC11U14_201_2 0x2998802B -#define LPC11U23_301 0x2972402B -#define LPC11U24_301 0x2988402B -#define LPC11U24_401 0x2980002B -#define LPC11U34_311 0x0003D440 -#define LPC11U34_421 0x0001CC40 -#define LPC11U35_401 0x0001BC40 -#define LPC11U35_501 0x0000BC40 -#define LPC11U36_401 0x00019C40 -#define LPC11U37_401 0x00017C40 -#define LPC11U37H_401 0x00007C44 -#define LPC11U37_501 0x00007C40 - -#define LPC11E66 0x0000DCC1 -#define LPC11E67 0x0000BC81 -#define LPC11E68 0x00007C01 - -#define LPC11U66 0x0000DCC8 -#define LPC11U67_1 0x0000BC88 -#define LPC11U67_2 0x0000BC80 -#define LPC11U68_1 0x00007C08 -#define LPC11U68_2 0x00007C00 - -#define LPC1311 0x2C42502B -#define LPC1311_1 0x1816902B -#define LPC1313 0x2C40102B -#define LPC1313_1 0x1830102B -#define LPC1315 0x3A010523 -#define LPC1316 0x1A018524 -#define LPC1317 0x1A020525 -#define LPC1342 0x3D01402B -#define LPC1343 0x3D00002B -#define LPC1343_1 0x3000002B -#define LPC1345 0x28010541 -#define LPC1346 0x08018542 -#define LPC1347 0x08020543 - -#define LPC1751_1 0x25001110 -#define LPC1751_2 0x25001118 -#define LPC1752 0x25001121 -#define LPC1754 0x25011722 -#define LPC1756 0x25011723 -#define LPC1758 0x25013F37 -#define LPC1759 0x25113737 -#define LPC1763 0x26012033 -#define LPC1764 0x26011922 -#define LPC1765 0x26013733 -#define LPC1766 0x26013F33 -#define LPC1767 0x26012837 -#define LPC1768 0x26013F37 -#define LPC1769 0x26113F37 -#define LPC1774 0x27011132 -#define LPC1776 0x27191F43 -#define LPC1777 0x27193747 -#define LPC1778 0x27193F47 -#define LPC1785 0x281D1743 -#define LPC1786 0x281D1F43 -#define LPC1787 0x281D3747 -#define LPC1788 0x281D3F47 - -#define LPC4072 0x47011121 -#define LPC4074 0x47011132 -#define LPC4076 0x47191F43 -#define LPC4078 0x47193F47 -#define LPC4088 0x481D3F47 - -#define LPC810_021 0x00008100 -#define LPC811_001 0x00008110 -#define LPC812_101 0x00008120 -#define LPC812_101_1 0x00008121 -#define LPC812_101_2 0x00008122 -#define LPC812_101_3 0x00008123 - -#define LPC822_101 0x00008221 -#define LPC822_101_1 0x00008222 -#define LPC824_201 0x00008241 -#define LPC824_201_1 0x00008242 - -#define IAP_CODE_LEN 0x34 - -typedef enum { - lpc2000_v1, - lpc2000_v2, - lpc1700, - lpc4300, - lpc800, - lpc1100, - lpc1500, - lpc54100, - lpc_auto, -} lpc2000_variant; - -struct lpc2000_flash_bank { - lpc2000_variant variant; - uint32_t cclk; - int cmd51_dst_boundary; - int calc_checksum; - uint32_t cmd51_max_buffer; - int checksum_vector; - uint32_t iap_max_stack; - uint32_t lpc4300_bank; - bool probed; -}; - -enum lpc2000_status_codes { - LPC2000_CMD_SUCCESS = 0, - LPC2000_INVALID_COMMAND = 1, - LPC2000_SRC_ADDR_ERROR = 2, - LPC2000_DST_ADDR_ERROR = 3, - LPC2000_SRC_ADDR_NOT_MAPPED = 4, - LPC2000_DST_ADDR_NOT_MAPPED = 5, - LPC2000_COUNT_ERROR = 6, - LPC2000_INVALID_SECTOR = 7, - LPC2000_SECTOR_NOT_BLANK = 8, - LPC2000_SECTOR_NOT_PREPARED = 9, - LPC2000_COMPARE_ERROR = 10, - LPC2000_BUSY = 11, - LPC2000_PARAM_ERROR = 12, - LPC2000_ADDR_ERROR = 13, - LPC2000_ADDR_NOT_MAPPED = 14, - LPC2000_CMD_NOT_LOCKED = 15, - LPC2000_INVALID_CODE = 16, - LPC2000_INVALID_BAUD_RATE = 17, - LPC2000_INVALID_STOP_BIT = 18, - LPC2000_CRP_ENABLED = 19, - LPC2000_INVALID_FLASH_UNIT = 20, - LPC2000_USER_CODE_CHECKSUM = 21, - LCP2000_ERROR_SETTING_ACTIVE_PARTITION = 22, -}; - -static int lpc2000_build_sector_list(struct flash_bank *bank) -{ - struct lpc2000_flash_bank *lpc2000_info = bank->driver_priv; - uint32_t offset = 0; - - /* default to a 4096 write buffer */ - lpc2000_info->cmd51_max_buffer = 4096; - - if (lpc2000_info->variant == lpc2000_v1) { - lpc2000_info->cmd51_dst_boundary = 512; - lpc2000_info->checksum_vector = 5; - lpc2000_info->iap_max_stack = 128; - - /* variant 1 has different layout for 128kb and 256kb flashes */ - if (bank->size == 128 * 1024) { - bank->num_sectors = 16; - bank->sectors = malloc(sizeof(struct flash_sector) * 16); - for (int i = 0; i < 16; i++) { - bank->sectors[i].offset = offset; - bank->sectors[i].size = 8 * 1024; - offset += bank->sectors[i].size; - bank->sectors[i].is_erased = -1; - bank->sectors[i].is_protected = 1; - } - } else if (bank->size == 256 * 1024) { - bank->num_sectors = 18; - bank->sectors = malloc(sizeof(struct flash_sector) * 18); - - for (int i = 0; i < 8; i++) { - bank->sectors[i].offset = offset; - bank->sectors[i].size = 8 * 1024; - offset += bank->sectors[i].size; - bank->sectors[i].is_erased = -1; - bank->sectors[i].is_protected = 1; - } - for (int i = 8; i < 10; i++) { - bank->sectors[i].offset = offset; - bank->sectors[i].size = 64 * 1024; - offset += bank->sectors[i].size; - bank->sectors[i].is_erased = -1; - bank->sectors[i].is_protected = 1; - } - for (int i = 10; i < 18; i++) { - bank->sectors[i].offset = offset; - bank->sectors[i].size = 8 * 1024; - offset += bank->sectors[i].size; - bank->sectors[i].is_erased = -1; - bank->sectors[i].is_protected = 1; - } - } else { - LOG_ERROR("BUG: unknown bank->size encountered"); - exit(-1); - } - } else if (lpc2000_info->variant == lpc2000_v2) { - lpc2000_info->cmd51_dst_boundary = 256; - lpc2000_info->checksum_vector = 5; - lpc2000_info->iap_max_stack = 128; - - /* variant 2 has a uniform layout, only number of sectors differs */ - switch (bank->size) { - case 4 * 1024: - lpc2000_info->cmd51_max_buffer = 1024; - bank->num_sectors = 1; - break; - case 8 * 1024: - lpc2000_info->cmd51_max_buffer = 1024; - bank->num_sectors = 2; - break; - case 16 * 1024: - bank->num_sectors = 4; - break; - case 32 * 1024: - bank->num_sectors = 8; - break; - case 64 * 1024: - bank->num_sectors = 9; - break; - case 128 * 1024: - bank->num_sectors = 11; - break; - case 256 * 1024: - bank->num_sectors = 15; - break; - case 500 * 1024: - bank->num_sectors = 27; - break; - case 512 * 1024: - case 504 * 1024: - bank->num_sectors = 28; - break; - default: - LOG_ERROR("BUG: unknown bank->size encountered"); - exit(-1); - break; - } - - bank->sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors); - - for (int i = 0; i < bank->num_sectors; i++) { - if (i < 8) { - bank->sectors[i].offset = offset; - bank->sectors[i].size = 4 * 1024; - offset += bank->sectors[i].size; - bank->sectors[i].is_erased = -1; - bank->sectors[i].is_protected = 1; - } else if (i < 22) { - bank->sectors[i].offset = offset; - bank->sectors[i].size = 32 * 1024; - offset += bank->sectors[i].size; - bank->sectors[i].is_erased = -1; - bank->sectors[i].is_protected = 1; - } else if (i < 28) { - bank->sectors[i].offset = offset; - bank->sectors[i].size = 4 * 1024; - offset += bank->sectors[i].size; - bank->sectors[i].is_erased = -1; - bank->sectors[i].is_protected = 1; - } - } - } else if (lpc2000_info->variant == lpc1700) { - lpc2000_info->cmd51_dst_boundary = 256; - lpc2000_info->checksum_vector = 7; - lpc2000_info->iap_max_stack = 128; - - switch (bank->size) { - case 4 * 1024: - lpc2000_info->cmd51_max_buffer = 256; - bank->num_sectors = 1; - break; - case 8 * 1024: - lpc2000_info->cmd51_max_buffer = 512; - bank->num_sectors = 2; - break; - case 16 * 1024: - lpc2000_info->cmd51_max_buffer = 512; - bank->num_sectors = 4; - break; - case 32 * 1024: - lpc2000_info->cmd51_max_buffer = 1024; - bank->num_sectors = 8; - break; - case 64 * 1024: - bank->num_sectors = 16; - break; - case 128 * 1024: - bank->num_sectors = 18; - break; - case 256 * 1024: - bank->num_sectors = 22; - break; - case 512 * 1024: - bank->num_sectors = 30; - break; - default: - LOG_ERROR("BUG: unknown bank->size encountered"); - exit(-1); - } - - bank->sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors); - - for (int i = 0; i < bank->num_sectors; i++) { - bank->sectors[i].offset = offset; - /* sectors 0-15 are 4kB-sized, 16 and above are 32kB-sized for LPC17xx/LPC40xx devices */ - bank->sectors[i].size = (i < 16) ? 4 * 1024 : 32 * 1024; - offset += bank->sectors[i].size; - bank->sectors[i].is_erased = -1; - bank->sectors[i].is_protected = 1; - } - } else if (lpc2000_info->variant == lpc4300) { - lpc2000_info->cmd51_dst_boundary = 512; - lpc2000_info->checksum_vector = 7; - lpc2000_info->iap_max_stack = 208; - - switch (bank->size) { - case 256 * 1024: - bank->num_sectors = 11; - break; - case 384 * 1024: - bank->num_sectors = 13; - break; - case 512 * 1024: - bank->num_sectors = 15; - break; - default: - LOG_ERROR("BUG: unknown bank->size encountered"); - exit(-1); - } - - bank->sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors); - - for (int i = 0; i < bank->num_sectors; i++) { - bank->sectors[i].offset = offset; - /* sectors 0-7 are 8kB-sized, 8 and above are 64kB-sized for LPC43xx devices */ - bank->sectors[i].size = (i < 8) ? 8 * 1024 : 64 * 1024; - offset += bank->sectors[i].size; - bank->sectors[i].is_erased = -1; - bank->sectors[i].is_protected = 1; - } - - } else if (lpc2000_info->variant == lpc800) { - lpc2000_info->cmd51_dst_boundary = 64; - lpc2000_info->checksum_vector = 7; - lpc2000_info->iap_max_stack = 208; /* 148byte for LPC81x,208byte for LPC82x. */ - lpc2000_info->cmd51_max_buffer = 256; /* smallest MCU in the series, LPC810, has 1 kB of SRAM */ - - switch (bank->size) { - case 4 * 1024: - bank->num_sectors = 4; - break; - case 8 * 1024: - bank->num_sectors = 8; - break; - case 16 * 1024: - bank->num_sectors = 16; - break; - case 32 * 1024: - lpc2000_info->cmd51_max_buffer = 1024; /* For LPC824, has 8kB of SRAM */ - bank->num_sectors = 32; - break; - default: - LOG_ERROR("BUG: unknown bank->size encountered"); - exit(-1); - } - - 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 1kB-sized for LPC8xx devices */ - bank->sectors[i].size = 1 * 1024; - offset += bank->sectors[i].size; - bank->sectors[i].is_erased = -1; - bank->sectors[i].is_protected = 1; - } - - } else if (lpc2000_info->variant == lpc1100) { - lpc2000_info->cmd51_dst_boundary = 256; - lpc2000_info->checksum_vector = 7; - lpc2000_info->iap_max_stack = 128; - - if ((bank->size % (4 * 1024)) != 0) { - LOG_ERROR("BUG: unknown bank->size encountered,\nLPC1100 flash size must be a multiple of 4096"); - 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; - - 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; - offset += bank->sectors[i].size; - bank->sectors[i].is_erased = -1; - bank->sectors[i].is_protected = 1; - } - - } else if (lpc2000_info->variant == lpc1500) { - lpc2000_info->cmd51_dst_boundary = 256; - lpc2000_info->checksum_vector = 7; - lpc2000_info->iap_max_stack = 128; - - switch (bank->size) { - case 64 * 1024: - bank->num_sectors = 16; - break; - case 128 * 1024: - bank->num_sectors = 32; - break; - case 256 * 1024: - bank->num_sectors = 64; - break; - default: - LOG_ERROR("BUG: unknown bank->size encountered"); - exit(-1); - } - - 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; - offset += bank->sectors[i].size; - bank->sectors[i].is_erased = -1; - bank->sectors[i].is_protected = 1; - } - - } else if (lpc2000_info->variant == lpc54100) { - lpc2000_info->cmd51_dst_boundary = 256; - lpc2000_info->checksum_vector = 7; - lpc2000_info->iap_max_stack = 128; - - switch (bank->size) { - case 256 * 1024: - bank->num_sectors = 8; - break; - case 512 * 1024: - bank->num_sectors = 16; - break; - default: - LOG_ERROR("BUG: unknown bank->size encountered"); - exit(-1); - } - - 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 32kB-sized */ - bank->sectors[i].size = 32 * 1024; - offset += bank->sectors[i].size; - bank->sectors[i].is_erased = -1; - bank->sectors[i].is_protected = 1; - } - - } else { - LOG_ERROR("BUG: unknown lpc2000_info->variant encountered"); - exit(-1); - } - - return ERROR_OK; -} - -/* this function allocates and initializes working area used for IAP algorithm - * uses 52 + max IAP stack bytes working area - * 0x0 to 0x7: jump gate (BX to thumb state, b -2 to wait) - * 0x8 to 0x1f: command parameter table (1+5 words) - * 0x20 to 0x33: command result table (1+4 words) - * 0x34 to 0xb3|0x104: stack - * (128b needed for lpc1xxx/2000/5410x, 208b for lpc43xx/lpc82x and 148b for lpc81x) - */ - -static int lpc2000_iap_working_area_init(struct flash_bank *bank, struct working_area **iap_working_area) -{ - struct target *target = bank->target; - struct lpc2000_flash_bank *lpc2000_info = bank->driver_priv; - - if (target_alloc_working_area(target, IAP_CODE_LEN + lpc2000_info->iap_max_stack, iap_working_area) != ERROR_OK) { - LOG_ERROR("no working area specified, can't write LPC2000 internal flash"); - return ERROR_FLASH_OPERATION_FAILED; - } - - uint8_t jump_gate[8]; - - /* write IAP code to working area */ - switch (lpc2000_info->variant) { - case lpc800: - case lpc1100: - case lpc1500: - case lpc1700: - case lpc4300: - case lpc54100: - case lpc_auto: - target_buffer_set_u32(target, jump_gate, ARMV4_5_T_BX(12)); - target_buffer_set_u32(target, jump_gate + 4, ARMV5_T_BKPT(0)); - break; - case lpc2000_v1: - case lpc2000_v2: - target_buffer_set_u32(target, jump_gate, ARMV4_5_BX(12)); - target_buffer_set_u32(target, jump_gate + 4, ARMV4_5_B(0xfffffe, 0)); - break; - default: - LOG_ERROR("BUG: unknown lpc2000_info->variant encountered"); - exit(-1); - } - - 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)", - (*iap_working_area)->address); - target_free_working_area(target, *iap_working_area); - } - - return retval; -} - -/* call LPC8xx/LPC1xxx/LPC4xxx/LPC5410x/LPC2000 IAP function */ - -static int lpc2000_iap_call(struct flash_bank *bank, struct working_area *iap_working_area, int code, - uint32_t param_table[5], uint32_t result_table[4]) -{ - struct lpc2000_flash_bank *lpc2000_info = bank->driver_priv; - struct target *target = bank->target; - - struct arm_algorithm arm_algo; /* for LPC2000 */ - struct armv7m_algorithm armv7m_info; /* for LPC8xx/LPC1xxx/LPC4xxx/LPC5410x */ - uint32_t iap_entry_point = 0; /* to make compiler happier */ - - switch (lpc2000_info->variant) { - case lpc800: - case lpc1100: - case lpc1700: - case lpc_auto: - armv7m_info.common_magic = ARMV7M_COMMON_MAGIC; - armv7m_info.core_mode = ARM_MODE_THREAD; - iap_entry_point = 0x1fff1ff1; - break; - case lpc1500: - case lpc54100: - armv7m_info.common_magic = ARMV7M_COMMON_MAGIC; - armv7m_info.core_mode = ARM_MODE_THREAD; - iap_entry_point = 0x03000205; - break; - case lpc2000_v1: - case lpc2000_v2: - arm_algo.common_magic = ARM_COMMON_MAGIC; - arm_algo.core_mode = ARM_MODE_SVC; - arm_algo.core_state = ARM_STATE_ARM; - iap_entry_point = 0x7ffffff1; - break; - case lpc4300: - armv7m_info.common_magic = ARMV7M_COMMON_MAGIC; - armv7m_info.core_mode = ARM_MODE_THREAD; - /* read out IAP entry point from ROM driver table at 0x10400100 */ - target_read_u32(target, 0x10400100, &iap_entry_point); - break; - default: - LOG_ERROR("BUG: unknown lpc2000->variant encountered"); - exit(-1); - } - - struct mem_param mem_params[2]; - - /* command parameter table */ - init_mem_param(&mem_params[0], iap_working_area->address + 8, 6 * 4, PARAM_OUT); - target_buffer_set_u32(target, mem_params[0].value, code); - target_buffer_set_u32(target, mem_params[0].value + 0x04, param_table[0]); - target_buffer_set_u32(target, mem_params[0].value + 0x08, param_table[1]); - target_buffer_set_u32(target, mem_params[0].value + 0x0c, param_table[2]); - target_buffer_set_u32(target, mem_params[0].value + 0x10, param_table[3]); - target_buffer_set_u32(target, mem_params[0].value + 0x14, param_table[4]); - - struct reg_param reg_params[5]; - - init_reg_param(®_params[0], "r0", 32, PARAM_OUT); - buf_set_u32(reg_params[0].value, 0, 32, iap_working_area->address + 0x08); - - /* command result table */ - init_mem_param(&mem_params[1], iap_working_area->address + 0x20, 5 * 4, PARAM_IN); - - init_reg_param(®_params[1], "r1", 32, PARAM_OUT); - buf_set_u32(reg_params[1].value, 0, 32, iap_working_area->address + 0x20); - - /* IAP entry point */ - init_reg_param(®_params[2], "r12", 32, PARAM_OUT); - buf_set_u32(reg_params[2].value, 0, 32, iap_entry_point); - - switch (lpc2000_info->variant) { - case lpc800: - case lpc1100: - case lpc1500: - case lpc1700: - case lpc4300: - case lpc54100: - case lpc_auto: - /* IAP stack */ - init_reg_param(®_params[3], "sp", 32, PARAM_OUT); - buf_set_u32(reg_params[3].value, 0, 32, - iap_working_area->address + IAP_CODE_LEN + lpc2000_info->iap_max_stack); - - /* return address */ - init_reg_param(®_params[4], "lr", 32, PARAM_OUT); - buf_set_u32(reg_params[4].value, 0, 32, (iap_working_area->address + 0x04) | 1); - /* bit0 of LR = 1 to return in Thumb mode */ - - target_run_algorithm(target, 2, mem_params, 5, reg_params, iap_working_area->address, 0, 10000, - &armv7m_info); - break; - case lpc2000_v1: - case lpc2000_v2: - /* IAP stack */ - init_reg_param(®_params[3], "sp_svc", 32, PARAM_OUT); - buf_set_u32(reg_params[3].value, 0, 32, - iap_working_area->address + IAP_CODE_LEN + lpc2000_info->iap_max_stack); - - /* return address */ - init_reg_param(®_params[4], "lr_svc", 32, PARAM_OUT); - buf_set_u32(reg_params[4].value, 0, 32, iap_working_area->address + 0x04); - - target_run_algorithm(target, 2, mem_params, 5, reg_params, iap_working_area->address, - iap_working_area->address + 0x4, 10000, &arm_algo); - break; - default: - LOG_ERROR("BUG: unknown lpc2000->variant encountered"); - exit(-1); - } - - int status_code = target_buffer_get_u32(target, mem_params[1].value); - result_table[0] = target_buffer_get_u32(target, mem_params[1].value + 0x04); - result_table[1] = target_buffer_get_u32(target, mem_params[1].value + 0x08); - result_table[2] = target_buffer_get_u32(target, mem_params[1].value + 0x0c); - result_table[3] = target_buffer_get_u32(target, mem_params[1].value + 0x10); - - LOG_DEBUG("IAP command = %i (0x%8.8" PRIx32 ", 0x%8.8" PRIx32 ", 0x%8.8" PRIx32 ", 0x%8.8" PRIx32 ", 0x%8.8" PRIx32 - ") completed with result = %8.8x", - code, param_table[0], param_table[1], param_table[2], param_table[3], param_table[4], status_code); - - destroy_mem_param(&mem_params[0]); - destroy_mem_param(&mem_params[1]); - - 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 status_code; -} - -static int lpc2000_iap_blank_check(struct flash_bank *bank, int first, int last) -{ - if ((first < 0) || (last >= bank->num_sectors)) - return ERROR_FLASH_SECTOR_INVALID; - - uint32_t param_table[5] = {0}; - uint32_t result_table[4]; - struct working_area *iap_working_area; - - int retval = lpc2000_iap_working_area_init(bank, &iap_working_area); - - if (retval != ERROR_OK) - return retval; - - struct lpc2000_flash_bank *lpc2000_info = bank->driver_priv; - if (lpc2000_info->variant == lpc4300) - param_table[2] = lpc2000_info->lpc4300_bank; - - for (int i = first; i <= last && retval == ERROR_OK; i++) { - /* check single sector */ - param_table[0] = param_table[1] = i; - int status_code = lpc2000_iap_call(bank, iap_working_area, 53, param_table, result_table); - - switch (status_code) { - case ERROR_FLASH_OPERATION_FAILED: - retval = ERROR_FLASH_OPERATION_FAILED; - break; - case LPC2000_CMD_SUCCESS: - bank->sectors[i].is_erased = 1; - break; - case LPC2000_SECTOR_NOT_BLANK: - bank->sectors[i].is_erased = 0; - break; - case LPC2000_INVALID_SECTOR: - bank->sectors[i].is_erased = 0; - break; - case LPC2000_BUSY: - retval = ERROR_FLASH_BUSY; - break; - default: - LOG_ERROR("BUG: unknown LPC2000 status code %i", status_code); - exit(-1); - } - } - - struct target *target = bank->target; - target_free_working_area(target, iap_working_area); - - return retval; -} - -/* - * flash bank lpc2000 0 0 [calc_checksum] - */ -FLASH_BANK_COMMAND_HANDLER(lpc2000_flash_bank_command) -{ - if (CMD_ARGC < 8) - return ERROR_COMMAND_SYNTAX_ERROR; - - struct lpc2000_flash_bank *lpc2000_info = calloc(1, sizeof(*lpc2000_info)); - lpc2000_info->probed = false; - - bank->driver_priv = lpc2000_info; - - if (strcmp(CMD_ARGV[6], "lpc2000_v1") == 0) { - lpc2000_info->variant = lpc2000_v1; - } else if (strcmp(CMD_ARGV[6], "lpc2000_v2") == 0) { - lpc2000_info->variant = lpc2000_v2; - } else if (strcmp(CMD_ARGV[6], "lpc1700") == 0 || strcmp(CMD_ARGV[6], "lpc4000") == 0) { - lpc2000_info->variant = lpc1700; - } else if (strcmp(CMD_ARGV[6], "lpc1800") == 0 || strcmp(CMD_ARGV[6], "lpc4300") == 0) { - lpc2000_info->variant = lpc4300; - } else if (strcmp(CMD_ARGV[6], "lpc800") == 0) { - lpc2000_info->variant = lpc800; - } else if (strcmp(CMD_ARGV[6], "lpc1100") == 0) { - lpc2000_info->variant = lpc1100; - } else if (strcmp(CMD_ARGV[6], "lpc1500") == 0) { - lpc2000_info->variant = lpc1500; - } else if (strcmp(CMD_ARGV[6], "lpc54100") == 0) { - lpc2000_info->variant = lpc54100; - } else if (strcmp(CMD_ARGV[6], "auto") == 0) { - lpc2000_info->variant = lpc_auto; - } else { - LOG_ERROR("unknown LPC2000 variant: %s", CMD_ARGV[6]); - free(lpc2000_info); - return ERROR_FLASH_BANK_INVALID; - } - - /* Maximum size required for the IAP stack. - This value only gets used when probing, only for auto, lpc1100 and lpc1700. - We use the maximum size for any part supported by the driver(!) to be safe - in case the auto variant is mistakenly used on a MCU from one of the series - for which we don't support auto-probing. */ - lpc2000_info->iap_max_stack = 208; - - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[7], lpc2000_info->cclk); - lpc2000_info->calc_checksum = 0; - - uint32_t temp_base = 0; - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], temp_base); - if (temp_base >= 0x1B000000) - lpc2000_info->lpc4300_bank = 1; /* bank B */ - else - lpc2000_info->lpc4300_bank = 0; /* bank A */ - - if (CMD_ARGC >= 9) { - if (strcmp(CMD_ARGV[8], "calc_checksum") == 0) - lpc2000_info->calc_checksum = 1; - } - - return ERROR_OK; -} - -static int lpc2000_erase(struct flash_bank *bank, int first, int last) -{ - if (bank->target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - struct lpc2000_flash_bank *lpc2000_info = bank->driver_priv; - uint32_t param_table[5] = {0}; - - param_table[0] = first; - param_table[1] = last; - - if (lpc2000_info->variant == lpc4300) - param_table[2] = lpc2000_info->lpc4300_bank; - else - param_table[2] = lpc2000_info->cclk; - - uint32_t result_table[4]; - struct working_area *iap_working_area; - - int retval = lpc2000_iap_working_area_init(bank, &iap_working_area); - - if (retval != ERROR_OK) - return retval; - - if (lpc2000_info->variant == lpc4300) - /* Init IAP Anyway */ - lpc2000_iap_call(bank, iap_working_area, 49, param_table, result_table); - - /* Prepare sectors */ - int status_code = lpc2000_iap_call(bank, iap_working_area, 50, param_table, result_table); - switch (status_code) { - case ERROR_FLASH_OPERATION_FAILED: - retval = ERROR_FLASH_OPERATION_FAILED; - break; - case LPC2000_CMD_SUCCESS: - break; - case LPC2000_INVALID_SECTOR: - retval = ERROR_FLASH_SECTOR_INVALID; - break; - default: - LOG_WARNING("lpc2000 prepare sectors returned %i", status_code); - retval = ERROR_FLASH_OPERATION_FAILED; - break; - } - - if (retval == ERROR_OK) { - /* Erase sectors */ - param_table[2] = lpc2000_info->cclk; - if (lpc2000_info->variant == lpc4300) - param_table[3] = lpc2000_info->lpc4300_bank; - - status_code = lpc2000_iap_call(bank, iap_working_area, 52, param_table, result_table); - switch (status_code) { - case ERROR_FLASH_OPERATION_FAILED: - retval = ERROR_FLASH_OPERATION_FAILED; - break; - case LPC2000_CMD_SUCCESS: - break; - case LPC2000_INVALID_SECTOR: - retval = ERROR_FLASH_SECTOR_INVALID; - break; - default: - LOG_WARNING("lpc2000 erase sectors returned %i", status_code); - retval = ERROR_FLASH_OPERATION_FAILED; - break; - } - } - - struct target *target = bank->target; - target_free_working_area(target, iap_working_area); - - return retval; -} - -static int lpc2000_protect(struct flash_bank *bank, int set, int first, int last) -{ - /* can't protect/unprotect on the lpc2000 */ - return ERROR_OK; -} - -static int lpc2000_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count) -{ - struct target *target = bank->target; - - if (bank->target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - if (offset + count > bank->size) - return ERROR_FLASH_DST_OUT_OF_BANK; - - struct lpc2000_flash_bank *lpc2000_info = bank->driver_priv; - - uint32_t dst_min_alignment = lpc2000_info->cmd51_dst_boundary; - - if (offset % dst_min_alignment) { - LOG_WARNING("offset 0x%" PRIx32 " breaks required alignment 0x%" PRIx32, offset, dst_min_alignment); - return ERROR_FLASH_DST_BREAKS_ALIGNMENT; - } - - int first_sector = 0; - int last_sector = 0; - - for (int i = 0; i < bank->num_sectors; i++) { - if (offset >= bank->sectors[i].offset) - first_sector = i; - if (offset + DIV_ROUND_UP(count, dst_min_alignment) * dst_min_alignment > bank->sectors[i].offset) - last_sector = i; - } - - LOG_DEBUG("first_sector: %i, last_sector: %i", first_sector, last_sector); - - /* check if exception vectors should be flashed */ - if ((offset == 0) && (count >= 0x20) && lpc2000_info->calc_checksum) { - assert(lpc2000_info->checksum_vector < 8); - uint32_t checksum = 0; - for (int i = 0; i < 8; i++) { - LOG_DEBUG("Vector 0x%2.2x: 0x%8.8" PRIx32, i * 4, buf_get_u32(buffer + (i * 4), 0, 32)); - if (i != lpc2000_info->checksum_vector) - checksum += buf_get_u32(buffer + (i * 4), 0, 32); - } - checksum = 0 - checksum; - LOG_DEBUG("checksum: 0x%8.8" PRIx32, checksum); - - uint32_t original_value = buf_get_u32(buffer + (lpc2000_info->checksum_vector * 4), 0, 32); - if (original_value != checksum) { - LOG_WARNING("Verification will fail since checksum in image (0x%8.8" PRIx32 ") to be written to flash is " - "different from calculated vector checksum (0x%8.8" PRIx32 ").", original_value, checksum); - LOG_WARNING("To remove this warning modify build tools on developer PC to inject correct LPC vector " - "checksum."); - } - - /* FIXME: WARNING! This code is broken because it modifies the callers buffer in place. */ - buf_set_u32((uint8_t *)buffer + (lpc2000_info->checksum_vector * 4), 0, 32, checksum); - } - - struct working_area *iap_working_area; - - int retval = lpc2000_iap_working_area_init(bank, &iap_working_area); - - if (retval != ERROR_OK) - return retval; - - struct working_area *download_area; - - /* allocate a working area */ - if (target_alloc_working_area(target, lpc2000_info->cmd51_max_buffer, &download_area) != ERROR_OK) { - LOG_ERROR("no working area specified, can't write LPC2000 internal flash"); - target_free_working_area(target, iap_working_area); - return ERROR_FLASH_OPERATION_FAILED; - } - - uint32_t bytes_remaining = count; - uint32_t bytes_written = 0; - uint32_t param_table[5] = {0}; - uint32_t result_table[4]; - - if (lpc2000_info->variant == lpc4300) - /* Init IAP Anyway */ - lpc2000_iap_call(bank, iap_working_area, 49, param_table, result_table); - - while (bytes_remaining > 0) { - uint32_t thisrun_bytes; - if (bytes_remaining >= lpc2000_info->cmd51_max_buffer) - thisrun_bytes = lpc2000_info->cmd51_max_buffer; - else - thisrun_bytes = lpc2000_info->cmd51_dst_boundary; - - /* Prepare sectors */ - param_table[0] = first_sector; - param_table[1] = last_sector; - - if (lpc2000_info->variant == lpc4300) - param_table[2] = lpc2000_info->lpc4300_bank; - else - param_table[2] = lpc2000_info->cclk; - - int status_code = lpc2000_iap_call(bank, iap_working_area, 50, param_table, result_table); - switch (status_code) { - case ERROR_FLASH_OPERATION_FAILED: - retval = ERROR_FLASH_OPERATION_FAILED; - break; - case LPC2000_CMD_SUCCESS: - break; - case LPC2000_INVALID_SECTOR: - retval = ERROR_FLASH_SECTOR_INVALID; - break; - default: - LOG_WARNING("lpc2000 prepare sectors returned %i", status_code); - retval = ERROR_FLASH_OPERATION_FAILED; - break; - } - - /* Exit if error occured */ - if (retval != ERROR_OK) - break; - - if (bytes_remaining >= thisrun_bytes) { - retval = target_write_buffer(bank->target, download_area->address, thisrun_bytes, buffer + bytes_written); - if (retval != ERROR_OK) { - retval = ERROR_FLASH_OPERATION_FAILED; - break; - } - } else { - uint8_t *last_buffer = malloc(thisrun_bytes); - memcpy(last_buffer, buffer + bytes_written, bytes_remaining); - memset(last_buffer + bytes_remaining, 0xff, thisrun_bytes - bytes_remaining); - target_write_buffer(bank->target, download_area->address, thisrun_bytes, last_buffer); - free(last_buffer); - } - - LOG_DEBUG("writing 0x%" PRIx32 " bytes to address 0x%" PRIx32, thisrun_bytes, - bank->base + offset + bytes_written); - - /* Write data */ - param_table[0] = bank->base + offset + bytes_written; - param_table[1] = download_area->address; - param_table[2] = thisrun_bytes; - param_table[3] = lpc2000_info->cclk; - status_code = lpc2000_iap_call(bank, iap_working_area, 51, param_table, result_table); - switch (status_code) { - case ERROR_FLASH_OPERATION_FAILED: - retval = ERROR_FLASH_OPERATION_FAILED; - break; - case LPC2000_CMD_SUCCESS: - break; - case LPC2000_INVALID_SECTOR: - retval = ERROR_FLASH_SECTOR_INVALID; - break; - default: - LOG_WARNING("lpc2000 returned %i", status_code); - retval = ERROR_FLASH_OPERATION_FAILED; - break; - } - - /* Exit if error occured */ - if (retval != ERROR_OK) - break; - - if (bytes_remaining > thisrun_bytes) - bytes_remaining -= thisrun_bytes; - else - bytes_remaining = 0; - bytes_written += thisrun_bytes; - } - - target_free_working_area(target, iap_working_area); - target_free_working_area(target, download_area); - - return retval; -} - -static int get_lpc2000_part_id(struct flash_bank *bank, uint32_t *part_id) -{ - if (bank->target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - uint32_t param_table[5] = {0}; - uint32_t result_table[4]; - struct working_area *iap_working_area; - - int retval = lpc2000_iap_working_area_init(bank, &iap_working_area); - - if (retval != ERROR_OK) - return retval; - - /* The status seems to be bogus with the part ID command on some IAP - firmwares, so ignore it. */ - lpc2000_iap_call(bank, iap_working_area, 54, param_table, result_table); - - struct target *target = bank->target; - target_free_working_area(target, iap_working_area); - - /* If the result is zero, the command probably didn't work out. */ - if (result_table[0] == 0) - return LPC2000_INVALID_COMMAND; - - *part_id = result_table[0]; - return LPC2000_CMD_SUCCESS; -} - -static int lpc2000_auto_probe_flash(struct flash_bank *bank) -{ - uint32_t part_id; - int retval; - struct lpc2000_flash_bank *lpc2000_info = bank->driver_priv; - - if (bank->target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - retval = get_lpc2000_part_id(bank, &part_id); - if (retval != LPC2000_CMD_SUCCESS) { - LOG_ERROR("Could not get part ID"); - return retval; - } - - switch (part_id) { - case LPC1110_1: - case LPC1110_2: - lpc2000_info->variant = lpc1100; - bank->size = 4 * 1024; - break; - - case LPC1111_002_1: - case LPC1111_002_2: - case LPC1111_101_1: - case LPC1111_101_2: - case LPC1111_103_1: - case LPC1111_201_1: - case LPC1111_201_2: - case LPC1111_203_1: - case LPC11A11_001_1: - case LPC11E11_101: - case LPC1311: - case LPC1311_1: - lpc2000_info->variant = lpc1100; - bank->size = 8 * 1024; - break; - - case LPC1112_101_1: - case LPC1112_101_2: - case LPC1112_102_1: - case LPC1112_102_2: - case LPC1112_103_1: - case LPC1112_201_1: - case LPC1112_201_2: - case LPC1112_203_1: - case LPC11A02_1: - case LPC11C12_301_1: - case LPC11C22_301_1: - case LPC11A12_101_1: - case LPC11E12_201: - case LPC11U12_201_1: - case LPC11U12_201_2: - case LPC1342: - lpc2000_info->variant = lpc1100; - bank->size = 16 * 1024; - break; - - case LPC1113_201_1: - case LPC1113_201_2: - case LPC1113_203_1: - case LPC1113_301_1: - case LPC1113_301_2: - case LPC1113_303_1: - case LPC11A13_201_1: - case LPC11E13_301: - case LPC11U13_201_1: - case LPC11U13_201_2: - case LPC11U23_301: - lpc2000_info->variant = lpc1100; - bank->size = 24 * 1024; - break; - - case LPC1114_102_1: - case LPC1114_102_2: - case LPC1114_201_1: - case LPC1114_201_2: - case LPC1114_203_1: - case LPC1114_301_1: - case LPC1114_301_2: - case LPC1114_303_1: - case LPC11A04_1: - case LPC11A14_301_1: - case LPC11A14_301_2: - case LPC11C14_301_1: - case LPC11C24_301_1: - case LPC11E14_401: - case LPC11U14_201_1: - case LPC11U14_201_2: - case LPC11U24_301: - case LPC11U24_401: - case LPC1313: - case LPC1313_1: - case LPC1315: - case LPC1343: - case LPC1343_1: - case LPC1345: - lpc2000_info->variant = lpc1100; - bank->size = 32 * 1024; - break; - - case LPC1751_1: - case LPC1751_2: - lpc2000_info->variant = lpc1700; - bank->size = 32 * 1024; - break; - - case LPC11U34_311: - lpc2000_info->variant = lpc1100; - bank->size = 40 * 1024; - break; - - case LPC1114_323_1: - case LPC11U34_421: - case LPC1316: - case LPC1346: - lpc2000_info->variant = lpc1100; - bank->size = 48 * 1024; - break; - - case LPC1114_333_1: - lpc2000_info->variant = lpc1100; - bank->size = 56 * 1024; - break; - - case LPC1115_303_1: - case LPC11U35_401: - case LPC11U35_501: - case LPC11E66: - case LPC11U66: - case LPC1317: - case LPC1347: - lpc2000_info->variant = lpc1100; - bank->size = 64 * 1024; - break; - - case LPC1752: - case LPC4072: - lpc2000_info->variant = lpc1700; - bank->size = 64 * 1024; - break; - - case LPC11E36_501: - case LPC11U36_401: - lpc2000_info->variant = lpc1100; - bank->size = 96 * 1024; - break; - - case LPC11E37_401: - case LPC11E37_501: - case LPC11U37_401: - case LPC11U37H_401: - case LPC11U37_501: - case LPC11E67: - case LPC11E68: - case LPC11U67_1: - case LPC11U67_2: - lpc2000_info->variant = lpc1100; - bank->size = 128 * 1024; - break; - - case LPC1754: - case LPC1764: - case LPC1774: - case LPC4074: - lpc2000_info->variant = lpc1700; - bank->size = 128 * 1024; - break; - - case LPC11U68_1: - case LPC11U68_2: - lpc2000_info->variant = lpc1100; - bank->size = 256 * 1024; - break; - - case LPC1756: - case LPC1763: - case LPC1765: - case LPC1766: - case LPC1776: - case LPC1785: - case LPC1786: - case LPC4076: - lpc2000_info->variant = lpc1700; - bank->size = 256 * 1024; - break; - - case LPC1758: - case LPC1759: - case LPC1767: - case LPC1768: - case LPC1769: - case LPC1777: - case LPC1778: - case LPC1787: - case LPC1788: - case LPC4078: - case LPC4088: - lpc2000_info->variant = lpc1700; - bank->size = 512 * 1024; - break; - - case LPC810_021: - lpc2000_info->variant = lpc800; - bank->size = 4 * 1024; - break; - - case LPC811_001: - lpc2000_info->variant = lpc800; - bank->size = 8 * 1024; - break; - - case LPC812_101: - case LPC812_101_1: - case LPC812_101_2: - case LPC812_101_3: - case LPC822_101: - case LPC822_101_1: - lpc2000_info->variant = lpc800; - bank->size = 16 * 1024; - break; - - case LPC824_201: - case LPC824_201_1: - lpc2000_info->variant = lpc800; - bank->size = 32 * 1024; - break; - - default: - LOG_ERROR("BUG: unknown Part ID encountered: 0x%" PRIx32, part_id); - exit(-1); - } - - return ERROR_OK; -} - -static int lpc2000_probe(struct flash_bank *bank) -{ - int status; - uint32_t part_id; - struct lpc2000_flash_bank *lpc2000_info = bank->driver_priv; - - if (!lpc2000_info->probed) { - if (lpc2000_info->variant == lpc_auto) { - status = lpc2000_auto_probe_flash(bank); - if (status != ERROR_OK) - return status; - } else if (lpc2000_info->variant == lpc1100 || lpc2000_info->variant == lpc1700) { - status = get_lpc2000_part_id(bank, &part_id); - if (status == LPC2000_CMD_SUCCESS) - LOG_INFO("If auto-detection fails for this part, please email " - "openocd-devel@lists.sourceforge.net, citing part id 0x%" PRIx32 ".\n", part_id); - } - - lpc2000_build_sector_list(bank); - lpc2000_info->probed = true; - } - - return ERROR_OK; -} - -static int lpc2000_erase_check(struct flash_bank *bank) -{ - if (bank->target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - return lpc2000_iap_blank_check(bank, 0, bank->num_sectors - 1); -} - -static int lpc2000_protect_check(struct flash_bank *bank) -{ - /* sectors are always protected */ - return ERROR_OK; -} - -static int get_lpc2000_info(struct flash_bank *bank, char *buf, int buf_size) -{ - struct lpc2000_flash_bank *lpc2000_info = bank->driver_priv; - - snprintf(buf, buf_size, "lpc2000 flash driver variant: %i, clk: %" PRIi32 "kHz", lpc2000_info->variant, - lpc2000_info->cclk); - - return ERROR_OK; -} - -COMMAND_HANDLER(lpc2000_handle_part_id_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; - - if (bank->target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - uint32_t part_id; - int status_code = get_lpc2000_part_id(bank, &part_id); - if (status_code != 0x0) { - if (status_code == ERROR_FLASH_OPERATION_FAILED) { - command_print(CMD_CTX, "no sufficient working area specified, can't access LPC2000 IAP interface"); - } else - command_print(CMD_CTX, "lpc2000 IAP returned status code %i", status_code); - } else - command_print(CMD_CTX, "lpc2000 part id: 0x%8.8" PRIx32, part_id); - - return retval; -} - -static const struct command_registration lpc2000_exec_command_handlers[] = { - { - .name = "part_id", - .handler = lpc2000_handle_part_id_command, - .mode = COMMAND_EXEC, - .help = "print part id of lpc2000 flash bank ", - .usage = "", - }, - COMMAND_REGISTRATION_DONE -}; -static const struct command_registration lpc2000_command_handlers[] = { - { - .name = "lpc2000", - .mode = COMMAND_ANY, - .help = "lpc2000 flash command group", - .usage = "", - .chain = lpc2000_exec_command_handlers, - }, - COMMAND_REGISTRATION_DONE -}; - -struct flash_driver lpc2000_flash = { - .name = "lpc2000", - .commands = lpc2000_command_handlers, - .flash_bank_command = lpc2000_flash_bank_command, - .erase = lpc2000_erase, - .protect = lpc2000_protect, - .write = lpc2000_write, - .read = default_flash_read, - .probe = lpc2000_probe, - .auto_probe = lpc2000_probe, - .erase_check = lpc2000_erase_check, - .protect_check = lpc2000_protect_check, - .info = get_lpc2000_info, -}; diff --git a/src/flash/nor/lpc288x.c b/src/flash/nor/lpc288x.c deleted file mode 100644 index a4d88de78..000000000 --- a/src/flash/nor/lpc288x.c +++ /dev/null @@ -1,436 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2008 by * - * Karl RobinSod * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -/*************************************************************************** -* There are some things to notice -* -* You need to unprotect flash sectors each time you connect the OpenOCD -* Dumping 1MB takes about 60 Seconds -* Full erase (sectors 0-22 inclusive) takes 2-4 seconds -* Writing 1MB takes 88 seconds -* - ***************************************************************************/ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "imp.h" -#include - -#define LOAD_TIMER_ERASE 0 -#define LOAD_TIMER_WRITE 1 - -#define FLASH_PAGE_SIZE 512 - -/* LPC288X control registers */ -#define DBGU_CIDR 0x8000507C -/* LPC288X flash registers */ -#define F_CTRL 0x80102000 /* Flash control register R/W 0x5 */ -#define F_STAT 0x80102004 /* Flash status register RO 0x45 */ -#define F_PROG_TIME 0x80102008 /* Flash program time register R/W 0 */ -#define F_WAIT 0x80102010 /* Flash read wait state register R/W 0xC004 */ -#define F_CLK_TIME 0x8010201C /* Flash clock divider for 66 kHz generation R/W 0 - **/ -#define F_INTEN_CLR 0x80102FD8 /* Clear interrupt enable bits WO - */ -#define F_INTEN_SET 0x80102FDC /* Set interrupt enable bits WO - */ -#define F_INT_STAT 0x80102FE0 /* Interrupt status bits RO 0 */ -#define F_INTEN 0x80102FE4 /* Interrupt enable bits RO 0 */ -#define F_INT_CLR 0x80102FE8 /* Clear interrupt status bits WO */ -#define F_INT_SET 0x80102FEC /* Set interrupt status bits WO - */ -#define FLASH_PD 0x80005030 /* Allows turning off the Flash memory for power - *savings. R/W 1*/ -#define FLASH_INIT 0x80005034 /* Monitors Flash readiness, such as recovery from - *Power Down mode. R/W -*/ - -/* F_CTRL bits */ -#define FC_CS 0x0001 -#define FC_FUNC 0x0002 -#define FC_WEN 0x0004 -#define FC_RD_LATCH 0x0020 -#define FC_PROTECT 0x0080 -#define FC_SET_DATA 0x0400 -#define FC_RSSL 0x0800 -#define FC_PROG_REQ 0x1000 -#define FC_CLR_BUF 0x4000 -#define FC_LOAD_REQ 0x8000 -/* F_STAT bits */ -#define FS_DONE 0x0001 -#define FS_PROGGNT 0x0002 -#define FS_RDY 0x0004 -#define FS_ERR 0x0020 -/* F_PROG_TIME */ -#define FPT_TIME_MASK 0x7FFF - -#define FPT_ENABLE 0x8000 -/* F_WAIT */ -#define FW_WAIT_STATES_MASK 0x00FF -#define FW_SET_MASK 0xC000 - -/* F_CLK_TIME */ -#define FCT_CLK_DIV_MASK 0x0FFF - -struct lpc288x_flash_bank { - uint32_t working_area; - uint32_t working_area_size; - - /* chip id register */ - uint32_t cidr; - const char *target_name; - uint32_t cclk; - - uint32_t sector_size_break; -}; - -static uint32_t lpc288x_wait_status_busy(struct flash_bank *bank, int timeout); -static void lpc288x_load_timer(int erase, struct target *target); -static void lpc288x_set_flash_clk(struct flash_bank *bank); -static uint32_t lpc288x_system_ready(struct flash_bank *bank); - -static uint32_t lpc288x_wait_status_busy(struct flash_bank *bank, int timeout) -{ - uint32_t status; - struct target *target = bank->target; - do { - alive_sleep(1); - timeout--; - target_read_u32(target, F_STAT, &status); - } while (((status & FS_DONE) == 0) && timeout); - - if (timeout == 0) { - LOG_DEBUG("Timedout!"); - return ERROR_FLASH_OPERATION_FAILED; - } - return ERROR_OK; -} - -/* Read device id register and fill in driver info structure */ -static int lpc288x_read_part_info(struct flash_bank *bank) -{ - struct lpc288x_flash_bank *lpc288x_info = bank->driver_priv; - struct target *target = bank->target; - uint32_t cidr; - - int i = 0; - uint32_t offset; - - if (lpc288x_info->cidr == 0x0102100A) - return ERROR_OK;/* already probed, multiple probes may cause memory leak, not - *allowed */ - - /* Read and parse chip identification register */ - target_read_u32(target, DBGU_CIDR, &cidr); - - if (cidr != 0x0102100A) { - LOG_WARNING("Cannot identify target as an LPC288X (%08" PRIx32 ")", cidr); - return ERROR_FLASH_OPERATION_FAILED; - } - - lpc288x_info->cidr = cidr; - lpc288x_info->sector_size_break = 0x000F0000; - lpc288x_info->target_name = "LPC288x"; - - /* setup the sector info... */ - offset = bank->base; - bank->num_sectors = 23; - bank->sectors = malloc(sizeof(struct flash_sector) * 23); - - for (i = 0; i < 15; i++) { - bank->sectors[i].offset = offset; - bank->sectors[i].size = 64 * 1024; - offset += bank->sectors[i].size; - bank->sectors[i].is_erased = -1; - bank->sectors[i].is_protected = 1; - } - for (i = 15; i < 23; i++) { - bank->sectors[i].offset = offset; - bank->sectors[i].size = 8 * 1024; - offset += bank->sectors[i].size; - bank->sectors[i].is_erased = -1; - bank->sectors[i].is_protected = 1; - } - - return ERROR_OK; -} - -static int lpc288x_protect_check(struct flash_bank *bank) -{ - return ERROR_OK; -} - -/* flash_bank LPC288x 0 0 0 0 */ -FLASH_BANK_COMMAND_HANDLER(lpc288x_flash_bank_command) -{ - struct lpc288x_flash_bank *lpc288x_info; - - if (CMD_ARGC < 6) - return ERROR_COMMAND_SYNTAX_ERROR; - - lpc288x_info = malloc(sizeof(struct lpc288x_flash_bank)); - bank->driver_priv = lpc288x_info; - - /* part wasn't probed for info yet */ - lpc288x_info->cidr = 0; - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[6], lpc288x_info->cclk); - - return ERROR_OK; -} - -/* The frequency is the AHB clock frequency divided by (CLK_DIV ×3) + 1. - * This must be programmed such that the Flash Programming clock frequency is 66 kHz ± 20%. - * AHB = 12 MHz ? - * 12000000/66000 = 182 - * CLK_DIV = 60 ? */ -static void lpc288x_set_flash_clk(struct flash_bank *bank) -{ - uint32_t clk_time; - struct lpc288x_flash_bank *lpc288x_info = bank->driver_priv; - clk_time = (lpc288x_info->cclk / 66000) / 3; - target_write_u32(bank->target, F_CTRL, FC_CS | FC_WEN); - target_write_u32(bank->target, F_CLK_TIME, clk_time); -} - -/* AHB tcyc (in ns) 83 ns - * LOAD_TIMER_ERASE FPT_TIME = ((400,000,000 / AHB tcyc (in ns)) - 2) / 512 - * = 9412 (9500) (AN10548 9375) - * LOAD_TIMER_WRITE FPT_TIME = ((1,000,000 / AHB tcyc (in ns)) - 2) / 512 - * = 23 (75) (AN10548 72 - is this wrong?) - * TODO: Sort out timing calcs ;) */ -static void lpc288x_load_timer(int erase, struct target *target) -{ - if (erase == LOAD_TIMER_ERASE) - target_write_u32(target, F_PROG_TIME, FPT_ENABLE | 9500); - else - target_write_u32(target, F_PROG_TIME, FPT_ENABLE | 75); -} - -static uint32_t lpc288x_system_ready(struct flash_bank *bank) -{ - struct lpc288x_flash_bank *lpc288x_info = bank->driver_priv; - if (lpc288x_info->cidr == 0) - return ERROR_FLASH_BANK_NOT_PROBED; - - if (bank->target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - return ERROR_OK; -} - -static int lpc288x_erase_check(struct flash_bank *bank) -{ - uint32_t status = lpc288x_system_ready(bank); /* probed? halted? */ - if (status != ERROR_OK) { - LOG_INFO("Processor not halted/not probed"); - return status; - } - - return ERROR_OK; -} - -static int lpc288x_erase(struct flash_bank *bank, int first, int last) -{ - uint32_t status; - int sector; - struct target *target = bank->target; - - status = lpc288x_system_ready(bank); /* probed? halted? */ - if (status != ERROR_OK) - return status; - - if ((first < 0) || (last < first) || (last >= bank->num_sectors)) { - LOG_INFO("Bad sector range"); - return ERROR_FLASH_SECTOR_INVALID; - } - - /* Configure the flash controller timing */ - lpc288x_set_flash_clk(bank); - - for (sector = first; sector <= last; sector++) { - if (lpc288x_wait_status_busy(bank, 1000) != ERROR_OK) - return ERROR_FLASH_OPERATION_FAILED; - - lpc288x_load_timer(LOAD_TIMER_ERASE, target); - - target_write_u32(target, bank->sectors[sector].offset, 0x00); - - target_write_u32(target, F_CTRL, FC_PROG_REQ | FC_PROTECT | FC_CS); - } - if (lpc288x_wait_status_busy(bank, 1000) != ERROR_OK) - return ERROR_FLASH_OPERATION_FAILED; - return ERROR_OK; -} - -static int lpc288x_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count) -{ - uint8_t page_buffer[FLASH_PAGE_SIZE]; - uint32_t status, source_offset, dest_offset; - struct target *target = bank->target; - uint32_t bytes_remaining = count; - uint32_t first_sector, last_sector, sector, page; - int i; - - /* probed? halted? */ - status = lpc288x_system_ready(bank); - if (status != ERROR_OK) - return status; - - /* Initialise search indices */ - first_sector = last_sector = 0xffffffff; - - /* validate the write range... */ - for (i = 0; i < bank->num_sectors; i++) { - if ((offset >= bank->sectors[i].offset) && - (offset < (bank->sectors[i].offset + bank->sectors[i].size)) && - (first_sector == 0xffffffff)) { - first_sector = i; - /* all writes must start on a sector boundary... */ - if (offset % bank->sectors[i].size) { - LOG_INFO( - "offset 0x%" PRIx32 " breaks required alignment 0x%" PRIx32 "", - offset, - bank->sectors[i].size); - return ERROR_FLASH_DST_BREAKS_ALIGNMENT; - } - } - if (((offset + count) > bank->sectors[i].offset) && - ((offset + count) <= (bank->sectors[i].offset + bank->sectors[i].size)) && - (last_sector == 0xffffffff)) - last_sector = i; - } - - /* Range check... */ - if (first_sector == 0xffffffff || last_sector == 0xffffffff) { - LOG_INFO("Range check failed %" PRIx32 " %" PRIx32 "", offset, count); - return ERROR_FLASH_DST_OUT_OF_BANK; - } - - /* Configure the flash controller timing */ - lpc288x_set_flash_clk(bank); - - /* initialise the offsets */ - source_offset = 0; - dest_offset = 0; - - for (sector = first_sector; sector <= last_sector; sector++) { - for (page = 0; page < bank->sectors[sector].size / FLASH_PAGE_SIZE; page++) { - if (bytes_remaining == 0) { - count = 0; - memset(page_buffer, 0xFF, FLASH_PAGE_SIZE); - } else if (bytes_remaining < FLASH_PAGE_SIZE) { - count = bytes_remaining; - memset(page_buffer, 0xFF, FLASH_PAGE_SIZE); - memcpy(page_buffer, &buffer[source_offset], count); - } else { - count = FLASH_PAGE_SIZE; - memcpy(page_buffer, &buffer[source_offset], count); - } - - /* Wait for flash to become ready */ - if (lpc288x_wait_status_busy(bank, 1000) != ERROR_OK) - return ERROR_FLASH_OPERATION_FAILED; - - /* fill flash data latches with 1's */ - target_write_u32(target, F_CTRL, FC_CS | FC_SET_DATA | FC_WEN | FC_FUNC); - - target_write_u32(target, F_CTRL, FC_CS | FC_WEN | FC_FUNC); - - if (target_write_buffer(target, offset + dest_offset, FLASH_PAGE_SIZE, - page_buffer) != ERROR_OK) { - LOG_INFO("Write to flash buffer failed"); - return ERROR_FLASH_OPERATION_FAILED; - } - - dest_offset += FLASH_PAGE_SIZE; - source_offset += count; - bytes_remaining -= count; - - lpc288x_load_timer(LOAD_TIMER_WRITE, target); - - target_write_u32(target, F_CTRL, FC_PROG_REQ | FC_PROTECT | FC_FUNC | - FC_CS); - } - } - - return ERROR_OK; -} - -static int lpc288x_probe(struct flash_bank *bank) -{ - /* we only deal with LPC2888 so flash config is fixed */ - struct lpc288x_flash_bank *lpc288x_info = bank->driver_priv; - int retval; - - if (lpc288x_info->cidr != 0) - return ERROR_OK;/* already probed */ - - if (bank->target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - retval = lpc288x_read_part_info(bank); - if (retval != ERROR_OK) - return retval; - return ERROR_OK; -} - -static int lpc288x_protect(struct flash_bank *bank, int set, int first, int last) -{ - int lockregion, status; - uint32_t value; - struct target *target = bank->target; - - /* probed? halted? */ - status = lpc288x_system_ready(bank); - if (status != ERROR_OK) - return status; - - if ((first < 0) || (last < first) || (last >= bank->num_sectors)) - return ERROR_FLASH_SECTOR_INVALID; - - /* Configure the flash controller timing */ - lpc288x_set_flash_clk(bank); - - for (lockregion = first; lockregion <= last; lockregion++) { - if (set) { - /* write an odd value to base addy to protect... */ - value = 0x01; - } else { - /* write an even value to base addy to unprotect... */ - value = 0x00; - } - target_write_u32(target, bank->sectors[lockregion].offset, value); - target_write_u32(target, F_CTRL, FC_LOAD_REQ | FC_PROTECT | FC_WEN | FC_FUNC | - FC_CS); - } - - return ERROR_OK; -} - -struct flash_driver lpc288x_flash = { - .name = "lpc288x", - .flash_bank_command = lpc288x_flash_bank_command, - .erase = lpc288x_erase, - .protect = lpc288x_protect, - .write = lpc288x_write, - .read = default_flash_read, - .probe = lpc288x_probe, - .auto_probe = lpc288x_probe, - .erase_check = lpc288x_erase_check, - .protect_check = lpc288x_protect_check, -}; diff --git a/src/flash/nor/lpc2900.c b/src/flash/nor/lpc2900.c deleted file mode 100644 index 515a3f7b2..000000000 --- a/src/flash/nor/lpc2900.c +++ /dev/null @@ -1,1601 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2009 by * - * Rolf Meeser * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 -#include "config.h" -#endif - -#include "imp.h" -#include -#include -#include -#include - -/* 1024 bytes */ -#define KiB 1024 - -/* Some flash constants */ -#define FLASH_PAGE_SIZE 512 /* bytes */ -#define FLASH_ERASE_TIME 100000 /* microseconds */ -#define FLASH_PROGRAM_TIME 1000 /* microseconds */ - -/* Chip ID / Feature Registers */ -#define CHIPID 0xE0000000 /* Chip ID */ -#define FEAT0 0xE0000100 /* Chip feature 0 */ -#define FEAT1 0xE0000104 /* Chip feature 1 */ -#define FEAT2 0xE0000108 /* Chip feature 2 (contains flash size indicator) */ -#define FEAT3 0xE000010C /* Chip feature 3 */ - -#define EXPECTED_CHIPID 0x209CE02B /* Chip ID of all LPC2900 devices */ - -/* Flash/EEPROM Control Registers */ -#define FCTR 0x20200000 /* Flash control */ -#define FPTR 0x20200008 /* Flash program-time */ -#define FTCTR 0x2020000C /* Flash test control */ -#define FBWST 0x20200010 /* Flash bridge wait-state */ -#define FCRA 0x2020001C /* Flash clock divider */ -#define FMSSTART 0x20200020 /* Flash Built-In Selft Test start address */ -#define FMSSTOP 0x20200024 /* Flash Built-In Selft Test stop address */ -#define FMS16 0x20200028 /* Flash 16-bit signature */ -#define FMSW0 0x2020002C /* Flash 128-bit signature Word 0 */ -#define FMSW1 0x20200030 /* Flash 128-bit signature Word 1 */ -#define FMSW2 0x20200034 /* Flash 128-bit signature Word 2 */ -#define FMSW3 0x20200038 /* Flash 128-bit signature Word 3 */ - -#define EECMD 0x20200080 /* EEPROM command */ -#define EEADDR 0x20200084 /* EEPROM address */ -#define EEWDATA 0x20200088 /* EEPROM write data */ -#define EERDATA 0x2020008C /* EEPROM read data */ -#define EEWSTATE 0x20200090 /* EEPROM wait state */ -#define EECLKDIV 0x20200094 /* EEPROM clock divider */ -#define EEPWRDWN 0x20200098 /* EEPROM power-down/start */ -#define EEMSSTART 0x2020009C /* EEPROM BIST start address */ -#define EEMSSTOP 0x202000A0 /* EEPROM BIST stop address */ -#define EEMSSIG 0x202000A4 /* EEPROM 24-bit BIST signature */ - -#define INT_CLR_ENABLE 0x20200FD8 /* Flash/EEPROM interrupt clear enable */ -#define INT_SET_ENABLE 0x20200FDC /* Flash/EEPROM interrupt set enable */ -#define INT_STATUS 0x20200FE0 /* Flash/EEPROM interrupt status */ -#define INT_ENABLE 0x20200FE4 /* Flash/EEPROM interrupt enable */ -#define INT_CLR_STATUS 0x20200FE8 /* Flash/EEPROM interrupt clear status */ -#define INT_SET_STATUS 0x20200FEC /* Flash/EEPROM interrupt set status */ - -/* Interrupt sources */ -#define INTSRC_END_OF_PROG (1 << 28) -#define INTSRC_END_OF_BIST (1 << 27) -#define INTSRC_END_OF_RDWR (1 << 26) -#define INTSRC_END_OF_MISR (1 << 2) -#define INTSRC_END_OF_BURN (1 << 1) -#define INTSRC_END_OF_ERASE (1 << 0) - -/* FCTR bits */ -#define FCTR_FS_LOADREQ (1 << 15) -#define FCTR_FS_CACHECLR (1 << 14) -#define FCTR_FS_CACHEBYP (1 << 13) -#define FCTR_FS_PROGREQ (1 << 12) -#define FCTR_FS_RLS (1 << 11) -#define FCTR_FS_PDL (1 << 10) -#define FCTR_FS_PD (1 << 9) -#define FCTR_FS_WPB (1 << 7) -#define FCTR_FS_ISS (1 << 6) -#define FCTR_FS_RLD (1 << 5) -#define FCTR_FS_DCR (1 << 4) -#define FCTR_FS_WEB (1 << 2) -#define FCTR_FS_WRE (1 << 1) -#define FCTR_FS_CS (1 << 0) -/* FPTR bits */ -#define FPTR_EN_T (1 << 15) -/* FTCTR bits */ -#define FTCTR_FS_BYPASS_R (1 << 29) -#define FTCTR_FS_BYPASS_W (1 << 28) -/* FMSSTOP bits */ -#define FMSSTOP_MISR_START (1 << 17) -/* EEMSSTOP bits */ -#define EEMSSTOP_STRTBIST (1 << 31) - -/* Index sector */ -#define ISS_CUSTOMER_START1 (0x830) -#define ISS_CUSTOMER_END1 (0xA00) -#define ISS_CUSTOMER_SIZE1 (ISS_CUSTOMER_END1 - ISS_CUSTOMER_START1) -#define ISS_CUSTOMER_NWORDS1 (ISS_CUSTOMER_SIZE1 / 4) -#define ISS_CUSTOMER_START2 (0xA40) -#define ISS_CUSTOMER_END2 (0xC00) -#define ISS_CUSTOMER_SIZE2 (ISS_CUSTOMER_END2 - ISS_CUSTOMER_START2) -#define ISS_CUSTOMER_NWORDS2 (ISS_CUSTOMER_SIZE2 / 4) -#define ISS_CUSTOMER_SIZE (ISS_CUSTOMER_SIZE1 + ISS_CUSTOMER_SIZE2) - -/** - * Private data for \c lpc2900 flash driver. - */ -struct lpc2900_flash_bank { - /** - * This flag is set when the device has been successfully probed. - */ - bool is_probed; - - /** - * Holds the value read from CHIPID register. - * The driver will not load if the chipid doesn't match the expected - * value of 0x209CE02B of the LPC2900 family. A probe will only be done - * if the chipid does not yet contain the expected value. - */ - uint32_t chipid; - - /** - * String holding device name. - * This string is set by the probe function to the type number of the - * device. It takes the form "LPC29xx". - */ - char *target_name; - - /** - * System clock frequency. - * Holds the clock frequency in Hz, as passed by the configuration file - * to the flash bank command. - */ - uint32_t clk_sys_fmc; - - /** - * Flag to indicate that dangerous operations are possible. - * This flag can be set by passing the correct password to the - * lpc2900 password command. If set, other dangerous commands, - * which operate on the index sector, can be executed. - */ - uint32_t risky; - - /** - * Maximum contiguous block of internal SRAM (bytes). - * Autodetected by the driver. Not the total amount of SRAM, only the - * the largest \em contiguous block! - */ - uint32_t max_ram_block; - -}; - -static uint32_t lpc2900_wait_status(struct flash_bank *bank, uint32_t mask, int timeout); -static void lpc2900_setup(struct flash_bank *bank); -static uint32_t lpc2900_is_ready(struct flash_bank *bank); -static uint32_t lpc2900_read_security_status(struct flash_bank *bank); -static uint32_t lpc2900_run_bist128(struct flash_bank *bank, - uint32_t addr_from, uint32_t addr_to, - uint32_t signature[4]); -static uint32_t lpc2900_address2sector(struct flash_bank *bank, uint32_t offset); -static uint32_t lpc2900_calc_tr(uint32_t clock_var, uint32_t time_var); - -/*********************** Helper functions **************************/ - -/** - * Wait for an event in mask to occur in INT_STATUS. - * - * Return when an event occurs, or after a timeout. - * - * @param[in] bank Pointer to the flash bank descriptor - * @param[in] mask Mask to be used for INT_STATUS - * @param[in] timeout Timeout in ms - */ -static uint32_t lpc2900_wait_status(struct flash_bank *bank, - uint32_t mask, - int timeout) -{ - uint32_t int_status; - struct target *target = bank->target; - - do { - alive_sleep(1); - timeout--; - target_read_u32(target, INT_STATUS, &int_status); - } while (((int_status & mask) == 0) && (timeout != 0)); - - if (timeout == 0) { - LOG_DEBUG("Timeout!"); - return ERROR_FLASH_OPERATION_FAILED; - } - - return ERROR_OK; -} - -/** - * Set up the flash for erase/program operations. - * - * Enable the flash, and set the correct CRA clock of 66 kHz. - * - * @param bank Pointer to the flash bank descriptor - */ -static void lpc2900_setup(struct flash_bank *bank) -{ - uint32_t fcra; - struct lpc2900_flash_bank *lpc2900_info = bank->driver_priv; - - /* Power up the flash block */ - target_write_u32(bank->target, FCTR, FCTR_FS_WEB | FCTR_FS_CS); - - fcra = (lpc2900_info->clk_sys_fmc / (3 * 66000)) - 1; - target_write_u32(bank->target, FCRA, fcra); -} - -/** - * Check if device is ready. - * - * Check if device is ready for flash operation: - * Must have been successfully probed. - * Must be halted. - */ -static uint32_t lpc2900_is_ready(struct flash_bank *bank) -{ - struct lpc2900_flash_bank *lpc2900_info = bank->driver_priv; - - if (!lpc2900_info->is_probed) - return ERROR_FLASH_BANK_NOT_PROBED; - - if (bank->target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - return ERROR_OK; -} - -/** - * Read the status of sector security from the index sector. - * - * @param bank Pointer to the flash bank descriptor - */ -static uint32_t lpc2900_read_security_status(struct flash_bank *bank) -{ - uint32_t status = lpc2900_is_ready(bank); - if (status != ERROR_OK) - return status; - - struct target *target = bank->target; - - /* Enable ISS access */ - target_write_u32(target, FCTR, FCTR_FS_CS | FCTR_FS_WEB | FCTR_FS_ISS); - - /* Read the relevant block of memory from the ISS sector */ - uint32_t iss_secured_field[0x230/16][4]; - target_read_memory(target, bank->base + 0xC00, 4, 0x230/4, - (uint8_t *)iss_secured_field); - - /* Disable ISS access */ - target_write_u32(target, FCTR, FCTR_FS_CS | FCTR_FS_WEB); - - /* Check status of each sector. Note that the sector numbering in the LPC2900 - * is different from the logical sector numbers used in OpenOCD! - * Refer to the user manual for details. - * - * All zeros (16x 0x00) are treated as a secured sector (is_protected = 1) - * All ones (16x 0xFF) are treated as a non-secured sector (is_protected = 0) - * Anything else is undefined (is_protected = -1). This is treated as - * a protected sector! - */ - int sector; - int index_t; - for (sector = 0; sector < bank->num_sectors; sector++) { - /* Convert logical sector number to physical sector number */ - if (sector <= 4) - index_t = sector + 11; - else if (sector <= 7) - index_t = sector + 27; - else - index_t = sector - 8; - - bank->sectors[sector].is_protected = -1; - - if ((iss_secured_field[index_t][0] == 0x00000000) && - (iss_secured_field[index_t][1] == 0x00000000) && - (iss_secured_field[index_t][2] == 0x00000000) && - (iss_secured_field[index_t][3] == 0x00000000)) - bank->sectors[sector].is_protected = 1; - - if ((iss_secured_field[index_t][0] == 0xFFFFFFFF) && - (iss_secured_field[index_t][1] == 0xFFFFFFFF) && - (iss_secured_field[index_t][2] == 0xFFFFFFFF) && - (iss_secured_field[index_t][3] == 0xFFFFFFFF)) - bank->sectors[sector].is_protected = 0; - } - - return ERROR_OK; -} - -/** - * Use BIST to calculate a 128-bit hash value over a range of flash. - * - * @param bank Pointer to the flash bank descriptor - * @param addr_from - * @param addr_to - * @param signature - */ -static uint32_t lpc2900_run_bist128(struct flash_bank *bank, - uint32_t addr_from, - uint32_t addr_to, - uint32_t signature[4]) -{ - struct target *target = bank->target; - - /* Clear END_OF_MISR interrupt status */ - target_write_u32(target, INT_CLR_STATUS, INTSRC_END_OF_MISR); - - /* Start address */ - target_write_u32(target, FMSSTART, addr_from >> 4); - /* End address, and issue start command */ - target_write_u32(target, FMSSTOP, (addr_to >> 4) | FMSSTOP_MISR_START); - - /* Poll for end of operation. Calculate a reasonable timeout. */ - if (lpc2900_wait_status(bank, INTSRC_END_OF_MISR, 1000) != ERROR_OK) - return ERROR_FLASH_OPERATION_FAILED; - - /* Return the signature */ - uint8_t sig_buf[4 * 4]; - target_read_memory(target, FMSW0, 4, 4, sig_buf); - target_buffer_get_u32_array(target, sig_buf, 4, signature); - - return ERROR_OK; -} - -/** - * Return sector number for given address. - * - * Return the (logical) sector number for a given relative address. - * No sanity check is done. It assumed that the address is valid. - * - * @param bank Pointer to the flash bank descriptor - * @param offset Offset address relative to bank start - */ -static uint32_t lpc2900_address2sector(struct flash_bank *bank, - uint32_t offset) -{ - uint32_t address = bank->base + offset; - - /* Run through all sectors of this bank */ - int sector; - for (sector = 0; sector < bank->num_sectors; sector++) { - /* Return immediately if address is within the current sector */ - if (address < (bank->sectors[sector].offset + bank->sectors[sector].size)) - return sector; - } - - /* We should never come here. If we do, return an arbitrary sector number. */ - return 0; -} - -/** - * Write one page to the index sector. - * - * @param bank Pointer to the flash bank descriptor - * @param pagenum Page number (0...7) - * @param page Page array (FLASH_PAGE_SIZE bytes) - */ -static int lpc2900_write_index_page(struct flash_bank *bank, - int pagenum, - uint8_t page[FLASH_PAGE_SIZE]) -{ - /* Only pages 4...7 are user writable */ - if ((pagenum < 4) || (pagenum > 7)) { - LOG_ERROR("Refuse to burn index sector page %d", pagenum); - return ERROR_COMMAND_ARGUMENT_INVALID; - } - - /* Get target, and check if it's halted */ - struct target *target = bank->target; - if (target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - /* Private info */ - struct lpc2900_flash_bank *lpc2900_info = bank->driver_priv; - - /* Enable flash block and set the correct CRA clock of 66 kHz */ - lpc2900_setup(bank); - - /* Un-protect the index sector */ - target_write_u32(target, bank->base, 0); - target_write_u32(target, FCTR, - FCTR_FS_LOADREQ | FCTR_FS_WPB | FCTR_FS_ISS | - FCTR_FS_WEB | FCTR_FS_WRE | FCTR_FS_CS); - - /* Set latch load mode */ - target_write_u32(target, FCTR, - FCTR_FS_ISS | FCTR_FS_WEB | FCTR_FS_WRE | FCTR_FS_CS); - - /* Write whole page to flash data latches */ - if (target_write_memory(target, - bank->base + pagenum * FLASH_PAGE_SIZE, - 4, FLASH_PAGE_SIZE / 4, page) != ERROR_OK) { - LOG_ERROR("Index sector write failed @ page %d", pagenum); - target_write_u32(target, FCTR, FCTR_FS_CS | FCTR_FS_WEB); - - return ERROR_FLASH_OPERATION_FAILED; - } - - /* Clear END_OF_BURN interrupt status */ - target_write_u32(target, INT_CLR_STATUS, INTSRC_END_OF_BURN); - - /* Set the program/erase time to FLASH_PROGRAM_TIME */ - target_write_u32(target, FPTR, - FPTR_EN_T | lpc2900_calc_tr(lpc2900_info->clk_sys_fmc, - FLASH_PROGRAM_TIME)); - - /* Trigger flash write */ - target_write_u32(target, FCTR, - FCTR_FS_PROGREQ | FCTR_FS_ISS | - FCTR_FS_WPB | FCTR_FS_WRE | FCTR_FS_CS); - - /* Wait for the end of the write operation. If it's not over after one - * second, something went dreadfully wrong... :-( - */ - if (lpc2900_wait_status(bank, INTSRC_END_OF_BURN, 1000) != ERROR_OK) { - LOG_ERROR("Index sector write failed @ page %d", pagenum); - target_write_u32(target, FCTR, FCTR_FS_CS | FCTR_FS_WEB); - - return ERROR_FLASH_OPERATION_FAILED; - } - - target_write_u32(target, FCTR, FCTR_FS_CS | FCTR_FS_WEB); - - return ERROR_OK; -} - -/** - * Calculate FPTR.TR register value for desired program/erase time. - * - * @param clock System clock in Hz - * @param time Program/erase time in µs - */ -static uint32_t lpc2900_calc_tr(uint32_t clock_var, uint32_t time_var) -{ - /* ((time[µs]/1e6) * f[Hz]) + 511 - * FPTR.TR = ------------------------------- - * 512 - */ - - uint32_t tr_val = (uint32_t)((((time_var / 1e6) * clock_var) + 511.0) / 512.0); - - return tr_val; -} - -/*********************** Private flash commands **************************/ - - -/** - * Command to determine the signature of the whole flash. - * - * Uses the Built-In-Self-Test (BIST) to generate a 128-bit hash value - * of the flash content. - */ -COMMAND_HANDLER(lpc2900_handle_signature_command) -{ - uint32_t status; - uint32_t signature[4]; - - 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; - - if (bank->target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - /* Run BIST over whole flash range */ - status = lpc2900_run_bist128(bank, bank->base, bank->base + (bank->size - 1), signature); - if (status != ERROR_OK) - return status; - - command_print(CMD_CTX, "signature: 0x%8.8" PRIx32 - ":0x%8.8" PRIx32 - ":0x%8.8" PRIx32 - ":0x%8.8" PRIx32, - signature[3], signature[2], signature[1], signature[0]); - - return ERROR_OK; -} - -/** - * Store customer info in file. - * - * Read customer info from index sector, and store that block of data into - * a disk file. The format is binary. - */ -COMMAND_HANDLER(lpc2900_handle_read_custom_command) -{ - if (CMD_ARGC < 2) - 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 lpc2900_flash_bank *lpc2900_info = bank->driver_priv; - lpc2900_info->risky = 0; - - /* Get target, and check if it's halted */ - struct target *target = bank->target; - if (target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - /* Storage for customer info. Read in two parts */ - uint8_t customer[4 * (ISS_CUSTOMER_NWORDS1 + ISS_CUSTOMER_NWORDS2)]; - - /* Enable access to index sector */ - target_write_u32(target, FCTR, FCTR_FS_CS | FCTR_FS_WEB | FCTR_FS_ISS); - - /* Read two parts */ - target_read_memory(target, bank->base+ISS_CUSTOMER_START1, 4, - ISS_CUSTOMER_NWORDS1, - &customer[0]); - target_read_memory(target, bank->base+ISS_CUSTOMER_START2, 4, - ISS_CUSTOMER_NWORDS2, - &customer[4 * ISS_CUSTOMER_NWORDS1]); - - /* Deactivate access to index sector */ - target_write_u32(target, FCTR, FCTR_FS_CS | FCTR_FS_WEB); - - /* Try and open the file */ - struct fileio *fileio; - const char *filename = CMD_ARGV[1]; - int ret = fileio_open(&fileio, filename, FILEIO_WRITE, FILEIO_BINARY); - if (ret != ERROR_OK) { - LOG_WARNING("Could not open file %s", filename); - return ret; - } - - size_t 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); - return ret; - } - - fileio_close(fileio); - - return ERROR_OK; -} - -/** - * Enter password to enable potentially dangerous options. - */ -COMMAND_HANDLER(lpc2900_handle_password_command) -{ - if (CMD_ARGC < 2) - 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 lpc2900_flash_bank *lpc2900_info = bank->driver_priv; - -#define ISS_PASSWORD "I_know_what_I_am_doing" - - lpc2900_info->risky = !strcmp(CMD_ARGV[1], ISS_PASSWORD); - - if (!lpc2900_info->risky) { - command_print(CMD_CTX, "Wrong password (use '%s')", ISS_PASSWORD); - return ERROR_COMMAND_ARGUMENT_INVALID; - } - - command_print(CMD_CTX, - "Potentially dangerous operation allowed in next command!"); - - return ERROR_OK; -} - -/** - * Write customer info from file to the index sector. - */ -COMMAND_HANDLER(lpc2900_handle_write_custom_command) -{ - if (CMD_ARGC < 2) - 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 lpc2900_flash_bank *lpc2900_info = bank->driver_priv; - - /* Check if command execution is allowed. */ - if (!lpc2900_info->risky) { - command_print(CMD_CTX, "Command execution not allowed!"); - return ERROR_COMMAND_ARGUMENT_INVALID; - } - lpc2900_info->risky = 0; - - /* Get target, and check if it's halted */ - struct target *target = bank->target; - if (target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - /* The image will always start at offset 0 */ - struct image image; - image.base_address_set = 1; - image.base_address = 0; - image.start_address_set = 0; - - const char *filename = CMD_ARGV[1]; - const char *type = (CMD_ARGC >= 3) ? CMD_ARGV[2] : NULL; - retval = image_open(&image, filename, type); - if (retval != ERROR_OK) - return retval; - - /* Do a sanity check: The image must be exactly the size of the customer - programmable area. Any other size is rejected. */ - if (image.num_sections != 1) { - LOG_ERROR("Only one section allowed in image file."); - return ERROR_COMMAND_SYNTAX_ERROR; - } - if ((image.sections[0].base_address != 0) || - (image.sections[0].size != ISS_CUSTOMER_SIZE)) { - LOG_ERROR("Incorrect image file size. Expected %d, " - "got %" PRIu32, - ISS_CUSTOMER_SIZE, image.sections[0].size); - return ERROR_COMMAND_SYNTAX_ERROR; - } - - /* Well boys, I reckon this is it... */ - - /* Customer info is split into two blocks in pages 4 and 5. */ - uint8_t page[FLASH_PAGE_SIZE]; - - /* Page 4 */ - uint32_t offset = ISS_CUSTOMER_START1 % FLASH_PAGE_SIZE; - memset(page, 0xff, FLASH_PAGE_SIZE); - size_t size_read; - retval = image_read_section(&image, 0, 0, - ISS_CUSTOMER_SIZE1, &page[offset], &size_read); - if (retval != ERROR_OK) { - LOG_ERROR("couldn't read from file '%s'", filename); - image_close(&image); - return retval; - } - retval = lpc2900_write_index_page(bank, 4, page); - if (retval != ERROR_OK) { - image_close(&image); - return retval; - } - - /* Page 5 */ - offset = ISS_CUSTOMER_START2 % FLASH_PAGE_SIZE; - memset(page, 0xff, FLASH_PAGE_SIZE); - retval = image_read_section(&image, 0, ISS_CUSTOMER_SIZE1, - ISS_CUSTOMER_SIZE2, &page[offset], &size_read); - if (retval != ERROR_OK) { - LOG_ERROR("couldn't read from file '%s'", filename); - image_close(&image); - return retval; - } - retval = lpc2900_write_index_page(bank, 5, page); - if (retval != ERROR_OK) { - image_close(&image); - return retval; - } - - image_close(&image); - - return ERROR_OK; -} - -/** - * Activate 'sector security' for a range of sectors. - */ -COMMAND_HANDLER(lpc2900_handle_secure_sector_command) -{ - if (CMD_ARGC < 3) - return ERROR_COMMAND_SYNTAX_ERROR; - - /* Get the bank descriptor */ - struct flash_bank *bank; - int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank); - if (ERROR_OK != retval) - return retval; - - struct lpc2900_flash_bank *lpc2900_info = bank->driver_priv; - - /* Check if command execution is allowed. */ - if (!lpc2900_info->risky) { - command_print(CMD_CTX, "Command execution not allowed! " - "(use 'password' command first)"); - return ERROR_COMMAND_ARGUMENT_INVALID; - } - lpc2900_info->risky = 0; - - /* Read sector range, and do a sanity check. */ - int first, last; - COMMAND_PARSE_NUMBER(int, CMD_ARGV[1], first); - COMMAND_PARSE_NUMBER(int, CMD_ARGV[2], last); - if ((first >= bank->num_sectors) || - (last >= bank->num_sectors) || - (first > last)) { - command_print(CMD_CTX, "Illegal sector range"); - return ERROR_COMMAND_ARGUMENT_INVALID; - } - - uint8_t page[FLASH_PAGE_SIZE]; - int sector; - - /* Sectors in page 6 */ - if ((first <= 4) || (last >= 8)) { - memset(&page, 0xff, FLASH_PAGE_SIZE); - for (sector = first; sector <= last; sector++) { - if (sector <= 4) - memset(&page[0xB0 + 16*sector], 0, 16); - else if (sector >= 8) - memset(&page[0x00 + 16*(sector - 8)], 0, 16); - } - - retval = lpc2900_write_index_page(bank, 6, page); - if (retval != ERROR_OK) { - LOG_ERROR("failed to update index sector page 6"); - return retval; - } - } - - /* Sectors in page 7 */ - if ((first <= 7) && (last >= 5)) { - memset(&page, 0xff, FLASH_PAGE_SIZE); - for (sector = first; sector <= last; sector++) { - if ((sector >= 5) && (sector <= 7)) - memset(&page[0x00 + 16*(sector - 5)], 0, 16); - } - - retval = lpc2900_write_index_page(bank, 7, page); - if (retval != ERROR_OK) { - LOG_ERROR("failed to update index sector page 7"); - return retval; - } - } - - command_print(CMD_CTX, - "Sectors security will become effective after next power cycle"); - - /* Update the sector security status */ - if (lpc2900_read_security_status(bank) != ERROR_OK) { - LOG_ERROR("Cannot determine sector security status"); - return ERROR_FLASH_OPERATION_FAILED; - } - - return ERROR_OK; -} - -/** - * Activate JTAG protection. - */ -COMMAND_HANDLER(lpc2900_handle_secure_jtag_command) -{ - if (CMD_ARGC < 1) - return ERROR_COMMAND_SYNTAX_ERROR; - - /* Get the bank descriptor */ - struct flash_bank *bank; - int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank); - if (ERROR_OK != retval) - return retval; - - struct lpc2900_flash_bank *lpc2900_info = bank->driver_priv; - - /* Check if command execution is allowed. */ - if (!lpc2900_info->risky) { - command_print(CMD_CTX, "Command execution not allowed! " - "(use 'password' command first)"); - return ERROR_COMMAND_ARGUMENT_INVALID; - } - lpc2900_info->risky = 0; - - /* Prepare page */ - uint8_t page[FLASH_PAGE_SIZE]; - memset(&page, 0xff, FLASH_PAGE_SIZE); - - - /* Insert "soft" protection word */ - page[0x30 + 15] = 0x7F; - page[0x30 + 11] = 0x7F; - page[0x30 + 7] = 0x7F; - page[0x30 + 3] = 0x7F; - - /* Write to page 5 */ - retval = lpc2900_write_index_page(bank, 5, page); - if (retval != ERROR_OK) { - LOG_ERROR("failed to update index sector page 5"); - return retval; - } - - LOG_INFO("JTAG security set. Good bye!"); - - return ERROR_OK; -} - -/*********************** Flash interface functions **************************/ - -static const struct command_registration lpc2900_exec_command_handlers[] = { - { - .name = "signature", - .usage = "", - .handler = lpc2900_handle_signature_command, - .mode = COMMAND_EXEC, - .help = "Calculate and display signature of flash bank.", - }, - { - .name = "read_custom", - .handler = lpc2900_handle_read_custom_command, - .mode = COMMAND_EXEC, - .usage = "bank_id filename", - .help = "Copies 912 bytes of customer information " - "from index sector into file.", - }, - { - .name = "password", - .handler = lpc2900_handle_password_command, - .mode = COMMAND_EXEC, - .usage = "bank_id password", - .help = "Enter fixed password to enable 'dangerous' options.", - }, - { - .name = "write_custom", - .handler = lpc2900_handle_write_custom_command, - .mode = COMMAND_EXEC, - .usage = "bank_id filename ('bin'|'ihex'|'elf'|'s19')", - .help = "Copies 912 bytes of customer info from file " - "to index sector.", - }, - { - .name = "secure_sector", - .handler = lpc2900_handle_secure_sector_command, - .mode = COMMAND_EXEC, - .usage = "bank_id first_sector last_sector", - .help = "Activate sector security for a range of sectors. " - "It will be effective after a power cycle.", - }, - { - .name = "secure_jtag", - .handler = lpc2900_handle_secure_jtag_command, - .mode = COMMAND_EXEC, - .usage = "bank_id", - .help = "Disable the JTAG port. " - "It will be effective after a power cycle.", - }, - COMMAND_REGISTRATION_DONE -}; - -static const struct command_registration lpc2900_command_handlers[] = { - { - .name = "lpc2900", - .mode = COMMAND_ANY, - .help = "LPC2900 flash command group", - .usage = "", - .chain = lpc2900_exec_command_handlers, - }, - COMMAND_REGISTRATION_DONE -}; - -/** Evaluate flash bank command. */ -FLASH_BANK_COMMAND_HANDLER(lpc2900_flash_bank_command) -{ - struct lpc2900_flash_bank *lpc2900_info; - - if (CMD_ARGC < 6) - return ERROR_COMMAND_SYNTAX_ERROR; - - lpc2900_info = malloc(sizeof(struct lpc2900_flash_bank)); - bank->driver_priv = lpc2900_info; - - /* Get flash clock. - * Reject it if we can't meet the requirements for program time - * (if clock too slow), or for erase time (clock too fast). - */ - uint32_t clk_sys_fmc; - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[6], clk_sys_fmc); - lpc2900_info->clk_sys_fmc = clk_sys_fmc * 1000; - - uint32_t clock_limit; - /* Check program time limit */ - clock_limit = 512000000l / FLASH_PROGRAM_TIME; - if (lpc2900_info->clk_sys_fmc < clock_limit) { - LOG_WARNING("flash clock must be at least %" PRIu32 " kHz", - (clock_limit / 1000)); - return ERROR_FLASH_BANK_INVALID; - } - - /* Check erase time limit */ - clock_limit = (uint32_t)((32767.0 * 512.0 * 1e6) / FLASH_ERASE_TIME); - if (lpc2900_info->clk_sys_fmc > clock_limit) { - LOG_WARNING("flash clock must be a maximum of %" PRIu32 " kHz", - (clock_limit / 1000)); - return ERROR_FLASH_BANK_INVALID; - } - - /* Chip ID will be obtained by probing the device later */ - lpc2900_info->chipid = 0; - lpc2900_info->is_probed = false; - - return ERROR_OK; -} - -/** - * Erase sector(s). - * - * @param bank Pointer to the flash bank descriptor - * @param first First sector to be erased - * @param last Last sector (including) to be erased - */ -static int lpc2900_erase(struct flash_bank *bank, int first, int last) -{ - uint32_t status; - int sector; - int last_unsecured_sector; - struct target *target = bank->target; - struct lpc2900_flash_bank *lpc2900_info = bank->driver_priv; - - - status = lpc2900_is_ready(bank); - if (status != ERROR_OK) - return status; - - /* Sanity check on sector range */ - if ((first < 0) || (last < first) || (last >= bank->num_sectors)) { - LOG_INFO("Bad sector range"); - return ERROR_FLASH_SECTOR_INVALID; - } - - /* Update the info about secured sectors */ - lpc2900_read_security_status(bank); - - /* The selected sector range might include secured sectors. An attempt - * to erase such a sector will cause the erase to fail also for unsecured - * sectors. It is necessary to determine the last unsecured sector now, - * because we have to treat the last relevant sector in the list in - * a special way. - */ - last_unsecured_sector = -1; - for (sector = first; sector <= last; sector++) { - if (!bank->sectors[sector].is_protected) - last_unsecured_sector = sector; - } - - /* Exit now, in case of the rare constellation where all sectors in range - * are secured. This is regarded a success, since erasing/programming of - * secured sectors shall be handled transparently. - */ - if (last_unsecured_sector == -1) - return ERROR_OK; - - /* Enable flash block and set the correct CRA clock of 66 kHz */ - lpc2900_setup(bank); - - /* Clear END_OF_ERASE interrupt status */ - target_write_u32(target, INT_CLR_STATUS, INTSRC_END_OF_ERASE); - - /* Set the program/erase timer to FLASH_ERASE_TIME */ - target_write_u32(target, FPTR, - FPTR_EN_T | lpc2900_calc_tr(lpc2900_info->clk_sys_fmc, - FLASH_ERASE_TIME)); - - /* Sectors are marked for erasure, then erased all together */ - for (sector = first; sector <= last_unsecured_sector; sector++) { - /* Only mark sectors that aren't secured. Any attempt to erase a group - * of sectors will fail if any single one of them is secured! - */ - if (!bank->sectors[sector].is_protected) { - /* Unprotect the sector */ - target_write_u32(target, bank->sectors[sector].offset, 0); - target_write_u32(target, FCTR, - FCTR_FS_LOADREQ | FCTR_FS_WPB | - FCTR_FS_WEB | FCTR_FS_WRE | FCTR_FS_CS); - - /* Mark the sector for erasure. The last sector in the list - triggers the erasure. */ - target_write_u32(target, bank->sectors[sector].offset, 0); - if (sector == last_unsecured_sector) { - target_write_u32(target, FCTR, - FCTR_FS_PROGREQ | FCTR_FS_WPB | FCTR_FS_CS); - } else { - target_write_u32(target, FCTR, - FCTR_FS_LOADREQ | FCTR_FS_WPB | - FCTR_FS_WEB | FCTR_FS_CS); - } - } - } - - /* Wait for the end of the erase operation. If it's not over after two seconds, - * something went dreadfully wrong... :-( - */ - if (lpc2900_wait_status(bank, INTSRC_END_OF_ERASE, 2000) != ERROR_OK) - return ERROR_FLASH_OPERATION_FAILED; - - /* Normal flash operating mode */ - target_write_u32(target, FCTR, FCTR_FS_CS | FCTR_FS_WEB); - - return ERROR_OK; -} - -static int lpc2900_protect(struct flash_bank *bank, int set, int first, int last) -{ - /* This command is not supported. - * "Protection" in LPC2900 terms is handled transparently. Sectors will - * automatically be unprotected as needed. - * Instead we use the concept of sector security. A secured sector is shown - * as "protected" in OpenOCD. Sector security is a permanent feature, and - * cannot be disabled once activated. - */ - - return ERROR_OK; -} - -/** - * Write data to flash. - * - * @param bank Pointer to the flash bank descriptor - * @param buffer Buffer with data - * @param offset Start address (relative to bank start) - * @param count Number of bytes to be programmed - */ -static int lpc2900_write(struct flash_bank *bank, const uint8_t *buffer, - uint32_t offset, uint32_t count) -{ - uint8_t page[FLASH_PAGE_SIZE]; - uint32_t status; - uint32_t num_bytes; - struct target *target = bank->target; - struct lpc2900_flash_bank *lpc2900_info = bank->driver_priv; - int sector; - int retval; - - static const uint32_t write_target_code[] = { - /* Set auto latch mode: FCTR=CS|WRE|WEB */ - 0xe3a0a007, /* loop mov r10, #0x007 */ - 0xe583a000, /* str r10,[r3,#0] */ - - /* Load complete page into latches */ - 0xe3a06020, /* mov r6,#(512/16) */ - 0xe8b00f00, /* next ldmia r0!,{r8-r11} */ - 0xe8a10f00, /* stmia r1!,{r8-r11} */ - 0xe2566001, /* subs r6,#1 */ - 0x1afffffb, /* bne next */ - - /* Clear END_OF_BURN interrupt status */ - 0xe3a0a002, /* mov r10,#(1 << 1) */ - 0xe583afe8, /* str r10,[r3,#0xfe8] */ - - /* Set the erase time to FLASH_PROGRAM_TIME */ - 0xe5834008, /* str r4,[r3,#8] */ - - /* Trigger flash write - * FCTR = CS | WRE | WPB | PROGREQ */ - 0xe3a0a083, /* mov r10,#0x83 */ - 0xe38aaa01, /* orr r10,#0x1000 */ - 0xe583a000, /* str r10,[r3,#0] */ - - /* Wait for end of burn */ - 0xe593afe0, /* wait ldr r10,[r3,#0xfe0] */ - 0xe21aa002, /* ands r10,#(1 << 1) */ - 0x0afffffc, /* beq wait */ - - /* End? */ - 0xe2522001, /* subs r2,#1 */ - 0x1affffed, /* bne loop */ - - 0xeafffffe /* done b done */ - }; - - - status = lpc2900_is_ready(bank); - if (status != ERROR_OK) - return status; - - /* Enable flash block and set the correct CRA clock of 66 kHz */ - lpc2900_setup(bank); - - /* Update the info about secured sectors */ - lpc2900_read_security_status(bank); - - /* Unprotect all involved sectors */ - for (sector = 0; sector < bank->num_sectors; sector++) { - /* Start address in or before this sector? - * End address in or behind this sector? */ - if (((bank->base + offset) < - (bank->sectors[sector].offset + bank->sectors[sector].size)) && - ((bank->base + (offset + count - 1)) >= bank->sectors[sector].offset)) { - /* This sector is involved and needs to be unprotected. - * Don't do it for secured sectors. - */ - if (!bank->sectors[sector].is_protected) { - target_write_u32(target, bank->sectors[sector].offset, 0); - target_write_u32(target, FCTR, - FCTR_FS_LOADREQ | FCTR_FS_WPB | - FCTR_FS_WEB | FCTR_FS_WRE | FCTR_FS_CS); - } - } - } - - /* Set the program/erase time to FLASH_PROGRAM_TIME */ - uint32_t prog_time = FPTR_EN_T | lpc2900_calc_tr(lpc2900_info->clk_sys_fmc, FLASH_PROGRAM_TIME); - - /* If there is a working area of reasonable size, use it to program via - * a target algorithm. If not, fall back to host programming. */ - - /* We need some room for target code. */ - const uint32_t target_code_size = sizeof(write_target_code); - - /* Try working area allocation. Start with a large buffer, and try with - * reduced size if that fails. */ - struct working_area *warea; - uint32_t buffer_size = lpc2900_info->max_ram_block - 1 * KiB; - while ((retval = target_alloc_working_area_try(target, - buffer_size + target_code_size, - &warea)) != ERROR_OK) { - /* Try a smaller buffer now, and stop if it's too small. */ - buffer_size -= 1 * KiB; - if (buffer_size < 2 * KiB) { - LOG_INFO("no (large enough) working area, falling back to host mode"); - warea = NULL; - break; - } - } - - if (warea) { - struct reg_param reg_params[5]; - struct arm_algorithm arm_algo; - - /* We can use target mode. Download the algorithm. */ - uint8_t code[sizeof(write_target_code)]; - target_buffer_set_u32_array(target, code, ARRAY_SIZE(write_target_code), - write_target_code); - retval = target_write_buffer(target, (warea->address) + buffer_size, sizeof(code), code); - if (retval != ERROR_OK) { - LOG_ERROR("Unable to write block write code to target"); - target_free_all_working_areas(target); - return ERROR_FLASH_OPERATION_FAILED; - } - - init_reg_param(®_params[0], "r0", 32, PARAM_OUT); - init_reg_param(®_params[1], "r1", 32, PARAM_OUT); - 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 to flash in large blocks */ - while (count != 0) { - uint32_t this_npages; - const uint8_t *this_buffer; - int start_sector = lpc2900_address2sector(bank, offset); - - /* First page / last page / rest */ - if (offset % FLASH_PAGE_SIZE) { - /* Block doesn't start on page boundary. - * Burn first partial page separately. */ - memset(&page, 0xff, sizeof(page)); - memcpy(&page[offset % FLASH_PAGE_SIZE], - buffer, - FLASH_PAGE_SIZE - (offset % FLASH_PAGE_SIZE)); - this_npages = 1; - this_buffer = &page[0]; - count = count + (offset % FLASH_PAGE_SIZE); - offset = offset - (offset % FLASH_PAGE_SIZE); - } else if (count < FLASH_PAGE_SIZE) { - /* Download last incomplete page separately. */ - memset(&page, 0xff, sizeof(page)); - memcpy(&page, buffer, count); - this_npages = 1; - this_buffer = &page[0]; - count = FLASH_PAGE_SIZE; - } else { - /* Download as many full pages as possible */ - this_npages = (count < buffer_size) ? - count / FLASH_PAGE_SIZE : - buffer_size / FLASH_PAGE_SIZE; - this_buffer = buffer; - - /* Make sure we stop at the next secured sector */ - sector = start_sector + 1; - while (sector < bank->num_sectors) { - /* Secured? */ - if (bank->sectors[sector].is_protected) { - /* Is that next sector within the current block? */ - if ((bank->sectors[sector].offset - bank->base) < - (offset + (this_npages * FLASH_PAGE_SIZE))) { - /* Yes! Split the block */ - this_npages = - (bank->sectors[sector].offset - - bank->base - offset) - / FLASH_PAGE_SIZE; - break; - } - } - - sector++; - } - } - - /* Skip the current sector if it is secured */ - if (bank->sectors[start_sector].is_protected) { - LOG_DEBUG("Skip secured sector %d", - start_sector); - - /* Stop if this is the last sector */ - if (start_sector == bank->num_sectors - 1) - break; - - /* Skip */ - uint32_t nskip = bank->sectors[start_sector].size - - (offset % bank->sectors[start_sector].size); - offset += nskip; - buffer += nskip; - count = (count >= nskip) ? (count - nskip) : 0; - continue; - } - - /* Execute buffer download */ - retval = target_write_buffer(target, warea->address, - this_npages * FLASH_PAGE_SIZE, this_buffer); - if (retval != ERROR_OK) { - LOG_ERROR("Unable to write data to target"); - target_free_all_working_areas(target); - return ERROR_FLASH_OPERATION_FAILED; - } - - /* Prepare registers */ - buf_set_u32(reg_params[0].value, 0, 32, warea->address); - buf_set_u32(reg_params[1].value, 0, 32, offset); - buf_set_u32(reg_params[2].value, 0, 32, this_npages); - buf_set_u32(reg_params[3].value, 0, 32, FCTR); - buf_set_u32(reg_params[4].value, 0, 32, FPTR_EN_T | prog_time); - - /* Execute algorithm, assume breakpoint for last instruction */ - arm_algo.common_magic = ARM_COMMON_MAGIC; - arm_algo.core_mode = ARM_MODE_SVC; - arm_algo.core_state = ARM_STATE_ARM; - - retval = target_run_algorithm(target, 0, NULL, 5, reg_params, - (warea->address) + buffer_size, - (warea->address) + buffer_size + target_code_size - 4, - 10000, /* 10s should be enough for max. 16 KiB of data */ - &arm_algo); - - if (retval != ERROR_OK) { - LOG_ERROR("Execution of flash algorithm failed."); - target_free_all_working_areas(target); - retval = ERROR_FLASH_OPERATION_FAILED; - break; - } - - count -= this_npages * FLASH_PAGE_SIZE; - buffer += this_npages * FLASH_PAGE_SIZE; - offset += this_npages * FLASH_PAGE_SIZE; - } - - /* Free all resources */ - 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]); - target_free_all_working_areas(target); - } else { - /* Write to flash memory page-wise */ - while (count != 0) { - /* How many bytes do we copy this time? */ - num_bytes = (count >= FLASH_PAGE_SIZE) ? - FLASH_PAGE_SIZE - (offset % FLASH_PAGE_SIZE) : - count; - - /* Don't do anything with it if the page is in a secured sector. */ - if (!bank->sectors[lpc2900_address2sector(bank, offset)].is_protected) { - /* Set latch load mode */ - target_write_u32(target, FCTR, - FCTR_FS_CS | FCTR_FS_WRE | FCTR_FS_WEB); - - /* Always clear the buffer (a little overhead, but who cares) */ - memset(page, 0xFF, FLASH_PAGE_SIZE); - - /* Copy them to the buffer */ - memcpy(&page[offset % FLASH_PAGE_SIZE], - &buffer[offset % FLASH_PAGE_SIZE], - num_bytes); - - /* Write whole page to flash data latches */ - if (target_write_memory(target, - bank->base + (offset - (offset % FLASH_PAGE_SIZE)), - 4, FLASH_PAGE_SIZE / 4, page) != ERROR_OK) { - LOG_ERROR("Write failed @ 0x%8.8" PRIx32, offset); - target_write_u32(target, FCTR, FCTR_FS_CS | FCTR_FS_WEB); - - return ERROR_FLASH_OPERATION_FAILED; - } - - /* Clear END_OF_BURN interrupt status */ - target_write_u32(target, INT_CLR_STATUS, INTSRC_END_OF_BURN); - - /* Set the programming time */ - target_write_u32(target, FPTR, FPTR_EN_T | prog_time); - - /* Trigger flash write */ - target_write_u32(target, FCTR, - FCTR_FS_CS | FCTR_FS_WRE | FCTR_FS_WPB | FCTR_FS_PROGREQ); - - /* Wait for the end of the write operation. If it's not over - * after one second, something went dreadfully wrong... :-( - */ - if (lpc2900_wait_status(bank, INTSRC_END_OF_BURN, 1000) != ERROR_OK) { - LOG_ERROR("Write failed @ 0x%8.8" PRIx32, offset); - target_write_u32(target, FCTR, FCTR_FS_CS | FCTR_FS_WEB); - - return ERROR_FLASH_OPERATION_FAILED; - } - } - - /* Update pointers and counters */ - offset += num_bytes; - buffer += num_bytes; - count -= num_bytes; - } - - retval = ERROR_OK; - } - - /* Normal flash operating mode */ - target_write_u32(target, FCTR, FCTR_FS_CS | FCTR_FS_WEB); - - return retval; -} - -/** - * Try and identify the device. - * - * Determine type number and its memory layout. - * - * @param bank Pointer to the flash bank descriptor - */ -static int lpc2900_probe(struct flash_bank *bank) -{ - struct lpc2900_flash_bank *lpc2900_info = bank->driver_priv; - struct target *target = bank->target; - int i = 0; - uint32_t offset; - - - if (target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - /* We want to do this only once. */ - if (lpc2900_info->is_probed) - return ERROR_OK; - - /* Probing starts with reading the CHIPID register. We will continue only - * if this identifies as an LPC2900 device. - */ - target_read_u32(target, CHIPID, &lpc2900_info->chipid); - - if (lpc2900_info->chipid != EXPECTED_CHIPID) { - LOG_WARNING("Device is not an LPC29xx"); - return ERROR_FLASH_OPERATION_FAILED; - } - - /* It's an LPC29xx device. Now read the feature register FEAT0...FEAT3. */ - uint32_t feat0, feat1, feat2, feat3; - target_read_u32(target, FEAT0, &feat0); - target_read_u32(target, FEAT1, &feat1); - target_read_u32(target, FEAT2, &feat2); - target_read_u32(target, FEAT3, &feat3); - - /* Base address */ - bank->base = 0x20000000; - - /* Determine flash layout from FEAT2 register */ - uint32_t num_64k_sectors = (feat2 >> 16) & 0xFF; - uint32_t num_8k_sectors = (feat2 >> 0) & 0xFF; - bank->num_sectors = num_64k_sectors + num_8k_sectors; - bank->size = KiB * (64 * num_64k_sectors + 8 * num_8k_sectors); - - /* Determine maximum contiguous RAM block */ - lpc2900_info->max_ram_block = 16 * KiB; - if ((feat1 & 0x30) == 0x30) { - lpc2900_info->max_ram_block = 32 * KiB; - if ((feat1 & 0x0C) == 0x0C) - lpc2900_info->max_ram_block = 48 * KiB; - } - - /* Determine package code and ITCM size */ - uint32_t package_code = feat0 & 0x0F; - uint32_t itcm_code = (feat1 >> 16) & 0x1F; - - /* Determine the exact type number. */ - uint32_t found = 1; - if ((package_code == 4) && (itcm_code == 5)) { - /* Old LPC2917 or LPC2919 (non-/01 devices) */ - lpc2900_info->target_name = (bank->size == 768*KiB) ? "LPC2919" : "LPC2917"; - } else { - if (package_code == 2) { - /* 100-pin package */ - if (bank->size == 128*KiB) - lpc2900_info->target_name = "LPC2921"; - else if (bank->size == 256*KiB) - lpc2900_info->target_name = "LPC2923"; - else if (bank->size == 512*KiB) - lpc2900_info->target_name = "LPC2925"; - else - found = 0; - } else if (package_code == 4) { - /* 144-pin package */ - if ((bank->size == 256*KiB) && (feat3 == 0xFFFFFFE9)) - lpc2900_info->target_name = "LPC2926"; - else if ((bank->size == 512*KiB) && (feat3 == 0xFFFFFCF0)) - lpc2900_info->target_name = "LPC2917/01"; - else if ((bank->size == 512*KiB) && (feat3 == 0xFFFFFFF1)) - lpc2900_info->target_name = "LPC2927"; - else if ((bank->size == 768*KiB) && (feat3 == 0xFFFFFCF8)) - lpc2900_info->target_name = "LPC2919/01"; - else if ((bank->size == 768*KiB) && (feat3 == 0xFFFFFFF9)) - lpc2900_info->target_name = "LPC2929"; - else - found = 0; - } else if (package_code == 5) { - /* 208-pin package */ - lpc2900_info->target_name = (bank->size == 0) ? "LPC2930" : "LPC2939"; - } else - found = 0; - } - - if (!found) { - LOG_WARNING("Unknown LPC29xx derivative (FEATx=" - "%08" PRIx32 ":%08" PRIx32 ":%08" PRIx32 ":%08" PRIx32 ")", - feat0, feat1, feat2, feat3); - return ERROR_FLASH_OPERATION_FAILED; - } - - /* Show detected device */ - LOG_INFO("Flash bank %d: Device %s, %" PRIu32 - " KiB in %d sectors", - bank->bank_number, - lpc2900_info->target_name, bank->size / KiB, - bank->num_sectors); - - /* Flashless devices cannot be handled */ - if (bank->num_sectors == 0) { - LOG_WARNING("Flashless device cannot be handled"); - return ERROR_FLASH_OPERATION_FAILED; - } - - /* Sector layout. - * These are logical sector numbers. When doing real flash operations, - * the logical flash number are translated into the physical flash numbers - * of the device. - */ - bank->sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors); - - offset = 0; - for (i = 0; i < bank->num_sectors; i++) { - bank->sectors[i].offset = offset; - bank->sectors[i].is_erased = -1; - bank->sectors[i].is_protected = -1; - - if (i <= 7) - bank->sectors[i].size = 8 * KiB; - else if (i <= 18) - bank->sectors[i].size = 64 * KiB; - else { - /* We shouldn't come here. But there might be a new part out there - * that has more than 19 sectors. Politely ask for a fix then. - */ - bank->sectors[i].size = 0; - LOG_ERROR("Never heard about sector %d", i); - } - - offset += bank->sectors[i].size; - } - - lpc2900_info->is_probed = true; - - /* Read sector security status */ - if (lpc2900_read_security_status(bank) != ERROR_OK) { - LOG_ERROR("Cannot determine sector security status"); - return ERROR_FLASH_OPERATION_FAILED; - } - - return ERROR_OK; -} - -/** - * Run a blank check for each sector. - * - * For speed reasons, the device isn't read word by word. - * A hash value is calculated by the hardware ("BIST") for each sector. - * This value is then compared against the known hash of an empty sector. - * - * @param bank Pointer to the flash bank descriptor - */ -static int lpc2900_erase_check(struct flash_bank *bank) -{ - uint32_t status = lpc2900_is_ready(bank); - if (status != ERROR_OK) { - LOG_INFO("Processor not halted/not probed"); - return status; - } - - /* Use the BIST (Built-In Selft Test) to generate a signature of each flash - * sector. Compare against the expected signature of an empty sector. - */ - int sector; - for (sector = 0; sector < bank->num_sectors; sector++) { - uint32_t signature[4]; - status = lpc2900_run_bist128(bank, bank->sectors[sector].offset, - bank->sectors[sector].offset + (bank->sectors[sector].size - 1), signature); - if (status != ERROR_OK) - return status; - - /* The expected signatures for an empty sector are different - * for 8 KiB and 64 KiB sectors. - */ - if (bank->sectors[sector].size == 8*KiB) { - bank->sectors[sector].is_erased = - (signature[3] == 0x01ABAAAA) && - (signature[2] == 0xAAAAAAAA) && - (signature[1] == 0xAAAAAAAA) && - (signature[0] == 0xAAA00AAA); - } - if (bank->sectors[sector].size == 64*KiB) { - bank->sectors[sector].is_erased = - (signature[3] == 0x11801222) && - (signature[2] == 0xB88844FF) && - (signature[1] == 0x11A22008) && - (signature[0] == 0x2B1BFE44); - } - } - - return ERROR_OK; -} - -/** - * Get protection (sector security) status. - * - * Determine the status of "sector security" for each sector. - * A secured sector is one that can never be erased/programmed again. - * - * @param bank Pointer to the flash bank descriptor - */ -static int lpc2900_protect_check(struct flash_bank *bank) -{ - return lpc2900_read_security_status(bank); -} - -struct flash_driver lpc2900_flash = { - .name = "lpc2900", - .commands = lpc2900_command_handlers, - .flash_bank_command = lpc2900_flash_bank_command, - .erase = lpc2900_erase, - .protect = lpc2900_protect, - .write = lpc2900_write, - .read = default_flash_read, - .probe = lpc2900_probe, - .auto_probe = lpc2900_probe, - .erase_check = lpc2900_erase_check, - .protect_check = lpc2900_protect_check, -}; diff --git a/src/flash/nor/lpcspifi.c b/src/flash/nor/lpcspifi.c deleted file mode 100644 index 4eb6cc38a..000000000 --- a/src/flash/nor/lpcspifi.c +++ /dev/null @@ -1,945 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2012 by George Harris * - * george@luminairecoffee.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "imp.h" -#include "spi.h" -#include -#include -#include -#include - -/* Offsets from ssp_base into config & data registers */ -#define SSP_CR0 (0x00) /* Control register 0 */ -#define SSP_CR1 (0x04) /* Control register 1 */ -#define SSP_DATA (0x08) /* Data register (TX and RX) */ -#define SSP_SR (0x0C) /* Status register */ -#define SSP_CPSR (0x10) /* Clock prescale register */ - -/* Status register fields */ -#define SSP_BSY (0x00000010) - -/* Timeout in ms */ -#define SSP_CMD_TIMEOUT (100) -#define SSP_PROBE_TIMEOUT (100) -#define SSP_MAX_TIMEOUT (3000) - -/* Size of the stack to alloc in the working area for the execution of - * the ROM spifi_init() function */ -#define SPIFI_INIT_STACK_SIZE 512 - -struct lpcspifi_flash_bank { - int probed; - uint32_t ssp_base; - uint32_t io_base; - uint32_t ioconfig_base; - uint32_t bank_num; - uint32_t max_spi_clock_mhz; - const struct flash_device *dev; -}; - -/* flash_bank lpcspifi - */ -FLASH_BANK_COMMAND_HANDLER(lpcspifi_flash_bank_command) -{ - struct lpcspifi_flash_bank *lpcspifi_info; - - if (CMD_ARGC < 6) - return ERROR_COMMAND_SYNTAX_ERROR; - - lpcspifi_info = malloc(sizeof(struct lpcspifi_flash_bank)); - if (lpcspifi_info == NULL) { - LOG_ERROR("not enough memory"); - return ERROR_FAIL; - } - - bank->driver_priv = lpcspifi_info; - lpcspifi_info->probed = 0; - - return ERROR_OK; -} - -static inline int ioconfig_write_reg(struct target *target, uint32_t ioconfig_base, uint32_t offset, uint32_t value) -{ - return target_write_u32(target, ioconfig_base + offset, value); -} - -static inline int ssp_write_reg(struct target *target, uint32_t ssp_base, uint32_t offset, uint32_t value) -{ - return target_write_u32(target, ssp_base + offset, value); -} - -static inline int io_write_reg(struct target *target, uint32_t io_base, uint32_t offset, uint32_t value) -{ - return target_write_u32(target, io_base + offset, value); -} - -static inline int ssp_read_reg(struct target *target, uint32_t ssp_base, uint32_t offset, uint32_t *value) -{ - return target_read_u32(target, ssp_base + offset, value); -} - -static int ssp_setcs(struct target *target, uint32_t io_base, unsigned int value) -{ - return io_write_reg(target, io_base, 0x12ac, value ? 0xffffffff : 0x00000000); -} - -/* Poll the SSP busy flag. When this comes back as 0, the transfer is complete - * and the controller is idle. */ -static int poll_ssp_busy(struct target *target, uint32_t ssp_base, int timeout) -{ - int64_t endtime; - uint32_t value; - int retval; - - retval = ssp_read_reg(target, ssp_base, SSP_SR, &value); - if ((retval == ERROR_OK) && (value & SSP_BSY) == 0) - return ERROR_OK; - else if (retval != ERROR_OK) - return retval; - - endtime = timeval_ms() + timeout; - do { - alive_sleep(1); - retval = ssp_read_reg(target, ssp_base, SSP_SR, &value); - if ((retval == ERROR_OK) && (value & SSP_BSY) == 0) - return ERROR_OK; - else if (retval != ERROR_OK) - return retval; - } while (timeval_ms() < endtime); - - LOG_ERROR("Timeout while polling BSY"); - return ERROR_FLASH_OPERATION_FAILED; -} - -/* Un-initialize the ssp module and initialize the SPIFI module */ -static int lpcspifi_set_hw_mode(struct flash_bank *bank) -{ - struct target *target = bank->target; - struct lpcspifi_flash_bank *lpcspifi_info = bank->driver_priv; - uint32_t ssp_base = lpcspifi_info->ssp_base; - struct armv7m_algorithm armv7m_info; - struct working_area *spifi_init_algorithm; - struct reg_param reg_params[2]; - int retval = ERROR_OK; - - LOG_DEBUG("Uninitializing LPC43xx SSP"); - /* Turn off the SSP module */ - retval = ssp_write_reg(target, ssp_base, SSP_CR1, 0x00000000); - if (retval != ERROR_OK) - return retval; - - /* see contrib/loaders/flash/lpcspifi_init.S for src */ - static const uint8_t spifi_init_code[] = { - 0x4f, 0xea, 0x00, 0x08, 0xa1, 0xb0, 0x00, 0xaf, - 0x4f, 0xf4, 0xc0, 0x43, 0xc4, 0xf2, 0x08, 0x03, - 0x4f, 0xf0, 0xf3, 0x02, 0xc3, 0xf8, 0x8c, 0x21, - 0x4f, 0xf4, 0xc0, 0x43, 0xc4, 0xf2, 0x08, 0x03, - 0x4f, 0xf4, 0xc0, 0x42, 0xc4, 0xf2, 0x08, 0x02, - 0x4f, 0xf4, 0xc0, 0x41, 0xc4, 0xf2, 0x08, 0x01, - 0x4f, 0xf4, 0xc0, 0x40, 0xc4, 0xf2, 0x08, 0x00, - 0x4f, 0xf0, 0xd3, 0x04, 0xc0, 0xf8, 0x9c, 0x41, - 0x20, 0x46, 0xc1, 0xf8, 0x98, 0x01, 0x01, 0x46, - 0xc2, 0xf8, 0x94, 0x11, 0xc3, 0xf8, 0x90, 0x11, - 0x4f, 0xf4, 0xc0, 0x43, 0xc4, 0xf2, 0x08, 0x03, - 0x4f, 0xf0, 0x13, 0x02, 0xc3, 0xf8, 0xa0, 0x21, - 0x40, 0xf2, 0x18, 0x13, 0xc1, 0xf2, 0x40, 0x03, - 0x1b, 0x68, 0x1c, 0x68, 0x40, 0xf2, 0xb4, 0x30, - 0xc1, 0xf2, 0x00, 0x00, 0x4f, 0xf0, 0x03, 0x01, - 0x4f, 0xf0, 0xc0, 0x02, 0x4f, 0xea, 0x08, 0x03, - 0xa0, 0x47, 0x00, 0xf0, 0x00, 0xb8, 0x00, 0xbe - }; - - armv7m_info.common_magic = ARMV7M_COMMON_MAGIC; - armv7m_info.core_mode = ARM_MODE_THREAD; - - - LOG_DEBUG("Allocating working area for SPIFI init algorithm"); - /* Get memory for spifi initialization algorithm */ - retval = target_alloc_working_area(target, sizeof(spifi_init_code) - + SPIFI_INIT_STACK_SIZE, &spifi_init_algorithm); - if (retval != ERROR_OK) { - LOG_ERROR("Insufficient working area to initialize SPIFI "\ - "module. You must allocate at least %zdB of working "\ - "area in order to use this driver.", - sizeof(spifi_init_code) + SPIFI_INIT_STACK_SIZE - ); - - return retval; - } - - LOG_DEBUG("Writing algorithm to working area at 0x%08" PRIx32, - spifi_init_algorithm->address); - /* Write algorithm to working area */ - retval = target_write_buffer(target, - spifi_init_algorithm->address, - sizeof(spifi_init_code), - spifi_init_code - ); - - if (retval != ERROR_OK) { - target_free_working_area(target, spifi_init_algorithm); - return retval; - } - - init_reg_param(®_params[0], "r0", 32, PARAM_OUT); /* spifi clk speed */ - /* the spifi_init() rom API makes use of the stack */ - init_reg_param(®_params[1], "sp", 32, PARAM_OUT); - - /* For now, the algorithm will set up the SPIFI module - * @ the IRC clock speed. In the future, it could be made - * a bit smarter to use other clock sources if the user has - * already configured them in order to speed up memory- - * mapped reads. */ - buf_set_u32(reg_params[0].value, 0, 32, 12); - /* valid stack pointer */ - buf_set_u32(reg_params[1].value, 0, 32, (spifi_init_algorithm->address + - sizeof(spifi_init_code) + SPIFI_INIT_STACK_SIZE) & ~7UL); - - /* Run the algorithm */ - LOG_DEBUG("Running SPIFI init algorithm"); - retval = target_run_algorithm(target, 0 , NULL, 2, reg_params, - spifi_init_algorithm->address, - spifi_init_algorithm->address + sizeof(spifi_init_code) - 2, - 1000, &armv7m_info); - - if (retval != ERROR_OK) - LOG_ERROR("Error executing SPIFI init algorithm"); - - target_free_working_area(target, spifi_init_algorithm); - - destroy_reg_param(®_params[0]); - destroy_reg_param(®_params[1]); - - return retval; -} - -/* Initialize the ssp module */ -static int lpcspifi_set_sw_mode(struct flash_bank *bank) -{ - struct target *target = bank->target; - struct lpcspifi_flash_bank *lpcspifi_info = bank->driver_priv; - uint32_t ssp_base = lpcspifi_info->ssp_base; - uint32_t io_base = lpcspifi_info->io_base; - uint32_t ioconfig_base = lpcspifi_info->ioconfig_base; - int retval = ERROR_OK; - - /* Re-initialize SPIFI. There are a couple of errata on this, so this makes - sure that nothing's in an unhappy state. */ - retval = lpcspifi_set_hw_mode(bank); - - /* If we couldn't initialize hardware mode, don't even bother continuing */ - if (retval != ERROR_OK) - return retval; - - /* Initialize the pins */ - retval = ioconfig_write_reg(target, ioconfig_base, 0x194, 0x00000040); - if (retval == ERROR_OK) - retval = ioconfig_write_reg(target, ioconfig_base, 0x1a0, 0x00000044); - if (retval == ERROR_OK) - retval = ioconfig_write_reg(target, ioconfig_base, 0x190, 0x00000040); - if (retval == ERROR_OK) - retval = ioconfig_write_reg(target, ioconfig_base, 0x19c, 0x000000ed); - if (retval == ERROR_OK) - retval = ioconfig_write_reg(target, ioconfig_base, 0x198, 0x000000ed); - if (retval == ERROR_OK) - retval = ioconfig_write_reg(target, ioconfig_base, 0x18c, 0x000000ea); - - /* Set CS high & as an output */ - if (retval == ERROR_OK) - retval = io_write_reg(target, io_base, 0x12ac, 0xffffffff); - if (retval == ERROR_OK) - retval = io_write_reg(target, io_base, 0x2014, 0x00000800); - - /* Initialize the module */ - if (retval == ERROR_OK) - retval = ssp_write_reg(target, ssp_base, SSP_CR0, 0x00000007); - if (retval == ERROR_OK) - retval = ssp_write_reg(target, ssp_base, SSP_CR1, 0x00000000); - if (retval == ERROR_OK) - retval = ssp_write_reg(target, ssp_base, SSP_CPSR, 0x00000008); - if (retval == ERROR_OK) - retval = ssp_write_reg(target, ssp_base, SSP_CR1, 0x00000002); - - /* If something didn't work out, attempt to return SPIFI to HW mode */ - if (retval != ERROR_OK) - lpcspifi_set_hw_mode(bank); - - return retval; -} - -/* Read the status register of the external SPI flash chip. */ -static int read_status_reg(struct flash_bank *bank, uint32_t *status) -{ - struct target *target = bank->target; - struct lpcspifi_flash_bank *lpcspifi_info = bank->driver_priv; - uint32_t ssp_base = lpcspifi_info->ssp_base; - uint32_t io_base = lpcspifi_info->io_base; - uint32_t value; - int retval = ERROR_OK; - - retval = ssp_setcs(target, io_base, 0); - if (retval == ERROR_OK) - retval = ssp_write_reg(target, ssp_base, SSP_DATA, SPIFLASH_READ_STATUS); - if (retval == ERROR_OK) - retval = poll_ssp_busy(target, ssp_base, SSP_CMD_TIMEOUT); - if (retval == ERROR_OK) - retval = ssp_read_reg(target, ssp_base, SSP_DATA, &value); - /* Dummy write to clock in the register */ - if (retval == ERROR_OK) - retval = ssp_write_reg(target, ssp_base, SSP_DATA, 0x00); - if (retval == ERROR_OK) - retval = poll_ssp_busy(target, ssp_base, SSP_CMD_TIMEOUT); - if (retval == ERROR_OK) - retval = ssp_setcs(target, io_base, 1); - - if (retval == ERROR_OK) - retval = ssp_read_reg(target, ssp_base, SSP_DATA, &value); - if (retval == ERROR_OK) - *status = value; - - return retval; -} - -/* check for BSY bit in flash status register */ -/* timeout in ms */ -static int wait_till_ready(struct flash_bank *bank, int timeout) -{ - uint32_t status; - int retval; - int64_t endtime; - - endtime = timeval_ms() + timeout; - do { - /* read flash status register */ - retval = read_status_reg(bank, &status); - if (retval != ERROR_OK) - return retval; - - if ((status & SPIFLASH_BSY_BIT) == 0) - return ERROR_OK; - alive_sleep(1); - } while (timeval_ms() < endtime); - - LOG_ERROR("timeout waiting for flash to finish write/erase operation"); - return ERROR_FAIL; -} - -/* Send "write enable" command to SPI flash chip. */ -static int lpcspifi_write_enable(struct flash_bank *bank) -{ - struct target *target = bank->target; - struct lpcspifi_flash_bank *lpcspifi_info = bank->driver_priv; - uint32_t ssp_base = lpcspifi_info->ssp_base; - uint32_t io_base = lpcspifi_info->io_base; - uint32_t status, value; - int retval = ERROR_OK; - - retval = ssp_setcs(target, io_base, 0); - if (retval == ERROR_OK) - retval = ssp_write_reg(target, ssp_base, SSP_DATA, SPIFLASH_WRITE_ENABLE); - if (retval == ERROR_OK) - retval = poll_ssp_busy(target, ssp_base, SSP_CMD_TIMEOUT); - if (retval == ERROR_OK) - retval = ssp_read_reg(target, ssp_base, SSP_DATA, &value); - if (retval == ERROR_OK) - retval = ssp_setcs(target, io_base, 1); - - /* read flash status register */ - if (retval == ERROR_OK) - retval = read_status_reg(bank, &status); - if (retval != ERROR_OK) - return retval; - - /* Check write enabled */ - if ((status & SPIFLASH_WE_BIT) == 0) { - LOG_ERROR("Cannot enable write to flash. Status=0x%08" PRIx32, status); - return ERROR_FAIL; - } - - return retval; -} - -static int lpcspifi_bulk_erase(struct flash_bank *bank) -{ - struct target *target = bank->target; - struct lpcspifi_flash_bank *lpcspifi_info = bank->driver_priv; - uint32_t ssp_base = lpcspifi_info->ssp_base; - uint32_t io_base = lpcspifi_info->io_base; - uint32_t value; - int retval = ERROR_OK; - - retval = lpcspifi_set_sw_mode(bank); - - if (retval == ERROR_OK) - retval = lpcspifi_write_enable(bank); - - /* send SPI command "bulk erase" */ - if (retval == ERROR_OK) - ssp_setcs(target, io_base, 0); - if (retval == ERROR_OK) - retval = ssp_write_reg(target, ssp_base, SSP_DATA, lpcspifi_info->dev->chip_erase_cmd); - if (retval == ERROR_OK) - retval = poll_ssp_busy(target, ssp_base, SSP_CMD_TIMEOUT); - if (retval == ERROR_OK) - retval = ssp_read_reg(target, ssp_base, SSP_DATA, &value); - if (retval == ERROR_OK) - retval = ssp_setcs(target, io_base, 1); - - /* poll flash BSY for self-timed bulk erase */ - if (retval == ERROR_OK) - retval = wait_till_ready(bank, bank->num_sectors*SSP_MAX_TIMEOUT); - - return retval; -} - -static int lpcspifi_erase(struct flash_bank *bank, int first, int last) -{ - struct target *target = bank->target; - struct lpcspifi_flash_bank *lpcspifi_info = bank->driver_priv; - struct reg_param reg_params[4]; - struct armv7m_algorithm armv7m_info; - struct working_area *erase_algorithm; - int retval = ERROR_OK; - int sector; - - LOG_DEBUG("erase from sector %d to sector %d", first, last); - - if (target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - if ((first < 0) || (last < first) || (last >= bank->num_sectors)) { - LOG_ERROR("Flash sector invalid"); - return ERROR_FLASH_SECTOR_INVALID; - } - - if (!(lpcspifi_info->probed)) { - LOG_ERROR("Flash bank not probed"); - return ERROR_FLASH_BANK_NOT_PROBED; - } - - for (sector = first; sector <= last; sector++) { - if (bank->sectors[sector].is_protected) { - LOG_ERROR("Flash sector %d protected", sector); - return ERROR_FAIL; - } - } - - /* If we're erasing the entire chip and the flash supports - * it, use a bulk erase instead of going sector-by-sector. */ - if (first == 0 && last == (bank->num_sectors - 1) - && lpcspifi_info->dev->chip_erase_cmd != lpcspifi_info->dev->erase_cmd) { - LOG_DEBUG("Chip supports the bulk erase command."\ - " Will use bulk erase instead of sector-by-sector erase."); - retval = lpcspifi_bulk_erase(bank); - - if (retval == ERROR_OK) { - retval = lpcspifi_set_hw_mode(bank); - return retval; - } else - LOG_WARNING("Bulk flash erase failed. Falling back to sector-by-sector erase."); - } - - retval = lpcspifi_set_hw_mode(bank); - if (retval != ERROR_OK) - return retval; - - /* see contrib/loaders/flash/lpcspifi_erase.S for src */ - static const uint8_t lpcspifi_flash_erase_code[] = { - 0x4f, 0xf4, 0xc0, 0x4a, 0xc4, 0xf2, 0x08, 0x0a, - 0x4f, 0xf0, 0xea, 0x08, 0xca, 0xf8, 0x8c, 0x81, - 0x4f, 0xf0, 0x40, 0x08, 0xca, 0xf8, 0x90, 0x81, - 0x4f, 0xf0, 0x40, 0x08, 0xca, 0xf8, 0x94, 0x81, - 0x4f, 0xf0, 0xed, 0x08, 0xca, 0xf8, 0x98, 0x81, - 0x4f, 0xf0, 0xed, 0x08, 0xca, 0xf8, 0x9c, 0x81, - 0x4f, 0xf0, 0x44, 0x08, 0xca, 0xf8, 0xa0, 0x81, - 0x4f, 0xf4, 0xc0, 0x4a, 0xc4, 0xf2, 0x0f, 0x0a, - 0x4f, 0xf4, 0x00, 0x68, 0xca, 0xf8, 0x14, 0x80, - 0x4f, 0xf4, 0x80, 0x4a, 0xc4, 0xf2, 0x0f, 0x0a, - 0x4f, 0xf0, 0xff, 0x08, 0xca, 0xf8, 0xab, 0x80, - 0x4f, 0xf0, 0x00, 0x0a, 0xc4, 0xf2, 0x05, 0x0a, - 0x4f, 0xf0, 0x00, 0x08, 0xc0, 0xf2, 0x00, 0x18, - 0xca, 0xf8, 0x94, 0x80, 0x4f, 0xf4, 0x00, 0x5a, - 0xc4, 0xf2, 0x05, 0x0a, 0x4f, 0xf0, 0x01, 0x08, - 0xca, 0xf8, 0x00, 0x87, 0x4f, 0xf4, 0x40, 0x5a, - 0xc4, 0xf2, 0x08, 0x0a, 0x4f, 0xf0, 0x07, 0x08, - 0xca, 0xf8, 0x00, 0x80, 0x4f, 0xf0, 0x02, 0x08, - 0xca, 0xf8, 0x10, 0x80, 0xca, 0xf8, 0x04, 0x80, - 0x00, 0xf0, 0x52, 0xf8, 0x4f, 0xf0, 0x06, 0x09, - 0x00, 0xf0, 0x3b, 0xf8, 0x00, 0xf0, 0x48, 0xf8, - 0x00, 0xf0, 0x4a, 0xf8, 0x4f, 0xf0, 0x05, 0x09, - 0x00, 0xf0, 0x33, 0xf8, 0x4f, 0xf0, 0x00, 0x09, - 0x00, 0xf0, 0x2f, 0xf8, 0x00, 0xf0, 0x3c, 0xf8, - 0x19, 0xf0, 0x02, 0x0f, 0x00, 0xf0, 0x45, 0x80, - 0x00, 0xf0, 0x3a, 0xf8, 0x4f, 0xea, 0x02, 0x09, - 0x00, 0xf0, 0x23, 0xf8, 0x4f, 0xea, 0x10, 0x49, - 0x00, 0xf0, 0x1f, 0xf8, 0x4f, 0xea, 0x10, 0x29, - 0x00, 0xf0, 0x1b, 0xf8, 0x4f, 0xea, 0x00, 0x09, - 0x00, 0xf0, 0x17, 0xf8, 0x00, 0xf0, 0x24, 0xf8, - 0x00, 0xf0, 0x26, 0xf8, 0x4f, 0xf0, 0x05, 0x09, - 0x00, 0xf0, 0x0f, 0xf8, 0x4f, 0xf0, 0x00, 0x09, - 0x00, 0xf0, 0x0b, 0xf8, 0x00, 0xf0, 0x18, 0xf8, - 0x19, 0xf0, 0x01, 0x0f, 0x7f, 0xf4, 0xf0, 0xaf, - 0x01, 0x39, 0xf9, 0xb1, 0x18, 0x44, 0xff, 0xf7, - 0xbf, 0xbf, 0x4f, 0xf4, 0x40, 0x5a, 0xc4, 0xf2, - 0x08, 0x0a, 0xca, 0xf8, 0x08, 0x90, 0xda, 0xf8, - 0x0c, 0x90, 0x19, 0xf0, 0x10, 0x0f, 0x7f, 0xf4, - 0xfa, 0xaf, 0xda, 0xf8, 0x08, 0x90, 0x70, 0x47, - 0x4f, 0xf0, 0xff, 0x08, 0x00, 0xf0, 0x02, 0xb8, - 0x4f, 0xf0, 0x00, 0x08, 0x4f, 0xf4, 0x80, 0x4a, - 0xc4, 0xf2, 0x0f, 0x0a, 0xca, 0xf8, 0xab, 0x80, - 0x70, 0x47, 0x00, 0x20, 0x00, 0xbe, 0xff, 0xff - }; - - armv7m_info.common_magic = ARMV7M_COMMON_MAGIC; - armv7m_info.core_mode = ARM_MODE_THREAD; - - - /* Get memory for spifi initialization algorithm */ - retval = target_alloc_working_area(target, sizeof(lpcspifi_flash_erase_code), - &erase_algorithm); - if (retval != ERROR_OK) { - LOG_ERROR("Insufficient working area. You must configure a working"\ - " area of at least %zdB in order to erase SPIFI flash.", - sizeof(lpcspifi_flash_erase_code)); - return retval; - } - - /* Write algorithm to working area */ - retval = target_write_buffer(target, erase_algorithm->address, - sizeof(lpcspifi_flash_erase_code), lpcspifi_flash_erase_code); - if (retval != ERROR_OK) { - target_free_working_area(target, erase_algorithm); - return retval; - } - - init_reg_param(®_params[0], "r0", 32, PARAM_IN_OUT); /* Start address */ - init_reg_param(®_params[1], "r1", 32, PARAM_OUT); /* Sector count */ - init_reg_param(®_params[2], "r2", 32, PARAM_OUT); /* Erase command */ - init_reg_param(®_params[3], "r3", 32, PARAM_OUT); /* Sector size */ - - buf_set_u32(reg_params[0].value, 0, 32, bank->sectors[first].offset); - buf_set_u32(reg_params[1].value, 0, 32, last - first + 1); - buf_set_u32(reg_params[2].value, 0, 32, lpcspifi_info->dev->erase_cmd); - buf_set_u32(reg_params[3].value, 0, 32, bank->sectors[first].size); - - /* Run the algorithm */ - retval = target_run_algorithm(target, 0 , NULL, 4, reg_params, - erase_algorithm->address, - erase_algorithm->address + sizeof(lpcspifi_flash_erase_code) - 4, - 3000*(last - first + 1), &armv7m_info); - - if (retval != ERROR_OK) - LOG_ERROR("Error executing flash erase algorithm"); - - target_free_working_area(target, erase_algorithm); - - destroy_reg_param(®_params[0]); - destroy_reg_param(®_params[1]); - destroy_reg_param(®_params[2]); - destroy_reg_param(®_params[3]); - - retval = lpcspifi_set_hw_mode(bank); - - return retval; -} - -static int lpcspifi_protect(struct flash_bank *bank, int set, - int first, int last) -{ - int sector; - - for (sector = first; sector <= last; sector++) - bank->sectors[sector].is_protected = set; - return ERROR_OK; -} - -static int lpcspifi_write(struct flash_bank *bank, const uint8_t *buffer, - uint32_t offset, uint32_t count) -{ - struct target *target = bank->target; - struct lpcspifi_flash_bank *lpcspifi_info = bank->driver_priv; - uint32_t page_size, fifo_size; - struct working_area *fifo; - struct reg_param reg_params[5]; - struct armv7m_algorithm armv7m_info; - struct working_area *write_algorithm; - int sector; - int retval = ERROR_OK; - - LOG_DEBUG("offset=0x%08" PRIx32 " count=0x%08" PRIx32, - offset, count); - - if (target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - if (offset + count > lpcspifi_info->dev->size_in_bytes) { - LOG_WARNING("Writes past end of flash. Extra data discarded."); - count = lpcspifi_info->dev->size_in_bytes - offset; - } - - /* Check sector protection */ - for (sector = 0; sector < bank->num_sectors; sector++) { - /* Start offset in or before this sector? */ - /* End offset in or behind this sector? */ - if ((offset < - (bank->sectors[sector].offset + bank->sectors[sector].size)) - && ((offset + count - 1) >= bank->sectors[sector].offset) - && bank->sectors[sector].is_protected) { - LOG_ERROR("Flash sector %d protected", sector); - return ERROR_FAIL; - } - } - - page_size = lpcspifi_info->dev->pagesize; - - retval = lpcspifi_set_hw_mode(bank); - if (retval != ERROR_OK) - return retval; - - /* see contrib/loaders/flash/lpcspifi_write.S for src */ - static const uint8_t lpcspifi_flash_write_code[] = { - 0x4f, 0xf4, 0xc0, 0x4a, 0xc4, 0xf2, 0x08, 0x0a, - 0x4f, 0xf0, 0xea, 0x08, 0xca, 0xf8, 0x8c, 0x81, - 0x4f, 0xf0, 0x40, 0x08, 0xca, 0xf8, 0x90, 0x81, - 0x4f, 0xf0, 0x40, 0x08, 0xca, 0xf8, 0x94, 0x81, - 0x4f, 0xf0, 0xed, 0x08, 0xca, 0xf8, 0x98, 0x81, - 0x4f, 0xf0, 0xed, 0x08, 0xca, 0xf8, 0x9c, 0x81, - 0x4f, 0xf0, 0x44, 0x08, 0xca, 0xf8, 0xa0, 0x81, - 0x4f, 0xf4, 0xc0, 0x4a, 0xc4, 0xf2, 0x0f, 0x0a, - 0x4f, 0xf4, 0x00, 0x68, 0xca, 0xf8, 0x14, 0x80, - 0x4f, 0xf4, 0x80, 0x4a, 0xc4, 0xf2, 0x0f, 0x0a, - 0x4f, 0xf0, 0xff, 0x08, 0xca, 0xf8, 0xab, 0x80, - 0x4f, 0xf0, 0x00, 0x0a, 0xc4, 0xf2, 0x05, 0x0a, - 0x4f, 0xf0, 0x00, 0x08, 0xc0, 0xf2, 0x00, 0x18, - 0xca, 0xf8, 0x94, 0x80, 0x4f, 0xf4, 0x00, 0x5a, - 0xc4, 0xf2, 0x05, 0x0a, 0x4f, 0xf0, 0x01, 0x08, - 0xca, 0xf8, 0x00, 0x87, 0x4f, 0xf4, 0x40, 0x5a, - 0xc4, 0xf2, 0x08, 0x0a, 0x4f, 0xf0, 0x07, 0x08, - 0xca, 0xf8, 0x00, 0x80, 0x4f, 0xf0, 0x02, 0x08, - 0xca, 0xf8, 0x10, 0x80, 0xca, 0xf8, 0x04, 0x80, - 0x4f, 0xf0, 0x00, 0x0b, 0xa3, 0x44, 0x93, 0x45, - 0x7f, 0xf6, 0xfc, 0xaf, 0x00, 0xf0, 0x6a, 0xf8, - 0x4f, 0xf0, 0x06, 0x09, 0x00, 0xf0, 0x53, 0xf8, - 0x00, 0xf0, 0x60, 0xf8, 0x00, 0xf0, 0x62, 0xf8, - 0x4f, 0xf0, 0x05, 0x09, 0x00, 0xf0, 0x4b, 0xf8, - 0x4f, 0xf0, 0x00, 0x09, 0x00, 0xf0, 0x47, 0xf8, - 0x00, 0xf0, 0x54, 0xf8, 0x19, 0xf0, 0x02, 0x0f, - 0x00, 0xf0, 0x5d, 0x80, 0x00, 0xf0, 0x52, 0xf8, - 0x4f, 0xf0, 0x02, 0x09, 0x00, 0xf0, 0x3b, 0xf8, - 0x4f, 0xea, 0x12, 0x49, 0x00, 0xf0, 0x37, 0xf8, - 0x4f, 0xea, 0x12, 0x29, 0x00, 0xf0, 0x33, 0xf8, - 0x4f, 0xea, 0x02, 0x09, 0x00, 0xf0, 0x2f, 0xf8, - 0xd0, 0xf8, 0x00, 0x80, 0xb8, 0xf1, 0x00, 0x0f, - 0x00, 0xf0, 0x47, 0x80, 0x47, 0x68, 0x47, 0x45, - 0x3f, 0xf4, 0xf6, 0xaf, 0x17, 0xf8, 0x01, 0x9b, - 0x00, 0xf0, 0x21, 0xf8, 0x8f, 0x42, 0x28, 0xbf, - 0x00, 0xf1, 0x08, 0x07, 0x47, 0x60, 0x01, 0x3b, - 0xbb, 0xb3, 0x02, 0xf1, 0x01, 0x02, 0x93, 0x45, - 0x7f, 0xf4, 0xe6, 0xaf, 0x00, 0xf0, 0x22, 0xf8, - 0xa3, 0x44, 0x00, 0xf0, 0x23, 0xf8, 0x4f, 0xf0, - 0x05, 0x09, 0x00, 0xf0, 0x0c, 0xf8, 0x4f, 0xf0, - 0x00, 0x09, 0x00, 0xf0, 0x08, 0xf8, 0x00, 0xf0, - 0x15, 0xf8, 0x19, 0xf0, 0x01, 0x0f, 0x7f, 0xf4, - 0xf0, 0xaf, 0xff, 0xf7, 0xa7, 0xbf, 0x4f, 0xf4, - 0x40, 0x5a, 0xc4, 0xf2, 0x08, 0x0a, 0xca, 0xf8, - 0x08, 0x90, 0xda, 0xf8, 0x0c, 0x90, 0x19, 0xf0, - 0x10, 0x0f, 0x7f, 0xf4, 0xfa, 0xaf, 0xda, 0xf8, - 0x08, 0x90, 0x70, 0x47, 0x4f, 0xf0, 0xff, 0x08, - 0x00, 0xf0, 0x02, 0xb8, 0x4f, 0xf0, 0x00, 0x08, - 0x4f, 0xf4, 0x80, 0x4a, 0xc4, 0xf2, 0x0f, 0x0a, - 0xca, 0xf8, 0xab, 0x80, 0x70, 0x47, 0x00, 0x20, - 0x50, 0x60, 0xff, 0xf7, 0xef, 0xff, 0x30, 0x46, - 0x00, 0xbe, 0xff, 0xff - }; - - if (target_alloc_working_area(target, sizeof(lpcspifi_flash_write_code), - &write_algorithm) != ERROR_OK) { - LOG_ERROR("Insufficient working area. You must configure"\ - " 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), - lpcspifi_flash_write_code); - if (retval != ERROR_OK) { - target_free_working_area(target, write_algorithm); - return retval; - } - - /* FIFO allocation */ - fifo_size = target_get_working_area_avail(target); - - if (fifo_size == 0) { - /* if we already allocated the writing code but failed to get fifo - * space, free the algorithm */ - target_free_working_area(target, write_algorithm); - - LOG_ERROR("Insufficient working area. Please allocate at least"\ - " %zdB of working area to enable flash writes.", - sizeof(lpcspifi_flash_write_code) + 1 - ); - - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - } else if (fifo_size < page_size) - LOG_WARNING("Working area size is limited; flash writes may be"\ - " slow. Increase working area size to at least %zdB"\ - " to reduce write times.", - (size_t)(sizeof(lpcspifi_flash_write_code) + page_size) - ); - else if (fifo_size > 0x2000) /* Beyond this point, we start to get diminishing returns */ - fifo_size = 0x2000; - - 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; - - init_reg_param(®_params[0], "r0", 32, PARAM_IN_OUT); /* buffer start, status (out) */ - init_reg_param(®_params[1], "r1", 32, PARAM_OUT); /* buffer end */ - init_reg_param(®_params[2], "r2", 32, PARAM_OUT); /* target address */ - init_reg_param(®_params[3], "r3", 32, PARAM_OUT); /* count (halfword-16bit) */ - init_reg_param(®_params[4], "r4", 32, PARAM_OUT); /* page size */ - - buf_set_u32(reg_params[0].value, 0, 32, fifo->address); - buf_set_u32(reg_params[1].value, 0, 32, fifo->address + fifo->size); - buf_set_u32(reg_params[2].value, 0, 32, offset); - buf_set_u32(reg_params[3].value, 0, 32, count); - buf_set_u32(reg_params[4].value, 0, 32, page_size); - - retval = target_run_flash_async_algorithm(target, buffer, count, 1, - 0, NULL, - 5, reg_params, - fifo->address, fifo->size, - write_algorithm->address, 0, - &armv7m_info - ); - - if (retval != ERROR_OK) - LOG_ERROR("Error executing flash write algorithm"); - - target_free_working_area(target, fifo); - target_free_working_area(target, write_algorithm); - - 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]); - - /* Switch to HW mode before return to prompt */ - retval = lpcspifi_set_hw_mode(bank); - return retval; -} - -/* Return ID of flash device */ -/* On exit, SW mode is kept */ -static int lpcspifi_read_flash_id(struct flash_bank *bank, uint32_t *id) -{ - struct target *target = bank->target; - struct lpcspifi_flash_bank *lpcspifi_info = bank->driver_priv; - uint32_t ssp_base = lpcspifi_info->ssp_base; - uint32_t io_base = lpcspifi_info->io_base; - uint32_t value; - uint8_t id_buf[3] = {0, 0, 0}; - int retval; - - if (target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - LOG_DEBUG("Getting ID"); - retval = lpcspifi_set_sw_mode(bank); - if (retval != ERROR_OK) - return retval; - - /* poll WIP */ - if (retval == ERROR_OK) - retval = wait_till_ready(bank, SSP_PROBE_TIMEOUT); - - /* Send SPI command "read ID" */ - if (retval == ERROR_OK) - retval = ssp_setcs(target, io_base, 0); - if (retval == ERROR_OK) - retval = ssp_write_reg(target, ssp_base, SSP_DATA, SPIFLASH_READ_ID); - if (retval == ERROR_OK) - retval = poll_ssp_busy(target, ssp_base, SSP_CMD_TIMEOUT); - if (retval == ERROR_OK) - retval = ssp_read_reg(target, ssp_base, SSP_DATA, &value); - - /* Dummy write to clock in data */ - if (retval == ERROR_OK) - retval = ssp_write_reg(target, ssp_base, SSP_DATA, 0x00); - if (retval == ERROR_OK) - retval = poll_ssp_busy(target, ssp_base, SSP_CMD_TIMEOUT); - if (retval == ERROR_OK) - retval = ssp_read_reg(target, ssp_base, SSP_DATA, &value); - if (retval == ERROR_OK) - id_buf[0] = value; - - /* Dummy write to clock in data */ - if (retval == ERROR_OK) - retval = ssp_write_reg(target, ssp_base, SSP_DATA, 0x00); - if (retval == ERROR_OK) - retval = poll_ssp_busy(target, ssp_base, SSP_CMD_TIMEOUT); - if (retval == ERROR_OK) - retval = ssp_read_reg(target, ssp_base, SSP_DATA, &value); - if (retval == ERROR_OK) - id_buf[1] = value; - - /* Dummy write to clock in data */ - if (retval == ERROR_OK) - retval = ssp_write_reg(target, ssp_base, SSP_DATA, 0x00); - if (retval == ERROR_OK) - retval = poll_ssp_busy(target, ssp_base, SSP_CMD_TIMEOUT); - if (retval == ERROR_OK) - retval = ssp_read_reg(target, ssp_base, SSP_DATA, &value); - if (retval == ERROR_OK) - id_buf[2] = value; - - if (retval == ERROR_OK) - retval = ssp_setcs(target, io_base, 1); - if (retval == ERROR_OK) - *id = id_buf[2] << 16 | id_buf[1] << 8 | id_buf[0]; - - return retval; -} - -static int lpcspifi_probe(struct flash_bank *bank) -{ - struct lpcspifi_flash_bank *lpcspifi_info = bank->driver_priv; - struct flash_sector *sectors; - uint32_t id = 0; /* silence uninitialized warning */ - int retval; - - /* If we've already probed, we should be fine to skip this time. */ - if (lpcspifi_info->probed) - return ERROR_OK; - lpcspifi_info->probed = 0; - - lpcspifi_info->ssp_base = 0x40083000; - lpcspifi_info->io_base = 0x400F4000; - lpcspifi_info->ioconfig_base = 0x40086000; - lpcspifi_info->bank_num = bank->bank_number; - - /* read and decode flash ID; returns in SW mode */ - retval = lpcspifi_read_flash_id(bank, &id); - if (retval != ERROR_OK) - return retval; - - retval = lpcspifi_set_hw_mode(bank); - if (retval != ERROR_OK) - return retval; - - lpcspifi_info->dev = NULL; - for (const struct flash_device *p = flash_devices; p->name ; p++) - if (p->device_id == id) { - lpcspifi_info->dev = p; - break; - } - - if (!lpcspifi_info->dev) { - LOG_ERROR("Unknown flash device (ID 0x%08" PRIx32 ")", id); - return ERROR_FAIL; - } - - LOG_INFO("Found flash device \'%s\' (ID 0x%08" PRIx32 ")", - lpcspifi_info->dev->name, lpcspifi_info->dev->device_id); - - /* Set correct size value */ - bank->size = lpcspifi_info->dev->size_in_bytes; - - /* create and fill sectors array */ - bank->num_sectors = - lpcspifi_info->dev->size_in_bytes / lpcspifi_info->dev->sectorsize; - sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors); - if (sectors == NULL) { - LOG_ERROR("not enough memory"); - return ERROR_FAIL; - } - - for (int sector = 0; sector < bank->num_sectors; sector++) { - sectors[sector].offset = sector * lpcspifi_info->dev->sectorsize; - sectors[sector].size = lpcspifi_info->dev->sectorsize; - sectors[sector].is_erased = -1; - sectors[sector].is_protected = 0; - } - - bank->sectors = sectors; - - lpcspifi_info->probed = 1; - return ERROR_OK; -} - -static int lpcspifi_auto_probe(struct flash_bank *bank) -{ - struct lpcspifi_flash_bank *lpcspifi_info = bank->driver_priv; - if (lpcspifi_info->probed) - return ERROR_OK; - return lpcspifi_probe(bank); -} - -static int lpcspifi_protect_check(struct flash_bank *bank) -{ - /* Nothing to do. Protection is only handled in SW. */ - return ERROR_OK; -} - -static int get_lpcspifi_info(struct flash_bank *bank, char *buf, int buf_size) -{ - struct lpcspifi_flash_bank *lpcspifi_info = bank->driver_priv; - - if (!(lpcspifi_info->probed)) { - snprintf(buf, buf_size, - "\nSPIFI flash bank not probed yet\n"); - return ERROR_OK; - } - - snprintf(buf, buf_size, "\nSPIFI flash information:\n" - " Device \'%s\' (ID 0x%08" PRIx32 ")\n", - lpcspifi_info->dev->name, lpcspifi_info->dev->device_id); - - return ERROR_OK; -} - -struct flash_driver lpcspifi_flash = { - .name = "lpcspifi", - .flash_bank_command = lpcspifi_flash_bank_command, - .erase = lpcspifi_erase, - .protect = lpcspifi_protect, - .write = lpcspifi_write, - .read = default_flash_read, - .probe = lpcspifi_probe, - .auto_probe = lpcspifi_auto_probe, - .erase_check = default_flash_blank_check, - .protect_check = lpcspifi_protect_check, - .info = get_lpcspifi_info, -}; diff --git a/src/flash/nor/mdr.c b/src/flash/nor/mdr.c deleted file mode 100644 index 374cb6f29..000000000 --- a/src/flash/nor/mdr.c +++ /dev/null @@ -1,635 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * Copyright (C) 2008 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * Copyright (C) 2011 by Andreas Fritiofson * - * andreas.fritiofson@gmail.com * - * * - * Copyright (C) 2013 by Paul Fertser * - * fercerpav@gmail.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "imp.h" -#include -#include -#include - -#define MD_RST_CLK 0x40020000 -#define MD_PER_CLOCK (MD_RST_CLK + 0x1C) -#define MD_PER_CLOCK_EEPROM (1 << 3) -#define MD_PER_CLOCK_RST_CLK (1 << 4) - -#define FLASH_REG_BASE 0x40018000 -#define FLASH_CMD (FLASH_REG_BASE + 0x00) -#define FLASH_ADR (FLASH_REG_BASE + 0x04) -#define FLASH_DI (FLASH_REG_BASE + 0x08) -#define FLASH_DO (FLASH_REG_BASE + 0x0C) -#define FLASH_KEY (FLASH_REG_BASE + 0x10) - -#define FLASH_NVSTR (1 << 13) -#define FLASH_PROG (1 << 12) -#define FLASH_MAS1 (1 << 11) -#define FLASH_ERASE (1 << 10) -#define FLASH_IFREN (1 << 9) -#define FLASH_SE (1 << 8) -#define FLASH_YE (1 << 7) -#define FLASH_XE (1 << 6) -#define FLASH_RD (1 << 2) -#define FLASH_WR (1 << 1) -#define FLASH_CON (1 << 0) -#define FLASH_DELAY_MASK (7 << 3) - -#define KEY 0x8AAA5551 - -struct mdr_flash_bank { - int probed; - unsigned int mem_type; - unsigned int page_count; - unsigned int sec_count; -}; - -/* flash bank mdr 0 0 */ -FLASH_BANK_COMMAND_HANDLER(mdr_flash_bank_command) -{ - struct mdr_flash_bank *mdr_info; - - if (CMD_ARGC < 9) - return ERROR_COMMAND_SYNTAX_ERROR; - - mdr_info = malloc(sizeof(struct mdr_flash_bank)); - - bank->driver_priv = mdr_info; - mdr_info->probed = 0; - COMMAND_PARSE_NUMBER(uint, CMD_ARGV[6], mdr_info->mem_type); - COMMAND_PARSE_NUMBER(uint, CMD_ARGV[7], mdr_info->page_count); - COMMAND_PARSE_NUMBER(uint, CMD_ARGV[8], mdr_info->sec_count); - return ERROR_OK; -} - -static int mdr_protect_check(struct flash_bank *bank) -{ - return ERROR_OK; -} - -static int mdr_mass_erase(struct flash_bank *bank) -{ - struct target *target = bank->target; - struct mdr_flash_bank *mdr_info = bank->driver_priv; - uint32_t flash_cmd; - int retval; - unsigned int i; - - retval = target_read_u32(target, FLASH_CMD, &flash_cmd); - if (retval != ERROR_OK) - return retval; - - for (i = 0; i < mdr_info->sec_count; i++) { - retval = target_write_u32(target, FLASH_ADR, i << 2); - if (retval != ERROR_OK) - return retval; - - flash_cmd |= FLASH_XE | FLASH_MAS1 | FLASH_ERASE; - retval = target_write_u32(target, FLASH_CMD, flash_cmd); - if (retval != ERROR_OK) - return retval; - flash_cmd |= FLASH_NVSTR; - retval = target_write_u32(target, FLASH_CMD, flash_cmd); - if (retval != ERROR_OK) - return retval; - flash_cmd &= ~FLASH_ERASE; - retval = target_write_u32(target, FLASH_CMD, flash_cmd); - if (retval != ERROR_OK) - return retval; - flash_cmd &= ~(FLASH_XE | FLASH_MAS1 | FLASH_NVSTR); - retval = target_write_u32(target, FLASH_CMD, flash_cmd); - if (retval != ERROR_OK) - return retval; - } - - return retval; -} - -static int mdr_erase(struct flash_bank *bank, int first, int last) -{ - struct target *target = bank->target; - struct mdr_flash_bank *mdr_info = bank->driver_priv; - int i, retval, retval2; - unsigned int j; - uint32_t flash_cmd, cur_per_clock; - - if (bank->target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - retval = target_read_u32(target, MD_PER_CLOCK, &cur_per_clock); - if (retval != ERROR_OK) - return retval; - - if (!(cur_per_clock & 0x10)) { - LOG_ERROR("Target needs reset before flash operations"); - return ERROR_FLASH_OPERATION_FAILED; - } - - retval = target_write_u32(target, MD_PER_CLOCK, cur_per_clock | MD_PER_CLOCK_EEPROM); - if (retval != ERROR_OK) - return retval; - - retval = target_write_u32(target, FLASH_KEY, KEY); - if (retval != ERROR_OK) - return retval; - - retval = target_read_u32(target, FLASH_CMD, &flash_cmd); - if (retval != ERROR_OK) - goto reset_pg_and_lock; - - /* Switch on register access */ - flash_cmd = (flash_cmd & FLASH_DELAY_MASK) | FLASH_CON; - if (mdr_info->mem_type) - flash_cmd |= FLASH_IFREN; - retval = target_write_u32(target, FLASH_CMD, flash_cmd); - if (retval != ERROR_OK) - goto reset_pg_and_lock; - - if ((first == 0) && (last == (bank->num_sectors - 1))) { - retval = mdr_mass_erase(bank); - goto reset_pg_and_lock; - } - - unsigned int page_size = bank->size / mdr_info->page_count; - for (i = first; i <= last; i++) { - for (j = 0; j < mdr_info->sec_count; j++) { - retval = target_write_u32(target, FLASH_ADR, (i * page_size) | (j << 2)); - if (retval != ERROR_OK) - goto reset_pg_and_lock; - - flash_cmd |= FLASH_XE | FLASH_ERASE; - retval = target_write_u32(target, FLASH_CMD, flash_cmd); - if (retval != ERROR_OK) - goto reset_pg_and_lock; - flash_cmd |= FLASH_NVSTR; - retval = target_write_u32(target, FLASH_CMD, flash_cmd); - if (retval != ERROR_OK) - goto reset_pg_and_lock; - flash_cmd &= ~FLASH_ERASE; - retval = target_write_u32(target, FLASH_CMD, flash_cmd); - if (retval != ERROR_OK) - goto reset_pg_and_lock; - flash_cmd &= ~(FLASH_XE | FLASH_NVSTR); - retval = target_write_u32(target, FLASH_CMD, flash_cmd); - if (retval != ERROR_OK) - goto reset_pg_and_lock; - } - bank->sectors[i].is_erased = 1; - } - -reset_pg_and_lock: - flash_cmd &= FLASH_DELAY_MASK; - retval2 = target_write_u32(target, FLASH_CMD, flash_cmd); - if (retval == ERROR_OK) - retval = retval2; - - retval2 = target_write_u32(target, FLASH_KEY, 0); - if (retval == ERROR_OK) - retval = retval2; - - return retval; -} - -static int mdr_protect(struct flash_bank *bank, int set, int first, int last) -{ - return ERROR_OK; -} - -static int mdr_write_block(struct flash_bank *bank, const uint8_t *buffer, - uint32_t offset, uint32_t count) -{ - struct target *target = bank->target; - uint32_t buffer_size = 16384; - struct working_area *write_algorithm; - struct working_area *source; - uint32_t address = bank->base + offset; - struct reg_param reg_params[5]; - struct armv7m_algorithm armv7m_info; - int retval = ERROR_OK; - - /* see contrib/loaders/flash/mdr32fx.S for src */ - static const uint8_t mdr32fx_flash_write_code[] = { - 0x07, 0x68, 0x16, 0x68, 0x00, 0x2e, 0x2e, 0xd0, 0x55, 0x68, 0xb5, 0x42, - 0xf9, 0xd0, 0x2e, 0x68, 0x44, 0x60, 0x86, 0x60, 0x17, 0x4e, 0x37, 0x43, - 0x07, 0x60, 0x05, 0x26, 0x00, 0xf0, 0x25, 0xf8, 0x15, 0x4e, 0x37, 0x43, - 0x07, 0x60, 0x0d, 0x26, 0x00, 0xf0, 0x1f, 0xf8, 0x80, 0x26, 0x37, 0x43, - 0x07, 0x60, 0x3d, 0x26, 0x00, 0xf0, 0x19, 0xf8, 0x80, 0x26, 0xb7, 0x43, - 0x07, 0x60, 0x0f, 0x4e, 0xb7, 0x43, 0x07, 0x60, 0x05, 0x26, 0x00, 0xf0, - 0x10, 0xf8, 0x0d, 0x4e, 0xb7, 0x43, 0x07, 0x60, 0x04, 0x35, 0x04, 0x34, - 0x9d, 0x42, 0x01, 0xd3, 0x15, 0x46, 0x08, 0x35, 0x55, 0x60, 0x01, 0x39, - 0x00, 0x29, 0x00, 0xd0, 0xcd, 0xe7, 0x30, 0x46, 0x00, 0xbe, 0x01, 0x3e, - 0x00, 0x2e, 0xfc, 0xd1, 0x70, 0x47, 0x00, 0x00, 0x40, 0x10, 0x00, 0x00, - 0x00, 0x20, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x40, 0x20, 0x00, 0x00 - }; - - /* flash write code */ - if (target_alloc_working_area(target, sizeof(mdr32fx_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(mdr32fx_flash_write_code), mdr32fx_flash_write_code); - if (retval != ERROR_OK) - return retval; - - /* memory buffer */ - while (target_alloc_working_area_try(target, buffer_size, &source) != ERROR_OK) { - buffer_size /= 2; - buffer_size &= ~3UL; /* Make sure it's 4 byte aligned */ - if (buffer_size <= 256) { - /* we already allocated the writing code, but failed to get a - * buffer, free the algorithm */ - target_free_working_area(target, write_algorithm); - - 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) */ - init_reg_param(®_params[2], "r2", 32, PARAM_OUT); /* buffer start */ - init_reg_param(®_params[3], "r3", 32, PARAM_OUT); /* buffer end */ - init_reg_param(®_params[4], "r4", 32, PARAM_IN_OUT); /* target address */ - - buf_set_u32(reg_params[0].value, 0, 32, FLASH_REG_BASE); - buf_set_u32(reg_params[1].value, 0, 32, count); - 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, address); - - armv7m_info.common_magic = ARMV7M_COMMON_MAGIC; - armv7m_info.core_mode = ARM_MODE_THREAD; - - retval = target_run_flash_async_algorithm(target, buffer, count, 4, - 0, NULL, - 5, reg_params, - source->address, source->size, - write_algorithm->address, 0, - &armv7m_info); - - if (retval == ERROR_FLASH_OPERATION_FAILED) - LOG_ERROR("flash write failed at address 0x%"PRIx32, - buf_get_u32(reg_params[4].value, 0, 32)); - - target_free_working_area(target, source); - target_free_working_area(target, write_algorithm); - - 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 mdr_write(struct flash_bank *bank, const uint8_t *buffer, - uint32_t offset, uint32_t count) -{ - struct target *target = bank->target; - struct mdr_flash_bank *mdr_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); - return ERROR_FLASH_DST_BREAKS_ALIGNMENT; - } - - /* If there's an odd number of bytes, 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 % 4; - if (rem) { - new_buffer = malloc(count + rem); - if (new_buffer == NULL) { - LOG_ERROR("odd number of bytes to write and no memory for padding buffer"); - return ERROR_FAIL; - } - LOG_INFO("odd number of bytes to write, padding with 0xff"); - buffer = memcpy(new_buffer, buffer, count); - while (rem--) - new_buffer[count++] = 0xff; - } - - uint32_t flash_cmd, cur_per_clock; - int retval, retval2; - - retval = target_read_u32(target, MD_PER_CLOCK, &cur_per_clock); - if (retval != ERROR_OK) - goto free_buffer; - - 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 free_buffer; - } - - retval = target_write_u32(target, MD_PER_CLOCK, cur_per_clock | MD_PER_CLOCK_EEPROM); - if (retval != ERROR_OK) - goto free_buffer; - - retval = target_write_u32(target, FLASH_KEY, KEY); - if (retval != ERROR_OK) - goto free_buffer; - - retval = target_read_u32(target, FLASH_CMD, &flash_cmd); - if (retval != ERROR_OK) - goto reset_pg_and_lock; - - /* Switch on register access */ - flash_cmd = (flash_cmd & FLASH_DELAY_MASK) | FLASH_CON; - if (mdr_info->mem_type) - flash_cmd |= FLASH_IFREN; - retval = target_write_u32(target, FLASH_CMD, flash_cmd); - if (retval != ERROR_OK) - goto reset_pg_and_lock; - - /* try using block write */ - retval = mdr_write_block(bank, buffer, offset, count/4); - - if (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE) { - /* if block write failed (no sufficient working area), - * we use normal (slow) single halfword accesses */ - LOG_WARNING("Can't use block writes, falling back to single memory accesses"); - - unsigned int page_size = bank->size / mdr_info->page_count; - unsigned int page_mask = page_size - 1; - while (count > 0) { - unsigned int i, j; - unsigned int cur_page = offset & ~page_mask; - unsigned int bytes_to_write = cur_page + page_size - offset; - if (count < bytes_to_write) - bytes_to_write = count; - - /*LOG_INFO("Selecting next page: %08x", cur_page);*/ - - for (i = 0; i < mdr_info->sec_count; i++) { - retval = target_write_u32(target, FLASH_ADR, offset + i*4); - if (retval != ERROR_OK) - goto reset_pg_and_lock; - /*LOG_INFO("Selecting page/sector: %08x", offset + i*4);*/ - - flash_cmd |= FLASH_XE | FLASH_PROG; - retval = target_write_u32(target, FLASH_CMD, flash_cmd); - if (retval != ERROR_OK) - goto reset_pg_and_lock; - - flash_cmd |= FLASH_NVSTR; - retval = target_write_u32(target, FLASH_CMD, flash_cmd); - if (retval != ERROR_OK) - goto reset_pg_and_lock; - - for (j = 0; - (((offset + j + i*4) & ~page_mask) == cur_page) && - (j + i*4 < count); - j += mdr_info->sec_count*4) { - uint32_t value; - memcpy(&value, buffer + j + i*4, sizeof(uint32_t)); - retval = target_write_u32(target, FLASH_DI, value); - if (retval != ERROR_OK) - goto reset_pg_and_lock; - /*LOG_INFO("Writing to addr %08x", offset + j + i*4);*/ - retval = target_write_u32(target, FLASH_ADR, offset + j + i*4); - if (retval != ERROR_OK) - goto reset_pg_and_lock; - - flash_cmd |= FLASH_YE; - retval = target_write_u32(target, FLASH_CMD, flash_cmd); - if (retval != ERROR_OK) - goto reset_pg_and_lock; - flash_cmd &= ~FLASH_YE; - retval = target_write_u32(target, FLASH_CMD, flash_cmd); - if (retval != ERROR_OK) - goto reset_pg_and_lock; - } - flash_cmd &= ~FLASH_NVSTR; - retval = target_write_u32(target, FLASH_CMD, flash_cmd); - if (retval != ERROR_OK) - goto reset_pg_and_lock; - - flash_cmd &= ~(FLASH_XE | FLASH_PROG); - retval = target_write_u32(target, FLASH_CMD, flash_cmd); - if (retval != ERROR_OK) - goto reset_pg_and_lock; - } - - buffer += bytes_to_write; - offset += bytes_to_write; - count -= bytes_to_write; - } - } - -reset_pg_and_lock: - flash_cmd &= FLASH_DELAY_MASK; - retval2 = target_write_u32(target, FLASH_CMD, flash_cmd); - if (retval == ERROR_OK) - retval = retval2; - - retval2 = target_write_u32(target, FLASH_KEY, 0); - if (retval == ERROR_OK) - retval = retval2; - -free_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; -} - -static int mdr_probe(struct flash_bank *bank) -{ - struct mdr_flash_bank *mdr_info = bank->driver_priv; - unsigned int page_count, page_size, i; - - page_count = mdr_info->page_count; - page_size = bank->size / page_count; - - if (bank->sectors) { - free(bank->sectors); - bank->sectors = NULL; - } - - bank->num_sectors = page_count; - bank->sectors = malloc(sizeof(struct flash_sector) * page_count); - - for (i = 0; i < page_count; i++) { - bank->sectors[i].offset = i * page_size; - bank->sectors[i].size = page_size; - bank->sectors[i].is_erased = -1; - bank->sectors[i].is_protected = 0; - } - - mdr_info->probed = 1; - - return ERROR_OK; -} - -static int mdr_auto_probe(struct flash_bank *bank) -{ - struct mdr_flash_bank *mdr_info = bank->driver_priv; - if (mdr_info->probed) - return ERROR_OK; - return mdr_probe(bank); -} - -static int get_mdr_info(struct flash_bank *bank, char *buf, int buf_size) -{ - struct mdr_flash_bank *mdr_info = bank->driver_priv; - snprintf(buf, buf_size, "MDR32Fx - %s", - mdr_info->mem_type ? "info memory" : "main memory"); - - return ERROR_OK; -} - -struct flash_driver mdr_flash = { - .name = "mdr", - .usage = "flash bank mdr 0 0 \n" - ": 0 for main memory, 1 for info memory", - .flash_bank_command = mdr_flash_bank_command, - .erase = mdr_erase, - .protect = mdr_protect, - .write = mdr_write, - .read = mdr_read, - .probe = mdr_probe, - .auto_probe = mdr_auto_probe, - .erase_check = default_flash_blank_check, - .protect_check = mdr_protect_check, - .info = get_mdr_info, -}; diff --git a/src/flash/nor/mrvlqspi.c b/src/flash/nor/mrvlqspi.c deleted file mode 100644 index d79917058..000000000 --- a/src/flash/nor/mrvlqspi.c +++ /dev/null @@ -1,958 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2014 by Mahavir Jain * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - - /* - * This is QSPI flash controller driver for Marvell's Wireless - * Microcontroller platform. - * - * For more information please refer, - * https://origin-www.marvell.com/microcontrollers/wi-fi-microcontroller-platform/ - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "imp.h" -#include "spi.h" -#include -#include -#include - -#define QSPI_R_EN (0x0) -#define QSPI_W_EN (0x1) -#define QSPI_SS_DISABLE (0x0) -#define QSPI_SS_ENABLE (0x1) -#define WRITE_DISBALE (0x0) -#define WRITE_ENABLE (0x1) - -#define QSPI_TIMEOUT (1000) -#define FIFO_FLUSH_TIMEOUT (1000) -#define BLOCK_ERASE_TIMEOUT (1000) -#define CHIP_ERASE_TIMEOUT (10000) - -#define SS_EN (1 << 0) -#define XFER_RDY (1 << 1) -#define RFIFO_EMPTY (1 << 4) -#define WFIFO_EMPTY (1 << 6) -#define WFIFO_FULL (1 << 7) -#define FIFO_FLUSH (1 << 9) -#define RW_EN (1 << 13) -#define XFER_STOP (1 << 14) -#define XFER_START (1 << 15) -#define CONF_MASK (0x7) -#define CONF_OFFSET (10) - -#define INS_WRITE_ENABLE 0x06 -#define INS_WRITE_DISABLE 0x04 -#define INS_READ_STATUS 0x05 -#define INS_PAGE_PROGRAM 0x02 - -#define CNTL 0x0 /* QSPI_BASE + 0x0 */ -#define CONF 0x4 -#define DOUT 0x8 -#define DIN 0xc -#define INSTR 0x10 -#define ADDR 0x14 -#define RDMODE 0x18 -#define HDRCNT 0x1c -#define DINCNT 0x20 - -struct mrvlqspi_flash_bank { - int probed; - uint32_t reg_base; - uint32_t bank_num; - const struct flash_device *dev; -}; - -static inline uint32_t mrvlqspi_get_reg(struct flash_bank *bank, uint32_t reg) -{ - struct mrvlqspi_flash_bank *mrvlqspi_info = bank->driver_priv; - return reg + mrvlqspi_info->reg_base; -} - -static inline int mrvlqspi_set_din_cnt(struct flash_bank *bank, uint32_t count) -{ - struct target *target = bank->target; - - return target_write_u32(target, mrvlqspi_get_reg(bank, DINCNT), count); -} - -static inline int mrvlqspi_set_addr(struct flash_bank *bank, uint32_t addr) -{ - struct target *target = bank->target; - - return target_write_u32(target, mrvlqspi_get_reg(bank, ADDR), addr); -} - -static inline int mrvlqspi_set_instr(struct flash_bank *bank, uint32_t instr) -{ - struct target *target = bank->target; - - return target_write_u32(target, mrvlqspi_get_reg(bank, INSTR), instr); -} - -static inline int mrvlqspi_set_hdr_cnt(struct flash_bank *bank, uint32_t hdr_cnt) -{ - struct target *target = bank->target; - - return target_write_u32(target, mrvlqspi_get_reg(bank, HDRCNT), hdr_cnt); -} - -static int mrvlqspi_set_conf(struct flash_bank *bank, uint32_t conf_val) -{ - int retval; - uint32_t regval; - struct target *target = bank->target; - - retval = target_read_u32(target, - mrvlqspi_get_reg(bank, CONF), ®val); - if (retval != ERROR_OK) - return retval; - - regval &= ~(CONF_MASK << CONF_OFFSET); - regval |= (conf_val << CONF_OFFSET); - - return target_write_u32(target, - mrvlqspi_get_reg(bank, CONF), regval); -} - -static int mrvlqspi_set_ss_state(struct flash_bank *bank, bool state, int timeout) -{ - int retval; - uint32_t regval; - struct target *target = bank->target; - - retval = target_read_u32(target, - mrvlqspi_get_reg(bank, CNTL), ®val); - if (retval != ERROR_OK) - return retval; - - if (state) - regval |= SS_EN; - else - regval &= ~(SS_EN); - - retval = target_write_u32(target, - mrvlqspi_get_reg(bank, CNTL), regval); - if (retval != ERROR_OK) - return retval; - - /* wait for xfer_ready to set */ - for (;;) { - retval = target_read_u32(target, - mrvlqspi_get_reg(bank, CNTL), ®val); - if (retval != ERROR_OK) - return retval; - LOG_DEBUG("status: 0x%08" PRIx32, regval); - if ((regval & XFER_RDY) == XFER_RDY) - break; - if (timeout-- <= 0) { - LOG_ERROR("timed out waiting for flash"); - return ERROR_FAIL; - } - alive_sleep(1); - } - return ERROR_OK; -} - -static int mrvlqspi_start_transfer(struct flash_bank *bank, bool rw_mode) -{ - int retval; - uint32_t regval; - struct target *target = bank->target; - - retval = mrvlqspi_set_ss_state(bank, QSPI_SS_ENABLE, QSPI_TIMEOUT); - if (retval != ERROR_OK) - return retval; - - retval = target_read_u32(target, - mrvlqspi_get_reg(bank, CONF), ®val); - if (retval != ERROR_OK) - return retval; - - if (rw_mode) - regval |= RW_EN; - else - regval &= ~(RW_EN); - - regval |= XFER_START; - - retval = target_write_u32(target, - mrvlqspi_get_reg(bank, CONF), regval); - if (retval != ERROR_OK) - return retval; - - return ERROR_OK; -} - -static int mrvlqspi_stop_transfer(struct flash_bank *bank) -{ - int retval; - uint32_t regval; - struct target *target = bank->target; - int timeout = QSPI_TIMEOUT; - - /* wait for xfer_ready and wfifo_empty to set */ - for (;;) { - retval = target_read_u32(target, - mrvlqspi_get_reg(bank, CNTL), ®val); - if (retval != ERROR_OK) - return retval; - LOG_DEBUG("status: 0x%08" PRIx32, regval); - if ((regval & (XFER_RDY | WFIFO_EMPTY)) == - (XFER_RDY | WFIFO_EMPTY)) - break; - if (timeout-- <= 0) { - LOG_ERROR("timed out waiting for flash"); - return ERROR_FAIL; - } - alive_sleep(1); - } - - retval = target_read_u32(target, - mrvlqspi_get_reg(bank, CONF), ®val); - if (retval != ERROR_OK) - return retval; - - regval |= XFER_STOP; - - retval = target_write_u32(target, - mrvlqspi_get_reg(bank, CONF), regval); - if (retval != ERROR_OK) - return retval; - - /* wait for xfer_start to reset */ - for (;;) { - retval = target_read_u32(target, - mrvlqspi_get_reg(bank, CONF), ®val); - if (retval != ERROR_OK) - return retval; - LOG_DEBUG("status: 0x%08" PRIx32, regval); - if ((regval & XFER_START) == 0) - break; - if (timeout-- <= 0) { - LOG_ERROR("timed out waiting for flash"); - return ERROR_FAIL; - } - alive_sleep(1); - } - - retval = mrvlqspi_set_ss_state(bank, QSPI_SS_DISABLE, QSPI_TIMEOUT); - if (retval != ERROR_OK) - return retval; - - return ERROR_OK; -} - -static int mrvlqspi_fifo_flush(struct flash_bank *bank, int timeout) -{ - int retval; - uint32_t val; - struct target *target = bank->target; - - retval = target_read_u32(target, - mrvlqspi_get_reg(bank, CONF), &val); - if (retval != ERROR_OK) - return retval; - - val |= FIFO_FLUSH; - - retval = target_write_u32(target, - mrvlqspi_get_reg(bank, CONF), val); - if (retval != ERROR_OK) - return retval; - - /* wait for fifo_flush to clear */ - for (;;) { - retval = target_read_u32(target, - mrvlqspi_get_reg(bank, CONF), &val); - if (retval != ERROR_OK) - return retval; - LOG_DEBUG("status: 0x%08" PRIX32, val); - if ((val & FIFO_FLUSH) == 0) - break; - if (timeout-- <= 0) { - LOG_ERROR("timed out waiting for flash"); - return ERROR_FAIL; - } - alive_sleep(1); - } - return ERROR_OK; -} - -static int mrvlqspi_read_byte(struct flash_bank *bank, uint8_t *data) -{ - int retval; - uint32_t val; - struct target *target = bank->target; - - /* wait for rfifo_empty to reset */ - for (;;) { - retval = target_read_u32(target, - mrvlqspi_get_reg(bank, CNTL), &val); - if (retval != ERROR_OK) - return retval; - LOG_DEBUG("status: 0x%08" PRIx32, val); - if ((val & RFIFO_EMPTY) == 0) - break; - usleep(10); - } - - retval = target_read_u32(target, - mrvlqspi_get_reg(bank, DIN), &val); - if (retval != ERROR_OK) - return retval; - - *data = val & 0xFF; - - return ERROR_OK; -} - -static int mrvlqspi_flash_busy_status(struct flash_bank *bank, int timeout) -{ - uint8_t val; - int retval; - - /* Flush read/write fifo's */ - retval = mrvlqspi_fifo_flush(bank, FIFO_FLUSH_TIMEOUT); - if (retval != ERROR_OK) - return retval; - - /* Set instruction/addr count value */ - retval = mrvlqspi_set_hdr_cnt(bank, 0x1); - if (retval != ERROR_OK) - return retval; - - /* Read flash status register in continuous manner */ - retval = mrvlqspi_set_din_cnt(bank, 0x0); - if (retval != ERROR_OK) - return retval; - - /* Set instruction */ - retval = mrvlqspi_set_instr(bank, INS_READ_STATUS); - if (retval != ERROR_OK) - return retval; - - /* Set data and addr pin length */ - retval = mrvlqspi_set_conf(bank, 0x0); - if (retval != ERROR_OK) - return retval; - - /* Enable read mode transfer */ - retval = mrvlqspi_start_transfer(bank, QSPI_R_EN); - if (retval != ERROR_OK) - return retval; - - for (;;) { - retval = mrvlqspi_read_byte(bank, &val); - if (retval != ERROR_OK) - return retval; - if (!(val & 0x1)) - break; - if (timeout-- <= 0) { - LOG_ERROR("timed out waiting for flash"); - return ERROR_FAIL; - } - alive_sleep(1); - } - - return mrvlqspi_stop_transfer(bank); -} - -static int mrvlqspi_set_write_status(struct flash_bank *bank, bool mode) -{ - int retval; - uint32_t instr; - - /* Flush read/write fifo's */ - retval = mrvlqspi_fifo_flush(bank, FIFO_FLUSH_TIMEOUT); - if (retval != ERROR_OK) - return retval; - - /* Set instruction/addr count value */ - retval = mrvlqspi_set_hdr_cnt(bank, 0x1); - if (retval != ERROR_OK) - return retval; - - if (mode) - instr = INS_WRITE_ENABLE; - else - instr = INS_WRITE_DISABLE; - - /* Set instruction */ - retval = mrvlqspi_set_instr(bank, instr); - if (retval != ERROR_OK) - return retval; - - retval = mrvlqspi_start_transfer(bank, QSPI_W_EN); - if (retval != ERROR_OK) - return retval; - - retval = mrvlqspi_stop_transfer(bank); - if (retval != ERROR_OK) - return retval; - - return retval; -} - -static int mrvlqspi_read_id(struct flash_bank *bank, uint32_t *id) -{ - uint8_t id_buf[3] = {0, 0, 0}; - int retval, i; - - LOG_DEBUG("Getting ID"); - - /* Flush read/write fifo's */ - retval = mrvlqspi_fifo_flush(bank, FIFO_FLUSH_TIMEOUT); - if (retval != ERROR_OK) - return retval; - - /* Set instruction/addr count value */ - retval = mrvlqspi_set_hdr_cnt(bank, 0x1); - if (retval != ERROR_OK) - return retval; - - /* Set count for number of bytes to read */ - retval = mrvlqspi_set_din_cnt(bank, 0x3); - if (retval != ERROR_OK) - return retval; - - /* Set instruction */ - retval = mrvlqspi_set_instr(bank, SPIFLASH_READ_ID); - if (retval != ERROR_OK) - return retval; - - /* Set data and addr pin length */ - retval = mrvlqspi_set_conf(bank, 0x0); - if (retval != ERROR_OK) - return retval; - - retval = mrvlqspi_start_transfer(bank, QSPI_R_EN); - if (retval != ERROR_OK) - return retval; - - for (i = 0; i < 3; i++) { - retval = mrvlqspi_read_byte(bank, &id_buf[i]); - if (retval != ERROR_OK) - return retval; - } - - LOG_DEBUG("ID is 0x%02" PRIx8 " 0x%02" PRIx8 " 0x%02" PRIx8, - id_buf[0], id_buf[1], id_buf[2]); - retval = mrvlqspi_set_ss_state(bank, QSPI_SS_DISABLE, QSPI_TIMEOUT); - if (retval != ERROR_OK) - return retval; - - *id = id_buf[2] << 16 | id_buf[1] << 8 | id_buf[0]; - return ERROR_OK; -} - -static int mrvlqspi_block_erase(struct flash_bank *bank, uint32_t offset) -{ - int retval; - struct mrvlqspi_flash_bank *mrvlqspi_info = bank->driver_priv; - - /* Set flash write enable */ - retval = mrvlqspi_set_write_status(bank, WRITE_ENABLE); - if (retval != ERROR_OK) - return retval; - - /* Set instruction/addr count value */ - retval = mrvlqspi_set_hdr_cnt(bank, (0x1 | (0x3 << 4))); - if (retval != ERROR_OK) - return retval; - - /* Set read offset address */ - retval = mrvlqspi_set_addr(bank, offset); - if (retval != ERROR_OK) - return retval; - - /* Set instruction */ - retval = mrvlqspi_set_instr(bank, mrvlqspi_info->dev->erase_cmd); - if (retval != ERROR_OK) - return retval; - - retval = mrvlqspi_start_transfer(bank, QSPI_W_EN); - if (retval != ERROR_OK) - return retval; - - retval = mrvlqspi_stop_transfer(bank); - if (retval != ERROR_OK) - return retval; - - return mrvlqspi_flash_busy_status(bank, BLOCK_ERASE_TIMEOUT); -} - -static int mrvlqspi_bulk_erase(struct flash_bank *bank) -{ - int retval; - struct mrvlqspi_flash_bank *mrvlqspi_info = bank->driver_priv; - - /* Set flash write enable */ - retval = mrvlqspi_set_write_status(bank, WRITE_ENABLE); - if (retval != ERROR_OK) - return retval; - - /* Set instruction */ - retval = mrvlqspi_set_instr(bank, mrvlqspi_info->dev->chip_erase_cmd); - if (retval != ERROR_OK) - return retval; - - retval = mrvlqspi_start_transfer(bank, QSPI_W_EN); - if (retval != ERROR_OK) - return retval; - - retval = mrvlqspi_stop_transfer(bank); - if (retval != ERROR_OK) - return retval; - - return mrvlqspi_flash_busy_status(bank, CHIP_ERASE_TIMEOUT); -} - -static int mrvlqspi_flash_erase(struct flash_bank *bank, int first, int last) -{ - struct target *target = bank->target; - struct mrvlqspi_flash_bank *mrvlqspi_info = bank->driver_priv; - int retval = ERROR_OK; - int sector; - - LOG_DEBUG("erase from sector %d to sector %d", first, last); - - if (target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - if ((first < 0) || (last < first) || (last >= bank->num_sectors)) { - LOG_ERROR("Flash sector invalid"); - return ERROR_FLASH_SECTOR_INVALID; - } - - if (!(mrvlqspi_info->probed)) { - LOG_ERROR("Flash bank not probed"); - return ERROR_FLASH_BANK_NOT_PROBED; - } - - for (sector = first; sector <= last; sector++) { - if (bank->sectors[sector].is_protected) { - LOG_ERROR("Flash sector %d protected", sector); - return ERROR_FAIL; - } - } - - /* If we're erasing the entire chip and the flash supports - * it, use a bulk erase instead of going sector-by-sector. */ - if (first == 0 && last == (bank->num_sectors - 1) - && mrvlqspi_info->dev->chip_erase_cmd != - mrvlqspi_info->dev->erase_cmd) { - LOG_DEBUG("Chip supports the bulk erase command."\ - " Will use bulk erase instead of sector-by-sector erase."); - retval = mrvlqspi_bulk_erase(bank); - if (retval == ERROR_OK) { - return retval; - } else - LOG_WARNING("Bulk flash erase failed." - " Falling back to sector-by-sector erase."); - } - - for (sector = first; sector <= last; sector++) { - retval = mrvlqspi_block_erase(bank, - sector * mrvlqspi_info->dev->sectorsize); - if (retval != ERROR_OK) - return retval; - } - - return retval; -} - -static int mrvlqspi_flash_write(struct flash_bank *bank, const uint8_t *buffer, - uint32_t offset, uint32_t count) -{ - struct target *target = bank->target; - struct mrvlqspi_flash_bank *mrvlqspi_info = bank->driver_priv; - int retval = ERROR_OK; - uint32_t page_size, fifo_size; - struct working_area *fifo; - struct reg_param reg_params[6]; - struct armv7m_algorithm armv7m_info; - struct working_area *write_algorithm; - int sector; - - LOG_DEBUG("offset=0x%08" PRIx32 " count=0x%08" PRIx32, - offset, count); - - if (target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - if (offset + count > mrvlqspi_info->dev->size_in_bytes) { - LOG_WARNING("Writes past end of flash. Extra data discarded."); - count = mrvlqspi_info->dev->size_in_bytes - offset; - } - - /* Check sector protection */ - for (sector = 0; sector < bank->num_sectors; sector++) { - /* Start offset in or before this sector? */ - /* End offset in or behind this sector? */ - if ((offset < - (bank->sectors[sector].offset + bank->sectors[sector].size)) - && ((offset + count - 1) >= bank->sectors[sector].offset) - && bank->sectors[sector].is_protected) { - LOG_ERROR("Flash sector %d protected", sector); - return ERROR_FAIL; - } - } - - page_size = mrvlqspi_info->dev->pagesize; - - /* See contrib/loaders/flash/mrvlqspi.S for src */ - static const uint8_t mrvlqspi_flash_write_code[] = { - 0x4f, 0xf0, 0x00, 0x0a, 0xa2, 0x44, 0x92, 0x45, - 0x7f, 0xf6, 0xfc, 0xaf, 0x00, 0xf0, 0x6b, 0xf8, - 0x5f, 0xf0, 0x01, 0x08, 0xc5, 0xf8, 0x1c, 0x80, - 0x5f, 0xf0, 0x06, 0x08, 0xc5, 0xf8, 0x10, 0x80, - 0x5f, 0xf0, 0x01, 0x09, 0x00, 0xf0, 0x6b, 0xf8, - 0x00, 0xf0, 0x7d, 0xf8, 0x5f, 0xf0, 0x31, 0x08, - 0xc5, 0xf8, 0x1c, 0x80, 0x90, 0x46, 0xc5, 0xf8, - 0x14, 0x80, 0x5f, 0xf0, 0x02, 0x08, 0xc5, 0xf8, - 0x10, 0x80, 0x5f, 0xf0, 0x01, 0x09, 0x00, 0xf0, - 0x5a, 0xf8, 0xd0, 0xf8, 0x00, 0x80, 0xb8, 0xf1, - 0x00, 0x0f, 0x00, 0xf0, 0x8b, 0x80, 0x47, 0x68, - 0x47, 0x45, 0x3f, 0xf4, 0xf6, 0xaf, 0x17, 0xf8, - 0x01, 0x9b, 0x00, 0xf0, 0x30, 0xf8, 0x8f, 0x42, - 0x28, 0xbf, 0x00, 0xf1, 0x08, 0x07, 0x47, 0x60, - 0x01, 0x3b, 0x00, 0x2b, 0x00, 0xf0, 0x05, 0x80, - 0x02, 0xf1, 0x01, 0x02, 0x92, 0x45, 0x7f, 0xf4, - 0xe4, 0xaf, 0x00, 0xf0, 0x50, 0xf8, 0xa2, 0x44, - 0x00, 0xf0, 0x2d, 0xf8, 0x5f, 0xf0, 0x01, 0x08, - 0xc5, 0xf8, 0x1c, 0x80, 0x5f, 0xf0, 0x00, 0x08, - 0xc5, 0xf8, 0x20, 0x80, 0x5f, 0xf0, 0x05, 0x08, - 0xc5, 0xf8, 0x10, 0x80, 0x5f, 0xf0, 0x00, 0x09, - 0x00, 0xf0, 0x29, 0xf8, 0x00, 0xf0, 0x13, 0xf8, - 0x09, 0xf0, 0x01, 0x09, 0xb9, 0xf1, 0x00, 0x0f, - 0xf8, 0xd1, 0x00, 0xf0, 0x34, 0xf8, 0x00, 0x2b, - 0xa4, 0xd1, 0x00, 0xf0, 0x53, 0xb8, 0xd5, 0xf8, - 0x00, 0x80, 0x5f, 0xea, 0x08, 0x68, 0xfa, 0xd4, - 0xc5, 0xf8, 0x08, 0x90, 0x70, 0x47, 0xd5, 0xf8, - 0x00, 0x80, 0x5f, 0xea, 0xc8, 0x68, 0xfa, 0xd4, - 0xd5, 0xf8, 0x0c, 0x90, 0x70, 0x47, 0xd5, 0xf8, - 0x04, 0x80, 0x48, 0xf4, 0x00, 0x78, 0xc5, 0xf8, - 0x04, 0x80, 0xd5, 0xf8, 0x04, 0x80, 0x5f, 0xea, - 0x88, 0x58, 0xfa, 0xd4, 0x70, 0x47, 0xd5, 0xf8, - 0x00, 0x80, 0x48, 0xf0, 0x01, 0x08, 0xc5, 0xf8, - 0x00, 0x80, 0xd5, 0xf8, 0x00, 0x80, 0x5f, 0xea, - 0x88, 0x78, 0xfa, 0xd5, 0xd5, 0xf8, 0x04, 0x80, - 0x69, 0xf3, 0x4d, 0x38, 0x48, 0xf4, 0x00, 0x48, - 0xc5, 0xf8, 0x04, 0x80, 0x70, 0x47, 0xd5, 0xf8, - 0x00, 0x80, 0x5f, 0xea, 0x88, 0x78, 0xfa, 0xd5, - 0xd5, 0xf8, 0x00, 0x80, 0x5f, 0xea, 0x48, 0x68, - 0xfa, 0xd5, 0xd5, 0xf8, 0x04, 0x80, 0x48, 0xf4, - 0x80, 0x48, 0xc5, 0xf8, 0x04, 0x80, 0xd5, 0xf8, - 0x04, 0x80, 0x5f, 0xea, 0x08, 0x48, 0xfa, 0xd4, - 0xd5, 0xf8, 0x00, 0x80, 0x28, 0xf0, 0x01, 0x08, - 0xc5, 0xf8, 0x00, 0x80, 0xd5, 0xf8, 0x00, 0x80, - 0x5f, 0xea, 0x88, 0x78, 0xfa, 0xd5, 0x70, 0x47, - 0x00, 0x20, 0x50, 0x60, 0x30, 0x46, 0x00, 0xbe - }; - - if (target_alloc_working_area(target, sizeof(mrvlqspi_flash_write_code), - &write_algorithm) != ERROR_OK) { - LOG_ERROR("Insufficient working area. You must configure"\ - " 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), - mrvlqspi_flash_write_code); - if (retval != ERROR_OK) { - target_free_working_area(target, write_algorithm); - return retval; - } - - /* FIFO allocation */ - fifo_size = target_get_working_area_avail(target); - - if (fifo_size == 0) { - /* if we already allocated the writing code but failed to get fifo - * space, free the algorithm */ - target_free_working_area(target, write_algorithm); - - LOG_ERROR("Insufficient working area. Please allocate at least"\ - " %zdB of working area to enable flash writes.", - sizeof(mrvlqspi_flash_write_code) + 1 - ); - - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - } else if (fifo_size < page_size) - LOG_WARNING("Working area size is limited; flash writes may be"\ - " slow. Increase working area size to at least %zdB"\ - " to reduce write times.", - (size_t)(sizeof(mrvlqspi_flash_write_code) + page_size) - ); - - 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; - - init_reg_param(®_params[0], "r0", 32, PARAM_IN_OUT); /* buffer start, status (out) */ - init_reg_param(®_params[1], "r1", 32, PARAM_OUT); /* buffer end */ - init_reg_param(®_params[2], "r2", 32, PARAM_OUT); /* target address */ - init_reg_param(®_params[3], "r3", 32, PARAM_OUT); /* count (halfword-16bit) */ - init_reg_param(®_params[4], "r4", 32, PARAM_OUT); /* page size */ - init_reg_param(®_params[5], "r5", 32, PARAM_OUT); /* qspi base address */ - - buf_set_u32(reg_params[0].value, 0, 32, fifo->address); - buf_set_u32(reg_params[1].value, 0, 32, fifo->address + fifo->size); - buf_set_u32(reg_params[2].value, 0, 32, offset); - buf_set_u32(reg_params[3].value, 0, 32, count); - buf_set_u32(reg_params[4].value, 0, 32, page_size); - buf_set_u32(reg_params[5].value, 0, 32, (uint32_t) mrvlqspi_info->reg_base); - - retval = target_run_flash_async_algorithm(target, buffer, count, 1, - 0, NULL, - 6, reg_params, - fifo->address, fifo->size, - write_algorithm->address, 0, - &armv7m_info - ); - - if (retval != ERROR_OK) - LOG_ERROR("Error executing flash write algorithm"); - - target_free_working_area(target, fifo); - target_free_working_area(target, write_algorithm); - - 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]); - destroy_reg_param(®_params[5]); - - return retval; -} - -int mrvlqspi_flash_read(struct flash_bank *bank, uint8_t *buffer, - uint32_t offset, uint32_t count) -{ - struct target *target = bank->target; - struct mrvlqspi_flash_bank *mrvlqspi_info = bank->driver_priv; - int retval; - uint32_t i; - - if (target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - if (!(mrvlqspi_info->probed)) { - LOG_ERROR("Flash bank not probed"); - return ERROR_FLASH_BANK_NOT_PROBED; - } - - /* Flush read/write fifo's */ - retval = mrvlqspi_fifo_flush(bank, FIFO_FLUSH_TIMEOUT); - if (retval != ERROR_OK) - return retval; - - /* Set instruction/addr count value */ - retval = mrvlqspi_set_hdr_cnt(bank, (0x1 | (0x3 << 4))); - if (retval != ERROR_OK) - return retval; - - /* Set count for number of bytes to read */ - retval = mrvlqspi_set_din_cnt(bank, count); - if (retval != ERROR_OK) - return retval; - - /* Set read address */ - retval = mrvlqspi_set_addr(bank, offset); - if (retval != ERROR_OK) - return retval; - - /* Set instruction */ - retval = mrvlqspi_set_instr(bank, SPIFLASH_READ); - if (retval != ERROR_OK) - return retval; - - /* Set data and addr pin length */ - retval = mrvlqspi_set_conf(bank, 0x0); - if (retval != ERROR_OK) - return retval; - - retval = mrvlqspi_start_transfer(bank, QSPI_R_EN); - if (retval != ERROR_OK) - return retval; - - for (i = 0; i < count; i++) { - retval = mrvlqspi_read_byte(bank, &buffer[i]); - if (retval != ERROR_OK) - return retval; - } - - retval = mrvlqspi_set_ss_state(bank, QSPI_SS_DISABLE, QSPI_TIMEOUT); - if (retval != ERROR_OK) - return retval; - - return ERROR_OK; -} - -static int mrvlqspi_probe(struct flash_bank *bank) -{ - struct target *target = bank->target; - struct mrvlqspi_flash_bank *mrvlqspi_info = bank->driver_priv; - uint32_t id = 0; - int retval; - struct flash_sector *sectors; - - /* If we've already probed, we should be fine to skip this time. */ - if (mrvlqspi_info->probed) - return ERROR_OK; - - if (target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - mrvlqspi_info->probed = 0; - mrvlqspi_info->bank_num = bank->bank_number; - - /* Read flash JEDEC ID */ - retval = mrvlqspi_read_id(bank, &id); - if (retval != ERROR_OK) - return retval; - - mrvlqspi_info->dev = NULL; - for (const struct flash_device *p = flash_devices; p->name ; p++) - if (p->device_id == id) { - mrvlqspi_info->dev = p; - break; - } - - if (!mrvlqspi_info->dev) { - LOG_ERROR("Unknown flash device ID 0x%08" PRIx32, id); - return ERROR_FAIL; - } - - LOG_INFO("Found flash device \'%s\' ID 0x%08" PRIx32, - mrvlqspi_info->dev->name, mrvlqspi_info->dev->device_id); - - /* Set correct size value */ - bank->size = mrvlqspi_info->dev->size_in_bytes; - - /* create and fill sectors array */ - bank->num_sectors = mrvlqspi_info->dev->size_in_bytes / - mrvlqspi_info->dev->sectorsize; - sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors); - if (sectors == NULL) { - LOG_ERROR("not enough memory"); - return ERROR_FAIL; - } - - for (int sector = 0; sector < bank->num_sectors; sector++) { - sectors[sector].offset = - sector * mrvlqspi_info->dev->sectorsize; - sectors[sector].size = mrvlqspi_info->dev->sectorsize; - sectors[sector].is_erased = -1; - sectors[sector].is_protected = 0; - } - - bank->sectors = sectors; - mrvlqspi_info->probed = 1; - - return ERROR_OK; -} - -static int mrvlqspi_auto_probe(struct flash_bank *bank) -{ - struct mrvlqspi_flash_bank *mrvlqspi_info = bank->driver_priv; - if (mrvlqspi_info->probed) - return ERROR_OK; - return mrvlqspi_probe(bank); -} - -static int mrvlqspi_flash_erase_check(struct flash_bank *bank) -{ - /* Not implemented yet */ - return ERROR_OK; -} - -static int mrvlqspi_protect_check(struct flash_bank *bank) -{ - /* Not implemented yet */ - return ERROR_OK; -} - -int mrvlqspi_get_info(struct flash_bank *bank, char *buf, int buf_size) -{ - struct mrvlqspi_flash_bank *mrvlqspi_info = bank->driver_priv; - - if (!(mrvlqspi_info->probed)) { - snprintf(buf, buf_size, - "\nQSPI flash bank not probed yet\n"); - return ERROR_OK; - } - - snprintf(buf, buf_size, "\nQSPI flash information:\n" - " Device \'%s\' ID 0x%08" PRIx32 "\n", - mrvlqspi_info->dev->name, mrvlqspi_info->dev->device_id); - - return ERROR_OK; -} - -FLASH_BANK_COMMAND_HANDLER(mrvlqspi_flash_bank_command) -{ - struct mrvlqspi_flash_bank *mrvlqspi_info; - - if (CMD_ARGC < 7) - return ERROR_COMMAND_SYNTAX_ERROR; - - mrvlqspi_info = malloc(sizeof(struct mrvlqspi_flash_bank)); - if (mrvlqspi_info == NULL) { - LOG_ERROR("not enough memory"); - return ERROR_FAIL; - } - - /* Get QSPI controller register map base address */ - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[6], mrvlqspi_info->reg_base); - bank->driver_priv = mrvlqspi_info; - mrvlqspi_info->probed = 0; - - return ERROR_OK; -} - -struct flash_driver mrvlqspi_flash = { - .name = "mrvlqspi", - .flash_bank_command = mrvlqspi_flash_bank_command, - .erase = mrvlqspi_flash_erase, - .protect = NULL, - .write = mrvlqspi_flash_write, - .read = mrvlqspi_flash_read, - .probe = mrvlqspi_probe, - .auto_probe = mrvlqspi_auto_probe, - .erase_check = mrvlqspi_flash_erase_check, - .protect_check = mrvlqspi_protect_check, - .info = mrvlqspi_get_info, -}; diff --git a/src/flash/nor/niietcm4.c b/src/flash/nor/niietcm4.c deleted file mode 100644 index 4a849fd26..000000000 --- a/src/flash/nor/niietcm4.c +++ /dev/null @@ -1,1744 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2015 by Bogdan Kolbov * - * kolbov@niiet.ru * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "imp.h" -#include -#include -#include - -#define FLASH_DRIVER_VER 0x00010000 -#define CHIPID_ADDR 0xF0000000 -#define K1921VK01T_ID 0x00000000 - -/*============================================================================== - * FLASH CONTROL REGS - *============================================================================== - */ - -#define MAIN_MEM_TYPE 0 -#define INFO_MEM_TYPE 1 -#define SERVICE_MODE_ERASE_ADDR 0x80030164 -#define MAGIC_KEY 0xA442 - -/*-- BOOTFLASH ---------------------------------------------------------------*/ -#define BOOTFLASH_BASE 0xA001C000 -#define FMA (BOOTFLASH_BASE + 0x00) -#define FMD1 (BOOTFLASH_BASE + 0x04) -#define FMC (BOOTFLASH_BASE + 0x08) -#define FCIS (BOOTFLASH_BASE + 0x0C) -#define FCIM (BOOTFLASH_BASE + 0x10) -#define FCIC (BOOTFLASH_BASE + 0x14) -#define FMD2 (BOOTFLASH_BASE + 0x50) -#define FMD3 (BOOTFLASH_BASE + 0x54) -#define FMD4 (BOOTFLASH_BASE + 0x58) - - -/*---- FMC: Command register */ -#define FMC_WRITE (1<<0) /* Writing in main region */ -#define FMC_PAGE_ERASE (1<<1) /* Page erase the main region */ -#define FMC_FULL_ERASE (1<<2) /* Erase full flash */ -#define FMC_WRITE_IFB (1<<4) /* Writing in info region */ -#define FMC_PAGEERASE_IFB (1<<5) /* Erase page of info region */ -#define FMC_MAGIC_KEY (MAGIC_KEY<<16) /* Operation run command */ - -/*---- FCIS: Status register */ -#define FCIS_OP_CMLT (1<<0) /* Completion flag operation */ -#define FCIS_OP_ERROR (1<<1) /* Flag operation error */ - -/*---- FCIC: CLear status register */ -#define FCIC_CLR_OPCMLT (1<<0) /* Cleare completion flag in register FCIS */ -#define FCIC_CLR_OPERROR (1<<1) /* Cleare error flag in register FCIS */ - -/*-- USERFLASH ---------------------------------------------------------------*/ -#define USERFLASH_PAGE_SIZE 256 -#define USERFLASH_PAGE_TOTALNUM 256 - -#define USERFLASH_BASE 0xA0022000 -#define UFMA (USERFLASH_BASE + 0x00) -#define UFMD (USERFLASH_BASE + 0x04) -#define UFMC (USERFLASH_BASE + 0x08) -#define UFCIS (USERFLASH_BASE + 0x0C) -#define UFCIM (USERFLASH_BASE + 0x10) -#define UFCIC (USERFLASH_BASE + 0x14) - -/*---- UFMC: Command register */ -#define UFMC_WRITE (1<<0) /* Writing in main region */ -#define UFMC_PAGE_ERASE (1<<1) /* Paged erase the main region */ -#define UFMC_FULL_ERASE (1<<2) /* Erase full flash */ -#define UFMC_READ (1<<3) /* Reading from main region */ -#define UFMC_WRITE_IFB (1<<4) /* Writing in info region */ -#define UFMC_PAGEERASE_IFB (1<<5) /* Erase page of info region */ -#define UFMC_READ_IFB (1<<6) /* Reading from info region */ -#define UFMC_MAGIC_KEY (MAGIC_KEY<<16) /* Operation run command */ - -/*---- UFCIS: Status register */ -#define UFCIS_OP_CMLT (1<<0) /* Completion flag operation */ -#define UFCIS_OP_ERROR (1<<1) /* Flag operation error */ - -/*---- UFCIC: CLear status register */ -#define UFCIC_CLR_OPCMLT (1<<0) /* Cleared completion flag in register FCIS */ -#define UFCIC_CLR_OPERROR (1<<1) /* Cleared error flag in register FCIS */ - -/*---- In info userflash address space */ -#define INFOWORD0_ADDR 0x00 -#define INFOWORD0_BOOTFROM_IFB (1<<0) /* Boot from bootflash or bootflash_ifb */ -#define INFOWORD0_EN_GPIO (1<<1) /* Remap to 0x00000000 extmem or bootflash */ -#define INFOWORD0_BOOTFROM_IFB_POS 0 -#define INFOWORD0_EN_GPIO_POS 1 -#define INFOWORD0_EXTMEM_SEL_POS 3 /* Choose altfunc of gpio to work with extmem */ - -#define INFOWORD1_ADDR 0x01 -#define INFOWORD1_PINNUM_POS 0 /* Choose gpio pin number to control extmem boot */ -#define INFOWORD1_PORTNUM_POS 4 /* Choose gpio port to control extmem boot */ - -#define INFOWORD2_ADDR 0x02 -#define INFOWORD2_LOCK_IFB_BF (1<<0) /* Protect info part of bootflash */ - -#define INFOWORD3_ADDR 0x03 -#define INFOWORD3_LOCK_IFB_UF (1<<0) /* Protect info part of userflash */ - -#define BF_LOCK_ADDR 0x40 -#define UF_LOCK_ADDR 0x80 - -/** - * Private data for flash driver. - */ -struct niietcm4_flash_bank { - /* target params */ - bool probed; - uint32_t chipid; - char *chip_name; - char chip_brief[4096]; - /* not mapped userflash params */ - uint32_t uflash_width; - uint32_t uflash_size; - uint32_t uflash_pagetotal; - uint32_t uflash_info_size; - uint32_t uflash_info_pagetotal; - /* boot params */ - bool bflash_info_remap; - char *extmem_boot_port; - uint32_t extmem_boot_pin; - uint32_t extmem_boot_altfunc; - bool extmem_boot; -}; - -/*============================================================================== - * HELPER FUNCTIONS - *============================================================================== - */ - -/** - * Wait while operation with bootflash being performed and check result status - */ -static int niietcm4_opstatus_check(struct flash_bank *bank) -{ - struct target *target = bank->target; - int retval; - int timeout = 5000; - - uint32_t flash_status; - retval = target_read_u32(target, FCIS, &flash_status); - if (retval != ERROR_OK) - return retval; - - while (flash_status == 0x00) { - retval = target_read_u32(target, FCIS, &flash_status); - if (retval != ERROR_OK) - return retval; - if (timeout-- <= 0) { - LOG_ERROR("Bootflash operation timeout"); - return ERROR_FLASH_OPERATION_FAILED; - } - busy_sleep(1); /* can use busy sleep for short times. */ - } - if (flash_status == FCIS_OP_ERROR) { - LOG_ERROR("Bootflash operation error"); - return ERROR_FLASH_OPERATION_FAILED; - } - /* clear status */ - uint32_t flash_cmd = FCIC_CLR_OPCMLT | FCIC_CLR_OPERROR; - retval = target_write_u32(target, FCIC, flash_cmd); - if (retval != ERROR_OK) - return retval; - - return retval; -} - -/** - * Wait while operation with userflash being performed and check result status - */ -static int niietcm4_uopstatus_check(struct flash_bank *bank) -{ - struct target *target = bank->target; - int retval; - int timeout = 5000; - - uint32_t uflash_status; - retval = target_read_u32(target, UFCIS, &uflash_status); - if (retval != ERROR_OK) - return retval; - - while (uflash_status == 0x00) { - retval = target_read_u32(target, UFCIS, &uflash_status); - if (retval != ERROR_OK) - return retval; - if (timeout-- <= 0) { - LOG_ERROR("Userflash operation timeout"); - return ERROR_FLASH_OPERATION_FAILED; - } - busy_sleep(1); /* can use busy sleep for short times. */ - } - if (uflash_status == UFCIS_OP_ERROR) { - LOG_ERROR("Userflash operation error"); - return ERROR_FLASH_OPERATION_FAILED; - } - /* clear status */ - uint32_t uflash_cmd = UFCIC_CLR_OPCMLT | UFCIC_CLR_OPERROR; - retval = target_write_u32(target, UFCIC, uflash_cmd); - if (retval != ERROR_OK) - return retval; - - return retval; -} - -/** - * Dump page of userflash region. - * If we want to change some settings, we have to dump it full, because userflash is flash(not EEPROM). - * And correct write to flash can be performed only after erase. - * So without dump, changing one registers will clear others. - */ -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; - int retval = ERROR_OK; - - uint32_t uflash_cmd; - if (mem_type == INFO_MEM_TYPE) - uflash_cmd = UFMC_MAGIC_KEY | UFMC_READ_IFB; - else - uflash_cmd = UFMC_MAGIC_KEY | UFMC_READ; - - int first = page_num*USERFLASH_PAGE_SIZE; - int last = first + USERFLASH_PAGE_SIZE; - - for (i = first; i < last; i++) { - retval = target_write_u32(target, UFMA, i); - if (retval != ERROR_OK) - return retval; - retval = target_write_u32(target, UFMC, uflash_cmd); - if (retval != ERROR_OK) - return retval; - retval = niietcm4_uopstatus_check(bank); - if (retval != ERROR_OK) - return retval; - retval = target_read_u32(target, UFMD, &dump[i]); - if (retval != ERROR_OK) - return retval; - } - - return retval; -} - -/** - * Load modified page dump to userflash region page. - */ -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; - int retval = ERROR_OK; - - uint32_t uflash_cmd; - if (mem_type == INFO_MEM_TYPE) - uflash_cmd = UFMC_MAGIC_KEY | UFMC_WRITE_IFB; - else - uflash_cmd = UFMC_MAGIC_KEY | UFMC_WRITE; - - int first = page_num*USERFLASH_PAGE_SIZE; - int last = first + USERFLASH_PAGE_SIZE; - - for (i = first; i < last; i++) { - retval = target_write_u32(target, UFMA, i); - if (retval != ERROR_OK) - return retval; - retval = target_write_u32(target, UFMD, dump[i]); - if (retval != ERROR_OK) - return retval; - retval = target_write_u32(target, UFMC, uflash_cmd); - if (retval != ERROR_OK) - return retval; - retval = niietcm4_uopstatus_check(bank); - if (retval != ERROR_OK) - return retval; - } - - return retval; -} - -/** - * Erase one page of userflash info or main region - */ -static int niietcm4_uflash_page_erase(struct flash_bank *bank, int page_num, int mem_type) -{ - struct target *target = bank->target; - int retval; - - uint32_t uflash_cmd; - if (mem_type == INFO_MEM_TYPE) - uflash_cmd = UFMC_MAGIC_KEY | UFMC_PAGEERASE_IFB; - else - uflash_cmd = UFMC_MAGIC_KEY | UFMC_PAGE_ERASE; - - retval = target_write_u32(target, UFMA, page_num*USERFLASH_PAGE_SIZE); - if (retval != ERROR_OK) - return retval; - retval = target_write_u32(target, UFMD, 0xFF); - if (retval != ERROR_OK) - return retval; - retval = target_write_u32(target, UFMC, uflash_cmd); - if (retval != ERROR_OK) - return retval; - /* status check */ - retval = niietcm4_uopstatus_check(bank); - if (retval != ERROR_OK) - return retval; - - return retval; -} - -/** - * Enable or disable protection of userflash pages - */ -static int niietcm4_uflash_protect(struct flash_bank *bank, int mem_type, int set, int first, int last) -{ - int retval; - if (mem_type == INFO_MEM_TYPE) { - /* read dump */ - uint32_t uflash_dump[USERFLASH_PAGE_SIZE]; - retval = niietcm4_dump_uflash_page(bank, uflash_dump, 0, 1); - if (retval != ERROR_OK) - return retval; - /* modify dump */ - if (set) - uflash_dump[INFOWORD2_ADDR] &= ~INFOWORD3_LOCK_IFB_UF; - else - uflash_dump[INFOWORD2_ADDR] |= INFOWORD3_LOCK_IFB_UF; - /* erase page 0 userflash */ - retval = niietcm4_uflash_page_erase(bank, 0, 1); - if (retval != ERROR_OK) - return retval; - /* write dump to userflash */ - retval = niietcm4_load_uflash_page(bank, uflash_dump, 0, 1); - if (retval != ERROR_OK) - return retval; - } else { - /* read dump */ - uint32_t uflash_dump[USERFLASH_PAGE_SIZE]; - retval = niietcm4_dump_uflash_page(bank, uflash_dump, 0, 1); - if (retval != ERROR_OK) - return retval; - /* modify dump */ - for (int i = first; i <= last; i++) { - uint32_t reg_num = i/8; - uint32_t bit_num = i%8; - if (set) - uflash_dump[UF_LOCK_ADDR+reg_num] &= ~(1<target; - - /* skip over flash bank */ - CMD_ARGC--; - CMD_ARGV++; - - uint32_t uflash_addr; - uint32_t uflash_cmd; - uint32_t uflash_data; - - if (strcmp("info", CMD_ARGV[0]) == 0) - uflash_cmd = UFMC_MAGIC_KEY | UFMC_READ_IFB; - else if (strcmp("main", CMD_ARGV[0]) == 0) - uflash_cmd = UFMC_MAGIC_KEY | UFMC_READ; - else - return ERROR_COMMAND_SYNTAX_ERROR; - - COMMAND_PARSE_NUMBER(uint, CMD_ARGV[1], uflash_addr); - - retval = target_write_u32(target, UFMA, uflash_addr); - if (retval != ERROR_OK) - return retval; - retval = target_write_u32(target, UFMC, uflash_cmd); - if (retval != ERROR_OK) - return retval; - /* status check */ - retval = niietcm4_uopstatus_check(bank); - if (retval != ERROR_OK) - return retval; - retval = target_read_u32(target, UFMD, &uflash_data); - if (retval != ERROR_OK) - return retval; - command_print(CMD_CTX, "Read userflash %s region:\n" - "address = 0x%04x,\n" - "value = 0x%02x.", CMD_ARGV[0], uflash_addr, uflash_data); - return retval; -} - -COMMAND_HANDLER(niietcm4_handle_uflash_write_byte_command) -{ - if (CMD_ARGC < 4) - return ERROR_COMMAND_SYNTAX_ERROR; - - struct flash_bank *bank; - int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank); - if (retval != ERROR_OK) - return retval; - struct target *target = bank->target; - - if (target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - /* skip over flash bank */ - CMD_ARGC--; - CMD_ARGV++; - - uint32_t uflash_addr; - uint32_t uflash_data; - int mem_type; - - if (strcmp("info", CMD_ARGV[0]) == 0) - mem_type = 1; - else if (strcmp("main", CMD_ARGV[0]) == 0) - mem_type = 0; - else - return ERROR_COMMAND_SYNTAX_ERROR; - - COMMAND_PARSE_NUMBER(uint, CMD_ARGV[1], uflash_addr); - COMMAND_PARSE_NUMBER(uint, CMD_ARGV[2], uflash_data); - - int page_num = uflash_addr/USERFLASH_PAGE_SIZE; - - command_print(CMD_CTX, "Write userflash %s region:\n" - "address = 0x%04x,\n" - "value = 0x%02x.\n" - "Please wait ... ", CMD_ARGV[0], uflash_addr, uflash_data); - /* dump */ - uint32_t uflash_dump[USERFLASH_PAGE_SIZE]; - niietcm4_dump_uflash_page(bank, uflash_dump, page_num, mem_type); - - /* modify dump */ - uflash_dump[uflash_addr%USERFLASH_PAGE_SIZE] = uflash_data; - - /* erase page userflash */ - niietcm4_uflash_page_erase(bank, page_num, mem_type); - - /* write dump to userflash */ - niietcm4_load_uflash_page(bank, uflash_dump, page_num, mem_type); - command_print(CMD_CTX, "done!"); - return retval; -} - -COMMAND_HANDLER(niietcm4_handle_uflash_full_erase_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 (retval != ERROR_OK) - return retval; - struct target *target = bank->target; - - if (target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - uint32_t uflash_addr = 0; - uint32_t uflash_data = 0xFF; - uint32_t uflash_cmd = UFMC_MAGIC_KEY | UFMC_FULL_ERASE; - - retval = target_write_u32(target, UFMA, uflash_addr); - if (retval != ERROR_OK) - return retval; - retval = target_write_u32(target, UFMD, uflash_data); - if (retval != ERROR_OK) - return retval; - retval = target_write_u32(target, UFMC, uflash_cmd); - if (retval != ERROR_OK) - return retval; - /* status check */ - retval = niietcm4_uopstatus_check(bank); - if (retval != ERROR_OK) - return retval; - command_print(CMD_CTX, "Userflash full erase done!"); - - return retval; -} - -COMMAND_HANDLER(niietcm4_handle_uflash_erase_command) -{ - if (CMD_ARGC < 4) - return ERROR_COMMAND_SYNTAX_ERROR; - - struct flash_bank *bank; - int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank); - if (retval != ERROR_OK) - return retval; - struct target *target = bank->target; - - if (target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - /* skip over flash bank */ - CMD_ARGC--; - CMD_ARGV++; - - unsigned int first, last; - int mem_type; - - if (strcmp("info", CMD_ARGV[0]) == 0) - mem_type = 1; - else if (strcmp("main", CMD_ARGV[0]) == 0) - mem_type = 0; - else - return ERROR_COMMAND_SYNTAX_ERROR; - - COMMAND_PARSE_NUMBER(uint, CMD_ARGV[1], first); - COMMAND_PARSE_NUMBER(uint, CMD_ARGV[2], last); - for (unsigned int i = first; i <= last; i++) { - retval = niietcm4_uflash_page_erase(bank, i, mem_type); - if (retval != ERROR_OK) - return retval; - } - - command_print(CMD_CTX, "Erase %s userflash pages %d through %d done!", CMD_ARGV[0], first, last); - - return retval; -} - -COMMAND_HANDLER(niietcm4_handle_uflash_protect_check_command) -{ - if (CMD_ARGC < 2) - return ERROR_COMMAND_SYNTAX_ERROR; - - struct flash_bank *bank; - int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank); - if (retval != ERROR_OK) - return retval; - - struct target *target = bank->target; - if (target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - /* skip over flash bank */ - CMD_ARGC--; - CMD_ARGV++; - - int mem_type; - if (strcmp("info", CMD_ARGV[0]) == 0) - mem_type = 1; - else if (strcmp("main", CMD_ARGV[0]) == 0) - mem_type = 0; - else - return ERROR_COMMAND_SYNTAX_ERROR; - - int i, j; - uint32_t uflash_addr; - uint32_t uflash_cmd; - uint32_t uflash_data; - - /* chose between main userflash and info userflash */ - if (mem_type == INFO_MEM_TYPE) { - uflash_addr = INFOWORD3_ADDR; - uflash_cmd = UFMC_MAGIC_KEY | UFMC_READ_IFB; - retval = target_write_u32(target, UFMA, uflash_addr); - if (retval != ERROR_OK) - return retval; - retval = target_write_u32(target, UFMC, uflash_cmd); - if (retval != ERROR_OK) - return retval; - - /* status check */ - retval = niietcm4_uopstatus_check(bank); - if (retval != ERROR_OK) - return retval; - retval = target_read_u32(target, UFMD, &uflash_data); - if (retval != ERROR_OK) - return retval; - - if (uflash_data & INFOWORD3_LOCK_IFB_UF) - command_print(CMD_CTX, "All sectors of info userflash are not protected!"); - else - command_print(CMD_CTX, "All sectors of info userflash are protected!"); - } else { - uflash_addr = UF_LOCK_ADDR; - uflash_cmd = UFMC_MAGIC_KEY | UFMC_READ_IFB; - for (i = 0; i < USERFLASH_PAGE_TOTALNUM/8; i++) { - retval = target_write_u32(target, UFMA, uflash_addr); - if (retval != ERROR_OK) - return retval; - retval = target_write_u32(target, UFMC, uflash_cmd); - if (retval != ERROR_OK) - return retval; - - /* status check */ - retval = niietcm4_uopstatus_check(bank); - if (retval != ERROR_OK) - return retval; - retval = target_read_u32(target, UFMD, &uflash_data); - if (retval != ERROR_OK) - return retval; - - for (j = 0; j < 8; j++) { - if (uflash_data & 0x1) - command_print(CMD_CTX, "Userflash sector #%03d: 0x%04x (0x100) is not protected!", - i*8+j, (i*8+j)*USERFLASH_PAGE_SIZE); - else - command_print(CMD_CTX, "Userflash sector #%03d: 0x%04x (0x100) is protected!", - i*8+j, (i*8+j)*USERFLASH_PAGE_SIZE); - uflash_data = uflash_data >> 1; - } - uflash_addr++; - } - } - - return retval; -} - -COMMAND_HANDLER(niietcm4_handle_uflash_protect_command) -{ - if (CMD_ARGC < 5) - return ERROR_COMMAND_SYNTAX_ERROR; - - struct flash_bank *bank; - int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank); - if (retval != ERROR_OK) - return retval; - struct target *target = bank->target; - - if (target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - /* skip over flash bank */ - CMD_ARGC--; - CMD_ARGV++; - - int mem_type; - if (strcmp("info", CMD_ARGV[0]) == 0) - mem_type = 1; - else if (strcmp("main", CMD_ARGV[0]) == 0) - mem_type = 0; - else - return ERROR_COMMAND_SYNTAX_ERROR; - - unsigned int first, last; - COMMAND_PARSE_NUMBER(uint, CMD_ARGV[1], first); - COMMAND_PARSE_NUMBER(uint, CMD_ARGV[2], last); - - int set; - if (strcmp("on", CMD_ARGV[3]) == 0) { - command_print(CMD_CTX, "Try to enable %s userflash sectors %d through %d protection. Please wait ... ", - CMD_ARGV[0], first, last); - set = 1; - } else if (strcmp("off", CMD_ARGV[3]) == 0) { - command_print(CMD_CTX, "Try to disable %s userflash sectors %d through %d protection. Please wait ... ", - CMD_ARGV[0], first, last); - set = 0; - } else - return ERROR_COMMAND_SYNTAX_ERROR; - - retval = niietcm4_uflash_protect(bank, mem_type, set, first, last); - if (retval != ERROR_OK) - return retval; - - command_print(CMD_CTX, "done!"); - return retval; -} - -COMMAND_HANDLER(niietcm4_handle_bflash_info_remap_command) -{ - if (CMD_ARGC < 2) - return ERROR_COMMAND_SYNTAX_ERROR; - - struct flash_bank *bank; - int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank); - if (retval != ERROR_OK) - return retval; - struct target *target = bank->target; - - if (target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - /* skip over flash bank */ - CMD_ARGC--; - CMD_ARGV++; - - int set; - if (strcmp("on", CMD_ARGV[0]) == 0) { - command_print(CMD_CTX, "Try to enable bootflash info region remap. Please wait ..."); - set = 1; - } else if (strcmp("off", CMD_ARGV[0]) == 0) { - command_print(CMD_CTX, "Try to disable bootflash info region remap. Please wait ..."); - set = 0; - } else - return ERROR_COMMAND_SYNTAX_ERROR; - - /* dump */ - uint32_t uflash_dump[USERFLASH_PAGE_SIZE]; - niietcm4_dump_uflash_page(bank, uflash_dump, 0, 1); - - /* modify dump */ - if (set) - uflash_dump[INFOWORD0_ADDR] &= ~INFOWORD0_BOOTFROM_IFB; - else - uflash_dump[INFOWORD0_ADDR] |= INFOWORD0_BOOTFROM_IFB; - - /* erase page userflash */ - niietcm4_uflash_page_erase(bank, 0, 1); - - /* write dump to userflash */ - niietcm4_load_uflash_page(bank, uflash_dump, 0, 1); - command_print(CMD_CTX, "done!"); - - return retval; -} - -COMMAND_HANDLER(niietcm4_handle_extmem_cfg_command) -{ - if (CMD_ARGC < 4) - return ERROR_COMMAND_SYNTAX_ERROR; - - struct flash_bank *bank; - int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank); - if (retval != ERROR_OK) - return retval; - struct target *target = bank->target; - - if (target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - /* skip over flash bank */ - CMD_ARGC--; - CMD_ARGV++; - - uint32_t port; - if (strcmp("gpioa", CMD_ARGV[0]) == 0) - port = 8; - else if (strcmp("gpiob", CMD_ARGV[0]) == 0) - port = 9; - else if (strcmp("gpioc", CMD_ARGV[0]) == 0) - port = 10; - else if (strcmp("gpiod", CMD_ARGV[0]) == 0) - port = 11; - else if (strcmp("gpioe", CMD_ARGV[0]) == 0) - port = 12; - else if (strcmp("gpiof", CMD_ARGV[0]) == 0) - port = 13; - else if (strcmp("gpiog", CMD_ARGV[0]) == 0) - port = 14; - else if (strcmp("gpioh", CMD_ARGV[0]) == 0) - port = 15; - else - return ERROR_COMMAND_SYNTAX_ERROR; - - uint32_t pin; - COMMAND_PARSE_NUMBER(uint, CMD_ARGV[1], pin); - if (pin > 15) - return ERROR_COMMAND_SYNTAX_ERROR; - - uint32_t func; - if (strcmp("func1", CMD_ARGV[2]) == 0) - func = 0; - else if (strcmp("func3", CMD_ARGV[2]) == 0) - func = 3; - else - return ERROR_COMMAND_SYNTAX_ERROR; - - command_print(CMD_CTX, "Try to configure external memory boot interface:\n" - "port = %s\n" - "pin = %s\n" - "func = %s\n" - "Please wait ...", CMD_ARGV[0], CMD_ARGV[1], CMD_ARGV[2]); - /* dump */ - uint32_t uflash_dump[USERFLASH_PAGE_SIZE]; - niietcm4_dump_uflash_page(bank, uflash_dump, 0, 1); - - /* modify dump */ - uflash_dump[INFOWORD0_ADDR] &= ~(3<target; - - if (target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - /* skip over flash bank */ - CMD_ARGC--; - CMD_ARGV++; - - int set; - - if (strcmp("on", CMD_ARGV[0]) == 0) { - command_print(CMD_CTX, "Try to enable boot from external memory. Please wait ..."); - set = 1; - } else if (strcmp("off", CMD_ARGV[0]) == 0) { - command_print(CMD_CTX, "Try to disable boot from external memory. Please wait ..."); - set = 0; - } else - return ERROR_COMMAND_SYNTAX_ERROR; - - /* dump */ - uint32_t uflash_dump[USERFLASH_PAGE_SIZE]; - niietcm4_dump_uflash_page(bank, uflash_dump, 0, 1); - - /* modify dump */ - if (set) - uflash_dump[INFOWORD0_ADDR] &= ~INFOWORD0_EN_GPIO; - else - uflash_dump[INFOWORD0_ADDR] |= INFOWORD0_EN_GPIO; - - /* erase page userflash */ - niietcm4_uflash_page_erase(bank, 0, 1); - - /* write dump to userflash */ - niietcm4_load_uflash_page(bank, uflash_dump, 0, 1); - command_print(CMD_CTX, "done!"); - - return retval; -} - -COMMAND_HANDLER(niietcm4_handle_service_mode_erase_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 (retval != ERROR_OK) - return retval; - struct target *target = bank->target; - - command_print(CMD_CTX, "Try to perform service mode erase. Please wait ..."); - - retval = target_write_u32(target, SERVICE_MODE_ERASE_ADDR, 1); - if (retval != ERROR_OK) - return retval; - - int timeout = 500; - uint32_t status; - - retval = target_read_u32(target, SERVICE_MODE_ERASE_ADDR, &status); - if (retval != ERROR_OK) - return retval; - - while (status != 0x03) { - retval = target_read_u32(target, SERVICE_MODE_ERASE_ADDR, &status); - if (retval != ERROR_OK) - return retval; - if (timeout-- <= 0) { - LOG_ERROR("Service mode erase timeout"); - return ERROR_FLASH_OPERATION_FAILED; - } - busy_sleep(1); /* can use busy sleep for short times. */ - } - command_print(CMD_CTX, "done! All data erased."); - - return retval; -} - -COMMAND_HANDLER(niietcm4_handle_driver_info_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 (retval != ERROR_OK) - return retval; - - command_print(CMD_CTX, "niietcm4 flash driver\n" - "version: %d.%d\n" - "author: Bogdan Kolbov\n" - "mail: kolbov@niiet.ru", - FLASH_DRIVER_VER>>16, - FLASH_DRIVER_VER&0xFFFF); - - return retval; -} - -static const struct command_registration niietcm4_exec_command_handlers[] = { - { - .name = "uflash_read_byte", - .handler = niietcm4_handle_uflash_read_byte_command, - .mode = COMMAND_EXEC, - .usage = "bank_id ('main'|'info') address", - .help = "Read byte from main or info userflash region", - }, - { - .name = "uflash_write_byte", - .handler = niietcm4_handle_uflash_write_byte_command, - .mode = COMMAND_EXEC, - .usage = "bank_id ('main'|'info') address value", - .help = "Write byte to main or info userflash region", - }, - { - .name = "uflash_full_erase", - .handler = niietcm4_handle_uflash_full_erase_command, - .mode = COMMAND_EXEC, - .usage = "bank_id", - .help = "Erase all userflash including info region", - }, - { - .name = "uflash_erase", - .handler = niietcm4_handle_uflash_erase_command, - .mode = COMMAND_EXEC, - .usage = "bank_id ('main'|'info') first_sector_num last_sector_num", - .help = "Erase sectors of main or info userflash region, starting at sector first up to and including last.", - }, - { - .name = "uflash_protect_check", - .handler = niietcm4_handle_uflash_protect_check_command, - .mode = COMMAND_EXEC, - .usage = "bank_id ('main'|'info')", - .help = "Check sectors protect.", - }, - { - .name = "uflash_protect", - .handler = niietcm4_handle_uflash_protect_command, - .mode = COMMAND_EXEC, - .usage = "bank_id ('main'|'info') first_sector_num last_sector_num ('on'|'off')", - .help = "Protect sectors of main or info userflash region, starting at sector first up to and including last.", - }, - { - .name = "bflash_info_remap", - .handler = niietcm4_handle_bflash_info_remap_command, - .mode = COMMAND_EXEC, - .usage = "bank_id ('on'|'off')", - .help = "Enable remapping bootflash info region to 0x00000000 (or 0x40000000 if external memory boot used).", - }, - { - .name = "extmem_cfg", - .handler = niietcm4_handle_extmem_cfg_command, - .mode = COMMAND_EXEC, - .usage = "bank_id ('gpioa'|'gpiob'|'gpioc'|'gpiod'|'gpioe'|'gpiof'|'gpiog'|'gpioh') pin_num ('func1'|'func3')", - .help = "Configure external memory interface for boot.", - }, - { - .name = "extmem_boot", - .handler = niietcm4_handle_extmem_boot_command, - .mode = COMMAND_EXEC, - .usage = "bank_id ('on'|'off')", - .help = "Enable boot from external memory.", - }, - { - .name = "service_mode_erase", - .handler = niietcm4_handle_service_mode_erase_command, - .mode = COMMAND_EXEC, - .usage = "bank_id", - .help = "Perform emergency erase of all flash (bootflash and userflash).", - }, - { - .name = "driver_info", - .handler = niietcm4_handle_driver_info_command, - .mode = COMMAND_EXEC, - .usage = "bank_id", - .help = "Show information about flash driver.", - }, - COMMAND_REGISTRATION_DONE -}; - -static const struct command_registration niietcm4_command_handlers[] = { - { - .name = "niietcm4", - .mode = COMMAND_ANY, - .help = "niietcm4 flash command group", - .usage = "", - .chain = niietcm4_exec_command_handlers, - }, - COMMAND_REGISTRATION_DONE -}; - -/*============================================================================== - * FLASH INTERFACE - *============================================================================== - */ - -FLASH_BANK_COMMAND_HANDLER(niietcm4_flash_bank_command) -{ - struct niietcm4_flash_bank *niietcm4_info; - - if (CMD_ARGC < 6) - return ERROR_COMMAND_SYNTAX_ERROR; - - niietcm4_info = malloc(sizeof(struct niietcm4_flash_bank)); - - bank->driver_priv = niietcm4_info; - - /* information will be updated by probing */ - niietcm4_info->probed = false; - niietcm4_info->chipid = 0; - niietcm4_info->chip_name = NULL; - niietcm4_info->uflash_width = 0; - niietcm4_info->uflash_size = 0; - niietcm4_info->uflash_pagetotal = 0; - niietcm4_info->uflash_info_size = 0; - niietcm4_info->uflash_info_pagetotal = 0; - niietcm4_info->bflash_info_remap = false; - niietcm4_info->extmem_boot_port = NULL; - niietcm4_info->extmem_boot_pin = 0; - niietcm4_info->extmem_boot_altfunc = 0; - niietcm4_info->extmem_boot = false; - - return ERROR_OK; -} - -static int niietcm4_protect_check(struct flash_bank *bank) -{ - struct target *target = bank->target; - struct niietcm4_flash_bank *niietcm4_info = bank->driver_priv; - - int retval = ERROR_FLASH_OPERATION_FAILED; - int set; - uint32_t uflash_addr; - uint32_t uflash_cmd; - uint32_t uflash_data; - /* chose between main bootflash and info bootflash */ - if (niietcm4_info->bflash_info_remap) { - uflash_addr = INFOWORD2_ADDR; - uflash_cmd = UFMC_MAGIC_KEY | UFMC_READ_IFB; - retval = target_write_u32(target, UFMA, uflash_addr); - if (retval != ERROR_OK) - return retval; - retval = target_write_u32(target, UFMC, uflash_cmd); - if (retval != ERROR_OK) - return retval; - - /* status check */ - retval = niietcm4_uopstatus_check(bank); - if (retval != ERROR_OK) - return retval; - retval = target_read_u32(target, UFMD, &uflash_data); - if (retval != ERROR_OK) - return retval; - - if (uflash_data & INFOWORD2_LOCK_IFB_BF) - set = 0; - else - set = 1; - bank->sectors[0].is_protected = set; - } else { - uflash_addr = BF_LOCK_ADDR; - uflash_cmd = UFMC_MAGIC_KEY | UFMC_READ_IFB; - for (int i = 0; i < bank->num_sectors/8; i++) { - retval = target_write_u32(target, UFMA, uflash_addr); - if (retval != ERROR_OK) - return retval; - retval = target_write_u32(target, UFMC, uflash_cmd); - if (retval != ERROR_OK) - return retval; - - /* status check */ - retval = niietcm4_uopstatus_check(bank); - if (retval != ERROR_OK) - return retval; - retval = target_read_u32(target, UFMD, &uflash_data); - if (retval != ERROR_OK) - return retval; - - for (int j = 0; j < 8; j++) { - if (uflash_data & 0x1) - set = 0; - else - set = 1; - bank->sectors[i*8+j].is_protected = set; - uflash_data = uflash_data >> 1; - } - uflash_addr++; - } - } - - return retval; -} - -static int niietcm4_mass_erase(struct flash_bank *bank) -{ - struct target *target = bank->target; - - int retval; - uint32_t flash_cmd; - - /* start mass erase */ - flash_cmd = FMC_MAGIC_KEY | FMC_FULL_ERASE; - retval = target_write_u32(target, FMC, flash_cmd); - if (retval != ERROR_OK) - return retval; - - /* status check */ - retval = niietcm4_opstatus_check(bank); - if (retval != ERROR_OK) - return retval; - - return retval; -} - -static int niietcm4_erase(struct flash_bank *bank, int first, int last) -{ - struct target *target = bank->target; - struct niietcm4_flash_bank *niietcm4_info = bank->driver_priv; - int retval = ERROR_FLASH_OPERATION_FAILED; - - if (bank->target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - if ((first == 0) && (last == (bank->num_sectors - 1))) { - retval = niietcm4_mass_erase(bank); - return retval; - } - - /* chose between main bootflash and info bootflash */ - uint32_t flash_cmd, flash_addr; - if (niietcm4_info->bflash_info_remap) - flash_cmd = FMC_MAGIC_KEY | FMC_PAGEERASE_IFB; - else - flash_cmd = FMC_MAGIC_KEY | FMC_PAGE_ERASE; - - /* erasing pages */ - unsigned int page_size = bank->size / bank->num_sectors; - for (int i = first; i <= last; i++) { - /* current page addr */ - flash_addr = i*page_size; - retval = target_write_u32(target, FMA, flash_addr); - if (retval != ERROR_OK) - return retval; - - /* start erase */ - retval = target_write_u32(target, FMC, flash_cmd); - if (retval != ERROR_OK) - return retval; - - /* status check */ - retval = niietcm4_opstatus_check(bank); - if (retval != ERROR_OK) - return retval; - - bank->sectors[i].is_erased = 1; - } - - return retval; -} - -static int niietcm4_protect(struct flash_bank *bank, int set, int first, int last) -{ - struct target *target = bank->target; - struct niietcm4_flash_bank *niietcm4_info = bank->driver_priv; - - int retval; - - if (target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - LOG_INFO("Plese wait ..."); /* it`s quite a long process */ - /* chose between main bootflash and info bootflash */ - if (niietcm4_info->bflash_info_remap) { - /* dump */ - uint32_t uflash_dump[USERFLASH_PAGE_SIZE]; - retval = niietcm4_dump_uflash_page(bank, uflash_dump, 0, 1); - if (retval != ERROR_OK) - return retval; - /* modify dump */ - if (set) - uflash_dump[INFOWORD2_ADDR] &= ~INFOWORD2_LOCK_IFB_BF; - else - uflash_dump[INFOWORD2_ADDR] |= INFOWORD2_LOCK_IFB_BF; - /* erase page 0 userflash */ - retval = niietcm4_uflash_page_erase(bank, 0, 1); - if (retval != ERROR_OK) - return retval; - /* write dump to userflash */ - retval = niietcm4_load_uflash_page(bank, uflash_dump, 0, 1); - if (retval != ERROR_OK) - return retval; - } else { - /* read dump*/ - uint32_t uflash_dump[USERFLASH_PAGE_SIZE]; - retval = niietcm4_dump_uflash_page(bank, uflash_dump, 0, 1); - if (retval != ERROR_OK) - return retval; - /* modify dump */ - for (int i = first; i <= last; i++) { - uint32_t reg_num = i/8; - uint32_t bit_num = i%8; - if (set) - uflash_dump[BF_LOCK_ADDR+reg_num] &= ~(1<target; - struct niietcm4_flash_bank *niietcm4_info = bank->driver_priv; - uint32_t buffer_size = 32768 + 8; /* 8 bytes for rp and wp */ - struct working_area *write_algorithm; - struct working_area *source; - uint32_t address = bank->base + offset; - struct reg_param reg_params[5]; - struct armv7m_algorithm armv7m_info; - int retval = ERROR_OK; - - /* see contrib/loaders/flash/k1921vk01t.S for src */ - static const uint8_t niietcm4_flash_write_code[] = { - 0x14, 0x4f, 0x16, 0x68, 0x00, 0x2e, 0x23, 0xd0, 0x55, 0x68, 0xb5, 0x42, 0xf9, 0xd0, 0x2e, 0x68, - 0x7e, 0x60, 0x04, 0x35, 0x2e, 0x68, 0x3e, 0x65, 0x04, 0x35, 0x2e, 0x68, 0x7e, 0x65, 0x04, 0x35, - 0x2e, 0x68, 0xbe, 0x65, 0x04, 0x35, 0x3c, 0x60, 0x10, 0x34, 0xb8, 0x60, 0xfe, 0x68, 0x00, 0x2e, - 0xfc, 0xd0, 0x02, 0x2e, 0x0a, 0xd0, 0x01, 0x26, 0x7e, 0x61, 0x9d, 0x42, 0x01, 0xd3, 0x15, 0x46, - 0x08, 0x35, 0x55, 0x60, 0x01, 0x39, 0x00, 0x29, 0x02, 0xd0, 0xda, 0xe7, 0x00, 0x20, 0x50, 0x60, - 0x30, 0x46, 0x00, 0xbe, 0x00, 0xc0, 0x01, 0xa0 - }; - - /* flash write code */ - if (target_alloc_working_area(target, sizeof(niietcm4_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(niietcm4_flash_write_code), niietcm4_flash_write_code); - if (retval != ERROR_OK) - return retval; - - /* memory buffer */ - while (target_alloc_working_area_try(target, buffer_size, &source) != ERROR_OK) { - buffer_size /= 2; - buffer_size &= ~15UL; /* Make sure it's 16 byte aligned */ - buffer_size += 8; /* And 8 bytes for WP and RP */ - if (buffer_size <= 256) { - /* we already allocated the writing code, but failed to get a - * buffer, free the algorithm */ - target_free_working_area(target, write_algorithm); - - 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) */ - init_reg_param(®_params[2], "r2", 32, PARAM_OUT); /* buffer start */ - init_reg_param(®_params[3], "r3", 32, PARAM_OUT); /* buffer end */ - init_reg_param(®_params[4], "r4", 32, PARAM_IN_OUT); /* target address */ - - uint32_t flash_cmd; - if (niietcm4_info->bflash_info_remap) - flash_cmd = FMC_MAGIC_KEY | FMC_WRITE_IFB; - else - flash_cmd = FMC_MAGIC_KEY | FMC_WRITE; - - buf_set_u32(reg_params[0].value, 0, 32, flash_cmd); - buf_set_u32(reg_params[1].value, 0, 32, count); - 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, address); - - armv7m_info.common_magic = ARMV7M_COMMON_MAGIC; - armv7m_info.core_mode = ARM_MODE_THREAD; - - retval = target_run_flash_async_algorithm(target, buffer, count, 16, - 0, NULL, - 5, reg_params, - source->address, source->size, - write_algorithm->address, 0, - &armv7m_info); - - if (retval == ERROR_FLASH_OPERATION_FAILED) - LOG_ERROR("flash write failed at address 0x%"PRIx32, - buf_get_u32(reg_params[4].value, 0, 32)); - - target_free_working_area(target, source); - target_free_working_area(target, write_algorithm); - - 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 niietcm4_write(struct flash_bank *bank, const uint8_t *buffer, - uint32_t offset, uint32_t count) -{ - 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 & 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 */ - retval = niietcm4_write_block(bank, buffer, offset, count/16); - uint32_t flash_addr, flash_cmd, flash_data; - - if (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE) { - /* if block write failed (no sufficient working area), - * we use normal (slow) single halfword accesses */ - LOG_WARNING("Can't use block writes, falling back to single memory accesses"); - LOG_INFO("Plese wait ..."); /* it`s quite a long process */ - - /* chose between main bootflash and info bootflash */ - if (niietcm4_info->bflash_info_remap) - flash_cmd = FMC_MAGIC_KEY | FMC_WRITE_IFB; - else - flash_cmd = FMC_MAGIC_KEY | FMC_WRITE; - - /* write 16 bytes per try */ - for (unsigned int i = 0; i < count; i += 16) { - /* current addr */ - LOG_INFO("%d byte of %d", i, count); - flash_addr = offset + i; - retval = target_write_u32(target, FMA, flash_addr); - if (retval != ERROR_OK) - goto free_buffer; - - /* 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 = value[0]; - retval = target_write_u32(target, FMD1, flash_data); - if (retval != ERROR_OK) - goto free_buffer; - flash_data = value[1]; - retval = target_write_u32(target, FMD2, flash_data); - if (retval != ERROR_OK) - goto free_buffer; - flash_data = value[2]; - retval = target_write_u32(target, FMD3, flash_data); - if (retval != ERROR_OK) - goto free_buffer; - flash_data = value[3]; - retval = target_write_u32(target, FMD4, flash_data); - if (retval != ERROR_OK) - goto free_buffer; - - /* write start */ - retval = target_write_u32(target, FMC, flash_cmd); - if (retval != ERROR_OK) - goto free_buffer; - - /* status check */ - retval = niietcm4_opstatus_check(bank); - if (retval != ERROR_OK) - goto free_buffer; - } - - } - -free_buffer: - if (new_buffer) - free(new_buffer); - - return retval; -} - -static int niietcm4_probe_k1921vk01t(struct flash_bank *bank) -{ - struct niietcm4_flash_bank *niietcm4_info = bank->driver_priv; - struct target *target = bank->target; - int retval; - - niietcm4_info->chip_name = "K1921VK01T"; - - /* check if we in service mode */ - uint32_t service_mode; - retval = target_read_u32(target, 0x80017000, &service_mode); - if (retval != ERROR_OK) - return retval; - service_mode = (service_mode>>2) & 0x1; - - if (!service_mode) { - niietcm4_info->uflash_width = 8; - niietcm4_info->uflash_size = 0x10000; - niietcm4_info->uflash_pagetotal = 256; - niietcm4_info->uflash_info_size = 0x200; - niietcm4_info->uflash_info_pagetotal = 2; - - uint32_t uflash_data[2]; - uint32_t uflash_cmd = UFMC_MAGIC_KEY | UFMC_READ_IFB; - for (int i = 0; i < 2; i++) { - retval = target_write_u32(target, UFMA, i); - if (retval != ERROR_OK) - return retval; - retval = target_write_u32(target, UFMC, uflash_cmd); - if (retval != ERROR_OK) - return retval; - /* status check */ - retval = niietcm4_uopstatus_check(bank); - if (retval != ERROR_OK) - return retval; - retval = target_read_u32(target, UFMD, &uflash_data[i]); - if (retval != ERROR_OK) - return retval; - } - - int boot_from_ifb = (uflash_data[0]>>INFOWORD0_BOOTFROM_IFB_POS) & 0x1; - int en_gpio = (uflash_data[0]>>INFOWORD0_EN_GPIO_POS) & 0x1; - int extmem_sel = (uflash_data[0]>>INFOWORD0_EXTMEM_SEL_POS) & 0x3; - int pinnum = (uflash_data[1]>>INFOWORD1_PINNUM_POS) & 0xF; - int portnum = (uflash_data[1]>>INFOWORD1_PORTNUM_POS) & 0x7; - - if (boot_from_ifb) - niietcm4_info->bflash_info_remap = false; - else - niietcm4_info->bflash_info_remap = true; - if (extmem_sel == 0x2) - niietcm4_info->extmem_boot_altfunc = 3; - else - niietcm4_info->extmem_boot_altfunc = 1; - if (portnum == 0x0) - niietcm4_info->extmem_boot_port = "GPIOA"; - else if (portnum == 0x1) - niietcm4_info->extmem_boot_port = "GPIOB"; - else if (portnum == 0x2) - niietcm4_info->extmem_boot_port = "GPIOC"; - else if (portnum == 0x3) - niietcm4_info->extmem_boot_port = "GPIOD"; - else if (portnum == 0x4) - niietcm4_info->extmem_boot_port = "GPIOE"; - else if (portnum == 0x5) - niietcm4_info->extmem_boot_port = "GPIOF"; - else if (portnum == 0x6) - niietcm4_info->extmem_boot_port = "GPIOG"; - else if (portnum == 0x7) - niietcm4_info->extmem_boot_port = "GPIOH"; - else - niietcm4_info->extmem_boot_port = "not defined"; - if (en_gpio) - niietcm4_info->extmem_boot = false; - else - niietcm4_info->extmem_boot = true; - niietcm4_info->extmem_boot_pin = pinnum; - - /* check state of extmem boot en pin, if "high", extmem remapped to 0x00000000 */ - uint32_t extmem_boot_port_data; - retval = target_read_u32(target, 0x80010000 + 0x1000*portnum, &extmem_boot_port_data); - if (retval != ERROR_OK) - return retval; - int extmem_boot_pin_data = (extmem_boot_port_data>>pinnum) & 0x1; - - uint32_t extmem_base; - uint32_t bflash_base; - if (extmem_boot_pin_data && niietcm4_info->extmem_boot) { - extmem_base = 0x00000000; - bflash_base = 0x40000000; - } else { - extmem_base = 0x40000000; - bflash_base = 0x00000000; - } - - uint32_t bflash_size = 0x100000; - uint32_t bflash_pages = 128; - uint32_t bflash_info_size = 0x2000; - uint32_t bflash_info_pages = 1; - if (niietcm4_info->bflash_info_remap) { - bflash_base += 0x2000; - bflash_size -= 0x2000; - bflash_pages--; - bank->size = bflash_info_size; - bank->num_sectors = bflash_info_pages; - } else { - bank->size = bflash_size; - bank->num_sectors = bflash_pages; - } - - char info_bootflash_addr_str[64]; - if (niietcm4_info->bflash_info_remap) - snprintf(info_bootflash_addr_str, sizeof(info_bootflash_addr_str), "0x%08x base adress", bank->base); - else - snprintf(info_bootflash_addr_str, sizeof(info_bootflash_addr_str), "not maped to global adress space"); - - snprintf(niietcm4_info->chip_brief, - sizeof(niietcm4_info->chip_brief), - "\n" - "MEMORY CONFIGURATION\n" - "Bootflash :\n" - " %d kB total\n" - " %d pages %d kB each\n" - " 0x%08x base adress\n" - "%s" - "Info bootflash :\n" - " %d kB total\n" - " %d pages %d kB each\n" - " %s\n" - "%s" - "Userflash :\n" - " %d kB total\n" - " %d pages %d B each\n" - " %d bit cells\n" - " not maped to global adress space\n" - "Info userflash :\n" - " %d B total\n" - " %d pages of %d B each\n" - " %d bit cells\n" - " not maped to global adress space\n" - "RAM :\n" - " 192 kB total\n" - " 0x20000000 base adress\n" - "External memory :\n" - " 8/16 bit address space\n" - " 0x%08x base adress\n" - "\n" - "INFOWORD STATUS\n" - "Bootflash info region remap :\n" - " %s\n" - "External memory boot port :\n" - " %s\n" - "External memory boot pin :\n" - " %d\n" - "External memory interface alternative function :\n" - " %d\n" - "Option boot from external memory :\n" - " %s\n", - bflash_size/1024, - bflash_pages, - (bflash_size/bflash_pages)/1024, - bflash_base, - niietcm4_info->bflash_info_remap ? "" : " this flash will be used for debugging, writing and etc\n", - bflash_info_size/1024, - bflash_info_pages, - (bflash_info_size/bflash_info_pages)/1024, - info_bootflash_addr_str, - niietcm4_info->bflash_info_remap ? " this flash will be used for debugging, writing and etc\n" : "", - niietcm4_info->uflash_size/1024, - niietcm4_info->uflash_pagetotal, - niietcm4_info->uflash_size/niietcm4_info->uflash_pagetotal, - niietcm4_info->uflash_width, - niietcm4_info->uflash_info_size, - niietcm4_info->uflash_info_pagetotal, - niietcm4_info->uflash_info_size/niietcm4_info->uflash_info_pagetotal, - niietcm4_info->uflash_width, - extmem_base, - niietcm4_info->bflash_info_remap ? "enable" : "disable", - niietcm4_info->extmem_boot_port, - niietcm4_info->extmem_boot_pin, - niietcm4_info->extmem_boot_altfunc, - niietcm4_info->extmem_boot ? "enable" : "disable"); - } else{ - bank->size = 0x100000; - bank->num_sectors = 128; - - sprintf(niietcm4_info->chip_brief, - "\n" - "H[2] was HIGH while startup. Device entered service mode.\n" - "All flashes were locked.\n" - "If you want to perform emergency erase (erase all flashes),\n" - "please use \"service_mode_erase\" command and reset device.\n" - "Do not forget to pull H[2] down while reset for returning to normal operation mode.\n" - ); - } - - return retval; -} - -static int niietcm4_probe(struct flash_bank *bank) -{ - struct niietcm4_flash_bank *niietcm4_info = bank->driver_priv; - struct target *target = bank->target; - - if (bank->sectors) { - free(bank->sectors); - bank->sectors = NULL; - } - uint32_t retval; - uint32_t chipid; - - retval = target_read_u32(target, CHIPID_ADDR, &chipid); - if (retval != ERROR_OK) { - chipid = K1921VK01T_ID; - LOG_INFO("unknown chipid, assuming K1921VK01T"); - } - - if (chipid == K1921VK01T_ID) - niietcm4_probe_k1921vk01t(bank); - - int page_total = bank->num_sectors; - int page_size = bank->size / page_total; - - bank->sectors = malloc(sizeof(struct flash_sector) * page_total); - - for (int i = 0; i < page_total; i++) { - bank->sectors[i].offset = i * page_size; - bank->sectors[i].size = page_size; - bank->sectors[i].is_erased = -1; - bank->sectors[i].is_protected = -1; - } - - niietcm4_info->probed = true; - - return ERROR_OK; -} - -static int niietcm4_auto_probe(struct flash_bank *bank) -{ - struct niietcm4_flash_bank *niietcm4_info = bank->driver_priv; - if (niietcm4_info->probed) - return ERROR_OK; - return niietcm4_probe(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); - snprintf(buf, buf_size, " "); - - return ERROR_OK; -} - - -struct flash_driver niietcm4_flash = { - .name = "niietcm4", - .usage = "flash bank niietcm4 0 0 ", - .commands = niietcm4_command_handlers, - .flash_bank_command = niietcm4_flash_bank_command, - .erase = niietcm4_erase, - .protect = niietcm4_protect, - .write = niietcm4_write, - .read = default_flash_read, - .probe = niietcm4_probe, - .auto_probe = niietcm4_auto_probe, - .erase_check = default_flash_blank_check, - .protect_check = niietcm4_protect_check, - .info = get_niietcm4_info, -}; diff --git a/src/flash/nor/non_cfi.c b/src/flash/nor/non_cfi.c deleted file mode 100644 index 851c0ae81..000000000 --- a/src/flash/nor/non_cfi.c +++ /dev/null @@ -1,560 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Dominic Rath * - * Dominic.Rath@gmx.de * - * Copyright (C) 2009 Michael Schwingen * - * michael@schwingen.org * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "imp.h" -#include "cfi.h" -#include "non_cfi.h" - -#define KB 1024 -#define MB (1024*1024) -#define ERASE_REGION(num, size) (((size/256) << 16) | (num-1)) - -/* non-CFI compatible flashes */ -static const struct non_cfi non_cfi_flashes[] = { - { - .mfr = CFI_MFR_SST, - .id = 0xd4, - .pri_id = 0x02, - .dev_size = 64*KB, - .interface_desc = 0x0, /* x8 only device */ - .max_buf_write_size = 0x0, - .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7, - .num_erase_regions = 1, - .erase_region_info = { - ERASE_REGION(16, 4*KB) - } - }, - { - .mfr = CFI_MFR_SST, - .id = 0xd5, - .pri_id = 0x02, - .dev_size = 128*KB, - .interface_desc = 0x0, /* x8 only device */ - .max_buf_write_size = 0x0, - .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7, - .num_erase_regions = 1, - .erase_region_info = { - ERASE_REGION(32, 4*KB) - } - }, - { - .mfr = CFI_MFR_SST, - .id = 0xd6, - .pri_id = 0x02, - .dev_size = 256*KB, - .interface_desc = 0x0, /* x8 only device */ - .max_buf_write_size = 0x0, - .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7, - .num_erase_regions = 1, - .erase_region_info = { - ERASE_REGION(64, 4*KB) - } - }, - { - .mfr = CFI_MFR_SST, - .id = 0xd7, - .pri_id = 0x02, - .dev_size = 512*KB, - .interface_desc = 0x0, /* x8 only device */ - .max_buf_write_size = 0x0, - .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7, - .num_erase_regions = 1, - .erase_region_info = { - ERASE_REGION(128, 4*KB) - } - }, - { - .mfr = CFI_MFR_AMD, /* Spansion AM29LV040B */ - .id = 0x4f, - .pri_id = 0x02, - .dev_size = 512*KB, - .interface_desc = 0x0, /* x8 only device */ - .max_buf_write_size = 0x0, - .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7, - .num_erase_regions = 1, - .erase_region_info = { - ERASE_REGION(8, 64*KB) - } - }, - { - .mfr = CFI_MFR_SST, - .id = 0x2780, - .pri_id = 0x02, - .dev_size = 512*KB, - .interface_desc = 0x2, /* x8 or x16 device */ - .max_buf_write_size = 0x0, - .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7, - .num_erase_regions = 1, - .erase_region_info = { - ERASE_REGION(128, 4*KB) - } - }, - { - .mfr = CFI_MFR_ST, - .id = 0xd6, /* ST29F400BB */ - .pri_id = 0x02, - .dev_size = 512*KB, - .interface_desc = 0x2, /* x8 or x16 device with nBYTE */ - .max_buf_write_size = 0x0, - .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7, - .num_erase_regions = 4, - .erase_region_info = { - ERASE_REGION(1, 16*KB), - ERASE_REGION(2, 8*KB), - ERASE_REGION(1, 32*KB), - ERASE_REGION(7, 64*KB) - } - }, - { - .mfr = CFI_MFR_ST, - .id = 0xd5, /* ST29F400BT */ - .pri_id = 0x02, - .dev_size = 512*KB, - .interface_desc = 0x2, /* x8 or x16 device with nBYTE */ - .max_buf_write_size = 0x0, - .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7, - .num_erase_regions = 4, - .erase_region_info = { - ERASE_REGION(7, 64*KB), - ERASE_REGION(1, 32*KB), - ERASE_REGION(2, 8*KB), - ERASE_REGION(1, 16*KB) - } - }, - - /* SST 39VF* do not support DQ5 status polling - this currently is - only supported by the host algorithm, not by the target code using - the work area. - Only true for 8-bit and 32-bit wide memories. 16-bit wide memories - without DQ5 status polling are supported by the target code. - */ - { - .mfr = CFI_MFR_SST, - .id = 0x2782, /* SST39xF160 */ - .pri_id = 0x02, - .dev_size = 2*MB, - .interface_desc = 0x2, /* x8 or x16 device with nBYTE */ - .max_buf_write_size = 0x0, - .status_poll_mask = CFI_STATUS_POLL_MASK_DQ6_DQ7, - .num_erase_regions = 1, - .erase_region_info = { - ERASE_REGION(512, 4*KB) - } - }, - { - .mfr = CFI_MFR_SST, - .id = 0x2783, /* SST39VF320 */ - .pri_id = 0x02, - .dev_size = 4*MB, - .interface_desc = 0x2, /* x8 or x16 device with nBYTE */ - .max_buf_write_size = 0x0, - .status_poll_mask = CFI_STATUS_POLL_MASK_DQ6_DQ7, - .num_erase_regions = 1, - .erase_region_info = { - ERASE_REGION(1024, 4*KB) - } - }, - { - .mfr = CFI_MFR_SST, - .id = 0x234b, /* SST39VF1601 */ - .pri_id = 0x02, - .dev_size = 2*MB, - .interface_desc = 0x2, /* x8 or x16 device with nBYTE */ - .max_buf_write_size = 0x0, - .status_poll_mask = CFI_STATUS_POLL_MASK_DQ6_DQ7, - .num_erase_regions = 1, - .erase_region_info = { - ERASE_REGION(512, 4*KB) - } - }, - { - .mfr = CFI_MFR_SST, - .id = 0x274b, /* SST39WF1601 */ - .pri_id = 0x02, - .dev_size = 2*MB, - .interface_desc = 0x2, /* x8 or x16 device with nBYTE */ - .max_buf_write_size = 0x0, - .status_poll_mask = CFI_STATUS_POLL_MASK_DQ6_DQ7, - .num_erase_regions = 1, - .erase_region_info = { - ERASE_REGION(512, 4*KB) - } - }, - { - .mfr = CFI_MFR_SST, - .id = 0x234a, /* SST39VF1602 */ - .pri_id = 0x02, - .dev_size = 2*MB, - .interface_desc = 0x2, /* x8 or x16 device with nBYTE */ - .max_buf_write_size = 0x0, - .status_poll_mask = CFI_STATUS_POLL_MASK_DQ6_DQ7, - .num_erase_regions = 1, - .erase_region_info = { - ERASE_REGION(512, 4*KB) - } - }, - { - .mfr = CFI_MFR_SST, - .id = 0x235b, /* SST39VF3201 */ - .pri_id = 0x02, - .dev_size = 4*MB, - .interface_desc = 0x2, /* x8 or x16 device with nBYTE */ - .max_buf_write_size = 0x0, - .status_poll_mask = CFI_STATUS_POLL_MASK_DQ6_DQ7, - .num_erase_regions = 1, - .erase_region_info = { - ERASE_REGION(1024, 4*KB) - } - }, - { - .mfr = CFI_MFR_SST, - .id = 0x235a, /* SST39VF3202 */ - .pri_id = 0x02, - .dev_size = 4*MB, - .interface_desc = 0x2, /* x8 or x16 device with nBYTE */ - .max_buf_write_size = 0x0, - .status_poll_mask = CFI_STATUS_POLL_MASK_DQ6_DQ7, - .num_erase_regions = 1, - .erase_region_info = { - ERASE_REGION(1024, 4*KB) - } - }, - { - .mfr = CFI_MFR_SST, - .id = 0x236d, /* SST39VF6401B */ - .pri_id = 0x02, - .dev_size = 8*MB, - .interface_desc = 0x2, /* x8 or x16 device with nBYTE */ - .max_buf_write_size = 0x0, - .status_poll_mask = CFI_STATUS_POLL_MASK_DQ6_DQ7, - .num_erase_regions = 1, - .erase_region_info = { - ERASE_REGION(2048, 4*KB) - } - }, - { - .mfr = CFI_MFR_AMD, - .id = 0x22ab, /* AM29F400BB */ - .pri_id = 0x02, - .dev_size = 512*KB, - .interface_desc = 0x2, /* x8 or x16 device with nBYTE */ - .max_buf_write_size = 0x0, - .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7, - .num_erase_regions = 4, - .erase_region_info = { - ERASE_REGION(1, 16*KB), - ERASE_REGION(2, 8*KB), - ERASE_REGION(1, 32*KB), - ERASE_REGION(7, 64*KB) - } - }, - { - .mfr = CFI_MFR_AMD, - .id = 0x2223, /* AM29F400BT */ - .pri_id = 0x02, - .dev_size = 512*KB, - .interface_desc = 0x2, /* x8 or x16 device with nBYTE */ - .max_buf_write_size = 0x0, - .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7, - .num_erase_regions = 4, - .erase_region_info = { - ERASE_REGION(7, 64*KB), - ERASE_REGION(1, 32*KB), - ERASE_REGION(2, 8*KB), - ERASE_REGION(1, 16*KB) - } - }, - { - .mfr = CFI_MFR_FUJITSU, - .id = 0x226b, /* AM29SL800DB */ - .pri_id = 0x02, - .dev_size = 1*MB, - .interface_desc = 0x2, /* x8 or x16 device with nBYTE */ - .max_buf_write_size = 0x0, - .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7, - .num_erase_regions = 4, - .erase_region_info = { - ERASE_REGION(1, 16*KB), - ERASE_REGION(2, 8*KB), - ERASE_REGION(1, 32*KB), - ERASE_REGION(15, 64*KB) - } - }, - { - .mfr = CFI_MFR_FUJITSU, - .id = 0x22ea, /* MBM29SL800TE */ - .pri_id = 0x02, - .dev_size = 1*MB, - .interface_desc = 0x2, /* x8 or x16 device with nBYTE */ - .max_buf_write_size = 0x0, - .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7, - .num_erase_regions = 4, - .erase_region_info = { - ERASE_REGION(15, 64*KB), - ERASE_REGION(1, 32*KB), - ERASE_REGION(2, 8*KB), - ERASE_REGION(1, 16*KB) - } - }, - { - .mfr = CFI_MFR_FUJITSU, - .id = 0xba, /* 29LV400BC */ - .pri_id = 0x02, - .dev_size = 512*KB, - .interface_desc = 0x1, /* x8 or x16 device w/ nBYTE */ - .max_buf_write_size = 0x00, - .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7, - .num_erase_regions = 4, - .erase_region_info = { - ERASE_REGION(1, 16*KB), - ERASE_REGION(2, 8*KB), - ERASE_REGION(1, 32*KB), - ERASE_REGION(7, 64*KB) - } - }, - { - .mfr = CFI_MFR_AMIC, - .id = 0xb31a, /* A29L800A */ - .pri_id = 0x02, - .dev_size = 1*MB, - .interface_desc = 0x2, - .max_buf_write_size = 0x0, - .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7, - .num_erase_regions = 4, - .erase_region_info = { - ERASE_REGION(1, 16*KB), - ERASE_REGION(2, 8*KB), - ERASE_REGION(1, 32*KB), - ERASE_REGION(15, 64*KB) - } - }, - { - .mfr = CFI_MFR_MX, - .id = 0x225b, /* MX29LV800B */ - .pri_id = 0x02, - .dev_size = 1*MB, - .interface_desc = 0x2, /* x8 or x16 device with nBYTE */ - .max_buf_write_size = 0x0, - .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7, - .num_erase_regions = 4, - .erase_region_info = { - ERASE_REGION(1, 16*KB), - ERASE_REGION(2, 8*KB), - ERASE_REGION(1, 32*KB), - ERASE_REGION(15, 64*KB) - } - }, - - { - .mfr = CFI_MFR_MX, - .id = 0x2249, /* MX29LV160AB: 2MB */ - .pri_id = 0x02, - .dev_size = 2*MB, - .interface_desc = 0x2, /* x8 or x16 device with nBYTE */ - .max_buf_write_size = 0x0, - .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7, - .num_erase_regions = 4, - .erase_region_info = { - ERASE_REGION(1, 16*KB), - ERASE_REGION(2, 8*KB), - ERASE_REGION(1, 32*KB), - ERASE_REGION(31, 64*KB) - } - }, - { - .mfr = CFI_MFR_MX, - .id = 0x22C4, /* MX29LV160AT: 2MB */ - .pri_id = 0x02, - .dev_size = 2*MB, - .interface_desc = 0x2, /* x8 or x16 device with nBYTE */ - .max_buf_write_size = 0x0, - .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7, - .num_erase_regions = 4, - .erase_region_info = { - ERASE_REGION(31, 64*KB), - ERASE_REGION(1, 32*KB), - ERASE_REGION(2, 8*KB), - ERASE_REGION(1, 16*KB) - } - }, - { - .mfr = CFI_MFR_EON, - .id = 0x225b, /* EN29LV800BB */ - .pri_id = 0x02, - .dev_size = 1*MB, - .interface_desc = 0x2, /* x8 or x16 device with nBYTE */ - .max_buf_write_size = 0x0, - .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7, - .num_erase_regions = 4, - .erase_region_info = { - ERASE_REGION(1, 16*KB), - ERASE_REGION(2, 8*KB), - ERASE_REGION(1, 32*KB), - ERASE_REGION(15, 64*KB) - } - }, - { - .mfr = CFI_MFR_ATMEL, - .id = 0x00c0, /* Atmel 49BV1614 */ - .pri_id = 0x02, - .dev_size = 2*MB, - .interface_desc = 0x2, /* x8 or x16 device with nBYTE */ - .max_buf_write_size = 0x0, - .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7, - .num_erase_regions = 3, - .erase_region_info = { - ERASE_REGION(8, 8*KB), - ERASE_REGION(2, 32*KB), - ERASE_REGION(30, 64*KB) - } - }, - { - .mfr = CFI_MFR_ATMEL, - .id = 0xC2, /* Atmel 49BV1614T */ - .pri_id = 0x02, - .dev_size = 2*MB, - .interface_desc = 0x2, /* x8 or x16 device with nBYTE */ - .max_buf_write_size = 0x0, - .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7, - .num_erase_regions = 3, - .erase_region_info = { - ERASE_REGION(30, 64*KB), - ERASE_REGION(2, 32*KB), - ERASE_REGION(8, 8*KB) - } - }, - { - .mfr = CFI_MFR_AMD, - .id = 0x225b, /* S29AL008D */ - .pri_id = 0x02, - .dev_size = 1*MB, - .interface_desc = 0x2, /* x8 or x16 device with nBYTE */ - .max_buf_write_size = 0x0, - .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7, - .num_erase_regions = 4, - .erase_region_info = { - ERASE_REGION(1, 16*KB), - ERASE_REGION(2, 8*KB), - ERASE_REGION(1, 32*KB), - ERASE_REGION(15, 64*KB) - } - }, - { - .mfr = 0, - .id = 0, - } -}; - -void cfi_fixup_non_cfi(struct flash_bank *bank) -{ - unsigned int mask; - struct cfi_flash_bank *cfi_info = bank->driver_priv; - const struct non_cfi *non_cfi = non_cfi_flashes; - - if (cfi_info->x16_as_x8) - mask = 0xFF; - else - mask = 0xFFFF; - - for (non_cfi = non_cfi_flashes; non_cfi->mfr; non_cfi++) { - if ((cfi_info->manufacturer == non_cfi->mfr) - && (cfi_info->device_id == (non_cfi->id & mask))) - break; - } - - /* only fixup jedec flashs found in table */ - if (!non_cfi->mfr) - return; - - cfi_info->not_cfi = 1; - - /* fill in defaults for non-critical data */ - cfi_info->vcc_min = 0x0; - cfi_info->vcc_max = 0x0; - cfi_info->vpp_min = 0x0; - cfi_info->vpp_max = 0x0; - /* these are used for timeouts - use vales that should be long enough - for normal operation. */ - cfi_info->word_write_timeout_typ = 0x0a; - cfi_info->buf_write_timeout_typ = 0x0d; - cfi_info->block_erase_timeout_typ = 0x0d; - cfi_info->chip_erase_timeout_typ = 0x10; - cfi_info->word_write_timeout_max = 0x0; - cfi_info->buf_write_timeout_max = 0x0; - cfi_info->block_erase_timeout_max = 0x0; - cfi_info->chip_erase_timeout_max = 0x0; - - cfi_info->qry[0] = 'Q'; - cfi_info->qry[1] = 'R'; - cfi_info->qry[2] = 'Y'; - - cfi_info->pri_id = non_cfi->pri_id; - cfi_info->pri_addr = 0x0; - cfi_info->alt_id = 0x0; - cfi_info->alt_addr = 0x0; - cfi_info->alt_ext = NULL; - - cfi_info->interface_desc = non_cfi->interface_desc; - cfi_info->max_buf_write_size = non_cfi->max_buf_write_size; - cfi_info->status_poll_mask = non_cfi->status_poll_mask; - cfi_info->num_erase_regions = non_cfi->num_erase_regions; - size_t erase_region_info_size = sizeof(*cfi_info->erase_region_info) * - cfi_info->num_erase_regions; - cfi_info->erase_region_info = malloc(erase_region_info_size); - memcpy(cfi_info->erase_region_info, - non_cfi->erase_region_info, erase_region_info_size); - cfi_info->dev_size = non_cfi->dev_size; - - if (cfi_info->pri_id == 0x2) { - struct cfi_spansion_pri_ext *pri_ext = malloc(sizeof(struct cfi_spansion_pri_ext)); - - pri_ext->pri[0] = 'P'; - pri_ext->pri[1] = 'R'; - pri_ext->pri[2] = 'I'; - - pri_ext->major_version = '1'; - pri_ext->minor_version = '0'; - - pri_ext->SiliconRevision = 0x0; - pri_ext->EraseSuspend = 0x0; - pri_ext->BlkProt = 0x0; - pri_ext->TmpBlkUnprotect = 0x0; - pri_ext->BlkProtUnprot = 0x0; - pri_ext->SimultaneousOps = 0x0; - pri_ext->BurstMode = 0x0; - pri_ext->PageMode = 0x0; - pri_ext->VppMin = 0x0; - pri_ext->VppMax = 0x0; - pri_ext->TopBottom = 0x0; - - pri_ext->_unlock1 = 0x5555; - pri_ext->_unlock2 = 0x2AAA; - pri_ext->_reversed_geometry = 0; - - cfi_info->pri_ext = pri_ext; - } else if ((cfi_info->pri_id == 0x1) || (cfi_info->pri_id == 0x3)) { - LOG_ERROR("BUG: non-CFI flashes using the Intel commandset are not yet supported"); - exit(-1); - } -} diff --git a/src/flash/nor/non_cfi.h b/src/flash/nor/non_cfi.h deleted file mode 100644 index c411cb885..000000000 --- a/src/flash/nor/non_cfi.h +++ /dev/null @@ -1,36 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifndef OPENOCD_FLASH_NOR_NON_CFI_H -#define OPENOCD_FLASH_NOR_NON_CFI_H - -struct non_cfi { - uint16_t mfr; - uint16_t id; - uint16_t pri_id; - uint32_t dev_size; - uint16_t interface_desc; - uint16_t max_buf_write_size; - uint8_t num_erase_regions; - uint32_t erase_region_info[6]; - uint8_t status_poll_mask; -}; - -void cfi_fixup_non_cfi(struct flash_bank *bank); - -#endif /* OPENOCD_FLASH_NOR_NON_CFI_H */ diff --git a/src/flash/nor/nrf51.c b/src/flash/nor/nrf51.c deleted file mode 100644 index 69bf66616..000000000 --- a/src/flash/nor/nrf51.c +++ /dev/null @@ -1,1334 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2013 Synapse Product Development * - * Andrey Smirnov * - * Angus Gratton * - * Erdem U. Altunyurt * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 -#include "config.h" -#endif - -#include "imp.h" -#include -#include -#include - -enum { - NRF51_FLASH_BASE = 0x00000000, -}; - -enum nrf51_ficr_registers { - NRF51_FICR_BASE = 0x10000000, /* Factory Information Configuration Registers */ - -#define NRF51_FICR_REG(offset) (NRF51_FICR_BASE + offset) - - NRF51_FICR_CODEPAGESIZE = NRF51_FICR_REG(0x010), - NRF51_FICR_CODESIZE = NRF51_FICR_REG(0x014), - NRF51_FICR_CLENR0 = NRF51_FICR_REG(0x028), - NRF51_FICR_PPFC = NRF51_FICR_REG(0x02C), - NRF51_FICR_NUMRAMBLOCK = NRF51_FICR_REG(0x034), - NRF51_FICR_SIZERAMBLOCK0 = NRF51_FICR_REG(0x038), - NRF51_FICR_SIZERAMBLOCK1 = NRF51_FICR_REG(0x03C), - NRF51_FICR_SIZERAMBLOCK2 = NRF51_FICR_REG(0x040), - NRF51_FICR_SIZERAMBLOCK3 = NRF51_FICR_REG(0x044), - NRF51_FICR_CONFIGID = NRF51_FICR_REG(0x05C), - NRF51_FICR_DEVICEID0 = NRF51_FICR_REG(0x060), - NRF51_FICR_DEVICEID1 = NRF51_FICR_REG(0x064), - NRF51_FICR_ER0 = NRF51_FICR_REG(0x080), - NRF51_FICR_ER1 = NRF51_FICR_REG(0x084), - NRF51_FICR_ER2 = NRF51_FICR_REG(0x088), - NRF51_FICR_ER3 = NRF51_FICR_REG(0x08C), - NRF51_FICR_IR0 = NRF51_FICR_REG(0x090), - NRF51_FICR_IR1 = NRF51_FICR_REG(0x094), - NRF51_FICR_IR2 = NRF51_FICR_REG(0x098), - NRF51_FICR_IR3 = NRF51_FICR_REG(0x09C), - NRF51_FICR_DEVICEADDRTYPE = NRF51_FICR_REG(0x0A0), - NRF51_FICR_DEVICEADDR0 = NRF51_FICR_REG(0x0A4), - NRF51_FICR_DEVICEADDR1 = NRF51_FICR_REG(0x0A8), - NRF51_FICR_OVERRIDEN = NRF51_FICR_REG(0x0AC), - NRF51_FICR_NRF_1MBIT0 = NRF51_FICR_REG(0x0B0), - NRF51_FICR_NRF_1MBIT1 = NRF51_FICR_REG(0x0B4), - NRF51_FICR_NRF_1MBIT2 = NRF51_FICR_REG(0x0B8), - NRF51_FICR_NRF_1MBIT3 = NRF51_FICR_REG(0x0BC), - NRF51_FICR_NRF_1MBIT4 = NRF51_FICR_REG(0x0C0), - NRF51_FICR_BLE_1MBIT0 = NRF51_FICR_REG(0x0EC), - NRF51_FICR_BLE_1MBIT1 = NRF51_FICR_REG(0x0F0), - NRF51_FICR_BLE_1MBIT2 = NRF51_FICR_REG(0x0F4), - NRF51_FICR_BLE_1MBIT3 = NRF51_FICR_REG(0x0F8), - NRF51_FICR_BLE_1MBIT4 = NRF51_FICR_REG(0x0FC), -}; - -enum nrf51_uicr_registers { - NRF51_UICR_BASE = 0x10001000, /* User Information - * Configuration Regsters */ - - NRF51_UICR_SIZE = 0x100, - -#define NRF51_UICR_REG(offset) (NRF51_UICR_BASE + offset) - - NRF51_UICR_CLENR0 = NRF51_UICR_REG(0x000), - NRF51_UICR_RBPCONF = NRF51_UICR_REG(0x004), - NRF51_UICR_XTALFREQ = NRF51_UICR_REG(0x008), - NRF51_UICR_FWID = NRF51_UICR_REG(0x010), -}; - -enum nrf51_nvmc_registers { - NRF51_NVMC_BASE = 0x4001E000, /* Non-Volatile Memory - * Controller Regsters */ - -#define NRF51_NVMC_REG(offset) (NRF51_NVMC_BASE + offset) - - NRF51_NVMC_READY = NRF51_NVMC_REG(0x400), - NRF51_NVMC_CONFIG = NRF51_NVMC_REG(0x504), - NRF51_NVMC_ERASEPAGE = NRF51_NVMC_REG(0x508), - NRF51_NVMC_ERASEALL = NRF51_NVMC_REG(0x50C), - NRF51_NVMC_ERASEUICR = NRF51_NVMC_REG(0x514), -}; - -enum nrf51_nvmc_config_bits { - NRF51_NVMC_CONFIG_REN = 0x00, - NRF51_NVMC_CONFIG_WEN = 0x01, - NRF51_NVMC_CONFIG_EEN = 0x02, - -}; - -struct nrf51_info { - uint32_t code_page_size; - uint32_t code_memory_size; - - struct { - bool probed; - int (*write) (struct flash_bank *bank, - struct nrf51_info *chip, - const uint8_t *buffer, uint32_t offset, uint32_t count); - } bank[2]; - struct target *target; -}; - -struct nrf51_device_spec { - uint16_t hwid; - const char *variant; - const char *build_code; - unsigned int flash_size_kb; -}; - -/* The known devices table below is derived from the "nRF51 Series - * Compatibility Matrix" document, which can be found by searching for - * ATTN-51 on the Nordic Semi website: - * - * http://www.nordicsemi.com/eng/content/search?SearchText=ATTN-51 - * - * Up to date with Matrix v2.0, plus some additional HWIDs. - * - * The additional HWIDs apply where the build code in the matrix is - * shown as Gx0, Bx0, etc. In these cases the HWID in the matrix is - * for x==0, x!=0 means different (unspecified) HWIDs. - */ -static const struct nrf51_device_spec nrf51_known_devices_table[] = { - /* nRF51822 Devices (IC rev 1). */ - { - .hwid = 0x001D, - .variant = "QFAA", - .build_code = "CA/C0", - .flash_size_kb = 256, - }, - { - .hwid = 0x0026, - .variant = "QFAB", - .build_code = "AA", - .flash_size_kb = 128, - }, - { - .hwid = 0x0027, - .variant = "QFAB", - .build_code = "A0", - .flash_size_kb = 128, - }, - { - .hwid = 0x0020, - .variant = "CEAA", - .build_code = "BA", - .flash_size_kb = 256, - }, - { - .hwid = 0x002F, - .variant = "CEAA", - .build_code = "B0", - .flash_size_kb = 256, - }, - - /* nRF51822 Devices (IC rev 2). */ - { - .hwid = 0x002A, - .variant = "QFAA", - .build_code = "FA0", - .flash_size_kb = 256, - }, - { - .hwid = 0x0044, - .variant = "QFAA", - .build_code = "GC0", - .flash_size_kb = 256, - }, - { - .hwid = 0x003C, - .variant = "QFAA", - .build_code = "G0", - .flash_size_kb = 256, - }, - { - .hwid = 0x0057, - .variant = "QFAA", - .build_code = "G2", - .flash_size_kb = 256, - }, - { - .hwid = 0x0058, - .variant = "QFAA", - .build_code = "G3", - .flash_size_kb = 256, - }, - { - .hwid = 0x004C, - .variant = "QFAB", - .build_code = "B0", - .flash_size_kb = 128, - }, - { - .hwid = 0x0040, - .variant = "CEAA", - .build_code = "CA0", - .flash_size_kb = 256, - }, - { - .hwid = 0x0047, - .variant = "CEAA", - .build_code = "DA0", - .flash_size_kb = 256, - }, - { - .hwid = 0x004D, - .variant = "CEAA", - .build_code = "D00", - .flash_size_kb = 256, - }, - - /* nRF51822 Devices (IC rev 3). */ - { - .hwid = 0x0072, - .variant = "QFAA", - .build_code = "H0", - .flash_size_kb = 256, - }, - { - .hwid = 0x007B, - .variant = "QFAB", - .build_code = "C0", - .flash_size_kb = 128, - }, - { - .hwid = 0x0083, - .variant = "QFAC", - .build_code = "A0", - .flash_size_kb = 256, - }, - { - .hwid = 0x0084, - .variant = "QFAC", - .build_code = "A1", - .flash_size_kb = 256, - }, - { - .hwid = 0x007D, - .variant = "CDAB", - .build_code = "A0", - .flash_size_kb = 128, - }, - { - .hwid = 0x0079, - .variant = "CEAA", - .build_code = "E0", - .flash_size_kb = 256, - }, - { - .hwid = 0x0087, - .variant = "CFAC", - .build_code = "A0", - .flash_size_kb = 256, - }, - - /* nRF51422 Devices (IC rev 1). */ - { - .hwid = 0x001E, - .variant = "QFAA", - .build_code = "CA", - .flash_size_kb = 256, - }, - { - .hwid = 0x0024, - .variant = "QFAA", - .build_code = "C0", - .flash_size_kb = 256, - }, - { - .hwid = 0x0031, - .variant = "CEAA", - .build_code = "A0A", - .flash_size_kb = 256, - }, - - /* nRF51422 Devices (IC rev 2). */ - { - .hwid = 0x002D, - .variant = "QFAA", - .build_code = "DAA", - .flash_size_kb = 256, - }, - { - .hwid = 0x002E, - .variant = "QFAA", - .build_code = "E0", - .flash_size_kb = 256, - }, - { - .hwid = 0x0061, - .variant = "QFAB", - .build_code = "A00", - .flash_size_kb = 128, - }, - { - .hwid = 0x0050, - .variant = "CEAA", - .build_code = "B0", - .flash_size_kb = 256, - }, - - /* nRF51422 Devices (IC rev 3). */ - { - .hwid = 0x0073, - .variant = "QFAA", - .build_code = "F0", - .flash_size_kb = 256, - }, - { - .hwid = 0x007C, - .variant = "QFAB", - .build_code = "B0", - .flash_size_kb = 128, - }, - { - .hwid = 0x0085, - .variant = "QFAC", - .build_code = "A0", - .flash_size_kb = 256, - }, - { - .hwid = 0x0086, - .variant = "QFAC", - .build_code = "A1", - .flash_size_kb = 256, - }, - { - .hwid = 0x007E, - .variant = "CDAB", - .build_code = "A0", - .flash_size_kb = 128, - }, - { - .hwid = 0x007A, - .variant = "CEAA", - .build_code = "C0", - .flash_size_kb = 256, - }, - { - .hwid = 0x0088, - .variant = "CFAC", - .build_code = "A0", - .flash_size_kb = 256, - }, - - /* Some early nRF51-DK (PCA10028) & nRF51-Dongle (PCA10031) boards - with built-in jlink seem to use engineering samples not listed - in the nRF51 Series Compatibility Matrix V1.0. */ - { - .hwid = 0x0071, - .variant = "QFAC", - .build_code = "AB", - .flash_size_kb = 256, - }, -}; - -static int nrf51_bank_is_probed(struct flash_bank *bank) -{ - struct nrf51_info *chip = bank->driver_priv; - - assert(chip != NULL); - - return chip->bank[bank->bank_number].probed; -} -static int nrf51_probe(struct flash_bank *bank); - -static int nrf51_get_probed_chip_if_halted(struct flash_bank *bank, struct nrf51_info **chip) -{ - if (bank->target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - *chip = bank->driver_priv; - - int probed = nrf51_bank_is_probed(bank); - if (probed < 0) - return probed; - else if (!probed) - return nrf51_probe(bank); - else - return ERROR_OK; -} - -static int nrf51_wait_for_nvmc(struct nrf51_info *chip) -{ - uint32_t ready; - int res; - int timeout = 100; - - do { - res = target_read_u32(chip->target, NRF51_NVMC_READY, &ready); - if (res != ERROR_OK) { - LOG_ERROR("Couldn't read NVMC_READY register"); - return res; - } - - if (ready == 0x00000001) - return ERROR_OK; - - alive_sleep(1); - } while (timeout--); - - LOG_DEBUG("Timed out waiting for NVMC_READY"); - return ERROR_FLASH_BUSY; -} - -static int nrf51_nvmc_erase_enable(struct nrf51_info *chip) -{ - int res; - res = target_write_u32(chip->target, - NRF51_NVMC_CONFIG, - NRF51_NVMC_CONFIG_EEN); - - if (res != ERROR_OK) { - LOG_ERROR("Failed to enable erase operation"); - return res; - } - - /* - According to NVMC examples in Nordic SDK busy status must be - checked after writing to NVMC_CONFIG - */ - res = nrf51_wait_for_nvmc(chip); - if (res != ERROR_OK) - LOG_ERROR("Erase enable did not complete"); - - return res; -} - -static int nrf51_nvmc_write_enable(struct nrf51_info *chip) -{ - int res; - res = target_write_u32(chip->target, - NRF51_NVMC_CONFIG, - NRF51_NVMC_CONFIG_WEN); - - if (res != ERROR_OK) { - LOG_ERROR("Failed to enable write operation"); - return res; - } - - /* - According to NVMC examples in Nordic SDK busy status must be - checked after writing to NVMC_CONFIG - */ - res = nrf51_wait_for_nvmc(chip); - if (res != ERROR_OK) - LOG_ERROR("Write enable did not complete"); - - return res; -} - -static int nrf51_nvmc_read_only(struct nrf51_info *chip) -{ - int res; - res = target_write_u32(chip->target, - NRF51_NVMC_CONFIG, - NRF51_NVMC_CONFIG_REN); - - if (res != ERROR_OK) { - LOG_ERROR("Failed to enable read-only operation"); - return res; - } - /* - According to NVMC examples in Nordic SDK busy status must be - checked after writing to NVMC_CONFIG - */ - res = nrf51_wait_for_nvmc(chip); - if (res != ERROR_OK) - LOG_ERROR("Read only enable did not complete"); - - return res; -} - -static int nrf51_nvmc_generic_erase(struct nrf51_info *chip, - uint32_t erase_register, uint32_t erase_value) -{ - int res; - - res = nrf51_nvmc_erase_enable(chip); - if (res != ERROR_OK) - goto error; - - res = target_write_u32(chip->target, - erase_register, - erase_value); - if (res != ERROR_OK) - goto set_read_only; - - res = nrf51_wait_for_nvmc(chip); - if (res != ERROR_OK) - goto set_read_only; - - return nrf51_nvmc_read_only(chip); - -set_read_only: - nrf51_nvmc_read_only(chip); -error: - LOG_ERROR("Failed to erase reg: 0x%08"PRIx32" val: 0x%08"PRIx32, - erase_register, erase_value); - return ERROR_FAIL; -} - -static int nrf51_protect_check(struct flash_bank *bank) -{ - int res; - uint32_t clenr0; - - /* UICR cannot be write protected so just return early */ - if (bank->base == NRF51_UICR_BASE) - return ERROR_OK; - - struct nrf51_info *chip = bank->driver_priv; - - assert(chip != NULL); - - res = target_read_u32(chip->target, NRF51_FICR_CLENR0, - &clenr0); - if (res != ERROR_OK) { - LOG_ERROR("Couldn't read code region 0 size[FICR]"); - return res; - } - - if (clenr0 == 0xFFFFFFFF) { - res = target_read_u32(chip->target, NRF51_UICR_CLENR0, - &clenr0); - if (res != ERROR_OK) { - LOG_ERROR("Couldn't read code region 0 size[UICR]"); - return res; - } - } - - for (int i = 0; i < bank->num_sectors; i++) - bank->sectors[i].is_protected = - clenr0 != 0xFFFFFFFF && bank->sectors[i].offset < clenr0; - - return ERROR_OK; -} - -static int nrf51_protect(struct flash_bank *bank, int set, int first, int last) -{ - int res; - uint32_t clenr0, ppfc; - struct nrf51_info *chip; - - /* UICR cannot be write protected so just bail out early */ - if (bank->base == NRF51_UICR_BASE) - return ERROR_FAIL; - - res = nrf51_get_probed_chip_if_halted(bank, &chip); - if (res != ERROR_OK) - return res; - - if (first != 0) { - LOG_ERROR("Code region 0 must start at the begining of the bank"); - return ERROR_FAIL; - } - - res = target_read_u32(chip->target, NRF51_FICR_PPFC, - &ppfc); - if (res != ERROR_OK) { - LOG_ERROR("Couldn't read PPFC register"); - return res; - } - - 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); - if (res != ERROR_OK) { - LOG_ERROR("Couldn't read code region 0 size[UICR]"); - return res; - } - - if (clenr0 == 0xFFFFFFFF) { - res = target_write_u32(chip->target, NRF51_UICR_CLENR0, - clenr0); - if (res != ERROR_OK) { - LOG_ERROR("Couldn't write code region 0 size[UICR]"); - return res; - } - - } else { - LOG_ERROR("You need to perform chip erase before changing the protection settings"); - } - - nrf51_protect_check(bank); - - return ERROR_OK; -} - -static int nrf51_probe(struct flash_bank *bank) -{ - uint32_t hwid; - int res; - struct nrf51_info *chip = bank->driver_priv; - - res = target_read_u32(chip->target, NRF51_FICR_CONFIGID, &hwid); - if (res != ERROR_OK) { - LOG_ERROR("Couldn't read CONFIGID register"); - return res; - } - - hwid &= 0xFFFF; /* HWID is stored in the lower two - * 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++) - 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); - else - LOG_WARNING("Unknown device (HWID 0x%08" PRIx32 ")", hwid); - } - - - if (bank->base == NRF51_FLASH_BASE) { - res = target_read_u32(chip->target, NRF51_FICR_CODEPAGESIZE, - &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); - 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->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) - return ERROR_FLASH_BANK_NOT_PROBED; - - /* Fill out the sector information: all NRF51 sectors are the same size and - * there is always a fixed number of them. */ - for (int i = 0; i < bank->num_sectors; i++) { - bank->sectors[i].size = chip->code_page_size; - bank->sectors[i].offset = i * chip->code_page_size; - - /* mark as unknown */ - bank->sectors[i].is_erased = -1; - bank->sectors[i].is_protected = -1; - } - - nrf51_protect_check(bank); - - chip->bank[0].probed = true; - } else { - bank->size = NRF51_UICR_SIZE; - bank->num_sectors = 1; - bank->sectors = calloc(bank->num_sectors, - sizeof((bank->sectors)[0])); - if (!bank->sectors) - return ERROR_FLASH_BANK_NOT_PROBED; - - bank->sectors[0].size = bank->size; - bank->sectors[0].offset = 0; - - /* mark as unknown */ - bank->sectors[0].is_erased = 0; - bank->sectors[0].is_protected = 0; - - chip->bank[1].probed = true; - } - - return ERROR_OK; -} - -static int nrf51_auto_probe(struct flash_bank *bank) -{ - int probed = nrf51_bank_is_probed(bank); - - if (probed < 0) - return probed; - else if (probed) - return ERROR_OK; - else - return nrf51_probe(bank); -} - -static struct flash_sector *nrf51_find_sector_by_address(struct flash_bank *bank, uint32_t address) -{ - struct nrf51_info *chip = bank->driver_priv; - - for (int i = 0; i < bank->num_sectors; i++) - if (bank->sectors[i].offset <= address && - address < (bank->sectors[i].offset + chip->code_page_size)) - return &bank->sectors[i]; - return NULL; -} - -static int nrf51_erase_all(struct nrf51_info *chip) -{ - LOG_DEBUG("Erasing all non-volatile memory"); - return nrf51_nvmc_generic_erase(chip, - NRF51_NVMC_ERASEALL, - 0x00000001); -} - -static int nrf51_erase_page(struct flash_bank *bank, - struct nrf51_info *chip, - struct flash_sector *sector) -{ - int res; - - LOG_DEBUG("Erasing page at 0x%"PRIx32, sector->offset); - if (sector->is_protected) { - LOG_ERROR("Cannot erase protected sector at 0x%" PRIx32, sector->offset); - return ERROR_FAIL; - } - - if (bank->base == NRF51_UICR_BASE) { - uint32_t ppfc; - res = target_read_u32(chip->target, NRF51_FICR_PPFC, - &ppfc); - if (res != ERROR_OK) { - LOG_ERROR("Couldn't read PPFC register"); - return res; - } - - if ((ppfc & 0xFF) == 0xFF) { - /* We can't erase the UICR. Double-check to - see if it's already erased before complaining. */ - default_flash_blank_check(bank); - if (sector->is_erased == 1) - return ERROR_OK; - - 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, - 0x00000001); - - - } else { - res = nrf51_nvmc_generic_erase(chip, - NRF51_NVMC_ERASEPAGE, - sector->offset); - } - - if (res == ERROR_OK) - sector->is_erased = 1; - - return res; -} - -static const uint8_t nrf51_flash_write_code[] = { - /* See contrib/loaders/flash/cortex-m0.S */ -/* : */ - 0x0d, 0x68, /* ldr r5, [r1, #0] */ - 0x00, 0x2d, /* cmp r5, #0 */ - 0x0b, 0xd0, /* beq.n 1e */ - 0x4c, 0x68, /* ldr r4, [r1, #4] */ - 0xac, 0x42, /* cmp r4, r5 */ - 0xf9, 0xd0, /* beq.n 0 */ - 0x20, 0xcc, /* ldmia r4!, {r5} */ - 0x20, 0xc3, /* stmia r3!, {r5} */ - 0x94, 0x42, /* cmp r4, r2 */ - 0x01, 0xd3, /* bcc.n 18 */ - 0x0c, 0x46, /* mov r4, r1 */ - 0x08, 0x34, /* adds r4, #8 */ -/* : */ - 0x4c, 0x60, /* str r4, [r1, #4] */ - 0x04, 0x38, /* subs r0, #4 */ - 0xf0, 0xd1, /* bne.n 0 */ -/* : */ - 0x00, 0xbe /* bkpt 0x0000 */ -}; - - -/* Start a low level flash write for the specified region */ -static int nrf51_ll_flash_write(struct nrf51_info *chip, uint32_t offset, const uint8_t *buffer, uint32_t bytes) -{ - struct target *target = chip->target; - uint32_t buffer_size = 8192; - struct working_area *write_algorithm; - struct working_area *source; - uint32_t address = NRF51_FLASH_BASE + offset; - struct reg_param reg_params[4]; - struct armv7m_algorithm armv7m_info; - int retval = ERROR_OK; - - - LOG_DEBUG("Writing buffer to flash offset=0x%"PRIx32" bytes=0x%"PRIx32, offset, bytes); - assert(bytes % 4 == 0); - - /* allocate working area with flash programming code */ - if (target_alloc_working_area(target, sizeof(nrf51_flash_write_code), - &write_algorithm) != ERROR_OK) { - LOG_WARNING("no working area available, falling back to slow memory writes"); - - for (; bytes > 0; bytes -= 4) { - retval = target_write_memory(chip->target, offset, 4, 1, buffer); - if (retval != ERROR_OK) - return retval; - - retval = nrf51_wait_for_nvmc(chip); - if (retval != ERROR_OK) - return retval; - - offset += 4; - buffer += 4; - } - - return ERROR_OK; - } - - LOG_WARNING("using fast async flash loader. This is currently supported"); - LOG_WARNING("only with ST-Link and CMSIS-DAP. If you have issues, add"); - LOG_WARNING("\"set WORKAREASIZE 0\" before sourcing nrf51.cfg to disable it"); - - retval = target_write_buffer(target, write_algorithm->address, - sizeof(nrf51_flash_write_code), - nrf51_flash_write_code); - if (retval != ERROR_OK) - return retval; - - /* memory buffer */ - while (target_alloc_working_area(target, buffer_size, &source) != ERROR_OK) { - buffer_size /= 2; - buffer_size &= ~3UL; /* Make sure it's 4 byte aligned */ - if (buffer_size <= 256) { - /* free working area, write algorithm already allocated */ - target_free_working_area(target, write_algorithm); - - 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; - - init_reg_param(®_params[0], "r0", 32, PARAM_IN_OUT); /* byte count */ - init_reg_param(®_params[1], "r1", 32, PARAM_OUT); /* buffer start */ - init_reg_param(®_params[2], "r2", 32, PARAM_OUT); /* buffer end */ - init_reg_param(®_params[3], "r3", 32, PARAM_IN_OUT); /* target address */ - - buf_set_u32(reg_params[0].value, 0, 32, bytes); - buf_set_u32(reg_params[1].value, 0, 32, source->address); - buf_set_u32(reg_params[2].value, 0, 32, source->address + source->size); - buf_set_u32(reg_params[3].value, 0, 32, address); - - retval = target_run_flash_async_algorithm(target, buffer, bytes/4, 4, - 0, NULL, - 4, reg_params, - source->address, source->size, - write_algorithm->address, 0, - &armv7m_info); - - target_free_working_area(target, source); - target_free_working_area(target, write_algorithm); - - destroy_reg_param(®_params[0]); - destroy_reg_param(®_params[1]); - destroy_reg_param(®_params[2]); - destroy_reg_param(®_params[3]); - - return retval; -} - -/* Check and erase flash sectors in specified range then start a low level page write. - start/end must be sector aligned. -*/ -static int nrf51_write_pages(struct flash_bank *bank, uint32_t start, uint32_t end, const uint8_t *buffer) -{ - int res = ERROR_FAIL; - struct nrf51_info *chip = bank->driver_priv; - struct flash_sector *sector; - uint32_t offset; - - assert(start % chip->code_page_size == 0); - assert(end % chip->code_page_size == 0); - - /* Erase all sectors */ - for (offset = start; offset < end; offset += chip->code_page_size) { - sector = nrf51_find_sector_by_address(bank, offset); - if (!sector) { - LOG_ERROR("Invalid sector @ 0x%08"PRIx32, offset); - return ERROR_FLASH_SECTOR_INVALID; - } - - if (sector->is_protected) { - LOG_ERROR("Can't erase protected sector @ 0x%08"PRIx32, offset); - goto error; - } - - if (sector->is_erased != 1) { /* 1 = erased, 0= not erased, -1 = unknown */ - res = nrf51_erase_page(bank, chip, sector); - if (res != ERROR_OK) { - LOG_ERROR("Failed to erase sector @ 0x%08"PRIx32, sector->offset); - goto error; - } - } - sector->is_erased = 0; - } - - res = nrf51_nvmc_write_enable(chip); - if (res != ERROR_OK) - goto error; - - res = nrf51_ll_flash_write(chip, start, buffer, (end - start)); - if (res != ERROR_OK) - goto set_read_only; - - return nrf51_nvmc_read_only(chip); - -set_read_only: - nrf51_nvmc_read_only(chip); -error: - LOG_ERROR("Failed to write to nrf51 flash"); - return res; -} - -static int nrf51_erase(struct flash_bank *bank, int first, int last) -{ - int res; - struct nrf51_info *chip; - - res = nrf51_get_probed_chip_if_halted(bank, &chip); - if (res != ERROR_OK) - return res; - - /* For each sector to be erased */ - for (int s = first; s <= last && res == ERROR_OK; s++) - res = nrf51_erase_page(bank, chip, &bank->sectors[s]); - - return res; -} - -static int nrf51_code_flash_write(struct flash_bank *bank, - struct nrf51_info *chip, - const uint8_t *buffer, uint32_t offset, uint32_t count) -{ - - int res; - /* Need to perform reads to fill any gaps we need to preserve in the first page, - before the start of buffer, or in the last page, after the end of buffer */ - uint32_t first_page = offset/chip->code_page_size; - uint32_t last_page = DIV_ROUND_UP(offset+count, chip->code_page_size); - - uint32_t first_page_offset = first_page * chip->code_page_size; - uint32_t last_page_offset = last_page * chip->code_page_size; - - LOG_DEBUG("Padding write from 0x%08"PRIx32"-0x%08"PRIx32" as 0x%08"PRIx32"-0x%08"PRIx32, - offset, offset+count, first_page_offset, last_page_offset); - - uint32_t page_cnt = last_page - first_page; - uint8_t buffer_to_flash[page_cnt*chip->code_page_size]; - - /* Fill in any space between start of first page and start of buffer */ - uint32_t pre = offset - first_page_offset; - if (pre > 0) { - res = target_read_memory(bank->target, - first_page_offset, - 1, - pre, - buffer_to_flash); - if (res != ERROR_OK) - return res; - } - - /* Fill in main contents of buffer */ - memcpy(buffer_to_flash+pre, buffer, count); - - /* Fill in any space between end of buffer and end of last page */ - uint32_t post = last_page_offset - (offset+count); - if (post > 0) { - /* Retrieve the full row contents from Flash */ - res = target_read_memory(bank->target, - offset + count, - 1, - post, - buffer_to_flash+pre+count); - if (res != ERROR_OK) - return res; - } - - return nrf51_write_pages(bank, first_page_offset, last_page_offset, buffer_to_flash); -} - -static int nrf51_uicr_flash_write(struct flash_bank *bank, - struct nrf51_info *chip, - const uint8_t *buffer, uint32_t offset, uint32_t count) -{ - int res; - uint8_t uicr[NRF51_UICR_SIZE]; - struct flash_sector *sector = &bank->sectors[0]; - - if ((offset + count) > NRF51_UICR_SIZE) - return ERROR_FAIL; - - res = target_read_memory(bank->target, - NRF51_UICR_BASE, - 1, - NRF51_UICR_SIZE, - uicr); - - if (res != ERROR_OK) - return res; - - if (sector->is_erased != 1) { - res = nrf51_erase_page(bank, chip, sector); - if (res != ERROR_OK) - return res; - } - - res = nrf51_nvmc_write_enable(chip); - if (res != ERROR_OK) - return res; - - memcpy(&uicr[offset], buffer, count); - - res = nrf51_ll_flash_write(chip, NRF51_UICR_BASE, uicr, NRF51_UICR_SIZE); - if (res != ERROR_OK) { - nrf51_nvmc_read_only(chip); - return res; - } - - return nrf51_nvmc_read_only(chip); -} - - -static int nrf51_write(struct flash_bank *bank, const uint8_t *buffer, - uint32_t offset, uint32_t count) -{ - int res; - struct nrf51_info *chip; - - res = nrf51_get_probed_chip_if_halted(bank, &chip); - if (res != ERROR_OK) - return res; - - return chip->bank[bank->bank_number].write(bank, chip, buffer, offset, count); -} - - -FLASH_BANK_COMMAND_HANDLER(nrf51_flash_bank_command) -{ - static struct nrf51_info *chip; - - switch (bank->base) { - case NRF51_FLASH_BASE: - bank->bank_number = 0; - break; - case NRF51_UICR_BASE: - bank->bank_number = 1; - break; - default: - LOG_ERROR("Invalid bank address 0x%08" PRIx32, bank->base); - return ERROR_FAIL; - } - - if (!chip) { - /* Create a new chip */ - chip = calloc(1, sizeof(*chip)); - if (!chip) - return ERROR_FAIL; - - chip->target = bank->target; - } - - switch (bank->base) { - case NRF51_FLASH_BASE: - chip->bank[bank->bank_number].write = nrf51_code_flash_write; - break; - case NRF51_UICR_BASE: - chip->bank[bank->bank_number].write = nrf51_uicr_flash_write; - break; - } - - chip->bank[bank->bank_number].probed = false; - bank->driver_priv = chip; - - return ERROR_OK; -} - -COMMAND_HANDLER(nrf51_handle_mass_erase_command) -{ - int res; - struct flash_bank *bank = NULL; - struct target *target = get_current_target(CMD_CTX); - - res = get_flash_bank_by_addr(target, NRF51_FLASH_BASE, true, &bank); - if (res != ERROR_OK) - return res; - - assert(bank != NULL); - - struct nrf51_info *chip; - - res = nrf51_get_probed_chip_if_halted(bank, &chip); - if (res != ERROR_OK) - return res; - - uint32_t ppfc; - - res = target_read_u32(target, NRF51_FICR_PPFC, - &ppfc); - if (res != ERROR_OK) { - LOG_ERROR("Couldn't read PPFC register"); - return res; - } - - if ((ppfc & 0xFF) == 0x00) { - 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) { - LOG_ERROR("Failed to erase the chip"); - nrf51_protect_check(bank); - return res; - } - - for (int i = 0; i < bank->num_sectors; i++) - bank->sectors[i].is_erased = 1; - - res = nrf51_protect_check(bank); - if (res != ERROR_OK) { - LOG_ERROR("Failed to check chip's write protection"); - return res; - } - - res = get_flash_bank_by_addr(target, NRF51_UICR_BASE, true, &bank); - if (res != ERROR_OK) - return res; - - bank->sectors[0].is_erased = 1; - - return ERROR_OK; -} - -static int nrf51_info(struct flash_bank *bank, char *buf, int buf_size) -{ - int res; - - struct nrf51_info *chip; - - res = nrf51_get_probed_chip_if_halted(bank, &chip); - if (res != ERROR_OK) - return res; - - static struct { - const uint32_t address; - uint32_t value; - } ficr[] = { - { .address = NRF51_FICR_CODEPAGESIZE }, - { .address = NRF51_FICR_CODESIZE }, - { .address = NRF51_FICR_CLENR0 }, - { .address = NRF51_FICR_PPFC }, - { .address = NRF51_FICR_NUMRAMBLOCK }, - { .address = NRF51_FICR_SIZERAMBLOCK0 }, - { .address = NRF51_FICR_SIZERAMBLOCK1 }, - { .address = NRF51_FICR_SIZERAMBLOCK2 }, - { .address = NRF51_FICR_SIZERAMBLOCK3 }, - { .address = NRF51_FICR_CONFIGID }, - { .address = NRF51_FICR_DEVICEID0 }, - { .address = NRF51_FICR_DEVICEID1 }, - { .address = NRF51_FICR_ER0 }, - { .address = NRF51_FICR_ER1 }, - { .address = NRF51_FICR_ER2 }, - { .address = NRF51_FICR_ER3 }, - { .address = NRF51_FICR_IR0 }, - { .address = NRF51_FICR_IR1 }, - { .address = NRF51_FICR_IR2 }, - { .address = NRF51_FICR_IR3 }, - { .address = NRF51_FICR_DEVICEADDRTYPE }, - { .address = NRF51_FICR_DEVICEADDR0 }, - { .address = NRF51_FICR_DEVICEADDR1 }, - { .address = NRF51_FICR_OVERRIDEN }, - { .address = NRF51_FICR_NRF_1MBIT0 }, - { .address = NRF51_FICR_NRF_1MBIT1 }, - { .address = NRF51_FICR_NRF_1MBIT2 }, - { .address = NRF51_FICR_NRF_1MBIT3 }, - { .address = NRF51_FICR_NRF_1MBIT4 }, - { .address = NRF51_FICR_BLE_1MBIT0 }, - { .address = NRF51_FICR_BLE_1MBIT1 }, - { .address = NRF51_FICR_BLE_1MBIT2 }, - { .address = NRF51_FICR_BLE_1MBIT3 }, - { .address = NRF51_FICR_BLE_1MBIT4 }, - }, uicr[] = { - { .address = NRF51_UICR_CLENR0, }, - { .address = NRF51_UICR_RBPCONF }, - { .address = NRF51_UICR_XTALFREQ }, - { .address = NRF51_UICR_FWID }, - }; - - for (size_t i = 0; i < ARRAY_SIZE(ficr); i++) { - res = target_read_u32(chip->target, ficr[i].address, - &ficr[i].value); - if (res != ERROR_OK) { - LOG_ERROR("Couldn't read %" PRIx32, ficr[i].address); - return res; - } - } - - for (size_t i = 0; i < ARRAY_SIZE(uicr); i++) { - res = target_read_u32(chip->target, uicr[i].address, - &uicr[i].value); - if (res != ERROR_OK) { - LOG_ERROR("Couldn't read %" PRIx32, uicr[i].address); - return res; - } - } - - snprintf(buf, buf_size, - "\n[factory information control block]\n\n" - "code page size: %"PRIu32"B\n" - "code memory size: %"PRIu32"kB\n" - "code region 0 size: %"PRIu32"kB\n" - "pre-programmed code: %s\n" - "number of ram blocks: %"PRIu32"\n" - "ram block 0 size: %"PRIu32"B\n" - "ram block 1 size: %"PRIu32"B\n" - "ram block 2 size: %"PRIu32"B\n" - "ram block 3 size: %"PRIu32 "B\n" - "config id: %" PRIx32 "\n" - "device id: 0x%"PRIx32"%08"PRIx32"\n" - "encryption root: 0x%08"PRIx32"%08"PRIx32"%08"PRIx32"%08"PRIx32"\n" - "identity root: 0x%08"PRIx32"%08"PRIx32"%08"PRIx32"%08"PRIx32"\n" - "device address type: 0x%"PRIx32"\n" - "device address: 0x%"PRIx32"%08"PRIx32"\n" - "override enable: %"PRIx32"\n" - "NRF_1MBIT values: %"PRIx32" %"PRIx32" %"PRIx32" %"PRIx32" %"PRIx32"\n" - "BLE_1MBIT values: %"PRIx32" %"PRIx32" %"PRIx32" %"PRIx32" %"PRIx32"\n" - "\n[user information control block]\n\n" - "code region 0 size: %"PRIu32"kB\n" - "read back protection configuration: %"PRIx32"\n" - "reset value for XTALFREQ: %"PRIx32"\n" - "firmware id: 0x%04"PRIx32, - ficr[0].value, - ficr[1].value, - (ficr[2].value == 0xFFFFFFFF) ? 0 : ficr[2].value / 1024, - ((ficr[3].value & 0xFF) == 0x00) ? "present" : "not present", - ficr[4].value, - ficr[5].value, - (ficr[6].value == 0xFFFFFFFF) ? 0 : ficr[6].value, - (ficr[7].value == 0xFFFFFFFF) ? 0 : ficr[7].value, - (ficr[8].value == 0xFFFFFFFF) ? 0 : ficr[8].value, - ficr[9].value, - ficr[10].value, ficr[11].value, - ficr[12].value, ficr[13].value, ficr[14].value, ficr[15].value, - ficr[16].value, ficr[17].value, ficr[18].value, ficr[19].value, - ficr[20].value, - ficr[21].value, ficr[22].value, - ficr[23].value, - ficr[24].value, ficr[25].value, ficr[26].value, ficr[27].value, ficr[28].value, - ficr[29].value, ficr[30].value, ficr[31].value, ficr[32].value, ficr[33].value, - (uicr[0].value == 0xFFFFFFFF) ? 0 : uicr[0].value / 1024, - uicr[1].value & 0xFFFF, - uicr[2].value & 0xFF, - uicr[3].value & 0xFFFF); - - return ERROR_OK; -} - -static const struct command_registration nrf51_exec_command_handlers[] = { - { - .name = "mass_erase", - .handler = nrf51_handle_mass_erase_command, - .mode = COMMAND_EXEC, - .help = "Erase all flash contents of the chip.", - }, - COMMAND_REGISTRATION_DONE -}; - -static const struct command_registration nrf51_command_handlers[] = { - { - .name = "nrf51", - .mode = COMMAND_ANY, - .help = "nrf51 flash command group", - .usage = "", - .chain = nrf51_exec_command_handlers, - }, - COMMAND_REGISTRATION_DONE -}; - -struct flash_driver nrf51_flash = { - .name = "nrf51", - .commands = nrf51_command_handlers, - .flash_bank_command = nrf51_flash_bank_command, - .info = nrf51_info, - .erase = nrf51_erase, - .protect = nrf51_protect, - .write = nrf51_write, - .read = default_flash_read, - .probe = nrf51_probe, - .auto_probe = nrf51_auto_probe, - .erase_check = default_flash_blank_check, - .protect_check = nrf51_protect_check, -}; diff --git a/src/flash/nor/numicro.c b/src/flash/nor/numicro.c deleted file mode 100644 index 992baa515..000000000 --- a/src/flash/nor/numicro.c +++ /dev/null @@ -1,1883 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2011 by James K. Larson * - * jlarson@pacifier.com * - * * - * Copyright (C) 2013 Cosmin Gorgovan * - * cosmin [at] linux-geek [dot] org * - * * - * Copyright (C) 2014 Pawel Si * - * stawel+openocd@gmail.com * - * * - * Copyright (C) 2015 Nemui Trinomius * - * nemuisan_kawausogasuki@live.jp * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include "imp.h" -#include -#include -#include -#include - -/* Nuvoton NuMicro register locations */ -#define NUMICRO_SYS_BASE 0x50000000 -#define NUMICRO_SYS_WRPROT 0x50000100 -#define NUMICRO_SYS_IPRSTC1 0x50000008 - -#define NUMICRO_SYSCLK_BASE 0x50000200 -#define NUMICRO_SYSCLK_PWRCON 0x50000200 -#define NUMICRO_SYSCLK_CLKSEL0 0x50000210 -#define NUMICRO_SYSCLK_CLKDIV 0x50000218 -#define NUMICRO_SYSCLK_AHBCLK 0x50000204 - -#define NUMICRO_FLASH_BASE 0x5000C000 -#define NUMICRO_FLASH_ISPCON 0x5000C000 -#define NUMICRO_FLASH_ISPADR 0x5000C004 -#define NUMICRO_FLASH_ISPDAT 0x5000C008 -#define NUMICRO_FLASH_ISPCMD 0x5000C00C -#define NUMICRO_FLASH_ISPTRG 0x5000C010 -#define NUMICRO_FLASH_CHEAT 0x5000C01C /* Undocumented isp register(may be cheat register) */ - -#define NUMICRO_SCS_BASE 0xE000E000 -#define NUMICRO_SCS_AIRCR 0xE000ED0C -#define NUMICRO_SCS_DHCSR 0xE000EDF0 -#define NUMICRO_SCS_DEMCR 0xE000EDFC - -#define NUMICRO_APROM_BASE 0x00000000 -#define NUMICRO_DATA_BASE 0x0001F000 -#define NUMICRO_LDROM_BASE 0x00100000 -#define NUMICRO_CONFIG_BASE 0x00300000 - -#define NUMICRO_CONFIG0 0x5000C000 -#define NUMICRO_CONFIG1 0x5000C004 - -/* Command register bits */ -#define PWRCON_OSC22M (1 << 2) -#define PWRCON_XTL12M (1 << 0) - -#define IPRSTC1_CPU_RST (1 << 1) -#define IPRSTC1_CHIP_RST (1 << 0) - -#define AHBCLK_ISP_EN (1 << 2) -#define AHBCLK_SRAM_EN (1 << 4) -#define AHBCLK_TICK_EN (1 << 5) - -#define ISPCON_ISPEN (1 << 0) -#define ISPCON_BS_AP (0 << 1) -#define ISPCON_BS_LP (1 << 1) -#define ISPCON_BS_MASK (1 << 1) -#define ISPCON_APUEN (1 << 3) -#define ISPCON_CFGUEN (1 << 4) -#define ISPCON_LDUEN (1 << 5) -#define ISPCON_ISPFF (1 << 6) - -#define CONFIG0_LOCK_MASK (1 << 1) - -/* isp commands */ -#define ISPCMD_READ 0x00 -#define ISPCMD_WRITE 0x21 -#define ISPCMD_ERASE 0x22 -#define ISPCMD_CHIPERASE 0x26 /* Undocumented isp "Chip-Erase" command */ -#define ISPCMD_READ_CID 0x0B -#define ISPCMD_READ_DID 0x0C -#define ISPCMD_READ_UID 0x04 -#define ISPCMD_VECMAP 0x2E -#define ISPTRG_ISPGO (1 << 0) - -/* access unlock keys */ -#define REG_KEY1 0x59 -#define REG_KEY2 0x16 -#define REG_KEY3 0x88 -#define REG_LOCK 0x00 - -/* flash pagesizes */ -#define NUMICRO_PAGESIZE 512 -/* flash MAX banks */ -#define NUMICRO_MAX_FLASH_BANKS 4 - -/* flash bank structs */ -struct numicro_flash_bank_type { - uint32_t base; - uint32_t size; -}; - -/* part structs */ -struct numicro_cpu_type { - char *partname; - uint32_t partid; - unsigned int n_banks; - struct numicro_flash_bank_type bank[NUMICRO_MAX_FLASH_BANKS]; -}; - -/* TODO : Support variable DataFlash region for 128kB Flash model */ -#define NUMICRO_BANKS_NUC100(aprom_size) \ - .n_banks = 4, \ - { {NUMICRO_APROM_BASE, (aprom_size)}, {NUMICRO_DATA_BASE, 4*1024}, {NUMICRO_LDROM_BASE, 4*1024}, \ - {NUMICRO_CONFIG_BASE, 1024} } - -#define NUMICRO_BANKS_M051(aprom_size) \ - .n_banks = 4, \ - { {NUMICRO_APROM_BASE, (aprom_size)}, {NUMICRO_DATA_BASE, 4*1024}, {NUMICRO_LDROM_BASE, 4*1024}, \ - {NUMICRO_CONFIG_BASE, 1024} } - -#define NUMICRO_BANKS_MINI51(aprom_size) \ - .n_banks = 3, \ - { {NUMICRO_APROM_BASE, (aprom_size)}, {NUMICRO_LDROM_BASE, 2*1024}, {NUMICRO_CONFIG_BASE, 512} } - -#define NUMICRO_BANKS_NANO(aprom_size) \ - .n_banks = 4, \ - { {NUMICRO_APROM_BASE, (aprom_size)}, {NUMICRO_DATA_BASE, 4*1024}, {NUMICRO_LDROM_BASE, 4*1024}, \ - {NUMICRO_CONFIG_BASE, 1024} } - -#define NUMICRO_BANKS_NUC400(aprom_size) \ - .n_banks = 4, \ - { {NUMICRO_APROM_BASE, (aprom_size)}, {NUMICRO_DATA_BASE, 4*1024}, {NUMICRO_LDROM_BASE, 16*1024}, \ - {NUMICRO_CONFIG_BASE, 1024} } - - -static const struct numicro_cpu_type NuMicroParts[] = { - /*PART NO*/ /*PART ID*/ /*Banks*/ - /* NUC100 Version B */ - {"NUC100LD2BN", 0x10010004, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC100LD1BN", 0x10010005, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC100LD0BN", 0x10010027, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC100LC2BN", 0x10010007, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC100LC1BN", 0x10010008, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC100LC0BN", 0x10010028, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC100LB2BN", 0x10010029, NUMICRO_BANKS_NUC100(16*1024)}, - {"NUC100LB1BN", 0x10010030, NUMICRO_BANKS_NUC100(16*1024)}, - {"NUC100LB0BN", 0x10010031, NUMICRO_BANKS_NUC100(16*1024)}, - {"NUC100LA2BN", 0x10010032, NUMICRO_BANKS_NUC100(8*1024)}, - {"NUC100LA1BN", 0x10010033, NUMICRO_BANKS_NUC100(8*1024)}, - {"NUC100LA0BN", 0x10010034, NUMICRO_BANKS_NUC100(8*1024)}, - - {"NUC100RD2BN", 0x10010013, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC100RD1BN", 0x10010014, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC100RD0BN", 0x10010035, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC100RC2BN", 0x10010016, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC100RC1BN", 0x10010017, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC100RC0BN", 0x10010036, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC100RB2BN", 0x10010037, NUMICRO_BANKS_NUC100(16*1024)}, - {"NUC100RB1BN", 0x10010038, NUMICRO_BANKS_NUC100(16*1024)}, - {"NUC100RB0BN", 0x10010039, NUMICRO_BANKS_NUC100(16*1024)}, - {"NUC100RA2BN", 0x10010040, NUMICRO_BANKS_NUC100(8*1024)}, - {"NUC100RA1BN", 0x10010041, NUMICRO_BANKS_NUC100(8*1024)}, - {"NUC100RA0BN", 0x10010042, NUMICRO_BANKS_NUC100(8*1024)}, - - /* NUC100 Version C */ - {"NUC100LE3CN", 0x20010000, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC100LE2CN", 0x20010001, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC100LE1CN", 0x20010002, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC100LD3CN", 0x20010003, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC100LD2CN", 0x20010004, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC100LD1CN", 0x20010005, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC100LC3CN", 0x20010006, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC100LC2CN", 0x20010007, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC100LC1CN", 0x20010008, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC100RE3CN", 0x20010009, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC100RE2CN", 0x20010010, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC100RE1CN", 0x20010011, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC100RD3CN", 0x20010012, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC100RD2CN", 0x20010013, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC100RD1CN", 0x20010014, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC100RC3CN", 0x20010015, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC100RC2CN", 0x20010016, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC100RC1CN", 0x20010017, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC100VE3CN", 0x20010018, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC100VE2CN", 0x20010019, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC100VE1CN", 0x20010020, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC100VD3CN", 0x20010021, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC100VD2CN", 0x20010022, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC100VD1CN", 0x20010023, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC100VC3CN", 0x20010024, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC100VC2CN", 0x20010025, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC100VC1CN", 0x20010026, NUMICRO_BANKS_NUC100(32*1024)}, - - /* NUC100 Version B */ - {"NUC101YD2BN", 0x10010143, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC101YD1BN", 0x10010144, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC101YD0BN", 0x10010145, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC101YC2BN", 0x10010146, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC101YC1BN", 0x10010147, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC101YC0BN", 0x10010148, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC101YB2BN", 0x10010149, NUMICRO_BANKS_NUC100(16*1024)}, - {"NUC101YB1BN", 0x10010150, NUMICRO_BANKS_NUC100(16*1024)}, - {"NUC101YB0BN", 0x10010151, NUMICRO_BANKS_NUC100(16*1024)}, - {"NUC101YA2BN", 0x10010152, NUMICRO_BANKS_NUC100(8*1024)}, - {"NUC101YA1BN", 0x10010153, NUMICRO_BANKS_NUC100(8*1024)}, - {"NUC101YA0BN", 0x10010154, NUMICRO_BANKS_NUC100(8*1024)}, - - {"NUC101LD2BN", 0x10010104, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC101LD1BN", 0x10010105, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC101LD0BN", 0x10010127, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC101LC2BN", 0x10010107, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC101LC1BN", 0x10010108, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC101LC0BN", 0x10010128, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC101LB2BN", 0x10010129, NUMICRO_BANKS_NUC100(16*1024)}, - {"NUC101LB1BN", 0x10010130, NUMICRO_BANKS_NUC100(16*1024)}, - {"NUC101LB0BN", 0x10010131, NUMICRO_BANKS_NUC100(16*1024)}, - {"NUC101LA2BN", 0x10010132, NUMICRO_BANKS_NUC100(8*1024)}, - {"NUC101LA1BN", 0x10010133, NUMICRO_BANKS_NUC100(8*1024)}, - {"NUC101LA0BN", 0x10010134, NUMICRO_BANKS_NUC100(8*1024)}, - - {"NUC101RD2BN", 0x10010113, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC101RD1BN", 0x10010114, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC101RD0BN", 0x10010135, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC101RC2BN", 0x10010116, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC101RC1BN", 0x10010117, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC101RC0BN", 0x10010136, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC101RB2BN", 0x10010137, NUMICRO_BANKS_NUC100(16*1024)}, - {"NUC101RB1BN", 0x10010138, NUMICRO_BANKS_NUC100(16*1024)}, - {"NUC101RB0BN", 0x10010139, NUMICRO_BANKS_NUC100(16*1024)}, - {"NUC101RA2BN", 0x10010140, NUMICRO_BANKS_NUC100(8*1024)}, - {"NUC101RA1BN", 0x10010141, NUMICRO_BANKS_NUC100(8*1024)}, - {"NUC101RA0BN", 0x10010142, NUMICRO_BANKS_NUC100(8*1024)}, - - /* NUC101 Version C */ - {"NUC101LE3CN", 0x20010100, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC101LE2CN", 0x20010101, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC101LE1CN", 0x20010102, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC101LD3CN", 0x20010103, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC101LD2CN", 0x20010104, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC101LD1CN", 0x20010105, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC101LC3CN", 0x20010106, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC101LC2CN", 0x20010107, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC101LC1CN", 0x20010108, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC101RE3CN", 0x20010109, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC101RE2CN", 0x20010110, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC101RE1CN", 0x20010111, NUMICRO_BANKS_NUC100(128*1024)}, - - {"NUC101RD3CN", 0x20010112, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC101RD2CN", 0x20010113, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC101RD1CN", 0x20010114, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC101RC3CN", 0x20010115, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC101RC2CN", 0x20010116, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC101RC1CN", 0x20010117, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC101VE3CN", 0x20010118, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC101VE2CN", 0x20010119, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC101VE1CN", 0x20010120, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC101VD3CN", 0x20010121, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC101VD2CN", 0x20010122, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC101VD1CN", 0x20010123, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC101VC3CN", 0x20010124, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC101VC2CN", 0x20010125, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC101VC1CN", 0x20010126, NUMICRO_BANKS_NUC100(32*1024)}, - - /* NUC102 Version A */ - {"NUC102ZD2AN", 0x00010231, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC102ZC1AN", 0x00010235, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC102LD2AN", 0x00010204, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC102LC1AN", 0x00010208, NUMICRO_BANKS_NUC100(32*1024)}, - - {"NUC102RB3AN", 0x00010248, NUMICRO_BANKS_NUC100(16*1024)}, - {"NUC102RB2AN", 0x00010249, NUMICRO_BANKS_NUC100(16*1024)}, - {"NUC102RB1AN", 0x00010250, NUMICRO_BANKS_NUC100(16*1024)}, - {"NUC102RA3AN", 0x00010251, NUMICRO_BANKS_NUC100(8*1024)}, - {"NUC102RA2AN", 0x00010252, NUMICRO_BANKS_NUC100(8*1024)}, - {"NUC102RA1AN", 0x00010253, NUMICRO_BANKS_NUC100(8*1024)}, - {"NUC102VB3AN", 0x00010254, NUMICRO_BANKS_NUC100(16*1024)}, - {"NUC102VB2AN", 0x00010255, NUMICRO_BANKS_NUC100(16*1024)}, - {"NUC102VB1AN", 0x00010256, NUMICRO_BANKS_NUC100(16*1024)}, - {"NUC102VA3AN", 0x00010257, NUMICRO_BANKS_NUC100(8*1024)}, - {"NUC102VA2AN", 0x00010258, NUMICRO_BANKS_NUC100(8*1024)}, - {"NUC102VA1AN", 0x00010259, NUMICRO_BANKS_NUC100(8*1024)}, - {"NUC102LA0AN", 0x00010260, NUMICRO_BANKS_NUC100(8*1024)}, - {"NUC102LB0AN", 0x00010261, NUMICRO_BANKS_NUC100(16*1024)}, - {"NUC102LC0AN", 0x00010262, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC102LD0AN", 0x00010263, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC102RA0AN", 0x00010264, NUMICRO_BANKS_NUC100(8*1024)}, - {"NUC102RB0AN", 0x00010265, NUMICRO_BANKS_NUC100(16*1024)}, - {"NUC102RC0AN", 0x00010266, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC102RD0AN", 0x00010267, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC102VA0AN", 0x00010268, NUMICRO_BANKS_NUC100(8*1024)}, - {"NUC102VB0AN", 0x00010269, NUMICRO_BANKS_NUC100(16*1024)}, - {"NUC102VC0AN", 0x00010270, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC102VD0AN", 0x00010271, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC102ZA0AN", 0x00010272, NUMICRO_BANKS_NUC100(8*1024)}, - {"NUC102ZB0AN", 0x00010273, NUMICRO_BANKS_NUC100(16*1024)}, - {"NUC102ZC0AN", 0x00010274, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC102ZD0AN", 0x00010275, NUMICRO_BANKS_NUC100(64*1024)}, - - /* NUC102 Version A */ - {"NUC122LD2AN", 0x00012204, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC122LD1AN", 0x00012205, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC122LC2AN", 0x00012207, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC122LC1AN", 0x00012208, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC122RD2AN", 0x00012213, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC122RD1AN", 0x00012214, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC122RC2AN", 0x00012216, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC122RC1AN", 0x00012217, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC122SD2AN", 0x00012222, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC122SD1AN", 0x00012223, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC122SC2AN", 0x00012225, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC122SC1AN", 0x00012226, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC122ZD2AN", 0x00012231, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC122ZD1AN", 0x00012232, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC122ZC2AN", 0x00012234, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC122ZC1AN", 0x00012235, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC122ZB2AN", 0x00012237, NUMICRO_BANKS_NUC100(16*1024)}, - {"NUC122ZB1AN", 0x00012238, NUMICRO_BANKS_NUC100(16*1024)}, - {"NUC122ZA2AN", 0x00012240, NUMICRO_BANKS_NUC100(8*1024)}, - {"NUC122ZA1AN", 0x00012241, NUMICRO_BANKS_NUC100(8*1024)}, - {"NUC122LB2AN", 0x00012243, NUMICRO_BANKS_NUC100(16*1024)}, - {"NUC122LB1AN", 0x00012244, NUMICRO_BANKS_NUC100(16*1024)}, - {"NUC122LA2AN", 0x00012246, NUMICRO_BANKS_NUC100(8*1024)}, - {"NUC122LA1AN", 0x00012247, NUMICRO_BANKS_NUC100(8*1024)}, - {"NUC122RB2AN", 0x00012249, NUMICRO_BANKS_NUC100(16*1024)}, - {"NUC122RB1AN", 0x00012250, NUMICRO_BANKS_NUC100(16*1024)}, - {"NUC122RA2AN", 0x00012252, NUMICRO_BANKS_NUC100(8*1024)}, - {"NUC122RA1AN", 0x00012253, NUMICRO_BANKS_NUC100(8*1024)}, - {"NUC122SB2AN", 0x00012255, NUMICRO_BANKS_NUC100(16*1024)}, - {"NUC122SB1AN", 0x00012256, NUMICRO_BANKS_NUC100(16*1024)}, - {"NUC122SA2AN", 0x00012258, NUMICRO_BANKS_NUC100(8*1024)}, - {"NUC122SA1AN", 0x00012259, NUMICRO_BANKS_NUC100(8*1024)}, - {"NUC122LA0AN", 0x00012260, NUMICRO_BANKS_NUC100(8*1024)}, - {"NUC122LB0AN", 0x00012261, NUMICRO_BANKS_NUC100(16*1024)}, - {"NUC122LC0AN", 0x00012262, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC122LD0AN", 0x00012263, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC122RA0AN", 0x00012264, NUMICRO_BANKS_NUC100(8*1024)}, - {"NUC122RB0AN", 0x00012265, NUMICRO_BANKS_NUC100(16*1024)}, - {"NUC122RC0AN", 0x00012266, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC122RD0AN", 0x00012267, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC122SA0AN", 0x00012268, NUMICRO_BANKS_NUC100(8*1024)}, - {"NUC122SB0AN", 0x00012269, NUMICRO_BANKS_NUC100(16*1024)}, - {"NUC122SC0AN", 0x00012270, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC122SD0AN", 0x00012271, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC122ZA0AN", 0x00012272, NUMICRO_BANKS_NUC100(8*1024)}, - {"NUC122ZB0AN", 0x00012273, NUMICRO_BANKS_NUC100(16*1024)}, - {"NUC122ZC0AN", 0x00012274, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC122ZD0AN", 0x00012275, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC122YD2AN", 0x00012277, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC122YD1AN", 0x00012278, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC122YD0AN", 0x00012279, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC122YC2AN", 0x00012281, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC122YC1AN", 0x00012282, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC122YC0AN", 0x00012283, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC122YB2AN", 0x00012285, NUMICRO_BANKS_NUC100(16*1024)}, - {"NUC122YB1AN", 0x00012286, NUMICRO_BANKS_NUC100(16*1024)}, - {"NUC122YB0AN", 0x00012287, NUMICRO_BANKS_NUC100(16*1024)}, - {"NUC122YA2AN", 0x00012289, NUMICRO_BANKS_NUC100(8*1024)}, - {"NUC122YA1AN", 0x00012290, NUMICRO_BANKS_NUC100(8*1024)}, - {"NUC122YA0AN", 0x00012291, NUMICRO_BANKS_NUC100(8*1024)}, - - /* NUC120 Version C */ - {"NUC120LD2BN", 0x10012004, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC120LD1BN", 0x10012005, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC120LD0BN", 0x10012027, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC120LC2BN", 0x10012007, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC120LC1BN", 0x10012008, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC120LC0BN", 0x10012028, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC120LB2BN", 0x10012029, NUMICRO_BANKS_NUC100(16*1024)}, - {"NUC120LB1BN", 0x10012030, NUMICRO_BANKS_NUC100(16*1024)}, - {"NUC120LB0BN", 0x10012031, NUMICRO_BANKS_NUC100(16*1024)}, - {"NUC120LA2BN", 0x10012032, NUMICRO_BANKS_NUC100(8*1024)}, - {"NUC120LA1BN", 0x10012033, NUMICRO_BANKS_NUC100(8*1024)}, - {"NUC120LA0BN", 0x10012034, NUMICRO_BANKS_NUC100(8*1024)}, - - {"NUC120RD2BN", 0x10012013, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC120RD1BN", 0x10012014, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC120RD0BN", 0x10012035, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC120RC2BN", 0x10012016, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC120RC1BN", 0x10012017, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC120RC0BN", 0x10012036, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC120RB2BN", 0x10012037, NUMICRO_BANKS_NUC100(16*1024)}, - {"NUC120RB1BN", 0x10012038, NUMICRO_BANKS_NUC100(16*1024)}, - {"NUC120RB0BN", 0x10012039, NUMICRO_BANKS_NUC100(16*1024)}, - {"NUC120RA2BN", 0x10012040, NUMICRO_BANKS_NUC100(8*1024)}, - {"NUC120RA1BN", 0x10012041, NUMICRO_BANKS_NUC100(8*1024)}, - {"NUC120RA0BN", 0x10012042, NUMICRO_BANKS_NUC100(8*1024)}, - - /* NUC120 Version C */ - {"NUC120LE3CN", 0x20012000, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC120LE2CN", 0x20012001, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC120LE1CN", 0x20012002, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC120LD3CN", 0x20012003, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC120LD2CN", 0x20012004, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC120LD1CN", 0x20012005, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC120LC3CN", 0x20012006, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC120LC2CN", 0x20012007, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC120LC1CN", 0x20012008, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC120RE3CN", 0x20012009, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC120RE2CN", 0x20012010, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC120RE1CN", 0x20012011, NUMICRO_BANKS_NUC100(128*1024)}, - - {"NUC120RD3CN", 0x20012012, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC120RD2CN", 0x20012013, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC120RD1CN", 0x20012014, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC120RC3CN", 0x20012015, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC120RC2CN", 0x20012016, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC120RC1CN", 0x20012017, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC120VE3CN", 0x20012018, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC120VE2CN", 0x20012019, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC120VE1CN", 0x20012020, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC120VD3CN", 0x20012021, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC120VD2CN", 0x20012022, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC120VD1CN", 0x20012023, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC120VC3CN", 0x20012024, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC120VC2CN", 0x20012025, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC120VC1CN", 0x20012026, NUMICRO_BANKS_NUC100(32*1024)}, - - /* NUC120 Version B */ - {"NUC130LD2BN", 0x10013004, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC130LD1BN", 0x10013005, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC130LD0BN", 0x10013027, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC130LC2BN", 0x10013007, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC130LC1BN", 0x10013008, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC130LC0BN", 0x10013028, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC130LB2BN", 0x10013029, NUMICRO_BANKS_NUC100(16*1024)}, - {"NUC130LB1BN", 0x10013030, NUMICRO_BANKS_NUC100(16*1024)}, - {"NUC130LB0BN", 0x10013031, NUMICRO_BANKS_NUC100(16*1024)}, - {"NUC130LA2BN", 0x10013032, NUMICRO_BANKS_NUC100(8*1024)}, - {"NUC130LA1BN", 0x10013033, NUMICRO_BANKS_NUC100(8*1024)}, - {"NUC130LA0BN", 0x10013034, NUMICRO_BANKS_NUC100(8*1024)}, - - {"NUC130RD2BN", 0x10013013, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC130RD1BN", 0x10013014, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC130RD0BN", 0x10013035, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC130RC2BN", 0x10013016, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC130RC1BN", 0x10013017, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC130RC0BN", 0x10013036, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC130RB2BN", 0x10013037, NUMICRO_BANKS_NUC100(16*1024)}, - {"NUC130RB1BN", 0x10013038, NUMICRO_BANKS_NUC100(16*1024)}, - {"NUC130RB0BN", 0x10013039, NUMICRO_BANKS_NUC100(16*1024)}, - {"NUC130RA2BN", 0x10013040, NUMICRO_BANKS_NUC100(8*1024)}, - {"NUC130RA1BN", 0x10013041, NUMICRO_BANKS_NUC100(8*1024)}, - {"NUC130RA0BN", 0x10013042, NUMICRO_BANKS_NUC100(8*1024)}, - - /* NUC130 Version C */ - {"NUC130LE3CN", 0x20013000, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC130LE2CN", 0x20013001, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC130LE1CN", 0x20013002, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC130LD3CN", 0x20013003, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC130LD2CN", 0x20013004, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC130LD1CN", 0x20013005, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC130LC3CN", 0x20013006, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC130LC2CN", 0x20013007, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC130LC1CN", 0x20013008, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC130RE3CN", 0x20013009, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC130RE2CN", 0x20013010, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC130RE1CN", 0x20013011, NUMICRO_BANKS_NUC100(128*1024)}, - - {"NUC130RD3CN", 0x20013012, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC130RD2CN", 0x20013013, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC130RD1CN", 0x20013014, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC130RC3CN", 0x20013015, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC130RC2CN", 0x20013016, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC130RC1CN", 0x20013017, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC130VE3CN", 0x20013018, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC130VE2CN", 0x20013019, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC130VE1CN", 0x20013020, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC130VD3CN", 0x20013021, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC130VD2CN", 0x20013022, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC130VD1CN", 0x20013023, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC130VC3CN", 0x20013024, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC130VC2CN", 0x20013025, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC130VC1CN", 0x20013026, NUMICRO_BANKS_NUC100(32*1024)}, - - /* NUC140 Version B */ - {"NUC140LD2BN", 0x10014004, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC140LD1BN", 0x10014005, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC140LD0BN", 0x10014027, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC140LC2BN", 0x10014007, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC140LC1BN", 0x10014008, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC140LC0BN", 0x10014028, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC140LB2BN", 0x10014029, NUMICRO_BANKS_NUC100(16*1024)}, - {"NUC140LB1BN", 0x10014030, NUMICRO_BANKS_NUC100(16*1024)}, - {"NUC140LB0BN", 0x10014031, NUMICRO_BANKS_NUC100(16*1024)}, - {"NUC140LA2BN", 0x10014032, NUMICRO_BANKS_NUC100(8*1024)}, - {"NUC140LA1BN", 0x10014033, NUMICRO_BANKS_NUC100(8*1024)}, - {"NUC140LA0BN", 0x10014034, NUMICRO_BANKS_NUC100(8*1024)}, - - {"NUC140RD2BN", 0x10014013, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC140RD1BN", 0x10014014, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC140RD0BN", 0x10014035, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC140RC2BN", 0x10014016, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC140RC1BN", 0x10014017, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC140RC0BN", 0x10014036, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC140RB2BN", 0x10014037, NUMICRO_BANKS_NUC100(16*1024)}, - {"NUC140RB1BN", 0x10014038, NUMICRO_BANKS_NUC100(16*1024)}, - {"NUC140RB0BN", 0x10014039, NUMICRO_BANKS_NUC100(16*1024)}, - {"NUC140RA2BN", 0x10014040, NUMICRO_BANKS_NUC100(8*1024)}, - {"NUC140RA1BN", 0x10014041, NUMICRO_BANKS_NUC100(8*1024)}, - {"NUC140RA0BN", 0x10014042, NUMICRO_BANKS_NUC100(8*1024)}, - - /* NUC140 Version C */ - {"NUC140LE3CN", 0x20014000, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC140LE2CN", 0x20014001, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC140LE1CN", 0x20014002, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC140LD3CN", 0x20014003, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC140LD2CN", 0x20014004, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC140LD1CN", 0x20014005, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC140LC3CN", 0x20014006, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC140LC2CN", 0x20014007, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC140LC1CN", 0x20014008, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC140RE3CN", 0x20014009, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC140RE2CN", 0x20014010, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC140RE1CN", 0x20014011, NUMICRO_BANKS_NUC100(128*1024)}, - - {"NUC140RD3CN", 0x20014012, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC140RD2CN", 0x20014013, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC140RD1CN", 0x20014014, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC140RC3CN", 0x20014015, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC140RC2CN", 0x20014016, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC140RC1CN", 0x20014017, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC140VE3CN", 0x20014018, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC140VE2CN", 0x20014019, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC140VE1CN", 0x20014020, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC140VD3CN", 0x20014021, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC140VD2CN", 0x20014022, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC140VD1CN", 0x20014023, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC140VC3CN", 0x20014024, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC140VC2CN", 0x20014025, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC140VC1CN", 0x20014026, NUMICRO_BANKS_NUC100(32*1024)}, - - /* NUC100 Version A */ - {"NUC100LE3AN", 0x00010000, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC100LE2AN", 0x00010001, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC100LE1AN", 0x00010002, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC100LD3AN", 0x00010003, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC100LD2AN", 0x00010004, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC100LD1AN", 0x00010005, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC100LC3AN", 0x00010006, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC100LC2AN", 0x00010007, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC100LC1AN", 0x00010008, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC100RE3AN", 0x00010009, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC100RE2AN", 0x00010010, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC100RE1AN", 0x00010011, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC100RD3AN", 0x00010012, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC100RD2AN", 0x00010013, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC100RD1AN", 0x00010014, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC100RC3AN", 0x00010015, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC100RC2AN", 0x00010016, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC100RC1AN", 0x00010017, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC100VE3AN", 0x00010018, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC100VE2AN", 0x00010019, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC100VE1AN", 0x00010020, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC100VD3AN", 0x00010021, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC100VD2AN", 0x00010022, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC100VD1AN", 0x00010023, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC100VC3AN", 0x00010024, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC100VC2AN", 0x00010025, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC100VC1AN", 0x00010026, NUMICRO_BANKS_NUC100(32*1024)}, - - /* NUC100 Version A */ - {"NUC101LE3AN", 0x00010100, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC101LE2AN", 0x00010101, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC101LE1AN", 0x00010102, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC101LD3AN", 0x00010103, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC101LD2AN", 0x00010104, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC101LD1AN", 0x00010105, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC101LC3AN", 0x00010106, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC101LC2AN", 0x00010107, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC101LC1AN", 0x00010108, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC101RE3AN", 0x00010109, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC101RE2AN", 0x00010110, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC101RE1AN", 0x00010111, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC101RD3AN", 0x00010112, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC101RD2AN", 0x00010113, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC101RD1AN", 0x00010114, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC101RC3AN", 0x00010115, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC101RC2AN", 0x00010116, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC101RC1AN", 0x00010117, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC101VE3AN", 0x00010118, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC101VE2AN", 0x00010119, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC101VE1AN", 0x00010120, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC101VD3AN", 0x00010121, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC101VD2AN", 0x00010122, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC101VD1AN", 0x00010123, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC101VC3AN", 0x00010124, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC101VC2AN", 0x00010125, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC101VC1AN", 0x00010126, NUMICRO_BANKS_NUC100(32*1024)}, - - /* NUC120 Version A */ - {"NUC120LE3AN", 0x00012000, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC120LE2AN", 0x00012001, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC120LE1AN", 0x00012002, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC120LD3AN", 0x00012003, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC120LD2AN", 0x00012004, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC120LD1AN", 0x00012005, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC120LC3AN", 0x00012006, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC120LC2AN", 0x00012007, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC120LC1AN", 0x00012008, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC120RE3AN", 0x00012009, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC120RE2AN", 0x00012010, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC120RE1AN", 0x00012011, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC120RD3AN", 0x00012012, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC120RD2AN", 0x00012013, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC120RD1AN", 0x00012014, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC120RC3AN", 0x00012015, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC120RC2AN", 0x00012016, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC120RC1AN", 0x00012017, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC120VE3AN", 0x00012018, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC120VE2AN", 0x00012019, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC120VE1AN", 0x00012020, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC120VD3AN", 0x00012021, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC120VD2AN", 0x00012022, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC120VD1AN", 0x00012023, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC120VC3AN", 0x00012024, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC120VC2AN", 0x00012025, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC120VC1AN", 0x00012026, NUMICRO_BANKS_NUC100(32*1024)}, - - /* NUC120 Version A */ - {"NUC130LE3AN", 0x00013000, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC130LE2AN", 0x00013001, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC130LE1AN", 0x00013002, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC130LD3AN", 0x00013003, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC130LD2AN", 0x00013004, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC130LD1AN", 0x00013005, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC130LC3AN", 0x00013006, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC130LC2AN", 0x00013007, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC130LC1AN", 0x00013008, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC130RE3AN", 0x00013009, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC130RE2AN", 0x00013010, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC130RE1AN", 0x00013011, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC130RD3AN", 0x00013012, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC130RD2AN", 0x00013013, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC130RD1AN", 0x00013014, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC130RC3AN", 0x00013015, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC130RC2AN", 0x00013016, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC130RC1AN", 0x00013017, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC130VE3AN", 0x00013018, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC130VE2AN", 0x00013019, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC130VE1AN", 0x00013020, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC130VD3AN", 0x00013021, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC130VD2AN", 0x00013022, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC130VD1AN", 0x00013023, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC130VC3AN", 0x00013024, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC130VC2AN", 0x00013025, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC130VC1AN", 0x00013026, NUMICRO_BANKS_NUC100(32*1024)}, - - /* NUC140 Version A */ - {"NUC140LE3AN", 0x00014000, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC140LE2AN", 0x00014001, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC140LE1AN", 0x00014002, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC140LD3AN", 0x00014003, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC140LD2AN", 0x00014004, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC140LD1AN", 0x00014005, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC140LC3AN", 0x00014006, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC140LC2AN", 0x00014007, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC140LC1AN", 0x00014008, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC140RE3AN", 0x00014009, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC140RE2AN", 0x00014010, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC140RE1AN", 0x00014011, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC140RD3AN", 0x00014012, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC140RD2AN", 0x00014013, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC140RD1AN", 0x00014014, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC140RC3AN", 0x00014015, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC140RC2AN", 0x00014016, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC140RC1AN", 0x00014017, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC140VE3AN", 0x00014018, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC140VE2AN", 0x00014019, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC140VE1AN", 0x00014020, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC140VD3AN", 0x00014021, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC140VD2AN", 0x00014022, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC140VD1AN", 0x00014023, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC140VC3AN", 0x00014024, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC140VC2AN", 0x00014025, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC140VC1AN", 0x00014026, NUMICRO_BANKS_NUC100(32*1024)}, - - - /* M052 */ - {"M052LAN" , 0x00005200, NUMICRO_BANKS_M051(8*1024)}, - {"M052PAN" , 0x00005201, NUMICRO_BANKS_M051(8*1024)}, - {"M052YAN" , 0x00005202, NUMICRO_BANKS_M051(8*1024)}, - {"M052ZAN" , 0x00005203, NUMICRO_BANKS_M051(8*1024)}, - - /* M054 */ - {"M054LAN" , 0x00005400, NUMICRO_BANKS_M051(16*1024)}, - {"M054PAN" , 0x00005401, NUMICRO_BANKS_M051(16*1024)}, - {"M054YAN" , 0x00005402, NUMICRO_BANKS_M051(16*1024)}, - {"M054ZAN" , 0x00005403, NUMICRO_BANKS_M051(16*1024)}, - - /* M058 */ - {"M058LAN" , 0x00005800, NUMICRO_BANKS_M051(32*1024)}, - {"M058PAN" , 0x00005801, NUMICRO_BANKS_M051(32*1024)}, - {"M058YAN" , 0x00005802, NUMICRO_BANKS_M051(32*1024)}, - {"M058ZAN" , 0x00005803, NUMICRO_BANKS_M051(32*1024)}, - - /* M0516 */ - {"M0516LAN" , 0x00005A00, NUMICRO_BANKS_M051(64*1024)}, - {"M0516PAN" , 0x00005A01, NUMICRO_BANKS_M051(64*1024)}, - {"M0516YAN" , 0x00005A02, NUMICRO_BANKS_M051(64*1024)}, - {"M0516ZAN" , 0x00005A03, NUMICRO_BANKS_M051(64*1024)}, - {"M051LBN" , 0x10005100, NUMICRO_BANKS_M051(4*1024)}, - {"M051PBN" , 0x10005101, NUMICRO_BANKS_M051(4*1024)}, - {"M051YBN" , 0x10005102, NUMICRO_BANKS_M051(4*1024)}, - {"M051ZBN" , 0x10005103, NUMICRO_BANKS_M051(4*1024)}, - {"M052LBN" , 0x10005200, NUMICRO_BANKS_M051(8*1024)}, - {"M052PBN" , 0x10005201, NUMICRO_BANKS_M051(8*1024)}, - {"M052YBN" , 0x10005202, NUMICRO_BANKS_M051(8*1024)}, - {"M052ZBN" , 0x10005203, NUMICRO_BANKS_M051(8*1024)}, - {"M054LBN" , 0x10005400, NUMICRO_BANKS_M051(16*1024)}, - {"M054PBN" , 0x10005401, NUMICRO_BANKS_M051(16*1024)}, - {"M054YBN" , 0x10005402, NUMICRO_BANKS_M051(16*1024)}, - {"M054ZBN" , 0x10005403, NUMICRO_BANKS_M051(16*1024)}, - {"M058LBN" , 0x10005800, NUMICRO_BANKS_M051(32*1024)}, - {"M058PBN" , 0x10005801, NUMICRO_BANKS_M051(32*1024)}, - {"M058YBN" , 0x10005802, NUMICRO_BANKS_M051(32*1024)}, - {"M058ZBN" , 0x10005803, NUMICRO_BANKS_M051(32*1024)}, - {"M0516LBN" , 0x10005A00, NUMICRO_BANKS_M051(64*1024)}, - {"M0516PBN" , 0x10005A01, NUMICRO_BANKS_M051(64*1024)}, - {"M0516YBN" , 0x10005A02, NUMICRO_BANKS_M051(64*1024)}, - {"M0516ZBN" , 0x10005A03, NUMICRO_BANKS_M051(64*1024)}, - {"M052LDN" , 0x20005200, NUMICRO_BANKS_M051(8*1024)}, - {"M054LDN" , 0x20005400, NUMICRO_BANKS_M051(16*1024)}, - {"M058LDN" , 0x20005800, NUMICRO_BANKS_M051(32*1024)}, - {"M0516LDN" , 0x20005A00, NUMICRO_BANKS_M051(64*1024)}, - {"M052ZDN" , 0x20005203, NUMICRO_BANKS_M051(8*1024)}, - {"M054ZDN" , 0x20005403, NUMICRO_BANKS_M051(16*1024)}, - {"M058ZDN" , 0x20005803, NUMICRO_BANKS_M051(32*1024)}, - {"M0516ZDN" , 0x20005A03, NUMICRO_BANKS_M051(64*1024)}, - {"M052TDN" , 0x20005204, NUMICRO_BANKS_M051(8*1024)}, - {"M054TDN" , 0x20005404, NUMICRO_BANKS_M051(16*1024)}, - {"M058TDN" , 0x20005804, NUMICRO_BANKS_M051(32*1024)}, - {"M0516TDN" , 0x20005A04, NUMICRO_BANKS_M051(64*1024)}, - {"M052XDN" , 0x20005205, NUMICRO_BANKS_M051(8*1024)}, - {"M054XDN" , 0x20005405, NUMICRO_BANKS_M051(16*1024)}, - {"M058XDN" , 0x20005805, NUMICRO_BANKS_M051(32*1024)}, - {"M0516XDN" , 0x20005A05, NUMICRO_BANKS_M051(64*1024)}, - {"M052LDE" , 0x30005200, NUMICRO_BANKS_M051(8*1024)}, - {"M054LDE" , 0x30005400, NUMICRO_BANKS_M051(16*1024)}, - {"M058LDE" , 0x30005800, NUMICRO_BANKS_M051(32*1024)}, - {"M0516LDE" , 0x30005A00, NUMICRO_BANKS_M051(64*1024)}, - {"M052ZDE" , 0x30005203, NUMICRO_BANKS_M051(8*1024)}, - {"M054ZDE" , 0x30005403, NUMICRO_BANKS_M051(16*1024)}, - {"M058ZDE" , 0x30005803, NUMICRO_BANKS_M051(32*1024)}, - {"M0516ZDE" , 0x30005A03, NUMICRO_BANKS_M051(64*1024)}, - {"M052TDE" , 0x30005204, NUMICRO_BANKS_M051(8*1024)}, - {"M054TDE" , 0x30005404, NUMICRO_BANKS_M051(16*1024)}, - {"M058TDE" , 0x30005804, NUMICRO_BANKS_M051(32*1024)}, - {"M0516TDE" , 0x30005A04, NUMICRO_BANKS_M051(64*1024)}, - {"M052XDE" , 0x30005205, NUMICRO_BANKS_M051(8*1024)}, - {"M054XDE" , 0x30005405, NUMICRO_BANKS_M051(16*1024)}, - {"M058XDE" , 0x30005805, NUMICRO_BANKS_M051(32*1024)}, - {"M0516XDE" , 0x30005A05, NUMICRO_BANKS_M051(64*1024)}, - - /* Mini51 */ - {"MINI51LAN", 0x00205100, NUMICRO_BANKS_MINI51(4*1024)}, - {"MINI51QAN", 0x00205101, NUMICRO_BANKS_MINI51(4*1024)}, - {"MINI51 ", 0x00205102, NUMICRO_BANKS_MINI51(4*1024)}, - {"MINI51ZAN", 0x00205103, NUMICRO_BANKS_MINI51(4*1024)}, - {"MINI51TAN", 0x00205104, NUMICRO_BANKS_MINI51(4*1024)}, - {"MINI52LAN", 0x00205200, NUMICRO_BANKS_MINI51(8*1024)}, - {"MINI52QAN", 0x00205201, NUMICRO_BANKS_MINI51(8*1024)}, - {"MINI52 ", 0x00205202, NUMICRO_BANKS_MINI51(8*1024)}, - {"MINI52ZAN", 0x00205203, NUMICRO_BANKS_MINI51(8*1024)}, - {"MINI52TAN", 0x00205204, NUMICRO_BANKS_MINI51(8*1024)}, - {"MINI54LAN", 0x00205400, NUMICRO_BANKS_MINI51(16*1024)}, - {"MINI54QAN", 0x00205401, NUMICRO_BANKS_MINI51(16*1024)}, - {"MINI54 ", 0x00205402, NUMICRO_BANKS_MINI51(16*1024)}, - {"MINI54ZAN", 0x00205403, NUMICRO_BANKS_MINI51(16*1024)}, - {"MINI54TAN", 0x00205404, NUMICRO_BANKS_MINI51(16*1024)}, - {"MINI51LBN", 0x10205100, NUMICRO_BANKS_MINI51(4*1024)}, - {"MINI51QBN", 0x10205101, NUMICRO_BANKS_MINI51(4*1024)}, - {"MINI51 ", 0x10205102, NUMICRO_BANKS_MINI51(4*1024)}, - {"MINI51ZBN", 0x10205103, NUMICRO_BANKS_MINI51(4*1024)}, - {"MINI51TBN", 0x10205104, NUMICRO_BANKS_MINI51(4*1024)}, - {"MINI52LBN", 0x10205200, NUMICRO_BANKS_MINI51(8*1024)}, - {"MINI52QBN", 0x10205201, NUMICRO_BANKS_MINI51(8*1024)}, - {"MINI52 ", 0x10205202, NUMICRO_BANKS_MINI51(8*1024)}, - {"MINI52ZBN", 0x10205203, NUMICRO_BANKS_MINI51(8*1024)}, - {"MINI52TBN", 0x10205204, NUMICRO_BANKS_MINI51(8*1024)}, - {"MINI54LBN", 0x10205400, NUMICRO_BANKS_MINI51(16*1024)}, - {"MINI54QBN", 0x10205401, NUMICRO_BANKS_MINI51(16*1024)}, - {"MINI54 ", 0x10205402, NUMICRO_BANKS_MINI51(16*1024)}, - {"MINI54ZBN" , 0x10205403, NUMICRO_BANKS_MINI51(16*1024)}, - {"MINI54TBN" , 0x10205404, NUMICRO_BANKS_MINI51(16*1024)}, - {"MINI51LDE" , 0x20205100, NUMICRO_BANKS_MINI51(4*1024)}, - {"MINI51QDE" , 0x20205101, NUMICRO_BANKS_MINI51(4*1024)}, - {"MINI51 " , 0x20205102, NUMICRO_BANKS_MINI51(4*1024)}, - {"MINI51ZDE" , 0x20205103, NUMICRO_BANKS_MINI51(4*1024)}, - {"MINI51TDE" , 0x20205104, NUMICRO_BANKS_MINI51(4*1024)}, - {"MINI51FDE" , 0x20205105, NUMICRO_BANKS_MINI51(4*1024)}, - {"MINI52LDE" , 0x20205200, NUMICRO_BANKS_MINI51(8*1024)}, - {"MINI52QDE" , 0x20205201, NUMICRO_BANKS_MINI51(8*1024)}, - {"MINI52 " , 0x20205202, NUMICRO_BANKS_MINI51(8*1024)}, - {"MINI52ZDE" , 0x20205203, NUMICRO_BANKS_MINI51(8*1024)}, - {"MINI52TDE" , 0x20205204, NUMICRO_BANKS_MINI51(8*1024)}, - {"MINI52FDE" , 0x20205205, NUMICRO_BANKS_MINI51(8*1024)}, - {"MINI54LDE" , 0x20205400, NUMICRO_BANKS_MINI51(16*1024)}, - {"MINI54QDE" , 0x20205401, NUMICRO_BANKS_MINI51(16*1024)}, - {"MINI54 " , 0x20205402, NUMICRO_BANKS_MINI51(16*1024)}, - {"MINI54ZDE" , 0x20205403, NUMICRO_BANKS_MINI51(16*1024)}, - {"MINI54TDE" , 0x20205404, NUMICRO_BANKS_MINI51(16*1024)}, - {"MINI54FDE" , 0x20205405, NUMICRO_BANKS_MINI51(16*1024)}, - {"MINI55LDE" , 0x20205500, NUMICRO_BANKS_MINI51(16*1024)}, - - /* NANO100 */ - {"NANO100VF3AN" , 0x00110000, NUMICRO_BANKS_NANO(256*1024)}, - {"NANO100VF2AN" , 0x00110001, NUMICRO_BANKS_NANO(256*1024)}, - {"NANO100RF3AN" , 0x00110002, NUMICRO_BANKS_NANO(256*1024)}, - {"NANO100RF2AN" , 0x00110003, NUMICRO_BANKS_NANO(256*1024)}, - {"NANO100LF3AN" , 0x00110004, NUMICRO_BANKS_NANO(256*1024)}, - {"NANO100LF2AN" , 0x00110005, NUMICRO_BANKS_NANO(256*1024)}, - {"NANO100VE3AN" , 0x00110006, NUMICRO_BANKS_NANO(128*1024)}, - {"NANO100VE2AN" , 0x00110007, NUMICRO_BANKS_NANO(128*1024)}, - {"NANO100RE3AN" , 0x00110008, NUMICRO_BANKS_NANO(128*1024)}, - {"NANO100RE2AN" , 0x00110009, NUMICRO_BANKS_NANO(128*1024)}, - {"NANO100LE3AN" , 0x00110010, NUMICRO_BANKS_NANO(128*1024)}, - {"NANO100LE2AN" , 0x00110011, NUMICRO_BANKS_NANO(128*1024)}, - {"NANO100VD3AN" , 0x00110012, NUMICRO_BANKS_NANO(64*1024)}, - {"NANO100VD2AN" , 0x00110013, NUMICRO_BANKS_NANO(64*1024)}, - {"NANO100VD1AN" , 0x00110014, NUMICRO_BANKS_NANO(64*1024)}, - {"NANO100RD3AN" , 0x00110015, NUMICRO_BANKS_NANO(64*1024)}, - {"NANO100RD2AN" , 0x00110016, NUMICRO_BANKS_NANO(64*1024)}, - {"NANO100RD1AN" , 0x00110017, NUMICRO_BANKS_NANO(64*1024)}, - {"NANO100LD3AN" , 0x00110018, NUMICRO_BANKS_NANO(64*1024)}, - {"NANO100LD2AN" , 0x00110019, NUMICRO_BANKS_NANO(64*1024)}, - {"NANO100LD1AN" , 0x00110020, NUMICRO_BANKS_NANO(64*1024)}, - {"NANO100VC2AN" , 0x00110021, NUMICRO_BANKS_NANO(32*1024)}, - {"NANO100VC1AN" , 0x00110022, NUMICRO_BANKS_NANO(32*1024)}, - {"NANO100RC2AN" , 0x00110023, NUMICRO_BANKS_NANO(32*1024)}, - {"NANO100RC1AN" , 0x00110024, NUMICRO_BANKS_NANO(32*1024)}, - {"NANO100LC2AN" , 0x00110025, NUMICRO_BANKS_NANO(32*1024)}, - {"NANO100LC1AN" , 0x00110026, NUMICRO_BANKS_NANO(32*1024)}, - {"NANO100VB1AN" , 0x00110027, NUMICRO_BANKS_NANO(16*1024)}, - {"NANO100VB0AN" , 0x00110028, NUMICRO_BANKS_NANO(16*1024)}, - {"NANO100RB1AN" , 0x00110029, NUMICRO_BANKS_NANO(16*1024)}, - - {"NANO110VF3AN" , 0x00111000, NUMICRO_BANKS_NANO(256*1024)}, - {"NANO110VF2AN" , 0x00111001, NUMICRO_BANKS_NANO(256*1024)}, - {"NANO110RF3AN" , 0x00111002, NUMICRO_BANKS_NANO(256*1024)}, - {"NANO110RF2AN" , 0x00111003, NUMICRO_BANKS_NANO(256*1024)}, - {"NANO110VE3AN" , 0x00111006, NUMICRO_BANKS_NANO(128*1024)}, - {"NANO110VE2AN" , 0x00111007, NUMICRO_BANKS_NANO(128*1024)}, - {"NANO110RE3AN" , 0x00111008, NUMICRO_BANKS_NANO(128*1024)}, - {"NANO110RE2AN" , 0x00111009, NUMICRO_BANKS_NANO(128*1024)}, - {"NANO110VD3AN" , 0x00111012, NUMICRO_BANKS_NANO(64*1024)}, - {"NANO110VD2AN" , 0x00111013, NUMICRO_BANKS_NANO(64*1024)}, - {"NANO110VD1AN" , 0x00111014, NUMICRO_BANKS_NANO(64*1024)}, - {"NANO110RD3AN" , 0x00111015, NUMICRO_BANKS_NANO(64*1024)}, - {"NANO110RD2AN" , 0x00111016, NUMICRO_BANKS_NANO(64*1024)}, - {"NANO110RD1AN" , 0x00111017, NUMICRO_BANKS_NANO(64*1024)}, - {"NANO110VC2AN" , 0x00111021, NUMICRO_BANKS_NANO(32*1024)}, - {"NANO110VC1AN" , 0x00111022, NUMICRO_BANKS_NANO(32*1024)}, - {"NANO110SC2AN" , 0x00111023, NUMICRO_BANKS_NANO(32*1024)}, - {"NANO110SC1AN" , 0x00111024, NUMICRO_BANKS_NANO(32*1024)}, - {"NANO120VF3AN" , 0x00112000, NUMICRO_BANKS_NANO(256*1024)}, - {"NANO120VF2AN" , 0x00112001, NUMICRO_BANKS_NANO(256*1024)}, - {"NANO120RF3AN" , 0x00112002, NUMICRO_BANKS_NANO(256*1024)}, - {"NANO120RF2AN" , 0x00112003, NUMICRO_BANKS_NANO(256*1024)}, - {"NANO120LF3AN" , 0x00112004, NUMICRO_BANKS_NANO(256*1024)}, - {"NANO120LF2AN" , 0x00112005, NUMICRO_BANKS_NANO(256*1024)}, - {"NANO120VE3AN" , 0x00112006, NUMICRO_BANKS_NANO(128*1024)}, - {"NANO120VE2AN" , 0x00112007, NUMICRO_BANKS_NANO(128*1024)}, - {"NANO120RE3AN" , 0x00112008, NUMICRO_BANKS_NANO(128*1024)}, - {"NANO120RE2AN" , 0x00112009, NUMICRO_BANKS_NANO(128*1024)}, - {"NANO120LE3AN" , 0x00112010, NUMICRO_BANKS_NANO(128*1024)}, - {"NANO120LE2AN" , 0x00112011, NUMICRO_BANKS_NANO(128*1024)}, - {"NANO120VD3AN" , 0x00112012, NUMICRO_BANKS_NANO(64*1024)}, - {"NANO120VD2AN" , 0x00112013, NUMICRO_BANKS_NANO(64*1024)}, - {"NANO120VD1AN" , 0x00112014, NUMICRO_BANKS_NANO(64*1024)}, - {"NANO120SD3AN" , 0x00112015, NUMICRO_BANKS_NANO(64*1024)}, - {"NANO120SD2AN" , 0x00112016, NUMICRO_BANKS_NANO(64*1024)}, - {"NANO120SD1AN" , 0x00112017, NUMICRO_BANKS_NANO(64*1024)}, - {"NANO120LD3AN" , 0x00112018, NUMICRO_BANKS_NANO(64*1024)}, - {"NANO120LD2AN" , 0x00112019, NUMICRO_BANKS_NANO(64*1024)}, - {"NANO120LD1AN" , 0x00112020, NUMICRO_BANKS_NANO(64*1024)}, - {"NANO120VC2AN" , 0x00112021, NUMICRO_BANKS_NANO(32*1024)}, - {"NANO120VC1AN" , 0x00112022, NUMICRO_BANKS_NANO(32*1024)}, - {"NANO120SC2AN" , 0x00112023, NUMICRO_BANKS_NANO(32*1024)}, - {"NANO120SC1AN" , 0x00112024, NUMICRO_BANKS_NANO(32*1024)}, - {"NANO120LC2AN" , 0x00112025, NUMICRO_BANKS_NANO(32*1024)}, - {"NANO120LC1AN" , 0x00112026, NUMICRO_BANKS_NANO(32*1024)}, - {"NANO130VF3AN" , 0x00113000, NUMICRO_BANKS_NANO(256*1024)}, - {"NANO130VF2AN" , 0x00113001, NUMICRO_BANKS_NANO(256*1024)}, - {"NANO130SF3AN" , 0x00113002, NUMICRO_BANKS_NANO(256*1024)}, - {"NANO130SF2AN" , 0x00113003, NUMICRO_BANKS_NANO(256*1024)}, - {"NANO130VE3AN" , 0x00113006, NUMICRO_BANKS_NANO(128*1024)}, - {"NANO130VE2AN" , 0x00113007, NUMICRO_BANKS_NANO(128*1024)}, - {"NANO130SE3AN" , 0x00113008, NUMICRO_BANKS_NANO(128*1024)}, - {"NANO130SE2AN" , 0x00113009, NUMICRO_BANKS_NANO(128*1024)}, - {"NANO130VD3AN" , 0x00113012, NUMICRO_BANKS_NANO(64*1024)}, - {"NANO130VD2AN" , 0x00113013, NUMICRO_BANKS_NANO(64*1024)}, - {"NANO130VD1AN" , 0x00113014, NUMICRO_BANKS_NANO(64*1024)}, - {"NANO130SD3AN" , 0x00113015, NUMICRO_BANKS_NANO(64*1024)}, - {"NANO130SD2AN" , 0x00113016, NUMICRO_BANKS_NANO(64*1024)}, - {"NANO130SD1AN" , 0x00113017, NUMICRO_BANKS_NANO(64*1024)}, - {"NANO130VC2AN" , 0x00113021, NUMICRO_BANKS_NANO(32*1024)}, - {"NANO130VC1AN" , 0x00113022, NUMICRO_BANKS_NANO(32*1024)}, - {"NANO130SC2AN" , 0x00113023, NUMICRO_BANKS_NANO(32*1024)}, - {"NANO130SC1AN" , 0x00113024, NUMICRO_BANKS_NANO(32*1024)}, - {"NANO100KE3BN" , 0x00110030, NUMICRO_BANKS_NANO(128*1024)}, - {"NANO100KE2BN" , 0x00110031, NUMICRO_BANKS_NANO(128*1024)}, - {"NANO100VE3BN" , 0x00110032, NUMICRO_BANKS_NANO(128*1024)}, - {"NANO100VE2BN" , 0x00110033, NUMICRO_BANKS_NANO(128*1024)}, - {"NANO100SE3BN" , 0x00110034, NUMICRO_BANKS_NANO(128*1024)}, - {"NANO100SE2BN" , 0x00110035, NUMICRO_BANKS_NANO(128*1024)}, - {"NANO100LE3BN" , 0x00110036, NUMICRO_BANKS_NANO(128*1024)}, - {"NANO100LE2BN" , 0x00110037, NUMICRO_BANKS_NANO(128*1024)}, - {"NANO100KD3BN" , 0x00110038, NUMICRO_BANKS_NANO(64*1024)}, - {"NANO100KD2BN" , 0x00110039, NUMICRO_BANKS_NANO(64*1024)}, - {"NANO100VD3BN" , 0x0011003A, NUMICRO_BANKS_NANO(64*1024)}, - {"NANO100VD2BN" , 0x0011003B, NUMICRO_BANKS_NANO(64*1024)}, - {"NANO100SD3BN" , 0x0011003C, NUMICRO_BANKS_NANO(64*1024)}, - {"NANO100SD2BN" , 0x0011003D, NUMICRO_BANKS_NANO(64*1024)}, - {"NANO100LD3BN" , 0x0011003E, NUMICRO_BANKS_NANO(64*1024)}, - {"NANO100LD2BN" , 0x0011003F, NUMICRO_BANKS_NANO(64*1024)}, - {"NANO100KC2BN" , 0x00110040, NUMICRO_BANKS_NANO(32*1024)}, - {"NANO100VC2BN" , 0x00110041, NUMICRO_BANKS_NANO(32*1024)}, - {"NANO100SC2BN" , 0x00110042, NUMICRO_BANKS_NANO(32*1024)}, - {"NANO100LC2BN" , 0x00110043, NUMICRO_BANKS_NANO(32*1024)}, - {"NANO110KE3BN" , 0x00111030, NUMICRO_BANKS_NANO(128*1024)}, - {"NANO110KE2BN" , 0x00111031, NUMICRO_BANKS_NANO(128*1024)}, - {"NANO110VE3BN" , 0x00111032, NUMICRO_BANKS_NANO(128*1024)}, - {"NANO110VE2BN" , 0x00111033, NUMICRO_BANKS_NANO(128*1024)}, - {"NANO110SE3BN" , 0x00111034, NUMICRO_BANKS_NANO(128*1024)}, - {"NANO110SE2BN" , 0x00111035, NUMICRO_BANKS_NANO(128*1024)}, - {"NANO110KD3BN" , 0x00111038, NUMICRO_BANKS_NANO(64*1024)}, - {"NANO110KD2BN" , 0x00111039, NUMICRO_BANKS_NANO(64*1024)}, - {"NANO110VD3BN" , 0x0011103A, NUMICRO_BANKS_NANO(64*1024)}, - {"NANO110VD2BN" , 0x0011103B, NUMICRO_BANKS_NANO(64*1024)}, - {"NANO110SD3BN" , 0x0011103C, NUMICRO_BANKS_NANO(64*1024)}, - {"NANO110SD2BN" , 0x0011103D, NUMICRO_BANKS_NANO(64*1024)}, - {"NANO110KC2BN" , 0x00111040, NUMICRO_BANKS_NANO(32*1024)}, - {"NANO110VC2BN" , 0x00111041, NUMICRO_BANKS_NANO(32*1024)}, - {"NANO110SC2BN" , 0x00111042, NUMICRO_BANKS_NANO(32*1024)}, - {"NANO120KE3BN" , 0x00112030, NUMICRO_BANKS_NANO(128*1024)}, - {"NANO120KE2BN" , 0x00112031, NUMICRO_BANKS_NANO(128*1024)}, - {"NANO120VE3BN" , 0x00112032, NUMICRO_BANKS_NANO(128*1024)}, - {"NANO120VE2BN" , 0x00112033, NUMICRO_BANKS_NANO(128*1024)}, - {"NANO120SE3BN" , 0x00112034, NUMICRO_BANKS_NANO(128*1024)}, - {"NANO120SE2BN" , 0x00112035, NUMICRO_BANKS_NANO(128*1024)}, - {"NANO120LE3BN" , 0x00112036, NUMICRO_BANKS_NANO(128*1024)}, - {"NANO120LE2BN" , 0x00112037, NUMICRO_BANKS_NANO(128*1024)}, - {"NANO120KD3BN" , 0x00112038, NUMICRO_BANKS_NANO(64*1024)}, - {"NANO120KD2BN" , 0x00112039, NUMICRO_BANKS_NANO(64*1024)}, - {"NANO120VD3BN" , 0x0011203A, NUMICRO_BANKS_NANO(64*1024)}, - {"NANO120VD2BN" , 0x0011203B, NUMICRO_BANKS_NANO(64*1024)}, - {"NANO120SD3BN" , 0x0011203C, NUMICRO_BANKS_NANO(64*1024)}, - {"NANO120SD2BN" , 0x0011203D, NUMICRO_BANKS_NANO(64*1024)}, - {"NANO120LD3BN" , 0x0011203E, NUMICRO_BANKS_NANO(64*1024)}, - {"NANO120LD2BN" , 0x0011203F, NUMICRO_BANKS_NANO(64*1024)}, - {"NANO120KC2BN" , 0x00112040, NUMICRO_BANKS_NANO(32*1024)}, - {"NANO120VC2BN" , 0x00112041, NUMICRO_BANKS_NANO(32*1024)}, - {"NANO120SC2BN" , 0x00112042, NUMICRO_BANKS_NANO(32*1024)}, - {"NANO120LC2BN" , 0x00112043, NUMICRO_BANKS_NANO(32*1024)}, - {"NANO130KE3BN" , 0x00113030, NUMICRO_BANKS_NANO(123*1024)}, - {"NANO130KE2BN" , 0x00113031, NUMICRO_BANKS_NANO(123*1024)}, - {"NANO130VE3BN" , 0x00113032, NUMICRO_BANKS_NANO(123*1024)}, - {"NANO130VE2BN" , 0x00113033, NUMICRO_BANKS_NANO(123*1024)}, - {"NANO130SE3BN" , 0x00113034, NUMICRO_BANKS_NANO(123*1024)}, - {"NANO130SE2BN" , 0x00113035, NUMICRO_BANKS_NANO(123*1024)}, - {"NANO130KD3BN" , 0x00113038, NUMICRO_BANKS_NANO(64*1024)}, - {"NANO130KD2BN" , 0x00113039, NUMICRO_BANKS_NANO(64*1024)}, - {"NANO130VD3BN" , 0x0011303A, NUMICRO_BANKS_NANO(64*1024)}, - {"NANO130VD2BN" , 0x0011303B, NUMICRO_BANKS_NANO(64*1024)}, - {"NANO130SD3BN" , 0x0011303C, NUMICRO_BANKS_NANO(64*1024)}, - {"NANO130SD2BN" , 0x0011303D, NUMICRO_BANKS_NANO(64*1024)}, - {"NANO130KC2BN" , 0x00113040, NUMICRO_BANKS_NANO(32*1024)}, - {"NANO130VC2BN" , 0x00113041, NUMICRO_BANKS_NANO(32*1024)}, - {"NANO130SC2BN" , 0x00113042, NUMICRO_BANKS_NANO(32*1024)}, - {"N512DC4" , 0x00100000, NUMICRO_BANKS_NANO(64*1024)}, - {"N512LC4" , 0x00100001, NUMICRO_BANKS_NANO(64*1024)}, - {"N512MC4" , 0x00100003, NUMICRO_BANKS_NANO(64*1024)}, - - {"N512SC4" , 0x00100005, NUMICRO_BANKS_NANO(64*1024)}, - {"N512VD4" , 0x00100008, NUMICRO_BANKS_NANO(128*1024)}, - {"N512MD4" , 0x00100009, NUMICRO_BANKS_NANO(128*1024)}, - {"N512SD4" , 0x00100010, NUMICRO_BANKS_NANO(128*1024)}, - {"NANO110RC2BN" , 0x00111043, NUMICRO_BANKS_NANO(32*1024)}, - {"NANO110RD3BN" , 0x00111045, NUMICRO_BANKS_NANO(64*1024)}, - {"TX110VE3BN" , 0x00111036, NUMICRO_BANKS_NANO(128*1024)}, - - /* NANO102/NANO112 */ - {"NANO112LB0AN" , 0x00111201, NUMICRO_BANKS_NANO(16*1024)}, - {"NANO112LB1AN" , 0x00111202, NUMICRO_BANKS_NANO(16*1024)}, - {"NANO112LC1AN" , 0x00111203, NUMICRO_BANKS_NANO(32*1024)}, - {"NANO112LC2AN" , 0x00111204, NUMICRO_BANKS_NANO(32*1024)}, - {"NANO112SB0AN" , 0x00111205, NUMICRO_BANKS_NANO(16*1024)}, - {"NANO112SB1AN" , 0x00111206, NUMICRO_BANKS_NANO(16*1024)}, - {"NANO112SC1AN" , 0x00111207, NUMICRO_BANKS_NANO(32*1024)}, - {"NANO112SC2AN" , 0x00111208, NUMICRO_BANKS_NANO(32*1024)}, - {"NANO112RB0AN" , 0x00111209, NUMICRO_BANKS_NANO(16*1024)}, - {"NANO112RB1AN" , 0x00111210, NUMICRO_BANKS_NANO(16*1024)}, - {"NANO112RC1AN" , 0x00111211, NUMICRO_BANKS_NANO(32*1024)}, - {"NANO112RC2AN" , 0x00111212, NUMICRO_BANKS_NANO(32*1024)}, - {"NANO112VB0AN" , 0x00111213, NUMICRO_BANKS_NANO(16*1024)}, - {"NANO112VB1AN" , 0x00111214, NUMICRO_BANKS_NANO(16*1024)}, - {"NANO112VC1AN" , 0x00111215, NUMICRO_BANKS_NANO(32*1024)}, - {"NANO112VC2AN" , 0x00111216, NUMICRO_BANKS_NANO(32*1024)}, - {"NANO102ZB0AN" , 0x00110201, NUMICRO_BANKS_NANO(16*1024)}, - {"NANO102ZB1AN" , 0x00110202, NUMICRO_BANKS_NANO(16*1024)}, - {"NANO102ZC1AN" , 0x00110203, NUMICRO_BANKS_NANO(32*1024)}, - {"NANO102ZC2AN" , 0x00110204, NUMICRO_BANKS_NANO(32*1024)}, - {"NANO102LB0AN" , 0x00110205, NUMICRO_BANKS_NANO(16*1024)}, - {"NANO102LB1AN" , 0x00110206, NUMICRO_BANKS_NANO(16*1024)}, - {"NANO102LC1AN" , 0x00110207, NUMICRO_BANKS_NANO(32*1024)}, - {"NANO102LC2AN" , 0x00110208, NUMICRO_BANKS_NANO(32*1024)}, - {"NANO102SB0AN" , 0x00110209, NUMICRO_BANKS_NANO(16*1024)}, - {"NANO102SB1AN" , 0x00110210, NUMICRO_BANKS_NANO(16*1024)}, - {"NANO102SC1AN" , 0x00110211, NUMICRO_BANKS_NANO(32*1024)}, - {"NANO102SC2AN" , 0x00110212, NUMICRO_BANKS_NANO(32*1024)}, - - /* NUC103/NUC105/NUC123 */ - {"NUC123SC2AN" , 0x00012305, NUMICRO_BANKS_NUC100(36*1024)}, - {"NUC123SD4AN" , 0x00012315, NUMICRO_BANKS_NUC100(68*1024)}, - {"NUC123LC2AN" , 0x00012325, NUMICRO_BANKS_NUC100(36*1024)}, - {"NUC103LC2AN" , 0x00010325, NUMICRO_BANKS_NUC100(36*1024)}, - {"NUC105LC2AN" , 0x00010525, NUMICRO_BANKS_NUC100(36*1024)}, - {"NUC123LD4AN" , 0x00012335, NUMICRO_BANKS_NUC100(68*1024)}, - {"NUC103LD4AN" , 0x00010335, NUMICRO_BANKS_NUC100(68*1024)}, - {"NUC105LD4AN" , 0x00010535, NUMICRO_BANKS_NUC100(68*1024)}, - {"NUC123ZC2AN" , 0x00012345, NUMICRO_BANKS_NUC100(36*1024)}, - {"NUC103ZC2AN" , 0x00010345, NUMICRO_BANKS_NUC100(36*1024)}, - {"NUC105ZC2AN" , 0x00010545, NUMICRO_BANKS_NUC100(36*1024)}, - {"NUC123ZD4AN" , 0x00012355, NUMICRO_BANKS_NUC100(68*1024)}, - {"NUC103ZD4AN" , 0x00010355, NUMICRO_BANKS_NUC100(68*1024)}, - {"NUC105ZD4AN" , 0x00010555, NUMICRO_BANKS_NUC100(68*1024)}, - - /* NUC200 */ - {"NUC200LC2AN" , 0x00020007, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC200LD2AN" , 0x00020004, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC200LE3AN" , 0x00020000, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC200SC1AN" , 0x00020035, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC200SD2AN" , 0x00020031, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC200SE3AN" , 0x00020027, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC200VE3AN" , 0x00020018, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC220LC2AN" , 0x00022007, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC220LD2AN" , 0x00022004, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC220LE3AN" , 0x00022000, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC220SC1AN" , 0x00022035, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC220SD2AN" , 0x00022031, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC220SE3AN" , 0x00022027, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC220VE3AN" , 0x00022018, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC230LC2AN" , 0x00023007, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC230LD2AN" , 0x00023004, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC230LE3AN" , 0x00023000, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC230SC1AN" , 0x00023035, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC230SD2AN" , 0x00023031, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC230SE3AN" , 0x00023027, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC230VE3AN" , 0x00023018, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC240LC2AN" , 0x00024007, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC240LD2AN" , 0x00024004, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC240LE3AN" , 0x00024000, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC240SC1AN" , 0x00024035, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC240SD2AN" , 0x00024031, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC240SE3AN" , 0x00024027, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC240VE3AN" , 0x00024018, NUMICRO_BANKS_NUC100(128*1024)}, - - /* NUC200 NUC2XXAE */ - {"NUC230RC1AE" , 0x40013017, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC200LC2AE" , 0x10020007, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC200LD2AE" , 0x10020004, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC200LE3AE" , 0x10020000, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC200SC2AE" , 0x10020034, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC200SD2AE" , 0x10020031, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC200SE3AE" , 0x10020027, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC200VE3AE" , 0x10020018, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC230LC2AE" , 0x10023007, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC230LD2AE" , 0x10023004, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC230LE3AE" , 0x10023000, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC230SC2AE" , 0x10023034, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC230SD2AE" , 0x10023031, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC230SE3AE" , 0x10023027, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC230VE3AE" , 0x10023018, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC240LC2AE" , 0x10024007, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC240LD2AE" , 0x10024004, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC240LE3AE" , 0x10024000, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC240SC2AE" , 0x10024034, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC240SD2AE" , 0x10024031, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC240SE3AE" , 0x10024027, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC240VE3AE" , 0x10024018, NUMICRO_BANKS_NUC100(128*1024)}, - - /* NUC100 Version D */ - {"NUC100LC1DN" , 0x30010008, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC100LD1DN" , 0x30010005, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC100LD2DN" , 0x30010004, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC100RC1DN" , 0x30010017, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC100RD1DN" , 0x30010014, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC100RD2DN" , 0x30010013, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC100LD3DN" , 0x30010003, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC100LE3DN" , 0x30010000, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC100RD3DN" , 0x30010012, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC100RE3DN" , 0x30010009, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC100VD2DN" , 0x30010022, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC100VD3DN" , 0x30010021, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC100VE3DN" , 0x30010018, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC120LC1DN" , 0x30012008, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC120LD1DN" , 0x30012005, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC120LD2DN" , 0x30012004, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC120RC1DN" , 0x30012017, NUMICRO_BANKS_NUC100(32*1024)}, - {"NUC120RD1DN" , 0x30012014, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC120RD2DN" , 0x30012013, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC120LD3DN" , 0x30012003, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC120LE3DN" , 0x30012000, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC120RD3DN" , 0x30012012, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC120RE3DN" , 0x30012009, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC120VD2DN" , 0x30012022, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC120VD3DN" , 0x30012021, NUMICRO_BANKS_NUC100(64*1024)}, - {"NUC120VE3DN" , 0x30012018, NUMICRO_BANKS_NUC100(128*1024)}, - {"NUC130RC1DN" , 0x30013017, NUMICRO_BANKS_NUC100(32*1024)}, - - {"UNKNOWN" , 0x00000000, NUMICRO_BANKS_NUC100(128*1024)}, -}; - -/* Private bank information for NuMicro. */ -struct numicro_flash_bank { - struct working_area *write_algorithm; - int probed; - const struct numicro_cpu_type *cpu; -}; - -/* Private methods */ -static int numicro_reg_unlock(struct target *target) -{ - uint32_t is_protected; - int retval = ERROR_OK; - - /* Check to see if NUC is register unlocked or not */ - retval = target_read_u32(target, NUMICRO_SYS_WRPROT, &is_protected); - if (retval != ERROR_OK) - return retval; - - LOG_DEBUG("protected = 0x%08" PRIx32 "", is_protected); - if (is_protected == 0) { /* means protected - so unlock it */ - /* unlock flash registers */ - retval = target_write_u32(target, NUMICRO_SYS_WRPROT, REG_KEY1); - if (retval != ERROR_OK) - return retval; - retval = target_write_u32(target, NUMICRO_SYS_WRPROT, REG_KEY2); - if (retval != ERROR_OK) - return retval; - retval = target_write_u32(target, NUMICRO_SYS_WRPROT, REG_KEY3); - if (retval != ERROR_OK) - return retval; - } - /* Check that unlock worked */ - retval = target_read_u32(target, NUMICRO_SYS_WRPROT, &is_protected); - if (retval != ERROR_OK) - return retval; - - if (is_protected == 1) { /* means unprotected */ - LOG_DEBUG("protection removed"); - } else { - LOG_DEBUG("still protected!!"); - } - - return ERROR_OK; -} - -static int numicro_init_isp(struct target *target) -{ - uint32_t reg_stat; - int retval = ERROR_OK; - - if (target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - retval = numicro_reg_unlock(target); - if (retval != ERROR_OK) - return retval; - - /* Enable ISP/SRAM/TICK Clock */ - retval = target_read_u32(target, NUMICRO_SYSCLK_AHBCLK, ®_stat); - if (retval != ERROR_OK) - return retval; - - reg_stat |= AHBCLK_ISP_EN | AHBCLK_SRAM_EN | AHBCLK_TICK_EN; - retval = target_write_u32(target, NUMICRO_SYSCLK_AHBCLK, reg_stat); - if (retval != ERROR_OK) - return retval; - - /* Enable ISP */ - retval = target_read_u32(target, NUMICRO_FLASH_ISPCON, ®_stat); - if (retval != ERROR_OK) - return retval; - - reg_stat |= ISPCON_ISPFF | ISPCON_LDUEN | ISPCON_APUEN | ISPCON_CFGUEN | ISPCON_ISPEN; - retval = target_write_u32(target, NUMICRO_FLASH_ISPCON, reg_stat); - if (retval != ERROR_OK) - return retval; - - /* Write one to undocumented flash control register */ - retval = target_write_u32(target, NUMICRO_FLASH_CHEAT, 1); - if (retval != ERROR_OK) - return retval; - - return ERROR_OK; -} - -static uint32_t numicro_fmc_cmd(struct target *target, uint32_t cmd, uint32_t addr, uint32_t wdata, uint32_t* rdata) -{ - uint32_t timeout, status; - int retval = ERROR_OK; - - retval = target_write_u32(target, NUMICRO_FLASH_ISPCMD, cmd); - if (retval != ERROR_OK) - return retval; - - retval = target_write_u32(target, NUMICRO_FLASH_ISPDAT, wdata); - if (retval != ERROR_OK) - return retval; - - retval = target_write_u32(target, NUMICRO_FLASH_ISPADR, addr); - if (retval != ERROR_OK) - return retval; - - retval = target_write_u32(target, NUMICRO_FLASH_ISPTRG, ISPTRG_ISPGO); - if (retval != ERROR_OK) - return retval; - - /* Wait for busy to clear - check the GO flag */ - timeout = 100; - for (;;) { - retval = target_read_u32(target, NUMICRO_FLASH_ISPTRG, &status); - if (retval != ERROR_OK) - return retval; - LOG_DEBUG("status: 0x%" PRIx32 "", status); - if ((status & (ISPTRG_ISPGO)) == 0) - break; - if (timeout-- <= 0) { - LOG_DEBUG("timed out waiting for flash"); - return ERROR_FAIL; - } - busy_sleep(1); /* can use busy sleep for short times. */ - } - - retval = target_read_u32(target, NUMICRO_FLASH_ISPDAT, rdata); - if (retval != ERROR_OK) - return retval; - - return ERROR_OK; -} - - -/* NuMicro Program-LongWord Microcodes */ -static const uint8_t numicro_flash_write_code[] = { - /* Params: - * r0 - workarea buffer / result - * r1 - target address - * r2 - wordcount - * Clobbered: - * r4 - tmp - * r5 - tmp - * r6 - tmp - * r7 - tmp - */ - - /* .L1: */ - /* for(register uint32_t i=0;itarget; - uint32_t buffer_size = 1024; /* Default minimum value */ - struct working_area *write_algorithm; - struct working_area *source; - uint32_t address = bank->base + offset; - struct reg_param reg_params[3]; - struct armv7m_algorithm armv7m_info; - int retval = ERROR_OK; - - /* Params: - * r0 - workarea buffer / result - * r1 - target address - * r2 - wordcount - * Clobbered: - * r4 - tmp - * r5 - tmp - * r6 - tmp - * r7 - tmp - */ - - /* Increase buffer_size if needed */ - if (buffer_size < (target->working_area_size/2)) - buffer_size = (target->working_area_size/2); - - /* 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(numicro_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(numicro_flash_write_code), numicro_flash_write_code); - if (retval != ERROR_OK) - return retval; - - /* memory buffer */ - while (target_alloc_working_area(target, buffer_size, &source) != ERROR_OK) { - buffer_size /= 4; - if (buffer_size <= 256) { - /* free working area, write algorithm already allocated */ - target_free_working_area(target, write_algorithm); - - 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; - - init_reg_param(®_params[0], "r0", 32, PARAM_IN_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 */ - - struct armv7m_common *armv7m = target_to_armv7m(target); - if (armv7m == NULL) { - /* something is very wrong if armv7m is NULL */ - LOG_ERROR("unable to get armv7m target"); - return retval; - } - - /* write code buffer and use Flash programming code within NuMicro */ - /* Set breakpoint to 0 with time-out of 1000 ms */ - while (count > 0) { - uint32_t thisrun_count = (count > (buffer_size / 4)) ? (buffer_size / 4) : count; - - retval = target_write_buffer(target, source->address, thisrun_count * 4, buffer); - if (retval != ERROR_OK) - break; - - 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); - - 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 NuMicro Flash programming algorithm"); - retval = ERROR_FLASH_OPERATION_FAILED; - break; - } - - buffer += thisrun_count * 4; - address += thisrun_count * 4; - count -= thisrun_count; - } - - target_free_working_area(target, source); - target_free_working_area(target, write_algorithm); - - destroy_reg_param(®_params[0]); - destroy_reg_param(®_params[1]); - destroy_reg_param(®_params[2]); - - return retval; -} - -/* Flash Lock checking - examines the lock bit. */ -static int numicro_protect_check(struct flash_bank *bank) -{ - struct target *target = bank->target; - uint32_t set, config[2]; - int i, retval = ERROR_OK; - - if (target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - LOG_INFO("Nuvoton NuMicro: Flash Lock Check..."); - - retval = numicro_init_isp(target); - if (retval != ERROR_OK) - return retval; - - /* Read CONFIG0,CONFIG1 */ - numicro_fmc_cmd(target, ISPCMD_READ, NUMICRO_CONFIG0, 0 , &config[0]); - numicro_fmc_cmd(target, ISPCMD_READ, NUMICRO_CONFIG1, 0 , &config[1]); - - LOG_DEBUG("CONFIG0: 0x%" PRIx32 ",CONFIG1: 0x%" PRIx32 "", config[0], config[1]); - - if ((config[0] & (1<<7)) == 0) - LOG_INFO("CBS=0: Boot From LPROM"); - else - LOG_INFO("CBS=1: Boot From APROM"); - - if ((config[0] & CONFIG0_LOCK_MASK) == 0) { - - LOG_INFO("Flash is secure locked!"); - LOG_INFO("TO UNLOCK FLASH,EXECUTE chip_erase COMMAND!!"); - set = 1; - } else { - LOG_INFO("Flash is not locked!"); - set = 0; - } - - for (i = 0; i < bank->num_sectors; i++) - bank->sectors[i].is_protected = set; - - return ERROR_OK; -} - - -static int numicro_erase(struct flash_bank *bank, int first, int last) -{ - struct target *target = bank->target; - uint32_t timeout, status; - int i, retval = ERROR_OK; - - if (target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - LOG_INFO("Nuvoton NuMicro: Sector Erase ... (%d to %d)", first, last); - - retval = numicro_init_isp(target); - if (retval != ERROR_OK) - return retval; - - retval = target_write_u32(target, NUMICRO_FLASH_ISPCMD, ISPCMD_ERASE); - if (retval != ERROR_OK) - return retval; - - for (i = first; i <= last; i++) { - LOG_DEBUG("erasing sector %d at address 0x%" PRIx32 "", i, bank->base + bank->sectors[i].offset); - retval = target_write_u32(target, NUMICRO_FLASH_ISPADR, bank->base + bank->sectors[i].offset); - if (retval != ERROR_OK) - return retval; - retval = target_write_u32(target, NUMICRO_FLASH_ISPTRG, ISPTRG_ISPGO); /* This is the only bit available */ - if (retval != ERROR_OK) - return retval; - - /* wait for busy to clear - check the GO flag */ - timeout = 100; - for (;;) { - retval = target_read_u32(target, NUMICRO_FLASH_ISPTRG, &status); - if (retval != ERROR_OK) - return retval; - LOG_DEBUG("status: 0x%" PRIx32 "", status); - if (status == 0) - break; - if (timeout-- <= 0) { - LOG_DEBUG("timed out waiting for flash"); - return ERROR_FAIL; - } - busy_sleep(1); /* can use busy sleep for short times. */ - } - - /* check for failure */ - retval = target_read_u32(target, NUMICRO_FLASH_ISPCON, &status); - if (retval != ERROR_OK) - return retval; - if ((status & ISPCON_ISPFF) != 0) { - LOG_DEBUG("failure: 0x%" PRIx32 "", status); - /* if bit is set, then must write to it to clear it. */ - retval = target_write_u32(target, NUMICRO_FLASH_ISPCON, (status | ISPCON_ISPFF)); - if (retval != ERROR_OK) - return retval; - } else { - bank->sectors[i].is_erased = 1; - } - } - - /* done, */ - LOG_DEBUG("Erase done."); - - return ERROR_OK; -} - -/* The write routine stub. */ -static int numicro_write(struct flash_bank *bank, const uint8_t *buffer, - uint32_t offset, uint32_t count) -{ - struct target *target = bank->target; - uint32_t timeout, status; - uint8_t *new_buffer = NULL; - int retval = ERROR_OK; - - if (target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - LOG_INFO("Nuvoton NuMicro: Flash Write ..."); - - retval = numicro_init_isp(target); - if (retval != ERROR_OK) - return retval; - - retval = target_write_u32(target, NUMICRO_FLASH_ISPCMD, ISPCMD_WRITE); - if (retval != ERROR_OK) - return retval; - - if (count & 0x3) { - uint32_t old_count = count; - count = (old_count | 3) + 1; - new_buffer = malloc(count); - if (new_buffer == NULL) { - LOG_ERROR("odd number of bytes to write and no memory " - "for padding buffer"); - return ERROR_FAIL; - } - LOG_INFO("odd number of bytes to write (%d), extending to %d " - "and padding with 0xff", old_count, count); - memset(new_buffer, 0xff, count); - buffer = memcpy(new_buffer, buffer, old_count); - } - - uint32_t words_remaining = count / 4; - - /* try using a block write */ - retval = numicro_writeblock(bank, buffer, offset, words_remaining); - - if (retval == 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"); - - /* program command */ - for (uint32_t i = 0; i < count; i += 4) { - - LOG_DEBUG("write longword @ %08X", offset + i); - - uint8_t padding[4] = {0xff, 0xff, 0xff, 0xff}; - memcpy(padding, buffer + i, MIN(4, count-i)); - - retval = target_write_u32(target, NUMICRO_FLASH_ISPADR, bank->base + offset + i); - if (retval != ERROR_OK) - return retval; - retval = target_write_memory(target, NUMICRO_FLASH_ISPDAT, 4, 1, padding); - if (retval != ERROR_OK) - return retval; - retval = target_write_u32(target, NUMICRO_FLASH_ISPTRG, ISPTRG_ISPGO); - if (retval != ERROR_OK) - return retval; - - /* wait for busy to clear - check the GO flag */ - timeout = 100; - for (;;) { - retval = target_read_u32(target, NUMICRO_FLASH_ISPTRG, &status); - if (retval != ERROR_OK) - return retval; - LOG_DEBUG("status: 0x%" PRIx32 "", status); - if (status == 0) - break; - if (timeout-- <= 0) { - LOG_DEBUG("timed out waiting for flash"); - return ERROR_FAIL; - } - busy_sleep(1); /* can use busy sleep for short times. */ - } - - } - } - - /* check for failure */ - retval = target_read_u32(target, NUMICRO_FLASH_ISPCON, &status); - if (retval != ERROR_OK) - return retval; - if ((status & ISPCON_ISPFF) != 0) { - LOG_DEBUG("failure: 0x%" PRIx32 "", status); - /* if bit is set, then must write to it to clear it. */ - retval = target_write_u32(target, NUMICRO_FLASH_ISPCON, (status | ISPCON_ISPFF)); - if (retval != ERROR_OK) - return retval; - } else { - LOG_DEBUG("Write OK"); - } - - /* done. */ - LOG_DEBUG("Write done."); - - return ERROR_OK; -} - -static int numicro_get_cpu_type(struct target *target, const struct numicro_cpu_type** cpu) -{ - uint32_t part_id; - int retval = ERROR_OK; - - /* Read NuMicro PartID */ - retval = target_read_u32(target, NUMICRO_SYS_BASE, &part_id); - if (retval != ERROR_OK) { - LOG_WARNING("NuMicro flash driver: Failed to Get PartID\n"); - return ERROR_FLASH_OPERATION_FAILED; - } - - LOG_INFO("Device ID: 0x%08" PRIx32 "", part_id); - /* search part numbers */ - for (size_t i = 0; i < sizeof(NuMicroParts)/sizeof(NuMicroParts[0]); i++) { - if (part_id == NuMicroParts[i].partid) { - *cpu = &NuMicroParts[i]; - LOG_INFO("Device Name: %s", (*cpu)->partname); - return ERROR_OK; - } - } - - return ERROR_FAIL; -} - -static int numicro_get_flash_size(struct flash_bank *bank, const struct numicro_cpu_type *cpu, uint32_t *flash_size) -{ - for (size_t i = 0; i < cpu->n_banks; i++) { - if (bank->base == cpu->bank[i].base) { - *flash_size = cpu->bank[i].size; - LOG_INFO("bank base = 0x%08" PRIx32 ", size = 0x%08" PRIx32 "", bank->base, *flash_size); - return ERROR_OK; - } - } - return ERROR_FLASH_OPERATION_FAILED; -} - -static int numicro_probe(struct flash_bank *bank) -{ - uint32_t flash_size, offset = 0; - int num_pages; - const struct numicro_cpu_type *cpu; - struct target *target = bank->target; - int retval = ERROR_OK; - - retval = numicro_get_cpu_type(target, &cpu); - if (retval != ERROR_OK) { - LOG_WARNING("NuMicro flash driver: Failed to detect a known part\n"); - return ERROR_FLASH_OPERATION_FAILED; - } - - retval = numicro_get_flash_size(bank, cpu, &flash_size); - if (retval != ERROR_OK) { - LOG_WARNING("NuMicro flash driver: Failed to detect flash size\n"); - return ERROR_FLASH_OPERATION_FAILED; - } - - num_pages = flash_size / NUMICRO_PAGESIZE; - - bank->num_sectors = num_pages; - bank->sectors = malloc(sizeof(struct flash_sector) * num_pages); - bank->size = flash_size; - - for (int i = 0; i < num_pages; i++) { - bank->sectors[i].offset = offset; - bank->sectors[i].size = NUMICRO_PAGESIZE; - bank->sectors[i].is_erased = -1; - bank->sectors[i].is_protected = 0; - offset += NUMICRO_PAGESIZE; - } - - struct numicro_flash_bank *numicro_info = bank->driver_priv; - numicro_info->probed = true; - numicro_info->cpu = cpu; - LOG_DEBUG("Nuvoton NuMicro: Probed ..."); - - return ERROR_OK; -} - -/* Standard approach to autoprobing. */ -static int numicro_auto_probe(struct flash_bank *bank) -{ - struct numicro_flash_bank *numicro_info = bank->driver_priv; - if (numicro_info->probed) - return ERROR_OK; - return numicro_probe(bank); -} - - -/* This is the function called in the config file. */ -FLASH_BANK_COMMAND_HANDLER(numicro_flash_bank_command) -{ - struct numicro_flash_bank *bank_info; - - if (CMD_ARGC < 6) - return ERROR_COMMAND_SYNTAX_ERROR; - - LOG_DEBUG("add flash_bank numicro %s", bank->name); - - bank_info = malloc(sizeof(struct numicro_flash_bank)); - - memset(bank_info, 0, sizeof(struct numicro_flash_bank)); - - bank->driver_priv = bank_info; - - return ERROR_OK; - -} - -COMMAND_HANDLER(numicro_handle_read_isp_command) -{ - uint32_t address; - uint32_t ispdat; - int retval = ERROR_OK; - - if (CMD_ARGC != 1) - return ERROR_COMMAND_SYNTAX_ERROR; - - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], address); - - struct target *target = get_current_target(CMD_CTX); - - retval = numicro_init_isp(target); - if (retval != ERROR_OK) - return retval; - - retval = numicro_fmc_cmd(target, ISPCMD_READ, address, 0, &ispdat); - if (retval != ERROR_OK) - return retval; - - LOG_INFO("0x%08" PRIx32 ": 0x%08" PRIx32, address, ispdat); - - return ERROR_OK; -} - -COMMAND_HANDLER(numicro_handle_write_isp_command) -{ - uint32_t address; - uint32_t ispdat, rdat; - int retval = ERROR_OK; - - if (CMD_ARGC != 2) - return ERROR_COMMAND_SYNTAX_ERROR; - - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], address); - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], ispdat); - - struct target *target = get_current_target(CMD_CTX); - - retval = numicro_init_isp(target); - if (retval != ERROR_OK) - return retval; - - retval = numicro_fmc_cmd(target, ISPCMD_WRITE, address, ispdat, &rdat); - if (retval != ERROR_OK) - return retval; - - LOG_INFO("0x%08" PRIx32 ": 0x%08" PRIx32, address, ispdat); - return ERROR_OK; -} - -COMMAND_HANDLER(numicro_handle_chip_erase_command) -{ - int retval = ERROR_OK; - uint32_t rdat; - - if (CMD_ARGC != 0) - return ERROR_COMMAND_SYNTAX_ERROR; - - struct target *target = get_current_target(CMD_CTX); - - retval = numicro_init_isp(target); - if (retval != ERROR_OK) - return retval; - - retval = numicro_fmc_cmd(target, ISPCMD_CHIPERASE, 0, 0, &rdat); - if (retval != ERROR_OK) { - command_print(CMD_CTX, "numicro chip_erase failed"); - return retval; - } - - command_print(CMD_CTX, "numicro chip_erase complete"); - - return ERROR_OK; -} - -static const struct command_registration numicro_exec_command_handlers[] = { - { - .name = "read_isp", - .handler = numicro_handle_read_isp_command, - .usage = "address", - .mode = COMMAND_EXEC, - .help = "read flash through ISP.", - }, - { - .name = "write_isp", - .handler = numicro_handle_write_isp_command, - .usage = "address value", - .mode = COMMAND_EXEC, - .help = "write flash through ISP.", - }, - { - .name = "chip_erase", - .handler = numicro_handle_chip_erase_command, - .mode = COMMAND_EXEC, - .help = "chip erase through ISP.", - }, - COMMAND_REGISTRATION_DONE -}; - -static const struct command_registration numicro_command_handlers[] = { - { - .name = "numicro", - .mode = COMMAND_ANY, - .help = "numicro flash command group", - .usage = "", - .chain = numicro_exec_command_handlers, - }, - COMMAND_REGISTRATION_DONE -}; - -struct flash_driver numicro_flash = { - .name = "numicro", - .commands = numicro_command_handlers, - .flash_bank_command = numicro_flash_bank_command, - .erase = numicro_erase, - .write = numicro_write, - .read = default_flash_read, - .probe = numicro_probe, - .auto_probe = numicro_auto_probe, - .erase_check = default_flash_blank_check, - .protect_check = numicro_protect_check, -}; diff --git a/src/flash/nor/ocl.c b/src/flash/nor/ocl.c deleted file mode 100644 index 4ae565219..000000000 --- a/src/flash/nor/ocl.c +++ /dev/null @@ -1,343 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Pavel Chromy * - * chromy@asix.cz * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "imp.h" -#include "ocl.h" -#include - -struct ocl_priv { - struct arm_jtag *jtag_info; - unsigned int buflen; - unsigned int bufalign; -}; - -static int ocl_erase_check(struct flash_bank *bank) -{ - return ERROR_OK; -} - -static int ocl_protect_check(struct flash_bank *bank) -{ - return ERROR_OK; -} - -/* flash_bank ocl 0 0 0 0 */ -FLASH_BANK_COMMAND_HANDLER(ocl_flash_bank_command) -{ - struct arm7_9_common *arm7_9; - struct ocl_priv *ocl; - - if (CMD_ARGC < 6) - return ERROR_COMMAND_SYNTAX_ERROR; - - arm7_9 = target_to_arm7_9(bank->target); - if (!is_arm7_9(arm7_9)) - return ERROR_TARGET_INVALID; - - ocl = bank->driver_priv = malloc(sizeof(struct ocl_priv)); - ocl->jtag_info = &arm7_9->jtag_info; - ocl->buflen = 0; - ocl->bufalign = 1; - - return ERROR_OK; -} - -static int ocl_erase(struct flash_bank *bank, int first, int last) -{ - struct ocl_priv *ocl = bank->driver_priv; - int retval; - uint32_t dcc_buffer[3]; - - /* check preconditions */ - if (bank->num_sectors == 0) - return ERROR_FLASH_BANK_NOT_PROBED; - - if (bank->target->state != TARGET_RUNNING) { - LOG_ERROR("target has to be running to communicate with the loader"); - return ERROR_TARGET_NOT_RUNNING; - } - - if ((first == 0) && (last == bank->num_sectors - 1)) { - dcc_buffer[0] = OCL_ERASE_ALL; - retval = embeddedice_send(ocl->jtag_info, dcc_buffer, 1); - if (retval != ERROR_OK) - return retval; - } else { - dcc_buffer[0] = OCL_ERASE_BLOCK; - dcc_buffer[1] = first; - dcc_buffer[2] = last; - retval = embeddedice_send(ocl->jtag_info, dcc_buffer, 3); - if (retval != ERROR_OK) - return retval; - } - - /* wait for response, fixed timeout of 1 s */ - retval = embeddedice_handshake(ocl->jtag_info, EICE_COMM_CTRL_WBIT, 1000); - if (retval != ERROR_OK) - return retval; - - /* receive response */ - retval = embeddedice_receive(ocl->jtag_info, dcc_buffer + 1, 1); - if (retval != ERROR_OK) - return retval; - - if (dcc_buffer[1] != OCL_CMD_DONE) { - if (dcc_buffer[0] == OCL_ERASE_ALL) - LOG_ERROR("loader response to OCL_ERASE_ALL 0x%08" PRIx32 "", dcc_buffer[1]); - else - LOG_ERROR("loader response to OCL_ERASE_BLOCK 0x%08" PRIx32 "", dcc_buffer[1]); - return ERROR_FLASH_OPERATION_FAILED; - } - - return ERROR_OK; -} - -static int ocl_protect(struct flash_bank *bank, int set, int first, int last) -{ - return ERROR_OK; -} - -static int ocl_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count) -{ - struct ocl_priv *ocl = bank->driver_priv; - int retval; - uint32_t *dcc_buffer; - uint32_t *dcc_bufptr; - int byteofs; - int runlen; - uint32_t chksum; - - int i; - - /* check preconditions */ - if (ocl->buflen == 0 || ocl->bufalign == 0) - return ERROR_FLASH_BANK_NOT_PROBED; - - if (bank->target->state != TARGET_RUNNING) { - LOG_ERROR("target has to be running to communicate with the loader"); - return ERROR_TARGET_NOT_RUNNING; - } - - /* allocate buffer for max. ocl buffer + overhead */ - dcc_buffer = malloc(sizeof(uint32_t)*(ocl->buflen/4 + 3)); - - while (count) { - if (count + (offset % ocl->bufalign) > ocl->buflen) - runlen = ocl->buflen - (offset % ocl->bufalign); - else - runlen = count; - - dcc_buffer[0] = OCL_FLASH_BLOCK | runlen; - dcc_buffer[1] = offset; - dcc_bufptr = &dcc_buffer[2]; - - *dcc_bufptr = 0xffffffff; - byteofs = (offset % ocl->bufalign) % 4; - chksum = OCL_CHKS_INIT; - - /* copy data to DCC buffer in proper byte order and properly aligned */ - for (i = 0; i < runlen; i++) { - switch (byteofs++) { - case 0: - *dcc_bufptr &= *(buffer++) | 0xffffff00; - break; - case 1: - *dcc_bufptr &= ((*(buffer++)) << 8) | 0xffff00ff; - break; - case 2: - *dcc_bufptr &= ((*(buffer++)) << 16) | 0xff00ffff; - break; - case 3: - *dcc_bufptr &= ((*(buffer++)) << 24) | 0x00ffffff; - chksum ^= *(dcc_bufptr++); - *dcc_bufptr = 0xffffffff; - byteofs = 0; - break; - } - } - - /* add the remaining word to checksum */ - if (byteofs) - chksum ^= *(dcc_bufptr++); - - *(dcc_bufptr++) = chksum; - - /* send the data */ - retval = embeddedice_send(ocl->jtag_info, dcc_buffer, dcc_bufptr-dcc_buffer); - if (retval != ERROR_OK) { - free(dcc_buffer); - return retval; - } - - /* wait for response, fixed timeout of 1 s */ - retval = embeddedice_handshake(ocl->jtag_info, EICE_COMM_CTRL_WBIT, 1000); - if (retval != ERROR_OK) { - free(dcc_buffer); - return retval; - } - - /* receive response */ - retval = embeddedice_receive(ocl->jtag_info, dcc_buffer, 1); - if (retval != ERROR_OK) { - free(dcc_buffer); - return retval; - } - - if (dcc_buffer[0] != OCL_CMD_DONE) { - LOG_ERROR("loader response to OCL_FLASH_BLOCK 0x%08" PRIx32 "", dcc_buffer[0]); - free(dcc_buffer); - return ERROR_FLASH_OPERATION_FAILED; - } - - count -= runlen; - offset += runlen; - } - - free(dcc_buffer); - return ERROR_OK; -} - -static int ocl_probe(struct flash_bank *bank) -{ - struct ocl_priv *ocl = bank->driver_priv; - int retval; - uint32_t dcc_buffer[1]; - int sectsize; - int i; - - /* purge pending data in DCC */ - embeddedice_receive(ocl->jtag_info, dcc_buffer, 1); - - dcc_buffer[0] = OCL_PROBE; - retval = embeddedice_send(ocl->jtag_info, dcc_buffer, 1); - if (retval != ERROR_OK) - return retval; - - /* wait for response, fixed timeout of 1 s */ - retval = embeddedice_handshake(ocl->jtag_info, EICE_COMM_CTRL_WBIT, 1000); - if (retval != ERROR_OK) - return retval; - - /* receive response */ - retval = embeddedice_receive(ocl->jtag_info, dcc_buffer, 1); - if (retval != ERROR_OK) - return retval; - - if (dcc_buffer[0] != OCL_CMD_DONE) { - LOG_ERROR("loader response to OCL_PROBE 0x%08" PRIx32 "", dcc_buffer[0]); - return ERROR_FLASH_OPERATION_FAILED; - } - - /* receive and fill in parameters, detection of loader is important, receive it one by one */ - retval = embeddedice_handshake(ocl->jtag_info, EICE_COMM_CTRL_WBIT, 0); - if (retval != ERROR_OK) - return retval; - retval = embeddedice_receive(ocl->jtag_info, dcc_buffer, 1); - if (retval != ERROR_OK) - return retval; - bank->base = dcc_buffer[0]; - - retval = embeddedice_handshake(ocl->jtag_info, EICE_COMM_CTRL_WBIT, 0); - if (retval != ERROR_OK) - return retval; - retval = embeddedice_receive(ocl->jtag_info, dcc_buffer, 1); - if (retval != ERROR_OK) - return retval; - bank->size = dcc_buffer[0]; - - retval = embeddedice_handshake(ocl->jtag_info, EICE_COMM_CTRL_WBIT, 0); - if (retval != ERROR_OK) - return retval; - retval = embeddedice_receive(ocl->jtag_info, dcc_buffer, 1); - if (retval != ERROR_OK) - return retval; - bank->num_sectors = dcc_buffer[0]; - - retval = embeddedice_handshake(ocl->jtag_info, EICE_COMM_CTRL_WBIT, 0); - if (retval != ERROR_OK) - return retval; - retval = embeddedice_receive(ocl->jtag_info, dcc_buffer, 1); - if (retval != ERROR_OK) - return retval; - ocl->buflen = dcc_buffer[0] & 0xffff; - ocl->bufalign = dcc_buffer[0] >> 16; - - bank->sectors = realloc(bank->sectors, sizeof(struct flash_sector)*bank->num_sectors); - if (bank->num_sectors == 0) { - LOG_ERROR("number of sectors shall be non zero value"); - return ERROR_FLASH_BANK_INVALID; - } - if (bank->size % bank->num_sectors) { - LOG_ERROR("bank size not divisible by number of sectors"); - return ERROR_FLASH_BANK_INVALID; - } - sectsize = bank->size / bank->num_sectors; - for (i = 0; i < bank->num_sectors; i++) { - bank->sectors[i].offset = i * sectsize; - bank->sectors[i].size = sectsize; - bank->sectors[i].is_erased = -1; - bank->sectors[i].is_protected = -1; - } - - if (ocl->bufalign == 0) - ocl->bufalign = 1; - - if (ocl->buflen == 0) { - LOG_ERROR("buflen shall be non zero value"); - return ERROR_FLASH_BANK_INVALID; - } - - if ((ocl->bufalign > ocl->buflen) || (ocl->buflen % ocl->bufalign)) { - LOG_ERROR("buflen is not multiple of bufalign"); - return ERROR_FLASH_BANK_INVALID; - } - - if (ocl->buflen % 4) { - LOG_ERROR("buflen shall be divisible by 4"); - return ERROR_FLASH_BANK_INVALID; - } - - return ERROR_OK; -} - -static int ocl_auto_probe(struct flash_bank *bank) -{ - struct ocl_priv *ocl = bank->driver_priv; - - if (ocl->buflen == 0 || ocl->bufalign == 0) - return ERROR_FLASH_BANK_NOT_PROBED; - - return ERROR_OK; -} - -struct flash_driver ocl_flash = { - .name = "ocl", - .flash_bank_command = ocl_flash_bank_command, - .erase = ocl_erase, - .protect = ocl_protect, - .write = ocl_write, - .read = default_flash_read, - .probe = ocl_probe, - .erase_check = ocl_erase_check, - .protect_check = ocl_protect_check, - .auto_probe = ocl_auto_probe, -}; diff --git a/src/flash/nor/ocl.h b/src/flash/nor/ocl.h deleted file mode 100644 index 3e83f76cf..000000000 --- a/src/flash/nor/ocl.h +++ /dev/null @@ -1,39 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Pavel Chromy * - * chromy@asix.cz * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifndef OPENOCD_FLASH_NOR_OCL_H -#define OPENOCD_FLASH_NOR_OCL_H - -/* command/response mask */ -#define OCL_CMD_MASK 0xFFFF0000L - -/* commads */ -#define OCL_FLASH_BLOCK 0x0CFB0000L -#define OCL_ERASE_BLOCK 0x0CEB0000L -#define OCL_ERASE_ALL 0x0CEA0000L -#define OCL_PROBE 0x0CBE0000L - -/* responses */ -#define OCL_CMD_DONE 0x0ACD0000L -#define OCL_CMD_ERR 0x0ACE0000L -#define OCL_CHKS_FAIL 0x0ACF0000L -#define OCL_BUFF_OVER 0x0AB00000L - -#define OCL_CHKS_INIT 0xC100CD0CL - -#endif /* OPENOCD_FLASH_NOR_OCL_H */ diff --git a/src/flash/nor/pic32mx.c b/src/flash/nor/pic32mx.c deleted file mode 100644 index de212ed36..000000000 --- a/src/flash/nor/pic32mx.c +++ /dev/null @@ -1,984 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * Copyright (C) 2008 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * Copyright (C) 2008 by John McCarthy * - * jgmcc@magma.ca * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include "imp.h" -#include -#include -#include - -#define PIC32MX_MANUF_ID 0x029 - -/* pic32mx memory locations */ - -#define PIC32MX_PHYS_RAM 0x00000000 -#define PIC32MX_PHYS_PGM_FLASH 0x1D000000 -#define PIC32MX_PHYS_PERIPHERALS 0x1F800000 -#define PIC32MX_PHYS_BOOT_FLASH 0x1FC00000 - -/* - * Translate Virtual and Physical addresses. - * Note: These macros only work for KSEG0/KSEG1 addresses. - */ - -#define Virt2Phys(v) ((v) & 0x1FFFFFFF) - -/* pic32mx configuration register locations */ - -#define PIC32MX_DEVCFG0_1xx_2xx 0xBFC00BFC -#define PIC32MX_DEVCFG0 0xBFC02FFC -#define PIC32MX_DEVCFG1 0xBFC02FF8 -#define PIC32MX_DEVCFG2 0xBFC02FF4 -#define PIC32MX_DEVCFG3 0xBFC02FF0 -#define PIC32MX_DEVID 0xBF80F220 - -#define PIC32MX_BMXPFMSZ 0xBF882060 -#define PIC32MX_BMXBOOTSZ 0xBF882070 -#define PIC32MX_BMXDRMSZ 0xBF882040 - -/* pic32mx flash controller register locations */ - -#define PIC32MX_NVMCON 0xBF80F400 -#define PIC32MX_NVMCONCLR 0xBF80F404 -#define PIC32MX_NVMCONSET 0xBF80F408 -#define PIC32MX_NVMCONINV 0xBF80F40C -#define NVMCON_NVMWR (1 << 15) -#define NVMCON_NVMWREN (1 << 14) -#define NVMCON_NVMERR (1 << 13) -#define NVMCON_LVDERR (1 << 12) -#define NVMCON_LVDSTAT (1 << 11) -#define NVMCON_OP_PFM_ERASE 0x5 -#define NVMCON_OP_PAGE_ERASE 0x4 -#define NVMCON_OP_ROW_PROG 0x3 -#define NVMCON_OP_WORD_PROG 0x1 -#define NVMCON_OP_NOP 0x0 - -#define PIC32MX_NVMKEY 0xBF80F410 -#define PIC32MX_NVMADDR 0xBF80F420 -#define PIC32MX_NVMADDRCLR 0xBF80F424 -#define PIC32MX_NVMADDRSET 0xBF80F428 -#define PIC32MX_NVMADDRINV 0xBF80F42C -#define PIC32MX_NVMDATA 0xBF80F430 -#define PIC32MX_NVMSRCADDR 0xBF80F440 - -/* flash unlock keys */ - -#define NVMKEY1 0xAA996655 -#define NVMKEY2 0x556699AA - -#define MX_1xx_2xx 1 /* PIC32mx1xx/2xx */ -#define MX_17x_27x 2 /* PIC32mx17x/27x */ - -struct pic32mx_flash_bank { - int probed; - int dev_type; /* Default 0. 1 for Pic32MX1XX/2XX variant */ -}; - -/* - * DEVID values as per PIC32MX Flash Programming Specification Rev N - */ - -static const struct pic32mx_devs_s { - uint32_t devid; - const char *name; -} pic32mx_devs[] = { - {0x04A07053, "110F016B"}, - {0x04A09053, "110F016C"}, - {0x04A0B053, "110F016D"}, - {0x04A06053, "120F032B"}, - {0x04A08053, "120F032C"}, - {0x04A0A053, "120F032D"}, - {0x04D07053, "130F064B"}, - {0x04D09053, "130F064C"}, - {0x04D0B053, "130F064D"}, - {0x04D06053, "150F128B"}, - {0x04D08053, "150F128C"}, - {0x04D0A053, "150F128D"}, - {0x06610053, "170F256B"}, - {0x0661A053, "170F256D"}, - {0x04A01053, "210F016B"}, - {0x04A03053, "210F016C"}, - {0x04A05053, "210F016D"}, - {0x04A00053, "220F032B"}, - {0x04A02053, "220F032C"}, - {0x04A04053, "220F032D"}, - {0x04D01053, "230F064B"}, - {0x04D03053, "230F064C"}, - {0x04D05053, "230F064D"}, - {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"}, - {0x0092A053, "320F128L"}, - {0x00916053, "340F512H"}, - {0x00912053, "340F256H"}, - {0x0090D053, "340F128H"}, - {0x0090A053, "320F128H"}, - {0x00906053, "320F064H"}, - {0x00902053, "320F032H"}, - {0x00978053, "460F512L"}, - {0x00974053, "460F256L"}, - {0x0096D053, "440F128L"}, - {0x00952053, "440F256H"}, - {0x00956053, "440F512H"}, - {0x0094D053, "440F128H"}, - {0x00942053, "420F032H"}, - {0x04307053, "795F512L"}, - {0x0430E053, "795F512H"}, - {0x04306053, "775F512L"}, - {0x0430D053, "775F512H"}, - {0x04312053, "775F256L"}, - {0x04303053, "775F256H"}, - {0x04417053, "764F128L"}, - {0x0440B053, "764F128H"}, - {0x04341053, "695F512L"}, - {0x04325053, "695F512H"}, - {0x04311053, "675F512L"}, - {0x0430C053, "675F512H"}, - {0x04305053, "675F256L"}, - {0x0430B053, "675F256H"}, - {0x04413053, "664F128L"}, - {0x04407053, "664F128H"}, - {0x04411053, "664F064L"}, - {0x04405053, "664F064H"}, - {0x0430F053, "575F512L"}, - {0x04309053, "575F512H"}, - {0x04333053, "575F256L"}, - {0x04317053, "575F256H"}, - {0x0440F053, "564F128L"}, - {0x04403053, "564F128H"}, - {0x0440D053, "564F064L"}, - {0x04401053, "564F064H"}, - {0x04400053, "534F064H"}, - {0x0440C053, "534F064L"}, - {0x00000000, NULL} -}; - -/* flash bank pic32mx 0 0 - */ -FLASH_BANK_COMMAND_HANDLER(pic32mx_flash_bank_command) -{ - struct pic32mx_flash_bank *pic32mx_info; - - if (CMD_ARGC < 6) - return ERROR_COMMAND_SYNTAX_ERROR; - - pic32mx_info = malloc(sizeof(struct pic32mx_flash_bank)); - bank->driver_priv = pic32mx_info; - - pic32mx_info->probed = 0; - pic32mx_info->dev_type = 0; - - return ERROR_OK; -} - -static uint32_t pic32mx_get_flash_status(struct flash_bank *bank) -{ - struct target *target = bank->target; - uint32_t status; - - target_read_u32(target, PIC32MX_NVMCON, &status); - - return status; -} - -static uint32_t pic32mx_wait_status_busy(struct flash_bank *bank, int timeout) -{ - uint32_t status; - - /* wait for busy to clear */ - while (((status = pic32mx_get_flash_status(bank)) & NVMCON_NVMWR) && (timeout-- > 0)) { - LOG_DEBUG("status: 0x%" PRIx32, status); - alive_sleep(1); - } - if (timeout <= 0) - LOG_DEBUG("timeout: status: 0x%" PRIx32, status); - - return status; -} - -static int pic32mx_nvm_exec(struct flash_bank *bank, uint32_t op, uint32_t timeout) -{ - struct target *target = bank->target; - uint32_t status; - - target_write_u32(target, PIC32MX_NVMCON, NVMCON_NVMWREN | op); - - /* unlock flash registers */ - target_write_u32(target, PIC32MX_NVMKEY, NVMKEY1); - target_write_u32(target, PIC32MX_NVMKEY, NVMKEY2); - - /* start operation */ - target_write_u32(target, PIC32MX_NVMCONSET, NVMCON_NVMWR); - - status = pic32mx_wait_status_busy(bank, timeout); - - /* lock flash registers */ - target_write_u32(target, PIC32MX_NVMCONCLR, NVMCON_NVMWREN); - - return status; -} - -static int pic32mx_protect_check(struct flash_bank *bank) -{ - struct target *target = bank->target; - struct pic32mx_flash_bank *pic32mx_info = bank->driver_priv; - - uint32_t config0_address; - uint32_t devcfg0; - int s; - int num_pages; - - if (target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - 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); - - if ((devcfg0 & (1 << 28)) == 0) /* code protect bit */ - num_pages = 0xffff; /* All pages protected */ - else if (Virt2Phys(bank->base) == PIC32MX_PHYS_BOOT_FLASH) { - if (devcfg0 & (1 << 24)) - num_pages = 0; /* All pages unprotected */ - else - num_pages = 0xffff; /* All pages protected */ - } else { - /* pgm flash */ - 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++) - bank->sectors[s].is_protected = 1; - for (; s < bank->num_sectors; s++) - bank->sectors[s].is_protected = 0; - - return ERROR_OK; -} - -static int pic32mx_erase(struct flash_bank *bank, int first, int last) -{ - struct target *target = bank->target; - int i; - uint32_t status; - - if (bank->target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - if ((first == 0) && (last == (bank->num_sectors - 1)) - && (Virt2Phys(bank->base) == PIC32MX_PHYS_PGM_FLASH)) { - /* this will only erase the Program Flash (PFM), not the Boot Flash (BFM) - * we need to use the MTAP to perform a full erase */ - LOG_DEBUG("Erasing entire program flash"); - status = pic32mx_nvm_exec(bank, NVMCON_OP_PFM_ERASE, 50); - if (status & NVMCON_NVMERR) - return ERROR_FLASH_OPERATION_FAILED; - if (status & NVMCON_LVDERR) - return ERROR_FLASH_OPERATION_FAILED; - return ERROR_OK; - } - - for (i = first; i <= last; i++) { - target_write_u32(target, PIC32MX_NVMADDR, Virt2Phys(bank->base + bank->sectors[i].offset)); - - status = pic32mx_nvm_exec(bank, NVMCON_OP_PAGE_ERASE, 10); - - if (status & NVMCON_NVMERR) - return ERROR_FLASH_OPERATION_FAILED; - if (status & NVMCON_LVDERR) - return ERROR_FLASH_OPERATION_FAILED; - bank->sectors[i].is_erased = 1; - } - - return ERROR_OK; -} - -static int pic32mx_protect(struct flash_bank *bank, int set, int first, int last) -{ - struct target *target = bank->target; - - if (target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - return ERROR_OK; -} - -/* see contib/loaders/flash/pic32mx.s for src */ - -static uint32_t pic32mx_flash_write_code[] = { - /* write: */ - 0x3C08AA99, /* lui $t0, 0xaa99 */ - 0x35086655, /* ori $t0, 0x6655 */ - 0x3C095566, /* lui $t1, 0x5566 */ - 0x352999AA, /* ori $t1, 0x99aa */ - 0x3C0ABF80, /* lui $t2, 0xbf80 */ - 0x354AF400, /* ori $t2, 0xf400 */ - 0x340B4003, /* ori $t3, $zero, 0x4003 */ - 0x340C8000, /* ori $t4, $zero, 0x8000 */ - /* write_row: */ - 0x2CD30080, /* sltiu $s3, $a2, 128 */ - 0x16600008, /* bne $s3, $zero, write_word */ - 0x340D4000, /* ori $t5, $zero, 0x4000 */ - 0xAD450020, /* sw $a1, 32($t2) */ - 0xAD440040, /* sw $a0, 64($t2) */ - 0x04110016, /* bal progflash */ - 0x24840200, /* addiu $a0, $a0, 512 */ - 0x24A50200, /* addiu $a1, $a1, 512 */ - 0x1000FFF7, /* beq $zero, $zero, write_row */ - 0x24C6FF80, /* addiu $a2, $a2, -128 */ - /* write_word: */ - 0x3C15A000, /* lui $s5, 0xa000 */ - 0x36B50000, /* ori $s5, $s5, 0x0 */ - 0x00952025, /* or $a0, $a0, $s5 */ - 0x10000008, /* beq $zero, $zero, next_word */ - 0x340B4001, /* ori $t3, $zero, 0x4001 */ - /* prog_word: */ - 0x8C940000, /* lw $s4, 0($a0) */ - 0xAD540030, /* sw $s4, 48($t2) */ - 0xAD450020, /* sw $a1, 32($t2) */ - 0x04110009, /* bal progflash */ - 0x24840004, /* addiu $a0, $a0, 4 */ - 0x24A50004, /* addiu $a1, $a1, 4 */ - 0x24C6FFFF, /* addiu $a2, $a2, -1 */ - /* next_word: */ - 0x14C0FFF8, /* bne $a2, $zero, prog_word */ - 0x00000000, /* nop */ - /* done: */ - 0x10000002, /* beq $zero, $zero, exit */ - 0x24040000, /* addiu $a0, $zero, 0 */ - /* error: */ - 0x26240000, /* addiu $a0, $s1, 0 */ - /* exit: */ - 0x7000003F, /* sdbbp */ - /* progflash: */ - 0xAD4B0000, /* sw $t3, 0($t2) */ - 0xAD480010, /* sw $t0, 16($t2) */ - 0xAD490010, /* sw $t1, 16($t2) */ - 0xAD4C0008, /* sw $t4, 8($t2) */ - /* waitflash: */ - 0x8D500000, /* lw $s0, 0($t2) */ - 0x020C8024, /* and $s0, $s0, $t4 */ - 0x1600FFFD, /* bne $s0, $zero, waitflash */ - 0x00000000, /* nop */ - 0x00000000, /* nop */ - 0x00000000, /* nop */ - 0x00000000, /* nop */ - 0x00000000, /* nop */ - 0x8D510000, /* lw $s1, 0($t2) */ - 0x30113000, /* andi $s1, $zero, 0x3000 */ - 0x1620FFEF, /* bne $s1, $zero, error */ - 0xAD4D0004, /* sw $t5, 4($t2) */ - 0x03E00008, /* jr $ra */ - 0x00000000 /* nop */ -}; - -static int pic32mx_write_block(struct flash_bank *bank, const uint8_t *buffer, - uint32_t offset, uint32_t count) -{ - struct target *target = bank->target; - uint32_t buffer_size = 16384; - struct working_area *write_algorithm; - struct working_area *source; - uint32_t address = bank->base + offset; - struct reg_param reg_params[3]; - uint32_t row_size; - int retval = ERROR_OK; - - struct pic32mx_flash_bank *pic32mx_info = bank->driver_priv; - struct mips32_algorithm mips32_info; - - /* flash write code */ - if (target_alloc_working_area(target, sizeof(pic32mx_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; - } - - /* Change values for counters and row size, depending on variant */ - 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; - 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)]; - target_buffer_set_u32_array(target, code, ARRAY_SIZE(pic32mx_flash_write_code), - pic32mx_flash_write_code); - retval = target_write_buffer(target, write_algorithm->address, sizeof(code), code); - if (retval != ERROR_OK) - return retval; - - /* memory buffer */ - while (target_alloc_working_area_try(target, buffer_size, &source) != ERROR_OK) { - buffer_size /= 2; - if (buffer_size <= 256) { - /* we already allocated the writing code, but failed to get a - * buffer, free the algorithm */ - target_free_working_area(target, write_algorithm); - - LOG_WARNING("no large enough working area available, can't do block memory writes"); - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - } - } - - mips32_info.common_magic = MIPS32_COMMON_MAGIC; - mips32_info.isa_mode = MIPS32_ISA_MIPS32; - - 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; - if (row_offset && (count >= (row_size / 4))) { - new_buffer = malloc(buffer_size); - if (new_buffer == NULL) { - LOG_ERROR("Out of memory"); - return ERROR_FAIL; - } - memset(new_buffer, 0xff, row_offset); - address -= row_offset; - } else - row_offset = 0; - - while (count > 0) { - uint32_t status; - uint32_t thisrun_count; - - if (row_offset) { - thisrun_count = (count > ((buffer_size - row_offset) / 4)) ? - ((buffer_size - row_offset) / 4) : count; - - memcpy(new_buffer + row_offset, buffer, thisrun_count * 4); - - retval = target_write_buffer(target, source->address, - row_offset + thisrun_count * 4, new_buffer); - if (retval != ERROR_OK) - break; - } else { - thisrun_count = (count > (buffer_size / 4)) ? - (buffer_size / 4) : count; - - retval = target_write_buffer(target, source->address, - thisrun_count * 4, buffer); - if (retval != ERROR_OK) - break; - } - - buf_set_u32(reg_params[0].value, 0, 32, Virt2Phys(source->address)); - buf_set_u32(reg_params[1].value, 0, 32, Virt2Phys(address)); - buf_set_u32(reg_params[2].value, 0, 32, thisrun_count + row_offset / 4); - - retval = target_run_algorithm(target, 0, NULL, 3, reg_params, - write_algorithm->address, - 0, 10000, &mips32_info); - if (retval != ERROR_OK) { - LOG_ERROR("error executing pic32mx flash write algorithm"); - retval = ERROR_FLASH_OPERATION_FAILED; - break; - } - - status = buf_get_u32(reg_params[0].value, 0, 32); - - if (status & NVMCON_NVMERR) { - LOG_ERROR("Flash write error NVMERR (status = 0x%08" PRIx32 ")", status); - retval = ERROR_FLASH_OPERATION_FAILED; - break; - } - - if (status & NVMCON_LVDERR) { - LOG_ERROR("Flash write error LVDERR (status = 0x%08" PRIx32 ")", status); - retval = ERROR_FLASH_OPERATION_FAILED; - break; - } - - buffer += thisrun_count * 4; - address += thisrun_count * 4; - count -= thisrun_count; - if (row_offset) { - address += row_offset; - row_offset = 0; - } - } - - target_free_working_area(target, source); - target_free_working_area(target, write_algorithm); - - destroy_reg_param(®_params[0]); - destroy_reg_param(®_params[1]); - destroy_reg_param(®_params[2]); - - if (new_buffer != NULL) - free(new_buffer); - return retval; -} - -static int pic32mx_write_word(struct flash_bank *bank, uint32_t address, uint32_t word) -{ - struct target *target = bank->target; - - target_write_u32(target, PIC32MX_NVMADDR, Virt2Phys(address)); - target_write_u32(target, PIC32MX_NVMDATA, word); - - return pic32mx_nvm_exec(bank, NVMCON_OP_WORD_PROG, 5); -} - -static int pic32mx_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count) -{ - uint32_t words_remaining = (count / 4); - uint32_t bytes_remaining = (count & 0x00000003); - uint32_t address = bank->base + offset; - uint32_t bytes_written = 0; - uint32_t status; - int retval; - - if (bank->target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - LOG_DEBUG("writing to flash at address 0x%08" PRIx32 " at offset 0x%8.8" PRIx32 - " count: 0x%8.8" PRIx32 "", bank->base, offset, count); - - if (offset & 0x3) { - LOG_WARNING("offset 0x%" PRIx32 "breaks required 4-byte alignment", offset); - return ERROR_FLASH_DST_BREAKS_ALIGNMENT; - } - - /* multiple words (4-byte) to be programmed? */ - if (words_remaining > 0) { - /* try using a block write */ - retval = pic32mx_write_block(bank, buffer, offset, words_remaining); - if (retval != ERROR_OK) { - if (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE) { - /* if block write failed (no sufficient working area), - * we use normal (slow) single dword accesses */ - LOG_WARNING("couldn't use block writes, falling back to single memory accesses"); - } else if (retval == ERROR_FLASH_OPERATION_FAILED) { - LOG_ERROR("flash writing failed"); - return retval; - } - } else { - buffer += words_remaining * 4; - address += words_remaining * 4; - words_remaining = 0; - } - } - - while (words_remaining > 0) { - uint32_t value; - memcpy(&value, buffer + bytes_written, sizeof(uint32_t)); - - status = pic32mx_write_word(bank, address, value); - - if (status & NVMCON_NVMERR) { - LOG_ERROR("Flash write error NVMERR (status = 0x%08" PRIx32 ")", status); - return ERROR_FLASH_OPERATION_FAILED; - } - - if (status & NVMCON_LVDERR) { - LOG_ERROR("Flash write error LVDERR (status = 0x%08" PRIx32 ")", status); - return ERROR_FLASH_OPERATION_FAILED; - } - - bytes_written += 4; - words_remaining--; - address += 4; - } - - if (bytes_remaining) { - uint32_t value = 0xffffffff; - memcpy(&value, buffer + bytes_written, bytes_remaining); - - status = pic32mx_write_word(bank, address, value); - - if (status & NVMCON_NVMERR) { - LOG_ERROR("Flash write error NVMERR (status = 0x%08" PRIx32 ")", status); - return ERROR_FLASH_OPERATION_FAILED; - } - - if (status & NVMCON_LVDERR) { - LOG_ERROR("Flash write error LVDERR (status = 0x%08" PRIx32 ")", status); - return ERROR_FLASH_OPERATION_FAILED; - } - } - - return ERROR_OK; -} - -static int pic32mx_probe(struct flash_bank *bank) -{ - struct target *target = bank->target; - struct pic32mx_flash_bank *pic32mx_info = bank->driver_priv; - struct mips32_common *mips32 = target->arch_info; - struct mips_ejtag *ejtag_info = &mips32->ejtag_info; - int i; - uint32_t num_pages = 0; - uint32_t device_id; - int page_size; - - pic32mx_info->probed = 0; - - device_id = ejtag_info->idcode; - LOG_INFO("device id = 0x%08" PRIx32 " (manuf 0x%03x dev 0x%04x, ver 0x%02x)", - device_id, - (unsigned)((device_id >> 1) & 0x7ff), - (unsigned)((device_id >> 12) & 0xffff), - (unsigned)((device_id >> 28) & 0xf)); - - if (((device_id >> 1) & 0x7ff) != PIC32MX_MANUF_ID) { - LOG_WARNING("Cannot identify target as a PIC32MX family."); - return ERROR_FLASH_OPERATION_FAILED; - } - - /* 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[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; - } - } - - switch (pic32mx_info->dev_type) { - case MX_1xx_2xx: - case MX_17x_27x: - page_size = 1024; - break; - default: - page_size = 4096; - break; - } - - if (Virt2Phys(bank->base) == PIC32MX_PHYS_BOOT_FLASH) { - /* 0x1FC00000: Boot flash size */ -#if 0 - /* for some reason this register returns 8k for the boot bank size - * this does not match the docs, so for now set the boot bank at a - * fixed 12k */ - if (target_read_u32(target, PIC32MX_BMXBOOTSZ, &num_pages) != ERROR_OK) { - LOG_WARNING("PIC32MX flash size failed, probe inaccurate - assuming 12k flash"); - num_pages = (12 * 1024); - } -#else - /* fixed 12k boot bank - see comments above */ - switch (pic32mx_info->dev_type) { - case MX_1xx_2xx: - case MX_17x_27x: - num_pages = (3 * 1024); - 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) { - 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); - break; - default: - LOG_WARNING("PIC32MX flash size failed, probe inaccurate - assuming 512k flash"); - num_pages = (512 * 1024); - break; - } - } - } - - LOG_INFO("flash size = %" PRId32 "kbytes", num_pages / 1024); - - if (bank->sectors) { - free(bank->sectors); - bank->sectors = NULL; - } - - /* calculate numbers of pages */ - num_pages /= page_size; - bank->size = (num_pages * page_size); - bank->num_sectors = num_pages; - bank->sectors = malloc(sizeof(struct flash_sector) * num_pages); - - for (i = 0; i < (int)num_pages; i++) { - bank->sectors[i].offset = i * page_size; - bank->sectors[i].size = page_size; - bank->sectors[i].is_erased = -1; - bank->sectors[i].is_protected = 1; - } - - pic32mx_info->probed = 1; - - return ERROR_OK; -} - -static int pic32mx_auto_probe(struct flash_bank *bank) -{ - struct pic32mx_flash_bank *pic32mx_info = bank->driver_priv; - if (pic32mx_info->probed) - return ERROR_OK; - return pic32mx_probe(bank); -} - -static int pic32mx_info(struct flash_bank *bank, char *buf, int buf_size) -{ - struct target *target = bank->target; - struct mips32_common *mips32 = target->arch_info; - struct mips_ejtag *ejtag_info = &mips32->ejtag_info; - uint32_t device_id; - int printed = 0, i; - - device_id = ejtag_info->idcode; - - if (((device_id >> 1) & 0x7ff) != PIC32MX_MANUF_ID) { - snprintf(buf, buf_size, - "Cannot identify target as a PIC32MX family (manufacturer 0x%03d != 0x%03d)\n", - (unsigned)((device_id >> 1) & 0x7ff), - PIC32MX_MANUF_ID); - return ERROR_FLASH_OPERATION_FAILED; - } - - for (i = 0; pic32mx_devs[i].name != NULL; i++) { - if (pic32mx_devs[i].devid == (device_id & 0x0fffffff)) { - printed = snprintf(buf, buf_size, "PIC32MX%s", pic32mx_devs[i].name); - break; - } - } - - if (pic32mx_devs[i].name == NULL) - printed = snprintf(buf, buf_size, "Unknown"); - - buf += printed; - buf_size -= printed; - snprintf(buf, buf_size, " Ver: 0x%02x", - (unsigned)((device_id >> 28) & 0xf)); - - return ERROR_OK; -} - -COMMAND_HANDLER(pic32mx_handle_pgm_word_command) -{ - uint32_t address, value; - int status, res; - - if (CMD_ARGC != 3) - return ERROR_COMMAND_SYNTAX_ERROR; - - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], address); - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], value); - - struct flash_bank *bank; - int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 2, &bank); - if (ERROR_OK != retval) - return retval; - - if (address < bank->base || address >= (bank->base + bank->size)) { - command_print(CMD_CTX, "flash address '%s' is out of bounds", CMD_ARGV[0]); - return ERROR_OK; - } - - res = ERROR_OK; - status = pic32mx_write_word(bank, address, value); - if (status & NVMCON_NVMERR) - res = ERROR_FLASH_OPERATION_FAILED; - if (status & NVMCON_LVDERR) - res = ERROR_FLASH_OPERATION_FAILED; - - if (res == ERROR_OK) - command_print(CMD_CTX, "pic32mx pgm word complete"); - else - command_print(CMD_CTX, "pic32mx pgm word failed (status = 0x%x)", status); - - return ERROR_OK; -} - -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; - int timeout = 10; - - if (CMD_ARGC < 1) { - command_print(CMD_CTX, "pic32mx unlock "); - 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; - - target = bank->target; - mips_m4k = target_to_m4k(target); - ejtag_info = &mips_m4k->mips32.ejtag_info; - - /* we have to use the MTAP to perform a full erase */ - mips_ejtag_set_instr(ejtag_info, MTAP_SW_MTAP); - mips_ejtag_set_instr(ejtag_info, MTAP_COMMAND); - - /* first check status of device */ - mchip_cmd = MCHP_STATUS; - mips_ejtag_drscan_8(ejtag_info, &mchip_cmd); - if (mchip_cmd & (1 << 7)) { - /* device is not locked */ - command_print(CMD_CTX, "pic32mx is already unlocked, erasing anyway"); - } - - /* unlock/erase device */ - mips_ejtag_drscan_8_out(ejtag_info, MCHP_ASERT_RST); - jtag_add_sleep(200); - - mips_ejtag_drscan_8_out(ejtag_info, MCHP_ERASE); - - do { - mchip_cmd = MCHP_STATUS; - mips_ejtag_drscan_8(ejtag_info, &mchip_cmd); - if (timeout-- == 0) { - LOG_DEBUG("timeout waiting for unlock: 0x%" PRIx32 "", mchip_cmd); - break; - } - alive_sleep(1); - } while ((mchip_cmd & (1 << 2)) || (!(mchip_cmd & (1 << 3)))); - - mips_ejtag_drscan_8_out(ejtag_info, MCHP_DE_ASSERT_RST); - - /* select ejtag tap */ - mips_ejtag_set_instr(ejtag_info, MTAP_SW_ETAP); - - command_print(CMD_CTX, "pic32mx unlocked.\n" - "INFO: a reset or power cycle is required " - "for the new settings to take effect."); - - return ERROR_OK; -} - -static const struct command_registration pic32mx_exec_command_handlers[] = { - { - .name = "pgm_word", - .usage = " ", - .handler = pic32mx_handle_pgm_word_command, - .mode = COMMAND_EXEC, - .help = "program a word", - }, - { - .name = "unlock", - .handler = pic32mx_handle_unlock_command, - .mode = COMMAND_EXEC, - .usage = "[bank_id]", - .help = "Unlock/Erase entire device.", - }, - COMMAND_REGISTRATION_DONE -}; - -static const struct command_registration pic32mx_command_handlers[] = { - { - .name = "pic32mx", - .mode = COMMAND_ANY, - .help = "pic32mx flash command group", - .usage = "", - .chain = pic32mx_exec_command_handlers, - }, - COMMAND_REGISTRATION_DONE -}; - -struct flash_driver pic32mx_flash = { - .name = "pic32mx", - .commands = pic32mx_command_handlers, - .flash_bank_command = pic32mx_flash_bank_command, - .erase = pic32mx_erase, - .protect = pic32mx_protect, - .write = pic32mx_write, - .read = default_flash_read, - .probe = pic32mx_probe, - .auto_probe = pic32mx_auto_probe, - .erase_check = default_flash_blank_check, - .protect_check = pic32mx_protect_check, - .info = pic32mx_info, -}; diff --git a/src/flash/nor/psoc4.c b/src/flash/nor/psoc4.c deleted file mode 100644 index c7c85737c..000000000 --- a/src/flash/nor/psoc4.c +++ /dev/null @@ -1,812 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * Copyright (C) 2008 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * Copyright (C) 2011 by Andreas Fritiofson * - * andreas.fritiofson@gmail.com * - * * - * Copyright (C) 2014 by Tomas Vanek (PSoC 4 support derived from STM32) * - * vanekt@fbl.cz * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "imp.h" -#include -#include -#include -#include - -/* device documets: - - PSoC(R) 4: PSoC 4200 Family Datasheet - Document Number: 001-87197 Rev. *B Revised August 29, 2013 - - PSoC 4100/4200 Family PSoC(R) 4 Architecture TRM - Document No. 001-85634 Rev. *C March 25, 2014 - - PSoC(R) 4 Registers TRM Spec. - Document No. 001-85847 Rev. *A June 25, 2013 - - CY8C41xx, CY8C42xx Programming Specifications - Document No. 001-81799 Rev. *C March 4, 2014 -*/ - -/* register locations */ -#define PSOC4_CPUSS_SYSREQ 0x40000004 -#define PSOC4_CPUSS_SYSARG 0x40000008 -#define PSOC4_TEST_MODE 0x40030014 -#define PSOC4_SPCIF_GEOMETRY 0x400E0000 - -#define PSOC4_SFLASH_MACRO 0x0ffff000 - -/* constants */ -#define PSOC4_SROM_KEY1 0xb6 -#define PSOC4_SROM_KEY2 0xd3 -#define PSOC4_SROM_SYSREQ_BIT (1<<31) -#define PSOC4_SROM_HMASTER_BIT (1<<30) -#define PSOC4_SROM_PRIVILEGED_BIT (1<<28) -#define PSOC4_SROM_STATUS_SUCCEEDED 0xa0000000 -#define PSOC4_SROM_STATUS_FAILED 0xf0000000 - -#define PSOC4_CMD_GET_SILICON_ID 0 -#define PSOC4_CMD_LOAD_LATCH 4 -#define PSOC4_CMD_WRITE_ROW 5 -#define PSOC4_CMD_PROGRAM_ROW 6 -#define PSOC4_CMD_ERASE_ALL 0xa -#define PSOC4_CMD_CHECKSUM 0xb -#define PSOC4_CMD_WRITE_PROTECTION 0xd - -#define PSOC4_CHIP_PROT_VIRGIN 0x0 -#define PSOC4_CHIP_PROT_OPEN 0x1 -#define PSOC4_CHIP_PROT_PROTECTED 0x2 -#define PSOC4_CHIP_PROT_KILL 0x4 - - -struct psoc4_chip_details { - uint16_t id; - const char *type; - const char *package; - uint32_t flash_size_in_kb; -}; - -/* list of PSoC 4 chips - * flash_size_in_kb is not necessary as it can be decoded from SPCIF_GEOMETRY - */ -const struct psoc4_chip_details psoc4_devices[] = { - /* 4200 series */ - { 0x04A6, "CY8C4245PVI-482", "SSOP-28", .flash_size_in_kb = 32 }, - { 0x04B6, "CY8C4245LQI-483", "QFN-40", .flash_size_in_kb = 32 }, - { 0x04C8, "CY8C4245AXI-483", "TQFP-44", .flash_size_in_kb = 32 }, - { 0x04FB, "CY8C4245AXI-473", "TQFP-44", .flash_size_in_kb = 32 }, - { 0x04F0, "CY8C4244PVI-432", "SSOP-28", .flash_size_in_kb = 16 }, - { 0x04F1, "CY8C4244PVI-442", "SSOP-28", .flash_size_in_kb = 16 }, - { 0x04F6, "CY8C4244LQI-443", "QFN-40", .flash_size_in_kb = 16 }, - { 0x04FA, "CY8C4244AXI-443", "TQFP-44", .flash_size_in_kb = 16 }, - - /* 4100 series */ - { 0x0410, "CY8C4124PVI-432", "SSOP-28", .flash_size_in_kb = 16 }, - { 0x0411, "CY8C4124PVI-442", "SSOP-28", .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 }, - { 0x0416, "CY8C4125AXI-483", "TQFP-44", .flash_size_in_kb = 32 }, - - /* CCG1 series */ - { 0x0490, "CYPD1103-35FNXI", "CSP-35", .flash_size_in_kb = 32 }, - { 0x0489, "CYPD1121-40LQXI", "QFN-40", .flash_size_in_kb = 32 }, - { 0x048A, "CYPD1122-40LQXI", "QFN-40", .flash_size_in_kb = 32 }, - { 0x0491, "CYPD1131-35FNXI", "CSP-35", .flash_size_in_kb = 32 }, - { 0x0498, "CYPD1132-16SXI", "SOIC-16", .flash_size_in_kb = 32 }, - { 0x0481, "CYPD1134-28PVXI", "SSOP-28", .flash_size_in_kb = 32 }, - { 0x048B, "CYPD1134-40LQXI", "QFN-40", .flash_size_in_kb = 32 }, -}; - - -struct psoc4_flash_bank { - uint32_t row_size; - uint32_t user_bank_size; - int probed; - uint32_t silicon_id; - uint8_t chip_protection; - uint8_t cmd_program_row; -}; - - -static const struct psoc4_chip_details *psoc4_details_by_id(uint32_t silicon_id) -{ - const struct psoc4_chip_details *p = psoc4_devices; - unsigned int i; - uint16_t id = silicon_id >> 16; /* ignore die revision */ - for (i = 0; i < sizeof(psoc4_devices)/sizeof(psoc4_devices[0]); i++, p++) { - if (p->id == id) - return p; - } - LOG_DEBUG("Unknown PSoC 4 device silicon id 0x%08" PRIx32 ".", silicon_id); - return NULL; -} - -static const char *psoc4_decode_chip_protection(uint8_t protection) -{ - switch (protection) { - case PSOC4_CHIP_PROT_VIRGIN: - return "protection VIRGIN"; - case PSOC4_CHIP_PROT_OPEN: - return "protection open"; - case PSOC4_CHIP_PROT_PROTECTED: - return "PROTECTED"; - case PSOC4_CHIP_PROT_KILL: - return "protection KILL"; - default: - LOG_WARNING("Unknown protection state 0x%02" PRIx8 "", protection); - return ""; - } -} - - -/* flash bank psoc 0 0 - */ -FLASH_BANK_COMMAND_HANDLER(psoc4_flash_bank_command) -{ - struct psoc4_flash_bank *psoc4_info; - - if (CMD_ARGC < 6) - return ERROR_COMMAND_SYNTAX_ERROR; - - psoc4_info = calloc(1, sizeof(struct psoc4_flash_bank)); - - bank->driver_priv = psoc4_info; - psoc4_info->user_bank_size = bank->size; - - return ERROR_OK; -} - - -/* PSoC 4 system ROM request - * Setting SROM_SYSREQ_BIT in CPUSS_SYSREQ register runs NMI service - * in sysrem ROM. Algorithm just waits for NMI to finish. - * When sysreq_params_size == 0 only one parameter is passed in CPUSS_SYSARG register. - * Otherwise address of memory parameter block is set in CPUSS_SYSARG - * and the first parameter is written to the first word of parameter block - */ -static int psoc4_sysreq(struct target *target, uint8_t cmd, uint16_t cmd_param, - uint32_t *sysreq_params, uint32_t sysreq_params_size) -{ - struct working_area *sysreq_wait_algorithm; - struct working_area *sysreq_mem; - - struct reg_param reg_params[1]; - struct armv7m_algorithm armv7m_info; - - int retval = ERROR_OK; - - uint32_t param1 = PSOC4_SROM_KEY1 - | ((PSOC4_SROM_KEY2 + cmd) << 8) - | (cmd_param << 16); - - static uint8_t psoc4_sysreq_wait_code[] = { - /* system request NMI is served immediately after algo run - now we are done: break */ - 0x00, 0xbe, /* bkpt 0 */ - }; - - const int code_words = (sizeof(psoc4_sysreq_wait_code) + 3) / 4; - /* stack must be aligned */ - const int stack_size = 196; - /* tested stack sizes on PSoC 4: - ERASE_ALL 144 - PROGRAM_ROW 112 - other sysreq 68 - */ - - /* allocate area for sysreq wait code and stack */ - if (target_alloc_working_area(target, code_words * 4 + stack_size, - &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, - sysreq_wait_algorithm->address, - sizeof(psoc4_sysreq_wait_code), - psoc4_sysreq_wait_code); - if (retval != ERROR_OK) { - /* we already allocated the writing code, but failed to get a - * buffer, free the algorithm */ - goto cleanup_algo; - } - - if (sysreq_params_size) { - /* Allocate memory for sysreq_params */ - retval = target_alloc_working_area(target, sysreq_params_size, &sysreq_mem); - if (retval != ERROR_OK) { - LOG_WARNING("no working area for sysreq parameters"); - - /* we already allocated the writing code, but failed to get a - * buffer, free the algorithm */ - retval = ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - goto cleanup_algo; - } - - /* Write sysreq_params */ - sysreq_params[0] = param1; - retval = target_write_buffer(target, sysreq_mem->address, - sysreq_params_size, (uint8_t *)sysreq_params); - if (retval != ERROR_OK) - goto cleanup_mem; - - /* Set address of sysreq parameters block */ - retval = target_write_u32(target, PSOC4_CPUSS_SYSARG, sysreq_mem->address); - if (retval != ERROR_OK) - goto cleanup_mem; - - } else { - /* Sysreq without memory block of parameters */ - /* Set register parameter */ - retval = target_write_u32(target, PSOC4_CPUSS_SYSARG, param1); - if (retval != ERROR_OK) - goto cleanup_mem; - } - - armv7m_info.common_magic = ARMV7M_COMMON_MAGIC; - armv7m_info.core_mode = ARM_MODE_THREAD; - - /* sysreq stack */ - init_reg_param(®_params[0], "sp", 32, PARAM_OUT); - buf_set_u32(reg_params[0].value, 0, 32, - sysreq_wait_algorithm->address + sysreq_wait_algorithm->size); - - struct armv7m_common *armv7m = target_to_armv7m(target); - if (armv7m == NULL) { - - /* something is very wrong if armv7m is NULL */ - LOG_ERROR("unable to get armv7m target"); - goto cleanup; - } - - /* Set SROM request */ - retval = target_write_u32(target, PSOC4_CPUSS_SYSREQ, - PSOC4_SROM_SYSREQ_BIT | PSOC4_SROM_HMASTER_BIT | cmd); - if (retval != ERROR_OK) - goto cleanup; - - /* Execute wait code */ - retval = target_run_algorithm(target, 0, NULL, - sizeof(reg_params) / sizeof(*reg_params), reg_params, - sysreq_wait_algorithm->address, 0, 1000, &armv7m_info); - if (retval != ERROR_OK) - LOG_ERROR("sysreq wait code execution failed"); - -cleanup: - destroy_reg_param(®_params[0]); - -cleanup_mem: - if (sysreq_params_size) - target_free_working_area(target, sysreq_mem); - -cleanup_algo: - target_free_working_area(target, sysreq_wait_algorithm); - - return retval; -} - - -/* helper routine to get silicon ID from a PSoC 4 chip */ -static int psoc4_get_silicon_id(struct target *target, uint32_t *silicon_id, uint8_t *protection) -{ - uint32_t params = PSOC4_SROM_KEY1 - | ((PSOC4_SROM_KEY2 + PSOC4_CMD_GET_SILICON_ID) << 8); - uint32_t part0, part1; - - int retval = psoc4_sysreq(target, PSOC4_CMD_GET_SILICON_ID, 0, NULL, 0); - if (retval != ERROR_OK) - return retval; - - retval = target_read_u32(target, PSOC4_CPUSS_SYSARG, &part0); - if (retval != ERROR_OK) - return retval; - - if (part0 == params) { - LOG_ERROR("sysreq silicon id request not served"); - return ERROR_FAIL; - } - - retval = target_read_u32(target, PSOC4_CPUSS_SYSREQ, &part1); - if (retval != ERROR_OK) - return retval; - - uint32_t silicon = ((part0 & 0xffff) << 16) - | (((part0 >> 16) & 0xff) << 8) - | (part1 & 0xff); - uint8_t prot = (part1 >> 12) & 0xff; - - if (silicon_id) - *silicon_id = silicon; - if (protection) - *protection = prot; - - LOG_DEBUG("silicon id: 0x%08" PRIx32 "", silicon); - LOG_DEBUG("protection: 0x%02" PRIx8 "", prot); - return retval; -} - - -static int psoc4_protect_check(struct flash_bank *bank) -{ - struct target *target = bank->target; - struct psoc4_flash_bank *psoc4_info = bank->driver_priv; - - uint32_t prot_addr = PSOC4_SFLASH_MACRO; - uint32_t protection; - int i, s; - int num_bits; - int retval = ERROR_OK; - - num_bits = bank->num_sectors; - - for (i = 0; i < num_bits; i += 32) { - retval = target_read_u32(target, prot_addr, &protection); - if (retval != ERROR_OK) - return retval; - - prot_addr += 4; - - for (s = 0; s < 32; s++) { - if (i + s >= num_bits) - break; - bank->sectors[i + s].is_protected = (protection & (1 << s)) ? 1 : 0; - } - } - - retval = psoc4_get_silicon_id(target, NULL, &(psoc4_info->chip_protection)); - return retval; -} - - -static int psoc4_mass_erase(struct flash_bank *bank) -{ - struct target *target = bank->target; - int i; - - if (bank->target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - /* Call "Erase All" system ROM API */ - uint32_t param; - int retval = psoc4_sysreq(target, PSOC4_CMD_ERASE_ALL, - 0, - ¶m, sizeof(param)); - - if (retval == ERROR_OK) - /* set all sectors as erased */ - for (i = 0; i < bank->num_sectors; i++) - bank->sectors[i].is_erased = 1; - - return retval; -} - - -static int psoc4_erase(struct flash_bank *bank, int first, int last) -{ - struct psoc4_flash_bank *psoc4_info = bank->driver_priv; - if (psoc4_info->cmd_program_row == PSOC4_CMD_WRITE_ROW) { - LOG_INFO("Autoerase enabled, erase command ignored"); - return ERROR_OK; - } - - if ((first == 0) && (last == (bank->num_sectors - 1))) - return psoc4_mass_erase(bank); - - LOG_ERROR("Only mass erase available"); - - return ERROR_FAIL; -} - - -static int psoc4_protect(struct flash_bank *bank, int set, int first, int last) -{ - struct target *target = bank->target; - struct psoc4_flash_bank *psoc4_info = bank->driver_priv; - - if (psoc4_info->probed == 0) - return ERROR_FAIL; - - if (target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - uint32_t *sysrq_buffer = NULL; - int retval; - int num_bits = bank->num_sectors; - const int param_sz = 8; - int prot_sz = num_bits / 8; - int chip_prot = PSOC4_CHIP_PROT_OPEN; - int flash_macro = 0; /* PSoC 42xx has only macro 0 */ - int i; - - sysrq_buffer = calloc(1, param_sz + prot_sz); - if (sysrq_buffer == NULL) { - LOG_ERROR("no memory for row buffer"); - return ERROR_FAIL; - } - - for (i = first; i < num_bits && i <= last; i++) - bank->sectors[i].is_protected = set; - - uint32_t *p = sysrq_buffer + 2; - for (i = 0; i < num_bits; i++) { - if (bank->sectors[i].is_protected) - p[i / 32] |= 1 << (i % 32); - } - - /* Call "Load Latch" system ROM API */ - sysrq_buffer[1] = prot_sz - 1; - retval = psoc4_sysreq(target, PSOC4_CMD_LOAD_LATCH, - 0, /* Byte number in latch from what to write */ - sysrq_buffer, param_sz + psoc4_info->row_size); - if (retval != ERROR_OK) - goto cleanup; - - /* Call "Write Protection" system ROM API */ - retval = psoc4_sysreq(target, PSOC4_CMD_WRITE_PROTECTION, - chip_prot | (flash_macro << 8), NULL, 0); -cleanup: - if (retval != ERROR_OK) - psoc4_protect_check(bank); - - if (sysrq_buffer) - free(sysrq_buffer); - - return retval; -} - - -COMMAND_HANDLER(psoc4_handle_flash_autoerase_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; - - struct psoc4_flash_bank *psoc4_info = bank->driver_priv; - bool enable = psoc4_info->cmd_program_row == PSOC4_CMD_WRITE_ROW; - - if (CMD_ARGC >= 2) - COMMAND_PARSE_ON_OFF(CMD_ARGV[1], enable); - - if (enable) { - psoc4_info->cmd_program_row = PSOC4_CMD_WRITE_ROW; - LOG_INFO("Flash auto-erase enabled, non mass erase commands will be ignored."); - } else { - psoc4_info->cmd_program_row = PSOC4_CMD_PROGRAM_ROW; - LOG_INFO("Flash auto-erase disabled. Use psoc mass_erase before flash programming."); - } - - return retval; -} - - -static int psoc4_write(struct flash_bank *bank, const uint8_t *buffer, - uint32_t offset, uint32_t count) -{ - struct psoc4_flash_bank *psoc4_info = bank->driver_priv; - struct target *target = bank->target; - uint32_t *sysrq_buffer = NULL; - int retval = ERROR_OK; - const int param_sz = 8; - - if (bank->target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - if (offset & 0x1) { - LOG_ERROR("offset 0x%08" PRIx32 " breaks required 2-byte alignment", offset); - return ERROR_FLASH_DST_BREAKS_ALIGNMENT; - } - - sysrq_buffer = malloc(param_sz + psoc4_info->row_size); - if (sysrq_buffer == NULL) { - LOG_ERROR("no memory for row buffer"); - return ERROR_FAIL; - } - - uint8_t *row_buffer = (uint8_t *)sysrq_buffer + param_sz; - uint32_t row_num = offset / psoc4_info->row_size; - uint32_t row_offset = offset - row_num * psoc4_info->row_size; - if (row_offset) - memset(row_buffer, 0, row_offset); - - bool save_poll = jtag_poll_get_enabled(); - jtag_poll_set_enabled(false); - - while (count) { - uint32_t chunk_size = psoc4_info->row_size - row_offset; - if (chunk_size > count) { - chunk_size = count; - memset(row_buffer + chunk_size, 0, psoc4_info->row_size - chunk_size); - } - memcpy(row_buffer + row_offset, buffer, chunk_size); - LOG_DEBUG("offset / row: 0x%08" PRIx32 " / %" PRIu32 ", size %" PRIu32 "", - offset, row_offset, chunk_size); - - /* Call "Load Latch" system ROM API */ - sysrq_buffer[1] = psoc4_info->row_size - 1; - retval = psoc4_sysreq(target, PSOC4_CMD_LOAD_LATCH, - 0, /* Byte number in latch from what to write */ - sysrq_buffer, param_sz + psoc4_info->row_size); - if (retval != ERROR_OK) - goto cleanup; - - /* Call "Program Row" or "Write Row" system ROM API */ - uint32_t sysrq_param; - retval = psoc4_sysreq(target, psoc4_info->cmd_program_row, - row_num & 0xffff, - &sysrq_param, sizeof(sysrq_param)); - if (retval != ERROR_OK) - goto cleanup; - - buffer += chunk_size; - row_num++; - row_offset = 0; - count -= chunk_size; - } - -cleanup: - jtag_poll_set_enabled(save_poll); - - if (sysrq_buffer) - free(sysrq_buffer); - - return retval; -} - - -static int psoc4_probe(struct flash_bank *bank) -{ - struct psoc4_flash_bank *psoc4_info = bank->driver_priv; - struct target *target = bank->target; - uint32_t flash_size_in_kb = 0; - uint32_t max_flash_size_in_kb; - uint32_t cpu_id; - uint32_t silicon_id; - uint32_t row_size; - uint32_t base_address = 0x00000000; - uint8_t protection; - - if (target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - psoc4_info->probed = 0; - psoc4_info->cmd_program_row = PSOC4_CMD_PROGRAM_ROW; - - /* Get the CPUID from the ARM Core - * http://infocenter.arm.com/help/topic/com.arm.doc.ddi0432c/DDI0432C_cortex_m0_r0p0_trm.pdf 4.2.1 */ - int retval = target_read_u32(target, 0xE000ED00, &cpu_id); - if (retval != ERROR_OK) - return retval; - - LOG_DEBUG("cpu id = 0x%08" PRIx32 "", cpu_id); - - /* set page size, protection granularity and max flash size depending on family */ - switch ((cpu_id >> 4) & 0xFFF) { - case 0xc20: /* M0 -> PSoC4 */ - row_size = 128; - max_flash_size_in_kb = 32; - break; - default: - LOG_WARNING("Cannot identify target as a PSoC 4 family."); - return ERROR_FAIL; - } - - uint32_t spcif_geometry; - retval = target_read_u32(target, PSOC4_SPCIF_GEOMETRY, &spcif_geometry); - if (retval == ERROR_OK) { - row_size = 128 * ((spcif_geometry >> 22) & 3); - flash_size_in_kb = (spcif_geometry & 0xffff) * 256 / 1024; - LOG_INFO("SPCIF geometry: %" PRIu32 " kb flash, row %" PRIu32 " bytes.", - flash_size_in_kb, row_size); - } - - /* Early revisions of ST-Link v2 have some problem reading PSOC4_SPCIF_GEOMETRY - and an error is reported late. Dummy read gets this error. */ - uint32_t dummy; - target_read_u32(target, PSOC4_CPUSS_SYSREQ, &dummy); - - /* get silicon ID from target. */ - retval = psoc4_get_silicon_id(target, &silicon_id, &protection); - if (retval != ERROR_OK) - return retval; - - const struct psoc4_chip_details *details = psoc4_details_by_id(silicon_id); - if (details) { - LOG_INFO("%s device detected.", details->type); - if (flash_size_in_kb == 0) - flash_size_in_kb = details->flash_size_in_kb; - else if (flash_size_in_kb != details->flash_size_in_kb) - LOG_ERROR("Flash size mismatch"); - } - - psoc4_info->row_size = row_size; - psoc4_info->silicon_id = silicon_id; - psoc4_info->chip_protection = protection; - - /* 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("PSoC 4 flash size failed, probe inaccurate - assuming %" PRIu32 " k flash", - max_flash_size_in_kb); - flash_size_in_kb = max_flash_size_in_kb; - } - - /* if the user sets the size manually then ignore the probed value - * this allows us to work around devices that have a invalid flash size register value */ - if (psoc4_info->user_bank_size) { - LOG_INFO("ignoring flash probed value, using configured bank size"); - flash_size_in_kb = psoc4_info->user_bank_size / 1024; - } - - LOG_INFO("flash size = %" PRIu32 " kbytes", flash_size_in_kb); - - /* did we assign flash size? */ - assert(flash_size_in_kb != 0xffff); - - /* calculate numbers of pages */ - uint32_t num_rows = flash_size_in_kb * 1024 / row_size; - - /* check that calculation result makes sense */ - assert(num_rows > 0); - - if (bank->sectors) { - free(bank->sectors); - bank->sectors = NULL; - } - - bank->base = base_address; - bank->size = num_rows * row_size; - bank->num_sectors = num_rows; - bank->sectors = malloc(sizeof(struct flash_sector) * num_rows); - - uint32_t i; - for (i = 0; i < num_rows; i++) { - bank->sectors[i].offset = i * row_size; - bank->sectors[i].size = row_size; - bank->sectors[i].is_erased = -1; - bank->sectors[i].is_protected = 1; - } - - LOG_INFO("flash bank set %" PRIu32 " rows", num_rows); - psoc4_info->probed = 1; - - return ERROR_OK; -} - -static int psoc4_auto_probe(struct flash_bank *bank) -{ - struct psoc4_flash_bank *psoc4_info = bank->driver_priv; - if (psoc4_info->probed) - return ERROR_OK; - return psoc4_probe(bank); -} - - -static int get_psoc4_info(struct flash_bank *bank, char *buf, int buf_size) -{ - struct psoc4_flash_bank *psoc4_info = bank->driver_priv; - int printed = 0; - - if (psoc4_info->probed == 0) - return ERROR_FAIL; - - const struct psoc4_chip_details *details = psoc4_details_by_id(psoc4_info->silicon_id); - - if (details) { - uint32_t chip_revision = psoc4_info->silicon_id & 0xffff; - printed = snprintf(buf, buf_size, "PSoC 4 %s rev 0x%04" PRIx32 " package %s", - details->type, chip_revision, details->package); - } else - printed = snprintf(buf, buf_size, "PSoC 4 silicon id 0x%08" PRIx32 "", - psoc4_info->silicon_id); - - buf += printed; - buf_size -= printed; - - const char *prot_txt = psoc4_decode_chip_protection(psoc4_info->chip_protection); - uint32_t size_in_kb = bank->size / 1024; - snprintf(buf, buf_size, " flash %" PRIu32 " kb %s", size_in_kb, prot_txt); - return ERROR_OK; -} - - -COMMAND_HANDLER(psoc4_handle_mass_erase_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 = psoc4_mass_erase(bank); - if (retval == ERROR_OK) - command_print(CMD_CTX, "psoc mass erase complete"); - else - command_print(CMD_CTX, "psoc mass erase failed"); - - return retval; -} - - -static const struct command_registration psoc4_exec_command_handlers[] = { - { - .name = "mass_erase", - .handler = psoc4_handle_mass_erase_command, - .mode = COMMAND_EXEC, - .usage = "bank_id", - .help = "Erase entire flash device.", - }, - { - .name = "flash_autoerase", - .handler = psoc4_handle_flash_autoerase_command, - .mode = COMMAND_EXEC, - .usage = "bank_id on|off", - .help = "Set autoerase mode for flash bank.", - }, - COMMAND_REGISTRATION_DONE -}; - -static const struct command_registration psoc4_command_handlers[] = { - { - .name = "psoc4", - .mode = COMMAND_ANY, - .help = "PSoC 4 flash command group", - .usage = "", - .chain = psoc4_exec_command_handlers, - }, - COMMAND_REGISTRATION_DONE -}; - -struct flash_driver psoc4_flash = { - .name = "psoc4", - .commands = psoc4_command_handlers, - .flash_bank_command = psoc4_flash_bank_command, - .erase = psoc4_erase, - .protect = psoc4_protect, - .write = psoc4_write, - .read = default_flash_read, - .probe = psoc4_probe, - .auto_probe = psoc4_auto_probe, - .erase_check = default_flash_blank_check, - .protect_check = psoc4_protect_check, - .info = get_psoc4_info, -}; diff --git a/src/flash/nor/sim3x.c b/src/flash/nor/sim3x.c deleted file mode 100644 index ce9a21ed5..000000000 --- a/src/flash/nor/sim3x.c +++ /dev/null @@ -1,1126 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2014 by Ladislav Bábel * - * ladababel@seznam.cz * - * * - * Copyright (C) 2015 by Andreas Bomholtz * - * andreas@seluxit.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "imp.h" -#include -#include -#include -#include - -/* SI32_DEVICEID0 */ -#define DEVICEID0_DEVICEID0 (0x400490C0) -#define DEVICEID0_DEVICEID1 (0x400490D0) -#define DEVICEID0_DEVICEID2 (0x400490E0) -#define DEVICEID0_DEVICEID3 (0x400490F0) - -/* cortex_m CPUID */ -#define CPUID_CHECK_VALUE (0x410FC230) -#define CPUID_CHECK_VALUE_MASK (0xFF0FFFF0) - -/* Flash */ -#define FLASH_BASE_ADDRESS (0x00000000) -#define LOCK_WORD_ADDRESS (0x0003FFFC) - -#define LOCK_WORD_MCU_UNLOCKED (0xFFFFFFFF) -/* Can't by locked again without erase, because LOCK_WORD is in FLASH */ -#define LOCK_WORD_MCU_UNLOCKED_BY_FIRMWARE (0x00000000) - -/* SI32_FLASHCTRL_0 */ -#define FLASHCTRL0_CONFIG_ALL (0x4002E000) -#define FLASHCTRL0_CONFIG_SET (0x4002E004) -#define FLASHCTRL0_CONFIG_CLR (0x4002E008) -#define FLASHCTRL0_CONFIG_ERASEEN_MASK (0x00040000) -#define FLASHCTRL0_CONFIG_BUSYF_MASK (0x00100000) - -#define FLASHCTRL0_WRADDR (0x4002E0A0) -#define FLASHCTRL0_WRDATA (0x4002E0B0) - -#define FLASHCTRL0_KEY (0x4002E0C0) -#define FLASHCTRL0_KEY_INITIAL_UNLOCK (0x000000A5) -#define FLASHCTRL0_KEY_SINGLE_UNLOCK (0x000000F1) -#define FLASHCTRL0_KEY_MULTIPLE_UNLOCK (0x000000F2) -#define FLASHCTRL0_KEY_MULTIPLE_LOCK (0x0000005A) - -#define FLASH_BUSY_TIMEOUT (100) - -/* SI32_RSTSRC_0 */ -#define RSTSRC0_RESETEN_ALL (0x4002D060) -#define RSTSRC0_RESETEN_SET (0x4002D064) -#define RSTSRC0_RESETEN_CLR (0x4002D068) -#define RSTSRC0_RESETEN_VMONREN_MASK (0x00000004) -#define RSTSRC0_RESETEN_SWREN_MASK (0x00000040) - -/* SI32_VMON_0 */ -#define VMON0_CONTROL_ALL (0x4002F000) -#define VMON0_CONTROL_SET (0x4002F004) -#define VMON0_CONTROL_CLR (0x4002F008) -#define VMON0_CONTROL_VMONEN_MASK (0x80000000) - -/* SI32_CLKCTRL_0 */ -#define CLKCTRL0_APBCLKG0_ALL (0x4002D020) -#define CLKCTRL0_APBCLKG0_SET (0x4002D024) -#define CLKCTRL0_APBCLKG0_CLR (0x4002D028) -#define CLKCTRL0_APBCLKG0_FLCTRLCEN_MASK (0x40000000) - -/* SI32_WDTIMER_0 */ -#define WDTIMER0_CONTROL_ALL (0x40030000) -#define WDTIMER0_CONTROL_SET (0x40030004) -#define WDTIMER0_CONTROL_CLR (0x40030008) -#define WDTIMER0_CONTROL_DBGMD_MASK (0x00000002) - -#define WDTIMER0_STATUS_ALL (0x40030010) -#define WDTIMER0_STATUS_SET (0x40030014) -#define WDTIMER0_STATUS_CLR (0x40030018) -#define WDTIMER0_STATUS_KEYSTS_MASK (0x00000001) -#define WDTIMER0_STATUS_PRIVSTS_MASK (0x00000002) - -#define WDTIMER0_THRESHOLD (0x40030020) - -#define WDTIMER0_WDTKEY (0x40030030) -#define WDTIMER0_KEY_ATTN (0x000000A5) -#define WDTIMER0_KEY_WRITE (0x000000F1) -#define WDTIMER0_KEY_RESET (0x000000CC) -#define WDTIMER0_KEY_DISABLE (0x000000DD) -#define WDTIMER0_KEY_START (0x000000EE) -#define WDTIMER0_KEY_LOCK (0x000000FF) - -/* DAP */ -#define SIM3X_AP (0x0A) - -#define SIM3X_AP_CTRL1 (0x00) -#define SIM3X_AP_CTRL2 (0x04) -#define SIM3X_AP_LOCK (0x08) -#define SIM3X_AP_CRC (0x0C) - -#define SIM3X_AP_INIT_STAT (0x10) -#define SIM3X_AP_DAP_IN (0x14) -#define SIM3X_AP_DAP_OUT (0x18) - -#define SIM3X_AP_ID (0xFC) - -/* DAP register values */ -#define SIM3X_AP_CTRL1_MASS_ERASE_REQ (0x00000001) -#define SIM3X_AP_CTRL1_RESET_REQ (0x00000008) -/* this bit is set if MCU is locked */ -#define SIM3X_AP_INIT_STAT_LOCK (0x00000004) -/* expected value inside SIM3X_AP_ID */ -#define SIM3X_AP_ID_VALUE (0x2430002) - -#define SIM3X_FLASH_PAGE_SIZE 1024 - -struct sim3x_info { - uint16_t flash_size_kb; - uint16_t part_number; - char part_family; - uint8_t device_revision; - char device_package[4]; - bool probed; - bool need_init; - bool flash_locked; -}; - -/* flash bank sim3x 0 0 0 0 */ -FLASH_BANK_COMMAND_HANDLER(sim3x_flash_bank_command) -{ - struct sim3x_info *sim3x_info; - - if (CMD_ARGC < 6) - return ERROR_COMMAND_SYNTAX_ERROR; - - /* Init sim3x_info struct */ - sim3x_info = malloc(sizeof(struct sim3x_info)); - sim3x_info->probed = false; - sim3x_info->need_init = true; - sim3x_info->device_revision = 0; - memset(sim3x_info->device_package, 0, 4); - bank->driver_priv = sim3x_info; - - return ERROR_OK; -} - -static int sim3x_init(struct flash_bank *bank) -{ - int ret; - struct target *target; - struct sim3x_info *sim3x_info; - - target = bank->target; - - /* Disable watchdog timer */ - ret = target_write_u32(target, WDTIMER0_WDTKEY, WDTIMER0_KEY_ATTN); - if (ret != ERROR_OK) - return ret; - - ret = target_write_u32(target, WDTIMER0_WDTKEY, WDTIMER0_KEY_DISABLE); - if (ret != ERROR_OK) - return ret; - - /* Enable one write command */ - ret = target_write_u32(target, WDTIMER0_WDTKEY, WDTIMER0_KEY_ATTN); - if (ret != ERROR_OK) - return ret; - - ret = target_write_u32(target, WDTIMER0_WDTKEY, WDTIMER0_KEY_WRITE); - if (ret != ERROR_OK) - return ret; - - /* Watchdog Timer Debug Mode */ - ret = target_write_u32(target, WDTIMER0_CONTROL_SET, - WDTIMER0_CONTROL_DBGMD_MASK); - if (ret != ERROR_OK) - return ret; - - /* Enable VDD Supply Monitor */ - ret = target_write_u32(target, VMON0_CONTROL_SET, - VMON0_CONTROL_VMONEN_MASK); - if (ret != ERROR_OK) - return ret; - - /* Set VDD Supply Monitor as a reset source */ - ret = target_write_u32(target, RSTSRC0_RESETEN_SET, - RSTSRC0_RESETEN_VMONREN_MASK); - if (ret != ERROR_OK) - return ret; - - /* Flash Controller Clock Enable */ - ret = target_write_u32(target, CLKCTRL0_APBCLKG0_SET, - CLKCTRL0_APBCLKG0_FLCTRLCEN_MASK); - if (ret != ERROR_OK) - return ret; - - /* Disable Flash Erase Mode */ - ret = target_write_u32(target, FLASHCTRL0_CONFIG_CLR, - FLASHCTRL0_CONFIG_ERASEEN_MASK); - if (ret != ERROR_OK) - return ret; - - sim3x_info = bank->driver_priv; - sim3x_info->need_init = 0; - return ERROR_OK; -} - -static int sim3x_erase_page(struct flash_bank *bank, uint32_t addr) -{ - int ret, i; - uint32_t temp; - struct target *target; - - target = bank->target; - - for (i = 0; i < FLASH_BUSY_TIMEOUT; i++) { - ret = target_read_u32(target, FLASHCTRL0_CONFIG_ALL, &temp); - if (ret != ERROR_OK) - return ret; - - /* If is not busy */ - if ((temp & FLASHCTRL0_CONFIG_BUSYF_MASK) == 0) { - /* If erase is not enabled */ - if ((temp & FLASHCTRL0_CONFIG_ERASEEN_MASK) == 0) { - /* Enter Flash Erase Mode */ - ret = target_write_u32(target, FLASHCTRL0_CONFIG_SET, - FLASHCTRL0_CONFIG_ERASEEN_MASK); - if (ret != ERROR_OK) - return ret; - } - - /* Write the address of the Flash page to WRADDR */ - ret = target_write_u32(target, FLASHCTRL0_WRADDR, addr); - if (ret != ERROR_OK) - return ret; - - /* Write the inital unlock value to KEY */ - ret = target_write_u32(target, FLASHCTRL0_KEY, - FLASHCTRL0_KEY_INITIAL_UNLOCK); - if (ret != ERROR_OK) - return ret; - - /* Write the single unlock value to KEY */ - ret = target_write_u32(target, FLASHCTRL0_KEY, - FLASHCTRL0_KEY_SINGLE_UNLOCK); - if (ret != ERROR_OK) - return ret; - - /* Write any value to WRDATA to initiate the page erase */ - ret = target_write_u32(target, FLASHCTRL0_WRDATA, 0); - if (ret != ERROR_OK) - return ret; - - return ERROR_OK; - } - - alive_sleep(1); - } - - LOG_ERROR("timed out waiting for FLASHCTRL0_CONFIG_BUSYF"); - return ERROR_FAIL; -} - -static int sim3x_flash_erase(struct flash_bank *bank, int first, int last) -{ - int ret, i; - uint32_t temp; - struct sim3x_info *sim3x_info; - struct target *target; - - /* Check if target is halted */ - if (bank->target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - sim3x_info = bank->driver_priv; - - /* Init MCU after reset */ - if (sim3x_info->need_init) { - ret = sim3x_init(bank); - if (ret != ERROR_OK) { - LOG_ERROR("Failed to init MCU"); - return ret; - } - } - - /* erase pages */ - for (i = first; i <= last; i++) { - ret = sim3x_erase_page(bank, bank->sectors[i].offset); - if (ret != ERROR_OK) - return ret; - } - - target = bank->target; - - /* Wait until busy */ - for (i = 0; i < FLASH_BUSY_TIMEOUT; i++) { - ret = target_read_u32(target, FLASHCTRL0_CONFIG_ALL, &temp); - if (ret != ERROR_OK) - return ret; - - if ((temp & FLASHCTRL0_CONFIG_BUSYF_MASK) == 0) { /* If is not busy */ - if ((temp & FLASHCTRL0_CONFIG_ERASEEN_MASK) != 0) { /* If erase is enabled */ - /* Disable Flash Erase Mode */ - ret = target_write_u32(target, FLASHCTRL0_CONFIG_CLR, - FLASHCTRL0_CONFIG_ERASEEN_MASK); - if (ret != ERROR_OK) - return ret; - } - - return ERROR_OK; - } - - alive_sleep(1); - } - - LOG_ERROR("timed out waiting for FLASHCTRL0_CONFIG_BUSYF"); - return ERROR_FAIL; -} - -static int sim3x_write_block(struct flash_bank *bank, const uint8_t *buf, - uint32_t offset, uint32_t count) /* count is count of half words (2 bytes)! */ -{ - struct target *target = bank->target; - uint32_t buffer_size = 16384; - struct working_area *write_algorithm; - struct working_area *source; - uint32_t address = bank->base + offset; - struct reg_param reg_params[5]; - struct armv7m_algorithm armv7m_info; - int ret = ERROR_OK; - - /* see contrib/loaders/flash/sim3x.s for src */ - - static const uint8_t sim3x_flash_write_code[] = { - /* Write the initial unlock value to KEY (0xA5) */ - 0xA5, 0x26, /* movs r6, #INITIAL_UNLOCK */ - 0xC0, 0xF8, 0xC0, 0x60, /* str r6, [r0, #FLASHCTRL_KEY] */ - - /* Write the multiple unlock value to KEY (0xF2) */ - 0xF2, 0x26, /* movs r6, #MULTIPLE_UNLOCK */ - 0xC0, 0xF8, 0xC0, 0x60, /* str r6, [r0, #FLASHCTRL_KEY] */ - - /* wait_fifo: */ - 0x16, 0x68, /* ldr r6, [r2, #0] */ - 0x00, 0x2E, /* cmp r6, #0 */ - 0x16, 0xD0, /* beq exit */ - 0x55, 0x68, /* ldr r5, [r2, #4] */ - 0xB5, 0x42, /* cmp r5, r6 */ - 0xF9, 0xD0, /* beq wait_fifo */ - - /* wait for BUSYF flag */ - /* wait_busy1: */ - 0x06, 0x68, /* ldr r6, [r0, #FLASHCTRL_CONFIG] */ - 0x16, 0xF4, 0x80, 0x1F, /* tst r6, #BUSYF */ - 0xFB, 0xD1, /* bne wait_busy1 */ - - /* Write the destination address to WRADDR */ - 0xC0, 0xF8, 0xA0, 0x40, /* str r4, [r0, #FLASHCTRL_WRADDR] */ - - /* Write the data half-word to WRDATA in right-justified format */ - 0x2E, 0x88, /* ldrh r6, [r5] */ - 0xC0, 0xF8, 0xB0, 0x60, /* str r6, [r0, #FLASHCTRL_WRDATA] */ - - 0x02, 0x35, /* adds r5, #2 */ - 0x02, 0x34, /* adds r4, #2 */ - - /* wrap rp at end of buffer */ - 0x9D, 0x42, /* cmp r5, r3 */ - 0x01, 0xD3, /* bcc no_wrap */ - 0x15, 0x46, /* mov r5, r2 */ - 0x08, 0x35, /* adds r5, #8 */ - - /* no_wrap: */ - 0x55, 0x60, /* str r5, [r2, #4] */ - 0x49, 0x1E, /* subs r1, r1, #1 */ - 0x00, 0x29, /* cmp r1, #0 */ - 0x00, 0xD0, /* beq exit */ - 0xE5, 0xE7, /* b wait_fifo */ - - /* exit: */ - 0x5A, 0x26, /* movs r6, #MULTIPLE_LOCK */ - 0xC0, 0xF8, 0xC0, 0x60, /* str r6, [r0, #FLASHCTRL_KEY] */ - - /* wait for BUSYF flag */ - /* wait_busy2: */ - 0x06, 0x68, /* ldr r6, [r0, #FLASHCTRL_CONFIG] */ - 0x16, 0xF4, 0x80, 0x1F, /* tst r6, #BUSYF */ - 0xFB, 0xD1, /* bne wait_busy2 */ - - 0x00, 0xBE /* bkpt #0 */ - }; - - /* flash write code */ - if (target_alloc_working_area(target, sizeof(sim3x_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; - } - - ret = target_write_buffer(target, write_algorithm->address, - sizeof(sim3x_flash_write_code), sim3x_flash_write_code); - if (ret != ERROR_OK) - return ret; - - /* memory buffer */ - while (target_alloc_working_area_try(target, buffer_size, &source) != ERROR_OK) { - buffer_size /= 2; - buffer_size &= ~1UL; /* Make sure it's 2 byte aligned */ - if (buffer_size <= 256) { - /* we already allocated the writing code, but failed to get a - * buffer, free the algorithm - */ - target_free_working_area(target, write_algorithm); - - 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_OUT); /* flash base */ - init_reg_param(®_params[1], "r1", 32, PARAM_OUT); /* count */ - init_reg_param(®_params[2], "r2", 32, PARAM_OUT); /* buffer start */ - init_reg_param(®_params[3], "r3", 32, PARAM_OUT); /* buffer end */ - init_reg_param(®_params[4], "r4", 32, PARAM_IN_OUT); /* target address */ - - buf_set_u32(reg_params[0].value, 0, 32, FLASHCTRL0_CONFIG_ALL); - buf_set_u32(reg_params[1].value, 0, 32, count); - 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, address); - - armv7m_info.common_magic = ARMV7M_COMMON_MAGIC; - armv7m_info.core_mode = ARM_MODE_THREAD; - - ret = target_run_flash_async_algorithm(target, buf, count, 2, 0, NULL, 5, - reg_params, source->address, source->size, write_algorithm->address, - 0, &armv7m_info); - - if (ret == ERROR_FLASH_OPERATION_FAILED) { - LOG_ERROR("flash write failed at address 0x%"PRIx32, - buf_get_u32(reg_params[4].value, 0, 32)); - } - - target_free_working_area(target, source); - target_free_working_area(target, write_algorithm); - - 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 ret; -} - -static int sim3x_flash_write(struct flash_bank *bank, const uint8_t * buffer, uint32_t offset, uint32_t count) -{ - int ret; - struct target *target; - struct sim3x_info *sim3x_info; - uint8_t *new_buffer = NULL; - - target = bank->target; - - /* Check if target is halted */ - if (target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - sim3x_info = bank->driver_priv; - - if (sim3x_info->flash_locked) { - LOG_ERROR("Falsh is locked"); - return ERROR_FAIL; - } - - /* Init MCU after reset */ - if (sim3x_info->need_init) { - ret = sim3x_init(bank); - if (ret != ERROR_OK) - return ret; - } - - if (offset & 0x1) { - LOG_ERROR("offset 0x%" PRIx32 " breaks required 2-byte alignment", offset); - return ERROR_FLASH_DST_BREAKS_ALIGNMENT; - } - - if (count & 0x1) { - uint32_t old_count = count; - count++; - new_buffer = malloc(count); - - if (new_buffer == NULL) { - LOG_ERROR("odd number of bytes to write and no memory " - "for padding buffer"); - return ERROR_FAIL; - } - LOG_INFO("odd number of bytes to write (%" PRIu32 "), extending to %" PRIu32 - " and padding with 0xff", old_count, count); - - new_buffer[count - 1] = 0xff; - buffer = memcpy(new_buffer, buffer, old_count); - } - - ret = sim3x_write_block(bank, buffer, offset, count / 2); - free(new_buffer); - return ret; -} - -static int sim3x_flash_lock_check(struct flash_bank *bank) -{ - int ret; - uint32_t lock_word; - struct sim3x_info *sim3x_info; - - ret = target_read_u32(bank->target, LOCK_WORD_ADDRESS, &lock_word); - if (ret != ERROR_OK) { - LOG_ERROR("Can not read Lock Word"); - return ret; - } - - sim3x_info = bank->driver_priv; - sim3x_info->flash_locked = (lock_word != 0xFFFFFFFF); - - return ERROR_OK; -} - -static int sim3x_flash_protect_check(struct flash_bank *bank) -{ - int ret, i; - struct sim3x_info *sim3x_info; - - /* Check if target is halted */ - if (bank->target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - ret = sim3x_flash_lock_check(bank); - if (ret != ERROR_OK) - return ret; - - sim3x_info = bank->driver_priv; - - for (i = 0; i < bank->num_sectors; i++) - bank->sectors[i].is_protected = sim3x_info->flash_locked; - - return ERROR_OK; -} - -static int sim3x_flash_protect(struct flash_bank *bank, int set, int first, int last) -{ - int ret; - uint8_t lock_word[4]; - struct sim3x_info *sim3x_info; - struct target *target; - - target = bank->target; - - /* Check if target is halted */ - if (target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - if (first != 0 || last != bank->num_sectors - 1) { - LOG_ERROR("Flash does not support finer granularity"); - return ERROR_FAIL; - } - - sim3x_info = bank->driver_priv; - - if (set) { - if (sim3x_info->flash_locked) { - LOG_INFO("Flash is already locked"); - return ERROR_OK; - } - - /* Lock Flash */ - target_buffer_set_u32(target, lock_word, 0xFFFFFFFE); - ret = sim3x_flash_write(bank, lock_word, LOCK_WORD_ADDRESS, 4); - if (ret != ERROR_OK) - return ret; - - } else { - /* Flash is unlocked by an erase operation */ - ret = sim3x_flash_erase(bank, 0, 0); - if (ret != ERROR_OK) - return ret; - } - - ret = sim3x_flash_protect_check(bank); - if (ret != ERROR_OK) - return ret; - - if (set) { - if (sim3x_info->flash_locked) { - LOG_INFO("Flash locked"); - return ERROR_OK; - } else { - LOG_ERROR("Flash lock error"); - return ERROR_FAIL; - } - } else { - if (sim3x_info->flash_locked) { - LOG_ERROR("Flash unlock error"); - return ERROR_FAIL; - } else { - LOG_INFO("Flash unlocked"); - return ERROR_OK; - } - } -} - -static int sim3x_read_deviceid(struct flash_bank *bank) -{ - int ret; - struct sim3x_info *sim3x_info; - - uint32_t device_id; - int part_number; - char part_num_string[4]; - - sim3x_info = bank->driver_priv; - - /* MCU check */ - ret = target_read_u32(bank->target, DEVICEID0_DEVICEID2, &device_id); - if (ret != ERROR_OK) - return ret; - - /* Device ID should be 'M3' */ - if (device_id != 0x00004D33) - return ERROR_FAIL; - - /* Family and Part number */ - ret = target_read_u32(bank->target, DEVICEID0_DEVICEID1, &device_id); - if (ret != ERROR_OK) - return ret; - - part_num_string[0] = device_id >> 16; - part_num_string[1] = device_id >> 8; - part_num_string[2] = device_id; - part_num_string[3] = 0; - - part_number = atoi(part_num_string); - - /* Part Number should be between 100 and 999 */ - if (!isalpha(device_id >> 24) || part_number < 100 || part_number > 999) - return ERROR_FAIL; - - sim3x_info->part_family = device_id >> 24; - sim3x_info->part_number = part_number; - - /* Package and Revision */ - ret = target_read_u32(bank->target, DEVICEID0_DEVICEID0, &device_id); - if (ret != ERROR_OK) - return ret; - - sim3x_info->device_package[0] = device_id >> 24; - sim3x_info->device_package[1] = device_id >> 16; - sim3x_info->device_package[2] = device_id >> 8; - sim3x_info->device_package[3] = 0; - - sim3x_info->device_revision = device_id; - - return ERROR_OK; -} - -static int sim3x_parse_part_info(struct sim3x_info *sim3x_info) -{ - switch (sim3x_info->part_number) { - case 134: - case 136: - sim3x_info->flash_size_kb = 32; - break; - case 144: - case 146: - sim3x_info->flash_size_kb = 64; - break; - case 154: - case 156: - case 157: - sim3x_info->flash_size_kb = 128; - break; - case 164: - case 166: - case 167: - sim3x_info->flash_size_kb = 256; - break; - default: - LOG_ERROR("Unknown Part number %d", sim3x_info->part_number); - sim3x_info->part_number = 0; - return ERROR_FAIL; - } - - switch (sim3x_info->part_family) { - case 'c': - case 'C': - LOG_INFO("SiM3C%d detected", sim3x_info->part_number); - break; - case 'u': - case 'U': - LOG_INFO("SiM3U%d detected", sim3x_info->part_number); - break; - case 'l': - case 'L': - LOG_INFO("SiM3L%d detected", sim3x_info->part_number); - break; - default: - LOG_ERROR("Unsupported MCU family %c", sim3x_info->part_family); - sim3x_info->part_family = 0; - return ERROR_FAIL; - } - - return ERROR_OK; -} - -static int sim3x_read_info(struct flash_bank *bank) -{ - int ret; - struct sim3x_info *sim3x_info; - uint32_t cpuid; - - sim3x_info = bank->driver_priv; - - /* Core check */ - ret = target_read_u32(bank->target, CPUID, &cpuid); - if (ret != ERROR_OK) { - LOG_ERROR("Failed to read CPU ID"); - return ret; - } - - if (((cpuid >> 4) & 0xfff) != 0xc23) { - LOG_ERROR("Target is not Cortex-M3"); - return ERROR_FAIL; - } - - /* Read info from chip */ - ret = sim3x_read_deviceid(bank); - if (ret == ERROR_OK) { - ret = sim3x_parse_part_info(sim3x_info); - if (ret != ERROR_OK) { - LOG_ERROR("Failed to parse info from MCU"); - return ERROR_FAIL; - } - } else { - LOG_WARNING("Failed to read info from MCU, using info from flash bank parameters"); - - /* Check if flash size is given in flash bank command */ - if (!bank->size) { - LOG_ERROR("Flash size not set in the flash bank command"); - return ERROR_FAIL; - } - - /* Convert bank size to kb */ - sim3x_info->flash_size_kb = bank->size / 1024; - } - - LOG_INFO("Flash size = %dKB", sim3x_info->flash_size_kb); - - return ERROR_OK; -} - -static int sim3x_probe(struct flash_bank *bank) -{ - int ret, i; - struct sim3x_info *sim3x_info; - - sim3x_info = bank->driver_priv; - sim3x_info->probed = false; - sim3x_info->need_init = true; - - /* Read info from chip */ - ret = sim3x_read_info(bank); - if (ret != ERROR_OK) - return ret; - - ret = sim3x_flash_lock_check(bank); - if (ret != ERROR_OK) - return ret; - - if (bank->sectors) { - free(bank->sectors); - bank->sectors = NULL; - } - - bank->base = FLASH_BASE_ADDRESS; - bank->size = sim3x_info->flash_size_kb * SIM3X_FLASH_PAGE_SIZE; - bank->num_sectors = SIM3X_FLASH_PAGE_SIZE; - bank->sectors = malloc(sizeof(struct flash_sector) * sim3x_info->flash_size_kb); - - for (i = 0; i < sim3x_info->flash_size_kb; i++) { - bank->sectors[i].offset = i * SIM3X_FLASH_PAGE_SIZE; - bank->sectors[i].size = SIM3X_FLASH_PAGE_SIZE; - bank->sectors[i].is_erased = -1; - bank->sectors[i].is_protected = sim3x_info->flash_locked; - } - - sim3x_info->probed = true; - - return ERROR_OK; -} - -static int sim3x_auto_probe(struct flash_bank *bank) -{ - struct sim3x_info *sim3x_info; - - sim3x_info = bank->driver_priv; - - if (sim3x_info->probed) { - sim3x_info->need_init = true; - return ERROR_OK; - } else { - return sim3x_probe(bank); - } -} - -static int sim3x_flash_info(struct flash_bank *bank, char *buf, int buf_size) -{ - int ret; - int printed = 0; - struct sim3x_info *sim3x_info; - - sim3x_info = bank->driver_priv; - - /* Read info about chip */ - ret = sim3x_read_info(bank); - if (ret != ERROR_OK) - return ret; - - /* Part */ - if (sim3x_info->part_family && sim3x_info->part_number) { - printed = snprintf(buf, buf_size, "SiM3%c%d", sim3x_info->part_family, sim3x_info->part_number); - buf += printed; - buf_size -= printed; - - if (buf_size <= 0) - return ERROR_BUF_TOO_SMALL; - - /* Revision */ - if (sim3x_info->device_revision && sim3x_info->device_revision <= 'Z' - 'A') { - printed = snprintf(buf, buf_size, "-%c", sim3x_info->device_revision + 'A'); - buf += printed; - buf_size -= printed; - - if (buf_size <= 0) - return ERROR_BUF_TOO_SMALL; - - /* Package */ - printed = snprintf(buf, buf_size, "-G%s", sim3x_info->device_package); - buf += printed; - buf_size -= printed; - - if (buf_size <= 0) - return ERROR_BUF_TOO_SMALL; - } - } - - /* Print flash size */ - printed = snprintf(buf, buf_size, " flash_size = %dKB", sim3x_info->flash_size_kb); - buf_size -= printed; - - if (buf_size <= 0) - return ERROR_BUF_TOO_SMALL; - - return ERROR_OK; -} -/** - * reg 31:8 - no effect - * reg 7:4 - bank - * reg 3:2 - register - * reg 1:0 - no effect - */ -static int ap_write_register(struct adiv5_dap *dap, unsigned reg, uint32_t value) -{ - int retval; - LOG_DEBUG("DAP_REG[0x%02x] <- %08" PRIX32, reg, value); - - retval = dap_queue_ap_write(dap_ap(dap, SIM3X_AP), reg, value); - if (retval != ERROR_OK) { - LOG_DEBUG("DAP: failed to queue a write request"); - return retval; - } - - retval = dap_run(dap); - if (retval != ERROR_OK) { - LOG_DEBUG("DAP: dap_run failed"); - return retval; - } - - return ERROR_OK; -} - -static int ap_read_register(struct adiv5_dap *dap, unsigned reg, uint32_t *result) -{ - int retval; - - retval = dap_queue_ap_read(dap_ap(dap, SIM3X_AP), reg, result); - if (retval != ERROR_OK) { - LOG_DEBUG("DAP: failed to queue a read request"); - return retval; - } - - retval = dap_run(dap); - if (retval != ERROR_OK) { - LOG_DEBUG("DAP: dap_run failed"); - return retval; - } - - LOG_DEBUG("DAP_REG[0x%02x]: %08" PRIX32, reg, *result); - return ERROR_OK; -} - -static int ap_poll_register(struct adiv5_dap *dap, unsigned reg, uint32_t mask, uint32_t value, int timeout) -{ - uint32_t val; - int retval; - - do { - retval = ap_read_register(dap, reg, &val); - if (retval != ERROR_OK || (val & mask) == value) - return retval; - - alive_sleep(1); - } while (timeout--); - - LOG_DEBUG("DAP: polling timed out"); - return ERROR_FAIL; -} - -COMMAND_HANDLER(sim3x_mass_erase) -{ - uint32_t val; - int ret; - - 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; - - if (dap == NULL) { - /* Used debug interface doesn't support direct DAP access */ - LOG_ERROR("mass_erase can't be used by this debug interface"); - return ERROR_FAIL; - } - - ret = ap_read_register(dap, SIM3X_AP_ID, &val); - if (ret != ERROR_OK) - return ret; - - if (val != SIM3X_AP_ID_VALUE) { - LOG_ERROR("Wrong SIM3X_AP_ID"); - return ERROR_FAIL; - } - - /* Mass erase sequence */ - ret = ap_write_register(dap, SIM3X_AP_CTRL1, SIM3X_AP_CTRL1_RESET_REQ); - if (ret != ERROR_OK) - return ret; - - ret = ap_write_register(dap, SIM3X_AP_CTRL1, SIM3X_AP_CTRL1_RESET_REQ | SIM3X_AP_CTRL1_MASS_ERASE_REQ); - if (ret != ERROR_OK) - return ret; - - ret = ap_poll_register(dap, SIM3X_AP_CTRL1, SIM3X_AP_CTRL1_MASS_ERASE_REQ, 0x00000000, FLASH_BUSY_TIMEOUT); - if (ret != ERROR_OK) - return ret; - - ret = ap_write_register(dap, SIM3X_AP_CTRL1, 0x00000000); /* clear SIM3X_AP_CTRL1_RESET_REQ */ - if (ret != ERROR_OK) - return ret; - - LOG_INFO("Mass erase success"); - return ERROR_OK; -} - -COMMAND_HANDLER(sim3x_lock) -{ - uint32_t val; - int ret; - - 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; - - if (dap == NULL) { - /* Used debug interface doesn't support direct DAP access */ - LOG_INFO("Target can't by unlocked by this debug interface"); - - /* Core check */ - ret = target_read_u32(target, CPUID, &val); - if (ret != ERROR_OK) - return ret; - - if ((val & CPUID_CHECK_VALUE_MASK) != CPUID_CHECK_VALUE) { - LOG_ERROR("Target is not ARM Cortex-M3 or is already locked"); - return ERROR_FAIL; - } - } else { - /* check SIM3X_AP_ID */ - ret = ap_read_register(dap, SIM3X_AP_ID, &val); - if (ret != ERROR_OK) - return ret; - - if (val != SIM3X_AP_ID_VALUE) { - LOG_ERROR("Wrong SIM3X_AP_ID"); - return ERROR_FAIL; - } - - /* check if locked */ - ret = target_read_u32(target, CPUID, &val); - /* if correct value is read, then it will continue */ - if (ret != ERROR_OK || (val & CPUID_CHECK_VALUE_MASK) != CPUID_CHECK_VALUE) { - /* if correct value is'n read, then it will check SIM3X_AP_INIT_STAT register */ - ret = ap_read_register(dap, SIM3X_AP_INIT_STAT, &val); - if (ret != ERROR_OK) - return ret; - - if (val & SIM3X_AP_INIT_STAT_LOCK) { - LOG_INFO("Target is already locked"); - return ERROR_OK; - } else { - LOG_ERROR("Target doesn't seem to be locked but memory was not read correct"); - return ERROR_FAIL; - } - } - } - - ret = target_read_u32(target, LOCK_WORD_ADDRESS, &val); - if (ret != ERROR_OK) - return ret; - - if (val == LOCK_WORD_MCU_UNLOCKED) { - /* Lock Flash */ - uint8_t lock_word[4]; - target_buffer_set_u32(target, lock_word, 0xFFFFFFFE); - - /* Get Flash Bank */ - struct flash_bank *bank; - int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank); - if (retval != ERROR_OK) - return retval; - - ret = sim3x_flash_write(bank, lock_word, LOCK_WORD_ADDRESS, 4); - if (ERROR_OK != ret) - return ret; - - LOG_INFO("Target is successfully locked"); - return ERROR_OK; - } else if (val == LOCK_WORD_MCU_UNLOCKED_BY_FIRMWARE) { - /* Can't by locked again without erase, because LOCK_WORD is in FLASH */ - LOG_ERROR("Target is unlocked by firmware and can't by locked again without the lock page erase or mass erase"); - return ERROR_FAIL; - } else { - LOG_ERROR("Unexpected lock word value"); - - /* SIM3X_AP_ID_VALUE is not checked */ - if (dap == NULL) - LOG_INFO("Maybe this isn't a SiM3x MCU"); - - return ERROR_FAIL; - } -} - -static const struct command_registration sim3x_exec_command_handlers[] = { - { - .name = "mass_erase", - .mode = COMMAND_EXEC, - .help = "Erase the complete flash", - .usage = "", - .handler = sim3x_mass_erase, - }, - { - .name = "lock", - .mode = COMMAND_EXEC, - .help = "Locks the flash. Unlock by mass erase", - .usage = "", - .handler = sim3x_lock, - }, - COMMAND_REGISTRATION_DONE -}; - -static const struct command_registration sim3x_command_handlers[] = { - { - .name = "sim3x", - .mode = COMMAND_ANY, - .help = "sim3x flash command group", - .usage = "", - .chain = sim3x_exec_command_handlers, - }, - COMMAND_REGISTRATION_DONE -}; - -struct flash_driver sim3x_flash = { - .name = "sim3x", - .commands = sim3x_command_handlers, - .flash_bank_command = sim3x_flash_bank_command, - .erase = sim3x_flash_erase, - .protect = sim3x_flash_protect, - .write = sim3x_flash_write, - .read = default_flash_read, - .probe = sim3x_probe, - .auto_probe = sim3x_auto_probe, - .erase_check = default_flash_blank_check, - .protect_check = sim3x_flash_protect_check, - .info = sim3x_flash_info -}; diff --git a/src/flash/nor/spi.c b/src/flash/nor/spi.c deleted file mode 100644 index c8239d2d2..000000000 --- a/src/flash/nor/spi.c +++ /dev/null @@ -1,83 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2012 by George Harris * - * george@luminairecoffee.com * - * * - * Copyright (C) 2010 by Antonio Borneo * - * borneo.antonio@gmail.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "imp.h" -#include "spi.h" -#include - - /* Shared table of known SPI flash devices for SPI-based flash drivers. Taken - * from device datasheets and Linux SPI flash drivers. */ -const struct flash_device flash_devices[] = { - /* name, erase_cmd, chip_erase_cmd, device_id, pagesize, sectorsize, size_in_bytes */ - FLASH_ID("st m25p05", 0xd8, 0xc7, 0x00102020, 0x80, 0x8000, 0x10000), - FLASH_ID("st m25p10", 0xd8, 0xc7, 0x00112020, 0x80, 0x8000, 0x20000), - FLASH_ID("st m25p20", 0xd8, 0xc7, 0x00122020, 0x100, 0x10000, 0x40000), - FLASH_ID("st m25p40", 0xd8, 0xc7, 0x00132020, 0x100, 0x10000, 0x80000), - FLASH_ID("st m25p80", 0xd8, 0xc7, 0x00142020, 0x100, 0x10000, 0x100000), - FLASH_ID("st m25p16", 0xd8, 0xc7, 0x00152020, 0x100, 0x10000, 0x200000), - FLASH_ID("st m25p32", 0xd8, 0xc7, 0x00162020, 0x100, 0x10000, 0x400000), - FLASH_ID("st m25p64", 0xd8, 0xc7, 0x00172020, 0x100, 0x10000, 0x800000), - FLASH_ID("st m25p128", 0xd8, 0xc7, 0x00182020, 0x100, 0x40000, 0x1000000), - FLASH_ID("st m45pe10", 0xd8, 0xd8, 0x00114020, 0x100, 0x10000, 0x20000), - FLASH_ID("st m45pe20", 0xd8, 0xd8, 0x00124020, 0x100, 0x10000, 0x40000), - FLASH_ID("st m45pe40", 0xd8, 0xd8, 0x00134020, 0x100, 0x10000, 0x80000), - FLASH_ID("st m45pe80", 0xd8, 0xd8, 0x00144020, 0x100, 0x10000, 0x100000), - 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 s25fl032", 0xd8, 0xc7, 0x00150201, 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("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, 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("micron n25q064", 0xd8, 0xc7, 0x0017ba20, 0x100, 0x10000, 0x800000), - FLASH_ID("micron n25q128", 0xd8, 0xc7, 0x0018ba20, 0x100, 0x10000, 0x1000000), - FLASH_ID("issi is25lp128", 0xd8, 0xc7, 0x0018609d, 0x100, 0x10000, 0x1000000), - 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), - FLASH_ID("win w25q64cv", 0xd8, 0xc7, 0x001740ef, 0x100, 0x10000, 0x800000), - FLASH_ID("win w25q128fv", 0xd8, 0xc7, 0x001840ef, 0x100, 0x10000, 0x1000000), - FLASH_ID("gd gd25q20", 0x20, 0xc7, 0x00c84012, 0x100, 0x1000, 0x80000), - 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(NULL, 0, 0, 0, 0, 0, 0) -}; diff --git a/src/flash/nor/spi.h b/src/flash/nor/spi.h deleted file mode 100644 index a1849983f..000000000 --- a/src/flash/nor/spi.h +++ /dev/null @@ -1,61 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2012 by George Harris * - * george@luminairecoffee.com * - * * - * Copyright (C) 2010 by Antonio Borneo * - * borneo.antonio@gmail.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#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; - uint8_t erase_cmd; - uint8_t chip_erase_cmd; - uint32_t device_id; - uint32_t pagesize; - unsigned long sectorsize; - unsigned long size_in_bytes; -}; - -#define FLASH_ID(n, es, ces, id, psize, ssize, size) \ -{ \ - .name = n, \ - .erase_cmd = es, \ - .chip_erase_cmd = ces, \ - .device_id = id, \ - .pagesize = psize, \ - .sectorsize = ssize, \ - .size_in_bytes = size \ -} - -extern const struct flash_device flash_devices[]; - -/* fields in SPI flash status register */ -#define SPIFLASH_BSY_BIT 0x00000001 /* WIP Bit of SPI SR on SMI SR */ -#define SPIFLASH_WE_BIT 0x00000002 /* WEL Bit of SPI SR on SMI SR */ - -/* SPI Flash Commands */ -#define SPIFLASH_READ_ID 0x9F /* Read Flash Identification */ -#define SPIFLASH_READ_STATUS 0x05 /* Read Status Register */ -#define SPIFLASH_WRITE_ENABLE 0x06 /* Write Enable */ -#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 deleted file mode 100644 index d28ceee4b..000000000 --- a/src/flash/nor/stellaris.c +++ /dev/null @@ -1,1455 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2006 by Magnus Lundin * - * lundin@mlu.mine.nu * - * * - * Copyright (C) 2008 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -/*************************************************************************** -* STELLARIS flash is tested on LM3S811, LM3S6965, LM3s3748, more. -***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "jtag/interface.h" -#include "imp.h" -#include -#include - -#define DID0_VER(did0) ((did0 >> 28)&0x07) - -/* STELLARIS control registers */ -#define SCB_BASE 0x400FE000 -#define DID0 0x000 -#define DID1 0x004 -#define DC0 0x008 -#define DC1 0x010 -#define DC2 0x014 -#define DC3 0x018 -#define DC4 0x01C - -#define RIS 0x050 -#define RCC 0x060 -#define PLLCFG 0x064 -#define RCC2 0x070 -#define NVMSTAT 0x1a0 - -/* "legacy" flash memory protection registers (64KB max) */ -#define FMPRE 0x130 -#define FMPPE 0x134 - -/* new flash memory protection registers (for more than 64KB) */ -#define FMPRE0 0x200 /* PRE1 = PRE0 + 4, etc */ -#define FMPPE0 0x400 /* PPE1 = PPE0 + 4, etc */ - -#define USECRL 0x140 - -#define FLASH_CONTROL_BASE 0x400FD000 -#define FLASH_FMA (FLASH_CONTROL_BASE | 0x000) -#define FLASH_FMD (FLASH_CONTROL_BASE | 0x004) -#define FLASH_FMC (FLASH_CONTROL_BASE | 0x008) -#define FLASH_CRIS (FLASH_CONTROL_BASE | 0x00C) -#define FLASH_CIM (FLASH_CONTROL_BASE | 0x010) -#define FLASH_MISC (FLASH_CONTROL_BASE | 0x014) -#define FLASH_FSIZE (FLASH_CONTROL_BASE | 0xFC0) -#define FLASH_SSIZE (FLASH_CONTROL_BASE | 0xFC4) - -#define AMISC 1 -#define PMISC 2 - -#define AMASK 1 -#define PMASK 2 - -/* Flash Controller Command bits */ -#define FMC_WRKEY (0xA442 << 16) -#define FMC_COMT (1 << 3) -#define FMC_MERASE (1 << 2) -#define FMC_ERASE (1 << 1) -#define FMC_WRITE (1 << 0) - -/* STELLARIS constants */ - -/* values to write in FMA to commit write-"once" values */ -#define FLASH_FMA_PRE(x) (2 * (x)) /* for FMPPREx */ -#define FLASH_FMA_PPE(x) (2 * (x) + 1) /* for FMPPPEx */ - -static void stellaris_read_clock_info(struct flash_bank *bank); -static int stellaris_mass_erase(struct flash_bank *bank); - -struct stellaris_flash_bank { - /* chip id register */ - uint32_t did0; - uint32_t did1; - uint32_t dc0; - uint32_t dc1; - uint32_t fsize; - uint32_t ssize; - - const char *target_name; - uint8_t target_class; - - uint32_t sramsiz; - /* flash geometry */ - uint32_t num_pages; - uint32_t pagesize; - - /* main clock status */ - uint32_t rcc; - uint32_t rcc2; - uint8_t mck_valid; - uint8_t xtal_mask; - uint32_t iosc_freq; - uint32_t mck_freq; - const char *iosc_desc; - const char *mck_desc; -}; - -/* Autogenerated by contrib/gen-stellaris-part-header.pl */ -/* From Stellaris Firmware Development Package revision 9453 */ -static const struct { - uint8_t class; - uint8_t partno; - const char *partname; -} StellarisParts[] = { - {0x00, 0x01, "LM3S101"}, - {0x00, 0x02, "LM3S102"}, - {0x01, 0xBF, "LM3S1110"}, - {0x01, 0xC3, "LM3S1133"}, - {0x01, 0xC5, "LM3S1138"}, - {0x01, 0xC1, "LM3S1150"}, - {0x01, 0xC4, "LM3S1162"}, - {0x01, 0xC2, "LM3S1165"}, - {0x01, 0xEC, "LM3S1166"}, - {0x01, 0xC6, "LM3S1332"}, - {0x01, 0xBC, "LM3S1435"}, - {0x01, 0xBA, "LM3S1439"}, - {0x01, 0xBB, "LM3S1512"}, - {0x01, 0xC7, "LM3S1538"}, - {0x01, 0xDB, "LM3S1601"}, - {0x03, 0x06, "LM3S1607"}, - {0x01, 0xDA, "LM3S1608"}, - {0x01, 0xC0, "LM3S1620"}, - {0x04, 0xCD, "LM3S1621"}, - {0x03, 0x03, "LM3S1625"}, - {0x03, 0x04, "LM3S1626"}, - {0x03, 0x05, "LM3S1627"}, - {0x01, 0xB3, "LM3S1635"}, - {0x01, 0xEB, "LM3S1636"}, - {0x01, 0xBD, "LM3S1637"}, - {0x04, 0xB1, "LM3S1651"}, - {0x01, 0xB9, "LM3S1751"}, - {0x03, 0x10, "LM3S1776"}, - {0x04, 0x16, "LM3S1811"}, - {0x04, 0x3D, "LM3S1816"}, - {0x01, 0xB4, "LM3S1850"}, - {0x01, 0xDD, "LM3S1911"}, - {0x01, 0xDC, "LM3S1918"}, - {0x01, 0xB7, "LM3S1937"}, - {0x01, 0xBE, "LM3S1958"}, - {0x01, 0xB5, "LM3S1960"}, - {0x01, 0xB8, "LM3S1968"}, - {0x01, 0xEA, "LM3S1969"}, - {0x04, 0xCE, "LM3S1B21"}, - {0x06, 0xCA, "LM3S1C21"}, - {0x06, 0xCB, "LM3S1C26"}, - {0x06, 0x98, "LM3S1C58"}, - {0x06, 0xB0, "LM3S1D21"}, - {0x06, 0xCC, "LM3S1D26"}, - {0x06, 0x1D, "LM3S1F11"}, - {0x06, 0x1B, "LM3S1F16"}, - {0x06, 0xAF, "LM3S1G21"}, - {0x06, 0x95, "LM3S1G58"}, - {0x06, 0x1E, "LM3S1H11"}, - {0x06, 0x1C, "LM3S1H16"}, - {0x04, 0x0F, "LM3S1J11"}, - {0x04, 0x3C, "LM3S1J16"}, - {0x04, 0x0E, "LM3S1N11"}, - {0x04, 0x3B, "LM3S1N16"}, - {0x04, 0xB2, "LM3S1P51"}, - {0x04, 0x9E, "LM3S1R21"}, - {0x04, 0xC9, "LM3S1R26"}, - {0x04, 0x30, "LM3S1W16"}, - {0x04, 0x2F, "LM3S1Z16"}, - {0x01, 0x51, "LM3S2110"}, - {0x01, 0x84, "LM3S2139"}, - {0x03, 0x39, "LM3S2276"}, - {0x01, 0xA2, "LM3S2410"}, - {0x01, 0x59, "LM3S2412"}, - {0x01, 0x56, "LM3S2432"}, - {0x01, 0x5A, "LM3S2533"}, - {0x01, 0xE1, "LM3S2601"}, - {0x01, 0xE0, "LM3S2608"}, - {0x03, 0x33, "LM3S2616"}, - {0x01, 0x57, "LM3S2620"}, - {0x01, 0x85, "LM3S2637"}, - {0x01, 0x53, "LM3S2651"}, - {0x03, 0x80, "LM3S2671"}, - {0x03, 0x50, "LM3S2678"}, - {0x01, 0xA4, "LM3S2730"}, - {0x01, 0x52, "LM3S2739"}, - {0x03, 0x3A, "LM3S2776"}, - {0x04, 0x6D, "LM3S2793"}, - {0x01, 0xE3, "LM3S2911"}, - {0x01, 0xE2, "LM3S2918"}, - {0x01, 0xED, "LM3S2919"}, - {0x01, 0x54, "LM3S2939"}, - {0x01, 0x8F, "LM3S2948"}, - {0x01, 0x58, "LM3S2950"}, - {0x01, 0x55, "LM3S2965"}, - {0x04, 0x6C, "LM3S2B93"}, - {0x06, 0x94, "LM3S2D93"}, - {0x06, 0x93, "LM3S2U93"}, - {0x00, 0x19, "LM3S300"}, - {0x00, 0x11, "LM3S301"}, - {0x00, 0x1A, "LM3S308"}, - {0x00, 0x12, "LM3S310"}, - {0x00, 0x13, "LM3S315"}, - {0x00, 0x14, "LM3S316"}, - {0x00, 0x17, "LM3S317"}, - {0x00, 0x15, "LM3S328"}, - {0x03, 0x08, "LM3S3634"}, - {0x03, 0x43, "LM3S3651"}, - {0x04, 0xC8, "LM3S3654"}, - {0x03, 0x44, "LM3S3739"}, - {0x03, 0x49, "LM3S3748"}, - {0x03, 0x45, "LM3S3749"}, - {0x04, 0x42, "LM3S3826"}, - {0x04, 0x41, "LM3S3J26"}, - {0x04, 0x40, "LM3S3N26"}, - {0x04, 0x3F, "LM3S3W26"}, - {0x04, 0x3E, "LM3S3Z26"}, - {0x03, 0x81, "LM3S5632"}, - {0x04, 0x0C, "LM3S5651"}, - {0x03, 0x8A, "LM3S5652"}, - {0x04, 0x4D, "LM3S5656"}, - {0x03, 0x91, "LM3S5662"}, - {0x03, 0x96, "LM3S5732"}, - {0x03, 0x97, "LM3S5737"}, - {0x03, 0xA0, "LM3S5739"}, - {0x03, 0x99, "LM3S5747"}, - {0x03, 0xA7, "LM3S5749"}, - {0x03, 0x9A, "LM3S5752"}, - {0x03, 0x9C, "LM3S5762"}, - {0x04, 0x69, "LM3S5791"}, - {0x04, 0x0B, "LM3S5951"}, - {0x04, 0x4E, "LM3S5956"}, - {0x04, 0x68, "LM3S5B91"}, - {0x06, 0x2E, "LM3S5C31"}, - {0x06, 0x2C, "LM3S5C36"}, - {0x06, 0x5E, "LM3S5C51"}, - {0x06, 0x5B, "LM3S5C56"}, - {0x06, 0x5F, "LM3S5D51"}, - {0x06, 0x5C, "LM3S5D56"}, - {0x06, 0x87, "LM3S5D91"}, - {0x06, 0x2D, "LM3S5G31"}, - {0x06, 0x1F, "LM3S5G36"}, - {0x06, 0x5D, "LM3S5G51"}, - {0x06, 0x4F, "LM3S5G56"}, - {0x04, 0x09, "LM3S5K31"}, - {0x04, 0x4A, "LM3S5K36"}, - {0x04, 0x0A, "LM3S5P31"}, - {0x04, 0x48, "LM3S5P36"}, - {0x04, 0xB6, "LM3S5P3B"}, - {0x04, 0x0D, "LM3S5P51"}, - {0x04, 0x4C, "LM3S5P56"}, - {0x04, 0x07, "LM3S5R31"}, - {0x04, 0x4B, "LM3S5R36"}, - {0x04, 0x47, "LM3S5T36"}, - {0x06, 0x7F, "LM3S5U91"}, - {0x04, 0x46, "LM3S5Y36"}, - {0x00, 0x2A, "LM3S600"}, - {0x00, 0x21, "LM3S601"}, - {0x00, 0x2B, "LM3S608"}, - {0x00, 0x22, "LM3S610"}, - {0x01, 0xA1, "LM3S6100"}, - {0x00, 0x23, "LM3S611"}, - {0x01, 0x74, "LM3S6110"}, - {0x00, 0x24, "LM3S612"}, - {0x00, 0x25, "LM3S613"}, - {0x00, 0x26, "LM3S615"}, - {0x00, 0x28, "LM3S617"}, - {0x00, 0x29, "LM3S618"}, - {0x00, 0x27, "LM3S628"}, - {0x01, 0xA5, "LM3S6420"}, - {0x01, 0x82, "LM3S6422"}, - {0x01, 0x75, "LM3S6432"}, - {0x01, 0x76, "LM3S6537"}, - {0x01, 0x71, "LM3S6610"}, - {0x01, 0xE7, "LM3S6611"}, - {0x01, 0xE6, "LM3S6618"}, - {0x01, 0x83, "LM3S6633"}, - {0x01, 0x8B, "LM3S6637"}, - {0x01, 0xA3, "LM3S6730"}, - {0x01, 0x77, "LM3S6753"}, - {0x01, 0xE9, "LM3S6911"}, - {0x01, 0xE8, "LM3S6918"}, - {0x01, 0x89, "LM3S6938"}, - {0x01, 0x72, "LM3S6950"}, - {0x01, 0x78, "LM3S6952"}, - {0x01, 0x73, "LM3S6965"}, - {0x06, 0xAA, "LM3S6C11"}, - {0x06, 0xAC, "LM3S6C65"}, - {0x06, 0x9F, "LM3S6G11"}, - {0x06, 0xAB, "LM3S6G65"}, - {0x00, 0x38, "LM3S800"}, - {0x00, 0x31, "LM3S801"}, - {0x00, 0x39, "LM3S808"}, - {0x00, 0x32, "LM3S811"}, - {0x00, 0x33, "LM3S812"}, - {0x00, 0x34, "LM3S815"}, - {0x00, 0x36, "LM3S817"}, - {0x00, 0x37, "LM3S818"}, - {0x00, 0x35, "LM3S828"}, - {0x01, 0x64, "LM3S8530"}, - {0x01, 0x8E, "LM3S8538"}, - {0x01, 0x61, "LM3S8630"}, - {0x01, 0x63, "LM3S8730"}, - {0x01, 0x8D, "LM3S8733"}, - {0x01, 0x86, "LM3S8738"}, - {0x01, 0x65, "LM3S8930"}, - {0x01, 0x8C, "LM3S8933"}, - {0x01, 0x88, "LM3S8938"}, - {0x01, 0xA6, "LM3S8962"}, - {0x01, 0x62, "LM3S8970"}, - {0x01, 0xD7, "LM3S8971"}, - {0x06, 0xAE, "LM3S8C62"}, - {0x06, 0xAD, "LM3S8G62"}, - {0x04, 0xCF, "LM3S9781"}, - {0x04, 0x67, "LM3S9790"}, - {0x04, 0x6B, "LM3S9792"}, - {0x04, 0x2D, "LM3S9971"}, - {0x04, 0x20, "LM3S9997"}, - {0x04, 0xD0, "LM3S9B81"}, - {0x04, 0x66, "LM3S9B90"}, - {0x04, 0x6A, "LM3S9B92"}, - {0x04, 0x6E, "LM3S9B95"}, - {0x04, 0x6F, "LM3S9B96"}, - {0x04, 0x1D, "LM3S9BN2"}, - {0x04, 0x1E, "LM3S9BN5"}, - {0x04, 0x1F, "LM3S9BN6"}, - {0x06, 0x70, "LM3S9C97"}, - {0x06, 0xA9, "LM3S9D81"}, - {0x06, 0x7E, "LM3S9D90"}, - {0x06, 0x92, "LM3S9D92"}, - {0x06, 0x9D, "LM3S9D96"}, - {0x06, 0x7B, "LM3S9DN5"}, - {0x06, 0x7C, "LM3S9DN6"}, - {0x06, 0x60, "LM3S9G97"}, - {0x06, 0x79, "LM3S9GN5"}, - {0x04, 0x1B, "LM3S9L71"}, - {0x04, 0x18, "LM3S9L97"}, - {0x06, 0xA8, "LM3S9U81"}, - {0x06, 0x7D, "LM3S9U90"}, - {0x06, 0x90, "LM3S9U92"}, - {0x06, 0x9B, "LM3S9U96"}, - {0x05, 0x01, "LM4F120B2QR/TM4C1233C3PM"}, - {0x05, 0x02, "LM4F120C4QR/TM4C1233D5PM"}, - {0x05, 0x03, "LM4F120E5QR/TM4C1233E6PM"}, - {0x05, 0x04, "LM4F120H5QR/TM4C1233H6PM"}, - {0x05, 0x08, "LM4F121B2QR/TM4C1232C3PM"}, - {0x05, 0x09, "LM4F121C4QR/TM4C1232D5PM"}, - {0x05, 0x0A, "LM4F121E5QR/TM4C1232E6PM"}, - {0x05, 0x0B, "LM4F121H5QR/TM4C1232H6PM"}, - {0x05, 0x10, "LM4F110E5QR/TM4C1231E6PM"}, - {0x05, 0x11, "LM4F110H5QR/TM4C1231H6PM"}, - {0x05, 0x18, "LM4F110B2QR/TM4C1231C3PM"}, - {0x05, 0x19, "LM4F110C4QR/TM4C1231D5PM"}, - {0x05, 0x20, "LM4F111E5QR/TM4C1230E6PM"}, - {0x05, 0x21, "LM4F111H5QR/TM4C1230H6PM"}, - {0x05, 0x22, "LM4F111B2QR/TM4C1230C3PM"}, - {0x05, 0x23, "LM4F111C4QR/TM4C1230D5PM"}, - {0x05, 0x30, "LM4F112E5QC/TM4C1231E6PZ"}, - {0x05, 0x31, "LM4F112H5QC/TM4C1231H6PZ"}, - {0x05, 0x35, "LM4F112H5QD/TM4C1231H6PGE"}, - {0x05, 0x36, "LM4F112C4QC/TM4C1231D5PZ"}, - {0x05, 0x40, "LM4F130E5QR/TM4C1237E6PM"}, - {0x05, 0x41, "LM4F130H5QR/TM4C1237H6PM"}, - {0x05, 0x48, "LM4F130C4QR/TM4C1237D5PM"}, - {0x05, 0x50, "LM4F131E5QR/TM4C1236E6PM"}, - {0x05, 0x51, "LM4F131H5QR/TM4C1236H6PM"}, - {0x05, 0x52, "LM4F131C4QR/TM4C1236D5PM"}, - {0x05, 0x60, "LM4F132E5QC/TM4C1237E6PZ"}, - {0x05, 0x61, "LM4F132H5QC/TM4C1237H6PZ"}, - {0x05, 0x65, "LM4F132H5QD/TM4C1237H6PGE"}, - {0x05, 0x66, "LM4F132C4QC/TM4C1237D5PZ"}, - {0x05, 0x70, "LM4F210E5QR/TM4C123BE6PM"}, - {0x05, 0x73, "LM4F210H5QR/TM4C123BH6PM"}, - {0x05, 0x80, "LM4F211E5QR/TM4C123AE6PM"}, - {0x05, 0x83, "LM4F211H5QR/TM4C123AH6PM"}, - {0x05, 0xA0, "LM4F230E5QR/TM4C123GE6PM"}, - {0x05, 0xA1, "LM4F230H5QR/TM4C123GH6PM"}, - {0x05, 0xB0, "LM4F231E5QR/TM4C123FE6PM"}, - {0x05, 0xB1, "LM4F231H5QR/TM4C123FH6PM"}, - {0x05, 0xC0, "LM4F232E5QC/TM4C123GE6PZ"}, - {0x05, 0xC1, "LM4F232H5QC/TM4C123GH6PZ"}, - {0x05, 0xC3, "LM4F212E5QC/TM4C123BE6PZ"}, - {0x05, 0xC4, "LM4F212H5QC/TM4C123BH6PZ"}, - {0x05, 0xC5, "LM4F232H5QD/TM4C123GH6PGE"}, - {0x05, 0xC6, "LM4F212H5QD/TM4C123BH6PGE"}, - {0x05, 0xD0, "LM4F122C4QC/TM4C1233D5PZ"}, - {0x05, 0xD1, "LM4F122E5QC/TM4C1233E6PZ"}, - {0x05, 0xD2, "LM4F122H5QC/TM4C1233H6PZ"}, - {0x05, 0xD6, "LM4F122H5QD/TM4C1233H6PGE"}, - {0x05, 0xE1, "LM4FSXLH5BB"}, - {0x05, 0xE3, "LM4F232H5BB/TM4C123GH6ZRB"}, - {0x05, 0xE4, "LM4FS99H5BB"}, - {0x05, 0xE5, "LM4FS1AH5BB"}, - {0x05, 0xE9, "LM4F212H5BB/TM4C123BH6ZRB"}, - {0x05, 0xEA, "LM4FS1GH5BB"}, - {0x05, 0xF0, "TM4C123GH6ZXR"}, - {0x0A, 0x19, "TM4C1290NCPDT"}, - {0x0A, 0x1B, "TM4C1290NCZAD"}, - {0x0A, 0x1C, "TM4C1292NCPDT"}, - {0x0A, 0x1E, "TM4C1292NCZAD"}, - {0x0A, 0x1F, "TM4C1294NCPDT"}, - {0x0A, 0x21, "TM4C1294NCZAD"}, - {0x0A, 0x22, "TM4C1297NCZAD"}, - {0x0A, 0x23, "TM4C1299NCZAD"}, - {0x0A, 0x24, "TM4C129CNCPDT"}, - {0x0A, 0x26, "TM4C129CNCZAD"}, - {0x0A, 0x27, "TM4C129DNCPDT"}, - {0x0A, 0x29, "TM4C129DNCZAD"}, - {0x0A, 0x2D, "TM4C129ENCPDT"}, - {0x0A, 0x2F, "TM4C129ENCZAD"}, - {0x0A, 0x30, "TM4C129LNCZAD"}, - {0x0A, 0x32, "TM4C129XNCZAD"}, - {0x0A, 0x34, "TM4C1294KCPDT"}, - {0x0A, 0x35, "TM4C129EKCPDT"}, - {0x0A, 0x36, "TM4C1299KCZAD"}, - {0x0A, 0x37, "TM4C129XKCZAD"}, - {0xFF, 0x00, "Unknown Part"} -}; - -static const char * const StellarisClassname[] = { - "Sandstorm", - "Fury", - "Unknown", - "DustDevil", - "Tempest", - "Blizzard/TM4C123x", - "Firestorm", - "", - "", - "", - "Snowflake", -}; - -/*************************************************************************** -* openocd command interface * -***************************************************************************/ - -/* flash_bank stellaris 0 0 - */ -FLASH_BANK_COMMAND_HANDLER(stellaris_flash_bank_command) -{ - struct stellaris_flash_bank *stellaris_info; - - if (CMD_ARGC < 6) - return ERROR_COMMAND_SYNTAX_ERROR; - - stellaris_info = calloc(sizeof(struct stellaris_flash_bank), 1); - bank->base = 0x0; - bank->driver_priv = stellaris_info; - - stellaris_info->target_name = "Unknown target"; - - /* part wasn't probed for info yet */ - stellaris_info->did1 = 0; - - /* TODO Specify the main crystal speed in kHz using an optional - * argument; ditto, the speed of an external oscillator used - * instead of a crystal. Avoid programming flash using IOSC. - */ - return ERROR_OK; -} - -static int get_stellaris_info(struct flash_bank *bank, char *buf, int buf_size) -{ - int printed; - struct stellaris_flash_bank *stellaris_info = bank->driver_priv; - - if (stellaris_info->did1 == 0) - return ERROR_FLASH_BANK_NOT_PROBED; - - /* Read main and master clock freqency register */ - stellaris_read_clock_info(bank); - - printed = snprintf(buf, - buf_size, - "\nTI/LMI Stellaris information: Chip is " - "class %i (%s) %s rev %c%i\n", - stellaris_info->target_class, - StellarisClassname[stellaris_info->target_class], - stellaris_info->target_name, - (int)('A' + ((stellaris_info->did0 >> 8) & 0xFF)), - (int)((stellaris_info->did0) & 0xFF)); - buf += printed; - buf_size -= printed; - - printed = snprintf(buf, - buf_size, - "did1: 0x%8.8" PRIx32 ", arch: 0x%4.4" PRIx32 - ", eproc: %s, ramsize: %" PRIu32 "k, flashsize: %" PRIu32 "k\n", - stellaris_info->did1, - stellaris_info->did1, - "ARMv7M", - stellaris_info->sramsiz, - (uint32_t)(stellaris_info->num_pages * stellaris_info->pagesize / 1024)); - buf += printed; - buf_size -= printed; - - snprintf(buf, - buf_size, - "master clock: %ikHz%s, " - "rcc is 0x%" PRIx32 ", rcc2 is 0x%" PRIx32 ", " - "pagesize: %" PRIu32 ", pages: %" PRIu32, - (int)(stellaris_info->mck_freq / 1000), - stellaris_info->mck_desc, - stellaris_info->rcc, - stellaris_info->rcc2, - stellaris_info->pagesize, - stellaris_info->num_pages); - - return ERROR_OK; -} - -/*************************************************************************** -* chip identification and status * -***************************************************************************/ - -/* Set the flash timimg register to match current clocking */ -static void stellaris_set_flash_timing(struct flash_bank *bank) -{ - struct stellaris_flash_bank *stellaris_info = bank->driver_priv; - struct target *target = bank->target; - uint32_t usecrl = (stellaris_info->mck_freq/1000000ul-1); - - /* only valid for Sandstorm and Fury class devices */ - if (stellaris_info->target_class > 1) - return; - - LOG_DEBUG("usecrl = %i", (int)(usecrl)); - target_write_u32(target, SCB_BASE | USECRL, usecrl); -} - -static const unsigned rcc_xtal[32] = { - [0x00] = 1000000, /* no pll */ - [0x01] = 1843200, /* no pll */ - [0x02] = 2000000, /* no pll */ - [0x03] = 2457600, /* no pll */ - - [0x04] = 3579545, - [0x05] = 3686400, - [0x06] = 4000000, /* usb */ - [0x07] = 4096000, - - [0x08] = 4915200, - [0x09] = 5000000, /* usb */ - [0x0a] = 5120000, - [0x0b] = 6000000, /* (reset) usb */ - - [0x0c] = 6144000, - [0x0d] = 7372800, - [0x0e] = 8000000, /* usb */ - [0x0f] = 8192000, - - /* parts before DustDevil use just 4 bits for xtal spec */ - - [0x10] = 10000000, /* usb */ - [0x11] = 12000000, /* usb */ - [0x12] = 12288000, - [0x13] = 13560000, - - [0x14] = 14318180, - [0x15] = 16000000, /* usb */ - [0x16] = 16384000, -}; - -/** Read clock configuration and set stellaris_info->usec_clocks. */ -static void stellaris_read_clock_info(struct flash_bank *bank) -{ - struct stellaris_flash_bank *stellaris_info = bank->driver_priv; - struct target *target = bank->target; - uint32_t rcc, rcc2, pllcfg, sysdiv, usesysdiv, bypass, oscsrc; - unsigned xtal; - unsigned long mainfreq; - - target_read_u32(target, SCB_BASE | RCC, &rcc); - LOG_DEBUG("Stellaris RCC %" PRIx32 "", rcc); - - target_read_u32(target, SCB_BASE | RCC2, &rcc2); - LOG_DEBUG("Stellaris RCC2 %" PRIx32 "", rcc); - - target_read_u32(target, SCB_BASE | PLLCFG, &pllcfg); - LOG_DEBUG("Stellaris PLLCFG %" PRIx32 "", pllcfg); - - stellaris_info->rcc = rcc; - stellaris_info->rcc2 = rcc2; - - sysdiv = (rcc >> 23) & 0xF; - usesysdiv = (rcc >> 22) & 0x1; - bypass = (rcc >> 11) & 0x1; - oscsrc = (rcc >> 4) & 0x3; - xtal = (rcc >> 6) & stellaris_info->xtal_mask; - - /* NOTE: post-Sandstorm parts have RCC2 which may override - * parts of RCC ... with more sysdiv options, option for - * 32768 Hz mainfreq, PLL controls. On Sandstorm it reads - * as zero, so the "use RCC2" flag is always clear. - */ - if (rcc2 & (1 << 31)) { - sysdiv = (rcc2 >> 23) & 0x3F; - bypass = (rcc2 >> 11) & 0x1; - oscsrc = (rcc2 >> 4) & 0x7; - - /* FIXME Tempest parts have an additional lsb for - * fractional sysdiv (200 MHz / 2.5 == 80 MHz) - */ - } - - stellaris_info->mck_desc = ""; - - switch (oscsrc) { - case 0: /* MOSC */ - mainfreq = rcc_xtal[xtal]; - break; - case 1: /* IOSC */ - mainfreq = stellaris_info->iosc_freq; - stellaris_info->mck_desc = stellaris_info->iosc_desc; - break; - case 2: /* IOSC/4 */ - mainfreq = stellaris_info->iosc_freq / 4; - stellaris_info->mck_desc = stellaris_info->iosc_desc; - break; - case 3: /* lowspeed */ - /* Sandstorm doesn't have this 30K +/- 30% osc */ - mainfreq = 30000; - stellaris_info->mck_desc = " (±30%)"; - break; - case 8: /* hibernation osc */ - /* not all parts support hibernation */ - mainfreq = 32768; - break; - - default: /* NOTREACHED */ - mainfreq = 0; - break; - } - - /* PLL is used if it's not bypassed; its output is 200 MHz - * even when it runs at 400 MHz (adds divide-by-two stage). - */ - if (!bypass) - mainfreq = 200000000; - - if (usesysdiv) - stellaris_info->mck_freq = mainfreq/(1 + sysdiv); - else - stellaris_info->mck_freq = mainfreq; -} - -/* Read device id register, main clock frequency register and fill in driver info structure */ -static int stellaris_read_part_info(struct flash_bank *bank) -{ - struct stellaris_flash_bank *stellaris_info = bank->driver_priv; - struct target *target = bank->target; - uint32_t did0, did1, ver, fam; - int i; - - /* Read and parse chip identification register */ - target_read_u32(target, SCB_BASE | DID0, &did0); - target_read_u32(target, SCB_BASE | DID1, &did1); - target_read_u32(target, SCB_BASE | DC0, &stellaris_info->dc0); - target_read_u32(target, SCB_BASE | DC1, &stellaris_info->dc1); - LOG_DEBUG("did0 0x%" PRIx32 ", did1 0x%" PRIx32 ", dc0 0x%" PRIx32 ", dc1 0x%" PRIx32 "", - did0, did1, stellaris_info->dc0, stellaris_info->dc1); - - ver = DID0_VER(did0); - if ((ver != 0) && (ver != 1)) { - LOG_WARNING("Unknown did0 version, cannot identify target"); - return ERROR_FLASH_OPERATION_FAILED; - } - - if (did1 == 0) { - LOG_WARNING("Cannot identify target as a Stellaris"); - return ERROR_FLASH_OPERATION_FAILED; - } - - ver = did1 >> 28; - fam = (did1 >> 24) & 0xF; - if (((ver != 0) && (ver != 1)) || (fam != 0)) { - LOG_WARNING("Unknown did1 version/family."); - return ERROR_FLASH_OPERATION_FAILED; - } - - /* For Sandstorm, Fury, DustDevil: current data sheets say IOSC - * is 12 MHz, but some older parts have 15 MHz. A few data sheets - * even give _both_ numbers! We'll use current numbers; IOSC is - * always approximate. - * - * For Tempest: IOSC is calibrated, 16 MHz - * For Blizzard: IOSC is calibrated, 16 MHz - * For Firestorm: IOSC is calibrated, 16 MHz - */ - stellaris_info->iosc_freq = 12000000; - stellaris_info->iosc_desc = " (±30%)"; - stellaris_info->xtal_mask = 0x0f; - - /* get device class */ - if (DID0_VER(did0) > 0) { - stellaris_info->target_class = (did0 >> 16) & 0xFF; - } else { - /* Sandstorm class */ - stellaris_info->target_class = 0; - } - - switch (stellaris_info->target_class) { - case 0: /* Sandstorm */ - /* - * Current (2009-August) parts seem to be rev C2 and use 12 MHz. - * Parts before rev C0 used 15 MHz; some C0 parts use 15 MHz - * (LM3S618), but some other C0 parts are 12 MHz (LM3S811). - */ - if (((did0 >> 8) & 0xff) < 2) { - stellaris_info->iosc_freq = 15000000; - stellaris_info->iosc_desc = " (±50%)"; - } - break; - - case 1: /* Fury */ - break; - - case 4: /* Tempest */ - case 5: /* Blizzard */ - case 6: /* Firestorm */ - case 0xa: /* Snowflake */ - stellaris_info->iosc_freq = 16000000; /* +/- 1% */ - stellaris_info->iosc_desc = " (±1%)"; - /* FALL THROUGH */ - - case 3: /* DustDevil */ - stellaris_info->xtal_mask = 0x1f; - break; - - default: - LOG_WARNING("Unknown did0 class"); - } - - for (i = 0; StellarisParts[i].partno; i++) { - if ((StellarisParts[i].partno == ((did1 >> 16) & 0xFF)) && - (StellarisParts[i].class == stellaris_info->target_class)) - break; - } - - stellaris_info->target_name = StellarisParts[i].partname; - - stellaris_info->did0 = did0; - stellaris_info->did1 = did1; - - if (stellaris_info->target_class == 5) { /* Blizzard */ - target_read_u32(target, FLASH_FSIZE, &stellaris_info->fsize); - target_read_u32(target, FLASH_SSIZE, &stellaris_info->ssize); - - stellaris_info->num_pages = 2 * (1 + (stellaris_info->fsize & 0xFFFF)); - stellaris_info->sramsiz = (1 + (stellaris_info->ssize & 0xFFFF)) / 4; - stellaris_info->pagesize = 1024; - } else if (stellaris_info->target_class == 0xa) { /* Snowflake */ - target_read_u32(target, FLASH_FSIZE, &stellaris_info->fsize); - target_read_u32(target, FLASH_SSIZE, &stellaris_info->ssize); - - stellaris_info->pagesize = (1 << ((stellaris_info->fsize >> 16) & 7)) * 1024; - stellaris_info->num_pages = 2048 * (1 + (stellaris_info->fsize & 0xFFFF)) / - stellaris_info->pagesize; - stellaris_info->sramsiz = (1 + (stellaris_info->ssize & 0xFFFF)) / 4; - } else { - stellaris_info->num_pages = 2 * (1 + (stellaris_info->dc0 & 0xFFFF)); - stellaris_info->sramsiz = (1 + ((stellaris_info->dc0 >> 16) & 0xFFFF)) / 4; - stellaris_info->pagesize = 1024; - } - - /* REVISIT for at least Tempest parts, read NVMSTAT.FWB too. - * That exposes a 32-word Flash Write Buffer ... enabling - * writes of more than one word at a time. - */ - - return ERROR_OK; -} - -/*************************************************************************** -* flash operations * -***************************************************************************/ - -static int stellaris_protect_check(struct flash_bank *bank) -{ - struct stellaris_flash_bank *stellaris = bank->driver_priv; - struct target *target = bank->target; - uint32_t flash_sizek = stellaris->pagesize / 1024 * - stellaris->num_pages; - uint32_t fmppe_addr; - int status = ERROR_OK; - unsigned i; - - if (stellaris->did1 == 0) - return ERROR_FLASH_BANK_NOT_PROBED; - - for (i = 0; i < (unsigned) bank->num_sectors; i++) - bank->sectors[i].is_protected = -1; - - /* Read each Flash Memory Protection Program Enable (FMPPE) register - * to report any pages that we can't write. Ignore the Read Enable - * register (FMPRE). - */ - - if (stellaris->target_class >= 0x0a || flash_sizek > 64) - fmppe_addr = SCB_BASE | FMPPE0; - else - fmppe_addr = SCB_BASE | FMPPE; - - unsigned int page = 0, lockbitnum, lockbitcnt = flash_sizek / 2; - unsigned int bits_per_page = stellaris->pagesize / 2048; - /* Every lock bit always corresponds to a 2k region */ - for (lockbitnum = 0; lockbitnum < lockbitcnt; lockbitnum += 32) { - uint32_t fmppe; - - target_read_u32(target, fmppe_addr, &fmppe); - for (i = 0; i < 32 && lockbitnum + i < lockbitcnt; i++) { - bool protect = !(fmppe & (1 << i)); - if (bits_per_page) { - bank->sectors[page++].is_protected = protect; - i += bits_per_page - 1; - } else { /* 1024k pages, every lockbit covers 2 pages */ - bank->sectors[page++].is_protected = protect; - bank->sectors[page++].is_protected = protect; - } - } - fmppe_addr += 4; - } - - return status; -} - -static int stellaris_erase(struct flash_bank *bank, int first, int last) -{ - int banknr; - uint32_t flash_fmc, flash_cris; - struct stellaris_flash_bank *stellaris_info = bank->driver_priv; - struct target *target = bank->target; - - if (bank->target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - if (stellaris_info->did1 == 0) - return ERROR_FLASH_BANK_NOT_PROBED; - - if ((first < 0) || (last < first) || (last >= (int)stellaris_info->num_pages)) - return ERROR_FLASH_SECTOR_INVALID; - - if ((first == 0) && (last == ((int)stellaris_info->num_pages-1))) - return stellaris_mass_erase(bank); - - /* Refresh flash controller timing */ - stellaris_read_clock_info(bank); - stellaris_set_flash_timing(bank); - - /* Clear and disable flash programming interrupts */ - target_write_u32(target, FLASH_CIM, 0); - target_write_u32(target, FLASH_MISC, PMISC | AMISC); - - /* REVISIT this clobbers state set by any halted firmware ... - * it might want to process those IRQs. - */ - - for (banknr = first; banknr <= last; banknr++) { - /* Address is first word in page */ - target_write_u32(target, FLASH_FMA, banknr * stellaris_info->pagesize); - /* Write erase command */ - target_write_u32(target, FLASH_FMC, FMC_WRKEY | FMC_ERASE); - /* Wait until erase complete */ - do { - target_read_u32(target, FLASH_FMC, &flash_fmc); - } while (flash_fmc & FMC_ERASE); - - /* Check acess violations */ - target_read_u32(target, FLASH_CRIS, &flash_cris); - if (flash_cris & (AMASK)) { - LOG_WARNING("Error erasing flash page %i, flash_cris 0x%" PRIx32 "", - banknr, flash_cris); - target_write_u32(target, FLASH_CRIS, 0); - return ERROR_FLASH_OPERATION_FAILED; - } - - bank->sectors[banknr].is_erased = 1; - } - - return ERROR_OK; -} - -static int stellaris_protect(struct flash_bank *bank, int set, int first, int last) -{ - struct stellaris_flash_bank *stellaris = bank->driver_priv; - struct target *target = bank->target; - uint32_t flash_fmc, flash_cris; - unsigned int bits_per_page = stellaris->pagesize / 2048; - - if (target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - if (!set) { - LOG_ERROR("Hardware doesn't support page-level unprotect. " - "Try the 'recover' command."); - return ERROR_COMMAND_SYNTAX_ERROR; - } - - if (stellaris->did1 == 0) - return ERROR_FLASH_BANK_NOT_PROBED; - - if (stellaris->target_class == 0x03 && - !((stellaris->did0 >> 8) & 0xFF) && - !((stellaris->did0) & 0xFF)) { - LOG_ERROR("DustDevil A0 parts can't be unprotected, see errata; refusing to proceed"); - return ERROR_FLASH_OPERATION_FAILED; - } - - if (!bits_per_page && (first % 2 || !(last % 2))) { - LOG_ERROR("Can't protect unaligned pages"); - return ERROR_FLASH_SECTOR_INVALID; - } - - /* Refresh flash controller timing */ - stellaris_read_clock_info(bank); - stellaris_set_flash_timing(bank); - - /* Clear and disable flash programming interrupts */ - target_write_u32(target, FLASH_CIM, 0); - target_write_u32(target, FLASH_MISC, PMISC | AMISC); - - uint32_t flash_sizek = stellaris->pagesize / 1024 * - stellaris->num_pages; - uint32_t fmppe_addr; - - if (stellaris->target_class >= 0x0a || flash_sizek > 64) - fmppe_addr = SCB_BASE | FMPPE0; - else - fmppe_addr = SCB_BASE | FMPPE; - - int page = 0; - unsigned int lockbitnum, lockbitcnt = flash_sizek / 2; - /* Every lock bit always corresponds to a 2k region */ - for (lockbitnum = 0; lockbitnum < lockbitcnt; lockbitnum += 32) { - uint32_t fmppe; - - target_read_u32(target, fmppe_addr, &fmppe); - for (unsigned int i = 0; - i < 32 && lockbitnum + i < lockbitcnt; - i++) { - if (page >= first && page <= last) - fmppe &= ~(1 << i); - - if (bits_per_page) { - if (!((i + 1) % bits_per_page)) - page++; - } else { /* 1024k pages, every lockbit covers 2 pages */ - page += 2; - } - } - target_write_u32(target, fmppe_addr, fmppe); - - /* Commit FMPPE* */ - target_write_u32(target, FLASH_FMA, 1 + lockbitnum / 16); - /* Write commit command */ - target_write_u32(target, FLASH_FMC, FMC_WRKEY | FMC_COMT); - - /* Wait until commit complete */ - do { - target_read_u32(target, FLASH_FMC, &flash_fmc); - } while (flash_fmc & FMC_COMT); - - /* Check access violations */ - target_read_u32(target, FLASH_CRIS, &flash_cris); - if (flash_cris & (AMASK)) { - LOG_WARNING("Error setting flash page protection, flash_cris 0x%" PRIx32 "", flash_cris); - target_write_u32(target, FLASH_CRIS, 0); - return ERROR_FLASH_OPERATION_FAILED; - } - - fmppe_addr += 4; - } - - return ERROR_OK; -} - -/* see contib/loaders/flash/stellaris.s for src */ - -static const uint8_t stellaris_write_code[] = { - /* write: */ - 0xDF, 0xF8, 0x40, 0x40, /* ldr r4, pFLASH_CTRL_BASE */ - 0xDF, 0xF8, 0x40, 0x50, /* ldr r5, FLASHWRITECMD */ - /* wait_fifo: */ - 0xD0, 0xF8, 0x00, 0x80, /* ldr r8, [r0, #0] */ - 0xB8, 0xF1, 0x00, 0x0F, /* cmp r8, #0 */ - 0x17, 0xD0, /* beq exit */ - 0x47, 0x68, /* ldr r7, [r0, #4] */ - 0x47, 0x45, /* cmp r7, r8 */ - 0xF7, 0xD0, /* beq wait_fifo */ - /* mainloop: */ - 0x22, 0x60, /* str r2, [r4, #0] */ - 0x02, 0xF1, 0x04, 0x02, /* add r2, r2, #4 */ - 0x57, 0xF8, 0x04, 0x8B, /* ldr r8, [r7], #4 */ - 0xC4, 0xF8, 0x04, 0x80, /* str r8, [r4, #4] */ - 0xA5, 0x60, /* str r5, [r4, #8] */ - /* busy: */ - 0xD4, 0xF8, 0x08, 0x80, /* ldr r8, [r4, #8] */ - 0x18, 0xF0, 0x01, 0x0F, /* tst r8, #1 */ - 0xFA, 0xD1, /* bne busy */ - 0x8F, 0x42, /* cmp r7, r1 */ - 0x28, 0xBF, /* it cs */ - 0x00, 0xF1, 0x08, 0x07, /* addcs r7, r0, #8 */ - 0x47, 0x60, /* str r7, [r0, #4] */ - 0x01, 0x3B, /* subs r3, r3, #1 */ - 0x03, 0xB1, /* cbz r3, exit */ - 0xE2, 0xE7, /* b wait_fifo */ - /* exit: */ - 0x00, 0xBE, /* bkpt #0 */ - - /* pFLASH_CTRL_BASE: */ - 0x00, 0xD0, 0x0F, 0x40, /* .word 0x400FD000 */ - /* FLASHWRITECMD: */ - 0x01, 0x00, 0x42, 0xA4 /* .word 0xA4420001 */ -}; -static int stellaris_write_block(struct flash_bank *bank, - const uint8_t *buffer, uint32_t offset, uint32_t wcount) -{ - struct target *target = bank->target; - uint32_t buffer_size = 16384; - struct working_area *source; - struct working_area *write_algorithm; - uint32_t address = bank->base + offset; - struct reg_param reg_params[4]; - struct armv7m_algorithm armv7m_info; - int retval = ERROR_OK; - - /* power of two, and multiple of word size */ - static const unsigned buf_min = 128; - - /* for small buffers it's faster not to download an algorithm */ - if (wcount * 4 < buf_min) - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - - LOG_DEBUG("(bank=%p buffer=%p offset=%08" PRIx32 " wcount=%08" PRIx32 "", - bank, buffer, offset, wcount); - - /* flash write code */ - if (target_alloc_working_area(target, sizeof(stellaris_write_code), - &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) - buffer_size = wcount * 4; - - /* memory buffer */ - while (target_alloc_working_area_try(target, buffer_size, &source) != ERROR_OK) { - buffer_size /= 2; - if (buffer_size <= buf_min) { - target_free_working_area(target, write_algorithm); - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - } - 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), - stellaris_write_code); - - armv7m_info.common_magic = ARMV7M_COMMON_MAGIC; - armv7m_info.core_mode = ARM_MODE_THREAD; - - init_reg_param(®_params[0], "r0", 32, PARAM_OUT); - init_reg_param(®_params[1], "r1", 32, PARAM_OUT); - init_reg_param(®_params[2], "r2", 32, PARAM_OUT); - init_reg_param(®_params[3], "r3", 32, PARAM_OUT); - - buf_set_u32(reg_params[0].value, 0, 32, source->address); - buf_set_u32(reg_params[1].value, 0, 32, source->address + source->size); - buf_set_u32(reg_params[2].value, 0, 32, address); - buf_set_u32(reg_params[3].value, 0, 32, wcount); - - retval = target_run_flash_async_algorithm(target, buffer, wcount, 4, - 0, NULL, - 4, reg_params, - source->address, source->size, - write_algorithm->address, 0, - &armv7m_info); - - if (retval == ERROR_FLASH_OPERATION_FAILED) - LOG_ERROR("error %d executing stellaris flash write algorithm", retval); - - target_free_working_area(target, write_algorithm); - target_free_working_area(target, source); - - destroy_reg_param(®_params[0]); - destroy_reg_param(®_params[1]); - destroy_reg_param(®_params[2]); - destroy_reg_param(®_params[3]); - - return retval; -} - -static int stellaris_write(struct flash_bank *bank, const uint8_t *buffer, - uint32_t offset, uint32_t count) -{ - struct stellaris_flash_bank *stellaris_info = bank->driver_priv; - struct target *target = bank->target; - uint32_t address = offset; - uint32_t flash_cris, flash_fmc; - uint32_t words_remaining = (count / 4); - uint32_t bytes_remaining = (count & 0x00000003); - uint32_t bytes_written = 0; - int retval; - - if (bank->target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - LOG_DEBUG("(bank=%p buffer=%p offset=%08" PRIx32 " count=%08" PRIx32 "", - bank, buffer, offset, count); - - if (stellaris_info->did1 == 0) - return ERROR_FLASH_BANK_NOT_PROBED; - - if (offset & 0x3) { - LOG_WARNING("offset size must be word aligned"); - return ERROR_FLASH_DST_BREAKS_ALIGNMENT; - } - - if (offset + count > bank->size) - return ERROR_FLASH_DST_OUT_OF_BANK; - - /* Refresh flash controller timing */ - stellaris_read_clock_info(bank); - stellaris_set_flash_timing(bank); - - /* Clear and disable flash programming interrupts */ - target_write_u32(target, FLASH_CIM, 0); - target_write_u32(target, FLASH_MISC, PMISC | AMISC); - - /* REVISIT this clobbers state set by any halted firmware ... - * it might want to process those IRQs. - */ - - /* multiple words to be programmed? */ - if (words_remaining > 0) { - /* try using a block write */ - retval = stellaris_write_block(bank, buffer, offset, - words_remaining); - if (retval != ERROR_OK) { - if (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE) { - LOG_DEBUG("writing flash word-at-a-time"); - } else if (retval == ERROR_FLASH_OPERATION_FAILED) { - /* if an error occured, we examine the reason, and quit */ - target_read_u32(target, FLASH_CRIS, &flash_cris); - - LOG_ERROR("flash writing failed with CRIS: 0x%" PRIx32 "", flash_cris); - return ERROR_FLASH_OPERATION_FAILED; - } - } else { - buffer += words_remaining * 4; - address += words_remaining * 4; - words_remaining = 0; - } - } - - while (words_remaining > 0) { - if (!(address & 0xff)) - LOG_DEBUG("0x%" PRIx32 "", address); - - /* Program one word */ - target_write_u32(target, FLASH_FMA, address); - target_write_buffer(target, FLASH_FMD, 4, buffer); - target_write_u32(target, FLASH_FMC, FMC_WRKEY | FMC_WRITE); - /* LOG_DEBUG("0x%x 0x%x 0x%x",address,buf_get_u32(buffer, 0, 32),FMC_WRKEY | FMC_WRITE); */ - /* Wait until write complete */ - do { - target_read_u32(target, FLASH_FMC, &flash_fmc); - } while (flash_fmc & FMC_WRITE); - - buffer += 4; - address += 4; - words_remaining--; - } - - if (bytes_remaining) { - uint8_t last_word[4] = {0xff, 0xff, 0xff, 0xff}; - - /* copy the last remaining bytes into the write buffer */ - memcpy(last_word, buffer+bytes_written, bytes_remaining); - - if (!(address & 0xff)) - LOG_DEBUG("0x%" PRIx32 "", address); - - /* Program one word */ - target_write_u32(target, FLASH_FMA, address); - target_write_buffer(target, FLASH_FMD, 4, last_word); - target_write_u32(target, FLASH_FMC, FMC_WRKEY | FMC_WRITE); - /* LOG_DEBUG("0x%x 0x%x 0x%x",address,buf_get_u32(buffer, 0, 32),FMC_WRKEY | FMC_WRITE); */ - /* Wait until write complete */ - do { - target_read_u32(target, FLASH_FMC, &flash_fmc); - } while (flash_fmc & FMC_WRITE); - } - - /* Check access violations */ - target_read_u32(target, FLASH_CRIS, &flash_cris); - if (flash_cris & (AMASK)) { - LOG_DEBUG("flash_cris 0x%" PRIx32 "", flash_cris); - return ERROR_FLASH_OPERATION_FAILED; - } - return ERROR_OK; -} - -static int stellaris_probe(struct flash_bank *bank) -{ - struct stellaris_flash_bank *stellaris_info = bank->driver_priv; - int retval; - - /* If this is a stellaris chip, it has flash; probe() is just - * to figure out how much is present. Only do it once. - */ - if (stellaris_info->did1 != 0) - return ERROR_OK; - - /* stellaris_read_part_info() already handled error checking and - * reporting. Note that it doesn't write, so we don't care about - * whether the target is halted or not. - */ - retval = stellaris_read_part_info(bank); - if (retval != ERROR_OK) - return retval; - - if (bank->sectors) { - free(bank->sectors); - bank->sectors = NULL; - } - - /* provide this for the benefit of the NOR flash framework */ - bank->size = stellaris_info->num_pages * stellaris_info->pagesize; - bank->num_sectors = stellaris_info->num_pages; - bank->sectors = calloc(bank->num_sectors, sizeof(struct flash_sector)); - for (int i = 0; i < bank->num_sectors; i++) { - bank->sectors[i].offset = i * stellaris_info->pagesize; - bank->sectors[i].size = stellaris_info->pagesize; - bank->sectors[i].is_erased = -1; - bank->sectors[i].is_protected = -1; - } - - return retval; -} - -static int stellaris_mass_erase(struct flash_bank *bank) -{ - struct target *target = NULL; - struct stellaris_flash_bank *stellaris_info = NULL; - uint32_t flash_fmc; - - stellaris_info = bank->driver_priv; - target = bank->target; - - if (target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - if (stellaris_info->did1 == 0) - return ERROR_FLASH_BANK_NOT_PROBED; - - /* Refresh flash controller timing */ - stellaris_read_clock_info(bank); - stellaris_set_flash_timing(bank); - - /* Clear and disable flash programming interrupts */ - target_write_u32(target, FLASH_CIM, 0); - target_write_u32(target, FLASH_MISC, PMISC | AMISC); - - /* REVISIT this clobbers state set by any halted firmware ... - * it might want to process those IRQs. - */ - - target_write_u32(target, FLASH_FMA, 0); - target_write_u32(target, FLASH_FMC, FMC_WRKEY | FMC_MERASE); - /* Wait until erase complete */ - do { - target_read_u32(target, FLASH_FMC, &flash_fmc); - } while (flash_fmc & FMC_MERASE); - - /* if device has > 128k, then second erase cycle is needed - * this is only valid for older devices, but will not hurt */ - if (stellaris_info->num_pages * stellaris_info->pagesize > 0x20000) { - target_write_u32(target, FLASH_FMA, 0x20000); - target_write_u32(target, FLASH_FMC, FMC_WRKEY | FMC_MERASE); - /* Wait until erase complete */ - do { - target_read_u32(target, FLASH_FMC, &flash_fmc); - } while (flash_fmc & FMC_MERASE); - } - - return ERROR_OK; -} - -COMMAND_HANDLER(stellaris_handle_mass_erase_command) -{ - int i; - - 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; - - if (stellaris_mass_erase(bank) == ERROR_OK) { - /* set all sectors as erased */ - for (i = 0; i < bank->num_sectors; i++) - bank->sectors[i].is_erased = 1; - - command_print(CMD_CTX, "stellaris mass erase complete"); - } else - command_print(CMD_CTX, "stellaris mass erase failed"); - - return ERROR_OK; -} - -/** - * Perform the Stellaris "Recovering a 'Locked' Device procedure. - * This performs a mass erase and then restores all nonvolatile registers - * (including USER_* registers and flash lock bits) to their defaults. - * Accordingly, flash can be reprogrammed, and JTAG can be used. - * - * NOTE that DustDevil parts (at least rev A0 silicon) have errata which - * can affect this operation if flash protection has been enabled. - */ -COMMAND_HANDLER(stellaris_handle_recover_command) -{ - struct flash_bank *bank; - int retval; - - if (CMD_ARGC != 0) - return ERROR_COMMAND_SYNTAX_ERROR; - - bank = get_flash_bank_by_num_noprobe(0); - if (!bank) - return ERROR_FAIL; - - /* REVISIT ... it may be worth sanity checking that the AP is - * inactive before we start. ARM documents that switching a DP's - * mode while it's active can cause fault modes that need a power - * cycle to recover. - */ - - Jim_Eval_Named(CMD_CTX->interp, "catch { hla_command \"debug unlock\" }", 0, 0); - if (!strcmp(Jim_GetString(Jim_GetResult(CMD_CTX->interp), NULL), "0")) { - retval = ERROR_OK; - goto user_action; - } - - /* assert SRST */ - if (!(jtag_get_reset_config() & RESET_HAS_SRST)) { - LOG_ERROR("Can't recover Stellaris flash without SRST"); - return ERROR_FAIL; - } - adapter_assert_reset(); - - for (int i = 0; i < 5; i++) { - retval = dap_to_swd(bank->target); - if (retval != ERROR_OK) - goto done; - - retval = dap_to_jtag(bank->target); - if (retval != ERROR_OK) - goto done; - } - - /* de-assert SRST */ - adapter_deassert_reset(); - retval = jtag_execute_queue(); - - /* wait 400+ msec ... OK, "1+ second" is simpler */ - usleep(1000); - -user_action: - /* USER INTERVENTION required for the power cycle - * Restarting OpenOCD is likely needed because of mode switching. - */ - LOG_INFO("USER ACTION: " - "power cycle Stellaris chip, then restart OpenOCD."); - -done: - return retval; -} - -static const struct command_registration stellaris_exec_command_handlers[] = { - { - .name = "mass_erase", - .usage = "", - .handler = stellaris_handle_mass_erase_command, - .mode = COMMAND_EXEC, - .help = "erase entire device", - }, - { - .name = "recover", - .handler = stellaris_handle_recover_command, - .mode = COMMAND_EXEC, - .usage = "", - .help = "recover (and erase) locked device", - }, - COMMAND_REGISTRATION_DONE -}; -static const struct command_registration stellaris_command_handlers[] = { - { - .name = "stellaris", - .mode = COMMAND_EXEC, - .help = "Stellaris flash command group", - .usage = "", - .chain = stellaris_exec_command_handlers, - }, - COMMAND_REGISTRATION_DONE -}; - -struct flash_driver stellaris_flash = { - .name = "stellaris", - .commands = stellaris_command_handlers, - .flash_bank_command = stellaris_flash_bank_command, - .erase = stellaris_erase, - .protect = stellaris_protect, - .write = stellaris_write, - .read = default_flash_read, - .probe = stellaris_probe, - .auto_probe = stellaris_probe, - .erase_check = default_flash_blank_check, - .protect_check = stellaris_protect_check, - .info = get_stellaris_info, -}; diff --git a/src/flash/nor/stm32f1x.c b/src/flash/nor/stm32f1x.c deleted file mode 100644 index d44670768..000000000 --- a/src/flash/nor/stm32f1x.c +++ /dev/null @@ -1,1650 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * Copyright (C) 2008 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * Copyright (C) 2011 by Andreas Fritiofson * - * andreas.fritiofson@gmail.com * - * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "imp.h" -#include -#include -#include - -/* stm32x register locations */ - -#define FLASH_REG_BASE_B0 0x40022000 -#define FLASH_REG_BASE_B1 0x40022040 - -#define STM32_FLASH_ACR 0x00 -#define STM32_FLASH_KEYR 0x04 -#define STM32_FLASH_OPTKEYR 0x08 -#define STM32_FLASH_SR 0x0C -#define STM32_FLASH_CR 0x10 -#define STM32_FLASH_AR 0x14 -#define STM32_FLASH_OBR 0x1C -#define STM32_FLASH_WRPR 0x20 - -/* TODO: Check if code using these really should be hard coded to bank 0. - * There are valid cases, on dual flash devices the protection of the - * second bank is done on the bank0 reg's. */ -#define STM32_FLASH_ACR_B0 0x40022000 -#define STM32_FLASH_KEYR_B0 0x40022004 -#define STM32_FLASH_OPTKEYR_B0 0x40022008 -#define STM32_FLASH_SR_B0 0x4002200C -#define STM32_FLASH_CR_B0 0x40022010 -#define STM32_FLASH_AR_B0 0x40022014 -#define STM32_FLASH_OBR_B0 0x4002201C -#define STM32_FLASH_WRPR_B0 0x40022020 - -/* option byte location */ - -#define STM32_OB_RDP 0x1FFFF800 -#define STM32_OB_USER 0x1FFFF802 -#define STM32_OB_DATA0 0x1FFFF804 -#define STM32_OB_DATA1 0x1FFFF806 -#define STM32_OB_WRP0 0x1FFFF808 -#define STM32_OB_WRP1 0x1FFFF80A -#define STM32_OB_WRP2 0x1FFFF80C -#define STM32_OB_WRP3 0x1FFFF80E - -/* FLASH_CR register bits */ - -#define FLASH_PG (1 << 0) -#define FLASH_PER (1 << 1) -#define FLASH_MER (1 << 2) -#define FLASH_OPTPG (1 << 4) -#define FLASH_OPTER (1 << 5) -#define FLASH_STRT (1 << 6) -#define FLASH_LOCK (1 << 7) -#define FLASH_OPTWRE (1 << 9) - -/* FLASH_SR register bits */ - -#define FLASH_BSY (1 << 0) -#define FLASH_PGERR (1 << 2) -#define FLASH_WRPRTERR (1 << 4) -#define FLASH_EOP (1 << 5) - -/* 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 */ - -/* register unlock keys */ - -#define KEY1 0x45670123 -#define KEY2 0xCDEF89AB - -/* timeout values */ - -#define FLASH_WRITE_TIMEOUT 10 -#define FLASH_ERASE_TIMEOUT 100 - -struct stm32x_options { - uint16_t RDP; - uint16_t user_options; - uint16_t user_data; - uint16_t protection[4]; -}; - -struct stm32x_flash_bank { - struct stm32x_options option_bytes; - int ppage_size; - int probed; - - bool has_dual_banks; - /* used to access dual flash bank stm32xl */ - uint32_t register_base; - uint16_t default_rdp; - int user_data_offset; - int option_offset; - uint32_t user_bank_size; -}; - -static int stm32x_mass_erase(struct flash_bank *bank); -static int stm32x_get_device_id(struct flash_bank *bank, uint32_t *device_id); -static int stm32x_write_block(struct flash_bank *bank, const uint8_t *buffer, - uint32_t offset, uint32_t count); - -/* flash bank stm32x 0 0 - */ -FLASH_BANK_COMMAND_HANDLER(stm32x_flash_bank_command) -{ - struct stm32x_flash_bank *stm32x_info; - - if (CMD_ARGC < 6) - return ERROR_COMMAND_SYNTAX_ERROR; - - stm32x_info = malloc(sizeof(struct stm32x_flash_bank)); - - bank->driver_priv = stm32x_info; - stm32x_info->probed = 0; - stm32x_info->has_dual_banks = false; - stm32x_info->register_base = FLASH_REG_BASE_B0; - stm32x_info->user_bank_size = bank->size; - - return ERROR_OK; -} - -static inline int stm32x_get_flash_reg(struct flash_bank *bank, uint32_t reg) -{ - struct stm32x_flash_bank *stm32x_info = bank->driver_priv; - return reg + stm32x_info->register_base; -} - -static inline int stm32x_get_flash_status(struct flash_bank *bank, uint32_t *status) -{ - struct target *target = bank->target; - return target_read_u32(target, stm32x_get_flash_reg(bank, STM32_FLASH_SR), status); -} - -static int stm32x_wait_status_busy(struct flash_bank *bank, int timeout) -{ - struct target *target = bank->target; - uint32_t status; - int retval = ERROR_OK; - - /* wait for busy to clear */ - for (;;) { - retval = stm32x_get_flash_status(bank, &status); - if (retval != ERROR_OK) - return retval; - LOG_DEBUG("status: 0x%" PRIx32 "", status); - if ((status & FLASH_BSY) == 0) - break; - if (timeout-- <= 0) { - LOG_ERROR("timed out waiting for flash"); - return ERROR_FAIL; - } - alive_sleep(1); - } - - if (status & FLASH_WRPRTERR) { - LOG_ERROR("stm32x device protected"); - retval = ERROR_FAIL; - } - - if (status & FLASH_PGERR) { - LOG_ERROR("stm32x device programming failed"); - retval = ERROR_FAIL; - } - - /* Clear but report errors */ - if (status & (FLASH_WRPRTERR | FLASH_PGERR)) { - /* If this operation fails, we ignore it and report the original - * retval - */ - target_write_u32(target, stm32x_get_flash_reg(bank, STM32_FLASH_SR), - FLASH_WRPRTERR | FLASH_PGERR); - } - return retval; -} - -static int stm32x_check_operation_supported(struct flash_bank *bank) -{ - struct stm32x_flash_bank *stm32x_info = bank->driver_priv; - - /* if we have a dual flash bank device then - * we need to perform option byte stuff on bank0 only */ - if (stm32x_info->register_base != FLASH_REG_BASE_B0) { - LOG_ERROR("Option Byte Operation's must use bank0"); - return ERROR_FLASH_OPERATION_FAILED; - } - - return ERROR_OK; -} - -static int stm32x_read_options(struct flash_bank *bank) -{ - uint32_t optiondata; - struct stm32x_flash_bank *stm32x_info = NULL; - struct target *target = bank->target; - - stm32x_info = bank->driver_priv; - - /* read current option bytes */ - int retval = target_read_u32(target, STM32_FLASH_OBR_B0, &optiondata); - if (retval != ERROR_OK) - return retval; - - stm32x_info->option_bytes.user_options = (optiondata >> stm32x_info->option_offset >> 2) & 0xffff; - stm32x_info->option_bytes.user_data = (optiondata >> stm32x_info->user_data_offset) & 0xffff; - stm32x_info->option_bytes.RDP = (optiondata & (1 << OPT_READOUT)) ? 0xFFFF : 0x5AA5; - - if (optiondata & (1 << OPT_READOUT)) - LOG_INFO("Device Security Bit Set"); - - /* each bit refers to a 4bank protection */ - retval = target_read_u32(target, STM32_FLASH_WRPR_B0, &optiondata); - if (retval != ERROR_OK) - return retval; - - stm32x_info->option_bytes.protection[0] = (uint16_t)optiondata; - stm32x_info->option_bytes.protection[1] = (uint16_t)(optiondata >> 8); - stm32x_info->option_bytes.protection[2] = (uint16_t)(optiondata >> 16); - stm32x_info->option_bytes.protection[3] = (uint16_t)(optiondata >> 24); - - return ERROR_OK; -} - -static int stm32x_erase_options(struct flash_bank *bank) -{ - struct stm32x_flash_bank *stm32x_info = NULL; - struct target *target = bank->target; - - stm32x_info = bank->driver_priv; - - /* read current options */ - stm32x_read_options(bank); - - /* unlock flash registers */ - int retval = target_write_u32(target, STM32_FLASH_KEYR_B0, KEY1); - if (retval != ERROR_OK) - return retval; - - retval = target_write_u32(target, STM32_FLASH_KEYR_B0, KEY2); - if (retval != ERROR_OK) - return retval; - - /* unlock option flash registers */ - retval = target_write_u32(target, STM32_FLASH_OPTKEYR_B0, KEY1); - if (retval != ERROR_OK) - return retval; - retval = target_write_u32(target, STM32_FLASH_OPTKEYR_B0, KEY2); - if (retval != ERROR_OK) - return retval; - - /* erase option bytes */ - retval = target_write_u32(target, STM32_FLASH_CR_B0, FLASH_OPTER | FLASH_OPTWRE); - if (retval != ERROR_OK) - return retval; - retval = target_write_u32(target, STM32_FLASH_CR_B0, FLASH_OPTER | FLASH_STRT | FLASH_OPTWRE); - if (retval != ERROR_OK) - return retval; - - retval = stm32x_wait_status_busy(bank, FLASH_ERASE_TIMEOUT); - if (retval != ERROR_OK) - return retval; - - /* clear readout protection and complementary option bytes - * this will also force a device unlock if set */ - stm32x_info->option_bytes.RDP = stm32x_info->default_rdp; - - return ERROR_OK; -} - -static int stm32x_write_options(struct flash_bank *bank) -{ - struct stm32x_flash_bank *stm32x_info = NULL; - struct target *target = bank->target; - - stm32x_info = bank->driver_priv; - - /* unlock flash registers */ - int retval = target_write_u32(target, STM32_FLASH_KEYR_B0, KEY1); - if (retval != ERROR_OK) - return retval; - retval = target_write_u32(target, STM32_FLASH_KEYR_B0, KEY2); - if (retval != ERROR_OK) - return retval; - - /* unlock option flash registers */ - retval = target_write_u32(target, STM32_FLASH_OPTKEYR_B0, KEY1); - if (retval != ERROR_OK) - return retval; - retval = target_write_u32(target, STM32_FLASH_OPTKEYR_B0, KEY2); - if (retval != ERROR_OK) - return retval; - - /* program option bytes */ - retval = target_write_u32(target, STM32_FLASH_CR_B0, FLASH_OPTPG | FLASH_OPTWRE); - if (retval != ERROR_OK) - return retval; - - uint8_t opt_bytes[16]; - - target_buffer_set_u16(target, opt_bytes, stm32x_info->option_bytes.RDP); - target_buffer_set_u16(target, opt_bytes + 2, stm32x_info->option_bytes.user_options); - target_buffer_set_u16(target, opt_bytes + 4, stm32x_info->option_bytes.user_data & 0xff); - target_buffer_set_u16(target, opt_bytes + 6, (stm32x_info->option_bytes.user_data >> 8) & 0xff); - target_buffer_set_u16(target, opt_bytes + 8, stm32x_info->option_bytes.protection[0]); - target_buffer_set_u16(target, opt_bytes + 10, stm32x_info->option_bytes.protection[1]); - target_buffer_set_u16(target, opt_bytes + 12, stm32x_info->option_bytes.protection[2]); - target_buffer_set_u16(target, opt_bytes + 14, stm32x_info->option_bytes.protection[3]); - - uint32_t offset = STM32_OB_RDP - bank->base; - retval = stm32x_write_block(bank, opt_bytes, offset, sizeof(opt_bytes) / 2); - if (retval != ERROR_OK) { - if (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE) - LOG_ERROR("working area required to erase options bytes"); - return retval; - } - - retval = target_write_u32(target, STM32_FLASH_CR_B0, FLASH_LOCK); - if (retval != ERROR_OK) - return retval; - - return ERROR_OK; -} - -static int stm32x_protect_check(struct flash_bank *bank) -{ - struct target *target = bank->target; - struct stm32x_flash_bank *stm32x_info = bank->driver_priv; - - uint32_t protection; - int i, s; - int num_bits; - int set; - - int retval = stm32x_check_operation_supported(bank); - if (ERROR_OK != retval) - return retval; - - /* medium density - each bit refers to a 4bank protection - * high density - each bit refers to a 2bank protection */ - retval = target_read_u32(target, STM32_FLASH_WRPR_B0, &protection); - if (retval != ERROR_OK) - return retval; - - /* medium density - each protection bit is for 4 * 1K pages - * high density - each protection bit is for 2 * 2K pages */ - num_bits = (bank->num_sectors / stm32x_info->ppage_size); - - if (stm32x_info->ppage_size == 2) { - /* high density flash/connectivity line protection */ - - set = 1; - - if (protection & (1 << 31)) - set = 0; - - /* bit 31 controls sector 62 - 255 protection for high density - * bit 31 controls sector 62 - 127 protection for connectivity line */ - for (s = 62; s < bank->num_sectors; s++) - bank->sectors[s].is_protected = set; - - if (bank->num_sectors > 61) - num_bits = 31; - - for (i = 0; i < num_bits; i++) { - set = 1; - - if (protection & (1 << i)) - set = 0; - - for (s = 0; s < stm32x_info->ppage_size; s++) - bank->sectors[(i * stm32x_info->ppage_size) + s].is_protected = set; - } - } else { - /* low/medium density flash protection */ - for (i = 0; i < num_bits; i++) { - set = 1; - - if (protection & (1 << i)) - set = 0; - - for (s = 0; s < stm32x_info->ppage_size; s++) - bank->sectors[(i * stm32x_info->ppage_size) + s].is_protected = set; - } - } - - return ERROR_OK; -} - -static int stm32x_erase(struct flash_bank *bank, int first, int last) -{ - struct target *target = bank->target; - int i; - - if (bank->target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - if ((first == 0) && (last == (bank->num_sectors - 1))) - return stm32x_mass_erase(bank); - - /* unlock flash registers */ - int retval = target_write_u32(target, stm32x_get_flash_reg(bank, STM32_FLASH_KEYR), KEY1); - if (retval != ERROR_OK) - return retval; - retval = target_write_u32(target, stm32x_get_flash_reg(bank, STM32_FLASH_KEYR), KEY2); - if (retval != ERROR_OK) - return retval; - - for (i = first; i <= last; i++) { - retval = target_write_u32(target, stm32x_get_flash_reg(bank, STM32_FLASH_CR), FLASH_PER); - if (retval != ERROR_OK) - return retval; - retval = target_write_u32(target, stm32x_get_flash_reg(bank, STM32_FLASH_AR), - bank->base + bank->sectors[i].offset); - if (retval != ERROR_OK) - return retval; - retval = target_write_u32(target, - stm32x_get_flash_reg(bank, STM32_FLASH_CR), FLASH_PER | FLASH_STRT); - if (retval != ERROR_OK) - return retval; - - retval = stm32x_wait_status_busy(bank, FLASH_ERASE_TIMEOUT); - if (retval != ERROR_OK) - return retval; - - bank->sectors[i].is_erased = 1; - } - - retval = target_write_u32(target, stm32x_get_flash_reg(bank, STM32_FLASH_CR), FLASH_LOCK); - if (retval != ERROR_OK) - return retval; - - return ERROR_OK; -} - -static int stm32x_protect(struct flash_bank *bank, int set, int first, int last) -{ - struct stm32x_flash_bank *stm32x_info = NULL; - struct target *target = bank->target; - uint16_t prot_reg[4] = {0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF}; - int i, reg, bit; - int status; - uint32_t protection; - - stm32x_info = bank->driver_priv; - - if (target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - int retval = stm32x_check_operation_supported(bank); - if (ERROR_OK != retval) - return retval; - - if ((first % stm32x_info->ppage_size) != 0) { - LOG_WARNING("aligned start protect sector to a %d sector boundary", - stm32x_info->ppage_size); - first = first - (first % stm32x_info->ppage_size); - } - if (((last + 1) % stm32x_info->ppage_size) != 0) { - LOG_WARNING("aligned end protect sector to a %d sector boundary", - stm32x_info->ppage_size); - last++; - last = last - (last % stm32x_info->ppage_size); - last--; - } - - /* medium density - each bit refers to a 4bank protection - * high density - each bit refers to a 2bank protection */ - retval = target_read_u32(target, STM32_FLASH_WRPR_B0, &protection); - if (retval != ERROR_OK) - return retval; - - prot_reg[0] = (uint16_t)protection; - prot_reg[1] = (uint16_t)(protection >> 8); - prot_reg[2] = (uint16_t)(protection >> 16); - prot_reg[3] = (uint16_t)(protection >> 24); - - if (stm32x_info->ppage_size == 2) { - /* high density flash */ - - /* bit 7 controls sector 62 - 255 protection */ - if (last > 61) { - if (set) - prot_reg[3] &= ~(1 << 7); - else - prot_reg[3] |= (1 << 7); - } - - if (first > 61) - first = 62; - if (last > 61) - last = 61; - - for (i = first; i <= last; i++) { - reg = (i / stm32x_info->ppage_size) / 8; - bit = (i / stm32x_info->ppage_size) - (reg * 8); - - if (set) - prot_reg[reg] &= ~(1 << bit); - else - prot_reg[reg] |= (1 << bit); - } - } else { - /* medium density flash */ - for (i = first; i <= last; i++) { - reg = (i / stm32x_info->ppage_size) / 8; - bit = (i / stm32x_info->ppage_size) - (reg * 8); - - if (set) - prot_reg[reg] &= ~(1 << bit); - else - prot_reg[reg] |= (1 << bit); - } - } - - status = stm32x_erase_options(bank); - if (status != ERROR_OK) - return status; - - stm32x_info->option_bytes.protection[0] = prot_reg[0]; - stm32x_info->option_bytes.protection[1] = prot_reg[1]; - stm32x_info->option_bytes.protection[2] = prot_reg[2]; - stm32x_info->option_bytes.protection[3] = prot_reg[3]; - - return stm32x_write_options(bank); -} - -static int stm32x_write_block(struct flash_bank *bank, const uint8_t *buffer, - uint32_t offset, uint32_t count) -{ - struct stm32x_flash_bank *stm32x_info = bank->driver_priv; - struct target *target = bank->target; - uint32_t buffer_size = 16384; - struct working_area *write_algorithm; - struct working_area *source; - uint32_t address = bank->base + offset; - struct reg_param reg_params[5]; - struct armv7m_algorithm armv7m_info; - int retval = ERROR_OK; - - /* see contrib/loaders/flash/stm32f1x.S for src */ - - static const uint8_t stm32x_flash_write_code[] = { - /* #define STM32_FLASH_SR_OFFSET 0x0C */ - /* wait_fifo: */ - 0x16, 0x68, /* ldr r6, [r2, #0] */ - 0x00, 0x2e, /* cmp r6, #0 */ - 0x18, 0xd0, /* beq exit */ - 0x55, 0x68, /* ldr r5, [r2, #4] */ - 0xb5, 0x42, /* cmp r5, r6 */ - 0xf9, 0xd0, /* beq wait_fifo */ - 0x2e, 0x88, /* ldrh r6, [r5, #0] */ - 0x26, 0x80, /* strh r6, [r4, #0] */ - 0x02, 0x35, /* adds r5, #2 */ - 0x02, 0x34, /* adds r4, #2 */ - /* busy: */ - 0xc6, 0x68, /* ldr r6, [r0, #STM32_FLASH_SR_OFFSET] */ - 0x01, 0x27, /* movs r7, #1 */ - 0x3e, 0x42, /* tst r6, r7 */ - 0xfb, 0xd1, /* bne busy */ - 0x14, 0x27, /* movs r7, #0x14 */ - 0x3e, 0x42, /* tst r6, r7 */ - 0x08, 0xd1, /* bne error */ - 0x9d, 0x42, /* cmp r5, r3 */ - 0x01, 0xd3, /* bcc no_wrap */ - 0x15, 0x46, /* mov r5, r2 */ - 0x08, 0x35, /* adds r5, #8 */ - /* no_wrap: */ - 0x55, 0x60, /* str r5, [r2, #4] */ - 0x01, 0x39, /* subs r1, r1, #1 */ - 0x00, 0x29, /* cmp r1, #0 */ - 0x02, 0xd0, /* beq exit */ - 0xe5, 0xe7, /* b wait_fifo */ - /* error: */ - 0x00, 0x20, /* movs r0, #0 */ - 0x50, 0x60, /* str r0, [r2, #4] */ - /* exit: */ - 0x30, 0x46, /* mov r0, r6 */ - 0x00, 0xbe, /* bkpt #0 */ - }; - - /* flash write code */ - if (target_alloc_working_area(target, sizeof(stm32x_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(stm32x_flash_write_code), stm32x_flash_write_code); - if (retval != ERROR_OK) - return retval; - - /* memory buffer */ - while (target_alloc_working_area_try(target, buffer_size, &source) != ERROR_OK) { - buffer_size /= 2; - buffer_size &= ~3UL; /* Make sure it's 4 byte aligned */ - if (buffer_size <= 256) { - /* we already allocated the writing code, but failed to get a - * buffer, free the algorithm */ - target_free_working_area(target, write_algorithm); - - 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) */ - init_reg_param(®_params[2], "r2", 32, PARAM_OUT); /* buffer start */ - init_reg_param(®_params[3], "r3", 32, PARAM_OUT); /* buffer end */ - init_reg_param(®_params[4], "r4", 32, PARAM_IN_OUT); /* target address */ - - buf_set_u32(reg_params[0].value, 0, 32, stm32x_info->register_base); - buf_set_u32(reg_params[1].value, 0, 32, count); - 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, address); - - armv7m_info.common_magic = ARMV7M_COMMON_MAGIC; - armv7m_info.core_mode = ARM_MODE_THREAD; - - retval = target_run_flash_async_algorithm(target, buffer, count, 2, - 0, NULL, - 5, reg_params, - source->address, source->size, - write_algorithm->address, 0, - &armv7m_info); - - if (retval == ERROR_FLASH_OPERATION_FAILED) { - LOG_ERROR("flash write failed at address 0x%"PRIx32, - buf_get_u32(reg_params[4].value, 0, 32)); - - if (buf_get_u32(reg_params[0].value, 0, 32) & FLASH_PGERR) { - LOG_ERROR("flash memory not erased before writing"); - /* Clear but report errors */ - target_write_u32(target, stm32x_get_flash_reg(bank, STM32_FLASH_SR), FLASH_PGERR); - } - - if (buf_get_u32(reg_params[0].value, 0, 32) & FLASH_WRPRTERR) { - LOG_ERROR("flash memory write protected"); - /* Clear but report errors */ - target_write_u32(target, stm32x_get_flash_reg(bank, STM32_FLASH_SR), FLASH_WRPRTERR); - } - } - - target_free_working_area(target, source); - target_free_working_area(target, write_algorithm); - - 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 stm32x_write(struct flash_bank *bank, const uint8_t *buffer, - uint32_t offset, uint32_t count) -{ - struct target *target = bank->target; - uint8_t *new_buffer = NULL; - - if (bank->target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - if (offset & 0x1) { - LOG_ERROR("offset 0x%" PRIx32 " breaks required 2-byte alignment", offset); - return ERROR_FLASH_DST_BREAKS_ALIGNMENT; - } - - /* If there's an odd number of bytes, 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. */ - if (count & 1) { - new_buffer = malloc(count + 1); - if (new_buffer == NULL) { - LOG_ERROR("odd number of bytes to write and no memory for padding buffer"); - return ERROR_FAIL; - } - LOG_INFO("odd number of bytes to write, padding with 0xff"); - buffer = memcpy(new_buffer, buffer, count); - new_buffer[count++] = 0xff; - } - - uint32_t words_remaining = count / 2; - int retval, retval2; - - /* unlock flash registers */ - retval = target_write_u32(target, stm32x_get_flash_reg(bank, STM32_FLASH_KEYR), KEY1); - if (retval != ERROR_OK) - goto cleanup; - retval = target_write_u32(target, stm32x_get_flash_reg(bank, STM32_FLASH_KEYR), KEY2); - if (retval != ERROR_OK) - goto cleanup; - - retval = target_write_u32(target, stm32x_get_flash_reg(bank, STM32_FLASH_CR), FLASH_PG); - if (retval != ERROR_OK) - goto cleanup; - - /* try using a block write */ - retval = stm32x_write_block(bank, buffer, offset, words_remaining); - - if (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE) { - /* if block write failed (no sufficient working area), - * we use normal (slow) single halfword accesses */ - LOG_WARNING("couldn't use block writes, falling back to single memory accesses"); - - while (words_remaining > 0) { - uint16_t value; - memcpy(&value, buffer, sizeof(uint16_t)); - - retval = target_write_u16(target, bank->base + offset, value); - if (retval != ERROR_OK) - goto reset_pg_and_lock; - - retval = stm32x_wait_status_busy(bank, 5); - if (retval != ERROR_OK) - goto reset_pg_and_lock; - - words_remaining--; - buffer += 2; - offset += 2; - } - } - -reset_pg_and_lock: - retval2 = target_write_u32(target, stm32x_get_flash_reg(bank, STM32_FLASH_CR), FLASH_LOCK); - if (retval == ERROR_OK) - retval = retval2; - -cleanup: - if (new_buffer) - free(new_buffer); - - return retval; -} - -static int stm32x_get_device_id(struct flash_bank *bank, uint32_t *device_id) -{ - /* This check the device CPUID core register to detect - * the M0 from the M3 devices. */ - - struct target *target = bank->target; - uint32_t cpuid, device_id_register = 0; - - /* Get the CPUID from the ARM Core - * http://infocenter.arm.com/help/topic/com.arm.doc.ddi0432c/DDI0432C_cortex_m0_r0p0_trm.pdf 4.2.1 */ - int retval = target_read_u32(target, 0xE000ED00, &cpuid); - if (retval != ERROR_OK) - return retval; - - if (((cpuid >> 4) & 0xFFF) == 0xC20) { - /* 0xC20 is M0 devices */ - device_id_register = 0x40015800; - } else if (((cpuid >> 4) & 0xFFF) == 0xC23) { - /* 0xC23 is M3 devices */ - device_id_register = 0xE0042000; - } else if (((cpuid >> 4) & 0xFFF) == 0xC24) { - /* 0xC24 is M4 devices */ - device_id_register = 0xE0042000; - } else { - LOG_ERROR("Cannot identify target as a stm32x"); - return ERROR_FAIL; - } - - /* read stm32 device id register */ - retval = target_read_u32(target, device_id_register, device_id); - if (retval != ERROR_OK) - return retval; - - return retval; -} - -static int stm32x_get_flash_size(struct flash_bank *bank, uint16_t *flash_size_in_kb) -{ - struct target *target = bank->target; - uint32_t cpuid, flash_size_reg; - - int retval = target_read_u32(target, 0xE000ED00, &cpuid); - if (retval != ERROR_OK) - return retval; - - if (((cpuid >> 4) & 0xFFF) == 0xC20) { - /* 0xC20 is M0 devices */ - flash_size_reg = 0x1FFFF7CC; - } else if (((cpuid >> 4) & 0xFFF) == 0xC23) { - /* 0xC23 is M3 devices */ - flash_size_reg = 0x1FFFF7E0; - } else if (((cpuid >> 4) & 0xFFF) == 0xC24) { - /* 0xC24 is M4 devices */ - flash_size_reg = 0x1FFFF7CC; - } else { - LOG_ERROR("Cannot identify target as a stm32x"); - return ERROR_FAIL; - } - - retval = target_read_u16(target, flash_size_reg, flash_size_in_kb); - if (retval != ERROR_OK) - return retval; - - return retval; -} - -static int stm32x_probe(struct flash_bank *bank) -{ - struct stm32x_flash_bank *stm32x_info = bank->driver_priv; - int i; - uint16_t flash_size_in_kb; - uint16_t max_flash_size_in_kb; - uint32_t device_id; - int page_size; - uint32_t base_address = 0x08000000; - - stm32x_info->probed = 0; - stm32x_info->register_base = FLASH_REG_BASE_B0; - stm32x_info->user_data_offset = 10; - stm32x_info->option_offset = 0; - - /* default factory protection level */ - stm32x_info->default_rdp = 0x5AA5; - - /* read stm32 device id register */ - int retval = stm32x_get_device_id(bank, &device_id); - if (retval != ERROR_OK) - return retval; - - LOG_INFO("device id = 0x%08" PRIx32 "", device_id); - - /* set page size, protection granularity and max flash size depending on family */ - switch (device_id & 0xfff) { - case 0x410: /* medium density */ - page_size = 1024; - stm32x_info->ppage_size = 4; - max_flash_size_in_kb = 128; - break; - case 0x412: /* low density */ - page_size = 1024; - stm32x_info->ppage_size = 4; - max_flash_size_in_kb = 32; - break; - case 0x414: /* high density */ - page_size = 2048; - stm32x_info->ppage_size = 2; - max_flash_size_in_kb = 512; - break; - case 0x418: /* connectivity line density */ - page_size = 2048; - stm32x_info->ppage_size = 2; - max_flash_size_in_kb = 256; - break; - case 0x420: /* value line density */ - page_size = 1024; - stm32x_info->ppage_size = 4; - max_flash_size_in_kb = 128; - break; - case 0x422: /* stm32f302/3xb/c */ - page_size = 2048; - stm32x_info->ppage_size = 2; - max_flash_size_in_kb = 256; - stm32x_info->user_data_offset = 16; - stm32x_info->option_offset = 6; - stm32x_info->default_rdp = 0x55AA; - break; - case 0x446: /* stm32f303xD/E */ - page_size = 2048; - stm32x_info->ppage_size = 2; - max_flash_size_in_kb = 512; - stm32x_info->user_data_offset = 16; - stm32x_info->option_offset = 6; - stm32x_info->default_rdp = 0x55AA; - break; - case 0x428: /* value line High density */ - page_size = 2048; - stm32x_info->ppage_size = 4; - max_flash_size_in_kb = 128; - break; - case 0x430: /* xl line density (dual flash banks) */ - page_size = 2048; - stm32x_info->ppage_size = 2; - max_flash_size_in_kb = 1024; - stm32x_info->has_dual_banks = true; - break; - case 0x432: /* stm32f37x */ - page_size = 2048; - stm32x_info->ppage_size = 2; - max_flash_size_in_kb = 256; - stm32x_info->user_data_offset = 16; - stm32x_info->option_offset = 6; - stm32x_info->default_rdp = 0x55AA; - break; - case 0x438: /* stm32f33x */ - case 0x439: /* stm32f302x6/8 */ - page_size = 2048; - stm32x_info->ppage_size = 2; - max_flash_size_in_kb = 64; - stm32x_info->user_data_offset = 16; - stm32x_info->option_offset = 6; - stm32x_info->default_rdp = 0x55AA; - break; - case 0x440: /* stm32f05x */ - case 0x444: /* stm32f03x */ - case 0x445: /* stm32f04x */ - page_size = 1024; - stm32x_info->ppage_size = 4; - max_flash_size_in_kb = 64; - stm32x_info->user_data_offset = 16; - stm32x_info->option_offset = 6; - stm32x_info->default_rdp = 0x55AA; - break; - case 0x448: /* stm32f07x */ - case 0x442: /* stm32f09x */ - page_size = 2048; - stm32x_info->ppage_size = 4; - max_flash_size_in_kb = 256; - stm32x_info->user_data_offset = 16; - stm32x_info->option_offset = 6; - stm32x_info->default_rdp = 0x55AA; - break; - default: - LOG_WARNING("Cannot identify target as a STM32 family."); - return ERROR_FAIL; - } - - /* get flash size from target. */ - retval = stm32x_get_flash_size(bank, &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; - } - - if (stm32x_info->has_dual_banks) { - /* split reported size into matching bank */ - if (bank->base != 0x08080000) { - /* bank 0 will be fixed 512k */ - flash_size_in_kb = 512; - } else { - flash_size_in_kb -= 512; - /* bank1 also uses a register offset */ - stm32x_info->register_base = FLASH_REG_BASE_B1; - base_address = 0x08080000; - } - } - - /* if the user sets the size manually then ignore the probed value - * this allows us to work around devices that have a invalid flash size register value */ - if (stm32x_info->user_bank_size) { - LOG_INFO("ignoring flash probed value, using configured bank size"); - flash_size_in_kb = stm32x_info->user_bank_size / 1024; - } - - LOG_INFO("flash size = %dkbytes", flash_size_in_kb); - - /* did we assign flash size? */ - assert(flash_size_in_kb != 0xffff); - - /* calculate numbers of pages */ - int num_pages = flash_size_in_kb * 1024 / page_size; - - /* check that calculation result makes sense */ - assert(num_pages > 0); - - if (bank->sectors) { - free(bank->sectors); - bank->sectors = NULL; - } - - bank->base = base_address; - bank->size = (num_pages * page_size); - bank->num_sectors = num_pages; - bank->sectors = malloc(sizeof(struct flash_sector) * num_pages); - - for (i = 0; i < num_pages; i++) { - bank->sectors[i].offset = i * page_size; - bank->sectors[i].size = page_size; - bank->sectors[i].is_erased = -1; - bank->sectors[i].is_protected = 1; - } - - stm32x_info->probed = 1; - - return ERROR_OK; -} - -static int stm32x_auto_probe(struct flash_bank *bank) -{ - struct stm32x_flash_bank *stm32x_info = bank->driver_priv; - if (stm32x_info->probed) - return ERROR_OK; - return stm32x_probe(bank); -} - -#if 0 -COMMAND_HANDLER(stm32x_handle_part_id_command) -{ - return ERROR_OK; -} -#endif - -static const char *get_stm32f0_revision(uint16_t rev_id) -{ - const char *rev_str = NULL; - - switch (rev_id) { - case 0x1000: - rev_str = "1.0"; - break; - case 0x2000: - rev_str = "2.0"; - break; - } - return rev_str; -} - -static int get_stm32x_info(struct flash_bank *bank, char *buf, int buf_size) -{ - uint32_t dbgmcu_idcode; - - /* read stm32 device id register */ - int retval = stm32x_get_device_id(bank, &dbgmcu_idcode); - if (retval != ERROR_OK) - return retval; - - uint16_t device_id = dbgmcu_idcode & 0xfff; - uint16_t rev_id = dbgmcu_idcode >> 16; - const char *device_str; - const char *rev_str = NULL; - - switch (device_id) { - case 0x410: - device_str = "STM32F10x (Medium Density)"; - - switch (rev_id) { - case 0x0000: - rev_str = "A"; - break; - - case 0x2000: - rev_str = "B"; - break; - - case 0x2001: - rev_str = "Z"; - break; - - case 0x2003: - rev_str = "Y"; - break; - } - break; - - case 0x412: - device_str = "STM32F10x (Low Density)"; - - switch (rev_id) { - case 0x1000: - rev_str = "A"; - break; - } - break; - - case 0x414: - device_str = "STM32F10x (High Density)"; - - switch (rev_id) { - case 0x1000: - rev_str = "A"; - break; - - case 0x1001: - rev_str = "Z"; - break; - - case 0x1003: - rev_str = "Y"; - break; - } - break; - - case 0x418: - device_str = "STM32F10x (Connectivity)"; - - switch (rev_id) { - case 0x1000: - rev_str = "A"; - break; - - case 0x1001: - rev_str = "Z"; - break; - } - break; - - case 0x420: - device_str = "STM32F100 (Low/Medium Density)"; - - switch (rev_id) { - case 0x1000: - rev_str = "A"; - break; - - case 0x1001: - rev_str = "Z"; - break; - } - break; - - case 0x422: - device_str = "STM32F302xB/C"; - - switch (rev_id) { - case 0x1000: - rev_str = "A"; - break; - - case 0x1001: - rev_str = "Z"; - break; - - case 0x1003: - rev_str = "Y"; - break; - - case 0x2000: - rev_str = "B"; - break; - } - break; - - case 0x428: - device_str = "STM32F100 (High Density)"; - - switch (rev_id) { - case 0x1000: - rev_str = "A"; - break; - - case 0x1001: - rev_str = "Z"; - break; - } - break; - - case 0x430: - device_str = "STM32F10x (XL Density)"; - - switch (rev_id) { - case 0x1000: - rev_str = "A"; - break; - } - break; - - case 0x432: - device_str = "STM32F37x"; - - switch (rev_id) { - case 0x1000: - rev_str = "A"; - break; - - case 0x2000: - rev_str = "B"; - break; - } - break; - - case 0x438: - device_str = "STM32F33x"; - - switch (rev_id) { - case 0x1000: - rev_str = "A"; - break; - } - break; - - case 0x439: - device_str = "STM32F302x6/8"; - - switch (rev_id) { - case 0x1000: - rev_str = "A"; - break; - - case 0x1001: - rev_str = "Z"; - break; - } - break; - - case 0x444: - device_str = "STM32F03x"; - rev_str = get_stm32f0_revision(rev_id); - break; - - case 0x440: - device_str = "STM32F05x"; - rev_str = get_stm32f0_revision(rev_id); - break; - - case 0x445: - device_str = "STM32F04x"; - rev_str = get_stm32f0_revision(rev_id); - break; - - case 0x446: - device_str = "STM32F303xD/E"; - switch (rev_id) { - case 0x1000: - rev_str = "A"; - break; - } - break; - - case 0x448: - device_str = "STM32F07x"; - rev_str = get_stm32f0_revision(rev_id); - break; - - case 0x442: - device_str = "STM32F09x"; - rev_str = get_stm32f0_revision(rev_id); - break; - - default: - snprintf(buf, buf_size, "Cannot identify target as a STM32F0/1/3\n"); - return ERROR_FAIL; - } - - if (rev_str != NULL) - snprintf(buf, buf_size, "%s - Rev: %s", device_str, rev_str); - else - snprintf(buf, buf_size, "%s - Rev: unknown (0x%04x)", device_str, rev_id); - - return ERROR_OK; -} - -COMMAND_HANDLER(stm32x_handle_lock_command) -{ - struct target *target = NULL; - struct stm32x_flash_bank *stm32x_info = 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; - - stm32x_info = bank->driver_priv; - - target = bank->target; - - if (target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - retval = stm32x_check_operation_supported(bank); - if (ERROR_OK != retval) - return retval; - - if (stm32x_erase_options(bank) != ERROR_OK) { - command_print(CMD_CTX, "stm32x failed to erase options"); - return ERROR_OK; - } - - /* set readout protection */ - stm32x_info->option_bytes.RDP = 0; - - if (stm32x_write_options(bank) != ERROR_OK) { - command_print(CMD_CTX, "stm32x failed to lock device"); - return ERROR_OK; - } - - command_print(CMD_CTX, "stm32x locked"); - - return ERROR_OK; -} - -COMMAND_HANDLER(stm32x_handle_unlock_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; - - target = bank->target; - - if (target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - retval = stm32x_check_operation_supported(bank); - if (ERROR_OK != retval) - return retval; - - if (stm32x_erase_options(bank) != ERROR_OK) { - command_print(CMD_CTX, "stm32x failed to unlock device"); - return ERROR_OK; - } - - if (stm32x_write_options(bank) != ERROR_OK) { - command_print(CMD_CTX, "stm32x failed to lock device"); - return ERROR_OK; - } - - command_print(CMD_CTX, "stm32x unlocked.\n" - "INFO: a reset or power cycle is required " - "for the new settings to take effect."); - - return ERROR_OK; -} - -COMMAND_HANDLER(stm32x_handle_options_read_command) -{ - uint32_t optionbyte; - struct target *target = NULL; - struct stm32x_flash_bank *stm32x_info = 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; - - stm32x_info = bank->driver_priv; - - target = bank->target; - - if (target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - retval = stm32x_check_operation_supported(bank); - if (ERROR_OK != retval) - return retval; - - retval = target_read_u32(target, STM32_FLASH_OBR_B0, &optionbyte); - if (retval != ERROR_OK) - return retval; - command_print(CMD_CTX, "Option Byte: 0x%" PRIx32 "", optionbyte); - - int user_data = optionbyte; - - if (optionbyte >> OPT_ERROR & 1) - command_print(CMD_CTX, "Option Byte Complement Error"); - - if (optionbyte >> OPT_READOUT & 1) - command_print(CMD_CTX, "Readout Protection On"); - else - command_print(CMD_CTX, "Readout Protection Off"); - - /* user option bytes are offset depending on variant */ - optionbyte >>= stm32x_info->option_offset; - - if (optionbyte >> OPT_RDWDGSW & 1) - command_print(CMD_CTX, "Software Watchdog"); - else - command_print(CMD_CTX, "Hardware Watchdog"); - - if (optionbyte >> OPT_RDRSTSTOP & 1) - command_print(CMD_CTX, "Stop: No reset generated"); - else - command_print(CMD_CTX, "Stop: Reset generated"); - - if (optionbyte >> OPT_RDRSTSTDBY & 1) - command_print(CMD_CTX, "Standby: No reset generated"); - else - command_print(CMD_CTX, "Standby: Reset generated"); - - if (stm32x_info->has_dual_banks) { - if (optionbyte >> OPT_BFB2 & 1) - command_print(CMD_CTX, "Boot: Bank 0"); - else - command_print(CMD_CTX, "Boot: Bank 1"); - } - - command_print(CMD_CTX, "User Option0: 0x%02" PRIx8, - (uint8_t)((user_data >> stm32x_info->user_data_offset) & 0xff)); - command_print(CMD_CTX, "User Option1: 0x%02" PRIx8, - (uint8_t)((user_data >> (stm32x_info->user_data_offset + 8)) & 0xff)); - - return ERROR_OK; -} - -COMMAND_HANDLER(stm32x_handle_options_write_command) -{ - struct target *target = NULL; - struct stm32x_flash_bank *stm32x_info = NULL; - uint16_t optionbyte; - - if (CMD_ARGC < 2) - 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; - - stm32x_info = bank->driver_priv; - - target = bank->target; - - if (target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - retval = stm32x_check_operation_supported(bank); - if (ERROR_OK != retval) - return retval; - - retval = stm32x_read_options(bank); - if (ERROR_OK != retval) - return retval; - - /* start with current options */ - optionbyte = stm32x_info->option_bytes.user_options; - - /* skip over flash bank */ - CMD_ARGC--; - CMD_ARGV++; - - while (CMD_ARGC) { - if (strcmp("SWWDG", CMD_ARGV[0]) == 0) - optionbyte |= (1 << 0); - else if (strcmp("HWWDG", CMD_ARGV[0]) == 0) - optionbyte &= ~(1 << 0); - else if (strcmp("NORSTSTOP", CMD_ARGV[0]) == 0) - optionbyte |= (1 << 1); - else if (strcmp("RSTSTOP", CMD_ARGV[0]) == 0) - optionbyte &= ~(1 << 1); - else if (strcmp("NORSTSTNDBY", CMD_ARGV[0]) == 0) - optionbyte |= (1 << 2); - else if (strcmp("RSTSTNDBY", CMD_ARGV[0]) == 0) - optionbyte &= ~(1 << 2); - else if (stm32x_info->has_dual_banks) { - if (strcmp("BOOT0", CMD_ARGV[0]) == 0) - optionbyte |= (1 << 3); - else if (strcmp("BOOT1", CMD_ARGV[0]) == 0) - optionbyte &= ~(1 << 3); - else - return ERROR_COMMAND_SYNTAX_ERROR; - } else - return ERROR_COMMAND_SYNTAX_ERROR; - CMD_ARGC--; - CMD_ARGV++; - } - - if (stm32x_erase_options(bank) != ERROR_OK) { - command_print(CMD_CTX, "stm32x failed to erase options"); - return ERROR_OK; - } - - stm32x_info->option_bytes.user_options = optionbyte; - - if (stm32x_write_options(bank) != ERROR_OK) { - command_print(CMD_CTX, "stm32x failed to write options"); - return ERROR_OK; - } - - command_print(CMD_CTX, "stm32x write options complete.\n" - "INFO: a reset or power cycle is required " - "for the new settings to take effect."); - - return ERROR_OK; -} - -static int stm32x_mass_erase(struct flash_bank *bank) -{ - struct target *target = bank->target; - - if (target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - /* unlock option flash registers */ - int retval = target_write_u32(target, stm32x_get_flash_reg(bank, STM32_FLASH_KEYR), KEY1); - if (retval != ERROR_OK) - return retval; - retval = target_write_u32(target, stm32x_get_flash_reg(bank, STM32_FLASH_KEYR), KEY2); - if (retval != ERROR_OK) - return retval; - - /* mass erase flash memory */ - 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); - if (retval != ERROR_OK) - return retval; - - retval = stm32x_wait_status_busy(bank, FLASH_ERASE_TIMEOUT); - if (retval != ERROR_OK) - return retval; - - retval = target_write_u32(target, stm32x_get_flash_reg(bank, STM32_FLASH_CR), FLASH_LOCK); - if (retval != ERROR_OK) - return retval; - - return ERROR_OK; -} - -COMMAND_HANDLER(stm32x_handle_mass_erase_command) -{ - int i; - - 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 = stm32x_mass_erase(bank); - if (retval == ERROR_OK) { - /* set all sectors as erased */ - for (i = 0; i < bank->num_sectors; i++) - bank->sectors[i].is_erased = 1; - - command_print(CMD_CTX, "stm32x mass erase complete"); - } else - command_print(CMD_CTX, "stm32x mass erase failed"); - - return retval; -} - -static const struct command_registration stm32x_exec_command_handlers[] = { - { - .name = "lock", - .handler = stm32x_handle_lock_command, - .mode = COMMAND_EXEC, - .usage = "bank_id", - .help = "Lock entire flash device.", - }, - { - .name = "unlock", - .handler = stm32x_handle_unlock_command, - .mode = COMMAND_EXEC, - .usage = "bank_id", - .help = "Unlock entire protected flash device.", - }, - { - .name = "mass_erase", - .handler = stm32x_handle_mass_erase_command, - .mode = COMMAND_EXEC, - .usage = "bank_id", - .help = "Erase entire flash device.", - }, - { - .name = "options_read", - .handler = stm32x_handle_options_read_command, - .mode = COMMAND_EXEC, - .usage = "bank_id", - .help = "Read and display device option byte.", - }, - { - .name = "options_write", - .handler = stm32x_handle_options_write_command, - .mode = COMMAND_EXEC, - .usage = "bank_id ('SWWDG'|'HWWDG') " - "('RSTSTNDBY'|'NORSTSTNDBY') " - "('RSTSTOP'|'NORSTSTOP')", - .help = "Replace bits in device option byte.", - }, - COMMAND_REGISTRATION_DONE -}; - -static const struct command_registration stm32x_command_handlers[] = { - { - .name = "stm32f1x", - .mode = COMMAND_ANY, - .help = "stm32f1x flash command group", - .usage = "", - .chain = stm32x_exec_command_handlers, - }, - COMMAND_REGISTRATION_DONE -}; - -struct flash_driver stm32f1x_flash = { - .name = "stm32f1x", - .commands = stm32x_command_handlers, - .flash_bank_command = stm32x_flash_bank_command, - .erase = stm32x_erase, - .protect = stm32x_protect, - .write = stm32x_write, - .read = default_flash_read, - .probe = stm32x_probe, - .auto_probe = stm32x_auto_probe, - .erase_check = default_flash_blank_check, - .protect_check = stm32x_protect_check, - .info = get_stm32x_info, -}; diff --git a/src/flash/nor/stm32f2x.c b/src/flash/nor/stm32f2x.c deleted file mode 100644 index 1acab8222..000000000 --- a/src/flash/nor/stm32f2x.c +++ /dev/null @@ -1,1463 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * Copyright (C) 2008 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * Copyright (C) 2011 Øyvind Harboe * - * oyvind.harboe@zylin.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "imp.h" -#include -#include -#include - -/* Regarding performance: - * - * Short story - it might be best to leave the performance at - * current levels. - * - * You may see a jump in speed if you change to using - * 32bit words for the block programming. - * - * Its a shame you cannot use the double word as its - * even faster - but you require external VPP for that mode. - * - * Having said all that 16bit writes give us the widest vdd - * operating range, so may be worth adding a note to that effect. - * - */ - -/* Danger!!!! The STM32F1x and STM32F2x series actually have - * quite different flash controllers. - * - * What's more scary is that the names of the registers and their - * addresses are the same, but the actual bits and what they do are - * can be very different. - * - * To reduce testing complexity and dangers of regressions, - * a seperate file is used for stm32fx2x. - * - * Sector sizes in kiBytes: - * 1 MiByte part with 4 x 16, 1 x 64, 7 x 128. - * 2 MiByte part with 4 x 16, 1 x 64, 7 x 128, 4 x 16, 1 x 64, 7 x 128. - * 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[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. - * - * STM32F4xx series for reference. - * - * RM0090 - * http://www.st.com/web/en/resource/technical/document/reference_manual/DM00031020.pdf - * - * PM0059 - * www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/ - * PROGRAMMING_MANUAL/CD00233952.pdf - * - * STM32F7xx series for reference. - * - * 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: - * - * RM0008 - Reference manual - * - * RM0042, the Flash programming manual for low-, medium- high-density and - * connectivity line STM32F10x devices - * - * PM0068, the Flash programming manual for XL-density STM32F10x devices. - * - */ - -/* Erase time can be as high as 1000ms, 10x this and it's toast... */ -#define FLASH_ERASE_TIMEOUT 10000 -#define FLASH_WRITE_TIMEOUT 5 - -#define STM32_FLASH_BASE 0x40023c00 -#define STM32_FLASH_ACR 0x40023c00 -#define STM32_FLASH_KEYR 0x40023c04 -#define STM32_FLASH_OPTKEYR 0x40023c08 -#define STM32_FLASH_SR 0x40023c0C -#define STM32_FLASH_CR 0x40023c10 -#define STM32_FLASH_OPTCR 0x40023c14 -#define STM32_FLASH_OPTCR1 0x40023c18 - -/* FLASH_CR register bits */ -#define FLASH_PG (1 << 0) -#define FLASH_SER (1 << 1) -#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) -#define FLASH_PSIZE_32 (2 << 8) -#define FLASH_PSIZE_64 (3 << 8) -/* The sector number encoding is not straight binary for dual bank flash. - * Warning: evaluates the argument multiple times */ -#define FLASH_SNB(a) ((((a) >= 12) ? 0x10 | ((a) - 12) : (a)) << 3) -#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 */ -#define FLASH_PGAERR (1 << 5) /* Programming alignment error */ -#define FLASH_WRPERR (1 << 4) /* Write protection error */ -#define FLASH_OPERR (1 << 1) /* Operation error */ - -#define FLASH_ERROR (FLASH_PGSERR | FLASH_PGPERR | FLASH_PGAERR | FLASH_WRPERR | FLASH_OPERR) - -/* STM32_FLASH_OPTCR register bits */ -#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 - -/* option register unlock key */ -#define OPTKEY1 0x08192A3B -#define OPTKEY2 0x4C5D6E7F - -struct stm32x_options { - uint8_t RDP; - 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; /* 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; -}; - -/* flash bank stm32x 0 0 - */ -FLASH_BANK_COMMAND_HANDLER(stm32x_flash_bank_command) -{ - struct stm32x_flash_bank *stm32x_info; - - if (CMD_ARGC < 6) - return ERROR_COMMAND_SYNTAX_ERROR; - - stm32x_info = malloc(sizeof(struct stm32x_flash_bank)); - bank->driver_priv = stm32x_info; - - stm32x_info->probed = 0; - stm32x_info->user_bank_size = bank->size; - - return ERROR_OK; -} - -static inline int stm32x_get_flash_reg(struct flash_bank *bank, uint32_t reg) -{ - return reg; -} - -static inline int stm32x_get_flash_status(struct flash_bank *bank, uint32_t *status) -{ - struct target *target = bank->target; - return target_read_u32(target, stm32x_get_flash_reg(bank, STM32_FLASH_SR), status); -} - -static int stm32x_wait_status_busy(struct flash_bank *bank, int timeout) -{ - struct target *target = bank->target; - uint32_t status; - int retval = ERROR_OK; - - /* wait for busy to clear */ - for (;;) { - retval = stm32x_get_flash_status(bank, &status); - if (retval != ERROR_OK) - return retval; - LOG_DEBUG("status: 0x%" PRIx32 "", status); - if ((status & FLASH_BSY) == 0) - break; - if (timeout-- <= 0) { - LOG_ERROR("timed out waiting for flash"); - return ERROR_FAIL; - } - alive_sleep(1); - } - - - if (status & FLASH_WRPERR) { - LOG_ERROR("stm32x device protected"); - retval = ERROR_FAIL; - } - - /* Clear but report errors */ - if (status & FLASH_ERROR) { - /* If this operation fails, we ignore it and report the original - * retval - */ - target_write_u32(target, stm32x_get_flash_reg(bank, STM32_FLASH_SR), - status & FLASH_ERROR); - } - return retval; -} - -static int stm32x_unlock_reg(struct target *target) -{ - uint32_t ctrl; - - /* first check if not already unlocked - * otherwise writing on STM32_FLASH_KEYR will fail - */ - int retval = target_read_u32(target, STM32_FLASH_CR, &ctrl); - if (retval != ERROR_OK) - return retval; - - if ((ctrl & FLASH_LOCK) == 0) - return ERROR_OK; - - /* unlock flash registers */ - retval = target_write_u32(target, STM32_FLASH_KEYR, KEY1); - if (retval != ERROR_OK) - return retval; - - retval = target_write_u32(target, STM32_FLASH_KEYR, KEY2); - if (retval != ERROR_OK) - return retval; - - retval = target_read_u32(target, STM32_FLASH_CR, &ctrl); - if (retval != ERROR_OK) - return retval; - - if (ctrl & FLASH_LOCK) { - LOG_ERROR("flash not unlocked STM32_FLASH_CR: %" PRIx32, ctrl); - return ERROR_TARGET_FAILURE; - } - - return ERROR_OK; -} - -static int stm32x_unlock_option_reg(struct target *target) -{ - uint32_t ctrl; - - int retval = target_read_u32(target, STM32_FLASH_OPTCR, &ctrl); - if (retval != ERROR_OK) - return retval; - - if ((ctrl & OPTCR_LOCK) == 0) - return ERROR_OK; - - /* unlock option registers */ - retval = target_write_u32(target, STM32_FLASH_OPTKEYR, OPTKEY1); - if (retval != ERROR_OK) - return retval; - - retval = target_write_u32(target, STM32_FLASH_OPTKEYR, OPTKEY2); - if (retval != ERROR_OK) - return retval; - - retval = target_read_u32(target, STM32_FLASH_OPTCR, &ctrl); - if (retval != ERROR_OK) - return retval; - - if (ctrl & OPTCR_LOCK) { - LOG_ERROR("options not unlocked STM32_FLASH_OPTCR: %" PRIx32, ctrl); - return ERROR_TARGET_FAILURE; - } - - return ERROR_OK; -} - -static int stm32x_read_options(struct flash_bank *bank) -{ - uint32_t optiondata; - struct stm32x_flash_bank *stm32x_info = NULL; - struct target *target = bank->target; - - stm32x_info = bank->driver_priv; - - /* read current option bytes */ - int retval = target_read_u32(target, STM32_FLASH_OPTCR, &optiondata); - if (retval != ERROR_OK) - return retval; - - /* 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_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; - - /* 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) - LOG_INFO("Device Security Bit Set"); - - return ERROR_OK; -} - -static int stm32x_write_options(struct flash_bank *bank) -{ - struct stm32x_flash_bank *stm32x_info = NULL; - struct target *target = bank->target; - uint32_t optiondata, optiondata2; - - stm32x_info = bank->driver_priv; - - int retval = stm32x_unlock_option_reg(target); - if (retval != ERROR_OK) - return retval; - - /* rebuild option data */ - optiondata = stm32x_info->option_bytes.user_options & 0xfc; - optiondata |= stm32x_info->option_bytes.RDP << 8; - optiondata |= (stm32x_info->option_bytes.protection & 0x0fff) << 16; - - 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 || 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; - } - - 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 | OPTCR_START); - if (retval != ERROR_OK) - return retval; - - /* wait for completion */ - retval = stm32x_wait_status_busy(bank, FLASH_ERASE_TIMEOUT); - if (retval != ERROR_OK) - return retval; - - /* relock registers */ - retval = target_write_u32(target, STM32_FLASH_OPTCR, optiondata | OPTCR_LOCK); - if (retval != ERROR_OK) - return retval; - - return ERROR_OK; -} - -static int stm32x_protect_check(struct flash_bank *bank) -{ - struct stm32x_flash_bank *stm32x_info = bank->driver_priv; - - /* read write protection settings */ - int retval = stm32x_read_options(bank); - if (retval != ERROR_OK) { - LOG_DEBUG("unable to read option bytes"); - return retval; - } - - 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; -} - -static int stm32x_erase(struct flash_bank *bank, int first, int last) -{ - struct target *target = bank->target; - int i; - - assert((0 <= first) && (first <= last) && (last < bank->num_sectors)); - - if (bank->target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - int retval; - retval = stm32x_unlock_reg(target); - if (retval != ERROR_OK) - return retval; - - /* - Sector Erase - To erase a sector, follow the procedure below: - 1. Check that no Flash memory operation is ongoing by checking the BSY bit in the - FLASH_SR register - 2. Set the SER bit and select the sector - you wish to erase (SNB) in the FLASH_CR register - 3. Set the STRT bit in the FLASH_CR register - 4. Wait for the BSY bit to be cleared - */ - - for (i = first; i <= last; i++) { - retval = target_write_u32(target, - stm32x_get_flash_reg(bank, STM32_FLASH_CR), FLASH_SER | FLASH_SNB(i) | FLASH_STRT); - if (retval != ERROR_OK) - return retval; - - retval = stm32x_wait_status_busy(bank, FLASH_ERASE_TIMEOUT); - if (retval != ERROR_OK) - return retval; - - bank->sectors[i].is_erased = 1; - } - - retval = target_write_u32(target, stm32x_get_flash_reg(bank, STM32_FLASH_CR), FLASH_LOCK); - if (retval != ERROR_OK) - return retval; - - return ERROR_OK; -} - -static int stm32x_protect(struct flash_bank *bank, int set, int first, int last) -{ - struct target *target = bank->target; - struct stm32x_flash_bank *stm32x_info = bank->driver_priv; - - if (target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - /* read protection settings */ - int retval = stm32x_read_options(bank); - if (retval != ERROR_OK) { - LOG_DEBUG("unable to read option bytes"); - return retval; - } - - 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 - stm32x_info->option_bytes.protection |= (1 << i); - } - - retval = stm32x_write_options(bank); - if (retval != ERROR_OK) - return retval; - - return ERROR_OK; -} - -static int stm32x_write_block(struct flash_bank *bank, const uint8_t *buffer, - uint32_t offset, uint32_t count) -{ - struct target *target = bank->target; - uint32_t buffer_size = 16384; - struct working_area *write_algorithm; - struct working_area *source; - uint32_t address = bank->base + offset; - struct reg_param reg_params[5]; - struct armv7m_algorithm armv7m_info; - int retval = ERROR_OK; - - /* see contrib/loaders/flash/stm32f2x.S for src */ - - static const uint8_t stm32x_flash_write_code[] = { - /* wait_fifo: */ - 0xD0, 0xF8, 0x00, 0x80, /* ldr r8, [r0, #0] */ - 0xB8, 0xF1, 0x00, 0x0F, /* cmp r8, #0 */ - 0x1A, 0xD0, /* beq exit */ - 0x47, 0x68, /* ldr r7, [r0, #4] */ - 0x47, 0x45, /* cmp r7, r8 */ - 0xF7, 0xD0, /* beq wait_fifo */ - - 0xDF, 0xF8, 0x34, 0x60, /* ldr r6, STM32_PROG16 */ - 0x26, 0x61, /* str r6, [r4, #STM32_FLASH_CR_OFFSET] */ - 0x37, 0xF8, 0x02, 0x6B, /* ldrh r6, [r7], #0x02 */ - 0x22, 0xF8, 0x02, 0x6B, /* strh r6, [r2], #0x02 */ - 0xBF, 0xF3, 0x4F, 0x8F, /* dsb sy */ - /* busy: */ - 0xE6, 0x68, /* ldr r6, [r4, #STM32_FLASH_SR_OFFSET] */ - 0x16, 0xF4, 0x80, 0x3F, /* tst r6, #0x10000 */ - 0xFB, 0xD1, /* bne busy */ - 0x16, 0xF0, 0xF0, 0x0F, /* tst r6, #0xf0 */ - 0x07, 0xD1, /* bne error */ - - 0x8F, 0x42, /* cmp r7, r1 */ - 0x28, 0xBF, /* it cs */ - 0x00, 0xF1, 0x08, 0x07, /* addcs r7, r0, #8 */ - 0x47, 0x60, /* str r7, [r0, #4] */ - 0x01, 0x3B, /* subs r3, r3, #1 */ - 0x13, 0xB1, /* cbz r3, exit */ - 0xDF, 0xE7, /* b wait_fifo */ - /* error: */ - 0x00, 0x21, /* movs r1, #0 */ - 0x41, 0x60, /* str r1, [r0, #4] */ - /* exit: */ - 0x30, 0x46, /* mov r0, r6 */ - 0x00, 0xBE, /* bkpt #0x00 */ - - /* : */ - 0x01, 0x01, 0x00, 0x00, /* .word 0x00000101 */ - }; - - if (target_alloc_working_area(target, sizeof(stm32x_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(stm32x_flash_write_code), - stm32x_flash_write_code); - if (retval != ERROR_OK) - return retval; - - /* memory buffer */ - while (target_alloc_working_area_try(target, buffer_size, &source) != ERROR_OK) { - buffer_size /= 2; - if (buffer_size <= 256) { - /* we already allocated the writing code, but failed to get a - * buffer, free the algorithm */ - target_free_working_area(target, write_algorithm); - - 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; - - init_reg_param(®_params[0], "r0", 32, PARAM_IN_OUT); /* buffer start, status (out) */ - init_reg_param(®_params[1], "r1", 32, PARAM_OUT); /* buffer end */ - init_reg_param(®_params[2], "r2", 32, PARAM_OUT); /* target address */ - init_reg_param(®_params[3], "r3", 32, PARAM_OUT); /* count (halfword-16bit) */ - init_reg_param(®_params[4], "r4", 32, PARAM_OUT); /* flash base */ - - buf_set_u32(reg_params[0].value, 0, 32, source->address); - buf_set_u32(reg_params[1].value, 0, 32, source->address + source->size); - buf_set_u32(reg_params[2].value, 0, 32, address); - buf_set_u32(reg_params[3].value, 0, 32, count); - buf_set_u32(reg_params[4].value, 0, 32, STM32_FLASH_BASE); - - retval = target_run_flash_async_algorithm(target, buffer, count, 2, - 0, NULL, - 5, reg_params, - source->address, source->size, - write_algorithm->address, 0, - &armv7m_info); - - if (retval == ERROR_FLASH_OPERATION_FAILED) { - LOG_ERROR("error executing stm32x flash write algorithm"); - - uint32_t error = buf_get_u32(reg_params[0].value, 0, 32) & FLASH_ERROR; - - if (error & FLASH_WRPERR) - LOG_ERROR("flash memory write protected"); - - if (error != 0) { - LOG_ERROR("flash write failed = %08" PRIx32, error); - /* Clear but report errors */ - target_write_u32(target, STM32_FLASH_SR, error); - retval = ERROR_FAIL; - } - } - - target_free_working_area(target, source); - target_free_working_area(target, write_algorithm); - - 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 stm32x_write(struct flash_bank *bank, const uint8_t *buffer, - uint32_t offset, uint32_t count) -{ - struct target *target = bank->target; - uint32_t words_remaining = (count / 2); - uint32_t bytes_remaining = (count & 0x00000001); - uint32_t address = bank->base + offset; - uint32_t bytes_written = 0; - int retval; - - if (bank->target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - if (offset & 0x1) { - LOG_WARNING("offset 0x%" PRIx32 " breaks required 2-byte alignment", offset); - return ERROR_FLASH_DST_BREAKS_ALIGNMENT; - } - - retval = stm32x_unlock_reg(target); - if (retval != ERROR_OK) - return retval; - - /* multiple half words (2-byte) to be programmed? */ - if (words_remaining > 0) { - /* try using a block write */ - retval = stm32x_write_block(bank, buffer, offset, words_remaining); - if (retval != ERROR_OK) { - if (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE) { - /* if block write failed (no sufficient working area), - * we use normal (slow) single dword accesses */ - LOG_WARNING("couldn't use block writes, falling back to single memory accesses"); - } - } else { - buffer += words_remaining * 2; - address += words_remaining * 2; - words_remaining = 0; - } - } - - if ((retval != ERROR_OK) && (retval != ERROR_TARGET_RESOURCE_NOT_AVAILABLE)) - return retval; - - /* - Standard programming - The Flash memory programming sequence is as follows: - 1. Check that no main Flash memory operation is ongoing by checking the BSY bit in the - FLASH_SR register. - 2. Set the PG bit in the FLASH_CR register - 3. Perform the data write operation(s) to the desired memory address (inside main - memory block or OTP area): - – – Half-word access in case of x16 parallelism - – Word access in case of x32 parallelism - – - 4. - Byte access in case of x8 parallelism - Double word access in case of x64 parallelism - Wait for the BSY bit to be cleared - */ - while (words_remaining > 0) { - uint16_t value; - memcpy(&value, buffer + bytes_written, sizeof(uint16_t)); - - retval = target_write_u32(target, stm32x_get_flash_reg(bank, STM32_FLASH_CR), - FLASH_PG | FLASH_PSIZE_16); - if (retval != ERROR_OK) - return retval; - - retval = target_write_u16(target, address, value); - if (retval != ERROR_OK) - return retval; - - retval = stm32x_wait_status_busy(bank, FLASH_WRITE_TIMEOUT); - if (retval != ERROR_OK) - return retval; - - bytes_written += 2; - words_remaining--; - address += 2; - } - - if (bytes_remaining) { - retval = target_write_u32(target, stm32x_get_flash_reg(bank, STM32_FLASH_CR), - FLASH_PG | FLASH_PSIZE_8); - if (retval != ERROR_OK) - return retval; - retval = target_write_u8(target, address, buffer[bytes_written]); - if (retval != ERROR_OK) - return retval; - - retval = stm32x_wait_status_busy(bank, FLASH_WRITE_TIMEOUT); - if (retval != ERROR_OK) - return retval; - } - - return target_write_u32(target, STM32_FLASH_CR, FLASH_LOCK); -} - -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) -{ - /* this checks for a stm32f4x errata issue where a - * stm32f2x DBGMCU_IDCODE is incorrectly returned. - * If the issue is detected target is forced to stm32f4x Rev A. - * Only effects Rev A silicon */ - - struct target *target = bank->target; - uint32_t cpuid; - - /* read stm32 device id register */ - int retval = target_read_u32(target, 0xE0042000, device_id); - if (retval != ERROR_OK) - return retval; - - if ((*device_id & 0xfff) == 0x411) { - /* read CPUID reg to check core type */ - retval = target_read_u32(target, 0xE000ED00, &cpuid); - if (retval != ERROR_OK) - return retval; - - /* check for cortex_m4 */ - if (((cpuid >> 4) & 0xFFF) == 0xC24) { - *device_id &= ~((0xFFFF << 16) | 0xfff); - *device_id |= (0x1000 << 16) | 0x413; - LOG_INFO("stm32f4x errata detected - fixing incorrect MCU_IDCODE"); - } - } - return retval; -} - -static int stm32x_probe(struct flash_bank *bank) -{ - struct target *target = bank->target; - struct stm32x_flash_bank *stm32x_info = bank->driver_priv; - int i; - uint16_t flash_size_in_kb; - uint32_t flash_size_reg = 0x1FFF7A22; - uint16_t max_sector_size_in_kb = 128; - uint16_t max_flash_size_in_kb; - uint32_t device_id; - uint32_t base_address = 0x08000000; - - 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); - if (retval != ERROR_OK) - return retval; - LOG_INFO("device id = 0x%08" PRIx32 "", device_id); - - /* set max flash size depending on family, id taken from AN2606 */ - switch (device_id & 0xfff) { - case 0x411: /* F20x/21x */ - case 0x413: /* F40x/41x */ - max_flash_size_in_kb = 1024; - break; - - case 0x419: /* F42x/43x */ - case 0x434: /* F469/479 */ - stm32x_info->has_extra_options = true; - max_flash_size_in_kb = 2048; - break; - - case 0x423: /* F401xB/C */ - max_flash_size_in_kb = 256; - break; - - case 0x421: /* F446 */ - case 0x431: /* F411 */ - case 0x433: /* F401xD/E */ - case 0x441: /* F412 */ - max_flash_size_in_kb = 512; - break; - - 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; - } - - /* 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; - } - - /* if the user sets the size manually then ignore the probed value - * this allows us to work around devices that have a invalid flash size register value */ - if (stm32x_info->user_bank_size) { - LOG_INFO("ignoring flash probed value, using configured bank size"); - flash_size_in_kb = stm32x_info->user_bank_size / 1024; - } - - LOG_INFO("flash size = %dkbytes", flash_size_in_kb); - - /* did we assign flash size? */ - assert(flash_size_in_kb != 0xffff); - - /* Devices with > 1024 kiByte always are dual-banked */ - if (flash_size_in_kb > 1024) - stm32x_info->has_large_mem = true; - - /* 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 ((flash_size_in_kb > 1024) || (optiondata & OPTCR_DB1M)) { - stm32x_info->has_large_mem = true; - 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); - } - } - - /* 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); - } - } - - /* 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); - bank->sectors = NULL; - } - - 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; - LOG_DEBUG("allocated %d sectors", num_pages); - - if (stm32x_info->has_large_mem) { - /* 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 { - /* 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; -} - -static int stm32x_auto_probe(struct flash_bank *bank) -{ - struct stm32x_flash_bank *stm32x_info = bank->driver_priv; - if (stm32x_info->probed) - return ERROR_OK; - return stm32x_probe(bank); -} - -static int get_stm32x_info(struct flash_bank *bank, char *buf, int buf_size) -{ - uint32_t dbgmcu_idcode; - - /* read stm32 device id register */ - int retval = stm32x_get_device_id(bank, &dbgmcu_idcode); - if (retval != ERROR_OK) - return retval; - - uint16_t device_id = dbgmcu_idcode & 0xfff; - uint16_t rev_id = dbgmcu_idcode >> 16; - const char *device_str; - const char *rev_str = NULL; - - switch (device_id) { - case 0x411: - device_str = "STM32F2xx"; - - switch (rev_id) { - case 0x1000: - rev_str = "A"; - break; - - case 0x2000: - rev_str = "B"; - break; - - case 0x1001: - rev_str = "Z"; - break; - - case 0x2001: - rev_str = "Y"; - break; - - 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; - - case 0x413: - case 0x419: - case 0x434: - device_str = "STM32F4xx"; - - switch (rev_id) { - case 0x1000: - rev_str = "A"; - break; - - case 0x1001: - rev_str = "Z"; - break; - - case 0x1003: - rev_str = "Y"; - break; - - case 0x1007: - rev_str = "1"; - break; - - case 0x2001: - rev_str = "3"; - break; - } - break; - - case 0x421: - device_str = "STM32F446"; - - switch (rev_id) { - case 0x1000: - rev_str = "A"; - break; - } - break; - - case 0x423: - case 0x431: - case 0x433: - case 0x458: - case 0x441: - device_str = "STM32F4xx (Low Power)"; - - switch (rev_id) { - case 0x1000: - rev_str = "A"; - break; - - case 0x1001: - rev_str = "Z"; - break; - } - break; - - case 0x449: - device_str = "STM32F7[4|5]x"; - - switch (rev_id) { - case 0x1000: - rev_str = "A"; - break; - - case 0x1001: - rev_str = "Z"; - break; - } - 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; - } - - if (rev_str != NULL) - snprintf(buf, buf_size, "%s - Rev: %s", device_str, rev_str); - else - snprintf(buf, buf_size, "%s - Rev: unknown (0x%04x)", device_str, rev_id); - - return ERROR_OK; -} - -COMMAND_HANDLER(stm32x_handle_lock_command) -{ - struct target *target = NULL; - struct stm32x_flash_bank *stm32x_info = 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; - - stm32x_info = bank->driver_priv; - target = bank->target; - - if (target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - if (stm32x_read_options(bank) != ERROR_OK) { - command_print(CMD_CTX, "%s failed to read options", bank->driver->name); - return ERROR_OK; - } - - /* set readout protection */ - stm32x_info->option_bytes.RDP = 0; - - if (stm32x_write_options(bank) != ERROR_OK) { - command_print(CMD_CTX, "%s failed to lock device", bank->driver->name); - return ERROR_OK; - } - - command_print(CMD_CTX, "%s locked", bank->driver->name); - - return ERROR_OK; -} - -COMMAND_HANDLER(stm32x_handle_unlock_command) -{ - struct target *target = NULL; - struct stm32x_flash_bank *stm32x_info = 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; - - stm32x_info = bank->driver_priv; - target = bank->target; - - if (target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - if (stm32x_read_options(bank) != ERROR_OK) { - command_print(CMD_CTX, "%s failed to read options", bank->driver->name); - return ERROR_OK; - } - - /* clear readout protection and complementary option bytes - * this will also force a device unlock if set */ - stm32x_info->option_bytes.RDP = 0xAA; - - if (stm32x_write_options(bank) != ERROR_OK) { - command_print(CMD_CTX, "%s failed to unlock device", bank->driver->name); - return ERROR_OK; - } - - command_print(CMD_CTX, "%s unlocked.\n" - "INFO: a reset or power cycle is required " - "for the new settings to take effect.", bank->driver->name); - - return ERROR_OK; -} - -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; - - if (target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - stm32x_info = bank->driver_priv; - - retval = stm32x_unlock_reg(target); - if (retval != ERROR_OK) - return retval; - - /* mass erase flash memory */ - if (stm32x_info->has_large_mem) - flash_mer = FLASH_MER | FLASH_MER1; - else - 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); - if (retval != ERROR_OK) - return retval; - - retval = stm32x_wait_status_busy(bank, 30000); - if (retval != ERROR_OK) - return retval; - - retval = target_write_u32(target, stm32x_get_flash_reg(bank, STM32_FLASH_CR), FLASH_LOCK); - if (retval != ERROR_OK) - return retval; - - return ERROR_OK; -} - -COMMAND_HANDLER(stm32x_handle_mass_erase_command) -{ - int i; - - if (CMD_ARGC < 1) { - command_print(CMD_CTX, "stm32x mass_erase "); - 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 = stm32x_mass_erase(bank); - if (retval == ERROR_OK) { - /* set all sectors as erased */ - for (i = 0; i < bank->num_sectors; i++) - bank->sectors[i].is_erased = 1; - - command_print(CMD_CTX, "stm32x mass erase complete"); - } else { - command_print(CMD_CTX, "stm32x mass erase failed"); - } - - 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", - .handler = stm32x_handle_lock_command, - .mode = COMMAND_EXEC, - .usage = "bank_id", - .help = "Lock entire flash device.", - }, - { - .name = "unlock", - .handler = stm32x_handle_unlock_command, - .mode = COMMAND_EXEC, - .usage = "bank_id", - .help = "Unlock entire protected flash device.", - }, - { - .name = "mass_erase", - .handler = stm32x_handle_mass_erase_command, - .mode = COMMAND_EXEC, - .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 -}; - -static const struct command_registration stm32x_command_handlers[] = { - { - .name = "stm32f2x", - .mode = COMMAND_ANY, - .help = "stm32f2x flash command group", - .usage = "", - .chain = stm32x_exec_command_handlers, - }, - COMMAND_REGISTRATION_DONE -}; - -struct flash_driver stm32f2x_flash = { - .name = "stm32f2x", - .commands = stm32x_command_handlers, - .flash_bank_command = stm32x_flash_bank_command, - .erase = stm32x_erase, - .protect = stm32x_protect, - .write = stm32x_write, - .read = default_flash_read, - .probe = stm32x_probe, - .auto_probe = stm32x_auto_probe, - .erase_check = default_flash_blank_check, - .protect_check = stm32x_protect_check, - .info = get_stm32x_info, -}; diff --git a/src/flash/nor/stm32l4x.c b/src/flash/nor/stm32l4x.c deleted file mode 100644 index 129b281e1..000000000 --- a/src/flash/nor/stm32l4x.c +++ /dev/null @@ -1,930 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2015 by Uwe Bonnes * - * bon@elektron.ikp.physik.tu-darmstadt.de * - * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "imp.h" -#include -#include -#include - -/* STM32L4xxx series for reference. - * - * RM0351 - * http://www.st.com/st-web-ui/static/active/en/resource/technical/document/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 - * - * - * 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. - * Both STM32 banks are treated as one OpenOCD bank, as other STM32 devices - * handlers do! - * - */ - -/* Erase time can be as high as 25ms, 10x this and assume it's toast... */ - -#define FLASH_ERASE_TIMEOUT 250 - -#define STM32_FLASH_BASE 0x40022000 -#define STM32_FLASH_ACR 0x40022000 -#define STM32_FLASH_KEYR 0x40022008 -#define STM32_FLASH_OPTKEYR 0x4002200c -#define STM32_FLASH_SR 0x40022010 -#define STM32_FLASH_CR 0x40022014 -#define STM32_FLASH_OPTR 0x40022020 -#define STM32_FLASH_WRP1AR 0x4002202c -#define STM32_FLASH_WRP2AR 0x40022030 -#define STM32_FLASH_WRP1BR 0x4002204c -#define STM32_FLASH_WRP2BR 0x40022050 - -/* FLASH_CR register bits */ - -#define FLASH_PG (1 << 0) -#define FLASH_PER (1 << 1) -#define FLASH_MER1 (1 << 2) -#define FLASH_PAGE_SHIFT 3 -#define FLASH_CR_BKER (1 << 11) -#define FLASH_MER2 (1 << 15) -#define FLASH_STRT (1 << 16) -#define FLASH_EOPIE (1 << 24) -#define FLASH_ERRIE (1 << 25) -#define FLASH_OPTLOCK (1 << 30) -#define FLASH_LOCK (1 << 31) - -/* FLASH_SR register bits */ - -#define FLASH_BSY (1 << 16) -/* Fast programming not used => related errors not used*/ -#define FLASH_PGSERR (1 << 7) /* Programming sequence error */ -#define FLASH_SIZERR (1 << 6) /* Size error */ -#define FLASH_PGAERR (1 << 5) /* Programming alignment error */ -#define FLASH_WRPERR (1 << 4) /* Write protection error */ -#define FLASH_PROGERR (1 << 3) /* Programming error */ -#define FLASH_OPERR (1 << 1) /* Operation error */ -#define FLASH_EOP (1 << 0) /* End of operation */ - -#define FLASH_ERROR (FLASH_PGSERR | FLASH_PGSERR | FLASH_PGAERR | FLASH_WRPERR | FLASH_OPERR) - -/* STM32_FLASH_OBR bit definitions (reading) */ - -#define OPT_DUALBANK 21 /* dual flash bank only */ - -/* register unlock keys */ - -#define KEY1 0x45670123 -#define KEY2 0xCDEF89AB - -/* option register unlock key */ -#define OPTKEY1 0x08192A3B -#define OPTKEY2 0x4C5D6E7F - - -/* other registers */ -#define DBGMCU_IDCODE 0xE0042000 -#define FLASH_SIZE_REG 0x1FFF75E0 - -struct stm32l4_options { - uint8_t RDP; - uint16_t bank_b_start; - uint8_t user_options; - uint8_t wpr1a_start; - uint8_t wpr1a_end; - uint8_t wpr1b_start; - uint8_t wpr1b_end; - uint8_t wpr2a_start; - uint8_t wpr2a_end; - uint8_t wpr2b_start; - uint8_t wpr2b_end; - /* Fixme: Handle PCROP */ -}; - -struct stm32l4_flash_bank { - struct stm32l4_options option_bytes; - int probed; -}; - -/* flash bank stm32l4x 0 0 - */ -FLASH_BANK_COMMAND_HANDLER(stm32l4_flash_bank_command) -{ - struct stm32l4_flash_bank *stm32l4_info; - - if (CMD_ARGC < 6) - return ERROR_COMMAND_SYNTAX_ERROR; - - stm32l4_info = malloc(sizeof(struct stm32l4_flash_bank)); - if (!stm32l4_info) - return ERROR_FAIL; /* Checkme: What better error to use?*/ - bank->driver_priv = stm32l4_info; - - stm32l4_info->probed = 0; - - return ERROR_OK; -} - -static inline int stm32l4_get_flash_reg(struct flash_bank *bank, uint32_t reg) -{ - return reg; -} - -static inline int stm32l4_get_flash_status(struct flash_bank *bank, uint32_t *status) -{ - struct target *target = bank->target; - return target_read_u32( - target, stm32l4_get_flash_reg(bank, STM32_FLASH_SR), status); -} - -static int stm32l4_wait_status_busy(struct flash_bank *bank, int timeout) -{ - struct target *target = bank->target; - uint32_t status; - int retval = ERROR_OK; - - /* wait for busy to clear */ - for (;;) { - retval = stm32l4_get_flash_status(bank, &status); - if (retval != ERROR_OK) - return retval; - LOG_DEBUG("status: 0x%" PRIx32 "", status); - if ((status & FLASH_BSY) == 0) - break; - if (timeout-- <= 0) { - LOG_ERROR("timed out waiting for flash"); - return ERROR_FAIL; - } - alive_sleep(1); - } - - - if (status & FLASH_WRPERR) { - LOG_ERROR("stm32x device protected"); - retval = ERROR_FAIL; - } - - /* Clear but report errors */ - if (status & FLASH_ERROR) { - /* If this operation fails, we ignore it and report the original - * retval - */ - target_write_u32(target, stm32l4_get_flash_reg(bank, STM32_FLASH_SR), - status & FLASH_ERROR); - } - return retval; -} - -static int stm32l4_unlock_reg(struct target *target) -{ - uint32_t ctrl; - - /* first check if not already unlocked - * otherwise writing on STM32_FLASH_KEYR will fail - */ - int retval = target_read_u32(target, STM32_FLASH_CR, &ctrl); - if (retval != ERROR_OK) - return retval; - - if ((ctrl & FLASH_LOCK) == 0) - return ERROR_OK; - - /* unlock flash registers */ - retval = target_write_u32(target, STM32_FLASH_KEYR, KEY1); - if (retval != ERROR_OK) - return retval; - - retval = target_write_u32(target, STM32_FLASH_KEYR, KEY2); - if (retval != ERROR_OK) - return retval; - - retval = target_read_u32(target, STM32_FLASH_CR, &ctrl); - if (retval != ERROR_OK) - return retval; - - if (ctrl & FLASH_LOCK) { - LOG_ERROR("flash not unlocked STM32_FLASH_CR: %" PRIx32, ctrl); - return ERROR_TARGET_FAILURE; - } - - return ERROR_OK; -} - -static int stm32l4_unlock_option_reg(struct target *target) -{ - uint32_t ctrl; - - int retval = target_read_u32(target, STM32_FLASH_CR, &ctrl); - if (retval != ERROR_OK) - return retval; - - if ((ctrl & FLASH_OPTLOCK) == 0) - return ERROR_OK; - - /* unlock option registers */ - retval = target_write_u32(target, STM32_FLASH_OPTKEYR, OPTKEY1); - if (retval != ERROR_OK) - return retval; - - retval = target_write_u32(target, STM32_FLASH_OPTKEYR, OPTKEY2); - if (retval != ERROR_OK) - return retval; - - retval = target_read_u32(target, STM32_FLASH_CR, &ctrl); - if (retval != ERROR_OK) - return retval; - - if (ctrl & FLASH_OPTLOCK) { - LOG_ERROR("options not unlocked STM32_FLASH_CR: %" PRIx32, ctrl); - return ERROR_TARGET_FAILURE; - } - - return ERROR_OK; -} - -static int stm32l4_read_options(struct flash_bank *bank) -{ - uint32_t optiondata; - struct stm32l4_flash_bank *stm32l4_info = NULL; - struct target *target = bank->target; - - stm32l4_info = bank->driver_priv; - - /* read current option bytes */ - int retval = target_read_u32(target, STM32_FLASH_OPTR, &optiondata); - if (retval != ERROR_OK) - return retval; - - stm32l4_info->option_bytes.user_options = (optiondata >> 8) & 0x3ffff; - stm32l4_info->option_bytes.RDP = optiondata & 0xff; - - retval = target_read_u32(target, STM32_FLASH_WRP1AR, &optiondata); - if (retval != ERROR_OK) - return retval; - stm32l4_info->option_bytes.wpr1a_start = optiondata & 0xff; - stm32l4_info->option_bytes.wpr1a_end = (optiondata >> 16) & 0xff; - - retval = target_read_u32(target, STM32_FLASH_WRP2AR, &optiondata); - if (retval != ERROR_OK) - return retval; - stm32l4_info->option_bytes.wpr2a_start = optiondata & 0xff; - stm32l4_info->option_bytes.wpr2a_end = (optiondata >> 16) & 0xff; - - retval = target_read_u32(target, STM32_FLASH_WRP1BR, &optiondata); - if (retval != ERROR_OK) - return retval; - stm32l4_info->option_bytes.wpr1b_start = optiondata & 0xff; - stm32l4_info->option_bytes.wpr1b_end = (optiondata >> 16) & 0xff; - - retval = target_read_u32(target, STM32_FLASH_WRP2BR, &optiondata); - if (retval != ERROR_OK) - return retval; - stm32l4_info->option_bytes.wpr2b_start = optiondata & 0xff; - stm32l4_info->option_bytes.wpr2b_end = (optiondata >> 16) & 0xff; - - if (stm32l4_info->option_bytes.RDP != 0xAA) - LOG_INFO("Device Security Bit Set"); - - return ERROR_OK; -} - -static int stm32l4_write_options(struct flash_bank *bank) -{ - struct stm32l4_flash_bank *stm32l4_info = NULL; - struct target *target = bank->target; - uint32_t optiondata; - - stm32l4_info = bank->driver_priv; - - (void) optiondata; - (void) stm32l4_info; - - int retval = stm32l4_unlock_option_reg(target); - if (retval != ERROR_OK) - return retval; - /* FIXME: Implement Option writing!*/ - return ERROR_OK; -} - -static int stm32l4_protect_check(struct flash_bank *bank) -{ - struct stm32l4_flash_bank *stm32l4_info = bank->driver_priv; - - /* read write protection settings */ - int retval = stm32l4_read_options(bank); - if (retval != ERROR_OK) { - LOG_DEBUG("unable to read option bytes"); - return retval; - } - - for (int i = 0; i < bank->num_sectors; i++) { - if (i < stm32l4_info->option_bytes.bank_b_start) { - if (((i >= stm32l4_info->option_bytes.wpr1a_start) && - (i <= stm32l4_info->option_bytes.wpr1a_end)) || - ((i >= stm32l4_info->option_bytes.wpr2a_start) && - (i <= stm32l4_info->option_bytes.wpr2a_end))) - bank->sectors[i].is_protected = 1; - else - bank->sectors[i].is_protected = 0; - } else { - uint8_t snb; - snb = i - stm32l4_info->option_bytes.bank_b_start + 256; - if (((snb >= stm32l4_info->option_bytes.wpr1b_start) && - (snb <= stm32l4_info->option_bytes.wpr1b_end)) || - ((snb >= stm32l4_info->option_bytes.wpr2b_start) && - (snb <= stm32l4_info->option_bytes.wpr2b_end))) - bank->sectors[i].is_protected = 1; - else - bank->sectors[i].is_protected = 0; - } - } - return ERROR_OK; -} - -static int stm32l4_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); - - if (bank->target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - int retval; - retval = stm32l4_unlock_reg(target); - if (retval != ERROR_OK) - return retval; - - /* - Sector Erase - To erase a sector, follow the procedure below: - 1. Check that no Flash memory operation is ongoing by - checking the BSY bit in the FLASH_SR register - 2. Set the PER bit and select the page and bank - you wish to erase in the FLASH_CR register - 3. Set the STRT bit in the FLASH_CR register - 4. Wait for the BSY bit to be cleared - */ - struct stm32l4_flash_bank *stm32l4_info = bank->driver_priv; - - for (i = first; i <= last; i++) { - uint32_t erase_flags; - erase_flags = FLASH_PER | FLASH_STRT; - - if (i >= stm32l4_info->option_bytes.bank_b_start) { - uint8_t snb; - snb = (i - stm32l4_info->option_bytes.bank_b_start) + 256; - erase_flags |= snb << FLASH_PAGE_SHIFT | FLASH_CR_BKER; - } else - erase_flags |= i << FLASH_PAGE_SHIFT; - retval = target_write_u32(target, - stm32l4_get_flash_reg(bank, STM32_FLASH_CR), erase_flags); - if (retval != ERROR_OK) - return retval; - - retval = stm32l4_wait_status_busy(bank, FLASH_ERASE_TIMEOUT); - if (retval != ERROR_OK) - return retval; - - bank->sectors[i].is_erased = 1; - } - - retval = target_write_u32( - target, stm32l4_get_flash_reg(bank, STM32_FLASH_CR), FLASH_LOCK); - if (retval != ERROR_OK) - return retval; - - return ERROR_OK; -} - -static int stm32l4_protect(struct flash_bank *bank, int set, int first, int last) -{ - struct target *target = bank->target; - struct stm32l4_flash_bank *stm32l4_info = bank->driver_priv; - - if (target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - /* read protection settings */ - int retval = stm32l4_read_options(bank); - if (retval != ERROR_OK) { - LOG_DEBUG("unable to read option bytes"); - return retval; - } - - (void)stm32l4_info; - /* FIXME: Write First and last in a valid WRPxx_start/end combo*/ - retval = stm32l4_write_options(bank); - if (retval != ERROR_OK) - return retval; - - return ERROR_OK; -} - -/* Count is in halfwords */ -static int stm32l4_write_block(struct flash_bank *bank, const uint8_t *buffer, - uint32_t offset, uint32_t count) -{ - struct target *target = bank->target; - uint32_t buffer_size = 16384; - struct working_area *write_algorithm; - struct working_area *source; - uint32_t address = bank->base + offset; - struct reg_param reg_params[5]; - struct armv7m_algorithm armv7m_info; - int retval = ERROR_OK; - - /* See contrib/loaders/flash/stm32l4x.S for source and - * hints how to generate the data! - */ - - static const uint8_t stm32l4_flash_write_code[] = { - 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), - stm32l4_flash_write_code); - if (retval != ERROR_OK) - return retval; - - /* memory buffer */ - while (target_alloc_working_area_try(target, buffer_size, &source) != - ERROR_OK) { - buffer_size /= 2; - if (buffer_size <= 256) { - /* we already allocated the writing code, but failed to get a - * buffer, free the algorithm */ - target_free_working_area(target, write_algorithm); - - 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; - - init_reg_param(®_params[0], "r0", 32, PARAM_IN_OUT); /* buffer start, status (out) */ - init_reg_param(®_params[1], "r1", 32, PARAM_OUT); /* buffer end */ - init_reg_param(®_params[2], "r2", 32, PARAM_OUT); /* target address */ - init_reg_param(®_params[3], "r3", 32, PARAM_OUT); /* count (double word-64bit) */ - init_reg_param(®_params[4], "r4", 32, PARAM_OUT); /* flash base */ - - buf_set_u32(reg_params[0].value, 0, 32, source->address); - buf_set_u32(reg_params[1].value, 0, 32, source->address + source->size); - buf_set_u32(reg_params[2].value, 0, 32, address); - buf_set_u32(reg_params[3].value, 0, 32, count / 4); - buf_set_u32(reg_params[4].value, 0, 32, STM32_FLASH_BASE); - - retval = target_run_flash_async_algorithm(target, buffer, count, 2, - 0, NULL, - 5, reg_params, - source->address, source->size, - write_algorithm->address, 0, - &armv7m_info); - - if (retval == ERROR_FLASH_OPERATION_FAILED) { - LOG_ERROR("error executing stm32l4 flash write algorithm"); - - uint32_t error = buf_get_u32(reg_params[0].value, 0, 32) & FLASH_ERROR; - - if (error & FLASH_WRPERR) - LOG_ERROR("flash memory write protected"); - - if (error != 0) { - LOG_ERROR("flash write failed = %08" PRIx32, error); - /* Clear but report errors */ - target_write_u32(target, STM32_FLASH_SR, error); - retval = ERROR_FAIL; - } - } - - target_free_working_area(target, source); - target_free_working_area(target, write_algorithm); - - 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 stm32l4_write(struct flash_bank *bank, const uint8_t *buffer, - uint32_t offset, uint32_t count) -{ - struct target *target = bank->target; - int retval; - - if (bank->target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - if (offset & 0x7) { - LOG_WARNING("offset 0x%" PRIx32 " breaks required 8-byte alignment", - offset); - return ERROR_FLASH_DST_BREAKS_ALIGNMENT; - } - - if (count & 0x7) { - LOG_WARNING("Padding %d bytes to keep 8-byte write size", - count & 7); - count = (count + 7) & ~7; - /* This pads the write chunk with random bytes by overrunning the - * write buffer. Padding with the erased pattern 0xff is purely - * cosmetical, as 8-byte flash words are ECC secured and the first - * write will program the ECC bits. A second write would need - * to reprogramm these ECC bits. - * But this can only be done after erase! - */ - } - - retval = stm32l4_unlock_reg(target); - if (retval != ERROR_OK) - return retval; - - /* Only full double words (8-byte) can be programmed*/ - retval = stm32l4_write_block(bank, buffer, offset, count / 2); - if (retval != ERROR_OK) { - LOG_WARNING("block write failed"); - return retval; - } - - LOG_WARNING("block write succeeded"); - return target_write_u32(target, STM32_FLASH_CR, FLASH_LOCK); -} - -static int stm32l4_probe(struct flash_bank *bank) -{ - struct target *target = bank->target; - 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; - - stm32l4_info->probed = 0; - - /* read stm32 device id register */ - int retval = target_read_u32(target, DBGMCU_IDCODE, &device_id); - if (retval != ERROR_OK) - return retval; - LOG_INFO("device id = 0x%08" PRIx32 "", device_id); - - /* set max flash size depending on family */ - switch (device_id & 0xfff) { - case 0x415: - max_flash_size_in_kb = 1024; - break; - default: - LOG_WARNING("Cannot identify target as a STM32L4 family."); - return ERROR_FAIL; - } - - /* 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); - - /* only devices with < 1024 kiB may be set to single bank dual banks */ - if ((flash_size_in_kb == 1024) || !(options & OPT_DUALBANK)) - stm32l4_info->option_bytes.bank_b_start = 256; - else - stm32l4_info->option_bytes.bank_b_start = flash_size_in_kb << 9; - - /* did we assign flash size? */ - assert((flash_size_in_kb != 0xffff) && flash_size_in_kb); - - /* calculate numbers of pages */ - int num_pages = flash_size_in_kb / 2; - - /* check that calculation result makes sense */ - assert(num_pages > 0); - - if (bank->sectors) { - free(bank->sectors); - bank->sectors = NULL; - } - - bank->base = base_address; - bank->size = num_pages * (1 << 11); - bank->num_sectors = num_pages; - bank->sectors = malloc(sizeof(struct flash_sector) * num_pages); - if (!bank->sectors) - return ERROR_FAIL; /* Checkme: What better error to use?*/ - - for (i = 0; i < num_pages; i++) { - bank->sectors[i].offset = i << 11; - bank->sectors[i].size = 1 << 11; - bank->sectors[i].is_erased = -1; - bank->sectors[i].is_protected = 1; - } - - stm32l4_info->probed = 1; - - return ERROR_OK; -} - -static int stm32l4_auto_probe(struct flash_bank *bank) -{ - struct stm32l4_flash_bank *stm32l4_info = bank->driver_priv; - if (stm32l4_info->probed) - return ERROR_OK; - return stm32l4_probe(bank); -} - -static int get_stm32l4_info(struct flash_bank *bank, char *buf, int buf_size) -{ - struct target *target = bank->target; - uint32_t dbgmcu_idcode; - - /* read stm32 device id register */ - int retval = target_read_u32(target, DBGMCU_IDCODE, &dbgmcu_idcode); - if (retval != ERROR_OK) - return retval; - - uint16_t device_id = dbgmcu_idcode & 0xffff; - uint8_t rev_id = dbgmcu_idcode >> 28; - uint8_t rev_minor = 0; - int i; - - for (i = 16; i < 28; i++) { - if (dbgmcu_idcode & (1 << i)) - rev_minor++; - else - break; - } - - const char *device_str; - - switch (device_id) { - case 0x6415: - device_str = "STM32L4xx"; - break; - - default: - snprintf(buf, buf_size, "Cannot identify target as a STM32L4\n"); - return ERROR_FAIL; - } - - snprintf(buf, buf_size, "%s - Rev: %1d.%02d", - device_str, rev_id, rev_minor); - - return ERROR_OK; -} - -COMMAND_HANDLER(stm32l4_handle_lock_command) -{ - struct target *target = NULL; - struct stm32l4_flash_bank *stm32l4_info = 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; - - stm32l4_info = bank->driver_priv; - target = bank->target; - - if (target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - if (stm32l4_read_options(bank) != ERROR_OK) { - command_print(CMD_CTX, "%s failed to read options", - bank->driver->name); - return ERROR_OK; - } - - /* set readout protection */ - stm32l4_info->option_bytes.RDP = 0; - - if (stm32l4_write_options(bank) != ERROR_OK) { - command_print(CMD_CTX, "%s failed to lock device", bank->driver->name); - return ERROR_OK; - } - - command_print(CMD_CTX, "%s locked", bank->driver->name); - - return ERROR_OK; -} - -COMMAND_HANDLER(stm32l4_handle_unlock_command) -{ - struct target *target = NULL; - struct stm32l4_flash_bank *stm32l4_info = 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; - - stm32l4_info = bank->driver_priv; - target = bank->target; - - if (target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - if (stm32l4_read_options(bank) != ERROR_OK) { - command_print(CMD_CTX, "%s failed to read options", bank->driver->name); - return ERROR_OK; - } - - /* clear readout protection and complementary option bytes - * this will also force a device unlock if set */ - stm32l4_info->option_bytes.RDP = 0xAA; - - if (stm32l4_write_options(bank) != ERROR_OK) { - command_print(CMD_CTX, "%s failed to unlock device", - bank->driver->name); - return ERROR_OK; - } - - command_print(CMD_CTX, "%s unlocked.\n" - "INFO: a reset or power cycle is required " - "for the new settings to take effect.", bank->driver->name); - - return ERROR_OK; -} - -static int stm32l4_mass_erase(struct flash_bank *bank, uint32_t action) -{ - int retval; - struct target *target = bank->target; - - if (target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - retval = stm32l4_unlock_reg(target); - if (retval != ERROR_OK) - return retval; - - /* mass erase flash memory */ - retval = target_write_u32( - target, stm32l4_get_flash_reg(bank, STM32_FLASH_CR), action); - if (retval != ERROR_OK) - return retval; - retval = target_write_u32( - target, stm32l4_get_flash_reg(bank, STM32_FLASH_CR), - action | FLASH_STRT); - if (retval != ERROR_OK) - return retval; - - retval = stm32l4_wait_status_busy(bank, FLASH_ERASE_TIMEOUT); - if (retval != ERROR_OK) - return retval; - - retval = target_write_u32( - target, stm32l4_get_flash_reg(bank, STM32_FLASH_CR), FLASH_LOCK); - if (retval != ERROR_OK) - return retval; - - return ERROR_OK; -} - -COMMAND_HANDLER(stm32l4_handle_mass_erase_command) -{ - int i; - uint32_t action; - - if (CMD_ARGC < 1) { - command_print(CMD_CTX, "stm32x mass_erase "); - 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; - - action = FLASH_MER1 | FLASH_MER2; - retval = stm32l4_mass_erase(bank, action); - if (retval == ERROR_OK) { - /* set all sectors as erased */ - for (i = 0; i < bank->num_sectors; i++) - bank->sectors[i].is_erased = 1; - - command_print(CMD_CTX, "stm32x mass erase complete"); - } else { - command_print(CMD_CTX, "stm32x mass erase failed"); - } - - return retval; -} - -static const struct command_registration stm32l4_exec_command_handlers[] = { - { - .name = "lock", - .handler = stm32l4_handle_lock_command, - .mode = COMMAND_EXEC, - .usage = "bank_id", - .help = "Lock entire flash device.", - }, - { - .name = "unlock", - .handler = stm32l4_handle_unlock_command, - .mode = COMMAND_EXEC, - .usage = "bank_id", - .help = "Unlock entire protected flash device.", - }, - { - .name = "mass_erase", - .handler = stm32l4_handle_mass_erase_command, - .mode = COMMAND_EXEC, - .usage = "bank_id", - .help = "Erase entire flash device.", - }, - COMMAND_REGISTRATION_DONE -}; - -static const struct command_registration stm32l4_command_handlers[] = { - { - .name = "stm32l4x", - .mode = COMMAND_ANY, - .help = "stm32l4x flash command group", - .usage = "", - .chain = stm32l4_exec_command_handlers, - }, - COMMAND_REGISTRATION_DONE -}; - -struct flash_driver stm32l4x_flash = { - .name = "stm32l4x", - .commands = stm32l4_command_handlers, - .flash_bank_command = stm32l4_flash_bank_command, - .erase = stm32l4_erase, - .protect = stm32l4_protect, - .write = stm32l4_write, - .read = default_flash_read, - .probe = stm32l4_probe, - .auto_probe = stm32l4_auto_probe, - .erase_check = default_flash_blank_check, - .protect_check = stm32l4_protect_check, - .info = get_stm32l4_info, -}; diff --git a/src/flash/nor/stm32lx.c b/src/flash/nor/stm32lx.c deleted file mode 100644 index 376c0f839..000000000 --- a/src/flash/nor/stm32lx.c +++ /dev/null @@ -1,1421 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * Copyright (C) 2008 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * Copyright (C) 2011 by Clement Burin des Roziers * - * clement.burin-des-roziers@hikob.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "imp.h" -#include -#include -#include -#include - -/* stm32lx flash register locations */ - -#define FLASH_ACR 0x00 -#define FLASH_PECR 0x04 -#define FLASH_PDKEYR 0x08 -#define FLASH_PEKEYR 0x0C -#define FLASH_PRGKEYR 0x10 -#define FLASH_OPTKEYR 0x14 -#define FLASH_SR 0x18 -#define FLASH_OBR 0x1C -#define FLASH_WRPR 0x20 - -/* FLASH_ACR bites */ -#define FLASH_ACR__LATENCY (1<<0) -#define FLASH_ACR__PRFTEN (1<<1) -#define FLASH_ACR__ACC64 (1<<2) -#define FLASH_ACR__SLEEP_PD (1<<3) -#define FLASH_ACR__RUN_PD (1<<4) - -/* FLASH_PECR bits */ -#define FLASH_PECR__PELOCK (1<<0) -#define FLASH_PECR__PRGLOCK (1<<1) -#define FLASH_PECR__OPTLOCK (1<<2) -#define FLASH_PECR__PROG (1<<3) -#define FLASH_PECR__DATA (1<<4) -#define FLASH_PECR__FTDW (1<<8) -#define FLASH_PECR__ERASE (1<<9) -#define FLASH_PECR__FPRG (1<<10) -#define FLASH_PECR__EOPIE (1<<16) -#define FLASH_PECR__ERRIE (1<<17) -#define FLASH_PECR__OBL_LAUNCH (1<<18) - -/* FLASH_SR bits */ -#define FLASH_SR__BSY (1<<0) -#define FLASH_SR__EOP (1<<1) -#define FLASH_SR__ENDHV (1<<2) -#define FLASH_SR__READY (1<<3) -#define FLASH_SR__WRPERR (1<<8) -#define FLASH_SR__PGAERR (1<<9) -#define FLASH_SR__SIZERR (1<<10) -#define FLASH_SR__OPTVERR (1<<11) - -/* Unlock keys */ -#define PEKEY1 0x89ABCDEF -#define PEKEY2 0x02030405 -#define PRGKEY1 0x8C9DAEBF -#define PRGKEY2 0x13141516 -#define OPTKEY1 0xFBEAD9C8 -#define OPTKEY2 0x24252627 - -/* other registers */ -#define DBGMCU_IDCODE 0xE0042000 -#define DBGMCU_IDCODE_L0 0x40015800 - -/* Constants */ -#define FLASH_SECTOR_SIZE 4096 -#define FLASH_BANK0_ADDRESS 0x08000000 - -/* option bytes */ -#define OPTION_BYTES_ADDRESS 0x1FF80000 - -#define OPTION_BYTE_0_PR1 0xFFFF0000 -#define OPTION_BYTE_0_PR0 0xFF5500AA - -static int stm32lx_unlock_program_memory(struct flash_bank *bank); -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); - -struct stm32lx_rev { - uint16_t rev; - const char *str; -}; - -struct stm32lx_part_info { - uint16_t id; - const char *device_str; - const struct stm32lx_rev *revs; - size_t num_revs; - unsigned int page_size; - unsigned int pages_per_sector; - uint16_t max_flash_size_kb; - uint16_t first_bank_size_kb; /* used when has_dual_banks is true */ - bool has_dual_banks; - - uint32_t flash_base; /* Flash controller registers location */ - uint32_t fsize_base; /* Location of FSIZE register */ -}; - -struct stm32lx_flash_bank { - int probed; - uint32_t idcode; - uint32_t user_bank_size; - uint32_t flash_base; - - const 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" }, { 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" }, -}; -static const struct stm32lx_rev stm32_429_revs[] = { - { 0x1000, "A" }, { 0x1018, "Z" }, -}; -static const struct stm32lx_rev stm32_436_revs[] = { - { 0x1000, "A" }, { 0x1008, "Z" }, { 0x1018, "Y" }, -}; -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[] = { - { - .id = 0x416, - .revs = stm32_416_revs, - .num_revs = ARRAY_SIZE(stm32_416_revs), - .device_str = "STM32L1xx (Cat.1 - Low/Medium Density)", - .page_size = 256, - .pages_per_sector = 16, - .max_flash_size_kb = 128, - .has_dual_banks = false, - .flash_base = 0x40023C00, - .fsize_base = 0x1FF8004C, - }, - { - .id = 0x417, - .revs = stm32_417_revs, - .num_revs = ARRAY_SIZE(stm32_417_revs), - .device_str = "STM32L0xx (Cat. 3)", - .page_size = 128, - .pages_per_sector = 32, - .max_flash_size_kb = 64, - .has_dual_banks = false, - .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, - .num_revs = ARRAY_SIZE(stm32_427_revs), - .device_str = "STM32L1xx (Cat.3 - Medium+ Density)", - .page_size = 256, - .pages_per_sector = 16, - .max_flash_size_kb = 256, - .has_dual_banks = false, - .flash_base = 0x40023C00, - .fsize_base = 0x1FF800CC, - }, - { - .id = 0x429, - .revs = stm32_429_revs, - .num_revs = ARRAY_SIZE(stm32_429_revs), - .device_str = "STM32L1xx (Cat.2)", - .page_size = 256, - .pages_per_sector = 16, - .max_flash_size_kb = 128, - .has_dual_banks = false, - .flash_base = 0x40023C00, - .fsize_base = 0x1FF8004C, - }, - { - .id = 0x436, - .revs = stm32_436_revs, - .num_revs = ARRAY_SIZE(stm32_436_revs), - .device_str = "STM32L1xx (Cat.4/Cat.3 - Medium+/High Density)", - .page_size = 256, - .pages_per_sector = 16, - .max_flash_size_kb = 384, - .first_bank_size_kb = 192, - .has_dual_banks = true, - .flash_base = 0x40023C00, - .fsize_base = 0x1FF800CC, - }, - { - .id = 0x437, - .revs = stm32_437_revs, - .num_revs = ARRAY_SIZE(stm32_437_revs), - .device_str = "STM32L1xx (Cat.5/Cat.6)", - .page_size = 256, - .pages_per_sector = 16, - .max_flash_size_kb = 512, - .first_bank_size_kb = 256, - .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 = 128, - .has_dual_banks = true, - .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 - */ -FLASH_BANK_COMMAND_HANDLER(stm32lx_flash_bank_command) -{ - struct stm32lx_flash_bank *stm32lx_info; - if (CMD_ARGC < 6) - return ERROR_COMMAND_SYNTAX_ERROR; - - /* Create the bank structure */ - stm32lx_info = calloc(1, sizeof(*stm32lx_info)); - - /* Check allocation */ - if (stm32lx_info == NULL) { - LOG_ERROR("failed to allocate bank structure"); - return ERROR_FAIL; - } - - bank->driver_priv = stm32lx_info; - - stm32lx_info->probed = 0; - stm32lx_info->user_bank_size = bank->size; - - /* the stm32l erased value is 0x00 */ - bank->default_padded_value = 0x00; - - return ERROR_OK; -} - -COMMAND_HANDLER(stm32lx_handle_mass_erase_command) -{ - int i; - - 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_mass_erase(bank); - if (retval == ERROR_OK) { - /* set all sectors as erased */ - for (i = 0; i < bank->num_sectors; i++) - bank->sectors[i].is_erased = 1; - - command_print(CMD_CTX, "stm32lx mass erase complete"); - } else { - command_print(CMD_CTX, "stm32lx mass erase failed"); - } - - 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; - struct target *target = bank->target; - struct stm32lx_flash_bank *stm32lx_info = bank->driver_priv; - - uint32_t wrpr; - - /* - * Read the WRPR word, and check each bit (corresponding to each - * flash sector - */ - retval = target_read_u32(target, stm32lx_info->flash_base + FLASH_WRPR, - &wrpr); - if (retval != ERROR_OK) - return retval; - - for (int i = 0; i < bank->num_sectors; i++) { - if (wrpr & (1 << i)) - bank->sectors[i].is_protected = 1; - else - bank->sectors[i].is_protected = 0; - } - return ERROR_OK; -} - -static int stm32lx_erase(struct flash_bank *bank, int first, int last) -{ - int retval; - - /* - * It could be possible to do a mass erase if all sectors must be - * erased, but it is not implemented yet. - */ - - if (bank->target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - /* - * Loop over the selected sectors and erase them - */ - for (int i = first; i <= last; i++) { - retval = stm32lx_erase_sector(bank, i); - if (retval != ERROR_OK) - return retval; - bank->sectors[i].is_erased = 1; - } - return ERROR_OK; -} - -static int stm32lx_protect(struct flash_bank *bank, int set, int first, - int last) -{ - LOG_WARNING("protection of the STM32L flash is not implemented"); - return ERROR_OK; -} - -static int stm32lx_write_half_pages(struct flash_bank *bank, const uint8_t *buffer, - uint32_t offset, uint32_t count) -{ - 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 buffer_size = 16384; - struct working_area *write_algorithm; - struct working_area *source; - uint32_t address = bank->base + offset; - - struct reg_param reg_params[3]; - struct armv7m_algorithm armv7m_info; - - int retval = ERROR_OK; - - /* 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 */ - }; - - /* Make sure we're performing a half-page aligned write. */ - if (count % hp_nb) { - LOG_ERROR("The byte count must be %" PRIu32 "B-aligned but count is %" PRIi32 "B)", hp_nb, count); - return ERROR_FAIL; - } - - /* flash write code */ - if (target_alloc_working_area(target, sizeof(stm32lx_flash_write_code), - &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, - write_algorithm->address, - sizeof(stm32lx_flash_write_code), - stm32lx_flash_write_code); - if (retval != ERROR_OK) { - target_free_working_area(target, write_algorithm); - return retval; - } - - /* Allocate half pages memory */ - while (target_alloc_working_area_try(target, buffer_size, &source) != ERROR_OK) { - if (buffer_size > 1024) - buffer_size -= 1024; - else - buffer_size /= 2; - - 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); - - 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; - init_reg_param(®_params[0], "r0", 32, PARAM_OUT); - init_reg_param(®_params[1], "r1", 32, PARAM_OUT); - init_reg_param(®_params[2], "r2", 32, PARAM_OUT); - - /* Enable half-page write */ - retval = stm32lx_enable_write_half_page(bank); - if (retval != ERROR_OK) { - target_free_working_area(target, source); - target_free_working_area(target, write_algorithm); - - destroy_reg_param(®_params[0]); - destroy_reg_param(®_params[1]); - destroy_reg_param(®_params[2]); - return retval; - } - - struct armv7m_common *armv7m = target_to_armv7m(target); - if (armv7m == NULL) { - - /* something is very wrong if armv7m is NULL */ - LOG_ERROR("unable to get armv7m target"); - return retval; - } - - /* save any DEMCR flags and configure target to catch any Hard Faults */ - uint32_t demcr_save = armv7m->demcr; - armv7m->demcr = VC_HARDERR; - - /* Loop while there are bytes to write */ - while (count > 0) { - uint32_t this_count; - this_count = (count > buffer_size) ? buffer_size : count; - - /* Write the next half pages */ - retval = target_write_buffer(target, source->address, this_count, buffer); - if (retval != ERROR_OK) - break; - - /* 4: Store useful information in the registers */ - /* the destination address of the copy (R0) */ - buf_set_u32(reg_params[0].value, 0, 32, address); - /* The source address of the copy (R1) */ - buf_set_u32(reg_params[1].value, 0, 32, source->address); - /* The length of the copy (R2) */ - buf_set_u32(reg_params[2].value, 0, 32, this_count / 4); - - /* 5: Execute the bunch of code */ - retval = target_run_algorithm(target, 0, NULL, sizeof(reg_params) - / sizeof(*reg_params), reg_params, - write_algorithm->address, 0, 10000, &armv7m_info); - if (retval != ERROR_OK) - break; - - /* check for Hard Fault */ - if (armv7m->exception_number == 3) - break; - - /* 6: Wait while busy */ - retval = stm32lx_wait_until_bsy_clear(bank); - if (retval != ERROR_OK) - break; - - buffer += this_count; - address += this_count; - count -= this_count; - } - - /* restore previous flags */ - armv7m->demcr = demcr_save; - - if (armv7m->exception_number == 3) { - - /* the stm32l15x devices seem to have an issue when blank. - * if a ram loader is executed on a blank device it will - * Hard Fault, this issue does not happen for a already programmed device. - * A related issue is described in the stm32l151xx errata (Doc ID 17721 Rev 6 - 2.1.3). - * The workaround of handling the Hard Fault exception does work, but makes the - * loader more complicated, as a compromise we manually write the pages, programming time - * is reduced by 50% using this slower method. - */ - - LOG_WARNING("couldn't use loader, falling back to page memory writes"); - - while (count > 0) { - uint32_t this_count; - this_count = (count > hp_nb) ? hp_nb : count; - - /* Write the next half pages */ - retval = target_write_buffer(target, address, this_count, buffer); - if (retval != ERROR_OK) - break; - - /* Wait while busy */ - retval = stm32lx_wait_until_bsy_clear(bank); - if (retval != ERROR_OK) - break; - - buffer += this_count; - address += this_count; - count -= this_count; - } - } - - if (retval == ERROR_OK) - retval = stm32lx_lock_program_memory(bank); - - target_free_working_area(target, source); - target_free_working_area(target, write_algorithm); - - destroy_reg_param(®_params[0]); - destroy_reg_param(®_params[1]); - destroy_reg_param(®_params[2]); - - return retval; -} - -static int stm32lx_write(struct flash_bank *bank, const uint8_t *buffer, - uint32_t offset, uint32_t count) -{ - 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 halfpages_number; - uint32_t bytes_remaining = 0; - uint32_t address = bank->base + offset; - uint32_t bytes_written = 0; - int retval, retval2; - - 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; - } - - retval = stm32lx_unlock_program_memory(bank); - if (retval != ERROR_OK) - return retval; - - /* first we need to write any unaligned head bytes upto - * the next 128 byte page */ - - if (offset % hp_nb) - bytes_remaining = MIN(count, hp_nb - (offset % hp_nb)); - - while (bytes_remaining > 0) { - uint8_t value[4] = {0xff, 0xff, 0xff, 0xff}; - - /* copy remaining bytes into the write buffer */ - uint32_t bytes_to_write = MIN(4, bytes_remaining); - memcpy(value, buffer + bytes_written, bytes_to_write); - - retval = target_write_buffer(target, address, 4, value); - if (retval != ERROR_OK) - goto reset_pg_and_lock; - - bytes_written += bytes_to_write; - bytes_remaining -= bytes_to_write; - address += 4; - - retval = stm32lx_wait_until_bsy_clear(bank); - if (retval != ERROR_OK) - goto reset_pg_and_lock; - } - - offset += bytes_written; - count -= bytes_written; - - /* this should always pass this check here */ - assert((offset % hp_nb) == 0); - - /* calculate half pages */ - halfpages_number = count / hp_nb; - - if (halfpages_number) { - retval = stm32lx_write_half_pages(bank, buffer + bytes_written, offset, hp_nb * halfpages_number); - if (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE) { - /* attempt slow memory writes */ - LOG_WARNING("couldn't use block writes, falling back to single memory accesses"); - halfpages_number = 0; - } else { - if (retval != ERROR_OK) - return ERROR_FAIL; - } - } - - /* write any remaining bytes */ - uint32_t page_bytes_written = hp_nb * halfpages_number; - bytes_written += page_bytes_written; - address += page_bytes_written; - bytes_remaining = count - page_bytes_written; - - retval = stm32lx_unlock_program_memory(bank); - if (retval != ERROR_OK) - return retval; - - while (bytes_remaining > 0) { - uint8_t value[4] = {0xff, 0xff, 0xff, 0xff}; - - /* copy remaining bytes into the write buffer */ - uint32_t bytes_to_write = MIN(4, bytes_remaining); - memcpy(value, buffer + bytes_written, bytes_to_write); - - retval = target_write_buffer(target, address, 4, value); - if (retval != ERROR_OK) - goto reset_pg_and_lock; - - bytes_written += bytes_to_write; - bytes_remaining -= bytes_to_write; - address += 4; - - retval = stm32lx_wait_until_bsy_clear(bank); - if (retval != ERROR_OK) - goto reset_pg_and_lock; - } - -reset_pg_and_lock: - retval2 = stm32lx_lock_program_memory(bank); - if (retval == ERROR_OK) - retval = retval2; - - return retval; -} - -static int stm32lx_read_id_code(struct target *target, uint32_t *id) -{ - /* read stm32 device id register */ - int retval = target_read_u32(target, DBGMCU_IDCODE, id); - if (retval != ERROR_OK) - return retval; - - /* STM32L0 parts will have 0 there, try reading the L0's location for - * DBG_IDCODE in case this is an L0 part. */ - if (*id == 0) - retval = target_read_u32(target, DBGMCU_IDCODE_L0, id); - - return retval; -} - -static int stm32lx_probe(struct flash_bank *bank) -{ - struct target *target = bank->target; - struct stm32lx_flash_bank *stm32lx_info = bank->driver_priv; - int i; - uint16_t flash_size_in_kb; - uint32_t device_id; - uint32_t base_address = FLASH_BANK0_ADDRESS; - uint32_t second_bank_base; - - stm32lx_info->probed = 0; - stm32lx_info->part_info = NULL; - - int retval = stm32lx_read_id_code(bank->target, &device_id); - if (retval != ERROR_OK) - return retval; - - stm32lx_info->idcode = device_id; - - 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]; - } - - if (!stm32lx_info->part_info) { - 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; - - /* Get the flash size from target. */ - 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 - * or 256K, respectively. Please see RM0038 r8 or newer and refer to - * section 30.1.1. */ - if (retval == ERROR_OK && (device_id & 0xfff) == 0x436) { - if (flash_size_in_kb == 0) - flash_size_in_kb = 384; - else if (flash_size_in_kb == 1) - flash_size_in_kb = 256; - } - - /* 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("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) { - 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; - } - - 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; - 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; - } else if (bank->base == base_address) { - /* This is the first bank */ - 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, - bank->base, base_address, second_bank_base); - return ERROR_FAIL; - } - LOG_INFO("STM32L flash has dual banks. Bank (%d) size is %dkb, base address is 0x%" PRIx32, - bank->bank_number, flash_size_in_kb, base_address); - } else { - LOG_INFO("STM32L flash size is %dkb, base address is 0x%" PRIx32, flash_size_in_kb, base_address); - } - - /* if the user sets the size manually then ignore the probed value - * this allows us to work around devices that have a invalid flash size register value */ - if (stm32lx_info->user_bank_size) { - flash_size_in_kb = stm32lx_info->user_bank_size / 1024; - LOG_INFO("ignoring flash probed value, using configured bank size: %dkbytes", flash_size_in_kb); - } - - /* calculate numbers of sectors (4kB per sector) */ - int num_sectors = (flash_size_in_kb * 1024) / FLASH_SECTOR_SIZE; - - if (bank->sectors) { - free(bank->sectors); - bank->sectors = NULL; - } - - bank->size = flash_size_in_kb * 1024; - bank->base = base_address; - bank->num_sectors = num_sectors; - bank->sectors = malloc(sizeof(struct flash_sector) * num_sectors); - if (bank->sectors == NULL) { - LOG_ERROR("failed to allocate bank sectors"); - return ERROR_FAIL; - } - - for (i = 0; i < num_sectors; i++) { - bank->sectors[i].offset = i * FLASH_SECTOR_SIZE; - bank->sectors[i].size = FLASH_SECTOR_SIZE; - bank->sectors[i].is_erased = -1; - bank->sectors[i].is_protected = 1; - } - - stm32lx_info->probed = 1; - - return ERROR_OK; -} - -static int stm32lx_auto_probe(struct flash_bank *bank) -{ - struct stm32lx_flash_bank *stm32lx_info = bank->driver_priv; - - if (stm32lx_info->probed) - return ERROR_OK; - - 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; - - if (!stm32lx_info->probed) { - int retval = stm32lx_probe(bank); - if (retval != ERROR_OK) { - snprintf(buf, buf_size, - "Unable to find bank information."); - return retval; - } - } - - 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; - - 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; - } else { - snprintf(buf, buf_size, "Cannot identify target as a STM32Lx"); - - return ERROR_FAIL; - } -} - -static const struct command_registration stm32lx_exec_command_handlers[] = { - { - .name = "mass_erase", - .handler = stm32lx_handle_mass_erase_command, - .mode = COMMAND_EXEC, - .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 -}; - -static const struct command_registration stm32lx_command_handlers[] = { - { - .name = "stm32lx", - .mode = COMMAND_ANY, - .help = "stm32lx flash command group", - .usage = "", - .chain = stm32lx_exec_command_handlers, - }, - COMMAND_REGISTRATION_DONE -}; - -struct flash_driver stm32lx_flash = { - .name = "stm32lx", - .commands = stm32lx_command_handlers, - .flash_bank_command = stm32lx_flash_bank_command, - .erase = stm32lx_erase, - .protect = stm32lx_protect, - .write = stm32lx_write, - .read = default_flash_read, - .probe = stm32lx_probe, - .auto_probe = stm32lx_auto_probe, - .erase_check = stm32lx_erase_check, - .protect_check = stm32lx_protect_check, - .info = stm32lx_get_info, -}; - -/* Static methods implementation */ -static int stm32lx_unlock_program_memory(struct flash_bank *bank) -{ - struct target *target = bank->target; - struct stm32lx_flash_bank *stm32lx_info = bank->driver_priv; - int retval; - uint32_t reg32; - - /* - * Unlocking the program memory is done by unlocking the PECR, - * then by writing the 2 PRGKEY to the PRGKEYR register - */ - - /* check flash is not already unlocked */ - retval = target_read_u32(target, stm32lx_info->flash_base + FLASH_PECR, - ®32); - if (retval != ERROR_OK) - return retval; - - if ((reg32 & FLASH_PECR__PRGLOCK) == 0) - return ERROR_OK; - - /* To unlock the PECR write the 2 PEKEY to the PEKEYR register */ - retval = target_write_u32(target, stm32lx_info->flash_base + FLASH_PEKEYR, - PEKEY1); - if (retval != ERROR_OK) - return retval; - - retval = target_write_u32(target, stm32lx_info->flash_base + FLASH_PEKEYR, - PEKEY2); - if (retval != ERROR_OK) - return retval; - - /* Make sure it worked */ - retval = target_read_u32(target, stm32lx_info->flash_base + FLASH_PECR, - ®32); - if (retval != ERROR_OK) - return retval; - - if (reg32 & FLASH_PECR__PELOCK) { - LOG_ERROR("PELOCK is not cleared :("); - return ERROR_FLASH_OPERATION_FAILED; - } - - retval = target_write_u32(target, stm32lx_info->flash_base + FLASH_PRGKEYR, - PRGKEY1); - if (retval != ERROR_OK) - return retval; - retval = target_write_u32(target, stm32lx_info->flash_base + FLASH_PRGKEYR, - PRGKEY2); - if (retval != ERROR_OK) - return retval; - - /* Make sure it worked */ - retval = target_read_u32(target, stm32lx_info->flash_base + FLASH_PECR, - ®32); - if (retval != ERROR_OK) - return retval; - - if (reg32 & FLASH_PECR__PRGLOCK) { - LOG_ERROR("PRGLOCK is not cleared :("); - return ERROR_FLASH_OPERATION_FAILED; - } - - return ERROR_OK; -} - -static int stm32lx_enable_write_half_page(struct flash_bank *bank) -{ - struct target *target = bank->target; - struct stm32lx_flash_bank *stm32lx_info = bank->driver_priv; - int retval; - uint32_t reg32; - - /** - * Unlock the program memory, then set the FPRG bit in the PECR register. - */ - retval = stm32lx_unlock_program_memory(bank); - if (retval != ERROR_OK) - return retval; - - retval = target_read_u32(target, stm32lx_info->flash_base + FLASH_PECR, - ®32); - if (retval != ERROR_OK) - return retval; - - reg32 |= FLASH_PECR__FPRG; - retval = target_write_u32(target, stm32lx_info->flash_base + FLASH_PECR, - reg32); - if (retval != ERROR_OK) - return retval; - - retval = target_read_u32(target, stm32lx_info->flash_base + FLASH_PECR, - ®32); - if (retval != ERROR_OK) - return retval; - - reg32 |= FLASH_PECR__PROG; - retval = target_write_u32(target, stm32lx_info->flash_base + FLASH_PECR, - reg32); - - return retval; -} - -static int stm32lx_lock_program_memory(struct flash_bank *bank) -{ - struct target *target = bank->target; - struct stm32lx_flash_bank *stm32lx_info = bank->driver_priv; - int retval; - uint32_t reg32; - - /* To lock the program memory, simply set the lock bit and lock PECR */ - - retval = target_read_u32(target, stm32lx_info->flash_base + FLASH_PECR, - ®32); - if (retval != ERROR_OK) - return retval; - - reg32 |= FLASH_PECR__PRGLOCK; - retval = target_write_u32(target, stm32lx_info->flash_base + FLASH_PECR, - reg32); - if (retval != ERROR_OK) - return retval; - - retval = target_read_u32(target, stm32lx_info->flash_base + FLASH_PECR, - ®32); - if (retval != ERROR_OK) - return retval; - - reg32 |= FLASH_PECR__PELOCK; - retval = target_write_u32(target, stm32lx_info->flash_base + FLASH_PECR, - reg32); - if (retval != ERROR_OK) - return retval; - - return ERROR_OK; -} - -static int stm32lx_erase_sector(struct flash_bank *bank, int sector) -{ - struct target *target = bank->target; - struct stm32lx_flash_bank *stm32lx_info = bank->driver_priv; - int retval; - uint32_t reg32; - - /* - * To erase a sector (i.e. stm32lx_info->part_info.pages_per_sector pages), - * first unlock the memory, loop over the pages of this sector - * and write 0x0 to its first word. - */ - - retval = stm32lx_unlock_program_memory(bank); - if (retval != ERROR_OK) - return retval; - - 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, - stm32lx_info->flash_base + FLASH_PECR, reg32); - if (retval != ERROR_OK) - return retval; - - retval = stm32lx_wait_until_bsy_clear(bank); - if (retval != ERROR_OK) - return retval; - - uint32_t addr = bank->base + bank->sectors[sector].offset + (page - * stm32lx_info->part_info->page_size); - retval = target_write_u32(target, addr, 0x0); - if (retval != ERROR_OK) - return retval; - - retval = stm32lx_wait_until_bsy_clear(bank); - if (retval != ERROR_OK) - return retval; - } - - retval = stm32lx_lock_program_memory(bank); - if (retval != ERROR_OK) - return retval; - - return ERROR_OK; -} - -static inline int stm32lx_get_flash_status(struct flash_bank *bank, uint32_t *status) -{ - struct target *target = bank->target; - struct stm32lx_flash_bank *stm32lx_info = bank->driver_priv; - - return target_read_u32(target, stm32lx_info->flash_base + FLASH_SR, status); -} - -static int stm32lx_wait_until_bsy_clear(struct flash_bank *bank) -{ - return stm32lx_wait_until_bsy_clear_timeout(bank, 100); -} - -static int stm32lx_unlock_options_bytes(struct flash_bank *bank) -{ - struct target *target = bank->target; - struct stm32lx_flash_bank *stm32lx_info = bank->driver_priv; - int retval; - uint32_t reg32; - - /* - * Unlocking the options bytes is done by unlocking the PECR, - * then by writing the 2 FLASH_PEKEYR to the FLASH_OPTKEYR register - */ - - /* check flash is not already unlocked */ - retval = target_read_u32(target, stm32lx_info->flash_base + FLASH_PECR, ®32); - if (retval != ERROR_OK) - return retval; - - if ((reg32 & FLASH_PECR__OPTLOCK) == 0) - return ERROR_OK; - - if ((reg32 & FLASH_PECR__PELOCK) != 0) { - - retval = target_write_u32(target, stm32lx_info->flash_base + FLASH_PEKEYR, PEKEY1); - if (retval != ERROR_OK) - return retval; - - retval = target_write_u32(target, stm32lx_info->flash_base + FLASH_PEKEYR, PEKEY2); - if (retval != ERROR_OK) - return retval; - } - - /* To unlock the PECR write the 2 OPTKEY to the FLASH_OPTKEYR register */ - retval = target_write_u32(target, stm32lx_info->flash_base + FLASH_OPTKEYR, OPTKEY1); - if (retval != ERROR_OK) - return retval; - - retval = target_write_u32(target, stm32lx_info->flash_base + FLASH_OPTKEYR, OPTKEY2); - if (retval != ERROR_OK) - return retval; - - return ERROR_OK; -} - -static int stm32lx_wait_until_bsy_clear_timeout(struct flash_bank *bank, int timeout) -{ - struct target *target = bank->target; - struct stm32lx_flash_bank *stm32lx_info = bank->driver_priv; - uint32_t status; - int retval = ERROR_OK; - - /* wait for busy to clear */ - for (;;) { - retval = stm32lx_get_flash_status(bank, &status); - if (retval != ERROR_OK) - return retval; - - LOG_DEBUG("status: 0x%" PRIx32 "", status); - if ((status & FLASH_SR__BSY) == 0) - break; - - if (timeout-- <= 0) { - LOG_ERROR("timed out waiting for flash"); - return ERROR_FAIL; - } - alive_sleep(1); - } - - if (status & FLASH_SR__WRPERR) { - LOG_ERROR("access denied / write protected"); - retval = ERROR_FAIL; - } - - if (status & FLASH_SR__PGAERR) { - LOG_ERROR("invalid program address"); - retval = ERROR_FAIL; - } - - /* Clear but report errors */ - if (status & FLASH_SR__OPTVERR) { - /* If this operation fails, we ignore it and report the original retval */ - target_write_u32(target, stm32lx_info->flash_base + FLASH_SR, status & FLASH_SR__OPTVERR); - } - - return retval; -} - -static int stm32lx_obl_launch(struct flash_bank *bank) -{ - struct target *target = bank->target; - struct stm32lx_flash_bank *stm32lx_info = bank->driver_priv; - int retval; - - /* This will fail as the target gets immediately rebooted */ - target_write_u32(target, stm32lx_info->flash_base + FLASH_PECR, - FLASH_PECR__OBL_LAUNCH); - - size_t tries = 10; - do { - target_halt(target); - retval = target_poll(target); - } while (--tries > 0 && - (retval != ERROR_OK || target->state != TARGET_HALTED)); - - return tries ? ERROR_OK : ERROR_FAIL; -} - -static int stm32lx_lock(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) - return retval; - - /* 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; - - 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) - return retval; - - /* set the RDP protection level to 0 */ - retval = target_write_u32(target, OPTION_BYTES_ADDRESS, OPTION_BYTE_0_PR0); - if (retval != ERROR_OK) - return retval; - - retval = stm32lx_wait_until_bsy_clear_timeout(bank, 30000); - 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; - - retval = target_read_u32(target, stm32lx_info->flash_base + FLASH_PECR, ®32); - if (retval != ERROR_OK) - return retval; - - retval = target_write_u32(target, stm32lx_info->flash_base + FLASH_PECR, reg32 | FLASH_PECR__OPTLOCK); - if (retval != ERROR_OK) - return retval; - - return ERROR_OK; -} diff --git a/src/flash/nor/stmsmi.c b/src/flash/nor/stmsmi.c deleted file mode 100644 index 781ea3b5b..000000000 --- a/src/flash/nor/stmsmi.c +++ /dev/null @@ -1,657 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2010 by Antonio Borneo * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -/* STM Serial Memory Interface (SMI) controller is a SPI bus controller - * specifically designed for SPI memories. - * Only SPI "mode 3" (CPOL=1 and CPHA=1) is supported. - * Two working modes are available: - * - SW mode: the SPI is controlled by SW. Any custom commands can be sent - * on the bus. - * - HW mode: the SPI but is under SMI control. Memory content is directly - * accessible in CPU memory space. CPU can read, write and execute memory - * content. */ - -/* ATTENTION: - * To have flash memory mapped in CPU memory space, the SMI controller - * have to be in "HW mode". This requires following constraints: - * 1) The command "reset init" have to initialize SMI controller and put - * it in HW mode; - * 2) every command in this file have to return to prompt in HW mode. */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "imp.h" -#include "spi.h" -#include -#include - -#define SMI_READ_REG(a) (_SMI_READ_REG(a)) -#define _SMI_READ_REG(a) \ -{ \ - int __a; \ - uint32_t __v; \ - \ - __a = target_read_u32(target, io_base + (a), &__v); \ - if (__a != ERROR_OK) \ - return __a; \ - __v; \ -} - -#define SMI_WRITE_REG(a, v) \ -{ \ - int __r; \ - \ - __r = target_write_u32(target, io_base + (a), (v)); \ - if (__r != ERROR_OK) \ - return __r; \ -} - -#define SMI_POLL_TFF(timeout) \ -{ \ - int __r; \ - \ - __r = poll_tff(target, io_base, timeout); \ - if (__r != ERROR_OK) \ - return __r; \ -} - -#define SMI_SET_SW_MODE() SMI_WRITE_REG(SMI_CR1, \ - SMI_READ_REG(SMI_CR1) | SMI_SW_MODE) -#define SMI_SET_HWWB_MODE() SMI_WRITE_REG(SMI_CR1, \ - (SMI_READ_REG(SMI_CR1) | SMI_WB_MODE) & ~SMI_SW_MODE) -#define SMI_SET_HW_MODE() SMI_WRITE_REG(SMI_CR1, \ - SMI_READ_REG(SMI_CR1) & ~(SMI_SW_MODE | SMI_WB_MODE)) -#define SMI_CLEAR_TFF() SMI_WRITE_REG(SMI_SR, ~SMI_TFF) - -#define SMI_BANK_SIZE (0x01000000) - -#define SMI_CR1 (0x00) /* Control register 1 */ -#define SMI_CR2 (0x04) /* Control register 2 */ -#define SMI_SR (0x08) /* Status register */ -#define SMI_TR (0x0c) /* TX */ -#define SMI_RR (0x10) /* RX */ - -/* fields in SMI_CR1 */ -#define SMI_SW_MODE 0x10000000 /* set to enable SW Mode */ -#define SMI_WB_MODE 0x20000000 /* Write Burst Mode */ - -/* fields in SMI_CR2 */ -#define SMI_TX_LEN_1 0x00000001 /* data length = 1 byte */ -#define SMI_TX_LEN_4 0x00000004 /* data length = 4 byte */ -#define SMI_RX_LEN_3 0x00000030 /* data length = 3 byte */ -#define SMI_SEND 0x00000080 /* Send data */ -#define SMI_RSR 0x00000400 /* reads status reg */ -#define SMI_WE 0x00000800 /* Write Enable */ -#define SMI_SEL_BANK0 0x00000000 /* Select Bank0 */ -#define SMI_SEL_BANK1 0x00001000 /* Select Bank1 */ -#define SMI_SEL_BANK2 0x00002000 /* Select Bank2 */ -#define SMI_SEL_BANK3 0x00003000 /* Select Bank3 */ - -/* fields in SMI_SR */ -#define SMI_TFF 0x00000100 /* Transfer Finished Flag */ - -/* Commands */ -#define SMI_READ_ID 0x0000009F /* Read Flash Identification */ - -/* Timeout in ms */ -#define SMI_CMD_TIMEOUT (100) -#define SMI_PROBE_TIMEOUT (100) -#define SMI_MAX_TIMEOUT (3000) - -struct stmsmi_flash_bank { - int probed; - uint32_t io_base; - uint32_t bank_num; - const struct flash_device *dev; -}; - -struct stmsmi_target { - char *name; - uint32_t tap_idcode; - uint32_t smi_base; - uint32_t io_base; -}; - -static const struct stmsmi_target target_devices[] = { - /* name, tap_idcode, smi_base, io_base */ - { "SPEAr3xx/6xx", 0x07926041, 0xf8000000, 0xfc000000 }, - { "STR75x", 0x4f1f0041, 0x80000000, 0x90000000 }, - { NULL, 0, 0, 0 } -}; - -FLASH_BANK_COMMAND_HANDLER(stmsmi_flash_bank_command) -{ - struct stmsmi_flash_bank *stmsmi_info; - - LOG_DEBUG("%s", __func__); - - if (CMD_ARGC < 6) - return ERROR_COMMAND_SYNTAX_ERROR; - - stmsmi_info = malloc(sizeof(struct stmsmi_flash_bank)); - if (stmsmi_info == NULL) { - LOG_ERROR("not enough memory"); - return ERROR_FAIL; - } - - bank->driver_priv = stmsmi_info; - stmsmi_info->probed = 0; - - return ERROR_OK; -} - -/* Poll transmit finished flag */ -/* timeout in ms */ -static int poll_tff(struct target *target, uint32_t io_base, int timeout) -{ - int64_t endtime; - - if (SMI_READ_REG(SMI_SR) & SMI_TFF) - return ERROR_OK; - - endtime = timeval_ms() + timeout; - do { - alive_sleep(1); - if (SMI_READ_REG(SMI_SR) & SMI_TFF) - return ERROR_OK; - } while (timeval_ms() < endtime); - - LOG_ERROR("Timeout while polling TFF"); - return ERROR_FLASH_OPERATION_FAILED; -} - -/* Read the status register of the external SPI flash chip. - * The operation is triggered by setting SMI_RSR bit. - * SMI sends the proper SPI command (0x05) and returns value in SMI_SR */ -static int read_status_reg(struct flash_bank *bank, uint32_t *status) -{ - struct target *target = bank->target; - struct stmsmi_flash_bank *stmsmi_info = bank->driver_priv; - uint32_t io_base = stmsmi_info->io_base; - - /* clear transmit finished flag */ - SMI_CLEAR_TFF(); - - /* Read status */ - SMI_WRITE_REG(SMI_CR2, stmsmi_info->bank_num | SMI_RSR); - - /* Poll transmit finished flag */ - SMI_POLL_TFF(SMI_CMD_TIMEOUT); - - /* clear transmit finished flag */ - SMI_CLEAR_TFF(); - - *status = SMI_READ_REG(SMI_SR) & 0x0000ffff; - - /* clean-up SMI_CR2 */ - SMI_WRITE_REG(SMI_CR2, 0); /* AB: Required ? */ - - return ERROR_OK; -} - -/* check for WIP (write in progress) bit in status register */ -/* timeout in ms */ -static int wait_till_ready(struct flash_bank *bank, int timeout) -{ - uint32_t status; - int retval; - int64_t endtime; - - endtime = timeval_ms() + timeout; - do { - /* read flash status register */ - retval = read_status_reg(bank, &status); - if (retval != ERROR_OK) - return retval; - - if ((status & SPIFLASH_BSY_BIT) == 0) - return ERROR_OK; - alive_sleep(1); - } while (timeval_ms() < endtime); - - LOG_ERROR("timeout"); - return ERROR_FAIL; -} - -/* Send "write enable" command to SPI flash chip. - * The operation is triggered by setting SMI_WE bit, and SMI sends - * the proper SPI command (0x06) */ -static int smi_write_enable(struct flash_bank *bank) -{ - struct target *target = bank->target; - struct stmsmi_flash_bank *stmsmi_info = bank->driver_priv; - uint32_t io_base = stmsmi_info->io_base; - uint32_t status; - int retval; - - /* Enter in HW mode */ - SMI_SET_HW_MODE(); /* AB: is this correct ?*/ - - /* clear transmit finished flag */ - SMI_CLEAR_TFF(); - - /* Send write enable command */ - SMI_WRITE_REG(SMI_CR2, stmsmi_info->bank_num | SMI_WE); - - /* Poll transmit finished flag */ - SMI_POLL_TFF(SMI_CMD_TIMEOUT); - - /* read flash status register */ - retval = read_status_reg(bank, &status); - if (retval != ERROR_OK) - return retval; - - /* Check write enabled */ - if ((status & SPIFLASH_WE_BIT) == 0) { - LOG_ERROR("Cannot enable write to flash. Status=0x%08" PRIx32, status); - return ERROR_FAIL; - } - - return ERROR_OK; -} - -static uint32_t erase_command(struct stmsmi_flash_bank *stmsmi_info, - uint32_t offset) -{ - union { - uint32_t command; - uint8_t x[4]; - } cmd; - - cmd.x[0] = stmsmi_info->dev->erase_cmd; - cmd.x[1] = offset >> 16; - cmd.x[2] = offset >> 8; - cmd.x[3] = offset; - - return cmd.command; -} - -static int smi_erase_sector(struct flash_bank *bank, int sector) -{ - struct target *target = bank->target; - struct stmsmi_flash_bank *stmsmi_info = bank->driver_priv; - uint32_t io_base = stmsmi_info->io_base; - uint32_t cmd; - int retval; - - retval = smi_write_enable(bank); - if (retval != ERROR_OK) - return retval; - - /* Switch to SW mode to send sector erase command */ - SMI_SET_SW_MODE(); - - /* clear transmit finished flag */ - SMI_CLEAR_TFF(); - - /* send SPI command "block erase" */ - cmd = erase_command(stmsmi_info, bank->sectors[sector].offset); - SMI_WRITE_REG(SMI_TR, cmd); - SMI_WRITE_REG(SMI_CR2, stmsmi_info->bank_num | SMI_SEND | SMI_TX_LEN_4); - - /* Poll transmit finished flag */ - SMI_POLL_TFF(SMI_CMD_TIMEOUT); - - /* poll WIP for end of self timed Sector Erase cycle */ - retval = wait_till_ready(bank, SMI_MAX_TIMEOUT); - if (retval != ERROR_OK) - return retval; - - return ERROR_OK; -} - -static int stmsmi_erase(struct flash_bank *bank, int first, int last) -{ - struct target *target = bank->target; - struct stmsmi_flash_bank *stmsmi_info = bank->driver_priv; - uint32_t io_base = stmsmi_info->io_base; - int retval = ERROR_OK; - int sector; - - LOG_DEBUG("%s: from sector %d to sector %d", __func__, first, last); - - if (target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - if ((first < 0) || (last < first) || (last >= bank->num_sectors)) { - LOG_ERROR("Flash sector invalid"); - return ERROR_FLASH_SECTOR_INVALID; - } - - if (!(stmsmi_info->probed)) { - LOG_ERROR("Flash bank not probed"); - return ERROR_FLASH_BANK_NOT_PROBED; - } - - for (sector = first; sector <= last; sector++) { - if (bank->sectors[sector].is_protected) { - LOG_ERROR("Flash sector %d protected", sector); - return ERROR_FAIL; - } - } - - for (sector = first; sector <= last; sector++) { - retval = smi_erase_sector(bank, sector); - if (retval != ERROR_OK) - break; - keep_alive(); - } - - /* Switch to HW mode before return to prompt */ - SMI_SET_HW_MODE(); - return retval; -} - -static int stmsmi_protect(struct flash_bank *bank, int set, - int first, int last) -{ - int sector; - - for (sector = first; sector <= last; sector++) - bank->sectors[sector].is_protected = set; - return ERROR_OK; -} - -static int smi_write_buffer(struct flash_bank *bank, const uint8_t *buffer, - uint32_t address, uint32_t len) -{ - struct target *target = bank->target; - struct stmsmi_flash_bank *stmsmi_info = bank->driver_priv; - uint32_t io_base = stmsmi_info->io_base; - int retval; - - LOG_DEBUG("%s: address=0x%08" PRIx32 " len=0x%08" PRIx32, - __func__, address, len); - - retval = smi_write_enable(bank); - if (retval != ERROR_OK) - return retval; - - /* HW mode, write burst mode */ - SMI_SET_HWWB_MODE(); - - retval = target_write_buffer(target, address, len, buffer); - if (retval != ERROR_OK) - return retval; - - return ERROR_OK; -} - -static int stmsmi_write(struct flash_bank *bank, const uint8_t *buffer, - uint32_t offset, uint32_t count) -{ - struct target *target = bank->target; - struct stmsmi_flash_bank *stmsmi_info = bank->driver_priv; - uint32_t io_base = stmsmi_info->io_base; - uint32_t cur_count, page_size, page_offset; - int sector; - int retval = ERROR_OK; - - LOG_DEBUG("%s: offset=0x%08" PRIx32 " count=0x%08" PRIx32, - __func__, offset, count); - - if (target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - if (offset + count > stmsmi_info->dev->size_in_bytes) { - LOG_WARNING("Write pasts end of flash. Extra data discarded."); - count = stmsmi_info->dev->size_in_bytes - offset; - } - - /* Check sector protection */ - for (sector = 0; sector < bank->num_sectors; sector++) { - /* Start offset in or before this sector? */ - /* End offset in or behind this sector? */ - if ((offset < - (bank->sectors[sector].offset + bank->sectors[sector].size)) - && ((offset + count - 1) >= bank->sectors[sector].offset) - && bank->sectors[sector].is_protected) { - LOG_ERROR("Flash sector %d protected", sector); - return ERROR_FAIL; - } - } - - page_size = stmsmi_info->dev->pagesize; - - /* unaligned buffer head */ - if (count > 0 && (offset & 3) != 0) { - cur_count = 4 - (offset & 3); - if (cur_count > count) - cur_count = count; - retval = smi_write_buffer(bank, buffer, bank->base + offset, - cur_count); - if (retval != ERROR_OK) - goto err; - offset += cur_count; - buffer += cur_count; - count -= cur_count; - } - - page_offset = offset % page_size; - /* central part, aligned words */ - while (count >= 4) { - /* clip block at page boundary */ - if (page_offset + count > page_size) - cur_count = page_size - page_offset; - else - cur_count = count & ~3; - - retval = smi_write_buffer(bank, buffer, bank->base + offset, - cur_count); - if (retval != ERROR_OK) - goto err; - - page_offset = 0; - buffer += cur_count; - offset += cur_count; - count -= cur_count; - - keep_alive(); - } - - /* buffer tail */ - if (count > 0) - retval = smi_write_buffer(bank, buffer, bank->base + offset, count); - -err: - /* Switch to HW mode before return to prompt */ - SMI_SET_HW_MODE(); - return retval; -} - -/* Return ID of flash device */ -/* On exit, SW mode is kept */ -static int read_flash_id(struct flash_bank *bank, uint32_t *id) -{ - struct target *target = bank->target; - struct stmsmi_flash_bank *stmsmi_info = bank->driver_priv; - uint32_t io_base = stmsmi_info->io_base; - int retval; - - if (target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - /* poll WIP */ - retval = wait_till_ready(bank, SMI_PROBE_TIMEOUT); - if (retval != ERROR_OK) - return retval; - - /* enter in SW mode */ - SMI_SET_SW_MODE(); - - /* clear transmit finished flag */ - SMI_CLEAR_TFF(); - - /* Send SPI command "read ID" */ - SMI_WRITE_REG(SMI_TR, SMI_READ_ID); - SMI_WRITE_REG(SMI_CR2, - stmsmi_info->bank_num | SMI_SEND | SMI_RX_LEN_3 | SMI_TX_LEN_1); - - /* Poll transmit finished flag */ - SMI_POLL_TFF(SMI_CMD_TIMEOUT); - - /* clear transmit finished flag */ - SMI_CLEAR_TFF(); - - /* read ID from Receive Register */ - *id = SMI_READ_REG(SMI_RR) & 0x00ffffff; - return ERROR_OK; -} - -static int stmsmi_probe(struct flash_bank *bank) -{ - struct target *target = bank->target; - struct stmsmi_flash_bank *stmsmi_info = bank->driver_priv; - uint32_t io_base; - struct flash_sector *sectors; - uint32_t id = 0; /* silence uninitialized warning */ - const struct stmsmi_target *target_device; - int retval; - - if (stmsmi_info->probed) - free(bank->sectors); - stmsmi_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 SMI capable", - target->tap->idcode); - return ERROR_FAIL; - } - - switch (bank->base - target_device->smi_base) { - case 0: - stmsmi_info->bank_num = SMI_SEL_BANK0; - break; - case SMI_BANK_SIZE: - stmsmi_info->bank_num = SMI_SEL_BANK1; - break; - case 2*SMI_BANK_SIZE: - stmsmi_info->bank_num = SMI_SEL_BANK2; - break; - case 3*SMI_BANK_SIZE: - stmsmi_info->bank_num = SMI_SEL_BANK3; - break; - default: - LOG_ERROR("Invalid SMI base address 0x%" PRIx32, bank->base); - return ERROR_FAIL; - } - io_base = target_device->io_base; - stmsmi_info->io_base = io_base; - - LOG_DEBUG("Valid SMI on device %s at address 0x%" PRIx32, - target_device->name, bank->base); - - /* read and decode flash ID; returns in SW mode */ - retval = read_flash_id(bank, &id); - SMI_SET_HW_MODE(); - if (retval != ERROR_OK) - return retval; - - stmsmi_info->dev = NULL; - for (const struct flash_device *p = flash_devices; p->name ; p++) - if (p->device_id == id) { - stmsmi_info->dev = p; - break; - } - - if (!stmsmi_info->dev) { - LOG_ERROR("Unknown flash device (ID 0x%08" PRIx32 ")", id); - return ERROR_FAIL; - } - - LOG_INFO("Found flash device \'%s\' (ID 0x%08" PRIx32 ")", - stmsmi_info->dev->name, stmsmi_info->dev->device_id); - - /* Set correct size value */ - bank->size = stmsmi_info->dev->size_in_bytes; - - /* create and fill sectors array */ - bank->num_sectors = - stmsmi_info->dev->size_in_bytes / stmsmi_info->dev->sectorsize; - sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors); - if (sectors == NULL) { - LOG_ERROR("not enough memory"); - return ERROR_FAIL; - } - - for (int sector = 0; sector < bank->num_sectors; sector++) { - sectors[sector].offset = sector * stmsmi_info->dev->sectorsize; - sectors[sector].size = stmsmi_info->dev->sectorsize; - sectors[sector].is_erased = -1; - sectors[sector].is_protected = 1; - } - - bank->sectors = sectors; - stmsmi_info->probed = 1; - return ERROR_OK; -} - -static int stmsmi_auto_probe(struct flash_bank *bank) -{ - struct stmsmi_flash_bank *stmsmi_info = bank->driver_priv; - if (stmsmi_info->probed) - return ERROR_OK; - return stmsmi_probe(bank); -} - -static int stmsmi_protect_check(struct flash_bank *bank) -{ - /* Nothing to do. Protection is only handled in SW. */ - return ERROR_OK; -} - -static int get_stmsmi_info(struct flash_bank *bank, char *buf, int buf_size) -{ - struct stmsmi_flash_bank *stmsmi_info = bank->driver_priv; - - if (!(stmsmi_info->probed)) { - snprintf(buf, buf_size, - "\nSMI flash bank not probed yet\n"); - return ERROR_OK; - } - - snprintf(buf, buf_size, "\nSMI flash information:\n" - " Device \'%s\' (ID 0x%08" PRIx32 ")\n", - stmsmi_info->dev->name, stmsmi_info->dev->device_id); - - return ERROR_OK; -} - -struct flash_driver stmsmi_flash = { - .name = "stmsmi", - .flash_bank_command = stmsmi_flash_bank_command, - .erase = stmsmi_erase, - .protect = stmsmi_protect, - .write = stmsmi_write, - .read = default_flash_read, - .probe = stmsmi_probe, - .auto_probe = stmsmi_auto_probe, - .erase_check = default_flash_blank_check, - .protect_check = stmsmi_protect_check, - .info = get_stmsmi_info, -}; diff --git a/src/flash/nor/str7x.c b/src/flash/nor/str7x.c deleted file mode 100644 index 11179f520..000000000 --- a/src/flash/nor/str7x.c +++ /dev/null @@ -1,815 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * Copyright (C) 2008 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * Copyright (C) 2010 Øyvind Harboe * - * oyvind.harboe@zylin.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "imp.h" -#include -#include -#include - -/* Flash registers */ - -#define FLASH_CR0 0x00000000 -#define FLASH_CR1 0x00000004 -#define FLASH_DR0 0x00000008 -#define FLASH_DR1 0x0000000C -#define FLASH_AR 0x00000010 -#define FLASH_ER 0x00000014 -#define FLASH_NVWPAR 0x0000DFB0 -#define FLASH_NVAPR0 0x0000DFB8 -#define FLASH_NVAPR1 0x0000DFBC - -/* FLASH_CR0 register bits */ - -#define FLASH_WMS 0x80000000 -#define FLASH_SUSP 0x40000000 -#define FLASH_WPG 0x20000000 -#define FLASH_DWPG 0x10000000 -#define FLASH_SER 0x08000000 -#define FLASH_SPR 0x01000000 -#define FLASH_BER 0x04000000 -#define FLASH_MER 0x02000000 -#define FLASH_LOCK 0x00000010 -#define FLASH_BSYA1 0x00000004 -#define FLASH_BSYA0 0x00000002 - -/* FLASH_CR1 register bits */ - -#define FLASH_B1S 0x02000000 -#define FLASH_B0S 0x01000000 -#define FLASH_B1F1 0x00020000 -#define FLASH_B1F0 0x00010000 -#define FLASH_B0F7 0x00000080 -#define FLASH_B0F6 0x00000040 -#define FLASH_B0F5 0x00000020 -#define FLASH_B0F4 0x00000010 -#define FLASH_B0F3 0x00000008 -#define FLASH_B0F2 0x00000004 -#define FLASH_B0F1 0x00000002 -#define FLASH_B0F0 0x00000001 - -/* FLASH_ER register bits */ - -#define FLASH_WPF 0x00000100 -#define FLASH_RESER 0x00000080 -#define FLASH_SEQER 0x00000040 -#define FLASH_10ER 0x00000008 -#define FLASH_PGER 0x00000004 -#define FLASH_ERER 0x00000002 -#define FLASH_ERR 0x00000001 - - -struct str7x_flash_bank { - uint32_t *sector_bits; - uint32_t disable_bit; - uint32_t busy_bits; - uint32_t register_base; -}; - -struct str7x_mem_layout { - uint32_t sector_start; - uint32_t sector_size; - uint32_t sector_bit; -}; - -enum str7x_status_codes { - STR7X_CMD_SUCCESS = 0, - STR7X_INVALID_COMMAND = 1, - STR7X_SRC_ADDR_ERROR = 2, - STR7X_DST_ADDR_ERROR = 3, - STR7X_SRC_ADDR_NOT_MAPPED = 4, - STR7X_DST_ADDR_NOT_MAPPED = 5, - STR7X_COUNT_ERROR = 6, - STR7X_INVALID_SECTOR = 7, - STR7X_SECTOR_NOT_BLANK = 8, - STR7X_SECTOR_NOT_PREPARED = 9, - STR7X_COMPARE_ERROR = 10, - STR7X_BUSY = 11 -}; - -static const struct str7x_mem_layout mem_layout_str7bank0[] = { - {0x00000000, 0x02000, 0x01}, - {0x00002000, 0x02000, 0x02}, - {0x00004000, 0x02000, 0x04}, - {0x00006000, 0x02000, 0x08}, - {0x00008000, 0x08000, 0x10}, - {0x00010000, 0x10000, 0x20}, - {0x00020000, 0x10000, 0x40}, - {0x00030000, 0x10000, 0x80} -}; - -static const struct str7x_mem_layout mem_layout_str7bank1[] = { - {0x00000000, 0x02000, 0x10000}, - {0x00002000, 0x02000, 0x20000} -}; - -static int str7x_get_flash_adr(struct flash_bank *bank, uint32_t reg) -{ - struct str7x_flash_bank *str7x_info = bank->driver_priv; - return str7x_info->register_base | reg; -} - -static int str7x_build_block_list(struct flash_bank *bank) -{ - struct str7x_flash_bank *str7x_info = bank->driver_priv; - - int i; - int num_sectors; - int b0_sectors = 0, b1_sectors = 0; - - switch (bank->size) { - case 16 * 1024: - b1_sectors = 2; - break; - case 64 * 1024: - b0_sectors = 5; - break; - case 128 * 1024: - b0_sectors = 6; - break; - case 256 * 1024: - b0_sectors = 8; - break; - default: - LOG_ERROR("BUG: unknown bank->size encountered"); - exit(-1); - } - - num_sectors = b0_sectors + b1_sectors; - - bank->num_sectors = num_sectors; - bank->sectors = malloc(sizeof(struct flash_sector) * num_sectors); - str7x_info->sector_bits = malloc(sizeof(uint32_t) * num_sectors); - - num_sectors = 0; - - for (i = 0; i < b0_sectors; i++) { - bank->sectors[num_sectors].offset = mem_layout_str7bank0[i].sector_start; - bank->sectors[num_sectors].size = mem_layout_str7bank0[i].sector_size; - bank->sectors[num_sectors].is_erased = -1; - /* the reset_init handler marks all the sectors unprotected, - * matching hardware after reset; keep the driver in sync - */ - bank->sectors[num_sectors].is_protected = 0; - str7x_info->sector_bits[num_sectors++] = mem_layout_str7bank0[i].sector_bit; - } - - for (i = 0; i < b1_sectors; i++) { - bank->sectors[num_sectors].offset = mem_layout_str7bank1[i].sector_start; - bank->sectors[num_sectors].size = mem_layout_str7bank1[i].sector_size; - bank->sectors[num_sectors].is_erased = -1; - /* the reset_init handler marks all the sectors unprotected, - * matching hardware after reset; keep the driver in sync - */ - bank->sectors[num_sectors].is_protected = 0; - str7x_info->sector_bits[num_sectors++] = mem_layout_str7bank1[i].sector_bit; - } - - return ERROR_OK; -} - -/* flash bank str7x 0 0 - */ -FLASH_BANK_COMMAND_HANDLER(str7x_flash_bank_command) -{ - struct str7x_flash_bank *str7x_info; - - if (CMD_ARGC < 7) - return ERROR_COMMAND_SYNTAX_ERROR; - - str7x_info = malloc(sizeof(struct str7x_flash_bank)); - bank->driver_priv = str7x_info; - - /* set default bits for str71x flash */ - str7x_info->busy_bits = (FLASH_LOCK | FLASH_BSYA1 | FLASH_BSYA0); - str7x_info->disable_bit = (1 << 1); - - if (strcmp(CMD_ARGV[6], "STR71x") == 0) - str7x_info->register_base = 0x40100000; - else if (strcmp(CMD_ARGV[6], "STR73x") == 0) { - str7x_info->register_base = 0x80100000; - str7x_info->busy_bits = (FLASH_LOCK | FLASH_BSYA0); - } else if (strcmp(CMD_ARGV[6], "STR75x") == 0) { - str7x_info->register_base = 0x20100000; - str7x_info->disable_bit = (1 << 0); - } else { - LOG_ERROR("unknown STR7x variant: '%s'", CMD_ARGV[6]); - free(str7x_info); - return ERROR_FLASH_BANK_INVALID; - } - - str7x_build_block_list(bank); - - return ERROR_OK; -} - -/* wait for flash to become idle or report errors. - - FIX!!! what's the maximum timeout??? The documentation doesn't - state any maximum time.... by inspection it seems > 1000ms is to be - expected. - - 10000ms is long enough that it should cover anything, yet not - quite be equivalent to an infinite loop. - - */ -static int str7x_waitbusy(struct flash_bank *bank) -{ - int err; - int i; - struct target *target = bank->target; - struct str7x_flash_bank *str7x_info = bank->driver_priv; - - for (i = 0 ; i < 10000; i++) { - uint32_t retval; - err = target_read_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), &retval); - if (err != ERROR_OK) - return err; - - if ((retval & str7x_info->busy_bits) == 0) - return ERROR_OK; - - alive_sleep(1); - } - LOG_ERROR("Timed out waiting for str7x flash"); - return ERROR_FAIL; -} - - -static int str7x_result(struct flash_bank *bank) -{ - struct target *target = bank->target; - uint32_t flash_flags; - - int retval; - retval = target_read_u32(target, str7x_get_flash_adr(bank, FLASH_ER), &flash_flags); - if (retval != ERROR_OK) - return retval; - - if (flash_flags & FLASH_WPF) { - LOG_ERROR("str7x hw write protection set"); - retval = ERROR_FAIL; - } - if (flash_flags & FLASH_RESER) { - LOG_ERROR("str7x suspended program erase not resumed"); - retval = ERROR_FAIL; - } - if (flash_flags & FLASH_10ER) { - LOG_ERROR("str7x trying to set bit to 1 when it is already 0"); - retval = ERROR_FAIL; - } - if (flash_flags & FLASH_PGER) { - LOG_ERROR("str7x program error"); - retval = ERROR_FAIL; - } - if (flash_flags & FLASH_ERER) { - LOG_ERROR("str7x erase error"); - retval = ERROR_FAIL; - } - if (retval == ERROR_OK) { - if (flash_flags & FLASH_ERR) { - /* this should always be set if one of the others are set... */ - LOG_ERROR("str7x write operation failed / bad setup"); - retval = ERROR_FAIL; - } - } - - return retval; -} - -static int str7x_protect_check(struct flash_bank *bank) -{ - struct str7x_flash_bank *str7x_info = bank->driver_priv; - struct target *target = bank->target; - - int i; - uint32_t flash_flags; - - if (bank->target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - int retval; - retval = target_read_u32(target, str7x_get_flash_adr(bank, FLASH_NVWPAR), &flash_flags); - if (retval != ERROR_OK) - return retval; - - for (i = 0; i < bank->num_sectors; i++) { - if (flash_flags & str7x_info->sector_bits[i]) - bank->sectors[i].is_protected = 0; - else - bank->sectors[i].is_protected = 1; - } - - return ERROR_OK; -} - -static int str7x_erase(struct flash_bank *bank, int first, int last) -{ - struct str7x_flash_bank *str7x_info = bank->driver_priv; - struct target *target = bank->target; - - int i; - uint32_t cmd; - uint32_t sectors = 0; - int err; - - if (bank->target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - for (i = first; i <= last; i++) - sectors |= str7x_info->sector_bits[i]; - - LOG_DEBUG("sectors: 0x%" PRIx32 "", sectors); - - /* clear FLASH_ER register */ - err = target_write_u32(target, str7x_get_flash_adr(bank, FLASH_ER), 0x0); - if (err != ERROR_OK) - return err; - - cmd = FLASH_SER; - err = target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd); - if (err != ERROR_OK) - return err; - - cmd = sectors; - err = target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR1), cmd); - if (err != ERROR_OK) - return err; - - cmd = FLASH_SER | FLASH_WMS; - err = target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd); - if (err != ERROR_OK) - return err; - - err = str7x_waitbusy(bank); - if (err != ERROR_OK) - return err; - - err = str7x_result(bank); - if (err != ERROR_OK) - return err; - - for (i = first; i <= last; i++) - bank->sectors[i].is_erased = 1; - - return ERROR_OK; -} - -static int str7x_protect(struct flash_bank *bank, int set, int first, int last) -{ - struct str7x_flash_bank *str7x_info = bank->driver_priv; - struct target *target = bank->target; - int i; - uint32_t cmd; - uint32_t protect_blocks; - - if (bank->target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - protect_blocks = 0xFFFFFFFF; - - if (set) { - for (i = first; i <= last; i++) - protect_blocks &= ~(str7x_info->sector_bits[i]); - } - - /* clear FLASH_ER register */ - int err; - err = target_write_u32(target, str7x_get_flash_adr(bank, FLASH_ER), 0x0); - if (err != ERROR_OK) - return err; - - cmd = FLASH_SPR; - err = target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd); - if (err != ERROR_OK) - return err; - - cmd = str7x_get_flash_adr(bank, FLASH_NVWPAR); - err = target_write_u32(target, str7x_get_flash_adr(bank, FLASH_AR), cmd); - if (err != ERROR_OK) - return err; - - cmd = protect_blocks; - err = target_write_u32(target, str7x_get_flash_adr(bank, FLASH_DR0), cmd); - if (err != ERROR_OK) - return err; - - cmd = FLASH_SPR | FLASH_WMS; - err = target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd); - if (err != ERROR_OK) - return err; - - err = str7x_waitbusy(bank); - if (err != ERROR_OK) - return err; - - err = str7x_result(bank); - if (err != ERROR_OK) - return err; - - return ERROR_OK; -} - -static int str7x_write_block(struct flash_bank *bank, const uint8_t *buffer, - uint32_t offset, uint32_t count) -{ - struct str7x_flash_bank *str7x_info = bank->driver_priv; - struct target *target = bank->target; - uint32_t buffer_size = 32768; - struct working_area *write_algorithm; - struct working_area *source; - uint32_t address = bank->base + offset; - struct reg_param reg_params[6]; - struct arm_algorithm arm_algo; - int retval = ERROR_OK; - - /* see contib/loaders/flash/str7x.s for src */ - - static const uint32_t str7x_flash_write_code[] = { - /* write: */ - 0xe3a04201, /* mov r4, #0x10000000 */ - 0xe5824000, /* str r4, [r2, #0x0] */ - 0xe5821010, /* str r1, [r2, #0x10] */ - 0xe4904004, /* ldr r4, [r0], #4 */ - 0xe5824008, /* str r4, [r2, #0x8] */ - 0xe4904004, /* ldr r4, [r0], #4 */ - 0xe582400c, /* str r4, [r2, #0xc] */ - 0xe3a04209, /* mov r4, #0x90000000 */ - 0xe5824000, /* str r4, [r2, #0x0] */ - /* busy: */ - 0xe5924000, /* ldr r4, [r2, #0x0] */ - 0xe1140005, /* tst r4, r5 */ - 0x1afffffc, /* bne busy */ - 0xe5924014, /* ldr r4, [r2, #0x14] */ - 0xe31400ff, /* tst r4, #0xff */ - 0x03140c01, /* tsteq r4, #0x100 */ - 0x1a000002, /* bne exit */ - 0xe2811008, /* add r1, r1, #0x8 */ - 0xe2533001, /* subs r3, r3, #1 */ - 0x1affffec, /* bne write */ - /* exit: */ - 0xeafffffe, /* b exit */ - }; - - /* flash write code */ - 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), - str7x_flash_write_code); - target_write_buffer(target, write_algorithm->address, sizeof(code), code); - - /* memory buffer */ - while (target_alloc_working_area_try(target, buffer_size, &source) != ERROR_OK) { - buffer_size /= 2; - if (buffer_size <= 256) { - /* we already allocated the writing code, but failed to get a - * buffer, free the algorithm */ - target_free_working_area(target, write_algorithm); - - LOG_WARNING("no large enough working area available, can't do block memory writes"); - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - } - } - - arm_algo.common_magic = ARM_COMMON_MAGIC; - arm_algo.core_mode = ARM_MODE_SVC; - arm_algo.core_state = ARM_STATE_ARM; - - init_reg_param(®_params[0], "r0", 32, PARAM_OUT); - init_reg_param(®_params[1], "r1", 32, PARAM_OUT); - 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_IN); - init_reg_param(®_params[5], "r5", 32, PARAM_OUT); - - while (count > 0) { - uint32_t thisrun_count = (count > (buffer_size / 8)) ? (buffer_size / 8) : count; - - target_write_buffer(target, source->address, thisrun_count * 8, buffer); - - 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, str7x_get_flash_adr(bank, FLASH_CR0)); - buf_set_u32(reg_params[3].value, 0, 32, thisrun_count); - buf_set_u32(reg_params[5].value, 0, 32, str7x_info->busy_bits); - - retval = target_run_algorithm(target, 0, NULL, 6, reg_params, - write_algorithm->address, - write_algorithm->address + (sizeof(str7x_flash_write_code) - 4), - 10000, &arm_algo); - if (retval != ERROR_OK) - break; - - if (buf_get_u32(reg_params[4].value, 0, 32) != 0x00) { - retval = str7x_result(bank); - break; - } - - buffer += thisrun_count * 8; - address += thisrun_count * 8; - count -= thisrun_count; - } - - target_free_working_area(target, source); - target_free_working_area(target, write_algorithm); - - 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]); - destroy_reg_param(®_params[5]); - - return retval; -} - -static int str7x_write(struct flash_bank *bank, const uint8_t *buffer, - uint32_t offset, uint32_t count) -{ - struct target *target = bank->target; - uint32_t dwords_remaining = (count / 8); - uint32_t bytes_remaining = (count & 0x00000007); - uint32_t address = bank->base + offset; - uint32_t bytes_written = 0; - uint32_t cmd; - int retval; - uint32_t check_address = offset; - int i; - - if (bank->target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - if (offset & 0x7) { - LOG_WARNING("offset 0x%" PRIx32 " breaks required 8-byte alignment", offset); - return ERROR_FLASH_DST_BREAKS_ALIGNMENT; - } - - for (i = 0; i < bank->num_sectors; i++) { - uint32_t sec_start = bank->sectors[i].offset; - uint32_t sec_end = sec_start + bank->sectors[i].size; - - /* check if destination falls within the current sector */ - if ((check_address >= sec_start) && (check_address < sec_end)) { - /* check if destination ends in the current sector */ - if (offset + count < sec_end) - check_address = offset + count; - else - check_address = sec_end; - } - } - - if (check_address != offset + count) - return ERROR_FLASH_DST_OUT_OF_BANK; - - /* clear FLASH_ER register */ - target_write_u32(target, str7x_get_flash_adr(bank, FLASH_ER), 0x0); - - /* multiple dwords (8-byte) to be programmed? */ - if (dwords_remaining > 0) { - /* try using a block write */ - retval = str7x_write_block(bank, buffer, offset, dwords_remaining); - if (retval != ERROR_OK) { - if (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE) { - /* if block write failed (no sufficient working area), - * we use normal (slow) single dword accesses */ - LOG_WARNING("couldn't use block writes, falling back to single memory accesses"); - } else { - return retval; - } - } else { - buffer += dwords_remaining * 8; - address += dwords_remaining * 8; - dwords_remaining = 0; - } - } - - while (dwords_remaining > 0) { - /* command */ - cmd = FLASH_DWPG; - target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd); - - /* address */ - target_write_u32(target, str7x_get_flash_adr(bank, FLASH_AR), address); - - /* data word 1 */ - target_write_memory(target, str7x_get_flash_adr(bank, FLASH_DR0), - 4, 1, buffer + bytes_written); - bytes_written += 4; - - /* data word 2 */ - target_write_memory(target, str7x_get_flash_adr(bank, FLASH_DR1), - 4, 1, buffer + bytes_written); - bytes_written += 4; - - /* start programming cycle */ - cmd = FLASH_DWPG | FLASH_WMS; - target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd); - - int err; - err = str7x_waitbusy(bank); - if (err != ERROR_OK) - return err; - - err = str7x_result(bank); - if (err != ERROR_OK) - return err; - - dwords_remaining--; - address += 8; - } - - if (bytes_remaining) { - uint8_t last_dword[8] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; - - /* copy the last remaining bytes into the write buffer */ - memcpy(last_dword, buffer+bytes_written, bytes_remaining); - - /* command */ - cmd = FLASH_DWPG; - target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd); - - /* address */ - target_write_u32(target, str7x_get_flash_adr(bank, FLASH_AR), address); - - /* data word 1 */ - target_write_memory(target, str7x_get_flash_adr(bank, FLASH_DR0), - 4, 1, last_dword); - - /* data word 2 */ - target_write_memory(target, str7x_get_flash_adr(bank, FLASH_DR1), - 4, 1, last_dword + 4); - - /* start programming cycle */ - cmd = FLASH_DWPG | FLASH_WMS; - target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd); - - int err; - err = str7x_waitbusy(bank); - if (err != ERROR_OK) - return err; - - err = str7x_result(bank); - if (err != ERROR_OK) - return err; - } - - return ERROR_OK; -} - -static int str7x_probe(struct flash_bank *bank) -{ - return ERROR_OK; -} - -#if 0 -COMMAND_HANDLER(str7x_handle_part_id_command) -{ - return ERROR_OK; -} -#endif - -static int get_str7x_info(struct flash_bank *bank, char *buf, int buf_size) -{ - /* Setting the write protection on a sector is a permanent change but it - * can be disabled temporarily. FLASH_NVWPAR reflects the permanent - * protection state of the sectors, not the temporary. - */ - snprintf(buf, buf_size, "STR7x flash protection info is only valid after a power cycle, " - "clearing the protection is only temporary and may not be reflected in the current " - "info returned."); - return ERROR_OK; -} - -COMMAND_HANDLER(str7x_handle_disable_jtag_command) -{ - struct target *target = NULL; - struct str7x_flash_bank *str7x_info = NULL; - - uint32_t flash_cmd; - uint16_t ProtectionLevel = 0; - uint16_t ProtectionRegs; - - 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; - - str7x_info = bank->driver_priv; - - target = bank->target; - - if (target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - /* first we get protection status */ - uint32_t reg; - target_read_u32(target, str7x_get_flash_adr(bank, FLASH_NVAPR0), ®); - - if (!(reg & str7x_info->disable_bit)) - ProtectionLevel = 1; - - target_read_u32(target, str7x_get_flash_adr(bank, FLASH_NVAPR1), ®); - ProtectionRegs = ~(reg >> 16); - - while (((ProtectionRegs) != 0) && (ProtectionLevel < 16)) { - ProtectionRegs >>= 1; - ProtectionLevel++; - } - - if (ProtectionLevel == 0) { - flash_cmd = FLASH_SPR; - target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), flash_cmd); - target_write_u32(target, str7x_get_flash_adr(bank, FLASH_AR), 0x4010DFB8); - target_write_u32(target, str7x_get_flash_adr(bank, FLASH_DR0), 0xFFFFFFFD); - flash_cmd = FLASH_SPR | FLASH_WMS; - target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), flash_cmd); - } else { - flash_cmd = FLASH_SPR; - target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), flash_cmd); - target_write_u32(target, str7x_get_flash_adr(bank, FLASH_AR), 0x4010DFBC); - target_write_u32(target, str7x_get_flash_adr(bank, FLASH_DR0), - ~(1 << (15 + ProtectionLevel))); - flash_cmd = FLASH_SPR | FLASH_WMS; - target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), flash_cmd); - } - - return ERROR_OK; -} - -static const struct command_registration str7x_exec_command_handlers[] = { - { - .name = "disable_jtag", - .usage = "", - .handler = str7x_handle_disable_jtag_command, - .mode = COMMAND_EXEC, - .help = "disable jtag access", - }, - COMMAND_REGISTRATION_DONE -}; - -static const struct command_registration str7x_command_handlers[] = { - { - .name = "str7x", - .mode = COMMAND_ANY, - .help = "str7x flash command group", - .usage = "", - .chain = str7x_exec_command_handlers, - }, - COMMAND_REGISTRATION_DONE -}; - -struct flash_driver str7x_flash = { - .name = "str7x", - .commands = str7x_command_handlers, - .flash_bank_command = str7x_flash_bank_command, - .erase = str7x_erase, - .protect = str7x_protect, - .write = str7x_write, - .read = default_flash_read, - .probe = str7x_probe, - .auto_probe = str7x_probe, - .erase_check = default_flash_blank_check, - .protect_check = str7x_protect_check, - .info = get_str7x_info, -}; diff --git a/src/flash/nor/str9x.c b/src/flash/nor/str9x.c deleted file mode 100644 index 3b7ca2aa7..000000000 --- a/src/flash/nor/str9x.c +++ /dev/null @@ -1,682 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * Copyright (C) 2008 by Spencer Oliver * - * spen@spen-soft.co.uk * - * - * Copyright (C) 2008 by Oyvind Harboe * - * oyvind.harboe@zylin.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "imp.h" -#include -#include - -/* Flash registers */ - -#define FLASH_BBSR 0x54000000 /* Boot Bank Size Register */ -#define FLASH_NBBSR 0x54000004 /* Non-Boot Bank Size Register */ -#define FLASH_BBADR 0x5400000C /* Boot Bank Base Address Register */ -#define FLASH_NBBADR 0x54000010 /* Non-Boot Bank Base Address Register */ -#define FLASH_CR 0x54000018 /* Control Register */ -#define FLASH_SR 0x5400001C /* Status Register */ -#define FLASH_BCE5ADDR 0x54000020 /* BC Fifth Entry Target Address Register */ - -struct str9x_flash_bank { - uint32_t *sector_bits; - int variant; - int bank1; -}; - -enum str9x_status_codes { - STR9X_CMD_SUCCESS = 0, - STR9X_INVALID_COMMAND = 1, - STR9X_SRC_ADDR_ERROR = 2, - STR9X_DST_ADDR_ERROR = 3, - STR9X_SRC_ADDR_NOT_MAPPED = 4, - STR9X_DST_ADDR_NOT_MAPPED = 5, - STR9X_COUNT_ERROR = 6, - STR9X_INVALID_SECTOR = 7, - STR9X_SECTOR_NOT_BLANK = 8, - STR9X_SECTOR_NOT_PREPARED = 9, - STR9X_COMPARE_ERROR = 10, - STR9X_BUSY = 11 -}; - -static uint32_t bank1start = 0x00080000; - -static int str9x_build_block_list(struct flash_bank *bank) -{ - struct str9x_flash_bank *str9x_info = bank->driver_priv; - - int i; - int num_sectors; - int b0_sectors = 0, b1_sectors = 0; - uint32_t offset = 0; - - /* set if we have large flash str9 */ - str9x_info->variant = 0; - str9x_info->bank1 = 0; - - switch (bank->size) { - case (256 * 1024): - b0_sectors = 4; - break; - case (512 * 1024): - b0_sectors = 8; - break; - case (1024 * 1024): - bank1start = 0x00100000; - str9x_info->variant = 1; - b0_sectors = 16; - break; - case (2048 * 1024): - bank1start = 0x00200000; - str9x_info->variant = 1; - b0_sectors = 32; - break; - case (128 * 1024): - str9x_info->variant = 1; - str9x_info->bank1 = 1; - b1_sectors = 8; - bank1start = bank->base; - break; - case (32 * 1024): - str9x_info->bank1 = 1; - b1_sectors = 4; - bank1start = bank->base; - break; - default: - LOG_ERROR("BUG: unknown bank->size encountered"); - exit(-1); - } - - num_sectors = b0_sectors + b1_sectors; - - bank->num_sectors = num_sectors; - bank->sectors = malloc(sizeof(struct flash_sector) * num_sectors); - str9x_info->sector_bits = malloc(sizeof(uint32_t) * num_sectors); - - num_sectors = 0; - - for (i = 0; i < b0_sectors; i++) { - bank->sectors[num_sectors].offset = offset; - bank->sectors[num_sectors].size = 0x10000; - offset += bank->sectors[i].size; - bank->sectors[num_sectors].is_erased = -1; - bank->sectors[num_sectors].is_protected = 1; - str9x_info->sector_bits[num_sectors++] = (1 << i); - } - - for (i = 0; i < b1_sectors; i++) { - bank->sectors[num_sectors].offset = offset; - bank->sectors[num_sectors].size = str9x_info->variant == 0 ? 0x2000 : 0x4000; - offset += bank->sectors[i].size; - bank->sectors[num_sectors].is_erased = -1; - bank->sectors[num_sectors].is_protected = 1; - if (str9x_info->variant) - str9x_info->sector_bits[num_sectors++] = (1 << i); - else - str9x_info->sector_bits[num_sectors++] = (1 << (i + 8)); - } - - return ERROR_OK; -} - -/* flash bank str9x 0 0 - */ -FLASH_BANK_COMMAND_HANDLER(str9x_flash_bank_command) -{ - struct str9x_flash_bank *str9x_info; - - if (CMD_ARGC < 6) - return ERROR_COMMAND_SYNTAX_ERROR; - - str9x_info = malloc(sizeof(struct str9x_flash_bank)); - bank->driver_priv = str9x_info; - - str9x_build_block_list(bank); - - return ERROR_OK; -} - -static int str9x_protect_check(struct flash_bank *bank) -{ - int retval; - struct str9x_flash_bank *str9x_info = bank->driver_priv; - struct target *target = bank->target; - - int i; - uint32_t adr; - uint32_t status = 0; - uint16_t hstatus = 0; - - if (bank->target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - /* read level one protection */ - - if (str9x_info->variant) { - if (str9x_info->bank1) { - adr = bank1start + 0x18; - retval = target_write_u16(target, adr, 0x90); - if (retval != ERROR_OK) - return retval; - retval = target_read_u16(target, adr, &hstatus); - if (retval != ERROR_OK) - return retval; - status = hstatus; - } else { - adr = bank1start + 0x14; - retval = target_write_u16(target, adr, 0x90); - if (retval != ERROR_OK) - return retval; - retval = target_read_u32(target, adr, &status); - if (retval != ERROR_OK) - return retval; - } - } else { - adr = bank1start + 0x10; - retval = target_write_u16(target, adr, 0x90); - if (retval != ERROR_OK) - return retval; - retval = target_read_u16(target, adr, &hstatus); - if (retval != ERROR_OK) - return retval; - status = hstatus; - } - - /* read array command */ - retval = target_write_u16(target, adr, 0xFF); - if (retval != ERROR_OK) - return retval; - - for (i = 0; i < bank->num_sectors; i++) { - if (status & str9x_info->sector_bits[i]) - bank->sectors[i].is_protected = 1; - else - bank->sectors[i].is_protected = 0; - } - - return ERROR_OK; -} - -static int str9x_erase(struct flash_bank *bank, int first, int last) -{ - struct target *target = bank->target; - int i; - uint32_t adr; - uint8_t status; - uint8_t erase_cmd; - int total_timeout; - - if (bank->target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - /* Check if we can erase whole bank */ - if ((first == 0) && (last == (bank->num_sectors - 1))) { - /* Optimize to run erase bank command instead of sector */ - erase_cmd = 0x80; - /* Add timeout duration since erase bank takes more time */ - total_timeout = 1000 * bank->num_sectors; - } else { - /* Erase sector command */ - erase_cmd = 0x20; - total_timeout = 1000; - } - - /* this is so the compiler can *know* */ - assert(total_timeout > 0); - - for (i = first; i <= last; i++) { - int retval; - adr = bank->base + bank->sectors[i].offset; - - /* erase sectors or block */ - retval = target_write_u16(target, adr, erase_cmd); - if (retval != ERROR_OK) - return retval; - retval = target_write_u16(target, adr, 0xD0); - if (retval != ERROR_OK) - return retval; - - /* get status */ - retval = target_write_u16(target, adr, 0x70); - if (retval != ERROR_OK) - return retval; - - int timeout; - for (timeout = 0; timeout < total_timeout; timeout++) { - retval = target_read_u8(target, adr, &status); - if (retval != ERROR_OK) - return retval; - if (status & 0x80) - break; - alive_sleep(1); - } - if (timeout == total_timeout) { - LOG_ERROR("erase timed out"); - return ERROR_FAIL; - } - - /* clear status, also clear read array */ - retval = target_write_u16(target, adr, 0x50); - if (retval != ERROR_OK) - return retval; - - /* read array command */ - retval = target_write_u16(target, adr, 0xFF); - if (retval != ERROR_OK) - return retval; - - if (status & 0x22) { - LOG_ERROR("error erasing flash bank, status: 0x%x", status); - return ERROR_FLASH_OPERATION_FAILED; - } - - /* If we ran erase bank command, we are finished */ - if (erase_cmd == 0x80) - break; - } - - for (i = first; i <= last; i++) - bank->sectors[i].is_erased = 1; - - return ERROR_OK; -} - -static int str9x_protect(struct flash_bank *bank, - int set, int first, int last) -{ - struct target *target = bank->target; - int i; - uint32_t adr; - uint8_t status; - - if (bank->target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - for (i = first; i <= last; i++) { - /* Level One Protection */ - - adr = bank->base + bank->sectors[i].offset; - - target_write_u16(target, adr, 0x60); - if (set) - target_write_u16(target, adr, 0x01); - else - target_write_u16(target, adr, 0xD0); - - /* query status */ - target_read_u8(target, adr, &status); - - /* clear status, also clear read array */ - target_write_u16(target, adr, 0x50); - - /* read array command */ - target_write_u16(target, adr, 0xFF); - } - - return ERROR_OK; -} - -static int str9x_write_block(struct flash_bank *bank, - const uint8_t *buffer, uint32_t offset, uint32_t count) -{ - struct target *target = bank->target; - uint32_t buffer_size = 32768; - struct working_area *write_algorithm; - struct working_area *source; - uint32_t address = bank->base + offset; - struct reg_param reg_params[4]; - struct arm_algorithm arm_algo; - int retval = ERROR_OK; - - /* see contib/loaders/flash/str9x.s for src */ - - static const uint32_t str9x_flash_write_code[] = { - /* write: */ - 0xe3c14003, /* bic r4, r1, #3 */ - 0xe3a03040, /* mov r3, #0x40 */ - 0xe1c430b0, /* strh r3, [r4, #0] */ - 0xe0d030b2, /* ldrh r3, [r0], #2 */ - 0xe0c130b2, /* strh r3, [r1], #2 */ - 0xe3a03070, /* mov r3, #0x70 */ - 0xe1c430b0, /* strh r3, [r4, #0] */ - /* busy: */ - 0xe5d43000, /* ldrb r3, [r4, #0] */ - 0xe3130080, /* tst r3, #0x80 */ - 0x0afffffc, /* beq busy */ - 0xe3a05050, /* mov r5, #0x50 */ - 0xe1c450b0, /* strh r5, [r4, #0] */ - 0xe3a050ff, /* mov r5, #0xFF */ - 0xe1c450b0, /* strh r5, [r4, #0] */ - 0xe3130012, /* tst r3, #0x12 */ - 0x1a000001, /* bne exit */ - 0xe2522001, /* subs r2, r2, #1 */ - 0x1affffed, /* bne write */ - /* exit: */ - 0xe1200070, /* bkpt #0 */ - }; - - /* flash write code */ - if (target_alloc_working_area(target, sizeof(str9x_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; - } - - uint8_t code[sizeof(str9x_flash_write_code)]; - target_buffer_set_u32_array(target, code, ARRAY_SIZE(str9x_flash_write_code), - str9x_flash_write_code); - target_write_buffer(target, write_algorithm->address, sizeof(code), code); - - /* memory buffer */ - while (target_alloc_working_area_try(target, buffer_size, &source) != ERROR_OK) { - buffer_size /= 2; - if (buffer_size <= 256) { - /* we already allocated the writing code, but failed to get a - * buffer, free the algorithm */ - target_free_working_area(target, write_algorithm); - - LOG_WARNING("no large enough working area available, can't do block memory writes"); - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - } - } - - arm_algo.common_magic = ARM_COMMON_MAGIC; - arm_algo.core_mode = ARM_MODE_SVC; - arm_algo.core_state = ARM_STATE_ARM; - - init_reg_param(®_params[0], "r0", 32, PARAM_OUT); - init_reg_param(®_params[1], "r1", 32, PARAM_OUT); - init_reg_param(®_params[2], "r2", 32, PARAM_OUT); - init_reg_param(®_params[3], "r3", 32, PARAM_IN); - - while (count > 0) { - uint32_t thisrun_count = (count > (buffer_size / 2)) ? (buffer_size / 2) : count; - - target_write_buffer(target, source->address, thisrun_count * 2, buffer); - - 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); - - retval = target_run_algorithm(target, 0, NULL, 4, reg_params, - write_algorithm->address, - 0, 10000, &arm_algo); - if (retval != ERROR_OK) { - LOG_ERROR("error executing str9x flash write algorithm"); - retval = ERROR_FLASH_OPERATION_FAILED; - break; - } - - if (buf_get_u32(reg_params[3].value, 0, 32) != 0x80) { - retval = ERROR_FLASH_OPERATION_FAILED; - break; - } - - buffer += thisrun_count * 2; - address += thisrun_count * 2; - count -= thisrun_count; - } - - target_free_working_area(target, source); - target_free_working_area(target, write_algorithm); - - destroy_reg_param(®_params[0]); - destroy_reg_param(®_params[1]); - destroy_reg_param(®_params[2]); - destroy_reg_param(®_params[3]); - - return retval; -} - -static int str9x_write(struct flash_bank *bank, - const uint8_t *buffer, uint32_t offset, uint32_t count) -{ - struct target *target = bank->target; - uint32_t words_remaining = (count / 2); - uint32_t bytes_remaining = (count & 0x00000001); - uint32_t address = bank->base + offset; - uint32_t bytes_written = 0; - uint8_t status; - int retval; - uint32_t check_address = offset; - uint32_t bank_adr; - int i; - - if (bank->target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - if (offset & 0x1) { - LOG_WARNING("offset 0x%" PRIx32 " breaks required 2-byte alignment", offset); - return ERROR_FLASH_DST_BREAKS_ALIGNMENT; - } - - for (i = 0; i < bank->num_sectors; i++) { - uint32_t sec_start = bank->sectors[i].offset; - uint32_t sec_end = sec_start + bank->sectors[i].size; - - /* check if destination falls within the current sector */ - if ((check_address >= sec_start) && (check_address < sec_end)) { - /* check if destination ends in the current sector */ - if (offset + count < sec_end) - check_address = offset + count; - else - check_address = sec_end; - } - } - - if (check_address != offset + count) - return ERROR_FLASH_DST_OUT_OF_BANK; - - /* multiple half words (2-byte) to be programmed? */ - if (words_remaining > 0) { - /* try using a block write */ - retval = str9x_write_block(bank, buffer, offset, words_remaining); - if (retval != ERROR_OK) { - if (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE) { - /* if block write failed (no sufficient working area), - * we use normal (slow) single dword accesses */ - LOG_WARNING("couldn't use block writes, falling back to single memory accesses"); - } else if (retval == ERROR_FLASH_OPERATION_FAILED) { - LOG_ERROR("flash writing failed"); - return ERROR_FLASH_OPERATION_FAILED; - } - } else { - buffer += words_remaining * 2; - address += words_remaining * 2; - words_remaining = 0; - } - } - - while (words_remaining > 0) { - bank_adr = address & ~0x03; - - /* write data command */ - target_write_u16(target, bank_adr, 0x40); - target_write_memory(target, address, 2, 1, buffer + bytes_written); - - /* get status command */ - target_write_u16(target, bank_adr, 0x70); - - int timeout; - for (timeout = 0; timeout < 1000; timeout++) { - target_read_u8(target, bank_adr, &status); - if (status & 0x80) - break; - alive_sleep(1); - } - if (timeout == 1000) { - LOG_ERROR("write timed out"); - return ERROR_FAIL; - } - - /* clear status reg and read array */ - target_write_u16(target, bank_adr, 0x50); - target_write_u16(target, bank_adr, 0xFF); - - if (status & 0x10) - return ERROR_FLASH_OPERATION_FAILED; - else if (status & 0x02) - return ERROR_FLASH_OPERATION_FAILED; - - bytes_written += 2; - words_remaining--; - address += 2; - } - - if (bytes_remaining) { - uint8_t last_halfword[2] = {0xff, 0xff}; - - /* copy the last remaining bytes into the write buffer */ - memcpy(last_halfword, buffer+bytes_written, bytes_remaining); - - bank_adr = address & ~0x03; - - /* write data command */ - target_write_u16(target, bank_adr, 0x40); - target_write_memory(target, address, 2, 1, last_halfword); - - /* query status command */ - target_write_u16(target, bank_adr, 0x70); - - int timeout; - for (timeout = 0; timeout < 1000; timeout++) { - target_read_u8(target, bank_adr, &status); - if (status & 0x80) - break; - alive_sleep(1); - } - if (timeout == 1000) { - LOG_ERROR("write timed out"); - return ERROR_FAIL; - } - - /* clear status reg and read array */ - target_write_u16(target, bank_adr, 0x50); - target_write_u16(target, bank_adr, 0xFF); - - if (status & 0x10) - return ERROR_FLASH_OPERATION_FAILED; - else if (status & 0x02) - return ERROR_FLASH_OPERATION_FAILED; - } - - return ERROR_OK; -} - -static int str9x_probe(struct flash_bank *bank) -{ - return ERROR_OK; -} - -#if 0 -COMMAND_HANDLER(str9x_handle_part_id_command) -{ - return ERROR_OK; -} -#endif - -COMMAND_HANDLER(str9x_handle_flash_config_command) -{ - struct target *target = NULL; - - if (CMD_ARGC < 5) - 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; - - uint32_t bbsr, nbbsr, bbadr, nbbadr; - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], bbsr); - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], nbbsr); - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[3], bbadr); - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[4], nbbadr); - - target = bank->target; - - if (bank->target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - /* config flash controller */ - target_write_u32(target, FLASH_BBSR, bbsr); - target_write_u32(target, FLASH_NBBSR, nbbsr); - target_write_u32(target, FLASH_BBADR, bbadr >> 2); - target_write_u32(target, FLASH_NBBADR, nbbadr >> 2); - - /* set bit 18 instruction TCM order as per flash programming manual */ - arm966e_write_cp15(target, 62, 0x40000); - - /* enable flash bank 1 */ - target_write_u32(target, FLASH_CR, 0x18); - return ERROR_OK; -} - -static const struct command_registration str9x_config_command_handlers[] = { - { - .name = "flash_config", - .handler = str9x_handle_flash_config_command, - .mode = COMMAND_EXEC, - .help = "Configure str9x flash controller, prior to " - "programming the flash.", - .usage = "bank_id BBSR NBBSR BBADR NBBADR", - }, - COMMAND_REGISTRATION_DONE -}; - -static const struct command_registration str9x_command_handlers[] = { - { - .name = "str9x", - .mode = COMMAND_ANY, - .help = "str9x flash command group", - .usage = "", - .chain = str9x_config_command_handlers, - }, - COMMAND_REGISTRATION_DONE -}; - -struct flash_driver str9x_flash = { - .name = "str9x", - .commands = str9x_command_handlers, - .flash_bank_command = str9x_flash_bank_command, - .erase = str9x_erase, - .protect = str9x_protect, - .write = str9x_write, - .read = default_flash_read, - .probe = str9x_probe, - .auto_probe = str9x_probe, - .erase_check = default_flash_blank_check, - .protect_check = str9x_protect_check, -}; diff --git a/src/flash/nor/str9xpec.c b/src/flash/nor/str9xpec.c deleted file mode 100644 index eb391e8fb..000000000 --- a/src/flash/nor/str9xpec.c +++ /dev/null @@ -1,1210 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * Copyright (C) 2008 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "imp.h" -#include - -/* ISC commands */ - -#define ISC_IDCODE 0xFE -#define ISC_MFG_READ 0x4C -#define ISC_CONFIGURATION 0x07 -#define ISC_ENABLE 0x0C -#define ISC_DISABLE 0x0F -#define ISC_NOOP 0x10 -#define ISC_ADDRESS_SHIFT 0x11 -#define ISC_CLR_STATUS 0x13 -#define ISC_PROGRAM 0x20 -#define ISC_PROGRAM_SECURITY 0x22 -#define ISC_PROGRAM_UC 0x23 -#define ISC_ERASE 0x30 -#define ISC_READ 0x50 -#define ISC_BLANK_CHECK 0x60 - -/* ISC_DEFAULT bit definitions */ - -#define ISC_STATUS_SECURITY 0x40 -#define ISC_STATUS_INT_ERROR 0x30 -#define ISC_STATUS_MODE 0x08 -#define ISC_STATUS_BUSY 0x04 -#define ISC_STATUS_ERROR 0x03 - -/* Option bytes definitions */ - -#define STR9XPEC_OPT_CSMAPBIT 48 -#define STR9XPEC_OPT_LVDTHRESBIT 49 -#define STR9XPEC_OPT_LVDSELBIT 50 -#define STR9XPEC_OPT_LVDWARNBIT 51 -#define STR9XPEC_OPT_OTPBIT 63 - -enum str9xpec_status_codes { - STR9XPEC_INVALID_COMMAND = 1, - STR9XPEC_ISC_SUCCESS = 2, - STR9XPEC_ISC_DISABLED = 3, - STR9XPEC_ISC_INTFAIL = 32, -}; - -struct str9xpec_flash_controller { - struct jtag_tap *tap; - uint32_t *sector_bits; - int chain_pos; - int isc_enable; - uint8_t options[8]; -}; - -static int str9xpec_erase_area(struct flash_bank *bank, int first, int last); -static int str9xpec_set_address(struct flash_bank *bank, uint8_t sector); -static int str9xpec_write_options(struct flash_bank *bank); - -static int str9xpec_set_instr(struct jtag_tap *tap, uint32_t new_instr, tap_state_t end_state) -{ - if (tap == NULL) - return ERROR_TARGET_INVALID; - - if (buf_get_u32(tap->cur_instr, 0, tap->ir_length) != new_instr) { - struct scan_field field; - - field.num_bits = tap->ir_length; - void *t = calloc(DIV_ROUND_UP(field.num_bits, 8), 1); - field.out_value = t; - buf_set_u32(t, 0, field.num_bits, new_instr); - field.in_value = NULL; - - jtag_add_ir_scan(tap, &field, end_state); - - free(t); - } - - return ERROR_OK; -} - -static uint8_t str9xpec_isc_status(struct jtag_tap *tap) -{ - struct scan_field field; - uint8_t status; - - if (str9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE) != ERROR_OK) - return ISC_STATUS_ERROR; - - field.num_bits = 8; - field.out_value = NULL; - field.in_value = &status; - - - jtag_add_dr_scan(tap, 1, &field, TAP_IDLE); - jtag_execute_queue(); - - LOG_DEBUG("status: 0x%2.2x", status); - - if (status & ISC_STATUS_SECURITY) - LOG_INFO("Device Security Bit Set"); - - return status; -} - -static int str9xpec_isc_enable(struct flash_bank *bank) -{ - uint8_t status; - struct jtag_tap *tap; - struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv; - - tap = str9xpec_info->tap; - - if (str9xpec_info->isc_enable) - return ERROR_OK; - - /* enter isc mode */ - if (str9xpec_set_instr(tap, ISC_ENABLE, TAP_IDLE) != ERROR_OK) - return ERROR_TARGET_INVALID; - - /* check ISC status */ - status = str9xpec_isc_status(tap); - if (status & ISC_STATUS_MODE) { - /* we have entered isc mode */ - str9xpec_info->isc_enable = 1; - LOG_DEBUG("ISC_MODE Enabled"); - } - - return ERROR_OK; -} - -static int str9xpec_isc_disable(struct flash_bank *bank) -{ - uint8_t status; - struct jtag_tap *tap; - struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv; - - tap = str9xpec_info->tap; - - if (!str9xpec_info->isc_enable) - return ERROR_OK; - - if (str9xpec_set_instr(tap, ISC_DISABLE, TAP_IDLE) != ERROR_OK) - return ERROR_TARGET_INVALID; - - /* delay to handle aborts */ - jtag_add_sleep(50); - - /* check ISC status */ - status = str9xpec_isc_status(tap); - if (!(status & ISC_STATUS_MODE)) { - /* we have left isc mode */ - str9xpec_info->isc_enable = 0; - LOG_DEBUG("ISC_MODE Disabled"); - } - - return ERROR_OK; -} - -static int str9xpec_read_config(struct flash_bank *bank) -{ - struct scan_field field; - uint8_t status; - struct jtag_tap *tap; - - struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv; - - tap = str9xpec_info->tap; - - LOG_DEBUG("ISC_CONFIGURATION"); - - /* execute ISC_CONFIGURATION command */ - str9xpec_set_instr(tap, ISC_CONFIGURATION, TAP_IRPAUSE); - - field.num_bits = 64; - field.out_value = NULL; - field.in_value = str9xpec_info->options; - - jtag_add_dr_scan(tap, 1, &field, TAP_IDLE); - jtag_execute_queue(); - - status = str9xpec_isc_status(tap); - - return status; -} - -static int str9xpec_build_block_list(struct flash_bank *bank) -{ - struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv; - - int i; - int num_sectors; - int b0_sectors = 0, b1_sectors = 0; - uint32_t offset = 0; - int b1_size = 0x2000; - - switch (bank->size) { - case (256 * 1024): - b0_sectors = 4; - break; - case (512 * 1024): - b0_sectors = 8; - break; - case (1024 * 1024): - b0_sectors = 16; - break; - case (2048 * 1024): - b0_sectors = 32; - break; - case (128 * 1024): - b1_size = 0x4000; - b1_sectors = 8; - break; - case (32 * 1024): - b1_sectors = 4; - break; - default: - LOG_ERROR("BUG: unknown bank->size encountered"); - exit(-1); - } - - num_sectors = b0_sectors + b1_sectors; - - bank->num_sectors = num_sectors; - bank->sectors = malloc(sizeof(struct flash_sector) * num_sectors); - str9xpec_info->sector_bits = malloc(sizeof(uint32_t) * num_sectors); - - num_sectors = 0; - - for (i = 0; i < b0_sectors; i++) { - bank->sectors[num_sectors].offset = offset; - bank->sectors[num_sectors].size = 0x10000; - offset += bank->sectors[i].size; - bank->sectors[num_sectors].is_erased = -1; - bank->sectors[num_sectors].is_protected = 1; - str9xpec_info->sector_bits[num_sectors++] = i; - } - - for (i = 0; i < b1_sectors; i++) { - bank->sectors[num_sectors].offset = offset; - bank->sectors[num_sectors].size = b1_size; - offset += bank->sectors[i].size; - bank->sectors[num_sectors].is_erased = -1; - bank->sectors[num_sectors].is_protected = 1; - str9xpec_info->sector_bits[num_sectors++] = i + 32; - } - - return ERROR_OK; -} - -/* flash bank str9x 0 0 - */ -FLASH_BANK_COMMAND_HANDLER(str9xpec_flash_bank_command) -{ - struct str9xpec_flash_controller *str9xpec_info; - struct arm *arm = NULL; - struct arm7_9_common *arm7_9 = NULL; - struct arm_jtag *jtag_info = NULL; - - if (CMD_ARGC < 6) - return ERROR_COMMAND_SYNTAX_ERROR; - - str9xpec_info = malloc(sizeof(struct str9xpec_flash_controller)); - bank->driver_priv = str9xpec_info; - - /* REVISIT verify that the jtag position of flash controller is - * right after *THIS* core, which must be a STR9xx core ... - */ - arm = bank->target->arch_info; - arm7_9 = arm->arch_info; - jtag_info = &arm7_9->jtag_info; - - /* The core is the next tap after the flash controller in the chain */ - str9xpec_info->tap = jtag_tap_by_position(jtag_info->tap->abs_chain_position - 1); - str9xpec_info->isc_enable = 0; - - str9xpec_build_block_list(bank); - - /* clear option byte register */ - buf_set_u32(str9xpec_info->options, 0, 64, 0); - - return ERROR_OK; -} - -static int str9xpec_blank_check(struct flash_bank *bank, int first, int last) -{ - struct scan_field field; - uint8_t status; - struct jtag_tap *tap; - int i; - uint8_t *buffer = NULL; - - struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv; - - tap = str9xpec_info->tap; - - if (!str9xpec_info->isc_enable) - str9xpec_isc_enable(bank); - - if (!str9xpec_info->isc_enable) - return ERROR_FLASH_OPERATION_FAILED; - - buffer = calloc(DIV_ROUND_UP(64, 8), 1); - - LOG_DEBUG("blank check: first_bank: %i, last_bank: %i", first, last); - - for (i = first; i <= last; i++) - buf_set_u32(buffer, str9xpec_info->sector_bits[i], 1, 1); - - /* execute ISC_BLANK_CHECK command */ - str9xpec_set_instr(tap, ISC_BLANK_CHECK, TAP_IRPAUSE); - - field.num_bits = 64; - field.out_value = buffer; - field.in_value = NULL; - - jtag_add_dr_scan(tap, 1, &field, TAP_IDLE); - jtag_add_sleep(40000); - - /* read blank check result */ - field.num_bits = 64; - field.out_value = NULL; - field.in_value = buffer; - - jtag_add_dr_scan(tap, 1, &field, TAP_IRPAUSE); - jtag_execute_queue(); - - status = str9xpec_isc_status(tap); - - for (i = first; i <= last; i++) { - if (buf_get_u32(buffer, str9xpec_info->sector_bits[i], 1)) - bank->sectors[i].is_erased = 0; - else - bank->sectors[i].is_erased = 1; - } - - free(buffer); - - str9xpec_isc_disable(bank); - - if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS) - return ERROR_FLASH_OPERATION_FAILED; - return ERROR_OK; -} - -static int str9xpec_protect_check(struct flash_bank *bank) -{ - uint8_t status; - int i; - - struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv; - - status = str9xpec_read_config(bank); - - for (i = 0; i < bank->num_sectors; i++) { - if (buf_get_u32(str9xpec_info->options, str9xpec_info->sector_bits[i], 1)) - bank->sectors[i].is_protected = 1; - else - bank->sectors[i].is_protected = 0; - } - - if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS) - return ERROR_FLASH_OPERATION_FAILED; - return ERROR_OK; -} - -static int str9xpec_erase_area(struct flash_bank *bank, int first, int last) -{ - struct scan_field field; - uint8_t status; - struct jtag_tap *tap; - int i; - uint8_t *buffer = NULL; - - struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv; - - tap = str9xpec_info->tap; - - if (!str9xpec_info->isc_enable) - str9xpec_isc_enable(bank); - - if (!str9xpec_info->isc_enable) - return ISC_STATUS_ERROR; - - buffer = calloc(DIV_ROUND_UP(64, 8), 1); - - LOG_DEBUG("erase: first_bank: %i, last_bank: %i", first, last); - - /* last bank: 0xFF signals a full erase (unlock complete device) */ - /* last bank: 0xFE signals a option byte erase */ - if (last == 0xFF) { - for (i = 0; i < 64; i++) - buf_set_u32(buffer, i, 1, 1); - } else if (last == 0xFE) - buf_set_u32(buffer, 49, 1, 1); - else { - for (i = first; i <= last; i++) - buf_set_u32(buffer, str9xpec_info->sector_bits[i], 1, 1); - } - - LOG_DEBUG("ISC_ERASE"); - - /* execute ISC_ERASE command */ - str9xpec_set_instr(tap, ISC_ERASE, TAP_IRPAUSE); - - field.num_bits = 64; - field.out_value = buffer; - field.in_value = NULL; - - jtag_add_dr_scan(tap, 1, &field, TAP_IDLE); - jtag_execute_queue(); - - jtag_add_sleep(10); - - /* wait for erase completion */ - while (!((status = str9xpec_isc_status(tap)) & ISC_STATUS_BUSY)) - alive_sleep(1); - - free(buffer); - - str9xpec_isc_disable(bank); - - return status; -} - -static int str9xpec_erase(struct flash_bank *bank, int first, int last) -{ - int status; - - status = str9xpec_erase_area(bank, first, last); - - if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS) - return ERROR_FLASH_OPERATION_FAILED; - - return ERROR_OK; -} - -static int str9xpec_lock_device(struct flash_bank *bank) -{ - struct scan_field field; - uint8_t status; - struct jtag_tap *tap; - struct str9xpec_flash_controller *str9xpec_info = NULL; - - str9xpec_info = bank->driver_priv; - tap = str9xpec_info->tap; - - if (!str9xpec_info->isc_enable) - str9xpec_isc_enable(bank); - - if (!str9xpec_info->isc_enable) - return ISC_STATUS_ERROR; - - /* set security address */ - str9xpec_set_address(bank, 0x80); - - /* execute ISC_PROGRAM command */ - str9xpec_set_instr(tap, ISC_PROGRAM_SECURITY, TAP_IDLE); - - str9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE); - - do { - field.num_bits = 8; - field.out_value = NULL; - field.in_value = &status; - - jtag_add_dr_scan(tap, 1, &field, TAP_IDLE); - jtag_execute_queue(); - - } while (!(status & ISC_STATUS_BUSY)); - - str9xpec_isc_disable(bank); - - return status; -} - -static int str9xpec_unlock_device(struct flash_bank *bank) -{ - uint8_t status; - - status = str9xpec_erase_area(bank, 0, 255); - - return status; -} - -static int str9xpec_protect(struct flash_bank *bank, int set, int first, int last) -{ - uint8_t status; - int i; - - struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv; - - status = str9xpec_read_config(bank); - - if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS) - return ERROR_FLASH_OPERATION_FAILED; - - LOG_DEBUG("protect: first_bank: %i, last_bank: %i", first, last); - - /* last bank: 0xFF signals a full device protect */ - if (last == 0xFF) { - if (set) - status = str9xpec_lock_device(bank); - else { - /* perform full erase to unlock device */ - status = str9xpec_unlock_device(bank); - } - } else { - for (i = first; i <= last; i++) { - if (set) - buf_set_u32(str9xpec_info->options, str9xpec_info->sector_bits[i], 1, 1); - else - buf_set_u32(str9xpec_info->options, str9xpec_info->sector_bits[i], 1, 0); - } - - status = str9xpec_write_options(bank); - } - - if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS) - return ERROR_FLASH_OPERATION_FAILED; - - return ERROR_OK; -} - -static int str9xpec_set_address(struct flash_bank *bank, uint8_t sector) -{ - struct jtag_tap *tap; - struct scan_field field; - struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv; - - tap = str9xpec_info->tap; - - /* set flash controller address */ - str9xpec_set_instr(tap, ISC_ADDRESS_SHIFT, TAP_IRPAUSE); - - field.num_bits = 8; - field.out_value = §or; - field.in_value = NULL; - - jtag_add_dr_scan(tap, 1, &field, TAP_IRPAUSE); - - return ERROR_OK; -} - -static int str9xpec_write(struct flash_bank *bank, const uint8_t *buffer, - uint32_t offset, uint32_t count) -{ - struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv; - uint32_t dwords_remaining = (count / 8); - uint32_t bytes_remaining = (count & 0x00000007); - uint32_t bytes_written = 0; - uint8_t status; - uint32_t check_address = offset; - struct jtag_tap *tap; - struct scan_field field; - uint8_t *scanbuf; - int i; - int first_sector = 0; - int last_sector = 0; - - tap = str9xpec_info->tap; - - if (!str9xpec_info->isc_enable) - str9xpec_isc_enable(bank); - - if (!str9xpec_info->isc_enable) - return ERROR_FLASH_OPERATION_FAILED; - - if (offset & 0x7) { - LOG_WARNING("offset 0x%" PRIx32 " breaks required 8-byte alignment", offset); - return ERROR_FLASH_DST_BREAKS_ALIGNMENT; - } - - for (i = 0; i < bank->num_sectors; i++) { - uint32_t sec_start = bank->sectors[i].offset; - uint32_t sec_end = sec_start + bank->sectors[i].size; - - /* check if destination falls within the current sector */ - if ((check_address >= sec_start) && (check_address < sec_end)) { - /* check if destination ends in the current sector */ - if (offset + count < sec_end) - check_address = offset + count; - else - check_address = sec_end; - } - - if ((offset >= sec_start) && (offset < sec_end)) - first_sector = i; - - if ((offset + count >= sec_start) && (offset + count < sec_end)) - last_sector = i; - } - - if (check_address != offset + count) - return ERROR_FLASH_DST_OUT_OF_BANK; - - LOG_DEBUG("first_sector: %i, last_sector: %i", first_sector, last_sector); - - scanbuf = calloc(DIV_ROUND_UP(64, 8), 1); - - LOG_DEBUG("ISC_PROGRAM"); - - for (i = first_sector; i <= last_sector; i++) { - str9xpec_set_address(bank, str9xpec_info->sector_bits[i]); - - dwords_remaining = dwords_remaining < (bank->sectors[i].size/8) - ? dwords_remaining : (bank->sectors[i].size/8); - - while (dwords_remaining > 0) { - str9xpec_set_instr(tap, ISC_PROGRAM, TAP_IRPAUSE); - - field.num_bits = 64; - field.out_value = (buffer + bytes_written); - field.in_value = NULL; - - jtag_add_dr_scan(tap, 1, &field, TAP_IDLE); - - /* small delay before polling */ - jtag_add_sleep(50); - - str9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE); - - do { - field.num_bits = 8; - field.out_value = NULL; - field.in_value = scanbuf; - - jtag_add_dr_scan(tap, 1, &field, TAP_IRPAUSE); - jtag_execute_queue(); - - status = buf_get_u32(scanbuf, 0, 8); - - } while (!(status & ISC_STATUS_BUSY)); - - if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS) - return ERROR_FLASH_OPERATION_FAILED; - - /* if ((status & ISC_STATUS_INT_ERROR) != STR9XPEC_ISC_INTFAIL) - return ERROR_FLASH_OPERATION_FAILED; */ - - dwords_remaining--; - bytes_written += 8; - } - } - - if (bytes_remaining) { - uint8_t last_dword[8] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; - - /* copy the last remaining bytes into the write buffer */ - memcpy(last_dword, buffer+bytes_written, bytes_remaining); - - str9xpec_set_instr(tap, ISC_PROGRAM, TAP_IRPAUSE); - - field.num_bits = 64; - field.out_value = last_dword; - field.in_value = NULL; - - jtag_add_dr_scan(tap, 1, &field, TAP_IDLE); - - /* small delay before polling */ - jtag_add_sleep(50); - - str9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE); - - do { - field.num_bits = 8; - field.out_value = NULL; - field.in_value = scanbuf; - - jtag_add_dr_scan(tap, 1, &field, TAP_IRPAUSE); - jtag_execute_queue(); - - status = buf_get_u32(scanbuf, 0, 8); - - } while (!(status & ISC_STATUS_BUSY)); - - if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS) - return ERROR_FLASH_OPERATION_FAILED; - - /* if ((status & ISC_STATUS_INT_ERROR) != STR9XPEC_ISC_INTFAIL) - return ERROR_FLASH_OPERATION_FAILED; */ - } - - free(scanbuf); - - str9xpec_isc_disable(bank); - - return ERROR_OK; -} - -static int str9xpec_probe(struct flash_bank *bank) -{ - return ERROR_OK; -} - -COMMAND_HANDLER(str9xpec_handle_part_id_command) -{ - struct scan_field field; - uint8_t *buffer = NULL; - struct jtag_tap *tap; - uint32_t idcode; - struct str9xpec_flash_controller *str9xpec_info = 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; - - str9xpec_info = bank->driver_priv; - tap = str9xpec_info->tap; - - buffer = calloc(DIV_ROUND_UP(32, 8), 1); - - str9xpec_set_instr(tap, ISC_IDCODE, TAP_IRPAUSE); - - field.num_bits = 32; - field.out_value = NULL; - field.in_value = buffer; - - jtag_add_dr_scan(tap, 1, &field, TAP_IDLE); - jtag_execute_queue(); - - idcode = buf_get_u32(buffer, 0, 32); - - command_print(CMD_CTX, "str9xpec part id: 0x%8.8" PRIx32 "", idcode); - - free(buffer); - - return ERROR_OK; -} - -static int str9xpec_erase_check(struct flash_bank *bank) -{ - return str9xpec_blank_check(bank, 0, bank->num_sectors - 1); -} - -COMMAND_HANDLER(str9xpec_handle_flash_options_read_command) -{ - uint8_t status; - struct str9xpec_flash_controller *str9xpec_info = 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; - - str9xpec_info = bank->driver_priv; - - status = str9xpec_read_config(bank); - - if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS) - return ERROR_FLASH_OPERATION_FAILED; - - /* boot bank */ - if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_CSMAPBIT, 1)) - command_print(CMD_CTX, "CS Map: bank1"); - else - command_print(CMD_CTX, "CS Map: bank0"); - - /* OTP lock */ - if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_OTPBIT, 1)) - command_print(CMD_CTX, "OTP Lock: OTP Locked"); - else - command_print(CMD_CTX, "OTP Lock: OTP Unlocked"); - - /* LVD Threshold */ - if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_LVDTHRESBIT, 1)) - command_print(CMD_CTX, "LVD Threshold: 2.7v"); - else - command_print(CMD_CTX, "LVD Threshold: 2.4v"); - - /* LVD reset warning */ - if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_LVDWARNBIT, 1)) - command_print(CMD_CTX, "LVD Reset Warning: VDD or VDDQ Inputs"); - else - command_print(CMD_CTX, "LVD Reset Warning: VDD Input Only"); - - /* LVD reset select */ - if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_LVDSELBIT, 1)) - command_print(CMD_CTX, "LVD Reset Selection: VDD or VDDQ Inputs"); - else - command_print(CMD_CTX, "LVD Reset Selection: VDD Input Only"); - - return ERROR_OK; -} - -static int str9xpec_write_options(struct flash_bank *bank) -{ - struct scan_field field; - uint8_t status; - struct jtag_tap *tap; - struct str9xpec_flash_controller *str9xpec_info = NULL; - - str9xpec_info = bank->driver_priv; - tap = str9xpec_info->tap; - - /* erase config options first */ - status = str9xpec_erase_area(bank, 0xFE, 0xFE); - - if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS) - return status; - - if (!str9xpec_info->isc_enable) - str9xpec_isc_enable(bank); - - if (!str9xpec_info->isc_enable) - return ISC_STATUS_ERROR; - - /* according to data 64th bit has to be set */ - buf_set_u32(str9xpec_info->options, 63, 1, 1); - - /* set option byte address */ - str9xpec_set_address(bank, 0x50); - - /* execute ISC_PROGRAM command */ - str9xpec_set_instr(tap, ISC_PROGRAM, TAP_IRPAUSE); - - field.num_bits = 64; - field.out_value = str9xpec_info->options; - field.in_value = NULL; - - jtag_add_dr_scan(tap, 1, &field, TAP_IDLE); - - /* small delay before polling */ - jtag_add_sleep(50); - - str9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE); - - do { - field.num_bits = 8; - field.out_value = NULL; - field.in_value = &status; - - jtag_add_dr_scan(tap, 1, &field, TAP_IRPAUSE); - jtag_execute_queue(); - - } while (!(status & ISC_STATUS_BUSY)); - - str9xpec_isc_disable(bank); - - return status; -} - -COMMAND_HANDLER(str9xpec_handle_flash_options_write_command) -{ - uint8_t status; - - 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; - - status = str9xpec_write_options(bank); - - if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS) - return ERROR_FLASH_OPERATION_FAILED; - - command_print(CMD_CTX, "str9xpec write options complete.\n" - "INFO: a reset or power cycle is required " - "for the new settings to take effect."); - - return ERROR_OK; -} - -COMMAND_HANDLER(str9xpec_handle_flash_options_cmap_command) -{ - struct str9xpec_flash_controller *str9xpec_info = NULL; - - if (CMD_ARGC < 2) - 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; - - str9xpec_info = bank->driver_priv; - - if (strcmp(CMD_ARGV[1], "bank1") == 0) - buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_CSMAPBIT, 1, 1); - else - buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_CSMAPBIT, 1, 0); - - return ERROR_OK; -} - -COMMAND_HANDLER(str9xpec_handle_flash_options_lvdthd_command) -{ - struct str9xpec_flash_controller *str9xpec_info = NULL; - - if (CMD_ARGC < 2) - 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; - - str9xpec_info = bank->driver_priv; - - if (strcmp(CMD_ARGV[1], "2.7v") == 0) - buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDTHRESBIT, 1, 1); - else - buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDTHRESBIT, 1, 0); - - return ERROR_OK; -} - -COMMAND_HANDLER(str9xpec_handle_flash_options_lvdsel_command) -{ - struct str9xpec_flash_controller *str9xpec_info = NULL; - - if (CMD_ARGC < 2) - 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; - - str9xpec_info = bank->driver_priv; - - if (strcmp(CMD_ARGV[1], "vdd_vddq") == 0) - buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDSELBIT, 1, 1); - else - buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDSELBIT, 1, 0); - - return ERROR_OK; -} - -COMMAND_HANDLER(str9xpec_handle_flash_options_lvdwarn_command) -{ - struct str9xpec_flash_controller *str9xpec_info = NULL; - - if (CMD_ARGC < 2) - 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; - - str9xpec_info = bank->driver_priv; - - if (strcmp(CMD_ARGV[1], "vdd_vddq") == 0) - buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDWARNBIT, 1, 1); - else - buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDWARNBIT, 1, 0); - - return ERROR_OK; -} - -COMMAND_HANDLER(str9xpec_handle_flash_lock_command) -{ - uint8_t status; - - 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; - - status = str9xpec_lock_device(bank); - - if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS) - return ERROR_FLASH_OPERATION_FAILED; - - return ERROR_OK; -} - -COMMAND_HANDLER(str9xpec_handle_flash_unlock_command) -{ - uint8_t status; - - 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; - - status = str9xpec_unlock_device(bank); - - if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS) - return ERROR_FLASH_OPERATION_FAILED; - - command_print(CMD_CTX, "str9xpec unlocked.\n" - "INFO: a reset or power cycle is required " - "for the new settings to take effect."); - - return ERROR_OK; -} - -COMMAND_HANDLER(str9xpec_handle_flash_enable_turbo_command) -{ - struct jtag_tap *tap0; - struct jtag_tap *tap1; - struct jtag_tap *tap2; - struct str9xpec_flash_controller *str9xpec_info = 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; - - str9xpec_info = bank->driver_priv; - - /* remove arm core from chain - enter turbo mode */ - tap0 = str9xpec_info->tap; - if (tap0 == NULL) { - /* things are *WRONG* */ - command_print(CMD_CTX, "**STR9FLASH** (tap0) invalid chain?"); - return ERROR_FAIL; - } - tap1 = tap0->next_tap; - if (tap1 == NULL) { - /* things are *WRONG* */ - command_print(CMD_CTX, "**STR9FLASH** (tap1) invalid chain?"); - return ERROR_FAIL; - } - tap2 = tap1->next_tap; - if (tap2 == NULL) { - /* things are *WRONG* */ - command_print(CMD_CTX, "**STR9FLASH** (tap2) invalid chain?"); - return ERROR_FAIL; - } - - /* enable turbo mode - TURBO-PROG-ENABLE */ - str9xpec_set_instr(tap2, 0xD, TAP_IDLE); - retval = jtag_execute_queue(); - if (retval != ERROR_OK) - return retval; - - /* modify scan chain - str9 core has been removed */ - tap1->enabled = 0; - - return ERROR_OK; -} - -COMMAND_HANDLER(str9xpec_handle_flash_disable_turbo_command) -{ - struct jtag_tap *tap; - struct str9xpec_flash_controller *str9xpec_info = 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; - - str9xpec_info = bank->driver_priv; - tap = str9xpec_info->tap; - - if (tap == NULL) - return ERROR_FAIL; - - /* exit turbo mode via RESET */ - str9xpec_set_instr(tap, ISC_NOOP, TAP_IDLE); - jtag_add_tlr(); - jtag_execute_queue(); - - /* restore previous scan chain */ - if (tap->next_tap) - tap->next_tap->enabled = 1; - - return ERROR_OK; -} - -static const struct command_registration str9xpec_config_command_handlers[] = { - { - .name = "enable_turbo", - .usage = "", - .handler = str9xpec_handle_flash_enable_turbo_command, - .mode = COMMAND_EXEC, - .help = "enable str9xpec turbo mode", - }, - { - .name = "disable_turbo", - .usage = "", - .handler = str9xpec_handle_flash_disable_turbo_command, - .mode = COMMAND_EXEC, - .help = "disable str9xpec turbo mode", - }, - { - .name = "options_cmap", - .usage = " ", - .handler = str9xpec_handle_flash_options_cmap_command, - .mode = COMMAND_EXEC, - .help = "configure str9xpec boot sector", - }, - { - .name = "options_lvdthd", - .usage = " <2.4v | 2.7v>", - .handler = str9xpec_handle_flash_options_lvdthd_command, - .mode = COMMAND_EXEC, - .help = "configure str9xpec lvd threshold", - }, - { - .name = "options_lvdsel", - .usage = " ", - .handler = str9xpec_handle_flash_options_lvdsel_command, - .mode = COMMAND_EXEC, - .help = "configure str9xpec lvd selection", - }, - { - .name = "options_lvdwarn", - .usage = " ", - .handler = str9xpec_handle_flash_options_lvdwarn_command, - .mode = COMMAND_EXEC, - .help = "configure str9xpec lvd warning", - }, - { - .name = "options_read", - .usage = "", - .handler = str9xpec_handle_flash_options_read_command, - .mode = COMMAND_EXEC, - .help = "read str9xpec options", - }, - { - .name = "options_write", - .usage = "", - .handler = str9xpec_handle_flash_options_write_command, - .mode = COMMAND_EXEC, - .help = "write str9xpec options", - }, - { - .name = "lock", - .usage = "", - .handler = str9xpec_handle_flash_lock_command, - .mode = COMMAND_EXEC, - .help = "lock str9xpec device", - }, - { - .name = "unlock", - .usage = "", - .handler = str9xpec_handle_flash_unlock_command, - .mode = COMMAND_EXEC, - .help = "unlock str9xpec device", - }, - { - .name = "part_id", - .handler = str9xpec_handle_part_id_command, - .mode = COMMAND_EXEC, - .help = "print part id of str9xpec flash bank ", - }, - COMMAND_REGISTRATION_DONE -}; - -static const struct command_registration str9xpec_command_handlers[] = { - { - .name = "str9xpec", - .mode = COMMAND_ANY, - .help = "str9xpec flash command group", - .usage = "", - .chain = str9xpec_config_command_handlers, - }, - COMMAND_REGISTRATION_DONE -}; - -struct flash_driver str9xpec_flash = { - .name = "str9xpec", - .commands = str9xpec_command_handlers, - .flash_bank_command = str9xpec_flash_bank_command, - .erase = str9xpec_erase, - .protect = str9xpec_protect, - .write = str9xpec_write, - .read = default_flash_read, - .probe = str9xpec_probe, - .auto_probe = str9xpec_probe, - .erase_check = str9xpec_erase_check, - .protect_check = str9xpec_protect_check, -}; diff --git a/src/flash/nor/tcl.c b/src/flash/nor/tcl.c deleted file mode 100644 index 6dd21407e..000000000 --- a/src/flash/nor/tcl.c +++ /dev/null @@ -1,1146 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005 by Dominic Rath * - * Copyright (C) 2007,2008 Øyvind Harboe * - * Copyright (C) 2008 by Spencer Oliver * - * Copyright (C) 2009 Zachary T Welch * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 -#include "config.h" -#endif -#include "imp.h" -#include -#include - -/** - * @file - * Implements Tcl commands used to access NOR flash facilities. - */ - -COMMAND_HELPER(flash_command_get_bank_maybe_probe, unsigned name_index, - struct flash_bank **bank, bool do_probe) -{ - const char *name = CMD_ARGV[name_index]; - int retval; - if (do_probe) { - retval = get_flash_bank_by_name(name, bank); - } else { - *bank = get_flash_bank_by_name_noprobe(name); - retval = ERROR_OK; - } - - if (retval != ERROR_OK) - return retval; - if (*bank) - return ERROR_OK; - - unsigned bank_num; - COMMAND_PARSE_NUMBER(uint, name, bank_num); - - if (do_probe) { - return get_flash_bank_by_num(bank_num, bank); - } else { - *bank = get_flash_bank_by_num_noprobe(bank_num); - retval = (bank) ? ERROR_OK : ERROR_FAIL; - return retval; - } -} - -COMMAND_HELPER(flash_command_get_bank, unsigned name_index, - struct flash_bank **bank) -{ - return CALL_COMMAND_HANDLER(flash_command_get_bank_maybe_probe, - name_index, bank, true); -} - -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 || 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); - if (retval != ERROR_OK) - return retval; - - /* We must query the hardware to avoid printing stale information! */ - retval = p->driver->protect_check(p); - if (retval != ERROR_OK) - return retval; - - command_print(CMD_CTX, - "#%d : %s at 0x%8.8" PRIx32 ", size 0x%8.8" PRIx32 - ", buswidth %i, chipwidth %i", - p->bank_number, - p->driver->name, - p->base, - p->size, - p->bus_width, - p->chip_width); - - 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 (block_array[j].is_protected == 1) - protect_state = "protected"; - 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, - block_array[j].offset, - block_array[j].size, - block_array[j].size >> 10, - protect_state); - } - - if (p->driver->info != NULL) { - retval = p->driver->info(p, buf, sizeof(buf)); - if (retval == ERROR_OK) - command_print(CMD_CTX, "%s", buf); - else - LOG_ERROR("error retrieving flash info"); - } - } - - return retval; -} - -COMMAND_HANDLER(handle_flash_probe_command) -{ - struct flash_bank *p; - int retval; - - if (CMD_ARGC != 1) - return ERROR_COMMAND_SYNTAX_ERROR; - - retval = CALL_COMMAND_HANDLER(flash_command_get_bank_maybe_probe, 0, &p, false); - if (retval != ERROR_OK) - return retval; - - if (p) { - retval = p->driver->probe(p); - if (retval == ERROR_OK) - command_print(CMD_CTX, - "flash '%s' found at 0x%8.8" PRIx32, - p->driver->name, - p->base); - } else { - command_print(CMD_CTX, "flash bank '#%s' is out of bounds", CMD_ARGV[0]); - retval = ERROR_FAIL; - } - - return retval; -} - -COMMAND_HANDLER(handle_flash_erase_check_command) -{ - bool blank = true; - if (CMD_ARGC != 1) - return ERROR_COMMAND_SYNTAX_ERROR; - - struct flash_bank *p; - int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &p); - if (ERROR_OK != retval) - return retval; - - int j; - retval = p->driver->erase_check(p); - if (retval == ERROR_OK) - command_print(CMD_CTX, "successfully checked erase state"); - else { - command_print(CMD_CTX, - "unknown error when checking erase state of flash bank #%s at 0x%8.8" PRIx32, - CMD_ARGV[0], - p->base); - } - - for (j = 0; j < p->num_sectors; j++) { - char *erase_state; - - if (p->sectors[j].is_erased == 0) - erase_state = "not erased"; - else if (p->sectors[j].is_erased == 1) - 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, - p->sectors[j].offset, - p->sectors[j].size, - p->sectors[j].size >> 10, - erase_state); - } - - if (blank) - command_print(CMD_CTX, "\tBank is erased"); - return retval; -} - -COMMAND_HANDLER(handle_flash_erase_address_command) -{ - struct flash_bank *p; - int retval = ERROR_OK; - uint32_t address; - uint32_t length; - bool do_pad = false; - bool do_unlock = false; - struct target *target = get_current_target(CMD_CTX); - - while (CMD_ARGC >= 3) { - /* Optionally pad out the address range to block/sector - * boundaries. We can't know if there's data in that part - * of the flash; only do padding if we're told to. - */ - if (strcmp("pad", CMD_ARGV[0]) == 0) - do_pad = true; - else if (strcmp("unlock", CMD_ARGV[0]) == 0) - do_unlock = true; - else - return ERROR_COMMAND_SYNTAX_ERROR; - CMD_ARGC--; - CMD_ARGV++; - } - if (CMD_ARGC != 2) - return ERROR_COMMAND_SYNTAX_ERROR; - - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], address); - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], length); - - if (length <= 0) { - command_print(CMD_CTX, "Length must be >0"); - return ERROR_COMMAND_SYNTAX_ERROR; - } - - retval = get_flash_bank_by_addr(target, address, true, &p); - if (retval != ERROR_OK) - return retval; - - /* We can't know if we did a resume + halt, in which case we no longer know the erased state - **/ - flash_set_dirty(); - - struct duration bench; - duration_start(&bench); - - if (do_unlock) - retval = flash_unlock_address_range(target, address, length); - - if (retval == ERROR_OK) - retval = flash_erase_address_range(target, do_pad, address, length); - - if ((ERROR_OK == retval) && (duration_measure(&bench) == ERROR_OK)) { - command_print(CMD_CTX, "erased address 0x%8.8" PRIx32 " (length %" PRIi32 ")" - " in %fs (%0.3f KiB/s)", address, length, - duration_elapsed(&bench), duration_kbps(&bench, length)); - } - - return retval; -} - -static int flash_check_sector_parameters(struct command_context *cmd_ctx, - uint32_t first, uint32_t last, uint32_t num_sectors) -{ - if (!(first <= last)) { - command_print(cmd_ctx, "ERROR: " - "first sector must be <= last sector"); - return ERROR_FAIL; - } - - if (!(last <= (num_sectors - 1))) { - command_print(cmd_ctx, "ERROR: last sector must be <= %d", - (int) num_sectors - 1); - return ERROR_FAIL; - } - - return ERROR_OK; -} - -COMMAND_HANDLER(handle_flash_erase_command) -{ - if (CMD_ARGC != 3) - return ERROR_COMMAND_SYNTAX_ERROR; - - uint32_t first; - uint32_t last; - - struct flash_bank *p; - int retval; - - retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &p); - if (retval != ERROR_OK) - return retval; - - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], first); - if (strcmp(CMD_ARGV[2], "last") == 0) - last = p->num_sectors - 1; - else - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], last); - - retval = flash_check_sector_parameters(CMD_CTX, first, last, p->num_sectors); - if (retval != ERROR_OK) - return retval; - - struct duration bench; - duration_start(&bench); - - retval = flash_driver_erase(p, first, last); - - if ((ERROR_OK == retval) && (duration_measure(&bench) == ERROR_OK)) { - command_print(CMD_CTX, "erased sectors %" PRIu32 " " - "through %" PRIu32 " on flash bank %d " - "in %fs", first, last, p->bank_number, duration_elapsed(&bench)); - } - - return ERROR_OK; -} - -COMMAND_HANDLER(handle_flash_protect_command) -{ - if (CMD_ARGC != 4) - return ERROR_COMMAND_SYNTAX_ERROR; - - uint32_t first; - uint32_t last; - - 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 = 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, 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); - } - - return retval; -} - -COMMAND_HANDLER(handle_flash_write_image_command) -{ - struct target *target = get_current_target(CMD_CTX); - - struct image image; - uint32_t written; - - int retval; - - /* flash auto-erase is disabled by default*/ - int auto_erase = 0; - bool auto_unlock = false; - - while (CMD_ARGC) { - if (strcmp(CMD_ARGV[0], "erase") == 0) { - auto_erase = 1; - CMD_ARGV++; - CMD_ARGC--; - command_print(CMD_CTX, "auto erase enabled"); - } else if (strcmp(CMD_ARGV[0], "unlock") == 0) { - auto_unlock = true; - CMD_ARGV++; - CMD_ARGC--; - command_print(CMD_CTX, "auto unlock enabled"); - } else - break; - } - - 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) { - image.base_address_set = 1; - COMMAND_PARSE_NUMBER(llong, CMD_ARGV[1], image.base_address); - } 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; - - retval = flash_write_unlock(target, &image, &written, auto_erase, auto_unlock); - if (retval != ERROR_OK) { - image_close(&image); - return retval; - } - - if ((ERROR_OK == retval) && (duration_measure(&bench) == ERROR_OK)) { - command_print(CMD_CTX, "wrote %" PRIu32 " bytes from file %s " - "in %fs (%0.3f KiB/s)", written, CMD_ARGV[0], - duration_elapsed(&bench), duration_kbps(&bench, written)); - } - - image_close(&image); - - return retval; -} - -COMMAND_HANDLER(handle_flash_fill_command) -{ - int err = ERROR_OK; - uint32_t address; - uint32_t pattern; - uint32_t count; - uint32_t wrote = 0; - uint32_t cur_size = 0; - uint32_t chunk_count; - struct target *target = get_current_target(CMD_CTX); - unsigned i; - uint32_t wordsize; - int retval = ERROR_OK; - - static size_t const chunksize = 1024; - uint8_t *chunk = NULL, *readback = NULL; - - if (CMD_ARGC != 3) { - retval = ERROR_COMMAND_SYNTAX_ERROR; - goto done; - } - - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], address); - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], pattern); - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], count); - - chunk = malloc(chunksize); - if (chunk == NULL) - return ERROR_FAIL; - - readback = malloc(chunksize); - if (readback == NULL) { - free(chunk); - return ERROR_FAIL; - } - - if (count == 0) - goto done; - - switch (CMD_NAME[4]) { - case 'w': - wordsize = 4; - break; - case 'h': - wordsize = 2; - break; - case 'b': - wordsize = 1; - break; - default: - retval = ERROR_COMMAND_SYNTAX_ERROR; - goto done; - } - - chunk_count = MIN(count, (chunksize / wordsize)); - switch (wordsize) { - case 4: - for (i = 0; i < chunk_count; i++) - target_buffer_set_u32(target, chunk + i * wordsize, pattern); - break; - case 2: - for (i = 0; i < chunk_count; i++) - target_buffer_set_u16(target, chunk + i * wordsize, pattern); - break; - case 1: - memset(chunk, pattern, chunk_count); - break; - default: - LOG_ERROR("BUG: can't happen"); - exit(-1); - } - - struct duration bench; - duration_start(&bench); - - for (wrote = 0; wrote < (count*wordsize); wrote += cur_size) { - struct flash_bank *bank; - - retval = get_flash_bank_by_addr(target, address, true, &bank); - if (retval != ERROR_OK) - goto done; - - cur_size = MIN((count * wordsize - wrote), chunksize); - err = flash_driver_write(bank, chunk, address - bank->base + wrote, cur_size); - if (err != ERROR_OK) { - retval = err; - goto done; - } - - err = flash_driver_read(bank, readback, address - bank->base + wrote, cur_size); - if (err != ERROR_OK) { - retval = err; - goto done; - } - - for (i = 0; i < cur_size; i++) { - if (readback[i] != chunk[i]) { - LOG_ERROR( - "Verification error address 0x%08" PRIx32 ", read back 0x%02x, expected 0x%02x", - address + wrote + i, - readback[i], - chunk[i]); - retval = ERROR_FAIL; - goto done; - } - } - } - - if ((retval == ERROR_OK) && (duration_measure(&bench) == ERROR_OK)) { - command_print(CMD_CTX, "wrote %" PRIu32 " bytes to 0x%8.8" PRIx32 - " in %fs (%0.3f KiB/s)", wrote, address, - duration_elapsed(&bench), duration_kbps(&bench, wrote)); - } - -done: - free(readback); - free(chunk); - - return retval; -} - -COMMAND_HANDLER(handle_flash_write_bank_command) -{ - uint32_t offset; - uint8_t *buffer; - struct fileio *fileio; - - if (CMD_ARGC != 3) - return ERROR_COMMAND_SYNTAX_ERROR; - - struct duration bench; - duration_start(&bench); - - struct flash_bank *p; - int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &p); - if (ERROR_OK != retval) - return retval; - - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], offset); - - if (fileio_open(&fileio, CMD_ARGV[1], FILEIO_READ, FILEIO_BINARY) != ERROR_OK) - return ERROR_OK; - - size_t filesize; - retval = fileio_size(fileio, &filesize); - if (retval != ERROR_OK) { - fileio_close(fileio); - return retval; - } - - buffer = malloc(filesize); - if (buffer == NULL) { - 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) { - free(buffer); - fileio_close(fileio); - return ERROR_OK; - } - - retval = flash_driver_write(p, buffer, offset, buf_cnt); - - free(buffer); - buffer = NULL; - - if ((ERROR_OK == retval) && (duration_measure(&bench) == ERROR_OK)) { - command_print(CMD_CTX, "wrote %zu bytes from file %s to flash bank %u" - " at offset 0x%8.8" PRIx32 " in %fs (%0.3f KiB/s)", - filesize, CMD_ARGV[1], p->bank_number, offset, - duration_elapsed(&bench), duration_kbps(&bench, filesize)); - } - - fileio_close(fileio); - - return retval; -} - -COMMAND_HANDLER(handle_flash_read_bank_command) -{ - uint32_t offset; - uint8_t *buffer; - struct fileio *fileio; - uint32_t length; - size_t written; - - if (CMD_ARGC != 4) - return ERROR_COMMAND_SYNTAX_ERROR; - - struct duration bench; - duration_start(&bench); - - struct flash_bank *p; - int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &p); - if (ERROR_OK != retval) - return retval; - - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], offset); - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[3], length); - - buffer = malloc(length); - if (buffer == NULL) { - LOG_ERROR("Out of memory"); - return ERROR_FAIL; - } - - retval = flash_driver_read(p, buffer, offset, length); - if (retval != ERROR_OK) { - LOG_ERROR("Read error"); - free(buffer); - return retval; - } - - retval = fileio_open(&fileio, CMD_ARGV[1], FILEIO_WRITE, FILEIO_BINARY); - if (retval != ERROR_OK) { - LOG_ERROR("Could not open file"); - free(buffer); - return retval; - } - - retval = fileio_write(fileio, length, buffer, &written); - fileio_close(fileio); - free(buffer); - if (retval != ERROR_OK) { - LOG_ERROR("Could not write file"); - return ERROR_FAIL; - } - - if (duration_measure(&bench) == ERROR_OK) - command_print(CMD_CTX, "wrote %ld 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, - duration_elapsed(&bench), duration_kbps(&bench, written)); - - return retval; -} - - -COMMAND_HANDLER(handle_flash_verify_bank_command) -{ - uint32_t offset; - uint8_t *buffer_file, *buffer_flash; - struct fileio *fileio; - size_t read_cnt; - size_t filesize; - int differ; - - if (CMD_ARGC != 3) - return ERROR_COMMAND_SYNTAX_ERROR; - - struct duration bench; - duration_start(&bench); - - struct flash_bank *p; - int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &p); - if (ERROR_OK != retval) - return retval; - - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], offset); - - retval = fileio_open(&fileio, CMD_ARGV[1], FILEIO_READ, FILEIO_BINARY); - if (retval != ERROR_OK) { - LOG_ERROR("Could not open file"); - return retval; - } - - retval = fileio_size(fileio, &filesize); - if (retval != ERROR_OK) { - fileio_close(fileio); - return retval; - } - - buffer_file = malloc(filesize); - if (buffer_file == NULL) { - LOG_ERROR("Out of memory"); - fileio_close(fileio); - return ERROR_FAIL; - } - - retval = fileio_read(fileio, filesize, buffer_file, &read_cnt); - fileio_close(fileio); - if (retval != ERROR_OK) { - LOG_ERROR("File read failure"); - free(buffer_file); - return retval; - } - - if (read_cnt != filesize) { - LOG_ERROR("Short read"); - free(buffer_file); - return ERROR_FAIL; - } - - buffer_flash = malloc(filesize); - if (buffer_flash == NULL) { - LOG_ERROR("Out of memory"); - free(buffer_file); - return ERROR_FAIL; - } - - retval = flash_driver_read(p, buffer_flash, offset, read_cnt); - if (retval != ERROR_OK) { - LOG_ERROR("Flash read error"); - free(buffer_flash); - free(buffer_file); - return retval; - } - - if (duration_measure(&bench) == ERROR_OK) - command_print(CMD_CTX, "read %ld 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, - duration_elapsed(&bench), duration_kbps(&bench, read_cnt)); - - differ = memcmp(buffer_file, buffer_flash, read_cnt); - command_print(CMD_CTX, "contents %s", differ ? "differ" : "match"); - if (differ) { - uint32_t t; - int diffs = 0; - for (t = 0; t < read_cnt; t++) { - if (buffer_flash[t] == buffer_file[t]) - continue; - command_print(CMD_CTX, "diff %d address 0x%08x. Was 0x%02x instead of 0x%02x", - diffs, t + offset, buffer_flash[t], buffer_file[t]); - if (diffs++ >= 127) { - command_print(CMD_CTX, "More than 128 errors, the rest are not printed."); - break; - } - keep_alive(); - } - } - free(buffer_flash); - free(buffer_file); - - return differ ? ERROR_FAIL : ERROR_OK; -} - -void flash_set_dirty(void) -{ - struct flash_bank *c; - int i; - - /* set all flash to require erasing */ - for (c = flash_bank_list(); c; c = c->next) { - for (i = 0; i < c->num_sectors; i++) - c->sectors[i].is_erased = 0; - } -} - -COMMAND_HANDLER(handle_flash_padded_value_command) -{ - if (CMD_ARGC != 2) - return ERROR_COMMAND_SYNTAX_ERROR; - - struct flash_bank *p; - int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &p); - if (ERROR_OK != retval) - return retval; - - COMMAND_PARSE_NUMBER(u8, CMD_ARGV[1], p->default_padded_value); - - command_print(CMD_CTX, "Default padded value set to 0x%" PRIx8 " for flash bank %u", \ - p->default_padded_value, p->bank_number); - - return retval; -} - -static const struct command_registration flash_exec_command_handlers[] = { - { - .name = "probe", - .handler = handle_flash_probe_command, - .mode = COMMAND_EXEC, - .usage = "bank_id", - .help = "Identify a flash bank.", - }, - { - .name = "info", - .handler = handle_flash_info_command, - .mode = COMMAND_EXEC, - .usage = "bank_id ['sectors']", - .help = "Print information about a flash bank.", - }, - { - .name = "erase_check", - .handler = handle_flash_erase_check_command, - .mode = COMMAND_EXEC, - .usage = "bank_id", - .help = "Check erase state of all blocks in a " - "flash bank.", - }, - { - .name = "erase_sector", - .handler = handle_flash_erase_command, - .mode = COMMAND_EXEC, - .usage = "bank_id first_sector_num last_sector_num", - .help = "Erase a range of sectors in a flash bank.", - }, - { - .name = "erase_address", - .handler = handle_flash_erase_address_command, - .mode = COMMAND_EXEC, - .usage = "['pad'] ['unlock'] address length", - .help = "Erase flash sectors starting at address and " - "continuing for length bytes. If 'pad' is specified, " - "data outside that range may also be erased: the start " - "address may be decreased, and length increased, so " - "that all of the first and last sectors are erased. " - "If 'unlock' is specified, then the flash is unprotected " - "before erasing.", - - }, - { - .name = "fillw", - .handler = handle_flash_fill_command, - .mode = COMMAND_EXEC, - .usage = "address value n", - .help = "Fill n words with 32-bit value, starting at " - "word address. (No autoerase.)", - }, - { - .name = "fillh", - .handler = handle_flash_fill_command, - .mode = COMMAND_EXEC, - .usage = "address value n", - .help = "Fill n halfwords with 16-bit value, starting at " - "word address. (No autoerase.)", - }, - { - .name = "fillb", - .handler = handle_flash_fill_command, - .mode = COMMAND_EXEC, - .usage = "address value n", - .help = "Fill n bytes with 8-bit value, starting at " - "word address. (No autoerase.)", - }, - { - .name = "write_bank", - .handler = handle_flash_write_bank_command, - .mode = COMMAND_EXEC, - .usage = "bank_id filename offset", - .help = "Write binary data from file to flash bank, " - "starting at specified byte offset from the " - "beginning of the bank.", - }, - { - .name = "write_image", - .handler = handle_flash_write_image_command, - .mode = COMMAND_EXEC, - .usage = "[erase] [unlock] filename [offset [file_type]]", - .help = "Write an image to flash. Optionally first unprotect " - "and/or erase the region to be used. Allow optional " - "offset from beginning of bank (defaults to zero)", - }, - { - .name = "read_bank", - .handler = handle_flash_read_bank_command, - .mode = COMMAND_EXEC, - .usage = "bank_id filename offset length", - .help = "Read binary data from flash bank to file, " - "starting at specified byte offset from the " - "beginning of the bank.", - }, - { - .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.", - }, - { - .name = "protect", - .handler = handle_flash_protect_command, - .mode = COMMAND_EXEC, - .usage = "bank_id first_sector [last_sector|'last'] " - "('on'|'off')", - .help = "Turn protection on or off for a range of sectors " - "in a given flash bank.", - }, - { - .name = "padded_value", - .handler = handle_flash_padded_value_command, - .mode = COMMAND_EXEC, - .usage = "bank_id value", - .help = "Set default flash padded value", - }, - COMMAND_REGISTRATION_DONE -}; - -static int flash_init_drivers(struct command_context *cmd_ctx) -{ - if (!flash_bank_list()) - return ERROR_OK; - - struct command *parent = command_find_in_context(cmd_ctx, "flash"); - return register_commands(cmd_ctx, parent, flash_exec_command_handlers); -} - -COMMAND_HANDLER(handle_flash_bank_command) -{ - if (CMD_ARGC < 7) { - LOG_ERROR("usage: flash bank " - " "); - return ERROR_COMMAND_SYNTAX_ERROR; - } - /* save bank name and advance arguments for compatibility */ - const char *bank_name = *CMD_ARGV++; - CMD_ARGC--; - - struct target *target = get_target(CMD_ARGV[5]); - if (target == NULL) { - LOG_ERROR("target '%s' not defined", CMD_ARGV[5]); - return ERROR_FAIL; - } - - const char *driver_name = CMD_ARGV[0]; - struct flash_driver *driver = flash_driver_find_by_name(driver_name); - if (NULL == driver) { - /* no matching flash driver found */ - LOG_ERROR("flash driver '%s' not found", driver_name); - return ERROR_FAIL; - } - - /* check the flash bank name is unique */ - if (get_flash_bank_by_name_noprobe(bank_name) != NULL) { - /* flash bank name already exists */ - LOG_ERROR("flash bank name '%s' already exists", bank_name); - return ERROR_FAIL; - } - - /* register flash specific commands */ - if (NULL != driver->commands) { - int retval = register_commands(CMD_CTX, NULL, - driver->commands); - if (ERROR_OK != retval) { - LOG_ERROR("couldn't register '%s' commands", - driver_name); - return ERROR_FAIL; - } - } - - struct flash_bank *c = malloc(sizeof(*c)); - c->name = strdup(bank_name); - c->target = target; - c->driver = driver; - c->driver_priv = NULL; - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], c->base); - 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->num_sectors = 0; - c->sectors = NULL; - c->num_prot_blocks = 0; - c->prot_blocks = NULL; - c->next = NULL; - - int retval; - retval = CALL_COMMAND_HANDLER(driver->flash_bank_command, c); - if (ERROR_OK != retval) { - LOG_ERROR("'%s' driver rejected flash bank at 0x%8.8" PRIx32 "; usage: %s", - driver_name, c->base, driver->usage); - free(c); - return retval; - } - - if (driver->usage == NULL) - LOG_DEBUG("'%s' driver usage field missing", driver_name); - - flash_bank_add(c); - - return ERROR_OK; -} - -COMMAND_HANDLER(handle_flash_banks_command) -{ - if (CMD_ARGC != 0) - return ERROR_COMMAND_SYNTAX_ERROR; - - unsigned n = 0; - for (struct flash_bank *p = flash_bank_list(); p; p = p->next, n++) { - LOG_USER("#%d : %s (%s) at 0x%8.8" PRIx32 ", size 0x%8.8" PRIx32 ", " - "buswidth %u, chipwidth %u", p->bank_number, - p->name, p->driver->name, p->base, p->size, - p->bus_width, p->chip_width); - } - return ERROR_OK; -} - -static int jim_flash_list(Jim_Interp *interp, int argc, Jim_Obj * const *argv) -{ - if (argc != 1) { - Jim_WrongNumArgs(interp, 1, argv, - "no arguments to 'flash list' command"); - return JIM_ERR; - } - - Jim_Obj *list = Jim_NewListObj(interp, NULL, 0); - - for (struct flash_bank *p = flash_bank_list(); p; p = p->next) { - Jim_Obj *elem = Jim_NewListObj(interp, NULL, 0); - - Jim_ListAppendElement(interp, elem, Jim_NewStringObj(interp, "name", -1)); - Jim_ListAppendElement(interp, elem, Jim_NewStringObj(interp, p->driver->name, -1)); - Jim_ListAppendElement(interp, elem, Jim_NewStringObj(interp, "base", -1)); - Jim_ListAppendElement(interp, elem, Jim_NewIntObj(interp, p->base)); - Jim_ListAppendElement(interp, elem, Jim_NewStringObj(interp, "size", -1)); - Jim_ListAppendElement(interp, elem, Jim_NewIntObj(interp, p->size)); - Jim_ListAppendElement(interp, elem, Jim_NewStringObj(interp, "bus_width", -1)); - Jim_ListAppendElement(interp, elem, Jim_NewIntObj(interp, p->bus_width)); - Jim_ListAppendElement(interp, elem, Jim_NewStringObj(interp, "chip_width", -1)); - Jim_ListAppendElement(interp, elem, Jim_NewIntObj(interp, p->chip_width)); - - Jim_ListAppendElement(interp, list, elem); - } - - Jim_SetResult(interp, list); - - return JIM_OK; -} - -COMMAND_HANDLER(handle_flash_init_command) -{ - if (CMD_ARGC != 0) - return ERROR_COMMAND_SYNTAX_ERROR; - - static bool flash_initialized; - if (flash_initialized) { - LOG_INFO("'flash init' has already been called"); - return ERROR_OK; - } - flash_initialized = true; - - LOG_DEBUG("Initializing flash devices..."); - return flash_init_drivers(CMD_CTX); -} - -static const struct command_registration flash_config_command_handlers[] = { - { - .name = "bank", - .handler = handle_flash_bank_command, - .mode = COMMAND_CONFIG, - .usage = "bank_id driver_name base_address size_bytes " - "chip_width_bytes bus_width_bytes target " - "[driver_options ...]", - .help = "Define a new bank with the given name, " - "using the specified NOR flash driver.", - }, - { - .name = "init", - .mode = COMMAND_CONFIG, - .handler = handle_flash_init_command, - .help = "Initialize flash devices.", - }, - { - .name = "banks", - .mode = COMMAND_ANY, - .handler = handle_flash_banks_command, - .help = "Display table with information about flash banks.", - }, - { - .name = "list", - .mode = COMMAND_ANY, - .jim_handler = jim_flash_list, - .help = "Returns a list of details about the flash banks.", - }, - COMMAND_REGISTRATION_DONE -}; -static const struct command_registration flash_command_handlers[] = { - { - .name = "flash", - .mode = COMMAND_ANY, - .help = "NOR flash command group", - .chain = flash_config_command_handlers, - }, - COMMAND_REGISTRATION_DONE -}; - -int flash_register_commands(struct command_context *cmd_ctx) -{ - return register_commands(cmd_ctx, NULL, flash_command_handlers); -} diff --git a/src/flash/nor/tms470.c b/src/flash/nor/tms470.c deleted file mode 100644 index a70891e89..000000000 --- a/src/flash/nor/tms470.c +++ /dev/null @@ -1,1189 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007,2008 by Christopher Kilgour * - * techie |_at_| whiterocker |_dot_| com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "imp.h" - -/* ---------------------------------------------------------------------- - * Internal Support, Helpers - * ---------------------------------------------------------------------- */ - -struct tms470_flash_bank { - unsigned ordinal; - - /* device identification register */ - uint32_t device_ident_reg; - uint32_t silicon_version; - uint32_t technology_family; - uint32_t rom_flash; - uint32_t part_number; - const char *part_name; - -}; - -static const struct flash_sector TMS470R1A256_SECTORS[] = { - {0x00000000, 0x00002000, -1, -1}, - {0x00002000, 0x00002000, -1, -1}, - {0x00004000, 0x00002000, -1, -1}, - {0x00006000, 0x00002000, -1, -1}, - {0x00008000, 0x00008000, -1, -1}, - {0x00010000, 0x00008000, -1, -1}, - {0x00018000, 0x00008000, -1, -1}, - {0x00020000, 0x00008000, -1, -1}, - {0x00028000, 0x00008000, -1, -1}, - {0x00030000, 0x00008000, -1, -1}, - {0x00038000, 0x00002000, -1, -1}, - {0x0003A000, 0x00002000, -1, -1}, - {0x0003C000, 0x00002000, -1, -1}, - {0x0003E000, 0x00002000, -1, -1}, -}; - -#define TMS470R1A256_NUM_SECTORS \ - ARRAY_SIZE(TMS470R1A256_SECTORS) - -static const struct flash_sector TMS470R1A288_BANK0_SECTORS[] = { - {0x00000000, 0x00002000, -1, -1}, - {0x00002000, 0x00002000, -1, -1}, - {0x00004000, 0x00002000, -1, -1}, - {0x00006000, 0x00002000, -1, -1}, -}; - -#define TMS470R1A288_BANK0_NUM_SECTORS \ - ARRAY_SIZE(TMS470R1A288_BANK0_SECTORS) - -static const struct flash_sector TMS470R1A288_BANK1_SECTORS[] = { - {0x00040000, 0x00010000, -1, -1}, - {0x00050000, 0x00010000, -1, -1}, - {0x00060000, 0x00010000, -1, -1}, - {0x00070000, 0x00010000, -1, -1}, -}; - -#define TMS470R1A288_BANK1_NUM_SECTORS \ - ARRAY_SIZE(TMS470R1A288_BANK1_SECTORS) - -static const struct flash_sector TMS470R1A384_BANK0_SECTORS[] = { - {0x00000000, 0x00002000, -1, -1}, - {0x00002000, 0x00002000, -1, -1}, - {0x00004000, 0x00004000, -1, -1}, - {0x00008000, 0x00004000, -1, -1}, - {0x0000C000, 0x00004000, -1, -1}, - {0x00010000, 0x00004000, -1, -1}, - {0x00014000, 0x00004000, -1, -1}, - {0x00018000, 0x00002000, -1, -1}, - {0x0001C000, 0x00002000, -1, -1}, - {0x0001E000, 0x00002000, -1, -1}, -}; - -#define TMS470R1A384_BANK0_NUM_SECTORS \ - ARRAY_SIZE(TMS470R1A384_BANK0_SECTORS) - -static const struct flash_sector TMS470R1A384_BANK1_SECTORS[] = { - {0x00020000, 0x00008000, -1, -1}, - {0x00028000, 0x00008000, -1, -1}, - {0x00030000, 0x00008000, -1, -1}, - {0x00038000, 0x00008000, -1, -1}, -}; - -#define TMS470R1A384_BANK1_NUM_SECTORS \ - ARRAY_SIZE(TMS470R1A384_BANK1_SECTORS) - -static const struct flash_sector TMS470R1A384_BANK2_SECTORS[] = { - {0x00040000, 0x00008000, -1, -1}, - {0x00048000, 0x00008000, -1, -1}, - {0x00050000, 0x00008000, -1, -1}, - {0x00058000, 0x00008000, -1, -1}, -}; - -#define TMS470R1A384_BANK2_NUM_SECTORS \ - ARRAY_SIZE(TMS470R1A384_BANK2_SECTORS) - -/* ---------------------------------------------------------------------- */ - -static int tms470_read_part_info(struct flash_bank *bank) -{ - struct tms470_flash_bank *tms470_info = bank->driver_priv; - struct target *target = bank->target; - uint32_t device_ident_reg; - uint32_t silicon_version; - uint32_t technology_family; - uint32_t rom_flash; - uint32_t part_number; - const char *part_name; - - /* we shall not rely on the caller in this test, this function allocates memory, - thus and executing the code more than once may cause memory leak */ - if (tms470_info->device_ident_reg) - return ERROR_OK; - - /* read and parse the device identification register */ - target_read_u32(target, 0xFFFFFFF0, &device_ident_reg); - - LOG_INFO("device_ident_reg = 0x%08" PRIx32 "", device_ident_reg); - - if ((device_ident_reg & 7) == 0) { - LOG_WARNING("Cannot identify target as a TMS470 family."); - return ERROR_FLASH_OPERATION_FAILED; - } - - silicon_version = (device_ident_reg >> 12) & 0xF; - technology_family = (device_ident_reg >> 11) & 1; - rom_flash = (device_ident_reg >> 10) & 1; - part_number = (device_ident_reg >> 3) & 0x7f; - - if (bank->sectors) { - free(bank->sectors); - bank->sectors = NULL; - } - - /* - * If the part number is known, determine if the flash bank is valid - * based on the base address being within the known flash bank - * ranges. Then fixup/complete the remaining fields of the flash - * bank structure. - */ - switch (part_number) { - case 0x0a: - part_name = "TMS470R1A256"; - - if (bank->base >= 0x00040000) { - LOG_ERROR("No %s flash bank contains base address 0x%08" PRIx32 ".", - part_name, - bank->base); - return ERROR_FLASH_OPERATION_FAILED; - } - tms470_info->ordinal = 0; - bank->base = 0x00000000; - bank->size = 256 * 1024; - bank->num_sectors = TMS470R1A256_NUM_SECTORS; - bank->sectors = malloc(sizeof(TMS470R1A256_SECTORS)); - if (!bank->sectors) - return ERROR_FLASH_OPERATION_FAILED; - (void)memcpy(bank->sectors, TMS470R1A256_SECTORS, sizeof(TMS470R1A256_SECTORS)); - break; - - case 0x2b: - part_name = "TMS470R1A288"; - - if (bank->base < 0x00008000) { - tms470_info->ordinal = 0; - bank->base = 0x00000000; - bank->size = 32 * 1024; - bank->num_sectors = TMS470R1A288_BANK0_NUM_SECTORS; - bank->sectors = malloc(sizeof(TMS470R1A288_BANK0_SECTORS)); - if (!bank->sectors) - return ERROR_FLASH_OPERATION_FAILED; - (void)memcpy(bank->sectors, TMS470R1A288_BANK0_SECTORS, - sizeof(TMS470R1A288_BANK0_SECTORS)); - } else if ((bank->base >= 0x00040000) && (bank->base < 0x00080000)) { - tms470_info->ordinal = 1; - bank->base = 0x00040000; - bank->size = 256 * 1024; - bank->num_sectors = TMS470R1A288_BANK1_NUM_SECTORS; - bank->sectors = malloc(sizeof(TMS470R1A288_BANK1_SECTORS)); - if (!bank->sectors) - return ERROR_FLASH_OPERATION_FAILED; - (void)memcpy(bank->sectors, TMS470R1A288_BANK1_SECTORS, - sizeof(TMS470R1A288_BANK1_SECTORS)); - } else { - LOG_ERROR("No %s flash bank contains base address 0x%08" PRIx32 ".", - part_name, bank->base); - return ERROR_FLASH_OPERATION_FAILED; - } - break; - - case 0x2d: - part_name = "TMS470R1A384"; - - if (bank->base < 0x00020000) { - tms470_info->ordinal = 0; - bank->base = 0x00000000; - bank->size = 128 * 1024; - bank->num_sectors = TMS470R1A384_BANK0_NUM_SECTORS; - bank->sectors = malloc(sizeof(TMS470R1A384_BANK0_SECTORS)); - if (!bank->sectors) - return ERROR_FLASH_OPERATION_FAILED; - (void)memcpy(bank->sectors, TMS470R1A384_BANK0_SECTORS, - sizeof(TMS470R1A384_BANK0_SECTORS)); - } else if ((bank->base >= 0x00020000) && (bank->base < 0x00040000)) { - tms470_info->ordinal = 1; - bank->base = 0x00020000; - bank->size = 128 * 1024; - bank->num_sectors = TMS470R1A384_BANK1_NUM_SECTORS; - bank->sectors = malloc(sizeof(TMS470R1A384_BANK1_SECTORS)); - if (!bank->sectors) - return ERROR_FLASH_OPERATION_FAILED; - (void)memcpy(bank->sectors, TMS470R1A384_BANK1_SECTORS, - sizeof(TMS470R1A384_BANK1_SECTORS)); - } else if ((bank->base >= 0x00040000) && (bank->base < 0x00060000)) { - tms470_info->ordinal = 2; - bank->base = 0x00040000; - bank->size = 128 * 1024; - bank->num_sectors = TMS470R1A384_BANK2_NUM_SECTORS; - bank->sectors = malloc(sizeof(TMS470R1A384_BANK2_SECTORS)); - if (!bank->sectors) - return ERROR_FLASH_OPERATION_FAILED; - (void)memcpy(bank->sectors, TMS470R1A384_BANK2_SECTORS, - sizeof(TMS470R1A384_BANK2_SECTORS)); - } else { - LOG_ERROR("No %s flash bank contains base address 0x%08" PRIx32 ".", - part_name, bank->base); - return ERROR_FLASH_OPERATION_FAILED; - } - break; - - default: - LOG_WARNING("Could not identify part 0x%02x as a member of the TMS470 family.", - (unsigned)part_number); - return ERROR_FLASH_OPERATION_FAILED; - } - - /* turn off memory selects */ - target_write_u32(target, 0xFFFFFFE4, 0x00000000); - target_write_u32(target, 0xFFFFFFE0, 0x00000000); - - bank->chip_width = 32; - bank->bus_width = 32; - - LOG_INFO("Identified %s, ver=%d, core=%s, nvmem=%s.", - part_name, - (int)(silicon_version), - (technology_family ? "1.8v" : "3.3v"), - (rom_flash ? "rom" : "flash")); - - tms470_info->device_ident_reg = device_ident_reg; - tms470_info->silicon_version = silicon_version; - tms470_info->technology_family = technology_family; - tms470_info->rom_flash = rom_flash; - tms470_info->part_number = part_number; - tms470_info->part_name = part_name; - - /* - * Disable reset on address access violation. - */ - target_write_u32(target, 0xFFFFFFE0, 0x00004007); - - return ERROR_OK; -} - -/* ---------------------------------------------------------------------- */ - -static uint32_t keysSet; -static uint32_t flashKeys[4]; - -COMMAND_HANDLER(tms470_handle_flash_keyset_command) -{ - if (CMD_ARGC > 4) - return ERROR_COMMAND_SYNTAX_ERROR; - else if (CMD_ARGC == 4) { - int i; - - for (i = 0; i < 4; i++) { - int start = (0 == strncmp(CMD_ARGV[i], "0x", 2)) ? 2 : 0; - - if (1 != sscanf(&CMD_ARGV[i][start], "%" SCNx32 "", &flashKeys[i])) { - command_print(CMD_CTX, "could not process flash key %s", - CMD_ARGV[i]); - LOG_ERROR("could not process flash key %s", CMD_ARGV[i]); - return ERROR_COMMAND_SYNTAX_ERROR; - } - } - - keysSet = 1; - } else if (CMD_ARGC != 0) { - command_print(CMD_CTX, "tms470 flash_keyset "); - return ERROR_COMMAND_SYNTAX_ERROR; - } - - if (keysSet) { - command_print(CMD_CTX, - "using flash keys 0x%08" PRIx32 ", 0x%08" PRIx32 ", 0x%08" PRIx32 ", 0x%08" PRIx32 "", - flashKeys[0], - flashKeys[1], - flashKeys[2], - flashKeys[3]); - } else - command_print(CMD_CTX, "flash keys not set"); - - return ERROR_OK; -} - -static const uint32_t FLASH_KEYS_ALL_ONES[] = { 0xFFFFFFFF, 0xFFFFFFFF, - 0xFFFFFFFF, 0xFFFFFFFF,}; - -static const uint32_t FLASH_KEYS_ALL_ZEROS[] = { 0x00000000, 0x00000000, - 0x00000000, 0x00000000,}; - -static const uint32_t FLASH_KEYS_MIX1[] = { 0xf0fff0ff, 0xf0fff0ff, - 0xf0fff0ff, 0xf0fff0ff}; - -static const uint32_t FLASH_KEYS_MIX2[] = { 0x0000ffff, 0x0000ffff, - 0x0000ffff, 0x0000ffff}; - -/* ---------------------------------------------------------------------- */ - -static int oscMHz = 12; - -COMMAND_HANDLER(tms470_handle_osc_megahertz_command) -{ - if (CMD_ARGC > 1) - return ERROR_COMMAND_SYNTAX_ERROR; - else if (CMD_ARGC == 1) - sscanf(CMD_ARGV[0], "%d", &oscMHz); - - if (oscMHz <= 0) { - LOG_ERROR("osc_megahertz must be positive and non-zero!"); - command_print(CMD_CTX, "osc_megahertz must be positive and non-zero!"); - oscMHz = 12; - return ERROR_COMMAND_SYNTAX_ERROR; - } - - command_print(CMD_CTX, "osc_megahertz=%d", oscMHz); - - return ERROR_OK; -} - -/* ---------------------------------------------------------------------- */ - -static int plldis; - -COMMAND_HANDLER(tms470_handle_plldis_command) -{ - if (CMD_ARGC > 1) - return ERROR_COMMAND_SYNTAX_ERROR; - else if (CMD_ARGC == 1) { - sscanf(CMD_ARGV[0], "%d", &plldis); - plldis = plldis ? 1 : 0; - } - - command_print(CMD_CTX, "plldis=%d", plldis); - - return ERROR_OK; -} - -/* ---------------------------------------------------------------------- */ - -static int tms470_check_flash_unlocked(struct target *target) -{ - uint32_t fmbbusy; - - target_read_u32(target, 0xFFE89C08, &fmbbusy); - LOG_INFO("tms470 fmbbusy = 0x%08" PRIx32 " -> %s", - fmbbusy, - fmbbusy & 0x8000 ? "unlocked" : "LOCKED"); - return fmbbusy & 0x8000 ? ERROR_OK : ERROR_FLASH_OPERATION_FAILED; -} - -/* ---------------------------------------------------------------------- */ - -static int tms470_try_flash_keys(struct target *target, const uint32_t *key_set) -{ - uint32_t glbctrl, fmmstat; - int retval = ERROR_FLASH_OPERATION_FAILED; - - /* set GLBCTRL.4 */ - target_read_u32(target, 0xFFFFFFDC, &glbctrl); - target_write_u32(target, 0xFFFFFFDC, glbctrl | 0x10); - - /* only perform the key match when 3VSTAT is clear */ - target_read_u32(target, 0xFFE8BC0C, &fmmstat); - if (!(fmmstat & 0x08)) { - unsigned i; - uint32_t fmbptr, fmbac2, orig_fmregopt; - - target_write_u32(target, 0xFFE8BC04, fmmstat & ~0x07); - - /* wait for pump ready */ - do { - target_read_u32(target, 0xFFE8A814, &fmbptr); - alive_sleep(1); - } while (!(fmbptr & 0x0200)); - - /* force max wait states */ - target_read_u32(target, 0xFFE88004, &fmbac2); - target_write_u32(target, 0xFFE88004, fmbac2 | 0xff); - - /* save current access mode, force normal read mode */ - target_read_u32(target, 0xFFE89C00, &orig_fmregopt); - target_write_u32(target, 0xFFE89C00, 0x00); - - for (i = 0; i < 4; i++) { - uint32_t tmp; - - /* There is no point displaying the value of tmp, it is - * filtered by the chip. The purpose of this read is to - * prime the unlocking logic rather than read out the value. - */ - target_read_u32(target, 0x00001FF0 + 4 * i, &tmp); - - LOG_INFO("tms470 writing fmpkey = 0x%08" PRIx32 "", key_set[i]); - target_write_u32(target, 0xFFE89C0C, key_set[i]); - } - - if (ERROR_OK == tms470_check_flash_unlocked(target)) { - /* - * There seems to be a side-effect of reading the FMPKEY - * register in that it re-enables the protection. So we - * re-enable it. - */ - for (i = 0; i < 4; i++) { - uint32_t tmp; - - target_read_u32(target, 0x00001FF0 + 4 * i, &tmp); - target_write_u32(target, 0xFFE89C0C, key_set[i]); - } - retval = ERROR_OK; - } - - /* restore settings */ - target_write_u32(target, 0xFFE89C00, orig_fmregopt); - target_write_u32(target, 0xFFE88004, fmbac2); - } - - /* clear config bit */ - target_write_u32(target, 0xFFFFFFDC, glbctrl); - - return retval; -} - -/* ---------------------------------------------------------------------- */ - -static int tms470_unlock_flash(struct flash_bank *bank) -{ - struct target *target = bank->target; - const uint32_t *p_key_sets[5]; - unsigned i, key_set_count; - - if (keysSet) { - key_set_count = 5; - p_key_sets[0] = flashKeys; - p_key_sets[1] = FLASH_KEYS_ALL_ONES; - p_key_sets[2] = FLASH_KEYS_ALL_ZEROS; - p_key_sets[3] = FLASH_KEYS_MIX1; - p_key_sets[4] = FLASH_KEYS_MIX2; - } else { - key_set_count = 4; - p_key_sets[0] = FLASH_KEYS_ALL_ONES; - p_key_sets[1] = FLASH_KEYS_ALL_ZEROS; - p_key_sets[2] = FLASH_KEYS_MIX1; - p_key_sets[3] = FLASH_KEYS_MIX2; - } - - for (i = 0; i < key_set_count; i++) { - if (tms470_try_flash_keys(target, p_key_sets[i]) == ERROR_OK) { - LOG_INFO("tms470 flash is unlocked"); - return ERROR_OK; - } - } - - LOG_WARNING("tms470 could not unlock flash memory protection level 2"); - return ERROR_FLASH_OPERATION_FAILED; -} - -/* ---------------------------------------------------------------------- */ - -static int tms470_flash_initialize_internal_state_machine(struct flash_bank *bank) -{ - uint32_t fmmac2, fmmac1, fmmaxep, k, delay, glbctrl, sysclk; - struct target *target = bank->target; - struct tms470_flash_bank *tms470_info = bank->driver_priv; - int result = ERROR_OK; - - /* - * Select the desired bank to be programmed by writing BANK[2:0] of - * FMMAC2. - */ - target_read_u32(target, 0xFFE8BC04, &fmmac2); - fmmac2 &= ~0x0007; - fmmac2 |= (tms470_info->ordinal & 7); - target_write_u32(target, 0xFFE8BC04, fmmac2); - LOG_DEBUG("set fmmac2 = 0x%04" PRIx32 "", fmmac2); - - /* - * Disable level 1 sector protection by setting bit 15 of FMMAC1. - */ - target_read_u32(target, 0xFFE8BC00, &fmmac1); - fmmac1 |= 0x8000; - target_write_u32(target, 0xFFE8BC00, fmmac1); - LOG_DEBUG("set fmmac1 = 0x%04" PRIx32 "", fmmac1); - - /* - * FMTCREG = 0x2fc0; - */ - target_write_u32(target, 0xFFE8BC10, 0x2fc0); - LOG_DEBUG("set fmtcreg = 0x2fc0"); - - /* - * MAXPP = 50 - */ - target_write_u32(target, 0xFFE8A07C, 50); - LOG_DEBUG("set fmmaxpp = 50"); - - /* - * MAXCP = 0xf000 + 2000 - */ - target_write_u32(target, 0xFFE8A084, 0xf000 + 2000); - LOG_DEBUG("set fmmaxcp = 0x%04x", 0xf000 + 2000); - - /* - * configure VHV - */ - target_read_u32(target, 0xFFE8A080, &fmmaxep); - if (fmmaxep == 0xf000) { - fmmaxep = 0xf000 + 4095; - target_write_u32(target, 0xFFE8A80C, 0x9964); - LOG_DEBUG("set fmptr3 = 0x9964"); - } else { - fmmaxep = 0xa000 + 4095; - target_write_u32(target, 0xFFE8A80C, 0x9b64); - LOG_DEBUG("set fmptr3 = 0x9b64"); - } - target_write_u32(target, 0xFFE8A080, fmmaxep); - LOG_DEBUG("set fmmaxep = 0x%04" PRIx32 "", fmmaxep); - - /* - * FMPTR4 = 0xa000 - */ - target_write_u32(target, 0xFFE8A810, 0xa000); - LOG_DEBUG("set fmptr4 = 0xa000"); - - /* - * FMPESETUP, delay parameter selected based on clock frequency. - * - * According to the TI App Note SPNU257 and flashing code, delay is - * int((sysclk(MHz) + 1) / 2), with a minimum of 5. The system - * clock is usually derived from the ZPLL module, and selected by - * the plldis global. - */ - target_read_u32(target, 0xFFFFFFDC, &glbctrl); - sysclk = (plldis ? 1 : (glbctrl & 0x08) ? 4 : 8) * oscMHz / (1 + (glbctrl & 7)); - delay = (sysclk > 10) ? (sysclk + 1) / 2 : 5; - target_write_u32(target, 0xFFE8A018, (delay << 4) | (delay << 8)); - LOG_DEBUG("set fmpsetup = 0x%04" PRIx32 "", (delay << 4) | (delay << 8)); - - /* - * FMPVEVACCESS, based on delay. - */ - k = delay | (delay << 8); - target_write_u32(target, 0xFFE8A05C, k); - LOG_DEBUG("set fmpvevaccess = 0x%04" PRIx32 "", k); - - /* - * FMPCHOLD, FMPVEVHOLD, FMPVEVSETUP, based on delay. - */ - k <<= 1; - target_write_u32(target, 0xFFE8A034, k); - LOG_DEBUG("set fmpchold = 0x%04" PRIx32 "", k); - target_write_u32(target, 0xFFE8A040, k); - LOG_DEBUG("set fmpvevhold = 0x%04" PRIx32 "", k); - target_write_u32(target, 0xFFE8A024, k); - LOG_DEBUG("set fmpvevsetup = 0x%04" PRIx32 "", k); - - /* - * FMCVACCESS, based on delay. - */ - k = delay * 16; - target_write_u32(target, 0xFFE8A060, k); - LOG_DEBUG("set fmcvaccess = 0x%04" PRIx32 "", k); - - /* - * FMCSETUP, based on delay. - */ - k = 0x3000 | delay * 20; - target_write_u32(target, 0xFFE8A020, k); - LOG_DEBUG("set fmcsetup = 0x%04" PRIx32 "", k); - - /* - * FMEHOLD, based on delay. - */ - k = (delay * 20) << 2; - target_write_u32(target, 0xFFE8A038, k); - LOG_DEBUG("set fmehold = 0x%04" PRIx32 "", k); - - /* - * PWIDTH, CWIDTH, EWIDTH, based on delay. - */ - target_write_u32(target, 0xFFE8A050, delay * 8); - LOG_DEBUG("set fmpwidth = 0x%04" PRIx32 "", delay * 8); - target_write_u32(target, 0xFFE8A058, delay * 1000); - LOG_DEBUG("set fmcwidth = 0x%04" PRIx32 "", delay * 1000); - target_write_u32(target, 0xFFE8A054, delay * 5400); - LOG_DEBUG("set fmewidth = 0x%04" PRIx32 "", delay * 5400); - - return result; -} - -/* ---------------------------------------------------------------------- */ - -static int tms470_flash_status(struct flash_bank *bank) -{ - struct target *target = bank->target; - int result = ERROR_OK; - uint32_t fmmstat; - - target_read_u32(target, 0xFFE8BC0C, &fmmstat); - LOG_DEBUG("set fmmstat = 0x%04" PRIx32 "", fmmstat); - - if (fmmstat & 0x0080) { - LOG_WARNING("tms470 flash command: erase still active after busy clear."); - result = ERROR_FLASH_OPERATION_FAILED; - } - - if (fmmstat & 0x0040) { - LOG_WARNING("tms470 flash command: program still active after busy clear."); - result = ERROR_FLASH_OPERATION_FAILED; - } - - if (fmmstat & 0x0020) { - LOG_WARNING("tms470 flash command: invalid data command."); - result = ERROR_FLASH_OPERATION_FAILED; - } - - if (fmmstat & 0x0010) { - LOG_WARNING("tms470 flash command: program, erase or validate sector failed."); - result = ERROR_FLASH_OPERATION_FAILED; - } - - if (fmmstat & 0x0008) { - LOG_WARNING("tms470 flash command: voltage instability detected."); - result = ERROR_FLASH_OPERATION_FAILED; - } - - if (fmmstat & 0x0006) { - LOG_WARNING("tms470 flash command: command suspend detected."); - result = ERROR_FLASH_OPERATION_FAILED; - } - - if (fmmstat & 0x0001) { - LOG_WARNING("tms470 flash command: sector was locked."); - result = ERROR_FLASH_OPERATION_FAILED; - } - - return result; -} - -/* ---------------------------------------------------------------------- */ - -static int tms470_erase_sector(struct flash_bank *bank, int sector) -{ - uint32_t glbctrl, orig_fmregopt, fmbsea, fmbseb, fmmstat; - struct target *target = bank->target; - uint32_t flashAddr = bank->base + bank->sectors[sector].offset; - int result = ERROR_OK; - - /* - * Set the bit GLBCTRL4 of the GLBCTRL register (in the System - * module) to enable writing to the flash registers }. - */ - target_read_u32(target, 0xFFFFFFDC, &glbctrl); - target_write_u32(target, 0xFFFFFFDC, glbctrl | 0x10); - LOG_DEBUG("set glbctrl = 0x%08" PRIx32 "", glbctrl | 0x10); - - /* Force normal read mode. */ - target_read_u32(target, 0xFFE89C00, &orig_fmregopt); - target_write_u32(target, 0xFFE89C00, 0); - LOG_DEBUG("set fmregopt = 0x%08x", 0); - - (void)tms470_flash_initialize_internal_state_machine(bank); - - /* - * Select one or more bits in FMBSEA or FMBSEB to disable Level 1 - * protection for the particular sector to be erased/written. - */ - if (sector < 16) { - target_read_u32(target, 0xFFE88008, &fmbsea); - target_write_u32(target, 0xFFE88008, fmbsea | (1 << sector)); - LOG_DEBUG("set fmbsea = 0x%04" PRIx32 "", fmbsea | (1 << sector)); - } else { - target_read_u32(target, 0xFFE8800C, &fmbseb); - target_write_u32(target, 0xFFE8800C, fmbseb | (1 << (sector - 16))); - LOG_DEBUG("set fmbseb = 0x%04" PRIx32 "", fmbseb | (1 << (sector - 16))); - } - bank->sectors[sector].is_protected = 0; - - /* - * clear status regiser, sent erase command, kickoff erase - */ - target_write_u16(target, flashAddr, 0x0040); - LOG_DEBUG("write *(uint16_t *)0x%08" PRIx32 "=0x0040", flashAddr); - target_write_u16(target, flashAddr, 0x0020); - LOG_DEBUG("write *(uint16_t *)0x%08" PRIx32 "=0x0020", flashAddr); - target_write_u16(target, flashAddr, 0xffff); - LOG_DEBUG("write *(uint16_t *)0x%08" PRIx32 "=0xffff", flashAddr); - - /* - * Monitor FMMSTAT, busy until clear, then check and other flags for - * ultimate result of the operation. - */ - do { - target_read_u32(target, 0xFFE8BC0C, &fmmstat); - if (fmmstat & 0x0100) - alive_sleep(1); - } while (fmmstat & 0x0100); - - result = tms470_flash_status(bank); - - if (sector < 16) { - target_write_u32(target, 0xFFE88008, fmbsea); - LOG_DEBUG("set fmbsea = 0x%04" PRIx32 "", fmbsea); - bank->sectors[sector].is_protected = fmbsea & (1 << sector) ? 0 : 1; - } else { - target_write_u32(target, 0xFFE8800C, fmbseb); - LOG_DEBUG("set fmbseb = 0x%04" PRIx32 "", fmbseb); - bank->sectors[sector].is_protected = fmbseb & (1 << (sector - 16)) ? 0 : 1; - } - target_write_u32(target, 0xFFE89C00, orig_fmregopt); - LOG_DEBUG("set fmregopt = 0x%08" PRIx32 "", orig_fmregopt); - target_write_u32(target, 0xFFFFFFDC, glbctrl); - LOG_DEBUG("set glbctrl = 0x%08" PRIx32 "", glbctrl); - - if (result == ERROR_OK) - bank->sectors[sector].is_erased = 1; - - return result; -} - -/*---------------------------------------------------------------------- - * Implementation of Flash Driver Interfaces - *---------------------------------------------------------------------- */ - -static const struct command_registration tms470_any_command_handlers[] = { - { - .name = "flash_keyset", - .usage = " ", - .handler = tms470_handle_flash_keyset_command, - .mode = COMMAND_ANY, - .help = "tms470 flash_keyset ", - }, - { - .name = "osc_megahertz", - .usage = "", - .handler = tms470_handle_osc_megahertz_command, - .mode = COMMAND_ANY, - .help = "tms470 osc_megahertz ", - }, - { - .name = "plldis", - .usage = "<0 | 1>", - .handler = tms470_handle_plldis_command, - .mode = COMMAND_ANY, - .help = "tms470 plldis <0/1>", - }, - COMMAND_REGISTRATION_DONE -}; -static const struct command_registration tms470_command_handlers[] = { - { - .name = "tms470", - .mode = COMMAND_ANY, - .help = "TI tms470 flash command group", - .usage = "", - .chain = tms470_any_command_handlers, - }, - COMMAND_REGISTRATION_DONE -}; - -/* ---------------------------------------------------------------------- */ - -static int tms470_erase(struct flash_bank *bank, int first, int last) -{ - struct tms470_flash_bank *tms470_info = bank->driver_priv; - int sector, result = ERROR_OK; - - if (bank->target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - tms470_read_part_info(bank); - - if ((first < 0) || (first >= bank->num_sectors) || (last < 0) || - (last >= bank->num_sectors) || (first > last)) { - LOG_ERROR("Sector range %d to %d invalid.", first, last); - return ERROR_FLASH_SECTOR_INVALID; - } - - result = tms470_unlock_flash(bank); - if (result != ERROR_OK) - return result; - - for (sector = first; sector <= last; sector++) { - LOG_INFO("Erasing tms470 bank %d sector %d...", tms470_info->ordinal, sector); - - result = tms470_erase_sector(bank, sector); - - if (result != ERROR_OK) { - LOG_ERROR("tms470 could not erase flash sector."); - break; - } else - LOG_INFO("sector erased successfully."); - } - - return result; -} - -/* ---------------------------------------------------------------------- */ - -static int tms470_protect(struct flash_bank *bank, int set, int first, int last) -{ - struct tms470_flash_bank *tms470_info = bank->driver_priv; - struct target *target = bank->target; - uint32_t fmmac2, fmbsea, fmbseb; - int sector; - - if (target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - tms470_read_part_info(bank); - - if ((first < 0) || (first >= bank->num_sectors) || (last < 0) || - (last >= bank->num_sectors) || (first > last)) { - LOG_ERROR("Sector range %d to %d invalid.", first, last); - return ERROR_FLASH_SECTOR_INVALID; - } - - /* enable the appropriate bank */ - target_read_u32(target, 0xFFE8BC04, &fmmac2); - target_write_u32(target, 0xFFE8BC04, (fmmac2 & ~7) | tms470_info->ordinal); - - /* get the original sector proection flags for this bank */ - target_read_u32(target, 0xFFE88008, &fmbsea); - target_read_u32(target, 0xFFE8800C, &fmbseb); - - for (sector = 0; sector < bank->num_sectors; sector++) { - if (sector < 16) { - fmbsea = set ? fmbsea & ~(1 << sector) : fmbsea | (1 << sector); - bank->sectors[sector].is_protected = set ? 1 : 0; - } else { - fmbseb = set ? fmbseb & - ~(1 << (sector - 16)) : fmbseb | (1 << (sector - 16)); - bank->sectors[sector].is_protected = set ? 1 : 0; - } - } - - /* update the protection bits */ - target_write_u32(target, 0xFFE88008, fmbsea); - target_write_u32(target, 0xFFE8800C, fmbseb); - - return ERROR_OK; -} - -/* ---------------------------------------------------------------------- */ - -static int tms470_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count) -{ - struct target *target = bank->target; - uint32_t glbctrl, fmbac2, orig_fmregopt, fmbsea, fmbseb, fmmaxpp, fmmstat; - int result = ERROR_OK; - uint32_t i; - - if (target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - tms470_read_part_info(bank); - - LOG_INFO("Writing %" PRId32 " bytes starting at 0x%08" PRIx32 "", count, bank->base + - offset); - - /* set GLBCTRL.4 */ - target_read_u32(target, 0xFFFFFFDC, &glbctrl); - target_write_u32(target, 0xFFFFFFDC, glbctrl | 0x10); - - (void)tms470_flash_initialize_internal_state_machine(bank); - - /* force max wait states */ - target_read_u32(target, 0xFFE88004, &fmbac2); - target_write_u32(target, 0xFFE88004, fmbac2 | 0xff); - - /* save current access mode, force normal read mode */ - target_read_u32(target, 0xFFE89C00, &orig_fmregopt); - target_write_u32(target, 0xFFE89C00, 0x00); - - /* - * Disable Level 1 protection for all sectors to be erased/written. - */ - target_read_u32(target, 0xFFE88008, &fmbsea); - target_write_u32(target, 0xFFE88008, 0xffff); - target_read_u32(target, 0xFFE8800C, &fmbseb); - target_write_u32(target, 0xFFE8800C, 0xffff); - - /* read MAXPP */ - target_read_u32(target, 0xFFE8A07C, &fmmaxpp); - - for (i = 0; i < count; i += 2) { - uint32_t addr = bank->base + offset + i; - uint16_t word = (((uint16_t) buffer[i]) << 8) | (uint16_t) buffer[i + 1]; - - if (word != 0xffff) { - LOG_INFO("writing 0x%04x at 0x%08" PRIx32 "", word, addr); - - /* clear status register */ - target_write_u16(target, addr, 0x0040); - /* program flash command */ - target_write_u16(target, addr, 0x0010); - /* burn the 16-bit word (big-endian) */ - target_write_u16(target, addr, word); - - /* - * Monitor FMMSTAT, busy until clear, then check and other flags - * for ultimate result of the operation. - */ - do { - target_read_u32(target, 0xFFE8BC0C, &fmmstat); - if (fmmstat & 0x0100) - alive_sleep(1); - } while (fmmstat & 0x0100); - - if (fmmstat & 0x3ff) { - LOG_ERROR("fmstat = 0x%04" PRIx32 "", fmmstat); - LOG_ERROR( - "Could not program word 0x%04x at address 0x%08" PRIx32 ".", - word, - addr); - result = ERROR_FLASH_OPERATION_FAILED; - break; - } - } else - LOG_INFO("skipping 0xffff at 0x%08" PRIx32 "", addr); - } - - /* restore */ - target_write_u32(target, 0xFFE88008, fmbsea); - target_write_u32(target, 0xFFE8800C, fmbseb); - target_write_u32(target, 0xFFE88004, fmbac2); - target_write_u32(target, 0xFFE89C00, orig_fmregopt); - target_write_u32(target, 0xFFFFFFDC, glbctrl); - - return result; -} - -/* ---------------------------------------------------------------------- */ - -static int tms470_probe(struct flash_bank *bank) -{ - if (bank->target->state != TARGET_HALTED) { - LOG_WARNING("Cannot communicate... target not halted."); - return ERROR_TARGET_NOT_HALTED; - } - - return tms470_read_part_info(bank); -} - -static int tms470_auto_probe(struct flash_bank *bank) -{ - struct tms470_flash_bank *tms470_info = bank->driver_priv; - - if (tms470_info->device_ident_reg) - return ERROR_OK; - return tms470_probe(bank); -} - -/* ---------------------------------------------------------------------- */ - -static int tms470_erase_check(struct flash_bank *bank) -{ - struct target *target = bank->target; - struct tms470_flash_bank *tms470_info = bank->driver_priv; - int sector, result = ERROR_OK; - uint32_t fmmac2, fmbac2, glbctrl, orig_fmregopt; - static uint8_t buffer[64 * 1024]; - - if (target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - if (!tms470_info->device_ident_reg) - tms470_read_part_info(bank); - - /* set GLBCTRL.4 */ - target_read_u32(target, 0xFFFFFFDC, &glbctrl); - target_write_u32(target, 0xFFFFFFDC, glbctrl | 0x10); - - /* save current access mode, force normal read mode */ - target_read_u32(target, 0xFFE89C00, &orig_fmregopt); - target_write_u32(target, 0xFFE89C00, 0x00); - - /* enable the appropriate bank */ - target_read_u32(target, 0xFFE8BC04, &fmmac2); - target_write_u32(target, 0xFFE8BC04, (fmmac2 & ~7) | tms470_info->ordinal); - - /* TCR = 0 */ - target_write_u32(target, 0xFFE8BC10, 0x2fc0); - - /* clear TEZ in fmbrdy */ - target_write_u32(target, 0xFFE88010, 0x0b); - - /* save current wait states, force max */ - target_read_u32(target, 0xFFE88004, &fmbac2); - target_write_u32(target, 0xFFE88004, fmbac2 | 0xff); - - /* - * The TI primitives inspect the flash memory by reading one 32-bit - * word at a time. Here we read an entire sector and inspect it in - * an attempt to reduce the JTAG overhead. - */ - for (sector = 0; sector < bank->num_sectors; sector++) { - if (bank->sectors[sector].is_erased != 1) { - uint32_t i, addr = bank->base + bank->sectors[sector].offset; - - LOG_INFO("checking flash bank %d sector %d", tms470_info->ordinal, sector); - - target_read_buffer(target, addr, bank->sectors[sector].size, buffer); - - bank->sectors[sector].is_erased = 1; - for (i = 0; i < bank->sectors[sector].size; i++) { - if (buffer[i] != 0xff) { - LOG_WARNING("tms470 bank %d, sector %d, not erased.", - tms470_info->ordinal, - sector); - LOG_WARNING( - "at location 0x%08" PRIx32 ": flash data is 0x%02x.", - addr + i, - buffer[i]); - - bank->sectors[sector].is_erased = 0; - break; - } - } - } - if (bank->sectors[sector].is_erased != 1) { - result = ERROR_FLASH_SECTOR_NOT_ERASED; - break; - } else - LOG_INFO("sector erased"); - } - - /* reset TEZ, wait states, read mode, GLBCTRL.4 */ - target_write_u32(target, 0xFFE88010, 0x0f); - target_write_u32(target, 0xFFE88004, fmbac2); - target_write_u32(target, 0xFFE89C00, orig_fmregopt); - target_write_u32(target, 0xFFFFFFDC, glbctrl); - - return result; -} - -/* ---------------------------------------------------------------------- */ - -static int tms470_protect_check(struct flash_bank *bank) -{ - struct target *target = bank->target; - struct tms470_flash_bank *tms470_info = bank->driver_priv; - int sector, result = ERROR_OK; - uint32_t fmmac2, fmbsea, fmbseb; - - if (target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - if (!tms470_info->device_ident_reg) - tms470_read_part_info(bank); - - /* enable the appropriate bank */ - target_read_u32(target, 0xFFE8BC04, &fmmac2); - target_write_u32(target, 0xFFE8BC04, (fmmac2 & ~7) | tms470_info->ordinal); - - target_read_u32(target, 0xFFE88008, &fmbsea); - target_read_u32(target, 0xFFE8800C, &fmbseb); - - for (sector = 0; sector < bank->num_sectors; sector++) { - int protected; - - if (sector < 16) { - protected = fmbsea & (1 << sector) ? 0 : 1; - bank->sectors[sector].is_protected = protected; - } else { - protected = fmbseb & (1 << (sector - 16)) ? 0 : 1; - bank->sectors[sector].is_protected = protected; - } - - LOG_DEBUG("bank %d sector %d is %s", - tms470_info->ordinal, - sector, - protected ? "protected" : "not protected"); - } - - return result; -} - -/* ---------------------------------------------------------------------- */ - -static int get_tms470_info(struct flash_bank *bank, char *buf, int buf_size) -{ - int used = 0; - struct tms470_flash_bank *tms470_info = bank->driver_priv; - - if (!tms470_info->device_ident_reg) - tms470_read_part_info(bank); - - if (!tms470_info->device_ident_reg) { - (void)snprintf(buf, buf_size, "Cannot identify target as a TMS470\n"); - return ERROR_FLASH_OPERATION_FAILED; - } - - used = - snprintf(buf, buf_size, "\ntms470 information: Chip is %s\n", - tms470_info->part_name); - buf += used; - buf_size -= used; - - snprintf(buf, buf_size, "Flash protection level 2 is %s\n", - tms470_check_flash_unlocked(bank->target) == ERROR_OK ? "disabled" : "enabled"); - - return ERROR_OK; -} - -/* ---------------------------------------------------------------------- */ - -/* - * flash bank tms470 - * [options...] - */ - -FLASH_BANK_COMMAND_HANDLER(tms470_flash_bank_command) -{ - bank->driver_priv = malloc(sizeof(struct tms470_flash_bank)); - - if (!bank->driver_priv) - return ERROR_FLASH_OPERATION_FAILED; - - (void)memset(bank->driver_priv, 0, sizeof(struct tms470_flash_bank)); - - return ERROR_OK; -} - -struct flash_driver tms470_flash = { - .name = "tms470", - .commands = tms470_command_handlers, - .flash_bank_command = tms470_flash_bank_command, - .erase = tms470_erase, - .protect = tms470_protect, - .write = tms470_write, - .read = default_flash_read, - .probe = tms470_probe, - .auto_probe = tms470_auto_probe, - .erase_check = tms470_erase_check, - .protect_check = tms470_protect_check, - .info = get_tms470_info, -}; diff --git a/src/flash/nor/virtual.c b/src/flash/nor/virtual.c deleted file mode 100644 index 3cb793e30..000000000 --- a/src/flash/nor/virtual.c +++ /dev/null @@ -1,233 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2010 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "imp.h" - -static struct flash_bank *virtual_get_master_bank(struct flash_bank *bank) -{ - struct flash_bank *master_bank; - - master_bank = get_flash_bank_by_name_noprobe(bank->driver_priv); - if (master_bank == NULL) - LOG_ERROR("master flash bank '%s' does not exist", (char *)bank->driver_priv); - - return master_bank; -} - -static void virtual_update_bank_info(struct flash_bank *bank) -{ - struct flash_bank *master_bank = virtual_get_master_bank(bank); - - if (master_bank == NULL) - return; - - /* update the info we do not have */ - bank->size = master_bank->size; - bank->chip_width = master_bank->chip_width; - bank->bus_width = master_bank->bus_width; - bank->default_padded_value = master_bank->default_padded_value; - bank->num_sectors = master_bank->num_sectors; - bank->sectors = master_bank->sectors; -} - -FLASH_BANK_COMMAND_HANDLER(virtual_flash_bank_command) -{ - if (CMD_ARGC < 7) - return ERROR_COMMAND_SYNTAX_ERROR; - - /* get the master flash bank */ - const char *bank_name = CMD_ARGV[6]; - struct flash_bank *master_bank = get_flash_bank_by_name_noprobe(bank_name); - - if (master_bank == NULL) { - LOG_ERROR("master flash bank '%s' does not exist", bank_name); - return ERROR_FLASH_OPERATION_FAILED; - } - - /* save master bank name - use this to get settings later */ - bank->driver_priv = strdup(bank_name); - - return ERROR_OK; -} - -static int virtual_protect(struct flash_bank *bank, int set, int first, int last) -{ - struct flash_bank *master_bank = virtual_get_master_bank(bank); - int retval; - - if (master_bank == NULL) - return ERROR_FLASH_OPERATION_FAILED; - - /* call master handler */ - retval = master_bank->driver->protect(master_bank, set, first, last); - if (retval != ERROR_OK) - return retval; - - return ERROR_OK; -} - -static int virtual_protect_check(struct flash_bank *bank) -{ - struct flash_bank *master_bank = virtual_get_master_bank(bank); - int retval; - - if (master_bank == NULL) - return ERROR_FLASH_OPERATION_FAILED; - - /* call master handler */ - retval = master_bank->driver->protect_check(master_bank); - if (retval != ERROR_OK) - return retval; - - return ERROR_OK; -} - -static int virtual_erase(struct flash_bank *bank, int first, int last) -{ - struct flash_bank *master_bank = virtual_get_master_bank(bank); - int retval; - - if (master_bank == NULL) - return ERROR_FLASH_OPERATION_FAILED; - - /* call master handler */ - retval = master_bank->driver->erase(master_bank, first, last); - if (retval != ERROR_OK) - return retval; - - return ERROR_OK; -} - -static int virtual_write(struct flash_bank *bank, const uint8_t *buffer, - uint32_t offset, uint32_t count) -{ - struct flash_bank *master_bank = virtual_get_master_bank(bank); - int retval; - - if (master_bank == NULL) - return ERROR_FLASH_OPERATION_FAILED; - - /* call master handler */ - retval = master_bank->driver->write(master_bank, buffer, offset, count); - if (retval != ERROR_OK) - return retval; - - return ERROR_OK; -} - -static int virtual_probe(struct flash_bank *bank) -{ - struct flash_bank *master_bank = virtual_get_master_bank(bank); - int retval; - - if (master_bank == NULL) - return ERROR_FLASH_OPERATION_FAILED; - - /* call master handler */ - retval = master_bank->driver->probe(master_bank); - if (retval != ERROR_OK) - return retval; - - /* update the info we do not have */ - virtual_update_bank_info(bank); - - return ERROR_OK; -} - -static int virtual_auto_probe(struct flash_bank *bank) -{ - struct flash_bank *master_bank = virtual_get_master_bank(bank); - int retval; - - if (master_bank == NULL) - return ERROR_FLASH_OPERATION_FAILED; - - /* call master handler */ - retval = master_bank->driver->auto_probe(master_bank); - if (retval != ERROR_OK) - return retval; - - /* update the info we do not have */ - virtual_update_bank_info(bank); - - return ERROR_OK; -} - -static int virtual_info(struct flash_bank *bank, char *buf, int buf_size) -{ - struct flash_bank *master_bank = virtual_get_master_bank(bank); - - if (master_bank == NULL) - return ERROR_FLASH_OPERATION_FAILED; - - snprintf(buf, buf_size, "%s driver for flash bank %s at 0x%8.8" PRIx32 "", - bank->driver->name, master_bank->name, master_bank->base); - - return ERROR_OK; -} - -static int virtual_blank_check(struct flash_bank *bank) -{ - struct flash_bank *master_bank = virtual_get_master_bank(bank); - int retval; - - if (master_bank == NULL) - return ERROR_FLASH_OPERATION_FAILED; - - /* call master handler */ - retval = master_bank->driver->erase_check(master_bank); - if (retval != ERROR_OK) - return retval; - - return ERROR_OK; -} - -static int virtual_flash_read(struct flash_bank *bank, - uint8_t *buffer, uint32_t offset, uint32_t count) -{ - struct flash_bank *master_bank = virtual_get_master_bank(bank); - int retval; - - if (master_bank == NULL) - return ERROR_FLASH_OPERATION_FAILED; - - /* call master handler */ - retval = master_bank->driver->read(master_bank, buffer, offset, count); - if (retval != ERROR_OK) - return retval; - - return ERROR_OK; -} - -struct flash_driver virtual_flash = { - .name = "virtual", - .flash_bank_command = virtual_flash_bank_command, - .erase = virtual_erase, - .protect = virtual_protect, - .write = virtual_write, - .read = virtual_flash_read, - .probe = virtual_probe, - .auto_probe = virtual_auto_probe, - .erase_check = virtual_blank_check, - .protect_check = virtual_protect_check, - .info = virtual_info, -}; diff --git a/src/flash/nor/xmc1xxx.c b/src/flash/nor/xmc1xxx.c deleted file mode 100644 index bb2ec1272..000000000 --- a/src/flash/nor/xmc1xxx.c +++ /dev/null @@ -1,549 +0,0 @@ -/* - * XMC1000 flash driver - * - * Copyright (c) 2016 Andreas Färber - * - * License: GPL-2.0+ - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "imp.h" -#include -#include -#include - -#define FLASH_BASE 0x10000000 -#define PAU_BASE 0x40000000 -#define SCU_BASE 0x40010000 -#define NVM_BASE 0x40050000 - -#define FLASH_CS0 (FLASH_BASE + 0xf00) - -#define PAU_FLSIZE (PAU_BASE + 0x404) - -#define SCU_IDCHIP (SCU_BASE + 0x004) - -#define NVMSTATUS (NVM_BASE + 0x00) -#define NVMPROG (NVM_BASE + 0x04) -#define NVMCONF (NVM_BASE + 0x08) - -#define NVMSTATUS_BUSY (1 << 0) -#define NVMSTATUS_VERR_MASK (0x3 << 2) - -#define NVMPROG_ACTION_OPTYPE_IDLE_VERIFY (0 << 0) -#define NVMPROG_ACTION_OPTYPE_WRITE (1 << 0) -#define NVMPROG_ACTION_OPTYPE_PAGE_ERASE (2 << 0) - -#define NVMPROG_ACTION_ONE_SHOT_ONCE (1 << 4) -#define NVMPROG_ACTION_ONE_SHOT_CONTINUOUS (2 << 4) - -#define NVMPROG_ACTION_VERIFY_EACH (1 << 6) -#define NVMPROG_ACTION_VERIFY_NO (2 << 6) -#define NVMPROG_ACTION_VERIFY_ARRAY (3 << 6) - -#define NVMPROG_ACTION_IDLE 0x00 -#define NVMPROG_ACTION_MASK 0xff - -#define NVM_WORD_SIZE 4 -#define NVM_BLOCK_SIZE (4 * NVM_WORD_SIZE) -#define NVM_PAGE_SIZE (16 * NVM_BLOCK_SIZE) - -struct xmc1xxx_flash_bank { - bool probed; -}; - -static int xmc1xxx_nvm_set_idle(struct target *target) -{ - return target_write_u16(target, NVMPROG, NVMPROG_ACTION_IDLE); -} - -static int xmc1xxx_nvm_check_idle(struct target *target) -{ - uint16_t val; - int retval; - - retval = target_read_u16(target, NVMPROG, &val); - if (retval != ERROR_OK) - return retval; - if ((val & NVMPROG_ACTION_MASK) != NVMPROG_ACTION_IDLE) { - LOG_WARNING("NVMPROG.ACTION"); - retval = xmc1xxx_nvm_set_idle(target); - } - - return retval; -} - -static int xmc1xxx_erase(struct flash_bank *bank, int first, int last) -{ - struct target *target = bank->target; - struct working_area *workarea; - struct reg_param reg_params[3]; - struct armv7m_algorithm armv7m_algo; - unsigned i; - int retval, sector; - const uint8_t erase_code[] = { -#include "../../../contrib/loaders/flash/xmc1xxx/erase.inc" - }; - - LOG_DEBUG("Infineon XMC1000 erase sectors %d to %d", first, last); - - if (bank->target->state != TARGET_HALTED) { - LOG_WARNING("Cannot communicate... target not halted."); - return ERROR_TARGET_NOT_HALTED; - } - - retval = xmc1xxx_nvm_check_idle(target); - if (retval != ERROR_OK) - return retval; - - retval = target_alloc_working_area(target, sizeof(erase_code), - &workarea); - if (retval != ERROR_OK) { - LOG_ERROR("No working area available."); - retval = ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - goto err_alloc_code; - } - retval = target_write_buffer(target, workarea->address, - sizeof(erase_code), erase_code); - if (retval != ERROR_OK) - goto err_write_code; - - armv7m_algo.common_magic = ARMV7M_COMMON_MAGIC; - armv7m_algo.core_mode = ARM_MODE_THREAD; - - init_reg_param(®_params[0], "r0", 32, PARAM_OUT); - init_reg_param(®_params[1], "r1", 32, PARAM_OUT); - init_reg_param(®_params[2], "r2", 32, PARAM_OUT); - - buf_set_u32(reg_params[0].value, 0, 32, NVM_BASE); - buf_set_u32(reg_params[1].value, 0, 32, bank->base + - bank->sectors[first].offset); - buf_set_u32(reg_params[2].value, 0, 32, bank->base + - bank->sectors[last].offset + bank->sectors[last].size); - - retval = target_run_algorithm(target, - 0, NULL, - ARRAY_SIZE(reg_params), reg_params, - workarea->address, 0, - 1000, &armv7m_algo); - if (retval != ERROR_OK) { - LOG_ERROR("Error executing flash sector erase " - "programming algorithm"); - retval = xmc1xxx_nvm_set_idle(target); - if (retval != ERROR_OK) - LOG_WARNING("Couldn't restore NVMPROG.ACTION"); - retval = ERROR_FLASH_OPERATION_FAILED; - goto err_run; - } - - for (sector = first; sector <= last; sector++) - bank->sectors[sector].is_erased = 1; - -err_run: - for (i = 0; i < ARRAY_SIZE(reg_params); i++) - destroy_reg_param(®_params[i]); - -err_write_code: - target_free_working_area(target, workarea); - -err_alloc_code: - return retval; -} - -static int xmc1xxx_erase_check(struct flash_bank *bank) -{ - struct target *target = bank->target; - struct working_area *workarea; - struct reg_param reg_params[3]; - struct armv7m_algorithm armv7m_algo; - uint16_t val; - unsigned i; - int retval, sector; - const uint8_t erase_check_code[] = { -#include "../../../contrib/loaders/flash/xmc1xxx/erase_check.inc" - }; - - if (bank->target->state != TARGET_HALTED) { - LOG_WARNING("Cannot communicate... target not halted."); - return ERROR_TARGET_NOT_HALTED; - } - - retval = target_alloc_working_area(target, sizeof(erase_check_code), - &workarea); - if (retval != ERROR_OK) { - LOG_ERROR("No working area available."); - retval = ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - goto err_alloc_code; - } - retval = target_write_buffer(target, workarea->address, - sizeof(erase_check_code), erase_check_code); - if (retval != ERROR_OK) - goto err_write_code; - - armv7m_algo.common_magic = ARMV7M_COMMON_MAGIC; - armv7m_algo.core_mode = ARM_MODE_THREAD; - - init_reg_param(®_params[0], "r0", 32, PARAM_OUT); - init_reg_param(®_params[1], "r1", 32, PARAM_OUT); - init_reg_param(®_params[2], "r2", 32, PARAM_OUT); - - buf_set_u32(reg_params[0].value, 0, 32, NVM_BASE); - - for (sector = 0; sector < bank->num_sectors; sector++) { - uint32_t start = bank->base + bank->sectors[sector].offset; - buf_set_u32(reg_params[1].value, 0, 32, start); - buf_set_u32(reg_params[2].value, 0, 32, start + bank->sectors[sector].size); - - retval = xmc1xxx_nvm_check_idle(target); - if (retval != ERROR_OK) - goto err_nvmprog; - - LOG_DEBUG("Erase-checking 0x%08" PRIx32, start); - retval = target_run_algorithm(target, - 0, NULL, - ARRAY_SIZE(reg_params), reg_params, - workarea->address, 0, - 1000, &armv7m_algo); - if (retval != ERROR_OK) { - LOG_ERROR("Error executing flash sector erase check " - "programming algorithm"); - retval = xmc1xxx_nvm_set_idle(target); - if (retval != ERROR_OK) - LOG_WARNING("Couldn't restore NVMPROG.ACTION"); - retval = ERROR_FLASH_OPERATION_FAILED; - goto err_run; - } - - retval = target_read_u16(target, NVMSTATUS, &val); - if (retval != ERROR_OK) { - LOG_ERROR("Couldn't read NVMSTATUS"); - goto err_nvmstatus; - } - bank->sectors[sector].is_erased = (val & NVMSTATUS_VERR_MASK) ? 0 : 1; - } - -err_nvmstatus: -err_run: -err_nvmprog: - for (i = 0; i < ARRAY_SIZE(reg_params); i++) - destroy_reg_param(®_params[i]); - -err_write_code: - target_free_working_area(target, workarea); - -err_alloc_code: - return retval; -} - -static int xmc1xxx_write(struct flash_bank *bank, const uint8_t *buffer, - uint32_t offset, uint32_t byte_count) -{ - struct target *target = bank->target; - struct working_area *code_workarea, *data_workarea; - struct reg_param reg_params[4]; - struct armv7m_algorithm armv7m_algo; - uint32_t block_count = DIV_ROUND_UP(byte_count, NVM_BLOCK_SIZE); - unsigned i; - int retval; - const uint8_t write_code[] = { -#include "../../../contrib/loaders/flash/xmc1xxx/write.inc" - }; - - LOG_DEBUG("Infineon XMC1000 write at 0x%08" PRIx32 " (%" PRId32 " bytes)", - offset, byte_count); - - if (offset & (NVM_BLOCK_SIZE - 1)) { - LOG_ERROR("offset 0x%" PRIx32 " breaks required block alignment", - offset); - return ERROR_FLASH_DST_BREAKS_ALIGNMENT; - } - if (byte_count & (NVM_BLOCK_SIZE - 1)) { - LOG_WARNING("length %" PRId32 " is not block aligned, rounding up", - byte_count); - } - - if (target->state != TARGET_HALTED) { - LOG_WARNING("Cannot communicate... target not halted."); - return ERROR_TARGET_NOT_HALTED; - } - - retval = target_alloc_working_area(target, sizeof(write_code), - &code_workarea); - if (retval != ERROR_OK) { - LOG_ERROR("No working area available for write code."); - retval = ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - goto err_alloc_code; - } - retval = target_write_buffer(target, code_workarea->address, - sizeof(write_code), write_code); - if (retval != ERROR_OK) - goto err_write_code; - - retval = target_alloc_working_area(target, MAX(NVM_BLOCK_SIZE, - MIN(block_count * NVM_BLOCK_SIZE, target_get_working_area_avail(target))), - &data_workarea); - if (retval != ERROR_OK) { - LOG_ERROR("No working area available for write data."); - retval = ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - goto err_alloc_data; - } - - armv7m_algo.common_magic = ARMV7M_COMMON_MAGIC; - armv7m_algo.core_mode = ARM_MODE_THREAD; - - init_reg_param(®_params[0], "r0", 32, PARAM_OUT); - init_reg_param(®_params[1], "r1", 32, PARAM_OUT); - init_reg_param(®_params[2], "r2", 32, PARAM_OUT); - init_reg_param(®_params[3], "r3", 32, PARAM_OUT); - - buf_set_u32(reg_params[0].value, 0, 32, NVM_BASE); - - while (byte_count > 0) { - uint32_t blocks = MIN(block_count, data_workarea->size / NVM_BLOCK_SIZE); - uint32_t addr = bank->base + offset; - - LOG_DEBUG("copying %" PRId32 " bytes to SRAM 0x%08" PRIx32, - MIN(blocks * NVM_BLOCK_SIZE, byte_count), - data_workarea->address); - - retval = target_write_buffer(target, data_workarea->address, - MIN(blocks * NVM_BLOCK_SIZE, byte_count), buffer); - if (retval != ERROR_OK) { - LOG_ERROR("Error writing data buffer"); - retval = ERROR_FLASH_OPERATION_FAILED; - goto err_write_data; - } - if (byte_count < blocks * NVM_BLOCK_SIZE) { - retval = target_write_memory(target, - data_workarea->address + byte_count, 1, - blocks * NVM_BLOCK_SIZE - byte_count, - &bank->default_padded_value); - if (retval != ERROR_OK) { - LOG_ERROR("Error writing data padding"); - retval = ERROR_FLASH_OPERATION_FAILED; - goto err_write_pad; - } - } - - LOG_DEBUG("writing 0x%08" PRIx32 "-0x%08" PRIx32 " (%" PRId32 "x)", - addr, addr + blocks * NVM_BLOCK_SIZE - 1, blocks); - - retval = xmc1xxx_nvm_check_idle(target); - if (retval != ERROR_OK) - goto err_nvmprog; - - buf_set_u32(reg_params[1].value, 0, 32, addr); - buf_set_u32(reg_params[2].value, 0, 32, data_workarea->address); - buf_set_u32(reg_params[3].value, 0, 32, blocks); - - retval = target_run_algorithm(target, - 0, NULL, - ARRAY_SIZE(reg_params), reg_params, - code_workarea->address, 0, - 5 * 60 * 1000, &armv7m_algo); - if (retval != ERROR_OK) { - LOG_ERROR("Error executing flash write " - "programming algorithm"); - retval = xmc1xxx_nvm_set_idle(target); - if (retval != ERROR_OK) - LOG_WARNING("Couldn't restore NVMPROG.ACTION"); - retval = ERROR_FLASH_OPERATION_FAILED; - goto err_run; - } - - block_count -= blocks; - offset += blocks * NVM_BLOCK_SIZE; - buffer += blocks * NVM_BLOCK_SIZE; - byte_count -= MIN(blocks * NVM_BLOCK_SIZE, byte_count); - } - -err_run: -err_nvmprog: -err_write_pad: -err_write_data: - for (i = 0; i < ARRAY_SIZE(reg_params); i++) - destroy_reg_param(®_params[i]); - - target_free_working_area(target, data_workarea); -err_alloc_data: -err_write_code: - target_free_working_area(target, code_workarea); - -err_alloc_code: - return retval; -} - -static int xmc1xxx_protect_check(struct flash_bank *bank) -{ - uint32_t nvmconf; - int i, num_protected, retval; - - if (bank->target->state != TARGET_HALTED) { - LOG_WARNING("Cannot communicate... target not halted."); - return ERROR_TARGET_NOT_HALTED; - } - - retval = target_read_u32(bank->target, NVMCONF, &nvmconf); - if (retval != ERROR_OK) { - LOG_ERROR("Cannot read NVMCONF register."); - return retval; - } - LOG_DEBUG("NVMCONF = %08" PRIx32, nvmconf); - - num_protected = (nvmconf >> 4) & 0xff; - - for (i = 0; i < bank->num_sectors; i++) - bank->sectors[i].is_protected = (i < num_protected) ? 1 : 0; - - return ERROR_OK; -} - -static int xmc1xxx_get_info_command(struct flash_bank *bank, char *buf, int buf_size) -{ - uint32_t chipid[8]; - int i, retval; - - if (bank->target->state != TARGET_HALTED) { - LOG_WARNING("Cannot communicate... target not halted."); - return ERROR_TARGET_NOT_HALTED; - } - - /* Obtain the 8-word Chip Identification Number */ - for (i = 0; i < 7; i++) { - retval = target_read_u32(bank->target, FLASH_CS0 + i * 4, &chipid[i]); - if (retval != ERROR_OK) { - LOG_ERROR("Cannot read CS0 register %i.", i); - return retval; - } - LOG_DEBUG("ID[%d] = %08" PRIX32, i, chipid[i]); - } - retval = target_read_u32(bank->target, SCU_BASE + 0x000, &chipid[7]); - if (retval != ERROR_OK) { - LOG_ERROR("Cannot read DBGROMID register."); - return retval; - } - LOG_DEBUG("ID[7] = %08" PRIX32, chipid[7]); - - snprintf(buf, buf_size, "XMC%" PRIx32 "00 %X flash %uKB ROM %uKB SRAM %uKB", - (chipid[0] >> 12) & 0xff, - 0xAA + (chipid[7] >> 28) - 1, - (((chipid[6] >> 12) & 0x3f) - 1) * 4, - (((chipid[4] >> 8) & 0x3f) * 256) / 1024, - (((chipid[5] >> 8) & 0x1f) * 256 * 4) / 1024); - - return ERROR_OK; -} - -static int xmc1xxx_probe(struct flash_bank *bank) -{ - struct xmc1xxx_flash_bank *xmc_bank = bank->driver_priv; - uint32_t flash_addr = bank->base; - uint32_t idchip, flsize; - int i, retval; - - if (xmc_bank->probed) - return ERROR_OK; - - if (bank->target->state != TARGET_HALTED) { - LOG_WARNING("Cannot communicate... target not halted."); - return ERROR_TARGET_NOT_HALTED; - } - - retval = target_read_u32(bank->target, SCU_IDCHIP, &idchip); - if (retval != ERROR_OK) { - LOG_ERROR("Cannot read IDCHIP register."); - return retval; - } - - if ((idchip & 0xffff0000) != 0x10000) { - LOG_ERROR("IDCHIP register does not match XMC1xxx."); - return ERROR_FAIL; - } - - LOG_DEBUG("IDCHIP = %08" PRIx32, idchip); - - retval = target_read_u32(bank->target, PAU_FLSIZE, &flsize); - if (retval != ERROR_OK) { - LOG_ERROR("Cannot read FLSIZE register."); - return retval; - } - - bank->num_sectors = 1 + ((flsize >> 12) & 0x3f) - 1; - bank->size = bank->num_sectors * 4 * 1024; - bank->sectors = calloc(bank->num_sectors, - sizeof(struct flash_sector)); - for (i = 0; i < bank->num_sectors; i++) { - if (i == 0) { - bank->sectors[i].size = 0x200; - bank->sectors[i].offset = 0xE00; - flash_addr += 0x1000; - } else { - bank->sectors[i].size = 4 * 1024; - bank->sectors[i].offset = flash_addr - bank->base; - flash_addr += bank->sectors[i].size; - } - bank->sectors[i].is_erased = -1; - bank->sectors[i].is_protected = -1; - } - - xmc_bank->probed = true; - - return ERROR_OK; -} - -static int xmc1xxx_auto_probe(struct flash_bank *bank) -{ - struct xmc1xxx_flash_bank *xmc_bank = bank->driver_priv; - - if (xmc_bank->probed) - return ERROR_OK; - - return xmc1xxx_probe(bank); -} - -FLASH_BANK_COMMAND_HANDLER(xmc1xxx_flash_bank_command) -{ - struct xmc1xxx_flash_bank *xmc_bank; - - xmc_bank = malloc(sizeof(struct xmc1xxx_flash_bank)); - if (!xmc_bank) - return ERROR_FLASH_OPERATION_FAILED; - - xmc_bank->probed = false; - - bank->driver_priv = xmc_bank; - - return ERROR_OK; -} - -static const struct command_registration xmc1xxx_exec_command_handlers[] = { - COMMAND_REGISTRATION_DONE -}; - -static const struct command_registration xmc1xxx_command_handlers[] = { - { - .name = "xmc1xxx", - .mode = COMMAND_ANY, - .help = "xmc1xxx flash command group", - .usage = "", - .chain = xmc1xxx_exec_command_handlers, - }, - COMMAND_REGISTRATION_DONE -}; - -struct flash_driver xmc1xxx_flash = { - .name = "xmc1xxx", - .commands = xmc1xxx_command_handlers, - .flash_bank_command = xmc1xxx_flash_bank_command, - .info = xmc1xxx_get_info_command, - .probe = xmc1xxx_probe, - .auto_probe = xmc1xxx_auto_probe, - .protect_check = xmc1xxx_protect_check, - .read = default_flash_read, - .erase = xmc1xxx_erase, - .erase_check = xmc1xxx_erase_check, - .write = xmc1xxx_write, -}; diff --git a/src/flash/nor/xmc4xxx.c b/src/flash/nor/xmc4xxx.c deleted file mode 100644 index 39aec7910..000000000 --- a/src/flash/nor/xmc4xxx.c +++ /dev/null @@ -1,1444 +0,0 @@ -/************************************************************************** -* Copyright (C) 2015 Jeff Ciesielski * -* * -* This program is free software; you can redistribute it and/or modify * -* it under the terms of the GNU General Public License as published by * -* the Free Software Foundation; either version 2 of the License, or * -* (at your option) any later version. * -* * -* This program is distributed in the hope that it will be useful, * -* but WITHOUT ANY WARRANTY; without even the implied warranty of * -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -* GNU General 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 -#include "config.h" -#endif - -#include "imp.h" -#include -#include -#include - -/* Maximum number of sectors */ -#define MAX_XMC_SECTORS 12 - -/* System control unit registers */ -#define SCU_REG_BASE 0x50004000 - -#define SCU_ID_CHIP 0x04 - -/* Base of the non-cached flash memory */ -#define PFLASH_BASE 0x0C000000 - -/* User configuration block offsets */ -#define UCB0_BASE 0x00000000 -#define UCB1_BASE 0x00000400 -#define UCB2_BASE 0x00000800 - -/* Flash register base */ -#define FLASH_REG_BASE 0x58000000 - -/* PMU ID Registers */ -#define FLASH_REG_PMU_ID (FLASH_REG_BASE | 0x0508) - -/* PMU Fields */ -#define PMU_MOD_REV_MASK 0xFF -#define PMU_MOD_TYPE_MASK 0xFF00 -#define PMU_MOD_NO_MASK 0xFFFF0000 - -/* Prefetch Config */ -#define FLASH_REG_PREF_PCON (FLASH_REG_BASE | 0x4000) - -/* Prefetch Fields */ -#define PCON_IBYP (1 << 0) -#define PCON_IINV (1 << 1) - -/* Flash ID Register */ -#define FLASH_REG_FLASH0_ID (FLASH_REG_BASE | 0x2008) - -/* Flash Status Register */ -#define FLASH_REG_FLASH0_FSR (FLASH_REG_BASE | 0x2010) - -#define FSR_PBUSY (0) -#define FSR_FABUSY (1) -#define FSR_PROG (4) -#define FSR_ERASE (5) -#define FSR_PFPAGE (6) -#define FSR_PFOPER (8) -#define FSR_SQER (10) -#define FSR_PROER (11) -#define FSR_PFSBER (12) -#define FSR_PFDBER (14) -#define FSR_PROIN (16) -#define FSR_RPROIN (18) -#define FSR_RPRODIS (19) -#define FSR_WPROIN0 (21) -#define FSR_WPROIN1 (22) -#define FSR_WPROIN2 (23) -#define FSR_WPRODIS0 (25) -#define FSR_WPRODIS1 (26) -#define FSR_SLM (28) -#define FSR_VER (31) - -#define FSR_PBUSY_MASK (0x01 << FSR_PBUSY) -#define FSR_FABUSY_MASK (0x01 << FSR_FABUSY) -#define FSR_PROG_MASK (0x01 << FSR_PROG) -#define FSR_ERASE_MASK (0x01 << FSR_ERASE) -#define FSR_PFPAGE_MASK (0x01 << FSR_PFPAGE) -#define FSR_PFOPER_MASK (0x01 << FSR_PFOPER) -#define FSR_SQER_MASK (0x01 << FSR_SQER) -#define FSR_PROER_MASK (0x01 << FSR_PROER) -#define FSR_PFSBER_MASK (0x01 << FSR_PFSBER) -#define FSR_PFDBER_MASK (0x01 << FSR_PFDBER) -#define FSR_PROIN_MASK (0x01 << FSR_PROIN) -#define FSR_RPROIN_MASK (0x01 << FSR_RPROIN) -#define FSR_RPRODIS_MASK (0x01 << FSR_RPRODIS) -#define FSR_WPROIN0_MASK (0x01 << FSR_WPROIN0) -#define FSR_WPROIN1_MASK (0x01 << FSR_WPROIN1) -#define FSR_WPROIN2_MASK (0x01 << FSR_WPROIN2) -#define FSR_WPRODIS0_MASK (0x01 << FSR_WPRODIS0) -#define FSR_WPRODIS1_MASK (0x01 << FSR_WPRODIS1) -#define FSR_SLM_MASK (0x01 << FSR_SLM) -#define FSR_VER_MASK (0x01 << FSR_VER) - -/* Flash Config Register */ -#define FLASH_REG_FLASH0_FCON (FLASH_REG_BASE | 0x2014) - -#define FCON_WSPFLASH (0) -#define FCON_WSECPF (4) -#define FCON_IDLE (13) -#define FCON_ESLDIS (14) -#define FCON_SLEEP (15) -#define FCON_RPA (16) -#define FCON_DCF (17) -#define FCON_DDF (18) -#define FCON_VOPERM (24) -#define FCON_SQERM (25) -#define FCON_PROERM (26) -#define FCON_PFSBERM (27) -#define FCON_PFDBERM (29) -#define FCON_EOBM (31) - -#define FCON_WSPFLASH_MASK (0x0f << FCON_WSPFLASH) -#define FCON_WSECPF_MASK (0x01 << FCON_WSECPF) -#define FCON_IDLE_MASK (0x01 << FCON_IDLE) -#define FCON_ESLDIS_MASK (0x01 << FCON_ESLDIS) -#define FCON_SLEEP_MASK (0x01 << FCON_SLEEP) -#define FCON_RPA_MASK (0x01 << FCON_RPA) -#define FCON_DCF_MASK (0x01 << FCON_DCF) -#define FCON_DDF_MASK (0x01 << FCON_DDF) -#define FCON_VOPERM_MASK (0x01 << FCON_VOPERM) -#define FCON_SQERM_MASK (0x01 << FCON_SQERM) -#define FCON_PROERM_MASK (0x01 << FCON_PROERM) -#define FCON_PFSBERM_MASK (0x01 << FCON_PFSBERM) -#define FCON_PFDBERM_MASK (0x01 << FCON_PFDBERM) -#define FCON_EOBM_MASK (0x01 << FCON_EOBM) - -/* Flash Margin Control Register */ -#define FLASH_REG_FLASH0_MARP (FLASH_REG_BASE | 0x2018) - -#define MARP_MARGIN (0) -#define MARP_TRAPDIS (15) - -#define MARP_MARGIN_MASK (0x0f << MARP_MARGIN) -#define MARP_TRAPDIS_MASK (0x01 << MARP_TRAPDIS) - -/* Flash Protection Registers */ -#define FLASH_REG_FLASH0_PROCON0 (FLASH_REG_BASE | 0x2020) -#define FLASH_REG_FLASH0_PROCON1 (FLASH_REG_BASE | 0x2024) -#define FLASH_REG_FLASH0_PROCON2 (FLASH_REG_BASE | 0x2028) - -#define PROCON_S0L (0) -#define PROCON_S1L (1) -#define PROCON_S2L (2) -#define PROCON_S3L (3) -#define PROCON_S4L (4) -#define PROCON_S5L (5) -#define PROCON_S6L (6) -#define PROCON_S7L (7) -#define PROCON_S8L (8) -#define PROCON_S9L (9) -#define PROCON_S10_S11L (10) -#define PROCON_RPRO (15) - -#define PROCON_S0L_MASK (0x01 << PROCON_S0L) -#define PROCON_S1L_MASK (0x01 << PROCON_S1L) -#define PROCON_S2L_MASK (0x01 << PROCON_S2L) -#define PROCON_S3L_MASK (0x01 << PROCON_S3L) -#define PROCON_S4L_MASK (0x01 << PROCON_S4L) -#define PROCON_S5L_MASK (0x01 << PROCON_S5L) -#define PROCON_S6L_MASK (0x01 << PROCON_S6L) -#define PROCON_S7L_MASK (0x01 << PROCON_S7L) -#define PROCON_S8L_MASK (0x01 << PROCON_S8L) -#define PROCON_S9L_MASK (0x01 << PROCON_S9L) -#define PROCON_S10_S11L_MASK (0x01 << PROCON_S10_S11L) -#define PROCON_RPRO_MASK (0x01 << PROCON_RPRO) - -#define FLASH_PROTECT_CONFIRMATION_CODE 0x8AFE15C3 - -/* Flash controller configuration values */ -#define FLASH_ID_XMC4500 0xA2 -#define FLASH_ID_XMC4700_4800 0x92 -#define FLASH_ID_XMC4100_4200 0x9C -#define FLASH_ID_XMC4400 0x9F - -/* Timeouts */ -#define FLASH_OP_TIMEOUT 5000 - -/* Flash commands (write/erase/protect) are performed using special - * command sequences that are written to magic addresses in the flash controller */ -/* Command sequence addresses. See reference manual, section 8: Flash Command Sequences */ -#define FLASH_CMD_ERASE_1 0x0C005554 -#define FLASH_CMD_ERASE_2 0x0C00AAA8 -#define FLASH_CMD_ERASE_3 FLASH_CMD_ERASE_1 -#define FLASH_CMD_ERASE_4 FLASH_CMD_ERASE_1 -#define FLASH_CMD_ERASE_5 FLASH_CMD_ERASE_2 -/* ERASE_6 is the sector base address */ - -#define FLASH_CMD_CLEAR_STATUS FLASH_CMD_ERASE_1 - -#define FLASH_CMD_ENTER_PAGEMODE FLASH_CMD_ERASE_1 - -#define FLASH_CMD_LOAD_PAGE_1 0x0C0055F0 -#define FLASH_CMD_LOAD_PAGE_2 0x0C0055F4 - -#define FLASH_CMD_WRITE_PAGE_1 FLASH_CMD_ERASE_1 -#define FLASH_CMD_WRITE_PAGE_2 FLASH_CMD_ERASE_2 -#define FLASH_CMD_WRITE_PAGE_3 FLASH_CMD_ERASE_1 -/* WRITE_PAGE_4 is the page base address */ - -#define FLASH_CMD_TEMP_UNPROT_1 FLASH_CMD_ERASE_1 -#define FLASH_CMD_TEMP_UNPROT_2 FLASH_CMD_ERASE_2 -#define FLASH_CMD_TEMP_UNPROT_3 0x0C00553C -#define FLASH_CMD_TEMP_UNPROT_4 FLASH_CMD_ERASE_2 -#define FLASH_CMD_TEMP_UNPROT_5 FLASH_CMD_ERASE_2 -#define FLASH_CMD_TEMP_UNPROT_6 0x0C005558 - -struct xmc4xxx_flash_bank { - bool probed; - - /* We need the flash controller ID to choose the sector layout */ - uint32_t fcon_id; - - /* Passwords used for protection operations */ - uint32_t pw1; - uint32_t pw2; - bool pw_set; - - /* Protection flags */ - bool read_protected; - - bool write_prot_otp[MAX_XMC_SECTORS]; -}; - -struct xmc4xxx_command_seq { - uint32_t address; - uint32_t magic; -}; - -/* Sector capacities. See section 8 of xmc4x00_rm */ -static const unsigned int sector_capacity_8[8] = { - 16, 16, 16, 16, 16, 16, 16, 128 -}; - -static const unsigned int sector_capacity_9[9] = { - 16, 16, 16, 16, 16, 16, 16, 128, 256 -}; - -static const unsigned int sector_capacity_12[12] = { - 16, 16, 16, 16, 16, 16, 16, 16, 128, 256, 256, 256 -}; - -static const unsigned int sector_capacity_16[16] = { - 16, 16, 16, 16, 16, 16, 16, 16, 128, 256, 256, 256, 256, 256, 256, 256 -}; - -static int xmc4xxx_write_command_sequence(struct flash_bank *bank, - struct xmc4xxx_command_seq *seq, - int seq_len) -{ - int res = ERROR_OK; - - for (int i = 0; i < seq_len; i++) { - res = target_write_u32(bank->target, seq[i].address, - seq[i].magic); - if (res != ERROR_OK) - return res; - } - - return ERROR_OK; -} - -static int xmc4xxx_load_bank_layout(struct flash_bank *bank) -{ - const unsigned int *capacity = NULL; - - /* At this point, we know which flash controller ID we're - * talking to and simply need to fill out the bank structure accordingly */ - LOG_DEBUG("%d sectors", bank->num_sectors); - - switch (bank->num_sectors) { - case 8: - capacity = sector_capacity_8; - break; - case 9: - capacity = sector_capacity_9; - break; - case 12: - capacity = sector_capacity_12; - break; - case 16: - capacity = sector_capacity_16; - break; - default: - LOG_ERROR("Unexpected number of sectors, %d\n", - bank->num_sectors); - return ERROR_FAIL; - } - - /* This looks like a bank that we understand, now we know the - * corresponding sector capacities and we can add those up into the - * bank size. */ - uint32_t total_offset = 0; - bank->sectors = calloc(bank->num_sectors, - sizeof(struct flash_sector)); - for (int i = 0; i < bank->num_sectors; i++) { - bank->sectors[i].size = capacity[i] * 1024; - bank->sectors[i].offset = total_offset; - bank->sectors[i].is_erased = -1; - bank->sectors[i].is_protected = -1; - - bank->size += bank->sectors[i].size; - LOG_DEBUG("\t%d: %uk", i, capacity[i]); - total_offset += bank->sectors[i].size; - } - - /* This part doesn't follow the typical standard of 0xff - * being the default padding value.*/ - bank->default_padded_value = 0x00; - - return ERROR_OK; -} - -static int xmc4xxx_probe(struct flash_bank *bank) -{ - int res; - uint32_t devid, config; - struct xmc4xxx_flash_bank *fb = bank->driver_priv; - uint8_t flash_id; - - if (fb->probed) - return ERROR_OK; - - /* It's not possible for the DAP to access the OTP locations needed for - * probing the part info and Flash geometry so we require that the target - * be halted before proceeding. */ - if (bank->target->state != TARGET_HALTED) { - LOG_WARNING("Cannot communicate... target not halted."); - return ERROR_TARGET_NOT_HALTED; - } - - /* The SCU registers contain the ID of the chip */ - res = target_read_u32(bank->target, SCU_REG_BASE + SCU_ID_CHIP, &devid); - if (res != ERROR_OK) { - LOG_ERROR("Cannot read device identification register."); - return res; - } - - /* Make sure this is a XMC4000 family device */ - if ((devid & 0xF0000) != 0x40000 && devid != 0) { - LOG_ERROR("Platform ID doesn't match XMC4xxx: 0x%08" PRIx32, devid); - return ERROR_FAIL; - } - - LOG_DEBUG("Found XMC4xxx with devid: 0x%08" PRIx32, devid); - - /* Now sanity-check the Flash controller itself. */ - res = target_read_u32(bank->target, FLASH_REG_FLASH0_ID, - &config); - if (res != ERROR_OK) { - LOG_ERROR("Cannot read Flash bank configuration."); - return res; - } - flash_id = (config & 0xff0000) >> 16; - - /* The Flash configuration register is our only means of - * determining the sector layout. We need to make sure that - * we understand the type of controller we're dealing with */ - switch (flash_id) { - case FLASH_ID_XMC4100_4200: - bank->num_sectors = 8; - LOG_DEBUG("XMC4xxx: XMC4100/4200 detected."); - break; - case FLASH_ID_XMC4400: - bank->num_sectors = 9; - LOG_DEBUG("XMC4xxx: XMC4400 detected."); - break; - case FLASH_ID_XMC4500: - bank->num_sectors = 12; - LOG_DEBUG("XMC4xxx: XMC4500 detected."); - break; - case FLASH_ID_XMC4700_4800: - bank->num_sectors = 16; - LOG_DEBUG("XMC4xxx: XMC4700/4800 detected."); - break; - default: - LOG_ERROR("XMC4xxx: Unexpected flash ID. got %02" PRIx8, - flash_id); - return ERROR_FAIL; - } - - /* Retrieve information about the particular bank we're probing and fill in - * the bank structure accordingly. */ - res = xmc4xxx_load_bank_layout(bank); - if (res == ERROR_OK) { - /* We're done */ - fb->probed = true; - } else { - LOG_ERROR("Unable to load bank information."); - return ERROR_FAIL; - } - - return ERROR_OK; -} - -static int xmc4xxx_get_sector_start_addr(struct flash_bank *bank, - int sector, uint32_t *ret_addr) -{ - /* Make sure we understand this sector */ - if (sector > bank->num_sectors) - return ERROR_FAIL; - - *ret_addr = bank->base + bank->sectors[sector].offset; - - return ERROR_OK; - -} - -static int xmc4xxx_clear_flash_status(struct flash_bank *bank) -{ - int res; - /* TODO: Do we need to check for sequence error? */ - LOG_INFO("Clearing flash status"); - res = target_write_u32(bank->target, FLASH_CMD_CLEAR_STATUS, - 0xF5); - if (res != ERROR_OK) { - LOG_ERROR("Unable to write erase command sequence"); - return res; - } - - return ERROR_OK; -} - -static int xmc4xxx_get_flash_status(struct flash_bank *bank, uint32_t *status) -{ - int res; - - res = target_read_u32(bank->target, FLASH_REG_FLASH0_FSR, status); - - if (res != ERROR_OK) - LOG_ERROR("Cannot read flash status register."); - - return res; -} - -static int xmc4xxx_wait_status_busy(struct flash_bank *bank, int timeout) -{ - int res; - uint32_t status; - - res = xmc4xxx_get_flash_status(bank, &status); - if (res != ERROR_OK) - return res; - - /* While the flash controller is busy, wait */ - while (status & FSR_PBUSY_MASK) { - res = xmc4xxx_get_flash_status(bank, &status); - if (res != ERROR_OK) - return res; - - if (timeout-- <= 0) { - LOG_ERROR("Timed out waiting for flash"); - return ERROR_FAIL; - } - alive_sleep(1); - keep_alive(); - } - - if (status & FSR_PROER_MASK) { - LOG_ERROR("XMC4xxx flash protected"); - res = ERROR_FAIL; - } - - return res; -} - -static int xmc4xxx_erase_sector(struct flash_bank *bank, uint32_t address, - bool user_config) -{ - int res; - uint32_t status; - - /* See reference manual table 8.4: Command Sequences for Flash Control */ - struct xmc4xxx_command_seq erase_cmd_seq[6] = { - {FLASH_CMD_ERASE_1, 0xAA}, - {FLASH_CMD_ERASE_2, 0x55}, - {FLASH_CMD_ERASE_3, 0x80}, - {FLASH_CMD_ERASE_4, 0xAA}, - {FLASH_CMD_ERASE_5, 0x55}, - {0xFF, 0xFF} /* Needs filled in */ - }; - - /* We need to fill in the base address of the sector we'll be - * erasing, as well as the magic code that determines whether - * this is a standard flash sector or a user configuration block */ - - erase_cmd_seq[5].address = address; - if (user_config) { - /* Removing flash protection requires the addition of - * the base address */ - erase_cmd_seq[5].address += bank->base; - erase_cmd_seq[5].magic = 0xC0; - } else { - erase_cmd_seq[5].magic = 0x30; - } - - res = xmc4xxx_write_command_sequence(bank, erase_cmd_seq, - ARRAY_SIZE(erase_cmd_seq)); - if (res != ERROR_OK) - return res; - - /* Read the flash status register */ - res = target_read_u32(bank->target, FLASH_REG_FLASH0_FSR, &status); - if (res != ERROR_OK) { - LOG_ERROR("Cannot read flash status register."); - return res; - } - - /* Check for a sequence error */ - if (status & FSR_SQER_MASK) { - LOG_ERROR("Error with flash erase sequence"); - return ERROR_FAIL; - } - - /* Make sure a flash erase was triggered */ - if (!(status & FSR_ERASE_MASK)) { - LOG_ERROR("Flash failed to erase"); - return ERROR_FAIL; - } - - /* Now we must wait for the erase operation to end */ - res = xmc4xxx_wait_status_busy(bank, FLASH_OP_TIMEOUT); - - return res; -} - -static int xmc4xxx_erase(struct flash_bank *bank, int first, int last) -{ - struct xmc4xxx_flash_bank *fb = bank->driver_priv; - int res; - - if (bank->target->state != TARGET_HALTED) { - LOG_ERROR("Unable to erase, target is not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - if (!fb->probed) { - res = xmc4xxx_probe(bank); - if (res != ERROR_OK) - return res; - } - - uint32_t tmp_addr; - /* Loop through the sectors and erase each one */ - for (int i = first; i <= last; i++) { - res = xmc4xxx_get_sector_start_addr(bank, i, &tmp_addr); - if (res != ERROR_OK) { - LOG_ERROR("Invalid sector %d", i); - return res; - } - - LOG_DEBUG("Erasing sector %d @ 0x%08"PRIx32, i, tmp_addr); - - res = xmc4xxx_erase_sector(bank, tmp_addr, false); - if (res != ERROR_OK) { - LOG_ERROR("Unable to write erase command sequence"); - goto clear_status_and_exit; - } - - /* Now we must wait for the erase operation to end */ - res = xmc4xxx_wait_status_busy(bank, FLASH_OP_TIMEOUT); - - if (res != ERROR_OK) - goto clear_status_and_exit; - - bank->sectors[i].is_erased = 1; - } - -clear_status_and_exit: - res = xmc4xxx_clear_flash_status(bank); - return res; - -} - -static int xmc4xxx_enter_page_mode(struct flash_bank *bank) -{ - int res; - uint32_t status; - - res = target_write_u32(bank->target, FLASH_CMD_ENTER_PAGEMODE, 0x50); - if (res != ERROR_OK) { - LOG_ERROR("Unable to write enter page mode command"); - return ERROR_FAIL; - } - - res = xmc4xxx_get_flash_status(bank, &status); - - if (res != ERROR_OK) - return res; - - /* Make sure we're in page mode */ - if (!(status & FSR_PFPAGE_MASK)) { - LOG_ERROR("Unable to enter page mode"); - return ERROR_FAIL; - } - - /* Make sure we didn't encounter a sequence error */ - if (status & FSR_SQER_MASK) { - LOG_ERROR("Sequence error while entering page mode"); - return ERROR_FAIL; - } - - 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. */ -static 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; - - static const uint8_t erase_check_code[] = { -#include "../../../contrib/loaders/erase_check/armv7m_0_erase_check.inc" - }; - - /* 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) - goto cleanup; - - 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]); - -cleanup: - 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 = ERROR_OK; - 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 retval; -} - -static int xmc4xxx_write_page(struct flash_bank *bank, const uint8_t *pg_buf, - uint32_t offset, bool user_config) -{ - int res; - uint32_t status; - - /* Base of the flash write command */ - struct xmc4xxx_command_seq write_cmd_seq[4] = { - {FLASH_CMD_WRITE_PAGE_1, 0xAA}, - {FLASH_CMD_WRITE_PAGE_2, 0x55}, - {FLASH_CMD_WRITE_PAGE_3, 0xFF}, /* Needs filled in */ - {0xFF, 0xFF} /* Needs filled in */ - }; - - /* The command sequence differs depending on whether this is - * being written to standard flash or the user configuration - * area */ - if (user_config) - write_cmd_seq[2].magic = 0xC0; - else - write_cmd_seq[2].magic = 0xA0; - - /* Finally, we need to add the address that this page will be - * written to */ - write_cmd_seq[3].address = bank->base + offset; - write_cmd_seq[3].magic = 0xAA; - - - /* Flash pages are written 256 bytes at a time. For each 256 - * byte chunk, we need to: - * 1. Enter page mode. This activates the flash write buffer - * 2. Load the page buffer with data (2x 32 bit words at a time) - * 3. Burn the page buffer into its intended location - * If the starting offset is not on a 256 byte boundary, we - * will need to pad the beginning of the write buffer - * accordingly. Likewise, if the last page does not fill the - * buffer, we should pad it to avoid leftover data from being - * written to flash - */ - res = xmc4xxx_enter_page_mode(bank); - if (res != ERROR_OK) - return res; - - /* Copy the data into the page buffer*/ - for (int i = 0; i < 256; i += 8) { - uint32_t w_lo = target_buffer_get_u32(bank->target, &pg_buf[i]); - uint32_t w_hi = target_buffer_get_u32(bank->target, &pg_buf[i + 4]); - LOG_DEBUG("WLO: %08"PRIx32, w_lo); - LOG_DEBUG("WHI: %08"PRIx32, w_hi); - - /* Data is loaded 2x 32 bit words at a time */ - res = target_write_u32(bank->target, FLASH_CMD_LOAD_PAGE_1, w_lo); - if (res != ERROR_OK) - return res; - - res = target_write_u32(bank->target, FLASH_CMD_LOAD_PAGE_2, w_hi); - if (res != ERROR_OK) - return res; - - /* Check for an error */ - res = xmc4xxx_get_flash_status(bank, &status); - if (res != ERROR_OK) - return res; - - if (status & FSR_SQER_MASK) { - LOG_ERROR("Error loading page buffer"); - return ERROR_FAIL; - } - } - - /* The page buffer is now full, time to commit it to flash */ - - res = xmc4xxx_write_command_sequence(bank, write_cmd_seq, ARRAY_SIZE(write_cmd_seq)); - if (res != ERROR_OK) { - LOG_ERROR("Unable to enter write command sequence"); - return res; - } - - /* Read the flash status register */ - res = xmc4xxx_get_flash_status(bank, &status); - if (res != ERROR_OK) - return res; - - /* Check for a sequence error */ - if (status & FSR_SQER_MASK) { - LOG_ERROR("Error with flash write sequence"); - return ERROR_FAIL; - } - - /* Make sure a flash write was triggered */ - if (!(status & FSR_PROG_MASK)) { - LOG_ERROR("Failed to write flash page"); - return ERROR_FAIL; - } - - /* Wait for the write operation to end */ - res = xmc4xxx_wait_status_busy(bank, FLASH_OP_TIMEOUT); - if (res != ERROR_OK) - return res; - - /* TODO: Verify that page was written without error */ - return res; -} - -static int xmc4xxx_write(struct flash_bank *bank, const uint8_t *buffer, - uint32_t offset, uint32_t count) -{ - struct xmc4xxx_flash_bank *fb = bank->driver_priv; - int res = ERROR_OK; - - if (bank->target->state != TARGET_HALTED) { - LOG_ERROR("Unable to erase, target is not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - if (!fb->probed) { - res = xmc4xxx_probe(bank); - if (res != ERROR_OK) - return res; - } - - /* Make sure we won't run off the end of the flash bank */ - if ((offset + count) > (bank->size)) { - LOG_ERROR("Attempting to write past the end of flash"); - return ERROR_FAIL; - } - - - /* Attempt to write the passed in buffer to flash */ - /* Pages are written 256 bytes at a time, we need to handle - * scenarios where padding is required at the beginning and - * end of a page */ - while (count) { - /* page working area */ - uint8_t tmp_buf[256] = {0}; - - /* Amount of data we'll be writing to this page */ - int remaining; - int end_pad; - - remaining = MIN(count, sizeof(tmp_buf)); - end_pad = sizeof(tmp_buf) - remaining; - - /* Make sure we're starting on a page boundary */ - int start_pad = offset % 256; - if (start_pad) { - LOG_INFO("Write does not start on a 256 byte boundary. " - "Padding by %d bytes", start_pad); - memset(tmp_buf, 0xff, start_pad); - /* Subtract the amount of start offset from - * the amount of data we'll need to write */ - remaining -= start_pad; - } - - /* Remove the amount we'll be writing from the total count */ - count -= remaining; - - /* Now copy in the remaining data */ - memcpy(&tmp_buf[start_pad], buffer, remaining); - - if (end_pad) { - LOG_INFO("Padding end of page @%08"PRIx32" by %d bytes", - bank->base + offset, end_pad); - memset(&tmp_buf[256 - end_pad], 0xff, end_pad); - } - - /* Now commit this page to flash, if there was start - * padding, we should subtract that from the target offset */ - res = xmc4xxx_write_page(bank, tmp_buf, (offset - start_pad), false); - if (res != ERROR_OK) { - LOG_ERROR("Unable to write flash page"); - goto abort_write_and_exit; - } - - /* Advance the buffer pointer */ - buffer += remaining; - - /* Advance the offset */ - offset += remaining; - } - -abort_write_and_exit: - xmc4xxx_clear_flash_status(bank); - return res; - -} - -static int xmc4xxx_get_info_command(struct flash_bank *bank, char *buf, int buf_size) -{ - struct xmc4xxx_flash_bank *fb = bank->driver_priv; - uint32_t scu_idcode; - - if (bank->target->state != TARGET_HALTED) { - LOG_WARNING("Cannot communicate... target not halted."); - return ERROR_TARGET_NOT_HALTED; - } - - /* The SCU registers contain the ID of the chip */ - int res = target_read_u32(bank->target, SCU_REG_BASE + SCU_ID_CHIP, &scu_idcode); - if (res != ERROR_OK) { - LOG_ERROR("Cannot read device identification register."); - return res; - } - - uint16_t dev_id = (scu_idcode & 0xfff0) >> 4; - uint16_t rev_id = scu_idcode & 0xf; - const char *dev_str; - const char *rev_str = NULL; - - switch (dev_id) { - case 0x100: - dev_str = "XMC4100"; - - switch (rev_id) { - case 0x1: - rev_str = "AA"; - break; - case 0x2: - rev_str = "AB"; - break; - } - break; - case 0x200: - dev_str = "XMC4200"; - - switch (rev_id) { - case 0x1: - rev_str = "AA"; - break; - case 0x2: - rev_str = "AB"; - break; - } - break; - case 0x400: - dev_str = "XMC4400"; - - switch (rev_id) { - case 0x1: - rev_str = "AA"; - break; - case 0x2: - rev_str = "AB"; - break; - } - break; - case 0: - /* XMC4500 EES AA13 with date codes before GE212 - * had zero SCU_IDCHIP - */ - dev_str = "XMC4500 EES"; - rev_str = "AA13"; - break; - case 0x500: - dev_str = "XMC4500"; - - switch (rev_id) { - case 0x2: - rev_str = "AA"; - break; - case 0x3: - rev_str = "AB"; - break; - case 0x4: - rev_str = "AC"; - break; - } - break; - case 0x700: - dev_str = "XMC4700"; - - switch (rev_id) { - case 0x1: - rev_str = "EES-AA"; - break; - } - break; - case 0x800: - dev_str = "XMC4800"; - - switch (rev_id) { - case 0x1: - rev_str = "EES-AA"; - break; - } - break; - - default: - snprintf(buf, buf_size, - "Cannot identify target as an XMC4xxx. SCU_ID: %"PRIx32"\n", - scu_idcode); - return ERROR_OK; - } - - /* String to declare protection data held in the private driver */ - char prot_str[512] = {0}; - if (fb->read_protected) - snprintf(prot_str, sizeof(prot_str), "\nFlash is read protected"); - - bool otp_enabled = false; - for (int i = 0; i < bank->num_sectors; i++) - if (fb->write_prot_otp[i]) - otp_enabled = true; - - /* If OTP Write protection is enabled (User 2), list each - * sector that has it enabled */ - char otp_str[8]; - if (otp_enabled) { - strcat(prot_str, "\nOTP Protection is enabled for sectors:\n"); - for (int i = 0; i < bank->num_sectors; i++) { - if (fb->write_prot_otp[i]) { - snprintf(otp_str, sizeof(otp_str), "- %d\n", i); - strncat(prot_str, otp_str, ARRAY_SIZE(otp_str)); - } - } - } - - if (rev_str != NULL) - snprintf(buf, buf_size, "%s - Rev: %s%s", - dev_str, rev_str, prot_str); - else - snprintf(buf, buf_size, "%s - Rev: unknown (0x%01x)%s", - dev_str, rev_id, prot_str); - - return ERROR_OK; -} - -static int xmc4xxx_temp_unprotect(struct flash_bank *bank, int user_level) -{ - struct xmc4xxx_flash_bank *fb; - int res = ERROR_OK; - uint32_t status = 0; - - struct xmc4xxx_command_seq temp_unprot_seq[6] = { - {FLASH_CMD_TEMP_UNPROT_1, 0xAA}, - {FLASH_CMD_TEMP_UNPROT_2, 0x55}, - {FLASH_CMD_TEMP_UNPROT_3, 0xFF}, /* Needs filled in */ - {FLASH_CMD_TEMP_UNPROT_4, 0xFF}, /* Needs filled in */ - {FLASH_CMD_TEMP_UNPROT_5, 0xFF}, /* Needs filled in */ - {FLASH_CMD_TEMP_UNPROT_6, 0x05} - }; - - if (user_level < 0 || user_level > 2) { - LOG_ERROR("Invalid user level, must be 0-2"); - return ERROR_FAIL; - } - - fb = bank->driver_priv; - - /* Fill in the user level and passwords */ - temp_unprot_seq[2].magic = user_level; - temp_unprot_seq[3].magic = fb->pw1; - temp_unprot_seq[4].magic = fb->pw2; - - res = xmc4xxx_write_command_sequence(bank, temp_unprot_seq, - ARRAY_SIZE(temp_unprot_seq)); - if (res != ERROR_OK) { - LOG_ERROR("Unable to write temp unprotect sequence"); - return res; - } - - res = xmc4xxx_get_flash_status(bank, &status); - if (res != ERROR_OK) - return res; - - if (status & FSR_WPRODIS0) { - LOG_INFO("Flash is temporarily unprotected"); - } else { - LOG_INFO("Unable to disable flash protection"); - res = ERROR_FAIL; - } - - - return res; -} - -static int xmc4xxx_flash_unprotect(struct flash_bank *bank, int32_t level) -{ - uint32_t addr; - int res; - - switch (level) { - case 0: - addr = UCB0_BASE; - break; - 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); - - if (res != ERROR_OK) - LOG_ERROR("Error erasing user configuration block"); - - return res; -} - -/* Reference: "XMC4500 Flash Protection.pptx" app note */ -static int xmc4xxx_flash_protect(struct flash_bank *bank, int level, bool read_protect, - int first, int last) -{ - /* User configuration block buffers */ - uint8_t ucp0_buf[8 * sizeof(uint32_t)] = {0}; - uint32_t ucb_base = 0; - uint32_t procon = 0; - int res = ERROR_OK; - uint32_t status = 0; - bool proin = false; - - struct xmc4xxx_flash_bank *fb = bank->driver_priv; - - /* Read protect only works for user 0, make sure we don't try - * to do something silly */ - if (level != 0 && read_protect) { - LOG_ERROR("Read protection is for user level 0 only!"); - return ERROR_FAIL; - } - - /* Check to see if protection is already installed for the - * specified user level. If it is, the user configuration - * block will need to be erased before we can continue */ - - /* Grab the flash status register*/ - res = xmc4xxx_get_flash_status(bank, &status); - if (res != ERROR_OK) - return res; - - switch (level) { - case 0: - if ((status & FSR_RPROIN_MASK) || (status & FSR_WPROIN0_MASK)) - proin = true; - break; - case 1: - if (status & FSR_WPROIN1_MASK) - proin = true; - break; - case 2: - if (status & FSR_WPROIN2_MASK) - proin = true; - break; - } - - if (proin) { - LOG_ERROR("Flash protection is installed for user %d" - " and must be removed before continuing", level); - return ERROR_FAIL; - } - - /* If this device has 12 flash sectors, protection for - * sectors 10 & 11 are handled jointly. If we are trying to - * write all sectors, we should decrement - * last to ensure we don't write to a register bit that - * doesn't exist*/ - if ((bank->num_sectors == 12) && (last == 12)) - last--; - - /* We need to fill out the procon register representation - * that we will be writing to the device */ - for (int i = first; i <= last; i++) - procon |= 1 << i; - - /* If read protection is requested, set the appropriate bit - * (we checked that this is allowed above) */ - if (read_protect) - procon |= PROCON_RPRO_MASK; - - LOG_DEBUG("Setting flash protection with procon:"); - LOG_DEBUG("PROCON: %"PRIx32, procon); - - /* First we need to copy in the procon register to the buffer - * we're going to attempt to write. This is written twice */ - target_buffer_set_u32(bank->target, &ucp0_buf[0 * 4], procon); - target_buffer_set_u32(bank->target, &ucp0_buf[2 * 4], procon); - - /* Now we must copy in both flash passwords. As with the - * procon data, this must be written twice (4 total words - * worth of data) */ - target_buffer_set_u32(bank->target, &ucp0_buf[4 * 4], fb->pw1); - target_buffer_set_u32(bank->target, &ucp0_buf[5 * 4], fb->pw2); - target_buffer_set_u32(bank->target, &ucp0_buf[6 * 4], fb->pw1); - target_buffer_set_u32(bank->target, &ucp0_buf[7 * 4], fb->pw2); - - /* Finally, (if requested) we copy in the confirmation - * code so that the protection is permanent and will - * require a password to undo. */ - target_buffer_set_u32(bank->target, &ucp0_buf[0 * 4], FLASH_PROTECT_CONFIRMATION_CODE); - target_buffer_set_u32(bank->target, &ucp0_buf[2 * 4], FLASH_PROTECT_CONFIRMATION_CODE); - - /* Now that the data is copied into place, we must write - * these pages into flash */ - - /* The user configuration block base depends on what level of - * protection we're trying to install, select the proper one */ - switch (level) { - case 0: - ucb_base = UCB0_BASE; - break; - case 1: - ucb_base = UCB1_BASE; - break; - case 2: - ucb_base = UCB2_BASE; - break; - } - - /* Write the user config pages */ - res = xmc4xxx_write_page(bank, ucp0_buf, ucb_base, true); - if (res != ERROR_OK) { - LOG_ERROR("Error writing user configuration block 0"); - return res; - } - - return ERROR_OK; -} - -static int xmc4xxx_protect(struct flash_bank *bank, int set, int first, int last) -{ - int ret; - struct xmc4xxx_flash_bank *fb = bank->driver_priv; - - /* Check for flash passwords */ - if (!fb->pw_set) { - LOG_ERROR("Flash passwords not set, use xmc4xxx flash_password to set them"); - return ERROR_FAIL; - } - - /* We want to clear flash protection temporarily*/ - if (set == 0) { - LOG_WARNING("Flash protection will be temporarily disabled" - " for all pages (User 0 only)!"); - ret = xmc4xxx_temp_unprotect(bank, 0); - return ret; - } - - /* Install write protection for user 0 on the specified pages */ - ret = xmc4xxx_flash_protect(bank, 0, false, first, last); - - return ret; -} - -static int xmc4xxx_protect_check(struct flash_bank *bank) -{ - int ret; - uint32_t protection[3] = {0}; - struct xmc4xxx_flash_bank *fb = bank->driver_priv; - - ret = target_read_u32(bank->target, FLASH_REG_FLASH0_PROCON0, &protection[0]); - if (ret != ERROR_OK) { - LOG_ERROR("Unable to read flash User0 protection register"); - return ret; - } - - ret = target_read_u32(bank->target, FLASH_REG_FLASH0_PROCON1, &protection[1]); - if (ret != ERROR_OK) { - LOG_ERROR("Unable to read flash User1 protection register"); - return ret; - } - - ret = target_read_u32(bank->target, FLASH_REG_FLASH0_PROCON2, &protection[2]); - if (ret != ERROR_OK) { - LOG_ERROR("Unable to read flash User2 protection register"); - return ret; - } - - int sectors = bank->num_sectors; - - /* On devices with 12 sectors, sectors 10 & 11 are ptected - * together instead of individually */ - if (sectors == 12) - sectors--; - - /* Clear the protection status */ - for (int i = 0; i < bank->num_sectors; i++) { - bank->sectors[i].is_protected = 0; - fb->write_prot_otp[i] = false; - } - fb->read_protected = false; - - /* The xmc4xxx series supports 3 levels of user protection - * (User0, User1 (low priority), and User 2(OTP), we need to - * check all 3 */ - for (unsigned int i = 0; i < ARRAY_SIZE(protection); i++) { - - /* Check for write protection on every available - * sector */ - for (int j = 0; j < sectors; j++) { - int set = (protection[i] & (1 << j)) ? 1 : 0; - bank->sectors[j].is_protected |= set; - - /* Handle sector 11 */ - if (j == 10) - bank->sectors[j + 1].is_protected |= set; - - /* User 2 indicates this protection is - * permanent, make note in the private driver structure */ - if (i == 2 && set) { - fb->write_prot_otp[j] = true; - - /* Handle sector 11 */ - if (j == 10) - fb->write_prot_otp[j + 1] = true; - } - - } - } - - /* XMC4xxx also supports read proptection, make a note - * in the private driver structure */ - if (protection[0] & PROCON_RPRO_MASK) - fb->read_protected = true; - - return ERROR_OK; -} - -FLASH_BANK_COMMAND_HANDLER(xmc4xxx_flash_bank_command) -{ - bank->driver_priv = malloc(sizeof(struct xmc4xxx_flash_bank)); - - if (!bank->driver_priv) - return ERROR_FLASH_OPERATION_FAILED; - - (void)memset(bank->driver_priv, 0, sizeof(struct xmc4xxx_flash_bank)); - - return ERROR_OK; -} - -COMMAND_HANDLER(xmc4xxx_handle_flash_password_command) -{ - int res; - struct flash_bank *bank; - - if (CMD_ARGC < 3) - return ERROR_COMMAND_SYNTAX_ERROR; - - res = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank); - if (res != ERROR_OK) - return res; - - struct xmc4xxx_flash_bank *fb = bank->driver_priv; - - errno = 0; - - /* We skip over the flash bank */ - fb->pw1 = strtol(CMD_ARGV[1], NULL, 16); - - if (errno) - return ERROR_COMMAND_SYNTAX_ERROR; - - fb->pw2 = strtol(CMD_ARGV[2], NULL, 16); - - if (errno) - return ERROR_COMMAND_SYNTAX_ERROR; - - fb->pw_set = true; - - command_print(CMD_CTX, "XMC4xxx flash passwords set to:\n"); - command_print(CMD_CTX, "-0x%08"PRIx32"\n", fb->pw1); - command_print(CMD_CTX, "-0x%08"PRIx32"\n", fb->pw2); - return ERROR_OK; -} - -COMMAND_HANDLER(xmc4xxx_handle_flash_unprotect_command) -{ - struct flash_bank *bank; - int res; - int32_t level; - - if (CMD_ARGC < 2) - return ERROR_COMMAND_SYNTAX_ERROR; - - res = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank); - if (res != ERROR_OK) - return res; - - COMMAND_PARSE_NUMBER(s32, CMD_ARGV[1], level); - - res = xmc4xxx_flash_unprotect(bank, level); - - return res; -} - -static const struct command_registration xmc4xxx_exec_command_handlers[] = { - { - .name = "flash_password", - .handler = xmc4xxx_handle_flash_password_command, - .mode = COMMAND_EXEC, - .usage = "bank_id password1 password2", - .help = "Set the flash passwords used for protect operations. " - "Passwords should be in standard hex form (0x00000000). " - "(You must call this before any other protect commands) " - "NOTE: The xmc4xxx's UCB area only allows for FOUR cycles. " - "Please use protection carefully!", - }, - { - .name = "flash_unprotect", - .handler = xmc4xxx_handle_flash_unprotect_command, - .mode = COMMAND_EXEC, - .usage = "bank_id user_level[0-1]", - .help = "Permanently Removes flash protection (read and write) " - "for the specified user level", - }, COMMAND_REGISTRATION_DONE -}; - -static const struct command_registration xmc4xxx_command_handlers[] = { - { - .name = "xmc4xxx", - .mode = COMMAND_ANY, - .help = "xmc4xxx flash command group", - .usage = "", - .chain = xmc4xxx_exec_command_handlers, - }, - COMMAND_REGISTRATION_DONE -}; - -struct flash_driver xmc4xxx_flash = { - .name = "xmc4xxx", - .commands = xmc4xxx_command_handlers, - .flash_bank_command = xmc4xxx_flash_bank_command, - .erase = xmc4xxx_erase, - .write = xmc4xxx_write, - .read = default_flash_read, - .probe = xmc4xxx_probe, - .auto_probe = xmc4xxx_probe, - .erase_check = xmc4xxx_flash_blank_check, - .info = xmc4xxx_get_info_command, - .protect_check = xmc4xxx_protect_check, - .protect = xmc4xxx_protect, -}; diff --git a/src/flash/startup.tcl b/src/flash/startup.tcl deleted file mode 100644 index fbb8d8ee4..000000000 --- a/src/flash/startup.tcl +++ /dev/null @@ -1,110 +0,0 @@ -# Defines basic Tcl procs for OpenOCD flash module - -# -# program utility proc -# usage: program filename -# optional args: verify, reset, exit and address -# - -proc program_error {description exit} { - if {$exit == 1} { - echo $description - shutdown error - } - - error $description -} - -proc program {filename args} { - set exit 0 - - foreach arg $args { - if {[string equal $arg "verify"]} { - set verify 1 - } elseif {[string equal $arg "reset"]} { - set reset 1 - } elseif {[string equal $arg "exit"]} { - set exit 1 - } else { - set address $arg - } - } - - # make sure init is called - if {[catch {init}] != 0} { - program_error "** OpenOCD init failed **" 1 - } - - # reset target and call any init scripts - if {[catch {reset init}] != 0} { - program_error "** Unable to reset target **" $exit - } - - # start programming phase - echo "** Programming Started **" - if {[info exists address]} { - set flash_args "$filename $address" - } else { - set flash_args "$filename" - } - - if {[catch {eval flash write_image erase $flash_args}] == 0} { - echo "** Programming Finished **" - if {[info exists verify]} { - # verify phase - echo "** Verify Started **" - if {[catch {eval verify_image $flash_args}] == 0} { - echo "** Verified OK **" - } else { - program_error "** Verify Failed **" $exit - } - } - - if {[info exists reset]} { - # reset target if requested - # also disable target polling, we are shutting down anyway - poll off - echo "** Resetting Target **" - reset run - } - } else { - program_error "** Programming Failed **" $exit - } - - if {$exit == 1} { - shutdown - } - return -} - -add_help_text program "write an image to flash, address is only required for binary images. verify, reset, exit are optional" -add_usage_text program " \[address\] \[verify\] \[reset\] \[exit\]" - -# stm32f0x uses the same flash driver as the stm32f1x -# this alias enables the use of either name. -proc stm32f0x args { - eval stm32f1x $args -} - -# stm32f3x uses the same flash driver as the stm32f1x -# this alias enables the use of either name. -proc stm32f3x args { - eval stm32f1x $args -} - -# stm32f4x uses the same flash driver as the stm32f2x -# this alias enables the use of either name. -proc stm32f4x args { - eval stm32f2x $args -} - -# ease migration to updated flash driver -proc stm32x args { - echo "DEPRECATED! use 'stm32f1x $args' not 'stm32x $args'" - eval stm32f1x $args -} - -proc stm32f2xxx args { - echo "DEPRECATED! use 'stm32f2x $args' not 'stm32f2xxx $args'" - eval stm32f2x $args -} diff --git a/src/hello.c b/src/hello.c deleted file mode 100644 index 25938bcf8..000000000 --- a/src/hello.c +++ /dev/null @@ -1,112 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2009 Zachary T Welch * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 -#include -#endif -#include - -COMMAND_HANDLER(handle_foo_command) -{ - if (CMD_ARGC < 1 || CMD_ARGC > 2) - return ERROR_COMMAND_SYNTAX_ERROR; - - uint32_t address; - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], address); - - const char *msg = ""; - if (CMD_ARGC == 2) { - bool enable; - COMMAND_PARSE_ENABLE(CMD_ARGV[1], enable); - msg = enable ? "enable" : "disable"; - } - - LOG_INFO("%s: address=0x%8.8" PRIx32 " enabled=%s", CMD_NAME, address, msg); - return ERROR_OK; -} - -static bool foo_flag; - -COMMAND_HANDLER(handle_flag_command) -{ - return CALL_COMMAND_HANDLER(handle_command_parse_bool, - &foo_flag, "foo flag"); -} - -static const struct command_registration foo_command_handlers[] = { - { - .name = "bar", - .handler = &handle_foo_command, - .mode = COMMAND_ANY, - .usage = "address ['enable'|'disable']", - .help = "an example command", - }, - { - .name = "baz", - .handler = &handle_foo_command, - .mode = COMMAND_ANY, - .usage = "address ['enable'|'disable']", - .help = "a sample command", - }, - { - .name = "flag", - .handler = &handle_flag_command, - .mode = COMMAND_ANY, - .usage = "[on|off]", - .help = "set a flag", - }, - COMMAND_REGISTRATION_DONE -}; - -static COMMAND_HELPER(handle_hello_args, const char **sep, const char **name) -{ - if (CMD_ARGC > 1) - return ERROR_COMMAND_SYNTAX_ERROR; - if (1 == CMD_ARGC) { - *sep = " "; - *name = CMD_ARGV[0]; - } else - *sep = *name = ""; - - return ERROR_OK; -} -COMMAND_HANDLER(handle_hello_command) -{ - const char *sep, *name; - int retval = CALL_COMMAND_HANDLER(handle_hello_args, &sep, &name); - if (ERROR_OK == retval) - command_print(CMD_CTX, "Greetings%s%s!", sep, name); - return retval; -} - -const struct command_registration hello_command_handlers[] = { - { - .name = "hello", - .handler = handle_hello_command, - .mode = COMMAND_ANY, - .help = "prints a warm welcome", - .usage = "[name]", - }, - { - .name = "foo", - .mode = COMMAND_ANY, - .help = "example command handler skeleton", - - .chain = foo_command_handlers, - }, - COMMAND_REGISTRATION_DONE -}; diff --git a/src/hello.h b/src/hello.h deleted file mode 100644 index c88c89ddf..000000000 --- a/src/hello.h +++ /dev/null @@ -1,29 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2009 Zachary T Welch * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 OPENOCD_HELLO_H -#define OPENOCD_HELLO_H - -struct command_registration; - -/** - * Export the registration for the hello command group, so it can be - * embedded in example drivers. - */ -extern const struct command_registration hello_command_handlers[]; - -#endif /* OPENOCD_HELLO_H */ diff --git a/src/helper/Makefile.am b/src/helper/Makefile.am deleted file mode 100644 index 64caf98b7..000000000 --- a/src/helper/Makefile.am +++ /dev/null @@ -1,56 +0,0 @@ -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 \ - jep106.c \ - jim-nvp.c - -if IOUTIL -libhelper_la_SOURCES += ioutil.c -else -libhelper_la_SOURCES += ioutil_stubs.c -endif - -libhelper_la_CFLAGS = -if IS_MINGW -# FD_* macros are sloppy with their signs on MinGW32 platform -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 \ - jep106.h \ - jep106.inc \ - update_jep106.pl \ - jim-nvp.h - -EXTRA_DIST = startup.tcl - -MAINTAINERCLEANFILES = $(srcdir)/Makefile.in diff --git a/src/helper/bin2char.sh b/src/helper/bin2char.sh deleted file mode 100755 index 85a0fd6a8..000000000 --- a/src/helper/bin2char.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -[ $# != 0 ] && { - echo "Usage: $0" - echo - echo "Read binary data from standard input and write it as a comma separated" - echo "list of hexadecimal byte values to standard ouput. The output is usable" - echo "as a C array initializer. It is terminated with a comma so it can be" - echo "continued e.g. for zero termination." - exit 1 -} - -echo "/* Autogenerated with $0 */" -od -v -A n -t x1 | sed 's/ *\(..\) */0x\1,/g' diff --git a/src/helper/binarybuffer.c b/src/helper/binarybuffer.c deleted file mode 100644 index c1e632265..000000000 --- a/src/helper/binarybuffer.c +++ /dev/null @@ -1,418 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2004, 2005 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * Copyright (C) 2007,2008 Øyvind Harboe * - * oyvind.harboe@zylin.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "log.h" -#include "binarybuffer.h" - -static const unsigned char bit_reverse_table256[] = { - 0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0, 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0, - 0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8, 0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8, - 0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4, 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4, - 0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC, 0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC, - 0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2, 0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2, - 0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA, 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA, - 0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6, 0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6, - 0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE, 0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE, - 0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1, 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1, - 0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9, 0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9, - 0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5, 0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5, - 0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED, 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD, - 0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3, 0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3, - 0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB, 0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB, - 0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7, 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7, - 0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF, 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF -}; - -void *buf_cpy(const void *from, void *_to, unsigned size) -{ - if (NULL == from || NULL == _to) - return NULL; - - /* copy entire buffer */ - memcpy(_to, from, DIV_ROUND_UP(size, 8)); - - /* mask out bits that don't belong to the buffer */ - unsigned trailing_bits = size % 8; - if (trailing_bits) { - uint8_t *to = _to; - to[size / 8] &= (1 << trailing_bits) - 1; - } - return _to; -} - -static bool buf_cmp_masked(uint8_t a, uint8_t b, uint8_t m) -{ - return (a & m) != (b & m); -} -static bool buf_cmp_trailing(uint8_t a, uint8_t b, uint8_t m, unsigned trailing) -{ - uint8_t mask = (1 << trailing) - 1; - return buf_cmp_masked(a, b, mask & m); -} - -bool buf_cmp(const void *_buf1, const void *_buf2, unsigned size) -{ - if (!_buf1 || !_buf2) - return _buf1 != _buf2; - - unsigned last = size / 8; - if (memcmp(_buf1, _buf2, last) != 0) - return false; - - unsigned trailing = size % 8; - if (!trailing) - return false; - - const uint8_t *buf1 = _buf1, *buf2 = _buf2; - return buf_cmp_trailing(buf1[last], buf2[last], 0xff, trailing); -} - -bool buf_cmp_mask(const void *_buf1, const void *_buf2, - const void *_mask, unsigned size) -{ - if (!_buf1 || !_buf2) - return _buf1 != _buf2 || _buf1 != _mask; - - const uint8_t *buf1 = _buf1, *buf2 = _buf2, *mask = _mask; - unsigned last = size / 8; - for (unsigned i = 0; i < last; i++) { - if (buf_cmp_masked(buf1[i], buf2[i], mask[i])) - return true; - } - unsigned trailing = size % 8; - if (!trailing) - return false; - return buf_cmp_trailing(buf1[last], buf2[last], mask[last], trailing); -} - - -void *buf_set_ones(void *_buf, unsigned size) -{ - uint8_t *buf = _buf; - if (!buf) - return NULL; - - memset(buf, 0xff, size / 8); - - unsigned trailing_bits = size % 8; - if (trailing_bits) - buf[size / 8] = (1 << trailing_bits) - 1; - - return buf; -} - -void *buf_set_buf(const void *_src, unsigned src_start, - void *_dst, unsigned dst_start, unsigned len) -{ - const uint8_t *src = _src; - uint8_t *dst = _dst; - unsigned i, sb, db, sq, dq, lb, lq; - - sb = src_start / 8; - db = dst_start / 8; - sq = src_start % 8; - dq = dst_start % 8; - lb = len / 8; - lq = len % 8; - - src += sb; - dst += db; - - /* check if both buffers are on byte boundary and - * len is a multiple of 8bit so we can simple copy - * the buffer */ - if ((sq == 0) && (dq == 0) && (lq == 0)) { - for (i = 0; i < lb; i++) - *dst++ = *src++; - return _dst; - } - - /* fallback to slow bit copy */ - for (i = 0; i < len; i++) { - if (((*src >> (sq&7)) & 1) == 1) - *dst |= 1 << (dq&7); - else - *dst &= ~(1 << (dq&7)); - if (sq++ == 7) { - sq = 0; - src++; - } - if (dq++ == 7) { - dq = 0; - dst++; - } - } - - return _dst; -} - -uint32_t flip_u32(uint32_t value, unsigned int num) -{ - uint32_t c = (bit_reverse_table256[value & 0xff] << 24) | - (bit_reverse_table256[(value >> 8) & 0xff] << 16) | - (bit_reverse_table256[(value >> 16) & 0xff] << 8) | - (bit_reverse_table256[(value >> 24) & 0xff]); - - if (num < 32) - c = c >> (32 - num); - - return c; -} - -static int ceil_f_to_u32(float x) -{ - if (x < 0) /* return zero for negative numbers */ - return 0; - - uint32_t y = x; /* cut off fraction */ - - if ((x - y) > 0.0) /* if there was a fractional part, increase by one */ - y++; - - return y; -} - -char *buf_to_str(const void *_buf, unsigned buf_len, unsigned radix) -{ - float factor; - switch (radix) { - case 16: - factor = 2.0; /* log(256) / log(16) = 2.0 */ - break; - case 10: - factor = 2.40824; /* log(256) / log(10) = 2.40824 */ - break; - case 8: - factor = 2.66667; /* log(256) / log(8) = 2.66667 */ - break; - default: - return NULL; - } - - unsigned str_len = ceil_f_to_u32(DIV_ROUND_UP(buf_len, 8) * factor); - char *str = calloc(str_len + 1, 1); - - const uint8_t *buf = _buf; - int b256_len = DIV_ROUND_UP(buf_len, 8); - for (int i = b256_len - 1; i >= 0; i--) { - uint32_t tmp = buf[i]; - if (((unsigned)i == (buf_len / 8)) && (buf_len % 8)) - tmp &= (0xff >> (8 - (buf_len % 8))); - - /* base-256 digits */ - for (unsigned j = str_len; j > 0; j--) { - tmp += (uint32_t)str[j-1] * 256; - str[j-1] = (uint8_t)(tmp % radix); - tmp /= radix; - } - } - - const char * const DIGITS = "0123456789ABCDEF"; - for (unsigned j = 0; j < str_len; j++) - str[j] = DIGITS[(int)str[j]]; - - return str; -} - -/** identify radix, and skip radix-prefix (0, 0x or 0X) */ -static void str_radix_guess(const char **_str, unsigned *_str_len, - unsigned *_radix) -{ - unsigned radix = *_radix; - if (0 != radix) - return; - const char *str = *_str; - unsigned str_len = *_str_len; - if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X')) { - radix = 16; - str += 2; - str_len -= 2; - } else if ((str[0] == '0') && (str_len != 1)) { - radix = 8; - str += 1; - str_len -= 1; - } else - radix = 10; - *_str = str; - *_str_len = str_len; - *_radix = radix; -} - -int str_to_buf(const char *str, unsigned str_len, - void *_buf, unsigned buf_len, unsigned radix) -{ - str_radix_guess(&str, &str_len, &radix); - - float factor; - if (radix == 16) - factor = 0.5; /* log(16) / log(256) = 0.5 */ - else if (radix == 10) - factor = 0.41524; /* log(10) / log(256) = 0.41524 */ - else if (radix == 8) - factor = 0.375; /* log(8) / log(256) = 0.375 */ - else - return 0; - - /* copy to zero-terminated buffer */ - char *charbuf = strndup(str, str_len); - - /* number of digits in base-256 notation */ - unsigned b256_len = ceil_f_to_u32(str_len * factor); - uint8_t *b256_buf = calloc(b256_len, 1); - - /* go through zero terminated buffer - * input digits (ASCII) */ - unsigned i; - for (i = 0; charbuf[i]; i++) { - uint32_t tmp = charbuf[i]; - if ((tmp >= '0') && (tmp <= '9')) - tmp = (tmp - '0'); - else if ((tmp >= 'a') && (tmp <= 'f')) - tmp = (tmp - 'a' + 10); - else if ((tmp >= 'A') && (tmp <= 'F')) - tmp = (tmp - 'A' + 10); - else - continue; /* skip characters other than [0-9,a-f,A-F] */ - - if (tmp >= radix) - continue; /* skip digits invalid for the current radix */ - - /* base-256 digits */ - for (unsigned j = 0; j < b256_len; j++) { - tmp += (uint32_t)b256_buf[j] * radix; - b256_buf[j] = (uint8_t)(tmp & 0xFF); - tmp >>= 8; - } - - } - - uint8_t *buf = _buf; - for (unsigned j = 0; j < DIV_ROUND_UP(buf_len, 8); j++) { - if (j < b256_len) - buf[j] = b256_buf[j]; - else - buf[j] = 0; - } - - /* mask out bits that don't belong to the buffer */ - if (buf_len % 8) - buf[(buf_len / 8)] &= 0xff >> (8 - (buf_len % 8)); - - free(b256_buf); - free(charbuf); - - return i; -} - -void bit_copy_queue_init(struct bit_copy_queue *q) -{ - INIT_LIST_HEAD(&q->list); -} - -int bit_copy_queued(struct bit_copy_queue *q, uint8_t *dst, unsigned dst_offset, const uint8_t *src, - unsigned src_offset, unsigned bit_count) -{ - struct bit_copy_queue_entry *qe = malloc(sizeof(*qe)); - if (!qe) - return ERROR_FAIL; - - qe->dst = dst; - qe->dst_offset = dst_offset; - qe->src = src; - qe->src_offset = src_offset; - qe->bit_count = bit_count; - list_add_tail(&qe->list, &q->list); - - return ERROR_OK; -} - -void bit_copy_execute(struct bit_copy_queue *q) -{ - struct bit_copy_queue_entry *qe; - struct bit_copy_queue_entry *tmp; - list_for_each_entry_safe(qe, tmp, &q->list, list) { - bit_copy(qe->dst, qe->dst_offset, qe->src, qe->src_offset, qe->bit_count); - list_del(&qe->list); - free(qe); - } -} - -void bit_copy_discard(struct bit_copy_queue *q) -{ - struct bit_copy_queue_entry *qe; - struct bit_copy_queue_entry *tmp; - list_for_each_entry_safe(qe, tmp, &q->list, list) { - list_del(&qe->list); - free(qe); - } -} - -int unhexify(char *bin, const char *hex, int count) -{ - int i, tmp; - - for (i = 0; i < count; i++) { - if (sscanf(hex + (2 * i), "%02x", &tmp) != 1) - return i; - bin[i] = tmp; - } - - return i; -} - -int hexify(char *hex, const char *bin, int count, int out_maxlen) -{ - int i, cmd_len = 0; - - /* May use a length, or a null-terminated string as input. */ - if (count == 0) - count = strlen(bin); - - for (i = 0; i < count; i++) - cmd_len += snprintf(hex + cmd_len, out_maxlen - cmd_len, "%02x", bin[i] & 0xff); - - return cmd_len; -} - -void buffer_shr(void *_buf, unsigned buf_len, unsigned count) -{ - unsigned i; - unsigned char *buf = _buf; - unsigned bytes_to_remove; - unsigned shift; - - bytes_to_remove = count / 8; - shift = count - (bytes_to_remove * 8); - - for (i = 0; i < (buf_len - 1); i++) - buf[i] = (buf[i] >> shift) | ((buf[i+1] << (8 - shift)) & 0xff); - - buf[(buf_len - 1)] = buf[(buf_len - 1)] >> shift; - - if (bytes_to_remove) { - memmove(buf, &buf[bytes_to_remove], buf_len - bytes_to_remove); - memset(&buf[buf_len - bytes_to_remove], 0, bytes_to_remove); - } -} diff --git a/src/helper/binarybuffer.h b/src/helper/binarybuffer.h deleted file mode 100644 index dd0d275ab..000000000 --- a/src/helper/binarybuffer.h +++ /dev/null @@ -1,241 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2004, 2005 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * Copyright (C) 2007,2008 Øyvind Harboe * - * oyvind.harboe@zylin.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifndef OPENOCD_HELPER_BINARYBUFFER_H -#define OPENOCD_HELPER_BINARYBUFFER_H - -#include "list.h" - -/** @file - * Support functions to access arbitrary bits in a byte array - */ - -/** - * Sets @c num bits in @c _buffer, starting at the @c first bit, - * using the bits in @c value. This routine fast-paths writes - * of little-endian, byte-aligned, 32-bit words. - * @param _buffer The buffer whose bits will be set. - * @param first The bit offset in @c _buffer to start writing (0-31). - * @param num The number of bits from @c value to copy (1-32). - * @param value Up to 32 bits that will be copied to _buffer. - */ -static inline void buf_set_u32(uint8_t *_buffer, - unsigned first, unsigned num, uint32_t value) -{ - uint8_t *buffer = _buffer; - - if ((num == 32) && (first == 0)) { - buffer[3] = (value >> 24) & 0xff; - buffer[2] = (value >> 16) & 0xff; - buffer[1] = (value >> 8) & 0xff; - buffer[0] = (value >> 0) & 0xff; - } else { - for (unsigned i = first; i < first + num; i++) { - if (((value >> (i - first)) & 1) == 1) - buffer[i / 8] |= 1 << (i % 8); - else - buffer[i / 8] &= ~(1 << (i % 8)); - } - } -} - -/** - * Sets @c num bits in @c _buffer, starting at the @c first bit, - * using the bits in @c value. This routine fast-paths writes - * of little-endian, byte-aligned, 64-bit words. - * @param _buffer The buffer whose bits will be set. - * @param first The bit offset in @c _buffer to start writing (0-63). - * @param num The number of bits from @c value to copy (1-64). - * @param value Up to 64 bits that will be copied to _buffer. - */ -static inline void buf_set_u64(uint8_t *_buffer, - unsigned first, unsigned num, uint64_t value) -{ - uint8_t *buffer = _buffer; - - if ((num == 32) && (first == 0)) { - buffer[3] = (value >> 24) & 0xff; - buffer[2] = (value >> 16) & 0xff; - buffer[1] = (value >> 8) & 0xff; - buffer[0] = (value >> 0) & 0xff; - } else if ((num == 64) && (first == 0)) { - buffer[7] = (value >> 56) & 0xff; - buffer[6] = (value >> 48) & 0xff; - buffer[5] = (value >> 40) & 0xff; - buffer[4] = (value >> 32) & 0xff; - buffer[3] = (value >> 24) & 0xff; - buffer[2] = (value >> 16) & 0xff; - buffer[1] = (value >> 8) & 0xff; - buffer[0] = (value >> 0) & 0xff; - } else { - for (unsigned i = first; i < first + num; i++) { - if (((value >> (i - first)) & 1) == 1) - buffer[i / 8] |= 1 << (i % 8); - else - buffer[i / 8] &= ~(1 << (i % 8)); - } - } -} - -/** - * Retrieves @c num bits from @c _buffer, starting at the @c first bit, - * returning the bits in a 32-bit word. This routine fast-paths reads - * of little-endian, byte-aligned, 32-bit words. - * @param _buffer The buffer whose bits will be read. - * @param first The bit offset in @c _buffer to start reading (0-31). - * @param num The number of bits from @c _buffer to read (1-32). - * @returns Up to 32-bits that were read from @c _buffer. - */ -static inline uint32_t buf_get_u32(const uint8_t *_buffer, - unsigned first, unsigned num) -{ - const uint8_t *buffer = _buffer; - - if ((num == 32) && (first == 0)) { - return (((uint32_t)buffer[3]) << 24) | - (((uint32_t)buffer[2]) << 16) | - (((uint32_t)buffer[1]) << 8) | - (((uint32_t)buffer[0]) << 0); - } else { - uint32_t result = 0; - for (unsigned i = first; i < first + num; i++) { - if (((buffer[i / 8] >> (i % 8)) & 1) == 1) - result |= 1 << (i - first); - } - return result; - } -} - -/** - * Retrieves @c num bits from @c _buffer, starting at the @c first bit, - * returning the bits in a 64-bit word. This routine fast-paths reads - * of little-endian, byte-aligned, 64-bit words. - * @param _buffer The buffer whose bits will be read. - * @param first The bit offset in @c _buffer to start reading (0-63). - * @param num The number of bits from @c _buffer to read (1-64). - * @returns Up to 64-bits that were read from @c _buffer. - */ -static inline uint64_t buf_get_u64(const uint8_t *_buffer, - unsigned first, unsigned num) -{ - const uint8_t *buffer = _buffer; - - if ((num == 32) && (first == 0)) { - return 0 + ((((uint32_t)buffer[3]) << 24) | /* Note - zero plus is to avoid a checkpatch bug */ - (((uint32_t)buffer[2]) << 16) | - (((uint32_t)buffer[1]) << 8) | - (((uint32_t)buffer[0]) << 0)); - } else if ((num == 64) && (first == 0)) { - return 0 + ((((uint64_t)buffer[7]) << 56) | /* Note - zero plus is to avoid a checkpatch bug */ - (((uint64_t)buffer[6]) << 48) | - (((uint64_t)buffer[5]) << 40) | - (((uint64_t)buffer[4]) << 32) | - (((uint64_t)buffer[3]) << 24) | - (((uint64_t)buffer[2]) << 16) | - (((uint64_t)buffer[1]) << 8) | - (((uint64_t)buffer[0]) << 0)); - } else { - uint64_t result = 0; - for (unsigned i = first; i < first + num; i++) { - if (((buffer[i / 8] >> (i % 8)) & 1) == 1) - result = result | ((uint64_t)1 << (uint64_t)(i - first)); - } - return result; - } -} - - -/** - * Inverts the ordering of bits inside a 32-bit word (e.g. 31..0 -> 0..31). - * This routine can be used to flip smaller data types by using smaller - * values for @c width. - * @param value The word to flip. - * @param width The number of bits in value (2-32). - * @returns A 32-bit word with @c value in reversed bit-order. - */ -uint32_t flip_u32(uint32_t value, unsigned width); - -bool buf_cmp(const void *buf1, const void *buf2, unsigned size); -bool buf_cmp_mask(const void *buf1, const void *buf2, - const void *mask, unsigned size); - -/** - * Copies @c size bits out of @c from and into @c to. Any extra - * bits in the final byte will be set to zero. - * @param from The buffer to copy into @c to. - * @param to The buffer that will receive the copy of @c from. - * @param size The number of bits to copy. - */ -void *buf_cpy(const void *from, void *to, unsigned size); - -/** - * Set the contents of @c buf with @c count bits, all set to 1. - * @param buf The buffer to fill with ones. - * @param size The number of bits. - * @returns The original buffer (@c buf). - */ -void *buf_set_ones(void *buf, unsigned size); - -void *buf_set_buf(const void *src, unsigned src_start, - void *dst, unsigned dst_start, unsigned len); - -int str_to_buf(const char *str, unsigned len, - void *bin_buf, unsigned buf_size, unsigned radix); -char *buf_to_str(const void *buf, unsigned size, unsigned radix); - -/* read a uint32_t from a buffer in target memory endianness */ -static inline uint32_t fast_target_buffer_get_u32(const void *p, bool le) -{ - return le ? le_to_h_u32(p) : be_to_h_u32(p); -} - -static inline void bit_copy(uint8_t *dst, unsigned dst_offset, const uint8_t *src, - unsigned src_offset, unsigned bit_count) -{ - buf_set_buf(src, src_offset, dst, dst_offset, bit_count); -} - -struct bit_copy_queue { - struct list_head list; -}; - -struct bit_copy_queue_entry { - uint8_t *dst; - unsigned dst_offset; - const uint8_t *src; - unsigned src_offset; - unsigned bit_count; - struct list_head list; -}; - -void bit_copy_queue_init(struct bit_copy_queue *q); -int bit_copy_queued(struct bit_copy_queue *q, uint8_t *dst, unsigned dst_offset, const uint8_t *src, - unsigned src_offset, unsigned bit_count); -void bit_copy_execute(struct bit_copy_queue *q); -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); -void buffer_shr(void *_buf, unsigned buf_len, unsigned count); - -#endif /* OPENOCD_HELPER_BINARYBUFFER_H */ diff --git a/src/helper/command.c b/src/helper/command.c deleted file mode 100644 index fc4aac72e..000000000 --- a/src/helper/command.c +++ /dev/null @@ -1,1466 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * Copyright (C) 2007,2008 Øyvind Harboe * - * oyvind.harboe@zylin.com * - * * - * Copyright (C) 2008, Duane Ellis * - * openocd@duaneeellis.com * - * * - * part of this file is taken from libcli (libcli.sourceforge.net) * - * Copyright (C) David Parrish (david@dparrish.com) * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -/* see Embedded-HOWTO.txt in Jim Tcl project hosted on BerliOS*/ -#define JIM_EMBEDDED - -/* @todo the inclusion of target.h here is a layering violation */ -#include -#include -#include "command.h" -#include "configuration.h" -#include "log.h" -#include "time_support.h" -#include "jim-eventloop.h" - -/* nice short description of source file */ -#define __THIS__FILE__ "command.c" - -static int run_command(struct command_context *context, - struct command *c, const char *words[], unsigned num_words); - -struct log_capture_state { - Jim_Interp *interp; - Jim_Obj *output; -}; - -static void tcl_output(void *privData, const char *file, unsigned line, - const char *function, const char *string) -{ - struct log_capture_state *state = privData; - Jim_AppendString(state->interp, state->output, string, strlen(string)); -} - -static struct log_capture_state *command_log_capture_start(Jim_Interp *interp) -{ - /* capture log output and return it. A garbage collect can - * happen, so we need a reference count to this object */ - Jim_Obj *tclOutput = Jim_NewStringObj(interp, "", 0); - if (NULL == tclOutput) - return NULL; - - struct log_capture_state *state = malloc(sizeof(*state)); - if (NULL == state) - return NULL; - - state->interp = interp; - Jim_IncrRefCount(tclOutput); - state->output = tclOutput; - - log_add_callback(tcl_output, state); - - return state; -} - -/* Classic openocd commands provide progress output which we - * will capture and return as a Tcl return value. - * - * However, if a non-openocd command has been invoked, then it - * makes sense to return the tcl return value from that command. - * - * The tcl return value is empty for openocd commands that provide - * progress output. - * - * Therefore we set the tcl return value only if we actually - * captured output. - */ -static void command_log_capture_finish(struct log_capture_state *state) -{ - if (NULL == state) - return; - - log_remove_callback(tcl_output, state); - - int length; - Jim_GetString(state->output, &length); - - if (length > 0) - Jim_SetResult(state->interp, state->output); - else { - /* No output captured, use tcl return value (which could - * be empty too). */ - } - Jim_DecrRefCount(state->interp, state->output); - - free(state); -} - -static int command_retval_set(Jim_Interp *interp, int retval) -{ - int *return_retval = Jim_GetAssocData(interp, "retval"); - if (return_retval != NULL) - *return_retval = retval; - - return (retval == ERROR_OK) ? JIM_OK : retval; -} - -extern struct command_context *global_cmd_ctx; - -/* dump a single line to the log for the command. - * Do nothing in case we are not at debug level 3 */ -void script_debug(Jim_Interp *interp, const char *name, - unsigned argc, Jim_Obj * const *argv) -{ - if (debug_level < LOG_LVL_DEBUG) - return; - - char *dbg = alloc_printf("command - %s", name); - for (unsigned i = 0; i < argc; i++) { - int len; - const char *w = Jim_GetString(argv[i], &len); - char *t = alloc_printf("%s %s", dbg, w); - free(dbg); - dbg = t; - } - LOG_DEBUG("%s", dbg); - free(dbg); -} - -static void script_command_args_free(char **words, unsigned nwords) -{ - for (unsigned i = 0; i < nwords; i++) - free(words[i]); - free(words); -} - -static char **script_command_args_alloc( - unsigned argc, Jim_Obj * const *argv, unsigned *nwords) -{ - char **words = malloc(argc * sizeof(char *)); - if (NULL == words) - return NULL; - - unsigned i; - for (i = 0; i < argc; i++) { - int len; - const char *w = Jim_GetString(argv[i], &len); - words[i] = strdup(w); - if (words[i] == NULL) { - script_command_args_free(words, i); - return NULL; - } - } - *nwords = i; - return words; -} - -struct command_context *current_command_context(Jim_Interp *interp) -{ - /* grab the command context from the associated data */ - struct command_context *cmd_ctx = Jim_GetAssocData(interp, "context"); - if (NULL == cmd_ctx) { - /* Tcl can invoke commands directly instead of via command_run_line(). This would - * happen when the Jim Tcl interpreter is provided by eCos or if we are running - * commands in a startup script. - * - * A telnet or gdb server would provide a non-default command context to - * handle piping of error output, have a separate current target, etc. - */ - cmd_ctx = global_cmd_ctx; - } - return cmd_ctx; -} - -static int script_command_run(Jim_Interp *interp, - int argc, Jim_Obj * const *argv, struct command *c, bool capture) -{ - target_call_timer_callbacks_now(); - LOG_USER_N("%s", ""); /* Keep GDB connection alive*/ - - unsigned nwords; - char **words = script_command_args_alloc(argc, argv, &nwords); - if (NULL == words) - return JIM_ERR; - - struct log_capture_state *state = NULL; - if (capture) - state = command_log_capture_start(interp); - - struct command_context *cmd_ctx = current_command_context(interp); - int retval = run_command(cmd_ctx, c, (const char **)words, nwords); - - command_log_capture_finish(state); - - script_command_args_free(words, nwords); - return command_retval_set(interp, retval); -} - -static int script_command(Jim_Interp *interp, int argc, Jim_Obj *const *argv) -{ - /* the private data is stashed in the interp structure */ - - struct command *c = interp->cmdPrivData; - assert(c); - script_debug(interp, c->name, argc, argv); - return script_command_run(interp, argc, argv, c, true); -} - -static struct command *command_root(struct command *c) -{ - while (NULL != c->parent) - c = c->parent; - return c; -} - -/** - * Find a command by name from a list of commands. - * @returns Returns the named command if it exists in the list. - * Returns NULL otherwise. - */ -static struct command *command_find(struct command *head, const char *name) -{ - for (struct command *cc = head; cc; cc = cc->next) { - if (strcmp(cc->name, name) == 0) - return cc; - } - return NULL; -} - -struct command *command_find_in_context(struct command_context *cmd_ctx, - const char *name) -{ - return command_find(cmd_ctx->commands, name); -} -struct command *command_find_in_parent(struct command *parent, - const char *name) -{ - return command_find(parent->children, name); -} - -/** - * Add the command into the linked list, sorted by name. - * @param head Address to head of command list pointer, which may be - * updated if @c c gets inserted at the beginning of the list. - * @param c The command to add to the list pointed to by @c head. - */ -static void command_add_child(struct command **head, struct command *c) -{ - assert(head); - if (NULL == *head) { - *head = c; - return; - } - - while ((*head)->next && (strcmp(c->name, (*head)->name) > 0)) - head = &(*head)->next; - - if (strcmp(c->name, (*head)->name) > 0) { - c->next = (*head)->next; - (*head)->next = c; - } else { - c->next = *head; - *head = c; - } -} - -static struct command **command_list_for_parent( - struct command_context *cmd_ctx, struct command *parent) -{ - return parent ? &parent->children : &cmd_ctx->commands; -} - -static void command_free(struct command *c) -{ - /** @todo if command has a handler, unregister its jim command! */ - - while (NULL != c->children) { - struct command *tmp = c->children; - c->children = tmp->next; - command_free(tmp); - } - - free(c->name); - free(c->help); - free(c->usage); - free(c); -} - -static struct command *command_new(struct command_context *cmd_ctx, - struct command *parent, const struct command_registration *cr) -{ - assert(cr->name); - - /* - * If it is a non-jim command with no .usage specified, - * log an error. - * - * strlen(.usage) == 0 means that the command takes no - * arguments. - */ - if ((cr->jim_handler == NULL) && (cr->usage == NULL)) { - LOG_DEBUG("BUG: command '%s%s%s' does not have the " - "'.usage' field filled out", - parent && parent->name ? parent->name : "", - parent && parent->name ? " " : "", - cr->name); - } - - struct command *c = calloc(1, sizeof(struct command)); - if (NULL == c) - return NULL; - - c->name = strdup(cr->name); - if (cr->help) - c->help = strdup(cr->help); - if (cr->usage) - c->usage = strdup(cr->usage); - - if (!c->name || (cr->help && !c->help) || (cr->usage && !c->usage)) - goto command_new_error; - - c->parent = parent; - c->handler = cr->handler; - c->jim_handler = cr->jim_handler; - c->jim_handler_data = cr->jim_handler_data; - c->mode = cr->mode; - - command_add_child(command_list_for_parent(cmd_ctx, parent), c); - - return c; - -command_new_error: - command_free(c); - return NULL; -} - -static int command_unknown(Jim_Interp *interp, int argc, Jim_Obj *const *argv); - -static int register_command_handler(struct command_context *cmd_ctx, - struct command *c) -{ - Jim_Interp *interp = cmd_ctx->interp; - char *ocd_name = alloc_printf("ocd_%s", c->name); - if (NULL == ocd_name) - return JIM_ERR; - - LOG_DEBUG("registering '%s'...", ocd_name); - - Jim_CmdProc *func = c->handler ? &script_command : &command_unknown; - int retval = Jim_CreateCommand(interp, ocd_name, func, c, NULL); - free(ocd_name); - if (JIM_OK != retval) - return retval; - - /* we now need to add an overrideable proc */ - char *override_name = alloc_printf( - "proc %s {args} {eval ocd_bouncer %s $args}", - c->name, c->name); - if (NULL == override_name) - return JIM_ERR; - - retval = Jim_Eval_Named(interp, override_name, 0, 0); - free(override_name); - - return retval; -} - -struct command *register_command(struct command_context *context, - struct command *parent, const struct command_registration *cr) -{ - if (!context || !cr->name) - return NULL; - - const char *name = cr->name; - struct command **head = command_list_for_parent(context, parent); - struct command *c = command_find(*head, name); - if (NULL != c) { - /* TODO: originally we treated attempting to register a cmd twice as an error - * Sometimes we need this behaviour, such as with flash banks. - * http://www.mail-archive.com/openocd-development@lists.berlios.de/msg11152.html */ - LOG_DEBUG("command '%s' is already registered in '%s' context", - name, parent ? parent->name : ""); - return c; - } - - c = command_new(context, parent, cr); - if (NULL == c) - return NULL; - - int retval = ERROR_OK; - if (NULL != cr->jim_handler && NULL == parent) { - retval = Jim_CreateCommand(context->interp, cr->name, - cr->jim_handler, cr->jim_handler_data, NULL); - } else if (NULL != cr->handler || NULL != parent) - retval = register_command_handler(context, command_root(c)); - - if (ERROR_OK != retval) { - unregister_command(context, parent, name); - c = NULL; - } - return c; -} - -int register_commands(struct command_context *cmd_ctx, struct command *parent, - const struct command_registration *cmds) -{ - int retval = ERROR_OK; - unsigned i; - for (i = 0; cmds[i].name || cmds[i].chain; i++) { - const struct command_registration *cr = cmds + i; - - struct command *c = NULL; - if (NULL != cr->name) { - c = register_command(cmd_ctx, parent, cr); - if (NULL == c) { - retval = ERROR_FAIL; - break; - } - } - if (NULL != cr->chain) { - struct command *p = c ? : parent; - retval = register_commands(cmd_ctx, p, cr->chain); - if (ERROR_OK != retval) - break; - } - } - if (ERROR_OK != retval) { - for (unsigned j = 0; j < i; j++) - unregister_command(cmd_ctx, parent, cmds[j].name); - } - return retval; -} - -int unregister_all_commands(struct command_context *context, - struct command *parent) -{ - if (context == NULL) - return ERROR_OK; - - struct command **head = command_list_for_parent(context, parent); - while (NULL != *head) { - struct command *tmp = *head; - *head = tmp->next; - command_free(tmp); - } - - return ERROR_OK; -} - -int unregister_command(struct command_context *context, - struct command *parent, const char *name) -{ - if ((!context) || (!name)) - return ERROR_COMMAND_SYNTAX_ERROR; - - struct command *p = NULL; - struct command **head = command_list_for_parent(context, parent); - for (struct command *c = *head; NULL != c; p = c, c = c->next) { - if (strcmp(name, c->name) != 0) - continue; - - if (p) - p->next = c->next; - else - *head = c->next; - - command_free(c); - return ERROR_OK; - } - - return ERROR_OK; -} - -void command_set_handler_data(struct command *c, void *p) -{ - if (NULL != c->handler || NULL != c->jim_handler) - c->jim_handler_data = p; - for (struct command *cc = c->children; NULL != cc; cc = cc->next) - command_set_handler_data(cc, p); -} - -void command_output_text(struct command_context *context, const char *data) -{ - if (context && context->output_handler && data) - context->output_handler(context, data); -} - -void command_print_sameline(struct command_context *context, const char *format, ...) -{ - char *string; - - va_list ap; - va_start(ap, format); - - string = alloc_vprintf(format, ap); - if (string != NULL) { - /* we want this collected in the log + we also want to pick it up as a tcl return - * value. - * - * The latter bit isn't precisely neat, but will do for now. - */ - LOG_USER_N("%s", string); - /* We already printed it above - * command_output_text(context, string); */ - free(string); - } - - va_end(ap); -} - -void command_print(struct command_context *context, const char *format, ...) -{ - char *string; - - va_list ap; - 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 */ - /* we want this collected in the log + we also want to pick it up as a tcl return - * value. - * - * The latter bit isn't precisely neat, but will do for now. - */ - LOG_USER_N("%s", string); - /* We already printed it above - * command_output_text(context, string); */ - free(string); - } - - va_end(ap); -} - -static char *__command_name(struct command *c, char delim, unsigned extra) -{ - char *name; - unsigned len = strlen(c->name); - if (NULL == c->parent) { - /* allocate enough for the name, child names, and '\0' */ - name = malloc(len + extra + 1); - strcpy(name, c->name); - } else { - /* parent's extra must include both the space and name */ - name = __command_name(c->parent, delim, 1 + len + extra); - char dstr[2] = { delim, 0 }; - strcat(name, dstr); - strcat(name, c->name); - } - return name; -} - -char *command_name(struct command *c, char delim) -{ - return __command_name(c, delim, 0); -} - -static bool command_can_run(struct command_context *cmd_ctx, struct command *c) -{ - return c->mode == COMMAND_ANY || c->mode == cmd_ctx->mode; -} - -static int run_command(struct command_context *context, - struct command *c, const char *words[], unsigned num_words) -{ - if (!command_can_run(context, c)) { - /* Many commands may be run only before/after 'init' */ - const char *when; - switch (c->mode) { - case COMMAND_CONFIG: - when = "before"; - break; - case COMMAND_EXEC: - when = "after"; - break; - /* handle the impossible with humor; it guarantees a bug report! */ - default: - when = "if Cthulhu is summoned by"; - break; - } - LOG_ERROR("The '%s' command must be used %s 'init'.", - c->name, when); - return ERROR_FAIL; - } - - struct command_invocation cmd = { - .ctx = context, - .current = c, - .name = c->name, - .argc = num_words - 1, - .argv = words + 1, - }; - int retval = c->handler(&cmd); - if (retval == ERROR_COMMAND_SYNTAX_ERROR) { - /* Print help for command */ - char *full_name = command_name(c, ' '); - if (NULL != full_name) { - command_run_linef(context, "usage %s", full_name); - free(full_name); - } else - retval = -ENOMEM; - } else if (retval == ERROR_COMMAND_CLOSE_CONNECTION) { - /* just fall through for a shutdown request */ - } else if (retval != ERROR_OK) { - /* we do not print out an error message because the command *should* - * have printed out an error - */ - LOG_DEBUG("Command failed with error code %d", retval); - } - - return retval; -} - -int command_run_line(struct command_context *context, char *line) -{ - /* all the parent commands have been registered with the interpreter - * so, can just evaluate the line as a script and check for - * results - */ - /* run the line thru a script engine */ - int retval = ERROR_FAIL; - int retcode; - /* Beware! This code needs to be reentrant. It is also possible - * for OpenOCD commands to be invoked directly from Tcl. This would - * happen when the Jim Tcl interpreter is provided by eCos for - * instance. - */ - Jim_Interp *interp = context->interp; - Jim_DeleteAssocData(interp, "context"); - retcode = Jim_SetAssocData(interp, "context", NULL, context); - if (retcode == JIM_OK) { - /* associated the return value */ - Jim_DeleteAssocData(interp, "retval"); - retcode = Jim_SetAssocData(interp, "retval", NULL, &retval); - if (retcode == JIM_OK) { - retcode = Jim_Eval_Named(interp, line, 0, 0); - - Jim_DeleteAssocData(interp, "retval"); - } - Jim_DeleteAssocData(interp, "context"); - } - if (retcode == JIM_OK) { - const char *result; - int reslen; - - result = Jim_GetString(Jim_GetResult(interp), &reslen); - if (reslen > 0) { - int i; - char buff[256 + 1]; - for (i = 0; i < reslen; i += 256) { - int chunk; - chunk = reslen - i; - if (chunk > 256) - chunk = 256; - strncpy(buff, result + i, chunk); - buff[chunk] = 0; - LOG_USER_N("%s", buff); - } - LOG_USER_N("\n"); - } - retval = ERROR_OK; - } else if (retcode == JIM_EXIT) { - /* ignore. - * exit(Jim_GetExitCode(interp)); */ - } else if (retcode == ERROR_COMMAND_CLOSE_CONNECTION) { - return retcode; - } else { - Jim_MakeErrorMessage(interp); - LOG_USER("%s", Jim_GetString(Jim_GetResult(interp), NULL)); - - if (retval == ERROR_OK) { - /* It wasn't a low level OpenOCD command that failed */ - return ERROR_FAIL; - } - return retval; - } - - return retval; -} - -int command_run_linef(struct command_context *context, const char *format, ...) -{ - int retval = ERROR_FAIL; - char *string; - va_list ap; - va_start(ap, format); - string = alloc_vprintf(format, ap); - if (string != NULL) { - retval = command_run_line(context, string); - free(string); - } - va_end(ap); - return retval; -} - -void command_set_output_handler(struct command_context *context, - command_output_handler_t output_handler, void *priv) -{ - context->output_handler = output_handler; - context->output_handler_priv = priv; -} - -struct command_context *copy_command_context(struct command_context *context) -{ - struct command_context *copy_context = malloc(sizeof(struct command_context)); - - *copy_context = *context; - - return copy_context; -} - -void command_done(struct command_context *cmd_ctx) -{ - if (NULL == cmd_ctx) - return; - - free(cmd_ctx); -} - -/* find full path to file */ -static int jim_find(Jim_Interp *interp, int argc, Jim_Obj *const *argv) -{ - if (argc != 2) - return JIM_ERR; - const char *file = Jim_GetString(argv[1], NULL); - char *full_path = find_file(file); - if (full_path == NULL) - return JIM_ERR; - Jim_Obj *result = Jim_NewStringObj(interp, full_path, strlen(full_path)); - free(full_path); - - Jim_SetResult(interp, result); - return JIM_OK; -} - -COMMAND_HANDLER(jim_echo) -{ - if (CMD_ARGC == 2 && !strcmp(CMD_ARGV[0], "-n")) { - LOG_USER_N("%s", CMD_ARGV[1]); - return JIM_OK; - } - if (CMD_ARGC != 1) - return JIM_ERR; - LOG_USER("%s", CMD_ARGV[0]); - return JIM_OK; -} - -/* Capture progress output and return as tcl return value. If the - * progress output was empty, return tcl return value. - */ -static int jim_capture(Jim_Interp *interp, int argc, Jim_Obj *const *argv) -{ - if (argc != 2) - return JIM_ERR; - - struct log_capture_state *state = command_log_capture_start(interp); - - /* disable polling during capture. This avoids capturing output - * from polling. - * - * This is necessary in order to avoid accidentally getting a non-empty - * string for tcl fn's. - */ - bool save_poll = jtag_poll_get_enabled(); - - jtag_poll_set_enabled(false); - - const char *str = Jim_GetString(argv[1], NULL); - int retcode = Jim_Eval_Named(interp, str, __THIS__FILE__, __LINE__); - - jtag_poll_set_enabled(save_poll); - - command_log_capture_finish(state); - - return retcode; -} - -static COMMAND_HELPER(command_help_find, struct command *head, - struct command **out) -{ - if (0 == CMD_ARGC) - return ERROR_COMMAND_SYNTAX_ERROR; - *out = command_find(head, CMD_ARGV[0]); - if (NULL == *out && strncmp(CMD_ARGV[0], "ocd_", 4) == 0) - *out = command_find(head, CMD_ARGV[0] + 4); - if (NULL == *out) - return ERROR_COMMAND_SYNTAX_ERROR; - if (--CMD_ARGC == 0) - return ERROR_OK; - CMD_ARGV++; - return CALL_COMMAND_HANDLER(command_help_find, (*out)->children, out); -} - -static COMMAND_HELPER(command_help_show, struct command *c, unsigned n, - bool show_help, const char *cmd_match); - -static COMMAND_HELPER(command_help_show_list, struct command *head, unsigned n, - bool show_help, const char *cmd_match) -{ - for (struct command *c = head; NULL != c; c = c->next) - CALL_COMMAND_HANDLER(command_help_show, c, n, show_help, cmd_match); - return ERROR_OK; -} - -#define HELP_LINE_WIDTH(_n) (int)(76 - (2 * _n)) - -static void command_help_show_indent(unsigned n) -{ - for (unsigned i = 0; i < n; i++) - LOG_USER_N(" "); -} -static void command_help_show_wrap(const char *str, unsigned n, unsigned n2) -{ - const char *cp = str, *last = str; - while (*cp) { - const char *next = last; - do { - cp = next; - do { - next++; - } while (*next != ' ' && *next != '\t' && *next != '\0'); - } while ((next - last < HELP_LINE_WIDTH(n)) && *next != '\0'); - if (next - last < HELP_LINE_WIDTH(n)) - cp = next; - command_help_show_indent(n); - LOG_USER("%.*s", (int)(cp - last), last); - last = cp + 1; - n = n2; - } -} - -static COMMAND_HELPER(command_help_show, struct command *c, unsigned n, - bool show_help, const char *cmd_match) -{ - char *cmd_name = command_name(c, ' '); - if (NULL == cmd_name) - return -ENOMEM; - - /* If the match string occurs anywhere, we print out - * stuff for this command. */ - bool is_match = (strstr(cmd_name, cmd_match) != NULL) || - ((c->usage != NULL) && (strstr(c->usage, cmd_match) != NULL)) || - ((c->help != NULL) && (strstr(c->help, cmd_match) != NULL)); - - if (is_match) { - command_help_show_indent(n); - LOG_USER_N("%s", cmd_name); - } - free(cmd_name); - - if (is_match) { - if (c->usage && strlen(c->usage) > 0) { - LOG_USER_N(" "); - command_help_show_wrap(c->usage, 0, n + 5); - } else - LOG_USER_N("\n"); - } - - if (is_match && show_help) { - char *msg; - - /* Normal commands are runtime-only; highlight exceptions */ - if (c->mode != COMMAND_EXEC) { - const char *stage_msg = ""; - - switch (c->mode) { - case COMMAND_CONFIG: - stage_msg = " (configuration command)"; - break; - case COMMAND_ANY: - stage_msg = " (command valid any time)"; - break; - default: - stage_msg = " (?mode error?)"; - break; - } - msg = alloc_printf("%s%s", c->help ? : "", stage_msg); - } else - msg = alloc_printf("%s", c->help ? : ""); - - if (NULL != msg) { - command_help_show_wrap(msg, n + 3, n + 3); - free(msg); - } else - return -ENOMEM; - } - - if (++n > 5) { - LOG_ERROR("command recursion exceeded"); - return ERROR_FAIL; - } - - return CALL_COMMAND_HANDLER(command_help_show_list, - c->children, n, show_help, cmd_match); -} - -COMMAND_HANDLER(handle_help_command) -{ - bool full = strcmp(CMD_NAME, "help") == 0; - int retval; - struct command *c = CMD_CTX->commands; - char *cmd_match = NULL; - - if (CMD_ARGC == 0) - cmd_match = ""; - else if (CMD_ARGC >= 1) { - unsigned i; - - for (i = 0; i < CMD_ARGC; ++i) { - if (NULL != cmd_match) { - char *prev = cmd_match; - - cmd_match = alloc_printf("%s %s", cmd_match, CMD_ARGV[i]); - free(prev); - if (NULL == cmd_match) { - LOG_ERROR("unable to build search string"); - return -ENOMEM; - } - } else { - cmd_match = alloc_printf("%s", CMD_ARGV[i]); - if (NULL == cmd_match) { - LOG_ERROR("unable to build search string"); - return -ENOMEM; - } - } - } - } else - return ERROR_COMMAND_SYNTAX_ERROR; - - retval = CALL_COMMAND_HANDLER(command_help_show_list, - c, 0, full, cmd_match); - - if (CMD_ARGC >= 1) - free(cmd_match); - return retval; -} - -static int command_unknown_find(unsigned argc, Jim_Obj *const *argv, - struct command *head, struct command **out, bool top_level) -{ - if (0 == argc) - return argc; - const char *cmd_name = Jim_GetString(argv[0], NULL); - struct command *c = command_find(head, cmd_name); - if (NULL == c && top_level && strncmp(cmd_name, "ocd_", 4) == 0) - c = command_find(head, cmd_name + 4); - if (NULL == c) - return argc; - *out = c; - return command_unknown_find(--argc, ++argv, (*out)->children, out, false); -} - -static int command_unknown(Jim_Interp *interp, int argc, Jim_Obj *const *argv) -{ - const char *cmd_name = Jim_GetString(argv[0], NULL); - if (strcmp(cmd_name, "unknown") == 0) { - if (argc == 1) - return JIM_OK; - argc--; - argv++; - } - script_debug(interp, cmd_name, argc, argv); - - struct command_context *cmd_ctx = current_command_context(interp); - struct command *c = cmd_ctx->commands; - int remaining = command_unknown_find(argc, argv, c, &c, true); - /* if nothing could be consumed, then it's really an unknown command */ - if (remaining == argc) { - const char *cmd = Jim_GetString(argv[0], NULL); - LOG_ERROR("Unknown command:\n %s", cmd); - return JIM_OK; - } - - bool found = true; - Jim_Obj *const *start; - unsigned count; - if (c->handler || c->jim_handler) { - /* include the command name in the list */ - count = remaining + 1; - start = argv + (argc - remaining - 1); - } else { - c = command_find(cmd_ctx->commands, "usage"); - if (NULL == c) { - LOG_ERROR("unknown command, but usage is missing too"); - return JIM_ERR; - } - count = argc - remaining; - start = argv; - found = false; - } - /* pass the command through to the intended handler */ - if (c->jim_handler) { - interp->cmdPrivData = c->jim_handler_data; - return (*c->jim_handler)(interp, count, start); - } - - return script_command_run(interp, count, start, c, found); -} - -static int jim_command_mode(Jim_Interp *interp, int argc, Jim_Obj *const *argv) -{ - struct command_context *cmd_ctx = current_command_context(interp); - enum command_mode mode; - - if (argc > 1) { - struct command *c = cmd_ctx->commands; - int remaining = command_unknown_find(argc - 1, argv + 1, c, &c, true); - /* if nothing could be consumed, then it's an unknown command */ - if (remaining == argc - 1) { - Jim_SetResultString(interp, "unknown", -1); - return JIM_OK; - } - mode = c->mode; - } else - mode = cmd_ctx->mode; - - const char *mode_str; - switch (mode) { - case COMMAND_ANY: - mode_str = "any"; - break; - case COMMAND_CONFIG: - mode_str = "config"; - break; - case COMMAND_EXEC: - mode_str = "exec"; - break; - default: - mode_str = "unknown"; - break; - } - Jim_SetResultString(interp, mode_str, -1); - return JIM_OK; -} - -static int jim_command_type(Jim_Interp *interp, int argc, Jim_Obj *const *argv) -{ - if (1 == argc) - return JIM_ERR; - - struct command_context *cmd_ctx = current_command_context(interp); - struct command *c = cmd_ctx->commands; - int remaining = command_unknown_find(argc - 1, argv + 1, c, &c, true); - /* if nothing could be consumed, then it's an unknown command */ - if (remaining == argc - 1) { - Jim_SetResultString(interp, "unknown", -1); - return JIM_OK; - } - - if (c->jim_handler) - Jim_SetResultString(interp, "native", -1); - else if (c->handler) - Jim_SetResultString(interp, "simple", -1); - else if (remaining == 0) - Jim_SetResultString(interp, "group", -1); - else - Jim_SetResultString(interp, "unknown", -1); - - return JIM_OK; -} - -int help_add_command(struct command_context *cmd_ctx, struct command *parent, - const char *cmd_name, const char *help_text, const char *usage) -{ - struct command **head = command_list_for_parent(cmd_ctx, parent); - struct command *nc = command_find(*head, cmd_name); - if (NULL == nc) { - /* add a new command with help text */ - struct command_registration cr = { - .name = cmd_name, - .mode = COMMAND_ANY, - .help = help_text, - .usage = usage, - }; - nc = register_command(cmd_ctx, parent, &cr); - if (NULL == nc) { - LOG_ERROR("failed to add '%s' help text", cmd_name); - return ERROR_FAIL; - } - LOG_DEBUG("added '%s' help text", cmd_name); - return ERROR_OK; - } - if (help_text) { - bool replaced = false; - if (nc->help) { - free(nc->help); - replaced = true; - } - nc->help = strdup(help_text); - if (replaced) - LOG_INFO("replaced existing '%s' help", cmd_name); - else - LOG_DEBUG("added '%s' help text", cmd_name); - } - if (usage) { - bool replaced = false; - if (nc->usage) { - free(nc->usage); - replaced = true; - } - nc->usage = strdup(usage); - if (replaced) - LOG_INFO("replaced existing '%s' usage", cmd_name); - else - LOG_DEBUG("added '%s' usage text", cmd_name); - } - return ERROR_OK; -} - -COMMAND_HANDLER(handle_help_add_command) -{ - if (CMD_ARGC < 2) { - LOG_ERROR("%s: insufficient arguments", CMD_NAME); - return ERROR_COMMAND_SYNTAX_ERROR; - } - - /* save help text and remove it from argument list */ - const char *str = CMD_ARGV[--CMD_ARGC]; - const char *help = !strcmp(CMD_NAME, "add_help_text") ? str : NULL; - const char *usage = !strcmp(CMD_NAME, "add_usage_text") ? str : NULL; - if (!help && !usage) { - LOG_ERROR("command name '%s' is unknown", CMD_NAME); - return ERROR_COMMAND_SYNTAX_ERROR; - } - /* likewise for the leaf command name */ - const char *cmd_name = CMD_ARGV[--CMD_ARGC]; - - struct command *c = NULL; - if (CMD_ARGC > 0) { - c = CMD_CTX->commands; - int retval = CALL_COMMAND_HANDLER(command_help_find, c, &c); - if (ERROR_OK != retval) - return retval; - } - return help_add_command(CMD_CTX, c, cmd_name, help, usage); -} - -/* sleep command sleeps for milliseconds - * this is useful in target startup scripts - */ -COMMAND_HANDLER(handle_sleep_command) -{ - bool busy = false; - if (CMD_ARGC == 2) { - if (strcmp(CMD_ARGV[1], "busy") == 0) - busy = true; - else - return ERROR_COMMAND_SYNTAX_ERROR; - } else if (CMD_ARGC < 1 || CMD_ARGC > 2) - return ERROR_COMMAND_SYNTAX_ERROR; - - unsigned long duration = 0; - int retval = parse_ulong(CMD_ARGV[0], &duration); - if (ERROR_OK != retval) - return retval; - - if (!busy) { - int64_t then = timeval_ms(); - while (timeval_ms() - then < (int64_t)duration) { - target_call_timer_callbacks_now(); - usleep(1000); - } - } else - busy_sleep(duration); - - return ERROR_OK; -} - -static const struct command_registration command_subcommand_handlers[] = { - { - .name = "mode", - .mode = COMMAND_ANY, - .jim_handler = jim_command_mode, - .usage = "[command_name ...]", - .help = "Returns the command modes allowed by a command:" - "'any', 'config', or 'exec'. If no command is" - "specified, returns the current command mode. " - "Returns 'unknown' if an unknown command is given. " - "Command can be multiple tokens.", - }, - { - .name = "type", - .mode = COMMAND_ANY, - .jim_handler = jim_command_type, - .usage = "command_name [...]", - .help = "Returns the type of built-in command:" - "'native', 'simple', 'group', or 'unknown'. " - "Command can be multiple tokens.", - }, - COMMAND_REGISTRATION_DONE -}; - -static const struct command_registration command_builtin_handlers[] = { - { - .name = "echo", - .handler = jim_echo, - .mode = COMMAND_ANY, - .help = "Logs a message at \"user\" priority. " - "Output message to stdout. " - "Option \"-n\" suppresses trailing newline", - .usage = "[-n] string", - }, - { - .name = "add_help_text", - .handler = handle_help_add_command, - .mode = COMMAND_ANY, - .help = "Add new command help text; " - "Command can be multiple tokens.", - .usage = "command_name helptext_string", - }, - { - .name = "add_usage_text", - .handler = handle_help_add_command, - .mode = COMMAND_ANY, - .help = "Add new command usage text; " - "command can be multiple tokens.", - .usage = "command_name usage_string", - }, - { - .name = "sleep", - .handler = handle_sleep_command, - .mode = COMMAND_ANY, - .help = "Sleep for specified number of milliseconds. " - "\"busy\" will busy wait instead (avoid this).", - .usage = "milliseconds ['busy']", - }, - { - .name = "help", - .handler = handle_help_command, - .mode = COMMAND_ANY, - .help = "Show full command help; " - "command can be multiple tokens.", - .usage = "[command_name]", - }, - { - .name = "usage", - .handler = handle_help_command, - .mode = COMMAND_ANY, - .help = "Show basic command usage; " - "command can be multiple tokens.", - .usage = "[command_name]", - }, - { - .name = "command", - .mode = COMMAND_ANY, - .help = "core command group (introspection)", - .chain = command_subcommand_handlers, - }, - COMMAND_REGISTRATION_DONE -}; - -struct command_context *command_init(const char *startup_tcl, Jim_Interp *interp) -{ - struct command_context *context = malloc(sizeof(struct command_context)); - const char *HostOs; - - context->mode = COMMAND_EXEC; - context->commands = NULL; - context->current_target = 0; - context->output_handler = NULL; - context->output_handler_priv = NULL; - - /* Create a jim interpreter if we were not handed one */ - if (interp == NULL) { - /* Create an interpreter */ - interp = Jim_CreateInterp(); - /* Add all the Jim core commands */ - Jim_RegisterCoreCommands(interp); - Jim_InitStaticExtensions(interp); - } - - context->interp = interp; - - /* Stick to lowercase for HostOS strings. */ -#if defined(_MSC_VER) - /* WinXX - is generic, the forward - * looking problem is this: - * - * "win32" or "win64" - * - * "winxx" is generic. - */ - HostOs = "winxx"; -#elif defined(__linux__) - HostOs = "linux"; -#elif defined(__APPLE__) || defined(__DARWIN__) - HostOs = "darwin"; -#elif defined(__CYGWIN__) - HostOs = "cygwin"; -#elif defined(__MINGW32__) - HostOs = "mingw32"; -#elif defined(__ECOS) - HostOs = "ecos"; -#elif defined(__FreeBSD__) - HostOs = "freebsd"; -#elif defined(__NetBSD__) - HostOs = "netbsd"; -#elif defined(__OpenBSD__) - HostOs = "openbsd"; -#else -#warning "Unrecognized host OS..." - HostOs = "other"; -#endif - Jim_SetGlobalVariableStr(interp, "ocd_HOSTOS", - Jim_NewStringObj(interp, HostOs, strlen(HostOs))); - - Jim_CreateCommand(interp, "ocd_find", jim_find, NULL, NULL); - Jim_CreateCommand(interp, "capture", jim_capture, NULL, NULL); - - register_commands(context, NULL, command_builtin_handlers); - - Jim_SetAssocData(interp, "context", NULL, context); - if (Jim_Eval_Named(interp, startup_tcl, "embedded:startup.tcl", 1) == JIM_ERR) { - LOG_ERROR("Failed to run startup.tcl (embedded into OpenOCD)"); - Jim_MakeErrorMessage(interp); - LOG_USER_N("%s", Jim_GetString(Jim_GetResult(interp), NULL)); - exit(-1); - } - Jim_DeleteAssocData(interp, "context"); - - return context; -} - -int command_context_mode(struct command_context *cmd_ctx, enum command_mode mode) -{ - if (!cmd_ctx) - return ERROR_COMMAND_SYNTAX_ERROR; - - cmd_ctx->mode = mode; - return ERROR_OK; -} - -void process_jim_events(struct command_context *cmd_ctx) -{ - static int recursion; - if (recursion) - return; - - recursion++; - Jim_ProcessEvents(cmd_ctx->interp, JIM_ALL_EVENTS | JIM_DONT_WAIT); - recursion--; -} - -#define DEFINE_PARSE_NUM_TYPE(name, type, func, min, max) \ - int parse ## name(const char *str, type * ul) \ - { \ - if (!*str) { \ - LOG_ERROR("Invalid command argument"); \ - return ERROR_COMMAND_ARGUMENT_INVALID; \ - } \ - char *end; \ - *ul = func(str, &end, 0); \ - if (*end) { \ - LOG_ERROR("Invalid command argument"); \ - return ERROR_COMMAND_ARGUMENT_INVALID; \ - } \ - if ((max == *ul) && (ERANGE == errno)) { \ - LOG_ERROR("Argument overflow"); \ - return ERROR_COMMAND_ARGUMENT_OVERFLOW; \ - } \ - if (min && (min == *ul) && (ERANGE == errno)) { \ - LOG_ERROR("Argument underflow"); \ - return ERROR_COMMAND_ARGUMENT_UNDERFLOW; \ - } \ - return ERROR_OK; \ - } -DEFINE_PARSE_NUM_TYPE(_ulong, unsigned long, strtoul, 0, ULONG_MAX) -DEFINE_PARSE_NUM_TYPE(_ullong, unsigned long long, strtoull, 0, ULLONG_MAX) -DEFINE_PARSE_NUM_TYPE(_long, long, strtol, LONG_MIN, LONG_MAX) -DEFINE_PARSE_NUM_TYPE(_llong, long long, strtoll, LLONG_MIN, LLONG_MAX) - -#define DEFINE_PARSE_WRAPPER(name, type, min, max, functype, funcname) \ - int parse ## name(const char *str, type * ul) \ - { \ - functype n; \ - int retval = parse ## funcname(str, &n); \ - if (ERROR_OK != retval) \ - return retval; \ - if (n > max) \ - return ERROR_COMMAND_ARGUMENT_OVERFLOW; \ - if (min) \ - return ERROR_COMMAND_ARGUMENT_UNDERFLOW; \ - *ul = n; \ - return ERROR_OK; \ - } - -#define DEFINE_PARSE_ULONGLONG(name, type, min, max) \ - DEFINE_PARSE_WRAPPER(name, type, min, max, unsigned long long, _ullong) -DEFINE_PARSE_ULONGLONG(_uint, unsigned, 0, UINT_MAX) -DEFINE_PARSE_ULONGLONG(_u64, uint64_t, 0, UINT64_MAX) -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 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) -DEFINE_PARSE_LONGLONG(_s64, int64_t, n < INT64_MIN, INT64_MAX) -DEFINE_PARSE_LONGLONG(_s32, int32_t, n < INT32_MIN, INT32_MAX) -DEFINE_PARSE_LONGLONG(_s16, int16_t, n < INT16_MIN, INT16_MAX) -DEFINE_PARSE_LONGLONG(_s8, int8_t, n < INT8_MIN, INT8_MAX) - -static int command_parse_bool(const char *in, bool *out, - const char *on, const char *off) -{ - if (strcasecmp(in, on) == 0) - *out = true; - else if (strcasecmp(in, off) == 0) - *out = false; - else - return ERROR_COMMAND_SYNTAX_ERROR; - return ERROR_OK; -} - -int command_parse_bool_arg(const char *in, bool *out) -{ - if (command_parse_bool(in, out, "on", "off") == ERROR_OK) - return ERROR_OK; - if (command_parse_bool(in, out, "enable", "disable") == ERROR_OK) - return ERROR_OK; - if (command_parse_bool(in, out, "true", "false") == ERROR_OK) - return ERROR_OK; - if (command_parse_bool(in, out, "yes", "no") == ERROR_OK) - return ERROR_OK; - if (command_parse_bool(in, out, "1", "0") == ERROR_OK) - return ERROR_OK; - return ERROR_COMMAND_SYNTAX_ERROR; -} - -COMMAND_HELPER(handle_command_parse_bool, bool *out, const char *label) -{ - switch (CMD_ARGC) { - case 1: { - const char *in = CMD_ARGV[0]; - if (command_parse_bool_arg(in, out) != ERROR_OK) { - LOG_ERROR("%s: argument '%s' is not valid", CMD_NAME, in); - return ERROR_COMMAND_SYNTAX_ERROR; - } - /* fall through */ - } - case 0: - LOG_INFO("%s is %s", label, *out ? "enabled" : "disabled"); - break; - default: - return ERROR_COMMAND_SYNTAX_ERROR; - } - return ERROR_OK; -} diff --git a/src/helper/command.h b/src/helper/command.h deleted file mode 100644 index 5c3966011..000000000 --- a/src/helper/command.h +++ /dev/null @@ -1,418 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * Copyright (C) 2007,2008 Øyvind Harboe * - * oyvind.harboe@zylin.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifndef OPENOCD_HELPER_COMMAND_H -#define OPENOCD_HELPER_COMMAND_H - -#include - -/* To achieve C99 printf compatibility in MinGW, gnu_printf should be - * used for __attribute__((format( ... ))), with GCC v4.4 or later - */ -#if (defined(IS_MINGW) && (((__GNUC__ << 16) + __GNUC_MINOR__) >= 0x00040004)) -#define PRINTF_ATTRIBUTE_FORMAT gnu_printf -#else -#define PRINTF_ATTRIBUTE_FORMAT printf -#endif - -enum command_mode { - COMMAND_EXEC, - COMMAND_CONFIG, - COMMAND_ANY, -}; - -struct command_context; - -/** The type signature for command context's output handler. */ -typedef int (*command_output_handler_t)(struct command_context *context, - const char *line); - -struct command_context { - Jim_Interp *interp; - enum command_mode mode; - struct command *commands; - int current_target; - command_output_handler_t output_handler; - void *output_handler_priv; -}; - -struct command; - -/** - * When run_command is called, a new instance will be created on the - * stack, filled with the proper values, and passed by reference to the - * required COMMAND_HANDLER routine. - */ -struct command_invocation { - struct command_context *ctx; - struct command *current; - const char *name; - unsigned argc; - const char **argv; -}; - -/** - * Command handlers may be defined with more parameters than the base - * set provided by command.c. This macro uses C99 magic to allow - * defining all such derivative types using this macro. - */ -#define __COMMAND_HANDLER(name, extra ...) \ - int name(struct command_invocation *cmd, ## extra) - -/** - * Use this to macro to call a command helper (or a nested handler). - * It provides command handler authors protection against reordering or - * removal of unused parameters. - * - * @b Note: This macro uses lexical capture to provide some arguments. - * As a result, this macro should be used @b only within functions - * defined by the COMMAND_HANDLER or COMMAND_HELPER macros. Those - * macros provide the expected lexical context captured by this macro. - * Furthermore, it should be used only from the top-level of handler or - * helper function, or care must be taken to avoid redefining the same - * variables in intervening scope(s) by accident. - */ -#define CALL_COMMAND_HANDLER(name, extra ...) \ - name(cmd, ## extra) - -/** - * Always use this macro to define new command handler functions. - * It ensures the parameters are ordered, typed, and named properly, so - * they be can be used by other macros (e.g. COMMAND_PARSE_NUMBER). - * All command handler functions must be defined as static in scope. - */ -#define COMMAND_HANDLER(name) \ - static __COMMAND_HANDLER(name) - -/** - * Similar to COMMAND_HANDLER, except some parameters are expected. - * A helper is globally-scoped because it may be shared between several - * source files (e.g. the s3c24xx device command helper). - */ -#define COMMAND_HELPER(name, extra ...) __COMMAND_HANDLER(name, extra) - -/** - * Use this macro to access the context of the command being handled, - * rather than accessing the variable directly. It may be moved. - */ -#define CMD_CTX (cmd->ctx) -/** - * Use this macro to access the number of arguments for the command being - * handled, rather than accessing the variable directly. It may be moved. - */ -#define CMD_ARGC (cmd->argc) -/** - * Use this macro to access the arguments for the command being handled, - * rather than accessing the variable directly. It may be moved. - */ -#define CMD_ARGV (cmd->argv) -/** - * Use this macro to access the name of the command being handled, - * rather than accessing the variable directly. It may be moved. - */ -#define CMD_NAME (cmd->name) -/** - * Use this macro to access the current command being handled, - * rather than accessing the variable directly. It may be moved. - */ -#define CMD_CURRENT (cmd->current) -/** - * Use this macro to access the invoked command handler's data pointer, - * rather than accessing the variable directly. It may be moved. - */ -#define CMD_DATA (CMD_CURRENT->jim_handler_data) - -/** - * The type signature for command handling functions. They are - * usually registered as part of command_registration, providing - * a high-level means for executing a command. - * - * If the command fails, it *MUST* return a value != ERROR_OK - * (many commands break this rule, patches welcome!) - * - * This is *especially* important for commands such as writing - * to flash or verifying memory. The reason is that those commands - * can be used by programs to determine if the operation succeded - * or not. If the operation failed, then a program can try - * an alternative approach. - * - * Returning ERROR_COMMAND_SYNTAX_ERROR will have the effect of - * printing out the syntax of the command. - */ -typedef __COMMAND_HANDLER((*command_handler_t)); - -struct command { - char *name; - char *help; - char *usage; - struct command *parent; - struct command *children; - command_handler_t handler; - Jim_CmdProc *jim_handler; - void *jim_handler_data; - enum command_mode mode; - struct command *next; -}; - -/** - * @param c The command to be named. - * @param delim The character to place between command names. - * @returns A malloc'd string containing the full command name, - * which may include one or more ancestor components. Multiple names - * are separated by single spaces. The caller must free() the string - * when done with it. - */ -char *command_name(struct command *c, char delim); - -/* - * Commands should be registered by filling in one or more of these - * structures and passing them to register_command(). - * - * A conventioal format should be used for help strings, to provide both - * usage and basic information: - * @code - * "@ ... - some explanation text" - * @endcode - * - * @param name The name of the command to register, which must not have - * been registered previously in the intended context. - * @param handler The callback function that will be called. If NULL, - * then the command serves as a placeholder for its children or a script. - * @param mode The command mode(s) in which this command may be run. - * @param help The help text that will be displayed to the user. - */ -struct command_registration { - const char *name; - command_handler_t handler; - Jim_CmdProc *jim_handler; - void *jim_handler_data; - enum command_mode mode; - const char *help; - /** a string listing the options and arguments, required or optional */ - const char *usage; - - /** - * If non-NULL, the commands in @c chain will be registered in - * the same context and scope of this registration record. - * This allows modules to inherit lists commands from other - * modules. - */ - const struct command_registration *chain; -}; - -/** Use this as the last entry in an array of command_registration records. */ -#define COMMAND_REGISTRATION_DONE { .name = NULL, .chain = NULL } - -/** - * Register a command @c handler that can be called from scripts during - * the execution @c mode specified. - * - * If @c parent is non-NULL, the new command will be registered as a - * sub-command under it; otherwise, it will be available as a top-level - * command. - * - * @param cmd_ctx The command_context in which to register the command. - * @param parent Register this command as a child of this, or NULL to - * register a top-level command. - * @param rec A command_registration record that contains the desired - * command parameters. - * @returns The new command, if successful; otherwise, NULL. - */ -struct command *register_command(struct command_context *cmd_ctx, - struct command *parent, const struct command_registration *rec); - -/** - * Register one or more commands in the specified context, as children - * of @c parent (or top-level commends, if NULL). In a registration's - * record contains a non-NULL @c chain member and name is NULL, the - * commands on the chain will be registered in the same context. - * Otherwise, the chained commands are added as children of the command. - * - * @param cmd_ctx The command_context in which to register the command. - * @param parent Register this command as a child of this, or NULL to - * register a top-level command. - * @param cmds Pointer to an array of command_registration records that - * contains the desired command parameters. The last record must have - * NULL for all fields. - * @returns ERROR_OK on success; ERROR_FAIL if any registration fails. - */ -int register_commands(struct command_context *cmd_ctx, struct command *parent, - const struct command_registration *cmds); - - -/** - * Unregisters command @c name from the given context, @c cmd_ctx. - * @param cmd_ctx The context of the registered command. - * @param parent The parent of the given command, or NULL. - * @param name The name of the command to unregister. - * @returns ERROR_OK on success, or an error code. - */ -int unregister_command(struct command_context *cmd_ctx, - struct command *parent, const char *name); -/** - * Unregisters all commands from the specfied context. - * @param cmd_ctx The context that will be cleared of registered commands. - * @param parent If given, only clear commands from under this one command. - * @returns ERROR_OK on success, or an error code. - */ -int unregister_all_commands(struct command_context *cmd_ctx, - struct command *parent); - -struct command *command_find_in_context(struct command_context *cmd_ctx, - const char *name); -struct command *command_find_in_parent(struct command *parent, - const char *name); - -/** - * Update the private command data field for a command and all descendents. - * This is used when creating a new heirarchy of commands that depends - * on obtaining a dynamically created context. The value will be available - * in command handlers by using the CMD_DATA macro. - * @param c The command (group) whose data pointer(s) will be updated. - * @param p The new data pointer to use for the command or its descendents. - */ -void command_set_handler_data(struct command *c, void *p); - -void command_set_output_handler(struct command_context *context, - command_output_handler_t output_handler, void *priv); - - -int command_context_mode(struct command_context *context, enum command_mode mode); - -/* Return the current command context associated with the Jim interpreter or - * alternatively the global default command interpreter - */ -struct command_context *current_command_context(Jim_Interp *interp); -/** - * Creates a new command context using the startup TCL provided and - * the existing Jim interpreter, if any. If interp == NULL, then command_init - * creates a command interpreter. - */ -struct command_context *command_init(const char *startup_tcl, Jim_Interp *interp); -/** - * Creates a copy of an existing command context. This does not create - * a deep copy of the command list, so modifications in one context will - * affect all shared contexts. The caller must track reference counting - * and ensure the commands are freed before destroying the last instance. - * @param cmd_ctx The command_context that will be copied. - * @returns A new command_context with the same state as the original. - */ -struct command_context *copy_command_context(struct command_context *cmd_ctx); -/** - * Frees the resources associated with a command context. The commands - * are not removed, so unregister_all_commands() must be called first. - * @param context The command_context that will be destroyed. - */ -void command_done(struct command_context *context); - -void command_print(struct command_context *context, const char *format, ...) -__attribute__ ((format (PRINTF_ATTRIBUTE_FORMAT, 2, 3))); -void command_print_sameline(struct command_context *context, const char *format, ...) -__attribute__ ((format (PRINTF_ATTRIBUTE_FORMAT, 2, 3))); -int command_run_line(struct command_context *context, char *line); -int command_run_linef(struct command_context *context, const char *format, ...) -__attribute__ ((format (PRINTF_ATTRIBUTE_FORMAT, 2, 3))); -void command_output_text(struct command_context *context, const char *data); - -void process_jim_events(struct command_context *cmd_ctx); - -#define ERROR_COMMAND_CLOSE_CONNECTION (-600) -#define ERROR_COMMAND_SYNTAX_ERROR (-601) -#define ERROR_COMMAND_NOTFOUND (-602) -#define ERROR_COMMAND_ARGUMENT_INVALID (-603) -#define ERROR_COMMAND_ARGUMENT_OVERFLOW (-604) -#define ERROR_COMMAND_ARGUMENT_UNDERFLOW (-605) - -int parse_ulong(const char *str, unsigned long *ul); -int parse_ullong(const char *str, unsigned long long *ul); - -int parse_long(const char *str, long *ul); -int parse_llong(const char *str, long long *ul); - -#define DECLARE_PARSE_WRAPPER(name, type) \ - int parse ## name(const char *str, type * ul) - -DECLARE_PARSE_WRAPPER(_uint, unsigned); -DECLARE_PARSE_WRAPPER(_u64, uint64_t); -DECLARE_PARSE_WRAPPER(_u32, uint32_t); -DECLARE_PARSE_WRAPPER(_u16, uint16_t); -DECLARE_PARSE_WRAPPER(_u8, uint8_t); - -DECLARE_PARSE_WRAPPER(_int, int); -DECLARE_PARSE_WRAPPER(_s32, int32_t); -DECLARE_PARSE_WRAPPER(_s16, int16_t); -DECLARE_PARSE_WRAPPER(_s8, int8_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 - * does occur, the calling function will return the error code produced - * by the parsing function (one of ERROR_COMMAND_ARGUMENT_*). - * - * This function may cause the calling function to return immediately, - * so it should be used carefully to avoid leaking resources. In most - * situations, parsing should be completed in full before proceding - * to allocate resources, and this strategy will most prevents leaks. - */ -#define COMMAND_PARSE_NUMBER(type, in, out) \ - do { \ - int retval_macro_tmp = parse_ ## type(in, &(out)); \ - if (ERROR_OK != retval_macro_tmp) { \ - command_print(CMD_CTX, stringify(out) \ - " option value ('%s') is not valid", in); \ - return retval_macro_tmp; \ - } \ - } while (0) - -/** - * 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 - * strings for true and false options (e.g. "on" and "off" or - * "enable" and "disable"). - */ -#define COMMAND_PARSE_BOOL(in, out, on, off) \ - do { \ - bool value; \ - int retval_macro_tmp = command_parse_bool_arg(in, &value); \ - if (ERROR_OK != retval_macro_tmp) { \ - command_print(CMD_CTX, stringify(out) \ - " option value ('%s') is not valid", in); \ - command_print(CMD_CTX, " choices are '%s' or '%s'", \ - on, off); \ - return retval_macro_tmp; \ - } \ - out = value; \ - } while (0) - -int command_parse_bool_arg(const char *in, bool *out); -COMMAND_HELPER(handle_command_parse_bool, bool *out, const char *label); - -/** parses an on/off command argument */ -#define COMMAND_PARSE_ON_OFF(in, out) \ - COMMAND_PARSE_BOOL(in, out, "on", "off") -/** parses an enable/disable command argument */ -#define COMMAND_PARSE_ENABLE(in, out) \ - COMMAND_PARSE_BOOL(in, out, "enable", "disable") - -void script_debug(Jim_Interp *interp, const char *cmd, - unsigned argc, Jim_Obj * const *argv); - -#endif /* OPENOCD_HELPER_COMMAND_H */ diff --git a/src/helper/configuration.c b/src/helper/configuration.c deleted file mode 100644 index 2a278838d..000000000 --- a/src/helper/configuration.c +++ /dev/null @@ -1,170 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2004, 2005 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * Copyright (C) 2007,2008 Øyvind Harboe * - * oyvind.harboe@zylin.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "configuration.h" -#include "log.h" - -static size_t num_config_files; -static char **config_file_names; - -static size_t num_script_dirs; -static char **script_search_dirs; - -void add_script_search_dir(const char *dir) -{ - num_script_dirs++; - script_search_dirs = realloc(script_search_dirs, (num_script_dirs + 1) * sizeof(char *)); - - script_search_dirs[num_script_dirs-1] = strdup(dir); - script_search_dirs[num_script_dirs] = NULL; - - LOG_DEBUG("adding %s", dir); -} - -void add_config_command(const char *cfg) -{ - num_config_files++; - config_file_names = realloc(config_file_names, (num_config_files + 1) * sizeof(char *)); - - config_file_names[num_config_files-1] = strdup(cfg); - config_file_names[num_config_files] = NULL; -} - -/* return full path or NULL according to search rules */ -char *find_file(const char *file) -{ - FILE *fp = NULL; - char **search_dirs = script_search_dirs; - char *dir; - char const *mode = "r"; - char *full_path; - - /* Check absolute and relative to current working dir first. - * This keeps full_path reporting belowing working. */ - full_path = alloc_printf("%s", file); - fp = fopen(full_path, mode); - - while (!fp) { - free(full_path); - full_path = NULL; - dir = *search_dirs++; - - if (!dir) - break; - - full_path = alloc_printf("%s/%s", dir, file); - fp = fopen(full_path, mode); - } - - if (fp) { - fclose(fp); - LOG_DEBUG("found %s", full_path); - return full_path; - } - - free(full_path); - - return NULL; -} - -FILE *open_file_from_path(const char *file, const char *mode) -{ - if (mode[0] != 'r') - return fopen(file, mode); - else { - char *full_path = find_file(file); - if (full_path == NULL) - return NULL; - FILE *fp = NULL; - fp = fopen(full_path, mode); - free(full_path); - return fp; - } -} - -int parse_config_file(struct command_context *cmd_ctx) -{ - int retval; - char **cfg; - - if (!config_file_names) { - command_run_line(cmd_ctx, "script openocd.cfg"); - return ERROR_OK; - } - - cfg = config_file_names; - - while (*cfg) { - retval = command_run_line(cmd_ctx, *cfg); - if (retval != ERROR_OK) - return retval; - cfg++; - } - - return ERROR_OK; -} - -#ifndef _WIN32 -#include -#endif - -char *get_home_dir(const char *append_path) -{ - char *home = getenv("HOME"); - - if (home == NULL) { - -#ifdef _WIN32 - home = getenv("USERPROFILE"); - - if (home == NULL) { - - char homepath[MAX_PATH]; - char *drive = getenv("HOMEDRIVE"); - char *path = getenv("HOMEPATH"); - if (drive && path) { - snprintf(homepath, MAX_PATH, "%s/%s", drive, path); - home = homepath; - } - } -#else - struct passwd *pwd = getpwuid(getuid()); - if (pwd) - home = pwd->pw_dir; - -#endif - } - - if (home == NULL) - return home; - - char *home_path; - - if (append_path) - home_path = alloc_printf("%s/%s", home, append_path); - else - home_path = alloc_printf("%s", home); - - return home_path; -} diff --git a/src/helper/configuration.h b/src/helper/configuration.h deleted file mode 100644 index 3cbcd41f6..000000000 --- a/src/helper/configuration.h +++ /dev/null @@ -1,43 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2004, 2005 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * Copyright (C) 2007,2008 Øyvind Harboe * - * oyvind.harboe@zylin.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifndef OPENOCD_HELPER_CONFIGURATION_H -#define OPENOCD_HELPER_CONFIGURATION_H - -#include - -int parse_cmdline_args(struct command_context *cmd_ctx, - int argc, char *argv[]); - -int parse_config_file(struct command_context *cmd_ctx); -void add_config_command(const char *cfg); - -void add_script_search_dir(const char *dir); - -int configuration_output_handler(struct command_context *cmd_ctx, - const char *line); - -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 /* OPENOCD_HELPER_CONFIGURATION_H */ diff --git a/src/helper/fileio.c b/src/helper/fileio.c deleted file mode 100644 index 47494dfcd..000000000 --- a/src/helper/fileio.c +++ /dev/null @@ -1,269 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * Copyright (C) 2007,2008 Øyvind Harboe * - * oyvind.harboe@zylin.com * - * * - * Copyright (C) 2008 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 -#include "config.h" -#endif - -#include "log.h" -#include "configuration.h" -#include "fileio.h" - -struct fileio { - char *url; - size_t size; - enum fileio_type type; - enum fileio_access access; - FILE *file; -}; - -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; - - switch (fileio->access) { - case FILEIO_READ: - strcpy(file_access, "r"); - break; - case FILEIO_WRITE: - strcpy(file_access, "w"); - break; - case FILEIO_READWRITE: - strcpy(file_access, "w+"); - break; - case FILEIO_APPEND: - strcpy(file_access, "a"); - break; - case FILEIO_APPENDREAD: - strcpy(file_access, "a+"); - break; - default: - LOG_ERROR("BUG: access neither read, write nor readwrite"); - return ERROR_COMMAND_SYNTAX_ERROR; - } - - /* win32 always opens in binary mode */ -#ifndef _WIN32 - if (fileio->type == FILEIO_BINARY) -#endif - strcat(file_access, "b"); - - fileio->file = open_file_from_path(fileio->url, file_access); - if (!fileio->file) { - LOG_ERROR("couldn't open %s", fileio->url); - return ERROR_FILEIO_OPERATION_FAILED; - } - - file_size = 0; - - if ((fileio->access != FILEIO_WRITE) || (fileio->access == FILEIO_READWRITE)) { - /* NB! Here we use fseek() instead of stat(), since stat is a - * more advanced operation that might not apply to e.g. a disk path - * that refers to e.g. a tftp client */ - int result, result2; - - result = fseek(fileio->file, 0, SEEK_END); - - file_size = ftell(fileio->file); - - result2 = fseek(fileio->file, 0, SEEK_SET); - - if ((file_size < 0) || (result < 0) || (result2 < 0)) { - fileio_close_local(fileio); - return ERROR_FILEIO_OPERATION_FAILED; - } - } - - fileio->size = file_size; - - return ERROR_OK; -} - -int fileio_open(struct fileio **fileio, const char *url, - enum fileio_access access_type, enum fileio_type type) -{ - int retval; - struct fileio *tmp; - - tmp = malloc(sizeof(struct fileio)); - - tmp->type = type; - tmp->access = access_type; - tmp->url = strdup(url); - - retval = fileio_open_local(tmp); - - if (retval != ERROR_OK) { - free(tmp->url); - free(tmp); - return retval; - } - - *fileio = tmp; - - return ERROR_OK; -} - -int fileio_close(struct fileio *fileio) -{ - int retval; - - retval = fileio_close_local(fileio); - - free(fileio->url); - free(fileio); - - return retval; -} - -int fileio_seek(struct fileio *fileio, size_t position) -{ - int retval; - - 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; - } - - return ERROR_OK; -} - -static int fileio_local_read(struct fileio *fileio, size_t size, void *buffer, - size_t *size_read) -{ - 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, size_t size, void *buffer, - size_t *size_read) -{ - return fileio_local_read(fileio, size, buffer, size_read); -} - -int fileio_read_u32(struct fileio *fileio, uint32_t *data) -{ - int retval; - uint8_t buf[4]; - size_t 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 *fileio, size_t size, void *buffer) -{ - if (fgets(buffer, size, fileio->file) == NULL) - return ERROR_FILEIO_OPERATION_FAILED; - - return ERROR_OK; -} - -int fileio_fgets(struct fileio *fileio, size_t size, void *buffer) -{ - return fileio_local_fgets(fileio, size, buffer); -} - -static int fileio_local_write(struct fileio *fileio, size_t size, - const void *buffer, size_t *size_written) -{ - 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, size_t size, const void *buffer, - size_t *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, uint32_t data) -{ - int retval; - uint8_t buf[4]; - h_u32_to_be(buf, data); - size_t size_written; - - retval = fileio_write(fileio, 4, buf, &size_written); - - if (ERROR_OK == retval && size_written != sizeof(uint32_t)) - retval = -EIO; - - return retval; -} - -/** - * FIX!!!! - * - * For now this can not fail, but that's because a seek was executed - * on startup. - * - * Avoiding the seek on startup opens up for using streams. - * - */ -int fileio_size(struct fileio *fileio, size_t *size) -{ - *size = fileio->size; - - return ERROR_OK; -} diff --git a/src/helper/fileio.h b/src/helper/fileio.h deleted file mode 100644 index ae4a3ecfc..000000000 --- a/src/helper/fileio.h +++ /dev/null @@ -1,69 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * Copyright (C) 2007,2008 Øyvind Harboe * - * oyvind.harboe@zylin.com * - * * - * Copyright (C) 2008 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 OPENOCD_HELPER_FILEIO_H -#define OPENOCD_HELPER_FILEIO_H - -#define FILEIO_MAX_ERROR_STRING (128) - -enum fileio_type { - FILEIO_TEXT, - FILEIO_BINARY, -}; - -enum fileio_access { - FILEIO_NONE, /* open without any access (invalid mode) */ - FILEIO_READ, /* open for reading, position at beginning */ - FILEIO_WRITE, /* open for writing, position at beginning */ - FILEIO_READWRITE, /* open for writing, position at beginning, allow reading */ - FILEIO_APPEND, /* open for writing, position at end */ - FILEIO_APPENDREAD, /* open for writing, position at end, allow reading */ -}; - -struct fileio; - -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); -int fileio_fgets(struct fileio *fileio, size_t size, void *buffer); - -int fileio_read(struct fileio *fileio, - size_t size, void *buffer, size_t *size_read); -int fileio_write(struct fileio *fileio, - size_t size, const void *buffer, size_t *size_written); - -int fileio_read_u32(struct fileio *fileio, uint32_t *data); -int fileio_write_u32(struct fileio *fileio, uint32_t data); -int fileio_size(struct fileio *fileio, size_t *size); - -#define ERROR_FILEIO_LOCATION_UNKNOWN (-1200) -#define ERROR_FILEIO_NOT_FOUND (-1201) -#define ERROR_FILEIO_OPERATION_FAILED (-1202) -#define ERROR_FILEIO_ACCESS_NOT_SUPPORTED (-1203) -#define ERROR_FILEIO_RESOURCE_TYPE_UNKNOWN (-1204) -#define ERROR_FILEIO_OPERATION_NOT_SUPPORTED (-1205) - -#endif /* OPENOCD_HELPER_FILEIO_H */ diff --git a/src/helper/ioutil.c b/src/helper/ioutil.c deleted file mode 100644 index f1123cd82..000000000 --- a/src/helper/ioutil.c +++ /dev/null @@ -1,534 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007-2010 by Øyvind Harboe * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -/* this file contains various functionality useful to standalone systems */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "log.h" -#include "time_support.h" - -#ifdef HAVE_ARPA_INET_H -#include -#endif -#ifdef HAVE_DIRENT_H -#include -#endif -#ifdef HAVE_NETDB_H -#include -#endif -#ifdef HAVE_NET_IF_H -#include -#endif -#ifdef HAVE_SYS_IOCTL_H -#include -#endif -#ifdef HAVE_SYS_STAT_H -#include -#endif -#ifdef HAVE_IFADDRS_H -#include -#endif -#ifdef HAVE_MALLOC_H -#include -#endif - -/* loads a file and returns a pointer to it in memory. The file contains - * a 0 byte(sentinel) after len bytes - the length of the file. */ -static int load_file(const char *fileName, char **data, size_t *len) -{ - /* ensure returned length is always sane */ - *len = 0; - - FILE *pFile; - pFile = fopen(fileName, "rb"); - if (pFile == NULL) { - LOG_ERROR("Can't open %s", fileName); - return ERROR_FAIL; - } - if (fseek(pFile, 0, SEEK_END) != 0) { - LOG_ERROR("Can't open %s", fileName); - fclose(pFile); - return ERROR_FAIL; - } - long fsize = ftell(pFile); - if (fsize == -1) { - LOG_ERROR("Can't open %s", fileName); - fclose(pFile); - return ERROR_FAIL; - } - *len = fsize; - - if (fseek(pFile, 0, SEEK_SET) != 0) { - LOG_ERROR("Can't open %s", fileName); - fclose(pFile); - return ERROR_FAIL; - } - *data = malloc(*len + 1); - if (*data == NULL) { - LOG_ERROR("Can't open %s", fileName); - fclose(pFile); - return ERROR_FAIL; - } - - if (fread(*data, 1, *len, pFile) != *len) { - fclose(pFile); - free(*data); - LOG_ERROR("Can't open %s", fileName); - return ERROR_FAIL; - } - fclose(pFile); - - /* 0-byte after buffer (not included in *len) serves as a sentinel */ - (*data)[*len] = 0; - - return ERROR_OK; -} - -COMMAND_HANDLER(handle_cat_command) -{ - if (CMD_ARGC != 1) - return ERROR_COMMAND_SYNTAX_ERROR; - - /* NOTE!!! we only have line printing capability so we print the entire file as a single - * line. */ - char *data; - size_t len; - - int retval = load_file(CMD_ARGV[0], &data, &len); - if (retval == ERROR_OK) { - command_print(CMD_CTX, "%s", data); - free(data); - } else - command_print(CMD_CTX, "%s not found", CMD_ARGV[0]); - - return ERROR_OK; -} - -COMMAND_HANDLER(handle_trunc_command) -{ - if (CMD_ARGC != 1) - return ERROR_COMMAND_SYNTAX_ERROR; - - FILE *config_file = NULL; - config_file = fopen(CMD_ARGV[0], "w"); - if (config_file != NULL) - fclose(config_file); - - return ERROR_OK; -} - -#ifdef HAVE_MALLOC_H -COMMAND_HANDLER(handle_meminfo_command) -{ - static int prev; - struct mallinfo info; - - if (CMD_ARGC != 0) - return ERROR_COMMAND_SYNTAX_ERROR; - - info = mallinfo(); - - if (prev > 0) - command_print(CMD_CTX, "Diff: %d", prev - info.fordblks); - prev = info.fordblks; - - command_print(CMD_CTX, "Available ram: %d", info.fordblks); - - return ERROR_OK; -} -#endif - -COMMAND_HANDLER(handle_append_command) -{ - if (CMD_ARGC < 1) - return ERROR_COMMAND_SYNTAX_ERROR; - - int retval = ERROR_FAIL; - FILE *config_file = NULL; - - config_file = fopen(CMD_ARGV[0], "a"); - if (config_file != NULL) { - fseek(config_file, 0, SEEK_END); - - unsigned i; - for (i = 1; i < CMD_ARGC; i++) { - if (fwrite(CMD_ARGV[i], 1, strlen(CMD_ARGV[i]), - config_file) != strlen(CMD_ARGV[i])) - break; - if (i != CMD_ARGC - 1) { - if (fwrite(" ", 1, 1, config_file) != 1) - break; - } - } - if ((i == CMD_ARGC) && (fwrite("\n", 1, 1, config_file) == 1)) - retval = ERROR_OK; - - fclose(config_file); - } - - return retval; -} - -COMMAND_HANDLER(handle_cp_command) -{ - if (CMD_ARGC != 2) - return ERROR_COMMAND_SYNTAX_ERROR; - - /* NOTE!!! we only have line printing capability so we print the entire file as a single - * line. */ - char *data; - size_t len; - - int retval = load_file(CMD_ARGV[0], &data, &len); - if (retval != ERROR_OK) - return retval; - - FILE *f = fopen(CMD_ARGV[1], "wb"); - if (f == NULL) - retval = ERROR_COMMAND_SYNTAX_ERROR; - - size_t pos = 0; - for (;; ) { - size_t chunk = len - pos; - static const size_t maxChunk = 512 * 1024; /* ~1/sec */ - if (chunk > maxChunk) - chunk = maxChunk; - - if ((retval == ERROR_OK) && (fwrite(data + pos, 1, chunk, f) != chunk)) - retval = ERROR_COMMAND_SYNTAX_ERROR; - - if (retval != ERROR_OK) - break; - - command_print(CMD_CTX, "%zu", len - pos); - - pos += chunk; - - if (pos == len) - break; - } - - if (retval == ERROR_OK) - command_print(CMD_CTX, "Copied %s to %s", CMD_ARGV[0], CMD_ARGV[1]); - else - command_print(CMD_CTX, "copy failed"); - - if (data != NULL) - free(data); - if (f != NULL) - fclose(f); - - if (retval != ERROR_OK) - unlink(CMD_ARGV[1]); - - return retval; -} - -COMMAND_HANDLER(handle_rm_command) -{ - if (CMD_ARGC != 1) - return ERROR_COMMAND_SYNTAX_ERROR; - - bool del = false; - if (rmdir(CMD_ARGV[0]) == 0) - del = true; - else if (unlink(CMD_ARGV[0]) == 0) - del = true; - - return del ? ERROR_OK : ERROR_FAIL; -} - -static int ioutil_Jim_Command_ls(Jim_Interp *interp, - int argc, - Jim_Obj * const *argv) -{ - if (argc != 2) { - Jim_WrongNumArgs(interp, 1, argv, "ls ?dir?"); - return JIM_ERR; - } - - const char *name = Jim_GetString(argv[1], NULL); - - DIR *dirp = NULL; - dirp = opendir(name); - if (dirp == NULL) - return JIM_ERR; - Jim_Obj *objPtr = Jim_NewListObj(interp, NULL, 0); - - for (;; ) { - struct dirent *entry = NULL; - entry = readdir(dirp); - if (entry == NULL) - break; - - if ((strcmp(".", entry->d_name) == 0) || (strcmp("..", entry->d_name) == 0)) - continue; - - Jim_ListAppendElement(interp, objPtr, - Jim_NewStringObj(interp, entry->d_name, strlen(entry->d_name))); - } - closedir(dirp); - - Jim_SetResult(interp, objPtr); - - return JIM_OK; -} - -static int ioutil_Jim_Command_peek(Jim_Interp *interp, - int argc, - Jim_Obj *const *argv) -{ - if (argc != 2) { - Jim_WrongNumArgs(interp, 1, argv, "peek ?address?"); - return JIM_ERR; - } - - long address; - if (Jim_GetLong(interp, argv[1], &address) != JIM_OK) - return JIM_ERR; - - int value = *((volatile int *) address); - - Jim_SetResult(interp, Jim_NewIntObj(interp, value)); - - return JIM_OK; -} - -static int ioutil_Jim_Command_poke(Jim_Interp *interp, - int argc, - Jim_Obj *const *argv) -{ - if (argc != 3) { - Jim_WrongNumArgs(interp, 1, argv, "poke ?address? ?value?"); - return JIM_ERR; - } - - long address; - if (Jim_GetLong(interp, argv[1], &address) != JIM_OK) - return JIM_ERR; - long value; - if (Jim_GetLong(interp, argv[2], &value) != JIM_OK) - return JIM_ERR; - - *((volatile int *) address) = value; - - return JIM_OK; -} - -/* not so pretty code to fish out ip number*/ -static int ioutil_Jim_Command_ip(Jim_Interp *interp, int argc, - Jim_Obj *const *argv) -{ -#if !defined(__CYGWIN__) - Jim_Obj *tclOutput = Jim_NewStringObj(interp, "", 0); - - struct ifaddrs *ifa = NULL, *ifp = NULL; - - if (getifaddrs(&ifp) < 0) - return JIM_ERR; - - for (ifa = ifp; ifa; ifa = ifa->ifa_next) { - char ip[200]; - socklen_t salen; - - if (ifa->ifa_addr->sa_family == AF_INET) - salen = sizeof(struct sockaddr_in); - else if (ifa->ifa_addr->sa_family == AF_INET6) - salen = sizeof(struct sockaddr_in6); - else - continue; - - if (getnameinfo(ifa->ifa_addr, salen, ip, sizeof(ip), NULL, 0, - NI_NUMERICHOST) < 0) - continue; - - Jim_AppendString(interp, tclOutput, ip, strlen(ip)); - break; - - } - - freeifaddrs(ifp); -#else - Jim_Obj *tclOutput = Jim_NewStringObj(interp, "fixme!!!", 0); - LOG_ERROR("NOT IMPLEMENTED!!!"); -#endif - Jim_SetResult(interp, tclOutput); - - return JIM_OK; -} - -#ifdef HAVE_SYS_IOCTL_H -#ifdef SIOCGIFHWADDR -/* not so pretty code to fish out eth0 mac address */ -static int ioutil_Jim_Command_mac(Jim_Interp *interp, int argc, - Jim_Obj *const *argv) -{ - struct ifreq *ifr, *ifend; - struct ifreq ifreq; - struct ifconf ifc; - struct ifreq ifs[5]; - int SockFD; - - SockFD = socket(AF_INET, SOCK_DGRAM, 0); - if (SockFD < 0) - return JIM_ERR; - - ifc.ifc_len = sizeof(ifs); - ifc.ifc_req = ifs; - if (ioctl(SockFD, SIOCGIFCONF, &ifc) < 0) { - close(SockFD); - return JIM_ERR; - } - - ifend = ifs + (ifc.ifc_len / sizeof(struct ifreq)); - for (ifr = ifc.ifc_req; ifr < ifend; ifr++) { - /* if (ifr->ifr_addr.sa_family == AF_INET) */ - { - if (strcmp("eth0", ifr->ifr_name) != 0) - continue; - strncpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name)); - if (ioctl(SockFD, SIOCGIFHWADDR, &ifreq) < 0) { - close(SockFD); - return JIM_ERR; - } - - close(SockFD); - - Jim_Obj *tclOutput = Jim_NewStringObj(interp, "", 0); - - char buffer[256]; - sprintf(buffer, "%02x-%02x-%02x-%02x-%02x-%02x", - ifreq.ifr_hwaddr.sa_data[0]&0xff, - ifreq.ifr_hwaddr.sa_data[1]&0xff, - ifreq.ifr_hwaddr.sa_data[2]&0xff, - ifreq.ifr_hwaddr.sa_data[3]&0xff, - ifreq.ifr_hwaddr.sa_data[4]&0xff, - ifreq.ifr_hwaddr.sa_data[5]&0xff); - - Jim_AppendString(interp, tclOutput, buffer, strlen(buffer)); - - Jim_SetResult(interp, tclOutput); - - return JIM_OK; - } - } - close(SockFD); - - return JIM_ERR; - -} -#endif -#endif - -static const struct command_registration ioutil_command_handlers[] = { - { - .name = "cat", - .handler = handle_cat_command, - .mode = COMMAND_ANY, - .help = "display text file content", - .usage = "file_name", - }, - { - .name = "trunc", - .handler = handle_trunc_command, - .mode = COMMAND_ANY, - .help = "truncate a file to zero length", - .usage = "file_name", - }, - { - .name = "cp", - .handler = handle_cp_command, - .mode = COMMAND_ANY, - .help = "copy a file", - .usage = "src_file_name dst_file_name", - }, - { - .name = "append_file", - .handler = handle_append_command, - .mode = COMMAND_ANY, - .help = "append a variable number of strings to a file", - .usage = "file_name [, [, ...]]", - }, -#ifdef HAVE_MALLOC_H - { - .name = "meminfo", - .handler = handle_meminfo_command, - .mode = COMMAND_ANY, - .help = "display free heap space", - }, -#endif - { - .name = "rm", - .mode = COMMAND_ANY, - .handler = handle_rm_command, - .help = "remove a directory or file", - .usage = "file_name", - }, - - /* - * Peek and poke are security holes -- they manipulate - * server-internal addresses. - */ - - /* jim handlers */ - { - .name = "peek", - .mode = COMMAND_ANY, - .jim_handler = ioutil_Jim_Command_peek, - .help = "peek at a memory address", - .usage = "address", - }, - { - .name = "poke", - .mode = COMMAND_ANY, - .jim_handler = ioutil_Jim_Command_poke, - .help = "poke at a memory address", - .usage = "address value", - }, - { - .name = "ls", - .mode = COMMAND_ANY, - .jim_handler = ioutil_Jim_Command_ls, - .help = "show a listing of files", - .usage = "dirname", - }, -#ifdef HAVE_SYS_IOCTL_H -#ifdef SIOCGIFHWADDR - { - .name = "mac", - .mode = COMMAND_ANY, - .jim_handler = ioutil_Jim_Command_mac, - .help = "show MAC address", - }, -#endif -#endif - { - .name = "ip", - .jim_handler = ioutil_Jim_Command_ip, - .mode = COMMAND_ANY, - .help = "show IP address", - }, - COMMAND_REGISTRATION_DONE -}; - -int ioutil_init(struct command_context *cmd_ctx) -{ - return register_commands(cmd_ctx, NULL, ioutil_command_handlers); -} diff --git a/src/helper/ioutil.h b/src/helper/ioutil.h deleted file mode 100644 index f060aab09..000000000 --- a/src/helper/ioutil.h +++ /dev/null @@ -1,25 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2009 Zachary T Welch * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 OPENOCD_HELPER_IOUTIL_H -#define OPENOCD_HELPER_IOUTIL_H - -struct command_context; - -int ioutil_init(struct command_context *cmd_ctx); - -#endif /* OPENOCD_HELPER_IOUTIL_H */ diff --git a/src/helper/ioutil_stubs.c b/src/helper/ioutil_stubs.c deleted file mode 100644 index 0d81fe665..000000000 --- a/src/helper/ioutil_stubs.c +++ /dev/null @@ -1,28 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2009 Zachary T Welch * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 -#include -#endif -#include "ioutil.h" -#include "log.h" - -int ioutil_init(struct command_context *cmd_ctx) -{ - LOG_DEBUG("libocdhelper was built without I/O utility support"); - return ERROR_OK; -} diff --git a/src/helper/jep106.c b/src/helper/jep106.c deleted file mode 100644 index 33dc61c91..000000000 --- a/src/helper/jep106.c +++ /dev/null @@ -1,44 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2015 Andreas Fritiofson * - * andreas.fritiofson@gmail.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "jep106.h" -#include "log.h" - -static const char * const jep106[][126] = { -#include "jep106.inc" -}; - -const char *jep106_manufacturer(unsigned bank, unsigned id) -{ - if (id < 1 || id > 126) { - LOG_DEBUG("BUG: Caller passed out-of-range JEP106 ID!"); - return ""; - } - - /* index is zero based */ - id--; - - if (bank >= ARRAY_SIZE(jep106) || jep106[bank][id] == 0) - return ""; - - return jep106[bank][id]; -} diff --git a/src/helper/jep106.h b/src/helper/jep106.h deleted file mode 100644 index 08445803e..000000000 --- a/src/helper/jep106.h +++ /dev/null @@ -1,32 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2015 Andreas Fritiofson * - * andreas.fritiofson@gmail.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifndef OPENOCD_HELPER_JEP106_H -#define OPENOCD_HELPER_JEP106_H - -/** - * Get the manufacturer name associated with a JEP106 ID. - * @param bank The bank (number of continuation codes) of the manufacturer ID. - * @param id The 7-bit manufacturer ID (i.e. with parity stripped). - * @return A pointer to static const storage containing the name of the - * manufacturer associated with bank and id, or one of the strings - * "" and "". - */ -const char *jep106_manufacturer(unsigned bank, unsigned id); - -#endif /* OPENOCD_HELPER_JEP106_H */ diff --git a/src/helper/jep106.inc b/src/helper/jep106.inc deleted file mode 100644 index 1895005ee..000000000 --- a/src/helper/jep106.inc +++ /dev/null @@ -1,1119 +0,0 @@ -/* Autogenerated with update_jep106.pl*/ -[0][0x01 - 1] = "AMD", -[0][0x02 - 1] = "AMI", -[0][0x03 - 1] = "Fairchild", -[0][0x04 - 1] = "Fujitsu", -[0][0x05 - 1] = "GTE", -[0][0x06 - 1] = "Harris", -[0][0x07 - 1] = "Hitachi", -[0][0x08 - 1] = "Inmos", -[0][0x09 - 1] = "Intel", -[0][0x0a - 1] = "I.T.T.", -[0][0x0b - 1] = "Intersil", -[0][0x0c - 1] = "Monolithic Memories", -[0][0x0d - 1] = "Mostek", -[0][0x0e - 1] = "Freescale (Motorola)", -[0][0x0f - 1] = "National", -[0][0x10 - 1] = "NEC", -[0][0x11 - 1] = "RCA", -[0][0x12 - 1] = "Raytheon", -[0][0x13 - 1] = "Conexant (Rockwell)", -[0][0x14 - 1] = "Seeq", -[0][0x15 - 1] = "NXP (Philips)", -[0][0x16 - 1] = "Synertek", -[0][0x17 - 1] = "Texas Instruments", -[0][0x18 - 1] = "Toshiba", -[0][0x19 - 1] = "Xicor", -[0][0x1a - 1] = "Zilog", -[0][0x1b - 1] = "Eurotechnique", -[0][0x1c - 1] = "Mitsubishi", -[0][0x1d - 1] = "Lucent (AT&T)", -[0][0x1e - 1] = "Exel", -[0][0x1f - 1] = "Atmel", -[0][0x20 - 1] = "STMicroelectronics", -[0][0x21 - 1] = "Lattice Semi.", -[0][0x22 - 1] = "NCR", -[0][0x23 - 1] = "Wafer Scale Integration", -[0][0x24 - 1] = "IBM", -[0][0x25 - 1] = "Tristar", -[0][0x26 - 1] = "Visic", -[0][0x27 - 1] = "Intl. CMOS Technology", -[0][0x28 - 1] = "SSSI", -[0][0x29 - 1] = "MicrochipTechnology", -[0][0x2a - 1] = "Ricoh Ltd.", -[0][0x2b - 1] = "VLSI", -[0][0x2c - 1] = "Micron Technology", -[0][0x2d - 1] = "SK Hynix", -[0][0x2e - 1] = "OKI Semiconductor", -[0][0x2f - 1] = "ACTEL", -[0][0x30 - 1] = "Sharp", -[0][0x31 - 1] = "Catalyst", -[0][0x32 - 1] = "Panasonic", -[0][0x33 - 1] = "IDT", -[0][0x34 - 1] = "Cypress", -[0][0x35 - 1] = "DEC", -[0][0x36 - 1] = "LSI Logic", -[0][0x37 - 1] = "Zarlink (Plessey)", -[0][0x38 - 1] = "UTMC", -[0][0x39 - 1] = "Thinking Machine", -[0][0x3a - 1] = "Thomson CSF", -[0][0x3b - 1] = "Integrated CMOS (Vertex)", -[0][0x3c - 1] = "Honeywell", -[0][0x3d - 1] = "Tektronix", -[0][0x3e - 1] = "Oracle Corporation", -[0][0x3f - 1] = "Silicon Storage Technology", -[0][0x40 - 1] = "ProMos/Mosel Vitelic", -[0][0x41 - 1] = "Infineon (Siemens)", -[0][0x42 - 1] = "Macronix", -[0][0x43 - 1] = "Xerox", -[0][0x44 - 1] = "Plus Logic", -[0][0x45 - 1] = "SanDisk Corporation", -[0][0x46 - 1] = "Elan Circuit Tech.", -[0][0x47 - 1] = "European Silicon Str.", -[0][0x48 - 1] = "Apple Computer", -[0][0x49 - 1] = "Xilinx", -[0][0x4a - 1] = "Compaq", -[0][0x4b - 1] = "Protocol Engines", -[0][0x4c - 1] = "SCI", -[0][0x4d - 1] = "Seiko Instruments", -[0][0x4e - 1] = "Samsung", -[0][0x4f - 1] = "I3 Design System", -[0][0x50 - 1] = "Klic", -[0][0x51 - 1] = "Crosspoint Solutions", -[0][0x52 - 1] = "Alliance Semiconductor", -[0][0x53 - 1] = "Tandem", -[0][0x54 - 1] = "Hewlett-Packard", -[0][0x55 - 1] = "Integrated Silicon Solutions", -[0][0x56 - 1] = "Brooktree", -[0][0x57 - 1] = "New Media", -[0][0x58 - 1] = "MHS Electronic", -[0][0x59 - 1] = "Performance Semi.", -[0][0x5a - 1] = "Winbond Electronic", -[0][0x5b - 1] = "Kawasaki Steel", -[0][0x5c - 1] = "Bright Micro", -[0][0x5d - 1] = "TECMAR", -[0][0x5e - 1] = "Exar", -[0][0x5f - 1] = "PCMCIA", -[0][0x60 - 1] = "LG Semi (Goldstar)", -[0][0x61 - 1] = "Northern Telecom", -[0][0x62 - 1] = "Sanyo", -[0][0x63 - 1] = "Array Microsystems", -[0][0x64 - 1] = "Crystal Semiconductor", -[0][0x65 - 1] = "Analog Devices", -[0][0x66 - 1] = "PMC-Sierra", -[0][0x67 - 1] = "Asparix", -[0][0x68 - 1] = "Convex Computer", -[0][0x69 - 1] = "Quality Semiconductor", -[0][0x6a - 1] = "Nimbus Technology", -[0][0x6b - 1] = "Transwitch", -[0][0x6c - 1] = "Micronas (ITT Intermetall)", -[0][0x6d - 1] = "Cannon", -[0][0x6e - 1] = "Altera", -[0][0x6f - 1] = "NEXCOM", -[0][0x70 - 1] = "Qualcomm", -[0][0x71 - 1] = "Sony", -[0][0x72 - 1] = "Cray Research", -[0][0x73 - 1] = "AMS(Austria Micro)", -[0][0x74 - 1] = "Vitesse", -[0][0x75 - 1] = "Aster Electronics", -[0][0x76 - 1] = "Bay Networks (Synoptic)", -[0][0x77 - 1] = "Zentrum/ZMD", -[0][0x78 - 1] = "TRW", -[0][0x79 - 1] = "Thesys", -[0][0x7a - 1] = "Solbourne Computer", -[0][0x7b - 1] = "Allied-Signal", -[0][0x7c - 1] = "Dialog Semiconductor", -[0][0x7d - 1] = "Media Vision", -[0][0x7e - 1] = "Numonyx Corporation", -[1][0x01 - 1] = "Cirrus Logic", -[1][0x02 - 1] = "National Instruments", -[1][0x03 - 1] = "ILC Data Device", -[1][0x04 - 1] = "Alcatel Mietec", -[1][0x05 - 1] = "Micro Linear", -[1][0x06 - 1] = "Univ. of NC", -[1][0x07 - 1] = "JTAG Technologies", -[1][0x08 - 1] = "BAE Systems (Loral)", -[1][0x09 - 1] = "Nchip", -[1][0x0a - 1] = "Galileo Tech", -[1][0x0b - 1] = "Bestlink Systems", -[1][0x0c - 1] = "Graychip", -[1][0x0d - 1] = "GENNUM", -[1][0x0e - 1] = "VideoLogic", -[1][0x0f - 1] = "Robert Bosch", -[1][0x10 - 1] = "Chip Express", -[1][0x11 - 1] = "DATARAM", -[1][0x12 - 1] = "United Microelectronics Corp.", -[1][0x13 - 1] = "TCSI", -[1][0x14 - 1] = "Smart Modular", -[1][0x15 - 1] = "Hughes Aircraft", -[1][0x16 - 1] = "Lanstar Semiconductor", -[1][0x17 - 1] = "Qlogic", -[1][0x18 - 1] = "Kingston", -[1][0x19 - 1] = "Music Semi", -[1][0x1a - 1] = "Ericsson Components", -[1][0x1b - 1] = "SpaSE", -[1][0x1c - 1] = "Eon Silicon Devices", -[1][0x1d - 1] = "Integrated Silicon Solution (ISSI)", -[1][0x1e - 1] = "DoD", -[1][0x1f - 1] = "Integ. Memories Tech.", -[1][0x20 - 1] = "Corollary Inc.", -[1][0x21 - 1] = "Dallas Semiconductor", -[1][0x22 - 1] = "Omnivision", -[1][0x23 - 1] = "EIV(Switzerland)", -[1][0x24 - 1] = "Novatel Wireless", -[1][0x25 - 1] = "Zarlink (Mitel)", -[1][0x26 - 1] = "Clearpoint", -[1][0x27 - 1] = "Cabletron", -[1][0x28 - 1] = "STEC (Silicon Tech)", -[1][0x29 - 1] = "Vanguard", -[1][0x2a - 1] = "Hagiwara Sys-Com", -[1][0x2b - 1] = "Vantis", -[1][0x2c - 1] = "Celestica", -[1][0x2d - 1] = "Century", -[1][0x2e - 1] = "Hal Computers", -[1][0x2f - 1] = "Rohm Company Ltd.", -[1][0x30 - 1] = "Juniper Networks", -[1][0x31 - 1] = "Libit Signal Processing", -[1][0x32 - 1] = "Mushkin Enhanced Memory", -[1][0x33 - 1] = "Tundra Semiconductor", -[1][0x34 - 1] = "Adaptec Inc.", -[1][0x35 - 1] = "LightSpeed Semi.", -[1][0x36 - 1] = "ZSP Corp.", -[1][0x37 - 1] = "AMIC Technology", -[1][0x38 - 1] = "Adobe Systems", -[1][0x39 - 1] = "Dynachip", -[1][0x3a - 1] = "PNY Technologies, Inc.", -[1][0x3b - 1] = "Newport Digital", -[1][0x3c - 1] = "MMC Networks", -[1][0x3d - 1] = "T Square", -[1][0x3e - 1] = "Seiko Epson", -[1][0x3f - 1] = "Broadcom", -[1][0x40 - 1] = "Viking Components", -[1][0x41 - 1] = "V3 Semiconductor", -[1][0x42 - 1] = "Flextronics (Orbit Semiconductor)", -[1][0x43 - 1] = "Suwa Electronics", -[1][0x44 - 1] = "Transmeta", -[1][0x45 - 1] = "Micron CMS", -[1][0x46 - 1] = "American Computer & Digital", -[1][0x47 - 1] = "Enhance 3000 Inc.", -[1][0x48 - 1] = "Tower Semiconductor", -[1][0x49 - 1] = "CPU Design", -[1][0x4a - 1] = "Price Point", -[1][0x4b - 1] = "Maxim Integrated Product", -[1][0x4c - 1] = "Tellabs", -[1][0x4d - 1] = "Centaur Technology", -[1][0x4e - 1] = "Unigen Corporation", -[1][0x4f - 1] = "Transcend Information", -[1][0x50 - 1] = "Memory Card Technology", -[1][0x51 - 1] = "CKD Corporation Ltd.", -[1][0x52 - 1] = "Capital Instruments, Inc.", -[1][0x53 - 1] = "Aica Kogyo, Ltd.", -[1][0x54 - 1] = "Linvex Technology", -[1][0x55 - 1] = "MSC Vertriebs GmbH", -[1][0x56 - 1] = "AKM Company, Ltd.", -[1][0x57 - 1] = "Dynamem, Inc.", -[1][0x58 - 1] = "NERA ASA", -[1][0x59 - 1] = "GSI Technology", -[1][0x5a - 1] = "Dane-Elec (C Memory)", -[1][0x5b - 1] = "Acorn Computers", -[1][0x5c - 1] = "Lara Technology", -[1][0x5d - 1] = "Oak Technology, Inc.", -[1][0x5e - 1] = "Itec Memory", -[1][0x5f - 1] = "Tanisys Technology", -[1][0x60 - 1] = "Truevision", -[1][0x61 - 1] = "Wintec Industries", -[1][0x62 - 1] = "Super PC Memory", -[1][0x63 - 1] = "MGV Memory", -[1][0x64 - 1] = "Galvantech", -[1][0x65 - 1] = "Gadzoox Networks", -[1][0x66 - 1] = "Multi Dimensional Cons.", -[1][0x67 - 1] = "GateField", -[1][0x68 - 1] = "Integrated Memory System", -[1][0x69 - 1] = "Triscend", -[1][0x6a - 1] = "XaQti", -[1][0x6b - 1] = "Goldenram", -[1][0x6c - 1] = "Clear Logic", -[1][0x6d - 1] = "Cimaron Communications", -[1][0x6e - 1] = "Nippon Steel Semi. Corp.", -[1][0x6f - 1] = "Advantage Memory", -[1][0x70 - 1] = "AMCC", -[1][0x71 - 1] = "LeCroy", -[1][0x72 - 1] = "Yamaha Corporation", -[1][0x73 - 1] = "Digital Microwave", -[1][0x74 - 1] = "NetLogic Microsystems", -[1][0x75 - 1] = "MIMOS Semiconductor", -[1][0x76 - 1] = "Advanced Fibre", -[1][0x77 - 1] = "BF Goodrich Data.", -[1][0x78 - 1] = "Epigram", -[1][0x79 - 1] = "Acbel Polytech Inc.", -[1][0x7a - 1] = "Apacer Technology", -[1][0x7b - 1] = "Admor Memory", -[1][0x7c - 1] = "FOXCONN", -[1][0x7d - 1] = "Quadratics Superconductor", -[1][0x7e - 1] = "3COM", -[2][0x01 - 1] = "Camintonn Corporation", -[2][0x02 - 1] = "ISOA Incorporated", -[2][0x03 - 1] = "Agate Semiconductor", -[2][0x04 - 1] = "ADMtek Incorporated", -[2][0x05 - 1] = "HYPERTEC", -[2][0x06 - 1] = "Adhoc Technologies", -[2][0x07 - 1] = "MOSAID Technologies", -[2][0x08 - 1] = "Ardent Technologies", -[2][0x09 - 1] = "Switchcore", -[2][0x0a - 1] = "Cisco Systems, Inc.", -[2][0x0b - 1] = "Allayer Technologies", -[2][0x0c - 1] = "WorkX AG (Wichman)", -[2][0x0d - 1] = "Oasis Semiconductor", -[2][0x0e - 1] = "Novanet Semiconductor", -[2][0x0f - 1] = "E-M Solutions", -[2][0x10 - 1] = "Power General", -[2][0x11 - 1] = "Advanced Hardware Arch.", -[2][0x12 - 1] = "Inova Semiconductors GmbH", -[2][0x13 - 1] = "Telocity", -[2][0x14 - 1] = "Delkin Devices", -[2][0x15 - 1] = "Symagery Microsystems", -[2][0x16 - 1] = "C-Port Corporation", -[2][0x17 - 1] = "SiberCore Technologies", -[2][0x18 - 1] = "Southland Microsystems", -[2][0x19 - 1] = "Malleable Technologies", -[2][0x1a - 1] = "Kendin Communications", -[2][0x1b - 1] = "Great Technology Microcomputer", -[2][0x1c - 1] = "Sanmina Corporation", -[2][0x1d - 1] = "HADCO Corporation", -[2][0x1e - 1] = "Corsair", -[2][0x1f - 1] = "Actrans System Inc.", -[2][0x20 - 1] = "ALPHA Technologies", -[2][0x21 - 1] = "Silicon Laboratories, Inc. (Cygnal)", -[2][0x22 - 1] = "Artesyn Technologies", -[2][0x23 - 1] = "Align Manufacturing", -[2][0x24 - 1] = "Peregrine Semiconductor", -[2][0x25 - 1] = "Chameleon Systems", -[2][0x26 - 1] = "Aplus Flash Technology", -[2][0x27 - 1] = "MIPS Technologies", -[2][0x28 - 1] = "Chrysalis ITS", -[2][0x29 - 1] = "ADTEC Corporation", -[2][0x2a - 1] = "Kentron Technologies", -[2][0x2b - 1] = "Win Technologies", -[2][0x2c - 1] = "Tezzaron Semiconductor", -[2][0x2d - 1] = "Extreme Packet Devices", -[2][0x2e - 1] = "RF Micro Devices", -[2][0x2f - 1] = "Siemens AG", -[2][0x30 - 1] = "Sarnoff Corporation", -[2][0x31 - 1] = "Itautec SA", -[2][0x32 - 1] = "Radiata Inc.", -[2][0x33 - 1] = "Benchmark Elect. (AVEX)", -[2][0x34 - 1] = "Legend", -[2][0x35 - 1] = "SpecTek Incorporated", -[2][0x36 - 1] = "Hi/fn", -[2][0x37 - 1] = "Enikia Incorporated", -[2][0x38 - 1] = "SwitchOn Networks", -[2][0x39 - 1] = "AANetcom Incorporated", -[2][0x3a - 1] = "Micro Memory Bank", -[2][0x3b - 1] = "ESS Technology", -[2][0x3c - 1] = "Virata Corporation", -[2][0x3d - 1] = "Excess Bandwidth", -[2][0x3e - 1] = "West Bay Semiconductor", -[2][0x3f - 1] = "DSP Group", -[2][0x40 - 1] = "Newport Communications", -[2][0x41 - 1] = "Chip2Chip Incorporated", -[2][0x42 - 1] = "Phobos Corporation", -[2][0x43 - 1] = "Intellitech Corporation", -[2][0x44 - 1] = "Nordic VLSI ASA", -[2][0x45 - 1] = "Ishoni Networks", -[2][0x46 - 1] = "Silicon Spice", -[2][0x47 - 1] = "Alchemy Semiconductor", -[2][0x48 - 1] = "Agilent Technologies", -[2][0x49 - 1] = "Centillium Communications", -[2][0x4a - 1] = "W.L. Gore", -[2][0x4b - 1] = "HanBit Electronics", -[2][0x4c - 1] = "GlobeSpan", -[2][0x4d - 1] = "Element 14", -[2][0x4e - 1] = "Pycon", -[2][0x4f - 1] = "Saifun Semiconductors", -[2][0x50 - 1] = "Sibyte, Incorporated", -[2][0x51 - 1] = "MetaLink Technologies", -[2][0x52 - 1] = "Feiya Technology", -[2][0x53 - 1] = "I & C Technology", -[2][0x54 - 1] = "Shikatronics", -[2][0x55 - 1] = "Elektrobit", -[2][0x56 - 1] = "Megic", -[2][0x57 - 1] = "Com-Tier", -[2][0x58 - 1] = "Malaysia Micro Solutions", -[2][0x59 - 1] = "Hyperchip", -[2][0x5a - 1] = "Gemstone Communications", -[2][0x5b - 1] = "Anadigm (Anadyne)", -[2][0x5c - 1] = "3ParData", -[2][0x5d - 1] = "Mellanox Technologies", -[2][0x5e - 1] = "Tenx Technologies", -[2][0x5f - 1] = "Helix AG", -[2][0x60 - 1] = "Domosys", -[2][0x61 - 1] = "Skyup Technology", -[2][0x62 - 1] = "HiNT Corporation", -[2][0x63 - 1] = "Chiaro", -[2][0x64 - 1] = "MDT Technologies GmbH", -[2][0x65 - 1] = "Exbit Technology A/S", -[2][0x66 - 1] = "Integrated Technology Express", -[2][0x67 - 1] = "AVED Memory", -[2][0x68 - 1] = "Legerity", -[2][0x69 - 1] = "Jasmine Networks", -[2][0x6a - 1] = "Caspian Networks", -[2][0x6b - 1] = "nCUBE", -[2][0x6c - 1] = "Silicon Access Networks", -[2][0x6d - 1] = "FDK Corporation", -[2][0x6e - 1] = "High Bandwidth Access", -[2][0x6f - 1] = "MultiLink Technology", -[2][0x70 - 1] = "BRECIS", -[2][0x71 - 1] = "World Wide Packets", -[2][0x72 - 1] = "APW", -[2][0x73 - 1] = "Chicory Systems", -[2][0x74 - 1] = "Xstream Logic", -[2][0x75 - 1] = "Fast-Chip", -[2][0x76 - 1] = "Zucotto Wireless", -[2][0x77 - 1] = "Realchip", -[2][0x78 - 1] = "Galaxy Power", -[2][0x79 - 1] = "eSilicon", -[2][0x7a - 1] = "Morphics Technology", -[2][0x7b - 1] = "Accelerant Networks", -[2][0x7c - 1] = "Silicon Wave", -[2][0x7d - 1] = "SandCraft", -[2][0x7e - 1] = "Elpida", -[3][0x01 - 1] = "Solectron", -[3][0x02 - 1] = "Optosys Technologies", -[3][0x03 - 1] = "Buffalo (Formerly Melco)", -[3][0x04 - 1] = "TriMedia Technologies", -[3][0x05 - 1] = "Cyan Technologies", -[3][0x06 - 1] = "Global Locate", -[3][0x07 - 1] = "Optillion", -[3][0x08 - 1] = "Terago Communications", -[3][0x09 - 1] = "Ikanos Communications", -[3][0x0a - 1] = "Princeton Technology", -[3][0x0b - 1] = "Nanya Technology", -[3][0x0c - 1] = "Elite Flash Storage", -[3][0x0d - 1] = "Mysticom", -[3][0x0e - 1] = "LightSand Communications", -[3][0x0f - 1] = "ATI Technologies", -[3][0x10 - 1] = "Agere Systems", -[3][0x11 - 1] = "NeoMagic", -[3][0x12 - 1] = "AuroraNetics", -[3][0x13 - 1] = "Golden Empire", -[3][0x14 - 1] = "Mushkin", -[3][0x15 - 1] = "Tioga Technologies", -[3][0x16 - 1] = "Netlist", -[3][0x17 - 1] = "TeraLogic", -[3][0x18 - 1] = "Cicada Semiconductor", -[3][0x19 - 1] = "Centon Electronics", -[3][0x1a - 1] = "Tyco Electronics", -[3][0x1b - 1] = "Magis Works", -[3][0x1c - 1] = "Zettacom", -[3][0x1d - 1] = "Cogency Semiconductor", -[3][0x1e - 1] = "Chipcon AS", -[3][0x1f - 1] = "Aspex Technology", -[3][0x20 - 1] = "F5 Networks", -[3][0x21 - 1] = "Programmable Silicon Solutions", -[3][0x22 - 1] = "ChipWrights", -[3][0x23 - 1] = "Acorn Networks", -[3][0x24 - 1] = "Quicklogic", -[3][0x25 - 1] = "Kingmax Semiconductor", -[3][0x26 - 1] = "BOPS", -[3][0x27 - 1] = "Flasys", -[3][0x28 - 1] = "BitBlitz Communications", -[3][0x29 - 1] = "eMemory Technology", -[3][0x2a - 1] = "Procket Networks", -[3][0x2b - 1] = "Purple Ray", -[3][0x2c - 1] = "Trebia Networks", -[3][0x2d - 1] = "Delta Electronics", -[3][0x2e - 1] = "Onex Communications", -[3][0x2f - 1] = "Ample Communications", -[3][0x30 - 1] = "Memory Experts Intl", -[3][0x31 - 1] = "Astute Networks", -[3][0x32 - 1] = "Azanda Network Devices", -[3][0x33 - 1] = "Dibcom", -[3][0x34 - 1] = "Tekmos", -[3][0x35 - 1] = "API NetWorks", -[3][0x36 - 1] = "Bay Microsystems", -[3][0x37 - 1] = "Firecron Ltd", -[3][0x38 - 1] = "Resonext Communications", -[3][0x39 - 1] = "Tachys Technologies", -[3][0x3a - 1] = "Equator Technology", -[3][0x3b - 1] = "Concept Computer", -[3][0x3c - 1] = "SILCOM", -[3][0x3d - 1] = "3Dlabs", -[3][0x3e - 1] = "c’t Magazine", -[3][0x3f - 1] = "Sanera Systems", -[3][0x40 - 1] = "Silicon Packets", -[3][0x41 - 1] = "Viasystems Group", -[3][0x42 - 1] = "Simtek", -[3][0x43 - 1] = "Semicon Devices Singapore", -[3][0x44 - 1] = "Satron Handelsges", -[3][0x45 - 1] = "Improv Systems", -[3][0x46 - 1] = "INDUSYS GmbH", -[3][0x47 - 1] = "Corrent", -[3][0x48 - 1] = "Infrant Technologies", -[3][0x49 - 1] = "Ritek Corp", -[3][0x4a - 1] = "empowerTel Networks", -[3][0x4b - 1] = "Hypertec", -[3][0x4c - 1] = "Cavium Networks", -[3][0x4d - 1] = "PLX Technology", -[3][0x4e - 1] = "Massana Design", -[3][0x4f - 1] = "Intrinsity", -[3][0x50 - 1] = "Valence Semiconductor", -[3][0x51 - 1] = "Terawave Communications", -[3][0x52 - 1] = "IceFyre Semiconductor", -[3][0x53 - 1] = "Primarion", -[3][0x54 - 1] = "Picochip Designs Ltd", -[3][0x55 - 1] = "Silverback Systems", -[3][0x56 - 1] = "Jade Star Technologies", -[3][0x57 - 1] = "Pijnenburg Securealink", -[3][0x58 - 1] = "takeMS - Ultron AG", -[3][0x59 - 1] = "Cambridge Silicon Radio", -[3][0x5a - 1] = "Swissbit", -[3][0x5b - 1] = "Nazomi Communications", -[3][0x5c - 1] = "eWave System", -[3][0x5d - 1] = "Rockwell Collins", -[3][0x5e - 1] = "Picocel Co. Ltd. (Paion)", -[3][0x5f - 1] = "Alphamosaic Ltd", -[3][0x60 - 1] = "Sandburst", -[3][0x61 - 1] = "SiCon Video", -[3][0x62 - 1] = "NanoAmp Solutions", -[3][0x63 - 1] = "Ericsson Technology", -[3][0x64 - 1] = "PrairieComm", -[3][0x65 - 1] = "Mitac International", -[3][0x66 - 1] = "Layer N Networks", -[3][0x67 - 1] = "MtekVision (Atsana)", -[3][0x68 - 1] = "Allegro Networks", -[3][0x69 - 1] = "Marvell Semiconductors", -[3][0x6a - 1] = "Netergy Microelectronic", -[3][0x6b - 1] = "NVIDIA", -[3][0x6c - 1] = "Internet Machines", -[3][0x6d - 1] = "Memorysolution GmbH", -[3][0x6e - 1] = "Litchfield Communication", -[3][0x6f - 1] = "Accton Technology", -[3][0x70 - 1] = "Teradiant Networks", -[3][0x71 - 1] = "Scaleo Chip", -[3][0x72 - 1] = "Cortina Systems", -[3][0x73 - 1] = "RAM Components", -[3][0x74 - 1] = "Raqia Networks", -[3][0x75 - 1] = "ClearSpeed", -[3][0x76 - 1] = "Matsushita Battery", -[3][0x77 - 1] = "Xelerated", -[3][0x78 - 1] = "SimpleTech", -[3][0x79 - 1] = "Utron Technology", -[3][0x7a - 1] = "Astec International", -[3][0x7b - 1] = "AVM gmbH", -[3][0x7c - 1] = "Redux Communications", -[3][0x7d - 1] = "Dot Hill Systems", -[3][0x7e - 1] = "TeraChip", -[4][0x01 - 1] = "T-RAM Incorporated", -[4][0x02 - 1] = "Innovics Wireless", -[4][0x03 - 1] = "Teknovus", -[4][0x04 - 1] = "KeyEye Communications", -[4][0x05 - 1] = "Runcom Technologies", -[4][0x06 - 1] = "RedSwitch", -[4][0x07 - 1] = "Dotcast", -[4][0x08 - 1] = "Silicon Mountain Memory", -[4][0x09 - 1] = "Signia Technologies", -[4][0x0a - 1] = "Pixim", -[4][0x0b - 1] = "Galazar Networks", -[4][0x0c - 1] = "White Electronic Designs", -[4][0x0d - 1] = "Patriot Scientific", -[4][0x0e - 1] = "Neoaxiom Corporation", -[4][0x0f - 1] = "3Y Power Technology", -[4][0x10 - 1] = "Scaleo Chip", -[4][0x11 - 1] = "Potentia Power Systems", -[4][0x12 - 1] = "C-guys Incorporated", -[4][0x13 - 1] = "Digital Communications Technology", -[4][0x14 - 1] = "Silicon-Based Technology", -[4][0x15 - 1] = "Fulcrum Microsystems", -[4][0x16 - 1] = "Positivo Informatica Ltd", -[4][0x17 - 1] = "XIOtech Corporation", -[4][0x18 - 1] = "PortalPlayer", -[4][0x19 - 1] = "Zhiying Software", -[4][0x1a - 1] = "ParkerVision, Inc.", -[4][0x1b - 1] = "Phonex Broadband", -[4][0x1c - 1] = "Skyworks Solutions", -[4][0x1d - 1] = "Entropic Communications", -[4][0x1e - 1] = "I’M Intelligent Memory Ltd.", -[4][0x1f - 1] = "Zensys A/S", -[4][0x20 - 1] = "Legend Silicon Corp.", -[4][0x21 - 1] = "Sci-worx GmbH", -[4][0x22 - 1] = "SMSC (Standard Microsystems)", -[4][0x23 - 1] = "Renesas Electronics", -[4][0x24 - 1] = "Raza Microelectronics", -[4][0x25 - 1] = "Phyworks", -[4][0x26 - 1] = "MediaTek", -[4][0x27 - 1] = "Non-cents Productions", -[4][0x28 - 1] = "US Modular", -[4][0x29 - 1] = "Wintegra Ltd.", -[4][0x2a - 1] = "Mathstar", -[4][0x2b - 1] = "StarCore", -[4][0x2c - 1] = "Oplus Technologies", -[4][0x2d - 1] = "Mindspeed", -[4][0x2e - 1] = "Just Young Computer", -[4][0x2f - 1] = "Radia Communications", -[4][0x30 - 1] = "OCZ", -[4][0x31 - 1] = "Emuzed", -[4][0x32 - 1] = "LOGIC Devices", -[4][0x33 - 1] = "Inphi Corporation", -[4][0x34 - 1] = "Quake Technologies", -[4][0x35 - 1] = "Vixel", -[4][0x36 - 1] = "SolusTek", -[4][0x37 - 1] = "Kongsberg Maritime", -[4][0x38 - 1] = "Faraday Technology", -[4][0x39 - 1] = "Altium Ltd.", -[4][0x3a - 1] = "Insyte", -[4][0x3b - 1] = "ARM Ltd.", -[4][0x3c - 1] = "DigiVision", -[4][0x3d - 1] = "Vativ Technologies", -[4][0x3e - 1] = "Endicott Interconnect Technologies", -[4][0x3f - 1] = "Pericom", -[4][0x40 - 1] = "Bandspeed", -[4][0x41 - 1] = "LeWiz Communications", -[4][0x42 - 1] = "CPU Technology", -[4][0x43 - 1] = "Ramaxel Technology", -[4][0x44 - 1] = "DSP Group", -[4][0x45 - 1] = "Axis Communications", -[4][0x46 - 1] = "Legacy Electronics", -[4][0x47 - 1] = "Chrontel", -[4][0x48 - 1] = "Powerchip Semiconductor", -[4][0x49 - 1] = "MobilEye Technologies", -[4][0x4a - 1] = "Excel Semiconductor", -[4][0x4b - 1] = "A-DATA Technology", -[4][0x4c - 1] = "VirtualDigm", -[4][0x4d - 1] = "G Skill Intl", -[4][0x4e - 1] = "Quanta Computer", -[4][0x4f - 1] = "Yield Microelectronics", -[4][0x50 - 1] = "Afa Technologies", -[4][0x51 - 1] = "KINGBOX Technology Co. Ltd.", -[4][0x52 - 1] = "Ceva", -[4][0x53 - 1] = "iStor Networks", -[4][0x54 - 1] = "Advance Modules", -[4][0x55 - 1] = "Microsoft", -[4][0x56 - 1] = "Open-Silicon", -[4][0x57 - 1] = "Goal Semiconductor", -[4][0x58 - 1] = "ARC International", -[4][0x59 - 1] = "Simmtec", -[4][0x5a - 1] = "Metanoia", -[4][0x5b - 1] = "Key Stream", -[4][0x5c - 1] = "Lowrance Electronics", -[4][0x5d - 1] = "Adimos", -[4][0x5e - 1] = "SiGe Semiconductor", -[4][0x5f - 1] = "Fodus Communications", -[4][0x60 - 1] = "Credence Systems Corp.", -[4][0x61 - 1] = "Genesis Microchip Inc.", -[4][0x62 - 1] = "Vihana, Inc.", -[4][0x63 - 1] = "WIS Technologies", -[4][0x64 - 1] = "GateChange Technologies", -[4][0x65 - 1] = "High Density Devices AS", -[4][0x66 - 1] = "Synopsys", -[4][0x67 - 1] = "Gigaram", -[4][0x68 - 1] = "Enigma Semiconductor Inc.", -[4][0x69 - 1] = "Century Micro Inc.", -[4][0x6a - 1] = "Icera Semiconductor", -[4][0x6b - 1] = "Mediaworks Integrated Systems", -[4][0x6c - 1] = "O’Neil Product Development", -[4][0x6d - 1] = "Supreme Top Technology Ltd.", -[4][0x6e - 1] = "MicroDisplay Corporation", -[4][0x6f - 1] = "Team Group Inc.", -[4][0x70 - 1] = "Sinett Corporation", -[4][0x71 - 1] = "Toshiba Corporation", -[4][0x72 - 1] = "Tensilica", -[4][0x73 - 1] = "SiRF Technology", -[4][0x74 - 1] = "Bacoc Inc.", -[4][0x75 - 1] = "SMaL Camera Technologies", -[4][0x76 - 1] = "Thomson SC", -[4][0x77 - 1] = "Airgo Networks", -[4][0x78 - 1] = "Wisair Ltd.", -[4][0x79 - 1] = "SigmaTel", -[4][0x7a - 1] = "Arkados", -[4][0x7b - 1] = "Compete IT gmbH Co. KG", -[4][0x7c - 1] = "Eudar Technology Inc.", -[4][0x7d - 1] = "Focus Enhancements", -[4][0x7e - 1] = "Xyratex", -[5][0x01 - 1] = "Specular Networks", -[5][0x02 - 1] = "Patriot Memory (PDP Systems)", -[5][0x03 - 1] = "U-Chip Technology Corp.", -[5][0x04 - 1] = "Silicon Optix", -[5][0x05 - 1] = "Greenfield Networks", -[5][0x06 - 1] = "CompuRAM GmbH", -[5][0x07 - 1] = "Stargen, Inc.", -[5][0x08 - 1] = "NetCell Corporation", -[5][0x09 - 1] = "Excalibrus Technologies Ltd", -[5][0x0a - 1] = "SCM Microsystems", -[5][0x0b - 1] = "Xsigo Systems, Inc.", -[5][0x0c - 1] = "CHIPS & Systems Inc", -[5][0x0d - 1] = "Tier 1 Multichip Solutions", -[5][0x0e - 1] = "CWRL Labs", -[5][0x0f - 1] = "Teradici", -[5][0x10 - 1] = "Gigaram, Inc.", -[5][0x11 - 1] = "g2 Microsystems", -[5][0x12 - 1] = "PowerFlash Semiconductor", -[5][0x13 - 1] = "P.A. Semi, Inc.", -[5][0x14 - 1] = "NovaTech Solutions, S.A.", -[5][0x15 - 1] = "c2 Microsystems, Inc.", -[5][0x16 - 1] = "Level5 Networks", -[5][0x17 - 1] = "COS Memory AG", -[5][0x18 - 1] = "Innovasic Semiconductor", -[5][0x19 - 1] = "02IC Co. Ltd", -[5][0x1a - 1] = "Tabula, Inc.", -[5][0x1b - 1] = "Crucial Technology", -[5][0x1c - 1] = "Chelsio Communications", -[5][0x1d - 1] = "Solarflare Communications", -[5][0x1e - 1] = "Xambala Inc.", -[5][0x1f - 1] = "EADS Astrium", -[5][0x20 - 1] = "Terra Semiconductor, Inc.", -[5][0x21 - 1] = "Imaging Works, Inc.", -[5][0x22 - 1] = "Astute Networks, Inc.", -[5][0x23 - 1] = "Tzero", -[5][0x24 - 1] = "Emulex", -[5][0x25 - 1] = "Power-One", -[5][0x26 - 1] = "Pulse~LINK Inc.", -[5][0x27 - 1] = "Hon Hai Precision Industry", -[5][0x28 - 1] = "White Rock Networks Inc.", -[5][0x29 - 1] = "Telegent Systems USA, Inc.", -[5][0x2a - 1] = "Atrua Technologies, Inc.", -[5][0x2b - 1] = "Acbel Polytech Inc.", -[5][0x2c - 1] = "eRide Inc.", -[5][0x2d - 1] = "ULi Electronics Inc.", -[5][0x2e - 1] = "Magnum Semiconductor Inc.", -[5][0x2f - 1] = "neoOne Technology, Inc.", -[5][0x30 - 1] = "Connex Technology, Inc.", -[5][0x31 - 1] = "Stream Processors, Inc.", -[5][0x32 - 1] = "Focus Enhancements", -[5][0x33 - 1] = "Telecis Wireless, Inc.", -[5][0x34 - 1] = "uNav Microelectronics", -[5][0x35 - 1] = "Tarari, Inc.", -[5][0x36 - 1] = "Ambric, Inc.", -[5][0x37 - 1] = "Newport Media, Inc.", -[5][0x38 - 1] = "VMTS", -[5][0x39 - 1] = "Enuclia Semiconductor, Inc.", -[5][0x3a - 1] = "Virtium Technology Inc.", -[5][0x3b - 1] = "Solid State System Co., Ltd.", -[5][0x3c - 1] = "Kian Tech LLC", -[5][0x3d - 1] = "Artimi", -[5][0x3e - 1] = "Power Quotient International", -[5][0x3f - 1] = "Avago Technologies", -[5][0x40 - 1] = "ADTechnology", -[5][0x41 - 1] = "Sigma Designs", -[5][0x42 - 1] = "SiCortex, Inc.", -[5][0x43 - 1] = "Ventura Technology Group", -[5][0x44 - 1] = "eASIC", -[5][0x45 - 1] = "M.H.S. SAS", -[5][0x46 - 1] = "Micro Star International", -[5][0x47 - 1] = "Rapport Inc.", -[5][0x48 - 1] = "Makway International", -[5][0x49 - 1] = "Broad Reach Engineering Co.", -[5][0x4a - 1] = "Semiconductor Mfg Intl Corp", -[5][0x4b - 1] = "SiConnect", -[5][0x4c - 1] = "FCI USA Inc.", -[5][0x4d - 1] = "Validity Sensors", -[5][0x4e - 1] = "Coney Technology Co. Ltd.", -[5][0x4f - 1] = "Spans Logic", -[5][0x50 - 1] = "Neterion Inc.", -[5][0x51 - 1] = "Qimonda", -[5][0x52 - 1] = "New Japan Radio Co. Ltd.", -[5][0x53 - 1] = "Velogix", -[5][0x54 - 1] = "Montalvo Systems", -[5][0x55 - 1] = "iVivity Inc.", -[5][0x56 - 1] = "Walton Chaintech", -[5][0x57 - 1] = "AENEON", -[5][0x58 - 1] = "Lorom Industrial Co. Ltd.", -[5][0x59 - 1] = "Radiospire Networks", -[5][0x5a - 1] = "Sensio Technologies, Inc.", -[5][0x5b - 1] = "Nethra Imaging", -[5][0x5c - 1] = "Hexon Technology Pte Ltd", -[5][0x5d - 1] = "CompuStocx (CSX)", -[5][0x5e - 1] = "Methode Electronics, Inc.", -[5][0x5f - 1] = "Connect One Ltd.", -[5][0x60 - 1] = "Opulan Technologies", -[5][0x61 - 1] = "Septentrio NV", -[5][0x62 - 1] = "Goldenmars Technology Inc.", -[5][0x63 - 1] = "Kreton Corporation", -[5][0x64 - 1] = "Cochlear Ltd.", -[5][0x65 - 1] = "Altair Semiconductor", -[5][0x66 - 1] = "NetEffect, Inc.", -[5][0x67 - 1] = "Spansion, Inc.", -[5][0x68 - 1] = "Taiwan Semiconductor Mfg", -[5][0x69 - 1] = "Emphany Systems Inc.", -[5][0x6a - 1] = "ApaceWave Technologies", -[5][0x6b - 1] = "Mobilygen Corporation", -[5][0x6c - 1] = "Tego", -[5][0x6d - 1] = "Cswitch Corporation", -[5][0x6e - 1] = "Haier (Beijing) IC Design Co.", -[5][0x6f - 1] = "MetaRAM", -[5][0x70 - 1] = "Axel Electronics Co. Ltd.", -[5][0x71 - 1] = "Tilera Corporation", -[5][0x72 - 1] = "Aquantia", -[5][0x73 - 1] = "Vivace Semiconductor", -[5][0x74 - 1] = "Redpine Signals", -[5][0x75 - 1] = "Octalica", -[5][0x76 - 1] = "InterDigital Communications", -[5][0x77 - 1] = "Avant Technology", -[5][0x78 - 1] = "Asrock, Inc.", -[5][0x79 - 1] = "Availink", -[5][0x7a - 1] = "Quartics, Inc.", -[5][0x7b - 1] = "Element CXI", -[5][0x7c - 1] = "Innovaciones Microelectronicas", -[5][0x7d - 1] = "VeriSilicon Microelectronics", -[5][0x7e - 1] = "W5 Networks", -[6][0x01 - 1] = "MOVEKING", -[6][0x02 - 1] = "Mavrix Technology, Inc.", -[6][0x03 - 1] = "CellGuide Ltd.", -[6][0x04 - 1] = "Faraday Technology", -[6][0x05 - 1] = "Diablo Technologies, Inc.", -[6][0x06 - 1] = "Jennic", -[6][0x07 - 1] = "Octasic", -[6][0x08 - 1] = "Molex Incorporated", -[6][0x09 - 1] = "3Leaf Networks", -[6][0x0a - 1] = "Bright Micron Technology", -[6][0x0b - 1] = "Netxen", -[6][0x0c - 1] = "NextWave Broadband Inc.", -[6][0x0d - 1] = "DisplayLink", -[6][0x0e - 1] = "ZMOS Technology", -[6][0x0f - 1] = "Tec-Hill", -[6][0x10 - 1] = "Multigig, Inc.", -[6][0x11 - 1] = "Amimon", -[6][0x12 - 1] = "Euphonic Technologies, Inc.", -[6][0x13 - 1] = "BRN Phoenix", -[6][0x14 - 1] = "InSilica", -[6][0x15 - 1] = "Ember Corporation", -[6][0x16 - 1] = "Avexir Technologies Corporation", -[6][0x17 - 1] = "Echelon Corporation", -[6][0x18 - 1] = "Edgewater Computer Systems", -[6][0x19 - 1] = "XMOS Semiconductor Ltd.", -[6][0x1a - 1] = "GENUSION, Inc.", -[6][0x1b - 1] = "Memory Corp NV", -[6][0x1c - 1] = "SiliconBlue Technologies", -[6][0x1d - 1] = "Rambus Inc.", -[6][0x1e - 1] = "Andes Technology Corporation", -[6][0x1f - 1] = "Coronis Systems", -[6][0x20 - 1] = "Achronix Semiconductor", -[6][0x21 - 1] = "Siano Mobile Silicon Ltd.", -[6][0x22 - 1] = "Semtech Corporation", -[6][0x23 - 1] = "Pixelworks Inc.", -[6][0x24 - 1] = "Gaisler Research AB", -[6][0x25 - 1] = "Teranetics", -[6][0x26 - 1] = "Toppan Printing Co. Ltd.", -[6][0x27 - 1] = "Kingxcon", -[6][0x28 - 1] = "Silicon Integrated Systems", -[6][0x29 - 1] = "I-O Data Device, Inc.", -[6][0x2a - 1] = "NDS Americas Inc.", -[6][0x2b - 1] = "Solomon Systech Limited", -[6][0x2c - 1] = "On Demand Microelectronics", -[6][0x2d - 1] = "Amicus Wireless Inc.", -[6][0x2e - 1] = "SMARDTV SNC", -[6][0x2f - 1] = "Comsys Communication Ltd.", -[6][0x30 - 1] = "Movidia Ltd.", -[6][0x31 - 1] = "Javad GNSS, Inc.", -[6][0x32 - 1] = "Montage Technology Group", -[6][0x33 - 1] = "Trident Microsystems", -[6][0x34 - 1] = "Super Talent", -[6][0x35 - 1] = "Optichron, Inc.", -[6][0x36 - 1] = "Future Waves UK Ltd.", -[6][0x37 - 1] = "SiBEAM, Inc.", -[6][0x38 - 1] = "Inicore,Inc.", -[6][0x39 - 1] = "Virident Systems", -[6][0x3a - 1] = "M2000, Inc.", -[6][0x3b - 1] = "ZeroG Wireless, Inc.", -[6][0x3c - 1] = "Gingle Technology Co. Ltd.", -[6][0x3d - 1] = "Space Micro Inc.", -[6][0x3e - 1] = "Wilocity", -[6][0x3f - 1] = "Novafora, Inc.", -[6][0x40 - 1] = "iKoa Corporation", -[6][0x41 - 1] = "ASint Technology", -[6][0x42 - 1] = "Ramtron", -[6][0x43 - 1] = "Plato Networks Inc.", -[6][0x44 - 1] = "IPtronics AS", -[6][0x45 - 1] = "Infinite-Memories", -[6][0x46 - 1] = "Parade Technologies Inc.", -[6][0x47 - 1] = "Dune Networks", -[6][0x48 - 1] = "GigaDevice Semiconductor", -[6][0x49 - 1] = "Modu Ltd.", -[6][0x4a - 1] = "CEITEC", -[6][0x4b - 1] = "Northrop Grumman", -[6][0x4c - 1] = "XRONET Corporation", -[6][0x4d - 1] = "Sicon Semiconductor AB", -[6][0x4e - 1] = "Atla Electronics Co. Ltd.", -[6][0x4f - 1] = "TOPRAM Technology", -[6][0x50 - 1] = "Silego Technology Inc.", -[6][0x51 - 1] = "Kinglife", -[6][0x52 - 1] = "Ability Industries Ltd.", -[6][0x53 - 1] = "Silicon Power Computer &", -[6][0x54 - 1] = "Augusta Technology, Inc.", -[6][0x55 - 1] = "Nantronics Semiconductors", -[6][0x56 - 1] = "Hilscher Gesellschaft", -[6][0x57 - 1] = "Quixant Ltd.", -[6][0x58 - 1] = "Percello Ltd.", -[6][0x59 - 1] = "NextIO Inc.", -[6][0x5a - 1] = "Scanimetrics Inc.", -[6][0x5b - 1] = "FS-Semi Company Ltd.", -[6][0x5c - 1] = "Infinera Corporation", -[6][0x5d - 1] = "SandForce Inc.", -[6][0x5e - 1] = "Lexar Media", -[6][0x5f - 1] = "Teradyne Inc.", -[6][0x60 - 1] = "Memory Exchange Corp.", -[6][0x61 - 1] = "Suzhou Smartek Electronics", -[6][0x62 - 1] = "Avantium Corporation", -[6][0x63 - 1] = "ATP Electronics Inc.", -[6][0x64 - 1] = "Valens Semiconductor Ltd", -[6][0x65 - 1] = "Agate Logic, Inc.", -[6][0x66 - 1] = "Netronome", -[6][0x67 - 1] = "Zenverge, Inc.", -[6][0x68 - 1] = "N-trig Ltd", -[6][0x69 - 1] = "SanMax Technologies Inc.", -[6][0x6a - 1] = "Contour Semiconductor Inc.", -[6][0x6b - 1] = "TwinMOS", -[6][0x6c - 1] = "Silicon Systems, Inc.", -[6][0x6d - 1] = "V-Color Technology Inc.", -[6][0x6e - 1] = "Certicom Corporation", -[6][0x6f - 1] = "JSC ICC Milandr", -[6][0x70 - 1] = "PhotoFast Global Inc.", -[6][0x71 - 1] = "InnoDisk Corporation", -[6][0x72 - 1] = "Muscle Power", -[6][0x73 - 1] = "Energy Micro", -[6][0x74 - 1] = "Innofidei", -[6][0x75 - 1] = "CopperGate Communications", -[6][0x76 - 1] = "Holtek Semiconductor Inc.", -[6][0x77 - 1] = "Myson Century, Inc.", -[6][0x78 - 1] = "FIDELIX", -[6][0x79 - 1] = "Red Digital Cinema", -[6][0x7a - 1] = "Densbits Technology", -[6][0x7b - 1] = "Zempro", -[6][0x7c - 1] = "MoSys", -[6][0x7d - 1] = "Provigent", -[6][0x7e - 1] = "Triad Semiconductor, Inc.", -[7][0x01 - 1] = "Siklu Communication Ltd.", -[7][0x02 - 1] = "A Force Manufacturing Ltd.", -[7][0x03 - 1] = "Strontium", -[7][0x04 - 1] = "Abilis Systems", -[7][0x05 - 1] = "Siglead, Inc.", -[7][0x06 - 1] = "Ubicom, Inc.", -[7][0x07 - 1] = "Unifosa Corporation", -[7][0x08 - 1] = "Stretch, Inc.", -[7][0x09 - 1] = "Lantiq Deutschland GmbH", -[7][0x0a - 1] = "Visipro.", -[7][0x0b - 1] = "EKMemory", -[7][0x0c - 1] = "Microelectronics Institute ZTE", -[7][0x0d - 1] = "Cognovo Ltd.", -[7][0x0e - 1] = "Carry Technology Co. Ltd.", -[7][0x0f - 1] = "Nokia", -[7][0x10 - 1] = "King Tiger Technology", -[7][0x11 - 1] = "Sierra Wireless", -[7][0x12 - 1] = "HT Micron", -[7][0x13 - 1] = "Albatron Technology Co. Ltd.", -[7][0x14 - 1] = "Leica Geosystems AG", -[7][0x15 - 1] = "BroadLight", -[7][0x16 - 1] = "AEXEA", -[7][0x17 - 1] = "ClariPhy Communications, Inc.", -[7][0x18 - 1] = "Green Plug", -[7][0x19 - 1] = "Design Art Networks", -[7][0x1a - 1] = "Mach Xtreme Technology Ltd.", -[7][0x1b - 1] = "ATO Solutions Co. Ltd.", -[7][0x1c - 1] = "Ramsta", -[7][0x1d - 1] = "Greenliant Systems, Ltd.", -[7][0x1e - 1] = "Teikon", -[7][0x1f - 1] = "Antec Hadron", -[7][0x20 - 1] = "NavCom Technology, Inc.", -[7][0x21 - 1] = "Shanghai Fudan Microelectronics", -[7][0x22 - 1] = "Calxeda, Inc.", -[7][0x23 - 1] = "JSC EDC Electronics", -[7][0x24 - 1] = "Kandit Technology Co. Ltd.", -[7][0x25 - 1] = "Ramos Technology", -[7][0x26 - 1] = "Goldenmars Technology", -[7][0x27 - 1] = "XeL Technology Inc.", -[7][0x28 - 1] = "Newzone Corporation", -[7][0x29 - 1] = "ShenZhen MercyPower Tech", -[7][0x2a - 1] = "Nanjing Yihuo Technology", -[7][0x2b - 1] = "Nethra Imaging Inc.", -[7][0x2c - 1] = "SiTel Semiconductor BV", -[7][0x2d - 1] = "SolidGear Corporation", -[7][0x2e - 1] = "Topower Computer Ind Co Ltd.", -[7][0x2f - 1] = "Wilocity", -[7][0x30 - 1] = "Profichip GmbH", -[7][0x31 - 1] = "Gerad Technologies", -[7][0x32 - 1] = "Ritek Corporation", -[7][0x33 - 1] = "Gomos Technology Limited", -[7][0x34 - 1] = "Memoright Corporation", -[7][0x35 - 1] = "D-Broad, Inc.", -[7][0x36 - 1] = "HiSilicon Technologies", -[7][0x37 - 1] = "Syndiant Inc..", -[7][0x38 - 1] = "Enverv Inc.", -[7][0x39 - 1] = "Cognex", -[7][0x3a - 1] = "Xinnova Technology Inc.", -[7][0x3b - 1] = "Ultron AG", -[7][0x3c - 1] = "Concord Idea Corporation", -[7][0x3d - 1] = "AIM Corporation", -[7][0x3e - 1] = "Lifetime Memory Products", -[7][0x3f - 1] = "Ramsway", -[7][0x40 - 1] = "Recore Systems B.V.", -[7][0x41 - 1] = "Haotian Jinshibo Science Tech", -[7][0x42 - 1] = "Being Advanced Memory", -[7][0x43 - 1] = "Adesto Technologies", -[7][0x44 - 1] = "Giantec Semiconductor, Inc.", -[7][0x45 - 1] = "HMD Electronics AG", -[7][0x46 - 1] = "Gloway International (HK)", -[7][0x47 - 1] = "Kingcore", -[7][0x48 - 1] = "Anucell Technology Holding", -[7][0x49 - 1] = "Accord Software & Systems Pvt. Ltd.", -[7][0x4a - 1] = "Active-Semi Inc.", -[7][0x4b - 1] = "Denso Corporation", -[7][0x4c - 1] = "TLSI Inc.", -[7][0x4d - 1] = "Qidan", -[7][0x4e - 1] = "Mustang", -[7][0x4f - 1] = "Orca Systems", -[7][0x50 - 1] = "Passif Semiconductor", -[7][0x51 - 1] = "GigaDevice Semiconductor (Beijing)", -[7][0x52 - 1] = "Memphis Electronic", -[7][0x53 - 1] = "Beckhoff Automation GmbH", -[7][0x54 - 1] = "Harmony Semiconductor Corp", -[7][0x55 - 1] = "Air Computers SRL", -[7][0x56 - 1] = "TMT Memory", -[7][0x57 - 1] = "Eorex Corporation", -[7][0x58 - 1] = "Xingtera", -[7][0x59 - 1] = "Netsol", -[7][0x5a - 1] = "Bestdon Technology Co. Ltd.", -[7][0x5b - 1] = "Baysand Inc.", -[7][0x5c - 1] = "Uroad Technology Co. Ltd.", -[7][0x5d - 1] = "Wilk Elektronik S.A.", -[7][0x5e - 1] = "AAI", -[7][0x5f - 1] = "Harman", -[7][0x60 - 1] = "Berg Microelectronics Inc.", -[7][0x61 - 1] = "ASSIA, Inc.", -[7][0x62 - 1] = "Visiontek Products LLC", -[7][0x63 - 1] = "OCMEMORY", -[7][0x64 - 1] = "Welink Solution Inc.", -[7][0x65 - 1] = "Shark Gaming", -[7][0x66 - 1] = "Avalanche Technology", -[7][0x67 - 1] = "R&D Center ELVEES OJSC", -[7][0x68 - 1] = "KingboMars Technology Co. Ltd.", -[7][0x69 - 1] = "High Bridge Solutions Industria", -[7][0x6a - 1] = "Transcend Technology Co. Ltd.", -[7][0x6b - 1] = "Everspin Technologies", -[7][0x6c - 1] = "Hon-Hai Precision", -[7][0x6d - 1] = "Smart Storage Systems", -[7][0x6e - 1] = "Toumaz Group", -[7][0x6f - 1] = "Zentel Electronics Corporation", -[7][0x70 - 1] = "Panram International Corporation", -[7][0x71 - 1] = "Silicon Space Technology", -[7][0x72 - 1] = "LITE-ON IT Corporation", -[7][0x73 - 1] = "Inuitive", -[7][0x74 - 1] = "HMicro", -[7][0x75 - 1] = "BittWare, Inc.", -[7][0x76 - 1] = "GLOBALFOUNDRIES", -[7][0x77 - 1] = "ACPI Digital Co. Ltd.", -[7][0x78 - 1] = "Annapurna Labs", -[7][0x79 - 1] = "AcSiP Technology Corporation", -[7][0x7a - 1] = "Idea! Electronic Systems", -[7][0x7b - 1] = "Gowe Technology Co. Ltd.", -[7][0x7c - 1] = "Hermes Testing Solutions, Inc.", -[7][0x7d - 1] = "Positivo BGH", -[7][0x7e - 1] = "Intelligence Silicon Technology", -[8][0x01 - 1] = "3D PLUS", -[8][0x02 - 1] = "Diehl Aerospace", -[8][0x03 - 1] = "Fairchild", -[8][0x04 - 1] = "Mercury Systems", -[8][0x05 - 1] = "Sonics, Inc.", -[8][0x06 - 1] = "GE Intelligent Platforms GmbH & Co.", -[8][0x07 - 1] = "Shenzhen Jinge Information Co. Ltd.", -[8][0x08 - 1] = "SCWW", -[8][0x09 - 1] = "Silicon Motion Inc.", -[8][0x0a - 1] = "Anurag", -[8][0x0b - 1] = "King Kong", -[8][0x0c - 1] = "FROM30 Co. Ltd.", -[8][0x0d - 1] = "Gowin Semiconductor Corp", -[8][0x0e - 1] = "Fremont Micro Devices Ltd.", -[8][0x0f - 1] = "Ericsson Modems", -[8][0x10 - 1] = "Exelis", -[8][0x11 - 1] = "Satixfy Ltd.", -[8][0x12 - 1] = "Galaxy Microsystems Ltd.", -[8][0x13 - 1] = "Gloway International Co. Ltd.", -[8][0x14 - 1] = "Lab", -[8][0x15 - 1] = "Smart Energy Instruments", -[8][0x16 - 1] = "Approved Memory Corporation", -[8][0x17 - 1] = "Axell Corporation", -[8][0x18 - 1] = "Essencore Limited", -[8][0x19 - 1] = "Phytium", -[8][0x1a - 1] = "Xi’an SinoChip Semiconductor", -[8][0x1b - 1] = "Ambiq Micro", -[8][0x1c - 1] = "eveRAM Technology, Inc.", -[8][0x1d - 1] = "Infomax", -[8][0x1e - 1] = "Butterfly Network, Inc.", -[8][0x1f - 1] = "Shenzhen City Gcai Electronics", -[8][0x20 - 1] = "Stack Devices Corporation", -[8][0x21 - 1] = "ADK Media Group", -[8][0x22 - 1] = "TSP Global Co., Ltd.", -[8][0x23 - 1] = "HighX", -[8][0x24 - 1] = "Shenzhen Elicks Technology", -[8][0x25 - 1] = "ISSI/Chingis", -[8][0x26 - 1] = "Google, Inc.", -[8][0x27 - 1] = "Dasima International Development", -[8][0x28 - 1] = "Leahkinn Technology Limited", -[8][0x29 - 1] = "HIMA Paul Hildebrandt GmbH Co KG", -[8][0x2a - 1] = "Keysight Technologies", -[8][0x2b - 1] = "Techcomp International (Fastable)", -[8][0x2c - 1] = "Ancore Technology Corporation", -[8][0x2d - 1] = "Nuvoton", -[8][0x2e - 1] = "Korea Uhbele International Group Ltd.", -[8][0x2f - 1] = "Ikegami Tsushinki Co Ltd.", -[8][0x30 - 1] = "RelChip, Inc.", -[8][0x31 - 1] = "Baikal Electronics", -[8][0x32 - 1] = "Nemostech Inc.", -[8][0x33 - 1] = "Memorysolution GmbH", -[8][0x34 - 1] = "Silicon Integrated Systems Corporation", -[8][0x35 - 1] = "Xiede", -[8][0x36 - 1] = "Multilaser Components", -[8][0x37 - 1] = "Flash Chi", -[8][0x38 - 1] = "Jone", -[8][0x39 - 1] = "GCT Semiconductor Inc.", -[8][0x3a - 1] = "Hong Kong Zetta Device Technology", -[8][0x3b - 1] = "Unimemory Technology(s) Pte Ltd.", -[8][0x3c - 1] = "Cuso", -[8][0x3d - 1] = "Kuso", -[8][0x3e - 1] = "Uniquify Inc.", -[8][0x3f - 1] = "Skymedi Corporation", -[8][0x40 - 1] = "Core Chance Co. Ltd.", -[8][0x41 - 1] = "Tekism Co. Ltd.", -[8][0x42 - 1] = "Seagate Technology PLC", -[8][0x43 - 1] = "Hong Kong Gaia Group Co. Limited", -[8][0x44 - 1] = "Gigacom Semiconductor LLC", -[8][0x45 - 1] = "V2 Technologies", -[8][0x46 - 1] = "TLi", -[8][0x47 - 1] = "Neotion", -[8][0x48 - 1] = "Lenovo", -[8][0x49 - 1] = "Shenzhen Zhongteng Electronic Corp. Ltd.", -[8][0x4a - 1] = "Compound Photonics", -[8][0x4b - 1] = "in2H2 inc", -[8][0x4c - 1] = "Shenzhen Pango Microsystems Co. Ltd", -[8][0x4d - 1] = "Vasekey", -[8][0x4e - 1] = "Cal-Comp Industria de Semicondutores", -[8][0x4f - 1] = "Eyenix Co., Ltd.", -[8][0x50 - 1] = "Heoriady", -[8][0x51 - 1] = "Accelerated Memory Production Inc.", -[8][0x52 - 1] = "INVECAS, Inc.", -[8][0x53 - 1] = "AP Memory", -[8][0x54 - 1] = "Douqi Technology", -[8][0x55 - 1] = "Etron Technology, Inc.", -[8][0x56 - 1] = "Indie Semiconductor", -[8][0x57 - 1] = "Socionext Inc.", -[8][0x58 - 1] = "HGST", -[8][0x59 - 1] = "EVGA", -[8][0x5a - 1] = "Audience Inc.", -[8][0x5b - 1] = "EpicGear", -[8][0x5c - 1] = "Vitesse Enterprise Co.", -[8][0x5d - 1] = "Foxtronn International Corporation", -[8][0x5e - 1] = "Bretelon Inc.", -[8][0x5f - 1] = "Zbit Semiconductor, Inc.", -[8][0x60 - 1] = "Eoplex Inc", -[8][0x61 - 1] = "MaxLinear, Inc.", -[8][0x62 - 1] = "ETA Devices", -[8][0x63 - 1] = "LOKI", -[8][0x64 - 1] = "IMS Semiconductor Co., Ltd", -[8][0x65 - 1] = "Dosilicon Co., Ltd.", -[8][0x66 - 1] = "Dolphin Integration", -[8][0x67 - 1] = "Shenzhen Mic Electronics Technology", -[8][0x68 - 1] = "Boya Microelectronics Inc.", -[8][0x69 - 1] = "Geniachip (Roche)", -[8][0x6a - 1] = "Axign", -[8][0x6b - 1] = "Kingred Electronic Technology Ltd.", -[8][0x6c - 1] = "Chao Yue Zhuo Computer Business Dept.", -[8][0x6d - 1] = "Guangzhou Si Nuo Electronic Technology.", -/* EOF */ diff --git a/src/helper/jim-nvp.c b/src/helper/jim-nvp.c deleted file mode 100644 index d13bdfba4..000000000 --- a/src/helper/jim-nvp.c +++ /dev/null @@ -1,341 +0,0 @@ -/* Jim - A small embeddable Tcl interpreter - * - * Copyright 2005 Salvatore Sanfilippo - * Copyright 2005 Clemens Hintze - * Copyright 2005 patthoyts - Pat Thoyts - * Copyright 2008 oharboe - Øyvind Harboe - oyvind.harboe@zylin.com - * Copyright 2008 Andrew Lunn - * Copyright 2008 Duane Ellis - * Copyright 2008 Uwe Klein - * Copyright 2008 Steve Bennett - * Copyright 2009 Nico Coesel - * Copyright 2009 Zachary T Welch zw@superlucidity.net - * Copyright 2009 David Brownell - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE JIM TCL PROJECT ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * JIM TCL PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * The views and conclusions contained in the software and documentation - * are those of the authors and should not be interpreted as representing - * official policies, either expressed or implied, of the Jim Tcl Project. - */ - -#include -#include - -int Jim_GetNvp(Jim_Interp *interp, - Jim_Obj *objPtr, const Jim_Nvp *nvp_table, const Jim_Nvp **result) -{ - Jim_Nvp *n; - int e; - - e = Jim_Nvp_name2value_obj(interp, nvp_table, objPtr, &n); - if (e == JIM_ERR) - return e; - - /* Success? found? */ - if (n->name) { - /* remove const */ - *result = (Jim_Nvp *) n; - return JIM_OK; - } else - return JIM_ERR; -} - -Jim_Nvp *Jim_Nvp_name2value_simple(const Jim_Nvp *p, const char *name) -{ - while (p->name) { - if (0 == strcmp(name, p->name)) - break; - p++; - } - return (Jim_Nvp *) (p); -} - -Jim_Nvp *Jim_Nvp_name2value_nocase_simple(const Jim_Nvp *p, const char *name) -{ - while (p->name) { - if (0 == strcasecmp(name, p->name)) - break; - p++; - } - return (Jim_Nvp *) (p); -} - -int Jim_Nvp_name2value_obj(Jim_Interp *interp, const Jim_Nvp *p, Jim_Obj *o, Jim_Nvp **result) -{ - return Jim_Nvp_name2value(interp, p, Jim_String(o), result); -} - -int Jim_Nvp_name2value(Jim_Interp *interp, const Jim_Nvp *_p, const char *name, Jim_Nvp **result) -{ - const Jim_Nvp *p; - - p = Jim_Nvp_name2value_simple(_p, name); - - /* result */ - if (result) - *result = (Jim_Nvp *) (p); - - /* found? */ - if (p->name) - return JIM_OK; - else - return JIM_ERR; -} - -int Jim_Nvp_name2value_obj_nocase(Jim_Interp *interp, - const Jim_Nvp *p, - Jim_Obj *o, - Jim_Nvp **puthere) -{ - return Jim_Nvp_name2value_nocase(interp, p, Jim_String(o), puthere); -} - -int Jim_Nvp_name2value_nocase(Jim_Interp *interp, const Jim_Nvp *_p, const char *name, - Jim_Nvp **puthere) -{ - const Jim_Nvp *p; - - p = Jim_Nvp_name2value_nocase_simple(_p, name); - - if (puthere) - *puthere = (Jim_Nvp *) (p); - /* found */ - if (p->name) - return JIM_OK; - else - return JIM_ERR; -} - -int Jim_Nvp_value2name_obj(Jim_Interp *interp, const Jim_Nvp *p, Jim_Obj *o, Jim_Nvp **result) -{ - int e; - jim_wide w; - - e = Jim_GetWide(interp, o, &w); - if (e != JIM_OK) - return e; - - return Jim_Nvp_value2name(interp, p, w, result); -} - -Jim_Nvp *Jim_Nvp_value2name_simple(const Jim_Nvp *p, int value) -{ - while (p->name) { - if (value == p->value) - break; - p++; - } - return (Jim_Nvp *) (p); -} - -int Jim_Nvp_value2name(Jim_Interp *interp, const Jim_Nvp *_p, int value, Jim_Nvp **result) -{ - const Jim_Nvp *p; - - p = Jim_Nvp_value2name_simple(_p, value); - - if (result) - *result = (Jim_Nvp *) (p); - - if (p->name) - return JIM_OK; - else - return JIM_ERR; -} - -int Jim_GetOpt_Setup(Jim_GetOptInfo *p, Jim_Interp *interp, int argc, Jim_Obj *const *argv) -{ - memset(p, 0, sizeof(*p)); - p->interp = interp; - p->argc = argc; - p->argv = argv; - - return JIM_OK; -} - -void Jim_GetOpt_Debug(Jim_GetOptInfo *p) -{ - int x; - - fprintf(stderr, "---args---\n"); - for (x = 0; x < p->argc; x++) - fprintf(stderr, "%2d) %s\n", x, Jim_String(p->argv[x])); - fprintf(stderr, "-------\n"); -} - -int Jim_GetOpt_Obj(Jim_GetOptInfo *goi, Jim_Obj **puthere) -{ - Jim_Obj *o; - - o = NULL; /* failure */ - if (goi->argc) { - /* success */ - o = goi->argv[0]; - goi->argc -= 1; - goi->argv += 1; - } - if (puthere) - *puthere = o; - if (o != NULL) - return JIM_OK; - else - return JIM_ERR; -} - -int Jim_GetOpt_String(Jim_GetOptInfo *goi, const char **puthere, int *len) -{ - int r; - Jim_Obj *o; - const char *cp; - - r = Jim_GetOpt_Obj(goi, &o); - if (r == JIM_OK) { - cp = Jim_GetString(o, len); - if (puthere) { - *puthere = cp; - } - } - return r; -} - -int Jim_GetOpt_Double(Jim_GetOptInfo *goi, double *puthere) -{ - int r; - Jim_Obj *o; - double _safe; - - if (puthere == NULL) - puthere = &_safe; - - r = Jim_GetOpt_Obj(goi, &o); - if (r == JIM_OK) { - r = Jim_GetDouble(goi->interp, o, puthere); - if (r != JIM_OK) - Jim_SetResultFormatted(goi->interp, "not a number: %#s", o); - } - return r; -} - -int Jim_GetOpt_Wide(Jim_GetOptInfo *goi, jim_wide *puthere) -{ - int r; - Jim_Obj *o; - jim_wide _safe; - - if (puthere == NULL) - puthere = &_safe; - - r = Jim_GetOpt_Obj(goi, &o); - if (r == JIM_OK) - r = Jim_GetWide(goi->interp, o, puthere); - return r; -} - -int Jim_GetOpt_Nvp(Jim_GetOptInfo *goi, const Jim_Nvp *nvp, Jim_Nvp **puthere) -{ - Jim_Nvp *_safe; - Jim_Obj *o; - int e; - - if (puthere == NULL) - puthere = &_safe; - - e = Jim_GetOpt_Obj(goi, &o); - if (e == JIM_OK) - e = Jim_Nvp_name2value_obj(goi->interp, nvp, o, puthere); - - return e; -} - -void Jim_GetOpt_NvpUnknown(Jim_GetOptInfo *goi, const Jim_Nvp *nvptable, int hadprefix) -{ - if (hadprefix) - Jim_SetResult_NvpUnknown(goi->interp, goi->argv[-2], goi->argv[-1], nvptable); - else - Jim_SetResult_NvpUnknown(goi->interp, NULL, goi->argv[-1], nvptable); -} - -int Jim_GetOpt_Enum(Jim_GetOptInfo *goi, const char *const *lookup, int *puthere) -{ - int _safe; - Jim_Obj *o; - int e; - - if (puthere == NULL) - puthere = &_safe; - e = Jim_GetOpt_Obj(goi, &o); - if (e == JIM_OK) - e = Jim_GetEnum(goi->interp, o, lookup, puthere, "option", JIM_ERRMSG); - return e; -} - -void Jim_SetResult_NvpUnknown(Jim_Interp *interp, - Jim_Obj *param_name, Jim_Obj *param_value, const Jim_Nvp *nvp) -{ - if (param_name) - Jim_SetResultFormatted(interp, - "%#s: Unknown: %#s, try one of: ", - param_name, - param_value); - else - Jim_SetResultFormatted(interp, "Unknown param: %#s, try one of: ", param_value); - while (nvp->name) { - const char *a; - const char *b; - - if ((nvp + 1)->name) { - a = nvp->name; - b = ", "; - } else { - a = "or "; - b = nvp->name; - } - Jim_AppendStrings(interp, Jim_GetResult(interp), a, b, NULL); - nvp++; - } -} - -const char *Jim_Debug_ArgvString(Jim_Interp *interp, int argc, Jim_Obj *const *argv) -{ - static Jim_Obj *debug_string_obj; - - int x; - - if (debug_string_obj) - Jim_FreeObj(interp, debug_string_obj); - - debug_string_obj = Jim_NewEmptyStringObj(interp); - for (x = 0; x < argc; x++) - Jim_AppendStrings(interp, debug_string_obj, Jim_String(argv[x]), " ", NULL); - - return Jim_String(debug_string_obj); -} - -int Jim_nvpInit(Jim_Interp *interp) -{ - /* This is really a helper library, not an extension, but this is the easy way */ - return JIM_OK; -} diff --git a/src/helper/jim-nvp.h b/src/helper/jim-nvp.h deleted file mode 100644 index 7b4a491d3..000000000 --- a/src/helper/jim-nvp.h +++ /dev/null @@ -1,329 +0,0 @@ -/* Jim - A small embeddable Tcl interpreter - * - * Copyright 2005 Salvatore Sanfilippo - * Copyright 2005 Clemens Hintze - * Copyright 2005 patthoyts - Pat Thoyts - * Copyright 2008 oharboe - Øyvind Harboe - oyvind.harboe@zylin.com - * Copyright 2008 Andrew Lunn - * Copyright 2008 Duane Ellis - * Copyright 2008 Uwe Klein - * Copyright 2008 Steve Bennett - * Copyright 2009 Nico Coesel - * Copyright 2009 Zachary T Welch zw@superlucidity.net - * Copyright 2009 David Brownell - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE JIM TCL PROJECT ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * JIM TCL PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * The views and conclusions contained in the software and documentation - * are those of the authors and should not be interpreted as representing - * official policies, either expressed or implied, of the Jim Tcl Project. - */ - -#ifndef OPENOCD_HELPER_JIM_NVP_H -#define OPENOCD_HELPER_JIM_NVP_H - -#include - -/** Name Value Pairs, aka: NVP - * - Given a string - return the associated int. - * - Given a number - return the associated string. - * . - * - * Very useful when the number is not a simple index into an array of - * known string, or there may be multiple strings (aliases) that mean then same - * thing. - * - * An NVP Table is terminated with ".name = NULL". - * - * During the 'name2value' operation, if no matching string is found - * the pointer to the terminal element (with p->name == NULL) is returned. - * - * Example: - * \code - * const Jim_Nvp yn[] = { - * { "yes", 1 }, - * { "no" , 0 }, - * { "yep", 1 }, - * { "nope", 0 }, - * { NULL, -1 }, - * }; - * - * Jim_Nvp *result - * e = Jim_Nvp_name2value(interp, yn, "y", &result); - * returns &yn[0]; - * e = Jim_Nvp_name2value(interp, yn, "n", &result); - * returns &yn[1]; - * e = Jim_Nvp_name2value(interp, yn, "Blah", &result); - * returns &yn[4]; - * \endcode - * - * During the number2name operation, the first matching value is returned. - */ -typedef struct { - const char *name; - int value; -} Jim_Nvp; - -int Jim_GetNvp(Jim_Interp *interp, - Jim_Obj *objPtr, - const Jim_Nvp *nvp_table, - const Jim_Nvp **result); - -/* Name Value Pairs Operations */ -Jim_Nvp *Jim_Nvp_name2value_simple(const Jim_Nvp *nvp_table, const char *name); -Jim_Nvp *Jim_Nvp_name2value_nocase_simple(const Jim_Nvp *nvp_table, const char *name); -Jim_Nvp *Jim_Nvp_value2name_simple(const Jim_Nvp *nvp_table, int v); - -int Jim_Nvp_name2value(Jim_Interp *interp, - const Jim_Nvp *nvp_table, - const char *name, - Jim_Nvp **result); -int Jim_Nvp_name2value_nocase(Jim_Interp *interp, - const Jim_Nvp *nvp_table, - const char *name, - Jim_Nvp **result); -int Jim_Nvp_value2name(Jim_Interp *interp, const Jim_Nvp *nvp_table, int value, Jim_Nvp **result); - -int Jim_Nvp_name2value_obj(Jim_Interp *interp, - const Jim_Nvp *nvp_table, - Jim_Obj *name_obj, - Jim_Nvp **result); -int Jim_Nvp_name2value_obj_nocase(Jim_Interp *interp, - const Jim_Nvp *nvp_table, - Jim_Obj *name_obj, - Jim_Nvp **result); -int Jim_Nvp_value2name_obj(Jim_Interp *interp, - const Jim_Nvp *nvp_table, - Jim_Obj *value_obj, - Jim_Nvp **result); - -/** prints a nice 'unknown' parameter error message to the 'result' */ -void Jim_SetResult_NvpUnknown(Jim_Interp *interp, - Jim_Obj *param_name, - Jim_Obj *param_value, - const Jim_Nvp *nvp_table); - -/** Debug: convert argc/argv into a printable string for printf() debug - * - * \param interp - the interpeter - * \param argc - arg count - * \param argv - the objects - * - * \returns string pointer holding the text. - * - * Note, next call to this function will free the old (last) string. - * - * For example might want do this: - * \code - * fp = fopen("some.file.log", "a"); - * fprintf(fp, "PARAMS are: %s\n", Jim_DebugArgvString(interp, argc, argv)); - * fclose(fp); - * \endcode - */ -const char *Jim_Debug_ArgvString(Jim_Interp *interp, int argc, Jim_Obj *const *argv); - - -/** A TCL -ish GetOpt like code. - * - * Some TCL objects have various "configuration" values. - * For example - in Tcl/Tk the "buttons" have many options. - * - * Usefull when dealing with command options. - * that may come in any order... - * - * Does not support "-foo = 123" type options. - * Only supports tcl type options, like "-foo 123" - */ - -typedef struct jim_getopt { - Jim_Interp *interp; - int argc; - Jim_Obj *const *argv; - int isconfigure; /* non-zero if configure */ -} Jim_GetOptInfo; - -/** GetOpt - how to. - * - * Example (short and incomplete): - * \code - * Jim_GetOptInfo goi; - * - * Jim_GetOpt_Setup(&goi, interp, argc, argv); - * - * while (goi.argc) { - * e = Jim_GetOpt_Nvp(&goi, nvp_options, &n); - * if (e != JIM_OK) { - * Jim_GetOpt_NvpUnknown(&goi, nvp_options, 0); - * return e; - * } - * - * switch (n->value) { - * case ALIVE: - * printf("Option ALIVE specified\n"); - * break; - * case FIRST: - * if (goi.argc < 1) { - * .. not enough args error .. - * } - * Jim_GetOpt_String(&goi, &cp, NULL); - * printf("FIRSTNAME: %s\n", cp); - * case AGE: - * Jim_GetOpt_Wide(&goi, &w); - * printf("AGE: %d\n", (int)(w)); - * break; - * case POLITICS: - * e = Jim_GetOpt_Nvp(&goi, nvp_politics, &n); - * if (e != JIM_OK) { - * Jim_GetOpt_NvpUnknown(&goi, nvp_politics, 1); - * return e; - * } - * } - * } - * - * \endcode - * - */ - -/** Setup GETOPT - * - * \param goi - get opt info to be initialized - * \param interp - jim interp - * \param argc - argc count. - * \param argv - argv (will be copied) - * - * \code - * Jim_GetOptInfo goi; - * - * Jim_GetOptSetup(&goi, interp, argc, argv); - * \endcode - */ - -int Jim_GetOpt_Setup(Jim_GetOptInfo *goi, - Jim_Interp *interp, - int argc, - Jim_Obj *const *argv); - - -/** Debug - Dump parameters to stderr - * \param goi - current parameters - */ -void Jim_GetOpt_Debug(Jim_GetOptInfo *goi); - -/** Remove argv[0] from the list. - * - * \param goi - get opt info - * \param puthere - where param is put - * - */ -int Jim_GetOpt_Obj(Jim_GetOptInfo *goi, Jim_Obj **puthere); - -/** Remove argv[0] as string. - * - * \param goi - get opt info - * \param puthere - where param is put - * \param len - return its length - */ -int Jim_GetOpt_String(Jim_GetOptInfo *goi, const char **puthere, int *len); - -/** Remove argv[0] as double. - * - * \param goi - get opt info - * \param puthere - where param is put. - * - */ -int Jim_GetOpt_Double(Jim_GetOptInfo *goi, double *puthere); - -/** Remove argv[0] as wide. - * - * \param goi - get opt info - * \param puthere - where param is put. - */ -int Jim_GetOpt_Wide(Jim_GetOptInfo *goi, jim_wide *puthere); - -/** Remove argv[0] as NVP. - * - * \param goi - get opt info - * \param lookup - nvp lookup table - * \param puthere - where param is put. - * - */ -int Jim_GetOpt_Nvp(Jim_GetOptInfo *goi, const Jim_Nvp *lookup, Jim_Nvp **puthere); - -/** Create an appropriate error message for an NVP. - * - * \param goi - options info - * \param lookup - the NVP table that was used. - * \param hadprefix - 0 or 1 if the option had a prefix. - * - * This function will set the "interp->result" to a human readable - * error message listing the available options. - * - * This function assumes the previous option argv[-1] is the unknown string. - * - * If this option had some prefix, then pass "hadprefix = 1" else pass "hadprefix = 0" - * - * Example: - * \code - * - * while (goi.argc) { - * // Get the next option - * e = Jim_GetOpt_Nvp(&goi, cmd_options, &n); - * if (e != JIM_OK) { - * // option was not recognized - * // pass 'hadprefix = 0' because there is no prefix - * Jim_GetOpt_NvpUnknown(&goi, cmd_options, 0); - * return e; - * } - * - * switch (n->value) { - * case OPT_SEX: - * // handle: --sex male | female | lots | needmore - * e = Jim_GetOpt_Nvp(&goi, &nvp_sex, &n); - * if (e != JIM_OK) { - * Jim_GetOpt_NvpUnknown(&ogi, nvp_sex, 1); - * return e; - * } - * printf("Code: (%d) is %s\n", n->value, n->name); - * break; - * case ...: - * [snip] - * } - * } - * \endcode - * - */ -void Jim_GetOpt_NvpUnknown(Jim_GetOptInfo *goi, const Jim_Nvp *lookup, int hadprefix); - - -/** Remove argv[0] as Enum - * - * \param goi - get opt info - * \param lookup - lookup table. - * \param puthere - where param is put. - * - */ -int Jim_GetOpt_Enum(Jim_GetOptInfo *goi, const char *const *lookup, int *puthere); - -#endif /* OPENOCD_HELPER_JIM_NVP_H */ diff --git a/src/helper/list.h b/src/helper/list.h deleted file mode 100644 index 6fd0e7ca7..000000000 --- a/src/helper/list.h +++ /dev/null @@ -1,737 +0,0 @@ -#ifndef OPENOCD_HELPER_LIST_H -#define OPENOCD_HELPER_LIST_H - -/* begin local changes */ -#include - -#define prefetch(x) ((void)x) -#define LIST_POISON1 NULL -#define LIST_POISON2 NULL - -struct list_head { - struct list_head *next, *prev; -}; -struct hlist_head { - struct hlist_node *first; -}; -struct hlist_node { - struct hlist_node *next, **pprev; -}; -/* end local changes */ - -/* - * Simple doubly linked list implementation. - * - * Some of the internal functions ("__xxx") are useful when - * manipulating whole lists rather than single entries, as - * sometimes we already know the next/prev entries and we can - * generate better code by using them directly rather than - * using the generic single-entry routines. - */ - -#define LIST_HEAD_INIT(name) { &(name), &(name) } - -#define LIST_HEAD(name) \ - struct list_head name = LIST_HEAD_INIT(name) - -static inline void INIT_LIST_HEAD(struct list_head *list) -{ - list->next = list; - list->prev = list; -} - -/* - * Insert a new entry between two known consecutive entries. - * - * This is only for internal list manipulation where we know - * the prev/next entries already! - */ -#ifndef CONFIG_DEBUG_LIST -static inline void __list_add(struct list_head *new, - struct list_head *prev, - struct list_head *next) -{ - next->prev = new; - new->next = next; - new->prev = prev; - prev->next = new; -} -#else -extern void __list_add(struct list_head *new, - struct list_head *prev, - struct list_head *next); -#endif - -/** - * list_add - add a new entry - * @new: new entry to be added - * @head: list head to add it after - * - * Insert a new entry after the specified head. - * This is good for implementing stacks. - */ -static inline void list_add(struct list_head *new, struct list_head *head) -{ - __list_add(new, head, head->next); -} - - -/** - * list_add_tail - add a new entry - * @new: new entry to be added - * @head: list head to add it before - * - * Insert a new entry before the specified head. - * This is useful for implementing queues. - */ -static inline void list_add_tail(struct list_head *new, struct list_head *head) -{ - __list_add(new, head->prev, head); -} - -/* - * Delete a list entry by making the prev/next entries - * point to each other. - * - * This is only for internal list manipulation where we know - * the prev/next entries already! - */ -static inline void __list_del(struct list_head *prev, struct list_head *next) -{ - next->prev = prev; - prev->next = next; -} - -/** - * list_del - deletes entry from list. - * @entry: the element to delete from the list. - * Note: list_empty() on entry does not return true after this, the entry is - * in an undefined state. - */ -#ifndef CONFIG_DEBUG_LIST -static inline void __list_del_entry(struct list_head *entry) -{ - __list_del(entry->prev, entry->next); -} - -static inline void list_del(struct list_head *entry) -{ - __list_del(entry->prev, entry->next); - entry->next = LIST_POISON1; - entry->prev = LIST_POISON2; -} -#else -extern void __list_del_entry(struct list_head *entry); -extern void list_del(struct list_head *entry); -#endif - -/** - * list_replace - replace old entry by new one - * @old : the element to be replaced - * @new : the new element to insert - * - * If @old was empty, it will be overwritten. - */ -static inline void list_replace(struct list_head *old, - struct list_head *new) -{ - new->next = old->next; - new->next->prev = new; - new->prev = old->prev; - new->prev->next = new; -} - -static inline void list_replace_init(struct list_head *old, - struct list_head *new) -{ - list_replace(old, new); - INIT_LIST_HEAD(old); -} - -/** - * list_del_init - deletes entry from list and reinitialize it. - * @entry: the element to delete from the list. - */ -static inline void list_del_init(struct list_head *entry) -{ - __list_del_entry(entry); - INIT_LIST_HEAD(entry); -} - -/** - * list_move - delete from one list and add as another's head - * @list: the entry to move - * @head: the head that will precede our entry - */ -static inline void list_move(struct list_head *list, struct list_head *head) -{ - __list_del_entry(list); - list_add(list, head); -} - -/** - * list_move_tail - delete from one list and add as another's tail - * @list: the entry to move - * @head: the head that will follow our entry - */ -static inline void list_move_tail(struct list_head *list, - struct list_head *head) -{ - __list_del_entry(list); - list_add_tail(list, head); -} - -/** - * list_is_last - tests whether @list is the last entry in list @head - * @list: the entry to test - * @head: the head of the list - */ -static inline int list_is_last(const struct list_head *list, - const struct list_head *head) -{ - return list->next == head; -} - -/** - * list_empty - tests whether a list is empty - * @head: the list to test. - */ -static inline int list_empty(const struct list_head *head) -{ - return head->next == head; -} - -/** - * list_empty_careful - tests whether a list is empty and not being modified - * @head: the list to test - * - * Description: - * tests whether a list is empty _and_ checks that no other CPU might be - * in the process of modifying either member (next or prev) - * - * NOTE: using list_empty_careful() without synchronization - * can only be safe if the only activity that can happen - * to the list entry is list_del_init(). Eg. it cannot be used - * if another CPU could re-list_add() it. - */ -static inline int list_empty_careful(const struct list_head *head) -{ - struct list_head *next = head->next; - return (next == head) && (next == head->prev); -} - -/** - * list_rotate_left - rotate the list to the left - * @head: the head of the list - */ -static inline void list_rotate_left(struct list_head *head) -{ - struct list_head *first; - - if (!list_empty(head)) { - first = head->next; - list_move_tail(first, head); - } -} - -/** - * list_is_singular - tests whether a list has just one entry. - * @head: the list to test. - */ -static inline int list_is_singular(const struct list_head *head) -{ - return !list_empty(head) && (head->next == head->prev); -} - -static inline void __list_cut_position(struct list_head *list, - struct list_head *head, struct list_head *entry) -{ - struct list_head *new_first = entry->next; - list->next = head->next; - list->next->prev = list; - list->prev = entry; - entry->next = list; - head->next = new_first; - new_first->prev = head; -} - -/** - * list_cut_position - cut a list into two - * @list: a new list to add all removed entries - * @head: a list with entries - * @entry: an entry within head, could be the head itself - * and if so we won't cut the list - * - * This helper moves the initial part of @head, up to and - * including @entry, from @head to @list. You should - * pass on @entry an element you know is on @head. @list - * should be an empty list or a list you do not care about - * losing its data. - * - */ -static inline void list_cut_position(struct list_head *list, - struct list_head *head, struct list_head *entry) -{ - if (list_empty(head)) - return; - if (list_is_singular(head) && - (head->next != entry && head != entry)) - return; - if (entry == head) - INIT_LIST_HEAD(list); - else - __list_cut_position(list, head, entry); -} - -static inline void __list_splice(const struct list_head *list, - struct list_head *prev, - struct list_head *next) -{ - struct list_head *first = list->next; - struct list_head *last = list->prev; - - first->prev = prev; - prev->next = first; - - last->next = next; - next->prev = last; -} - -/** - * list_splice - join two lists, this is designed for stacks - * @list: the new list to add. - * @head: the place to add it in the first list. - */ -static inline void list_splice(const struct list_head *list, - struct list_head *head) -{ - if (!list_empty(list)) - __list_splice(list, head, head->next); -} - -/** - * list_splice_tail - join two lists, each list being a queue - * @list: the new list to add. - * @head: the place to add it in the first list. - */ -static inline void list_splice_tail(struct list_head *list, - struct list_head *head) -{ - if (!list_empty(list)) - __list_splice(list, head->prev, head); -} - -/** - * list_splice_init - join two lists and reinitialise the emptied list. - * @list: the new list to add. - * @head: the place to add it in the first list. - * - * The list at @list is reinitialised - */ -static inline void list_splice_init(struct list_head *list, - struct list_head *head) -{ - if (!list_empty(list)) { - __list_splice(list, head, head->next); - INIT_LIST_HEAD(list); - } -} - -/** - * list_splice_tail_init - join two lists and reinitialise the emptied list - * @list: the new list to add. - * @head: the place to add it in the first list. - * - * Each of the lists is a queue. - * The list at @list is reinitialised - */ -static inline void list_splice_tail_init(struct list_head *list, - struct list_head *head) -{ - if (!list_empty(list)) { - __list_splice(list, head->prev, head); - INIT_LIST_HEAD(list); - } -} - -/** - * list_entry - get the struct for this entry - * @ptr: the &struct list_head pointer. - * @type: the type of the struct this is embedded in. - * @member: the name of the list_struct within the struct. - */ -#define list_entry(ptr, type, member) \ - container_of(ptr, type, member) - -/** - * list_first_entry - get the first element from a list - * @ptr: the list head to take the element from. - * @type: the type of the struct this is embedded in. - * @member: the name of the list_struct within the struct. - * - * Note, that list is expected to be not empty. - */ -#define list_first_entry(ptr, type, member) \ - list_entry((ptr)->next, type, member) - -/** - * list_for_each - iterate over a list - * @pos: the &struct list_head to use as a loop cursor. - * @head: the head for your list. - */ -#define list_for_each(pos, head) \ - for (pos = (head)->next; prefetch(pos->next), pos != (head); \ - pos = pos->next) - -/** - * __list_for_each - iterate over a list - * @pos: the &struct list_head to use as a loop cursor. - * @head: the head for your list. - * - * This variant differs from list_for_each() in that it's the - * simplest possible list iteration code, no prefetching is done. - * Use this for code that knows the list to be very short (empty - * or 1 entry) most of the time. - */ -#define __list_for_each(pos, head) \ - for (pos = (head)->next; pos != (head); pos = pos->next) - -/** - * list_for_each_prev - iterate over a list backwards - * @pos: the &struct list_head to use as a loop cursor. - * @head: the head for your list. - */ -#define list_for_each_prev(pos, head) \ - for (pos = (head)->prev; prefetch(pos->prev), pos != (head); \ - pos = pos->prev) - -/** - * list_for_each_safe - iterate over a list safe against removal of list entry - * @pos: the &struct list_head to use as a loop cursor. - * @n: another &struct list_head to use as temporary storage - * @head: the head for your list. - */ -#define list_for_each_safe(pos, n, head) \ - for (pos = (head)->next, n = pos->next; pos != (head); \ - pos = n, n = pos->next) - -/** - * list_for_each_prev_safe - iterate over a list backwards safe against removal of list entry - * @pos: the &struct list_head to use as a loop cursor. - * @n: another &struct list_head to use as temporary storage - * @head: the head for your list. - */ -#define list_for_each_prev_safe(pos, n, head) \ - for (pos = (head)->prev, n = pos->prev; \ - prefetch(pos->prev), pos != (head); \ - pos = n, n = pos->prev) - -/** - * list_for_each_entry - iterate over list of given type - * @pos: the type * to use as a loop cursor. - * @head: the head for your list. - * @member: the name of the list_struct within the struct. - */ -#define list_for_each_entry(pos, head, member) \ - for (pos = list_entry((head)->next, typeof(*pos), member); \ - prefetch(pos->member.next), &pos->member != (head); \ - pos = list_entry(pos->member.next, typeof(*pos), member)) - -/** - * list_for_each_entry_reverse - iterate backwards over list of given type. - * @pos: the type * to use as a loop cursor. - * @head: the head for your list. - * @member: the name of the list_struct within the struct. - */ -#define list_for_each_entry_reverse(pos, head, member) \ - for (pos = list_entry((head)->prev, typeof(*pos), member); \ - prefetch(pos->member.prev), &pos->member != (head); \ - pos = list_entry(pos->member.prev, typeof(*pos), member)) - -/** - * list_prepare_entry - prepare a pos entry for use in list_for_each_entry_continue() - * @pos: the type * to use as a start point - * @head: the head of the list - * @member: the name of the list_struct within the struct. - * - * Prepares a pos entry for use as a start point in list_for_each_entry_continue(). - */ -#define list_prepare_entry(pos, head, member) \ - ((pos) ? : list_entry(head, typeof(*pos), member)) - -/** - * list_for_each_entry_continue - continue iteration over list of given type - * @pos: the type * to use as a loop cursor. - * @head: the head for your list. - * @member: the name of the list_struct within the struct. - * - * Continue to iterate over list of given type, continuing after - * the current position. - */ -#define list_for_each_entry_continue(pos, head, member) \ - for (pos = list_entry(pos->member.next, typeof(*pos), member); \ - prefetch(pos->member.next), &pos->member != (head); \ - pos = list_entry(pos->member.next, typeof(*pos), member)) - -/** - * list_for_each_entry_continue_reverse - iterate backwards from the given point - * @pos: the type * to use as a loop cursor. - * @head: the head for your list. - * @member: the name of the list_struct within the struct. - * - * Start to iterate over list of given type backwards, continuing after - * the current position. - */ -#define list_for_each_entry_continue_reverse(pos, head, member) \ - for (pos = list_entry(pos->member.prev, typeof(*pos), member); \ - prefetch(pos->member.prev), &pos->member != (head); \ - pos = list_entry(pos->member.prev, typeof(*pos), member)) - -/** - * list_for_each_entry_from - iterate over list of given type from the current point - * @pos: the type * to use as a loop cursor. - * @head: the head for your list. - * @member: the name of the list_struct within the struct. - * - * Iterate over list of given type, continuing from current position. - */ -#define list_for_each_entry_from(pos, head, member) \ - for (; prefetch(pos->member.next), &pos->member != (head); \ - pos = list_entry(pos->member.next, typeof(*pos), member)) - -/** - * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry - * @pos: the type * to use as a loop cursor. - * @n: another type * to use as temporary storage - * @head: the head for your list. - * @member: the name of the list_struct within the struct. - */ -#define list_for_each_entry_safe(pos, n, head, member) \ - for (pos = list_entry((head)->next, typeof(*pos), member), \ - n = list_entry(pos->member.next, typeof(*pos), member); \ - &pos->member != (head); \ - pos = n, n = list_entry(n->member.next, typeof(*n), member)) - -/** - * list_for_each_entry_safe_continue - continue list iteration safe against removal - * @pos: the type * to use as a loop cursor. - * @n: another type * to use as temporary storage - * @head: the head for your list. - * @member: the name of the list_struct within the struct. - * - * Iterate over list of given type, continuing after current point, - * safe against removal of list entry. - */ -#define list_for_each_entry_safe_continue(pos, n, head, member) \ - for (pos = list_entry(pos->member.next, typeof(*pos), member), \ - n = list_entry(pos->member.next, typeof(*pos), member); \ - &pos->member != (head); \ - pos = n, n = list_entry(n->member.next, typeof(*n), member)) - -/** - * list_for_each_entry_safe_from - iterate over list from current point safe against removal - * @pos: the type * to use as a loop cursor. - * @n: another type * to use as temporary storage - * @head: the head for your list. - * @member: the name of the list_struct within the struct. - * - * Iterate over list of given type from current point, safe against - * removal of list entry. - */ -#define list_for_each_entry_safe_from(pos, n, head, member) \ - for (n = list_entry(pos->member.next, typeof(*pos), member); \ - &pos->member != (head); \ - pos = n, n = list_entry(n->member.next, typeof(*n), member)) - -/** - * list_for_each_entry_safe_reverse - iterate backwards over list safe against removal - * @pos: the type * to use as a loop cursor. - * @n: another type * to use as temporary storage - * @head: the head for your list. - * @member: the name of the list_struct within the struct. - * - * Iterate backwards over list of given type, safe against removal - * of list entry. - */ -#define list_for_each_entry_safe_reverse(pos, n, head, member) \ - for (pos = list_entry((head)->prev, typeof(*pos), member), \ - n = list_entry(pos->member.prev, typeof(*pos), member); \ - &pos->member != (head); \ - pos = n, n = list_entry(n->member.prev, typeof(*n), member)) - -/** - * list_safe_reset_next - reset a stale list_for_each_entry_safe loop - * @pos: the loop cursor used in the list_for_each_entry_safe loop - * @n: temporary storage used in list_for_each_entry_safe - * @member: the name of the list_struct within the struct. - * - * list_safe_reset_next is not safe to use in general if the list may be - * modified concurrently (eg. the lock is dropped in the loop body). An - * exception to this is if the cursor element (pos) is pinned in the list, - * and list_safe_reset_next is called after re-taking the lock and before - * completing the current iteration of the loop body. - */ -#define list_safe_reset_next(pos, n, member) \ - n = list_entry(pos->member.next, typeof(*pos), member) - -/* - * Double linked lists with a single pointer list head. - * Mostly useful for hash tables where the two pointer list head is - * too wasteful. - * You lose the ability to access the tail in O(1). - */ - -#define HLIST_HEAD_INIT { .first = NULL } -#define HLIST_HEAD(name) struct hlist_head name = { .first = NULL } -#define INIT_HLIST_HEAD(ptr) ((ptr)->first = NULL) -static inline void INIT_HLIST_NODE(struct hlist_node *h) -{ - h->next = NULL; - h->pprev = NULL; -} - -static inline int hlist_unhashed(const struct hlist_node *h) -{ - return !h->pprev; -} - -static inline int hlist_empty(const struct hlist_head *h) -{ - return !h->first; -} - -static inline void __hlist_del(struct hlist_node *n) -{ - struct hlist_node *next = n->next; - struct hlist_node **pprev = n->pprev; - *pprev = next; - if (next) - next->pprev = pprev; -} - -static inline void hlist_del(struct hlist_node *n) -{ - __hlist_del(n); - n->next = LIST_POISON1; - n->pprev = LIST_POISON2; -} - -static inline void hlist_del_init(struct hlist_node *n) -{ - if (!hlist_unhashed(n)) { - __hlist_del(n); - INIT_HLIST_NODE(n); - } -} - -static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h) -{ - struct hlist_node *first = h->first; - n->next = first; - if (first) - first->pprev = &n->next; - h->first = n; - n->pprev = &h->first; -} - -/* next must be != NULL */ -static inline void hlist_add_before(struct hlist_node *n, - struct hlist_node *next) -{ - n->pprev = next->pprev; - n->next = next; - next->pprev = &n->next; - *(n->pprev) = n; -} - -static inline void hlist_add_after(struct hlist_node *n, - struct hlist_node *next) -{ - next->next = n->next; - n->next = next; - next->pprev = &n->next; - - if (next->next) - next->next->pprev = &next->next; -} - -/* after that we'll appear to be on some hlist and hlist_del will work */ -static inline void hlist_add_fake(struct hlist_node *n) -{ - n->pprev = &n->next; -} - -/* - * Move a list from one list head to another. Fixup the pprev - * reference of the first entry if it exists. - */ -static inline void hlist_move_list(struct hlist_head *old, - struct hlist_head *new) -{ - new->first = old->first; - if (new->first) - new->first->pprev = &new->first; - old->first = NULL; -} - -#define hlist_entry(ptr, type, member) container_of(ptr, type, member) - -#define hlist_for_each(pos, head) \ - for (pos = (head)->first; pos && ({ prefetch(pos->next); 1; }); \ - pos = pos->next) - -#define hlist_for_each_safe(pos, n, head) \ - for (pos = (head)->first; pos && ({ n = pos->next; 1; }); \ - pos = n) - -/** - * hlist_for_each_entry - iterate over list of given type - * @tpos: the type * to use as a loop cursor. - * @pos: the &struct hlist_node to use as a loop cursor. - * @head: the head for your list. - * @member: the name of the hlist_node within the struct. - */ -#define hlist_for_each_entry(tpos, pos, head, member) \ - for (pos = (head)->first; \ - pos && ({ prefetch(pos->next); 1; }) && \ - ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1; }); \ - pos = pos->next) - -/** - * hlist_for_each_entry_continue - iterate over a hlist continuing after current point - * @tpos: the type * to use as a loop cursor. - * @pos: the &struct hlist_node to use as a loop cursor. - * @member: the name of the hlist_node within the struct. - */ -#define hlist_for_each_entry_continue(tpos, pos, member) \ - for (pos = (pos)->next; \ - pos && ({ prefetch(pos->next); 1; }) && \ - ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1; }); \ - pos = pos->next) - -/** - * hlist_for_each_entry_from - iterate over a hlist continuing from current point - * @tpos: the type * to use as a loop cursor. - * @pos: the &struct hlist_node to use as a loop cursor. - * @member: the name of the hlist_node within the struct. - */ -#define hlist_for_each_entry_from(tpos, pos, member) \ - for (; pos && ({ prefetch(pos->next); 1; }) && \ - ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1; }); \ - pos = pos->next) - -/** - * hlist_for_each_entry_safe - iterate over list of given type safe against removal of list entry - * @tpos: the type * to use as a loop cursor. - * @pos: the &struct hlist_node to use as a loop cursor. - * @n: another &struct hlist_node to use as temporary storage - * @head: the head for your list. - * @member: the name of the hlist_node within the struct. - */ -#define hlist_for_each_entry_safe(tpos, pos, n, head, member) \ - for (pos = (head)->first; \ - pos && ({ n = pos->next; 1; }) && \ - ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1; }); \ - pos = n) - -#endif /* OPENOCD_HELPER_LIST_H */ diff --git a/src/helper/log.c b/src/helper/log.c deleted file mode 100644 index e33f869d0..000000000 --- a/src/helper/log.c +++ /dev/null @@ -1,467 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * Copyright (C) 2007-2010 Øyvind Harboe * - * oyvind.harboe@zylin.com * - * * - * Copyright (C) 2008 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "log.h" -#include "command.h" -#include "time_support.h" - -#include - -#ifdef _DEBUG_FREE_SPACE_ -#ifdef HAVE_MALLOC_H -#include -#else -#error "malloc.h is required to use --enable-malloc-logging" -#endif -#endif - -int debug_level = -1; - -static FILE *log_output; -static struct log_callback *log_callbacks; - -static int64_t last_time; -static int64_t current_time; - -static int64_t start; - -static const char * const log_strings[5] = { - "User : ", - "Error: ", - "Warn : ", /* want a space after each colon, all same width, colons aligned */ - "Info : ", - "Debug: " -}; - -static int count; - -static struct store_log_forward *log_head; -static int log_forward_count; - -struct store_log_forward { - struct store_log_forward *next; - const char *file; - int line; - const char *function; - const char *string; -}; - -/* either forward the log to the listeners or store it for possible forwarding later */ -static void log_forward(const char *file, unsigned line, const char *function, const char *string) -{ - if (log_forward_count == 0) { - struct log_callback *cb, *next; - cb = log_callbacks; - /* DANGER!!!! the log callback can remove itself!!!! */ - while (cb) { - next = cb->next; - cb->fn(cb->priv, file, line, function, string); - cb = next; - } - } else { - struct store_log_forward *log = malloc(sizeof(struct store_log_forward)); - log->file = strdup(file); - log->line = line; - log->function = strdup(function); - log->string = strdup(string); - log->next = NULL; - if (log_head == NULL) - log_head = log; - else { - /* append to tail */ - struct store_log_forward *t; - t = log_head; - while (t->next != NULL) - t = t->next; - t->next = log; - } - } -} - -/* The log_puts() serves two somewhat different goals: - * - * - logging - * - feeding low-level info to the user in GDB or Telnet - * - * The latter dictates that strings without newline are not logged, lest there - * will be *MANY log lines when sending one char at the time(e.g. - * target_request.c). - * - */ -static void log_puts(enum log_levels level, - const char *file, - int line, - const char *function, - const char *string) -{ - char *f; - if (level == LOG_LVL_OUTPUT) { - /* do not prepend any headers, just print out what we were given and return */ - fputs(string, log_output); - fflush(log_output); - return; - } - - f = strrchr(file, '/'); - if (f != NULL) - file = f + 1; - - if (strlen(string) > 0) { - if (debug_level >= LOG_LVL_DEBUG) { - /* print with count and time information */ - int64_t t = timeval_ms() - start; -#ifdef _DEBUG_FREE_SPACE_ - struct mallinfo info; - info = mallinfo(); -#endif - fprintf(log_output, "%s%d %" PRId64 " %s:%d %s()" -#ifdef _DEBUG_FREE_SPACE_ - " %d" -#endif - ": %s", log_strings[level + 1], count, t, file, line, function, -#ifdef _DEBUG_FREE_SPACE_ - info.fordblks, -#endif - string); - } else { - /* if we are using gdb through pipes then we do not want any output - * to the pipe otherwise we get repeated strings */ - fprintf(log_output, "%s%s", - (level > LOG_LVL_USER) ? log_strings[level + 1] : "", string); - } - } else { - /* Empty strings are sent to log callbacks to keep e.g. gdbserver alive, here we do - *nothing. */ - } - - fflush(log_output); - - /* Never forward LOG_LVL_DEBUG, too verbose and they can be found in the log if need be */ - if (level <= LOG_LVL_INFO) - log_forward(file, line, function, string); -} - -void log_printf(enum log_levels level, - const char *file, - unsigned line, - const char *function, - 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) { - log_puts(level, file, line, function, string); - free(string); - } - - va_end(ap); -} - -void log_printf_lf(enum log_levels level, - const char *file, - unsigned line, - const char *function, - 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); - } - - va_end(ap); -} - -COMMAND_HANDLER(handle_debug_level_command) -{ - if (CMD_ARGC == 1) { - int new_level; - COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], new_level); - if ((new_level > LOG_LVL_DEBUG) || (new_level < LOG_LVL_SILENT)) { - LOG_ERROR("level must be between %d and %d", LOG_LVL_SILENT, LOG_LVL_DEBUG); - return ERROR_COMMAND_SYNTAX_ERROR; - } - debug_level = new_level; - } else if (CMD_ARGC > 1) - return ERROR_COMMAND_SYNTAX_ERROR; - - command_print(CMD_CTX, "debug_level: %i", debug_level); - - return ERROR_OK; -} - -COMMAND_HANDLER(handle_log_output_command) -{ - if (CMD_ARGC == 1) { - FILE *file = fopen(CMD_ARGV[0], "w"); - - if (file) - log_output = file; - } - - return ERROR_OK; -} - -static struct command_registration log_command_handlers[] = { - { - .name = "log_output", - .handler = handle_log_output_command, - .mode = COMMAND_ANY, - .help = "redirect logging to a file (default: stderr)", - .usage = "file_name", - }, - { - .name = "debug_level", - .handler = handle_debug_level_command, - .mode = COMMAND_ANY, - .help = "Sets the verbosity level of debugging output. " - "0 shows errors only; 1 adds warnings; " - "2 (default) adds other info; 3 adds debugging.", - .usage = "number", - }, - COMMAND_REGISTRATION_DONE -}; - -int log_register_commands(struct command_context *cmd_ctx) -{ - return register_commands(cmd_ctx, NULL, log_command_handlers); -} - -void log_init(void) -{ - /* set defaults for daemon configuration, - * if not set by cmdline or cfgfile */ - if (debug_level == -1) - debug_level = LOG_LVL_INFO; - - char *debug_env = getenv("OPENOCD_DEBUG_LEVEL"); - if (NULL != debug_env) { - int value; - int retval = parse_int(debug_env, &value); - if (ERROR_OK == retval && - debug_level >= LOG_LVL_SILENT && - debug_level <= LOG_LVL_DEBUG) - debug_level = value; - } - - if (log_output == NULL) - log_output = stderr; - - start = last_time = timeval_ms(); -} - -int set_log_output(struct command_context *cmd_ctx, FILE *output) -{ - log_output = output; - return ERROR_OK; -} - -/* add/remove log callback handler */ -int log_add_callback(log_callback_fn fn, void *priv) -{ - struct log_callback *cb; - - /* prevent the same callback to be registered more than once, just for sure */ - for (cb = log_callbacks; cb; cb = cb->next) { - if (cb->fn == fn && cb->priv == priv) - return ERROR_COMMAND_SYNTAX_ERROR; - } - - /* alloc memory, it is safe just to return in case of an error, no need for the caller to - *check this */ - cb = malloc(sizeof(struct log_callback)); - if (cb == NULL) - return ERROR_BUF_TOO_SMALL; - - /* add item to the beginning of the linked list */ - cb->fn = fn; - cb->priv = priv; - cb->next = log_callbacks; - log_callbacks = cb; - - return ERROR_OK; -} - -int log_remove_callback(log_callback_fn fn, void *priv) -{ - struct log_callback *cb, **p; - - for (p = &log_callbacks; (cb = *p); p = &(*p)->next) { - if (cb->fn == fn && cb->priv == priv) { - *p = cb->next; - free(cb); - return ERROR_OK; - } - } - - /* no such item */ - return ERROR_COMMAND_SYNTAX_ERROR; -} - -/* return allocated string w/printf() result */ -char *alloc_vprintf(const char *fmt, va_list ap) -{ - va_list ap_copy; - int len; - char *string; - - /* determine the length of the buffer needed */ - va_copy(ap_copy, ap); - len = vsnprintf(NULL, 0, fmt, ap_copy); - va_end(ap_copy); - - /* allocate and make room for terminating zero. */ - /* FIXME: The old version always allocated at least one byte extra and - * other code depend on that. They should be probably be fixed, but for - * now reserve the extra byte. */ - string = malloc(len + 2); - if (string == NULL) - return NULL; - - /* do the real work */ - vsnprintf(string, len + 1, fmt, ap); - - return string; -} - -char *alloc_printf(const char *format, ...) -{ - char *string; - va_list ap; - va_start(ap, format); - string = alloc_vprintf(format, ap); - va_end(ap); - return string; -} - -/* Code must return to the server loop before 1000ms has returned or invoke - * this function. - * - * The GDB connection will time out if it spends >2000ms and you'll get nasty - * error messages from GDB: - * - * Ignoring packet error, continuing... - * Reply contains invalid hex digit 116 - * - * While it is possible use "set remotetimeout" to more than the default 2000ms - * in GDB, OpenOCD guarantees that it sends keep-alive packages on the - * GDB protocol and it is a bug in OpenOCD not to either return to the server - * loop or invoke keep_alive() every 1000ms. - * - * This function will send a keep alive packet if >500ms has passed since last time - * it was invoked. - * - * Note that this function can be invoked often, so it needs to be relatively - * fast when invoked more often than every 500ms. - * - */ -void keep_alive() -{ - current_time = timeval_ms(); - if (current_time-last_time > 1000) { - extern int gdb_actual_connections; - - if (gdb_actual_connections) - LOG_WARNING("keep_alive() was not invoked in the " - "1000ms timelimit. GDB alive packet not " - "sent! (%" PRId64 "). Workaround: increase " - "\"set remotetimeout\" in GDB", - current_time-last_time); - else - LOG_DEBUG("keep_alive() was not invoked in the " - "1000ms timelimit (%" PRId64 "). This may cause " - "trouble with GDB connections.", - current_time-last_time); - } - if (current_time-last_time > 500) { - /* this will keep the GDB connection alive */ - LOG_USER_N("%s", ""); - - /* DANGER!!!! do not add code to invoke e.g. target event processing, - * jim timer processing, etc. it can cause infinite recursion + - * jim event callbacks need to happen at a well defined time, - * not anywhere keep_alive() is invoked. - * - * These functions should be invoked at a well defined spot in server.c - */ - - last_time = current_time; - } -} - -/* reset keep alive timer without sending message */ -void kept_alive() -{ - current_time = timeval_ms(); - last_time = current_time; -} - -/* if we sleep for extended periods of time, we must invoke keep_alive() intermittantly */ -void alive_sleep(uint64_t ms) -{ - uint64_t napTime = 10; - for (uint64_t i = 0; i < ms; i += napTime) { - uint64_t sleep_a_bit = ms - i; - if (sleep_a_bit > napTime) - sleep_a_bit = napTime; - - usleep(sleep_a_bit * 1000); - keep_alive(); - } -} - -void busy_sleep(uint64_t ms) -{ - uint64_t then = timeval_ms(); - while (timeval_ms() - then < ms) { - /* - * busy wait - */ - } -} diff --git a/src/helper/log.h b/src/helper/log.h deleted file mode 100644 index eb222cbb7..000000000 --- a/src/helper/log.h +++ /dev/null @@ -1,142 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * Copyright (C) 2007,2008 Øyvind Harboe * - * oyvind.harboe@zylin.com * - * * - * Copyright (C) 2008 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 OPENOCD_HELPER_LOG_H -#define OPENOCD_HELPER_LOG_H - -#include - -/* To achieve C99 printf compatibility in MinGW, gnu_printf should be - * used for __attribute__((format( ... ))), with GCC v4.4 or later - */ -#if (defined(IS_MINGW) && (((__GNUC__ << 16) + __GNUC_MINOR__) >= 0x00040004)) -#define PRINTF_ATTRIBUTE_FORMAT gnu_printf -#else -#define PRINTF_ATTRIBUTE_FORMAT printf -#endif - -/* logging priorities - * LOG_LVL_SILENT - turn off all output. In lieu of try + catch this can be used as a - * feeble ersatz. - * LOG_LVL_USER - user messages. Could be anything from information - * to progress messags. These messages do not represent - * incorrect or unexpected behaviour, just normal execution. - * LOG_LVL_ERROR - fatal errors, that are likely to cause program abort - * LOG_LVL_WARNING - non-fatal errors, that may be resolved later - * LOG_LVL_INFO - state information, etc. - * LOG_LVL_DEBUG - debug statements, execution trace - */ -enum log_levels { - LOG_LVL_SILENT = -3, - LOG_LVL_OUTPUT = -2, - LOG_LVL_USER = -1, - LOG_LVL_ERROR = 0, - LOG_LVL_WARNING = 1, - LOG_LVL_INFO = 2, - LOG_LVL_DEBUG = 3 -}; - -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_printf_lf(enum log_levels level, const char *file, unsigned line, - const char *function, const char *format, ...) -__attribute__ ((format (PRINTF_ATTRIBUTE_FORMAT, 5, 6))); - -/** - * Initialize logging module. Call during program startup. - */ -void log_init(void); -int set_log_output(struct command_context *cmd_ctx, FILE *output); - -int log_register_commands(struct command_context *cmd_ctx); - -void keep_alive(void); -void kept_alive(void); - -void alive_sleep(uint64_t ms); -void busy_sleep(uint64_t ms); - -typedef void (*log_callback_fn)(void *priv, const char *file, unsigned line, - const char *function, const char *string); - -struct log_callback { - log_callback_fn fn; - void *priv; - struct log_callback *next; -}; - -int log_add_callback(log_callback_fn fn, void *priv); -int log_remove_callback(log_callback_fn fn, void *priv); - -char *alloc_vprintf(const char *fmt, va_list ap); -char *alloc_printf(const char *fmt, ...); - -extern int debug_level; - -/* Avoid fn call and building parameter list if we're not outputting the information. - * Matters on feeble CPUs for DEBUG/INFO statements that are involved frequently */ - -#define LOG_LEVEL_IS(FOO) ((debug_level) >= (FOO)) - -#define LOG_DEBUG(expr ...) \ - do { \ - if (debug_level >= LOG_LVL_DEBUG) \ - log_printf_lf(LOG_LVL_DEBUG, \ - __FILE__, __LINE__, __func__, \ - expr); \ - } while (0) - -#define LOG_INFO(expr ...) \ - log_printf_lf(LOG_LVL_INFO, __FILE__, __LINE__, __func__, expr) - -#define LOG_WARNING(expr ...) \ - log_printf_lf(LOG_LVL_WARNING, __FILE__, __LINE__, __func__, expr) - -#define LOG_ERROR(expr ...) \ - log_printf_lf(LOG_LVL_ERROR, __FILE__, __LINE__, __func__, expr) - -#define LOG_USER(expr ...) \ - log_printf_lf(LOG_LVL_USER, __FILE__, __LINE__, __func__, expr) - -#define LOG_USER_N(expr ...) \ - log_printf(LOG_LVL_USER, __FILE__, __LINE__, __func__, expr) - -#define LOG_OUTPUT(expr ...) \ - log_printf(LOG_LVL_OUTPUT, __FILE__, __LINE__, __func__, expr) - -/* general failures - * error codes < 100 - */ -#define ERROR_OK (0) -#define ERROR_NO_CONFIG_FILE (-2) -#define ERROR_BUF_TOO_SMALL (-3) -/* see "Error:" log entry for meaningful message to the user. The caller should - * make no assumptions about what went wrong and try to handle the problem. - */ -#define ERROR_FAIL (-4) -#define ERROR_WAIT (-5) - - -#endif /* OPENOCD_HELPER_LOG_H */ diff --git a/src/helper/options.c b/src/helper/options.c deleted file mode 100644 index b7db10f92..000000000 --- a/src/helper/options.c +++ /dev/null @@ -1,230 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2004, 2005 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * Copyright (C) 2007-2010 Øyvind Harboe * - * oyvind.harboe@zylin.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "configuration.h" -#include "log.h" -#include "command.h" - -#include - -static int help_flag, version_flag; - -static const struct option long_options[] = { - {"help", no_argument, &help_flag, 1}, - {"version", no_argument, &version_flag, 1}, - {"debug", optional_argument, 0, 'd'}, - {"file", required_argument, 0, 'f'}, - {"search", required_argument, 0, 's'}, - {"log_output", required_argument, 0, 'l'}, - {"command", required_argument, 0, 'c'}, - {"pipe", no_argument, 0, 'p'}, - {0, 0, 0, 0} -}; - -int configuration_output_handler(struct command_context *context, const char *line) -{ - LOG_USER_N("%s", line); - - return ERROR_OK; -} - -#ifdef _WIN32 -static char *find_suffix(const char *text, const char *suffix) -{ - size_t text_len = strlen(text); - size_t suffix_len = strlen(suffix); - - if (suffix_len == 0) - return (char *)text + text_len; - - if (suffix_len > text_len || strncmp(text + text_len - suffix_len, suffix, suffix_len) != 0) - return NULL; /* Not a suffix of text */ - - return (char *)text + text_len - suffix_len; -} -#endif - -static void add_default_dirs(void) -{ - const char *run_prefix; - char *path; - -#ifdef _WIN32 - char strExePath[MAX_PATH]; - GetModuleFileName(NULL, strExePath, MAX_PATH); - - /* Strip executable file name, leaving path */ - *strrchr(strExePath, '\\') = '\0'; - - /* Convert path separators to UNIX style, should work on Windows also. */ - for (char *p = strExePath; *p; p++) { - if (*p == '\\') - *p = '/'; - } - - char *end_of_prefix = find_suffix(strExePath, BINDIR); - if (end_of_prefix != NULL) - *end_of_prefix = '\0'; - - run_prefix = strExePath; -#else - run_prefix = ""; -#endif - - LOG_DEBUG("bindir=%s", BINDIR); - LOG_DEBUG("pkgdatadir=%s", PKGDATADIR); - LOG_DEBUG("run_prefix=%s", run_prefix); - - /* - * The directory containing OpenOCD-supplied scripts should be - * listed last in the built-in search order, so the user can - * override these scripts with site-specific customizations. - */ - const char *home = getenv("HOME"); - - if (home) { - path = alloc_printf("%s/.openocd", home); - if (path) { - add_script_search_dir(path); - free(path); - } - } - - path = getenv("OPENOCD_SCRIPTS"); - - if (path) - add_script_search_dir(path); - -#ifdef _WIN32 - const char *appdata = getenv("APPDATA"); - - if (appdata) { - path = alloc_printf("%s/OpenOCD", appdata); - if (path) { - add_script_search_dir(path); - free(path); - } - } -#endif - - path = alloc_printf("%s%s%s", run_prefix, PKGDATADIR, "/site"); - if (path) { - add_script_search_dir(path); - free(path); - } - - path = alloc_printf("%s%s%s", run_prefix, PKGDATADIR, "/scripts"); - if (path) { - add_script_search_dir(path); - free(path); - } -} - -int parse_cmdline_args(struct command_context *cmd_ctx, int argc, char *argv[]) -{ - int c; - - while (1) { - /* getopt_long stores the option index here. */ - int option_index = 0; - - c = getopt_long(argc, argv, "hvd::l:f:s:c:p", long_options, &option_index); - - /* Detect the end of the options. */ - if (c == -1) - break; - - switch (c) { - case 0: - break; - case 'h': /* --help | -h */ - help_flag = 1; - break; - case 'v': /* --version | -v */ - version_flag = 1; - break; - case 'f': /* --file | -f */ - { - char *command = alloc_printf("script {%s}", optarg); - add_config_command(command); - free(command); - break; - } - case 's': /* --search | -s */ - add_script_search_dir(optarg); - break; - case 'd': /* --debug | -d */ - { - char *command = alloc_printf("debug_level %s", optarg ? optarg : "3"); - command_run_line(cmd_ctx, command); - free(command); - break; - } - case 'l': /* --log_output | -l */ - if (optarg) { - char *command = alloc_printf("log_output %s", optarg); - command_run_line(cmd_ctx, command); - free(command); - } - break; - case 'c': /* --command | -c */ - if (optarg) - add_config_command(optarg); - break; - case 'p': - /* to replicate the old syntax this needs to be synchronous - * otherwise the gdb stdin will overflow with the warning message */ - command_run_line(cmd_ctx, "gdb_port pipe; log_output openocd.log"); - LOG_WARNING("deprecated option: -p/--pipe. Use '-c \"gdb_port pipe; " - "log_output openocd.log\"' instead."); - break; - } - } - - 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("--log_output | -l\tredirect log output to file \n"); - LOG_OUTPUT("--command | -c\trun \n"); - exit(-1); - } - - if (version_flag) { - /* Nothing to do, version gets printed automatically. */ - /* It is not an error to request the VERSION number. */ - exit(0); - } - - /* paths specified on the command line take precedence over these - * built-in paths - */ - add_default_dirs(); - - return ERROR_OK; -} diff --git a/src/helper/replacements.c b/src/helper/replacements.c deleted file mode 100644 index b4bb94f06..000000000 --- a/src/helper/replacements.c +++ /dev/null @@ -1,318 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2006 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * Copyright (C) 2007,2008 Øyvind Harboe * - * oyvind.harboe@zylin.com * - * * - * Copyright (C) 2008 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ -/* DANGER!!!! These must be defined *BEFORE* replacements.h and the malloc() macro!!!! */ - -#include -#include -/* - * clear_malloc - * - * will alloc memory and clear it - */ -void *clear_malloc(size_t size) -{ - void *t = malloc(size); - if (t != NULL) - memset(t, 0x00, size); - return t; -} - -void *fill_malloc(size_t size) -{ - void *t = malloc(size); - if (t != NULL) { - /* We want to initialize memory to some known bad state. - * 0 and 0xff yields 0 and -1 as integers, which often - * have meaningful values. 0x5555... is not often a valid - * integer and is quite easily spotted in the debugger - * also it is almost certainly an invalid address */ - memset(t, 0x55, size); - } - return t; -} - -#define IN_REPLACEMENTS_C -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif -#ifdef HAVE_STRINGS_H -#include -#endif - -#ifdef _WIN32 -#include -#endif - -/* replacements for gettimeofday */ -#ifndef HAVE_GETTIMEOFDAY - -/* Windows */ -#ifdef _WIN32 - -#ifndef __GNUC__ -#define EPOCHFILETIME (116444736000000000i64) -#else -#define EPOCHFILETIME (116444736000000000LL) -#endif - -int gettimeofday(struct timeval *tv, struct timezone *tz) -{ - FILETIME ft; - LARGE_INTEGER li; - __int64 t; - static int tzflag; - - if (tv) { - GetSystemTimeAsFileTime(&ft); - li.LowPart = ft.dwLowDateTime; - li.HighPart = ft.dwHighDateTime; - t = li.QuadPart; /* In 100-nanosecond intervals */ - t -= EPOCHFILETIME; /* Offset to the Epoch time */ - t /= 10; /* In microseconds */ - tv->tv_sec = (long)(t / 1000000); - tv->tv_usec = (long)(t % 1000000); - } - - if (tz) { - if (!tzflag) { - _tzset(); - tzflag++; - } - tz->tz_minuteswest = _timezone / 60; - tz->tz_dsttime = _daylight; - } - - return 0; -} -#endif /* _WIN32 */ - -#endif /* HAVE_GETTIMEOFDAY */ - -#ifndef HAVE_STRNLEN -size_t strnlen(const char *s, size_t maxlen) -{ - const char *end = (const char *)memchr(s, '\0', maxlen); - return end ? (size_t) (end - s) : maxlen; -} -#endif - -#ifndef HAVE_STRNDUP -char *strndup(const char *s, size_t n) -{ - size_t len = strnlen(s, n); - char *new = malloc(len + 1); - - if (new == NULL) - return NULL; - - new[len] = '\0'; - return (char *) memcpy(new, s, len); -} -#endif - -#ifdef _WIN32 -int win_select(int max_fd, fd_set *rfds, fd_set *wfds, fd_set *efds, struct timeval *tv) -{ - DWORD ms_total, limit; - HANDLE handles[MAXIMUM_WAIT_OBJECTS]; - int handle_slot_to_fd[MAXIMUM_WAIT_OBJECTS]; - int n_handles = 0, i; - fd_set sock_read, sock_write, sock_except; - fd_set aread, awrite, aexcept; - int sock_max_fd = -1; - struct timeval tvslice; - int retcode; - -#define SAFE_FD_ISSET(fd, set) (set != NULL && FD_ISSET(fd, set)) - - /* calculate how long we need to wait in milliseconds */ - if (tv == NULL) - ms_total = INFINITE; - else { - ms_total = tv->tv_sec * 1000; - ms_total += tv->tv_usec / 1000; - } - - FD_ZERO(&sock_read); - FD_ZERO(&sock_write); - FD_ZERO(&sock_except); - - /* build an array of handles for non-sockets */ - for (i = 0; i < max_fd; i++) { - if (SAFE_FD_ISSET(i, rfds) || SAFE_FD_ISSET(i, wfds) || SAFE_FD_ISSET(i, efds)) { - intptr_t handle = (intptr_t) _get_osfhandle(i); - handles[n_handles] = (HANDLE)handle; - if (handles[n_handles] == INVALID_HANDLE_VALUE) { - /* socket */ - if (SAFE_FD_ISSET(i, rfds)) - FD_SET(i, &sock_read); - if (SAFE_FD_ISSET(i, wfds)) - FD_SET(i, &sock_write); - if (SAFE_FD_ISSET(i, efds)) - FD_SET(i, &sock_except); - if (i > sock_max_fd) - sock_max_fd = i; - } else { - handle_slot_to_fd[n_handles] = i; - n_handles++; - } - } - } - - if (n_handles == 0) { - /* plain sockets only - let winsock handle the whole thing */ - return select(max_fd, rfds, wfds, efds, tv); - } - - /* mixture of handles and sockets; lets multiplex between - * winsock and waiting on the handles */ - - FD_ZERO(&aread); - FD_ZERO(&awrite); - FD_ZERO(&aexcept); - - limit = GetTickCount() + ms_total; - do { - retcode = 0; - - if (sock_max_fd >= 0) { - /* overwrite the zero'd sets here; the select call - * will clear those that are not active */ - aread = sock_read; - awrite = sock_write; - aexcept = sock_except; - - tvslice.tv_sec = 0; - tvslice.tv_usec = 1000; - - retcode = select(sock_max_fd + 1, &aread, &awrite, &aexcept, &tvslice); - } - - if (n_handles > 0) { - /* check handles */ - DWORD wret; - - wret = MsgWaitForMultipleObjects(n_handles, - handles, - FALSE, - retcode > 0 ? 0 : 1, - QS_ALLEVENTS); - - if (wret == WAIT_TIMEOUT) { - /* set retcode to 0; this is the default. - * select() may have set it to something else, - * in which case we leave it alone, so this branch - * does nothing */ - ; - } else if (wret == WAIT_FAILED) { - if (retcode == 0) - retcode = -1; - } else { - if (retcode < 0) - retcode = 0; - for (i = 0; i < n_handles; i++) { - if (WAIT_OBJECT_0 == WaitForSingleObject(handles[i], 0)) { - if (SAFE_FD_ISSET(handle_slot_to_fd[i], rfds)) { - DWORD dwBytes; - intptr_t handle = (intptr_t) _get_osfhandle( - handle_slot_to_fd[i]); - - if (PeekNamedPipe((HANDLE)handle, NULL, 0, - NULL, &dwBytes, NULL)) { - /* check to see if gdb pipe has data available */ - if (dwBytes) { - FD_SET(handle_slot_to_fd[i], &aread); - retcode++; - } - } else { - FD_SET(handle_slot_to_fd[i], &aread); - retcode++; - } - } - if (SAFE_FD_ISSET(handle_slot_to_fd[i], wfds)) { - FD_SET(handle_slot_to_fd[i], &awrite); - retcode++; - } - if (SAFE_FD_ISSET(handle_slot_to_fd[i], efds)) { - FD_SET(handle_slot_to_fd[i], &aexcept); - retcode++; - } - } - } - } - } - } while (retcode == 0 && (ms_total == INFINITE || GetTickCount() < limit)); - - if (rfds) - *rfds = aread; - if (wfds) - *wfds = awrite; - if (efds) - *efds = aexcept; - - return retcode; -} -#endif - -#if defined HAVE_LIBUSB1 && !defined HAVE_LIBUSB_ERROR_NAME -#include -/* Verbatim from git://git.libusb.org/libusb.git tag 1.0.9 - * The libusb_error enum is compatible down to v0.9.1 - */ -const char *libusb_error_name(int error_code) -{ - enum libusb_error error = error_code; - switch (error) { - case LIBUSB_SUCCESS: - return "LIBUSB_SUCCESS"; - case LIBUSB_ERROR_IO: - return "LIBUSB_ERROR_IO"; - case LIBUSB_ERROR_INVALID_PARAM: - return "LIBUSB_ERROR_INVALID_PARAM"; - case LIBUSB_ERROR_ACCESS: - return "LIBUSB_ERROR_ACCESS"; - case LIBUSB_ERROR_NO_DEVICE: - return "LIBUSB_ERROR_NO_DEVICE"; - case LIBUSB_ERROR_NOT_FOUND: - return "LIBUSB_ERROR_NOT_FOUND"; - case LIBUSB_ERROR_BUSY: - return "LIBUSB_ERROR_BUSY"; - case LIBUSB_ERROR_TIMEOUT: - return "LIBUSB_ERROR_TIMEOUT"; - case LIBUSB_ERROR_OVERFLOW: - return "LIBUSB_ERROR_OVERFLOW"; - case LIBUSB_ERROR_PIPE: - return "LIBUSB_ERROR_PIPE"; - case LIBUSB_ERROR_INTERRUPTED: - return "LIBUSB_ERROR_INTERRUPTED"; - case LIBUSB_ERROR_NO_MEM: - return "LIBUSB_ERROR_NO_MEM"; - case LIBUSB_ERROR_NOT_SUPPORTED: - return "LIBUSB_ERROR_NOT_SUPPORTED"; - case LIBUSB_ERROR_OTHER: - return "LIBUSB_ERROR_OTHER"; - } - return "**UNKNOWN**"; -} -#endif diff --git a/src/helper/replacements.h b/src/helper/replacements.h deleted file mode 100644 index 1e2fbf20f..000000000 --- a/src/helper/replacements.h +++ /dev/null @@ -1,283 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2006 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * Copyright (C) 2007,2008 Øyvind Harboe * - * oyvind.harboe@zylin.com * - * * - * Copyright (C) 2008 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 OPENOCD_HELPER_REPLACEMENTS_H -#define OPENOCD_HELPER_REPLACEMENTS_H - -/* MIN,MAX macros */ -#ifndef MIN -#define MIN(a, b) (((a) < (b)) ? (a) : (b)) -#endif -#ifndef MAX -#define MAX(a, b) (((a) > (b)) ? (a) : (b)) -#endif - -/* for systems that do not support ENOTSUP - * win32 being one of them */ -#ifndef ENOTSUP -#define ENOTSUP 134 /* Not supported */ -#endif - -/* for systems that do not support O_BINARY - * linux being one of them */ -#ifndef O_BINARY -#define O_BINARY 0 -#endif - -#ifndef HAVE_SYS_TIME_H - -#ifndef _TIMEVAL_DEFINED -#define _TIMEVAL_DEFINED - -struct timeval { - long tv_sec; - long tv_usec; -}; - -#endif /* _TIMEVAL_DEFINED */ - -#endif - -/* gettimeofday() */ -#ifndef HAVE_GETTIMEOFDAY - -#ifdef _WIN32 -struct timezone { - int tz_minuteswest; - int tz_dsttime; -}; -#endif -struct timezone; - -int gettimeofday(struct timeval *tv, struct timezone *tz); - -#endif - -#ifndef IN_REPLACEMENTS_C -/**** clear_malloc & fill_malloc ****/ -void *clear_malloc(size_t size); -void *fill_malloc(size_t size); -#endif - -/* - * Now you have 3 ways for the malloc function: - * - * 1. Do not change anything, use the original malloc - * - * 2. Use the clear_malloc function instead of the original malloc. - * In this case you must use the following define: - * #define malloc((_a)) clear_malloc((_a)) - * - * 3. Use the fill_malloc function instead of the original malloc. - * In this case you must use the following define: - * #define malloc((_a)) fill_malloc((_a)) - * - * We have figured out that there could exist some malloc problems - * where variables are using without to be initialise. To find this - * places, use the fill_malloc function. With this function we want - * to initialize memory to some known bad state. This is quite easily - * spotted in the debugger and will trap to an invalid address. - * - * clear_malloc can be used if you want to set not initialise - * variable to 0. - * - * If you do not want to change the malloc function, to not use one of - * the following macros. Which is the default way. - */ - -/* #define malloc(_a) clear_malloc(_a) - * #define malloc(_a) fill_malloc(_a) */ - -/* GNU extensions to the C library that may be missing on some systems */ -#ifndef HAVE_STRNDUP -char *strndup(const char *s, size_t n); -#endif /* HAVE_STRNDUP */ - -#ifndef HAVE_STRNLEN -size_t strnlen(const char *s, size_t maxlen); -#endif /* HAVE_STRNLEN */ - -#ifndef HAVE_USLEEP -#ifdef _WIN32 -static inline unsigned usleep(unsigned int usecs) -{ - Sleep((usecs/1000)); - return 0; -} -#else -#error no usleep defined for your platform -#endif -#endif /* HAVE_USLEEP */ - -/* Windows specific */ -#ifdef _WIN32 - -#include -#include - -/* Windows does not declare sockaddr_un */ -#define UNIX_PATH_LEN 108 -struct sockaddr_un { - uint16_t sun_family; - char sun_path[UNIX_PATH_LEN]; -}; - -/* win32 systems do not support ETIMEDOUT */ - -#ifndef ETIMEDOUT -#define ETIMEDOUT WSAETIMEDOUT -#endif - -#if IS_MINGW == 1 -static inline unsigned char inb(unsigned short int port) -{ - unsigned char _v; - __asm__ __volatile__ ("inb %w1,%0" : "=a" (_v) : "Nd" (port)); - return _v; -} - -static inline void outb(unsigned char value, unsigned short int port) -{ - __asm__ __volatile__ ("outb %b0,%w1" : : "a" (value), "Nd" (port)); -} - -/* mingw does not have ffs, so use gcc builtin types */ -#define ffs __builtin_ffs - -#endif /* IS_MINGW */ - -int win_select(int max_fd, fd_set *rfds, fd_set *wfds, fd_set *efds, struct timeval *tv); - -#endif /* _WIN32 */ - -/* generic socket functions for Windows and Posix */ -static inline int write_socket(int handle, const void *buffer, unsigned int count) -{ -#ifdef _WIN32 - return send(handle, buffer, count, 0); -#else - return write(handle, buffer, count); -#endif -} - -static inline int read_socket(int handle, void *buffer, unsigned int count) -{ -#ifdef _WIN32 - return recv(handle, buffer, count, 0); -#else - return read(handle, buffer, count); -#endif -} - -static inline int close_socket(int sock) -{ -#ifdef _WIN32 - return closesocket(sock); -#else - return close(sock); -#endif -} - -static inline void socket_nonblock(int fd) -{ -#ifdef _WIN32 - unsigned long nonblock = 1; - ioctlsocket(fd, FIONBIO, &nonblock); -#else - int oldopts = fcntl(fd, F_GETFL, 0); - fcntl(fd, F_SETFL, oldopts | O_NONBLOCK); -#endif -} - -static inline int socket_select(int max_fd, - fd_set *rfds, - fd_set *wfds, - fd_set *efds, - struct timeval *tv) -{ -#ifdef _WIN32 - return win_select(max_fd, rfds, wfds, efds, tv); -#else - return select(max_fd, rfds, wfds, efds, tv); -#endif -} - -#ifndef HAVE_ELF_H - -typedef uint32_t Elf32_Addr; -typedef uint16_t Elf32_Half; -typedef uint32_t Elf32_Off; -typedef int32_t Elf32_Sword; -typedef uint32_t Elf32_Word; -typedef uint32_t Elf32_Size; -typedef Elf32_Off Elf32_Hashelt; - -typedef struct { - unsigned char e_ident[16]; /* Magic number and other info */ - Elf32_Half e_type; /* Object file type */ - Elf32_Half e_machine; /* Architecture */ - Elf32_Word e_version; /* Object file version */ - Elf32_Addr e_entry; /* Entry point virtual address */ - Elf32_Off e_phoff; /* Program header table file offset */ - Elf32_Off e_shoff; /* Section header table file offset */ - Elf32_Word e_flags; /* Processor-specific flags */ - Elf32_Half e_ehsize; /* ELF header size in bytes */ - Elf32_Half e_phentsize; /* Program header table entry size */ - Elf32_Half e_phnum; /* Program header table entry count */ - Elf32_Half e_shentsize; /* Section header table entry size */ - Elf32_Half e_shnum; /* Section header table entry count */ - Elf32_Half e_shstrndx; /* Section header string table index */ -} Elf32_Ehdr; - -#define ELFMAG "\177ELF" -#define SELFMAG 4 - -#define EI_CLASS 4 /* File class byte index */ -#define ELFCLASS32 1 /* 32-bit objects */ -#define ELFCLASS64 2 /* 64-bit objects */ - -#define EI_DATA 5 /* Data encoding byte index */ -#define ELFDATA2LSB 1 /* 2's complement, little endian */ -#define ELFDATA2MSB 2 /* 2's complement, big endian */ - -typedef struct { - Elf32_Word p_type; /* Segment type */ - Elf32_Off p_offset; /* Segment file offset */ - Elf32_Addr p_vaddr; /* Segment virtual address */ - Elf32_Addr p_paddr; /* Segment physical address */ - Elf32_Size p_filesz; /* Segment size in file */ - Elf32_Size p_memsz; /* Segment size in memory */ - Elf32_Word p_flags; /* Segment flags */ - Elf32_Size p_align; /* Segment alignment */ -} Elf32_Phdr; - -#define PT_LOAD 1 /* Loadable program segment */ - -#endif /* HAVE_ELF_H */ - -#if defined HAVE_LIBUSB1 && !defined HAVE_LIBUSB_ERROR_NAME -const char *libusb_error_name(int error_code); -#endif /* defined HAVE_LIBUSB1 && !defined HAVE_LIBUSB_ERROR_NAME */ - -#endif /* OPENOCD_HELPER_REPLACEMENTS_H */ diff --git a/src/helper/startup.tcl b/src/helper/startup.tcl deleted file mode 100644 index 4ca2cabc2..000000000 --- a/src/helper/startup.tcl +++ /dev/null @@ -1,66 +0,0 @@ -# Defines basic Tcl procs that must exist for OpenOCD scripts to work. -# -# Embedded into OpenOCD executable -# - - -# We need to explicitly redirect this to the OpenOCD command -# as Tcl defines the exit proc -proc exit {} { - ocd_throw exit -} - -# All commands are registered with an 'ocd_' prefix, while the "real" -# command is a wrapper that calls this function. Its primary purpose is -# to discard 'handler' command output, -proc ocd_bouncer {name args} { - set cmd [format "ocd_%s" $name] - set type [eval ocd_command type $cmd $args] - set errcode error - if {$type == "native"} { - return [eval $cmd $args] - } else {if {$type == "simple"} { - set errcode [catch {eval $cmd $args}] - if {$errcode == 0} { - return "" - } else { - # 'classic' commands output error message as part of progress output - set errmsg "" - } - } else {if {$type == "group"} { - catch {eval ocd_usage $name $args} - set errmsg [format "%s: command requires more arguments" \ - [concat $name " " $args]] - } else { - set errmsg [format "invalid subcommand \"%s\"" $args] - }}} - return -code $errcode $errmsg -} - -# Try flipping / and \ to find file if the filename does not -# match the precise spelling -proc find {filename} { - if {[catch {ocd_find $filename} t]==0} { - return $t - } - if {[catch {ocd_find [string map {\ /} $filename} t]==0} { - return $t - } - if {[catch {ocd_find [string map {/ \\} $filename} t]==0} { - return $t - } - # make sure error message matches original input string - return -code error "Can't find $filename" -} -add_usage_text find "" -add_help_text find "print full path to file according to OpenOCD search rules" - -# Find and run a script -proc script {filename} { - uplevel #0 [list source [find $filename]] -} -add_help_text script "filename of OpenOCD script (tcl) to run" -add_usage_text script "" - -######### - diff --git a/src/helper/system.h b/src/helper/system.h deleted file mode 100644 index 97b3443be..000000000 --- a/src/helper/system.h +++ /dev/null @@ -1,89 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2006 by Dominic Rath * - * Copyright (C) 2007-2008 by Øyvind Harboe * - * Copyright (C) 2008 by Spencer Oliver * - * Copyright (C) 2009 by Zachary T Welch * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 OPENOCD_HELPER_SYSTEM_H -#define OPENOCD_HELPER_SYSTEM_H - -/* standard C library header files */ -#include -#include -#include -#include -#include -#include - -/* +++ AC_HEADER_TIME +++ */ -#ifdef TIME_WITH_SYS_TIME -# include -# include -#else -# ifdef HAVE_SYS_TIME_H -# include -# else -# include -# endif -#endif -/* --- AC_HEADER_TIME --- */ - -/* +++ platform specific headers +++ */ -#ifdef _WIN32 -#include -#include -#include -#include -#endif -/* --- platform specific headers --- */ - -#ifdef HAVE_SYS_SOCKET_H -#include -#endif -#ifdef HAVE_POLL_H -#include -#endif - -#ifdef __ECOS -/* missing from eCos */ -#ifndef EFAULT -#define EFAULT 14 /* Bad address */ -#endif -#endif - -#ifdef HAVE_NETINET_IN_H -#include -#endif -#ifdef HAVE_SYS_SELECT_H -#include /* select, FD_SET and friends (POSIX.1-2001) */ -#endif -#ifdef HAVE_SYS_PARAM_H -#include /* for MIN/MAX macros */ -#endif -#ifdef HAVE_UNISTD_H -#include -#endif -#ifdef HAVE_FCNTL_H -#include -#endif - -#ifndef true -#define true 1 -#define false 0 -#endif - -#endif /* OPENOCD_HELPER_SYSTEM_H */ diff --git a/src/helper/time_support.c b/src/helper/time_support.c deleted file mode 100644 index 8337e73ba..000000000 --- a/src/helper/time_support.c +++ /dev/null @@ -1,89 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2006 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * Copyright (C) 2007,2008 Øyvind Harboe * - * oyvind.harboe@zylin.com * - * * - * Copyright (C) 2008 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 -#include "config.h" -#endif - -#include "time_support.h" - -/* calculate difference between two struct timeval values */ -int timeval_subtract(struct timeval *result, struct timeval *x, struct timeval *y) -{ - if (x->tv_usec < y->tv_usec) { - int nsec = (y->tv_usec - x->tv_usec) / 1000000 + 1; - y->tv_usec -= 1000000 * nsec; - y->tv_sec += nsec; - } - if (x->tv_usec - y->tv_usec > 1000000) { - int nsec = (x->tv_usec - y->tv_usec) / 1000000; - y->tv_usec += 1000000 * nsec; - y->tv_sec -= nsec; - } - - result->tv_sec = x->tv_sec - y->tv_sec; - result->tv_usec = x->tv_usec - y->tv_usec; - - /* Return 1 if result is negative. */ - return x->tv_sec < y->tv_sec; -} - -int timeval_add_time(struct timeval *result, long sec, long usec) -{ - result->tv_sec += sec; - result->tv_usec += usec; - - while (result->tv_usec > 1000000) { - result->tv_usec -= 1000000; - result->tv_sec++; - } - - return 0; -} - -int duration_start(struct duration *duration) -{ - return gettimeofday(&duration->start, NULL); -} - -int duration_measure(struct duration *duration) -{ - struct timeval end; - int retval = gettimeofday(&end, NULL); - if (0 == retval) - timeval_subtract(&duration->elapsed, &end, &duration->start); - return retval; -} - -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(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 deleted file mode 100644 index 58c8c48bb..000000000 --- a/src/helper/time_support.h +++ /dev/null @@ -1,60 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2006 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * Copyright (C) 2007,2008 Øyvind Harboe * - * oyvind.harboe@zylin.com * - * * - * Copyright (C) 2008 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 OPENOCD_HELPER_TIME_SUPPORT_H -#define OPENOCD_HELPER_TIME_SUPPORT_H - -#ifdef TIME_WITH_SYS_TIME -# include -# include -#else -# ifdef HAVE_SYS_TIME_H -# include -# else -# include -# endif -#endif - -int timeval_subtract(struct timeval *result, struct timeval *x, struct timeval *y); -int timeval_add_time(struct timeval *result, long sec, long usec); - -/** @returns gettimeofday() timeval as 64-bit in ms */ -int64_t timeval_ms(void); - -struct duration { - struct timeval start; - struct timeval elapsed; -}; - -/** Update the duration->start field to start the @a duration measurement. */ -int duration_start(struct duration *duration); -/** Update the duration->elapsed field to finish the @a duration measurment. */ -int duration_measure(struct duration *duration); - -/** @returns Elapsed time in seconds. */ -float duration_elapsed(const struct duration *duration); -/** @returns KB/sec for the elapsed @a duration and @a count bytes. */ -float duration_kbps(const struct duration *duration, size_t count); - -#endif /* OPENOCD_HELPER_TIME_SUPPORT_H */ diff --git a/src/helper/time_support_common.c b/src/helper/time_support_common.c deleted file mode 100644 index b733c270e..000000000 --- a/src/helper/time_support_common.c +++ /dev/null @@ -1,41 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2006 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * Copyright (C) 2007,2008 Øyvind Harboe * - * oyvind.harboe@zylin.com * - * * - * Copyright (C) 2008 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 -#include "config.h" -#endif - -#include "time_support.h" - -/* simple and low overhead fetching of ms counter. Use only - * the difference between ms counters returned from this fn. - */ -int64_t timeval_ms(void) -{ - struct timeval now; - int retval = gettimeofday(&now, NULL); - if (retval < 0) - return retval; - return (int64_t)now.tv_sec * 1000 + now.tv_usec / 1000; -} diff --git a/src/helper/types.h b/src/helper/types.h deleted file mode 100644 index 1854ba85b..000000000 --- a/src/helper/types.h +++ /dev/null @@ -1,340 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2004, 2005 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * Copyright (C) 2007,2008 Øyvind Harboe * - * oyvind.harboe@zylin.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifndef OPENOCD_HELPER_TYPES_H -#define OPENOCD_HELPER_TYPES_H - -#include -#ifdef HAVE_SYS_TYPES_H -#include -#endif -#ifdef HAVE_STDINT_H -#include -#endif -#ifdef HAVE_INTTYPES_H -#include -#endif - -#ifdef HAVE_STDBOOL_H -#include -#else /* HAVE_STDBOOL_H */ -#define __bool_true_false_are_defined 1 - -#ifndef HAVE__BOOL -#ifndef __cplusplus - -#define false 0 -#define true 1 - -typedef int _Bool; -#else -typedef bool _Bool; -#endif /* __cplusplus */ -#endif /* HAVE__BOOL */ - -#define bool _Bool - -#endif /* HAVE_STDBOOL_H */ - -/// turns a macro argument into a string constant -#define stringify(s) __stringify(s) -#define __stringify(s) #s - - -/** - * Compute the number of elements of a variable length array. - * - * const char *strs[] = { "a", "b", "c" }; - * unsigned num_strs = ARRAY_SIZE(strs); - * - */ -#define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x))) - - -/** - * Cast a member of a structure out to the containing structure. - * @param ptr The pointer to the member. - * @param type The type of the container struct this is embedded in. - * @param member The name of the member within the struct. - * - * This is a mechanism which is used throughout the Linux kernel. - */ -#define container_of(ptr, type, member) ({ \ - const typeof( ((type *)0)->member ) *__mptr = (ptr); \ - (type *)( (void *) ( (char *)__mptr - offsetof(type,member) ) );}) - - -/** - * Rounds @c m up to the nearest multiple of @c n using division. - * @param m The value to round up to @c n. - * @param n Round @c m up to a multiple of this number. - * @returns The rounded integer value. - */ -#define DIV_ROUND_UP(m, n) (((m) + (n) - 1) / (n)) - - -/* DANGER!!!! here be dragons! - * - * Leave these fn's as byte accesses because it is safe - * across architectures. Clever usage of 32 bit access - * will create problems on some hosts. - * - * Note that the "buf" pointer in memory is probably unaligned. - * - * Were these functions to be re-written to take a 32 bit wide or 16 bit wide - * memory access shortcut, then on some CPU's, i.e. ARM7, the 2 lsbytes of the address are - * ignored for 32 bit access, whereas on other CPU's a 32 bit wide unaligned memory access - * will cause an exception, and lastly on x86, an unaligned "greater than bytewide" - * memory access works as if aligned. So what follows below will work for all - * platforms and gives the compiler leeway to do its own platform specific optimizations. - * - * Again, note that the "buf" pointer in memory is probably unaligned. - */ - -static inline uint64_t le_to_h_u64(const uint8_t *buf) -{ - return (uint64_t)((uint64_t)buf[0] | - (uint64_t)buf[1] << 8 | - (uint64_t)buf[2] << 16 | - (uint64_t)buf[3] << 24 | - (uint64_t)buf[4] << 32 | - (uint64_t)buf[5] << 40 | - (uint64_t)buf[6] << 48 | - (uint64_t)buf[7] << 56); -} - -static inline uint32_t le_to_h_u32(const uint8_t* buf) -{ - return (uint32_t)(buf[0] | buf[1] << 8 | buf[2] << 16 | buf[3] << 24); -} - -static inline uint32_t le_to_h_u24(const uint8_t* buf) -{ - return (uint32_t)(buf[0] | buf[1] << 8 | buf[2] << 16); -} - -static inline uint16_t le_to_h_u16(const uint8_t* buf) -{ - return (uint16_t)(buf[0] | buf[1] << 8); -} - -static inline uint64_t be_to_h_u64(const uint8_t *buf) -{ - return (uint64_t)((uint64_t)buf[7] | - (uint64_t)buf[6] << 8 | - (uint64_t)buf[5] << 16 | - (uint64_t)buf[4] << 24 | - (uint64_t)buf[3] << 32 | - (uint64_t)buf[2] << 40 | - (uint64_t)buf[1] << 48 | - (uint64_t)buf[0] << 56); -} - -static inline uint32_t be_to_h_u32(const uint8_t* buf) -{ - return (uint32_t)(buf[3] | buf[2] << 8 | buf[1] << 16 | buf[0] << 24); -} - -static inline uint32_t be_to_h_u24(const uint8_t* buf) -{ - return (uint32_t)(buf[2] | buf[1] << 8 | buf[0] << 16); -} - -static inline uint16_t be_to_h_u16(const uint8_t* buf) -{ - return (uint16_t)(buf[1] | buf[0] << 8); -} - -static inline void h_u64_to_le(uint8_t *buf, int64_t val) -{ - buf[7] = (uint8_t) (val >> 56); - buf[6] = (uint8_t) (val >> 48); - buf[5] = (uint8_t) (val >> 40); - buf[4] = (uint8_t) (val >> 32); - buf[3] = (uint8_t) (val >> 24); - buf[2] = (uint8_t) (val >> 16); - buf[1] = (uint8_t) (val >> 8); - buf[0] = (uint8_t) (val >> 0); -} - -static inline void h_u64_to_be(uint8_t *buf, int64_t val) -{ - buf[0] = (uint8_t) (val >> 56); - buf[1] = (uint8_t) (val >> 48); - buf[2] = (uint8_t) (val >> 40); - buf[3] = (uint8_t) (val >> 32); - buf[4] = (uint8_t) (val >> 24); - buf[5] = (uint8_t) (val >> 16); - buf[6] = (uint8_t) (val >> 8); - buf[7] = (uint8_t) (val >> 0); -} - -static inline void h_u32_to_le(uint8_t* buf, int val) -{ - buf[3] = (uint8_t) (val >> 24); - buf[2] = (uint8_t) (val >> 16); - buf[1] = (uint8_t) (val >> 8); - buf[0] = (uint8_t) (val >> 0); -} - -static inline void h_u32_to_be(uint8_t* buf, int val) -{ - buf[0] = (uint8_t) (val >> 24); - buf[1] = (uint8_t) (val >> 16); - buf[2] = (uint8_t) (val >> 8); - buf[3] = (uint8_t) (val >> 0); -} - -static inline void h_u24_to_le(uint8_t* buf, int val) -{ - buf[2] = (uint8_t) (val >> 16); - buf[1] = (uint8_t) (val >> 8); - buf[0] = (uint8_t) (val >> 0); -} - -static inline void h_u24_to_be(uint8_t* buf, int val) -{ - buf[0] = (uint8_t) (val >> 16); - buf[1] = (uint8_t) (val >> 8); - buf[2] = (uint8_t) (val >> 0); -} - -static inline void h_u16_to_le(uint8_t* buf, int val) -{ - buf[1] = (uint8_t) (val >> 8); - buf[0] = (uint8_t) (val >> 0); -} - -static inline void h_u16_to_be(uint8_t* buf, int val) -{ - buf[0] = (uint8_t) (val >> 8); - buf[1] = (uint8_t) (val >> 0); -} - -/** - * Byte-swap buffer 16-bit. - * - * Len must be even, dst and src must be either the same or non-overlapping. - * - * @param dst Destination buffer. - * @param src Source buffer. - * @param len Length of source (and destination) buffer, in bytes. - */ -static inline void buf_bswap16(uint8_t *dst, const uint8_t *src, size_t len) -{ - assert(len % 2 == 0); - assert(dst == src || dst + len <= src || src + len <= dst); - - for (size_t n = 0; n < len; n += 2) { - uint16_t x = be_to_h_u16(src + n); - h_u16_to_le(dst + n, x); - } -} - -/** - * Byte-swap buffer 32-bit. - * - * Len must be divisible by four, dst and src must be either the same or non-overlapping. - * - * @param dst Destination buffer. - * @param src Source buffer. - * @param len Length of source (and destination) buffer, in bytes. - */ -static inline void buf_bswap32(uint8_t *dst, const uint8_t *src, size_t len) -{ - assert(len % 4 == 0); - assert(dst == src || dst + len <= src || src + len <= dst); - - for (size_t n = 0; n < len; n += 4) { - uint32_t x = be_to_h_u32(src + n); - h_u32_to_le(dst + n, x); - } -} - -/** - * Calculate the (even) parity of a 32-bit datum. - * @param x The datum. - * @return 1 if the number of set bits in x is odd, 0 if it is even. - */ -static inline int parity_u32(uint32_t x) -{ -#ifdef __GNUC__ - return __builtin_parityl(x); -#else - x ^= x >> 16; - x ^= x >> 8; - x ^= x >> 4; - x ^= x >> 2; - x ^= x >> 1; - return x & 1; -#endif -} - -#if defined(__ECOS) - -/* eCos plain lacks these definition... A series of upstream patches - * could probably repair it, but it seems like too much work to be - * worth it. - */ - -#if !defined(_STDINT_H) -#define PRIx32 "x" -#define PRId32 "d" -#define SCNx32 "x" -#define PRIi32 "i" -#define PRIu32 "u" -#define PRId8 PRId32 -#define SCNx64 "llx" -#define PRIx64 "llx" - -typedef CYG_ADDRWORD intptr_t; -typedef int64_t intmax_t; -typedef uint64_t uintmax_t; -#define INT8_MAX 0x7f -#define INT8_MIN (-INT8_MAX - 1) -# define UINT8_MAX (255) -#define INT16_MAX 0x7fff -#define INT16_MIN (-INT16_MAX - 1) -# define UINT16_MAX (65535) -#define INT32_MAX 0x7fffffffL -#define INT32_MIN (-INT32_MAX - 1L) -# define UINT32_MAX (4294967295U) -#define INT64_MAX 0x7fffffffffffffffLL -#define INT64_MIN (-INT64_MAX - 1LL) -#define UINT64_MAX (__CONCAT(INT64_MAX, U) * 2ULL + 1ULL) -#endif - - #ifndef LLONG_MAX - #define ULLONG_MAX UINT64_C(0xFFFFFFFFFFFFFFFF) - #define LLONG_MAX INT64_C(0x7FFFFFFFFFFFFFFF) - #define LLONG_MIN ULLONG_MAX - #endif - - -#define ULLONG_MAX 18446744073709551615 - -/* C99, eCos is C90 compliant (with bits of C99) */ -#define isblank(c) ((c) == ' ' || (c) == '\t') - - -#endif - -#endif /* OPENOCD_HELPER_TYPES_H */ diff --git a/src/helper/update_jep106.pl b/src/helper/update_jep106.pl deleted file mode 100755 index caec0664f..000000000 --- a/src/helper/update_jep106.pl +++ /dev/null @@ -1,35 +0,0 @@ -#!/usr/bin/perl -use strict; -use warnings; -use File::Basename; - -if (@ARGV != 1) { - die "Usage: $0 \n\n" - . "Convert the JEDEC document containing manufacturer identification codes\n" - . "to an array initializer suitable for incusion into jep106.c. The latest\n" - . "version of the document can be found here:\n" - . "http://www.jedec.org/standards-documents/results/jep106\n"; -}; - -my $outfile = dirname($0) . "/jep106.inc"; - -open(my $out, ">", $outfile) || die "Cannot open $outfile: $!\n"; -open(my $pdftotext, "pdftotext -layout $ARGV[0] - |") || die "Cannot fork: $!\n"; - -print $out "/* Autogenerated with " . basename($0) . "*/\n"; - -my $bank = -1; - -while (<$pdftotext>) { - if (/^[0-9]+[[:space:]]+(.*?)[[:space:]]+([01][[:space:]]+){8}([0-9A-F]{2})$/) { - if ($3 eq "01") { - $bank++ - } - my $id=sprintf("0x%02x",hex($3)&0x7f); - print $out "[$bank][$id - 1] = \"$1\",\n"; - } -} - -close $pdftotext || die "Error: $! $?\n"; - -print $out "/* EOF */\n"; diff --git a/src/helper/util.c b/src/helper/util.c deleted file mode 100644 index 56baf95d1..000000000 --- a/src/helper/util.c +++ /dev/null @@ -1,59 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2010 by Øyvind Harboe * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -/* this file contains various functionality useful to standalone systems */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "log.h" -#include "time_support.h" - -static int util_Jim_Command_ms(Jim_Interp *interp, - int argc, - Jim_Obj * const *argv) -{ - if (argc != 1) { - Jim_WrongNumArgs(interp, 1, argv, "ls ?dir?"); - return JIM_ERR; - } - - /* Cast from 64 to 32 bit int works for 2's-compliment - * when calculating differences*/ - Jim_SetResult(interp, Jim_NewIntObj(interp, (int)timeval_ms())); - - return JIM_OK; -} - -static const struct command_registration util_command_handlers[] = { - /* jim handlers */ - { - .name = "ms", - .mode = COMMAND_ANY, - .jim_handler = util_Jim_Command_ms, - .help = - "Returns ever increasing milliseconds. Used to calculuate differences in time.", - .usage = "", - }, - COMMAND_REGISTRATION_DONE -}; - -int util_init(struct command_context *cmd_ctx) -{ - return register_commands(cmd_ctx, NULL, util_command_handlers); -} diff --git a/src/helper/util.h b/src/helper/util.h deleted file mode 100644 index c9a11ddac..000000000 --- a/src/helper/util.h +++ /dev/null @@ -1,25 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2010 by Øyvind Harboe * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifndef OPENOCD_HELPER_UTIL_H -#define OPENOCD_HELPER_UTIL_H - -struct command_context; - -int util_init(struct command_context *cmd_ctx); - -#endif /* OPENOCD_HELPER_UTIL_H */ diff --git a/src/jtag/Makefile.am b/src/jtag/Makefile.am deleted file mode 100644 index db3e6ff2a..000000000 --- a/src/jtag/Makefile.am +++ /dev/null @@ -1,86 +0,0 @@ -include $(top_srcdir)/common.mk - -METASOURCES = AUTO -noinst_LTLIBRARIES = libjtag.la - -SUBDIRS = -DRIVERFILES = -libjtag_la_LIBADD = - -CLEANFILES = - -BUILT_SOURCES = - -BUILT_SOURCES += minidriver_imp.h -CLEANFILES += minidriver_imp.h - -if MINIDRIVER - -if ZY1000 -DRIVERFILES += zy1000/zy1000.c -JTAG_MINIDRIVER_DIR = $(srcdir)/zy1000 -endif -if MINIDRIVER_DUMMY -DRIVERFILES += minidummy/minidummy.c commands.c -JTAG_MINIDRIVER_DIR = $(srcdir)/minidummy -endif - -MINIDRIVER_IMP_DIR = $(srcdir)/minidriver - -jtag_minidriver.h: $(JTAG_MINIDRIVER_DIR)/jtag_minidriver.h - cp $< $@ - -BUILT_SOURCES += jtag_minidriver.h - -CLEANFILES += jtag_minidriver.h - -else - -MINIDRIVER_IMP_DIR = $(srcdir)/drivers -DRIVERFILES += commands.c - -if HLADAPTER -SUBDIRS += hla -libjtag_la_LIBADD += $(top_builddir)/src/jtag/hla/libocdhla.la -endif - -if AICE -SUBDIRS += aice -libjtag_la_LIBADD += $(top_builddir)/src/jtag/aice/libocdaice.la -endif - -SUBDIRS += drivers -libjtag_la_LIBADD += $(top_builddir)/src/jtag/drivers/libocdjtagdrivers.la - - -endif - -# endif // MINIDRIVER - -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 diff --git a/src/jtag/adapter.c b/src/jtag/adapter.c deleted file mode 100644 index 5953de7e5..000000000 --- a/src/jtag/adapter.c +++ /dev/null @@ -1,535 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * Copyright (C) 2007-2010 Øyvind Harboe * - * oyvind.harboe@zylin.com * - * * - * Copyright (C) 2009 SoftPLC Corporation * - * http://softplc.com * - * dick@softplc.com * - * * - * Copyright (C) 2009 Zachary T Welch * - * zw@superlucidity.net * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "jtag.h" -#include "minidriver.h" -#include "interface.h" -#include "interfaces.h" -#include - -#ifdef HAVE_STRINGS_H -#include -#endif - -/** - * @file - * Holds support for configuring debug adapters from TCl scripts. - */ - -extern struct jtag_interface *jtag_interface; -const char * const jtag_only[] = { "jtag", NULL }; - -static int jim_adapter_name(Jim_Interp *interp, int argc, Jim_Obj * const *argv) -{ - Jim_GetOptInfo goi; - Jim_GetOpt_Setup(&goi, interp, argc-1, argv + 1); - - /* return the name of the interface */ - /* TCL code might need to know the exact type... */ - /* FUTURE: we allow this as a means to "set" the interface. */ - if (goi.argc != 0) { - Jim_WrongNumArgs(goi.interp, 1, goi.argv-1, "(no params)"); - return JIM_ERR; - } - const char *name = jtag_interface ? jtag_interface->name : NULL; - Jim_SetResultString(goi.interp, name ? : "undefined", -1); - return JIM_OK; -} - -static int default_khz(int khz, int *jtag_speed) -{ - LOG_ERROR("Translation from khz to jtag_speed not implemented"); - return ERROR_FAIL; -} - -static int default_speed_div(int speed, int *khz) -{ - LOG_ERROR("Translation from jtag_speed to khz not implemented"); - return ERROR_FAIL; -} - -static int default_power_dropout(int *dropout) -{ - *dropout = 0; /* by default we can't detect power dropout */ - return ERROR_OK; -} - -static int default_srst_asserted(int *srst_asserted) -{ - *srst_asserted = 0; /* by default we can't detect srst asserted */ - return ERROR_OK; -} - -COMMAND_HANDLER(interface_transport_command) -{ - char **transports; - int retval; - - retval = CALL_COMMAND_HANDLER(transport_list_parse, &transports); - if (retval != ERROR_OK) - return retval; - - retval = allow_transports(CMD_CTX, (const char **)transports); - - if (retval != ERROR_OK) { - for (unsigned i = 0; transports[i]; i++) - free(transports[i]); - free(transports); - } - return retval; -} - -COMMAND_HANDLER(handle_interface_list_command) -{ - if (strcmp(CMD_NAME, "interface_list") == 0 && CMD_ARGC > 0) - return ERROR_COMMAND_SYNTAX_ERROR; - - command_print(CMD_CTX, "The following debug interfaces are available:"); - for (unsigned i = 0; NULL != jtag_interfaces[i]; i++) { - const char *name = jtag_interfaces[i]->name; - command_print(CMD_CTX, "%u: %s", i + 1, name); - } - - return ERROR_OK; -} - -COMMAND_HANDLER(handle_interface_command) -{ - int retval; - - /* check whether the interface is already configured */ - if (jtag_interface) { - LOG_WARNING("Interface already configured, ignoring"); - return ERROR_OK; - } - - /* interface name is a mandatory argument */ - if (CMD_ARGC != 1 || CMD_ARGV[0][0] == '\0') - return ERROR_COMMAND_SYNTAX_ERROR; - - for (unsigned i = 0; NULL != jtag_interfaces[i]; i++) { - if (strcmp(CMD_ARGV[0], jtag_interfaces[i]->name) != 0) - continue; - - if (NULL != jtag_interfaces[i]->commands) { - retval = register_commands(CMD_CTX, NULL, - jtag_interfaces[i]->commands); - if (ERROR_OK != retval) - return retval; - } - - jtag_interface = jtag_interfaces[i]; - - /* LEGACY SUPPORT ... adapter drivers must declare what - * transports they allow. Until they all do so, assume - * the legacy drivers are JTAG-only - */ - if (!jtag_interface->transports) - LOG_WARNING("Adapter driver '%s' did not declare " - "which transports it allows; assuming " - "legacy JTAG-only", jtag_interface->name); - retval = allow_transports(CMD_CTX, jtag_interface->transports - ? jtag_interface->transports : jtag_only); - if (ERROR_OK != retval) - return retval; - - if (jtag_interface->khz == NULL) - jtag_interface->khz = default_khz; - if (jtag_interface->speed_div == NULL) - jtag_interface->speed_div = default_speed_div; - if (jtag_interface->power_dropout == NULL) - jtag_interface->power_dropout = default_power_dropout; - if (jtag_interface->srst_asserted == NULL) - jtag_interface->srst_asserted = default_srst_asserted; - - return ERROR_OK; - } - - /* no valid interface was found (i.e. the configuration option, - * didn't match one of the compiled-in interfaces - */ - LOG_ERROR("The specified debug interface was not found (%s)", - CMD_ARGV[0]); - CALL_COMMAND_HANDLER(handle_interface_list_command); - return ERROR_JTAG_INVALID_INTERFACE; -} - -COMMAND_HANDLER(handle_reset_config_command) -{ - int new_cfg = 0; - int mask = 0; - - /* Original versions cared about the order of these tokens: - * reset_config signals [combination [trst_type [srst_type]]] - * They also clobbered the previous configuration even on error. - * - * Here we don't care about the order, and only change values - * which have been explicitly specified. - */ - for (; CMD_ARGC; CMD_ARGC--, CMD_ARGV++) { - int tmp = 0; - int m; - - /* gating */ - m = RESET_SRST_NO_GATING; - if (strcmp(*CMD_ARGV, "srst_gates_jtag") == 0) - /* default: don't use JTAG while SRST asserted */; - else if (strcmp(*CMD_ARGV, "srst_nogate") == 0) - tmp = RESET_SRST_NO_GATING; - else - m = 0; - if (mask & m) { - LOG_ERROR("extra reset_config %s spec (%s)", - "gating", *CMD_ARGV); - return ERROR_COMMAND_SYNTAX_ERROR; - } - if (m) - goto next; - - /* signals */ - m = RESET_HAS_TRST | RESET_HAS_SRST; - if (strcmp(*CMD_ARGV, "none") == 0) - tmp = RESET_NONE; - else if (strcmp(*CMD_ARGV, "trst_only") == 0) - tmp = RESET_HAS_TRST; - else if (strcmp(*CMD_ARGV, "srst_only") == 0) - tmp = RESET_HAS_SRST; - else if (strcmp(*CMD_ARGV, "trst_and_srst") == 0) - tmp = RESET_HAS_TRST | RESET_HAS_SRST; - else - m = 0; - if (mask & m) { - LOG_ERROR("extra reset_config %s spec (%s)", - "signal", *CMD_ARGV); - return ERROR_COMMAND_SYNTAX_ERROR; - } - if (m) - goto next; - - /* combination (options for broken wiring) */ - m = RESET_SRST_PULLS_TRST | RESET_TRST_PULLS_SRST; - if (strcmp(*CMD_ARGV, "separate") == 0) - /* separate reset lines - default */; - else if (strcmp(*CMD_ARGV, "srst_pulls_trst") == 0) - tmp |= RESET_SRST_PULLS_TRST; - else if (strcmp(*CMD_ARGV, "trst_pulls_srst") == 0) - tmp |= RESET_TRST_PULLS_SRST; - else if (strcmp(*CMD_ARGV, "combined") == 0) - tmp |= RESET_SRST_PULLS_TRST | RESET_TRST_PULLS_SRST; - else - m = 0; - if (mask & m) { - LOG_ERROR("extra reset_config %s spec (%s)", - "combination", *CMD_ARGV); - return ERROR_COMMAND_SYNTAX_ERROR; - } - if (m) - goto next; - - /* trst_type (NOP without HAS_TRST) */ - m = RESET_TRST_OPEN_DRAIN; - if (strcmp(*CMD_ARGV, "trst_open_drain") == 0) - tmp |= RESET_TRST_OPEN_DRAIN; - else if (strcmp(*CMD_ARGV, "trst_push_pull") == 0) - /* push/pull from adapter - default */; - else - m = 0; - if (mask & m) { - LOG_ERROR("extra reset_config %s spec (%s)", - "trst_type", *CMD_ARGV); - return ERROR_COMMAND_SYNTAX_ERROR; - } - if (m) - goto next; - - /* srst_type (NOP without HAS_SRST) */ - m = RESET_SRST_PUSH_PULL; - if (strcmp(*CMD_ARGV, "srst_push_pull") == 0) - tmp |= RESET_SRST_PUSH_PULL; - else if (strcmp(*CMD_ARGV, "srst_open_drain") == 0) - /* open drain from adapter - default */; - else - m = 0; - if (mask & m) { - LOG_ERROR("extra reset_config %s spec (%s)", - "srst_type", *CMD_ARGV); - return ERROR_COMMAND_SYNTAX_ERROR; - } - if (m) - goto next; - - /* connect_type - only valid when srst_nogate */ - m = RESET_CNCT_UNDER_SRST; - if (strcmp(*CMD_ARGV, "connect_assert_srst") == 0) - tmp |= RESET_CNCT_UNDER_SRST; - else if (strcmp(*CMD_ARGV, "connect_deassert_srst") == 0) - /* connect normally - default */; - else - m = 0; - if (mask & m) { - LOG_ERROR("extra reset_config %s spec (%s)", - "connect_type", *CMD_ARGV); - return ERROR_COMMAND_SYNTAX_ERROR; - } - if (m) - goto next; - - /* caller provided nonsense; fail */ - LOG_ERROR("unknown reset_config flag (%s)", *CMD_ARGV); - return ERROR_COMMAND_SYNTAX_ERROR; - -next: - /* Remember the bits which were specified (mask) - * and their new values (new_cfg). - */ - mask |= m; - new_cfg |= tmp; - } - - /* clear previous values of those bits, save new values */ - if (mask) { - int old_cfg = jtag_get_reset_config(); - - old_cfg &= ~mask; - new_cfg |= old_cfg; - jtag_set_reset_config(new_cfg); - } else - new_cfg = jtag_get_reset_config(); - - /* - * Display the (now-)current reset mode - */ - char *modes[6]; - - /* minimal JTAG has neither SRST nor TRST (so that's the default) */ - switch (new_cfg & (RESET_HAS_TRST | RESET_HAS_SRST)) { - case RESET_HAS_SRST: - modes[0] = "srst_only"; - break; - case RESET_HAS_TRST: - modes[0] = "trst_only"; - break; - case RESET_TRST_AND_SRST: - modes[0] = "trst_and_srst"; - break; - default: - modes[0] = "none"; - break; - } - - /* normally SRST and TRST are decoupled; but bugs happen ... */ - switch (new_cfg & (RESET_SRST_PULLS_TRST | RESET_TRST_PULLS_SRST)) { - case RESET_SRST_PULLS_TRST: - modes[1] = "srst_pulls_trst"; - break; - case RESET_TRST_PULLS_SRST: - modes[1] = "trst_pulls_srst"; - break; - case RESET_SRST_PULLS_TRST | RESET_TRST_PULLS_SRST: - modes[1] = "combined"; - break; - default: - modes[1] = "separate"; - break; - } - - /* TRST-less connectors include Altera, Xilinx, and minimal JTAG */ - if (new_cfg & RESET_HAS_TRST) { - if (new_cfg & RESET_TRST_OPEN_DRAIN) - modes[3] = " trst_open_drain"; - else - modes[3] = " trst_push_pull"; - } else - modes[3] = ""; - - /* SRST-less connectors include TI-14, Xilinx, and minimal JTAG */ - if (new_cfg & RESET_HAS_SRST) { - if (new_cfg & RESET_SRST_NO_GATING) - modes[2] = " srst_nogate"; - else - modes[2] = " srst_gates_jtag"; - - if (new_cfg & RESET_SRST_PUSH_PULL) - modes[4] = " srst_push_pull"; - else - modes[4] = " srst_open_drain"; - - if (new_cfg & RESET_CNCT_UNDER_SRST) - modes[5] = " connect_assert_srst"; - else - modes[5] = " connect_deassert_srst"; - } else { - modes[2] = ""; - modes[4] = ""; - modes[5] = ""; - } - - command_print(CMD_CTX, "%s %s%s%s%s%s", - modes[0], modes[1], - modes[2], modes[3], modes[4], modes[5]); - - return ERROR_OK; -} - -COMMAND_HANDLER(handle_adapter_nsrst_delay_command) -{ - if (CMD_ARGC > 1) - return ERROR_COMMAND_SYNTAX_ERROR; - if (CMD_ARGC == 1) { - unsigned delay; - COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], delay); - - jtag_set_nsrst_delay(delay); - } - command_print(CMD_CTX, "adapter_nsrst_delay: %u", jtag_get_nsrst_delay()); - return ERROR_OK; -} - -COMMAND_HANDLER(handle_adapter_nsrst_assert_width_command) -{ - if (CMD_ARGC > 1) - return ERROR_COMMAND_SYNTAX_ERROR; - if (CMD_ARGC == 1) { - unsigned width; - COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], width); - - jtag_set_nsrst_assert_width(width); - } - command_print(CMD_CTX, "adapter_nsrst_assert_width: %u", jtag_get_nsrst_assert_width()); - return ERROR_OK; -} - -COMMAND_HANDLER(handle_adapter_khz_command) -{ - if (CMD_ARGC > 1) - return ERROR_COMMAND_SYNTAX_ERROR; - - int retval = ERROR_OK; - if (CMD_ARGC == 1) { - unsigned khz = 0; - COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], khz); - - retval = jtag_config_khz(khz); - if (ERROR_OK != retval) - return retval; - } - - int cur_speed = jtag_get_speed_khz(); - retval = jtag_get_speed_readable(&cur_speed); - if (ERROR_OK != retval) - return retval; - - if (cur_speed) - command_print(CMD_CTX, "adapter speed: %d kHz", cur_speed); - else - command_print(CMD_CTX, "adapter speed: RCLK - adaptive"); - - return retval; -} - -static const struct command_registration interface_command_handlers[] = { - { - .name = "adapter_khz", - .handler = handle_adapter_khz_command, - .mode = COMMAND_ANY, - .help = "With an argument, change to the specified maximum " - "jtag speed. For JTAG, 0 KHz signifies adaptive " - " clocking. " - "With or without argument, display current setting.", - .usage = "[khz]", - }, - { - .name = "adapter_name", - .mode = COMMAND_ANY, - .jim_handler = jim_adapter_name, - .help = "Returns the name of the currently " - "selected adapter (driver)", - }, - { - .name = "adapter_nsrst_delay", - .handler = handle_adapter_nsrst_delay_command, - .mode = COMMAND_ANY, - .help = "delay after deasserting SRST in ms", - .usage = "[milliseconds]", - }, - { - .name = "adapter_nsrst_assert_width", - .handler = handle_adapter_nsrst_assert_width_command, - .mode = COMMAND_ANY, - .help = "delay after asserting SRST in ms", - .usage = "[milliseconds]", - }, - { - .name = "interface", - .handler = handle_interface_command, - .mode = COMMAND_CONFIG, - .help = "Select a debug adapter interface (driver)", - .usage = "driver_name", - }, - { - .name = "interface_transports", - .handler = interface_transport_command, - .mode = COMMAND_CONFIG, - .help = "Declare transports the interface supports.", - .usage = "transport ... ", - }, - { - .name = "interface_list", - .handler = handle_interface_list_command, - .mode = COMMAND_ANY, - .help = "List all built-in debug adapter interfaces (drivers)", - }, - { - .name = "reset_config", - .handler = handle_reset_config_command, - .mode = COMMAND_ANY, - .help = "configure adapter reset behavior", - .usage = "[none|trst_only|srst_only|trst_and_srst] " - "[srst_pulls_trst|trst_pulls_srst|combined|separate] " - "[srst_gates_jtag|srst_nogate] " - "[trst_push_pull|trst_open_drain] " - "[srst_push_pull|srst_open_drain] " - "[connect_deassert_srst|connect_assert_srst]", - }, - COMMAND_REGISTRATION_DONE -}; - -/** - * Register the commands which deal with arbitrary debug adapter drivers. - * - * @todo Remove internal assumptions that all debug adapters use JTAG for - * transport. Various types and data structures are not named generically. - */ -int interface_register_commands(struct command_context *ctx) -{ - return register_commands(ctx, NULL, interface_command_handlers); -} diff --git a/src/jtag/aice/Makefile.am b/src/jtag/aice/Makefile.am deleted file mode 100644 index 7b9469d86..000000000 --- a/src/jtag/aice/Makefile.am +++ /dev/null @@ -1,27 +0,0 @@ -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 diff --git a/src/jtag/aice/aice_interface.c b/src/jtag/aice/aice_interface.c deleted file mode 100644 index 20f1f07f9..000000000 --- a/src/jtag/aice/aice_interface.c +++ /dev/null @@ -1,507 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2013 by Andes Technology * - * Hsiangkai Wang * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 -#include "config.h" -#endif - -#include -#include -#include -#include -#include -#include -#include "aice_usb.h" - -#define AICE_KHZ_TO_SPEED_MAP_SIZE 16 -static const int aice_khz_to_speed_map[AICE_KHZ_TO_SPEED_MAP_SIZE] = { - 30000, - 15000, - 7500, - 3750, - 1875, - 937, - 468, - 234, - 48000, - 24000, - 12000, - 6000, - 3000, - 1500, - 750, - 375, -}; - -static const struct aice_port *aice_port; -static struct aice_port_param_s param; -static uint32_t retry_times; -static uint32_t count_to_check_dbger; - -/***************************************************************************/ -/* External interface implementation */ -static uint32_t aice_target_id_codes[AICE_MAX_NUM_CORE]; -static uint8_t aice_num_of_target_id_codes; - -/***************************************************************************/ -/* AICE operations */ -int aice_init_targets(void) -{ - int res; - struct target *target; - struct aice_port_s *aice; - - LOG_DEBUG("aice_init_targets"); - - if (aice_num_of_target_id_codes == 0) { - res = aice_port->api->idcode(aice_target_id_codes, &aice_num_of_target_id_codes); - if (res != ERROR_OK) { - LOG_ERROR("<-- TARGET ERROR! Failed to identify AndesCore " - "JTAG Manufacture ID in the JTAG scan chain. " - "Failed to access EDM registers. -->"); - return res; - } - } - - for (target = all_targets; target; target = target->next) { - target->tap->idcode = aice_target_id_codes[target->tap->abs_chain_position]; - - unsigned ii, limit = target->tap->expected_ids_cnt; - int found = 0; - - for (ii = 0; ii < limit; ii++) { - uint32_t expected = target->tap->expected_ids[ii]; - - /* treat "-expected-id 0" as a "don't-warn" wildcard */ - if (!expected || (target->tap->idcode == expected)) { - found = 1; - break; - } - } - - if (found == 0) { - LOG_ERROR - ("aice_init_targets: target not found: idcode: %" PRIx32, - target->tap->idcode); - return ERROR_FAIL; - } - - aice = calloc(1, sizeof(struct aice_port_s)); - aice->port = aice_port; - aice->coreid = target->tap->abs_chain_position; - - target->tap->priv = aice; - target->tap->hasidcode = 1; - } - - return ERROR_OK; -} - -/***************************************************************************/ -/* End of External interface implementation */ - -/* initial aice - * 1. open usb - * 2. get/show version number - * 3. reset - */ -static int aice_init(void) -{ - if (ERROR_OK != aice_port->api->open(¶m)) { - LOG_ERROR("Cannot find AICE Interface! Please check " - "connection and permissions."); - return ERROR_JTAG_INIT_FAILED; - } - - aice_port->api->set_retry_times(retry_times); - aice_port->api->set_count_to_check_dbger(count_to_check_dbger); - - LOG_INFO("AICE JTAG Interface ready"); - - return ERROR_OK; -} - -/* cleanup aice resource - * close usb - */ -static int aice_quit(void) -{ - aice_port->api->close(); - return ERROR_OK; -} - -static int aice_execute_reset(struct jtag_command *cmd) -{ - static int last_trst; - int retval = ERROR_OK; - - DEBUG_JTAG_IO("reset trst: %d", cmd->cmd.reset->trst); - - if (cmd->cmd.reset->trst != last_trst) { - if (cmd->cmd.reset->trst) - retval = aice_port->api->reset(); - - last_trst = cmd->cmd.reset->trst; - } - - return retval; -} - -static int aice_execute_command(struct jtag_command *cmd) -{ - int retval; - - switch (cmd->type) { - case JTAG_RESET: - retval = aice_execute_reset(cmd); - break; - default: - retval = ERROR_OK; - break; - } - return retval; -} - -/* aice has no need to implement jtag execution model -*/ -static int aice_execute_queue(void) -{ - struct jtag_command *cmd = jtag_command_queue; /* currently processed command */ - int retval; - - retval = ERROR_OK; - - while (cmd) { - if (aice_execute_command(cmd) != ERROR_OK) - retval = ERROR_JTAG_QUEUE_FAILED; - - cmd = cmd->next; - } - - return retval; -} - -/* set jtag frequency(base frequency/frequency divider) to your jtag adapter */ -static int aice_speed(int speed) -{ - return aice_port->api->set_jtag_clock(speed); -} - -/* convert jtag adapter frequency(base frequency/frequency divider) to - * human readable KHz value */ -static int aice_speed_div(int speed, int *khz) -{ - *khz = aice_khz_to_speed_map[speed]; - - return ERROR_OK; -} - -/* convert human readable KHz value to jtag adapter frequency - * (base frequency/frequency divider) */ -static int aice_khz(int khz, int *jtag_speed) -{ - int i; - for (i = 0 ; i < AICE_KHZ_TO_SPEED_MAP_SIZE ; i++) { - if (khz == aice_khz_to_speed_map[i]) { - if (8 <= i) - *jtag_speed = i | AICE_TCK_CONTROL_TCK3048; - else - *jtag_speed = i; - break; - } - } - - if (i == AICE_KHZ_TO_SPEED_MAP_SIZE) { - LOG_INFO("No support the jtag clock: %d", khz); - LOG_INFO("Supported jtag clocks are:"); - - for (i = 0 ; i < AICE_KHZ_TO_SPEED_MAP_SIZE ; i++) - LOG_INFO("* %d", aice_khz_to_speed_map[i]); - - return ERROR_FAIL; - } - - return ERROR_OK; -} - -/***************************************************************************/ -/* Command handlers */ -COMMAND_HANDLER(aice_handle_aice_info_command) -{ - LOG_DEBUG("aice_handle_aice_info_command"); - - command_print(CMD_CTX, "Description: %s", param.device_desc); - command_print(CMD_CTX, "Serial number: %s", param.serial); - if (strncmp(aice_port->name, "aice_pipe", 9) == 0) - command_print(CMD_CTX, "Adapter: %s", param.adapter_name); - - return ERROR_OK; -} - -COMMAND_HANDLER(aice_handle_aice_port_command) -{ - LOG_DEBUG("aice_handle_aice_port_command"); - - if (CMD_ARGC != 1) { - LOG_ERROR("Need exactly one argument to 'aice port'"); - return ERROR_COMMAND_SYNTAX_ERROR; - } - - for (const struct aice_port *l = aice_port_get_list(); l->name; l++) { - if (strcmp(l->name, CMD_ARGV[0]) == 0) { - aice_port = l; - return ERROR_OK; - } - } - - LOG_ERROR("No AICE port '%s' found", CMD_ARGV[0]); - return ERROR_FAIL; -} - -COMMAND_HANDLER(aice_handle_aice_desc_command) -{ - LOG_DEBUG("aice_handle_aice_desc_command"); - - if (CMD_ARGC == 1) - param.device_desc = strdup(CMD_ARGV[0]); - else - LOG_ERROR("expected exactly one argument to aice desc "); - - return ERROR_OK; -} - -COMMAND_HANDLER(aice_handle_aice_serial_command) -{ - LOG_DEBUG("aice_handle_aice_serial_command"); - - if (CMD_ARGC == 1) - param.serial = strdup(CMD_ARGV[0]); - else - LOG_ERROR("expected exactly one argument to aice serial "); - - return ERROR_OK; -} - -COMMAND_HANDLER(aice_handle_aice_vid_pid_command) -{ - LOG_DEBUG("aice_handle_aice_vid_pid_command"); - - if (CMD_ARGC != 2) { - LOG_WARNING("ignoring extra IDs in aice vid_pid (maximum is 1 pair)"); - return ERROR_COMMAND_SYNTAX_ERROR; - } - - COMMAND_PARSE_NUMBER(u16, CMD_ARGV[0], param.vid); - COMMAND_PARSE_NUMBER(u16, CMD_ARGV[1], param.pid); - - return ERROR_OK; -} - -COMMAND_HANDLER(aice_handle_aice_adapter_command) -{ - LOG_DEBUG("aice_handle_aice_adapter_command"); - - if (CMD_ARGC == 1) - param.adapter_name = strdup(CMD_ARGV[0]); - else - LOG_ERROR("expected exactly one argument to aice adapter "); - - return ERROR_OK; -} - -COMMAND_HANDLER(aice_handle_aice_retry_times_command) -{ - LOG_DEBUG("aice_handle_aice_retry_times_command"); - - if (CMD_ARGC == 1) - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], retry_times); - else - LOG_ERROR("expected exactly one argument to aice retry_times "); - - return ERROR_OK; -} - -COMMAND_HANDLER(aice_handle_aice_count_to_check_dbger_command) -{ - LOG_DEBUG("aice_handle_aice_count_to_check_dbger_command"); - - if (CMD_ARGC == 1) - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], count_to_check_dbger); - else - LOG_ERROR("expected exactly one argument to aice count_to_check_dbger " - ""); - - return ERROR_OK; -} - -COMMAND_HANDLER(aice_handle_aice_custom_srst_script_command) -{ - LOG_DEBUG("aice_handle_aice_custom_srst_script_command"); - - if (CMD_ARGC > 0) { - aice_port->api->set_custom_srst_script(CMD_ARGV[0]); - return ERROR_OK; - } - - return ERROR_FAIL; -} - -COMMAND_HANDLER(aice_handle_aice_custom_trst_script_command) -{ - LOG_DEBUG("aice_handle_aice_custom_trst_script_command"); - - if (CMD_ARGC > 0) { - aice_port->api->set_custom_trst_script(CMD_ARGV[0]); - return ERROR_OK; - } - - return ERROR_FAIL; -} - -COMMAND_HANDLER(aice_handle_aice_custom_restart_script_command) -{ - LOG_DEBUG("aice_handle_aice_custom_restart_script_command"); - - if (CMD_ARGC > 0) { - aice_port->api->set_custom_restart_script(CMD_ARGV[0]); - return ERROR_OK; - } - - return ERROR_FAIL; -} - -COMMAND_HANDLER(aice_handle_aice_reset_command) -{ - LOG_DEBUG("aice_handle_aice_reset_command"); - - return aice_port->api->reset(); -} - - -static const struct command_registration aice_subcommand_handlers[] = { - { - .name = "info", - .handler = &aice_handle_aice_info_command, - .mode = COMMAND_EXEC, - .help = "show aice info", - .usage = "aice info", - }, - { - .name = "port", - .handler = &aice_handle_aice_port_command, - .mode = COMMAND_CONFIG, - .help = "set the port of the AICE", - .usage = "aice port ['aice_pipe'|'aice_usb']", - }, - { - .name = "desc", - .handler = &aice_handle_aice_desc_command, - .mode = COMMAND_CONFIG, - .help = "set the aice device description", - .usage = "aice desc [desciption string]", - }, - { - .name = "serial", - .handler = &aice_handle_aice_serial_command, - .mode = COMMAND_CONFIG, - .help = "set the serial number of the AICE device", - .usage = "aice serial [serial string]", - }, - { - .name = "vid_pid", - .handler = &aice_handle_aice_vid_pid_command, - .mode = COMMAND_CONFIG, - .help = "the vendor and product ID of the AICE device", - .usage = "aice vid_pid (vid pid)*", - }, - { - .name = "adapter", - .handler = &aice_handle_aice_adapter_command, - .mode = COMMAND_CONFIG, - .help = "set the file name of adapter", - .usage = "aice adapter [adapter name]", - }, - { - .name = "retry_times", - .handler = &aice_handle_aice_retry_times_command, - .mode = COMMAND_CONFIG, - .help = "set retry times as AICE timeout", - .usage = "aice retry_times num_of_retry", - }, - { - .name = "count_to_check_dbger", - .handler = &aice_handle_aice_count_to_check_dbger_command, - .mode = COMMAND_CONFIG, - .help = "set retry times as checking $DBGER status", - .usage = "aice count_to_check_dbger count_of_checking", - }, - { - .name = "custom_srst_script", - .handler = &aice_handle_aice_custom_srst_script_command, - .mode = COMMAND_CONFIG, - .usage = "custom_srst_script script_file_name", - .help = "set custom srst script", - }, - { - .name = "custom_trst_script", - .handler = &aice_handle_aice_custom_trst_script_command, - .mode = COMMAND_CONFIG, - .usage = "custom_trst_script script_file_name", - .help = "set custom trst script", - }, - { - .name = "custom_restart_script", - .handler = &aice_handle_aice_custom_restart_script_command, - .mode = COMMAND_CONFIG, - .usage = "custom_restart_script script_file_name", - .help = "set custom restart script", - }, - { - .name = "reset", - .handler = &aice_handle_aice_reset_command, - .mode = COMMAND_EXEC, - .usage = "aice reset", - .help = "reset AICE", - }, - COMMAND_REGISTRATION_DONE -}; - -static const struct command_registration aice_command_handlers[] = { - { - .name = "aice", - .mode = COMMAND_ANY, - .help = "perform aice management", - .usage = "aice [subcommand]", - .chain = aice_subcommand_handlers, - }, - COMMAND_REGISTRATION_DONE -}; -/***************************************************************************/ -/* End of Command handlers */ - -struct jtag_interface aice_interface = { - .name = "aice", - .commands = aice_command_handlers, - .transports = aice_transports, - .init = aice_init, - .quit = aice_quit, - .execute_queue = aice_execute_queue, - .speed = aice_speed, /* set interface speed */ - .speed_div = aice_speed_div, /* return readable value */ - .khz = aice_khz, /* convert khz to interface speed value */ -}; diff --git a/src/jtag/aice/aice_interface.h b/src/jtag/aice/aice_interface.h deleted file mode 100644 index 0e3f10836..000000000 --- a/src/jtag/aice/aice_interface.h +++ /dev/null @@ -1,35 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2013 by Andes Technology * - * Hsiangkai Wang * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 OPENOCD_JTAG_AICE_AICE_INTERFACE_H -#define OPENOCD_JTAG_AICE_AICE_INTERFACE_H - -struct aice_interface_param_s { - /** */ - const char *device_desc; - /** */ - const char *serial; - /** */ - uint16_t vid; - /** */ - uint16_t pid; -}; - -int aice_init_targets(void); - -#endif /* OPENOCD_JTAG_AICE_AICE_INTERFACE_H */ diff --git a/src/jtag/aice/aice_pipe.c b/src/jtag/aice/aice_pipe.c deleted file mode 100644 index 18ad40eaa..000000000 --- a/src/jtag/aice/aice_pipe.c +++ /dev/null @@ -1,893 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2013 by Andes Technology * - * Hsiangkai Wang * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 -#include "config.h" -#endif - -#ifdef _WIN32 -#include -#else -#include -#endif - -#include -#include -#include "aice_port.h" -#include "aice_pipe.h" - -#define AICE_PIPE_MAXLINE 8192 - -#ifdef _WIN32 -PROCESS_INFORMATION proc_info; - -HANDLE aice_pipe_output[2]; -HANDLE aice_pipe_input[2]; - -static int aice_pipe_write(const void *buffer, int count) -{ - BOOL success; - DWORD written; - - success = WriteFile(aice_pipe_output[1], buffer, count, &written, NULL); - if (!success) { - LOG_ERROR("(WIN32) write to pipe failed, error code: 0x%08l" PRIx32, GetLastError()); - return -1; - } - - return written; -} - -static int aice_pipe_read(void *buffer, int count) -{ - BOOL success; - DWORD has_read; - - success = ReadFile(aice_pipe_input[0], buffer, count, &has_read, NULL); - if (!success || (has_read == 0)) { - LOG_ERROR("(WIN32) read from pipe failed, error code: 0x%08l" PRIx32, GetLastError()); - return -1; - } - - return has_read; -} - -static int aice_pipe_child_init(struct aice_port_param_s *param) -{ - STARTUPINFO start_info; - BOOL success; - - ZeroMemory(&proc_info, sizeof(PROCESS_INFORMATION)); - ZeroMemory(&start_info, sizeof(STARTUPINFO)); - start_info.cb = sizeof(STARTUPINFO); - start_info.hStdError = aice_pipe_input[1]; - start_info.hStdOutput = aice_pipe_input[1]; - start_info.hStdInput = aice_pipe_output[0]; - start_info.dwFlags |= STARTF_USESTDHANDLES; - - success = CreateProcess(NULL, - param->adapter_name, - NULL, - NULL, - TRUE, - 0, - NULL, - NULL, - &start_info, - &proc_info); - - if (!success) { - LOG_ERROR("Create new process failed"); - return ERROR_FAIL; - } - - return ERROR_OK; -} - -static int aice_pipe_parent_init(struct aice_port_param_s *param) -{ - /* send open to adapter */ - char line[AICE_PIPE_MAXLINE]; - char command[AICE_PIPE_MAXLINE]; - - command[0] = AICE_OPEN; - set_u16(command + 1, param->vid); - set_u16(command + 3, param->pid); - - if (aice_pipe_write(command, 5) != 5) { - LOG_ERROR("write failed\n"); - return ERROR_FAIL; - } - - if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0) { - LOG_ERROR("read failed\n"); - return ERROR_FAIL; - } - - if (line[0] == AICE_OK) - return ERROR_OK; - else - return ERROR_FAIL; -} - -static int aice_pipe_open(struct aice_port_param_s *param) -{ - SECURITY_ATTRIBUTES attribute; - - attribute.nLength = sizeof(SECURITY_ATTRIBUTES); - attribute.bInheritHandle = TRUE; - attribute.lpSecurityDescriptor = NULL; - - if (!CreatePipe(&aice_pipe_output[0], &aice_pipe_output[1], - &attribute, AICE_PIPE_MAXLINE)) { - LOG_ERROR("Create pipes failed"); - return ERROR_FAIL; - } - if (!CreatePipe(&aice_pipe_input[0], &aice_pipe_input[1], - &attribute, AICE_PIPE_MAXLINE)) { - LOG_ERROR("Create pipes failed"); - return ERROR_FAIL; - } - - /* do not inherit aice_pipe_output[1] & aice_pipe_input[0] to child process */ - if (!SetHandleInformation(aice_pipe_output[1], HANDLE_FLAG_INHERIT, 0)) - return ERROR_FAIL; - if (!SetHandleInformation(aice_pipe_input[0], HANDLE_FLAG_INHERIT, 0)) - return ERROR_FAIL; - - aice_pipe_child_init(param); - - aice_pipe_parent_init(param); - - return ERROR_OK; -} - -#else - -int aice_pipe_output[2]; -int aice_pipe_input[2]; - -static int aice_pipe_write(const void *buffer, int count) -{ - if (write(aice_pipe_output[1], buffer, count) != count) { - LOG_ERROR("write to pipe failed"); - return -1; - } - - return count; -} - -static int aice_pipe_read(void *buffer, int count) -{ - int n; - int64_t then, cur; - - then = timeval_ms(); - - while (1) { - n = read(aice_pipe_input[0], buffer, count); - - if ((n == -1) && (errno == EAGAIN)) { - cur = timeval_ms(); - if (cur - then > 500) - keep_alive(); - continue; - } else if (n > 0) - break; - else { - LOG_ERROR("read from pipe failed"); - break; - } - } - - return n; -} - -static int aice_pipe_child_init(struct aice_port_param_s *param) -{ - close(aice_pipe_output[1]); - close(aice_pipe_input[0]); - - if (aice_pipe_output[0] != STDIN_FILENO) { - if (dup2(aice_pipe_output[0], STDIN_FILENO) != STDIN_FILENO) { - LOG_ERROR("Map aice_pipe to STDIN failed"); - return ERROR_FAIL; - } - close(aice_pipe_output[0]); - } - - if (aice_pipe_input[1] != STDOUT_FILENO) { - if (dup2(aice_pipe_input[1], STDOUT_FILENO) != STDOUT_FILENO) { - LOG_ERROR("Map aice_pipe to STDOUT failed"); - return ERROR_FAIL; - } - close(aice_pipe_input[1]); - } - - if (execl(param->adapter_name, param->adapter_name, (char *)0) < 0) { - LOG_ERROR("Execute aice_pipe failed"); - return ERROR_FAIL; - } - - return ERROR_OK; -} - -static int aice_pipe_parent_init(struct aice_port_param_s *param) -{ - close(aice_pipe_output[0]); - close(aice_pipe_input[1]); - - /* set read end of pipe as non-blocking */ - if (fcntl(aice_pipe_input[0], F_SETFL, O_NONBLOCK)) - return ERROR_FAIL; - - /* send open to adapter */ - char line[AICE_PIPE_MAXLINE]; - char command[AICE_PIPE_MAXLINE]; - - command[0] = AICE_OPEN; - set_u16(command + 1, param->vid); - set_u16(command + 3, param->pid); - - if (aice_pipe_write(command, 5) != 5) { - LOG_ERROR("write failed\n"); - return ERROR_FAIL; - } - - if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0) { - LOG_ERROR("read failed\n"); - return ERROR_FAIL; - } - - if (line[0] == AICE_OK) - return ERROR_OK; - else - return ERROR_FAIL; -} - -static void sig_pipe(int signo) -{ - exit(1); -} - -static int aice_pipe_open(struct aice_port_param_s *param) -{ - pid_t pid; - - if (signal(SIGPIPE, sig_pipe) == SIG_ERR) { - LOG_ERROR("Register SIGPIPE handler failed"); - return ERROR_FAIL; - } - - if (pipe(aice_pipe_output) < 0 || pipe(aice_pipe_input) < 0) { - LOG_ERROR("Create pipes failed"); - return ERROR_FAIL; - } - - pid = fork(); - if (pid < 0) { - LOG_ERROR("Fork new process failed"); - return ERROR_FAIL; - } else if (pid == 0) { - if (aice_pipe_child_init(param) != ERROR_OK) { - LOG_ERROR("AICE_PIPE child process initial error"); - return ERROR_FAIL; - } else { - if (aice_pipe_parent_init(param) != ERROR_OK) { - LOG_ERROR("AICE_PIPE parent process initial error"); - return ERROR_FAIL; - } - } - } - - return ERROR_OK; -} -#endif - -static int aice_pipe_close(void) -{ - char line[AICE_PIPE_MAXLINE]; - char command[AICE_PIPE_MAXLINE]; - - command[0] = AICE_CLOSE; - - if (aice_pipe_write(command, 1) != 1) - return ERROR_FAIL; - - if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0) - return ERROR_FAIL; - - if (line[0] == AICE_OK) { -#ifdef _WIN32 - WaitForSingleObject(proc_info.hProcess, INFINITE); - CloseHandle(proc_info.hProcess); - CloseHandle(proc_info.hThread); -#endif - return ERROR_OK; - } else - return ERROR_FAIL; -} - -static int aice_pipe_idcode(uint32_t *idcode, uint8_t *num_of_idcode) -{ - char line[AICE_PIPE_MAXLINE]; - char command[AICE_PIPE_MAXLINE]; - - command[0] = AICE_IDCODE; - - if (aice_pipe_write(command, 1) != 1) - return ERROR_FAIL; - - if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0) - return ERROR_FAIL; - - *num_of_idcode = line[0]; - - if ((*num_of_idcode == 0) || (*num_of_idcode >= 16)) - return ERROR_FAIL; - - for (int i = 0 ; i < *num_of_idcode ; i++) - idcode[i] = get_u32(line + i * 4 + 1); - - return ERROR_OK; -} - -static int aice_pipe_state(uint32_t coreid, enum aice_target_state_s *state) -{ - char line[AICE_PIPE_MAXLINE]; - char command[AICE_PIPE_MAXLINE]; - - command[0] = AICE_STATE; - - if (aice_pipe_write(command, 1) != 1) - return ERROR_FAIL; - - if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0) - return ERROR_FAIL; - - *state = (enum aice_target_state_s)line[0]; - - return ERROR_OK; -} - -static int aice_pipe_reset(void) -{ - char line[AICE_PIPE_MAXLINE]; - char command[AICE_PIPE_MAXLINE]; - - command[0] = AICE_RESET; - - if (aice_pipe_write(command, 1) != 1) - return ERROR_FAIL; - - if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0) - return ERROR_FAIL; - - if (line[0] == AICE_OK) - return ERROR_OK; - else - return ERROR_FAIL; -} - -static int aice_pipe_assert_srst(uint32_t coreid, enum aice_srst_type_s srst) -{ - char line[AICE_PIPE_MAXLINE]; - char command[AICE_PIPE_MAXLINE]; - - command[0] = AICE_ASSERT_SRST; - command[1] = srst; - - if (aice_pipe_write(command, 2) != 2) - return ERROR_FAIL; - - if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0) - return ERROR_FAIL; - - if (line[0] == AICE_OK) - return ERROR_OK; - else - return ERROR_FAIL; -} - -static int aice_pipe_run(uint32_t coreid) -{ - char line[AICE_PIPE_MAXLINE]; - char command[AICE_PIPE_MAXLINE]; - - command[0] = AICE_RUN; - - if (aice_pipe_write(command, 1) != 1) - return ERROR_FAIL; - - if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0) - return ERROR_FAIL; - - if (line[0] == AICE_OK) - return ERROR_OK; - else - return ERROR_FAIL; -} - -static int aice_pipe_halt(uint32_t coreid) -{ - char line[AICE_PIPE_MAXLINE]; - char command[AICE_PIPE_MAXLINE]; - - command[0] = AICE_HALT; - - if (aice_pipe_write(command, 1) != 1) - return ERROR_FAIL; - - if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0) - return ERROR_FAIL; - - if (line[0] == AICE_OK) - return ERROR_OK; - else - return ERROR_FAIL; -} - -static int aice_pipe_read_reg(uint32_t coreid, uint32_t num, uint32_t *val) -{ - char line[AICE_PIPE_MAXLINE]; - char command[AICE_PIPE_MAXLINE]; - - command[0] = AICE_READ_REG; - set_u32(command + 1, num); - - if (aice_pipe_write(command, 5) != 5) - return ERROR_FAIL; - - if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0) - return ERROR_FAIL; - - *val = get_u32(line); - - return ERROR_OK; -} - -static int aice_pipe_write_reg(uint32_t coreid, uint32_t num, uint32_t val) -{ - char line[AICE_PIPE_MAXLINE]; - char command[AICE_PIPE_MAXLINE]; - - command[0] = AICE_WRITE_REG; - set_u32(command + 1, num); - set_u32(command + 5, val); - - if (aice_pipe_write(command, 9) != 9) - return ERROR_FAIL; - - if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0) - return ERROR_FAIL; - - if (line[0] == AICE_OK) - return ERROR_OK; - else - return ERROR_FAIL; -} - -static int aice_pipe_read_reg_64(uint32_t coreid, uint32_t num, uint64_t *val) -{ - char line[AICE_PIPE_MAXLINE]; - char command[AICE_PIPE_MAXLINE]; - - command[0] = AICE_READ_REG_64; - set_u32(command + 1, num); - - if (aice_pipe_write(command, 5) != 5) - return ERROR_FAIL; - - if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0) - return ERROR_FAIL; - - *val = (((uint64_t)get_u32(line + 4)) << 32) | get_u32(line); - - return ERROR_OK; -} - -static int aice_pipe_write_reg_64(uint32_t coreid, uint32_t num, uint64_t val) -{ - char line[AICE_PIPE_MAXLINE]; - char command[AICE_PIPE_MAXLINE]; - - command[0] = AICE_WRITE_REG_64; - set_u32(command + 1, num); - set_u32(command + 5, val & 0xFFFFFFFF); - set_u32(command + 9, (val >> 32) & 0xFFFFFFFF); - - if (aice_pipe_write(command, 13) != 9) - return ERROR_FAIL; - - if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0) - return ERROR_FAIL; - - if (line[0] == AICE_OK) - return ERROR_OK; - else - return ERROR_FAIL; -} - -static int aice_pipe_step(uint32_t coreid) -{ - char line[AICE_PIPE_MAXLINE]; - char command[AICE_PIPE_MAXLINE]; - - command[0] = AICE_STEP; - - if (aice_pipe_write(command, 1) != 1) - return ERROR_FAIL; - - if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0) - return ERROR_FAIL; - - if (line[0] == AICE_OK) - return ERROR_OK; - else - return ERROR_FAIL; -} - -static int aice_pipe_read_mem_unit(uint32_t coreid, uint32_t addr, uint32_t size, - uint32_t count, uint8_t *buffer) -{ - char command[AICE_PIPE_MAXLINE]; - - command[0] = AICE_READ_MEM_UNIT; - set_u32(command + 1, addr); - set_u32(command + 5, size); - set_u32(command + 9, count); - - if (aice_pipe_write(command, 13) != 13) - return ERROR_FAIL; - - if (aice_pipe_read(buffer, size * count) < 0) - return ERROR_FAIL; - - return ERROR_OK; -} - -static int aice_pipe_write_mem_unit(uint32_t coreid, uint32_t addr, uint32_t size, - uint32_t count, const uint8_t *buffer) -{ - char line[AICE_PIPE_MAXLINE]; - char command[AICE_PIPE_MAXLINE]; - - command[0] = AICE_WRITE_MEM_UNIT; - set_u32(command + 1, addr); - set_u32(command + 5, size); - set_u32(command + 9, count); - - /* WRITE_MEM_UNIT|addr|size|count|data */ - memcpy(command + 13, buffer, size * count); - - if (aice_pipe_write(command, 13 + size * count) < 0) - return ERROR_FAIL; - - if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0) - return ERROR_FAIL; - - if (line[0] == AICE_OK) - return ERROR_OK; - else - return ERROR_FAIL; - - return ERROR_OK; -} - -static int aice_pipe_read_mem_bulk(uint32_t coreid, uint32_t addr, - uint32_t length, uint8_t *buffer) -{ - char line[AICE_PIPE_MAXLINE + 1]; - char command[AICE_PIPE_MAXLINE]; - uint32_t remain_len = length; - uint32_t prepare_len; - char *received_line; - uint32_t received_len; - int read_len; - - command[0] = AICE_READ_MEM_BULK; - set_u32(command + 1, addr); - set_u32(command + 5, length); - - if (aice_pipe_write(command, 9) < 0) - return ERROR_FAIL; - - while (remain_len > 0) { - if (remain_len > AICE_PIPE_MAXLINE) - prepare_len = AICE_PIPE_MAXLINE; - else - prepare_len = remain_len; - - prepare_len++; - received_len = 0; - received_line = line; - do { - read_len = aice_pipe_read(received_line, prepare_len - received_len); - if (read_len < 0) - return ERROR_FAIL; - received_line += read_len; - received_len += read_len; - } while (received_len < prepare_len); - - if (line[0] != AICE_OK) - return ERROR_FAIL; - - prepare_len--; - memcpy(buffer, line + 1, prepare_len); - remain_len -= prepare_len; - buffer += prepare_len; - } - - return ERROR_OK; -} - -static int aice_pipe_write_mem_bulk(uint32_t coreid, uint32_t addr, - uint32_t length, const uint8_t *buffer) -{ - char line[AICE_PIPE_MAXLINE]; - char command[AICE_PIPE_MAXLINE + 4]; - uint32_t remain_len = length; - uint32_t written_len = 0; - uint32_t write_len; - - command[0] = AICE_WRITE_MEM_BULK; - set_u32(command + 1, addr); - set_u32(command + 5, length); - - /* Send command first */ - if (aice_pipe_write(command, 9) < 0) - return ERROR_FAIL; - - if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0) - return ERROR_FAIL; - - if (line[0] == AICE_ERROR) - return ERROR_FAIL; - - while (remain_len > 0) { - if (remain_len > AICE_PIPE_MAXLINE) - write_len = AICE_PIPE_MAXLINE; - else - write_len = remain_len; - - set_u32(command, write_len); - memcpy(command + 4, buffer + written_len, write_len); /* data only */ - - if (aice_pipe_write(command, write_len + 4) < 0) - return ERROR_FAIL; - - if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0) - return ERROR_FAIL; - - if (line[0] == AICE_ERROR) - return ERROR_FAIL; - - remain_len -= write_len; - written_len += write_len; - } - - if (line[0] == AICE_OK) - return ERROR_OK; - else - return ERROR_FAIL; -} - -static int aice_pipe_read_debug_reg(uint32_t coreid, uint32_t addr, uint32_t *val) -{ - char line[AICE_PIPE_MAXLINE]; - char command[AICE_PIPE_MAXLINE]; - - command[0] = AICE_READ_DEBUG_REG; - set_u32(command + 1, addr); - - if (aice_pipe_write(command, 5) != 5) - return ERROR_FAIL; - - if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0) - return ERROR_FAIL; - - *val = get_u32(line); - - return ERROR_OK; -} - -static int aice_pipe_write_debug_reg(uint32_t coreid, uint32_t addr, const uint32_t val) -{ - char line[AICE_PIPE_MAXLINE]; - char command[AICE_PIPE_MAXLINE]; - - command[0] = AICE_WRITE_DEBUG_REG; - set_u32(command + 1, addr); - set_u32(command + 5, val); - - if (aice_pipe_write(command, 9) != 9) - return ERROR_FAIL; - - if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0) - return ERROR_FAIL; - - if (line[0] == AICE_OK) - return ERROR_OK; - else - return ERROR_FAIL; -} - -static int aice_pipe_set_jtag_clock(uint32_t a_clock) -{ - char line[AICE_PIPE_MAXLINE]; - char command[AICE_PIPE_MAXLINE]; - - command[0] = AICE_SET_JTAG_CLOCK; - set_u32(command + 1, a_clock); - - if (aice_pipe_write(command, 5) != 5) - return ERROR_FAIL; - - if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0) - return ERROR_FAIL; - - if (line[0] == AICE_OK) - return ERROR_OK; - else - return ERROR_FAIL; -} - -static int aice_pipe_memory_access(uint32_t coreid, enum nds_memory_access access_channel) -{ - char line[AICE_PIPE_MAXLINE]; - char command[AICE_PIPE_MAXLINE]; - - command[0] = AICE_MEMORY_ACCESS; - set_u32(command + 1, access_channel); - - if (aice_pipe_write(command, 5) != 5) - return ERROR_FAIL; - - if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0) - return ERROR_FAIL; - - if (line[0] == AICE_OK) - return ERROR_OK; - else - return ERROR_FAIL; -} - -static int aice_pipe_memory_mode(uint32_t coreid, enum nds_memory_select mem_select) -{ - char line[AICE_PIPE_MAXLINE]; - char command[AICE_PIPE_MAXLINE]; - - command[0] = AICE_MEMORY_MODE; - set_u32(command + 1, mem_select); - - if (aice_pipe_write(command, 5) != 5) - return ERROR_FAIL; - - if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0) - return ERROR_FAIL; - - if (line[0] == AICE_OK) - return ERROR_OK; - else - return ERROR_FAIL; -} - -static int aice_pipe_read_tlb(uint32_t coreid, uint32_t virtual_address, - uint32_t *physical_address) -{ - char line[AICE_PIPE_MAXLINE]; - char command[AICE_PIPE_MAXLINE]; - - command[0] = AICE_READ_TLB; - set_u32(command + 1, virtual_address); - - if (aice_pipe_write(command, 5) != 5) - return ERROR_FAIL; - - if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0) - return ERROR_FAIL; - - if (line[0] == AICE_OK) { - *physical_address = get_u32(line + 1); - return ERROR_OK; - } else - return ERROR_FAIL; -} - -static int aice_pipe_cache_ctl(uint32_t coreid, uint32_t subtype, uint32_t address) -{ - char line[AICE_PIPE_MAXLINE]; - char command[AICE_PIPE_MAXLINE]; - - command[0] = AICE_CACHE_CTL; - set_u32(command + 1, subtype); - set_u32(command + 5, address); - - if (aice_pipe_write(command, 9) != 9) - return ERROR_FAIL; - - if (aice_pipe_read(line, AICE_PIPE_MAXLINE) < 0) - return ERROR_FAIL; - - if (line[0] == AICE_OK) - return ERROR_OK; - else - return ERROR_FAIL; -} - -static int aice_pipe_set_retry_times(uint32_t a_retry_times) -{ - return ERROR_OK; -} - -/** */ -struct aice_port_api_s aice_pipe = { - /** */ - .open = aice_pipe_open, - /** */ - .close = aice_pipe_close, - /** */ - .idcode = aice_pipe_idcode, - /** */ - .set_jtag_clock = aice_pipe_set_jtag_clock, - /** */ - .state = aice_pipe_state, - /** */ - .reset = aice_pipe_reset, - /** */ - .assert_srst = aice_pipe_assert_srst, - /** */ - .run = aice_pipe_run, - /** */ - .halt = aice_pipe_halt, - /** */ - .step = aice_pipe_step, - /** */ - .read_reg = aice_pipe_read_reg, - /** */ - .write_reg = aice_pipe_write_reg, - /** */ - .read_reg_64 = aice_pipe_read_reg_64, - /** */ - .write_reg_64 = aice_pipe_write_reg_64, - /** */ - .read_mem_unit = aice_pipe_read_mem_unit, - /** */ - .write_mem_unit = aice_pipe_write_mem_unit, - /** */ - .read_mem_bulk = aice_pipe_read_mem_bulk, - /** */ - .write_mem_bulk = aice_pipe_write_mem_bulk, - /** */ - .read_debug_reg = aice_pipe_read_debug_reg, - /** */ - .write_debug_reg = aice_pipe_write_debug_reg, - - /** */ - .memory_access = aice_pipe_memory_access, - /** */ - .memory_mode = aice_pipe_memory_mode, - - /** */ - .read_tlb = aice_pipe_read_tlb, - - /** */ - .cache_ctl = aice_pipe_cache_ctl, - - /** */ - .set_retry_times = aice_pipe_set_retry_times, -}; diff --git a/src/jtag/aice/aice_pipe.h b/src/jtag/aice/aice_pipe.h deleted file mode 100644 index 467ad0ad5..000000000 --- a/src/jtag/aice/aice_pipe.h +++ /dev/null @@ -1,31 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2013 by Andes Technology * - * Hsiangkai Wang * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 OPENOCD_JTAG_AICE_AICE_PIPE_H -#define OPENOCD_JTAG_AICE_AICE_PIPE_H - -#include - -#define set_u32(buffer, value) h_u32_to_le((uint8_t *)buffer, value) -#define set_u16(buffer, value) h_u16_to_le((uint8_t *)buffer, value) -#define get_u32(buffer) le_to_h_u32((const uint8_t *)buffer) -#define get_u16(buffer) le_to_h_u16((const uint8_t *)buffer) - -extern struct aice_port_api_s aice_pipe; - -#endif /* OPENOCD_JTAG_AICE_AICE_PIPE_H */ diff --git a/src/jtag/aice/aice_port.c b/src/jtag/aice/aice_port.c deleted file mode 100644 index 2fa346ca0..000000000 --- a/src/jtag/aice/aice_port.c +++ /dev/null @@ -1,45 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2013 by Andes Technology * - * Hsiangkai Wang * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 -#include "config.h" -#endif - -#include -#include "aice_usb.h" -#include "aice_pipe.h" -#include "aice_port.h" - -static const struct aice_port aice_ports[] = { - { - .name = "aice_usb", - .type = AICE_PORT_AICE_USB, - .api = &aice_usb_api, - }, - { - .name = "aice_pipe", - .type = AICE_PORT_AICE_PIPE, - .api = &aice_pipe, - }, - {.name = NULL, /* END OF TABLE */ }, -}; - -/** */ -const struct aice_port *aice_port_get_list(void) -{ - return aice_ports; -} diff --git a/src/jtag/aice/aice_port.h b/src/jtag/aice/aice_port.h deleted file mode 100644 index 4568ce121..000000000 --- a/src/jtag/aice/aice_port.h +++ /dev/null @@ -1,237 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2013 by Andes Technology * - * Hsiangkai Wang * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 OPENOCD_JTAG_AICE_AICE_PORT_H -#define OPENOCD_JTAG_AICE_AICE_PORT_H - -#include - -#define AICE_MAX_NUM_CORE (0x10) - -#define ERROR_AICE_DISCONNECT (-200) -#define ERROR_AICE_TIMEOUT (-201) - -enum aice_target_state_s { - AICE_DISCONNECT = 0, - AICE_TARGET_DETACH, - AICE_TARGET_UNKNOWN, - AICE_TARGET_RUNNING, - AICE_TARGET_HALTED, - AICE_TARGET_RESET, - AICE_TARGET_DEBUG_RUNNING, -}; - -enum aice_srst_type_s { - AICE_SRST = 0x1, - AICE_RESET_HOLD = 0x8, -}; - -enum aice_target_endian { - AICE_LITTLE_ENDIAN = 0, - AICE_BIG_ENDIAN, -}; - -enum aice_api_s { - AICE_OPEN = 0x0, - AICE_CLOSE, - AICE_RESET, - AICE_IDCODE, - AICE_SET_JTAG_CLOCK, - AICE_ASSERT_SRST, - AICE_RUN, - AICE_HALT, - AICE_STEP, - AICE_READ_REG, - AICE_WRITE_REG, - AICE_READ_REG_64, - AICE_WRITE_REG_64, - AICE_READ_MEM_UNIT, - AICE_WRITE_MEM_UNIT, - AICE_READ_MEM_BULK, - AICE_WRITE_MEM_BULK, - AICE_READ_DEBUG_REG, - AICE_WRITE_DEBUG_REG, - AICE_STATE, - AICE_MEMORY_ACCESS, - AICE_MEMORY_MODE, - AICE_READ_TLB, - AICE_CACHE_CTL, - AICE_SET_RETRY_TIMES, - AICE_PROGRAM_EDM, - AICE_SET_COMMAND_MODE, - AICE_EXECUTE, - AICE_SET_CUSTOM_SRST_SCRIPT, - AICE_SET_CUSTOM_TRST_SCRIPT, - AICE_SET_CUSTOM_RESTART_SCRIPT, - AICE_SET_COUNT_TO_CHECK_DBGER, - AICE_SET_DATA_ENDIAN, -}; - -enum aice_error_s { - AICE_OK, - AICE_ACK, - AICE_ERROR, -}; - -enum aice_cache_ctl_type { - AICE_CACHE_CTL_L1D_INVALALL = 0, - AICE_CACHE_CTL_L1D_VA_INVAL, - AICE_CACHE_CTL_L1D_WBALL, - AICE_CACHE_CTL_L1D_VA_WB, - AICE_CACHE_CTL_L1I_INVALALL, - AICE_CACHE_CTL_L1I_VA_INVAL, -}; - -enum aice_command_mode { - AICE_COMMAND_MODE_NORMAL, - AICE_COMMAND_MODE_PACK, - AICE_COMMAND_MODE_BATCH, -}; - -struct aice_port_param_s { - /** */ - const char *device_desc; - /** */ - const char *serial; - /** */ - uint16_t vid; - /** */ - uint16_t pid; - /** */ - char *adapter_name; -}; - -struct aice_port_s { - /** */ - uint32_t coreid; - /** */ - const struct aice_port *port; -}; - -/** */ -extern struct aice_port_api_s aice_usb_layout_api; - -/** */ -struct aice_port_api_s { - /** */ - int (*open)(struct aice_port_param_s *param); - /** */ - int (*close)(void); - /** */ - int (*reset)(void); - /** */ - int (*idcode)(uint32_t *idcode, uint8_t *num_of_idcode); - /** */ - int (*set_jtag_clock)(uint32_t a_clock); - /** */ - int (*assert_srst)(uint32_t coreid, enum aice_srst_type_s srst); - /** */ - int (*run)(uint32_t coreid); - /** */ - int (*halt)(uint32_t coreid); - /** */ - int (*step)(uint32_t coreid); - /** */ - int (*read_reg)(uint32_t coreid, uint32_t num, uint32_t *val); - /** */ - int (*write_reg)(uint32_t coreid, uint32_t num, uint32_t val); - /** */ - int (*read_reg_64)(uint32_t coreid, uint32_t num, uint64_t *val); - /** */ - int (*write_reg_64)(uint32_t coreid, uint32_t num, uint64_t val); - /** */ - int (*read_mem_unit)(uint32_t coreid, uint32_t addr, uint32_t size, - uint32_t count, uint8_t *buffer); - /** */ - int (*write_mem_unit)(uint32_t coreid, uint32_t addr, uint32_t size, - uint32_t count, const uint8_t *buffer); - /** */ - int (*read_mem_bulk)(uint32_t coreid, uint32_t addr, uint32_t length, - uint8_t *buffer); - /** */ - int (*write_mem_bulk)(uint32_t coreid, uint32_t addr, uint32_t length, - const uint8_t *buffer); - /** */ - int (*read_debug_reg)(uint32_t coreid, uint32_t addr, uint32_t *val); - /** */ - int (*write_debug_reg)(uint32_t coreid, uint32_t addr, const uint32_t val); - - /** */ - int (*state)(uint32_t coreid, enum aice_target_state_s *state); - - /** */ - int (*memory_access)(uint32_t coreid, enum nds_memory_access a_access); - /** */ - int (*memory_mode)(uint32_t coreid, enum nds_memory_select mem_select); - - /** */ - int (*read_tlb)(uint32_t coreid, uint32_t virtual_address, uint32_t *physical_address); - - /** */ - int (*cache_ctl)(uint32_t coreid, uint32_t subtype, uint32_t address); - - /** */ - int (*set_retry_times)(uint32_t a_retry_times); - - /** */ - int (*program_edm)(uint32_t coreid, char *command_sequence); - - /** */ - int (*set_command_mode)(enum aice_command_mode command_mode); - - /** */ - int (*execute)(uint32_t coreid, uint32_t *instructions, uint32_t instruction_num); - - /** */ - int (*set_custom_srst_script)(const char *script); - - /** */ - int (*set_custom_trst_script)(const char *script); - - /** */ - int (*set_custom_restart_script)(const char *script); - - /** */ - int (*set_count_to_check_dbger)(uint32_t count_to_check); - - /** */ - int (*set_data_endian)(uint32_t coreid, enum aice_target_endian target_data_endian); - - /** */ - int (*profiling)(uint32_t coreid, uint32_t interval, uint32_t iteration, - uint32_t reg_no, uint32_t *samples, uint32_t *num_samples); -}; - -#define AICE_PORT_UNKNOWN 0 -#define AICE_PORT_AICE_USB 1 -#define AICE_PORT_AICE_PIPE 2 - -/** */ -struct aice_port { - /** */ - const char *name; - /** */ - int type; - /** */ - struct aice_port_api_s *const api; -}; - -/** */ -const struct aice_port *aice_port_get_list(void); - -#endif /* OPENOCD_JTAG_AICE_AICE_PORT_H */ diff --git a/src/jtag/aice/aice_transport.c b/src/jtag/aice/aice_transport.c deleted file mode 100644 index 9f079468c..000000000 --- a/src/jtag/aice/aice_transport.c +++ /dev/null @@ -1,385 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2013 by Andes Technology * - * Hsiangkai Wang * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 -#include "config.h" -#endif - -/* project specific includes */ -#include -#include -#include -#include -#include -#include - -/* */ -static int jim_newtap_expected_id(Jim_Nvp *n, Jim_GetOptInfo *goi, - struct jtag_tap *pTap) -{ - jim_wide w; - int e = Jim_GetOpt_Wide(goi, &w); - if (e != JIM_OK) { - Jim_SetResultFormatted(goi->interp, "option: %s bad parameter", - n->name); - return e; - } - - unsigned expected_len = sizeof(uint32_t) * pTap->expected_ids_cnt; - uint32_t *new_expected_ids = malloc(expected_len + sizeof(uint32_t)); - if (new_expected_ids == NULL) { - Jim_SetResultFormatted(goi->interp, "no memory"); - return JIM_ERR; - } - - memcpy(new_expected_ids, pTap->expected_ids, expected_len); - - new_expected_ids[pTap->expected_ids_cnt] = w; - - free(pTap->expected_ids); - pTap->expected_ids = new_expected_ids; - pTap->expected_ids_cnt++; - - return JIM_OK; -} - -#define NTAP_OPT_EXPECTED_ID 0 - -/* */ -static int jim_aice_newtap_cmd(Jim_GetOptInfo *goi) -{ - struct jtag_tap *pTap; - int x; - int e; - Jim_Nvp *n; - char *cp; - const Jim_Nvp opts[] = { - {.name = "-expected-id", .value = NTAP_OPT_EXPECTED_ID}, - {.name = NULL, .value = -1}, - }; - - pTap = calloc(1, sizeof(struct jtag_tap)); - if (!pTap) { - Jim_SetResultFormatted(goi->interp, "no memory"); - return JIM_ERR; - } - - /* - * we expect CHIP + TAP + OPTIONS - * */ - if (goi->argc < 3) { - Jim_SetResultFormatted(goi->interp, - "Missing CHIP TAP OPTIONS ...."); - free(pTap); - return JIM_ERR; - } - - 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; - cp = malloc(x); - sprintf(cp, "%s.%s", pTap->chip, pTap->tapname); - pTap->dotted_name = cp; - - LOG_DEBUG("Creating New Tap, Chip: %s, Tap: %s, Dotted: %s, %d params", - pTap->chip, pTap->tapname, pTap->dotted_name, goi->argc); - - while (goi->argc) { - e = Jim_GetOpt_Nvp(goi, opts, &n); - if (e != JIM_OK) { - Jim_GetOpt_NvpUnknown(goi, opts, 0); - free(cp); - free(pTap); - return e; - } - LOG_DEBUG("Processing option: %s", n->name); - switch (n->value) { - case NTAP_OPT_EXPECTED_ID: - e = jim_newtap_expected_id(n, goi, pTap); - if (JIM_OK != e) { - free(cp); - free(pTap); - return e; - } - break; - } /* switch (n->value) */ - } /* while (goi->argc) */ - - /* default is enabled-after-reset */ - pTap->enabled = !pTap->disabled_after_reset; - - jtag_tap_init(pTap); - return JIM_OK; -} - -/* */ -static int jim_aice_newtap(Jim_Interp *interp, int argc, Jim_Obj * const *argv) -{ - Jim_GetOptInfo goi; - Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1); - return jim_aice_newtap_cmd(&goi); -} - -/* */ -COMMAND_HANDLER(handle_aice_init_command) -{ - if (CMD_ARGC != 0) - return ERROR_COMMAND_SYNTAX_ERROR; - - static bool jtag_initialized; - if (jtag_initialized) { - LOG_INFO("'jtag init' has already been called"); - return ERROR_OK; - } - jtag_initialized = true; - - LOG_DEBUG("Initializing jtag devices..."); - return jtag_init(CMD_CTX); -} - -static int jim_aice_arp_init(Jim_Interp *interp, int argc, Jim_Obj * const *argv) -{ - LOG_DEBUG("No implement: jim_aice_arp_init"); - - return JIM_OK; -} - -/* */ -static int aice_init_reset(struct command_context *cmd_ctx) -{ - LOG_DEBUG("Initializing with hard TRST+SRST reset"); - - int retval; - enum reset_types jtag_reset_config = jtag_get_reset_config(); - - jtag_add_reset(1, 0); /* TAP_RESET */ - if (jtag_reset_config & RESET_HAS_SRST) { - jtag_add_reset(1, 1); - if ((jtag_reset_config & RESET_SRST_PULLS_TRST) == 0) - jtag_add_reset(0, 1); - } - jtag_add_reset(0, 0); - retval = jtag_execute_queue(); - if (retval != ERROR_OK) - return retval; - - return ERROR_OK; -} - -/* */ -static int jim_aice_arp_init_reset(Jim_Interp *interp, int argc, Jim_Obj * const *argv) -{ - int e = ERROR_OK; - Jim_GetOptInfo goi; - Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1); - if (goi.argc != 0) { - Jim_WrongNumArgs(goi.interp, 1, goi.argv - 1, "(no params)"); - return JIM_ERR; - } - struct command_context *context = current_command_context(interp); - e = aice_init_reset(context); - - if (e != ERROR_OK) { - Jim_Obj *eObj = Jim_NewIntObj(goi.interp, e); - Jim_SetResultFormatted(goi.interp, "error: %#s", eObj); - Jim_FreeNewObj(goi.interp, eObj); - return JIM_ERR; - } - return JIM_OK; -} - -static int jim_aice_names(Jim_Interp *interp, int argc, Jim_Obj *const *argv) -{ - Jim_GetOptInfo goi; - Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1); - if (goi.argc != 0) { - Jim_WrongNumArgs(goi.interp, 1, goi.argv, "Too many parameters"); - return JIM_ERR; - } - Jim_SetResult(goi.interp, Jim_NewListObj(goi.interp, NULL, 0)); - struct jtag_tap *tap; - - for (tap = jtag_all_taps(); tap; tap = tap->next_tap) - Jim_ListAppendElement(goi.interp, - Jim_GetResult(goi.interp), - Jim_NewStringObj(goi.interp, - tap->dotted_name, -1)); - - return JIM_OK; -} - -/* */ -static const struct command_registration -aice_transport_jtag_subcommand_handlers[] = { - { - .name = "init", - .mode = COMMAND_ANY, - .handler = handle_aice_init_command, - .help = "initialize jtag scan chain", - .usage = "" - }, - { - .name = "arp_init", - .mode = COMMAND_ANY, - .jim_handler = jim_aice_arp_init, - .help = "Validates JTAG scan chain against the list of " - "declared TAPs.", - }, - { - .name = "arp_init-reset", - .mode = COMMAND_ANY, - .jim_handler = jim_aice_arp_init_reset, - .help = "Uses TRST and SRST to try resetting everything on " - "the JTAG scan chain, then performs 'jtag arp_init'." - }, - { - .name = "newtap", - .mode = COMMAND_CONFIG, - .jim_handler = jim_aice_newtap, - .help = "Create a new TAP instance named basename.tap_type, " - "and appends it to the scan chain.", - .usage = "basename tap_type ['-expected_id' number]" - }, - { - .name = "tapisenabled", - .mode = COMMAND_EXEC, - .jim_handler = jim_jtag_tap_enabler, - .help = "Returns a Tcl boolean (0/1) indicating whether " - "the TAP is enabled (1) or not (0).", - .usage = "tap_name", - }, - { - .name = "tapenable", - .mode = COMMAND_EXEC, - .jim_handler = jim_jtag_tap_enabler, - .help = "Try to enable the specified TAP using the " - "'tap-enable' TAP event.", - .usage = "tap_name", - }, - { - .name = "tapdisable", - .mode = COMMAND_EXEC, - .jim_handler = jim_jtag_tap_enabler, - .help = "Try to disable the specified TAP using the " - "'tap-disable' TAP event.", - .usage = "tap_name", - }, - { - .name = "configure", - .mode = COMMAND_EXEC, - .jim_handler = jim_jtag_configure, - .help = "Provide a Tcl handler for the specified " - "TAP event.", - .usage = "tap_name '-event' event_name handler", - }, - { - .name = "cget", - .mode = COMMAND_EXEC, - .jim_handler = jim_jtag_configure, - .help = "Return any Tcl handler for the specified " - "TAP event.", - .usage = "tap_name '-event' event_name", - }, - { - .name = "names", - .mode = COMMAND_ANY, - .jim_handler = jim_aice_names, - .help = "Returns list of all JTAG tap names.", - }, - - COMMAND_REGISTRATION_DONE -}; - -/* */ -static const struct command_registration aice_transport_command_handlers[] = { - { - .name = "jtag", - .mode = COMMAND_ANY, - .usage = "", - .chain = aice_transport_jtag_subcommand_handlers, - }, - COMMAND_REGISTRATION_DONE - -}; - -/* */ -static int aice_transport_register_commands(struct command_context *cmd_ctx) -{ - return register_commands(cmd_ctx, NULL, - aice_transport_command_handlers); -} - -/* */ -static int aice_transport_init(struct command_context *cmd_ctx) -{ - LOG_DEBUG("aice_transport_init"); - struct target *t = get_current_target(cmd_ctx); - struct transport *transport; - - if (!t) { - LOG_ERROR("no current target"); - return ERROR_FAIL; - } - - transport = get_current_transport(); - - if (!transport) { - LOG_ERROR("no transport selected"); - return ERROR_FAIL; - } - - LOG_DEBUG("current transport %s", transport->name); - - return aice_init_targets(); -} - -/* */ -static int aice_transport_select(struct command_context *ctx) -{ - LOG_DEBUG("aice_transport_select"); - - int retval; - - retval = aice_transport_register_commands(ctx); - - if (retval != ERROR_OK) - return retval; - - return ERROR_OK; -} - -static struct transport aice_jtag_transport = { - .name = "aice_jtag", - .select = aice_transport_select, - .init = aice_transport_init, -}; - -const char *aice_transports[] = { "aice_jtag", NULL }; - -static void aice_constructor(void) __attribute__((constructor)); -static void aice_constructor(void) -{ - transport_register(&aice_jtag_transport); -} - diff --git a/src/jtag/aice/aice_transport.h b/src/jtag/aice/aice_transport.h deleted file mode 100644 index 3af8bc2ee..000000000 --- a/src/jtag/aice/aice_transport.h +++ /dev/null @@ -1,24 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2013 by Andes Technology * - * Hsiangkai Wang * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 OPENOCD_JTAG_AICE_AICE_TRANSPORT_H -#define OPENOCD_JTAG_AICE_AICE_TRANSPORT_H - -extern const char *aice_transports[]; - -#endif /* OPENOCD_JTAG_AICE_AICE_TRANSPORT_H */ diff --git a/src/jtag/aice/aice_usb.c b/src/jtag/aice/aice_usb.c deleted file mode 100644 index b27f72004..000000000 --- a/src/jtag/aice/aice_usb.c +++ /dev/null @@ -1,4123 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2013 by Andes Technology * - * Hsiangkai Wang * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 -#include "config.h" -#endif - -#include -#include -#include -#include -#include -#include -#include -#include "aice_usb.h" - - -/* Global USB buffers */ -static uint8_t usb_in_buffer[AICE_IN_BUFFER_SIZE]; -static uint8_t usb_out_buffer[AICE_OUT_BUFFER_SIZE]; -static uint32_t jtag_clock; -static struct aice_usb_handler_s aice_handler; -/* AICE max retry times. If AICE command timeout, retry it. */ -static int aice_max_retry_times = 50; -/* Default endian is little endian. */ -static enum aice_target_endian data_endian; - -/* Constants for AICE command format length */ -static const int32_t AICE_FORMAT_HTDA = 3; -static const int32_t AICE_FORMAT_HTDC = 7; -static const int32_t AICE_FORMAT_HTDMA = 4; -static const int32_t AICE_FORMAT_HTDMB = 8; -static const int32_t AICE_FORMAT_HTDMC = 8; -static const int32_t AICE_FORMAT_HTDMD = 12; -static const int32_t AICE_FORMAT_DTHA = 6; -static const int32_t AICE_FORMAT_DTHB = 2; -static const int32_t AICE_FORMAT_DTHMA = 8; -static const int32_t AICE_FORMAT_DTHMB = 4; - -/* Constants for AICE command */ -static const uint8_t AICE_CMD_SCAN_CHAIN = 0x00; -static const uint8_t AICE_CMD_T_READ_MISC = 0x20; -static const uint8_t AICE_CMD_T_READ_EDMSR = 0x21; -static const uint8_t AICE_CMD_T_READ_DTR = 0x22; -static const uint8_t AICE_CMD_T_READ_MEM_B = 0x24; -static const uint8_t AICE_CMD_T_READ_MEM_H = 0x25; -static const uint8_t AICE_CMD_T_READ_MEM = 0x26; -static const uint8_t AICE_CMD_T_FASTREAD_MEM = 0x27; -static const uint8_t AICE_CMD_T_WRITE_MISC = 0x28; -static const uint8_t AICE_CMD_T_WRITE_EDMSR = 0x29; -static const uint8_t AICE_CMD_T_WRITE_DTR = 0x2A; -static const uint8_t AICE_CMD_T_WRITE_DIM = 0x2B; -static const uint8_t AICE_CMD_T_WRITE_MEM_B = 0x2C; -static const uint8_t AICE_CMD_T_WRITE_MEM_H = 0x2D; -static const uint8_t AICE_CMD_T_WRITE_MEM = 0x2E; -static const uint8_t AICE_CMD_T_FASTWRITE_MEM = 0x2F; -static const uint8_t AICE_CMD_T_EXECUTE = 0x3E; -static const uint8_t AICE_CMD_READ_CTRL = 0x50; -static const uint8_t AICE_CMD_WRITE_CTRL = 0x51; -static const uint8_t AICE_CMD_BATCH_BUFFER_READ = 0x60; -static const uint8_t AICE_CMD_READ_DTR_TO_BUFFER = 0x61; -static const uint8_t AICE_CMD_BATCH_BUFFER_WRITE = 0x68; -static const uint8_t AICE_CMD_WRITE_DTR_FROM_BUFFER = 0x69; - -/***************************************************************************/ -/* AICE commands' pack/unpack functions */ -static void aice_pack_htda(uint8_t cmd_code, uint8_t extra_word_length, - uint32_t address) -{ - usb_out_buffer[0] = cmd_code; - usb_out_buffer[1] = extra_word_length; - usb_out_buffer[2] = (uint8_t)(address & 0xFF); -} - -static void aice_pack_htdc(uint8_t cmd_code, uint8_t extra_word_length, - uint32_t address, uint32_t word, enum aice_target_endian access_endian) -{ - usb_out_buffer[0] = cmd_code; - usb_out_buffer[1] = extra_word_length; - usb_out_buffer[2] = (uint8_t)(address & 0xFF); - if (access_endian == AICE_BIG_ENDIAN) { - usb_out_buffer[6] = (uint8_t)((word >> 24) & 0xFF); - usb_out_buffer[5] = (uint8_t)((word >> 16) & 0xFF); - usb_out_buffer[4] = (uint8_t)((word >> 8) & 0xFF); - usb_out_buffer[3] = (uint8_t)(word & 0xFF); - } else { - usb_out_buffer[3] = (uint8_t)((word >> 24) & 0xFF); - usb_out_buffer[4] = (uint8_t)((word >> 16) & 0xFF); - usb_out_buffer[5] = (uint8_t)((word >> 8) & 0xFF); - usb_out_buffer[6] = (uint8_t)(word & 0xFF); - } -} - -static void aice_pack_htdma(uint8_t cmd_code, uint8_t target_id, - uint8_t extra_word_length, uint32_t address) -{ - usb_out_buffer[0] = cmd_code; - usb_out_buffer[1] = target_id; - usb_out_buffer[2] = extra_word_length; - usb_out_buffer[3] = (uint8_t)(address & 0xFF); -} - -static void aice_pack_htdmb(uint8_t cmd_code, uint8_t target_id, - uint8_t extra_word_length, uint32_t address) -{ - usb_out_buffer[0] = cmd_code; - usb_out_buffer[1] = target_id; - usb_out_buffer[2] = extra_word_length; - usb_out_buffer[3] = 0; - usb_out_buffer[4] = (uint8_t)((address >> 24) & 0xFF); - usb_out_buffer[5] = (uint8_t)((address >> 16) & 0xFF); - usb_out_buffer[6] = (uint8_t)((address >> 8) & 0xFF); - usb_out_buffer[7] = (uint8_t)(address & 0xFF); -} - -static void aice_pack_htdmc(uint8_t cmd_code, uint8_t target_id, - uint8_t extra_word_length, uint32_t address, uint32_t word, - enum aice_target_endian access_endian) -{ - usb_out_buffer[0] = cmd_code; - usb_out_buffer[1] = target_id; - usb_out_buffer[2] = extra_word_length; - usb_out_buffer[3] = (uint8_t)(address & 0xFF); - if (access_endian == AICE_BIG_ENDIAN) { - usb_out_buffer[7] = (uint8_t)((word >> 24) & 0xFF); - usb_out_buffer[6] = (uint8_t)((word >> 16) & 0xFF); - usb_out_buffer[5] = (uint8_t)((word >> 8) & 0xFF); - usb_out_buffer[4] = (uint8_t)(word & 0xFF); - } else { - usb_out_buffer[4] = (uint8_t)((word >> 24) & 0xFF); - usb_out_buffer[5] = (uint8_t)((word >> 16) & 0xFF); - usb_out_buffer[6] = (uint8_t)((word >> 8) & 0xFF); - usb_out_buffer[7] = (uint8_t)(word & 0xFF); - } -} - -static void aice_pack_htdmc_multiple_data(uint8_t cmd_code, uint8_t target_id, - uint8_t extra_word_length, uint32_t address, uint32_t *word, - uint8_t num_of_words, enum aice_target_endian access_endian) -{ - usb_out_buffer[0] = cmd_code; - usb_out_buffer[1] = target_id; - usb_out_buffer[2] = extra_word_length; - usb_out_buffer[3] = (uint8_t)(address & 0xFF); - - uint8_t i; - for (i = 0 ; i < num_of_words ; i++, word++) { - if (access_endian == AICE_BIG_ENDIAN) { - usb_out_buffer[7 + i * 4] = (uint8_t)((*word >> 24) & 0xFF); - usb_out_buffer[6 + i * 4] = (uint8_t)((*word >> 16) & 0xFF); - usb_out_buffer[5 + i * 4] = (uint8_t)((*word >> 8) & 0xFF); - usb_out_buffer[4 + i * 4] = (uint8_t)(*word & 0xFF); - } else { - usb_out_buffer[4 + i * 4] = (uint8_t)((*word >> 24) & 0xFF); - usb_out_buffer[5 + i * 4] = (uint8_t)((*word >> 16) & 0xFF); - usb_out_buffer[6 + i * 4] = (uint8_t)((*word >> 8) & 0xFF); - usb_out_buffer[7 + i * 4] = (uint8_t)(*word & 0xFF); - } - } -} - -static void aice_pack_htdmd(uint8_t cmd_code, uint8_t target_id, - uint8_t extra_word_length, uint32_t address, uint32_t word, - enum aice_target_endian access_endian) -{ - usb_out_buffer[0] = cmd_code; - usb_out_buffer[1] = target_id; - usb_out_buffer[2] = extra_word_length; - usb_out_buffer[3] = 0; - usb_out_buffer[4] = (uint8_t)((address >> 24) & 0xFF); - usb_out_buffer[5] = (uint8_t)((address >> 16) & 0xFF); - usb_out_buffer[6] = (uint8_t)((address >> 8) & 0xFF); - usb_out_buffer[7] = (uint8_t)(address & 0xFF); - if (access_endian == AICE_BIG_ENDIAN) { - usb_out_buffer[11] = (uint8_t)((word >> 24) & 0xFF); - usb_out_buffer[10] = (uint8_t)((word >> 16) & 0xFF); - usb_out_buffer[9] = (uint8_t)((word >> 8) & 0xFF); - usb_out_buffer[8] = (uint8_t)(word & 0xFF); - } else { - usb_out_buffer[8] = (uint8_t)((word >> 24) & 0xFF); - usb_out_buffer[9] = (uint8_t)((word >> 16) & 0xFF); - usb_out_buffer[10] = (uint8_t)((word >> 8) & 0xFF); - usb_out_buffer[11] = (uint8_t)(word & 0xFF); - } -} - -static void aice_pack_htdmd_multiple_data(uint8_t cmd_code, uint8_t target_id, - uint8_t extra_word_length, uint32_t address, const uint8_t *word, - enum aice_target_endian access_endian) -{ - usb_out_buffer[0] = cmd_code; - usb_out_buffer[1] = target_id; - usb_out_buffer[2] = extra_word_length; - usb_out_buffer[3] = 0; - usb_out_buffer[4] = (uint8_t)((address >> 24) & 0xFF); - usb_out_buffer[5] = (uint8_t)((address >> 16) & 0xFF); - usb_out_buffer[6] = (uint8_t)((address >> 8) & 0xFF); - usb_out_buffer[7] = (uint8_t)(address & 0xFF); - - uint32_t i; - /* num_of_words may be over 0xFF, so use uint32_t */ - uint32_t num_of_words = extra_word_length + 1; - - for (i = 0 ; i < num_of_words ; i++, word += 4) { - if (access_endian == AICE_BIG_ENDIAN) { - usb_out_buffer[11 + i * 4] = word[3]; - usb_out_buffer[10 + i * 4] = word[2]; - usb_out_buffer[9 + i * 4] = word[1]; - usb_out_buffer[8 + i * 4] = word[0]; - } else { - usb_out_buffer[8 + i * 4] = word[3]; - usb_out_buffer[9 + i * 4] = word[2]; - usb_out_buffer[10 + i * 4] = word[1]; - usb_out_buffer[11 + i * 4] = word[0]; - } - } -} - -static void aice_unpack_dtha(uint8_t *cmd_ack_code, uint8_t *extra_word_length, - uint32_t *word, enum aice_target_endian access_endian) -{ - *cmd_ack_code = usb_in_buffer[0]; - *extra_word_length = usb_in_buffer[1]; - - if (access_endian == AICE_BIG_ENDIAN) { - *word = (usb_in_buffer[5] << 24) | - (usb_in_buffer[4] << 16) | - (usb_in_buffer[3] << 8) | - (usb_in_buffer[2]); - } else { - *word = (usb_in_buffer[2] << 24) | - (usb_in_buffer[3] << 16) | - (usb_in_buffer[4] << 8) | - (usb_in_buffer[5]); - } -} - -static void aice_unpack_dtha_multiple_data(uint8_t *cmd_ack_code, - uint8_t *extra_word_length, uint32_t *word, uint8_t num_of_words, - enum aice_target_endian access_endian) -{ - *cmd_ack_code = usb_in_buffer[0]; - *extra_word_length = usb_in_buffer[1]; - - uint8_t i; - for (i = 0 ; i < num_of_words ; i++, word++) { - if (access_endian == AICE_BIG_ENDIAN) { - *word = (usb_in_buffer[5 + i * 4] << 24) | - (usb_in_buffer[4 + i * 4] << 16) | - (usb_in_buffer[3 + i * 4] << 8) | - (usb_in_buffer[2 + i * 4]); - } else { - *word = (usb_in_buffer[2 + i * 4] << 24) | - (usb_in_buffer[3 + i * 4] << 16) | - (usb_in_buffer[4 + i * 4] << 8) | - (usb_in_buffer[5 + i * 4]); - } - } -} - -static void aice_unpack_dthb(uint8_t *cmd_ack_code, uint8_t *extra_word_length) -{ - *cmd_ack_code = usb_in_buffer[0]; - *extra_word_length = usb_in_buffer[1]; -} - -static void aice_unpack_dthma(uint8_t *cmd_ack_code, uint8_t *target_id, - uint8_t *extra_word_length, uint32_t *word, - enum aice_target_endian access_endian) -{ - *cmd_ack_code = usb_in_buffer[0]; - *target_id = usb_in_buffer[1]; - *extra_word_length = usb_in_buffer[2]; - if (access_endian == AICE_BIG_ENDIAN) { - *word = (usb_in_buffer[7] << 24) | - (usb_in_buffer[6] << 16) | - (usb_in_buffer[5] << 8) | - (usb_in_buffer[4]); - } else { - *word = (usb_in_buffer[4] << 24) | - (usb_in_buffer[5] << 16) | - (usb_in_buffer[6] << 8) | - (usb_in_buffer[7]); - } -} - -static void aice_unpack_dthma_multiple_data(uint8_t *cmd_ack_code, - uint8_t *target_id, uint8_t *extra_word_length, uint8_t *word, - enum aice_target_endian access_endian) -{ - *cmd_ack_code = usb_in_buffer[0]; - *target_id = usb_in_buffer[1]; - *extra_word_length = usb_in_buffer[2]; - if (access_endian == AICE_BIG_ENDIAN) { - word[0] = usb_in_buffer[4]; - word[1] = usb_in_buffer[5]; - word[2] = usb_in_buffer[6]; - word[3] = usb_in_buffer[7]; - } else { - word[0] = usb_in_buffer[7]; - word[1] = usb_in_buffer[6]; - word[2] = usb_in_buffer[5]; - word[3] = usb_in_buffer[4]; - } - word += 4; - - uint8_t i; - for (i = 0; i < *extra_word_length; i++) { - if (access_endian == AICE_BIG_ENDIAN) { - word[0] = usb_in_buffer[8 + i * 4]; - word[1] = usb_in_buffer[9 + i * 4]; - word[2] = usb_in_buffer[10 + i * 4]; - word[3] = usb_in_buffer[11 + i * 4]; - } else { - word[0] = usb_in_buffer[11 + i * 4]; - word[1] = usb_in_buffer[10 + i * 4]; - word[2] = usb_in_buffer[9 + i * 4]; - word[3] = usb_in_buffer[8 + i * 4]; - } - word += 4; - } -} - -static void aice_unpack_dthmb(uint8_t *cmd_ack_code, uint8_t *target_id, - uint8_t *extra_word_length) -{ - *cmd_ack_code = usb_in_buffer[0]; - *target_id = usb_in_buffer[1]; - *extra_word_length = usb_in_buffer[2]; -} - -/***************************************************************************/ -/* End of AICE commands' pack/unpack functions */ - -/* calls the given usb_bulk_* function, allowing for the data to - * trickle in with some timeouts */ -static int usb_bulk_with_retries( - int (*f)(jtag_libusb_device_handle *, int, char *, int, int), - jtag_libusb_device_handle *dev, int ep, - char *bytes, int size, int timeout) -{ - int tries = 3, count = 0; - - while (tries && (count < size)) { - int result = f(dev, ep, bytes + count, size - count, timeout); - if (result > 0) - count += result; - else if ((-ETIMEDOUT != result) || !--tries) - return result; - } - return count; -} - -static int wrap_usb_bulk_write(jtag_libusb_device_handle *dev, int ep, - char *buff, int size, int timeout) -{ - /* usb_bulk_write() takes const char *buff */ - return jtag_libusb_bulk_write(dev, ep, buff, size, timeout); -} - -static inline int usb_bulk_write_ex(jtag_libusb_device_handle *dev, int ep, - char *bytes, int size, int timeout) -{ - return usb_bulk_with_retries(&wrap_usb_bulk_write, - dev, ep, bytes, size, timeout); -} - -static inline int usb_bulk_read_ex(jtag_libusb_device_handle *dev, int ep, - char *bytes, int size, int timeout) -{ - return usb_bulk_with_retries(&jtag_libusb_bulk_read, - dev, ep, bytes, size, timeout); -} - -/* Write data from out_buffer to USB. */ -static int aice_usb_write(uint8_t *out_buffer, int out_length) -{ - int result; - - if (out_length > AICE_OUT_BUFFER_SIZE) { - LOG_ERROR("aice_write illegal out_length=%i (max=%i)", - out_length, AICE_OUT_BUFFER_SIZE); - return -1; - } - - result = usb_bulk_write_ex(aice_handler.usb_handle, aice_handler.usb_write_ep, - (char *)out_buffer, out_length, AICE_USB_TIMEOUT); - - DEBUG_JTAG_IO("aice_usb_write, out_length = %i, result = %i", - out_length, result); - - return result; -} - -/* Read data from USB into in_buffer. */ -static int aice_usb_read(uint8_t *in_buffer, int expected_size) -{ - int32_t result = usb_bulk_read_ex(aice_handler.usb_handle, aice_handler.usb_read_ep, - (char *)in_buffer, expected_size, AICE_USB_TIMEOUT); - - DEBUG_JTAG_IO("aice_usb_read, result = %" PRId32, result); - - return result; -} - -static uint8_t usb_out_packets_buffer[AICE_OUT_PACKETS_BUFFER_SIZE]; -static uint8_t usb_in_packets_buffer[AICE_IN_PACKETS_BUFFER_SIZE]; -static uint32_t usb_out_packets_buffer_length; -static uint32_t usb_in_packets_buffer_length; -static enum aice_command_mode aice_command_mode; - -static int aice_batch_buffer_write(uint8_t buf_index, const uint8_t *word, - uint32_t num_of_words); - -static int aice_usb_packet_flush(void) -{ - if (usb_out_packets_buffer_length == 0) - return 0; - - if (AICE_COMMAND_MODE_PACK == aice_command_mode) { - LOG_DEBUG("Flush usb packets (AICE_COMMAND_MODE_PACK)"); - - if (aice_usb_write(usb_out_packets_buffer, - usb_out_packets_buffer_length) < 0) - return ERROR_FAIL; - - if (aice_usb_read(usb_in_packets_buffer, - usb_in_packets_buffer_length) < 0) - return ERROR_FAIL; - - usb_out_packets_buffer_length = 0; - usb_in_packets_buffer_length = 0; - - } else if (AICE_COMMAND_MODE_BATCH == aice_command_mode) { - LOG_DEBUG("Flush usb packets (AICE_COMMAND_MODE_BATCH)"); - - /* use BATCH_BUFFER_WRITE to fill command-batch-buffer */ - if (aice_batch_buffer_write(AICE_BATCH_COMMAND_BUFFER_0, - usb_out_packets_buffer, - (usb_out_packets_buffer_length + 3) / 4) != ERROR_OK) - return ERROR_FAIL; - - usb_out_packets_buffer_length = 0; - usb_in_packets_buffer_length = 0; - - /* enable BATCH command */ - aice_command_mode = AICE_COMMAND_MODE_NORMAL; - if (aice_write_ctrl(AICE_WRITE_CTRL_BATCH_CTRL, 0x80000000) != ERROR_OK) - return ERROR_FAIL; - aice_command_mode = AICE_COMMAND_MODE_BATCH; - - /* wait 1 second (AICE bug, workaround) */ - alive_sleep(1000); - - /* check status */ - uint32_t i; - uint32_t batch_status; - - i = 0; - while (1) { - aice_read_ctrl(AICE_READ_CTRL_BATCH_STATUS, &batch_status); - - if (batch_status & 0x1) - return ERROR_OK; - else if (batch_status & 0xE) - return ERROR_FAIL; - - if ((i % 30) == 0) - keep_alive(); - - i++; - } - } - - return ERROR_OK; -} - -static int aice_usb_packet_append(uint8_t *out_buffer, int out_length, int in_length) -{ - uint32_t max_packet_size = AICE_OUT_PACKETS_BUFFER_SIZE; - - if (AICE_COMMAND_MODE_PACK == aice_command_mode) { - max_packet_size = AICE_OUT_PACK_COMMAND_SIZE; - } else if (AICE_COMMAND_MODE_BATCH == aice_command_mode) { - max_packet_size = AICE_OUT_BATCH_COMMAND_SIZE; - } else { - /* AICE_COMMAND_MODE_NORMAL */ - if (aice_usb_packet_flush() != ERROR_OK) - return ERROR_FAIL; - } - - if (usb_out_packets_buffer_length + out_length > max_packet_size) - if (aice_usb_packet_flush() != ERROR_OK) { - LOG_DEBUG("Flush usb packets failed"); - return ERROR_FAIL; - } - - LOG_DEBUG("Append usb packets 0x%02x", out_buffer[0]); - - memcpy(usb_out_packets_buffer + usb_out_packets_buffer_length, out_buffer, out_length); - usb_out_packets_buffer_length += out_length; - usb_in_packets_buffer_length += in_length; - - return ERROR_OK; -} - -/***************************************************************************/ -/* AICE commands */ -static int aice_reset_box(void) -{ - if (aice_write_ctrl(AICE_WRITE_CTRL_CLEAR_TIMEOUT_STATUS, 0x1) != ERROR_OK) - return ERROR_FAIL; - - /* turn off FASTMODE */ - uint32_t pin_status; - if (aice_read_ctrl(AICE_READ_CTRL_GET_JTAG_PIN_STATUS, &pin_status) - != ERROR_OK) - return ERROR_FAIL; - - if (aice_write_ctrl(AICE_WRITE_CTRL_JTAG_PIN_STATUS, pin_status & (~0x2)) - != ERROR_OK) - return ERROR_FAIL; - - return ERROR_OK; -} - -static int aice_scan_chain(uint32_t *id_codes, uint8_t *num_of_ids) -{ - int32_t result; - int retry_times = 0; - - if ((AICE_COMMAND_MODE_PACK == aice_command_mode) || - (AICE_COMMAND_MODE_BATCH == aice_command_mode)) - aice_usb_packet_flush(); - - do { - aice_pack_htda(AICE_CMD_SCAN_CHAIN, 0x0F, 0x0); - - aice_usb_write(usb_out_buffer, AICE_FORMAT_HTDA); - - LOG_DEBUG("SCAN_CHAIN, length: 0x0F"); - - /** TODO: modify receive length */ - result = aice_usb_read(usb_in_buffer, AICE_FORMAT_DTHA); - if (AICE_FORMAT_DTHA != result) { - LOG_ERROR("aice_usb_read failed (requested=%" PRIu32 ", result=%" PRId32 ")", - AICE_FORMAT_DTHA, result); - return ERROR_FAIL; - } - - uint8_t cmd_ack_code; - aice_unpack_dtha_multiple_data(&cmd_ack_code, num_of_ids, id_codes, - 0x10, AICE_LITTLE_ENDIAN); - - if (cmd_ack_code != AICE_CMD_SCAN_CHAIN) { - - if (retry_times > aice_max_retry_times) { - LOG_ERROR("aice command timeout (command=0x%" PRIx8 ", response=0x%" PRIx8 ")", - AICE_CMD_SCAN_CHAIN, cmd_ack_code); - return ERROR_FAIL; - } - - /* clear timeout and retry */ - if (aice_reset_box() != ERROR_OK) - return ERROR_FAIL; - - retry_times++; - continue; - } - - LOG_DEBUG("SCAN_CHAIN response, # of IDs: %" PRIu8, *num_of_ids); - - if (*num_of_ids == 0xFF) { - LOG_ERROR("No target connected"); - return ERROR_FAIL; - } else if (*num_of_ids == AICE_MAX_NUM_CORE) { - LOG_INFO("The ice chain over 16 targets"); - } else { - (*num_of_ids)++; - } - break; - } while (1); - - return ERROR_OK; -} - -int aice_read_ctrl(uint32_t address, uint32_t *data) -{ - int32_t result; - - if ((AICE_COMMAND_MODE_PACK == aice_command_mode) || - (AICE_COMMAND_MODE_BATCH == aice_command_mode)) - aice_usb_packet_flush(); - - aice_pack_htda(AICE_CMD_READ_CTRL, 0, address); - - aice_usb_write(usb_out_buffer, AICE_FORMAT_HTDA); - - LOG_DEBUG("READ_CTRL, address: 0x%" PRIx32, address); - - result = aice_usb_read(usb_in_buffer, AICE_FORMAT_DTHA); - if (AICE_FORMAT_DTHA != result) { - LOG_ERROR("aice_usb_read failed (requested=%" PRIu32 ", result=%" PRId32 ")", - AICE_FORMAT_DTHA, result); - return ERROR_FAIL; - } - - uint8_t cmd_ack_code; - uint8_t extra_length; - aice_unpack_dtha(&cmd_ack_code, &extra_length, data, AICE_LITTLE_ENDIAN); - - LOG_DEBUG("READ_CTRL response, data: 0x%" PRIx32, *data); - - if (cmd_ack_code != AICE_CMD_READ_CTRL) { - LOG_ERROR("aice command error (command=0x%" PRIx32 ", response=0x%" PRIx8 ")", - (uint32_t)AICE_CMD_READ_CTRL, cmd_ack_code); - return ERROR_FAIL; - } - - return ERROR_OK; -} - -int aice_write_ctrl(uint32_t address, uint32_t data) -{ - int32_t result; - - if (AICE_COMMAND_MODE_PACK == aice_command_mode) { - aice_usb_packet_flush(); - } else if (AICE_COMMAND_MODE_BATCH == aice_command_mode) { - aice_pack_htdc(AICE_CMD_WRITE_CTRL, 0, address, data, AICE_LITTLE_ENDIAN); - return aice_usb_packet_append(usb_out_buffer, AICE_FORMAT_HTDC, - AICE_FORMAT_DTHB); - } - - aice_pack_htdc(AICE_CMD_WRITE_CTRL, 0, address, data, AICE_LITTLE_ENDIAN); - - aice_usb_write(usb_out_buffer, AICE_FORMAT_HTDC); - - LOG_DEBUG("WRITE_CTRL, address: 0x%" PRIx32 ", data: 0x%" PRIx32, address, data); - - result = aice_usb_read(usb_in_buffer, AICE_FORMAT_DTHB); - if (AICE_FORMAT_DTHB != result) { - LOG_ERROR("aice_usb_read failed (requested=%" PRIu32 ", result=%" PRId32 ")", - AICE_FORMAT_DTHB, result); - return ERROR_FAIL; - } - - uint8_t cmd_ack_code; - uint8_t extra_length; - aice_unpack_dthb(&cmd_ack_code, &extra_length); - - LOG_DEBUG("WRITE_CTRL response"); - - if (cmd_ack_code != AICE_CMD_WRITE_CTRL) { - LOG_ERROR("aice command error (command=0x%" PRIx8 ", response=0x%" PRIx8 ")", - AICE_CMD_WRITE_CTRL, cmd_ack_code); - return ERROR_FAIL; - } - - return ERROR_OK; -} - -int aice_read_dtr(uint8_t target_id, uint32_t *data) -{ - int32_t result; - int retry_times = 0; - - if ((AICE_COMMAND_MODE_PACK == aice_command_mode) || - (AICE_COMMAND_MODE_BATCH == aice_command_mode)) - aice_usb_packet_flush(); - - do { - aice_pack_htdma(AICE_CMD_T_READ_DTR, target_id, 0, 0); - - aice_usb_write(usb_out_buffer, AICE_FORMAT_HTDMA); - - LOG_DEBUG("READ_DTR, COREID: %" PRIu8, target_id); - - result = aice_usb_read(usb_in_buffer, AICE_FORMAT_DTHMA); - if (AICE_FORMAT_DTHMA != result) { - LOG_ERROR("aice_usb_read failed (requested=%" PRId32 ", result=%" PRId32 ")", - AICE_FORMAT_DTHMA, result); - return ERROR_FAIL; - } - - uint8_t cmd_ack_code; - uint8_t extra_length; - uint8_t res_target_id; - aice_unpack_dthma(&cmd_ack_code, &res_target_id, &extra_length, - data, AICE_LITTLE_ENDIAN); - - if (cmd_ack_code == AICE_CMD_T_READ_DTR) { - LOG_DEBUG("READ_DTR response, data: 0x%" PRIx32, *data); - break; - } else { - - if (retry_times > aice_max_retry_times) { - LOG_ERROR("aice command timeout (command=0x%" PRIx8 ", response=0x%" PRIx8 ")", - AICE_CMD_T_READ_DTR, cmd_ack_code); - return ERROR_FAIL; - } - - /* clear timeout and retry */ - if (aice_reset_box() != ERROR_OK) - return ERROR_FAIL; - - retry_times++; - } - } while (1); - - return ERROR_OK; -} - -int aice_read_dtr_to_buffer(uint8_t target_id, uint32_t buffer_idx) -{ - int32_t result; - int retry_times = 0; - - if (AICE_COMMAND_MODE_PACK == aice_command_mode) { - aice_usb_packet_flush(); - } else if (AICE_COMMAND_MODE_BATCH == aice_command_mode) { - aice_pack_htdma(AICE_CMD_READ_DTR_TO_BUFFER, target_id, 0, buffer_idx); - return aice_usb_packet_append(usb_out_buffer, AICE_FORMAT_HTDMA, - AICE_FORMAT_DTHMB); - } - - do { - aice_pack_htdma(AICE_CMD_READ_DTR_TO_BUFFER, target_id, 0, buffer_idx); - - aice_usb_write(usb_out_buffer, AICE_FORMAT_HTDMA); - - LOG_DEBUG("READ_DTR_TO_BUFFER, COREID: %" PRIu8, target_id); - - result = aice_usb_read(usb_in_buffer, AICE_FORMAT_DTHMB); - if (AICE_FORMAT_DTHMB != result) { - LOG_ERROR("aice_usb_read failed (requested=%" PRId32 ", result=%" PRId32 ")", AICE_FORMAT_DTHMB, result); - return ERROR_FAIL; - } - - uint8_t cmd_ack_code; - uint8_t extra_length; - uint8_t res_target_id; - aice_unpack_dthmb(&cmd_ack_code, &res_target_id, &extra_length); - - if (cmd_ack_code == AICE_CMD_READ_DTR_TO_BUFFER) { - break; - } else { - if (retry_times > aice_max_retry_times) { - LOG_ERROR("aice command timeout (command=0x%" PRIx8 ", response=0x%" PRIx8 ")", - AICE_CMD_READ_DTR_TO_BUFFER, cmd_ack_code); - - return ERROR_FAIL; - } - - /* clear timeout and retry */ - if (aice_reset_box() != ERROR_OK) - return ERROR_FAIL; - - retry_times++; - } - } while (1); - - return ERROR_OK; -} - -int aice_write_dtr(uint8_t target_id, uint32_t data) -{ - int32_t result; - int retry_times = 0; - - if (AICE_COMMAND_MODE_PACK == aice_command_mode) { - aice_usb_packet_flush(); - } else if (AICE_COMMAND_MODE_BATCH == aice_command_mode) { - aice_pack_htdmc(AICE_CMD_T_WRITE_DTR, target_id, 0, 0, data, AICE_LITTLE_ENDIAN); - return aice_usb_packet_append(usb_out_buffer, AICE_FORMAT_HTDMC, - AICE_FORMAT_DTHMB); - } - - do { - aice_pack_htdmc(AICE_CMD_T_WRITE_DTR, target_id, 0, 0, data, AICE_LITTLE_ENDIAN); - - aice_usb_write(usb_out_buffer, AICE_FORMAT_HTDMC); - - LOG_DEBUG("WRITE_DTR, COREID: %" PRIu8 ", data: 0x%" PRIx32, target_id, data); - - result = aice_usb_read(usb_in_buffer, AICE_FORMAT_DTHMB); - if (AICE_FORMAT_DTHMB != result) { - LOG_ERROR("aice_usb_read failed (requested=%" PRId32 ", result=%" PRId32 ")", AICE_FORMAT_DTHMB, result); - return ERROR_FAIL; - } - - uint8_t cmd_ack_code; - uint8_t extra_length; - uint8_t res_target_id; - aice_unpack_dthmb(&cmd_ack_code, &res_target_id, &extra_length); - - if (cmd_ack_code == AICE_CMD_T_WRITE_DTR) { - LOG_DEBUG("WRITE_DTR response"); - break; - } else { - if (retry_times > aice_max_retry_times) { - LOG_ERROR("aice command timeout (command=0x%" PRIx8 ", response=0x%" PRIx8 ")", - AICE_CMD_T_WRITE_DTR, cmd_ack_code); - - return ERROR_FAIL; - } - - /* clear timeout and retry */ - if (aice_reset_box() != ERROR_OK) - return ERROR_FAIL; - - retry_times++; - } - } while (1); - - return ERROR_OK; -} - -int aice_write_dtr_from_buffer(uint8_t target_id, uint32_t buffer_idx) -{ - int32_t result; - int retry_times = 0; - - if (AICE_COMMAND_MODE_PACK == aice_command_mode) { - aice_usb_packet_flush(); - } else if (AICE_COMMAND_MODE_BATCH == aice_command_mode) { - aice_pack_htdma(AICE_CMD_WRITE_DTR_FROM_BUFFER, target_id, 0, buffer_idx); - return aice_usb_packet_append(usb_out_buffer, AICE_FORMAT_HTDMA, - AICE_FORMAT_DTHMB); - } - - do { - aice_pack_htdma(AICE_CMD_WRITE_DTR_FROM_BUFFER, target_id, 0, buffer_idx); - - aice_usb_write(usb_out_buffer, AICE_FORMAT_HTDMA); - - LOG_DEBUG("WRITE_DTR_FROM_BUFFER, COREID: %" PRIu8 "", target_id); - - result = aice_usb_read(usb_in_buffer, AICE_FORMAT_DTHMB); - if (AICE_FORMAT_DTHMB != result) { - LOG_ERROR("aice_usb_read failed (requested=%" PRId32 ", result=%" PRId32 ")", AICE_FORMAT_DTHMB, result); - return ERROR_FAIL; - } - - uint8_t cmd_ack_code; - uint8_t extra_length; - uint8_t res_target_id; - aice_unpack_dthmb(&cmd_ack_code, &res_target_id, &extra_length); - - if (cmd_ack_code == AICE_CMD_WRITE_DTR_FROM_BUFFER) { - break; - } else { - if (retry_times > aice_max_retry_times) { - LOG_ERROR("aice command timeout (command=0x%" PRIx8 ", response=0x%" PRIx8 ")", - AICE_CMD_WRITE_DTR_FROM_BUFFER, cmd_ack_code); - - return ERROR_FAIL; - } - - /* clear timeout and retry */ - if (aice_reset_box() != ERROR_OK) - return ERROR_FAIL; - - retry_times++; - } - } while (1); - - return ERROR_OK; -} - -int aice_read_misc(uint8_t target_id, uint32_t address, uint32_t *data) -{ - int32_t result; - int retry_times = 0; - - if ((AICE_COMMAND_MODE_PACK == aice_command_mode) || - (AICE_COMMAND_MODE_BATCH == aice_command_mode)) - aice_usb_packet_flush(); - - do { - aice_pack_htdma(AICE_CMD_T_READ_MISC, target_id, 0, address); - - aice_usb_write(usb_out_buffer, AICE_FORMAT_HTDMA); - - LOG_DEBUG("READ_MISC, COREID: %" PRIu8 ", address: 0x%" PRIx32, target_id, address); - - result = aice_usb_read(usb_in_buffer, AICE_FORMAT_DTHMA); - if (AICE_FORMAT_DTHMA != result) { - LOG_ERROR("aice_usb_read failed (requested=%" PRId32 ", result=%" PRId32 ")", - AICE_FORMAT_DTHMA, result); - return ERROR_AICE_DISCONNECT; - } - - uint8_t cmd_ack_code; - uint8_t extra_length; - uint8_t res_target_id; - aice_unpack_dthma(&cmd_ack_code, &res_target_id, &extra_length, - data, AICE_LITTLE_ENDIAN); - - if (cmd_ack_code == AICE_CMD_T_READ_MISC) { - LOG_DEBUG("READ_MISC response, data: 0x%" PRIx32, *data); - break; - } else { - if (retry_times > aice_max_retry_times) { - LOG_ERROR("aice command timeout (command=0x%" PRIx8 ", response=0x%" PRIx8 ")", - AICE_CMD_T_READ_MISC, cmd_ack_code); - return ERROR_FAIL; - } - - /* clear timeout and retry */ - if (aice_reset_box() != ERROR_OK) - return ERROR_FAIL; - - retry_times++; - } - } while (1); - - return ERROR_OK; -} - -int aice_write_misc(uint8_t target_id, uint32_t address, uint32_t data) -{ - int32_t result; - int retry_times = 0; - - if (AICE_COMMAND_MODE_PACK == aice_command_mode) { - aice_usb_packet_flush(); - } else if (AICE_COMMAND_MODE_BATCH == aice_command_mode) { - aice_pack_htdmc(AICE_CMD_T_WRITE_MISC, target_id, 0, address, data, - AICE_LITTLE_ENDIAN); - return aice_usb_packet_append(usb_out_buffer, AICE_FORMAT_HTDMC, - AICE_FORMAT_DTHMB); - } - - do { - aice_pack_htdmc(AICE_CMD_T_WRITE_MISC, target_id, 0, address, - data, AICE_LITTLE_ENDIAN); - - aice_usb_write(usb_out_buffer, AICE_FORMAT_HTDMC); - - LOG_DEBUG("WRITE_MISC, COREID: %" PRIu8 ", address: 0x%" PRIx32 ", data: 0x%" PRIx32, - target_id, address, data); - - result = aice_usb_read(usb_in_buffer, AICE_FORMAT_DTHMB); - if (AICE_FORMAT_DTHMB != result) { - LOG_ERROR("aice_usb_read failed (requested=%" PRId32 ", result=%" PRId32 ")", - AICE_FORMAT_DTHMB, result); - return ERROR_FAIL; - } - - uint8_t cmd_ack_code; - uint8_t extra_length; - uint8_t res_target_id; - aice_unpack_dthmb(&cmd_ack_code, &res_target_id, &extra_length); - - if (cmd_ack_code == AICE_CMD_T_WRITE_MISC) { - LOG_DEBUG("WRITE_MISC response"); - break; - } else { - if (retry_times > aice_max_retry_times) { - LOG_ERROR("aice command timeout (command=0x%" PRIx8 ", response=0x%" PRIx8 ")", - AICE_CMD_T_WRITE_MISC, cmd_ack_code); - - return ERROR_FAIL; - } - - /* clear timeout and retry */ - if (aice_reset_box() != ERROR_OK) - return ERROR_FAIL; - - retry_times++; - } - } while (1); - - return ERROR_OK; -} - -int aice_read_edmsr(uint8_t target_id, uint32_t address, uint32_t *data) -{ - int32_t result; - int retry_times = 0; - - if ((AICE_COMMAND_MODE_PACK == aice_command_mode) || - (AICE_COMMAND_MODE_BATCH == aice_command_mode)) - aice_usb_packet_flush(); - - do { - aice_pack_htdma(AICE_CMD_T_READ_EDMSR, target_id, 0, address); - - aice_usb_write(usb_out_buffer, AICE_FORMAT_HTDMA); - - LOG_DEBUG("READ_EDMSR, COREID: %" PRIu8 ", address: 0x%" PRIx32, target_id, address); - - result = aice_usb_read(usb_in_buffer, AICE_FORMAT_DTHMA); - if (AICE_FORMAT_DTHMA != result) { - LOG_ERROR("aice_usb_read failed (requested=%" PRId32 ", result=%" PRId32 ")", - AICE_FORMAT_DTHMA, result); - return ERROR_FAIL; - } - - uint8_t cmd_ack_code; - uint8_t extra_length; - uint8_t res_target_id; - aice_unpack_dthma(&cmd_ack_code, &res_target_id, &extra_length, - data, AICE_LITTLE_ENDIAN); - - if (cmd_ack_code == AICE_CMD_T_READ_EDMSR) { - LOG_DEBUG("READ_EDMSR response, data: 0x%" PRIx32, *data); - break; - } else { - if (retry_times > aice_max_retry_times) { - LOG_ERROR("aice command timeout (command=0x%" PRIx8 ", response=0x%" PRIx8 ")", - AICE_CMD_T_READ_EDMSR, cmd_ack_code); - - return ERROR_FAIL; - } - - /* clear timeout and retry */ - if (aice_reset_box() != ERROR_OK) - return ERROR_FAIL; - - retry_times++; - } - } while (1); - - return ERROR_OK; -} - -int aice_write_edmsr(uint8_t target_id, uint32_t address, uint32_t data) -{ - int32_t result; - int retry_times = 0; - - if (AICE_COMMAND_MODE_PACK == aice_command_mode) { - aice_usb_packet_flush(); - } else if (AICE_COMMAND_MODE_BATCH == aice_command_mode) { - aice_pack_htdmc(AICE_CMD_T_WRITE_EDMSR, target_id, 0, address, data, - AICE_LITTLE_ENDIAN); - return aice_usb_packet_append(usb_out_buffer, AICE_FORMAT_HTDMC, - AICE_FORMAT_DTHMB); - } - - do { - aice_pack_htdmc(AICE_CMD_T_WRITE_EDMSR, target_id, 0, address, - data, AICE_LITTLE_ENDIAN); - - aice_usb_write(usb_out_buffer, AICE_FORMAT_HTDMC); - - LOG_DEBUG("WRITE_EDMSR, COREID: %" PRIu8 ", address: 0x%" PRIx32 ", data: 0x%" PRIx32, - target_id, address, data); - - result = aice_usb_read(usb_in_buffer, AICE_FORMAT_DTHMB); - if (AICE_FORMAT_DTHMB != result) { - LOG_ERROR("aice_usb_read failed (requested=%" PRId32 ", result=%" PRId32 ")", - AICE_FORMAT_DTHMB, result); - return ERROR_FAIL; - } - - uint8_t cmd_ack_code; - uint8_t extra_length; - uint8_t res_target_id; - aice_unpack_dthmb(&cmd_ack_code, &res_target_id, &extra_length); - - if (cmd_ack_code == AICE_CMD_T_WRITE_EDMSR) { - LOG_DEBUG("WRITE_EDMSR response"); - break; - } else { - if (retry_times > aice_max_retry_times) { - LOG_ERROR("aice command timeout (command=0x%" PRIx8 ", response=0x%" PRIx8 ")", - AICE_CMD_T_WRITE_EDMSR, cmd_ack_code); - - return ERROR_FAIL; - } - - /* clear timeout and retry */ - if (aice_reset_box() != ERROR_OK) - return ERROR_FAIL; - - retry_times++; - } - } while (1); - - return ERROR_OK; -} - -static int aice_switch_to_big_endian(uint32_t *word, uint8_t num_of_words) -{ - uint32_t tmp; - - for (uint8_t i = 0 ; i < num_of_words ; i++) { - tmp = ((word[i] >> 24) & 0x000000FF) | - ((word[i] >> 8) & 0x0000FF00) | - ((word[i] << 8) & 0x00FF0000) | - ((word[i] << 24) & 0xFF000000); - word[i] = tmp; - } - - return ERROR_OK; -} - -static int aice_write_dim(uint8_t target_id, uint32_t *word, uint8_t num_of_words) -{ - int32_t result; - uint32_t big_endian_word[4]; - int retry_times = 0; - - /** instruction is big-endian */ - memcpy(big_endian_word, word, sizeof(big_endian_word)); - aice_switch_to_big_endian(big_endian_word, num_of_words); - - if (AICE_COMMAND_MODE_PACK == aice_command_mode) { - aice_usb_packet_flush(); - } else if (AICE_COMMAND_MODE_BATCH == aice_command_mode) { - aice_pack_htdmc_multiple_data(AICE_CMD_T_WRITE_DIM, target_id, - num_of_words - 1, 0, big_endian_word, num_of_words, - AICE_LITTLE_ENDIAN); - return aice_usb_packet_append(usb_out_buffer, - AICE_FORMAT_HTDMC + (num_of_words - 1) * 4, - AICE_FORMAT_DTHMB); - } - - do { - aice_pack_htdmc_multiple_data(AICE_CMD_T_WRITE_DIM, target_id, num_of_words - 1, 0, - big_endian_word, num_of_words, AICE_LITTLE_ENDIAN); - - aice_usb_write(usb_out_buffer, AICE_FORMAT_HTDMC + (num_of_words - 1) * 4); - - LOG_DEBUG("WRITE_DIM, COREID: %" PRIu8 - ", data: 0x%08" PRIx32 ", 0x%08" PRIx32 ", 0x%08" PRIx32 ", 0x%08" PRIx32, - target_id, - big_endian_word[0], - big_endian_word[1], - big_endian_word[2], - big_endian_word[3]); - - result = aice_usb_read(usb_in_buffer, AICE_FORMAT_DTHMB); - if (AICE_FORMAT_DTHMB != result) { - LOG_ERROR("aice_usb_read failed (requested=%" PRId32 ", result=%" PRId32 ")", AICE_FORMAT_DTHMB, result); - return ERROR_FAIL; - } - - uint8_t cmd_ack_code; - uint8_t extra_length; - uint8_t res_target_id; - aice_unpack_dthmb(&cmd_ack_code, &res_target_id, &extra_length); - - - if (cmd_ack_code == AICE_CMD_T_WRITE_DIM) { - LOG_DEBUG("WRITE_DIM response"); - break; - } else { - if (retry_times > aice_max_retry_times) { - LOG_ERROR("aice command timeout (command=0x%" PRIx8 - ", response=0x%" PRIx8 ")", - AICE_CMD_T_WRITE_DIM, cmd_ack_code); - - return ERROR_FAIL; - } - - /* clear timeout and retry */ - if (aice_reset_box() != ERROR_OK) - return ERROR_FAIL; - - retry_times++; - } - } while (1); - - return ERROR_OK; -} - -static int aice_do_execute(uint8_t target_id) -{ - int32_t result; - int retry_times = 0; - - if (AICE_COMMAND_MODE_PACK == aice_command_mode) { - aice_usb_packet_flush(); - } else if (AICE_COMMAND_MODE_BATCH == aice_command_mode) { - aice_pack_htdmc(AICE_CMD_T_EXECUTE, target_id, 0, 0, 0, AICE_LITTLE_ENDIAN); - return aice_usb_packet_append(usb_out_buffer, - AICE_FORMAT_HTDMC, - AICE_FORMAT_DTHMB); - } - - do { - aice_pack_htdmc(AICE_CMD_T_EXECUTE, target_id, 0, 0, 0, AICE_LITTLE_ENDIAN); - - aice_usb_write(usb_out_buffer, AICE_FORMAT_HTDMC); - - LOG_DEBUG("EXECUTE, COREID: %" PRIu8 "", target_id); - - result = aice_usb_read(usb_in_buffer, AICE_FORMAT_DTHMB); - if (AICE_FORMAT_DTHMB != result) { - LOG_ERROR("aice_usb_read failed (requested=%" PRId32 ", result=%" PRId32 ")", - AICE_FORMAT_DTHMB, result); - return ERROR_FAIL; - } - - uint8_t cmd_ack_code; - uint8_t extra_length; - uint8_t res_target_id; - aice_unpack_dthmb(&cmd_ack_code, &res_target_id, &extra_length); - - if (cmd_ack_code == AICE_CMD_T_EXECUTE) { - LOG_DEBUG("EXECUTE response"); - break; - } else { - if (retry_times > aice_max_retry_times) { - LOG_ERROR("aice command timeout (command=0x%" PRIx8 ", response=0x%" PRIx8 ")", - AICE_CMD_T_EXECUTE, cmd_ack_code); - - return ERROR_FAIL; - } - - /* clear timeout and retry */ - if (aice_reset_box() != ERROR_OK) - return ERROR_FAIL; - - retry_times++; - } - } while (1); - - return ERROR_OK; -} - -int aice_write_mem_b(uint8_t target_id, uint32_t address, uint32_t data) -{ - int32_t result; - int retry_times = 0; - - LOG_DEBUG("WRITE_MEM_B, COREID: %" PRIu8 ", ADDRESS %08" PRIx32 " VALUE %08" PRIx32, - target_id, - address, - data); - - if ((AICE_COMMAND_MODE_PACK == aice_command_mode) || - (AICE_COMMAND_MODE_BATCH == aice_command_mode)) { - aice_pack_htdmd(AICE_CMD_T_WRITE_MEM_B, target_id, 0, address, - data & 0x000000FF, data_endian); - return aice_usb_packet_append(usb_out_buffer, AICE_FORMAT_HTDMD, - AICE_FORMAT_DTHMB); - } else { - do { - aice_pack_htdmd(AICE_CMD_T_WRITE_MEM_B, target_id, 0, - address, data & 0x000000FF, data_endian); - aice_usb_write(usb_out_buffer, AICE_FORMAT_HTDMD); - - result = aice_usb_read(usb_in_buffer, AICE_FORMAT_DTHMB); - if (AICE_FORMAT_DTHMB != result) { - LOG_ERROR("aice_usb_read failed (requested=%" PRId32 - ", result=%" PRId32 ")", AICE_FORMAT_DTHMB, result); - return ERROR_FAIL; - } - - uint8_t cmd_ack_code; - uint8_t extra_length; - uint8_t res_target_id; - aice_unpack_dthmb(&cmd_ack_code, &res_target_id, &extra_length); - - if (cmd_ack_code == AICE_CMD_T_WRITE_MEM_B) { - break; - } else { - if (retry_times > aice_max_retry_times) { - LOG_ERROR("aice command timeout (command=0x%" PRIx8 ", response=0x%" PRIx8 ")", - AICE_CMD_T_WRITE_MEM_B, cmd_ack_code); - - return ERROR_FAIL; - } - - /* clear timeout and retry */ - if (aice_reset_box() != ERROR_OK) - return ERROR_FAIL; - - retry_times++; - } - } while (1); - } - - return ERROR_OK; -} - -int aice_write_mem_h(uint8_t target_id, uint32_t address, uint32_t data) -{ - int32_t result; - int retry_times = 0; - - LOG_DEBUG("WRITE_MEM_H, COREID: %" PRIu8 ", ADDRESS %08" PRIx32 " VALUE %08" PRIx32, - target_id, - address, - data); - - if ((AICE_COMMAND_MODE_PACK == aice_command_mode) || - (AICE_COMMAND_MODE_BATCH == aice_command_mode)) { - aice_pack_htdmd(AICE_CMD_T_WRITE_MEM_H, target_id, 0, - (address >> 1) & 0x7FFFFFFF, data & 0x0000FFFF, data_endian); - return aice_usb_packet_append(usb_out_buffer, AICE_FORMAT_HTDMD, - AICE_FORMAT_DTHMB); - } else { - do { - aice_pack_htdmd(AICE_CMD_T_WRITE_MEM_H, target_id, 0, - (address >> 1) & 0x7FFFFFFF, data & 0x0000FFFF, data_endian); - aice_usb_write(usb_out_buffer, AICE_FORMAT_HTDMD); - - result = aice_usb_read(usb_in_buffer, AICE_FORMAT_DTHMB); - if (AICE_FORMAT_DTHMB != result) { - LOG_ERROR("aice_usb_read failed (requested=%" PRId32 ", result=%" PRId32 ")", - AICE_FORMAT_DTHMB, result); - return ERROR_FAIL; - } - - uint8_t cmd_ack_code; - uint8_t extra_length; - uint8_t res_target_id; - aice_unpack_dthmb(&cmd_ack_code, &res_target_id, &extra_length); - - if (cmd_ack_code == AICE_CMD_T_WRITE_MEM_H) { - break; - } else { - if (retry_times > aice_max_retry_times) { - LOG_ERROR("aice command timeout (command=0x%" PRIx8 ", response=0x%" PRIx8 ")", - AICE_CMD_T_WRITE_MEM_H, cmd_ack_code); - - return ERROR_FAIL; - } - - /* clear timeout and retry */ - if (aice_reset_box() != ERROR_OK) - return ERROR_FAIL; - - retry_times++; - } - } while (1); - } - - return ERROR_OK; -} - -int aice_write_mem(uint8_t target_id, uint32_t address, uint32_t data) -{ - int32_t result; - int retry_times = 0; - - LOG_DEBUG("WRITE_MEM, COREID: %" PRIu8 ", ADDRESS %08" PRIx32 " VALUE %08" PRIx32, - target_id, - address, - data); - - if ((AICE_COMMAND_MODE_PACK == aice_command_mode) || - (AICE_COMMAND_MODE_BATCH == aice_command_mode)) { - aice_pack_htdmd(AICE_CMD_T_WRITE_MEM, target_id, 0, - (address >> 2) & 0x3FFFFFFF, data, data_endian); - return aice_usb_packet_append(usb_out_buffer, AICE_FORMAT_HTDMD, - AICE_FORMAT_DTHMB); - } else { - do { - aice_pack_htdmd(AICE_CMD_T_WRITE_MEM, target_id, 0, - (address >> 2) & 0x3FFFFFFF, data, data_endian); - aice_usb_write(usb_out_buffer, AICE_FORMAT_HTDMD); - - result = aice_usb_read(usb_in_buffer, AICE_FORMAT_DTHMB); - if (AICE_FORMAT_DTHMB != result) { - LOG_ERROR("aice_usb_read failed (requested=%" PRId32 ", result=%" PRId32 ")", - AICE_FORMAT_DTHMB, result); - return ERROR_FAIL; - } - - uint8_t cmd_ack_code; - uint8_t extra_length; - uint8_t res_target_id; - aice_unpack_dthmb(&cmd_ack_code, &res_target_id, &extra_length); - - if (cmd_ack_code == AICE_CMD_T_WRITE_MEM) { - break; - } else { - if (retry_times > aice_max_retry_times) { - LOG_ERROR("aice command timeout (command=0x%" PRIx8 ", response=0x%" PRIx8 ")", - AICE_CMD_T_WRITE_MEM, cmd_ack_code); - - return ERROR_FAIL; - } - - /* clear timeout and retry */ - if (aice_reset_box() != ERROR_OK) - return ERROR_FAIL; - - retry_times++; - } - } while (1); - } - - return ERROR_OK; -} - -int aice_fastread_mem(uint8_t target_id, uint8_t *word, uint32_t num_of_words) -{ - int32_t result; - int retry_times = 0; - - if ((AICE_COMMAND_MODE_PACK == aice_command_mode) || - (AICE_COMMAND_MODE_BATCH == aice_command_mode)) - aice_usb_packet_flush(); - - do { - aice_pack_htdmb(AICE_CMD_T_FASTREAD_MEM, target_id, num_of_words - 1, 0); - - aice_usb_write(usb_out_buffer, AICE_FORMAT_HTDMB); - - LOG_DEBUG("FASTREAD_MEM, COREID: %" PRIu8 ", # of DATA %08" PRIx32, - target_id, num_of_words); - - result = aice_usb_read(usb_in_buffer, AICE_FORMAT_DTHMA + (num_of_words - 1) * 4); - if (result < 0) { - LOG_ERROR("aice_usb_read failed (requested=%" PRId32 ", result=%" PRId32 ")", - AICE_FORMAT_DTHMA + (num_of_words - 1) * 4, result); - return ERROR_FAIL; - } - - uint8_t cmd_ack_code; - uint8_t extra_length; - uint8_t res_target_id; - aice_unpack_dthma_multiple_data(&cmd_ack_code, &res_target_id, - &extra_length, word, data_endian); - - if (cmd_ack_code == AICE_CMD_T_FASTREAD_MEM) { - break; - } else { - if (retry_times > aice_max_retry_times) { - LOG_ERROR("aice command timeout (command=0x%" PRIx8 ", response=0x%" PRIx8 ")", - AICE_CMD_T_FASTREAD_MEM, cmd_ack_code); - - return ERROR_FAIL; - } - - /* clear timeout and retry */ - if (aice_reset_box() != ERROR_OK) - return ERROR_FAIL; - - retry_times++; - } - } while (1); - - return ERROR_OK; -} - -int aice_fastwrite_mem(uint8_t target_id, const uint8_t *word, uint32_t num_of_words) -{ - int32_t result; - int retry_times = 0; - - if (AICE_COMMAND_MODE_PACK == aice_command_mode) { - aice_usb_packet_flush(); - } else if (AICE_COMMAND_MODE_BATCH == aice_command_mode) { - aice_pack_htdmd_multiple_data(AICE_CMD_T_FASTWRITE_MEM, target_id, - num_of_words - 1, 0, word, data_endian); - return aice_usb_packet_append(usb_out_buffer, - AICE_FORMAT_HTDMD + (num_of_words - 1) * 4, - AICE_FORMAT_DTHMB); - } - - do { - aice_pack_htdmd_multiple_data(AICE_CMD_T_FASTWRITE_MEM, target_id, - num_of_words - 1, 0, word, data_endian); - - aice_usb_write(usb_out_buffer, AICE_FORMAT_HTDMD + (num_of_words - 1) * 4); - - LOG_DEBUG("FASTWRITE_MEM, COREID: %" PRIu8 ", # of DATA %08" PRIx32, - target_id, num_of_words); - - result = aice_usb_read(usb_in_buffer, AICE_FORMAT_DTHMB); - if (AICE_FORMAT_DTHMB != result) { - LOG_ERROR("aice_usb_read failed (requested=%" PRId32 ", result=%" PRId32 ")", - AICE_FORMAT_DTHMB, result); - return ERROR_FAIL; - } - - uint8_t cmd_ack_code; - uint8_t extra_length; - uint8_t res_target_id; - aice_unpack_dthmb(&cmd_ack_code, &res_target_id, &extra_length); - - if (cmd_ack_code == AICE_CMD_T_FASTWRITE_MEM) { - break; - } else { - if (retry_times > aice_max_retry_times) { - LOG_ERROR("aice command timeout (command=0x%" PRIx8 ", response=0x%" PRIx8 ")", - AICE_CMD_T_FASTWRITE_MEM, cmd_ack_code); - - return ERROR_FAIL; - } - - /* clear timeout and retry */ - if (aice_reset_box() != ERROR_OK) - return ERROR_FAIL; - - retry_times++; - } - } while (1); - - return ERROR_OK; -} - -int aice_read_mem_b(uint8_t target_id, uint32_t address, uint32_t *data) -{ - int32_t result; - int retry_times = 0; - - if ((AICE_COMMAND_MODE_PACK == aice_command_mode) || - (AICE_COMMAND_MODE_BATCH == aice_command_mode)) - aice_usb_packet_flush(); - - do { - aice_pack_htdmb(AICE_CMD_T_READ_MEM_B, target_id, 0, address); - - aice_usb_write(usb_out_buffer, AICE_FORMAT_HTDMB); - - LOG_DEBUG("READ_MEM_B, COREID: %" PRIu8 "", target_id); - - result = aice_usb_read(usb_in_buffer, AICE_FORMAT_DTHMA); - if (AICE_FORMAT_DTHMA != result) { - LOG_ERROR("aice_usb_read failed (requested=%" PRId32 ", result=%" PRId32 ")", - AICE_FORMAT_DTHMA, result); - return ERROR_FAIL; - } - - uint8_t cmd_ack_code; - uint8_t extra_length; - uint8_t res_target_id; - aice_unpack_dthma(&cmd_ack_code, &res_target_id, &extra_length, - data, data_endian); - - if (cmd_ack_code == AICE_CMD_T_READ_MEM_B) { - LOG_DEBUG("READ_MEM_B response, data: 0x%02" PRIx32, *data); - break; - } else { - if (retry_times > aice_max_retry_times) { - LOG_ERROR("aice command timeout (command=0x%" PRIx8 ", response=0x%" PRIx8 ")", - AICE_CMD_T_READ_MEM_B, cmd_ack_code); - - return ERROR_FAIL; - } - - /* clear timeout and retry */ - if (aice_reset_box() != ERROR_OK) - return ERROR_FAIL; - - retry_times++; - } - } while (1); - - return ERROR_OK; -} - -int aice_read_mem_h(uint8_t target_id, uint32_t address, uint32_t *data) -{ - int32_t result; - int retry_times = 0; - - if ((AICE_COMMAND_MODE_PACK == aice_command_mode) || - (AICE_COMMAND_MODE_BATCH == aice_command_mode)) - aice_usb_packet_flush(); - - do { - aice_pack_htdmb(AICE_CMD_T_READ_MEM_H, target_id, 0, (address >> 1) & 0x7FFFFFFF); - - aice_usb_write(usb_out_buffer, AICE_FORMAT_HTDMB); - - LOG_DEBUG("READ_MEM_H, CORE_ID: %" PRIu8 "", target_id); - - result = aice_usb_read(usb_in_buffer, AICE_FORMAT_DTHMA); - if (AICE_FORMAT_DTHMA != result) { - LOG_ERROR("aice_usb_read failed (requested=%" PRId32 ", result=%" PRId32 ")", - AICE_FORMAT_DTHMA, result); - return ERROR_FAIL; - } - - uint8_t cmd_ack_code; - uint8_t extra_length; - uint8_t res_target_id; - aice_unpack_dthma(&cmd_ack_code, &res_target_id, &extra_length, - data, data_endian); - - if (cmd_ack_code == AICE_CMD_T_READ_MEM_H) { - LOG_DEBUG("READ_MEM_H response, data: 0x%" PRIx32, *data); - break; - } else { - if (retry_times > aice_max_retry_times) { - LOG_ERROR("aice command timeout (command=0x%" PRIx8 ", response=0x%" PRIx8 ")", - AICE_CMD_T_READ_MEM_H, cmd_ack_code); - - return ERROR_FAIL; - } - - /* clear timeout and retry */ - if (aice_reset_box() != ERROR_OK) - return ERROR_FAIL; - - retry_times++; - } - } while (1); - - return ERROR_OK; -} - -int aice_read_mem(uint8_t target_id, uint32_t address, uint32_t *data) -{ - int32_t result; - int retry_times = 0; - - if ((AICE_COMMAND_MODE_PACK == aice_command_mode) || - (AICE_COMMAND_MODE_BATCH == aice_command_mode)) - aice_usb_packet_flush(); - - do { - aice_pack_htdmb(AICE_CMD_T_READ_MEM, target_id, 0, - (address >> 2) & 0x3FFFFFFF); - - aice_usb_write(usb_out_buffer, AICE_FORMAT_HTDMB); - - LOG_DEBUG("READ_MEM, COREID: %" PRIu8 "", target_id); - - result = aice_usb_read(usb_in_buffer, AICE_FORMAT_DTHMA); - if (AICE_FORMAT_DTHMA != result) { - LOG_ERROR("aice_usb_read failed (requested=%" PRId32 ", result=%" PRId32 ")", - AICE_FORMAT_DTHMA, result); - return ERROR_FAIL; - } - - uint8_t cmd_ack_code; - uint8_t extra_length; - uint8_t res_target_id; - aice_unpack_dthma(&cmd_ack_code, &res_target_id, &extra_length, - data, data_endian); - - if (cmd_ack_code == AICE_CMD_T_READ_MEM) { - LOG_DEBUG("READ_MEM response, data: 0x%" PRIx32, *data); - break; - } else { - if (retry_times > aice_max_retry_times) { - LOG_ERROR("aice command timeout (command=0x%" PRIx8 ", response=0x%" PRIx8 ")", - AICE_CMD_T_READ_MEM, cmd_ack_code); - - return ERROR_FAIL; - } - - /* clear timeout and retry */ - if (aice_reset_box() != ERROR_OK) - return ERROR_FAIL; - - retry_times++; - } - } while (1); - - return ERROR_OK; -} - -int aice_batch_buffer_read(uint8_t buf_index, uint32_t *word, uint32_t num_of_words) -{ - int32_t result; - int retry_times = 0; - - do { - aice_pack_htdma(AICE_CMD_BATCH_BUFFER_READ, 0, num_of_words - 1, buf_index); - - aice_usb_write(usb_out_buffer, AICE_FORMAT_HTDMA); - - LOG_DEBUG("BATCH_BUFFER_READ, # of DATA %08" PRIx32, num_of_words); - - result = aice_usb_read(usb_in_buffer, AICE_FORMAT_DTHMA + (num_of_words - 1) * 4); - if (result < 0) { - LOG_ERROR("aice_usb_read failed (requested=%" PRId32 ", result=%" PRId32 ")", - AICE_FORMAT_DTHMA + (num_of_words - 1) * 4, result); - return ERROR_FAIL; - } - - uint8_t cmd_ack_code; - uint8_t extra_length; - uint8_t res_target_id; - aice_unpack_dthma_multiple_data(&cmd_ack_code, &res_target_id, - &extra_length, (uint8_t *)word, data_endian); - - if (cmd_ack_code == AICE_CMD_BATCH_BUFFER_READ) { - break; - } else { - if (retry_times > aice_max_retry_times) { - LOG_ERROR("aice command timeout (command=0x%" PRIx8 ", response=0x%" PRIx8 ")", - AICE_CMD_BATCH_BUFFER_READ, cmd_ack_code); - - return ERROR_FAIL; - } - - /* clear timeout and retry */ - if (aice_reset_box() != ERROR_OK) - return ERROR_FAIL; - - retry_times++; - } - } while (1); - - return ERROR_OK; -} - -int aice_batch_buffer_write(uint8_t buf_index, const uint8_t *word, uint32_t num_of_words) -{ - int32_t result; - int retry_times = 0; - - if (num_of_words == 0) - return ERROR_OK; - - do { - /* only pack AICE_CMD_BATCH_BUFFER_WRITE command header */ - aice_pack_htdmc(AICE_CMD_BATCH_BUFFER_WRITE, 0, num_of_words - 1, buf_index, - 0, data_endian); - - /* use append instead of pack */ - memcpy(usb_out_buffer + 4, word, num_of_words * 4); - - aice_usb_write(usb_out_buffer, AICE_FORMAT_HTDMC + (num_of_words - 1) * 4); - - LOG_DEBUG("BATCH_BUFFER_WRITE, # of DATA %08" PRIx32, num_of_words); - - result = aice_usb_read(usb_in_buffer, AICE_FORMAT_DTHMB); - if (AICE_FORMAT_DTHMB != result) { - LOG_ERROR("aice_usb_read failed (requested=%" PRId32 ", result=%" PRId32 ")", - AICE_FORMAT_DTHMB, result); - return ERROR_FAIL; - } - - uint8_t cmd_ack_code; - uint8_t extra_length; - uint8_t res_target_id; - aice_unpack_dthmb(&cmd_ack_code, &res_target_id, &extra_length); - - if (cmd_ack_code == AICE_CMD_BATCH_BUFFER_WRITE) { - break; - } else { - if (retry_times > aice_max_retry_times) { - LOG_ERROR("aice command timeout (command=0x%" PRIx8 ", response=0x%" PRIx8 ")", - AICE_CMD_BATCH_BUFFER_WRITE, cmd_ack_code); - - return ERROR_FAIL; - } - - /* clear timeout and retry */ - if (aice_reset_box() != ERROR_OK) - return ERROR_FAIL; - - retry_times++; - } - } while (1); - - return ERROR_OK; -} - -/***************************************************************************/ -/* End of AICE commands */ - -typedef int (*read_mem_func_t)(uint32_t coreid, uint32_t address, uint32_t *data); -typedef int (*write_mem_func_t)(uint32_t coreid, uint32_t address, uint32_t data); - -struct aice_nds32_info core_info[AICE_MAX_NUM_CORE]; -static uint8_t total_num_of_core; - -static char *custom_srst_script; -static char *custom_trst_script; -static char *custom_restart_script; -static uint32_t aice_count_to_check_dbger = 30; - -static int aice_read_reg(uint32_t coreid, uint32_t num, uint32_t *val); -static int aice_write_reg(uint32_t coreid, uint32_t num, uint32_t val); - -static int check_suppressed_exception(uint32_t coreid, uint32_t dbger_value) -{ - uint32_t ir4_value; - uint32_t ir6_value; - /* the default value of handling_suppressed_exception is false */ - static bool handling_suppressed_exception; - - if (handling_suppressed_exception) - return ERROR_OK; - - if ((dbger_value & NDS_DBGER_ALL_SUPRS_EX) == NDS_DBGER_ALL_SUPRS_EX) { - LOG_ERROR("<-- TARGET WARNING! Exception is detected and suppressed. -->"); - handling_suppressed_exception = true; - - aice_read_reg(coreid, IR4, &ir4_value); - /* Clear IR6.SUPRS_EXC, IR6.IMP_EXC */ - aice_read_reg(coreid, IR6, &ir6_value); - /* - * For MCU version(MSC_CFG.MCU == 1) like V3m - * | SWID[30:16] | Reserved[15:10] | SUPRS_EXC[9] | IMP_EXC[8] - * |VECTOR[7:5] | INST[4] | Exc Type[3:0] | - * - * For non-MCU version(MSC_CFG.MCU == 0) like V3 - * | SWID[30:16] | Reserved[15:14] | SUPRS_EXC[13] | IMP_EXC[12] - * | VECTOR[11:5] | INST[4] | Exc Type[3:0] | - */ - LOG_INFO("EVA: 0x%08" PRIx32, ir4_value); - LOG_INFO("ITYPE: 0x%08" PRIx32, ir6_value); - - ir6_value = ir6_value & (~0x300); /* for MCU */ - ir6_value = ir6_value & (~0x3000); /* for non-MCU */ - aice_write_reg(coreid, IR6, ir6_value); - - handling_suppressed_exception = false; - } - - return ERROR_OK; -} - -static int check_privilege(uint32_t coreid, uint32_t dbger_value) -{ - if ((dbger_value & NDS_DBGER_ILL_SEC_ACC) == NDS_DBGER_ILL_SEC_ACC) { - LOG_ERROR("<-- TARGET ERROR! Insufficient security privilege " - "to execute the debug operations. -->"); - - /* Clear DBGER.ILL_SEC_ACC */ - if (aice_write_misc(coreid, NDS_EDM_MISC_DBGER, - NDS_DBGER_ILL_SEC_ACC) != ERROR_OK) - return ERROR_FAIL; - } - - return ERROR_OK; -} - -static int aice_check_dbger(uint32_t coreid, uint32_t expect_status) -{ - uint32_t i = 0; - uint32_t value_dbger; - - while (1) { - aice_read_misc(coreid, NDS_EDM_MISC_DBGER, &value_dbger); - - if ((value_dbger & expect_status) == expect_status) { - if (ERROR_OK != check_suppressed_exception(coreid, value_dbger)) - return ERROR_FAIL; - if (ERROR_OK != check_privilege(coreid, value_dbger)) - return ERROR_FAIL; - return ERROR_OK; - } - - if ((i % 30) == 0) - keep_alive(); - - int64_t then = 0; - if (i == aice_count_to_check_dbger) - then = timeval_ms(); - if (i >= aice_count_to_check_dbger) { - if ((timeval_ms() - then) > 1000) { - LOG_ERROR("Timeout (1000ms) waiting for $DBGER status " - "being 0x%08" PRIx32, expect_status); - return ERROR_FAIL; - } - } - i++; - } - - return ERROR_FAIL; -} - -static int aice_execute_dim(uint32_t coreid, uint32_t *insts, uint8_t n_inst) -{ - /** fill DIM */ - if (aice_write_dim(coreid, insts, n_inst) != ERROR_OK) - return ERROR_FAIL; - - /** clear DBGER.DPED */ - if (aice_write_misc(coreid, NDS_EDM_MISC_DBGER, NDS_DBGER_DPED) != ERROR_OK) - return ERROR_FAIL; - - /** execute DIM */ - if (aice_do_execute(coreid) != ERROR_OK) - return ERROR_FAIL; - - /** read DBGER.DPED */ - if (aice_check_dbger(coreid, NDS_DBGER_DPED) != ERROR_OK) { - LOG_ERROR("<-- TARGET ERROR! Debug operations do not finish properly: " - "0x%08" PRIx32 "0x%08" PRIx32 "0x%08" PRIx32 "0x%08" PRIx32 ". -->", - insts[0], - insts[1], - insts[2], - insts[3]); - return ERROR_FAIL; - } - - return ERROR_OK; -} - -static int aice_read_reg(uint32_t coreid, uint32_t num, uint32_t *val) -{ - LOG_DEBUG("aice_read_reg, reg_no: 0x%08" PRIx32, num); - - uint32_t instructions[4]; /** execute instructions in DIM */ - - if (NDS32_REG_TYPE_GPR == nds32_reg_type(num)) { /* general registers */ - instructions[0] = MTSR_DTR(num); - instructions[1] = DSB; - instructions[2] = NOP; - instructions[3] = BEQ_MINUS_12; - } else if (NDS32_REG_TYPE_SPR == nds32_reg_type(num)) { /* user special registers */ - instructions[0] = MFUSR_G0(0, nds32_reg_sr_index(num)); - instructions[1] = MTSR_DTR(0); - instructions[2] = DSB; - instructions[3] = BEQ_MINUS_12; - } else if (NDS32_REG_TYPE_AUMR == nds32_reg_type(num)) { /* audio registers */ - if ((CB_CTL <= num) && (num <= CBE3)) { - instructions[0] = AMFAR2(0, nds32_reg_sr_index(num)); - instructions[1] = MTSR_DTR(0); - instructions[2] = DSB; - instructions[3] = BEQ_MINUS_12; - } else { - instructions[0] = AMFAR(0, nds32_reg_sr_index(num)); - instructions[1] = MTSR_DTR(0); - instructions[2] = DSB; - instructions[3] = BEQ_MINUS_12; - } - } else if (NDS32_REG_TYPE_FPU == nds32_reg_type(num)) { /* fpu registers */ - if (FPCSR == num) { - instructions[0] = FMFCSR; - instructions[1] = MTSR_DTR(0); - instructions[2] = DSB; - instructions[3] = BEQ_MINUS_12; - } else if (FPCFG == num) { - instructions[0] = FMFCFG; - instructions[1] = MTSR_DTR(0); - instructions[2] = DSB; - instructions[3] = BEQ_MINUS_12; - } else { - if (FS0 <= num && num <= FS31) { /* single precision */ - instructions[0] = FMFSR(0, nds32_reg_sr_index(num)); - instructions[1] = MTSR_DTR(0); - instructions[2] = DSB; - instructions[3] = BEQ_MINUS_12; - } else if (FD0 <= num && num <= FD31) { /* double precision */ - instructions[0] = FMFDR(0, nds32_reg_sr_index(num)); - instructions[1] = MTSR_DTR(0); - instructions[2] = DSB; - instructions[3] = BEQ_MINUS_12; - } - } - } else { /* system registers */ - instructions[0] = MFSR(0, nds32_reg_sr_index(num)); - instructions[1] = MTSR_DTR(0); - instructions[2] = DSB; - instructions[3] = BEQ_MINUS_12; - } - - aice_execute_dim(coreid, instructions, 4); - - uint32_t value_edmsw; - aice_read_edmsr(coreid, NDS_EDM_SR_EDMSW, &value_edmsw); - if (value_edmsw & NDS_EDMSW_WDV) - aice_read_dtr(coreid, val); - else { - LOG_ERROR("<-- TARGET ERROR! The debug target failed to update " - "the DTR register. -->"); - return ERROR_FAIL; - } - - return ERROR_OK; -} - -static int aice_usb_read_reg(uint32_t coreid, uint32_t num, uint32_t *val) -{ - LOG_DEBUG("aice_usb_read_reg"); - - if (num == R0) { - *val = core_info[coreid].r0_backup; - } else if (num == R1) { - *val = core_info[coreid].r1_backup; - } else if (num == DR41) { - /* As target is halted, OpenOCD will backup DR41/DR42/DR43. - * As user wants to read these registers, OpenOCD should return - * the backup values, instead of reading the real values. - * As user wants to write these registers, OpenOCD should write - * to the backup values, instead of writing to real registers. */ - *val = core_info[coreid].edmsw_backup; - } else if (num == DR42) { - *val = core_info[coreid].edm_ctl_backup; - } else if ((core_info[coreid].target_dtr_valid == true) && (num == DR43)) { - *val = core_info[coreid].target_dtr_backup; - } else { - if (ERROR_OK != aice_read_reg(coreid, num, val)) - *val = 0xBBADBEEF; - } - - return ERROR_OK; -} - -static int aice_write_reg(uint32_t coreid, uint32_t num, uint32_t val) -{ - LOG_DEBUG("aice_write_reg, reg_no: 0x%08" PRIx32 ", value: 0x%08" PRIx32, num, val); - - uint32_t instructions[4]; /** execute instructions in DIM */ - uint32_t value_edmsw; - - aice_write_dtr(coreid, val); - aice_read_edmsr(coreid, NDS_EDM_SR_EDMSW, &value_edmsw); - if (0 == (value_edmsw & NDS_EDMSW_RDV)) { - LOG_ERROR("<-- TARGET ERROR! AICE failed to write to the DTR register. -->"); - return ERROR_FAIL; - } - - if (NDS32_REG_TYPE_GPR == nds32_reg_type(num)) { /* general registers */ - instructions[0] = MFSR_DTR(num); - instructions[1] = DSB; - instructions[2] = NOP; - instructions[3] = BEQ_MINUS_12; - } else if (NDS32_REG_TYPE_SPR == nds32_reg_type(num)) { /* user special registers */ - instructions[0] = MFSR_DTR(0); - instructions[1] = MTUSR_G0(0, nds32_reg_sr_index(num)); - instructions[2] = DSB; - instructions[3] = BEQ_MINUS_12; - } else if (NDS32_REG_TYPE_AUMR == nds32_reg_type(num)) { /* audio registers */ - if ((CB_CTL <= num) && (num <= CBE3)) { - instructions[0] = MFSR_DTR(0); - instructions[1] = AMTAR2(0, nds32_reg_sr_index(num)); - instructions[2] = DSB; - instructions[3] = BEQ_MINUS_12; - } else { - instructions[0] = MFSR_DTR(0); - instructions[1] = AMTAR(0, nds32_reg_sr_index(num)); - instructions[2] = DSB; - instructions[3] = BEQ_MINUS_12; - } - } else if (NDS32_REG_TYPE_FPU == nds32_reg_type(num)) { /* fpu registers */ - if (FPCSR == num) { - instructions[0] = MFSR_DTR(0); - instructions[1] = FMTCSR; - instructions[2] = DSB; - instructions[3] = BEQ_MINUS_12; - } else if (FPCFG == num) { - /* FPCFG is readonly */ - } else { - if (FS0 <= num && num <= FS31) { /* single precision */ - instructions[0] = MFSR_DTR(0); - instructions[1] = FMTSR(0, nds32_reg_sr_index(num)); - instructions[2] = DSB; - instructions[3] = BEQ_MINUS_12; - } else if (FD0 <= num && num <= FD31) { /* double precision */ - instructions[0] = MFSR_DTR(0); - instructions[1] = FMTDR(0, nds32_reg_sr_index(num)); - instructions[2] = DSB; - instructions[3] = BEQ_MINUS_12; - } - } - } else { - instructions[0] = MFSR_DTR(0); - instructions[1] = MTSR(0, nds32_reg_sr_index(num)); - instructions[2] = DSB; - instructions[3] = BEQ_MINUS_12; - } - - return aice_execute_dim(coreid, instructions, 4); -} - -static int aice_usb_write_reg(uint32_t coreid, uint32_t num, uint32_t val) -{ - LOG_DEBUG("aice_usb_write_reg"); - - if (num == R0) - core_info[coreid].r0_backup = val; - else if (num == R1) - core_info[coreid].r1_backup = val; - else if (num == DR42) - /* As target is halted, OpenOCD will backup DR41/DR42/DR43. - * As user wants to read these registers, OpenOCD should return - * the backup values, instead of reading the real values. - * As user wants to write these registers, OpenOCD should write - * to the backup values, instead of writing to real registers. */ - core_info[coreid].edm_ctl_backup = val; - else if ((core_info[coreid].target_dtr_valid == true) && (num == DR43)) - core_info[coreid].target_dtr_backup = val; - else - return aice_write_reg(coreid, num, val); - - return ERROR_OK; -} - -static int aice_usb_open(struct aice_port_param_s *param) -{ - const uint16_t vids[] = { param->vid, 0 }; - const uint16_t pids[] = { param->pid, 0 }; - struct jtag_libusb_device_handle *devh; - - if (jtag_libusb_open(vids, pids, NULL, &devh) != ERROR_OK) - return ERROR_FAIL; - - /* BE ***VERY CAREFUL*** ABOUT MAKING CHANGES IN THIS - * AREA!!!!!!!!!!! The behavior of libusb is not completely - * consistent across Windows, Linux, and Mac OS X platforms. - * The actions taken in the following compiler conditionals may - * not agree with published documentation for libusb, but were - * found to be necessary through trials and tribulations. Even - * little tweaks can break one or more platforms, so if you do - * make changes test them carefully on all platforms before - * committing them! - */ - -#if IS_WIN32 == 0 - - jtag_libusb_reset_device(devh); - -#if IS_DARWIN == 0 - - int timeout = 5; - /* reopen jlink after usb_reset - * on win32 this may take a second or two to re-enumerate */ - int retval; - while ((retval = jtag_libusb_open(vids, pids, NULL, &devh)) != ERROR_OK) { - usleep(1000); - timeout--; - if (!timeout) - break; - } - if (ERROR_OK != retval) - return ERROR_FAIL; -#endif - -#endif - - /* usb_set_configuration required under win32 */ - jtag_libusb_set_configuration(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); - - aice_handler.usb_read_ep = aice_read_ep; - aice_handler.usb_write_ep = aice_write_ep; - aice_handler.usb_handle = devh; - - return ERROR_OK; -} - -static int aice_usb_read_reg_64(uint32_t coreid, uint32_t num, uint64_t *val) -{ - LOG_DEBUG("aice_usb_read_reg_64, %s", nds32_reg_simple_name(num)); - - uint32_t value; - uint32_t high_value; - - if (ERROR_OK != aice_read_reg(coreid, num, &value)) - value = 0xBBADBEEF; - - aice_read_reg(coreid, R1, &high_value); - - LOG_DEBUG("low: 0x%08" PRIx32 ", high: 0x%08" PRIx32 "\n", value, high_value); - - if (data_endian == AICE_BIG_ENDIAN) - *val = (((uint64_t)high_value) << 32) | value; - else - *val = (((uint64_t)value) << 32) | high_value; - - return ERROR_OK; -} - -static int aice_usb_write_reg_64(uint32_t coreid, uint32_t num, uint64_t val) -{ - uint32_t value; - uint32_t high_value; - - if (data_endian == AICE_BIG_ENDIAN) { - value = val & 0xFFFFFFFF; - high_value = (val >> 32) & 0xFFFFFFFF; - } else { - high_value = val & 0xFFFFFFFF; - value = (val >> 32) & 0xFFFFFFFF; - } - - LOG_DEBUG("aice_usb_write_reg_64, %s, low: 0x%08" PRIx32 ", high: 0x%08" PRIx32 "\n", - nds32_reg_simple_name(num), value, high_value); - - aice_write_reg(coreid, R1, high_value); - return aice_write_reg(coreid, num, value); -} - -static int aice_get_version_info(void) -{ - uint32_t hardware_version; - uint32_t firmware_version; - uint32_t fpga_version; - - if (aice_read_ctrl(AICE_READ_CTRL_GET_HARDWARE_VERSION, &hardware_version) != ERROR_OK) - return ERROR_FAIL; - - if (aice_read_ctrl(AICE_READ_CTRL_GET_FIRMWARE_VERSION, &firmware_version) != ERROR_OK) - return ERROR_FAIL; - - if (aice_read_ctrl(AICE_READ_CTRL_GET_FPGA_VERSION, &fpga_version) != ERROR_OK) - return ERROR_FAIL; - - LOG_INFO("AICE version: hw_ver = 0x%" PRIx32 ", fw_ver = 0x%" PRIx32 ", fpga_ver = 0x%" PRIx32, - hardware_version, firmware_version, fpga_version); - - return ERROR_OK; -} - -#define LINE_BUFFER_SIZE 1024 - -static int aice_execute_custom_script(const char *script) -{ - FILE *script_fd; - char line_buffer[LINE_BUFFER_SIZE]; - char *op_str; - char *reset_str; - uint32_t delay; - uint32_t write_ctrl_value; - bool set_op; - - script_fd = fopen(script, "r"); - if (script_fd == NULL) { - return ERROR_FAIL; - } else { - while (fgets(line_buffer, LINE_BUFFER_SIZE, script_fd) != NULL) { - /* execute operations */ - set_op = false; - op_str = strstr(line_buffer, "set"); - if (op_str != NULL) { - set_op = true; - goto get_reset_type; - } - - op_str = strstr(line_buffer, "clear"); - if (op_str == NULL) - continue; -get_reset_type: - reset_str = strstr(op_str, "srst"); - if (reset_str != NULL) { - if (set_op) - write_ctrl_value = AICE_CUSTOM_DELAY_SET_SRST; - else - write_ctrl_value = AICE_CUSTOM_DELAY_CLEAN_SRST; - goto get_delay; - } - reset_str = strstr(op_str, "dbgi"); - if (reset_str != NULL) { - if (set_op) - write_ctrl_value = AICE_CUSTOM_DELAY_SET_DBGI; - else - write_ctrl_value = AICE_CUSTOM_DELAY_CLEAN_DBGI; - goto get_delay; - } - reset_str = strstr(op_str, "trst"); - if (reset_str != NULL) { - if (set_op) - write_ctrl_value = AICE_CUSTOM_DELAY_SET_TRST; - else - write_ctrl_value = AICE_CUSTOM_DELAY_CLEAN_TRST; - goto get_delay; - } - continue; -get_delay: - /* get delay */ - delay = strtoul(reset_str + 4, NULL, 0); - write_ctrl_value |= (delay << 16); - - if (aice_write_ctrl(AICE_WRITE_CTRL_CUSTOM_DELAY, - write_ctrl_value) != ERROR_OK) { - fclose(script_fd); - return ERROR_FAIL; - } - } - fclose(script_fd); - } - - return ERROR_OK; -} - -static int aice_usb_set_clock(int set_clock) -{ - if (aice_write_ctrl(AICE_WRITE_CTRL_TCK_CONTROL, - AICE_TCK_CONTROL_TCK_SCAN) != ERROR_OK) - return ERROR_FAIL; - - /* Read out TCK_SCAN clock value */ - uint32_t scan_clock; - if (aice_read_ctrl(AICE_READ_CTRL_GET_ICE_STATE, &scan_clock) != ERROR_OK) - return ERROR_FAIL; - - scan_clock &= 0x0F; - - uint32_t scan_base_freq; - if (scan_clock & 0x8) - scan_base_freq = 48000; /* 48 MHz */ - else - scan_base_freq = 30000; /* 30 MHz */ - - uint32_t set_base_freq; - if (set_clock & 0x8) - set_base_freq = 48000; - else - set_base_freq = 30000; - - uint32_t set_freq; - uint32_t scan_freq; - set_freq = set_base_freq >> (set_clock & 0x7); - scan_freq = scan_base_freq >> (scan_clock & 0x7); - - if (scan_freq < set_freq) { - LOG_ERROR("User specifies higher jtag clock than TCK_SCAN clock"); - return ERROR_FAIL; - } - - if (aice_write_ctrl(AICE_WRITE_CTRL_TCK_CONTROL, set_clock) != ERROR_OK) - return ERROR_FAIL; - - uint32_t check_speed; - if (aice_read_ctrl(AICE_READ_CTRL_GET_ICE_STATE, &check_speed) != ERROR_OK) - return ERROR_FAIL; - - if (((int)check_speed & 0x0F) != set_clock) { - LOG_ERROR("Set jtag clock failed"); - return ERROR_FAIL; - } - - return ERROR_OK; -} - -static int aice_edm_init(uint32_t coreid) -{ - aice_write_edmsr(coreid, NDS_EDM_SR_DIMBR, 0xFFFF0000); - aice_write_misc(coreid, NDS_EDM_MISC_DIMIR, 0); - - /* unconditionally try to turn on V3_EDM_MODE */ - uint32_t edm_ctl_value; - aice_read_edmsr(coreid, NDS_EDM_SR_EDM_CTL, &edm_ctl_value); - aice_write_edmsr(coreid, NDS_EDM_SR_EDM_CTL, edm_ctl_value | 0x00000040); - - /* clear DBGER */ - aice_write_misc(coreid, NDS_EDM_MISC_DBGER, - NDS_DBGER_DPED | NDS_DBGER_CRST | NDS_DBGER_AT_MAX); - - /* get EDM version */ - uint32_t value_edmcfg; - aice_read_edmsr(coreid, NDS_EDM_SR_EDM_CFG, &value_edmcfg); - core_info[coreid].edm_version = (value_edmcfg >> 16) & 0xFFFF; - - return ERROR_OK; -} - -static bool is_v2_edm(uint32_t coreid) -{ - if ((core_info[coreid].edm_version & 0x1000) == 0) - return true; - else - return false; -} - -static int aice_init_edm_registers(uint32_t coreid, bool clear_dex_use_psw) -{ - /* enable DEH_SEL & MAX_STOP & V3_EDM_MODE & DBGI_MASK */ - uint32_t host_edm_ctl = core_info[coreid].edm_ctl_backup | 0xA000004F; - if (clear_dex_use_psw) - /* After entering debug mode, OpenOCD may set - * DEX_USE_PSW accidentally through backup value - * of target EDM_CTL. - * So, clear DEX_USE_PSW by force. */ - host_edm_ctl &= ~(0x40000000); - - LOG_DEBUG("aice_init_edm_registers - EDM_CTL: 0x%08" PRIx32, host_edm_ctl); - - int result = aice_write_edmsr(coreid, NDS_EDM_SR_EDM_CTL, host_edm_ctl); - - return result; -} - -/** - * EDM_CTL will be modified by OpenOCD as debugging. OpenOCD has the - * responsibility to keep EDM_CTL untouched after debugging. - * - * There are two scenarios to consider: - * 1. single step/running as debugging (running under debug session) - * 2. detached from gdb (exit debug session) - * - * So, we need to bakcup EDM_CTL before halted and restore it after - * running. The difference of these two scenarios is EDM_CTL.DEH_SEL - * is on for scenario 1, and off for scenario 2. - */ -static int aice_backup_edm_registers(uint32_t coreid) -{ - int result = aice_read_edmsr(coreid, NDS_EDM_SR_EDM_CTL, - &core_info[coreid].edm_ctl_backup); - - /* To call aice_backup_edm_registers() after DEX on, DEX_USE_PSW - * may be not correct. (For example, hit breakpoint, then backup - * EDM_CTL. EDM_CTL.DEX_USE_PSW will be cleared.) Because debug - * interrupt will clear DEX_USE_PSW, DEX_USE_PSW is always off after - * DEX is on. It only backups correct value before OpenOCD issues DBGI. - * (Backup EDM_CTL, then issue DBGI actively (refer aice_usb_halt())) */ - if (core_info[coreid].edm_ctl_backup & 0x40000000) - core_info[coreid].dex_use_psw_on = true; - else - core_info[coreid].dex_use_psw_on = false; - - LOG_DEBUG("aice_backup_edm_registers - EDM_CTL: 0x%08" PRIx32 ", DEX_USE_PSW: %s", - core_info[coreid].edm_ctl_backup, - core_info[coreid].dex_use_psw_on ? "on" : "off"); - - return result; -} - -static int aice_restore_edm_registers(uint32_t coreid) -{ - LOG_DEBUG("aice_restore_edm_registers -"); - - /* set DEH_SEL, because target still under EDM control */ - int result = aice_write_edmsr(coreid, NDS_EDM_SR_EDM_CTL, - core_info[coreid].edm_ctl_backup | 0x80000000); - - return result; -} - -static int aice_backup_tmp_registers(uint32_t coreid) -{ - LOG_DEBUG("backup_tmp_registers -"); - - /* backup target DTR first(if the target DTR is valid) */ - uint32_t value_edmsw; - aice_read_edmsr(coreid, NDS_EDM_SR_EDMSW, &value_edmsw); - core_info[coreid].edmsw_backup = value_edmsw; - if (value_edmsw & 0x1) { /* EDMSW.WDV == 1 */ - aice_read_dtr(coreid, &core_info[coreid].target_dtr_backup); - core_info[coreid].target_dtr_valid = true; - - LOG_DEBUG("Backup target DTR: 0x%08" PRIx32, core_info[coreid].target_dtr_backup); - } else { - core_info[coreid].target_dtr_valid = false; - } - - /* Target DTR has been backup, then backup $R0 and $R1 */ - aice_read_reg(coreid, R0, &core_info[coreid].r0_backup); - aice_read_reg(coreid, R1, &core_info[coreid].r1_backup); - - /* backup host DTR(if the host DTR is valid) */ - if (value_edmsw & 0x2) { /* EDMSW.RDV == 1*/ - /* read out host DTR and write into target DTR, then use aice_read_edmsr to - * read out */ - uint32_t instructions[4] = { - MFSR_DTR(R0), /* R0 has already been backup */ - DSB, - MTSR_DTR(R0), - BEQ_MINUS_12 - }; - aice_execute_dim(coreid, instructions, 4); - - aice_read_dtr(coreid, &core_info[coreid].host_dtr_backup); - core_info[coreid].host_dtr_valid = true; - - LOG_DEBUG("Backup host DTR: 0x%08" PRIx32, core_info[coreid].host_dtr_backup); - } else { - core_info[coreid].host_dtr_valid = false; - } - - LOG_DEBUG("r0: 0x%08" PRIx32 ", r1: 0x%08" PRIx32, - core_info[coreid].r0_backup, core_info[coreid].r1_backup); - - return ERROR_OK; -} - -static int aice_restore_tmp_registers(uint32_t coreid) -{ - LOG_DEBUG("restore_tmp_registers - r0: 0x%08" PRIx32 ", r1: 0x%08" PRIx32, - core_info[coreid].r0_backup, core_info[coreid].r1_backup); - - if (core_info[coreid].target_dtr_valid) { - uint32_t instructions[4] = { - SETHI(R0, core_info[coreid].target_dtr_backup >> 12), - ORI(R0, R0, core_info[coreid].target_dtr_backup & 0x00000FFF), - NOP, - BEQ_MINUS_12 - }; - aice_execute_dim(coreid, instructions, 4); - - instructions[0] = MTSR_DTR(R0); - instructions[1] = DSB; - instructions[2] = NOP; - instructions[3] = BEQ_MINUS_12; - aice_execute_dim(coreid, instructions, 4); - - LOG_DEBUG("Restore target DTR: 0x%08" PRIx32, core_info[coreid].target_dtr_backup); - } - - aice_write_reg(coreid, R0, core_info[coreid].r0_backup); - aice_write_reg(coreid, R1, core_info[coreid].r1_backup); - - if (core_info[coreid].host_dtr_valid) { - aice_write_dtr(coreid, core_info[coreid].host_dtr_backup); - - LOG_DEBUG("Restore host DTR: 0x%08" PRIx32, core_info[coreid].host_dtr_backup); - } - - return ERROR_OK; -} - -static int aice_open_device(struct aice_port_param_s *param) -{ - if (ERROR_OK != aice_usb_open(param)) - return ERROR_FAIL; - - if (ERROR_FAIL == aice_get_version_info()) { - LOG_ERROR("Cannot get AICE version!"); - return ERROR_FAIL; - } - - LOG_INFO("AICE initialization started"); - - /* attempt to reset Andes EDM */ - if (ERROR_FAIL == aice_reset_box()) { - LOG_ERROR("Cannot initial AICE box!"); - return ERROR_FAIL; - } - - return ERROR_OK; -} - -static int aice_usb_set_jtag_clock(uint32_t a_clock) -{ - jtag_clock = a_clock; - - if (ERROR_OK != aice_usb_set_clock(a_clock)) { - LOG_ERROR("Cannot set AICE JTAG clock!"); - return ERROR_FAIL; - } - - return ERROR_OK; -} - -static int aice_usb_close(void) -{ - jtag_libusb_close(aice_handler.usb_handle); - - if (custom_srst_script) - free(custom_srst_script); - - if (custom_trst_script) - free(custom_trst_script); - - if (custom_restart_script) - free(custom_restart_script); - - return ERROR_OK; -} - -static int aice_core_init(uint32_t coreid) -{ - core_info[coreid].access_channel = NDS_MEMORY_ACC_CPU; - core_info[coreid].memory_select = NDS_MEMORY_SELECT_AUTO; - core_info[coreid].core_state = AICE_TARGET_UNKNOWN; - - return ERROR_OK; -} - -static int aice_usb_idcode(uint32_t *idcode, uint8_t *num_of_idcode) -{ - int retval; - - retval = aice_scan_chain(idcode, num_of_idcode); - if (ERROR_OK == retval) { - for (int i = 0; i < *num_of_idcode; i++) { - aice_core_init(i); - aice_edm_init(i); - } - total_num_of_core = *num_of_idcode; - } - - return retval; -} - -static int aice_usb_halt(uint32_t coreid) -{ - if (core_info[coreid].core_state == AICE_TARGET_HALTED) { - LOG_DEBUG("aice_usb_halt check halted"); - return ERROR_OK; - } - - LOG_DEBUG("aice_usb_halt"); - - /** backup EDM registers */ - aice_backup_edm_registers(coreid); - /** init EDM for host debugging */ - /** no need to clear dex_use_psw, because dbgi will clear it */ - aice_init_edm_registers(coreid, false); - - /** Clear EDM_CTL.DBGIM & EDM_CTL.DBGACKM */ - uint32_t edm_ctl_value; - aice_read_edmsr(coreid, NDS_EDM_SR_EDM_CTL, &edm_ctl_value); - if (edm_ctl_value & 0x3) - aice_write_edmsr(coreid, NDS_EDM_SR_EDM_CTL, edm_ctl_value & ~(0x3)); - - uint32_t dbger; - uint32_t acc_ctl_value; - - core_info[coreid].debug_under_dex_on = false; - aice_read_misc(coreid, NDS_EDM_MISC_DBGER, &dbger); - - if (dbger & NDS_DBGER_AT_MAX) - LOG_ERROR("<-- TARGET ERROR! Reaching the max interrupt stack level. -->"); - - if (dbger & NDS_DBGER_DEX) { - if (is_v2_edm(coreid) == false) { - /** debug 'debug mode'. use force_debug to issue dbgi */ - aice_read_misc(coreid, NDS_EDM_MISC_ACC_CTL, &acc_ctl_value); - acc_ctl_value |= 0x8; - aice_write_misc(coreid, NDS_EDM_MISC_ACC_CTL, acc_ctl_value); - core_info[coreid].debug_under_dex_on = true; - - aice_write_misc(coreid, NDS_EDM_MISC_EDM_CMDR, 0); - /* If CPU stalled due to AT_MAX, clear AT_MAX status. */ - if (dbger & NDS_DBGER_AT_MAX) - aice_write_misc(coreid, NDS_EDM_MISC_DBGER, NDS_DBGER_AT_MAX); - } - } else { - /** Issue DBGI normally */ - aice_write_misc(coreid, NDS_EDM_MISC_EDM_CMDR, 0); - /* If CPU stalled due to AT_MAX, clear AT_MAX status. */ - if (dbger & NDS_DBGER_AT_MAX) - aice_write_misc(coreid, NDS_EDM_MISC_DBGER, NDS_DBGER_AT_MAX); - } - - if (aice_check_dbger(coreid, NDS_DBGER_DEX) != ERROR_OK) { - LOG_ERROR("<-- TARGET ERROR! Unable to stop the debug target through DBGI. -->"); - return ERROR_FAIL; - } - - if (core_info[coreid].debug_under_dex_on) { - if (core_info[coreid].dex_use_psw_on == false) { - /* under debug 'debug mode', force $psw to 'debug mode' bahavior */ - /* !!!NOTICE!!! this is workaround for debug 'debug mode'. - * it is only for debugging 'debug exception handler' purpose. - * after openocd detaches from target, target behavior is - * undefined. */ - uint32_t ir0_value; - uint32_t debug_mode_ir0_value; - aice_read_reg(coreid, IR0, &ir0_value); - debug_mode_ir0_value = ir0_value | 0x408; /* turn on DEX, set POM = 1 */ - debug_mode_ir0_value &= ~(0x000000C1); /* turn off DT/IT/GIE */ - aice_write_reg(coreid, IR0, debug_mode_ir0_value); - } - } - - /** set EDM_CTL.DBGIM & EDM_CTL.DBGACKM after halt */ - if (edm_ctl_value & 0x3) - aice_write_edmsr(coreid, NDS_EDM_SR_EDM_CTL, edm_ctl_value); - - /* backup r0 & r1 */ - aice_backup_tmp_registers(coreid); - core_info[coreid].core_state = AICE_TARGET_HALTED; - - return ERROR_OK; -} - -static int aice_usb_state(uint32_t coreid, enum aice_target_state_s *state) -{ - uint32_t dbger_value; - uint32_t ice_state; - - int result = aice_read_misc(coreid, NDS_EDM_MISC_DBGER, &dbger_value); - - if (ERROR_AICE_TIMEOUT == result) { - if (aice_read_ctrl(AICE_READ_CTRL_GET_ICE_STATE, &ice_state) != ERROR_OK) { - LOG_ERROR("<-- AICE ERROR! AICE is unplugged. -->"); - return ERROR_FAIL; - } - - if ((ice_state & 0x20) == 0) { - LOG_ERROR("<-- TARGET ERROR! Target is disconnected with AICE. -->"); - return ERROR_FAIL; - } else { - return ERROR_FAIL; - } - } else if (ERROR_AICE_DISCONNECT == result) { - LOG_ERROR("<-- AICE ERROR! AICE is unplugged. -->"); - return ERROR_FAIL; - } - - if ((dbger_value & NDS_DBGER_ILL_SEC_ACC) == NDS_DBGER_ILL_SEC_ACC) { - LOG_ERROR("<-- TARGET ERROR! Insufficient security privilege. -->"); - - /* Clear ILL_SEC_ACC */ - aice_write_misc(coreid, NDS_EDM_MISC_DBGER, NDS_DBGER_ILL_SEC_ACC); - - *state = AICE_TARGET_RUNNING; - core_info[coreid].core_state = AICE_TARGET_RUNNING; - } else if ((dbger_value & NDS_DBGER_AT_MAX) == NDS_DBGER_AT_MAX) { - /* Issue DBGI to exit cpu stall */ - aice_usb_halt(coreid); - - /* Read OIPC to find out the trigger point */ - uint32_t ir11_value; - aice_read_reg(coreid, IR11, &ir11_value); - - LOG_ERROR("<-- TARGET ERROR! Reaching the max interrupt stack level; " - "CPU is stalled at 0x%08" PRIx32 " for debugging. -->", ir11_value); - - *state = AICE_TARGET_HALTED; - } else if ((dbger_value & NDS_DBGER_CRST) == NDS_DBGER_CRST) { - LOG_DEBUG("DBGER.CRST is on."); - - *state = AICE_TARGET_RESET; - core_info[coreid].core_state = AICE_TARGET_RUNNING; - - /* Clear CRST */ - aice_write_misc(coreid, NDS_EDM_MISC_DBGER, NDS_DBGER_CRST); - } else if ((dbger_value & NDS_DBGER_DEX) == NDS_DBGER_DEX) { - if (AICE_TARGET_RUNNING == core_info[coreid].core_state) { - /* enter debug mode, init EDM registers */ - /* backup EDM registers */ - aice_backup_edm_registers(coreid); - /* init EDM for host debugging */ - aice_init_edm_registers(coreid, true); - aice_backup_tmp_registers(coreid); - core_info[coreid].core_state = AICE_TARGET_HALTED; - } else if (AICE_TARGET_UNKNOWN == core_info[coreid].core_state) { - /* debug 'debug mode', use force debug to halt core */ - aice_usb_halt(coreid); - } - *state = AICE_TARGET_HALTED; - } else { - *state = AICE_TARGET_RUNNING; - core_info[coreid].core_state = AICE_TARGET_RUNNING; - } - - return ERROR_OK; -} - -static int aice_usb_reset(void) -{ - if (aice_reset_box() != ERROR_OK) - return ERROR_FAIL; - - /* issue TRST */ - if (custom_trst_script == NULL) { - if (aice_write_ctrl(AICE_WRITE_CTRL_JTAG_PIN_CONTROL, - AICE_JTAG_PIN_CONTROL_TRST) != ERROR_OK) - return ERROR_FAIL; - } else { - /* custom trst operations */ - if (aice_execute_custom_script(custom_trst_script) != ERROR_OK) - return ERROR_FAIL; - } - - if (aice_usb_set_clock(jtag_clock) != ERROR_OK) - return ERROR_FAIL; - - return ERROR_OK; -} - -static int aice_issue_srst(uint32_t coreid) -{ - LOG_DEBUG("aice_issue_srst"); - - /* After issuing srst, target will be running. So we need to restore EDM_CTL. */ - aice_restore_edm_registers(coreid); - - if (custom_srst_script == NULL) { - if (aice_write_ctrl(AICE_WRITE_CTRL_JTAG_PIN_CONTROL, - AICE_JTAG_PIN_CONTROL_SRST) != ERROR_OK) - return ERROR_FAIL; - } else { - /* custom srst operations */ - if (aice_execute_custom_script(custom_srst_script) != ERROR_OK) - return ERROR_FAIL; - } - - /* wait CRST infinitely */ - uint32_t dbger_value; - int i = 0; - while (1) { - if (aice_read_misc(coreid, - NDS_EDM_MISC_DBGER, &dbger_value) != ERROR_OK) - return ERROR_FAIL; - - if (dbger_value & NDS_DBGER_CRST) - break; - - if ((i % 30) == 0) - keep_alive(); - i++; - } - - core_info[coreid].host_dtr_valid = false; - core_info[coreid].target_dtr_valid = false; - - core_info[coreid].core_state = AICE_TARGET_RUNNING; - return ERROR_OK; -} - -static int aice_issue_reset_hold(uint32_t coreid) -{ - LOG_DEBUG("aice_issue_reset_hold"); - - /* set no_dbgi_pin to 0 */ - uint32_t pin_status; - aice_read_ctrl(AICE_READ_CTRL_GET_JTAG_PIN_STATUS, &pin_status); - if (pin_status | 0x4) - aice_write_ctrl(AICE_WRITE_CTRL_JTAG_PIN_STATUS, pin_status & (~0x4)); - - /* issue restart */ - if (custom_restart_script == NULL) { - if (aice_write_ctrl(AICE_WRITE_CTRL_JTAG_PIN_CONTROL, - AICE_JTAG_PIN_CONTROL_RESTART) != ERROR_OK) - return ERROR_FAIL; - } else { - /* custom restart operations */ - if (aice_execute_custom_script(custom_restart_script) != ERROR_OK) - return ERROR_FAIL; - } - - if (aice_check_dbger(coreid, NDS_DBGER_CRST | NDS_DBGER_DEX) == ERROR_OK) { - aice_backup_tmp_registers(coreid); - core_info[coreid].core_state = AICE_TARGET_HALTED; - - return ERROR_OK; - } else { - /* set no_dbgi_pin to 1 */ - aice_write_ctrl(AICE_WRITE_CTRL_JTAG_PIN_STATUS, pin_status | 0x4); - - /* issue restart again */ - if (custom_restart_script == NULL) { - if (aice_write_ctrl(AICE_WRITE_CTRL_JTAG_PIN_CONTROL, - AICE_JTAG_PIN_CONTROL_RESTART) != ERROR_OK) - return ERROR_FAIL; - } else { - /* custom restart operations */ - if (aice_execute_custom_script(custom_restart_script) != ERROR_OK) - return ERROR_FAIL; - } - - if (aice_check_dbger(coreid, NDS_DBGER_CRST | NDS_DBGER_DEX) == ERROR_OK) { - aice_backup_tmp_registers(coreid); - core_info[coreid].core_state = AICE_TARGET_HALTED; - - return ERROR_OK; - } - - /* do software reset-and-hold */ - aice_issue_srst(coreid); - aice_usb_halt(coreid); - - uint32_t value_ir3; - aice_read_reg(coreid, IR3, &value_ir3); - aice_write_reg(coreid, PC, value_ir3 & 0xFFFF0000); - } - - return ERROR_FAIL; -} - -static int aice_issue_reset_hold_multi(void) -{ - uint32_t write_ctrl_value = 0; - - /* set SRST */ - write_ctrl_value = AICE_CUSTOM_DELAY_SET_SRST; - write_ctrl_value |= (0x200 << 16); - if (aice_write_ctrl(AICE_WRITE_CTRL_CUSTOM_DELAY, - write_ctrl_value) != ERROR_OK) - return ERROR_FAIL; - - for (uint8_t i = 0 ; i < total_num_of_core ; i++) - aice_write_misc(i, NDS_EDM_MISC_EDM_CMDR, 0); - - /* clear SRST */ - write_ctrl_value = AICE_CUSTOM_DELAY_CLEAN_SRST; - write_ctrl_value |= (0x200 << 16); - if (aice_write_ctrl(AICE_WRITE_CTRL_CUSTOM_DELAY, - write_ctrl_value) != ERROR_OK) - return ERROR_FAIL; - - for (uint8_t i = 0; i < total_num_of_core; i++) - aice_edm_init(i); - - return ERROR_FAIL; -} - -static int aice_usb_assert_srst(uint32_t coreid, enum aice_srst_type_s srst) -{ - if ((AICE_SRST != srst) && (AICE_RESET_HOLD != srst)) - return ERROR_FAIL; - - /* clear DBGER */ - if (aice_write_misc(coreid, NDS_EDM_MISC_DBGER, - NDS_DBGER_CLEAR_ALL) != ERROR_OK) - return ERROR_FAIL; - - int result = ERROR_OK; - if (AICE_SRST == srst) - result = aice_issue_srst(coreid); - else { - if (1 == total_num_of_core) - result = aice_issue_reset_hold(coreid); - else - result = aice_issue_reset_hold_multi(); - } - - /* Clear DBGER.CRST after reset to avoid 'core-reset checking' errors. - * assert_srst is user-intentional reset behavior, so we could - * clear DBGER.CRST safely. - */ - if (aice_write_misc(coreid, - NDS_EDM_MISC_DBGER, NDS_DBGER_CRST) != ERROR_OK) - return ERROR_FAIL; - - return result; -} - -static int aice_usb_run(uint32_t coreid) -{ - LOG_DEBUG("aice_usb_run"); - - uint32_t dbger_value; - if (aice_read_misc(coreid, - NDS_EDM_MISC_DBGER, &dbger_value) != ERROR_OK) - return ERROR_FAIL; - - if ((dbger_value & NDS_DBGER_DEX) != NDS_DBGER_DEX) { - LOG_WARNING("<-- TARGET WARNING! The debug target exited " - "the debug mode unexpectedly. -->"); - return ERROR_FAIL; - } - - /* restore r0 & r1 before free run */ - aice_restore_tmp_registers(coreid); - core_info[coreid].core_state = AICE_TARGET_RUNNING; - - /* clear DBGER */ - aice_write_misc(coreid, NDS_EDM_MISC_DBGER, - NDS_DBGER_CLEAR_ALL); - - /** restore EDM registers */ - /** OpenOCD should restore EDM_CTL **before** to exit debug state. - * Otherwise, following instruction will read wrong EDM_CTL value. - * - * pc -> mfsr $p0, EDM_CTL (single step) - * slli $p0, $p0, 1 - * slri $p0, $p0, 31 - */ - aice_restore_edm_registers(coreid); - - /** execute instructions in DIM */ - uint32_t instructions[4] = { - NOP, - NOP, - NOP, - IRET - }; - int result = aice_execute_dim(coreid, instructions, 4); - - return result; -} - -static int aice_usb_step(uint32_t coreid) -{ - LOG_DEBUG("aice_usb_step"); - - uint32_t ir0_value; - uint32_t ir0_reg_num; - - if (is_v2_edm(coreid) == true) - /* V2 EDM will push interrupt stack as debug exception */ - ir0_reg_num = IR1; - else - ir0_reg_num = IR0; - - /** enable HSS */ - aice_read_reg(coreid, ir0_reg_num, &ir0_value); - if ((ir0_value & 0x800) == 0) { - /** set PSW.HSS */ - ir0_value |= (0x01 << 11); - aice_write_reg(coreid, ir0_reg_num, ir0_value); - } - - if (ERROR_FAIL == aice_usb_run(coreid)) - return ERROR_FAIL; - - int i = 0; - enum aice_target_state_s state; - while (1) { - /* read DBGER */ - if (aice_usb_state(coreid, &state) != ERROR_OK) - return ERROR_FAIL; - - if (AICE_TARGET_HALTED == state) - break; - - int64_t then = 0; - if (i == 30) - then = timeval_ms(); - - if (i >= 30) { - if ((timeval_ms() - then) > 1000) - LOG_WARNING("Timeout (1000ms) waiting for halt to complete"); - - return ERROR_FAIL; - } - i++; - } - - /** disable HSS */ - aice_read_reg(coreid, ir0_reg_num, &ir0_value); - ir0_value &= ~(0x01 << 11); - aice_write_reg(coreid, ir0_reg_num, ir0_value); - - return ERROR_OK; -} - -static int aice_usb_read_mem_b_bus(uint32_t coreid, uint32_t address, uint32_t *data) -{ - return aice_read_mem_b(coreid, address, data); -} - -static int aice_usb_read_mem_h_bus(uint32_t coreid, uint32_t address, uint32_t *data) -{ - return aice_read_mem_h(coreid, address, data); -} - -static int aice_usb_read_mem_w_bus(uint32_t coreid, uint32_t address, uint32_t *data) -{ - return aice_read_mem(coreid, address, data); -} - -static int aice_usb_read_mem_b_dim(uint32_t coreid, uint32_t address, uint32_t *data) -{ - uint32_t value; - uint32_t instructions[4] = { - LBI_BI(R1, R0), - MTSR_DTR(R1), - DSB, - BEQ_MINUS_12 - }; - - aice_execute_dim(coreid, instructions, 4); - - aice_read_dtr(coreid, &value); - *data = value & 0xFF; - - return ERROR_OK; -} - -static int aice_usb_read_mem_h_dim(uint32_t coreid, uint32_t address, uint32_t *data) -{ - uint32_t value; - uint32_t instructions[4] = { - LHI_BI(R1, R0), - MTSR_DTR(R1), - DSB, - BEQ_MINUS_12 - }; - - aice_execute_dim(coreid, instructions, 4); - - aice_read_dtr(coreid, &value); - *data = value & 0xFFFF; - - return ERROR_OK; -} - -static int aice_usb_read_mem_w_dim(uint32_t coreid, uint32_t address, uint32_t *data) -{ - uint32_t instructions[4] = { - LWI_BI(R1, R0), - MTSR_DTR(R1), - DSB, - BEQ_MINUS_12 - }; - - aice_execute_dim(coreid, instructions, 4); - - aice_read_dtr(coreid, data); - - return ERROR_OK; -} - -static int aice_usb_set_address_dim(uint32_t coreid, uint32_t address) -{ - uint32_t instructions[4] = { - SETHI(R0, address >> 12), - ORI(R0, R0, address & 0x00000FFF), - NOP, - BEQ_MINUS_12 - }; - - return aice_execute_dim(coreid, instructions, 4); -} - -static int aice_usb_read_memory_unit(uint32_t coreid, uint32_t addr, uint32_t size, - uint32_t count, uint8_t *buffer) -{ - LOG_DEBUG("aice_usb_read_memory_unit, addr: 0x%08" PRIx32 - ", size: %" PRIu32 ", count: %" PRIu32 "", - addr, size, count); - - if (NDS_MEMORY_ACC_CPU == core_info[coreid].access_channel) - aice_usb_set_address_dim(coreid, addr); - - uint32_t value; - size_t i; - read_mem_func_t read_mem_func; - - switch (size) { - case 1: - if (NDS_MEMORY_ACC_BUS == core_info[coreid].access_channel) - read_mem_func = aice_usb_read_mem_b_bus; - else - read_mem_func = aice_usb_read_mem_b_dim; - - for (i = 0; i < count; i++) { - read_mem_func(coreid, addr, &value); - *buffer++ = (uint8_t)value; - addr++; - } - break; - case 2: - if (NDS_MEMORY_ACC_BUS == core_info[coreid].access_channel) - read_mem_func = aice_usb_read_mem_h_bus; - else - read_mem_func = aice_usb_read_mem_h_dim; - - for (i = 0; i < count; i++) { - read_mem_func(coreid, addr, &value); - uint16_t svalue = value; - memcpy(buffer, &svalue, sizeof(uint16_t)); - buffer += 2; - addr += 2; - } - break; - case 4: - if (NDS_MEMORY_ACC_BUS == core_info[coreid].access_channel) - read_mem_func = aice_usb_read_mem_w_bus; - else - read_mem_func = aice_usb_read_mem_w_dim; - - for (i = 0; i < count; i++) { - read_mem_func(coreid, addr, &value); - memcpy(buffer, &value, sizeof(uint32_t)); - buffer += 4; - addr += 4; - } - break; - } - - return ERROR_OK; -} - -static int aice_usb_write_mem_b_bus(uint32_t coreid, uint32_t address, uint32_t data) -{ - return aice_write_mem_b(coreid, address, data); -} - -static int aice_usb_write_mem_h_bus(uint32_t coreid, uint32_t address, uint32_t data) -{ - return aice_write_mem_h(coreid, address, data); -} - -static int aice_usb_write_mem_w_bus(uint32_t coreid, uint32_t address, uint32_t data) -{ - return aice_write_mem(coreid, address, data); -} - -static int aice_usb_write_mem_b_dim(uint32_t coreid, uint32_t address, uint32_t data) -{ - uint32_t instructions[4] = { - MFSR_DTR(R1), - SBI_BI(R1, R0), - DSB, - BEQ_MINUS_12 - }; - - aice_write_dtr(coreid, data & 0xFF); - aice_execute_dim(coreid, instructions, 4); - - return ERROR_OK; -} - -static int aice_usb_write_mem_h_dim(uint32_t coreid, uint32_t address, uint32_t data) -{ - uint32_t instructions[4] = { - MFSR_DTR(R1), - SHI_BI(R1, R0), - DSB, - BEQ_MINUS_12 - }; - - aice_write_dtr(coreid, data & 0xFFFF); - aice_execute_dim(coreid, instructions, 4); - - return ERROR_OK; -} - -static int aice_usb_write_mem_w_dim(uint32_t coreid, uint32_t address, uint32_t data) -{ - uint32_t instructions[4] = { - MFSR_DTR(R1), - SWI_BI(R1, R0), - DSB, - BEQ_MINUS_12 - }; - - aice_write_dtr(coreid, data); - aice_execute_dim(coreid, instructions, 4); - - return ERROR_OK; -} - -static int aice_usb_write_memory_unit(uint32_t coreid, uint32_t addr, uint32_t size, - uint32_t count, const uint8_t *buffer) -{ - LOG_DEBUG("aice_usb_write_memory_unit, addr: 0x%08" PRIx32 - ", size: %" PRIu32 ", count: %" PRIu32 "", - addr, size, count); - - if (NDS_MEMORY_ACC_CPU == core_info[coreid].access_channel) - aice_usb_set_address_dim(coreid, addr); - - size_t i; - write_mem_func_t write_mem_func; - - switch (size) { - case 1: - if (NDS_MEMORY_ACC_BUS == core_info[coreid].access_channel) - write_mem_func = aice_usb_write_mem_b_bus; - else - write_mem_func = aice_usb_write_mem_b_dim; - - for (i = 0; i < count; i++) { - write_mem_func(coreid, addr, *buffer); - buffer++; - addr++; - } - break; - case 2: - if (NDS_MEMORY_ACC_BUS == core_info[coreid].access_channel) - write_mem_func = aice_usb_write_mem_h_bus; - else - write_mem_func = aice_usb_write_mem_h_dim; - - for (i = 0; i < count; i++) { - uint16_t value; - memcpy(&value, buffer, sizeof(uint16_t)); - - write_mem_func(coreid, addr, value); - buffer += 2; - addr += 2; - } - break; - case 4: - if (NDS_MEMORY_ACC_BUS == core_info[coreid].access_channel) - write_mem_func = aice_usb_write_mem_w_bus; - else - write_mem_func = aice_usb_write_mem_w_dim; - - for (i = 0; i < count; i++) { - uint32_t value; - memcpy(&value, buffer, sizeof(uint32_t)); - - write_mem_func(coreid, addr, value); - buffer += 4; - addr += 4; - } - break; - } - - return ERROR_OK; -} - -static int aice_bulk_read_mem(uint32_t coreid, uint32_t addr, uint32_t count, - uint8_t *buffer) -{ - uint32_t packet_size; - - while (count > 0) { - packet_size = (count >= 0x100) ? 0x100 : count; - - /** set address */ - addr &= 0xFFFFFFFC; - if (aice_write_misc(coreid, NDS_EDM_MISC_SBAR, addr) != ERROR_OK) - return ERROR_FAIL; - - if (aice_fastread_mem(coreid, buffer, - packet_size) != ERROR_OK) - return ERROR_FAIL; - - buffer += (packet_size * 4); - addr += (packet_size * 4); - count -= packet_size; - } - - return ERROR_OK; -} - -static int aice_bulk_write_mem(uint32_t coreid, uint32_t addr, uint32_t count, - const uint8_t *buffer) -{ - uint32_t packet_size; - - while (count > 0) { - packet_size = (count >= 0x100) ? 0x100 : count; - - /** set address */ - addr &= 0xFFFFFFFC; - if (aice_write_misc(coreid, NDS_EDM_MISC_SBAR, addr | 1) != ERROR_OK) - return ERROR_FAIL; - - if (aice_fastwrite_mem(coreid, buffer, - packet_size) != ERROR_OK) - return ERROR_FAIL; - - buffer += (packet_size * 4); - addr += (packet_size * 4); - count -= packet_size; - } - - return ERROR_OK; -} - -static int aice_usb_bulk_read_mem(uint32_t coreid, uint32_t addr, - uint32_t length, uint8_t *buffer) -{ - LOG_DEBUG("aice_usb_bulk_read_mem, addr: 0x%08" PRIx32 ", length: 0x%08" PRIx32, addr, length); - - int retval; - - if (NDS_MEMORY_ACC_CPU == core_info[coreid].access_channel) - aice_usb_set_address_dim(coreid, addr); - - if (NDS_MEMORY_ACC_CPU == core_info[coreid].access_channel) - retval = aice_usb_read_memory_unit(coreid, addr, 4, length / 4, buffer); - else - retval = aice_bulk_read_mem(coreid, addr, length / 4, buffer); - - return retval; -} - -static int aice_usb_bulk_write_mem(uint32_t coreid, uint32_t addr, - uint32_t length, const uint8_t *buffer) -{ - LOG_DEBUG("aice_usb_bulk_write_mem, addr: 0x%08" PRIx32 ", length: 0x%08" PRIx32, addr, length); - - int retval; - - if (NDS_MEMORY_ACC_CPU == core_info[coreid].access_channel) - aice_usb_set_address_dim(coreid, addr); - - if (NDS_MEMORY_ACC_CPU == core_info[coreid].access_channel) - retval = aice_usb_write_memory_unit(coreid, addr, 4, length / 4, buffer); - else - retval = aice_bulk_write_mem(coreid, addr, length / 4, buffer); - - return retval; -} - -static int aice_usb_read_debug_reg(uint32_t coreid, uint32_t addr, uint32_t *val) -{ - if (AICE_TARGET_HALTED == core_info[coreid].core_state) { - if (NDS_EDM_SR_EDMSW == addr) { - *val = core_info[coreid].edmsw_backup; - } else if (NDS_EDM_SR_EDM_DTR == addr) { - if (core_info[coreid].target_dtr_valid) { - /* if EDM_DTR has read out, clear it. */ - *val = core_info[coreid].target_dtr_backup; - core_info[coreid].edmsw_backup &= (~0x1); - core_info[coreid].target_dtr_valid = false; - } else { - *val = 0; - } - } - } - - return aice_read_edmsr(coreid, addr, val); -} - -static int aice_usb_write_debug_reg(uint32_t coreid, uint32_t addr, const uint32_t val) -{ - if (AICE_TARGET_HALTED == core_info[coreid].core_state) { - if (NDS_EDM_SR_EDM_DTR == addr) { - core_info[coreid].host_dtr_backup = val; - core_info[coreid].edmsw_backup |= 0x2; - core_info[coreid].host_dtr_valid = true; - } - } - - return aice_write_edmsr(coreid, addr, val); -} - -static int aice_usb_memory_access(uint32_t coreid, enum nds_memory_access channel) -{ - LOG_DEBUG("aice_usb_memory_access, access channel: %u", channel); - - core_info[coreid].access_channel = channel; - - return ERROR_OK; -} - -static int aice_usb_memory_mode(uint32_t coreid, enum nds_memory_select mem_select) -{ - if (core_info[coreid].memory_select == mem_select) - return ERROR_OK; - - LOG_DEBUG("aice_usb_memory_mode, memory select: %u", mem_select); - - core_info[coreid].memory_select = mem_select; - - if (NDS_MEMORY_SELECT_AUTO != core_info[coreid].memory_select) - aice_write_misc(coreid, NDS_EDM_MISC_ACC_CTL, - core_info[coreid].memory_select - 1); - else - aice_write_misc(coreid, NDS_EDM_MISC_ACC_CTL, - NDS_MEMORY_SELECT_MEM - 1); - - return ERROR_OK; -} - -static int aice_usb_read_tlb(uint32_t coreid, uint32_t virtual_address, - uint32_t *physical_address) -{ - LOG_DEBUG("aice_usb_read_tlb, virtual address: 0x%08" PRIx32, virtual_address); - - uint32_t instructions[4]; - uint32_t probe_result; - uint32_t value_mr3; - uint32_t value_mr4; - uint32_t access_page_size; - uint32_t virtual_offset; - uint32_t physical_page_number; - - aice_write_dtr(coreid, virtual_address); - - /* probe TLB first */ - instructions[0] = MFSR_DTR(R0); - instructions[1] = TLBOP_TARGET_PROBE(R1, R0); - instructions[2] = DSB; - instructions[3] = BEQ_MINUS_12; - aice_execute_dim(coreid, instructions, 4); - - aice_read_reg(coreid, R1, &probe_result); - - if (probe_result & 0x80000000) - return ERROR_FAIL; - - /* read TLB entry */ - aice_write_dtr(coreid, probe_result & 0x7FF); - - /* probe TLB first */ - instructions[0] = MFSR_DTR(R0); - instructions[1] = TLBOP_TARGET_READ(R0); - instructions[2] = DSB; - instructions[3] = BEQ_MINUS_12; - aice_execute_dim(coreid, instructions, 4); - - /* TODO: it should backup mr3, mr4 */ - aice_read_reg(coreid, MR3, &value_mr3); - aice_read_reg(coreid, MR4, &value_mr4); - - access_page_size = value_mr4 & 0xF; - if (0 == access_page_size) { /* 4K page */ - virtual_offset = virtual_address & 0x00000FFF; - physical_page_number = value_mr3 & 0xFFFFF000; - } else if (1 == access_page_size) { /* 8K page */ - virtual_offset = virtual_address & 0x00001FFF; - physical_page_number = value_mr3 & 0xFFFFE000; - } else if (5 == access_page_size) { /* 1M page */ - virtual_offset = virtual_address & 0x000FFFFF; - physical_page_number = value_mr3 & 0xFFF00000; - } else { - return ERROR_FAIL; - } - - *physical_address = physical_page_number | virtual_offset; - - return ERROR_OK; -} - -static int aice_usb_init_cache(uint32_t coreid) -{ - LOG_DEBUG("aice_usb_init_cache"); - - uint32_t value_cr1; - uint32_t value_cr2; - - aice_read_reg(coreid, CR1, &value_cr1); - aice_read_reg(coreid, CR2, &value_cr2); - - struct cache_info *icache = &core_info[coreid].icache; - - icache->set = value_cr1 & 0x7; - icache->log2_set = icache->set + 6; - icache->set = 64 << icache->set; - icache->way = ((value_cr1 >> 3) & 0x7) + 1; - icache->line_size = (value_cr1 >> 6) & 0x7; - if (icache->line_size != 0) { - icache->log2_line_size = icache->line_size + 2; - icache->line_size = 8 << (icache->line_size - 1); - } else { - icache->log2_line_size = 0; - } - - LOG_DEBUG("\ticache set: %" PRIu32 ", way: %" PRIu32 ", line size: %" PRIu32 ", " - "log2(set): %" PRIu32 ", log2(line_size): %" PRIu32 "", - icache->set, icache->way, icache->line_size, - icache->log2_set, icache->log2_line_size); - - struct cache_info *dcache = &core_info[coreid].dcache; - - dcache->set = value_cr2 & 0x7; - dcache->log2_set = dcache->set + 6; - dcache->set = 64 << dcache->set; - dcache->way = ((value_cr2 >> 3) & 0x7) + 1; - dcache->line_size = (value_cr2 >> 6) & 0x7; - if (dcache->line_size != 0) { - dcache->log2_line_size = dcache->line_size + 2; - dcache->line_size = 8 << (dcache->line_size - 1); - } else { - dcache->log2_line_size = 0; - } - - LOG_DEBUG("\tdcache set: %" PRIu32 ", way: %" PRIu32 ", line size: %" PRIu32 ", " - "log2(set): %" PRIu32 ", log2(line_size): %" PRIu32 "", - dcache->set, dcache->way, dcache->line_size, - dcache->log2_set, dcache->log2_line_size); - - core_info[coreid].cache_init = true; - - return ERROR_OK; -} - -static int aice_usb_dcache_inval_all(uint32_t coreid) -{ - LOG_DEBUG("aice_usb_dcache_inval_all"); - - uint32_t set_index; - uint32_t way_index; - uint32_t cache_index; - uint32_t instructions[4]; - - instructions[0] = MFSR_DTR(R0); - instructions[1] = L1D_IX_INVAL(R0); - instructions[2] = DSB; - instructions[3] = BEQ_MINUS_12; - - struct cache_info *dcache = &core_info[coreid].dcache; - - for (set_index = 0; set_index < dcache->set; set_index++) { - for (way_index = 0; way_index < dcache->way; way_index++) { - cache_index = (way_index << (dcache->log2_set + dcache->log2_line_size)) | - (set_index << dcache->log2_line_size); - - if (ERROR_OK != aice_write_dtr(coreid, cache_index)) - return ERROR_FAIL; - - if (ERROR_OK != aice_execute_dim(coreid, instructions, 4)) - return ERROR_FAIL; - } - } - - return ERROR_OK; -} - -static int aice_usb_dcache_va_inval(uint32_t coreid, uint32_t address) -{ - LOG_DEBUG("aice_usb_dcache_va_inval"); - - uint32_t instructions[4]; - - aice_write_dtr(coreid, address); - - instructions[0] = MFSR_DTR(R0); - instructions[1] = L1D_VA_INVAL(R0); - instructions[2] = DSB; - instructions[3] = BEQ_MINUS_12; - - return aice_execute_dim(coreid, instructions, 4); -} - -static int aice_usb_dcache_wb_all(uint32_t coreid) -{ - LOG_DEBUG("aice_usb_dcache_wb_all"); - - uint32_t set_index; - uint32_t way_index; - uint32_t cache_index; - uint32_t instructions[4]; - - instructions[0] = MFSR_DTR(R0); - instructions[1] = L1D_IX_WB(R0); - instructions[2] = DSB; - instructions[3] = BEQ_MINUS_12; - - struct cache_info *dcache = &core_info[coreid].dcache; - - for (set_index = 0; set_index < dcache->set; set_index++) { - for (way_index = 0; way_index < dcache->way; way_index++) { - cache_index = (way_index << (dcache->log2_set + dcache->log2_line_size)) | - (set_index << dcache->log2_line_size); - - if (ERROR_OK != aice_write_dtr(coreid, cache_index)) - return ERROR_FAIL; - - if (ERROR_OK != aice_execute_dim(coreid, instructions, 4)) - return ERROR_FAIL; - } - } - - return ERROR_OK; -} - -static int aice_usb_dcache_va_wb(uint32_t coreid, uint32_t address) -{ - LOG_DEBUG("aice_usb_dcache_va_wb"); - - uint32_t instructions[4]; - - aice_write_dtr(coreid, address); - - instructions[0] = MFSR_DTR(R0); - instructions[1] = L1D_VA_WB(R0); - instructions[2] = DSB; - instructions[3] = BEQ_MINUS_12; - - return aice_execute_dim(coreid, instructions, 4); -} - -static int aice_usb_icache_inval_all(uint32_t coreid) -{ - LOG_DEBUG("aice_usb_icache_inval_all"); - - uint32_t set_index; - uint32_t way_index; - uint32_t cache_index; - uint32_t instructions[4]; - - instructions[0] = MFSR_DTR(R0); - instructions[1] = L1I_IX_INVAL(R0); - instructions[2] = ISB; - instructions[3] = BEQ_MINUS_12; - - struct cache_info *icache = &core_info[coreid].icache; - - for (set_index = 0; set_index < icache->set; set_index++) { - for (way_index = 0; way_index < icache->way; way_index++) { - cache_index = (way_index << (icache->log2_set + icache->log2_line_size)) | - (set_index << icache->log2_line_size); - - if (ERROR_OK != aice_write_dtr(coreid, cache_index)) - return ERROR_FAIL; - - if (ERROR_OK != aice_execute_dim(coreid, instructions, 4)) - return ERROR_FAIL; - } - } - - return ERROR_OK; -} - -static int aice_usb_icache_va_inval(uint32_t coreid, uint32_t address) -{ - LOG_DEBUG("aice_usb_icache_va_inval"); - - uint32_t instructions[4]; - - aice_write_dtr(coreid, address); - - instructions[0] = MFSR_DTR(R0); - instructions[1] = L1I_VA_INVAL(R0); - instructions[2] = ISB; - instructions[3] = BEQ_MINUS_12; - - return aice_execute_dim(coreid, instructions, 4); -} - -static int aice_usb_cache_ctl(uint32_t coreid, uint32_t subtype, uint32_t address) -{ - LOG_DEBUG("aice_usb_cache_ctl"); - - int result; - - if (core_info[coreid].cache_init == false) - aice_usb_init_cache(coreid); - - switch (subtype) { - case AICE_CACHE_CTL_L1D_INVALALL: - result = aice_usb_dcache_inval_all(coreid); - break; - case AICE_CACHE_CTL_L1D_VA_INVAL: - result = aice_usb_dcache_va_inval(coreid, address); - break; - case AICE_CACHE_CTL_L1D_WBALL: - result = aice_usb_dcache_wb_all(coreid); - break; - case AICE_CACHE_CTL_L1D_VA_WB: - result = aice_usb_dcache_va_wb(coreid, address); - break; - case AICE_CACHE_CTL_L1I_INVALALL: - result = aice_usb_icache_inval_all(coreid); - break; - case AICE_CACHE_CTL_L1I_VA_INVAL: - result = aice_usb_icache_va_inval(coreid, address); - break; - default: - result = ERROR_FAIL; - break; - } - - return result; -} - -static int aice_usb_set_retry_times(uint32_t a_retry_times) -{ - aice_max_retry_times = a_retry_times; - return ERROR_OK; -} - -static int aice_usb_program_edm(uint32_t coreid, char *command_sequence) -{ - char *command_str; - char *reg_name_0; - char *reg_name_1; - uint32_t data_value; - int i; - - /* init strtok() */ - command_str = strtok(command_sequence, ";"); - if (command_str == NULL) - return ERROR_OK; - - do { - i = 0; - /* process one command */ - while (command_str[i] == ' ' || - command_str[i] == '\n' || - command_str[i] == '\r' || - command_str[i] == '\t') - i++; - - /* skip ' ', '\r', '\n', '\t' */ - command_str = command_str + i; - - if (strncmp(command_str, "write_misc", 10) == 0) { - reg_name_0 = strstr(command_str, "gen_port0"); - reg_name_1 = strstr(command_str, "gen_port1"); - - if (reg_name_0 != NULL) { - data_value = strtoul(reg_name_0 + 9, NULL, 0); - - if (aice_write_misc(coreid, - NDS_EDM_MISC_GEN_PORT0, data_value) != ERROR_OK) - return ERROR_FAIL; - - } else if (reg_name_1 != NULL) { - data_value = strtoul(reg_name_1 + 9, NULL, 0); - - if (aice_write_misc(coreid, - NDS_EDM_MISC_GEN_PORT1, data_value) != ERROR_OK) - return ERROR_FAIL; - } else { - LOG_ERROR("program EDM, unsupported misc register: %s", command_str); - } - } else { - LOG_ERROR("program EDM, unsupported command: %s", command_str); - } - - /* update command_str */ - command_str = strtok(NULL, ";"); - - } while (command_str != NULL); - - return ERROR_OK; -} - -static int aice_usb_set_command_mode(enum aice_command_mode command_mode) -{ - int retval = ERROR_OK; - - /* flush usb_packets_buffer as users change mode */ - retval = aice_usb_packet_flush(); - - if (AICE_COMMAND_MODE_BATCH == command_mode) { - /* reset batch buffer */ - aice_command_mode = AICE_COMMAND_MODE_NORMAL; - retval = aice_write_ctrl(AICE_WRITE_CTRL_BATCH_CMD_BUF0_CTRL, 0x40000); - } - - aice_command_mode = command_mode; - - return retval; -} - -static int aice_usb_execute(uint32_t coreid, uint32_t *instructions, - uint32_t instruction_num) -{ - uint32_t i, j; - uint8_t current_instruction_num; - uint32_t dim_instructions[4] = {NOP, NOP, NOP, BEQ_MINUS_12}; - - /* To execute 4 instructions as a special case */ - if (instruction_num == 4) - return aice_execute_dim(coreid, instructions, 4); - - for (i = 0 ; i < instruction_num ; i += 3) { - if (instruction_num - i < 3) { - current_instruction_num = instruction_num - i; - for (j = current_instruction_num ; j < 3 ; j++) - dim_instructions[j] = NOP; - } else { - current_instruction_num = 3; - } - - memcpy(dim_instructions, instructions + i, - current_instruction_num * sizeof(uint32_t)); - - /** fill DIM */ - if (aice_write_dim(coreid, - dim_instructions, - 4) != ERROR_OK) - return ERROR_FAIL; - - /** clear DBGER.DPED */ - if (aice_write_misc(coreid, - NDS_EDM_MISC_DBGER, NDS_DBGER_DPED) != ERROR_OK) - return ERROR_FAIL; - - /** execute DIM */ - if (aice_do_execute(coreid) != ERROR_OK) - return ERROR_FAIL; - - /** check DBGER.DPED */ - if (aice_check_dbger(coreid, NDS_DBGER_DPED) != ERROR_OK) { - - LOG_ERROR("<-- TARGET ERROR! Debug operations do not finish properly:" - "0x%08" PRIx32 " 0x%08" PRIx32 " 0x%08" PRIx32 " 0x%08" PRIx32 ". -->", - dim_instructions[0], - dim_instructions[1], - dim_instructions[2], - dim_instructions[3]); - return ERROR_FAIL; - } - } - - return ERROR_OK; -} - -static int aice_usb_set_custom_srst_script(const char *script) -{ - custom_srst_script = strdup(script); - - return ERROR_OK; -} - -static int aice_usb_set_custom_trst_script(const char *script) -{ - custom_trst_script = strdup(script); - - return ERROR_OK; -} - -static int aice_usb_set_custom_restart_script(const char *script) -{ - custom_restart_script = strdup(script); - - return ERROR_OK; -} - -static int aice_usb_set_count_to_check_dbger(uint32_t count_to_check) -{ - aice_count_to_check_dbger = count_to_check; - - return ERROR_OK; -} - -static int aice_usb_set_data_endian(uint32_t coreid, - enum aice_target_endian target_data_endian) -{ - data_endian = target_data_endian; - - return ERROR_OK; -} - -static int fill_profiling_batch_commands(uint32_t coreid, uint32_t reg_no) -{ - uint32_t dim_instructions[4]; - - aice_usb_set_command_mode(AICE_COMMAND_MODE_BATCH); - - /* halt */ - if (aice_write_misc(coreid, NDS_EDM_MISC_EDM_CMDR, 0) != ERROR_OK) - return ERROR_FAIL; - - /* backup $r0 */ - dim_instructions[0] = MTSR_DTR(0); - dim_instructions[1] = DSB; - dim_instructions[2] = NOP; - dim_instructions[3] = BEQ_MINUS_12; - if (aice_write_dim(coreid, dim_instructions, 4) != ERROR_OK) - return ERROR_FAIL; - aice_read_dtr_to_buffer(coreid, AICE_BATCH_DATA_BUFFER_0); - - /* get samples */ - if (NDS32_REG_TYPE_GPR == nds32_reg_type(reg_no)) { - /* general registers */ - dim_instructions[0] = MTSR_DTR(reg_no); - dim_instructions[1] = DSB; - dim_instructions[2] = NOP; - dim_instructions[3] = BEQ_MINUS_12; - } else if (NDS32_REG_TYPE_SPR == nds32_reg_type(reg_no)) { - /* user special registers */ - dim_instructions[0] = MFUSR_G0(0, nds32_reg_sr_index(reg_no)); - dim_instructions[1] = MTSR_DTR(0); - dim_instructions[2] = DSB; - dim_instructions[3] = BEQ_MINUS_12; - } else { /* system registers */ - dim_instructions[0] = MFSR(0, nds32_reg_sr_index(reg_no)); - dim_instructions[1] = MTSR_DTR(0); - dim_instructions[2] = DSB; - dim_instructions[3] = BEQ_MINUS_12; - } - if (aice_write_dim(coreid, dim_instructions, 4) != ERROR_OK) - return ERROR_FAIL; - aice_read_dtr_to_buffer(coreid, AICE_BATCH_DATA_BUFFER_1); - - /* restore $r0 */ - aice_write_dtr_from_buffer(coreid, AICE_BATCH_DATA_BUFFER_0); - dim_instructions[0] = MFSR_DTR(0); - dim_instructions[1] = DSB; - dim_instructions[2] = NOP; - dim_instructions[3] = IRET; /* free run */ - if (aice_write_dim(coreid, dim_instructions, 4) != ERROR_OK) - return ERROR_FAIL; - - aice_command_mode = AICE_COMMAND_MODE_NORMAL; - - /* use BATCH_BUFFER_WRITE to fill command-batch-buffer */ - if (aice_batch_buffer_write(AICE_BATCH_COMMAND_BUFFER_0, - usb_out_packets_buffer, - (usb_out_packets_buffer_length + 3) / 4) != ERROR_OK) - return ERROR_FAIL; - - usb_out_packets_buffer_length = 0; - usb_in_packets_buffer_length = 0; - - return ERROR_OK; -} - -static int aice_usb_profiling(uint32_t coreid, uint32_t interval, uint32_t iteration, - uint32_t reg_no, uint32_t *samples, uint32_t *num_samples) -{ - uint32_t iteration_count; - uint32_t this_iteration; - int retval = ERROR_OK; - const uint32_t MAX_ITERATION = 250; - - *num_samples = 0; - - /* init DIM size */ - if (aice_write_ctrl(AICE_WRITE_CTRL_BATCH_DIM_SIZE, 4) != ERROR_OK) - return ERROR_FAIL; - - /* Use AICE_BATCH_DATA_BUFFER_0 to read/write $DTR. - * Set it to circular buffer */ - if (aice_write_ctrl(AICE_WRITE_CTRL_BATCH_DATA_BUF0_CTRL, 0xC0000) != ERROR_OK) - return ERROR_FAIL; - - fill_profiling_batch_commands(coreid, reg_no); - - iteration_count = 0; - while (iteration_count < iteration) { - if (iteration - iteration_count < MAX_ITERATION) - this_iteration = iteration - iteration_count; - else - this_iteration = MAX_ITERATION; - - /* set number of iterations */ - uint32_t val_iteration; - val_iteration = interval << 16 | this_iteration; - if (aice_write_ctrl(AICE_WRITE_CTRL_BATCH_ITERATION, - val_iteration) != ERROR_OK) { - retval = ERROR_FAIL; - goto end_profiling; - } - - /* init AICE_WRITE_CTRL_BATCH_DATA_BUF1_CTRL to store $PC */ - if (aice_write_ctrl(AICE_WRITE_CTRL_BATCH_DATA_BUF1_CTRL, - 0x40000) != ERROR_OK) { - retval = ERROR_FAIL; - goto end_profiling; - } - - aice_usb_run(coreid); - - /* enable BATCH command */ - if (aice_write_ctrl(AICE_WRITE_CTRL_BATCH_CTRL, - 0x80000000) != ERROR_OK) { - aice_usb_halt(coreid); - retval = ERROR_FAIL; - goto end_profiling; - } - - /* wait a while (AICE bug, workaround) */ - alive_sleep(this_iteration); - - /* check status */ - uint32_t i; - uint32_t batch_status; - - i = 0; - while (1) { - aice_read_ctrl(AICE_READ_CTRL_BATCH_STATUS, &batch_status); - - if (batch_status & 0x1) { - break; - } else if (batch_status & 0xE) { - aice_usb_halt(coreid); - retval = ERROR_FAIL; - goto end_profiling; - } - - if ((i % 30) == 0) - keep_alive(); - - i++; - } - - aice_usb_halt(coreid); - - /* get samples from batch data buffer */ - if (aice_batch_buffer_read(AICE_BATCH_DATA_BUFFER_1, - samples + iteration_count, this_iteration) != ERROR_OK) { - retval = ERROR_FAIL; - goto end_profiling; - } - - iteration_count += this_iteration; - } - -end_profiling: - *num_samples = iteration_count; - - return retval; -} - -/** */ -struct aice_port_api_s aice_usb_api = { - /** */ - .open = aice_open_device, - /** */ - .close = aice_usb_close, - /** */ - .idcode = aice_usb_idcode, - /** */ - .state = aice_usb_state, - /** */ - .reset = aice_usb_reset, - /** */ - .assert_srst = aice_usb_assert_srst, - /** */ - .run = aice_usb_run, - /** */ - .halt = aice_usb_halt, - /** */ - .step = aice_usb_step, - /** */ - .read_reg = aice_usb_read_reg, - /** */ - .write_reg = aice_usb_write_reg, - /** */ - .read_reg_64 = aice_usb_read_reg_64, - /** */ - .write_reg_64 = aice_usb_write_reg_64, - /** */ - .read_mem_unit = aice_usb_read_memory_unit, - /** */ - .write_mem_unit = aice_usb_write_memory_unit, - /** */ - .read_mem_bulk = aice_usb_bulk_read_mem, - /** */ - .write_mem_bulk = aice_usb_bulk_write_mem, - /** */ - .read_debug_reg = aice_usb_read_debug_reg, - /** */ - .write_debug_reg = aice_usb_write_debug_reg, - /** */ - .set_jtag_clock = aice_usb_set_jtag_clock, - /** */ - .memory_access = aice_usb_memory_access, - /** */ - .memory_mode = aice_usb_memory_mode, - /** */ - .read_tlb = aice_usb_read_tlb, - /** */ - .cache_ctl = aice_usb_cache_ctl, - /** */ - .set_retry_times = aice_usb_set_retry_times, - /** */ - .program_edm = aice_usb_program_edm, - /** */ - .set_command_mode = aice_usb_set_command_mode, - /** */ - .execute = aice_usb_execute, - /** */ - .set_custom_srst_script = aice_usb_set_custom_srst_script, - /** */ - .set_custom_trst_script = aice_usb_set_custom_trst_script, - /** */ - .set_custom_restart_script = aice_usb_set_custom_restart_script, - /** */ - .set_count_to_check_dbger = aice_usb_set_count_to_check_dbger, - /** */ - .set_data_endian = aice_usb_set_data_endian, - /** */ - .profiling = aice_usb_profiling, -}; diff --git a/src/jtag/aice/aice_usb.h b/src/jtag/aice/aice_usb.h deleted file mode 100644 index 2911ae56b..000000000 --- a/src/jtag/aice/aice_usb.h +++ /dev/null @@ -1,132 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2013 by Andes Technology * - * Hsiangkai Wang * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 OPENOCD_JTAG_AICE_AICE_USB_H -#define OPENOCD_JTAG_AICE_AICE_USB_H - -#include "aice_port.h" - -/* AICE USB timeout value */ -#define AICE_USB_TIMEOUT 5000 - -/* AICE USB buffer size */ -#define AICE_IN_BUFFER_SIZE 2048 -#define AICE_OUT_BUFFER_SIZE 2048 -#define AICE_IN_PACKETS_BUFFER_SIZE 2048 -#define AICE_OUT_PACKETS_BUFFER_SIZE 2048 -#define AICE_IN_BATCH_COMMAND_SIZE 512 -#define AICE_OUT_BATCH_COMMAND_SIZE 512 -#define AICE_IN_PACK_COMMAND_SIZE 2048 -#define AICE_OUT_PACK_COMMAND_SIZE 2048 - -/* Constants for AICE command READ_CTRL */ -#define AICE_READ_CTRL_GET_ICE_STATE 0x00 -#define AICE_READ_CTRL_GET_HARDWARE_VERSION 0x01 -#define AICE_READ_CTRL_GET_FPGA_VERSION 0x02 -#define AICE_READ_CTRL_GET_FIRMWARE_VERSION 0x03 -#define AICE_READ_CTRL_GET_JTAG_PIN_STATUS 0x04 -#define AICE_READ_CTRL_BATCH_BUF_INFO 0x22 -#define AICE_READ_CTRL_BATCH_STATUS 0x23 -#define AICE_READ_CTRL_BATCH_BUF0_STATE 0x31 -#define AICE_READ_CTRL_BATCH_BUF4_STATE 0x39 -#define AICE_READ_CTRL_BATCH_BUF5_STATE 0x3b - -/* Constants for AICE command WRITE_CTRL */ -#define AICE_WRITE_CTRL_TCK_CONTROL 0x00 -#define AICE_WRITE_CTRL_JTAG_PIN_CONTROL 0x01 -#define AICE_WRITE_CTRL_CLEAR_TIMEOUT_STATUS 0x02 -#define AICE_WRITE_CTRL_RESERVED 0x03 -#define AICE_WRITE_CTRL_JTAG_PIN_STATUS 0x04 -#define AICE_WRITE_CTRL_CUSTOM_DELAY 0x0d -#define AICE_WRITE_CTRL_BATCH_CTRL 0x20 -#define AICE_WRITE_CTRL_BATCH_ITERATION 0x21 -#define AICE_WRITE_CTRL_BATCH_DIM_SIZE 0x22 -#define AICE_WRITE_CTRL_BATCH_CMD_BUF0_CTRL 0x30 -#define AICE_WRITE_CTRL_BATCH_DATA_BUF0_CTRL 0x38 -#define AICE_WRITE_CTRL_BATCH_DATA_BUF1_CTRL 0x3a - -#define AICE_BATCH_COMMAND_BUFFER_0 0x0 -#define AICE_BATCH_COMMAND_BUFFER_1 0x1 -#define AICE_BATCH_COMMAND_BUFFER_2 0x2 -#define AICE_BATCH_COMMAND_BUFFER_3 0x3 -#define AICE_BATCH_DATA_BUFFER_0 0x4 -#define AICE_BATCH_DATA_BUFFER_1 0x5 -#define AICE_BATCH_DATA_BUFFER_2 0x6 -#define AICE_BATCH_DATA_BUFFER_3 0x7 - -/* Constants for AICE command WRITE_CTRL:TCK_CONTROL */ -#define AICE_TCK_CONTROL_TCK3048 0x08 - -/* Constants for AICE command WRITE_CTRL:JTAG_PIN_CONTROL */ -#define AICE_JTAG_PIN_CONTROL_SRST 0x01 -#define AICE_JTAG_PIN_CONTROL_TRST 0x02 -#define AICE_JTAG_PIN_CONTROL_STOP 0x04 -#define AICE_JTAG_PIN_CONTROL_RESTART 0x08 - -/* Constants for AICE command WRITE_CTRL:TCK_CONTROL */ -#define AICE_TCK_CONTROL_TCK_SCAN 0x10 - -/* Custom SRST/DBGI/TRST */ -#define AICE_CUSTOM_DELAY_SET_SRST 0x01 -#define AICE_CUSTOM_DELAY_CLEAN_SRST 0x02 -#define AICE_CUSTOM_DELAY_SET_DBGI 0x04 -#define AICE_CUSTOM_DELAY_CLEAN_DBGI 0x08 -#define AICE_CUSTOM_DELAY_SET_TRST 0x10 -#define AICE_CUSTOM_DELAY_CLEAN_TRST 0x20 - -struct aice_usb_handler_s { - unsigned int usb_read_ep; - unsigned int usb_write_ep; - struct jtag_libusb_device_handle *usb_handle; -}; - -struct cache_info { - uint32_t set; - uint32_t way; - uint32_t line_size; - - uint32_t log2_set; - uint32_t log2_line_size; -}; - -struct aice_nds32_info { - uint32_t edm_version; - uint32_t r0_backup; - uint32_t r1_backup; - uint32_t host_dtr_backup; - uint32_t target_dtr_backup; - uint32_t edmsw_backup; - uint32_t edm_ctl_backup; - bool debug_under_dex_on; - bool dex_use_psw_on; - bool host_dtr_valid; - bool target_dtr_valid; - enum nds_memory_access access_channel; - enum nds_memory_select memory_select; - enum aice_target_state_s core_state; - bool cache_init; - struct cache_info icache; - struct cache_info dcache; -}; - -extern struct aice_port_api_s aice_usb_api; - -int aice_read_ctrl(uint32_t address, uint32_t *data); -int aice_write_ctrl(uint32_t address, uint32_t data); - -#endif /* OPENOCD_JTAG_AICE_AICE_USB_H */ diff --git a/src/jtag/commands.c b/src/jtag/commands.c deleted file mode 100644 index ed40755b7..000000000 --- a/src/jtag/commands.c +++ /dev/null @@ -1,253 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * Copyright (C) 2007,2008 Øyvind Harboe * - * oyvind.harboe@zylin.com * - * * - * Copyright (C) 2009 SoftPLC Corporation * - * http://softplc.com * - * dick@softplc.com * - * * - * Copyright (C) 2009 Zachary T Welch * - * zw@superlucidity.net * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include "commands.h" - -struct cmd_queue_page { - struct cmd_queue_page *next; - void *address; - size_t used; -}; - -#define CMD_QUEUE_PAGE_SIZE (1024 * 1024) -static struct cmd_queue_page *cmd_queue_pages; -static struct cmd_queue_page *cmd_queue_pages_tail; - -struct jtag_command *jtag_command_queue; -static struct jtag_command **next_command_pointer = &jtag_command_queue; - -void jtag_queue_command(struct jtag_command *cmd) -{ - /* this command goes on the end, so ensure the queue terminates */ - cmd->next = NULL; - - struct jtag_command **last_cmd = next_command_pointer; - assert(NULL != last_cmd); - assert(NULL == *last_cmd); - *last_cmd = cmd; - - /* store location where the next command pointer will be stored */ - next_command_pointer = &cmd->next; -} - -void *cmd_queue_alloc(size_t size) -{ - struct cmd_queue_page **p_page = &cmd_queue_pages; - int offset; - uint8_t *t; - - /* - * WARNING: - * We align/round the *SIZE* per below - * so that all pointers returned by - * this function are reasonably well - * aligned. - * - * If we did not, then an "odd-length" request would cause the - * *next* allocation to be at an *odd* address, and because - * this function has the same type of api as malloc() - we - * must also return pointers that have the same type of - * alignment. - * - * What I do not/have is a reasonable portable means - * to align by... - * - * The solution here, is based on these suggestions. - * http://gcc.gnu.org/ml/gcc-help/2008-12/msg00041.html - * - */ - union worse_case_align { - int i; - long l; - float f; - void *v; - }; -#define ALIGN_SIZE (sizeof(union worse_case_align)) - - /* The alignment process. */ - size = (size + ALIGN_SIZE - 1) & (~(ALIGN_SIZE - 1)); - /* Done... */ - - if (*p_page) { - p_page = &cmd_queue_pages_tail; - if (CMD_QUEUE_PAGE_SIZE - (*p_page)->used < size) - p_page = &((*p_page)->next); - } - - if (!*p_page) { - *p_page = malloc(sizeof(struct cmd_queue_page)); - (*p_page)->used = 0; - size_t alloc_size = (size < CMD_QUEUE_PAGE_SIZE) ? - CMD_QUEUE_PAGE_SIZE : size; - (*p_page)->address = malloc(alloc_size); - (*p_page)->next = NULL; - cmd_queue_pages_tail = *p_page; - } - - offset = (*p_page)->used; - (*p_page)->used += size; - - t = (*p_page)->address; - return t + offset; -} - -static void cmd_queue_free(void) -{ - struct cmd_queue_page *page = cmd_queue_pages; - - while (page) { - struct cmd_queue_page *last = page; - free(page->address); - page = page->next; - free(last); - } - - cmd_queue_pages = NULL; - cmd_queue_pages_tail = NULL; -} - -void jtag_command_queue_reset(void) -{ - cmd_queue_free(); - - jtag_command_queue = NULL; - next_command_pointer = &jtag_command_queue; -} - -enum scan_type jtag_scan_type(const struct scan_command *cmd) -{ - int i; - int type = 0; - - for (i = 0; i < cmd->num_fields; i++) { - if (cmd->fields[i].in_value) - type |= SCAN_IN; - if (cmd->fields[i].out_value) - type |= SCAN_OUT; - } - - return type; -} - -int jtag_scan_size(const struct scan_command *cmd) -{ - int bit_count = 0; - int i; - - /* count bits in scan command */ - for (i = 0; i < cmd->num_fields; i++) - bit_count += cmd->fields[i].num_bits; - - return bit_count; -} - -int jtag_build_buffer(const struct scan_command *cmd, uint8_t **buffer) -{ - int bit_count = 0; - int i; - - bit_count = jtag_scan_size(cmd); - *buffer = calloc(1, DIV_ROUND_UP(bit_count, 8)); - - bit_count = 0; - - DEBUG_JTAG_IO("%s num_fields: %i", - cmd->ir_scan ? "IRSCAN" : "DRSCAN", - cmd->num_fields); - - for (i = 0; i < cmd->num_fields; i++) { - if (cmd->fields[i].out_value) { -#ifdef _DEBUG_JTAG_IO_ - char *char_buf = buf_to_str(cmd->fields[i].out_value, - (cmd->fields[i].num_bits > DEBUG_JTAG_IOZ) - ? DEBUG_JTAG_IOZ - : cmd->fields[i].num_bits, 16); - - LOG_DEBUG("fields[%i].out_value[%i]: 0x%s", i, - cmd->fields[i].num_bits, char_buf); - free(char_buf); -#endif - buf_set_buf(cmd->fields[i].out_value, 0, *buffer, - bit_count, cmd->fields[i].num_bits); - } else { - DEBUG_JTAG_IO("fields[%i].out_value[%i]: NULL", - i, cmd->fields[i].num_bits); - } - - bit_count += cmd->fields[i].num_bits; - } - - /*DEBUG_JTAG_IO("bit_count totalling: %i", bit_count); */ - - return bit_count; -} - -int jtag_read_buffer(uint8_t *buffer, const struct scan_command *cmd) -{ - int i; - int bit_count = 0; - int retval; - - /* we return ERROR_OK, unless a check fails, or a handler reports a problem */ - retval = ERROR_OK; - - for (i = 0; i < cmd->num_fields; i++) { - /* if neither in_value nor in_handler - * are specified we don't have to examine this field - */ - if (cmd->fields[i].in_value) { - int num_bits = cmd->fields[i].num_bits; - uint8_t *captured = buf_set_buf(buffer, bit_count, - malloc(DIV_ROUND_UP(num_bits, 8)), 0, num_bits); - -#ifdef _DEBUG_JTAG_IO_ - char *char_buf = buf_to_str(captured, - (num_bits > DEBUG_JTAG_IOZ) - ? DEBUG_JTAG_IOZ - : num_bits, 16); - - LOG_DEBUG("fields[%i].in_value[%i]: 0x%s", - i, num_bits, char_buf); - free(char_buf); -#endif - - if (cmd->fields[i].in_value) - buf_cpy(captured, cmd->fields[i].in_value, num_bits); - - free(captured); - } - bit_count += cmd->fields[i].num_bits; - } - - return retval; -} diff --git a/src/jtag/commands.h b/src/jtag/commands.h deleted file mode 100644 index 947c94725..000000000 --- a/src/jtag/commands.h +++ /dev/null @@ -1,176 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * Copyright (C) 2007,2008 Øyvind Harboe * - * oyvind.harboe@zylin.com * - * * - * Copyright (C) 2009 Zachary T Welch * - * zw@superlucidity.net * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifndef OPENOCD_JTAG_COMMANDS_H -#define OPENOCD_JTAG_COMMANDS_H - -/** - * The inferred type of a scan_command_s structure, indicating whether - * the command has the host scan in from the device, the host scan out - * to the device, or both. - */ -enum scan_type { - /** From device to host, */ - SCAN_IN = 1, - /** From host to device, */ - SCAN_OUT = 2, - /** Full-duplex scan. */ - SCAN_IO = 3 -}; - -/** - * The scan_command provide a means of encapsulating a set of scan_field_s - * structures that should be scanned in/out to the device. - */ -struct scan_command { - /** instruction/not data scan */ - bool ir_scan; - /** number of fields in *fields array */ - int num_fields; - /** pointer to an array of data scan fields */ - struct scan_field *fields; - /** state in which JTAG commands should finish */ - tap_state_t end_state; -}; - -struct statemove_command { - /** state in which JTAG commands should finish */ - tap_state_t end_state; -}; - -struct pathmove_command { - /** number of states in *path */ - int num_states; - /** states that have to be passed */ - tap_state_t *path; -}; - -struct runtest_command { - /** number of cycles to spend in Run-Test/Idle state */ - int num_cycles; - /** state in which JTAG commands should finish */ - tap_state_t end_state; -}; - - -struct stableclocks_command { - /** number of clock cycles that should be sent */ - int num_cycles; -}; - - -struct reset_command { - /** Set TRST output: 0 = deassert, 1 = assert, -1 = no change */ - int trst; - /** Set SRST output: 0 = deassert, 1 = assert, -1 = no change */ - int srst; -}; - -struct end_state_command { - /** state in which JTAG commands should finish */ - tap_state_t end_state; -}; - -struct sleep_command { - /** number of microseconds to sleep */ - uint32_t us; -}; - -/** - * Encapsulates a series of bits to be clocked out, affecting state - * and mode of the interface. - * - * In JTAG mode these are clocked out on TMS, using TCK. They may be - * used for link resets, transitioning between JTAG and SWD modes, or - * to implement JTAG state machine transitions (implementing pathmove - * or statemove operations). - * - * In SWD mode these are clocked out on SWDIO, using SWCLK, and are - * used for link resets and transitioning between SWD and JTAG modes. - */ -struct tms_command { - /** How many bits should be clocked out. */ - unsigned num_bits; - /** The bits to clock out; the LSB is bit 0 of bits[0]. */ - const uint8_t *bits; -}; - -/** - * Defines a container type that hold a pointer to a JTAG command - * structure of any defined type. - */ -union jtag_command_container { - struct scan_command *scan; - struct statemove_command *statemove; - struct pathmove_command *pathmove; - struct runtest_command *runtest; - struct stableclocks_command *stableclocks; - struct reset_command *reset; - struct end_state_command *end_state; - struct sleep_command *sleep; - struct tms_command *tms; -}; - -/** - * The type of the @c jtag_command_container contained by a - * @c jtag_command_s structure. - */ -enum jtag_command_type { - JTAG_SCAN = 1, - /* JTAG_TLR_RESET's non-minidriver implementation is a - * vestige from a statemove cmd. The statemove command - * is obsolete and replaced by pathmove. - * - * pathmove does not support reset as one of it's states, - * hence the need for an explicit statemove command. - */ - JTAG_TLR_RESET = 2, - JTAG_RUNTEST = 3, - JTAG_RESET = 4, - JTAG_PATHMOVE = 6, - JTAG_SLEEP = 7, - JTAG_STABLECLOCKS = 8, - JTAG_TMS = 9, -}; - -struct jtag_command { - union jtag_command_container cmd; - enum jtag_command_type type; - struct jtag_command *next; -}; - -/** The current queue of jtag_command_s structures. */ -extern struct jtag_command *jtag_command_queue; - -void *cmd_queue_alloc(size_t size); - -void jtag_queue_command(struct jtag_command *cmd); -void jtag_command_queue_reset(void); - -enum scan_type jtag_scan_type(const struct scan_command *cmd); -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 /* OPENOCD_JTAG_COMMANDS_H */ diff --git a/src/jtag/core.c b/src/jtag/core.c deleted file mode 100644 index 3da69ff3d..000000000 --- a/src/jtag/core.c +++ /dev/null @@ -1,1966 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2009 Zachary T Welch * - * zw@superlucidity.net * - * * - * Copyright (C) 2007,2008,2009 Øyvind Harboe * - * oyvind.harboe@zylin.com * - * * - * Copyright (C) 2009 SoftPLC Corporation * - * http://softplc.com * - * dick@softplc.com * - * * - * Copyright (C) 2005 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "jtag.h" -#include "swd.h" -#include "interface.h" -#include -#include - -#ifdef HAVE_STRINGS_H -#include -#endif - -/* SVF and XSVF are higher level JTAG command sets (for boundary scan) */ -#include "svf/svf.h" -#include "xsvf/xsvf.h" - -/** The number of JTAG queue flushes (for profiling and debugging purposes). */ -static int jtag_flush_queue_count; - -/* Sleep this # of ms after flushing the queue */ -static int jtag_flush_queue_sleep; - -static void jtag_add_scan_check(struct jtag_tap *active, - void (*jtag_add_scan)(struct jtag_tap *active, - int in_num_fields, - const struct scan_field *in_fields, - tap_state_t state), - int in_num_fields, struct scan_field *in_fields, tap_state_t state); - -/** - * The jtag_error variable is set when an error occurs while executing - * the queue. Application code may set this using jtag_set_error(), - * when an error occurs during processing that should be reported during - * jtag_execute_queue(). - * - * The value is set and cleared, but never read by normal application code. - * - * This value is returned (and cleared) by jtag_execute_queue(). - */ -static int jtag_error = ERROR_OK; - -static const char *jtag_event_strings[] = { - [JTAG_TRST_ASSERTED] = "TAP reset", - [JTAG_TAP_EVENT_SETUP] = "TAP setup", - [JTAG_TAP_EVENT_ENABLE] = "TAP enabled", - [JTAG_TAP_EVENT_DISABLE] = "TAP disabled", -}; - -/* - * JTAG adapters must initialize with TRST and SRST de-asserted - * (they're negative logic, so that means *high*). But some - * hardware doesn't necessarily work that way ... so set things - * up so that jtag_init() always forces that state. - */ -static int jtag_trst = -1; -static int jtag_srst = -1; - -/** - * List all TAPs that have been created. - */ -static struct jtag_tap *__jtag_all_taps; - -static enum reset_types jtag_reset_config = RESET_NONE; -tap_state_t cmd_queue_cur_state = TAP_RESET; - -static bool jtag_verify_capture_ir = true; -static int jtag_verify = 1; - -/* how long the OpenOCD should wait before attempting JTAG communication after reset lines - *deasserted (in ms) */ -static int adapter_nsrst_delay; /* default to no nSRST delay */ -static int jtag_ntrst_delay;/* default to no nTRST delay */ -static int adapter_nsrst_assert_width; /* width of assertion */ -static int jtag_ntrst_assert_width; /* width of assertion */ - -/** - * Contains a single callback along with a pointer that will be passed - * when an event occurs. - */ -struct jtag_event_callback { - /** a event callback */ - jtag_event_handler_t callback; - /** the private data to pass to the callback */ - void *priv; - /** the next callback */ - struct jtag_event_callback *next; -}; - -/* callbacks to inform high-level handlers about JTAG state changes */ -static struct jtag_event_callback *jtag_event_callbacks; - -/* speed in kHz*/ -static int speed_khz; -/* speed to fallback to when RCLK is requested but not supported */ -static int rclk_fallback_speed_khz; -static enum {CLOCK_MODE_UNSELECTED, CLOCK_MODE_KHZ, CLOCK_MODE_RCLK} clock_mode; -static int jtag_speed; - -static struct jtag_interface *jtag; - -/* configuration */ -struct jtag_interface *jtag_interface; - -void jtag_set_flush_queue_sleep(int ms) -{ - jtag_flush_queue_sleep = ms; -} - -void jtag_set_error(int error) -{ - if ((error == ERROR_OK) || (jtag_error != ERROR_OK)) - return; - jtag_error = error; -} - -int jtag_error_clear(void) -{ - int temp = jtag_error; - jtag_error = ERROR_OK; - return temp; -} - -/************/ - -static bool jtag_poll = 1; - -bool is_jtag_poll_safe(void) -{ - /* Polling can be disabled explicitly with set_enabled(false). - * It is also implicitly disabled while TRST is active and - * while SRST is gating the JTAG clock. - */ - if (!transport_is_jtag()) - return jtag_poll; - - if (!jtag_poll || jtag_trst != 0) - return false; - return jtag_srst == 0 || (jtag_reset_config & RESET_SRST_NO_GATING); -} - -bool jtag_poll_get_enabled(void) -{ - return jtag_poll; -} - -void jtag_poll_set_enabled(bool value) -{ - jtag_poll = value; -} - -/************/ - -struct jtag_tap *jtag_all_taps(void) -{ - return __jtag_all_taps; -}; - -unsigned jtag_tap_count(void) -{ - struct jtag_tap *t = jtag_all_taps(); - unsigned n = 0; - while (t) { - n++; - t = t->next_tap; - } - return n; -} - -unsigned jtag_tap_count_enabled(void) -{ - struct jtag_tap *t = jtag_all_taps(); - unsigned n = 0; - while (t) { - if (t->enabled) - n++; - t = t->next_tap; - } - return n; -} - -/** Append a new TAP to the chain of all taps. */ -void jtag_tap_add(struct jtag_tap *t) -{ - unsigned jtag_num_taps = 0; - - struct jtag_tap **tap = &__jtag_all_taps; - while (*tap != NULL) { - jtag_num_taps++; - tap = &(*tap)->next_tap; - } - *tap = t; - t->abs_chain_position = jtag_num_taps; -} - -/* returns a pointer to the n-th device in the scan chain */ -struct jtag_tap *jtag_tap_by_position(unsigned n) -{ - struct jtag_tap *t = jtag_all_taps(); - - while (t && n-- > 0) - t = t->next_tap; - - return t; -} - -struct jtag_tap *jtag_tap_by_string(const char *s) -{ - /* try by name first */ - struct jtag_tap *t = jtag_all_taps(); - - while (t) { - if (0 == strcmp(t->dotted_name, s)) - return t; - t = t->next_tap; - } - - /* no tap found by name, so try to parse the name as a number */ - unsigned n; - if (parse_uint(s, &n) != ERROR_OK) - return NULL; - - /* FIXME remove this numeric fallback code late June 2010, along - * with all info in the User's Guide that TAPs have numeric IDs. - * Also update "scan_chain" output to not display the numbers. - */ - t = jtag_tap_by_position(n); - if (t) - LOG_WARNING("Specify TAP '%s' by name, not number %u", - t->dotted_name, n); - - return t; -} - -struct jtag_tap *jtag_tap_next_enabled(struct jtag_tap *p) -{ - p = p ? p->next_tap : jtag_all_taps(); - while (p) { - if (p->enabled) - return p; - p = p->next_tap; - } - return NULL; -} - -const char *jtag_tap_name(const struct jtag_tap *tap) -{ - return (tap == NULL) ? "(unknown)" : tap->dotted_name; -} - - -int jtag_register_event_callback(jtag_event_handler_t callback, void *priv) -{ - struct jtag_event_callback **callbacks_p = &jtag_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 jtag_event_callback)); - (*callbacks_p)->callback = callback; - (*callbacks_p)->priv = priv; - (*callbacks_p)->next = NULL; - - return ERROR_OK; -} - -int jtag_unregister_event_callback(jtag_event_handler_t callback, void *priv) -{ - struct jtag_event_callback **p = &jtag_event_callbacks, *temp; - - if (callback == NULL) - return ERROR_COMMAND_SYNTAX_ERROR; - - while (*p) { - if (((*p)->priv != priv) || ((*p)->callback != callback)) { - p = &(*p)->next; - continue; - } - - temp = *p; - *p = (*p)->next; - free(temp); - } - - return ERROR_OK; -} - -int jtag_call_event_callbacks(enum jtag_event event) -{ - struct jtag_event_callback *callback = jtag_event_callbacks; - - LOG_DEBUG("jtag event: %s", jtag_event_strings[event]); - - while (callback) { - struct jtag_event_callback *next; - - /* callback may remove itself */ - next = callback->next; - callback->callback(event, callback->priv); - callback = next; - } - - return ERROR_OK; -} - -static void jtag_checks(void) -{ - assert(jtag_trst == 0); -} - -static void jtag_prelude(tap_state_t state) -{ - jtag_checks(); - - assert(state != TAP_INVALID); - - cmd_queue_cur_state = state; -} - -void jtag_add_ir_scan_noverify(struct jtag_tap *active, const struct scan_field *in_fields, - tap_state_t state) -{ - jtag_prelude(state); - - int retval = interface_jtag_add_ir_scan(active, in_fields, state); - jtag_set_error(retval); -} - -static void jtag_add_ir_scan_noverify_callback(struct jtag_tap *active, - int dummy, - const struct scan_field *in_fields, - tap_state_t state) -{ - jtag_add_ir_scan_noverify(active, in_fields, state); -} - -/* If fields->in_value is filled out, then the captured IR value will be checked */ -void jtag_add_ir_scan(struct jtag_tap *active, struct scan_field *in_fields, tap_state_t state) -{ - assert(state != TAP_RESET); - - if (jtag_verify && jtag_verify_capture_ir) { - /* 8 x 32 bit id's is enough for all invocations */ - - /* if we are to run a verification of the ir scan, we need to get the input back. - * We may have to allocate space if the caller didn't ask for the input back. - */ - in_fields->check_value = active->expected; - in_fields->check_mask = active->expected_mask; - jtag_add_scan_check(active, jtag_add_ir_scan_noverify_callback, 1, in_fields, - state); - } else - jtag_add_ir_scan_noverify(active, in_fields, state); -} - -void jtag_add_plain_ir_scan(int num_bits, const uint8_t *out_bits, uint8_t *in_bits, - tap_state_t state) -{ - assert(out_bits != NULL); - assert(state != TAP_RESET); - - jtag_prelude(state); - - int retval = interface_jtag_add_plain_ir_scan( - num_bits, out_bits, in_bits, state); - jtag_set_error(retval); -} - -static int jtag_check_value_inner(uint8_t *captured, uint8_t *in_check_value, - uint8_t *in_check_mask, int num_bits); - -static int jtag_check_value_mask_callback(jtag_callback_data_t data0, - jtag_callback_data_t data1, - jtag_callback_data_t data2, - jtag_callback_data_t data3) -{ - return jtag_check_value_inner((uint8_t *)data0, - (uint8_t *)data1, - (uint8_t *)data2, - (int)data3); -} - -static void jtag_add_scan_check(struct jtag_tap *active, void (*jtag_add_scan)( - struct jtag_tap *active, - int in_num_fields, - const struct scan_field *in_fields, - tap_state_t state), - int in_num_fields, struct scan_field *in_fields, tap_state_t state) -{ - jtag_add_scan(active, in_num_fields, in_fields, state); - - for (int i = 0; i < in_num_fields; i++) { - if ((in_fields[i].check_value != NULL) && (in_fields[i].in_value != NULL)) { - /* this is synchronous for a minidriver */ - jtag_add_callback4(jtag_check_value_mask_callback, - (jtag_callback_data_t)in_fields[i].in_value, - (jtag_callback_data_t)in_fields[i].check_value, - (jtag_callback_data_t)in_fields[i].check_mask, - (jtag_callback_data_t)in_fields[i].num_bits); - } - } -} - -void jtag_add_dr_scan_check(struct jtag_tap *active, - int in_num_fields, - struct scan_field *in_fields, - tap_state_t state) -{ - if (jtag_verify) - jtag_add_scan_check(active, jtag_add_dr_scan, in_num_fields, in_fields, state); - else - jtag_add_dr_scan(active, in_num_fields, in_fields, state); -} - - -void jtag_add_dr_scan(struct jtag_tap *active, - int in_num_fields, - const struct scan_field *in_fields, - tap_state_t state) -{ - assert(state != TAP_RESET); - - jtag_prelude(state); - - int retval; - retval = interface_jtag_add_dr_scan(active, in_num_fields, in_fields, state); - jtag_set_error(retval); -} - -void jtag_add_plain_dr_scan(int num_bits, const uint8_t *out_bits, uint8_t *in_bits, - tap_state_t state) -{ - assert(out_bits != NULL); - assert(state != TAP_RESET); - - jtag_prelude(state); - - int retval; - retval = interface_jtag_add_plain_dr_scan(num_bits, out_bits, in_bits, state); - jtag_set_error(retval); -} - -void jtag_add_tlr(void) -{ - jtag_prelude(TAP_RESET); - jtag_set_error(interface_jtag_add_tlr()); - - /* NOTE: order here matches TRST path in jtag_add_reset() */ - jtag_call_event_callbacks(JTAG_TRST_ASSERTED); - jtag_notify_event(JTAG_TRST_ASSERTED); -} - -/** - * If supported by the underlying adapter, this clocks a raw bit sequence - * onto TMS for switching betwen JTAG and SWD modes. - * - * DO NOT use this to bypass the integrity checks and logging provided - * by the jtag_add_pathmove() and jtag_add_statemove() calls. - * - * @param nbits How many bits to clock out. - * @param seq The bit sequence. The LSB is bit 0 of seq[0]. - * @param state The JTAG tap state to record on completion. Use - * TAP_INVALID to represent being in in SWD mode. - * - * @todo Update naming conventions to stop assuming everything is JTAG. - */ -int jtag_add_tms_seq(unsigned nbits, const uint8_t *seq, enum tap_state state) -{ - int retval; - - if (!(jtag->supported & DEBUG_CAP_TMS_SEQ)) - return ERROR_JTAG_NOT_IMPLEMENTED; - - jtag_checks(); - cmd_queue_cur_state = state; - - retval = interface_add_tms_seq(nbits, seq, state); - jtag_set_error(retval); - return retval; -} - -void jtag_add_pathmove(int num_states, const tap_state_t *path) -{ - tap_state_t cur_state = cmd_queue_cur_state; - - /* the last state has to be a stable state */ - if (!tap_is_state_stable(path[num_states - 1])) { - LOG_ERROR("BUG: TAP path doesn't finish in a stable state"); - jtag_set_error(ERROR_JTAG_NOT_STABLE_STATE); - return; - } - - for (int i = 0; i < num_states; i++) { - if (path[i] == TAP_RESET) { - LOG_ERROR("BUG: TAP_RESET is not a valid state for pathmove sequences"); - jtag_set_error(ERROR_JTAG_STATE_INVALID); - return; - } - - if (tap_state_transition(cur_state, true) != path[i] && - tap_state_transition(cur_state, false) != path[i]) { - LOG_ERROR("BUG: %s -> %s isn't a valid TAP transition", - tap_state_name(cur_state), tap_state_name(path[i])); - jtag_set_error(ERROR_JTAG_TRANSITION_INVALID); - return; - } - cur_state = path[i]; - } - - jtag_checks(); - - jtag_set_error(interface_jtag_add_pathmove(num_states, path)); - cmd_queue_cur_state = path[num_states - 1]; -} - -int jtag_add_statemove(tap_state_t goal_state) -{ - tap_state_t cur_state = cmd_queue_cur_state; - - if (goal_state != cur_state) { - LOG_DEBUG("cur_state=%s goal_state=%s", - tap_state_name(cur_state), - tap_state_name(goal_state)); - } - - /* If goal is RESET, be paranoid and force that that transition - * (e.g. five TCK cycles, TMS high). Else trust "cur_state". - */ - if (goal_state == TAP_RESET) - jtag_add_tlr(); - else if (goal_state == cur_state) - /* nothing to do */; - - else if (tap_is_state_stable(cur_state) && tap_is_state_stable(goal_state)) { - unsigned tms_bits = tap_get_tms_path(cur_state, goal_state); - unsigned tms_count = tap_get_tms_path_len(cur_state, goal_state); - tap_state_t moves[8]; - assert(tms_count < ARRAY_SIZE(moves)); - - for (unsigned i = 0; i < tms_count; i++, tms_bits >>= 1) { - bool bit = tms_bits & 1; - - cur_state = tap_state_transition(cur_state, bit); - moves[i] = cur_state; - } - - jtag_add_pathmove(tms_count, moves); - } else if (tap_state_transition(cur_state, true) == goal_state - || tap_state_transition(cur_state, false) == goal_state) - jtag_add_pathmove(1, &goal_state); - else - return ERROR_FAIL; - - return ERROR_OK; -} - -void jtag_add_runtest(int num_cycles, tap_state_t state) -{ - jtag_prelude(state); - jtag_set_error(interface_jtag_add_runtest(num_cycles, state)); -} - - -void jtag_add_clocks(int num_cycles) -{ - if (!tap_is_state_stable(cmd_queue_cur_state)) { - LOG_ERROR("jtag_add_clocks() called with TAP in unstable state \"%s\"", - tap_state_name(cmd_queue_cur_state)); - jtag_set_error(ERROR_JTAG_NOT_STABLE_STATE); - return; - } - - if (num_cycles > 0) { - jtag_checks(); - jtag_set_error(interface_jtag_add_clocks(num_cycles)); - } -} - -void swd_add_reset(int req_srst) -{ - if (req_srst) { - if (!(jtag_reset_config & RESET_HAS_SRST)) { - LOG_ERROR("BUG: can't assert SRST"); - jtag_set_error(ERROR_FAIL); - return; - } - req_srst = 1; - } - - /* Maybe change SRST signal state */ - if (jtag_srst != req_srst) { - int retval; - - retval = interface_jtag_add_reset(0, req_srst); - if (retval != ERROR_OK) - jtag_set_error(retval); - else - retval = jtag_execute_queue(); - - if (retval != ERROR_OK) { - LOG_ERROR("TRST/SRST error"); - return; - } - - /* SRST resets everything hooked up to that signal */ - jtag_srst = req_srst; - if (jtag_srst) { - LOG_DEBUG("SRST line asserted"); - if (adapter_nsrst_assert_width) - jtag_add_sleep(adapter_nsrst_assert_width * 1000); - } else { - LOG_DEBUG("SRST line released"); - if (adapter_nsrst_delay) - jtag_add_sleep(adapter_nsrst_delay * 1000); - } - - retval = jtag_execute_queue(); - if (retval != ERROR_OK) { - LOG_ERROR("SRST timings error"); - return; - } - } -} - -void jtag_add_reset(int req_tlr_or_trst, int req_srst) -{ - int trst_with_tlr = 0; - int new_srst = 0; - int new_trst = 0; - - /* Without SRST, we must use target-specific JTAG operations - * on each target; callers should not be requesting SRST when - * that signal doesn't exist. - * - * RESET_SRST_PULLS_TRST is a board or chip level quirk, which - * can kick in even if the JTAG adapter can't drive TRST. - */ - if (req_srst) { - if (!(jtag_reset_config & RESET_HAS_SRST)) { - LOG_ERROR("BUG: can't assert SRST"); - jtag_set_error(ERROR_FAIL); - return; - } - if ((jtag_reset_config & RESET_SRST_PULLS_TRST) != 0 - && !req_tlr_or_trst) { - LOG_ERROR("BUG: can't assert only SRST"); - jtag_set_error(ERROR_FAIL); - return; - } - new_srst = 1; - } - - /* JTAG reset (entry to TAP_RESET state) can always be achieved - * using TCK and TMS; that may go through a TAP_{IR,DR}UPDATE - * state first. TRST accelerates it, and bypasses those states. - * - * RESET_TRST_PULLS_SRST is a board or chip level quirk, which - * can kick in even if the JTAG adapter can't drive SRST. - */ - if (req_tlr_or_trst) { - if (!(jtag_reset_config & RESET_HAS_TRST)) - trst_with_tlr = 1; - else if ((jtag_reset_config & RESET_TRST_PULLS_SRST) != 0 - && !req_srst) - trst_with_tlr = 1; - else - new_trst = 1; - } - - /* Maybe change TRST and/or SRST signal state */ - if (jtag_srst != new_srst || jtag_trst != new_trst) { - int retval; - - retval = interface_jtag_add_reset(new_trst, new_srst); - if (retval != ERROR_OK) - jtag_set_error(retval); - else - retval = jtag_execute_queue(); - - if (retval != ERROR_OK) { - LOG_ERROR("TRST/SRST error"); - return; - } - } - - /* SRST resets everything hooked up to that signal */ - if (jtag_srst != new_srst) { - jtag_srst = new_srst; - if (jtag_srst) { - LOG_DEBUG("SRST line asserted"); - if (adapter_nsrst_assert_width) - jtag_add_sleep(adapter_nsrst_assert_width * 1000); - } else { - LOG_DEBUG("SRST line released"); - if (adapter_nsrst_delay) - jtag_add_sleep(adapter_nsrst_delay * 1000); - } - } - - /* Maybe enter the JTAG TAP_RESET state ... - * - using only TMS, TCK, and the JTAG state machine - * - or else more directly, using TRST - * - * TAP_RESET should be invisible to non-debug parts of the system. - */ - if (trst_with_tlr) { - LOG_DEBUG("JTAG reset with TLR instead of TRST"); - jtag_add_tlr(); - - } else if (jtag_trst != new_trst) { - jtag_trst = new_trst; - if (jtag_trst) { - LOG_DEBUG("TRST line asserted"); - tap_set_state(TAP_RESET); - if (jtag_ntrst_assert_width) - jtag_add_sleep(jtag_ntrst_assert_width * 1000); - } else { - LOG_DEBUG("TRST line released"); - if (jtag_ntrst_delay) - jtag_add_sleep(jtag_ntrst_delay * 1000); - - /* We just asserted nTRST, so we're now in TAP_RESET. - * Inform possible listeners about this, now that - * JTAG instructions and data can be shifted. This - * sequence must match jtag_add_tlr(). - */ - jtag_call_event_callbacks(JTAG_TRST_ASSERTED); - jtag_notify_event(JTAG_TRST_ASSERTED); - } - } -} - -void jtag_add_sleep(uint32_t us) -{ - /** @todo Here, keep_alive() appears to be a layering violation!!! */ - keep_alive(); - jtag_set_error(interface_jtag_add_sleep(us)); -} - -static int jtag_check_value_inner(uint8_t *captured, uint8_t *in_check_value, - uint8_t *in_check_mask, int num_bits) -{ - int retval = ERROR_OK; - int compare_failed; - - if (in_check_mask) - compare_failed = buf_cmp_mask(captured, in_check_value, in_check_mask, num_bits); - else - compare_failed = buf_cmp(captured, in_check_value, num_bits); - - if (compare_failed) { - char *captured_str, *in_check_value_str; - int bits = (num_bits > DEBUG_JTAG_IOZ) ? DEBUG_JTAG_IOZ : num_bits; - - /* NOTE: we've lost diagnostic context here -- 'which tap' */ - - captured_str = buf_to_str(captured, bits, 16); - in_check_value_str = buf_to_str(in_check_value, bits, 16); - - LOG_WARNING("Bad value '%s' captured during DR or IR scan:", - captured_str); - LOG_WARNING(" check_value: 0x%s", in_check_value_str); - - free(captured_str); - free(in_check_value_str); - - if (in_check_mask) { - char *in_check_mask_str; - - in_check_mask_str = buf_to_str(in_check_mask, bits, 16); - LOG_WARNING(" check_mask: 0x%s", in_check_mask_str); - free(in_check_mask_str); - } - - retval = ERROR_JTAG_QUEUE_FAILED; - } - return retval; -} - -void jtag_check_value_mask(struct scan_field *field, uint8_t *value, uint8_t *mask) -{ - assert(field->in_value != NULL); - - if (value == NULL) { - /* no checking to do */ - return; - } - - jtag_execute_queue_noclear(); - - int retval = jtag_check_value_inner(field->in_value, value, mask, field->num_bits); - jtag_set_error(retval); -} - -int default_interface_jtag_execute_queue(void) -{ - if (NULL == jtag) { - LOG_ERROR("No JTAG interface configured yet. " - "Issue 'init' command in startup scripts " - "before communicating with targets."); - return ERROR_FAIL; - } - - 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; -} - -void jtag_execute_queue_noclear(void) -{ - jtag_flush_queue_count++; - jtag_set_error(interface_jtag_execute_queue()); - - if (jtag_flush_queue_sleep > 0) { - /* For debug purposes it can be useful to test performance - * or behavior when delaying after flushing the queue, - * e.g. to simulate long roundtrip times. - */ - usleep(jtag_flush_queue_sleep * 1000); - } -} - -int jtag_get_flush_queue_count(void) -{ - return jtag_flush_queue_count; -} - -int jtag_execute_queue(void) -{ - jtag_execute_queue_noclear(); - return jtag_error_clear(); -} - -static int jtag_reset_callback(enum jtag_event event, void *priv) -{ - struct jtag_tap *tap = priv; - - if (event == JTAG_TRST_ASSERTED) { - tap->enabled = !tap->disabled_after_reset; - - /* current instruction is either BYPASS or IDCODE */ - buf_set_ones(tap->cur_instr, tap->ir_length); - tap->bypass = 1; - } - - return ERROR_OK; -} - -/* sleep at least us microseconds. When we sleep more than 1000ms we - * do an alive sleep, i.e. keep GDB alive. Note that we could starve - * GDB if we slept for <1000ms many times. - */ -void jtag_sleep(uint32_t us) -{ - if (us < 1000) - usleep(us); - else - alive_sleep((us+999)/1000); -} - -#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) - -/* A reserved manufacturer ID is used in END_OF_CHAIN_FLAG, so we - * know that no valid TAP will have it as an IDCODE value. - */ -#define END_OF_CHAIN_FLAG 0xffffffff - -/* a larger IR length than we ever expect to autoprobe */ -#define JTAG_IRLEN_MAX 60 - -static int jtag_examine_chain_execute(uint8_t *idcode_buffer, unsigned num_idcode) -{ - struct scan_field field = { - .num_bits = num_idcode * 32, - .out_value = idcode_buffer, - .in_value = idcode_buffer, - }; - - /* initialize to the end of chain ID value */ - for (unsigned i = 0; i < num_idcode; i++) - buf_set_u32(idcode_buffer, i * 32, 32, END_OF_CHAIN_FLAG); - - jtag_add_plain_dr_scan(field.num_bits, field.out_value, field.in_value, TAP_DRPAUSE); - jtag_add_tlr(); - return jtag_execute_queue(); -} - -static bool jtag_examine_chain_check(uint8_t *idcodes, unsigned count) -{ - uint8_t zero_check = 0x0; - uint8_t one_check = 0xff; - - for (unsigned i = 0; i < count * 4; i++) { - zero_check |= idcodes[i]; - one_check &= idcodes[i]; - } - - /* if there wasn't a single non-zero bit or if all bits were one, - * the scan is not valid. We wrote a mix of both values; either - * - * - There's a hardware issue (almost certainly): - * + all-zeroes can mean a target stuck in JTAG reset - * + all-ones tends to mean no target - * - The scan chain is WAY longer than we can handle, *AND* either - * + there are several hundreds of TAPs in bypass, or - * + at least a few dozen TAPs all have an all-ones IDCODE - */ - if (zero_check == 0x00 || one_check == 0xff) { - LOG_ERROR("JTAG scan chain interrogation failed: all %s", - (zero_check == 0x00) ? "zeroes" : "ones"); - LOG_ERROR("Check JTAG interface, timings, target power, etc."); - return false; - } - return true; -} - -static void jtag_examine_chain_display(enum log_levels level, const char *msg, - const char *name, uint32_t idcode) -{ - log_printf_lf(level, __FILE__, __LINE__, __func__, - "JTAG tap: %s %16.16s: 0x%08x " - "(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)); -} - -static bool jtag_idcode_is_final(uint32_t idcode) -{ - /* - * Some devices, such as AVR8, will output all 1's instead - * of TDI input value at end of chain. Allow those values - * instead of failing. - */ - return idcode == END_OF_CHAIN_FLAG; -} - -/** - * This helper checks that remaining bits in the examined chain data are - * all as expected, but a single JTAG device requires only 64 bits to be - * read back correctly. This can help identify and diagnose problems - * with the JTAG chain earlier, gives more helpful/explicit error messages. - * Returns TRUE iff garbage was found. - */ -static bool jtag_examine_chain_end(uint8_t *idcodes, unsigned count, unsigned max) -{ - bool triggered = false; - for (; count < max - 31; count += 32) { - uint32_t idcode = buf_get_u32(idcodes, count, 32); - - /* do not trigger the warning if the data looks good */ - if (jtag_idcode_is_final(idcode)) - continue; - LOG_WARNING("Unexpected idcode after end of chain: %d 0x%08x", - count, (unsigned int)idcode); - triggered = true; - } - return triggered; -} - -static bool jtag_examine_chain_match_tap(const struct jtag_tap *tap) -{ - - if (tap->expected_ids_cnt == 0 || !tap->hasidcode) - return true; - - /* optionally ignore the JTAG version field - bits 28-31 of IDCODE */ - uint32_t mask = tap->ignore_version ? ~(0xf << 28) : ~0; - uint32_t idcode = tap->idcode & mask; - - /* Loop over the expected identification codes and test for a match */ - for (unsigned ii = 0; ii < tap->expected_ids_cnt; ii++) { - uint32_t expected = tap->expected_ids[ii] & mask; - - if (idcode == expected) - return true; - - /* treat "-expected-id 0" as a "don't-warn" wildcard */ - if (0 == tap->expected_ids[ii]) - return true; - } - - /* If none of the expected ids matched, warn */ - jtag_examine_chain_display(LOG_LVL_WARNING, "UNEXPECTED", - tap->dotted_name, tap->idcode); - for (unsigned ii = 0; ii < tap->expected_ids_cnt; ii++) { - char msg[32]; - - snprintf(msg, sizeof(msg), "expected %u of %u", ii + 1, tap->expected_ids_cnt); - jtag_examine_chain_display(LOG_LVL_ERROR, msg, - tap->dotted_name, tap->expected_ids[ii]); - } - return false; -} - -/* Try to examine chain layout according to IEEE 1149.1 §12 - * This is called a "blind interrogation" of the scan chain. - */ -static int jtag_examine_chain(void) -{ - int retval; - unsigned max_taps = jtag_tap_count(); - - /* Autoprobe up to this many. */ - if (max_taps < JTAG_MAX_AUTO_TAPS) - max_taps = JTAG_MAX_AUTO_TAPS; - - /* Add room for end-of-chain marker. */ - max_taps++; - - uint8_t *idcode_buffer = malloc(max_taps * 4); - if (idcode_buffer == NULL) - return ERROR_JTAG_INIT_FAILED; - - /* DR scan to collect BYPASS or IDCODE register contents. - * Then make sure the scan data has both ones and zeroes. - */ - LOG_DEBUG("DR scan interrogation for IDCODE/BYPASS"); - retval = jtag_examine_chain_execute(idcode_buffer, max_taps); - if (retval != ERROR_OK) - goto out; - if (!jtag_examine_chain_check(idcode_buffer, max_taps)) { - retval = ERROR_JTAG_INIT_FAILED; - goto out; - } - - /* Point at the 1st predefined tap, if any */ - struct jtag_tap *tap = jtag_tap_next_enabled(NULL); - - unsigned bit_count = 0; - unsigned autocount = 0; - for (unsigned i = 0; i < max_taps; i++) { - assert(bit_count < max_taps * 32); - uint32_t idcode = buf_get_u32(idcode_buffer, bit_count, 32); - - /* No predefined TAP? Auto-probe. */ - if (tap == NULL) { - /* Is there another TAP? */ - if (jtag_idcode_is_final(idcode)) - break; - - /* Default everything in this TAP except IR length. - * - * REVISIT create a jtag_alloc(chip, tap) routine, and - * share it with jim_newtap_cmd(). - */ - tap = calloc(1, sizeof *tap); - if (!tap) { - retval = ERROR_FAIL; - goto out; - } - - tap->chip = alloc_printf("auto%u", autocount++); - tap->tapname = strdup("tap"); - tap->dotted_name = alloc_printf("%s.%s", tap->chip, tap->tapname); - - tap->ir_length = 0; /* ... signifying irlen autoprobe */ - tap->ir_capture_mask = 0x03; - tap->ir_capture_value = 0x01; - - tap->enabled = true; - - jtag_tap_init(tap); - } - - if ((idcode & 1) == 0) { - /* Zero for LSB indicates a device in bypass */ - LOG_INFO("TAP %s does not have valid IDCODE (idcode=0x%x)", - tap->dotted_name, idcode); - tap->hasidcode = false; - tap->idcode = 0; - - bit_count += 1; - } else { - /* Friendly devices support IDCODE */ - tap->hasidcode = true; - tap->idcode = idcode; - jtag_examine_chain_display(LOG_LVL_INFO, "tap/device found", tap->dotted_name, idcode); - - bit_count += 32; - } - - /* ensure the TAP ID matches what was expected */ - if (!jtag_examine_chain_match_tap(tap)) - retval = ERROR_JTAG_INIT_SOFT_FAIL; - - tap = jtag_tap_next_enabled(tap); - } - - /* After those IDCODE or BYPASS register values should be - * only the data we fed into the scan chain. - */ - if (jtag_examine_chain_end(idcode_buffer, bit_count, max_taps * 32)) { - LOG_ERROR("double-check your JTAG setup (interface, speed, ...)"); - retval = ERROR_JTAG_INIT_FAILED; - goto out; - } - - /* Return success or, for backwards compatibility if only - * some IDCODE values mismatched, a soft/continuable fault. - */ -out: - free(idcode_buffer); - return retval; -} - -/* - * Validate the date loaded by entry to the Capture-IR state, to help - * find errors related to scan chain configuration (wrong IR lengths) - * or communication. - * - * Entry state can be anything. On non-error exit, all TAPs are in - * bypass mode. On error exits, the scan chain is reset. - */ -static int jtag_validate_ircapture(void) -{ - struct jtag_tap *tap; - int total_ir_length = 0; - uint8_t *ir_test = NULL; - struct scan_field field; - uint64_t val; - int chain_pos = 0; - int retval; - - /* when autoprobing, accomodate huge IR lengths */ - for (tap = NULL, total_ir_length = 0; - (tap = jtag_tap_next_enabled(tap)) != NULL; - total_ir_length += tap->ir_length) { - if (tap->ir_length == 0) - total_ir_length += JTAG_IRLEN_MAX; - } - - /* increase length to add 2 bit sentinel after scan */ - total_ir_length += 2; - - ir_test = malloc(DIV_ROUND_UP(total_ir_length, 8)); - if (ir_test == NULL) - return ERROR_FAIL; - - /* after this scan, all TAPs will capture BYPASS instructions */ - buf_set_ones(ir_test, total_ir_length); - - field.num_bits = total_ir_length; - field.out_value = ir_test; - field.in_value = ir_test; - - jtag_add_plain_ir_scan(field.num_bits, field.out_value, field.in_value, TAP_IDLE); - - LOG_DEBUG("IR capture validation scan"); - retval = jtag_execute_queue(); - if (retval != ERROR_OK) - goto done; - - tap = NULL; - chain_pos = 0; - - for (;; ) { - tap = jtag_tap_next_enabled(tap); - if (tap == NULL) - break; - - /* If we're autoprobing, guess IR lengths. They must be at - * least two bits. Guessing will fail if (a) any TAP does - * not conform to the JTAG spec; or (b) when the upper bits - * captured from some conforming TAP are nonzero. Or if - * (c) an IR length is longer than JTAG_IRLEN_MAX bits, - * an implementation limit, which could someday be raised. - * - * REVISIT optimization: if there's a *single* TAP we can - * lift restrictions (a) and (b) by scanning a recognizable - * pattern before the all-ones BYPASS. Check for where the - * pattern starts in the result, instead of an 0...01 value. - * - * REVISIT alternative approach: escape to some tcl code - * which could provide more knowledge, based on IDCODE; and - * only guess when that has no success. - */ - if (tap->ir_length == 0) { - tap->ir_length = 2; - while ((val = buf_get_u64(ir_test, chain_pos, tap->ir_length + 1)) == 1 - && tap->ir_length < JTAG_IRLEN_MAX) { - tap->ir_length++; - } - LOG_WARNING("AUTO %s - use \"jtag newtap " "%s %s -irlen %d " - "-expected-id 0x%08" PRIx32 "\"", - tap->dotted_name, tap->chip, tap->tapname, tap->ir_length, tap->idcode); - } - - /* Validate the two LSBs, which must be 01 per JTAG spec. - * - * Or ... more bits could be provided by TAP declaration. - * Plus, some taps (notably in i.MX series chips) violate - * this part of the JTAG spec, so their capture mask/value - * attributes might disable this test. - */ - val = buf_get_u64(ir_test, chain_pos, tap->ir_length); - if ((val & tap->ir_capture_mask) != tap->ir_capture_value) { - LOG_ERROR("%s: IR capture error; saw 0x%0*" PRIx64 " not 0x%0*" PRIx32, - jtag_tap_name(tap), - (tap->ir_length + 7) / tap->ir_length, val, - (tap->ir_length + 7) / tap->ir_length, tap->ir_capture_value); - - retval = ERROR_JTAG_INIT_FAILED; - goto done; - } - LOG_DEBUG("%s: IR capture 0x%0*" PRIx64, jtag_tap_name(tap), - (tap->ir_length + 7) / tap->ir_length, val); - chain_pos += tap->ir_length; - } - - /* verify the '11' sentinel we wrote is returned at the end */ - val = buf_get_u64(ir_test, chain_pos, 2); - if (val != 0x3) { - char *cbuf = buf_to_str(ir_test, total_ir_length, 16); - - LOG_ERROR("IR capture error at bit %d, saw 0x%s not 0x...3", - chain_pos, cbuf); - free(cbuf); - retval = ERROR_JTAG_INIT_FAILED; - } - -done: - free(ir_test); - if (retval != ERROR_OK) { - jtag_add_tlr(); - jtag_execute_queue(); - } - return retval; -} - -void jtag_tap_init(struct jtag_tap *tap) -{ - unsigned ir_len_bits; - unsigned ir_len_bytes; - - /* if we're autoprobing, cope with potentially huge ir_length */ - ir_len_bits = tap->ir_length ? : JTAG_IRLEN_MAX; - ir_len_bytes = DIV_ROUND_UP(ir_len_bits, 8); - - tap->expected = calloc(1, ir_len_bytes); - tap->expected_mask = calloc(1, ir_len_bytes); - tap->cur_instr = malloc(ir_len_bytes); - - /** @todo cope better with ir_length bigger than 32 bits */ - if (ir_len_bits > 32) - ir_len_bits = 32; - - buf_set_u32(tap->expected, 0, ir_len_bits, tap->ir_capture_value); - buf_set_u32(tap->expected_mask, 0, ir_len_bits, tap->ir_capture_mask); - - /* TAP will be in bypass mode after jtag_validate_ircapture() */ - tap->bypass = 1; - buf_set_ones(tap->cur_instr, tap->ir_length); - - /* register the reset callback for the TAP */ - jtag_register_event_callback(&jtag_reset_callback, tap); - jtag_tap_add(tap); - - LOG_DEBUG("Created Tap: %s @ abs position %d, " - "irlen %d, capture: 0x%x mask: 0x%x", tap->dotted_name, - tap->abs_chain_position, tap->ir_length, - (unsigned) tap->ir_capture_value, - (unsigned) tap->ir_capture_mask); -} - -void jtag_tap_free(struct jtag_tap *tap) -{ - jtag_unregister_event_callback(&jtag_reset_callback, tap); - - free(tap->expected); - free(tap->expected_mask); - free(tap->expected_ids); - free(tap->cur_instr); - free(tap->chip); - free(tap->tapname); - free(tap->dotted_name); - free(tap); -} - -/** - * Do low-level setup like initializing registers, output signals, - * and clocking. - */ -int adapter_init(struct command_context *cmd_ctx) -{ - if (jtag) - return ERROR_OK; - - if (!jtag_interface) { - /* nothing was previously specified by "interface" command */ - LOG_ERROR("Debug Adapter has to be specified, " - "see \"interface\" command"); - return ERROR_JTAG_INVALID_INTERFACE; - } - - int retval; - retval = jtag_interface->init(); - if (retval != ERROR_OK) - return retval; - jtag = jtag_interface; - - /* LEGACY SUPPORT ... adapter drivers must declare what - * transports they allow. Until they all do so, assume - * the legacy drivers are JTAG-only - */ - if (!transports_are_declared()) { - LOG_ERROR("Adapter driver '%s' did not declare " - "which transports it allows; assuming " - "JTAG-only", jtag->name); - retval = allow_transports(cmd_ctx, jtag_only); - if (retval != ERROR_OK) - return retval; - } - - if (jtag->speed == NULL) { - LOG_INFO("This adapter doesn't support configurable speed"); - return ERROR_OK; - } - - if (CLOCK_MODE_UNSELECTED == clock_mode) { - LOG_ERROR("An adapter speed is not selected in the init script." - " Insert a call to adapter_khz or jtag_rclk to proceed."); - return ERROR_JTAG_INIT_FAILED; - } - - int requested_khz = jtag_get_speed_khz(); - int actual_khz = requested_khz; - int jtag_speed_var = 0; - retval = jtag_get_speed(&jtag_speed_var); - if (retval != ERROR_OK) - return retval; - retval = jtag->speed(jtag_speed_var); - if (retval != ERROR_OK) - return retval; - retval = jtag_get_speed_readable(&actual_khz); - if (ERROR_OK != retval) - LOG_INFO("adapter-specific clock speed value %d", jtag_speed_var); - else if (actual_khz) { - /* Adaptive clocking -- JTAG-specific */ - if ((CLOCK_MODE_RCLK == clock_mode) - || ((CLOCK_MODE_KHZ == clock_mode) && !requested_khz)) { - LOG_INFO("RCLK (adaptive clock speed) not supported - fallback to %d kHz" - , actual_khz); - } else - LOG_INFO("clock speed %d kHz", actual_khz); - } else - LOG_INFO("RCLK (adaptive clock speed)"); - - return ERROR_OK; -} - -int jtag_init_inner(struct command_context *cmd_ctx) -{ - struct jtag_tap *tap; - int retval; - bool issue_setup = true; - - LOG_DEBUG("Init JTAG chain"); - - tap = jtag_tap_next_enabled(NULL); - if (tap == NULL) { - /* Once JTAG itself is properly set up, and the scan chain - * isn't absurdly large, IDCODE autoprobe should work fine. - * - * But ... IRLEN autoprobe can fail even on systems which - * are fully conformant to JTAG. Also, JTAG setup can be - * quite finicky on some systems. - * - * REVISIT: if TAP autoprobe works OK, then in many cases - * we could escape to tcl code and set up targets based on - * the TAP's IDCODE values. - */ - LOG_WARNING("There are no enabled taps. " - "AUTO PROBING MIGHT NOT WORK!!"); - - /* REVISIT default clock will often be too fast ... */ - } - - jtag_add_tlr(); - retval = jtag_execute_queue(); - if (retval != ERROR_OK) - return retval; - - /* Examine DR values first. This discovers problems which will - * prevent communication ... hardware issues like TDO stuck, or - * configuring the wrong number of (enabled) TAPs. - */ - retval = jtag_examine_chain(); - switch (retval) { - case ERROR_OK: - /* complete success */ - break; - default: - /* For backward compatibility reasons, try coping with - * configuration errors involving only ID mismatches. - * We might be able to talk to the devices. - * - * Also the device might be powered down during startup. - * - * After OpenOCD starts, we can try to power on the device - * and run a reset. - */ - LOG_ERROR("Trying to use configured scan chain anyway..."); - issue_setup = false; - break; - } - - /* Now look at IR values. Problems here will prevent real - * communication. They mostly mean that the IR length is - * wrong ... or that the IR capture value is wrong. (The - * latter is uncommon, but easily worked around: provide - * ircapture/irmask values during TAP setup.) - */ - retval = jtag_validate_ircapture(); - if (retval != ERROR_OK) { - /* The target might be powered down. The user - * can power it up and reset it after firing - * up OpenOCD. - */ - issue_setup = false; - } - - if (issue_setup) - jtag_notify_event(JTAG_TAP_EVENT_SETUP); - else - LOG_WARNING("Bypassing JTAG setup events due to errors"); - - - return ERROR_OK; -} - -int adapter_quit(void) -{ - if (!jtag || !jtag->quit) - return ERROR_OK; - - /* close the JTAG interface */ - int result = jtag->quit(); - if (ERROR_OK != result) - LOG_ERROR("failed: %d", result); - - return ERROR_OK; -} - -int swd_init_reset(struct command_context *cmd_ctx) -{ - int retval = adapter_init(cmd_ctx); - if (retval != ERROR_OK) - return retval; - - LOG_DEBUG("Initializing with hard SRST reset"); - - if (jtag_reset_config & RESET_HAS_SRST) - swd_add_reset(1); - swd_add_reset(0); - retval = jtag_execute_queue(); - return retval; -} - -int jtag_init_reset(struct command_context *cmd_ctx) -{ - int retval = adapter_init(cmd_ctx); - if (retval != ERROR_OK) - return retval; - - LOG_DEBUG("Initializing with hard TRST+SRST reset"); - - /* - * This procedure is used by default when OpenOCD triggers a reset. - * It's now done through an overridable Tcl "init_reset" wrapper. - * - * This started out as a more powerful "get JTAG working" reset than - * jtag_init_inner(), applying TRST because some chips won't activate - * JTAG without a TRST cycle (presumed to be async, though some of - * those chips synchronize JTAG activation using TCK). - * - * But some chips only activate JTAG as part of an SRST cycle; SRST - * got mixed in. So it became a hard reset routine, which got used - * in more places, and which coped with JTAG reset being forced as - * part of SRST (srst_pulls_trst). - * - * And even more corner cases started to surface: TRST and/or SRST - * assertion timings matter; some chips need other JTAG operations; - * TRST/SRST sequences can need to be different from these, etc. - * - * Systems should override that wrapper to support system-specific - * requirements that this not-fully-generic code doesn't handle. - * - * REVISIT once Tcl code can read the reset_config modes, this won't - * need to be a C routine at all... - */ - if (jtag_reset_config & RESET_HAS_SRST) { - jtag_add_reset(1, 1); - if ((jtag_reset_config & RESET_SRST_PULLS_TRST) == 0) - jtag_add_reset(0, 1); - } else { - jtag_add_reset(1, 0); /* TAP_RESET, using TMS+TCK or TRST */ - } - - /* some targets enable us to connect with srst asserted */ - if (jtag_reset_config & RESET_CNCT_UNDER_SRST) { - if (jtag_reset_config & RESET_SRST_NO_GATING) - jtag_add_reset(0, 1); - else { - LOG_WARNING("\'srst_nogate\' reset_config option is required"); - jtag_add_reset(0, 0); - } - } else - jtag_add_reset(0, 0); - retval = jtag_execute_queue(); - if (retval != ERROR_OK) - return retval; - - /* Check that we can communication on the JTAG chain + eventually we want to - * be able to perform enumeration only after OpenOCD has started - * telnet and GDB server - * - * That would allow users to more easily perform any magic they need to before - * reset happens. - */ - return jtag_init_inner(cmd_ctx); -} - -int jtag_init(struct command_context *cmd_ctx) -{ - int retval = adapter_init(cmd_ctx); - if (retval != ERROR_OK) - return retval; - - /* guard against oddball hardware: force resets to be inactive */ - jtag_add_reset(0, 0); - - /* some targets enable us to connect with srst asserted */ - if (jtag_reset_config & RESET_CNCT_UNDER_SRST) { - if (jtag_reset_config & RESET_SRST_NO_GATING) - jtag_add_reset(0, 1); - else - LOG_WARNING("\'srst_nogate\' reset_config option is required"); - } - retval = jtag_execute_queue(); - if (retval != ERROR_OK) - return retval; - - if (Jim_Eval_Named(cmd_ctx->interp, "jtag_init", __FILE__, __LINE__) != JIM_OK) - return ERROR_FAIL; - - return ERROR_OK; -} - -unsigned jtag_get_speed_khz(void) -{ - return speed_khz; -} - -static int adapter_khz_to_speed(unsigned khz, int *speed) -{ - LOG_DEBUG("convert khz to interface specific speed value"); - speed_khz = khz; - if (jtag != NULL) { - LOG_DEBUG("have interface set up"); - int speed_div1; - int retval = jtag->khz(jtag_get_speed_khz(), &speed_div1); - if (ERROR_OK != retval) - return retval; - *speed = speed_div1; - } - return ERROR_OK; -} - -static int jtag_rclk_to_speed(unsigned fallback_speed_khz, int *speed) -{ - int retval = adapter_khz_to_speed(0, speed); - if ((ERROR_OK != retval) && fallback_speed_khz) { - LOG_DEBUG("trying fallback speed..."); - retval = adapter_khz_to_speed(fallback_speed_khz, speed); - } - return retval; -} - -static int jtag_set_speed(int speed) -{ - jtag_speed = speed; - /* this command can be called during CONFIG, - * in which case jtag isn't initialized */ - return jtag ? jtag->speed(speed) : ERROR_OK; -} - -int jtag_config_khz(unsigned khz) -{ - LOG_DEBUG("handle jtag khz"); - clock_mode = CLOCK_MODE_KHZ; - int speed = 0; - int retval = adapter_khz_to_speed(khz, &speed); - return (ERROR_OK != retval) ? retval : jtag_set_speed(speed); -} - -int jtag_config_rclk(unsigned fallback_speed_khz) -{ - LOG_DEBUG("handle jtag rclk"); - clock_mode = CLOCK_MODE_RCLK; - rclk_fallback_speed_khz = fallback_speed_khz; - int speed = 0; - int retval = jtag_rclk_to_speed(fallback_speed_khz, &speed); - return (ERROR_OK != retval) ? retval : jtag_set_speed(speed); -} - -int jtag_get_speed(int *speed) -{ - switch (clock_mode) { - case CLOCK_MODE_KHZ: - adapter_khz_to_speed(jtag_get_speed_khz(), speed); - break; - case CLOCK_MODE_RCLK: - jtag_rclk_to_speed(rclk_fallback_speed_khz, speed); - break; - default: - LOG_ERROR("BUG: unknown jtag clock mode"); - return ERROR_FAIL; - } - return ERROR_OK; -} - -int jtag_get_speed_readable(int *khz) -{ - int jtag_speed_var = 0; - int retval = jtag_get_speed(&jtag_speed_var); - if (retval != ERROR_OK) - return retval; - return jtag ? jtag->speed_div(jtag_speed_var, khz) : ERROR_OK; -} - -void jtag_set_verify(bool enable) -{ - jtag_verify = enable; -} - -bool jtag_will_verify() -{ - return jtag_verify; -} - -void jtag_set_verify_capture_ir(bool enable) -{ - jtag_verify_capture_ir = enable; -} - -bool jtag_will_verify_capture_ir() -{ - return jtag_verify_capture_ir; -} - -int jtag_power_dropout(int *dropout) -{ - if (jtag == NULL) { - /* TODO: as the jtag interface is not valid all - * we can do at the moment is exit OpenOCD */ - LOG_ERROR("No Valid JTAG Interface Configured."); - exit(-1); - } - return jtag->power_dropout(dropout); -} - -int jtag_srst_asserted(int *srst_asserted) -{ - return jtag->srst_asserted(srst_asserted); -} - -enum reset_types jtag_get_reset_config(void) -{ - return jtag_reset_config; -} -void jtag_set_reset_config(enum reset_types type) -{ - jtag_reset_config = type; -} - -int jtag_get_trst(void) -{ - return jtag_trst; -} -int jtag_get_srst(void) -{ - return jtag_srst; -} - -void jtag_set_nsrst_delay(unsigned delay) -{ - adapter_nsrst_delay = delay; -} -unsigned jtag_get_nsrst_delay(void) -{ - return adapter_nsrst_delay; -} -void jtag_set_ntrst_delay(unsigned delay) -{ - jtag_ntrst_delay = delay; -} -unsigned jtag_get_ntrst_delay(void) -{ - return jtag_ntrst_delay; -} - - -void jtag_set_nsrst_assert_width(unsigned delay) -{ - adapter_nsrst_assert_width = delay; -} -unsigned jtag_get_nsrst_assert_width(void) -{ - return adapter_nsrst_assert_width; -} -void jtag_set_ntrst_assert_width(unsigned delay) -{ - jtag_ntrst_assert_width = delay; -} -unsigned jtag_get_ntrst_assert_width(void) -{ - return jtag_ntrst_assert_width; -} - -static int jtag_select(struct command_context *ctx) -{ - int retval; - - /* NOTE: interface init must already have been done. - * That works with only C code ... no Tcl glue required. - */ - - retval = jtag_register_commands(ctx); - - if (retval != ERROR_OK) - return retval; - - retval = svf_register_commands(ctx); - - if (retval != ERROR_OK) - return retval; - - return xsvf_register_commands(ctx); -} - -static struct transport jtag_transport = { - .name = "jtag", - .select = jtag_select, - .init = jtag_init, -}; - -static void jtag_constructor(void) __attribute__((constructor)); -static void jtag_constructor(void) -{ - transport_register(&jtag_transport); -} - -/** Returns true if the current debug session - * is using JTAG as its transport. - */ -bool transport_is_jtag(void) -{ - return get_current_transport() == &jtag_transport; -} - -void adapter_assert_reset(void) -{ - if (transport_is_jtag()) { - if (jtag_reset_config & RESET_SRST_PULLS_TRST) - jtag_add_reset(1, 1); - else - jtag_add_reset(0, 1); - } else if (transport_is_swd()) - swd_add_reset(1); - else if (get_current_transport() != NULL) - LOG_ERROR("reset is not supported on %s", - get_current_transport()->name); - else - LOG_ERROR("transport is not selected"); -} - -void adapter_deassert_reset(void) -{ - if (transport_is_jtag()) - jtag_add_reset(0, 0); - else if (transport_is_swd()) - swd_add_reset(0); - else if (get_current_transport() != NULL) - LOG_ERROR("reset is not supported on %s", - get_current_transport()->name); - else - LOG_ERROR("transport is not selected"); -} - -int adapter_config_trace(bool enabled, enum tpio_pin_protocol pin_protocol, - uint32_t port_size, unsigned int *trace_freq) -{ - if (jtag->config_trace) - return jtag->config_trace(enabled, pin_protocol, port_size, - trace_freq); - else if (enabled) { - LOG_ERROR("The selected interface does not support tracing"); - return ERROR_FAIL; - } - - return ERROR_OK; -} - -int adapter_poll_trace(uint8_t *buf, size_t *size) -{ - if (jtag->poll_trace) - return jtag->poll_trace(buf, size); - - return ERROR_FAIL; -} diff --git a/src/jtag/driver.h b/src/jtag/driver.h deleted file mode 100644 index ae00414c4..000000000 --- a/src/jtag/driver.h +++ /dev/null @@ -1,26 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifndef OPENOCD_JTAG_DRIVER_H -#define OPENOCD_JTAG_DRIVER_H - -struct command_context; - -int interface_register_commands(struct command_context *ctx); - -#endif /* OPENOCD_JTAG_DRIVER_H */ diff --git a/src/jtag/drivers/Makefile.am b/src/jtag/drivers/Makefile.am deleted file mode 100644 index 2aaf8fd84..000000000 --- a/src/jtag/drivers/Makefile.am +++ /dev/null @@ -1,173 +0,0 @@ -include $(top_srcdir)/common.mk - -noinst_LTLIBRARIES = libocdjtagdrivers.la -libocdjtagdrivers_la_LIBADD = - -libocdjtagdrivers_la_SOURCES = \ - $(DRIVERFILES) - -libocdjtagdrivers_la_CPPFLAGS = $(AM_CPPFLAGS) $(LIBUSB1_CFLAGS) \ - $(LIBUSB0_CFLAGS) $(HIDAPI_CFLAGS) $(LIBFTDI_CFLAGS) - -ULINK_FIRMWARE = $(srcdir)/OpenULINK - -EXTRA_DIST = $(ULINK_FIRMWARE) \ - usb_blaster/README.CheapClone \ - Makefile.rlink \ - rlink_call.m4 \ - rlink_init.m4 - -DRIVERFILES = -SUBDIRS= - -if JLINK -if INTERNAL_LIBJAYLINK -SUBDIRS += libjaylink - -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) - -noinst_LTLIBRARIES += libjaylink_internal.la -libocdjtagdrivers_la_LIBADD += libjaylink_internal.la -else -DRIVERFILES += jlink.c -endif -endif - -# Standard Driver: common files -DRIVERFILES += driver.c - -if USE_LIBUSB1 -DRIVERFILES += libusb1_common.c -endif - -if USE_LIBUSB0 -DRIVERFILES += usb_common.c -if !USE_LIBUSB1 -DRIVERFILES += libusb0_common.c -endif -endif - -if BITBANG -DRIVERFILES += bitbang.c -endif -if PARPORT -DRIVERFILES += parport.c -endif -if DUMMY -DRIVERFILES += dummy.c -endif -if FT2232_DRIVER -DRIVERFILES += ft2232.c -endif -if FTDI -DRIVERFILES += ftdi.c mpsse.c -endif -if JTAG_VPI -DRIVERFILES += jtag_vpi.c -endif -if USB_BLASTER_DRIVER -SUBDIRS += usb_blaster -libocdjtagdrivers_la_LIBADD += $(top_builddir)/src/jtag/drivers/usb_blaster/libocdusbblaster.la -endif -if AMTJTAGACCEL -DRIVERFILES += amt_jtagaccel.c -endif -if EP93XX -DRIVERFILES += ep93xx.c -endif -if AT91RM9200 -DRIVERFILES += at91rm9200.c -endif -if GW16012 -DRIVERFILES += gw16012.c -endif -if BITQ -DRIVERFILES += bitq.c -endif -if PRESTO_DRIVER -DRIVERFILES += presto.c -endif -if USBPROG -DRIVERFILES += usbprog.c -endif -if RLINK -DRIVERFILES += rlink.c rlink_speed_table.c -endif -if ULINK -DRIVERFILES += ulink.c -ulinkdir = $(pkgdatadir)/OpenULINK -dist_ulink_DATA = $(ULINK_FIRMWARE)/ulink_firmware.hex -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 -endif -if ARMJTAGEW -DRIVERFILES += arm-jtag-ew.c -endif -if BUSPIRATE -DRIVERFILES += buspirate.c -endif -if REMOTE_BITBANG -DRIVERFILES += remote_bitbang.c -endif -if HLADAPTER -DRIVERFILES += stlink_usb.c -DRIVERFILES += ti_icdi_usb.c -endif -if OSBDM -DRIVERFILES += osbdm.c -endif -if OPENDOUS -DRIVERFILES += opendous.c -endif -if SYSFSGPIO -DRIVERFILES += sysfsgpio.c -endif -if BCM2835GPIO -DRIVERFILES += bcm2835gpio.c -endif - -if OPENJTAG -DRIVERFILES += 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 - -MAINTAINERCLEANFILES = $(srcdir)/Makefile.in diff --git a/src/jtag/drivers/Makefile.rlink b/src/jtag/drivers/Makefile.rlink deleted file mode 100644 index 6168332c8..000000000 --- a/src/jtag/drivers/Makefile.rlink +++ /dev/null @@ -1,71 +0,0 @@ -#*************************************************************************** -#* Copyright (C) 2008 Lou Deluxe * -#* lou.openocd012@fixit.nospammail.net * -#* * -#* This program is free software; you can redistribute it and/or modify * -#* it under the terms of the GNU General Public License as published by * -#* the Free Software Foundation; either version 2 of the License, or * -#* (at your option) any later version. * -#* * -#* This program is distributed in the hope that it will be useful, * -#* but WITHOUT ANY WARRANTY; without even the implied warranty of * -#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -#* GNU General Public License for more details. * -#* * -#* You should have received a copy of the GNU General Public License * -#* along with this program. If not, see . * -#*************************************************************************** - -TOP = ../../.. -INTERFACE_NAME = rlink - -PERL = perl -M4 = m4 - -TARGETDIR = ${TOP}/src/target -TOOLSDIR = ${TOP}/tools - -MAKE_SPEED_TABLE = ${TOOLSDIR}/rlink_make_speed_table/rlink_make_speed_table -ST7_DTC_AS = ${TOOLSDIR}/st7_dtc_as/st7_dtc_as - -OPENOCD = ${TOP}/src/openocd -OPENOCD_CONFIG = -s ${TARGETDIR} -OPENOCD_CONFIG += -f interface/rlink.cfg -OPENOCD_CONFIG += -f board/stm32f10x_128k_eval.cfg - -PATCHFILE = /tmp/openocd_${INTERFACE_NAME}.diff.gz - -# relative to ${TOP} -SVNADDFILES = -SVNADDFILES += src/target/interface/rlink.cfg -SVNADDFILES += src/jtag/${INTERFACE_NAME}.c -SVNADDFILES += src/jtag/${INTERFACE_NAME} - -PRESCALERS = 64 11 8 2 - -DTCFILES = -DTCFILES += $(addsuffix _init.dtc, ${PRESCALERS}) -DTCFILES += $(addsuffix _call.dtc, ${PRESCALERS}) - -default: rlink_speed_table.c clean - -%_init.fsm: rlink_init.m4 - ${M4} -P -DSHIFTER_PRESCALER=`echo "$@" | sed -e's/_.*//'` $< > $@ - -%_call.fsm: rlink_call.m4 - ${M4} -P -DSHIFTER_PRESCALER=`echo "$@" | sed -e's/_.*//'` $< > $@ - -%.dtc: %.fsm - ${ST7_DTC_AS} -b -o $@ -i $< > /dev/null - -rlink_speed_table.c: ${DTCFILES} - ${MAKE_SPEED_TABLE} ${PRESCALERS} > $@ || rm $@ - -clean: - -rm *.dtc *.fsm - -distclean: clean - -test: default - (cd ${TOP} && (rm src/jtag/${INTERFACE_NAME}.o; ${MAKE})) - ${OPENOCD} -d0 ${OPENOCD_CONFIG} -c init -c 'poll off' diff --git a/src/jtag/drivers/OpenULINK/Makefile b/src/jtag/drivers/OpenULINK/Makefile deleted file mode 100644 index 9f6acc660..000000000 --- a/src/jtag/drivers/OpenULINK/Makefile +++ /dev/null @@ -1,87 +0,0 @@ -############################################################################ -# Copyright (C) 2011 by Martin Schmoelzer # -# # -# # -# This program is free software; you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation; either version 2 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see . # -############################################################################ - -# Define the name of our tools. Some distributions (e. g. Fedora) prefix -# the SDCC executables, change this accordingly! -PREFIX = - -# Small Device C Compiler: http://sdcc.sourceforge.net/ -CC = $(PREFIX)-sdcc - -# 8051 assembler, part of the SDCC software package. -AS = $(PREFIX)-sdas8051 - -# SDCC produces quite messy Intel HEX files. This tool is be used to re-format -# those files. It is not required for the firmware download functionality in -# the OpenOCD driver, but the resulting file is smaller. -PACKIHX = $(PREFIX)-packihx - -# GNU binutils size. Used to print the size of the IHX file generated by SDCC. -SIZE = size - -# Source and header directories. -SRC_DIR = src -INCLUDE_DIR = include - -CODE_SIZE = 0x1B00 - -# Starting address of __xdata variables. Since the OpenULINK firmware does not -# use any of the isochronous interrupts, we can use the isochronous buffer space -# as XDATA memory. -XRAM_LOC = 0x2000 -XRAM_SIZE = 0x0800 - -CFLAGS = --std-sdcc99 --opt-code-size --model-small -LDFLAGS = --code-loc 0x0000 --code-size $(CODE_SIZE) --xram-loc $(XRAM_LOC) \ - --xram-size $(XRAM_SIZE) --iram-size 256 --model-small - -# list of base object files -OBJECTS = main.rel usb.rel protocol.rel jtag.rel delay.rel USBJmpTb.rel -HEADERS = $(INCLUDE_DIR)/main.h \ - $(INCLUDE_DIR)/usb.h \ - $(INCLUDE_DIR)/protocol.h \ - $(INCLUDE_DIR)/jtag.h \ - $(INCLUDE_DIR)/delay.h \ - $(INCLUDE_DIR)/reg_ezusb.h \ - $(INCLUDE_DIR)/io.h \ - $(INCLUDE_DIR)/msgtypes.h - -# Disable all built-in rules. -.SUFFIXES: - -# Targets which are executed even when identically named file is present. -.PHONY: all, clean - -all: ulink_firmware.ihx - $(SIZE) ulink_firmware.ihx - -ulink_firmware.ihx: $(OBJECTS) - $(CC) -mmcs51 $(LDFLAGS) -o $@ $^ - -# Rebuild every C module (there are only 5 of them) if any header changes. -%.rel: $(SRC_DIR)/%.c $(HEADERS) - $(CC) -c $(CFLAGS) -mmcs51 -I$(INCLUDE_DIR) -o $@ $< - -%.rel: $(SRC_DIR)/%.a51 - $(AS) -lsgo $@ $< - -clean: - rm -f *.asm *.lst *.rel *.rst *.sym *.ihx *.lk *.map *.mem - -hex: ulink_firmware.ihx - $(PACKIHX) ulink_firmware.ihx > ulink_firmware.hex diff --git a/src/jtag/drivers/OpenULINK/README b/src/jtag/drivers/OpenULINK/README deleted file mode 100644 index 445d77038..000000000 --- a/src/jtag/drivers/OpenULINK/README +++ /dev/null @@ -1,34 +0,0 @@ -This is the OpenULINK firmware for the Keil ULINK JTAG adapter. - -The main components of the Keil ULINK adapter are: -- Cypress EZ-USB microcontroller: enhanced 8051 CPU + USB core (1.1 Full-Speed) -- SRAM memory chip -- Level shifters to support different JTAG signal voltage levels -- Pin headers for various JTAG pin assignments - -This firmware can only be run on the ORIGINAL Keil ULINK adapter, not on the -newer ULINK2, ULINK-ME or ULINK-PRO, as these adapters are based on different -hardware. - -To compile the firmware, the SDCC compiler package is required. Most Linux -distributions include SDCC in their official package repositories. The SDCC -source code can be found at http://sdcc.sourceforge.net/ -Simply type "make hex" in the OpenULINK directory to compile the firmware. -"make clean" will remove all generated files except the Intel HEX file required -for downloading the firmware to the ULINK adapter. - -Note that the EZ-USB microcontroller does not have on-chip flash, nor does the -Keil ULINK include on-board memory to store the firmware program of the EZ-USB. -Instead, upon initial connection of the ULINK adapter to the host PC via USB, -the EZ-USB core has enough intelligence to act as a stand-alone USB device, -responding to USB control requests and allowing firmware download via a special -VENDOR-type control request. Then, the EZ-USB microcontroller simulates a -disconnect and re-connect to the USB bus. It may take up to two seconds for the -host to recognize the newly connected device before OpenOCD can proceed to -execute JTAG commands. This delay is only visible when OpenOCD first uses a -blank (unconfigured) ULINK device. - -Once the user disconnects the ULINK adapter, all its memory contents are lost -and the firmware download process has to be executed again. This also maintains -compatibility with the original Keil uVision IDE, which will happily download -its own firmware image to a blank ULINK adapter. diff --git a/src/jtag/drivers/OpenULINK/include/common.h b/src/jtag/drivers/OpenULINK/include/common.h deleted file mode 100644 index 56222fe6c..000000000 --- a/src/jtag/drivers/OpenULINK/include/common.h +++ /dev/null @@ -1,24 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2011 by Martin Schmoelzer * - * * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 __COMMON_H -#define __COMMON_H - -#define DIV_ROUND_UP(m, n) (((m) + (n) - 1) / (n)) - -#endif diff --git a/src/jtag/drivers/OpenULINK/include/delay.h b/src/jtag/drivers/OpenULINK/include/delay.h deleted file mode 100644 index ed454be9b..000000000 --- a/src/jtag/drivers/OpenULINK/include/delay.h +++ /dev/null @@ -1,32 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2011 by Martin Schmoelzer * - * * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 __DELAY_H -#define __DELAY_H - -#include - -#define NOP { __asm nop __endasm; } - -void delay_5us(void); -void delay_1ms(void); - -void delay_us(uint16_t delay); -void delay_ms(uint16_t delay); - -#endif diff --git a/src/jtag/drivers/OpenULINK/include/io.h b/src/jtag/drivers/OpenULINK/include/io.h deleted file mode 100644 index a4a8b8acd..000000000 --- a/src/jtag/drivers/OpenULINK/include/io.h +++ /dev/null @@ -1,122 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2011 by Martin Schmoelzer * - * * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 __IO_H -#define __IO_H - -#include "reg_ezusb.h" - -/*************************************************************************** - * JTAG Signals: * - *************************************************************************** - * TMS ....... Test Mode Select * - * TCK ....... Test Clock * - * TDI ....... Test Data Input (from device point of view, not JTAG * - * adapter point of view!) * - * TDO ....... Test Data Output (from device point of view, not JTAG * - * adapter point of view!) * - * TRST ...... Test Reset: Used to reset the TAP Finite State Machine * - * into the Test Logic Reset state * - * RTCK ...... Return Test Clock * - * OCDSE ..... Enable/Disable OCDS interface (Infineon specific) - shared * - * with /JEN * - * TRAP ...... Trap Condition (Infineon specific) - shared with TSTAT * - * BRKIN ..... Hardware Break-In (Infineon specific) * - * BRKOUT .... Hardware Break-Out (Infineon specific) * - * /JEN ...... JTAG-Enable (STMicroelectronics specific) - shared * - * with OCDSE * - * TSTAT ..... JTAG ISP Status (STMicroelectronics specific) - shared * - * with TRAP * - * RESET ..... Chip Reset (STMicroelectronics specific) * - * /TERR ..... JTAG ISP Error (STMicroelectronics specific) - shared * - * with BRKOUT * - ***************************************************************************/ - -/* PORT A */ -#define PIN_U_OE OUTA0 -/* PA1 Not Connected */ -#define PIN_OE OUTA2 -/* PA3 Not Connected */ -#define PIN_RUN_LED OUTA4 -#define PIN_TDO PINA5 -#define PIN_BRKOUT PINA6 -#define PIN_COM_LED OUTA7 - -/* PORT B */ -#define PIN_TDI OUTB0 -#define PIN_TMS OUTB1 -#define PIN_TCK OUTB2 -#define PIN_TRST OUTB3 -#define PIN_BRKIN OUTB4 -#define PIN_RESET OUTB5 -#define PIN_OCDSE OUTB6 -#define PIN_TRAP PINB7 - -/* JTAG Signals with direction 'OUT' on port B */ -#define MASK_PORTB_DIRECTION_OUT (PIN_TDI | PIN_TMS | PIN_TCK | PIN_TRST | PIN_BRKIN | PIN_RESET | PIN_OCDSE) - -/* PORT C */ -#define PIN_RXD0 PINC0 -#define PIN_TXD0 OUTC1 -#define PIN_RESET_2 PINC2 -/* PC3 Not Connecte */ -/* PC4 Not Connected */ -#define PIN_RTCK PINC5 -#define PIN_WR OUTC6 -/* PC7 Not Connected */ - -/* LED Macros */ -#define SET_RUN_LED() (OUTA &= ~PIN_RUN_LED) -#define CLEAR_RUN_LED() (OUTA |= PIN_RUN_LED) - -#define SET_COM_LED() (OUTA &= ~PIN_COM_LED) -#define CLEAR_COM_LED() (OUTA |= PIN_COM_LED) - -/* JTAG Pin Macros */ -#define GET_TMS() (PINSB & PIN_TMS) -#define GET_TCK() (PINSB & PIN_TCK) - -#define GET_TDO() (PINSA & PIN_TDO) -#define GET_BRKOUT() (PINSA & PIN_BRKOUT) -#define GET_TRAP() (PINSB & PIN_TRAP) -#define GET_RTCK() (PINSC & PIN_RTCK) - -#define SET_TMS_HIGH() (OUTB |= PIN_TMS) -#define SET_TMS_LOW() (OUTB &= ~PIN_TMS) - -#define SET_TCK_HIGH() (OUTB |= PIN_TCK) -#define SET_TCK_LOW() (OUTB &= ~PIN_TCK) - -#define SET_TDI_HIGH() (OUTB |= PIN_TDI) -#define SET_TDI_LOW() (OUTB &= ~PIN_TDI) - -/* TRST and RESET are low-active and inverted by hardware. SET_HIGH de-asserts - * the signal (enabling reset), SET_LOW asserts the signal (disabling reset) */ -#define SET_TRST_HIGH() (OUTB |= PIN_TRST) -#define SET_TRST_LOW() (OUTB &= ~PIN_TRST) - -#define SET_RESET_HIGH() (OUTB |= PIN_RESET) -#define SET_RESET_LOW() (OUTB &= ~PIN_RESET) - -#define SET_OCDSE_HIGH() (OUTB |= PIN_OCDSE) -#define SET_OCDSE_LOW() (OUTB &= ~PIN_OCDSE) - -#define SET_BRKIN_HIGH() (OUTB |= PIN_BRKIN) -#define SET_BRKIN_LOW() (OUTB &= ~PIN_BRKIN) - -#endif diff --git a/src/jtag/drivers/OpenULINK/include/jtag.h b/src/jtag/drivers/OpenULINK/include/jtag.h deleted file mode 100644 index fa492b9ed..000000000 --- a/src/jtag/drivers/OpenULINK/include/jtag.h +++ /dev/null @@ -1,46 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2011 by Martin Schmoelzer * - * * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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_H -#define __JTAG_H - -#include - -#define NOP { __asm nop __endasm; } - -void jtag_scan_in(uint8_t out_offset, uint8_t in_offset); -void jtag_slow_scan_in(uint8_t out_offset, uint8_t in_offset); - -void jtag_scan_out(uint8_t out_offset); -void jtag_slow_scan_out(uint8_t out_offset); - -void jtag_scan_io(uint8_t out_offset, uint8_t in_offset); -void jtag_slow_scan_io(uint8_t out_offset, uint8_t in_offset); - -void jtag_clock_tck(uint16_t count); -void jtag_slow_clock_tck(uint16_t count); -void jtag_clock_tms(uint8_t count, uint8_t sequence); -void jtag_slow_clock_tms(uint8_t count, uint8_t sequence); - -uint16_t jtag_get_signals(void); -void jtag_set_signals(uint8_t low, uint8_t high); - -void jtag_configure_tck_delay(uint8_t scan_in, uint8_t scan_out, - uint8_t scan_io, uint8_t tck, uint8_t tms); - -#endif diff --git a/src/jtag/drivers/OpenULINK/include/main.h b/src/jtag/drivers/OpenULINK/include/main.h deleted file mode 100644 index 9e7dd5a86..000000000 --- a/src/jtag/drivers/OpenULINK/include/main.h +++ /dev/null @@ -1,24 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2011 by Martin Schmoelzer * - * * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 __MAIN_H -#define __MAIN_H - -void io_init(void); - -#endif diff --git a/src/jtag/drivers/OpenULINK/include/msgtypes.h b/src/jtag/drivers/OpenULINK/include/msgtypes.h deleted file mode 100644 index f761a845f..000000000 --- a/src/jtag/drivers/OpenULINK/include/msgtypes.h +++ /dev/null @@ -1,189 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2011 by Martin Schmoelzer * - * * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -/** - * @file - * Definition of the commands supported by the OpenULINK firmware. - * - * Basically, two types of commands can be distinguished: - * - Commands with fixed payload size - * - Commands with variable payload size - * - * SCAN commands (in all variations) carry payloads of variable size, all - * other commands carry payloads of fixed size. - * - * In the case of SCAN commands, the payload size (n) is calculated by - * dividing the scan_size_bits variable by 8, rounding up the result. - * - * Offset zero always contains the command ID. - * - **************************************************************************** - * CMD_SCAN_IN, CMD_SLOW_SCAN_IN: * - * * - * OUT: * - * offset 1: scan_size_bytes * - * offset 2: bits_last_byte * - * offset 3: tms_count_start + tms_count_end * - * offset 4: tms_sequence_start * - * offset 5: tms_sequence_end * - * * - * IN: * - * offset 0..n: TDO data * - **************************************************************************** - * CMD_SCAN_OUT, CMD_SLOW_SCAN_OUT: * - * * - * OUT: * - * offset 1: scan_size_bytes * - * offset 2: bits_last_byte * - * offset 3: tms_count_start + tms_count_end * - * offset 4: tms_sequence_start * - * offset 5: tms_sequence_end * - * offset 6..x: TDI data * - **************************************************************************** - * CMD_SCAN_IO, CMD_SLOW_SCAN_IO: * - * * - * OUT: * - * offset 1: scan_size_bytes * - * offset 2: bits_last_byte * - * offset 3: tms_count_start + tms_count_end * - * offset 4: tms_sequence_start * - * offset 5: tms_sequence_end * - * offset 6..x: TDI data * - * * - * IN: * - * offset 0..n: TDO data * - **************************************************************************** - * CMD_CLOCK_TMS, CMD_SLOW_CLOCK_TMS: * - * * - * OUT: * - * offset 1: tms_count * - * offset 2: tms_sequence * - **************************************************************************** - * CMD_CLOCK_TCK, CMD_SLOW_CLOCK_TCK: * - * * - * OUT: * - * offset 1: low byte of tck_count * - * offset 2: high byte of tck_count * - **************************************************************************** - * CMD_CLOCK_SLEEP_US: * - * * - * OUT: * - * offset 1: low byte of sleep_us * - * offset 2: high byte of sleep_us * - **************************************************************************** - * CMD_CLOCK_SLEEP_MS: * - * * - * OUT: * - * offset 1: low byte of sleep_ms * - * offset 2: high byte of sleep_ms * - **************************************************************************** - * CMD_GET_SIGNALS: * - * * - * IN: * - * offset 0: current state of input signals * - * offset 1: current state of output signals * - **************************************************************************** - * CMD_SET_SIGNALS: * - * * - * OUT: * - * offset 1: signals that should be de-asserted * - * offset 2: signals that should be asserted * - **************************************************************************** - * CMD_CONFIGURE_TCK_FREQ: * - * * - * OUT: * - * offset 1: delay value for scan_in function * - * offset 2: delay value for scan_out function * - * offset 3: delay value for scan_io function * - * offset 4: delay value for clock_tck function * - * offset 5: delay value for clock_tms function * - **************************************************************************** - * CMD_SET_LEDS: * - * * - * OUT: * - * offset 1: LED states: * - * Bit 0: turn COM LED on * - * Bit 1: turn RUN LED on * - * Bit 2: turn COM LED off * - * Bit 3: turn RUN LED off * - * Bits 7..4: Reserved * - **************************************************************************** - * CMD_TEST: * - * * - * OUT: * - * offset 1: unused dummy value * - **************************************************************************** - */ - -#ifndef __MSGTYPES_H -#define __MSGTYPES_H - -/* - * Command IDs: - * - * Bits 7..6: Reserved, should always be zero - * Bits 5..0: Command ID. There are 62 usable IDs. Of this 63 available IDs, - * the IDs 0x00..0x1F are commands with variable payload size, - * the IDs 0x20..0x3F are commands with fixed payload size. - */ - -#define CMD_ID_MASK 0x3F - -/* Commands with variable payload size */ -#define CMD_SCAN_IN 0x00 -#define CMD_SLOW_SCAN_IN 0x01 -#define CMD_SCAN_OUT 0x02 -#define CMD_SLOW_SCAN_OUT 0x03 -#define CMD_SCAN_IO 0x04 -#define CMD_SLOW_SCAN_IO 0x05 - -/* Commands with fixed payload size */ -#define CMD_CLOCK_TMS 0x20 -#define CMD_SLOW_CLOCK_TMS 0x21 -#define CMD_CLOCK_TCK 0x22 -#define CMD_SLOW_CLOCK_TCK 0x23 -#define CMD_SLEEP_US 0x24 -#define CMD_SLEEP_MS 0x25 -#define CMD_GET_SIGNALS 0x26 -#define CMD_SET_SIGNALS 0x27 -#define CMD_CONFIGURE_TCK_FREQ 0x28 -#define CMD_SET_LEDS 0x29 -#define CMD_TEST 0x2A - -/* JTAG signal definition for jtag_get_signals() -- Input signals! */ -#define SIGNAL_TDO (1<<0) -#define SIGNAL_BRKOUT (1<<1) -#define SIGNAL_TRAP (1<<2) -#define SIGNAL_RTCK (1<<3) - -/* JTAG signal definition for jtag_get_signals() -- Output signals! */ -#define SIGNAL_TDI (1<<0) -#define SIGNAL_TMS (1<<1) -#define SIGNAL_TCK (1<<2) -#define SIGNAL_TRST (1<<3) -#define SIGNAL_BRKIN (1<<4) -#define SIGNAL_RESET (1<<5) -#define SIGNAL_OCDSE (1<<6) - -/* LED definitions for CMD_SET_LEDS and CMD_CLEAR_LEDS commands */ -#define COM_LED_ON (1<<0) -#define RUN_LED_ON (1<<1) -#define COM_LED_OFF (1<<2) -#define RUN_LED_OFF (1<<3) - -#endif diff --git a/src/jtag/drivers/OpenULINK/include/protocol.h b/src/jtag/drivers/OpenULINK/include/protocol.h deleted file mode 100644 index 0b6a7d67d..000000000 --- a/src/jtag/drivers/OpenULINK/include/protocol.h +++ /dev/null @@ -1,30 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2011 by Martin Schmoelzer * - * * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 __PROTOCOL_H -#define __PROTOCOL_H - -#include "common.h" -#include - -void execute_set_led_command(void); - -bool execute_command(void); -void command_loop(void); - -#endif diff --git a/src/jtag/drivers/OpenULINK/include/reg_ezusb.h b/src/jtag/drivers/OpenULINK/include/reg_ezusb.h deleted file mode 100644 index 4988367db..000000000 --- a/src/jtag/drivers/OpenULINK/include/reg_ezusb.h +++ /dev/null @@ -1,741 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2011 by Martin Schmoelzer * - * * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 REG_EZUSB_H -#define REG_EZUSB_H - -/** - * @file - * All information in this file was taken from the EZ-USB Technical - * Reference Manual, Cypress Semiconductor, 3901 North First Street - * San Jose, CA 95134 (www.cypress.com). - * - * The EZ-USB Technical Reference Manual is called "EZ-USB TRM" hereafter. - * - * The following bit name definitions differ from those in the EZ-USB TRM: - * - All lowercase characters in the EZ-USB TRM bit names have been converted - * to capitals (e. g. "WakeSRC" converted to "WAKESRC"). - * - CPUCS: 8051RES is named "RES8051". - * - ISOCTL: Two MBZ ("Must Be Zero") bits are named "MBZ0" and "MBZ1". - * - I2CS: STOP and START bits are preceded by "I2C_" - * - INxCS, OUTxCS: the busy and stall bits are named "EPBSY" and "EPSTALL". - * - TOGCTL: EZ-USB TRM bit names are preceded by "TOG_". - */ - -/* Compiler-specific definitions of SBIT, SFR, SFRX, ... macros */ -#include - -/* Bit vectors */ -#define bmBit0 0x01 -#define bmBit1 0x02 -#define bmBit2 0x04 -#define bmBit3 0x08 -#define bmBit4 0x10 -#define bmBit5 0x20 -#define bmBit6 0x40 -#define bmBit7 0x80 - -/************************************************************************** - ************************ Special Function Registers ********************** - ***************************************************************************/ - -/* See EZ-USB TRM, pp. A-9 - A-10 */ - -SFR(SP, 0x81); -SFR(DPL0, 0x82); -SFR(DPH0, 0x83); -SFR(DPL1, 0x84); -SFR(DPL2, 0x85); - -SFR(DPS, 0x86); -#define SEL bmBit0 -/* Bit 1 read-only, always reads '0' */ -/* Bit 2 read-only, always reads '0' */ -/* Bit 3 read-only, always reads '0' */ -/* Bit 4 read-only, always reads '0' */ -/* Bit 5 read-only, always reads '0' */ -/* Bit 6 read-only, always reads '0' */ -/* Bit 7 read-only, always reads '0' */ - -SFR(PCON, 0x87); -#define IDLE bmBit0 -#define STOP bmBit1 -#define GF0 bmBit2 -#define GF1 bmBit3 -/* Bit 4 read-only, always reads '1' */ -/* Bit 5 read-only, always reads '1' */ -/* Bit 6 unused */ -#define SMOD0 bmBit7 - -SFR(TCON, 0x88); -SBIT(IT0, 0x88, 0); -SBIT(IE0, 0x88, 1); -SBIT(IT1, 0x88, 2); -SBIT(IE1, 0x88, 3); -SBIT(TR0, 0x88, 4); -SBIT(TF0, 0x88, 5); -SBIT(TR1, 0x88, 6); -SBIT(TF1, 0x88, 7); - -SFR(TMOD, 0x89); -/* Some bits in this register share the same name in the EZ-USB TRM. Therefore, - * we add a '0'/'1' to distinguish them */ -#define M00 bmBit0 -#define M01 bmBit1 -#define CT0 bmBit2 -#define GATE0 bmBit3 -#define M10 bmBit4 -#define M11 bmBit5 -#define CT1 bmBit6 -#define GATE1 bmBit7 - -SFR(TL0, 0x8A); -SFR(TL1, 0x8B); -SFR(TH0, 0x8C); -SFR(TH1, 0x8D); - -SFR(CKCON, 0x8E); -#define MD0 bmBit0 -#define MD1 bmBit1 -#define MD2 bmBit2 -#define T0M bmBit3 -#define T1M bmBit4 -#define T2M bmBit5 -/* Bit 6 unused */ -/* Bit 7 unused */ - -SFR(SPC_FNC, 0x8D); -#define bmWRS bmBit0 -/* Bit 1 read-only, always reads '0' */ -/* Bit 2 read-only, always reads '0' */ -/* Bit 3 read-only, always reads '0' */ -/* Bit 4 read-only, always reads '0' */ -/* Bit 5 read-only, always reads '0' */ -/* Bit 6 read-only, always reads '0' */ -/* Bit 7 read-only, always reads '0' */ - -SFR(EXIF, 0x91); -/* Bit 0 read-only, always reads '0' */ -/* Bit 1 read-only, always reads '0' */ -/* Bit 2 read-only, always reads '0' */ -/* Bit 3 read-only, always reads '1' */ -#define USBINT bmBit4 -#define I2CINT bmBit5 -#define IE4 bmBit6 -#define IE5 bmBit7 - -/* Definition of the _XPAGE register, according to SDCC Compiler User Guide, - * Version 3.0.1, Chapter 4, p. 61. Also see EZ-USB TRM, p. 2-4. */ -SFR(MPAGE, 0x92); -SFR(_XPAGE, 0x92); - -SFR(SCON0, 0x98); -SBIT(RI_0, 0x98, 0); -SBIT(TI_0, 0x98, 1); -SBIT(RB8_0, 0x98, 2); -SBIT(TB8_0, 0x98, 3); -SBIT(REN_0, 0x98, 4); -SBIT(SM2_0, 0x98, 5); -SBIT(SM1_0, 0x98, 6); -SBIT(SM0_0, 0x98, 7); - -SFR(SBUF0, 0x99); - -SFR(IE, 0xA8); -SBIT(EX0, 0xA8, 0); -SBIT(ET0, 0xA8, 1); -SBIT(EX1, 0xA8, 2); -SBIT(ET1, 0xA8, 3); -SBIT(ES0, 0xA8, 4); -SBIT(ET2, 0xA8, 5); -SBIT(ES1, 0xA8, 6); -SBIT(EA, 0xA8, 7); - -SFR(IP, 0xB8); -SBIT(PX0, 0xB8, 0); -SBIT(PT0, 0xB8, 1); -SBIT(PX1, 0xB8, 2); -SBIT(PT1, 0xB8, 3); -SBIT(PS0, 0xB8, 4); -SBIT(PT2, 0xB8, 5); -SBIT(PS1, 0xB8, 6); -/* Bit 7 read-only, always reads '1' */ - -SFR(SCON1, 0xC0); -SBIT(RI_1, 0xC0, 0); -SBIT(TI_1, 0xC0, 1); -SBIT(RB8_1, 0xC0, 2); -SBIT(TB8_1, 0xC0, 3); -SBIT(REN_1, 0xC0, 4); -SBIT(SM2_1, 0xC0, 5); -SBIT(SM1_1, 0xC0, 6); -SBIT(SM0_1, 0xC0, 7); - -SFR(SBUF1, 0xC1); - -SFR(T2CON, 0xC8); -SBIT(CPRL2, 0xC8, 0); -SBIT(CT2, 0xC8, 1); -SBIT(TR2, 0xC8, 2); -SBIT(EXEN2, 0xC8, 3); -SBIT(TCLK, 0xC8, 4); -SBIT(RCLK, 0xC8, 5); -SBIT(EXF2, 0xC8, 6); -SBIT(TF2, 0xC8, 7); - -SFR(RCAP2L, 0xCA); -SFR(RCAP2H, 0xCB); -SFR(TL2, 0xCC); -SFR(TH2, 0xCD); - -SFR(PSW, 0xD0); -SBIT(P, 0xD0, 0); -SBIT(F1, 0xD0, 1); -SBIT(OV, 0xD0, 2); -SBIT(RS0, 0xD0, 3); -SBIT(RS1, 0xD0, 4); -SBIT(F0, 0xD0, 5); -SBIT(AC, 0xD0, 6); -SBIT(CY, 0xD0, 7); - -SFR(EICON, 0xD8); -/* Bit 0 read-only, always reads '0' */ -/* Bit 1 read-only, always reads '0' */ -/* Bit 2 read-only, always reads '0' */ -SBIT(INT6, 0xD8, 3); -SBIT(RESI, 0xD8, 4); -SBIT(ERESI, 0xD8, 5); -/* Bit 6 read-only, always reads '1' */ -SBIT(SMOD1, 0xD8, 7); - -SFR(ACC, 0xE0); - -SFR(EIE, 0xE8); -SBIT(EUSB, 0xE8, 0); -SBIT(EI2C, 0xE8, 1); -SBIT(EX4, 0xE8, 2); -SBIT(EX5, 0xE8, 3); -SBIT(EWDI, 0xE8, 4); -/* Bit 5 read-only, always reads '1' */ -/* Bit 6 read-only, always reads '1' */ -/* Bit 7 read-only, always reads '1' */ - -SFR(B, 0xF0); - -SFR(EIP, 0xF8); -SBIT(PUSB, 0xF8, 0); -SBIT(PI2C, 0xF8, 1); -SBIT(PX4, 0xF8, 2); -SBIT(PX5, 0xF8, 3); -SBIT(PX6, 0xF8, 4); -/* Bit 5 read-only, always reads '1' */ -/* Bit 6 read-only, always reads '1' */ -/* Bit 7 read-only, always reads '1' */ - -/************************************************************************** - ***************************** XDATA Registers **************************** - ***************************************************************************/ - -/************************ Endpoint 0-7 Data Buffers ************************/ -SFRX(OUT7BUF[64], 0x7B40); -SFRX(IN7BUF[64], 0x7B80); -SFRX(OUT6BUF[64], 0x7BC0); -SFRX(IN6BUF[64], 0x7C00); -SFRX(OUT5BUF[64], 0x7C40); -SFRX(IN5BUF[64], 0x7C80); -SFRX(OUT4BUF[64], 0x7CC0); -SFRX(IN4BUF[64], 0x7D00); -SFRX(OUT3BUF[64], 0x7D40); -SFRX(IN3BUF[64], 0x7D80); -SFRX(OUT2BUF[64], 0x7DC0); -SFRX(IN2BUF[64], 0x7E00); -SFRX(OUT1BUF[64], 0x7E40); -SFRX(IN1BUF[64], 0x7E80); -SFRX(OUT0BUF[64], 0x7EC0); -SFRX(IN0BUF[64], 0x7F00); -/* 0x7F40 - 0x7F5F reserved */ - -/**************************** Isochronous Data *****************************/ -SFRX(OUT8DATA, 0x7F60); -SFRX(OUT9DATA, 0x7F61); -SFRX(OUT10DATA, 0x7F62); -SFRX(OUT11DATA, 0x7F63); -SFRX(OUT12DATA, 0x7F64); -SFRX(OUT13DATA, 0x7F65); -SFRX(OUT14DATA, 0x7F66); -SFRX(OUT15DATA, 0x7F67); - -SFRX(IN8DATA, 0x7F68); -SFRX(IN9DATA, 0x7F69); -SFRX(IN10DATA, 0x7F6A); -SFRX(IN11DATA, 0x7F6B); -SFRX(IN12DATA, 0x7F6C); -SFRX(IN13DATA, 0x7F6D); -SFRX(IN14DATA, 0x7F6E); -SFRX(IN15DATA, 0x7F6F); - -/************************* Isochronous Byte Counts *************************/ -SFRX(OUT8BCH, 0x7F70); -SFRX(OUT8BCL, 0x7F71); -SFRX(OUT9BCH, 0x7F72); -SFRX(OUT9BCL, 0x7F73); -SFRX(OUT10BCH, 0x7F74); -SFRX(OUT10BCL, 0x7F75); -SFRX(OUT11BCH, 0x7F76); -SFRX(OUT11BCL, 0x7F77); -SFRX(OUT12BCH, 0x7F78); -SFRX(OUT12BCL, 0x7F79); -SFRX(OUT13BCH, 0x7F7A); -SFRX(OUT13BCL, 0x7F7B); -SFRX(OUT14BCH, 0x7F7C); -SFRX(OUT14BCL, 0x7F7D); -SFRX(OUT15BCH, 0x7F7E); -SFRX(OUT16BCL, 0x7F7F); - -/****************************** CPU Registers ******************************/ -SFRX(CPUCS, 0x7F92); -#define RES8051 bmBit0 -#define CLK24OE bmBit1 -/* Bit 2 read-only, always reads '0' */ -/* Bit 3 read-only, always reads '0' */ -/* Bits 4...7: Chip Revision */ - -SFRX(PORTACFG, 0x7F93); -#define T0OUT bmBit0 -#define T1OUT bmBit1 -#define OE bmBit2 -#define CS bmBit3 -#define FWR bmBit4 -#define FRD bmBit5 -#define RXD0OUT bmBit6 -#define RXD1OUT bmBit7 - -SFRX(PORTBCFG, 0x7F94); -#define T2 bmBit0 -#define T2EX bmBit1 -#define RXD1 bmBit2 -#define TXD1 bmBit3 -#define INT4 bmBit4 -#define INT5 bmBit5 -#define INT6 bmBit6 -#define T2OUT bmBit7 - -SFRX(PORTCCFG, 0x7F95); -#define RXD0 bmBit0 -#define TXD0 bmBit1 -#define INT0 bmBit2 -#define INT1 bmBit3 -#define T0 bmBit4 -#define T1 bmBit5 -#define WR bmBit6 -#define RD bmBit7 - -/*********************** Input-Output Port Registers ***********************/ -SFRX(OUTA, 0x7F96); -#define OUTA0 bmBit0 -#define OUTA1 bmBit1 -#define OUTA2 bmBit2 -#define OUTA3 bmBit3 -#define OUTA4 bmBit4 -#define OUTA5 bmBit5 -#define OUTA6 bmBit6 -#define OUTA7 bmBit7 - -SFRX(OUTB, 0x7F97); -#define OUTB0 bmBit0 -#define OUTB1 bmBit1 -#define OUTB2 bmBit2 -#define OUTB3 bmBit3 -#define OUTB4 bmBit4 -#define OUTB5 bmBit5 -#define OUTB6 bmBit6 -#define OUTB7 bmBit7 - -SFRX(OUTC, 0x7F98); -#define OUTC0 bmBit0 -#define OUTC1 bmBit1 -#define OUTC2 bmBit2 -#define OUTC3 bmBit3 -#define OUTC4 bmBit4 -#define OUTC5 bmBit5 -#define OUTC6 bmBit6 -#define OUTC7 bmBit7 - -SFRX(PINSA, 0x7F99); -#define PINA0 bmBit0 -#define PINA1 bmBit1 -#define PINA2 bmBit2 -#define PINA3 bmBit3 -#define PINA4 bmBit4 -#define PINA5 bmBit5 -#define PINA6 bmBit6 -#define PINA7 bmBit7 - -SFRX(PINSB, 0x7F9A); -#define PINB0 bmBit0 -#define PINB1 bmBit1 -#define PINB2 bmBit2 -#define PINB3 bmBit3 -#define PINB4 bmBit4 -#define PINB5 bmBit5 -#define PINB6 bmBit6 -#define PINB7 bmBit7 - -SFRX(PINSC, 0x7F9B); -#define PINC0 bmBit0 -#define PINC1 bmBit1 -#define PINC2 bmBit2 -#define PINC3 bmBit3 -#define PINC4 bmBit4 -#define PINC5 bmBit5 -#define PINC6 bmBit6 -#define PINC7 bmBit7 - -SFRX(OEA, 0x7F9C); -#define OEA0 bmBit0 -#define OEA1 bmBit1 -#define OEA2 bmBit2 -#define OEA3 bmBit3 -#define OEA4 bmBit4 -#define OEA5 bmBit5 -#define OEA6 bmBit6 -#define OEA7 bmBit7 - -SFRX(OEB, 0x7F9D); -#define OEB0 bmBit0 -#define OEB1 bmBit1 -#define OEB2 bmBit2 -#define OEB3 bmBit3 -#define OEB4 bmBit4 -#define OEB5 bmBit5 -#define OEB6 bmBit6 -#define OEB7 bmBit7 - -SFRX(OEC, 0x7F9E); -#define OEC0 bmBit0 -#define OEC1 bmBit1 -#define OEC2 bmBit2 -#define OEC3 bmBit3 -#define OEC4 bmBit4 -#define OEC5 bmBit5 -#define OEC6 bmBit6 -#define OEC7 bmBit7 - -/* 0x7F9F reserved */ - -/****************** Isochronous Control/Status Registers *******************/ -SFRX(ISOERR, 0x7FA0); -#define ISO8ERR bmBit0 -#define ISO9ERR bmBit1 -#define ISO10ERR bmBit2 -#define ISO11ERR bmBit3 -#define ISO12ERR bmBit4 -#define ISO13ERR bmBit5 -#define ISO14ERR bmBit6 -#define ISO15ERR bmBit7 - -SFRX(ISOCTL, 0x7FA1); -#define ISODISAB bmBit0 -#define MBZ0 bmBit1 -#define MBZ1 bmBit2 -#define PPSTAT bmBit3 -/* Bit 4 unused */ -/* Bit 5 unused */ -/* Bit 6 unused */ -/* Bit 7 unused */ - -SFRX(ZBCOUT, 0x7FA2); -#define EP8 bmBit0 -#define EP9 bmBit1 -#define EP10 bmBit2 -#define EP11 bmBit3 -#define EP12 bmBit4 -#define EP13 bmBit5 -#define EP14 bmBit6 -#define EP15 bmBit7 - -/* 0x7FA3 reserved */ -/* 0x7FA4 reserved */ - -/****************************** I2C Registers ******************************/ -SFRX(I2CS, 0x7FA5); -#define DONE bmBit0 -#define ACK bmBit1 -#define BERR bmBit2 -#define ID0 bmBit3 -#define ID1 bmBit4 -#define LASTRD bmBit5 -#define I2C_STOP bmBit6 -#define I2C_START bmBit7 - -SFRX(I2DAT, 0x7FA6); -/* 0x7FA7 reserved */ - -/******************************* Interrupts ********************************/ -SFRX(IVEC, 0x7FA8); -/* Bit 0 read-only, always reads '0' */ -/* Bit 1 read-only, always reads '0' */ -#define IV0 bmBit2 -#define IV1 bmBit3 -#define IV2 bmBit4 -#define IV3 bmBit5 -#define IV4 bmBit6 -/* Bit 7 read-only, always reads '0' */ - -SFRX(IN07IRQ, 0x7FA9); -#define IN0IR bmBit0 -#define IN1IR bmBit1 -#define IN2IR bmBit2 -#define IN3IR bmBit3 -#define IN4IR bmBit4 -#define IN5IR bmBit5 -#define IN6IR bmBit6 -#define IN7IR bmBit7 - -SFRX(OUT07IRQ, 0x7FAA); -#define OUT0IR bmBit0 -#define OUT1IR bmBit1 -#define OUT2IR bmBit2 -#define OUT3IR bmBit3 -#define OUT4IR bmBit4 -#define OUT5IR bmBit5 -#define OUT6IR bmBit6 -#define OUT7IR bmBit7 - -SFRX(USBIRQ, 0x7FAB); -#define SUDAVIR bmBit0 -#define SOFIR bmBit1 -#define SUTOKIR bmBit2 -#define SUSPIR bmBit3 -#define URESIR bmBit4 -/* Bit 5 unused */ -/* Bit 6 unused */ -/* Bit 7 unused */ - -SFRX(IN07IEN, 0x7FAC); -#define IN0IEN bmBit0 -#define IN1IEN bmBit1 -#define IN2IEN bmBit2 -#define IN3IEN bmBit3 -#define IN4IEN bmBit4 -#define IN5IEN bmBit5 -#define IN6IEN bmBit6 -#define IN7IEN bmBit7 - -SFRX(OUT07IEN, 0x7FAD); -#define OUT0IEN bmBit0 -#define OUT1IEN bmBit1 -#define OUT2IEN bmBit2 -#define OUT3IEN bmBit3 -#define OUT4IEN bmBit4 -#define OUT5IEN bmBit5 -#define OUT6IEN bmBit6 -#define OUT7IEN bmBit7 - -SFRX(USBIEN, 0x7FAE); -#define SUDAVIE bmBit0 -#define SOFIE bmBit1 -#define SUTOKIE bmBit2 -#define SUSPIE bmBit3 -#define URESIE bmBit4 -/* Bit 5 unused */ -/* Bit 6 unused */ -/* Bit 7 unused */ - -SFRX(USBBAV, 0x7FAF); -#define AVEN bmBit0 -#define BPEN bmBit1 -#define BPPULSE bmBit2 -#define BREAK bmBit3 -/* Bit 4 unused */ -/* Bit 5 unused */ -/* Bit 6 unused */ -/* Bit 7 unused */ - -/* 0x7FB0 reserved */ -/* 0x7FB1 reserved */ -SFRX(BPADDRH, 0x7FB2); -SFRX(BPADDRL, 0x7FB3); - -/****************************** Endpoints 0-7 ******************************/ -SFRX(EP0CS, 0x7FB4); -#define EP0STALL bmBit0 -#define HSNAK bmBit1 -#define IN0BSY bmBit2 -#define OUT0BSY bmBit3 -/* Bit 4 unused */ -/* Bit 5 unused */ -/* Bit 6 unused */ -/* Bit 7 unused */ - -SFRX(IN0BC, 0x7FB5); -SFRX(IN1CS, 0x7FB6); -SFRX(IN1BC, 0x7FB7); -SFRX(IN2CS, 0x7FB8); -SFRX(IN2BC, 0x7FB9); -SFRX(IN3CS, 0x7FBA); -SFRX(IN3BC, 0x7FBB); -SFRX(IN4CS, 0x7FBC); -SFRX(IN4BC, 0x7FBD); -SFRX(IN5CS, 0x7FBE); -SFRX(IN5BC, 0x7FBF); -SFRX(IN6CS, 0x7FC0); -SFRX(IN6BC, 0x7FC1); -SFRX(IN7CS, 0x7FC2); -SFRX(IN7BC, 0x7FC3); -/* 0x7FC4 reserved */ -SFRX(OUT0BC, 0x7FC5); -SFRX(OUT1CS, 0x7FC6); -SFRX(OUT1BC, 0x7FC7); -SFRX(OUT2CS, 0x7FC8); -SFRX(OUT2BC, 0x7FC9); -SFRX(OUT3CS, 0x7FCA); -SFRX(OUT3BC, 0x7FCB); -SFRX(OUT4CS, 0x7FCC); -SFRX(OUT4BC, 0x7FCD); -SFRX(OUT5CS, 0x7FCE); -SFRX(OUT5BC, 0x7FCF); -SFRX(OUT6CS, 0x7FD0); -SFRX(OUT6BC, 0x7FD1); -SFRX(OUT7CS, 0x7FD2); -SFRX(OUT7BC, 0x7FD3); - -/* The INxSTALL, OUTxSTALL, INxBSY and OUTxBSY bits are the same for all - * INxCS/OUTxCS registers. For better readability, we define them only once */ -#define EPSTALL bmBit0 -#define EPBSY bmBit1 - -/************************** Global USB Registers ***************************/ -SFRX(SUDPTRH, 0x7FD4); -SFRX(SUDPTRL, 0x7FD5); - -SFRX(USBCS, 0x7FD6); -#define SIGRSUME bmBit0 -#define RENUM bmBit1 -#define DISCOE bmBit2 -#define DISCON bmBit3 -/* Bit 4 unused */ -/* Bit 5 unused */ -/* Bit 6 unused */ -#define WAKESRC bmBit7 - -SFRX(TOGCTL, 0x7FD7); -#define TOG_EP0 bmBit0 -#define TOG_EP1 bmBit1 -#define TOG_EP2 bmBit2 -/* Bit 3 is read-only, always reads '0' */ -#define TOG_IO bmBit4 -#define TOG_R bmBit5 -#define TOG_S bmBit6 -#define TOG_Q bmBit7 - -SFRX(USBFRAMEL, 0x7FD8); -SFRX(USBFRAMEH, 0x7FD9); -/* 0x7FDA reserved */ -SFRX(FNADDR, 0x7FDB); -/* 0x7FDC reserved */ - -SFRX(USBPAIR, 0x7FDD); -#define PR2IN bmBit0 -#define PR4IN bmBit1 -#define PR6IN bmBit2 -#define PR2OUT bmBit3 -#define PR4OUT bmBit4 -#define PR6OUT bmBit5 -/* Bit 6 unused */ -#define ISOSEND0 bmBit7 - -SFRX(IN07VAL, 0x7FDE); -/* Bit 0 is read-only, always reads '1' */ -#define IN1VAL bmBit1 -#define IN2VAL bmBit2 -#define IN3VAL bmBit3 -#define IN4VAL bmBit4 -#define IN5VAL bmBit5 -#define IN6VAL bmBit6 -#define IN7VAL bmBit7 - -SFRX(OUT07VAL, 0x7FDF); -/* Bit 0 is read-only, always reads '1' */ -#define OUT1VAL bmBit1 -#define OUT2VAL bmBit2 -#define OUT3VAL bmBit3 -#define OUT4VAL bmBit4 -#define OUT5VAL bmBit5 -#define OUT6VAL bmBit6 -#define OUT7VAL bmBit7 - -SFRX(INISOVAL, 0x7FE0); -#define IN8VAL bmBit0 -#define IN9VAL bmBit1 -#define IN10VAL bmBit2 -#define IN11VAL bmBit3 -#define IN12VAL bmBit4 -#define IN13VAL bmBit5 -#define IN14VAL bmBit6 -#define IN15VAL bmBit7 - -SFRX(OUTISOVAL, 0x7FE1); -#define OUT8VAL bmBit0 -#define OUT9VAL bmBit1 -#define OUT10VAL bmBit2 -#define OUT11VAL bmBit3 -#define OUT12VAL bmBit4 -#define OUT13VAL bmBit5 -#define OUT14VAL bmBit6 -#define OUT15VAL bmBit7 - -SFRX(FASTXFR, 0x7FE2); -#define WMOD0 bmBit0 -#define WMOD1 bmBit1 -#define WPOL bmBit2 -#define RMOD0 bmBit3 -#define RMOD1 bmBit4 -#define RPOL bmBit5 -#define FBLK bmBit6 -#define FISO bmBit7 - -SFRX(AUTOPTRH, 0x7FE3); -SFRX(AUTOPTRL, 0x7FE4); -SFRX(AUTODATA, 0x7FE5); -/* 0x7FE6 reserved */ -/* 0x7FE7 reserved */ - -/******************************* Setup Data ********************************/ -SFRX(SETUPDAT[8], 0x7FE8); - -/************************* Isochronous FIFO sizes **************************/ -SFRX(OUT8ADDR, 0x7FF0); -SFRX(OUT9ADDR, 0x7FF1); -SFRX(OUT10ADDR, 0x7FF2); -SFRX(OUT11ADDR, 0x7FF3); -SFRX(OUT12ADDR, 0x7FF4); -SFRX(OUT13ADDR, 0x7FF5); -SFRX(OUT14ADDR, 0x7FF6); -SFRX(OUT15ADDR, 0x7FF7); - -SFRX(IN8ADDR, 0x7FF8); -SFRX(IN9ADDR, 0x7FF9); -SFRX(IN10ADDR, 0x7FFA); -SFRX(IN11ADDR, 0x7FFB); -SFRX(IN12ADDR, 0x7FFC); -SFRX(IN13ADDR, 0x7FFD); -SFRX(IN14ADDR, 0x7FFE); -SFRX(IN15ADDR, 0x7FFF); - -#endif diff --git a/src/jtag/drivers/OpenULINK/include/usb.h b/src/jtag/drivers/OpenULINK/include/usb.h deleted file mode 100644 index 9a261fed0..000000000 --- a/src/jtag/drivers/OpenULINK/include/usb.h +++ /dev/null @@ -1,265 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2011 by Martin Schmoelzer * - * * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 __USB_H -#define __USB_H - -#include "reg_ezusb.h" - -#include -#include - -#define NULL (void *)0; - -/* High and Low byte of a word (uint16_t) */ -#define HI8(word) (uint8_t)(((uint16_t)word >> 8) & 0xff) -#define LO8(word) (uint8_t)((uint16_t)word & 0xff) - -/* Convenience functions */ -#define STALL_EP0() (EP0CS |= EP0STALL) -#define CLEAR_IRQ() (EXIF &= ~USBINT) - -/*********** USB descriptors. See section 9.5 of the USB 1.1 spec **********/ - -/* USB Descriptor Types. See USB 1.1 spec, page 187, table 9-5 */ -#define DESCRIPTOR_TYPE_DEVICE 0x01 -#define DESCRIPTOR_TYPE_CONFIGURATION 0x02 -#define DESCRIPTOR_TYPE_STRING 0x03 -#define DESCRIPTOR_TYPE_INTERFACE 0x04 -#define DESCRIPTOR_TYPE_ENDPOINT 0x05 - -#define STR_DESCR(len, ...) { len * 2 + 2, DESCRIPTOR_TYPE_STRING, { __VA_ARGS__ } } - -/** USB Device Descriptor. See USB 1.1 spec, pp. 196 - 198 */ -struct usb_device_descriptor { - uint8_t bLength; /**< Size of this descriptor in bytes. */ - uint8_t bDescriptorType; /**< DEVICE Descriptor Type. */ - uint16_t bcdUSB; /**< USB specification release number (BCD). */ - uint8_t bDeviceClass; /**< Class code. */ - uint8_t bDeviceSubClass; /**< Subclass code. */ - uint8_t bDeviceProtocol; /**< Protocol code. */ - uint8_t bMaxPacketSize0; /**< Maximum packet size for EP0 (8, 16, 32, 64). */ - uint16_t idVendor; /**< USB Vendor ID. */ - uint16_t idProduct; /**< USB Product ID. */ - uint16_t bcdDevice; /**< Device Release Number (BCD). */ - uint8_t iManufacturer; /**< Index of manufacturer string descriptor. */ - uint8_t iProduct; /**< Index of product string descriptor. */ - uint8_t iSerialNumber; /**< Index of string descriptor containing serial #. */ - uint8_t bNumConfigurations; /**< Number of possible configurations. */ -}; - -/** USB Configuration Descriptor. See USB 1.1 spec, pp. 199 - 200 */ -struct usb_config_descriptor { - uint8_t bLength; /**< Size of this descriptor in bytes. */ - uint8_t bDescriptorType; /**< CONFIGURATION descriptor type. */ - uint16_t wTotalLength; /**< Combined total length of all descriptors. */ - uint8_t bNumInterfaces; /**< Number of interfaces in this configuration. */ - uint8_t bConfigurationValue; /**< Value used to select this configuration. */ - uint8_t iConfiguration; /**< Index of configuration string descriptor. */ - uint8_t bmAttributes; /**< Configuration characteristics. */ - uint8_t MaxPower; /**< Maximum power consumption in 2 mA units. */ -}; - -/** USB Interface Descriptor. See USB 1.1 spec, pp. 201 - 203 */ -struct usb_interface_descriptor { - uint8_t bLength; /**< Size of this descriptor in bytes. */ - uint8_t bDescriptorType; /**< INTERFACE descriptor type. */ - uint8_t bInterfaceNumber; /**< Interface number. */ - uint8_t bAlternateSetting; /**< Value used to select alternate setting. */ - uint8_t bNumEndpoints; /**< Number of endpoints used by this interface. */ - uint8_t bInterfaceClass; /**< Class code. */ - uint8_t bInterfaceSubclass; /**< Subclass code. */ - uint8_t bInterfaceProtocol; /**< Protocol code. */ - uint8_t iInterface; /**< Index of interface string descriptor. */ -}; - -/** USB Endpoint Descriptor. See USB 1.1 spec, pp. 203 - 204 */ -struct usb_endpoint_descriptor { - uint8_t bLength; /**< Size of this descriptor in bytes. */ - uint8_t bDescriptorType; /**< ENDPOINT descriptor type. */ - uint8_t bEndpointAddress; /**< Endpoint Address: USB 1.1 spec, table 9-10. */ - uint8_t bmAttributes; /**< Endpoint Attributes: USB 1.1 spec, table 9-10. */ - uint16_t wMaxPacketSize; /**< Maximum packet size for this endpoint. */ - uint8_t bInterval; /**< Polling interval (in ms) for this endpoint. */ -}; - -/** USB Language Descriptor. See USB 1.1 spec, pp. 204 - 205 */ -struct usb_language_descriptor { - uint8_t bLength; /**< Size of this descriptor in bytes. */ - uint8_t bDescriptorType; /**< STRING descriptor type. */ - uint16_t wLANGID[]; /**< LANGID codes. */ -}; - -/** USB String Descriptor. See USB 1.1 spec, pp. 204 - 205 */ -struct usb_string_descriptor { - uint8_t bLength; /**< Size of this descriptor in bytes. */ - uint8_t bDescriptorType; /**< STRING descriptor type. */ - uint16_t bString[]; /**< UNICODE encoded string. */ -}; - -/********************** USB Control Endpoint 0 related *********************/ - -/** USB Control Setup Data. See USB 1.1 spec, pp. 183 - 185 */ -struct setup_data { - uint8_t bmRequestType; /**< Characteristics of a request. */ - uint8_t bRequest; /**< Specific request. */ - uint16_t wValue; /**< Field that varies according to request. */ - uint16_t wIndex; /**< Field that varies according to request. */ - uint16_t wLength; /**< Number of bytes to transfer in data stage. */ -}; - -/* External declarations for variables that need to be accessed outside of - * the USB module */ -extern volatile bool EP2_out; -extern volatile bool EP2_in; -extern volatile __xdata __at 0x7FE8 struct setup_data setup_data; - -/* - * USB Request Types (bmRequestType): See USB 1.1 spec, page 183, table 9-2 - * - * Bit 7: Data transfer direction - * 0 = Host-to-device - * 1 = Device-to-host - * Bit 6...5: Type - * 0 = Standard - * 1 = Class - * 2 = Vendor - * 3 = Reserved - * Bit 4...0: Recipient - * 0 = Device - * 1 = Interface - * 2 = Endpoint - * 3 = Other - * 4...31 = Reserved - */ - -#define USB_DIR_OUT 0x00 -#define USB_DIR_IN 0x80 - -#define USB_REQ_TYPE_STANDARD (0x00 << 5) -#define USB_REQ_TYPE_CLASS (0x01 << 5) -#define USB_REQ_TYPE_VENDOR (0x02 << 5) -#define USB_REQ_TYPE_RESERVED (0x03 << 5) - -#define USB_RECIP_DEVICE 0x00 -#define USB_RECIP_INTERFACE 0x01 -#define USB_RECIP_ENDPOINT 0x02 -#define USB_RECIP_OTHER 0x03 - -/* bmRequestType for USB Standard Requests */ - -/* Clear Interface Request */ -#define CF_DEVICE (USB_DIR_OUT | USB_REQ_TYPE_STANDARD | USB_RECIP_DEVICE) -#define CF_INTERFACE (USB_DIR_OUT | USB_REQ_TYPE_STANDARD | USB_RECIP_INTERFACE) -#define CF_ENDPOINT (USB_DIR_OUT | USB_REQ_TYPE_STANDARD | USB_RECIP_ENDPOINT) - -/* Get Configuration Request */ -#define GC_DEVICE (USB_DIR_IN | USB_REQ_TYPE_STANDARD | USB_RECIP_DEVICE) - -/* Get Descriptor Request */ -#define GD_DEVICE (USB_DIR_IN | USB_REQ_TYPE_STANDARD | USB_RECIP_DEVICE) - -/* Get Interface Request */ -#define GI_INTERFACE (USB_DIR_IN | USB_REQ_TYPE_STANDARD | USB_RECIP_INTERFACE) - -/* Get Status Request: See USB 1.1 spec, page 190 */ -#define GS_DEVICE (USB_DIR_IN | USB_REQ_TYPE_STANDARD | USB_RECIP_DEVICE) -#define GS_INTERFACE (USB_DIR_IN | USB_REQ_TYPE_STANDARD | USB_RECIP_INTERFACE) -#define GS_ENDPOINT (USB_DIR_IN | USB_REQ_TYPE_STANDARD | USB_RECIP_ENDPOINT) - -/* Set Address Request is handled by EZ-USB core */ - -/* Set Configuration Request */ -#define SC_DEVICE (USB_DIR_OUT | USB_REQ_TYPE_STANDARD | USB_RECIP_DEVICE) - -/* Set Descriptor Request */ -#define SD_DEVICE (USB_DIR_OUT | USB_REQ_TYPE_STANDARD | USB_RECIP_DEVICE) - -/* Set Feature Request */ -#define SF_DEVICE (USB_DIR_OUT | USB_REQ_TYPE_STANDARD | USB_RECIP_DEVICE) -#define SF_INTERFACE (USB_DIR_OUT | USB_REQ_TYPE_STANDARD | USB_RECIP_INTERFACE) -#define SF_ENDPOINT (USB_DIR_OUT | USB_REQ_TYPE_STANDARD | USB_RECIP_ENDPOINT) - -/* Set Interface Request */ -#define SI_INTERFACE (USB_DIR_OUT | USB_REQ_TYPE_STANDARD | USB_RECIP_INTERFACE) - -/* Synch Frame Request */ -#define SY_ENDPOINT (USB_DIR_IN | USB_REQ_TYPE_STANDARD | USB_RECIP_ENDPOINT) - -/* USB Requests (bRequest): See USB 1.1 spec, table 9-4 on page 187 */ -#define GET_STATUS 0 -#define CLEAR_FEATURE 1 -/* Value '2' is reserved for future use */ -#define SET_FEATURE 3 -/* Value '4' is reserved for future use */ -#define SET_ADDRESS 5 -#define GET_DESCRIPTOR 6 -#define SET_DESCRIPTOR 7 -#define GET_CONFIGURATION 8 -#define SET_CONFIGURATION 9 -#define GET_INTERFACE 10 -#define SET_INTERFACE 11 -#define SYNCH_FRAME 12 - -/* Standard Feature Selectors: See USB 1.1 spec, table 9-6 on page 188 */ -#define DEVICE_REMOTE_WAKEUP 1 -#define ENDPOINT_HALT 0 - -/************************** EZ-USB specific stuff **************************/ - -/** USB Interrupts. See AN2131-TRM, page 9-4 for details */ -enum usb_isr { - SUDAV_ISR = 13, - SOF_ISR, - SUTOK_ISR, - SUSPEND_ISR, - USBRESET_ISR, - IBN_ISR, - EP0IN_ISR, - EP0OUT_ISR, - EP1IN_ISR, - EP1OUT_ISR, - EP2IN_ISR, - EP2OUT_ISR, - EP3IN_ISR, - EP3OUT_ISR, - EP4IN_ISR, - EP4OUT_ISR, - EP5IN_ISR, - EP5OUT_ISR, - EP6IN_ISR, - EP6OUT_ISR, - EP7IN_ISR, - EP7OUT_ISR -}; - -/*************************** Function Prototypes ***************************/ - -__xdata uint8_t *usb_get_endpoint_cs_reg(uint8_t ep); -void usb_reset_data_toggle(uint8_t ep); - -bool usb_handle_get_status(void); -bool usb_handle_clear_feature(void); -bool usb_handle_set_feature(void); -bool usb_handle_get_descriptor(void); -void usb_handle_set_interface(void); - -void usb_handle_setup_data(void); -void usb_init(void); - -#endif diff --git a/src/jtag/drivers/OpenULINK/src/USBJmpTb.a51 b/src/jtag/drivers/OpenULINK/src/USBJmpTb.a51 deleted file mode 100644 index f10ad484f..000000000 --- a/src/jtag/drivers/OpenULINK/src/USBJmpTb.a51 +++ /dev/null @@ -1,81 +0,0 @@ -;--------------------------------------------------------------------------; -; Copyright (C) 2011-2013 by Martin Schmoelzer ; -; ; -; ; -; This program is free software; you can redistribute it and/or modify ; -; it under the terms of the GNU General Public License as published by ; -; the Free Software Foundation; either version 2 of the License, or ; -; (at your option) any later version. ; -; ; -; This program is distributed in the hope that it will be useful, ; -; but WITHOUT ANY WARRANTY; without even the implied warranty of ; -; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ; -; GNU General Public License for more details. ; -; ; -; You should have received a copy of the GNU General Public License ; -; along with this program. If not, see . ; -;--------------------------------------------------------------------------; - -.module JUMPTABLE -.globl USB_AutoVector -.globl USB_Jump_Table - -;--------------------------------------------------------------------------; -; Interrupt Vectors ; -;--------------------------------------------------------------------------; -.area USB_JV (ABS,OVR) ; Absolute, Overlay -.org 0x43 ; USB interrupt (INT2) jumps here -USB_AutoVector = #. + 2 - ljmp USB_Jump_Table - -;--------------------------------------------------------------------------; -; USB Jump Table ; -;--------------------------------------------------------------------------; -.area USB_JT (ABS) ; Absolute placement -.org 0x1B00 ; Place jump table at 0x1B00 - -USB_Jump_Table: ; autovector jump table - ljmp _sudav_isr ; Setup Data Available - .db 0 - ljmp _sof_isr ; Start of Frame - .db 0 - ljmp _sutok_isr ; Setup Data Loading - .db 0 - ljmp _suspend_isr ; Global Suspend - .db 0 - ljmp _usbreset_isr ; USB Reset - .db 0 - ljmp _ibn_isr ; IN Bulk NAK interrupt - .db 0 - ljmp _ep0in_isr ; Endpoint 0 IN - .db 0 - ljmp _ep0out_isr ; Endpoint 0 OUT - .db 0 - ljmp _ep1in_isr ; Endpoint 1 IN - .db 0 - ljmp _ep1out_isr ; Endpoint 1 OUT - .db 0 - ljmp _ep2in_isr ; Endpoint 2 IN - .db 0 - ljmp _ep2out_isr ; Endpoint 2 OUT - .db 0 - ljmp _ep3in_isr ; Endpoint 3 IN - .db 0 - ljmp _ep3out_isr ; Endpoint 3 OUT - .db 0 - ljmp _ep4in_isr ; Endpoint 4 IN - .db 0 - ljmp _ep4out_isr ; Endpoint 4 OUT - .db 0 - ljmp _ep5in_isr ; Endpoint 5 IN - .db 0 - ljmp _ep5out_isr ; Endpoint 5 OUT - .db 0 - ljmp _ep6in_isr ; Endpoint 6 IN - .db 0 - ljmp _ep6out_isr ; Endpoint 6 OUT - .db 0 - ljmp _ep7in_isr ; Endpoint 7 IN - .db 0 - ljmp _ep7out_isr ; Endpoint 7 OUT - .db 0 diff --git a/src/jtag/drivers/OpenULINK/src/delay.c b/src/jtag/drivers/OpenULINK/src/delay.c deleted file mode 100644 index 326056768..000000000 --- a/src/jtag/drivers/OpenULINK/src/delay.c +++ /dev/null @@ -1,49 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2011 by Martin Schmoelzer * - * * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#include "delay.h" - -void delay_5us(void) -{ - NOP; -} - -void delay_1ms(void) -{ - uint16_t i; - - for (i = 0; i < 598; i++) - ; -} - -void delay_us(uint16_t delay) -{ - uint16_t i; - uint16_t maxcount = (delay / 5); - - for (i = 0; i < maxcount; i++) - delay_5us(); -} - -void delay_ms(uint16_t delay) -{ - uint16_t i; - - for (i = 0; i < delay; i++) - delay_1ms(); -} diff --git a/src/jtag/drivers/OpenULINK/src/jtag.c b/src/jtag/drivers/OpenULINK/src/jtag.c deleted file mode 100644 index 413945566..000000000 --- a/src/jtag/drivers/OpenULINK/src/jtag.c +++ /dev/null @@ -1,721 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2011 by Martin Schmoelzer * - * * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#include "jtag.h" - -#include "io.h" -#include "msgtypes.h" -#include "common.h" - -#include - -/** Delay value for SCAN_IN operations with less than maximum TCK frequency */ -uint8_t delay_scan_in; - -/** Delay value for SCAN_OUT operations with less than maximum TCK frequency */ -uint8_t delay_scan_out; - -/** Delay value for SCAN_IO operations with less than maximum TCK frequency */ -uint8_t delay_scan_io; - -/** Delay value for CLOCK_TCK operations with less than maximum frequency */ -uint8_t delay_tck; - -/** Delay value for CLOCK_TMS operations with less than maximum frequency */ -uint8_t delay_tms; - -/** - * Perform JTAG SCAN-IN operation at maximum TCK frequency. - * - * Dummy data is shifted into the JTAG chain via TDI, TDO data is sampled and - * stored in the EP2 IN buffer. - * - * Maximum achievable TCK frequency is 182 kHz for ULINK clocked at 24 MHz. - * - * @param out_offset offset in OUT2BUF where payload data starts - */ -void jtag_scan_in(uint8_t out_offset, uint8_t in_offset) -{ - uint8_t scan_size_bytes, bits_last_byte; - uint8_t tms_count_start, tms_count_end; - uint8_t tms_sequence_start, tms_sequence_end; - uint8_t tdo_data, i, j; - - uint8_t outb_buffer; - - /* Get parameters from OUT2BUF */ - scan_size_bytes = OUT2BUF[out_offset]; - bits_last_byte = OUT2BUF[out_offset + 1]; - tms_count_start = (OUT2BUF[out_offset + 2] >> 4) & 0x0F; - tms_count_end = OUT2BUF[out_offset + 2] & 0x0F; - tms_sequence_start = OUT2BUF[out_offset + 3]; - tms_sequence_end = OUT2BUF[out_offset + 4]; - - if (tms_count_start > 0) - jtag_clock_tms(tms_count_start, tms_sequence_start); - - outb_buffer = OUTB & ~(PIN_TDI | PIN_TCK | PIN_TMS); - - /* Shift all bytes except the last byte */ - for (i = 0; i < scan_size_bytes - 1; i++) { - tdo_data = 0; - - for (j = 0; j < 8; j++) { - OUTB = outb_buffer; /* TCK changes here */ - tdo_data = tdo_data >> 1; - OUTB = (outb_buffer | PIN_TCK); - - if (GET_TDO()) - tdo_data |= 0x80; - } - - /* Copy TDO data to IN2BUF */ - IN2BUF[i + in_offset] = tdo_data; - } - - tdo_data = 0; - - /* Shift the last byte */ - for (j = 0; j < bits_last_byte; j++) { - /* Assert TMS signal if requested and this is the last bit */ - if ((j == bits_last_byte - 1) && (tms_count_end > 0)) { - outb_buffer |= PIN_TMS; - tms_count_end--; - tms_sequence_end = tms_sequence_end >> 1; - } - - OUTB = outb_buffer; /* TCK changes here */ - tdo_data = tdo_data >> 1; - OUTB = (outb_buffer | PIN_TCK); - - if (GET_TDO()) - tdo_data |= 0x80; - } - tdo_data = tdo_data >> (8 - bits_last_byte); - - /* Copy TDO data to IN2BUF */ - IN2BUF[i + in_offset] = tdo_data; - - /* Move to correct end state */ - if (tms_count_end > 0) - jtag_clock_tms(tms_count_end, tms_sequence_end); -} - -/** - * Perform JTAG SCAN-IN operation at variable TCK frequency. - * - * Dummy data is shifted into the JTAG chain via TDI, TDO data is sampled and - * stored in the EP2 IN buffer. - * - * Maximum achievable TCK frequency is 113 kHz for ULINK clocked at 24 MHz. - * - * @param out_offset offset in OUT2BUF where payload data starts - */ -void jtag_slow_scan_in(uint8_t out_offset, uint8_t in_offset) -{ - uint8_t scan_size_bytes, bits_last_byte; - uint8_t tms_count_start, tms_count_end; - uint8_t tms_sequence_start, tms_sequence_end; - uint8_t tdo_data, i, j, k; - - uint8_t outb_buffer; - - /* Get parameters from OUT2BUF */ - scan_size_bytes = OUT2BUF[out_offset]; - bits_last_byte = OUT2BUF[out_offset + 1]; - tms_count_start = (OUT2BUF[out_offset + 2] >> 4) & 0x0F; - tms_count_end = OUT2BUF[out_offset + 2] & 0x0F; - tms_sequence_start = OUT2BUF[out_offset + 3]; - tms_sequence_end = OUT2BUF[out_offset + 4]; - - if (tms_count_start > 0) - jtag_slow_clock_tms(tms_count_start, tms_sequence_start); - - outb_buffer = OUTB & ~(PIN_TDI | PIN_TCK | PIN_TMS); - - /* Shift all bytes except the last byte */ - for (i = 0; i < scan_size_bytes - 1; i++) { - tdo_data = 0; - - for (j = 0; j < 8; j++) { - OUTB = outb_buffer; /* TCK changes here */ - for (k = 0; k < delay_scan_in; k++) - ; - tdo_data = tdo_data >> 1; - - OUTB = (outb_buffer | PIN_TCK); - for (k = 0; k < delay_scan_in; k++) - ; - - if (GET_TDO()) - tdo_data |= 0x80; - } - - /* Copy TDO data to IN2BUF */ - IN2BUF[i + in_offset] = tdo_data; - } - - tdo_data = 0; - - /* Shift the last byte */ - for (j = 0; j < bits_last_byte; j++) { - /* Assert TMS signal if requested and this is the last bit */ - if ((j == bits_last_byte - 1) && (tms_count_end > 0)) { - outb_buffer |= PIN_TMS; - tms_count_end--; - tms_sequence_end = tms_sequence_end >> 1; - } - - OUTB = outb_buffer; /* TCK changes here */ - for (k = 0; k < delay_scan_in; k++) - ; - tdo_data = tdo_data >> 1; - - OUTB = (outb_buffer | PIN_TCK); - for (k = 0; k < delay_scan_in; k++) - ; - - if (GET_TDO()) - tdo_data |= 0x80; - } - tdo_data = tdo_data >> (8 - bits_last_byte); - - /* Copy TDO data to IN2BUF */ - IN2BUF[i + in_offset] = tdo_data; - - /* Move to correct end state */ - if (tms_count_end > 0) - jtag_slow_clock_tms(tms_count_end, tms_sequence_end); -} - -/** - * Perform JTAG SCAN-OUT operation at maximum TCK frequency. - * - * Data stored in EP2 OUT buffer is shifted into the JTAG chain via TDI, TDO - * data is not sampled. - * The TAP-FSM state is alyways left in the PAUSE-DR/PAUSE-IR state. - * - * Maximum achievable TCK frequency is 142 kHz for ULINK clocked at 24 MHz. - * - * @param out_offset offset in OUT2BUF where payload data starts - */ -void jtag_scan_out(uint8_t out_offset) -{ - uint8_t scan_size_bytes, bits_last_byte; - uint8_t tms_count_start, tms_count_end; - uint8_t tms_sequence_start, tms_sequence_end; - uint8_t tdi_data, i, j; - - uint8_t outb_buffer; - - /* Get parameters from OUT2BUF */ - scan_size_bytes = OUT2BUF[out_offset]; - bits_last_byte = OUT2BUF[out_offset + 1]; - tms_count_start = (OUT2BUF[out_offset + 2] >> 4) & 0x0F; - tms_count_end = OUT2BUF[out_offset + 2] & 0x0F; - tms_sequence_start = OUT2BUF[out_offset + 3]; - tms_sequence_end = OUT2BUF[out_offset + 4]; - - if (tms_count_start > 0) - jtag_clock_tms(tms_count_start, tms_sequence_start); - - outb_buffer = OUTB & ~(PIN_TCK | PIN_TMS); - - /* Shift all bytes except the last byte */ - for (i = 0; i < scan_size_bytes - 1; i++) { - tdi_data = OUT2BUF[i + out_offset + 5]; - - for (j = 0; j < 8; j++) { - if (tdi_data & 0x01) - outb_buffer |= PIN_TDI; - else - outb_buffer &= ~PIN_TDI; - - OUTB = outb_buffer; /* TDI and TCK change here */ - tdi_data = tdi_data >> 1; - OUTB = (outb_buffer | PIN_TCK); - } - } - - tdi_data = OUT2BUF[i + out_offset + 5]; - - /* Shift the last byte */ - for (j = 0; j < bits_last_byte; j++) { - if (tdi_data & 0x01) - outb_buffer |= PIN_TDI; - else - outb_buffer &= ~PIN_TDI; - - /* Assert TMS signal if requested and this is the last bit */ - if ((j == bits_last_byte - 1) && (tms_count_end > 0)) { - outb_buffer |= PIN_TMS; - tms_count_end--; - tms_sequence_end = tms_sequence_end >> 1; - } - - OUTB = outb_buffer; /* TDI and TCK change here */ - tdi_data = tdi_data >> 1; - OUTB = (outb_buffer | PIN_TCK); - } - - /* Move to correct end state */ - if (tms_count_end > 0) - jtag_clock_tms(tms_count_end, tms_sequence_end); -} - -/** - * Perform JTAG SCAN-OUT operation at maximum TCK frequency. - * - * Data stored in EP2 OUT buffer is shifted into the JTAG chain via TDI, TDO - * data is not sampled. - * The TAP-FSM state is alyways left in the PAUSE-DR/PAUSE-IR state. - * - * Maximum achievable TCK frequency is 97 kHz for ULINK clocked at 24 MHz. - * - * @param out_offset offset in OUT2BUF where payload data starts - */ -void jtag_slow_scan_out(uint8_t out_offset) -{ - uint8_t scan_size_bytes, bits_last_byte; - uint8_t tms_count_start, tms_count_end; - uint8_t tms_sequence_start, tms_sequence_end; - uint8_t tdi_data, i, j, k; - - uint8_t outb_buffer; - - /* Get parameters from OUT2BUF */ - scan_size_bytes = OUT2BUF[out_offset]; - bits_last_byte = OUT2BUF[out_offset + 1]; - tms_count_start = (OUT2BUF[out_offset + 2] >> 4) & 0x0F; - tms_count_end = OUT2BUF[out_offset + 2] & 0x0F; - tms_sequence_start = OUT2BUF[out_offset + 3]; - tms_sequence_end = OUT2BUF[out_offset + 4]; - - if (tms_count_start > 0) - jtag_slow_clock_tms(tms_count_start, tms_sequence_start); - - outb_buffer = OUTB & ~(PIN_TCK | PIN_TMS); - - /* Shift all bytes except the last byte */ - for (i = 0; i < scan_size_bytes - 1; i++) { - tdi_data = OUT2BUF[i + out_offset + 5]; - - for (j = 0; j < 8; j++) { - if (tdi_data & 0x01) - outb_buffer |= PIN_TDI; - else - outb_buffer &= ~PIN_TDI; - - OUTB = outb_buffer; /* TDI and TCK change here */ - for (k = 0; k < delay_scan_out; k++) - ; - tdi_data = tdi_data >> 1; - - OUTB = (outb_buffer | PIN_TCK); - for (k = 0; k < delay_scan_out; k++) - ; - } - } - - tdi_data = OUT2BUF[i + out_offset + 5]; - - /* Shift the last byte */ - for (j = 0; j < bits_last_byte; j++) { - if (tdi_data & 0x01) - outb_buffer |= PIN_TDI; - else - outb_buffer &= ~PIN_TDI; - - /* Assert TMS signal if requested and this is the last bit */ - if ((j == bits_last_byte - 1) && (tms_count_end > 0)) { - outb_buffer |= PIN_TMS; - tms_count_end--; - tms_sequence_end = tms_sequence_end >> 1; - } - - OUTB = outb_buffer; /* TDI and TCK change here */ - for (k = 0; k < delay_scan_out; k++) - ; - tdi_data = tdi_data >> 1; - - OUTB = (outb_buffer | PIN_TCK); - for (k = 0; k < delay_scan_out; k++) - ; - } - - /* Move to correct end state */ - if (tms_count_end > 0) - jtag_slow_clock_tms(tms_count_end, tms_sequence_end); -} - -/** - * Perform bidirectional JTAG SCAN operation at maximum TCK frequency. - * - * Data stored in EP2 OUT buffer is shifted into the JTAG chain via TDI, TDO - * data is sampled and stored in the EP2 IN buffer. - * The TAP-FSM state is alyways left in the PAUSE-DR/PAUSE-IR state. - * - * Maximum achievable TCK frequency is 100 kHz for ULINK clocked at 24 MHz. - * - * @param out_offset offset in OUT2BUF where payload data starts - */ -void jtag_scan_io(uint8_t out_offset, uint8_t in_offset) -{ - uint8_t scan_size_bytes, bits_last_byte; - uint8_t tms_count_start, tms_count_end; - uint8_t tms_sequence_start, tms_sequence_end; - uint8_t tdi_data, tdo_data, i, j; - - uint8_t outb_buffer; - - /* Get parameters from OUT2BUF */ - scan_size_bytes = OUT2BUF[out_offset]; - bits_last_byte = OUT2BUF[out_offset + 1]; - tms_count_start = (OUT2BUF[out_offset + 2] >> 4) & 0x0F; - tms_count_end = OUT2BUF[out_offset + 2] & 0x0F; - tms_sequence_start = OUT2BUF[out_offset + 3]; - tms_sequence_end = OUT2BUF[out_offset + 4]; - - if (tms_count_start > 0) - jtag_clock_tms(tms_count_start, tms_sequence_start); - - outb_buffer = OUTB & ~(PIN_TCK | PIN_TMS); - - /* Shift all bytes except the last byte */ - for (i = 0; i < scan_size_bytes - 1; i++) { - tdi_data = OUT2BUF[i + out_offset + 5]; - tdo_data = 0; - - for (j = 0; j < 8; j++) { - if (tdi_data & 0x01) - outb_buffer |= PIN_TDI; - else - outb_buffer &= ~PIN_TDI; - - OUTB = outb_buffer; /* TDI and TCK change here */ - tdi_data = tdi_data >> 1; - OUTB = (outb_buffer | PIN_TCK); - tdo_data = tdo_data >> 1; - - if (GET_TDO()) - tdo_data |= 0x80; - } - - /* Copy TDO data to IN2BUF */ - IN2BUF[i + in_offset] = tdo_data; - } - - tdi_data = OUT2BUF[i + out_offset + 5]; - tdo_data = 0; - - /* Shift the last byte */ - for (j = 0; j < bits_last_byte; j++) { - if (tdi_data & 0x01) - outb_buffer |= PIN_TDI; - else - outb_buffer &= ~PIN_TDI; - - /* Assert TMS signal if requested and this is the last bit */ - if ((j == bits_last_byte - 1) && (tms_count_end > 0)) { - outb_buffer |= PIN_TMS; - tms_count_end--; - tms_sequence_end = tms_sequence_end >> 1; - } - - OUTB = outb_buffer; /* TDI and TCK change here */ - tdi_data = tdi_data >> 1; - OUTB = (outb_buffer | PIN_TCK); - tdo_data = tdo_data >> 1; - - if (GET_TDO()) - tdo_data |= 0x80; - } - tdo_data = tdo_data >> (8 - bits_last_byte); - - /* Copy TDO data to IN2BUF */ - IN2BUF[i + in_offset] = tdo_data; - - /* Move to correct end state */ - if (tms_count_end > 0) - jtag_clock_tms(tms_count_end, tms_sequence_end); -} - -/** - * Perform bidirectional JTAG SCAN operation at maximum TCK frequency. - * - * Data stored in EP2 OUT buffer is shifted into the JTAG chain via TDI, TDO - * data is sampled and stored in the EP2 IN buffer. - * The TAP-FSM state is alyways left in the PAUSE-DR/PAUSE-IR state. - * - * Maximum achievable TCK frequency is 78 kHz for ULINK clocked at 24 MHz. - * - * @param out_offset offset in OUT2BUF where payload data starts - */ -void jtag_slow_scan_io(uint8_t out_offset, uint8_t in_offset) -{ - uint8_t scan_size_bytes, bits_last_byte; - uint8_t tms_count_start, tms_count_end; - uint8_t tms_sequence_start, tms_sequence_end; - uint8_t tdi_data, tdo_data, i, j, k; - - uint8_t outb_buffer; - - /* Get parameters from OUT2BUF */ - scan_size_bytes = OUT2BUF[out_offset]; - bits_last_byte = OUT2BUF[out_offset + 1]; - tms_count_start = (OUT2BUF[out_offset + 2] >> 4) & 0x0F; - tms_count_end = OUT2BUF[out_offset + 2] & 0x0F; - tms_sequence_start = OUT2BUF[out_offset + 3]; - tms_sequence_end = OUT2BUF[out_offset + 4]; - - if (tms_count_start > 0) - jtag_slow_clock_tms(tms_count_start, tms_sequence_start); - - outb_buffer = OUTB & ~(PIN_TCK | PIN_TMS); - - /* Shift all bytes except the last byte */ - for (i = 0; i < scan_size_bytes - 1; i++) { - tdi_data = OUT2BUF[i + out_offset + 5]; - tdo_data = 0; - - for (j = 0; j < 8; j++) { - if (tdi_data & 0x01) - outb_buffer |= PIN_TDI; - else - outb_buffer &= ~PIN_TDI; - - OUTB = outb_buffer; /* TDI and TCK change here */ - for (k = 0; k < delay_scan_io; k++) - ; - tdi_data = tdi_data >> 1; - - OUTB = (outb_buffer | PIN_TCK); - for (k = 0; k < delay_scan_io; k++) - ; - tdo_data = tdo_data >> 1; - - if (GET_TDO()) - tdo_data |= 0x80; - } - - /* Copy TDO data to IN2BUF */ - IN2BUF[i + in_offset] = tdo_data; - } - - tdi_data = OUT2BUF[i + out_offset + 5]; - tdo_data = 0; - - /* Shift the last byte */ - for (j = 0; j < bits_last_byte; j++) { - if (tdi_data & 0x01) - outb_buffer |= PIN_TDI; - else - outb_buffer &= ~PIN_TDI; - - /* Assert TMS signal if requested and this is the last bit */ - if ((j == bits_last_byte - 1) && (tms_count_end > 0)) { - outb_buffer |= PIN_TMS; - tms_count_end--; - tms_sequence_end = tms_sequence_end >> 1; - } - - OUTB = outb_buffer; /* TDI and TCK change here */ - for (k = 0; k < delay_scan_io; k++) - ; - tdi_data = tdi_data >> 1; - - OUTB = (outb_buffer | PIN_TCK); - for (k = 0; k < delay_scan_io; k++) - ; - tdo_data = tdo_data >> 1; - - if (GET_TDO()) - tdo_data |= 0x80; - } - tdo_data = tdo_data >> (8 - bits_last_byte); - - /* Copy TDO data to IN2BUF */ - IN2BUF[i + in_offset] = tdo_data; - - /* Move to correct end state */ - if (tms_count_end > 0) - jtag_slow_clock_tms(tms_count_end, tms_sequence_end); -} - -/** - * Generate TCK clock cycles. - * - * Maximum achievable TCK frequency is 375 kHz for ULINK clocked at 24 MHz. - * - * @param count number of TCK clock cyclces to generate. - */ -void jtag_clock_tck(uint16_t count) -{ - uint16_t i; - uint8_t outb_buffer = OUTB & ~(PIN_TCK); - - for (i = 0; i < count; i++) { - OUTB = outb_buffer; - OUTB = outb_buffer | PIN_TCK; - } -} - -/** - * Generate TCK clock cycles at variable frequency. - * - * Maximum achieveable TCK frequency is 166.6 kHz for ULINK clocked at 24 MHz. - * - * @param count number of TCK clock cyclces to generate. - */ -void jtag_slow_clock_tck(uint16_t count) -{ - uint16_t i; - uint8_t j; - uint8_t outb_buffer = OUTB & ~(PIN_TCK); - - for (i = 0; i < count; i++) { - OUTB = outb_buffer; - for (j = 0; j < delay_tck; j++) - ; - OUTB = outb_buffer | PIN_TCK; - for (j = 0; j < delay_tck; j++) - ; - } -} - -/** - * Perform TAP FSM state transitions at maximum TCK frequency. - * - * Maximum achievable TCK frequency is 176 kHz for ULINK clocked at 24 MHz. - * - * @param count the number of state transitions to perform. - * @param sequence the TMS pin levels for each state transition, starting with - * the least-significant bit. - */ -void jtag_clock_tms(uint8_t count, uint8_t sequence) -{ - uint8_t outb_buffer = OUTB & ~(PIN_TCK); - uint8_t i; - - for (i = 0; i < count; i++) { - /* Set TMS pin according to sequence parameter */ - if (sequence & 0x1) - outb_buffer |= PIN_TMS; - else - outb_buffer &= ~PIN_TMS; - - OUTB = outb_buffer; - sequence = sequence >> 1; - OUTB = outb_buffer | PIN_TCK; - } -} - -/** - * Perform TAP-FSM state transitions at less than maximum TCK frequency. - * - * Maximum achievable TCK frequency is 117 kHz for ULINK clocked at 24 MHz. - * - * @param count the number of state transitions to perform. - * @param sequence the TMS pin levels for each state transition, starting with - * the least-significant bit. - */ -void jtag_slow_clock_tms(uint8_t count, uint8_t sequence) -{ - uint8_t outb_buffer = OUTB & ~(PIN_TCK); - uint8_t i, j; - - for (i = 0; i < count; i++) { - /* Set TMS pin according to sequence parameter */ - if (sequence & 0x1) - outb_buffer |= PIN_TMS; - else - outb_buffer &= ~PIN_TMS; - - OUTB = outb_buffer; - for (j = 0; j < delay_tms; j++) - ; - sequence = sequence >> 1; - OUTB = outb_buffer | PIN_TCK; - for (j = 0; j < delay_tms; j++) - ; - } -} - -/** - * Get current JTAG signal states. - * - * @return a 16-bit integer where the most-significant byte contains the state - * of the JTAG input signals and the least-significant byte contains the state - * of the JTAG output signals. - */ -uint16_t jtag_get_signals(void) -{ - uint8_t input_signal_state, output_signal_state; - - input_signal_state = 0; - output_signal_state = 0; - - /* Get states of input pins */ - if (GET_TDO()) - input_signal_state |= SIGNAL_TDO; - if (GET_BRKOUT()) - input_signal_state |= SIGNAL_BRKOUT; - if (GET_TRAP()) - input_signal_state |= SIGNAL_TRAP; - if (GET_RTCK()) { - /* Using RTCK this way would be extremely slow, - * implemented only for the sake of completeness */ - input_signal_state |= SIGNAL_RTCK; - } - - /* Get states of output pins */ - output_signal_state = PINSB & MASK_PORTB_DIRECTION_OUT; - - return ((uint16_t)input_signal_state << 8) | ((uint16_t)output_signal_state); -} - -/** - * Set state of JTAG output signals. - * - * @param low signals which should be de-asserted. - * @param high signals which should be asserted. - */ -void jtag_set_signals(uint8_t low, uint8_t high) -{ - OUTB &= ~(low & MASK_PORTB_DIRECTION_OUT); - OUTB |= (high & MASK_PORTB_DIRECTION_OUT); -} - -/** - * Configure TCK delay parameters. - * - * @param scan_in number of delay cycles in scan_in operations. - * @param scan_out number of delay cycles in scan_out operations. - * @param scan_io number of delay cycles in scan_io operations. - * @param tck number of delay cycles in clock_tck operations. - * @param tms number of delay cycles in clock_tms operations. - */ -void jtag_configure_tck_delay(uint8_t scan_in, uint8_t scan_out, - uint8_t scan_io, uint8_t tck, uint8_t tms) -{ - delay_scan_in = scan_in; - delay_scan_out = scan_out; - delay_scan_io = scan_io; - delay_tck = tck; - delay_tms = tms; -} diff --git a/src/jtag/drivers/OpenULINK/src/main.c b/src/jtag/drivers/OpenULINK/src/main.c deleted file mode 100644 index f331c9ebf..000000000 --- a/src/jtag/drivers/OpenULINK/src/main.c +++ /dev/null @@ -1,89 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2011 by Martin Schmoelzer * - * * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#include "main.h" - -#include "io.h" -#include "usb.h" -#include "protocol.h" - -extern void sudav_isr(void) __interrupt SUDAV_ISR; -extern void sof_isr(void) __interrupt; -extern void sutok_isr(void) __interrupt; -extern void suspend_isr(void) __interrupt; -extern void usbreset_isr(void) __interrupt; -extern void ibn_isr(void) __interrupt; -extern void ep0in_isr(void) __interrupt; -extern void ep0out_isr(void) __interrupt; -extern void ep1in_isr(void) __interrupt; -extern void ep1out_isr(void) __interrupt; -extern void ep2in_isr(void) __interrupt; -extern void ep2out_isr(void) __interrupt; -extern void ep3in_isr(void) __interrupt; -extern void ep3out_isr(void) __interrupt; -extern void ep4in_isr(void) __interrupt; -extern void ep4out_isr(void) __interrupt; -extern void ep5in_isr(void) __interrupt; -extern void ep5out_isr(void) __interrupt; -extern void ep6in_isr(void) __interrupt; -extern void ep6out_isr(void) __interrupt; -extern void ep7in_isr(void) __interrupt; -extern void ep7out_isr(void) __interrupt; - -void io_init(void) -{ - /* PORTxCFG register bits select alternate functions (1 == alternate function, - * 0 == standard I/O) - * OEx register bits turn on/off output buffer (1 == output, 0 == input) - * OUTx register bits determine pin state of output - * PINx register bits reflect pin state (high == 1, low == 0) */ - - /* PORT A */ - PORTACFG = PIN_OE; - OEA = PIN_U_OE | PIN_OE | PIN_RUN_LED | PIN_COM_LED; - OUTA = PIN_RUN_LED | PIN_COM_LED; - - /* PORT B */ - PORTBCFG = 0x00; - OEB = PIN_TDI | PIN_TMS | PIN_TCK | PIN_TRST | PIN_BRKIN | PIN_RESET - | PIN_OCDSE; - - /* TRST and RESET signals are low-active but inverted by hardware, so we clear - * these signals here! */ - OUTB = 0x00; - - /* PORT C */ - PORTCCFG = PIN_WR; - OEC = PIN_TXD0 | PIN_WR; - OUTC = 0x00; -} - -int main(void) -{ - io_init(); - usb_init(); - - /* Enable Interrupts */ - EA = 1; - - /* Begin executing command(s). This function never returns. */ - command_loop(); - - /* Never reached, but SDCC complains about missing return statement */ - return 0; -} diff --git a/src/jtag/drivers/OpenULINK/src/protocol.c b/src/jtag/drivers/OpenULINK/src/protocol.c deleted file mode 100644 index 901f52482..000000000 --- a/src/jtag/drivers/OpenULINK/src/protocol.c +++ /dev/null @@ -1,238 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2011 by Martin Schmoelzer * - * * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#include "protocol.h" -#include "jtag.h" -#include "delay.h" -#include "usb.h" -#include "io.h" -#include "msgtypes.h" - -#include "reg_ezusb.h" - -/** - * @file - * Implementation of the OpenULINK communication protocol. - * - * The OpenULINK protocol uses one OUT and one IN endpoint. These two endpoints - * are configured to use the maximum packet size for full-speed transfers, - * 64 bytes. Commands always start with a command ID (see msgtypes.h for - * command ID definitions) and contain zero or more payload data bytes in both - * transfer directions (IN and OUT). The payload - * - * Almost all commands contain a fixed number of payload data bytes. The number - * of payload data bytes for the IN and OUT direction does not need to be the - * same. - * - * Multiple commands may be sent in one EP2 Bulk-OUT packet. Because the - * OpenULINK firmware does not perform bounds checking for EP2 Bulk-IN packets, - * the host MUST ensure that the commands sent in the OUT packet require a - * maximum of 64 bytes of IN data. - */ - -/** Index in EP2 Bulk-OUT data buffer that contains the current command ID */ -volatile uint8_t cmd_id_index; - -/** Number of data bytes already in EP2 Bulk-IN buffer */ -volatile uint8_t payload_index_in; - -/** - * Execute a SET_LEDS command. - */ -void execute_set_led_command(void) -{ - uint8_t led_state = OUT2BUF[cmd_id_index + 1]; - - if (led_state & RUN_LED_ON) - SET_RUN_LED(); - - if (led_state & COM_LED_ON) - SET_COM_LED(); - - if (led_state & RUN_LED_OFF) - CLEAR_RUN_LED(); - - if (led_state & COM_LED_OFF) - CLEAR_COM_LED(); -} - -/** - * Executes one command and updates global command indexes. - * - * @return true if this command was the last command. - * @return false if there are more commands within the current contents of the - * Bulk EP2-OUT data buffer. - */ -bool execute_command(void) -{ - uint8_t usb_out_bytecount, usb_in_bytecount; - uint16_t signal_state; - uint16_t count; - - /* Most commands do not transfer IN data. To save code space, we write 0 to - * usb_in_bytecount here, then modify it in the switch statement below where - * neccessary */ - usb_in_bytecount = 0; - - switch (OUT2BUF[cmd_id_index] /* Command ID */) { - case CMD_SCAN_IN: - usb_out_bytecount = 5; - usb_in_bytecount = OUT2BUF[cmd_id_index + 1]; - jtag_scan_in(cmd_id_index + 1, payload_index_in); - break; - case CMD_SCAN_OUT: - usb_out_bytecount = OUT2BUF[cmd_id_index + 1] + 5; - jtag_scan_out(cmd_id_index + 1); - break; - case CMD_SCAN_IO: - usb_in_bytecount = OUT2BUF[cmd_id_index + 1]; - usb_out_bytecount = usb_in_bytecount + 5; - jtag_scan_io(cmd_id_index + 1, payload_index_in); - break; - case CMD_CLOCK_TMS: - usb_out_bytecount = 2; - jtag_clock_tms(OUT2BUF[cmd_id_index + 1], OUT2BUF[cmd_id_index + 2]); - break; - case CMD_CLOCK_TCK: - usb_out_bytecount = 2; - count = (uint16_t)OUT2BUF[cmd_id_index + 1]; - count |= ((uint16_t)OUT2BUF[cmd_id_index + 2]) << 8; - jtag_clock_tck(count); - break; - case CMD_SLOW_SCAN_IN: - usb_out_bytecount = 5; - usb_in_bytecount = OUT2BUF[cmd_id_index + 1]; - jtag_slow_scan_in(cmd_id_index + 1, payload_index_in); - break; - case CMD_SLOW_SCAN_OUT: - usb_out_bytecount = OUT2BUF[cmd_id_index + 1] + 5; - jtag_slow_scan_out(cmd_id_index + 1); - break; - case CMD_SLOW_SCAN_IO: - usb_in_bytecount = OUT2BUF[cmd_id_index + 1]; - usb_out_bytecount = usb_in_bytecount + 5; - jtag_slow_scan_io(cmd_id_index + 1, payload_index_in); - break; - case CMD_SLOW_CLOCK_TMS: - usb_out_bytecount = 2; - jtag_slow_clock_tms(OUT2BUF[cmd_id_index + 1], OUT2BUF[cmd_id_index + 2]); - break; - case CMD_SLOW_CLOCK_TCK: - usb_out_bytecount = 2; - count = (uint16_t)OUT2BUF[cmd_id_index + 1]; - count |= ((uint16_t)OUT2BUF[cmd_id_index + 2]) << 8; - jtag_slow_clock_tck(count); - break; - case CMD_SLEEP_US: - usb_out_bytecount = 2; - count = (uint16_t)OUT2BUF[cmd_id_index + 1]; - count |= ((uint16_t)OUT2BUF[cmd_id_index + 2]) << 8; - delay_us(count); - break; - case CMD_SLEEP_MS: - usb_out_bytecount = 2; - count = (uint16_t)OUT2BUF[cmd_id_index + 1]; - count |= ((uint16_t)OUT2BUF[cmd_id_index + 2]) << 8; - delay_ms(count); - break; - case CMD_GET_SIGNALS: - usb_out_bytecount = 0; - usb_in_bytecount = 2; - signal_state = jtag_get_signals(); - IN2BUF[payload_index_in] = (signal_state >> 8) & 0x00FF; - IN2BUF[payload_index_in + 1] = signal_state & 0x00FF; - break; - case CMD_SET_SIGNALS: - usb_out_bytecount = 2; - jtag_set_signals(OUT2BUF[cmd_id_index + 1], OUT2BUF[cmd_id_index + 2]); - break; - case CMD_CONFIGURE_TCK_FREQ: - usb_out_bytecount = 5; - jtag_configure_tck_delay( - OUT2BUF[cmd_id_index + 1], /* scan_in */ - OUT2BUF[cmd_id_index + 2], /* scan_out */ - OUT2BUF[cmd_id_index + 3], /* scan_io */ - OUT2BUF[cmd_id_index + 4], /* clock_tck */ - OUT2BUF[cmd_id_index + 5]); /* clock_tms */ - break; - case CMD_SET_LEDS: - usb_out_bytecount = 1; - execute_set_led_command(); - break; - case CMD_TEST: - usb_out_bytecount = 1; - /* Do nothing... This command is only used to test if the device is ready - * to accept new commands */ - break; - default: - /* Should never be reached */ - usb_out_bytecount = 0; - break; - } - - /* Update EP2 Bulk-IN data byte count */ - payload_index_in += usb_in_bytecount; - - /* Determine if this was the last command */ - if ((cmd_id_index + usb_out_bytecount + 1) >= OUT2BC) - return true; - else { - /* Not the last command, update cmd_id_index */ - cmd_id_index += (usb_out_bytecount + 1); - return false; - } -} - -/** - * Forever wait for commands and execute them as they arrive. - */ -void command_loop(void) -{ - bool last_command; - - while (1) { - cmd_id_index = 0; - payload_index_in = 0; - - /* Wait until host sends EP2 Bulk-OUT packet */ - while (!EP2_out) - ; - EP2_out = 0; - - /* Turn on COM LED to indicate command execution */ - SET_COM_LED(); - - /* Execute the commands */ - last_command = false; - while (last_command == false) - last_command = execute_command(); - - CLEAR_COM_LED(); - - /* Send back EP2 Bulk-IN packet if required */ - if (payload_index_in > 0) { - IN2BC = payload_index_in; - while (!EP2_in) - ; - EP2_in = 0; - } - - /* Re-arm EP2-OUT after command execution */ - OUT2BC = 0; - } -} diff --git a/src/jtag/drivers/OpenULINK/src/usb.c b/src/jtag/drivers/OpenULINK/src/usb.c deleted file mode 100644 index fb77f6482..000000000 --- a/src/jtag/drivers/OpenULINK/src/usb.c +++ /dev/null @@ -1,562 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2011-2013 by Martin Schmoelzer * - * * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -/** - * @file - * Defines USB descriptors, interrupt routines and helper functions. - * To minimize code size, we make the following assumptions: - * - The OpenULINK has exactly one configuration - * - and exactly one alternate setting - * - * Therefore, we do not have to support the Set Configuration USB request. - */ - -#include "usb.h" -#include "delay.h" -#include "io.h" - -/* Also update external declarations in "include/usb.h" if making changes to - * these variables! */ -volatile bool EP2_out; -volatile bool EP2_in; - -volatile __xdata __at 0x7FE8 struct setup_data setup_data; - -/* Define number of endpoints (except Control Endpoint 0) in a central place. - * Be sure to include the neccessary endpoint descriptors! */ -#define NUM_ENDPOINTS 2 - -__code struct usb_device_descriptor device_descriptor = { - .bLength = sizeof(struct usb_device_descriptor), - .bDescriptorType = DESCRIPTOR_TYPE_DEVICE, - .bcdUSB = 0x0110, /* BCD: 01.00 (Version 1.0 USB spec) */ - .bDeviceClass = 0xFF, /* 0xFF = vendor-specific */ - .bDeviceSubClass = 0xFF, - .bDeviceProtocol = 0xFF, - .bMaxPacketSize0 = 64, - .idVendor = 0xC251, - .idProduct = 0x2710, - .bcdDevice = 0x0100, - .iManufacturer = 1, - .iProduct = 2, - .iSerialNumber = 3, - .bNumConfigurations = 1 -}; - -/* WARNING: ALL config, interface and endpoint descriptors MUST be adjacent! */ - -__code struct usb_config_descriptor config_descriptor = { - .bLength = sizeof(struct usb_config_descriptor), - .bDescriptorType = DESCRIPTOR_TYPE_CONFIGURATION, - .wTotalLength = sizeof(struct usb_config_descriptor) + - sizeof(struct usb_interface_descriptor) + - (NUM_ENDPOINTS * sizeof(struct usb_endpoint_descriptor)), - .bNumInterfaces = 1, - .bConfigurationValue = 1, - .iConfiguration = 4, /* String describing this configuration */ - .bmAttributes = 0x80, /* Only MSB set according to USB spec */ - .MaxPower = 50 /* 100 mA */ -}; - -__code struct usb_interface_descriptor interface_descriptor00 = { - .bLength = sizeof(struct usb_interface_descriptor), - .bDescriptorType = DESCRIPTOR_TYPE_INTERFACE, - .bInterfaceNumber = 0, - .bAlternateSetting = 0, - .bNumEndpoints = NUM_ENDPOINTS, - .bInterfaceClass = 0xFF, - .bInterfaceSubclass = 0xFF, - .bInterfaceProtocol = 0xFF, - .iInterface = 0 -}; - -__code struct usb_endpoint_descriptor Bulk_EP2_IN_Endpoint_Descriptor = { - .bLength = sizeof(struct usb_endpoint_descriptor), - .bDescriptorType = 0x05, - .bEndpointAddress = (2 | USB_DIR_IN), - .bmAttributes = 0x02, - .wMaxPacketSize = 64, - .bInterval = 0 -}; - -__code struct usb_endpoint_descriptor Bulk_EP2_OUT_Endpoint_Descriptor = { - .bLength = sizeof(struct usb_endpoint_descriptor), - .bDescriptorType = 0x05, - .bEndpointAddress = (2 | USB_DIR_OUT), - .bmAttributes = 0x02, - .wMaxPacketSize = 64, - .bInterval = 0 -}; - -__code struct usb_language_descriptor language_descriptor = { - .bLength = 4, - .bDescriptorType = DESCRIPTOR_TYPE_STRING, - .wLANGID = {0x0409 /* US English */} -}; - -__code struct usb_string_descriptor strManufacturer = - STR_DESCR(9, 'O', 'p', 'e', 'n', 'U', 'L', 'I', 'N', 'K'); - -__code struct usb_string_descriptor strProduct = - STR_DESCR(9, 'O', 'p', 'e', 'n', 'U', 'L', 'I', 'N', 'K'); - -__code struct usb_string_descriptor strSerialNumber = - STR_DESCR(6, '0', '0', '0', '0', '0', '1'); - -__code struct usb_string_descriptor strConfigDescr = - STR_DESCR(12, 'J', 'T', 'A', 'G', ' ', 'A', 'd', 'a', 'p', 't', 'e', 'r'); - -/* Table containing pointers to string descriptors */ -__code struct usb_string_descriptor *__code en_string_descriptors[4] = { - &strManufacturer, - &strProduct, - &strSerialNumber, - &strConfigDescr -}; - -void sudav_isr(void) __interrupt SUDAV_ISR -{ - CLEAR_IRQ(); - - usb_handle_setup_data(); - - USBIRQ = SUDAVIR; - EP0CS |= HSNAK; -} - -void sof_isr(void) __interrupt SOF_ISR -{ -} -void sutok_isr(void) __interrupt SUTOK_ISR -{ -} -void suspend_isr(void) __interrupt SUSPEND_ISR -{ -} -void usbreset_isr(void) __interrupt USBRESET_ISR -{ -} -void ibn_isr(void) __interrupt IBN_ISR -{ -} - -void ep0in_isr(void) __interrupt EP0IN_ISR -{ -} -void ep0out_isr(void) __interrupt EP0OUT_ISR -{ -} -void ep1in_isr(void) __interrupt EP1IN_ISR -{ -} -void ep1out_isr(void) __interrupt EP1OUT_ISR -{ -} - -/** - * EP2 IN: called after the transfer from uC->Host has finished: we sent data - */ -void ep2in_isr(void) __interrupt EP2IN_ISR -{ - EP2_in = 1; - - CLEAR_IRQ(); - IN07IRQ = IN2IR;/* Clear OUT2 IRQ */ -} - -/** - * EP2 OUT: called after the transfer from Host->uC has finished: we got data - */ -void ep2out_isr(void) __interrupt EP2OUT_ISR -{ - EP2_out = 1; - - CLEAR_IRQ(); - OUT07IRQ = OUT2IR; /* Clear OUT2 IRQ */ -} - -void ep3in_isr(void) __interrupt EP3IN_ISR -{ -} -void ep3out_isr(void) __interrupt EP3OUT_ISR -{ -} -void ep4in_isr(void) __interrupt EP4IN_ISR -{ -} -void ep4out_isr(void) __interrupt EP4OUT_ISR -{ -} -void ep5in_isr(void) __interrupt EP5IN_ISR -{ -} -void ep5out_isr(void) __interrupt EP5OUT_ISR -{ -} -void ep6in_isr(void) __interrupt EP6IN_ISR -{ -} -void ep6out_isr(void) __interrupt EP6OUT_ISR -{ -} -void ep7in_isr(void) __interrupt EP7IN_ISR -{ -} -void ep7out_isr(void) __interrupt EP7OUT_ISR -{ -} - -/** - * Return the control/status register for an endpoint - * - * @param ep endpoint address - * @return on success: pointer to Control & Status register for endpoint - * specified in \a ep - * @return on failure: NULL - */ -__xdata uint8_t *usb_get_endpoint_cs_reg(uint8_t ep) -{ - /* Mask direction bit */ - uint8_t ep_num = ep & 0x7F; - - switch (ep_num) { - case 0: - return &EP0CS; - break; - case 1: - return ep & 0x80 ? &IN1CS : &OUT1CS; - break; - case 2: - return ep & 0x80 ? &IN2CS : &OUT2CS; - break; - case 3: - return ep & 0x80 ? &IN3CS : &OUT3CS; - break; - case 4: - return ep & 0x80 ? &IN4CS : &OUT4CS; - break; - case 5: - return ep & 0x80 ? &IN5CS : &OUT5CS; - break; - case 6: - return ep & 0x80 ? &IN6CS : &OUT6CS; - break; - case 7: - return ep & 0x80 ? &IN7CS : &OUT7CS; - break; - } - - return NULL; -} - -void usb_reset_data_toggle(uint8_t ep) -{ - /* TOGCTL register: - +----+-----+-----+------+-----+-------+-------+-------+ - | Q | S | R | IO | 0 | EP2 | EP1 | EP0 | - +----+-----+-----+------+-----+-------+-------+-------+ - - To reset data toggle bits, we have to write the endpoint direction (IN/OUT) - to the IO bit and the endpoint number to the EP2..EP0 bits. Then, in a - separate write cycle, the R bit needs to be set. - */ - uint8_t togctl_value = (ep & 0x80 >> 3) | (ep & 0x7); - - /* First step: Write EP number and direction bit */ - TOGCTL = togctl_value; - - /* Second step: Set R bit */ - togctl_value |= TOG_R; - TOGCTL = togctl_value; -} - -/** - * Handle GET_STATUS request. - * - * @return on success: true - * @return on failure: false - */ -bool usb_handle_get_status(void) -{ - uint8_t *ep_cs; - - switch (setup_data.bmRequestType) { - case GS_DEVICE: - /* Two byte response: Byte 0, Bit 0 = self-powered, Bit 1 = remote wakeup. - * Byte 1: reserved, reset to zero */ - IN0BUF[0] = 0; - IN0BUF[1] = 0; - - /* Send response */ - IN0BC = 2; - break; - case GS_INTERFACE: - /* Always return two zero bytes according to USB 1.1 spec, p. 191 */ - IN0BUF[0] = 0; - IN0BUF[1] = 0; - - /* Send response */ - IN0BC = 2; - break; - case GS_ENDPOINT: - /* Get stall bit for endpoint specified in low byte of wIndex */ - ep_cs = usb_get_endpoint_cs_reg(setup_data.wIndex & 0xff); - - if (*ep_cs & EPSTALL) - IN0BUF[0] = 0x01; - else - IN0BUF[0] = 0x00; - - /* Second byte sent has to be always zero */ - IN0BUF[1] = 0; - - /* Send response */ - IN0BC = 2; - break; - default: - return false; - break; - } - - return true; -} - -/** - * Handle CLEAR_FEATURE request. - * - * @return on success: true - * @return on failure: false - */ -bool usb_handle_clear_feature(void) -{ - __xdata uint8_t *ep_cs; - - switch (setup_data.bmRequestType) { - case CF_DEVICE: - /* Clear remote wakeup not supported: stall EP0 */ - STALL_EP0(); - break; - case CF_ENDPOINT: - if (setup_data.wValue == 0) { - /* Unstall the endpoint specified in wIndex */ - ep_cs = usb_get_endpoint_cs_reg(setup_data.wIndex); - if (!ep_cs) - return false; - *ep_cs &= ~EPSTALL; - } else { - /* Unsupported feature, stall EP0 */ - STALL_EP0(); - } - break; - default: - /* Vendor commands... */ - } - - return true; -} - -/** - * Handle SET_FEATURE request. - * - * @return on success: true - * @return on failure: false - */ -bool usb_handle_set_feature(void) -{ - __xdata uint8_t *ep_cs; - - switch (setup_data.bmRequestType) { - case SF_DEVICE: - if (setup_data.wValue == 2) - return true; - break; - case SF_ENDPOINT: - if (setup_data.wValue == 0) { - /* Stall the endpoint specified in wIndex */ - ep_cs = usb_get_endpoint_cs_reg(setup_data.wIndex); - if (!ep_cs) - return false; - *ep_cs |= EPSTALL; - } else { - /* Unsupported endpoint feature */ - return false; - } - break; - default: - /* Vendor commands... */ - break; - } - - return true; -} - -/** - * Handle GET_DESCRIPTOR request. - * - * @return on success: true - * @return on failure: false - */ -bool usb_handle_get_descriptor(void) -{ - __xdata uint8_t descriptor_type; - __xdata uint8_t descriptor_index; - - descriptor_type = (setup_data.wValue & 0xff00) >> 8; - descriptor_index = setup_data.wValue & 0x00ff; - - switch (descriptor_type) { - case DESCRIPTOR_TYPE_DEVICE: - SUDPTRH = HI8(&device_descriptor); - SUDPTRL = LO8(&device_descriptor); - break; - case DESCRIPTOR_TYPE_CONFIGURATION: - SUDPTRH = HI8(&config_descriptor); - SUDPTRL = LO8(&config_descriptor); - break; - case DESCRIPTOR_TYPE_STRING: - if (setup_data.wIndex == 0) { - /* Supply language descriptor */ - SUDPTRH = HI8(&language_descriptor); - SUDPTRL = LO8(&language_descriptor); - } else if (setup_data.wIndex == 0x0409 /* US English */) { - /* Supply string descriptor */ - SUDPTRH = HI8(en_string_descriptors[descriptor_index - 1]); - SUDPTRL = LO8(en_string_descriptors[descriptor_index - 1]); - } else - return false; - break; - default: - /* Unsupported descriptor type */ - return false; - break; - } - - return true; -} - -/** - * Handle SET_INTERFACE request. - */ -void usb_handle_set_interface(void) -{ - /* Reset Data Toggle */ - usb_reset_data_toggle(USB_DIR_IN | 2); - usb_reset_data_toggle(USB_DIR_OUT | 2); - - /* Unstall & clear busy flag of all valid IN endpoints */ - IN2CS = 0 | EPBSY; - - /* Unstall all valid OUT endpoints, reset bytecounts */ - OUT2CS = 0; - OUT2BC = 0; -} - -/** - * Handle the arrival of a USB Control Setup Packet. - */ -void usb_handle_setup_data(void) -{ - switch (setup_data.bRequest) { - case GET_STATUS: - if (!usb_handle_get_status()) - STALL_EP0(); - break; - case CLEAR_FEATURE: - if (!usb_handle_clear_feature()) - STALL_EP0(); - break; - case 2: case 4: - /* Reserved values */ - STALL_EP0(); - break; - case SET_FEATURE: - if (!usb_handle_set_feature()) - STALL_EP0(); - break; - case SET_ADDRESS: - /* Handled by USB core */ - break; - case SET_DESCRIPTOR: - /* Set Descriptor not supported. */ - STALL_EP0(); - break; - case GET_DESCRIPTOR: - if (!usb_handle_get_descriptor()) - STALL_EP0(); - break; - case GET_CONFIGURATION: - /* OpenULINK has only one configuration, return its index */ - IN0BUF[0] = config_descriptor.bConfigurationValue; - IN0BC = 1; - break; - case SET_CONFIGURATION: - /* OpenULINK has only one configuration -> nothing to do */ - break; - case GET_INTERFACE: - /* OpenULINK only has one interface, return its number */ - IN0BUF[0] = interface_descriptor00.bInterfaceNumber; - IN0BC = 1; - break; - case SET_INTERFACE: - usb_handle_set_interface(); - break; - case SYNCH_FRAME: - /* Isochronous endpoints not used -> nothing to do */ - break; - default: - /* Any other requests: do nothing */ - break; - } -} - -/** - * USB initialization. Configures USB interrupts, endpoints and performs - * ReNumeration. - */ -void usb_init(void) -{ - /* Mark endpoint 2 IN & OUT as valid */ - IN07VAL = IN2VAL; - OUT07VAL = OUT2VAL; - - /* Make sure no isochronous endpoints are marked valid */ - INISOVAL = 0; - OUTISOVAL = 0; - - /* Disable isochronous endpoints. This makes the isochronous data buffers - * available as 8051 XDATA memory at address 0x2000 - 0x27FF */ - ISOCTL = ISODISAB; - - /* Enable USB Autovectoring */ - USBBAV |= AVEN; - - /* Enable SUDAV interrupt */ - USBIEN |= SUDAVIE; - - /* Enable EP2 OUT & IN interrupts */ - OUT07IEN = OUT2IEN; - IN07IEN = IN2IEN; - - /* Enable USB interrupt (EIE register) */ - EUSB = 1; - - /* Perform ReNumeration */ - USBCS = DISCON | RENUM; - delay_ms(200); - USBCS = DISCOE | RENUM; -} diff --git a/src/jtag/drivers/OpenULINK/ulink_firmware.hex b/src/jtag/drivers/OpenULINK/ulink_firmware.hex deleted file mode 100644 index efaea58dd..000000000 --- a/src/jtag/drivers/OpenULINK/ulink_firmware.hex +++ /dev/null @@ -1,347 +0,0 @@ -:040000000200713257 -:01000B0032C2 -:0100130032BA -:01001B0032B2 -:0100230032AA -:01002B0032A2 -:01003300329A -:01003B003292 -:01004300328A -:01004B003282 -:01005300327A -:01005B003272 -:01006300326A -:03006B000201107F -:0300CA0002006EC3 -:03006E000201018B -:1000CD00907F937404F0907F9C7495F0907F96745C -:1000DD0090F0907F94E4F0907F9D747FF0907F97E7 -:1000ED00E4F0907F957440F0907F9E7442F0907F85 -:1000FD0098E4F0221200CD1204ADD2AF1208E090B8 -:10010D00000022C021C0E0C0F0C082C083C007C083 -:10011D0006C005C004C003C002C001C000C0D07538 -:10012D00D000AF9174EF5FF59112040C907FAB741A -:10013D0001F0907FB4E04402F0D0D0D000D001D0D7 -:10014D0002D003D004D005D006D007D083D082D002 -:10015D00F0D0E0D02132323232323232323232C04D -:10016D00E0C082C083C007C0D075D000D201AF916E -:10017D0074EF5FF591907FA97404F0D0D0D007D0C3 -:10018D0083D082D0E032C0E0C082C083C007C0D02F -:10019D0075D000D200AF9174EF5FF591907FAA7486 -:1001AD0004F0D0D0D007D083D082D0E032323232BA -:1001BD0032323232323232AF82747F5FFE24F850E7 -:1001CD0003020278EE240A83F582EE240C83F58374 -:1001DD00E473EFF306192C3F52650101020202028E -:1001ED000202907FB422EF30E7067DB67E7F800459 -:1001FD007DC67E7F8D828E8322EF30E7067DB87EB1 -:10020D007F80047DC87E7F8D828E8322EF30E7064E -:10021D007DBA7E7F80047DCA7E7F8D828E8322EFA4 -:10022D0030E7067DBC7E7F80047DCC7E7F8D828E07 -:10023D008322EF30E7067DBE7E7F80047DCE7E7FFC -:10024D008D828E8322EF30E7067DC07E7F80047D18 -:10025D00D07E7F8D828E8322EF30E7067EC27F7F38 -:10026D0080047ED27F7F8E828F832290000022AF0A -:10027D008274105FFE74075F4206907FD7EEF074B4 -:10028D00204EF022907FE8E0C322907FE8E0FF60EF -:10029D0005BF0246800A907FB4E0FF4401F0803A2A -:1002AD00907FEAE0FEA3E0FF4E7027907FECE0FE2A -:1002BD00A3E08E821201C4AE82AF83EE4F7002C3F3 -:1002CD00228E828F83E0FD5305FE8E828F83EDF0AB -:1002DD008008907FB4E0FF4401F0D322907FE8E0E6 -:1002ED00FF6005BF02468010907FEAE0FEA3E0FFAD -:1002FD00BE0239BF0036D322907FEAE0FEA3E0FFB5 -:10030D004E7027907FECE0FEA3E08E821201C4AE0A -:10031D0082AF83EE4F7002C3228E828F83E0FD4346 -:10032D0005018E828F83EDF08002C322D322907F50 -:10033D00EAE0A3E0FF907FEAE0FDA3E07E00BF01CD -:10034D0002800DBF02028021BF030280340203EC44 -:10035D007ED37F138F06907FD4EEF07ED37F137FF5 -:10036D0000907FD5EEF00203EE7EE57F138F0690B1 -:10037D007FD4EEF07EE57F137F00907FD5EEF08089 -:10038D0060907FECE0FEA3E0FF4E70187E057F14B9 -:10039D008F06907FD4EEF07E057F147F00907FD581 -:1003AD00EEF0803D907FECE0FEA3E0FFBE092EBF96 -:1003BD00042BED1475F002A42459F582741435F054 -:1003CD00F583E493FEA3E493FF8E048F058D0490D3 -:1003DD007FD4ECF07F00907FD5EEF08004C322C374 -:1003ED0022D32275828212027C75820212027C90C7 -:1003FD007FB87402F0907FC8E4F0907FC9F022902E -:10040D007FE9E0FF24F3500122EFF5F0240B83F593 -:10041D0082E5F0241183F583E473414F5D655D72D0 -:10042D007B73889899A9AC0404040404040404049F -:10043D0004040404120291500122907FB4E044019F -:10044D00F022120297500122907FB4E04401F02275 -:10045D00907FB4E04401F0221202E94042907FB453 -:10046D00E04401F02222907FB4E04401F022120317 -:10047D003B402C907FB4E04401F0229013EAE493CA -:10048D00907F00F0907FB57401F022229013F0E47C -:10049D0093907F00F0907FB57401F0221203F0224B -:1004AD00907FDE7404F0907FDF7404F0907FE0E4C1 -:1004BD00F0907FE1F0907FA17401F0907FAFE04468 -:1004CD0001F0907FAEE04401F0907FAD7404F090A8 -:1004DD007FAC7404F0D2E8907FD6740AF09000C817 -:0A04ED0012137C907FD67406F022F3 -:1013D30012011001FFFFFF4051C21027000101025B -:1013E3000301090220000101048032090400000204 -:1013F300FFFFFF00070582024000000705020240CD -:1014030000000403090414034F00700065006E001C -:1014130055004C0049004E004B0014034F00700070 -:1014230065006E0055004C0049004E004B000E0352 -:101433003000300030003000300031001A034A0021 -:101443005400410047002000410064006100700027 -:0E14530074006500720009141D1431143F145A -:1004F700E5080424C0F582E4347DF583E0FF30E1AC -:1005070008907F96E0FE54EFF08F06EE30E00890FB -:100517007F96E0FE547FF0EF30E308907F96E0FE91 -:100527004410F0EF30E208907F96E0FF4480F0221D -:100537007F00E50824C0F582E4347DF583E0FE24DE -:10054700D550030208A6EE240A83F582EE242F83F2 -:10055700F583E473B18AD7B0FAD3A6A6A6A6A6A652 -:10056700A6A6A6A6A6A6A6A6A6A6A6A6A6A6A6A624 -:10057700A6A6A6A621FA512A639CD5053493A205FF -:1005870006050605060808080808080808080808F0 -:1005970008080808080808080808080808080806D6 -:1005A700060607070707080808087E05E508042464 -:1005B700C0F582E4347DF583E0FFE50804F5828524 -:1005C7000927C007C00612091DD006D0070208A8D0 -:1005D700E5080424C0F582E4347DF583E02405FEB4 -:1005E700E50804F582C007C006120BDED006D00767 -:1005F7000208A8E5080424C0F582E4347DF583E009 -:10060700FF2405FEE50804F58285093CC007C006FE -:10061700120E79D006D0070208A87E02E508042446 -:10062700C0F582E4347DF583E0FD7402250824C01B -:10063700F582E4347DF583E0F50A8D82C007C006B4 -:1006470012124AD006D0070208A87E02E508042441 -:10065700C0F582E4347DF583E0FC7D007402250853 -:1006670024C0F582E4347DF583E0FAE44204EA42EB -:10067700058C828D83C007C0061211DDD006D00716 -:100687000208A87E05E5080424C0F582E4347DF558 -:1006970083E0FFE50804F58285092DC007C006122F -:1006A7000A67D006D0070208A8E5080424C0F58227 -:1006B700E4347DF583E02405FEE50804F582C007F0 -:1006C700C006120D14D006D0070208A8E5080424B6 -:1006D700C0F582E4347DF583E0FF2405FEE50804D8 -:1006E700F582850943C007C006121013D006D0074C -:1006F7000208A87E02E5080424C0F582E4347DF5EB -:1007070083E0FB7402250824C0F582E4347DF58379 -:10071700E0F50A8B82C007C006121281D006D00707 -:100727000208A87E02E5080424C0F582E4347DF5BA -:1007370083E0FC7D007402250824C0F582E4347D43 -:10074700F583E0FAE44204EA42058C828D83C00710 -:10075700C006121207D006D0070208A87E02E508D5 -:100767000424C0F582E4347DF583E0FC7D00740247 -:10077700250824C0F582E4347DF583E0FAE44204D9 -:10078700EA42058C828D83C007C006121349D00642 -:10079700D0070208A87E02E5080424C0F582E434E5 -:1007A7007DF583E0FC7D007402250824C0F582E412 -:1007B700347DF583E0FAE44204EA42058C828D83B6 -:1007C700C007C00612137CD006D0070208A87E0017 -:1007D7007F02C007C0061212CEAC82AD83D006D00E -:1007E7000785098275837E8D03EBF0E509042400F4 -:1007F700F582E4347EF5837D00ECF00208A87E02E2 -:10080700E5080424C0F582E4347DF583E0FD740235 -:10081700250824C0F582E4347DF583E0F50A8D824E -:10082700C007C006121311D006D00780747E05E5F5 -:10083700080424C0F582E4347DF583E0FD740225C5 -:100847000824C0F582E4347DF583E0F50A740325B6 -:100857000824C0F582E4347DF583E0F50B740425A4 -:100867000824C0F582E4347DF583E0F50C74052592 -:100877000824C0F582E4347DF583E0F50D8D82C050 -:1008870007C006121329D006D00780157E01C007BE -:10089700C0061204F7D006D00780067E0180027ECC -:1008A70000EF2509F509AD087F008E037C00EB2DCD -:1008B700FDEC3FFF0DBD00010F907FC9E0FC7B0001 -:1008C700C3ED9CEF64808BF063F08095F04002D31A -:1008D70022EE042508F508C32275080075090010E3 -:1008E700000280FB907F96E0FF547FF0C202200257 -:1008F70007120537920280F6907F96E0FF4480F05A -:10090700E509600B907FB9E509F010010280FB90C3 -:100917007FC9E4F080C3E582FF24C0F582E4347D1B -:10092700F583E0F528EF0424C0F582E4347DF583F0 -:10093700E0F52974022FFC24C0F582E4347DF583A9 -:10094700E0C4540FFB53030FEC24C0F582E4347D5D -:10095700F583E0FC740F5CF52A74032F24C0F5823D -:10096700E4347DF583E0FA74042F24C0F582E4347F -:100977007DF583E0F52BEB60078A0A8B8212124A1A -:10098700907F97E0FB5303F874044BFA7900A8288B -:100997007C0018B8FF011C89067F00C3EE98EF643E -:1009A700808CF063F08095F050347F007E00907F5C -:1009B70097EBF0EFC313FF907F97EAF0907F99E0F2 -:1009C700FC30E5034307800EBE080040E1E5272918 -:1009D7002400F582E4347EF583EFF00980B0892C9A -:1009E7007F00AC2A7A00C3EA95295040A8297900EC -:1009F70018B8FF01198A057E00EDB50011EEB501A3 -:100A07000DEC600A4303021CE52BC313F52B907F03 -:100A170097EBF0EFC313FF907F9774044BF0907F31 -:100A270099E0FE30E5034307800A80BAAD297E00CE -:100A37007408C39DFDE49EFE8DF005F0EF8002C3B0 -:100A470013D5F0FBFFE527252C2400F582E4347E3F -:100A5700F583EFF0EC6008852B0A8C8202124A229C -:100A6700E582FF24C0F582E4347DF583E0F52EEFBF -:100A77000424C0F582E4347DF583E0F52F74022F5A -:100A8700FC24C0F582E4347DF583E0C4540FFB53A6 -:100A9700030FEC24C0F582E4347DF583E0FC740F8A -:100AA7005CF53074032F24C0F582E4347DF583E0D0 -:100AB700FA74042F24C0F582E4347DF583E0F53120 -:100AC700EB60078A0A8B82121281907F97E0FB53B3 -:100AD70003F874044BFA753200A82E7C0018B8FF8F -:100AE700011CA9327E00C3E998EE64808CF063F0A4 -:100AF7008095F0504C7E007C00907F97EBF079005A -:100B0700C3E9952250030980F7EEC313FE907F9740 -:100B1700EAF07900C3E9952250030980F7907F999D -:100B2700E0F930E5034306800CBC080040CBE52D17 -:100B370025322400F582E4347EF583EEF005328019 -:100B4700987E00AA307900C3E9952F5056A82F7CCC -:100B57000018B8FF011C89057F00EDB50011EFB53E -:100B6700040DEA600A4303021AE531C313F5319015 -:100B77007F97EBF07F00C3EF952250030F80F7EECE -:100B8700C313FE907F9774044BF07F00C3EF952249 -:100B970050030F80F7907F99E0FF30E5034306800D -:100BA7000980A4AD2F7F007408C39DFDE49FFF8DCE -:100BB700F005F0EE8002C313D5F0FBFEE52D2532DC -:100BC7002400F582E4347EF583EEF0EA600885318F -:100BD7000A8A8202128122E582FF24C0F582E43468 -:100BE7007DF583E0F533EF0424C0F582E4347DF529 -:100BF70083E0F53474022FFC24C0F582E4347DF5DC -:100C070083E0C4540FFB53030FEC24C0F582E43494 -:100C17007DF583E0FC740F5CF53574032F24C0F574 -:100C270082E4347DF583E0FA74042F24C0F582E46E -:100C3700347DF583E0F536EB600B8A0A8B82C007BB -:100C470012124AD007907F97E0FB5303F97A00A866 -:100C5700337C0018B8FF011C8A017E00C3E998EEB7 -:100C670064808CF063F08095F05039EF2A240524D6 -:100C7700C0F582E4347DF583E0FE7C00EE30E005CC -:100C870043030180068B0174FE59FB907F97EBF0BD -:100C9700EEC313FE907F9774044BF00CBC08004022 -:100CA700DB0A80ABEF2A240524C0F582E4347DF506 -:100CB70083E0FEAF357C00C3EC95345044EE30E062 -:100CC7000543030180068B0274FE5AFBA9347A00A0 -:100CD70019B9FF011A8C007D00E8B50111EDB502C5 -:100CE7000DEF600A4303021FE536C313F536907F05 -:100CF70097EBF0EEC313FE907F9774044BF00C80D4 -:100D0700B6EF600885360A8F8202124A22E582F51D -:100D17003724C0F582E4347DF583E0F538E5370400 -:100D270024C0F582E4347DF583E0F5397402253774 -:100D3700FC24C0F582E4347DF583E0C4540FFB53F3 -:100D4700030FEC24C0F582E4347DF583E0FC740FD7 -:100D57005CF53A7403253724C0F582E4347DF583C6 -:100D6700E0FA7404253724C0F582E4347DF583E086 -:100D7700F53BEB60078A0A8B82121281907F97E01E -:100D8700FB5303F97A00A8387C0018B8FF011C8AC6 -:100D9700067F00C3EE98EF64808CF063F08095F0D7 -:100DA7005050E5372A240524C0F582E4347DF583C5 -:100DB700E0FF7E00EF30E00543030180068B0474FB -:100DC700FE5CFB907F97EBF07C00C3EC9523500310 -:100DD7000C80F7EFC313FF907F9774044BF07C00F0 -:100DE700C3EC952350030C80F70EBE080040C50ADC -:100DF7008094E5372A240524C0F582E4347DF58301 -:100E0700E0FFAE3A7C00C3EC9539505AEF30E0056D -:100E170043030180068B0274FE5AFBA8397A001837 -:100E2700B8FF011A8C017D00E9B50011EDB5020D7F -:100E3700EE600A4303021EE53BC313F53B907F9721 -:100E4700EBF07D00C3ED952350030D80F7EFC3133F -:100E5700FF907F9774044BF07D00C3ED95235003FB -:100E67000D80F70C80A0EE6008853B0A8E82021287 -:100E77008122E582FF24C0F582E4347DF583E0F525 -:100E87003DEF0424C0F582E4347DF583E0F53E743C -:100E9700022FFC24C0F582E4347DF583E0C4540FAF -:100EA700FB53030FEC24C0F582E4347DF583E0FCAB -:100EB700740F5CF53F74032F24C0F582E4347DF58D -:100EC70083E0FA74042F24C0F582E4347DF583E0CF -:100ED700F540EB600B8A0A8B82C00712124AD007D3 -:100EE700907F97E0FB5303F97A00A83D7C0018B880 -:100EF700FF011C8A017E00C3E998EE64808CF063D1 -:100F0700F08095F0505CEF2A240524C0F582E43484 -:100F17007DF583E0F5417C007900E54130E005434C -:100F2700030180068B0074FE58FB907F97EBF0E57A -:100F370041C313F541907F9774044BF0ECC313FC46 -:100F4700907F99E0F830E50343048009B908004031 -:100F5700C9E53C2A2400F582E4347EF583ECF00AE7 -:100F670080888A01EF2A240524C0F582E4347DF5C0 -:100F770083E0F5417C00AF3F754200C3E542953EF3 -:100F87005057E54130E00543030180068B0074FEAE -:100F970058FBA83E7D0018B8FF011DAA427E00EA53 -:100FA700B50011EEB5050DEF600A4303021FE540DA -:100FB700C313F540907F97EBF0E541C313F54190DC -:100FC7007F9774044BF0ECC313FC907F99E0FE30DD -:100FD700E503430480054280A2AD3E7E007408C34A -:100FE7009DFDE49EFE8DF005F0EC8002C313D5F065 -:100FF700FBFCE53C292400F582E4347EF583ECF024 -:10100700EF600885400A8F8202124A22E582F54482 -:1010170024C0F582E4347DF583E0F545E5440424F6 -:10102700C0F582E4347DF583E0F54674022544FC7F -:1010370024C0F582E4347DF583E0C4540FFB5303E9 -:101047000FEC24C0F582E4347DF583E0FC740F5C7B -:10105700F5477403254424C0F582E4347DF583E025 -:10106700FA7404254424C0F582E4347DF583E0F561 -:1010770048EB60078A0A8B82121281907F97E0FB08 -:101087005303F97A00A8457C0018B8FF011C8A06AB -:101097007F00C3EE98EF64808CF063F08095F0508A -:1010A70074E5442A240524C0F582E4347DF583E001 -:1010B700F5497E007C00E54930E0054303018006E1 -:1010C7008B0074FE58FB907F97EBF07800C3E89590 -:1010D7002450030880F7E549C313F549907F9774B7 -:1010E700044BF07800C3E8952450030880F7EEC35B -:1010F70013FE907F99E0F830E5034306800CBC08A7 -:101107000040B3E5432A2400F582E4347EF583EEFC -:10111700F00A02108C8A04E5442A240524C0F582CB -:10112700E4347DF583E0F5497E00AA47754A00C39C -:10113700E54A9546506DE54930E0054303018006D1 -:101147008B0174FE59FBA9467D0019B9FF011DA843 -:101157004A7F00E8B50111EFB5050DEA600A4303C0 -:10116700021AE548C313F548907F97EBF07F00C359 -:10117700EF952450030F80F7E549C313F549907F96 -:101187009774044BF07F00C3EF952450030F80F74B -:10119700EEC313FE907F99E0FF30E5034306800519 -:1011A7004A808CAD467F007408C39DFDE49FFF8D88 -:1011B700F005F0EE8002C313D5F0FBFEE5432C24C7 -:1011C70000F582E4347EF583EEF0EA600885480A8C -:1011D7008A8202128122AE82AF83907F97E0FD530D -:1011E70005FB74044DFC7A007B00C3EA9EEB9F501D -:1011F7000E907F97EDF0ECF00ABA00EE0B80EB2231 -:10120700AE82AF83907F97E0FD5305FB74044DFCDE -:101217007A007B00C3EA9EEB9F5027907F97EDF003 -:101227007900C3E9952550030980F7907F97ECF083 -:101237007900C3E9952550030980F70ABA00D50B51 -:1012470080D222AF82907F97E0FE5306FB7D00C3DA -:10125700ED9F5025E50A30E00543060280068E041F -:1012670074FD5CFE907F97EEF0E50AC313F50A90D4 -:101277007F9774044EF00D80D622AF82907F97E05F -:10128700FE5306FB7D00C3ED9F503BE50A30E005AA -:1012970043060280068E0474FD5CFE907F97EEF095 -:1012A7007C00C3EC952650030C80F7E50AC313F5C1 -:1012B7000A907F9774044EF07C00C3EC9526500388 -:1012C7000C80F70D80C0227F00907F99E0FE30E50B -:1012D700027F01907F99E0FE30E603430702907F8B -:1012E7009AE0FE30E703430704907F9BE0FE30E57A -:1012F70003430708907F9AE0FE53067F8F05E4FFBC -:10130700FCEE4FF582EC4DF58322E582547FF4FF26 -:10131700907F97E05FF0747F550AFF907F97E04FCB -:10132700F022858222850A23850B24850C25850DCD -:10133700262200227E567F021EBEFF011FEE4F703F -:10134700F722750A05750B001213A6AE82AF837CD0 -:10135700007D00C3EC9EED9F501AC007C006C00574 -:10136700C004121339D004D005D006D0070CBC0036 -:10137700E20D80DF22AE82AF837C007D00C3EC9E4E -:10138700ED9F501AC007C006C005C00412133BD01A -:0F13970004D005D006D0070CBC00E20D80DF2289 -:03004300021B009D -:101B0000020110000201630002016400020165008D -:101B1000020166000201670002016800020169001B -:101B200002016A0002016B0002016C0002019300D5 -:101B30000201BA000201BB000201BC000201BD00AB -:101B40000201BE000201BF000201C0000201C1008B -:081B50000201C2000201C30002 -:1013A6007A10E4FBFCE58225E0F582E58333F583DC -:1013B600EB33FBEC33FCEB950AF5F0EC950B4006B2 -:0913C600FCABF0438201DADD22E8 -:0600A000E478FFF6D8FD34 -:10007E007900E94400601B7A009014617800759253 -:10008E0020E493F2A308B800020592D9F4DAF275CF -:02009E0092FFCF -:1000A6007800E84400600A7900759220E4F309D8E4 -:1000B600FC7800E84400600C7900902000E4F0A38E -:0400C600D8FCD9FA8F -:0D00710075814A1213CFE582600302006E14 -:0413CF007582002201 -:00000001FF diff --git a/src/jtag/drivers/amt_jtagaccel.c b/src/jtag/drivers/amt_jtagaccel.c deleted file mode 100644 index 57c0ce600..000000000 --- a/src/jtag/drivers/amt_jtagaccel.c +++ /dev/null @@ -1,605 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include - -#if PARPORT_USE_PPDEV == 1 -#include -#include -#include -#else /* not PARPORT_USE_PPDEV */ -#ifndef _WIN32 -#include -#endif -#endif - -#if PARPORT_USE_GIVEIO == 1 -#if IS_CYGWIN == 1 -#include -#endif -#endif - -/** - * @file - * Support the Amontec Chameleon POD with JTAG Accelerator support. - * This is a parallel port JTAG adapter with a CPLD between the - * parallel port and the JTAG connection. VHDL code running in the - * CPLD significantly accelerates JTAG operations compared to the - * bitbanging "Wiggler" style of most parallel port adapters. - */ - -/* configuration */ -static uint16_t amt_jtagaccel_port; - -/* interface variables - */ -static uint8_t aw_control_rst; -static uint8_t aw_control_fsm = 0x10; -static uint8_t aw_control_baudrate = 0x20; - -static int rtck_enabled; - -#if PARPORT_USE_PPDEV == 1 -static int device_handle; - -static const int addr_mode = IEEE1284_MODE_EPP | IEEE1284_ADDR; - -/* FIXME do something sane when these ioctl/read/write calls fail. */ - -#define AMT_AW(val) \ - do { \ - int __retval; \ - \ - __retval = ioctl(device_handle, PPSETMODE, &addr_mode); \ - assert(__retval >= 0); \ - __retval = write(device_handle, &val, 1); \ - assert(__retval >= 0); \ - } while (0) -#define AMT_AR(val) \ - do { \ - int __retval; \ - \ - __retval = ioctl(device_handle, PPSETMODE, &addr_mode); \ - assert(__retval >= 0); \ - __retval = read(device_handle, &val, 1); \ - assert(__retval >= 0); \ - } while (0) - -static const int data_mode = IEEE1284_MODE_EPP | IEEE1284_DATA; - -#define AMT_DW(val) \ - do { \ - int __retval; \ - \ - __retval = ioctl(device_handle, PPSETMODE, &data_mode); \ - assert(__retval >= 0); \ - __retval = write(device_handle, &val, 1); \ - assert(__retval >= 0); \ - } while (0) -#define AMT_DR(val) \ - do { \ - int __retval; \ - \ - __retval = ioctl(device_handle, PPSETMODE, &data_mode); \ - assert(__retval >= 0); \ - __retval = read(device_handle, &val, 1); \ - assert(__retval >= 0); \ - } while (0) - -#else - -#define AMT_AW(val) do { outb(val, amt_jtagaccel_port + 3); } while (0) -#define AMT_AR(val) do { val = inb(amt_jtagaccel_port + 3); } while (0) -#define AMT_DW(val) do { outb(val, amt_jtagaccel_port + 4); } while (0) -#define AMT_DR(val) do { val = inb(amt_jtagaccel_port + 4); } while (0) - -#endif /* PARPORT_USE_PPDEV */ - -/* tap_move[i][j]: tap movement command to go from state i to state j - * 0: Test-Logic-Reset - * 1: Run-Test/Idle - * 2: Shift-DR - * 3: Pause-DR - * 4: Shift-IR - * 5: Pause-IR - */ -static const uint8_t amt_jtagaccel_tap_move[6][6][2] = { - /* RESET IDLE DRSHIFT DRPAUSE IRSHIFT IRPAUSE */ - { {0x1f, 0x00}, {0x0f, 0x00}, {0x05, 0x00}, {0x0a, 0x00}, {0x06, 0x00}, {0x96, 0x00} }, /* RESET */ - { {0x1f, 0x00}, {0x00, 0x00}, {0x04, 0x00}, {0x05, 0x00}, {0x06, 0x00}, {0x0b, 0x00} }, /* IDLE */ - { {0x1f, 0x00}, {0x0d, 0x00}, {0x00, 0x00}, {0x01, 0x00}, {0x8f, 0x09}, {0x8f, 0x01} }, /* DRSHIFT */ - { {0x1f, 0x00}, {0x0c, 0x00}, {0x08, 0x00}, {0x00, 0x00}, {0x8f, 0x09}, {0x8f, 0x01} }, /* DRPAUSE */ - { {0x1f, 0x00}, {0x0d, 0x00}, {0x07, 0x00}, {0x97, 0x00}, {0x00, 0x00}, {0x01, 0x00} }, /* IRSHIFT */ - { {0x1f, 0x00}, {0x0c, 0x00}, {0x07, 0x00}, {0x97, 0x00}, {0x08, 0x00}, {0x00, 0x00} }, /* IRPAUSE */ -}; - -static void amt_jtagaccel_reset(int trst, int srst) -{ - if (trst == 1) - aw_control_rst |= 0x4; - else if (trst == 0) - aw_control_rst &= ~0x4; - - if (srst == 1) - aw_control_rst |= 0x1; - else if (srst == 0) - aw_control_rst &= ~0x1; - - AMT_AW(aw_control_rst); -} - -static int amt_jtagaccel_speed(int speed) -{ - aw_control_baudrate &= 0xf0; - aw_control_baudrate |= speed & 0x0f; - AMT_AW(aw_control_baudrate); - - return ERROR_OK; -} - -static void amt_jtagaccel_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); - } -} - -static void amt_wait_scan_busy(void) -{ - int timeout = 4096; - uint8_t ar_status; - - AMT_AR(ar_status); - while (((ar_status) & 0x80) && (timeout-- > 0)) - AMT_AR(ar_status); - - if (ar_status & 0x80) { - LOG_ERROR( - "amt_jtagaccel timed out while waiting for end of scan, rtck was %s, last AR_STATUS: 0x%2.2x", - (rtck_enabled) ? "enabled" : "disabled", - ar_status); - exit(-1); - } -} - -static void amt_jtagaccel_state_move(void) -{ - uint8_t aw_scan_tms_5; - uint8_t tms_scan[2]; - - tap_state_t cur_state = tap_get_state(); - tap_state_t end_state = tap_get_end_state(); - - tms_scan[0] = amt_jtagaccel_tap_move[tap_move_ndx(cur_state)][tap_move_ndx(end_state)][0]; - tms_scan[1] = amt_jtagaccel_tap_move[tap_move_ndx(cur_state)][tap_move_ndx(end_state)][1]; - - aw_scan_tms_5 = 0x40 | (tms_scan[0] & 0x1f); - AMT_AW(aw_scan_tms_5); - int jtag_speed = 0; - int retval = jtag_get_speed(&jtag_speed); - assert(retval == ERROR_OK); - if (jtag_speed > 3 || rtck_enabled) - amt_wait_scan_busy(); - - if (tms_scan[0] & 0x80) { - aw_scan_tms_5 = 0x40 | (tms_scan[1] & 0x1f); - AMT_AW(aw_scan_tms_5); - if (jtag_speed > 3 || rtck_enabled) - amt_wait_scan_busy(); - } - - tap_set_state(end_state); -} - -static void amt_jtagaccel_runtest(int num_cycles) -{ - int i = 0; - uint8_t aw_scan_tms_5; - uint8_t aw_scan_tms_1to4; - - 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) { - amt_jtagaccel_end_state(TAP_IDLE); - amt_jtagaccel_state_move(); - } - - while (num_cycles - i >= 5) { - aw_scan_tms_5 = 0x40; - AMT_AW(aw_scan_tms_5); - i += 5; - } - - if (num_cycles - i > 0) { - aw_scan_tms_1to4 = 0x80 | ((num_cycles - i - 1) & 0x3) << 4; - AMT_AW(aw_scan_tms_1to4); - } - - amt_jtagaccel_end_state(saved_end_state); - if (tap_get_state() != tap_get_end_state()) - amt_jtagaccel_state_move(); -} - -static void amt_jtagaccel_scan(bool ir_scan, enum scan_type type, uint8_t *buffer, int scan_size) -{ - int bits_left = scan_size; - int bit_count = 0; - tap_state_t saved_end_state = tap_get_end_state(); - uint8_t aw_tdi_option; - uint8_t dw_tdi_scan; - uint8_t dr_tdo; - uint8_t aw_tms_scan; - uint8_t tms_scan[2]; - int jtag_speed_var; - int retval = jtag_get_speed(&jtag_speed_var); - assert(retval == ERROR_OK); - - if (ir_scan) - amt_jtagaccel_end_state(TAP_IRSHIFT); - else - amt_jtagaccel_end_state(TAP_DRSHIFT); - - /* Only move if we're not already there */ - if (tap_get_state() != tap_get_end_state()) - amt_jtagaccel_state_move(); - - amt_jtagaccel_end_state(saved_end_state); - - /* handle unaligned bits at the beginning */ - if ((scan_size - 1) % 8) { - aw_tdi_option = 0x30 | (((scan_size - 1) % 8) - 1); - AMT_AW(aw_tdi_option); - - dw_tdi_scan = buf_get_u32(buffer, bit_count, (scan_size - 1) % 8) & 0xff; - AMT_DW(dw_tdi_scan); - if (jtag_speed_var > 3 || rtck_enabled) - amt_wait_scan_busy(); - - if ((type == SCAN_IN) || (type == SCAN_IO)) { - AMT_DR(dr_tdo); - dr_tdo = dr_tdo >> (8 - ((scan_size - 1) % 8)); - buf_set_u32(buffer, bit_count, (scan_size - 1) % 8, dr_tdo); - } - - bit_count += (scan_size - 1) % 8; - bits_left -= (scan_size - 1) % 8; - } - - while (bits_left - 1 >= 8) { - dw_tdi_scan = buf_get_u32(buffer, bit_count, 8) & 0xff; - AMT_DW(dw_tdi_scan); - if (jtag_speed_var > 3 || rtck_enabled) - amt_wait_scan_busy(); - - if ((type == SCAN_IN) || (type == SCAN_IO)) { - AMT_DR(dr_tdo); - buf_set_u32(buffer, bit_count, 8, dr_tdo); - } - - bit_count += 8; - bits_left -= 8; - } - - tms_scan[0] = - amt_jtagaccel_tap_move[tap_move_ndx(tap_get_state())][tap_move_ndx(tap_get_end_state())][0]; - tms_scan[1] = - amt_jtagaccel_tap_move[tap_move_ndx(tap_get_state())][tap_move_ndx(tap_get_end_state())][1]; - aw_tms_scan = 0x40 | (tms_scan[0] & 0x1f) | (buf_get_u32(buffer, bit_count, 1) << 5); - AMT_AW(aw_tms_scan); - if (jtag_speed_var > 3 || rtck_enabled) - amt_wait_scan_busy(); - - if ((type == SCAN_IN) || (type == SCAN_IO)) { - AMT_DR(dr_tdo); - dr_tdo = dr_tdo >> 7; - buf_set_u32(buffer, bit_count, 1, dr_tdo); - } - - if (tms_scan[0] & 0x80) { - aw_tms_scan = 0x40 | (tms_scan[1] & 0x1f); - AMT_AW(aw_tms_scan); - if (jtag_speed_var > 3 || rtck_enabled) - amt_wait_scan_busy(); - } - tap_set_state(tap_get_end_state()); -} - -static int amt_jtagaccel_execute_queue(void) -{ - struct jtag_command *cmd = jtag_command_queue; /* currently processed command */ - int scan_size; - enum scan_type type; - uint8_t *buffer; - int retval; - - /* return ERROR_OK, unless a jtag_read_buffer returns a failed check - * that wasn't handled by a caller-provided error handler - */ - retval = ERROR_OK; - - while (cmd) { - switch (cmd->type) { - case JTAG_RESET: -#ifdef _DEBUG_JTAG_IO_ - LOG_DEBUG("reset trst: %i srst %i", - cmd->cmd.reset->trst, - cmd->cmd.reset->srst); -#endif - if (cmd->cmd.reset->trst == 1) - tap_set_state(TAP_RESET); - amt_jtagaccel_reset(cmd->cmd.reset->trst, cmd->cmd.reset->srst); - break; - case JTAG_RUNTEST: -#ifdef _DEBUG_JTAG_IO_ - LOG_DEBUG("runtest %i cycles, end in %i", - cmd->cmd.runtest->num_cycles, - cmd->cmd.runtest->end_state); -#endif - amt_jtagaccel_end_state(cmd->cmd.runtest->end_state); - amt_jtagaccel_runtest(cmd->cmd.runtest->num_cycles); - break; - case JTAG_TLR_RESET: -#ifdef _DEBUG_JTAG_IO_ - LOG_DEBUG("statemove end in %i", cmd->cmd.statemove->end_state); -#endif - amt_jtagaccel_end_state(cmd->cmd.statemove->end_state); - amt_jtagaccel_state_move(); - break; - case JTAG_SCAN: -#ifdef _DEBUG_JTAG_IO_ - LOG_DEBUG("scan end in %i", cmd->cmd.scan->end_state); -#endif - amt_jtagaccel_end_state(cmd->cmd.scan->end_state); - scan_size = jtag_build_buffer(cmd->cmd.scan, &buffer); - type = jtag_scan_type(cmd->cmd.scan); - amt_jtagaccel_scan(cmd->cmd.scan->ir_scan, type, buffer, scan_size); - if (jtag_read_buffer(buffer, cmd->cmd.scan) != ERROR_OK) - retval = ERROR_JTAG_QUEUE_FAILED; - if (buffer) - free(buffer); - break; - case JTAG_SLEEP: -#ifdef _DEBUG_JTAG_IO_ - LOG_DEBUG("sleep %" PRIi32, cmd->cmd.sleep->us); -#endif - jtag_sleep(cmd->cmd.sleep->us); - break; - default: - LOG_ERROR("BUG: unknown JTAG command type encountered"); - exit(-1); - } - cmd = cmd->next; - } - - return retval; -} - -#if PARPORT_USE_GIVEIO == 1 -int amt_jtagaccel_get_giveio_access(void) -{ - HANDLE h; - OSVERSIONINFO version; - - version.dwOSVersionInfoSize = sizeof version; - if (!GetVersionEx(&version)) { - errno = EINVAL; - return -1; - } - if (version.dwPlatformId != VER_PLATFORM_WIN32_NT) - return 0; - - h = CreateFile("\\\\.\\giveio", - GENERIC_READ, - 0, - NULL, - OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL, - NULL); - if (h == INVALID_HANDLE_VALUE) { - errno = ENODEV; - return -1; - } - - CloseHandle(h); - - return 0; -} -#endif - -static int amt_jtagaccel_init(void) -{ -#if PARPORT_USE_PPDEV == 1 - char buffer[256]; - int i = 0; - uint8_t control_port; -#else - uint8_t status_port; -#endif - uint8_t ar_status; - -#if PARPORT_USE_PPDEV == 1 - if (device_handle > 0) { - LOG_ERROR("device is already opened"); - return ERROR_JTAG_INIT_FAILED; - } - - snprintf(buffer, 256, "/dev/parport%d", amt_jtagaccel_port); - device_handle = open(buffer, O_RDWR); - - if (device_handle < 0) { - LOG_ERROR( - "cannot open device. check it exists and that user read and write rights are set"); - return ERROR_JTAG_INIT_FAILED; - } - - i = ioctl(device_handle, PPCLAIM); - if (i < 0) { - LOG_ERROR("cannot claim device"); - return ERROR_JTAG_INIT_FAILED; - } - - i = IEEE1284_MODE_EPP; - i = ioctl(device_handle, PPSETMODE, &i); - if (i < 0) { - LOG_ERROR(" cannot set compatible mode to device"); - return ERROR_JTAG_INIT_FAILED; - } - - control_port = 0x00; - i = ioctl(device_handle, PPWCONTROL, &control_port); - - control_port = 0x04; - i = ioctl(device_handle, PPWCONTROL, &control_port); - -#else - if (amt_jtagaccel_port == 0) { - amt_jtagaccel_port = 0x378; - LOG_WARNING("No parport port specified, using default '0x378' (LPT1)"); - } - -#if PARPORT_USE_GIVEIO == 1 - if (amt_jtagaccel_get_giveio_access() != 0) { -#else /* PARPORT_USE_GIVEIO */ - if (ioperm(amt_jtagaccel_port, 5, 1) != 0) { -#endif /* PARPORT_USE_GIVEIO */ - LOG_ERROR("missing privileges for direct i/o"); - return ERROR_JTAG_INIT_FAILED; - } - - /* prepare epp port - * clear timeout */ - status_port = inb(amt_jtagaccel_port + 1); - outb(status_port | 0x1, amt_jtagaccel_port + 1); - - /* reset epp port */ - outb(0x00, amt_jtagaccel_port + 2); - outb(0x04, amt_jtagaccel_port + 2); -#endif - - if (rtck_enabled) { - /* set RTCK enable bit */ - aw_control_fsm |= 0x02; - } - - /* enable JTAG port */ - aw_control_fsm |= 0x04; - AMT_AW(aw_control_fsm); - - enum reset_types jtag_reset_config = jtag_get_reset_config(); - if (jtag_reset_config & RESET_TRST_OPEN_DRAIN) - aw_control_rst &= ~0x8; - else - aw_control_rst |= 0x8; - - if (jtag_reset_config & RESET_SRST_PUSH_PULL) - aw_control_rst &= ~0x2; - else - aw_control_rst |= 0x2; - - amt_jtagaccel_reset(0, 0); - - /* read status register */ - AMT_AR(ar_status); - LOG_DEBUG("AR_STATUS: 0x%2.2x", ar_status); - - return ERROR_OK; -} - -static int amt_jtagaccel_quit(void) -{ - - return ERROR_OK; -} - -COMMAND_HANDLER(amt_jtagaccel_handle_parport_port_command) -{ - if (CMD_ARGC == 1) { - /* only if the port wasn't overwritten by cmdline */ - if (amt_jtagaccel_port == 0) { - uint16_t port; - COMMAND_PARSE_NUMBER(u16, CMD_ARGV[0], port); - amt_jtagaccel_port = port; - } else { - LOG_ERROR("The parport port was already configured!"); - return ERROR_FAIL; - } - } - - command_print(CMD_CTX, "parport port = %u", amt_jtagaccel_port); - - return ERROR_OK; -} - -COMMAND_HANDLER(amt_jtagaccel_handle_rtck_command) -{ - if (CMD_ARGC == 0) { - command_print(CMD_CTX, - "amt_jtagaccel RTCK feature %s", - (rtck_enabled) ? "enabled" : "disabled"); - return ERROR_OK; - } else { - if (strcmp(CMD_ARGV[0], "enabled") == 0) - rtck_enabled = 1; - else - rtck_enabled = 0; - } - - return ERROR_OK; -} - -static const struct command_registration amtjtagaccel_command_handlers[] = { - { - .name = "parport_port", - .handler = &amt_jtagaccel_handle_parport_port_command, - .mode = COMMAND_CONFIG, - .help = "configure or display the parallel port to use", - .usage = "[port_num]", - }, - { - /** - * @todo Remove this "rtck" command; just use the standard - * mechanism to enable/disable adaptive clocking. First - * implement the standard mechanism and deprecate "rtck"; - * after a year or so, it'll be safe to remove this. - */ - .name = "rtck", - .handler = &amt_jtagaccel_handle_rtck_command, - .mode = COMMAND_CONFIG, - .help = "configure or display RTCK support", - .usage = "[enable|disable]", - }, - COMMAND_REGISTRATION_DONE -}; - -struct jtag_interface amt_jtagaccel_interface = { - .name = "amt_jtagaccel", - .commands = amtjtagaccel_command_handlers, - - .init = amt_jtagaccel_init, - .quit = amt_jtagaccel_quit, - .speed = amt_jtagaccel_speed, - .execute_queue = amt_jtagaccel_execute_queue, -}; diff --git a/src/jtag/drivers/arm-jtag-ew.c b/src/jtag/drivers/arm-jtag-ew.c deleted file mode 100644 index d9ea367ce..000000000 --- a/src/jtag/drivers/arm-jtag-ew.c +++ /dev/null @@ -1,793 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2009 by Dimitar Dimitrov * - * based on Dominic Rath's and Benedikt Sauter's usbprog.c * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include -#include "usb_common.h" - -#define USB_VID 0x15ba -#define USB_PID 0x001e - -#define ARMJTAGEW_EPT_BULK_OUT 0x01u -#define ARMJTAGEW_EPT_BULK_IN 0x82u - -#define ARMJTAGEW_USB_TIMEOUT 2000 - -#define ARMJTAGEW_IN_BUFFER_SIZE (4*1024) -#define ARMJTAGEW_OUT_BUFFER_SIZE (4*1024) - -/* USB command request codes. */ -#define CMD_GET_VERSION 0x00 -#define CMD_SELECT_DPIMPL 0x10 -#define CMD_SET_TCK_FREQUENCY 0x11 -#define CMD_GET_TCK_FREQUENCY 0x12 -#define CMD_MEASURE_MAX_TCK_FREQ 0x15 -#define CMD_MEASURE_RTCK_RESPONSE 0x16 -#define CMD_TAP_SHIFT 0x17 -#define CMD_SET_TAPHW_STATE 0x20 -#define CMD_GET_TAPHW_STATE 0x21 -#define CMD_TGPWR_SETUP 0x22 - -/* Global USB buffers */ -static uint8_t usb_in_buffer[ARMJTAGEW_IN_BUFFER_SIZE]; -static uint8_t usb_out_buffer[ARMJTAGEW_OUT_BUFFER_SIZE]; - -/* Queue command functions */ -static void armjtagew_end_state(tap_state_t state); -static void armjtagew_state_move(void); -static void armjtagew_path_move(int num_states, tap_state_t *path); -static void armjtagew_runtest(int num_cycles); -static void armjtagew_scan(bool ir_scan, - enum scan_type type, - uint8_t *buffer, - int scan_size, - struct scan_command *command); -static void armjtagew_reset(int trst, int srst); -/* static void armjtagew_simple_command(uint8_t command); */ -static int armjtagew_get_status(void); - -/* tap buffer functions */ -static void armjtagew_tap_init(void); -static int armjtagew_tap_execute(void); -static void armjtagew_tap_ensure_space(int scans, int bits); -static void armjtagew_tap_append_step(int tms, int tdi); -static void armjtagew_tap_append_scan(int length, uint8_t *buffer, struct scan_command *command); - -/* ARM-JTAG-EW lowlevel functions */ -struct armjtagew { - struct usb_dev_handle *usb_handle; -}; - -static struct armjtagew *armjtagew_usb_open(void); -static void armjtagew_usb_close(struct armjtagew *armjtagew); -static int armjtagew_usb_message(struct armjtagew *armjtagew, int out_length, int in_length); -static int armjtagew_usb_write(struct armjtagew *armjtagew, int out_length); -static int armjtagew_usb_read(struct armjtagew *armjtagew, int exp_in_length); - -/* helper functions */ -static int armjtagew_get_version_info(void); - -#ifdef _DEBUG_USB_COMMS_ -static void armjtagew_debug_buffer(uint8_t *buffer, int length); -#endif - -static struct armjtagew *armjtagew_handle; - -/************************************************************************** - * External interface implementation */ - -static int armjtagew_execute_queue(void) -{ - struct jtag_command *cmd = jtag_command_queue; - int scan_size; - enum scan_type type; - uint8_t *buffer; - - while (cmd != NULL) { - switch (cmd->type) { - case JTAG_RUNTEST: - DEBUG_JTAG_IO("runtest %i cycles, end in %i", - cmd->cmd.runtest->num_cycles, \ - cmd->cmd.runtest->end_state); - - armjtagew_end_state(cmd->cmd.runtest->end_state); - armjtagew_runtest(cmd->cmd.runtest->num_cycles); - break; - - case JTAG_TLR_RESET: - DEBUG_JTAG_IO("statemove end in %i", cmd->cmd.statemove->end_state); - - armjtagew_end_state(cmd->cmd.statemove->end_state); - armjtagew_state_move(); - break; - - case JTAG_PATHMOVE: - DEBUG_JTAG_IO("pathmove: %i states, end in %i", \ - cmd->cmd.pathmove->num_states, \ - cmd->cmd.pathmove->path[cmd->cmd.pathmove->num_states - 1]); - - armjtagew_path_move(cmd->cmd.pathmove->num_states, - cmd->cmd.pathmove->path); - break; - - case JTAG_SCAN: - DEBUG_JTAG_IO("scan end in %i", cmd->cmd.scan->end_state); - - armjtagew_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); - -#ifdef _DEBUG_USB_COMMS_ - armjtagew_debug_buffer(buffer, (scan_size + 7) / 8); -#endif - type = jtag_scan_type(cmd->cmd.scan); - armjtagew_scan(cmd->cmd.scan->ir_scan, - type, buffer, - scan_size, cmd->cmd.scan); - break; - - case JTAG_RESET: - DEBUG_JTAG_IO("reset trst: %i srst %i", - cmd->cmd.reset->trst, - cmd->cmd.reset->srst); - - armjtagew_tap_execute(); - - if (cmd->cmd.reset->trst == 1) - tap_set_state(TAP_RESET); - armjtagew_reset(cmd->cmd.reset->trst, cmd->cmd.reset->srst); - break; - - case JTAG_SLEEP: - DEBUG_JTAG_IO("sleep %i", cmd->cmd.sleep->us); - armjtagew_tap_execute(); - jtag_sleep(cmd->cmd.sleep->us); - break; - - default: - LOG_ERROR("BUG: unknown JTAG command type encountered"); - exit(-1); - } - cmd = cmd->next; - } - - return armjtagew_tap_execute(); -} - -/* Sets speed in kHz. */ -static int armjtagew_speed(int speed) -{ - int result; - int speed_real; - - - usb_out_buffer[0] = CMD_SET_TCK_FREQUENCY; - buf_set_u32(usb_out_buffer + 1, 0, 32, speed*1000); - - result = armjtagew_usb_message(armjtagew_handle, 5, 4); - - if (result < 0) { - LOG_ERROR("ARM-JTAG-EW setting speed failed (%d)", result); - return ERROR_JTAG_DEVICE_ERROR; - } - - usb_out_buffer[0] = CMD_GET_TCK_FREQUENCY; - result = armjtagew_usb_message(armjtagew_handle, 1, 4); - speed_real = (int)buf_get_u32(usb_in_buffer, 0, 32) / 1000; - if (result < 0) { - LOG_ERROR("ARM-JTAG-EW getting speed failed (%d)", result); - return ERROR_JTAG_DEVICE_ERROR; - } else - LOG_INFO("Requested speed %dkHz, emulator reported %dkHz.", speed, speed_real); - - return ERROR_OK; -} - -static int armjtagew_khz(int khz, int *jtag_speed) -{ - *jtag_speed = khz; - - return ERROR_OK; -} - -static int armjtagew_speed_div(int speed, int *khz) -{ - *khz = speed; - - return ERROR_OK; -} - -static int armjtagew_init(void) -{ - int check_cnt; - - armjtagew_handle = armjtagew_usb_open(); - - if (armjtagew_handle == 0) { - LOG_ERROR( - "Cannot find ARM-JTAG-EW Interface! Please check connection and permissions."); - return ERROR_JTAG_INIT_FAILED; - } - - check_cnt = 0; - while (check_cnt < 3) { - if (armjtagew_get_version_info() == ERROR_OK) { - /* attempt to get status */ - armjtagew_get_status(); - break; - } - - check_cnt++; - } - - if (check_cnt == 3) - LOG_INFO("ARM-JTAG-EW initial read failed, don't worry"); - - /* Initial JTAG speed (for reset and initialization): 32 kHz */ - armjtagew_speed(32); - - LOG_INFO("ARM-JTAG-EW JTAG Interface ready"); - - armjtagew_reset(0, 0); - armjtagew_tap_init(); - - return ERROR_OK; -} - -static int armjtagew_quit(void) -{ - armjtagew_usb_close(armjtagew_handle); - return ERROR_OK; -} - -/************************************************************************** - * Queue command implementations */ - -static void armjtagew_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); - } -} - -/* Goes to the end state. */ -static void armjtagew_state_move(void) -{ - int i; - int tms = 0; - uint8_t tms_scan = tap_get_tms_path(tap_get_state(), tap_get_end_state()); - int tms_count = tap_get_tms_path_len(tap_get_state(), tap_get_end_state()); - - for (i = 0; i < tms_count; i++) { - tms = (tms_scan >> i) & 1; - armjtagew_tap_append_step(tms, 0); - } - - tap_set_state(tap_get_end_state()); -} - -static void armjtagew_path_move(int num_states, tap_state_t *path) -{ - int i; - - for (i = 0; i < num_states; i++) { - /* - * TODO: The ARM-JTAG-EW hardware delays TDI with 3 TCK cycles when in RTCK mode. - * Either handle that here, or update the documentation with examples - * how to fix that in the configuration files. - */ - if (path[i] == tap_state_transition(tap_get_state(), false)) - armjtagew_tap_append_step(0, 0); - else if (path[i] == tap_state_transition(tap_get_state(), true)) - armjtagew_tap_append_step(1, 0); - 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]); - } - - tap_set_end_state(tap_get_state()); -} - -static void armjtagew_runtest(int num_cycles) -{ - int i; - - 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) { - armjtagew_end_state(TAP_IDLE); - armjtagew_state_move(); - } - - /* execute num_cycles */ - for (i = 0; i < num_cycles; i++) - armjtagew_tap_append_step(0, 0); - - /* finish in end_state */ - armjtagew_end_state(saved_end_state); - if (tap_get_state() != tap_get_end_state()) - armjtagew_state_move(); -} - -static void armjtagew_scan(bool ir_scan, - enum scan_type type, - uint8_t *buffer, - int scan_size, - struct scan_command *command) -{ - tap_state_t saved_end_state; - - armjtagew_tap_ensure_space(1, scan_size + 8); - - saved_end_state = tap_get_end_state(); - - /* Move to appropriate scan state */ - armjtagew_end_state(ir_scan ? TAP_IRSHIFT : TAP_DRSHIFT); - - /* Only move if we're not already there */ - if (tap_get_state() != tap_get_end_state()) - armjtagew_state_move(); - - armjtagew_end_state(saved_end_state); - - /* Scan */ - armjtagew_tap_append_scan(scan_size, buffer, command); - - /* We are in Exit1, go to Pause */ - armjtagew_tap_append_step(0, 0); - - tap_set_state(ir_scan ? TAP_IRPAUSE : TAP_DRPAUSE); - - if (tap_get_state() != tap_get_end_state()) - armjtagew_state_move(); -} - -static void armjtagew_reset(int trst, int srst) -{ - const uint8_t trst_mask = (1u << 5); - const uint8_t srst_mask = (1u << 6); - uint8_t val = 0; - uint8_t outp_en = 0; - uint8_t change_mask = 0; - int result; - - LOG_DEBUG("trst: %i, srst: %i", trst, srst); - - if (srst == 0) { - val |= srst_mask; - outp_en &= ~srst_mask; /* tristate */ - change_mask |= srst_mask; - } else if (srst == 1) { - val &= ~srst_mask; - outp_en |= srst_mask; - change_mask |= srst_mask; - } - - if (trst == 0) { - val |= trst_mask; - outp_en &= ~trst_mask; /* tristate */ - change_mask |= trst_mask; - } else if (trst == 1) { - val &= ~trst_mask; - outp_en |= trst_mask; - change_mask |= trst_mask; - } - - usb_out_buffer[0] = CMD_SET_TAPHW_STATE; - usb_out_buffer[1] = val; - usb_out_buffer[2] = outp_en; - usb_out_buffer[3] = change_mask; - result = armjtagew_usb_write(armjtagew_handle, 4); - if (result != 4) - LOG_ERROR("ARM-JTAG-EW TRST/SRST pin set failed failed (%d)", result); -} - -static int armjtagew_get_status(void) -{ - int result; - - usb_out_buffer[0] = CMD_GET_TAPHW_STATE; - result = armjtagew_usb_message(armjtagew_handle, 1, 12); - - if (result == 0) { - unsigned int u_tg = buf_get_u32(usb_in_buffer, 0, 16); - LOG_INFO( - "U_tg = %d mV, U_aux = %d mV, U_tgpwr = %d mV, I_tgpwr = %d mA, D1 = %d, Target power %s %s", - (int)(buf_get_u32(usb_in_buffer + 0, 0, 16)), - (int)(buf_get_u32(usb_in_buffer + 2, 0, 16)), - (int)(buf_get_u32(usb_in_buffer + 4, 0, 16)), - (int)(buf_get_u32(usb_in_buffer + 6, 0, 16)), - usb_in_buffer[9], - usb_in_buffer[11] ? "OVERCURRENT" : "OK", - usb_in_buffer[10] ? "enabled" : "disabled"); - - if (u_tg < 1500) - LOG_ERROR("Vref too low. Check Target Power"); - } else - LOG_ERROR("ARM-JTAG-EW command CMD_GET_TAPHW_STATE failed (%d)", result); - - return ERROR_OK; -} - -static int armjtagew_get_version_info(void) -{ - int result; - char sn[16]; - char auxinfo[257]; - - /* query hardware version */ - usb_out_buffer[0] = CMD_GET_VERSION; - result = armjtagew_usb_message(armjtagew_handle, 1, 4 + 15 + 256); - - if (result != 0) { - LOG_ERROR("ARM-JTAG-EW command CMD_GET_VERSION failed (%d)", result); - return ERROR_JTAG_DEVICE_ERROR; - } - - memcpy(sn, usb_in_buffer + 4, 15); - sn[15] = '\0'; - memcpy(auxinfo, usb_in_buffer + 4+15, 256); - auxinfo[256] = '\0'; - - LOG_INFO( - "ARM-JTAG-EW firmware version %d.%d, hardware revision %c, SN=%s, Additional info: %s", \ - usb_in_buffer[1], - usb_in_buffer[0], \ - isgraph(usb_in_buffer[2]) ? usb_in_buffer[2] : 'X', \ - sn, - auxinfo); - - if (1 != usb_in_buffer[1] || 6 != usb_in_buffer[0]) - LOG_WARNING( - "ARM-JTAG-EW firmware version %d.%d is untested with this version of OpenOCD. You might experience unexpected behavior.", - usb_in_buffer[1], - usb_in_buffer[0]); - return ERROR_OK; -} - -COMMAND_HANDLER(armjtagew_handle_armjtagew_info_command) -{ - if (armjtagew_get_version_info() == ERROR_OK) { - /* attempt to get status */ - armjtagew_get_status(); - } - - return ERROR_OK; -} - -static const struct command_registration armjtagew_command_handlers[] = { - { - .name = "armjtagew_info", - .handler = &armjtagew_handle_armjtagew_info_command, - .mode = COMMAND_EXEC, - .help = "query armjtagew info", - }, - COMMAND_REGISTRATION_DONE -}; - -struct jtag_interface armjtagew_interface = { - .name = "arm-jtag-ew", - .commands = armjtagew_command_handlers, - .transports = jtag_only, - .execute_queue = armjtagew_execute_queue, - .speed = armjtagew_speed, - .speed_div = armjtagew_speed_div, - .khz = armjtagew_khz, - .init = armjtagew_init, - .quit = armjtagew_quit, -}; - -/************************************************************************** - * ARM-JTAG-EW tap functions */ - -/* 2048 is the max value we can use here */ -#define ARMJTAGEW_TAP_BUFFER_SIZE 2048 - -static int tap_length; -static uint8_t tms_buffer[ARMJTAGEW_TAP_BUFFER_SIZE]; -static uint8_t tdi_buffer[ARMJTAGEW_TAP_BUFFER_SIZE]; -static uint8_t tdo_buffer[ARMJTAGEW_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 */ - uint8_t *buffer; -}; - -#define MAX_PENDING_SCAN_RESULTS 256 - -static int pending_scan_results_length; -static struct pending_scan_result pending_scan_results_buffer[MAX_PENDING_SCAN_RESULTS]; - -static int last_tms; - -static void armjtagew_tap_init(void) -{ - tap_length = 0; - pending_scan_results_length = 0; -} - -static void armjtagew_tap_ensure_space(int scans, int bits) -{ - int available_scans = MAX_PENDING_SCAN_RESULTS - pending_scan_results_length; - int available_bits = ARMJTAGEW_TAP_BUFFER_SIZE * 8 - tap_length; - - if (scans > available_scans || bits > available_bits) - armjtagew_tap_execute(); -} - -static void armjtagew_tap_append_step(int tms, int tdi) -{ - last_tms = tms; - int index_local = tap_length / 8; - - if (index_local < ARMJTAGEW_TAP_BUFFER_SIZE) { - int bit_index = tap_length % 8; - uint8_t bit = 1 << bit_index; - - if (tms) - tms_buffer[index_local] |= bit; - else - tms_buffer[index_local] &= ~bit; - - if (tdi) - tdi_buffer[index_local] |= bit; - else - tdi_buffer[index_local] &= ~bit; - - tap_length++; - } else - LOG_ERROR("armjtagew_tap_append_step, overflow"); -} - -void armjtagew_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; - - pending_scan_result->first = tap_length; - pending_scan_result->length = length; - pending_scan_result->command = command; - pending_scan_result->buffer = buffer; - - for (i = 0; i < length; i++) - armjtagew_tap_append_step((i < length-1 ? 0 : 1), (buffer[i/8] >> (i%8)) & 1); - pending_scan_results_length++; -} - -/* 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 armjtagew_tap_execute(void) -{ - int byte_length; - int tms_offset; - int tdi_offset; - int i; - int result; - - if (tap_length > 0) { - /* Pad last byte so that tap_length is divisible by 8 */ - while (tap_length % 8 != 0) { - /* More of the last TMS value keeps us in the same state, - * analogous to free-running JTAG interfaces. */ - armjtagew_tap_append_step(last_tms, 0); - } - - byte_length = tap_length / 8; - - usb_out_buffer[0] = CMD_TAP_SHIFT; - buf_set_u32(usb_out_buffer + 1, 0, 16, byte_length); - - tms_offset = 3; - for (i = 0; i < byte_length; i++) - usb_out_buffer[tms_offset + i] = flip_u32(tms_buffer[i], 8); - - tdi_offset = tms_offset + byte_length; - for (i = 0; i < byte_length; i++) - usb_out_buffer[tdi_offset + i] = flip_u32(tdi_buffer[i], 8); - - result = armjtagew_usb_message(armjtagew_handle, - 3 + 2 * byte_length, - byte_length + 4); - - if (result == 0) { - int stat_local; - - stat_local = (int)buf_get_u32(usb_in_buffer + byte_length, 0, 32); - if (stat_local) { - LOG_ERROR( - "armjtagew_tap_execute, emulator returned error code %d for a CMD_TAP_SHIFT command", - stat_local); - return ERROR_JTAG_QUEUE_FAILED; - } - - for (i = 0; i < byte_length; i++) - tdo_buffer[i] = flip_u32(usb_in_buffer[i], 8); - - 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); - - DEBUG_JTAG_IO("pending scan result, length = %d", length); - -#ifdef _DEBUG_USB_COMMS_ - armjtagew_debug_buffer(buffer, byte_length); -#endif - - if (jtag_read_buffer(buffer, command) != ERROR_OK) { - armjtagew_tap_init(); - return ERROR_JTAG_QUEUE_FAILED; - } - - if (pending_scan_result->buffer != NULL) - free(pending_scan_result->buffer); - } - } else { - LOG_ERROR("armjtagew_tap_execute, wrong result %d, expected %d", - result, - byte_length); - return ERROR_JTAG_QUEUE_FAILED; - } - - armjtagew_tap_init(); - } - - return ERROR_OK; -} - -/**************************************************************************** - * JLink USB low-level functions */ - -static struct armjtagew *armjtagew_usb_open() -{ - usb_init(); - - const uint16_t vids[] = { USB_VID, 0 }; - const uint16_t pids[] = { USB_PID, 0 }; - struct usb_dev_handle *dev; - if (jtag_usb_open(vids, pids, &dev) != ERROR_OK) - return NULL; - - struct armjtagew *result = malloc(sizeof(struct armjtagew)); - result->usb_handle = dev; - -#if 0 - /* usb_set_configuration required under win32 */ - usb_set_configuration(dev, dev->config[0].bConfigurationValue); -#endif - usb_claim_interface(dev, 0); -#if 0 - /* - * This makes problems under Mac OS X. And is not needed - * under Windows. Hopefully this will not break a linux build - */ - usb_set_altinterface(dev, 0); -#endif - return result; -} - -static void armjtagew_usb_close(struct armjtagew *armjtagew) -{ - usb_close(armjtagew->usb_handle); - free(armjtagew); -} - -/* Send a message and receive the reply. */ -static int armjtagew_usb_message(struct armjtagew *armjtagew, int out_length, int in_length) -{ - int result; - - result = armjtagew_usb_write(armjtagew, out_length); - if (result == out_length) { - result = armjtagew_usb_read(armjtagew, in_length); - if (result != in_length) { - LOG_ERROR("usb_bulk_read failed (requested=%d, result=%d)", - in_length, - result); - return -1; - } - } else { - LOG_ERROR("usb_bulk_write failed (requested=%d, result=%d)", out_length, result); - return -1; - } - return 0; -} - -/* Write data from out_buffer to USB. */ -static int armjtagew_usb_write(struct armjtagew *armjtagew, int out_length) -{ - int result; - - if (out_length > ARMJTAGEW_OUT_BUFFER_SIZE) { - LOG_ERROR("armjtagew_write illegal out_length=%d (max=%d)", - out_length, - ARMJTAGEW_OUT_BUFFER_SIZE); - return -1; - } - - result = usb_bulk_write(armjtagew->usb_handle, ARMJTAGEW_EPT_BULK_OUT, \ - (char *)usb_out_buffer, out_length, ARMJTAGEW_USB_TIMEOUT); - - DEBUG_JTAG_IO("armjtagew_usb_write, out_length = %d, result = %d", out_length, result); - -#ifdef _DEBUG_USB_COMMS_ - armjtagew_debug_buffer(usb_out_buffer, out_length); -#endif - return result; -} - -/* Read data from USB into in_buffer. */ -static int armjtagew_usb_read(struct armjtagew *armjtagew, int exp_in_length) -{ - int result = usb_bulk_read(armjtagew->usb_handle, ARMJTAGEW_EPT_BULK_IN, \ - (char *)usb_in_buffer, exp_in_length, ARMJTAGEW_USB_TIMEOUT); - - DEBUG_JTAG_IO("armjtagew_usb_read, result = %d", result); - -#ifdef _DEBUG_USB_COMMS_ - armjtagew_debug_buffer(usb_in_buffer, result); -#endif - return result; -} - -#ifdef _DEBUG_USB_COMMS_ -#define BYTES_PER_LINE 16 - -static void armjtagew_debug_buffer(uint8_t *buffer, int length) -{ - char line[81]; - char s[4]; - int i; - int j; - - for (i = 0; i < length; i += BYTES_PER_LINE) { - snprintf(line, 5, "%04x", i); - for (j = i; j < i + BYTES_PER_LINE && j < length; j++) { - snprintf(s, 4, " %02x", buffer[j]); - strcat(line, s); - } - LOG_DEBUG("%s", line); - - /* Prevent GDB timeout (writing to log might take some time) */ - keep_alive(); - } -} -#endif diff --git a/src/jtag/drivers/at91rm9200.c b/src/jtag/drivers/at91rm9200.c deleted file mode 100644 index 8f65413a2..000000000 --- a/src/jtag/drivers/at91rm9200.c +++ /dev/null @@ -1,266 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2006 by Anders Larsen * - * al@alarsen.net * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include "bitbang.h" - -#include - -/* AT91RM9200 */ -#define AT91C_BASE_SYS (0xfffff000) - -/* GPIO assignment */ -#define PIOA (0 << 7) -#define PIOB (1 << 7) -#define PIOC (2 << 7) -#define PIOD (3 << 7) - -#define PIO_PER (0) /* PIO enable */ -#define PIO_OER (4) /* output enable */ -#define PIO_ODR (5) /* output disable */ -#define PIO_SODR (12) /* set output data */ -#define PIO_CODR (13) /* clear output data */ -#define PIO_PDSR (15) /* pin data status */ -#define PIO_PPUER (25) /* pull-up enable */ - -#define NC (0) /* not connected */ -#define P0 (1 << 0) -#define P1 (1 << 1) -#define P2 (1 << 2) -#define P3 (1 << 3) -#define P4 (1 << 4) -#define P5 (1 << 5) -#define P6 (1 << 6) -#define P7 (1 << 7) -#define P8 (1 << 8) -#define P9 (1 << 9) -#define P10 (1 << 10) -#define P11 (1 << 11) -#define P12 (1 << 12) -#define P13 (1 << 13) -#define P14 (1 << 14) -#define P15 (1 << 15) -#define P16 (1 << 16) -#define P17 (1 << 17) -#define P18 (1 << 18) -#define P19 (1 << 19) -#define P20 (1 << 20) -#define P21 (1 << 21) -#define P22 (1 << 22) -#define P23 (1 << 23) -#define P24 (1 << 24) -#define P25 (1 << 25) -#define P26 (1 << 26) -#define P27 (1 << 27) -#define P28 (1 << 28) -#define P29 (1 << 29) -#define P30 (1 << 30) -#define P31 (1 << 31) - -struct device_t { - const char *name; - int TDO_PIO; /* PIO holding TDO */ - uint32_t TDO_MASK; /* TDO bitmask */ - int TRST_PIO; /* PIO holding TRST */ - uint32_t TRST_MASK; /* TRST bitmask */ - int TMS_PIO; /* PIO holding TMS */ - uint32_t TMS_MASK; /* TMS bitmask */ - int TCK_PIO; /* PIO holding TCK */ - uint32_t TCK_MASK; /* TCK bitmask */ - int TDI_PIO; /* PIO holding TDI */ - uint32_t TDI_MASK; /* TDI bitmask */ - int SRST_PIO; /* PIO holding SRST */ - uint32_t SRST_MASK; /* SRST bitmask */ -}; - -static const struct device_t devices[] = { - { "rea_ecr", PIOD, P27, PIOA, NC, PIOD, P23, PIOD, P24, PIOD, P26, PIOC, P5 }, - { .name = NULL }, -}; - -/* configuration */ -static char *at91rm9200_device; - -/* interface variables - */ -static const struct device_t *device; -static int dev_mem_fd; -static void *sys_controller; -static uint32_t *pio_base; - -/* low level command set - */ -static int at91rm9200_read(void); -static void at91rm9200_write(int tck, int tms, int tdi); -static void at91rm9200_reset(int trst, int srst); - -static int at91rm9200_init(void); -static int at91rm9200_quit(void); - -static struct bitbang_interface at91rm9200_bitbang = { - .read = at91rm9200_read, - .write = at91rm9200_write, - .reset = at91rm9200_reset, - .blink = 0 -}; - -static int at91rm9200_read(void) -{ - return (pio_base[device->TDO_PIO + PIO_PDSR] & device->TDO_MASK) != 0; -} - -static void at91rm9200_write(int tck, int tms, int tdi) -{ - if (tck) - pio_base[device->TCK_PIO + PIO_SODR] = device->TCK_MASK; - else - pio_base[device->TCK_PIO + PIO_CODR] = device->TCK_MASK; - - if (tms) - pio_base[device->TMS_PIO + PIO_SODR] = device->TMS_MASK; - else - pio_base[device->TMS_PIO + PIO_CODR] = device->TMS_MASK; - - if (tdi) - pio_base[device->TDI_PIO + PIO_SODR] = device->TDI_MASK; - else - pio_base[device->TDI_PIO + PIO_CODR] = device->TDI_MASK; -} - -/* (1) assert or (0) deassert reset lines */ -static void at91rm9200_reset(int trst, int srst) -{ - if (trst == 0) - pio_base[device->TRST_PIO + PIO_SODR] = device->TRST_MASK; - else if (trst == 1) - pio_base[device->TRST_PIO + PIO_CODR] = device->TRST_MASK; - - if (srst == 0) - pio_base[device->SRST_PIO + PIO_SODR] = device->SRST_MASK; - else if (srst == 1) - pio_base[device->SRST_PIO + PIO_CODR] = device->SRST_MASK; -} - -COMMAND_HANDLER(at91rm9200_handle_device_command) -{ - if (CMD_ARGC == 0) - return ERROR_COMMAND_SYNTAX_ERROR; - - /* only if the device name wasn't overwritten by cmdline */ - if (at91rm9200_device == 0) { - at91rm9200_device = malloc(strlen(CMD_ARGV[0]) + sizeof(char)); - strcpy(at91rm9200_device, CMD_ARGV[0]); - } - - return ERROR_OK; -} - -static const struct command_registration at91rm9200_command_handlers[] = { - { - .name = "at91rm9200_device", - .handler = &at91rm9200_handle_device_command, - .mode = COMMAND_CONFIG, - .help = "query armjtagew info", - }, - COMMAND_REGISTRATION_DONE -}; - -struct jtag_interface at91rm9200_interface = { - .name = "at91rm9200", - .execute_queue = bitbang_execute_queue, - .commands = at91rm9200_command_handlers, - .init = at91rm9200_init, - .quit = at91rm9200_quit, -}; - -static int at91rm9200_init(void) -{ - const struct device_t *cur_device; - - cur_device = devices; - - if (at91rm9200_device == NULL || at91rm9200_device[0] == 0) { - at91rm9200_device = "rea_ecr"; - LOG_WARNING("No at91rm9200 device specified, using default 'rea_ecr'"); - } - - while (cur_device->name) { - if (strcmp(cur_device->name, at91rm9200_device) == 0) { - device = cur_device; - break; - } - cur_device++; - } - - if (!device) { - LOG_ERROR("No matching device found for %s", at91rm9200_device); - return ERROR_JTAG_INIT_FAILED; - } - - bitbang_interface = &at91rm9200_bitbang; - - dev_mem_fd = open("/dev/mem", O_RDWR | O_SYNC); - if (dev_mem_fd < 0) { - perror("open"); - return ERROR_JTAG_INIT_FAILED; - } - - sys_controller = mmap(NULL, 4096, PROT_READ | PROT_WRITE, - MAP_SHARED, dev_mem_fd, AT91C_BASE_SYS); - if (sys_controller == MAP_FAILED) { - perror("mmap"); - close(dev_mem_fd); - return ERROR_JTAG_INIT_FAILED; - } - pio_base = (uint32_t *)sys_controller + 0x100; - - /* - * Configure TDO as an input, and TDI, TCK, TMS, TRST, SRST - * as outputs. Drive TDI and TCK low, and TMS/TRST/SRST high. - */ - pio_base[device->TDI_PIO + PIO_CODR] = device->TDI_MASK; - pio_base[device->TDI_PIO + PIO_OER] = device->TDI_MASK; - pio_base[device->TDI_PIO + PIO_PER] = device->TDI_MASK; - pio_base[device->TCK_PIO + PIO_CODR] = device->TCK_MASK; - pio_base[device->TCK_PIO + PIO_OER] = device->TCK_MASK; - pio_base[device->TCK_PIO + PIO_PER] = device->TCK_MASK; - pio_base[device->TMS_PIO + PIO_SODR] = device->TMS_MASK; - pio_base[device->TMS_PIO + PIO_OER] = device->TMS_MASK; - pio_base[device->TMS_PIO + PIO_PER] = device->TMS_MASK; - pio_base[device->TRST_PIO + PIO_SODR] = device->TRST_MASK; - pio_base[device->TRST_PIO + PIO_OER] = device->TRST_MASK; - pio_base[device->TRST_PIO + PIO_PER] = device->TRST_MASK; - pio_base[device->SRST_PIO + PIO_SODR] = device->SRST_MASK; - pio_base[device->SRST_PIO + PIO_OER] = device->SRST_MASK; - pio_base[device->SRST_PIO + PIO_PER] = device->SRST_MASK; - pio_base[device->TDO_PIO + PIO_ODR] = device->TDO_MASK; - pio_base[device->TDO_PIO + PIO_PPUER] = device->TDO_MASK; - pio_base[device->TDO_PIO + PIO_PER] = device->TDO_MASK; - - return ERROR_OK; -} - -static int at91rm9200_quit(void) -{ - - return ERROR_OK; -} diff --git a/src/jtag/drivers/bcm2835gpio.c b/src/jtag/drivers/bcm2835gpio.c deleted file mode 100644 index 1622b2215..000000000 --- a/src/jtag/drivers/bcm2835gpio.c +++ /dev/null @@ -1,531 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2013 by Paul Fertser, fercerpav@gmail.com * - * * - * Copyright (C) 2012 by Creative Product Design, marc @ cpdesign.com.au * - * Based on at91rm9200.c (c) Anders Larsen * - * and RPi GPIO examples by Gert van Loo & Dom * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include "bitbang.h" - -#include - -uint32_t bcm2835_peri_base = 0x20000000; -#define BCM2835_GPIO_BASE (bcm2835_peri_base + 0x200000) /* GPIO controller */ - -#define BCM2835_PADS_GPIO_0_27 (bcm2835_peri_base + 0x100000) -#define BCM2835_PADS_GPIO_0_27_OFFSET (0x2c / 4) - -/* GPIO setup macros */ -#define MODE_GPIO(g) (*(pio_base+((g)/10))>>(((g)%10)*3) & 7) -#define INP_GPIO(g) do { *(pio_base+((g)/10)) &= ~(7<<(((g)%10)*3)); } while (0) -#define SET_MODE_GPIO(g, m) do { /* clear the mode bits first, then set as necessary */ \ - INP_GPIO(g); \ - *(pio_base+((g)/10)) |= ((m)<<(((g)%10)*3)); } while (0) -#define OUT_GPIO(g) SET_MODE_GPIO(g, 1) - -#define GPIO_SET (*(pio_base+7)) /* sets bits which are 1, ignores bits which are 0 */ -#define GPIO_CLR (*(pio_base+10)) /* clears bits which are 1, ignores bits which are 0 */ -#define GPIO_LEV (*(pio_base+13)) /* current level of the pin */ - -static int dev_mem_fd; -static volatile uint32_t *pio_base; - -static int bcm2835gpio_read(void); -static void bcm2835gpio_write(int tck, int tms, int tdi); -static void bcm2835gpio_reset(int trst, int srst); - -static int bcm2835_swdio_read(void); -static void bcm2835_swdio_drive(bool is_output); - -static int bcm2835gpio_init(void); -static int bcm2835gpio_quit(void); - -static struct bitbang_interface bcm2835gpio_bitbang = { - .read = bcm2835gpio_read, - .write = bcm2835gpio_write, - .reset = bcm2835gpio_reset, - .swdio_read = bcm2835_swdio_read, - .swdio_drive = bcm2835_swdio_drive, - .blink = NULL -}; - -/* GPIO numbers for each signal. Negative values are invalid */ -static int tck_gpio = -1; -static int tck_gpio_mode; -static int tms_gpio = -1; -static int tms_gpio_mode; -static int tdi_gpio = -1; -static int tdi_gpio_mode; -static int tdo_gpio = -1; -static int tdo_gpio_mode; -static int trst_gpio = -1; -static int trst_gpio_mode; -static int srst_gpio = -1; -static int srst_gpio_mode; -static int swclk_gpio = -1; -static int swclk_gpio_mode; -static int swdio_gpio = -1; -static int swdio_gpio_mode; - -/* Transition delay coefficients */ -static int speed_coeff = 113714; -static int speed_offset = 28; -static unsigned int jtag_delay; - -static int bcm2835gpio_read(void) -{ - return !!(GPIO_LEV & 1< 0) { - set |= !trst< 0) { - set |= !srst<= 0 && gpio <= 53; -} - -COMMAND_HANDLER(bcm2835gpio_handle_jtag_gpionums) -{ - if (CMD_ARGC == 4) { - COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], tck_gpio); - COMMAND_PARSE_NUMBER(int, CMD_ARGV[1], tms_gpio); - COMMAND_PARSE_NUMBER(int, CMD_ARGV[2], tdi_gpio); - COMMAND_PARSE_NUMBER(int, CMD_ARGV[3], tdo_gpio); - } else if (CMD_ARGC != 0) { - return ERROR_COMMAND_SYNTAX_ERROR; - } - - command_print(CMD_CTX, - "BCM2835 GPIO config: tck = %d, tms = %d, tdi = %d, tdo = %d", - tck_gpio, tms_gpio, tdi_gpio, tdo_gpio); - - return ERROR_OK; -} - -COMMAND_HANDLER(bcm2835gpio_handle_jtag_gpionum_tck) -{ - if (CMD_ARGC == 1) - COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], tck_gpio); - - command_print(CMD_CTX, "BCM2835 GPIO config: tck = %d", tck_gpio); - return ERROR_OK; -} - -COMMAND_HANDLER(bcm2835gpio_handle_jtag_gpionum_tms) -{ - if (CMD_ARGC == 1) - COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], tms_gpio); - - command_print(CMD_CTX, "BCM2835 GPIO config: tms = %d", tms_gpio); - return ERROR_OK; -} - -COMMAND_HANDLER(bcm2835gpio_handle_jtag_gpionum_tdo) -{ - if (CMD_ARGC == 1) - COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], tdo_gpio); - - command_print(CMD_CTX, "BCM2835 GPIO config: tdo = %d", tdo_gpio); - return ERROR_OK; -} - -COMMAND_HANDLER(bcm2835gpio_handle_jtag_gpionum_tdi) -{ - if (CMD_ARGC == 1) - COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], tdi_gpio); - - command_print(CMD_CTX, "BCM2835 GPIO config: tdi = %d", tdi_gpio); - return ERROR_OK; -} - -COMMAND_HANDLER(bcm2835gpio_handle_jtag_gpionum_srst) -{ - if (CMD_ARGC == 1) - COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], srst_gpio); - - command_print(CMD_CTX, "BCM2835 GPIO config: srst = %d", srst_gpio); - return ERROR_OK; -} - -COMMAND_HANDLER(bcm2835gpio_handle_jtag_gpionum_trst) -{ - if (CMD_ARGC == 1) - COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], trst_gpio); - - command_print(CMD_CTX, "BCM2835 GPIO config: trst = %d", trst_gpio); - return ERROR_OK; -} - -COMMAND_HANDLER(bcm2835gpio_handle_swd_gpionums) -{ - if (CMD_ARGC == 2) { - COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], swclk_gpio); - COMMAND_PARSE_NUMBER(int, CMD_ARGV[1], swdio_gpio); - } else if (CMD_ARGC != 0) { - return ERROR_COMMAND_SYNTAX_ERROR; - } - - command_print(CMD_CTX, - "BCM2835 GPIO nums: swclk = %d, swdio = %d", - swclk_gpio, swdio_gpio); - - return ERROR_OK; -} - -COMMAND_HANDLER(bcm2835gpio_handle_swd_gpionum_swclk) -{ - if (CMD_ARGC == 1) - COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], swclk_gpio); - - command_print(CMD_CTX, "BCM2835 num: swclk = %d", swclk_gpio); - return ERROR_OK; -} - -COMMAND_HANDLER(bcm2835gpio_handle_swd_gpionum_swdio) -{ - if (CMD_ARGC == 1) - COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], swdio_gpio); - - command_print(CMD_CTX, "BCM2835 num: swdio = %d", swdio_gpio); - return ERROR_OK; -} - -COMMAND_HANDLER(bcm2835gpio_handle_speed_coeffs) -{ - if (CMD_ARGC == 2) { - COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], speed_coeff); - COMMAND_PARSE_NUMBER(int, CMD_ARGV[1], speed_offset); - } - return ERROR_OK; -} - -COMMAND_HANDLER(bcm2835gpio_handle_peripheral_base) -{ - if (CMD_ARGC == 1) - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], bcm2835_peri_base); - return ERROR_OK; -} - -static const struct command_registration bcm2835gpio_command_handlers[] = { - { - .name = "bcm2835gpio_jtag_nums", - .handler = &bcm2835gpio_handle_jtag_gpionums, - .mode = COMMAND_CONFIG, - .help = "gpio numbers for tck, tms, tdi, tdo. (in that order)", - .usage = "(tck tms tdi tdo)* ", - }, - { - .name = "bcm2835gpio_tck_num", - .handler = &bcm2835gpio_handle_jtag_gpionum_tck, - .mode = COMMAND_CONFIG, - .help = "gpio number for tck.", - }, - { - .name = "bcm2835gpio_tms_num", - .handler = &bcm2835gpio_handle_jtag_gpionum_tms, - .mode = COMMAND_CONFIG, - .help = "gpio number for tms.", - }, - { - .name = "bcm2835gpio_tdo_num", - .handler = &bcm2835gpio_handle_jtag_gpionum_tdo, - .mode = COMMAND_CONFIG, - .help = "gpio number for tdo.", - }, - { - .name = "bcm2835gpio_tdi_num", - .handler = &bcm2835gpio_handle_jtag_gpionum_tdi, - .mode = COMMAND_CONFIG, - .help = "gpio number for tdi.", - }, - { - .name = "bcm2835gpio_swd_nums", - .handler = &bcm2835gpio_handle_swd_gpionums, - .mode = COMMAND_CONFIG, - .help = "gpio numbers for swclk, swdio. (in that order)", - .usage = "(swclk swdio)* ", - }, - { - .name = "bcm2835gpio_swclk_num", - .handler = &bcm2835gpio_handle_swd_gpionum_swclk, - .mode = COMMAND_CONFIG, - .help = "gpio number for swclk.", - }, - { - .name = "bcm2835gpio_swdio_num", - .handler = &bcm2835gpio_handle_swd_gpionum_swdio, - .mode = COMMAND_CONFIG, - .help = "gpio number for swdio.", - }, - { - .name = "bcm2835gpio_srst_num", - .handler = &bcm2835gpio_handle_jtag_gpionum_srst, - .mode = COMMAND_CONFIG, - .help = "gpio number for srst.", - }, - { - .name = "bcm2835gpio_trst_num", - .handler = &bcm2835gpio_handle_jtag_gpionum_trst, - .mode = COMMAND_CONFIG, - .help = "gpio number for trst.", - }, - { - .name = "bcm2835gpio_speed_coeffs", - .handler = &bcm2835gpio_handle_speed_coeffs, - .mode = COMMAND_CONFIG, - .help = "SPEED_COEFF and SPEED_OFFSET for delay calculations.", - }, - { - .name = "bcm2835gpio_peripheral_base", - .handler = &bcm2835gpio_handle_peripheral_base, - .mode = COMMAND_CONFIG, - .help = "peripheral base to access GPIOs (RPi1 0x20000000, RPi2 0x3F000000).", - }, - - COMMAND_REGISTRATION_DONE -}; - -static const char * const bcm2835_transports[] = { "jtag", "swd", NULL }; - -struct jtag_interface bcm2835gpio_interface = { - .name = "bcm2835gpio", - .supported = DEBUG_CAP_TMS_SEQ, - .execute_queue = bitbang_execute_queue, - .transports = bcm2835_transports, - .swd = &bitbang_swd, - .speed = bcm2835gpio_speed, - .khz = bcm2835gpio_khz, - .speed_div = bcm2835gpio_speed_div, - .commands = bcm2835gpio_command_handlers, - .init = bcm2835gpio_init, - .quit = bcm2835gpio_quit, -}; - -static bool bcm2835gpio_jtag_mode_possible(void) -{ - if (!is_gpio_valid(tck_gpio)) - return 0; - if (!is_gpio_valid(tms_gpio)) - return 0; - if (!is_gpio_valid(tdi_gpio)) - return 0; - if (!is_gpio_valid(tdo_gpio)) - return 0; - return 1; -} - -static bool bcm2835gpio_swd_mode_possible(void) -{ - if (!is_gpio_valid(swclk_gpio)) - return 0; - if (!is_gpio_valid(swdio_gpio)) - return 0; - return 1; -} - -static int bcm2835gpio_init(void) -{ - bitbang_interface = &bcm2835gpio_bitbang; - - LOG_INFO("BCM2835 GPIO JTAG/SWD bitbang driver"); - - if (bcm2835gpio_jtag_mode_possible()) { - if (bcm2835gpio_swd_mode_possible()) - LOG_INFO("JTAG and SWD modes enabled"); - else - LOG_INFO("JTAG only mode enabled (specify swclk and swdio gpio to add SWD mode)"); - if (!is_gpio_valid(trst_gpio) && !is_gpio_valid(srst_gpio)) { - LOG_ERROR("Require at least one of trst or srst gpios to be specified"); - return ERROR_JTAG_INIT_FAILED; - } - } else if (bcm2835gpio_swd_mode_possible()) { - LOG_INFO("SWD only mode enabled (specify tck, tms, tdi and tdo gpios to add JTAG mode)"); - } else { - LOG_ERROR("Require tck, tms, tdi and tdo gpios for JTAG mode and/or swclk and swdio gpio for SWD mode"); - return ERROR_JTAG_INIT_FAILED; - } - - dev_mem_fd = open("/dev/mem", O_RDWR | O_SYNC); - if (dev_mem_fd < 0) { - perror("open"); - return ERROR_JTAG_INIT_FAILED; - } - - pio_base = mmap(NULL, sysconf(_SC_PAGE_SIZE), PROT_READ | PROT_WRITE, - MAP_SHARED, dev_mem_fd, BCM2835_GPIO_BASE); - - if (pio_base == MAP_FAILED) { - perror("mmap"); - close(dev_mem_fd); - return ERROR_JTAG_INIT_FAILED; - } - - static volatile uint32_t *pads_base; - pads_base = mmap(NULL, sysconf(_SC_PAGE_SIZE), PROT_READ | PROT_WRITE, - MAP_SHARED, dev_mem_fd, BCM2835_PADS_GPIO_0_27); - - if (pads_base == MAP_FAILED) { - perror("mmap"); - close(dev_mem_fd); - return ERROR_JTAG_INIT_FAILED; - } - - /* set 16mA drive strength */ - pads_base[BCM2835_PADS_GPIO_0_27_OFFSET] = 0x5a000018 + 7; - - tdo_gpio_mode = MODE_GPIO(tdo_gpio); - tdi_gpio_mode = MODE_GPIO(tdi_gpio); - tck_gpio_mode = MODE_GPIO(tck_gpio); - tms_gpio_mode = MODE_GPIO(tms_gpio); - swclk_gpio_mode = MODE_GPIO(swclk_gpio); - swdio_gpio_mode = MODE_GPIO(swdio_gpio); - /* - * Configure TDO as an input, and TDI, TCK, TMS, TRST, SRST - * as outputs. Drive TDI and TCK low, and TMS/TRST/SRST high. - */ - INP_GPIO(tdo_gpio); - - GPIO_CLR = 1<. * - ***************************************************************************/ - -/* 2014-12: Addition of the SWD protocol support is based on the initial work - * by Paul Fertser and modifications by Jean-Christian de Rivaz. */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "bitbang.h" -#include -#include - -/* YUK! - but this is currently a global.... */ -extern struct jtag_interface *jtag_interface; - -/** - * Function bitbang_stableclocks - * issues a number of clock cycles while staying in a stable state. - * Because the TMS value required to stay in the RESET state is a 1, whereas - * the TMS value required to stay in any of the other stable states is a 0, - * this function checks the current stable state to decide on the value of TMS - * to use. - */ -static void bitbang_stableclocks(int num_cycles); - -static void bitbang_swd_write_reg(uint8_t cmd, uint32_t value, uint32_t ap_delay_clk); - -struct bitbang_interface *bitbang_interface; - -/* DANGER!!!! clock absolutely *MUST* be 0 in idle or reset won't work! - * - * Set this to 1 and str912 reset halt will fail. - * - * If someone can submit a patch with an explanation it will be greatly - * appreciated, but as far as I can tell (ØH) DCLK is generated upon - * clk = 0 in TAP_IDLE. Good luck deducing that from the ARM documentation! - * The ARM documentation uses the term "DCLK is asserted while in the TAP_IDLE - * state". With hardware there is no such thing as *while* in a state. There - * are only edges. So clk => 0 is in fact a very subtle state transition that - * happens *while* in the TAP_IDLE state. "#&¤"#¤&"#&"#& - * - * For "reset halt" the last thing that happens before srst is asserted - * is that the breakpoint is set up. If DCLK is not wiggled one last - * time before the reset, then the breakpoint is not set up and - * "reset halt" will fail to halt. - * - */ -#define CLOCK_IDLE() 0 - -/* The bitbang driver leaves the TCK 0 when in idle */ -static void bitbang_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); - } -} - -static void bitbang_state_move(int skip) -{ - int i = 0, tms = 0; - uint8_t tms_scan = tap_get_tms_path(tap_get_state(), tap_get_end_state()); - int tms_count = tap_get_tms_path_len(tap_get_state(), tap_get_end_state()); - - for (i = skip; i < tms_count; i++) { - tms = (tms_scan >> i) & 1; - bitbang_interface->write(0, tms, 0); - bitbang_interface->write(1, tms, 0); - } - bitbang_interface->write(CLOCK_IDLE(), tms, 0); - - tap_set_state(tap_get_end_state()); -} - -/** - * Clock a bunch of TMS (or SWDIO) transitions, to change the JTAG - * (or SWD) state machine. - */ -static int bitbang_execute_tms(struct jtag_command *cmd) -{ - unsigned num_bits = cmd->cmd.tms->num_bits; - const uint8_t *bits = cmd->cmd.tms->bits; - - DEBUG_JTAG_IO("TMS: %d bits", num_bits); - - int tms = 0; - for (unsigned i = 0; i < num_bits; i++) { - tms = ((bits[i/8] >> (i % 8)) & 1); - bitbang_interface->write(0, tms, 0); - bitbang_interface->write(1, tms, 0); - } - bitbang_interface->write(CLOCK_IDLE(), tms, 0); - - return ERROR_OK; -} - -static void bitbang_path_move(struct pathmove_command *cmd) -{ - int num_states = cmd->num_states; - int state_count; - int tms = 0; - - state_count = 0; - while (num_states) { - if (tap_state_transition(tap_get_state(), false) == cmd->path[state_count]) - tms = 0; - else if (tap_state_transition(tap_get_state(), true) == cmd->path[state_count]) - tms = 1; - else { - LOG_ERROR("BUG: %s -> %s isn't a valid TAP transition", - tap_state_name(tap_get_state()), - tap_state_name(cmd->path[state_count])); - exit(-1); - } - - bitbang_interface->write(0, tms, 0); - bitbang_interface->write(1, tms, 0); - - tap_set_state(cmd->path[state_count]); - state_count++; - num_states--; - } - - bitbang_interface->write(CLOCK_IDLE(), tms, 0); - - tap_set_end_state(tap_get_state()); -} - -static void bitbang_runtest(int num_cycles) -{ - int i; - - 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) { - bitbang_end_state(TAP_IDLE); - bitbang_state_move(0); - } - - /* execute num_cycles */ - for (i = 0; i < num_cycles; i++) { - bitbang_interface->write(0, 0, 0); - bitbang_interface->write(1, 0, 0); - } - bitbang_interface->write(CLOCK_IDLE(), 0, 0); - - /* finish in end_state */ - bitbang_end_state(saved_end_state); - if (tap_get_state() != tap_get_end_state()) - bitbang_state_move(0); -} - -static void bitbang_stableclocks(int num_cycles) -{ - int tms = (tap_get_state() == TAP_RESET ? 1 : 0); - int i; - - /* send num_cycles clocks onto the cable */ - for (i = 0; i < num_cycles; i++) { - bitbang_interface->write(1, tms, 0); - bitbang_interface->write(0, tms, 0); - } -} - -static void bitbang_scan(bool ir_scan, enum scan_type type, uint8_t *buffer, int scan_size) -{ - tap_state_t saved_end_state = tap_get_end_state(); - int bit_cnt; - - if (!((!ir_scan && - (tap_get_state() == TAP_DRSHIFT)) || - (ir_scan && (tap_get_state() == TAP_IRSHIFT)))) { - if (ir_scan) - bitbang_end_state(TAP_IRSHIFT); - else - bitbang_end_state(TAP_DRSHIFT); - - bitbang_state_move(0); - bitbang_end_state(saved_end_state); - } - - for (bit_cnt = 0; bit_cnt < scan_size; bit_cnt++) { - int val = 0; - int tms = (bit_cnt == scan_size-1) ? 1 : 0; - int tdi; - int bytec = bit_cnt/8; - int bcval = 1 << (bit_cnt % 8); - - /* if we're just reading the scan, but don't care about the output - * default to outputting 'low', this also makes valgrind traces more readable, - * as it removes the dependency on an uninitialised value - */ - tdi = 0; - if ((type != SCAN_IN) && (buffer[bytec] & bcval)) - tdi = 1; - - bitbang_interface->write(0, tms, tdi); - - if (type != SCAN_OUT) - val = bitbang_interface->read(); - - bitbang_interface->write(1, tms, tdi); - - if (type != SCAN_OUT) { - if (val) - buffer[bytec] |= bcval; - else - buffer[bytec] &= ~bcval; - } - } - - if (tap_get_state() != tap_get_end_state()) { - /* we *KNOW* the above loop transitioned out of - * the shift state, so we skip the first state - * and move directly to the end state. - */ - bitbang_state_move(1); - } -} - -int bitbang_execute_queue(void) -{ - struct jtag_command *cmd = jtag_command_queue; /* currently processed command */ - int scan_size; - enum scan_type type; - uint8_t *buffer; - int retval; - - if (!bitbang_interface) { - LOG_ERROR("BUG: Bitbang interface called, but not yet initialized"); - exit(-1); - } - - /* return ERROR_OK, unless a jtag_read_buffer returns a failed check - * that wasn't handled by a caller-provided error handler - */ - retval = ERROR_OK; - - if (bitbang_interface->blink) - bitbang_interface->blink(1); - - while (cmd) { - switch (cmd->type) { - case JTAG_RESET: -#ifdef _DEBUG_JTAG_IO_ - LOG_DEBUG("reset trst: %i srst %i", - cmd->cmd.reset->trst, - cmd->cmd.reset->srst); -#endif - if ((cmd->cmd.reset->trst == 1) || - (cmd->cmd.reset->srst && (jtag_get_reset_config() & RESET_SRST_PULLS_TRST))) - tap_set_state(TAP_RESET); - bitbang_interface->reset(cmd->cmd.reset->trst, cmd->cmd.reset->srst); - break; - case JTAG_RUNTEST: -#ifdef _DEBUG_JTAG_IO_ - LOG_DEBUG("runtest %i cycles, end in %s", - cmd->cmd.runtest->num_cycles, - tap_state_name(cmd->cmd.runtest->end_state)); -#endif - bitbang_end_state(cmd->cmd.runtest->end_state); - bitbang_runtest(cmd->cmd.runtest->num_cycles); - break; - - case JTAG_STABLECLOCKS: - /* this is only allowed while in a stable state. A check for a stable - * state was done in jtag_add_clocks() - */ - bitbang_stableclocks(cmd->cmd.stableclocks->num_cycles); - break; - - case JTAG_TLR_RESET: -#ifdef _DEBUG_JTAG_IO_ - LOG_DEBUG("statemove end in %s", - tap_state_name(cmd->cmd.statemove->end_state)); -#endif - bitbang_end_state(cmd->cmd.statemove->end_state); - bitbang_state_move(0); - break; - case JTAG_PATHMOVE: -#ifdef _DEBUG_JTAG_IO_ - LOG_DEBUG("pathmove: %i states, end in %s", - cmd->cmd.pathmove->num_states, - tap_state_name(cmd->cmd.pathmove->path[cmd->cmd.pathmove->num_states - 1])); -#endif - bitbang_path_move(cmd->cmd.pathmove); - break; - case JTAG_SCAN: -#ifdef _DEBUG_JTAG_IO_ - LOG_DEBUG("%s scan end in %s", - (cmd->cmd.scan->ir_scan) ? "IR" : "DR", - tap_state_name(cmd->cmd.scan->end_state)); -#endif - bitbang_end_state(cmd->cmd.scan->end_state); - scan_size = jtag_build_buffer(cmd->cmd.scan, &buffer); - type = jtag_scan_type(cmd->cmd.scan); - bitbang_scan(cmd->cmd.scan->ir_scan, type, buffer, scan_size); - if (jtag_read_buffer(buffer, cmd->cmd.scan) != ERROR_OK) - retval = ERROR_JTAG_QUEUE_FAILED; - if (buffer) - free(buffer); - break; - case JTAG_SLEEP: -#ifdef _DEBUG_JTAG_IO_ - LOG_DEBUG("sleep %" PRIi32, cmd->cmd.sleep->us); -#endif - jtag_sleep(cmd->cmd.sleep->us); - break; - case JTAG_TMS: - retval = bitbang_execute_tms(cmd); - break; - default: - LOG_ERROR("BUG: unknown JTAG command type encountered"); - exit(-1); - } - cmd = cmd->next; - } - if (bitbang_interface->blink) - bitbang_interface->blink(0); - - return retval; -} - - -bool swd_mode; -static int queued_retval; - -static int bitbang_swd_init(void) -{ - LOG_DEBUG("bitbang_swd_init"); - swd_mode = true; - return ERROR_OK; -} - -static void bitbang_exchange(bool rnw, uint8_t buf[], unsigned int offset, unsigned int bit_cnt) -{ - LOG_DEBUG("bitbang_exchange"); - int tdi; - - for (unsigned int i = offset; i < bit_cnt + offset; i++) { - int bytec = i/8; - int bcval = 1 << (i % 8); - tdi = !rnw && (buf[bytec] & bcval); - - bitbang_interface->write(0, 0, tdi); - - if (rnw && buf) { - if (bitbang_interface->swdio_read()) - buf[bytec] |= bcval; - else - buf[bytec] &= ~bcval; - } - - bitbang_interface->write(1, 0, tdi); - } -} - -int bitbang_swd_switch_seq(enum swd_special_seq seq) -{ - LOG_DEBUG("bitbang_swd_switch_seq"); - - switch (seq) { - case LINE_RESET: - LOG_DEBUG("SWD line reset"); - bitbang_exchange(false, (uint8_t *)swd_seq_line_reset, 0, swd_seq_line_reset_len); - break; - case JTAG_TO_SWD: - LOG_DEBUG("JTAG-to-SWD"); - bitbang_exchange(false, (uint8_t *)swd_seq_jtag_to_swd, 0, swd_seq_jtag_to_swd_len); - break; - case SWD_TO_JTAG: - LOG_DEBUG("SWD-to-JTAG"); - bitbang_exchange(false, (uint8_t *)swd_seq_swd_to_jtag, 0, swd_seq_swd_to_jtag_len); - break; - default: - LOG_ERROR("Sequence %d not supported", seq); - return ERROR_FAIL; - } - - return ERROR_OK; -} - -void bitbang_switch_to_swd(void) -{ - LOG_DEBUG("bitbang_switch_to_swd"); - bitbang_exchange(false, (uint8_t *)swd_seq_jtag_to_swd, 0, swd_seq_jtag_to_swd_len); -} - -static void swd_clear_sticky_errors(void) -{ - bitbang_swd_write_reg(swd_cmd(false, false, DP_ABORT), - STKCMPCLR | STKERRCLR | WDERRCLR | ORUNERRCLR, 0); -} - -static void bitbang_swd_read_reg(uint8_t cmd, uint32_t *value, uint32_t ap_delay_clk) -{ - LOG_DEBUG("bitbang_swd_read_reg"); - assert(cmd & SWD_CMD_RnW); - - if (queued_retval != ERROR_OK) { - LOG_DEBUG("Skip bitbang_swd_read_reg because queued_retval=%d", queued_retval); - return; - } - - for (;;) { - uint8_t trn_ack_data_parity_trn[DIV_ROUND_UP(4 + 3 + 32 + 1 + 4, 8)]; - - cmd |= SWD_CMD_START | (1 << 7); - bitbang_exchange(false, &cmd, 0, 8); - - bitbang_interface->swdio_drive(false); - bitbang_exchange(true, trn_ack_data_parity_trn, 0, 1 + 3 + 32 + 1 + 1); - bitbang_interface->swdio_drive(true); - - int ack = buf_get_u32(trn_ack_data_parity_trn, 1, 3); - uint32_t data = buf_get_u32(trn_ack_data_parity_trn, 1 + 3, 32); - int parity = buf_get_u32(trn_ack_data_parity_trn, 1 + 3 + 32, 1); - - LOG_DEBUG("%s %s %s reg %X = %08"PRIx32, - ack == SWD_ACK_OK ? "OK" : ack == SWD_ACK_WAIT ? "WAIT" : ack == SWD_ACK_FAULT ? "FAULT" : "JUNK", - cmd & SWD_CMD_APnDP ? "AP" : "DP", - cmd & SWD_CMD_RnW ? "read" : "write", - (cmd & SWD_CMD_A32) >> 1, - data); - - switch (ack) { - case SWD_ACK_OK: - if (parity != parity_u32(data)) { - LOG_DEBUG("Wrong parity detected"); - queued_retval = ERROR_FAIL; - return; - } - if (value) - *value = data; - if (cmd & SWD_CMD_APnDP) - bitbang_exchange(true, NULL, 0, ap_delay_clk); - return; - case SWD_ACK_WAIT: - LOG_DEBUG("SWD_ACK_WAIT"); - swd_clear_sticky_errors(); - break; - case SWD_ACK_FAULT: - LOG_DEBUG("SWD_ACK_FAULT"); - queued_retval = ack; - return; - default: - LOG_DEBUG("No valid acknowledge: ack=%d", ack); - queued_retval = ack; - return; - } - } -} - -static void bitbang_swd_write_reg(uint8_t cmd, uint32_t value, uint32_t ap_delay_clk) -{ - LOG_DEBUG("bitbang_swd_write_reg"); - assert(!(cmd & SWD_CMD_RnW)); - - if (queued_retval != ERROR_OK) { - LOG_DEBUG("Skip bitbang_swd_write_reg because queued_retval=%d", queued_retval); - return; - } - - for (;;) { - uint8_t trn_ack_data_parity_trn[DIV_ROUND_UP(4 + 3 + 32 + 1 + 4, 8)]; - buf_set_u32(trn_ack_data_parity_trn, 1 + 3 + 1, 32, value); - buf_set_u32(trn_ack_data_parity_trn, 1 + 3 + 1 + 32, 1, parity_u32(value)); - - cmd |= SWD_CMD_START | (1 << 7); - bitbang_exchange(false, &cmd, 0, 8); - - bitbang_interface->swdio_drive(false); - bitbang_exchange(true, trn_ack_data_parity_trn, 0, 1 + 3 + 1); - bitbang_interface->swdio_drive(true); - bitbang_exchange(false, trn_ack_data_parity_trn, 1 + 3 + 1, 32 + 1); - - int ack = buf_get_u32(trn_ack_data_parity_trn, 1, 3); - LOG_DEBUG("%s %s %s reg %X = %08"PRIx32, - ack == SWD_ACK_OK ? "OK" : ack == SWD_ACK_WAIT ? "WAIT" : ack == SWD_ACK_FAULT ? "FAULT" : "JUNK", - cmd & SWD_CMD_APnDP ? "AP" : "DP", - cmd & SWD_CMD_RnW ? "read" : "write", - (cmd & SWD_CMD_A32) >> 1, - buf_get_u32(trn_ack_data_parity_trn, 1 + 3 + 1, 32)); - - switch (ack) { - case SWD_ACK_OK: - if (cmd & SWD_CMD_APnDP) - bitbang_exchange(true, NULL, 0, ap_delay_clk); - return; - case SWD_ACK_WAIT: - LOG_DEBUG("SWD_ACK_WAIT"); - swd_clear_sticky_errors(); - break; - case SWD_ACK_FAULT: - LOG_DEBUG("SWD_ACK_FAULT"); - queued_retval = ack; - return; - default: - LOG_DEBUG("No valid acknowledge: ack=%d", ack); - queued_retval = ack; - return; - } - } -} - -static int bitbang_swd_run_queue(void) -{ - LOG_DEBUG("bitbang_swd_run_queue"); - /* A transaction must be followed by another transaction or at least 8 idle cycles to - * ensure that data is clocked through the AP. */ - bitbang_exchange(true, NULL, 0, 8); - - int retval = queued_retval; - queued_retval = ERROR_OK; - LOG_DEBUG("SWD queue return value: %02x", retval); - return retval; -} - -const struct swd_driver bitbang_swd = { - .init = bitbang_swd_init, - .switch_seq = bitbang_swd_switch_seq, - .read_reg = bitbang_swd_read_reg, - .write_reg = bitbang_swd_write_reg, - .run = bitbang_swd_run_queue, -}; diff --git a/src/jtag/drivers/bitbang.h b/src/jtag/drivers/bitbang.h deleted file mode 100644 index c5b44bfd5..000000000 --- a/src/jtag/drivers/bitbang.h +++ /dev/null @@ -1,48 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * Copyright (C) 2007,2008 Øyvind Harboe * - * oyvind.harboe@zylin.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifndef OPENOCD_JTAG_DRIVERS_BITBANG_H -#define OPENOCD_JTAG_DRIVERS_BITBANG_H - -#include - -struct bitbang_interface { - /* low level callbacks (for bitbang) - */ - int (*read)(void); - void (*write)(int tck, int tms, int tdi); - void (*reset)(int trst, int srst); - void (*blink)(int on); - int (*swdio_read)(void); - void (*swdio_drive)(bool on); -}; - -const struct swd_driver bitbang_swd; - -extern bool swd_mode; - -int bitbang_execute_queue(void); - -extern struct bitbang_interface *bitbang_interface; -void bitbang_switch_to_swd(void); -int bitbang_swd_switch_seq(enum swd_special_seq seq); - -#endif /* OPENOCD_JTAG_DRIVERS_BITBANG_H */ diff --git a/src/jtag/drivers/bitq.c b/src/jtag/drivers/bitq.c deleted file mode 100644 index 66285f700..000000000 --- a/src/jtag/drivers/bitq.c +++ /dev/null @@ -1,315 +0,0 @@ -/*************************************************************************** -* Copyright (C) 2007 by Pavel Chromy * -* chromy@asix.cz * -* * -* This program is free software; you can redistribute it and/or modify * -* it under the terms of the GNU General Public License as published by * -* the Free Software Foundation; either version 2 of the License, or * -* (at your option) any later version. * -* * -* This program is distributed in the hope that it will be useful, * -* but WITHOUT ANY WARRANTY; without even the implied warranty of * -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -* GNU General Public License for more details. * -* * -* You should have received a copy of the GNU General Public License * -* along with this program. If not, see . * -***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include "bitq.h" -#include - -struct bitq_interface *bitq_interface; /* low level bit queue interface */ - -/* state of input queue */ -struct bitq_state { - struct jtag_command *cmd; /* command currently processed */ - int field_idx; /* index of field currently being processed */ - int bit_pos; /* position of bit currently being processed */ - int status; /* processing status */ -}; -static struct bitq_state bitq_in_state; - -/* - * input queue processing does not use jtag_read_buffer() to avoid unnecessary overhead - * no parameters, makes use of stored state information - */ -static void bitq_in_proc(void) -{ - /* loop through the queue */ - while (bitq_in_state.cmd) { - /* only JTAG_SCAN command may return data */ - if (bitq_in_state.cmd->type == JTAG_SCAN) { - /* loop through the fields */ - while (bitq_in_state.field_idx < bitq_in_state.cmd->cmd.scan->num_fields) { - struct scan_field *field; - field = &bitq_in_state.cmd->cmd.scan->fields[bitq_in_state.field_idx]; - if (field->in_value) { - /* field scanning */ - while (bitq_in_state.bit_pos < field->num_bits) { - /* index of byte being scanned */ - int in_idx = bitq_in_state.bit_pos / 8; - /* mask of next bit to be scanned */ - uint8_t in_mask = 1 << (bitq_in_state.bit_pos % 8); - - int tdo = bitq_interface->in(); - if (tdo < 0) { -#ifdef _DEBUG_JTAG_IO_ - LOG_DEBUG("bitq in EOF"); -#endif - return; - } - if (in_mask == 0x01) - field->in_value[in_idx] = 0; - if (tdo) - field->in_value[in_idx] |= in_mask; - bitq_in_state.bit_pos++; - } - } - - bitq_in_state.field_idx++; /* advance to next field */ - bitq_in_state.bit_pos = 0; /* start next field from the first bit */ - } - } - bitq_in_state.cmd = bitq_in_state.cmd->next; /* advance to next command */ - bitq_in_state.field_idx = 0; /* preselect first field */ - } -} - -static void bitq_io(int tms, int tdi, int tdo_req) -{ - bitq_interface->out(tms, tdi, tdo_req); - /* check and process the input queue */ - if (bitq_interface->in_rdy()) - bitq_in_proc(); -} - -static void bitq_end_state(tap_state_t state) -{ - if (!tap_is_state_stable(state)) { - LOG_ERROR("BUG: %i is not a valid end state", state); - exit(-1); - } - tap_set_end_state(state); -} - -static void bitq_state_move(tap_state_t new_state) -{ - int i = 0; - uint8_t tms_scan; - - if (!tap_is_state_stable(tap_get_state()) || !tap_is_state_stable(new_state)) { - LOG_ERROR("TAP move from or to unstable state"); - exit(-1); - } - - tms_scan = tap_get_tms_path(tap_get_state(), new_state); - int tms_count = tap_get_tms_path_len(tap_get_state(), new_state); - - for (i = 0; i < tms_count; i++) { - bitq_io(tms_scan & 1, 0, 0); - tms_scan >>= 1; - } - - tap_set_state(new_state); -} - -static void bitq_path_move(struct pathmove_command *cmd) -{ - int i; - - for (i = 0; i <= cmd->num_states; i++) { - if (tap_state_transition(tap_get_state(), false) == cmd->path[i]) - bitq_io(0, 0, 0); - else if (tap_state_transition(tap_get_state(), true) == cmd->path[i]) - bitq_io(1, 0, 0); - else { - LOG_ERROR("BUG: %s -> %s isn't a valid TAP transition", tap_state_name( - tap_get_state()), tap_state_name(cmd->path[i])); - exit(-1); - } - - tap_set_state(cmd->path[i]); - } - - tap_set_end_state(tap_get_state()); -} - -static void bitq_runtest(int num_cycles) -{ - int i; - - /* only do a state_move when we're not already in IDLE */ - if (tap_get_state() != TAP_IDLE) - bitq_state_move(TAP_IDLE); - - /* execute num_cycles */ - for (i = 0; i < num_cycles; i++) - bitq_io(0, 0, 0); - - /* finish in end_state */ - if (tap_get_state() != tap_get_end_state()) - bitq_state_move(tap_get_end_state()); -} - -static void bitq_scan_field(struct scan_field *field, int do_pause) -{ - int bit_cnt; - int tdo_req; - - const uint8_t *out_ptr; - uint8_t out_mask; - - if (field->in_value) - tdo_req = 1; - else - tdo_req = 0; - - if (field->out_value == NULL) { - /* just send zeros and request data from TDO */ - for (bit_cnt = field->num_bits; bit_cnt > 1; bit_cnt--) - bitq_io(0, 0, tdo_req); - - bitq_io(do_pause, 0, tdo_req); - } else { - /* send data, and optionally request TDO */ - out_mask = 0x01; - out_ptr = field->out_value; - for (bit_cnt = field->num_bits; bit_cnt > 1; bit_cnt--) { - bitq_io(0, ((*out_ptr) & out_mask) != 0, tdo_req); - if (out_mask == 0x80) { - out_mask = 0x01; - out_ptr++; - } else - out_mask <<= 1; - } - - bitq_io(do_pause, ((*out_ptr) & out_mask) != 0, tdo_req); - } - - if (do_pause) { - bitq_io(0, 0, 0); - if (tap_get_state() == TAP_IRSHIFT) - tap_set_state(TAP_IRPAUSE); - else if (tap_get_state() == TAP_DRSHIFT) - tap_set_state(TAP_DRPAUSE); - } -} - -static void bitq_scan(struct scan_command *cmd) -{ - int i; - - if (cmd->ir_scan) - bitq_state_move(TAP_IRSHIFT); - else - bitq_state_move(TAP_DRSHIFT); - - for (i = 0; i < cmd->num_fields - 1; i++) - bitq_scan_field(&cmd->fields[i], 0); - - bitq_scan_field(&cmd->fields[i], 1); -} - -int bitq_execute_queue(void) -{ - struct jtag_command *cmd = jtag_command_queue; /* currently processed command */ - - bitq_in_state.cmd = jtag_command_queue; - bitq_in_state.field_idx = 0; - bitq_in_state.bit_pos = 0; - bitq_in_state.status = ERROR_OK; - - while (cmd) { - switch (cmd->type) { - case JTAG_RESET: -#ifdef _DEBUG_JTAG_IO_ - LOG_DEBUG("reset trst: %i srst %i", cmd->cmd.reset->trst, cmd->cmd.reset->srst); -#endif - if ((cmd->cmd.reset->trst == 1) || - (cmd->cmd.reset->srst && - (jtag_get_reset_config() & RESET_SRST_PULLS_TRST))) - tap_set_state(TAP_RESET); - bitq_interface->reset(cmd->cmd.reset->trst, cmd->cmd.reset->srst); - if (bitq_interface->in_rdy()) - bitq_in_proc(); - break; - - case JTAG_RUNTEST: -#ifdef _DEBUG_JTAG_IO_ - LOG_DEBUG("runtest %i cycles, end in %i", cmd->cmd.runtest->num_cycles, cmd->cmd.runtest->end_state); -#endif - bitq_end_state(cmd->cmd.runtest->end_state); - bitq_runtest(cmd->cmd.runtest->num_cycles); - break; - - case JTAG_TLR_RESET: -#ifdef _DEBUG_JTAG_IO_ - LOG_DEBUG("statemove end in %i", cmd->cmd.statemove->end_state); -#endif - bitq_end_state(cmd->cmd.statemove->end_state); - bitq_state_move(tap_get_end_state()); /* uncoditional TAP move */ - break; - - case JTAG_PATHMOVE: -#ifdef _DEBUG_JTAG_IO_ - LOG_DEBUG("pathmove: %i states, end in %i", cmd->cmd.pathmove->num_states, - cmd->cmd.pathmove->path[cmd->cmd.pathmove->num_states - 1]); -#endif - bitq_path_move(cmd->cmd.pathmove); - break; - - case JTAG_SCAN: -#ifdef _DEBUG_JTAG_IO_ - LOG_DEBUG("scan end in %i", cmd->cmd.scan->end_state); - if (cmd->cmd.scan->ir_scan) - LOG_DEBUG("scan ir"); - else - LOG_DEBUG("scan dr"); -#endif - bitq_end_state(cmd->cmd.scan->end_state); - bitq_scan(cmd->cmd.scan); - if (tap_get_state() != tap_get_end_state()) - bitq_state_move(tap_get_end_state()); - break; - - case JTAG_SLEEP: -#ifdef _DEBUG_JTAG_IO_ - LOG_DEBUG("sleep %i", cmd->cmd.sleep->us); -#endif - bitq_interface->sleep(cmd->cmd.sleep->us); - if (bitq_interface->in_rdy()) - bitq_in_proc(); - break; - - default: - LOG_ERROR("BUG: unknown JTAG command type encountered"); - exit(-1); - } - - cmd = cmd->next; - } - - bitq_interface->flush(); - bitq_in_proc(); - - if (bitq_in_state.cmd) { - LOG_ERROR("missing data from bitq interface"); - return ERROR_JTAG_QUEUE_FAILED; - } - if (bitq_interface->in() >= 0) { - LOG_ERROR("extra data from bitq interface"); - return ERROR_JTAG_QUEUE_FAILED; - } - - return bitq_in_state.status; -} - -void bitq_cleanup(void) -{ -} diff --git a/src/jtag/drivers/bitq.h b/src/jtag/drivers/bitq.h deleted file mode 100644 index df6a08d44..000000000 --- a/src/jtag/drivers/bitq.h +++ /dev/null @@ -1,45 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Pavel Chromy * - * chromy@asix.cz * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifndef OPENOCD_JTAG_DRIVERS_BITQ_H -#define OPENOCD_JTAG_DRIVERS_BITQ_H - -#include - -struct bitq_interface { - /* function to enqueueing low level IO requests */ - int (*out)(int tms, int tdi, int tdo_req); - int (*flush)(void); - - int (*sleep)(unsigned long us); - int (*reset)(int trst, int srst); - - /* delayed read of requested TDO data, - * the input shall be checked after call to any enqueuing function - */ - int (*in_rdy)(void); - int (*in)(void); -}; - -extern struct bitq_interface *bitq_interface; - -int bitq_execute_queue(void); - -void bitq_cleanup(void); - -#endif /* OPENOCD_JTAG_DRIVERS_BITQ_H */ diff --git a/src/jtag/drivers/buspirate.c b/src/jtag/drivers/buspirate.c deleted file mode 100644 index aa0d8cc3f..000000000 --- a/src/jtag/drivers/buspirate.c +++ /dev/null @@ -1,1126 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2010 by Michal Demin * - * based on usbprog.c and arm-jtag-ew.c * - * Several fixes by R. Diez in 2013. * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include - -#include -#include -#include - -#undef DEBUG_SERIAL -/*#define DEBUG_SERIAL */ -static int buspirate_execute_queue(void); -static int buspirate_init(void); -static int buspirate_quit(void); - -static void buspirate_end_state(tap_state_t state); -static void buspirate_state_move(void); -static void buspirate_path_move(int num_states, tap_state_t *path); -static void buspirate_runtest(int num_cycles); -static void buspirate_scan(bool ir_scan, enum scan_type type, - uint8_t *buffer, int scan_size, struct scan_command *command); -static void buspirate_stableclocks(int num_cycles); - -#define CMD_UNKNOWN 0x00 -#define CMD_PORT_MODE 0x01 -#define CMD_FEATURE 0x02 -#define CMD_READ_ADCS 0x03 -/*#define CMD_TAP_SHIFT 0x04 // old protocol */ -#define CMD_TAP_SHIFT 0x05 -#define CMD_ENTER_OOCD 0x06 -#define CMD_UART_SPEED 0x07 -#define CMD_JTAG_SPEED 0x08 - -/* Not all OSes have this speed defined */ -#if !defined(B1000000) -#define B1000000 0010010 -#endif - -enum { - MODE_HIZ = 0, - MODE_JTAG = 1, /* push-pull outputs */ - MODE_JTAG_OD = 2, /* open-drain outputs */ -}; - -enum { - FEATURE_LED = 0x01, - FEATURE_VREG = 0x02, - FEATURE_TRST = 0x04, - FEATURE_SRST = 0x08, - FEATURE_PULLUP = 0x10 -}; - -enum { - ACTION_DISABLE = 0, - ACTION_ENABLE = 1 -}; - -enum { - SERIAL_NORMAL = 0, - SERIAL_FAST = 1 -}; - -static const cc_t SHORT_TIMEOUT = 1; /* Must be at least 1. */ -static const cc_t NORMAL_TIMEOUT = 10; - -static int buspirate_fd = -1; -static int buspirate_pinmode = MODE_JTAG_OD; -static int buspirate_baudrate = SERIAL_NORMAL; -static int buspirate_vreg; -static int buspirate_pullup; -static char *buspirate_port; - -static enum tap_state last_tap_state = TAP_RESET; - - -/* TAP interface */ -static void buspirate_tap_init(void); -static int buspirate_tap_execute(void); -static void buspirate_tap_append(int tms, int tdi); -static void buspirate_tap_append_scan(int length, uint8_t *buffer, - struct scan_command *command); -static void buspirate_tap_make_space(int scan, int bits); - -static void buspirate_reset(int trst, int srst); - -/* low level interface */ -static void buspirate_jtag_reset(int); -static void buspirate_jtag_enable(int); -static unsigned char buspirate_jtag_command(int, char *, int); -static void buspirate_jtag_set_speed(int, char); -static void buspirate_jtag_set_mode(int, char); -static void buspirate_jtag_set_feature(int, char, char); -static void buspirate_jtag_get_adcs(int); - -/* low level HW communication interface */ -static int buspirate_serial_open(char *port); -static int buspirate_serial_setspeed(int fd, char speed, cc_t timeout); -static int buspirate_serial_write(int fd, char *buf, int size); -static int buspirate_serial_read(int fd, char *buf, int size); -static void buspirate_serial_close(int fd); -static void buspirate_print_buffer(char *buf, int size); - -static int buspirate_execute_queue(void) -{ - /* currently processed command */ - struct jtag_command *cmd = jtag_command_queue; - int scan_size; - enum scan_type type; - uint8_t *buffer; - - while (cmd) { - switch (cmd->type) { - case JTAG_RUNTEST: - DEBUG_JTAG_IO("runtest %i cycles, end in %s", - cmd->cmd.runtest->num_cycles, - tap_state_name(cmd->cmd.runtest - ->end_state)); - buspirate_end_state(cmd->cmd.runtest - ->end_state); - buspirate_runtest(cmd->cmd.runtest - ->num_cycles); - break; - case JTAG_TLR_RESET: - DEBUG_JTAG_IO("statemove end in %s", - tap_state_name(cmd->cmd.statemove - ->end_state)); - buspirate_end_state(cmd->cmd.statemove - ->end_state); - buspirate_state_move(); - break; - case JTAG_PATHMOVE: - DEBUG_JTAG_IO("pathmove: %i states, end in %s", - cmd->cmd.pathmove->num_states, - tap_state_name(cmd->cmd.pathmove - ->path[cmd->cmd.pathmove - ->num_states - 1])); - buspirate_path_move(cmd->cmd.pathmove - ->num_states, - cmd->cmd.pathmove->path); - break; - case JTAG_SCAN: - DEBUG_JTAG_IO("scan end in %s", - tap_state_name(cmd->cmd.scan - ->end_state)); - - buspirate_end_state(cmd->cmd.scan - ->end_state); - - scan_size = jtag_build_buffer(cmd->cmd.scan, - &buffer); - type = jtag_scan_type(cmd->cmd.scan); - buspirate_scan(cmd->cmd.scan->ir_scan, type, - buffer, scan_size, cmd->cmd.scan); - - break; - case JTAG_RESET: - DEBUG_JTAG_IO("reset trst: %i srst %i", - cmd->cmd.reset->trst, cmd->cmd.reset->srst); - - /* flush buffers, so we can reset */ - buspirate_tap_execute(); - - if (cmd->cmd.reset->trst == 1) - tap_set_state(TAP_RESET); - buspirate_reset(cmd->cmd.reset->trst, - cmd->cmd.reset->srst); - break; - case JTAG_SLEEP: - DEBUG_JTAG_IO("sleep %i", cmd->cmd.sleep->us); - buspirate_tap_execute(); - jtag_sleep(cmd->cmd.sleep->us); - break; - case JTAG_STABLECLOCKS: - DEBUG_JTAG_IO("stable clock %i cycles", cmd->cmd.stableclocks->num_cycles); - buspirate_stableclocks(cmd->cmd.stableclocks->num_cycles); - break; - default: - LOG_ERROR("BUG: unknown JTAG command type encountered"); - exit(-1); - } - - cmd = cmd->next; - } - - return buspirate_tap_execute(); -} - - -/* Returns true if successful, false if error. */ - -static bool read_and_discard_all_data(const int fd) -{ - /* LOG_INFO("Discarding any stale data from a previous connection..."); */ - - bool was_msg_already_printed = false; - - for ( ; ; ) { - char buffer[1024]; /* Any size will do, it's a trade-off between stack size and performance. */ - - const ssize_t read_count = read(fd, buffer, sizeof(buffer)); - - if (read_count == 0) { - /* This is the "end of file" or "connection closed at the other end" condition. */ - return true; - } - - if (read_count > 0) { - if (!was_msg_already_printed) { - LOG_INFO("Some stale data from a previous connection was discarded."); - was_msg_already_printed = true; - } - - continue; - } - - assert(read_count == -1); /* According to the specification. */ - - const int errno_code = errno; - - if (errno_code == EINTR) - continue; - - if (errno_code == EAGAIN || - errno_code == EWOULDBLOCK) { - /* We know that the file descriptor has been opened with O_NONBLOCK or O_NDELAY, - and these codes mean that there is no data to read at present. */ - return true; - } - - /* Some other error has occurred. */ - return false; - } -} - - -static int buspirate_init(void) -{ - if (buspirate_port == NULL) { - LOG_ERROR("You need to specify the serial port!"); - return ERROR_JTAG_INIT_FAILED; - } - - buspirate_fd = buspirate_serial_open(buspirate_port); - if (buspirate_fd == -1) { - LOG_ERROR("Could not open serial port"); - return ERROR_JTAG_INIT_FAILED; - } - - /* The Operating System or the device itself may deliver stale data from the last connection, - so discard all available bytes right after the new connection has been established. - After all, we are implementing here a master/slave protocol, so the slave should have nothing - to say until the master sends the first command. - - In the past, there was a tcflush() call in buspirate_serial_setspeed(), but that - was not enough. I guess you must actively read from the serial port to trigger any - data collection from the device and/or lower USB layers. If you disable the serial port - read timeout (if you set SHORT_TIMEOUT to 0), then the discarding does not work any more. - - Note that we are lowering the serial port timeout for this first read operation, - otherwise the normal initialisation would be delayed for too long. */ - - if (-1 == buspirate_serial_setspeed(buspirate_fd, SERIAL_NORMAL, SHORT_TIMEOUT)) { - LOG_ERROR("Error configuring the serial port."); - return ERROR_JTAG_INIT_FAILED; - } - - if (!read_and_discard_all_data(buspirate_fd)) { - LOG_ERROR("Error while attempting to discard any stale data right after establishing the connection."); - return ERROR_JTAG_INIT_FAILED; - } - - if (-1 == buspirate_serial_setspeed(buspirate_fd, SERIAL_NORMAL, NORMAL_TIMEOUT)) { - LOG_ERROR("Error configuring the serial port."); - return ERROR_JTAG_INIT_FAILED; - } - - buspirate_jtag_enable(buspirate_fd); - - if (buspirate_baudrate != SERIAL_NORMAL) - buspirate_jtag_set_speed(buspirate_fd, SERIAL_FAST); - - LOG_INFO("Buspirate Interface ready!"); - - buspirate_tap_init(); - buspirate_jtag_set_mode(buspirate_fd, buspirate_pinmode); - buspirate_jtag_set_feature(buspirate_fd, FEATURE_VREG, - (buspirate_vreg == 1) ? ACTION_ENABLE : ACTION_DISABLE); - buspirate_jtag_set_feature(buspirate_fd, FEATURE_PULLUP, - (buspirate_pullup == 1) ? ACTION_ENABLE : ACTION_DISABLE); - buspirate_reset(0, 0); - - return ERROR_OK; -} - -static int buspirate_quit(void) -{ - LOG_INFO("Shutting down buspirate."); - buspirate_jtag_set_mode(buspirate_fd, MODE_HIZ); - - buspirate_jtag_set_speed(buspirate_fd, SERIAL_NORMAL); - buspirate_jtag_reset(buspirate_fd); - - buspirate_serial_close(buspirate_fd); - - if (buspirate_port) { - free(buspirate_port); - buspirate_port = NULL; - } - return ERROR_OK; -} - -/* openocd command interface */ -COMMAND_HANDLER(buspirate_handle_adc_command) -{ - if (buspirate_fd == -1) - return ERROR_OK; - - /* send the command */ - buspirate_jtag_get_adcs(buspirate_fd); - - return ERROR_OK; - -} - -COMMAND_HANDLER(buspirate_handle_vreg_command) -{ - if (CMD_ARGC < 1) - return ERROR_COMMAND_SYNTAX_ERROR; - - if (atoi(CMD_ARGV[0]) == 1) - buspirate_vreg = 1; - else if (atoi(CMD_ARGV[0]) == 0) - buspirate_vreg = 0; - else - LOG_ERROR("usage: buspirate_vreg <1|0>"); - - return ERROR_OK; - -} - -COMMAND_HANDLER(buspirate_handle_pullup_command) -{ - if (CMD_ARGC < 1) - return ERROR_COMMAND_SYNTAX_ERROR; - - if (atoi(CMD_ARGV[0]) == 1) - buspirate_pullup = 1; - else if (atoi(CMD_ARGV[0]) == 0) - buspirate_pullup = 0; - else - LOG_ERROR("usage: buspirate_pullup <1|0>"); - - return ERROR_OK; - -} - -COMMAND_HANDLER(buspirate_handle_led_command) -{ - if (CMD_ARGC < 1) - return ERROR_COMMAND_SYNTAX_ERROR; - - if (atoi(CMD_ARGV[0]) == 1) { - /* enable led */ - buspirate_jtag_set_feature(buspirate_fd, FEATURE_LED, - ACTION_ENABLE); - } else if (atoi(CMD_ARGV[0]) == 0) { - /* disable led */ - buspirate_jtag_set_feature(buspirate_fd, FEATURE_LED, - ACTION_DISABLE); - } else { - LOG_ERROR("usage: buspirate_led <1|0>"); - } - - return ERROR_OK; - -} - -COMMAND_HANDLER(buspirate_handle_mode_command) -{ - if (CMD_ARGC < 1) - return ERROR_COMMAND_SYNTAX_ERROR; - - if (CMD_ARGV[0][0] == 'n') - buspirate_pinmode = MODE_JTAG; - else if (CMD_ARGV[0][0] == 'o') - buspirate_pinmode = MODE_JTAG_OD; - else - LOG_ERROR("usage: buspirate_mode "); - - return ERROR_OK; - -} - -COMMAND_HANDLER(buspirate_handle_speed_command) -{ - if (CMD_ARGC < 1) - return ERROR_COMMAND_SYNTAX_ERROR; - - if (CMD_ARGV[0][0] == 'n') - buspirate_baudrate = SERIAL_NORMAL; - else if (CMD_ARGV[0][0] == 'f') - buspirate_baudrate = SERIAL_FAST; - else - LOG_ERROR("usage: buspirate_speed "); - - return ERROR_OK; - -} - -COMMAND_HANDLER(buspirate_handle_port_command) -{ - if (CMD_ARGC < 1) - return ERROR_COMMAND_SYNTAX_ERROR; - - if (buspirate_port == NULL) - buspirate_port = strdup(CMD_ARGV[0]); - - return ERROR_OK; - -} - -static const struct command_registration buspirate_command_handlers[] = { - { - .name = "buspirate_adc", - .handler = &buspirate_handle_adc_command, - .mode = COMMAND_EXEC, - .help = "reads voltages on adc pins", - }, - { - .name = "buspirate_vreg", - .usage = "<1|0>", - .handler = &buspirate_handle_vreg_command, - .mode = COMMAND_CONFIG, - .help = "changes the state of voltage regulators", - }, - { - .name = "buspirate_pullup", - .usage = "<1|0>", - .handler = &buspirate_handle_pullup_command, - .mode = COMMAND_CONFIG, - .help = "changes the state of pullup", - }, - { - .name = "buspirate_led", - .usage = "<1|0>", - .handler = &buspirate_handle_led_command, - .mode = COMMAND_EXEC, - .help = "changes the state of led", - }, - { - .name = "buspirate_speed", - .usage = "", - .handler = &buspirate_handle_speed_command, - .mode = COMMAND_CONFIG, - .help = "speed of the interface", - }, - { - .name = "buspirate_mode", - .usage = "", - .handler = &buspirate_handle_mode_command, - .mode = COMMAND_CONFIG, - .help = "pin mode of the interface", - }, - { - .name = "buspirate_port", - .usage = "/dev/ttyUSB0", - .handler = &buspirate_handle_port_command, - .mode = COMMAND_CONFIG, - .help = "name of the serial port to open", - }, - COMMAND_REGISTRATION_DONE -}; - -struct jtag_interface buspirate_interface = { - .name = "buspirate", - .execute_queue = buspirate_execute_queue, - .commands = buspirate_command_handlers, - .init = buspirate_init, - .quit = buspirate_quit -}; - -/*************** jtag execute commands **********************/ -static void buspirate_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); - } -} - -static void buspirate_state_move(void) -{ - int i = 0, tms = 0; - uint8_t tms_scan = tap_get_tms_path(tap_get_state(), - tap_get_end_state()); - int tms_count = tap_get_tms_path_len(tap_get_state(), - tap_get_end_state()); - - for (i = 0; i < tms_count; i++) { - tms = (tms_scan >> i) & 1; - buspirate_tap_append(tms, 0); - } - - tap_set_state(tap_get_end_state()); -} - -static void buspirate_path_move(int num_states, tap_state_t *path) -{ - int i; - - for (i = 0; i < num_states; i++) { - if (tap_state_transition(tap_get_state(), false) == path[i]) { - buspirate_tap_append(0, 0); - } else if (tap_state_transition(tap_get_state(), true) - == path[i]) { - buspirate_tap_append(1, 0); - } 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]); - } - - tap_set_end_state(tap_get_state()); -} - -static void buspirate_runtest(int num_cycles) -{ - int i; - - 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) { - buspirate_end_state(TAP_IDLE); - buspirate_state_move(); - } - - for (i = 0; i < num_cycles; i++) - buspirate_tap_append(0, 0); - - DEBUG_JTAG_IO("runtest: cur_state %s end_state %s", - tap_state_name(tap_get_state()), - tap_state_name(tap_get_end_state())); - - /* finish in end_state */ - buspirate_end_state(saved_end_state); - if (tap_get_state() != tap_get_end_state()) - buspirate_state_move(); -} - -static void buspirate_scan(bool ir_scan, enum scan_type type, - uint8_t *buffer, int scan_size, struct scan_command *command) -{ - tap_state_t saved_end_state; - - buspirate_tap_make_space(1, scan_size+8); - /* is 8 correct ? (2 moves = 16) */ - - saved_end_state = tap_get_end_state(); - - buspirate_end_state(ir_scan ? TAP_IRSHIFT : TAP_DRSHIFT); - - /* Only move if we're not already there */ - if (tap_get_state() != tap_get_end_state()) - buspirate_state_move(); - - buspirate_tap_append_scan(scan_size, buffer, command); - - /* move to PAUSE */ - buspirate_tap_append(0, 0); - - /* restore the saved state */ - buspirate_end_state(saved_end_state); - tap_set_state(ir_scan ? TAP_IRPAUSE : TAP_DRPAUSE); - - if (tap_get_state() != tap_get_end_state()) - buspirate_state_move(); -} - -static void buspirate_stableclocks(int num_cycles) -{ - int i; - int tms = (tap_get_state() == TAP_RESET ? 1 : 0); - - buspirate_tap_make_space(0, num_cycles); - - for (i = 0; i < num_cycles; i++) - buspirate_tap_append(tms, 0); -} - -/************************* TAP related stuff **********/ - -/* This buffer size matches the maximum CMD_TAP_SHIFT bit length in the Bus Pirate firmware, - look for constant 0x2000 in OpenOCD.c . */ -#define BUSPIRATE_BUFFER_SIZE 1024 - -/* The old value of 32 scans was not enough to achieve near 100% utilisation ratio - for the current BUSPIRATE_BUFFER_SIZE value of 1024. - With 128 scans I am getting full USB 2.0 high speed packets (512 bytes long) when - using the JtagDue firmware on the Arduino Due instead of the Bus Pirate, which - amounts approximately to a 10% overall speed gain. Bigger packets should also - benefit the Bus Pirate, but the speed difference is much smaller. - Unfortunately, each 512-byte packet is followed by a 329-byte one, which is not ideal. - However, increasing BUSPIRATE_BUFFER_SIZE for the benefit of the JtagDue would - make it incompatible with the Bus Pirate firmware. */ -#define BUSPIRATE_MAX_PENDING_SCANS 128 - -static char tms_chain[BUSPIRATE_BUFFER_SIZE]; /* send */ -static char tdi_chain[BUSPIRATE_BUFFER_SIZE]; /* send */ -static int tap_chain_index; - -struct pending_scan_result /* this was stolen from arm-jtag-ew */ -{ - int first; /* First bit position in tdo_buffer to read */ - int length; /* Number of bits to read */ - struct scan_command *command; /* Corresponding scan command */ - uint8_t *buffer; -}; - -static struct pending_scan_result -tap_pending_scans[BUSPIRATE_MAX_PENDING_SCANS]; -static int tap_pending_scans_num; - -static void buspirate_tap_init(void) -{ - tap_chain_index = 0; - tap_pending_scans_num = 0; -} - -static int buspirate_tap_execute(void) -{ - static const int CMD_TAP_SHIFT_HEADER_LEN = 3; - - char tmp[4096]; - uint8_t *in_buf; - int i; - int fill_index = 0; - int ret; - int bytes_to_send; - - if (tap_chain_index <= 0) - return ERROR_OK; - - LOG_DEBUG("executing tap num bits = %i scans = %i", - tap_chain_index, tap_pending_scans_num); - - bytes_to_send = DIV_ROUND_UP(tap_chain_index, 8); - - tmp[0] = CMD_TAP_SHIFT; /* this command expects number of bits */ - tmp[1] = (char)(tap_chain_index >> 8); /* high */ - tmp[2] = (char)(tap_chain_index); /* low */ - - fill_index = CMD_TAP_SHIFT_HEADER_LEN; - for (i = 0; i < bytes_to_send; i++) { - tmp[fill_index] = tdi_chain[i]; - fill_index++; - tmp[fill_index] = tms_chain[i]; - fill_index++; - } - - /* jlink.c calls the routine below, which may be useful for debugging purposes. - For example, enabling this allows you to compare the log outputs from jlink.c - and from this module for JTAG development or troubleshooting purposes. */ - if (false) { - last_tap_state = jtag_debug_state_machine(tms_chain, tdi_chain, - tap_chain_index, last_tap_state); - } - - ret = buspirate_serial_write(buspirate_fd, tmp, CMD_TAP_SHIFT_HEADER_LEN + bytes_to_send*2); - if (ret != bytes_to_send*2+CMD_TAP_SHIFT_HEADER_LEN) { - LOG_ERROR("error writing :("); - return ERROR_JTAG_DEVICE_ERROR; - } - - ret = buspirate_serial_read(buspirate_fd, tmp, bytes_to_send + CMD_TAP_SHIFT_HEADER_LEN); - if (ret != bytes_to_send + CMD_TAP_SHIFT_HEADER_LEN) { - LOG_ERROR("error reading"); - return ERROR_FAIL; - } - in_buf = (uint8_t *)(&tmp[CMD_TAP_SHIFT_HEADER_LEN]); - - /* parse the scans */ - for (i = 0; i < tap_pending_scans_num; i++) { - uint8_t *buffer = tap_pending_scans[i].buffer; - int length = tap_pending_scans[i].length; - int first = tap_pending_scans[i].first; - struct scan_command *command = tap_pending_scans[i].command; - - /* copy bits from buffer */ - buf_set_buf(in_buf, first, buffer, 0, length); - - /* return buffer to higher level */ - if (jtag_read_buffer(buffer, command) != ERROR_OK) { - buspirate_tap_init(); - return ERROR_JTAG_QUEUE_FAILED; - } - - free(buffer); - } - buspirate_tap_init(); - return ERROR_OK; -} - -static void buspirate_tap_make_space(int scans, int bits) -{ - int have_scans = BUSPIRATE_MAX_PENDING_SCANS - tap_pending_scans_num; - int have_bits = BUSPIRATE_BUFFER_SIZE * 8 - tap_chain_index; - - if ((have_scans < scans) || (have_bits < bits)) - buspirate_tap_execute(); -} - -static void buspirate_tap_append(int tms, int tdi) -{ - int chain_index; - - buspirate_tap_make_space(0, 1); - chain_index = tap_chain_index / 8; - - if (chain_index < BUSPIRATE_BUFFER_SIZE) { - int bit_index = tap_chain_index % 8; - uint8_t bit = 1 << bit_index; - - if (0 == bit_index) { - /* Let's say that the TAP shift operation wants to shift 9 bits, - so we will be sending to the Bus Pirate a bit count of 9 but still - full 16 bits (2 bytes) of shift data. - If we don't clear all bits at this point, the last 7 bits will contain - random data from the last buffer contents, which is not pleasant to the eye. - Besides, the Bus Pirate (or some clone) may want to assert in debug builds - that, after consuming all significant data bits, the rest of them are zero. - Therefore, for aesthetic and for assert purposes, we clear all bits below. */ - tms_chain[chain_index] = 0; - tdi_chain[chain_index] = 0; - } - - if (tms) - tms_chain[chain_index] |= bit; - else - tms_chain[chain_index] &= ~bit; - - if (tdi) - tdi_chain[chain_index] |= bit; - else - tdi_chain[chain_index] &= ~bit; - - tap_chain_index++; - } else { - LOG_ERROR("tap_chain overflow, bad things will happen"); - /* Exit abruptly, like jlink.c does. After a buffer overflow we don't want - to carry on, as data will be corrupt. Another option would be to return - some error code at this point. */ - exit(-1); - } -} - -static void buspirate_tap_append_scan(int length, uint8_t *buffer, - struct scan_command *command) -{ - int i; - tap_pending_scans[tap_pending_scans_num].length = length; - tap_pending_scans[tap_pending_scans_num].buffer = buffer; - tap_pending_scans[tap_pending_scans_num].command = command; - tap_pending_scans[tap_pending_scans_num].first = tap_chain_index; - - for (i = 0; i < length; i++) { - int tms = (i < length-1 ? 0 : 1); - int tdi = (buffer[i/8] >> (i%8)) & 1; - buspirate_tap_append(tms, tdi); - } - tap_pending_scans_num++; -} - -/*************** jtag wrapper functions *********************/ - -/* (1) assert or (0) deassert reset lines */ -static void buspirate_reset(int trst, int srst) -{ - LOG_DEBUG("trst: %i, srst: %i", trst, srst); - - if (trst) - buspirate_jtag_set_feature(buspirate_fd, - FEATURE_TRST, ACTION_DISABLE); - else - buspirate_jtag_set_feature(buspirate_fd, - FEATURE_TRST, ACTION_ENABLE); - - if (srst) - buspirate_jtag_set_feature(buspirate_fd, - FEATURE_SRST, ACTION_DISABLE); - else - buspirate_jtag_set_feature(buspirate_fd, - FEATURE_SRST, ACTION_ENABLE); -} - -/*************** jtag lowlevel functions ********************/ -static void buspirate_jtag_enable(int fd) -{ - int ret; - char tmp[21] = { [0 ... 20] = 0x00 }; - int done = 0; - int cmd_sent = 0; - - LOG_DEBUG("Entering binary mode"); - buspirate_serial_write(fd, tmp, 20); - usleep(10000); - - /* reads 1 to n "BBIO1"s and one "OCD1" */ - while (!done) { - ret = buspirate_serial_read(fd, tmp, 4); - if (ret != 4) { - LOG_ERROR("Buspirate error. Is binary" - "/OpenOCD support enabled?"); - exit(-1); - } - if (strncmp(tmp, "BBIO", 4) == 0) { - ret = buspirate_serial_read(fd, tmp, 1); - if (ret != 1) { - LOG_ERROR("Buspirate did not answer correctly! " - "Do you have correct firmware?"); - exit(-1); - } - if (tmp[0] != '1') { - LOG_ERROR("Unsupported binary protocol"); - exit(-1); - } - if (cmd_sent == 0) { - cmd_sent = 1; - tmp[0] = CMD_ENTER_OOCD; - ret = buspirate_serial_write(fd, tmp, 1); - if (ret != 1) { - LOG_ERROR("error reading"); - exit(-1); - } - } - } else if (strncmp(tmp, "OCD1", 4) == 0) - done = 1; - else { - LOG_ERROR("Buspirate did not answer correctly! " - "Do you have correct firmware?"); - exit(-1); - } - } - -} - -static void buspirate_jtag_reset(int fd) -{ - char tmp[5]; - - tmp[0] = 0x00; /* exit OCD1 mode */ - buspirate_serial_write(fd, tmp, 1); - usleep(10000); - /* We ignore the return value here purposly, nothing we can do */ - buspirate_serial_read(fd, tmp, 5); - if (strncmp(tmp, "BBIO1", 5) == 0) { - tmp[0] = 0x0F; /* reset BP */ - buspirate_serial_write(fd, tmp, 1); - } else - LOG_ERROR("Unable to restart buspirate!"); -} - -static void buspirate_jtag_set_speed(int fd, char speed) -{ - int ret; - char tmp[2]; - char ack[2]; - - ack[0] = 0xAA; - ack[1] = 0x55; - - tmp[0] = CMD_UART_SPEED; - tmp[1] = speed; - buspirate_jtag_command(fd, tmp, 2); - - /* here the adapter changes speed, we need follow */ - if (-1 == buspirate_serial_setspeed(fd, speed, NORMAL_TIMEOUT)) { - LOG_ERROR("Error configuring the serial port."); - exit(-1); - } - - buspirate_serial_write(fd, ack, 2); - ret = buspirate_serial_read(fd, tmp, 2); - if (ret != 2) { - LOG_ERROR("Buspirate did not ack speed change"); - exit(-1); - } - if ((tmp[0] != CMD_UART_SPEED) || (tmp[1] != speed)) { - LOG_ERROR("Buspirate did not reply as expected to the speed change command"); - exit(-1); - } - LOG_INFO("Buspirate switched to %s mode", - (speed == SERIAL_NORMAL) ? "normal" : "FAST"); -} - - -static void buspirate_jtag_set_mode(int fd, char mode) -{ - char tmp[2]; - tmp[0] = CMD_PORT_MODE; - tmp[1] = mode; - buspirate_jtag_command(fd, tmp, 2); -} - -static void buspirate_jtag_set_feature(int fd, char feat, char action) -{ - char tmp[3]; - tmp[0] = CMD_FEATURE; - tmp[1] = feat; /* what */ - tmp[2] = action; /* action */ - buspirate_jtag_command(fd, tmp, 3); -} - -static void buspirate_jtag_get_adcs(int fd) -{ - uint8_t tmp[10]; - uint16_t a, b, c, d; - tmp[0] = CMD_READ_ADCS; - buspirate_jtag_command(fd, (char *)tmp, 1); - a = tmp[2] << 8 | tmp[3]; - b = tmp[4] << 8 | tmp[5]; - c = tmp[6] << 8 | tmp[7]; - d = tmp[8] << 8 | tmp[9]; - - LOG_INFO("ADC: ADC_Pin = %.02f VPullup = %.02f V33 = %.02f " - "V50 = %.02f", - ((float)a)/155.1515, ((float)b)/155.1515, - ((float)c)/155.1515, ((float)d)/155.1515); -} - -static unsigned char buspirate_jtag_command(int fd, - char *cmd, int cmdlen) -{ - int res; - int len = 0; - - res = buspirate_serial_write(fd, cmd, cmdlen); - - if ((cmd[0] == CMD_UART_SPEED) - || (cmd[0] == CMD_PORT_MODE) - || (cmd[0] == CMD_FEATURE) - || (cmd[0] == CMD_JTAG_SPEED)) - return 1; - - if (res == cmdlen) { - switch (cmd[0]) { - case CMD_READ_ADCS: - len = 10; /* 2*sizeof(char)+4*sizeof(uint16_t) */ - break; - case CMD_TAP_SHIFT: - len = cmdlen; - break; - default: - LOG_INFO("Wrong !"); - } - res = buspirate_serial_read(fd, cmd, len); - if (res > 0) - return (unsigned char)cmd[1]; - else - return -1; - } else - return -1; - return 0; -} - -/* low level serial port */ -/* TODO add support for WIN32 and others ! */ -static int buspirate_serial_open(char *port) -{ - int fd; - fd = open(buspirate_port, O_RDWR | O_NOCTTY | O_NDELAY); - return fd; -} - - -/* Returns -1 on error. */ - -static int buspirate_serial_setspeed(int fd, char speed, cc_t timeout) -{ - struct termios t_opt; - speed_t baud = (speed == SERIAL_FAST) ? B1000000 : B115200; - - /* set the serial port parameters */ - fcntl(fd, F_SETFL, 0); - if (0 != tcgetattr(fd, &t_opt)) - return -1; - - if (0 != cfsetispeed(&t_opt, baud)) - return -1; - - if (0 != cfsetospeed(&t_opt, baud)) - return -1; - - t_opt.c_cflag |= (CLOCAL | CREAD); - t_opt.c_cflag &= ~PARENB; - t_opt.c_cflag &= ~CSTOPB; - t_opt.c_cflag &= ~CSIZE; - t_opt.c_cflag |= CS8; - t_opt.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); - - /* The serial port may have been configured for human interaction with - the Bus Pirate console, but OpenOCD is going to use a binary protocol, - so make sure to turn off any CR/LF translation and the like. */ - t_opt.c_iflag &= ~(IXON | IXOFF | IXANY | INLCR | ICRNL); - - t_opt.c_oflag &= ~OPOST; - t_opt.c_cc[VMIN] = 0; - t_opt.c_cc[VTIME] = timeout; - - /* Note that, in the past, TCSANOW was used below instead of TCSADRAIN, - and CMD_UART_SPEED did not work properly then, at least with - the Bus Pirate v3.5 (USB). */ - if (0 != tcsetattr(fd, TCSADRAIN, &t_opt)) { - /* According to the Linux documentation, this is actually not enough - to detect errors, you need to call tcgetattr() and check that - all changes have been performed successfully. */ - return -1; - } - - return 0; -} - -static int buspirate_serial_write(int fd, char *buf, int size) -{ - int ret = 0; - - ret = write(fd, buf, size); - - LOG_DEBUG("size = %d ret = %d", size, ret); - buspirate_print_buffer(buf, size); - - if (ret != size) - LOG_ERROR("Error sending data"); - - return ret; -} - -static int buspirate_serial_read(int fd, char *buf, int size) -{ - int len = 0; - int ret = 0; - int timeout = 0; - - while (len < size) { - ret = read(fd, buf+len, size-len); - if (ret == -1) - return -1; - - if (ret == 0) { - timeout++; - - if (timeout >= 10) - break; - - continue; - } - - len += ret; - } - - LOG_DEBUG("should have read = %d actual size = %d", size, len); - buspirate_print_buffer(buf, len); - - if (len != size) - LOG_ERROR("Error reading data"); - - return len; -} - -static void buspirate_serial_close(int fd) -{ - close(fd); -} - -#define LINE_SIZE 81 -#define BYTES_PER_LINE 16 -static void buspirate_print_buffer(char *buf, int size) -{ - char line[LINE_SIZE]; - char tmp[10]; - int offset = 0; - - line[0] = 0; - while (offset < size) { - snprintf(tmp, 5, "%02x ", (uint8_t)buf[offset]); - offset++; - - strcat(line, tmp); - - if (offset % BYTES_PER_LINE == 0) { - LOG_DEBUG("%s", line); - line[0] = 0; - } - } - - if (line[0] != 0) - LOG_DEBUG("%s", line); -} diff --git a/src/jtag/drivers/cmsis_dap_usb.c b/src/jtag/drivers/cmsis_dap_usb.c deleted file mode 100644 index a07064be5..000000000 --- a/src/jtag/drivers/cmsis_dap_usb.c +++ /dev/null @@ -1,1630 +0,0 @@ -/*************************************************************************** - * 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 * - * * - * Copyright (C) 2013 by mike brown * - * mike@theshedworks.org.uk * - * * - * Copyright (C) 2013 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include -#include -#include - -#include - -/* - * See CMSIS-DAP documentation: - * Version 0.01 - Beta. - */ - -/* USB Config */ - -/* Known vid/pid pairs: - * VID 0xc251: Keil Software - * PID 0xf001: LPC-Link-II CMSIS_DAP - * PID 0xf002: OPEN-SDA CMSIS_DAP (Freedom Board) - * PID 0x2722: Keil ULINK2 CMSIS-DAP - * - * VID 0x0d28: mbed Software - * PID 0x0204: MBED CMSIS-DAP - */ - -#define MAX_USB_IDS 8 -/* vid = pid = 0 marks the end of the list */ -static uint16_t cmsis_dap_vid[MAX_USB_IDS + 1] = { 0 }; -static uint16_t cmsis_dap_pid[MAX_USB_IDS + 1] = { 0 }; -static wchar_t *cmsis_dap_serial; -static bool swd_mode; - -#define PACKET_SIZE (64 + 1) /* 64 bytes plus report id */ -#define USB_TIMEOUT 1000 - -/* CMSIS-DAP General Commands */ -#define CMD_DAP_INFO 0x00 -#define CMD_DAP_LED 0x01 -#define CMD_DAP_CONNECT 0x02 -#define CMD_DAP_DISCONNECT 0x03 -#define CMD_DAP_WRITE_ABORT 0x08 -#define CMD_DAP_DELAY 0x09 -#define CMD_DAP_RESET_TARGET 0x0A - -/* CMD_INFO */ -#define INFO_ID_VID 0x00 /* string */ -#define INFO_ID_PID 0x02 /* string */ -#define INFO_ID_SERNUM 0x03 /* string */ -#define INFO_ID_FW_VER 0x04 /* string */ -#define INFO_ID_TD_VEND 0x05 /* string */ -#define INFO_ID_TD_NAME 0x06 /* string */ -#define INFO_ID_CAPS 0xf0 /* byte */ -#define INFO_ID_PKT_CNT 0xfe /* byte */ -#define INFO_ID_PKT_SZ 0xff /* short */ - -#define INFO_CAPS_SWD 0x01 -#define INFO_CAPS_JTAG 0x02 - -/* CMD_LED */ -#define LED_ID_CONNECT 0x00 -#define LED_ID_RUN 0x01 - -#define LED_OFF 0x00 -#define LED_ON 0x01 - -/* CMD_CONNECT */ -#define CONNECT_DEFAULT 0x00 -#define CONNECT_SWD 0x01 -#define CONNECT_JTAG 0x02 - -/* CMSIS-DAP Common SWD/JTAG Commands */ -#define CMD_DAP_DELAY 0x09 -#define CMD_DAP_SWJ_PINS 0x10 -#define CMD_DAP_SWJ_CLOCK 0x11 -#define CMD_DAP_SWJ_SEQ 0x12 - -/* - * PINS - * Bit 0: SWCLK/TCK - * Bit 1: SWDIO/TMS - * Bit 2: TDI - * Bit 3: TDO - * Bit 5: nTRST - * Bit 7: nRESET - */ - -/* CMSIS-DAP SWD Commands */ -#define CMD_DAP_SWD_CONFIGURE 0x13 - -/* CMSIS-DAP JTAG Commands */ -#define CMD_DAP_JTAG_SEQ 0x14 -#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 -#define CMD_DAP_TFER_BLOCK 0x06 -#define CMD_DAP_TFER_ABORT 0x07 - -/* DAP Status Code */ -#define DAP_OK 0 -#define DAP_ERROR 0xFF - -/* CMSIS-DAP Vendor Commands - * None as yet... */ - -static const char * const info_caps_str[] = { - "SWD Supported", - "JTAG Supported" -}; - -/* max clock speed (kHz) */ -#define DAP_MAX_CLOCK 5000 - -struct cmsis_dap { - hid_device *dev_handle; - uint16_t packet_size; - uint16_t packet_count; - uint8_t *packet_buffer; - uint8_t caps; - uint8_t mode; -}; - -struct pending_transfer_result { - uint8_t cmd; - uint32_t data; - 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; - -static int cmsis_dap_usb_open(void) -{ - hid_device *dev = NULL; - int i; - struct hid_device_info *devs, *cur_dev; - unsigned short target_vid, target_pid; - wchar_t *target_serial = NULL; - - bool found = false; - bool serial_found = false; - - target_vid = 0; - target_pid = 0; - - /* - * The CMSIS-DAP specification stipulates: - * "The Product String must contain "CMSIS-DAP" somewhere in the string. This is used by the - * debuggers to identify a CMSIS-DAP compliant Debug Unit that is connected to a host computer." - */ - devs = hid_enumerate(0x0, 0x0); - cur_dev = devs; - while (NULL != cur_dev) { - if (0 == cmsis_dap_vid[0]) { - if (NULL == cur_dev->product_string) { - LOG_DEBUG("Cannot read product string of device 0x%x:0x%x", - cur_dev->vendor_id, cur_dev->product_id); - } else { - if (wcsstr(cur_dev->product_string, L"CMSIS-DAP")) { - /* if the user hasn't specified VID:PID *and* - * product string contains "CMSIS-DAP", pick it - */ - found = true; - } - } - } else { - /* otherwise, exhaustively compare against all VID:PID in list */ - for (i = 0; cmsis_dap_vid[i] || cmsis_dap_pid[i]; i++) { - if ((cmsis_dap_vid[i] == cur_dev->vendor_id) && (cmsis_dap_pid[i] == cur_dev->product_id)) - found = true; - } - - if (cmsis_dap_vid[i] || cmsis_dap_pid[i]) - found = true; - } - - if (found) { - /* we have found an adapter, so exit further checks */ - /* check serial number matches if given */ - if (cmsis_dap_serial != NULL) { - 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; - } - - if (NULL != cur_dev) { - target_vid = cur_dev->vendor_id; - target_pid = cur_dev->product_id; - if (serial_found) - target_serial = cmsis_dap_serial; - } - - hid_free_enumeration(devs); - - if (target_vid == 0 && target_pid == 0) { - LOG_ERROR("unable to find CMSIS-DAP device"); - return ERROR_FAIL; - } - - if (hid_init() != 0) { - LOG_ERROR("unable to open HIDAPI"); - return ERROR_FAIL; - } - - dev = hid_open(target_vid, target_pid, target_serial); - - if (dev == NULL) { - LOG_ERROR("unable to open CMSIS-DAP device 0x%x:0x%x", target_vid, target_pid); - return ERROR_FAIL; - } - - struct cmsis_dap *dap = malloc(sizeof(struct cmsis_dap)); - if (dap == NULL) { - LOG_ERROR("unable to allocate memory"); - return ERROR_FAIL; - } - - dap->dev_handle = dev; - dap->caps = 0; - dap->mode = 0; - - cmsis_dap_handle = dap; - - /* allocate default packet buffer, may be changed later. - * currently with HIDAPI we have no way of getting the output report length - * without this info we cannot communicate with the adapter. - * For the moment we ahve to hard code the packet size */ - - int packet_size = PACKET_SIZE; - - /* atmel cmsis-dap uses 512 byte reports */ - /* TODO: HID report descriptor should be parsed instead of - * hardcoding a match by VID */ - if (target_vid == 0x03eb) - packet_size = 512 + 1; - - cmsis_dap_handle->packet_buffer = malloc(packet_size); - cmsis_dap_handle->packet_size = packet_size; - - if (cmsis_dap_handle->packet_buffer == NULL) { - LOG_ERROR("unable to allocate memory"); - return ERROR_FAIL; - } - - return ERROR_OK; -} - -static void cmsis_dap_usb_close(struct cmsis_dap *dap) -{ - hid_close(dap->dev_handle); - hid_exit(); - - free(cmsis_dap_handle->packet_buffer); - free(cmsis_dap_handle); - cmsis_dap_handle = NULL; - free(cmsis_dap_serial); - cmsis_dap_serial = NULL; - free(pending_transfers); - pending_transfers = NULL; - - return; -} - -/* 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); - - /* write data to device */ - int retval = hid_write(dap->dev_handle, dap->packet_buffer, dap->packet_size); - if (retval == -1) { - LOG_ERROR("error writing data: %ls", hid_error(dap->dev_handle)); - return ERROR_FAIL; - } - - /* get reply */ - retval = hid_read_timeout(dap->dev_handle, dap->packet_buffer, dap->packet_size, USB_TIMEOUT); - if (retval == -1 || retval == 0) { - LOG_DEBUG("error reading data: %ls", hid_error(dap->dev_handle)); - return ERROR_FAIL; - } - - return ERROR_OK; -} - -static int cmsis_dap_cmd_DAP_SWJ_Pins(uint8_t pins, uint8_t mask, uint32_t delay, uint8_t *input) -{ - int retval; - uint8_t *buffer = cmsis_dap_handle->packet_buffer; - - buffer[0] = 0; /* report number */ - buffer[1] = CMD_DAP_SWJ_PINS; - buffer[2] = pins; - buffer[3] = mask; - buffer[4] = delay & 0xff; - buffer[5] = (delay >> 8) & 0xff; - buffer[6] = (delay >> 16) & 0xff; - buffer[7] = (delay >> 24) & 0xff; - retval = cmsis_dap_usb_xfer(cmsis_dap_handle, 8); - - if (retval != ERROR_OK) { - LOG_ERROR("CMSIS-DAP command CMD_DAP_SWJ_PINS failed."); - return ERROR_JTAG_DEVICE_ERROR; - } - - if (input) - *input = buffer[1]; - - return ERROR_OK; -} - -static int cmsis_dap_cmd_DAP_SWJ_Clock(uint32_t swj_clock) -{ - int retval; - uint8_t *buffer = cmsis_dap_handle->packet_buffer; - - /* set clock in Hz */ - swj_clock *= 1000; - buffer[0] = 0; /* report number */ - buffer[1] = CMD_DAP_SWJ_CLOCK; - buffer[2] = swj_clock & 0xff; - buffer[3] = (swj_clock >> 8) & 0xff; - buffer[4] = (swj_clock >> 16) & 0xff; - buffer[5] = (swj_clock >> 24) & 0xff; - retval = cmsis_dap_usb_xfer(cmsis_dap_handle, 6); - - if (retval != ERROR_OK || buffer[1] != DAP_OK) { - LOG_ERROR("CMSIS-DAP command CMD_DAP_SWJ_CLOCK failed."); - return ERROR_JTAG_DEVICE_ERROR; - } - - 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; - uint8_t *buffer = cmsis_dap_handle->packet_buffer; - - buffer[0] = 0; /* report number */ - buffer[1] = CMD_DAP_INFO; - buffer[2] = info; - retval = cmsis_dap_usb_xfer(cmsis_dap_handle, 3); - - if (retval != ERROR_OK) { - LOG_ERROR("CMSIS-DAP command CMD_INFO failed."); - return ERROR_JTAG_DEVICE_ERROR; - } - - *data = &(buffer[1]); - - return ERROR_OK; -} - -static int cmsis_dap_cmd_DAP_LED(uint8_t leds) -{ - int retval; - uint8_t *buffer = cmsis_dap_handle->packet_buffer; - - buffer[0] = 0; /* report number */ - buffer[1] = CMD_DAP_LED; - buffer[2] = 0x00; - buffer[3] = leds; - retval = cmsis_dap_usb_xfer(cmsis_dap_handle, 4); - - if (retval != ERROR_OK || buffer[1] != 0x00) { - LOG_ERROR("CMSIS-DAP command CMD_LED failed."); - return ERROR_JTAG_DEVICE_ERROR; - } - - return ERROR_OK; -} - -static int cmsis_dap_cmd_DAP_Connect(uint8_t mode) -{ - int retval; - uint8_t *buffer = cmsis_dap_handle->packet_buffer; - - buffer[0] = 0; /* report number */ - buffer[1] = CMD_DAP_CONNECT; - buffer[2] = mode; - retval = cmsis_dap_usb_xfer(cmsis_dap_handle, 3); - - if (retval != ERROR_OK) { - LOG_ERROR("CMSIS-DAP command CMD_CONNECT failed."); - return ERROR_JTAG_DEVICE_ERROR; - } - - if (buffer[1] != mode) { - LOG_ERROR("CMSIS-DAP failed to connect in mode (%d)", mode); - return ERROR_JTAG_DEVICE_ERROR; - } - - return ERROR_OK; -} - -static int cmsis_dap_cmd_DAP_Disconnect(void) -{ - int retval; - uint8_t *buffer = cmsis_dap_handle->packet_buffer; - - buffer[0] = 0; /* report number */ - buffer[1] = CMD_DAP_DISCONNECT; - retval = cmsis_dap_usb_xfer(cmsis_dap_handle, 2); - - if (retval != ERROR_OK || buffer[1] != DAP_OK) { - LOG_ERROR("CMSIS-DAP command CMD_DISCONNECT failed."); - return ERROR_JTAG_DEVICE_ERROR; - } - - return ERROR_OK; -} - -static int cmsis_dap_cmd_DAP_TFER_Configure(uint8_t idle, uint16_t retry_count, uint16_t match_retry) -{ - int retval; - uint8_t *buffer = cmsis_dap_handle->packet_buffer; - - buffer[0] = 0; /* report number */ - buffer[1] = CMD_DAP_TFER_CONFIGURE; - buffer[2] = idle; - buffer[3] = retry_count & 0xff; - buffer[4] = (retry_count >> 8) & 0xff; - buffer[5] = match_retry & 0xff; - buffer[6] = (match_retry >> 8) & 0xff; - retval = cmsis_dap_usb_xfer(cmsis_dap_handle, 7); - - if (retval != ERROR_OK || buffer[1] != DAP_OK) { - LOG_ERROR("CMSIS-DAP command CMD_TFER_Configure failed."); - return ERROR_JTAG_DEVICE_ERROR; - } - - return ERROR_OK; -} - -static int cmsis_dap_cmd_DAP_SWD_Configure(uint8_t cfg) -{ - int retval; - uint8_t *buffer = cmsis_dap_handle->packet_buffer; - - buffer[0] = 0; /* report number */ - buffer[1] = CMD_DAP_SWD_CONFIGURE; - buffer[2] = cfg; - retval = cmsis_dap_usb_xfer(cmsis_dap_handle, 3); - - if (retval != ERROR_OK || buffer[1] != DAP_OK) { - LOG_ERROR("CMSIS-DAP command CMD_SWD_Configure failed."); - return ERROR_JTAG_DEVICE_ERROR; - } - - return ERROR_OK; -} - -#if 0 -static int cmsis_dap_cmd_DAP_Delay(uint16_t delay_us) -{ - int retval; - uint8_t *buffer = cmsis_dap_handle->packet_buffer; - - buffer[0] = 0; /* report number */ - buffer[1] = CMD_DAP_DELAY; - buffer[2] = delay_us & 0xff; - buffer[3] = (delay_us >> 8) & 0xff; - retval = cmsis_dap_usb_xfer(cmsis_dap_handle, 4); - - if (retval != ERROR_OK || buffer[1] != DAP_OK) { - LOG_ERROR("CMSIS-DAP command CMD_Delay failed."); - return ERROR_JTAG_DEVICE_ERROR; - } - - return ERROR_OK; -} -#endif - -static int cmsis_dap_swd_run_queue(void) -{ - uint8_t *buffer = cmsis_dap_handle->packet_buffer; - - LOG_DEBUG("Executing %d queued transactions", pending_transfer_count); - - if (queued_retval != ERROR_OK) { - LOG_DEBUG("Skipping due to previous errors: %d", queued_retval); - goto skip; - } - - if (!pending_transfer_count) - goto skip; - - size_t idx = 0; - buffer[idx++] = 0; /* report number */ - buffer[idx++] = CMD_DAP_TFER; - buffer[idx++] = 0x00; /* DAP Index */ - buffer[idx++] = pending_transfer_count; - - for (int i = 0; i < pending_transfer_count; i++) { - uint8_t cmd = pending_transfers[i].cmd; - uint32_t data = pending_transfers[i].data; - - LOG_DEBUG("%s %s reg %x %"PRIx32, - cmd & SWD_CMD_APnDP ? "AP" : "DP", - cmd & SWD_CMD_RnW ? "read" : "write", - (cmd & SWD_CMD_A32) >> 1, data); - - /* When proper WAIT handling is implemented in the - * common SWD framework, this kludge can be - * removed. However, this might lead to minor - * performance degradation as the adapter wouldn't be - * able to automatically retry anything (because ARM - * has forgotten to implement sticky error flags - * clearing). See also comments regarding - * cmsis_dap_cmd_DAP_TFER_Configure() and - * cmsis_dap_cmd_DAP_SWD_Configure() in - * cmsis_dap_init(). - */ - if (!(cmd & SWD_CMD_RnW) && - !(cmd & SWD_CMD_APnDP) && - (cmd & SWD_CMD_A32) >> 1 == DP_CTRL_STAT && - (data & CORUNDETECT)) { - LOG_DEBUG("refusing to enable sticky overrun detection"); - data &= ~CORUNDETECT; - } - - buffer[idx++] = (cmd >> 1) & 0x0f; - if (!(cmd & SWD_CMD_RnW)) { - buffer[idx++] = (data) & 0xff; - buffer[idx++] = (data >> 8) & 0xff; - buffer[idx++] = (data >> 16) & 0xff; - buffer[idx++] = (data >> 24) & 0xff; - } - } - - queued_retval = cmsis_dap_usb_xfer(cmsis_dap_handle, idx); - if (queued_retval != ERROR_OK) - goto skip; - - idx = 2; - uint8_t ack = buffer[idx] & 0x07; - if (ack != SWD_ACK_OK || (buffer[idx] & 0x08)) { - LOG_DEBUG("SWD ack not OK: %d %s", buffer[idx-1], - ack == SWD_ACK_WAIT ? "WAIT" : ack == SWD_ACK_FAULT ? "FAULT" : "JUNK"); - queued_retval = ack == SWD_ACK_WAIT ? ERROR_WAIT : ERROR_FAIL; - goto skip; - } - idx++; - - if (pending_transfer_count != buffer[1]) - LOG_ERROR("CMSIS-DAP transfer count mismatch: expected %d, got %d", - pending_transfer_count, buffer[1]); - - for (int i = 0; i < buffer[1]; i++) { - if (pending_transfers[i].cmd & SWD_CMD_RnW) { - static uint32_t last_read; - uint32_t data = le_to_h_u32(&buffer[idx]); - uint32_t tmp = data; - idx += 4; - - LOG_DEBUG("Read result: %"PRIx32, data); - - /* Imitate posted AP reads */ - if ((pending_transfers[i].cmd & SWD_CMD_APnDP) || - ((pending_transfers[i].cmd & SWD_CMD_A32) >> 1 == DP_RDBUFF)) { - tmp = last_read; - last_read = data; - } - - if (pending_transfers[i].buffer) - *(uint32_t *)pending_transfers[i].buffer = tmp; - } - } - -skip: - pending_transfer_count = 0; - int retval = queued_retval; - queued_retval = ERROR_OK; - - return retval; -} - -static void cmsis_dap_swd_queue_cmd(uint8_t cmd, uint32_t *dst, uint32_t data) -{ - if (pending_transfer_count == pending_queue_len) { - /* Not enough room in the queue. Run the queue. */ - queued_retval = cmsis_dap_swd_run_queue(); - } - - if (queued_retval != ERROR_OK) - return; - - pending_transfers[pending_transfer_count].data = data; - pending_transfers[pending_transfer_count].cmd = cmd; - if (cmd & SWD_CMD_RnW) { - /* Queue a read transaction */ - pending_transfers[pending_transfer_count].buffer = dst; - } - pending_transfer_count++; -} - -static void cmsis_dap_swd_write_reg(uint8_t cmd, uint32_t value, uint32_t ap_delay_clk) -{ - assert(!(cmd & SWD_CMD_RnW)); - cmsis_dap_swd_queue_cmd(cmd, NULL, value); -} - -static void cmsis_dap_swd_read_reg(uint8_t cmd, uint32_t *value, uint32_t ap_delay_clk) -{ - assert(cmd & SWD_CMD_RnW); - cmsis_dap_swd_queue_cmd(cmd, value, 0); -} - -static int cmsis_dap_get_version_info(void) -{ - uint8_t *data; - - /* INFO_ID_FW_VER - string */ - int retval = cmsis_dap_cmd_DAP_Info(INFO_ID_FW_VER, &data); - if (retval != ERROR_OK) - return retval; - - if (data[0]) /* strlen */ - LOG_INFO("CMSIS-DAP: FW Version = %s", &data[1]); - - return ERROR_OK; -} - -static int cmsis_dap_get_caps_info(void) -{ - uint8_t *data; - - /* INFO_ID_CAPS - byte */ - int retval = cmsis_dap_cmd_DAP_Info(INFO_ID_CAPS, &data); - if (retval != ERROR_OK) - return retval; - - if (data[0] == 1) { - uint8_t caps = data[1]; - - cmsis_dap_handle->caps = caps; - - if (caps & INFO_CAPS_SWD) - LOG_INFO("CMSIS-DAP: %s", info_caps_str[0]); - if (caps & INFO_CAPS_JTAG) - LOG_INFO("CMSIS-DAP: %s", info_caps_str[1]); - } - - return ERROR_OK; -} - -static int cmsis_dap_get_status(void) -{ - uint8_t d; - - int retval = cmsis_dap_cmd_DAP_SWJ_Pins(0, 0, 0, &d); - - 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 */ - } - - return retval; -} - -static int cmsis_dap_swd_switch_seq(enum swd_special_seq seq) -{ - const uint8_t *s; - unsigned int s_len; - int retval; - - /* First disconnect before connecting, Atmel EDBG needs it for SAMD/R/L/C */ - cmsis_dap_cmd_DAP_Disconnect(); - - /* When we are reconnecting, DAP_Connect needs to be rerun, at - * least on Keil ULINK-ME */ - retval = cmsis_dap_cmd_DAP_Connect(seq == LINE_RESET || seq == JTAG_TO_SWD ? - CONNECT_SWD : CONNECT_JTAG); - if (retval != ERROR_OK) - return retval; - - switch (seq) { - case LINE_RESET: - LOG_DEBUG("SWD line reset"); - s = swd_seq_line_reset; - s_len = swd_seq_line_reset_len; - break; - case JTAG_TO_SWD: - LOG_DEBUG("JTAG-to-SWD"); - s = swd_seq_jtag_to_swd; - s_len = swd_seq_jtag_to_swd_len; - break; - case SWD_TO_JTAG: - LOG_DEBUG("SWD-to-JTAG"); - s = swd_seq_swd_to_jtag; - s_len = swd_seq_swd_to_jtag_len; - break; - default: - LOG_ERROR("Sequence %d not supported", seq); - return ERROR_FAIL; - } - - return cmsis_dap_cmd_DAP_SWJ_Sequence(s_len, s); -} - -static int cmsis_dap_swd_open(void) -{ - int retval; - - if (cmsis_dap_handle == NULL) { - /* SWD init */ - retval = cmsis_dap_usb_open(); - if (retval != ERROR_OK) - return retval; - - retval = cmsis_dap_get_caps_info(); - if (retval != ERROR_OK) - return retval; - } - - if (!(cmsis_dap_handle->caps & INFO_CAPS_SWD)) { - LOG_ERROR("CMSIS-DAP: SWD not supported"); - return ERROR_JTAG_DEVICE_ERROR; - } - - retval = cmsis_dap_cmd_DAP_Connect(CONNECT_SWD); - if (retval != ERROR_OK) - return retval; - - /* Add more setup here.??... */ - - LOG_INFO("CMSIS-DAP: Interface Initialised (SWD)"); - return ERROR_OK; -} - -static int cmsis_dap_init(void) -{ - int retval; - uint8_t *data; - - if (swd_mode) { - retval = cmsis_dap_swd_open(); - if (retval != ERROR_OK) - return retval; - } - - if (cmsis_dap_handle == NULL) { - - /* JTAG init */ - retval = cmsis_dap_usb_open(); - if (retval != ERROR_OK) - return retval; - - retval = cmsis_dap_get_caps_info(); - if (retval != ERROR_OK) - return retval; - - /* Connect in JTAG mode */ - if (!(cmsis_dap_handle->caps & INFO_CAPS_JTAG)) { - LOG_ERROR("CMSIS-DAP: JTAG not supported"); - return ERROR_JTAG_DEVICE_ERROR; - } - - retval = cmsis_dap_cmd_DAP_Connect(CONNECT_JTAG); - if (retval != ERROR_OK) - return retval; - - LOG_INFO("CMSIS-DAP: Interface Initialised (JTAG)"); - } - - retval = cmsis_dap_get_version_info(); - if (retval != ERROR_OK) - return retval; - - /* INFO_ID_PKT_SZ - short */ - retval = cmsis_dap_cmd_DAP_Info(INFO_ID_PKT_SZ, &data); - if (retval != ERROR_OK) - return retval; - - if (data[0] == 2) { /* short */ - uint16_t pkt_sz = data[1] + (data[2] << 8); - - /* 4 bytes of command header + 5 bytes per register - * write. For bulk read sequences just 4 bytes are - * needed per transfer, so this is suboptimal. */ - pending_queue_len = (pkt_sz - 4) / 5; - pending_transfers = malloc(pending_queue_len * sizeof(*pending_transfers)); - if (!pending_transfers) { - LOG_ERROR("Unable to allocate memory for CMSIS-DAP queue"); - return ERROR_FAIL; - } - - if (cmsis_dap_handle->packet_size != pkt_sz + 1) { - /* reallocate buffer */ - cmsis_dap_handle->packet_size = pkt_sz + 1; - cmsis_dap_handle->packet_buffer = realloc(cmsis_dap_handle->packet_buffer, - cmsis_dap_handle->packet_size); - if (cmsis_dap_handle->packet_buffer == NULL) { - LOG_ERROR("unable to reallocate memory"); - return ERROR_FAIL; - } - } - - LOG_DEBUG("CMSIS-DAP: Packet Size = %" PRId16, pkt_sz); - } - - /* INFO_ID_PKT_CNT - byte */ - retval = cmsis_dap_cmd_DAP_Info(INFO_ID_PKT_CNT, &data); - if (retval != ERROR_OK) - return retval; - - if (data[0] == 1) { /* byte */ - uint16_t pkt_cnt = data[1]; - cmsis_dap_handle->packet_count = pkt_cnt; - LOG_DEBUG("CMSIS-DAP: Packet Count = %" PRId16, pkt_cnt); - } - - retval = cmsis_dap_get_status(); - if (retval != ERROR_OK) - return ERROR_FAIL; - - /* Now try to connect to the target - * TODO: This is all SWD only @ present */ - retval = cmsis_dap_cmd_DAP_SWJ_Clock(jtag_get_speed_khz()); - if (retval != ERROR_OK) - return ERROR_FAIL; - - /* Ask CMSIS-DAP to automatically retry on receiving WAIT for - * up to 64 times. This must be changed to 0 if sticky - * overrun detection is enabled. */ - retval = cmsis_dap_cmd_DAP_TFER_Configure(0, 64, 0); - if (retval != ERROR_OK) - return ERROR_FAIL; - /* Data Phase (bit 2) must be set to 1 if sticky overrun - * detection is enabled */ - retval = cmsis_dap_cmd_DAP_SWD_Configure(0); /* 1 TRN, no Data Phase */ - if (retval != ERROR_OK) - return ERROR_FAIL; - - retval = cmsis_dap_cmd_DAP_LED(0x03); /* Both LEDs on */ - if (retval != ERROR_OK) - return ERROR_FAIL; - - /* support connecting with srst asserted */ - 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) { - retval = cmsis_dap_cmd_DAP_SWJ_Pins(0, (1 << 7), 0, NULL); - if (retval != ERROR_OK) - return ERROR_FAIL; - LOG_INFO("Connecting under reset"); - } - } - - cmsis_dap_cmd_DAP_LED(0x00); /* Both LEDs off */ - - LOG_INFO("CMSIS-DAP: Interface ready"); - - return ERROR_OK; -} - -static int cmsis_dap_swd_init(void) -{ - swd_mode = true; - return ERROR_OK; -} - -static int cmsis_dap_quit(void) -{ - cmsis_dap_cmd_DAP_Disconnect(); - cmsis_dap_cmd_DAP_LED(0x00); /* Both LEDs off */ - - cmsis_dap_usb_close(cmsis_dap_handle); - - return ERROR_OK; -} - -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); - if (retval != ERROR_OK) - LOG_ERROR("CMSIS-DAP: Interface reset failed"); -} - -static void cmsis_dap_execute_sleep(struct jtag_command *cmd) -{ -#if 0 - int retval = cmsis_dap_cmd_DAP_Delay(cmd->cmd.sleep->us); - if (retval != ERROR_OK) -#endif - 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 0x%X encountered", cmd->type); - exit(-1); - } -} - -static int cmsis_dap_execute_queue(void) -{ - struct jtag_command *cmd = jtag_command_queue; - - while (cmd != NULL) { - cmsis_dap_execute_command(cmd); - 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 == 0) { - LOG_INFO("RTCK not supported"); - return ERROR_JTAG_NOT_IMPLEMENTED; - } - - return cmsis_dap_cmd_DAP_SWJ_Clock(speed); -} - -static int cmsis_dap_speed_div(int speed, int *khz) -{ - *khz = speed; - return ERROR_OK; -} - -static int cmsis_dap_khz(int khz, int *jtag_speed) -{ - *jtag_speed = khz; - return ERROR_OK; -} - -static int_least32_t cmsis_dap_swd_frequency(int_least32_t hz) -{ - if (hz > 0) - cmsis_dap_speed(hz / 1000); - - return hz; -} - - -COMMAND_HANDLER(cmsis_dap_handle_info_command) -{ - if (cmsis_dap_get_version_info() == ERROR_OK) - cmsis_dap_get_status(); - - return ERROR_OK; -} - -COMMAND_HANDLER(cmsis_dap_handle_vid_pid_command) -{ - if (CMD_ARGC > MAX_USB_IDS * 2) { - LOG_WARNING("ignoring extra IDs in cmsis_dap_vid_pid " - "(maximum is %d pairs)", MAX_USB_IDS); - CMD_ARGC = MAX_USB_IDS * 2; - } - if (CMD_ARGC < 2 || (CMD_ARGC & 1)) { - LOG_WARNING("incomplete cmsis_dap_vid_pid configuration directive"); - if (CMD_ARGC < 2) - return ERROR_COMMAND_SYNTAX_ERROR; - /* remove the incomplete trailing id */ - CMD_ARGC -= 1; - } - - unsigned i; - for (i = 0; i < CMD_ARGC; i += 2) { - COMMAND_PARSE_NUMBER(u16, CMD_ARGV[i], cmsis_dap_vid[i >> 1]); - COMMAND_PARSE_NUMBER(u16, CMD_ARGV[i + 1], cmsis_dap_pid[i >> 1]); - } - - /* - * Explicitly terminate, in case there are multiples instances of - * cmsis_dap_vid_pid. - */ - cmsis_dap_vid[i >> 1] = cmsis_dap_pid[i >> 1] = 0; - - return ERROR_OK; -} - -COMMAND_HANDLER(cmsis_dap_handle_serial_command) -{ - if (CMD_ARGC == 1) { - size_t len = mbstowcs(NULL, CMD_ARGV[0], 0); - cmsis_dap_serial = calloc(len + 1, sizeof(wchar_t)); - if (cmsis_dap_serial == NULL) { - LOG_ERROR("unable to allocate memory"); - return ERROR_OK; - } - if (mbstowcs(cmsis_dap_serial, CMD_ARGV[0], len + 1) == (size_t)-1) { - free(cmsis_dap_serial); - cmsis_dap_serial = NULL; - LOG_ERROR("unable to convert serial"); - } - } else { - LOG_ERROR("expected exactly one argument to cmsis_dap_serial "); - } - - return ERROR_OK; -} - -static const struct command_registration cmsis_dap_subcommand_handlers[] = { - { - .name = "info", - .handler = &cmsis_dap_handle_info_command, - .mode = COMMAND_EXEC, - .usage = "", - .help = "show cmsis-dap info", - }, - COMMAND_REGISTRATION_DONE -}; - -static const struct command_registration cmsis_dap_command_handlers[] = { - { - .name = "cmsis-dap", - .mode = COMMAND_ANY, - .help = "perform CMSIS-DAP management", - .usage = "", - .chain = cmsis_dap_subcommand_handlers, - }, - { - .name = "cmsis_dap_vid_pid", - .handler = &cmsis_dap_handle_vid_pid_command, - .mode = COMMAND_CONFIG, - .help = "the vendor ID and product ID of the CMSIS-DAP device", - .usage = "(vid pid)* ", - }, - { - .name = "cmsis_dap_serial", - .handler = &cmsis_dap_handle_serial_command, - .mode = COMMAND_CONFIG, - .help = "set the serial number of the adapter", - .usage = "serial_string", - }, - COMMAND_REGISTRATION_DONE -}; - -static const struct swd_driver cmsis_dap_swd_driver = { - .init = cmsis_dap_swd_init, - .frequency = cmsis_dap_swd_frequency, - .switch_seq = cmsis_dap_swd_switch_seq, - .read_reg = cmsis_dap_swd_read_reg, - .write_reg = cmsis_dap_swd_write_reg, - .run = cmsis_dap_swd_run_queue, -}; - -static const char * const cmsis_dap_transport[] = { "swd", "jtag", NULL }; - -struct jtag_interface cmsis_dap_interface = { - .name = "cmsis-dap", - .commands = cmsis_dap_command_handlers, - .swd = &cmsis_dap_swd_driver, - .transports = cmsis_dap_transport, - - .execute_queue = cmsis_dap_execute_queue, - .speed = cmsis_dap_speed, - .speed_div = cmsis_dap_speed_div, - .khz = cmsis_dap_khz, - .init = cmsis_dap_init, - .quit = cmsis_dap_quit, -}; diff --git a/src/jtag/drivers/driver.c b/src/jtag/drivers/driver.c deleted file mode 100644 index daf7cd426..000000000 --- a/src/jtag/drivers/driver.c +++ /dev/null @@ -1,421 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * Copyright (C) 2007-2010 Øyvind Harboe * - * oyvind.harboe@zylin.com * - * * - * Copyright (C) 2009 SoftPLC Corporation * - * http://softplc.com * - * dick@softplc.com * - * * - * Copyright (C) 2009 Zachary T Welch * - * zw@superlucidity.net * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include -#include -#include - -struct jtag_callback_entry { - struct jtag_callback_entry *next; - - jtag_callback_t callback; - jtag_callback_data_t data0; - jtag_callback_data_t data1; - jtag_callback_data_t data2; - jtag_callback_data_t data3; -}; - -static struct jtag_callback_entry *jtag_callback_queue_head; -static struct jtag_callback_entry *jtag_callback_queue_tail; - -static void jtag_callback_queue_reset(void) -{ - jtag_callback_queue_head = NULL; - jtag_callback_queue_tail = NULL; -} - -/** - * Copy a struct scan_field for insertion into the queue. - * - * This allocates a new copy of out_value using cmd_queue_alloc. - */ -static void cmd_queue_scan_field_clone(struct scan_field *dst, const struct scan_field *src) -{ - dst->num_bits = src->num_bits; - dst->out_value = buf_cpy(src->out_value, cmd_queue_alloc(DIV_ROUND_UP(src->num_bits, 8)), src->num_bits); - dst->in_value = src->in_value; -} - -/** - * see jtag_add_ir_scan() - * - */ -int interface_jtag_add_ir_scan(struct jtag_tap *active, - const struct scan_field *in_fields, tap_state_t state) -{ - size_t num_taps = jtag_tap_count_enabled(); - - struct jtag_command *cmd = cmd_queue_alloc(sizeof(struct jtag_command)); - struct scan_command *scan = cmd_queue_alloc(sizeof(struct scan_command)); - struct scan_field *out_fields = cmd_queue_alloc(num_taps * sizeof(struct scan_field)); - - jtag_queue_command(cmd); - - cmd->type = JTAG_SCAN; - cmd->cmd.scan = scan; - - scan->ir_scan = true; - scan->num_fields = num_taps; /* one field per device */ - scan->fields = out_fields; - scan->end_state = state; - - struct scan_field *field = out_fields; /* keep track where we insert data */ - - /* loop over all enabled TAPs */ - - for (struct jtag_tap *tap = jtag_tap_next_enabled(NULL); tap != NULL; tap = jtag_tap_next_enabled(tap)) { - /* search the input field list for fields for the current TAP */ - - if (tap == active) { - /* if TAP is listed in input fields, copy the value */ - tap->bypass = 0; - - cmd_queue_scan_field_clone(field, in_fields); - } else { - /* if a TAP isn't listed in input fields, set it to BYPASS */ - - tap->bypass = 1; - - field->num_bits = tap->ir_length; - field->out_value = buf_set_ones(cmd_queue_alloc(DIV_ROUND_UP(tap->ir_length, 8)), tap->ir_length); - field->in_value = NULL; /* do not collect input for tap's in bypass */ - } - - /* update device information */ - buf_cpy(field->out_value, tap->cur_instr, tap->ir_length); - - field++; - } - /* paranoia: jtag_tap_count_enabled() and jtag_tap_next_enabled() not in sync */ - assert(field == out_fields + num_taps); - - return ERROR_OK; -} - -/** - * see jtag_add_dr_scan() - * - */ -int interface_jtag_add_dr_scan(struct jtag_tap *active, int in_num_fields, - const struct scan_field *in_fields, tap_state_t state) -{ - /* count devices in bypass */ - - size_t bypass_devices = 0; - - for (struct jtag_tap *tap = jtag_tap_next_enabled(NULL); tap != NULL; tap = jtag_tap_next_enabled(tap)) { - if (tap->bypass) - bypass_devices++; - } - - struct jtag_command *cmd = cmd_queue_alloc(sizeof(struct jtag_command)); - struct scan_command *scan = cmd_queue_alloc(sizeof(struct scan_command)); - struct scan_field *out_fields = cmd_queue_alloc((in_num_fields + bypass_devices) * sizeof(struct scan_field)); - - jtag_queue_command(cmd); - - cmd->type = JTAG_SCAN; - cmd->cmd.scan = scan; - - scan->ir_scan = false; - scan->num_fields = in_num_fields + bypass_devices; - scan->fields = out_fields; - scan->end_state = state; - - struct scan_field *field = out_fields; /* keep track where we insert data */ - - /* loop over all enabled TAPs */ - - for (struct jtag_tap *tap = jtag_tap_next_enabled(NULL); tap != NULL; tap = jtag_tap_next_enabled(tap)) { - /* if TAP is not bypassed insert matching input fields */ - - if (!tap->bypass) { - assert(active == tap); -#ifndef NDEBUG - /* remember initial position for assert() */ - struct scan_field *start_field = field; -#endif /* NDEBUG */ - - for (int j = 0; j < in_num_fields; j++) { - cmd_queue_scan_field_clone(field, in_fields + j); - - field++; - } - - assert(field > start_field); /* must have at least one input field per not bypassed TAP */ - } - - /* if a TAP is bypassed, generated a dummy bit*/ - else { - field->num_bits = 1; - field->out_value = NULL; - field->in_value = NULL; - - field++; - } - } - - assert(field == out_fields + scan->num_fields); /* no superfluous input fields permitted */ - - return ERROR_OK; -} - -static int jtag_add_plain_scan(int num_bits, const uint8_t *out_bits, - uint8_t *in_bits, tap_state_t state, bool ir_scan) -{ - struct jtag_command *cmd = cmd_queue_alloc(sizeof(struct jtag_command)); - struct scan_command *scan = cmd_queue_alloc(sizeof(struct scan_command)); - struct scan_field *out_fields = cmd_queue_alloc(sizeof(struct scan_field)); - - jtag_queue_command(cmd); - - cmd->type = JTAG_SCAN; - cmd->cmd.scan = scan; - - scan->ir_scan = ir_scan; - scan->num_fields = 1; - scan->fields = out_fields; - scan->end_state = state; - - out_fields->num_bits = num_bits; - out_fields->out_value = buf_cpy(out_bits, cmd_queue_alloc(DIV_ROUND_UP(num_bits, 8)), num_bits); - out_fields->in_value = in_bits; - - return ERROR_OK; -} - -int interface_jtag_add_plain_dr_scan(int num_bits, const uint8_t *out_bits, uint8_t *in_bits, tap_state_t state) -{ - return jtag_add_plain_scan(num_bits, out_bits, in_bits, state, false); -} - -int interface_jtag_add_plain_ir_scan(int num_bits, const uint8_t *out_bits, uint8_t *in_bits, tap_state_t state) -{ - return jtag_add_plain_scan(num_bits, out_bits, in_bits, state, true); -} - -int interface_jtag_add_tlr(void) -{ - tap_state_t state = TAP_RESET; - - /* allocate memory for a new list member */ - struct jtag_command *cmd = cmd_queue_alloc(sizeof(struct jtag_command)); - - jtag_queue_command(cmd); - - cmd->type = JTAG_TLR_RESET; - - cmd->cmd.statemove = cmd_queue_alloc(sizeof(struct statemove_command)); - cmd->cmd.statemove->end_state = state; - - return ERROR_OK; -} - -int interface_add_tms_seq(unsigned num_bits, const uint8_t *seq, enum tap_state state) -{ - struct jtag_command *cmd; - - cmd = cmd_queue_alloc(sizeof(struct jtag_command)); - if (cmd == NULL) - return ERROR_FAIL; - - cmd->type = JTAG_TMS; - cmd->cmd.tms = cmd_queue_alloc(sizeof(*cmd->cmd.tms)); - if (!cmd->cmd.tms) - return ERROR_FAIL; - - /* copy the bits; our caller doesn't guarantee they'll persist */ - cmd->cmd.tms->num_bits = num_bits; - cmd->cmd.tms->bits = buf_cpy(seq, - cmd_queue_alloc(DIV_ROUND_UP(num_bits, 8)), num_bits); - if (!cmd->cmd.tms->bits) - return ERROR_FAIL; - - jtag_queue_command(cmd); - - return ERROR_OK; -} - -int interface_jtag_add_pathmove(int num_states, const tap_state_t *path) -{ - /* allocate memory for a new list member */ - struct jtag_command *cmd = cmd_queue_alloc(sizeof(struct jtag_command)); - - jtag_queue_command(cmd); - - cmd->type = JTAG_PATHMOVE; - - cmd->cmd.pathmove = cmd_queue_alloc(sizeof(struct pathmove_command)); - cmd->cmd.pathmove->num_states = num_states; - cmd->cmd.pathmove->path = cmd_queue_alloc(sizeof(tap_state_t) * num_states); - - for (int i = 0; i < num_states; i++) - cmd->cmd.pathmove->path[i] = path[i]; - - return ERROR_OK; -} - -int interface_jtag_add_runtest(int num_cycles, tap_state_t state) -{ - /* allocate memory for a new list member */ - struct jtag_command *cmd = cmd_queue_alloc(sizeof(struct jtag_command)); - - jtag_queue_command(cmd); - - cmd->type = JTAG_RUNTEST; - - cmd->cmd.runtest = cmd_queue_alloc(sizeof(struct runtest_command)); - cmd->cmd.runtest->num_cycles = num_cycles; - cmd->cmd.runtest->end_state = state; - - return ERROR_OK; -} - -int interface_jtag_add_clocks(int num_cycles) -{ - /* allocate memory for a new list member */ - struct jtag_command *cmd = cmd_queue_alloc(sizeof(struct jtag_command)); - - jtag_queue_command(cmd); - - cmd->type = JTAG_STABLECLOCKS; - - cmd->cmd.stableclocks = cmd_queue_alloc(sizeof(struct stableclocks_command)); - cmd->cmd.stableclocks->num_cycles = num_cycles; - - return ERROR_OK; -} - -int interface_jtag_add_reset(int req_trst, int req_srst) -{ - /* allocate memory for a new list member */ - struct jtag_command *cmd = cmd_queue_alloc(sizeof(struct jtag_command)); - - jtag_queue_command(cmd); - - cmd->type = JTAG_RESET; - - cmd->cmd.reset = cmd_queue_alloc(sizeof(struct reset_command)); - cmd->cmd.reset->trst = req_trst; - cmd->cmd.reset->srst = req_srst; - - return ERROR_OK; -} - -int interface_jtag_add_sleep(uint32_t us) -{ - /* allocate memory for a new list member */ - struct jtag_command *cmd = cmd_queue_alloc(sizeof(struct jtag_command)); - - jtag_queue_command(cmd); - - cmd->type = JTAG_SLEEP; - - cmd->cmd.sleep = cmd_queue_alloc(sizeof(struct sleep_command)); - cmd->cmd.sleep->us = us; - - return ERROR_OK; -} - -/* add callback to end of queue */ -void interface_jtag_add_callback4(jtag_callback_t callback, - jtag_callback_data_t data0, jtag_callback_data_t data1, - jtag_callback_data_t data2, jtag_callback_data_t data3) -{ - struct jtag_callback_entry *entry = cmd_queue_alloc(sizeof(struct jtag_callback_entry)); - - entry->next = NULL; - entry->callback = callback; - entry->data0 = data0; - entry->data1 = data1; - entry->data2 = data2; - entry->data3 = data3; - - if (jtag_callback_queue_head == NULL) { - jtag_callback_queue_head = entry; - jtag_callback_queue_tail = entry; - } else { - jtag_callback_queue_tail->next = entry; - jtag_callback_queue_tail = entry; - } -} - -int interface_jtag_execute_queue(void) -{ - static int reentry; - - assert(reentry == 0); - reentry++; - - int retval = default_interface_jtag_execute_queue(); - if (retval == ERROR_OK) { - struct jtag_callback_entry *entry; - for (entry = jtag_callback_queue_head; entry != NULL; entry = entry->next) { - retval = entry->callback(entry->data0, entry->data1, entry->data2, entry->data3); - if (retval != ERROR_OK) - break; - } - } - - jtag_command_queue_reset(); - jtag_callback_queue_reset(); - - reentry--; - - return retval; -} - -static int jtag_convert_to_callback4(jtag_callback_data_t data0, - jtag_callback_data_t data1, jtag_callback_data_t data2, jtag_callback_data_t data3) -{ - ((jtag_callback1_t)data1)(data0); - return ERROR_OK; -} - -void interface_jtag_add_callback(jtag_callback1_t callback, jtag_callback_data_t data0) -{ - jtag_add_callback4(jtag_convert_to_callback4, data0, (jtag_callback_data_t)callback, 0, 0); -} - -void jtag_add_callback(jtag_callback1_t f, jtag_callback_data_t data0) -{ - interface_jtag_add_callback(f, data0); -} - -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) -{ - interface_jtag_add_callback4(f, data0, data1, data2, data3); -} diff --git a/src/jtag/drivers/dummy.c b/src/jtag/drivers/dummy.c deleted file mode 100644 index 0f7c12dd4..000000000 --- a/src/jtag/drivers/dummy.c +++ /dev/null @@ -1,160 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2008 by Øyvind Harboe * - * oyvind.harboe@zylin.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include "bitbang.h" -#include "hello.h" - -/* my private tap controller state, which tracks state for calling code */ -static tap_state_t dummy_state = TAP_RESET; - -static int dummy_clock; /* edge detector */ - -static int clock_count; /* count clocks in any stable state, only stable states */ - -static uint32_t dummy_data; - -static int dummy_read(void) -{ - int data = 1 & dummy_data; - dummy_data = (dummy_data >> 1) | (1 << 31); - return data; -} - -static void dummy_write(int tck, int tms, int tdi) -{ - /* TAP standard: "state transitions occur on rising edge of clock" */ - if (tck != dummy_clock) { - if (tck) { - tap_state_t old_state = dummy_state; - dummy_state = tap_state_transition(old_state, tms); - - if (old_state != dummy_state) { - if (clock_count) { - LOG_DEBUG("dummy_tap: %d stable clocks", clock_count); - clock_count = 0; - } - - LOG_DEBUG("dummy_tap: %s", tap_state_name(dummy_state)); - -#if defined(DEBUG) - if (dummy_state == TAP_DRCAPTURE) - dummy_data = 0x01255043; -#endif - } else { - /* this is a stable state clock edge, no change of state here, - * simply increment clock_count for subsequent logging - */ - ++clock_count; - } - } - dummy_clock = tck; - } -} - -static void dummy_reset(int trst, int srst) -{ - dummy_clock = 0; - - if (trst || (srst && (jtag_get_reset_config() & RESET_SRST_PULLS_TRST))) - dummy_state = TAP_RESET; - - LOG_DEBUG("reset to: %s", tap_state_name(dummy_state)); -} - -static void dummy_led(int on) -{ -} - -static struct bitbang_interface dummy_bitbang = { - .read = &dummy_read, - .write = &dummy_write, - .reset = &dummy_reset, - .blink = &dummy_led, - }; - -static int dummy_khz(int khz, int *jtag_speed) -{ - if (khz == 0) - *jtag_speed = 0; - else - *jtag_speed = 64000/khz; - return ERROR_OK; -} - -static int dummy_speed_div(int speed, int *khz) -{ - if (speed == 0) - *khz = 0; - else - *khz = 64000/speed; - - return ERROR_OK; -} - -static int dummy_speed(int speed) -{ - return ERROR_OK; -} - -static int dummy_init(void) -{ - bitbang_interface = &dummy_bitbang; - - return ERROR_OK; -} - -static int dummy_quit(void) -{ - return ERROR_OK; -} - -static const struct command_registration dummy_command_handlers[] = { - { - .name = "dummy", - .mode = COMMAND_ANY, - .help = "dummy interface driver commands", - - .chain = hello_command_handlers, - }, - COMMAND_REGISTRATION_DONE, -}; - -/* The dummy driver is used to easily check the code path - * where the target is unresponsive. - */ -struct jtag_interface dummy_interface = { - .name = "dummy", - - .supported = DEBUG_CAP_TMS_SEQ, - .commands = dummy_command_handlers, - .transports = jtag_only, - - .execute_queue = &bitbang_execute_queue, - - .speed = &dummy_speed, - .khz = &dummy_khz, - .speed_div = &dummy_speed_div, - - .init = &dummy_init, - .quit = &dummy_quit, - }; diff --git a/src/jtag/drivers/ep93xx.c b/src/jtag/drivers/ep93xx.c deleted file mode 100644 index ccd979502..000000000 --- a/src/jtag/drivers/ep93xx.c +++ /dev/null @@ -1,212 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include "bitbang.h" - -#define TDO_BIT 1 -#define TDI_BIT 2 -#define TCK_BIT 4 -#define TMS_BIT 8 -#define TRST_BIT 16 -#define SRST_BIT 32 -#define VCC_BIT 64 - -#include - -static uint8_t output_value; -static int dev_mem_fd; -static void *gpio_controller; -static volatile uint8_t *gpio_data_register; -static volatile uint8_t *gpio_data_direction_register; - -/* low level command set - */ -static int ep93xx_read(void); -static void ep93xx_write(int tck, int tms, int tdi); -static void ep93xx_reset(int trst, int srst); - -static int ep93xx_init(void); -static int ep93xx_quit(void); - -struct timespec ep93xx_zzzz; - -struct jtag_interface ep93xx_interface = { - .name = "ep93xx", - - .supported = DEBUG_CAP_TMS_SEQ, - .execute_queue = bitbang_execute_queue, - - .init = ep93xx_init, - .quit = ep93xx_quit, -}; - -static struct bitbang_interface ep93xx_bitbang = { - .read = ep93xx_read, - .write = ep93xx_write, - .reset = ep93xx_reset, - .blink = 0, -}; - -static int ep93xx_read(void) -{ - return !!(*gpio_data_register & TDO_BIT); -} - -static void ep93xx_write(int tck, int tms, int tdi) -{ - if (tck) - output_value |= TCK_BIT; - else - output_value &= ~TCK_BIT; - - if (tms) - output_value |= TMS_BIT; - else - output_value &= ~TMS_BIT; - - if (tdi) - output_value |= TDI_BIT; - else - output_value &= ~TDI_BIT; - - *gpio_data_register = output_value; - nanosleep(&ep93xx_zzzz, NULL); -} - -/* (1) assert or (0) deassert reset lines */ -static void ep93xx_reset(int trst, int srst) -{ - if (trst == 0) - output_value |= TRST_BIT; - else if (trst == 1) - output_value &= ~TRST_BIT; - - if (srst == 0) - output_value |= SRST_BIT; - else if (srst == 1) - output_value &= ~SRST_BIT; - - *gpio_data_register = output_value; - nanosleep(&ep93xx_zzzz, NULL); -} - -static int set_gonk_mode(void) -{ - void *syscon; - uint32_t devicecfg; - - syscon = mmap(NULL, 4096, PROT_READ | PROT_WRITE, - MAP_SHARED, dev_mem_fd, 0x80930000); - if (syscon == MAP_FAILED) { - perror("mmap"); - return ERROR_JTAG_INIT_FAILED; - } - - devicecfg = *((volatile int *)(syscon + 0x80)); - *((volatile int *)(syscon + 0xc0)) = 0xaa; - *((volatile int *)(syscon + 0x80)) = devicecfg | 0x08000000; - - munmap(syscon, 4096); - - return ERROR_OK; -} - -static int ep93xx_init(void) -{ - int ret; - - bitbang_interface = &ep93xx_bitbang; - - ep93xx_zzzz.tv_sec = 0; - ep93xx_zzzz.tv_nsec = 10000000; - - dev_mem_fd = open("/dev/mem", O_RDWR | O_SYNC); - if (dev_mem_fd < 0) { - perror("open"); - return ERROR_JTAG_INIT_FAILED; - } - - gpio_controller = mmap(NULL, 4096, PROT_READ | PROT_WRITE, - MAP_SHARED, dev_mem_fd, 0x80840000); - if (gpio_controller == MAP_FAILED) { - perror("mmap"); - close(dev_mem_fd); - return ERROR_JTAG_INIT_FAILED; - } - - ret = set_gonk_mode(); - if (ret != ERROR_OK) { - munmap(gpio_controller, 4096); - close(dev_mem_fd); - return ret; - } - -#if 0 - /* Use GPIO port A. */ - gpio_data_register = gpio_controller + 0x00; - gpio_data_direction_register = gpio_controller + 0x10; - - - /* Use GPIO port B. */ - gpio_data_register = gpio_controller + 0x04; - gpio_data_direction_register = gpio_controller + 0x14; - - /* Use GPIO port C. */ - gpio_data_register = gpio_controller + 0x08; - gpio_data_direction_register = gpio_controller + 0x18; - - /* Use GPIO port D. */ - gpio_data_register = gpio_controller + 0x0c; - gpio_data_direction_register = gpio_controller + 0x1c; -#endif - - /* Use GPIO port C. */ - gpio_data_register = gpio_controller + 0x08; - gpio_data_direction_register = gpio_controller + 0x18; - - LOG_INFO("gpio_data_register = %p", gpio_data_register); - LOG_INFO("gpio_data_direction_reg = %p", gpio_data_direction_register); - /* - * Configure bit 0 (TDO) as an input, and bits 1-5 (TDI, TCK - * TMS, TRST, SRST) as outputs. Drive TDI and TCK low, and - * TMS/TRST/SRST high. - */ - output_value = TMS_BIT | TRST_BIT | SRST_BIT | VCC_BIT; - *gpio_data_register = output_value; - nanosleep(&ep93xx_zzzz, NULL); - - /* - * Configure the direction register. 1 = output, 0 = input. - */ - *gpio_data_direction_register = - TDI_BIT | TCK_BIT | TMS_BIT | TRST_BIT | SRST_BIT | VCC_BIT; - - nanosleep(&ep93xx_zzzz, NULL); - return ERROR_OK; -} - -static int ep93xx_quit(void) -{ - - return ERROR_OK; -} diff --git a/src/jtag/drivers/ft2232.c b/src/jtag/drivers/ft2232.c deleted file mode 100644 index 621da8e21..000000000 --- a/src/jtag/drivers/ft2232.c +++ /dev/null @@ -1,4308 +0,0 @@ -/*************************************************************************** -* Copyright (C) 2009 by Øyvind Harboe * -* Øyvind Harboe * -* * -* Copyright (C) 2009 by SoftPLC Corporation. http://softplc.com * -* Dick Hollenbeck * -* * -* Copyright (C) 2004, 2006 by Dominic Rath * -* Dominic.Rath@gmx.de * -* * -* Copyright (C) 2008 by Spencer Oliver * -* spen@spen-soft.co.uk * -* * -* This program is free software; you can redistribute it and/or modify * -* it under the terms of the GNU General Public License as published by * -* the Free Software Foundation; either version 2 of the License, or * -* (at your option) any later version. * -* * -* This program is distributed in the hope that it will be useful, * -* but WITHOUT ANY WARRANTY; without even the implied warranty of * -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -* GNU General Public License for more details. * -* * -* You should have received a copy of the GNU General Public License * -* along with this program. If not, see . * -***************************************************************************/ - -/** - * @file - * JTAG adapters based on the FT2232 full and high speed USB parts are - * popular low cost JTAG debug solutions. Many FT2232 based JTAG adapters - * are discrete, but development boards may integrate them as alternatives - * to more capable (and expensive) third party JTAG pods. - * - * JTAG uses only one of the two communications channels ("MPSSE engines") - * on these devices. Adapters based on FT4232 parts have four ports/channels - * (A/B/C/D), instead of just two (A/B). - * - * Especially on development boards integrating one of these chips (as - * opposed to discrete pods/dongles), the additional channels can be used - * for a variety of purposes, but OpenOCD only uses one channel at a time. - * - * - As a USB-to-serial adapter for the target's console UART ... - * which may be able to support ROM boot loaders that load initial - * firmware images to flash (or SRAM). - * - * - On systems which support ARM's SWD in addition to JTAG, or instead - * of it, that second port can be used for reading SWV/SWO trace data. - * - * - Additional JTAG links, e.g. to a CPLD or * FPGA. - * - * FT2232 based JTAG adapters are "dumb" not "smart", because most JTAG - * request/response interactions involve round trips over the USB link. - * A "smart" JTAG adapter has intelligence close to the scan chain, so it - * can for example poll quickly for a status change (usually taking on the - * order of microseconds not milliseconds) before beginning a queued - * transaction which require the previous one to have completed. - * - * There are dozens of adapters of this type, differing in details which - * this driver needs to understand. Those "layout" details are required - * as part of FT2232 driver configuration. - * - * This code uses information contained in the MPSSE specification which was - * found here: - * http://www.ftdichip.com/Documents/AppNotes/AN2232C-01_MPSSE_Cmnd.pdf - * Hereafter this is called the "MPSSE Spec". - * - * The datasheet for the ftdichip.com's FT2232D part is here: - * http://www.ftdichip.com/Documents/DataSheets/DS_FT2232D.pdf - * - * Also note the issue with code 0x4b (clock data to TMS) noted in - * http://developer.intra2net.com/mailarchive/html/libftdi/2009/msg00292.html - * which can affect longer JTAG state paths. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -/* project specific includes */ -#include -#include -#include - -#if IS_CYGWIN == 1 -#include -#endif - -#include - -#if (BUILD_FT2232_FTD2XX == 1 && BUILD_FT2232_LIBFTDI == 1) -#error "BUILD_FT2232_FTD2XX && BUILD_FT2232_LIBFTDI are mutually exclusive" -#elif (BUILD_FT2232_FTD2XX != 1 && BUILD_FT2232_LIBFTDI != 1) -#error "BUILD_FT2232_FTD2XX || BUILD_FT2232_LIBFTDI must be chosen" -#endif - -/* FT2232 access library includes */ -#if BUILD_FT2232_FTD2XX == 1 -#include -#include "ftd2xx_common.h" - -enum ftdi_interface { - INTERFACE_ANY = 0, - INTERFACE_A = 1, - INTERFACE_B = 2, - INTERFACE_C = 3, - INTERFACE_D = 4 -}; - -#elif BUILD_FT2232_LIBFTDI == 1 -#include -#endif - -/* max TCK for the high speed devices 30000 kHz */ -#define FTDI_x232H_MAX_TCK 30000 -/* max TCK for the full speed devices 6000 kHz */ -#define FTDI_2232C_MAX_TCK 6000 -/* this speed value tells that RTCK is requested */ -#define RTCK_SPEED -1 - -/* - * On my Athlon XP 1900+ EHCI host with FT2232H JTAG dongle I get read timeout - * errors with a retry count of 100. Increasing it solves the problem for me. - * - Dimitar - * - * FIXME There's likely an issue with the usb_read_timeout from libftdi. - * Fix that (libusb? kernel? libftdi? here?) and restore the retry count - * to something sane. - */ -#define LIBFTDI_READ_RETRY_COUNT 2000 - -#ifndef BUILD_FT2232_HIGHSPEED - #if BUILD_FT2232_FTD2XX == 1 - enum { FT_DEVICE_2232H = 6, FT_DEVICE_4232H, FT_DEVICE_232H }; - #elif BUILD_FT2232_LIBFTDI == 1 - enum ftdi_chip_type { TYPE_2232H = 4, TYPE_4232H = 5, TYPE_232H = 6 }; - #endif -#endif - -/** - * Send out \a num_cycles on the TCK line while the TAP(s) are in a - * stable state. Calling code must ensure that current state is stable, - * that verification is not done in here. - * - * @param num_cycles The number of clocks cycles to send. - * @param cmd The command to send. - * - * @returns ERROR_OK on success, or ERROR_JTAG_QUEUE_FAILED on failure. - */ -static int ft2232_stableclocks(int num_cycles, struct jtag_command *cmd); - -static char *ft2232_device_desc_A; -static char *ft2232_device_desc; -static char *ft2232_serial; -static uint8_t ft2232_latency = 2; -static unsigned ft2232_max_tck = FTDI_2232C_MAX_TCK; -static int ft2232_channel = INTERFACE_ANY; - -#define MAX_USB_IDS 8 -/* vid = pid = 0 marks the end of the list */ -static uint16_t ft2232_vid[MAX_USB_IDS + 1] = { 0x0403, 0 }; -static uint16_t ft2232_pid[MAX_USB_IDS + 1] = { 0x6010, 0 }; - -struct ft2232_layout { - const char *name; - int (*init)(void); - void (*reset)(int trst, int srst); - void (*blink)(void); - int channel; -}; - -/* init procedures for supported layouts */ -static int usbjtag_init(void); -static int jtagkey_init(void); -static int lm3s811_jtag_init(void); -static int icdi_jtag_init(void); -static int olimex_jtag_init(void); -static int flyswatter1_init(void); -static int flyswatter2_init(void); -static int minimodule_init(void); -static int turtle_init(void); -static int comstick_init(void); -static int stm32stick_init(void); -static int axm0432_jtag_init(void); -static int sheevaplug_init(void); -static int icebear_jtag_init(void); -static int cortino_jtag_init(void); -static int signalyzer_init(void); -static int signalyzer_h_init(void); -static int ktlink_init(void); -static int redbee_init(void); -static int lisa_l_init(void); -static int flossjtag_init(void); -static int xds100v2_init(void); -static int digilent_hs1_init(void); - -/* reset procedures for supported layouts */ -static void ftx23_reset(int trst, int srst); -static void jtagkey_reset(int trst, int srst); -static void olimex_jtag_reset(int trst, int srst); -static void flyswatter1_reset(int trst, int srst); -static void flyswatter2_reset(int trst, int srst); -static void minimodule_reset(int trst, int srst); -static void turtle_reset(int trst, int srst); -static void comstick_reset(int trst, int srst); -static void stm32stick_reset(int trst, int srst); -static void axm0432_jtag_reset(int trst, int srst); -static void sheevaplug_reset(int trst, int srst); -static void icebear_jtag_reset(int trst, int srst); -static void signalyzer_h_reset(int trst, int srst); -static void ktlink_reset(int trst, int srst); -static void redbee_reset(int trst, int srst); -static void xds100v2_reset(int trst, int srst); -static void digilent_hs1_reset(int trst, int srst); - -/* blink procedures for layouts that support a blinking led */ -static void olimex_jtag_blink(void); -static void flyswatter1_jtag_blink(void); -static void flyswatter2_jtag_blink(void); -static void turtle_jtag_blink(void); -static void signalyzer_h_blink(void); -static void ktlink_blink(void); -static void lisa_l_blink(void); -static void flossjtag_blink(void); - -/* common transport support options */ - -/* static const char *jtag_and_swd[] = { "jtag", "swd", NULL }; */ - -static const struct ft2232_layout ft2232_layouts[] = { - { .name = "usbjtag", - .init = usbjtag_init, - .reset = ftx23_reset, - }, - { .name = "jtagkey", - .init = jtagkey_init, - .reset = jtagkey_reset, - }, - { .name = "jtagkey_prototype_v1", - .init = jtagkey_init, - .reset = jtagkey_reset, - }, - { .name = "oocdlink", - .init = jtagkey_init, - .reset = jtagkey_reset, - }, - { .name = "signalyzer", - .init = signalyzer_init, - .reset = ftx23_reset, - }, - { .name = "evb_lm3s811", - .init = lm3s811_jtag_init, - .reset = ftx23_reset, - }, - { .name = "luminary_icdi", - .init = icdi_jtag_init, - .reset = ftx23_reset, - }, - { .name = "olimex-jtag", - .init = olimex_jtag_init, - .reset = olimex_jtag_reset, - .blink = olimex_jtag_blink - }, - { .name = "flyswatter", - .init = flyswatter1_init, - .reset = flyswatter1_reset, - .blink = flyswatter1_jtag_blink - }, - { .name = "flyswatter2", - .init = flyswatter2_init, - .reset = flyswatter2_reset, - .blink = flyswatter2_jtag_blink - }, - { .name = "minimodule", - .init = minimodule_init, - .reset = minimodule_reset, - }, - { .name = "turtelizer2", - .init = turtle_init, - .reset = turtle_reset, - .blink = turtle_jtag_blink - }, - { .name = "comstick", - .init = comstick_init, - .reset = comstick_reset, - }, - { .name = "stm32stick", - .init = stm32stick_init, - .reset = stm32stick_reset, - }, - { .name = "axm0432_jtag", - .init = axm0432_jtag_init, - .reset = axm0432_jtag_reset, - }, - { .name = "sheevaplug", - .init = sheevaplug_init, - .reset = sheevaplug_reset, - }, - { .name = "icebear", - .init = icebear_jtag_init, - .reset = icebear_jtag_reset, - }, - { .name = "cortino", - .init = cortino_jtag_init, - .reset = comstick_reset, - }, - { .name = "signalyzer-h", - .init = signalyzer_h_init, - .reset = signalyzer_h_reset, - .blink = signalyzer_h_blink - }, - { .name = "ktlink", - .init = ktlink_init, - .reset = ktlink_reset, - .blink = ktlink_blink - }, - { .name = "redbee-econotag", - .init = redbee_init, - .reset = redbee_reset, - }, - { .name = "redbee-usb", - .init = redbee_init, - .reset = redbee_reset, - .channel = INTERFACE_B, - }, - { .name = "lisa-l", - .init = lisa_l_init, - .reset = ftx23_reset, - .blink = lisa_l_blink, - .channel = INTERFACE_B, - }, - { .name = "flossjtag", - .init = flossjtag_init, - .reset = ftx23_reset, - .blink = flossjtag_blink, - }, - { .name = "xds100v2", - .init = xds100v2_init, - .reset = xds100v2_reset, - }, - { .name = "digilent-hs1", - .init = digilent_hs1_init, - .reset = digilent_hs1_reset, - .channel = INTERFACE_A, - }, - { .name = NULL, /* END OF TABLE */ }, -}; - -/* bitmask used to drive nTRST; usually a GPIOLx signal */ -static uint8_t nTRST; -static uint8_t nTRSTnOE; -/* bitmask used to drive nSRST; usually a GPIOLx signal */ -static uint8_t nSRST; -static uint8_t nSRSTnOE; - -/** the layout being used with this debug session */ -static const struct ft2232_layout *layout; - -/** default bitmask values driven on DBUS: TCK/TDI/TDO/TMS and GPIOL(0..4) */ -static uint8_t low_output; - -/* note that direction bit == 1 means that signal is an output */ - -/** default direction bitmask for DBUS: TCK/TDI/TDO/TMS and GPIOL(0..4) */ -static uint8_t low_direction; -/** default value bitmask for CBUS GPIOH(0..4) */ -static uint8_t high_output; -/** default direction bitmask for CBUS GPIOH(0..4) */ -static uint8_t high_direction; - -#if BUILD_FT2232_FTD2XX == 1 -static FT_HANDLE ftdih; -static FT_DEVICE ftdi_device; -#elif BUILD_FT2232_LIBFTDI == 1 -static struct ftdi_context ftdic; -static enum ftdi_chip_type ftdi_device; -#endif - -static struct jtag_command *first_unsent; /* next command that has to be sent */ -static int require_send; - -/* http://urjtag.wiki.sourceforge.net/Cable + FT2232 says: - - "There is a significant difference between libftdi and libftd2xx. The latter - one allows to schedule up to 64*64 bytes of result data while libftdi fails - with more than 4*64. As a consequence, the FT2232 driver is forced to - perform around 16x more USB transactions for long command streams with TDO - capture when running with libftdi." - - No idea how we get - #define FT2232_BUFFER_SIZE 131072 - a comment would have been nice. -*/ - -#if BUILD_FT2232_FTD2XX == 1 -#define FT2232_BUFFER_READ_QUEUE_SIZE (64*64) -#else -#define FT2232_BUFFER_READ_QUEUE_SIZE (64*4) -#endif - -#define FT2232_BUFFER_SIZE 131072 - -static uint8_t *ft2232_buffer; -static int ft2232_buffer_size; -static int ft2232_read_pointer; -static int ft2232_expect_read; - -/** - * Function buffer_write - * writes a byte into the byte buffer, "ft2232_buffer", which must be sent later. - * @param val is the byte to send. - */ -static inline void buffer_write(uint8_t val) -{ - assert(ft2232_buffer); - assert((unsigned) ft2232_buffer_size < (unsigned) FT2232_BUFFER_SIZE); - ft2232_buffer[ft2232_buffer_size++] = val; -} - -/** - * Function buffer_read - * returns a byte from the byte buffer. - */ -static inline uint8_t buffer_read(void) -{ - assert(ft2232_buffer); - assert(ft2232_read_pointer < ft2232_buffer_size); - return ft2232_buffer[ft2232_read_pointer++]; -} - -/** - * Clocks out \a bit_count bits on the TMS line, starting with the least - * significant bit of tms_bits and progressing to more significant bits. - * Rigorous state transition logging is done here via tap_set_state(). - * - * @param mpsse_cmd One of the MPSSE TMS oriented commands such as - * 0x4b or 0x6b. See the MPSSE spec referenced above for their - * functionality. The MPSSE command "Clock Data to TMS/CS Pin (no Read)" - * is often used for this, 0x4b. - * - * @param tms_bits Holds the sequence of bits to send. - * @param tms_count Tells how many bits in the sequence. - * @param tdi_bit A single bit to pass on to TDI before the first TCK - * cycle and held static for the duration of TMS clocking. - * - * See the MPSSE spec referenced above. - */ -static void clock_tms(uint8_t mpsse_cmd, int tms_bits, int tms_count, bool tdi_bit) -{ - uint8_t tms_byte; - int i; - int tms_ndx; /* bit index into tms_byte */ - - assert(tms_count > 0); - - DEBUG_JTAG_IO("mpsse cmd=%02x, tms_bits = 0x%08x, bit_count=%d", - mpsse_cmd, tms_bits, tms_count); - - for (tms_byte = tms_ndx = i = 0; i < tms_count; ++i, tms_bits >>= 1) { - bool bit = tms_bits & 1; - - if (bit) - tms_byte |= (1 << tms_ndx); - - /* always do state transitions in public view */ - tap_set_state(tap_state_transition(tap_get_state(), bit)); - - /* we wrote a bit to tms_byte just above, increment bit index. if bit was zero - * also increment. - */ - ++tms_ndx; - - if (tms_ndx == 7 || i == tms_count-1) { - buffer_write(mpsse_cmd); - buffer_write(tms_ndx - 1); - - /* Bit 7 of the byte is passed on to TDI/DO before the first TCK/SK of - * TMS/CS and is held static for the duration of TMS/CS clocking. - */ - buffer_write(tms_byte | (tdi_bit << 7)); - } - } -} - -/** - * Function get_tms_buffer_requirements - * returns what clock_tms() will consume if called with - * same \a bit_count. - */ -static inline int get_tms_buffer_requirements(int bit_count) -{ - return ((bit_count + 6)/7) * 3; -} - -/** - * Function move_to_state - * moves the TAP controller from the current state to a - * \a goal_state through a path given by tap_get_tms_path(). State transition - * logging is performed by delegation to clock_tms(). - * - * @param goal_state is the destination state for the move. - */ -static void move_to_state(tap_state_t goal_state) -{ - tap_state_t start_state = tap_get_state(); - - /* goal_state is 1/2 of a tuple/pair of states which allow convenient - * lookup of the required TMS pattern to move to this state from the start state. - */ - - /* do the 2 lookups */ - int tms_bits = tap_get_tms_path(start_state, goal_state); - int tms_count = tap_get_tms_path_len(start_state, goal_state); - - DEBUG_JTAG_IO("start=%s goal=%s", tap_state_name(start_state), tap_state_name(goal_state)); - - clock_tms(0x4b, tms_bits, tms_count, 0); -} - -static int ft2232_write(uint8_t *buf, int size, uint32_t *bytes_written) -{ -#if BUILD_FT2232_FTD2XX == 1 - FT_STATUS status; - DWORD dw_bytes_written = 0; - status = FT_Write(ftdih, buf, size, &dw_bytes_written); - if (status != FT_OK) { - *bytes_written = dw_bytes_written; - LOG_ERROR("FT_Write returned: %s", ftd2xx_status_string(status)); - return ERROR_JTAG_DEVICE_ERROR; - } else - *bytes_written = dw_bytes_written; - -#elif BUILD_FT2232_LIBFTDI == 1 - int retval = ftdi_write_data(&ftdic, buf, size); - if (retval < 0) { - *bytes_written = 0; - LOG_ERROR("ftdi_write_data: %s", ftdi_get_error_string(&ftdic)); - return ERROR_JTAG_DEVICE_ERROR; - } else - *bytes_written = retval; - -#endif - - if (*bytes_written != (uint32_t)size) - return ERROR_JTAG_DEVICE_ERROR; - - return ERROR_OK; -} - -static int ft2232_read(uint8_t *buf, uint32_t size, uint32_t *bytes_read) -{ -#if BUILD_FT2232_FTD2XX == 1 - DWORD dw_bytes_read; - FT_STATUS status; - int timeout = 5; - *bytes_read = 0; - - while ((*bytes_read < size) && timeout--) { - status = FT_Read(ftdih, buf + *bytes_read, size - - *bytes_read, &dw_bytes_read); - if (status != FT_OK) { - *bytes_read = 0; - LOG_ERROR("FT_Read returned: %s", ftd2xx_status_string(status)); - return ERROR_JTAG_DEVICE_ERROR; - } - *bytes_read += dw_bytes_read; - } - -#elif BUILD_FT2232_LIBFTDI == 1 - int retval; - int timeout = LIBFTDI_READ_RETRY_COUNT; - *bytes_read = 0; - - while ((*bytes_read < size) && timeout--) { - retval = ftdi_read_data(&ftdic, buf + *bytes_read, size - *bytes_read); - if (retval < 0) { - *bytes_read = 0; - LOG_ERROR("ftdi_read_data: %s", ftdi_get_error_string(&ftdic)); - return ERROR_JTAG_DEVICE_ERROR; - } - *bytes_read += retval; - } - -#endif - - if (*bytes_read < size) { - LOG_ERROR("couldn't read enough bytes from " - "FT2232 device (%i < %i)", - (unsigned)*bytes_read, - (unsigned)size); - return ERROR_JTAG_DEVICE_ERROR; - } - - return ERROR_OK; -} - -static bool ft2232_device_is_highspeed(void) -{ -#if BUILD_FT2232_FTD2XX == 1 - return (ftdi_device == FT_DEVICE_2232H) || (ftdi_device == FT_DEVICE_4232H) - #ifdef HAS_ENUM_FT232H - || (ftdi_device == FT_DEVICE_232H) - #endif - ; -#elif BUILD_FT2232_LIBFTDI == 1 - return (ftdi_device == TYPE_2232H || ftdi_device == TYPE_4232H - #ifdef HAS_ENUM_FT232H - || ftdi_device == TYPE_232H - #endif - ); -#endif -} - -/* - * Commands that only apply to the highspeed FTx232H devices (FT2232H, FT4232H, FT232H). - * See chapter 6 in http://www.ftdichip.com/Documents/AppNotes/ - * AN_108_Command_Processor_for_MPSSE_and_MCU_Host_Bus_Emulation_Modes.pdf - */ - -static int ftx232h_adaptive_clocking(bool enable) -{ - uint8_t buf = enable ? 0x96 : 0x97; - LOG_DEBUG("%2.2x", buf); - - uint32_t bytes_written; - int retval; - - retval = ft2232_write(&buf, sizeof(buf), &bytes_written); - if (retval != ERROR_OK) { - LOG_ERROR("couldn't write command to %s adaptive clocking" - , enable ? "enable" : "disable"); - return retval; - } - - return ERROR_OK; -} - -/** - * Enable/disable the clk divide by 5 of the 60MHz master clock. - * This result in a JTAG clock speed range of 91.553Hz-6MHz - * respective 457.763Hz-30MHz. - */ -static int ftx232h_clk_divide_by_5(bool enable) -{ - uint32_t bytes_written; - uint8_t buf = enable ? 0x8b : 0x8a; - - if (ft2232_write(&buf, sizeof(buf), &bytes_written) != ERROR_OK) { - LOG_ERROR("couldn't write command to %s clk divide by 5" - , enable ? "enable" : "disable"); - return ERROR_JTAG_INIT_FAILED; - } - ft2232_max_tck = enable ? FTDI_2232C_MAX_TCK : FTDI_x232H_MAX_TCK; - LOG_INFO("max TCK change to: %u kHz", ft2232_max_tck); - - return ERROR_OK; -} - -static int ft2232_speed(int speed) -{ - uint8_t buf[3]; - int retval; - uint32_t bytes_written; - - retval = ERROR_OK; - bool enable_adaptive_clocking = (RTCK_SPEED == speed); - if (ft2232_device_is_highspeed()) - retval = ftx232h_adaptive_clocking(enable_adaptive_clocking); - else if (enable_adaptive_clocking) { - LOG_ERROR("ft2232 device %lu does not support RTCK" - , (long unsigned int)ftdi_device); - return ERROR_FAIL; - } - - if ((enable_adaptive_clocking) || (ERROR_OK != retval)) - return retval; - - buf[0] = 0x86; /* command "set divisor" */ - buf[1] = speed & 0xff; /* valueL (0 = 6MHz, 1 = 3MHz, 2 = 2.0MHz, ...*/ - buf[2] = (speed >> 8) & 0xff; /* valueH */ - - LOG_DEBUG("%2.2x %2.2x %2.2x", buf[0], buf[1], buf[2]); - retval = ft2232_write(buf, sizeof(buf), &bytes_written); - if (retval != ERROR_OK) { - LOG_ERROR("couldn't set FT2232 TCK speed"); - return retval; - } - - return ERROR_OK; -} - -static int ft2232_speed_div(int speed, int *khz) -{ - /* Take a look in the FT2232 manual, - * AN2232C-01 Command Processor for - * MPSSE and MCU Host Bus. Chapter 3.8 */ - - *khz = (RTCK_SPEED == speed) ? 0 : ft2232_max_tck / (1 + speed); - - return ERROR_OK; -} - -static int ft2232_khz(int khz, int *jtag_speed) -{ - if (khz == 0) { - if (ft2232_device_is_highspeed()) { - *jtag_speed = RTCK_SPEED; - return ERROR_OK; - } else { - LOG_DEBUG("RCLK not supported"); - return ERROR_FAIL; - } - } - - /* Take a look in the FT2232 manual, - * AN2232C-01 Command Processor for - * MPSSE and MCU Host Bus. Chapter 3.8 - * - * We will calc here with a multiplier - * of 10 for better rounding later. */ - - /* Calc speed, (ft2232_max_tck / khz) - 1 - * Use 65000 for better rounding */ - *jtag_speed = ((ft2232_max_tck*10) / khz) - 10; - - /* Add 0.9 for rounding */ - *jtag_speed += 9; - - /* Calc real speed */ - *jtag_speed = *jtag_speed / 10; - - /* Check if speed is greater than 0 */ - if (*jtag_speed < 0) - *jtag_speed = 0; - - /* Check max value */ - if (*jtag_speed > 0xFFFF) - *jtag_speed = 0xFFFF; - - return ERROR_OK; -} - -static void ft2232_end_state(tap_state_t state) -{ - if (tap_is_state_stable(state)) - tap_set_end_state(state); - else { - LOG_ERROR("BUG: %s is not a stable end state", tap_state_name(state)); - exit(-1); - } -} - -static void ft2232_read_scan(enum scan_type type, uint8_t *buffer, int scan_size) -{ - int num_bytes = (scan_size + 7) / 8; - int bits_left = scan_size; - int cur_byte = 0; - - while (num_bytes-- > 1) { - buffer[cur_byte++] = buffer_read(); - bits_left -= 8; - } - - buffer[cur_byte] = 0x0; - - /* There is one more partial byte left from the clock data in/out instructions */ - if (bits_left > 1) - buffer[cur_byte] = buffer_read() >> 1; - /* This shift depends on the length of the - *clock data to tms instruction, insterted - *at end of the scan, now fixed to a two - *step transition in ft2232_add_scan */ - buffer[cur_byte] = (buffer[cur_byte] | (((buffer_read()) << 1) & 0x80)) >> (8 - bits_left); -} - -static void ft2232_debug_dump_buffer(void) -{ - int i; - char line[256]; - char *line_p = line; - - for (i = 0; i < ft2232_buffer_size; i++) { - line_p += snprintf(line_p, - sizeof(line) - (line_p - line), - "%2.2x ", - ft2232_buffer[i]); - if (i % 16 == 15) { - LOG_DEBUG("%s", line); - line_p = line; - } - } - - if (line_p != line) - LOG_DEBUG("%s", line); -} - -static int ft2232_send_and_recv(struct jtag_command *first, struct jtag_command *last) -{ - struct jtag_command *cmd; - uint8_t *buffer; - int scan_size; - enum scan_type type; - int retval; - uint32_t bytes_written = 0; - uint32_t bytes_read = 0; - -#ifdef _DEBUG_USB_IO_ - struct timeval start, inter, inter2, end; - struct timeval d_inter, d_inter2, d_end; -#endif - -#ifdef _DEBUG_USB_COMMS_ - LOG_DEBUG("write buffer (size %i):", ft2232_buffer_size); - ft2232_debug_dump_buffer(); -#endif - -#ifdef _DEBUG_USB_IO_ - gettimeofday(&start, NULL); -#endif - - retval = ft2232_write(ft2232_buffer, ft2232_buffer_size, &bytes_written); - if (retval != ERROR_OK) { - LOG_ERROR("couldn't write MPSSE commands to FT2232"); - return retval; - } - -#ifdef _DEBUG_USB_IO_ - gettimeofday(&inter, NULL); -#endif - - if (ft2232_expect_read) { - /* FIXME this "timeout" is never changed ... */ - int timeout = LIBFTDI_READ_RETRY_COUNT; - ft2232_buffer_size = 0; - -#ifdef _DEBUG_USB_IO_ - gettimeofday(&inter2, NULL); -#endif - - retval = ft2232_read(ft2232_buffer, ft2232_expect_read, &bytes_read); - if (retval != ERROR_OK) { - LOG_ERROR("couldn't read from FT2232"); - return retval; - } - -#ifdef _DEBUG_USB_IO_ - gettimeofday(&end, NULL); - - timeval_subtract(&d_inter, &inter, &start); - timeval_subtract(&d_inter2, &inter2, &start); - timeval_subtract(&d_end, &end, &start); - - LOG_INFO("inter: %u.%06u, inter2: %u.%06u end: %u.%06u", - (unsigned)d_inter.tv_sec, (unsigned)d_inter.tv_usec, - (unsigned)d_inter2.tv_sec, (unsigned)d_inter2.tv_usec, - (unsigned)d_end.tv_sec, (unsigned)d_end.tv_usec); -#endif - - ft2232_buffer_size = bytes_read; - - if (ft2232_expect_read != ft2232_buffer_size) { - LOG_ERROR("ft2232_expect_read (%i) != " - "ft2232_buffer_size (%i) " - "(%i retries)", - ft2232_expect_read, - ft2232_buffer_size, - LIBFTDI_READ_RETRY_COUNT - timeout); - ft2232_debug_dump_buffer(); - - exit(-1); - } - -#ifdef _DEBUG_USB_COMMS_ - LOG_DEBUG("read buffer (%i retries): %i bytes", - LIBFTDI_READ_RETRY_COUNT - timeout, - ft2232_buffer_size); - ft2232_debug_dump_buffer(); -#endif - } - - ft2232_expect_read = 0; - ft2232_read_pointer = 0; - - /* return ERROR_OK, unless a jtag_read_buffer returns a failed check - * that wasn't handled by a caller-provided error handler - */ - retval = ERROR_OK; - - cmd = first; - while (cmd != last) { - switch (cmd->type) { - case JTAG_SCAN: - type = jtag_scan_type(cmd->cmd.scan); - if (type != SCAN_OUT) { - scan_size = jtag_scan_size(cmd->cmd.scan); - buffer = calloc(DIV_ROUND_UP(scan_size, 8), 1); - ft2232_read_scan(type, buffer, scan_size); - if (jtag_read_buffer(buffer, cmd->cmd.scan) != ERROR_OK) - retval = ERROR_JTAG_QUEUE_FAILED; - free(buffer); - } - break; - - default: - break; - } - - cmd = cmd->next; - } - - ft2232_buffer_size = 0; - - return retval; -} - -/** - * Function ft2232_add_pathmove - * moves the TAP controller from the current state to a new state through the - * given path, where path is an array of tap_state_t's. - * - * @param path is an array of tap_stat_t which gives the states to traverse through - * ending with the last state at path[num_states-1] - * @param num_states is the count of state steps to move through - */ -static void ft2232_add_pathmove(tap_state_t *path, int num_states) -{ - int state_count = 0; - - assert((unsigned) num_states <= 32u); /* tms_bits only holds 32 bits */ - - DEBUG_JTAG_IO("-"); - - /* this loop verifies that the path is legal and logs each state in the path */ - while (num_states) { - unsigned char tms_byte = 0; /* zero this on each MPSSE batch */ - int bit_count = 0; - int num_states_batch = num_states > 7 ? 7 : num_states; - - /* command "Clock Data to TMS/CS Pin (no Read)" */ - buffer_write(0x4b); - - /* number of states remaining */ - buffer_write(num_states_batch - 1); - - while (num_states_batch--) { - /* either TMS=0 or TMS=1 must work ... */ - if (tap_state_transition(tap_get_state(), false) == path[state_count]) - buf_set_u32(&tms_byte, bit_count++, 1, 0x0); - else if (tap_state_transition(tap_get_state(), true) == path[state_count]) - buf_set_u32(&tms_byte, bit_count++, 1, 0x1); - - /* ... or else the caller goofed BADLY */ - else { - LOG_ERROR("BUG: %s -> %s isn't a valid " - "TAP state transition", - tap_state_name(tap_get_state()), - tap_state_name(path[state_count])); - exit(-1); - } - - tap_set_state(path[state_count]); - state_count++; - num_states--; - } - - buffer_write(tms_byte); - } - tap_set_end_state(tap_get_state()); -} - -static void ft2232_add_scan(bool ir_scan, enum scan_type type, uint8_t *buffer, int scan_size) -{ - int num_bytes = (scan_size + 7) / 8; - int bits_left = scan_size; - int cur_byte = 0; - int last_bit; - - if (!ir_scan) { - if (tap_get_state() != TAP_DRSHIFT) - move_to_state(TAP_DRSHIFT); - } else { - if (tap_get_state() != TAP_IRSHIFT) - move_to_state(TAP_IRSHIFT); - } - - /* add command for complete bytes */ - while (num_bytes > 1) { - int thisrun_bytes; - if (type == SCAN_IO) { - /* Clock Data Bytes In and Out LSB First */ - buffer_write(0x39); - /* LOG_DEBUG("added TDI bytes (io %i)", num_bytes); */ - } else if (type == SCAN_OUT) { - /* Clock Data Bytes Out on -ve Clock Edge LSB First (no Read) */ - buffer_write(0x19); - /* LOG_DEBUG("added TDI bytes (o)"); */ - } else if (type == SCAN_IN) { - /* Clock Data Bytes In on +ve Clock Edge LSB First (no Write) */ - buffer_write(0x28); - /* LOG_DEBUG("added TDI bytes (i %i)", num_bytes); */ - } - - thisrun_bytes = (num_bytes > 65537) ? 65536 : (num_bytes - 1); - num_bytes -= thisrun_bytes; - - buffer_write((uint8_t) (thisrun_bytes - 1)); - buffer_write((uint8_t) ((thisrun_bytes - 1) >> 8)); - - if (type != SCAN_IN) { - /* add complete bytes */ - while (thisrun_bytes-- > 0) { - buffer_write(buffer[cur_byte++]); - bits_left -= 8; - } - } else /* (type == SCAN_IN) */ - bits_left -= 8 * (thisrun_bytes); - } - - /* the most signifcant bit is scanned during TAP movement */ - if (type != SCAN_IN) - last_bit = (buffer[cur_byte] >> (bits_left - 1)) & 0x1; - else - last_bit = 0; - - /* process remaining bits but the last one */ - if (bits_left > 1) { - if (type == SCAN_IO) { - /* Clock Data Bits In and Out LSB First */ - buffer_write(0x3b); - /* LOG_DEBUG("added TDI bits (io) %i", bits_left - 1); */ - } else if (type == SCAN_OUT) { - /* Clock Data Bits Out on -ve Clock Edge LSB First (no Read) */ - buffer_write(0x1b); - /* LOG_DEBUG("added TDI bits (o)"); */ - } else if (type == SCAN_IN) { - /* Clock Data Bits In on +ve Clock Edge LSB First (no Write) */ - buffer_write(0x2a); - /* LOG_DEBUG("added TDI bits (i %i)", bits_left - 1); */ - } - - buffer_write(bits_left - 2); - if (type != SCAN_IN) - buffer_write(buffer[cur_byte]); - } - - if ((ir_scan && (tap_get_end_state() == TAP_IRSHIFT)) - || (!ir_scan && (tap_get_end_state() == TAP_DRSHIFT))) { - if (type == SCAN_IO) { - /* Clock Data Bits In and Out LSB First */ - buffer_write(0x3b); - /* LOG_DEBUG("added TDI bits (io) %i", bits_left - 1); */ - } else if (type == SCAN_OUT) { - /* Clock Data Bits Out on -ve Clock Edge LSB First (no Read) */ - buffer_write(0x1b); - /* LOG_DEBUG("added TDI bits (o)"); */ - } else if (type == SCAN_IN) { - /* Clock Data Bits In on +ve Clock Edge LSB First (no Write) */ - buffer_write(0x2a); - /* LOG_DEBUG("added TDI bits (i %i)", bits_left - 1); */ - } - buffer_write(0x0); - if (type != SCAN_IN) - buffer_write(last_bit); - } else { - int tms_bits; - int tms_count; - uint8_t mpsse_cmd; - - /* move from Shift-IR/DR to end state */ - if (type != SCAN_OUT) { - /* We always go to the PAUSE state in two step at the end of an IN or IO - *scan - * This must be coordinated with the bit shifts in ft2232_read_scan */ - tms_bits = 0x01; - tms_count = 2; - /* Clock Data to TMS/CS Pin with Read */ - mpsse_cmd = 0x6b; - } else { - tms_bits = tap_get_tms_path(tap_get_state(), tap_get_end_state()); - tms_count = tap_get_tms_path_len(tap_get_state(), tap_get_end_state()); - /* Clock Data to TMS/CS Pin (no Read) */ - mpsse_cmd = 0x4b; - } - - DEBUG_JTAG_IO("finish %s", (type == SCAN_OUT) ? "without read" : "via PAUSE"); - clock_tms(mpsse_cmd, tms_bits, tms_count, last_bit); - } - - if (tap_get_state() != tap_get_end_state()) - move_to_state(tap_get_end_state()); -} - -static int ft2232_large_scan(struct scan_command *cmd, - enum scan_type type, - uint8_t *buffer, - int scan_size) -{ - int num_bytes = (scan_size + 7) / 8; - int bits_left = scan_size; - int cur_byte = 0; - int last_bit; - uint8_t *receive_buffer = malloc(DIV_ROUND_UP(scan_size, 8)); - uint8_t *receive_pointer = receive_buffer; - uint32_t bytes_written; - uint32_t bytes_read; - int retval; - int thisrun_read = 0; - - if (!receive_buffer) { - LOG_ERROR("failed to allocate memory"); - exit(-1); - } - - if (cmd->ir_scan) { - LOG_ERROR("BUG: large IR scans are not supported"); - exit(-1); - } - - if (tap_get_state() != TAP_DRSHIFT) - move_to_state(TAP_DRSHIFT); - - retval = ft2232_write(ft2232_buffer, ft2232_buffer_size, &bytes_written); - if (retval != ERROR_OK) { - LOG_ERROR("couldn't write MPSSE commands to FT2232"); - exit(-1); - } - LOG_DEBUG("ft2232_buffer_size: %i, bytes_written: %i", - ft2232_buffer_size, (int)bytes_written); - ft2232_buffer_size = 0; - - /* add command for complete bytes */ - while (num_bytes > 1) { - int thisrun_bytes; - - if (type == SCAN_IO) { - /* Clock Data Bytes In and Out LSB First */ - buffer_write(0x39); - /* LOG_DEBUG("added TDI bytes (io %i)", num_bytes); */ - } else if (type == SCAN_OUT) { - /* Clock Data Bytes Out on -ve Clock Edge LSB First (no Read) */ - buffer_write(0x19); - /* LOG_DEBUG("added TDI bytes (o)"); */ - } else if (type == SCAN_IN) { - /* Clock Data Bytes In on +ve Clock Edge LSB First (no Write) */ - buffer_write(0x28); - /* LOG_DEBUG("added TDI bytes (i %i)", num_bytes); */ - } - - thisrun_bytes = (num_bytes > 65537) ? 65536 : (num_bytes - 1); - thisrun_read = thisrun_bytes; - num_bytes -= thisrun_bytes; - buffer_write((uint8_t) (thisrun_bytes - 1)); - buffer_write((uint8_t) ((thisrun_bytes - 1) >> 8)); - - if (type != SCAN_IN) { - /* add complete bytes */ - while (thisrun_bytes-- > 0) { - buffer_write(buffer[cur_byte]); - cur_byte++; - bits_left -= 8; - } - } else /* (type == SCAN_IN) */ - bits_left -= 8 * (thisrun_bytes); - - retval = ft2232_write(ft2232_buffer, ft2232_buffer_size, &bytes_written); - if (retval != ERROR_OK) { - LOG_ERROR("couldn't write MPSSE commands to FT2232"); - exit(-1); - } - LOG_DEBUG("ft2232_buffer_size: %i, bytes_written: %i", - ft2232_buffer_size, - (int)bytes_written); - ft2232_buffer_size = 0; - - if (type != SCAN_OUT) { - retval = ft2232_read(receive_pointer, thisrun_read, &bytes_read); - if (retval != ERROR_OK) { - LOG_ERROR("couldn't read from FT2232"); - exit(-1); - } - LOG_DEBUG("thisrun_read: %i, bytes_read: %i", - thisrun_read, - (int)bytes_read); - receive_pointer += bytes_read; - } - } - - thisrun_read = 0; - - /* the most signifcant bit is scanned during TAP movement */ - if (type != SCAN_IN) - last_bit = (buffer[cur_byte] >> (bits_left - 1)) & 0x1; - else - last_bit = 0; - - /* process remaining bits but the last one */ - if (bits_left > 1) { - if (type == SCAN_IO) { - /* Clock Data Bits In and Out LSB First */ - buffer_write(0x3b); - /* LOG_DEBUG("added TDI bits (io) %i", bits_left - 1); */ - } else if (type == SCAN_OUT) { - /* Clock Data Bits Out on -ve Clock Edge LSB First (no Read) */ - buffer_write(0x1b); - /* LOG_DEBUG("added TDI bits (o)"); */ - } else if (type == SCAN_IN) { - /* Clock Data Bits In on +ve Clock Edge LSB First (no Write) */ - buffer_write(0x2a); - /* LOG_DEBUG("added TDI bits (i %i)", bits_left - 1); */ - } - buffer_write(bits_left - 2); - if (type != SCAN_IN) - buffer_write(buffer[cur_byte]); - - if (type != SCAN_OUT) - thisrun_read += 2; - } - - if (tap_get_end_state() == TAP_DRSHIFT) { - if (type == SCAN_IO) { - /* Clock Data Bits In and Out LSB First */ - buffer_write(0x3b); - /* LOG_DEBUG("added TDI bits (io) %i", bits_left - 1); */ - } else if (type == SCAN_OUT) { - /* Clock Data Bits Out on -ve Clock Edge LSB First (no Read) */ - buffer_write(0x1b); - /* LOG_DEBUG("added TDI bits (o)"); */ - } else if (type == SCAN_IN) { - /* Clock Data Bits In on +ve Clock Edge LSB First (no Write) */ - buffer_write(0x2a); - /* LOG_DEBUG("added TDI bits (i %i)", bits_left - 1); */ - } - buffer_write(0x0); - buffer_write(last_bit); - } else { - int tms_bits = tap_get_tms_path(tap_get_state(), tap_get_end_state()); - int tms_count = tap_get_tms_path_len(tap_get_state(), tap_get_end_state()); - uint8_t mpsse_cmd; - - /* move from Shift-IR/DR to end state */ - if (type != SCAN_OUT) { - /* Clock Data to TMS/CS Pin with Read */ - mpsse_cmd = 0x6b; - /* LOG_DEBUG("added TMS scan (read)"); */ - } else { - /* Clock Data to TMS/CS Pin (no Read) */ - mpsse_cmd = 0x4b; - /* LOG_DEBUG("added TMS scan (no read)"); */ - } - - DEBUG_JTAG_IO("finish, %s", (type == SCAN_OUT) ? "no read" : "read"); - clock_tms(mpsse_cmd, tms_bits, tms_count, last_bit); - } - - if (type != SCAN_OUT) - thisrun_read += 1; - - retval = ft2232_write(ft2232_buffer, ft2232_buffer_size, &bytes_written); - if (retval != ERROR_OK) { - LOG_ERROR("couldn't write MPSSE commands to FT2232"); - exit(-1); - } - LOG_DEBUG("ft2232_buffer_size: %i, bytes_written: %i", - ft2232_buffer_size, - (int)bytes_written); - ft2232_buffer_size = 0; - - if (type != SCAN_OUT) { - retval = ft2232_read(receive_pointer, thisrun_read, &bytes_read); - if (retval != ERROR_OK) { - LOG_ERROR("couldn't read from FT2232"); - exit(-1); - } - LOG_DEBUG("thisrun_read: %i, bytes_read: %i", - thisrun_read, - (int)bytes_read); - } - - free(receive_buffer); - - return ERROR_OK; -} - -static int ft2232_predict_scan_out(int scan_size, enum scan_type type) -{ - int predicted_size = 3; - int num_bytes = (scan_size - 1) / 8; - - if (tap_get_state() != TAP_DRSHIFT) - predicted_size += get_tms_buffer_requirements( - tap_get_tms_path_len(tap_get_state(), TAP_DRSHIFT)); - - if (type == SCAN_IN) { /* only from device to host */ - /* complete bytes */ - predicted_size += DIV_ROUND_UP(num_bytes, 65536) * 3; - - /* remaining bits - 1 (up to 7) */ - predicted_size += ((scan_size - 1) % 8) ? 2 : 0; - } else {/* host to device, or bidirectional - * complete bytes */ - predicted_size += num_bytes + DIV_ROUND_UP(num_bytes, 65536) * 3; - - /* remaining bits -1 (up to 7) */ - predicted_size += ((scan_size - 1) % 8) ? 3 : 0; - } - - return predicted_size; -} - -static int ft2232_predict_scan_in(int scan_size, enum scan_type type) -{ - int predicted_size = 0; - - if (type != SCAN_OUT) { - /* complete bytes */ - predicted_size += - (DIV_ROUND_UP(scan_size, 8) > 1) ? (DIV_ROUND_UP(scan_size, 8) - 1) : 0; - - /* remaining bits - 1 */ - predicted_size += ((scan_size - 1) % 8) ? 1 : 0; - - /* last bit (from TMS scan) */ - predicted_size += 1; - } - - /* LOG_DEBUG("scan_size: %i, predicted_size: %i", scan_size, predicted_size); */ - - return predicted_size; -} - -/* semi-generic FT2232/FT4232 reset code */ -static void ftx23_reset(int trst, int srst) -{ - enum reset_types jtag_reset_config = jtag_get_reset_config(); - if (trst == 1) { - if (jtag_reset_config & RESET_TRST_OPEN_DRAIN) - low_direction |= nTRSTnOE; /* switch to output pin (output is low) */ - else - low_output &= ~nTRST; /* switch output low */ - } else if (trst == 0) { - if (jtag_reset_config & RESET_TRST_OPEN_DRAIN) - low_direction &= ~nTRSTnOE; /* switch to input pin (high-Z + internal - *and external pullup) */ - else - low_output |= nTRST; /* switch output high */ - } - - if (srst == 1) { - if (jtag_reset_config & RESET_SRST_PUSH_PULL) - low_output &= ~nSRST; /* switch output low */ - else - low_direction |= nSRSTnOE; /* switch to output pin (output is low) */ - } else if (srst == 0) { - if (jtag_reset_config & RESET_SRST_PUSH_PULL) - low_output |= nSRST; /* switch output high */ - else - low_direction &= ~nSRSTnOE; /* switch to input pin (high-Z) */ - } - - /* command "set data bits low byte" */ - buffer_write(0x80); - buffer_write(low_output); - buffer_write(low_direction); -} - -static void jtagkey_reset(int trst, int srst) -{ - enum reset_types jtag_reset_config = jtag_get_reset_config(); - if (trst == 1) { - if (jtag_reset_config & RESET_TRST_OPEN_DRAIN) - high_output &= ~nTRSTnOE; - else - high_output &= ~nTRST; - } else if (trst == 0) { - if (jtag_reset_config & RESET_TRST_OPEN_DRAIN) - high_output |= nTRSTnOE; - else - high_output |= nTRST; - } - - if (srst == 1) { - if (jtag_reset_config & RESET_SRST_PUSH_PULL) - high_output &= ~nSRST; - else - high_output &= ~nSRSTnOE; - } else if (srst == 0) { - if (jtag_reset_config & RESET_SRST_PUSH_PULL) - high_output |= nSRST; - else - high_output |= nSRSTnOE; - } - - /* command "set data bits high byte" */ - buffer_write(0x82); - buffer_write(high_output); - buffer_write(high_direction); - LOG_DEBUG("trst: %i, srst: %i, high_output: 0x%2.2x, high_direction: 0x%2.2x", - trst, - srst, - high_output, - high_direction); -} - -static void olimex_jtag_reset(int trst, int srst) -{ - enum reset_types jtag_reset_config = jtag_get_reset_config(); - if (trst == 1) { - if (jtag_reset_config & RESET_TRST_OPEN_DRAIN) - high_output &= ~nTRSTnOE; - else - high_output &= ~nTRST; - } else if (trst == 0) { - if (jtag_reset_config & RESET_TRST_OPEN_DRAIN) - high_output |= nTRSTnOE; - else - high_output |= nTRST; - } - - if (srst == 1) - high_output |= nSRST; - else if (srst == 0) - high_output &= ~nSRST; - - /* command "set data bits high byte" */ - buffer_write(0x82); - buffer_write(high_output); - buffer_write(high_direction); - LOG_DEBUG("trst: %i, srst: %i, high_output: 0x%2.2x, high_direction: 0x%2.2x", - trst, - srst, - high_output, - high_direction); -} - -static void axm0432_jtag_reset(int trst, int srst) -{ - if (trst == 1) { - tap_set_state(TAP_RESET); - high_output &= ~nTRST; - } else if (trst == 0) - high_output |= nTRST; - - if (srst == 1) - high_output &= ~nSRST; - else if (srst == 0) - high_output |= nSRST; - - /* command "set data bits low byte" */ - buffer_write(0x82); - buffer_write(high_output); - buffer_write(high_direction); - LOG_DEBUG("trst: %i, srst: %i, high_output: 0x%2.2x, high_direction: 0x%2.2x", - trst, - srst, - high_output, - high_direction); -} - -static void flyswatter_reset(int trst, int srst) -{ - if (trst == 1) - low_output &= ~nTRST; - else if (trst == 0) - low_output |= nTRST; - - if (srst == 1) - low_output |= nSRST; - else if (srst == 0) - low_output &= ~nSRST; - - /* command "set data bits low byte" */ - buffer_write(0x80); - buffer_write(low_output); - buffer_write(low_direction); - LOG_DEBUG("trst: %i, srst: %i, low_output: 0x%2.2x, low_direction: 0x%2.2x", - trst, - srst, - low_output, - low_direction); -} - -static void flyswatter1_reset(int trst, int srst) -{ - flyswatter_reset(trst, srst); -} - -static void flyswatter2_reset(int trst, int srst) -{ - flyswatter_reset(trst, !srst); -} - -static void minimodule_reset(int trst, int srst) -{ - if (srst == 1) - low_output &= ~nSRST; - else if (srst == 0) - low_output |= nSRST; - - /* command "set data bits low byte" */ - buffer_write(0x80); - buffer_write(low_output); - buffer_write(low_direction); - LOG_DEBUG("trst: %i, srst: %i, low_output: 0x%2.2x, low_direction: 0x%2.2x", - trst, - srst, - low_output, - low_direction); -} - -static void turtle_reset(int trst, int srst) -{ - if (trst == 1) - LOG_ERROR("Can't assert TRST: the adapter lacks this signal"); - - if (srst == 1) - low_output |= nSRST; - else if (srst == 0) - low_output &= ~nSRST; - - /* command "set data bits low byte" */ - buffer_write(0x80); - buffer_write(low_output); - buffer_write(low_direction); - LOG_DEBUG("srst: %i, low_output: 0x%2.2x, low_direction: 0x%2.2x", - srst, - low_output, - low_direction); -} - -static void comstick_reset(int trst, int srst) -{ - if (trst == 1) - high_output &= ~nTRST; - else if (trst == 0) - high_output |= nTRST; - - if (srst == 1) - high_output &= ~nSRST; - else if (srst == 0) - high_output |= nSRST; - - /* command "set data bits high byte" */ - buffer_write(0x82); - buffer_write(high_output); - buffer_write(high_direction); - LOG_DEBUG("trst: %i, srst: %i, high_output: 0x%2.2x, high_direction: 0x%2.2x", - trst, - srst, - high_output, - high_direction); -} - -static void stm32stick_reset(int trst, int srst) -{ - if (trst == 1) - high_output &= ~nTRST; - else if (trst == 0) - high_output |= nTRST; - - if (srst == 1) - low_output &= ~nSRST; - else if (srst == 0) - low_output |= nSRST; - - /* command "set data bits low byte" */ - buffer_write(0x80); - buffer_write(low_output); - buffer_write(low_direction); - - /* command "set data bits high byte" */ - buffer_write(0x82); - buffer_write(high_output); - buffer_write(high_direction); - LOG_DEBUG("trst: %i, srst: %i, high_output: 0x%2.2x, high_direction: 0x%2.2x", - trst, - srst, - high_output, - high_direction); -} - -static void sheevaplug_reset(int trst, int srst) -{ - if (trst == 1) - high_output &= ~nTRST; - else if (trst == 0) - high_output |= nTRST; - - if (srst == 1) - high_output &= ~nSRSTnOE; - else if (srst == 0) - high_output |= nSRSTnOE; - - /* command "set data bits high byte" */ - buffer_write(0x82); - buffer_write(high_output); - buffer_write(high_direction); - LOG_DEBUG("trst: %i, srst: %i, high_output: 0x%2.2x, high_direction: 0x%2.2x", - trst, - srst, - high_output, - high_direction); -} - -static void redbee_reset(int trst, int srst) -{ - if (trst == 1) { - tap_set_state(TAP_RESET); - high_output &= ~nTRST; - } else if (trst == 0) - high_output |= nTRST; - - if (srst == 1) - high_output &= ~nSRST; - else if (srst == 0) - high_output |= nSRST; - - /* command "set data bits low byte" */ - buffer_write(0x82); - buffer_write(high_output); - buffer_write(high_direction); - LOG_DEBUG("trst: %i, srst: %i, high_output: 0x%2.2x, " - "high_direction: 0x%2.2x", trst, srst, high_output, - high_direction); -} - -static void xds100v2_reset(int trst, int srst) -{ - if (trst == 1) { - tap_set_state(TAP_RESET); - high_output &= ~nTRST; - } else if (trst == 0) - high_output |= nTRST; - - if (srst == 1) - high_output |= nSRST; - else if (srst == 0) - high_output &= ~nSRST; - - /* command "set data bits low byte" */ - buffer_write(0x82); - buffer_write(high_output); - buffer_write(high_direction); - LOG_DEBUG("trst: %i, srst: %i, high_output: 0x%2.2x, " - "high_direction: 0x%2.2x", trst, srst, high_output, - high_direction); -} - -static int ft2232_execute_runtest(struct jtag_command *cmd) -{ - int retval; - int i; - int predicted_size = 0; - retval = ERROR_OK; - - DEBUG_JTAG_IO("runtest %i cycles, end in %s", - cmd->cmd.runtest->num_cycles, - tap_state_name(cmd->cmd.runtest->end_state)); - - /* only send the maximum buffer size that FT2232C can handle */ - predicted_size = 0; - if (tap_get_state() != TAP_IDLE) - predicted_size += 3; - predicted_size += 3 * DIV_ROUND_UP(cmd->cmd.runtest->num_cycles, 7); - if (cmd->cmd.runtest->end_state != TAP_IDLE) - predicted_size += 3; - if (tap_get_end_state() != TAP_IDLE) - predicted_size += 3; - if (ft2232_buffer_size + predicted_size + 1 > FT2232_BUFFER_SIZE) { - if (ft2232_send_and_recv(first_unsent, cmd) != ERROR_OK) - retval = ERROR_JTAG_QUEUE_FAILED; - require_send = 0; - first_unsent = cmd; - } - if (tap_get_state() != TAP_IDLE) { - move_to_state(TAP_IDLE); - require_send = 1; - } - i = cmd->cmd.runtest->num_cycles; - while (i > 0) { - /* there are no state transitions in this code, so omit state tracking */ - - /* command "Clock Data to TMS/CS Pin (no Read)" */ - buffer_write(0x4b); - - /* scan 7 bits */ - buffer_write((i > 7) ? 6 : (i - 1)); - - /* TMS data bits */ - buffer_write(0x0); - - i -= (i > 7) ? 7 : i; - /* LOG_DEBUG("added TMS scan (no read)"); */ - } - - ft2232_end_state(cmd->cmd.runtest->end_state); - - if (tap_get_state() != tap_get_end_state()) - move_to_state(tap_get_end_state()); - - require_send = 1; - DEBUG_JTAG_IO("runtest: %i, end in %s", - cmd->cmd.runtest->num_cycles, - tap_state_name(tap_get_end_state())); - return retval; -} - -static int ft2232_execute_statemove(struct jtag_command *cmd) -{ - int predicted_size = 0; - int retval = ERROR_OK; - - DEBUG_JTAG_IO("statemove end in %s", - tap_state_name(cmd->cmd.statemove->end_state)); - - /* only send the maximum buffer size that FT2232C can handle */ - predicted_size = 3; - if (ft2232_buffer_size + predicted_size + 1 > FT2232_BUFFER_SIZE) { - if (ft2232_send_and_recv(first_unsent, cmd) != ERROR_OK) - retval = ERROR_JTAG_QUEUE_FAILED; - require_send = 0; - first_unsent = cmd; - } - ft2232_end_state(cmd->cmd.statemove->end_state); - - /* For TAP_RESET, ignore the current recorded state. It's often - * wrong at server startup, and this transation is critical whenever - * it's requested. - */ - if (tap_get_end_state() == TAP_RESET) { - clock_tms(0x4b, 0xff, 5, 0); - require_send = 1; - - /* shortest-path move to desired end state */ - } else if (tap_get_state() != tap_get_end_state()) { - move_to_state(tap_get_end_state()); - require_send = 1; - } - - return retval; -} - -/** - * Clock a bunch of TMS (or SWDIO) transitions, to change the JTAG - * (or SWD) state machine. - */ -static int ft2232_execute_tms(struct jtag_command *cmd) -{ - int retval = ERROR_OK; - unsigned num_bits = cmd->cmd.tms->num_bits; - const uint8_t *bits = cmd->cmd.tms->bits; - unsigned count; - - DEBUG_JTAG_IO("TMS: %d bits", num_bits); - - /* only send the maximum buffer size that FT2232C can handle */ - count = 3 * DIV_ROUND_UP(num_bits, 4); - if (ft2232_buffer_size + 3*count + 1 > FT2232_BUFFER_SIZE) { - if (ft2232_send_and_recv(first_unsent, cmd) != ERROR_OK) - retval = ERROR_JTAG_QUEUE_FAILED; - - require_send = 0; - first_unsent = cmd; - } - - /* Shift out in batches of at most 6 bits; there's a report of an - * FT2232 bug in this area, where shifting exactly 7 bits can make - * problems with TMS signaling for the last clock cycle: - * - * http://developer.intra2net.com/mailarchive/html/ - * libftdi/2009/msg00292.html - * - * Command 0x4b is: "Clock Data to TMS/CS Pin (no Read)" - * - * Note that pathmoves in JTAG are not often seven bits, so that - * isn't a particularly likely situation outside of "special" - * signaling such as switching between JTAG and SWD modes. - */ - while (num_bits) { - if (num_bits <= 6) { - buffer_write(0x4b); - buffer_write(num_bits - 1); - buffer_write(*bits & 0x3f); - break; - } - - /* Yes, this is lazy ... we COULD shift out more data - * bits per operation, but doing it in nybbles is easy - */ - buffer_write(0x4b); - buffer_write(3); - buffer_write(*bits & 0xf); - num_bits -= 4; - - count = (num_bits > 4) ? 4 : num_bits; - - buffer_write(0x4b); - buffer_write(count - 1); - buffer_write((*bits >> 4) & 0xf); - num_bits -= count; - - bits++; - } - - require_send = 1; - return retval; -} - -static int ft2232_execute_pathmove(struct jtag_command *cmd) -{ - int predicted_size = 0; - int retval = ERROR_OK; - - tap_state_t *path = cmd->cmd.pathmove->path; - int num_states = cmd->cmd.pathmove->num_states; - - DEBUG_JTAG_IO("pathmove: %i states, current: %s end: %s", num_states, - tap_state_name(tap_get_state()), - tap_state_name(path[num_states-1])); - - /* only send the maximum buffer size that FT2232C can handle */ - predicted_size = 3 * DIV_ROUND_UP(num_states, 7); - if (ft2232_buffer_size + predicted_size + 1 > FT2232_BUFFER_SIZE) { - if (ft2232_send_and_recv(first_unsent, cmd) != ERROR_OK) - retval = ERROR_JTAG_QUEUE_FAILED; - - require_send = 0; - first_unsent = cmd; - } - - ft2232_add_pathmove(path, num_states); - require_send = 1; - - return retval; -} - -static int ft2232_execute_scan(struct jtag_command *cmd) -{ - uint8_t *buffer; - int scan_size; /* size of IR or DR scan */ - int predicted_size = 0; - int retval = ERROR_OK; - - enum scan_type type = jtag_scan_type(cmd->cmd.scan); - - DEBUG_JTAG_IO("%s type:%d", cmd->cmd.scan->ir_scan ? "IRSCAN" : "DRSCAN", type); - - scan_size = jtag_build_buffer(cmd->cmd.scan, &buffer); - - predicted_size = ft2232_predict_scan_out(scan_size, type); - if ((predicted_size + 1) > FT2232_BUFFER_SIZE) { - LOG_DEBUG("oversized ft2232 scan (predicted_size > FT2232_BUFFER_SIZE)"); - /* unsent commands before this */ - if (first_unsent != cmd) - if (ft2232_send_and_recv(first_unsent, cmd) != ERROR_OK) - retval = ERROR_JTAG_QUEUE_FAILED; - - /* current command */ - ft2232_end_state(cmd->cmd.scan->end_state); - ft2232_large_scan(cmd->cmd.scan, type, buffer, scan_size); - require_send = 0; - first_unsent = cmd->next; - if (buffer) - free(buffer); - return retval; - } else if (ft2232_buffer_size + predicted_size + 1 > FT2232_BUFFER_SIZE) { - LOG_DEBUG( - "ft2232 buffer size reached, sending queued commands (first_unsent: %p, cmd: %p)", - first_unsent, - cmd); - if (ft2232_send_and_recv(first_unsent, cmd) != ERROR_OK) - retval = ERROR_JTAG_QUEUE_FAILED; - require_send = 0; - first_unsent = cmd; - } - ft2232_expect_read += ft2232_predict_scan_in(scan_size, type); - /* LOG_DEBUG("new read size: %i", ft2232_expect_read); */ - ft2232_end_state(cmd->cmd.scan->end_state); - ft2232_add_scan(cmd->cmd.scan->ir_scan, type, buffer, scan_size); - require_send = 1; - if (buffer) - free(buffer); - 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())); - return retval; - -} - -static int ft2232_execute_reset(struct jtag_command *cmd) -{ - int retval; - int predicted_size = 0; - retval = ERROR_OK; - - DEBUG_JTAG_IO("reset trst: %i srst %i", - cmd->cmd.reset->trst, cmd->cmd.reset->srst); - - /* only send the maximum buffer size that FT2232C can handle */ - predicted_size = 3; - if (ft2232_buffer_size + predicted_size + 1 > FT2232_BUFFER_SIZE) { - if (ft2232_send_and_recv(first_unsent, cmd) != ERROR_OK) - retval = ERROR_JTAG_QUEUE_FAILED; - require_send = 0; - first_unsent = cmd; - } - - if ((cmd->cmd.reset->trst == 1) || - (cmd->cmd.reset->srst && (jtag_get_reset_config() & RESET_SRST_PULLS_TRST))) - tap_set_state(TAP_RESET); - - layout->reset(cmd->cmd.reset->trst, cmd->cmd.reset->srst); - require_send = 1; - - DEBUG_JTAG_IO("trst: %i, srst: %i", - cmd->cmd.reset->trst, cmd->cmd.reset->srst); - return retval; -} - -static int ft2232_execute_sleep(struct jtag_command *cmd) -{ - int retval; - retval = ERROR_OK; - - DEBUG_JTAG_IO("sleep %" PRIi32, cmd->cmd.sleep->us); - - if (ft2232_send_and_recv(first_unsent, cmd) != ERROR_OK) - retval = ERROR_JTAG_QUEUE_FAILED; - first_unsent = cmd->next; - jtag_sleep(cmd->cmd.sleep->us); - DEBUG_JTAG_IO("sleep %" PRIi32 " usec while in %s", - cmd->cmd.sleep->us, - tap_state_name(tap_get_state())); - return retval; -} - -static int ft2232_execute_stableclocks(struct jtag_command *cmd) -{ - int retval; - retval = ERROR_OK; - - /* this is only allowed while in a stable state. A check for a stable - * state was done in jtag_add_clocks() - */ - if (ft2232_stableclocks(cmd->cmd.stableclocks->num_cycles, cmd) != ERROR_OK) - retval = ERROR_JTAG_QUEUE_FAILED; - DEBUG_JTAG_IO("clocks %i while in %s", - cmd->cmd.stableclocks->num_cycles, - tap_state_name(tap_get_state())); - return retval; -} - -static int ft2232_execute_command(struct jtag_command *cmd) -{ - int retval; - - switch (cmd->type) { - case JTAG_RESET: - retval = ft2232_execute_reset(cmd); - break; - case JTAG_RUNTEST: - retval = ft2232_execute_runtest(cmd); - break; - case JTAG_TLR_RESET: - retval = ft2232_execute_statemove(cmd); - break; - case JTAG_PATHMOVE: - retval = ft2232_execute_pathmove(cmd); - break; - case JTAG_SCAN: - retval = ft2232_execute_scan(cmd); - break; - case JTAG_SLEEP: - retval = ft2232_execute_sleep(cmd); - break; - case JTAG_STABLECLOCKS: - retval = ft2232_execute_stableclocks(cmd); - break; - case JTAG_TMS: - retval = ft2232_execute_tms(cmd); - break; - default: - LOG_ERROR("BUG: unknown JTAG command type encountered"); - retval = ERROR_JTAG_QUEUE_FAILED; - break; - } - return retval; -} - -static int ft2232_execute_queue(void) -{ - struct jtag_command *cmd = jtag_command_queue; /* currently processed command */ - int retval; - - first_unsent = cmd; /* next command that has to be sent */ - require_send = 0; - - /* return ERROR_OK, unless ft2232_send_and_recv reports a failed check - * that wasn't handled by a caller-provided error handler - */ - retval = ERROR_OK; - - ft2232_buffer_size = 0; - ft2232_expect_read = 0; - - /* blink, if the current layout has that feature */ - if (layout->blink) - layout->blink(); - - while (cmd) { - /* fill the write buffer with the desired command */ - if (ft2232_execute_command(cmd) != ERROR_OK) - retval = ERROR_JTAG_QUEUE_FAILED; - /* Start reading input before FT2232 TX buffer fills up. - * Sometimes this happens because we don't know the - * length of the last command before we execute it. So - * we simple inform the user. - */ - cmd = cmd->next; - - if (ft2232_expect_read >= FT2232_BUFFER_READ_QUEUE_SIZE) { - if (ft2232_expect_read > (FT2232_BUFFER_READ_QUEUE_SIZE+1)) - LOG_DEBUG("read buffer size looks too high %d/%d", - ft2232_expect_read, - (FT2232_BUFFER_READ_QUEUE_SIZE+1)); - if (ft2232_send_and_recv(first_unsent, cmd) != ERROR_OK) - retval = ERROR_JTAG_QUEUE_FAILED; - first_unsent = cmd; - } - } - - if (require_send > 0) - if (ft2232_send_and_recv(first_unsent, cmd) != ERROR_OK) - retval = ERROR_JTAG_QUEUE_FAILED; - - return retval; -} - -#if BUILD_FT2232_FTD2XX == 1 -static int ft2232_init_ftd2xx(uint16_t vid, uint16_t pid, int more, int *try_more) -{ - FT_STATUS status; - DWORD deviceID; - char SerialNumber[16]; - char Description[64]; - DWORD openex_flags = 0; - char *openex_string = NULL; - uint8_t latency_timer; - - if (layout == NULL) { - LOG_WARNING("No ft2232 layout specified'"); - return ERROR_JTAG_INIT_FAILED; - } - - LOG_DEBUG("'ft2232' interface using FTD2XX with '%s' layout (%4.4x:%4.4x)", - layout->name, vid, pid); - -#if IS_WIN32 == 0 - /* Add non-standard Vid/Pid to the linux driver */ - status = FT_SetVIDPID(vid, pid); - if (status != FT_OK) - LOG_WARNING("couldn't add %4.4x:%4.4x", vid, pid); - -#endif - - if (ft2232_device_desc && ft2232_serial) { - LOG_WARNING( - "can't open by device description and serial number, giving precedence to serial"); - ft2232_device_desc = NULL; - } - - if (ft2232_device_desc) { - openex_string = ft2232_device_desc; - openex_flags = FT_OPEN_BY_DESCRIPTION; - } else if (ft2232_serial) { - openex_string = ft2232_serial; - openex_flags = FT_OPEN_BY_SERIAL_NUMBER; - } else { - LOG_ERROR("neither device description nor serial number specified"); - LOG_ERROR( - "please add \"ft2232_device_desc \" or \"ft2232_serial \" to your .cfg file"); - - return ERROR_JTAG_INIT_FAILED; - } - - status = FT_OpenEx(openex_string, openex_flags, &ftdih); - if (status != FT_OK) { - /* under Win32, the FTD2XX driver appends an "A" to the end - * of the description, if we tried by the desc, then - * try by the alternate "A" description. */ - if (openex_string == ft2232_device_desc) { - /* Try the alternate method. */ - openex_string = ft2232_device_desc_A; - status = FT_OpenEx(openex_string, openex_flags, &ftdih); - if (status == FT_OK) { - /* yea, the "alternate" method worked! */ - } else { - /* drat, give the user a meaningfull message. - * telling the use we tried *BOTH* methods. */ - LOG_WARNING("Unable to open FTDI Device tried: '%s' and '%s'", - ft2232_device_desc, - ft2232_device_desc_A); - } - } - } - - if (status != FT_OK) { - DWORD num_devices; - - if (more) { - LOG_WARNING("unable to open ftdi device (trying more): %s", - ftd2xx_status_string(status)); - *try_more = 1; - return ERROR_JTAG_INIT_FAILED; - } - LOG_ERROR("unable to open ftdi device: %s", - ftd2xx_status_string(status)); - status = FT_ListDevices(&num_devices, NULL, FT_LIST_NUMBER_ONLY); - if (status == FT_OK) { - char **desc_array = malloc(sizeof(char *) * (num_devices + 1)); - uint32_t 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 | openex_flags); - - if (status == FT_OK) { - LOG_ERROR("ListDevices: %" PRIu32, (uint32_t)num_devices); - for (i = 0; i < num_devices; i++) - LOG_ERROR("%" PRIu32 ": \"%s\"", i, desc_array[i]); - } - - for (i = 0; i < num_devices; i++) - free(desc_array[i]); - - free(desc_array); - } else - LOG_ERROR("ListDevices: NONE"); - return ERROR_JTAG_INIT_FAILED; - } - - status = FT_SetLatencyTimer(ftdih, ft2232_latency); - if (status != FT_OK) { - LOG_ERROR("unable to set latency timer: %s", - ftd2xx_status_string(status)); - return ERROR_JTAG_INIT_FAILED; - } - - status = FT_GetLatencyTimer(ftdih, &latency_timer); - if (status != FT_OK) { - /* ftd2xx 1.04 (linux) has a bug when calling FT_GetLatencyTimer - * so ignore errors if using this driver version */ - DWORD dw_version; - - status = FT_GetDriverVersion(ftdih, &dw_version); - LOG_ERROR("unable to get latency timer: %s", - ftd2xx_status_string(status)); - - if ((status == FT_OK) && (dw_version == 0x10004)) { - LOG_ERROR("ftd2xx 1.04 detected - this has known issues " \ - "with FT_GetLatencyTimer, upgrade to a newer version"); - } else - return ERROR_JTAG_INIT_FAILED; - } else - LOG_DEBUG("current latency timer: %i", latency_timer); - - status = FT_SetTimeouts(ftdih, 5000, 5000); - if (status != FT_OK) { - LOG_ERROR("unable to set timeouts: %s", - ftd2xx_status_string(status)); - return ERROR_JTAG_INIT_FAILED; - } - - status = FT_SetBitMode(ftdih, 0x0b, 2); - if (status != FT_OK) { - LOG_ERROR("unable to enable bit i/o mode: %s", - ftd2xx_status_string(status)); - return ERROR_JTAG_INIT_FAILED; - } - - status = FT_GetDeviceInfo(ftdih, &ftdi_device, &deviceID, - SerialNumber, Description, NULL); - if (status != FT_OK) { - LOG_ERROR("unable to get FT_GetDeviceInfo: %s", - ftd2xx_status_string(status)); - return ERROR_JTAG_INIT_FAILED; - } else { - static const char *type_str[] = { - "BM", "AM", "100AX", "UNKNOWN", "2232C", "232R", "2232H", "4232H", "232H" - }; - unsigned no_of_known_types = ARRAY_SIZE(type_str) - 1; - unsigned type_index = ((unsigned)ftdi_device <= no_of_known_types) - ? ftdi_device : FT_DEVICE_UNKNOWN; - LOG_INFO("device: %" PRIu32 " \"%s\"", (uint32_t)ftdi_device, type_str[type_index]); - LOG_INFO("deviceID: %" PRIu32, (uint32_t)deviceID); - LOG_INFO("SerialNumber: %s", SerialNumber); - LOG_INFO("Description: %s", Description); - } - - return ERROR_OK; -} - -static int ft2232_purge_ftd2xx(void) -{ - FT_STATUS status; - - status = FT_Purge(ftdih, FT_PURGE_RX | FT_PURGE_TX); - if (status != FT_OK) { - LOG_ERROR("error purging ftd2xx device: %s", - ftd2xx_status_string(status)); - return ERROR_JTAG_INIT_FAILED; - } - - return ERROR_OK; -} - -#endif /* BUILD_FT2232_FTD2XX == 1 */ - -#if BUILD_FT2232_LIBFTDI == 1 -static int ft2232_init_libftdi(uint16_t vid, uint16_t pid, int more, int *try_more, int channel) -{ - uint8_t latency_timer; - - if (layout == NULL) { - LOG_WARNING("No ft2232 layout specified'"); - return ERROR_JTAG_INIT_FAILED; - } - - LOG_DEBUG("'ft2232' interface using libftdi with '%s' layout (%4.4x:%4.4x)", - layout->name, vid, pid); - - if (ftdi_init(&ftdic) < 0) - return ERROR_JTAG_INIT_FAILED; - - /* default to INTERFACE_A */ - if (channel == INTERFACE_ANY) - channel = INTERFACE_A; - if (ftdi_set_interface(&ftdic, channel) < 0) { - LOG_ERROR("unable to select FT2232 channel A: %s", ftdic.error_str); - return ERROR_JTAG_INIT_FAILED; - } - - /* context, vendor id, product id */ - if (ftdi_usb_open_desc(&ftdic, vid, pid, ft2232_device_desc, ft2232_serial) < 0) { - if (more) - LOG_WARNING("unable to open ftdi device (trying more): %s", - ftdic.error_str); - else - LOG_ERROR("unable to open ftdi device: %s", ftdic.error_str); - *try_more = 1; - return ERROR_JTAG_INIT_FAILED; - } - - /* There is already a reset in ftdi_usb_open_desc, this should be redundant */ - if (ftdi_usb_reset(&ftdic) < 0) { - LOG_ERROR("unable to reset ftdi device"); - return ERROR_JTAG_INIT_FAILED; - } - - if (ftdi_set_latency_timer(&ftdic, ft2232_latency) < 0) { - LOG_ERROR("unable to set latency timer"); - return ERROR_JTAG_INIT_FAILED; - } - - if (ftdi_get_latency_timer(&ftdic, &latency_timer) < 0) { - LOG_ERROR("unable to get latency timer"); - return ERROR_JTAG_INIT_FAILED; - } else - LOG_DEBUG("current latency timer: %i", latency_timer); - - ftdi_set_bitmode(&ftdic, 0x0b, 2); /* ctx, JTAG I/O mask */ - - ftdi_device = ftdic.type; - static const char *type_str[] = { - "AM", "BM", "2232C", "R", "2232H", "4232H", "232H", "Unknown" - }; - unsigned no_of_known_types = ARRAY_SIZE(type_str) - 1; - unsigned type_index = ((unsigned)ftdi_device < no_of_known_types) - ? ftdi_device : no_of_known_types; - LOG_DEBUG("FTDI chip type: %i \"%s\"", (int)ftdi_device, type_str[type_index]); - return ERROR_OK; -} - -static int ft2232_purge_libftdi(void) -{ - if (ftdi_usb_purge_buffers(&ftdic) < 0) { - LOG_ERROR("ftdi_purge_buffers: %s", ftdic.error_str); - return ERROR_JTAG_INIT_FAILED; - } - - return ERROR_OK; -} - -#endif /* BUILD_FT2232_LIBFTDI == 1 */ - -static int ft2232_set_data_bits_low_byte(uint8_t value, uint8_t direction) -{ - uint8_t buf[3]; - uint32_t bytes_written; - - buf[0] = 0x80; /* command "set data bits low byte" */ - buf[1] = value; /* value */ - buf[2] = direction; /* direction */ - - LOG_DEBUG("%2.2x %2.2x %2.2x", buf[0], buf[1], buf[2]); - - if (ft2232_write(buf, sizeof(buf), &bytes_written) != ERROR_OK) { - LOG_ERROR("couldn't initialize data bits low byte"); - return ERROR_JTAG_INIT_FAILED; - } - - return ERROR_OK; -} - -static int ft2232_set_data_bits_high_byte(uint8_t value, uint8_t direction) -{ - uint8_t buf[3]; - uint32_t bytes_written; - - buf[0] = 0x82; /* command "set data bits high byte" */ - buf[1] = value; /* value */ - buf[2] = direction; /* direction */ - - LOG_DEBUG("%2.2x %2.2x %2.2x", buf[0], buf[1], buf[2]); - - if (ft2232_write(buf, sizeof(buf), &bytes_written) != ERROR_OK) { - LOG_ERROR("couldn't initialize data bits high byte"); - return ERROR_JTAG_INIT_FAILED; - } - - return ERROR_OK; -} - -static int ft2232_init(void) -{ - uint8_t buf[1]; - int retval; - uint32_t bytes_written; - - LOG_WARNING("Using DEPRECATED interface driver 'ft2232'"); -#if BUILD_FTDI - LOG_INFO("Consider using the 'ftdi' interface driver, with configuration files in interface/ftdi/..."); -#endif - - if (tap_get_tms_path_len(TAP_IRPAUSE, TAP_IRPAUSE) == 7) - LOG_DEBUG("ft2232 interface using 7 step jtag state transitions"); - else - LOG_DEBUG("ft2232 interface using shortest path jtag state transitions"); - if (layout == NULL) { - LOG_WARNING("No ft2232 layout specified'"); - return ERROR_JTAG_INIT_FAILED; - } - - for (int i = 0; 1; i++) { - /* - * "more indicates that there are more IDs to try, so we should - * not print an error for an ID mismatch (but for anything - * else, we should). - * - * try_more indicates that the error code returned indicates an - * ID mismatch (and nothing else) and that we should proceeed - * with the next ID pair. - */ - int more = ft2232_vid[i + 1] || ft2232_pid[i + 1]; - int try_more = 0; - -#if BUILD_FT2232_FTD2XX == 1 - retval = ft2232_init_ftd2xx(ft2232_vid[i], ft2232_pid[i], - more, &try_more); -#elif BUILD_FT2232_LIBFTDI == 1 - retval = ft2232_init_libftdi(ft2232_vid[i], ft2232_pid[i], - more, &try_more, ft2232_channel); -#endif - if (retval >= 0) - break; - if (!more || !try_more) - return retval; - } - - ft2232_buffer_size = 0; - ft2232_buffer = malloc(FT2232_BUFFER_SIZE); - - if (layout->init() != ERROR_OK) - return ERROR_JTAG_INIT_FAILED; - - if (ft2232_device_is_highspeed()) { -#ifndef BUILD_FT2232_HIGHSPEED - #if BUILD_FT2232_FTD2XX == 1 - LOG_WARNING( - "High Speed device found - You need a newer FTD2XX driver (version 2.04.16 or later)"); - #elif BUILD_FT2232_LIBFTDI == 1 - LOG_WARNING( - "High Speed device found - You need a newer libftdi version (0.16 or later)"); - #endif -#endif - /* make sure the legacy mode is disabled */ - if (ftx232h_clk_divide_by_5(false) != ERROR_OK) - return ERROR_JTAG_INIT_FAILED; - } - - buf[0] = 0x85; /* Disconnect TDI/DO to TDO/DI for Loopback */ - retval = ft2232_write(buf, 1, &bytes_written); - if (retval != ERROR_OK) { - LOG_ERROR("couldn't write to FT2232 to disable loopback"); - return ERROR_JTAG_INIT_FAILED; - } - -#if BUILD_FT2232_FTD2XX == 1 - return ft2232_purge_ftd2xx(); -#elif BUILD_FT2232_LIBFTDI == 1 - return ft2232_purge_libftdi(); -#endif - - return ERROR_OK; -} - -/** Updates defaults for DBUS signals: the four JTAG signals - * (TCK, TDI, TDO, TMS) and * the four GPIOL signals. - */ -static inline void ftx232_dbus_init(void) -{ - low_output = 0x08; - low_direction = 0x0b; -} - -/** Initializes DBUS signals: the four JTAG signals (TCK, TDI, TDO, TMS), - * the four GPIOL signals. Initialization covers value and direction, - * as customized for each layout. - */ -static int ftx232_dbus_write(void) -{ - enum reset_types jtag_reset_config = jtag_get_reset_config(); - if (jtag_reset_config & RESET_TRST_OPEN_DRAIN) { - low_direction &= ~nTRSTnOE; /* nTRST input */ - low_output &= ~nTRST; /* nTRST = 0 */ - } else { - low_direction |= nTRSTnOE; /* nTRST output */ - low_output |= nTRST; /* nTRST = 1 */ - } - - if (jtag_reset_config & RESET_SRST_PUSH_PULL) { - low_direction |= nSRSTnOE; /* nSRST output */ - low_output |= nSRST; /* nSRST = 1 */ - } else { - low_direction &= ~nSRSTnOE; /* nSRST input */ - low_output &= ~nSRST; /* nSRST = 0 */ - } - - /* initialize low byte for jtag */ - if (ft2232_set_data_bits_low_byte(low_output, low_direction) != ERROR_OK) { - LOG_ERROR("couldn't initialize FT2232 DBUS"); - return ERROR_JTAG_INIT_FAILED; - } - - return ERROR_OK; -} - -static int usbjtag_init(void) -{ - /* - * NOTE: This is now _specific_ to the "usbjtag" layout. - * Don't try cram any more layouts into this. - */ - ftx232_dbus_init(); - - nTRST = 0x10; - nTRSTnOE = 0x10; - nSRST = 0x40; - nSRSTnOE = 0x40; - - return ftx232_dbus_write(); -} - -static int lm3s811_jtag_init(void) -{ - ftx232_dbus_init(); - - /* There are multiple revisions of LM3S811 eval boards: - * - Rev B (and older?) boards have no SWO trace support. - * - Rev C boards add ADBUS_6 DBG_ENn and BDBUS_4 SWO_EN; - * they should use the "luminary_icdi" layout instead. - */ - nTRST = 0x0; - nTRSTnOE = 0x00; - nSRST = 0x20; - nSRSTnOE = 0x20; - low_output = 0x88; - low_direction = 0x8b; - - return ftx232_dbus_write(); -} - -static int icdi_jtag_init(void) -{ - ftx232_dbus_init(); - - /* Most Luminary eval boards support SWO trace output, - * and should use this "luminary_icdi" layout. - * - * ADBUS 0..3 are used for JTAG as usual. GPIOs are used - * to switch between JTAG and SWD, or switch the ft2232 UART - * on the second MPSSE channel/interface (BDBUS) - * between (i) the stellaris UART (on Luminary boards) - * or (ii) SWO trace data (generic). - * - * We come up in JTAG mode and may switch to SWD later (with - * SWO/trace option if SWD is active). - * - * DBUS == GPIO-Lx - * CBUS == GPIO-Hx - */ - - -#define ICDI_JTAG_EN (1 << 7) /* ADBUS 7 (a.k.a. DBGMOD) */ -#define ICDI_DBG_ENn (1 << 6) /* ADBUS 6 */ -#define ICDI_SRST (1 << 5) /* ADBUS 5 */ - - - /* GPIOs on second channel/interface (UART) ... */ -#define ICDI_SWO_EN (1 << 4) /* BDBUS 4 */ -#define ICDI_TX_SWO (1 << 1) /* BDBUS 1 */ -#define ICDI_VCP_RX (1 << 0) /* BDBUS 0 (to stellaris UART) */ - - nTRST = 0x0; - nTRSTnOE = 0x00; - nSRST = ICDI_SRST; - nSRSTnOE = ICDI_SRST; - - low_direction |= ICDI_JTAG_EN | ICDI_DBG_ENn; - low_output |= ICDI_JTAG_EN; - low_output &= ~ICDI_DBG_ENn; - - return ftx232_dbus_write(); -} - -static int signalyzer_init(void) -{ - ftx232_dbus_init(); - - nTRST = 0x10; - nTRSTnOE = 0x10; - nSRST = 0x20; - nSRSTnOE = 0x20; - return ftx232_dbus_write(); -} - -static int axm0432_jtag_init(void) -{ - low_output = 0x08; - low_direction = 0x2b; - - /* initialize low byte for jtag */ - if (ft2232_set_data_bits_low_byte(low_output, low_direction) != ERROR_OK) { - LOG_ERROR("couldn't initialize FT2232 with 'JTAGkey' layout"); - return ERROR_JTAG_INIT_FAILED; - } - - if (strcmp(layout->name, "axm0432_jtag") == 0) { - nTRST = 0x08; - nTRSTnOE = 0x0; /* No output enable for TRST*/ - nSRST = 0x04; - nSRSTnOE = 0x0; /* No output enable for SRST*/ - } else { - LOG_ERROR("BUG: axm0432_jtag_init called for non axm0432 layout"); - exit(-1); - } - - high_output = 0x0; - high_direction = 0x0c; - - enum reset_types jtag_reset_config = jtag_get_reset_config(); - if (jtag_reset_config & RESET_TRST_OPEN_DRAIN) - LOG_ERROR("can't set nTRSTOE to push-pull on the Dicarlo jtag"); - else - high_output |= nTRST; - - if (jtag_reset_config & RESET_SRST_PUSH_PULL) - LOG_ERROR("can't set nSRST to push-pull on the Dicarlo jtag"); - else - high_output |= nSRST; - - /* initialize high byte for jtag */ - if (ft2232_set_data_bits_high_byte(high_output, high_direction) != ERROR_OK) { - LOG_ERROR("couldn't initialize FT2232 with 'Dicarlo' layout"); - return ERROR_JTAG_INIT_FAILED; - } - - return ERROR_OK; -} - -static int redbee_init(void) -{ - low_output = 0x08; - low_direction = 0x2b; - - /* initialize low byte for jtag */ - if (ft2232_set_data_bits_low_byte(low_output, low_direction) != ERROR_OK) { - LOG_ERROR("couldn't initialize FT2232 with 'redbee' layout"); - return ERROR_JTAG_INIT_FAILED; - } - - nTRST = 0x08; - nTRSTnOE = 0x0; /* No output enable for TRST*/ - nSRST = 0x04; - nSRSTnOE = 0x0; /* No output enable for SRST*/ - - high_output = 0x0; - high_direction = 0x0c; - - enum reset_types jtag_reset_config = jtag_get_reset_config(); - if (jtag_reset_config & RESET_TRST_OPEN_DRAIN) - LOG_ERROR("can't set nTRSTOE to push-pull on redbee"); - else - high_output |= nTRST; - - if (jtag_reset_config & RESET_SRST_PUSH_PULL) - LOG_ERROR("can't set nSRST to push-pull on redbee"); - else - high_output |= nSRST; - - /* initialize high byte for jtag */ - if (ft2232_set_data_bits_high_byte(high_output, high_direction) != ERROR_OK) { - LOG_ERROR("couldn't initialize FT2232 with 'redbee' layout"); - return ERROR_JTAG_INIT_FAILED; - } - - return ERROR_OK; -} - -static int jtagkey_init(void) -{ - low_output = 0x08; - low_direction = 0x1b; - - /* initialize low byte for jtag */ - if (ft2232_set_data_bits_low_byte(low_output, low_direction) != ERROR_OK) { - LOG_ERROR("couldn't initialize FT2232 with 'JTAGkey' layout"); - return ERROR_JTAG_INIT_FAILED; - } - - if (strcmp(layout->name, "jtagkey") == 0) { - nTRST = 0x01; - nTRSTnOE = 0x4; - nSRST = 0x02; - nSRSTnOE = 0x08; - } else if ((strcmp(layout->name, "jtagkey_prototype_v1") == 0) - || (strcmp(layout->name, "oocdlink") == 0)) { - nTRST = 0x02; - nTRSTnOE = 0x1; - nSRST = 0x08; - nSRSTnOE = 0x04; - } else { - LOG_ERROR("BUG: jtagkey_init called for non jtagkey layout"); - exit(-1); - } - - high_output = 0x0; - high_direction = 0x0f; - - enum reset_types jtag_reset_config = jtag_get_reset_config(); - if (jtag_reset_config & RESET_TRST_OPEN_DRAIN) { - high_output |= nTRSTnOE; - high_output &= ~nTRST; - } else { - high_output &= ~nTRSTnOE; - high_output |= nTRST; - } - - if (jtag_reset_config & RESET_SRST_PUSH_PULL) { - high_output &= ~nSRSTnOE; - high_output |= nSRST; - } else { - high_output |= nSRSTnOE; - high_output &= ~nSRST; - } - - /* initialize high byte for jtag */ - if (ft2232_set_data_bits_high_byte(high_output, high_direction) != ERROR_OK) { - LOG_ERROR("couldn't initialize FT2232 with 'JTAGkey' layout"); - return ERROR_JTAG_INIT_FAILED; - } - - return ERROR_OK; -} - -static int olimex_jtag_init(void) -{ - low_output = 0x08; - low_direction = 0x1b; - - /* initialize low byte for jtag */ - if (ft2232_set_data_bits_low_byte(low_output, low_direction) != ERROR_OK) { - LOG_ERROR("couldn't initialize FT2232 with 'Olimex' layout"); - return ERROR_JTAG_INIT_FAILED; - } - - nTRST = 0x01; - nTRSTnOE = 0x4; - nSRST = 0x02; - nSRSTnOE = 0x00;/* no output enable for nSRST */ - - high_output = 0x0; - high_direction = 0x0f; - - enum reset_types jtag_reset_config = jtag_get_reset_config(); - if (jtag_reset_config & RESET_TRST_OPEN_DRAIN) { - high_output |= nTRSTnOE; - high_output &= ~nTRST; - } else { - high_output &= ~nTRSTnOE; - high_output |= nTRST; - } - - if (jtag_reset_config & RESET_SRST_PUSH_PULL) - LOG_ERROR("can't set nSRST to push-pull on the Olimex ARM-USB-OCD"); - else - high_output &= ~nSRST; - - /* turn red LED on */ - high_output |= 0x08; - - /* initialize high byte for jtag */ - if (ft2232_set_data_bits_high_byte(high_output, high_direction) != ERROR_OK) { - LOG_ERROR("couldn't initialize FT2232 with 'Olimex' layout"); - return ERROR_JTAG_INIT_FAILED; - } - - return ERROR_OK; -} - -static int flyswatter_init(int rev) -{ - low_output = 0x18; - low_direction = 0x7b; - - if ((rev < 0) || (rev > 3)) { - LOG_ERROR("bogus 'flyswatter' revision supplied (%i)", rev); - return ERROR_JTAG_INIT_FAILED; - } - - if (rev == 1) - low_direction |= 1 << 7; - - /* initialize low byte for jtag */ - if (ft2232_set_data_bits_low_byte(low_output, low_direction) != ERROR_OK) { - LOG_ERROR("couldn't initialize FT2232 with 'flyswatter' layout"); - return ERROR_JTAG_INIT_FAILED; - } - - nTRST = 0x10; - nTRSTnOE = 0x0; /* not output enable for nTRST */ - nSRST = 0x20; - nSRSTnOE = 0x00; /* no output enable for nSRST */ - - high_output = 0x00; - - if (rev == 1) - high_direction = 0x0c; - else - high_direction = 0x01; - - /* turn red LED3 on, LED2 off */ - high_output |= 0x08; - - /* initialize high byte for jtag */ - if (ft2232_set_data_bits_high_byte(high_output, high_direction) != ERROR_OK) { - LOG_ERROR("couldn't initialize FT2232 with 'flyswatter' layout"); - return ERROR_JTAG_INIT_FAILED; - } - - return ERROR_OK; -} - -static int flyswatter1_init(void) -{ - return flyswatter_init(1); -} - -static int flyswatter2_init(void) -{ - return flyswatter_init(2); -} - -static int minimodule_init(void) -{ - low_output = 0x18; /* check if srst should be 1 or 0 initially. (0x08) (flyswatter was - * 0x18) */ - low_direction = 0xfb; /* 0xfb; */ - - /* initialize low byte for jtag */ - if (ft2232_set_data_bits_low_byte(low_output, low_direction) != ERROR_OK) { - LOG_ERROR("couldn't initialize FT2232 with 'minimodule' layout"); - return ERROR_JTAG_INIT_FAILED; - } - - - nSRST = 0x20; - - high_output = 0x00; - high_direction = 0x05; - - /* turn red LED3 on, LED2 off */ - /* high_output |= 0x08; */ - - /* initialize high byte for jtag */ - if (ft2232_set_data_bits_high_byte(high_output, high_direction) != ERROR_OK) { - LOG_ERROR("couldn't initialize FT2232 with 'minimodule' layout"); - return ERROR_JTAG_INIT_FAILED; - } - - return ERROR_OK; -} - -static int turtle_init(void) -{ - low_output = 0x08; - low_direction = 0x5b; - - /* initialize low byte for jtag */ - if (ft2232_set_data_bits_low_byte(low_output, low_direction) != ERROR_OK) { - LOG_ERROR("couldn't initialize FT2232 with 'turtelizer2' layout"); - return ERROR_JTAG_INIT_FAILED; - } - - nSRST = 0x40; - - high_output = 0x00; - high_direction = 0x0C; - - /* initialize high byte for jtag */ - if (ft2232_set_data_bits_high_byte(high_output, high_direction) != ERROR_OK) { - LOG_ERROR("couldn't initialize FT2232 with 'turtelizer2' layout"); - return ERROR_JTAG_INIT_FAILED; - } - - return ERROR_OK; -} - -static int comstick_init(void) -{ - low_output = 0x08; - low_direction = 0x0b; - - /* initialize low byte for jtag */ - if (ft2232_set_data_bits_low_byte(low_output, low_direction) != ERROR_OK) { - LOG_ERROR("couldn't initialize FT2232 with 'comstick' layout"); - return ERROR_JTAG_INIT_FAILED; - } - - nTRST = 0x01; - nTRSTnOE = 0x00; /* no output enable for nTRST */ - nSRST = 0x02; - nSRSTnOE = 0x00; /* no output enable for nSRST */ - - high_output = 0x03; - high_direction = 0x03; - - /* initialize high byte for jtag */ - if (ft2232_set_data_bits_high_byte(high_output, high_direction) != ERROR_OK) { - LOG_ERROR("couldn't initialize FT2232 with 'comstick' layout"); - return ERROR_JTAG_INIT_FAILED; - } - - return ERROR_OK; -} - -static int stm32stick_init(void) -{ - low_output = 0x88; - low_direction = 0x8b; - - /* initialize low byte for jtag */ - if (ft2232_set_data_bits_low_byte(low_output, low_direction) != ERROR_OK) { - LOG_ERROR("couldn't initialize FT2232 with 'stm32stick' layout"); - return ERROR_JTAG_INIT_FAILED; - } - - nTRST = 0x01; - nTRSTnOE = 0x00; /* no output enable for nTRST */ - nSRST = 0x80; - nSRSTnOE = 0x00; /* no output enable for nSRST */ - - high_output = 0x01; - high_direction = 0x03; - - /* initialize high byte for jtag */ - if (ft2232_set_data_bits_high_byte(high_output, high_direction) != ERROR_OK) { - LOG_ERROR("couldn't initialize FT2232 with 'stm32stick' layout"); - return ERROR_JTAG_INIT_FAILED; - } - - return ERROR_OK; -} - -static int sheevaplug_init(void) -{ - low_output = 0x08; - low_direction = 0x1b; - - /* initialize low byte for jtag */ - if (ft2232_set_data_bits_low_byte(low_output, low_direction) != ERROR_OK) { - LOG_ERROR("couldn't initialize FT2232 with 'sheevaplug' layout"); - return ERROR_JTAG_INIT_FAILED; - } - - nTRSTnOE = 0x1; - nTRST = 0x02; - nSRSTnOE = 0x4; - nSRST = 0x08; - - high_output = 0x0; - high_direction = 0x0f; - - /* nTRST is always push-pull */ - high_output &= ~nTRSTnOE; - high_output |= nTRST; - - /* nSRST is always open-drain */ - high_output |= nSRSTnOE; - high_output &= ~nSRST; - - /* initialize high byte for jtag */ - if (ft2232_set_data_bits_high_byte(high_output, high_direction) != ERROR_OK) { - LOG_ERROR("couldn't initialize FT2232 with 'sheevaplug' layout"); - return ERROR_JTAG_INIT_FAILED; - } - - return ERROR_OK; -} - -static int cortino_jtag_init(void) -{ - low_output = 0x08; - low_direction = 0x1b; - - /* initialize low byte for jtag */ - if (ft2232_set_data_bits_low_byte(low_output, low_direction) != ERROR_OK) { - LOG_ERROR("couldn't initialize FT2232 with 'cortino' layout"); - return ERROR_JTAG_INIT_FAILED; - } - - nTRST = 0x01; - nTRSTnOE = 0x00; /* no output enable for nTRST */ - nSRST = 0x02; - nSRSTnOE = 0x00; /* no output enable for nSRST */ - - high_output = 0x03; - high_direction = 0x03; - - /* initialize high byte for jtag */ - if (ft2232_set_data_bits_high_byte(high_output, high_direction) != ERROR_OK) { - LOG_ERROR("couldn't initialize FT2232 with 'cortino' layout"); - return ERROR_JTAG_INIT_FAILED; - } - - return ERROR_OK; -} - -static int lisa_l_init(void) -{ - ftx232_dbus_init(); - - nTRST = 0x10; - nTRSTnOE = 0x10; - nSRST = 0x40; - nSRSTnOE = 0x40; - - high_output = 0x00; - high_direction = 0x18; - - /* initialize high byte for jtag */ - if (ft2232_set_data_bits_high_byte(high_output, high_direction) != ERROR_OK) { - LOG_ERROR("couldn't initialize FT2232 with 'lisa_l' layout"); - return ERROR_JTAG_INIT_FAILED; - } - - return ftx232_dbus_write(); -} - -static int flossjtag_init(void) -{ - ftx232_dbus_init(); - - nTRST = 0x10; - nTRSTnOE = 0x10; - nSRST = 0x40; - nSRSTnOE = 0x40; - - high_output = 0x00; - high_direction = 0x18; - - /* initialize high byte for jtag */ - if (ft2232_set_data_bits_high_byte(high_output, high_direction) != ERROR_OK) { - LOG_ERROR("couldn't initialize FT2232 with 'Floss-JTAG' layout"); - return ERROR_JTAG_INIT_FAILED; - } - - return ftx232_dbus_write(); -} - -/* - * The reference schematic from TI for the XDS100v2 has a CPLD on which opens - * the door for a number of different configurations - * - * Known Implementations: - * http://processors.wiki.ti.com/images/9/93/TMS570LS20216_USB_STICK_Schematic.pdf - * - * http://processors.wiki.ti.com/index.php/XDS100 (rev2) - * * CLPD logic: Rising edge to enable outputs (XDS100_PWR_RST) - * * ACBUS3 to transition 0->1 (OE rising edge) - * * CPLD logic: Put the EMU0/1 pins in Hi-Z: - * * ADBUS5/GPIOL1 = EMU_EN = 1 - * * ADBUS6/GPIOL2 = EMU0 = 0 - * * ACBUS4/SPARE0 = EMU1 = 0 - * * CPLD logic: Disable loopback - * * ACBUS6/SPARE2 = LOOPBACK = 0 - */ -#define XDS100_nEMU_EN (1<<5) -#define XDS100_nEMU0 (1<<6) - -#define XDS100_PWR_RST (1<<3) -#define XDS100_nEMU1 (1<<4) -#define XDS100_LOOPBACK (1<<6) -static int xds100v2_init(void) -{ - /* These are in the lower byte */ - nTRST = 0x10; - nTRSTnOE = 0x10; - - /* These aren't actually used on 14 pin connectors - * These are in the upper byte */ - nSRST = 0x01; - nSRSTnOE = 0x01; - - low_output = 0x08 | nTRST | XDS100_nEMU_EN; - low_direction = 0x0b | nTRSTnOE | XDS100_nEMU_EN | XDS100_nEMU0; - - if (ft2232_set_data_bits_low_byte(low_output, low_direction) != ERROR_OK) { - LOG_ERROR("couldn't initialize FT2232 with 'xds100v2' layout"); - return ERROR_JTAG_INIT_FAILED; - } - - high_output = 0; - high_direction = nSRSTnOE | XDS100_LOOPBACK | XDS100_PWR_RST | XDS100_nEMU1; - - /* initialize high byte for jtag */ - if (ft2232_set_data_bits_high_byte(high_output, high_direction) != ERROR_OK) { - LOG_ERROR("couldn't put CPLD in to reset with 'xds100v2' layout"); - return ERROR_JTAG_INIT_FAILED; - } - - high_output |= XDS100_PWR_RST; - - /* initialize high byte for jtag */ - if (ft2232_set_data_bits_high_byte(high_output, high_direction) != ERROR_OK) { - LOG_ERROR("couldn't bring CPLD out of reset with 'xds100v2' layout"); - return ERROR_JTAG_INIT_FAILED; - } - - return ERROR_OK; -} - -static void olimex_jtag_blink(void) -{ - /* Olimex ARM-USB-OCD has a LED connected to ACBUS3 - * ACBUS3 is bit 3 of the GPIOH port - */ - high_output ^= 0x08; - - buffer_write(0x82); - buffer_write(high_output); - buffer_write(high_direction); -} - -static void flyswatter_jtag_blink(unsigned char led) -{ - buffer_write(0x82); - buffer_write(high_output ^ led); - buffer_write(high_direction); -} - -static void flyswatter1_jtag_blink(void) -{ - /* - * Flyswatter has two LEDs connected to ACBUS2 and ACBUS3 - */ - flyswatter_jtag_blink(0xc); -} - -static void flyswatter2_jtag_blink(void) -{ - /* - * Flyswatter2 only has one LED connected to ACBUS2 - */ - flyswatter_jtag_blink(0x4); -} - -static void turtle_jtag_blink(void) -{ - /* - * Turtelizer2 has two LEDs connected to ACBUS2 and ACBUS3 - */ - if (high_output & 0x08) - high_output = 0x04; - else - high_output = 0x08; - - buffer_write(0x82); - buffer_write(high_output); - buffer_write(high_direction); -} - -static void lisa_l_blink(void) -{ - /* - * Lisa/L has two LEDs connected to BCBUS3 and BCBUS4 - */ - if (high_output & 0x10) - high_output = 0x08; - else - high_output = 0x10; - - buffer_write(0x82); - buffer_write(high_output); - buffer_write(high_direction); -} - -static void flossjtag_blink(void) -{ - /* - * Floss-JTAG has two LEDs connected to ACBUS3 and ACBUS4 - */ - if (high_output & 0x10) - high_output = 0x08; - else - high_output = 0x10; - - buffer_write(0x82); - buffer_write(high_output); - buffer_write(high_direction); -} - -static int ft2232_quit(void) -{ -#if BUILD_FT2232_FTD2XX == 1 - - FT_Close(ftdih); -#elif BUILD_FT2232_LIBFTDI == 1 - ftdi_usb_close(&ftdic); - - ftdi_deinit(&ftdic); -#endif - - free(ft2232_buffer); - ft2232_buffer = NULL; - - return ERROR_OK; -} - -COMMAND_HANDLER(ft2232_handle_device_desc_command) -{ - char *cp; - char buf[200]; - if (CMD_ARGC == 1) { - ft2232_device_desc = strdup(CMD_ARGV[0]); - cp = strchr(ft2232_device_desc, 0); - /* under Win32, the FTD2XX driver appends an "A" to the end - * of the description, this examines the given desc - * and creates the 'missing' _A or non_A variable. */ - if ((cp[-1] == 'A') && (cp[-2] == ' ')) { - /* it was, so make this the "A" version. */ - ft2232_device_desc_A = ft2232_device_desc; - /* and *CREATE* the non-A version. */ - strcpy(buf, ft2232_device_desc); - cp = strchr(buf, 0); - cp[-2] = 0; - ft2232_device_desc = strdup(buf); - } else { - /* A not defined - * so create it */ - sprintf(buf, "%s A", ft2232_device_desc); - ft2232_device_desc_A = strdup(buf); - } - } else - LOG_ERROR("expected exactly one argument to ft2232_device_desc "); - - return ERROR_OK; -} - -COMMAND_HANDLER(ft2232_handle_serial_command) -{ - if (CMD_ARGC == 1) - ft2232_serial = strdup(CMD_ARGV[0]); - else - return ERROR_COMMAND_SYNTAX_ERROR; - - return ERROR_OK; -} - -COMMAND_HANDLER(ft2232_handle_layout_command) -{ - if (CMD_ARGC != 1) - return ERROR_COMMAND_SYNTAX_ERROR; - - if (layout) { - LOG_ERROR("already specified ft2232_layout %s", - layout->name); - return (strcmp(layout->name, CMD_ARGV[0]) != 0) - ? ERROR_FAIL - : ERROR_OK; - } - - for (const struct ft2232_layout *l = ft2232_layouts; l->name; l++) { - if (strcmp(l->name, CMD_ARGV[0]) == 0) { - layout = l; - ft2232_channel = l->channel; - return ERROR_OK; - } - } - - LOG_ERROR("No FT2232 layout '%s' found", CMD_ARGV[0]); - return ERROR_FAIL; -} - -COMMAND_HANDLER(ft2232_handle_vid_pid_command) -{ - if (CMD_ARGC > MAX_USB_IDS * 2) { - LOG_WARNING("ignoring extra IDs in ft2232_vid_pid " - "(maximum is %d pairs)", MAX_USB_IDS); - CMD_ARGC = MAX_USB_IDS * 2; - } - if (CMD_ARGC < 2 || (CMD_ARGC & 1)) { - LOG_WARNING("incomplete ft2232_vid_pid configuration directive"); - if (CMD_ARGC < 2) - return ERROR_COMMAND_SYNTAX_ERROR; - /* remove the incomplete trailing id */ - CMD_ARGC -= 1; - } - - unsigned i; - for (i = 0; i < CMD_ARGC; i += 2) { - COMMAND_PARSE_NUMBER(u16, CMD_ARGV[i], ft2232_vid[i >> 1]); - COMMAND_PARSE_NUMBER(u16, CMD_ARGV[i + 1], ft2232_pid[i >> 1]); - } - - /* - * Explicitly terminate, in case there are multiples instances of - * ft2232_vid_pid. - */ - ft2232_vid[i >> 1] = ft2232_pid[i >> 1] = 0; - - return ERROR_OK; -} - -COMMAND_HANDLER(ft2232_handle_latency_command) -{ - if (CMD_ARGC == 1) - ft2232_latency = atoi(CMD_ARGV[0]); - else - return ERROR_COMMAND_SYNTAX_ERROR; - - return ERROR_OK; -} - -COMMAND_HANDLER(ft2232_handle_channel_command) -{ - if (CMD_ARGC == 1) { - ft2232_channel = atoi(CMD_ARGV[0]); - if (ft2232_channel < 0 || ft2232_channel > 4) - LOG_ERROR("ft2232_channel must be in the 0 to 4 range"); - } else - LOG_ERROR("expected exactly one argument to ft2232_channel "); - - return ERROR_OK; -} - -static int ft2232_stableclocks(int num_cycles, struct jtag_command *cmd) -{ - int retval = 0; - - /* 7 bits of either ones or zeros. */ - uint8_t tms = (tap_get_state() == TAP_RESET ? 0x7F : 0x00); - - while (num_cycles > 0) { - /* the command 0x4b, "Clock Data to TMS/CS Pin (no Read)" handles - * at most 7 bits per invocation. Here we invoke it potentially - * several times. - */ - int bitcount_per_command = (num_cycles > 7) ? 7 : num_cycles; - - if (ft2232_buffer_size + 3 >= FT2232_BUFFER_SIZE) { - if (ft2232_send_and_recv(first_unsent, cmd) != ERROR_OK) - retval = ERROR_JTAG_QUEUE_FAILED; - - first_unsent = cmd; - } - - /* there are no state transitions in this code, so omit state tracking */ - - /* command "Clock Data to TMS/CS Pin (no Read)" */ - buffer_write(0x4b); - - /* scan 7 bit */ - buffer_write(bitcount_per_command - 1); - - /* TMS data bits are either all zeros or ones to stay in the current stable state */ - buffer_write(tms); - - require_send = 1; - - num_cycles -= bitcount_per_command; - } - - return retval; -} - -/* --------------------------------------------------------------------- - * Support for IceBear JTAG adapter from Section5: - * http://section5.ch/icebear - * - * Author: Sten, debian@sansys-electronic.com - */ - -/* Icebear pin layout - * - * ADBUS5 (nEMU) nSRST | 2 1| GND (10k->VCC) - * GND GND | 4 3| n.c. - * ADBUS3 TMS | 6 5| ADBUS6 VCC - * ADBUS0 TCK | 8 7| ADBUS7 (GND) - * ADBUS4 nTRST |10 9| ACBUS0 (GND) - * ADBUS1 TDI |12 11| ACBUS1 (GND) - * ADBUS2 TDO |14 13| GND GND - * - * ADBUS0 O L TCK ACBUS0 GND - * ADBUS1 O L TDI ACBUS1 GND - * ADBUS2 I TDO ACBUS2 n.c. - * ADBUS3 O H TMS ACBUS3 n.c. - * ADBUS4 O H nTRST - * ADBUS5 O H nSRST - * ADBUS6 - VCC - * ADBUS7 - GND - */ -static int icebear_jtag_init(void) -{ - low_direction = 0x0b; /* output: TCK TDI TMS; input: TDO */ - low_output = 0x08; /* high: TMS; low: TCK TDI */ - nTRST = 0x10; - nSRST = 0x20; - - enum reset_types jtag_reset_config = jtag_get_reset_config(); - if ((jtag_reset_config & RESET_TRST_OPEN_DRAIN) != 0) - low_direction &= ~nTRST; /* nTRST high impedance */ - else { - low_direction |= nTRST; - low_output |= nTRST; - } - - low_direction |= nSRST; - low_output |= nSRST; - - /* initialize low byte for jtag */ - if (ft2232_set_data_bits_low_byte(low_output, low_direction) != ERROR_OK) { - LOG_ERROR("couldn't initialize FT2232 with 'IceBear' layout (low)"); - return ERROR_JTAG_INIT_FAILED; - } - - high_output = 0x0; - high_direction = 0x00; - - /* initialize high byte for jtag */ - if (ft2232_set_data_bits_high_byte(high_output, high_direction) != ERROR_OK) { - LOG_ERROR("couldn't initialize FT2232 with 'IceBear' layout (high)"); - return ERROR_JTAG_INIT_FAILED; - } - - return ERROR_OK; -} - -static void icebear_jtag_reset(int trst, int srst) -{ - if (trst == 1) { - low_direction |= nTRST; - low_output &= ~nTRST; - } else if (trst == 0) { - enum reset_types jtag_reset_config = jtag_get_reset_config(); - if ((jtag_reset_config & RESET_TRST_OPEN_DRAIN) != 0) - low_direction &= ~nTRST; - else - low_output |= nTRST; - } - - if (srst == 1) - low_output &= ~nSRST; - else if (srst == 0) - low_output |= nSRST; - - /* command "set data bits low byte" */ - buffer_write(0x80); - buffer_write(low_output); - buffer_write(low_direction); - - LOG_DEBUG("trst: %i, srst: %i, low_output: 0x%2.2x, low_direction: 0x%2.2x", - trst, - srst, - low_output, - low_direction); -} - -/* --------------------------------------------------------------------- - * Support for Signalyzer H2 and Signalyzer H4 - * JTAG adapter from Xverve Technologies Inc. - * http://www.signalyzer.com or http://www.xverve.com - * - * Author: Oleg Seiljus, oleg@signalyzer.com - */ -static unsigned char signalyzer_h_side; -static unsigned int signalyzer_h_adapter_type; - -static int signalyzer_h_ctrl_write(int address, unsigned short value); - -#if BUILD_FT2232_FTD2XX == 1 -static int signalyzer_h_ctrl_read(int address, unsigned short *value); -#endif - -#define SIGNALYZER_COMMAND_ADDR 128 -#define SIGNALYZER_DATA_BUFFER_ADDR 129 - -#define SIGNALYZER_COMMAND_VERSION 0x41 -#define SIGNALYZER_COMMAND_RESET 0x42 -#define SIGNALYZER_COMMAND_POWERCONTROL_GET 0x50 -#define SIGNALYZER_COMMAND_POWERCONTROL_SET 0x51 -#define SIGNALYZER_COMMAND_PWM_SET 0x52 -#define SIGNALYZER_COMMAND_LED_SET 0x53 -#define SIGNALYZER_COMMAND_ADC 0x54 -#define SIGNALYZER_COMMAND_GPIO_STATE 0x55 -#define SIGNALYZER_COMMAND_GPIO_MODE 0x56 -#define SIGNALYZER_COMMAND_GPIO_PORT 0x57 -#define SIGNALYZER_COMMAND_I2C 0x58 - -#define SIGNALYZER_CHAN_A 1 -#define SIGNALYZER_CHAN_B 2 -/* LEDS use channel C */ -#define SIGNALYZER_CHAN_C 4 - -#define SIGNALYZER_LED_GREEN 1 -#define SIGNALYZER_LED_RED 2 - -#define SIGNALYZER_MODULE_TYPE_EM_LT16_A 0x0301 -#define SIGNALYZER_MODULE_TYPE_EM_ARM_JTAG 0x0302 -#define SIGNALYZER_MODULE_TYPE_EM_JTAG 0x0303 -#define SIGNALYZER_MODULE_TYPE_EM_ARM_JTAG_P 0x0304 -#define SIGNALYZER_MODULE_TYPE_EM_JTAG_P 0x0305 - - -static int signalyzer_h_ctrl_write(int address, unsigned short value) -{ -#if BUILD_FT2232_FTD2XX == 1 - return FT_WriteEE(ftdih, address, value); -#elif BUILD_FT2232_LIBFTDI == 1 - return 0; -#endif -} - -#if BUILD_FT2232_FTD2XX == 1 -static int signalyzer_h_ctrl_read(int address, unsigned short *value) -{ - return FT_ReadEE(ftdih, address, value); -} -#endif - -static int signalyzer_h_led_set(unsigned char channel, unsigned char led, - int on_time_ms, int off_time_ms, unsigned char cycles) -{ - unsigned char on_time; - unsigned char off_time; - - if (on_time_ms < 0xFFFF) - on_time = (unsigned char)(on_time_ms / 62); - else - on_time = 0xFF; - - off_time = (unsigned char)(off_time_ms / 62); - -#if BUILD_FT2232_FTD2XX == 1 - FT_STATUS status; - - status = signalyzer_h_ctrl_write(SIGNALYZER_DATA_BUFFER_ADDR, - ((uint32_t)(channel << 8) | led)); - if (status != FT_OK) { - LOG_ERROR("signalyzer_h_ctrl_write returned: %s", - ftd2xx_status_string(status)); - return ERROR_JTAG_DEVICE_ERROR; - } - - status = signalyzer_h_ctrl_write((SIGNALYZER_DATA_BUFFER_ADDR + 1), - ((uint32_t)(on_time << 8) | off_time)); - if (status != FT_OK) { - LOG_ERROR("signalyzer_h_ctrl_write returned: %s", - ftd2xx_status_string(status)); - return ERROR_JTAG_DEVICE_ERROR; - } - - status = signalyzer_h_ctrl_write((SIGNALYZER_DATA_BUFFER_ADDR + 2), - ((uint32_t)cycles)); - if (status != FT_OK) { - LOG_ERROR("signalyzer_h_ctrl_write returned: %s", - ftd2xx_status_string(status)); - return ERROR_JTAG_DEVICE_ERROR; - } - - status = signalyzer_h_ctrl_write(SIGNALYZER_COMMAND_ADDR, - SIGNALYZER_COMMAND_LED_SET); - if (status != FT_OK) { - LOG_ERROR("signalyzer_h_ctrl_write returned: %s", - ftd2xx_status_string(status)); - return ERROR_JTAG_DEVICE_ERROR; - } - - return ERROR_OK; -#elif BUILD_FT2232_LIBFTDI == 1 - int retval; - - retval = signalyzer_h_ctrl_write(SIGNALYZER_DATA_BUFFER_ADDR, - ((uint32_t)(channel << 8) | led)); - if (retval < 0) { - LOG_ERROR("signalyzer_h_ctrl_write returned: %s", - ftdi_get_error_string(&ftdic)); - return ERROR_JTAG_DEVICE_ERROR; - } - - retval = signalyzer_h_ctrl_write((SIGNALYZER_DATA_BUFFER_ADDR + 1), - ((uint32_t)(on_time << 8) | off_time)); - if (retval < 0) { - LOG_ERROR("signalyzer_h_ctrl_write returned: %s", - ftdi_get_error_string(&ftdic)); - return ERROR_JTAG_DEVICE_ERROR; - } - - retval = signalyzer_h_ctrl_write((SIGNALYZER_DATA_BUFFER_ADDR + 2), - (uint32_t)cycles); - if (retval < 0) { - LOG_ERROR("signalyzer_h_ctrl_write returned: %s", - ftdi_get_error_string(&ftdic)); - return ERROR_JTAG_DEVICE_ERROR; - } - - retval = signalyzer_h_ctrl_write(SIGNALYZER_COMMAND_ADDR, - SIGNALYZER_COMMAND_LED_SET); - if (retval < 0) { - LOG_ERROR("signalyzer_h_ctrl_write returned: %s", - ftdi_get_error_string(&ftdic)); - return ERROR_JTAG_DEVICE_ERROR; - } - - return ERROR_OK; -#endif -} - -static int signalyzer_h_init(void) -{ -#if BUILD_FT2232_FTD2XX == 1 - FT_STATUS status; - int i; -#endif - - char *end_of_desc; - - uint16_t read_buf[12] = { 0 }; - - /* turn on center green led */ - signalyzer_h_led_set(SIGNALYZER_CHAN_C, SIGNALYZER_LED_GREEN, - 0xFFFF, 0x00, 0x00); - - /* determine what channel config wants to open - * TODO: change me... current implementation is made to work - * with openocd description parsing. - */ - end_of_desc = strrchr(ft2232_device_desc, 0x00); - - if (end_of_desc) { - signalyzer_h_side = *(end_of_desc - 1); - if (signalyzer_h_side == 'B') - signalyzer_h_side = SIGNALYZER_CHAN_B; - else - signalyzer_h_side = SIGNALYZER_CHAN_A; - } else { - LOG_ERROR("No Channel was specified"); - return ERROR_FAIL; - } - - signalyzer_h_led_set(signalyzer_h_side, SIGNALYZER_LED_GREEN, - 1000, 1000, 0xFF); - -#if BUILD_FT2232_FTD2XX == 1 - /* read signalyzer versionining information */ - status = signalyzer_h_ctrl_write(SIGNALYZER_COMMAND_ADDR, - SIGNALYZER_COMMAND_VERSION); - if (status != FT_OK) { - LOG_ERROR("signalyzer_h_ctrl_write returned: %s", - ftd2xx_status_string(status)); - return ERROR_JTAG_DEVICE_ERROR; - } - - for (i = 0; i < 10; i++) { - status = signalyzer_h_ctrl_read((SIGNALYZER_DATA_BUFFER_ADDR + i), - &read_buf[i]); - if (status != FT_OK) { - LOG_ERROR("signalyzer_h_ctrl_read returned: %s", - ftd2xx_status_string(status)); - return ERROR_JTAG_DEVICE_ERROR; - } - } - - LOG_INFO("Signalyzer: ID info: { %.4x %.4x %.4x %.4x %.4x %.4x %.4x }", - read_buf[0], read_buf[1], read_buf[2], read_buf[3], - read_buf[4], read_buf[5], read_buf[6]); - - /* set gpio register */ - status = signalyzer_h_ctrl_write(SIGNALYZER_DATA_BUFFER_ADDR, - (uint32_t)(signalyzer_h_side << 8)); - if (status != FT_OK) { - LOG_ERROR("signalyzer_h_ctrl_write returned: %s", - ftd2xx_status_string(status)); - return ERROR_JTAG_DEVICE_ERROR; - } - - status = signalyzer_h_ctrl_write(SIGNALYZER_DATA_BUFFER_ADDR + 1, 0x0404); - if (status != FT_OK) { - LOG_ERROR("signalyzer_h_ctrl_write returned: %s", - ftd2xx_status_string(status)); - return ERROR_JTAG_DEVICE_ERROR; - } - - status = signalyzer_h_ctrl_write(SIGNALYZER_COMMAND_ADDR, - SIGNALYZER_COMMAND_GPIO_STATE); - if (status != FT_OK) { - LOG_ERROR("signalyzer_h_ctrl_write returned: %s", - ftd2xx_status_string(status)); - return ERROR_JTAG_DEVICE_ERROR; - } - - /* read adapter type information */ - status = signalyzer_h_ctrl_write(SIGNALYZER_DATA_BUFFER_ADDR, - ((uint32_t)(signalyzer_h_side << 8) | 0x01)); - if (status != FT_OK) { - LOG_ERROR("signalyzer_h_ctrl_write returned: %s", - ftd2xx_status_string(status)); - return ERROR_JTAG_DEVICE_ERROR; - } - - status = signalyzer_h_ctrl_write( - (SIGNALYZER_DATA_BUFFER_ADDR + 1), 0xA000); - if (status != FT_OK) { - LOG_ERROR("signalyzer_h_ctrl_write returned: %s", - ftd2xx_status_string(status)); - return ERROR_JTAG_DEVICE_ERROR; - } - - status = signalyzer_h_ctrl_write( - (SIGNALYZER_DATA_BUFFER_ADDR + 2), 0x0008); - if (status != FT_OK) { - LOG_ERROR("signalyzer_h_ctrl_write returned: %s", - ftd2xx_status_string(status)); - return ERROR_JTAG_DEVICE_ERROR; - } - - status = signalyzer_h_ctrl_write(SIGNALYZER_COMMAND_ADDR, - SIGNALYZER_COMMAND_I2C); - if (status != FT_OK) { - LOG_ERROR("signalyzer_h_ctrl_write returned: %s", - ftd2xx_status_string(status)); - return ERROR_JTAG_DEVICE_ERROR; - } - - usleep(100000); - - status = signalyzer_h_ctrl_read(SIGNALYZER_COMMAND_ADDR, &read_buf[0]); - if (status != FT_OK) { - LOG_ERROR("signalyzer_h_ctrl_read returned: %s", - ftd2xx_status_string(status)); - return ERROR_JTAG_DEVICE_ERROR; - } - - if (read_buf[0] != 0x0498) - signalyzer_h_adapter_type = 0x0000; - else { - for (i = 0; i < 4; i++) { - status = signalyzer_h_ctrl_read((SIGNALYZER_DATA_BUFFER_ADDR + i), &read_buf[i]); - if (status != FT_OK) { - LOG_ERROR("signalyzer_h_ctrl_read returned: %s", - ftd2xx_status_string(status)); - return ERROR_JTAG_DEVICE_ERROR; - } - } - - signalyzer_h_adapter_type = read_buf[0]; - } - -#elif BUILD_FT2232_LIBFTDI == 1 - /* currently libftdi does not allow reading individual eeprom - * locations, therefore adapter type cannot be detected. - * override with most common type - */ - signalyzer_h_adapter_type = SIGNALYZER_MODULE_TYPE_EM_ARM_JTAG; -#endif - - enum reset_types jtag_reset_config = jtag_get_reset_config(); - - /* ADAPTOR: EM_LT16_A */ - if (signalyzer_h_adapter_type == SIGNALYZER_MODULE_TYPE_EM_LT16_A) { - LOG_INFO("Signalyzer: EM-LT (16-channel level translator) " - "detected. (HW: %2x).", (read_buf[1] >> 8)); - - nTRST = 0x10; - nTRSTnOE = 0x10; - nSRST = 0x20; - nSRSTnOE = 0x20; - - low_output = 0x08; - low_direction = 0x1b; - - high_output = 0x0; - high_direction = 0x0; - - if (jtag_reset_config & RESET_TRST_OPEN_DRAIN) { - low_direction &= ~nTRSTnOE; /* nTRST input */ - low_output &= ~nTRST; /* nTRST = 0 */ - } else { - low_direction |= nTRSTnOE; /* nTRST output */ - low_output |= nTRST; /* nTRST = 1 */ - } - - if (jtag_reset_config & RESET_SRST_PUSH_PULL) { - low_direction |= nSRSTnOE; /* nSRST output */ - low_output |= nSRST; /* nSRST = 1 */ - } else { - low_direction &= ~nSRSTnOE; /* nSRST input */ - low_output &= ~nSRST; /* nSRST = 0 */ - } - -#if BUILD_FT2232_FTD2XX == 1 - /* enable power to the module */ - status = signalyzer_h_ctrl_write(SIGNALYZER_DATA_BUFFER_ADDR, - ((uint32_t)(signalyzer_h_side << 8) | 0x01)); - if (status != FT_OK) { - LOG_ERROR("signalyzer_h_ctrl_write returned: %s", - ftd2xx_status_string(status)); - return ERROR_JTAG_DEVICE_ERROR; - } - - status = signalyzer_h_ctrl_write(SIGNALYZER_COMMAND_ADDR, - SIGNALYZER_COMMAND_POWERCONTROL_SET); - if (status != FT_OK) { - LOG_ERROR("signalyzer_h_ctrl_write returned: %s", - ftd2xx_status_string(status)); - return ERROR_JTAG_DEVICE_ERROR; - } - - /* set gpio mode register */ - status = signalyzer_h_ctrl_write(SIGNALYZER_DATA_BUFFER_ADDR, - (uint32_t)(signalyzer_h_side << 8)); - if (status != FT_OK) { - LOG_ERROR("signalyzer_h_ctrl_write returned: %s", - ftd2xx_status_string(status)); - return ERROR_JTAG_DEVICE_ERROR; - } - - status = signalyzer_h_ctrl_write(SIGNALYZER_DATA_BUFFER_ADDR + 1, 0x0000); - if (status != FT_OK) { - LOG_ERROR("signalyzer_h_ctrl_write returned: %s", - ftd2xx_status_string(status)); - return ERROR_JTAG_DEVICE_ERROR; - } - - status = signalyzer_h_ctrl_write(SIGNALYZER_COMMAND_ADDR, SIGNALYZER_COMMAND_GPIO_MODE); - if (status != FT_OK) { - LOG_ERROR("signalyzer_h_ctrl_write returned: %s", - ftd2xx_status_string(status)); - return ERROR_JTAG_DEVICE_ERROR; - } - - /* set gpio register */ - status = signalyzer_h_ctrl_write(SIGNALYZER_DATA_BUFFER_ADDR, - (uint32_t)(signalyzer_h_side << 8)); - if (status != FT_OK) { - LOG_ERROR("signalyzer_h_ctrl_write returned: %s", - ftd2xx_status_string(status)); - return ERROR_JTAG_DEVICE_ERROR; - } - - status = signalyzer_h_ctrl_write(SIGNALYZER_DATA_BUFFER_ADDR + 1, 0x4040); - if (status != FT_OK) { - LOG_ERROR("signalyzer_h_ctrl_write returned: %s", - ftd2xx_status_string(status)); - return ERROR_JTAG_DEVICE_ERROR; - } - - status = signalyzer_h_ctrl_write(SIGNALYZER_COMMAND_ADDR, - SIGNALYZER_COMMAND_GPIO_STATE); - if (status != FT_OK) { - LOG_ERROR("signalyzer_h_ctrl_write returned: %s", - ftd2xx_status_string(status)); - return ERROR_JTAG_DEVICE_ERROR; - } -#endif - } - /* ADAPTOR: EM_ARM_JTAG, EM_ARM_JTAG_P, EM_JTAG, EM_JTAG_P */ - else if ((signalyzer_h_adapter_type == SIGNALYZER_MODULE_TYPE_EM_ARM_JTAG) || - (signalyzer_h_adapter_type == SIGNALYZER_MODULE_TYPE_EM_ARM_JTAG_P) || - (signalyzer_h_adapter_type == SIGNALYZER_MODULE_TYPE_EM_JTAG) || - (signalyzer_h_adapter_type == SIGNALYZER_MODULE_TYPE_EM_JTAG_P)) { - if (signalyzer_h_adapter_type - == SIGNALYZER_MODULE_TYPE_EM_ARM_JTAG) - LOG_INFO("Signalyzer: EM-ARM-JTAG (ARM JTAG) " - "detected. (HW: %2x).", (read_buf[1] >> 8)); - else if (signalyzer_h_adapter_type - == SIGNALYZER_MODULE_TYPE_EM_ARM_JTAG_P) - LOG_INFO("Signalyzer: EM-ARM-JTAG_P " - "(ARM JTAG with PSU) detected. (HW: %2x).", - (read_buf[1] >> 8)); - else if (signalyzer_h_adapter_type - == SIGNALYZER_MODULE_TYPE_EM_JTAG) - LOG_INFO("Signalyzer: EM-JTAG (Generic JTAG) " - "detected. (HW: %2x).", (read_buf[1] >> 8)); - else if (signalyzer_h_adapter_type - == SIGNALYZER_MODULE_TYPE_EM_JTAG_P) - LOG_INFO("Signalyzer: EM-JTAG-P " - "(Generic JTAG with PSU) detected. (HW: %2x).", - (read_buf[1] >> 8)); - - nTRST = 0x02; - nTRSTnOE = 0x04; - nSRST = 0x08; - nSRSTnOE = 0x10; - - low_output = 0x08; - low_direction = 0x1b; - - high_output = 0x0; - high_direction = 0x1f; - - if (jtag_reset_config & RESET_TRST_OPEN_DRAIN) { - high_output |= nTRSTnOE; - high_output &= ~nTRST; - } else { - high_output &= ~nTRSTnOE; - high_output |= nTRST; - } - - if (jtag_reset_config & RESET_SRST_PUSH_PULL) { - high_output &= ~nSRSTnOE; - high_output |= nSRST; - } else { - high_output |= nSRSTnOE; - high_output &= ~nSRST; - } - -#if BUILD_FT2232_FTD2XX == 1 - /* enable power to the module */ - status = signalyzer_h_ctrl_write(SIGNALYZER_DATA_BUFFER_ADDR, - ((uint32_t)(signalyzer_h_side << 8) | 0x01)); - if (status != FT_OK) { - LOG_ERROR("signalyzer_h_ctrl_write returned: %s", - ftd2xx_status_string(status)); - return ERROR_JTAG_DEVICE_ERROR; - } - - status = signalyzer_h_ctrl_write(SIGNALYZER_COMMAND_ADDR, - SIGNALYZER_COMMAND_POWERCONTROL_SET); - if (status != FT_OK) { - LOG_ERROR("signalyzer_h_ctrl_write returned: %s", - ftd2xx_status_string(status)); - return ERROR_JTAG_DEVICE_ERROR; - } - - /* set gpio mode register (IO_16 and IO_17 set as analog - * inputs, other is gpio) - */ - status = signalyzer_h_ctrl_write(SIGNALYZER_DATA_BUFFER_ADDR, - (uint32_t)(signalyzer_h_side << 8)); - if (status != FT_OK) { - LOG_ERROR("signalyzer_h_ctrl_write returned: %s", - ftd2xx_status_string(status)); - return ERROR_JTAG_DEVICE_ERROR; - } - - status = signalyzer_h_ctrl_write(SIGNALYZER_DATA_BUFFER_ADDR + 1, 0x0060); - if (status != FT_OK) { - LOG_ERROR("signalyzer_h_ctrl_write returned: %s", - ftd2xx_status_string(status)); - return ERROR_JTAG_DEVICE_ERROR; - } - - status = signalyzer_h_ctrl_write(SIGNALYZER_COMMAND_ADDR, SIGNALYZER_COMMAND_GPIO_MODE); - if (status != FT_OK) { - LOG_ERROR("signalyzer_h_ctrl_write returned: %s", - ftd2xx_status_string(status)); - return ERROR_JTAG_DEVICE_ERROR; - } - - /* set gpio register (all inputs, for -P modules, - * PSU will be turned off) - */ - status = signalyzer_h_ctrl_write(SIGNALYZER_DATA_BUFFER_ADDR, - (uint32_t)(signalyzer_h_side << 8)); - if (status != FT_OK) { - LOG_ERROR("signalyzer_h_ctrl_write returned: %s", - ftd2xx_status_string(status)); - return ERROR_JTAG_DEVICE_ERROR; - } - - status = signalyzer_h_ctrl_write(SIGNALYZER_DATA_BUFFER_ADDR + 1, 0x0000); - if (status != FT_OK) { - LOG_ERROR("signalyzer_h_ctrl_write returned: %s", - ftd2xx_status_string(status)); - return ERROR_JTAG_DEVICE_ERROR; - } - - status = signalyzer_h_ctrl_write(SIGNALYZER_COMMAND_ADDR, SIGNALYZER_COMMAND_GPIO_STATE); - if (status != FT_OK) { - LOG_ERROR("signalyzer_h_ctrl_write returned: %s", - ftd2xx_status_string(status)); - return ERROR_JTAG_DEVICE_ERROR; - } -#endif - } else if (signalyzer_h_adapter_type == 0x0000) { - LOG_INFO("Signalyzer: No external modules were detected."); - - nTRST = 0x10; - nTRSTnOE = 0x10; - nSRST = 0x20; - nSRSTnOE = 0x20; - - low_output = 0x08; - low_direction = 0x1b; - - high_output = 0x0; - high_direction = 0x0; - - if (jtag_reset_config & RESET_TRST_OPEN_DRAIN) { - low_direction &= ~nTRSTnOE; /* nTRST input */ - low_output &= ~nTRST; /* nTRST = 0 */ - } else { - low_direction |= nTRSTnOE; /* nTRST output */ - low_output |= nTRST; /* nTRST = 1 */ - } - - if (jtag_reset_config & RESET_SRST_PUSH_PULL) { - low_direction |= nSRSTnOE; /* nSRST output */ - low_output |= nSRST; /* nSRST = 1 */ - } else { - low_direction &= ~nSRSTnOE; /* nSRST input */ - low_output &= ~nSRST; /* nSRST = 0 */ - } - } else { - LOG_ERROR("Unknown module type is detected: %.4x", - signalyzer_h_adapter_type); - return ERROR_JTAG_DEVICE_ERROR; - } - - /* initialize low byte of controller for jtag operation */ - if (ft2232_set_data_bits_low_byte(low_output, low_direction) != ERROR_OK) { - LOG_ERROR("couldn't initialize Signalyzer-H layout"); - return ERROR_JTAG_INIT_FAILED; - } - -#if BUILD_FT2232_FTD2XX == 1 - if (ftdi_device == FT_DEVICE_2232H) { - /* initialize high byte of controller for jtag operation */ - if (ft2232_set_data_bits_high_byte(high_output, high_direction) != ERROR_OK) { - LOG_ERROR("couldn't initialize Signalyzer-H layout"); - return ERROR_JTAG_INIT_FAILED; - } - } -#elif BUILD_FT2232_LIBFTDI == 1 - if (ftdi_device == TYPE_2232H) { - /* initialize high byte of controller for jtag operation */ - if (ft2232_set_data_bits_high_byte(high_output, high_direction) != ERROR_OK) { - LOG_ERROR("couldn't initialize Signalyzer-H layout"); - return ERROR_JTAG_INIT_FAILED; - } - } -#endif - return ERROR_OK; -} - -static void signalyzer_h_reset(int trst, int srst) -{ - enum reset_types jtag_reset_config = jtag_get_reset_config(); - - /* ADAPTOR: EM_LT16_A */ - if (signalyzer_h_adapter_type == SIGNALYZER_MODULE_TYPE_EM_LT16_A) { - if (trst == 1) { - if (jtag_reset_config & RESET_TRST_OPEN_DRAIN) - /* switch to output pin (output is low) */ - low_direction |= nTRSTnOE; - else - /* switch output low */ - low_output &= ~nTRST; - } else if (trst == 0) { - if (jtag_reset_config & RESET_TRST_OPEN_DRAIN) - /* switch to input pin (high-Z + internal - * and external pullup) */ - low_direction &= ~nTRSTnOE; - else - /* switch output high */ - low_output |= nTRST; - } - - if (srst == 1) { - if (jtag_reset_config & RESET_SRST_PUSH_PULL) - /* switch output low */ - low_output &= ~nSRST; - else - /* switch to output pin (output is low) */ - low_direction |= nSRSTnOE; - } else if (srst == 0) { - if (jtag_reset_config & RESET_SRST_PUSH_PULL) - /* switch output high */ - low_output |= nSRST; - else - /* switch to input pin (high-Z) */ - low_direction &= ~nSRSTnOE; - } - - /* command "set data bits low byte" */ - buffer_write(0x80); - buffer_write(low_output); - buffer_write(low_direction); - LOG_DEBUG("trst: %i, srst: %i, low_output: 0x%2.2x, " - "low_direction: 0x%2.2x", - trst, srst, low_output, low_direction); - } - /* ADAPTOR: EM_ARM_JTAG, EM_ARM_JTAG_P, EM_JTAG, EM_JTAG_P */ - else if ((signalyzer_h_adapter_type == SIGNALYZER_MODULE_TYPE_EM_ARM_JTAG) || - (signalyzer_h_adapter_type == SIGNALYZER_MODULE_TYPE_EM_ARM_JTAG_P) || - (signalyzer_h_adapter_type == SIGNALYZER_MODULE_TYPE_EM_JTAG) || - (signalyzer_h_adapter_type == SIGNALYZER_MODULE_TYPE_EM_JTAG_P)) { - if (trst == 1) { - if (jtag_reset_config & RESET_TRST_OPEN_DRAIN) - high_output &= ~nTRSTnOE; - else - high_output &= ~nTRST; - } else if (trst == 0) { - if (jtag_reset_config & RESET_TRST_OPEN_DRAIN) - high_output |= nTRSTnOE; - else - high_output |= nTRST; - } - - if (srst == 1) { - if (jtag_reset_config & RESET_SRST_PUSH_PULL) - high_output &= ~nSRST; - else - high_output &= ~nSRSTnOE; - } else if (srst == 0) { - if (jtag_reset_config & RESET_SRST_PUSH_PULL) - high_output |= nSRST; - else - high_output |= nSRSTnOE; - } - - /* command "set data bits high byte" */ - buffer_write(0x82); - buffer_write(high_output); - buffer_write(high_direction); - LOG_INFO("trst: %i, srst: %i, high_output: 0x%2.2x, " - "high_direction: 0x%2.2x", - trst, srst, high_output, high_direction); - } else if (signalyzer_h_adapter_type == 0x0000) { - if (trst == 1) { - if (jtag_reset_config & RESET_TRST_OPEN_DRAIN) - /* switch to output pin (output is low) */ - low_direction |= nTRSTnOE; - else - /* switch output low */ - low_output &= ~nTRST; - } else if (trst == 0) { - if (jtag_reset_config & RESET_TRST_OPEN_DRAIN) - /* switch to input pin (high-Z + internal - * and external pullup) */ - low_direction &= ~nTRSTnOE; - else - /* switch output high */ - low_output |= nTRST; - } - - if (srst == 1) { - if (jtag_reset_config & RESET_SRST_PUSH_PULL) - /* switch output low */ - low_output &= ~nSRST; - else - /* switch to output pin (output is low) */ - low_direction |= nSRSTnOE; - } else if (srst == 0) { - if (jtag_reset_config & RESET_SRST_PUSH_PULL) - /* switch output high */ - low_output |= nSRST; - else - /* switch to input pin (high-Z) */ - low_direction &= ~nSRSTnOE; - } - - /* command "set data bits low byte" */ - buffer_write(0x80); - buffer_write(low_output); - buffer_write(low_direction); - LOG_DEBUG("trst: %i, srst: %i, low_output: 0x%2.2x, " - "low_direction: 0x%2.2x", - trst, srst, low_output, low_direction); - } -} - -static void signalyzer_h_blink(void) -{ - signalyzer_h_led_set(signalyzer_h_side, SIGNALYZER_LED_RED, 100, 0, 1); -} - -/******************************************************************** - * Support for KT-LINK - * JTAG adapter from KRISTECH - * http://www.kristech.eu - *******************************************************************/ -static int ktlink_init(void) -{ - uint8_t swd_en = 0x20; /* 0x20 SWD disable, 0x00 SWD enable (ADBUS5) */ - - low_output = 0x08 | swd_en; /* value; TMS=1,TCK=0,TDI=0,SWD=swd_en */ - low_direction = 0x3B; /* out=1; TCK/TDI/TMS=out,TDO=in,SWD=out,RTCK=in,SRSTIN=in */ - - /* initialize low byte for jtag */ - if (ft2232_set_data_bits_low_byte(low_output, low_direction) != ERROR_OK) { - LOG_ERROR("couldn't initialize FT2232 with 'ktlink' layout"); - return ERROR_JTAG_INIT_FAILED; - } - - nTRST = 0x01; - nSRST = 0x02; - nTRSTnOE = 0x04; - nSRSTnOE = 0x08; - - high_output = 0x80; /* turn LED on */ - high_direction = 0xFF; /* all outputs */ - - enum reset_types jtag_reset_config = jtag_get_reset_config(); - - if (jtag_reset_config & RESET_TRST_OPEN_DRAIN) { - high_output |= nTRSTnOE; - high_output &= ~nTRST; - } else { - high_output &= ~nTRSTnOE; - high_output |= nTRST; - } - - if (jtag_reset_config & RESET_SRST_PUSH_PULL) { - high_output &= ~nSRSTnOE; - high_output |= nSRST; - } else { - high_output |= nSRSTnOE; - high_output &= ~nSRST; - } - - /* initialize high byte for jtag */ - if (ft2232_set_data_bits_high_byte(high_output, high_direction) != ERROR_OK) { - LOG_ERROR("couldn't initialize FT2232 with 'ktlink' layout"); - return ERROR_JTAG_INIT_FAILED; - } - - return ERROR_OK; -} - -static void ktlink_reset(int trst, int srst) -{ - enum reset_types jtag_reset_config = jtag_get_reset_config(); - - if (trst == 1) { - if (jtag_reset_config & RESET_TRST_OPEN_DRAIN) - high_output &= ~nTRSTnOE; - else - high_output &= ~nTRST; - } else if (trst == 0) { - if (jtag_reset_config & RESET_TRST_OPEN_DRAIN) - high_output |= nTRSTnOE; - else - high_output |= nTRST; - } - - if (srst == 1) { - if (jtag_reset_config & RESET_SRST_PUSH_PULL) - high_output &= ~nSRST; - else - high_output &= ~nSRSTnOE; - } else if (srst == 0) { - if (jtag_reset_config & RESET_SRST_PUSH_PULL) - high_output |= nSRST; - else - high_output |= nSRSTnOE; - } - - buffer_write(0x82); /* command "set data bits high byte" */ - buffer_write(high_output); - buffer_write(high_direction); - LOG_DEBUG("trst: %i, srst: %i, high_output: 0x%2.2x, high_direction: 0x%2.2x", - trst, - srst, - high_output, - high_direction); -} - -static void ktlink_blink(void) -{ - /* LED connected to ACBUS7 */ - high_output ^= 0x80; - - buffer_write(0x82); /* command "set data bits high byte" */ - buffer_write(high_output); - buffer_write(high_direction); -} - -/******************************************************************** - * Support for Digilent HS-1 - * JTAG adapter from Digilent - * http://www.digilent.com - * Author: Stephane Bonnet bonnetst@hds.utc.fr - *******************************************************************/ - -static int digilent_hs1_init(void) -{ - /* the adapter only supports the base JTAG signals, no nTRST - nor nSRST */ - low_output = 0x88; - low_direction = 0x8b; - - /* initialize low byte for jtag */ - if (ft2232_set_data_bits_low_byte(low_output, low_direction) != ERROR_OK) { - LOG_ERROR("couldn't initialize FT2232 with 'digilent_hs1' layout"); - return ERROR_JTAG_INIT_FAILED; - } - return ERROR_OK; -} - -static void digilent_hs1_reset(int trst, int srst) -{ - /* Dummy function, no reset signals supported. */ -} - -static const struct command_registration ft2232_command_handlers[] = { - { - .name = "ft2232_device_desc", - .handler = &ft2232_handle_device_desc_command, - .mode = COMMAND_CONFIG, - .help = "set the USB device description of the FTDI FT2232 device", - .usage = "description_string", - }, - { - .name = "ft2232_serial", - .handler = &ft2232_handle_serial_command, - .mode = COMMAND_CONFIG, - .help = "set the serial number of the FTDI FT2232 device", - .usage = "serial_string", - }, - { - .name = "ft2232_layout", - .handler = &ft2232_handle_layout_command, - .mode = COMMAND_CONFIG, - .help = "set the layout of the FT2232 GPIO signals used " - "to control output-enables and reset signals", - .usage = "layout_name", - }, - { - .name = "ft2232_vid_pid", - .handler = &ft2232_handle_vid_pid_command, - .mode = COMMAND_CONFIG, - .help = "the vendor ID and product ID of the FTDI FT2232 device", - .usage = "(vid pid)* ", - }, - { - .name = "ft2232_latency", - .handler = &ft2232_handle_latency_command, - .mode = COMMAND_CONFIG, - .help = "set the FT2232 latency timer to a new value", - .usage = "value", - }, - { - .name = "ft2232_channel", - .handler = &ft2232_handle_channel_command, - .mode = COMMAND_CONFIG, - .help = "set the FT2232 channel to a new value", - .usage = "value", - }, - COMMAND_REGISTRATION_DONE -}; - -struct jtag_interface ft2232_interface = { - .name = "ft2232", - .supported = DEBUG_CAP_TMS_SEQ, - .commands = ft2232_command_handlers, - .transports = jtag_only, - - .init = ft2232_init, - .quit = ft2232_quit, - .speed = ft2232_speed, - .speed_div = ft2232_speed_div, - .khz = ft2232_khz, - .execute_queue = ft2232_execute_queue, -}; diff --git a/src/jtag/drivers/ftd2xx_common.h b/src/jtag/drivers/ftd2xx_common.h deleted file mode 100644 index 14b845585..000000000 --- a/src/jtag/drivers/ftd2xx_common.h +++ /dev/null @@ -1,55 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2011 by Spencer Oliver * - * * - * Written by Arnim Laeuger, 2008 (from urjtag) * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 OPENOCD_JTAG_DRIVERS_FTD2XX_COMMON_H -#define OPENOCD_JTAG_DRIVERS_FTD2XX_COMMON_H - -#if ((BUILD_FT2232_FTD2XX == 1) || (BUILD_PRESTO_FTD2XX == 1) || (BUILD_USB_BLASTER_FTD2XX == 1)) -#include - -static const char *ftd2xx_status_string(FT_STATUS status) -{ - switch (status) { - case FT_OK: return "OK"; - case FT_INVALID_HANDLE: return "invalid handle"; - case FT_DEVICE_NOT_FOUND: return "device not found"; - case FT_DEVICE_NOT_OPENED: return "device not opened"; - case FT_IO_ERROR: return "io error"; - case FT_INSUFFICIENT_RESOURCES: return "insufficient resources"; - case FT_INVALID_PARAMETER: return "invalid parameter"; - case FT_INVALID_BAUD_RATE: return "invalid baud rate"; - - case FT_DEVICE_NOT_OPENED_FOR_ERASE: return "device not opened for erase"; - case FT_DEVICE_NOT_OPENED_FOR_WRITE: return "device not opened for write"; - case FT_FAILED_TO_WRITE_DEVICE: return "failed to write device"; - case FT_EEPROM_READ_FAILED: return "eeprom read failed"; - case FT_EEPROM_WRITE_FAILED: return "eeprom write failed"; - case FT_EEPROM_ERASE_FAILED: return "eeprom erase failed"; - case FT_EEPROM_NOT_PRESENT: return "eeprom not present"; - case FT_EEPROM_NOT_PROGRAMMED: return "eeprom not programmed"; - case FT_INVALID_ARGS: return "invalid args"; - case FT_NOT_SUPPORTED: return "not supported"; - case FT_OTHER_ERROR: return "other error"; - } - - return "undefined FTD2xx error"; -} - -#endif -#endif /* OPENOCD_JTAG_DRIVERS_FTD2XX_COMMON_H */ diff --git a/src/jtag/drivers/ftdi.c b/src/jtag/drivers/ftdi.c deleted file mode 100644 index 8b78fe8d5..000000000 --- a/src/jtag/drivers/ftdi.c +++ /dev/null @@ -1,1297 +0,0 @@ -/************************************************************************** -* Copyright (C) 2012 by Andreas Fritiofson * -* andreas.fritiofson@gmail.com * -* * -* This program is free software; you can redistribute it and/or modify * -* it under the terms of the GNU General Public License as published by * -* the Free Software Foundation; either version 2 of the License, or * -* (at your option) any later version. * -* * -* This program is distributed in the hope that it will be useful, * -* but WITHOUT ANY WARRANTY; without even the implied warranty of * -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -* GNU General Public License for more details. * -* * -* You should have received a copy of the GNU General Public License * -* along with this program. If not, see . * -***************************************************************************/ - -/** - * @file - * JTAG adapters based on the FT2232 full and high speed USB parts are - * popular low cost JTAG debug solutions. Many FT2232 based JTAG adapters - * are discrete, but development boards may integrate them as alternatives - * to more capable (and expensive) third party JTAG pods. - * - * JTAG uses only one of the two communications channels ("MPSSE engines") - * on these devices. Adapters based on FT4232 parts have four ports/channels - * (A/B/C/D), instead of just two (A/B). - * - * Especially on development boards integrating one of these chips (as - * opposed to discrete pods/dongles), the additional channels can be used - * for a variety of purposes, but OpenOCD only uses one channel at a time. - * - * - As a USB-to-serial adapter for the target's console UART ... - * which may be able to support ROM boot loaders that load initial - * firmware images to flash (or SRAM). - * - * - On systems which support ARM's SWD in addition to JTAG, or instead - * of it, that second port can be used for reading SWV/SWO trace data. - * - * - Additional JTAG links, e.g. to a CPLD or * FPGA. - * - * FT2232 based JTAG adapters are "dumb" not "smart", because most JTAG - * request/response interactions involve round trips over the USB link. - * A "smart" JTAG adapter has intelligence close to the scan chain, so it - * can for example poll quickly for a status change (usually taking on the - * order of microseconds not milliseconds) before beginning a queued - * transaction which require the previous one to have completed. - * - * There are dozens of adapters of this type, differing in details which - * this driver needs to understand. Those "layout" details are required - * as part of FT2232 driver configuration. - * - * This code uses information contained in the MPSSE specification which was - * found here: - * http://www.ftdichip.com/Documents/AppNotes/AN2232C-01_MPSSE_Cmnd.pdf - * Hereafter this is called the "MPSSE Spec". - * - * The datasheet for the ftdichip.com's FT2232D part is here: - * http://www.ftdichip.com/Documents/DataSheets/DS_FT2232D.pdf - * - * Also note the issue with code 0x4b (clock data to TMS) noted in - * http://developer.intra2net.com/mailarchive/html/libftdi/2009/msg00292.html - * which can affect longer JTAG state paths. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -/* project specific includes */ -#include -#include -#include -#include - -#if IS_CYGWIN == 1 -#include -#endif - -#include - -/* FTDI access library includes */ -#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; - -#define MAX_USB_IDS 8 -/* vid = pid = 0 marks the end of the list */ -static uint16_t ftdi_vid[MAX_USB_IDS + 1] = { 0 }; -static uint16_t ftdi_pid[MAX_USB_IDS + 1] = { 0 }; - -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; -}; - -static struct signal *signals; - -/* FIXME: Where to store per-instance data? We need an SWD context. */ -static struct swd_cmd_queue_entry { - uint8_t cmd; - uint32_t *dst; - uint8_t trn_ack_data_parity_trn[DIV_ROUND_UP(4 + 3 + 32 + 1 + 4, 8)]; -} *swd_cmd_queue; -static size_t swd_cmd_queue_length; -static size_t swd_cmd_queue_alloced; -static int queued_retval; -static int freq; - -static uint16_t output; -static uint16_t direction; -static uint16_t jtag_output_init; -static uint16_t jtag_direction_init; - -static int ftdi_swd_switch_seq(enum swd_special_seq seq); - -static struct signal *find_signal_by_name(const char *name) -{ - for (struct signal *sig = signals; sig; sig = sig->next) { - if (strcmp(name, sig->name) == 0) - return sig; - } - return NULL; -} - -static struct signal *create_signal(const char *name) -{ - struct signal **psig = &signals; - while (*psig) - psig = &(*psig)->next; - - *psig = calloc(1, sizeof(**psig)); - if (*psig == NULL) - return NULL; - - (*psig)->name = strdup(name); - if ((*psig)->name == NULL) { - free(*psig); - *psig = NULL; - } - return *psig; -} - -static int ftdi_set_signal(const struct signal *s, char value) -{ - bool data; - bool oe; - - if (s->data_mask == 0 && s->oe_mask == 0) { - LOG_ERROR("interface doesn't provide signal '%s'", s->name); - return ERROR_FAIL; - } - switch (value) { - case '0': - data = s->invert_data; - oe = !s->invert_oe; - break; - case '1': - if (s->data_mask == 0) { - LOG_ERROR("interface can't drive '%s' high", s->name); - return ERROR_FAIL; - } - data = !s->invert_data; - oe = !s->invert_oe; - break; - case 'z': - case 'Z': - if (s->oe_mask == 0) { - LOG_ERROR("interface can't tri-state '%s'", s->name); - return ERROR_FAIL; - } - data = s->invert_data; - oe = s->invert_oe; - break; - default: - assert(0 && "invalid signal level specifier"); - return ERROR_FAIL; - } - - uint16_t old_output = output; - uint16_t old_direction = direction; - - output = data ? output | s->data_mask : output & ~s->data_mask; - if (s->oe_mask == s->data_mask) - direction = oe ? direction | s->oe_mask : direction & ~s->oe_mask; - else - output = oe ? output | s->oe_mask : output & ~s->oe_mask; - - if ((output & 0xff) != (old_output & 0xff) || (direction & 0xff) != (old_direction & 0xff)) - mpsse_set_data_bits_low_byte(mpsse_ctx, output & 0xff, direction & 0xff); - if ((output >> 8 != old_output >> 8) || (direction >> 8 != old_direction >> 8)) - mpsse_set_data_bits_high_byte(mpsse_ctx, output >> 8, direction >> 8); - - 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 - * moves the TAP controller from the current state to a - * \a goal_state through a path given by tap_get_tms_path(). State transition - * logging is performed by delegation to clock_tms(). - * - * @param goal_state is the destination state for the move. - */ -static void move_to_state(tap_state_t goal_state) -{ - tap_state_t start_state = tap_get_state(); - - /* goal_state is 1/2 of a tuple/pair of states which allow convenient - lookup of the required TMS pattern to move to this state from the - start state. - */ - - /* do the 2 lookups */ - uint8_t tms_bits = tap_get_tms_path(start_state, goal_state); - int tms_count = tap_get_tms_path_len(start_state, goal_state); - assert(tms_count <= 8); - - DEBUG_JTAG_IO("start=%s goal=%s", tap_state_name(start_state), tap_state_name(goal_state)); - - /* Track state transitions step by step */ - for (int i = 0; i < tms_count; i++) - tap_set_state(tap_state_transition(tap_get_state(), (tms_bits >> i) & 1)); - - mpsse_clock_tms_cs_out(mpsse_ctx, - &tms_bits, - 0, - tms_count, - false, - ftdi_jtag_mode); -} - -static int ftdi_speed(int speed) -{ - int retval; - retval = mpsse_set_frequency(mpsse_ctx, speed); - - if (retval < 0) { - LOG_ERROR("couldn't set FTDI TCK 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; -} - -static int ftdi_speed_div(int speed, int *khz) -{ - *khz = speed / 1000; - return ERROR_OK; -} - -static int ftdi_khz(int khz, int *jtag_speed) -{ - if (khz == 0 && !mpsse_is_high_speed(mpsse_ctx)) { - LOG_DEBUG("RCLK not supported"); - return ERROR_FAIL; - } - - *jtag_speed = khz * 1000; - return ERROR_OK; -} - -static void ftdi_end_state(tap_state_t state) -{ - if (tap_is_state_stable(state)) - tap_set_end_state(state); - else { - LOG_ERROR("BUG: %s is not a stable end state", tap_state_name(state)); - exit(-1); - } -} - -static void ftdi_execute_runtest(struct jtag_command *cmd) -{ - int i; - uint8_t zero = 0; - - DEBUG_JTAG_IO("runtest %i cycles, end in %s", - cmd->cmd.runtest->num_cycles, - tap_state_name(cmd->cmd.runtest->end_state)); - - if (tap_get_state() != TAP_IDLE) - move_to_state(TAP_IDLE); - - /* TODO: Reuse ftdi_execute_stableclocks */ - i = cmd->cmd.runtest->num_cycles; - 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, ftdi_jtag_mode); - i -= this_len; - } - - ftdi_end_state(cmd->cmd.runtest->end_state); - - if (tap_get_state() != tap_get_end_state()) - move_to_state(tap_get_end_state()); - - DEBUG_JTAG_IO("runtest: %i, end in %s", - cmd->cmd.runtest->num_cycles, - tap_state_name(tap_get_end_state())); -} - -static void ftdi_execute_statemove(struct jtag_command *cmd) -{ - DEBUG_JTAG_IO("statemove end in %s", - tap_state_name(cmd->cmd.statemove->end_state)); - - ftdi_end_state(cmd->cmd.statemove->end_state); - - /* shortest-path move to desired end state */ - if (tap_get_state() != tap_get_end_state() || tap_get_end_state() == TAP_RESET) - move_to_state(tap_get_end_state()); -} - -/** - * Clock a bunch of TMS (or SWDIO) transitions, to change the JTAG - * (or SWD) state machine. REVISIT: Not the best method, perhaps. - */ -static void ftdi_execute_tms(struct jtag_command *cmd) -{ - DEBUG_JTAG_IO("TMS: %d bits", cmd->cmd.tms->num_bits); - - /* TODO: Missing tap state tracking, also missing from ft2232.c! */ - mpsse_clock_tms_cs_out(mpsse_ctx, - cmd->cmd.tms->bits, - 0, - cmd->cmd.tms->num_bits, - false, - ftdi_jtag_mode); -} - -static void ftdi_execute_pathmove(struct jtag_command *cmd) -{ - tap_state_t *path = cmd->cmd.pathmove->path; - int num_states = cmd->cmd.pathmove->num_states; - - DEBUG_JTAG_IO("pathmove: %i states, current: %s end: %s", num_states, - tap_state_name(tap_get_state()), - tap_state_name(path[num_states-1])); - - int state_count = 0; - unsigned bit_count = 0; - uint8_t tms_byte = 0; - - DEBUG_JTAG_IO("-"); - - /* this loop verifies that the path is legal and logs each state in the path */ - while (num_states--) { - - /* either TMS=0 or TMS=1 must work ... */ - if (tap_state_transition(tap_get_state(), false) - == path[state_count]) - buf_set_u32(&tms_byte, bit_count++, 1, 0x0); - else if (tap_state_transition(tap_get_state(), true) - == path[state_count]) { - buf_set_u32(&tms_byte, bit_count++, 1, 0x1); - - /* ... or else the caller goofed BADLY */ - } else { - LOG_ERROR("BUG: %s -> %s isn't a valid " - "TAP state transition", - tap_state_name(tap_get_state()), - tap_state_name(path[state_count])); - exit(-1); - } - - tap_set_state(path[state_count]); - state_count++; - - if (bit_count == 7 || num_states == 0) { - mpsse_clock_tms_cs_out(mpsse_ctx, - &tms_byte, - 0, - bit_count, - false, - ftdi_jtag_mode); - bit_count = 0; - } - } - tap_set_end_state(tap_get_state()); -} - -#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 - -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)); -#ifdef _DEBUG_JTAG_IO_ - debug_jtag_io_value(" out=", cmd->cmd.scan->fields->out_value, - cmd->cmd.scan->fields->num_bits); -#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 - && 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) - move_to_state(TAP_IRSHIFT); - } else { - if (tap_get_state() != TAP_DRSHIFT) - move_to_state(TAP_DRSHIFT); - } - - ftdi_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()) { - /* 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. */ - mpsse_clock_data(mpsse_ctx, - field->out_value, - 0, - field->in_value, - 0, - field->num_bits - 1, - 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); - uint8_t tms_bits = 0x01; - mpsse_clock_tms_cs(mpsse_ctx, - &tms_bits, - 0, - field->in_value, - field->num_bits - 1, - 1, - last_bit, - 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, - ftdi_jtag_mode); - tap_set_state(tap_state_transition(tap_get_state(), 0)); - } else - mpsse_clock_data(mpsse_ctx, - field->out_value, - 0, - field->in_value, - 0, - field->num_bits, - ftdi_jtag_mode); - } - - if (tap_get_state() != tap_get_end_state()) - move_to_state(tap_get_end_state()); - - 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())); - -#ifdef _DEBUG_JTAG_IO_ - debug_jtag_io_value(" in=", cmd->cmd.scan->fields->in_value, - cmd->cmd.scan->fields->num_bits); -#endif -} - -static void ftdi_execute_reset(struct jtag_command *cmd) -{ - DEBUG_JTAG_IO("reset trst: %i srst %i", - cmd->cmd.reset->trst, cmd->cmd.reset->srst); - - if (cmd->cmd.reset->trst == 1 - || (cmd->cmd.reset->srst - && (jtag_get_reset_config() & RESET_SRST_PULLS_TRST))) - tap_set_state(TAP_RESET); - - struct signal *trst = find_signal_by_name("nTRST"); - if (cmd->cmd.reset->trst == 1) { - if (trst) - ftdi_set_signal(trst, '0'); - else - LOG_ERROR("Can't assert TRST: nTRST signal is not defined"); - } else if (trst && jtag_get_reset_config() & RESET_HAS_TRST && - cmd->cmd.reset->trst == 0) { - if (jtag_get_reset_config() & RESET_TRST_OPEN_DRAIN) - ftdi_set_signal(trst, 'z'); - else - ftdi_set_signal(trst, '1'); - } - - struct signal *srst = find_signal_by_name("nSRST"); - if (cmd->cmd.reset->srst == 1) { - if (srst) - ftdi_set_signal(srst, '0'); - else - LOG_ERROR("Can't assert SRST: nSRST signal is not defined"); - } else if (srst && jtag_get_reset_config() & RESET_HAS_SRST && - cmd->cmd.reset->srst == 0) { - if (jtag_get_reset_config() & RESET_SRST_PUSH_PULL) - ftdi_set_signal(srst, '1'); - else - ftdi_set_signal(srst, 'z'); - } - - DEBUG_JTAG_IO("trst: %i, srst: %i", - cmd->cmd.reset->trst, cmd->cmd.reset->srst); -} - -static void ftdi_execute_sleep(struct jtag_command *cmd) -{ - DEBUG_JTAG_IO("sleep %" PRIi32, cmd->cmd.sleep->us); - - mpsse_flush(mpsse_ctx); - jtag_sleep(cmd->cmd.sleep->us); - DEBUG_JTAG_IO("sleep %" PRIi32 " usec while in %s", - cmd->cmd.sleep->us, - tap_state_name(tap_get_state())); -} - -static void ftdi_execute_stableclocks(struct jtag_command *cmd) -{ - /* this is only allowed while in a stable state. A check for a stable - * state was done in jtag_add_clocks() - */ - int num_cycles = cmd->cmd.stableclocks->num_cycles; - - /* 7 bits of either ones or zeros. */ - uint8_t tms = tap_get_state() == TAP_RESET ? 0x7f : 0x00; - - /* TODO: Use mpsse_clock_data with in=out=0 for this, if TMS can be set to - * the correct level and remain there during the scan */ - 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, ftdi_jtag_mode); - num_cycles -= this_len; - } - - DEBUG_JTAG_IO("clocks %i while in %s", - cmd->cmd.stableclocks->num_cycles, - tap_state_name(tap_get_state())); -} - -static void ftdi_execute_command(struct jtag_command *cmd) -{ - switch (cmd->type) { - case JTAG_RESET: - ftdi_execute_reset(cmd); - break; - case JTAG_RUNTEST: - ftdi_execute_runtest(cmd); - break; - case JTAG_TLR_RESET: - ftdi_execute_statemove(cmd); - break; - case JTAG_PATHMOVE: - ftdi_execute_pathmove(cmd); - break; - case JTAG_SCAN: - ftdi_execute_scan(cmd); - break; - case JTAG_SLEEP: - ftdi_execute_sleep(cmd); - break; - case JTAG_STABLECLOCKS: - ftdi_execute_stableclocks(cmd); - break; - case JTAG_TMS: - ftdi_execute_tms(cmd); - break; - default: - LOG_ERROR("BUG: unknown JTAG command type encountered: %d", cmd->type); - break; - } -} - -static int ftdi_execute_queue(void) -{ - /* blink, if the current layout has that feature */ - struct signal *led = find_signal_by_name("LED"); - if (led) - ftdi_set_signal(led, '1'); - - for (struct jtag_command *cmd = jtag_command_queue; cmd; cmd = cmd->next) { - /* fill the write buffer with the desired command */ - ftdi_execute_command(cmd); - } - - if (led) - ftdi_set_signal(led, '0'); - - int retval = mpsse_flush(mpsse_ctx); - if (retval != ERROR_OK) - LOG_ERROR("error while flushing MPSSE queue: %d", retval); - - return retval; -} - -static int ftdi_initialize(void) -{ - if (tap_get_tms_path_len(TAP_IRPAUSE, TAP_IRPAUSE) == 7) - LOG_DEBUG("ftdi interface using 7 step jtag state transitions"); - else - LOG_DEBUG("ftdi interface using shortest path jtag state transitions"); - - 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_location, ftdi_channel); - if (mpsse_ctx) - break; - } - - if (!mpsse_ctx) - return ERROR_JTAG_INIT_FAILED; - - output = jtag_output_init; - direction = jtag_direction_init; - - if (swd_mode) { - struct signal *sig = find_signal_by_name("SWD_EN"); - if (!sig) { - LOG_ERROR("SWD mode is active but SWD_EN signal is not defined"); - return ERROR_JTAG_INIT_FAILED; - } - /* A dummy SWD_EN would have zero mask */ - if (sig->data_mask) - ftdi_set_signal(sig, '1'); - } - - mpsse_set_data_bits_low_byte(mpsse_ctx, output & 0xff, direction & 0xff); - mpsse_set_data_bits_high_byte(mpsse_ctx, output >> 8, direction >> 8); - - mpsse_loopback_config(mpsse_ctx, false); - - freq = mpsse_set_frequency(mpsse_ctx, jtag_get_speed_khz() * 1000); - - return mpsse_flush(mpsse_ctx); -} - -static int ftdi_quit(void) -{ - mpsse_close(mpsse_ctx); - - free(swd_cmd_queue); - - return ERROR_OK; -} - -COMMAND_HANDLER(ftdi_handle_device_desc_command) -{ - if (CMD_ARGC == 1) { - if (ftdi_device_desc) - free(ftdi_device_desc); - ftdi_device_desc = strdup(CMD_ARGV[0]); - } else { - LOG_ERROR("expected exactly one argument to ftdi_device_desc "); - } - - return ERROR_OK; -} - -COMMAND_HANDLER(ftdi_handle_serial_command) -{ - if (CMD_ARGC == 1) { - if (ftdi_serial) - free(ftdi_serial); - ftdi_serial = strdup(CMD_ARGV[0]); - } else { - return ERROR_COMMAND_SYNTAX_ERROR; - } - - 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) - COMMAND_PARSE_NUMBER(u8, CMD_ARGV[0], ftdi_channel); - else - return ERROR_COMMAND_SYNTAX_ERROR; - - return ERROR_OK; -} - -COMMAND_HANDLER(ftdi_handle_layout_init_command) -{ - if (CMD_ARGC != 2) - return ERROR_COMMAND_SYNTAX_ERROR; - - COMMAND_PARSE_NUMBER(u16, CMD_ARGV[0], jtag_output_init); - COMMAND_PARSE_NUMBER(u16, CMD_ARGV[1], jtag_direction_init); - - return ERROR_OK; -} - -COMMAND_HANDLER(ftdi_handle_layout_signal_command) -{ - if (CMD_ARGC < 1) - return ERROR_COMMAND_SYNTAX_ERROR; - - 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) { - if (strcmp("-data", CMD_ARGV[i]) == 0) { - invert_data = false; - COMMAND_PARSE_NUMBER(u16, CMD_ARGV[i + 1], data_mask); - } 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); - } else if (strcmp("-noe", CMD_ARGV[i]) == 0) { - invert_oe = true; - 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])) { - 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 { - LOG_ERROR("unknown option '%s'", CMD_ARGV[i]); - return ERROR_COMMAND_SYNTAX_ERROR; - } - } - - struct signal *sig; - sig = find_signal_by_name(CMD_ARGV[0]); - if (!sig) - sig = create_signal(CMD_ARGV[0]); - if (!sig) { - LOG_ERROR("failed to create signal %s", CMD_ARGV[0]); - return ERROR_FAIL; - } - - 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; - - return ERROR_OK; -} - -COMMAND_HANDLER(ftdi_handle_set_signal_command) -{ - if (CMD_ARGC < 2) - return ERROR_COMMAND_SYNTAX_ERROR; - - struct signal *sig; - 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; - } - - switch (*CMD_ARGV[1]) { - case '0': - case '1': - case 'z': - case 'Z': - /* single character level specifier only */ - if (CMD_ARGV[1][1] == '\0') { - ftdi_set_signal(sig, *CMD_ARGV[1]); - break; - } - default: - LOG_ERROR("unknown signal level '%s', use 0, 1 or z", CMD_ARGV[1]); - return ERROR_COMMAND_SYNTAX_ERROR; - } - - 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) { - LOG_WARNING("ignoring extra IDs in ftdi_vid_pid " - "(maximum is %d pairs)", MAX_USB_IDS); - CMD_ARGC = MAX_USB_IDS * 2; - } - if (CMD_ARGC < 2 || (CMD_ARGC & 1)) { - LOG_WARNING("incomplete ftdi_vid_pid configuration directive"); - if (CMD_ARGC < 2) - return ERROR_COMMAND_SYNTAX_ERROR; - /* remove the incomplete trailing id */ - CMD_ARGC -= 1; - } - - unsigned i; - for (i = 0; i < CMD_ARGC; i += 2) { - COMMAND_PARSE_NUMBER(u16, CMD_ARGV[i], ftdi_vid[i >> 1]); - COMMAND_PARSE_NUMBER(u16, CMD_ARGV[i + 1], ftdi_pid[i >> 1]); - } - - /* - * Explicitly terminate, in case there are multiples instances of - * ftdi_vid_pid. - */ - ftdi_vid[i >> 1] = ftdi_pid[i >> 1] = 0; - - 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", - .handler = &ftdi_handle_device_desc_command, - .mode = COMMAND_CONFIG, - .help = "set the USB device description of the FTDI device", - .usage = "description_string", - }, - { - .name = "ftdi_serial", - .handler = &ftdi_handle_serial_command, - .mode = COMMAND_CONFIG, - .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, - .mode = COMMAND_CONFIG, - .help = "set the channel of the FTDI device that is used as JTAG", - .usage = "(0-3)", - }, - { - .name = "ftdi_layout_init", - .handler = &ftdi_handle_layout_init_command, - .mode = COMMAND_CONFIG, - .help = "initialize the FTDI GPIO signals used " - "to control output-enables and reset signals", - .usage = "data direction", - }, - { - .name = "ftdi_layout_signal", - .handler = &ftdi_handle_layout_signal_command, - .mode = COMMAND_ANY, - .help = "define a signal controlled by one or more FTDI GPIO as data " - "and/or output enable", - .usage = "name [-data mask|-ndata mask] [-oe mask|-noe mask] [-alias|-nalias name]", - }, - { - .name = "ftdi_set_signal", - .handler = &ftdi_handle_set_signal_command, - .mode = COMMAND_EXEC, - .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, - .mode = COMMAND_CONFIG, - .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 -}; - -static int create_default_signal(const char *name, uint16_t data_mask) -{ - struct signal *sig = create_signal(name); - if (!sig) { - LOG_ERROR("failed to create signal %s", name); - return ERROR_FAIL; - } - sig->invert_data = false; - sig->data_mask = data_mask; - sig->invert_oe = false; - sig->oe_mask = 0; - - return ERROR_OK; -} - -static int create_signals(void) -{ - if (create_default_signal("TCK", 0x01) != ERROR_OK) - return ERROR_FAIL; - if (create_default_signal("TDI", 0x02) != ERROR_OK) - return ERROR_FAIL; - if (create_default_signal("TDO", 0x04) != ERROR_OK) - return ERROR_FAIL; - if (create_default_signal("TMS", 0x08) != ERROR_OK) - return ERROR_FAIL; - return ERROR_OK; -} - -static int ftdi_swd_init(void) -{ - LOG_INFO("FTDI SWD mode enabled"); - swd_mode = true; - - if (create_signals() != ERROR_OK) - return ERROR_FAIL; - - swd_cmd_queue_alloced = 10; - swd_cmd_queue = malloc(swd_cmd_queue_alloced * sizeof(*swd_cmd_queue)); - - return swd_cmd_queue != NULL ? ERROR_OK : ERROR_FAIL; -} - -static void ftdi_swd_swdio_en(bool enable) -{ - struct signal *oe = find_signal_by_name("SWDIO_OE"); - if (oe) - ftdi_set_signal(oe, enable ? '1' : '0'); -} - -/** - * Flush the MPSSE queue and process the SWD transaction queue - * @param dap - * @return - */ -static int ftdi_swd_run_queue(void) -{ - LOG_DEBUG("Executing %zu queued transactions", swd_cmd_queue_length); - int retval; - struct signal *led = find_signal_by_name("LED"); - - if (queued_retval != ERROR_OK) { - LOG_DEBUG("Skipping due to previous errors: %d", queued_retval); - goto skip; - } - - /* A transaction must be followed by another transaction or at least 8 idle cycles to - * ensure that data is clocked through the AP. */ - mpsse_clock_data_out(mpsse_ctx, NULL, 0, 8, SWD_MODE); - - /* Terminate the "blink", if the current layout has that feature */ - if (led) - ftdi_set_signal(led, '0'); - - queued_retval = mpsse_flush(mpsse_ctx); - if (queued_retval != ERROR_OK) { - LOG_ERROR("MPSSE failed"); - goto skip; - } - - for (size_t i = 0; i < swd_cmd_queue_length; i++) { - int ack = buf_get_u32(swd_cmd_queue[i].trn_ack_data_parity_trn, 1, 3); - - LOG_DEBUG("%s %s %s reg %X = %08"PRIx32, - ack == SWD_ACK_OK ? "OK" : ack == SWD_ACK_WAIT ? "WAIT" : ack == SWD_ACK_FAULT ? "FAULT" : "JUNK", - swd_cmd_queue[i].cmd & SWD_CMD_APnDP ? "AP" : "DP", - swd_cmd_queue[i].cmd & SWD_CMD_RnW ? "read" : "write", - (swd_cmd_queue[i].cmd & SWD_CMD_A32) >> 1, - buf_get_u32(swd_cmd_queue[i].trn_ack_data_parity_trn, - 1 + 3 + (swd_cmd_queue[i].cmd & SWD_CMD_RnW ? 0 : 1), 32)); - - if (ack != SWD_ACK_OK) { - queued_retval = ack == SWD_ACK_WAIT ? ERROR_WAIT : ERROR_FAIL; - goto skip; - - } else if (swd_cmd_queue[i].cmd & SWD_CMD_RnW) { - uint32_t data = buf_get_u32(swd_cmd_queue[i].trn_ack_data_parity_trn, 1 + 3, 32); - int parity = buf_get_u32(swd_cmd_queue[i].trn_ack_data_parity_trn, 1 + 3 + 32, 1); - - if (parity != parity_u32(data)) { - LOG_ERROR("SWD Read data parity mismatch"); - queued_retval = ERROR_FAIL; - goto skip; - } - - if (swd_cmd_queue[i].dst != NULL) - *swd_cmd_queue[i].dst = data; - } - } - -skip: - swd_cmd_queue_length = 0; - retval = queued_retval; - queued_retval = ERROR_OK; - - /* Queue a new "blink" */ - if (led && retval == ERROR_OK) - ftdi_set_signal(led, '1'); - - return retval; -} - -static void ftdi_swd_queue_cmd(uint8_t cmd, uint32_t *dst, uint32_t data, uint32_t ap_delay_clk) -{ - if (swd_cmd_queue_length >= swd_cmd_queue_alloced) { - /* Not enough room in the queue. Run the queue and increase its size for next time. - * Note that it's not possible to avoid running the queue here, because mpsse contains - * pointers into the queue which may be invalid after the realloc. */ - queued_retval = ftdi_swd_run_queue(); - struct swd_cmd_queue_entry *q = realloc(swd_cmd_queue, swd_cmd_queue_alloced * 2 * sizeof(*swd_cmd_queue)); - if (q != NULL) { - swd_cmd_queue = q; - swd_cmd_queue_alloced *= 2; - LOG_DEBUG("Increased SWD command queue to %zu elements", swd_cmd_queue_alloced); - } - } - - if (queued_retval != ERROR_OK) - return; - - size_t i = swd_cmd_queue_length++; - swd_cmd_queue[i].cmd = cmd | SWD_CMD_START | SWD_CMD_PARK; - - mpsse_clock_data_out(mpsse_ctx, &swd_cmd_queue[i].cmd, 0, 8, SWD_MODE); - - if (swd_cmd_queue[i].cmd & SWD_CMD_RnW) { - /* Queue a read transaction */ - swd_cmd_queue[i].dst = dst; - - ftdi_swd_swdio_en(false); - mpsse_clock_data_in(mpsse_ctx, swd_cmd_queue[i].trn_ack_data_parity_trn, - 0, 1 + 3 + 32 + 1 + 1, SWD_MODE); - ftdi_swd_swdio_en(true); - } else { - /* Queue a write transaction */ - ftdi_swd_swdio_en(false); - - mpsse_clock_data_in(mpsse_ctx, swd_cmd_queue[i].trn_ack_data_parity_trn, - 0, 1 + 3 + 1, SWD_MODE); - - ftdi_swd_swdio_en(true); - - buf_set_u32(swd_cmd_queue[i].trn_ack_data_parity_trn, 1 + 3 + 1, 32, data); - buf_set_u32(swd_cmd_queue[i].trn_ack_data_parity_trn, 1 + 3 + 1 + 32, 1, parity_u32(data)); - - mpsse_clock_data_out(mpsse_ctx, swd_cmd_queue[i].trn_ack_data_parity_trn, - 1 + 3 + 1, 32 + 1, SWD_MODE); - } - - /* Insert idle cycles after AP accesses to avoid WAIT */ - if (cmd & SWD_CMD_APnDP) - mpsse_clock_data_out(mpsse_ctx, NULL, 0, ap_delay_clk, SWD_MODE); - -} - -static void ftdi_swd_read_reg(uint8_t cmd, uint32_t *value, uint32_t ap_delay_clk) -{ - assert(cmd & SWD_CMD_RnW); - ftdi_swd_queue_cmd(cmd, value, 0, ap_delay_clk); -} - -static void ftdi_swd_write_reg(uint8_t cmd, uint32_t value, uint32_t ap_delay_clk) -{ - assert(!(cmd & SWD_CMD_RnW)); - ftdi_swd_queue_cmd(cmd, NULL, value, ap_delay_clk); -} - -static int_least32_t ftdi_swd_frequency(int_least32_t hz) -{ - if (hz > 0) - freq = mpsse_set_frequency(mpsse_ctx, hz); - - return freq; -} - -static int ftdi_swd_switch_seq(enum swd_special_seq seq) -{ - switch (seq) { - case LINE_RESET: - LOG_DEBUG("SWD line reset"); - mpsse_clock_data_out(mpsse_ctx, swd_seq_line_reset, 0, swd_seq_line_reset_len, SWD_MODE); - break; - case JTAG_TO_SWD: - LOG_DEBUG("JTAG-to-SWD"); - mpsse_clock_data_out(mpsse_ctx, swd_seq_jtag_to_swd, 0, swd_seq_jtag_to_swd_len, SWD_MODE); - break; - case SWD_TO_JTAG: - LOG_DEBUG("SWD-to-JTAG"); - mpsse_clock_data_out(mpsse_ctx, swd_seq_swd_to_jtag, 0, swd_seq_swd_to_jtag_len, SWD_MODE); - break; - default: - LOG_ERROR("Sequence %d not supported", seq); - return ERROR_FAIL; - } - - return ERROR_OK; -} - -static const struct swd_driver ftdi_swd = { - .init = ftdi_swd_init, - .frequency = ftdi_swd_frequency, - .switch_seq = ftdi_swd_switch_seq, - .read_reg = ftdi_swd_read_reg, - .write_reg = ftdi_swd_write_reg, - .run = ftdi_swd_run_queue, -}; - -static const char * const ftdi_transports[] = { "jtag", "swd", NULL }; - -struct jtag_interface ftdi_interface = { - .name = "ftdi", - .supported = DEBUG_CAP_TMS_SEQ, - .commands = ftdi_command_handlers, - .transports = ftdi_transports, - .swd = &ftdi_swd, - - .init = ftdi_initialize, - .quit = ftdi_quit, - .speed = ftdi_speed, - .speed_div = ftdi_speed_div, - .khz = ftdi_khz, - .execute_queue = ftdi_execute_queue, -}; diff --git a/src/jtag/drivers/gw16012.c b/src/jtag/drivers/gw16012.c deleted file mode 100644 index f6689969a..000000000 --- a/src/jtag/drivers/gw16012.c +++ /dev/null @@ -1,543 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2006 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include - -#if 1 -#define _DEBUG_GW16012_IO_ -#endif - -/* system includes */ -/* -ino: 060521-1036 */ -#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) - -#include -#include -#define ioperm(startport, length, enable) \ - 386_set_ioperm((startport), (length), (enable)) - -#else - -#endif /* __FreeBSD__, __FreeBSD_kernel__ */ - -#if PARPORT_USE_PPDEV == 1 -#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) -#include -#include -#define PPRSTATUS PPIGSTATUS -#define PPWDATA PPISDATA -#else -#include -#include -#endif -#include -#include -#else /* not PARPORT_USE_PPDEV */ -#ifndef _WIN32 -#include -#endif -#endif - -#if PARPORT_USE_GIVEIO == 1 && IS_CYGWIN == 1 -#include -#endif - -/* configuration */ -uint16_t gw16012_port; - -/* interface variables - */ -static uint8_t gw16012_msb; -static uint8_t gw16012_control_value; - -#if PARPORT_USE_PPDEV == 1 -static int device_handle; -#endif - -static void gw16012_data(uint8_t value) -{ - value = (value & 0x7f) | gw16012_msb; - gw16012_msb ^= 0x80; /* toggle MSB */ - -#ifdef _DEBUG_GW16012_IO_ - LOG_DEBUG("%2.2x", value); -#endif - - #if PARPORT_USE_PPDEV == 1 - ioctl(device_handle, PPWDATA, &value); - #else - #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) - outb(gw16012_port, value); - #else - outb(value, gw16012_port); - #endif - #endif -} - -static void gw16012_control(uint8_t value) -{ - if (value != gw16012_control_value) { - gw16012_control_value = value; - -#ifdef _DEBUG_GW16012_IO_ - LOG_DEBUG("%2.2x", gw16012_control_value); -#endif - - #if PARPORT_USE_PPDEV == 1 - ioctl(device_handle, PPWCONTROL, &gw16012_control_value); - #else - #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) - outb(gw16012_port + 2, gw16012_control_value); - #else - outb(gw16012_control_value, gw16012_port + 2); - #endif - #endif - } -} - -static void gw16012_input(uint8_t *value) -{ - #if PARPORT_USE_PPDEV == 1 - ioctl(device_handle, PPRSTATUS, value); - #else - *value = inb(gw16012_port + 1); - #endif - -#ifdef _DEBUG_GW16012_IO_ - LOG_DEBUG("%2.2x", *value); -#endif -} - -/* (1) assert or (0) deassert reset lines */ -static void gw16012_reset(int trst, int srst) -{ - LOG_DEBUG("trst: %i, srst: %i", trst, srst); - - if (trst == 0) - gw16012_control(0x0d); - else if (trst == 1) - gw16012_control(0x0c); - - if (srst == 0) - gw16012_control(0x0a); - else if (srst == 1) - gw16012_control(0x0b); -} - -static void gw16012_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); - } -} - -static void gw16012_state_move(void) -{ - int i = 0, tms = 0; - uint8_t tms_scan = tap_get_tms_path(tap_get_state(), tap_get_end_state()); - int tms_count = tap_get_tms_path_len(tap_get_state(), tap_get_end_state()); - - gw16012_control(0x0); /* single-bit mode */ - - for (i = 0; i < tms_count; i++) { - tms = (tms_scan >> i) & 1; - gw16012_data(tms << 1); /* output next TMS bit */ - } - - tap_set_state(tap_get_end_state()); -} - -static void gw16012_path_move(struct pathmove_command *cmd) -{ - int num_states = cmd->num_states; - int state_count; - - state_count = 0; - while (num_states) { - gw16012_control(0x0); /* single-bit mode */ - if (tap_state_transition(tap_get_state(), false) == cmd->path[state_count]) - gw16012_data(0x0); /* TCK cycle with TMS low */ - else if (tap_state_transition(tap_get_state(), true) == cmd->path[state_count]) - gw16012_data(0x2); /* TCK cycle with TMS high */ - else { - LOG_ERROR("BUG: %s -> %s isn't a valid TAP transition", - tap_state_name(tap_get_state()), tap_state_name(cmd->path[state_count])); - exit(-1); - } - - tap_set_state(cmd->path[state_count]); - state_count++; - num_states--; - } - - tap_set_end_state(tap_get_state()); -} - -static void gw16012_runtest(int num_cycles) -{ - tap_state_t saved_end_state = tap_get_end_state(); - int i; - - /* only do a state_move when we're not already in IDLE */ - if (tap_get_state() != TAP_IDLE) { - gw16012_end_state(TAP_IDLE); - gw16012_state_move(); - } - - for (i = 0; i < num_cycles; i++) { - gw16012_control(0x0); /* single-bit mode */ - gw16012_data(0x0); /* TMS cycle with TMS low */ - } - - gw16012_end_state(saved_end_state); - if (tap_get_state() != tap_get_end_state()) - gw16012_state_move(); -} - -static void gw16012_scan(bool ir_scan, enum scan_type type, uint8_t *buffer, int scan_size) -{ - int bits_left = scan_size; - int bit_count = 0; - tap_state_t saved_end_state = tap_get_end_state(); - uint8_t scan_out, scan_in; - - /* only if we're not already in the correct Shift state */ - if (!((!ir_scan && (tap_get_state() == TAP_DRSHIFT)) || - (ir_scan && (tap_get_state() == TAP_IRSHIFT)))) { - if (ir_scan) - gw16012_end_state(TAP_IRSHIFT); - else - gw16012_end_state(TAP_DRSHIFT); - - gw16012_state_move(); - gw16012_end_state(saved_end_state); - } - - while (type == SCAN_OUT && ((bits_left - 1) > 7)) { - gw16012_control(0x2); /* seven-bit mode */ - scan_out = buf_get_u32(buffer, bit_count, 7); - gw16012_data(scan_out); - bit_count += 7; - bits_left -= 7; - } - - gw16012_control(0x0); /* single-bit mode */ - while (bits_left-- > 0) { - uint8_t tms = 0; - - scan_out = buf_get_u32(buffer, bit_count, 1); - - if (bits_left == 0) /* last bit */ { - if ((ir_scan && (tap_get_end_state() == TAP_IRSHIFT)) - || (!ir_scan && (tap_get_end_state() == TAP_DRSHIFT))) - tms = 0; - else - tms = 2; - } - - gw16012_data(scan_out | tms); - - if (type != SCAN_OUT) { - gw16012_input(&scan_in); - buf_set_u32(buffer, bit_count, 1, ((scan_in & 0x08) >> 3)); - } - - bit_count++; - } - - if (!((ir_scan && (tap_get_end_state() == TAP_IRSHIFT)) || - (!ir_scan && (tap_get_end_state() == TAP_DRSHIFT)))) { - gw16012_data(0x0); - if (ir_scan) - tap_set_state(TAP_IRPAUSE); - else - tap_set_state(TAP_DRPAUSE); - - if (tap_get_state() != tap_get_end_state()) - gw16012_state_move(); - } -} - -static int gw16012_execute_queue(void) -{ - struct jtag_command *cmd = jtag_command_queue; /* currently processed command */ - int scan_size; - enum scan_type type; - uint8_t *buffer; - int retval; - - /* return ERROR_OK, unless a jtag_read_buffer returns a failed check - * that wasn't handled by a caller-provided error handler - */ - retval = ERROR_OK; - - while (cmd) { - switch (cmd->type) { - case JTAG_RESET: -#ifdef _DEBUG_JTAG_IO_ - LOG_DEBUG("reset trst: %i srst %i", cmd->cmd.reset->trst, cmd->cmd.reset->srst); -#endif - if (cmd->cmd.reset->trst == 1) - tap_set_state(TAP_RESET); - gw16012_reset(cmd->cmd.reset->trst, cmd->cmd.reset->srst); - break; - case JTAG_RUNTEST: -#ifdef _DEBUG_JTAG_IO_ - LOG_DEBUG("runtest %i cycles, end in %i", cmd->cmd.runtest->num_cycles, - cmd->cmd.runtest->end_state); -#endif - gw16012_end_state(cmd->cmd.runtest->end_state); - gw16012_runtest(cmd->cmd.runtest->num_cycles); - break; - case JTAG_TLR_RESET: -#ifdef _DEBUG_JTAG_IO_ - LOG_DEBUG("statemove end in %i", cmd->cmd.statemove->end_state); -#endif - gw16012_end_state(cmd->cmd.statemove->end_state); - gw16012_state_move(); - break; - case JTAG_PATHMOVE: -#ifdef _DEBUG_JTAG_IO_ - LOG_DEBUG("pathmove: %i states, end in %i", cmd->cmd.pathmove->num_states, - cmd->cmd.pathmove->path[cmd->cmd.pathmove->num_states - 1]); -#endif - gw16012_path_move(cmd->cmd.pathmove); - break; - case JTAG_SCAN: - gw16012_end_state(cmd->cmd.scan->end_state); - scan_size = jtag_build_buffer(cmd->cmd.scan, &buffer); - type = jtag_scan_type(cmd->cmd.scan); -#ifdef _DEBUG_JTAG_IO_ - LOG_DEBUG("%s scan (%i) %i bit end in %i", (cmd->cmd.scan->ir_scan) ? "ir" : "dr", - type, scan_size, cmd->cmd.scan->end_state); -#endif - gw16012_scan(cmd->cmd.scan->ir_scan, type, buffer, scan_size); - if (jtag_read_buffer(buffer, cmd->cmd.scan) != ERROR_OK) - retval = ERROR_JTAG_QUEUE_FAILED; - if (buffer) - free(buffer); - break; - case JTAG_SLEEP: -#ifdef _DEBUG_JTAG_IO_ - LOG_DEBUG("sleep %i", cmd->cmd.sleep->us); -#endif - jtag_sleep(cmd->cmd.sleep->us); - break; - default: - LOG_ERROR("BUG: unknown JTAG command type encountered"); - exit(-1); - } - cmd = cmd->next; - } - - return retval; -} - -#if PARPORT_USE_GIVEIO == 1 -static int gw16012_get_giveio_access(void) -{ - HANDLE h; - OSVERSIONINFO version; - - version.dwOSVersionInfoSize = sizeof version; - if (!GetVersionEx(&version)) { - errno = EINVAL; - return -1; - } - if (version.dwPlatformId != VER_PLATFORM_WIN32_NT) - return 0; - - h = CreateFile("\\\\.\\giveio", GENERIC_READ, 0, NULL, OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL, NULL); - if (h == INVALID_HANDLE_VALUE) { - errno = ENODEV; - return -1; - } - - CloseHandle(h); - - return 0; -} -#endif - -#if PARPORT_USE_PPDEV == 1 - -#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) - -#define GW16012_PPDEV_NAME "ppi" - -static int gw16012_init_ioctls(void) -{ - int temp = 0; - temp = ioctl(device_handle, PPCLAIM); - if (temp < 0) { - LOG_ERROR("cannot claim device"); - return ERROR_JTAG_INIT_FAILED; - } - - temp = PARPORT_MODE_COMPAT; - temp = ioctl(device_handle, PPSETMODE, &temp); - if (temp < 0) { - LOG_ERROR(" cannot set compatible mode to device"); - return ERROR_JTAG_INIT_FAILED; - } - - temp = IEEE1284_MODE_COMPAT; - temp = ioctl(device_handle, PPNEGOT, &temp); - if (temp < 0) { - LOG_ERROR("cannot set compatible 1284 mode to device"); - return ERROR_JTAG_INIT_FAILED; - } - return ERROR_OK; -} -#else - -#define GW16012_PPDEV_NAME "parport" - -static int gw16012_init_ioctls(void) -{ - return ERROR_OK; -} - -#endif /* defined(__FreeBSD__) || defined(__FreeBSD_kernel__) */ - -static int gw16012_init_device(void) -{ - const char *device_name = GW16012_PPDEV_NAME; - char buffer[256]; - - if (device_handle > 0) { - LOG_ERROR("device is already opened"); - return ERROR_JTAG_INIT_FAILED; - } - - snprintf(buffer, 256, "/dev/%s%d", device_name, gw16012_port); - LOG_DEBUG("opening %s...", buffer); - - device_handle = open(buffer, O_WRONLY); - if (device_handle < 0) { - LOG_ERROR("cannot open device. check it exists and that user read and write rights are set"); - return ERROR_JTAG_INIT_FAILED; - } - - LOG_DEBUG("...open"); - - if (gw16012_init_ioctls() != ERROR_OK) - return ERROR_JTAG_INIT_FAILED; - - return ERROR_OK; -} - -#else /* PARPORT_USE_PPDEV */ - -static int gw16012_init_device(void) -{ - if (gw16012_port == 0) { - gw16012_port = 0x378; - LOG_WARNING("No gw16012 port specified, using default '0x378' (LPT1)"); - } - - LOG_DEBUG("requesting privileges for parallel port 0x%lx...", (long unsigned)(gw16012_port)); -#if PARPORT_USE_GIVEIO == 1 - if (gw16012_get_giveio_access() != 0) { -#else /* PARPORT_USE_GIVEIO */ - if (ioperm(gw16012_port, 3, 1) != 0) { -#endif /* PARPORT_USE_GIVEIO */ - LOG_ERROR("missing privileges for direct i/o"); - return ERROR_JTAG_INIT_FAILED; - } - LOG_DEBUG("...privileges granted"); - - /* make sure parallel port is in right mode (clear tristate and interrupt */ -#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) - outb(gw16012_port + 2, 0x0); -#else - outb(0x0, gw16012_port + 2); -#endif - return ERROR_OK; -} - -#endif /* PARPORT_USE_PPDEV */ - -static int gw16012_init(void) -{ - uint8_t status_port; - - if (gw16012_init_device() != ERROR_OK) - return ERROR_JTAG_INIT_FAILED; - - gw16012_input(&status_port); - gw16012_msb = (status_port & 0x80) ^ 0x80; - - gw16012_reset(0, 0); - - return ERROR_OK; -} - -static int gw16012_quit(void) -{ - - return ERROR_OK; -} - -COMMAND_HANDLER(gw16012_handle_parport_port_command) -{ - if (CMD_ARGC == 1) { - /* only if the port wasn't overwritten by cmdline */ - if (gw16012_port == 0) - COMMAND_PARSE_NUMBER(u16, CMD_ARGV[0], gw16012_port); - else { - LOG_ERROR("The parport port was already configured!"); - return ERROR_FAIL; - } - } - - command_print(CMD_CTX, "parport port = %u", gw16012_port); - - return ERROR_OK; -} - -static const struct command_registration gw16012_command_handlers[] = { - { - .name = "parport_port", - .handler = gw16012_handle_parport_port_command, - .mode = COMMAND_CONFIG, - .help = "Display the address of the I/O port (e.g. 0x378) " - "or the number of the '/dev/parport' device used. " - "If a parameter is provided, first change that port.", - .usage = "[port_number]", - }, - COMMAND_REGISTRATION_DONE -}; - -struct jtag_interface gw16012_interface = { - .name = "gw16012", - .commands = gw16012_command_handlers, - - .init = gw16012_init, - .quit = gw16012_quit, - .execute_queue = gw16012_execute_queue, -}; diff --git a/src/jtag/drivers/jlink.c b/src/jtag/drivers/jlink.c deleted file mode 100644 index 300905823..000000000 --- a/src/jtag/drivers/jlink.c +++ /dev/null @@ -1,1979 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Juergen Stuber * - * based on Dominic Rath's and Benedikt Sauter's usbprog.c * - * * - * Copyright (C) 2008 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * Copyright (C) 2011 by Jean-Christophe PLAGNIOL-VIILARD * - * plagnioj@jcrosoft.com * - * * - * 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 * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 -#include "config.h" -#endif - -#include -#include - -#include -#include -#include - -#include - -static struct jaylink_context *jayctx; -static struct jaylink_device_handle *devh; -static struct jaylink_connection conn; -static struct jaylink_connection connlist[JAYLINK_MAX_CONNECTIONS]; -static enum jaylink_jtag_version jtag_command_version; -static uint8_t caps[JAYLINK_DEV_EXT_CAPS_SIZE]; - -static uint32_t serial_number; -static bool use_serial_number; -static enum jaylink_usb_address usb_address; -static bool use_usb_address; -static enum jaylink_target_interface iface = JAYLINK_TIF_JTAG; -static bool trace_enabled; - -#define JLINK_MAX_SPEED 12000 -#define JLINK_TAP_BUFFER_SIZE 2048 - -static unsigned int swd_buffer_size = JLINK_TAP_BUFFER_SIZE; - -/* 256 byte non-volatile memory */ -struct device_config { - uint8_t usb_address; - /* 0ffset 0x01 to 0x03 */ - uint8_t reserved_1[3]; - uint32_t target_power; - /* 0ffset 0x08 to 0x1f */ - uint8_t reserved_2[24]; - /* IP only for J-Link Pro */ - uint8_t ip_address[4]; - uint8_t subnet_mask[4]; - /* 0ffset 0x28 to 0x2f */ - uint8_t reserved_3[8]; - uint8_t mac_address[6]; - /* 0ffset 0x36 to 0xff */ - uint8_t reserved_4[202]; -} __attribute__ ((packed)); - -static struct device_config config; -static struct device_config tmp_config; - -/* Queue command functions */ -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_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); -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_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; - -/***************************************************************************/ -/* 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, - cmd->cmd.runtest->end_state); - - jlink_end_state(cmd->cmd.runtest->end_state); - jlink_runtest(cmd->cmd.runtest->num_cycles); -} - -static void jlink_execute_statemove(struct jtag_command *cmd) -{ - DEBUG_JTAG_IO("statemove end in %i", cmd->cmd.statemove->end_state); - - jlink_end_state(cmd->cmd.statemove->end_state); - jlink_state_move(); -} - -static void jlink_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]); - - jlink_path_move(cmd->cmd.pathmove->num_states, cmd->cmd.pathmove->path); -} - -static void jlink_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) { - 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); - - 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(); - } - - 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) -{ - DEBUG_JTAG_IO("reset trst: %i srst %i", cmd->cmd.reset->trst, - cmd->cmd.reset->srst); - - jlink_flush(); - jlink_reset(cmd->cmd.reset->trst, cmd->cmd.reset->srst); - jlink_flush(); -} - -static void jlink_execute_sleep(struct jtag_command *cmd) -{ - DEBUG_JTAG_IO("sleep %" PRIi32 "", cmd->cmd.sleep->us); - 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; - case JTAG_TLR_RESET: - jlink_execute_statemove(cmd); - break; - case JTAG_PATHMOVE: - jlink_execute_pathmove(cmd); - break; - case JTAG_SCAN: - jlink_execute_scan(cmd); - break; - case JTAG_RESET: - jlink_execute_reset(cmd); - break; - case JTAG_SLEEP: - jlink_execute_sleep(cmd); - break; - default: - LOG_ERROR("BUG: Unknown JTAG command type encountered."); - return ERROR_JTAG_QUEUE_FAILED; - } - - return ERROR_OK; -} - -static int jlink_execute_queue(void) -{ - int ret; - struct jtag_command *cmd = jtag_command_queue; - - while (cmd != NULL) { - ret = jlink_execute_command(cmd); - - if (ret != ERROR_OK) - return ret; - - cmd = cmd->next; - } - - return jlink_flush(); -} - -static int jlink_speed(int speed) -{ - int ret; - uint32_t freq; - uint16_t divider; - int max_speed; - - if (jaylink_has_cap(caps, JAYLINK_DEV_CAP_GET_SPEEDS)) { - ret = jaylink_get_speeds(devh, &freq, ÷r); - - if (ret != JAYLINK_OK) { - LOG_ERROR("jaylink_get_speeds() failed: %s.", - jaylink_strerror_name(ret)); - return ERROR_JTAG_DEVICE_ERROR; - } - - freq = freq / 1000; - max_speed = freq / divider; - } else { - max_speed = JLINK_MAX_SPEED; - } - - if (!speed) { - if (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_ADAPTIVE_CLOCKING)) { - LOG_ERROR("Adaptive clocking is not supported by the device."); - return ERROR_JTAG_NOT_IMPLEMENTED; - } - - speed = JAYLINK_SPEED_ADAPTIVE_CLOCKING; - } else if (speed > max_speed) { - LOG_INFO("Reduced speed from %d kHz to %d kHz (maximum).", speed, - max_speed); - speed = max_speed; - } - - ret = jaylink_set_speed(devh, speed); - - if (ret != JAYLINK_OK) { - LOG_ERROR("jaylink_set_speed() failed: %s.", - jaylink_strerror_name(ret)); - return ERROR_JTAG_DEVICE_ERROR; - } - - return ERROR_OK; -} - -static int jlink_speed_div(int speed, int *khz) -{ - *khz = speed; - - return ERROR_OK; -} - -static int jlink_khz(int khz, int *jtag_speed) -{ - *jtag_speed = khz; - - return ERROR_OK; -} - -static bool read_device_config(struct device_config *cfg) -{ - int ret; - - ret = jaylink_read_raw_config(devh, (uint8_t *)cfg); - - if (ret != JAYLINK_OK) { - LOG_ERROR("jaylink_read_raw_config() failed: %s.", - jaylink_strerror_name(ret)); - return false; - } - - if (cfg->usb_address == 0xff) - cfg->usb_address = 0x00; - - if (cfg->target_power == 0xffffffff) - cfg->target_power = 0; - - return true; -} - -static int select_interface(void) -{ - int ret; - uint32_t interfaces; - - if (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_SELECT_TIF)) { - if (iface != JAYLINK_TIF_JTAG) { - LOG_ERROR("Device supports JTAG transport only."); - return ERROR_JTAG_INIT_FAILED; - } - - return ERROR_OK; - } - - ret = jaylink_get_available_interfaces(devh, &interfaces); - - if (ret != JAYLINK_OK) { - LOG_ERROR("jaylink_get_available_interfaces() failed: %s.", - jaylink_strerror_name(ret)); - return ERROR_JTAG_INIT_FAILED; - } - - if (!(interfaces & (1 << iface))) { - LOG_ERROR("Selected transport is not supported by the device."); - return ERROR_JTAG_INIT_FAILED; - } - - ret = jaylink_select_interface(devh, iface, NULL); - - if (ret < 0) { - LOG_ERROR("jaylink_select_interface() failed: %s.", - jaylink_strerror_name(ret)); - return ERROR_JTAG_INIT_FAILED; - } - - return ERROR_OK; -} - -static int jlink_register(void) -{ - int ret; - int i; - bool handle_found; - - if (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_REGISTER)) - return ERROR_OK; - - ret = jaylink_register(devh, &conn, connlist, NULL, NULL); - - if (ret < 0) { - LOG_ERROR("jaylink_register() failed: %s.", - jaylink_strerror_name(ret)); - return ERROR_FAIL; - } - - handle_found = false; - - for (i = 0; i < ret; i++) { - if (connlist[i].handle == conn.handle) { - handle_found = true; - break; - } - } - - if (!handle_found) { - LOG_ERROR("Registration failed: maximum number of connections on the " - "device reached."); - return ERROR_FAIL; - } - - return ERROR_OK; -} - -/* - * Adjust the SWD transaction buffer size depending on the free device internal - * memory. This ensures that the SWD transactions sent to the device do not - * exceed the internal memory of the device. - */ -static bool adjust_swd_buffer_size(void) -{ - int ret; - uint32_t tmp; - - if (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_GET_FREE_MEMORY)) - return true; - - ret = jaylink_get_free_memory(devh, &tmp); - - if (ret != JAYLINK_OK) { - LOG_ERROR("jaylink_get_free_memory() failed: %s.", - jaylink_strerror_name(ret)); - return false; - } - - if (tmp < 143) { - LOG_ERROR("Not enough free device internal memory: %u bytes.", tmp); - return false; - } - - tmp = MIN(JLINK_TAP_BUFFER_SIZE, (tmp - 16) / 2); - - if (tmp != swd_buffer_size) { - swd_buffer_size = tmp; - LOG_DEBUG("Adjusted SWD transaction buffer size to %u bytes.", - swd_buffer_size); - } - - return true; -} - -static int jlink_init(void) -{ - int ret; - struct jaylink_device **devs; - unsigned int i; - bool found_device; - uint32_t tmp; - char *firmware_version; - struct jaylink_hardware_version hwver; - struct jaylink_hardware_status hwstatus; - enum jaylink_usb_address address; - size_t length; - - ret = jaylink_init(&jayctx); - - if (ret != JAYLINK_OK) { - LOG_ERROR("jaylink_init() failed: %s.", - jaylink_strerror_name(ret)); - return ERROR_JTAG_INIT_FAILED; - } - - ret = jaylink_get_device_list(jayctx, &devs); - - if (ret < 0) { - LOG_ERROR("jaylink_get_device_list() failed: %s.", - jaylink_strerror_name(ret)); - jaylink_exit(jayctx); - return ERROR_JTAG_INIT_FAILED; - } - - found_device = false; - - if (!use_serial_number && !use_usb_address) - LOG_INFO("No device selected, using first device."); - - for (i = 0; devs[i]; 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) { - ret = jaylink_device_get_usb_address(devs[i], &address); - - 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) { - found_device = true; - break; - } - - LOG_ERROR("Failed to open device: %s.", jaylink_strerror_name(ret)); - } - - jaylink_free_device_list(devs, 1); - - if (!found_device) { - LOG_ERROR("No J-Link device found."); - jaylink_exit(jayctx); - return ERROR_JTAG_INIT_FAILED; - } - - /* - * Be careful with changing the following initialization sequence because - * some devices are known to be sensitive regarding the order. - */ - - ret = jaylink_get_firmware_version(devh, &firmware_version, &length); - - 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); - ret = jaylink_get_caps(devh, caps); - - if (ret != JAYLINK_OK) { - LOG_ERROR("jaylink_get_caps() failed: %s.", jaylink_strerror_name(ret)); - jaylink_close(devh); - jaylink_exit(jayctx); - return ERROR_JTAG_INIT_FAILED; - } - - if (jaylink_has_cap(caps, JAYLINK_DEV_CAP_GET_EXT_CAPS)) { - ret = jaylink_get_extended_caps(devh, caps); - - if (ret != JAYLINK_OK) { - LOG_ERROR("jaylink_get_extended_caps() failed: %s.", - jaylink_strerror_name(ret)); - jaylink_close(devh); - jaylink_exit(jayctx); - return ERROR_JTAG_INIT_FAILED; - } - } - - jtag_command_version = JAYLINK_JTAG_V2; - - if (jaylink_has_cap(caps, JAYLINK_DEV_CAP_GET_HW_VERSION)) { - ret = jaylink_get_hardware_version(devh, &hwver); - - if (ret != JAYLINK_OK) { - LOG_ERROR("Failed to retrieve hardware version: %s.", - jaylink_strerror_name(ret)); - jaylink_close(devh); - jaylink_exit(jayctx); - return ERROR_JTAG_INIT_FAILED; - } - - LOG_INFO("Hardware version: %u.%02u", hwver.major, hwver.minor); - - if (hwver.major >= 5) - jtag_command_version = JAYLINK_JTAG_V3; - } - - if (iface == JAYLINK_TIF_SWD) { - /* - * Adjust the SWD transaction buffer size in case there is already - * allocated memory on the device. This happens for example if the - * memory for SWO capturing is still allocated because the software - * which used the device before has not been shut down properly. - */ - if (!adjust_swd_buffer_size()) { - jaylink_close(devh); - jaylink_exit(jayctx); - return ERROR_JTAG_INIT_FAILED; - } - } - - if (jaylink_has_cap(caps, JAYLINK_DEV_CAP_READ_CONFIG)) { - if (!read_device_config(&config)) { - LOG_ERROR("Failed to read device configuration data."); - jaylink_close(devh); - jaylink_exit(jayctx); - return ERROR_JTAG_INIT_FAILED; - } - - memcpy(&tmp_config, &config, sizeof(struct device_config)); - } - - ret = jaylink_get_hardware_status(devh, &hwstatus); - - if (ret != JAYLINK_OK) { - LOG_ERROR("jaylink_get_hardware_status() failed: %s.", - jaylink_strerror_name(ret)); - jaylink_close(devh); - jaylink_exit(jayctx); - return ERROR_JTAG_INIT_FAILED; - } - - LOG_INFO("VTarget = %u.%03u V", hwstatus.target_voltage / 1000, - hwstatus.target_voltage % 1000); - - conn.handle = 0; - conn.pid = 0; - conn.hid = 0; - conn.iid = 0; - conn.cid = 0; - - ret = jlink_register(); - - if (ret != ERROR_OK) { - jaylink_close(devh); - jaylink_exit(jayctx); - return ERROR_JTAG_INIT_FAILED; - } - - ret = select_interface(); - - if (ret != ERROR_OK) { - jaylink_close(devh); - jaylink_exit(jayctx); - return ret; - } - - jlink_reset(0, 0); - jtag_sleep(3000); - jlink_tap_init(); - - jlink_speed(jtag_get_speed_khz()); - - if (iface == JAYLINK_TIF_JTAG) { - /* - * J-Link devices with firmware version v5 and v6 seems to have an issue - * if the first tap move is not divisible by 8, so we send a TLR on - * first power up. - */ - uint8_t tms = 0xff; - jlink_clock_data(NULL, 0, &tms, 0, NULL, 0, 8); - - jlink_flush(); - } - - return ERROR_OK; -} - -static int jlink_quit(void) -{ - int ret; - - if (trace_enabled) { - ret = jaylink_swo_stop(devh); - - if (ret != JAYLINK_OK) - LOG_ERROR("jaylink_swo_stop() failed: %s.", - jaylink_strerror_name(ret)); - } - - if (jaylink_has_cap(caps, JAYLINK_DEV_CAP_REGISTER)) { - ret = jaylink_unregister(devh, &conn, connlist, NULL, NULL); - - if (ret < 0) - LOG_ERROR("jaylink_unregister() failed: %s.", - jaylink_strerror_name(ret)); - } - - jaylink_close(devh); - jaylink_exit(jayctx); - - return ERROR_OK; -} - -/***************************************************************************/ -/* Queue command implementations */ - -static void jlink_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); - } -} - -/* Goes to the end state. */ -static void jlink_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()); - - jlink_clock_data(NULL, 0, &tms_scan, 0, NULL, 0, tms_scan_bits); - - tap_set_state(tap_get_end_state()); -} - -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_clock_data(NULL, 0, NULL, 0, NULL, 0, 1); - else if (path[i] == tap_state_transition(tap_get_state(), true)) - 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])); - exit(-1); - } - - tap_set_state(path[i]); - } - - tap_set_end_state(tap_get_state()); -} - -static void jlink_stableclocks(int num_cycles) -{ - int i; - - 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); -} - -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) { - jlink_end_state(TAP_IDLE); - jlink_state_move(); - /* num_cycles--; */ - } - - jlink_stableclocks(num_cycles); - - /* Finish in end_state. */ - jlink_end_state(saved_end_state); - - 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); - - /* Signals are active low. */ - if (srst == 0) - jaylink_set_reset(devh); - - if (srst == 1) - jaylink_clear_reset(devh); - - if (trst == 1) - jaylink_jtag_clear_trst(devh); - - if (trst == 0) - jaylink_jtag_set_trst(devh); -} - -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], "%i", &tmp) != 1) { - command_print(CMD_CTX, "Invalid USB address: %s.", CMD_ARGV[0]); - return ERROR_FAIL; - } - - 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; - - return ERROR_OK; -} - -COMMAND_HANDLER(jlink_serial_command) -{ - 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) { - command_print(CMD_CTX, "Invalid serial number: %s.", CMD_ARGV[0]); - return ERROR_FAIL; - } - - use_serial_number = true; - use_usb_address = false; - - return ERROR_OK; -} - -COMMAND_HANDLER(jlink_handle_hwstatus_command) -{ - int ret; - struct jaylink_hardware_status status; - - ret = jaylink_get_hardware_status(devh, &status); - - if (ret != JAYLINK_OK) { - command_print(CMD_CTX, "jaylink_get_hardware_status() failed: %s.", - jaylink_strerror_name(ret)); - return ERROR_FAIL; - } - - command_print(CMD_CTX, "VTarget = %u.%03u V", - status.target_voltage / 1000, status.target_voltage % 1000); - - command_print(CMD_CTX, "TCK = %u TDI = %u TDO = %u TMS = %u SRST = %u " - "TRST = %u", status.tck, status.tdi, status.tdo, status.tms, - status.tres, status.trst); - - if (status.target_voltage < 1500) - command_print(CMD_CTX, "Target voltage too low. Check target power."); - - return ERROR_OK; -} - -COMMAND_HANDLER(jlink_handle_free_memory_command) -{ - int ret; - uint32_t tmp; - - if (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_GET_FREE_MEMORY)) { - command_print(CMD_CTX, "Retrieval of free memory is not supported by " - "the device."); - return ERROR_OK; - } - - ret = jaylink_get_free_memory(devh, &tmp); - - if (ret != JAYLINK_OK) { - command_print(CMD_CTX, "jaylink_get_free_memory() failed: %s.", - jaylink_strerror_name(ret)); - return ERROR_FAIL; - } - - command_print(CMD_CTX, "Device has %u bytes of free memory.", tmp); - - return ERROR_OK; -} - -COMMAND_HANDLER(jlink_handle_jlink_jtag_command) -{ - int tmp; - int version; - - if (!CMD_ARGC) { - switch (jtag_command_version) { - case JAYLINK_JTAG_V2: - version = 2; - break; - case JAYLINK_JTAG_V3: - version = 3; - break; - default: - return ERROR_FAIL; - } - - command_print(CMD_CTX, "JTAG command version: %i", version); - } else if (CMD_ARGC == 1) { - if (sscanf(CMD_ARGV[0], "%i", &tmp) != 1) { - command_print(CMD_CTX, "Invalid argument: %s.", CMD_ARGV[0]); - return ERROR_COMMAND_SYNTAX_ERROR; - } - - switch (tmp) { - case 2: - jtag_command_version = JAYLINK_JTAG_V2; - break; - case 3: - jtag_command_version = JAYLINK_JTAG_V3; - break; - default: - command_print(CMD_CTX, "Invalid argument: %s.", CMD_ARGV[0]); - return ERROR_COMMAND_SYNTAX_ERROR; - } - } else { - command_print(CMD_CTX, "Need exactly one argument for jlink jtag."); - return ERROR_COMMAND_SYNTAX_ERROR; - } - - return ERROR_OK; -} - -COMMAND_HANDLER(jlink_handle_target_power_command) -{ - int ret; - int enable; - - if (CMD_ARGC != 1) { - command_print(CMD_CTX, "Need exactly one argument for jlink " - "targetpower."); - return ERROR_COMMAND_SYNTAX_ERROR; - } - - if (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_SET_TARGET_POWER)) { - command_print(CMD_CTX, "Target power supply is not supported by the " - "device."); - return ERROR_OK; - } - - if (!strcmp(CMD_ARGV[0], "on")) { - enable = true; - } else if (!strcmp(CMD_ARGV[0], "off")) { - enable = false; - } else { - command_print(CMD_CTX, "Invalid argument: %s.", CMD_ARGV[0]); - return ERROR_FAIL; - } - - ret = jaylink_set_target_power(devh, enable); - - if (ret != JAYLINK_OK) { - command_print(CMD_CTX, "jaylink_set_target_power() failed: %s.", - jaylink_strerror_name(ret)); - return ERROR_FAIL; - } - - return ERROR_OK; -} - -static void show_config_usb_address(struct command_context *ctx) -{ - if (config.usb_address != tmp_config.usb_address) - command_print(ctx, "USB address: %u [%u]", config.usb_address, - tmp_config.usb_address); - else - command_print(ctx, "USB address: %u", config.usb_address); -} - -static void show_config_ip_address(struct command_context *ctx) -{ - if (!memcmp(config.ip_address, tmp_config.ip_address, 4)) - command_print(ctx, "IP address: %d.%d.%d.%d", - config.ip_address[3], config.ip_address[2], - config.ip_address[1], config.ip_address[0]); - else - command_print(ctx, "IP address: %d.%d.%d.%d [%d.%d.%d.%d]", - config.ip_address[3], config.ip_address[2], - config.ip_address[1], config.ip_address[0], - tmp_config.ip_address[3], tmp_config.ip_address[2], - tmp_config.ip_address[1], tmp_config.ip_address[0]); - - if (!memcmp(config.subnet_mask, tmp_config.subnet_mask, 4)) - command_print(ctx, "Subnet mask: %d.%d.%d.%d", - config.subnet_mask[3], config.subnet_mask[2], - config.subnet_mask[1], config.subnet_mask[0]); - else - command_print(ctx, "Subnet mask: %d.%d.%d.%d [%d.%d.%d.%d]", - config.subnet_mask[3], config.subnet_mask[2], - config.subnet_mask[1], config.subnet_mask[0], - tmp_config.subnet_mask[3], tmp_config.subnet_mask[2], - tmp_config.subnet_mask[1], tmp_config.subnet_mask[0]); -} - -static void show_config_mac_address(struct command_context *ctx) -{ - if (!memcmp(config.mac_address, tmp_config.mac_address, 6)) - command_print(ctx, "MAC address: %.02x:%.02x:%.02x:%.02x:%.02x:%.02x", - config.mac_address[5], config.mac_address[4], - config.mac_address[3], config.mac_address[2], - config.mac_address[1], config.mac_address[0]); - else - command_print(ctx, "MAC address: %.02x:%.02x:%.02x:%.02x:%.02x:%.02x " - "[%.02x:%.02x:%.02x:%.02x:%.02x:%.02x]", - config.mac_address[5], config.mac_address[4], - config.mac_address[3], config.mac_address[2], - config.mac_address[1], config.mac_address[0], - tmp_config.mac_address[5], tmp_config.mac_address[4], - tmp_config.mac_address[3], tmp_config.mac_address[2], - tmp_config.mac_address[1], tmp_config.mac_address[0]); -} - -static void show_config_target_power(struct command_context *ctx) -{ - const char *target_power; - const char *current_target_power; - - if (!config.target_power) - target_power = "off"; - else - target_power = "on"; - - if (!tmp_config.target_power) - current_target_power = "off"; - else - current_target_power = "on"; - - if (config.target_power != tmp_config.target_power) - command_print(ctx, "Target power supply: %s [%s]", target_power, - current_target_power); - else - command_print(ctx, "Target power supply: %s", target_power); -} - -static void show_config(struct command_context *ctx) -{ - command_print(ctx, "J-Link device configuration:"); - - show_config_usb_address(ctx); - - if (jaylink_has_cap(caps, JAYLINK_DEV_CAP_SET_TARGET_POWER)) - show_config_target_power(ctx); - - if (jaylink_has_cap(caps, JAYLINK_DEV_CAP_ETHERNET)) { - show_config_ip_address(ctx); - show_config_mac_address(ctx); - } -} - -static int poll_trace(uint8_t *buf, size_t *size) -{ - int ret; - uint32_t length; - - length = *size; - - ret = jaylink_swo_read(devh, buf, &length); - - if (ret != JAYLINK_OK) { - LOG_ERROR("jaylink_swo_read() failed: %s.", jaylink_strerror_name(ret)); - return ERROR_FAIL; - } - - *size = length; - - return ERROR_OK; -} - -static uint32_t calculate_trace_buffer_size(void) -{ - int ret; - uint32_t tmp; - - if (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_GET_FREE_MEMORY)) - return 0; - - ret = jaylink_get_free_memory(devh, &tmp); - - if (ret != JAYLINK_OK) { - LOG_ERROR("jaylink_get_free_memory() failed: %s.", - jaylink_strerror_name(ret)); - return ERROR_FAIL; - } - - if (tmp > 0x3fff || tmp <= 0x600) - tmp = tmp >> 1; - else - tmp = tmp - 0x400; - - return tmp & 0xffffff00; -} - -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 - (speed.freq / ((double)trace_freq * speed.min_div))); - - 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 " - "%.02f %%.", divider, deviation); - return true; - } - - if (deviation < min) - min = deviation; - } - - LOG_ERROR("Selected trace frequency is not supported by the device. " - "Please choose a different trace frequency."); - LOG_ERROR("Maximum permitted deviation is 3.00 %%, but only %.02f %% " - "could be achieved.", min * 100); - - return false; -} - -static int config_trace(bool enabled, enum tpio_pin_protocol pin_protocol, - uint32_t port_size, unsigned int *trace_freq) -{ - int ret; - uint32_t buffer_size; - struct jaylink_swo_speed speed; - - if (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_SWO)) { - LOG_ERROR("Trace capturing is not supported by the device."); - return ERROR_FAIL; - } - - if (pin_protocol != ASYNC_UART) { - LOG_ERROR("Selected pin protocol is not supported."); - return ERROR_FAIL; - } - - trace_enabled = enabled; - - ret = jaylink_swo_stop(devh); - - if (ret != JAYLINK_OK) { - LOG_ERROR("jaylink_swo_stop() failed: %s.", jaylink_strerror_name(ret)); - return ERROR_FAIL; - } - - if (!enabled) { - /* - * Adjust the SWD transaction buffer size as stopping SWO capturing - * deallocates device internal memory. - */ - if (!adjust_swd_buffer_size()) - return ERROR_FAIL; - - return ERROR_OK; - } - - buffer_size = calculate_trace_buffer_size(); - - if (!buffer_size) { - LOG_ERROR("Not enough free device memory to start trace capturing."); - return ERROR_FAIL; - } - - ret = jaylink_swo_get_speeds(devh, JAYLINK_SWO_MODE_UART, &speed); - - if (ret != JAYLINK_OK) { - LOG_ERROR("jaylink_swo_get_speeds() failed: %s.", - jaylink_strerror_name(ret)); - return ERROR_FAIL; - } - - if (!*trace_freq) - *trace_freq = speed.freq / speed.min_div; - - if (!check_trace_freq(speed, *trace_freq)) - return ERROR_FAIL; - - LOG_DEBUG("Using %u bytes device memory for trace capturing.", buffer_size); - - ret = jaylink_swo_start(devh, JAYLINK_SWO_MODE_UART, *trace_freq, - buffer_size); - - if (ret != JAYLINK_OK) { - LOG_ERROR("jaylink_start_swo() failed: %s.", - jaylink_strerror_name(ret)); - return ERROR_FAIL; - } - - /* - * Adjust the SWD transaction buffer size as starting SWO capturing - * allocates device internal memory. - */ - if (!adjust_swd_buffer_size()) - return ERROR_FAIL; - - return ERROR_OK; -} - -COMMAND_HANDLER(jlink_handle_config_usb_address_command) -{ - uint8_t tmp; - - if (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_READ_CONFIG)) { - command_print(CMD_CTX, "Reading configuration is not supported by the " - "device."); - return ERROR_OK; - } - - if (!CMD_ARGC) { - show_config_usb_address(CMD_CTX); - } else if (CMD_ARGC == 1) { - if (sscanf(CMD_ARGV[0], "%" SCNd8, &tmp) != 1) { - command_print(CMD_CTX, "Invalid USB address: %s.", CMD_ARGV[0]); - return ERROR_FAIL; - } - - if (tmp > JAYLINK_USB_ADDRESS_3) { - command_print(CMD_CTX, "Invalid USB address: %u.", tmp); - return ERROR_FAIL; - } - - tmp_config.usb_address = tmp; - } else { - command_print(CMD_CTX, "Need exactly one argument for jlink config " - "usb."); - return ERROR_COMMAND_SYNTAX_ERROR; - } - - return ERROR_OK; -} - -COMMAND_HANDLER(jlink_handle_config_target_power_command) -{ - int enable; - - if (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_READ_CONFIG)) { - command_print(CMD_CTX, "Reading configuration is not supported by the " - "device."); - return ERROR_OK; - } - - if (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_SET_TARGET_POWER)) { - command_print(CMD_CTX, "Target power supply is not supported by the " - "device."); - return ERROR_OK; - } - - if (!CMD_ARGC) { - show_config_target_power(CMD_CTX); - } else if (CMD_ARGC == 1) { - if (!strcmp(CMD_ARGV[0], "on")) { - enable = true; - } else if (!strcmp(CMD_ARGV[0], "off")) { - enable = false; - } else { - command_print(CMD_CTX, "Invalid argument: %s.", CMD_ARGV[0]); - return ERROR_FAIL; - } - - tmp_config.target_power = enable; - } else { - command_print(CMD_CTX, "Need exactly one argument for jlink config " - "targetpower."); - return ERROR_COMMAND_SYNTAX_ERROR; - } - - return ERROR_OK; -} - -COMMAND_HANDLER(jlink_handle_config_mac_address_command) -{ - uint8_t addr[6]; - int i; - char *e; - const char *str; - - if (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_READ_CONFIG)) { - command_print(CMD_CTX, "Reading configuration is not supported by the " - "device."); - return ERROR_OK; - } - - if (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_ETHERNET)) { - command_print(CMD_CTX, "Ethernet connectivity is not supported by the " - "device."); - return ERROR_OK; - } - - if (!CMD_ARGC) { - show_config_mac_address(CMD_CTX); - } else if (CMD_ARGC == 1) { - str = CMD_ARGV[0]; - - if ((strlen(str) != 17) || (str[2] != ':' || str[5] != ':' || \ - str[8] != ':' || str[11] != ':' || str[14] != ':')) { - command_print(CMD_CTX, "Invalid MAC address format."); - return ERROR_COMMAND_SYNTAX_ERROR; - } - - for (i = 5; i >= 0; i--) { - addr[i] = strtoul(str, &e, 16); - str = e + 1; - } - - if (!(addr[0] | addr[1] | addr[2] | addr[3] | addr[4] | addr[5])) { - command_print(CMD_CTX, "Invalid MAC address: zero address."); - return ERROR_COMMAND_SYNTAX_ERROR; - } - - if (!(0x01 & addr[0])) { - command_print(CMD_CTX, "Invalid MAC address: multicast address."); - return ERROR_COMMAND_SYNTAX_ERROR; - } - - memcpy(tmp_config.mac_address, addr, sizeof(addr)); - } else { - command_print(CMD_CTX, "Need exactly one argument for jlink config " - " mac."); - return ERROR_COMMAND_SYNTAX_ERROR; - } - - return ERROR_OK; -} - -static bool string_to_ip(const char *s, uint8_t *ip, int *pos) -{ - uint8_t lip[4]; - char *e; - const char *s_save = s; - int i; - - if (!s) - return false; - - for (i = 0; i < 4; i++) { - lip[i] = strtoul(s, &e, 10); - - if (*e != '.' && i != 3) - return false; - - s = e + 1; - } - - *pos = e - s_save; - memcpy(ip, lip, sizeof(lip)); - - return true; -} - -static void cpy_ip(uint8_t *dst, uint8_t *src) -{ - int i, j; - - for (i = 0, j = 3; i < 4; i++, j--) - dst[i] = src[j]; -} - -COMMAND_HANDLER(jlink_handle_config_ip_address_command) -{ - uint8_t ip_address[4]; - uint32_t subnet_mask = 0; - int i, len; - uint8_t subnet_bits = 24; - - if (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_READ_CONFIG)) { - command_print(CMD_CTX, "Reading configuration is not supported by the " - "device."); - return ERROR_OK; - } - - if (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_ETHERNET)) { - command_print(CMD_CTX, "Ethernet connectivity is not supported by the " - "device."); - return ERROR_OK; - } - - if (!CMD_ARGC) { - show_config_ip_address(CMD_CTX); - } else { - if (!string_to_ip(CMD_ARGV[0], ip_address, &i)) - return ERROR_COMMAND_SYNTAX_ERROR; - - len = strlen(CMD_ARGV[0]); - - /* Check for format A.B.C.D/E. */ - if (i < len) { - if (CMD_ARGV[0][i] != '/') - return ERROR_COMMAND_SYNTAX_ERROR; - - COMMAND_PARSE_NUMBER(u8, CMD_ARGV[0] + i + 1, subnet_bits); - } else if (CMD_ARGC > 1) { - if (!string_to_ip(CMD_ARGV[1], (uint8_t *)&subnet_mask, &i)) - return ERROR_COMMAND_SYNTAX_ERROR; - } - - if (!subnet_mask) - subnet_mask = (uint32_t)(subnet_bits < 32 ? - ((1ULL << subnet_bits) - 1) : 0xffffffff); - - cpy_ip(tmp_config.ip_address, ip_address); - cpy_ip(tmp_config.subnet_mask, (uint8_t *)&subnet_mask); - } - - return ERROR_OK; -} - -COMMAND_HANDLER(jlink_handle_config_reset_command) -{ - if (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_READ_CONFIG)) - return ERROR_OK; - - memcpy(&tmp_config, &config, sizeof(struct device_config)); - - return ERROR_OK; -} - - -COMMAND_HANDLER(jlink_handle_config_write_command) -{ - int ret; - - if (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_READ_CONFIG)) { - command_print(CMD_CTX, "Reading configuration is not supported by the " - "device."); - return ERROR_OK; - } - - if (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_WRITE_CONFIG)) { - command_print(CMD_CTX, "Writing configuration is not supported by the " - "device."); - return ERROR_OK; - } - - if (!memcmp(&config, &tmp_config, sizeof(struct device_config))) { - command_print(CMD_CTX, "Operation not performed due to no changes in " - "the configuration."); - return ERROR_OK; - } - - ret = jaylink_write_raw_config(devh, (const uint8_t *)&tmp_config); - - if (ret != JAYLINK_OK) { - LOG_ERROR("jaylink_write_raw_config() failed: %s.", - jaylink_strerror_name(ret)); - return ERROR_FAIL; - } - - if (!read_device_config(&config)) { - LOG_ERROR("Failed to read device configuration for verification."); - return ERROR_FAIL; - } - - if (memcmp(&config, &tmp_config, sizeof(struct device_config))) { - LOG_ERROR("Verification of device configuration failed. Please check " - "your device."); - return ERROR_FAIL; - } - - memcpy(&tmp_config, &config, sizeof(struct device_config)); - command_print(CMD_CTX, "The new device configuration applies after power " - "cycling the J-Link device."); - - return ERROR_OK; -} - -COMMAND_HANDLER(jlink_handle_config_command) -{ - if (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_READ_CONFIG)) { - command_print(CMD_CTX, "Device doesn't support reading configuration."); - return ERROR_OK; - } - - if (CMD_ARGC == 0) - show_config(CMD_CTX); - - return ERROR_OK; -} - -static const struct command_registration jlink_config_subcommand_handlers[] = { - { - .name = "usb", - .handler = &jlink_handle_config_usb_address_command, - .mode = COMMAND_EXEC, - .help = "set the USB address", - .usage = "[0-3]", - }, - { - .name = "targetpower", - .handler = &jlink_handle_config_target_power_command, - .mode = COMMAND_EXEC, - .help = "set the target power supply", - .usage = "[on|off]" - }, - { - .name = "mac", - .handler = &jlink_handle_config_mac_address_command, - .mode = COMMAND_EXEC, - .help = "set the MAC Address", - .usage = "[ff:ff:ff:ff:ff:ff]", - }, - { - .name = "ip", - .handler = &jlink_handle_config_ip_address_command, - .mode = COMMAND_EXEC, - .help = "set the IP address, where A.B.C.D is the IP address, " - "E the bit of the subnet mask, F.G.H.I the subnet mask", - .usage = "[A.B.C.D[/E] [F.G.H.I]]", - }, - { - .name = "reset", - .handler = &jlink_handle_config_reset_command, - .mode = COMMAND_EXEC, - .help = "undo configuration changes" - }, - { - .name = "write", - .handler = &jlink_handle_config_write_command, - .mode = COMMAND_EXEC, - .help = "write configuration to the device" - }, - COMMAND_REGISTRATION_DONE -}; - -static const struct command_registration jlink_subcommand_handlers[] = { - { - .name = "jtag", - .handler = &jlink_handle_jlink_jtag_command, - .mode = COMMAND_EXEC, - .help = "select the JTAG command version", - .usage = "[2|3]", - }, - { - .name = "targetpower", - .handler = &jlink_handle_target_power_command, - .mode = COMMAND_EXEC, - .help = "set the target power supply", - .usage = "" - }, - { - .name = "freemem", - .handler = &jlink_handle_free_memory_command, - .mode = COMMAND_EXEC, - .help = "show free device memory" - }, - { - .name = "hwstatus", - .handler = &jlink_handle_hwstatus_command, - .mode = COMMAND_EXEC, - .help = "show the hardware status" - }, - { - .name = "usb", - .handler = &jlink_usb_command, - .mode = COMMAND_CONFIG, - .help = "set the USB address of the device that should be used", - .usage = "<0-3>" - }, - { - .name = "serial", - .handler = &jlink_serial_command, - .mode = COMMAND_CONFIG, - .help = "set the serial number of the device that should be used", - .usage = "" - }, - { - .name = "config", - .handler = &jlink_handle_config_command, - .mode = COMMAND_EXEC, - .help = "access the device configuration. If no argument is given " - "this will show the device configuration", - .chain = jlink_config_subcommand_handlers, - }, - COMMAND_REGISTRATION_DONE -}; - -static const struct command_registration jlink_command_handlers[] = { - { - .name = "jlink", - .mode = COMMAND_ANY, - .help = "perform jlink management", - .chain = jlink_subcommand_handlers, - }, - COMMAND_REGISTRATION_DONE -}; - -static int jlink_swd_init(void) -{ - iface = JAYLINK_TIF_SWD; - - return ERROR_OK; -} - -static void jlink_swd_write_reg(uint8_t cmd, uint32_t value, uint32_t ap_delay_clk) -{ - assert(!(cmd & SWD_CMD_RnW)); - jlink_swd_queue_cmd(cmd, NULL, value, ap_delay_clk); -} - -static void jlink_swd_read_reg(uint8_t cmd, uint32_t *value, uint32_t ap_delay_clk) -{ - assert(cmd & SWD_CMD_RnW); - jlink_swd_queue_cmd(cmd, value, 0, ap_delay_clk); -} - -static int_least32_t jlink_swd_frequency(int_least32_t hz) -{ - if (hz > 0) - jlink_speed(hz / 1000); - - return hz; -} - -/***************************************************************************/ -/* J-Link tap functions */ - -static unsigned tap_length; -/* In SWD mode use tms buffer for direction control */ -static uint8_t tms_buffer[JLINK_TAP_BUFFER_SIZE]; -static uint8_t tdi_buffer[JLINK_TAP_BUFFER_SIZE]; -static uint8_t tdo_buffer[JLINK_TAP_BUFFER_SIZE]; - -struct pending_scan_result { - /** 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 - -static int pending_scan_results_length; -static struct pending_scan_result pending_scan_results_buffer[MAX_PENDING_SCAN_RESULTS]; - -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_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) -{ - 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; - } - - struct pending_scan_result *pending_scan_result = - &pending_scan_results_buffer[pending_scan_results_length]; - - unsigned scan_length = length > available_length ? - available_length : length; - - 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); - - 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++; - } - - tap_length += scan_length; - out_offset += scan_length; - tms_offset += scan_length; - in_offset += scan_length; - length -= scan_length; - } while (length > 0); -} - -static int jlink_flush(void) -{ - int i; - int ret; - - if (!tap_length) - return ERROR_OK; - - 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); - - if (ret != JAYLINK_OK) { - LOG_ERROR("jaylink_jtag_io() failed: %s.", jaylink_strerror_name(ret)); - jlink_tap_init(); - return ERROR_JTAG_QUEUE_FAILED; - } - - for (i = 0; i < pending_scan_results_length; i++) { - struct pending_scan_result *p = &pending_scan_results_buffer[i]; - - buf_set_buf(tdo_buffer, p->first, p->buffer, - p->buffer_offset, p->length); - - DEBUG_JTAG_IO("Pending scan result, length = %d.", p->length); - } - - jlink_tap_init(); - - return ERROR_OK; -} - -static void fill_buffer(uint8_t *buf, uint32_t val, uint32_t len) -{ - unsigned int tap_pos = tap_length; - - while (len > 32) { - buf_set_u32(buf, tap_pos, 32, val); - len -= 32; - tap_pos += 32; - } - - if (len) - buf_set_u32(buf, tap_pos, len, val); -} - -static void jlink_queue_data_out(const uint8_t *data, uint32_t len) -{ - const uint32_t dir_out = 0xffffffff; - - if (data) - bit_copy(tdi_buffer, tap_length, data, 0, len); - else - fill_buffer(tdi_buffer, 0, len); - - fill_buffer(tms_buffer, dir_out, len); - tap_length += len; -} - -static void jlink_queue_data_in(uint32_t len) -{ - const uint32_t dir_in = 0; - - fill_buffer(tms_buffer, dir_in, len); - tap_length += len; -} - -static int jlink_swd_switch_seq(enum swd_special_seq seq) -{ - const uint8_t *s; - unsigned int s_len; - - switch (seq) { - case LINE_RESET: - LOG_DEBUG("SWD line reset"); - s = swd_seq_line_reset; - s_len = swd_seq_line_reset_len; - break; - case JTAG_TO_SWD: - LOG_DEBUG("JTAG-to-SWD"); - s = swd_seq_jtag_to_swd; - s_len = swd_seq_jtag_to_swd_len; - break; - case SWD_TO_JTAG: - LOG_DEBUG("SWD-to-JTAG"); - s = swd_seq_swd_to_jtag; - s_len = swd_seq_swd_to_jtag_len; - break; - default: - LOG_ERROR("Sequence %d not supported.", seq); - return ERROR_FAIL; - } - - jlink_queue_data_out(s, s_len); - - return ERROR_OK; -} - -static int jlink_swd_run_queue(void) -{ - int i; - int ret; - - LOG_DEBUG("Executing %d queued transactions.", pending_scan_results_length); - - if (queued_retval != ERROR_OK) { - LOG_DEBUG("Skipping due to previous errors: %d.", queued_retval); - goto skip; - } - - /* - * A transaction must be followed by another transaction or at least 8 idle - * cycles to ensure that data is clocked through the AP. - */ - jlink_queue_data_out(NULL, 8); - - ret = jaylink_swd_io(devh, tms_buffer, tdi_buffer, tdo_buffer, tap_length); - - if (ret != JAYLINK_OK) { - LOG_ERROR("jaylink_swd_io() failed: %s.", jaylink_strerror_name(ret)); - goto skip; - } - - for (i = 0; i < pending_scan_results_length; i++) { - int ack = buf_get_u32(tdo_buffer, pending_scan_results_buffer[i].first, 3); - - if (ack != SWD_ACK_OK) { - LOG_DEBUG("SWD ack not OK: %d %s", ack, - ack == SWD_ACK_WAIT ? "WAIT" : ack == SWD_ACK_FAULT ? "FAULT" : "JUNK"); - queued_retval = ack == SWD_ACK_WAIT ? ERROR_WAIT : ERROR_FAIL; - goto skip; - } else if (pending_scan_results_buffer[i].length) { - uint32_t data = buf_get_u32(tdo_buffer, 3 + pending_scan_results_buffer[i].first, 32); - int parity = buf_get_u32(tdo_buffer, 3 + 32 + pending_scan_results_buffer[i].first, 1); - - if (parity != parity_u32(data)) { - LOG_ERROR("SWD: Read data parity mismatch."); - queued_retval = ERROR_FAIL; - goto skip; - } - - if (pending_scan_results_buffer[i].buffer) - *(uint32_t *)pending_scan_results_buffer[i].buffer = data; - } - } - -skip: - jlink_tap_init(); - ret = queued_retval; - queued_retval = ERROR_OK; - - return ret; -} - -static void jlink_swd_queue_cmd(uint8_t cmd, uint32_t *dst, uint32_t data, uint32_t ap_delay_clk) -{ - uint8_t data_parity_trn[DIV_ROUND_UP(32 + 1, 8)]; - if (tap_length + 46 + 8 + ap_delay_clk >= sizeof(tdi_buffer) * 8 || - pending_scan_results_length == MAX_PENDING_SCAN_RESULTS) { - /* Not enough room in the queue. Run the queue. */ - queued_retval = jlink_swd_run_queue(); - } - - if (queued_retval != ERROR_OK) - return; - - cmd |= SWD_CMD_START | SWD_CMD_PARK; - - jlink_queue_data_out(&cmd, 8); - - pending_scan_results_buffer[pending_scan_results_length].first = tap_length; - - if (cmd & SWD_CMD_RnW) { - /* Queue a read transaction. */ - pending_scan_results_buffer[pending_scan_results_length].length = 32; - pending_scan_results_buffer[pending_scan_results_length].buffer = dst; - - jlink_queue_data_in(1 + 3 + 32 + 1 + 1); - } else { - /* Queue a write transaction. */ - pending_scan_results_buffer[pending_scan_results_length].length = 0; - jlink_queue_data_in(1 + 3 + 1); - - buf_set_u32(data_parity_trn, 0, 32, data); - buf_set_u32(data_parity_trn, 32, 1, parity_u32(data)); - - jlink_queue_data_out(data_parity_trn, 32 + 1); - } - - pending_scan_results_length++; - - /* Insert idle cycles after AP accesses to avoid WAIT. */ - if (cmd & SWD_CMD_APnDP) - jlink_queue_data_out(NULL, ap_delay_clk); -} - -static const struct swd_driver jlink_swd = { - .init = &jlink_swd_init, - .frequency = &jlink_swd_frequency, - .switch_seq = &jlink_swd_switch_seq, - .read_reg = &jlink_swd_read_reg, - .write_reg = &jlink_swd_write_reg, - .run = &jlink_swd_run_queue, -}; - -static const char * const jlink_transports[] = { "jtag", "swd", NULL }; - -struct jtag_interface jlink_interface = { - .name = "jlink", - .commands = jlink_command_handlers, - .transports = jlink_transports, - .swd = &jlink_swd, - .execute_queue = &jlink_execute_queue, - .speed = &jlink_speed, - .speed_div = &jlink_speed_div, - .khz = &jlink_khz, - .init = &jlink_init, - .quit = &jlink_quit, - .config_trace = &config_trace, - .poll_trace = &poll_trace, -}; diff --git a/src/jtag/drivers/jtag_vpi.c b/src/jtag/drivers/jtag_vpi.c deleted file mode 100644 index 1b0fcbac5..000000000 --- a/src/jtag/drivers/jtag_vpi.c +++ /dev/null @@ -1,466 +0,0 @@ -/* - * JTAG to VPI driver - * - * Copyright (C) 2013 Franck Jullien, - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#ifdef HAVE_ARPA_INET_H -#include -#endif - -#define NO_TAP_SHIFT 0 -#define TAP_SHIFT 1 - -#define SERVER_ADDRESS "127.0.0.1" -#define SERVER_PORT 5555 - -#define XFERT_MAX_SIZE 512 - -#define CMD_RESET 0 -#define CMD_TMS_SEQ 1 -#define CMD_SCAN_CHAIN 2 -#define CMD_SCAN_CHAIN_FLIP_TMS 3 -#define CMD_STOP_SIMU 4 - -int server_port = SERVER_PORT; -char *server_address; - -int sockfd; -struct sockaddr_in serv_addr; - -struct vpi_cmd { - int cmd; - unsigned char buffer_out[XFERT_MAX_SIZE]; - unsigned char buffer_in[XFERT_MAX_SIZE]; - int length; - int nb_bits; -}; - -static int jtag_vpi_send_cmd(struct vpi_cmd *vpi) -{ - int retval = write_socket(sockfd, vpi, sizeof(struct vpi_cmd)); - if (retval <= 0) - return ERROR_FAIL; - - return ERROR_OK; -} - -static int jtag_vpi_receive_cmd(struct vpi_cmd *vpi) -{ - int retval = read_socket(sockfd, vpi, sizeof(struct vpi_cmd)); - if (retval < (int)sizeof(struct vpi_cmd)) - return ERROR_FAIL; - - return ERROR_OK; -} - -/** - * jtag_vpi_reset - ask to reset the JTAG device - * @trst: 1 if TRST is to be asserted - * @srst: 1 if SRST is to be asserted - */ -static int jtag_vpi_reset(int trst, int srst) -{ - struct vpi_cmd vpi; - - vpi.cmd = CMD_RESET; - vpi.length = 0; - return jtag_vpi_send_cmd(&vpi); -} - -/** - * jtag_vpi_tms_seq - ask a TMS sequence transition to JTAG - * @bits: TMS bits to be written (bit0, bit1 .. bitN) - * @nb_bits: number of TMS bits (between 1 and 8) - * - * Write a serie of TMS transitions, where each transition consists in : - * - writing out TCK=0, TMS=, TDI= - * - writing out TCK=1, TMS=, TDI= which triggers the transition - * The function ensures that at the end of the sequence, the clock (TCK) is put - * low. - */ -static int jtag_vpi_tms_seq(const uint8_t *bits, int nb_bits) -{ - struct vpi_cmd vpi; - int nb_bytes; - - nb_bytes = DIV_ROUND_UP(nb_bits, 8); - - vpi.cmd = CMD_TMS_SEQ; - memcpy(vpi.buffer_out, bits, nb_bytes); - vpi.length = nb_bytes; - vpi.nb_bits = nb_bits; - - return jtag_vpi_send_cmd(&vpi); -} - -/** - * jtag_vpi_path_move - ask a TMS sequence transition to JTAG - * @cmd: path transition - * - * Write a serie of TMS transitions, where each transition consists in : - * - writing out TCK=0, TMS=, TDI= - * - writing out TCK=1, TMS=, TDI= which triggers the transition - * The function ensures that at the end of the sequence, the clock (TCK) is put - * low. - */ - -static int jtag_vpi_path_move(struct pathmove_command *cmd) -{ - uint8_t trans[DIV_ROUND_UP(cmd->num_states, 8)]; - - memset(trans, 0, DIV_ROUND_UP(cmd->num_states, 8)); - - for (int i = 0; i < cmd->num_states; i++) { - if (tap_state_transition(tap_get_state(), true) == cmd->path[i]) - buf_set_u32(trans, i, 1, 1); - tap_set_state(cmd->path[i]); - } - - return jtag_vpi_tms_seq(trans, cmd->num_states); -} - -/** - * jtag_vpi_tms - ask a tms command - * @cmd: tms command - */ -static int jtag_vpi_tms(struct tms_command *cmd) -{ - return jtag_vpi_tms_seq(cmd->bits, cmd->num_bits); -} - -static int jtag_vpi_state_move(tap_state_t state) -{ - if (tap_get_state() == state) - return ERROR_OK; - - uint8_t tms_scan = tap_get_tms_path(tap_get_state(), state); - int tms_len = tap_get_tms_path_len(tap_get_state(), state); - - int retval = jtag_vpi_tms_seq(&tms_scan, tms_len); - if (retval != ERROR_OK) - return retval; - - tap_set_state(state); - - return ERROR_OK; -} - -static int jtag_vpi_queue_tdi_xfer(uint8_t *bits, int nb_bits, int tap_shift) -{ - struct vpi_cmd vpi; - int nb_bytes = DIV_ROUND_UP(nb_bits, 8); - - vpi.cmd = tap_shift ? CMD_SCAN_CHAIN_FLIP_TMS : CMD_SCAN_CHAIN; - - if (bits) - memcpy(vpi.buffer_out, bits, nb_bytes); - else - memset(vpi.buffer_out, 0xff, nb_bytes); - - vpi.length = nb_bytes; - vpi.nb_bits = nb_bits; - - int retval = jtag_vpi_send_cmd(&vpi); - if (retval != ERROR_OK) - return retval; - - retval = jtag_vpi_receive_cmd(&vpi); - if (retval != ERROR_OK) - return retval; - - if (bits) - memcpy(bits, vpi.buffer_in, nb_bytes); - - return ERROR_OK; -} - -/** - * jtag_vpi_queue_tdi - short description - * @bits: bits to be queued on TDI (or NULL if 0 are to be queued) - * @nb_bits: number of bits - */ -static int jtag_vpi_queue_tdi(uint8_t *bits, int nb_bits, int tap_shift) -{ - int nb_xfer = DIV_ROUND_UP(nb_bits, XFERT_MAX_SIZE * 8); - uint8_t *xmit_buffer = bits; - int xmit_nb_bits = nb_bits; - int i = 0; - int retval; - - while (nb_xfer) { - - if (nb_xfer == 1) { - retval = jtag_vpi_queue_tdi_xfer(&xmit_buffer[i], xmit_nb_bits, tap_shift); - if (retval != ERROR_OK) - return retval; - } else { - retval = jtag_vpi_queue_tdi_xfer(&xmit_buffer[i], XFERT_MAX_SIZE * 8, NO_TAP_SHIFT); - if (retval != ERROR_OK) - return retval; - xmit_nb_bits -= XFERT_MAX_SIZE * 8; - i += XFERT_MAX_SIZE; - } - - nb_xfer--; - } - - return ERROR_OK; -} - -/** - * jtag_vpi_clock_tms - clock a TMS transition - * @tms: the TMS to be sent - * - * Triggers a TMS transition (ie. one JTAG TAP state move). - */ -static int jtag_vpi_clock_tms(int tms) -{ - const uint8_t tms_0 = 0; - const uint8_t tms_1 = 1; - - return jtag_vpi_tms_seq(tms ? &tms_1 : &tms_0, 1); -} - -/** - * jtag_vpi_scan - launches a DR-scan or IR-scan - * @cmd: the command to launch - * - * Launch a JTAG IR-scan or DR-scan - * - * Returns ERROR_OK if OK, ERROR_xxx if a read/write error occured. - */ -static int jtag_vpi_scan(struct scan_command *cmd) -{ - int scan_bits; - uint8_t *buf = NULL; - int retval = ERROR_OK; - - scan_bits = jtag_build_buffer(cmd, &buf); - - if (cmd->ir_scan) { - retval = jtag_vpi_state_move(TAP_IRSHIFT); - if (retval != ERROR_OK) - return retval; - } else { - retval = jtag_vpi_state_move(TAP_DRSHIFT); - if (retval != ERROR_OK) - return retval; - } - - if (cmd->end_state == TAP_DRSHIFT) { - retval = jtag_vpi_queue_tdi(buf, scan_bits, NO_TAP_SHIFT); - if (retval != ERROR_OK) - return retval; - } else { - retval = jtag_vpi_queue_tdi(buf, scan_bits, TAP_SHIFT); - if (retval != ERROR_OK) - return retval; - } - - if (cmd->end_state != TAP_DRSHIFT) { - /* - * As our JTAG is in an unstable state (IREXIT1 or DREXIT1), move it - * forward to a stable IRPAUSE or DRPAUSE. - */ - retval = jtag_vpi_clock_tms(0); - if (retval != ERROR_OK) - return retval; - - if (cmd->ir_scan) - tap_set_state(TAP_IRPAUSE); - else - tap_set_state(TAP_DRPAUSE); - } - - retval = jtag_read_buffer(buf, cmd); - if (retval != ERROR_OK) - return retval; - - if (buf) - free(buf); - - if (cmd->end_state != TAP_DRSHIFT) { - retval = jtag_vpi_state_move(cmd->end_state); - if (retval != ERROR_OK) - return retval; - } - - return ERROR_OK; -} - -static int jtag_vpi_runtest(int cycles, tap_state_t state) -{ - int retval; - - retval = jtag_vpi_state_move(TAP_IDLE); - if (retval != ERROR_OK) - return retval; - - retval = jtag_vpi_queue_tdi(NULL, cycles, NO_TAP_SHIFT); - if (retval != ERROR_OK) - return retval; - - return jtag_vpi_state_move(state); -} - -static int jtag_vpi_stableclocks(int cycles) -{ - return jtag_vpi_queue_tdi(NULL, cycles, TAP_SHIFT); -} - -static int jtag_vpi_execute_queue(void) -{ - struct jtag_command *cmd; - int retval = ERROR_OK; - - for (cmd = jtag_command_queue; retval == ERROR_OK && cmd != NULL; - cmd = cmd->next) { - switch (cmd->type) { - case JTAG_RESET: - retval = jtag_vpi_reset(cmd->cmd.reset->trst, cmd->cmd.reset->srst); - break; - case JTAG_RUNTEST: - retval = jtag_vpi_runtest(cmd->cmd.runtest->num_cycles, - cmd->cmd.runtest->end_state); - break; - case JTAG_STABLECLOCKS: - retval = jtag_vpi_stableclocks(cmd->cmd.stableclocks->num_cycles); - break; - case JTAG_TLR_RESET: - retval = jtag_vpi_state_move(cmd->cmd.statemove->end_state); - break; - case JTAG_PATHMOVE: - retval = jtag_vpi_path_move(cmd->cmd.pathmove); - break; - case JTAG_TMS: - retval = jtag_vpi_tms(cmd->cmd.tms); - break; - case JTAG_SLEEP: - jtag_sleep(cmd->cmd.sleep->us); - break; - case JTAG_SCAN: - retval = jtag_vpi_scan(cmd->cmd.scan); - break; - } - } - - return retval; -} - -static int jtag_vpi_init(void) -{ - sockfd = socket(AF_INET, SOCK_STREAM, 0); - if (sockfd < 0) { - LOG_ERROR("Could not create socket"); - return ERROR_FAIL; - } - - memset(&serv_addr, 0, sizeof(serv_addr)); - - serv_addr.sin_family = AF_INET; - serv_addr.sin_port = htons(server_port); - - if (!server_address) - server_address = strdup(SERVER_ADDRESS); - - serv_addr.sin_addr.s_addr = inet_addr(server_address); - - if (serv_addr.sin_addr.s_addr == INADDR_NONE) { - LOG_ERROR("inet_addr error occured"); - return ERROR_FAIL; - } - - if (connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) { - close(sockfd); - LOG_ERROR("Can't connect to %s : %u", server_address, server_port); - return ERROR_COMMAND_CLOSE_CONNECTION; - } - - LOG_INFO("Connection to %s : %u succeed", server_address, server_port); - - return ERROR_OK; -} - -static int jtag_vpi_quit(void) -{ - free(server_address); - return close(sockfd); -} - -COMMAND_HANDLER(jtag_vpi_set_port) -{ - if (CMD_ARGC == 0) - LOG_WARNING("You need to set a port number"); - else - COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], server_port); - - LOG_INFO("Set server port to %u", server_port); - - return ERROR_OK; -} - -COMMAND_HANDLER(jtag_vpi_set_address) -{ - free(server_address); - - if (CMD_ARGC == 0) { - LOG_WARNING("You need to set an address"); - server_address = strdup(SERVER_ADDRESS); - } else - server_address = strdup(CMD_ARGV[0]); - - LOG_INFO("Set server address to %s", server_address); - - return ERROR_OK; -} - -static const struct command_registration jtag_vpi_command_handlers[] = { - { - .name = "jtag_vpi_set_port", - .handler = &jtag_vpi_set_port, - .mode = COMMAND_CONFIG, - .help = "set the port of the VPI server", - .usage = "description_string", - }, - { - .name = "jtag_vpi_set_address", - .handler = &jtag_vpi_set_address, - .mode = COMMAND_CONFIG, - .help = "set the address of the VPI server", - .usage = "description_string", - }, - COMMAND_REGISTRATION_DONE -}; - -struct jtag_interface jtag_vpi_interface = { - .name = "jtag_vpi", - .supported = DEBUG_CAP_TMS_SEQ, - .commands = jtag_vpi_command_handlers, - .transports = jtag_only, - - .init = jtag_vpi_init, - .quit = jtag_vpi_quit, - .execute_queue = jtag_vpi_execute_queue, -}; diff --git a/src/jtag/drivers/libjaylink b/src/jtag/drivers/libjaylink deleted file mode 160000 index d57dee67b..000000000 --- a/src/jtag/drivers/libjaylink +++ /dev/null @@ -1 +0,0 @@ -Subproject commit d57dee67bc756291b7d8b51d350d1c6213e514f0 diff --git a/src/jtag/drivers/libusb0_common.c b/src/jtag/drivers/libusb0_common.c deleted file mode 100644 index e319751a3..000000000 --- a/src/jtag/drivers/libusb0_common.c +++ /dev/null @@ -1,188 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2009 by Zachary T Welch * - * * - * Copyright (C) 2011 by Mauro Gamba * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 -#include "config.h" -#endif -#include "log.h" -#include "libusb0_common.h" - -static bool jtag_libusb_match(struct jtag_libusb_device *dev, - const uint16_t vids[], const uint16_t pids[]) -{ - for (unsigned i = 0; vids[i]; i++) { - if (dev->descriptor.idVendor == vids[i] && - dev->descriptor.idProduct == pids[i]) { - return true; - } - } - return false; -} - -/* Returns true if the string descriptor indexed by str_index in device matches string */ -static bool string_descriptor_equal(usb_dev_handle *device, uint8_t str_index, - const char *string) -{ - int retval; - bool matched; - char desc_string[256+1]; /* Max size of string descriptor */ - - if (str_index == 0) - return false; - - retval = usb_get_string_simple(device, str_index, - desc_string, sizeof(desc_string)-1); - if (retval < 0) { - LOG_ERROR("usb_get_string_simple() failed with %d", retval); - return false; - } - - /* Null terminate descriptor string in case it needs to be logged. */ - desc_string[sizeof(desc_string)-1] = '\0'; - - matched = strncmp(string, desc_string, sizeof(desc_string)) == 0; - if (!matched) - LOG_DEBUG("Device serial number '%s' doesn't match requested serial '%s'", - desc_string, string); - return matched; -} - -int jtag_libusb_open(const uint16_t vids[], const uint16_t pids[], - const char *serial, - struct jtag_libusb_device_handle **out) -{ - int retval = -ENODEV; - struct jtag_libusb_device_handle *libusb_handle; - usb_init(); - - usb_find_busses(); - usb_find_devices(); - - struct usb_bus *busses = usb_get_busses(); - for (struct usb_bus *bus = busses; bus; bus = bus->next) { - for (struct usb_device *dev = bus->devices; - dev; dev = dev->next) { - if (!jtag_libusb_match(dev, vids, pids)) - continue; - - libusb_handle = usb_open(dev); - if (NULL == libusb_handle) { - retval = -errno; - continue; - } - - /* Device must be open to use libusb_get_string_descriptor_ascii. */ - if (serial != NULL && - !string_descriptor_equal(libusb_handle, dev->descriptor.iSerialNumber, serial)) { - usb_close(libusb_handle); - continue; - } - *out = libusb_handle; - retval = 0; - break; - } - } - return retval; -} - -void jtag_libusb_close(jtag_libusb_device_handle *dev) -{ - /* Close device */ - usb_close(dev); -} - -int jtag_libusb_control_transfer(jtag_libusb_device_handle *dev, uint8_t requestType, - uint8_t request, uint16_t wValue, uint16_t wIndex, char *bytes, - uint16_t size, unsigned int timeout) -{ - int transferred = 0; - - transferred = usb_control_msg(dev, requestType, request, wValue, wIndex, - bytes, size, timeout); - - if (transferred < 0) - transferred = 0; - - return transferred; -} - -int jtag_libusb_bulk_write(jtag_libusb_device_handle *dev, int ep, char *bytes, - int size, int timeout) -{ - return usb_bulk_write(dev, ep, bytes, size, timeout); -} - -int jtag_libusb_bulk_read(jtag_libusb_device_handle *dev, int ep, char *bytes, - int size, int timeout) -{ - return usb_bulk_read(dev, ep, bytes, size, timeout); -} - -int jtag_libusb_set_configuration(jtag_libusb_device_handle *devh, - int configuration) -{ - struct jtag_libusb_device *udev = jtag_libusb_get_device(devh); - - return usb_set_configuration(devh, - udev->config[configuration].bConfigurationValue); -} - -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) -{ - struct jtag_libusb_device *udev = jtag_libusb_get_device(devh); - struct usb_interface *iface = udev->config->interface; - struct usb_interface_descriptor *desc = iface->altsetting; - - *usb_read_ep = *usb_write_ep = 0; - - for (int i = 0; i < desc->bNumEndpoints; i++) { - if ((bclass > 0 && desc->bInterfaceClass != bclass) || - (subclass > 0 && desc->bInterfaceSubClass != subclass) || - (protocol > 0 && desc->bInterfaceProtocol != protocol)) - continue; - - uint8_t epnum = desc->endpoint[i].bEndpointAddress; - bool is_input = epnum & 0x80; - LOG_DEBUG("usb ep %s %02x", is_input ? "in" : "out", epnum); - if (is_input) - *usb_read_ep = epnum; - else - *usb_write_ep = epnum; - - if (*usb_read_ep && *usb_write_ep) { - LOG_DEBUG("Claiming interface %d", (int)desc->bInterfaceNumber); - usb_claim_interface(devh, (int)desc->bInterfaceNumber); - return ERROR_OK; - } - } - - return ERROR_FAIL; -} - -int jtag_libusb_get_pid(struct jtag_libusb_device *dev, uint16_t *pid) -{ - if (!dev) - return ERROR_FAIL; - - *pid = dev->descriptor.idProduct; - return ERROR_OK; -} diff --git a/src/jtag/drivers/libusb0_common.h b/src/jtag/drivers/libusb0_common.h deleted file mode 100644 index 7163b4314..000000000 --- a/src/jtag/drivers/libusb0_common.h +++ /dev/null @@ -1,73 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2009 by Zachary T Welch * - * * - * Copyright (C) 2011 by Mauro Gamba * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 OPENOCD_JTAG_DRIVERS_LIBUSB0_COMMON_H -#define OPENOCD_JTAG_DRIVERS_LIBUSB0_COMMON_H - -#include - -#define jtag_libusb_device usb_device -#define jtag_libusb_device_handle usb_dev_handle -#define jtag_libusb_device_descriptor usb_device_descriptor -#define jtag_libusb_interface usb_interface -#define jtag_libusb_interface_descriptor usb_interface_descriptor -#define jtag_libusb_endpoint_descriptor usb_endpoint_descriptor -#define jtag_libusb_config_descriptor usb_config_descriptor - -#define jtag_libusb_reset_device(dev) usb_reset(dev) -#define jtag_libusb_get_device(devh) usb_device(devh) - -/* make some defines compatible to libusb1 */ -#define LIBUSB_REQUEST_TYPE_VENDOR USB_TYPE_VENDOR -#define LIBUSB_RECIPIENT_DEVICE USB_RECIP_DEVICE -#define LIBUSB_ENDPOINT_OUT USB_ENDPOINT_OUT -#define LIBUSB_ENDPOINT_IN USB_ENDPOINT_IN - -static inline int jtag_libusb_claim_interface(jtag_libusb_device_handle *devh, - int iface) -{ - return usb_claim_interface(devh, iface); -}; - -static inline int jtag_libusb_release_interface(jtag_libusb_device_handle *devh, - int iface) -{ - return usb_release_interface(devh, iface); -} - -int jtag_libusb_open(const uint16_t vids[], const uint16_t pids[], - const char *serial, - struct jtag_libusb_device_handle **out); -void jtag_libusb_close(jtag_libusb_device_handle *dev); -int jtag_libusb_control_transfer(jtag_libusb_device_handle *dev, - uint8_t requestType, uint8_t request, uint16_t wValue, - uint16_t wIndex, char *bytes, uint16_t size, unsigned int timeout); -int jtag_libusb_bulk_write(struct jtag_libusb_device_handle *dev, int ep, - char *bytes, int size, int timeout); -int jtag_libusb_bulk_read(struct jtag_libusb_device_handle *dev, int ep, - char *bytes, int size, int timeout); -int jtag_libusb_set_configuration(jtag_libusb_device_handle *devh, - int configuration); -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 jtag_libusb_get_pid(struct jtag_libusb_device *dev, uint16_t *pid); - -#endif /* OPENOCD_JTAG_DRIVERS_LIBUSB0_COMMON_H */ diff --git a/src/jtag/drivers/libusb1_common.c b/src/jtag/drivers/libusb1_common.c deleted file mode 100644 index f8b7c754c..000000000 --- a/src/jtag/drivers/libusb1_common.c +++ /dev/null @@ -1,248 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2009 by Zachary T Welch * - * * - * Copyright (C) 2011 by Mauro Gamba * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 -#include "config.h" -#endif -#include "log.h" -#include "libusb1_common.h" - -static struct libusb_context *jtag_libusb_context; /**< Libusb context **/ -static libusb_device **devs; /**< The usb device list **/ - -static bool jtag_libusb_match(struct libusb_device_descriptor *dev_desc, - const uint16_t vids[], const uint16_t pids[]) -{ - for (unsigned i = 0; vids[i]; i++) { - if (dev_desc->idVendor == vids[i] && - dev_desc->idProduct == pids[i]) { - return true; - } - } - return false; -} - -/* Returns true if the string descriptor indexed by str_index in device matches string */ -static bool string_descriptor_equal(libusb_device_handle *device, uint8_t str_index, - const char *string) -{ - int retval; - bool matched; - char desc_string[256+1]; /* Max size of string descriptor */ - - if (str_index == 0) - return false; - - retval = libusb_get_string_descriptor_ascii(device, str_index, - (unsigned char *)desc_string, sizeof(desc_string)-1); - if (retval < 0) { - LOG_ERROR("libusb_get_string_descriptor_ascii() failed with %d", retval); - return false; - } - - /* Null terminate descriptor string in case it needs to be logged. */ - desc_string[sizeof(desc_string)-1] = '\0'; - - matched = strncmp(string, desc_string, sizeof(desc_string)) == 0; - if (!matched) - LOG_DEBUG("Device serial number '%s' doesn't match requested serial '%s'", - desc_string, string); - return matched; -} - -int jtag_libusb_open(const uint16_t vids[], const uint16_t pids[], - const char *serial, - struct jtag_libusb_device_handle **out) -{ - int cnt, idx, errCode; - int retval = -ENODEV; - struct jtag_libusb_device_handle *libusb_handle = NULL; - - if (libusb_init(&jtag_libusb_context) < 0) - return -ENODEV; - - cnt = libusb_get_device_list(jtag_libusb_context, &devs); - - for (idx = 0; idx < cnt; idx++) { - struct libusb_device_descriptor dev_desc; - - if (libusb_get_device_descriptor(devs[idx], &dev_desc) != 0) - continue; - - if (!jtag_libusb_match(&dev_desc, vids, pids)) - continue; - - errCode = libusb_open(devs[idx], &libusb_handle); - - if (errCode) { - LOG_ERROR("libusb_open() failed with %s", - libusb_error_name(errCode)); - continue; - } - - /* Device must be open to use libusb_get_string_descriptor_ascii. */ - if (serial != NULL && - !string_descriptor_equal(libusb_handle, dev_desc.iSerialNumber, serial)) { - libusb_close(libusb_handle); - continue; - } - - /* Success. */ - *out = libusb_handle; - retval = 0; - break; - } - if (cnt >= 0) - libusb_free_device_list(devs, 1); - return retval; -} - -void jtag_libusb_close(jtag_libusb_device_handle *dev) -{ - /* Close device */ - libusb_close(dev); - - libusb_exit(jtag_libusb_context); -} - -int jtag_libusb_control_transfer(jtag_libusb_device_handle *dev, uint8_t requestType, - uint8_t request, uint16_t wValue, uint16_t wIndex, char *bytes, - uint16_t size, unsigned int timeout) -{ - int transferred = 0; - - transferred = libusb_control_transfer(dev, requestType, request, wValue, wIndex, - (unsigned char *)bytes, size, timeout); - - if (transferred < 0) - transferred = 0; - - return transferred; -} - -int jtag_libusb_bulk_write(jtag_libusb_device_handle *dev, int ep, char *bytes, - int size, int timeout) -{ - int transferred = 0; - - libusb_bulk_transfer(dev, ep, (unsigned char *)bytes, size, - &transferred, timeout); - return transferred; -} - -int jtag_libusb_bulk_read(jtag_libusb_device_handle *dev, int ep, char *bytes, - int size, int timeout) -{ - int transferred = 0; - - libusb_bulk_transfer(dev, ep, (unsigned char *)bytes, size, - &transferred, timeout); - return transferred; -} - -int jtag_libusb_set_configuration(jtag_libusb_device_handle *devh, - int configuration) -{ - struct jtag_libusb_device *udev = jtag_libusb_get_device(devh); - int retCode = -99; - - struct libusb_config_descriptor *config = NULL; - int current_config = -1; - - retCode = libusb_get_configuration(devh, ¤t_config); - if (retCode != 0) - return retCode; - - retCode = libusb_get_config_descriptor(udev, configuration, &config); - if (retCode != 0 || config == NULL) - return retCode; - - /* Only change the configuration if it is not already set to the - same one. Otherwise this issues a lightweight reset and hangs - LPC-Link2 with JLink firmware. */ - if (current_config != config->bConfigurationValue) - retCode = libusb_set_configuration(devh, config->bConfigurationValue); - - libusb_free_config_descriptor(config); - - return retCode; -} - -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) -{ - struct jtag_libusb_device *udev = jtag_libusb_get_device(devh); - const struct libusb_interface *inter; - const struct libusb_interface_descriptor *interdesc; - const struct libusb_endpoint_descriptor *epdesc; - struct libusb_config_descriptor *config; - - *usb_read_ep = *usb_write_ep = 0; - - libusb_get_config_descriptor(udev, 0, &config); - for (int i = 0; i < (int)config->bNumInterfaces; i++) { - inter = &config->interface[i]; - - interdesc = &inter->altsetting[0]; - for (int k = 0; - k < (int)interdesc->bNumEndpoints; k++) { - if ((bclass > 0 && interdesc->bInterfaceClass != bclass) || - (subclass > 0 && interdesc->bInterfaceSubClass != subclass) || - (protocol > 0 && interdesc->bInterfaceProtocol != protocol)) - continue; - - epdesc = &interdesc->endpoint[k]; - - uint8_t epnum = epdesc->bEndpointAddress; - bool is_input = epnum & 0x80; - LOG_DEBUG("usb ep %s %02x", - is_input ? "in" : "out", epnum); - - if (is_input) - *usb_read_ep = epnum; - else - *usb_write_ep = epnum; - - if (*usb_read_ep && *usb_write_ep) { - LOG_DEBUG("Claiming interface %d", (int)interdesc->bInterfaceNumber); - libusb_claim_interface(devh, (int)interdesc->bInterfaceNumber); - libusb_free_config_descriptor(config); - return ERROR_OK; - } - } - } - libusb_free_config_descriptor(config); - - return ERROR_FAIL; -} - -int jtag_libusb_get_pid(struct jtag_libusb_device *dev, uint16_t *pid) -{ - struct libusb_device_descriptor dev_desc; - - if (libusb_get_device_descriptor(dev, &dev_desc) == 0) { - *pid = dev_desc.idProduct; - - return ERROR_OK; - } - - return ERROR_FAIL; -} diff --git a/src/jtag/drivers/libusb1_common.h b/src/jtag/drivers/libusb1_common.h deleted file mode 100644 index fc6526a30..000000000 --- a/src/jtag/drivers/libusb1_common.h +++ /dev/null @@ -1,80 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2009 by Zachary T Welch * - * * - * Copyright (C) 2011 by Mauro Gamba * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 OPENOCD_JTAG_DRIVERS_LIBUSB1_COMMON_H -#define OPENOCD_JTAG_DRIVERS_LIBUSB1_COMMON_H - -#include - -#define jtag_libusb_device libusb_device -#define jtag_libusb_device_handle libusb_device_handle -#define jtag_libusb_device_descriptor libusb_device_descriptor -#define jtag_libusb_interface libusb_interface -#define jtag_libusb_interface_descriptor libusb_interface_descriptor -#define jtag_libusb_endpoint_descriptor libusb_endpoint_descriptor -#define jtag_libusb_config_descriptor libusb_config_descriptor - -#define jtag_libusb_reset_device(dev) libusb_reset_device(dev) -#define jtag_libusb_get_device(devh) libusb_get_device(devh) - -static inline int jtag_libusb_claim_interface(jtag_libusb_device_handle *devh, - int iface) -{ - return libusb_claim_interface(devh, iface); -}; - -static inline int jtag_libusb_release_interface(jtag_libusb_device_handle *devh, - int iface) -{ - return libusb_release_interface(devh, iface); -} - -int jtag_libusb_open(const uint16_t vids[], const uint16_t pids[], - const char *serial, - struct jtag_libusb_device_handle **out); -void jtag_libusb_close(jtag_libusb_device_handle *dev); -int jtag_libusb_control_transfer(jtag_libusb_device_handle *dev, - uint8_t requestType, uint8_t request, uint16_t wValue, - uint16_t wIndex, char *bytes, uint16_t size, unsigned int timeout); -int jtag_libusb_bulk_write(struct jtag_libusb_device_handle *dev, int ep, - char *bytes, int size, int timeout); -int jtag_libusb_bulk_read(struct jtag_libusb_device_handle *dev, int ep, - char *bytes, int size, int timeout); -int jtag_libusb_set_configuration(jtag_libusb_device_handle *devh, - int configuration); -/** - * Find the first interface optionally matching class, subclass and - * protocol and claim it. - * @param devh _libusb_ device handle. - * @param usb_read_ep A pointer to a variable where the _IN_ endpoint - * number will be stored. - * @param usb_write_ep A pointer to a variable where the _OUT_ endpoint - * number will be stored. - * @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. - * @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 jtag_libusb_get_pid(struct jtag_libusb_device *dev, uint16_t *pid); - -#endif /* OPENOCD_JTAG_DRIVERS_LIBUSB1_COMMON_H */ diff --git a/src/jtag/drivers/libusb_common.h b/src/jtag/drivers/libusb_common.h deleted file mode 100644 index 563af10ed..000000000 --- a/src/jtag/drivers/libusb_common.h +++ /dev/null @@ -1,27 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2011 by Mauro Gamba * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 OPENOCD_JTAG_DRIVERS_LIBUSB_COMMON_H -#define OPENOCD_JTAG_DRIVERS_LIBUSB_COMMON_H - -#ifdef HAVE_LIBUSB1 -#include -#else -#include -#endif - -#endif /* OPENOCD_JTAG_DRIVERS_LIBUSB_COMMON_H */ diff --git a/src/jtag/drivers/minidriver_imp.h b/src/jtag/drivers/minidriver_imp.h deleted file mode 100644 index cd59a74fb..000000000 --- a/src/jtag/drivers/minidriver_imp.h +++ /dev/null @@ -1,41 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005 by Dominic Rath * - * Copyright (C) 2007-2009 Øyvind Harboe * - * Copyright (C) 2009 Zachary T Welch * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 OPENOCD_JTAG_DRIVERS_MINIDRIVER_IMP_H -#define OPENOCD_JTAG_DRIVERS_MINIDRIVER_IMP_H - -#include - -static inline void interface_jtag_add_scan_check_alloc(struct scan_field *field) -{ - unsigned num_bytes = DIV_ROUND_UP(field->num_bits, 8); - field->in_value = cmd_queue_alloc(num_bytes); -} - -void interface_jtag_add_callback(jtag_callback1_t f, jtag_callback_data_t data0); - -void interface_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); - -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 /* OPENOCD_JTAG_DRIVERS_MINIDRIVER_IMP_H */ diff --git a/src/jtag/drivers/mpsse.c b/src/jtag/drivers/mpsse.c deleted file mode 100644 index 0ef88ba2d..000000000 --- a/src/jtag/drivers/mpsse.c +++ /dev/null @@ -1,930 +0,0 @@ -/************************************************************************** - * Copyright (C) 2012 by Andreas Fritiofson * - * andreas.fritiofson@gmail.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "mpsse.h" -#include "helper/log.h" -#include - -/* Compatibility define for older libusb-1.0 */ -#ifndef LIBUSB_CALL -#define LIBUSB_CALL -#endif - -#ifdef _DEBUG_JTAG_IO_ -#define DEBUG_IO(expr...) LOG_DEBUG(expr) -#define DEBUG_PRINT_BUF(buf, len) \ - do { \ - char buf_string[32 * 3 + 1]; \ - int buf_string_pos = 0; \ - for (int i = 0; i < len; i++) { \ - buf_string_pos += sprintf(buf_string + buf_string_pos, " %02x", buf[i]); \ - if (i % 32 == 32 - 1) { \ - LOG_DEBUG("%s", buf_string); \ - buf_string_pos = 0; \ - } \ - } \ - if (buf_string_pos > 0) \ - LOG_DEBUG("%s", buf_string);\ - } while (0) -#else -#define DEBUG_IO(expr...) do {} while (0) -#define DEBUG_PRINT_BUF(buf, len) do {} while (0) -#endif - -#define FTDI_DEVICE_OUT_REQTYPE (LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE) -#define FTDI_DEVICE_IN_REQTYPE (0x80 | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE) - -#define BITMODE_MPSSE 0x02 - -#define SIO_RESET_REQUEST 0x00 -#define SIO_SET_LATENCY_TIMER_REQUEST 0x09 -#define SIO_GET_LATENCY_TIMER_REQUEST 0x0A -#define SIO_SET_BITMODE_REQUEST 0x0B - -#define SIO_RESET_SIO 0 -#define SIO_RESET_PURGE_RX 1 -#define SIO_RESET_PURGE_TX 2 - -struct mpsse_ctx { - libusb_context *usb_ctx; - libusb_device_handle *usb_dev; - unsigned int usb_write_timeout; - unsigned int usb_read_timeout; - uint8_t in_ep; - uint8_t out_ep; - uint16_t max_packet_size; - uint16_t index; - uint8_t interface; - enum ftdi_chip_type type; - uint8_t *write_buffer; - unsigned write_size; - unsigned write_count; - uint8_t *read_buffer; - unsigned read_size; - unsigned read_count; - uint8_t *read_chunk; - unsigned read_chunk_size; - struct bit_copy_queue read_queue; - int retval; -}; - -/* Returns true if the string descriptor indexed by str_index in device matches string */ -static bool string_descriptor_equal(libusb_device_handle *device, uint8_t str_index, - const char *string) -{ - int retval; - char desc_string[256]; /* Max size of string descriptor */ - retval = libusb_get_string_descriptor_ascii(device, str_index, (unsigned char *)desc_string, - sizeof(desc_string)); - if (retval < 0) { - LOG_ERROR("libusb_get_string_descriptor_ascii() failed with %s", libusb_error_name(retval)); - return false; - } - 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 *location) -{ - libusb_device **list; - struct libusb_device_descriptor desc; - struct libusb_config_descriptor *config0; - int err; - bool found = false; - ssize_t cnt = libusb_get_device_list(ctx->usb_ctx, &list); - if (cnt < 0) - LOG_ERROR("libusb_get_device_list() failed with %s", libusb_error_name(cnt)); - - for (ssize_t i = 0; i < cnt; i++) { - libusb_device *device = list[i]; - - err = libusb_get_device_descriptor(device, &desc); - if (err != LIBUSB_SUCCESS) { - LOG_ERROR("libusb_get_device_descriptor() failed with %s", libusb_error_name(err)); - continue; - } - - if (vid && *vid != desc.idVendor) - continue; - if (pid && *pid != desc.idProduct) - continue; - - err = libusb_open(device, &ctx->usb_dev); - if (err != LIBUSB_SUCCESS) { - LOG_ERROR("libusb_open() failed with %s", - libusb_error_name(err)); - 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; - } - - if (serial && !string_descriptor_equal(ctx->usb_dev, desc.iSerialNumber, serial)) { - libusb_close(ctx->usb_dev); - continue; - } - - found = true; - break; - } - - libusb_free_device_list(list, 1); - - if (!found) { - LOG_ERROR("no device found"); - return false; - } - - err = libusb_get_config_descriptor(libusb_get_device(ctx->usb_dev), 0, &config0); - if (err != LIBUSB_SUCCESS) { - LOG_ERROR("libusb_get_config_descriptor() failed with %s", libusb_error_name(err)); - libusb_close(ctx->usb_dev); - return false; - } - - /* Make sure the first configuration is selected */ - int cfg; - err = libusb_get_configuration(ctx->usb_dev, &cfg); - if (err != LIBUSB_SUCCESS) { - LOG_ERROR("libusb_get_configuration() failed with %s", libusb_error_name(err)); - goto error; - } - - if (desc.bNumConfigurations > 0 && cfg != config0->bConfigurationValue) { - err = libusb_set_configuration(ctx->usb_dev, config0->bConfigurationValue); - if (err != LIBUSB_SUCCESS) { - LOG_ERROR("libusb_set_configuration() failed with %s", libusb_error_name(err)); - goto error; - } - } - - /* Try to detach ftdi_sio kernel module */ - 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; - } - - err = libusb_claim_interface(ctx->usb_dev, ctx->interface); - if (err != LIBUSB_SUCCESS) { - LOG_ERROR("libusb_claim_interface() failed with %s", libusb_error_name(err)); - goto error; - } - - /* Reset FTDI device */ - err = libusb_control_transfer(ctx->usb_dev, FTDI_DEVICE_OUT_REQTYPE, - SIO_RESET_REQUEST, SIO_RESET_SIO, - ctx->index, NULL, 0, ctx->usb_write_timeout); - if (err < 0) { - LOG_ERROR("failed to reset FTDI device: %s", libusb_error_name(err)); - goto error; - } - - switch (desc.bcdDevice) { - case 0x500: - ctx->type = TYPE_FT2232C; - break; - case 0x700: - ctx->type = TYPE_FT2232H; - break; - case 0x800: - ctx->type = TYPE_FT4232H; - break; - case 0x900: - ctx->type = TYPE_FT232H; - break; - default: - LOG_ERROR("unsupported FTDI chip type: 0x%04x", desc.bcdDevice); - goto error; - } - - /* Determine maximum packet size and endpoint addresses */ - if (!(desc.bNumConfigurations > 0 && ctx->interface < config0->bNumInterfaces - && config0->interface[ctx->interface].num_altsetting > 0)) - goto desc_error; - - const struct libusb_interface_descriptor *descriptor; - descriptor = &config0->interface[ctx->interface].altsetting[0]; - if (descriptor->bNumEndpoints != 2) - goto desc_error; - - ctx->in_ep = 0; - ctx->out_ep = 0; - for (int i = 0; i < descriptor->bNumEndpoints; i++) { - if (descriptor->endpoint[i].bEndpointAddress & 0x80) { - ctx->in_ep = descriptor->endpoint[i].bEndpointAddress; - ctx->max_packet_size = - descriptor->endpoint[i].wMaxPacketSize; - } else { - ctx->out_ep = descriptor->endpoint[i].bEndpointAddress; - } - } - - if (ctx->in_ep == 0 || ctx->out_ep == 0) - goto desc_error; - - libusb_free_config_descriptor(config0); - return true; - -desc_error: - LOG_ERROR("unrecognized USB device descriptor"); -error: - libusb_free_config_descriptor(config0); - libusb_close(ctx->usb_dev); - return false; -} - -struct mpsse_ctx *mpsse_open(const uint16_t *vid, const uint16_t *pid, const char *description, - const char *serial, const char *location, int channel) -{ - struct mpsse_ctx *ctx = calloc(1, sizeof(*ctx)); - int err; - - if (!ctx) - return 0; - - bit_copy_queue_init(&ctx->read_queue); - ctx->read_chunk_size = 16384; - ctx->read_size = 16384; - ctx->write_size = 16384; - ctx->read_chunk = malloc(ctx->read_chunk_size); - ctx->read_buffer = malloc(ctx->read_size); - ctx->write_buffer = malloc(ctx->write_size); - if (!ctx->read_chunk || !ctx->read_buffer || !ctx->write_buffer) - goto error; - - ctx->interface = channel; - ctx->index = channel + 1; - ctx->usb_read_timeout = 5000; - ctx->usb_write_timeout = 5000; - - err = libusb_init(&ctx->usb_ctx); - if (err != LIBUSB_SUCCESS) { - LOG_ERROR("libusb_init() failed with %s", libusb_error_name(err)); - goto error; - } - - 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', " - "serial '%s' at bus location '%s'", - vid ? sprintf(vidstr, "%04x", *vid), vidstr : "*", - pid ? sprintf(pidstr, "%04x", *pid), pidstr : "*", - description ? description : "*", - serial ? serial : "*", - location ? location : "*"); - ctx->usb_dev = 0; - goto error; - } - - err = libusb_control_transfer(ctx->usb_dev, FTDI_DEVICE_OUT_REQTYPE, - SIO_SET_LATENCY_TIMER_REQUEST, 255, ctx->index, NULL, 0, - ctx->usb_write_timeout); - if (err < 0) { - LOG_ERROR("unable to set latency timer: %s", libusb_error_name(err)); - goto error; - } - - err = libusb_control_transfer(ctx->usb_dev, - FTDI_DEVICE_OUT_REQTYPE, - SIO_SET_BITMODE_REQUEST, - 0x0b | (BITMODE_MPSSE << 8), - ctx->index, - NULL, - 0, - ctx->usb_write_timeout); - if (err < 0) { - LOG_ERROR("unable to set MPSSE bitmode: %s", libusb_error_name(err)); - goto error; - } - - mpsse_purge(ctx); - - return ctx; -error: - mpsse_close(ctx); - return 0; -} - -void mpsse_close(struct mpsse_ctx *ctx) -{ - if (ctx->usb_dev) - libusb_close(ctx->usb_dev); - if (ctx->usb_ctx) - libusb_exit(ctx->usb_ctx); - bit_copy_discard(&ctx->read_queue); - if (ctx->write_buffer) - free(ctx->write_buffer); - if (ctx->read_buffer) - free(ctx->read_buffer); - if (ctx->read_chunk) - free(ctx->read_chunk); - - free(ctx); -} - -bool mpsse_is_high_speed(struct mpsse_ctx *ctx) -{ - return ctx->type != TYPE_FT2232C; -} - -void mpsse_purge(struct mpsse_ctx *ctx) -{ - int err; - LOG_DEBUG("-"); - ctx->write_count = 0; - ctx->read_count = 0; - ctx->retval = ERROR_OK; - bit_copy_discard(&ctx->read_queue); - err = libusb_control_transfer(ctx->usb_dev, FTDI_DEVICE_OUT_REQTYPE, SIO_RESET_REQUEST, - SIO_RESET_PURGE_RX, ctx->index, NULL, 0, ctx->usb_write_timeout); - if (err < 0) { - LOG_ERROR("unable to purge ftdi rx buffers: %s", libusb_error_name(err)); - return; - } - - err = libusb_control_transfer(ctx->usb_dev, FTDI_DEVICE_OUT_REQTYPE, SIO_RESET_REQUEST, - SIO_RESET_PURGE_TX, ctx->index, NULL, 0, ctx->usb_write_timeout); - if (err < 0) { - LOG_ERROR("unable to purge ftdi tx buffers: %s", libusb_error_name(err)); - return; - } -} - -static unsigned buffer_write_space(struct mpsse_ctx *ctx) -{ - /* Reserve one byte for SEND_IMMEDIATE */ - return ctx->write_size - ctx->write_count - 1; -} - -static unsigned buffer_read_space(struct mpsse_ctx *ctx) -{ - return ctx->read_size - ctx->read_count; -} - -static void buffer_write_byte(struct mpsse_ctx *ctx, uint8_t data) -{ - DEBUG_IO("%02x", data); - assert(ctx->write_count < ctx->write_size); - ctx->write_buffer[ctx->write_count++] = data; -} - -static unsigned buffer_write(struct mpsse_ctx *ctx, const uint8_t *out, unsigned out_offset, - unsigned bit_count) -{ - DEBUG_IO("%d bits", bit_count); - assert(ctx->write_count + DIV_ROUND_UP(bit_count, 8) <= ctx->write_size); - bit_copy(ctx->write_buffer + ctx->write_count, 0, out, out_offset, bit_count); - ctx->write_count += DIV_ROUND_UP(bit_count, 8); - return bit_count; -} - -static unsigned buffer_add_read(struct mpsse_ctx *ctx, uint8_t *in, unsigned in_offset, - unsigned bit_count, unsigned offset) -{ - DEBUG_IO("%d bits, offset %d", bit_count, offset); - assert(ctx->read_count + DIV_ROUND_UP(bit_count, 8) <= ctx->read_size); - bit_copy_queued(&ctx->read_queue, in, in_offset, ctx->read_buffer + ctx->read_count, offset, - bit_count); - ctx->read_count += DIV_ROUND_UP(bit_count, 8); - return bit_count; -} - -void mpsse_clock_data_out(struct mpsse_ctx *ctx, const uint8_t *out, unsigned out_offset, - unsigned length, uint8_t mode) -{ - mpsse_clock_data(ctx, out, out_offset, 0, 0, length, mode); -} - -void mpsse_clock_data_in(struct mpsse_ctx *ctx, uint8_t *in, unsigned in_offset, unsigned length, - uint8_t mode) -{ - mpsse_clock_data(ctx, 0, 0, in, in_offset, length, mode); -} - -void mpsse_clock_data(struct mpsse_ctx *ctx, const uint8_t *out, unsigned out_offset, uint8_t *in, - unsigned in_offset, unsigned length, uint8_t mode) -{ - /* TODO: Fix MSB first modes */ - DEBUG_IO("%s%s %d bits", in ? "in" : "", out ? "out" : "", length); - - if (ctx->retval != ERROR_OK) { - DEBUG_IO("Ignoring command due to previous error"); - return; - } - - /* TODO: On H chips, use command 0x8E/0x8F if in and out are both 0 */ - if (out || (!out && !in)) - mode |= 0x10; - if (in) - mode |= 0x20; - - while (length > 0) { - /* Guarantee buffer space enough for a minimum size transfer */ - if (buffer_write_space(ctx) + (length < 8) < (out || (!out && !in) ? 4 : 3) - || (in && buffer_read_space(ctx) < 1)) - ctx->retval = mpsse_flush(ctx); - - if (length < 8) { - /* Transfer remaining bits in bit mode */ - buffer_write_byte(ctx, 0x02 | mode); - buffer_write_byte(ctx, length - 1); - if (out) - out_offset += buffer_write(ctx, out, out_offset, length); - if (in) - in_offset += buffer_add_read(ctx, in, in_offset, length, 8 - length); - if (!out && !in) - buffer_write_byte(ctx, 0x00); - length = 0; - } else { - /* Byte transfer */ - unsigned this_bytes = length / 8; - /* MPSSE command limit */ - if (this_bytes > 65536) - this_bytes = 65536; - /* Buffer space limit. We already made sure there's space for the minimum - * transfer. */ - if ((out || (!out && !in)) && this_bytes + 3 > buffer_write_space(ctx)) - this_bytes = buffer_write_space(ctx) - 3; - if (in && this_bytes > buffer_read_space(ctx)) - this_bytes = buffer_read_space(ctx); - - if (this_bytes > 0) { - buffer_write_byte(ctx, mode); - buffer_write_byte(ctx, (this_bytes - 1) & 0xff); - buffer_write_byte(ctx, (this_bytes - 1) >> 8); - if (out) - out_offset += buffer_write(ctx, - out, - out_offset, - this_bytes * 8); - if (in) - in_offset += buffer_add_read(ctx, - in, - in_offset, - this_bytes * 8, - 0); - if (!out && !in) - for (unsigned n = 0; n < this_bytes; n++) - buffer_write_byte(ctx, 0x00); - length -= this_bytes * 8; - } - } - } -} - -void mpsse_clock_tms_cs_out(struct mpsse_ctx *ctx, const uint8_t *out, unsigned out_offset, - unsigned length, bool tdi, uint8_t mode) -{ - mpsse_clock_tms_cs(ctx, out, out_offset, 0, 0, length, tdi, mode); -} - -void mpsse_clock_tms_cs(struct mpsse_ctx *ctx, const uint8_t *out, unsigned out_offset, uint8_t *in, - unsigned in_offset, unsigned length, bool tdi, uint8_t mode) -{ - DEBUG_IO("%sout %d bits, tdi=%d", in ? "in" : "", length, tdi); - assert(out); - - if (ctx->retval != ERROR_OK) { - DEBUG_IO("Ignoring command due to previous error"); - return; - } - - mode |= 0x42; - if (in) - mode |= 0x20; - - while (length > 0) { - /* Guarantee buffer space enough for a minimum size transfer */ - if (buffer_write_space(ctx) < 3 || (in && buffer_read_space(ctx) < 1)) - ctx->retval = mpsse_flush(ctx); - - /* Byte transfer */ - unsigned this_bits = length; - /* MPSSE command limit */ - /* NOTE: there's a report of an FT2232 bug in this area, where shifting - * exactly 7 bits can make problems with TMS signaling for the last - * clock cycle: - * - * http://developer.intra2net.com/mailarchive/html/libftdi/2009/msg00292.html - */ - if (this_bits > 7) - this_bits = 7; - - if (this_bits > 0) { - buffer_write_byte(ctx, mode); - buffer_write_byte(ctx, this_bits - 1); - uint8_t data = 0; - /* TODO: Fix MSB first, if allowed in MPSSE */ - bit_copy(&data, 0, out, out_offset, this_bits); - out_offset += this_bits; - buffer_write_byte(ctx, data | (tdi ? 0x80 : 0x00)); - if (in) - in_offset += buffer_add_read(ctx, - in, - in_offset, - this_bits, - 8 - this_bits); - length -= this_bits; - } - } -} - -void mpsse_set_data_bits_low_byte(struct mpsse_ctx *ctx, uint8_t data, uint8_t dir) -{ - DEBUG_IO("-"); - - if (ctx->retval != ERROR_OK) { - DEBUG_IO("Ignoring command due to previous error"); - return; - } - - if (buffer_write_space(ctx) < 3) - ctx->retval = mpsse_flush(ctx); - - buffer_write_byte(ctx, 0x80); - buffer_write_byte(ctx, data); - buffer_write_byte(ctx, dir); -} - -void mpsse_set_data_bits_high_byte(struct mpsse_ctx *ctx, uint8_t data, uint8_t dir) -{ - DEBUG_IO("-"); - - if (ctx->retval != ERROR_OK) { - DEBUG_IO("Ignoring command due to previous error"); - return; - } - - if (buffer_write_space(ctx) < 3) - ctx->retval = mpsse_flush(ctx); - - buffer_write_byte(ctx, 0x82); - buffer_write_byte(ctx, data); - buffer_write_byte(ctx, dir); -} - -void mpsse_read_data_bits_low_byte(struct mpsse_ctx *ctx, uint8_t *data) -{ - DEBUG_IO("-"); - - if (ctx->retval != ERROR_OK) { - DEBUG_IO("Ignoring command due to previous error"); - return; - } - - if (buffer_write_space(ctx) < 1 || buffer_read_space(ctx) < 1) - ctx->retval = mpsse_flush(ctx); - - buffer_write_byte(ctx, 0x81); - buffer_add_read(ctx, data, 0, 8, 0); -} - -void mpsse_read_data_bits_high_byte(struct mpsse_ctx *ctx, uint8_t *data) -{ - DEBUG_IO("-"); - - if (ctx->retval != ERROR_OK) { - DEBUG_IO("Ignoring command due to previous error"); - return; - } - - if (buffer_write_space(ctx) < 1 || buffer_read_space(ctx) < 1) - ctx->retval = mpsse_flush(ctx); - - buffer_write_byte(ctx, 0x83); - buffer_add_read(ctx, data, 0, 8, 0); -} - -static void single_byte_boolean_helper(struct mpsse_ctx *ctx, bool var, uint8_t val_if_true, - uint8_t val_if_false) -{ - if (ctx->retval != ERROR_OK) { - DEBUG_IO("Ignoring command due to previous error"); - return; - } - - if (buffer_write_space(ctx) < 1) - ctx->retval = mpsse_flush(ctx); - - buffer_write_byte(ctx, var ? val_if_true : val_if_false); -} - -void mpsse_loopback_config(struct mpsse_ctx *ctx, bool enable) -{ - LOG_DEBUG("%s", enable ? "on" : "off"); - single_byte_boolean_helper(ctx, enable, 0x84, 0x85); -} - -void mpsse_set_divisor(struct mpsse_ctx *ctx, uint16_t divisor) -{ - LOG_DEBUG("%d", divisor); - - if (ctx->retval != ERROR_OK) { - DEBUG_IO("Ignoring command due to previous error"); - return; - } - - if (buffer_write_space(ctx) < 3) - ctx->retval = mpsse_flush(ctx); - - buffer_write_byte(ctx, 0x86); - buffer_write_byte(ctx, divisor & 0xff); - buffer_write_byte(ctx, divisor >> 8); -} - -int mpsse_divide_by_5_config(struct mpsse_ctx *ctx, bool enable) -{ - if (!mpsse_is_high_speed(ctx)) - return ERROR_FAIL; - - LOG_DEBUG("%s", enable ? "on" : "off"); - single_byte_boolean_helper(ctx, enable, 0x8b, 0x8a); - - return ERROR_OK; -} - -int mpsse_rtck_config(struct mpsse_ctx *ctx, bool enable) -{ - if (!mpsse_is_high_speed(ctx)) - return ERROR_FAIL; - - LOG_DEBUG("%s", enable ? "on" : "off"); - single_byte_boolean_helper(ctx, enable, 0x96, 0x97); - - return ERROR_OK; -} - -int mpsse_set_frequency(struct mpsse_ctx *ctx, int frequency) -{ - LOG_DEBUG("target %d Hz", frequency); - assert(frequency >= 0); - int base_clock; - - if (frequency == 0) - return mpsse_rtck_config(ctx, true); - - mpsse_rtck_config(ctx, false); /* just try */ - - if (frequency > 60000000 / 2 / 65536 && mpsse_divide_by_5_config(ctx, false) == ERROR_OK) { - base_clock = 60000000; - } else { - mpsse_divide_by_5_config(ctx, true); /* just try */ - base_clock = 12000000; - } - - int divisor = (base_clock / 2 + frequency - 1) / frequency - 1; - if (divisor > 65535) - divisor = 65535; - assert(divisor >= 0); - - mpsse_set_divisor(ctx, divisor); - - frequency = base_clock / 2 / (1 + divisor); - LOG_DEBUG("actually %d Hz", frequency); - - return frequency; -} - -/* Context needed by the callbacks */ -struct transfer_result { - struct mpsse_ctx *ctx; - bool done; - unsigned transferred; -}; - -static LIBUSB_CALL void read_cb(struct libusb_transfer *transfer) -{ - struct transfer_result *res = transfer->user_data; - struct mpsse_ctx *ctx = res->ctx; - - unsigned packet_size = ctx->max_packet_size; - - DEBUG_PRINT_BUF(transfer->buffer, transfer->actual_length); - - /* Strip the two status bytes sent at the beginning of each USB packet - * while copying the chunk buffer to the read buffer */ - unsigned num_packets = DIV_ROUND_UP(transfer->actual_length, packet_size); - unsigned chunk_remains = transfer->actual_length; - for (unsigned i = 0; i < num_packets && chunk_remains > 2; i++) { - unsigned this_size = packet_size - 2; - if (this_size > chunk_remains - 2) - this_size = chunk_remains - 2; - if (this_size > ctx->read_count - res->transferred) - this_size = ctx->read_count - res->transferred; - memcpy(ctx->read_buffer + res->transferred, - ctx->read_chunk + packet_size * i + 2, - this_size); - res->transferred += this_size; - chunk_remains -= this_size + 2; - if (res->transferred == ctx->read_count) { - res->done = true; - break; - } - } - - DEBUG_IO("raw chunk %d, transferred %d of %d", transfer->actual_length, res->transferred, - ctx->read_count); - - if (!res->done) - if (libusb_submit_transfer(transfer) != LIBUSB_SUCCESS) - res->done = true; -} - -static LIBUSB_CALL void write_cb(struct libusb_transfer *transfer) -{ - struct transfer_result *res = transfer->user_data; - struct mpsse_ctx *ctx = res->ctx; - - res->transferred += transfer->actual_length; - - DEBUG_IO("transferred %d of %d", res->transferred, ctx->write_count); - - DEBUG_PRINT_BUF(transfer->buffer, transfer->actual_length); - - if (res->transferred == ctx->write_count) - res->done = true; - else { - transfer->length = ctx->write_count - res->transferred; - transfer->buffer = ctx->write_buffer + res->transferred; - if (libusb_submit_transfer(transfer) != LIBUSB_SUCCESS) - res->done = true; - } -} - -int mpsse_flush(struct mpsse_ctx *ctx) -{ - int retval = ctx->retval; - - if (retval != ERROR_OK) { - DEBUG_IO("Ignoring flush due to previous error"); - assert(ctx->write_count == 0 && ctx->read_count == 0); - ctx->retval = ERROR_OK; - return retval; - } - - DEBUG_IO("write %d%s, read %d", ctx->write_count, ctx->read_count ? "+1" : "", - ctx->read_count); - assert(ctx->write_count > 0 || ctx->read_count == 0); /* No read data without write data */ - - if (ctx->write_count == 0) - return retval; - - struct libusb_transfer *read_transfer = 0; - struct transfer_result read_result = { .ctx = ctx, .done = true }; - if (ctx->read_count) { - buffer_write_byte(ctx, 0x87); /* SEND_IMMEDIATE */ - read_result.done = false; - /* delay read transaction to ensure the FTDI chip can support us with data - immediately after processing the MPSSE commands in the write transaction */ - } - - struct transfer_result write_result = { .ctx = ctx, .done = false }; - struct libusb_transfer *write_transfer = libusb_alloc_transfer(0); - 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 (ctx->read_count) { - read_transfer = libusb_alloc_transfer(0); - libusb_fill_bulk_transfer(read_transfer, ctx->usb_dev, ctx->in_ep, ctx->read_chunk, - ctx->read_chunk_size, read_cb, &read_result, - ctx->usb_read_timeout); - retval = libusb_submit_transfer(read_transfer); - } - - /* Polling loop, more or less taken from libftdi */ - while (!write_result.done || !read_result.done) { - retval = libusb_handle_events(ctx->usb_ctx); - keep_alive(); - if (retval != LIBUSB_SUCCESS && retval != LIBUSB_ERROR_INTERRUPTED) { - 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) - break; - } - } - - if (retval != LIBUSB_SUCCESS) { - LOG_ERROR("libusb_handle_events() failed with %s", libusb_error_name(retval)); - retval = ERROR_FAIL; - } else if (write_result.transferred < ctx->write_count) { - LOG_ERROR("ftdi device did not accept all data: %d, tried %d", - write_result.transferred, - ctx->write_count); - retval = ERROR_FAIL; - } else if (read_result.transferred < ctx->read_count) { - LOG_ERROR("ftdi device did not return all data: %d, expected %d", - read_result.transferred, - ctx->read_count); - retval = ERROR_FAIL; - } else if (ctx->read_count) { - ctx->write_count = 0; - ctx->read_count = 0; - bit_copy_execute(&ctx->read_queue); - retval = ERROR_OK; - } else { - ctx->write_count = 0; - bit_copy_discard(&ctx->read_queue); - retval = ERROR_OK; - } - - libusb_free_transfer(write_transfer); - if (read_transfer) - libusb_free_transfer(read_transfer); - - if (retval != ERROR_OK) - mpsse_purge(ctx); - - return retval; -} diff --git a/src/jtag/drivers/mpsse.h b/src/jtag/drivers/mpsse.h deleted file mode 100644 index 651eef940..000000000 --- a/src/jtag/drivers/mpsse.h +++ /dev/null @@ -1,78 +0,0 @@ -/************************************************************************** - * Copyright (C) 2012 by Andreas Fritiofson * - * andreas.fritiofson@gmail.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifndef OPENOCD_JTAG_DRIVERS_MPSSE_H -#define OPENOCD_JTAG_DRIVERS_MPSSE_H - -#include -#include "helper/binarybuffer.h" - -/* Mode flags */ -#define POS_EDGE_OUT 0x00 -#define NEG_EDGE_OUT 0x01 -#define POS_EDGE_IN 0x00 -#define NEG_EDGE_IN 0x04 -#define MSB_FIRST 0x00 -#define LSB_FIRST 0x08 - -enum ftdi_chip_type { - TYPE_FT2232C, - TYPE_FT2232H, - TYPE_FT4232H, - TYPE_FT232H, -}; - -struct mpsse_ctx; - -/* Device handling */ -struct mpsse_ctx *mpsse_open(const uint16_t *vid, const uint16_t *pid, const char *description, - const char *serial, const char *location, int channel); -void mpsse_close(struct mpsse_ctx *ctx); -bool mpsse_is_high_speed(struct mpsse_ctx *ctx); - -/* Command queuing. These correspond to the MPSSE commands with the same names, but no need to care - * about bit/byte transfer or data length limitation. Read data is guaranteed to be available only - * after the following mpsse_flush(). */ -void mpsse_clock_data_out(struct mpsse_ctx *ctx, const uint8_t *out, unsigned out_offset, - unsigned length, uint8_t mode); -void mpsse_clock_data_in(struct mpsse_ctx *ctx, uint8_t *in, unsigned in_offset, unsigned length, - uint8_t mode); -void mpsse_clock_data(struct mpsse_ctx *ctx, const uint8_t *out, unsigned out_offset, uint8_t *in, - unsigned in_offset, unsigned length, uint8_t mode); -void mpsse_clock_tms_cs_out(struct mpsse_ctx *ctx, const uint8_t *out, unsigned out_offset, - unsigned length, bool tdi, uint8_t mode); -void mpsse_clock_tms_cs(struct mpsse_ctx *ctx, const uint8_t *out, unsigned out_offset, uint8_t *in, - unsigned in_offset, unsigned length, bool tdi, uint8_t mode); -void mpsse_set_data_bits_low_byte(struct mpsse_ctx *ctx, uint8_t data, uint8_t dir); -void mpsse_set_data_bits_high_byte(struct mpsse_ctx *ctx, uint8_t data, uint8_t dir); -void mpsse_read_data_bits_low_byte(struct mpsse_ctx *ctx, uint8_t *data); -void mpsse_read_data_bits_high_byte(struct mpsse_ctx *ctx, uint8_t *data); -void mpsse_loopback_config(struct mpsse_ctx *ctx, bool enable); -void mpsse_set_divisor(struct mpsse_ctx *ctx, uint16_t divisor); -int mpsse_divide_by_5_config(struct mpsse_ctx *ctx, bool enable); -int mpsse_rtck_config(struct mpsse_ctx *ctx, bool enable); - -/* Helper to set frequency in Hertz. Returns actual realizable frequency or negative error. - * Frequency 0 means RTCK. */ -int mpsse_set_frequency(struct mpsse_ctx *ctx, int frequency); - -/* Queue handling */ -int mpsse_flush(struct mpsse_ctx *ctx); -void mpsse_purge(struct mpsse_ctx *ctx); - -#endif /* OPENOCD_JTAG_DRIVERS_MPSSE_H */ diff --git a/src/jtag/drivers/opendous.c b/src/jtag/drivers/opendous.c deleted file mode 100644 index 458df34a7..000000000 --- a/src/jtag/drivers/opendous.c +++ /dev/null @@ -1,825 +0,0 @@ -/*************************************************************************** - * * - * Copyright (C) 2009 by Cahya Wirawan * - * Based on opendous driver by Vladimir Fonov * - * * - * Copyright (C) 2009 by Vladimir Fonov * - * Based on J-link driver by Juergen Stuber * - * * - * Copyright (C) 2007 by Juergen Stuber * - * based on Dominic Rath's and Benedikt Sauter's usbprog.c * - * * - * Copyright (C) 2008 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include "libusb_common.h" -#include -#include - -#define OPENDOUS_MAX_VIDS_PIDS 4 -/* define some probes with similar interface */ -struct opendous_probe { - const char *name; - uint16_t VID[OPENDOUS_MAX_VIDS_PIDS]; - uint16_t PID[OPENDOUS_MAX_VIDS_PIDS]; - uint8_t READ_EP; - uint8_t WRITE_EP; - uint8_t CONTROL_TRANSFER; - int BUFFERSIZE; -}; - -static const struct opendous_probe opendous_probes[] = { - {"usbprog-jtag", {0x1781, 0}, {0x0C63, 0}, 0x82, 0x02, 0x00, 510 }, - {"opendous", {0x1781, 0x03EB, 0}, {0xC0C0, 0x204F, 0}, 0x81, 0x02, 0x00, 360 }, - {"usbvlab", {0x16C0, 0}, {0x05DC, 0}, 0x81, 0x02, 0x01, 360 }, - {NULL, {0x0000}, {0x0000}, 0x00, 0x00, 0x00, 0 } -}; - -#define OPENDOUS_WRITE_ENDPOINT (opendous_probe->WRITE_EP) -#define OPENDOUS_READ_ENDPOINT (opendous_probe->READ_EP) - -static unsigned int opendous_hw_jtag_version = 1; - -#define OPENDOUS_USB_TIMEOUT 1000 - -#define OPENDOUS_USB_BUFFER_SIZE (opendous_probe->BUFFERSIZE) -#define OPENDOUS_IN_BUFFER_SIZE (OPENDOUS_USB_BUFFER_SIZE) -#define OPENDOUS_OUT_BUFFER_SIZE (OPENDOUS_USB_BUFFER_SIZE) - -/* Global USB buffers */ -static uint8_t *usb_in_buffer; -static uint8_t *usb_out_buffer; - -/* Constants for OPENDOUS command */ - -#define OPENDOUS_MAX_SPEED 66 -#define OPENDOUS_MAX_TAP_TRANSMIT ((opendous_probe->BUFFERSIZE)-10) -#define OPENDOUS_MAX_INPUT_DATA (OPENDOUS_MAX_TAP_TRANSMIT*4) - -/* TAP */ -#define OPENDOUS_TAP_BUFFER_SIZE 65536 - -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 */ - uint8_t *buffer; -}; - -static int pending_scan_results_length; -static struct pending_scan_result *pending_scan_results_buffer; - -#define MAX_PENDING_SCAN_RESULTS (OPENDOUS_MAX_INPUT_DATA) - -/* JTAG usb commands */ -#define JTAG_CMD_TAP_OUTPUT 0x0 -#define JTAG_CMD_SET_TRST 0x1 -#define JTAG_CMD_SET_SRST 0x2 -#define JTAG_CMD_READ_INPUT 0x3 -#define JTAG_CMD_TAP_OUTPUT_EMU 0x4 -#define JTAG_CMD_SET_DELAY 0x5 -#define JTAG_CMD_SET_SRST_TRST 0x6 -#define JTAG_CMD_READ_CONFIG 0x7 - -/* usbvlab control transfer */ -#define FUNC_START_BOOTLOADER 30 -#define FUNC_WRITE_DATA 0x50 -#define FUNC_READ_DATA 0x51 - -static char *opendous_type; -static const struct opendous_probe *opendous_probe; - -/* External interface functions */ -static int opendous_execute_queue(void); -static int opendous_init(void); -static int opendous_quit(void); - -/* Queue command functions */ -static void opendous_end_state(tap_state_t state); -static void opendous_state_move(void); -static void opendous_path_move(int num_states, tap_state_t *path); -static void opendous_runtest(int num_cycles); -static void opendous_scan(int ir_scan, enum scan_type type, uint8_t *buffer, - int scan_size, struct scan_command *command); -static void opendous_reset(int trst, int srst); -static void opendous_simple_command(uint8_t command, uint8_t _data); -static int opendous_get_status(void); - -/* opendous tap buffer functions */ -static void opendous_tap_init(void); -static int opendous_tap_execute(void); -static void opendous_tap_ensure_space(int scans, int bits); -static void opendous_tap_append_step(int tms, int tdi); -static void opendous_tap_append_scan(int length, uint8_t *buffer, struct scan_command *command); - -/* opendous lowlevel functions */ -struct opendous_jtag { - struct jtag_libusb_device_handle *usb_handle; -}; - -static struct opendous_jtag *opendous_usb_open(void); -static void opendous_usb_close(struct opendous_jtag *opendous_jtag); -static int opendous_usb_message(struct opendous_jtag *opendous_jtag, int out_length, int in_length); -static int opendous_usb_write(struct opendous_jtag *opendous_jtag, int out_length); -static int opendous_usb_read(struct opendous_jtag *opendous_jtag); - -/* helper functions */ -int opendous_get_version_info(void); - -#ifdef _DEBUG_USB_COMMS_ -static void opendous_debug_buffer(uint8_t *buffer, int length); -#endif - -static struct opendous_jtag *opendous_jtag_handle; - -/***************************************************************************/ -/* External interface implementation */ - -COMMAND_HANDLER(opendous_handle_opendous_type_command) -{ - if (CMD_ARGC == 0) - return ERROR_OK; - - /* only if the cable name wasn't overwritten by cmdline */ - if (opendous_type == NULL) { - /* REVISIT first verify that it's listed in cables[] ... */ - opendous_type = strdup(CMD_ARGV[0]); - } - - /* REVISIT it's probably worth returning the current value ... */ - - return ERROR_OK; -} - -COMMAND_HANDLER(opendous_handle_opendous_info_command) -{ - if (opendous_get_version_info() == ERROR_OK) { - /* attempt to get status */ - opendous_get_status(); - } - - return ERROR_OK; -} - -COMMAND_HANDLER(opendous_handle_opendous_hw_jtag_command) -{ - switch (CMD_ARGC) { - case 0: - command_print(CMD_CTX, "opendous hw jtag %i", opendous_hw_jtag_version); - break; - - case 1: { - int request_version = atoi(CMD_ARGV[0]); - switch (request_version) { - case 2: - case 3: - opendous_hw_jtag_version = request_version; - break; - - default: - return ERROR_COMMAND_SYNTAX_ERROR; - } - break; - } - - default: - return ERROR_COMMAND_SYNTAX_ERROR; - } - - return ERROR_OK; -} - -static const struct command_registration opendous_command_handlers[] = { - { - .name = "opendous_info", - .handler = &opendous_handle_opendous_info_command, - .mode = COMMAND_EXEC, - .help = "show opendous info", - }, - { - .name = "opendous_hw_jtag", - .handler = &opendous_handle_opendous_hw_jtag_command, - .mode = COMMAND_EXEC, - .help = "access opendous HW JTAG command version", - .usage = "[2|3]", - }, - { - .name = "opendous_type", - .handler = &opendous_handle_opendous_type_command, - .mode = COMMAND_CONFIG, - .help = "set opendous type", - .usage = "[usbvlab|usbprog-jtag|opendous]", - }, - COMMAND_REGISTRATION_DONE -}; - -struct jtag_interface opendous_interface = { - .name = "opendous", - .commands = opendous_command_handlers, - .execute_queue = opendous_execute_queue, - .init = opendous_init, - .quit = opendous_quit, -}; - -static int opendous_execute_queue(void) -{ - struct jtag_command *cmd = jtag_command_queue; - int scan_size; - enum scan_type type; - uint8_t *buffer; - - while (cmd != NULL) { - switch (cmd->type) { - case JTAG_RUNTEST: - DEBUG_JTAG_IO("runtest %i cycles, end in %i", cmd->cmd.runtest->num_cycles, \ - cmd->cmd.runtest->end_state); - - if (cmd->cmd.runtest->end_state != -1) - opendous_end_state(cmd->cmd.runtest->end_state); - opendous_runtest(cmd->cmd.runtest->num_cycles); - break; - - case JTAG_TLR_RESET: - DEBUG_JTAG_IO("statemove end in %i", cmd->cmd.statemove->end_state); - - if (cmd->cmd.statemove->end_state != -1) - opendous_end_state(cmd->cmd.statemove->end_state); - opendous_state_move(); - break; - - case JTAG_PATHMOVE: - DEBUG_JTAG_IO("pathmove: %i states, end in %i", \ - cmd->cmd.pathmove->num_states, \ - cmd->cmd.pathmove->path[cmd->cmd.pathmove->num_states - 1]); - - opendous_path_move(cmd->cmd.pathmove->num_states, cmd->cmd.pathmove->path); - break; - - case JTAG_SCAN: - DEBUG_JTAG_IO("scan end in %i", cmd->cmd.scan->end_state); - - if (cmd->cmd.scan->end_state != -1) - opendous_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); - -#ifdef _DEBUG_USB_COMMS_ - opendous_debug_buffer(buffer, (scan_size + 7) / 8); -#endif - type = jtag_scan_type(cmd->cmd.scan); - opendous_scan(cmd->cmd.scan->ir_scan, type, buffer, scan_size, cmd->cmd.scan); - break; - - case JTAG_RESET: - DEBUG_JTAG_IO("reset trst: %i srst %i", cmd->cmd.reset->trst, cmd->cmd.reset->srst); - - opendous_tap_execute(); - - if (cmd->cmd.reset->trst == 1) - tap_set_state(TAP_RESET); - opendous_reset(cmd->cmd.reset->trst, cmd->cmd.reset->srst); - break; - - case JTAG_SLEEP: - DEBUG_JTAG_IO("sleep %" PRIi32, cmd->cmd.sleep->us); - opendous_tap_execute(); - jtag_sleep(cmd->cmd.sleep->us); - break; - - default: - LOG_ERROR("BUG: unknown JTAG command type encountered"); - exit(-1); - } - cmd = cmd->next; - } - return opendous_tap_execute(); -} - -static int opendous_init(void) -{ - int check_cnt; - const struct opendous_probe *cur_opendous_probe; - - cur_opendous_probe = opendous_probes; - - if (opendous_type == NULL) { - opendous_type = strdup("opendous"); - LOG_WARNING("No opendous_type specified, using default 'opendous'"); - } - - while (cur_opendous_probe->name) { - if (strcmp(cur_opendous_probe->name, opendous_type) == 0) { - opendous_probe = cur_opendous_probe; - break; - } - cur_opendous_probe++; - } - - if (!opendous_probe) { - LOG_ERROR("No matching cable found for %s", opendous_type); - return ERROR_JTAG_INIT_FAILED; - } - - - usb_in_buffer = malloc(opendous_probe->BUFFERSIZE); - usb_out_buffer = malloc(opendous_probe->BUFFERSIZE); - - pending_scan_results_buffer = malloc( - MAX_PENDING_SCAN_RESULTS * sizeof(*pending_scan_results_buffer)); - - opendous_jtag_handle = opendous_usb_open(); - - if (opendous_jtag_handle == 0) { - LOG_ERROR("Cannot find opendous Interface! Please check connection and permissions."); - return ERROR_JTAG_INIT_FAILED; - } - - check_cnt = 0; - while (check_cnt < 3) { - if (opendous_get_version_info() == ERROR_OK) { - /* attempt to get status */ - opendous_get_status(); - break; - } - - check_cnt++; - } - - LOG_INFO("opendous JTAG Interface ready"); - - opendous_reset(0, 0); - opendous_tap_init(); - - return ERROR_OK; -} - -static int opendous_quit(void) -{ - opendous_usb_close(opendous_jtag_handle); - - if (usb_out_buffer) { - free(usb_out_buffer); - usb_out_buffer = NULL; - } - - if (usb_in_buffer) { - free(usb_in_buffer); - usb_in_buffer = NULL; - } - - if (pending_scan_results_buffer) { - free(pending_scan_results_buffer); - pending_scan_results_buffer = NULL; - } - - if (opendous_type) { - free(opendous_type); - opendous_type = NULL; - } - - return ERROR_OK; -} - -/***************************************************************************/ -/* Queue command implementations */ - -void opendous_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); - } -} - -/* Goes to the end state. */ -void opendous_state_move(void) -{ - int i; - int tms = 0; - uint8_t tms_scan = tap_get_tms_path(tap_get_state(), tap_get_end_state()); - uint8_t 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; - opendous_tap_append_step(tms, 0); - } - - tap_set_state(tap_get_end_state()); -} - -void opendous_path_move(int num_states, tap_state_t *path) -{ - int i; - - for (i = 0; i < num_states; i++) { - if (path[i] == tap_state_transition(tap_get_state(), false)) - opendous_tap_append_step(0, 0); - else if (path[i] == tap_state_transition(tap_get_state(), true)) - opendous_tap_append_step(1, 0); - 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]); - } - - tap_set_end_state(tap_get_state()); -} - -void opendous_runtest(int num_cycles) -{ - int i; - - 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) { - opendous_end_state(TAP_IDLE); - opendous_state_move(); - } - - /* execute num_cycles */ - for (i = 0; i < num_cycles; i++) - opendous_tap_append_step(0, 0); - - /* finish in end_state */ - opendous_end_state(saved_end_state); - if (tap_get_state() != tap_get_end_state()) - opendous_state_move(); -} - -void opendous_scan(int ir_scan, enum scan_type type, uint8_t *buffer, int scan_size, struct scan_command *command) -{ - tap_state_t saved_end_state; - - opendous_tap_ensure_space(1, scan_size + 8); - - saved_end_state = tap_get_end_state(); - - /* Move to appropriate scan state */ - opendous_end_state(ir_scan ? TAP_IRSHIFT : TAP_DRSHIFT); - - if (tap_get_state() != tap_get_end_state()) - opendous_state_move(); - - opendous_end_state(saved_end_state); - - /* Scan */ - opendous_tap_append_scan(scan_size, buffer, command); - - /* We are in Exit1, go to Pause */ - opendous_tap_append_step(0, 0); - - tap_set_state(ir_scan ? TAP_IRPAUSE : TAP_DRPAUSE); - - if (tap_get_state() != tap_get_end_state()) - opendous_state_move(); -} - -void opendous_reset(int trst, int srst) -{ - LOG_DEBUG("trst: %i, srst: %i", trst, srst); - - /* Signals are active low */ -#if 0 - if (srst == 0) - opendous_simple_command(JTAG_CMD_SET_SRST, 1); - else if (srst == 1) - opendous_simple_command(JTAG_CMD_SET_SRST, 0); - - if (trst == 0) - opendous_simple_command(JTAG_CMD_SET_TRST, 1); - else if (trst == 1) - opendous_simple_command(JTAG_CMD_SET_TRST, 0); -#endif - - srst = srst ? 0 : 1; - trst = trst ? 0 : 2; - opendous_simple_command(JTAG_CMD_SET_SRST_TRST, srst | trst); -} - -void opendous_simple_command(uint8_t command, uint8_t _data) -{ - int result; - - DEBUG_JTAG_IO("0x%02x 0x%02x", command, _data); - - usb_out_buffer[0] = 2; - usb_out_buffer[1] = 0; - usb_out_buffer[2] = command; - usb_out_buffer[3] = _data; - - result = opendous_usb_message(opendous_jtag_handle, 4, 1); - if (result != 1) - LOG_ERROR("opendous command 0x%02x failed (%d)", command, result); -} - -int opendous_get_status(void) -{ - return ERROR_OK; -} - -int opendous_get_version_info(void) -{ - return ERROR_OK; -} - -/***************************************************************************/ -/* Estick tap functions */ - -static int tap_length; -static uint8_t tms_buffer[OPENDOUS_TAP_BUFFER_SIZE]; -static uint8_t tdo_buffer[OPENDOUS_TAP_BUFFER_SIZE]; - -static int last_tms; - -void opendous_tap_init(void) -{ - tap_length = 0; - pending_scan_results_length = 0; -} - -void opendous_tap_ensure_space(int scans, int bits) -{ - int available_scans = MAX_PENDING_SCAN_RESULTS - pending_scan_results_length; - int available_bits = OPENDOUS_TAP_BUFFER_SIZE / 2 - tap_length; - - if ((scans > available_scans) || (bits > available_bits)) - opendous_tap_execute(); -} - -void opendous_tap_append_step(int tms, int tdi) -{ - last_tms = tms; - unsigned char _tms = tms ? 1 : 0; - unsigned char _tdi = tdi ? 1 : 0; - - opendous_tap_ensure_space(0, 1); - - int tap_index = tap_length / 4; - int bits = (tap_length % 4) * 2; - - if (tap_length < OPENDOUS_TAP_BUFFER_SIZE) { - if (!bits) - tms_buffer[tap_index] = 0; - - tms_buffer[tap_index] |= (_tdi << bits)|(_tms << (bits + 1)) ; - tap_length++; - } else - LOG_ERROR("opendous_tap_append_step, overflow"); -} - -void opendous_tap_append_scan(int length, uint8_t *buffer, struct scan_command *command) -{ - DEBUG_JTAG_IO("append scan, length = %d", length); - - struct pending_scan_result *pending_scan_result = &pending_scan_results_buffer[pending_scan_results_length]; - int i; - - pending_scan_result->first = tap_length; - pending_scan_result->length = length; - pending_scan_result->command = command; - pending_scan_result->buffer = buffer; - - for (i = 0; i < length; i++) - opendous_tap_append_step((i < length-1 ? 0 : 1), (buffer[i / 8] >> (i % 8)) & 1); - pending_scan_results_length++; -} - -/* 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. */ -int opendous_tap_execute(void) -{ - int byte_length; - int i, j; - int result; - -#ifdef _DEBUG_USB_COMMS_ - int byte_length_out; -#endif - - if (tap_length > 0) { - - /* memset(tdo_buffer,0,OPENDOUS_TAP_BUFFER_SIZE); */ - /* LOG_INFO("OPENDOUS tap execute %d",tap_length); */ - byte_length = (tap_length + 3) / 4; - -#ifdef _DEBUG_USB_COMMS_ - byte_length_out = (tap_length + 7) / 8; - LOG_DEBUG("opendous is sending %d bytes", byte_length); -#endif - - for (j = 0, i = 0; j < byte_length;) { - - int receive; - int transmit = byte_length - j; - if (transmit > OPENDOUS_MAX_TAP_TRANSMIT) { - transmit = OPENDOUS_MAX_TAP_TRANSMIT; - receive = (OPENDOUS_MAX_TAP_TRANSMIT) / 2; - usb_out_buffer[2] = JTAG_CMD_TAP_OUTPUT; - } else { - usb_out_buffer[2] = JTAG_CMD_TAP_OUTPUT | ((tap_length % 4) << 4); - receive = (transmit + 1) / 2; - } - usb_out_buffer[0] = (transmit + 1) & 0xff; - usb_out_buffer[1] = ((transmit + 1) >> 8) & 0xff; - - memmove(usb_out_buffer + 3, tms_buffer + j, transmit); - result = opendous_usb_message(opendous_jtag_handle, 3 + transmit, receive); - if (result != receive) { - LOG_ERROR("opendous_tap_execute, wrong result %d, expected %d", result, receive); - return ERROR_JTAG_QUEUE_FAILED; - } - - memmove(tdo_buffer + i, usb_in_buffer, receive); - i += receive; - j += transmit; - } - -#ifdef _DEBUG_USB_COMMS_ - LOG_DEBUG("opendous tap result %d", byte_length_out); - opendous_debug_buffer(tdo_buffer, byte_length_out); -#endif - - /* LOG_INFO("eStick tap execute %d",tap_length); */ - for (i = 0; i < pending_scan_results_length; i++) { - - 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); - - DEBUG_JTAG_IO("pending scan result, length = %d", length); - -#ifdef _DEBUG_USB_COMMS_ - opendous_debug_buffer(buffer, byte_length_out); -#endif - - if (jtag_read_buffer(buffer, command) != ERROR_OK) { - opendous_tap_init(); - return ERROR_JTAG_QUEUE_FAILED; - } - - if (pending_scan_result->buffer != NULL) - free(pending_scan_result->buffer); - } - - opendous_tap_init(); - } - - return ERROR_OK; -} - -/*****************************************************************************/ -/* Estick USB low-level functions */ - -struct opendous_jtag *opendous_usb_open(void) -{ - struct opendous_jtag *result; - - struct jtag_libusb_device_handle *devh; - if (jtag_libusb_open(opendous_probe->VID, opendous_probe->PID, NULL, &devh) != ERROR_OK) - return NULL; - - jtag_libusb_set_configuration(devh, 0); - jtag_libusb_claim_interface(devh, 0); - - result = malloc(sizeof(*result)); - result->usb_handle = devh; - return result; -} - -void opendous_usb_close(struct opendous_jtag *opendous_jtag) -{ - jtag_libusb_close(opendous_jtag->usb_handle); - free(opendous_jtag); -} - -/* Send a message and receive the reply. */ -int opendous_usb_message(struct opendous_jtag *opendous_jtag, int out_length, int in_length) -{ - int result; - - result = opendous_usb_write(opendous_jtag, out_length); - if (result == out_length) { - result = opendous_usb_read(opendous_jtag); - if (result == in_length) - return result; - else { - LOG_ERROR("usb_bulk_read failed (requested=%d, result=%d)", in_length, result); - return -1; - } - } else { - LOG_ERROR("usb_bulk_write failed (requested=%d, result=%d)", out_length, result); - return -1; - } -} - -/* Write data from out_buffer to USB. */ -int opendous_usb_write(struct opendous_jtag *opendous_jtag, int out_length) -{ - int result; - - if (out_length > OPENDOUS_OUT_BUFFER_SIZE) { - LOG_ERROR("opendous_jtag_write illegal out_length=%d (max=%d)", out_length, OPENDOUS_OUT_BUFFER_SIZE); - return -1; - } - -#ifdef _DEBUG_USB_COMMS_ - LOG_DEBUG("USB write begin"); -#endif - if (opendous_probe->CONTROL_TRANSFER) { - result = jtag_libusb_control_transfer(opendous_jtag->usb_handle, - LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE | LIBUSB_ENDPOINT_OUT, - FUNC_WRITE_DATA, 0, 0, (char *) usb_out_buffer, out_length, OPENDOUS_USB_TIMEOUT); - } else { - result = jtag_libusb_bulk_write(opendous_jtag->usb_handle, OPENDOUS_WRITE_ENDPOINT, \ - (char *)usb_out_buffer, out_length, OPENDOUS_USB_TIMEOUT); - } -#ifdef _DEBUG_USB_COMMS_ - LOG_DEBUG("USB write end: %d bytes", result); -#endif - - DEBUG_JTAG_IO("opendous_usb_write, out_length = %d, result = %d", out_length, result); - -#ifdef _DEBUG_USB_COMMS_ - opendous_debug_buffer(usb_out_buffer, out_length); -#endif - return result; -} - -/* Read data from USB into in_buffer. */ -int opendous_usb_read(struct opendous_jtag *opendous_jtag) -{ -#ifdef _DEBUG_USB_COMMS_ - LOG_DEBUG("USB read begin"); -#endif - int result; - if (opendous_probe->CONTROL_TRANSFER) { - result = jtag_libusb_control_transfer(opendous_jtag->usb_handle, - LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE | LIBUSB_ENDPOINT_IN, - FUNC_READ_DATA, 0, 0, (char *) usb_in_buffer, OPENDOUS_IN_BUFFER_SIZE, OPENDOUS_USB_TIMEOUT); - } else { - result = jtag_libusb_bulk_read(opendous_jtag->usb_handle, OPENDOUS_READ_ENDPOINT, - (char *)usb_in_buffer, OPENDOUS_IN_BUFFER_SIZE, OPENDOUS_USB_TIMEOUT); - } -#ifdef _DEBUG_USB_COMMS_ - LOG_DEBUG("USB read end: %d bytes", result); -#endif - DEBUG_JTAG_IO("opendous_usb_read, result = %d", result); - -#ifdef _DEBUG_USB_COMMS_ - opendous_debug_buffer(usb_in_buffer, result); -#endif - return result; -} - -#ifdef _DEBUG_USB_COMMS_ -#define BYTES_PER_LINE 16 - -void opendous_debug_buffer(uint8_t *buffer, int length) -{ - char line[81]; - char s[4]; - int i; - int j; - - for (i = 0; i < length; i += BYTES_PER_LINE) { - snprintf(line, 5, "%04x", i); - for (j = i; j < i + BYTES_PER_LINE && j < length; j++) { - snprintf(s, 4, " %02x", buffer[j]); - strcat(line, s); - } - LOG_DEBUG("%s", line); - } -} -#endif diff --git a/src/jtag/drivers/openjtag.c b/src/jtag/drivers/openjtag.c deleted file mode 100644 index 157020e8d..000000000 --- a/src/jtag/drivers/openjtag.c +++ /dev/null @@ -1,843 +0,0 @@ -/******************************************************************************* - * Driver for OpenJTAG Project (www.openjtag.org) * - * Compatible with libftdi and ftd2xx drivers. * - * * - * Copyright (C) 2010 by Ivan Meleca * - * * - * Copyright (C) 2013 by Ryan Corbin, GlueLogix Inc. * - * Updated to work with OpenOCD v0.7.0. Fixed libftdi read speed issue. * - * * - * Based on usb_blaster.c * - * Copyright (C) 2009 Catalin Patulea * - * Copyright (C) 2006 Kolja Waschk * - * * - * And jlink.c * - * Copyright (C) 2008 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -/*************************************************************************** - * Version 1.0 Tested on a MCBSTM32 board using a Cortex-M3 (stm32f103x), * - * GDB and Eclipse under Linux (Ubuntu 10.04) * - * * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include "usb_common.h" - -/* - * OpenJTAG-OpenOCD state conversion - */ -typedef enum openjtag_tap_state { - OPENJTAG_TAP_INVALID = -1, - OPENJTAG_TAP_RESET = 0, - OPENJTAG_TAP_IDLE = 1, - OPENJTAG_TAP_SELECT_DR = 2, - OPENJTAG_TAP_CAPTURE_DR = 3, - OPENJTAG_TAP_SHIFT_DR = 4, - OPENJTAG_TAP_EXIT1_DR = 5, - OPENJTAG_TAP_PAUSE_DR = 6, - OPENJTAG_TAP_EXIT2_DR = 7, - OPENJTAG_TAP_UPDATE_DR = 8, - OPENJTAG_TAP_SELECT_IR = 9, - OPENJTAG_TAP_CAPURE_IR = 10, - OPENJTAG_TAP_SHIFT_IR = 11, - OPENJTAG_TAP_EXIT1_IR = 12, - OPENJTAG_TAP_PAUSE_IR = 13, - OPENJTAG_TAP_EXIT2_IR = 14, - 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; -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 - -struct openjtag_scan_result { - uint32_t bits; /* Length in bits*/ - struct scan_command *command; /* Corresponding scan command */ - uint8_t *buffer; -}; - -/* USB RX/TX buffers */ -static int usb_tx_buf_offs; -static uint8_t usb_tx_buf[OPENJTAG_BUFFER_SIZE]; -static uint32_t usb_rx_buf_len; -static uint8_t usb_rx_buf[OPENJTAG_BUFFER_SIZE]; - -/* Pending readings */ -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; -}; - -#ifdef _DEBUG_USB_COMMS_ - -#define DEBUG_TYPE_READ 0 -#define DEBUG_TYPE_WRITE 1 -#define DEBUG_TYPE_OCD_READ 2 -#define DEBUG_TYPE_BUFFER 3 - -#define LINE_LEN 16 -static void openjtag_debug_buffer(uint8_t *buffer, int length, uint8_t type) -{ - char line[128]; - char s[4]; - int i; - int j; - - switch (type) { - case DEBUG_TYPE_READ: - sprintf(line, "USB READ %d bytes", length); - break; - case DEBUG_TYPE_WRITE: - sprintf(line, "USB WRITE %d bytes", length); - break; - case DEBUG_TYPE_OCD_READ: - sprintf(line, "TO OpenOCD %d bytes", length); - break; - case DEBUG_TYPE_BUFFER: - sprintf(line, "Buffer %d bytes", length); - break; - } - - LOG_DEBUG("%s", line); - - for (i = 0; i < length; i += LINE_LEN) { - switch (type) { - case DEBUG_TYPE_READ: - sprintf(line, "USB READ: %04x", i); - break; - case DEBUG_TYPE_WRITE: - sprintf(line, "USB WRITE: %04x", i); - break; - case DEBUG_TYPE_OCD_READ: - sprintf(line, "TO OpenOCD: %04x", i); - break; - case DEBUG_TYPE_BUFFER: - sprintf(line, "BUFFER: %04x", i); - break; - } - - for (j = i; j < i + LINE_LEN && j < length; j++) { - sprintf(s, " %02x", buffer[j]); - strcat(line, s); - } - LOG_DEBUG("%s", line); - } - -} - -#endif - -static int8_t openjtag_get_tap_state(int8_t state) -{ - - switch (state) { - case TAP_DREXIT2: return OPENJTAG_TAP_EXIT2_DR; - case TAP_DREXIT1: return OPENJTAG_TAP_EXIT1_DR; - case TAP_DRSHIFT: return OPENJTAG_TAP_SHIFT_DR; - case TAP_DRPAUSE: return OPENJTAG_TAP_PAUSE_DR; - case TAP_IRSELECT: return OPENJTAG_TAP_SELECT_IR; - case TAP_DRUPDATE: return OPENJTAG_TAP_UPDATE_DR; - case TAP_DRCAPTURE: return OPENJTAG_TAP_CAPTURE_DR; - case TAP_DRSELECT: return OPENJTAG_TAP_SELECT_DR; - case TAP_IREXIT2: return OPENJTAG_TAP_EXIT2_IR; - case TAP_IREXIT1: return OPENJTAG_TAP_EXIT1_IR; - case TAP_IRSHIFT: return OPENJTAG_TAP_SHIFT_IR; - case TAP_IRPAUSE: return OPENJTAG_TAP_PAUSE_IR; - case TAP_IDLE: return OPENJTAG_TAP_IDLE; - case TAP_IRUPDATE: return OPENJTAG_TAP_UPDATE_IR; - case TAP_IRCAPTURE: return OPENJTAG_TAP_CAPURE_IR; - case TAP_RESET: return OPENJTAG_TAP_RESET; - case TAP_INVALID: - default: return OPENJTAG_TAP_INVALID; - } -} - -static int openjtag_buf_write( - 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); -#endif - - retval = ftdi_write_data(&ftdic, buf, size); - if (retval < 0) { - *bytes_written = 0; - LOG_ERROR("ftdi_write_data: %s", ftdi_get_error_string(&ftdic)); - return ERROR_JTAG_DEVICE_ERROR; - } - - *bytes_written += retval; - - return ERROR_OK; -#endif -} - -static int openjtag_buf_read(uint8_t *buf, uint32_t qty, uint32_t *bytes_read) -{ - -#if BUILD_OPENJTAG_FTD2XX == 1 - DWORD dw_bytes_read; - FT_STATUS status; - int timeout = 50; - - *bytes_read = 0; - while (qty && (*bytes_read < qty) && timeout--) { - - 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; - } - -#ifdef _DEBUG_USB_COMMS_ - openjtag_debug_buffer(buf, *bytes_read, DEBUG_TYPE_READ); -#endif - - return ERROR_OK; -#elif BUILD_OPENJTAG_LIBFTDI == 1 - int retval; - int timeout = 5; - - *bytes_read = 0; - - while ((*bytes_read < qty) && timeout--) { - retval = ftdi_read_data(&ftdic, buf + *bytes_read, - qty - *bytes_read); - if (retval < 0) { - *bytes_read = 0; - DEBUG_JTAG_IO("ftdi_read_data: %s", - ftdi_get_error_string(&ftdic)); - return ERROR_JTAG_DEVICE_ERROR; - } - *bytes_read += retval; - } - -#ifdef _DEBUG_USB_COMMS_ - openjtag_debug_buffer(buf, *bytes_read, DEBUG_TYPE_READ); -#endif - -#endif - return ERROR_OK; -} - -static int openjtag_sendcommand(uint8_t cmd) -{ - uint32_t written; - return openjtag_buf_write(&cmd, 1, &written); -} - -static int openjtag_speed(int speed) -{ - int clockcmd; - switch (speed) { - case 48000: - clockcmd = 0x00; - break; - case 24000: - clockcmd = 0x20; - break; - case 12000: - clockcmd = 0x40; - break; - case 6000: - clockcmd = 0x60; - break; - case 3000: - clockcmd = 0x80; - break; - case 1500: - clockcmd = 0xA0; - break; - case 750: - clockcmd = 0xC0; - break; - case 375: - clockcmd = 0xE0; - break; - default: - clockcmd = 0xE0; - LOG_WARNING("adapter speed not recognized, reverting to 375 kHz"); - break; - } - openjtag_sendcommand(clockcmd); - - return ERROR_OK; -} - -static int openjtag_init(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, " - "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); - } -#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; - - /* context, vendor id, product id, description, serial id */ - if (ftdi_usb_open_desc(&ftdic, openjtag_vid, openjtag_pid, openjtag_device_desc, NULL) < 0) { - LOG_ERROR("unable to open ftdi device: %s", ftdic.error_str); - return ERROR_JTAG_INIT_FAILED; - } - - if (ftdi_usb_reset(&ftdic) < 0) { - LOG_ERROR("unable to reset ftdi device"); - return ERROR_JTAG_INIT_FAILED; - } - - if (ftdi_set_latency_timer(&ftdic, 2) < 0) { - LOG_ERROR("unable to set latency timer"); - return ERROR_JTAG_INIT_FAILED; - } - - if (ftdi_get_latency_timer(&ftdic, &latency_timer) < 0) { - LOG_ERROR("unable to get latency timer"); - return ERROR_JTAG_INIT_FAILED; - } - LOG_DEBUG("current latency timer: %u", latency_timer); - - ftdi_disable_bitbang(&ftdic); - /* was (3000000 / 4) with a comment about a bug in libftdi when using high baudrate */ - if (ftdi_set_baudrate(&ftdic, 3000000) < 0) { - 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*/ - - /* MSB */ - openjtag_sendcommand(0x75); - - return ERROR_OK; -} - -static int openjtag_quit(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 void openjtag_write_tap_buffer(void) -{ - uint32_t written; - - openjtag_buf_write(usb_tx_buf, usb_tx_buf_offs, &written); - openjtag_buf_read(usb_rx_buf, usb_tx_buf_offs, &usb_rx_buf_len); - - usb_tx_buf_offs = 0; -} - -static int openjtag_execute_tap_queue(void) -{ - openjtag_write_tap_buffer(); - - int res_count = 0; - - if (openjtag_scan_result_count && usb_rx_buf_len) { - - int count; - int rx_offs = 0; - int len; - - /* for every pending result */ - while (res_count < openjtag_scan_result_count) { - - /* get sent bits */ - len = openjtag_scan_result_buffer[res_count].bits; - - count = 0; - - uint8_t *buffer = openjtag_scan_result_buffer[res_count].buffer; - - while (len) { - if (len <= 8) { - 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); - len = 0; - } else { - buffer[count] = usb_rx_buf[rx_offs]; - len -= 8; - } - - rx_offs++; - count++; - } - -#ifdef _DEBUG_USB_COMMS_ - openjtag_debug_buffer(buffer, - DIV_ROUND_UP(openjtag_scan_result_buffer[res_count].bits, 8), DEBUG_TYPE_OCD_READ); -#endif - jtag_read_buffer(buffer, openjtag_scan_result_buffer[res_count].command); - - if (openjtag_scan_result_buffer[res_count].buffer) - free(openjtag_scan_result_buffer[res_count].buffer); - - res_count++; - } - } - - openjtag_scan_result_count = 0; - - return ERROR_OK; -} - -static void openjtag_add_byte(char buf) -{ - - if (usb_tx_buf_offs == OPENJTAG_BUFFER_SIZE) { - DEBUG_JTAG_IO("Forcing execute_tap_queue"); - DEBUG_JTAG_IO("TX Buff offs=%d", usb_tx_buf_offs); - openjtag_execute_tap_queue(); - } - - usb_tx_buf[usb_tx_buf_offs] = buf; - usb_tx_buf_offs++; -} - -static void openjtag_add_scan(uint8_t *buffer, int length, struct scan_command *scan_cmd) -{ - - /* Ensure space to send long chains */ - /* We add two byte for each eight (or less) bits, one for command, one for data */ - if (usb_tx_buf_offs + (DIV_ROUND_UP(length, 8) * 2) >= OPENJTAG_BUFFER_SIZE) { - DEBUG_JTAG_IO("Forcing execute_tap_queue from scan"); - DEBUG_JTAG_IO("TX Buff offs=%d len=%d", usb_tx_buf_offs, DIV_ROUND_UP(length, 8) * 2); - openjtag_execute_tap_queue(); - } - - openjtag_scan_result_buffer[openjtag_scan_result_count].bits = length; - openjtag_scan_result_buffer[openjtag_scan_result_count].command = scan_cmd; - openjtag_scan_result_buffer[openjtag_scan_result_count].buffer = buffer; - - uint8_t command; - uint8_t bits; - int count = 0; - while (length) { - - /* write command */ - command = 6; - - /* last bits? */ - if (length <= 8) { - /* tms high */ - command |= (1 << 4); - - /* bits to transfer */ - bits = (length - 1); - command |= bits << 5; - length = 0; - } else { - /* whole byte */ - - /* bits to transfer */ - bits = 7; - command |= (7 << 5); - length -= 8; - } - - openjtag_add_byte(command); - openjtag_add_byte(buffer[count]); - count++; - } - - openjtag_scan_result_count++; -} - -static void openjtag_execute_reset(struct jtag_command *cmd) -{ - - DEBUG_JTAG_IO("reset trst: %i srst %i", - cmd->cmd.reset->trst, cmd->cmd.reset->srst); - - uint8_t buf = 0x00; - - if (cmd->cmd.reset->trst) { - buf = 0x03; - } else { - buf |= 0x04; - buf |= 0x05 << 4; - } - - openjtag_add_byte(buf); -} - -static void openjtag_execute_sleep(struct jtag_command *cmd) -{ - jtag_sleep(cmd->cmd.sleep->us); -} - -static void openjtag_set_state(uint8_t openocd_state) -{ - int8_t state = openjtag_get_tap_state(openocd_state); - - uint8_t buf = 0; - buf = 0x01; - buf |= state << 4; - - openjtag_add_byte(buf); -} - -static void openjtag_execute_statemove(struct jtag_command *cmd) -{ - DEBUG_JTAG_IO("state move to %i", cmd->cmd.statemove->end_state); - - tap_set_end_state(cmd->cmd.statemove->end_state); - - openjtag_set_state(cmd->cmd.statemove->end_state); - - tap_set_state(tap_get_end_state()); -} - - -static void openjtag_execute_scan(struct jtag_command *cmd) -{ - - int scan_size, old_state; - uint8_t *buffer; - - DEBUG_JTAG_IO("scan ends in %s", tap_state_name(cmd->cmd.scan->end_state)); - - /* get scan info */ - tap_set_end_state(cmd->cmd.scan->end_state); - scan_size = jtag_build_buffer(cmd->cmd.scan, &buffer); - -#ifdef _DEBUG_USB_COMMS_ - openjtag_debug_buffer(buffer, (scan_size + 7) / 8, DEBUG_TYPE_BUFFER); -#endif - /* set state */ - old_state = tap_get_end_state(); - openjtag_set_state(cmd->cmd.scan->ir_scan ? TAP_IRSHIFT : TAP_DRSHIFT); - tap_set_state(cmd->cmd.scan->ir_scan ? TAP_IRSHIFT : TAP_DRSHIFT); - tap_set_end_state(old_state); - - openjtag_add_scan(buffer, scan_size, cmd->cmd.scan); - - openjtag_set_state(cmd->cmd.scan->ir_scan ? TAP_IRPAUSE : TAP_DRPAUSE); - tap_set_state(cmd->cmd.scan->ir_scan ? TAP_IRPAUSE : TAP_DRPAUSE); - - if (tap_get_state() != tap_get_end_state()) { - openjtag_set_state(tap_get_end_state()); - tap_set_state(tap_get_end_state()); - } -} - -static void openjtag_execute_runtest(struct jtag_command *cmd) -{ - - tap_state_t end_state = cmd->cmd.runtest->end_state; - tap_set_end_state(end_state); - - /* only do a state_move when we're not already in IDLE */ - if (tap_get_state() != TAP_IDLE) { - openjtag_set_state(TAP_IDLE); - tap_set_state(TAP_IDLE); - } - - 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; - - openjtag_add_byte(command); - - tap_set_end_state(end_state); - if (tap_get_end_state() != tap_get_state()) { - openjtag_set_state(end_state); - tap_set_state(end_state); - } -} - -static void openjtag_execute_command(struct jtag_command *cmd) -{ - DEBUG_JTAG_IO("openjtag_execute_command %i", cmd->type); - switch (cmd->type) { - case JTAG_RESET: - openjtag_execute_reset(cmd); - break; - case JTAG_SLEEP: - openjtag_execute_sleep(cmd); - break; - case JTAG_TLR_RESET: - openjtag_execute_statemove(cmd); - break; - case JTAG_SCAN: - openjtag_execute_scan(cmd); - break; - case JTAG_RUNTEST: - openjtag_execute_runtest(cmd); - break; - case JTAG_PATHMOVE: - /* jlink_execute_pathmove(cmd); break; */ - default: - LOG_ERROR("BUG: unknown Open JTAG command type encountered"); - exit(-1); - } -} - -static int openjtag_execute_queue(void) -{ - struct jtag_command *cmd = jtag_command_queue; - - while (cmd != NULL) { - openjtag_execute_command(cmd); - cmd = cmd->next; - } - - return openjtag_execute_tap_queue(); -} - -static int openjtag_speed_div(int speed, int *khz) -{ - *khz = speed; - - return ERROR_OK; -} - -static int openjtag_khz(int khz, int *jtag_speed) -{ - - if (khz >= 48000) - *jtag_speed = 48000; - else if (khz >= 24000) - *jtag_speed = 24000; - else if (khz >= 12000) - *jtag_speed = 12000; - else if (khz >= 6000) - *jtag_speed = 6000; - else if (khz >= 3000) - *jtag_speed = 3000; - else if (khz >= 1500) - *jtag_speed = 1500; - else if (khz >= 750) - *jtag_speed = 750; - else - *jtag_speed = 375; - - return ERROR_OK; -} - -COMMAND_HANDLER(openjtag_handle_device_desc_command) -{ - if (CMD_ARGC == 1) - openjtag_device_desc = strdup(CMD_ARGV[0]); - else - LOG_ERROR("require exactly one argument to " - "openjtag_device_desc "); - return ERROR_OK; -} - - -static const struct command_registration openjtag_command_handlers[] = { - { - .name = "openjtag_device_desc", - .handler = openjtag_handle_device_desc_command, - .mode = COMMAND_CONFIG, - .help = "set the USB device description of the OpenJTAG", - .usage = "description-string", - }, - COMMAND_REGISTRATION_DONE -}; - -struct jtag_interface openjtag_interface = { - .name = "openjtag", - .commands = openjtag_command_handlers, - - .execute_queue = openjtag_execute_queue, - .speed = openjtag_speed, - .speed_div = openjtag_speed_div, - .khz = openjtag_khz, - .init = openjtag_init, - .quit = openjtag_quit, -}; - - diff --git a/src/jtag/drivers/osbdm.c b/src/jtag/drivers/osbdm.c deleted file mode 100644 index 5db36a122..000000000 --- a/src/jtag/drivers/osbdm.c +++ /dev/null @@ -1,699 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2012 by Jan Dakinevich * - * jan.dakinevich@gmail.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include -#include -#include -#include -#include "libusb_common.h" - -struct sequence { - int len; - void *tms; - void *tdo; - const void *tdi; - struct sequence *next; -}; - -struct queue { - struct sequence *head; - struct sequence *tail; -}; - -static struct sequence *queue_add_tail(struct queue *queue, int len) -{ - if (len <= 0) { - LOG_ERROR("BUG: sequences with zero length are not allowed"); - return NULL; - } - - struct sequence *next; - next = malloc(sizeof(*next)); - if (next) { - next->tms = calloc(1, DIV_ROUND_UP(len, 8)); - if (next->tms) { - next->len = len; - next->tdo = NULL; - next->tdi = NULL; - next->next = NULL; - - if (!queue->head) { - /* Queue is empty at the moment */ - queue->head = next; - } else { - /* Queue already contains at least one sequence */ - queue->tail->next = next; - } - - queue->tail = next; - } else { - free(next); - next = NULL; - } - } - - if (!next) - LOG_ERROR("Not enough memory"); - - return next; -} - -static void queue_drop_head(struct queue *queue) -{ - struct sequence *head = queue->head->next; /* New head */ - free(queue->head->tms); - free(queue->head); - queue->head = head; -} - -static void queue_free(struct queue *queue) -{ - if (queue) { - while (queue->head) - queue_drop_head(queue); - - free(queue); - } -} - -static struct queue *queue_alloc(void) -{ - struct queue *queue = malloc(sizeof(*queue)); - if (queue) - queue->head = NULL; - else - LOG_ERROR("Not enough memory"); - - return queue; -} - -/* Size of usb communication buffer */ -#define OSBDM_USB_BUFSIZE 64 -/* Timeout for USB transfer, ms */ -#define OSBDM_USB_TIMEOUT 1000 -/* Write end point */ -#define OSBDM_USB_EP_WRITE 0x01 -/* Read end point */ -#define OSBDM_USB_EP_READ 0x82 - -/* Initialize OSBDM device */ -#define OSBDM_CMD_INIT 0x11 -/* Execute special, not-BDM command. But only this - * command is used for JTAG operation */ -#define OSBDM_CMD_SPECIAL 0x27 -/* Execute JTAG swap (tms/tdi -> tdo) */ -#define OSBDM_CMD_SPECIAL_SWAP 0x05 -/* Reset control */ -#define OSBDM_CMD_SPECIAL_SRST 0x01 -/* Maximum bit-length in one swap */ -#define OSBDM_SWAP_MAX (((OSBDM_USB_BUFSIZE - 6) / 5) * 16) - -/* Lists of valid VID/PID pairs - */ -static const uint16_t osbdm_vid[] = { 0x15a2, 0x15a2, 0x15a2, 0 }; -static const uint16_t osbdm_pid[] = { 0x0042, 0x0058, 0x005e, 0 }; - -struct osbdm { - struct jtag_libusb_device_handle *devh; /* USB handle */ - uint8_t buffer[OSBDM_USB_BUFSIZE]; /* Data to send and receive */ - int count; /* Count data to send and to read */ -}; - -/* osbdm instance - */ -static struct osbdm osbdm_context; - -static int osbdm_send_and_recv(struct osbdm *osbdm) -{ - /* Send request */ - int count = jtag_libusb_bulk_write(osbdm->devh, OSBDM_USB_EP_WRITE, - (char *)osbdm->buffer, osbdm->count, OSBDM_USB_TIMEOUT); - - if (count != osbdm->count) { - LOG_ERROR("OSBDM communication error: can't write"); - return ERROR_FAIL; - } - - /* Save command code for next checking */ - uint8_t cmd_saved = osbdm->buffer[0]; - - /* Reading answer */ - osbdm->count = jtag_libusb_bulk_read(osbdm->devh, OSBDM_USB_EP_READ, - (char *)osbdm->buffer, OSBDM_USB_BUFSIZE, OSBDM_USB_TIMEOUT); - - /* Now perform basic checks for data sent by BDM device - */ - - if (osbdm->count < 0) { - LOG_ERROR("OSBDM communication error: can't read"); - return ERROR_FAIL; - } - - if (osbdm->count < 2) { - LOG_ERROR("OSBDM communication error: reply too small"); - return ERROR_FAIL; - } - - if (osbdm->count != osbdm->buffer[1]) { - LOG_ERROR("OSBDM communication error: reply size mismatch"); - return ERROR_FAIL; - } - - if (cmd_saved != osbdm->buffer[0]) { - LOG_ERROR("OSBDM communication error: reply command mismatch"); - return ERROR_FAIL; - } - - return ERROR_OK; -} - -static int osbdm_srst(struct osbdm *osbdm, int srst) -{ - osbdm->count = 0; - (void)memset(osbdm->buffer, 0, OSBDM_USB_BUFSIZE); - - /* Composing request - */ - osbdm->buffer[osbdm->count++] = OSBDM_CMD_SPECIAL; /* Command */ - osbdm->buffer[osbdm->count++] = OSBDM_CMD_SPECIAL_SRST; /* Subcommand */ - /* Length in bytes - not used */ - osbdm->buffer[osbdm->count++] = 0; - osbdm->buffer[osbdm->count++] = 0; - /* SRST state */ - osbdm->buffer[osbdm->count++] = (srst ? 0 : 0x08); - - /* Sending data - */ - if (osbdm_send_and_recv(osbdm) != ERROR_OK) - return ERROR_FAIL; - - return ERROR_OK; -} - -static int osbdm_swap(struct osbdm *osbdm, void *tms, void *tdi, - void *tdo, int length) -{ - if (length > OSBDM_SWAP_MAX) { - LOG_ERROR("BUG: bit sequence too long"); - return ERROR_FAIL; - } - - if (length <= 0) { - LOG_ERROR("BUG: bit sequence equal or less than 0"); - return ERROR_FAIL; - } - - int swap_count = DIV_ROUND_UP(length, 16); - - /* cleanup */ - osbdm->count = 0; - (void)memset(osbdm->buffer, 0, OSBDM_USB_BUFSIZE); - - /* Composing request - */ - - osbdm->buffer[osbdm->count++] = OSBDM_CMD_SPECIAL; /* Command */ - osbdm->buffer[osbdm->count++] = OSBDM_CMD_SPECIAL_SWAP; /* Subcommand */ - /* Length in bytes - not used */ - osbdm->buffer[osbdm->count++] = 0; - osbdm->buffer[osbdm->count++] = 0; - /* Swap count */ - osbdm->buffer[osbdm->count++] = 0; - osbdm->buffer[osbdm->count++] = (uint8_t)swap_count; - - for (int bit_idx = 0; bit_idx < length; ) { - /* Bit count in swap */ - int bit_count = length - bit_idx; - if (bit_count > 16) - bit_count = 16; - - osbdm->buffer[osbdm->count++] = (uint8_t)bit_count; - - /* Copying TMS and TDI data to output buffer */ - uint32_t tms_data = buf_get_u32(tms, bit_idx, bit_count); - uint32_t tdi_data = buf_get_u32(tdi, bit_idx, bit_count); - osbdm->buffer[osbdm->count++] = (uint8_t)(tdi_data >> 8); - osbdm->buffer[osbdm->count++] = (uint8_t)tdi_data; - osbdm->buffer[osbdm->count++] = (uint8_t)(tms_data >> 8); - osbdm->buffer[osbdm->count++] = (uint8_t)tms_data; - - /* Next bit offset */ - bit_idx += bit_count; - } - - assert(osbdm->count <= OSBDM_USB_BUFSIZE); - - /* Sending data - */ - if (osbdm_send_and_recv(osbdm) != ERROR_OK) - return ERROR_FAIL; - - /* Extra check - */ - if (((osbdm->buffer[2] << 8) | osbdm->buffer[3]) != 2 * swap_count) { - LOG_ERROR("OSBDM communication error: invalid swap command reply"); - return ERROR_FAIL; - } - - /* Copy TDO responce - */ - uint8_t *buffer = osbdm->buffer + 4; - for (int bit_idx = 0; bit_idx < length; ) { - int bit_count = length - bit_idx; - if (bit_count > 16) - bit_count = 16; - - /* Prepare data */ - uint32_t tdo_data = 0; - tdo_data |= (*buffer++) << 8; - tdo_data |= (*buffer++); - tdo_data >>= (16 - bit_count); - - /* Copy TDO to return */ - buf_set_u32(tdo, bit_idx, bit_count, tdo_data); - - bit_idx += bit_count; - } - - return ERROR_OK; -} - -static int osbdm_flush(struct osbdm *osbdm, struct queue* queue) -{ - uint8_t tms[DIV_ROUND_UP(OSBDM_SWAP_MAX, 8)]; - uint8_t tdi[DIV_ROUND_UP(OSBDM_SWAP_MAX, 8)]; - uint8_t tdo[DIV_ROUND_UP(OSBDM_SWAP_MAX, 8)]; - - int seq_back_len = 0; - - while (queue->head) { - (void)memset(tms, 0, sizeof(tms)); - (void)memset(tdi, 0, sizeof(tdi)); - (void)memset(tdo, 0, sizeof(tdo)); - - int seq_len; - int swap_len; - struct sequence *seq; - - /* Copy from queue to tms/tdi streams - */ - seq = queue->head; - seq_len = seq_back_len; - swap_len = 0; - - while (seq && swap_len != OSBDM_SWAP_MAX) { - /* Count bit for copy at this iteration. - * len should fit into remaining space - * in tms/tdo bitstreams - */ - int len = seq->len - seq_len; - if (len > OSBDM_SWAP_MAX - swap_len) - len = OSBDM_SWAP_MAX - swap_len; - - /* Set tms data */ - buf_set_buf(seq->tms, seq_len, tms, swap_len, len); - - /* Set tdi data if they exists */ - if (seq->tdi) - buf_set_buf(seq->tdi, seq_len, tdi, swap_len, len); - - swap_len += len; - seq_len += len; - if (seq_len == seq->len) { - seq = seq->next; /* Move to next sequence */ - seq_len = 0; - } - } - - if (osbdm_swap(osbdm, tms, tdi, tdo, swap_len)) - return ERROR_FAIL; - - /* Copy from tdo stream to queue - */ - - for (int swap_back_len = 0; swap_back_len < swap_len; ) { - int len = queue->head->len - seq_back_len; - if (len > swap_len - swap_back_len) - len = swap_len - swap_back_len; - - if (queue->head->tdo) - buf_set_buf(tdo, swap_back_len, queue->head->tdo, seq_back_len, len); - - swap_back_len += len; - seq_back_len += len; - if (seq_back_len == queue->head->len) { - queue_drop_head(queue); - seq_back_len = 0; - } - } - } - - return ERROR_OK; -} - -/* Basic operation for opening USB device */ -static int osbdm_open(struct osbdm *osbdm) -{ - (void)memset(osbdm, 0, sizeof(*osbdm)); - if (jtag_libusb_open(osbdm_vid, osbdm_pid, NULL, &osbdm->devh) != ERROR_OK) - return ERROR_FAIL; - - if (jtag_libusb_claim_interface(osbdm->devh, 0) != ERROR_OK) - return ERROR_FAIL; - - return ERROR_OK; -} - -static int osbdm_quit(void) -{ - jtag_libusb_close(osbdm_context.devh); - return ERROR_OK; -} - -static int osbdm_add_pathmove( - struct queue *queue, - tap_state_t *path, - int num_states) -{ - assert(num_states <= 32); - - struct sequence *next = queue_add_tail(queue, num_states); - if (!next) { - LOG_ERROR("BUG: can't allocate bit sequence"); - return ERROR_FAIL; - } - - uint32_t tms = 0; - for (int i = 0; i < num_states; i++) { - if (tap_state_transition(tap_get_state(), 1) == path[i]) { - tms |= (1 << i); - } else if (tap_state_transition(tap_get_state(), 0) == path[i]) { - tms &= ~(1 << i); /* This line not so needed */ - } else { - LOG_ERROR("BUG: %s -> %s isn't a valid TAP state transition", - tap_state_name(tap_get_state()), - tap_state_name(path[i])); - return ERROR_FAIL; - } - - tap_set_state(path[i]); - } - - buf_set_u32(next->tms, 0, num_states, tms); - tap_set_end_state(tap_get_state()); - - return ERROR_OK; -} - -static int osbdm_add_statemove( - struct queue *queue, - tap_state_t new_state, - int skip_first) -{ - int len = 0; - int tms = 0; - - tap_set_end_state(new_state); - if (tap_get_end_state() == TAP_RESET) { - /* Ignore current state */ - tms = 0xff; - len = 5; - } else if (tap_get_state() != tap_get_end_state()) { - tms = tap_get_tms_path(tap_get_state(), new_state); - len = tap_get_tms_path_len(tap_get_state(), new_state); - } - - if (len && skip_first) { - len--; - tms >>= 1; - } - - if (len) { - struct sequence *next = queue_add_tail(queue, len); - if (!next) { - LOG_ERROR("BUG: can't allocate bit sequence"); - return ERROR_FAIL; - } - buf_set_u32(next->tms, 0, len, tms); - } - - tap_set_state(tap_get_end_state()); - return ERROR_OK; -} - -static int osbdm_add_stableclocks( - struct queue *queue, - int count) -{ - if (!tap_is_state_stable(tap_get_state())) { - LOG_ERROR("BUG: current state (%s) is not stable", - tap_state_name(tap_get_state())); - return ERROR_FAIL; - } - - struct sequence *next = queue_add_tail(queue, count); - if (!next) { - LOG_ERROR("BUG: can't allocate bit sequence"); - return ERROR_FAIL; - } - - if (tap_get_state() == TAP_RESET) - (void)memset(next->tms, 0xff, DIV_ROUND_UP(count, 8)); - - return ERROR_OK; -} - -static int osbdm_add_tms( - struct queue *queue, - const uint8_t *tms, - int num_bits) -{ - struct sequence *next = queue_add_tail(queue, num_bits); - if (!next) { - LOG_ERROR("BUG: can't allocate bit sequence"); - return ERROR_FAIL; - } - buf_set_buf(tms, 0, next->tms, 0, num_bits); - - return ERROR_OK; -} - -static int osbdm_add_scan( - struct queue *queue, - struct scan_field *fields, - int num_fields, - tap_state_t end_state, - bool ir_scan) -{ - /* Move to desired shift state */ - if (ir_scan) { - if (tap_get_state() != TAP_IRSHIFT) { - if (osbdm_add_statemove(queue, TAP_IRSHIFT, 0) != ERROR_OK) - return ERROR_FAIL; - } - } else { - if (tap_get_state() != TAP_DRSHIFT) { - if (osbdm_add_statemove(queue, TAP_DRSHIFT, 0) != ERROR_OK) - return ERROR_FAIL; - } - } - - /* Add scan */ - tap_set_end_state(end_state); - for (int idx = 0; idx < num_fields; idx++) { - struct sequence *next = queue_add_tail(queue, fields[idx].num_bits); - if (!next) { - LOG_ERROR("Can't allocate bit sequence"); - return ERROR_FAIL; - } - - (void)memset(next->tms, 0, DIV_ROUND_UP(fields[idx].num_bits, 8)); - next->tdi = fields[idx].out_value; - next->tdo = fields[idx].in_value; - } - - /* Move to end state - */ - if (tap_get_state() != tap_get_end_state()) { - /* Exit from IRSHIFT/DRSHIFT */ - buf_set_u32(queue->tail->tms, queue->tail->len - 1, 1, 1); - - /* Move with skip_first flag */ - if (osbdm_add_statemove(queue, tap_get_end_state(), 1) != ERROR_OK) - return ERROR_FAIL; - } - - return ERROR_OK; -} - -static int osbdm_add_runtest( - struct queue *queue, - int num_cycles, - tap_state_t end_state) -{ - if (osbdm_add_statemove(queue, TAP_IDLE, 0) != ERROR_OK) - return ERROR_FAIL; - - if (osbdm_add_stableclocks(queue, num_cycles) != ERROR_OK) - return ERROR_FAIL; - - if (osbdm_add_statemove(queue, end_state, 0) != ERROR_OK) - return ERROR_FAIL; - - return ERROR_OK; -} - -static int osbdm_execute_command( - struct osbdm *osbdm, - struct queue *queue, - struct jtag_command *cmd) -{ - int retval = ERROR_OK; - - switch (cmd->type) { - case JTAG_RESET: - if (cmd->cmd.reset->trst) { - LOG_ERROR("BUG: nTRST signal is not supported"); - retval = ERROR_FAIL; - } else { - retval = osbdm_flush(osbdm, queue); - if (retval == ERROR_OK) - retval = osbdm_srst(osbdm, cmd->cmd.reset->srst); - } - break; - - case JTAG_PATHMOVE: - retval = osbdm_add_pathmove( - queue, - cmd->cmd.pathmove->path, - cmd->cmd.pathmove->num_states); - break; - - case JTAG_TLR_RESET: - retval = osbdm_add_statemove( - queue, - cmd->cmd.statemove->end_state, - 0); - break; - - case JTAG_STABLECLOCKS: - retval = osbdm_add_stableclocks( - queue, - cmd->cmd.stableclocks->num_cycles); - break; - - case JTAG_TMS: - retval = osbdm_add_tms( - queue, - cmd->cmd.tms->bits, - cmd->cmd.tms->num_bits); - break; - - case JTAG_SCAN: - retval = osbdm_add_scan( - queue, - cmd->cmd.scan->fields, - cmd->cmd.scan->num_fields, - cmd->cmd.scan->end_state, - cmd->cmd.scan->ir_scan); - break; - - case JTAG_SLEEP: - retval = osbdm_flush(osbdm, queue); - if (retval == ERROR_OK) - jtag_sleep(cmd->cmd.sleep->us); - break; - - case JTAG_RUNTEST: - retval = osbdm_add_runtest( - queue, - cmd->cmd.runtest->num_cycles, - cmd->cmd.runtest->end_state); - break; - - default: - LOG_ERROR("BUG: unknown JTAG command type encountered"); - retval = ERROR_FAIL; - break; - } - - return retval; -} - -static int osbdm_execute_queue(void) -{ - int retval = ERROR_OK; - - struct queue *queue = queue_alloc(); - if (!queue) { - LOG_ERROR("BUG: can't allocate bit queue"); - retval = ERROR_FAIL; - } else { - struct jtag_command *cmd = jtag_command_queue; - - while (retval == ERROR_OK && cmd) { - retval = osbdm_execute_command(&osbdm_context, queue, cmd); - cmd = cmd->next; - } - - if (retval == ERROR_OK) - retval = osbdm_flush(&osbdm_context, queue); - - queue_free(queue); - } - - if (retval != ERROR_OK) { - LOG_ERROR("FATAL: can't execute jtag command"); - exit(-1); - } - - return retval; -} - -static int osbdm_init(void) -{ - /* Open device */ - if (osbdm_open(&osbdm_context) != ERROR_OK) { - LOG_ERROR("Can't open OSBDM device"); - return ERROR_FAIL; - } else { - /* Device successfully opened */ - LOG_DEBUG("OSBDM init"); - } - - /* Perform initialize command */ - osbdm_context.count = 0; - osbdm_context.buffer[osbdm_context.count++] = OSBDM_CMD_INIT; - if (osbdm_send_and_recv(&osbdm_context) != ERROR_OK) - return ERROR_FAIL; - - return ERROR_OK; -} - -struct jtag_interface osbdm_interface = { - .name = "osbdm", - - .transports = jtag_only, - .execute_queue = osbdm_execute_queue, - - .init = osbdm_init, - .quit = osbdm_quit -}; diff --git a/src/jtag/drivers/parport.c b/src/jtag/drivers/parport.c deleted file mode 100644 index c9e331644..000000000 --- a/src/jtag/drivers/parport.c +++ /dev/null @@ -1,518 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * Copyright (C) 2008 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include "bitbang.h" - -/* -ino: 060521-1036 */ -#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) -#include -#include -#define ioperm(startport, length, enable)\ - i386_set_ioperm((startport), (length), (enable)) -#endif /* __FreeBSD__ */ - -#if PARPORT_USE_PPDEV == 1 -#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) -#include -#include -#define PPRSTATUS PPIGSTATUS -#define PPWDATA PPISDATA -#else -#include -#include -#endif -#include -#else /* not PARPORT_USE_PPDEV */ -#ifndef _WIN32 -#include -#endif -#endif - -#if PARPORT_USE_GIVEIO == 1 && IS_CYGWIN == 1 -#include -#endif - -/* parallel port cable description - */ -struct cable { - const char *name; - uint8_t TDO_MASK; /* status port bit containing current TDO value */ - uint8_t TRST_MASK; /* data port bit for TRST */ - uint8_t TMS_MASK; /* data port bit for TMS */ - uint8_t TCK_MASK; /* data port bit for TCK */ - uint8_t TDI_MASK; /* data port bit for TDI */ - uint8_t SRST_MASK; /* data port bit for SRST */ - uint8_t OUTPUT_INVERT; /* data port bits that should be inverted */ - uint8_t INPUT_INVERT; /* status port that should be inverted */ - uint8_t PORT_INIT; /* initialize data port with this value */ - uint8_t PORT_EXIT; /* de-initialize data port with this value */ - uint8_t LED_MASK; /* data port bit for LED */ -}; - -static const struct cable cables[] = { - /* name tdo trst tms tck tdi srst o_inv i_inv init exit led */ - { "wiggler", 0x80, 0x10, 0x02, 0x04, 0x08, 0x01, 0x01, 0x80, 0x80, 0x80, 0x00 }, - { "wiggler2", 0x80, 0x10, 0x02, 0x04, 0x08, 0x01, 0x01, 0x80, 0x80, 0x00, 0x20 }, - { "wiggler_ntrst_inverted", 0x80, 0x10, 0x02, 0x04, 0x08, 0x01, 0x11, 0x80, 0x80, 0x80, 0x00 }, - { "old_amt_wiggler", 0x80, 0x01, 0x02, 0x04, 0x08, 0x10, 0x11, 0x80, 0x80, 0x80, 0x00 }, - { "arm-jtag", 0x80, 0x01, 0x02, 0x04, 0x08, 0x10, 0x01, 0x80, 0x80, 0x80, 0x00 }, - { "chameleon", 0x80, 0x00, 0x04, 0x01, 0x02, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00 }, - { "dlc5", 0x10, 0x00, 0x04, 0x02, 0x01, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00 }, - { "triton", 0x80, 0x08, 0x04, 0x01, 0x02, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00 }, - { "lattice", 0x40, 0x10, 0x04, 0x02, 0x01, 0x08, 0x00, 0x00, 0x18, 0x18, 0x00 }, - { "flashlink", 0x20, 0x10, 0x02, 0x01, 0x04, 0x20, 0x30, 0x20, 0x00, 0x00, 0x00 }, -/* Altium Universal JTAG cable. Set the cable to Xilinx Mode and wire to target as follows: - HARD TCK - Target TCK - HARD TMS - Target TMS - HARD TDI - Target TDI - HARD TDO - Target TDO - SOFT TCK - Target TRST - SOFT TDI - Target SRST -*/ - { "altium", 0x10, 0x20, 0x04, 0x02, 0x01, 0x80, 0x00, 0x00, 0x10, 0x00, 0x08 }, - { "aspo", 0x10, 0x01, 0x04, 0x08, 0x02, 0x10, 0x17, 0x00, 0x17, 0x17, 0x00 }, - { NULL, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } -}; - -/* configuration */ -static char *parport_cable; -static uint16_t parport_port; -static bool parport_exit; -static uint32_t parport_toggling_time_ns = 1000; -static int wait_states; - -/* interface variables - */ -static const struct cable *cable; -static uint8_t dataport_value; - -#if PARPORT_USE_PPDEV == 1 -static int device_handle; -#else -static unsigned long dataport; -static unsigned long statusport; -#endif - -static int parport_read(void) -{ - int data = 0; - -#if PARPORT_USE_PPDEV == 1 - ioctl(device_handle, PPRSTATUS, &data); -#else - data = inb(statusport); -#endif - - if ((data ^ cable->INPUT_INVERT) & cable->TDO_MASK) - return 1; - else - return 0; -} - -static inline void parport_write_data(void) -{ - uint8_t output; - output = dataport_value ^ cable->OUTPUT_INVERT; - -#if PARPORT_USE_PPDEV == 1 - ioctl(device_handle, PPWDATA, &output); -#else -#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) - outb(dataport, output); -#else - outb(output, dataport); -#endif -#endif -} - -static void parport_write(int tck, int tms, int tdi) -{ - int i = wait_states + 1; - - if (tck) - dataport_value |= cable->TCK_MASK; - else - dataport_value &= ~cable->TCK_MASK; - - if (tms) - dataport_value |= cable->TMS_MASK; - else - dataport_value &= ~cable->TMS_MASK; - - if (tdi) - dataport_value |= cable->TDI_MASK; - else - dataport_value &= ~cable->TDI_MASK; - - while (i-- > 0) - parport_write_data(); -} - -/* (1) assert or (0) deassert reset lines */ -static void parport_reset(int trst, int srst) -{ - LOG_DEBUG("trst: %i, srst: %i", trst, srst); - - if (trst == 0) - dataport_value |= cable->TRST_MASK; - else if (trst == 1) - dataport_value &= ~cable->TRST_MASK; - - if (srst == 0) - dataport_value |= cable->SRST_MASK; - else if (srst == 1) - dataport_value &= ~cable->SRST_MASK; - - parport_write_data(); -} - -/* turn LED on parport adapter on (1) or off (0) */ -static void parport_led(int on) -{ - if (on) - dataport_value |= cable->LED_MASK; - else - dataport_value &= ~cable->LED_MASK; - - parport_write_data(); -} - -static int parport_speed(int speed) -{ - wait_states = speed; - return ERROR_OK; -} - -static int parport_khz(int khz, int *jtag_speed) -{ - if (khz == 0) { - LOG_DEBUG("RCLK not supported"); - return ERROR_FAIL; - } - - *jtag_speed = 499999 / (khz * parport_toggling_time_ns); - return ERROR_OK; -} - -static int parport_speed_div(int speed, int *khz) -{ - uint32_t denominator = (speed + 1) * parport_toggling_time_ns; - - *khz = (499999 + denominator) / denominator; - return ERROR_OK; -} - -#if PARPORT_USE_GIVEIO == 1 -static int parport_get_giveio_access(void) -{ - HANDLE h; - OSVERSIONINFO version; - - version.dwOSVersionInfoSize = sizeof version; - if (!GetVersionEx(&version)) { - errno = EINVAL; - return -1; - } - if (version.dwPlatformId != VER_PLATFORM_WIN32_NT) - return 0; - - h = CreateFile("\\\\.\\giveio", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); - if (h == INVALID_HANDLE_VALUE) { - errno = ENODEV; - return -1; - } - - CloseHandle(h); - - return 0; -} -#endif - -static struct bitbang_interface parport_bitbang = { - .read = &parport_read, - .write = &parport_write, - .reset = &parport_reset, - .blink = &parport_led, - }; - -static int parport_init(void) -{ - const struct cable *cur_cable; -#if PARPORT_USE_PPDEV == 1 - char buffer[256]; -#endif - - cur_cable = cables; - - if (parport_cable == NULL) { - parport_cable = strdup("wiggler"); - LOG_WARNING("No parport cable specified, using default 'wiggler'"); - } - - while (cur_cable->name) { - if (strcmp(cur_cable->name, parport_cable) == 0) { - cable = cur_cable; - break; - } - cur_cable++; - } - - if (!cable) { - LOG_ERROR("No matching cable found for %s", parport_cable); - return ERROR_JTAG_INIT_FAILED; - } - - dataport_value = cable->PORT_INIT; - -#if PARPORT_USE_PPDEV == 1 - if (device_handle > 0) { - LOG_ERROR("device is already opened"); - return ERROR_JTAG_INIT_FAILED; - } - -#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) - LOG_DEBUG("opening /dev/ppi%d...", parport_port); - - snprintf(buffer, 256, "/dev/ppi%d", parport_port); - device_handle = open(buffer, O_WRONLY); -#else /* not __FreeBSD__, __FreeBSD_kernel__ */ - LOG_DEBUG("opening /dev/parport%d...", parport_port); - - snprintf(buffer, 256, "/dev/parport%d", parport_port); - device_handle = open(buffer, O_WRONLY); -#endif /* __FreeBSD__, __FreeBSD_kernel__ */ - - if (device_handle < 0) { - int err = errno; - LOG_ERROR("cannot open device. check it exists and that user read and write rights are set. errno=%d", err); - return ERROR_JTAG_INIT_FAILED; - } - - LOG_DEBUG("...open"); - -#if !defined(__FreeBSD__) && !defined(__FreeBSD_kernel__) - int i = ioctl(device_handle, PPCLAIM); - - if (i < 0) { - LOG_ERROR("cannot claim device"); - return ERROR_JTAG_INIT_FAILED; - } - - i = PARPORT_MODE_COMPAT; - i = ioctl(device_handle, PPSETMODE, &i); - if (i < 0) { - LOG_ERROR(" cannot set compatible mode to device"); - return ERROR_JTAG_INIT_FAILED; - } - - i = IEEE1284_MODE_COMPAT; - i = ioctl(device_handle, PPNEGOT, &i); - if (i < 0) { - LOG_ERROR("cannot set compatible 1284 mode to device"); - return ERROR_JTAG_INIT_FAILED; - } -#endif /* not __FreeBSD__, __FreeBSD_kernel__ */ - -#else /* not PARPORT_USE_PPDEV */ - if (parport_port == 0) { - parport_port = 0x378; - LOG_WARNING("No parport port specified, using default '0x378' (LPT1)"); - } - - dataport = parport_port; - statusport = parport_port + 1; - - LOG_DEBUG("requesting privileges for parallel port 0x%lx...", dataport); -#if PARPORT_USE_GIVEIO == 1 - if (parport_get_giveio_access() != 0) { -#else /* PARPORT_USE_GIVEIO */ - if (ioperm(dataport, 3, 1) != 0) { -#endif /* PARPORT_USE_GIVEIO */ - LOG_ERROR("missing privileges for direct i/o"); - return ERROR_JTAG_INIT_FAILED; - } - LOG_DEBUG("...privileges granted"); - - /* make sure parallel port is in right mode (clear tristate and interrupt */ - #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) - outb(parport_port + 2, 0x0); - #else - outb(0x0, parport_port + 2); - #endif - -#endif /* PARPORT_USE_PPDEV */ - - parport_reset(0, 0); - parport_write(0, 0, 0); - parport_led(1); - - bitbang_interface = &parport_bitbang; - - return ERROR_OK; -} - -static int parport_quit(void) -{ - parport_led(0); - - if (parport_exit) { - dataport_value = cable->PORT_EXIT; - parport_write_data(); - } - - if (parport_cable) { - free(parport_cable); - parport_cable = NULL; - } - - return ERROR_OK; -} - -COMMAND_HANDLER(parport_handle_parport_port_command) -{ - if (CMD_ARGC == 1) { - /* only if the port wasn't overwritten by cmdline */ - if (parport_port == 0) - COMMAND_PARSE_NUMBER(u16, CMD_ARGV[0], parport_port); - else { - LOG_ERROR("The parport port was already configured!"); - return ERROR_FAIL; - } - } - - command_print(CMD_CTX, "parport port = 0x%" PRIx16 "", parport_port); - - return ERROR_OK; -} - -COMMAND_HANDLER(parport_handle_parport_cable_command) -{ - if (CMD_ARGC == 0) - return ERROR_OK; - - /* only if the cable name wasn't overwritten by cmdline */ - if (parport_cable == 0) { - /* REVISIT first verify that it's listed in cables[] ... */ - parport_cable = malloc(strlen(CMD_ARGV[0]) + sizeof(char)); - strcpy(parport_cable, CMD_ARGV[0]); - } - - /* REVISIT it's probably worth returning the current value ... */ - - return ERROR_OK; -} - -COMMAND_HANDLER(parport_handle_write_on_exit_command) -{ - if (CMD_ARGC != 1) - return ERROR_COMMAND_SYNTAX_ERROR; - - COMMAND_PARSE_ON_OFF(CMD_ARGV[0], parport_exit); - - return ERROR_OK; -} - -COMMAND_HANDLER(parport_handle_parport_toggling_time_command) -{ - if (CMD_ARGC == 1) { - uint32_t ns; - int retval = parse_u32(CMD_ARGV[0], &ns); - - if (ERROR_OK != retval) - return retval; - - if (ns == 0) { - LOG_ERROR("0 ns is not a valid parport toggling time"); - return ERROR_FAIL; - } - - parport_toggling_time_ns = ns; - retval = jtag_get_speed(&wait_states); - if (retval != ERROR_OK) { - /* if jtag_get_speed fails then the clock_mode - * has not been configured, this happens if parport_toggling_time is - * called before the adapter speed is set */ - LOG_INFO("no parport speed set - defaulting to zero wait states"); - wait_states = 0; - } - } - - command_print(CMD_CTX, "parport toggling time = %" PRIu32 " ns", - parport_toggling_time_ns); - - return ERROR_OK; -} - -static const struct command_registration parport_command_handlers[] = { - { - .name = "parport_port", - .handler = parport_handle_parport_port_command, - .mode = COMMAND_CONFIG, - .help = "Display the address of the I/O port (e.g. 0x378) " - "or the number of the '/dev/parport' device used. " - "If a parameter is provided, first change that port.", - .usage = "[port_number]", - }, - { - .name = "parport_cable", - .handler = parport_handle_parport_cable_command, - .mode = COMMAND_CONFIG, - .help = "Set the layout of the parallel port cable " - "used to connect to the target.", - /* REVISIT there's no way to list layouts we know ... */ - .usage = "[layout]", - }, - { - .name = "parport_write_on_exit", - .handler = parport_handle_write_on_exit_command, - .mode = COMMAND_CONFIG, - .help = "Configure the parallel driver to write " - "a known value to the parallel interface on exit.", - .usage = "('on'|'off')", - }, - { - .name = "parport_toggling_time", - .handler = parport_handle_parport_toggling_time_command, - .mode = COMMAND_CONFIG, - .help = "Displays or assigns how many nanoseconds it " - "takes for the hardware to toggle TCK.", - .usage = "[nanoseconds]", - }, - COMMAND_REGISTRATION_DONE -}; - -struct jtag_interface parport_interface = { - .name = "parport", - .supported = DEBUG_CAP_TMS_SEQ, - .commands = parport_command_handlers, - - .init = parport_init, - .quit = parport_quit, - .khz = parport_khz, - .speed_div = parport_speed_div, - .speed = parport_speed, - .execute_queue = bitbang_execute_queue, -}; diff --git a/src/jtag/drivers/presto.c b/src/jtag/drivers/presto.c deleted file mode 100644 index 0a18dc9c4..000000000 --- a/src/jtag/drivers/presto.c +++ /dev/null @@ -1,794 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Pavel Chromy * - * chromy@asix.cz * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -/** - * @file - * Holds driver for PRESTO programmer from ASIX. - * http://tools.asix.net/prg_presto.htm - */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#if IS_CYGWIN == 1 -#include "windows.h" -#endif - -#include -#include -#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 - -/* -------------------------------------------------------------------------- */ - -#define FT_DEVICE_NAME_LEN 64 -#define FT_DEVICE_SERNUM_LEN 64 - -#define PRESTO_VID_PID 0x0403f1a0 -#define PRESTO_VID (0x0403) -#define PRESTO_PID (0xf1a0) - -#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]; - - uint8_t buff_out[BUFFER_SIZE]; - int buff_out_pos; - - uint8_t buff_in[BUFFER_SIZE]; - int buff_in_exp;/* expected in buffer length */ - int buff_in_len;/* length of data received */ - int buff_in_pos; - - unsigned long total_out; - unsigned long total_in; - - int jtag_tms; /* last tms state */ - int jtag_tck; /* last tck state */ - int jtag_rst; /* last trst state */ - - int jtag_tdi_data; - int jtag_tdi_count; - - int jtag_speed; -}; - -static struct presto presto_state; -static struct presto *presto = &presto_state; - -static uint8_t presto_init_seq[] = { - 0x80, 0xA0, 0xA8, 0xB0, 0xC0, 0xE0 -}; - -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) { - LOG_ERROR("ftdi_write_data: %s", ftdi_get_error_string(&presto->ftdic)); - 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)", - (unsigned)ftbytes, (unsigned)size); - return ERROR_JTAG_DEVICE_ERROR; - } - - return ERROR_OK; -} - -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; - gettimeofday(&timeout, NULL); - timeval_add_time(&timeout, 1, 0); /* one second timeout */ - - while (ftbytes < size) { - presto->retval = ftdi_read_data(&presto->ftdic, buf + ftbytes, size - ftbytes); - if (presto->retval < 0) { - LOG_ERROR("ftdi_read_data: %s", ftdi_get_error_string(&presto->ftdic)); - return ERROR_JTAG_DEVICE_ERROR; - } - ftbytes += presto->retval; - - gettimeofday(&now, NULL); - if ((now.tv_sec > timeout.tv_sec) || - ((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, - *which is not fatal */ - LOG_WARNING("couldn't read the requested number of bytes from PRESTO (%u < %u)", - (unsigned)ftbytes, (unsigned)size); - return ERROR_JTAG_DEVICE_ERROR; - } - - 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; - - LOG_DEBUG("searching for PRESTO using libftdi"); - - /* initialize FTDI context structure */ - if (ftdi_init(&presto->ftdic) < 0) { - LOG_ERROR("unable to init libftdi: %s", presto->ftdic.error_str); - return ERROR_JTAG_DEVICE_ERROR; - } - - /* context, vendor id, product id */ - if (ftdi_usb_open_desc(&presto->ftdic, PRESTO_VID, PRESTO_PID, NULL, req_serial) < 0) { - LOG_ERROR("unable to open PRESTO: %s", presto->ftdic.error_str); - return ERROR_JTAG_DEVICE_ERROR; - } - - if (ftdi_usb_reset(&presto->ftdic) < 0) { - LOG_ERROR("unable to reset PRESTO device"); - return ERROR_JTAG_DEVICE_ERROR; - } - - if (ftdi_set_latency_timer(&presto->ftdic, 1) < 0) { - LOG_ERROR("unable to set latency timer"); - return ERROR_JTAG_DEVICE_ERROR; - } - - if (ftdi_usb_purge_buffers(&presto->ftdic) < 0) { - LOG_ERROR("unable to purge PRESTO buffers"); - return ERROR_JTAG_DEVICE_ERROR; - } - - presto_data = 0xD0; - if (presto_write(&presto_data, 1) != ERROR_OK) { - LOG_ERROR("error writing to PRESTO"); - return ERROR_JTAG_DEVICE_ERROR; - } - - if (presto_read(&presto_data, 1) != ERROR_OK) { - LOG_DEBUG("no response from PRESTO, retrying"); - - if (ftdi_usb_purge_buffers(&presto->ftdic) < 0) - return ERROR_JTAG_DEVICE_ERROR; - - presto_data = 0xD0; - if (presto_write(&presto_data, 1) != ERROR_OK) - return ERROR_JTAG_DEVICE_ERROR; - - if (presto_read(&presto_data, 1) != ERROR_OK) { - LOG_ERROR("no response from PRESTO, giving up"); - return ERROR_JTAG_DEVICE_ERROR; - } - } - - if (presto_write(presto_init_seq, sizeof(presto_init_seq)) != ERROR_OK) { - LOG_ERROR("error writing PRESTO init sequence"); - return ERROR_JTAG_DEVICE_ERROR; - } - - return ERROR_OK; -} -#endif /* BUILD_PRESTO_LIBFTDI == 1 */ - -static int presto_open(char *req_serial) -{ - presto->buff_out_pos = 0; - presto->buff_in_pos = 0; - presto->buff_in_len = 0; - presto->buff_in_exp = 0; - - presto->total_out = 0; - presto->total_in = 0; - - presto->jtag_tms = 0; - presto->jtag_tck = 0; - presto->jtag_rst = 0; - presto->jtag_tdi_data = 0; - presto->jtag_tdi_count = 0; - - 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) -{ - - 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; - - presto->retval = ftdi_set_latency_timer(&presto->ftdic, 16); - if (presto->retval < 0) - result = ERROR_JTAG_DEVICE_ERROR; - - presto->retval = ftdi_usb_close(&presto->ftdic); - if (presto->retval < 0) - result = ERROR_JTAG_DEVICE_ERROR; - else - ftdi_deinit(&presto->ftdic); -#endif - - return result; -} - -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; - } - - if (presto_write(presto->buff_out, presto->buff_out_pos) != ERROR_OK) { - presto->buff_out_pos = 0; - return ERROR_JTAG_DEVICE_ERROR; - } - - presto->total_out += presto->buff_out_pos; - presto->buff_out_pos = 0; - - if (presto->buff_in_exp == 0) - return ERROR_OK; - - presto->buff_in_pos = 0; - presto->buff_in_len = 0; - - if (presto_read(presto->buff_in, presto->buff_in_exp) != ERROR_OK) { - presto->buff_in_exp = 0; - return ERROR_JTAG_DEVICE_ERROR; - } - - presto->total_in += presto->buff_in_exp; - presto->buff_in_len = presto->buff_in_exp; - presto->buff_in_exp = 0; - - return ERROR_OK; -} - -static int presto_sendbyte(int data) -{ - if (data == EOF) - return presto_flush(); - - if (presto->buff_out_pos < BUFFER_SIZE) { - presto->buff_out[presto->buff_out_pos++] = (uint8_t)data; - if (((data & 0xC0) == 0x40) || ((data & 0xD0) == 0xD0)) - presto->buff_in_exp++; - } 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; -} - -#if 0 -static int presto_getbyte(void) -{ - if (presto->buff_in_pos < presto->buff_in_len) - return presto->buff_in[presto->buff_in_pos++]; - - if (presto->buff_in_exp == 0) - return -1; - - if (presto_flush() != ERROR_OK) - return -1; - - if (presto->buff_in_pos < presto->buff_in_len) - return presto->buff_in[presto->buff_in_pos++]; - - return -1; -} -#endif - -/* -------------------------------------------------------------------------- */ - -static int presto_tdi_flush(void) -{ - if (presto->jtag_tdi_count == 0) - return 0; - - if (presto->jtag_tck == 0) { - LOG_ERROR("BUG: unexpected TAP condition, TCK low"); - return -1; - } - - presto->jtag_tdi_data |= (presto->jtag_tdi_count - 1) << 4; - presto_sendbyte(presto->jtag_tdi_data); - presto->jtag_tdi_count = 0; - presto->jtag_tdi_data = 0; - - return 0; -} - -static int presto_tck_idle(void) -{ - if (presto->jtag_tck == 1) { - presto_sendbyte(0xCA); - presto->jtag_tck = 0; - } - - return 0; -} - -/* -------------------------------------------------------------------------- */ - -static int presto_bitq_out(int tms, int tdi, int tdo_req) -{ - int i; - unsigned char cmd; - - if (presto->jtag_tck == 0) - presto_sendbyte(0xA4); /* LED idicator - JTAG active */ - else if (presto->jtag_speed == 0 && !tdo_req && tms == presto->jtag_tms) { - presto->jtag_tdi_data |= (tdi != 0) << presto->jtag_tdi_count; - - if (++presto->jtag_tdi_count == 4) - presto_tdi_flush(); - - return 0; - } - - presto_tdi_flush(); - - cmd = tdi ? 0xCB : 0xCA; - presto_sendbyte(cmd); - - if (tms != presto->jtag_tms) { - presto_sendbyte((tms ? 0xEC : 0xE8) | (presto->jtag_rst ? 0x02 : 0)); - presto->jtag_tms = tms; - } - - /* delay with TCK low */ - for (i = presto->jtag_speed; i > 1; i--) - presto_sendbyte(cmd); - - cmd |= 0x04; - presto_sendbyte(cmd | (tdo_req ? 0x10 : 0)); - - /* delay with TCK high */ - for (i = presto->jtag_speed; i > 1; i--) - presto_sendbyte(cmd); - - presto->jtag_tck = 1; - - return 0; -} - -static int presto_bitq_flush(void) -{ - presto_tdi_flush(); - presto_tck_idle(); - - presto_sendbyte(0xA0); /* LED idicator - JTAG idle */ - - return presto_flush(); -} - -static int presto_bitq_in_rdy(void) -{ - if (presto->buff_in_pos >= presto->buff_in_len) - return 0; - return presto->buff_in_len-presto->buff_in_pos; -} - -static int presto_bitq_in(void) -{ - if (presto->buff_in_pos >= presto->buff_in_len) - return -1; - if (presto->buff_in[presto->buff_in_pos++]&0x08) - return 1; - return 0; -} - -static int presto_bitq_sleep(unsigned long us) -{ - long waits; - - presto_tdi_flush(); - presto_tck_idle(); - - if (us > 100000) { - presto_bitq_flush(); - jtag_sleep(us); - return 0; - } - - waits = us / 170 + 2; - while (waits--) - presto_sendbyte(0x80); - - return 0; -} - -static int presto_bitq_reset(int trst, int srst) -{ - presto_tdi_flush(); - presto_tck_idle(); - - /* add a delay after possible TCK transition */ - presto_sendbyte(0x80); - presto_sendbyte(0x80); - - presto->jtag_rst = trst || srst; - presto_sendbyte((presto->jtag_rst ? 0xEA : 0xE8) | (presto->jtag_tms ? 0x04 : 0)); - - return 0; -} - -static struct bitq_interface presto_bitq = { - .out = &presto_bitq_out, - .flush = &presto_bitq_flush, - .sleep = &presto_bitq_sleep, - .reset = &presto_bitq_reset, - .in_rdy = &presto_bitq_in_rdy, - .in = &presto_bitq_in, -}; - -/* -------------------------------------------------------------------------- */ - -static int presto_adapter_khz(int khz, int *jtag_speed) -{ - if (khz < 0) { - *jtag_speed = 0; - return ERROR_COMMAND_SYNTAX_ERROR; - } - - if (khz >= 3000) - *jtag_speed = 0; - else - *jtag_speed = (1000 + khz-1)/khz; - - return 0; -} - -static int presto_jtag_speed_div(int speed, int *khz) -{ - if ((speed < 0) || (speed > 1000)) { - *khz = 0; - return ERROR_COMMAND_SYNTAX_ERROR; - } - - if (speed == 0) - *khz = 3000; - else - *khz = 1000/speed; - - return 0; -} - -static int presto_jtag_speed(int speed) -{ - int khz; - - if (presto_jtag_speed_div(speed, &khz)) - return ERROR_COMMAND_SYNTAX_ERROR; - - presto->jtag_speed = speed; - - if (khz%1000 == 0) - LOG_INFO("setting speed to %d, max. TCK freq. is %d MHz", speed, khz/1000); - else - LOG_INFO("setting speed to %d, max. TCK freq. is %d kHz", speed, khz); - - return 0; -} - -static char *presto_serial; - -COMMAND_HANDLER(presto_handle_serial_command) -{ - if (CMD_ARGC == 1) { - if (presto_serial) - free(presto_serial); - presto_serial = strdup(CMD_ARGV[0]); - } else - return ERROR_COMMAND_SYNTAX_ERROR; - - return ERROR_OK; -} - -static const struct command_registration presto_command_handlers[] = { - { - .name = "presto_serial", - .handler = presto_handle_serial_command, - .mode = COMMAND_CONFIG, - .help = "Configure USB serial number of Presto device.", - .usage = "serial_string", - }, - COMMAND_REGISTRATION_DONE -}; - -static int presto_jtag_init(void) -{ - if (presto_open(presto_serial) != ERROR_OK) { - presto_close(); - if (presto_serial != NULL) - LOG_ERROR("Cannot open PRESTO, serial number '%s'", presto_serial); - else - LOG_ERROR("Cannot open PRESTO"); - return ERROR_JTAG_INIT_FAILED; - } - LOG_INFO("PRESTO open, serial number '%s'", presto->serial); - - bitq_interface = &presto_bitq; - return ERROR_OK; -} - -static int presto_jtag_quit(void) -{ - bitq_cleanup(); - presto_close(); - LOG_INFO("PRESTO closed"); - - if (presto_serial) { - free(presto_serial); - presto_serial = NULL; - } - - return ERROR_OK; -} - -struct jtag_interface presto_interface = { - .name = "presto", - .commands = presto_command_handlers, - - .execute_queue = bitq_execute_queue, - .speed = presto_jtag_speed, - .khz = presto_adapter_khz, - .speed_div = presto_jtag_speed_div, - .init = presto_jtag_init, - .quit = presto_jtag_quit, -}; diff --git a/src/jtag/drivers/remote_bitbang.c b/src/jtag/drivers/remote_bitbang.c deleted file mode 100644 index c8d013666..000000000 --- a/src/jtag/drivers/remote_bitbang.c +++ /dev/null @@ -1,280 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2011 by Richard Uhler * - * ruhler@mit.edu * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#ifndef _WIN32 -#include -#include -#endif -#include -#include "bitbang.h" - -/* arbitrary limit on host name length: */ -#define REMOTE_BITBANG_HOST_MAX 255 - -#define REMOTE_BITBANG_RAISE_ERROR(expr ...) \ - do { \ - LOG_ERROR(expr); \ - LOG_ERROR("Terminating openocd."); \ - exit(-1); \ - } while (0) - -static char *remote_bitbang_host; -static char *remote_bitbang_port; - -FILE *remote_bitbang_in; -FILE *remote_bitbang_out; - -static void remote_bitbang_putc(int c) -{ - if (EOF == fputc(c, remote_bitbang_out)) - REMOTE_BITBANG_RAISE_ERROR("remote_bitbang_putc: %s", strerror(errno)); -} - -static int remote_bitbang_quit(void) -{ - if (EOF == fputc('Q', remote_bitbang_out)) { - LOG_ERROR("fputs: %s", strerror(errno)); - return ERROR_FAIL; - } - - if (EOF == fflush(remote_bitbang_out)) { - LOG_ERROR("fflush: %s", strerror(errno)); - return ERROR_FAIL; - } - - /* We only need to close one of the FILE*s, because they both use the same */ - /* underlying file descriptor. */ - if (EOF == fclose(remote_bitbang_out)) { - LOG_ERROR("fclose: %s", strerror(errno)); - return ERROR_FAIL; - } - - free(remote_bitbang_host); - free(remote_bitbang_port); - - LOG_INFO("remote_bitbang interface quit"); - return ERROR_OK; -} - -/* Get the next read response. */ -static int remote_bitbang_rread(void) -{ - if (EOF == fflush(remote_bitbang_out)) { - remote_bitbang_quit(); - REMOTE_BITBANG_RAISE_ERROR("fflush: %s", strerror(errno)); - } - - int c = fgetc(remote_bitbang_in); - switch (c) { - case '0': - return 0; - case '1': - return 1; - default: - remote_bitbang_quit(); - REMOTE_BITBANG_RAISE_ERROR( - "remote_bitbang: invalid read response: %c(%i)", c, c); - } -} - -static int remote_bitbang_read(void) -{ - remote_bitbang_putc('R'); - return remote_bitbang_rread(); -} - -static void remote_bitbang_write(int tck, int tms, int tdi) -{ - char c = '0' + ((tck ? 0x4 : 0x0) | (tms ? 0x2 : 0x0) | (tdi ? 0x1 : 0x0)); - remote_bitbang_putc(c); -} - -static void remote_bitbang_reset(int trst, int srst) -{ - char c = 'r' + ((trst ? 0x2 : 0x0) | (srst ? 0x1 : 0x0)); - remote_bitbang_putc(c); -} - -static void remote_bitbang_blink(int on) -{ - char c = on ? 'B' : 'b'; - remote_bitbang_putc(c); -} - -static struct bitbang_interface remote_bitbang_bitbang = { - .read = &remote_bitbang_read, - .write = &remote_bitbang_write, - .reset = &remote_bitbang_reset, - .blink = &remote_bitbang_blink, -}; - -static int remote_bitbang_init_tcp(void) -{ - struct addrinfo hints = { .ai_family = AF_UNSPEC, .ai_socktype = SOCK_STREAM }; - struct addrinfo *result, *rp; - int fd; - - LOG_INFO("Connecting to %s:%s", - remote_bitbang_host ? remote_bitbang_host : "localhost", - remote_bitbang_port); - - /* Obtain address(es) matching host/port */ - int s = getaddrinfo(remote_bitbang_host, remote_bitbang_port, &hints, &result); - if (s != 0) { - LOG_ERROR("getaddrinfo: %s\n", gai_strerror(s)); - return ERROR_FAIL; - } - - /* getaddrinfo() returns a list of address structures. - Try each address until we successfully connect(2). - If socket(2) (or connect(2)) fails, we (close the socket - and) try the next address. */ - - for (rp = result; rp != NULL ; rp = rp->ai_next) { - fd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); - if (fd == -1) - continue; - - if (connect(fd, rp->ai_addr, rp->ai_addrlen) != -1) - break; /* Success */ - - close(fd); - } - - freeaddrinfo(result); /* No longer needed */ - - if (rp == NULL) { /* No address succeeded */ - LOG_ERROR("Failed to connect: %s", strerror(errno)); - return ERROR_FAIL; - } - - return fd; -} - -static int remote_bitbang_init_unix(void) -{ - if (remote_bitbang_host == NULL) { - LOG_ERROR("host/socket not specified"); - return ERROR_FAIL; - } - - LOG_INFO("Connecting to unix socket %s", remote_bitbang_host); - int fd = socket(PF_UNIX, SOCK_STREAM, 0); - if (fd < 0) { - LOG_ERROR("socket: %s", strerror(errno)); - return ERROR_FAIL; - } - - struct sockaddr_un addr; - addr.sun_family = AF_UNIX; - strncpy(addr.sun_path, remote_bitbang_host, sizeof(addr.sun_path)); - addr.sun_path[sizeof(addr.sun_path)-1] = '\0'; - - if (connect(fd, (struct sockaddr *)&addr, sizeof(struct sockaddr_un)) < 0) { - LOG_ERROR("connect: %s", strerror(errno)); - return ERROR_FAIL; - } - - return fd; -} - -static int remote_bitbang_init(void) -{ - int fd; - bitbang_interface = &remote_bitbang_bitbang; - - LOG_INFO("Initializing remote_bitbang driver"); - if (remote_bitbang_port == NULL) - fd = remote_bitbang_init_unix(); - else - fd = remote_bitbang_init_tcp(); - - if (fd < 0) - return fd; - - remote_bitbang_in = fdopen(fd, "r"); - if (remote_bitbang_in == NULL) { - LOG_ERROR("fdopen: failed to open read stream"); - close(fd); - return ERROR_FAIL; - } - - remote_bitbang_out = fdopen(fd, "w"); - if (remote_bitbang_out == NULL) { - LOG_ERROR("fdopen: failed to open write stream"); - fclose(remote_bitbang_in); - return ERROR_FAIL; - } - - LOG_INFO("remote_bitbang driver initialized"); - return ERROR_OK; -} - -COMMAND_HANDLER(remote_bitbang_handle_remote_bitbang_port_command) -{ - if (CMD_ARGC == 1) { - uint16_t port; - COMMAND_PARSE_NUMBER(u16, CMD_ARGV[0], port); - free(remote_bitbang_port); - remote_bitbang_port = port == 0 ? NULL : strdup(CMD_ARGV[0]); - return ERROR_OK; - } - return ERROR_COMMAND_SYNTAX_ERROR; -} - -COMMAND_HANDLER(remote_bitbang_handle_remote_bitbang_host_command) -{ - if (CMD_ARGC == 1) { - free(remote_bitbang_host); - remote_bitbang_host = strdup(CMD_ARGV[0]); - return ERROR_OK; - } - return ERROR_COMMAND_SYNTAX_ERROR; -} - -static const struct command_registration remote_bitbang_command_handlers[] = { - { - .name = "remote_bitbang_port", - .handler = remote_bitbang_handle_remote_bitbang_port_command, - .mode = COMMAND_CONFIG, - .help = "Set the port to use to connect to the remote jtag.\n" - " if 0 or unset, use unix sockets to connect to the remote jtag.", - .usage = "port_number", - }, - { - .name = "remote_bitbang_host", - .handler = remote_bitbang_handle_remote_bitbang_host_command, - .mode = COMMAND_CONFIG, - .help = "Set the host to use to connect to the remote jtag.\n" - " if port is 0 or unset, this is the name of the unix socket to use.", - .usage = "host_name", - }, - COMMAND_REGISTRATION_DONE, -}; - -struct jtag_interface remote_bitbang_interface = { - .name = "remote_bitbang", - .execute_queue = &bitbang_execute_queue, - .commands = remote_bitbang_command_handlers, - .init = &remote_bitbang_init, - .quit = &remote_bitbang_quit, -}; diff --git a/src/jtag/drivers/rlink.c b/src/jtag/drivers/rlink.c deleted file mode 100644 index 3f9e33268..000000000 --- a/src/jtag/drivers/rlink.c +++ /dev/null @@ -1,1683 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * Copyright (C) 2007,2008 Øyvind Harboe * - * oyvind.harboe@zylin.com * - * * - * Copyright (C) 2008 Rob Brown, Lou Deluxe * - * rob@cobbleware.com, lou.openocd012@fixit.nospammail.net * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -/* project specific includes */ -#include -#include -#include "rlink.h" -#include "rlink_st7.h" -#include "rlink_ep1_cmd.h" -#include "rlink_dtc_cmd.h" -#include "usb_common.h" - -/* This feature is made useless by running the DTC all the time. When automatic, the LED is on - *whenever the DTC is running. Otherwise, USB messages are sent to turn it on and off. */ -#undef AUTOMATIC_BUSY_LED - -/* This feature may require derating the speed due to reduced hold time. */ -#undef USE_HARDWARE_SHIFTER_FOR_TMS - -#define INTERFACE_NAME "RLink" - -#define USB_IDVENDOR (0x138e) -#define USB_IDPRODUCT (0x9000) - -#define USB_EP1OUT_ADDR (0x01) -#define USB_EP1OUT_SIZE (16) -#define USB_EP1IN_ADDR (USB_EP1OUT_ADDR | 0x80) -#define USB_EP1IN_SIZE (USB_EP1OUT_SIZE) - -#define USB_EP2OUT_ADDR (0x02) -#define USB_EP2OUT_SIZE (64) -#define USB_EP2IN_ADDR (USB_EP2OUT_ADDR | 0x80) -#define USB_EP2IN_SIZE (USB_EP2OUT_SIZE) -#define USB_EP2BANK_SIZE (512) - -#define USB_TIMEOUT_MS (3 * 1000) - -#define DTC_STATUS_POLL_BYTE (ST7_USB_BUF_EP0OUT + 0xff) - -#define ST7_PD_NBUSY_LED ST7_PD0 -#define ST7_PD_NRUN_LED ST7_PD1 -/* low enables VPP at adapter header, high connects it to GND instead */ -#define ST7_PD_VPP_SEL ST7_PD6 -/* low: VPP = 12v, high: VPP <= 5v */ -#define ST7_PD_VPP_SHDN ST7_PD7 - -/* These pins are connected together */ -#define ST7_PE_ADAPTER_SENSE_IN ST7_PE3 -#define ST7_PE_ADAPTER_SENSE_OUT ST7_PE4 - -/* Symbolic mapping between port pins and numbered IO lines */ -#define ST7_PA_IO1 ST7_PA1 -#define ST7_PA_IO2 ST7_PA2 -#define ST7_PA_IO4 ST7_PA4 -#define ST7_PA_IO8 ST7_PA6 -#define ST7_PA_IO10 ST7_PA7 -#define ST7_PB_IO5 ST7_PB5 -#define ST7_PC_IO9 ST7_PC1 -#define ST7_PC_IO3 ST7_PC2 -#define ST7_PC_IO7 ST7_PC3 -#define ST7_PE_IO6 ST7_PE5 - -/* Symbolic mapping between numbered IO lines and adapter signals */ -#define ST7_PA_RTCK ST7_PA_IO0 -#define ST7_PA_NTRST ST7_PA_IO1 -#define ST7_PC_TDI ST7_PC_IO3 -#define ST7_PA_DBGRQ ST7_PA_IO4 -#define ST7_PB_NSRST ST7_PB_IO5 -#define ST7_PE_TMS ST7_PE_IO6 -#define ST7_PC_TCK ST7_PC_IO7 -#define ST7_PC_TDO ST7_PC_IO9 -#define ST7_PA_DBGACK ST7_PA_IO10 - -static usb_dev_handle *pHDev; - -/* - * ep1 commands are up to USB_EP1OUT_SIZE bytes in length. - * This function takes care of zeroing the unused bytes before sending the packet. - * Any reply packet is not handled by this function. - */ -static int ep1_generic_commandl(usb_dev_handle *pHDev_param, size_t length, ...) -{ - uint8_t usb_buffer[USB_EP1OUT_SIZE]; - uint8_t *usb_buffer_p; - va_list ap; - int usb_ret; - - if (length > sizeof(usb_buffer)) - length = sizeof(usb_buffer); - - usb_buffer_p = usb_buffer; - - va_start(ap, length); - while (length > 0) { - *usb_buffer_p++ = va_arg(ap, int); - length--; - } - - memset( - usb_buffer_p, - 0, - sizeof(usb_buffer) - (usb_buffer_p - usb_buffer) - ); - - usb_ret = usb_bulk_write( - pHDev_param, - USB_EP1OUT_ADDR, - (char *)usb_buffer, sizeof(usb_buffer), - USB_TIMEOUT_MS - ); - - return usb_ret; -} - -#if 0 -static ssize_t ep1_memory_read( - usb_dev_handle *pHDev, uint16_t addr, - size_t length, uint8_t *buffer) -{ - uint8_t usb_buffer[USB_EP1OUT_SIZE]; - int usb_ret; - size_t remain; - ssize_t count; - - usb_buffer[0] = EP1_CMD_MEMORY_READ; - memset( - usb_buffer + 4, - 0, - sizeof(usb_buffer) - 4 - ); - - remain = length; - count = 0; - - while (remain) { - if (remain > sizeof(usb_buffer)) - length = sizeof(usb_buffer); - else - length = remain; - - usb_buffer[1] = addr >> 8; - usb_buffer[2] = addr; - usb_buffer[3] = length; - - usb_ret = usb_bulk_write( - pHDev, USB_EP1OUT_ADDR, - usb_buffer, sizeof(usb_buffer), - USB_TIMEOUT_MS - ); - - if (usb_ret < sizeof(usb_buffer)) - break; - - usb_ret = usb_bulk_read( - pHDev, USB_EP1IN_ADDR, - buffer, length, - USB_TIMEOUT_MS - ); - - if (usb_ret < length) - break; - - addr += length; - buffer += length; - count += length; - remain -= length; - } - - return count; -} -#endif - -static ssize_t ep1_memory_write(usb_dev_handle *pHDev_param, uint16_t addr, - size_t length, uint8_t const *buffer) -{ - uint8_t usb_buffer[USB_EP1OUT_SIZE]; - int usb_ret; - size_t remain; - ssize_t count; - - usb_buffer[0] = EP1_CMD_MEMORY_WRITE; - - remain = length; - count = 0; - - while (remain) { - if (remain > (sizeof(usb_buffer) - 4)) - length = (sizeof(usb_buffer) - 4); - else - length = remain; - - usb_buffer[1] = addr >> 8; - usb_buffer[2] = addr; - usb_buffer[3] = length; - memcpy( - usb_buffer + 4, - buffer, - length - ); - memset( - usb_buffer + 4 + length, - 0, - sizeof(usb_buffer) - 4 - length - ); - - usb_ret = usb_bulk_write( - pHDev_param, USB_EP1OUT_ADDR, - (char *)usb_buffer, sizeof(usb_buffer), - USB_TIMEOUT_MS - ); - - if ((size_t)usb_ret < sizeof(usb_buffer)) - break; - - addr += length; - buffer += length; - count += length; - remain -= length; - } - - return count; -} - - -#if 0 -static ssize_t ep1_memory_writel(usb_dev_handle *pHDev, uint16_t addr, - size_t length, ...) -{ - uint8_t buffer[USB_EP1OUT_SIZE - 4]; - uint8_t *buffer_p; - va_list ap; - size_t remain; - - if (length > sizeof(buffer)) - length = sizeof(buffer); - - remain = length; - buffer_p = buffer; - - va_start(ap, length); - while (remain > 0) { - *buffer_p++ = va_arg(ap, int); - remain--; - } - - return ep1_memory_write(pHDev, addr, length, buffer); -} -#endif - -#define DTCLOAD_COMMENT (0) -#define DTCLOAD_ENTRY (1) -#define DTCLOAD_LOAD (2) -#define DTCLOAD_RUN (3) -#define DTCLOAD_LUT_START (4) -#define DTCLOAD_LUT (5) - -#define DTC_LOAD_BUFFER ST7_USB_BUF_EP2UIDO - -/* This gets set by the DTC loader */ -static uint8_t dtc_entry_download; - -/* The buffer is specially formatted to represent a valid image to load into the DTC. */ -static int dtc_load_from_buffer(usb_dev_handle *pHDev_param, const uint8_t *buffer, - size_t length) -{ - struct header_s { - uint8_t type; - uint8_t length; - }; - - int usb_err; - struct header_s *header; - uint8_t lut_start = 0xc0; - - dtc_entry_download = 0; - - /* Stop the DTC before loading anything. */ - usb_err = ep1_generic_commandl( - pHDev_param, 1, - EP1_CMD_DTC_STOP - ); - if (usb_err < 0) - return usb_err; - - while (length) { - if (length < sizeof(*header)) { - LOG_ERROR("Malformed DTC image"); - exit(1); - } - - header = (struct header_s *)buffer; - buffer += sizeof(*header); - length -= sizeof(*header); - - if (length < (size_t)header->length + 1) { - LOG_ERROR("Malformed DTC image"); - exit(1); - } - - switch (header->type) { - case DTCLOAD_COMMENT: - break; - - case DTCLOAD_ENTRY: - /* store entry addresses somewhere */ - if (!strncmp("download", (char *)buffer + 1, 8)) - dtc_entry_download = buffer[0]; - break; - - case DTCLOAD_LOAD: - /* Send the DTC program to ST7 RAM. */ - usb_err = ep1_memory_write( - pHDev_param, - DTC_LOAD_BUFFER, - header->length + 1, buffer - ); - if (usb_err < 0) - return usb_err; - - /* Load it into the DTC. */ - usb_err = ep1_generic_commandl( - pHDev_param, 3, - EP1_CMD_DTC_LOAD, - (DTC_LOAD_BUFFER >> 8), - DTC_LOAD_BUFFER - ); - if (usb_err < 0) - return usb_err; - - break; - - case DTCLOAD_RUN: - usb_err = ep1_generic_commandl( - pHDev_param, 3, - EP1_CMD_DTC_CALL, - buffer[0], - EP1_CMD_DTC_WAIT - ); - if (usb_err < 0) - return usb_err; - - break; - - case DTCLOAD_LUT_START: - lut_start = buffer[0]; - break; - - case DTCLOAD_LUT: - usb_err = ep1_memory_write( - pHDev_param, - ST7_USB_BUF_EP0OUT + lut_start, - header->length + 1, buffer - ); - if (usb_err < 0) - return usb_err; - break; - - default: - LOG_ERROR("Invalid DTC image record type: 0x%02x", header->type); - exit(1); - break; - } - - buffer += (header->length + 1); - length -= (header->length + 1); - } - - return 0; -} - -/* - * Start the DTC running in download mode (waiting for 512 byte command packets on ep2). - */ -static int dtc_start_download(void) -{ - int usb_err; - uint8_t ep2txr; - - /* set up for download mode and make sure EP2 is set up to transmit */ - usb_err = ep1_generic_commandl( - pHDev, 7, - - EP1_CMD_DTC_STOP, - EP1_CMD_SET_UPLOAD, - EP1_CMD_SET_DOWNLOAD, - EP1_CMD_MEMORY_READ, /* read EP2TXR for its data toggle */ - ST7_EP2TXR >> 8, - ST7_EP2TXR, - 1 - ); - if (usb_err < 0) - return usb_err; - - /* read back ep2txr */ - usb_err = usb_bulk_read( - pHDev, USB_EP1IN_ADDR, - (char *)&ep2txr, 1, - USB_TIMEOUT_MS - ); - if (usb_err < 0) - return usb_err; - - usb_err = ep1_generic_commandl( - pHDev, 13, - - EP1_CMD_MEMORY_WRITE, /* preinitialize poll byte */ - DTC_STATUS_POLL_BYTE >> 8, - DTC_STATUS_POLL_BYTE, - 1, - 0x00, - EP1_CMD_MEMORY_WRITE, /* set EP2IN to return data */ - ST7_EP2TXR >> 8, - ST7_EP2TXR, - 1, - (ep2txr & ST7_EP2TXR_DTOG_TX) | ST7_EP2TXR_STAT_VALID, - EP1_CMD_DTC_CALL, /* start running the DTC */ - dtc_entry_download, - EP1_CMD_DTC_GET_CACHED_STATUS - ); - if (usb_err < 0) - return usb_err; - - /* wait for completion */ - usb_err = usb_bulk_read( - pHDev, USB_EP1IN_ADDR, - (char *)&ep2txr, 1, - USB_TIMEOUT_MS - ); - - return usb_err; -} - -static int dtc_run_download( - usb_dev_handle *pHDev_param, - uint8_t *command_buffer, - int command_buffer_size, - uint8_t *reply_buffer, - int reply_buffer_size - ) -{ - char dtc_status; - int usb_err; - int i; - - LOG_DEBUG("%d/%d", command_buffer_size, reply_buffer_size); - - usb_err = usb_bulk_write( - pHDev_param, - USB_EP2OUT_ADDR, - (char *)command_buffer, USB_EP2BANK_SIZE, - USB_TIMEOUT_MS - ); - if (usb_err < 0) - return usb_err; - - - /* Wait for DTC to finish running command buffer */ - for (i = 50;; ) { - usb_err = ep1_generic_commandl( - pHDev_param, 4, - - EP1_CMD_MEMORY_READ, - DTC_STATUS_POLL_BYTE >> 8, - DTC_STATUS_POLL_BYTE, - 1 - ); - if (usb_err < 0) - return usb_err; - - usb_err = usb_bulk_read( - pHDev_param, - USB_EP1IN_ADDR, - &dtc_status, 1, - USB_TIMEOUT_MS - ); - if (usb_err < 0) - return usb_err; - - if (dtc_status & 0x01) - break; - - if (!--i) { - LOG_ERROR("too many retries waiting for DTC status"); - return -ETIMEDOUT; - } - } - - - if (reply_buffer && reply_buffer_size) { - usb_err = usb_bulk_read( - pHDev_param, - USB_EP2IN_ADDR, - (char *)reply_buffer, reply_buffer_size, - USB_TIMEOUT_MS - ); - - if (usb_err < reply_buffer_size) { - LOG_ERROR("Read of endpoint 2 returned %d, expected %d", - usb_err, reply_buffer_size - ); - return usb_err; - } - } - - return usb_err; -} - -/* - * The dtc reply queue is a singly linked list that describes what to do - * with the reply packet that comes from the DTC. Only SCAN_IN and SCAN_IO generate - * these entries. - */ - -struct dtc_reply_queue_entry { - struct dtc_reply_queue_entry *next; - struct jtag_command *cmd; /* the command that resulted in this entry */ - - struct { - uint8_t *buffer; /* the scan buffer */ - int size; /* size of the scan buffer in bits */ - int offset; /* how many bits were already done before this? */ - int length; /* how many bits are processed in this operation? */ - enum scan_type type; /* SCAN_IN/SCAN_OUT/SCAN_IO */ - } scan; -}; - - -/* - * The dtc_queue consists of a buffer of pending commands and a reply queue. - * rlink_scan and tap_state_run add to the command buffer and maybe to the reply queue. - */ - -static struct { - struct dtc_reply_queue_entry *rq_head; - struct dtc_reply_queue_entry *rq_tail; - uint32_t cmd_index; - uint32_t reply_index; - uint8_t cmd_buffer[USB_EP2BANK_SIZE]; -} dtc_queue; - -/* - * The tap state queue is for accumulating TAP state changes wiithout needlessly - * flushing the dtc_queue. When it fills or is run, it adds the accumulated bytes to - * the dtc_queue. - */ - -static struct { - uint32_t length; - uint32_t buffer; -} tap_state_queue; - -static int dtc_queue_init(void) -{ - dtc_queue.rq_head = NULL; - dtc_queue.rq_tail = NULL; - dtc_queue.cmd_index = 0; - dtc_queue.reply_index = 0; - return 0; -} - -static inline struct dtc_reply_queue_entry *dtc_queue_enqueue_reply( - enum scan_type type, uint8_t *buffer, int size, int offset, - int length, struct jtag_command *cmd) -{ - struct dtc_reply_queue_entry *rq_entry; - - rq_entry = malloc(sizeof(struct dtc_reply_queue_entry)); - if (rq_entry != NULL) { - rq_entry->scan.type = type; - rq_entry->scan.buffer = buffer; - rq_entry->scan.size = size; - rq_entry->scan.offset = offset; - rq_entry->scan.length = length; - rq_entry->cmd = cmd; - rq_entry->next = NULL; - - if (dtc_queue.rq_head == NULL) - dtc_queue.rq_head = rq_entry; - else - dtc_queue.rq_tail->next = rq_entry; - - dtc_queue.rq_tail = rq_entry; - } - - return rq_entry; -} - -/* - * Running the queue means that any pending command buffer is run - * and any reply data dealt with. The command buffer is then cleared for subsequent processing. - * The queue is automatically run by append when it is necessary to get space for the append. - */ - -static int dtc_queue_run(void) -{ - struct dtc_reply_queue_entry *rq_p, *rq_next; - int retval; - int usb_err; - int bit_cnt; - int x; - uint8_t *dtc_p, *tdo_p; - uint8_t dtc_mask, tdo_mask; - uint8_t reply_buffer[USB_EP2IN_SIZE]; - - assert((dtc_queue.rq_head != 0) == (dtc_queue.reply_index > 0)); - assert(dtc_queue.cmd_index < USB_EP2BANK_SIZE); - assert(dtc_queue.reply_index <= USB_EP2IN_SIZE); - - retval = ERROR_OK; - - if (dtc_queue.cmd_index < 1) - return retval; - - dtc_queue.cmd_buffer[dtc_queue.cmd_index++] = DTC_CMD_STOP; - - usb_err = dtc_run_download(pHDev, - dtc_queue.cmd_buffer, dtc_queue.cmd_index, - reply_buffer, sizeof(reply_buffer) - ); - if (usb_err < 0) { - LOG_ERROR("dtc_run_download: %s", usb_strerror()); - exit(1); - } - - if (dtc_queue.rq_head != NULL) { - /* process the reply, which empties the reply queue and frees its entries */ - dtc_p = reply_buffer; - - /* The rigamarole with the masks and doing it bit-by-bit is due to the fact that the - *scan buffer is LSb-first and the DTC code is MSb-first for hardware reasons. It - *was that or craft a function to do the reversal, and that wouldn't work with - *bit-stuffing (supplying extra bits to use mostly byte operations), or any other - *scheme which would throw the byte alignment off. */ - - for ( - rq_p = dtc_queue.rq_head; - rq_p != NULL; - rq_p = rq_next - ) { - tdo_p = rq_p->scan.buffer + (rq_p->scan.offset / 8); - tdo_mask = 1 << (rq_p->scan.offset % 8); - - - bit_cnt = rq_p->scan.length; - if (bit_cnt >= 8) { - /* bytes */ - - dtc_mask = 1 << (8 - 1); - - for ( - ; - bit_cnt; - bit_cnt-- - ) { - if (*dtc_p & dtc_mask) - *tdo_p |= tdo_mask; - else - *tdo_p &= ~tdo_mask; - - dtc_mask >>= 1; - if (dtc_mask == 0) { - dtc_p++; - dtc_mask = 1 << (8 - 1); - } - - tdo_mask <<= 1; - if (tdo_mask == 0) { - tdo_p++; - tdo_mask = 1; - } - } - } else { - /* extra bits or last bit */ - - x = *dtc_p++; - if ((rq_p->scan.type == SCAN_IN) && ( - rq_p->scan.offset != rq_p->scan.size - 1 - )) { - /* extra bits were sent as a full byte with padding on the - *end */ - dtc_mask = 1 << (8 - 1); - } else - dtc_mask = 1 << (bit_cnt - 1); - - for ( - ; - bit_cnt; - bit_cnt-- - ) { - if (x & dtc_mask) - *tdo_p |= tdo_mask; - else - *tdo_p &= ~tdo_mask; - - dtc_mask >>= 1; - - tdo_mask <<= 1; - if (tdo_mask == 0) { - tdo_p++; - tdo_mask = 1; - } - - } - } - - if ((rq_p->scan.offset + rq_p->scan.length) >= rq_p->scan.size) { - /* feed scan buffer back into openocd and free it */ - if (jtag_read_buffer(rq_p->scan.buffer, - rq_p->cmd->cmd.scan) != ERROR_OK) - retval = ERROR_JTAG_QUEUE_FAILED; - free(rq_p->scan.buffer); - } - - rq_next = rq_p->next; - free(rq_p); - } - dtc_queue.rq_head = NULL; - dtc_queue.rq_tail = NULL; - } - - /* reset state for new appends */ - dtc_queue.cmd_index = 0; - dtc_queue.reply_index = 0; - - return retval; -} - -/* runs the queue if it cannot take reserved_cmd bytes of command data - * or reserved_reply bytes of reply data */ -static int dtc_queue_run_if_full(int reserved_cmd, int reserved_reply) -{ - /* reserve one additional byte for the STOP cmd appended during run */ - if (dtc_queue.cmd_index + reserved_cmd + 1 > USB_EP2BANK_SIZE) - return dtc_queue_run(); - - if (dtc_queue.reply_index + reserved_reply > USB_EP2IN_SIZE) - return dtc_queue_run(); - - return ERROR_OK; -} - -static int tap_state_queue_init(void) -{ - tap_state_queue.length = 0; - tap_state_queue.buffer = 0; - return 0; -} - -static int tap_state_queue_run(void) -{ - int i; - int bits; - uint8_t byte_param; - int retval; - - retval = 0; - if (!tap_state_queue.length) - return retval; - bits = 1; - byte_param = 0; - for (i = tap_state_queue.length; i--; ) { - - byte_param <<= 1; - if (tap_state_queue.buffer & 1) - byte_param |= 1; - if ((bits >= 8) || !i) { - byte_param <<= (8 - bits); - - /* make sure there's room for two cmd bytes */ - dtc_queue_run_if_full(2, 0); - -#ifdef USE_HARDWARE_SHIFTER_FOR_TMS - if (bits == 8) { - dtc_queue.cmd_buffer[dtc_queue.cmd_index++] = - DTC_CMD_SHIFT_TMS_BYTES(1); - } else { -#endif - dtc_queue.cmd_buffer[dtc_queue.cmd_index++] = - DTC_CMD_SHIFT_TMS_BITS(bits); -#ifdef USE_HARDWARE_SHIFTER_FOR_TMS - } -#endif - - dtc_queue.cmd_buffer[dtc_queue.cmd_index++] = - byte_param; - - byte_param = 0; - bits = 1; - } else - bits++; - - tap_state_queue.buffer >>= 1; - } - retval = tap_state_queue_init(); - return retval; -} - -static int tap_state_queue_append(uint8_t tms) -{ - int retval; - - if (tap_state_queue.length >= sizeof(tap_state_queue.buffer) * 8) { - retval = tap_state_queue_run(); - if (retval != 0) - return retval; - } - - if (tms) - tap_state_queue.buffer |= (1 << tap_state_queue.length); - tap_state_queue.length++; - - return 0; -} - -static void rlink_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); - } -} - -static void rlink_state_move(void) -{ - - int i = 0, tms = 0; - uint8_t tms_scan = tap_get_tms_path(tap_get_state(), tap_get_end_state()); - int tms_count = tap_get_tms_path_len(tap_get_state(), tap_get_end_state()); - - for (i = 0; i < tms_count; i++) { - tms = (tms_scan >> i) & 1; - tap_state_queue_append(tms); - } - - tap_set_state(tap_get_end_state()); -} - -static void rlink_path_move(struct pathmove_command *cmd) -{ - int num_states = cmd->num_states; - int state_count; - int tms = 0; - - state_count = 0; - while (num_states) { - if (tap_state_transition(tap_get_state(), false) == cmd->path[state_count]) - tms = 0; - else if (tap_state_transition(tap_get_state(), true) == cmd->path[state_count]) - tms = 1; - else { - LOG_ERROR("BUG: %s -> %s isn't a valid TAP transition", - tap_state_name(tap_get_state()), - tap_state_name(cmd->path[state_count])); - exit(-1); - } - - tap_state_queue_append(tms); - - tap_set_state(cmd->path[state_count]); - state_count++; - num_states--; - } - - tap_set_end_state(tap_get_state()); -} - -static void rlink_runtest(int num_cycles) -{ - int i; - - tap_state_t saved_end_state = tap_get_end_state(); - - /* only do a state_move when we're not already in RTI */ - if (tap_get_state() != TAP_IDLE) { - rlink_end_state(TAP_IDLE); - rlink_state_move(); - } - - /* execute num_cycles */ - for (i = 0; i < num_cycles; i++) - tap_state_queue_append(0); - - /* finish in end_state */ - rlink_end_state(saved_end_state); - if (tap_get_state() != tap_get_end_state()) - rlink_state_move(); -} - -/* (1) assert or (0) deassert reset lines */ -static void rlink_reset(int trst, int srst) -{ - uint8_t bitmap; - int usb_err; - - /* Read port A for bit op */ - usb_err = ep1_generic_commandl( - pHDev, 4, - EP1_CMD_MEMORY_READ, - ST7_PADR >> 8, - ST7_PADR, - 1 - ); - if (usb_err < 0) { - LOG_ERROR("%s", usb_strerror()); - exit(1); - } - - usb_err = usb_bulk_read( - pHDev, USB_EP1IN_ADDR, - (char *)&bitmap, 1, - USB_TIMEOUT_MS - ); - if (usb_err < 1) { - LOG_ERROR("%s", usb_strerror()); - exit(1); - } - - if (trst) - bitmap &= ~ST7_PA_NTRST; - else - bitmap |= ST7_PA_NTRST; - - /* Write port A and read port B for bit op - * port B has no OR, and we want to emulate open drain on NSRST, so we initialize DR to 0 - *and assert NSRST by setting DDR to 1. */ - usb_err = ep1_generic_commandl( - pHDev, 9, - EP1_CMD_MEMORY_WRITE, - ST7_PADR >> 8, - ST7_PADR, - 1, - bitmap, - EP1_CMD_MEMORY_READ, - ST7_PBDDR >> 8, - ST7_PBDDR, - 1 - ); - if (usb_err < 0) { - LOG_ERROR("%s", usb_strerror()); - exit(1); - } - - usb_err = usb_bulk_read( - pHDev, USB_EP1IN_ADDR, - (char *)&bitmap, 1, - USB_TIMEOUT_MS - ); - if (usb_err < 1) { - LOG_ERROR("%s", usb_strerror()); - exit(1); - } - - if (srst) - bitmap |= ST7_PB_NSRST; - else - bitmap &= ~ST7_PB_NSRST; - - /* write port B and read dummy to ensure completion before returning */ - usb_err = ep1_generic_commandl( - pHDev, 6, - EP1_CMD_MEMORY_WRITE, - ST7_PBDDR >> 8, - ST7_PBDDR, - 1, - bitmap, - EP1_CMD_DTC_GET_CACHED_STATUS - ); - if (usb_err < 0) { - LOG_ERROR("%s", usb_strerror()); - exit(1); - } - - usb_err = usb_bulk_read( - pHDev, USB_EP1IN_ADDR, - (char *)&bitmap, 1, - USB_TIMEOUT_MS - ); - if (usb_err < 1) { - LOG_ERROR("%s", usb_strerror()); - exit(1); - } -} - -static int rlink_scan(struct jtag_command *cmd, enum scan_type type, - uint8_t *buffer, int scan_size) -{ - bool ir_scan; - tap_state_t saved_end_state; - int byte_bits; - int extra_bits; - int chunk_bits; - int chunk_bytes; - int x; - - int tdi_bit_offset; - uint8_t tdi_mask, *tdi_p; - uint8_t dtc_mask; - - if (scan_size < 1) { - LOG_ERROR("scan_size cannot be less than 1 bit"); - exit(1); - } - - ir_scan = cmd->cmd.scan->ir_scan; - - /* Move to the proper state before starting to shift TDI/TDO. */ - if (!((!ir_scan && (tap_get_state() == TAP_DRSHIFT)) || - (ir_scan && (tap_get_state() == TAP_IRSHIFT)))) { - saved_end_state = tap_get_end_state(); - rlink_end_state(ir_scan ? TAP_IRSHIFT : TAP_DRSHIFT); - rlink_state_move(); - rlink_end_state(saved_end_state); - } - - tap_state_queue_run(); - - -#if 0 - printf("scan_size = %d, type = 0x%x\n", scan_size, type); - { - int i; - - /* clear unused bits in scan buffer for ease of debugging - * (it makes diffing output easier) */ - buffer[scan_size / 8] &= ((1 << ((scan_size - 1) % 8) + 1) - 1); - - printf("before scan:"); - for (i = 0; i < (scan_size + 7) / 8; i++) - printf(" %02x", buffer[i]); - printf("\n"); - } -#endif - - /* The number of bits that can be shifted as complete bytes */ - byte_bits = (int)(scan_size - 1) / 8 * 8; - /* The number of bits left over, not counting the last bit */ - extra_bits = (scan_size - 1) - byte_bits; - - tdi_bit_offset = 0; - tdi_p = buffer; - tdi_mask = 1; - - if (extra_bits && (type == SCAN_OUT)) { - /* Schedule any extra bits into the DTC command buffer, padding as needed - * For SCAN_OUT, this comes before the full bytes so the (leading) padding bits will - *fall off the end */ - - /* make sure there's room for two cmd bytes */ - dtc_queue_run_if_full(2, 0); - - x = 0; - dtc_mask = 1 << (extra_bits - 1); - - while (extra_bits--) { - if (*tdi_p & tdi_mask) - x |= dtc_mask; - - dtc_mask >>= 1; - - tdi_mask <<= 1; - if (tdi_mask == 0) { - tdi_p++; - tdi_mask = 1; - } - } - - dtc_queue.cmd_buffer[dtc_queue.cmd_index++] = - DTC_CMD_SHIFT_TDI_BYTES(1); - - dtc_queue.cmd_buffer[dtc_queue.cmd_index++] = x; - } - - /* Loop scheduling full bytes into the DTC command buffer */ - while (byte_bits) { - /* make sure there's room for one (for in scans) or two cmd bytes and - * at least one reply byte for in or inout scans*/ - dtc_queue_run_if_full(type == SCAN_IN ? 1 : 2, type != SCAN_OUT ? 1 : 0); - - chunk_bits = byte_bits; - /* we can only use up to 16 bytes at a time */ - if (chunk_bits > (16 * 8)) - chunk_bits = (16 * 8); - - if (type != SCAN_IN) { - /* how much is there room for, considering stop and byte op? */ - x = (sizeof(dtc_queue.cmd_buffer) - (dtc_queue.cmd_index + 1 + 1)) * 8; - if (chunk_bits > x) - chunk_bits = x; - } - - if (type != SCAN_OUT) { - /* how much is there room for in the reply buffer? */ - x = (USB_EP2IN_SIZE - dtc_queue.reply_index) * 8; - if (chunk_bits > x) - chunk_bits = x; - } - - /* so the loop will end */ - byte_bits -= chunk_bits; - - if (type != SCAN_OUT) { - if (dtc_queue_enqueue_reply( - type, buffer, scan_size, tdi_bit_offset, - chunk_bits, - cmd - ) == NULL) { - LOG_ERROR("enqueuing DTC reply entry: %s", strerror(errno)); - exit(1); - } - dtc_queue.reply_index += (chunk_bits + 7) / 8; - - tdi_bit_offset += chunk_bits; - } - - /* chunk_bits is a multiple of 8, so there are no rounding issues. */ - chunk_bytes = chunk_bits / 8; - - switch (type) { - case SCAN_IN: - x = DTC_CMD_SHIFT_TDO_BYTES(chunk_bytes); - break; - case SCAN_OUT: - x = DTC_CMD_SHIFT_TDI_BYTES(chunk_bytes); - break; - default: - x = DTC_CMD_SHIFT_TDIO_BYTES(chunk_bytes); - break; - } - dtc_queue.cmd_buffer[dtc_queue.cmd_index++] = x; - - if (type != SCAN_IN) { - x = 0; - dtc_mask = 1 << (8 - 1); - - while (chunk_bits--) { - if (*tdi_p & tdi_mask) - x |= dtc_mask; - - dtc_mask >>= 1; - if (dtc_mask == 0) { - dtc_queue.cmd_buffer[dtc_queue.cmd_index++] = x; - x = 0; - dtc_mask = 1 << (8 - 1); - } - - tdi_mask <<= 1; - if (tdi_mask == 0) { - tdi_p++; - tdi_mask = 1; - } - } - } - } - - if (extra_bits && (type != SCAN_OUT)) { - /* Schedule any extra bits into the DTC command buffer */ - - /* make sure there's room for one (for in scans) or two cmd bytes - * and one reply byte */ - dtc_queue_run_if_full(type == SCAN_IN ? 1 : 2, 1); - - if (dtc_queue_enqueue_reply( - type, buffer, scan_size, tdi_bit_offset, - extra_bits, - cmd - ) == NULL) { - LOG_ERROR("enqueuing DTC reply entry: %s", strerror(errno)); - exit(1); - } - - dtc_queue.reply_index++; - - tdi_bit_offset += extra_bits; - - if (type == SCAN_IN) { - dtc_queue.cmd_buffer[dtc_queue.cmd_index++] = - DTC_CMD_SHIFT_TDO_BYTES(1); - - } else { - dtc_queue.cmd_buffer[dtc_queue.cmd_index++] = - DTC_CMD_SHIFT_TDIO_BITS(extra_bits); - - x = 0; - dtc_mask = 1 << (8 - 1); - - while (extra_bits--) { - if (*tdi_p & tdi_mask) - x |= dtc_mask; - - dtc_mask >>= 1; - - tdi_mask <<= 1; - if (tdi_mask == 0) { - tdi_p++; - tdi_mask = 1; - } - } - - dtc_queue.cmd_buffer[dtc_queue.cmd_index++] = x; - } - } - - /* Schedule the last bit into the DTC command buffer */ - - /* make sure there's room for one cmd byte and one reply byte - * for in or inout scans*/ - dtc_queue_run_if_full(1, type == SCAN_OUT ? 0 : 1); - - if (type == SCAN_OUT) { - dtc_queue.cmd_buffer[dtc_queue.cmd_index++] = - DTC_CMD_SHIFT_TMS_TDI_BIT_PAIR(1, (*tdi_p & tdi_mask), 0); - - } else { - if (dtc_queue_enqueue_reply( - type, buffer, scan_size, tdi_bit_offset, - 1, - cmd - ) == NULL) { - LOG_ERROR("enqueuing DTC reply entry: %s", strerror(errno)); - exit(1); - } - - dtc_queue.reply_index++; - - dtc_queue.cmd_buffer[dtc_queue.cmd_index++] = - DTC_CMD_SHIFT_TMS_TDI_BIT_PAIR(1, (*tdi_p & tdi_mask), 1); - } - - /* Move to pause state */ - tap_state_queue_append(0); - tap_set_state(ir_scan ? TAP_IRPAUSE : TAP_DRPAUSE); - if (tap_get_state() != tap_get_end_state()) - rlink_state_move(); - - return 0; -} - -static int rlink_execute_queue(void) -{ - struct jtag_command *cmd = jtag_command_queue; /* currently processed command */ - int scan_size; - enum scan_type type; - uint8_t *buffer; - int retval, tmp_retval; - - /* return ERROR_OK, unless something goes wrong */ - retval = ERROR_OK; - -#ifndef AUTOMATIC_BUSY_LED - /* turn LED on */ - ep1_generic_commandl(pHDev, 2, - EP1_CMD_SET_PORTD_LEDS, - ~(ST7_PD_NBUSY_LED) - ); -#endif - - while (cmd) { - switch (cmd->type) { - case JTAG_RUNTEST: - case JTAG_TLR_RESET: - case JTAG_PATHMOVE: - case JTAG_SCAN: - break; - - default: - /* some events, such as resets, need a queue flush to ensure - *consistency */ - tap_state_queue_run(); - dtc_queue_run(); - break; - } - - switch (cmd->type) { - case JTAG_RESET: -#ifdef _DEBUG_JTAG_IO_ - LOG_DEBUG("reset trst: %i srst %i", - cmd->cmd.reset->trst, - cmd->cmd.reset->srst); -#endif - if ((cmd->cmd.reset->trst == 1) || - (cmd->cmd.reset->srst && - (jtag_get_reset_config() & RESET_SRST_PULLS_TRST))) - tap_set_state(TAP_RESET); - rlink_reset(cmd->cmd.reset->trst, cmd->cmd.reset->srst); - break; - case JTAG_RUNTEST: -#ifdef _DEBUG_JTAG_IO_ - LOG_DEBUG("runtest %i cycles, end in %i", - cmd->cmd.runtest->num_cycles, - cmd->cmd.runtest->end_state); -#endif - if (cmd->cmd.runtest->end_state != -1) - rlink_end_state(cmd->cmd.runtest->end_state); - rlink_runtest(cmd->cmd.runtest->num_cycles); - break; - case JTAG_TLR_RESET: -#ifdef _DEBUG_JTAG_IO_ - LOG_DEBUG("statemove end in %i", cmd->cmd.statemove->end_state); -#endif - if (cmd->cmd.statemove->end_state != -1) - rlink_end_state(cmd->cmd.statemove->end_state); - rlink_state_move(); - break; - case JTAG_PATHMOVE: -#ifdef _DEBUG_JTAG_IO_ - LOG_DEBUG("pathmove: %i states, end in %i", - cmd->cmd.pathmove->num_states, - cmd->cmd.pathmove->path[cmd->cmd.pathmove->num_states - 1]); -#endif - rlink_path_move(cmd->cmd.pathmove); - break; - case JTAG_SCAN: -#ifdef _DEBUG_JTAG_IO_ - LOG_DEBUG("%s scan end in %i", - (cmd->cmd.scan->ir_scan) ? "IR" : "DR", - cmd->cmd.scan->end_state); -#endif - if (cmd->cmd.scan->end_state != -1) - rlink_end_state(cmd->cmd.scan->end_state); - scan_size = jtag_build_buffer(cmd->cmd.scan, &buffer); - type = jtag_scan_type(cmd->cmd.scan); - if (rlink_scan(cmd, type, buffer, scan_size) != ERROR_OK) - retval = ERROR_FAIL; - break; - case JTAG_SLEEP: -#ifdef _DEBUG_JTAG_IO_ - LOG_DEBUG("sleep %i", cmd->cmd.sleep->us); -#endif - jtag_sleep(cmd->cmd.sleep->us); - break; - default: - LOG_ERROR("BUG: unknown JTAG command type encountered"); - exit(-1); - } - cmd = cmd->next; - } - - /* Flush the DTC queue to make sure any pending reads have been done before exiting this - *function */ - tap_state_queue_run(); - tmp_retval = dtc_queue_run(); - if (tmp_retval != ERROR_OK) - retval = tmp_retval; - -#ifndef AUTOMATIC_BUSY_LED - /* turn LED onff */ - ep1_generic_commandl(pHDev, 2, - EP1_CMD_SET_PORTD_LEDS, - ~0 - ); -#endif - - return retval; -} - -/* Using an unindexed table because it is infrequently accessed and it is short. The table must be - *in order of ascending speed (and descending prescaler), as it is scanned in reverse. */ - -static int rlink_speed(int speed) -{ - int i; - - if (speed == 0) { - /* fastest speed */ - speed = rlink_speed_table[rlink_speed_table_size - 1].prescaler; - } - - for (i = rlink_speed_table_size; i--; ) { - if (rlink_speed_table[i].prescaler == speed) { - if (dtc_load_from_buffer(pHDev, rlink_speed_table[i].dtc, - rlink_speed_table[i].dtc_size) != 0) { - LOG_ERROR( - "An error occurred while trying to load DTC code for speed \"%d\".", - speed); - exit(1); - } - - if (dtc_start_download() < 0) { - LOG_ERROR("starting DTC: %s", usb_strerror()); - exit(1); - } - - return ERROR_OK; - } - } - - LOG_ERROR("%d is not a supported speed", speed); - return ERROR_FAIL; -} - -static int rlink_speed_div(int speed, int *khz) -{ - int i; - - for (i = rlink_speed_table_size; i--; ) { - if (rlink_speed_table[i].prescaler == speed) { - *khz = rlink_speed_table[i].khz; - return ERROR_OK; - } - } - - LOG_ERROR("%d is not a supported speed", speed); - return ERROR_FAIL; -} - -static int rlink_khz(int khz, int *speed) -{ - int i; - - if (khz == 0) { - LOG_ERROR("RCLK not supported"); - return ERROR_FAIL; - } - - for (i = rlink_speed_table_size; i--; ) { - if (rlink_speed_table[i].khz <= khz) { - *speed = rlink_speed_table[i].prescaler; - return ERROR_OK; - } - } - - LOG_WARNING("The lowest supported JTAG speed is %d KHz", rlink_speed_table[0].khz); - *speed = rlink_speed_table[0].prescaler; - return ERROR_OK; -} - -static int rlink_init(void) -{ - int i, j, retries; - uint8_t reply_buffer[USB_EP1IN_SIZE]; - - usb_init(); - const uint16_t vids[] = { USB_IDVENDOR, 0 }; - const uint16_t pids[] = { USB_IDPRODUCT, 0 }; - if (jtag_usb_open(vids, pids, &pHDev) != ERROR_OK) - return ERROR_FAIL; - - struct usb_device *dev = usb_device(pHDev); - if (dev->descriptor.bNumConfigurations > 1) { - LOG_ERROR("Whoops! NumConfigurations is not 1, don't know what to do..."); - return ERROR_FAIL; - } - if (dev->config->bNumInterfaces > 1) { - LOG_ERROR("Whoops! NumInterfaces is not 1, don't know what to do..."); - return ERROR_FAIL; - } - - LOG_DEBUG("Opened device, pHDev = %p", pHDev); - - /* usb_set_configuration required under win32 */ - usb_set_configuration(pHDev, dev->config[0].bConfigurationValue); - - retries = 3; - do { - i = usb_claim_interface(pHDev, 0); - if (i) { - LOG_ERROR("usb_claim_interface: %s", usb_strerror()); -#ifdef LIBUSB_HAS_DETACH_KERNEL_DRIVER_NP - j = usb_detach_kernel_driver_np(pHDev, 0); - if (j) - LOG_ERROR("detach kernel driver: %s", usb_strerror()); -#endif - } else { - LOG_DEBUG("interface claimed!"); - break; - } - } while (--retries); - - if (i) { - LOG_ERROR("Initialisation failed."); - return ERROR_FAIL; - } - if (usb_set_altinterface(pHDev, 0) != 0) { - LOG_ERROR("Failed to set interface."); - return ERROR_FAIL; - } - - /* The device starts out in an unknown state on open. As such, - * result reads time out, and it's not even known whether the - * command was accepted. So, for this first command, we issue - * it repeatedly until its response doesn't time out. Also, if - * sending a command is going to time out, we find that out here. - * - * It must be possible to open the device in such a way that - * this special magic isn't needed, but, so far, it escapes us. - */ - for (i = 0; i < 5; i++) { - j = ep1_generic_commandl( - pHDev, 1, - EP1_CMD_GET_FWREV - ); - if (j < USB_EP1OUT_SIZE) { - LOG_ERROR("USB write error: %s", usb_strerror()); - return ERROR_FAIL; - } - j = usb_bulk_read( - pHDev, USB_EP1IN_ADDR, - (char *)reply_buffer, sizeof(reply_buffer), - 200 - ); - if (j != -ETIMEDOUT) - break; - } - - if (j < (int)sizeof(reply_buffer)) { - LOG_ERROR("USB read error: %s", usb_strerror()); - return ERROR_FAIL; - } - LOG_DEBUG(INTERFACE_NAME " firmware version: %d.%d.%d", - reply_buffer[0], - reply_buffer[1], - reply_buffer[2]); - - if ((reply_buffer[0] != 0) || (reply_buffer[1] != 0) || (reply_buffer[2] != 3)) - LOG_WARNING( - "The rlink device is not of the version that the developers have played with. It may or may not work."); - - /* Probe port E for adapter presence */ - ep1_generic_commandl( - pHDev, 16, - EP1_CMD_MEMORY_WRITE, /* Drive sense pin with 0 */ - ST7_PEDR >> 8, - ST7_PEDR, - 3, - 0x00, /* DR */ - ST7_PE_ADAPTER_SENSE_OUT, /* DDR */ - ST7_PE_ADAPTER_SENSE_OUT, /* OR */ - EP1_CMD_MEMORY_READ, /* Read back */ - ST7_PEDR >> 8, - ST7_PEDR, - 1, - EP1_CMD_MEMORY_WRITE, /* Drive sense pin with 1 */ - ST7_PEDR >> 8, - ST7_PEDR, - 1, - ST7_PE_ADAPTER_SENSE_OUT - ); - - usb_bulk_read( - pHDev, USB_EP1IN_ADDR, - (char *)reply_buffer, 1, - USB_TIMEOUT_MS - ); - - if ((reply_buffer[0] & ST7_PE_ADAPTER_SENSE_IN) != 0) - LOG_WARNING("target detection problem"); - - ep1_generic_commandl( - pHDev, 11, - EP1_CMD_MEMORY_READ, /* Read back */ - ST7_PEDR >> 8, - ST7_PEDR, - 1, - EP1_CMD_MEMORY_WRITE, /* float port E */ - ST7_PEDR >> 8, - ST7_PEDR, - 3, - 0x00, /* DR */ - 0x00, /* DDR */ - 0x00 /* OR */ - ); - - usb_bulk_read( - pHDev, USB_EP1IN_ADDR, - (char *)reply_buffer, 1, - USB_TIMEOUT_MS - ); - - - if ((reply_buffer[0] & ST7_PE_ADAPTER_SENSE_IN) == 0) - LOG_WARNING("target not plugged in"); - - /* float ports A and B */ - ep1_generic_commandl( - pHDev, 11, - EP1_CMD_MEMORY_WRITE, - ST7_PADDR >> 8, - ST7_PADDR, - 2, - 0x00, - 0x00, - EP1_CMD_MEMORY_WRITE, - ST7_PBDDR >> 8, - ST7_PBDDR, - 1, - 0x00 - ); - - /* make sure DTC is stopped, set VPP control, set up ports A and B */ - ep1_generic_commandl( - pHDev, 14, - EP1_CMD_DTC_STOP, - EP1_CMD_SET_PORTD_VPP, - ~(ST7_PD_VPP_SHDN), - EP1_CMD_MEMORY_WRITE, - ST7_PADR >> 8, - ST7_PADR, - 2, - ((~(0)) & (ST7_PA_NTRST)), - (ST7_PA_NTRST), - /* port B has no OR, and we want to emulate open drain on NSRST, so we set DR to 0 - *here and later assert NSRST by setting DDR bit to 1. */ - EP1_CMD_MEMORY_WRITE, - ST7_PBDR >> 8, - ST7_PBDR, - 1, - 0x00 - ); - - /* set LED updating mode and make sure they're unlit */ - ep1_generic_commandl( - pHDev, 3, -#ifdef AUTOMATIC_BUSY_LED - EP1_CMD_LEDUE_BUSY, -#else - EP1_CMD_LEDUE_NONE, -#endif - EP1_CMD_SET_PORTD_LEDS, - ~0 - ); - - tap_state_queue_init(); - dtc_queue_init(); - rlink_reset(0, 0); - - return ERROR_OK; -} - -static int rlink_quit(void) -{ - /* stop DTC and make sure LEDs are off */ - ep1_generic_commandl( - pHDev, 6, - EP1_CMD_DTC_STOP, - EP1_CMD_LEDUE_NONE, - EP1_CMD_SET_PORTD_LEDS, - ~0, - EP1_CMD_SET_PORTD_VPP, - ~0 - ); - - usb_release_interface(pHDev, 0); - usb_close(pHDev); - - return ERROR_OK; -} - -struct jtag_interface rlink_interface = { - .name = "rlink", - .init = rlink_init, - .quit = rlink_quit, - .speed = rlink_speed, - .speed_div = rlink_speed_div, - .khz = rlink_khz, - .execute_queue = rlink_execute_queue, -}; diff --git a/src/jtag/drivers/rlink.h b/src/jtag/drivers/rlink.h deleted file mode 100644 index 74b62580c..000000000 --- a/src/jtag/drivers/rlink.h +++ /dev/null @@ -1,32 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2008 Lou Deluxe * - * lou.openocd012@fixit.nospammail.net * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifndef OPENOCD_JTAG_DRIVERS_RLINK_H -#define OPENOCD_JTAG_DRIVERS_RLINK_H - -struct rlink_speed_table { - uint8_t const *dtc; - uint16_t dtc_size; - uint16_t khz; - uint8_t prescaler; -}; - -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 deleted file mode 100644 index b27f39238..000000000 --- a/src/jtag/drivers/rlink_call.m4 +++ /dev/null @@ -1,483 +0,0 @@ -m4_divert(`-1') -/*************************************************************************** - * Copyright (C) 2008 Lou Deluxe * - * lou.openocd012@fixit.nospammail.net * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -m4_dnl Setup and hold times depend on SHIFTER_PRESCALER -m4_define(`SETUP_DELAY_CYCLES', m4_eval(`('SHIFTER_PRESCALER` + 1) / 2')) -m4_define(`HOLD_DELAY_CYCLES', m4_eval(`'SHIFTER_PRESCALER` / 2')) - -m4_dnl Some macros to make nybble handling a little easier -m4_define(`m4_high_nybble', `m4_eval(`(($1) >> 4) & 0xf')') -m4_define(`m4_low_nybble', `m4_eval(`($1) & 0xf')') - -m4_dnl A macro to generate a number of NOPs depending on the argument -m4_define(`m4_0_to_5_nops', `m4_ifelse(m4_eval(`($1) >= 1'), 1, ` NOP -'m4_ifelse(m4_eval(`($1) >= 2'), 1, ` NOP -'m4_ifelse(m4_eval(`($1) >= 3'), 1, ` NOP -'m4_ifelse(m4_eval(`($1) >= 4'), 1, ` NOP -'m4_ifelse(m4_eval(`($1) >= 5'), 1, ` NOP -')))))') - - -m4_dnl Some macros to facilitate bit-banging delays. -m4_dnl There are 3 of them. One for self-contained delays, and two for those which must be split between setup and loop to keep from disturbing A at delay time. -m4_dnl The argument passed to any of them is the number of cycles which the delay should consume. - -m4_dnl This one is self-contained. - -m4_define(`m4_delay', -`; delay (m4_eval($1) cycles)' -`m4_ifelse(m4_eval(`('$1`) < 6'), 1, - m4_0_to_5_nops($1) -, - m4_ifelse(m4_eval(`(('$1`) - 3) % 2'), 1, ` NOP') - A.H = m4_high_nybble(`(('$1`) - 3) / 2') - A.L = m4_low_nybble(`(('$1`) - 3) / 2') - Y = A - DECY - JP -1 -)') - - -m4_dnl These are the setup and loop parts of the split delay. -m4_dnl The argument passed to both must match for the result to make sense. -m4_dnl The setup does not figure into the delay. It takes 3 cycles when a loop is used and none if nops are used. - -m4_define(`m4_delay_setup', -`; delay setup (m4_eval($1) cycles)' -`m4_ifelse(m4_eval(`('$1`) < 6'), 0, ` ' - A.H = m4_high_nybble(`('$1`) / 2') - A.L = m4_low_nybble(`('$1`) / 2') - Y = A -)') - -m4_define(`m4_delay_loop', -`; delay loop (m4_eval($1) cycles)' -`m4_ifelse(m4_eval(`('$1`) < 6'), 1, - m4_0_to_5_nops($1) -, - m4_ifelse(m4_eval(`('$1`) % 2'), 1, ` NOP') - DECY - JP -1 -)') - -m4_dnl These are utility macros for use with delays. Specifically, there is code below which needs some predictability in code size for relative jumps to reach. The m4_delay macro generates an extra NOP when an even delay is needed, and the m4_delay_loop macro generates an extra NOP when an odd delay is needed. Using this for the argument to the respective macro rounds up the argument so that the extra NOP will not be generated. There is also logic built in to cancel the rounding when the result is small enough that a loop would not be generated. - -m4_define(`m4_delay_loop_round_up', `m4_ifelse(m4_eval($1` < 6'), 1, $1, m4_eval(`(('$1`) + 1) / 2 * 2'))') -m4_define(`m4_delay_round_up', `m4_ifelse(m4_eval($1` < 6'), 1, $1, m4_eval(`(('$1`) / 2 * 2) + 1'))') - - -m4_divert(`0')m4_dnl - -;------------------------------------------------------------------------------ -:opcode_error -; This is at address 0x00 in case of empty LUT entries - STATUS STOP ERROR - -;------------------------------------------------------------------------------ -; Command interpreter at address 0x01 because it is branched to a lot and having it be 0x01 means we can use X for it, which is already used for other purposes which want it to be 1. -; Assumes X is 1 -; Assumes ADR_BUFFER0 points to the next command byte -; Stores the current command byte in CMP01 - -:command_interpreter - A = DATA_BUFFER0 - ADR_BUFFER0 += X - CMP01 = A ; store the current command for later - - EXCHANGE ; put MSN into LSN - A.H = 0xc ; lookup table at 0x1550 + 0xc0 = 0x1610 - - ; branch to address in lookup table - Y = A - A = - BRANCH - -;------------------------------------------------------------------------------ -; LUT for high nybble - -;LUT; c0 opcode_error -;LUT; c1 opcode_shift_tdi_andor_tms_bytes -;LUT; c2 opcode_shift_tdi_andor_tms_bytes -;LUT; c3 opcode_shift_tdi_andor_tms_bytes -;LUT; c4 opcode_shift_tdo_bytes -;LUT; c5 opcode_error -;LUT; c6 opcode_shift_tdio_bytes -;LUT; c7 opcode_error -;LUT; c8 opcode_shift_tms_tdi_bit_pair -;LUT; c9 opcode_shift_tms_bits -;LUT; ca opcode_error -;LUT; cb opcode_error -;LUT; cc opcode_error -;LUT; cd opcode_error -;LUT; ce opcode_shift_tdio_bits -;LUT; cf opcode_stop - - -;------------------------------------------------------------------------------ -; USB/buffer handling -; - -;ENTRY; download entry_download - -opcode_stop: -opcode_next_buffer: - ; pointer to completion flag - A.H = 0xf - A.L = 0xf - Y = A - - A = OR_MPEG ; buffer indicator from previous iteration - = A ; either indicator will have bit 0 set - BSET 1 ; was buffer 1 previously current? -; A.H = 0 ; already zero from OR_MPEG - JP opcode_next_buffer_0 - -opcode_next_buffer_1: - A.L = 0x1 ; ack buffer 0 - BUFFER_MNGT = A -; A.H = 0x0 ; already zero from BUFFER_MNGT - A.L = 0x3 ; Input buffer 1 = 0x1850 (0x0300) - JP +4 - -opcode_next_buffer_0: - A.L = 0x2 ; ack buffer 1 - BUFFER_MNGT = A -entry_download: - A = X ; Input buffer 0 = 0x1650 (0x0100) - - ADR_BUFFER01 = A - OR_MPEG = A ; store for next iteration - - A.L = 0x0 - BUFFER_MNGT = A ; finish acking previous buffer - Y = A - ADR_BUFFER00 = A - ADR_BUFFER11 = A - - A.H = 0x4 ; Output buffer = 0x1590 (0x0040) - ADR_BUFFER10 = A - - EXCHANGE ; 0x04 - X = A ; for the spin loop below - - ; pointer to status in shared memory - DECY ; setting to 0 above and decrementing here saves a byte - - ; wait until a command buffer is available - A = BUFFER_MNGT ; spin while neither of bits 2 or 3 are set - CP A = A ; update status once done spinning - - ; restore X, since we used it -; A.H = 0 ; high nybble of BUFFER_MNGT will always be 0 the way we use it - A.L = 1 - X = A - - ; go to command interpreter - BRANCH - - -;;------------------------------------------------------------------------------ -;:opcode_stop -;; -; -; ; Ack buffer 0 in download mode -; A.L = 0x1 -; BUFFER_MNGT = A -; -; STATUS STOP - - -;------------------------------------------------------------------------------ -:opcode_shift_tdi_andor_tms_bytes -; - - A = CMP01 ; bits 3..0 contain the number of bytes to shift - 1 - A.H = 0 - Y = A ; loop counter - - A = CMP01 - EXCHANGE - CMP01 = A ; we're interested in bits in the high nybble - -opcode_shift_tdi_andor_tms_bytes__loop: - -; set tdi to supplied byte or zero - A = CMP01 - BSET 1 - JP +4 - A.H = 0 - A.L = 0 - JP +3 - A = DATA_BUFFER0 - ADR_BUFFER0 += X - SHIFT_MPEG = A - -; set tms to supplied byte or zero - A = CMP01 - BCLR 0 - JP +5 - A = DATA_BUFFER0 - ADR_BUFFER0 += X - SHIFT_CARD = A - SHIFT CARD OUT=>PIN0 - -; run both shifters as nearly simultaneously as possible - SHIFT MPEG OUT=>PIN1 - - A = CTRL_FCI - EXCHANGE - BCLR 3 - JP -3 - - DECY - JP opcode_shift_tdi_andor_tms_bytes__loop - - A = X - BRANCH - - -;------------------------------------------------------------------------------ -:opcode_shift_tdo_bytes -; - - A = CMP01 ; bits 3..0 contain the number of bytes to shift - 1 - A.H = 0 - Y = A ; loop counter - -opcode_shift_tdo_bytes__loop: - SHIFT MPEG PIN0=>IN - - A = CTRL_FCI - EXCHANGE - BCLR 3 - JP -3 - - ; put shifted byte into output buffer - A = SHIFT_MPEG - DATA_BUFFER1 = A - ADR_BUFFER1 += X - - DECY - JP opcode_shift_tdo_bytes__loop - - A = X - BRANCH - - -;------------------------------------------------------------------------------ -:opcode_shift_tdio_bytes -; - - A = CMP01 ; bits 3..0 contain the number of bytes to shift - 1 - A.H = 0 - CMP10 = A ; byte loop counter - - A.H = opcode_shift_tdio_bytes__sub_return - A.L = opcode_shift_tdio_bytes__sub_return - CMP00 = A ; return address - -opcode_shift_tdio_bytes__loop: - A.H = 0 - A.L = 7 - CMP11 = A ; always use 8 bits - - JP sub_shift_tdio_bits -opcode_shift_tdio_bytes__sub_return: - - A = CMP10 ; byte loop counter - CP A=>X - CLC - A -= X - CMP10 = A - JP opcode_shift_tdio_bytes__loop - - A = X -;DR_MPEG = A ; return TCK low, as str912 reset halt seems to require it - BRANCH - - -;------------------------------------------------------------------------------ -:opcode_shift_tdio_bits -; - - A = CMP01 ; bits 2..0 contain the number of bits to shift - 1 - A.H = 0 - BCLR 3 ; set TMS=1 if bit 3 was set - CMP11 = A ; bit loop counter - - A.H = opcode_shift_tdio_bits__sub_return - A.L = opcode_shift_tdio_bits__sub_return - CMP00 = A ; return address - - JP sub_shift_tdio_bits - A.L = 0x1 ; TMS=1 - DR_CARD = A - JP sub_shift_tdio_bits -opcode_shift_tdio_bits__sub_return: - - A = X -;DR_MPEG = A ; return TCK low, as str912 reset halt seems to require it - BRANCH - - -;------------------------------------------------------------------------------ -:sub_shift_tdio_bits -; - - A = DATA_BUFFER0 ; get byte from input buffer - ADR_BUFFER0 += X - MASK = A ; put it in MASK where bit routine will use it - -:sub_shift_tdio_bits__loop -m4_delay_setup(m4_delay_loop_round_up(SETUP_DELAY_CYCLES - 1)) - - A = MASK ; shift TDO into and TDI out of MASK via carry - A += MASK - MASK = A - - ; shifting out TDI - A.L = 0x2 ; TCK=0, TDI=1 - CP CARRY - JP +2 - A.L = 0x0 ; TCK=0, TDI=0 - DR_MPEG = A - -m4_delay_loop(m4_delay_loop_round_up(SETUP_DELAY_CYCLES - 1)) - - BSET 2 ; TCK high - DR_MPEG = A - - A = DR_MPEG ; set carry bit to TDO - CLC - BCLR 0 - JP +2 - SEC - -m4_delay(HOLD_DELAY_CYCLES - 10) - - A = CMP11 ; bit loop counter - Y = A ; use Y to avoid corrupting carry bit with subtract - DECY - A = Y - CMP11 = A - JP :sub_shift_tdio_bits__loop - - ; shift last TDO bit into result - A = MASK - A += MASK - DATA_BUFFER1 = A - ADR_BUFFER1 += X - - A = CMP00 ; return to caller - BRANCH - - -;------------------------------------------------------------------------------ -:opcode_shift_tms_tdi_bit_pair -; - -; set TMS line manually - A = CMP01 ; bits 3..0 contain TDI and TMS bits and whether to return TDO - BSET 0 ; TMS bit - A.L = 0x1 ; TMS=1 - JP +2 - A.L = 0x0 ; TMS=0 - DR_CARD = A - -; stuff command buffer with bitmap of single TDI bit - A = CMP01 - BSET 1 ; TDI bit - A.H = 0x8 ; TDI=1 - JP +2 - A.H = 0x0 ; TDI=0 - ADR_BUFFER0 -= X - DATA_BUFFER0 = A - - A.H = 0 - A.L = 0 - CMP11 = A ; bit loop counter (only doing one bit) - - A.H = opcode_shift_tms_tdi_bit_pair__sub_return - A.L = opcode_shift_tms_tdi_bit_pair__sub_return - CMP00 = A ; return address - -; jump this way due to relative jump range issues - A.H = sub_shift_tdio_bits - A.L = sub_shift_tdio_bits - BRANCH -opcode_shift_tms_tdi_bit_pair__sub_return: - - A = CMP01 - BSET 3 ; bit says whether to return TDO - JP +2 - ADR_BUFFER1 -= X ; subroutine returns it, so undo that - - A = X - DR_MPEG = A ; return TCK low, as str912 reset halt seems to require it - BRANCH - - -;------------------------------------------------------------------------------ -:opcode_shift_tms_bits -; - - A = CMP01 ; bits 3..0 contain the number of bits to shift - 1 (only 1-8 bits is valid... no checking, just improper operation) - A.H = 0 - CMP11 = A ; bit loop counter - - A = DATA_BUFFER0 ; get byte from input buffer - ADR_BUFFER0 += X - MASK = A ; The byte we'll be shifting - -:opcode_shift_tms_bits__loop -m4_delay_setup(SETUP_DELAY_CYCLES - 1) - - A = MASK ; shift TMS out of MASK via carry - A += MASK - MASK = A - - ; shifting out TMS - A.L = 0x1 ; TCK=0, TDI=0, TMS=1 - CP CARRY - JP +2 - A.L = 0x0 ; TCK=0, TDI=0, TMS=0 - DR_CARD = A - DR_MPEG = A - -m4_delay_loop(SETUP_DELAY_CYCLES - 1) - - BSET 2 ; TCK high - DR_MPEG = A - -m4_delay(HOLD_DELAY_CYCLES - 10) - - A = CMP11 ; bit loop counter - CP A=>X - CLC - A -= X - CMP11 = A - JP :opcode_shift_tms_bits__loop - - A = X - DR_MPEG = A ; return TCK low, as str912 reset halt seems to require it - BRANCH - - diff --git a/src/jtag/drivers/rlink_dtc_cmd.h b/src/jtag/drivers/rlink_dtc_cmd.h deleted file mode 100644 index ff9e8b25f..000000000 --- a/src/jtag/drivers/rlink_dtc_cmd.h +++ /dev/null @@ -1,76 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2008 Lou Deluxe * - * lou.openocd012@fixit.nospammail.net * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#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 */ - -#define DTC_CMD_SHIFT_TMS_BYTES(bytes) ((0x1 << 4) | ((bytes) - 1)) -/* Shift 1-16 bytes out TMS. TDI is 0. */ -/* Bytes to shift follow. */ - -#define DTC_CMD_SHIFT_TDI_BYTES(bytes) ((0x2 << 4) | ((bytes) - 1)) -/* Shift 1-16 bytes out TDI. TMS is 0. */ -/* Bytes to shift follow. */ - -#define DTC_CMD_SHIFT_TDI_AND_TMS_BYTES(bytes) ((0x3 << 4) | ((bytes) - 1)) -/* Shift 1-16 byte pairs out TDI and TMS. */ -/* Byte pairs to shift follow in TDI, TMS order. */ - -#define DTC_CMD_SHIFT_TDO_BYTES(bytes) ((0x4 << 4) | ((bytes) - 1)) -/* Shift 1-16 bytes in TDO. TMS is unaffected. */ -/* Reply buffer contains bytes shifted in. */ - -#define DTC_CMD_SHIFT_TDIO_BYTES(bytes) ((0x6 << 4) | ((bytes) - 1)) -/* Shift 1-16 bytes out TDI and in TDO. TMS is unaffected. */ - -#define DTC_CMD_SHIFT_TMS_TDI_BIT_PAIR(tms, tdi, tdo) ((0x8 << 4) | (\ - (tms) ? (1 << 0) : 0 \ -) | (\ - (tdi) ? (1 << 1) : 0 \ -) | (\ - (tdo) ? (1 << 3) : 0 \ -)) -/* Single bit shift. - * tms and tdi are the levels shifted out on TMS and TDI, respectively. - * tdo indicates whether a byte will be returned in the reply buffer with its - * least significant bit set to reflect TDO - * Care should be taken when tdo is zero, as the underlying code actually does put - * that byte in the reply buffer. Setting tdo to zero just moves the pointer back. - * The result is that if this command is executed when the reply buffer is already full, - * a byte will be written erroneously to memory not belonging to the reply buffer. - * This could be worked around at the expense of DTC code space and speed. */ - -#define DTC_CMD_SHIFT_TMS_BITS(bits) ((0x9 << 4) | ((bits) - 1)) -/* Shift 1-8 bits out TMS. */ -/* Bits to be shifted out are left justified in the following byte. */ - -#define DTC_CMD_SHIFT_TDIO_BITS(bits) ((0xe << 4) | ((bits) - 1)) -/* Shift 1-8 bits out TDI and in TDO, TMS is unaffected. */ -/* Bits to be shifted out are left justified in the following byte. */ -/* Bits shifted in are right justified in the byte placed in the reply buffer. */ - -#define DTC_CMD_STOP (0xf << 4) -/* Stop processing the command buffer and wait for the next one. */ -/* 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 deleted file mode 100644 index 3f9f2b381..000000000 --- a/src/jtag/drivers/rlink_ep1_cmd.h +++ /dev/null @@ -1,60 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2008 Lou Deluxe * - * lou.openocd012@fixit.nospammail.net * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#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 . - * The buffer can contain several of these, but only one which returns data. - * Some of these opcodes have arguments, which follow immediately. - * If shorter than the packet size, trailing positions should be zero-filled. - */ - -/* LED update enables: - * When enabled, each LED is updated automatically. - * When not enabled, each LED can be controlled manually with EP1_CMD_SET_PORTD_LEDS. - */ -#define EP1_CMD_LEDUE_BOTH (0x05) -/* EP1_CMD_LEDUE_NONE has the side effect of turning the LEDs on */ -#define EP1_CMD_LEDUE_NONE (0x06) -#define EP1_CMD_LEDUE_ERROR (0x17) -#define EP1_CMD_LEDUE_BUSY (0x18) - -#define EP1_CMD_DTC_STOP (0x0b) -#define EP1_CMD_DTC_LOAD (0x0c) -#define EP1_CMD_DTC_CALL (0x0d) -#define EP1_CMD_SET_UPLOAD (0x0f) -#define EP1_CMD_SET_DOWNLOAD (0x10) -#define EP1_CMD_DTC_WAIT (0x12) -#define EP1_CMD_DTC_GET_STATUS (0x15) -/* a quick way to just read back one byte */ -#define EP1_CMD_DTC_GET_CACHED_STATUS (0x16) - -/* Writes upper 2 bits (SHDN and SEL) of port D with argument */ -#define EP1_CMD_SET_PORTD_VPP (0x19) -/* Writes lower 2 bits (BUSY and ERROR) of port D with argument */ -#define EP1_CMD_SET_PORTD_LEDS (0x1a) - -#define EP1_CMD_MEMORY_READ (0x28) -#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 deleted file mode 100644 index 8ad2f51d8..000000000 --- a/src/jtag/drivers/rlink_init.m4 +++ /dev/null @@ -1,72 +0,0 @@ -m4_divert(`-1') -/*************************************************************************** - * Copyright (C) 2008 Lou Deluxe * - * lou.openocd012@fixit.nospammail.net * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -m4_undefine(`CTRL_MPEG_L') -m4_undefine(`CTRL_CARD_L') - -m4_ifelse(SHIFTER_PRESCALER, 1, ` - m4_define(`CTRL_MPEG_L', `m4_eval(`0x8 | 0x0')') -') -m4_ifelse(SHIFTER_PRESCALER, 2, ` - m4_define(`CTRL_MPEG_L', `m4_eval(`0x8 | 0x2')') - m4_define(`CTRL_CARD_L', `m4_eval(`0x8 | 0x1')') -') -m4_ifelse(SHIFTER_PRESCALER, 8, ` - m4_define(`CTRL_MPEG_L', `m4_eval(`0x8 | 0x3')') -') -m4_ifelse(SHIFTER_PRESCALER, 11, ` - m4_define(`CTRL_MPEG_L', `m4_eval(`0x8 | 0x4')') -') -m4_ifelse(SHIFTER_PRESCALER, 64, ` - m4_define(`CTRL_MPEG_L', `m4_eval(`0x8 | 0x7')') -') - -m4_ifdef(`CTRL_MPEG_L',,` - m4_errprint(`SHIFTER_PRESCALER was not defined with a supported value -') m4_m4exit(`1') -') - -m4_divert(`0')m4_dnl - -init: - A.H = 0 - - A.L = 0 - - DR_MPEG = A ; TDI and TCK start out low - DR_CARD = A ; TMS starts out low - - A.L = 0x6 - - CTRL_FCI = A ; MPEG and CARD driven by FCI - DDR_MPEG = A ; TDI and TCK are outputs - - A.L = 0x1 - - X = A ; X == 1 - DDR_CARD = A ; TMS is output - - A.L = CTRL_MPEG_L - CTRL_MPEG = A -m4_ifdef(`CTRL_CARD_L', -` A.L = 'CTRL_CARD_L` -')m4_dnl - CTRL_CARD = A - - STATUS STOP diff --git a/src/jtag/drivers/rlink_speed_table.c b/src/jtag/drivers/rlink_speed_table.c deleted file mode 100644 index b84357731..000000000 --- a/src/jtag/drivers/rlink_speed_table.c +++ /dev/null @@ -1,101 +0,0 @@ -/* This file was created automatically by ../../../tools/rlink_make_speed_table/rlink_make_speed_table.pl. */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "rlink.h" -#include "rlink_st7.h" - -static const uint8_t dtc_64[] = { - 0, 2, 68, 84, 67, 2, 13, 160, 176, 151, 147, 182, 141, 152, 177, 129, 148, - 191, 143, 142, 5, 3, 0, 0, 0, 2, 68, 84, 67, 4, 0, 192, 5, 15, 0, 42, 42, - 42, 73, 0, 88, 0, 160, 189, 0, 0, 0, 0, 106, 9, 1, 8, 22, 100, 111, 119, - 110, 108, 111, 97, 100, 2, 226, 7, 219, 39, 137, 51, 172, 130, 192, 96, - 175, 191, 130, 217, 128, 57, 69, 177, 159, 179, 68, 178, 159, 193, 133, - 153, 176, 159, 130, 132, 135, 164, 134, 51, 129, 60, 223, 9, 98, 128, 177, - 129, 96, 201, 160, 130, 201, 51, 137, 201, 57, 68, 160, 176, 67, 219, 39, - 154, 201, 40, 69, 219, 39, 150, 17, 27, 205, 51, 43, 99, 60, 118, 193, - 96, 201, 160, 130, 24, 205, 51, 43, 99, 218, 156, 47, 60, 105, 193, 96, - 201, 160, 138, 166, 178, 136, 160, 183, 139, 86, 202, 8, 2, 36, 138, 105, - 193, 96, 201, 160, 43, 139, 167, 181, 136, 70, 177, 147, 67, 193, 96, 219, - 39, 131, 161, 176, 130, 195, 53, 131, 178, 10, 66, 176, 151, 60, 97, 58, - 151, 215, 2, 40, 66, 1, 0, 160, 185, 130, 60, 97, 203, 130, 60, 194, 139, - 127, 195, 53, 156, 47, 200, 96, 201, 56, 177, 66, 176, 147, 201, 57, 168, - 66, 160, 38, 155, 160, 176, 139, 171, 182, 136, 167, 183, 96, 201, 59, - 66, 46, 193, 151, 96, 201, 160, 139, 219, 39, 131, 160, 191, 130, 195, - 53, 131, 177, 10, 66, 176, 147, 151, 0, 60, 97, 58, 151, 0, 160, 185, 130, - 60, 97, 203, 8, 2, 36, 139, 124, 193, 151, 96 -}; - -static const uint8_t dtc_11[] = { - 0, 2, 68, 84, 67, 2, 13, 160, 176, 151, 147, 182, 141, 152, 177, 129, 148, - 188, 143, 142, 5, 3, 0, 0, 0, 2, 68, 84, 67, 4, 0, 192, 5, 15, 0, 42, 42, - 42, 73, 0, 88, 0, 154, 183, 0, 0, 0, 0, 106, 9, 1, 8, 22, 100, 111, 119, - 110, 108, 111, 97, 100, 2, 213, 7, 219, 39, 137, 51, 172, 130, 192, 96, - 175, 191, 130, 217, 128, 57, 69, 177, 159, 179, 68, 178, 159, 193, 133, - 153, 176, 159, 130, 132, 135, 164, 134, 51, 129, 60, 223, 9, 98, 128, 177, - 129, 96, 201, 160, 130, 201, 51, 137, 201, 57, 68, 160, 176, 67, 219, 39, - 154, 201, 40, 69, 219, 39, 150, 17, 27, 205, 51, 43, 99, 60, 118, 193, - 96, 201, 160, 130, 24, 205, 51, 43, 99, 218, 156, 47, 60, 105, 193, 96, - 201, 160, 138, 166, 178, 136, 160, 183, 139, 86, 202, 8, 2, 36, 138, 105, - 193, 96, 201, 160, 43, 139, 167, 181, 136, 70, 177, 147, 67, 193, 96, 219, - 39, 131, 195, 53, 131, 178, 10, 66, 176, 151, 0, 0, 0, 0, 0, 58, 151, 215, - 2, 40, 66, 1, 203, 130, 60, 194, 139, 121, 195, 53, 156, 47, 200, 96, 201, - 56, 177, 66, 176, 147, 201, 57, 168, 66, 160, 38, 155, 160, 176, 139, 171, - 176, 136, 167, 183, 96, 201, 59, 66, 46, 193, 151, 96, 201, 160, 139, 219, - 39, 131, 195, 53, 131, 177, 10, 66, 176, 147, 151, 0, 0, 0, 0, 0, 58, 151, - 203, 8, 2, 36, 139, 117, 193, 151, 96 -}; - -static const uint8_t dtc_8[] = { - 0, 2, 68, 84, 67, 2, 13, 160, 176, 151, 147, 182, 141, 152, 177, 129, 148, - 187, 143, 142, 5, 3, 0, 0, 0, 2, 68, 84, 67, 4, 0, 192, 5, 15, 0, 42, 42, - 42, 73, 0, 88, 0, 152, 181, 0, 0, 0, 0, 106, 9, 1, 8, 22, 100, 111, 119, - 110, 108, 111, 97, 100, 2, 209, 7, 219, 39, 137, 51, 172, 130, 192, 96, - 175, 191, 130, 217, 128, 57, 69, 177, 159, 179, 68, 178, 159, 193, 133, - 153, 176, 159, 130, 132, 135, 164, 134, 51, 129, 60, 223, 9, 98, 128, 177, - 129, 96, 201, 160, 130, 201, 51, 137, 201, 57, 68, 160, 176, 67, 219, 39, - 154, 201, 40, 69, 219, 39, 150, 17, 27, 205, 51, 43, 99, 60, 118, 193, - 96, 201, 160, 130, 24, 205, 51, 43, 99, 218, 156, 47, 60, 105, 193, 96, - 201, 160, 138, 166, 178, 136, 160, 183, 139, 86, 202, 8, 2, 36, 138, 105, - 193, 96, 201, 160, 43, 139, 167, 181, 136, 70, 177, 147, 67, 193, 96, 219, - 39, 131, 195, 53, 131, 178, 10, 66, 176, 151, 0, 0, 0, 58, 151, 215, 2, - 40, 66, 1, 203, 130, 60, 194, 139, 119, 195, 53, 156, 47, 200, 96, 201, - 56, 177, 66, 176, 147, 201, 57, 168, 66, 160, 38, 155, 160, 176, 139, 170, - 190, 136, 167, 183, 96, 201, 59, 66, 46, 193, 151, 96, 201, 160, 139, 219, - 39, 131, 195, 53, 131, 177, 10, 66, 176, 147, 151, 0, 0, 0, 58, 151, 203, - 8, 2, 36, 139, 115, 193, 151, 96 -}; - -static const uint8_t dtc_2[] = { - 0, 2, 68, 84, 67, 2, 14, 160, 176, 151, 147, 182, 141, 152, 177, 129, 148, - 186, 143, 185, 142, 5, 3, 0, 0, 0, 2, 68, 84, 67, 4, 0, 192, 5, 15, 0, - 42, 42, 42, 73, 0, 88, 0, 149, 178, 0, 0, 0, 0, 106, 9, 1, 8, 22, 100, - 111, 119, 110, 108, 111, 97, 100, 2, 203, 7, 219, 39, 137, 51, 172, 130, - 192, 96, 175, 191, 130, 217, 128, 57, 69, 177, 159, 179, 68, 178, 159, - 193, 133, 153, 176, 159, 130, 132, 135, 164, 134, 51, 129, 60, 223, 9, - 98, 128, 177, 129, 96, 201, 160, 130, 201, 51, 137, 201, 57, 68, 160, 176, - 67, 219, 39, 154, 201, 40, 69, 219, 39, 150, 17, 27, 205, 51, 43, 99, 60, - 118, 193, 96, 201, 160, 130, 24, 205, 51, 43, 99, 218, 156, 47, 60, 105, - 193, 96, 201, 160, 138, 166, 178, 136, 160, 183, 139, 86, 202, 8, 2, 36, - 138, 105, 193, 96, 201, 160, 43, 139, 167, 181, 136, 70, 177, 147, 67, - 193, 96, 219, 39, 131, 195, 53, 131, 178, 10, 66, 176, 151, 58, 151, 215, - 2, 40, 66, 1, 203, 130, 60, 194, 139, 116, 195, 53, 156, 47, 200, 96, 201, - 56, 177, 66, 176, 147, 201, 57, 168, 66, 160, 38, 155, 160, 176, 139, 170, - 187, 136, 167, 183, 96, 201, 59, 66, 46, 193, 151, 96, 201, 160, 139, 219, - 39, 131, 195, 53, 131, 177, 10, 66, 176, 147, 151, 58, 151, 203, 8, 2, - 36, 139, 112, 193, 151, 96 -}; - -const struct rlink_speed_table rlink_speed_table[] = {{ - dtc_64, sizeof(dtc_64), (ST7_FOSC * 2) / (1000 * 64), 64 -}, { - dtc_11, sizeof(dtc_11), (ST7_FOSC * 2) / (1000 * 11), 11 -}, { - dtc_8, sizeof(dtc_8), (ST7_FOSC * 2) / (1000 * 8), 8 -}, { - dtc_2, sizeof(dtc_2), (ST7_FOSC * 2) / (1000 * 2), 2 -} }; - -const size_t rlink_speed_table_size = ARRAY_SIZE(rlink_speed_table); - diff --git a/src/jtag/drivers/rlink_st7.h b/src/jtag/drivers/rlink_st7.h deleted file mode 100644 index 3d573e72c..000000000 --- a/src/jtag/drivers/rlink_st7.h +++ /dev/null @@ -1,117 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2008 Lou Deluxe * - * lou.openocd012@fixit.nospammail.net * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#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. */ - -#define ST7_PADR (0x0000) -#define ST7_PADDR (ST7_PADR + 1) -#define ST7_PAOR (ST7_PADR + 2) -#define ST7_PBDR (0x0003) -#define ST7_PBDDR (ST7_PBDR + 1) -#define ST7_PCDR (0x0006) -#define ST7_PCDDR (ST7_PCDR + 1) -#define ST7_PCOR (ST7_PCDR + 2) -#define ST7_PDDR (0x0009) -#define ST7_PDDDR (ST7_PDDR + 1) -#define ST7_PDOR (ST7_PDDR + 2) -#define ST7_PEDR (0x000c) -#define ST7_PEDDR (ST7_PEDR + 1) -#define ST7_PEOR (ST7_PEDR + 2) -#define ST7_PFDR (0x000f) -#define ST7_PFDDR (ST7_PFDR + 1) - -#define ST7_ADCDR (0x0012) -#define ST7_ADCCSR (ST7_ADCDR + 1) - -#define ST7_EP2TXR (0x003e) -#define ST7_EP2TXR_STAT_TX0 (1 << 0) -#define ST7_EP2TXR_STAT_TX1 (1 << 1) -#define ST7_EP2TXR_STAT_DISABLED (0) -#define ST7_EP2TXR_STAT_STALL (ST7_EP2TXR_STAT_TX0) -#define ST7_EP2TXR_STAT_VALID (ST7_EP2TXR_STAT_TX1 | ST7_EP2TXR_STAT_TX0) -#define ST7_EP2TXR_STAT_NAK (ST7_EP2TXR_STAT_TX1) -#define ST7_EP2TXR_DTOG_TX (1 << 2) -#define ST7_EP2TXR_CTR_TX (1 << 3) - -#define ST7_USB_BUF_EP0OUT (0x1550) -#define ST7_USB_BUF_EP0IN (0x1560) -#define ST7_USB_BUF_EP1OUT (0x1570) -#define ST7_USB_BUF_EP1IN (0x1580) -#define ST7_USB_BUF_EP2UODI (0x1590) -#define ST7_USB_BUF_EP2UIDO (0x1650) - -#define ST7_PA0 (1 << 0) -#define ST7_PA1 (1 << 1) -#define ST7_PA2 (1 << 2) -#define ST7_PA3 (1 << 3) -#define ST7_PA4 (1 << 4) -#define ST7_PA5 (1 << 5) -#define ST7_PA6 (1 << 6) -#define ST7_PA7 (1 << 7) - -#define ST7_PB0 (1 << 0) -#define ST7_PB1 (1 << 1) -#define ST7_PB2 (1 << 2) -#define ST7_PB3 (1 << 3) -#define ST7_PB4 (1 << 4) -#define ST7_PB5 (1 << 5) -#define ST7_PB6 (1 << 6) -#define ST7_PB7 (1 << 7) - -#define ST7_PC0 (1 << 0) -#define ST7_PC1 (1 << 1) -#define ST7_PC2 (1 << 2) -#define ST7_PC3 (1 << 3) -#define ST7_PC4 (1 << 4) -#define ST7_PC5 (1 << 5) -#define ST7_PC6 (1 << 6) -#define ST7_PC7 (1 << 7) - -#define ST7_PD0 (1 << 0) -#define ST7_PD1 (1 << 1) -#define ST7_PD2 (1 << 2) -#define ST7_PD3 (1 << 3) -#define ST7_PD4 (1 << 4) -#define ST7_PD5 (1 << 5) -#define ST7_PD6 (1 << 6) -#define ST7_PD7 (1 << 7) - -#define ST7_PE0 (1 << 0) -#define ST7_PE1 (1 << 1) -#define ST7_PE2 (1 << 2) -#define ST7_PE3 (1 << 3) -#define ST7_PE4 (1 << 4) -#define ST7_PE5 (1 << 5) -#define ST7_PE6 (1 << 6) -#define ST7_PE7 (1 << 7) - -#define ST7_PF0 (1 << 0) -#define ST7_PF1 (1 << 1) -#define ST7_PF2 (1 << 2) -#define ST7_PF3 (1 << 3) -#define ST7_PF4 (1 << 4) -#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 deleted file mode 100644 index 699c41fa3..000000000 --- a/src/jtag/drivers/stlink_usb.c +++ /dev/null @@ -1,1890 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2011-2012 by Mathias Kuester * - * Mathias Kuester * - * * - * Copyright (C) 2012 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * This code is based on https://github.com/texane/stlink * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -/* project specific includes */ -#include -#include -#include -#include -#include -#include - -#include - -#include "libusb_common.h" - -#define ENDPOINT_IN 0x80 -#define ENDPOINT_OUT 0x00 - -#define STLINK_WRITE_TIMEOUT 1000 -#define STLINK_READ_TIMEOUT 1000 - -#define STLINK_NULL_EP 0 -#define STLINK_RX_EP (1|ENDPOINT_IN) -#define STLINK_TX_EP (2|ENDPOINT_OUT) -#define STLINK_TRACE_EP (3|ENDPOINT_IN) - -#define STLINK_V2_1_TX_EP (1|ENDPOINT_OUT) -#define STLINK_V2_1_TRACE_EP (2|ENDPOINT_IN) - -#define STLINK_SG_SIZE (31) -#define STLINK_DATA_SIZE (4096) -#define STLINK_CMD_SIZE_V2 (16) -#define STLINK_CMD_SIZE_V1 (10) - -#define STLINK_V1_PID (0x3744) -#define STLINK_V2_PID (0x3748) -#define STLINK_V2_1_PID (0x374B) - -/* the current implementation of the stlink limits - * 8bit read/writes to max 64 bytes. */ -#define STLINK_MAX_RW8 (64) - -/* "WAIT" responses will be retried (with exponential backoff) at - * most this many times before failing to caller. - */ -#define MAX_WAIT_RETRIES 8 - -enum stlink_jtag_api_version { - STLINK_JTAG_API_V1 = 1, - STLINK_JTAG_API_V2, -}; - -/** */ -struct stlink_usb_version { - /** */ - int stlink; - /** */ - int jtag; - /** */ - int swim; - /** highest supported jtag api version */ - enum stlink_jtag_api_version jtag_api_max; -}; - -/** */ -struct stlink_usb_handle_s { - /** */ - struct jtag_libusb_device_handle *fd; - /** */ - struct libusb_transfer *trans; - /** */ - uint8_t rx_ep; - /** */ - uint8_t tx_ep; - /** */ - uint8_t trace_ep; - /** */ - uint8_t cmdbuf[STLINK_SG_SIZE]; - /** */ - uint8_t cmdidx; - /** */ - uint8_t direction; - /** */ - uint8_t databuf[STLINK_DATA_SIZE]; - /** */ - uint32_t max_mem_packet; - /** */ - enum hl_transports transport; - /** */ - struct stlink_usb_version version; - /** */ - uint16_t vid; - /** */ - uint16_t pid; - /** this is the currently used jtag api */ - enum stlink_jtag_api_version jtag_api; - /** */ - struct { - /** whether SWO tracing is enabled or not */ - bool enabled; - /** trace module source clock */ - uint32_t source_hz; - } trace; - /** reconnect is needed next time we try to query the - * status */ - bool reconnect_pending; -}; - -#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 -#define STLINK_CORE_STAT_UNKNOWN -1 - -#define STLINK_GET_VERSION 0xF1 -#define STLINK_DEBUG_COMMAND 0xF2 -#define STLINK_DFU_COMMAND 0xF3 -#define STLINK_SWIM_COMMAND 0xF4 -#define STLINK_GET_CURRENT_MODE 0xF5 -#define STLINK_GET_TARGET_VOLTAGE 0xF7 - -#define STLINK_DEV_DFU_MODE 0x00 -#define STLINK_DEV_MASS_MODE 0x01 -#define STLINK_DEV_DEBUG_MODE 0x02 -#define STLINK_DEV_SWIM_MODE 0x03 -#define STLINK_DEV_BOOTLOADER_MODE 0x04 -#define STLINK_DEV_UNKNOWN_MODE -1 - -#define STLINK_DFU_EXIT 0x07 - -#define STLINK_SWIM_ENTER 0x00 -#define STLINK_SWIM_EXIT 0x01 - -#define STLINK_DEBUG_ENTER_JTAG 0x00 -#define STLINK_DEBUG_GETSTATUS 0x01 -#define STLINK_DEBUG_FORCEDEBUG 0x02 -#define STLINK_DEBUG_APIV1_RESETSYS 0x03 -#define STLINK_DEBUG_APIV1_READALLREGS 0x04 -#define STLINK_DEBUG_APIV1_READREG 0x05 -#define STLINK_DEBUG_APIV1_WRITEREG 0x06 -#define STLINK_DEBUG_READMEM_32BIT 0x07 -#define STLINK_DEBUG_WRITEMEM_32BIT 0x08 -#define STLINK_DEBUG_RUNCORE 0x09 -#define STLINK_DEBUG_STEPCORE 0x0a -#define STLINK_DEBUG_APIV1_SETFP 0x0b -#define STLINK_DEBUG_READMEM_8BIT 0x0c -#define STLINK_DEBUG_WRITEMEM_8BIT 0x0d -#define STLINK_DEBUG_APIV1_CLEARFP 0x0e -#define STLINK_DEBUG_APIV1_WRITEDEBUGREG 0x0f -#define STLINK_DEBUG_APIV1_SETWATCHPOINT 0x10 - -#define STLINK_DEBUG_ENTER_JTAG 0x00 -#define STLINK_DEBUG_ENTER_SWD 0xa3 - -#define STLINK_DEBUG_APIV1_ENTER 0x20 -#define STLINK_DEBUG_EXIT 0x21 -#define STLINK_DEBUG_READCOREID 0x22 - -#define STLINK_DEBUG_APIV2_ENTER 0x30 -#define STLINK_DEBUG_APIV2_READ_IDCODES 0x31 -#define STLINK_DEBUG_APIV2_RESETSYS 0x32 -#define STLINK_DEBUG_APIV2_READREG 0x33 -#define STLINK_DEBUG_APIV2_WRITEREG 0x34 -#define STLINK_DEBUG_APIV2_WRITEDEBUGREG 0x35 -#define STLINK_DEBUG_APIV2_READDEBUGREG 0x36 - -#define STLINK_DEBUG_APIV2_READALLREGS 0x3A -#define STLINK_DEBUG_APIV2_GETLASTRWSTATUS 0x3B -#define STLINK_DEBUG_APIV2_DRIVE_NRST 0x3C - -#define STLINK_DEBUG_APIV2_START_TRACE_RX 0x40 -#define STLINK_DEBUG_APIV2_STOP_TRACE_RX 0x41 -#define STLINK_DEBUG_APIV2_GET_TRACE_NB 0x42 -#define STLINK_DEBUG_APIV2_SWD_SET_FREQ 0x43 - -#define STLINK_DEBUG_APIV2_DRIVE_NRST_LOW 0x00 -#define STLINK_DEBUG_APIV2_DRIVE_NRST_HIGH 0x01 -#define STLINK_DEBUG_APIV2_DRIVE_NRST_PULSE 0x02 - -#define STLINK_TRACE_SIZE 1024 -#define STLINK_TRACE_MAX_HZ 2000000 -#define STLINK_TRACE_MIN_VERSION 13 - -/** */ -enum stlink_mode { - STLINK_MODE_UNKNOWN = 0, - STLINK_MODE_DFU, - STLINK_MODE_MASS, - STLINK_MODE_DEBUG_JTAG, - STLINK_MODE_DEBUG_SWD, - STLINK_MODE_DEBUG_SWIM -}; - -#define REQUEST_SENSE 0x03 -#define REQUEST_SENSE_LENGTH 18 - -static const struct { - int speed; - int speed_divisor; -} stlink_khz_to_speed_map[] = { - {4000, 0}, - {1800, 1}, /* default */ - {1200, 2}, - {950, 3}, - {480, 7}, - {240, 15}, - {125, 31}, - {100, 40}, - {50, 79}, - {25, 158}, - {15, 265}, - {5, 798} -}; - -static void stlink_usb_init_buffer(void *handle, uint8_t direction, uint32_t size); - -/** */ -static int stlink_usb_xfer_v1_get_status(void *handle) -{ - struct stlink_usb_handle_s *h = handle; - - assert(handle != NULL); - - /* read status */ - memset(h->cmdbuf, 0, STLINK_SG_SIZE); - - if (jtag_libusb_bulk_read(h->fd, h->rx_ep, (char *)h->cmdbuf, - 13, STLINK_READ_TIMEOUT) != 13) - return ERROR_FAIL; - - uint32_t t1; - - t1 = buf_get_u32(h->cmdbuf, 0, 32); - - /* check for USBS */ - if (t1 != 0x53425355) - return ERROR_FAIL; - /* - * CSW status: - * 0 success - * 1 command failure - * 2 phase error - */ - if (h->cmdbuf[12] != 0) - return ERROR_FAIL; - - return ERROR_OK; -} - -/** */ -static int stlink_usb_xfer_rw(void *handle, int cmdsize, const uint8_t *buf, int size) -{ - struct stlink_usb_handle_s *h = handle; - - assert(handle != NULL); - - if (jtag_libusb_bulk_write(h->fd, h->tx_ep, (char *)h->cmdbuf, cmdsize, - STLINK_WRITE_TIMEOUT) != cmdsize) { - return ERROR_FAIL; - } - - if (h->direction == h->tx_ep && size) { - if (jtag_libusb_bulk_write(h->fd, h->tx_ep, (char *)buf, - size, STLINK_WRITE_TIMEOUT) != size) { - LOG_DEBUG("bulk write failed"); - return ERROR_FAIL; - } - } else if (h->direction == h->rx_ep && size) { - if (jtag_libusb_bulk_read(h->fd, h->rx_ep, (char *)buf, - size, STLINK_READ_TIMEOUT) != size) { - LOG_DEBUG("bulk read failed"); - return ERROR_FAIL; - } - } - - return ERROR_OK; -} - -/** */ -static int stlink_usb_xfer_v1_get_sense(void *handle) -{ - int res; - struct stlink_usb_handle_s *h = handle; - - assert(handle != NULL); - - stlink_usb_init_buffer(handle, h->rx_ep, 16); - - h->cmdbuf[h->cmdidx++] = REQUEST_SENSE; - h->cmdbuf[h->cmdidx++] = 0; - h->cmdbuf[h->cmdidx++] = 0; - h->cmdbuf[h->cmdidx++] = 0; - h->cmdbuf[h->cmdidx++] = REQUEST_SENSE_LENGTH; - - res = stlink_usb_xfer_rw(handle, REQUEST_SENSE_LENGTH, h->databuf, 16); - - if (res != ERROR_OK) - return res; - - if (stlink_usb_xfer_v1_get_status(handle) != ERROR_OK) - return ERROR_FAIL; - - return ERROR_OK; -} - -/** */ -static int stlink_usb_xfer(void *handle, const uint8_t *buf, int size) -{ - int err, cmdsize = STLINK_CMD_SIZE_V2; - struct stlink_usb_handle_s *h = handle; - - assert(handle != NULL); - - if (h->version.stlink == 1) - cmdsize = STLINK_SG_SIZE; - - err = stlink_usb_xfer_rw(handle, cmdsize, buf, size); - - if (err != ERROR_OK) - return err; - - if (h->version.stlink == 1) { - if (stlink_usb_xfer_v1_get_status(handle) != ERROR_OK) { - /* check csw status */ - if (h->cmdbuf[12] == 1) { - LOG_DEBUG("get sense"); - if (stlink_usb_xfer_v1_get_sense(handle) != ERROR_OK) - return ERROR_FAIL; - } - return ERROR_FAIL; - } - } - - return ERROR_OK; -} - - -/** - Converts an STLINK status code held in the first byte of a response - to an openocd error, logs any error/wait status as debug output. -*/ -static int stlink_usb_error_check(void *handle) -{ - struct stlink_usb_handle_s *h = handle; - - assert(handle != NULL); - - /* TODO: no error checking yet on api V1 */ - if (h->jtag_api == STLINK_JTAG_API_V1) - h->databuf[0] = STLINK_DEBUG_ERR_OK; - - switch (h->databuf[0]) { - case STLINK_DEBUG_ERR_OK: - return ERROR_OK; - case STLINK_DEBUG_ERR_FAULT: - LOG_DEBUG("SWD fault response (0x%x)", STLINK_DEBUG_ERR_FAULT); - return ERROR_FAIL; - case STLINK_SWD_AP_WAIT: - LOG_DEBUG("wait status SWD_AP_WAIT (0x%x)", STLINK_SWD_AP_WAIT); - return ERROR_WAIT; - case STLINK_SWD_DP_WAIT: - LOG_DEBUG("wait status SWD_DP_WAIT (0x%x)", STLINK_SWD_DP_WAIT); - return ERROR_WAIT; - case STLINK_JTAG_WRITE_ERROR: - LOG_DEBUG("Write error"); - return ERROR_FAIL; - 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; - } -} - - -/** Issue an STLINK command via USB transfer, with retries on any wait status responses. - - Works for commands where the STLINK_DEBUG status is returned in the first - byte of the response packet. - - Returns an openocd result code. -*/ -static int stlink_cmd_allow_retry(void *handle, const uint8_t *buf, int size) -{ - int retries = 0; - int res; - while (1) { - res = stlink_usb_xfer(handle, buf, size); - if (res != ERROR_OK) - return res; - res = stlink_usb_error_check(handle); - if (res == ERROR_WAIT && retries < MAX_WAIT_RETRIES) { - usleep((1<version.stlink >= 2); - - if (jtag_libusb_bulk_read(h->fd, h->trace_ep, (char *)buf, - size, STLINK_READ_TIMEOUT) != size) { - LOG_ERROR("bulk trace read failed"); - return ERROR_FAIL; - } - - return ERROR_OK; -} - -/** */ -static void stlink_usb_xfer_v1_create_cmd(void *handle, uint8_t direction, uint32_t size) -{ - struct stlink_usb_handle_s *h = handle; - - /* fill the send buffer */ - strcpy((char *)h->cmdbuf, "USBC"); - h->cmdidx += 4; - /* csw tag not used */ - h->cmdidx += 4; - buf_set_u32(h->cmdbuf+h->cmdidx, 0, 32, size); - h->cmdidx += 4; - h->cmdbuf[h->cmdidx++] = (direction == h->rx_ep ? ENDPOINT_IN : ENDPOINT_OUT); - h->cmdbuf[h->cmdidx++] = 0; /* lun */ - h->cmdbuf[h->cmdidx++] = STLINK_CMD_SIZE_V1; -} - -/** */ -static void stlink_usb_init_buffer(void *handle, uint8_t direction, uint32_t size) -{ - struct stlink_usb_handle_s *h = handle; - - h->direction = direction; - - h->cmdidx = 0; - - memset(h->cmdbuf, 0, STLINK_SG_SIZE); - memset(h->databuf, 0, STLINK_DATA_SIZE); - - if (h->version.stlink == 1) - stlink_usb_xfer_v1_create_cmd(handle, direction, size); -} - -/** */ -static int stlink_usb_version(void *handle) -{ - int res; - uint16_t v; - struct stlink_usb_handle_s *h = handle; - - assert(handle != NULL); - - stlink_usb_init_buffer(handle, h->rx_ep, 6); - - h->cmdbuf[h->cmdidx++] = STLINK_GET_VERSION; - - res = stlink_usb_xfer(handle, h->databuf, 6); - - if (res != ERROR_OK) - return res; - - v = (h->databuf[0] << 8) | h->databuf[1]; - - h->version.stlink = (v >> 12) & 0x0f; - h->version.jtag = (v >> 6) & 0x3f; - h->version.swim = v & 0x3f; - h->vid = buf_get_u32(h->databuf, 16, 16); - h->pid = buf_get_u32(h->databuf, 32, 16); - - /* set the supported jtag api version - * API V2 is supported since JTAG V11 - */ - if (h->version.jtag >= 11) - h->version.jtag_api_max = STLINK_JTAG_API_V2; - else - h->version.jtag_api_max = STLINK_JTAG_API_V1; - - LOG_INFO("STLINK v%d JTAG v%d API v%d SWIM v%d VID 0x%04X PID 0x%04X", - h->version.stlink, - h->version.jtag, - (h->version.jtag_api_max == STLINK_JTAG_API_V1) ? 1 : 2, - h->version.swim, - h->vid, - h->pid); - - return ERROR_OK; -} - -static int stlink_usb_check_voltage(void *handle, float *target_voltage) -{ - struct stlink_usb_handle_s *h = handle; - uint32_t adc_results[2]; - - /* only supported by stlink/v2 and for firmware >= 13 */ - if (h->version.stlink == 1 || h->version.jtag < 13) - return ERROR_COMMAND_NOTFOUND; - - stlink_usb_init_buffer(handle, h->rx_ep, 8); - - h->cmdbuf[h->cmdidx++] = STLINK_GET_TARGET_VOLTAGE; - - int result = stlink_usb_xfer(handle, h->databuf, 8); - - if (result != ERROR_OK) - return result; - - /* convert result */ - adc_results[0] = le_to_h_u32(h->databuf); - adc_results[1] = le_to_h_u32(h->databuf + 4); - - *target_voltage = 0; - - if (adc_results[0]) - *target_voltage = 2 * ((float)adc_results[1]) * (float)(1.2 / adc_results[0]); - - LOG_INFO("Target voltage: %f", (double)*target_voltage); - - return ERROR_OK; -} - -static int stlink_usb_set_swdclk(void *handle, uint16_t clk_divisor) -{ - struct stlink_usb_handle_s *h = handle; - - assert(handle != NULL); - - /* only supported by stlink/v2 and for firmware >= 22 */ - if (h->version.stlink == 1 || h->version.jtag < 22) - return ERROR_COMMAND_NOTFOUND; - - stlink_usb_init_buffer(handle, h->rx_ep, 2); - - h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_COMMAND; - h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_APIV2_SWD_SET_FREQ; - h_u16_to_le(h->cmdbuf+h->cmdidx, clk_divisor); - h->cmdidx += 2; - - int result = stlink_cmd_allow_retry(handle, h->databuf, 2); - - if (result != ERROR_OK) - return result; - - return ERROR_OK; -} - -/** */ -static int stlink_usb_current_mode(void *handle, uint8_t *mode) -{ - int res; - struct stlink_usb_handle_s *h = handle; - - assert(handle != NULL); - - stlink_usb_init_buffer(handle, h->rx_ep, 2); - - h->cmdbuf[h->cmdidx++] = STLINK_GET_CURRENT_MODE; - - res = stlink_usb_xfer(handle, h->databuf, 2); - - if (res != ERROR_OK) - return res; - - *mode = h->databuf[0]; - - return ERROR_OK; -} - -/** */ -static int stlink_usb_mode_enter(void *handle, enum stlink_mode type) -{ - int rx_size = 0; - struct stlink_usb_handle_s *h = handle; - - assert(handle != NULL); - - /* on api V2 we are able the read the latest command - * status - * TODO: we need the test on api V1 too - */ - if (h->jtag_api == STLINK_JTAG_API_V2) - rx_size = 2; - - stlink_usb_init_buffer(handle, h->rx_ep, rx_size); - - switch (type) { - case STLINK_MODE_DEBUG_JTAG: - h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_COMMAND; - if (h->jtag_api == STLINK_JTAG_API_V1) - h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_APIV1_ENTER; - else - h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_APIV2_ENTER; - h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_ENTER_JTAG; - break; - case STLINK_MODE_DEBUG_SWD: - h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_COMMAND; - if (h->jtag_api == STLINK_JTAG_API_V1) - h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_APIV1_ENTER; - else - h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_APIV2_ENTER; - h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_ENTER_SWD; - break; - case STLINK_MODE_DEBUG_SWIM: - h->cmdbuf[h->cmdidx++] = STLINK_SWIM_COMMAND; - h->cmdbuf[h->cmdidx++] = STLINK_SWIM_ENTER; - break; - case STLINK_MODE_DFU: - case STLINK_MODE_MASS: - default: - return ERROR_FAIL; - } - - return stlink_cmd_allow_retry(handle, h->databuf, rx_size); -} - -/** */ -static int stlink_usb_mode_leave(void *handle, enum stlink_mode type) -{ - int res; - struct stlink_usb_handle_s *h = handle; - - assert(handle != NULL); - - stlink_usb_init_buffer(handle, STLINK_NULL_EP, 0); - - switch (type) { - case STLINK_MODE_DEBUG_JTAG: - case STLINK_MODE_DEBUG_SWD: - h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_COMMAND; - h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_EXIT; - break; - case STLINK_MODE_DEBUG_SWIM: - h->cmdbuf[h->cmdidx++] = STLINK_SWIM_COMMAND; - h->cmdbuf[h->cmdidx++] = STLINK_SWIM_EXIT; - break; - case STLINK_MODE_DFU: - h->cmdbuf[h->cmdidx++] = STLINK_DFU_COMMAND; - h->cmdbuf[h->cmdidx++] = STLINK_DFU_EXIT; - break; - case STLINK_MODE_MASS: - default: - return ERROR_FAIL; - } - - res = stlink_usb_xfer(handle, 0, 0); - - if (res != ERROR_OK) - return res; - - return ERROR_OK; -} - -static int stlink_usb_assert_srst(void *handle, int srst); - -static enum stlink_mode stlink_get_mode(enum hl_transports t) -{ - switch (t) { - case HL_TRANSPORT_SWD: - return STLINK_MODE_DEBUG_SWD; - case HL_TRANSPORT_JTAG: - return STLINK_MODE_DEBUG_JTAG; - case HL_TRANSPORT_SWIM: - return STLINK_MODE_DEBUG_SWIM; - default: - return STLINK_MODE_UNKNOWN; - } -} - -/** */ -static int stlink_usb_init_mode(void *handle, bool connect_under_reset) -{ - int res; - uint8_t mode; - enum stlink_mode emode; - struct stlink_usb_handle_s *h = handle; - - assert(handle != NULL); - - res = stlink_usb_current_mode(handle, &mode); - - if (res != ERROR_OK) - return res; - - LOG_DEBUG("MODE: 0x%02X", mode); - - /* try to exit current mode */ - switch (mode) { - case STLINK_DEV_DFU_MODE: - emode = STLINK_MODE_DFU; - break; - case STLINK_DEV_DEBUG_MODE: - emode = STLINK_MODE_DEBUG_SWD; - break; - case STLINK_DEV_SWIM_MODE: - emode = STLINK_MODE_DEBUG_SWIM; - break; - case STLINK_DEV_BOOTLOADER_MODE: - case STLINK_DEV_MASS_MODE: - default: - emode = STLINK_MODE_UNKNOWN; - break; - } - - if (emode != STLINK_MODE_UNKNOWN) { - res = stlink_usb_mode_leave(handle, emode); - - if (res != ERROR_OK) - return res; - } - - res = stlink_usb_current_mode(handle, &mode); - - if (res != ERROR_OK) - return res; - - /* we check the target voltage here as an aid to debugging connection problems. - * the stlink requires the target Vdd to be connected for reliable debugging. - * this cmd is supported in all modes except DFU - */ - if (mode != STLINK_DEV_DFU_MODE) { - - float target_voltage; - - /* check target voltage (if supported) */ - res = stlink_usb_check_voltage(h, &target_voltage); - - if (res != ERROR_OK) { - if (res != ERROR_COMMAND_NOTFOUND) - LOG_ERROR("voltage check failed"); - /* attempt to continue as it is not a catastrophic failure */ - } else { - /* check for a sensible target voltage, operating range is 1.65-5.5v - * according to datasheet */ - if (target_voltage < 1.5) - LOG_ERROR("target voltage may be too low for reliable debugging"); - } - } - - LOG_DEBUG("MODE: 0x%02X", mode); - - /* set selected mode */ - emode = stlink_get_mode(h->transport); - - if (emode == STLINK_MODE_UNKNOWN) { - LOG_ERROR("selected mode (transport) not supported"); - return ERROR_FAIL; - } - - if (connect_under_reset) { - res = stlink_usb_assert_srst(handle, 0); - if (res != ERROR_OK) - return res; - } - - res = stlink_usb_mode_enter(handle, emode); - - if (res != ERROR_OK) - return res; - - res = stlink_usb_current_mode(handle, &mode); - - if (res != ERROR_OK) - return res; - - LOG_DEBUG("MODE: 0x%02X", mode); - - return ERROR_OK; -} - -/** */ -static int stlink_usb_idcode(void *handle, uint32_t *idcode) -{ - int res; - struct stlink_usb_handle_s *h = handle; - - assert(handle != NULL); - - stlink_usb_init_buffer(handle, h->rx_ep, 4); - - h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_COMMAND; - h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_READCOREID; - - res = stlink_usb_xfer(handle, h->databuf, 4); - - if (res != ERROR_OK) - return res; - - *idcode = le_to_h_u32(h->databuf); - - LOG_DEBUG("IDCODE: 0x%08" PRIX32, *idcode); - - return ERROR_OK; -} - -static int stlink_usb_v2_read_debug_reg(void *handle, uint32_t addr, uint32_t *val) -{ - struct stlink_usb_handle_s *h = handle; - int res; - - assert(handle != NULL); - - stlink_usb_init_buffer(handle, h->rx_ep, 8); - - h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_COMMAND; - h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_APIV2_READDEBUGREG; - h_u32_to_le(h->cmdbuf+h->cmdidx, addr); - h->cmdidx += 4; - - res = stlink_cmd_allow_retry(handle, h->databuf, 8); - if (res != ERROR_OK) - return res; - - *val = le_to_h_u32(h->databuf + 4); - return ERROR_OK; -} - -static int stlink_usb_write_debug_reg(void *handle, uint32_t addr, uint32_t val) -{ - struct stlink_usb_handle_s *h = handle; - - assert(handle != NULL); - - stlink_usb_init_buffer(handle, h->rx_ep, 2); - - h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_COMMAND; - if (h->jtag_api == STLINK_JTAG_API_V1) - h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_APIV1_WRITEDEBUGREG; - else - h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_APIV2_WRITEDEBUGREG; - h_u32_to_le(h->cmdbuf+h->cmdidx, addr); - h->cmdidx += 4; - h_u32_to_le(h->cmdbuf+h->cmdidx, val); - h->cmdidx += 4; - - return stlink_cmd_allow_retry(handle, h->databuf, 2); -} - -/** */ -static int stlink_usb_trace_read(void *handle, uint8_t *buf, size_t *size) -{ - struct stlink_usb_handle_s *h = handle; - - assert(handle != NULL); - - if (h->trace.enabled && h->version.jtag >= STLINK_TRACE_MIN_VERSION) { - int res; - - stlink_usb_init_buffer(handle, h->rx_ep, 10); - - h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_COMMAND; - h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_APIV2_GET_TRACE_NB; - - res = stlink_usb_xfer(handle, h->databuf, 2); - if (res != ERROR_OK) - return res; - - size_t bytes_avail = le_to_h_u16(h->databuf); - *size = bytes_avail < *size ? bytes_avail : *size - 1; - - if (*size > 0) { - res = stlink_usb_read_trace(handle, buf, *size); - if (res != ERROR_OK) - return res; - return ERROR_OK; - } - } - *size = 0; - return ERROR_OK; -} - -static enum target_state stlink_usb_v2_get_status(void *handle) -{ - int result; - uint32_t status; - - result = stlink_usb_v2_read_debug_reg(handle, DCB_DHCSR, &status); - if (result != ERROR_OK) - return TARGET_UNKNOWN; - - if (status & S_HALT) - return TARGET_HALTED; - else if (status & S_RESET_ST) - return TARGET_RESET; - - return TARGET_RUNNING; -} - -/** */ -static enum target_state stlink_usb_state(void *handle) -{ - int res; - struct stlink_usb_handle_s *h = handle; - - assert(handle != NULL); - - if (h->reconnect_pending) { - LOG_INFO("Previous state query failed, trying to reconnect"); - res = stlink_usb_mode_enter(handle, stlink_get_mode(h->transport)); - - if (res != ERROR_OK) - return TARGET_UNKNOWN; - - h->reconnect_pending = false; - } - - if (h->jtag_api == STLINK_JTAG_API_V2) { - res = stlink_usb_v2_get_status(handle); - if (res == TARGET_UNKNOWN) - h->reconnect_pending = true; - return res; - } - - stlink_usb_init_buffer(handle, h->rx_ep, 2); - - h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_COMMAND; - h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_GETSTATUS; - - res = stlink_usb_xfer(handle, h->databuf, 2); - - if (res != ERROR_OK) - return TARGET_UNKNOWN; - - if (h->databuf[0] == STLINK_CORE_RUNNING) - return TARGET_RUNNING; - if (h->databuf[0] == STLINK_CORE_HALTED) - return TARGET_HALTED; - - h->reconnect_pending = true; - - return TARGET_UNKNOWN; -} - -static int stlink_usb_assert_srst(void *handle, int srst) -{ - struct stlink_usb_handle_s *h = handle; - - assert(handle != NULL); - - if (h->version.stlink == 1) - return ERROR_COMMAND_NOTFOUND; - - stlink_usb_init_buffer(handle, h->rx_ep, 2); - - h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_COMMAND; - h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_APIV2_DRIVE_NRST; - h->cmdbuf[h->cmdidx++] = srst; - - return stlink_cmd_allow_retry(handle, h->databuf, 2); -} - -/** */ -static void stlink_usb_trace_disable(void *handle) -{ - int res = ERROR_OK; - struct stlink_usb_handle_s *h = handle; - - assert(handle != NULL); - - assert(h->version.jtag >= STLINK_TRACE_MIN_VERSION); - - LOG_DEBUG("Tracing: disable"); - - stlink_usb_init_buffer(handle, h->rx_ep, 2); - h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_COMMAND; - h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_APIV2_STOP_TRACE_RX; - res = stlink_usb_xfer(handle, h->databuf, 2); - - if (res == ERROR_OK) - h->trace.enabled = false; -} - - -/** */ -static int stlink_usb_trace_enable(void *handle) -{ - int res; - struct stlink_usb_handle_s *h = handle; - - assert(handle != NULL); - - if (h->version.jtag >= STLINK_TRACE_MIN_VERSION) { - stlink_usb_init_buffer(handle, h->rx_ep, 10); - - h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_COMMAND; - h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_APIV2_START_TRACE_RX; - h_u16_to_le(h->cmdbuf+h->cmdidx, (uint16_t)STLINK_TRACE_SIZE); - h->cmdidx += 2; - h_u32_to_le(h->cmdbuf+h->cmdidx, h->trace.source_hz); - h->cmdidx += 4; - - res = stlink_usb_xfer(handle, h->databuf, 2); - - if (res == ERROR_OK) { - h->trace.enabled = true; - LOG_DEBUG("Tracing: recording at %" PRIu32 "Hz", h->trace.source_hz); - } - } else { - LOG_ERROR("Tracing is not supported by this version."); - res = ERROR_FAIL; - } - - return res; -} - -/** */ -static int stlink_usb_reset(void *handle) -{ - struct stlink_usb_handle_s *h = handle; - int retval; - - assert(handle != NULL); - - stlink_usb_init_buffer(handle, h->rx_ep, 2); - - h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_COMMAND; - - if (h->jtag_api == STLINK_JTAG_API_V1) - h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_APIV1_RESETSYS; - else - h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_APIV2_RESETSYS; - - retval = stlink_cmd_allow_retry(handle, h->databuf, 2); - if (retval != ERROR_OK) - return retval; - - if (h->trace.enabled) { - stlink_usb_trace_disable(h); - return stlink_usb_trace_enable(h); - } - - return ERROR_OK; -} - -/** */ -static int stlink_usb_run(void *handle) -{ - int res; - struct stlink_usb_handle_s *h = handle; - - assert(handle != NULL); - - if (h->jtag_api == STLINK_JTAG_API_V2) { - res = stlink_usb_write_debug_reg(handle, DCB_DHCSR, DBGKEY|C_DEBUGEN); - - return res; - } - - stlink_usb_init_buffer(handle, h->rx_ep, 2); - - h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_COMMAND; - h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_RUNCORE; - - return stlink_cmd_allow_retry(handle, h->databuf, 2); -} - -/** */ -static int stlink_usb_halt(void *handle) -{ - int res; - struct stlink_usb_handle_s *h = handle; - - assert(handle != NULL); - - if (h->jtag_api == STLINK_JTAG_API_V2) { - res = stlink_usb_write_debug_reg(handle, DCB_DHCSR, DBGKEY|C_HALT|C_DEBUGEN); - - return res; - } - - stlink_usb_init_buffer(handle, h->rx_ep, 2); - - h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_COMMAND; - h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_FORCEDEBUG; - - return stlink_cmd_allow_retry(handle, h->databuf, 2); -} - -/** */ -static int stlink_usb_step(void *handle) -{ - struct stlink_usb_handle_s *h = handle; - - assert(handle != NULL); - - 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. */ - 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); - } - - stlink_usb_init_buffer(handle, h->rx_ep, 2); - - h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_COMMAND; - h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_STEPCORE; - - return stlink_cmd_allow_retry(handle, h->databuf, 2); -} - -/** */ -static int stlink_usb_read_regs(void *handle) -{ - int res; - struct stlink_usb_handle_s *h = handle; - - assert(handle != NULL); - - stlink_usb_init_buffer(handle, h->rx_ep, 84); - - h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_COMMAND; - if (h->jtag_api == STLINK_JTAG_API_V1) - h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_APIV1_READALLREGS; - else - h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_APIV2_READALLREGS; - - res = stlink_usb_xfer(handle, h->databuf, 84); - - if (res != ERROR_OK) - return res; - - return ERROR_OK; -} - -/** */ -static int stlink_usb_read_reg(void *handle, int num, uint32_t *val) -{ - int res; - struct stlink_usb_handle_s *h = handle; - - assert(handle != NULL); - - stlink_usb_init_buffer(handle, h->rx_ep, h->jtag_api == STLINK_JTAG_API_V1 ? 4 : 8); - - h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_COMMAND; - if (h->jtag_api == STLINK_JTAG_API_V1) - h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_APIV1_READREG; - else - h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_APIV2_READREG; - h->cmdbuf[h->cmdidx++] = num; - - if (h->jtag_api == STLINK_JTAG_API_V1) { - res = stlink_usb_xfer(handle, h->databuf, 4); - if (res != ERROR_OK) - return res; - *val = le_to_h_u32(h->databuf); - return ERROR_OK; - } else { - res = stlink_cmd_allow_retry(handle, h->databuf, 8); - if (res != ERROR_OK) - return res; - *val = le_to_h_u32(h->databuf + 4); - return ERROR_OK; - } -} - -/** */ -static int stlink_usb_write_reg(void *handle, int num, uint32_t val) -{ - struct stlink_usb_handle_s *h = handle; - - assert(handle != NULL); - - stlink_usb_init_buffer(handle, h->rx_ep, 2); - - h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_COMMAND; - if (h->jtag_api == STLINK_JTAG_API_V1) - h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_APIV1_WRITEREG; - else - h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_APIV2_WRITEREG; - h->cmdbuf[h->cmdidx++] = num; - h_u32_to_le(h->cmdbuf+h->cmdidx, val); - h->cmdidx += 4; - - return stlink_cmd_allow_retry(handle, h->databuf, 2); -} - -static int stlink_usb_get_rw_status(void *handle) -{ - int res; - struct stlink_usb_handle_s *h = handle; - - assert(handle != NULL); - - if (h->jtag_api == STLINK_JTAG_API_V1) - return ERROR_OK; - - stlink_usb_init_buffer(handle, h->rx_ep, 2); - - h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_COMMAND; - h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_APIV2_GETLASTRWSTATUS; - - res = stlink_usb_xfer(handle, h->databuf, 2); - - if (res != ERROR_OK) - return res; - - return stlink_usb_error_check(h); -} - -/** */ -static int stlink_usb_read_mem8(void *handle, uint32_t addr, uint16_t len, - uint8_t *buffer) -{ - int res; - uint16_t read_len = len; - struct stlink_usb_handle_s *h = handle; - - assert(handle != NULL); - - /* max 8bit read/write is 64bytes */ - if (len > STLINK_MAX_RW8) { - LOG_DEBUG("max buffer length exceeded"); - return ERROR_FAIL; - } - - stlink_usb_init_buffer(handle, h->rx_ep, read_len); - - h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_COMMAND; - h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_READMEM_8BIT; - h_u32_to_le(h->cmdbuf+h->cmdidx, addr); - h->cmdidx += 4; - h_u16_to_le(h->cmdbuf+h->cmdidx, len); - h->cmdidx += 2; - - /* we need to fix read length for single bytes */ - if (read_len == 1) - read_len++; - - res = stlink_usb_xfer(handle, h->databuf, read_len); - - if (res != ERROR_OK) - return res; - - memcpy(buffer, h->databuf, len); - - return stlink_usb_get_rw_status(handle); -} - -/** */ -static int stlink_usb_write_mem8(void *handle, uint32_t addr, uint16_t len, - const uint8_t *buffer) -{ - int res; - struct stlink_usb_handle_s *h = handle; - - assert(handle != NULL); - - /* max 8bit read/write is 64bytes */ - if (len > STLINK_MAX_RW8) { - LOG_DEBUG("max buffer length exceeded"); - return ERROR_FAIL; - } - - stlink_usb_init_buffer(handle, h->tx_ep, len); - - h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_COMMAND; - h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_WRITEMEM_8BIT; - h_u32_to_le(h->cmdbuf+h->cmdidx, addr); - h->cmdidx += 4; - h_u16_to_le(h->cmdbuf+h->cmdidx, len); - h->cmdidx += 2; - - res = stlink_usb_xfer(handle, buffer, len); - - if (res != ERROR_OK) - return res; - - return stlink_usb_get_rw_status(handle); -} - -/** */ -static int stlink_usb_read_mem32(void *handle, uint32_t addr, uint16_t len, - uint8_t *buffer) -{ - int res; - struct stlink_usb_handle_s *h = handle; - - assert(handle != NULL); - - /* data must be a multiple of 4 and word aligned */ - if (len % 4 || addr % 4) { - LOG_DEBUG("Invalid data alignment"); - return ERROR_TARGET_UNALIGNED_ACCESS; - } - - stlink_usb_init_buffer(handle, h->rx_ep, len); - - h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_COMMAND; - h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_READMEM_32BIT; - h_u32_to_le(h->cmdbuf+h->cmdidx, addr); - h->cmdidx += 4; - h_u16_to_le(h->cmdbuf+h->cmdidx, len); - h->cmdidx += 2; - - res = stlink_usb_xfer(handle, h->databuf, len); - - if (res != ERROR_OK) - return res; - - memcpy(buffer, h->databuf, len); - - return stlink_usb_get_rw_status(handle); -} - -/** */ -static int stlink_usb_write_mem32(void *handle, uint32_t addr, uint16_t len, - const uint8_t *buffer) -{ - int res; - struct stlink_usb_handle_s *h = handle; - - assert(handle != NULL); - - /* data must be a multiple of 4 and word aligned */ - if (len % 4 || addr % 4) { - LOG_DEBUG("Invalid data alignment"); - return ERROR_TARGET_UNALIGNED_ACCESS; - } - - stlink_usb_init_buffer(handle, h->tx_ep, len); - - h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_COMMAND; - h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_WRITEMEM_32BIT; - h_u32_to_le(h->cmdbuf+h->cmdidx, addr); - h->cmdidx += 4; - h_u16_to_le(h->cmdbuf+h->cmdidx, len); - h->cmdidx += 2; - - res = stlink_usb_xfer(handle, buffer, len); - - if (res != ERROR_OK) - return res; - - return stlink_usb_get_rw_status(handle); -} - -static uint32_t stlink_max_block_size(uint32_t tar_autoincr_block, uint32_t address) -{ - uint32_t max_tar_block = (tar_autoincr_block - ((tar_autoincr_block - 1) & address)); - if (max_tar_block == 0) - max_tar_block = 4; - return max_tar_block; -} - -static int stlink_usb_read_mem(void *handle, uint32_t addr, uint32_t size, - uint32_t count, uint8_t *buffer) -{ - int retval = ERROR_OK; - uint32_t bytes_remaining; - int retries = 0; - struct stlink_usb_handle_s *h = handle; - - /* calculate byte count */ - count *= size; - - while (count) { - - bytes_remaining = (size == 4) ? \ - stlink_max_block_size(h->max_mem_packet, addr) : STLINK_MAX_RW8; - - if (count < bytes_remaining) - bytes_remaining = count; - - /* the stlink only supports 8/32bit memory read/writes - * honour 32bit, all others will be handled as 8bit access */ - if (size == 4) { - - /* When in jtag mode the stlink uses the auto-increment functinality. - * However it expects us to pass the data correctly, this includes - * alignment and any page boundaries. We already do this as part of the - * adi_v5 implementation, but the stlink is a hla adapter and so this - * needs implementiong manually. - * currently this only affects jtag mode, according to ST they do single - * access in SWD mode - but this may change and so we do it for both modes */ - - /* we first need to check for any unaligned bytes */ - if (addr % 4) { - - uint32_t head_bytes = 4 - (addr % 4); - retval = stlink_usb_read_mem8(handle, addr, head_bytes, buffer); - if (retval == ERROR_WAIT && retries < MAX_WAIT_RETRIES) { - usleep((1<max_mem_packet, addr) : STLINK_MAX_RW8; - - if (count < bytes_remaining) - bytes_remaining = count; - - /* the stlink only supports 8/32bit memory read/writes - * honour 32bit, all others will be handled as 8bit access */ - if (size == 4) { - - /* When in jtag mode the stlink uses the auto-increment functinality. - * However it expects us to pass the data correctly, this includes - * alignment and any page boundaries. We already do this as part of the - * adi_v5 implementation, but the stlink is a hla adapter and so this - * needs implementiong manually. - * currently this only affects jtag mode, according to ST they do single - * access in SWD mode - but this may change and so we do it for both modes */ - - /* we first need to check for any unaligned bytes */ - if (addr % 4) { - - uint32_t head_bytes = 4 - (addr % 4); - retval = stlink_usb_write_mem8(handle, addr, head_bytes, buffer); - if (retval == ERROR_WAIT && retries < MAX_WAIT_RETRIES) { - usleep((1<= 22 */ - if (h && (h->version.stlink == 1 || h->version.jtag < 22)) - return khz; - - for (i = 0; i < ARRAY_SIZE(stlink_khz_to_speed_map); i++) { - if (khz == stlink_khz_to_speed_map[i].speed) { - speed_index = i; - break; - } else { - int current_diff = khz - stlink_khz_to_speed_map[i].speed; - /* get abs value for comparison */ - current_diff = (current_diff > 0) ? current_diff : -current_diff; - if ((current_diff < speed_diff) && khz >= stlink_khz_to_speed_map[i].speed) { - speed_diff = current_diff; - speed_index = i; - } - } - } - - bool match = true; - - if (speed_index == -1) { - /* this will only be here if we cannot match the slow speed. - * use the slowest speed we support.*/ - speed_index = ARRAY_SIZE(stlink_khz_to_speed_map) - 1; - match = false; - } else if (i == ARRAY_SIZE(stlink_khz_to_speed_map)) - match = false; - - if (!match && query) { - LOG_INFO("Unable to match requested speed %d kHz, using %d kHz", \ - khz, stlink_khz_to_speed_map[speed_index].speed); - } - - if (h && !query) { - int result = stlink_usb_set_swdclk(h, stlink_khz_to_speed_map[speed_index].speed_divisor); - if (result != ERROR_OK) { - LOG_ERROR("Unable to set adapter speed"); - return khz; - } - } - - return stlink_khz_to_speed_map[speed_index].speed; -} - -/** */ -static int stlink_usb_close(void *handle) -{ - struct stlink_usb_handle_s *h = handle; - - if (h && h->fd) - jtag_libusb_close(h->fd); - - free(h); - - return ERROR_OK; -} - -/** */ -static int stlink_usb_open(struct hl_interface_param_s *param, void **fd) -{ - int err, retry_count = 1; - struct stlink_usb_handle_s *h; - enum stlink_jtag_api_version api; - - LOG_DEBUG("stlink_usb_open"); - - h = calloc(1, sizeof(struct stlink_usb_handle_s)); - - if (h == 0) { - LOG_DEBUG("malloc failed"); - return ERROR_FAIL; - } - - h->transport = param->transport; - - const uint16_t vids[] = { param->vid, 0 }; - const uint16_t pids[] = { param->pid, 0 }; - const char *serial = param->serial; - - LOG_DEBUG("transport: %d vid: 0x%04x pid: 0x%04x serial: %s", - param->transport, param->vid, param->pid, - param->serial ? param->serial : ""); - - /* - On certain host USB configurations(e.g. MacBook Air) - STLINKv2 dongle seems to have its FW in a funky state if, - after plugging it in, you try to use openocd with it more - then once (by launching and closing openocd). In cases like - that initial attempt to read the FW info via - stlink_usb_version will fail and the device has to be reset - in order to become operational. - */ - do { - if (jtag_libusb_open(vids, pids, serial, &h->fd) != ERROR_OK) { - LOG_ERROR("open failed"); - goto error_open; - } - - jtag_libusb_set_configuration(h->fd, 0); - - if (jtag_libusb_claim_interface(h->fd, 0) != ERROR_OK) { - LOG_DEBUG("claim interface failed"); - goto error_open; - } - - /* RX EP is common for all versions */ - h->rx_ep = STLINK_RX_EP; - - /* wrap version for first read */ - switch (param->pid) { - case STLINK_V1_PID: - h->version.stlink = 1; - h->tx_ep = STLINK_TX_EP; - h->trace_ep = STLINK_TRACE_EP; - break; - case STLINK_V2_1_PID: - h->version.stlink = 2; - h->tx_ep = STLINK_V2_1_TX_EP; - h->trace_ep = STLINK_V2_1_TRACE_EP; - break; - default: - /* fall through - we assume V2 to be the default version*/ - case STLINK_V2_PID: - h->version.stlink = 2; - h->tx_ep = STLINK_TX_EP; - h->trace_ep = STLINK_TRACE_EP; - break; - } - - /* get the device version */ - err = stlink_usb_version(h); - - if (err == ERROR_OK) { - break; - } else if (h->version.stlink == 1 || - retry_count == 0) { - LOG_ERROR("read version failed"); - goto error_open; - } else { - err = jtag_libusb_release_interface(h->fd, 0); - if (err != ERROR_OK) { - LOG_ERROR("release interface failed"); - goto error_open; - } - - err = jtag_libusb_reset_device(h->fd); - if (err != ERROR_OK) { - LOG_ERROR("reset device failed"); - goto error_open; - } - - jtag_libusb_close(h->fd); - /* - Give the device one second to settle down and - reenumerate. - */ - usleep(1 * 1000 * 1000); - retry_count--; - } - } while (1); - - /* compare usb vid/pid */ - if ((param->vid != h->vid) || (param->pid != h->pid)) - LOG_INFO("vid/pid are not identical: 0x%04X/0x%04X 0x%04X/0x%04X", - param->vid, param->pid, - h->vid, h->pid); - - /* check if mode is supported */ - err = ERROR_OK; - - switch (h->transport) { - case HL_TRANSPORT_SWD: - case HL_TRANSPORT_JTAG: - if (h->version.jtag == 0) - err = ERROR_FAIL; - break; - case HL_TRANSPORT_SWIM: - if (h->version.swim == 0) - err = ERROR_FAIL; - break; - default: - err = ERROR_FAIL; - break; - } - - if (err != ERROR_OK) { - LOG_ERROR("mode (transport) not supported by device"); - goto error_open; - } - - api = h->version.jtag_api_max; - - LOG_INFO("using stlink api v%d", api); - - /* set the used jtag api, this will default to the newest supported version */ - h->jtag_api = api; - - /* initialize the debug hardware */ - err = stlink_usb_init_mode(h, param->connect_under_reset); - - if (err != ERROR_OK) { - LOG_ERROR("init mode failed (unable to connect to the target)"); - goto error_open; - } - - /* clock speed only supported by stlink/v2 and for firmware >= 22 */ - if (h->version.stlink >= 2 && h->version.jtag >= 22) { - LOG_DEBUG("Supported clock speeds are:"); - - for (unsigned i = 0; i < ARRAY_SIZE(stlink_khz_to_speed_map); i++) - LOG_DEBUG("%d kHz", stlink_khz_to_speed_map[i].speed); - - stlink_speed(h, param->initial_interface_speed, false); - } - - /* get cpuid, so we can determine the max page size - * start with a safe default */ - h->max_mem_packet = (1 << 10); - - uint8_t buffer[4]; - err = stlink_usb_read_mem32(h, CPUID, 4, buffer); - if (err == ERROR_OK) { - uint32_t cpuid = le_to_h_u32(buffer); - int i = (cpuid >> 4) & 0xf; - if (i == 4 || i == 3) { - /* Cortex-M3/M4 has 4096 bytes autoincrement range */ - h->max_mem_packet = (1 << 12); - } - } - - LOG_DEBUG("Using TAR autoincrement: %" PRIu32, h->max_mem_packet); - - *fd = h; - - return ERROR_OK; - -error_open: - stlink_usb_close(h); - - return ERROR_FAIL; -} - -int stlink_config_trace(void *handle, bool enabled, enum tpio_pin_protocol pin_protocol, - uint32_t port_size, unsigned int *trace_freq) -{ - struct stlink_usb_handle_s *h = handle; - - if (enabled && (h->jtag_api < 2 || pin_protocol != ASYNC_UART)) { - LOG_ERROR("The attached ST-LINK version doesn't support this trace mode"); - return ERROR_FAIL; - } - - if (!enabled) { - stlink_usb_trace_disable(h); - return ERROR_OK; - } - - if (*trace_freq > STLINK_TRACE_MAX_HZ) { - LOG_ERROR("ST-LINK doesn't support SWO frequency higher than %u", - STLINK_TRACE_MAX_HZ); - return ERROR_FAIL; - } - - stlink_usb_trace_disable(h); - - if (!*trace_freq) - *trace_freq = STLINK_TRACE_MAX_HZ; - h->trace.source_hz = *trace_freq; - - return stlink_usb_trace_enable(h); -} - -/** */ -struct hl_layout_api_s stlink_usb_layout_api = { - /** */ - .open = stlink_usb_open, - /** */ - .close = stlink_usb_close, - /** */ - .idcode = stlink_usb_idcode, - /** */ - .state = stlink_usb_state, - /** */ - .reset = stlink_usb_reset, - /** */ - .assert_srst = stlink_usb_assert_srst, - /** */ - .run = stlink_usb_run, - /** */ - .halt = stlink_usb_halt, - /** */ - .step = stlink_usb_step, - /** */ - .read_regs = stlink_usb_read_regs, - /** */ - .read_reg = stlink_usb_read_reg, - /** */ - .write_reg = stlink_usb_write_reg, - /** */ - .read_mem = stlink_usb_read_mem, - /** */ - .write_mem = stlink_usb_write_mem, - /** */ - .write_debug_reg = stlink_usb_write_debug_reg, - /** */ - .override_target = stlink_usb_override_target, - /** */ - .speed = stlink_speed, - /** */ - .config_trace = stlink_config_trace, - /** */ - .poll_trace = stlink_usb_trace_read, -}; diff --git a/src/jtag/drivers/sysfsgpio.c b/src/jtag/drivers/sysfsgpio.c deleted file mode 100644 index 77b727c27..000000000 --- a/src/jtag/drivers/sysfsgpio.c +++ /dev/null @@ -1,681 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2012 by Creative Product Design, marc @ cpdesign.com.au * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -/* 2014-12: Addition of the SWD protocol support is based on the initial work - * on bcm2835gpio.c by Paul Fertser and modifications by Jean-Christian de Rivaz. */ - -/** - * @file - * This driver implements a bitbang jtag interface using gpio lines via - * sysfs. - * The aim of this driver implementation is use system GPIOs but avoid the - * need for a additional kernel driver. - * (Note memory mapped IO is another option, however it doesn't mix well with - * the kernel gpiolib driver - which makes sense I guess.) - * - * A gpio is required for tck, tms, tdi and tdo. One or both of srst and trst - * must be also be specified. The required jtag gpios are specified via the - * sysfsgpio_jtag_nums command or the relevant sysfsgpio_XXX_num commang. - * The srst and trst gpios are set via the sysfsgpio_srst_num and - * sysfsgpio_trst_num respectively. GPIO numbering follows the kernel - * convention of starting from 0. - * - * The gpios should not be in use by another entity, and must not be requested - * by a kernel driver without also being exported by it (otherwise they can't - * be exported by sysfs). - * - * The sysfs gpio interface can only manipulate one gpio at a time, so the - * bitbang write handler remembers the last state for tck, tms, tdi to avoid - * superfluous writes. - * For speed the sysfs "value" entry is opened at init and held open. - * This results in considerable gains over open-write-close (45s vs 900s) - * - * Further work could address: - * -srst and trst open drain/ push pull - * -configurable active high/low for srst & trst - */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include "bitbang.h" - -/* - * Helper func to determine if gpio number valid - * - * Assume here that there will be less than 1000 gpios on a system - */ -static int is_gpio_valid(int gpio) -{ - return gpio >= 0 && gpio < 1000; -} - -/* - * Helper func to open, write to and close a file - * name and valstr must be null terminated. - * - * Returns negative on failure. - */ -static int open_write_close(const char *name, const char *valstr) -{ - int ret; - int fd = open(name, O_WRONLY); - if (fd < 0) - return fd; - - ret = write(fd, valstr, strlen(valstr)); - close(fd); - - return ret; -} - -/* - * Helper func to unexport gpio from sysfs - */ -static void unexport_sysfs_gpio(int gpio) -{ - char gpiostr[4]; - - if (!is_gpio_valid(gpio)) - return; - - snprintf(gpiostr, sizeof(gpiostr), "%d", gpio); - if (open_write_close("/sys/class/gpio/unexport", gpiostr) < 0) - LOG_ERROR("Couldn't unexport gpio %d", gpio); - - return; -} - -/* - * Exports and sets up direction for gpio. - * If the gpio is an output, it is initialized according to init_high, - * otherwise it is ignored. - * - * If the gpio is already exported we just show a warning and continue; if - * openocd happened to crash (or was killed by user) then the gpios will not - * have been cleaned up. - */ -static int setup_sysfs_gpio(int gpio, int is_output, int init_high) -{ - char buf[40]; - char gpiostr[4]; - int ret; - - if (!is_gpio_valid(gpio)) - return ERROR_OK; - - snprintf(gpiostr, sizeof(gpiostr), "%d", gpio); - ret = open_write_close("/sys/class/gpio/export", gpiostr); - if (ret < 0) { - if (errno == EBUSY) { - LOG_WARNING("gpio %d is already exported", gpio); - } else { - LOG_ERROR("Couldn't export gpio %d", gpio); - perror("sysfsgpio: "); - return ERROR_FAIL; - } - } - - snprintf(buf, sizeof(buf), "/sys/class/gpio/gpio%d/direction", gpio); - ret = open_write_close(buf, is_output ? (init_high ? "high" : "low") : "in"); - if (ret < 0) { - LOG_ERROR("Couldn't set direction for gpio %d", gpio); - perror("sysfsgpio: "); - unexport_sysfs_gpio(gpio); - return ERROR_FAIL; - } - - snprintf(buf, sizeof(buf), "/sys/class/gpio/gpio%d/value", gpio); - ret = open(buf, O_RDWR | O_NONBLOCK | O_SYNC); - if (ret < 0) { - LOG_ERROR("Couldn't open value for gpio %d", gpio); - perror("sysfsgpio: "); - unexport_sysfs_gpio(gpio); - } - - return ret; -} - -/* gpio numbers for each gpio. Negative values are invalid */ -static int tck_gpio = -1; -static int tms_gpio = -1; -static int tdi_gpio = -1; -static int tdo_gpio = -1; -static int trst_gpio = -1; -static int srst_gpio = -1; -static int swclk_gpio = -1; -static int swdio_gpio = -1; - -/* - * file descriptors for /sys/class/gpio/gpioXX/value - * Set up during init. - */ -static int tck_fd = -1; -static int tms_fd = -1; -static int tdi_fd = -1; -static int tdo_fd = -1; -static int trst_fd = -1; -static int srst_fd = -1; -static int swclk_fd = -1; -static int swdio_fd = -1; - -static int last_swclk; -static int last_swdio; -static bool last_stored; -static bool swdio_input; - -static void sysfsgpio_swdio_drive(bool is_output) -{ - char buf[40]; - int ret; - - snprintf(buf, sizeof(buf), "/sys/class/gpio/gpio%d/direction", swdio_gpio); - ret = open_write_close(buf, is_output ? "high" : "in"); - if (ret < 0) { - LOG_ERROR("Couldn't set direction for gpio %d", swdio_gpio); - perror("sysfsgpio: "); - } - - last_stored = false; - swdio_input = !is_output; -} - -static int sysfsgpio_swdio_read(void) -{ - char buf[1]; - - /* important to seek to signal sysfs of new read */ - lseek(swdio_fd, 0, SEEK_SET); - int ret = read(swdio_fd, &buf, sizeof(buf)); - - if (ret < 0) { - LOG_WARNING("reading swdio failed"); - return 0; - } - - return buf[0] != '0'; -} - -static void sysfsgpio_swdio_write(int swclk, int swdio) -{ - const char one[] = "1"; - const char zero[] = "0"; - - size_t bytes_written; - - if (!swdio_input) { - if (!last_stored || (swdio != last_swdio)) { - bytes_written = write(swdio_fd, swdio ? &one : &zero, 1); - if (bytes_written != 1) - LOG_WARNING("writing swdio failed"); - } - } - - /* write swclk last */ - if (!last_stored || (swclk != last_swclk)) { - bytes_written = write(swclk_fd, swclk ? &one : &zero, 1); - if (bytes_written != 1) - LOG_WARNING("writing swclk failed"); - } - - last_swdio = swdio; - last_swclk = swclk; - last_stored = true; -} - -/* - * Bitbang interface read of TDO - * - * The sysfs value will read back either '0' or '1'. The trick here is to call - * lseek to bypass buffering in the sysfs kernel driver. - */ -static int sysfsgpio_read(void) -{ - char buf[1]; - - /* important to seek to signal sysfs of new read */ - lseek(tdo_fd, 0, SEEK_SET); - int ret = read(tdo_fd, &buf, sizeof(buf)); - - if (ret < 0) { - LOG_WARNING("reading tdo failed"); - return 0; - } - - return buf[0] != '0'; -} - -/* - * Bitbang interface write of TCK, TMS, TDI - * - * Seeing as this is the only function where the outputs are changed, - * we can cache the old value to avoid needlessly writing it. - */ -static void sysfsgpio_write(int tck, int tms, int tdi) -{ - if (swd_mode) { - sysfsgpio_swdio_write(tck, tdi); - return; - } - - const char one[] = "1"; - const char zero[] = "0"; - - static int last_tck; - static int last_tms; - static int last_tdi; - - static int first_time; - size_t bytes_written; - - if (!first_time) { - last_tck = !tck; - last_tms = !tms; - last_tdi = !tdi; - first_time = 1; - } - - if (tdi != last_tdi) { - bytes_written = write(tdi_fd, tdi ? &one : &zero, 1); - if (bytes_written != 1) - LOG_WARNING("writing tdi failed"); - } - - if (tms != last_tms) { - bytes_written = write(tms_fd, tms ? &one : &zero, 1); - if (bytes_written != 1) - LOG_WARNING("writing tms failed"); - } - - /* write clk last */ - if (tck != last_tck) { - bytes_written = write(tck_fd, tck ? &one : &zero, 1); - if (bytes_written != 1) - LOG_WARNING("writing tck failed"); - } - - last_tdi = tdi; - last_tms = tms; - last_tck = tck; -} - -/* - * Bitbang interface to manipulate reset lines SRST and TRST - * - * (1) assert or (0) deassert reset lines - */ -static void sysfsgpio_reset(int trst, int srst) -{ - LOG_DEBUG("sysfsgpio_reset"); - const char one[] = "1"; - const char zero[] = "0"; - size_t bytes_written; - - /* assume active low */ - if (srst_fd >= 0) { - bytes_written = write(srst_fd, srst ? &zero : &one, 1); - if (bytes_written != 1) - LOG_WARNING("writing srst failed"); - } - - /* assume active low */ - if (trst_fd >= 0) { - bytes_written = write(trst_fd, trst ? &zero : &one, 1); - if (bytes_written != 1) - LOG_WARNING("writing trst failed"); - } -} - -COMMAND_HANDLER(sysfsgpio_handle_jtag_gpionums) -{ - if (CMD_ARGC == 4) { - COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], tck_gpio); - COMMAND_PARSE_NUMBER(int, CMD_ARGV[1], tms_gpio); - COMMAND_PARSE_NUMBER(int, CMD_ARGV[2], tdi_gpio); - COMMAND_PARSE_NUMBER(int, CMD_ARGV[3], tdo_gpio); - } else if (CMD_ARGC != 0) { - return ERROR_COMMAND_SYNTAX_ERROR; - } - - command_print(CMD_CTX, - "SysfsGPIO nums: tck = %d, tms = %d, tdi = %d, tdo = %d", - tck_gpio, tms_gpio, tdi_gpio, tdo_gpio); - - return ERROR_OK; -} - -COMMAND_HANDLER(sysfsgpio_handle_jtag_gpionum_tck) -{ - if (CMD_ARGC == 1) - COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], tck_gpio); - - command_print(CMD_CTX, "SysfsGPIO num: tck = %d", tck_gpio); - return ERROR_OK; -} - -COMMAND_HANDLER(sysfsgpio_handle_jtag_gpionum_tms) -{ - if (CMD_ARGC == 1) - COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], tms_gpio); - - command_print(CMD_CTX, "SysfsGPIO num: tms = %d", tms_gpio); - return ERROR_OK; -} - -COMMAND_HANDLER(sysfsgpio_handle_jtag_gpionum_tdo) -{ - if (CMD_ARGC == 1) - COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], tdo_gpio); - - command_print(CMD_CTX, "SysfsGPIO num: tdo = %d", tdo_gpio); - return ERROR_OK; -} - -COMMAND_HANDLER(sysfsgpio_handle_jtag_gpionum_tdi) -{ - if (CMD_ARGC == 1) - COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], tdi_gpio); - - command_print(CMD_CTX, "SysfsGPIO num: tdi = %d", tdi_gpio); - return ERROR_OK; -} - -COMMAND_HANDLER(sysfsgpio_handle_jtag_gpionum_srst) -{ - if (CMD_ARGC == 1) - COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], srst_gpio); - - command_print(CMD_CTX, "SysfsGPIO num: srst = %d", srst_gpio); - return ERROR_OK; -} - -COMMAND_HANDLER(sysfsgpio_handle_jtag_gpionum_trst) -{ - if (CMD_ARGC == 1) - COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], trst_gpio); - - command_print(CMD_CTX, "SysfsGPIO num: trst = %d", trst_gpio); - return ERROR_OK; -} - -COMMAND_HANDLER(sysfsgpio_handle_swd_gpionums) -{ - if (CMD_ARGC == 2) { - COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], swclk_gpio); - COMMAND_PARSE_NUMBER(int, CMD_ARGV[1], swdio_gpio); - } else if (CMD_ARGC != 0) { - return ERROR_COMMAND_SYNTAX_ERROR; - } - - command_print(CMD_CTX, - "SysfsGPIO nums: swclk = %d, swdio = %d", - swclk_gpio, swdio_gpio); - - return ERROR_OK; -} - -COMMAND_HANDLER(sysfsgpio_handle_swd_gpionum_swclk) -{ - if (CMD_ARGC == 1) - COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], swclk_gpio); - - command_print(CMD_CTX, "SysfsGPIO num: swclk = %d", swclk_gpio); - return ERROR_OK; -} - -COMMAND_HANDLER(sysfsgpio_handle_swd_gpionum_swdio) -{ - if (CMD_ARGC == 1) - COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], swdio_gpio); - - command_print(CMD_CTX, "SysfsGPIO num: swdio = %d", swdio_gpio); - return ERROR_OK; -} - -static const struct command_registration sysfsgpio_command_handlers[] = { - { - .name = "sysfsgpio_jtag_nums", - .handler = &sysfsgpio_handle_jtag_gpionums, - .mode = COMMAND_CONFIG, - .help = "gpio numbers for tck, tms, tdi, tdo. (in that order)", - .usage = "(tck tms tdi tdo)* ", - }, - { - .name = "sysfsgpio_tck_num", - .handler = &sysfsgpio_handle_jtag_gpionum_tck, - .mode = COMMAND_CONFIG, - .help = "gpio number for tck.", - }, - { - .name = "sysfsgpio_tms_num", - .handler = &sysfsgpio_handle_jtag_gpionum_tms, - .mode = COMMAND_CONFIG, - .help = "gpio number for tms.", - }, - { - .name = "sysfsgpio_tdo_num", - .handler = &sysfsgpio_handle_jtag_gpionum_tdo, - .mode = COMMAND_CONFIG, - .help = "gpio number for tdo.", - }, - { - .name = "sysfsgpio_tdi_num", - .handler = &sysfsgpio_handle_jtag_gpionum_tdi, - .mode = COMMAND_CONFIG, - .help = "gpio number for tdi.", - }, - { - .name = "sysfsgpio_srst_num", - .handler = &sysfsgpio_handle_jtag_gpionum_srst, - .mode = COMMAND_CONFIG, - .help = "gpio number for srst.", - }, - { - .name = "sysfsgpio_trst_num", - .handler = &sysfsgpio_handle_jtag_gpionum_trst, - .mode = COMMAND_CONFIG, - .help = "gpio number for trst.", - }, - { - .name = "sysfsgpio_swd_nums", - .handler = &sysfsgpio_handle_swd_gpionums, - .mode = COMMAND_CONFIG, - .help = "gpio numbers for swclk, swdio. (in that order)", - .usage = "(swclk swdio)* ", - }, - { - .name = "sysfsgpio_swclk_num", - .handler = &sysfsgpio_handle_swd_gpionum_swclk, - .mode = COMMAND_CONFIG, - .help = "gpio number for swclk.", - }, - { - .name = "sysfsgpio_swdio_num", - .handler = &sysfsgpio_handle_swd_gpionum_swdio, - .mode = COMMAND_CONFIG, - .help = "gpio number for swdio.", - }, - COMMAND_REGISTRATION_DONE -}; - -static int sysfsgpio_init(void); -static int sysfsgpio_quit(void); - -static const char * const sysfsgpio_transports[] = { "jtag", "swd", NULL }; - -struct jtag_interface sysfsgpio_interface = { - .name = "sysfsgpio", - .supported = DEBUG_CAP_TMS_SEQ, - .execute_queue = bitbang_execute_queue, - .transports = sysfsgpio_transports, - .swd = &bitbang_swd, - .commands = sysfsgpio_command_handlers, - .init = sysfsgpio_init, - .quit = sysfsgpio_quit, -}; - -static struct bitbang_interface sysfsgpio_bitbang = { - .read = sysfsgpio_read, - .write = sysfsgpio_write, - .reset = sysfsgpio_reset, - .swdio_read = sysfsgpio_swdio_read, - .swdio_drive = sysfsgpio_swdio_drive, - .blink = 0 -}; - -/* helper func to close and cleanup files only if they were valid/ used */ -static void cleanup_fd(int fd, int gpio) -{ - if (gpio >= 0) { - if (fd >= 0) - close(fd); - - unexport_sysfs_gpio(gpio); - } -} - -static void cleanup_all_fds(void) -{ - cleanup_fd(tck_fd, tck_gpio); - cleanup_fd(tms_fd, tms_gpio); - cleanup_fd(tdi_fd, tdi_gpio); - cleanup_fd(tdo_fd, tdo_gpio); - cleanup_fd(trst_fd, trst_gpio); - cleanup_fd(srst_fd, srst_gpio); -} - -static bool sysfsgpio_jtag_mode_possible(void) -{ - if (!is_gpio_valid(tck_gpio)) - return 0; - if (!is_gpio_valid(tms_gpio)) - return 0; - if (!is_gpio_valid(tdi_gpio)) - return 0; - if (!is_gpio_valid(tdo_gpio)) - return 0; - return 1; -} - -static bool sysfsgpio_swd_mode_possible(void) -{ - if (!is_gpio_valid(swclk_gpio)) - return 0; - if (!is_gpio_valid(swdio_gpio)) - return 0; - return 1; -} - -static int sysfsgpio_init(void) -{ - bitbang_interface = &sysfsgpio_bitbang; - - LOG_INFO("SysfsGPIO JTAG/SWD bitbang driver"); - - if (sysfsgpio_jtag_mode_possible()) { - if (sysfsgpio_swd_mode_possible()) - LOG_INFO("JTAG and SWD modes enabled"); - else - LOG_INFO("JTAG only mode enabled (specify swclk and swdio gpio to add SWD mode)"); - if (!is_gpio_valid(trst_gpio) && !is_gpio_valid(srst_gpio)) { - LOG_ERROR("Require at least one of trst or srst gpios to be specified"); - return ERROR_JTAG_INIT_FAILED; - } - } else if (sysfsgpio_swd_mode_possible()) { - LOG_INFO("SWD only mode enabled (specify tck, tms, tdi and tdo gpios to add JTAG mode)"); - } else { - LOG_ERROR("Require tck, tms, tdi and tdo gpios for JTAG mode and/or swclk and swdio gpio for SWD mode"); - return ERROR_JTAG_INIT_FAILED; - } - - - /* - * Configure TDO as an input, and TDI, TCK, TMS, TRST, SRST - * as outputs. Drive TDI and TCK low, and TMS/TRST/SRST high. - * For SWD, SWCLK and SWDIO are configures as output high. - */ - if (tck_gpio >= 0) { - tck_fd = setup_sysfs_gpio(tck_gpio, 1, 0); - if (tck_fd < 0) - goto out_error; - } - - if (tms_gpio >= 0) { - tms_fd = setup_sysfs_gpio(tms_gpio, 1, 1); - if (tms_fd < 0) - goto out_error; - } - - if (tdi_gpio >= 0) { - tdi_fd = setup_sysfs_gpio(tdi_gpio, 1, 0); - if (tdi_fd < 0) - goto out_error; - } - - if (tdo_gpio >= 0) { - tdo_fd = setup_sysfs_gpio(tdo_gpio, 0, 0); - if (tdo_fd < 0) - goto out_error; - } - - /* assume active low*/ - if (trst_gpio >= 0) { - trst_fd = setup_sysfs_gpio(trst_gpio, 1, 1); - if (trst_fd < 0) - goto out_error; - } - - /* assume active low*/ - if (srst_gpio >= 0) { - srst_fd = setup_sysfs_gpio(srst_gpio, 1, 1); - if (srst_fd < 0) - goto out_error; - } - - if (swclk_gpio >= 0) { - swclk_fd = setup_sysfs_gpio(swclk_gpio, 1, 0); - if (swclk_fd < 0) - goto out_error; - } - - if (swdio_gpio >= 0) { - swdio_fd = setup_sysfs_gpio(swdio_gpio, 1, 0); - if (swdio_fd < 0) - goto out_error; - } - - if (sysfsgpio_swd_mode_possible()) { - if (swd_mode) - bitbang_swd_switch_seq(JTAG_TO_SWD); - else - bitbang_swd_switch_seq(SWD_TO_JTAG); - } - - return ERROR_OK; - -out_error: - cleanup_all_fds(); - return ERROR_JTAG_INIT_FAILED; -} - -static int sysfsgpio_quit(void) -{ - cleanup_all_fds(); - return ERROR_OK; -} - diff --git a/src/jtag/drivers/ti_icdi_usb.c b/src/jtag/drivers/ti_icdi_usb.c deleted file mode 100644 index 3db03b032..000000000 --- a/src/jtag/drivers/ti_icdi_usb.c +++ /dev/null @@ -1,782 +0,0 @@ -/*************************************************************************** - * * - * Copyright (C) 2012 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -/* project specific includes */ -#include -#include -#include -#include -#include -#include - -#include - -#include - -#define ICDI_WRITE_ENDPOINT 0x02 -#define ICDI_READ_ENDPOINT 0x83 - -#define ICDI_WRITE_TIMEOUT 1000 -#define ICDI_READ_TIMEOUT 1000 -#define ICDI_PACKET_SIZE 2048 - -#define PACKET_START "$" -#define PACKET_END "#" - -struct icdi_usb_handle_s { - libusb_context *usb_ctx; - libusb_device_handle *usb_dev; - - char *read_buffer; - char *write_buffer; - int max_packet; - int read_count; - uint32_t max_rw_packet; /* max X packet (read/write memory) transfers */ -}; - -static int icdi_usb_read_mem(void *handle, uint32_t addr, uint32_t size, - uint32_t count, uint8_t *buffer); -static int icdi_usb_write_mem(void *handle, uint32_t addr, uint32_t size, - uint32_t count, const uint8_t *buffer); - -static int remote_escape_output(const char *buffer, int len, char *out_buf, int *out_len, int out_maxlen) -{ - int input_index, output_index; - - output_index = 0; - - for (input_index = 0; input_index < len; input_index++) { - - char b = buffer[input_index]; - - if (b == '$' || b == '#' || b == '}' || b == '*') { - /* These must be escaped. */ - if (output_index + 2 > out_maxlen) - break; - out_buf[output_index++] = '}'; - out_buf[output_index++] = b ^ 0x20; - } else { - if (output_index + 1 > out_maxlen) - break; - out_buf[output_index++] = b; - } - } - - *out_len = input_index; - return output_index; -} - -static int remote_unescape_input(const char *buffer, int len, char *out_buf, int out_maxlen) -{ - int input_index, output_index; - int escaped; - - output_index = 0; - escaped = 0; - - for (input_index = 0; input_index < len; input_index++) { - - char b = buffer[input_index]; - - if (output_index + 1 > out_maxlen) - LOG_ERROR("Received too much data from the target."); - - if (escaped) { - out_buf[output_index++] = b ^ 0x20; - escaped = 0; - } else if (b == '}') - escaped = 1; - else - out_buf[output_index++] = b; - } - - if (escaped) - LOG_ERROR("Unmatched escape character in target response."); - - return output_index; -} - -static int icdi_send_packet(void *handle, int len) -{ - unsigned char cksum = 0; - struct icdi_usb_handle_s *h = handle; - int result, retry = 0; - int transferred = 0; - - assert(handle != NULL); - - /* check we have a large enough buffer for checksum "#00" */ - if (len + 3 > h->max_packet) { - LOG_ERROR("packet buffer too small"); - return ERROR_FAIL; - } - - /* calculate checksum - offset start of packet */ - for (int i = 1; i < len; i++) - cksum += h->write_buffer[i]; - - len += sprintf(&h->write_buffer[len], PACKET_END "%02x", cksum); - -#ifdef _DEBUG_USB_COMMS_ - char buffer[50]; - char ch = h->write_buffer[1]; - if (ch == 'x' || ch == 'X') - LOG_DEBUG("writing packet: "); - else { - memcpy(buffer, h->write_buffer, len >= 50 ? 50-1 : len); - buffer[len] = 0; - LOG_DEBUG("writing packet: %s", buffer); - } -#endif - - while (1) { - - result = libusb_bulk_transfer(h->usb_dev, ICDI_WRITE_ENDPOINT, (unsigned char *)h->write_buffer, len, - &transferred, ICDI_WRITE_TIMEOUT); - if (result != 0 || transferred != len) { - LOG_DEBUG("Error TX Data %d", result); - return ERROR_FAIL; - } - - /* check that the client got the message ok, or shall we resend */ - result = libusb_bulk_transfer(h->usb_dev, ICDI_READ_ENDPOINT, (unsigned char *)h->read_buffer, h->max_packet, - &transferred, ICDI_READ_TIMEOUT); - if (result != 0 || transferred < 1) { - LOG_DEBUG("Error RX Data %d", result); - return ERROR_FAIL; - } - -#ifdef _DEBUG_USB_COMMS_ - LOG_DEBUG("received reply: '%c' : count %d", h->read_buffer[0], transferred); -#endif - - if (h->read_buffer[0] == '-') { - LOG_DEBUG("Resending packet %d", ++retry); - } else { - if (h->read_buffer[0] != '+') - LOG_DEBUG("Unexpected Reply from ICDI: %c", h->read_buffer[0]); - break; - } - - if (retry == 3) { - LOG_DEBUG("maximum nack retries attempted"); - return ERROR_FAIL; - } - } - - retry = 0; - h->read_count = transferred; - - while (1) { - - /* read reply from icdi */ - result = libusb_bulk_transfer(h->usb_dev, ICDI_READ_ENDPOINT, (unsigned char *)h->read_buffer + h->read_count, - h->max_packet - h->read_count, &transferred, ICDI_READ_TIMEOUT); - -#ifdef _DEBUG_USB_COMMS_ - LOG_DEBUG("received data: count %d", transferred); -#endif - - /* check for errors but retry for timeout */ - if (result != 0) { - - if (result == LIBUSB_ERROR_TIMEOUT) { - LOG_DEBUG("Error RX timeout %d", result); - } else { - LOG_DEBUG("Error RX Data %d", result); - return ERROR_FAIL; - } - } - - h->read_count += transferred; - - /* we need to make sure we have a full packet, including checksum */ - if (h->read_count > 5) { - - /* check that we have received an packet delimiter - * we do not validate the checksum - * reply should contain $...#AA - so we check for # */ - if (h->read_buffer[h->read_count - 3] == '#') - return ERROR_OK; - } - - if (retry++ == 3) { - LOG_DEBUG("maximum data retries attempted"); - break; - } - } - - return ERROR_FAIL; -} - -static int icdi_send_cmd(void *handle, const char *cmd) -{ - struct icdi_usb_handle_s *h = handle; - - int cmd_len = snprintf(h->write_buffer, h->max_packet, PACKET_START "%s", cmd); - return icdi_send_packet(handle, cmd_len); -} - -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); - - return icdi_send_packet(handle, cmd_len); -} - -static int icdi_get_cmd_result(void *handle) -{ - struct icdi_usb_handle_s *h = handle; - int offset = 0; - char ch; - - assert(handle != NULL); - - do { - ch = h->read_buffer[offset++]; - if (offset > h->read_count) - return ERROR_FAIL; - } while (ch != '$'); - - if (memcmp("OK", h->read_buffer + offset, 2) == 0) - return ERROR_OK; - - if (h->read_buffer[offset] == 'E') { - /* get error code */ - char result; - if (unhexify(&result, h->read_buffer + offset + 1, 1) != 1) - return ERROR_FAIL; - return result; - } - - /* for now we assume everything else is ok */ - return ERROR_OK; -} - -static int icdi_usb_idcode(void *handle, uint32_t *idcode) -{ - *idcode = 0; - return ERROR_OK; -} - -static int icdi_usb_write_debug_reg(void *handle, uint32_t addr, uint32_t val) -{ - uint8_t buf[4]; - /* REVISIT: There's no target pointer here so there's no way to use target_buffer_set_u32(). - * I guess all supported chips are little-endian anyway. */ - h_u32_to_le(buf, val); - return icdi_usb_write_mem(handle, addr, 4, 1, buf); -} - -static enum target_state icdi_usb_state(void *handle) -{ - int result; - struct icdi_usb_handle_s *h = handle; - uint32_t dhcsr; - uint8_t buf[4]; - - result = icdi_usb_read_mem(h, DCB_DHCSR, 4, 1, buf); - if (result != ERROR_OK) - return TARGET_UNKNOWN; - - /* REVISIT: There's no target pointer here so there's no way to use target_buffer_get_u32(). - * I guess all supported chips are little-endian anyway. */ - dhcsr = le_to_h_u32(buf); - if (dhcsr & S_HALT) - return TARGET_HALTED; - - return TARGET_RUNNING; -} - -static int icdi_usb_version(void *handle) -{ - struct icdi_usb_handle_s *h = handle; - - char version[20]; - - /* get info about icdi */ - int result = icdi_send_remote_cmd(handle, "version"); - if (result != ERROR_OK) - return result; - - if (h->read_count < 8) { - LOG_ERROR("Invalid Reply Received"); - return ERROR_FAIL; - } - - /* convert reply */ - if (unhexify(version, h->read_buffer + 2, 4) != 4) { - LOG_WARNING("unable to get ICDI version"); - return ERROR_OK; - } - - /* null terminate and print info */ - version[4] = 0; - - LOG_INFO("ICDI Firmware version: %s", version); - - return ERROR_OK; -} - -static int icdi_usb_query(void *handle) -{ - int result; - - struct icdi_usb_handle_s *h = handle; - - result = icdi_send_cmd(handle, "qSupported"); - if (result != ERROR_OK) - return result; - - /* check result */ - result = icdi_get_cmd_result(handle); - if (result != ERROR_OK) { - LOG_ERROR("query supported failed: 0x%x", result); - return ERROR_FAIL; - } - - /* from this we can get the max packet supported */ - - /* query packet buffer size */ - char *offset = strstr(h->read_buffer, "PacketSize"); - if (offset) { - char *separator; - int max_packet; - - max_packet = strtol(offset + 11, &separator, 16); - if (!max_packet) - LOG_ERROR("invalid max packet, using defaults"); - else - h->max_packet = max_packet; - LOG_DEBUG("max packet supported : %i bytes", h->max_packet); - } - - - /* if required re allocate packet buffer */ - if (h->max_packet != ICDI_PACKET_SIZE) { - h->read_buffer = realloc(h->read_buffer, h->max_packet); - h->write_buffer = realloc(h->write_buffer, h->max_packet); - if (h->read_buffer == 0 || h->write_buffer == 0) { - LOG_ERROR("unable to reallocate memory"); - return ERROR_FAIL; - } - } - - /* set extended mode */ - result = icdi_send_cmd(handle, "!"); - if (result != ERROR_OK) - return result; - - /* check result */ - result = icdi_get_cmd_result(handle); - if (result != ERROR_OK) { - LOG_ERROR("unable to enable extended mode: 0x%x", result); - return ERROR_FAIL; - } - - return ERROR_OK; -} - -static int icdi_usb_reset(void *handle) -{ - /* we do this in hla_target.c */ - return ERROR_OK; -} - -static int icdi_usb_assert_srst(void *handle, int srst) -{ - /* TODO not supported yet */ - return ERROR_COMMAND_NOTFOUND; -} - -static int icdi_usb_run(void *handle) -{ - int result; - - /* resume target at current address */ - result = icdi_send_cmd(handle, "c"); - if (result != ERROR_OK) - return result; - - /* check result */ - result = icdi_get_cmd_result(handle); - if (result != ERROR_OK) { - LOG_ERROR("continue failed: 0x%x", result); - return ERROR_FAIL; - } - - return result; -} - -static int icdi_usb_halt(void *handle) -{ - int result; - - /* this query halts the target ?? */ - result = icdi_send_cmd(handle, "?"); - if (result != ERROR_OK) - return result; - - /* check result */ - result = icdi_get_cmd_result(handle); - if (result != ERROR_OK) { - LOG_ERROR("halt failed: 0x%x", result); - return ERROR_FAIL; - } - - return result; -} - -static int icdi_usb_step(void *handle) -{ - int result; - - /* step target at current address */ - result = icdi_send_cmd(handle, "s"); - if (result != ERROR_OK) - return result; - - /* check result */ - result = icdi_get_cmd_result(handle); - if (result != ERROR_OK) { - LOG_ERROR("step failed: 0x%x", result); - return ERROR_FAIL; - } - - return result; -} - -static int icdi_usb_read_regs(void *handle) -{ - /* currently unsupported */ - return ERROR_OK; -} - -static int icdi_usb_read_reg(void *handle, int num, uint32_t *val) -{ - int result; - struct icdi_usb_handle_s *h = handle; - char cmd[10]; - - snprintf(cmd, sizeof(cmd), "p%x", num); - result = icdi_send_cmd(handle, cmd); - if (result != ERROR_OK) - return result; - - /* check result */ - result = icdi_get_cmd_result(handle); - if (result != ERROR_OK) { - LOG_ERROR("register read failed: 0x%x", result); - return ERROR_FAIL; - } - - /* convert result */ - uint8_t buf[4]; - if (unhexify((char *)buf, h->read_buffer + 2, 4) != 4) { - LOG_ERROR("failed to convert result"); - return ERROR_FAIL; - } - *val = le_to_h_u32(buf); - - return result; -} - -static int icdi_usb_write_reg(void *handle, int num, uint32_t val) -{ - int result; - char cmd[20]; - uint8_t buf[4]; - 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)); - - result = icdi_send_cmd(handle, cmd); - if (result != ERROR_OK) - return result; - - /* check result */ - result = icdi_get_cmd_result(handle); - if (result != ERROR_OK) { - LOG_ERROR("register write failed: 0x%x", result); - return ERROR_FAIL; - } - - return result; -} - -static int icdi_usb_read_mem_int(void *handle, uint32_t addr, uint32_t len, uint8_t *buffer) -{ - int result; - struct icdi_usb_handle_s *h = handle; - char cmd[20]; - - snprintf(cmd, sizeof(cmd), "x%" PRIx32 ",%" PRIx32, addr, len); - result = icdi_send_cmd(handle, cmd); - if (result != ERROR_OK) - return result; - - /* check result */ - result = icdi_get_cmd_result(handle); - if (result != ERROR_OK) { - LOG_ERROR("memory read failed: 0x%x", result); - return ERROR_FAIL; - } - - /* unescape input */ - int read_len = remote_unescape_input(h->read_buffer + 5, h->read_count - 8, (char *)buffer, len); - if (read_len != (int)len) { - LOG_ERROR("read more bytes than expected: actual 0x%x expected 0x%" PRIx32, read_len, len); - return ERROR_FAIL; - } - - return ERROR_OK; -} - -static int icdi_usb_write_mem_int(void *handle, uint32_t addr, uint32_t len, const uint8_t *buffer) -{ - int result; - struct icdi_usb_handle_s *h = handle; - - size_t cmd_len = snprintf(h->write_buffer, h->max_packet, PACKET_START "X%" PRIx32 ",%" PRIx32 ":", addr, len); - - int out_len; - cmd_len += remote_escape_output((const char *)buffer, len, h->write_buffer + cmd_len, - &out_len, h->max_packet - cmd_len); - - if (out_len < (int)len) { - /* for now issue a error as we have no way of allocating a larger buffer */ - LOG_ERROR("memory buffer too small: requires 0x%x actual 0x%" PRIx32, out_len, len); - return ERROR_FAIL; - } - - result = icdi_send_packet(handle, cmd_len); - if (result != ERROR_OK) - return result; - - /* check result */ - result = icdi_get_cmd_result(handle); - if (result != ERROR_OK) { - LOG_ERROR("memory write failed: 0x%x", result); - return ERROR_FAIL; - } - - return ERROR_OK; -} - -static int icdi_usb_read_mem(void *handle, uint32_t addr, uint32_t size, - uint32_t count, uint8_t *buffer) -{ - int retval = ERROR_OK; - struct icdi_usb_handle_s *h = handle; - uint32_t bytes_remaining; - - /* calculate byte count */ - count *= size; - - while (count) { - - bytes_remaining = h->max_rw_packet; - if (count < bytes_remaining) - bytes_remaining = count; - - retval = icdi_usb_read_mem_int(handle, addr, bytes_remaining, buffer); - if (retval != ERROR_OK) - return retval; - - buffer += bytes_remaining; - addr += bytes_remaining; - count -= bytes_remaining; - } - - return retval; -} - -static int icdi_usb_write_mem(void *handle, uint32_t addr, uint32_t size, - uint32_t count, const uint8_t *buffer) -{ - int retval = ERROR_OK; - struct icdi_usb_handle_s *h = handle; - uint32_t bytes_remaining; - - /* calculate byte count */ - count *= size; - - while (count) { - - bytes_remaining = h->max_rw_packet; - if (count < bytes_remaining) - bytes_remaining = count; - - retval = icdi_usb_write_mem_int(handle, addr, bytes_remaining, buffer); - if (retval != ERROR_OK) - return retval; - - buffer += bytes_remaining; - addr += bytes_remaining; - count -= bytes_remaining; - } - - return retval; -} - -static int icdi_usb_override_target(const char *targetname) -{ - return !strcmp(targetname, "cortex_m"); -} - -static int icdi_usb_close(void *handle) -{ - struct icdi_usb_handle_s *h = handle; - - if (!h) - return ERROR_OK; - - if (h->usb_dev) - libusb_close(h->usb_dev); - - if (h->usb_ctx) - libusb_exit(h->usb_ctx); - - if (h->read_buffer) - free(h->read_buffer); - - if (h->write_buffer) - free(h->write_buffer); - - free(handle); - - return ERROR_OK; -} - -static int icdi_usb_open(struct hl_interface_param_s *param, void **fd) -{ - int retval; - struct icdi_usb_handle_s *h; - - LOG_DEBUG("icdi_usb_open"); - - h = calloc(1, sizeof(struct icdi_usb_handle_s)); - - if (h == 0) { - LOG_ERROR("unable to allocate memory"); - return ERROR_FAIL; - } - - LOG_DEBUG("transport: %d vid: 0x%04x pid: 0x%04x", param->transport, - param->vid, param->pid); - - if (libusb_init(&h->usb_ctx) != 0) { - LOG_ERROR("libusb init failed"); - goto error_open; - } - - h->usb_dev = libusb_open_device_with_vid_pid(h->usb_ctx, param->vid, param->pid); - if (!h->usb_dev) { - LOG_ERROR("open failed"); - goto error_open; - } - - if (libusb_claim_interface(h->usb_dev, 2)) { - LOG_DEBUG("claim interface failed"); - goto error_open; - } - - /* check if mode is supported */ - retval = ERROR_OK; - - switch (param->transport) { -#if 0 - /* TODO place holder as swd is not currently supported */ - case HL_TRANSPORT_SWD: -#endif - case HL_TRANSPORT_JTAG: - break; - default: - retval = ERROR_FAIL; - break; - } - - if (retval != ERROR_OK) { - LOG_ERROR("mode (transport) not supported by device"); - goto error_open; - } - - /* allocate buffer */ - h->read_buffer = malloc(ICDI_PACKET_SIZE); - h->write_buffer = malloc(ICDI_PACKET_SIZE); - h->max_packet = ICDI_PACKET_SIZE; - - if (h->read_buffer == 0 || h->write_buffer == 0) { - LOG_DEBUG("malloc failed"); - goto error_open; - } - - /* query icdi version etc */ - retval = icdi_usb_version(h); - if (retval != ERROR_OK) - goto error_open; - - /* query icdi support */ - retval = icdi_usb_query(h); - if (retval != ERROR_OK) - goto error_open; - - *fd = h; - - /* set the max target read/write buffer in bytes - * as we are using gdb binary packets to transfer memory we have to - * reserve half the buffer for any possible escape chars plus - * at least 64 bytes for the gdb packet header */ - h->max_rw_packet = (((h->max_packet - 64) / 4) * 4) / 2; - - return ERROR_OK; - -error_open: - icdi_usb_close(h); - - return ERROR_FAIL; -} - -struct hl_layout_api_s icdi_usb_layout_api = { - .open = icdi_usb_open, - .close = icdi_usb_close, - .idcode = icdi_usb_idcode, - .state = icdi_usb_state, - .reset = icdi_usb_reset, - .assert_srst = icdi_usb_assert_srst, - .run = icdi_usb_run, - .halt = icdi_usb_halt, - .step = icdi_usb_step, - .read_regs = icdi_usb_read_regs, - .read_reg = icdi_usb_read_reg, - .write_reg = icdi_usb_write_reg, - .read_mem = icdi_usb_read_mem, - .write_mem = icdi_usb_write_mem, - .write_debug_reg = icdi_usb_write_debug_reg, - .override_target = icdi_usb_override_target, - .custom_command = icdi_send_remote_cmd, -}; diff --git a/src/jtag/drivers/ulink.c b/src/jtag/drivers/ulink.c deleted file mode 100644 index c319a11df..000000000 --- a/src/jtag/drivers/ulink.c +++ /dev/null @@ -1,2316 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2011-2013 by Martin Schmoelzer * - * * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 -#include "config.h" -#endif - -#include -#include -#include -#include -#include -#include "OpenULINK/include/msgtypes.h" - -/** USB Vendor ID of ULINK device in unconfigured state (no firmware loaded - * yet) or with OpenULINK firmware. */ -#define ULINK_VID 0xC251 - -/** USB Product ID of ULINK device in unconfigured state (no firmware loaded - * yet) or with OpenULINK firmware. */ -#define ULINK_PID 0x2710 - -/** Address of EZ-USB CPU Control & Status register. This register can be - * written by issuing a Control EP0 vendor request. */ -#define CPUCS_REG 0x7F92 - -/** USB Control EP0 bRequest: "Firmware Load". */ -#define REQUEST_FIRMWARE_LOAD 0xA0 - -/** Value to write into CPUCS to put EZ-USB into reset. */ -#define CPU_RESET 0x01 - -/** Value to write into CPUCS to put EZ-USB out of reset. */ -#define CPU_START 0x00 - -/** Base address of firmware in EZ-USB code space. */ -#define FIRMWARE_ADDR 0x0000 - -/** USB interface number */ -#define USB_INTERFACE 0 - -/** libusb timeout in ms */ -#define USB_TIMEOUT 5000 - -/** Delay (in microseconds) to wait while EZ-USB performs ReNumeration. */ -#define ULINK_RENUMERATION_DELAY 1500000 - -/** Default location of OpenULINK firmware image. */ -#define ULINK_FIRMWARE_FILE PKGDATADIR "/OpenULINK/ulink_firmware.hex" - -/** Maximum size of a single firmware section. Entire EZ-USB code space = 8kB */ -#define SECTION_BUFFERSIZE 8192 - -/** Tuning of OpenOCD SCAN commands split into multiple OpenULINK commands. */ -#define SPLIT_SCAN_THRESHOLD 10 - -/** ULINK hardware type */ -enum ulink_type { - /** Original ULINK adapter, based on Cypress EZ-USB (AN2131): - * Full JTAG support, no SWD support. */ - ULINK_1, - - /** Newer ULINK adapter, based on NXP LPC2148. Currently unsupported. */ - ULINK_2, - - /** Newer ULINK adapter, based on EZ-USB FX2 + FPGA. Currently unsupported. */ - ULINK_PRO, - - /** Newer ULINK adapter, possibly based on ULINK 2. Currently unsupported. */ - ULINK_ME -}; - -enum ulink_payload_direction { - PAYLOAD_DIRECTION_OUT, - PAYLOAD_DIRECTION_IN -}; - -enum ulink_delay_type { - DELAY_CLOCK_TCK, - DELAY_CLOCK_TMS, - DELAY_SCAN_IN, - DELAY_SCAN_OUT, - DELAY_SCAN_IO -}; - -/** - * OpenULINK command (OpenULINK command queue element). - * - * For the OUT direction payload, things are quite easy: Payload is stored - * in a rather small array (up to 63 bytes), the payload is always allocated - * by the function generating the command and freed by ulink_clear_queue(). - * - * For the IN direction payload, things get a little bit more complicated: - * The maximum IN payload size for a single command is 64 bytes. Assume that - * a single OpenOCD command needs to scan 256 bytes. This results in the - * generation of four OpenULINK commands. The function generating these - * commands shall allocate an uint8_t[256] array. Each command's #payload_in - * pointer shall point to the corresponding offset where IN data shall be - * placed, while #payload_in_start shall point to the first element of the 256 - * byte array. - * - first command: #payload_in_start + 0 - * - second command: #payload_in_start + 64 - * - third command: #payload_in_start + 128 - * - fourth command: #payload_in_start + 192 - * - * The last command sets #needs_postprocessing to true. - */ -struct ulink_cmd { - uint8_t id; /**< ULINK command ID */ - - uint8_t *payload_out; /**< OUT direction payload data */ - uint8_t payload_out_size; /**< OUT direction payload size for this command */ - - uint8_t *payload_in_start; /**< Pointer to first element of IN payload array */ - uint8_t *payload_in; /**< Pointer where IN payload shall be stored */ - uint8_t payload_in_size; /**< IN direction payload size for this command */ - - /** Indicates if this command needs post-processing */ - bool needs_postprocessing; - - /** Indicates if ulink_clear_queue() should free payload_in_start */ - bool free_payload_in_start; - - /** Pointer to corresponding OpenOCD command for post-processing */ - struct jtag_command *cmd_origin; - - struct ulink_cmd *next; /**< Pointer to next command (linked list) */ -}; - -/** Describes one driver instance */ -struct ulink { - struct libusb_context *libusb_ctx; - struct libusb_device_handle *usb_device_handle; - enum ulink_type type; - - int delay_scan_in; /**< Delay value for SCAN_IN commands */ - int delay_scan_out; /**< Delay value for SCAN_OUT commands */ - int delay_scan_io; /**< Delay value for SCAN_IO commands */ - int delay_clock_tck; /**< Delay value for CLOCK_TMS commands */ - int delay_clock_tms; /**< Delay value for CLOCK_TCK commands */ - - int commands_in_queue; /**< Number of commands in queue */ - struct ulink_cmd *queue_start; /**< Pointer to first command in queue */ - struct ulink_cmd *queue_end; /**< Pointer to last command in queue */ -}; - -/**************************** Function Prototypes *****************************/ - -/* USB helper functions */ -int ulink_usb_open(struct ulink **device); -int ulink_usb_close(struct ulink **device); - -/* ULINK MCU (Cypress EZ-USB) specific functions */ -int ulink_cpu_reset(struct ulink *device, unsigned char reset_bit); -int ulink_load_firmware_and_renumerate(struct ulink **device, const char *filename, - uint32_t delay); -int ulink_load_firmware(struct ulink *device, const char *filename); -int ulink_write_firmware_section(struct ulink *device, - struct image *firmware_image, int section_index); - -/* Generic helper functions */ -void ulink_print_signal_states(uint8_t input_signals, uint8_t output_signals); - -/* OpenULINK command generation helper functions */ -int ulink_allocate_payload(struct ulink_cmd *ulink_cmd, int size, - enum ulink_payload_direction direction); - -/* OpenULINK command queue helper functions */ -int ulink_get_queue_size(struct ulink *device, - enum ulink_payload_direction direction); -void ulink_clear_queue(struct ulink *device); -int ulink_append_queue(struct ulink *device, struct ulink_cmd *ulink_cmd); -int ulink_execute_queued_commands(struct ulink *device, int timeout); - -#ifdef _DEBUG_JTAG_IO_ -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, - enum scan_type scan_type, - int scan_size_bits, - uint8_t *tdi, - uint8_t *tdo_start, - uint8_t *tdo, - uint8_t tms_count_start, - uint8_t tms_sequence_start, - uint8_t tms_count_end, - uint8_t tms_sequence_end, - struct jtag_command *origin, - bool postprocess); -int ulink_append_clock_tms_cmd(struct ulink *device, uint8_t count, - uint8_t sequence); -int ulink_append_clock_tck_cmd(struct ulink *device, uint16_t count); -int ulink_append_get_signals_cmd(struct ulink *device); -int ulink_append_set_signals_cmd(struct ulink *device, uint8_t low, - uint8_t high); -int ulink_append_sleep_cmd(struct ulink *device, uint32_t us); -int ulink_append_configure_tck_cmd(struct ulink *device, - int delay_scan_in, - int delay_scan_out, - int delay_scan_io, - int delay_tck, - int delay_tms); -int ulink_append_led_cmd(struct ulink *device, uint8_t led_state); -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); - -/* Interface between OpenULINK and OpenOCD */ -static void ulink_set_end_state(tap_state_t endstate); -int ulink_queue_statemove(struct ulink *device); - -int ulink_queue_scan(struct ulink *device, struct jtag_command *cmd); -int ulink_queue_tlr_reset(struct ulink *device, struct jtag_command *cmd); -int ulink_queue_runtest(struct ulink *device, struct jtag_command *cmd); -int ulink_queue_reset(struct ulink *device, struct jtag_command *cmd); -int ulink_queue_pathmove(struct ulink *device, struct jtag_command *cmd); -int ulink_queue_sleep(struct ulink *device, struct jtag_command *cmd); -int ulink_queue_stableclocks(struct ulink *device, struct jtag_command *cmd); - -int ulink_post_process_scan(struct ulink_cmd *ulink_cmd); -int ulink_post_process_queue(struct ulink *device); - -/* JTAG driver functions (registered in struct jtag_interface) */ -static int ulink_execute_queue(void); -static int ulink_khz(int khz, int *jtag_speed); -static int ulink_speed(int speed); -static int ulink_speed_div(int speed, int *khz); -static int ulink_init(void); -static int ulink_quit(void); - -/****************************** Global Variables ******************************/ - -struct ulink *ulink_handle; - -/**************************** USB helper functions ****************************/ - -/** - * Opens the ULINK device and claims its USB interface. - * - * Currently, only the original ULINK is supported - * - * @param device pointer to struct ulink identifying ULINK driver instance. - * @return on success: ERROR_OK - * @return on failure: ERROR_FAIL - */ -int ulink_usb_open(struct ulink **device) -{ - ssize_t num_devices, i; - bool found; - libusb_device **usb_devices; - struct libusb_device_descriptor usb_desc; - struct libusb_device_handle *usb_device_handle; - - num_devices = libusb_get_device_list((*device)->libusb_ctx, &usb_devices); - - if (num_devices <= 0) - return ERROR_FAIL; - - found = false; - for (i = 0; i < num_devices; i++) { - if (libusb_get_device_descriptor(usb_devices[i], &usb_desc) != 0) - continue; - else if (usb_desc.idVendor == ULINK_VID && usb_desc.idProduct == ULINK_PID) { - found = true; - break; - } - } - - if (!found) - return ERROR_FAIL; - - if (libusb_open(usb_devices[i], &usb_device_handle) != 0) - return ERROR_FAIL; - libusb_free_device_list(usb_devices, 1); - - if (libusb_claim_interface(usb_device_handle, 0) != 0) - return ERROR_FAIL; - - (*device)->usb_device_handle = usb_device_handle; - (*device)->type = ULINK_1; - - return ERROR_OK; -} - -/** - * Releases the ULINK interface and closes the USB device handle. - * - * @param device pointer to struct ulink identifying ULINK driver instance. - * @return on success: ERROR_OK - * @return on failure: ERROR_FAIL - */ -int ulink_usb_close(struct ulink **device) -{ - if (libusb_release_interface((*device)->usb_device_handle, 0) != 0) - return ERROR_FAIL; - - libusb_close((*device)->usb_device_handle); - - (*device)->usb_device_handle = NULL; - - return ERROR_OK; -} - -/******************* ULINK CPU (EZ-USB) specific functions ********************/ - -/** - * Writes '0' or '1' to the CPUCS register, putting the EZ-USB CPU into reset - * or out of reset. - * - * @param device pointer to struct ulink identifying ULINK driver instance. - * @param reset_bit 0 to put CPU into reset, 1 to put CPU out of reset. - * @return on success: ERROR_OK - * @return on failure: ERROR_FAIL - */ -int ulink_cpu_reset(struct ulink *device, unsigned char reset_bit) -{ - int ret; - - ret = libusb_control_transfer(device->usb_device_handle, - (LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE), - REQUEST_FIRMWARE_LOAD, CPUCS_REG, 0, &reset_bit, 1, USB_TIMEOUT); - - /* usb_control_msg() returns the number of bytes transferred during the - * DATA stage of the control transfer - must be exactly 1 in this case! */ - if (ret != 1) - return ERROR_FAIL; - return ERROR_OK; -} - -/** - * Puts the ULINK's EZ-USB microcontroller into reset state, downloads - * the firmware image, resumes the microcontroller and re-enumerates - * USB devices. - * - * @param device pointer to struct ulink identifying ULINK driver instance. - * The usb_handle member will be modified during re-enumeration. - * @param filename path to the Intel HEX file containing the firmware image. - * @param delay the delay to wait for the device to re-enumerate. - * @return on success: ERROR_OK - * @return on failure: ERROR_FAIL - */ -int ulink_load_firmware_and_renumerate(struct ulink **device, - const char *filename, uint32_t delay) -{ - int ret; - - /* Basic process: After downloading the firmware, the ULINK will disconnect - * itself and re-connect after a short amount of time so we have to close - * the handle and re-enumerate USB devices */ - - ret = ulink_load_firmware(*device, filename); - if (ret != ERROR_OK) - return ret; - - ret = ulink_usb_close(device); - if (ret != ERROR_OK) - return ret; - - usleep(delay); - - ret = ulink_usb_open(device); - if (ret != ERROR_OK) - return ret; - - return ERROR_OK; -} - -/** - * Downloads a firmware image to the ULINK's EZ-USB microcontroller - * over the USB bus. - * - * @param device pointer to struct ulink identifying ULINK driver instance. - * @param filename an absolute or relative path to the Intel HEX file - * containing the firmware image. - * @return on success: ERROR_OK - * @return on failure: ERROR_FAIL - */ -int ulink_load_firmware(struct ulink *device, const char *filename) -{ - struct image ulink_firmware_image; - int ret, i; - - ret = ulink_cpu_reset(device, CPU_RESET); - if (ret != ERROR_OK) { - LOG_ERROR("Could not halt ULINK CPU"); - return ret; - } - - ulink_firmware_image.base_address = 0; - ulink_firmware_image.base_address_set = 0; - - ret = image_open(&ulink_firmware_image, filename, "ihex"); - if (ret != ERROR_OK) { - LOG_ERROR("Could not load firmware image"); - return ret; - } - - /* Download all sections in the image to ULINK */ - for (i = 0; i < ulink_firmware_image.num_sections; i++) { - ret = ulink_write_firmware_section(device, &ulink_firmware_image, i); - if (ret != ERROR_OK) - return ret; - } - - image_close(&ulink_firmware_image); - - ret = ulink_cpu_reset(device, CPU_START); - if (ret != ERROR_OK) { - LOG_ERROR("Could not restart ULINK CPU"); - return ret; - } - - return ERROR_OK; -} - -/** - * Send one contiguous firmware section to the ULINK's EZ-USB microcontroller - * over the USB bus. - * - * @param device pointer to struct ulink identifying ULINK driver instance. - * @param firmware_image pointer to the firmware image that contains the section - * which should be sent to the ULINK's EZ-USB microcontroller. - * @param section_index index of the section within the firmware image. - * @return on success: ERROR_OK - * @return on failure: ERROR_FAIL - */ -int ulink_write_firmware_section(struct ulink *device, - struct image *firmware_image, int section_index) -{ - uint16_t addr, size, bytes_remaining, chunk_size; - uint8_t data[SECTION_BUFFERSIZE]; - uint8_t *data_ptr = data; - size_t size_read; - int ret; - - size = (uint16_t)firmware_image->sections[section_index].size; - addr = (uint16_t)firmware_image->sections[section_index].base_address; - - LOG_DEBUG("section %02i at addr 0x%04x (size 0x%04x)", section_index, addr, - size); - - /* Copy section contents to local buffer */ - ret = image_read_section(firmware_image, section_index, 0, size, data, - &size_read); - - if ((ret != ERROR_OK) || (size_read != size)) { - /* Propagating the return code would return '0' (misleadingly indicating - * successful execution of the function) if only the size check fails. */ - return ERROR_FAIL; - } - - bytes_remaining = size; - - /* Send section data in chunks of up to 64 bytes to ULINK */ - while (bytes_remaining > 0) { - if (bytes_remaining > 64) - chunk_size = 64; - else - chunk_size = bytes_remaining; - - ret = libusb_control_transfer(device->usb_device_handle, - (LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE), - REQUEST_FIRMWARE_LOAD, addr, FIRMWARE_ADDR, (unsigned char *)data_ptr, - chunk_size, USB_TIMEOUT); - - if (ret != (int)chunk_size) { - /* Abort if libusb sent less data than requested */ - return ERROR_FAIL; - } - - bytes_remaining -= chunk_size; - addr += chunk_size; - data_ptr += chunk_size; - } - - return ERROR_OK; -} - -/************************** Generic helper functions **************************/ - -/** - * Print state of interesting signals via LOG_INFO(). - * - * @param input_signals input signal states as returned by CMD_GET_SIGNALS - * @param output_signals output signal states as returned by CMD_GET_SIGNALS - */ -void ulink_print_signal_states(uint8_t input_signals, uint8_t output_signals) -{ - LOG_INFO("ULINK signal states: TDI: %i, TDO: %i, TMS: %i, TCK: %i, TRST: %i," - " SRST: %i", - (output_signals & SIGNAL_TDI ? 1 : 0), - (input_signals & SIGNAL_TDO ? 1 : 0), - (output_signals & SIGNAL_TMS ? 1 : 0), - (output_signals & SIGNAL_TCK ? 1 : 0), - (output_signals & SIGNAL_TRST ? 0 : 1), /* Inverted by hardware */ - (output_signals & SIGNAL_RESET ? 0 : 1)); /* Inverted by hardware */ -} - -/**************** OpenULINK command generation helper functions ***************/ - -/** - * Allocate and initialize space in memory for OpenULINK command payload. - * - * @param ulink_cmd pointer to command whose payload should be allocated. - * @param size the amount of memory to allocate (bytes). - * @param direction which payload to allocate. - * @return on success: ERROR_OK - * @return on failure: ERROR_FAIL - */ -int ulink_allocate_payload(struct ulink_cmd *ulink_cmd, int size, - enum ulink_payload_direction direction) -{ - uint8_t *payload; - - payload = calloc(size, sizeof(uint8_t)); - - if (payload == NULL) { - LOG_ERROR("Could not allocate OpenULINK command payload: out of memory"); - return ERROR_FAIL; - } - - switch (direction) { - case PAYLOAD_DIRECTION_OUT: - if (ulink_cmd->payload_out != NULL) { - LOG_ERROR("BUG: Duplicate payload allocation for OpenULINK command"); - free(payload); - return ERROR_FAIL; - } else { - ulink_cmd->payload_out = payload; - ulink_cmd->payload_out_size = size; - } - break; - case PAYLOAD_DIRECTION_IN: - if (ulink_cmd->payload_in_start != NULL) { - LOG_ERROR("BUG: Duplicate payload allocation for OpenULINK command"); - free(payload); - return ERROR_FAIL; - } else { - ulink_cmd->payload_in_start = payload; - ulink_cmd->payload_in = payload; - ulink_cmd->payload_in_size = size; - - /* By default, free payload_in_start in ulink_clear_queue(). Commands - * that do not want this behavior (e. g. split scans) must turn it off - * separately! */ - ulink_cmd->free_payload_in_start = true; - } - break; - } - - return ERROR_OK; -} - -/****************** OpenULINK command queue helper functions ******************/ - -/** - * Get the current number of bytes in the queue, including command IDs. - * - * @param device pointer to struct ulink identifying ULINK driver instance. - * @param direction the transfer direction for which to get byte count. - * @return the number of bytes currently stored in the queue for the specified - * direction. - */ -int ulink_get_queue_size(struct ulink *device, - enum ulink_payload_direction direction) -{ - struct ulink_cmd *current = device->queue_start; - int sum = 0; - - while (current != NULL) { - switch (direction) { - case PAYLOAD_DIRECTION_OUT: - sum += current->payload_out_size + 1; /* + 1 byte for Command ID */ - break; - case PAYLOAD_DIRECTION_IN: - sum += current->payload_in_size; - break; - } - - current = current->next; - } - - return sum; -} - -/** - * Clear the OpenULINK command queue. - * - * @param device pointer to struct ulink identifying ULINK driver instance. - * @return on success: ERROR_OK - * @return on failure: ERROR_FAIL - */ -void ulink_clear_queue(struct ulink *device) -{ - struct ulink_cmd *current = device->queue_start; - struct ulink_cmd *next = NULL; - - while (current != NULL) { - /* Save pointer to next element */ - next = current->next; - - /* Free payloads: OUT payload can be freed immediately */ - free(current->payload_out); - current->payload_out = NULL; - - /* IN payload MUST be freed ONLY if no other commands use the - * payload_in_start buffer */ - if (current->free_payload_in_start == true) { - free(current->payload_in_start); - current->payload_in_start = NULL; - current->payload_in = NULL; - } - - /* Free queue element */ - free(current); - - /* Proceed with next element */ - current = next; - } - - device->commands_in_queue = 0; - device->queue_start = NULL; - device->queue_end = NULL; -} - -/** - * Add a command to the OpenULINK command queue. - * - * @param device pointer to struct ulink identifying ULINK driver instance. - * @param ulink_cmd pointer to command that shall be appended to the OpenULINK - * command queue. - * @return on success: ERROR_OK - * @return on failure: ERROR_FAIL - */ -int ulink_append_queue(struct ulink *device, struct ulink_cmd *ulink_cmd) -{ - int newsize_out, newsize_in; - int ret; - - newsize_out = ulink_get_queue_size(device, PAYLOAD_DIRECTION_OUT) + 1 - + ulink_cmd->payload_out_size; - - newsize_in = ulink_get_queue_size(device, PAYLOAD_DIRECTION_IN) - + ulink_cmd->payload_in_size; - - /* Check if the current command can be appended to the queue */ - if ((newsize_out > 64) || (newsize_in > 64)) { - /* New command does not fit. Execute all commands in queue before starting - * new queue with the current command as first entry. */ - ret = ulink_execute_queued_commands(device, USB_TIMEOUT); - if (ret != ERROR_OK) - return ret; - - ret = ulink_post_process_queue(device); - if (ret != ERROR_OK) - return ret; - - ulink_clear_queue(device); - } - - if (device->queue_start == NULL) { - /* Queue was empty */ - device->commands_in_queue = 1; - - device->queue_start = ulink_cmd; - device->queue_end = ulink_cmd; - } else { - /* There are already commands in the queue */ - device->commands_in_queue++; - - device->queue_end->next = ulink_cmd; - device->queue_end = ulink_cmd; - } - - return ERROR_OK; -} - -/** - * Sends all queued OpenULINK commands to the ULINK for execution. - * - * @param device pointer to struct ulink identifying ULINK driver instance. - * @return on success: ERROR_OK - * @return on failure: ERROR_FAIL - */ -int ulink_execute_queued_commands(struct ulink *device, int timeout) -{ - struct ulink_cmd *current; - int ret, i, index_out, index_in, count_out, count_in, transferred; - uint8_t buffer[64]; - -#ifdef _DEBUG_JTAG_IO_ - ulink_print_queue(device); -#endif - - index_out = 0; - count_out = 0; - count_in = 0; - - for (current = device->queue_start; current; current = current->next) { - /* Add command to packet */ - buffer[index_out] = current->id; - index_out++; - count_out++; - - for (i = 0; i < current->payload_out_size; i++) - buffer[index_out + i] = current->payload_out[i]; - index_out += current->payload_out_size; - count_in += current->payload_in_size; - count_out += current->payload_out_size; - } - - /* Send packet to ULINK */ - ret = libusb_bulk_transfer(device->usb_device_handle, (2 | LIBUSB_ENDPOINT_OUT), - (unsigned char *)buffer, count_out, &transferred, timeout); - if (ret != 0) - return ERROR_FAIL; - if (transferred != count_out) - return ERROR_FAIL; - - /* Wait for response if commands contain IN payload data */ - if (count_in > 0) { - ret = libusb_bulk_transfer(device->usb_device_handle, (2 | LIBUSB_ENDPOINT_IN), - (unsigned char *)buffer, 64, &transferred, timeout); - if (ret != 0) - return ERROR_FAIL; - if (transferred != count_in) - return ERROR_FAIL; - - /* Write back IN payload data */ - index_in = 0; - for (current = device->queue_start; current; current = current->next) { - for (i = 0; i < current->payload_in_size; i++) { - current->payload_in[i] = buffer[index_in]; - index_in++; - } - } - } - - return ERROR_OK; -} - -#ifdef _DEBUG_JTAG_IO_ - -/** - * Convert an OpenULINK command ID (\a id) to a human-readable string. - * - * @param id the OpenULINK command ID. - * @return the corresponding human-readable string. - */ -const char *ulink_cmd_id_string(uint8_t id) -{ - switch (id) { - case CMD_SCAN_IN: - return "CMD_SCAN_IN"; - break; - case CMD_SLOW_SCAN_IN: - return "CMD_SLOW_SCAN_IN"; - break; - case CMD_SCAN_OUT: - return "CMD_SCAN_OUT"; - break; - case CMD_SLOW_SCAN_OUT: - return "CMD_SLOW_SCAN_OUT"; - break; - case CMD_SCAN_IO: - return "CMD_SCAN_IO"; - break; - case CMD_SLOW_SCAN_IO: - return "CMD_SLOW_SCAN_IO"; - break; - case CMD_CLOCK_TMS: - return "CMD_CLOCK_TMS"; - break; - case CMD_SLOW_CLOCK_TMS: - return "CMD_SLOW_CLOCK_TMS"; - break; - case CMD_CLOCK_TCK: - return "CMD_CLOCK_TCK"; - break; - case CMD_SLOW_CLOCK_TCK: - return "CMD_SLOW_CLOCK_TCK"; - break; - case CMD_SLEEP_US: - return "CMD_SLEEP_US"; - break; - case CMD_SLEEP_MS: - return "CMD_SLEEP_MS"; - break; - case CMD_GET_SIGNALS: - return "CMD_GET_SIGNALS"; - break; - case CMD_SET_SIGNALS: - return "CMD_SET_SIGNALS"; - break; - case CMD_CONFIGURE_TCK_FREQ: - return "CMD_CONFIGURE_TCK_FREQ"; - break; - case CMD_SET_LEDS: - return "CMD_SET_LEDS"; - break; - case CMD_TEST: - return "CMD_TEST"; - break; - default: - return "CMD_UNKNOWN"; - break; - } -} - -/** - * Print one OpenULINK command to stdout. - * - * @param ulink_cmd pointer to OpenULINK command. - */ -void ulink_print_command(struct ulink_cmd *ulink_cmd) -{ - int i; - - printf(" %-22s | OUT size = %i, bytes = 0x", - ulink_cmd_id_string(ulink_cmd->id), ulink_cmd->payload_out_size); - - for (i = 0; i < ulink_cmd->payload_out_size; i++) - printf("%02X ", ulink_cmd->payload_out[i]); - printf("\n | IN size = %i\n", - ulink_cmd->payload_in_size); -} - -/** - * Print the OpenULINK command queue to stdout. - * - * @param device pointer to struct ulink identifying ULINK driver instance. - */ -void ulink_print_queue(struct ulink *device) -{ - struct ulink_cmd *current; - - printf("OpenULINK command queue:\n"); - - for (current = device->queue_start; current; current = current->next) - ulink_print_command(current); -} - -#endif /* _DEBUG_JTAG_IO_ */ - -/** - * Perform JTAG scan - * - * Creates and appends a JTAG scan command to the OpenULINK command queue. - * A JTAG scan consists of three steps: - * - Move to the desired SHIFT state, depending on scan type (IR/DR scan). - * - Shift TDI data into the JTAG chain, optionally reading the TDO pin. - * - Move to the desired end state. - * - * @param device pointer to struct ulink identifying ULINK driver instance. - * @param scan_type the type of the scan (IN, OUT, IO (bidirectional)). - * @param scan_size_bits number of bits to shift into the JTAG chain. - * @param tdi pointer to array containing TDI data. - * @param tdo_start pointer to first element of array where TDO data shall be - * stored. See #ulink_cmd for details. - * @param tdo pointer to array where TDO data shall be stored - * @param tms_count_start number of TMS state transitions to perform BEFORE - * shifting data into the JTAG chain. - * @param tms_sequence_start sequence of TMS state transitions that will be - * performed BEFORE shifting data into the JTAG chain. - * @param tms_count_end number of TMS state transitions to perform AFTER - * shifting data into the JTAG chain. - * @param tms_sequence_end sequence of TMS state transitions that will be - * performed AFTER shifting data into the JTAG chain. - * @param origin pointer to OpenOCD command that generated this scan command. - * @param postprocess whether this command needs to be post-processed after - * execution. - * @return on success: ERROR_OK - * @return on failure: ERROR_FAIL - */ -int ulink_append_scan_cmd(struct ulink *device, enum scan_type scan_type, - int scan_size_bits, uint8_t *tdi, uint8_t *tdo_start, uint8_t *tdo, - uint8_t tms_count_start, uint8_t tms_sequence_start, uint8_t tms_count_end, - uint8_t tms_sequence_end, struct jtag_command *origin, bool postprocess) -{ - struct ulink_cmd *cmd = calloc(1, sizeof(struct ulink_cmd)); - int ret, i, scan_size_bytes; - uint8_t bits_last_byte; - - if (cmd == NULL) - return ERROR_FAIL; - - /* Check size of command. USB buffer can hold 64 bytes, 1 byte is command ID, - * 5 bytes are setup data -> 58 remaining payload bytes for TDI data */ - if (scan_size_bits > (58 * 8)) { - LOG_ERROR("BUG: Tried to create CMD_SCAN_IO OpenULINK command with too" - " large payload"); - free(cmd); - return ERROR_FAIL; - } - - scan_size_bytes = DIV_ROUND_UP(scan_size_bits, 8); - - bits_last_byte = scan_size_bits % 8; - if (bits_last_byte == 0) - bits_last_byte = 8; - - /* Allocate out_payload depending on scan type */ - switch (scan_type) { - case SCAN_IN: - if (device->delay_scan_in < 0) - cmd->id = CMD_SCAN_IN; - else - cmd->id = CMD_SLOW_SCAN_IN; - ret = ulink_allocate_payload(cmd, 5, PAYLOAD_DIRECTION_OUT); - break; - case SCAN_OUT: - if (device->delay_scan_out < 0) - cmd->id = CMD_SCAN_OUT; - else - cmd->id = CMD_SLOW_SCAN_OUT; - ret = ulink_allocate_payload(cmd, scan_size_bytes + 5, PAYLOAD_DIRECTION_OUT); - break; - case SCAN_IO: - if (device->delay_scan_io < 0) - cmd->id = CMD_SCAN_IO; - else - cmd->id = CMD_SLOW_SCAN_IO; - ret = ulink_allocate_payload(cmd, scan_size_bytes + 5, PAYLOAD_DIRECTION_OUT); - break; - default: - LOG_ERROR("BUG: ulink_append_scan_cmd() encountered an unknown scan type"); - ret = ERROR_FAIL; - break; - } - - if (ret != ERROR_OK) { - free(cmd); - return ret; - } - - /* Build payload_out that is common to all scan types */ - cmd->payload_out[0] = scan_size_bytes & 0xFF; - cmd->payload_out[1] = bits_last_byte & 0xFF; - cmd->payload_out[2] = ((tms_count_start & 0x0F) << 4) | (tms_count_end & 0x0F); - cmd->payload_out[3] = tms_sequence_start; - cmd->payload_out[4] = tms_sequence_end; - - /* Setup payload_out for types with OUT transfer */ - if ((scan_type == SCAN_OUT) || (scan_type == SCAN_IO)) { - for (i = 0; i < scan_size_bytes; i++) - cmd->payload_out[i + 5] = tdi[i]; - } - - /* Setup payload_in pointers for types with IN transfer */ - if ((scan_type == SCAN_IN) || (scan_type == SCAN_IO)) { - cmd->payload_in_start = tdo_start; - cmd->payload_in = tdo; - cmd->payload_in_size = scan_size_bytes; - } - - cmd->needs_postprocessing = postprocess; - cmd->cmd_origin = origin; - - /* For scan commands, we free payload_in_start only when the command is - * the last in a series of split commands or a stand-alone command */ - cmd->free_payload_in_start = postprocess; - - return ulink_append_queue(device, cmd); -} - -/** - * Perform TAP state transitions - * - * @param device pointer to struct ulink identifying ULINK driver instance. - * @param count defines the number of TCK clock cycles generated (up to 8). - * @param sequence defines the TMS pin levels for each state transition. The - * Least-Significant Bit is read first. - * @return on success: ERROR_OK - * @return on failure: ERROR_FAIL - */ -int ulink_append_clock_tms_cmd(struct ulink *device, uint8_t count, - uint8_t sequence) -{ - struct ulink_cmd *cmd = calloc(1, sizeof(struct ulink_cmd)); - int ret; - - if (cmd == NULL) - return ERROR_FAIL; - - if (device->delay_clock_tms < 0) - cmd->id = CMD_CLOCK_TMS; - else - cmd->id = CMD_SLOW_CLOCK_TMS; - - /* CMD_CLOCK_TMS has two OUT payload bytes and zero IN payload bytes */ - ret = ulink_allocate_payload(cmd, 2, PAYLOAD_DIRECTION_OUT); - if (ret != ERROR_OK) { - free(cmd); - return ret; - } - - cmd->payload_out[0] = count; - cmd->payload_out[1] = sequence; - - return ulink_append_queue(device, cmd); -} - -/** - * Generate a defined amount of TCK clock cycles - * - * All other JTAG signals are left unchanged. - * - * @param device pointer to struct ulink identifying ULINK driver instance. - * @param count the number of TCK clock cycles to generate. - * @return on success: ERROR_OK - * @return on failure: ERROR_FAIL - */ -int ulink_append_clock_tck_cmd(struct ulink *device, uint16_t count) -{ - struct ulink_cmd *cmd = calloc(1, sizeof(struct ulink_cmd)); - int ret; - - if (cmd == NULL) - return ERROR_FAIL; - - if (device->delay_clock_tck < 0) - cmd->id = CMD_CLOCK_TCK; - else - cmd->id = CMD_SLOW_CLOCK_TCK; - - /* CMD_CLOCK_TCK has two OUT payload bytes and zero IN payload bytes */ - ret = ulink_allocate_payload(cmd, 2, PAYLOAD_DIRECTION_OUT); - if (ret != ERROR_OK) { - free(cmd); - return ret; - } - - cmd->payload_out[0] = count & 0xff; - cmd->payload_out[1] = (count >> 8) & 0xff; - - return ulink_append_queue(device, cmd); -} - -/** - * Read JTAG signals. - * - * @param device pointer to struct ulink identifying ULINK driver instance. - * @return on success: ERROR_OK - * @return on failure: ERROR_FAIL - */ -int ulink_append_get_signals_cmd(struct ulink *device) -{ - struct ulink_cmd *cmd = calloc(1, sizeof(struct ulink_cmd)); - int ret; - - if (cmd == NULL) - return ERROR_FAIL; - - cmd->id = CMD_GET_SIGNALS; - cmd->needs_postprocessing = true; - - /* CMD_GET_SIGNALS has two IN payload bytes */ - ret = ulink_allocate_payload(cmd, 2, PAYLOAD_DIRECTION_IN); - - if (ret != ERROR_OK) { - free(cmd); - return ret; - } - - return ulink_append_queue(device, cmd); -} - -/** - * Arbitrarily set JTAG output signals. - * - * @param device pointer to struct ulink identifying ULINK driver instance. - * @param low defines which signals will be de-asserted. Each bit corresponds - * to a JTAG signal: - * - SIGNAL_TDI - * - SIGNAL_TMS - * - SIGNAL_TCK - * - SIGNAL_TRST - * - SIGNAL_BRKIN - * - SIGNAL_RESET - * - SIGNAL_OCDSE - * @param high defines which signals will be asserted. - * @return on success: ERROR_OK - * @return on failure: ERROR_FAIL - */ -int ulink_append_set_signals_cmd(struct ulink *device, uint8_t low, - uint8_t high) -{ - struct ulink_cmd *cmd = calloc(1, sizeof(struct ulink_cmd)); - int ret; - - if (cmd == NULL) - return ERROR_FAIL; - - cmd->id = CMD_SET_SIGNALS; - - /* CMD_SET_SIGNALS has two OUT payload bytes and zero IN payload bytes */ - ret = ulink_allocate_payload(cmd, 2, PAYLOAD_DIRECTION_OUT); - - if (ret != ERROR_OK) { - free(cmd); - return ret; - } - - cmd->payload_out[0] = low; - cmd->payload_out[1] = high; - - return ulink_append_queue(device, cmd); -} - -/** - * Sleep for a pre-defined number of microseconds - * - * @param device pointer to struct ulink identifying ULINK driver instance. - * @param us the number microseconds to sleep. - * @return on success: ERROR_OK - * @return on failure: ERROR_FAIL - */ -int ulink_append_sleep_cmd(struct ulink *device, uint32_t us) -{ - struct ulink_cmd *cmd = calloc(1, sizeof(struct ulink_cmd)); - int ret; - - if (cmd == NULL) - return ERROR_FAIL; - - cmd->id = CMD_SLEEP_US; - - /* CMD_SLEEP_US has two OUT payload bytes and zero IN payload bytes */ - ret = ulink_allocate_payload(cmd, 2, PAYLOAD_DIRECTION_OUT); - - if (ret != ERROR_OK) { - free(cmd); - return ret; - } - - cmd->payload_out[0] = us & 0x00ff; - cmd->payload_out[1] = (us >> 8) & 0x00ff; - - return ulink_append_queue(device, cmd); -} - -/** - * Set TCK delay counters - * - * @param device pointer to struct ulink identifying ULINK driver instance. - * @param delay_scan_in delay count top value in jtag_slow_scan_in() function. - * @param delay_scan_out delay count top value in jtag_slow_scan_out() function. - * @param delay_scan_io delay count top value in jtag_slow_scan_io() function. - * @param delay_tck delay count top value in jtag_clock_tck() function. - * @param delay_tms delay count top value in jtag_slow_clock_tms() function. - * @return on success: ERROR_OK - * @return on failure: ERROR_FAIL - */ -int ulink_append_configure_tck_cmd(struct ulink *device, int delay_scan_in, - int delay_scan_out, int delay_scan_io, int delay_tck, int delay_tms) -{ - struct ulink_cmd *cmd = calloc(1, sizeof(struct ulink_cmd)); - int ret; - - if (cmd == NULL) - return ERROR_FAIL; - - cmd->id = CMD_CONFIGURE_TCK_FREQ; - - /* CMD_CONFIGURE_TCK_FREQ has five OUT payload bytes and zero - * IN payload bytes */ - ret = ulink_allocate_payload(cmd, 5, PAYLOAD_DIRECTION_OUT); - if (ret != ERROR_OK) { - free(cmd); - return ret; - } - - if (delay_scan_in < 0) - cmd->payload_out[0] = 0; - else - cmd->payload_out[0] = (uint8_t)delay_scan_in; - - if (delay_scan_out < 0) - cmd->payload_out[1] = 0; - else - cmd->payload_out[1] = (uint8_t)delay_scan_out; - - if (delay_scan_io < 0) - cmd->payload_out[2] = 0; - else - cmd->payload_out[2] = (uint8_t)delay_scan_io; - - if (delay_tck < 0) - cmd->payload_out[3] = 0; - else - cmd->payload_out[3] = (uint8_t)delay_tck; - - if (delay_tms < 0) - cmd->payload_out[4] = 0; - else - cmd->payload_out[4] = (uint8_t)delay_tms; - - return ulink_append_queue(device, cmd); -} - -/** - * Turn on/off ULINK LEDs. - * - * @param device pointer to struct ulink identifying ULINK driver instance. - * @param led_state which LED(s) to turn on or off. The following bits - * influence the LEDS: - * - Bit 0: Turn COM LED on - * - Bit 1: Turn RUN LED on - * - Bit 2: Turn COM LED off - * - Bit 3: Turn RUN LED off - * If both the on-bit and the off-bit for the same LED is set, the LED is - * turned off. - * @return on success: ERROR_OK - * @return on failure: ERROR_FAIL - */ -int ulink_append_led_cmd(struct ulink *device, uint8_t led_state) -{ - struct ulink_cmd *cmd = calloc(1, sizeof(struct ulink_cmd)); - int ret; - - if (cmd == NULL) - return ERROR_FAIL; - - cmd->id = CMD_SET_LEDS; - - /* CMD_SET_LEDS has one OUT payload byte and zero IN payload bytes */ - ret = ulink_allocate_payload(cmd, 1, PAYLOAD_DIRECTION_OUT); - if (ret != ERROR_OK) { - free(cmd); - return ret; - } - - cmd->payload_out[0] = led_state; - - return ulink_append_queue(device, cmd); -} - -/** - * Test command. Used to check if the ULINK device is ready to accept new - * commands. - * - * @param device pointer to struct ulink identifying ULINK driver instance. - * @return on success: ERROR_OK - * @return on failure: ERROR_FAIL - */ -int ulink_append_test_cmd(struct ulink *device) -{ - struct ulink_cmd *cmd = calloc(1, sizeof(struct ulink_cmd)); - int ret; - - if (cmd == NULL) - return ERROR_FAIL; - - cmd->id = CMD_TEST; - - /* CMD_TEST has one OUT payload byte and zero IN payload bytes */ - ret = ulink_allocate_payload(cmd, 1, PAYLOAD_DIRECTION_OUT); - if (ret != ERROR_OK) { - free(cmd); - return ret; - } - - cmd->payload_out[0] = 0xAA; - - return ulink_append_queue(device, cmd); -} - -/****************** OpenULINK TCK frequency helper functions ******************/ - -/** - * Calculate delay values for a given TCK frequency. - * - * The OpenULINK firmware uses five different speed values for different - * commands. These speed values are calculated in these functions. - * - * The five different commands which support variable TCK frequency are - * implemented twice in the firmware: - * 1. Maximum possible frequency without any artificial delay - * 2. Variable frequency with artificial linear delay loop - * - * To set the ULINK to maximum frequency, it is only neccessary to use the - * corresponding command IDs. To set the ULINK to a lower frequency, the - * delay loop top values have to be calculated first. Then, a - * CMD_CONFIGURE_TCK_FREQ command needs to be sent to the ULINK device. - * - * The delay values are described by linear equations: - * t = k * x + d - * (t = period, k = constant, x = delay value, d = constant) - * - * Thus, the delay can be calculated as in the following equation: - * x = (t - d) / k - * - * The constants in these equations have been determined and validated by - * measuring the frequency resulting from different delay values. - * - * @param type for which command to calculate the delay value. - * @param f TCK frequency for which to calculate the delay value in Hz. - * @param delay where to store resulting delay value. - * @return on success: ERROR_OK - * @return on failure: ERROR_FAIL - */ -int ulink_calculate_delay(enum ulink_delay_type type, long f, int *delay) -{ - float t, x, x_ceil; - - /* Calculate period of requested TCK frequency */ - t = 1.0 / (float)(f); - - switch (type) { - case DELAY_CLOCK_TCK: - x = (t - (float)(6E-6)) / (float)(4E-6); - break; - case DELAY_CLOCK_TMS: - x = (t - (float)(8.5E-6)) / (float)(4E-6); - break; - case DELAY_SCAN_IN: - x = (t - (float)(8.8308E-6)) / (float)(4E-6); - break; - case DELAY_SCAN_OUT: - x = (t - (float)(1.0527E-5)) / (float)(4E-6); - break; - case DELAY_SCAN_IO: - x = (t - (float)(1.3132E-5)) / (float)(4E-6); - break; - default: - return ERROR_FAIL; - break; - } - - /* Check if the delay value is negative. This happens when a frequency is - * requested that is too high for the delay loop implementation. In this - * case, set delay value to zero. */ - if (x < 0) - x = 0; - - /* We need to convert the exact delay value to an integer. Therefore, we - * round the exact value UP to ensure that the resulting frequency is NOT - * higher than the requested frequency. */ - x_ceil = ceilf(x); - - /* Check if the value is within limits */ - if (x_ceil > 255) - return ERROR_FAIL; - - *delay = (int)x_ceil; - - return ERROR_OK; -} - -#ifdef _DEBUG_JTAG_IO_ -/** - * Calculate frequency for a given delay value. - * - * Similar to the #ulink_calculate_delay function, this function calculates the - * TCK frequency for a given delay value by using linear equations of the form: - * t = k * x + d - * (t = period, k = constant, x = delay value, d = constant) - * - * @param type for which command to calculate the delay value. - * @param delay delay value for which to calculate the resulting TCK frequency. - * @param f where to store the resulting TCK frequency. - * @return on success: ERROR_OK - * @return on failure: ERROR_FAIL - */ -static int ulink_calculate_frequency(enum ulink_delay_type type, int delay, long *f) -{ - float t, f_float, f_rounded; - - if (delay > 255) - return ERROR_FAIL; - - switch (type) { - case DELAY_CLOCK_TCK: - if (delay < 0) - t = (float)(2.666E-6); - else - t = (float)(4E-6) * (float)(delay) + (float)(6E-6); - break; - case DELAY_CLOCK_TMS: - if (delay < 0) - t = (float)(5.666E-6); - else - t = (float)(4E-6) * (float)(delay) + (float)(8.5E-6); - break; - case DELAY_SCAN_IN: - if (delay < 0) - t = (float)(5.5E-6); - else - t = (float)(4E-6) * (float)(delay) + (float)(8.8308E-6); - break; - case DELAY_SCAN_OUT: - if (delay < 0) - t = (float)(7.0E-6); - else - t = (float)(4E-6) * (float)(delay) + (float)(1.0527E-5); - break; - case DELAY_SCAN_IO: - if (delay < 0) - t = (float)(9.926E-6); - else - t = (float)(4E-6) * (float)(delay) + (float)(1.3132E-5); - break; - default: - return ERROR_FAIL; - break; - } - - f_float = 1.0 / t; - f_rounded = roundf(f_float); - *f = (long)f_rounded; - - return ERROR_OK; -} -#endif - -/******************* Interface between OpenULINK and OpenOCD ******************/ - -/** - * Sets the end state follower (see interface.h) if \a endstate is a stable - * state. - * - * @param endstate the state the end state follower should be set to. - */ -static void ulink_set_end_state(tap_state_t endstate) -{ - if (tap_is_state_stable(endstate)) - tap_set_end_state(endstate); - else { - LOG_ERROR("BUG: %s is not a valid end state", tap_state_name(endstate)); - exit(EXIT_FAILURE); - } -} - -/** - * Move from the current TAP state to the current TAP end state. - * - * @param device pointer to struct ulink identifying ULINK driver instance. - * @return on success: ERROR_OK - * @return on failure: ERROR_FAIL - */ -int ulink_queue_statemove(struct ulink *device) -{ - uint8_t tms_sequence, tms_count; - int ret; - - if (tap_get_state() == tap_get_end_state()) { - /* Do nothing if we are already there */ - return ERROR_OK; - } - - tms_sequence = tap_get_tms_path(tap_get_state(), tap_get_end_state()); - tms_count = tap_get_tms_path_len(tap_get_state(), tap_get_end_state()); - - ret = ulink_append_clock_tms_cmd(device, tms_count, tms_sequence); - - if (ret == ERROR_OK) - tap_set_state(tap_get_end_state()); - - return ret; -} - -/** - * Perform a scan operation on a JTAG register. - * - * @param device pointer to struct ulink identifying ULINK driver instance. - * @param cmd pointer to the command that shall be executed. - * @return on success: ERROR_OK - * @return on failure: ERROR_FAIL - */ -int ulink_queue_scan(struct ulink *device, struct jtag_command *cmd) -{ - uint32_t scan_size_bits, scan_size_bytes, bits_last_scan; - uint32_t scans_max_payload, bytecount; - uint8_t *tdi_buffer_start = NULL, *tdi_buffer = NULL; - uint8_t *tdo_buffer_start = NULL, *tdo_buffer = NULL; - - uint8_t first_tms_count, first_tms_sequence; - uint8_t last_tms_count, last_tms_sequence; - - uint8_t tms_count_pause, tms_sequence_pause; - uint8_t tms_count_resume, tms_sequence_resume; - - uint8_t tms_count_start, tms_sequence_start; - uint8_t tms_count_end, tms_sequence_end; - - enum scan_type type; - int ret; - - /* Determine scan size */ - scan_size_bits = jtag_scan_size(cmd->cmd.scan); - scan_size_bytes = DIV_ROUND_UP(scan_size_bits, 8); - - /* Determine scan type (IN/OUT/IO) */ - type = jtag_scan_type(cmd->cmd.scan); - - /* Determine number of scan commands with maximum payload */ - scans_max_payload = scan_size_bytes / 58; - - /* Determine size of last shift command */ - bits_last_scan = scan_size_bits - (scans_max_payload * 58 * 8); - - /* Allocate TDO buffer if required */ - if ((type == SCAN_IN) || (type == SCAN_IO)) { - tdo_buffer_start = calloc(sizeof(uint8_t), scan_size_bytes); - - if (tdo_buffer_start == NULL) - return ERROR_FAIL; - - tdo_buffer = tdo_buffer_start; - } - - /* Fill TDI buffer if required */ - if ((type == SCAN_OUT) || (type == SCAN_IO)) { - jtag_build_buffer(cmd->cmd.scan, &tdi_buffer_start); - tdi_buffer = tdi_buffer_start; - } - - /* Get TAP state transitions */ - if (cmd->cmd.scan->ir_scan) { - ulink_set_end_state(TAP_IRSHIFT); - first_tms_count = tap_get_tms_path_len(tap_get_state(), tap_get_end_state()); - first_tms_sequence = tap_get_tms_path(tap_get_state(), tap_get_end_state()); - - tap_set_state(TAP_IRSHIFT); - tap_set_end_state(cmd->cmd.scan->end_state); - last_tms_count = tap_get_tms_path_len(tap_get_state(), tap_get_end_state()); - last_tms_sequence = tap_get_tms_path(tap_get_state(), tap_get_end_state()); - - /* TAP state transitions for split scans */ - tms_count_pause = tap_get_tms_path_len(TAP_IRSHIFT, TAP_IRPAUSE); - tms_sequence_pause = tap_get_tms_path(TAP_IRSHIFT, TAP_IRPAUSE); - tms_count_resume = tap_get_tms_path_len(TAP_IRPAUSE, TAP_IRSHIFT); - tms_sequence_resume = tap_get_tms_path(TAP_IRPAUSE, TAP_IRSHIFT); - } else { - ulink_set_end_state(TAP_DRSHIFT); - first_tms_count = tap_get_tms_path_len(tap_get_state(), tap_get_end_state()); - first_tms_sequence = tap_get_tms_path(tap_get_state(), tap_get_end_state()); - - tap_set_state(TAP_DRSHIFT); - tap_set_end_state(cmd->cmd.scan->end_state); - last_tms_count = tap_get_tms_path_len(tap_get_state(), tap_get_end_state()); - last_tms_sequence = tap_get_tms_path(tap_get_state(), tap_get_end_state()); - - /* TAP state transitions for split scans */ - tms_count_pause = tap_get_tms_path_len(TAP_DRSHIFT, TAP_DRPAUSE); - tms_sequence_pause = tap_get_tms_path(TAP_DRSHIFT, TAP_DRPAUSE); - tms_count_resume = tap_get_tms_path_len(TAP_DRPAUSE, TAP_DRSHIFT); - tms_sequence_resume = tap_get_tms_path(TAP_DRPAUSE, TAP_DRSHIFT); - } - - /* Generate scan commands */ - bytecount = scan_size_bytes; - while (bytecount > 0) { - if (bytecount == scan_size_bytes) { - /* This is the first scan */ - tms_count_start = first_tms_count; - tms_sequence_start = first_tms_sequence; - } else { - /* Resume from previous scan */ - tms_count_start = tms_count_resume; - tms_sequence_start = tms_sequence_resume; - } - - if (bytecount > 58) { /* Full scan, at least one scan will follow */ - tms_count_end = tms_count_pause; - tms_sequence_end = tms_sequence_pause; - - ret = ulink_append_scan_cmd(device, - type, - 58 * 8, - tdi_buffer, - tdo_buffer_start, - tdo_buffer, - tms_count_start, - tms_sequence_start, - tms_count_end, - tms_sequence_end, - cmd, - false); - - bytecount -= 58; - - /* Update TDI and TDO buffer pointers */ - if (tdi_buffer_start != NULL) - tdi_buffer += 58; - if (tdo_buffer_start != NULL) - tdo_buffer += 58; - } else if (bytecount == 58) { /* Full scan, no further scans */ - tms_count_end = last_tms_count; - tms_sequence_end = last_tms_sequence; - - ret = ulink_append_scan_cmd(device, - type, - 58 * 8, - tdi_buffer, - tdo_buffer_start, - tdo_buffer, - tms_count_start, - tms_sequence_start, - tms_count_end, - tms_sequence_end, - cmd, - true); - - bytecount = 0; - } else {/* Scan with less than maximum payload, no further scans */ - tms_count_end = last_tms_count; - tms_sequence_end = last_tms_sequence; - - ret = ulink_append_scan_cmd(device, - type, - bits_last_scan, - tdi_buffer, - tdo_buffer_start, - tdo_buffer, - tms_count_start, - tms_sequence_start, - tms_count_end, - tms_sequence_end, - cmd, - true); - - bytecount = 0; - } - - if (ret != ERROR_OK) { - free(tdi_buffer_start); - return ret; - } - } - - free(tdi_buffer_start); - - /* Set current state to the end state requested by the command */ - tap_set_state(cmd->cmd.scan->end_state); - - return ERROR_OK; -} - -/** - * Move the TAP into the Test Logic Reset state. - * - * @param device pointer to struct ulink identifying ULINK driver instance. - * @param cmd pointer to the command that shall be executed. - * @return on success: ERROR_OK - * @return on failure: ERROR_FAIL - */ -int ulink_queue_tlr_reset(struct ulink *device, struct jtag_command *cmd) -{ - int ret; - - ret = ulink_append_clock_tms_cmd(device, 5, 0xff); - - if (ret == ERROR_OK) - tap_set_state(TAP_RESET); - - return ret; -} - -/** - * Run Test. - * - * Generate TCK clock cycles while remaining - * in the Run-Test/Idle state. - * - * @param device pointer to struct ulink identifying ULINK driver instance. - * @param cmd pointer to the command that shall be executed. - * @return on success: ERROR_OK - * @return on failure: ERROR_FAIL - */ -int ulink_queue_runtest(struct ulink *device, struct jtag_command *cmd) -{ - int ret; - - /* Only perform statemove if the TAP currently isn't in the TAP_IDLE state */ - if (tap_get_state() != TAP_IDLE) { - ulink_set_end_state(TAP_IDLE); - ulink_queue_statemove(device); - } - - /* Generate the clock cycles */ - ret = ulink_append_clock_tck_cmd(device, cmd->cmd.runtest->num_cycles); - if (ret != ERROR_OK) - return ret; - - /* Move to end state specified in command */ - if (cmd->cmd.runtest->end_state != tap_get_state()) { - tap_set_end_state(cmd->cmd.runtest->end_state); - ulink_queue_statemove(device); - } - - return ERROR_OK; -} - -/** - * Execute a JTAG_RESET command - * - * @param cmd pointer to the command that shall be executed. - * @return on success: ERROR_OK - * @return on failure: ERROR_FAIL - */ -int ulink_queue_reset(struct ulink *device, struct jtag_command *cmd) -{ - uint8_t low = 0, high = 0; - - if (cmd->cmd.reset->trst) { - tap_set_state(TAP_RESET); - high |= SIGNAL_TRST; - } else - low |= SIGNAL_TRST; - - if (cmd->cmd.reset->srst) - high |= SIGNAL_RESET; - else - low |= SIGNAL_RESET; - - return ulink_append_set_signals_cmd(device, low, high); -} - -/** - * Move to one TAP state or several states in succession. - * - * @param device pointer to struct ulink identifying ULINK driver instance. - * @param cmd pointer to the command that shall be executed. - * @return on success: ERROR_OK - * @return on failure: ERROR_FAIL - */ -int ulink_queue_pathmove(struct ulink *device, struct jtag_command *cmd) -{ - int ret, i, num_states, batch_size, state_count; - tap_state_t *path; - uint8_t tms_sequence; - - num_states = cmd->cmd.pathmove->num_states; - path = cmd->cmd.pathmove->path; - state_count = 0; - - while (num_states > 0) { - tms_sequence = 0; - - /* Determine batch size */ - if (num_states >= 8) - batch_size = 8; - else - batch_size = num_states; - - for (i = 0; i < batch_size; i++) { - if (tap_state_transition(tap_get_state(), false) == path[state_count]) { - /* Append '0' transition: clear bit 'i' in tms_sequence */ - buf_set_u32(&tms_sequence, i, 1, 0x0); - } else if (tap_state_transition(tap_get_state(), true) - == path[state_count]) { - /* Append '1' transition: set bit 'i' in tms_sequence */ - buf_set_u32(&tms_sequence, i, 1, 0x1); - } else { - /* Invalid state transition */ - LOG_ERROR("BUG: %s -> %s isn't a valid TAP state transition", - tap_state_name(tap_get_state()), - tap_state_name(path[state_count])); - return ERROR_FAIL; - } - - tap_set_state(path[state_count]); - state_count++; - num_states--; - } - - /* Append CLOCK_TMS command to OpenULINK command queue */ - LOG_INFO( - "pathmove batch: count = %i, sequence = 0x%x", batch_size, tms_sequence); - ret = ulink_append_clock_tms_cmd(ulink_handle, batch_size, tms_sequence); - if (ret != ERROR_OK) - return ret; - } - - return ERROR_OK; -} - -/** - * Sleep for a specific amount of time. - * - * @param device pointer to struct ulink identifying ULINK driver instance. - * @param cmd pointer to the command that shall be executed. - * @return on success: ERROR_OK - * @return on failure: ERROR_FAIL - */ -int ulink_queue_sleep(struct ulink *device, struct jtag_command *cmd) -{ - /* IMPORTANT! Due to the time offset in command execution introduced by - * command queueing, this needs to be implemented in the ULINK device */ - return ulink_append_sleep_cmd(device, cmd->cmd.sleep->us); -} - -/** - * Generate TCK cycles while remaining in a stable state. - * - * @param device pointer to struct ulink identifying ULINK driver instance. - * @param cmd pointer to the command that shall be executed. - */ -int ulink_queue_stableclocks(struct ulink *device, struct jtag_command *cmd) -{ - int ret; - unsigned num_cycles; - - if (!tap_is_state_stable(tap_get_state())) { - LOG_ERROR("JTAG_STABLECLOCKS: state not stable"); - return ERROR_FAIL; - } - - num_cycles = cmd->cmd.stableclocks->num_cycles; - - /* TMS stays either high (Test Logic Reset state) or low (all other states) */ - if (tap_get_state() == TAP_RESET) - ret = ulink_append_set_signals_cmd(device, 0, SIGNAL_TMS); - else - ret = ulink_append_set_signals_cmd(device, SIGNAL_TMS, 0); - - if (ret != ERROR_OK) - return ret; - - while (num_cycles > 0) { - if (num_cycles > 0xFFFF) { - /* OpenULINK CMD_CLOCK_TCK can generate up to 0xFFFF (uint16_t) cycles */ - ret = ulink_append_clock_tck_cmd(device, 0xFFFF); - num_cycles -= 0xFFFF; - } else { - ret = ulink_append_clock_tck_cmd(device, num_cycles); - num_cycles = 0; - } - - if (ret != ERROR_OK) - return ret; - } - - return ERROR_OK; -} - -/** - * Post-process JTAG_SCAN command - * - * @param ulink_cmd pointer to OpenULINK command that shall be processed. - * @return on success: ERROR_OK - * @return on failure: ERROR_FAIL - */ -int ulink_post_process_scan(struct ulink_cmd *ulink_cmd) -{ - struct jtag_command *cmd = ulink_cmd->cmd_origin; - int ret; - - switch (jtag_scan_type(cmd->cmd.scan)) { - case SCAN_IN: - case SCAN_IO: - ret = jtag_read_buffer(ulink_cmd->payload_in_start, cmd->cmd.scan); - break; - case SCAN_OUT: - /* Nothing to do for OUT scans */ - ret = ERROR_OK; - break; - default: - LOG_ERROR("BUG: ulink_post_process_scan() encountered an unknown" - " JTAG scan type"); - ret = ERROR_FAIL; - break; - } - - return ret; -} - -/** - * Perform post-processing of commands after OpenULINK queue has been executed. - * - * @param device pointer to struct ulink identifying ULINK driver instance. - * @return on success: ERROR_OK - * @return on failure: ERROR_FAIL - */ -int ulink_post_process_queue(struct ulink *device) -{ - struct ulink_cmd *current; - struct jtag_command *openocd_cmd; - int ret; - - current = device->queue_start; - - while (current != NULL) { - openocd_cmd = current->cmd_origin; - - /* Check if a corresponding OpenOCD command is stored for this - * OpenULINK command */ - if ((current->needs_postprocessing == true) && (openocd_cmd != NULL)) { - switch (openocd_cmd->type) { - case JTAG_SCAN: - ret = ulink_post_process_scan(current); - break; - case JTAG_TLR_RESET: - case JTAG_RUNTEST: - case JTAG_RESET: - case JTAG_PATHMOVE: - case JTAG_SLEEP: - case JTAG_STABLECLOCKS: - /* Nothing to do for these commands */ - ret = ERROR_OK; - break; - default: - ret = ERROR_FAIL; - LOG_ERROR("BUG: ulink_post_process_queue() encountered unknown JTAG " - "command type"); - break; - } - - if (ret != ERROR_OK) - return ret; - } - - current = current->next; - } - - return ERROR_OK; -} - -/**************************** JTAG driver functions ***************************/ - -/** - * Executes the JTAG Command Queue. - * - * This is done in three stages: First, all OpenOCD commands are processed into - * queued OpenULINK commands. Next, the OpenULINK command queue is sent to the - * ULINK device and data received from the ULINK device is cached. Finally, - * the post-processing function writes back data to the corresponding OpenOCD - * commands. - * - * @return on success: ERROR_OK - * @return on failure: ERROR_FAIL - */ -static int ulink_execute_queue(void) -{ - struct jtag_command *cmd = jtag_command_queue; - int ret; - - while (cmd) { - switch (cmd->type) { - case JTAG_SCAN: - ret = ulink_queue_scan(ulink_handle, cmd); - break; - case JTAG_TLR_RESET: - ret = ulink_queue_tlr_reset(ulink_handle, cmd); - break; - case JTAG_RUNTEST: - ret = ulink_queue_runtest(ulink_handle, cmd); - break; - case JTAG_RESET: - ret = ulink_queue_reset(ulink_handle, cmd); - break; - case JTAG_PATHMOVE: - ret = ulink_queue_pathmove(ulink_handle, cmd); - break; - case JTAG_SLEEP: - ret = ulink_queue_sleep(ulink_handle, cmd); - break; - case JTAG_STABLECLOCKS: - ret = ulink_queue_stableclocks(ulink_handle, cmd); - break; - default: - ret = ERROR_FAIL; - LOG_ERROR("BUG: encountered unknown JTAG command type"); - break; - } - - if (ret != ERROR_OK) - return ret; - - cmd = cmd->next; - } - - if (ulink_handle->commands_in_queue > 0) { - ret = ulink_execute_queued_commands(ulink_handle, USB_TIMEOUT); - if (ret != ERROR_OK) - return ret; - - ret = ulink_post_process_queue(ulink_handle); - if (ret != ERROR_OK) - return ret; - - ulink_clear_queue(ulink_handle); - } - - return ERROR_OK; -} - -/** - * Set the TCK frequency of the ULINK adapter. - * - * @param khz desired JTAG TCK frequency. - * @param jtag_speed where to store corresponding adapter-specific speed value. - * @return on success: ERROR_OK - * @return on failure: ERROR_FAIL - */ -static int ulink_khz(int khz, int *jtag_speed) -{ - int ret; - - if (khz == 0) { - LOG_ERROR("RCLK not supported"); - return ERROR_FAIL; - } - - /* CLOCK_TCK commands are decoupled from others. Therefore, the frequency - * setting can be done independently from all other commands. */ - if (khz >= 375) - ulink_handle->delay_clock_tck = -1; - else { - ret = ulink_calculate_delay(DELAY_CLOCK_TCK, khz * 1000, - &ulink_handle->delay_clock_tck); - if (ret != ERROR_OK) - return ret; - } - - /* SCAN_{IN,OUT,IO} commands invoke CLOCK_TMS commands. Therefore, if the - * requested frequency goes below the maximum frequency for SLOW_CLOCK_TMS - * commands, all SCAN commands MUST also use the variable frequency - * implementation! */ - if (khz >= 176) { - ulink_handle->delay_clock_tms = -1; - ulink_handle->delay_scan_in = -1; - ulink_handle->delay_scan_out = -1; - ulink_handle->delay_scan_io = -1; - } else { - ret = ulink_calculate_delay(DELAY_CLOCK_TMS, khz * 1000, - &ulink_handle->delay_clock_tms); - if (ret != ERROR_OK) - return ret; - - ret = ulink_calculate_delay(DELAY_SCAN_IN, khz * 1000, - &ulink_handle->delay_scan_in); - if (ret != ERROR_OK) - return ret; - - ret = ulink_calculate_delay(DELAY_SCAN_OUT, khz * 1000, - &ulink_handle->delay_scan_out); - if (ret != ERROR_OK) - return ret; - - ret = ulink_calculate_delay(DELAY_SCAN_IO, khz * 1000, - &ulink_handle->delay_scan_io); - if (ret != ERROR_OK) - return ret; - } - -#ifdef _DEBUG_JTAG_IO_ - long f_tck, f_tms, f_scan_in, f_scan_out, f_scan_io; - - ulink_calculate_frequency(DELAY_CLOCK_TCK, ulink_handle->delay_clock_tck, - &f_tck); - ulink_calculate_frequency(DELAY_CLOCK_TMS, ulink_handle->delay_clock_tms, - &f_tms); - ulink_calculate_frequency(DELAY_SCAN_IN, ulink_handle->delay_scan_in, - &f_scan_in); - ulink_calculate_frequency(DELAY_SCAN_OUT, ulink_handle->delay_scan_out, - &f_scan_out); - ulink_calculate_frequency(DELAY_SCAN_IO, ulink_handle->delay_scan_io, - &f_scan_io); - - DEBUG_JTAG_IO("ULINK TCK setup: delay_tck = %i (%li Hz),", - ulink_handle->delay_clock_tck, f_tck); - DEBUG_JTAG_IO(" delay_tms = %i (%li Hz),", - ulink_handle->delay_clock_tms, f_tms); - DEBUG_JTAG_IO(" delay_scan_in = %i (%li Hz),", - ulink_handle->delay_scan_in, f_scan_in); - DEBUG_JTAG_IO(" delay_scan_out = %i (%li Hz),", - ulink_handle->delay_scan_out, f_scan_out); - DEBUG_JTAG_IO(" delay_scan_io = %i (%li Hz),", - ulink_handle->delay_scan_io, f_scan_io); -#endif - - /* Configure the ULINK device with the new delay values */ - ret = ulink_append_configure_tck_cmd(ulink_handle, - ulink_handle->delay_scan_in, - ulink_handle->delay_scan_out, - ulink_handle->delay_scan_io, - ulink_handle->delay_clock_tck, - ulink_handle->delay_clock_tms); - - if (ret != ERROR_OK) - return ret; - - *jtag_speed = khz; - - return ERROR_OK; -} - -/** - * Set the TCK frequency of the ULINK adapter. - * - * Because of the way the TCK frequency is set up in the OpenULINK firmware, - * there are five different speed settings. To simplify things, the - * adapter-specific speed setting value is identical to the TCK frequency in - * khz. - * - * @param speed desired adapter-specific speed value. - * @return on success: ERROR_OK - * @return on failure: ERROR_FAIL - */ -static int ulink_speed(int speed) -{ - int dummy; - - return ulink_khz(speed, &dummy); -} - -/** - * Convert adapter-specific speed value to corresponding TCK frequency in kHz. - * - * Because of the way the TCK frequency is set up in the OpenULINK firmware, - * there are five different speed settings. To simplify things, the - * adapter-specific speed setting value is identical to the TCK frequency in - * khz. - * - * @param speed adapter-specific speed value. - * @param khz where to store corresponding TCK frequency in kHz. - * @return on success: ERROR_OK - * @return on failure: ERROR_FAIL - */ -static int ulink_speed_div(int speed, int *khz) -{ - *khz = speed; - - return ERROR_OK; -} - -/** - * Initiates the firmware download to the ULINK adapter and prepares - * the USB handle. - * - * @return on success: ERROR_OK - * @return on failure: ERROR_FAIL - */ -static int ulink_init(void) -{ - int ret, transferred; - char str_manufacturer[20]; - bool download_firmware = false; - unsigned char *dummy; - uint8_t input_signals, output_signals; - - ulink_handle = calloc(1, sizeof(struct ulink)); - if (ulink_handle == NULL) - return ERROR_FAIL; - - libusb_init(&ulink_handle->libusb_ctx); - - ret = ulink_usb_open(&ulink_handle); - if (ret != ERROR_OK) { - LOG_ERROR("Could not open ULINK device"); - free(ulink_handle); - ulink_handle = NULL; - return ret; - } - - /* Get String Descriptor to determine if firmware needs to be loaded */ - ret = libusb_get_string_descriptor_ascii(ulink_handle->usb_device_handle, 1, (unsigned char *)str_manufacturer, 20); - if (ret < 0) { - /* Could not get descriptor -> Unconfigured or original Keil firmware */ - download_firmware = true; - } else { - /* We got a String Descriptor, check if it is the correct one */ - if (strncmp(str_manufacturer, "OpenULINK", 9) != 0) - download_firmware = true; - } - - if (download_firmware == true) { - LOG_INFO("Loading OpenULINK firmware. This is reversible by power-cycling" - " ULINK device."); - ret = ulink_load_firmware_and_renumerate(&ulink_handle, - ULINK_FIRMWARE_FILE, ULINK_RENUMERATION_DELAY); - if (ret != ERROR_OK) { - LOG_ERROR("Could not download firmware and re-numerate ULINK"); - free(ulink_handle); - ulink_handle = NULL; - return ret; - } - } else - LOG_INFO("ULINK device is already running OpenULINK firmware"); - - /* Initialize OpenULINK command queue */ - ulink_clear_queue(ulink_handle); - - /* Issue one test command with short timeout */ - ret = ulink_append_test_cmd(ulink_handle); - if (ret != ERROR_OK) - return ret; - - ret = ulink_execute_queued_commands(ulink_handle, 200); - if (ret != ERROR_OK) { - /* Sending test command failed. The ULINK device may be forever waiting for - * the host to fetch an USB Bulk IN packet (e. g. OpenOCD crashed or was - * shut down by the user via Ctrl-C. Try to retrieve this Bulk IN packet. */ - dummy = calloc(64, sizeof(uint8_t)); - - ret = libusb_bulk_transfer(ulink_handle->usb_device_handle, (2 | LIBUSB_ENDPOINT_IN), - dummy, 64, &transferred, 200); - - free(dummy); - - if (ret != 0 || transferred == 0) { - /* Bulk IN transfer failed -> unrecoverable error condition */ - LOG_ERROR("Cannot communicate with ULINK device. Disconnect ULINK from " - "the USB port and re-connect, then re-run OpenOCD"); - free(ulink_handle); - ulink_handle = NULL; - return ERROR_FAIL; - } -#ifdef _DEBUG_USB_COMMS_ - else { - /* Successfully received Bulk IN packet -> continue */ - LOG_INFO("Recovered from lost Bulk IN packet"); - } -#endif - } - ulink_clear_queue(ulink_handle); - - ulink_append_get_signals_cmd(ulink_handle); - ulink_execute_queued_commands(ulink_handle, 200); - - /* Post-process the single CMD_GET_SIGNALS command */ - input_signals = ulink_handle->queue_start->payload_in[0]; - output_signals = ulink_handle->queue_start->payload_in[1]; - - ulink_print_signal_states(input_signals, output_signals); - - ulink_clear_queue(ulink_handle); - - return ERROR_OK; -} - -/** - * Closes the USB handle for the ULINK device. - * - * @return on success: ERROR_OK - * @return on failure: ERROR_FAIL - */ -static int ulink_quit(void) -{ - int ret; - - ret = ulink_usb_close(&ulink_handle); - free(ulink_handle); - - return ret; -} - -/** - * Set a custom path to ULINK firmware image and force downloading to ULINK. - */ -COMMAND_HANDLER(ulink_download_firmware_handler) -{ - int ret; - - if (CMD_ARGC != 1) - return ERROR_COMMAND_SYNTAX_ERROR; - - - LOG_INFO("Downloading ULINK firmware image %s", CMD_ARGV[0]); - - /* Download firmware image in CMD_ARGV[0] */ - ret = ulink_load_firmware_and_renumerate(&ulink_handle, CMD_ARGV[0], - ULINK_RENUMERATION_DELAY); - - return ret; -} - -/*************************** Command Registration **************************/ - -static const struct command_registration ulink_command_handlers[] = { - { - .name = "ulink_download_firmware", - .handler = &ulink_download_firmware_handler, - .mode = COMMAND_EXEC, - .help = "download firmware image to ULINK device", - .usage = "path/to/ulink_firmware.hex", - }, - COMMAND_REGISTRATION_DONE, -}; - -struct jtag_interface ulink_interface = { - .name = "ulink", - - .commands = ulink_command_handlers, - .transports = jtag_only, - - .execute_queue = ulink_execute_queue, - .khz = ulink_khz, - .speed = ulink_speed, - .speed_div = ulink_speed_div, - - .init = ulink_init, - .quit = ulink_quit -}; diff --git a/src/jtag/drivers/usb_blaster/Makefile.am b/src/jtag/drivers/usb_blaster/Makefile.am deleted file mode 100644 index 0fb470051..000000000 --- a/src/jtag/drivers/usb_blaster/Makefile.am +++ /dev/null @@ -1,24 +0,0 @@ -include $(top_srcdir)/common.mk - -AM_CPPFLAGS += -I$(top_srcdir)/src/jtag/drivers $(LIBUSB1_CFLAGS) $(LIBFTDI_CFLAGS) - -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 -endif - -if USB_BLASTER_2 -USB_BLASTER_SRC += ublast2_access_libusb.c -endif - -noinst_HEADERS = ublast_access.h - -MAINTAINERCLEANFILES = $(srcdir)/Makefile.in diff --git a/src/jtag/drivers/usb_blaster/README.CheapClone b/src/jtag/drivers/usb_blaster/README.CheapClone deleted file mode 100644 index 983a441a1..000000000 --- a/src/jtag/drivers/usb_blaster/README.CheapClone +++ /dev/null @@ -1,71 +0,0 @@ -USB Blaster Cheap Clone -======================= - -The Altera USB Blaster has a cheap clone, based on : - - a Cypress CY7C68013A-56PVXC as the main chip - - a 74HC244D as the output latch - - a 24 MHz quartz - - a EEPROM 24C64BN - -The schematics (cut down to essential) is : - - /-----------------+----------------------\ - +--------------+ | | | -USB--| CY7C68013A | | +----------+ | | - | | | | 74HC244D | | | - . . | | | | | - . . \--o 1 20 o | 10 pins header | - | 47 o-- TCK --o 2 19 o---/ +-------+ | - | 46 o-- TDO --o 3 18 o-- TCK -----o 1 2 o | - | 45 o-- TMS --o 4 17 o-- TDO -----o 3 4 o | - | 44 o o 5 16 o-- TMS -----o 5 6 o | - | 43 o-- o 6 15 o o 7 8 o | - | 42 o-- o 7 14 o +--o 9 10 o | - | 41 o-- TDI --o 8 13 o-- ? | +-------+ | - . 40 o-- nOE \ o 9 12 o-- TDI --+ | - . . | o 10 11 o | - o 28 29 o | | | | - | | | +----------+ | - +--------------+ \ | - ---------------------------------------/ - -From this one can deduce that : - - the cypress emulates the Altera chip - - as the cypress pins used are 41-47, all output/input are controlled by 8051 - PortA. - - as the 8051 is clocked at 24Mhz, and because each USB byte is handled by the - 8051, assuming a 40 instruction cycles per USB packet, the maximum throughput - would be around 500 kHz. - -Pinout -====== - Port A.0: nOE (output enable of 74HC244D) - Port A.1: TDI - Port A.5: TMS - Port A.6: TDO - Port A.7: TCK - -Throughput considerations -========================= -Mesurements on a scope reveal that : - - for bitbang mode, the throughtput is 56.5 kbits/s - (as each clock transition is mesured at 17.7us) - - for byteshift mode, the throughput is 107.7 kbits/s - (as 63 bits TDI transmission is mesured in 585 us) - -Let's suppose that to upload a 32 bits value, it is necessary to : - - move from IDLE to DR-SHIFT : 3 bitbang (3 TMS transitions) - - input the 32 bits of data : 1 byteshift (24 bits) + 8 bitbang (8 bits) - - move from DR-SHIFT to IDLE : 5 bitbang (5 TMS transitions) -So for this 32 bits of data, the time would be : - 3 * 17.7us + 1 * 585us/63*24 + 5 * 17.7us - = 53.1us + 222us + 88.5us - = 363us - -Throughtput in bit/s: 32 * (1 / 363E-6) = 88000 bits/s -Throughtput in bytes/s: 11kBytes/s - -Conclusion -========== -Contrary to the original USB Blaster, the cheap clone will never reach high -transfer speeds over JTAG. diff --git a/src/jtag/drivers/usb_blaster/ublast2_access_libusb.c b/src/jtag/drivers/usb_blaster/ublast2_access_libusb.c deleted file mode 100644 index d99173369..000000000 --- a/src/jtag/drivers/usb_blaster/ublast2_access_libusb.c +++ /dev/null @@ -1,253 +0,0 @@ -/* - * Driver for USB-JTAG, Altera USB-Blaster II and compatibles - * - * Copyright (C) 2013 Franck Jullien franck.jullien@gmail.com - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#ifdef HAVE_CONFIG_H -#include -#endif -#include -#include -#include -#include - -#include "ublast_access.h" - -#define USBBLASTER_CTRL_READ_REV 0x94 -#define USBBLASTER_CTRL_LOAD_FIRM 0xA0 -#define USBBLASTER_EPOUT 4 -#define USBBLASTER_EPIN 8 - -#define EZUSB_CPUCS 0xe600 -#define CPU_RESET 1 - -/** Maximum size of a single firmware section. Entire EZ-USB code space = 16kB */ -#define SECTION_BUFFERSIZE 16384 - -static int ublast2_libusb_read(struct ublast_lowlevel *low, uint8_t *buf, - unsigned size, uint32_t *bytes_read) -{ - *bytes_read = jtag_libusb_bulk_read(low->libusb_dev, - USBBLASTER_EPIN | \ - LIBUSB_ENDPOINT_IN, - (char *)buf, - size, - 100); - return ERROR_OK; -} - -static int ublast2_libusb_write(struct ublast_lowlevel *low, uint8_t *buf, - int size, uint32_t *bytes_written) -{ - *bytes_written = jtag_libusb_bulk_write(low->libusb_dev, - USBBLASTER_EPOUT | \ - LIBUSB_ENDPOINT_OUT, - (char *)buf, - size, - 100); - return ERROR_OK; -} - -static int ublast2_write_firmware_section(struct jtag_libusb_device_handle *libusb_dev, - struct image *firmware_image, int section_index) -{ - uint16_t chunk_size; - uint8_t data[SECTION_BUFFERSIZE]; - uint8_t *data_ptr = data; - size_t size_read; - - uint16_t size = (uint16_t)firmware_image->sections[section_index].size; - uint16_t addr = (uint16_t)firmware_image->sections[section_index].base_address; - - LOG_DEBUG("section %02i at addr 0x%04x (size 0x%04x)", section_index, addr, - size); - - /* Copy section contents to local buffer */ - int ret = image_read_section(firmware_image, section_index, 0, size, data, - &size_read); - - if ((ret != ERROR_OK) || (size_read != size)) { - /* Propagating the return code would return '0' (misleadingly indicating - * successful execution of the function) if only the size check fails. */ - return ERROR_FAIL; - } - - uint16_t bytes_remaining = size; - - /* Send section data in chunks of up to 64 bytes to ULINK */ - while (bytes_remaining > 0) { - if (bytes_remaining > 64) - chunk_size = 64; - else - chunk_size = bytes_remaining; - - jtag_libusb_control_transfer(libusb_dev, - LIBUSB_REQUEST_TYPE_VENDOR | \ - LIBUSB_ENDPOINT_OUT, - USBBLASTER_CTRL_LOAD_FIRM, - addr, - 0, - (char *)data_ptr, - chunk_size, - 100); - - bytes_remaining -= chunk_size; - addr += chunk_size; - data_ptr += chunk_size; - } - - return ERROR_OK; -} - -static int load_usb_blaster_firmware(struct jtag_libusb_device_handle *libusb_dev, - struct ublast_lowlevel *low) -{ - struct image ublast2_firmware_image; - - if (!low->firmware_path) { - LOG_ERROR("No firmware path specified"); - return ERROR_FAIL; - } - - ublast2_firmware_image.base_address = 0; - ublast2_firmware_image.base_address_set = 0; - - int ret = image_open(&ublast2_firmware_image, low->firmware_path, "ihex"); - if (ret != ERROR_OK) { - LOG_ERROR("Could not load firmware image"); - return ret; - } - - /** A host loader program must write 0x01 to the CPUCS register - * to put the CPU into RESET, load all or part of the EZUSB - * RAM with firmware, then reload the CPUCS register - * with ‘0’ to take the CPU out of RESET. The CPUCS register - * (at 0xE600) is the only EZ-USB register that can be written - * using the Firmware Download command. - */ - - char value = CPU_RESET; - jtag_libusb_control_transfer(libusb_dev, - LIBUSB_REQUEST_TYPE_VENDOR | \ - LIBUSB_ENDPOINT_OUT, - USBBLASTER_CTRL_LOAD_FIRM, - EZUSB_CPUCS, - 0, - &value, - 1, - 100); - - /* Download all sections in the image to ULINK */ - for (int i = 0; i < ublast2_firmware_image.num_sections; i++) { - ret = ublast2_write_firmware_section(libusb_dev, - &ublast2_firmware_image, i); - if (ret != ERROR_OK) { - LOG_ERROR("Error while downloading the firmware"); - return ret; - } - } - - value = !CPU_RESET; - jtag_libusb_control_transfer(libusb_dev, - LIBUSB_REQUEST_TYPE_VENDOR | \ - LIBUSB_ENDPOINT_OUT, - USBBLASTER_CTRL_LOAD_FIRM, - EZUSB_CPUCS, - 0, - &value, - 1, - 100); - - image_close(&ublast2_firmware_image); - - return ERROR_OK; -} - -static int ublast2_libusb_init(struct ublast_lowlevel *low) -{ - const uint16_t vids[] = { low->ublast_vid_uninit, 0 }; - const uint16_t pids[] = { low->ublast_pid_uninit, 0 }; - struct jtag_libusb_device_handle *temp; - bool renumeration = false; - int ret; - - if (jtag_libusb_open(vids, pids, NULL, &temp) == ERROR_OK) { - LOG_INFO("Altera USB-Blaster II (uninitialized) found"); - LOG_INFO("Loading firmware..."); - ret = load_usb_blaster_firmware(temp, low); - jtag_libusb_close(temp); - if (ret != ERROR_OK) - return ret; - renumeration = true; - } - - const uint16_t vids_renum[] = { low->ublast_vid, 0 }; - const uint16_t pids_renum[] = { low->ublast_pid, 0 }; - - if (renumeration == false) { - if (jtag_libusb_open(vids_renum, pids_renum, NULL, &low->libusb_dev) != ERROR_OK) { - LOG_ERROR("Altera USB-Blaster II not found"); - return ERROR_FAIL; - } - } else { - int retry = 10; - while (jtag_libusb_open(vids_renum, pids_renum, NULL, &low->libusb_dev) != ERROR_OK && retry--) { - usleep(1000000); - LOG_INFO("Waiting for renumerate..."); - } - - if (!retry) { - LOG_ERROR("Altera USB-Blaster II not found"); - return ERROR_FAIL; - } - } - - char buffer[5]; - jtag_libusb_control_transfer(low->libusb_dev, - LIBUSB_REQUEST_TYPE_VENDOR | \ - LIBUSB_ENDPOINT_IN, - USBBLASTER_CTRL_READ_REV, - 0, - 0, - buffer, - 5, - 100); - - LOG_INFO("Altera USB-Blaster II found (Firm. rev. = %s)", buffer); - - return ERROR_OK; -} - -static int ublast2_libusb_quit(struct ublast_lowlevel *low) -{ - jtag_libusb_close(low->libusb_dev); - return ERROR_OK; -}; - -static struct ublast_lowlevel low = { - .open = ublast2_libusb_init, - .close = ublast2_libusb_quit, - .read = ublast2_libusb_read, - .write = ublast2_libusb_write, - .flags = COPY_TDO_BUFFER, -}; - -struct ublast_lowlevel *ublast2_register_libusb(void) -{ - return &low; -} diff --git a/src/jtag/drivers/usb_blaster/ublast_access.h b/src/jtag/drivers/usb_blaster/ublast_access.h deleted file mode 100644 index 00349d2ed..000000000 --- a/src/jtag/drivers/usb_blaster/ublast_access.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Driver for USB-JTAG, Altera USB-Blaster and compatibles - * - * Inspired from original code from Kolja Waschk's USB-JTAG project - * (http://www.ixo.de/info/usb_jtag/), and from openocd project. - * - * Copyright (C) 2013 Franck Jullien franck.jullien@gmail.com - * Copyright (C) 2012 Robert Jarzmik robert.jarzmik@free.fr - * Copyright (C) 2011 Ali Lown ali@lown.me.uk - * Copyright (C) 2009 Catalin Patulea cat@vv.carleton.ca - * Copyright (C) 2006 Kolja Waschk usbjtag@ixo.de - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#ifndef OPENOCD_JTAG_DRIVERS_USB_BLASTER_UBLAST_ACCESS_H -#define OPENOCD_JTAG_DRIVERS_USB_BLASTER_UBLAST_ACCESS_H - -#include - -/* Low level flags */ -#define COPY_TDO_BUFFER (1 << 0) - -struct ublast_lowlevel { - uint16_t ublast_vid; - uint16_t ublast_pid; - uint16_t ublast_vid_uninit; - uint16_t ublast_pid_uninit; - char *ublast_device_desc; - struct jtag_libusb_device_handle *libusb_dev; - char *firmware_path; - - int (*write)(struct ublast_lowlevel *low, uint8_t *buf, int size, - uint32_t *bytes_written); - int (*read)(struct ublast_lowlevel *low, uint8_t *buf, unsigned size, - uint32_t *bytes_read); - int (*open)(struct ublast_lowlevel *low); - int (*close)(struct ublast_lowlevel *low); - int (*speed)(struct ublast_lowlevel *low, int speed); - - void *priv; - int flags; -}; - -/** - * 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 - * possible lowlevel drivers : - * - one based on libftdi from ftdichip.com - * - one based on libftdxx, the free alternative - * - 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 /* OPENOCD_JTAG_DRIVERS_USB_BLASTER_UBLAST_ACCESS_H */ diff --git a/src/jtag/drivers/usb_blaster/ublast_access_ftd2xx.c b/src/jtag/drivers/usb_blaster/ublast_access_ftd2xx.c deleted file mode 100644 index ffcf312e6..000000000 --- a/src/jtag/drivers/usb_blaster/ublast_access_ftd2xx.c +++ /dev/null @@ -1,180 +0,0 @@ -/* - * Driver for USB-JTAG, Altera USB-Blaster and compatibles - * - * Inspired from original code from Kolja Waschk's USB-JTAG project - * (http://www.ixo.de/info/usb_jtag/), and from openocd project. - * - * Copyright (C) 2012 Robert Jarzmik robert.jarzmik@free.fr - * Copyright (C) 2011 Ali Lown ali@lown.me.uk - * Copyright (C) 2009 Catalin Patulea cat@vv.carleton.ca - * Copyright (C) 2006 Kolja Waschk usbjtag@ixo.de - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#ifdef HAVE_CONFIG_H -#include -#endif -#include -#include - -#include "ublast_access.h" - -#include -#include "jtag/drivers/ftd2xx_common.h" - -static FT_HANDLE *ublast_getftdih(struct ublast_lowlevel *low) -{ - return low->priv; -} - -static int ublast_ftd2xx_write(struct ublast_lowlevel *low, uint8_t *buf, int size, - uint32_t *bytes_written) -{ - FT_STATUS status; - DWORD dw_bytes_written; - FT_HANDLE *ftdih = ublast_getftdih(low); - - status = FT_Write(*ftdih, buf, size, &dw_bytes_written); - if (status != FT_OK) { - *bytes_written = dw_bytes_written; - LOG_ERROR("FT_Write returned: %s", ftd2xx_status_string(status)); - return ERROR_JTAG_DEVICE_ERROR; - } - *bytes_written = dw_bytes_written; - return ERROR_OK; -} - -static int ublast_ftd2xx_read(struct ublast_lowlevel *low, uint8_t *buf, - unsigned size, uint32_t *bytes_read) -{ - DWORD dw_bytes_read; - FT_STATUS status; - FT_HANDLE *ftdih = ublast_getftdih(low); - - status = FT_Read(*ftdih, buf, size, &dw_bytes_read); - if (status != FT_OK) { - *bytes_read = dw_bytes_read; - LOG_ERROR("FT_Read returned: %s", ftd2xx_status_string(status)); - return ERROR_JTAG_DEVICE_ERROR; - } - *bytes_read = dw_bytes_read; - return ERROR_OK; -} - -static int ublast_ftd2xx_init(struct ublast_lowlevel *low) -{ - FT_STATUS status; - FT_HANDLE *ftdih = ublast_getftdih(low); - uint8_t latency_timer; - - LOG_INFO("usb blaster interface using FTD2XX"); - /* Open by device description */ - if (low->ublast_device_desc == NULL) { - LOG_WARNING("no usb blaster device description specified, " - "using default 'USB-Blaster'"); - low->ublast_device_desc = "USB-Blaster"; - } - -#if IS_WIN32 == 0 - /* Add non-standard Vid/Pid to the linux driver */ - status = FT_SetVIDPID(low->ublast_vid, low->ublast_pid); - if (status != FT_OK) { - LOG_WARNING("couldn't add %4.4x:%4.4x", - low->ublast_vid, low->ublast_pid); - } -#endif - status = FT_OpenEx(low->ublast_device_desc, FT_OPEN_BY_DESCRIPTION, - ftdih); - if (status != FT_OK) { - DWORD num_devices; - - LOG_ERROR("unable to open ftdi device: %s", - ftd2xx_status_string(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: %" PRIu32, (uint32_t)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 { - printf("ListDevices: NONE\n"); - } - return ERROR_JTAG_INIT_FAILED; - } - - status = FT_SetLatencyTimer(*ftdih, 2); - if (status != FT_OK) { - LOG_ERROR("unable to set latency timer: %s", - ftd2xx_status_string(status)); - return ERROR_JTAG_INIT_FAILED; - } - - status = FT_GetLatencyTimer(*ftdih, &latency_timer); - if (status != FT_OK) - LOG_ERROR("unable to get latency timer: %s", - ftd2xx_status_string(status)); - else - LOG_DEBUG("current latency timer: %i", latency_timer); - - status = FT_SetBitMode(*ftdih, 0x00, 0); - if (status != FT_OK) { - LOG_ERROR("unable to disable bit i/o mode: %s", - ftd2xx_status_string(status)); - return ERROR_JTAG_INIT_FAILED; - } - return ERROR_OK; -} - -static int ublast_ftd2xx_quit(struct ublast_lowlevel *low) -{ - FT_HANDLE *ftdih = ublast_getftdih(low); - - FT_Close(*ftdih); - return ERROR_OK; -} - -static struct ublast_lowlevel_priv { - FT_HANDLE ftdih; -} info; - -static struct ublast_lowlevel low = { - .open = ublast_ftd2xx_init, - .close = ublast_ftd2xx_quit, - .read = ublast_ftd2xx_read, - .write = ublast_ftd2xx_write, - .priv = &info, -}; - -struct ublast_lowlevel *ublast_register_ftd2xx(void) -{ - return &low; -} diff --git a/src/jtag/drivers/usb_blaster/ublast_access_ftdi.c b/src/jtag/drivers/usb_blaster/ublast_access_ftdi.c deleted file mode 100644 index cb442f2b5..000000000 --- a/src/jtag/drivers/usb_blaster/ublast_access_ftdi.c +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Driver for USB-JTAG, Altera USB-Blaster and compatibles - * - * Inspired from original code from Kolja Waschk's USB-JTAG project - * (http://www.ixo.de/info/usb_jtag/), and from openocd project. - * - * Copyright (C) 2012 Robert Jarzmik robert.jarzmik@free.fr - * Copyright (C) 2011 Ali Lown ali@lown.me.uk - * Copyright (C) 2009 Catalin Patulea cat@vv.carleton.ca - * Copyright (C) 2006 Kolja Waschk usbjtag@ixo.de - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#ifdef HAVE_CONFIG_H -#include -#endif -#include -#include - -#include "ublast_access.h" -#include - -static struct ftdi_context *ublast_getftdic(struct ublast_lowlevel *low) -{ - return low->priv; -} - -static int ublast_ftdi_read(struct ublast_lowlevel *low, uint8_t *buf, - unsigned size, uint32_t *bytes_read) -{ - int retval; - int timeout = 100; - struct ftdi_context *ftdic = ublast_getftdic(low); - - *bytes_read = 0; - while ((*bytes_read < size) && timeout--) { - retval = ftdi_read_data(ftdic, buf + *bytes_read, - size - *bytes_read); - if (retval < 0) { - *bytes_read = 0; - LOG_ERROR("ftdi_read_data: %s", - ftdi_get_error_string(ftdic)); - return ERROR_JTAG_DEVICE_ERROR; - } - *bytes_read += retval; - } - return ERROR_OK; -} - -static int ublast_ftdi_write(struct ublast_lowlevel *low, uint8_t *buf, int size, - uint32_t *bytes_written) -{ - int retval; - struct ftdi_context *ftdic = ublast_getftdic(low); - - retval = ftdi_write_data(ftdic, buf, size); - if (retval < 0) { - *bytes_written = 0; - LOG_ERROR("ftdi_write_data: %s", - ftdi_get_error_string(ftdic)); - return ERROR_JTAG_DEVICE_ERROR; - } - *bytes_written = retval; - return ERROR_OK; -} - -static int ublast_ftdi_init(struct ublast_lowlevel *low) -{ - uint8_t latency_timer; - struct ftdi_context *ftdic = ublast_getftdic(low); - - LOG_INFO("usb blaster interface using libftdi"); - if (ftdi_init(ftdic) < 0) - return ERROR_JTAG_INIT_FAILED; - - /* context, vendor id, product id */ - if (ftdi_usb_open(ftdic, low->ublast_vid, low->ublast_pid) < 0) { - LOG_ERROR("unable to open ftdi device: %s", ftdic->error_str); - return ERROR_JTAG_INIT_FAILED; - } - - if (ftdi_usb_reset(ftdic) < 0) { - LOG_ERROR("unable to reset ftdi device"); - return ERROR_JTAG_INIT_FAILED; - } - - if (ftdi_set_latency_timer(ftdic, 2) < 0) { - LOG_ERROR("unable to set latency timer"); - return ERROR_JTAG_INIT_FAILED; - } - - if (ftdi_get_latency_timer(ftdic, &latency_timer) < 0) - LOG_ERROR("unable to get latency timer"); - else - LOG_DEBUG("current latency timer: %u", latency_timer); - - ftdi_disable_bitbang(ftdic); - return ERROR_OK; -} - -static int ublast_ftdi_quit(struct ublast_lowlevel *low) -{ - struct ftdi_context *ftdic = ublast_getftdic(low); - - ftdi_usb_close(ftdic); - ftdi_deinit(ftdic); - return ERROR_OK; -}; - -static struct ublast_lowlevel_priv { - struct ftdi_context ftdic; -} info; - -static struct ublast_lowlevel low = { - .open = ublast_ftdi_init, - .close = ublast_ftdi_quit, - .read = ublast_ftdi_read, - .write = ublast_ftdi_write, - .priv = &info, -}; - -struct ublast_lowlevel *ublast_register_ftdi(void) -{ - return &low; -} diff --git a/src/jtag/drivers/usb_blaster/usb_blaster.c b/src/jtag/drivers/usb_blaster/usb_blaster.c deleted file mode 100644 index 8f3f327b9..000000000 --- a/src/jtag/drivers/usb_blaster/usb_blaster.c +++ /dev/null @@ -1,1079 +0,0 @@ -/* - * Driver for USB-JTAG, Altera USB-Blaster and compatibles - * - * Inspired from original code from Kolja Waschk's USB-JTAG project - * (http://www.ixo.de/info/usb_jtag/), and from openocd project. - * - * Copyright (C) 2013 Franck Jullien franck.jullien@gmail.com - * Copyright (C) 2012 Robert Jarzmik robert.jarzmik@free.fr - * Copyright (C) 2011 Ali Lown ali@lown.me.uk - * Copyright (C) 2009 Catalin Patulea cat@vv.carleton.ca - * Copyright (C) 2006 Kolja Waschk usbjtag@ixo.de - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/* - * The following information is originally from Kolja Waschk's USB-JTAG, - * where it was obtained by reverse engineering an Altera USB-Blaster. - * See http://www.ixo.de/info/usb_jtag/ for USB-Blaster block diagram and - * usb_jtag-20080705-1200.zip#usb_jtag/host/openocd for protocol. - * - * The same information is also on the UrJTAG mediawiki, with some additional - * notes on bits marked as "unknown" by usb_jtag. - * (http://sourceforge.net/apps/mediawiki/urjtag/index.php? - * title=Cable_Altera_USB-Blaster) - * - * USB-JTAG, Altera USB-Blaster and compatibles are typically implemented as - * an FTDIChip FT245 followed by a CPLD which handles a two-mode protocol: - * - * _________ - * | | - * | AT93C46 | - * |_________| - * __|__________ _________ - * | | | | - * USB__| FTDI 245BM |__| EPM7064 |__JTAG (B_TDO,B_TDI,B_TMS,B_TCK) - * |_____________| |_________| - * __|__________ _|___________ - * | | | | - * | 6 MHz XTAL | | 24 MHz Osc. | - * |_____________| |_____________| - * - * USB-JTAG, Altera USB-Blaster II are typically implemented as a Cypress - * EZ-USB FX2LP followed by a CPLD. - * _____________ _________ - * | | | | - * USB__| EZ-USB FX2 |__| EPM570 |__JTAG (B_TDO,B_TDI,B_TMS,B_TCK) - * |_____________| |_________| - * __|__________ - * | | - * | 24 MHz XTAL | - * |_____________| - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#if IS_CYGWIN == 1 -#include "windows.h" -#undef LOG_ERROR -#endif - -/* project specific includes */ -#include -#include -#include -#include "ublast_access.h" - -/* system includes */ -#include -#include -#include -#include -#include - -/* Size of USB endpoint max packet size, ie. 64 bytes */ -#define MAX_PACKET_SIZE 64 -/* - * Size of data buffer that holds bytes in byte-shift mode. - * This buffer can hold multiple USB packets aligned to - * MAX_PACKET_SIZE bytes boundaries. - * BUF_LEN must be grater than or equal MAX_PACKET_SIZE. - */ -#define BUF_LEN 4096 - -/* USB-Blaster II specific command */ -#define CMD_COPY_TDO_BUFFER 0x5F - -enum gpio_steer { - FIXED_0 = 0, - FIXED_1, - SRST, - TRST, -}; - -struct ublast_info { - enum gpio_steer pin6; - enum gpio_steer pin8; - int tms; - int tdi; - bool trst_asserted; - bool srst_asserted; - uint8_t buf[BUF_LEN]; - int bufidx; - - char *lowlevel_name; - struct ublast_lowlevel *drv; - char *ublast_device_desc; - uint16_t ublast_vid, ublast_pid; - uint16_t ublast_vid_uninit, ublast_pid_uninit; - int flags; - char *firmware_path; -}; - -/* - * Global device control - */ -static struct ublast_info info = { - .ublast_vid = 0x09fb, /* Altera */ - .ublast_pid = 0x6001, /* USB-Blaster */ - .lowlevel_name = NULL, - .srst_asserted = false, - .trst_asserted = false, - .pin6 = FIXED_1, - .pin8 = FIXED_1, -}; - -/* - * Available lowlevel drivers (FTDI, FTD2xx, ...) - */ -struct drvs_map { - char *name; - struct ublast_lowlevel *(*drv_register)(void); -}; - -static struct drvs_map lowlevel_drivers_map[] = { -#if BUILD_USB_BLASTER_LIBFTDI - { .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 - { NULL, NULL }, -}; - -/* - * Access functions to lowlevel driver, agnostic of libftdi/libftdxx - */ -static char *hexdump(uint8_t *buf, unsigned int size) -{ - unsigned int i; - char *str = calloc(size * 2 + 1, 1); - - for (i = 0; i < size; i++) - sprintf(str + 2*i, "%02x", buf[i]); - return str; -} - -static int ublast_buf_read(uint8_t *buf, unsigned size, uint32_t *bytes_read) -{ - int ret = info.drv->read(info.drv, buf, size, bytes_read); - char *str = hexdump(buf, *bytes_read); - - DEBUG_JTAG_IO("(size=%d, buf=[%s]) -> %u", size, str, - *bytes_read); - free(str); - return ret; -} - -static int ublast_buf_write(uint8_t *buf, int size, uint32_t *bytes_written) -{ - int ret = info.drv->write(info.drv, buf, size, bytes_written); - char *str = hexdump(buf, *bytes_written); - - DEBUG_JTAG_IO("(size=%d, buf=[%s]) -> %u", size, str, - *bytes_written); - free(str); - return ret; -} - -static int nb_buf_remaining(void) -{ - return BUF_LEN - info.bufidx; -} - -static void ublast_flush_buffer(void) -{ - unsigned int retlen; - int nb = info.bufidx, ret = ERROR_OK; - - while (ret == ERROR_OK && nb > 0) { - ret = ublast_buf_write(info.buf, nb, &retlen); - nb -= retlen; - } - info.bufidx = 0; -} - -/* - * Actually, the USB-Blaster offers a byte-shift mode to transmit up to 504 data - * bits (bidirectional) in a single USB packet. A header byte has to be sent as - * the first byte in a packet with the following meaning: - * - * Bit 7 (0x80): Must be set to indicate byte-shift mode. - * Bit 6 (0x40): If set, the USB-Blaster will also read data, not just write. - * Bit 5..0: Define the number N of following bytes - * - * All N following bytes will then be clocked out serially on TDI. If Bit 6 was - * set, it will afterwards return N bytes with TDO data read while clocking out - * the TDI data. LSB of the first byte after the header byte will appear first - * on TDI. - */ - -/* Simple bit banging mode: - * - * Bit 7 (0x80): Must be zero (see byte-shift mode above) - * Bit 6 (0x40): If set, you will receive a byte indicating the state of TDO - * in return. - * Bit 5 (0x20): Output Enable/LED. - * Bit 4 (0x10): TDI Output. - * Bit 3 (0x08): nCS Output (not used in JTAG mode). - * Bit 2 (0x04): nCE Output (not used in JTAG mode). - * Bit 1 (0x02): TMS Output. - * Bit 0 (0x01): TCK Output. - * - * For transmitting a single data bit, you need to write two bytes (one for - * setting up TDI/TMS/TCK=0, and one to trigger TCK high with same TDI/TMS - * held). Up to 64 bytes can be combined in a single USB packet. - * It isn't possible to read a data without transmitting data. - */ - -#define TCK (1 << 0) -#define TMS (1 << 1) -#define NCE (1 << 2) -#define NCS (1 << 3) -#define TDI (1 << 4) -#define LED (1 << 5) -#define READ (1 << 6) -#define SHMODE (1 << 7) -#define READ_TDO (1 << 0) - -/** - * ublast_queue_byte - queue one 'bitbang mode' byte for USB Blaster - * @abyte: the byte to queue - * - * Queues one byte in 'bitbang mode' to the USB Blaster. The byte is not - * actually sent, but stored in a buffer. The write is performed once - * the buffer is filled, or if an explicit ublast_flush_buffer() is called. - */ -static void ublast_queue_byte(uint8_t abyte) -{ - if (nb_buf_remaining() < 1) - ublast_flush_buffer(); - info.buf[info.bufidx++] = abyte; - if (nb_buf_remaining() == 0) - ublast_flush_buffer(); - DEBUG_JTAG_IO("(byte=0x%02x)", abyte); -} - -/** - * ublast_compute_pin - compute if gpio should be asserted - * @steer: control (ie. TRST driven, SRST driven, of fixed) - * - * Returns pin value (1 means driven high, 0 mean driven low) - */ -bool ublast_compute_pin(enum gpio_steer steer) -{ - switch (steer) { - case FIXED_0: - return 0; - case FIXED_1: - return 1; - case SRST: - return !info.srst_asserted; - case TRST: - return !info.trst_asserted; - default: - return 1; - } -} - -/** - * ublast_build_out - build bitbang mode output byte - * @type: says if reading back TDO is required - * - * Returns the compute bitbang mode byte - */ -static uint8_t ublast_build_out(enum scan_type type) -{ - uint8_t abyte = 0; - - abyte |= info.tms ? TMS : 0; - abyte |= ublast_compute_pin(info.pin6) ? NCE : 0; - abyte |= ublast_compute_pin(info.pin8) ? NCS : 0; - abyte |= info.tdi ? TDI : 0; - abyte |= LED; - if (type == SCAN_IN || type == SCAN_IO) - abyte |= READ; - return abyte; -} - -/** - * ublast_reset - reset the JTAG device is possible - * @trst: 1 if TRST is to be asserted - * @srst: 1 if SRST is to be asserted - */ -static void ublast_reset(int trst, int srst) -{ - uint8_t out_value; - - info.trst_asserted = trst; - info.srst_asserted = srst; - out_value = ublast_build_out(SCAN_OUT); - ublast_queue_byte(out_value); - ublast_flush_buffer(); -} - -/** - * ublast_clock_tms - clock a TMS transition - * @tms: the TMS to be sent - * - * Triggers a TMS transition (ie. one JTAG TAP state move). - */ -static void ublast_clock_tms(int tms) -{ - uint8_t out; - - DEBUG_JTAG_IO("(tms=%d)", !!tms); - info.tms = !!tms; - info.tdi = 0; - out = ublast_build_out(SCAN_OUT); - ublast_queue_byte(out); - ublast_queue_byte(out | TCK); -} - -/** - * ublast_idle_clock - put back TCK to low level - * - * See ublast_queue_tdi() comment for the usage of this function. - */ -static void ublast_idle_clock(void) -{ - uint8_t out = ublast_build_out(SCAN_OUT); - - DEBUG_JTAG_IO("."); - ublast_queue_byte(out); -} - -/** - * ublast_clock_tdi - Output a TDI with bitbang mode - * @tdi: the TDI bit to be shifted out - * @type: scan type (ie. does a readback of TDO is required) - * - * Output a TDI bit and assert clock to push it into the JTAG device : - * - writing out TCK=0, TMS==0, TDI= - * - writing out TCK=1, TMS=, TDI= which triggers the JTAG - * device aquiring the data. - * - * If a TDO is to be read back, the required read is requested (bitbang mode), - * and the USB Blaster will send back a byte with bit0 reprensenting the TDO. - */ -static void ublast_clock_tdi(int tdi, enum scan_type type) -{ - uint8_t out; - - DEBUG_JTAG_IO("(tdi=%d)", !!tdi); - info.tdi = !!tdi; - - out = ublast_build_out(SCAN_OUT); - ublast_queue_byte(out); - - out = ublast_build_out(type); - ublast_queue_byte(out | TCK); -} - -/** - * ublast_clock_tdi_flip_tms - Output a TDI with bitbang mode, change JTAG state - * @tdi: the TDI bit to be shifted out - * @type: scan type (ie. does a readback of TDO is required) - * - * This function is the same as ublast_clock_tdi(), but it changes also the TMS - * while outputing the TDI. This should be the last TDI output of a TDI - * sequence, which will change state from : - * - IRSHIFT -> IREXIT1 - * - or DRSHIFT -> DREXIT1 - */ -static void ublast_clock_tdi_flip_tms(int tdi, enum scan_type type) -{ - uint8_t out; - - DEBUG_JTAG_IO("(tdi=%d)", !!tdi); - info.tdi = !!tdi; - info.tms = !info.tms; - - out = ublast_build_out(SCAN_OUT); - ublast_queue_byte(out); - - out = ublast_build_out(type); - ublast_queue_byte(out | TCK); - - out = ublast_build_out(SCAN_OUT); - ublast_queue_byte(out); -} - -/** - * ublast_queue_bytes - queue bytes for the USB Blaster - * @bytes: byte array - * @nb_bytes: number of bytes - * - * Queues bytes to be sent to the USB Blaster. The bytes are not - * actually sent, but stored in a buffer. The write is performed once - * the buffer is filled, or if an explicit ublast_flush_buffer() is called. - */ -static void ublast_queue_bytes(uint8_t *bytes, int nb_bytes) -{ - if (info.bufidx + nb_bytes > BUF_LEN) { - LOG_ERROR("buggy code, should never queue more that %d bytes", - info.bufidx + nb_bytes); - exit(-1); - } - DEBUG_JTAG_IO("(nb_bytes=%d, bytes=[0x%02x, ...])", nb_bytes, - bytes ? bytes[0] : 0); - if (bytes) - memcpy(&info.buf[info.bufidx], bytes, nb_bytes); - else - memset(&info.buf[info.bufidx], 0, nb_bytes); - info.bufidx += nb_bytes; - if (nb_buf_remaining() == 0) - ublast_flush_buffer(); -} - -/** - * ublast_tms_seq - write a TMS sequence transition to JTAG - * @bits: TMS bits to be written (bit0, bit1 .. bitN) - * @nb_bits: number of TMS bits (between 1 and 8) - * - * Write a serie of TMS transitions, where each transition consists in : - * - writing out TCK=0, TMS=, TDI= - * - writing out TCK=1, TMS=, TDI= which triggers the transition - * The function ensures that at the end of the sequence, the clock (TCK) is put - * low. - */ -static void ublast_tms_seq(const uint8_t *bits, int nb_bits) -{ - int i; - - DEBUG_JTAG_IO("(bits=%02x..., nb_bits=%d)", bits[0], nb_bits); - for (i = 0; i < nb_bits; i++) - ublast_clock_tms((bits[i / 8] >> (i % 8)) & 0x01); - ublast_idle_clock(); -} - -/** - * ublast_tms - write a tms command - * @cmd: tms command - */ -static void ublast_tms(struct tms_command *cmd) -{ - DEBUG_JTAG_IO("(num_bits=%d)", cmd->num_bits); - ublast_tms_seq(cmd->bits, cmd->num_bits); -} - -/** - * ublast_path_move - write a TMS sequence transition to JTAG - * @cmd: path transition - * - * Write a serie of TMS transitions, where each transition consists in : - * - writing out TCK=0, TMS=, TDI= - * - writing out TCK=1, TMS=, TDI= which triggers the transition - * The function ensures that at the end of the sequence, the clock (TCK) is put - * low. - */ -static void ublast_path_move(struct pathmove_command *cmd) -{ - int i; - - DEBUG_JTAG_IO("(num_states=%d, last_state=%d)", - cmd->num_states, cmd->path[cmd->num_states - 1]); - for (i = 0; i < cmd->num_states; i++) { - if (tap_state_transition(tap_get_state(), false) == cmd->path[i]) - ublast_clock_tms(0); - if (tap_state_transition(tap_get_state(), true) == cmd->path[i]) - ublast_clock_tms(1); - tap_set_state(cmd->path[i]); - } - ublast_idle_clock(); -} - -/** - * ublast_state_move - move JTAG state to the target state - * @state: the target state - * - * Input the correct TMS sequence to the JTAG TAP so that we end up in the - * target state. This assumes the current state (tap_get_state()) is correct. - */ -static void ublast_state_move(tap_state_t state) -{ - uint8_t tms_scan; - int tms_len; - - DEBUG_JTAG_IO("(from %s to %s)", tap_state_name(tap_get_state()), - tap_state_name(state)); - if (tap_get_state() == state) - return; - tms_scan = tap_get_tms_path(tap_get_state(), state); - tms_len = tap_get_tms_path_len(tap_get_state(), state); - ublast_tms_seq(&tms_scan, tms_len); - tap_set_state(state); -} - -/** - * ublast_read_byteshifted_tdos - read TDO of byteshift writes - * @buf: the buffer to store the bits - * @nb_bits: the number of bits - * - * Reads back from USB Blaster TDO bits, triggered by a 'byteshift write', ie. eight - * bits per received byte from USB interface, and store them in buffer. - * - * As the USB blaster stores the TDO bits in LSB (ie. first bit in (byte0, - * bit0), second bit in (byte0, bit1), ...), which is what we want to return, - * simply read bytes from USB interface and store them. - * - * Returns ERROR_OK if OK, ERROR_xxx if a read error occured - */ -static int ublast_read_byteshifted_tdos(uint8_t *buf, int nb_bytes) -{ - unsigned int retlen; - int ret = ERROR_OK; - - DEBUG_JTAG_IO("%s(buf=%p, num_bits=%d)", __func__, buf, nb_bytes * 8); - ublast_flush_buffer(); - while (ret == ERROR_OK && nb_bytes > 0) { - ret = ublast_buf_read(buf, nb_bytes, &retlen); - nb_bytes -= retlen; - } - return ret; -} - -/** - * ublast_read_bitbang_tdos - read TDO of bitbang writes - * @buf: the buffer to store the bits - * @nb_bits: the number of bits - * - * Reads back from USB Blaster TDO bits, triggered by a 'bitbang write', ie. one - * bit per received byte from USB interface, and store them in buffer, where : - * - first bit is stored in byte0, bit0 (LSB) - * - second bit is stored in byte0, bit 1 - * ... - * - eight bit is sotred in byte0, bit 7 - * - ninth bit is sotred in byte1, bit 0 - * - etc ... - * - * Returns ERROR_OK if OK, ERROR_xxx if a read error occured - */ -static int ublast_read_bitbang_tdos(uint8_t *buf, int nb_bits) -{ - int nb1 = nb_bits; - int i, ret = ERROR_OK; - unsigned int retlen; - uint8_t tmp[8]; - - DEBUG_JTAG_IO("%s(buf=%p, num_bits=%d)", __func__, buf, nb_bits); - - /* - * Ensure all previous bitbang writes were issued to the dongle, so that - * it returns back the read values. - */ - ublast_flush_buffer(); - - ret = ublast_buf_read(tmp, nb1, &retlen); - for (i = 0; ret == ERROR_OK && i < nb1; i++) - if (tmp[i] & READ_TDO) - *buf |= (1 << i); - else - *buf &= ~(1 << i); - return ret; -} - -/** - * ublast_queue_tdi - short description - * @bits: bits to be queued on TDI (or NULL if 0 are to be queued) - * @nb_bits: number of bits - * @scan: scan type (ie. if TDO read back is required or not) - * - * Outputs a serie of TDI bits on TDI. - * As a side effect, the last TDI bit is sent along a TMS=1, and triggers a JTAG - * TAP state shift if input bits were non NULL. - * - * In order to not saturate the USB Blaster queues, this method reads back TDO - * if the scan type requests it, and stores them back in bits. - * - * As a side note, the state of TCK when entering this function *must* be - * low. This is because byteshift mode outputs TDI on rising TCK and reads TDO - * on falling TCK if and only if TCK is low before queuing byteshift mode bytes. - * If TCK was high, the USB blaster will queue TDI on falling edge, and read TDO - * on rising edge !!! - */ -static void ublast_queue_tdi(uint8_t *bits, int nb_bits, enum scan_type scan) -{ - int nb8 = nb_bits / 8; - int nb1 = nb_bits % 8; - int nbfree_in_packet, i, trans = 0, read_tdos; - uint8_t *tdos = calloc(1, nb_bits / 8 + 1); - static uint8_t byte0[BUF_LEN]; - - /* - * As the last TDI bit should always be output in bitbang mode in order - * to activate the TMS=1 transition to EXIT_?R state. Therefore a - * situation where nb_bits is a multiple of 8 is handled as follows: - * - the number of TDI shifted out in "byteshift mode" is 8 less than - * nb_bits - * - nb1 = 8 - * This ensures that nb1 is never 0, and allows the TMS transition. - */ - if (nb8 > 0 && nb1 == 0) { - nb8--; - nb1 = 8; - } - - read_tdos = (scan == SCAN_IN || scan == SCAN_IO); - for (i = 0; i < nb8; i += trans) { - /* - * Calculate number of bytes to fill USB packet of size MAX_PACKET_SIZE - */ - nbfree_in_packet = (MAX_PACKET_SIZE - (info.bufidx%MAX_PACKET_SIZE)); - trans = MIN(nbfree_in_packet - 1, nb8 - i); - - /* - * Queue a byte-shift mode transmission, with as many bytes as - * is possible with regard to : - * - current filling level of write buffer - * - remaining bytes to write in byte-shift mode - */ - if (read_tdos) - ublast_queue_byte(SHMODE | READ | trans); - else - ublast_queue_byte(SHMODE | trans); - if (bits) - ublast_queue_bytes(&bits[i], trans); - else - ublast_queue_bytes(byte0, trans); - if (read_tdos) { - if (info.flags & COPY_TDO_BUFFER) - ublast_queue_byte(CMD_COPY_TDO_BUFFER); - ublast_read_byteshifted_tdos(&tdos[i], trans); - } - } - - /* - * Queue the remaining TDI bits in bitbang mode. - */ - for (i = 0; i < nb1; i++) { - int tdi = bits ? bits[nb8 + i / 8] & (1 << i) : 0; - if (bits && i == nb1 - 1) - ublast_clock_tdi_flip_tms(tdi, scan); - else - ublast_clock_tdi(tdi, scan); - } - if (nb1 && read_tdos) { - if (info.flags & COPY_TDO_BUFFER) - ublast_queue_byte(CMD_COPY_TDO_BUFFER); - ublast_read_bitbang_tdos(&tdos[nb8], nb1); - } - - if (bits) - memcpy(bits, tdos, DIV_ROUND_UP(nb_bits, 8)); - free(tdos); - - /* - * Ensure clock is in lower state - */ - ublast_idle_clock(); -} - -static void ublast_runtest(int cycles, tap_state_t state) -{ - DEBUG_JTAG_IO("%s(cycles=%i, end_state=%d)", __func__, cycles, state); - - ublast_state_move(TAP_IDLE); - ublast_queue_tdi(NULL, cycles, SCAN_OUT); - ublast_state_move(state); -} - -static void ublast_stableclocks(int cycles) -{ - DEBUG_JTAG_IO("%s(cycles=%i)", __func__, cycles); - ublast_queue_tdi(NULL, cycles, SCAN_OUT); -} - -/** - * ublast_scan - launches a DR-scan or IR-scan - * @cmd: the command to launch - * - * Launch a JTAG IR-scan or DR-scan - * - * Returns ERROR_OK if OK, ERROR_xxx if a read/write error occured. - */ -static int ublast_scan(struct scan_command *cmd) -{ - int scan_bits; - uint8_t *buf = NULL; - enum scan_type type; - int ret = ERROR_OK; - static const char * const type2str[] = { "", "SCAN_IN", "SCAN_OUT", "SCAN_IO" }; - char *log_buf = NULL; - - type = jtag_scan_type(cmd); - scan_bits = jtag_build_buffer(cmd, &buf); - - if (cmd->ir_scan) - ublast_state_move(TAP_IRSHIFT); - else - ublast_state_move(TAP_DRSHIFT); - - log_buf = hexdump(buf, DIV_ROUND_UP(scan_bits, 8)); - DEBUG_JTAG_IO("%s(scan=%s, type=%s, bits=%d, buf=[%s], end_state=%d)", __func__, - cmd->ir_scan ? "IRSCAN" : "DRSCAN", - type2str[type], - scan_bits, log_buf, cmd->end_state); - free(log_buf); - - ublast_queue_tdi(buf, scan_bits, type); - - /* - * As our JTAG is in an unstable state (IREXIT1 or DREXIT1), move it - * forward to a stable IRPAUSE or DRPAUSE. - */ - ublast_clock_tms(0); - if (cmd->ir_scan) - tap_set_state(TAP_IRPAUSE); - else - tap_set_state(TAP_DRPAUSE); - - ret = jtag_read_buffer(buf, cmd); - if (buf) - free(buf); - ublast_state_move(cmd->end_state); - return ret; -} - -static void ublast_usleep(int us) -{ - DEBUG_JTAG_IO("%s(us=%d)", __func__, us); - jtag_sleep(us); -} - -static void ublast_initial_wipeout(void) -{ - static uint8_t tms_reset = 0xff; - uint8_t out_value; - uint32_t retlen; - int i; - - out_value = ublast_build_out(SCAN_OUT); - for (i = 0; i < BUF_LEN; i++) - info.buf[i] = out_value | ((i % 2) ? TCK : 0); - - /* - * Flush USB-Blaster queue fifos - * - empty the write FIFO (128 bytes) - * - empty the read FIFO (384 bytes) - */ - ublast_buf_write(info.buf, BUF_LEN, &retlen); - /* - * Put JTAG in RESET state (five 1 on TMS) - */ - ublast_tms_seq(&tms_reset, 5); - tap_set_state(TAP_RESET); -} - -static int ublast_execute_queue(void) -{ - struct jtag_command *cmd; - static int first_call = 1; - int ret = ERROR_OK; - - if (first_call) { - first_call--; - ublast_initial_wipeout(); - } - - for (cmd = jtag_command_queue; ret == ERROR_OK && cmd != NULL; - cmd = cmd->next) { - switch (cmd->type) { - case JTAG_RESET: - ublast_reset(cmd->cmd.reset->trst, cmd->cmd.reset->srst); - break; - case JTAG_RUNTEST: - ublast_runtest(cmd->cmd.runtest->num_cycles, - cmd->cmd.runtest->end_state); - break; - case JTAG_STABLECLOCKS: - ublast_stableclocks(cmd->cmd.stableclocks->num_cycles); - break; - case JTAG_TLR_RESET: - ublast_state_move(cmd->cmd.statemove->end_state); - break; - case JTAG_PATHMOVE: - ublast_path_move(cmd->cmd.pathmove); - break; - case JTAG_TMS: - ublast_tms(cmd->cmd.tms); - break; - case JTAG_SLEEP: - ublast_usleep(cmd->cmd.sleep->us); - break; - case JTAG_SCAN: - ret = ublast_scan(cmd->cmd.scan); - break; - } - } - - ublast_flush_buffer(); - return ret; -} - -/** - * ublast_init - Initialize the Altera device - * - * Initialize the device : - * - open the USB device - * - pretend it's initialized while actual init is delayed until first jtag command - * - * Returns ERROR_OK if USB device found, error if not. - */ -static int ublast_init(void) -{ - int ret, i; - - if (info.lowlevel_name) { - for (i = 0; lowlevel_drivers_map[i].name; i++) - if (!strcmp(lowlevel_drivers_map[i].name, info.lowlevel_name)) - break; - if (lowlevel_drivers_map[i].name) - info.drv = lowlevel_drivers_map[i].drv_register(); - if (!info.drv) { - LOG_ERROR("no lowlevel driver found for %s or lowlevel driver opening error", - info.lowlevel_name); - return ERROR_JTAG_DEVICE_ERROR; - } - } else { - LOG_INFO("No lowlevel driver configured, will try them all"); - for (i = 0; !info.drv && lowlevel_drivers_map[i].name; i++) - info.drv = lowlevel_drivers_map[i].drv_register(); - if (!info.drv) { - LOG_ERROR("no lowlevel driver found"); - return ERROR_JTAG_DEVICE_ERROR; - } - info.lowlevel_name = strdup(lowlevel_drivers_map[i-1].name); - } - - /* - * Register the lowlevel driver - */ - info.drv->ublast_vid = info.ublast_vid; - info.drv->ublast_pid = info.ublast_pid; - info.drv->ublast_vid_uninit = info.ublast_vid_uninit; - info.drv->ublast_pid_uninit = info.ublast_pid_uninit; - info.drv->ublast_device_desc = info.ublast_device_desc; - info.drv->firmware_path = info.firmware_path; - - info.flags |= info.drv->flags; - - ret = info.drv->open(info.drv); - - /* - * Let lie here : the TAP is in an unknown state, but the first - * execute_queue() will trigger a ublast_initial_wipeout(), which will - * put the TAP in RESET. - */ - tap_set_state(TAP_RESET); - return ret; -} - -/** - * ublast_quit - Release the Altera device - * - * Releases the device : - * - put the device pins in 'high impedance' mode - * - close the USB device - * - * Returns always ERROR_OK - */ -static int ublast_quit(void) -{ - uint8_t byte0 = 0; - unsigned int retlen; - - ublast_buf_write(&byte0, 1, &retlen); - return info.drv->close(info.drv); -} - -COMMAND_HANDLER(ublast_handle_device_desc_command) -{ - if (CMD_ARGC != 1) - return ERROR_COMMAND_SYNTAX_ERROR; - - info.ublast_device_desc = strdup(CMD_ARGV[0]); - - return ERROR_OK; -} - -COMMAND_HANDLER(ublast_handle_vid_pid_command) -{ - if (CMD_ARGC > 4) { - LOG_WARNING("ignoring extra IDs in ublast_vid_pid " - "(maximum is 2 pairs)"); - CMD_ARGC = 4; - } - - if (CMD_ARGC >= 2) { - COMMAND_PARSE_NUMBER(u16, CMD_ARGV[0], info.ublast_vid); - COMMAND_PARSE_NUMBER(u16, CMD_ARGV[1], info.ublast_pid); - } else { - LOG_WARNING("incomplete ublast_vid_pid configuration"); - } - - if (CMD_ARGC == 4) { - COMMAND_PARSE_NUMBER(u16, CMD_ARGV[2], info.ublast_vid_uninit); - COMMAND_PARSE_NUMBER(u16, CMD_ARGV[3], info.ublast_pid_uninit); - } else { - LOG_WARNING("incomplete ublast_vid_pid configuration"); - } - - return ERROR_OK; -} - -COMMAND_HANDLER(ublast_handle_pin_command) -{ - uint8_t out_value; - const char * const pin_name = CMD_ARGV[0]; - enum gpio_steer *steer = NULL; - static const char * const pin_val_str[] = { - [FIXED_0] = "0", - [FIXED_1] = "1", - [SRST] = "SRST driven", - [TRST] = "TRST driven", - }; - - if (CMD_ARGC > 2) { - LOG_ERROR("%s takes exactly one or two arguments", CMD_NAME); - return ERROR_COMMAND_SYNTAX_ERROR; - } - - if (!strcmp(pin_name, "pin6")) - steer = &info.pin6; - if (!strcmp(pin_name, "pin8")) - steer = &info.pin8; - if (!steer) { - LOG_ERROR("%s: pin name must be \"pin6\" or \"pin8\"", - CMD_NAME); - return ERROR_COMMAND_SYNTAX_ERROR; - } - - if (CMD_ARGC == 1) { - LOG_INFO("%s: %s is set as %s\n", CMD_NAME, pin_name, - pin_val_str[*steer]); - } - - if (CMD_ARGC == 2) { - const char * const pin_value = CMD_ARGV[1]; - char val = pin_value[0]; - - if (strlen(pin_value) > 1) - val = '?'; - switch (tolower((unsigned char)val)) { - case '0': - *steer = FIXED_0; - break; - case '1': - *steer = FIXED_1; - break; - case 't': - *steer = TRST; - break; - case 's': - *steer = SRST; - break; - default: - LOG_ERROR("%s: pin value must be 0, 1, s (SRST) or t (TRST)", - pin_value); - return ERROR_COMMAND_SYNTAX_ERROR; - } - - if (info.drv) { - out_value = ublast_build_out(SCAN_OUT); - ublast_queue_byte(out_value); - ublast_flush_buffer(); - } - } - return ERROR_OK; -} - -COMMAND_HANDLER(ublast_handle_lowlevel_drv_command) -{ - if (CMD_ARGC != 1) - return ERROR_COMMAND_SYNTAX_ERROR; - - info.lowlevel_name = strdup(CMD_ARGV[0]); - - return ERROR_OK; -} - -COMMAND_HANDLER(ublast_firmware_command) -{ - if (CMD_ARGC != 1) - return ERROR_COMMAND_SYNTAX_ERROR; - - info.firmware_path = strdup(CMD_ARGV[0]); - - return ERROR_OK; -} - - -static const struct command_registration ublast_command_handlers[] = { - { - .name = "usb_blaster_device_desc", - .handler = ublast_handle_device_desc_command, - .mode = COMMAND_CONFIG, - .help = "set the USB device description of the USB-Blaster", - .usage = "description-string", - }, - { - .name = "usb_blaster_vid_pid", - .handler = ublast_handle_vid_pid_command, - .mode = COMMAND_CONFIG, - .help = "the vendor ID and product ID of the USB-Blaster and " \ - "vendor ID and product ID of the uninitialized device " \ - "for USB-Blaster II", - .usage = "vid pid vid_uninit pid_uninit", - }, - { - .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)", - }, - { - .name = "usb_blaster_pin", - .handler = ublast_handle_pin_command, - .mode = COMMAND_ANY, - .help = "show or set pin state for the unused GPIO pins", - .usage = "(pin6|pin8) (0|1|s|t)", - }, - { - .name = "usb_blaster_firmware", - .handler = &ublast_firmware_command, - .mode = COMMAND_CONFIG, - .help = "configure the USB-Blaster II firmware location", - .usage = "path/to/blaster_xxxx.hex", - }, - COMMAND_REGISTRATION_DONE -}; - -struct jtag_interface usb_blaster_interface = { - .name = "usb_blaster", - .commands = ublast_command_handlers, - .supported = DEBUG_CAP_TMS_SEQ, - - .execute_queue = ublast_execute_queue, - .init = ublast_init, - .quit = ublast_quit, -}; diff --git a/src/jtag/drivers/usb_common.c b/src/jtag/drivers/usb_common.c deleted file mode 100644 index 54be6a624..000000000 --- a/src/jtag/drivers/usb_common.c +++ /dev/null @@ -1,54 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2009 by Zachary T Welch * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 -#include "config.h" -#endif -#include "usb_common.h" - - -static bool jtag_usb_match(struct usb_device *dev, - const uint16_t vids[], const uint16_t pids[]) -{ - for (unsigned i = 0; vids[i] && pids[i]; i++) { - if (dev->descriptor.idVendor == vids[i] && - dev->descriptor.idProduct == pids[i]) - return true; - } - return false; -} - -int jtag_usb_open(const uint16_t vids[], const uint16_t pids[], - struct usb_dev_handle **out) -{ - usb_find_busses(); - usb_find_devices(); - - struct usb_bus *busses = usb_get_busses(); - for (struct usb_bus *bus = busses; bus; bus = bus->next) { - for (struct usb_device *dev = bus->devices; dev; dev = dev->next) { - if (!jtag_usb_match(dev, vids, pids)) - continue; - - *out = usb_open(dev); - if (NULL == *out) - return -errno; - return 0; - } - } - return -ENODEV; -} diff --git a/src/jtag/drivers/usb_common.h b/src/jtag/drivers/usb_common.h deleted file mode 100644 index 4d2bd2686..000000000 --- a/src/jtag/drivers/usb_common.h +++ /dev/null @@ -1,26 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2009 by Zachary T Welch * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 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 /* OPENOCD_JTAG_DRIVERS_USB_COMMON_H */ diff --git a/src/jtag/drivers/usbprog.c b/src/jtag/drivers/usbprog.c deleted file mode 100644 index d81c329d4..000000000 --- a/src/jtag/drivers/usbprog.c +++ /dev/null @@ -1,619 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Benedikt Sauter * - * sauter@ixbat.de * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -/* - * This file is based on Dominic Rath's amt_jtagaccel.c. - * - * usbprog is a free programming adapter. You can easily install - * different firmware versions from an "online pool" over USB. - * The adapter can be used for programming and debugging AVR and ARM - * processors, as USB to RS232 converter, as JTAG interface or as - * simple I/O interface (5 lines). - * - * http://www.embedded-projects.net/usbprog - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include "usb_common.h" - -#define VID 0x1781 -#define PID 0x0c63 - -/* Pins at usbprog */ -#define TDO_BIT 0 -#define TDI_BIT 3 -#define TCK_BIT 2 -#define TMS_BIT 1 - -static void usbprog_end_state(tap_state_t state); -static void usbprog_state_move(void); -static void usbprog_path_move(struct pathmove_command *cmd); -static void usbprog_runtest(int num_cycles); -static void usbprog_scan(bool ir_scan, enum scan_type type, uint8_t *buffer, int scan_size); - -#define UNKNOWN_COMMAND 0x00 -#define PORT_DIRECTION 0x01 -#define PORT_SET 0x02 -#define PORT_GET 0x03 -#define PORT_SETBIT 0x04 -#define PORT_GETBIT 0x05 -#define WRITE_TDI 0x06 -#define READ_TDO 0x07 -#define WRITE_AND_READ 0x08 -#define WRITE_TMS 0x09 -#define WRITE_TMS_CHAIN 0x0A - -struct usbprog_jtag { - struct usb_dev_handle *usb_handle; -}; - -static struct usbprog_jtag *usbprog_jtag_handle; - -static struct usbprog_jtag *usbprog_jtag_open(void); -/* static void usbprog_jtag_close(struct usbprog_jtag *usbprog_jtag); */ -static void usbprog_jtag_init(struct usbprog_jtag *usbprog_jtag); -static unsigned char usbprog_jtag_message(struct usbprog_jtag *usbprog_jtag, char *msg, int msglen); - -static void usbprog_jtag_read_tdo(struct usbprog_jtag *usbprog_jtag, char *buffer, int size); -static void usbprog_jtag_write_tdi(struct usbprog_jtag *usbprog_jtag, char *buffer, int size); -static void usbprog_jtag_write_and_read(struct usbprog_jtag *usbprog_jtag, char *buffer, int size); -static void usbprog_jtag_write_tms(struct usbprog_jtag *usbprog_jtag, char tms_scan); - -static char tms_chain[64]; -static int tms_chain_index; - -static void usbprog_jtag_tms_collect(char tms_scan); -static void usbprog_jtag_tms_send(struct usbprog_jtag *usbprog_jtag); - -static void usbprog_write(int tck, int tms, int tdi); -static void usbprog_reset(int trst, int srst); - -static void usbprog_jtag_set_direction(struct usbprog_jtag *usbprog_jtag, unsigned char direction); -static void usbprog_jtag_write_slice(struct usbprog_jtag *usbprog_jtag, unsigned char value); -/* static unsigned char usbprog_jtag_get_port(struct usbprog_jtag *usbprog_jtag); */ -static void usbprog_jtag_set_bit(struct usbprog_jtag *usbprog_jtag, int bit, int value); -/* static int usbprog_jtag_get_bit(struct usbprog_jtag *usbprog_jtag, int bit); */ - -static int usbprog_execute_queue(void) -{ - struct jtag_command *cmd = jtag_command_queue; /* currently processed command */ - int scan_size; - enum scan_type type; - uint8_t *buffer; - - while (cmd) { - switch (cmd->type) { - case JTAG_RESET: -#ifdef _DEBUG_JTAG_IO_ - LOG_DEBUG("reset trst: %i srst %i", - cmd->cmd.reset->trst, - cmd->cmd.reset->srst); -#endif - if (cmd->cmd.reset->trst == 1) - tap_set_state(TAP_RESET); - usbprog_reset(cmd->cmd.reset->trst, cmd->cmd.reset->srst); - break; - case JTAG_RUNTEST: -#ifdef _DEBUG_JTAG_IO_ - LOG_DEBUG("runtest %i cycles, end in %i", - cmd->cmd.runtest->num_cycles, - cmd->cmd.runtest->end_state); -#endif - usbprog_end_state(cmd->cmd.runtest->end_state); - usbprog_runtest(cmd->cmd.runtest->num_cycles); - break; - case JTAG_TLR_RESET: -#ifdef _DEBUG_JTAG_IO_ - LOG_DEBUG("statemove end in %i", cmd->cmd.statemove->end_state); -#endif - usbprog_end_state(cmd->cmd.statemove->end_state); - usbprog_state_move(); - break; - case JTAG_PATHMOVE: -#ifdef _DEBUG_JTAG_IO_ - LOG_DEBUG("pathmove: %i states, end in %i", - cmd->cmd.pathmove->num_states, - cmd->cmd.pathmove->path[cmd->cmd.pathmove->num_states - 1]); -#endif - usbprog_path_move(cmd->cmd.pathmove); - break; - case JTAG_SCAN: -#ifdef _DEBUG_JTAG_IO_ - LOG_DEBUG("scan end in %i", cmd->cmd.scan->end_state); -#endif - usbprog_end_state(cmd->cmd.scan->end_state); - scan_size = jtag_build_buffer(cmd->cmd.scan, &buffer); - type = jtag_scan_type(cmd->cmd.scan); - usbprog_scan(cmd->cmd.scan->ir_scan, type, buffer, scan_size); - if (jtag_read_buffer(buffer, cmd->cmd.scan) != ERROR_OK) - return ERROR_JTAG_QUEUE_FAILED; - if (buffer) - free(buffer); - break; - case JTAG_SLEEP: -#ifdef _DEBUG_JTAG_IO_ - LOG_DEBUG("sleep %i", cmd->cmd.sleep->us); -#endif - jtag_sleep(cmd->cmd.sleep->us); - break; - default: - LOG_ERROR("BUG: unknown JTAG command type encountered"); - exit(-1); - } - - cmd = cmd->next; - } - - return ERROR_OK; -} - -static int usbprog_init(void) -{ - usbprog_jtag_handle = usbprog_jtag_open(); - - tms_chain_index = 0; - if (usbprog_jtag_handle == 0) { - LOG_ERROR("Can't find USB JTAG Interface! Please check connection and permissions."); - return ERROR_JTAG_INIT_FAILED; - } - - LOG_INFO("USB JTAG Interface ready!"); - - usbprog_jtag_init(usbprog_jtag_handle); - usbprog_reset(0, 0); - usbprog_write(0, 0, 0); - - return ERROR_OK; -} - -static int usbprog_quit(void) -{ - return ERROR_OK; -} - -/*************** jtag execute commands **********************/ -static void usbprog_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); - } -} - -static void usbprog_state_move(void) -{ - uint8_t tms_scan = tap_get_tms_path(tap_get_state(), tap_get_end_state()); - - usbprog_jtag_write_tms(usbprog_jtag_handle, (char)tms_scan); - - tap_set_state(tap_get_end_state()); -} - -static void usbprog_path_move(struct pathmove_command *cmd) -{ - int num_states = cmd->num_states; - int state_count; - - /* There may be queued transitions, and before following a specified - path, we must flush those queued transitions */ - usbprog_jtag_tms_send(usbprog_jtag_handle); - - state_count = 0; - while (num_states) { - if (tap_state_transition(tap_get_state(), false) == cmd->path[state_count]) { - /* LOG_INFO("1"); */ - usbprog_write(0, 0, 0); - usbprog_write(1, 0, 0); - } else if (tap_state_transition(tap_get_state(), - true) == cmd->path[state_count]) { - /* LOG_INFO("2"); */ - usbprog_write(0, 1, 0); - usbprog_write(1, 1, 0); - } else { - LOG_ERROR("BUG: %s -> %s isn't a valid TAP transition", - tap_state_name(tap_get_state()), - tap_state_name(cmd->path[state_count])); - exit(-1); - } - - tap_set_state(cmd->path[state_count]); - state_count++; - num_states--; - } - - tap_set_end_state(tap_get_state()); -} - -static void usbprog_runtest(int num_cycles) -{ - int i; - - /* only do a state_move when we're not already in IDLE */ - if (tap_get_state() != TAP_IDLE) { - usbprog_end_state(TAP_IDLE); - usbprog_state_move(); - } - - /* execute num_cycles */ - if (num_cycles > 0) { - usbprog_jtag_tms_send(usbprog_jtag_handle); - usbprog_write(0, 0, 0); - } else { - usbprog_jtag_tms_send(usbprog_jtag_handle); - /* LOG_INFO("NUM CYCLES %i",num_cycles); */ - } - - for (i = 0; i < num_cycles; i++) { - usbprog_write(1, 0, 0); - usbprog_write(0, 0, 0); - } - -#ifdef _DEBUG_JTAG_IO_ - LOG_DEBUG("runtest: cur_state %s end_state %s", tap_state_name( - tap_get_state()), tap_state_name(tap_get_end_state())); -#endif - - /* finish in end_state */ - /* - usbprog_end_state(saved_end_state); - if (tap_get_state() != tap_get_end_state()) - usbprog_state_move(); - */ -} - -static void usbprog_scan(bool ir_scan, enum scan_type type, uint8_t *buffer, int scan_size) -{ - tap_state_t saved_end_state = tap_get_end_state(); - - if (ir_scan) - usbprog_end_state(TAP_IRSHIFT); - else - usbprog_end_state(TAP_DRSHIFT); - - /* Only move if we're not already there */ - if (tap_get_state() != tap_get_end_state()) - usbprog_state_move(); - - usbprog_end_state(saved_end_state); - - usbprog_jtag_tms_send(usbprog_jtag_handle); - - void (*f)(struct usbprog_jtag *usbprog_jtag, char *buffer_local, int size); - switch (type) { - case SCAN_OUT: - f = &usbprog_jtag_write_tdi; - break; - case SCAN_IN: - f = &usbprog_jtag_read_tdo; - break; - case SCAN_IO: - f = &usbprog_jtag_write_and_read; - break; - default: - LOG_ERROR("unknown scan type: %i", type); - exit(-1); - } - f(usbprog_jtag_handle, (char *)buffer, scan_size); - - /* The adapter does the transition to PAUSE internally */ - if (ir_scan) - tap_set_state(TAP_IRPAUSE); - else - tap_set_state(TAP_DRPAUSE); - - if (tap_get_state() != tap_get_end_state()) - usbprog_state_move(); -} - -/*************** jtag wrapper functions *********************/ - -static void usbprog_write(int tck, int tms, int tdi) -{ - unsigned char output_value = 0x00; - - if (tms) - output_value |= (1 << TMS_BIT); - if (tdi) - output_value |= (1 << TDI_BIT); - if (tck) - output_value |= (1 << TCK_BIT); - - usbprog_jtag_write_slice(usbprog_jtag_handle, output_value); -} - -/* (1) assert or (0) deassert reset lines */ -static void usbprog_reset(int trst, int srst) -{ - LOG_DEBUG("trst: %i, srst: %i", trst, srst); - - if (trst) - usbprog_jtag_set_bit(usbprog_jtag_handle, 5, 0); - else - usbprog_jtag_set_bit(usbprog_jtag_handle, 5, 1); - - if (srst) - usbprog_jtag_set_bit(usbprog_jtag_handle, 4, 0); - else - usbprog_jtag_set_bit(usbprog_jtag_handle, 4, 1); -} - -/*************** jtag lowlevel functions ********************/ - -struct usb_bus *busses; - -struct usbprog_jtag *usbprog_jtag_open(void) -{ - usb_set_debug(10); - usb_init(); - - const uint16_t vids[] = { VID, 0 }; - const uint16_t pids[] = { PID, 0 }; - struct usb_dev_handle *dev; - if (jtag_usb_open(vids, pids, &dev) != ERROR_OK) - return NULL; - - struct usbprog_jtag *tmp = malloc(sizeof(struct usbprog_jtag)); - tmp->usb_handle = dev; - - usb_set_configuration(dev, 1); - usb_claim_interface(dev, 0); - usb_set_altinterface(dev, 0); - - return tmp; -} - -#if 0 -static void usbprog_jtag_close(struct usbprog_jtag *usbprog_jtag) -{ - usb_close(usbprog_jtag->usb_handle); - free(usbprog_jtag); -} -#endif - -static unsigned char usbprog_jtag_message(struct usbprog_jtag *usbprog_jtag, char *msg, int msglen) -{ - int res = usb_bulk_write(usbprog_jtag->usb_handle, 3, msg, msglen, 100); - if ((msg[0] == 2) || (msg[0] == 1) || (msg[0] == 4) || (msg[0] == 0) || \ - (msg[0] == 6) || (msg[0] == 0x0A) || (msg[0] == 9)) - return 1; - if (res == msglen) { - /* LOG_INFO("HALLLLOOO %i",(int)msg[0]); */ - res = usb_bulk_read(usbprog_jtag->usb_handle, 0x82, msg, 2, 100); - if (res > 0) - return (unsigned char)msg[1]; - else - return -1; - } else - return -1; - return 0; -} - -static void usbprog_jtag_init(struct usbprog_jtag *usbprog_jtag) -{ - usbprog_jtag_set_direction(usbprog_jtag, 0xFE); -} - -static void usbprog_jtag_write_and_read(struct usbprog_jtag *usbprog_jtag, char *buffer, int size) -{ - char tmp[64]; /* fastes packet size for usb controller */ - int send_bits, bufindex = 0, fillindex = 0, i, loops; - - char swap; - /* 61 byte can be transfered (488 bit) */ - - while (size > 0) { - if (size > 488) { - send_bits = 488; - size = size - 488; - loops = 61; - } else { - send_bits = size; - loops = size / 8; - loops++; - size = 0; - } - tmp[0] = WRITE_AND_READ; - tmp[1] = (char)(send_bits >> 8); /* high */ - tmp[2] = (char)(send_bits); /* low */ - - for (i = 0; i < loops; i++) { - tmp[3 + i] = buffer[bufindex]; - bufindex++; - } - - if (usb_bulk_write(usbprog_jtag->usb_handle, 3, tmp, 64, 1000) == 64) { - /* LOG_INFO("HALLLLOOO2 %i",(int)tmp[0]); */ - usleep(1); - int timeout = 0; - while (usb_bulk_read(usbprog_jtag->usb_handle, 0x82, tmp, 64, 1000) < 1) { - timeout++; - if (timeout > 10) - break; - } - - for (i = 0; i < loops; i++) { - swap = tmp[3 + i]; - buffer[fillindex++] = swap; - } - } - } -} - -static void usbprog_jtag_read_tdo(struct usbprog_jtag *usbprog_jtag, char *buffer, int size) -{ - char tmp[64]; /* fastes packet size for usb controller */ - int send_bits, fillindex = 0, i, loops; - - char swap; - /* 61 byte can be transfered (488 bit) */ - - while (size > 0) { - if (size > 488) { - send_bits = 488; - size = size - 488; - loops = 61; - } else { - send_bits = size; - loops = size / 8; - loops++; - size = 0; - } - tmp[0] = WRITE_AND_READ; - tmp[1] = (char)(send_bits >> 8); /* high */ - tmp[2] = (char)(send_bits); /* low */ - - usb_bulk_write(usbprog_jtag->usb_handle, 3, tmp, 3, 1000); - - /* LOG_INFO("HALLLLOOO3 %i",(int)tmp[0]); */ - int timeout = 0; - usleep(1); - while (usb_bulk_read(usbprog_jtag->usb_handle, 0x82, tmp, 64, 10) < 1) { - timeout++; - if (timeout > 10) - break; - } - - for (i = 0; i < loops; i++) { - swap = tmp[3 + i]; - buffer[fillindex++] = swap; - } - } -} - -static void usbprog_jtag_write_tdi(struct usbprog_jtag *usbprog_jtag, char *buffer, int size) -{ - char tmp[64]; /* fastes packet size for usb controller */ - int send_bits, bufindex = 0, i, loops; - - /* 61 byte can be transfered (488 bit) */ - while (size > 0) { - if (size > 488) { - send_bits = 488; - size = size - 488; - loops = 61; - } else { - send_bits = size; - loops = size/8; - /* if (loops == 0) */ - loops++; - size = 0; - } - tmp[0] = WRITE_TDI; - tmp[1] = (char)(send_bits >> 8); /* high */ - tmp[2] = (char)(send_bits); /* low */ - - for (i = 0; i < loops; i++) { - tmp[3 + i] = buffer[bufindex]; - bufindex++; - } - usb_bulk_write(usbprog_jtag->usb_handle, 3, tmp, 64, 1000); - } -} - -static void usbprog_jtag_write_tms(struct usbprog_jtag *usbprog_jtag, char tms_scan) -{ - usbprog_jtag_tms_collect(tms_scan); -} - -static void usbprog_jtag_set_direction(struct usbprog_jtag *usbprog_jtag, unsigned char direction) -{ - char tmp[2]; - tmp[0] = PORT_DIRECTION; - tmp[1] = (char)direction; - usbprog_jtag_message(usbprog_jtag, tmp, 2); -} - -static void usbprog_jtag_write_slice(struct usbprog_jtag *usbprog_jtag, unsigned char value) -{ - char tmp[2]; - tmp[0] = PORT_SET; - tmp[1] = (char)value; - usbprog_jtag_message(usbprog_jtag, tmp, 2); -} - -#if 0 -static unsigned char usbprog_jtag_get_port(struct usbprog_jtag *usbprog_jtag) -{ - char tmp[2]; - tmp[0] = PORT_GET; - tmp[1] = 0x00; - return usbprog_jtag_message(usbprog_jtag, tmp, 2); -} -#endif - -static void usbprog_jtag_set_bit(struct usbprog_jtag *usbprog_jtag, int bit, int value) -{ - char tmp[3]; - tmp[0] = PORT_SETBIT; - tmp[1] = (char)bit; - if (value == 1) - tmp[2] = 0x01; - else - tmp[2] = 0x00; - usbprog_jtag_message(usbprog_jtag, tmp, 3); -} - -#if 0 -static int usbprog_jtag_get_bit(struct usbprog_jtag *usbprog_jtag, int bit) -{ - char tmp[2]; - tmp[0] = PORT_GETBIT; - tmp[1] = (char)bit; - - if (usbprog_jtag_message(usbprog_jtag, tmp, 2) > 0) - return 1; - else - return 0; -} -#endif - -static void usbprog_jtag_tms_collect(char tms_scan) -{ - tms_chain[tms_chain_index] = tms_scan; - tms_chain_index++; -} - -static void usbprog_jtag_tms_send(struct usbprog_jtag *usbprog_jtag) -{ - int i; - /* LOG_INFO("TMS SEND"); */ - if (tms_chain_index > 0) { - char tmp[tms_chain_index + 2]; - tmp[0] = WRITE_TMS_CHAIN; - tmp[1] = (char)(tms_chain_index); - for (i = 0; i < tms_chain_index + 1; i++) - tmp[2 + i] = tms_chain[i]; - usb_bulk_write(usbprog_jtag->usb_handle, 3, tmp, tms_chain_index + 2, 1000); - tms_chain_index = 0; - } -} - -struct jtag_interface usbprog_interface = { - .name = "usbprog", - - .execute_queue = usbprog_execute_queue, - .init = usbprog_init, - .quit = usbprog_quit -}; diff --git a/src/jtag/drivers/versaloon/usbtoxxx/usbtogpio.c b/src/jtag/drivers/versaloon/usbtoxxx/usbtogpio.c deleted file mode 100644 index 0d60725a6..000000000 --- a/src/jtag/drivers/versaloon/usbtoxxx/usbtogpio.c +++ /dev/null @@ -1,95 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2009 - 2010 by Simon Qian * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 -#include "config.h" -#endif - -#include - -#include "../versaloon_include.h" -#include "../versaloon.h" -#include "../versaloon_internal.h" -#include "usbtoxxx.h" -#include "usbtoxxx_internal.h" - -RESULT usbtogpio_init(uint8_t interface_index) -{ - return usbtoxxx_init_command(USB_TO_GPIO, interface_index); -} - -RESULT usbtogpio_fini(uint8_t interface_index) -{ - return usbtoxxx_fini_command(USB_TO_GPIO, interface_index); -} - -RESULT usbtogpio_config(uint8_t interface_index, uint32_t mask, - uint32_t dir_mask, uint32_t pull_en_mask, - uint32_t input_pull_mask) -{ - uint8_t conf[8]; - -#if PARAM_CHECK - if (interface_index > 7) { - LOG_BUG(ERRMSG_INVALID_INTERFACE_NUM, interface_index); - return ERROR_FAIL; - } -#endif - - dir_mask &= mask; - SET_LE_U16(&conf[0], mask); - SET_LE_U16(&conf[2], dir_mask); - SET_LE_U16(&conf[4], pull_en_mask); - SET_LE_U16(&conf[6], input_pull_mask); - - return usbtoxxx_conf_command(USB_TO_GPIO, interface_index, conf, - sizeof(conf)); -} - -RESULT usbtogpio_in(uint8_t interface_index, uint32_t mask, uint32_t *value) -{ - uint8_t buf[2]; - -#if PARAM_CHECK - if (interface_index > 7) { - LOG_BUG(ERRMSG_INVALID_INTERFACE_NUM, interface_index); - return ERROR_FAIL; - } -#endif - - SET_LE_U16(&buf[0], mask); - - return usbtoxxx_in_command(USB_TO_GPIO, interface_index, buf, 2, 2, - (uint8_t *)value, 0, 2, 0); -} - -RESULT usbtogpio_out(uint8_t interface_index, uint32_t mask, uint32_t value) -{ - uint8_t buf[4]; - -#if PARAM_CHECK - if (interface_index > 7) { - LOG_BUG(ERRMSG_INVALID_INTERFACE_NUM, interface_index); - return ERROR_FAIL; - } -#endif - - SET_LE_U16(&buf[0], mask); - SET_LE_U16(&buf[2], value); - - return usbtoxxx_out_command(USB_TO_GPIO, interface_index, buf, 4, 0); -} diff --git a/src/jtag/drivers/versaloon/usbtoxxx/usbtojtagraw.c b/src/jtag/drivers/versaloon/usbtoxxx/usbtojtagraw.c deleted file mode 100644 index f2ea175ad..000000000 --- a/src/jtag/drivers/versaloon/usbtoxxx/usbtojtagraw.c +++ /dev/null @@ -1,78 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2009 - 2010 by Simon Qian * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 -#include "config.h" -#endif - -#include - -#include "../versaloon_include.h" -#include "../versaloon.h" -#include "../versaloon_internal.h" -#include "usbtoxxx.h" -#include "usbtoxxx_internal.h" - -RESULT usbtojtagraw_init(uint8_t interface_index) -{ - return usbtoxxx_init_command(USB_TO_JTAG_RAW, interface_index); -} - -RESULT usbtojtagraw_fini(uint8_t interface_index) -{ - return usbtoxxx_fini_command(USB_TO_JTAG_RAW, interface_index); -} - -RESULT usbtojtagraw_config(uint8_t interface_index, uint32_t kHz) -{ - uint8_t cfg_buf[4]; - -#if PARAM_CHECK - if (interface_index > 7) { - LOG_BUG(ERRMSG_INVALID_INTERFACE_NUM, interface_index); - return ERROR_FAIL; - } -#endif - - SET_LE_U32(&cfg_buf[0], kHz); - - return usbtoxxx_conf_command(USB_TO_JTAG_RAW, interface_index, cfg_buf, 4); -} - -RESULT usbtojtagraw_execute(uint8_t interface_index, uint8_t *tdi, - uint8_t *tms, uint8_t *tdo, uint32_t bitlen) -{ - uint16_t bytelen; - -#if PARAM_CHECK - if (interface_index > 7) { - LOG_BUG(ERRMSG_INVALID_INTERFACE_NUM, interface_index); - return ERROR_FAIL; - } -#endif - - if (bitlen > 8 * 0xFFFF) - return ERROR_FAIL; - bytelen = (uint16_t)((bitlen + 7) >> 3); - - SET_LE_U32(&versaloon_cmd_buf[0], bitlen); - memcpy(versaloon_cmd_buf + 4, tdi, bytelen); - memcpy(versaloon_cmd_buf + 4 + bytelen, tms, bytelen); - - return usbtoxxx_inout_command(USB_TO_JTAG_RAW, interface_index, - versaloon_cmd_buf, 4 + bytelen * 2, bytelen, tdo, 0, bytelen, 0); -} diff --git a/src/jtag/drivers/versaloon/usbtoxxx/usbtopwr.c b/src/jtag/drivers/versaloon/usbtoxxx/usbtopwr.c deleted file mode 100644 index 16433aff5..000000000 --- a/src/jtag/drivers/versaloon/usbtoxxx/usbtopwr.c +++ /dev/null @@ -1,63 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2009 - 2010 by Simon Qian * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 -#include "config.h" -#endif - -#include - -#include "../versaloon_include.h" -#include "../versaloon.h" -#include "../versaloon_internal.h" -#include "usbtoxxx.h" -#include "usbtoxxx_internal.h" - -RESULT usbtopwr_init(uint8_t interface_index) -{ - return usbtoxxx_init_command(USB_TO_POWER, interface_index); -} - -RESULT usbtopwr_fini(uint8_t interface_index) -{ - return usbtoxxx_fini_command(USB_TO_POWER, interface_index); -} - -RESULT usbtopwr_config(uint8_t interface_index) -{ -#if PARAM_CHECK - if (interface_index > 7) { - LOG_BUG(ERRMSG_INVALID_INTERFACE_NUM, interface_index); - return ERROR_FAIL; - } -#endif - - return usbtoxxx_conf_command(USB_TO_POWER, interface_index, NULL, 0); -} - -RESULT usbtopwr_output(uint8_t interface_index, uint16_t mV) -{ -#if PARAM_CHECK - if (interface_index > 7) { - LOG_BUG(ERRMSG_INVALID_INTERFACE_NUM, interface_index); - return ERROR_FAIL; - } -#endif - - return usbtoxxx_out_command(USB_TO_POWER, interface_index, (uint8_t *)&mV, - 2, 0); -} diff --git a/src/jtag/drivers/versaloon/usbtoxxx/usbtoswd.c b/src/jtag/drivers/versaloon/usbtoxxx/usbtoswd.c deleted file mode 100644 index ef1b675f7..000000000 --- a/src/jtag/drivers/versaloon/usbtoxxx/usbtoswd.c +++ /dev/null @@ -1,156 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2009 - 2010 by Simon Qian * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 -#include "config.h" -#endif - -#include -#include - -#include "../versaloon_include.h" -#include "../versaloon.h" -#include "../versaloon_internal.h" -#include "usbtoxxx.h" -#include "usbtoxxx_internal.h" - -RESULT usbtoswd_read_callback(void *p, uint8_t *src, uint8_t *processed) -{ - struct versaloon_pending_t *pending = (struct versaloon_pending_t *)p; - - if (pending->extra_data != NULL) - *((uint8_t *)pending->extra_data) = src[0]; - - return ERROR_OK; -} - -RESULT usbtoswd_write_callback(void *p, uint8_t *src, uint8_t *processed) -{ - struct versaloon_pending_t *pending = (struct versaloon_pending_t *)p; - - if (pending->extra_data != NULL) - *((uint8_t *)pending->extra_data) = src[0]; - - /* mark it processed to ignore other input data */ - *processed = 1; - return ERROR_OK; -} - -RESULT usbtoswd_init(uint8_t interface_index) -{ - return usbtoxxx_init_command(USB_TO_SWD, interface_index); -} - -RESULT usbtoswd_fini(uint8_t interface_index) -{ - return usbtoxxx_fini_command(USB_TO_SWD, interface_index); -} - -RESULT usbtoswd_config(uint8_t interface_index, uint8_t trn, uint16_t retry, - uint16_t dly) -{ - uint8_t cfg_buf[5]; - -#if PARAM_CHECK - if (interface_index > 7) { - LOG_BUG(ERRMSG_INVALID_INTERFACE_NUM, interface_index); - return ERROR_FAIL; - } -#endif - - cfg_buf[0] = trn; - SET_LE_U16(&cfg_buf[1], retry); - SET_LE_U16(&cfg_buf[3], dly); - - return usbtoxxx_conf_command(USB_TO_SWD, interface_index, cfg_buf, 5); -} - -RESULT usbtoswd_seqout(uint8_t interface_index, const uint8_t *data, - uint16_t bitlen) -{ - uint16_t bytelen = (bitlen + 7) >> 3; - -#if PARAM_CHECK - if (interface_index > 7) { - LOG_BUG(ERRMSG_INVALID_INTERFACE_NUM, interface_index); - return ERROR_FAIL; - } -#endif - - SET_LE_U16(&versaloon_cmd_buf[0], bitlen); - memcpy(versaloon_cmd_buf + 2, data, bytelen); - - return usbtoxxx_out_command(USB_TO_SWD, interface_index, - versaloon_cmd_buf, bytelen + 2, 0); -} - -RESULT usbtoswd_seqin(uint8_t interface_index, uint8_t *data, uint16_t bitlen) -{ - uint16_t bytelen = (bitlen + 7) >> 3; - uint8_t buff[2]; - -#if PARAM_CHECK - if (interface_index > 7) { - LOG_BUG(ERRMSG_INVALID_INTERFACE_NUM, interface_index); - return ERROR_FAIL; - } -#endif - - SET_LE_U16(&buff[0], bitlen); - - return usbtoxxx_in_command(USB_TO_SWD, interface_index, buff, 2, bytelen, - data, 0, bytelen, 0); -} - -RESULT usbtoswd_transact(uint8_t interface_index, uint8_t request, - uint32_t *data, uint8_t *ack) -{ - uint8_t parity; - uint8_t buff[5]; - -#if PARAM_CHECK - if (interface_index > 7) { - LOG_BUG(ERRMSG_INVALID_INTERFACE_NUM, interface_index); - return ERROR_FAIL; - } -#endif - - parity = (request >> 1) & 1; - parity += (request >> 2) & 1; - parity += (request >> 3) & 1; - parity += (request >> 4) & 1; - parity &= 1; - buff[0] = (request | 0x81 | (parity << 5)) & ~0x40; - if (data != NULL) - SET_LE_U32(&buff[1], *data); - else - memset(buff + 1, 0, 4); - - versaloon_set_extra_data(ack); - if (request & 0x04) { - /* read */ - versaloon_set_callback(usbtoswd_read_callback); - } else { - /* write */ - versaloon_set_callback(usbtoswd_write_callback); - } - - /* Input buffer must be passed even for write operations. Otherwise - * the callback function is not called and ack value is not set. */ - return usbtoxxx_inout_command(USB_TO_SWD, interface_index, buff, 5, 5, - (uint8_t *)data, 1, 4, 0); -} diff --git a/src/jtag/drivers/versaloon/usbtoxxx/usbtoxxx.c b/src/jtag/drivers/versaloon/usbtoxxx/usbtoxxx.c deleted file mode 100644 index 53a7e989b..000000000 --- a/src/jtag/drivers/versaloon/usbtoxxx/usbtoxxx.c +++ /dev/null @@ -1,553 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2009 - 2010 by Simon Qian * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 -#include "config.h" -#endif - -#include - -#include "../versaloon_include.h" -#include "../versaloon.h" -#include "../versaloon_internal.h" -#include "usbtoxxx.h" -#include "usbtoxxx_internal.h" - -#define N_A "n/a" - -const char *types_name[96] = { - "usbtousart", "usbtospi", "usbtoi2c", "usbtogpio", "usbtocan", "usbtopwm", - "usbtoadc", "usbtodac", - "usbtomicrowire", "usbtoswim", "usbtodusi", N_A, N_A, N_A, "usbtopower", "usbtodelay", - N_A, N_A, N_A, N_A, N_A, N_A, N_A, N_A, N_A, - N_A, N_A, N_A, N_A, N_A, N_A, N_A, - "usbtojtagll", "usbtojtaghl", "usbtoissp", "usbtoc2", "usbtosbw", - "usbtolpcicp", "usbtoswd", "usbtojtagraw", - "usbtobdm", N_A, N_A, N_A, N_A, N_A, N_A, N_A, - N_A, N_A, N_A, N_A, N_A, N_A, N_A, N_A, - "usbtomsp430jtag", N_A, N_A, N_A, N_A, N_A, N_A, N_A, - "usbtopower", "usbtodelay", "usbtopoll", N_A, N_A, N_A, N_A, N_A, - N_A, N_A, N_A, N_A, N_A, N_A, N_A, "usbtoall" -}; - -uint8_t usbtoxxx_abilities[USB_TO_XXX_ABILITIES_LEN]; - -#define usbtoxxx_get_type_name(type) \ - types_name[((type) - VERSALOON_USB_TO_XXX_CMD_START) \ - % (sizeof(types_name) / sizeof(types_name[0]))] - -static uint8_t type_pre; -static uint16_t usbtoxxx_buffer_index; -static uint16_t usbtoxxx_current_cmd_index; -static uint8_t *usbtoxxx_buffer; - -uint16_t collect_index; -uint8_t collect_cmd; -static uint8_t poll_nesting; - -struct usbtoxxx_context_t { - uint8_t type_pre; - uint8_t *usbtoxxx_buffer; - uint16_t usbtoxxx_current_cmd_index; - uint16_t usbtoxxx_buffer_index; - uint16_t versaloon_pending_idx; -}; -static struct usbtoxxx_context_t poll_context; - -static void usbtoxxx_save_context(struct usbtoxxx_context_t *c) -{ - c->type_pre = type_pre; - c->usbtoxxx_buffer = usbtoxxx_buffer; - c->usbtoxxx_buffer_index = usbtoxxx_buffer_index; - c->usbtoxxx_current_cmd_index = usbtoxxx_current_cmd_index; - c->versaloon_pending_idx = versaloon_pending_idx; -} - -static void usbtoxxx_pop_context(struct usbtoxxx_context_t *c) -{ - type_pre = c->type_pre; - usbtoxxx_buffer = c->usbtoxxx_buffer; - usbtoxxx_buffer_index = c->usbtoxxx_buffer_index; - usbtoxxx_current_cmd_index = c->usbtoxxx_current_cmd_index; - versaloon_pending_idx = c->versaloon_pending_idx; -} - -RESULT usbtoxxx_validate_current_command_type(void) -{ - if (type_pre > 0) { - /* not the first command */ - if (NULL == usbtoxxx_buffer) { - LOG_BUG(ERRMSG_INVALID_BUFFER, TO_STR(usbtoxxx_buffer)); - return ERRCODE_INVALID_BUFFER; - } - - usbtoxxx_buffer[0] = type_pre; - SET_LE_U16(&usbtoxxx_buffer[1], usbtoxxx_current_cmd_index); - - usbtoxxx_buffer_index += usbtoxxx_current_cmd_index; - } else { - /* first command */ - usbtoxxx_buffer_index = 3; - } - - /* prepare for next command */ - usbtoxxx_current_cmd_index = 3; - usbtoxxx_buffer = versaloon_buf + usbtoxxx_buffer_index; - - collect_index = 0; - collect_cmd = 0; - - return ERROR_OK; -} - -RESULT usbtoxxx_execute_command(void) -{ - uint16_t i; - uint16_t inlen; - RESULT result = ERROR_OK; - - if (poll_nesting) { - LOG_BUG(ERRMSG_INVALID_USAGE, "USB_TO_POLL"); - versaloon_free_want_pos(); - return ERROR_FAIL; - } - - if (ERROR_OK != usbtoxxx_validate_current_command_type()) { - LOG_BUG(ERRMSG_FAILURE_OPERATION, "validate previous commands"); - versaloon_free_want_pos(); - return ERRCODE_FAILURE_OPERATION; - } - if (3 == usbtoxxx_buffer_index) { - versaloon_free_want_pos(); - return ERROR_OK; - } - - versaloon_buf[0] = USB_TO_ALL; - SET_LE_U16(&versaloon_buf[1], usbtoxxx_buffer_index); - - if (ERROR_OK != versaloon_send_command(usbtoxxx_buffer_index, &inlen)) { - versaloon_free_want_pos(); - return ERROR_FAIL; - } - - /* process return data */ - usbtoxxx_buffer_index = 0; - for (i = 0; i < versaloon_pending_idx; i++) { - /* check result */ - if ((0 == i) || !((versaloon_pending[i].collect) - && (versaloon_pending[i - 1].collect) - && (versaloon_pending[i].cmd - == versaloon_pending[i - 1].cmd))) { - if (USB_TO_XXX_CMD_NOT_SUPPORT - == versaloon_buf[usbtoxxx_buffer_index]) { - LOG_ERROR(ERRMSG_NOT_SUPPORT_BY, - usbtoxxx_get_type_name(versaloon_pending[i].type), - "current dongle"); - result = ERROR_FAIL; - break; - } else if (USB_TO_XXX_OK != versaloon_buf[usbtoxxx_buffer_index]) { - LOG_ERROR("%s command 0x%02x failed with 0x%02x", - usbtoxxx_get_type_name(versaloon_pending[i].type), - versaloon_pending[i].cmd, - versaloon_buf[usbtoxxx_buffer_index]); - result = ERROR_FAIL; - break; - } - usbtoxxx_buffer_index++; - } - - /* get result data */ - if (versaloon_pending[i].pos != NULL) { - uint8_t processed = 0; - - if (versaloon_pending[i].callback != NULL) { - versaloon_pending[i].callback(&versaloon_pending[i], - versaloon_buf + usbtoxxx_buffer_index, &processed); - } - if (!processed) { - struct versaloon_want_pos_t *tmp; - - tmp = versaloon_pending[i].pos; - while (tmp != NULL) { - if ((tmp->buff != NULL) && (tmp->size > 0)) { - memcpy(tmp->buff, - versaloon_buf + usbtoxxx_buffer_index - + tmp->offset, - tmp->size); - } - struct versaloon_want_pos_t *free_tmp; - free_tmp = tmp; - tmp = tmp->next; - free(free_tmp); - } - versaloon_pending[i].pos = NULL; - } - } else if ((versaloon_pending[i].want_data_size > 0) - && (versaloon_pending[i].data_buffer != NULL)) { - uint8_t processed = 0; - - if (versaloon_pending[i].callback != NULL) { - versaloon_pending[i].callback(&versaloon_pending[i], - versaloon_buf + usbtoxxx_buffer_index, &processed); - } - if (!processed) { - memcpy(versaloon_pending[i].data_buffer, - versaloon_buf + usbtoxxx_buffer_index - + versaloon_pending[i].want_data_pos, - versaloon_pending[i].want_data_size); - } - } - usbtoxxx_buffer_index += versaloon_pending[i].actual_data_size; - if (usbtoxxx_buffer_index > inlen) { - LOG_BUG("%s command 0x%02x process error", - usbtoxxx_get_type_name(versaloon_pending[i].type), - versaloon_pending[i].cmd); - result = ERROR_FAIL; - break; - } - } - - /* data is not the right size */ - if (inlen != usbtoxxx_buffer_index) { - LOG_ERROR(ERRMSG_INVALID_TARGET, "length of return data"); - result = ERROR_FAIL; - } - - if (versaloon_pending_idx > 0) - versaloon_pending_idx = 0; - else { - /* no receive data, avoid collision */ - sleep_ms(10); - } - - type_pre = 0; - collect_cmd = 0; - collect_index = 0; - versaloon_free_want_pos(); - return result; -} - -RESULT usbtoxxx_init(void) -{ - versaloon_pending_idx = 0; - - if ((ERROR_OK != usbtoinfo_get_abilities(usbtoxxx_abilities)) || - (ERROR_OK != usbtoxxx_execute_command())) - return ERROR_FAIL; - LOG_INFO("USB_TO_XXX abilities: 0x%08X:0x%08X:0x%08X", - GET_LE_U32(&usbtoxxx_abilities[0]), - GET_LE_U32(&usbtoxxx_abilities[4]), - GET_LE_U32(&usbtoxxx_abilities[8])); - return ERROR_OK; -} - -RESULT usbtoxxx_fini(void) -{ - usbtoxxx_buffer = NULL; - type_pre = 0; - return ERROR_OK; -} - -bool usbtoxxx_interface_supported(uint8_t cmd) -{ - if ((cmd < VERSALOON_USB_TO_XXX_CMD_START) || - (cmd > VERSALOON_USB_TO_XXX_CMD_END)) - return false; - - cmd -= VERSALOON_USB_TO_XXX_CMD_START; - return (usbtoxxx_abilities[cmd / 8] & (1 << (cmd % 8))) > 0; -} - -RESULT usbtoxxx_ensure_buffer_size(uint16_t cmdlen) -{ - /* check free space, commit if not enough */ - if (((usbtoxxx_buffer_index + usbtoxxx_current_cmd_index + cmdlen) - >= versaloon_buf_size) - || (versaloon_pending_idx >= VERSALOON_MAX_PENDING_NUMBER)) { - struct usbtoxxx_context_t context_tmp; - uint8_t poll_nesting_tmp = 0; - - memset(&context_tmp, 0, sizeof(context_tmp)); - if (poll_nesting) { - if (0 == poll_context.type_pre) { - LOG_BUG("USB_TO_POLL toooooo long"); - return ERROR_OK; - } - - usbtoxxx_save_context(&context_tmp); - usbtoxxx_pop_context(&poll_context); - poll_nesting_tmp = poll_nesting; - poll_nesting = 0; - } - - if (usbtoxxx_execute_command() != ERROR_OK) - return ERROR_FAIL; - - if (poll_nesting_tmp) { - uint16_t newlen, oldlen; - - newlen = context_tmp.versaloon_pending_idx - - poll_context.versaloon_pending_idx; - memcpy(&versaloon_pending[0], - &versaloon_pending[poll_context.versaloon_pending_idx], - sizeof(versaloon_pending[0]) * newlen); - context_tmp.versaloon_pending_idx = newlen; - oldlen = poll_context.usbtoxxx_buffer_index - + poll_context.usbtoxxx_current_cmd_index; - newlen = context_tmp.usbtoxxx_buffer_index - + context_tmp.usbtoxxx_current_cmd_index; - memcpy(versaloon_buf + 3, versaloon_buf + oldlen, newlen - oldlen); - oldlen -= 3; - context_tmp.usbtoxxx_buffer -= oldlen; - context_tmp.usbtoxxx_buffer_index -= oldlen; - usbtoxxx_pop_context(&context_tmp); - poll_nesting = poll_nesting_tmp; - } - } - return ERROR_OK; -} - -RESULT usbtoxxx_add_command(uint8_t type, uint8_t cmd, uint8_t *cmdbuf, - uint16_t cmdlen, uint16_t retlen, uint8_t *wantbuf, - uint16_t wantpos, uint16_t wantlen, uint8_t collect) -{ - uint16_t len_tmp; - - /* 3 more bytes by usbtoxxx_validate_current_command_type */ - /* 3 more bytes when ((0 == collect_index) || (collect_cmd != cmd)) */ - if (ERROR_OK != usbtoxxx_ensure_buffer_size(cmdlen + 6)) - return ERROR_FAIL; - - if ((type_pre != type) || (NULL == usbtoxxx_buffer)) { - if (ERROR_OK != usbtoxxx_validate_current_command_type()) { - LOG_BUG(ERRMSG_FAILURE_OPERATION, "validate previous commands"); - return ERRCODE_FAILURE_OPERATION; - } - type_pre = type; - } - - if ((0 == collect_index) || (collect_cmd != cmd)) { - usbtoxxx_buffer[usbtoxxx_current_cmd_index++] = cmd; - - if (collect) { - collect_index = usbtoxxx_current_cmd_index; - collect_cmd = cmd; - } else { - collect_index = 0; - collect_cmd = 0; - } - SET_LE_U16(&usbtoxxx_buffer[usbtoxxx_current_cmd_index], cmdlen); - usbtoxxx_current_cmd_index += 2; - } else { - len_tmp = GET_LE_U16(&usbtoxxx_buffer[collect_index]) + cmdlen; - SET_LE_U16(&usbtoxxx_buffer[collect_index], len_tmp); - } - - if (cmdbuf != NULL) { - memcpy(usbtoxxx_buffer + usbtoxxx_current_cmd_index, cmdbuf, cmdlen); - usbtoxxx_current_cmd_index += cmdlen; - } - - return versaloon_add_pending(type, cmd, retlen, wantpos, wantlen, - wantbuf, collect); -} - -RESULT usbtoinfo_get_abilities(uint8_t abilities[USB_TO_XXX_ABILITIES_LEN]) -{ - if (ERROR_OK != usbtoxxx_ensure_buffer_size(3)) - return ERROR_FAIL; - - if (ERROR_OK != usbtoxxx_validate_current_command_type()) { - LOG_BUG(ERRMSG_FAILURE_OPERATION, "validate previous commands"); - return ERRCODE_FAILURE_OPERATION; - } - type_pre = USB_TO_INFO; - - return versaloon_add_pending(USB_TO_INFO, 0, USB_TO_XXX_ABILITIES_LEN, 0, - USB_TO_XXX_ABILITIES_LEN, abilities, 0); -} - -RESULT usbtopoll_start(uint16_t retry_cnt, uint16_t interval_us) -{ - if (ERROR_OK != usbtoxxx_ensure_buffer_size(3 + 5)) - return ERROR_FAIL; - if (!poll_nesting) - usbtoxxx_save_context(&poll_context); - - if (ERROR_OK != usbtoxxx_validate_current_command_type()) { - LOG_BUG(ERRMSG_FAILURE_OPERATION, "validate previous commands"); - return ERRCODE_FAILURE_OPERATION; - } - poll_nesting++; - type_pre = USB_TO_POLL; - - usbtoxxx_buffer[usbtoxxx_current_cmd_index++] = USB_TO_POLL_START; - SET_LE_U16(&usbtoxxx_buffer[usbtoxxx_current_cmd_index], retry_cnt); - usbtoxxx_current_cmd_index += 2; - SET_LE_U16(&usbtoxxx_buffer[usbtoxxx_current_cmd_index], interval_us); - usbtoxxx_current_cmd_index += 2; - - return versaloon_add_pending(USB_TO_POLL, 0, 0, 0, 0, NULL, 0); -} - -RESULT usbtopoll_end(void) -{ - if (!poll_nesting) { - LOG_BUG(ERRMSG_FAILURE_OPERATION, "check poll nesting"); - return ERRCODE_FAILURE_OPERATION; - } - if (ERROR_OK != usbtoxxx_ensure_buffer_size(3 + 1)) - return ERROR_FAIL; - - if (ERROR_OK != usbtoxxx_validate_current_command_type()) { - LOG_BUG(ERRMSG_FAILURE_OPERATION, "validate previous commands"); - return ERRCODE_FAILURE_OPERATION; - } - - poll_nesting--; - type_pre = USB_TO_POLL; - - usbtoxxx_buffer[usbtoxxx_current_cmd_index++] = USB_TO_POLL_END; - - return versaloon_add_pending(USB_TO_POLL, 0, 0, 0, 0, NULL, 0); -} - -RESULT usbtopoll_checkok(uint8_t equ, uint16_t offset, uint8_t size, - uint32_t mask, uint32_t value) -{ - uint8_t i; - - if (size > 4) { - LOG_BUG(ERRMSG_INVALID_PARAMETER, __func__); - return ERRCODE_INVALID_PARAMETER; - } - if (!poll_nesting) { - LOG_BUG(ERRMSG_FAILURE_OPERATION, "check poll nesting"); - return ERRCODE_FAILURE_OPERATION; - } - if (ERROR_OK != usbtoxxx_ensure_buffer_size(3 + 4 + 2 * size)) - return ERROR_FAIL; - - if (ERROR_OK != usbtoxxx_validate_current_command_type()) { - LOG_BUG(ERRMSG_FAILURE_OPERATION, "validate previous commands"); - return ERRCODE_FAILURE_OPERATION; - } - - type_pre = USB_TO_POLL; - - usbtoxxx_buffer[usbtoxxx_current_cmd_index++] = USB_TO_POLL_CHECKOK; - SET_LE_U16(&usbtoxxx_buffer[usbtoxxx_current_cmd_index], offset); - usbtoxxx_current_cmd_index += 2; - usbtoxxx_buffer[usbtoxxx_current_cmd_index++] = size; - usbtoxxx_buffer[usbtoxxx_current_cmd_index++] = equ; - for (i = 0; i < size; i++) - usbtoxxx_buffer[usbtoxxx_current_cmd_index++] = (mask >> (8 * i)) & 0xFF; - for (i = 0; i < size; i++) - usbtoxxx_buffer[usbtoxxx_current_cmd_index++] = (value >> (8 * i)) & 0xFF; - - return ERROR_OK; -} - -RESULT usbtopoll_checkfail(uint8_t equ, uint16_t offset, uint8_t size, - uint32_t mask, uint32_t value) -{ - uint8_t i; - - if (size > 4) { - LOG_BUG(ERRMSG_INVALID_PARAMETER, __func__); - return ERRCODE_INVALID_PARAMETER; - } - if (!poll_nesting) { - LOG_BUG(ERRMSG_FAILURE_OPERATION, "check poll nesting"); - return ERRCODE_FAILURE_OPERATION; - } - if (ERROR_OK != usbtoxxx_ensure_buffer_size(3 + 4 + 2 * size)) - return ERROR_FAIL; - - if (ERROR_OK != usbtoxxx_validate_current_command_type()) { - LOG_BUG(ERRMSG_FAILURE_OPERATION, "validate previous commands"); - return ERRCODE_FAILURE_OPERATION; - } - - type_pre = USB_TO_POLL; - - usbtoxxx_buffer[usbtoxxx_current_cmd_index++] = USB_TO_POLL_CHECKFAIL; - SET_LE_U16(&usbtoxxx_buffer[usbtoxxx_current_cmd_index], offset); - usbtoxxx_current_cmd_index += 2; - usbtoxxx_buffer[usbtoxxx_current_cmd_index++] = size; - usbtoxxx_buffer[usbtoxxx_current_cmd_index++] = equ; - for (i = 0; i < size; i++) - usbtoxxx_buffer[usbtoxxx_current_cmd_index++] = (mask >> (8 * i)) & 0xFF; - for (i = 0; i < size; i++) - usbtoxxx_buffer[usbtoxxx_current_cmd_index++] = (value >> (8 * i)) & 0xFF; - - return ERROR_OK; -} - -RESULT usbtopoll_verifybuff(uint16_t offset, uint16_t size, uint8_t *buff) -{ - if (!poll_nesting) { - LOG_BUG(ERRMSG_FAILURE_OPERATION, "check poll nesting"); - return ERRCODE_FAILURE_OPERATION; - } - if (ERROR_OK != usbtoxxx_ensure_buffer_size(3 + 5 + size)) - return ERROR_FAIL; - - if (ERROR_OK != usbtoxxx_validate_current_command_type()) { - LOG_BUG(ERRMSG_FAILURE_OPERATION, "validate previous commands"); - return ERRCODE_FAILURE_OPERATION; - } - - type_pre = USB_TO_POLL; - - usbtoxxx_buffer[usbtoxxx_current_cmd_index++] = USB_TO_POLL_VERIFYBUFF; - SET_LE_U16(&usbtoxxx_buffer[usbtoxxx_current_cmd_index], offset); - usbtoxxx_current_cmd_index += 2; - SET_LE_U16(&usbtoxxx_buffer[usbtoxxx_current_cmd_index], size); - usbtoxxx_current_cmd_index += 2; - memcpy(&usbtoxxx_buffer[usbtoxxx_current_cmd_index], buff, size); - usbtoxxx_current_cmd_index += size; - - return ERROR_OK; -} - -RESULT usbtodelay_delay(uint16_t dly) -{ - if (ERROR_OK != usbtoxxx_ensure_buffer_size(3 + 2)) - return ERROR_FAIL; - - if (ERROR_OK != usbtoxxx_validate_current_command_type()) { - LOG_BUG(ERRMSG_FAILURE_OPERATION, "validate previous commands"); - return ERRCODE_FAILURE_OPERATION; - } - type_pre = USB_TO_DELAY; - - SET_LE_U16(&usbtoxxx_buffer[usbtoxxx_current_cmd_index], dly); - usbtoxxx_current_cmd_index += 2; - - return versaloon_add_pending(USB_TO_DELAY, 0, 0, 0, 0, NULL, 0); -} - -RESULT usbtodelay_delayms(uint16_t ms) -{ - return usbtodelay_delay(ms | 0x8000); -} - -RESULT usbtodelay_delayus(uint16_t us) -{ - return usbtodelay_delay(us & 0x7FFF); -} diff --git a/src/jtag/drivers/versaloon/usbtoxxx/usbtoxxx.h b/src/jtag/drivers/versaloon/usbtoxxx/usbtoxxx.h deleted file mode 100644 index 98a056a8b..000000000 --- a/src/jtag/drivers/versaloon/usbtoxxx/usbtoxxx.h +++ /dev/null @@ -1,237 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2009 - 2010 by Simon Qian * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 OPENOCD_JTAG_DRIVERS_VERSALOON_USBTOXXX_USBTOXXX_H -#define OPENOCD_JTAG_DRIVERS_VERSALOON_USBTOXXX_USBTOXXX_H - -RESULT usbtoxxx_init(void); -RESULT usbtoxxx_fini(void); -RESULT usbtoxxx_execute_command(void); - -#define USB_TO_XXX_ABILITIES_LEN 12 -extern uint8_t usbtoxxx_abilities[USB_TO_XXX_ABILITIES_LEN]; -bool usbtoxxx_interface_supported(uint8_t cmd); - -/* USB_TO_INFO */ -RESULT usbtoinfo_get_abilities(uint8_t abilities[USB_TO_XXX_ABILITIES_LEN]); - -/* USB_TO_DELAY */ -RESULT usbtodelay_delay(uint16_t dly); -RESULT usbtodelay_delayms(uint16_t ms); -RESULT usbtodelay_delayus(uint16_t us); - -/* USB_TO_USART */ -RESULT usbtousart_init(uint8_t interface_index); -RESULT usbtousart_fini(uint8_t interface_index); -RESULT usbtousart_config(uint8_t interface_index, uint32_t baudrate, - uint8_t datalength, uint8_t mode); -RESULT usbtousart_send(uint8_t interface_index, uint8_t *buf, uint16_t len); -RESULT usbtousart_receive(uint8_t interface_index, uint8_t *buf, uint16_t len); -RESULT usbtousart_status(uint8_t interface_index, - struct usart_status_t *status); - -/* USB_TO_SPI */ -RESULT usbtospi_init(uint8_t interface_index); -RESULT usbtospi_fini(uint8_t interface_index); -RESULT usbtospi_config(uint8_t interface_index, uint32_t kHz, uint8_t mode); -RESULT usbtospi_io(uint8_t interface_index, uint8_t *out, uint8_t *in, - uint16_t bytelen); - -/* USB_TO_GPIO */ -RESULT usbtogpio_init(uint8_t interface_index); -RESULT usbtogpio_fini(uint8_t interface_index); -RESULT usbtogpio_config(uint8_t interface_index, uint32_t mask, - uint32_t dir_mask, uint32_t pull_en_mask, - uint32_t input_pull_mask); -RESULT usbtogpio_in(uint8_t interface_index, uint32_t mask, uint32_t *value); -RESULT usbtogpio_out(uint8_t interface_index, uint32_t mask, uint32_t value); - -/* USB_TO_ISSP */ -RESULT usbtoissp_init(uint8_t interface_index); -RESULT usbtoissp_fini(uint8_t interface_index); -RESULT usbtoissp_enter_program_mode(uint8_t interface_index, uint8_t mode); -RESULT usbtoissp_leave_program_mode(uint8_t interface_index, uint8_t mode); -RESULT usbtoissp_wait_and_poll(uint8_t interface_index); -RESULT usbtoissp_vector(uint8_t interface_index, uint8_t operate, uint8_t addr, - uint8_t data, uint8_t *buf); - -/* USB_TO_LPCICP */ -RESULT usbtolpcicp_init(uint8_t interface_index); -RESULT usbtolpcicp_fini(uint8_t interface_index); -RESULT usbtolpcicp_config(uint8_t interface_index); -RESULT usbtolpcicp_enter_program_mode(uint8_t interface_index); -RESULT usbtolpcicp_in(uint8_t interface_index, uint8_t *buff, uint16_t len); -RESULT usbtolpcicp_out(uint8_t interface_index, uint8_t *buff, uint16_t len); -RESULT usbtolpcicp_poll_ready(uint8_t interface_index, uint8_t data, - uint8_t *ret, uint8_t setmask, uint8_t clearmask, uint16_t pollcnt); - -/* USB_TO_JTAG_LL */ -RESULT usbtojtagll_init(uint8_t interface_index); -RESULT usbtojtagll_fini(uint8_t interface_index); -RESULT usbtojtagll_config(uint8_t interface_index, uint32_t kHz); -RESULT usbtojtagll_tms(uint8_t interface_index, uint8_t *tms, uint8_t bytelen); -RESULT usbtojtagll_tms_clocks(uint8_t interface_index, uint32_t bytelen, - uint8_t tms); -RESULT usbtojtagll_scan(uint8_t interface_index, uint8_t *data, - uint16_t bitlen, uint8_t tms_before_valid, - uint8_t tms_before, uint8_t tms_after0, - uint8_t tms_after1); - -/* USB_TO_JTAG_HL */ -RESULT usbtojtaghl_init(uint8_t interface_index); -RESULT usbtojtaghl_fini(uint8_t interface_index); -RESULT usbtojtaghl_config(uint8_t interface_index, uint32_t kHz, uint8_t ub, - uint8_t ua, uint16_t bb, uint16_t ba); -RESULT usbtojtaghl_ir(uint8_t interface_index, uint8_t *ir, uint16_t bitlen, - uint8_t idle, uint8_t want_ret); -RESULT usbtojtaghl_dr(uint8_t interface_index, uint8_t *dr, uint16_t bitlen, - uint8_t idle, uint8_t want_ret); -RESULT usbtojtaghl_tms(uint8_t interface_index, uint8_t *tms, uint16_t bitlen); -RESULT usbtojtaghl_runtest(uint8_t interface_index, uint32_t cycles); -RESULT usbtojtaghl_register_callback(uint8_t index, jtag_callback_t send_callback, - jtag_callback_t receive_callback); - -/* USB_TO_JTAG_RAW */ -RESULT usbtojtagraw_init(uint8_t interface_index); -RESULT usbtojtagraw_fini(uint8_t interface_index); -RESULT usbtojtagraw_config(uint8_t interface_index, uint32_t kHz); -RESULT usbtojtagraw_execute(uint8_t interface_index, uint8_t *tdi, - uint8_t *tms, uint8_t *tdo, uint32_t bitlen); - -/* USB_TO_C2 */ -RESULT usbtoc2_init(uint8_t interface_index); -RESULT usbtoc2_fini(uint8_t interface_index); -RESULT usbtoc2_writeaddr(uint8_t interface_index, uint8_t addr); -RESULT usbtoc2_readaddr(uint8_t interface_index, uint8_t *data); -RESULT usbtoc2_writedata(uint8_t interface_index, uint8_t *buf, uint8_t len); -RESULT usbtoc2_readdata(uint8_t interface_index, uint8_t *buf, uint8_t len); - -/* USB_TO_I2C */ -RESULT usbtoi2c_init(uint8_t interface_index); -RESULT usbtoi2c_fini(uint8_t interface_index); -RESULT usbtoi2c_config(uint8_t interface_index, uint16_t kHz, - uint16_t byte_interval, uint16_t max_dly); -RESULT usbtoi2c_read(uint8_t interface_index, uint16_t chip_addr, - uint8_t *data, uint16_t data_len, uint8_t stop, - bool nacklast); -RESULT usbtoi2c_write(uint8_t interface_index, uint16_t chip_addr, - uint8_t *data, uint16_t data_len, uint8_t stop); - -/* USB_TO_MSP430_JTAG */ -RESULT usbtomsp430jtag_init(uint8_t interface_index); -RESULT usbtomsp430jtag_fini(uint8_t interface_index); -RESULT usbtomsp430jtag_config(uint8_t interface_index, uint8_t has_test); -RESULT usbtomsp430jtag_ir(uint8_t interface_index, uint8_t *ir, - uint8_t want_ret); -RESULT usbtomsp430jtag_dr(uint8_t interface_index, uint32_t *dr, - uint8_t bitlen, uint8_t want_ret); -RESULT usbtomsp430jtag_tclk(uint8_t interface_index, uint8_t value); -RESULT usbtomsp430jtag_tclk_strobe(uint8_t interface_index, uint16_t cnt); -RESULT usbtomsp430jtag_reset(uint8_t interface_index); -RESULT usbtomsp430jtag_poll(uint8_t interface_index, uint32_t dr, - uint32_t mask, uint32_t value, uint8_t len, - uint16_t poll_cnt, uint8_t toggle_tclk); - -/* USB_TO_MSP430_SBW */ -RESULT usbtomsp430sbw_init(uint8_t interface_index); -RESULT usbtomsp430sbw_fini(uint8_t interface_index); -RESULT usbtomsp430sbw_config(uint8_t interface_index, uint8_t has_test); -RESULT usbtomsp430sbw_ir(uint8_t interface_index, uint8_t *ir, - uint8_t want_ret); -RESULT usbtomsp430sbw_dr(uint8_t interface_index, uint32_t *dr, - uint8_t bitlen, uint8_t want_ret); -RESULT usbtomsp430sbw_tclk(uint8_t interface_index, uint8_t value); -RESULT usbtomsp430sbw_tclk_strobe(uint8_t interface_index, uint16_t cnt); -RESULT usbtomsp430sbw_reset(uint8_t interface_index); -RESULT usbtomsp430sbw_poll(uint8_t interface_index, uint32_t dr, uint32_t mask, - uint32_t value, uint8_t len, uint16_t poll_cnt, - uint8_t toggle_tclk); - -/* USB_TO_POWER */ -RESULT usbtopwr_init(uint8_t interface_index); -RESULT usbtopwr_fini(uint8_t interface_index); -RESULT usbtopwr_config(uint8_t interface_index); -RESULT usbtopwr_output(uint8_t interface_index, uint16_t mV); - -/* USB_TO_POLL */ -RESULT usbtopoll_start(uint16_t retry_cnt, uint16_t interval_us); -RESULT usbtopoll_end(void); -RESULT usbtopoll_checkok(uint8_t equ, uint16_t offset, uint8_t size, - uint32_t mask, uint32_t value); -RESULT usbtopoll_checkfail(uint8_t equ, uint16_t offset, uint8_t size, - uint32_t mask, uint32_t value); -RESULT usbtopoll_verifybuff(uint16_t offset, uint16_t size, uint8_t *buff); - -/* USB_TO_SWD */ -RESULT usbtoswd_init(uint8_t interface_index); -RESULT usbtoswd_fini(uint8_t interface_index); -RESULT usbtoswd_config(uint8_t interface_index, uint8_t trn, uint16_t retry, - uint16_t dly); -RESULT usbtoswd_seqout(uint8_t interface_index, const uint8_t *data, - uint16_t bitlen); -RESULT usbtoswd_seqin(uint8_t interface_index, uint8_t *data, uint16_t bitlen); -RESULT usbtoswd_transact(uint8_t interface_index, uint8_t request, - uint32_t *data, uint8_t *ack); - -/* USB_TO_SWIM */ -RESULT usbtoswim_init(uint8_t interface_index); -RESULT usbtoswim_fini(uint8_t interface_index); -RESULT usbtoswim_config(uint8_t interface_index, uint8_t mHz, uint8_t cnt0, - uint8_t cnt1); -RESULT usbtoswim_srst(uint8_t interface_index); -RESULT usbtoswim_wotf(uint8_t interface_index, uint8_t *data, - uint16_t bytelen, uint32_t addr); -RESULT usbtoswim_rotf(uint8_t interface_index, uint8_t *data, - uint16_t bytelen, uint32_t addr); -RESULT usbtoswim_sync(uint8_t interface_index, uint8_t mHz); -RESULT usbtoswim_enable(uint8_t interface_index); - -/* USB_TO_BDM */ -RESULT usbtobdm_init(uint8_t interface_index); -RESULT usbtobdm_fini(uint8_t interface_index); -RESULT usbtobdm_sync(uint8_t interface_index, uint16_t *khz); -RESULT usbtobdm_transact(uint8_t interface_index, uint8_t *out, - uint8_t outlen, uint8_t *in, uint8_t inlen, uint8_t delay, uint8_t ack); - -/* USB_TO_DUSI */ -RESULT usbtodusi_init(uint8_t interface_index); -RESULT usbtodusi_fini(uint8_t interface_index); -RESULT usbtodusi_config(uint8_t interface_index, uint32_t kHz, uint8_t mode); -RESULT usbtodusi_io(uint8_t interface_index, uint8_t *mo, uint8_t *mi, - uint8_t *so, uint8_t *si, uint32_t bitlen); - -/* USB_TO_MICROWIRE */ -RESULT usbtomicrowire_init(uint8_t interface_index); -RESULT usbtomicrowire_fini(uint8_t interface_index); -RESULT usbtomicrowire_config(uint8_t interface_index, uint16_t kHz, - uint8_t sel_polarity); -RESULT usbtomicrowire_transport(uint8_t interface_index, - uint32_t opcode, uint8_t opcode_bitlen, - uint32_t addr, uint8_t addr_bitlen, - uint32_t data, uint8_t data_bitlen, - uint8_t *reply, uint8_t reply_bitlen); -RESULT usbtomicrowire_poll(uint8_t interface_index, uint16_t interval_us, - uint16_t retry_cnt); - -/* USB_TO_PWM */ -RESULT usbtopwm_init(uint8_t interface_index); -RESULT usbtopwm_fini(uint8_t interface_index); -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 /* 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 deleted file mode 100644 index e40667e91..000000000 --- a/src/jtag/drivers/versaloon/usbtoxxx/usbtoxxx_internal.h +++ /dev/null @@ -1,161 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2009 - 2010 by Simon Qian * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 OPENOCD_JTAG_DRIVERS_VERSALOON_USBTOXXX_USBTOXXX_INTERNAL_H -#define OPENOCD_JTAG_DRIVERS_VERSALOON_USBTOXXX_USBTOXXX_INTERNAL_H - -/* USB_TO_XXX USB Commands */ -/* Page0 */ -#define USB_TO_USART (VERSALOON_USB_TO_XXX_CMD_START + 0x00) -#define USB_TO_SPI (VERSALOON_USB_TO_XXX_CMD_START + 0x01) -#define USB_TO_I2C (VERSALOON_USB_TO_XXX_CMD_START + 0x02) -#define USB_TO_GPIO (VERSALOON_USB_TO_XXX_CMD_START + 0x03) -#define USB_TO_CAN (VERSALOON_USB_TO_XXX_CMD_START + 0x04) -#define USB_TO_PWM (VERSALOON_USB_TO_XXX_CMD_START + 0x05) -#define USB_TO_ADC (VERSALOON_USB_TO_XXX_CMD_START + 0x06) -#define USB_TO_DAC (VERSALOON_USB_TO_XXX_CMD_START + 0x07) -#define USB_TO_MICROWIRE (VERSALOON_USB_TO_XXX_CMD_START + 0x08) -#define USB_TO_SWIM (VERSALOON_USB_TO_XXX_CMD_START + 0x09) -#define USB_TO_DUSI (VERSALOON_USB_TO_XXX_CMD_START + 0x0A) -/* Page1 */ -#define USB_TO_JTAG_LL (VERSALOON_USB_TO_XXX_CMD_START + 0x20) -#define USB_TO_JTAG_HL (VERSALOON_USB_TO_XXX_CMD_START + 0x21) -#define USB_TO_ISSP (VERSALOON_USB_TO_XXX_CMD_START + 0x22) -#define USB_TO_C2 (VERSALOON_USB_TO_XXX_CMD_START + 0x23) -#define USB_TO_SBW (VERSALOON_USB_TO_XXX_CMD_START + 0x24) -#define USB_TO_LPCICP (VERSALOON_USB_TO_XXX_CMD_START + 0x25) -#define USB_TO_SWD (VERSALOON_USB_TO_XXX_CMD_START + 0x26) -#define USB_TO_JTAG_RAW (VERSALOON_USB_TO_XXX_CMD_START + 0x27) -#define USB_TO_BDM (VERSALOON_USB_TO_XXX_CMD_START + 0x28) -#define USB_TO_MSP430_JTAG (VERSALOON_USB_TO_XXX_CMD_START + 0x38) -/* Page2 */ -#define USB_TO_POWER (VERSALOON_USB_TO_XXX_CMD_START + 0x40) -#define USB_TO_DELAY (VERSALOON_USB_TO_XXX_CMD_START + 0x41) -#define USB_TO_POLL (VERSALOON_USB_TO_XXX_CMD_START + 0x42) -#define USB_TO_INFO (VERSALOON_USB_TO_XXX_CMD_START + 0x5E) -#define USB_TO_ALL (VERSALOON_USB_TO_XXX_CMD_START + 0x5F) - -/* USB_TO_XXX Masks */ -#define USB_TO_XXX_CMDMASK 0xF8 -#define USB_TO_XXX_CMDSHIFT 3 -#define USB_TO_XXX_IDXMASK 0x07 -/* USB_TO_XXX Sub Commands */ -/* Common Sub Commands */ -#define USB_TO_XXX_INIT (0x00 << USB_TO_XXX_CMDSHIFT) -#define USB_TO_XXX_FINI (0x01 << USB_TO_XXX_CMDSHIFT) -#define USB_TO_XXX_CONFIG (0x02 << USB_TO_XXX_CMDSHIFT) -#define USB_TO_XXX_GETHWINFO (0x03 << USB_TO_XXX_CMDSHIFT) -#define USB_TO_XXX_STATUS (0X04 << USB_TO_XXX_CMDSHIFT) -#define USB_TO_XXX_IN_OUT (0x05 << USB_TO_XXX_CMDSHIFT) -#define USB_TO_XXX_IN (0x06 << USB_TO_XXX_CMDSHIFT) -#define USB_TO_XXX_OUT (0x07 << USB_TO_XXX_CMDSHIFT) -#define USB_TO_XXX_POLL (0x08 << USB_TO_XXX_CMDSHIFT) -#define USB_TO_XXX_SPECIAL (0x09 << USB_TO_XXX_CMDSHIFT) -#define USB_TO_XXX_RESET (0x0A << USB_TO_XXX_CMDSHIFT) -#define USB_TO_XXX_SYNC (0x0B << USB_TO_XXX_CMDSHIFT) -#define USB_TO_XXX_ENABLE (0x0C << USB_TO_XXX_CMDSHIFT) -#define USB_TO_XXX_DISABLE (0x0D << USB_TO_XXX_CMDSHIFT) -/* USB_TO_POLL */ -#define USB_TO_POLL_START 0x00 -#define USB_TO_POLL_END 0x01 -#define USB_TO_POLL_CHECKOK 0x02 -#define USB_TO_POLL_CHECKFAIL 0x03 -#define USB_TO_POLL_VERIFYBUFF 0x04 - -/* USB_TO_XXX Replys */ -#define USB_TO_XXX_OK 0x00 -#define USB_TO_XXX_FAILED 0x01 -#define USB_TO_XXX_TIME_OUT 0x02 -#define USB_TO_XXX_INVALID_INDEX 0x03 -#define USB_TO_XXX_INVALID_PARA 0x04 -#define USB_TO_XXX_INVALID_CMD 0x05 -#define USB_TO_XXX_CMD_NOT_SUPPORT 0x06 - -/* USB_TO_XXX */ -RESULT usbtoxxx_add_pending(uint8_t type, uint8_t cmd, uint16_t - actual_szie, uint16_t want_pos, - uint16_t want_size, uint8_t *buffer); - -RESULT usbtoxxx_add_command(uint8_t type, uint8_t cmd, uint8_t *cmdbuf, - uint16_t cmdlen, uint16_t retlen, - uint8_t *wantbuf, uint16_t wantpos, - uint16_t wantlen, uint8_t collect); - -#define usbtoxxx_init_command(type, port) \ - usbtoxxx_add_command((type), (USB_TO_XXX_INIT | (port)), \ - NULL, 0, 0, NULL, 0, 0, 0) -#define usbtoxxx_fini_command(type, port) \ - usbtoxxx_add_command((type), (USB_TO_XXX_FINI | (port)), \ - NULL, 0, 0, NULL, 0, 0, 0) -#define usbtoxxx_conf_command(type, port, cmdbuf, cmdlen) \ - usbtoxxx_add_command((type), (USB_TO_XXX_CONFIG | (port)), \ - (cmdbuf), (cmdlen), 0, NULL, 0, 0, 0) -#define usbtoxxx_inout_command(type, port, cmdbuf, cmdlen, retlen, wantbuf, \ - wantpos, wantlen, c) \ - usbtoxxx_add_command((type), (USB_TO_XXX_IN_OUT | (port)), \ - (cmdbuf), (cmdlen), (retlen), (wantbuf), \ - (wantpos), (wantlen), (c)) -#define usbtoxxx_in_command(type, port, cmdbuf, cmdlen, retlen, wantbuf, \ - wantpos, wantlen, c) \ - usbtoxxx_add_command((type), (USB_TO_XXX_IN | (port)), (cmdbuf), \ - (cmdlen), (retlen), (wantbuf), (wantpos), \ - (wantlen), (c)) -#define usbtoxxx_out_command(type, port, cmdbuf, cmdlen, c) \ - usbtoxxx_add_command((type), (USB_TO_XXX_OUT | (port)), (cmdbuf), \ - (cmdlen), 0, NULL, 0, 0, (c)) -#define usbtoxxx_poll_command(type, port, cmdbuf, cmdlen, retbuf, retlen) \ - usbtoxxx_add_command((type), (USB_TO_XXX_POLL | (port)), (cmdbuf), \ - (cmdlen), (retlen), (retbuf), 0, (retlen), 0) -#define usbtoxxx_status_command(type, port, retlen, wantbuf, wantpos, wantlen, c) \ - usbtoxxx_add_command((type), (USB_TO_XXX_STATUS | (port)), \ - NULL, 0, (retlen), (wantbuf), (wantpos), \ - (wantlen), (c)) -#define usbtoxxx_special_command(type, port, cmdbuf, cmdlen, retlen, wantbuf, \ - wantpos, wantlen, c) \ - usbtoxxx_add_command((type), (USB_TO_XXX_SPECIAL | (port)), \ - (cmdbuf), (cmdlen), retlen, wantbuf, \ - wantpos, wantlen, (c)) -#define usbtoxxx_reset_command(type, port, cmdbuf, cmdlen) \ - usbtoxxx_add_command((type), (USB_TO_XXX_RESET | (port)), \ - (cmdbuf), (cmdlen), 0, NULL, 0, 0, 0) -#define usbtoxxx_sync_command(type, port, cmdbuf, cmdlen, retlen, wantbuf) \ - usbtoxxx_add_command((type), (USB_TO_XXX_SYNC | (port)), \ - (cmdbuf), (cmdlen), (retlen), (wantbuf), 0, \ - (retlen), 0) -#define usbtoxxx_enable_command(type, port, cmdbuf, cmdlen) \ - usbtoxxx_add_command((type), (USB_TO_XXX_ENABLE | (port)), \ - (cmdbuf), (cmdlen), 0, NULL, 0, 0, 0) -#define usbtoxxx_disable_command(type, port, cmdbuf, cmdlen) \ - usbtoxxx_add_command((type), (USB_TO_XXX_DISABLE | (port)), \ - (cmdbuf), (cmdlen), 0, NULL, 0, 0, 0) - -/* USB_TO_SPI */ -#define USB_TO_SPI_BAUDRATE_MSK 0x1F -#define USB_TO_SPI_CPOL_MSK 0x20 -#define USB_TO_SPI_CPHA_MSK 0x40 -#define USB_TO_SPI_MSB_FIRST 0x80 - -/* USB_TO_DUSI */ -#define USB_TO_DUSI_BAUDRATE_MSK 0x1F -#define USB_TO_DUSI_CPOL_MSK 0x20 -#define USB_TO_DUSI_CPHA_MSK 0x40 -#define USB_TO_DUSI_MSB_FIRST 0x80 - -/* USB_TO_GPIO */ -#define USB_TO_GPIO_DIR_MSK 0x01 - -#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 deleted file mode 100644 index 146383961..000000000 --- a/src/jtag/drivers/versaloon/versaloon.c +++ /dev/null @@ -1,359 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2009 - 2010 by Simon Qian * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 -#include "config.h" -#endif - -#include -#include -#include - -#include "versaloon_include.h" -#include "versaloon.h" -#include "versaloon_internal.h" -#include "usbtoxxx/usbtoxxx.h" - -uint8_t *versaloon_buf; -uint8_t *versaloon_cmd_buf; -uint16_t versaloon_buf_size; - -struct versaloon_pending_t versaloon_pending[VERSALOON_MAX_PENDING_NUMBER]; -uint16_t versaloon_pending_idx; - -libusb_device_handle *versaloon_usb_device_handle; -static uint32_t versaloon_usb_to = VERSALOON_TIMEOUT; - -RESULT versaloon_init(void); -RESULT versaloon_fini(void); -RESULT versaloon_get_target_voltage(uint16_t *voltage); -RESULT versaloon_set_target_voltage(uint16_t voltage); -RESULT versaloon_delay_ms(uint16_t ms); -RESULT versaloon_delay_us(uint16_t us); - -struct versaloon_interface_t versaloon_interface = { - .init = versaloon_init, - .fini = versaloon_fini, - { /* adaptors */ - { /* target_voltage */ - .get = versaloon_get_target_voltage, - .set = versaloon_set_target_voltage, - }, - { /* gpio */ - .init = usbtogpio_init, - .fini = usbtogpio_fini, - .config = usbtogpio_config, - .out = usbtogpio_out, - .in = usbtogpio_in, - }, - { /* delay */ - .delayms = versaloon_delay_ms, - .delayus = versaloon_delay_us, - }, - { /* swd */ - .init = usbtoswd_init, - .fini = usbtoswd_fini, - .config = usbtoswd_config, - .seqout = usbtoswd_seqout, - .seqin = usbtoswd_seqin, - .transact = usbtoswd_transact, - }, - { /* jtag_raw */ - .init = usbtojtagraw_init, - .fini = usbtojtagraw_fini, - .config = usbtojtagraw_config, - .execute = usbtojtagraw_execute, - }, - .peripheral_commit = usbtoxxx_execute_command, - }, - { /* usb_setting */ - .vid = VERSALOON_VID, - .pid = VERSALOON_PID, - .ep_out = VERSALOON_OUTP, - .ep_in = VERSALOON_INP, - .interface = VERSALOON_IFACE, - .serialstring = NULL, - .buf_size = 256, - } -}; - -/* programmer_cmd */ -static uint32_t versaloon_pending_id; -static versaloon_callback_t versaloon_callback; -static void *versaloon_extra_data; -static struct versaloon_want_pos_t *versaloon_want_pos; - -void versaloon_set_pending_id(uint32_t id) -{ - versaloon_pending_id = id; -} -void versaloon_set_callback(versaloon_callback_t callback) -{ - versaloon_callback = callback; -} -void versaloon_set_extra_data(void *p) -{ - versaloon_extra_data = p; -} - -void versaloon_free_want_pos(void) -{ - uint16_t i; - struct versaloon_want_pos_t *tmp, *free_tmp; - - tmp = versaloon_want_pos; - while (tmp != NULL) { - free_tmp = tmp; - tmp = tmp->next; - free(free_tmp); - } - versaloon_want_pos = NULL; - - for (i = 0; i < dimof(versaloon_pending); i++) { - tmp = versaloon_pending[i].pos; - while (tmp != NULL) { - free_tmp = tmp; - tmp = tmp->next; - free(free_tmp); - } - versaloon_pending[i].pos = NULL; - } -} - -RESULT versaloon_add_want_pos(uint16_t offset, uint16_t size, uint8_t *buff) -{ - struct versaloon_want_pos_t *new_pos = NULL; - - new_pos = malloc(sizeof(*new_pos)); - if (NULL == new_pos) { - LOG_ERROR(ERRMSG_NOT_ENOUGH_MEMORY); - return ERRCODE_NOT_ENOUGH_MEMORY; - } - new_pos->offset = offset; - new_pos->size = size; - new_pos->buff = buff; - new_pos->next = NULL; - - if (NULL == versaloon_want_pos) - versaloon_want_pos = new_pos; - else { - struct versaloon_want_pos_t *tmp = versaloon_want_pos; - - while (tmp->next != NULL) - tmp = tmp->next; - tmp->next = new_pos; - } - - return ERROR_OK; -} - -RESULT versaloon_add_pending(uint8_t type, uint8_t cmd, uint16_t actual_szie, - uint16_t want_pos, uint16_t want_size, uint8_t *buffer, uint8_t collect) -{ -#if PARAM_CHECK - if (versaloon_pending_idx >= VERSALOON_MAX_PENDING_NUMBER) { - LOG_BUG(ERRMSG_INVALID_INDEX, versaloon_pending_idx, - "versaloon pending data"); - return ERROR_FAIL; - } -#endif - - versaloon_pending[versaloon_pending_idx].type = type; - versaloon_pending[versaloon_pending_idx].cmd = cmd; - versaloon_pending[versaloon_pending_idx].actual_data_size = actual_szie; - versaloon_pending[versaloon_pending_idx].want_data_pos = want_pos; - versaloon_pending[versaloon_pending_idx].want_data_size = want_size; - versaloon_pending[versaloon_pending_idx].data_buffer = buffer; - versaloon_pending[versaloon_pending_idx].collect = collect; - versaloon_pending[versaloon_pending_idx].id = versaloon_pending_id; - versaloon_pending_id = 0; - versaloon_pending[versaloon_pending_idx].extra_data = versaloon_extra_data; - versaloon_extra_data = NULL; - versaloon_pending[versaloon_pending_idx].callback = versaloon_callback; - versaloon_callback = NULL; - versaloon_pending[versaloon_pending_idx].pos = versaloon_want_pos; - versaloon_want_pos = NULL; - versaloon_pending_idx++; - - return ERROR_OK; -} - -RESULT versaloon_send_command(uint16_t out_len, uint16_t *inlen) -{ - int ret; - int transferred; - -#if PARAM_CHECK - if (NULL == versaloon_buf) { - LOG_BUG(ERRMSG_INVALID_BUFFER, TO_STR(versaloon_buf)); - return ERRCODE_INVALID_BUFFER; - } - if ((0 == out_len) || (out_len > versaloon_interface.usb_setting.buf_size)) { - LOG_BUG(ERRMSG_INVALID_PARAMETER, __func__); - return ERRCODE_INVALID_PARAMETER; - } -#endif - - ret = libusb_bulk_transfer(versaloon_usb_device_handle, - versaloon_interface.usb_setting.ep_out, - versaloon_buf, out_len, &transferred, versaloon_usb_to); - if (0 != ret || transferred != out_len) { - LOG_ERROR(ERRMSG_FAILURE_OPERATION, "send usb data"); - return ERRCODE_FAILURE_OPERATION; - } - - if (inlen != NULL) { - ret = libusb_bulk_transfer(versaloon_usb_device_handle, - versaloon_interface.usb_setting.ep_in, - versaloon_buf, versaloon_interface.usb_setting.buf_size, - &transferred, versaloon_usb_to); - if (0 == ret) { - *inlen = (uint16_t)transferred; - return ERROR_OK; - } else { - LOG_ERROR(ERRMSG_FAILURE_OPERATION, "receive usb data"); - return ERROR_FAIL; - } - } else - return ERROR_OK; -} - -#define VERSALOON_RETRY_CNT 10 -RESULT versaloon_init(void) -{ - uint16_t ret = 0; - uint8_t retry; - uint32_t timeout_tmp; - - /* malloc temporary buffer */ - versaloon_buf = malloc(versaloon_interface.usb_setting.buf_size); - if (NULL == versaloon_buf) { - LOG_ERROR(ERRMSG_NOT_ENOUGH_MEMORY); - return ERRCODE_NOT_ENOUGH_MEMORY; - } - - /* connect to versaloon */ - timeout_tmp = versaloon_usb_to; - /* not output error message when connectting */ - /* 100ms delay when connect */ - versaloon_usb_to = 100; - for (retry = 0; retry < VERSALOON_RETRY_CNT; retry++) { - versaloon_buf[0] = VERSALOON_GET_INFO; - if ((ERROR_OK == versaloon_send_command(1, &ret)) && (ret >= 3)) - break; - } - versaloon_usb_to = timeout_tmp; - if (VERSALOON_RETRY_CNT == retry) { - versaloon_fini(); - LOG_ERROR(ERRMSG_FAILURE_OPERATION, "communicate with versaloon"); - return ERRCODE_FAILURE_OPERATION; - } - - versaloon_buf[ret] = 0; - versaloon_buf_size = versaloon_buf[0] + (versaloon_buf[1] << 8); - versaloon_interface.usb_setting.buf_size = versaloon_buf_size; - LOG_INFO("%s", versaloon_buf + 2); - - /* free temporary buffer */ - free(versaloon_buf); - versaloon_buf = NULL; - - versaloon_buf = malloc(versaloon_interface.usb_setting.buf_size); - if (NULL == versaloon_buf) { - versaloon_fini(); - LOG_ERROR(ERRMSG_NOT_ENOUGH_MEMORY); - return ERRCODE_NOT_ENOUGH_MEMORY; - } - versaloon_cmd_buf = malloc(versaloon_interface.usb_setting.buf_size - 3); - if (NULL == versaloon_cmd_buf) { - versaloon_fini(); - LOG_ERROR(ERRMSG_NOT_ENOUGH_MEMORY); - return ERRCODE_NOT_ENOUGH_MEMORY; - } - if (ERROR_OK != usbtoxxx_init()) { - LOG_ERROR(ERRMSG_FAILURE_OPERATION, "initialize usbtoxxx"); - return ERROR_FAIL; - } - return versaloon_get_target_voltage(&ret); -} - -RESULT versaloon_fini(void) -{ - if (versaloon_usb_device_handle != NULL) { - usbtoxxx_fini(); - versaloon_free_want_pos(); - - versaloon_usb_device_handle = NULL; - - if (versaloon_buf != NULL) { - free(versaloon_buf); - versaloon_buf = NULL; - } - if (versaloon_cmd_buf != NULL) { - free(versaloon_cmd_buf); - versaloon_cmd_buf = NULL; - } - } - - return ERROR_OK; -} - -RESULT versaloon_set_target_voltage(uint16_t voltage) -{ - usbtopwr_init(0); - usbtopwr_config(0); - usbtopwr_output(0, voltage); - usbtopwr_fini(0); - - return usbtoxxx_execute_command(); -} - -RESULT versaloon_get_target_voltage(uint16_t *voltage) -{ - uint16_t inlen; - -#if PARAM_CHECK - if (NULL == versaloon_buf) { - LOG_BUG(ERRMSG_INVALID_BUFFER, TO_STR(versaloon_buf)); - return ERRCODE_INVALID_BUFFER; - } - if (NULL == voltage) { - LOG_BUG(ERRMSG_INVALID_PARAMETER, __func__); - return ERRCODE_INVALID_PARAMETER; - } -#endif - - versaloon_buf[0] = VERSALOON_GET_TVCC; - - if ((ERROR_OK != versaloon_send_command(1, &inlen)) || (inlen != 2)) { - LOG_ERROR(ERRMSG_FAILURE_OPERATION, "communicate with versaloon"); - return ERRCODE_FAILURE_OPERATION; - } else { - *voltage = versaloon_buf[0] + (versaloon_buf[1] << 8); - return ERROR_OK; - } -} - -RESULT versaloon_delay_ms(uint16_t ms) -{ - return usbtodelay_delay(ms | 0x8000); -} - -RESULT versaloon_delay_us(uint16_t us) -{ - return usbtodelay_delay(us & 0x7FFF); -} diff --git a/src/jtag/drivers/versaloon/versaloon.h b/src/jtag/drivers/versaloon/versaloon.h deleted file mode 100644 index 9d92bcaa1..000000000 --- a/src/jtag/drivers/versaloon/versaloon.h +++ /dev/null @@ -1,112 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2009 by Simon Qian * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 OPENOCD_JTAG_DRIVERS_VERSALOON_VERSALOON_H -#define OPENOCD_JTAG_DRIVERS_VERSALOON_VERSALOON_H - -#include - -struct usart_status_t { - uint32_t tx_buff_avail; - uint32_t tx_buff_size; - uint32_t rx_buff_avail; - uint32_t rx_buff_size; -}; - -#include "usbtoxxx/usbtoxxx.h" - -/* GPIO pins */ -#define GPIO_SRST (1 << 0) -#define GPIO_TRST (1 << 1) -#define GPIO_USR1 (1 << 2) -#define GPIO_USR2 (1 << 3) -#define GPIO_TCK (1 << 4) -#define GPIO_TDO (1 << 5) -#define GPIO_TDI (1 << 6) -#define GPIO_RTCK (1 << 7) -#define GPIO_TMS (1 << 8) - -struct interface_gpio_t { - RESULT(*init)(uint8_t interface_index); - RESULT(*fini)(uint8_t interface_index); - RESULT(*config)(uint8_t interface_index, uint32_t pin_mask, uint32_t io, - uint32_t pull_en_mask, uint32_t input_pull_mask); - RESULT(*out)(uint8_t interface_index, uint32_t pin_mask, uint32_t value); - RESULT(*in)(uint8_t interface_index, uint32_t pin_mask, uint32_t *value); -}; - -struct interface_delay_t { - RESULT(*delayms)(uint16_t ms); - RESULT(*delayus)(uint16_t us); -}; - -struct interface_swd_t { - RESULT(*init)(uint8_t interface_index); - RESULT(*fini)(uint8_t interface_index); - RESULT(*config)(uint8_t interface_index, uint8_t trn, uint16_t retry, - uint16_t dly); - RESULT(*seqout)(uint8_t interface_index, const uint8_t *data, - uint16_t bitlen); - RESULT(*seqin)(uint8_t interface_index, uint8_t *data, uint16_t bitlen); - RESULT(*transact)(uint8_t interface_index, uint8_t request, - uint32_t *data, uint8_t *ack); -}; - -struct interface_jtag_raw_t { - RESULT(*init)(uint8_t interface_index); - RESULT(*fini)(uint8_t interface_index); - RESULT(*config)(uint8_t interface_index, uint32_t kHz); - RESULT(*execute)(uint8_t interface_index, uint8_t *tdi, uint8_t *tms, - uint8_t *tdo, uint32_t bitlen); -}; - -struct interface_target_voltage_t { - RESULT(*get)(uint16_t *voltage); - RESULT(*set)(uint16_t voltage); -}; - -struct versaloon_adaptors_t { - struct interface_target_voltage_t target_voltage; - struct interface_gpio_t gpio; - struct interface_delay_t delay; - struct interface_swd_t swd; - struct interface_jtag_raw_t jtag_raw; - RESULT(*peripheral_commit)(void); -}; - -struct versaloon_usb_setting_t { - uint16_t vid; - uint16_t pid; - uint8_t ep_out; - uint8_t ep_in; - uint8_t interface; - char *serialstring; - - uint16_t buf_size; -}; - -struct versaloon_interface_t { - RESULT(*init)(void); - RESULT(*fini)(void); - struct versaloon_adaptors_t adaptors; - struct versaloon_usb_setting_t usb_setting; -}; - -extern struct versaloon_interface_t versaloon_interface; -extern libusb_device_handle *versaloon_usb_device_handle; - -#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 deleted file mode 100644 index 089056d02..000000000 --- a/src/jtag/drivers/versaloon/versaloon_include.h +++ /dev/null @@ -1,102 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2009 by Simon Qian * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 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 -#include - -#define PARAM_CHECK 1 - -#define sleep_ms(ms) jtag_sleep((ms) * 1000) -#define dimof(arr) (sizeof(arr) / sizeof((arr)[0])) -#define TO_STR(name) #name - -#define RESULT int -#define LOG_BUG LOG_ERROR - -/* Common error messages */ -#define ERRMSG_NOT_ENOUGH_MEMORY "Lack of memory." -#define ERRCODE_NOT_ENOUGH_MEMORY ERROR_FAIL - -#define ERRMSG_INVALID_VALUE "%d is invalid for %s." -#define ERRMSG_INVALID_INDEX "Index %d is invalid for %s." -#define ERRMSG_INVALID_USAGE "Invalid usage of %s" -#define ERRMSG_INVALID_TARGET "Invalid %s" -#define ERRMSG_INVALID_PARAMETER "Invalid parameter of %s." -#define ERRMSG_INVALID_INTERFACE_NUM "invalid inteface %d" -#define ERRMSG_INVALID_BUFFER "Buffer %s is not valid." -#define ERRCODE_INVALID_BUFFER ERROR_FAIL -#define ERRCODE_INVALID_PARAMETER ERROR_FAIL - -#define ERRMSG_NOT_SUPPORT_BY "%s is not supported by %s." - -#define ERRMSG_FAILURE_OPERATION "Fail to %s." -#define ERRMSG_FAILURE_OPERATION_MESSAGE "Fail to %s, %s" -#define ERRCODE_FAILURE_OPERATION ERROR_FAIL - -#define GET_U16_MSBFIRST(p) (((*((uint8_t *)(p) + 0)) << 8) | \ - ((*((uint8_t *)(p) + 1)) << 0)) -#define GET_U32_MSBFIRST(p) (((*((uint8_t *)(p) + 0)) << 24) | \ - ((*((uint8_t *)(p) + 1)) << 16) | \ - ((*((uint8_t *)(p) + 2)) << 8) | \ - ((*((uint8_t *)(p) + 3)) << 0)) -#define GET_U16_LSBFIRST(p) (((*((uint8_t *)(p) + 0)) << 0) | \ - ((*((uint8_t *)(p) + 1)) << 8)) -#define GET_U32_LSBFIRST(p) (((*((uint8_t *)(p) + 0)) << 0) | \ - ((*((uint8_t *)(p) + 1)) << 8) | \ - ((*((uint8_t *)(p) + 2)) << 16) | \ - ((*((uint8_t *)(p) + 3)) << 24)) - -#define SET_U16_MSBFIRST(p, v) \ - do {\ - *((uint8_t *)(p) + 0) = (((uint16_t)(v)) >> 8) & 0xFF;\ - *((uint8_t *)(p) + 1) = (((uint16_t)(v)) >> 0) & 0xFF;\ - } while (0) -#define SET_U32_MSBFIRST(p, v) \ - do {\ - *((uint8_t *)(p) + 0) = (((uint32_t)(v)) >> 24) & 0xFF;\ - *((uint8_t *)(p) + 1) = (((uint32_t)(v)) >> 16) & 0xFF;\ - *((uint8_t *)(p) + 2) = (((uint32_t)(v)) >> 8) & 0xFF;\ - *((uint8_t *)(p) + 3) = (((uint32_t)(v)) >> 0) & 0xFF;\ - } while (0) -#define SET_U16_LSBFIRST(p, v) \ - do {\ - *((uint8_t *)(p) + 0) = (((uint16_t)(v)) >> 0) & 0xFF;\ - *((uint8_t *)(p) + 1) = (((uint16_t)(v)) >> 8) & 0xFF;\ - } while (0) -#define SET_U32_LSBFIRST(p, v) \ - do {\ - *((uint8_t *)(p) + 0) = (((uint32_t)(v)) >> 0) & 0xFF;\ - *((uint8_t *)(p) + 1) = (((uint32_t)(v)) >> 8) & 0xFF;\ - *((uint8_t *)(p) + 2) = (((uint32_t)(v)) >> 16) & 0xFF;\ - *((uint8_t *)(p) + 3) = (((uint32_t)(v)) >> 24) & 0xFF;\ - } while (0) - -#define GET_LE_U16(p) GET_U16_LSBFIRST(p) -#define GET_LE_U32(p) GET_U32_LSBFIRST(p) -#define GET_BE_U16(p) GET_U16_MSBFIRST(p) -#define GET_BE_U32(p) GET_U32_MSBFIRST(p) -#define SET_LE_U16(p, v) SET_U16_LSBFIRST(p, v) -#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 deleted file mode 100644 index 497b6b9ce..000000000 --- a/src/jtag/drivers/versaloon/versaloon_internal.h +++ /dev/null @@ -1,110 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2009 - 2010 by Simon Qian * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 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 - -#define VERSALOON_PRODUCTSTRING "Versaloon" - -#define VERSALOON_VID 0x0483 -#define VERSALOON_PID 0xA038 -#define VERSALOON_INP 0x82 -#define VERSALOON_OUTP 0x03 -#define VERSALOON_IFACE 0x00 - -#define VERSALOON_FULL 1 -#define VERSALOON_MINI 2 -#define VERSALOON_NANO 3 - -#define VERSALOON_TIMEOUT 5000 -#define VERSALOON_TIMEOUT_LONG 60000 - -/* USB Commands */ -/* Common Commands */ -#define VERSALOON_COMMON_CMD_START 0x00 -#define VERSALOON_COMMON_CMD_END 0x0F - -#define VERSALOON_GET_INFO 0x00 -#define VERSALOON_GET_TVCC 0x01 -#define VERSALOON_GET_HARDWARE 0x02 -#define VERSALOON_GET_OFFLINE_SIZE 0x08 -#define VERSALOON_ERASE_OFFLINE_DATA 0x09 -#define VERSALOON_WRITE_OFFLINE_DATA 0x0A -#define VERSALOON_GET_OFFLINE_CHECKSUM 0x0B -#define VERSALOON_FW_UPDATE 0x0F -#define VERSALOON_FW_UPDATE_KEY 0xAA - -/* MCU Command */ -#define VERSALOON_MCU_CMD_START 0x10 -#define VERSALOON_MCU_CMD_END 0x1F - -/* USB_TO_XXX Command */ -#define VERSALOON_USB_TO_XXX_CMD_START 0x20 -#define VERSALOON_USB_TO_XXX_CMD_END 0x7F - -/* VSLLink Command */ -#define VERSALOON_VSLLINK_CMD_START 0x80 -#define VERSALOON_VSLLINK_CMD_END 0xFF - -/* Mass-product */ -#define MP_OK 0x00 -#define MP_FAIL 0x01 - -#define MP_ISSP 0x11 - -/* pending struct */ -#define VERSALOON_MAX_PENDING_NUMBER 4096 -typedef RESULT(*versaloon_callback_t)(void *, uint8_t *, uint8_t *); -struct versaloon_want_pos_t { - uint16_t offset; - uint16_t size; - uint8_t *buff; - struct versaloon_want_pos_t *next; -}; -struct versaloon_pending_t { - uint8_t type; - uint8_t cmd; - uint16_t want_data_pos; - uint16_t want_data_size; - uint16_t actual_data_size; - uint8_t *data_buffer; - uint8_t collect; - uint32_t id; - struct versaloon_want_pos_t *pos; - void *extra_data; - versaloon_callback_t callback; -}; -extern struct versaloon_pending_t \ - versaloon_pending[VERSALOON_MAX_PENDING_NUMBER]; -extern uint16_t versaloon_pending_idx; -void versaloon_set_pending_id(uint32_t id); -void versaloon_set_callback(versaloon_callback_t callback); -void versaloon_set_extra_data(void *p); -RESULT versaloon_add_want_pos(uint16_t offset, uint16_t size, uint8_t *buff); -RESULT versaloon_add_pending(uint8_t type, uint8_t cmd, uint16_t actual_szie, - uint16_t want_pos, uint16_t want_size, uint8_t *buffer, uint8_t collect); -void versaloon_free_want_pos(void); - -RESULT versaloon_send_command(uint16_t out_len, uint16_t *inlen); -extern uint8_t *versaloon_buf; -extern uint8_t *versaloon_cmd_buf; -extern uint16_t versaloon_buf_size; - -#endif /* OPENOCD_JTAG_DRIVERS_VERSALOON_VERSALOON_INTERNAL_H */ diff --git a/src/jtag/drivers/vsllink.c b/src/jtag/drivers/vsllink.c deleted file mode 100644 index 6f7e9cadf..000000000 --- a/src/jtag/drivers/vsllink.c +++ /dev/null @@ -1,975 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2009-2010 by Simon Qian * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -/* Versaloon is a programming tool for multiple MCUs. - * It's distributed under GPLv3. - * You can find it at http://www.Versaloon.com/. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include -#include - -#include "versaloon/versaloon_include.h" -#include "versaloon/versaloon.h" - -static int vsllink_tms_offset; - -struct pending_scan_result { - int src_offset; - int dest_offset; - int length; /* Number of bits to read */ - struct scan_command *command; /* Corresponding scan command */ - uint8_t *ack; - uint8_t *buffer; - bool last; /* indicate the last scan pending */ -}; - -#define MAX_PENDING_SCAN_RESULTS 256 - -static int pending_scan_results_length; -static struct pending_scan_result - pending_scan_results_buffer[MAX_PENDING_SCAN_RESULTS]; - -/* Queue command functions */ -static void vsllink_end_state(tap_state_t state); -static void vsllink_state_move(void); -static void vsllink_path_move(int num_states, tap_state_t *path); -static void vsllink_tms(int num_bits, const uint8_t *bits); -static void vsllink_runtest(int num_cycles); -static void vsllink_stableclocks(int num_cycles, int tms); -static void vsllink_scan(bool ir_scan, enum scan_type type, - uint8_t *buffer, int scan_size, struct scan_command *command); -static void vsllink_reset(int trst, int srst); - -/* VSLLink tap buffer functions */ -static void vsllink_tap_append_step(int tms, int tdi); -static void vsllink_tap_init(void); -static int vsllink_tap_execute(void); -static void vsllink_tap_ensure_pending(int scans); -static void vsllink_tap_append_scan(int length, uint8_t *buffer, - struct scan_command *command); - -/* VSLLink SWD functions */ -static int_least32_t vsllink_swd_frequency(int_least32_t hz); -static int vsllink_swd_switch_seq(enum swd_special_seq seq); - -/* VSLLink lowlevel functions */ -struct vsllink { - struct libusb_context *libusb_ctx; - struct libusb_device_handle *usb_device_handle; -}; - -static int vsllink_usb_open(struct vsllink *vsllink); -static void vsllink_usb_close(struct vsllink *vsllink); - -#if defined _DEBUG_JTAG_IO_ -static void vsllink_debug_buffer(uint8_t *buffer, int length); -#endif - -static int tap_length; -static int tap_buffer_size; -static uint8_t *tms_buffer; -static uint8_t *tdi_buffer; -static uint8_t *tdo_buffer; - -static bool swd_mode; - -static struct vsllink *vsllink_handle; - -static int vsllink_execute_queue(void) -{ - struct jtag_command *cmd = jtag_command_queue; - int scan_size; - enum scan_type type; - uint8_t *buffer; - - DEBUG_JTAG_IO("-------------------------------------" - " vsllink " - "-------------------------------------"); - - while (cmd != NULL) { - switch (cmd->type) { - case JTAG_RUNTEST: - DEBUG_JTAG_IO("runtest %i cycles, end in %s", - cmd->cmd.runtest->num_cycles, - tap_state_name(cmd->cmd.runtest->end_state)); - - vsllink_end_state(cmd->cmd.runtest->end_state); - vsllink_runtest(cmd->cmd.runtest->num_cycles); - break; - - case JTAG_TLR_RESET: - DEBUG_JTAG_IO("statemove end in %s", - tap_state_name(cmd->cmd.statemove->end_state)); - - vsllink_end_state(cmd->cmd.statemove->end_state); - vsllink_state_move(); - break; - - case JTAG_PATHMOVE: - DEBUG_JTAG_IO("pathmove: %i states, end in %s", - cmd->cmd.pathmove->num_states, - tap_state_name(cmd->cmd.pathmove->path[cmd->cmd.pathmove->num_states - 1])); - - vsllink_path_move(cmd->cmd.pathmove->num_states, cmd->cmd.pathmove->path); - break; - - case JTAG_SCAN: - DEBUG_JTAG_IO("JTAG Scan..."); - - vsllink_end_state(cmd->cmd.scan->end_state); - - scan_size = jtag_build_buffer( - cmd->cmd.scan, &buffer); - - if (cmd->cmd.scan->ir_scan) - DEBUG_JTAG_IO( - "JTAG Scan write IR(%d bits), " - "end in %s:", - scan_size, - tap_state_name(cmd->cmd.scan->end_state)); - - else - DEBUG_JTAG_IO( - "JTAG Scan write DR(%d bits), " - "end in %s:", - scan_size, - tap_state_name(cmd->cmd.scan->end_state)); - -#ifdef _DEBUG_JTAG_IO_ - vsllink_debug_buffer(buffer, - DIV_ROUND_UP(scan_size, 8)); -#endif - - type = jtag_scan_type(cmd->cmd.scan); - - vsllink_scan(cmd->cmd.scan->ir_scan, - type, buffer, scan_size, - cmd->cmd.scan); - break; - - case JTAG_RESET: - DEBUG_JTAG_IO("reset trst: %i srst %i", - cmd->cmd.reset->trst, - cmd->cmd.reset->srst); - - vsllink_tap_execute(); - - if (cmd->cmd.reset->trst == 1) - tap_set_state(TAP_RESET); - - vsllink_reset(cmd->cmd.reset->trst, - cmd->cmd.reset->srst); - break; - - case JTAG_SLEEP: - DEBUG_JTAG_IO("sleep %i", cmd->cmd.sleep->us); - vsllink_tap_execute(); - jtag_sleep(cmd->cmd.sleep->us); - break; - - case JTAG_STABLECLOCKS: - DEBUG_JTAG_IO("add %d clocks", - cmd->cmd.stableclocks->num_cycles); - - switch (tap_get_state()) { - case TAP_RESET: - /* tms must be '1' to stay - * n TAP_RESET mode - */ - scan_size = 1; - break; - case TAP_DRSHIFT: - case TAP_IDLE: - case TAP_DRPAUSE: - case TAP_IRSHIFT: - case TAP_IRPAUSE: - /* else, tms should be '0' */ - scan_size = 0; - break; - /* above stable states are OK */ - default: - LOG_ERROR("jtag_add_clocks() " - "in non-stable state \"%s\"", - tap_state_name(tap_get_state()) - ); - exit(-1); - } - vsllink_stableclocks(cmd->cmd.stableclocks->num_cycles, scan_size); - break; - - case JTAG_TMS: - DEBUG_JTAG_IO("add %d jtag tms", - cmd->cmd.tms->num_bits); - - vsllink_tms(cmd->cmd.tms->num_bits, cmd->cmd.tms->bits); - break; - - default: - LOG_ERROR("BUG: unknown JTAG command type " - "encountered: %d", cmd->type); - exit(-1); - } - cmd = cmd->next; - } - - return vsllink_tap_execute(); -} - -static int vsllink_speed(int speed) -{ - if (swd_mode) { - vsllink_swd_frequency(speed * 1000); - return ERROR_OK; - } - - versaloon_interface.adaptors.jtag_raw.config(0, (uint16_t)speed); - return versaloon_interface.adaptors.peripheral_commit(); -} - -static int vsllink_khz(int khz, int *jtag_speed) -{ - *jtag_speed = khz; - - return ERROR_OK; -} - -static int vsllink_speed_div(int jtag_speed, int *khz) -{ - *khz = jtag_speed; - - return ERROR_OK; -} - -static void vsllink_free_buffer(void) -{ - if (tdi_buffer != NULL) { - free(tdi_buffer); - tdi_buffer = NULL; - } - if (tdo_buffer != NULL) { - free(tdo_buffer); - tdo_buffer = NULL; - } - if (tms_buffer != NULL) { - free(tms_buffer); - tms_buffer = NULL; - } -} - -static int vsllink_quit(void) -{ - versaloon_interface.adaptors.gpio.config(0, GPIO_SRST | GPIO_TRST, - 0, 0, GPIO_SRST | GPIO_TRST); - versaloon_interface.adaptors.gpio.fini(0); - - if (swd_mode) - versaloon_interface.adaptors.swd.fini(0); - else - versaloon_interface.adaptors.jtag_raw.fini(0); - - versaloon_interface.adaptors.peripheral_commit(); - versaloon_interface.fini(); - - vsllink_free_buffer(); - vsllink_usb_close(vsllink_handle); - - free(vsllink_handle); - - return ERROR_OK; -} - -static int vsllink_interface_init(void) -{ - vsllink_handle = malloc(sizeof(struct vsllink)); - if (NULL == vsllink_handle) { - LOG_ERROR("unable to allocate memory"); - return ERROR_FAIL; - } - - libusb_init(&vsllink_handle->libusb_ctx); - - if (ERROR_OK != vsllink_usb_open(vsllink_handle)) { - LOG_ERROR("Can't find USB JTAG Interface!" \ - "Please check connection and permissions."); - return ERROR_JTAG_INIT_FAILED; - } - LOG_DEBUG("vsllink found on %04X:%04X", - versaloon_interface.usb_setting.vid, - versaloon_interface.usb_setting.pid); - versaloon_usb_device_handle = vsllink_handle->usb_device_handle; - - if (ERROR_OK != versaloon_interface.init()) - return ERROR_FAIL; - if (versaloon_interface.usb_setting.buf_size < 32) { - versaloon_interface.fini(); - return ERROR_FAIL; - } - - return ERROR_OK; -} - -static int vsllink_init(void) -{ - int retval = vsllink_interface_init(); - if (ERROR_OK != retval) - return retval; - - versaloon_interface.adaptors.gpio.init(0); - versaloon_interface.adaptors.gpio.config(0, GPIO_SRST, 0, GPIO_SRST, - GPIO_SRST); - versaloon_interface.adaptors.delay.delayms(100); - versaloon_interface.adaptors.peripheral_commit(); - - if (swd_mode) { - versaloon_interface.adaptors.gpio.config(0, GPIO_TRST, 0, - GPIO_TRST, GPIO_TRST); - versaloon_interface.adaptors.swd.init(0); - vsllink_swd_frequency(jtag_get_speed_khz() * 1000); - vsllink_swd_switch_seq(JTAG_TO_SWD); - - } else { - /* malloc buffer size for tap */ - tap_buffer_size = versaloon_interface.usb_setting.buf_size / 2 - 32; - vsllink_free_buffer(); - tdi_buffer = malloc(tap_buffer_size); - tdo_buffer = malloc(tap_buffer_size); - tms_buffer = malloc(tap_buffer_size); - if ((NULL == tdi_buffer) || (NULL == tdo_buffer) || (NULL == tms_buffer)) { - vsllink_quit(); - return ERROR_FAIL; - } - - versaloon_interface.adaptors.jtag_raw.init(0); - versaloon_interface.adaptors.jtag_raw.config(0, jtag_get_speed_khz()); - versaloon_interface.adaptors.gpio.config(0, GPIO_SRST | GPIO_TRST, - GPIO_TRST, GPIO_SRST, GPIO_SRST); - } - - if (ERROR_OK != versaloon_interface.adaptors.peripheral_commit()) - return ERROR_FAIL; - - vsllink_reset(0, 0); - vsllink_tap_init(); - return ERROR_OK; -} - -/************************************************************************** - * Queue command implementations */ - -static void vsllink_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); - } -} - -/* Goes to the end state. */ -static void vsllink_state_move(void) -{ - int i; - uint8_t tms_scan = tap_get_tms_path(tap_get_state(), - tap_get_end_state()); - uint8_t tms_scan_bits = tap_get_tms_path_len(tap_get_state(), - tap_get_end_state()); - - for (i = 0; i < tms_scan_bits; i++) - vsllink_tap_append_step((tms_scan >> i) & 1, 0); - - tap_set_state(tap_get_end_state()); -} - -static void vsllink_path_move(int num_states, tap_state_t *path) -{ - for (int i = 0; i < num_states; i++) { - if (path[i] == tap_state_transition(tap_get_state(), false)) - vsllink_tap_append_step(0, 0); - else if (path[i] == tap_state_transition(tap_get_state(), true)) - vsllink_tap_append_step(1, 0); - 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]); - } - - tap_set_end_state(tap_get_state()); -} - -static void vsllink_tms(int num_bits, const uint8_t *bits) -{ - for (int i = 0; i < num_bits; i++) - vsllink_tap_append_step((bits[i / 8] >> (i % 8)) & 1, 0); -} - -static void vsllink_stableclocks(int num_cycles, int tms) -{ - while (num_cycles > 0) { - vsllink_tap_append_step(tms, 0); - num_cycles--; - } -} - -static void vsllink_runtest(int num_cycles) -{ - tap_state_t saved_end_state = tap_get_end_state(); - - if (tap_get_state() != TAP_IDLE) { - /* enter IDLE state */ - vsllink_end_state(TAP_IDLE); - vsllink_state_move(); - } - - vsllink_stableclocks(num_cycles, 0); - - /* post-process */ - /* set end_state */ - vsllink_end_state(saved_end_state); - if (tap_get_end_state() != tap_get_end_state()) - vsllink_state_move(); -} - -static void vsllink_scan(bool ir_scan, enum scan_type type, uint8_t *buffer, - int scan_size, struct scan_command *command) -{ - tap_state_t saved_end_state; - - saved_end_state = tap_get_end_state(); - - /* Move to appropriate scan state */ - vsllink_end_state(ir_scan ? TAP_IRSHIFT : TAP_DRSHIFT); - - if (tap_get_state() != tap_get_end_state()) - vsllink_state_move(); - vsllink_end_state(saved_end_state); - - /* Scan */ - vsllink_tap_append_scan(scan_size, buffer, command); - - /* Goto Pause and record position to insert tms:0 */ - vsllink_tap_append_step(0, 0); - vsllink_tms_offset = tap_length; - - tap_set_state(ir_scan ? TAP_IRPAUSE : TAP_DRPAUSE); - - if (tap_get_state() != tap_get_end_state()) - vsllink_state_move(); -} - -static void vsllink_reset(int trst, int srst) -{ - LOG_DEBUG("trst: %i, srst: %i", trst, srst); - - if (!srst) - versaloon_interface.adaptors.gpio.config(0, GPIO_SRST, 0, GPIO_SRST, GPIO_SRST); - else - versaloon_interface.adaptors.gpio.config(0, GPIO_SRST, GPIO_SRST, 0, 0); - - if (!swd_mode) { - if (!trst) - versaloon_interface.adaptors.gpio.out(0, GPIO_TRST, GPIO_TRST); - else - versaloon_interface.adaptors.gpio.out(0, GPIO_TRST, 0); - } - - versaloon_interface.adaptors.peripheral_commit(); -} - -COMMAND_HANDLER(vsllink_handle_usb_vid_command) -{ - if (CMD_ARGC != 1) - return ERROR_COMMAND_SYNTAX_ERROR; - - COMMAND_PARSE_NUMBER(u16, CMD_ARGV[0], - versaloon_interface.usb_setting.vid); - return ERROR_OK; -} - -COMMAND_HANDLER(vsllink_handle_usb_pid_command) -{ - if (CMD_ARGC != 1) - return ERROR_COMMAND_SYNTAX_ERROR; - COMMAND_PARSE_NUMBER(u16, CMD_ARGV[0], - versaloon_interface.usb_setting.pid); - return ERROR_OK; -} - -COMMAND_HANDLER(vsllink_handle_usb_serial_command) -{ - if (CMD_ARGC > 1) - return ERROR_COMMAND_SYNTAX_ERROR; - - free(versaloon_interface.usb_setting.serialstring); - - if (CMD_ARGC == 1) - versaloon_interface.usb_setting.serialstring = strdup(CMD_ARGV[0]); - else - versaloon_interface.usb_setting.serialstring = NULL; - - return ERROR_OK; -} - -COMMAND_HANDLER(vsllink_handle_usb_bulkin_command) -{ - if (CMD_ARGC != 1) - return ERROR_COMMAND_SYNTAX_ERROR; - - COMMAND_PARSE_NUMBER(u8, CMD_ARGV[0], - versaloon_interface.usb_setting.ep_in); - - versaloon_interface.usb_setting.ep_in |= 0x80; - - return ERROR_OK; -} - -COMMAND_HANDLER(vsllink_handle_usb_bulkout_command) -{ - if (CMD_ARGC != 1) - return ERROR_COMMAND_SYNTAX_ERROR; - - COMMAND_PARSE_NUMBER(u8, CMD_ARGV[0], - versaloon_interface.usb_setting.ep_out); - - versaloon_interface.usb_setting.ep_out &= ~0x80; - - return ERROR_OK; -} - -COMMAND_HANDLER(vsllink_handle_usb_interface_command) -{ - if (CMD_ARGC != 1) - return ERROR_COMMAND_SYNTAX_ERROR; - - COMMAND_PARSE_NUMBER(u8, CMD_ARGV[0], - versaloon_interface.usb_setting.interface); - return ERROR_OK; -} - -/************************************************************************** - * VSLLink tap functions */ - -static void vsllink_tap_init(void) -{ - tap_length = 0; - pending_scan_results_length = 0; - vsllink_tms_offset = 0; -} - -static void vsllink_tap_ensure_pending(int scans) -{ - int available_scans = - MAX_PENDING_SCAN_RESULTS - pending_scan_results_length; - - if (scans > available_scans) - vsllink_tap_execute(); -} - -static void vsllink_tap_append_step(int tms, int tdi) -{ - int index_var = tap_length / 8; - - int bit_index = tap_length % 8; - uint8_t bit = 1 << bit_index; - - 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; - - tap_length++; - - if (tap_buffer_size * 8 <= tap_length) - vsllink_tap_execute(); -} - -static void vsllink_tap_append_scan(int length, uint8_t *buffer, - struct scan_command *command) -{ - struct pending_scan_result *pending_scan_result; - int len_tmp, len_all, i; - - len_all = 0; - while (len_all < length) { - vsllink_tap_ensure_pending(1); - pending_scan_result = - &pending_scan_results_buffer[ - pending_scan_results_length]; - - if ((length - len_all) > (tap_buffer_size * 8 - tap_length)) { - /* Use all memory available - vsllink_tap_append_step will commit automatically */ - len_tmp = tap_buffer_size * 8 - tap_length; - pending_scan_result->last = false; - } else { - len_tmp = length - len_all; - pending_scan_result->last = true; - } - pending_scan_result->src_offset = tap_length; - pending_scan_result->dest_offset = len_all; - pending_scan_result->length = len_tmp; - pending_scan_result->command = command; - pending_scan_result->buffer = buffer; - pending_scan_results_length++; - - for (i = 0; i < len_tmp; i++) { - vsllink_tap_append_step(((len_all + i) < length-1 - ? 0 : 1), - (buffer[(len_all + i)/8] - >> ((len_all + i)%8)) & 1); - } - - len_all += len_tmp; - } -} - -static int vsllink_jtag_execute(void) -{ - int i; - int result; - - if (tap_length <= 0) - return ERROR_OK; - - versaloon_interface.adaptors.jtag_raw.execute(0, tdi_buffer, tms_buffer, - tdo_buffer, tap_length); - - result = versaloon_interface.adaptors.peripheral_commit(); - - if (result == ERROR_OK) { - 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 src_first = pending_scan_result->src_offset; - int dest_first = pending_scan_result->dest_offset; - bool last = pending_scan_result->last; - - struct scan_command *command; - - command = pending_scan_result->command; - buf_set_buf(tdo_buffer, src_first, buffer, dest_first, length); - -#ifdef _DEBUG_JTAG_IO_ - DEBUG_JTAG_IO( - "JTAG scan read(%d bits, from src %d bits to dest %d bits):", - length, src_first, dest_first); - vsllink_debug_buffer(buffer + dest_first / 8, - DIV_ROUND_UP(length, 7)); -#endif - - if (last) { - if (jtag_read_buffer(buffer, command) - != ERROR_OK) { - vsllink_tap_init(); - return ERROR_JTAG_QUEUE_FAILED; - } - - if (pending_scan_result->buffer != NULL) - free(pending_scan_result->buffer); - } - } - } else { - LOG_ERROR("vsllink_jtag_execute failure"); - return ERROR_JTAG_QUEUE_FAILED; - } - - vsllink_tap_init(); - - return ERROR_OK; -} - -static int vsllink_tap_execute(void) -{ - if (swd_mode) - return ERROR_OK; - - return vsllink_jtag_execute(); -} - -static int vsllink_swd_init(void) -{ - LOG_INFO("VSLLink SWD mode enabled"); - swd_mode = true; - - return ERROR_OK; -} - -static int_least32_t vsllink_swd_frequency(int_least32_t hz) -{ - const int_least32_t delay2hz[] = { - 1850000, 235000, 130000, 102000, 85000, 72000 - }; - - if (hz > 0) { - uint16_t delay = UINT16_MAX; - - for (uint16_t i = 0; i < ARRAY_SIZE(delay2hz); i++) { - if (hz >= delay2hz[i]) { - hz = delay2hz[i]; - delay = i; - break; - } - } - - if (delay == UINT16_MAX) - delay = (500000 / hz) - 1; - - /* Calculate retry count after a WAIT response. This will give - * a retry timeout at about ~250 ms. 54 is the number of bits - * found in a transaction. */ - uint16_t retry_count = 250 * hz / 1000 / 54; - - LOG_DEBUG("SWD delay: %d, retry count: %d", delay, retry_count); - - versaloon_interface.adaptors.swd.config(0, 2, retry_count, delay); - } - - return hz; -} - -static int vsllink_swd_switch_seq(enum swd_special_seq seq) -{ - switch (seq) { - case LINE_RESET: - LOG_DEBUG("SWD line reset"); - versaloon_interface.adaptors.swd.seqout(0, swd_seq_line_reset, - swd_seq_line_reset_len); - break; - case JTAG_TO_SWD: - LOG_DEBUG("JTAG-to-SWD"); - versaloon_interface.adaptors.swd.seqout(0, swd_seq_jtag_to_swd, - swd_seq_jtag_to_swd_len); - break; - case SWD_TO_JTAG: - LOG_DEBUG("SWD-to-JTAG"); - versaloon_interface.adaptors.swd.seqout(0, swd_seq_swd_to_jtag, - swd_seq_swd_to_jtag_len); - break; - default: - LOG_ERROR("Sequence %d not supported", seq); - return ERROR_FAIL; - } - - return ERROR_OK; -} - -static void vsllink_swd_read_reg(uint8_t cmd, uint32_t *value, uint32_t ap_delay_clk) -{ - versaloon_interface.adaptors.swd.transact(0, cmd, value, NULL); -} - -static void vsllink_swd_write_reg(uint8_t cmd, uint32_t value, uint32_t ap_delay_clk) -{ - versaloon_interface.adaptors.swd.transact(0, cmd, &value, NULL); -} - -static int vsllink_swd_run_queue(void) -{ - return versaloon_interface.adaptors.peripheral_commit(); -} - -/**************************************************************************** - * VSLLink USB low-level functions */ - -static int vsllink_check_usb_strings( - struct libusb_device_handle *usb_device_handle, - struct libusb_device_descriptor *usb_desc) -{ - char desc_string[256]; - int retval; - - if (NULL != versaloon_interface.usb_setting.serialstring) { - retval = libusb_get_string_descriptor_ascii(usb_device_handle, - usb_desc->iSerialNumber, (unsigned char *)desc_string, - sizeof(desc_string)); - if (retval < 0) - return ERROR_FAIL; - - if (strncmp(desc_string, versaloon_interface.usb_setting.serialstring, - sizeof(desc_string))) - return ERROR_FAIL; - } - - retval = libusb_get_string_descriptor_ascii(usb_device_handle, - usb_desc->iProduct, (unsigned char *)desc_string, - sizeof(desc_string)); - if (retval < 0) - return ERROR_FAIL; - - if (strstr(desc_string, "Versaloon") == NULL) - return ERROR_FAIL; - - return ERROR_OK; -} - -static int vsllink_usb_open(struct vsllink *vsllink) -{ - ssize_t num_devices, i; - libusb_device **usb_devices; - struct libusb_device_descriptor usb_desc; - struct libusb_device_handle *usb_device_handle; - int retval; - - num_devices = libusb_get_device_list(vsllink->libusb_ctx, &usb_devices); - - if (num_devices <= 0) - return ERROR_FAIL; - - for (i = 0; i < num_devices; i++) { - libusb_device *device = usb_devices[i]; - - retval = libusb_get_device_descriptor(device, &usb_desc); - if (retval != 0) - continue; - - if (usb_desc.idVendor != versaloon_interface.usb_setting.vid || - usb_desc.idProduct != versaloon_interface.usb_setting.pid) - continue; - - retval = libusb_open(device, &usb_device_handle); - if (retval != 0) - continue; - - retval = vsllink_check_usb_strings(usb_device_handle, &usb_desc); - if (ERROR_OK == retval) - break; - - libusb_close(usb_device_handle); - } - - libusb_free_device_list(usb_devices, 1); - - if (i == num_devices) - return ERROR_FAIL; - - retval = libusb_claim_interface(usb_device_handle, - versaloon_interface.usb_setting.interface); - if (retval != 0) { - LOG_ERROR("unable to claim interface"); - libusb_close(usb_device_handle); - return ERROR_FAIL; - } - - vsllink->usb_device_handle = usb_device_handle; - return ERROR_OK; -} - -static void vsllink_usb_close(struct vsllink *vsllink) -{ - libusb_release_interface(vsllink->usb_device_handle, - versaloon_interface.usb_setting.interface); - libusb_close(vsllink->usb_device_handle); -} - -#define BYTES_PER_LINE 16 - -#if defined _DEBUG_JTAG_IO_ -static void vsllink_debug_buffer(uint8_t *buffer, int length) -{ - char line[81]; - char s[4]; - int i; - int j; - - for (i = 0; i < length; i += BYTES_PER_LINE) { - snprintf(line, 5, "%04x", i); - for (j = i; j < i + BYTES_PER_LINE && j < length; j++) { - snprintf(s, 4, " %02x", buffer[j]); - strcat(line, s); - } - LOG_DEBUG("%s", line); - } -} -#endif /* _DEBUG_JTAG_IO_ */ - -static const struct command_registration vsllink_command_handlers[] = { - { - .name = "vsllink_usb_vid", - .handler = &vsllink_handle_usb_vid_command, - .mode = COMMAND_CONFIG, - }, - { - .name = "vsllink_usb_pid", - .handler = &vsllink_handle_usb_pid_command, - .mode = COMMAND_CONFIG, - }, - { - .name = "vsllink_usb_serial", - .handler = &vsllink_handle_usb_serial_command, - .mode = COMMAND_CONFIG, - }, - { - .name = "vsllink_usb_bulkin", - .handler = &vsllink_handle_usb_bulkin_command, - .mode = COMMAND_CONFIG, - }, - { - .name = "vsllink_usb_bulkout", - .handler = &vsllink_handle_usb_bulkout_command, - .mode = COMMAND_CONFIG, - }, - { - .name = "vsllink_usb_interface", - .handler = &vsllink_handle_usb_interface_command, - .mode = COMMAND_CONFIG, - }, - COMMAND_REGISTRATION_DONE -}; - -static const char * const vsllink_transports[] = {"jtag", "swd", NULL}; - -static const struct swd_driver vsllink_swd_driver = { - .init = vsllink_swd_init, - .frequency = vsllink_swd_frequency, - .switch_seq = vsllink_swd_switch_seq, - .read_reg = vsllink_swd_read_reg, - .write_reg = vsllink_swd_write_reg, - .run = vsllink_swd_run_queue, -}; - -struct jtag_interface vsllink_interface = { - .name = "vsllink", - .supported = DEBUG_CAP_TMS_SEQ, - .commands = vsllink_command_handlers, - .transports = vsllink_transports, - .swd = &vsllink_swd_driver, - - .init = vsllink_init, - .quit = vsllink_quit, - .khz = vsllink_khz, - .speed = vsllink_speed, - .speed_div = vsllink_speed_div, - .execute_queue = vsllink_execute_queue, -}; diff --git a/src/jtag/hla/Makefile.am b/src/jtag/hla/Makefile.am deleted file mode 100644 index 4fbc70e9c..000000000 --- a/src/jtag/hla/Makefile.am +++ /dev/null @@ -1,23 +0,0 @@ -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 diff --git a/src/jtag/hla/hla_interface.c b/src/jtag/hla/hla_interface.c deleted file mode 100644 index 9217631b0..000000000 --- a/src/jtag/hla/hla_interface.c +++ /dev/null @@ -1,347 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2011 by Mathias Kuester * - * Mathias Kuester * - * * - * Copyright (C) 2012 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -/* project specific includes */ -#include -#include -#include - -#include -#include -#include -#include - -#include - -static struct hl_interface_s hl_if = { {0, 0, 0, 0, 0, HL_TRANSPORT_UNKNOWN, false, -1}, 0, 0 }; - -int hl_interface_open(enum hl_transports tr) -{ - LOG_DEBUG("hl_interface_open"); - - 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) - hl_if.param.connect_under_reset = true; - else - LOG_WARNING("\'srst_nogate\' reset_config option is required"); - } - - /* set transport mode */ - hl_if.param.transport = tr; - - int result = hl_if.layout->open(&hl_if); - if (result != ERROR_OK) - return result; - - return hl_interface_init_reset(); -} - -int hl_interface_init_target(struct target *t) -{ - int res; - - LOG_DEBUG("hl_interface_init_target"); - - /* this is the interface for the current target and we - * can setup the private pointer in the tap structure - * if the interface match the tap idcode - */ - res = hl_if.layout->api->idcode(hl_if.handle, &t->tap->idcode); - - if (res != ERROR_OK) - return res; - - unsigned ii, limit = t->tap->expected_ids_cnt; - int found = 0; - - for (ii = 0; ii < limit; ii++) { - uint32_t expected = t->tap->expected_ids[ii]; - - /* treat "-expected-id 0" as a "don't-warn" wildcard */ - if (!expected || !t->tap->idcode || - (t->tap->idcode == expected)) { - found = 1; - break; - } - } - - if (found == 0) { - LOG_WARNING("UNEXPECTED idcode: 0x%08" PRIx32, t->tap->idcode); - for (ii = 0; ii < limit; ii++) - LOG_ERROR("expected %u of %u: 0x%08" PRIx32, ii + 1, limit, - t->tap->expected_ids[ii]); - - return ERROR_FAIL; - } - - t->tap->priv = &hl_if; - t->tap->hasidcode = 1; - - return ERROR_OK; -} - -static int hl_interface_init(void) -{ - LOG_DEBUG("hl_interface_init"); - - /* here we can initialize the layout */ - return hl_layout_init(&hl_if); -} - -static int hl_interface_quit(void) -{ - LOG_DEBUG("hl_interface_quit"); - - if (hl_if.layout->api->close) - hl_if.layout->api->close(hl_if.handle); - - return ERROR_OK; -} - -static int hl_interface_execute_queue(void) -{ - LOG_DEBUG("hl_interface_execute_queue: ignored"); - - return ERROR_OK; -} - -int hl_interface_init_reset(void) -{ - /* incase the adapter has not already handled asserting srst - * we will attempt it again */ - if (hl_if.param.connect_under_reset) { - jtag_add_reset(0, 1); - hl_if.layout->api->assert_srst(hl_if.handle, 0); - } else { - jtag_add_reset(0, 0); - } - - return ERROR_OK; -} - -static int hl_interface_khz(int khz, int *jtag_speed) -{ - if (hl_if.layout->api->speed == NULL) - return ERROR_OK; - - *jtag_speed = hl_if.layout->api->speed(hl_if.handle, khz, true); - return ERROR_OK; -} - -static int hl_interface_speed_div(int speed, int *khz) -{ - *khz = speed; - return ERROR_OK; -} - -static int hl_interface_speed(int speed) -{ - if (hl_if.layout->api->speed == NULL) - return ERROR_OK; - - if (hl_if.handle == NULL) { - /* pass speed as initial param as interface not open yet */ - hl_if.param.initial_interface_speed = speed; - return ERROR_OK; - } - - hl_if.layout->api->speed(hl_if.handle, speed, false); - - return ERROR_OK; -} - -int hl_interface_override_target(const char **targetname) -{ - if (hl_if.layout->api->override_target) { - if (hl_if.layout->api->override_target(*targetname)) { - *targetname = "hla_target"; - return ERROR_OK; - } else - return ERROR_FAIL; - } - return ERROR_FAIL; -} - -int hl_interface_config_trace(bool enabled, enum tpio_pin_protocol pin_protocol, - uint32_t port_size, unsigned int *trace_freq) -{ - if (hl_if.layout->api->config_trace) - return hl_if.layout->api->config_trace(hl_if.handle, enabled, pin_protocol, - port_size, trace_freq); - else if (enabled) { - LOG_ERROR("The selected interface does not support tracing"); - return ERROR_FAIL; - } - - return ERROR_OK; -} - -int hl_interface_poll_trace(uint8_t *buf, size_t *size) -{ - if (hl_if.layout->api->poll_trace) - return hl_if.layout->api->poll_trace(hl_if.handle, buf, size); - - return ERROR_FAIL; -} - -COMMAND_HANDLER(hl_interface_handle_device_desc_command) -{ - LOG_DEBUG("hl_interface_handle_device_desc_command"); - - if (CMD_ARGC == 1) { - hl_if.param.device_desc = strdup(CMD_ARGV[0]); - } else { - LOG_ERROR("expected exactly one argument to hl_device_desc "); - } - - return ERROR_OK; -} - -COMMAND_HANDLER(hl_interface_handle_serial_command) -{ - LOG_DEBUG("hl_interface_handle_serial_command"); - - if (CMD_ARGC == 1) { - hl_if.param.serial = strdup(CMD_ARGV[0]); - } else { - LOG_ERROR("expected exactly one argument to hl_serial "); - } - - return ERROR_OK; -} - -COMMAND_HANDLER(hl_interface_handle_layout_command) -{ - LOG_DEBUG("hl_interface_handle_layout_command"); - - if (CMD_ARGC != 1) { - LOG_ERROR("Need exactly one argument to stlink_layout"); - return ERROR_COMMAND_SYNTAX_ERROR; - } - - if (hl_if.layout) { - LOG_ERROR("already specified hl_layout %s", - hl_if.layout->name); - return (strcmp(hl_if.layout->name, CMD_ARGV[0]) != 0) - ? ERROR_FAIL : ERROR_OK; - } - - for (const struct hl_layout *l = hl_layout_get_list(); l->name; - l++) { - if (strcmp(l->name, CMD_ARGV[0]) == 0) { - hl_if.layout = l; - return ERROR_OK; - } - } - - LOG_ERROR("No adapter layout '%s' found", CMD_ARGV[0]); - return ERROR_FAIL; -} - -COMMAND_HANDLER(hl_interface_handle_vid_pid_command) -{ - LOG_DEBUG("hl_interface_handle_vid_pid_command"); - - if (CMD_ARGC != 2) { - LOG_WARNING("ignoring extra IDs in hl_vid_pid (maximum is 1 pair)"); - return ERROR_COMMAND_SYNTAX_ERROR; - } - - COMMAND_PARSE_NUMBER(u16, CMD_ARGV[0], hl_if.param.vid); - COMMAND_PARSE_NUMBER(u16, CMD_ARGV[1], hl_if.param.pid); - - return ERROR_OK; -} - -COMMAND_HANDLER(interface_handle_hla_command) -{ - if (CMD_ARGC != 1) - return ERROR_COMMAND_SYNTAX_ERROR; - - if (!hl_if.layout->api->custom_command) { - LOG_ERROR("The selected adapter doesn't support custom commands"); - return ERROR_FAIL; - } - - hl_if.layout->api->custom_command(hl_if.handle, CMD_ARGV[0]); - - return ERROR_OK; -} - -static const struct command_registration hl_interface_command_handlers[] = { - { - .name = "hla_device_desc", - .handler = &hl_interface_handle_device_desc_command, - .mode = COMMAND_CONFIG, - .help = "set the a device description of the adapter", - .usage = "description_string", - }, - { - .name = "hla_serial", - .handler = &hl_interface_handle_serial_command, - .mode = COMMAND_CONFIG, - .help = "set the serial number of the adapter", - .usage = "serial_string", - }, - { - .name = "hla_layout", - .handler = &hl_interface_handle_layout_command, - .mode = COMMAND_CONFIG, - .help = "set the layout of the adapter", - .usage = "layout_name", - }, - { - .name = "hla_vid_pid", - .handler = &hl_interface_handle_vid_pid_command, - .mode = COMMAND_CONFIG, - .help = "the vendor and product ID of the adapter", - .usage = "(vid pid)* ", - }, - { - .name = "hla_command", - .handler = &interface_handle_hla_command, - .mode = COMMAND_EXEC, - .help = "execute a custom adapter-specific command", - .usage = "hla_command ", - }, - COMMAND_REGISTRATION_DONE -}; - -struct jtag_interface hl_interface = { - .name = "hla", - .supported = 0, - .commands = hl_interface_command_handlers, - .transports = hl_transports, - .init = hl_interface_init, - .quit = hl_interface_quit, - .execute_queue = hl_interface_execute_queue, - .speed = &hl_interface_speed, - .khz = &hl_interface_khz, - .speed_div = &hl_interface_speed_div, - .config_trace = &hl_interface_config_trace, - .poll_trace = &hl_interface_poll_trace, -}; diff --git a/src/jtag/hla/hla_interface.h b/src/jtag/hla/hla_interface.h deleted file mode 100644 index 0992d1cad..000000000 --- a/src/jtag/hla/hla_interface.h +++ /dev/null @@ -1,68 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2011 by Mathias Kuester * - * Mathias Kuester * - * * - * Copyright (C) 2012 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifndef OPENOCD_JTAG_HLA_HLA_INTERFACE_H -#define OPENOCD_JTAG_HLA_HLA_INTERFACE_H - -/** */ -struct target; -/** */ -enum e_hl_transports; -/** */ -extern const char *hl_transports[]; - -struct hl_interface_param_s { - /** */ - const char *device_desc; - /** */ - const char *serial; - /** */ - uint16_t vid; - /** */ - uint16_t pid; - /** */ - unsigned api; - /** */ - enum hl_transports transport; - /** */ - bool connect_under_reset; - /** Initial interface clock clock speed */ - int initial_interface_speed; -}; - -struct hl_interface_s { - /** */ - struct hl_interface_param_s param; - /** */ - const struct hl_layout *layout; - /** */ - void *handle; -}; - -/** */ -int hl_interface_open(enum hl_transports tr); -/** */ - -int hl_interface_init_target(struct target *t); -int hl_interface_init_reset(void); -int hl_interface_override_target(const char **targetname); - -#endif /* OPENOCD_JTAG_HLA_HLA_INTERFACE_H */ diff --git a/src/jtag/hla/hla_layout.c b/src/jtag/hla/hla_layout.c deleted file mode 100644 index c5e35182d..000000000 --- a/src/jtag/hla/hla_layout.c +++ /dev/null @@ -1,90 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2011 by Mathias Kuester * - * Mathias Kuester * - * * - * Copyright (C) 2012 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -/* project specific includes */ -#include -#include -#include - -#include -#include -#include -#include - -static int hl_layout_open(struct hl_interface_s *adapter) -{ - int res; - - LOG_DEBUG("hl_layout_open"); - - adapter->handle = NULL; - - res = adapter->layout->api->open(&adapter->param, &adapter->handle); - - if (res != ERROR_OK) { - LOG_DEBUG("failed"); - return res; - } - - return ERROR_OK; -} - -static int hl_layout_close(struct hl_interface_s *adapter) -{ - return ERROR_OK; -} - -static const struct hl_layout hl_layouts[] = { - { - .name = "stlink", - .open = hl_layout_open, - .close = hl_layout_close, - .api = &stlink_usb_layout_api, - }, - { - .name = "ti-icdi", - .open = hl_layout_open, - .close = hl_layout_close, - .api = &icdi_usb_layout_api, - }, - {.name = NULL, /* END OF TABLE */ }, -}; - -/** */ -const struct hl_layout *hl_layout_get_list(void) -{ - return hl_layouts; -} - -int hl_layout_init(struct hl_interface_s *adapter) -{ - LOG_DEBUG("hl_layout_init"); - - if (adapter->layout == NULL) { - LOG_ERROR("no layout specified"); - return ERROR_FAIL; - } - return ERROR_OK; -} diff --git a/src/jtag/hla/hla_layout.h b/src/jtag/hla/hla_layout.h deleted file mode 100644 index 40c1321ba..000000000 --- a/src/jtag/hla/hla_layout.h +++ /dev/null @@ -1,128 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2011 by Mathias Kuester * - * Mathias Kuester * - * * - * Copyright (C) 2012 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifndef OPENOCD_JTAG_HLA_HLA_LAYOUT_H -#define OPENOCD_JTAG_HLA_HLA_LAYOUT_H - -#include - -/** */ -struct hl_interface_s; -struct hl_interface_param_s; - -/** */ -extern struct hl_layout_api_s stlink_usb_layout_api; -extern struct hl_layout_api_s icdi_usb_layout_api; - -/** */ -struct hl_layout_api_s { - /** */ - int (*open) (struct hl_interface_param_s *param, void **handle); - /** */ - int (*close) (void *handle); - /** */ - int (*reset) (void *handle); - /** */ - int (*assert_srst) (void *handle, int srst); - /** */ - int (*run) (void *handle); - /** */ - int (*halt) (void *handle); - /** */ - int (*step) (void *handle); - /** */ - int (*read_regs) (void *handle); - /** */ - int (*read_reg) (void *handle, int num, uint32_t *val); - /** */ - int (*write_reg) (void *handle, int num, uint32_t val); - /** */ - int (*read_mem) (void *handle, uint32_t addr, uint32_t size, - uint32_t count, uint8_t *buffer); - /** */ - int (*write_mem) (void *handle, uint32_t addr, uint32_t size, - uint32_t count, const uint8_t *buffer); - /** */ - int (*write_debug_reg) (void *handle, uint32_t addr, uint32_t val); - /** - * Read the idcode of the target connected to the adapter - * - * If the adapter doesn't support idcode retrieval, this callback should - * store 0 to indicate a wildcard match. - * - * @param handle A pointer to the device-specific handle - * @param idcode Storage for the detected idcode - * @returns ERROR_OK on success, or an error code on failure. - */ - int (*idcode) (void *handle, uint32_t *idcode); - /** */ - int (*override_target) (const char *targetname); - /** */ - int (*custom_command) (void *handle, const char *command); - /** */ - int (*speed)(void *handle, int khz, bool query); - /** - * Configure trace parameters for the adapter - * - * @param handle A handle to adapter - * @param enabled Whether to enable trace - * @param pin_protocol Configured pin protocol - * @param port_size Trace port width for sync mode - * @param trace_freq A pointer to the configured trace - * frequency; if it points to 0, the adapter driver must write - * its maximum supported rate there - * @returns ERROR_OK on success, an error code on failure. - */ - int (*config_trace)(void *handle, bool enabled, enum tpio_pin_protocol pin_protocol, - uint32_t port_size, unsigned int *trace_freq); - /** - * Poll for new trace data - * - * @param handle A handle to adapter - * @param buf A pointer to buffer to store received data - * @param size A pointer to buffer size; must be filled with - * the actual amount of bytes written - * - * @returns ERROR_OK on success, an error code on failure. - */ - int (*poll_trace)(void *handle, uint8_t *buf, size_t *size); - /** */ - enum target_state (*state) (void *fd); -}; - -/** */ -struct hl_layout { - /** */ - char *name; - /** */ - int (*open) (struct hl_interface_s *adapter); - /** */ - int (*close) (struct hl_interface_s *adapter); - /** */ - struct hl_layout_api_s *api; -}; - -/** */ -const struct hl_layout *hl_layout_get_list(void); -/** */ -int hl_layout_init(struct hl_interface_s *adapter); - -#endif /* OPENOCD_JTAG_HLA_HLA_LAYOUT_H */ diff --git a/src/jtag/hla/hla_tcl.c b/src/jtag/hla/hla_tcl.c deleted file mode 100644 index 9378427b0..000000000 --- a/src/jtag/hla/hla_tcl.c +++ /dev/null @@ -1,157 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2011 by Mathias Kuester * - * Mathias Kuester * - * * - * Copyright (C) 2012 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -/* project specific includes */ -#include -#include -#include - -static int jim_newtap_expected_id(Jim_Nvp *n, Jim_GetOptInfo *goi, - struct jtag_tap *pTap) -{ - jim_wide w; - int e = Jim_GetOpt_Wide(goi, &w); - if (e != JIM_OK) { - Jim_SetResultFormatted(goi->interp, "option: %s bad parameter", - n->name); - return e; - } - - unsigned expected_len = sizeof(uint32_t) * pTap->expected_ids_cnt; - uint32_t *new_expected_ids = malloc(expected_len + sizeof(uint32_t)); - if (new_expected_ids == NULL) { - Jim_SetResultFormatted(goi->interp, "no memory"); - return JIM_ERR; - } - - memcpy(new_expected_ids, pTap->expected_ids, expected_len); - - new_expected_ids[pTap->expected_ids_cnt] = w; - - free(pTap->expected_ids); - pTap->expected_ids = new_expected_ids; - pTap->expected_ids_cnt++; - - return JIM_OK; -} - -#define NTAP_OPT_IRLEN 0 -#define NTAP_OPT_IRMASK 1 -#define NTAP_OPT_IRCAPTURE 2 -#define NTAP_OPT_ENABLED 3 -#define NTAP_OPT_DISABLED 4 -#define NTAP_OPT_EXPECTED_ID 5 -#define NTAP_OPT_VERSION 6 - -static int jim_hl_newtap_cmd(Jim_GetOptInfo *goi) -{ - struct jtag_tap *pTap; - int x; - int e; - Jim_Nvp *n; - char *cp; - const Jim_Nvp opts[] = { - { .name = "-irlen", .value = NTAP_OPT_IRLEN }, - { .name = "-irmask", .value = NTAP_OPT_IRMASK }, - { .name = "-ircapture", .value = NTAP_OPT_IRCAPTURE }, - { .name = "-enable", .value = NTAP_OPT_ENABLED }, - { .name = "-disable", .value = NTAP_OPT_DISABLED }, - { .name = "-expected-id", .value = NTAP_OPT_EXPECTED_ID }, - { .name = "-ignore-version", .value = NTAP_OPT_VERSION }, - { .name = NULL, .value = -1}, - }; - - pTap = calloc(1, sizeof(struct jtag_tap)); - if (!pTap) { - Jim_SetResultFormatted(goi->interp, "no memory"); - return JIM_ERR; - } - - /* - * we expect CHIP + TAP + OPTIONS - * */ - if (goi->argc < 3) { - Jim_SetResultFormatted(goi->interp, - "Missing CHIP TAP OPTIONS ...."); - free(pTap); - return JIM_ERR; - } - - 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; - cp = malloc(x); - sprintf(cp, "%s.%s", pTap->chip, pTap->tapname); - pTap->dotted_name = cp; - - LOG_DEBUG("Creating New Tap, Chip: %s, Tap: %s, Dotted: %s, %d params", - pTap->chip, pTap->tapname, pTap->dotted_name, goi->argc); - - while (goi->argc) { - e = Jim_GetOpt_Nvp(goi, opts, &n); - if (e != JIM_OK) { - Jim_GetOpt_NvpUnknown(goi, opts, 0); - free(cp); - free(pTap); - return e; - } - LOG_DEBUG("Processing option: %s", n->name); - switch (n->value) { - case NTAP_OPT_EXPECTED_ID: - e = jim_newtap_expected_id(n, goi, pTap); - if (JIM_OK != e) { - free(cp); - free(pTap); - return e; - } - break; - case NTAP_OPT_IRLEN: - case NTAP_OPT_IRMASK: - case NTAP_OPT_IRCAPTURE: - /* dummy read to ignore the next argument */ - Jim_GetOpt_Wide(goi, NULL); - break; - } /* switch (n->value) */ - } /* while (goi->argc) */ - - /* default is enabled-after-reset */ - pTap->enabled = !pTap->disabled_after_reset; - - jtag_tap_init(pTap); - return JIM_OK; -} - -int jim_hl_newtap(Jim_Interp *interp, int argc, Jim_Obj * const *argv) -{ - Jim_GetOptInfo goi; - Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1); - return jim_hl_newtap_cmd(&goi); -} diff --git a/src/jtag/hla/hla_tcl.h b/src/jtag/hla/hla_tcl.h deleted file mode 100644 index ac00add51..000000000 --- a/src/jtag/hla/hla_tcl.h +++ /dev/null @@ -1,28 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2011 by Mathias Kuester * - * Mathias Kuester * - * * - * Copyright (C) 2012 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#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 /* OPENOCD_JTAG_HLA_HLA_TCL_H */ diff --git a/src/jtag/hla/hla_transport.c b/src/jtag/hla/hla_transport.c deleted file mode 100644 index 5a5671db6..000000000 --- a/src/jtag/hla/hla_transport.c +++ /dev/null @@ -1,235 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2011 by Mathias Kuester * - * Mathias Kuester * - * * - * Copyright (C) 2012 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -/* project specific includes */ -#include -#include -#include -#include -#include -#include -#include -#include - -COMMAND_HANDLER(hl_transport_jtag_command) -{ - LOG_DEBUG("hl_transport_jtag_command"); - - return ERROR_OK; -} - -COMMAND_HANDLER(hl_transport_reset_command) -{ - return hl_interface_init_reset(); -} - -static const struct command_registration -hl_transport_stlink_subcommand_handlers[] = { - { - .name = "newtap", - .mode = COMMAND_CONFIG, - .jim_handler = jim_hl_newtap, - .help = "Create a new TAP instance named basename.tap_type, " - "and appends it to the scan chain.", - .usage = "basename tap_type '-irlen' count " - "['-expected_id' number] ", - }, - - COMMAND_REGISTRATION_DONE -}; - -static const struct command_registration -hl_transport_jtag_subcommand_handlers[] = { - { - .name = "init", - .mode = COMMAND_ANY, - .handler = hl_transport_jtag_command, - .usage = "" - }, - { - .name = "arp_init", - .mode = COMMAND_ANY, - .handler = hl_transport_jtag_command, - .usage = "" - }, - { - .name = "arp_init-reset", - .mode = COMMAND_ANY, - .handler = hl_transport_reset_command, - .usage = "" - }, - { - .name = "tapisenabled", - .mode = COMMAND_EXEC, - .jim_handler = jim_jtag_tap_enabler, - }, - { - .name = "tapenable", - .mode = COMMAND_EXEC, - .jim_handler = jim_jtag_tap_enabler, - }, - { - .name = "tapdisable", - .mode = COMMAND_EXEC, - .handler = hl_transport_jtag_command, - .usage = "", - }, - { - .name = "configure", - .mode = COMMAND_EXEC, - .handler = hl_transport_jtag_command, - .usage = "", - }, - { - .name = "cget", - .mode = COMMAND_EXEC, - .jim_handler = jim_jtag_configure, - }, - { - .name = "names", - .mode = COMMAND_ANY, - .handler = hl_transport_jtag_command, - .usage = "", - }, - - COMMAND_REGISTRATION_DONE -}; - -static const struct command_registration stlink_transport_command_handlers[] = { - - { - .name = "hla", - .mode = COMMAND_ANY, - .help = "perform hl adapter actions", - .usage = "", - .chain = hl_transport_stlink_subcommand_handlers, - }, - { - .name = "jtag", - .mode = COMMAND_ANY, - .usage = "", - .chain = hl_transport_jtag_subcommand_handlers, - }, - { - .name = "jtag_ntrst_delay", - .mode = COMMAND_ANY, - .handler = hl_transport_jtag_command, - .usage = "", - }, - COMMAND_REGISTRATION_DONE -}; - -static int hl_transport_register_commands(struct command_context *cmd_ctx) -{ - return register_commands(cmd_ctx, NULL, - stlink_transport_command_handlers); -} - -static int hl_transport_init(struct command_context *cmd_ctx) -{ - LOG_DEBUG("hl_transport_init"); - struct target *t = get_current_target(cmd_ctx); - struct transport *transport; - enum hl_transports tr; - - if (!t) { - LOG_ERROR("no current target"); - return ERROR_FAIL; - } - - transport = get_current_transport(); - - if (!transport) { - LOG_ERROR("no transport selected"); - return ERROR_FAIL; - } - - LOG_DEBUG("current transport %s", transport->name); - - /* get selected transport as enum */ - tr = HL_TRANSPORT_UNKNOWN; - - if (strcmp(transport->name, "hla_swd") == 0) - tr = HL_TRANSPORT_SWD; - else if (strcmp(transport->name, "hla_jtag") == 0) - tr = HL_TRANSPORT_JTAG; - else if (strcmp(transport->name, "stlink_swim") == 0) - tr = HL_TRANSPORT_SWIM; - - int retval = hl_interface_open(tr); - - if (retval != ERROR_OK) - return retval; - - return hl_interface_init_target(t); -} - -static int hl_transport_select(struct command_context *ctx) -{ - LOG_DEBUG("hl_transport_select"); - - int retval; - - /* NOTE: interface init must already have been done. - * That works with only C code ... no Tcl glue required. - */ - - retval = hl_transport_register_commands(ctx); - - if (retval != ERROR_OK) - return retval; - - return ERROR_OK; -} - -static struct transport hl_swd_transport = { - .name = "hla_swd", - .select = hl_transport_select, - .init = hl_transport_init, - .override_target = hl_interface_override_target, -}; - -static struct transport hl_jtag_transport = { - .name = "hla_jtag", - .select = hl_transport_select, - .init = hl_transport_init, - .override_target = hl_interface_override_target, -}; - -static struct transport stlink_swim_transport = { - .name = "stlink_swim", - .select = hl_transport_select, - .init = hl_transport_init, -}; - -const char *hl_transports[] = { "hla_swd", "hla_jtag", "stlink_swim", NULL }; - -static void hl_constructor(void) __attribute__ ((constructor)); -static void hl_constructor(void) -{ - transport_register(&hl_swd_transport); - transport_register(&hl_jtag_transport); - transport_register(&stlink_swim_transport); -} diff --git a/src/jtag/hla/hla_transport.h b/src/jtag/hla/hla_transport.h deleted file mode 100644 index 07eb751e2..000000000 --- a/src/jtag/hla/hla_transport.h +++ /dev/null @@ -1,32 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2011 by Mathias Kuester * - * Mathias Kuester * - * * - * Copyright (C) 2012 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifndef OPENOCD_JTAG_HLA_HLA_TRANSPORT_H -#define OPENOCD_JTAG_HLA_HLA_TRANSPORT_H - -enum hl_transports { - HL_TRANSPORT_UNKNOWN = 0, - HL_TRANSPORT_SWD, - HL_TRANSPORT_JTAG, - HL_TRANSPORT_SWIM -}; - -#endif /* OPENOCD_JTAG_HLA_HLA_TRANSPORT_H */ diff --git a/src/jtag/interface.c b/src/jtag/interface.c deleted file mode 100644 index e12b2aebb..000000000 --- a/src/jtag/interface.c +++ /dev/null @@ -1,468 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * Copyright (C) 2007,2008 Øyvind Harboe * - * oyvind.harboe@zylin.com * - * * - * Copyright (C) 2009 SoftPLC Corporation * - * http://softplc.com * - * dick@softplc.com * - * * - * Copyright (C) 2009 Zachary T Welch * - * zw@superlucidity.net * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "jtag.h" -#include "interface.h" - -/** - * @see tap_set_state() and tap_get_state() accessors. - * Actual name is not important since accessors hide it. - */ -static tap_state_t state_follower = TAP_RESET; - -void tap_set_state_impl(tap_state_t new_state) -{ - /* this is the state we think the TAPs are in now, was cur_state */ - state_follower = new_state; -} - -tap_state_t tap_get_state() -{ - return state_follower; -} - -/** - * @see tap_set_end_state() and tap_get_end_state() accessors. - * Actual name is not important because accessors hide it. - */ -static tap_state_t end_state_follower = TAP_RESET; - -void tap_set_end_state(tap_state_t new_end_state) -{ - /* this is the state we think the TAPs will be in at completion of the - * current TAP operation, was end_state - */ - end_state_follower = new_end_state; -} - -tap_state_t tap_get_end_state() -{ - return end_state_follower; -} - -int tap_move_ndx(tap_state_t astate) -{ - /* given a stable state, return the index into the tms_seqs[] - * array within tap_get_tms_path() - */ - - int ndx; - - switch (astate) { - case TAP_RESET: - ndx = 0; - break; - case TAP_IDLE: - ndx = 1; - break; - case TAP_DRSHIFT: - ndx = 2; - break; - case TAP_DRPAUSE: - ndx = 3; - break; - case TAP_IRSHIFT: - ndx = 4; - break; - case TAP_IRPAUSE: - ndx = 5; - break; - default: - LOG_ERROR("FATAL: unstable state \"%s\" in tap_move_ndx()", - tap_state_name(astate)); - exit(1); - } - - return ndx; -} - -/* tap_move[i][j]: tap movement command to go from state i to state j - * encodings of i and j are what tap_move_ndx() reports. - * - * DRSHIFT->DRSHIFT and IRSHIFT->IRSHIFT have to be caught in interface specific code - */ -struct tms_sequences { - uint8_t bits; - uint8_t bit_count; -}; - -/* - * These macros allow us to specify TMS state transitions by bits rather than hex bytes. - * Read the bits from LSBit first to MSBit last (right-to-left). - */ -#define HEX__(n) 0x##n##LU - -#define B8__(x) \ - ((((x) & 0x0000000FLU) ? (1 << 0) : 0) \ - +(((x) & 0x000000F0LU) ? (1 << 1) : 0) \ - +(((x) & 0x00000F00LU) ? (1 << 2) : 0) \ - +(((x) & 0x0000F000LU) ? (1 << 3) : 0) \ - +(((x) & 0x000F0000LU) ? (1 << 4) : 0) \ - +(((x) & 0x00F00000LU) ? (1 << 5) : 0) \ - +(((x) & 0x0F000000LU) ? (1 << 6) : 0) \ - +(((x) & 0xF0000000LU) ? (1 << 7) : 0)) - -#define B8(bits, count) {((uint8_t)B8__(HEX__(bits))), (count)} - -static const struct tms_sequences old_tms_seqs[6][6] = { /* [from_state_ndx][to_state_ndx] */ - /* value clocked to TMS to move from one of six stable states to another. - * N.B. OOCD clocks TMS from LSB first, so read these right-to-left. - * N.B. Reset only needs to be 0b11111, but in JLink an even byte of 1's is more stable. - * These extra ones cause no TAP state problem, because we go into reset and stay in reset. - */ - -/* to state: */ -/* RESET IDLE DRSHIFT DRPAUSE IRSHIFT IRPAUSE */ /* from state: */ -{B8(1111111, 7), B8(0000000, 7), B8(0010111, 7), B8(0001010, 7), B8(0011011, 7), B8(0010110, 7)},/* RESET */ -{B8(1111111, 7), B8(0000000, 7), B8(0100101, 7), B8(0000101, 7), B8(0101011, 7), B8(0001011, 7)},/* IDLE */ -{B8(1111111, 7), B8(0110001, 7), B8(0000000, 7), B8(0000001, 7), B8(0001111, 7), B8(0101111, 7)},/* DRSHIFT */ -{B8(1111111, 7), B8(0110000, 7), B8(0100000, 7), B8(0010111, 7), B8(0011110, 7), B8(0101111, 7)},/* DRPAUSE */ -{B8(1111111, 7), B8(0110001, 7), B8(0000111, 7), B8(0010111, 7), B8(0000000, 7), B8(0000001, 7)},/* IRSHIFT */ -{B8(1111111, 7), B8(0110000, 7), B8(0011100, 7), B8(0010111, 7), B8(0011110, 7), B8(0101111, 7)},/* IRPAUSE */ -}; - -static const struct tms_sequences short_tms_seqs[6][6] = { /* [from_state_ndx][to_state_ndx] */ - /* this is the table submitted by Jeff Williams on 3/30/2009 with this comment: - - OK, I added Peter's version of the state table, and it works OK for - me on MC1322x. I've recreated the jlink portion of patch with this - new state table. His changes to my state table are pretty minor in - terms of total transitions, but Peter feels that his version fixes - some long-standing problems. - Jeff - - I added the bit count into the table, reduced RESET column to 7 bits from 8. - Dick - - state specific comments: - ------------------------ - *->RESET tried the 5 bit reset and it gave me problems, 7 bits seems to - work better on ARM9 with ft2232 driver. (Dick) - - RESET->DRSHIFT add 1 extra clock cycles in the RESET state before advancing. - needed on ARM9 with ft2232 driver. (Dick) - (For a total of *THREE* extra clocks in RESET; NOP.) - - RESET->IRSHIFT add 1 extra clock cycles in the RESET state before advancing. - needed on ARM9 with ft2232 driver. (Dick) - (For a total of *TWO* extra clocks in RESET; NOP.) - - RESET->* always adds one or more clocks in the target state, - which should be NOPS; except shift states which (as - noted above) add those clocks in RESET. - - The X-to-X transitions always add clocks; from *SHIFT, they go - via IDLE and thus *DO HAVE SIDE EFFECTS* (capture and update). -*/ - -/* to state: */ -/* RESET IDLE DRSHIFT DRPAUSE IRSHIFT IRPAUSE */ /* from state: */ -{B8(1111111, 7), B8(0000000, 7), B8(0010111, 7), B8(0001010, 7), B8(0011011, 7), B8(0010110, 7)}, /* RESET */ -{B8(1111111, 7), B8(0000000, 7), B8(001, 3), B8(0101, 4), B8(0011, 4), B8(01011, 5)}, /* IDLE */ -{B8(1111111, 7), B8(011, 3), B8(00111, 5), B8(01, 2), B8(001111, 6), B8(0101111, 7)}, /* DRSHIFT */ -{B8(1111111, 7), B8(011, 3), B8(01, 2), B8(0, 1), B8(001111, 6), B8(0101111, 7)}, /* DRPAUSE */ -{B8(1111111, 7), B8(011, 3), B8(00111, 5), B8(010111, 6), B8(001111, 6), B8(01, 2)}, /* IRSHIFT */ -{B8(1111111, 7), B8(011, 3), B8(00111, 5), B8(010111, 6), B8(01, 2), B8(0, 1)} /* IRPAUSE */ -}; - -typedef const struct tms_sequences tms_table[6][6]; - -static tms_table *tms_seqs = &short_tms_seqs; - -int tap_get_tms_path(tap_state_t from, tap_state_t to) -{ - return (*tms_seqs)[tap_move_ndx(from)][tap_move_ndx(to)].bits; -} - -int tap_get_tms_path_len(tap_state_t from, tap_state_t to) -{ - return (*tms_seqs)[tap_move_ndx(from)][tap_move_ndx(to)].bit_count; -} - -bool tap_is_state_stable(tap_state_t astate) -{ - bool is_stable; - - /* A switch () is used because it is symbol dependent - * (not value dependent like an array), and can also check bounds. - */ - switch (astate) { - case TAP_RESET: - case TAP_IDLE: - case TAP_DRSHIFT: - case TAP_DRPAUSE: - case TAP_IRSHIFT: - case TAP_IRPAUSE: - is_stable = true; - break; - default: - is_stable = false; - } - - return is_stable; -} - -tap_state_t tap_state_transition(tap_state_t cur_state, bool tms) -{ - tap_state_t new_state; - - /* A switch is used because it is symbol dependent and not value dependent - * like an array. Also it can check for out of range conditions. - */ - - if (tms) { - switch (cur_state) { - case TAP_RESET: - new_state = cur_state; - break; - case TAP_IDLE: - case TAP_DRUPDATE: - case TAP_IRUPDATE: - new_state = TAP_DRSELECT; - break; - case TAP_DRSELECT: - new_state = TAP_IRSELECT; - break; - case TAP_DRCAPTURE: - case TAP_DRSHIFT: - new_state = TAP_DREXIT1; - break; - case TAP_DREXIT1: - case TAP_DREXIT2: - new_state = TAP_DRUPDATE; - break; - case TAP_DRPAUSE: - new_state = TAP_DREXIT2; - break; - case TAP_IRSELECT: - new_state = TAP_RESET; - break; - case TAP_IRCAPTURE: - case TAP_IRSHIFT: - new_state = TAP_IREXIT1; - break; - case TAP_IREXIT1: - case TAP_IREXIT2: - new_state = TAP_IRUPDATE; - break; - case TAP_IRPAUSE: - new_state = TAP_IREXIT2; - break; - default: - LOG_ERROR("fatal: invalid argument cur_state=%d", cur_state); - exit(1); - break; - } - } else { - switch (cur_state) { - case TAP_RESET: - case TAP_IDLE: - case TAP_DRUPDATE: - case TAP_IRUPDATE: - new_state = TAP_IDLE; - break; - case TAP_DRSELECT: - new_state = TAP_DRCAPTURE; - break; - case TAP_DRCAPTURE: - case TAP_DRSHIFT: - case TAP_DREXIT2: - new_state = TAP_DRSHIFT; - break; - case TAP_DREXIT1: - case TAP_DRPAUSE: - new_state = TAP_DRPAUSE; - break; - case TAP_IRSELECT: - new_state = TAP_IRCAPTURE; - break; - case TAP_IRCAPTURE: - case TAP_IRSHIFT: - case TAP_IREXIT2: - new_state = TAP_IRSHIFT; - break; - case TAP_IREXIT1: - case TAP_IRPAUSE: - new_state = TAP_IRPAUSE; - break; - default: - LOG_ERROR("fatal: invalid argument cur_state=%d", cur_state); - exit(1); - break; - } - } - - return new_state; -} - -/* NOTE: do not change these state names. They're documented, - * and we rely on them to match SVF input (except for "RUN/IDLE"). - */ -static const struct name_mapping { - enum tap_state symbol; - const char *name; -} tap_name_mapping[] = { - { TAP_RESET, "RESET", }, - { TAP_IDLE, "RUN/IDLE", }, - { TAP_DRSELECT, "DRSELECT", }, - { TAP_DRCAPTURE, "DRCAPTURE", }, - { TAP_DRSHIFT, "DRSHIFT", }, - { TAP_DREXIT1, "DREXIT1", }, - { TAP_DRPAUSE, "DRPAUSE", }, - { TAP_DREXIT2, "DREXIT2", }, - { TAP_DRUPDATE, "DRUPDATE", }, - { TAP_IRSELECT, "IRSELECT", }, - { TAP_IRCAPTURE, "IRCAPTURE", }, - { TAP_IRSHIFT, "IRSHIFT", }, - { TAP_IREXIT1, "IREXIT1", }, - { TAP_IRPAUSE, "IRPAUSE", }, - { TAP_IREXIT2, "IREXIT2", }, - { TAP_IRUPDATE, "IRUPDATE", }, - - /* only for input: accept standard SVF name */ - { TAP_IDLE, "IDLE", }, -}; - -const char *tap_state_name(tap_state_t state) -{ - unsigned i; - - for (i = 0; i < ARRAY_SIZE(tap_name_mapping); i++) { - if (tap_name_mapping[i].symbol == state) - return tap_name_mapping[i].name; - } - return "???"; -} - -tap_state_t tap_state_by_name(const char *name) -{ - unsigned i; - - for (i = 0; i < ARRAY_SIZE(tap_name_mapping); i++) { - /* be nice to the human */ - if (strcasecmp(name, tap_name_mapping[i].name) == 0) - return tap_name_mapping[i].symbol; - } - /* not found */ - return TAP_INVALID; -} - -#ifdef _DEBUG_JTAG_IO_ - -#define JTAG_DEBUG_STATE_APPEND(buf, len, bit) \ - do { buf[len] = bit ? '1' : '0'; } while (0) -#define JTAG_DEBUG_STATE_PRINT(a, b, astr, bstr) \ - DEBUG_JTAG_IO("TAP/SM: %9s -> %5s\tTMS: %s\tTDI: %s", \ - tap_state_name(a), tap_state_name(b), astr, bstr) - -tap_state_t jtag_debug_state_machine(const void *tms_buf, const void *tdi_buf, - unsigned tap_bits, tap_state_t next_state) -{ - const uint8_t *tms_buffer; - const uint8_t *tdi_buffer; - unsigned tap_bytes; - unsigned cur_byte; - unsigned cur_bit; - - unsigned tap_out_bits; - char tms_str[33]; - char tdi_str[33]; - - tap_state_t last_state; - - /* set startstate (and possibly last, if tap_bits == 0) */ - last_state = next_state; - DEBUG_JTAG_IO("TAP/SM: START state: %s", tap_state_name(next_state)); - - tms_buffer = (const uint8_t *)tms_buf; - tdi_buffer = (const uint8_t *)tdi_buf; - - tap_bytes = DIV_ROUND_UP(tap_bits, 8); - DEBUG_JTAG_IO("TAP/SM: TMS bits: %u (bytes: %u)", tap_bits, tap_bytes); - - tap_out_bits = 0; - for (cur_byte = 0; cur_byte < tap_bytes; cur_byte++) { - for (cur_bit = 0; cur_bit < 8; cur_bit++) { - /* make sure we do not run off the end of the buffers */ - unsigned tap_bit = cur_byte * 8 + cur_bit; - if (tap_bit == tap_bits) - break; - - /* check and save TMS bit */ - tap_bit = !!(tms_buffer[cur_byte] & (1 << cur_bit)); - JTAG_DEBUG_STATE_APPEND(tms_str, tap_out_bits, tap_bit); - - /* use TMS bit to find the next TAP state */ - next_state = tap_state_transition(last_state, tap_bit); - - /* check and store TDI bit */ - tap_bit = !!(tdi_buffer[cur_byte] & (1 << cur_bit)); - JTAG_DEBUG_STATE_APPEND(tdi_str, tap_out_bits, tap_bit); - - /* increment TAP bits */ - tap_out_bits++; - - /* Only show TDO bits on state transitions, or */ - /* after some number of bits in the same state. */ - if ((next_state == last_state) && (tap_out_bits < 32)) - continue; - - /* terminate strings and display state transition */ - tms_str[tap_out_bits] = tdi_str[tap_out_bits] = 0; - JTAG_DEBUG_STATE_PRINT(last_state, next_state, tms_str, tdi_str); - - /* reset state */ - last_state = next_state; - tap_out_bits = 0; - } - } - - if (tap_out_bits) { - /* terminate strings and display state transition */ - tms_str[tap_out_bits] = tdi_str[tap_out_bits] = 0; - JTAG_DEBUG_STATE_PRINT(last_state, next_state, tms_str, tdi_str); - } - - DEBUG_JTAG_IO("TAP/SM: FINAL state: %s", tap_state_name(next_state)); - - return next_state; -} -#endif /* _DEBUG_JTAG_IO_ */ - -void tap_use_new_tms_table(bool use_new) -{ - tms_seqs = use_new ? &short_tms_seqs : &old_tms_seqs; -} -bool tap_uses_new_tms_table(void) -{ - return tms_seqs == &short_tms_seqs; -} diff --git a/src/jtag/interface.h b/src/jtag/interface.h deleted file mode 100644 index cdfc676ee..000000000 --- a/src/jtag/interface.h +++ /dev/null @@ -1,335 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * Copyright (C) 2007,2008 Øyvind Harboe * - * oyvind.harboe@zylin.com * - * * - * Copyright (C) 2009 Zachary T Welch * - * zw@superlucidity.net * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifndef OPENOCD_JTAG_INTERFACE_H -#define OPENOCD_JTAG_INTERFACE_H - -#include -#include - -/* @file - * The "Cable Helper API" is what the cable drivers can use to help - * implement their "Cable API". So a Cable Helper API is a set of - * helper functions used by cable drivers, and this is different from a - * Cable API. A "Cable API" is what higher level code used to talk to a - * cable. - */ - - -/** implementation of wrapper function tap_set_state() */ -void tap_set_state_impl(tap_state_t new_state); - -/** - * This function sets the state of a "state follower" which tracks the - * state of the TAPs connected to the cable. The state follower is - * hopefully always in the same state as the actual TAPs in the jtag - * chain, and will be so if there are no bugs in the tracking logic - * within that cable driver. - * - * All the cable drivers call this function to indicate the state they - * think the TAPs attached to their cables are in. Because this - * function can also log transitions, it will be helpful to call this - * function with every transition that the TAPs being manipulated are - * expected to traverse, not just end points of a multi-step state path. - * - * @param new_state The state we think the TAPs are currently in (or - * are about to enter). - */ -#if defined(_DEBUG_JTAG_IO_) -#define tap_set_state(new_state) \ - do { \ - LOG_DEBUG("tap_set_state(%s)", tap_state_name(new_state)); \ - tap_set_state_impl(new_state); \ - } while (0) -#else -static inline void tap_set_state(tap_state_t new_state) -{ - tap_set_state_impl(new_state); -} -#endif - -/** - * This function gets the state of the "state follower" which tracks the - * state of the TAPs connected to the cable. @see tap_set_state @return - * tap_state_t The state the TAPs are in now. - */ -tap_state_t tap_get_state(void); - -/** - * This function sets the state of an "end state follower" which tracks - * the state that any cable driver thinks will be the end (resultant) - * state of the current TAP SIR or SDR operation. - * - * At completion of that TAP operation this value is copied into the - * state follower via tap_set_state(). - * - * @param new_end_state The state the TAPs should enter at completion of - * a pending TAP operation. - */ -void tap_set_end_state(tap_state_t new_end_state); - -/** - * For more information, @see tap_set_end_state - * @return tap_state_t - The state the TAPs should be in at completion of the current TAP operation. - */ -tap_state_t tap_get_end_state(void); - -/** - * This function provides a "bit sequence" indicating what has to be - * done with TMS during a sequence of seven TAP clock cycles in order to - * get from state \a "from" to state \a "to". - * - * The length of the sequence must be determined with a parallel call to - * tap_get_tms_path_len(). - * - * @param from The starting state. - * @param to The desired final state. - * @return int The required TMS bit sequence, with the first bit in the - * sequence at bit 0. - */ -int tap_get_tms_path(tap_state_t from, tap_state_t to); - -/** - * Function int tap_get_tms_path_len - * returns the total number of bits that represents a TMS path - * transition as given by the function tap_get_tms_path(). - * - * For at least one interface (JLink) it's not OK to simply "pad" TMS - * sequences to fit a whole byte. (I suspect this is a general TAP - * problem within OOCD.) Padding TMS causes all manner of instability - * that's not easily discovered. Using this routine we can apply - * EXACTLY the state transitions required to make something work - no - * more - no less. - * - * @param from is the starting state - * @param to is the resultant or final state - * @return int - the total number of bits in a transition. - */ -int tap_get_tms_path_len(tap_state_t from, tap_state_t to); - - -/** - * Function tap_move_ndx - * when given a stable state, returns an index from 0-5. The index corresponds to a - * sequence of stable states which are given in this order:

- * { TAP_RESET, TAP_IDLE, TAP_DRSHIFT, TAP_DRPAUSE, TAP_IRSHIFT, TAP_IRPAUSE } - *

- * This sequence corresponds to look up tables which are used in some of the - * cable drivers. - * @param astate is the stable state to find in the sequence. If a non stable - * state is passed, this may cause the program to output an error message - * and terminate. - * @return int - the array (or sequence) index as described above - */ -int tap_move_ndx(tap_state_t astate); - -/** - * Function tap_is_state_stable - * returns true if the \a astate is stable. - */ -bool tap_is_state_stable(tap_state_t astate); - -/** - * Function tap_state_transition - * takes a current TAP state and returns the next state according to the tms value. - * @param current_state is the state of a TAP currently. - * @param tms is either zero or non-zero, just like a real TMS line in a jtag interface. - * @return tap_state_t - the next state a TAP would enter. - */ -tap_state_t tap_state_transition(tap_state_t current_state, bool tms); - -/** Allow switching between old and new TMS tables. @see tap_get_tms_path */ -void tap_use_new_tms_table(bool use_new); -/** @returns True if new TMS table is active; false otherwise. */ -bool tap_uses_new_tms_table(void); - -#ifdef _DEBUG_JTAG_IO_ -/** - * @brief Prints verbose TAP state transitions for the given TMS/TDI buffers. - * @param tms_buf must points to a buffer containing the TMS bitstream. - * @param tdi_buf must points to a buffer containing the TDI bitstream. - * @param tap_len must specify the length of the TMS/TDI bitstreams. - * @param start_tap_state must specify the current TAP state. - * @returns the final TAP state; pass as @a start_tap_state in following call. - */ -tap_state_t jtag_debug_state_machine(const void *tms_buf, const void *tdi_buf, - unsigned tap_len, tap_state_t start_tap_state); -#else -static inline tap_state_t jtag_debug_state_machine(const void *tms_buf, - const void *tdi_buf, unsigned tap_len, tap_state_t start_tap_state) -{ - return start_tap_state; -} -#endif /* _DEBUG_JTAG_IO_ */ - -/** - * Represents a driver for a debugging interface. - * - * @todo Rename; perhaps "debug_driver". This isn't an interface, - * it's a driver! Also, not all drivers support JTAG. - * - * @todo We need a per-instance structure too, and changes to pass - * that structure to the driver. Instances can for example be in - * either SWD or JTAG modes. This will help remove globals, and - * eventually to cope with systems which have more than one such - * debugging interface. - */ -struct jtag_interface { - /** The name of the JTAG interface driver. */ - const char * const name; - - /** - * Bit vector listing capabilities exposed by this driver. - */ - unsigned supported; -#define DEBUG_CAP_TMS_SEQ (1 << 0) - - /** transports supported in C code (NULL terminated vector) */ - const char * const *transports; - - const struct swd_driver *swd; - - /** - * Execute queued commands. - * @returns ERROR_OK on success, or an error code on failure. - */ - int (*execute_queue)(void); - - /** - * Set the interface speed. - * @param speed The new interface speed setting. - * @returns ERROR_OK on success, or an error code on failure. - */ - int (*speed)(int speed); - - /** - * The interface driver may register additional commands to expose - * additional features not covered by the standard command set. - */ - const struct command_registration *commands; - - /** - * Interface driver must initialize any resources and connect to a - * JTAG device. - * - * quit() is invoked if and only if init() succeeds. quit() is always - * invoked if init() succeeds. Same as malloc() + free(). Always - * invoke free() if malloc() succeeds and do not invoke free() - * otherwise. - * - * @returns ERROR_OK on success, or an error code on failure. - */ - int (*init)(void); - - /** - * Interface driver must tear down all resources and disconnect from - * the JTAG device. - * - * @returns ERROR_OK on success, or an error code on failure. - */ - int (*quit)(void); - - /** - * Returns JTAG maxium speed for KHz. 0 = RTCK. The function returns - * a failure if it can't support the KHz/RTCK. - * - * WARNING!!!! if RTCK is *slow* then think carefully about - * whether you actually want to support this in the driver. - * Many target scripts are written to handle the absence of RTCK - * and use a fallback kHz TCK. - * @returns ERROR_OK on success, or an error code on failure. - */ - int (*khz)(int khz, int *jtag_speed); - - /** - * Calculate the clock frequency (in KHz) for the given @a speed. - * @param speed The desired interface speed setting. - * @param khz On return, contains the speed in KHz (0 for RTCK). - * @returns ERROR_OK on success, or an error code if the - * interface cannot support the specified speed (KHz or RTCK). - */ - int (*speed_div)(int speed, int *khz); - - /** - * Read and clear the power dropout flag. Note that a power dropout - * can be transitionary, easily much less than a ms. - * - * To find out if the power is *currently* on, one must invoke this - * method twice. Once to clear the power dropout flag and a second - * time to read the current state. The default implementation - * never reports power dropouts. - * - * @returns ERROR_OK on success, or an error code on failure. - */ - int (*power_dropout)(int *power_dropout); - - /** - * Read and clear the srst asserted detection flag. - * - * Like power_dropout this does *not* read the current - * state. SRST assertion is transitionary and may be much - * less than 1ms, so the interface driver must watch for these - * events until this routine is called. - * - * @param srst_asserted On return, indicates whether SRST has - * been asserted. - * @returns ERROR_OK on success, or an error code on failure. - */ - int (*srst_asserted)(int *srst_asserted); - - /** - * Configure trace parameters for the adapter - * - * @param enabled Whether to enable trace - * @param pin_protocol Configured pin protocol - * @param port_size Trace port width for sync mode - * @param trace_freq A pointer to the configured trace - * frequency; if it points to 0, the adapter driver must write - * its maximum supported rate there - * @returns ERROR_OK on success, an error code on failure. - */ - int (*config_trace)(bool enabled, enum tpio_pin_protocol pin_protocol, - uint32_t port_size, unsigned int *trace_freq); - - /** - * Poll for new trace data - * - * @param buf A pointer to buffer to store received data - * @param size A pointer to buffer size; must be filled with - * the actual amount of bytes written - * - * @returns ERROR_OK on success, an error code on failure. - */ - int (*poll_trace)(uint8_t *buf, size_t *size); -}; - -extern const char * const jtag_only[]; - -void adapter_assert_reset(void); -void adapter_deassert_reset(void); -int adapter_config_trace(bool enabled, enum tpio_pin_protocol pin_protocol, - uint32_t port_size, unsigned int *trace_freq); -int adapter_poll_trace(uint8_t *buf, size_t *size); - -#endif /* OPENOCD_JTAG_INTERFACE_H */ diff --git a/src/jtag/interfaces.c b/src/jtag/interfaces.c deleted file mode 100644 index 64fdd71d6..000000000 --- a/src/jtag/interfaces.c +++ /dev/null @@ -1,238 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * Copyright (C) 2007,2008 Øyvind Harboe * - * oyvind.harboe@zylin.com * - * * - * Copyright (C) 2009 SoftPLC Corporation * - * http://softplc.com * - * dick@softplc.com * - * * - * Copyright (C) 2009 Zachary T Welch * - * zw@superlucidity.net * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "interfaces.h" - -/** @file - * This file includes declarations for all built-in jtag interfaces, - * which are then listed in the jtag_interfaces array. - * - * Dynamic loading can be implemented be searching for shared libraries - * that contain a jtag_interface structure that can added to this list. - */ - -#if BUILD_ZY1000 == 1 -extern struct jtag_interface zy1000_interface; -#elif defined(BUILD_MINIDRIVER_DUMMY) -extern struct jtag_interface minidummy_interface; -#else /* standard drivers */ -#if BUILD_PARPORT == 1 -extern struct jtag_interface parport_interface; -#endif -#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_USB_BLASTER_LIBFTDI == 1 || BUILD_USB_BLASTER_FTD2XX == 1 || BUILD_USB_BLASTER_2 == 1 -extern struct jtag_interface usb_blaster_interface; -#endif -#if BUILD_JTAG_VPI == 1 -extern struct jtag_interface jtag_vpi_interface; -#endif -#if BUILD_AMTJTAGACCEL == 1 -extern struct jtag_interface amt_jtagaccel_interface; -#endif -#if BUILD_EP93XX == 1 -extern struct jtag_interface ep93xx_interface; -#endif -#if BUILD_AT91RM9200 == 1 -extern struct jtag_interface at91rm9200_interface; -#endif -#if BUILD_GW16012 == 1 -extern struct jtag_interface gw16012_interface; -#endif -#if BUILD_PRESTO_LIBFTDI == 1 || BUILD_PRESTO_FTD2XX == 1 -extern struct jtag_interface presto_interface; -#endif -#if BUILD_USBPROG == 1 -extern struct jtag_interface usbprog_interface; -#endif -#if BUILD_OPENJTAG == 1 -extern struct jtag_interface openjtag_interface; -#endif -#if BUILD_JLINK == 1 -extern struct jtag_interface jlink_interface; -#endif -#if BUILD_VSLLINK == 1 -extern struct jtag_interface vsllink_interface; -#endif -#if BUILD_RLINK == 1 -extern struct jtag_interface rlink_interface; -#endif -#if BUILD_ULINK == 1 -extern struct jtag_interface ulink_interface; -#endif -#if BUILD_ARMJTAGEW == 1 -extern struct jtag_interface armjtagew_interface; -#endif -#if BUILD_BUSPIRATE == 1 -extern struct jtag_interface buspirate_interface; -#endif -#if BUILD_REMOTE_BITBANG == 1 -extern struct jtag_interface remote_bitbang_interface; -#endif -#if BUILD_HLADAPTER == 1 -extern struct jtag_interface hl_interface; -#endif -#if BUILD_OSBDM == 1 -extern struct jtag_interface osbdm_interface; -#endif -#if BUILD_OPENDOUS == 1 -extern struct jtag_interface opendous_interface; -#endif -#if BUILD_SYSFSGPIO == 1 -extern struct jtag_interface sysfsgpio_interface; -#endif -#if BUILD_AICE == 1 -extern struct jtag_interface aice_interface; -#endif -#if BUILD_BCM2835GPIO == 1 -extern struct jtag_interface bcm2835gpio_interface; -#endif -#if BUILD_CMSIS_DAP == 1 -extern struct jtag_interface cmsis_dap_interface; -#endif -#endif /* standard drivers */ - -/** - * The list of built-in JTAG interfaces, containing entries for those - * drivers that were enabled by the @c configure script. - * - * The list should be defined to contain either one minidriver interface - * or some number of standard driver interfaces, never both. - */ -struct jtag_interface *jtag_interfaces[] = { -#if BUILD_ZY1000 == 1 - &zy1000_interface, -#elif defined(BUILD_MINIDRIVER_DUMMY) - &minidummy_interface, -#else /* standard drivers */ -#if BUILD_PARPORT == 1 - &parport_interface, -#endif -#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_USB_BLASTER_LIBFTDI == 1 || BUILD_USB_BLASTER_FTD2XX == 1 || BUILD_USB_BLASTER_2 == 1 - &usb_blaster_interface, -#endif -#if BUILD_JTAG_VPI == 1 - &jtag_vpi_interface, -#endif -#if BUILD_AMTJTAGACCEL == 1 - &amt_jtagaccel_interface, -#endif -#if BUILD_EP93XX == 1 - &ep93xx_interface, -#endif -#if BUILD_AT91RM9200 == 1 - &at91rm9200_interface, -#endif -#if BUILD_GW16012 == 1 - &gw16012_interface, -#endif -#if BUILD_PRESTO_LIBFTDI == 1 || BUILD_PRESTO_FTD2XX == 1 - &presto_interface, -#endif -#if BUILD_USBPROG == 1 - &usbprog_interface, -#endif -#if BUILD_OPENJTAG == 1 - &openjtag_interface, -#endif -#if BUILD_JLINK == 1 - &jlink_interface, -#endif -#if BUILD_VSLLINK == 1 - &vsllink_interface, -#endif -#if BUILD_RLINK == 1 - &rlink_interface, -#endif -#if BUILD_ULINK == 1 - &ulink_interface, -#endif -#if BUILD_ARMJTAGEW == 1 - &armjtagew_interface, -#endif -#if BUILD_BUSPIRATE == 1 - &buspirate_interface, -#endif -#if BUILD_REMOTE_BITBANG == 1 - &remote_bitbang_interface, -#endif -#if BUILD_HLADAPTER == 1 - &hl_interface, -#endif -#if BUILD_OSBDM == 1 - &osbdm_interface, -#endif -#if BUILD_OPENDOUS == 1 - &opendous_interface, -#endif -#if BUILD_SYSFSGPIO == 1 - &sysfsgpio_interface, -#endif -#if BUILD_AICE == 1 - &aice_interface, -#endif -#if BUILD_BCM2835GPIO == 1 - &bcm2835gpio_interface, -#endif -#if BUILD_CMSIS_DAP == 1 - &cmsis_dap_interface, -#endif -#endif /* standard drivers */ - NULL, - }; - -void jtag_interface_modules_load(const char *path) -{ - /* @todo: implement dynamic module loading for JTAG interface drivers */ -} diff --git a/src/jtag/interfaces.h b/src/jtag/interfaces.h deleted file mode 100644 index 02d201b1f..000000000 --- a/src/jtag/interfaces.h +++ /dev/null @@ -1,44 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * Copyright (C) 2007,2008 Øyvind Harboe * - * oyvind.harboe@zylin.com * - * * - * Copyright (C) 2009 SoftPLC Corporation * - * http://softplc.com * - * dick@softplc.com * - * * - * Copyright (C) 2009 Zachary T Welch * - * zw@superlucidity.net * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifndef OPENOCD_JTAG_INTERFACES_H -#define OPENOCD_JTAG_INTERFACES_H - -/** @file - * Exports the list of JTAG interface drivers, along with routines - * for loading and unloading them dynamically from shared libraries. - */ - -#include - -/** Dynamically load all JTAG interface modules from specified directory. */ -void jtag_interface_modules_load(const char *path); - -extern struct jtag_interface *jtag_interfaces[]; - -#endif /* OPENOCD_JTAG_INTERFACES_H */ diff --git a/src/jtag/jtag.h b/src/jtag/jtag.h deleted file mode 100644 index 7702d6ca8..000000000 --- a/src/jtag/jtag.h +++ /dev/null @@ -1,649 +0,0 @@ -/*************************************************************************** -* Copyright (C) 2005 by Dominic Rath * -* Dominic.Rath@gmx.de * -* * -* Copyright (C) 2007-2010 Øyvind Harboe * -* oyvind.harboe@zylin.com * -* * -* This program is free software; you can redistribute it and/or modify * -* it under the terms of the GNU General Public License as published by * -* the Free Software Foundation; either version 2 of the License, or * -* (at your option) any later version. * -* * -* This program is distributed in the hope that it will be useful, * -* but WITHOUT ANY WARRANTY; without even the implied warranty of * -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -* GNU General Public License for more details. * -* * -* You should have received a copy of the GNU General Public License * -* along with this program. If not, see . * -***************************************************************************/ - -#ifndef OPENOCD_JTAG_JTAG_H -#define OPENOCD_JTAG_JTAG_H - -#include -#include - -#ifdef _DEBUG_JTAG_IO_ -#define DEBUG_JTAG_IO(expr ...) \ - do { if (1) LOG_DEBUG(expr); } while (0) -#else -#define DEBUG_JTAG_IO(expr ...) \ - do { if (0) LOG_DEBUG(expr); } while (0) -#endif - -#ifndef DEBUG_JTAG_IOZ -#define DEBUG_JTAG_IOZ 64 -#endif - -/*------------------------------------------------------*/ - -/** - * Defines JTAG Test Access Port states. - * - * These definitions were gleaned from the ARM7TDMI-S Technical - * Reference Manual and validated against several other ARM core - * technical manuals. - * - * FIXME some interfaces require specific numbers be used, as they - * are handed-off directly to their hardware implementations. - * Fix those drivers to map as appropriate ... then pick some - * sane set of numbers here (where 0/uninitialized == INVALID). - */ -typedef enum tap_state { - TAP_INVALID = -1, - -#if BUILD_ZY1000 - /* These are the old numbers. Leave as-is for now... */ - TAP_RESET = 0, TAP_IDLE = 8, - TAP_DRSELECT = 1, TAP_DRCAPTURE = 2, TAP_DRSHIFT = 3, TAP_DREXIT1 = 4, - TAP_DRPAUSE = 5, TAP_DREXIT2 = 6, TAP_DRUPDATE = 7, - TAP_IRSELECT = 9, TAP_IRCAPTURE = 10, TAP_IRSHIFT = 11, TAP_IREXIT1 = 12, - TAP_IRPAUSE = 13, TAP_IREXIT2 = 14, TAP_IRUPDATE = 15, - -#else - /* Proper ARM recommended numbers */ - TAP_DREXIT2 = 0x0, - TAP_DREXIT1 = 0x1, - TAP_DRSHIFT = 0x2, - TAP_DRPAUSE = 0x3, - TAP_IRSELECT = 0x4, - TAP_DRUPDATE = 0x5, - TAP_DRCAPTURE = 0x6, - TAP_DRSELECT = 0x7, - TAP_IREXIT2 = 0x8, - TAP_IREXIT1 = 0x9, - TAP_IRSHIFT = 0xa, - TAP_IRPAUSE = 0xb, - TAP_IDLE = 0xc, - TAP_IRUPDATE = 0xd, - TAP_IRCAPTURE = 0xe, - TAP_RESET = 0x0f, - -#endif -} tap_state_t; - -/** - * Function tap_state_name - * Returns a string suitable for display representing the JTAG tap_state - */ -const char *tap_state_name(tap_state_t state); - -/** Provides user-friendly name lookup of TAP states. */ -tap_state_t tap_state_by_name(const char *name); - -/** The current TAP state of the pending JTAG command queue. */ -extern tap_state_t cmd_queue_cur_state; - -/** - * This structure defines a single scan field in the scan. It provides - * fields for the field's width and pointers to scan input and output - * values. - * - * In addition, this structure includes a value and mask that is used by - * jtag_add_dr_scan_check() to validate the value that was scanned out. - */ -struct scan_field { - /** 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; - /** A pointer to a 32-bit memory location for data scanned out */ - uint8_t *in_value; - - /** The value used to check the data scanned out. */ - uint8_t *check_value; - /** The mask to go with check_value */ - uint8_t *check_mask; -}; - -struct jtag_tap { - char *chip; - char *tapname; - char *dotted_name; - int abs_chain_position; - /** Is this TAP disabled after JTAG reset? */ - bool disabled_after_reset; - /** Is this TAP currently enabled? */ - bool enabled; - int ir_length; /**< size of instruction register */ - uint32_t ir_capture_value; - uint8_t *expected; /**< Capture-IR expected value */ - uint32_t ir_capture_mask; - uint8_t *expected_mask; /**< Capture-IR expected mask */ - uint32_t idcode; /**< device identification code */ - /** not all devices have idcode, - * we'll discover this during chain examination */ - bool hasidcode; - - /** Array of expected identification codes */ - uint32_t *expected_ids; - /** Number of expected identification codes */ - uint8_t expected_ids_cnt; - - /** Flag saying whether to ignore version field in expected_ids[] */ - bool ignore_version; - - /** current instruction */ - uint8_t *cur_instr; - /** Bypass register selected */ - int bypass; - - struct jtag_tap_event_action *event_action; - - struct jtag_tap *next_tap; - /* dap instance if some null if no instance , initialized to 0 by calloc*/ - struct adiv5_dap *dap; - /* private pointer to support none-jtag specific functions */ - void *priv; -}; - -void jtag_tap_init(struct jtag_tap *tap); -void jtag_tap_free(struct jtag_tap *tap); - -struct jtag_tap *jtag_all_taps(void); -const char *jtag_tap_name(const struct jtag_tap *tap); -struct jtag_tap *jtag_tap_by_string(const char* dotted_name); -struct jtag_tap *jtag_tap_by_jim_obj(Jim_Interp* interp, Jim_Obj *obj); -struct jtag_tap *jtag_tap_by_position(unsigned abs_position); -struct jtag_tap *jtag_tap_next_enabled(struct jtag_tap *p); -unsigned jtag_tap_count_enabled(void); -unsigned jtag_tap_count(void); - -/* - * - TRST_ASSERTED triggers two sets of callbacks, after operations to - * reset the scan chain -- via TMS+TCK signaling, or deasserting the - * nTRST signal -- are queued: - * - * + Callbacks in C code fire first, patching internal state - * + Then post-reset event scripts fire ... activating JTAG circuits - * via TCK cycles, exiting SWD mode via TMS sequences, etc - * - * During those callbacks, scan chain contents have not been validated. - * JTAG operations that address a specific TAP (primarily DR/IR scans) - * must *not* be queued. - * - * - TAP_EVENT_SETUP is reported after TRST_ASSERTED, and after the scan - * chain has been validated. JTAG operations including scans that - * target specific TAPs may be performed. - * - * - TAP_EVENT_ENABLE and TAP_EVENT_DISABLE implement TAP activation and - * deactivation outside the core using scripted code that understands - * the specific JTAG router type. They might be triggered indirectly - * from EVENT_SETUP operations. - */ -enum jtag_event { - JTAG_TRST_ASSERTED, - JTAG_TAP_EVENT_SETUP, - JTAG_TAP_EVENT_ENABLE, - JTAG_TAP_EVENT_DISABLE, -}; - -struct jtag_tap_event_action { - /** The event for which this action will be triggered. */ - enum jtag_event event; - /** The interpreter to use for evaluating the @c body. */ - Jim_Interp *interp; - /** Contains a script to 'eval' when the @c event is triggered. */ - Jim_Obj *body; - /* next action in linked list */ - struct jtag_tap_event_action *next; -}; - -/** - * Defines the function signature requide for JTAG event callback - * functions, which are added with jtag_register_event_callback() - * and removed jtag_unregister_event_callback(). - * @param event The event to handle. - * @param prive A pointer to data that was passed to - * jtag_register_event_callback(). - * @returns Must return ERROR_OK on success, or an error code on failure. - * - * @todo Change to return void or define a use for its return code. - */ -typedef int (*jtag_event_handler_t)(enum jtag_event event, void *priv); - -int jtag_register_event_callback(jtag_event_handler_t f, void *x); -int jtag_unregister_event_callback(jtag_event_handler_t f, void *x); - -int jtag_call_event_callbacks(enum jtag_event event); - - -/** @returns The current JTAG speed setting. */ -int jtag_get_speed(int *speed); - -/** - * Given a @a speed setting, use the interface @c speed_div callback to - * adjust the setting. - * @param speed The speed setting to convert back to readable KHz. - * @returns ERROR_OK if the interface has not been initialized or on success; - * otherwise, the error code produced by the @c speed_div callback. - */ -int jtag_get_speed_readable(int *speed); - -/** Attempt to configure the interface for the specified KHz. */ -int jtag_config_khz(unsigned khz); - -/** - * Attempt to enable RTCK/RCLK. If that fails, fallback to the - * specified frequency. - */ -int jtag_config_rclk(unsigned fallback_speed_khz); - -/** Retreives the clock speed of the JTAG interface in KHz. */ -unsigned jtag_get_speed_khz(void); - -enum reset_types { - RESET_NONE = 0x0, - RESET_HAS_TRST = 0x1, - RESET_HAS_SRST = 0x2, - RESET_TRST_AND_SRST = 0x3, - RESET_SRST_PULLS_TRST = 0x4, - RESET_TRST_PULLS_SRST = 0x8, - RESET_TRST_OPEN_DRAIN = 0x10, - RESET_SRST_PUSH_PULL = 0x20, - RESET_SRST_NO_GATING = 0x40, - RESET_CNCT_UNDER_SRST = 0x80 -}; - -enum reset_types jtag_get_reset_config(void); -void jtag_set_reset_config(enum reset_types type); - -void jtag_set_nsrst_delay(unsigned delay); -unsigned jtag_get_nsrst_delay(void); - -void jtag_set_ntrst_delay(unsigned delay); -unsigned jtag_get_ntrst_delay(void); - -void jtag_set_nsrst_assert_width(unsigned delay); -unsigned jtag_get_nsrst_assert_width(void); - -void jtag_set_ntrst_assert_width(unsigned delay); -unsigned jtag_get_ntrst_assert_width(void); - -/** @returns The current state of TRST. */ -int jtag_get_trst(void); -/** @returns The current state of SRST. */ -int jtag_get_srst(void); - -/** Enable or disable data scan verification checking. */ -void jtag_set_verify(bool enable); -/** @returns True if data scan verification will be performed. */ -bool jtag_will_verify(void); - -/** Enable or disable verification of IR scan checking. */ -void jtag_set_verify_capture_ir(bool enable); -/** @returns True if IR scan verification will be performed. */ -bool jtag_will_verify_capture_ir(void); - -/** Initialize debug adapter upon startup. */ -int adapter_init(struct command_context *cmd_ctx); - -/** Shutdown the debug adapter upon program exit. */ -int adapter_quit(void); - -/** Set ms to sleep after jtag_execute_queue() flushes queue. Debug purposes. */ -void jtag_set_flush_queue_sleep(int ms); - -/** - * Initialize JTAG chain using only a RESET reset. If init fails, - * try reset + init. - */ -int jtag_init(struct command_context *cmd_ctx); - -/** reset, then initialize JTAG chain */ -int jtag_init_reset(struct command_context *cmd_ctx); -int jtag_register_commands(struct command_context *cmd_ctx); -int jtag_init_inner(struct command_context *cmd_ctx); - -/** - * @file - * The JTAG interface can be implemented with a software or hardware fifo. - * - * TAP_DRSHIFT and TAP_IRSHIFT are illegal end states; however, - * TAP_DRSHIFT/IRSHIFT can be emulated as end states, by using longer - * scans. - * - * Code that is relatively insensitive to the path taken through state - * machine (as long as it is JTAG compliant) can use @a endstate for - * jtag_add_xxx_scan(). Otherwise, the pause state must be specified as - * end state and a subsequent jtag_add_pathmove() must be issued. - */ - -/** - * Generate an IR SCAN with a list of scan fields with one entry for - * each enabled TAP. - * - * If the input field list contains an instruction value for a TAP then - * that is used otherwise the TAP is set to bypass. - * - * TAPs for which no fields are passed are marked as bypassed for - * subsequent DR SCANs. - * - */ -void jtag_add_ir_scan(struct jtag_tap *tap, - struct scan_field *fields, tap_state_t endstate); -/** - * The same as jtag_add_ir_scan except no verification is performed out - * the output values. - */ -void jtag_add_ir_scan_noverify(struct jtag_tap *tap, - const struct scan_field *fields, tap_state_t state); -/** - * Scan out the bits in ir scan mode. - * - * If in_bits == NULL, discard incoming bits. - */ -void jtag_add_plain_ir_scan(int num_bits, const uint8_t *out_bits, uint8_t *in_bits, - tap_state_t endstate); - -/** - * Generate a DR SCAN using the fields passed to the function. - * For connected TAPs, the function checks in_fields and uses fields - * specified there. For bypassed TAPs, the function generates a dummy - * 1-bit field. The bypass status of TAPs is set by jtag_add_ir_scan(). - */ -void jtag_add_dr_scan(struct jtag_tap *tap, int num_fields, - const struct scan_field *fields, tap_state_t endstate); -/** A version of jtag_add_dr_scan() that uses the check_value/mask fields */ -void jtag_add_dr_scan_check(struct jtag_tap *tap, int num_fields, - struct scan_field *fields, tap_state_t endstate); -/** - * Scan out the bits in ir scan mode. - * - * If in_bits == NULL, discard incoming bits. - */ -void jtag_add_plain_dr_scan(int num_bits, - const uint8_t *out_bits, uint8_t *in_bits, tap_state_t endstate); - -/** - * Defines the type of data passed to the jtag_callback_t interface. - * The underlying type must allow storing an @c int or pointer type. - */ -typedef intptr_t jtag_callback_data_t; - -/** - * Defines a simple JTAG callback that can allow conversions on data - * scanned in from an interface. - * - * This callback should only be used for conversion that cannot fail. - * For conversion types or checks that can fail, use the more complete - * variant: jtag_callback_t. - */ -typedef void (*jtag_callback1_t)(jtag_callback_data_t data0); - -/** A simpler version of jtag_add_callback4(). */ -void jtag_add_callback(jtag_callback1_t, jtag_callback_data_t data0); - - -/** - * Defines the interface of the JTAG callback mechanism. Such - * callbacks can be executed once the queue has been flushed. - * - * The JTAG queue can be executed synchronously or asynchronously. - * Typically for USB, the queue is executed asynchronously. For - * low-latency interfaces, the queue may be executed synchronously. - * - * The callback mechanism is very general and does not make many - * assumptions about what the callback does or what its arguments are. - * These callbacks are typically executed *after* the *entire* JTAG - * queue has been executed for e.g. USB interfaces, and they are - * guaranteeed to be invoked in the order that they were queued. - * - * If the execution of the queue fails before the callbacks, then -- - * depending on driver implementation -- the callbacks may or may not be - * invoked. - * - * @todo Make that behavior consistent. - * - * @param data0 Typically used to point to the data to operate on. - * Frequently this will be the data clocked in during a shift operation. - * @param data1 An integer big enough to use as an @c int or a pointer. - * @param data2 An integer big enough to use as an @c int or a pointer. - * @param data3 An integer big enough to use as an @c int or a pointer. - * @returns an error code - */ -typedef int (*jtag_callback_t)(jtag_callback_data_t data0, - jtag_callback_data_t data1, - jtag_callback_data_t data2, - jtag_callback_data_t data3); - -/** - * Run a TAP_RESET reset where the end state is TAP_RESET, - * regardless of the start state. - */ -void jtag_add_tlr(void); - -/** - * Application code *must* assume that interfaces will - * implement transitions between states with different - * paths and path lengths through the state diagram. The - * path will vary across interface and also across versions - * of the same interface over time. Even if the OpenOCD code - * is unchanged, the actual path taken may vary over time - * and versions of interface firmware or PCB revisions. - * - * Use jtag_add_pathmove() when specific transition sequences - * are required. - * - * Do not use jtag_add_pathmove() unless you need to, but do use it - * if you have to. - * - * DANGER! If the target is dependent upon a particular sequence - * of transitions for things to work correctly(e.g. as a workaround - * for an errata that contradicts the JTAG standard), then pathmove - * must be used, even if some jtag interfaces happen to use the - * desired path. Worse, the jtag interface used for testing a - * particular implementation, could happen to use the "desired" - * path when transitioning to/from end - * state. - * - * A list of unambigious single clock state transitions, not - * all drivers can support this, but it is required for e.g. - * XScale and Xilinx support - * - * Note! TAP_RESET must not be used in the path! - * - * Note that the first on the list must be reachable - * via a single transition from the current state. - * - * All drivers are required to implement jtag_add_pathmove(). - * However, if the pathmove sequence can not be precisely - * executed, an interface_jtag_add_pathmove() or jtag_execute_queue() - * must return an error. It is legal, but not recommended, that - * a driver returns an error in all cases for a pathmove if it - * can only implement a few transitions and therefore - * a partial implementation of pathmove would have little practical - * application. - * - * If an error occurs, jtag_error will contain one of these error codes: - * - ERROR_JTAG_NOT_STABLE_STATE -- The final state was not stable. - * - ERROR_JTAG_STATE_INVALID -- The path passed through TAP_RESET. - * - ERROR_JTAG_TRANSITION_INVALID -- The path includes invalid - * state transitions. - */ -void jtag_add_pathmove(int num_states, const tap_state_t *path); - -/** - * jtag_add_statemove() moves from the current state to @a goal_state. - * - * @param goal_state The final TAP state. - * @return ERROR_OK on success, or an error code on failure. - * - * Moves from the current state to the goal \a state. - * Both states must be stable. - */ -int jtag_add_statemove(tap_state_t goal_state); - -/** - * Goes to TAP_IDLE (if we're not already there), cycle - * precisely num_cycles in the TAP_IDLE state, after which move - * to @a endstate (unless it is also TAP_IDLE). - * - * @param num_cycles Number of cycles in TAP_IDLE state. This argument - * may be 0, in which case this routine will navigate to @a endstate - * via TAP_IDLE. - * @param endstate The final state. - */ -void jtag_add_runtest(int num_cycles, tap_state_t endstate); - -/** - * A reset of the TAP state machine can be requested. - * - * Whether tms or trst reset is used depends on the capabilities of - * the target and jtag interface(reset_config command configures this). - * - * srst can driver a reset of the TAP state machine and vice - * versa - * - * Application code may need to examine value of jtag_reset_config - * to determine the proper codepath - * - * DANGER! Even though srst drives trst, trst might not be connected to - * the interface, and it might actually be *harmful* to assert trst in this case. - * - * This is why combinations such as "reset_config srst_only srst_pulls_trst" - * are supported. - * - * only req_tlr_or_trst and srst can have a transition for a - * call as the effects of transitioning both at the "same time" - * are undefined, but when srst_pulls_trst or vice versa, - * then trst & srst *must* be asserted together. - */ -void jtag_add_reset(int req_tlr_or_trst, int srst); - -void jtag_add_sleep(uint32_t us); - -int jtag_add_tms_seq(unsigned nbits, const uint8_t *seq, enum tap_state t); - -/** - * Function jtag_add_clocks - * first checks that the state in which the clocks are to be issued is - * stable, then queues up num_cycles clocks for transmission. - */ -void jtag_add_clocks(int num_cycles); - -/** - * For software FIFO implementations, the queued commands can be executed - * during this call or earlier. A sw queue might decide to push out - * some of the jtag_add_xxx() operations once the queue is "big enough". - * - * This fn will return an error code if any of the prior jtag_add_xxx() - * calls caused a failure, e.g. check failure. Note that it does not - * matter if the operation was executed *before* jtag_execute_queue(), - * jtag_execute_queue() will still return an error code. - * - * All jtag_add_xxx() calls that have in_handler != NULL will have been - * executed when this fn returns, but if what has been queued only - * clocks data out, without reading anything back, then JTAG could - * be running *after* jtag_execute_queue() returns. The API does - * not define a way to flush a hw FIFO that runs *after* - * jtag_execute_queue() returns. - * - * jtag_add_xxx() commands can either be executed immediately or - * at some time between the jtag_add_xxx() fn call and jtag_execute_queue(). - */ -int jtag_execute_queue(void); - -/** same as jtag_execute_queue() but does not clear the error flag */ -void jtag_execute_queue_noclear(void); - -/** @returns the number of times the scan queue has been flushed */ -int jtag_get_flush_queue_count(void); - -/** Report Tcl event to all TAPs */ -void jtag_notify_event(enum jtag_event); - -/* can be implemented by hw + sw */ -int jtag_power_dropout(int *dropout); -int jtag_srst_asserted(int *srst_asserted); - -/* JTAG support functions */ - -/** - * Execute jtag queue and check value with an optional mask. - * @param field Pointer to scan field. - * @param value Pointer to scan value. - * @param mask Pointer to scan mask; may be NULL. - * @returns Nothing, but calls jtag_set_error() on any error. - */ -void jtag_check_value_mask(struct scan_field *field, uint8_t *value, uint8_t *mask); - -void jtag_sleep(uint32_t us); - -/* - * The JTAG subsystem defines a number of error codes, - * using codes between -100 and -199. - */ -#define ERROR_JTAG_INIT_FAILED (-100) -#define ERROR_JTAG_INVALID_INTERFACE (-101) -#define ERROR_JTAG_NOT_IMPLEMENTED (-102) -#define ERROR_JTAG_TRST_ASSERTED (-103) -#define ERROR_JTAG_QUEUE_FAILED (-104) -#define ERROR_JTAG_NOT_STABLE_STATE (-105) -#define ERROR_JTAG_DEVICE_ERROR (-107) -#define ERROR_JTAG_STATE_INVALID (-108) -#define ERROR_JTAG_TRANSITION_INVALID (-109) -#define ERROR_JTAG_INIT_SOFT_FAIL (-110) - -/** - * Set the current JTAG core execution error, unless one was set - * by a previous call previously. Driver or application code must - * use jtag_error_clear to reset jtag_error once this routine has been - * called with a non-zero error code. - */ -void jtag_set_error(int error); -/** - * Resets jtag_error to ERROR_OK, returning its previous value. - * @returns The previous value of @c jtag_error. - */ -int jtag_error_clear(void); - -/** - * Return true if it's safe for a background polling task to access the - * JTAG scan chain. Polling may be explicitly disallowed, and is also - * unsafe while nTRST is active or the JTAG clock is gated off. - */ -bool is_jtag_poll_safe(void); - -/** - * Return flag reporting whether JTAG polling is disallowed. - */ -bool jtag_poll_get_enabled(void); - -/** - * Assign flag reporting whether JTAG polling is disallowed. - */ -void jtag_poll_set_enabled(bool value); - - -/* The minidriver may have inline versions of some of the low - * level APIs that are used in inner loops. */ -#include - -bool transport_is_jtag(void); - -int jim_jtag_newtap(Jim_Interp *interp, int argc, Jim_Obj *const *argv); - -#endif /* OPENOCD_JTAG_JTAG_H */ diff --git a/src/jtag/minidriver.h b/src/jtag/minidriver.h deleted file mode 100644 index 688c39630..000000000 --- a/src/jtag/minidriver.h +++ /dev/null @@ -1,90 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * Copyright (C) 2007,2008 Øyvind Harboe * - * oyvind.harboe@zylin.com * - * * - * Copyright (C) 2009 Zachary T Welch * - * zw@superlucidity.net * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifndef OPENOCD_JTAG_MINIDRIVER_H -#define OPENOCD_JTAG_MINIDRIVER_H - -/** - * @page jtagminidriver JTAG Mini-Driver - * - * The JTAG minidriver interface allows the definition of alternate - * interface functions, instead of the built-in asynchronous driver - * module that is used by the standard JTAG interface drivers. - * - * In addtion to the functions defined in the @c minidriver.h file, the - * @c jtag_minidriver.h file must declare the following functions (or - * define static inline versions of them): - * - jtag_add_callback - * - jtag_add_callback4 - * - * The following core functions are declared in this file for use by - * the minidriver and do @b not need to be defined by an implementation: - * - default_interface_jtag_execute_queue() - */ - -/* this header will be provided by the minidriver implementation, */ -/* and it may provide additional declarations that must be defined. */ -#include - -int interface_jtag_add_ir_scan(struct jtag_tap *active, - const struct scan_field *fields, - tap_state_t endstate); -int interface_jtag_add_plain_ir_scan( - int num_bits, const uint8_t *out_bits, uint8_t *in_bits, - tap_state_t endstate); - -int interface_jtag_add_dr_scan(struct jtag_tap *active, - int num_fields, const struct scan_field *fields, - tap_state_t endstate); -int interface_jtag_add_plain_dr_scan( - int num_bits, const uint8_t *out_bits, uint8_t *in_bits, - tap_state_t endstate); - -int interface_jtag_add_tlr(void); -int interface_jtag_add_pathmove(int num_states, const tap_state_t *path); -int interface_jtag_add_runtest(int num_cycles, tap_state_t endstate); - -int interface_add_tms_seq(unsigned num_bits, - const uint8_t *bits, enum tap_state state); - -/** - * This drives the actual srst and trst pins. srst will always be 0 - * if jtag_reset_config & RESET_SRST_PULLS_TRST != 0 and ditto for - * trst. - * - * the higher level jtag_add_reset will invoke jtag_add_tlr() if - * approperiate - */ -int interface_jtag_add_reset(int trst, int srst); -int interface_jtag_add_sleep(uint32_t us); -int interface_jtag_add_clocks(int num_cycles); -int interface_jtag_execute_queue(void); - -/** - * Calls the interface callback to execute the queue. This routine - * is used by the JTAG driver layer and should not be called directly. - */ -int default_interface_jtag_execute_queue(void); - -#endif /* OPENOCD_JTAG_MINIDRIVER_H */ diff --git a/src/jtag/minidriver/minidriver_imp.h b/src/jtag/minidriver/minidriver_imp.h deleted file mode 100644 index 11d0fae72..000000000 --- a/src/jtag/minidriver/minidriver_imp.h +++ /dev/null @@ -1,30 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005 by Dominic Rath * - * Copyright (C) 2007,2008 Øyvind Harboe * - * Copyright (C) 2009 Zachary T Welch * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 OPENOCD_JTAG_MINIDRIVER_MINIDRIVER_IMP_H -#define OPENOCD_JTAG_MINIDRIVER_MINIDRIVER_IMP_H - -#include - -#define jtag_add_callback(callback, in) interface_jtag_add_callback(callback, in) - -#define jtag_add_callback4(callback, in, data1, data2, data3) \ - interface_jtag_add_callback4(callback, in, data1, data2, data3) - -#endif /* OPENOCD_JTAG_MINIDRIVER_MINIDRIVER_IMP_H */ diff --git a/src/jtag/minidummy/jtag_minidriver.h b/src/jtag/minidummy/jtag_minidriver.h deleted file mode 100644 index 1708356a5..000000000 --- a/src/jtag/minidummy/jtag_minidriver.h +++ /dev/null @@ -1,21 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007-2008 by Øyvind Harboe * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#define interface_jtag_add_callback(callback, in) callback(in) - -#define interface_jtag_add_callback4(callback, in, data1, data2, data3) \ - jtag_set_error(callback(in, data1, data2, data3)) diff --git a/src/jtag/minidummy/minidummy.c b/src/jtag/minidummy/minidummy.c deleted file mode 100644 index b7c989fc0..000000000 --- a/src/jtag/minidummy/minidummy.c +++ /dev/null @@ -1,169 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007-2008 by Øyvind Harboe * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include -#include - -struct jtag_interface minidummy_interface = { - .name = "minidummy", - .execute_queue = NULL, - .speed = NULL, - .commands = NULL, - .init = NULL, - .quit = NULL, - .khz = NULL, - .speed_div = NULL, - .power_dropout = NULL, - .srst_asserted = NULL, -}; - -int interface_jtag_execute_queue(void) -{ - /* synchronously do the operation here */ - - return ERROR_OK; -} - -int interface_jtag_add_ir_scan(struct jtag_tap *active, const struct scan_field *fields, - tap_state_t state) -{ - /* synchronously do the operation here */ - - return ERROR_OK; -} - -int interface_jtag_add_plain_ir_scan(int num_bits, const uint8_t *out_bits, - uint8_t *in_bits, tap_state_t state) -{ - /* synchronously do the operation here */ - - return ERROR_OK; -} - -int interface_jtag_add_dr_scan(struct jtag_tap *active, int num_fields, - const struct scan_field *fields, tap_state_t state) -{ - /* synchronously do the operation here */ - - return ERROR_OK; -} - -int interface_jtag_add_plain_dr_scan(int num_bits, const uint8_t *out_bits, - uint8_t *in_bits, tap_state_t state) -{ - /* synchronously do the operation here */ - - return ERROR_OK; -} - -int interface_jtag_add_tlr() -{ - /* synchronously do the operation here */ - - return ERROR_OK; -} - -int interface_jtag_add_reset(int req_trst, int req_srst) -{ - /* synchronously do the operation here */ - - return ERROR_OK; -} - -int interface_jtag_add_runtest(int num_cycles, tap_state_t state) -{ - /* synchronously do the operation here */ - - return ERROR_OK; -} - -int interface_jtag_add_clocks(int num_cycles) -{ - /* synchronously do the operation here */ - - return ERROR_OK; -} - -int interface_jtag_add_sleep(uint32_t us) -{ - jtag_sleep(us); - return ERROR_OK; -} - -int interface_jtag_add_pathmove(int num_states, const tap_state_t *path) -{ - int state_count; - int tms = 0; - - state_count = 0; - - tap_state_t cur_state = cmd_queue_cur_state; - - while (num_states) { - if (tap_state_transition(cur_state, false) == path[state_count]) - tms = 0; - else if (tap_state_transition(cur_state, true) == path[state_count]) - tms = 1; - else { - LOG_ERROR("BUG: %s -> %s isn't a valid TAP transition", - tap_state_name(cur_state), tap_state_name(path[state_count])); - exit(-1); - } - - /* synchronously do the operation here */ - - cur_state = path[state_count]; - state_count++; - num_states--; - } - - - /* synchronously do the operation here */ - - return ERROR_OK; -} - -int interface_add_tms_seq(unsigned num_bits, const uint8_t *seq, enum tap_state state) -{ - /* synchronously do the operation here */ - - return ERROR_OK; -} - -void embeddedice_write_dcc(struct jtag_tap *tap, int reg_addr, const uint8_t *buffer, - int little, int count) -{ - int i; - for (i = 0; i < count; i++) { - embeddedice_write_reg_inner(tap, reg_addr, fast_target_buffer_get_u32(buffer, little)); - buffer += 4; - } -} - -int arm11_run_instr_data_to_core_noack_inner(struct jtag_tap *tap, uint32_t opcode, - uint32_t *data, size_t count) -{ - int arm11_run_instr_data_to_core_noack_inner_default(struct jtag_tap *tap, \ - uint32_t opcode, uint32_t *data, size_t count); - return arm11_run_instr_data_to_core_noack_inner_default(tap, opcode, data, count); -} diff --git a/src/jtag/startup.tcl b/src/jtag/startup.tcl deleted file mode 100644 index d57cafb23..000000000 --- a/src/jtag/startup.tcl +++ /dev/null @@ -1,163 +0,0 @@ -# Defines basic Tcl procs for OpenOCD JTAG module - -# Executed during "init". Can be overridden -# by board/target/... scripts -proc jtag_init {} { - if {[catch {jtag arp_init} err]!=0} { - # try resetting additionally - init_reset startup - } -} - -# This reset logic may be overridden by board/target/... scripts as needed -# to provide a reset that, if possible, is close to a power-up reset. -# -# Exit requirements include: (a) JTAG must be working, (b) the scan -# chain was validated with "jtag arp_init" (or equivalent), (c) nothing -# stays in reset. No TAP-specific scans were performed. It's OK if -# some targets haven't been reset yet; they may need TAP-specific scans. -# -# The "mode" values include: halt, init, run (from "reset" command); -# startup (at OpenOCD server startup, when JTAG may not yet work); and -# potentially more (for reset types like cold, warm, etc) -proc init_reset { mode } { - if {[using_jtag]} { - jtag arp_init-reset - } -} - -######### - -# TODO: power_restore and power_dropout are currently neither -# documented nor supported except on ZY1000. - -proc power_restore {} { - echo "Sensed power restore, running reset init and halting GDB." - reset init - - # Halt GDB so user can deal with a detected power restore. - # - # After GDB is halted, then output is no longer forwarded - # to the GDB console. - set targets [target names] - foreach t $targets { - # New event script. - $t invoke-event arp_halt_gdb - } -} - -add_help_text power_restore "Overridable procedure run when power restore is detected. Runs 'reset init' by default." - -proc power_dropout {} { - echo "Sensed power dropout." -} - -######### - -# TODO: srst_deasserted and srst_asserted are currently neither -# documented nor supported except on ZY1000. - -proc srst_deasserted {} { - echo "Sensed nSRST deasserted, running reset init and halting GDB." - reset init - - # Halt GDB so user can deal with a detected reset. - # - # After GDB is halted, then output is no longer forwarded - # to the GDB console. - set targets [target names] - foreach t $targets { - # New event script. - $t invoke-event arp_halt_gdb - } -} - -add_help_text srst_deasserted "Overridable procedure run when srst deassert is detected. Runs 'reset init' by default." - -proc srst_asserted {} { - echo "Sensed nSRST asserted." -} - -# measure actual JTAG clock -proc measure_clk {} { - set start_time [ms]; - set iterations 10000000; - runtest $iterations; - echo "Running at more than [expr $iterations.0 / ([ms]-$start_time)] kHz"; -} - -add_help_text measure_clk "Runs a test to measure the JTAG clk. Useful with RCLK / RTCK." - -proc default_to_jtag { f args } { - set current_transport [transport select] - if {[using_jtag]} { - eval $f $args - } { - error "session transport is \"$current_transport\" but your config requires JTAG" - } -} - -proc jtag args { - eval default_to_jtag jtag $args -} - -proc jtag_rclk args { - eval default_to_jtag jtag_rclk $args -} - -proc jtag_ntrst_delay args { - eval default_to_jtag jtag_ntrst_delay $args -} - -proc jtag_ntrst_assert_width args { - eval default_to_jtag jtag_ntrst_assert_width $args -} - -# BEGIN MIGRATION AIDS ... these adapter operations originally had -# JTAG-specific names despite the fact that the operations were not -# specific to JTAG, or otherewise had troublesome/misleading names. -# -# FIXME phase these aids out after about April 2011 -# -proc jtag_khz args { - echo "DEPRECATED! use 'adapter_khz' not 'jtag_khz'" - eval adapter_khz $args -} - -proc jtag_nsrst_delay args { - echo "DEPRECATED! use 'adapter_nsrst_delay' not 'jtag_nsrst_delay'" - eval adapter_nsrst_delay $args -} - -proc jtag_nsrst_assert_width args { - echo "DEPRECATED! use 'adapter_nsrst_assert_width' not 'jtag_nsrst_assert_width'" - eval adapter_nsrst_assert_width $args -} - -# stlink migration helpers -proc stlink_device_desc args { - echo "DEPRECATED! use 'hla_device_desc' not 'stlink_device_desc'" - eval hla_device_desc $args -} - -proc stlink_serial args { - echo "DEPRECATED! use 'hla_serial' not 'stlink_serial'" - eval hla_serial $args -} - -proc stlink_layout args { - echo "DEPRECATED! use 'hla_layout' not 'stlink_layout'" - eval hla_layout $args -} - -proc stlink_vid_pid args { - echo "DEPRECATED! use 'hla_vid_pid' not 'stlink_vid_pid'" - eval hla_vid_pid $args -} - -proc stlink args { - echo "DEPRECATED! use 'hla' not 'stlink'" - eval hla $args -} - -# END MIGRATION AIDS diff --git a/src/jtag/swd.h b/src/jtag/swd.h deleted file mode 100644 index c888cc07d..000000000 --- a/src/jtag/swd.h +++ /dev/null @@ -1,216 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2009-2010 by David Brownell * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifndef OPENOCD_JTAG_SWD_H -#define OPENOCD_JTAG_SWD_H - -#include - -/* Bits in SWD command packets, written from host to target - * first bit on the wire is START - */ -#define SWD_CMD_START (1 << 0) /* always set */ -#define SWD_CMD_APnDP (1 << 1) /* set only for AP access */ -#define SWD_CMD_RnW (1 << 2) /* set only for read access */ -#define SWD_CMD_A32 (3 << 3) /* bits A[3:2] of register addr */ -#define SWD_CMD_PARITY (1 << 5) /* parity of APnDP|RnW|A32 */ -#define SWD_CMD_STOP (0 << 6) /* always clear for synch SWD */ -#define SWD_CMD_PARK (1 << 7) /* driven high by host */ -/* followed by TRN, 3-bits of ACK, TRN */ - -/** - * Construct a "cmd" byte, in lSB bit order, which swd_driver.read_reg() - * and swd_driver.write_reg() methods will use directly. - */ -static inline uint8_t swd_cmd(bool is_read, bool is_ap, uint8_t regnum) -{ - uint8_t cmd = (is_ap ? SWD_CMD_APnDP : 0) - | (is_read ? SWD_CMD_RnW : 0) - | ((regnum & 0xc) << 1); - - /* 8 cmd bits 4:1 may be set */ - if (parity_u32(cmd)) - cmd |= SWD_CMD_PARITY; - - /* driver handles START, STOP, and TRN */ - - return cmd; -} - -/* SWD_ACK_* bits are defined in */ - -/** - * Line reset. - * - * Line reset is at least 50 SWCLK cycles with SWDIO driven high, followed - * by at least one idle (low) cycle. - */ -static const uint8_t swd_seq_line_reset[] = { - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03 -}; -static const unsigned swd_seq_line_reset_len = 51; - -/** - * JTAG-to-SWD sequence. - * - * The JTAG-to-SWD sequence is at least 50 TCK/SWCLK cycles with TMS/SWDIO - * high, putting either interface logic into reset state, followed by a - * specific 16-bit sequence and finally a line reset in case the SWJ-DP was - * already in SWD mode. - */ -static const uint8_t swd_seq_jtag_to_swd[] = { - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7b, 0x9e, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, -}; -static const unsigned swd_seq_jtag_to_swd_len = 118; - -/** - * SWD-to-JTAG sequence. - * - * The SWD-to-JTAG sequence is at least 50 TCK/SWCLK cycles with TMS/SWDIO - * high, putting either interface logic into reset state, followed by a - * specific 16-bit sequence and finally at least 5 TCK cycles to put the - * JTAG TAP in TLR. - */ -static const uint8_t swd_seq_swd_to_jtag[] = { - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0x9c, 0xff -}; -static const unsigned swd_seq_swd_to_jtag_len = 71; - -/** - * SWD-to-dormant sequence. - * - * This is at least 50 SWCLK cycles with SWDIO high to put the interface - * in reset state, followed by a specific 16-bit sequence. - */ -static const uint8_t swd_seq_swd_to_dormant[] = { - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0x8e, 0x03 -}; -static const unsigned swd_seq_swd_to_dormant_len = 66; - -/** - * Dormant-to-SWD sequence. - * - * This is at least 8 TCK/SWCLK cycles with TMS/SWDIO high to abort any ongoing - * selection alert sequence, followed by a specific 128-bit selection alert - * sequence, followed by 4 TCK/SWCLK cycles with TMS/SWDIO low, followed by - * a specific protocol-dependent activation code. For SWD the activation code - * is an 8-bit sequence. The sequence ends with a line reset. - */ -static const uint8_t swd_seq_dormant_to_swd[] = { - 0xff, - 0x92, 0xf3, 0x09, 0x62, 0x95, 0x2d, 0x85, 0x86, - 0xe9, 0xaf, 0xdd, 0xe3, 0xa2, 0x0e, 0xbc, 0x19, - 0x10, 0xfa, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f -}; -static const unsigned swd_seq_dormant_to_swd_len = 199; - -enum swd_special_seq { - LINE_RESET, - JTAG_TO_SWD, - SWD_TO_JTAG, - SWD_TO_DORMANT, - DORMANT_TO_SWD, -}; - -struct swd_driver { - /** - * Initialize the debug link so it can perform SWD operations. - * - * As an example, this would switch a dual-mode debug adapter - * into SWD mode and out of JTAG mode. - * - * @return ERROR_OK on success, else a negative fault code. - */ - int (*init)(void); - - /** - * Set the SWCLK frequency of the SWD link. - * - * The driver should round the desired value, downwards if possible, to - * the nearest supported frequency. A negative value should be ignored - * and can be used to query the current setting. If the driver does not - * support a variable frequency a fixed, nominal, value should be - * returned. - * - * If the frequency is increased, it must not apply before the currently - * queued transactions are executed. If the frequency is lowered, it may - * apply immediately. - * - * @param hz The desired frequency in Hz. - * @return The actual resulting frequency after rounding. - */ - int_least32_t (*frequency)(int_least32_t hz); - - /** - * Queue a special SWDIO sequence. - * - * @param seq The special sequence to generate. - * @return ERROR_OK if the sequence was queued, negative error if the - * sequence is unsupported. - */ - int (*switch_seq)(enum swd_special_seq seq); - - /** - * Queued read of an AP or DP register. - * - * @param Command byte with APnDP/RnW/addr/parity bits - * @param Where to store value to read from register - * @param ap_delay_hint Number of idle cycles that may be - * needed after an AP access to avoid WAITs - */ - void (*read_reg)(uint8_t cmd, uint32_t *value, uint32_t ap_delay_hint); - - /** - * Queued write of an AP or DP register. - * - * @param Command byte with APnDP/RnW/addr/parity bits - * @param Value to be written to the register - * @param ap_delay_hint Number of idle cycles that may be - * needed after an AP access to avoid WAITs - */ - void (*write_reg)(uint8_t cmd, uint32_t value, uint32_t ap_delay_hint); - - /** - * Execute any queued transactions and collect the result. - * - * @return ERROR_OK on success, Ack response code on WAIT/FAULT - * or negative error code on other kinds of failure. - */ - int (*run)(void); - - /** - * Configures data collection from the Single-wire - * trace (SWO) signal. - * @param swo true if SWO data collection should be routed. - * - * For example, some debug adapters include a UART which - * is normally connected to a microcontroller's UART TX, - * but which may instead be connected to SWO for use in - * collecting ITM (and possibly ETM) trace data. - * - * @return ERROR_OK on success, else a negative fault code. - */ - int *(*trace)(bool swo); -}; - -int swd_init_reset(struct command_context *cmd_ctx); -void swd_add_reset(int req_srst); - -bool transport_is_swd(void); - -#endif /* OPENOCD_JTAG_SWD_H */ diff --git a/src/jtag/tcl.c b/src/jtag/tcl.c deleted file mode 100644 index bc6bbf204..000000000 --- a/src/jtag/tcl.c +++ /dev/null @@ -1,1387 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * Copyright (C) 2007-2010 Øyvind Harboe * - * oyvind.harboe@zylin.com * - * * - * Copyright (C) 2009 SoftPLC Corporation * - * http://softplc.com * - * dick@softplc.com * - * * - * Copyright (C) 2009 Zachary T Welch * - * zw@superlucidity.net * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "jtag.h" -#include "swd.h" -#include "minidriver.h" -#include "interface.h" -#include "interfaces.h" -#include "tcl.h" - -#ifdef HAVE_STRINGS_H -#include -#endif - -#include - -/** - * @file - * Holds support for accessing JTAG-specific mechanisms from TCl scripts. - */ - -static const Jim_Nvp nvp_jtag_tap_event[] = { - { .value = JTAG_TRST_ASSERTED, .name = "post-reset" }, - { .value = JTAG_TAP_EVENT_SETUP, .name = "setup" }, - { .value = JTAG_TAP_EVENT_ENABLE, .name = "tap-enable" }, - { .value = JTAG_TAP_EVENT_DISABLE, .name = "tap-disable" }, - - { .name = NULL, .value = -1 } -}; - -struct jtag_tap *jtag_tap_by_jim_obj(Jim_Interp *interp, Jim_Obj *o) -{ - const char *cp = Jim_GetString(o, NULL); - struct jtag_tap *t = cp ? jtag_tap_by_string(cp) : NULL; - if (NULL == cp) - cp = "(unknown)"; - if (NULL == t) - Jim_SetResultFormatted(interp, "Tap '%s' could not be found", cp); - return t; -} - -static bool scan_is_safe(tap_state_t state) -{ - switch (state) { - case TAP_RESET: - case TAP_IDLE: - case TAP_DRPAUSE: - case TAP_IRPAUSE: - return true; - default: - return false; - } -} - -static int Jim_Command_drscan(Jim_Interp *interp, int argc, Jim_Obj *const *args) -{ - int retval; - struct scan_field *fields; - int num_fields; - int field_count = 0; - int i, e; - struct jtag_tap *tap; - tap_state_t endstate; - - /* args[1] = device - * args[2] = num_bits - * args[3] = hex string - * ... repeat num bits and hex string ... - * - * .. optionally: - * args[N-2] = "-endstate" - * args[N-1] = statename - */ - if ((argc < 4) || ((argc % 2) != 0)) { - Jim_WrongNumArgs(interp, 1, args, "wrong arguments"); - return JIM_ERR; - } - - endstate = TAP_IDLE; - - script_debug(interp, "drscan", argc, args); - - /* validate arguments as numbers */ - e = JIM_OK; - for (i = 2; i < argc; i += 2) { - long bits; - const char *cp; - - e = Jim_GetLong(interp, args[i], &bits); - /* If valid - try next arg */ - if (e == JIM_OK) - continue; - - /* Not valid.. are we at the end? */ - if (((i + 2) != argc)) { - /* nope, then error */ - return e; - } - - /* it could be: "-endstate FOO" - * e.g. DRPAUSE so we can issue more instructions - * before entering RUN/IDLE and executing them. - */ - - /* get arg as a string. */ - cp = Jim_GetString(args[i], NULL); - /* is it the magic? */ - if (0 == strcmp("-endstate", cp)) { - /* is the statename valid? */ - cp = Jim_GetString(args[i + 1], NULL); - - /* see if it is a valid state name */ - endstate = tap_state_by_name(cp); - if (endstate < 0) { - /* update the error message */ - Jim_SetResultFormatted(interp, "endstate: %s invalid", cp); - } else { - if (!scan_is_safe(endstate)) - LOG_WARNING("drscan with unsafe " - "endstate \"%s\"", cp); - - /* valid - so clear the error */ - e = JIM_OK; - /* and remove the last 2 args */ - argc -= 2; - } - } - - /* Still an error? */ - if (e != JIM_OK) - return e; /* too bad */ - } /* validate args */ - - assert(e == JIM_OK); - - tap = jtag_tap_by_jim_obj(interp, args[1]); - if (tap == NULL) - return JIM_ERR; - - num_fields = (argc-2)/2; - if (num_fields <= 0) { - Jim_SetResultString(interp, "drscan: no scan fields supplied", -1); - return JIM_ERR; - } - fields = malloc(sizeof(struct scan_field) * num_fields); - for (i = 2; i < argc; i += 2) { - long bits; - int len; - const char *str; - - Jim_GetLong(interp, args[i], &bits); - str = Jim_GetString(args[i + 1], &len); - - fields[field_count].num_bits = bits; - void *t = malloc(DIV_ROUND_UP(bits, 8)); - fields[field_count].out_value = t; - str_to_buf(str, len, t, bits, 0); - fields[field_count].in_value = t; - field_count++; - } - - jtag_add_dr_scan(tap, num_fields, fields, endstate); - - retval = jtag_execute_queue(); - if (retval != ERROR_OK) { - Jim_SetResultString(interp, "drscan: jtag execute failed", -1); - return JIM_ERR; - } - - field_count = 0; - Jim_Obj *list = Jim_NewListObj(interp, NULL, 0); - for (i = 2; i < argc; i += 2) { - long bits; - char *str; - - Jim_GetLong(interp, args[i], &bits); - str = buf_to_str(fields[field_count].in_value, bits, 16); - free(fields[field_count].in_value); - - Jim_ListAppendElement(interp, list, Jim_NewStringObj(interp, str, strlen(str))); - free(str); - field_count++; - } - - Jim_SetResult(interp, list); - - free(fields); - - return JIM_OK; -} - - -static int Jim_Command_pathmove(Jim_Interp *interp, int argc, Jim_Obj *const *args) -{ - tap_state_t states[8]; - - if ((argc < 2) || ((size_t)argc > (ARRAY_SIZE(states) + 1))) { - Jim_WrongNumArgs(interp, 1, args, "wrong arguments"); - return JIM_ERR; - } - - script_debug(interp, "pathmove", argc, args); - - int i; - for (i = 0; i < argc-1; i++) { - const char *cp; - cp = Jim_GetString(args[i + 1], NULL); - states[i] = tap_state_by_name(cp); - if (states[i] < 0) { - /* update the error message */ - Jim_SetResultFormatted(interp, "endstate: %s invalid", cp); - return JIM_ERR; - } - } - - if ((jtag_add_statemove(states[0]) != ERROR_OK) || (jtag_execute_queue() != ERROR_OK)) { - Jim_SetResultString(interp, "pathmove: jtag execute failed", -1); - return JIM_ERR; - } - - jtag_add_pathmove(argc - 2, states + 1); - - if (jtag_execute_queue() != ERROR_OK) { - Jim_SetResultString(interp, "pathmove: failed", -1); - return JIM_ERR; - } - - return JIM_OK; -} - - -static int Jim_Command_flush_count(Jim_Interp *interp, int argc, Jim_Obj *const *args) -{ - script_debug(interp, "flush_count", argc, args); - - Jim_SetResult(interp, Jim_NewIntObj(interp, jtag_get_flush_queue_count())); - - return JIM_OK; -} - -/* REVISIT Just what about these should "move" ... ? - * These registrations, into the main JTAG table? - * - * There's a minor compatibility issue, these all show up twice; - * that's not desirable: - * - jtag drscan ... NOT DOCUMENTED! - * - drscan ... - * - * The "irscan" command (for example) doesn't show twice. - */ -static const struct command_registration jtag_command_handlers_to_move[] = { - { - .name = "drscan", - .mode = COMMAND_EXEC, - .jim_handler = Jim_Command_drscan, - .help = "Execute Data Register (DR) scan for one TAP. " - "Other TAPs must be in BYPASS mode.", - .usage = "tap_name [num_bits value]* ['-endstate' state_name]", - }, - { - .name = "flush_count", - .mode = COMMAND_EXEC, - .jim_handler = Jim_Command_flush_count, - .help = "Returns the number of times the JTAG queue " - "has been flushed.", - }, - { - .name = "pathmove", - .mode = COMMAND_EXEC, - .jim_handler = Jim_Command_pathmove, - .usage = "start_state state1 [state2 [state3 ...]]", - .help = "Move JTAG state machine from current state " - "(start_state) to state1, then state2, state3, etc.", - }, - COMMAND_REGISTRATION_DONE -}; - - -enum jtag_tap_cfg_param { - JCFG_EVENT -}; - -static Jim_Nvp nvp_config_opts[] = { - { .name = "-event", .value = JCFG_EVENT }, - - { .name = NULL, .value = -1 } -}; - -static int jtag_tap_configure_event(Jim_GetOptInfo *goi, struct jtag_tap *tap) -{ - if (goi->argc == 0) { - Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv, "-event ..."); - return JIM_ERR; - } - - Jim_Nvp *n; - int e = Jim_GetOpt_Nvp(goi, nvp_jtag_tap_event, &n); - if (e != JIM_OK) { - Jim_GetOpt_NvpUnknown(goi, nvp_jtag_tap_event, 1); - return e; - } - - if (goi->isconfigure) { - if (goi->argc != 1) { - Jim_WrongNumArgs(goi->interp, - goi->argc, - goi->argv, - "-event "); - return JIM_ERR; - } - } else { - if (goi->argc != 0) { - Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv, "-event "); - return JIM_ERR; - } - } - - struct jtag_tap_event_action *jteap = tap->event_action; - /* replace existing event body */ - bool found = false; - while (jteap) { - if (jteap->event == (enum jtag_event)n->value) { - found = true; - break; - } - jteap = jteap->next; - } - - Jim_SetEmptyResult(goi->interp); - - if (goi->isconfigure) { - if (!found) - jteap = calloc(1, sizeof(*jteap)); - else if (NULL != jteap->body) - Jim_DecrRefCount(goi->interp, jteap->body); - - jteap->interp = goi->interp; - jteap->event = n->value; - - Jim_Obj *o; - Jim_GetOpt_Obj(goi, &o); - jteap->body = Jim_DuplicateObj(goi->interp, o); - Jim_IncrRefCount(jteap->body); - - if (!found) { - /* add to head of event list */ - jteap->next = tap->event_action; - tap->event_action = jteap; - } - } else if (found) { - jteap->interp = goi->interp; - Jim_SetResult(goi->interp, - Jim_DuplicateObj(goi->interp, jteap->body)); - } - return JIM_OK; -} - -static int jtag_tap_configure_cmd(Jim_GetOptInfo *goi, struct jtag_tap *tap) -{ - /* parse config or cget options */ - while (goi->argc > 0) { - Jim_SetEmptyResult(goi->interp); - - Jim_Nvp *n; - int 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 JCFG_EVENT: - e = jtag_tap_configure_event(goi, tap); - if (e != JIM_OK) - return e; - break; - default: - Jim_SetResultFormatted(goi->interp, "unknown event: %s", n->name); - return JIM_ERR; - } - } - - return JIM_OK; -} - -static int is_bad_irval(int ir_length, jim_wide w) -{ - jim_wide v = 1; - - v <<= ir_length; - v -= 1; - v = ~v; - return (w & v) != 0; -} - -static int jim_newtap_expected_id(Jim_Nvp *n, Jim_GetOptInfo *goi, - struct jtag_tap *pTap) -{ - jim_wide w; - int e = Jim_GetOpt_Wide(goi, &w); - if (e != JIM_OK) { - Jim_SetResultFormatted(goi->interp, "option: %s bad parameter", n->name); - return e; - } - - uint32_t *p = realloc(pTap->expected_ids, - (pTap->expected_ids_cnt + 1) * sizeof(uint32_t)); - if (!p) { - Jim_SetResultFormatted(goi->interp, "no memory"); - return JIM_ERR; - } - - pTap->expected_ids = p; - pTap->expected_ids[pTap->expected_ids_cnt++] = w; - - return JIM_OK; -} - -#define NTAP_OPT_IRLEN 0 -#define NTAP_OPT_IRMASK 1 -#define NTAP_OPT_IRCAPTURE 2 -#define NTAP_OPT_ENABLED 3 -#define NTAP_OPT_DISABLED 4 -#define NTAP_OPT_EXPECTED_ID 5 -#define NTAP_OPT_VERSION 6 - -static int jim_newtap_ir_param(Jim_Nvp *n, Jim_GetOptInfo *goi, - struct jtag_tap *pTap) -{ - jim_wide w; - int e = Jim_GetOpt_Wide(goi, &w); - if (e != JIM_OK) { - Jim_SetResultFormatted(goi->interp, - "option: %s bad parameter", n->name); - return e; - } - switch (n->value) { - case NTAP_OPT_IRLEN: - if (w > (jim_wide) (8 * sizeof(pTap->ir_capture_value))) { - LOG_WARNING("%s: huge IR length %d", - pTap->dotted_name, (int) w); - } - pTap->ir_length = w; - break; - case NTAP_OPT_IRMASK: - if (is_bad_irval(pTap->ir_length, w)) { - LOG_ERROR("%s: IR mask %x too big", - pTap->dotted_name, - (int) w); - return JIM_ERR; - } - if ((w & 3) != 3) - LOG_WARNING("%s: nonstandard IR mask", pTap->dotted_name); - pTap->ir_capture_mask = w; - break; - case NTAP_OPT_IRCAPTURE: - if (is_bad_irval(pTap->ir_length, w)) { - LOG_ERROR("%s: IR capture %x too big", - pTap->dotted_name, (int) w); - return JIM_ERR; - } - if ((w & 3) != 1) - LOG_WARNING("%s: nonstandard IR value", - pTap->dotted_name); - pTap->ir_capture_value = w; - break; - default: - return JIM_ERR; - } - return JIM_OK; -} - -static int jim_newtap_cmd(Jim_GetOptInfo *goi) -{ - struct jtag_tap *pTap; - int x; - int e; - Jim_Nvp *n; - char *cp; - const Jim_Nvp opts[] = { - { .name = "-irlen", .value = NTAP_OPT_IRLEN }, - { .name = "-irmask", .value = NTAP_OPT_IRMASK }, - { .name = "-ircapture", .value = NTAP_OPT_IRCAPTURE }, - { .name = "-enable", .value = NTAP_OPT_ENABLED }, - { .name = "-disable", .value = NTAP_OPT_DISABLED }, - { .name = "-expected-id", .value = NTAP_OPT_EXPECTED_ID }, - { .name = "-ignore-version", .value = NTAP_OPT_VERSION }, - { .name = NULL, .value = -1 }, - }; - - pTap = calloc(1, sizeof(struct jtag_tap)); - if (!pTap) { - Jim_SetResultFormatted(goi->interp, "no memory"); - return JIM_ERR; - } - - /* - * we expect CHIP + TAP + OPTIONS - * */ - if (goi->argc < 3) { - Jim_SetResultFormatted(goi->interp, "Missing CHIP TAP OPTIONS ...."); - free(pTap); - return JIM_ERR; - } - - 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; - cp = malloc(x); - sprintf(cp, "%s.%s", pTap->chip, pTap->tapname); - pTap->dotted_name = cp; - - LOG_DEBUG("Creating New Tap, Chip: %s, Tap: %s, Dotted: %s, %d params", - pTap->chip, pTap->tapname, pTap->dotted_name, goi->argc); - - if (!transport_is_jtag()) { - /* SWD doesn't require any JTAG tap parameters */ - pTap->enabled = true; - jtag_tap_init(pTap); - return JIM_OK; - } - - /* IEEE specifies that the two LSBs of an IR scan are 01, so make - * that the default. The "-ircapture" and "-irmask" options are only - * needed to cope with nonstandard TAPs, or to specify more bits. - */ - pTap->ir_capture_mask = 0x03; - pTap->ir_capture_value = 0x01; - - while (goi->argc) { - e = Jim_GetOpt_Nvp(goi, opts, &n); - if (e != JIM_OK) { - Jim_GetOpt_NvpUnknown(goi, opts, 0); - free(cp); - free(pTap); - return e; - } - LOG_DEBUG("Processing option: %s", n->name); - switch (n->value) { - case NTAP_OPT_ENABLED: - pTap->disabled_after_reset = false; - break; - case NTAP_OPT_DISABLED: - pTap->disabled_after_reset = true; - break; - case NTAP_OPT_EXPECTED_ID: - e = jim_newtap_expected_id(n, goi, pTap); - if (JIM_OK != e) { - free(cp); - free(pTap); - return e; - } - break; - case NTAP_OPT_IRLEN: - case NTAP_OPT_IRMASK: - case NTAP_OPT_IRCAPTURE: - e = jim_newtap_ir_param(n, goi, pTap); - if (JIM_OK != e) { - free(cp); - free(pTap); - return e; - } - break; - case NTAP_OPT_VERSION: - pTap->ignore_version = true; - break; - } /* switch (n->value) */ - } /* while (goi->argc) */ - - /* default is enabled-after-reset */ - pTap->enabled = !pTap->disabled_after_reset; - - /* Did all the required option bits get cleared? */ - if (pTap->ir_length != 0) { - jtag_tap_init(pTap); - return JIM_OK; - } - - Jim_SetResultFormatted(goi->interp, - "newtap: %s missing IR length", - pTap->dotted_name); - jtag_tap_free(pTap); - return JIM_ERR; -} - -static void jtag_tap_handle_event(struct jtag_tap *tap, enum jtag_event e) -{ - struct jtag_tap_event_action *jteap; - - for (jteap = tap->event_action; jteap != NULL; jteap = jteap->next) { - if (jteap->event != e) - continue; - - Jim_Nvp *nvp = Jim_Nvp_value2name_simple(nvp_jtag_tap_event, e); - LOG_DEBUG("JTAG tap: %s event: %d (%s)\n\taction: %s", - tap->dotted_name, e, nvp->name, - Jim_GetString(jteap->body, NULL)); - - if (Jim_EvalObj(jteap->interp, jteap->body) != JIM_OK) { - Jim_MakeErrorMessage(jteap->interp); - LOG_USER("%s", Jim_GetString(Jim_GetResult(jteap->interp), NULL)); - continue; - } - - switch (e) { - case JTAG_TAP_EVENT_ENABLE: - case JTAG_TAP_EVENT_DISABLE: - /* NOTE: we currently assume the handlers - * can't fail. Right here is where we should - * really be verifying the scan chains ... - */ - tap->enabled = (e == JTAG_TAP_EVENT_ENABLE); - LOG_INFO("JTAG tap: %s %s", tap->dotted_name, - tap->enabled ? "enabled" : "disabled"); - break; - default: - break; - } - } -} - -static int jim_jtag_arp_init(Jim_Interp *interp, int argc, Jim_Obj *const *argv) -{ - Jim_GetOptInfo goi; - Jim_GetOpt_Setup(&goi, interp, argc-1, argv + 1); - if (goi.argc != 0) { - Jim_WrongNumArgs(goi.interp, 1, goi.argv-1, "(no params)"); - return JIM_ERR; - } - struct command_context *context = current_command_context(interp); - int e = jtag_init_inner(context); - if (e != ERROR_OK) { - Jim_Obj *eObj = Jim_NewIntObj(goi.interp, e); - Jim_SetResultFormatted(goi.interp, "error: %#s", eObj); - Jim_FreeNewObj(goi.interp, eObj); - return JIM_ERR; - } - return JIM_OK; -} - -static int jim_jtag_arp_init_reset(Jim_Interp *interp, int argc, Jim_Obj *const *argv) -{ - int e = ERROR_OK; - Jim_GetOptInfo goi; - Jim_GetOpt_Setup(&goi, interp, argc-1, argv + 1); - if (goi.argc != 0) { - Jim_WrongNumArgs(goi.interp, 1, goi.argv-1, "(no params)"); - return JIM_ERR; - } - struct command_context *context = current_command_context(interp); - if (transport_is_jtag()) - e = jtag_init_reset(context); - else if (transport_is_swd()) - e = swd_init_reset(context); - - if (e != ERROR_OK) { - Jim_Obj *eObj = Jim_NewIntObj(goi.interp, e); - Jim_SetResultFormatted(goi.interp, "error: %#s", eObj); - Jim_FreeNewObj(goi.interp, eObj); - return JIM_ERR; - } - return JIM_OK; -} - -int jim_jtag_newtap(Jim_Interp *interp, int argc, Jim_Obj *const *argv) -{ - Jim_GetOptInfo goi; - Jim_GetOpt_Setup(&goi, interp, argc-1, argv + 1); - return jim_newtap_cmd(&goi); -} - -static bool jtag_tap_enable(struct jtag_tap *t) -{ - if (t->enabled) - return false; - jtag_tap_handle_event(t, JTAG_TAP_EVENT_ENABLE); - if (!t->enabled) - return false; - - /* FIXME add JTAG sanity checks, w/o TLR - * - scan chain length grew by one (this) - * - IDs and IR lengths are as expected - */ - jtag_call_event_callbacks(JTAG_TAP_EVENT_ENABLE); - return true; -} -static bool jtag_tap_disable(struct jtag_tap *t) -{ - if (!t->enabled) - return false; - jtag_tap_handle_event(t, JTAG_TAP_EVENT_DISABLE); - if (t->enabled) - return false; - - /* FIXME add JTAG sanity checks, w/o TLR - * - scan chain length shrank by one (this) - * - IDs and IR lengths are as expected - */ - jtag_call_event_callbacks(JTAG_TAP_EVENT_DISABLE); - return true; -} - -int jim_jtag_tap_enabler(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) { - Jim_SetResultFormatted(goi.interp, "usage: %s ", cmd_name); - return JIM_ERR; - } - - struct jtag_tap *t; - - t = jtag_tap_by_jim_obj(goi.interp, goi.argv[0]); - if (t == NULL) - return JIM_ERR; - - if (strcasecmp(cmd_name, "tapisenabled") == 0) { - /* do nothing, just return the value */ - } else if (strcasecmp(cmd_name, "tapenable") == 0) { - if (!jtag_tap_enable(t)) { - LOG_WARNING("failed to enable tap %s", t->dotted_name); - return JIM_ERR; - } - } else if (strcasecmp(cmd_name, "tapdisable") == 0) { - if (!jtag_tap_disable(t)) { - LOG_WARNING("failed to disable tap %s", t->dotted_name); - return JIM_ERR; - } - } else { - LOG_ERROR("command '%s' unknown", cmd_name); - return JIM_ERR; - } - bool e = t->enabled; - Jim_SetResult(goi.interp, Jim_NewIntObj(goi.interp, e)); - return JIM_OK; -} - -int jim_jtag_configure(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); - goi.isconfigure = !strcmp(cmd_name, "configure"); - if (goi.argc < 2 + goi.isconfigure) { - Jim_WrongNumArgs(goi.interp, 0, NULL, - " ..."); - return JIM_ERR; - } - - struct jtag_tap *t; - - Jim_Obj *o; - Jim_GetOpt_Obj(&goi, &o); - t = jtag_tap_by_jim_obj(goi.interp, o); - if (t == NULL) - return JIM_ERR; - - return jtag_tap_configure_cmd(&goi, t); -} - -static int jim_jtag_names(Jim_Interp *interp, int argc, Jim_Obj *const *argv) -{ - Jim_GetOptInfo goi; - Jim_GetOpt_Setup(&goi, interp, argc-1, argv + 1); - if (goi.argc != 0) { - Jim_WrongNumArgs(goi.interp, 1, goi.argv, "Too many parameters"); - return JIM_ERR; - } - Jim_SetResult(goi.interp, Jim_NewListObj(goi.interp, NULL, 0)); - struct jtag_tap *tap; - - for (tap = jtag_all_taps(); tap; tap = tap->next_tap) { - Jim_ListAppendElement(goi.interp, - Jim_GetResult(goi.interp), - Jim_NewStringObj(goi.interp, - tap->dotted_name, -1)); - } - return JIM_OK; -} - -COMMAND_HANDLER(handle_jtag_init_command) -{ - if (CMD_ARGC != 0) - return ERROR_COMMAND_SYNTAX_ERROR; - - static bool jtag_initialized; - if (jtag_initialized) { - LOG_INFO("'jtag init' has already been called"); - return ERROR_OK; - } - jtag_initialized = true; - - LOG_DEBUG("Initializing jtag devices..."); - return jtag_init(CMD_CTX); -} - -static const struct command_registration jtag_subcommand_handlers[] = { - { - .name = "init", - .mode = COMMAND_ANY, - .handler = handle_jtag_init_command, - .help = "initialize jtag scan chain", - .usage = "" - }, - { - .name = "arp_init", - .mode = COMMAND_ANY, - .jim_handler = jim_jtag_arp_init, - .help = "Validates JTAG scan chain against the list of " - "declared TAPs using just the four standard JTAG " - "signals.", - }, - { - .name = "arp_init-reset", - .mode = COMMAND_ANY, - .jim_handler = jim_jtag_arp_init_reset, - .help = "Uses TRST and SRST to try resetting everything on " - "the JTAG scan chain, then performs 'jtag arp_init'." - }, - { - .name = "newtap", - .mode = COMMAND_CONFIG, - .jim_handler = jim_jtag_newtap, - .help = "Create a new TAP instance named basename.tap_type, " - "and appends it to the scan chain.", - .usage = "basename tap_type '-irlen' count " - "['-enable'|'-disable'] " - "['-expected_id' number] " - "['-ignore-version'] " - "['-ircapture' number] " - "['-mask' number] ", - }, - { - .name = "tapisenabled", - .mode = COMMAND_EXEC, - .jim_handler = jim_jtag_tap_enabler, - .help = "Returns a Tcl boolean (0/1) indicating whether " - "the TAP is enabled (1) or not (0).", - .usage = "tap_name", - }, - { - .name = "tapenable", - .mode = COMMAND_EXEC, - .jim_handler = jim_jtag_tap_enabler, - .help = "Try to enable the specified TAP using the " - "'tap-enable' TAP event.", - .usage = "tap_name", - }, - { - .name = "tapdisable", - .mode = COMMAND_EXEC, - .jim_handler = jim_jtag_tap_enabler, - .help = "Try to disable the specified TAP using the " - "'tap-disable' TAP event.", - .usage = "tap_name", - }, - { - .name = "configure", - .mode = COMMAND_EXEC, - .jim_handler = jim_jtag_configure, - .help = "Provide a Tcl handler for the specified " - "TAP event.", - .usage = "tap_name '-event' event_name handler", - }, - { - .name = "cget", - .mode = COMMAND_EXEC, - .jim_handler = jim_jtag_configure, - .help = "Return any Tcl handler for the specified " - "TAP event.", - .usage = "tap_name '-event' event_name", - }, - { - .name = "names", - .mode = COMMAND_ANY, - .jim_handler = jim_jtag_names, - .help = "Returns list of all JTAG tap names.", - }, - { - .chain = jtag_command_handlers_to_move, - }, - COMMAND_REGISTRATION_DONE -}; - -void jtag_notify_event(enum jtag_event event) -{ - struct jtag_tap *tap; - - for (tap = jtag_all_taps(); tap; tap = tap->next_tap) - jtag_tap_handle_event(tap, event); -} - - -COMMAND_HANDLER(handle_scan_chain_command) -{ - struct jtag_tap *tap; - char expected_id[12]; - - tap = jtag_all_taps(); - command_print(CMD_CTX, - " TapName Enabled IdCode Expected IrLen IrCap IrMask"); - command_print(CMD_CTX, - "-- ------------------- -------- ---------- ---------- ----- ----- ------"); - - while (tap) { - uint32_t expected, expected_mask, ii; - - snprintf(expected_id, sizeof expected_id, "0x%08x", - (unsigned)((tap->expected_ids_cnt > 0) - ? tap->expected_ids[0] - : 0)); - if (tap->ignore_version) - expected_id[2] = '*'; - - expected = buf_get_u32(tap->expected, 0, tap->ir_length); - expected_mask = buf_get_u32(tap->expected_mask, 0, tap->ir_length); - - command_print(CMD_CTX, - "%2d %-18s %c 0x%08x %s %5d 0x%02x 0x%02x", - tap->abs_chain_position, - tap->dotted_name, - tap->enabled ? 'Y' : 'n', - (unsigned int)(tap->idcode), - expected_id, - (unsigned int)(tap->ir_length), - (unsigned int)(expected), - (unsigned int)(expected_mask)); - - for (ii = 1; ii < tap->expected_ids_cnt; ii++) { - snprintf(expected_id, sizeof expected_id, "0x%08x", - (unsigned) tap->expected_ids[ii]); - if (tap->ignore_version) - expected_id[2] = '*'; - - command_print(CMD_CTX, - " %s", - expected_id); - } - - tap = tap->next_tap; - } - - return ERROR_OK; -} - -COMMAND_HANDLER(handle_jtag_ntrst_delay_command) -{ - if (CMD_ARGC > 1) - return ERROR_COMMAND_SYNTAX_ERROR; - if (CMD_ARGC == 1) { - unsigned delay; - COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], delay); - - jtag_set_ntrst_delay(delay); - } - command_print(CMD_CTX, "jtag_ntrst_delay: %u", jtag_get_ntrst_delay()); - return ERROR_OK; -} - -COMMAND_HANDLER(handle_jtag_ntrst_assert_width_command) -{ - if (CMD_ARGC > 1) - return ERROR_COMMAND_SYNTAX_ERROR; - if (CMD_ARGC == 1) { - unsigned delay; - COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], delay); - - jtag_set_ntrst_assert_width(delay); - } - command_print(CMD_CTX, "jtag_ntrst_assert_width: %u", jtag_get_ntrst_assert_width()); - return ERROR_OK; -} - -COMMAND_HANDLER(handle_jtag_rclk_command) -{ - if (CMD_ARGC > 1) - return ERROR_COMMAND_SYNTAX_ERROR; - - int retval = ERROR_OK; - if (CMD_ARGC == 1) { - unsigned khz = 0; - COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], khz); - - retval = jtag_config_rclk(khz); - if (ERROR_OK != retval) - return retval; - } - - int cur_khz = jtag_get_speed_khz(); - retval = jtag_get_speed_readable(&cur_khz); - if (ERROR_OK != retval) - return retval; - - if (cur_khz) - command_print(CMD_CTX, "RCLK not supported - fallback to %d kHz", cur_khz); - else - command_print(CMD_CTX, "RCLK - adaptive"); - - return retval; -} - -COMMAND_HANDLER(handle_jtag_reset_command) -{ - if (CMD_ARGC != 2) - return ERROR_COMMAND_SYNTAX_ERROR; - - int trst = -1; - if (CMD_ARGV[0][0] == '1') - trst = 1; - else if (CMD_ARGV[0][0] == '0') - trst = 0; - else - return ERROR_COMMAND_SYNTAX_ERROR; - - int srst = -1; - if (CMD_ARGV[1][0] == '1') - srst = 1; - else if (CMD_ARGV[1][0] == '0') - srst = 0; - else - return ERROR_COMMAND_SYNTAX_ERROR; - - if (adapter_init(CMD_CTX) != ERROR_OK) - return ERROR_JTAG_INIT_FAILED; - - jtag_add_reset(trst, srst); - return jtag_execute_queue(); -} - -COMMAND_HANDLER(handle_runtest_command) -{ - if (CMD_ARGC != 1) - return ERROR_COMMAND_SYNTAX_ERROR; - - unsigned num_clocks; - COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], num_clocks); - - jtag_add_runtest(num_clocks, TAP_IDLE); - return jtag_execute_queue(); -} - -/* - * For "irscan" or "drscan" commands, the "end" (really, "next") state - * should be stable ... and *NOT* a shift state, otherwise free-running - * jtag clocks could change the values latched by the update state. - * Not surprisingly, this is the same constraint as SVF; the "irscan" - * and "drscan" commands are a write-only subset of what SVF provides. - */ - -COMMAND_HANDLER(handle_irscan_command) -{ - int i; - struct scan_field *fields; - struct jtag_tap *tap = NULL; - tap_state_t endstate; - - if ((CMD_ARGC < 2) || (CMD_ARGC % 2)) - return ERROR_COMMAND_SYNTAX_ERROR; - - /* optional "-endstate" "statename" at the end of the arguments, - * so that e.g. IRPAUSE can let us load the data register before - * entering RUN/IDLE to execute the instruction we load here. - */ - endstate = TAP_IDLE; - - if (CMD_ARGC >= 4) { - /* have at least one pair of numbers. - * is last pair the magic text? */ - if (strcmp("-endstate", CMD_ARGV[CMD_ARGC - 2]) == 0) { - endstate = tap_state_by_name(CMD_ARGV[CMD_ARGC - 1]); - if (endstate == TAP_INVALID) - return ERROR_COMMAND_SYNTAX_ERROR; - if (!scan_is_safe(endstate)) - LOG_WARNING("unstable irscan endstate \"%s\"", - CMD_ARGV[CMD_ARGC - 1]); - CMD_ARGC -= 2; - } - } - - int num_fields = CMD_ARGC / 2; - if (num_fields > 1) { - /* we really should be looking at plain_ir_scan if we want - * anything more fancy. - */ - LOG_ERROR("Specify a single value for tap"); - return ERROR_COMMAND_SYNTAX_ERROR; - } - - fields = calloc(num_fields, sizeof(*fields)); - - int retval; - for (i = 0; i < num_fields; i++) { - tap = jtag_tap_by_string(CMD_ARGV[i*2]); - if (tap == NULL) { - free(fields); - command_print(CMD_CTX, "Tap: %s unknown", CMD_ARGV[i*2]); - - return ERROR_FAIL; - } - int field_size = tap->ir_length; - fields[i].num_bits = field_size; - uint8_t *v = malloc(DIV_ROUND_UP(field_size, 8)); - - uint64_t value; - retval = parse_u64(CMD_ARGV[i * 2 + 1], &value); - if (ERROR_OK != retval) - goto error_return; - buf_set_u64(v, 0, field_size, value); - fields[i].out_value = v; - fields[i].in_value = NULL; - } - - /* did we have an endstate? */ - jtag_add_ir_scan(tap, fields, endstate); - - retval = jtag_execute_queue(); - -error_return: - for (i = 0; i < num_fields; i++) { - if (NULL != fields[i].out_value) - free((void *)fields[i].out_value); - } - - free(fields); - - return retval; -} - -COMMAND_HANDLER(handle_verify_ircapture_command) -{ - if (CMD_ARGC > 1) - return ERROR_COMMAND_SYNTAX_ERROR; - - if (CMD_ARGC == 1) { - bool enable; - COMMAND_PARSE_ENABLE(CMD_ARGV[0], enable); - jtag_set_verify_capture_ir(enable); - } - - const char *status = jtag_will_verify_capture_ir() ? "enabled" : "disabled"; - command_print(CMD_CTX, "verify Capture-IR is %s", status); - - return ERROR_OK; -} - -COMMAND_HANDLER(handle_verify_jtag_command) -{ - if (CMD_ARGC > 1) - return ERROR_COMMAND_SYNTAX_ERROR; - - if (CMD_ARGC == 1) { - bool enable; - COMMAND_PARSE_ENABLE(CMD_ARGV[0], enable); - jtag_set_verify(enable); - } - - const char *status = jtag_will_verify() ? "enabled" : "disabled"; - command_print(CMD_CTX, "verify jtag capture is %s", status); - - return ERROR_OK; -} - -COMMAND_HANDLER(handle_tms_sequence_command) -{ - if (CMD_ARGC > 1) - return ERROR_COMMAND_SYNTAX_ERROR; - - if (CMD_ARGC == 1) { - bool use_new_table; - if (strcmp(CMD_ARGV[0], "short") == 0) - use_new_table = true; - else if (strcmp(CMD_ARGV[0], "long") == 0) - use_new_table = false; - else - return ERROR_COMMAND_SYNTAX_ERROR; - - tap_use_new_tms_table(use_new_table); - } - - command_print(CMD_CTX, "tms sequence is %s", - tap_uses_new_tms_table() ? "short" : "long"); - - return ERROR_OK; -} - -COMMAND_HANDLER(handle_jtag_flush_queue_sleep) -{ - if (CMD_ARGC != 1) - return ERROR_COMMAND_SYNTAX_ERROR; - - int sleep_ms; - COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], sleep_ms); - - jtag_set_flush_queue_sleep(sleep_ms); - - return ERROR_OK; -} - -COMMAND_HANDLER(handle_wait_srst_deassert) -{ - if (CMD_ARGC != 1) - return ERROR_COMMAND_SYNTAX_ERROR; - - int timeout_ms; - COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], timeout_ms); - if ((timeout_ms <= 0) || (timeout_ms > 100000)) { - LOG_ERROR("Timeout must be an integer between 0 and 100000"); - return ERROR_FAIL; - } - - LOG_USER("Waiting for srst assert + deassert for at most %dms", timeout_ms); - int asserted_yet; - int64_t then = timeval_ms(); - while (jtag_srst_asserted(&asserted_yet) == ERROR_OK) { - if ((timeval_ms() - then) > timeout_ms) { - LOG_ERROR("Timed out"); - return ERROR_FAIL; - } - if (asserted_yet) - break; - } - while (jtag_srst_asserted(&asserted_yet) == ERROR_OK) { - if ((timeval_ms() - then) > timeout_ms) { - LOG_ERROR("Timed out"); - return ERROR_FAIL; - } - if (!asserted_yet) - break; - } - - return ERROR_OK; -} - -static const struct command_registration jtag_command_handlers[] = { - - { - .name = "jtag_flush_queue_sleep", - .handler = handle_jtag_flush_queue_sleep, - .mode = COMMAND_ANY, - .help = "For debug purposes(simulate long delays of interface) " - "to test performance or change in behavior. Default 0ms.", - .usage = "[sleep in ms]", - }, - { - .name = "jtag_rclk", - .handler = handle_jtag_rclk_command, - .mode = COMMAND_ANY, - .help = "With an argument, change to to use adaptive clocking " - "if possible; else to use the fallback speed. " - "With or without argument, display current setting.", - .usage = "[fallback_speed_khz]", - }, - { - .name = "jtag_ntrst_delay", - .handler = handle_jtag_ntrst_delay_command, - .mode = COMMAND_ANY, - .help = "delay after deasserting trst in ms", - .usage = "[milliseconds]", - }, - { - .name = "jtag_ntrst_assert_width", - .handler = handle_jtag_ntrst_assert_width_command, - .mode = COMMAND_ANY, - .help = "delay after asserting trst in ms", - .usage = "[milliseconds]", - }, - { - .name = "scan_chain", - .handler = handle_scan_chain_command, - .mode = COMMAND_ANY, - .help = "print current scan chain configuration", - .usage = "" - }, - { - .name = "jtag_reset", - .handler = handle_jtag_reset_command, - .mode = COMMAND_EXEC, - .help = "Set reset line values. Value '1' is active, " - "value '0' is inactive.", - .usage = "trst_active srst_active", - }, - { - .name = "runtest", - .handler = handle_runtest_command, - .mode = COMMAND_EXEC, - .help = "Move to Run-Test/Idle, and issue TCK for num_cycles.", - .usage = "num_cycles" - }, - { - .name = "irscan", - .handler = handle_irscan_command, - .mode = COMMAND_EXEC, - .help = "Execute Instruction Register (DR) scan. The " - "specified opcodes are put into each TAP's IR, " - "and other TAPs are put in BYPASS.", - .usage = "[tap_name instruction]* ['-endstate' state_name]", - }, - { - .name = "verify_ircapture", - .handler = handle_verify_ircapture_command, - .mode = COMMAND_ANY, - .help = "Display or assign flag controlling whether to " - "verify values captured during Capture-IR.", - .usage = "['enable'|'disable']", - }, - { - .name = "verify_jtag", - .handler = handle_verify_jtag_command, - .mode = COMMAND_ANY, - .help = "Display or assign flag controlling whether to " - "verify values captured during IR and DR scans.", - .usage = "['enable'|'disable']", - }, - { - .name = "tms_sequence", - .handler = handle_tms_sequence_command, - .mode = COMMAND_ANY, - .help = "Display or change what style TMS sequences to use " - "for JTAG state transitions: short (default) or " - "long. Only for working around JTAG bugs.", - /* Specifically for working around DRIVER bugs... */ - .usage = "['short'|'long']", - }, - { - .name = "wait_srst_deassert", - .handler = handle_wait_srst_deassert, - .mode = COMMAND_ANY, - .help = "Wait for an SRST deassert. " - "Useful for cases where you need something to happen within ms " - "of an srst deassert. Timeout in ms ", - .usage = "ms", - }, - { - .name = "jtag", - .mode = COMMAND_ANY, - .help = "perform jtag tap actions", - .usage = "", - - .chain = jtag_subcommand_handlers, - }, - { - .chain = jtag_command_handlers_to_move, - }, - COMMAND_REGISTRATION_DONE -}; - -int jtag_register_commands(struct command_context *cmd_ctx) -{ - return register_commands(cmd_ctx, NULL, jtag_command_handlers); -} diff --git a/src/jtag/tcl.h b/src/jtag/tcl.h deleted file mode 100644 index 932b47ac8..000000000 --- a/src/jtag/tcl.h +++ /dev/null @@ -1,37 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * Copyright (C) 2007-2010 Øyvind Harboe * - * oyvind.harboe@zylin.com * - * * - * Copyright (C) 2009 SoftPLC Corporation * - * http://softplc.com * - * dick@softplc.com * - * * - * Copyright (C) 2009 Zachary T Welch * - * zw@superlucidity.net * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#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 /* OPENOCD_JTAG_TCL_H */ diff --git a/src/jtag/zy1000/jtag_minidriver.h b/src/jtag/zy1000/jtag_minidriver.h deleted file mode 100644 index 7d1ede5d4..000000000 --- a/src/jtag/zy1000/jtag_minidriver.h +++ /dev/null @@ -1,182 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007-2010 by Øyvind Harboe * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -/* used to test manual mode */ -#define TEST_MANUAL() 0 -#define VERBOSE(a) - -#if BUILD_ZY1000_MASTER - -#define ZY1000_PEEK(a, b) do {b = *((volatile uint32_t *)(a)); } while (0) -#define ZY1000_POKE(a, b) do {*((volatile uint32_t *)(a)) = b; } while (0) -extern volatile void *zy1000_jtag_master; -#define ZY1000_JTAG_BASE ((unsigned long)zy1000_jtag_master) - -#else - -/* redirect this to TCP/IP */ -#define ZY1000_JTAG_BASE 0 -extern void zy1000_tcpout(uint32_t address, uint32_t data); -extern uint32_t zy1000_tcpin(uint32_t address); -#define ZY1000_PEEK(a, b) b = zy1000_tcpin(a) -#define ZY1000_POKE(a, b) zy1000_tcpout(a, b) - -#endif - -#if BUILD_ZY1000_MASTER -/* FIFO empty? */ -static inline void waitIdle(void) -{ - uint32_t empty; - do { - ZY1000_PEEK(ZY1000_JTAG_BASE + 0x10, empty); - } while ((empty & 0x100) == 0); -} - -static inline void zy1000_flush_readqueue(void) -{ - /* Not used w/hardware fifo */ -} -static inline void zy1000_flush_callbackqueue(void) -{ - /* Not used w/hardware fifo */ -} -#else -extern void waitIdle(void); -void zy1000_flush_readqueue(void); -void zy1000_flush_callbackqueue(void); -void zy1000_jtag_add_callback4(jtag_callback_t callback, - jtag_callback_data_t data0, - jtag_callback_data_t data1, - jtag_callback_data_t data2, - jtag_callback_data_t data3); -void zy1000_jtag_add_callback(jtag_callback1_t callback, jtag_callback_data_t data0); -#endif - -static inline void waitQueue(void) -{ -/* waitIdle(); */ -} - -static inline void sampleShiftRegister(void) -{ -#if 0 - uint32_t dummy; - waitIdle(); - ZY1000_PEEK(ZY1000_JTAG_BASE + 0xc, dummy); -#endif -} - -static inline void setCurrentState(enum tap_state state) -{ - uint32_t a; - a = state; - int repeat = 0; - if (state == TAP_RESET) { - /* The FPGA nor we know the current state of the CPU TAP */ - /* controller. This will move it to TAP for sure. */ - /* */ - /* 5 should be enough here, 7 is what OpenOCD uses */ - repeat = 7; - } - waitQueue(); - sampleShiftRegister(); - ZY1000_POKE(ZY1000_JTAG_BASE + 0x8, (repeat << 8) | (a << 4) | a); - -} - -/* - * Enter state and cause repeat transitions *out* of that state. So if the endState != state, then - * the transition from state to endState counts as a transition out of state. - */ -static inline void shiftValueInner(const enum tap_state state, - const enum tap_state endState, - int repeat, - uint32_t value) -{ - uint32_t a, b; - a = state; - b = endState; - waitQueue(); - sampleShiftRegister(); - ZY1000_POKE(ZY1000_JTAG_BASE + 0xc, value); -#if 1 -#if TEST_MANUAL() - if ((state == TAP_DRSHIFT) && (endState != TAP_DRSHIFT)) { - int i; - setCurrentState(state); - for (i = 0; i < repeat; i++) { - int tms; - tms = 0; - if ((i == repeat-1) && (state != endState)) - tms = 1; - /* shift out value */ - waitIdle(); - ZY1000_POKE(ZY1000_JTAG_BASE + 0x28, (((value >> i)&1) << 1) | tms); - } - waitIdle(); - ZY1000_POKE(ZY1000_JTAG_BASE + 0x28, 0); - waitIdle(); - /* ZY1000_POKE(ZY1000_JTAG_BASE + 0x20, TAP_DRSHIFT); // set this state and things - * break => expected */ - ZY1000_POKE(ZY1000_JTAG_BASE + 0x20, TAP_DRPAUSE); /* set this and things will - * work => expected. Not - * setting this is not - * sufficient to make things - * break. */ - setCurrentState(endState); - } else - ZY1000_POKE(ZY1000_JTAG_BASE + 0x8, (repeat << 8) | (a << 4) | b); - -#else - /* fast version */ - ZY1000_POKE(ZY1000_JTAG_BASE + 0x8, (repeat << 8) | (a << 4) | b); -#endif -#else - /* maximum debug version */ - if ((repeat > 0) && ((state == TAP_DRSHIFT) || (state == TAP_SI))) { - int i; - /* sample shift register for every bit. */ - for (i = 0; i < repeat-1; i++) { - sampleShiftRegister(); - ZY1000_POKE(ZY1000_JTAG_BASE + 0xc, value >> i); - ZY1000_POKE(ZY1000_JTAG_BASE + 0x8, (1 << 8) | (a << 4) | a); - } - sampleShiftRegister(); - ZY1000_POKE(ZY1000_JTAG_BASE + 0xc, value >> (repeat-1)); - ZY1000_POKE(ZY1000_JTAG_BASE + 0x8, (1 << 8) | (a << 4) | b); - } else { - sampleShiftRegister(); - ZY1000_POKE(ZY1000_JTAG_BASE + 0x8, (repeat << 8) | (a << 4) | b); - } - sampleShiftRegister(); -#endif -} - -#if BUILD_ZY1000_MASTER -#define interface_jtag_add_callback(callback, in) callback(in) -#define interface_jtag_add_callback4(callback, in, data1, data2, \ - data3) jtag_set_error(callback(in, data1, data2, data3)) -#else -#define interface_jtag_add_callback(callback, in) zy1000_jtag_add_callback(callback, in) -#define interface_jtag_add_callback4(callback, in, data1, data2, data3) zy1000_jtag_add_callback4( \ - callback, \ - in, \ - data1, \ - data2, \ - data3) -#endif diff --git a/src/jtag/zy1000/zy1000.c b/src/jtag/zy1000/zy1000.c deleted file mode 100644 index 67d990700..000000000 --- a/src/jtag/zy1000/zy1000.c +++ /dev/null @@ -1,1252 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007-2010 by Øyvind Harboe * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -/* This file supports the zy1000 debugger: - * - * http://www.ultsol.com/index.php/component/content/article/8/33-zylin-zy1000-jtag-probe - * - * The zy1000 is a standalone debugger that has a web interface and - * requires no drivers on the developer host as all communication - * is via TCP/IP. The zy1000 gets it performance(~400-700kBytes/s - * DCC downloads @ 16MHz target) as it has an FPGA to hardware - * accelerate the JTAG commands, while offering *very* low latency - * between OpenOCD and the FPGA registers. - * - * The disadvantage of the zy1000 is that it has a feeble CPU compared to - * a PC(ca. 50-500 DMIPS depending on how one counts it), whereas a PC - * is on the order of 10000 DMIPS(i.e. at a factor of 20-200). - * - * The zy1000 revc hardware is using an Altera Nios CPU, whereas the - * revb is using ARM7 + Xilinx. - * - * See Zylin web pages or contact Zylin for more information. - * - * The reason this code is in OpenOCD rather than OpenOCD linked with the - * ZY1000 code is that OpenOCD is the long road towards getting - * libopenocd into place. libopenocd will support both low performance, - * low latency systems(embedded) and high performance high latency - * systems(PCs). - */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include - -#include -#include -#include -#include -#include - -#include - -/* Assume we're connecting to a revc w/60MHz clock. */ -#define ZYLIN_KHZ 60000 - -/* The software needs to check if it's in RCLK mode or not */ -static bool zy1000_rclk; - -static int zy1000_khz(int khz, int *jtag_speed) -{ - if (khz == 0) - *jtag_speed = 0; - else { - int speed; - /* Round speed up to nearest divisor. - * - * E.g. 16000kHz - * (64000 + 15999) / 16000 = 4 - * (4 + 1) / 2 = 2 - * 2 * 2 = 4 - * - * 64000 / 4 = 16000 - * - * E.g. 15999 - * (64000 + 15998) / 15999 = 5 - * (5 + 1) / 2 = 3 - * 3 * 2 = 6 - * - * 64000 / 6 = 10666 - * - */ - speed = (ZYLIN_KHZ + (khz - 1)) / khz; - speed = (speed + 1) / 2; - speed *= 2; - if (speed > 8190) { - /* maximum dividend */ - speed = 8190; - } - *jtag_speed = speed; - } - return ERROR_OK; -} - -static int zy1000_speed_div(int speed, int *khz) -{ - if (speed == 0) - *khz = 0; - else - *khz = ZYLIN_KHZ / speed; - - return ERROR_OK; -} - -static bool readPowerDropout(void) -{ - uint32_t state; - /* sample and clear power dropout */ - ZY1000_POKE(ZY1000_JTAG_BASE + 0x10, 0x80); - ZY1000_PEEK(ZY1000_JTAG_BASE + 0x10, state); - bool powerDropout; - powerDropout = (state & 0x80) != 0; - return powerDropout; -} - - -static bool readSRST(void) -{ - uint32_t state; - /* sample and clear SRST sensing */ - ZY1000_POKE(ZY1000_JTAG_BASE + 0x10, 0x00000040); - ZY1000_PEEK(ZY1000_JTAG_BASE + 0x10, state); - bool srstAsserted; - srstAsserted = (state & 0x40) != 0; - return srstAsserted; -} - -static int zy1000_srst_asserted(int *srst_asserted) -{ - *srst_asserted = readSRST(); - return ERROR_OK; -} - -static int zy1000_power_dropout(int *dropout) -{ - *dropout = readPowerDropout(); - return ERROR_OK; -} - -/* Wait for SRST to assert or deassert */ -static void waitSRST(bool asserted) -{ - bool first = true; - int64_t start = 0; - int64_t total = 0; - const char *mode = asserted ? "assert" : "deassert"; - - for (;; ) { - bool srstAsserted = readSRST(); - if ((asserted && srstAsserted) || (!asserted && !srstAsserted)) { - if (total > 1) - LOG_USER("SRST took %dms to %s", (int)total, mode); - break; - } - - if (first) { - first = false; - start = timeval_ms(); - } - - total = timeval_ms() - start; - - keep_alive(); - - if (total > 5000) { - LOG_ERROR("SRST took too long to %s: %" PRId64 "ms", mode, total); - break; - } - } -} - -void zy1000_reset(int trst, int srst) -{ - LOG_DEBUG("zy1000 trst=%d, srst=%d", trst, srst); - - /* flush the JTAG FIFO. Not flushing the queue before messing with - * reset has such interesting bugs as causing hard to reproduce - * RCLK bugs as RCLK will stop responding when TRST is asserted - */ - waitIdle(); - - if (!srst) - ZY1000_POKE(ZY1000_JTAG_BASE + 0x14, 0x00000001); - else { - /* Danger!!! if clk != 0 when in - * idle in TAP_IDLE, reset halt on str912 will fail. - */ - ZY1000_POKE(ZY1000_JTAG_BASE + 0x10, 0x00000001); - - waitSRST(true); - } - - if (!trst) - ZY1000_POKE(ZY1000_JTAG_BASE + 0x14, 0x00000002); - else { - /* assert reset */ - ZY1000_POKE(ZY1000_JTAG_BASE + 0x10, 0x00000002); - } - - if (trst || (srst && (jtag_get_reset_config() & RESET_SRST_PULLS_TRST))) { - /* we're now in the RESET state until trst is deasserted */ - ZY1000_POKE(ZY1000_JTAG_BASE + 0x20, TAP_RESET); - } else { - /* We'll get RCLK failure when we assert TRST, so clear any false positives here */ - ZY1000_POKE(ZY1000_JTAG_BASE + 0x14, 0x400); - } - - /* wait for srst to float back up */ - if ((!srst && ((jtag_get_reset_config() & RESET_TRST_PULLS_SRST) == 0)) || - (!srst && !trst && (jtag_get_reset_config() & RESET_TRST_PULLS_SRST))) - waitSRST(false); -} - -int zy1000_speed(int speed) -{ - /* flush JTAG master FIFO before setting speed */ - waitIdle(); - - zy1000_rclk = false; - - if (speed == 0) { - /*0 means RCLK*/ - ZY1000_POKE(ZY1000_JTAG_BASE + 0x10, 0x100); - zy1000_rclk = true; - LOG_DEBUG("jtag_speed using RCLK"); - } else { - if (speed > 8190 || speed < 2) { - LOG_USER( - "valid ZY1000 jtag_speed=[8190,2]. With divisor is %dkHz / even values between 8190-2, i.e. min %dHz, max %dMHz", - ZYLIN_KHZ, - (ZYLIN_KHZ * 1000) / 8190, - ZYLIN_KHZ / (2 * 1000)); - return ERROR_COMMAND_SYNTAX_ERROR; - } - - int khz; - speed &= ~1; - zy1000_speed_div(speed, &khz); - LOG_USER("jtag_speed %d => JTAG clk=%d kHz", speed, khz); - ZY1000_POKE(ZY1000_JTAG_BASE + 0x14, 0x100); - ZY1000_POKE(ZY1000_JTAG_BASE + 0x1c, speed); - } - return ERROR_OK; -} - -static bool savePower; - -static void setPower(bool power) -{ - savePower = power; - if (power) - ZY1000_POKE(ZY1000_JTAG_BASE + 0x14, 0x8); - else - ZY1000_POKE(ZY1000_JTAG_BASE + 0x10, 0x8); -} - -COMMAND_HANDLER(handle_power_command) -{ - switch (CMD_ARGC) { - case 1: { - bool enable; - COMMAND_PARSE_ON_OFF(CMD_ARGV[0], enable); - setPower(enable); - /* fall through */ - } - case 0: - LOG_INFO("Target power %s", savePower ? "on" : "off"); - break; - default: - return ERROR_COMMAND_SYNTAX_ERROR; - } - - return ERROR_OK; -} - -#if !BUILD_ZY1000_MASTER -static char *tcp_server = "notspecified"; -static int jim_zy1000_server(Jim_Interp *interp, int argc, Jim_Obj * const *argv) -{ - if (argc != 2) - return JIM_ERR; - - tcp_server = strdup(Jim_GetString(argv[1], NULL)); - - return JIM_OK; -} -#endif - -static int zylinjtag_Jim_Command_powerstatus(Jim_Interp *interp, - int argc, - Jim_Obj * const *argv) -{ - if (argc != 1) { - Jim_WrongNumArgs(interp, 1, argv, "powerstatus"); - return JIM_ERR; - } - - bool dropout = readPowerDropout(); - - Jim_SetResult(interp, Jim_NewIntObj(interp, dropout)); - - return JIM_OK; -} - -int zy1000_quit(void) -{ - - return ERROR_OK; -} - -int interface_jtag_execute_queue(void) -{ - uint32_t empty; - - waitIdle(); - - /* We must make sure to write data read back to memory location before we return - * from this fn - */ - zy1000_flush_readqueue(); - - /* and handle any callbacks... */ - zy1000_flush_callbackqueue(); - - if (zy1000_rclk) { - /* Only check for errors when using RCLK to speed up - * jtag over TCP/IP - */ - ZY1000_PEEK(ZY1000_JTAG_BASE + 0x10, empty); - /* clear JTAG error register */ - ZY1000_POKE(ZY1000_JTAG_BASE + 0x14, 0x400); - - if ((empty&0x400) != 0) { - LOG_WARNING("RCLK timeout"); - /* the error is informative only as we don't want to break the firmware if there - * is a false positive. - */ - /* return ERROR_FAIL; */ - } - } - return ERROR_OK; -} - -static void writeShiftValue(uint8_t *data, int bits); - -/* here we shuffle N bits out/in */ -static inline void scanBits(const uint8_t *out_value, - uint8_t *in_value, - int num_bits, - bool pause_now, - tap_state_t shiftState, - tap_state_t end_state) -{ - tap_state_t pause_state = shiftState; - for (int j = 0; j < num_bits; j += 32) { - int k = num_bits - j; - if (k > 32) { - k = 32; - /* we have more to shift out */ - } else if (pause_now) { - /* this was the last to shift out this time */ - pause_state = end_state; - } - - /* we have (num_bits + 7)/8 bytes of bits to toggle out. */ - /* bits are pushed out LSB to MSB */ - uint32_t value; - value = 0; - if (out_value != NULL) { - for (int l = 0; l < k; l += 8) - value |= out_value[(j + l)/8]<= 32 is not defined by the C standard - * and will in fact shift by &0x1f bits on nios */ - } - - shiftValueInner(shiftState, pause_state, k, value); - - if (in_value != NULL) - writeShiftValue(in_value + (j/8), k); - } -} - -static inline void scanFields(int num_fields, - const struct scan_field *fields, - tap_state_t shiftState, - tap_state_t end_state) -{ - for (int i = 0; i < num_fields; i++) { - scanBits(fields[i].out_value, - fields[i].in_value, - fields[i].num_bits, - (i == num_fields-1), - shiftState, - end_state); - } -} - -int interface_jtag_add_ir_scan(struct jtag_tap *active, - const struct scan_field *fields, - tap_state_t state) -{ - int scan_size = 0; - struct jtag_tap *tap, *nextTap; - tap_state_t pause_state = TAP_IRSHIFT; - - for (tap = jtag_tap_next_enabled(NULL); tap != NULL; tap = nextTap) { - nextTap = jtag_tap_next_enabled(tap); - if (nextTap == NULL) - pause_state = state; - scan_size = tap->ir_length; - - /* search the list */ - if (tap == active) { - scanFields(1, fields, TAP_IRSHIFT, pause_state); - /* update device information */ - buf_cpy(fields[0].out_value, tap->cur_instr, scan_size); - - tap->bypass = 0; - } else { - /* if a device isn't listed, set it to BYPASS */ - assert(scan_size <= 32); - shiftValueInner(TAP_IRSHIFT, pause_state, scan_size, 0xffffffff); - - /* Optimization code will check what the cur_instr is set to, so - * we must set it to bypass value. - */ - buf_set_ones(tap->cur_instr, tap->ir_length); - - tap->bypass = 1; - } - } - - return ERROR_OK; -} - -int interface_jtag_add_plain_ir_scan(int num_bits, - const uint8_t *out_bits, - uint8_t *in_bits, - tap_state_t state) -{ - scanBits(out_bits, in_bits, num_bits, true, TAP_IRSHIFT, state); - return ERROR_OK; -} - -int interface_jtag_add_dr_scan(struct jtag_tap *active, - int num_fields, - const struct scan_field *fields, - tap_state_t state) -{ - struct jtag_tap *tap, *nextTap; - tap_state_t pause_state = TAP_DRSHIFT; - for (tap = jtag_tap_next_enabled(NULL); tap != NULL; tap = nextTap) { - nextTap = jtag_tap_next_enabled(tap); - if (nextTap == NULL) - pause_state = state; - - /* Find a range of fields to write to this tap */ - if (tap == active) { - assert(!tap->bypass); - - scanFields(num_fields, fields, TAP_DRSHIFT, pause_state); - } else { - /* Shift out a 0 for disabled tap's */ - assert(tap->bypass); - shiftValueInner(TAP_DRSHIFT, pause_state, 1, 0); - } - } - return ERROR_OK; -} - -int interface_jtag_add_plain_dr_scan(int num_bits, - const uint8_t *out_bits, - uint8_t *in_bits, - tap_state_t state) -{ - scanBits(out_bits, in_bits, num_bits, true, TAP_DRSHIFT, state); - return ERROR_OK; -} - -int interface_jtag_add_tlr() -{ - setCurrentState(TAP_RESET); - return ERROR_OK; -} - -int interface_jtag_add_reset(int req_trst, int req_srst) -{ - zy1000_reset(req_trst, req_srst); - return ERROR_OK; -} - -static int zy1000_jtag_add_clocks(int num_cycles, tap_state_t state, tap_state_t clockstate) -{ - /* num_cycles can be 0 */ - setCurrentState(clockstate); - - /* execute num_cycles, 32 at the time. */ - int i; - for (i = 0; i < num_cycles; i += 32) { - int num; - num = 32; - if (num_cycles-i < num) - num = num_cycles-i; - shiftValueInner(clockstate, clockstate, num, 0); - } - -#if !TEST_MANUAL() - /* finish in end_state */ - setCurrentState(state); -#else - tap_state_t t = TAP_IDLE; - /* test manual drive code on any target */ - int tms; - uint8_t tms_scan = tap_get_tms_path(t, state); - int tms_count = tap_get_tms_path_len(tap_get_state(), tap_get_end_state()); - - for (i = 0; i < tms_count; i++) { - tms = (tms_scan >> i) & 1; - waitIdle(); - ZY1000_POKE(ZY1000_JTAG_BASE + 0x28, tms); - } - waitIdle(); - ZY1000_POKE(ZY1000_JTAG_BASE + 0x20, state); -#endif - - return ERROR_OK; -} - -int interface_jtag_add_runtest(int num_cycles, tap_state_t state) -{ - return zy1000_jtag_add_clocks(num_cycles, state, TAP_IDLE); -} - -int interface_jtag_add_clocks(int num_cycles) -{ - return zy1000_jtag_add_clocks(num_cycles, cmd_queue_cur_state, cmd_queue_cur_state); -} - -int interface_add_tms_seq(unsigned num_bits, const uint8_t *seq, enum tap_state state) -{ - /*wait for the fifo to be empty*/ - waitIdle(); - - for (unsigned i = 0; i < num_bits; i++) { - int tms; - - if (((seq[i/8] >> (i % 8)) & 1) == 0) - tms = 0; - else - tms = 1; - - waitIdle(); - ZY1000_POKE(ZY1000_JTAG_BASE + 0x28, tms); - } - - waitIdle(); - if (state != TAP_INVALID) - ZY1000_POKE(ZY1000_JTAG_BASE + 0x20, state); - else { - /* this would be normal if - * we are switching to SWD mode */ - } - return ERROR_OK; -} - -int interface_jtag_add_pathmove(int num_states, const tap_state_t *path) -{ - int state_count; - int tms = 0; - - state_count = 0; - - tap_state_t cur_state = cmd_queue_cur_state; - - uint8_t seq[16]; - memset(seq, 0, sizeof(seq)); - assert(num_states < (int)((sizeof(seq) * 8))); - - while (num_states) { - if (tap_state_transition(cur_state, false) == path[state_count]) - tms = 0; - else if (tap_state_transition(cur_state, true) == path[state_count]) - tms = 1; - else { - LOG_ERROR("BUG: %s -> %s isn't a valid TAP transition", - tap_state_name(cur_state), tap_state_name(path[state_count])); - exit(-1); - } - - seq[state_count/8] = seq[state_count/8] | (tms << (state_count % 8)); - - cur_state = path[state_count]; - state_count++; - num_states--; - } - - return interface_add_tms_seq(state_count, seq, cur_state); -} - -static void jtag_pre_post_bits(struct jtag_tap *tap, int *pre, int *post) -{ - /* bypass bits before and after */ - int pre_bits = 0; - int post_bits = 0; - - bool found = false; - struct jtag_tap *cur_tap, *nextTap; - for (cur_tap = jtag_tap_next_enabled(NULL); cur_tap != NULL; cur_tap = nextTap) { - nextTap = jtag_tap_next_enabled(cur_tap); - if (cur_tap == tap) - found = true; - else { - if (found) - post_bits++; - else - pre_bits++; - } - } - *pre = pre_bits; - *post = post_bits; -} - -void embeddedice_write_dcc(struct jtag_tap *tap, - int reg_addr, - const uint8_t *buffer, - int little, - int count) -{ -#if 0 - int i; - for (i = 0; i < count; i++) { - embeddedice_write_reg_inner(tap, reg_addr, fast_target_buffer_get_u32(buffer, - little)); - buffer += 4; - } -#else - int pre_bits; - int post_bits; - jtag_pre_post_bits(tap, &pre_bits, &post_bits); - - if ((pre_bits > 32) || (post_bits + 6 > 32)) { - int i; - for (i = 0; i < count; i++) { - embeddedice_write_reg_inner(tap, reg_addr, - fast_target_buffer_get_u32(buffer, little)); - buffer += 4; - } - } else { - int i; - for (i = 0; i < count; i++) { - /* Fewer pokes means we get to use the FIFO more efficiently */ - shiftValueInner(TAP_DRSHIFT, TAP_DRSHIFT, pre_bits, 0); - shiftValueInner(TAP_DRSHIFT, TAP_DRSHIFT, 32, - fast_target_buffer_get_u32(buffer, little)); - /* Danger! here we need to exit into the TAP_IDLE state to make - * DCC pick up this value. - */ - shiftValueInner(TAP_DRSHIFT, TAP_IDLE, 6 + post_bits, - (reg_addr | (1 << 5))); - buffer += 4; - } - } -#endif -} - -int arm11_run_instr_data_to_core_noack_inner(struct jtag_tap *tap, - uint32_t opcode, - const uint32_t *data, - size_t count) -{ - /* bypass bits before and after */ - int pre_bits; - int post_bits; - jtag_pre_post_bits(tap, &pre_bits, &post_bits); - post_bits += 2; - - if ((pre_bits > 32) || (post_bits > 32)) { - int arm11_run_instr_data_to_core_noack_inner_default(struct jtag_tap *, - uint32_t, const uint32_t *, size_t); - return arm11_run_instr_data_to_core_noack_inner_default(tap, opcode, data, count); - } else { - static const uint8_t zero; - - /* FIX!!!!!! the target_write_memory() API started this nasty problem - * with unaligned uint32_t * pointers... */ - const uint8_t *t = (const uint8_t *)data; - - while (--count > 0) { -#if 1 - /* Danger! This code doesn't update cmd_queue_cur_state, so - * invoking jtag_add_pathmove() before jtag_add_dr_scan() after - * this loop would fail! - */ - shiftValueInner(TAP_DRSHIFT, TAP_DRSHIFT, pre_bits, 0); - - uint32_t value; - value = *t++; - value |= (*t++<<8); - value |= (*t++<<16); - value |= (*t++<<24); - - shiftValueInner(TAP_DRSHIFT, TAP_DRSHIFT, 32, value); - /* minimum 2 bits */ - shiftValueInner(TAP_DRSHIFT, TAP_DRPAUSE, post_bits, 0); - - /* copy & paste from arm11_dbgtap.c */ - /* TAP_DREXIT2, TAP_DRUPDATE, TAP_IDLE, TAP_IDLE, TAP_IDLE, TAP_DRSELECT, - * TAP_DRCAPTURE, TAP_DRSHIFT */ - /* KLUDGE! we have to flush the fifo or the Nios CPU locks up. - * This is probably a bug in the Avalon bus(cross clocking bridge?) - * or in the jtag registers module. - */ - waitIdle(); - ZY1000_POKE(ZY1000_JTAG_BASE + 0x28, 1); - ZY1000_POKE(ZY1000_JTAG_BASE + 0x28, 1); - ZY1000_POKE(ZY1000_JTAG_BASE + 0x28, 0); - ZY1000_POKE(ZY1000_JTAG_BASE + 0x28, 0); - ZY1000_POKE(ZY1000_JTAG_BASE + 0x28, 0); - ZY1000_POKE(ZY1000_JTAG_BASE + 0x28, 1); - ZY1000_POKE(ZY1000_JTAG_BASE + 0x28, 0); - ZY1000_POKE(ZY1000_JTAG_BASE + 0x28, 0); - /* we don't have to wait for the queue to empty here */ - ZY1000_POKE(ZY1000_JTAG_BASE + 0x20, TAP_DRSHIFT); - waitIdle(); -#else - static const tap_state_t arm11_MOVE_DRPAUSE_IDLE_DRPAUSE_with_delay[] = { - TAP_DREXIT2, TAP_DRUPDATE, TAP_IDLE, TAP_IDLE, TAP_IDLE, - TAP_DRSELECT, TAP_DRCAPTURE, TAP_DRSHIFT - }; - - struct scan_field fields[2] = { - { .num_bits = 32, .out_value = t }, - { .num_bits = 2, .out_value = &zero }, - }; - t += 4; - - jtag_add_dr_scan(tap, - 2, - fields, - TAP_IDLE); - - jtag_add_pathmove(ARRAY_SIZE(arm11_MOVE_DRPAUSE_IDLE_DRPAUSE_with_delay), - arm11_MOVE_DRPAUSE_IDLE_DRPAUSE_with_delay); -#endif - } - - struct scan_field fields[2] = { - { .num_bits = 32, .out_value = t }, - { .num_bits = 2, .out_value = &zero }, - }; - - /* This will happen on the last iteration updating cmd_queue_cur_state - * so we don't have to track it during the common code path - */ - jtag_add_dr_scan(tap, - 2, - fields, - TAP_IDLE); - - return jtag_execute_queue(); - } -} - -static const struct command_registration zy1000_commands[] = { - { - .name = "power", - .handler = handle_power_command, - .mode = COMMAND_ANY, - .help = "Turn power switch to target on/off. " - "With no arguments, prints status.", - .usage = "('on'|'off)", - }, -#if !BUILD_ZY1000_MASTER - { - .name = "zy1000_server", - .mode = COMMAND_ANY, - .jim_handler = jim_zy1000_server, - .help = "Tcpip address for ZY1000 server.", - .usage = "address", - }, -#endif - { - .name = "powerstatus", - .mode = COMMAND_ANY, - .jim_handler = zylinjtag_Jim_Command_powerstatus, - .help = "Returns power status of target", - }, - COMMAND_REGISTRATION_DONE -}; - -#if !BUILD_ZY1000_MASTER - -static int tcp_ip = -1; - -/* Write large packets if we can */ -static size_t out_pos; -static uint8_t out_buffer[16384]; -static size_t in_pos; -static size_t in_write; -static uint8_t in_buffer[16384]; - -static bool flush_writes(void) -{ - bool ok = (write(tcp_ip, out_buffer, out_pos) == (int)out_pos); - out_pos = 0; - return ok; -} - -static bool writeLong(uint32_t l) -{ - int i; - for (i = 0; i < 4; i++) { - uint8_t c = (l >> (i*8))&0xff; - out_buffer[out_pos++] = c; - if (out_pos >= sizeof(out_buffer)) { - if (!flush_writes()) - return false; - } - } - return true; -} - -static bool readLong(uint32_t *out_data) -{ - uint32_t data = 0; - int i; - for (i = 0; i < 4; i++) { - uint8_t c; - if (in_pos == in_write) { - /* If we have some data that we can send, send them before - * we wait for more data - */ - if (out_pos > 0) { - if (!flush_writes()) - return false; - } - - /* read more */ - int t; - t = read(tcp_ip, in_buffer, sizeof(in_buffer)); - if (t < 1) - return false; - in_write = (size_t) t; - in_pos = 0; - } - c = in_buffer[in_pos++]; - - data |= (c << (i*8)); - } - *out_data = data; - return true; -} - -enum ZY1000_CMD { - ZY1000_CMD_POKE = 0x0, - ZY1000_CMD_PEEK = 0x8, - ZY1000_CMD_SLEEP = 0x1, - ZY1000_CMD_WAITIDLE = 2 -}; - -#include /* for socket(), connect(), send(), and recv() */ -#include /* for sockaddr_in and inet_addr() */ - -/* We initialize this late since we need to know the server address - * first. - */ -static void tcpip_open(void) -{ - if (tcp_ip >= 0) - return; - - struct sockaddr_in echoServAddr;/* Echo server address */ - - /* Create a reliable, stream socket using TCP */ - tcp_ip = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); - if (tcp_ip < 0) { - fprintf(stderr, "Failed to connect to zy1000 server\n"); - exit(-1); - } - - /* Construct the server address structure */ - memset(&echoServAddr, 0, sizeof(echoServAddr)); /* Zero out structure */ - echoServAddr.sin_family = AF_INET; /* Internet address family */ - echoServAddr.sin_addr.s_addr = inet_addr(tcp_server); /* Server IP address */ - echoServAddr.sin_port = htons(7777); /* Server port */ - - /* Establish the connection to the echo server */ - if (connect(tcp_ip, (struct sockaddr *) &echoServAddr, sizeof(echoServAddr)) < 0) { - fprintf(stderr, "Failed to connect to zy1000 server\n"); - exit(-1); - } - - int flag = 1; - setsockopt(tcp_ip, /* socket affected */ - IPPROTO_TCP, /* set option at TCP level */ - TCP_NODELAY, /* name of option */ - (char *)&flag, /* the cast is historical cruft */ - sizeof(int)); /* length of option value */ - -} - -/* send a poke */ -void zy1000_tcpout(uint32_t address, uint32_t data) -{ - tcpip_open(); - if (!writeLong((ZY1000_CMD_POKE << 24) | address) || !writeLong(data)) { - fprintf(stderr, "Could not write to zy1000 server\n"); - exit(-1); - } -} - -/* By sending the wait to the server, we avoid a readback - * of status. Radically improves performance for this operation - * with long ping times. - */ -void waitIdle(void) -{ - tcpip_open(); - if (!writeLong((ZY1000_CMD_WAITIDLE << 24))) { - fprintf(stderr, "Could not write to zy1000 server\n"); - exit(-1); - } -} - -uint32_t zy1000_tcpin(uint32_t address) -{ - tcpip_open(); - - zy1000_flush_readqueue(); - - uint32_t data; - if (!writeLong((ZY1000_CMD_PEEK << 24) | address) || !readLong(&data)) { - fprintf(stderr, "Could not read from zy1000 server\n"); - exit(-1); - } - return data; -} - -int interface_jtag_add_sleep(uint32_t us) -{ - tcpip_open(); - if (!writeLong((ZY1000_CMD_SLEEP << 24)) || !writeLong(us)) { - fprintf(stderr, "Could not read from zy1000 server\n"); - exit(-1); - } - return ERROR_OK; -} - -/* queue a readback */ -#define readqueue_size 16384 -static struct { - uint8_t *dest; - int bits; -} readqueue[readqueue_size]; - -static int readqueue_pos; - -/* flush the readqueue, this means reading any data that - * we're expecting and store them into the final position - */ -void zy1000_flush_readqueue(void) -{ - if (readqueue_pos == 0) { - /* simply debugging by allowing easy breakpoints when there - * is something to do. */ - return; - } - int i; - tcpip_open(); - for (i = 0; i < readqueue_pos; i++) { - uint32_t value; - if (!readLong(&value)) { - fprintf(stderr, "Could not read from zy1000 server\n"); - exit(-1); - } - - uint8_t *in_value = readqueue[i].dest; - int k = readqueue[i].bits; - - /* we're shifting in data to MSB, shift data to be aligned for returning the value */ - value >>= 32-k; - - for (int l = 0; l < k; l += 8) - in_value[l/8] = (value >> l)&0xff; - } - readqueue_pos = 0; -} - -/* By queuing the callback's we avoid flushing the - * read queue until jtag_execute_queue(). This can - * reduce latency dramatically for cases where - * callbacks are used extensively. -*/ -#define callbackqueue_size 128 -static struct callbackentry { - jtag_callback_t callback; - jtag_callback_data_t data0; - jtag_callback_data_t data1; - jtag_callback_data_t data2; - jtag_callback_data_t data3; -} callbackqueue[callbackqueue_size]; - -static int callbackqueue_pos; - -void zy1000_jtag_add_callback4(jtag_callback_t callback, - jtag_callback_data_t data0, - jtag_callback_data_t data1, - jtag_callback_data_t data2, - jtag_callback_data_t data3) -{ - if (callbackqueue_pos >= callbackqueue_size) - zy1000_flush_callbackqueue(); - - callbackqueue[callbackqueue_pos].callback = callback; - callbackqueue[callbackqueue_pos].data0 = data0; - callbackqueue[callbackqueue_pos].data1 = data1; - callbackqueue[callbackqueue_pos].data2 = data2; - callbackqueue[callbackqueue_pos].data3 = data3; - callbackqueue_pos++; - - /* KLUDGE! - * make callbacks synchronous for now as minidriver requires callback - * to be synchronous. - * - * We can get away with making read and writes asynchronous so we - * don't completely kill performance. - */ - zy1000_flush_callbackqueue(); -} - -static int zy1000_jtag_convert_to_callback4(jtag_callback_data_t data0, - jtag_callback_data_t data1, - jtag_callback_data_t data2, - jtag_callback_data_t data3) -{ - ((jtag_callback1_t)data1)(data0); - return ERROR_OK; -} - -void zy1000_jtag_add_callback(jtag_callback1_t callback, jtag_callback_data_t data0) -{ - zy1000_jtag_add_callback4(zy1000_jtag_convert_to_callback4, - data0, - (jtag_callback_data_t)callback, - 0, - 0); -} - -void zy1000_flush_callbackqueue(void) -{ - /* we have to flush the read queue so we have access to - the data the callbacks will use - */ - zy1000_flush_readqueue(); - int i; - for (i = 0; i < callbackqueue_pos; i++) { - struct callbackentry *entry = &callbackqueue[i]; - jtag_set_error(entry->callback(entry->data0, entry->data1, entry->data2, - entry->data3)); - } - callbackqueue_pos = 0; -} - -static void writeShiftValue(uint8_t *data, int bits) -{ - waitIdle(); - - if (!writeLong((ZY1000_CMD_PEEK << 24) | (ZY1000_JTAG_BASE + 0xc))) { - fprintf(stderr, "Could not read from zy1000 server\n"); - exit(-1); - } - - if (readqueue_pos >= readqueue_size) - zy1000_flush_readqueue(); - - readqueue[readqueue_pos].dest = data; - readqueue[readqueue_pos].bits = bits; - readqueue_pos++; - - /* KLUDGE!!! minidriver requires readqueue to be synchronous */ - zy1000_flush_readqueue(); -} - -#else - -static void writeShiftValue(uint8_t *data, int bits) -{ - uint32_t value; - waitIdle(); - ZY1000_PEEK(ZY1000_JTAG_BASE + 0xc, value); - VERBOSE(LOG_INFO("getShiftValue %08x", value)); - - /* data in, LSB to MSB */ - /* we're shifting in data to MSB, shift data to be aligned for returning the value */ - value >>= 32 - bits; - - for (int l = 0; l < bits; l += 8) - data[l/8] = (value >> l)&0xff; -} - -#endif - -#if BUILD_ZY1000_MASTER - -#ifdef WATCHDOG_BASE -/* If we connect to port 8888 we must send a char every 10s or the board resets itself */ -static void watchdog_server(cyg_addrword_t data) -{ - int so_reuseaddr_option = 1; - - int fd = socket(AF_INET, SOCK_STREAM, 0); - if (fd == -1) { - LOG_ERROR("error creating socket: %s", strerror(errno)); - exit(-1); - } - - setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void *) &so_reuseaddr_option, - sizeof(int)); - - struct sockaddr_in sin; - unsigned int address_size; - address_size = sizeof(sin); - memset(&sin, 0, sizeof(sin)); - sin.sin_family = AF_INET; - sin.sin_addr.s_addr = INADDR_ANY; - sin.sin_port = htons(8888); - - if (bind(fd, (struct sockaddr *) &sin, sizeof(sin)) == -1) { - LOG_ERROR("couldn't bind to socket: %s", strerror(errno)); - exit(-1); - } - - if (listen(fd, 1) == -1) { - LOG_ERROR("couldn't listen on socket: %s", strerror(errno)); - exit(-1); - } - - - for (;; ) { - int watchdog_ip = accept(fd, (struct sockaddr *) &sin, &address_size); - - /* Start watchdog, must be reset every 10 seconds. */ - HAL_WRITE_UINT32(WATCHDOG_BASE + 4, 4); - - if (watchdog_ip < 0) { - LOG_ERROR("couldn't open watchdog socket: %s", strerror(errno)); - exit(-1); - } - - int flag = 1; - setsockopt(watchdog_ip, /* socket affected */ - IPPROTO_TCP, /* set option at TCP level */ - TCP_NODELAY, /* name of option */ - (char *)&flag, /* the cast is historical cruft */ - sizeof(int)); /* length of option value */ - - - char buf; - for (;; ) { - if (read(watchdog_ip, &buf, 1) == 1) { - /* Reset timer */ - HAL_WRITE_UINT32(WATCHDOG_BASE + 8, 0x1234); - /* Echo so we can telnet in and see that resetting works */ - write(watchdog_ip, &buf, 1); - } else { - /* Stop tickling the watchdog, the CPU will reset in < 10 seconds - * now. - */ - return; - } - - } - - /* Never reached */ - } -} -#endif - -#endif - -#if BUILD_ZY1000_MASTER -int interface_jtag_add_sleep(uint32_t us) -{ - jtag_sleep(us); - return ERROR_OK; -} -#endif - -#if BUILD_ZY1000_MASTER -volatile void *zy1000_jtag_master; -#include -#endif - -int zy1000_init(void) -{ -#if BUILD_ZY1000_MASTER - int fd = open("/dev/mem", O_RDWR | O_SYNC); - if (fd == -1) { - LOG_ERROR("No access to /dev/mem"); - return ERROR_FAIL; - } -#ifndef REGISTERS_BASE -#define REGISTERS_BASE 0x9002000 -#define REGISTERS_SPAN 128 -#endif - - zy1000_jtag_master = mmap(0, - REGISTERS_SPAN, - PROT_READ | PROT_WRITE, - MAP_SHARED, - fd, - REGISTERS_BASE); - - if (zy1000_jtag_master == (void *) -1) { - close(fd); - LOG_ERROR("No access to /dev/mem"); - return ERROR_FAIL; - } -#endif - - ZY1000_POKE(ZY1000_JTAG_BASE + 0x10, 0x30); /* Turn on LED1 & LED2 */ - - setPower(true); /* on by default */ - - /* deassert resets. Important to avoid infinite loop waiting for SRST to deassert */ - zy1000_reset(0, 0); - - return ERROR_OK; -} - -struct jtag_interface zy1000_interface = { - .name = "ZY1000", - .supported = DEBUG_CAP_TMS_SEQ, - .execute_queue = NULL, - .speed = zy1000_speed, - .commands = zy1000_commands, - .init = zy1000_init, - .quit = zy1000_quit, - .khz = zy1000_khz, - .speed_div = zy1000_speed_div, - .power_dropout = zy1000_power_dropout, - .srst_asserted = zy1000_srst_asserted, -}; diff --git a/src/main.c b/src/main.c deleted file mode 100644 index 83e60d8e0..000000000 --- a/src/main.c +++ /dev/null @@ -1,40 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif -#include "openocd.h" - -/* This is the main entry for developer PC hosted OpenOCD. - * - * OpenOCD can also be used as a library that is linked with - * another application(not mainstream yet, but possible), e.g. - * w/as an embedded application. - * - * Those applications will have their own main() implementation - * and use bits and pieces from openocd.c. */ - -int main(int argc, char *argv[]) -{ - /* disable buffering otherwise piping to logs causes problems work */ - setvbuf(stdout, NULL, _IONBF, 0); - setvbuf(stderr, NULL, _IONBF, 0); - - return openocd_main(argc, argv); -} diff --git a/src/openocd.c b/src/openocd.c deleted file mode 100644 index b5bb44b33..000000000 --- a/src/openocd.c +++ /dev/null @@ -1,351 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * Copyright (C) 2007-2010 Øyvind Harboe * - * oyvind.harboe@zylin.com * - * * - * Copyright (C) 2008 Richard Missenden * - * richard.missenden@googlemail.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "openocd.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#ifdef HAVE_STRINGS_H -#include -#endif - -#define OPENOCD_VERSION \ - "Open On-Chip Debugger " VERSION RELSTR " (" PKGBLDDATE ")" - -static const char openocd_startup_tcl[] = { -#include "startup_tcl.inc" -0 /* Terminate with zero */ -}; - -/* Give scripts and TELNET a way to find out what version this is */ -static int jim_version_command(Jim_Interp *interp, int argc, - Jim_Obj * const *argv) -{ - if (argc > 2) - return JIM_ERR; - const char *str = ""; - char *version_str; - version_str = OPENOCD_VERSION; - - if (argc == 2) - str = Jim_GetString(argv[1], NULL); - - if (strcmp("git", str) == 0) - version_str = GITVERSION; - - Jim_SetResult(interp, Jim_NewStringObj(interp, version_str, -1)); - - return JIM_OK; -} - -static int log_target_callback_event_handler(struct target *target, - enum target_event event, - void *priv) -{ - switch (event) { - case TARGET_EVENT_GDB_START: - target->display = 0; - break; - case TARGET_EVENT_GDB_END: - target->display = 1; - break; - case TARGET_EVENT_HALTED: - if (target->display) { - /* do not display information when debugger caused the halt */ - target_arch_state(target); - } - break; - default: - break; - } - - return ERROR_OK; -} - -static bool init_at_startup = true; - -COMMAND_HANDLER(handle_noinit_command) -{ - if (CMD_ARGC != 0) - return ERROR_COMMAND_SYNTAX_ERROR; - init_at_startup = false; - return ERROR_OK; -} - -/* OpenOCD can't really handle failure of this command. Patches welcome! :-) */ -COMMAND_HANDLER(handle_init_command) -{ - - if (CMD_ARGC != 0) - return ERROR_COMMAND_SYNTAX_ERROR; - - int retval; - static int initialized; - if (initialized) - return ERROR_OK; - - initialized = 1; - - retval = command_run_line(CMD_CTX, "target init"); - if (ERROR_OK != retval) - return ERROR_FAIL; - - retval = adapter_init(CMD_CTX); - if (retval != ERROR_OK) { - /* we must be able to set up the debug adapter */ - return retval; - } - - LOG_DEBUG("Debug Adapter init complete"); - - /* "transport init" verifies the expected devices are present; - * for JTAG, it checks the list of configured TAPs against - * what's discoverable, possibly with help from the platform's - * JTAG event handlers. (which require COMMAND_EXEC) - */ - command_context_mode(CMD_CTX, COMMAND_EXEC); - - retval = command_run_line(CMD_CTX, "transport init"); - if (ERROR_OK != retval) - return ERROR_FAIL; - - LOG_DEBUG("Examining targets..."); - if (target_examine() != ERROR_OK) - LOG_DEBUG("target examination failed"); - - command_context_mode(CMD_CTX, COMMAND_CONFIG); - - if (command_run_line(CMD_CTX, "flash init") != ERROR_OK) - return ERROR_FAIL; - - if (command_run_line(CMD_CTX, "mflash init") != ERROR_OK) - return ERROR_FAIL; - - if (command_run_line(CMD_CTX, "nand init") != ERROR_OK) - return ERROR_FAIL; - - if (command_run_line(CMD_CTX, "pld init") != ERROR_OK) - return ERROR_FAIL; - command_context_mode(CMD_CTX, COMMAND_EXEC); - - /* initialize telnet subsystem */ - gdb_target_add_all(all_targets); - - target_register_event_callback(log_target_callback_event_handler, CMD_CTX); - - return ERROR_OK; -} - -COMMAND_HANDLER(handle_add_script_search_dir_command) -{ - if (CMD_ARGC != 1) - return ERROR_COMMAND_SYNTAX_ERROR; - - add_script_search_dir(CMD_ARGV[0]); - - return ERROR_OK; -} - -static const struct command_registration openocd_command_handlers[] = { - { - .name = "version", - .jim_handler = jim_version_command, - .mode = COMMAND_ANY, - .help = "show program version", - }, - { - .name = "noinit", - .handler = &handle_noinit_command, - .mode = COMMAND_CONFIG, - .help = "Prevent 'init' from being called at startup.", - .usage = "" - }, - { - .name = "init", - .handler = &handle_init_command, - .mode = COMMAND_ANY, - .help = "Initializes configured targets and servers. " - "Changes command mode from CONFIG to EXEC. " - "Unless 'noinit' is called, this command is " - "called automatically at the end of startup.", - .usage = "" - }, - { - .name = "add_script_search_dir", - .handler = &handle_add_script_search_dir_command, - .mode = COMMAND_ANY, - .help = "dir to search for config files and scripts", - .usage = "" - }, - COMMAND_REGISTRATION_DONE -}; - -static int openocd_register_commands(struct command_context *cmd_ctx) -{ - return register_commands(cmd_ctx, NULL, openocd_command_handlers); -} - -struct command_context *global_cmd_ctx; - -/* NB! this fn can be invoked outside this file for non PC hosted builds - * NB! do not change to 'static'!!!! - */ -struct command_context *setup_command_handler(Jim_Interp *interp) -{ - log_init(); - LOG_DEBUG("log_init: complete"); - - struct command_context *cmd_ctx = command_init(openocd_startup_tcl, interp); - - /* register subsystem commands */ - typedef int (*command_registrant_t)(struct command_context *cmd_ctx_value); - static const command_registrant_t command_registrants[] = { - &openocd_register_commands, - &server_register_commands, - &gdb_register_commands, - &log_register_commands, - &transport_register_commands, - &interface_register_commands, - &target_register_commands, - &flash_register_commands, - &nand_register_commands, - &pld_register_commands, - &mflash_register_commands, - NULL - }; - for (unsigned i = 0; NULL != command_registrants[i]; i++) { - int retval = (*command_registrants[i])(cmd_ctx); - if (ERROR_OK != retval) { - command_done(cmd_ctx); - return NULL; - } - } - LOG_DEBUG("command registration: complete"); - - LOG_OUTPUT(OPENOCD_VERSION "\n" - "Licensed under GNU GPL v2\n"); - - global_cmd_ctx = cmd_ctx; - - return cmd_ctx; -} - -/** OpenOCD runtime meat that can become single-thread in future. It parse - * commandline, reads configuration, sets up the target and starts server loop. - * Commandline arguments are passed into this function from openocd_main(). - */ -static int openocd_thread(int argc, char *argv[], struct command_context *cmd_ctx) -{ - int ret; - - if (parse_cmdline_args(cmd_ctx, argc, argv) != ERROR_OK) - return ERROR_FAIL; - - if (server_preinit() != ERROR_OK) - return ERROR_FAIL; - - ret = parse_config_file(cmd_ctx); - if (ret == ERROR_COMMAND_CLOSE_CONNECTION) - return ERROR_OK; - else if (ret != ERROR_OK) - return ERROR_FAIL; - - ret = server_init(cmd_ctx); - if (ERROR_OK != ret) - return ERROR_FAIL; - - if (init_at_startup) { - ret = command_run_line(cmd_ctx, "init"); - if (ERROR_OK != ret) - return ERROR_FAIL; - } - - ret = server_loop(cmd_ctx); - - int last_signal = server_quit(); - if (last_signal != ERROR_OK) - return last_signal; - - if (ret != ERROR_OK) - return ERROR_FAIL; - return ERROR_OK; -} - -/* normally this is the main() function entry, but if OpenOCD is linked - * into application, then this fn will not be invoked, but rather that - * application will have it's own implementation of main(). */ -int openocd_main(int argc, char *argv[]) -{ - int ret; - - /* initialize commandline interface */ - struct command_context *cmd_ctx; - - cmd_ctx = setup_command_handler(NULL); - - if (util_init(cmd_ctx) != ERROR_OK) - return EXIT_FAILURE; - - if (ioutil_init(cmd_ctx) != ERROR_OK) - return EXIT_FAILURE; - - LOG_OUTPUT("For bug reports, read\n\t" - "http://openocd.org/doc/doxygen/bugs.html" - "\n"); - - command_context_mode(cmd_ctx, COMMAND_CONFIG); - command_set_output_handler(cmd_ctx, configuration_output_handler, NULL); - - /* Start the executable meat that can evolve into thread in future. */ - ret = openocd_thread(argc, argv, cmd_ctx); - - unregister_all_commands(cmd_ctx, NULL); - - /* free commandline interface */ - command_done(cmd_ctx); - - adapter_quit(); - - if (ERROR_FAIL == ret) - return EXIT_FAILURE; - else if (ERROR_OK != ret) - exit_on_signal(ret); - - return ret; -} diff --git a/src/openocd.h b/src/openocd.h deleted file mode 100644 index 543ac3c23..000000000 --- a/src/openocd.h +++ /dev/null @@ -1,32 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005 by Dominic Rath * - * Copyright (C) 2009 by Zachary T Welch * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 OPENOCD_OPENOCD_H -#define OPENOCD_OPENOCD_H - -/** - * Different applications can define this entry point to override - * the default openocd main function. On most systems, this will be - * defined in src/openocd.c. - * @param argc normally passed from main() - * @param argv normally passed from main() - * @returns return code for main() - */ -int openocd_main(int argc, char *argv[]); - -#endif /* OPENOCD_OPENOCD_H */ diff --git a/src/pld/Makefile.am b/src/pld/Makefile.am deleted file mode 100644 index 93b79f4a1..000000000 --- a/src/pld/Makefile.am +++ /dev/null @@ -1,8 +0,0 @@ -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 diff --git a/src/pld/pld.c b/src/pld/pld.c deleted file mode 100644 index 5210b97b7..000000000 --- a/src/pld/pld.c +++ /dev/null @@ -1,239 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2006 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "pld.h" -#include -#include - - -/* pld drivers - */ -extern struct pld_driver virtex2_pld; - -static struct pld_driver *pld_drivers[] = { - &virtex2_pld, - NULL, -}; - -static struct pld_device *pld_devices; - -struct pld_device *get_pld_device_by_num(int num) -{ - struct pld_device *p; - int i = 0; - - for (p = pld_devices; p; p = p->next) { - if (i++ == num) - return p; - } - - return NULL; -} - -/* pld device [driver_options ...] - */ -COMMAND_HANDLER(handle_pld_device_command) -{ - int i; - int found = 0; - - if (CMD_ARGC < 1) - return ERROR_COMMAND_SYNTAX_ERROR; - - for (i = 0; pld_drivers[i]; i++) { - if (strcmp(CMD_ARGV[0], pld_drivers[i]->name) == 0) { - struct pld_device *p, *c; - - /* register pld specific commands */ - int retval; - if (pld_drivers[i]->commands) { - retval = register_commands(CMD_CTX, NULL, - pld_drivers[i]->commands); - if (ERROR_OK != retval) { - LOG_ERROR("couldn't register '%s' commands", CMD_ARGV[0]); - return ERROR_FAIL; - } - } - - c = malloc(sizeof(struct pld_device)); - c->driver = pld_drivers[i]; - c->next = NULL; - - retval = CALL_COMMAND_HANDLER( - pld_drivers[i]->pld_device_command, c); - if (ERROR_OK != retval) { - LOG_ERROR("'%s' driver rejected pld device", - CMD_ARGV[0]); - free(c); - return ERROR_OK; - } - - /* put pld device in linked list */ - if (pld_devices) { - /* find last pld device */ - for (p = pld_devices; p && p->next; p = p->next) - ; - if (p) - p->next = c; - } else - pld_devices = c; - - found = 1; - } - } - - /* no matching pld driver found */ - if (!found) { - LOG_ERROR("pld driver '%s' not found", CMD_ARGV[0]); - exit(-1); - } - - return ERROR_OK; -} - -COMMAND_HANDLER(handle_pld_devices_command) -{ - struct pld_device *p; - int i = 0; - - if (!pld_devices) { - command_print(CMD_CTX, "no pld devices configured"); - return ERROR_OK; - } - - for (p = pld_devices; p; p = p->next) - command_print(CMD_CTX, "#%i: %s", i++, p->driver->name); - - return ERROR_OK; -} - -COMMAND_HANDLER(handle_pld_load_command) -{ - int retval; - struct timeval start, end, duration; - struct pld_device *p; - - gettimeofday(&start, NULL); - - if (CMD_ARGC < 2) - return ERROR_COMMAND_SYNTAX_ERROR; - - unsigned dev_id; - COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], dev_id); - p = get_pld_device_by_num(dev_id); - if (!p) { - command_print(CMD_CTX, "pld device '#%s' is out of bounds", CMD_ARGV[0]); - return ERROR_OK; - } - - retval = p->driver->load(p, CMD_ARGV[1]); - if (retval != ERROR_OK) { - command_print(CMD_CTX, "failed loading file %s to pld device %u", - CMD_ARGV[1], dev_id); - switch (retval) { - } - return retval; - } else { - gettimeofday(&end, NULL); - timeval_subtract(&duration, &end, &start); - - command_print(CMD_CTX, "loaded file %s to pld device %u in %jis %jius", - CMD_ARGV[1], dev_id, - (intmax_t)duration.tv_sec, (intmax_t)duration.tv_usec); - } - - return ERROR_OK; -} - -static const struct command_registration pld_exec_command_handlers[] = { - { - .name = "devices", - .handler = handle_pld_devices_command, - .mode = COMMAND_EXEC, - .help = "list configured pld devices", - }, - { - .name = "load", - .handler = handle_pld_load_command, - .mode = COMMAND_EXEC, - .help = "load configuration file into PLD", - .usage = "pld_num filename", - }, - COMMAND_REGISTRATION_DONE -}; - -static int pld_init(struct command_context *cmd_ctx) -{ - if (!pld_devices) - return ERROR_OK; - - struct command *parent = command_find_in_context(cmd_ctx, "pld"); - return register_commands(cmd_ctx, parent, pld_exec_command_handlers); -} - -COMMAND_HANDLER(handle_pld_init_command) -{ - if (CMD_ARGC != 0) - return ERROR_COMMAND_SYNTAX_ERROR; - - static bool pld_initialized; - if (pld_initialized) { - LOG_INFO("'pld init' has already been called"); - return ERROR_OK; - } - pld_initialized = true; - - LOG_DEBUG("Initializing PLDs..."); - return pld_init(CMD_CTX); -} - -static const struct command_registration pld_config_command_handlers[] = { - { - .name = "device", - .mode = COMMAND_CONFIG, - .handler = handle_pld_device_command, - .help = "configure a PLD device", - .usage = "driver_name [driver_args ... ]", - }, - { - .name = "init", - .mode = COMMAND_CONFIG, - .handler = handle_pld_init_command, - .help = "initialize PLD devices", - .usage = "" - }, - COMMAND_REGISTRATION_DONE -}; -static const struct command_registration pld_command_handler[] = { - { - .name = "pld", - .mode = COMMAND_ANY, - .help = "programmable logic device commands", - .usage = "", - .chain = pld_config_command_handlers, - }, - COMMAND_REGISTRATION_DONE -}; -int pld_register_commands(struct command_context *cmd_ctx) -{ - return register_commands(cmd_ctx, NULL, pld_command_handler); -} diff --git a/src/pld/pld.h b/src/pld/pld.h deleted file mode 100644 index 3178fd459..000000000 --- a/src/pld/pld.h +++ /dev/null @@ -1,52 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2006 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifndef OPENOCD_PLD_PLD_H -#define OPENOCD_PLD_PLD_H - -#include - -struct pld_device; - -#define __PLD_DEVICE_COMMAND(name) \ - COMMAND_HELPER(name, struct pld_device *pld) - -struct pld_driver { - const char *name; - __PLD_DEVICE_COMMAND((*pld_device_command)); - const struct command_registration *commands; - int (*load)(struct pld_device *pld_device, const char *filename); -}; - -#define PLD_DEVICE_COMMAND_HANDLER(name) \ - static __PLD_DEVICE_COMMAND(name) - -struct pld_device { - struct pld_driver *driver; - void *driver_priv; - struct pld_device *next; -}; - -int pld_register_commands(struct command_context *cmd_ctx); - -struct pld_device *get_pld_device_by_num(int num); - -#define ERROR_PLD_DEVICE_INVALID (-1000) -#define ERROR_PLD_FILE_LOAD_FAILED (-1001) - -#endif /* OPENOCD_PLD_PLD_H */ diff --git a/src/pld/virtex2.c b/src/pld/virtex2.c deleted file mode 100644 index 4e385e97b..000000000 --- a/src/pld/virtex2.c +++ /dev/null @@ -1,250 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2006 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "virtex2.h" -#include "xilinx_bit.h" -#include "pld.h" - -static int virtex2_set_instr(struct jtag_tap *tap, uint32_t new_instr) -{ - if (tap == NULL) - return ERROR_FAIL; - - if (buf_get_u32(tap->cur_instr, 0, tap->ir_length) != new_instr) { - struct scan_field field; - - field.num_bits = tap->ir_length; - void *t = calloc(DIV_ROUND_UP(field.num_bits, 8), 1); - 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); - - free(t); - } - - return ERROR_OK; -} - -static int virtex2_send_32(struct pld_device *pld_device, - int num_words, uint32_t *words) -{ - struct virtex2_pld_device *virtex2_info = pld_device->driver_priv; - struct scan_field scan_field; - uint8_t *values; - int i; - - values = malloc(num_words * 4); - - scan_field.num_bits = num_words * 32; - scan_field.out_value = values; - scan_field.in_value = NULL; - - for (i = 0; i < num_words; i++) - buf_set_u32(values + 4 * i, 0, 32, flip_u32(*words++, 32)); - - virtex2_set_instr(virtex2_info->tap, 0x5); /* CFG_IN */ - - jtag_add_dr_scan(virtex2_info->tap, 1, &scan_field, TAP_DRPAUSE); - - free(values); - - return ERROR_OK; -} - -static inline void virtexflip32(jtag_callback_data_t arg) -{ - uint8_t *in = (uint8_t *)arg; - *((uint32_t *)arg) = flip_u32(le_to_h_u32(in), 32); -} - -static int virtex2_receive_32(struct pld_device *pld_device, - int num_words, uint32_t *words) -{ - struct virtex2_pld_device *virtex2_info = pld_device->driver_priv; - struct scan_field scan_field; - - scan_field.num_bits = 32; - scan_field.out_value = NULL; - scan_field.in_value = NULL; - - virtex2_set_instr(virtex2_info->tap, 0x4); /* CFG_OUT */ - - while (num_words--) { - scan_field.in_value = (uint8_t *)words; - - jtag_add_dr_scan(virtex2_info->tap, 1, &scan_field, TAP_DRPAUSE); - - jtag_add_callback(virtexflip32, (jtag_callback_data_t)words); - - words++; - } - - return ERROR_OK; -} - -static int virtex2_read_stat(struct pld_device *pld_device, uint32_t *status) -{ - uint32_t data[5]; - - jtag_add_tlr(); - - data[0] = 0xaa995566; /* synch word */ - data[1] = 0x2800E001; /* Type 1, read, address 7, 1 word */ - data[2] = 0x20000000; /* NOOP (Type 1, read, address 0, 0 words */ - data[3] = 0x20000000; /* NOOP */ - data[4] = 0x20000000; /* NOOP */ - virtex2_send_32(pld_device, 5, data); - - virtex2_receive_32(pld_device, 1, status); - - jtag_execute_queue(); - - LOG_DEBUG("status: 0x%8.8" PRIx32 "", *status); - - return ERROR_OK; -} - -static int virtex2_load(struct pld_device *pld_device, const char *filename) -{ - struct virtex2_pld_device *virtex2_info = pld_device->driver_priv; - struct xilinx_bit_file bit_file; - int retval; - unsigned int i; - struct scan_field field; - - field.in_value = NULL; - - retval = xilinx_read_bit_file(&bit_file, filename); - if (retval != ERROR_OK) - return retval; - - virtex2_set_instr(virtex2_info->tap, 0xb); /* JPROG_B */ - jtag_execute_queue(); - jtag_add_sleep(1000); - - virtex2_set_instr(virtex2_info->tap, 0x5); /* CFG_IN */ - jtag_execute_queue(); - - for (i = 0; i < bit_file.length; i++) - bit_file.data[i] = flip_u32(bit_file.data[i], 8); - - field.num_bits = bit_file.length * 8; - field.out_value = bit_file.data; - - jtag_add_dr_scan(virtex2_info->tap, 1, &field, TAP_DRPAUSE); - jtag_execute_queue(); - - jtag_add_tlr(); - - if (!(virtex2_info->no_jstart)) - virtex2_set_instr(virtex2_info->tap, 0xc); /* JSTART */ - jtag_add_runtest(13, TAP_IDLE); - virtex2_set_instr(virtex2_info->tap, 0x3f); /* BYPASS */ - virtex2_set_instr(virtex2_info->tap, 0x3f); /* BYPASS */ - if (!(virtex2_info->no_jstart)) - virtex2_set_instr(virtex2_info->tap, 0xc); /* JSTART */ - jtag_add_runtest(13, TAP_IDLE); - virtex2_set_instr(virtex2_info->tap, 0x3f); /* BYPASS */ - jtag_execute_queue(); - - return ERROR_OK; -} - -COMMAND_HANDLER(virtex2_handle_read_stat_command) -{ - struct pld_device *device; - uint32_t status; - - if (CMD_ARGC < 1) - return ERROR_COMMAND_SYNTAX_ERROR; - - unsigned dev_id; - COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], dev_id); - device = get_pld_device_by_num(dev_id); - if (!device) { - command_print(CMD_CTX, "pld device '#%s' is out of bounds", CMD_ARGV[0]); - return ERROR_OK; - } - - virtex2_read_stat(device, &status); - - command_print(CMD_CTX, "virtex2 status register: 0x%8.8" PRIx32 "", status); - - return ERROR_OK; -} - -PLD_DEVICE_COMMAND_HANDLER(virtex2_pld_device_command) -{ - struct jtag_tap *tap; - - struct virtex2_pld_device *virtex2_info; - - if (CMD_ARGC < 2) - return ERROR_COMMAND_SYNTAX_ERROR; - - tap = jtag_tap_by_string(CMD_ARGV[1]); - if (tap == NULL) { - command_print(CMD_CTX, "Tap: %s does not exist", CMD_ARGV[1]); - return ERROR_OK; - } - - virtex2_info = malloc(sizeof(struct virtex2_pld_device)); - virtex2_info->tap = tap; - - virtex2_info->no_jstart = 0; - if (CMD_ARGC >= 3) - COMMAND_PARSE_NUMBER(int, CMD_ARGV[2], virtex2_info->no_jstart); - - pld->driver_priv = virtex2_info; - - return ERROR_OK; -} - -static const struct command_registration virtex2_exec_command_handlers[] = { - { - .name = "read_stat", - .mode = COMMAND_EXEC, - .handler = virtex2_handle_read_stat_command, - .help = "read status register", - .usage = "pld_num", - }, - COMMAND_REGISTRATION_DONE -}; -static const struct command_registration virtex2_command_handler[] = { - { - .name = "virtex2", - .mode = COMMAND_ANY, - .help = "Virtex-II specific commands", - .usage = "", - .chain = virtex2_exec_command_handlers, - }, - COMMAND_REGISTRATION_DONE -}; - -struct pld_driver virtex2_pld = { - .name = "virtex2", - .commands = virtex2_command_handler, - .pld_device_command = &virtex2_pld_device_command, - .load = &virtex2_load, -}; diff --git a/src/pld/virtex2.h b/src/pld/virtex2.h deleted file mode 100644 index d6d922e79..000000000 --- a/src/pld/virtex2.h +++ /dev/null @@ -1,29 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2006 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifndef OPENOCD_PLD_VIRTEX2_H -#define OPENOCD_PLD_VIRTEX2_H - -#include - -struct virtex2_pld_device { - struct jtag_tap *tap; - int no_jstart; -}; - -#endif /* OPENOCD_PLD_VIRTEX2_H */ diff --git a/src/pld/xilinx_bit.c b/src/pld/xilinx_bit.c deleted file mode 100644 index a975a7a0c..000000000 --- a/src/pld/xilinx_bit.c +++ /dev/null @@ -1,128 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2006 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "xilinx_bit.h" -#include "pld.h" -#include - -#include - - -static int read_section(FILE *input_file, int length_size, char section, - uint32_t *buffer_length, uint8_t **buffer) -{ - uint8_t length_buffer[4]; - int length; - char section_char; - int read_count; - - if ((length_size != 2) && (length_size != 4)) { - LOG_ERROR("BUG: length_size neither 2 nor 4"); - return ERROR_PLD_FILE_LOAD_FAILED; - } - - read_count = fread(§ion_char, 1, 1, input_file); - if (read_count != 1) - return ERROR_PLD_FILE_LOAD_FAILED; - - if (section_char != section) - return ERROR_PLD_FILE_LOAD_FAILED; - - read_count = fread(length_buffer, 1, length_size, input_file); - if (read_count != length_size) - return ERROR_PLD_FILE_LOAD_FAILED; - - if (length_size == 4) - length = be_to_h_u32(length_buffer); - else /* (length_size == 2) */ - length = be_to_h_u16(length_buffer); - - if (buffer_length) - *buffer_length = length; - - *buffer = malloc(length); - - read_count = fread(*buffer, 1, length, input_file); - if (read_count != length) - return ERROR_PLD_FILE_LOAD_FAILED; - - return ERROR_OK; -} - -int xilinx_read_bit_file(struct xilinx_bit_file *bit_file, const char *filename) -{ - FILE *input_file; - struct stat input_stat; - int read_count; - - if (!filename || !bit_file) - return ERROR_COMMAND_SYNTAX_ERROR; - - if (stat(filename, &input_stat) == -1) { - LOG_ERROR("couldn't stat() %s: %s", filename, strerror(errno)); - return ERROR_PLD_FILE_LOAD_FAILED; - } - - if (S_ISDIR(input_stat.st_mode)) { - LOG_ERROR("%s is a directory", filename); - return ERROR_PLD_FILE_LOAD_FAILED; - } - - if (input_stat.st_size == 0) { - LOG_ERROR("Empty file %s", filename); - return ERROR_PLD_FILE_LOAD_FAILED; - } - - input_file = fopen(filename, "rb"); - if (input_file == NULL) { - LOG_ERROR("couldn't open %s: %s", filename, strerror(errno)); - return ERROR_PLD_FILE_LOAD_FAILED; - } - - read_count = fread(bit_file->unknown_header, 1, 13, input_file); - if (read_count != 13) { - LOG_ERROR("couldn't read unknown_header from file '%s'", filename); - return ERROR_PLD_FILE_LOAD_FAILED; - } - - if (read_section(input_file, 2, 'a', NULL, &bit_file->source_file) != ERROR_OK) - return ERROR_PLD_FILE_LOAD_FAILED; - - if (read_section(input_file, 2, 'b', NULL, &bit_file->part_name) != ERROR_OK) - return ERROR_PLD_FILE_LOAD_FAILED; - - if (read_section(input_file, 2, 'c', NULL, &bit_file->date) != ERROR_OK) - return ERROR_PLD_FILE_LOAD_FAILED; - - if (read_section(input_file, 2, 'd', NULL, &bit_file->time) != ERROR_OK) - return ERROR_PLD_FILE_LOAD_FAILED; - - if (read_section(input_file, 4, 'e', &bit_file->length, &bit_file->data) != ERROR_OK) - return ERROR_PLD_FILE_LOAD_FAILED; - - LOG_DEBUG("bit_file: %s %s %s,%s %" PRIi32 "", bit_file->source_file, bit_file->part_name, - bit_file->date, bit_file->time, bit_file->length); - - fclose(input_file); - - return ERROR_OK; -} diff --git a/src/pld/xilinx_bit.h b/src/pld/xilinx_bit.h deleted file mode 100644 index 1a35c3be2..000000000 --- a/src/pld/xilinx_bit.h +++ /dev/null @@ -1,34 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2006 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifndef OPENOCD_PLD_XILINX_BIT_H -#define OPENOCD_PLD_XILINX_BIT_H - -struct xilinx_bit_file { - uint8_t unknown_header[13]; - uint8_t *source_file; - uint8_t *part_name; - uint8_t *date; - uint8_t *time; - uint32_t length; - uint8_t *data; -}; - -int xilinx_read_bit_file(struct xilinx_bit_file *bit_file, const char *filename); - -#endif /* OPENOCD_PLD_XILINX_BIT_H */ diff --git a/src/rtos/ChibiOS.c b/src/rtos/ChibiOS.c deleted file mode 100644 index 00e9df783..000000000 --- a/src/rtos/ChibiOS.c +++ /dev/null @@ -1,547 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2012 by Matthias Blaicher * - * Matthias Blaicher - matthias@blaicher.com * - * * - * Copyright (C) 2011 by Broadcom Corporation * - * Evan Hunter - ehunter@broadcom.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include "target/target.h" -#include "target/target_type.h" -#include "target/armv7m.h" -#include "target/cortex_m.h" -#include "rtos.h" -#include "helper/log.h" -#include "helper/types.h" -#include "rtos_chibios_stackings.h" - -/** - * @brief ChibiOS/RT memory signature record. - * - * @details Definition copied from os/kernel/include/chregistry.h of ChibiOS/RT. - */ -struct ChibiOS_chdebug { - char ch_identifier[4]; /**< @brief Always set to "main". */ - uint8_t ch_zero; /**< @brief Must be zero. */ - uint8_t ch_size; /**< @brief Size of this structure. */ - uint16_t ch_version; /**< @brief Encoded ChibiOS/RT version. */ - uint8_t ch_ptrsize; /**< @brief Size of a pointer. */ - uint8_t ch_timesize; /**< @brief Size of a @p systime_t. */ - uint8_t ch_threadsize; /**< @brief Size of a @p Thread struct. */ - uint8_t cf_off_prio; /**< @brief Offset of @p p_prio field. */ - uint8_t cf_off_ctx; /**< @brief Offset of @p p_ctx field. */ - uint8_t cf_off_newer; /**< @brief Offset of @p p_newer field. */ - uint8_t cf_off_older; /**< @brief Offset of @p p_older field. */ - uint8_t cf_off_name; /**< @brief Offset of @p p_name field. */ - uint8_t cf_off_stklimit; /**< @brief Offset of @p p_stklimit - field. */ - uint8_t cf_off_state; /**< @brief Offset of @p p_state field. */ - uint8_t cf_off_flags; /**< @brief Offset of @p p_flags field. */ - uint8_t cf_off_refs; /**< @brief Offset of @p p_refs field. */ - uint8_t cf_off_preempt; /**< @brief Offset of @p p_preempt - field. */ - uint8_t cf_off_time; /**< @brief Offset of @p p_time field. */ -}; - -#define GET_CH_KERNEL_MAJOR(codedVersion) ((codedVersion >> 11) & 0x1f) -#define GET_CH_KERNEL_MINOR(codedVersion) ((codedVersion >> 6) & 0x1f) -#define GET_CH_KERNEL_PATCH(codedVersion) ((codedVersion >> 0) & 0x3f) - -/** - * @brief ChibiOS thread states. - */ -static const char * const ChibiOS_thread_states[] = { - "READY", "CURRENT", "SUSPENDED", "WTSEM", "WTMTX", "WTCOND", "SLEEPING", - "WTEXIT", "WTOREVT", "WTANDEVT", "SNDMSGQ", "SNDMSG", "WTMSG", "WTQUEUE", - "FINAL" -}; - -#define CHIBIOS_NUM_STATES (sizeof(ChibiOS_thread_states)/sizeof(char *)) - -/* Maximum ChibiOS thread name. There is no real limit set by ChibiOS but 64 - * chars ought to be enough. - */ -#define CHIBIOS_THREAD_NAME_STR_SIZE (64) - -struct ChibiOS_params { - const char *target_name; - - struct ChibiOS_chdebug *signature; - const struct rtos_register_stacking *stacking_info; -}; - -static struct ChibiOS_params ChibiOS_params_list[] = { - { - "cortex_m", /* target_name */ - 0, - NULL, /* stacking_info */ - }, - { - "hla_target", /* target_name */ - 0, - NULL, /* stacking_info */ - } -}; -#define CHIBIOS_NUM_PARAMS ((int)(sizeof(ChibiOS_params_list)/sizeof(struct ChibiOS_params))) - -static int ChibiOS_detect_rtos(struct target *target); -static int ChibiOS_create(struct target *target); -static int ChibiOS_update_threads(struct rtos *rtos); -static int ChibiOS_get_thread_reg_list(struct rtos *rtos, int64_t thread_id, char **hex_reg_list); -static int ChibiOS_get_symbol_list_to_lookup(symbol_table_elem_t *symbol_list[]); - -struct rtos_type ChibiOS_rtos = { - .name = "ChibiOS", - - .detect_rtos = ChibiOS_detect_rtos, - .create = ChibiOS_create, - .update_threads = ChibiOS_update_threads, - .get_thread_reg_list = ChibiOS_get_thread_reg_list, - .get_symbol_list_to_lookup = ChibiOS_get_symbol_list_to_lookup, -}; - - -/* In ChibiOS/RT 3.0 the rlist structure has become part of a system - * data structure ch. We declare both symbols as optional and later - * use whatever is available. - */ - -enum ChibiOS_symbol_values { - ChibiOS_VAL_rlist = 0, - ChibiOS_VAL_ch = 1, - 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 */ - { NULL, 0, false} -}; - -/* Offset of the rlist structure within the system data structure (ch) */ -#define CH_RLIST_OFFSET 0x00 - -static int ChibiOS_update_memory_signature(struct rtos *rtos) -{ - int retval; - struct ChibiOS_params *param; - struct ChibiOS_chdebug *signature; - - param = (struct ChibiOS_params *) rtos->rtos_specific_params; - - /* Free existing memory description.*/ - if (param->signature) { - free(param->signature); - param->signature = 0; - } - - signature = malloc(sizeof(*signature)); - if (!signature) { - LOG_ERROR("Could not allocate space for ChibiOS/RT memory signature"); - return -1; - } - - retval = target_read_buffer(rtos->target, - rtos->symbols[ChibiOS_VAL_ch_debug].address, - sizeof(*signature), - (uint8_t *) signature); - if (retval != ERROR_OK) { - LOG_ERROR("Could not read ChibiOS/RT memory signature from target"); - goto errfree; - } - - if (strncmp(signature->ch_identifier, "main", 4) != 0) { - LOG_ERROR("Memory signature identifier does not contain magic bytes."); - goto errfree; - } - - if (signature->ch_size < sizeof(*signature)) { - LOG_ERROR("ChibiOS/RT memory signature claims to be smaller " - "than expected"); - goto errfree; - } - - if (signature->ch_size > sizeof(*signature)) { - LOG_WARNING("ChibiOS/RT memory signature claims to be bigger than" - " expected. Assuming compatibility..."); - } - - /* Convert endianness of version field */ - const uint8_t *versionTarget = (const uint8_t *) - &signature->ch_version; - signature->ch_version = rtos->target->endianness == TARGET_LITTLE_ENDIAN ? - le_to_h_u32(versionTarget) : be_to_h_u32(versionTarget); - - const uint16_t ch_version = signature->ch_version; - LOG_INFO("Successfully loaded memory map of ChibiOS/RT target " - "running version %i.%i.%i", GET_CH_KERNEL_MAJOR(ch_version), - GET_CH_KERNEL_MINOR(ch_version), GET_CH_KERNEL_PATCH(ch_version)); - - /* Currently, we have the inherent assumption that all address pointers - * are 32 bit wide. */ - if (signature->ch_ptrsize != sizeof(uint32_t)) { - LOG_ERROR("ChibiOS/RT target memory signature claims an address" - "width unequal to 32 bits!"); - free(signature); - return -1; - } - - param->signature = signature; - return 0; - -errfree: - /* Error reading the ChibiOS memory structure */ - free(signature); - param->signature = 0; - return -1; -} - - -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 - * only stack the FPU registers if it is enabled during ChibiOS build. - * - * Terminating which stacking is used is target depending. - * - * Assumptions: - * - Once ChibiOS is actually initialized, the stacking is fixed. - * - During startup code, the FPU might not be initialized and the - * detection might fail. - * - Since no threads are running during startup, the problem is solved - * by delaying stacking detection until there are more threads - * available than the current execution. In which case - * ChibiOS_get_thread_reg_list is called. - */ - int retval; - - if (!rtos->rtos_specific_params) - return -1; - - struct ChibiOS_params *param; - param = (struct ChibiOS_params *) rtos->rtos_specific_params; - - /* 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) { - /* 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. - * In ChibiOS this is done in ResetHandler() in crt0.c */ - if (cpacr & 0x00F00000) { - LOG_DEBUG("Enabled FPU detected."); - param->stacking_info = &rtos_chibios_arm_v7m_stacking_w_fpu; - return 0; - } - } - - /* Found ARM v7m target with no or disabled FPU */ - param->stacking_info = &rtos_chibios_arm_v7m_stacking; - return 0; - } - - return -1; -} - -static int ChibiOS_update_threads(struct rtos *rtos) -{ - int retval; - const struct ChibiOS_params *param; - int tasks_found = 0; - int rtos_valid = -1; - - if (!rtos->rtos_specific_params) - return -1; - - if (!rtos->symbols) { - LOG_ERROR("No symbols for ChibiOS"); - return -3; - } - - param = (const struct ChibiOS_params *) rtos->rtos_specific_params; - /* Update the memory signature saved in the target memory */ - if (!param->signature) { - retval = ChibiOS_update_memory_signature(rtos); - if (retval != ERROR_OK) { - LOG_ERROR("Reading the memory signature of ChibiOS/RT failed"); - return retval; - } - } - - /* wipe out previous thread details if any */ - rtos_free_threadlist(rtos); - - /* ChibiOS does not save the current thread count. We have to first - * parse the double linked thread list to check for errors and the number of - * threads. */ - const uint32_t rlist = rtos->symbols[ChibiOS_VAL_rlist].address ? - rtos->symbols[ChibiOS_VAL_rlist].address : - rtos->symbols[ChibiOS_VAL_ch].address + CH_RLIST_OFFSET /* ChibiOS3 */; - const struct ChibiOS_chdebug *signature = param->signature; - uint32_t current; - uint32_t previous; - uint32_t older; - - current = rlist; - previous = rlist; - while (1) { - retval = target_read_u32(rtos->target, - current + signature->cf_off_newer, ¤t); - if (retval != ERROR_OK) { - LOG_ERROR("Could not read next ChibiOS thread"); - return retval; - } - /* Could be NULL if the kernel is not initialized yet or if the - * registry is corrupted. */ - if (current == 0) { - LOG_ERROR("ChibiOS registry integrity check failed, NULL pointer"); - - rtos_valid = 0; - break; - } - /* Fetch previous thread in the list as a integrity check. */ - retval = target_read_u32(rtos->target, - current + signature->cf_off_older, &older); - if ((retval != ERROR_OK) || (older == 0) || (older != previous)) { - LOG_ERROR("ChibiOS registry integrity check failed, " - "double linked list violation"); - rtos_valid = 0; - break; - } - /* Check for full iteration of the linked list. */ - if (current == rlist) - break; - tasks_found++; - previous = current; - } - if (!rtos_valid) { - /* No RTOS, there is always at least the current execution, though */ - LOG_INFO("Only showing current execution because of a broken " - "ChibiOS thread registry."); - - const char tmp_thread_name[] = "Current Execution"; - const char tmp_thread_extra_info[] = "No RTOS thread"; - - rtos->thread_details = malloc( - sizeof(struct thread_detail)); - rtos->thread_details->threadid = 1; - rtos->thread_details->exists = true; - - rtos->thread_details->extra_info_str = malloc( - sizeof(tmp_thread_extra_info)); - strcpy(rtos->thread_details->extra_info_str, tmp_thread_extra_info); - - rtos->thread_details->thread_name_str = malloc( - sizeof(tmp_thread_name)); - strcpy(rtos->thread_details->thread_name_str, tmp_thread_name); - - rtos->current_thread = 1; - rtos->thread_count = 1; - return ERROR_OK; - } - - /* create space for new thread details */ - rtos->thread_details = malloc( - sizeof(struct thread_detail) * tasks_found); - if (!rtos->thread_details) { - LOG_ERROR("Could not allocate space for thread details"); - return -1; - } - - rtos->thread_count = tasks_found; - /* Loop through linked list. */ - struct thread_detail *curr_thrd_details = rtos->thread_details; - while (curr_thrd_details < rtos->thread_details + tasks_found) { - uint32_t name_ptr = 0; - char tmp_str[CHIBIOS_THREAD_NAME_STR_SIZE]; - - retval = target_read_u32(rtos->target, - current + signature->cf_off_newer, ¤t); - if (retval != ERROR_OK) { - LOG_ERROR("Could not read next ChibiOS thread"); - return -6; - } - - /* Check for full iteration of the linked list. */ - if (current == rlist) - break; - - /* Save the thread pointer */ - curr_thrd_details->threadid = current; - - /* read the name pointer */ - retval = target_read_u32(rtos->target, - current + signature->cf_off_name, &name_ptr); - if (retval != ERROR_OK) { - LOG_ERROR("Could not read ChibiOS thread name pointer from target"); - return retval; - } - - /* Read the thread name */ - retval = target_read_buffer(rtos->target, name_ptr, - CHIBIOS_THREAD_NAME_STR_SIZE, - (uint8_t *)&tmp_str); - if (retval != ERROR_OK) { - LOG_ERROR("Error reading thread name from ChibiOS target"); - return retval; - } - tmp_str[CHIBIOS_THREAD_NAME_STR_SIZE - 1] = '\x00'; - - if (tmp_str[0] == '\x00') - strcpy(tmp_str, "No Name"); - - curr_thrd_details->thread_name_str = malloc( - strlen(tmp_str) + 1); - strcpy(curr_thrd_details->thread_name_str, tmp_str); - - /* State info */ - uint8_t threadState; - const char *state_desc; - - retval = target_read_u8(rtos->target, - current + signature->cf_off_state, &threadState); - if (retval != ERROR_OK) { - LOG_ERROR("Error reading thread state from ChibiOS target"); - return retval; - } - - - if (threadState < CHIBIOS_NUM_STATES) - state_desc = ChibiOS_thread_states[threadState]; - else - state_desc = "Unknown state"; - - curr_thrd_details->extra_info_str = malloc(strlen( - state_desc)+1); - strcpy(curr_thrd_details->extra_info_str, state_desc); - - curr_thrd_details->exists = true; - - curr_thrd_details++; - } - - uint32_t current_thrd; - /* NOTE: By design, cf_off_name equals readylist_current_offset */ - retval = target_read_u32(rtos->target, - rlist + signature->cf_off_name, - ¤t_thrd); - if (retval != ERROR_OK) { - LOG_ERROR("Could not read current Thread from ChibiOS target"); - return retval; - } - rtos->current_thread = current_thrd; - - return 0; -} - -static int ChibiOS_get_thread_reg_list(struct rtos *rtos, int64_t thread_id, char **hex_reg_list) -{ - int retval; - const struct ChibiOS_params *param; - uint32_t stack_ptr = 0; - - *hex_reg_list = NULL; - if ((rtos == NULL) || (thread_id == 0) || - (rtos->rtos_specific_params == NULL)) - return -1; - - param = (const struct ChibiOS_params *) rtos->rtos_specific_params; - - if (!param->signature) - return -1; - - /* Update stacking if it can only be determined from runtime information */ - if ((param->stacking_info == 0) && - (ChibiOS_update_stacking(rtos) != ERROR_OK)) { - LOG_ERROR("Failed to determine exact stacking for the target type %s", rtos->target->type->name); - return -1; - } - - /* Read the stack pointer */ - retval = target_read_u32(rtos->target, - thread_id + param->signature->cf_off_ctx, &stack_ptr); - if (retval != ERROR_OK) { - LOG_ERROR("Error reading stack frame from ChibiOS thread"); - return retval; - } - - return rtos_generic_stack_read(rtos->target, param->stacking_info, stack_ptr, hex_reg_list); -} - -static int ChibiOS_get_symbol_list_to_lookup(symbol_table_elem_t *symbol_list[]) -{ - *symbol_list = malloc(sizeof(ChibiOS_symbol_list)); - - if (*symbol_list == NULL) - return ERROR_FAIL; - - memcpy(*symbol_list, ChibiOS_symbol_list, sizeof(ChibiOS_symbol_list)); - return 0; -} - -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))) { - - if (target->rtos->symbols[ChibiOS_VAL_ch_debug].address == 0) { - LOG_INFO("It looks like the target may be running ChibiOS " - "without ch_debug."); - return 0; - } - - /* looks like ChibiOS with memory map enabled.*/ - return 1; - } - - return 0; -} - -static int ChibiOS_create(struct target *target) -{ - int i = 0; - while ((i < CHIBIOS_NUM_PARAMS) && - (0 != strcmp(ChibiOS_params_list[i].target_name, target->type->name))) { - i++; - } - if (i >= CHIBIOS_NUM_PARAMS) { - LOG_WARNING("Could not find target \"%s\" in ChibiOS compatibility " - "list", target->type->name); - return -1; - } - - target->rtos->rtos_specific_params = (void *) &ChibiOS_params_list[i]; - return 0; -} diff --git a/src/rtos/FreeRTOS.c b/src/rtos/FreeRTOS.c deleted file mode 100644 index 52cebadc7..000000000 --- a/src/rtos/FreeRTOS.c +++ /dev/null @@ -1,555 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2011 by Broadcom Corporation * - * Evan Hunter - ehunter@broadcom.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include "target/target.h" -#include "target/target_type.h" -#include "rtos.h" -#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 - -#define FreeRTOS_STRUCT(int_type, ptr_type, list_prev_offset) - -struct FreeRTOS_params { - const char *target_name; - const unsigned char thread_count_width; - const unsigned char pointer_width; - const unsigned char list_next_offset; - const unsigned char list_width; - const unsigned char list_elem_next_offset; - 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_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[] = { - { - "cortex_m", /* target_name */ - 4, /* thread_count_width; */ - 4, /* pointer_width; */ - 16, /* list_next_offset; */ - 20, /* list_width; */ - 8, /* list_elem_next_offset; */ - 12, /* list_elem_content_offset */ - 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 */ - 4, /* thread_count_width; */ - 4, /* pointer_width; */ - 16, /* list_next_offset; */ - 20, /* list_width; */ - 8, /* list_elem_next_offset; */ - 12, /* list_elem_content_offset */ - 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 */ - 4, /* thread_count_width; */ - 4, /* pointer_width; */ - 16, /* list_next_offset; */ - 20, /* list_width; */ - 8, /* list_elem_next_offset; */ - 12, /* list_elem_content_offset */ - 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, - }, -}; - -#define FREERTOS_NUM_PARAMS ((int)(sizeof(FreeRTOS_params_list)/sizeof(struct FreeRTOS_params))) - -static int FreeRTOS_detect_rtos(struct target *target); -static int FreeRTOS_create(struct target *target); -static int FreeRTOS_update_threads(struct rtos *rtos); -static int FreeRTOS_get_thread_reg_list(struct rtos *rtos, int64_t thread_id, char **hex_reg_list); -static int FreeRTOS_get_symbol_list_to_lookup(symbol_table_elem_t *symbol_list[]); - -struct rtos_type FreeRTOS_rtos = { - .name = "FreeRTOS", - - .detect_rtos = FreeRTOS_detect_rtos, - .create = FreeRTOS_create, - .update_threads = FreeRTOS_update_threads, - .get_thread_reg_list = FreeRTOS_get_thread_reg_list, - .get_symbol_list_to_lookup = FreeRTOS_get_symbol_list_to_lookup, -}; - -enum FreeRTOS_symbol_values { - FreeRTOS_VAL_pxCurrentTCB = 0, - FreeRTOS_VAL_pxReadyTasksLists = 1, - FreeRTOS_VAL_xDelayedTaskList1 = 2, - FreeRTOS_VAL_xDelayedTaskList2 = 3, - FreeRTOS_VAL_pxDelayedTaskList = 4, - FreeRTOS_VAL_pxOverflowDelayedTaskList = 5, - FreeRTOS_VAL_xPendingReadyList = 6, - FreeRTOS_VAL_xTasksWaitingTermination = 7, - FreeRTOS_VAL_xSuspendedTaskList = 8, - FreeRTOS_VAL_uxCurrentNumberOfTasks = 9, - FreeRTOS_VAL_uxTopUsedPriority = 10, -}; - -struct symbols { - const char *name; - bool optional; -}; - -static const struct symbols FreeRTOS_symbol_list[] = { - { "pxCurrentTCB", false }, - { "pxReadyTasksLists", false }, - { "xDelayedTaskList1", false }, - { "xDelayedTaskList2", false }, - { "pxDelayedTaskList", false }, - { "pxOverflowDelayedTaskList", false }, - { "xPendingReadyList", false }, - { "xTasksWaitingTermination", true }, /* Only if INCLUDE_vTaskDelete */ - { "xSuspendedTaskList", true }, /* Only if INCLUDE_vTaskSuspend */ - { "uxCurrentNumberOfTasks", false }, - { "uxTopUsedPriority", true }, /* Unavailable since v7.5.3 */ - { NULL, false } -}; - -/* TODO: */ -/* this is not safe for little endian yet */ -/* may be problems reading if sizes are not 32 bit long integers. */ -/* test mallocs for failure */ - -static int FreeRTOS_update_threads(struct rtos *rtos) -{ - int i = 0; - int retval; - int tasks_found = 0; - const struct FreeRTOS_params *param; - - if (rtos->rtos_specific_params == NULL) - return -1; - - param = (const struct FreeRTOS_params *) rtos->rtos_specific_params; - - if (rtos->symbols == NULL) { - LOG_ERROR("No symbols for FreeRTOS"); - return -3; - } - - if (rtos->symbols[FreeRTOS_VAL_uxCurrentNumberOfTasks].address == 0) { - LOG_ERROR("Don't have the number of threads in FreeRTOS"); - return -2; - } - - int thread_list_size = 0; - retval = target_read_buffer(rtos->target, - rtos->symbols[FreeRTOS_VAL_uxCurrentNumberOfTasks].address, - param->thread_count_width, - (uint8_t *)&thread_list_size); - LOG_DEBUG("FreeRTOS: Read uxCurrentNumberOfTasks at 0x%" PRIx64 ", value %d\r\n", - rtos->symbols[FreeRTOS_VAL_uxCurrentNumberOfTasks].address, - thread_list_size); - - if (retval != ERROR_OK) { - LOG_ERROR("Could not read FreeRTOS thread count from target"); - return retval; - } - - /* wipe out previous thread details if any */ - rtos_free_threadlist(rtos); - - /* read the current thread */ - retval = target_read_buffer(rtos->target, - rtos->symbols[FreeRTOS_VAL_pxCurrentTCB].address, - param->pointer_width, - (uint8_t *)&rtos->current_thread); - if (retval != ERROR_OK) { - LOG_ERROR("Error reading current thread in FreeRTOS thread list"); - return retval; - } - LOG_DEBUG("FreeRTOS: Read pxCurrentTCB at 0x%" PRIx64 ", value 0x%" PRIx64 "\r\n", - rtos->symbols[FreeRTOS_VAL_pxCurrentTCB].address, - rtos->current_thread); - - if ((thread_list_size == 0) || (rtos->current_thread == 0)) { - /* Either : No RTOS threads - there is always at least the current execution though */ - /* OR : No current thread - all threads suspended - show the current execution - * of idling */ - char tmp_str[] = "Current Execution"; - thread_list_size++; - tasks_found++; - rtos->thread_details = malloc( - sizeof(struct thread_detail) * thread_list_size); - if (!rtos->thread_details) { - LOG_ERROR("Error allocating memory for %d threads", thread_list_size); - return ERROR_FAIL; - } - rtos->thread_details->threadid = 1; - rtos->thread_details->exists = true; - rtos->thread_details->extra_info_str = NULL; - rtos->thread_details->thread_name_str = malloc(sizeof(tmp_str)); - strcpy(rtos->thread_details->thread_name_str, tmp_str); - - if (thread_list_size == 1) { - rtos->thread_count = 1; - return ERROR_OK; - } - } else { - /* create space for new thread details */ - rtos->thread_details = malloc( - sizeof(struct thread_detail) * thread_list_size); - if (!rtos->thread_details) { - LOG_ERROR("Error allocating memory for %d threads", thread_list_size); - return ERROR_FAIL; - } - } - - /* Find out how many lists are needed to be read from pxReadyTasksLists, */ - if (rtos->symbols[FreeRTOS_VAL_uxTopUsedPriority].address == 0) { - LOG_ERROR("FreeRTOS: uxTopUsedPriority is not defined, consult the OpenOCD manual for a work-around"); - return ERROR_FAIL; - } - int64_t max_used_priority = 0; - retval = target_read_buffer(rtos->target, - rtos->symbols[FreeRTOS_VAL_uxTopUsedPriority].address, - param->pointer_width, - (uint8_t *)&max_used_priority); - if (retval != ERROR_OK) - return retval; - LOG_DEBUG("FreeRTOS: Read uxTopUsedPriority at 0x%" PRIx64 ", value %" PRId64 "\r\n", - rtos->symbols[FreeRTOS_VAL_uxTopUsedPriority].address, - max_used_priority); - if (max_used_priority > FREERTOS_MAX_PRIORITIES) { - LOG_ERROR("FreeRTOS maximum used priority is unreasonably big, not proceeding: %" PRId64 "", - max_used_priority); - return ERROR_FAIL; - } - - symbol_address_t *list_of_lists = - malloc(sizeof(symbol_address_t) * - (max_used_priority+1 + 5)); - if (!list_of_lists) { - LOG_ERROR("Error allocating memory for %" PRId64 " priorities", max_used_priority); - return ERROR_FAIL; - } - - int num_lists; - for (num_lists = 0; num_lists <= max_used_priority; num_lists++) - list_of_lists[num_lists] = rtos->symbols[FreeRTOS_VAL_pxReadyTasksLists].address + - num_lists * param->list_width; - - list_of_lists[num_lists++] = rtos->symbols[FreeRTOS_VAL_xDelayedTaskList1].address; - list_of_lists[num_lists++] = rtos->symbols[FreeRTOS_VAL_xDelayedTaskList2].address; - list_of_lists[num_lists++] = rtos->symbols[FreeRTOS_VAL_xPendingReadyList].address; - list_of_lists[num_lists++] = rtos->symbols[FreeRTOS_VAL_xSuspendedTaskList].address; - list_of_lists[num_lists++] = rtos->symbols[FreeRTOS_VAL_xTasksWaitingTermination].address; - - for (i = 0; i < num_lists; i++) { - if (list_of_lists[i] == 0) - continue; - - /* Read the number of threads in this list */ - int64_t list_thread_count = 0; - retval = target_read_buffer(rtos->target, - list_of_lists[i], - param->thread_count_width, - (uint8_t *)&list_thread_count); - if (retval != ERROR_OK) { - LOG_ERROR("Error reading number of threads in FreeRTOS thread list"); - free(list_of_lists); - return retval; - } - LOG_DEBUG("FreeRTOS: Read thread count for list %d at 0x%" PRIx64 ", value %" PRId64 "\r\n", - i, list_of_lists[i], list_thread_count); - - if (list_thread_count == 0) - continue; - - /* Read the location of first list item */ - uint64_t prev_list_elem_ptr = -1; - uint64_t list_elem_ptr = 0; - retval = target_read_buffer(rtos->target, - list_of_lists[i] + param->list_next_offset, - param->pointer_width, - (uint8_t *)&list_elem_ptr); - if (retval != ERROR_OK) { - LOG_ERROR("Error reading first thread item location in FreeRTOS thread list"); - free(list_of_lists); - return retval; - } - LOG_DEBUG("FreeRTOS: Read first item for list %d at 0x%" PRIx64 ", value 0x%" PRIx64 "\r\n", - i, list_of_lists[i] + param->list_next_offset, list_elem_ptr); - - while ((list_thread_count > 0) && (list_elem_ptr != 0) && - (list_elem_ptr != prev_list_elem_ptr) && - (tasks_found < thread_list_size)) { - /* Get the location of the thread structure. */ - rtos->thread_details[tasks_found].threadid = 0; - retval = target_read_buffer(rtos->target, - list_elem_ptr + param->list_elem_content_offset, - param->pointer_width, - (uint8_t *)&(rtos->thread_details[tasks_found].threadid)); - if (retval != ERROR_OK) { - LOG_ERROR("Error reading thread list item object in FreeRTOS thread list"); - free(list_of_lists); - return retval; - } - LOG_DEBUG("FreeRTOS: Read Thread ID at 0x%" PRIx64 ", value 0x%" PRIx64 "\r\n", - list_elem_ptr + param->list_elem_content_offset, - rtos->thread_details[tasks_found].threadid); - - /* get thread name */ - - #define FREERTOS_THREAD_NAME_STR_SIZE (200) - char tmp_str[FREERTOS_THREAD_NAME_STR_SIZE]; - - /* Read the thread name */ - retval = target_read_buffer(rtos->target, - rtos->thread_details[tasks_found].threadid + param->thread_name_offset, - FREERTOS_THREAD_NAME_STR_SIZE, - (uint8_t *)&tmp_str); - if (retval != ERROR_OK) { - LOG_ERROR("Error reading first thread item location in FreeRTOS thread list"); - free(list_of_lists); - return retval; - } - tmp_str[FREERTOS_THREAD_NAME_STR_SIZE-1] = '\x00'; - LOG_DEBUG("FreeRTOS: Read Thread Name at 0x%" PRIx64 ", value \"%s\"\r\n", - rtos->thread_details[tasks_found].threadid + param->thread_name_offset, - tmp_str); - - if (tmp_str[0] == '\x00') - strcpy(tmp_str, "No Name"); - - 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].exists = true; - - if (rtos->thread_details[tasks_found].threadid == rtos->current_thread) { - char running_str[] = "Running"; - rtos->thread_details[tasks_found].extra_info_str = malloc( - sizeof(running_str)); - strcpy(rtos->thread_details[tasks_found].extra_info_str, - running_str); - } else - rtos->thread_details[tasks_found].extra_info_str = NULL; - - tasks_found++; - list_thread_count--; - - prev_list_elem_ptr = list_elem_ptr; - list_elem_ptr = 0; - retval = target_read_buffer(rtos->target, - prev_list_elem_ptr + param->list_elem_next_offset, - param->pointer_width, - (uint8_t *)&list_elem_ptr); - if (retval != ERROR_OK) { - LOG_ERROR("Error reading next thread item location in FreeRTOS thread list"); - free(list_of_lists); - return retval; - } - LOG_DEBUG("FreeRTOS: Read next thread location at 0x%" PRIx64 ", value 0x%" PRIx64 "\r\n", - prev_list_elem_ptr + param->list_elem_next_offset, - list_elem_ptr); - } - } - - free(list_of_lists); - rtos->thread_count = tasks_found; - return 0; -} - -static int FreeRTOS_get_thread_reg_list(struct rtos *rtos, int64_t thread_id, char **hex_reg_list) -{ - int retval; - const struct FreeRTOS_params *param; - int64_t stack_ptr = 0; - - *hex_reg_list = NULL; - if (rtos == NULL) - return -1; - - if (thread_id == 0) - return -2; - - if (rtos->rtos_specific_params == NULL) - return -1; - - param = (const struct FreeRTOS_params *) rtos->rtos_specific_params; - - /* Read the stack pointer */ - retval = target_read_buffer(rtos->target, - thread_id + param->thread_stack_offset, - param->pointer_width, - (uint8_t *)&stack_ptr); - if (retval != ERROR_OK) { - LOG_ERROR("Error reading stack frame from FreeRTOS thread"); - return retval; - } - LOG_DEBUG("FreeRTOS: Read stack pointer at 0x%" PRIx64 ", value 0x%" PRIx64 "\r\n", - thread_id + param->thread_stack_offset, - stack_ptr); - - /* 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[]) -{ - unsigned int i; - *symbol_list = calloc( - ARRAY_SIZE(FreeRTOS_symbol_list), sizeof(symbol_table_elem_t)); - - for (i = 0; i < ARRAY_SIZE(FreeRTOS_symbol_list); i++) { - (*symbol_list)[i].symbol_name = FreeRTOS_symbol_list[i].name; - (*symbol_list)[i].optional = FreeRTOS_symbol_list[i].optional; - } - - return 0; -} - -#if 0 - -static int FreeRTOS_set_current_thread(struct rtos *rtos, threadid_t thread_id) -{ - return 0; -} - -static int FreeRTOS_get_thread_ascii_info(struct rtos *rtos, threadid_t thread_id, char **info) -{ - int retval; - const struct FreeRTOS_params *param; - - if (rtos == NULL) - return -1; - - if (thread_id == 0) - return -2; - - if (rtos->rtos_specific_params == NULL) - return -3; - - param = (const struct FreeRTOS_params *) rtos->rtos_specific_params; - -#define FREERTOS_THREAD_NAME_STR_SIZE (200) - char tmp_str[FREERTOS_THREAD_NAME_STR_SIZE]; - - /* Read the thread name */ - retval = target_read_buffer(rtos->target, - thread_id + param->thread_name_offset, - FREERTOS_THREAD_NAME_STR_SIZE, - (uint8_t *)&tmp_str); - if (retval != ERROR_OK) { - LOG_ERROR("Error reading first thread item location in FreeRTOS thread list"); - return retval; - } - tmp_str[FREERTOS_THREAD_NAME_STR_SIZE-1] = '\x00'; - - if (tmp_str[0] == '\x00') - strcpy(tmp_str, "No Name"); - - *info = malloc(strlen(tmp_str)+1); - strcpy(*info, tmp_str); - return 0; -} - -#endif - -static int FreeRTOS_detect_rtos(struct target *target) -{ - if ((target->rtos->symbols != NULL) && - (target->rtos->symbols[FreeRTOS_VAL_pxReadyTasksLists].address != 0)) { - /* looks like FreeRTOS */ - return 1; - } - return 0; -} - -static int FreeRTOS_create(struct target *target) -{ - int i = 0; - while ((i < FREERTOS_NUM_PARAMS) && - (0 != strcmp(FreeRTOS_params_list[i].target_name, target->type->name))) { - i++; - } - if (i >= FREERTOS_NUM_PARAMS) { - LOG_ERROR("Could not find target in FreeRTOS compatibility list"); - return -1; - } - - target->rtos->rtos_specific_params = (void *) &FreeRTOS_params_list[i]; - return 0; -} diff --git a/src/rtos/Makefile.am b/src/rtos/Makefile.am deleted file mode 100644 index a7dab00d3..000000000 --- a/src/rtos/Makefile.am +++ /dev/null @@ -1,32 +0,0 @@ -# *************************************************************************** -# * Copyright (C) 2011 by Broadcom Corporation * -# * Evan Hunter - ehunter@broadcom.com * -# * * -# * This program is free software; you can redistribute it and/or modify * -# * it under the terms of the GNU General Public License as published by * -# * the Free Software Foundation; either version 2 of the License, or * -# * (at your option) any later version. * -# * * -# * This program is distributed in the hope that it will be useful, * -# * but WITHOUT ANY WARRANTY; without even the implied warranty of * -# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -# * GNU General Public License for more details. * -# * * -# * You should have received a copy of the GNU General Public License * -# * along with this program. If not, see . * -# *************************************************************************** - -include $(top_srcdir)/common.mk - -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 riscv_debug.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 riscv_debug.c - -librtos_la_CFLAGS = -if IS_MINGW -# FD_* macros are sloppy with their signs on MinGW32 platform -librtos_la_CFLAGS += -Wno-sign-compare -endif - -MAINTAINERCLEANFILES = $(srcdir)/Makefile.in diff --git a/src/rtos/ThreadX.c b/src/rtos/ThreadX.c deleted file mode 100644 index 8267b9f6a..000000000 --- a/src/rtos/ThreadX.c +++ /dev/null @@ -1,617 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2011 by Broadcom Corporation * - * Evan Hunter - ehunter@broadcom.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include "target/target.h" -#include "target/target_type.h" -#include "rtos.h" -#include "helper/log.h" -#include "helper/types.h" -#include "rtos_standard_stackings.h" - -static const struct rtos_register_stacking *get_stacking_info(const struct rtos *rtos, int64_t stack_ptr); -static const struct rtos_register_stacking *get_stacking_info_arm926ejs(const struct rtos *rtos, int64_t stack_ptr); - -static int is_thread_id_valid(const struct rtos *rtos, int64_t thread_id); -static int is_thread_id_valid_arm926ejs(const struct rtos *rtos, int64_t thread_id); - -static int ThreadX_detect_rtos(struct target *target); -static int ThreadX_create(struct target *target); -static int ThreadX_update_threads(struct rtos *rtos); -static int ThreadX_get_thread_reg_list(struct rtos *rtos, int64_t thread_id, char **hex_reg_list); -static int ThreadX_get_symbol_list_to_lookup(symbol_table_elem_t *symbol_list[]); - - - -struct ThreadX_thread_state { - int value; - const char *desc; -}; - -static const struct ThreadX_thread_state ThreadX_thread_states[] = { - { 0, "Ready" }, - { 1, "Completed" }, - { 2, "Terminated" }, - { 3, "Suspended" }, - { 4, "Sleeping" }, - { 5, "Waiting - Queue" }, - { 6, "Waiting - Semaphore" }, - { 7, "Waiting - Event flag" }, - { 8, "Waiting - Memory" }, - { 9, "Waiting - Memory" }, - { 10, "Waiting - I/O" }, - { 11, "Waiting - Filesystem" }, - { 12, "Waiting - Network" }, - { 13, "Waiting - Mutex" }, -}; - -#define THREADX_NUM_STATES (sizeof(ThreadX_thread_states)/sizeof(struct ThreadX_thread_state)) - -#define ARM926EJS_REGISTERS_SIZE_SOLICITED (11 * 4) -static const struct stack_register_offset rtos_threadx_arm926ejs_stack_offsets_solicited[] = { - { -1, 32 }, /* r0 */ - { -1, 32 }, /* r1 */ - { -1, 32 }, /* r2 */ - { -1, 32 }, /* r3 */ - { 0x08, 32 }, /* r4 */ - { 0x0C, 32 }, /* r5 */ - { 0x10, 32 }, /* r6 */ - { 0x14, 32 }, /* r7 */ - { 0x18, 32 }, /* r8 */ - { 0x1C, 32 }, /* r9 */ - { 0x20, 32 }, /* r10 */ - { 0x24, 32 }, /* r11 */ - { -1, 32 }, /* r12 */ - { -2, 32 }, /* sp (r13) */ - { 0x28, 32 }, /* lr (r14) */ - { -1, 32 }, /* pc (r15) */ - /*{ -1, 32 },*/ /* lr (r14) */ - /*{ 0x28, 32 },*/ /* pc (r15) */ - { 0x04, 32 }, /* xPSR */ -}; -#define ARM926EJS_REGISTERS_SIZE_INTERRUPT (17 * 4) -static const struct stack_register_offset rtos_threadx_arm926ejs_stack_offsets_interrupt[] = { - { 0x08, 32 }, /* r0 */ - { 0x0C, 32 }, /* r1 */ - { 0x10, 32 }, /* r2 */ - { 0x14, 32 }, /* r3 */ - { 0x18, 32 }, /* r4 */ - { 0x1C, 32 }, /* r5 */ - { 0x20, 32 }, /* r6 */ - { 0x24, 32 }, /* r7 */ - { 0x28, 32 }, /* r8 */ - { 0x2C, 32 }, /* r9 */ - { 0x30, 32 }, /* r10 */ - { 0x34, 32 }, /* r11 */ - { 0x38, 32 }, /* r12 */ - { -2, 32 }, /* sp (r13) */ - { 0x3C, 32 }, /* lr (r14) */ - { 0x40, 32 }, /* pc (r15) */ - { 0x04, 32 }, /* xPSR */ -}; - -const struct rtos_register_stacking rtos_threadx_arm926ejs_stacking[] = { -{ - ARM926EJS_REGISTERS_SIZE_SOLICITED, /* stack_registers_size */ - -1, /* stack_growth_direction */ - 17, /* num_output_registers */ - NULL, /* stack_alignment */ - rtos_threadx_arm926ejs_stack_offsets_solicited /* register_offsets */ -}, -{ - ARM926EJS_REGISTERS_SIZE_INTERRUPT, /* stack_registers_size */ - -1, /* stack_growth_direction */ - 17, /* num_output_registers */ - NULL, /* stack_alignment */ - rtos_threadx_arm926ejs_stack_offsets_interrupt /* register_offsets */ -}, -}; - -struct ThreadX_params { - const char *target_name; - unsigned char pointer_width; - unsigned char thread_stack_offset; - unsigned char thread_name_offset; - unsigned char thread_state_offset; - unsigned char thread_next_offset; - const struct rtos_register_stacking *stacking_info; - size_t stacking_info_nb; - const struct rtos_register_stacking* (*fn_get_stacking_info)(const struct rtos *rtos, int64_t stack_ptr); - int (*fn_is_thread_id_valid)(const struct rtos *rtos, int64_t thread_id); -}; - -static const struct ThreadX_params ThreadX_params_list[] = { - { - "cortex_m", /* target_name */ - 4, /* pointer_width; */ - 8, /* thread_stack_offset; */ - 40, /* thread_name_offset; */ - 48, /* thread_state_offset; */ - 136, /* thread_next_offset */ - &rtos_standard_Cortex_M3_stacking, /* stacking_info */ - 1, /* stacking_info_nb */ - NULL, /* fn_get_stacking_info */ - NULL, /* fn_is_thread_id_valid */ - }, - { - "cortex_r4", /* target_name */ - 4, /* pointer_width; */ - 8, /* thread_stack_offset; */ - 40, /* thread_name_offset; */ - 48, /* thread_state_offset; */ - 136, /* thread_next_offset */ - &rtos_standard_Cortex_R4_stacking, /* stacking_info */ - 1, /* stacking_info_nb */ - NULL, /* fn_get_stacking_info */ - NULL, /* fn_is_thread_id_valid */ - }, - { - "arm926ejs", /* target_name */ - 4, /* pointer_width; */ - 8, /* thread_stack_offset; */ - 40, /* thread_name_offset; */ - 48, /* thread_state_offset; */ - 136, /* thread_next_offset */ - rtos_threadx_arm926ejs_stacking, /* stacking_info */ - 2, /* stacking_info_nb */ - get_stacking_info_arm926ejs, /* fn_get_stacking_info */ - is_thread_id_valid_arm926ejs, /* fn_is_thread_id_valid */ - }, -}; - -#define THREADX_NUM_PARAMS ((int)(sizeof(ThreadX_params_list)/sizeof(struct ThreadX_params))) - -enum ThreadX_symbol_values { - ThreadX_VAL_tx_thread_current_ptr = 0, - ThreadX_VAL_tx_thread_created_ptr = 1, - ThreadX_VAL_tx_thread_created_count = 2, -}; - -static const char * const ThreadX_symbol_list[] = { - "_tx_thread_current_ptr", - "_tx_thread_created_ptr", - "_tx_thread_created_count", - NULL -}; - -const struct rtos_type ThreadX_rtos = { - .name = "ThreadX", - - .detect_rtos = ThreadX_detect_rtos, - .create = ThreadX_create, - .update_threads = ThreadX_update_threads, - .get_thread_reg_list = ThreadX_get_thread_reg_list, - .get_symbol_list_to_lookup = ThreadX_get_symbol_list_to_lookup, -}; - -static const struct rtos_register_stacking *get_stacking_info(const struct rtos *rtos, int64_t stack_ptr) -{ - const struct ThreadX_params *param = (const struct ThreadX_params *) rtos->rtos_specific_params; - - if (param->fn_get_stacking_info != NULL) - return param->fn_get_stacking_info(rtos, stack_ptr); - - return param->stacking_info + 0; -} - -static int is_thread_id_valid(const struct rtos *rtos, int64_t thread_id) -{ - const struct ThreadX_params *param; - - if (rtos->rtos_specific_params == NULL) - return 0; /* invalid */ - - param = (const struct ThreadX_params *) rtos->rtos_specific_params; - - if (param->fn_is_thread_id_valid != NULL) - return param->fn_is_thread_id_valid(rtos, thread_id); - - return (thread_id != 0); -} - -static const struct rtos_register_stacking *get_stacking_info_arm926ejs(const struct rtos *rtos, int64_t stack_ptr) -{ - const struct ThreadX_params *param = (const struct ThreadX_params *) rtos->rtos_specific_params; - int retval; - uint32_t flag; - - retval = target_read_buffer(rtos->target, - stack_ptr, - sizeof(flag), - (uint8_t *)&flag); - if (retval != ERROR_OK) { - LOG_ERROR("Error reading stack data from ThreadX thread: stack_ptr=0x%" PRIx64, stack_ptr); - return NULL; - } - - if (flag == 0) { - LOG_DEBUG(" solicited stack"); - return param->stacking_info + 0; - } else { - LOG_DEBUG(" interrupt stack: %u", flag); - return param->stacking_info + 1; - } -} - -static int is_thread_id_valid_arm926ejs(const struct rtos *rtos, int64_t thread_id) -{ - return (thread_id != 0 && thread_id != 1); -} - -static int ThreadX_update_threads(struct rtos *rtos) -{ - int retval; - int tasks_found = 0; - int thread_list_size = 0; - const struct ThreadX_params *param; - - if (rtos == NULL) - return -1; - - if (rtos->rtos_specific_params == NULL) - return -3; - - param = (const struct ThreadX_params *) rtos->rtos_specific_params; - - if (rtos->symbols == NULL) { - LOG_ERROR("No symbols for ThreadX"); - return -4; - } - - if (rtos->symbols[ThreadX_VAL_tx_thread_created_count].address == 0) { - LOG_ERROR("Don't have the number of threads in ThreadX"); - return -2; - } - - /* read the number of threads */ - retval = target_read_buffer(rtos->target, - rtos->symbols[ThreadX_VAL_tx_thread_created_count].address, - 4, - (uint8_t *)&thread_list_size); - - if (retval != ERROR_OK) { - LOG_ERROR("Could not read ThreadX thread count from target"); - return retval; - } - - /* wipe out previous thread details if any */ - rtos_free_threadlist(rtos); - - /* read the current thread id */ - retval = target_read_buffer(rtos->target, - rtos->symbols[ThreadX_VAL_tx_thread_current_ptr].address, - 4, - (uint8_t *)&rtos->current_thread); - - if (retval != ERROR_OK) { - LOG_ERROR("Could not read ThreadX current thread from target"); - return retval; - } - - if ((thread_list_size == 0) || (rtos->current_thread == 0)) { - /* Either : No RTOS threads - there is always at least the current execution though */ - /* OR : No current thread - all threads suspended - show the current execution - * of idling */ - char tmp_str[] = "Current Execution"; - thread_list_size++; - tasks_found++; - rtos->thread_details = malloc( - sizeof(struct thread_detail) * thread_list_size); - rtos->thread_details->threadid = 1; - rtos->thread_details->exists = true; - rtos->thread_details->extra_info_str = NULL; - rtos->thread_details->thread_name_str = malloc(sizeof(tmp_str)); - strcpy(rtos->thread_details->thread_name_str, tmp_str); - - if (thread_list_size == 0) { - rtos->thread_count = 1; - return ERROR_OK; - } - } else { - /* create space for new thread details */ - rtos->thread_details = malloc( - sizeof(struct thread_detail) * thread_list_size); - } - - /* Read the pointer to the first thread */ - int64_t thread_ptr = 0; - retval = target_read_buffer(rtos->target, - rtos->symbols[ThreadX_VAL_tx_thread_created_ptr].address, - param->pointer_width, - (uint8_t *)&thread_ptr); - if (retval != ERROR_OK) { - LOG_ERROR("Could not read ThreadX thread location from target"); - return retval; - } - - /* loop over all threads */ - int64_t prev_thread_ptr = 0; - while ((thread_ptr != prev_thread_ptr) && (tasks_found < thread_list_size)) { - - #define THREADX_THREAD_NAME_STR_SIZE (200) - char tmp_str[THREADX_THREAD_NAME_STR_SIZE]; - unsigned int i = 0; - int64_t name_ptr = 0; - - /* Save the thread pointer */ - rtos->thread_details[tasks_found].threadid = thread_ptr; - - /* read the name pointer */ - retval = target_read_buffer(rtos->target, - thread_ptr + param->thread_name_offset, - param->pointer_width, - (uint8_t *)&name_ptr); - if (retval != ERROR_OK) { - LOG_ERROR("Could not read ThreadX thread name pointer from target"); - return retval; - } - - /* Read the thread name */ - retval = - target_read_buffer(rtos->target, - name_ptr, - THREADX_THREAD_NAME_STR_SIZE, - (uint8_t *)&tmp_str); - if (retval != ERROR_OK) { - LOG_ERROR("Error reading thread name from ThreadX target"); - return retval; - } - tmp_str[THREADX_THREAD_NAME_STR_SIZE-1] = '\x00'; - - if (tmp_str[0] == '\x00') - strcpy(tmp_str, "No Name"); - - rtos->thread_details[tasks_found].thread_name_str = - malloc(strlen(tmp_str)+1); - strcpy(rtos->thread_details[tasks_found].thread_name_str, tmp_str); - - /* Read the thread status */ - int64_t thread_status = 0; - retval = target_read_buffer(rtos->target, - thread_ptr + param->thread_state_offset, - 4, - (uint8_t *)&thread_status); - if (retval != ERROR_OK) { - LOG_ERROR("Error reading thread state from ThreadX target"); - return retval; - } - - for (i = 0; (i < THREADX_NUM_STATES) && - (ThreadX_thread_states[i].value != thread_status); i++) { - /* empty */ - } - - const char *state_desc; - if (i < THREADX_NUM_STATES) - state_desc = ThreadX_thread_states[i].desc; - else - 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); - - rtos->thread_details[tasks_found].exists = true; - - tasks_found++; - prev_thread_ptr = thread_ptr; - - /* Get the location of the next thread structure. */ - thread_ptr = 0; - retval = target_read_buffer(rtos->target, - prev_thread_ptr + param->thread_next_offset, - param->pointer_width, - (uint8_t *) &thread_ptr); - if (retval != ERROR_OK) { - LOG_ERROR("Error reading next thread pointer in ThreadX thread list"); - return retval; - } - } - - rtos->thread_count = tasks_found; - - return 0; -} - -static int ThreadX_get_thread_reg_list(struct rtos *rtos, int64_t thread_id, char **hex_reg_list) -{ - int retval; - const struct ThreadX_params *param; - - *hex_reg_list = NULL; - - if (rtos == NULL) - return -1; - - if (!is_thread_id_valid(rtos, thread_id)) - return -2; - - if (rtos->rtos_specific_params == NULL) - return -3; - - param = (const struct ThreadX_params *) rtos->rtos_specific_params; - - /* Read the stack pointer */ - int64_t stack_ptr = 0; - retval = target_read_buffer(rtos->target, - thread_id + param->thread_stack_offset, - param->pointer_width, - (uint8_t *)&stack_ptr); - if (retval != ERROR_OK) { - LOG_ERROR("Error reading stack frame from ThreadX thread"); - return retval; - } - - LOG_INFO("thread: 0x%" PRIx64 ", stack_ptr=0x%" PRIx64, (uint64_t)thread_id, (uint64_t)stack_ptr); - - if (stack_ptr == 0) { - LOG_ERROR("null stack pointer in thread"); - return -5; - } - - const struct rtos_register_stacking *stacking_info = - get_stacking_info(rtos, stack_ptr); - - if (stacking_info == NULL) { - LOG_ERROR("Unknown stacking info for thread id=0x%" PRIx64, (uint64_t)thread_id); - return -6; - } - - return rtos_generic_stack_read(rtos->target, stacking_info, stack_ptr, hex_reg_list); -} - -static int ThreadX_get_symbol_list_to_lookup(symbol_table_elem_t *symbol_list[]) -{ - unsigned int i; - *symbol_list = calloc( - ARRAY_SIZE(ThreadX_symbol_list), sizeof(symbol_table_elem_t)); - - for (i = 0; i < ARRAY_SIZE(ThreadX_symbol_list); i++) - (*symbol_list)[i].symbol_name = ThreadX_symbol_list[i]; - - return 0; -} - -static int ThreadX_detect_rtos(struct target *target) -{ - if ((target->rtos->symbols != NULL) && - (target->rtos->symbols[ThreadX_VAL_tx_thread_created_ptr].address != 0)) { - /* looks like ThreadX */ - return 1; - } - return 0; -} - -#if 0 - -static int ThreadX_set_current_thread(struct rtos *rtos, threadid_t thread_id) -{ - return 0; -} - -static int ThreadX_get_thread_detail(struct rtos *rtos, - threadid_t thread_id, - struct thread_detail *detail) -{ - unsigned int i = 0; - int retval; - -#define THREADX_THREAD_NAME_STR_SIZE (200) - char tmp_str[THREADX_THREAD_NAME_STR_SIZE]; - - const struct ThreadX_params *param; - - if (rtos == NULL) - return -1; - - if (thread_id == 0) - return -2; - - if (rtos->rtos_specific_params == NULL) - return -3; - - param = (const struct ThreadX_params *) rtos->rtos_specific_params; - - if (rtos->symbols == NULL) { - LOG_ERROR("No symbols for ThreadX"); - return -3; - } - - detail->threadid = thread_id; - - int64_t name_ptr = 0; - /* read the name pointer */ - retval = target_read_buffer(rtos->target, - thread_id + param->thread_name_offset, - param->pointer_width, - (uint8_t *)&name_ptr); - if (retval != ERROR_OK) { - LOG_ERROR("Could not read ThreadX thread name pointer from target"); - return retval; - } - - /* Read the thread name */ - retval = target_read_buffer(rtos->target, - name_ptr, - THREADX_THREAD_NAME_STR_SIZE, - (uint8_t *)&tmp_str); - if (retval != ERROR_OK) { - LOG_ERROR("Error reading thread name from ThreadX target"); - return retval; - } - tmp_str[THREADX_THREAD_NAME_STR_SIZE-1] = '\x00'; - - if (tmp_str[0] == '\x00') - strcpy(tmp_str, "No Name"); - - detail->thread_name_str = malloc(strlen(tmp_str)+1); - - /* Read the thread status */ - int64_t thread_status = 0; - retval = - target_read_buffer(rtos->target, - thread_id + param->thread_state_offset, - 4, - (uint8_t *)&thread_status); - if (retval != ERROR_OK) { - LOG_ERROR("Error reading thread state from ThreadX target"); - return retval; - } - - for (i = 0; (i < THREADX_NUM_STATES) && - (ThreadX_thread_states[i].value != thread_status); i++) { - /* empty */ - } - - char *state_desc; - if (i < THREADX_NUM_STATES) - state_desc = ThreadX_thread_states[i].desc; - else - state_desc = "Unknown state"; - - detail->extra_info_str = malloc(strlen(state_desc)+1); - - detail->exists = true; - - return 0; -} - -#endif - -static int ThreadX_create(struct target *target) -{ - int i = 0; - while ((i < THREADX_NUM_PARAMS) && - (0 != strcmp(ThreadX_params_list[i].target_name, target->type->name))) { - i++; - } - if (i >= THREADX_NUM_PARAMS) { - LOG_ERROR("Could not find target in ThreadX compatibility list"); - return -1; - } - - target->rtos->rtos_specific_params = (void *) &ThreadX_params_list[i]; - target->rtos->current_thread = 0; - target->rtos->thread_details = NULL; - return 0; -} diff --git a/src/rtos/eCos.c b/src/rtos/eCos.c deleted file mode 100644 index e38e11f04..000000000 --- a/src/rtos/eCos.c +++ /dev/null @@ -1,392 +0,0 @@ -/*************************************************************************** - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 -#include "config.h" -#endif - -#include -#include -#include "target/target.h" -#include "target/target_type.h" -#include "rtos.h" -#include "helper/log.h" -#include "helper/types.h" -#include "rtos_ecos_stackings.h" - -static int eCos_detect_rtos(struct target *target); -static int eCos_create(struct target *target); -static int eCos_update_threads(struct rtos *rtos); -static int eCos_get_thread_reg_list(struct rtos *rtos, int64_t thread_id, char **hex_reg_list); -static int eCos_get_symbol_list_to_lookup(symbol_table_elem_t *symbol_list[]); - -struct eCos_thread_state { - int value; - const char *desc; -}; - -static const struct eCos_thread_state eCos_thread_states[] = { - { 0, "Ready" }, - { 1, "Sleeping" }, - { 2, "Countsleep" }, - { 4, "Suspended" }, - { 8, "Creating" }, - { 16, "Exited" } -}; - -#define ECOS_NUM_STATES (sizeof(eCos_thread_states)/sizeof(struct eCos_thread_state)) - -struct eCos_params { - const char *target_name; - unsigned char pointer_width; - unsigned char thread_stack_offset; - unsigned char thread_name_offset; - unsigned char thread_state_offset; - unsigned char thread_next_offset; - unsigned char thread_uniqueid_offset; - const struct rtos_register_stacking *stacking_info; -}; - -static const struct eCos_params eCos_params_list[] = { - { - "cortex_m", /* target_name */ - 4, /* pointer_width; */ - 0x0c, /* thread_stack_offset; */ - 0x9c, /* thread_name_offset; */ - 0x3c, /* thread_state_offset; */ - 0xa0, /* thread_next_offset */ - 0x4c, /* thread_uniqueid_offset */ - &rtos_eCos_Cortex_M3_stacking /* stacking_info */ - } -}; - -#define ECOS_NUM_PARAMS ((int)(sizeof(eCos_params_list)/sizeof(struct eCos_params))) - -enum eCos_symbol_values { - eCos_VAL_thread_list = 0, - eCos_VAL_current_thread_ptr = 1 -}; - -static const char * const eCos_symbol_list[] = { - "Cyg_Thread::thread_list", - "Cyg_Scheduler_Base::current_thread", - NULL -}; - -const struct rtos_type eCos_rtos = { - .name = "eCos", - - .detect_rtos = eCos_detect_rtos, - .create = eCos_create, - .update_threads = eCos_update_threads, - .get_thread_reg_list = eCos_get_thread_reg_list, - .get_symbol_list_to_lookup = eCos_get_symbol_list_to_lookup, - -}; - -static int eCos_update_threads(struct rtos *rtos) -{ - int retval; - int tasks_found = 0; - int thread_list_size = 0; - const struct eCos_params *param; - - if (rtos == NULL) - return -1; - - if (rtos->rtos_specific_params == NULL) - return -3; - - param = (const struct eCos_params *) rtos->rtos_specific_params; - - if (rtos->symbols == NULL) { - LOG_ERROR("No symbols for eCos"); - return -4; - } - - if (rtos->symbols[eCos_VAL_thread_list].address == 0) { - LOG_ERROR("Don't have the thread list head"); - return -2; - } - - /* wipe out previous thread details if any */ - rtos_free_threadlist(rtos); - - /* determine the number of current threads */ - uint32_t thread_list_head = rtos->symbols[eCos_VAL_thread_list].address; - uint32_t thread_index; - target_read_buffer(rtos->target, - thread_list_head, - param->pointer_width, - (uint8_t *) &thread_index); - uint32_t first_thread = thread_index; - do { - thread_list_size++; - retval = target_read_buffer(rtos->target, - thread_index + param->thread_next_offset, - param->pointer_width, - (uint8_t *) &thread_index); - if (retval != ERROR_OK) - return retval; - } while (thread_index != first_thread); - - /* read the current thread id */ - uint32_t current_thread_addr; - retval = target_read_buffer(rtos->target, - rtos->symbols[eCos_VAL_current_thread_ptr].address, - 4, - (uint8_t *)¤t_thread_addr); - if (retval != ERROR_OK) - return retval; - rtos->current_thread = 0; - retval = target_read_buffer(rtos->target, - current_thread_addr + param->thread_uniqueid_offset, - 2, - (uint8_t *)&rtos->current_thread); - if (retval != ERROR_OK) { - LOG_ERROR("Could not read eCos current thread from target"); - return retval; - } - - if ((thread_list_size == 0) || (rtos->current_thread == 0)) { - /* Either : No RTOS threads - there is always at least the current execution though */ - /* OR : No current thread - all threads suspended - show the current execution - * of idling */ - char tmp_str[] = "Current Execution"; - thread_list_size++; - tasks_found++; - rtos->thread_details = malloc( - sizeof(struct thread_detail) * thread_list_size); - rtos->thread_details->threadid = 1; - rtos->thread_details->exists = true; - rtos->thread_details->extra_info_str = NULL; - rtos->thread_details->thread_name_str = malloc(sizeof(tmp_str)); - strcpy(rtos->thread_details->thread_name_str, tmp_str); - - if (thread_list_size == 0) { - rtos->thread_count = 1; - return ERROR_OK; - } - } else { - /* create space for new thread details */ - rtos->thread_details = malloc( - sizeof(struct thread_detail) * thread_list_size); - } - - /* loop over all threads */ - thread_index = first_thread; - do { - - #define ECOS_THREAD_NAME_STR_SIZE (200) - char tmp_str[ECOS_THREAD_NAME_STR_SIZE]; - unsigned int i = 0; - uint32_t name_ptr = 0; - uint32_t prev_thread_ptr; - - /* Save the thread pointer */ - uint16_t thread_id; - retval = target_read_buffer(rtos->target, - thread_index + param->thread_uniqueid_offset, - 2, - (uint8_t *)&thread_id); - if (retval != ERROR_OK) { - LOG_ERROR("Could not read eCos thread id from target"); - return retval; - } - rtos->thread_details[tasks_found].threadid = thread_id; - - /* read the name pointer */ - retval = target_read_buffer(rtos->target, - thread_index + param->thread_name_offset, - param->pointer_width, - (uint8_t *)&name_ptr); - if (retval != ERROR_OK) { - LOG_ERROR("Could not read eCos thread name pointer from target"); - return retval; - } - - /* Read the thread name */ - retval = - target_read_buffer(rtos->target, - name_ptr, - ECOS_THREAD_NAME_STR_SIZE, - (uint8_t *)&tmp_str); - if (retval != ERROR_OK) { - LOG_ERROR("Error reading thread name from eCos target"); - return retval; - } - tmp_str[ECOS_THREAD_NAME_STR_SIZE-1] = '\x00'; - - if (tmp_str[0] == '\x00') - strcpy(tmp_str, "No Name"); - - rtos->thread_details[tasks_found].thread_name_str = - malloc(strlen(tmp_str)+1); - strcpy(rtos->thread_details[tasks_found].thread_name_str, tmp_str); - - /* Read the thread status */ - int64_t thread_status = 0; - retval = target_read_buffer(rtos->target, - thread_index + param->thread_state_offset, - 4, - (uint8_t *)&thread_status); - if (retval != ERROR_OK) { - LOG_ERROR("Error reading thread state from eCos target"); - return retval; - } - - for (i = 0; (i < ECOS_NUM_STATES) && (eCos_thread_states[i].value != thread_status); i++) { - /* - * empty - */ - } - - const char *state_desc; - if (i < ECOS_NUM_STATES) - state_desc = eCos_thread_states[i].desc; - else - 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); - - rtos->thread_details[tasks_found].exists = true; - - tasks_found++; - prev_thread_ptr = thread_index; - - /* Get the location of the next thread structure. */ - thread_index = rtos->symbols[eCos_VAL_thread_list].address; - retval = target_read_buffer(rtos->target, - prev_thread_ptr + param->thread_next_offset, - param->pointer_width, - (uint8_t *) &thread_index); - if (retval != ERROR_OK) { - LOG_ERROR("Error reading next thread pointer in eCos thread list"); - return retval; - } - } while (thread_index != first_thread); - - rtos->thread_count = tasks_found; - return 0; -} - -static int eCos_get_thread_reg_list(struct rtos *rtos, int64_t thread_id, char **hex_reg_list) -{ - int retval; - const struct eCos_params *param; - - *hex_reg_list = NULL; - - if (rtos == NULL) - return -1; - - if (thread_id == 0) - return -2; - - if (rtos->rtos_specific_params == NULL) - return -3; - - param = (const struct eCos_params *) rtos->rtos_specific_params; - - /* Find the thread with that thread id */ - uint16_t id = 0; - uint32_t thread_list_head = rtos->symbols[eCos_VAL_thread_list].address; - uint32_t thread_index; - target_read_buffer(rtos->target, thread_list_head, param->pointer_width, - (uint8_t *)&thread_index); - bool done = false; - while (!done) { - retval = target_read_buffer(rtos->target, - thread_index + param->thread_uniqueid_offset, - 2, - (uint8_t *)&id); - if (retval != ERROR_OK) { - LOG_ERROR("Error reading unique id from eCos thread"); - return retval; - } - - if (id == thread_id) { - done = true; - break; - } - target_read_buffer(rtos->target, - thread_index + param->thread_next_offset, - param->pointer_width, - (uint8_t *) &thread_index); - } - - if (done) { - /* Read the stack pointer */ - int64_t stack_ptr = 0; - retval = target_read_buffer(rtos->target, - thread_index + param->thread_stack_offset, - param->pointer_width, - (uint8_t *)&stack_ptr); - if (retval != ERROR_OK) { - LOG_ERROR("Error reading stack frame from eCos thread"); - return retval; - } - - return rtos_generic_stack_read(rtos->target, - param->stacking_info, - stack_ptr, - hex_reg_list); - } - - return -1; -} - -static int eCos_get_symbol_list_to_lookup(symbol_table_elem_t *symbol_list[]) -{ - unsigned int i; - *symbol_list = calloc( - ARRAY_SIZE(eCos_symbol_list), sizeof(symbol_table_elem_t)); - - for (i = 0; i < ARRAY_SIZE(eCos_symbol_list); i++) - (*symbol_list)[i].symbol_name = eCos_symbol_list[i]; - - return 0; -} - -static int eCos_detect_rtos(struct target *target) -{ - if ((target->rtos->symbols != NULL) && - (target->rtos->symbols[eCos_VAL_thread_list].address != 0)) { - /* looks like eCos */ - return 1; - } - return 0; -} - -static int eCos_create(struct target *target) -{ - int i = 0; - while ((i < ECOS_NUM_PARAMS) && - (0 != strcmp(eCos_params_list[i].target_name, target->type->name))) { - i++; - } - if (i >= ECOS_NUM_PARAMS) { - LOG_ERROR("Could not find target in eCos compatibility list"); - return -1; - } - - target->rtos->rtos_specific_params = (void *) &eCos_params_list[i]; - target->rtos->current_thread = 0; - target->rtos->thread_details = NULL; - return 0; -} diff --git a/src/rtos/embKernel.c b/src/rtos/embKernel.c deleted file mode 100644 index ceb313f02..000000000 --- a/src/rtos/embKernel.c +++ /dev/null @@ -1,342 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2011 by Broadcom Corporation * - * Evan Hunter - ehunter@broadcom.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include "target/target.h" -#include "target/target_type.h" -#include "rtos.h" -#include "helper/log.h" -#include "helper/types.h" -#include "rtos_embkernel_stackings.h" - -#define EMBKERNEL_MAX_THREAD_NAME_STR_SIZE (64) - -static int embKernel_detect_rtos(struct target *target); -static int embKernel_create(struct target *target); -static int embKernel_update_threads(struct rtos *rtos); -static int embKernel_get_thread_reg_list(struct rtos *rtos, int64_t thread_id, char **hex_reg_list); -static int embKernel_get_symbol_list_to_lookup(symbol_table_elem_t *symbol_list[]); - -struct rtos_type embKernel_rtos = { - .name = "embKernel", - .detect_rtos = embKernel_detect_rtos, - .create = embKernel_create, - .update_threads = embKernel_update_threads, - .get_thread_reg_list = - embKernel_get_thread_reg_list, - .get_symbol_list_to_lookup = embKernel_get_symbol_list_to_lookup, -}; - -enum { - SYMBOL_ID_sCurrentTask = 0, - SYMBOL_ID_sListReady = 1, - SYMBOL_ID_sListSleep = 2, - SYMBOL_ID_sListSuspended = 3, - SYMBOL_ID_sMaxPriorities = 4, - SYMBOL_ID_sCurrentTaskCount = 5, -}; - -static const char * const embKernel_symbol_list[] = { - "Rtos::sCurrentTask", - "Rtos::sListReady", - "Rtos::sListSleep", - "Rtos::sListSuspended", - "Rtos::sMaxPriorities", - "Rtos::sCurrentTaskCount", - NULL }; - -struct embKernel_params { - const char *target_name; - const unsigned char pointer_width; - const unsigned char thread_count_width; - const unsigned char rtos_list_size; - const unsigned char thread_stack_offset; - const unsigned char thread_name_offset; - const unsigned char thread_priority_offset; - const unsigned char thread_priority_width; - const unsigned char iterable_next_offset; - const unsigned char iterable_task_owner_offset; - const struct rtos_register_stacking *stacking_info; -}; - -static const struct embKernel_params embKernel_params_list[] = { - { - "cortex_m", /* target_name */ - 4, /* pointer_width */ - 4, /* thread_count_width */ - 8, /*rtos_list_size */ - 0, /*thread_stack_offset */ - 4, /*thread_name_offset */ - 8, /*thread_priority_offset */ - 4, /*thread_priority_width */ - 4, /*iterable_next_offset */ - 12, /*iterable_task_owner_offset */ - &rtos_embkernel_Cortex_M_stacking, /* stacking_info*/ - }, - { "hla_target", /* target_name */ - 4, /* pointer_width */ - 4, /* thread_count_width */ - 8, /*rtos_list_size */ - 0, /*thread_stack_offset */ - 4, /*thread_name_offset */ - 8, /*thread_priority_offset */ - 4, /*thread_priority_width */ - 4, /*iterable_next_offset */ - 12, /*iterable_task_owner_offset */ - &rtos_embkernel_Cortex_M_stacking, /* stacking_info */ - } -}; - -static int embKernel_detect_rtos(struct target *target) -{ - if (target->rtos->symbols != NULL) { - if (target->rtos->symbols[SYMBOL_ID_sCurrentTask].address != 0) - return 1; - } - return 0; -} - -static int embKernel_create(struct target *target) -{ - size_t i = 0; - while ((i < ARRAY_SIZE(embKernel_params_list)) && - (0 != strcmp(embKernel_params_list[i].target_name, target->type->name))) - i++; - - if (i >= ARRAY_SIZE(embKernel_params_list)) { - LOG_WARNING("Could not find target \"%s\" in embKernel compatibility " - "list", target->type->name); - return -1; - } - - target->rtos->rtos_specific_params = (void *) &embKernel_params_list[i]; - return 0; -} - -static int embKernel_get_tasks_details(struct rtos *rtos, int64_t iterable, const struct embKernel_params *param, - struct thread_detail *details, const char* state_str) -{ - int64_t task = 0; - int retval = target_read_buffer(rtos->target, iterable + param->iterable_task_owner_offset, param->pointer_width, - (uint8_t *) &task); - if (retval != ERROR_OK) - return retval; - details->threadid = (threadid_t) task; - details->exists = true; - - int64_t name_ptr = 0; - retval = target_read_buffer(rtos->target, task + param->thread_name_offset, param->pointer_width, - (uint8_t *) &name_ptr); - if (retval != ERROR_OK) - return retval; - - details->thread_name_str = malloc(EMBKERNEL_MAX_THREAD_NAME_STR_SIZE); - if (name_ptr) { - retval = target_read_buffer(rtos->target, name_ptr, EMBKERNEL_MAX_THREAD_NAME_STR_SIZE, - (uint8_t *) details->thread_name_str); - if (retval != ERROR_OK) - return retval; - details->thread_name_str[EMBKERNEL_MAX_THREAD_NAME_STR_SIZE - 1] = 0; - } else { - snprintf(details->thread_name_str, EMBKERNEL_MAX_THREAD_NAME_STR_SIZE, "NoName:[0x%08X]", (unsigned int) task); - } - - int64_t priority = 0; - retval = target_read_buffer(rtos->target, task + param->thread_priority_offset, param->thread_priority_width, - (uint8_t *) &priority); - if (retval != ERROR_OK) - 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", - (unsigned int) priority); - } else { - snprintf(details->extra_info_str, EMBKERNEL_MAX_THREAD_NAME_STR_SIZE, "Pri=%u, %s", (unsigned int) priority, - state_str); - } - - LOG_OUTPUT("Getting task details: iterable=0x%08X, task=0x%08X, name=%s\n", (unsigned int)iterable, - (unsigned int)task, details->thread_name_str); - return 0; -} - -static int embKernel_update_threads(struct rtos *rtos) -{ - /* int i = 0; */ - int retval; - const struct embKernel_params *param; - - if (rtos == NULL) - return -1; - - if (rtos->rtos_specific_params == NULL) - return -3; - - if (rtos->symbols == NULL) { - LOG_ERROR("No symbols for embKernel"); - return -4; - } - - if (rtos->symbols[SYMBOL_ID_sCurrentTask].address == 0) { - LOG_ERROR("Don't have the thread list head"); - return -2; - } - - /* wipe out previous thread details if any */ - rtos_free_threadlist(rtos); - - param = (const struct embKernel_params *) rtos->rtos_specific_params; - - retval = target_read_buffer(rtos->target, rtos->symbols[SYMBOL_ID_sCurrentTask].address, param->pointer_width, - (uint8_t *) &rtos->current_thread); - if (retval != ERROR_OK) { - LOG_ERROR("Error reading current thread in embKernel thread list"); - return retval; - } - - int64_t max_used_priority = 0; - retval = target_read_buffer(rtos->target, rtos->symbols[SYMBOL_ID_sMaxPriorities].address, param->pointer_width, - (uint8_t *) &max_used_priority); - if (retval != ERROR_OK) - return retval; - - int thread_list_size = 0; - retval = target_read_buffer(rtos->target, rtos->symbols[SYMBOL_ID_sCurrentTaskCount].address, - param->thread_count_width, (uint8_t *) &thread_list_size); - - if (retval != ERROR_OK) { - LOG_ERROR("Could not read embKernel thread count from target"); - return retval; - } - - /* create space for new thread details */ - rtos->thread_details = malloc(sizeof(struct thread_detail) * thread_list_size); - if (!rtos->thread_details) { - LOG_ERROR("Error allocating memory for %d threads", thread_list_size); - return ERROR_FAIL; - } - - int threadIdx = 0; - /* Look for ready tasks */ - for (int pri = 0; pri < max_used_priority; pri++) { - /* Get first item in queue */ - int64_t iterable = 0; - retval = target_read_buffer(rtos->target, - rtos->symbols[SYMBOL_ID_sListReady].address + (pri * param->rtos_list_size), param->pointer_width, - (uint8_t *) &iterable); - if (retval != ERROR_OK) - return retval; - for (; iterable && threadIdx < thread_list_size; threadIdx++) { - /* Get info from this iterable item */ - retval = embKernel_get_tasks_details(rtos, iterable, param, &rtos->thread_details[threadIdx], "Ready"); - if (retval != ERROR_OK) - return retval; - /* Get next iterable item */ - retval = target_read_buffer(rtos->target, iterable + param->iterable_next_offset, param->pointer_width, - (uint8_t *) &iterable); - if (retval != ERROR_OK) - return retval; - } - } - /* Look for sleeping tasks */ - int64_t iterable = 0; - retval = target_read_buffer(rtos->target, rtos->symbols[SYMBOL_ID_sListSleep].address, param->pointer_width, - (uint8_t *) &iterable); - if (retval != ERROR_OK) - return retval; - for (; iterable && threadIdx < thread_list_size; threadIdx++) { - /*Get info from this iterable item */ - retval = embKernel_get_tasks_details(rtos, iterable, param, &rtos->thread_details[threadIdx], "Sleeping"); - if (retval != ERROR_OK) - return retval; - /*Get next iterable item */ - retval = target_read_buffer(rtos->target, iterable + param->iterable_next_offset, param->pointer_width, - (uint8_t *) &iterable); - if (retval != ERROR_OK) - return retval; - } - - /* Look for suspended tasks */ - iterable = 0; - retval = target_read_buffer(rtos->target, rtos->symbols[SYMBOL_ID_sListSuspended].address, param->pointer_width, - (uint8_t *) &iterable); - if (retval != ERROR_OK) - return retval; - for (; iterable && threadIdx < thread_list_size; threadIdx++) { - /* Get info from this iterable item */ - retval = embKernel_get_tasks_details(rtos, iterable, param, &rtos->thread_details[threadIdx], "Suspended"); - if (retval != ERROR_OK) - return retval; - /*Get next iterable item */ - retval = target_read_buffer(rtos->target, iterable + param->iterable_next_offset, param->pointer_width, - (uint8_t *) &iterable); - if (retval != ERROR_OK) - return retval; - } - - rtos->thread_count = 0; - rtos->thread_count = threadIdx; - LOG_OUTPUT("Found %u tasks\n", (unsigned int)threadIdx); - return 0; -} - -static int embKernel_get_thread_reg_list(struct rtos *rtos, int64_t thread_id, char **hex_reg_list) -{ - int retval; - const struct embKernel_params *param; - int64_t stack_ptr = 0; - - *hex_reg_list = NULL; - if (rtos == NULL) - return -1; - - if (thread_id == 0) - return -2; - - if (rtos->rtos_specific_params == NULL) - return -1; - - param = (const struct embKernel_params *) rtos->rtos_specific_params; - - /* Read the stack pointer */ - retval = target_read_buffer(rtos->target, thread_id + param->thread_stack_offset, param->pointer_width, - (uint8_t *) &stack_ptr); - if (retval != ERROR_OK) { - LOG_ERROR("Error reading stack frame from embKernel thread"); - return retval; - } - - return rtos_generic_stack_read(rtos->target, param->stacking_info, stack_ptr, hex_reg_list); -} - -static int embKernel_get_symbol_list_to_lookup(symbol_table_elem_t *symbol_list[]) -{ - unsigned int i; - *symbol_list = calloc(ARRAY_SIZE(embKernel_symbol_list), sizeof(symbol_table_elem_t)); - - for (i = 0; i < ARRAY_SIZE(embKernel_symbol_list); i++) - (*symbol_list)[i].symbol_name = embKernel_symbol_list[i]; - - return 0; -} - diff --git a/src/rtos/linux.c b/src/rtos/linux.c deleted file mode 100644 index 8c150af2e..000000000 --- a/src/rtos/linux.c +++ /dev/null @@ -1,1594 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2011 by STEricsson * - * Heythem Bouhaja heythem.bouhaja@stericsson.com : creation * - * Michel JAOUEN michel.jaouen@stericsson.com : adaptation to rtos * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include "target/target.h" -#include "target/target_type.h" -#include "helper/log.h" -#include "helper/types.h" -#include "rtos.h" -#include "rtos_standard_stackings.h" -#include -#include "server/gdb_server.h" - -#define LINUX_USER_KERNEL_BORDER 0xc0000000 -#include "linux_header.h" -#define PHYS -#define MAX_THREADS 200 -/* specific task */ -struct linux_os { - const char *name; - uint32_t init_task_addr; - int thread_count; - int threadid_count; - int preupdtate_threadid_count; - int nr_cpus; - int threads_lookup; - int threads_needs_update; - struct current_thread *current_threads; - struct threads *thread_list; - /* virt2phys parameter */ - uint32_t phys_mask; - uint32_t phys_base; -}; - -struct current_thread { - int64_t threadid; - int32_t core_id; -#ifdef PID_CHECK - uint32_t pid; -#endif - uint32_t TS; - struct current_thread *next; -}; - -struct threads { - char name[17]; - uint32_t base_addr; /* address to read magic */ - uint32_t state; /* magic value : filled only at creation */ - uint32_t pid; /* linux pid : id for identifying a thread */ - uint32_t oncpu; /* content cpu number in current thread */ - uint32_t asid; /* filled only at creation */ - int64_t threadid; - int status; /* dead = 1 alive = 2 current = 3 alive and current */ - /* value that should not change during the live of a thread ? */ - uint32_t thread_info_addr; /* contain latest thread_info_addr computed */ - /* retrieve from thread_info */ - struct cpu_context *context; - struct threads *next; -}; - -struct cpu_context { - uint32_t R4; - uint32_t R5; - uint32_t R6; - uint32_t R7; - uint32_t R8; - uint32_t R9; - uint32_t IP; - uint32_t FP; - uint32_t SP; - uint32_t PC; - uint32_t preempt_count; -}; -struct cpu_context *cpu_context_read(struct target *target, uint32_t base_addr, - uint32_t *info_addr); -static int insert_into_threadlist(struct target *target, struct threads *t); - -static int linux_os_create(struct target *target); - -static int linux_os_dummy_update(struct rtos *rtos) -{ - /* update is done only when thread request come - * too many thread to do it on each stop */ - return 0; -} - -static int linux_compute_virt2phys(struct target *target, uint32_t address) -{ - struct linux_os *linux_os = (struct linux_os *) - target->rtos->rtos_specific_params; - uint32_t pa = 0; - int retval = target->type->virt2phys(target, address, &pa); - if (retval != ERROR_OK) { - LOG_ERROR("Cannot compute linux virt2phys translation"); - /* fixes default address */ - linux_os->phys_base = 0; - return ERROR_FAIL; - } - - linux_os->init_task_addr = address; - address = address & linux_os->phys_mask; - linux_os->phys_base = pa - address; - return ERROR_OK; -} - -static int linux_read_memory(struct target *target, - uint32_t address, uint32_t size, uint32_t count, - uint8_t *buffer) -{ -#ifdef PHYS - struct linux_os *linux_os = (struct linux_os *) - target->rtos->rtos_specific_params; - uint32_t pa = (address & linux_os->phys_mask) + linux_os->phys_base; -#endif - if (address < 0xc000000) { - LOG_ERROR("linux awareness : address in user space"); - return ERROR_FAIL; - } -#ifdef PHYS - target_read_phys_memory(target, pa, size, count, buffer); -#endif - target_read_memory(target, address, size, count, buffer); - return ERROR_OK; -} - -static char *reg_converter(char *buffer, void *reg, int size) -{ - int i; - - for (i = 0; i < size; i++) - buffer += sprintf(buffer, "%02x", ((uint8_t *) reg)[i]); - - return buffer; -} - -int fill_buffer(struct target *target, uint32_t addr, uint8_t *buffer) -{ - - if ((addr & 0xfffffffc) != addr) - LOG_INFO("unaligned address %" PRIx32 "!!", addr); - - int retval = linux_read_memory(target, addr, 4, 1, buffer); - return retval; - -} - -uint32_t get_buffer(struct target *target, const uint8_t *buffer) -{ - uint32_t value = 0; - const uint8_t *value_ptr = buffer; - value = target_buffer_get_u32(target, value_ptr); - return value; -} - -static int linux_os_thread_reg_list(struct rtos *rtos, - int64_t thread_id, char **hex_reg_list) -{ - struct target *target = rtos->target; - struct linux_os *linux_os = (struct linux_os *) - target->rtos->rtos_specific_params; - int i = 0; - struct current_thread *tmp = linux_os->current_threads; - struct current_thread *next; - char *hex_string; - int found = 0; - int retval; - /* check if a current thread is requested */ - next = tmp; - - do { - if (next->threadid == thread_id) - found = 1; - else - next = next->next; - } while ((found == 0) && (next != tmp) && (next != NULL)); - - if (found == 1) { - /* search target to perfom the access */ - struct reg **reg_list; - int reg_list_size, reg_packet_size = 0; - struct target_list *head; - head = target->head; - found = 0; - do { - if (head->target->coreid == next->core_id) { - - target = head->target; - found = 1; - } else - head = head->next; - - } while ((head != (struct target_list *)NULL) && (found == 0)); - - if (found == 0) { - LOG_ERROR - ( - "current thread %" PRIx64 ": no target to perform access of core id %" PRIx32, - thread_id, - next->core_id); - return ERROR_FAIL; - } - - /*LOG_INFO("thread %lx current on core %x",thread_id, - * target->coreid);*/ - retval = - target_get_gdb_reg_list(target, ®_list, ®_list_size, - REG_CLASS_GENERAL); - - if (retval != ERROR_OK) - return retval; - - for (i = 0; i < reg_list_size; i++) - reg_packet_size += reg_list[i]->size; - - assert(reg_packet_size > 0); - - *hex_reg_list = malloc(DIV_ROUND_UP(reg_packet_size, 8) * 2); - - hex_string = *hex_reg_list; - - for (i = 0; i < reg_list_size; i++) { - if (!reg_list[i]->valid) - reg_list[i]->type->get(reg_list[i]); - - hex_string = reg_converter(hex_string, - reg_list[i]->value, - (reg_list[i]->size) / 8); - } - - free(reg_list); - - } else { - struct threads *temp = linux_os->thread_list; - *hex_reg_list = calloc(1, 500 * sizeof(char)); - hex_string = *hex_reg_list; - - for (i = 0; i < 16; i++) - hex_string += sprintf(hex_string, "%02x", 0); - - while ((temp != NULL) && - (temp->threadid != target->rtos->current_threadid)) - temp = temp->next; - - if (temp != NULL) { - if (temp->context == NULL) - temp->context = cpu_context_read(target, - temp-> - base_addr, - &temp-> - thread_info_addr); - - hex_string = - reg_converter(hex_string, &temp->context->R4, 4); - hex_string = - reg_converter(hex_string, &temp->context->R5, 4); - hex_string = - reg_converter(hex_string, &temp->context->R6, 4); - hex_string = - reg_converter(hex_string, &temp->context->R7, 4); - hex_string = - reg_converter(hex_string, &temp->context->R8, 4); - hex_string = - reg_converter(hex_string, &temp->context->R9, 4); - - for (i = 0; i < 4; i++) /*R10 = 0x0 */ - hex_string += sprintf(hex_string, "%02x", 0); - - hex_string = - reg_converter(hex_string, &temp->context->FP, 4); - hex_string = - reg_converter(hex_string, &temp->context->IP, 4); - hex_string = - reg_converter(hex_string, &temp->context->SP, 4); - - for (i = 0; i < 4; i++) - hex_string += sprintf(hex_string, "%02x", 0); - - hex_string = - reg_converter(hex_string, &temp->context->PC, 4); - - for (i = 0; i < 100; i++) /*100 */ - hex_string += sprintf(hex_string, "%02x", 0); - - uint32_t cpsr = 0x00000000; - reg_converter(hex_string, &cpsr, 4); - } - } - return ERROR_OK; -} - -static int linux_os_detect(struct target *target) -{ - LOG_INFO("should no be called"); - return 0; -} - -static int linux_os_smp_init(struct target *target); -static int linux_os_clean(struct target *target); -#define INIT_TASK 0 -static const char * const linux_symbol_list[] = { - "init_task", - NULL -}; - -static int linux_get_symbol_list_to_lookup(symbol_table_elem_t *symbol_list[]) -{ - unsigned int i; - *symbol_list = (symbol_table_elem_t *) - calloc(ARRAY_SIZE(linux_symbol_list), sizeof(symbol_table_elem_t)); - - for (i = 0; i < ARRAY_SIZE(linux_symbol_list); i++) - (*symbol_list)[i].symbol_name = linux_symbol_list[i]; - - return 0; -} - -static char *linux_ps_command(struct target *target); - -const struct rtos_type Linux_os = { - .name = "linux", - .detect_rtos = linux_os_detect, - .create = linux_os_create, - .smp_init = linux_os_smp_init, - .update_threads = linux_os_dummy_update, - .get_thread_reg_list = linux_os_thread_reg_list, - .get_symbol_list_to_lookup = linux_get_symbol_list_to_lookup, - .clean = linux_os_clean, - .ps_command = linux_ps_command, -}; - -static int linux_thread_packet(struct connection *connection, char const *packet, - int packet_size); -static void linux_identify_current_threads(struct target *target); - -#ifdef PID_CHECK -int fill_task_pid(struct target *target, struct threads *t) -{ - uint32_t pid_addr = t->base_addr + PID; - uint8_t buffer[4]; - int retval = fill_buffer(target, pid_addr, buffer); - - if (retval == ERROR_OK) { - uint32_t val = get_buffer(target, buffer); - t->pid = val; - } else - LOG_ERROR("fill_task_pid: unable to read memory"); - - return retval; -} -#endif - -int fill_task(struct target *target, struct threads *t) -{ - int retval; - uint32_t pid_addr = t->base_addr + PID; - uint32_t mem_addr = t->base_addr + MEM; - uint32_t on_cpu = t->base_addr + ONCPU; - uint8_t *buffer = calloc(1, 4); - retval = fill_buffer(target, t->base_addr, buffer); - - if (retval == ERROR_OK) { - uint32_t val = get_buffer(target, buffer); - t->state = val; - } else - LOG_ERROR("fill_task: unable to read memory"); - - retval = fill_buffer(target, pid_addr, buffer); - - if (retval == ERROR_OK) { - uint32_t val = get_buffer(target, buffer); - t->pid = val; - } else - LOG_ERROR("fill task: unable to read memory"); - - retval = fill_buffer(target, on_cpu, buffer); - - if (retval == ERROR_OK) { - uint32_t val = get_buffer(target, buffer); - t->oncpu = val; - } else - LOG_ERROR("fill task: unable to read memory"); - - retval = fill_buffer(target, mem_addr, buffer); - - if (retval == ERROR_OK) { - uint32_t val = get_buffer(target, buffer); - - if (val != 0) { - uint32_t asid_addr = val + MM_CTX; - retval = fill_buffer(target, asid_addr, buffer); - - if (retval == ERROR_OK) { - val = get_buffer(target, buffer); - t->asid = val; - } else - LOG_ERROR - ("fill task: unable to read memory -- ASID"); - } else - t->asid = 0; - } else - LOG_ERROR("fill task: unable to read memory"); - - free(buffer); - - return retval; -} - -int get_name(struct target *target, struct threads *t) -{ - int retval; - uint32_t full_name[4]; - uint32_t comm = t->base_addr + COMM; - int i; - - for (i = 0; i < 17; i++) - t->name[i] = 0; - - retval = linux_read_memory(target, comm, 4, 4, (uint8_t *) full_name); - - if (retval != ERROR_OK) { - LOG_ERROR("get_name: unable to read memory\n"); - return ERROR_FAIL; - } - - uint32_t raw_name = target_buffer_get_u32(target, - (const uint8_t *) - &full_name[0]); - t->name[3] = raw_name >> 24; - t->name[2] = raw_name >> 16; - t->name[1] = raw_name >> 8; - t->name[0] = raw_name; - raw_name = - target_buffer_get_u32(target, (const uint8_t *)&full_name[1]); - t->name[7] = raw_name >> 24; - t->name[6] = raw_name >> 16; - t->name[5] = raw_name >> 8; - t->name[4] = raw_name; - raw_name = - target_buffer_get_u32(target, (const uint8_t *)&full_name[2]); - t->name[11] = raw_name >> 24; - t->name[10] = raw_name >> 16; - t->name[9] = raw_name >> 8; - t->name[8] = raw_name; - raw_name = - target_buffer_get_u32(target, (const uint8_t *)&full_name[3]); - t->name[15] = raw_name >> 24; - t->name[14] = raw_name >> 16; - t->name[13] = raw_name >> 8; - t->name[12] = raw_name; - return ERROR_OK; - -} - -int get_current(struct target *target, int create) -{ - struct target_list *head; - head = target->head; - uint8_t *buf; - uint32_t val; - uint32_t ti_addr; - uint8_t *buffer = calloc(1, 4); - struct linux_os *linux_os = (struct linux_os *) - target->rtos->rtos_specific_params; - struct current_thread *ctt = linux_os->current_threads; - - /* invalid current threads content */ - while (ctt != NULL) { - ctt->threadid = -1; - ctt->TS = 0xdeadbeef; - ctt = ctt->next; - } - - while (head != (struct target_list *)NULL) { - struct reg **reg_list; - int reg_list_size; - int retval; - - if (target_get_gdb_reg_list(head->target, ®_list, - ®_list_size, REG_CLASS_GENERAL) != ERROR_OK) { - free(buffer); - return ERROR_TARGET_FAILURE; - } - - if (!reg_list[13]->valid) - reg_list[13]->type->get(reg_list[13]); - - buf = reg_list[13]->value; - val = get_buffer(target, buf); - ti_addr = (val & 0xffffe000); - uint32_t TS_addr = ti_addr + 0xc; - retval = fill_buffer(target, TS_addr, buffer); - - if (retval == ERROR_OK) { - uint32_t TS = get_buffer(target, buffer); - uint32_t cpu, on_cpu = TS + ONCPU; - retval = fill_buffer(target, on_cpu, buffer); - - if (retval == ERROR_OK) { - /*uint32_t cpu = get_buffer(target, buffer);*/ - struct current_thread *ct = - linux_os->current_threads; - cpu = head->target->coreid; - - while ((ct != NULL) && (ct->core_id != (int32_t) cpu)) - ct = ct->next; - - if ((ct != NULL) && (ct->TS == 0xdeadbeef)) - ct->TS = TS; - else - LOG_ERROR - ("error in linux current thread update"); - - if (create && ct) { - struct threads *t; - t = calloc(1, sizeof(struct threads)); - t->base_addr = ct->TS; - fill_task(target, t); - get_name(target, t); - t->oncpu = cpu; - insert_into_threadlist(target, t); - t->status = 3; - t->thread_info_addr = 0xdeadbeef; - ct->threadid = t->threadid; - linux_os->thread_count++; -#ifdef PID_CHECK - ct->pid = t->pid; -#endif - /*LOG_INFO("Creation of current thread %s",t->name);*/ - } - } - } - - free(reg_list); - head = head->next; - } - - free(buffer); - - return ERROR_OK; -} - -struct cpu_context *cpu_context_read(struct target *target, uint32_t base_addr, - uint32_t *thread_info_addr_old) -{ - struct cpu_context *context = calloc(1, sizeof(struct cpu_context)); - uint32_t preempt_count_addr = 0; - uint32_t registers[10]; - uint8_t *buffer = calloc(1, 4); - uint32_t stack = base_addr + QAT; - uint32_t thread_info_addr = 0; - uint32_t thread_info_addr_update = 0; - int retval = ERROR_FAIL; - context->R4 = 0xdeadbeef; - context->R5 = 0xdeadbeef; - context->R6 = 0xdeadbeef; - context->R7 = 0xdeadbeef; - context->R8 = 0xdeadbeef; - context->R9 = 0xdeadbeef; - context->IP = 0xdeadbeef; - context->FP = 0xdeadbeef; - context->SP = 0xdeadbeef; - context->PC = 0xdeadbeef; -retry: - - if (*thread_info_addr_old == 0xdeadbeef) { - retval = fill_buffer(target, stack, buffer); - - if (retval == ERROR_OK) - thread_info_addr = get_buffer(target, buffer); - else - LOG_ERROR("cpu_context: unable to read memory"); - - thread_info_addr_update = thread_info_addr; - } else - thread_info_addr = *thread_info_addr_old; - - preempt_count_addr = thread_info_addr + PREEMPT; - retval = fill_buffer(target, preempt_count_addr, buffer); - - if (retval == ERROR_OK) - context->preempt_count = get_buffer(target, buffer); - else { - if (*thread_info_addr_old != 0xdeadbeef) { - LOG_ERROR - ("cpu_context: cannot read at thread_info_addr"); - - if (*thread_info_addr_old < LINUX_USER_KERNEL_BORDER) - LOG_INFO - ("cpu_context : thread_info_addr in userspace!!!"); - - *thread_info_addr_old = 0xdeadbeef; - goto retry; - } - - LOG_ERROR("cpu_context: unable to read memory"); - } - - thread_info_addr += CPU_CONT; - - retval = linux_read_memory(target, thread_info_addr, 4, 10, - (uint8_t *) registers); - - if (retval != ERROR_OK) { - free(buffer); - LOG_ERROR("cpu_context: unable to read memory\n"); - return context; - } - - context->R4 = - target_buffer_get_u32(target, (const uint8_t *)®isters[0]); - context->R5 = - target_buffer_get_u32(target, (const uint8_t *)®isters[1]); - context->R6 = - target_buffer_get_u32(target, (const uint8_t *)®isters[2]); - context->R7 = - target_buffer_get_u32(target, (const uint8_t *)®isters[3]); - context->R8 = - target_buffer_get_u32(target, (const uint8_t *)®isters[4]); - context->R9 = - target_buffer_get_u32(target, (const uint8_t *)®isters[5]); - context->IP = - target_buffer_get_u32(target, (const uint8_t *)®isters[6]); - context->FP = - target_buffer_get_u32(target, (const uint8_t *)®isters[7]); - context->SP = - target_buffer_get_u32(target, (const uint8_t *)®isters[8]); - context->PC = - target_buffer_get_u32(target, (const uint8_t *)®isters[9]); - - if (*thread_info_addr_old == 0xdeadbeef) - *thread_info_addr_old = thread_info_addr_update; - - free(buffer); - - return context; -} - -uint32_t next_task(struct target *target, struct threads *t) -{ - uint8_t *buffer = calloc(1, 4); - uint32_t next_addr = t->base_addr + NEXT; - int retval = fill_buffer(target, next_addr, buffer); - - if (retval == ERROR_OK) { - uint32_t val = get_buffer(target, buffer); - val = val - NEXT; - free(buffer); - return val; - } else - LOG_ERROR("next task: unable to read memory"); - - free(buffer); - - return 0; -} - -struct current_thread *add_current_thread(struct current_thread *currents, - struct current_thread *ct) -{ - ct->next = NULL; - - if (currents == NULL) { - currents = ct; - return currents; - } else { - struct current_thread *temp = currents; - - while (temp->next != NULL) - temp = temp->next; - - temp->next = ct; - return currents; - } -} - -struct threads *liste_del_task(struct threads *task_list, struct threads **t, - struct threads *prev) -{ - LOG_INFO("del task %" PRId64, (*t)->threadid); - prev->next = (*t)->next; - - if (prev == task_list) - task_list = prev; - - /* free content of threads */ - if ((*t)->context) - free((*t)->context); - - free(*t); - *t = prev; - return task_list; -} - -struct threads *liste_add_task(struct threads *task_list, struct threads *t, - struct threads **last) -{ - t->next = NULL; - - if (*last == NULL) - if (task_list == NULL) { - task_list = t; - return task_list; - } else { - struct threads *temp = task_list; - - while (temp->next != NULL) - temp = temp->next; - - temp->next = t; - *last = t; - return task_list; - } else { - (*last)->next = t; - *last = t; - return task_list; - } -} - -#ifdef PID_CHECK -static int current_pid(struct linux_os *linux_os, uint32_t pid) -#else -static int current_base_addr(struct linux_os *linux_os, uint32_t base_addr) -#endif -{ - struct current_thread *ct = linux_os->current_threads; -#ifdef PID_CHECK - - while ((ct != NULL) && (ct->pid != pid)) -#else - while ((ct != NULL) && (ct->TS != base_addr)) -#endif - ct = ct->next; -#ifdef PID_CHECK - if ((ct != NULL) && (ct->pid == pid)) -#else - if ((ct != NULL) && (ct->TS == base_addr)) -#endif - return 1; - - return 0; -} - -int linux_get_tasks(struct target *target, int context) -{ - int loop = 0; - int retval = 0; - struct linux_os *linux_os = (struct linux_os *) - target->rtos->rtos_specific_params; - linux_os->thread_list = NULL; - linux_os->thread_count = 0; - - if (linux_os->init_task_addr == 0xdeadbeef) { - LOG_INFO("no init symbol\n"); - return ERROR_FAIL; - } - - int64_t start = timeval_ms(); - - struct threads *t = calloc(1, sizeof(struct threads)); - struct threads *last = NULL; - t->base_addr = linux_os->init_task_addr; - /* retrieve the thread id , currently running in the different smp core */ - get_current(target, 1); - - while (((t->base_addr != linux_os->init_task_addr) && - (t->base_addr != 0)) || (loop == 0)) { - loop++; - fill_task(target, t); - retval = get_name(target, t); - - if (loop > MAX_THREADS) { - free(t); - LOG_INFO("more than %d threads !!", MAX_THREADS); - return ERROR_FAIL; - } - - if (retval != ERROR_OK) { - free(t); - return ERROR_FAIL; - } - - /* check that this thread is not one the current threads already - * created */ -#ifdef PID_CHECK - - if (!current_pid(linux_os, t->pid)) { -#else - if (!current_base_addr(linux_os, t->base_addr)) { -#endif - t->threadid = linux_os->threadid_count; - t->status = 1; - linux_os->threadid_count++; - - linux_os->thread_list = - liste_add_task(linux_os->thread_list, t, &last); - /* no interest to fill the context if it is a current thread. */ - linux_os->thread_count++; - t->thread_info_addr = 0xdeadbeef; - - if (context) - t->context = - cpu_context_read(target, t->base_addr, - &t->thread_info_addr); - } else { - /*LOG_INFO("thread %s is a current thread already created",t->name); */ - free(t); - } - - uint32_t base_addr = next_task(target, t); - t = calloc(1, sizeof(struct threads)); - t->base_addr = base_addr; - } - - linux_os->threads_lookup = 1; - linux_os->threads_needs_update = 0; - linux_os->preupdtate_threadid_count = linux_os->threadid_count - 1; - /* check that all current threads have been identified */ - - LOG_INFO("complete time %" PRId64 ", thread mean %" PRId64 "\n", - (timeval_ms() - start), - (timeval_ms() - start) / linux_os->threadid_count); - - LOG_INFO("threadid count %d", linux_os->threadid_count); - free(t); - - return ERROR_OK; -} - -static int clean_threadlist(struct target *target) -{ - struct linux_os *linux_os = (struct linux_os *) - target->rtos->rtos_specific_params; - struct threads *old, *temp = linux_os->thread_list; - - while (temp != NULL) { - old = temp; - - if (temp->context) - free(temp->context); - - temp = temp->next; - free(old); - } - - return ERROR_OK; -} - -static int linux_os_clean(struct target *target) -{ - struct linux_os *os_linux = (struct linux_os *) - target->rtos->rtos_specific_params; - clean_threadlist(target); - os_linux->init_task_addr = 0xdeadbeef; - os_linux->name = "linux"; - os_linux->thread_list = NULL; - os_linux->thread_count = 0; - os_linux->nr_cpus = 0; - os_linux->threads_lookup = 0; - os_linux->threads_needs_update = 0; - os_linux->threadid_count = 1; - return ERROR_OK; -} - -static int insert_into_threadlist(struct target *target, struct threads *t) -{ - struct linux_os *linux_os = (struct linux_os *) - target->rtos->rtos_specific_params; - struct threads *temp = linux_os->thread_list; - t->threadid = linux_os->threadid_count; - linux_os->threadid_count++; - t->status = 1; - t->next = NULL; - - if (temp == NULL) - linux_os->thread_list = t; - else { - while (temp->next != NULL) - temp = temp->next; - - t->next = NULL; - temp->next = t; - } - - return ERROR_OK; -} - -static void linux_identify_current_threads(struct target *target) -{ - struct linux_os *linux_os = (struct linux_os *) - target->rtos->rtos_specific_params; - struct threads *thread_list = linux_os->thread_list; - struct current_thread *ct = linux_os->current_threads; - struct threads *t = NULL; - - while ((ct != NULL)) { - if (ct->threadid == -1) { - - /* un-identified thread */ - int found = 0; - t = calloc(1, sizeof(struct threads)); - t->base_addr = ct->TS; -#ifdef PID_CHECK - - if (fill_task_pid(target, t) != ERROR_OK) { -error_handling: - free(t); - LOG_ERROR - ("linux identify_current_threads: unable to read pid"); - return; - } -#endif - - /* search in the list of threads if pid - already present */ - while ((thread_list != NULL) && (found == 0)) { -#ifdef PID_CHECK - if (thread_list->pid == t->pid) { -#else - if (thread_list->base_addr == t->base_addr) { -#endif - free(t); - t = thread_list; - found = 1; - } - thread_list = thread_list->next; - } - - if (!found) { - /* it is a new thread */ - if (fill_task(target, t) != ERROR_OK) - goto error_handling; - - get_name(target, t); - insert_into_threadlist(target, t); - t->thread_info_addr = 0xdeadbeef; - } - - t->status = 3; - ct->threadid = t->threadid; -#ifdef PID_CHECK - ct->pid = t->pid; -#endif - linux_os->thread_count++; -#if 0 - if (found == 0) - LOG_INFO("current thread core %x identified %s", - ct->core_id, t->name); - else - LOG_INFO("current thread core %x, reused %s", - ct->core_id, t->name); -#endif - } -#if 0 - else { - struct threads tmp; - tmp.base_addr = ct->TS; - get_name(target, &tmp); - LOG_INFO("current thread core %x , already identified %s !!!", - ct->core_id, tmp.name); - } -#endif - ct = ct->next; - } - - return; -#ifndef PID_CHECK -error_handling: - free(t); - LOG_ERROR("unable to read pid"); - return; - -#endif -} - -static int linux_task_update(struct target *target, int context) -{ - struct linux_os *linux_os = (struct linux_os *) - target->rtos->rtos_specific_params; - struct threads *thread_list = linux_os->thread_list; - int retval; - int loop = 0; - linux_os->thread_count = 0; - - /*thread_list = thread_list->next; skip init_task*/ - while (thread_list != NULL) { - thread_list->status = 0; /*setting all tasks to dead state*/ - - if (thread_list->context) { - free(thread_list->context); - thread_list->context = NULL; - } - - thread_list = thread_list->next; - } - - int found = 0; - - if (linux_os->init_task_addr == 0xdeadbeef) { - LOG_INFO("no init symbol\n"); - return ERROR_FAIL; - } - int64_t start = timeval_ms(); - struct threads *t = calloc(1, sizeof(struct threads)); - uint32_t previous = 0xdeadbeef; - t->base_addr = linux_os->init_task_addr; - retval = get_current(target, 0); - /*check that all current threads have been identified */ - linux_identify_current_threads(target); - - while (((t->base_addr != linux_os->init_task_addr) && - (t->base_addr != previous)) || (loop == 0)) { - /* for avoiding any permanent loop for any reason possibly due to - * target */ - loop++; - previous = t->base_addr; - /* read only pid */ -#ifdef PID_CHECK - retval = fill_task_pid(target, t); -#endif - - if (retval != ERROR_OK) { - free(t); - return ERROR_FAIL; - } - - thread_list = linux_os->thread_list; - - while (thread_list != NULL) { -#ifdef PID_CHECK - if (t->pid == thread_list->pid) { -#else - if (t->base_addr == thread_list->base_addr) { -#endif - if (!thread_list->status) { -#ifdef PID_CHECK - if (t->base_addr != thread_list->base_addr) - LOG_INFO("thread base_addr has changed !!"); -#endif - /* this is not a current thread */ - thread_list->base_addr = t->base_addr; - thread_list->status = 1; - - /* we don 't update this field any more */ - - /*thread_list->state = t->state; - thread_list->oncpu = t->oncpu; - thread_list->asid = t->asid; - */ - if (context) - thread_list->context = - cpu_context_read(target, - thread_list-> - base_addr, - &thread_list-> - thread_info_addr); - } else { - /* it is a current thread no need to read context */ - } - - linux_os->thread_count++; - found = 1; - break; - } else { - found = 0; - thread_list = thread_list->next; - } - } - - if (found == 0) { - uint32_t base_addr; - fill_task(target, t); - get_name(target, t); - retval = insert_into_threadlist(target, t); - t->thread_info_addr = 0xdeadbeef; - - if (context) - t->context = - cpu_context_read(target, t->base_addr, - &t->thread_info_addr); - - base_addr = next_task(target, t); - t = calloc(1, sizeof(struct threads)); - t->base_addr = base_addr; - linux_os->thread_count++; - } else - t->base_addr = next_task(target, t); - } - - LOG_INFO("update thread done %" PRId64 ", mean%" PRId64 "\n", - (timeval_ms() - start), (timeval_ms() - start) / loop); - free(t); - linux_os->threads_needs_update = 0; - return ERROR_OK; -} - -int linux_gdb_thread_packet(struct target *target, - struct connection *connection, char const *packet, - int packet_size) -{ - int retval; - struct linux_os *linux_os = - (struct linux_os *)target->rtos->rtos_specific_params; - - if (linux_os->init_task_addr == 0xdeadbeef) { - /* it has not been initialized */ - LOG_INFO("received thread request without init task address"); - gdb_put_packet(connection, "l", 1); - return ERROR_OK; - } - - retval = linux_get_tasks(target, 1); - - if (retval != ERROR_OK) - return ERROR_TARGET_FAILURE; - - char *out_str = calloc(1, 350 * sizeof(int64_t)); - char *tmp_str = out_str; - tmp_str += sprintf(tmp_str, "m"); - struct threads *temp = linux_os->thread_list; - - while (temp != NULL) { - tmp_str += sprintf(tmp_str, "%016" PRIx64, temp->threadid); - temp = temp->next; - if (temp) - tmp_str += sprintf(tmp_str, ","); - } - - gdb_put_packet(connection, out_str, strlen(out_str)); - free(out_str); - return ERROR_OK; -} - -int linux_gdb_thread_update(struct target *target, - struct connection *connection, char const *packet, - int packet_size) -{ - int found = 0; - struct linux_os *linux_os = (struct linux_os *) - target->rtos->rtos_specific_params; - struct threads *temp = linux_os->thread_list; - - while (temp != NULL) { - if (temp->threadid == linux_os->preupdtate_threadid_count + 1) { - /*LOG_INFO("FOUND");*/ - found = 1; - break; - } else - temp = temp->next; - } - - if (found == 1) { - /*LOG_INFO("INTO GDB THREAD UPDATE FOUNDING START TASK");*/ - char *out_strr = calloc(1, 350 * sizeof(int64_t)); - char *tmp_strr = out_strr; - tmp_strr += sprintf(tmp_strr, "m"); - /*LOG_INFO("CHAR MALLOC & M DONE");*/ - tmp_strr += sprintf(tmp_strr, "%016" PRIx64, temp->threadid); - - temp = temp->next; - - while (temp != NULL) { - /*LOG_INFO("INTO GDB THREAD UPDATE WHILE");*/ - tmp_strr += sprintf(tmp_strr, ","); - tmp_strr += - sprintf(tmp_strr, "%016" PRIx64, temp->threadid); - temp = temp->next; - } - - /*tmp_str[0] = 0;*/ - gdb_put_packet(connection, out_strr, strlen(out_strr)); - linux_os->preupdtate_threadid_count = - linux_os->threadid_count - 1; - free(out_strr); - } else - gdb_put_packet(connection, "l", 1); - - return ERROR_OK; -} - -int linux_thread_extra_info(struct target *target, - struct connection *connection, char const *packet, - int packet_size) -{ - int64_t threadid = 0; - struct linux_os *linux_os = (struct linux_os *) - target->rtos->rtos_specific_params; - sscanf(packet, "qThreadExtraInfo,%" SCNx64, &threadid); - /*LOG_INFO("lookup extra info for thread %" SCNx64, threadid);*/ - struct threads *temp = linux_os->thread_list; - - while (temp != NULL) { - if (temp->threadid == threadid) { - char *pid = " PID: "; - char *pid_current = "*PID: "; - char *name = "NAME: "; - int str_size = strlen(pid) + strlen(name); - char *tmp_str = calloc(1, str_size + 50); - char *tmp_str_ptr = tmp_str; - - /* discriminate current task */ - if (temp->status == 3) - tmp_str_ptr += sprintf(tmp_str_ptr, "%s", - pid_current); - 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", " | "); - 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); - gdb_put_packet(connection, hex_str, pkt_len); - free(hex_str); - free(tmp_str); - return ERROR_OK; - } - - temp = temp->next; - } - - LOG_INFO("thread not found"); - return ERROR_OK; -} - -int linux_gdb_T_packet(struct connection *connection, - struct target *target, char const *packet, int packet_size) -{ - int64_t threadid; - struct linux_os *linux_os = (struct linux_os *) - target->rtos->rtos_specific_params; - int retval = ERROR_OK; - sscanf(packet, "T%" SCNx64, &threadid); - - if (linux_os->threads_needs_update == 0) { - struct threads *temp = linux_os->thread_list; - struct threads *prev = linux_os->thread_list; - - while (temp != NULL) { - if (temp->threadid == threadid) { - if (temp->status != 0) { - gdb_put_packet(connection, "OK", 2); - return ERROR_OK; - } else { - /* delete item in the list */ - linux_os->thread_list = - liste_del_task(linux_os-> - thread_list, &temp, - prev); - linux_os->thread_count--; - gdb_put_packet(connection, "E01", 3); - return ERROR_OK; - } - } - - /* for deletion */ - prev = temp; - temp = temp->next; - } - - LOG_INFO("gdb requested status on non existing thread"); - gdb_put_packet(connection, "E01", 3); - return ERROR_OK; - - } else { - retval = linux_task_update(target, 1); - struct threads *temp = linux_os->thread_list; - - while (temp != NULL) { - if (temp->threadid == threadid) { - if (temp->status == 1) { - gdb_put_packet(connection, "OK", 2); - return ERROR_OK; - } else { - gdb_put_packet(connection, "E01", 3); - return ERROR_OK; - } - } - - temp = temp->next; - } - } - - return retval; -} - -int linux_gdb_h_packet(struct connection *connection, - struct target *target, char const *packet, int packet_size) -{ - struct linux_os *linux_os = (struct linux_os *) - target->rtos->rtos_specific_params; - struct current_thread *ct = linux_os->current_threads; - - /* select to display the current thread of the selected target */ - while ((ct != NULL) && (ct->core_id != target->coreid)) - ct = ct->next; - - int64_t current_gdb_thread_rq; - - if (linux_os->threads_lookup == 1) { - if ((ct != NULL) && (ct->threadid == -1)) { - ct = linux_os->current_threads; - - while ((ct != NULL) && (ct->threadid == -1)) - ct = ct->next; - } - - if (ct == NULL) { - /* no current thread can be identified - * any way with smp */ - LOG_INFO("no current thread identified"); - /* attempt to display the name of the 2 threads identified with - * get_current */ - struct threads t; - ct = linux_os->current_threads; - - while ((ct != NULL) && (ct->threadid == -1)) { - t.base_addr = ct->TS; - get_name(target, &t); - LOG_INFO("name of unidentified thread %s", - t.name); - ct = ct->next; - } - - gdb_put_packet(connection, "OK", 2); - return ERROR_OK; - } - - if (packet[1] == 'g') { - sscanf(packet, "Hg%16" SCNx64, ¤t_gdb_thread_rq); - - if (current_gdb_thread_rq == 0) { - target->rtos->current_threadid = ct->threadid; - gdb_put_packet(connection, "OK", 2); - } else { - target->rtos->current_threadid = - current_gdb_thread_rq; - gdb_put_packet(connection, "OK", 2); - } - } else if (packet[1] == 'c') { - sscanf(packet, "Hc%16" SCNx64, ¤t_gdb_thread_rq); - - if ((current_gdb_thread_rq == 0) || - (current_gdb_thread_rq == ct->threadid)) { - target->rtos->current_threadid = ct->threadid; - gdb_put_packet(connection, "OK", 2); - } else - gdb_put_packet(connection, "E01", 3); - } - } else - gdb_put_packet(connection, "OK", 2); - - return ERROR_OK; -} - -static int linux_thread_packet(struct connection *connection, char const *packet, - int packet_size) -{ - int retval = ERROR_OK; - struct current_thread *ct; - struct target *target = get_target_from_connection(connection); - struct linux_os *linux_os = (struct linux_os *) - target->rtos->rtos_specific_params; - - switch (packet[0]) { - case 'T': /* Is thread alive?*/ - - linux_gdb_T_packet(connection, target, packet, packet_size); - break; - case 'H': /* Set current thread */ - /* ( 'c' for step and continue, 'g' for all other operations )*/ - /*LOG_INFO(" H packet received '%s'", packet);*/ - linux_gdb_h_packet(connection, target, packet, packet_size); - break; - case 'q': - - if (strncmp(packet, "qSymbol", 7) == 0) { - if (rtos_qsymbol(connection, packet, packet_size) == 1) { - linux_compute_virt2phys(target, - target->rtos-> - symbols[INIT_TASK]. - address); - } - - break; - } else if (strncmp(packet, "qfThreadInfo", 12) == 0) { - if (linux_os->thread_list == NULL) { - retval = linux_gdb_thread_packet(target, - connection, - packet, - packet_size); - break; - } else { - retval = linux_gdb_thread_update(target, - connection, - packet, - packet_size); - break; - } - } else if (strncmp(packet, "qsThreadInfo", 12) == 0) { - gdb_put_packet(connection, "l", 1); - break; - } else if (strncmp(packet, "qThreadExtraInfo,", 17) == 0) { - linux_thread_extra_info(target, connection, packet, - packet_size); - break; - } else { - retval = GDB_THREAD_PACKET_NOT_CONSUMED; - break; - } - - case 'Q': - /* previously response was : thread not found - * gdb_put_packet(connection, "E01", 3); */ - retval = GDB_THREAD_PACKET_NOT_CONSUMED; - break; - case 'c': - case 's': { - if (linux_os->threads_lookup == 1) { - ct = linux_os->current_threads; - - while ((ct != NULL) && (ct->core_id) != target->coreid) - ct = ct->next; - - if ((ct != NULL) && (ct->threadid == -1)) { - ct = linux_os->current_threads; - - while ((ct != NULL) && (ct->threadid == -1)) - ct = ct->next; - } - - if ((ct != NULL) && (ct->threadid != - target->rtos-> - current_threadid) - && (target->rtos->current_threadid != -1)) - LOG_WARNING("WARNING! current GDB thread do not match" \ - "current thread running." \ - "Switch thread in GDB to threadid %d", - (int)ct->threadid); - - LOG_INFO("threads_needs_update = 1"); - linux_os->threads_needs_update = 1; - } - } - - /* if a packet handler returned an error, exit input loop */ - if (retval != ERROR_OK) - return retval; - } - - return retval; -} - -static int linux_os_smp_init(struct target *target) -{ - struct target_list *head; - /* keep only target->rtos */ - struct rtos *rtos = target->rtos; - struct linux_os *os_linux = - (struct linux_os *)rtos->rtos_specific_params; - struct current_thread *ct; - head = target->head; - - while (head != (struct target_list *)NULL) { - if (head->target->rtos != rtos) { - struct linux_os *smp_os_linux = - (struct linux_os *)head->target->rtos-> - rtos_specific_params; - /* remap smp target on rtos */ - free(head->target->rtos); - head->target->rtos = rtos; - /* reuse allocated ct */ - ct = smp_os_linux->current_threads; - ct->threadid = -1; - ct->TS = 0xdeadbeef; - ct->core_id = head->target->coreid; - os_linux->current_threads = - add_current_thread(os_linux->current_threads, ct); - os_linux->nr_cpus++; - free(smp_os_linux); - } - - head = head->next; - } - - return ERROR_OK; -} - -static int linux_os_create(struct target *target) -{ - struct linux_os *os_linux = calloc(1, sizeof(struct linux_os)); - struct current_thread *ct = calloc(1, sizeof(struct current_thread)); - LOG_INFO("linux os creation\n"); - os_linux->init_task_addr = 0xdeadbeef; - os_linux->name = "linux"; - os_linux->thread_list = NULL; - os_linux->thread_count = 0; - target->rtos->current_threadid = -1; - os_linux->nr_cpus = 1; - os_linux->threads_lookup = 0; - os_linux->threads_needs_update = 0; - os_linux->threadid_count = 1; - os_linux->current_threads = NULL; - target->rtos->rtos_specific_params = os_linux; - ct->core_id = target->coreid; - ct->threadid = -1; - ct->TS = 0xdeadbeef; - os_linux->current_threads = - add_current_thread(os_linux->current_threads, ct); - /* overload rtos thread default handler */ - target->rtos->gdb_thread_packet = linux_thread_packet; - /* initialize a default virt 2 phys translation */ - os_linux->phys_mask = ~0xc0000000; - os_linux->phys_base = 0x0; - return JIM_OK; -} - -static char *linux_ps_command(struct target *target) -{ - struct linux_os *linux_os = (struct linux_os *) - target->rtos->rtos_specific_params; - int retval = ERROR_OK; - char *display; - - if (linux_os->threads_lookup == 0) - retval = linux_get_tasks(target, 1); - else { - if (linux_os->threads_needs_update != 0) - retval = linux_task_update(target, 0); - } - - if (retval == ERROR_OK) { - struct threads *temp = linux_os->thread_list; - char *tmp; - LOG_INFO("allocation for %d threads line", - linux_os->thread_count); - display = calloc((linux_os->thread_count + 2) * 80, 1); - - if (!display) - goto error; - - tmp = display; - tmp += sprintf(tmp, "PID\t\tCPU\t\tASID\t\tNAME\n"); - tmp += sprintf(tmp, "---\t\t---\t\t----\t\t----\n"); - - while (temp != NULL) { - if (temp->status) { - if (temp->context) - tmp += - sprintf(tmp, - "%" PRId32 "\t\t%" PRId32 "\t\t%" PRIx32 "\t\t%s\n", - temp->pid, temp->oncpu, - temp->asid, temp->name); - else - tmp += - sprintf(tmp, - "%" PRId32 "\t\t%" PRId32 "\t\t%" PRIx32 "\t\t%s\n", - temp->pid, temp->oncpu, - temp->asid, temp->name); - } - - temp = temp->next; - } - - return display; - } - -error: - display = calloc(40, 1); - sprintf(display, "linux_ps_command failed\n"); - return display; -} diff --git a/src/rtos/linux_header.h b/src/rtos/linux_header.h deleted file mode 100644 index a2b408efd..000000000 --- a/src/rtos/linux_header.h +++ /dev/null @@ -1,37 +0,0 @@ -#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 - kernel symbol must be loaded : symbol vmlinux - -define awareness - set logging off - set logging file linux_header.h - set logging on - - printf "#define QAT %p\n",&((struct task_struct *)(0))->stack - set $a=&((struct list_head *)(0))->next - set $a=(int)$a+(int)&((struct task_struct *)(0))->tasks - printf "#define NEXT %p\n",$a - printf "#define COMM %p\n",&((struct task_struct *)(0))->comm - printf "#define MEM %p\n",&((struct task_struct *)(0))->mm - printf "#define ONCPU %p\n",&((struct task_struct *)(0))->on_cpu - printf "#define PID %p\n",&((struct task_struct *)(0))->pid - printf "#define CPU_CONT %p\n",&((struct thread_info *)(0))->cpu_context - printf "#define PREEMPT %p\n",&((struct thread_info *)(0))->preempt_count - printf "#define MM_CTX %p\n",&((struct mm_struct *)(0))->context - end -*/ -#define QAT 0x4 -#define NEXT 0x1b0 -#define COMM 0x2d4 -#define MEM 0x1cc -#define ONCPU 0x18 -#define PID 0x1f4 -#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 deleted file mode 100644 index b8095a0cf..000000000 --- a/src/rtos/mqx.c +++ /dev/null @@ -1,561 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2014 by Marian Cingel * - * cingel.marian@gmail.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include -#include "target/target.h" -#include "target/target_type.h" -#include "rtos.h" -#include "helper/log.h" -#include "helper/types.h" -#include "rtos_mqx_stackings.h" - -/* constants */ -#define MQX_THREAD_NAME_LENGTH (255) -#define MQX_KERNEL_OFFSET_TDLIST (0x0108) -#define MQX_KERNEL_OFFSET_SYSTEM_TASK (0x0050) -#define MQX_KERNEL_OFFSET_ACTIVE_TASK (0x001C) -#define MQX_KERNEL_OFFSET_CAPABILITY (0x0000) -#define MQX_QUEUE_OFFSET_SIZE (0x0008) -#define MQX_TASK_OFFSET_STATE (0x0008) -#define MQX_TASK_OFFSET_ID (0x000c) -#define MQX_TASK_OFFSET_TEMPLATE (0x0068) -#define MQX_TASK_OFFSET_STACK (0x0014) -#define MQX_TASK_OFFSET_TDLIST (0x006C) -#define MQX_TASK_OFFSET_NEXT (0x0000) -#define MQX_TASK_TEMPLATE_OFFSET_NAME (0x0010) -#define MQX_TASK_OFFSET_ERROR_CODE (0x005C) -#define MQX_TASK_STATE_MASK (0xFFF) - -/* types */ -enum mqx_symbols { - mqx_VAL_mqx_kernel_data, - mqx_VAL_MQX_init_struct, -}; - -enum mqx_arch { - mqx_arch_cortexm, -}; - -struct mqx_params { - const char *target_name; - const enum mqx_arch target_arch; - const struct rtos_register_stacking *stacking_info; -}; - -struct mqx_state { - uint32_t state; - char *name; -}; - -/* local data */ -static const struct mqx_state mqx_states[] = { - { 0x0002, "READY" }, - { 0x0003, "BLOCKED" }, - { 0x0005, "RCV_SPECIFIC_BLOCKED" }, - { 0x0007, "RCV_ANY_BLOCKED" }, - { 0x0009, "DYING" }, - { 0x000B, "UNHANDLED_INT_BLOCKED" }, - { 0x000D, "SEND_BLOCKED" }, - { 0x000F, "BREAKPOINT_BLOCKED" }, - { 0x0211, "IO_BLOCKED" }, - { 0x0021, "SEM_BLOCKED" }, - { 0x0223, "MUTEX_BLOCKED" }, - { 0x0025, "EVENT_BLOCKED" }, - { 0x0229, "TASK_QUEUE_BLOCKED" }, - { 0x042B, "LWSEM_BLOCKED" }, - { 0x042D, "LWEVENT_BLOCKED" }, -}; - -static const char * const mqx_symbol_list[] = { - "_mqx_kernel_data", - "MQX_init_struct", - NULL -}; - -static const struct mqx_params mqx_params_list[] = { - { "cortex_m", mqx_arch_cortexm, &rtos_mqx_arm_v7m_stacking }, -}; - -/* - * Perform simple address check to avoid bus fault. - */ -static int mqx_valid_address_check( - struct rtos *rtos, - uint32_t address -) -{ - 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 */ - if (arch_type == mqx_arch_cortexm) { - if ( - /* code and sram area */ - (address && address <= 0x3FFFFFFFu) || - /* external ram area*/ - (address >= 0x6000000u && address <= 0x9FFFFFFFu) - ) { - return ERROR_OK; - } - return ERROR_FAIL; - } - LOG_ERROR("MQX RTOS - unknown architecture %s", targetname); - return ERROR_FAIL; -} - -/* - * Wrapper of 'target_read_buffer' fn. - * Include address check. - */ -static int mqx_target_read_buffer( - struct target *target, - uint32_t address, - uint32_t size, - uint8_t *buffer -) -{ - int status = mqx_valid_address_check(target->rtos, address); - if (status != ERROR_OK) { - LOG_WARNING("MQX RTOS - target address 0x%" PRIx32 " is not allowed to read", address); - return status; - } - status = target_read_buffer(target, address, size, buffer); - if (status != ERROR_OK) { - LOG_ERROR("MQX RTOS - reading target address 0x%" PRIx32" failed", address); - return status; - } - return ERROR_OK; -} - -/* - * Get symbol address if present - */ -static int mqx_get_symbol( - struct rtos *rtos, - enum mqx_symbols symbol, - void *result -) -{ - /* TODO: additional check ?? */ - (*(int *)result) = (uint32_t)rtos->symbols[symbol].address; - return ERROR_OK; -} - -/* - * Get value of struct member by passing - * member offset, width and name (debug purpose) - */ -static int mqx_get_member( - struct rtos *rtos, - const uint32_t base_address, - int32_t member_offset, - int32_t member_width, - const char *member_name, - void *result -) -{ - int status = ERROR_FAIL; - status = mqx_target_read_buffer( - rtos->target, base_address + member_offset, member_width, result - ); - if (status != ERROR_OK) - LOG_WARNING("MQX RTOS - cannot read \"%s\" at address 0x%" PRIx32, - member_name, (uint32_t)(base_address + member_offset)); - return status; -} - -/* - * Check whether scheduler started - */ -static int mqx_is_scheduler_running( - struct rtos *rtos -) -{ - uint32_t kernel_data_symbol = 0; - uint32_t kernel_data_addr = 0; - uint32_t system_td_addr = 0; - uint32_t active_td_addr = 0; - uint32_t capability_value = 0; - - /* get '_mqx_kernel_data' symbol */ - if (ERROR_OK != mqx_get_symbol( - rtos, mqx_VAL_mqx_kernel_data, &kernel_data_symbol - )) { - return ERROR_FAIL; - } - /* get '_mqx_kernel_data' */ - if (ERROR_OK != mqx_get_member( - rtos, kernel_data_symbol, 0, 4, - "_mqx_kernel_data", &kernel_data_addr - )) { - return ERROR_FAIL; - } - /* return if '_mqx_kernel_data' is NULL or default 0xFFFFFFFF */ - if (0 == kernel_data_addr || (uint32_t)(-1) == kernel_data_addr) - return ERROR_FAIL; - /* get kernel_data->ADDRESSING_CAPABILITY */ - if (ERROR_OK != mqx_get_member( - rtos, kernel_data_addr, MQX_KERNEL_OFFSET_CAPABILITY, 4, - "kernel_data->ADDRESSING_CAPABILITY", (void *)&capability_value - )) { - return ERROR_FAIL; - } - /* check first member, the '_mqx_kernel_data->ADDRESSING_CAPABILITY'. - it supose to be set to value 8 */ - if (capability_value != 8) { - LOG_WARNING("MQX RTOS - value of '_mqx_kernel_data->ADDRESSING_CAPABILITY' contains invalid value"); - return ERROR_FAIL; - } - /* get active ptr */ - if (ERROR_OK != mqx_get_member( - rtos, kernel_data_addr, MQX_KERNEL_OFFSET_ACTIVE_TASK, 4, - "kernel_data->ACTIVE_PTR", (void *)&active_td_addr - )) { - return ERROR_FAIL; - } - /* active task is system task, scheduler has not not run yet */ - system_td_addr = kernel_data_addr + MQX_KERNEL_OFFSET_SYSTEM_TASK; - if (active_td_addr == system_td_addr) { - LOG_WARNING("MQX RTOS - scheduler does not run"); - return ERROR_FAIL; - } - return ERROR_OK; -} - -/* - * API function, return 1 if MQX is present - */ -static int mqx_detect_rtos( - struct target *target -) -{ - if ( - (target->rtos->symbols != NULL) && - (target->rtos->symbols[mqx_VAL_mqx_kernel_data].address != 0) - ) { - return 1; - } - return 0; -} - -/* - * API function, pass MQX extra info to context data - */ -static int mqx_create( - struct target *target -) -{ - /* check target name against supported architectures */ - int mqx_params_list_num = (sizeof(mqx_params_list)/sizeof(struct mqx_params)); - for (int i = 0; i < mqx_params_list_num; i++) { - if (0 == strcmp(mqx_params_list[i].target_name, target->type->name)) { - target->rtos->rtos_specific_params = (void *)&mqx_params_list[i]; - /* LOG_DEBUG("MQX RTOS - valid architecture: %s", target->type->name); */ - return 0; - } - } - LOG_ERROR("MQX RTOS - could not find target \"%s\" in MQX compatibility list", target->type->name); - return -1; -} - -/* - * API function, update list of threads - */ -static int mqx_update_threads( - struct rtos *rtos -) -{ - uint32_t task_queue_addr = 0; - uint32_t kernel_data_addr = 0; - uint16_t task_queue_size = 0; - uint32_t active_td_addr = 0; - - if (!rtos->rtos_specific_params) - return -3; - - if (!rtos->symbols) - return -4; - - /* clear old data */ - rtos_free_threadlist(rtos); - /* check scheduler */ - if (ERROR_OK != mqx_is_scheduler_running(rtos)) - return ERROR_FAIL; - /* get kernel_data symbol */ - if (ERROR_OK != mqx_get_symbol( - rtos, mqx_VAL_mqx_kernel_data, &kernel_data_addr - )) { - return ERROR_FAIL; - } - /* read kernel_data */ - if (ERROR_OK != mqx_get_member( - rtos, kernel_data_addr, 0, 4, "_mqx_kernel_data", &kernel_data_addr - )) { - return ERROR_FAIL; - } - /* get task queue address */ - task_queue_addr = kernel_data_addr + MQX_KERNEL_OFFSET_TDLIST; - /* get task queue size */ - if (ERROR_OK != mqx_get_member( - rtos, task_queue_addr, MQX_QUEUE_OFFSET_SIZE, 2, - "kernel_data->TD_LIST.SIZE", &task_queue_size - )) { - return ERROR_FAIL; - } - /* get active ptr */ - if (ERROR_OK != mqx_get_member( - rtos, kernel_data_addr, MQX_KERNEL_OFFSET_ACTIVE_TASK, 4, - "kernel_data->ACTIVE_PTR", (void *)&active_td_addr - )) { - return ERROR_FAIL; - } - - /* setup threads info */ - rtos->thread_count = task_queue_size; - rtos->current_thread = 0; - rtos->thread_details = calloc(rtos->thread_count, sizeof(struct thread_detail)); - if (NULL == rtos->thread_details) - return ERROR_FAIL; - - /* loop over each task and setup thread details, - the current_taskpool_addr is set to queue head - NOTE: debugging functions task create/destroy - might cause to show invalid data. - */ - for ( - uint32_t i = 0, taskpool_addr = task_queue_addr; - i < (uint32_t)rtos->thread_count; - i++ - ) { - uint8_t task_name[MQX_THREAD_NAME_LENGTH + 1]; - uint32_t task_addr = 0, task_template = 0, task_state = 0; - 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"; - - /* set current taskpool address */ - if (ERROR_OK != mqx_get_member( - rtos, taskpool_addr, MQX_TASK_OFFSET_NEXT, 4, - "td_struct_ptr->NEXT", &taskpool_addr - )) { - return ERROR_FAIL; - } - /* get task address from taskpool */ - task_addr = taskpool_addr - MQX_TASK_OFFSET_TDLIST; - /* get address of 'td_struct_ptr->TEMPLATE_LIST_PTR' */ - if (ERROR_OK != mqx_get_member( - rtos, task_addr, MQX_TASK_OFFSET_TEMPLATE, 4, - "td_struct_ptr->TEMPLATE_LIST_PTR", &task_template - )) { - return ERROR_FAIL; - } - /* get address of 'td_struct_ptr->TEMPLATE_LIST_PTR->NAME' */ - if (ERROR_OK != mqx_get_member( - rtos, task_template, MQX_TASK_TEMPLATE_OFFSET_NAME, 4, - "td_struct_ptr->TEMPLATE_LIST_PTR->NAME", &task_name_addr - )) { - return ERROR_FAIL; - } - /* get value of 'td_struct->TEMPLATE_LIST_PTR->NAME' */ - if (ERROR_OK != mqx_get_member( - rtos, task_name_addr, 0, MQX_THREAD_NAME_LENGTH, - "*td_struct_ptr->TEMPLATE_LIST_PTR->NAME", task_name - )) { - return ERROR_FAIL; - } - /* always terminate last character by force, - otherwise openocd might fail if task_name - has corrupted data */ - task_name[MQX_THREAD_NAME_LENGTH] = '\0'; - /* get value of 'td_struct_ptr->TASK_ID' */ - if (ERROR_OK != mqx_get_member( - rtos, task_addr, MQX_TASK_OFFSET_ID, 4, - "td_struct_ptr->TASK_ID", &task_id - )) { - return ERROR_FAIL; - } - /* get task errno */ - if (ERROR_OK != mqx_get_member( - rtos, task_addr, MQX_TASK_OFFSET_ERROR_CODE, 4, - "td_struct_ptr->TASK_ERROR_CODE", &task_errno - )) { - return ERROR_FAIL; - } - /* get value of 'td_struct_ptr->STATE' */ - if (ERROR_OK != mqx_get_member( - rtos, task_addr, MQX_TASK_OFFSET_STATE, 4, - "td_struct_ptr->STATE", &task_state - )) { - return ERROR_FAIL; - } - task_state &= MQX_TASK_STATE_MASK; - /* and search for defined state */ - state_max = (sizeof(mqx_states)/sizeof(struct mqx_state)); - for (state_index = 0; (state_index < state_max); state_index++) { - if (mqx_states[state_index].state == task_state) { - state_name = mqx_states[state_index].name; - break; - } - } - - /* setup thread details struct */ - rtos->thread_details[i].threadid = task_id; - rtos->thread_details[i].exists = true; - /* 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) - return ERROR_FAIL; - strcpy(rtos->thread_details[i].thread_name_str, (void *)task_name); - /* set thread extra info - * - task state - * - task address - * - task errno - * calculate length as: - * state length + address length + errno length + formatter length - */ - extra_info_length += strlen((void *)state_name) + 8 + 8 + 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 - ); - /* set active thread */ - if (active_td_addr == task_addr) - rtos->current_thread = task_id; - } - return ERROR_OK; -} - -/* - * API function, get info of selected thread - */ -static int mqx_get_thread_reg_list( - struct rtos *rtos, - int64_t thread_id, - char **hex_reg_list -) -{ - int64_t stack_ptr = 0; - uint32_t my_task_addr = 0; - uint32_t task_queue_addr = 0; - uint32_t task_queue_size = 0; - uint32_t kernel_data_addr = 0; - - *hex_reg_list = NULL; - if (thread_id == 0) { - LOG_ERROR("MQX RTOS - invalid threadid: 0x%X", (int)thread_id); - return ERROR_FAIL; - } - if (ERROR_OK != mqx_is_scheduler_running(rtos)) - return ERROR_FAIL; - /* get kernel_data symbol */ - if (ERROR_OK != mqx_get_symbol( - rtos, mqx_VAL_mqx_kernel_data, &kernel_data_addr - )) { - return ERROR_FAIL; - } - /* read kernel_data */ - if (ERROR_OK != mqx_get_member( - rtos, kernel_data_addr, 0, 4, "_mqx_kernel_data", &kernel_data_addr - )) { - return ERROR_FAIL; - } - /* get task queue address */ - task_queue_addr = kernel_data_addr + MQX_KERNEL_OFFSET_TDLIST; - /* get task queue size */ - if (ERROR_OK != mqx_get_member( - rtos, task_queue_addr, MQX_QUEUE_OFFSET_SIZE, 2, - "kernel_data->TD_LIST.SIZE", &task_queue_size - )) { - return ERROR_FAIL; - } - /* search for taskid */ - for ( - uint32_t i = 0, taskpool_addr = task_queue_addr; - i < (uint32_t)rtos->thread_count; - i++ - ) { - uint32_t tmp_address = 0, task_addr = 0; - uint32_t task_id = 0; - /* set current taskpool address */ - tmp_address = taskpool_addr; - if (ERROR_OK != mqx_get_member( - rtos, tmp_address, MQX_TASK_OFFSET_NEXT, 4, - "td_struct_ptr->NEXT", &taskpool_addr - )) { - return ERROR_FAIL; - } - /* get task address from taskpool */ - task_addr = taskpool_addr - MQX_TASK_OFFSET_TDLIST; - /* get value of td_struct->TASK_ID */ - if (ERROR_OK != mqx_get_member( - rtos, task_addr, MQX_TASK_OFFSET_ID, 4, - "td_struct_ptr->TASK_ID", &task_id - )) { - return ERROR_FAIL; - } - /* found taskid, break */ - if (task_id == thread_id) { - my_task_addr = task_addr; - break; - } - } - if (!my_task_addr) { - LOG_ERROR("MQX_RTOS - threadid %" PRId64 " does not match any task", thread_id); - return ERROR_FAIL; - } - /* get task stack head address */ - if (ERROR_OK != mqx_get_member( - rtos, my_task_addr, MQX_TASK_OFFSET_STACK, 4, "task->STACK_PTR", &stack_ptr - )) { - return ERROR_FAIL; - } - return rtos_generic_stack_read( - rtos->target, ((struct mqx_params *)rtos->rtos_specific_params)->stacking_info, stack_ptr, hex_reg_list - ); -} - -/* API function, export list of required symbols */ -static int mqx_get_symbol_list_to_lookup(symbol_table_elem_t *symbol_list[]) -{ - *symbol_list = calloc(ARRAY_SIZE(mqx_symbol_list), sizeof(symbol_table_elem_t)); - if (NULL == *symbol_list) - return ERROR_FAIL; - /* export required symbols */ - for (int i = 0; i < (int)(ARRAY_SIZE(mqx_symbol_list)); i++) - (*symbol_list)[i].symbol_name = mqx_symbol_list[i]; - return ERROR_OK; -} - -struct rtos_type mqx_rtos = { - .name = "mqx", - .detect_rtos = mqx_detect_rtos, - .create = mqx_create, - .update_threads = mqx_update_threads, - .get_thread_reg_list = mqx_get_thread_reg_list, - .get_symbol_list_to_lookup = mqx_get_symbol_list_to_lookup, -}; diff --git a/src/rtos/riscv_debug.c b/src/rtos/riscv_debug.c deleted file mode 100644 index 181d47122..000000000 --- a/src/rtos/riscv_debug.c +++ /dev/null @@ -1,280 +0,0 @@ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "riscv_debug.h" -#include "target/target.h" -#include "target/riscv/riscv.h" -#include "rtos.h" -#include "server/gdb_server.h" - -static int riscv_update_threads(struct rtos *rtos); -static int riscv_gdb_thread_packet(struct connection *connection, const char *packet, int packet_size); - -static int riscv_detect_rtos(struct target *target) -{ - LOG_ERROR("riscv_detect_rtos() unimplemented"); - return -1; -} - -static int riscv_create_rtos(struct target *target) -{ - LOG_DEBUG("RISC-V Debug 'RTOS' created: this doesn't meat you're running an RTOS, just that you have multi-hart support on RISC-V"); - - struct riscv_rtos *r = calloc(1, sizeof(*r)); - target->rtos->rtos_specific_params = r; -#if 0 - r->target_hartid = 0; - r->target_any_hart = true; - r->target_every_hart = true; -#endif - - target->rtos->current_threadid = 1; - target->rtos->current_thread = 1; - riscv_update_threads(target->rtos); - - target->rtos->gdb_thread_packet = riscv_gdb_thread_packet; - - return JIM_OK; -} - -static int riscv_update_threads(struct rtos *rtos) -{ - LOG_DEBUG("Updating the RISC-V Hart List"); - - /* Figures out how many harts there are on the system. */ - int hart_count = riscv_count_harts(rtos->target); - if (rtos->thread_count != hart_count) { - rtos_free_threadlist(rtos); - rtos->thread_count = hart_count; - rtos->thread_details = calloc(rtos->thread_count, sizeof(*rtos->thread_details)); - for (int i = 0; i < rtos->thread_count; ++i) { - LOG_DEBUG(" Setting up Hart %d", i); - rtos->thread_details[i].threadid = i + 1; - rtos->thread_details[i].exists = true; - if (asprintf(&rtos->thread_details[i].thread_name_str, "Hart %d", i) < 0) - LOG_ERROR("riscv_update_threads() failed asprintf"); - if (asprintf(&rtos->thread_details[i].extra_info_str, "RV64") < 0) - LOG_ERROR("riscv_update_threads() failed asprintf"); - } - } - return JIM_OK; -} - -static int riscv_gdb_thread_packet(struct connection *connection, const char *packet, int packet_size) -{ - struct target *target = get_target_from_connection(connection); - struct rtos *rtos = target->rtos; - struct riscv_rtos *r = (struct riscv_rtos *)(target->rtos->rtos_specific_params); - - char *packet_stttrr = malloc(packet_size + 1); - memset(packet_stttrr, '\0', packet_size + 1); - memcpy(packet_stttrr, packet, packet_size); - LOG_DEBUG("riscv_gdb_thread_packet(%s)", packet_stttrr); - - switch (packet[0]) { - case 'q': - if (strncmp(packet, "qfThreadInfo", 12) == 0) { - riscv_update_threads(target->rtos); - r->qs_thread_info_offset = 1; - - char m[16]; - snprintf(m, 16, "m%08x", (int)rtos->thread_details[0].threadid); - gdb_put_packet(connection, m, strlen(m)); - return ERROR_OK; - } - - if (strncmp(packet, "qsThreadInfo", 12) == 0) { - if (r->qs_thread_info_offset >= rtos->thread_count) { - gdb_put_packet(connection, "l", 1); - return ERROR_OK; - } - - int tid = r->qs_thread_info_offset++; - char m[16]; - snprintf(m, 16, "m%08x", (int)rtos->thread_details[tid].threadid); - gdb_put_packet(connection, m, strlen(m)); - return ERROR_OK; - } - - if (strncmp(packet, "qAttached", 9) == 0) { - gdb_put_packet(connection, "1", 1); - return ERROR_OK; - } - - if (strncmp(packet, "qThreadExtraInfo", 16) == 0) { - char tid_str[32]; - memcpy(tid_str, packet + 17, packet_size - 17); - tid_str[packet_size - 17] = '\0'; - char *end; - int tid = strtol(tid_str, &end, 16); - if (*end != '\0') { - LOG_ERROR("Got qThreadExtraInfo with non-numeric TID: '%s'", tid_str); - gdb_put_packet(connection, NULL, 0); - return ERROR_FAIL; - } - - char m[16]; - snprintf(m, 16, "hart %d", tid); - char h[33]; - h[0] = '\0'; - for (size_t i = 0; i < strlen(m); ++i) { - char byte[3]; - snprintf(byte, 3, "%02x", m[i]); - strncat(h, byte, 32); - } - gdb_put_packet(connection, h, strlen(h)); - return ERROR_OK; - } - - return GDB_THREAD_PACKET_NOT_CONSUMED; - - case 'Q': - return GDB_THREAD_PACKET_NOT_CONSUMED; - - case 'H': - /* ‘H op thread-id’ - * - * Set thread for subsequent operations (‘m’, ‘M’, ‘g’, ‘G’, - * et.al.). Depending on the operation to be performed, op - * should be ‘c’ for step and continue operations (note that - * this is deprecated, supporting the ‘vCont’ command is a - * better option), and ‘g’ for other operations. The thread - * designator thread-id has the format and interpretation - * described in thread-id syntax. - * - * Reply: - * ‘OK’ for success - * ‘E NN’ for an error - */ - { - char tid_str[32]; - memcpy(tid_str, packet + 2, packet_size - 2); - tid_str[packet_size - 2] = '\0'; - char *entptr; - int tid = strtol(tid_str, &entptr, 16); - if (*entptr != '\0') { - LOG_ERROR("Got H packet, but without integer: %s", tid_str); - return GDB_THREAD_PACKET_NOT_CONSUMED; - } - - riscv_enable_rtos(target); - switch (tid) { - case 0: - case -1: - riscv_set_all_rtos_harts(target); - break; - default: - riscv_set_rtos_hartid(target, tid - 1); - break; - } - - switch (packet[1]) { - case 'g': - case 'c': - gdb_put_packet(connection, "OK", 2); - return ERROR_OK; - default: - LOG_ERROR("Unknown H packet subtype %2x\n", packet[1]); - gdb_put_packet(connection, NULL, 0); - return ERROR_FAIL; - } - } - - case 'T': - { - char tid_str[32]; - memcpy(tid_str, packet + 1, packet_size - 1); - tid_str[packet_size - 1] = '\0'; - char *end; - int tid = strtol(tid_str, &end, 16); - if (*end != '\0') { - LOG_ERROR("T packet with non-numeric tid %s", tid_str); - gdb_put_packet(connection, NULL, 0); - return ERROR_FAIL; - } - - riscv_enable_rtos(target); - riscv_update_threads(target->rtos); - if (tid <= target->rtos->thread_count) { - gdb_put_packet(connection, "OK", 2); - return ERROR_OK; - } else { - gdb_put_packet(connection, "E00", 3); - return ERROR_OK; - } - } - - - case 'c': - case 's': - target->state = TARGET_HALTED; - return JIM_OK; - - case 'R': - { - char *packet_str = malloc(packet_size + 1); - memset(packet_str, '\0', packet_size + 1); - memcpy(packet_str, packet, packet_size); - LOG_WARNING("riscv_gdb_thread_packet(%s): unimplemented", packet_str); - gdb_put_packet(connection, NULL, 0); - return JIM_OK; - } - default: - LOG_ERROR("Unknown packet of type 0x%2.2x", packet[0]); - gdb_put_packet(connection, NULL, 0); - return JIM_OK; - } -} - -static int riscv_get_thread_reg_list(struct rtos *rtos, int64_t thread_id, char **hex_reg_list) -{ - LOG_DEBUG("Updating RISC-V regiser list for hart %d", (int)(thread_id - 1)); - -#if 0 - LOG_ERROR(" Not actually updating"); - *hex_reg_list = 0; - return JIM_OK; -#endif - - size_t n_regs = 32; - size_t xlen = 64; - size_t reg_chars = xlen / 8 * 2; - - ssize_t hex_reg_list_length = n_regs * reg_chars + 2; - *hex_reg_list = malloc(hex_reg_list_length); - *hex_reg_list[0] = '\0'; - for (size_t i = 0; i < n_regs; ++i) { - if (riscv_has_register(rtos->target, thread_id, i)) { - uint64_t reg_value = riscv_get_register(rtos->target, thread_id - 1, i); - for (size_t byte = 0; byte < xlen / 8; ++byte) { - uint8_t reg_byte = reg_value >> (byte * 8); - char hex[3]; - snprintf(hex, 3, "%02x", reg_byte); - strncat(*hex_reg_list, hex, hex_reg_list_length); - } - } else { - for (size_t byte = 0; byte < xlen / 8; ++byte) - strncat(*hex_reg_list, "xx", hex_reg_list_length); - } - } - return JIM_OK; -} - -static int riscv_get_symbol_list_to_lookup(symbol_table_elem_t *symbol_list[]) -{ - *symbol_list = calloc(1, sizeof(symbol_table_elem_t)); - (*symbol_list)[0].symbol_name = NULL; - (*symbol_list)[0].optional = false; - return JIM_OK; -} - -const struct rtos_type riscv_rtos = -{ - .name = "riscv", - .detect_rtos = riscv_detect_rtos, - .create = riscv_create_rtos, - .update_threads = riscv_update_threads, - .get_thread_reg_list = riscv_get_thread_reg_list, - .get_symbol_list_to_lookup = riscv_get_symbol_list_to_lookup, -}; diff --git a/src/rtos/riscv_debug.h b/src/rtos/riscv_debug.h deleted file mode 100644 index bcc74112b..000000000 --- a/src/rtos/riscv_debug.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef RTOS__RISCV_H -#define RTOS__RISCV_H - -struct riscv_rtos { - /* The index into the thread list used to handle */ - int qs_thread_info_offset; -}; - -#endif diff --git a/src/rtos/rtos.c b/src/rtos/rtos.c deleted file mode 100644 index 76443b6a4..000000000 --- a/src/rtos/rtos.c +++ /dev/null @@ -1,549 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2011 by Broadcom Corporation * - * Evan Hunter - ehunter@broadcom.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "rtos.h" -#include "target/target.h" -#include "helper/log.h" -#include "helper/binarybuffer.h" -#include "server/gdb_server.h" - -/* RTOSs */ -extern struct rtos_type FreeRTOS_rtos; -extern struct rtos_type ThreadX_rtos; -extern struct rtos_type eCos_rtos; -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 riscv_rtos; - -static struct rtos_type *rtos_types[] = { - &ThreadX_rtos, - &FreeRTOS_rtos, - &eCos_rtos, - &Linux_os, - &ChibiOS_rtos, - &embKernel_rtos, - &mqx_rtos, - &riscv_rtos, - NULL -}; - -int rtos_thread_packet(struct connection *connection, const char *packet, int packet_size); - -int rtos_smp_init(struct target *target) -{ - if (target->rtos->type->smp_init) - return target->rtos->type->smp_init(target); - return ERROR_TARGET_INIT_FAILED; -} - -static int os_alloc(struct target *target, struct rtos_type *ostype) -{ - struct rtos *os = target->rtos = calloc(1, sizeof(struct rtos)); - - if (!os) - return JIM_ERR; - - os->type = ostype; - os->current_threadid = -1; - os->current_thread = 0; - os->symbols = NULL; - os->target = target; - - /* RTOS drivers can override the packet handler in _create(). */ - os->gdb_thread_packet = rtos_thread_packet; - - return JIM_OK; -} - -static void os_free(struct target *target) -{ - if (!target->rtos) - return; - - if (target->rtos->symbols) - free(target->rtos->symbols); - - free(target->rtos); - target->rtos = NULL; -} - -static int os_alloc_create(struct target *target, struct rtos_type *ostype) -{ - int ret = os_alloc(target, ostype); - - if (JIM_OK == ret) { - ret = target->rtos->type->create(target); - if (ret != JIM_OK) - os_free(target); - } - - return ret; -} - -int rtos_create(Jim_GetOptInfo *goi, struct target *target) -{ - int x; - const char *cp; - struct Jim_Obj *res; - - if (!goi->isconfigure && goi->argc != 0) { - Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv, "NO PARAMS"); - return JIM_ERR; - } - - os_free(target); - - Jim_GetOpt_String(goi, &cp, NULL); - - if (0 == strcmp(cp, "auto")) { - /* Auto detect tries to look up all symbols for each RTOS, - * and runs the RTOS driver's _detect() function when GDB - * finds all symbols for any RTOS. See rtos_qsymbol(). */ - target->rtos_auto_detect = true; - - /* rtos_qsymbol() will iterate over all RTOSes. Allocate - * target->rtos here, and set it to the first RTOS type. */ - return os_alloc(target, rtos_types[0]); - } - - for (x = 0; rtos_types[x]; x++) - if (0 == strcmp(cp, rtos_types[x]->name)) - return os_alloc_create(target, rtos_types[x]); - - Jim_SetResultFormatted(goi->interp, "Unknown RTOS type %s, try one of: ", cp); - res = Jim_GetResult(goi->interp); - for (x = 0; rtos_types[x]; x++) - Jim_AppendStrings(goi->interp, res, rtos_types[x]->name, ", ", NULL); - Jim_AppendStrings(goi->interp, res, " or auto", NULL); - - return JIM_ERR; -} - -int gdb_thread_packet(struct connection *connection, char const *packet, int packet_size) -{ - struct target *target = get_target_from_connection(connection); - if (target->rtos == NULL) - return rtos_thread_packet(connection, packet, packet_size); /* thread not - *found*/ - return target->rtos->gdb_thread_packet(connection, packet, packet_size); -} - -static symbol_table_elem_t *next_symbol(struct rtos *os, char *cur_symbol, uint64_t cur_addr) -{ - symbol_table_elem_t *s; - - if (!os->symbols) - os->type->get_symbol_list_to_lookup(&os->symbols); - - if (!cur_symbol[0]) - return &os->symbols[0]; - - for (s = os->symbols; s->symbol_name; s++) - if (!strcmp(s->symbol_name, cur_symbol)) { - s->address = cur_addr; - s++; - return s; - } - - return NULL; -} - -/* searches for 'symbol' in the lookup table for 'os' and returns TRUE, - * if 'symbol' is not declared optional */ -static bool is_symbol_mandatory(const struct rtos *os, const char *symbol) -{ - for (symbol_table_elem_t *s = os->symbols; s->symbol_name; ++s) { - if (!strcmp(s->symbol_name, symbol)) - return !s->optional; - } - return false; -} - -/* rtos_qsymbol() processes and replies to all qSymbol packets from GDB. - * - * GDB sends a qSymbol:: packet (empty address, empty name) to notify - * that it can now answer qSymbol::hexcodedname queries, to look up symbols. - * - * If the qSymbol packet has no address that means GDB did not find the - * symbol, in which case auto-detect will move on to try the next RTOS. - * - * rtos_qsymbol() then calls the next_symbol() helper function, which - * iterates over symbol names for the current RTOS until it finds the - * symbol in the received GDB packet, and then returns the next entry - * in the list of symbols. - * - * If GDB replied about the last symbol for the RTOS and the RTOS was - * specified explicitly, then no further symbol lookup is done. When - * auto-detecting, the RTOS driver _detect() function must return success. - * - * rtos_qsymbol() returns 1 if an RTOS has been detected, or 0 otherwise. - */ -int rtos_qsymbol(struct connection *connection, char const *packet, int packet_size) -{ - int rtos_detected = 0; - uint64_t addr = 0; - size_t reply_len; - char reply[GDB_BUFFER_SIZE], cur_sym[GDB_BUFFER_SIZE / 2] = ""; - symbol_table_elem_t *next_sym = NULL; - struct target *target = get_target_from_connection(connection); - struct rtos *os = target->rtos; - - reply_len = sprintf(reply, "OK"); - - if (!os) - goto done; - - /* Decode any symbol name in the packet*/ - int len = unhexify(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 */ - (!sscanf(packet, "qSymbol:%" SCNx64 ":", &addr)) && /* GDB did not find an address for a symbol */ - is_symbol_mandatory(os, cur_sym)) { /* the symbol is mandatory for this RTOS */ - - /* GDB could not find an address for the previous symbol */ - if (!target->rtos_auto_detect) { - LOG_WARNING("RTOS %s not detected. (GDB could not find symbol \'%s\')", os->type->name, cur_sym); - goto done; - } else { - /* Autodetecting RTOS - try next RTOS */ - if (!rtos_try_next(target)) { - LOG_WARNING("No RTOS could be auto-detected!"); - goto done; - } - - /* Next RTOS selected - invalidate current symbol */ - cur_sym[0] = '\x00'; - } - } - next_sym = next_symbol(os, cur_sym, addr); - - if (!next_sym->symbol_name) { - /* No more symbols need looking up */ - - if (!target->rtos_auto_detect) { - rtos_detected = 1; - goto done; - } - - if (os->type->detect_rtos(target)) { - LOG_INFO("Auto-detected RTOS: %s", os->type->name); - rtos_detected = 1; - goto done; - } else { - LOG_WARNING("No RTOS could be auto-detected!"); - goto done; - } - } - - if (8 + (strlen(next_sym->symbol_name) * 2) + 1 > sizeof(reply)) { - LOG_ERROR("ERROR: RTOS symbol '%s' name is too long for GDB!", next_sym->symbol_name); - goto done; - } - - reply_len = snprintf(reply, sizeof(reply), "qSymbol:"); - reply_len += hexify(reply + reply_len, next_sym->symbol_name, 0, sizeof(reply) - reply_len); - -done: - gdb_put_packet(connection, reply, reply_len); - return rtos_detected; -} - -int rtos_thread_packet(struct connection *connection, char const *packet, int packet_size) -{ - struct target *target = get_target_from_connection(connection); - - if (strncmp(packet, "qThreadExtraInfo,", 17) == 0) { - if ((target->rtos != NULL) && (target->rtos->thread_details != NULL) && - (target->rtos->thread_count != 0)) { - threadid_t threadid = 0; - int found = -1; - sscanf(packet, "qThreadExtraInfo,%" SCNx64, &threadid); - - if ((target->rtos != NULL) && (target->rtos->thread_details != NULL)) { - int thread_num; - for (thread_num = 0; thread_num < target->rtos->thread_count; thread_num++) { - if (target->rtos->thread_details[thread_num].threadid == threadid) { - if (target->rtos->thread_details[thread_num].exists) - found = thread_num; - } - } - } - if (found == -1) { - gdb_put_packet(connection, "E01", 3); /* thread not found */ - return ERROR_OK; - } - - struct thread_detail *detail = &target->rtos->thread_details[found]; - - int str_size = 0; - 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 + 4, sizeof(char)); - char *tmp_str_ptr = tmp_str; - - if (detail->thread_name_str != NULL) - tmp_str_ptr += sprintf(tmp_str_ptr, "%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); - } - - 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); - - gdb_put_packet(connection, hex_str, pkt_len); - free(hex_str); - free(tmp_str); - return ERROR_OK; - - } - gdb_put_packet(connection, "", 0); - return ERROR_OK; - } else if (strncmp(packet, "qSymbol", 7) == 0) { - if (rtos_qsymbol(connection, packet, packet_size) == 1) { - target->rtos_auto_detect = false; - target->rtos->type->create(target); - target->rtos->type->update_threads(target->rtos); - } - return ERROR_OK; - } else if (strncmp(packet, "qfThreadInfo", 12) == 0) { - int i; - if (target->rtos != NULL) { - if (target->rtos->thread_count == 0) { - gdb_put_packet(connection, "l", 1); - } else { - /*thread id are 16 char +1 for ',' */ - char *out_str = malloc(17 * target->rtos->thread_count + 1); - char *tmp_str = out_str; - for (i = 0; i < target->rtos->thread_count; i++) { - tmp_str += sprintf(tmp_str, "%c%016" PRIx64, i == 0 ? 'm' : ',', - target->rtos->thread_details[i].threadid); - } - gdb_put_packet(connection, out_str, strlen(out_str)); - free(out_str); - } - } else - gdb_put_packet(connection, "l", 1); - - return ERROR_OK; - } else if (strncmp(packet, "qsThreadInfo", 12) == 0) { - gdb_put_packet(connection, "l", 1); - return ERROR_OK; - } else if (strncmp(packet, "qAttached", 9) == 0) { - gdb_put_packet(connection, "1", 1); - return ERROR_OK; - } else if (strncmp(packet, "qOffsets", 8) == 0) { - char offsets[] = "Text=0;Data=0;Bss=0"; - gdb_put_packet(connection, offsets, sizeof(offsets)-1); - return ERROR_OK; - } else if (strncmp(packet, "qCRC:", 5) == 0) { - /* make sure we check this before "qC" packet below - * otherwise it gets incorrectly handled */ - return GDB_THREAD_PACKET_NOT_CONSUMED; - } else if (strncmp(packet, "qC", 2) == 0) { - if (target->rtos != NULL) { - char buffer[19]; - int size; - size = snprintf(buffer, 19, "QC%016" PRIx64, target->rtos->current_thread); - gdb_put_packet(connection, buffer, size); - } else - gdb_put_packet(connection, "QC0", 3); - return ERROR_OK; - } else if (packet[0] == 'T') { /* Is thread alive? */ - threadid_t threadid; - int found = -1; - sscanf(packet, "T%" SCNx64, &threadid); - if ((target->rtos != NULL) && (target->rtos->thread_details != NULL)) { - int thread_num; - for (thread_num = 0; thread_num < target->rtos->thread_count; thread_num++) { - if (target->rtos->thread_details[thread_num].threadid == threadid) { - if (target->rtos->thread_details[thread_num].exists) - found = thread_num; - } - } - } - if (found != -1) - gdb_put_packet(connection, "OK", 2); /* thread alive */ - else - gdb_put_packet(connection, "E01", 3); /* thread not found */ - return ERROR_OK; - } 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); - } - gdb_put_packet(connection, "OK", 2); - return ERROR_OK; - } - - return GDB_THREAD_PACKET_NOT_CONSUMED; -} - -int rtos_get_gdb_reg_list(struct connection *connection) -{ - struct target *target = get_target_from_connection(connection); - int64_t current_threadid = target->rtos->current_threadid; - if ((target->rtos != NULL) && (current_threadid != -1) && - (current_threadid != 0) && - ((current_threadid != target->rtos->current_thread) || - (target->smp))) { /* in smp several current thread are possible */ - char *hex_reg_list; - - LOG_INFO("RTOS: getting register list for thread 0x%" PRIx64 - ", target->rtos->current_thread=0x%" PRIx64 "\r\n", - current_threadid, - target->rtos->current_thread); - - target->rtos->type->get_thread_reg_list(target->rtos, - current_threadid, - &hex_reg_list); - - if (hex_reg_list != NULL) { - gdb_put_packet(connection, hex_reg_list, strlen(hex_reg_list)); - free(hex_reg_list); - return ERROR_OK; - } - } - return ERROR_FAIL; -} - -int rtos_generic_stack_read(struct target *target, - const struct rtos_register_stacking *stacking, - int64_t stack_ptr, - char **hex_reg_list) -{ - int list_size = 0; - char *tmp_str_ptr; - int64_t new_stack_ptr; - int i; - int retval; - - if (stack_ptr == 0) { - LOG_ERROR("Error: null stack pointer in thread"); - return -5; - } - /* Read the stack */ - uint8_t *stack_data = malloc(stacking->stack_registers_size); - uint32_t address = stack_ptr; - - if (stacking->stack_growth_direction == 1) - address -= stacking->stack_registers_size; - retval = target_read_buffer(target, address, stacking->stack_registers_size, stack_data); - if (retval != ERROR_OK) { - free(stack_data); - LOG_ERROR("Error reading stack frame from thread"); - return retval; - } - LOG_DEBUG("RTOS: Read stack frame at 0x%" PRIx32, address); - -#if 0 - LOG_OUTPUT("Stack Data :"); - for (i = 0; i < stacking->stack_registers_size; i++) - LOG_OUTPUT("%02X", stack_data[i]); - LOG_OUTPUT("\r\n"); -#endif - for (i = 0; i < stacking->num_output_registers; i++) - list_size += stacking->register_offsets[i].width_bits/8; - *hex_reg_list = malloc(list_size*2 + 1); - tmp_str_ptr = *hex_reg_list; - if (stacking->calculate_process_stack != NULL) { - new_stack_ptr = stacking->calculate_process_stack(target, - stack_data, stacking, stack_ptr); - } else { - new_stack_ptr = stack_ptr - stacking->stack_growth_direction * - stacking->stack_registers_size; - } - for (i = 0; i < stacking->num_output_registers; i++) { - int j; - for (j = 0; j < stacking->register_offsets[i].width_bits/8; j++) { - if (stacking->register_offsets[i].offset == -1) - tmp_str_ptr += sprintf(tmp_str_ptr, "%02x", 0); - else if (stacking->register_offsets[i].offset == -2) - tmp_str_ptr += sprintf(tmp_str_ptr, "%02x", - ((uint8_t *)&new_stack_ptr)[j]); - else - tmp_str_ptr += sprintf(tmp_str_ptr, "%02x", - stack_data[stacking->register_offsets[i].offset + j]); - } - } - free(stack_data); -/* LOG_OUTPUT("Output register string: %s\r\n", *hex_reg_list); */ - return ERROR_OK; -} - -int rtos_try_next(struct target *target) -{ - struct rtos *os = target->rtos; - struct rtos_type **type = rtos_types; - - if (!os) - return 0; - - while (*type && os->type != *type) - type++; - - if (!*type || !*(++type)) - return 0; - - os->type = *type; - if (os->symbols) { - free(os->symbols); - os->symbols = NULL; - } - - return 1; -} - -int rtos_update_threads(struct target *target) -{ - if ((target->rtos != NULL) && (target->rtos->type != NULL)) - target->rtos->type->update_threads(target->rtos); - return ERROR_OK; -} - -void rtos_free_threadlist(struct rtos *rtos) -{ - if (rtos->thread_details) { - int j; - - for (j = 0; j < rtos->thread_count; j++) { - struct thread_detail *current_thread = &rtos->thread_details[j]; - free(current_thread->thread_name_str); - free(current_thread->extra_info_str); - } - free(rtos->thread_details); - rtos->thread_details = NULL; - rtos->thread_count = 0; - } -} diff --git a/src/rtos/rtos.h b/src/rtos/rtos.h deleted file mode 100644 index 70c1193e5..000000000 --- a/src/rtos/rtos.h +++ /dev/null @@ -1,111 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2011 by Broadcom Corporation * - * Evan Hunter - ehunter@broadcom.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifndef OPENOCD_RTOS_RTOS_H -#define OPENOCD_RTOS_RTOS_H - -#include "server/server.h" -#include - -typedef int64_t threadid_t; -typedef int64_t symbol_address_t; - -struct reg; - -/** - * Table should be terminated by an element with NULL in symbol_name - */ -typedef struct symbol_table_elem_struct { - const char *symbol_name; - symbol_address_t address; - bool optional; -} symbol_table_elem_t; - -struct thread_detail { - threadid_t threadid; - bool exists; - char *thread_name_str; - char *extra_info_str; -}; - -struct rtos { - const struct rtos_type *type; - - symbol_table_elem_t *symbols; - struct target *target; - /* add a context variable instead of global variable */ - int64_t current_threadid; - threadid_t current_thread; - struct thread_detail *thread_details; - int thread_count; - int (*gdb_thread_packet)(struct connection *connection, char const *packet, int packet_size); - void *rtos_specific_params; -}; - -struct rtos_type { - const char *name; - int (*detect_rtos)(struct target *target); - int (*create)(struct target *target); - int (*smp_init)(struct target *target); - int (*update_threads)(struct rtos *rtos); - int (*get_thread_reg_list)(struct rtos *rtos, int64_t thread_id, char **hex_reg_list); - int (*get_symbol_list_to_lookup)(symbol_table_elem_t *symbol_list[]); - int (*clean)(struct target *target); - char * (*ps_command)(struct target *target); -}; - -struct stack_register_offset { - signed short offset; /* offset in bytes from stack head, or -1 to indicate - * register is not stacked, or -2 to indicate this is the - * stack pointer register */ - unsigned short width_bits; -}; - -struct rtos_register_stacking { - unsigned char stack_registers_size; - signed char stack_growth_direction; - unsigned char num_output_registers; - /* Some targets require evaluating the stack to determine the - * actual stack pointer for a process. If this field is NULL, - * just use stacking->stack_registers_size * stack_growth_direction - * to calculate adjustment. - */ - int64_t (*calculate_process_stack)(struct target *target, - const uint8_t *stack_data, - const struct rtos_register_stacking *stacking, - int64_t stack_ptr); - const struct stack_register_offset *register_offsets; -}; - -#define GDB_THREAD_PACKET_NOT_CONSUMED (-40) - -int rtos_create(Jim_GetOptInfo *goi, struct target *target); -int rtos_generic_stack_read(struct target *target, - const struct rtos_register_stacking *stacking, - int64_t stack_ptr, - char **hex_reg_list); -int rtos_try_next(struct target *target); -int gdb_thread_packet(struct connection *connection, char const *packet, int packet_size); -int rtos_get_gdb_reg_list(struct connection *connection); -int rtos_update_threads(struct target *target); -void rtos_free_threadlist(struct rtos *rtos); -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 /* OPENOCD_RTOS_RTOS_H */ diff --git a/src/rtos/rtos_chibios_stackings.c b/src/rtos/rtos_chibios_stackings.c deleted file mode 100644 index 3651c49a9..000000000 --- a/src/rtos/rtos_chibios_stackings.c +++ /dev/null @@ -1,83 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2012 by Matthias Blaicher * - * Matthias Blaicher - matthias@blaicher.com * - * * - * Copyright (C) 2011 by Broadcom Corporation * - * Evan Hunter - ehunter@broadcom.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "rtos.h" -#include "target/armv7m.h" - -static const struct stack_register_offset rtos_chibios_arm_v7m_stack_offsets[ARMV7M_NUM_CORE_REGS] = { - { -1, 32 }, /* r0 */ - { -1, 32 }, /* r1 */ - { -1, 32 }, /* r2 */ - { -1, 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 */ - { -1, 32 }, /* r12 */ - { -2, 32 }, /* sp */ - { -1, 32 }, /* lr */ - { 0x20, 32 }, /* pc */ - { -1, 32 }, /* xPSR */ -}; - -const struct rtos_register_stacking rtos_chibios_arm_v7m_stacking = { - 0x24, /* stack_registers_size */ - -1, /* stack_growth_direction */ - ARMV7M_NUM_CORE_REGS, /* num_output_registers */ - NULL, /* stack_alignment */ - rtos_chibios_arm_v7m_stack_offsets /* register_offsets */ -}; - -static const struct stack_register_offset rtos_chibios_arm_v7m_stack_offsets_w_fpu[ARMV7M_NUM_CORE_REGS] = { - { -1, 32 }, /* r0 */ - { -1, 32 }, /* r1 */ - { -1, 32 }, /* r2 */ - { -1, 32 }, /* r3 */ - { 0x40, 32 }, /* r4 */ - { 0x44, 32 }, /* r5 */ - { 0x48, 32 }, /* r6 */ - { 0x4c, 32 }, /* r7 */ - { 0x50, 32 }, /* r8 */ - { 0x54, 32 }, /* r9 */ - { 0x58, 32 }, /* r10 */ - { 0x5c, 32 }, /* r11 */ - { -1, 32 }, /* r12 */ - { -2, 32 }, /* sp */ - { -1, 32 }, /* lr */ - { 0x60, 32 }, /* pc */ - { -1, 32 }, /* xPSR */ -}; - -const struct rtos_register_stacking rtos_chibios_arm_v7m_stacking_w_fpu = { - 0x64, /* stack_registers_size */ - -1, /* stack_growth_direction */ - ARMV7M_NUM_CORE_REGS, /* num_output_registers */ - NULL, /* stack_alignment */ - rtos_chibios_arm_v7m_stack_offsets_w_fpu /* register_offsets */ -}; diff --git a/src/rtos/rtos_chibios_stackings.h b/src/rtos/rtos_chibios_stackings.h deleted file mode 100644 index 130aaa18f..000000000 --- a/src/rtos/rtos_chibios_stackings.h +++ /dev/null @@ -1,31 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2011 by Broadcom Corporation * - * Evan Hunter - ehunter@broadcom.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifndef OPENOCD_RTOS_RTOS_CHIBIOS_STACKINGS_H -#define OPENOCD_RTOS_RTOS_CHIBIOS_STACKINGS_H - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "rtos.h" - -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 /* OPENOCD_RTOS_RTOS_CHIBIOS_STACKINGS_H */ diff --git a/src/rtos/rtos_ecos_stackings.c b/src/rtos/rtos_ecos_stackings.c deleted file mode 100644 index 43d97a605..000000000 --- a/src/rtos/rtos_ecos_stackings.c +++ /dev/null @@ -1,51 +0,0 @@ -/*************************************************************************** - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 -#include "config.h" -#endif - -#include "rtos.h" -#include "rtos_standard_stackings.h" -#include "target/armv7m.h" - -static const struct stack_register_offset rtos_eCos_Cortex_M3_stack_offsets[ARMV7M_NUM_CORE_REGS] = { - { 0x0c, 32 }, /* r0 */ - { 0x10, 32 }, /* r1 */ - { 0x14, 32 }, /* r2 */ - { 0x18, 32 }, /* r3 */ - { 0x1c, 32 }, /* r4 */ - { 0x20, 32 }, /* r5 */ - { 0x24, 32 }, /* r6 */ - { 0x28, 32 }, /* r7 */ - { 0x2c, 32 }, /* r8 */ - { 0x30, 32 }, /* r9 */ - { 0x34, 32 }, /* r10 */ - { 0x38, 32 }, /* r11 */ - { 0x3c, 32 }, /* r12 */ - { -2, 32 }, /* sp */ - { -1, 32 }, /* lr */ - { 0x40, 32 }, /* pc */ - { -1, 32 }, /* xPSR */ -}; - -const struct rtos_register_stacking rtos_eCos_Cortex_M3_stacking = { - 0x44, /* stack_registers_size */ - -1, /* stack_growth_direction */ - ARMV7M_NUM_CORE_REGS, /* num_output_registers */ - rtos_generic_stack_align8, /* stack_alignment */ - rtos_eCos_Cortex_M3_stack_offsets /* register_offsets */ -}; diff --git a/src/rtos/rtos_ecos_stackings.h b/src/rtos/rtos_ecos_stackings.h deleted file mode 100644 index 951f7de50..000000000 --- a/src/rtos/rtos_ecos_stackings.h +++ /dev/null @@ -1,28 +0,0 @@ -/*************************************************************************** - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 OPENOCD_RTOS_RTOS_ECOS_STACKINGS_H -#define OPENOCD_RTOS_RTOS_ECOS_STACKINGS_H - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "rtos.h" - -extern const struct rtos_register_stacking rtos_eCos_Cortex_M3_stacking; - -#endif /* OPENOCD_RTOS_RTOS_ECOS_STACKINGS_H */ diff --git a/src/rtos/rtos_embkernel_stackings.c b/src/rtos/rtos_embkernel_stackings.c deleted file mode 100644 index 2a3062955..000000000 --- a/src/rtos/rtos_embkernel_stackings.c +++ /dev/null @@ -1,55 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2011 by Broadcom Corporation * - * Evan Hunter - ehunter@broadcom.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "rtos.h" -#include "target/armv7m.h" -#include "rtos_standard_stackings.h" - -static const struct stack_register_offset rtos_embkernel_Cortex_M_stack_offsets[ARMV7M_NUM_CORE_REGS] = { - { 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 */ -}; - -const struct rtos_register_stacking rtos_embkernel_Cortex_M_stacking = { - 0x40, /* stack_registers_size */ - -1, /* stack_growth_direction */ - ARMV7M_NUM_CORE_REGS, /* num_output_registers */ - rtos_generic_stack_align8, /* stack_alignment */ - rtos_embkernel_Cortex_M_stack_offsets /* register_offsets */ -}; - - diff --git a/src/rtos/rtos_embkernel_stackings.h b/src/rtos/rtos_embkernel_stackings.h deleted file mode 100644 index 89a0c2f12..000000000 --- a/src/rtos/rtos_embkernel_stackings.h +++ /dev/null @@ -1,30 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2011 by Broadcom Corporation * - * Evan Hunter - ehunter@broadcom.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifndef OPENOCD_RTOS_RTOS_EMBKERNEL_STACKINGS_H -#define OPENOCD_RTOS_RTOS_EMBKERNEL_STACKINGS_H - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "rtos.h" - -extern const struct rtos_register_stacking rtos_embkernel_Cortex_M_stacking; - -#endif /* OPENOCD_RTOS_RTOS_EMBKERNEL_STACKINGS_H */ diff --git a/src/rtos/rtos_mqx_stackings.c b/src/rtos/rtos_mqx_stackings.c deleted file mode 100644 index 5db2f8ec3..000000000 --- a/src/rtos/rtos_mqx_stackings.c +++ /dev/null @@ -1,80 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2014 by Marian Cingel * - * cingel.marian@gmail.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "rtos.h" -#include "target/armv7m.h" - - -/* - * standard exception stack - * ( stack base, higher memory address ) - * - xpsr - 0x48 - * - pc - 0x44 - * - lr - 0x40 - * - r12 - 0x3C - * - r3 - 0x38 - * - r2 - 0x34 - * - r1 - 0x30 - * - r0 - 0x2C - * extended stack in svc_pending handler - * - lr - 0x28 - * - r11 - 0x24 - * - r10 - 0x20 - * - r9 - 0x1C - * - r8 - 0x18 - * - r7 - 0x14 - * - r6 - 0x10 - * - r5 - 0x0C - * - r4 - 0x08 - * - BASEPRI - 0x04 - * - SHPR3 - 0x00 ( contains pend_svc exception priority ) - * ( stack head, lower address, stored in 'task->STACK_PTR' ) - */ - -static const struct stack_register_offset rtos_mqx_arm_v7m_stack_offsets[ARMV7M_NUM_CORE_REGS] = { - { 0x2C, 32 }, /* r0 */ - { 0x30, 32 }, /* r1 */ - { 0x34, 32 }, /* r2 */ - { 0x38, 32 }, /* r3 */ - { 0x08, 32 }, /* r4 */ - { 0x0C, 32 }, /* r5 */ - { 0x10, 32 }, /* r6 */ - { 0x14, 32 }, /* r7 */ - { 0x18, 32 }, /* r8 */ - { 0x1C, 32 }, /* r9 */ - { 0x20, 32 }, /* r10 */ - { 0x24, 32 }, /* r11 */ - { 0x3C, 32 }, /* r12 */ - { -2 , 32 }, /* sp */ - { 0x28, 32 }, /* lr */ - { 0x44, 32 }, /* pc */ - { 0x48, 32 }, /* xPSR */ -}; - -const struct rtos_register_stacking rtos_mqx_arm_v7m_stacking = { - 0x4C, /* stack_registers_size, calculate offset base address */ - -1, /* stack_growth_direction */ - ARMV7M_NUM_CORE_REGS, /* num_output_registers */ - NULL, /* stack_alignment */ - rtos_mqx_arm_v7m_stack_offsets /* register_offsets */ -}; - diff --git a/src/rtos/rtos_mqx_stackings.h b/src/rtos/rtos_mqx_stackings.h deleted file mode 100644 index 6ebd28789..000000000 --- a/src/rtos/rtos_mqx_stackings.h +++ /dev/null @@ -1,30 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2014 by Marian Cingel * - * cingel.marian@gmail.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifndef OPENOCD_RTOS_RTOS_MQX_STACKINGS_H -#define OPENOCD_RTOS_RTOS_MQX_STACKINGS_H - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "rtos.h" - -extern const struct rtos_register_stacking rtos_mqx_arm_v7m_stacking; - -#endif /* OPENOCD_RTOS_RTOS_MQX_STACKINGS_H */ diff --git a/src/rtos/rtos_standard_stackings.c b/src/rtos/rtos_standard_stackings.c deleted file mode 100644 index 0176c01ab..000000000 --- a/src/rtos/rtos_standard_stackings.c +++ /dev/null @@ -1,270 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2011 by Broadcom Corporation * - * Evan Hunter - ehunter@broadcom.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "rtos.h" -#include "target/armv7m.h" - -static const struct stack_register_offset rtos_standard_Cortex_M3_stack_offsets[ARMV7M_NUM_CORE_REGS] = { - { 0x20, 32 }, /* r0 */ - { 0x24, 32 }, /* r1 */ - { 0x28, 32 }, /* r2 */ - { 0x2c, 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 */ - { 0x30, 32 }, /* r12 */ - { -2, 32 }, /* sp */ - { 0x34, 32 }, /* lr */ - { 0x38, 32 }, /* pc */ - { 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) */ - { 0x10, 32 }, /* r2 (a3) */ - { 0x14, 32 }, /* r3 (a4) */ - { 0x18, 32 }, /* r4 (v1) */ - { 0x1c, 32 }, /* r5 (v2) */ - { 0x20, 32 }, /* r6 (v3) */ - { 0x24, 32 }, /* r7 (v4) */ - { 0x28, 32 }, /* r8 (a1) */ - { 0x2c, 32 }, /* r9 (sb) */ - { 0x30, 32 }, /* r10 (sl) */ - { 0x34, 32 }, /* r11 (fp) */ - { 0x38, 32 }, /* r12 (ip) */ - { -2, 32 }, /* sp */ - { 0x3c, 32 }, /* lr */ - { 0x40, 32 }, /* pc */ - { -1, 96 }, /* FPA1 */ - { -1, 96 }, /* FPA2 */ - { -1, 96 }, /* FPA3 */ - { -1, 96 }, /* FPA4 */ - { -1, 96 }, /* FPA5 */ - { -1, 96 }, /* FPA6 */ - { -1, 96 }, /* FPA7 */ - { -1, 96 }, /* FPA8 */ - { -1, 32 }, /* FPS */ - { 0x04, 32 }, /* CSPR */ -}; - -static const struct stack_register_offset rtos_standard_NDS32_N1068_stack_offsets[] = { - { 0x88, 32 }, /* R0 */ - { 0x8C, 32 }, /* R1 */ - { 0x14, 32 }, /* R2 */ - { 0x18, 32 }, /* R3 */ - { 0x1C, 32 }, /* R4 */ - { 0x20, 32 }, /* R5 */ - { 0x24, 32 }, /* R6 */ - { 0x28, 32 }, /* R7 */ - { 0x2C, 32 }, /* R8 */ - { 0x30, 32 }, /* R9 */ - { 0x34, 32 }, /* R10 */ - { 0x38, 32 }, /* R11 */ - { 0x3C, 32 }, /* R12 */ - { 0x40, 32 }, /* R13 */ - { 0x44, 32 }, /* R14 */ - { 0x48, 32 }, /* R15 */ - { 0x4C, 32 }, /* R16 */ - { 0x50, 32 }, /* R17 */ - { 0x54, 32 }, /* R18 */ - { 0x58, 32 }, /* R19 */ - { 0x5C, 32 }, /* R20 */ - { 0x60, 32 }, /* R21 */ - { 0x64, 32 }, /* R22 */ - { 0x68, 32 }, /* R23 */ - { 0x6C, 32 }, /* R24 */ - { 0x70, 32 }, /* R25 */ - { 0x74, 32 }, /* R26 */ - { 0x78, 32 }, /* R27 */ - { 0x7C, 32 }, /* R28 */ - { 0x80, 32 }, /* R29 */ - { 0x84, 32 }, /* R30 (LP) */ - { 0x00, 32 }, /* R31 (SP) */ - { 0x04, 32 }, /* PSW */ - { 0x08, 32 }, /* IPC */ - { 0x0C, 32 }, /* IPSW */ - { 0x10, 32 }, /* IFC_LP */ -}; - -static int64_t rtos_generic_stack_align(struct target *target, - const uint8_t *stack_data, const struct rtos_register_stacking *stacking, - int64_t stack_ptr, int align) -{ - int64_t new_stack_ptr; - int64_t aligned_stack_ptr; - new_stack_ptr = stack_ptr - stacking->stack_growth_direction * - stacking->stack_registers_size; - aligned_stack_ptr = new_stack_ptr & ~((int64_t)align - 1); - if (aligned_stack_ptr != new_stack_ptr && - stacking->stack_growth_direction == -1) { - /* If we have a downward growing stack, the simple alignment code - * above results in a wrong result (since it rounds down to nearest - * alignment). We want to round up so add an extra align. - */ - aligned_stack_ptr += (int64_t)align; - } - return aligned_stack_ptr; -} - -int64_t rtos_generic_stack_align8(struct target *target, - const uint8_t *stack_data, const struct rtos_register_stacking *stacking, - int64_t stack_ptr) -{ - return rtos_generic_stack_align(target, stack_data, - stacking, stack_ptr, 8); -} - -/* 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 - * make this a little unclear but the padding takes place before the - * normal exception stacking - so xPSR is always available at a fixed - * location. - * - * Relevant documentation: - * Cortex-M series processors -> Cortex-M3 -> Revision: xxx -> - * Cortex-M3 Devices Generic User Guide -> The Cortex-M3 Processor -> - * Exception Model -> Exception entry and return -> Exception entry - * Cortex-M series processors -> Cortex-M3 -> Revision: xxx -> - * Cortex-M3 Devices Generic User Guide -> Cortex-M3 Peripherals -> - * System control block -> Configuration and Control Register (STKALIGN) - * - * This is just a helper function for use in the calculate_process_stack - * function for a given architecture/rtos. - */ -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) -{ - const uint32_t ALIGN_NEEDED = (1 << 9); - uint32_t xpsr; - int64_t new_stack_ptr; - - new_stack_ptr = stack_ptr - stacking->stack_growth_direction * - stacking->stack_registers_size; - xpsr = (target->endianness == TARGET_LITTLE_ENDIAN) ? - le_to_h_u32(&stack_data[xpsr_offset]) : - be_to_h_u32(&stack_data[xpsr_offset]); - if ((xpsr & ALIGN_NEEDED) != 0) { - LOG_DEBUG("XPSR(0x%08" PRIx32 ") indicated stack alignment was necessary\r\n", - xpsr); - new_stack_ptr -= (stacking->stack_growth_direction * 4); - } - return new_stack_ptr; -} - -static int64_t rtos_standard_Cortex_M3_stack_align(struct target *target, - const uint8_t *stack_data, const struct rtos_register_stacking *stacking, - int64_t stack_ptr) -{ - const int XPSR_OFFSET = 0x3c; - return rtos_Cortex_M_stack_align(target, stack_data, stacking, - stack_ptr, XPSR_OFFSET); -} - -const struct rtos_register_stacking rtos_standard_Cortex_M3_stacking = { - 0x40, /* stack_registers_size */ - -1, /* stack_growth_direction */ - ARMV7M_NUM_CORE_REGS, /* num_output_registers */ - rtos_standard_Cortex_M3_stack_align, /* stack_alignment */ - 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 */ - 26, /* num_output_registers */ - rtos_generic_stack_align8, /* stack_alignment */ - rtos_standard_Cortex_R4_stack_offsets /* register_offsets */ -}; - -const struct rtos_register_stacking rtos_standard_NDS32_N1068_stacking = { - 0x90, /* stack_registers_size */ - -1, /* stack_growth_direction */ - 32, /* num_output_registers */ - rtos_generic_stack_align8, /* stack_alignment */ - rtos_standard_NDS32_N1068_stack_offsets /* register_offsets */ -}; diff --git a/src/rtos/rtos_standard_stackings.h b/src/rtos/rtos_standard_stackings.h deleted file mode 100644 index 6971efd1e..000000000 --- a/src/rtos/rtos_standard_stackings.h +++ /dev/null @@ -1,40 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2011 by Broadcom Corporation * - * Evan Hunter - ehunter@broadcom.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifndef OPENOCD_RTOS_RTOS_STANDARD_STACKINGS_H -#define OPENOCD_RTOS_RTOS_STANDARD_STACKINGS_H - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#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, - const uint8_t *stack_data, const struct rtos_register_stacking *stacking, - int64_t stack_ptr); -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 /* OPENOCD_RTOS_RTOS_STANDARD_STACKINGS_H */ diff --git a/src/server/Makefile.am b/src/server/Makefile.am deleted file mode 100644 index 04d3035f4..000000000 --- a/src/server/Makefile.am +++ /dev/null @@ -1,23 +0,0 @@ -include $(top_srcdir)/common.mk - -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 = -if IS_MINGW -# FD_* macros are sloppy with their signs on MinGW32 platform -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 diff --git a/src/server/gdb_server.c b/src/server/gdb_server.c deleted file mode 100644 index 238749630..000000000 --- a/src/server/gdb_server.c +++ /dev/null @@ -1,3197 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * Copyright (C) 2007-2010 Øyvind Harboe * - * oyvind.harboe@zylin.com * - * * - * Copyright (C) 2008 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * Copyright (C) 2011 by Broadcom Corporation * - * Evan Hunter - ehunter@broadcom.com * - * * - * Copyright (C) ST-Ericsson SA 2011 * - * michel.jaouen@stericsson.com : smp minimum support * - * * - * Copyright (C) 2013 Andes Technology * - * Hsiangkai Wang * - * * - * Copyright (C) 2013 Franck Jullien * - * elec4fun@gmail.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include -#include "server.h" -#include -#include "gdb_server.h" -#include -#include -#include "rtos/rtos.h" -#include "target/smp.h" - -/** - * @file - * GDB server implementation. - * - * This implements the GDB Remote Serial Protocol, over TCP connections, - * giving GDB access to the JTAG or other hardware debugging facilities - * found in most modern embedded processors. - */ - -struct target_desc_format { - char *tdesc; - uint32_t tdesc_length; -}; - -/* private connection data for GDB */ -struct gdb_connection { - char buffer[GDB_BUFFER_SIZE]; - char *buf_p; - int buf_cnt; - int ctrl_c; - enum target_state frontend_state; - struct image *vflash_image; - int closed; - int busy; - int noack_mode; - /* set flag to true if you want the next stepi to return immediately. - * allowing GDB to pick up a fresh set of register values from the target - * without modifying the target state. */ - bool sync; - /* We delay reporting memory write errors until next step/continue or memory - * write. This improves performance of gdb load significantly as the GDB packet - * can be replied immediately and a new GDB packet will be ready without delay - * (ca. 10% or so...). */ - bool mem_write_error; - /* with extended-remote it seems we need to better emulate attach/detach. - * what this means is we reply with a W stop reply after a kill packet, - * normally we reply with a S reply via gdb_last_signal_packet. - * as a side note this behaviour only effects gdb > 6.8 */ - bool attached; - /* temporarily used for target description support */ - struct target_desc_format target_desc; -}; - -#if 0 -#define _DEBUG_GDB_IO_ -#endif - -static struct gdb_connection *current_gdb_connection; - -static int gdb_breakpoint_override; -static enum breakpoint_type gdb_breakpoint_override_type; - -static int gdb_error(struct connection *connection, int retval); -static char *gdb_port; -static char *gdb_port_next; - -static void gdb_log_callback(void *priv, const char *file, unsigned line, - const char *function, const char *string); - -/* number of gdb connections, mainly to suppress gdb related debugging spam - * in helper/log.c when no gdb connections are actually active */ -int gdb_actual_connections; - -/* set if we are sending a memory map to gdb - * via qXfer:memory-map:read packet */ -/* enabled by default*/ -static int gdb_use_memory_map = 1; -/* enabled by default*/ -static int gdb_flash_program = 1; - -/* if set, data aborts cause an error to be reported in memory read packets - * see the code in gdb_read_memory_packet() for further explanations. - * Disabled by default. - */ -static int gdb_report_data_abort; - -/* set if we are sending target descriptions to gdb - * via qXfer:features:read packet */ -/* enabled by default */ -static int gdb_use_target_description = 1; - -/* current processing free-run type, used by file-I/O */ -static char gdb_running_type; - -static int gdb_last_signal(struct target *target) -{ - switch (target->debug_reason) { - case DBG_REASON_DBGRQ: - return 0x2; /* SIGINT */ - case DBG_REASON_BREAKPOINT: - case DBG_REASON_WATCHPOINT: - case DBG_REASON_WPTANDBKPT: - return 0x05; /* SIGTRAP */ - case DBG_REASON_SINGLESTEP: - return 0x05; /* SIGTRAP */ - case DBG_REASON_NOTHALTED: - return 0x0; /* no signal... shouldn't happen */ - default: - LOG_USER("undefined debug reason %d - target needs reset", - target->debug_reason); - return 0x0; - } -} - -static int check_pending(struct connection *connection, - int timeout_s, int *got_data) -{ - /* a non-blocking socket will block if there is 0 bytes available on the socket, - * but return with as many bytes as are available immediately - */ - struct timeval tv; - fd_set read_fds; - struct gdb_connection *gdb_con = connection->priv; - int t; - if (got_data == NULL) - got_data = &t; - *got_data = 0; - - if (gdb_con->buf_cnt > 0) { - *got_data = 1; - return ERROR_OK; - } - - FD_ZERO(&read_fds); - FD_SET(connection->fd, &read_fds); - - tv.tv_sec = timeout_s; - tv.tv_usec = 0; - if (socket_select(connection->fd + 1, &read_fds, NULL, NULL, &tv) == 0) { - /* This can typically be because a "monitor" command took too long - * before printing any progress messages - */ - if (timeout_s > 0) - return ERROR_GDB_TIMEOUT; - else - return ERROR_OK; - } - *got_data = FD_ISSET(connection->fd, &read_fds) != 0; - return ERROR_OK; -} - -static int gdb_get_char_inner(struct connection *connection, int *next_char) -{ - struct gdb_connection *gdb_con = connection->priv; - int retval = ERROR_OK; - -#ifdef _DEBUG_GDB_IO_ - char *debug_buffer; -#endif - for (;; ) { - if (connection->service->type != CONNECTION_TCP) - gdb_con->buf_cnt = read(connection->fd, gdb_con->buffer, GDB_BUFFER_SIZE); - else { - retval = check_pending(connection, 1, NULL); - if (retval != ERROR_OK) - return retval; - gdb_con->buf_cnt = read_socket(connection->fd, - gdb_con->buffer, - GDB_BUFFER_SIZE); - } - - if (gdb_con->buf_cnt > 0) - break; - if (gdb_con->buf_cnt == 0) { - gdb_con->closed = 1; - return ERROR_SERVER_REMOTE_CLOSED; - } - -#ifdef _WIN32 - errno = WSAGetLastError(); - - switch (errno) { - case WSAEWOULDBLOCK: - usleep(1000); - break; - case WSAECONNABORTED: - gdb_con->closed = 1; - return ERROR_SERVER_REMOTE_CLOSED; - case WSAECONNRESET: - gdb_con->closed = 1; - return ERROR_SERVER_REMOTE_CLOSED; - default: - LOG_ERROR("read: %d", errno); - exit(-1); - } -#else - switch (errno) { - case EAGAIN: - usleep(1000); - break; - case ECONNABORTED: - gdb_con->closed = 1; - return ERROR_SERVER_REMOTE_CLOSED; - case ECONNRESET: - gdb_con->closed = 1; - return ERROR_SERVER_REMOTE_CLOSED; - default: - LOG_ERROR("read: %s", strerror(errno)); - gdb_con->closed = 1; - return ERROR_SERVER_REMOTE_CLOSED; - } -#endif - } - -#ifdef _DEBUG_GDB_IO_ - debug_buffer = strndup(gdb_con->buffer, gdb_con->buf_cnt); - LOG_DEBUG("received '%s'", debug_buffer); - free(debug_buffer); -#endif - - gdb_con->buf_p = gdb_con->buffer; - gdb_con->buf_cnt--; - *next_char = *(gdb_con->buf_p++); - if (gdb_con->buf_cnt > 0) - connection->input_pending = 1; - else - connection->input_pending = 0; -#ifdef _DEBUG_GDB_IO_ - LOG_DEBUG("returned char '%c' (0x%2.2x)", *next_char, *next_char); -#endif - - return retval; -} - -/** - * The cool thing about this fn is that it allows buf_p and buf_cnt to be - * held in registers in the inner loop. - * - * For small caches and embedded systems this is important! - */ -static inline int gdb_get_char_fast(struct connection *connection, - int *next_char, char **buf_p, int *buf_cnt) -{ - int retval = ERROR_OK; - - if ((*buf_cnt)-- > 0) { - *next_char = **buf_p; - (*buf_p)++; - if (*buf_cnt > 0) - connection->input_pending = 1; - else - connection->input_pending = 0; - -#ifdef _DEBUG_GDB_IO_ - LOG_DEBUG("returned char '%c' (0x%2.2x)", *next_char, *next_char); -#endif - - return ERROR_OK; - } - - struct gdb_connection *gdb_con = connection->priv; - gdb_con->buf_p = *buf_p; - gdb_con->buf_cnt = *buf_cnt; - retval = gdb_get_char_inner(connection, next_char); - *buf_p = gdb_con->buf_p; - *buf_cnt = gdb_con->buf_cnt; - - return retval; -} - -static int gdb_get_char(struct connection *connection, int *next_char) -{ - struct gdb_connection *gdb_con = connection->priv; - return gdb_get_char_fast(connection, next_char, &gdb_con->buf_p, &gdb_con->buf_cnt); -} - -static int gdb_putback_char(struct connection *connection, int last_char) -{ - struct gdb_connection *gdb_con = connection->priv; - - if (gdb_con->buf_p > gdb_con->buffer) { - *(--gdb_con->buf_p) = last_char; - gdb_con->buf_cnt++; - } else - LOG_ERROR("BUG: couldn't put character back"); - - return ERROR_OK; -} - -/* The only way we can detect that the socket is closed is the first time - * we write to it, we will fail. Subsequent write operations will - * succeed. Shudder! */ -static int gdb_write(struct connection *connection, void *data, int len) -{ - struct gdb_connection *gdb_con = connection->priv; - if (gdb_con->closed) - return ERROR_SERVER_REMOTE_CLOSED; - - if (connection_write(connection, data, len) == len) - return ERROR_OK; - gdb_con->closed = 1; - return ERROR_SERVER_REMOTE_CLOSED; -} - -static int gdb_put_packet_inner(struct connection *connection, - char *buffer, int len) -{ - int i; - unsigned char my_checksum = 0; -#ifdef _DEBUG_GDB_IO_ - char *debug_buffer; -#endif - int reply; - int retval; - struct gdb_connection *gdb_con = connection->priv; - - for (i = 0; i < len; i++) - my_checksum += buffer[i]; - -#ifdef _DEBUG_GDB_IO_ - /* - * At this point we should have nothing in the input queue from GDB, - * however sometimes '-' is sent even though we've already received - * an ACK (+) for everything we've sent off. - */ - int gotdata; - for (;; ) { - retval = check_pending(connection, 0, &gotdata); - if (retval != ERROR_OK) - return retval; - if (!gotdata) - break; - retval = gdb_get_char(connection, &reply); - if (retval != ERROR_OK) - return retval; - if (reply == '$') { - /* fix a problem with some IAR tools */ - gdb_putback_char(connection, reply); - LOG_DEBUG("Unexpected start of new packet"); - break; - } - - LOG_WARNING("Discard unexpected char %c", reply); - } -#endif - - while (1) { -#ifdef _DEBUG_GDB_IO_ - debug_buffer = strndup(buffer, len); - LOG_DEBUG("sending packet '$%s#%2.2x'", debug_buffer, my_checksum); - free(debug_buffer); -#endif - - char local_buffer[1024]; - local_buffer[0] = '$'; - if ((size_t)len + 4 <= sizeof(local_buffer)) { - /* performance gain on smaller packets by only a single call to gdb_write() */ - memcpy(local_buffer + 1, buffer, len++); - len += snprintf(local_buffer + len, sizeof(local_buffer) - len, "#%02x", my_checksum); - retval = gdb_write(connection, local_buffer, len); - if (retval != ERROR_OK) - return retval; - } else { - /* larger packets are transmitted directly from caller supplied buffer - * by several calls to gdb_write() to avoid dynamic allocation */ - snprintf(local_buffer + 1, sizeof(local_buffer) - 1, "#%02x", my_checksum); - retval = gdb_write(connection, local_buffer, 1); - if (retval != ERROR_OK) - return retval; - retval = gdb_write(connection, buffer, len); - if (retval != ERROR_OK) - return retval; - retval = gdb_write(connection, local_buffer + 1, 3); - if (retval != ERROR_OK) - return retval; - } - - if (gdb_con->noack_mode) - break; - - retval = gdb_get_char(connection, &reply); - if (retval != ERROR_OK) - return retval; - - if (reply == '+') - break; - else if (reply == '-') { - /* Stop sending output packets for now */ - log_remove_callback(gdb_log_callback, connection); - LOG_WARNING("negative reply, retrying"); - } else if (reply == 0x3) { - gdb_con->ctrl_c = 1; - retval = gdb_get_char(connection, &reply); - if (retval != ERROR_OK) - return retval; - if (reply == '+') - break; - else if (reply == '-') { - /* Stop sending output packets for now */ - log_remove_callback(gdb_log_callback, connection); - LOG_WARNING("negative reply, retrying"); - } else if (reply == '$') { - LOG_ERROR("GDB missing ack(1) - assumed good"); - gdb_putback_char(connection, reply); - return ERROR_OK; - } else { - LOG_ERROR("unknown character(1) 0x%2.2x in reply, dropping connection", reply); - gdb_con->closed = 1; - return ERROR_SERVER_REMOTE_CLOSED; - } - } else if (reply == '$') { - LOG_ERROR("GDB missing ack(2) - assumed good"); - gdb_putback_char(connection, reply); - return ERROR_OK; - } else { - LOG_ERROR("unknown character(2) 0x%2.2x in reply, dropping connection", - reply); - gdb_con->closed = 1; - return ERROR_SERVER_REMOTE_CLOSED; - } - } - if (gdb_con->closed) - return ERROR_SERVER_REMOTE_CLOSED; - - return ERROR_OK; -} - -int gdb_put_packet(struct connection *connection, char *buffer, int len) -{ - struct gdb_connection *gdb_con = connection->priv; - gdb_con->busy = 1; - int retval = gdb_put_packet_inner(connection, buffer, len); - gdb_con->busy = 0; - - /* we sent some data, reset timer for keep alive messages */ - kept_alive(); - - return retval; -} - -static inline int fetch_packet(struct connection *connection, - int *checksum_ok, int noack, int *len, char *buffer) -{ - unsigned char my_checksum = 0; - char checksum[3]; - int character; - int retval = ERROR_OK; - - struct gdb_connection *gdb_con = connection->priv; - my_checksum = 0; - int count = 0; - count = 0; - - /* move this over into local variables to use registers and give the - * more freedom to optimize */ - char *buf_p = gdb_con->buf_p; - int buf_cnt = gdb_con->buf_cnt; - - for (;; ) { - /* The common case is that we have an entire packet with no escape chars. - * We need to leave at least 2 bytes in the buffer to have - * gdb_get_char() update various bits and bobs correctly. - */ - if ((buf_cnt > 2) && ((buf_cnt + count) < *len)) { - /* The compiler will struggle a bit with constant propagation and - * aliasing, so we help it by showing that these values do not - * change inside the loop - */ - int i; - char *buf = buf_p; - int run = buf_cnt - 2; - i = 0; - int done = 0; - while (i < run) { - character = *buf++; - i++; - if (character == '#') { - /* Danger! character can be '#' when esc is - * used so we need an explicit boolean for done here. */ - done = 1; - break; - } - - if (character == '}') { - /* data transmitted in binary mode (X packet) - * uses 0x7d as escape character */ - my_checksum += character & 0xff; - character = *buf++; - i++; - my_checksum += character & 0xff; - buffer[count++] = (character ^ 0x20) & 0xff; - } else { - my_checksum += character & 0xff; - buffer[count++] = character & 0xff; - } - } - buf_p += i; - buf_cnt -= i; - if (done) - break; - } - if (count > *len) { - LOG_ERROR("packet buffer too small"); - retval = ERROR_GDB_BUFFER_TOO_SMALL; - break; - } - - retval = gdb_get_char_fast(connection, &character, &buf_p, &buf_cnt); - if (retval != ERROR_OK) - break; - - if (character == '#') - break; - - if (character == '}') { - /* data transmitted in binary mode (X packet) - * uses 0x7d as escape character */ - my_checksum += character & 0xff; - - retval = gdb_get_char_fast(connection, &character, &buf_p, &buf_cnt); - if (retval != ERROR_OK) - break; - - my_checksum += character & 0xff; - buffer[count++] = (character ^ 0x20) & 0xff; - } else { - my_checksum += character & 0xff; - buffer[count++] = character & 0xff; - } - } - - gdb_con->buf_p = buf_p; - gdb_con->buf_cnt = buf_cnt; - - if (retval != ERROR_OK) - return retval; - - *len = count; - - retval = gdb_get_char(connection, &character); - if (retval != ERROR_OK) - return retval; - checksum[0] = character; - retval = gdb_get_char(connection, &character); - if (retval != ERROR_OK) - return retval; - checksum[1] = character; - checksum[2] = 0; - - if (!noack) - *checksum_ok = (my_checksum == strtoul(checksum, NULL, 16)); - - return ERROR_OK; -} - -static int gdb_get_packet_inner(struct connection *connection, - char *buffer, int *len) -{ - int character; - int retval; - struct gdb_connection *gdb_con = connection->priv; - - while (1) { - do { - retval = gdb_get_char(connection, &character); - if (retval != ERROR_OK) - return retval; - -#ifdef _DEBUG_GDB_IO_ - LOG_DEBUG("character: '%c'", character); -#endif - - switch (character) { - case '$': - break; - case '+': - /* According to the GDB documentation - * (https://sourceware.org/gdb/onlinedocs/gdb/Packet-Acknowledgment.html): - * "gdb sends a final `+` acknowledgment of the stub's `OK` - * response, which can be safely ignored by the stub." - * However OpenOCD server already is in noack mode at this - * point and instead of ignoring this it was emitting a - * warning. This code makes server ignore the first ACK - * that will be received after going into noack mode, - * warning only about subsequent ACK's. */ - if (gdb_con->noack_mode > 1) { - LOG_WARNING("acknowledgment received, but no packet pending"); - } else if (gdb_con->noack_mode) { - LOG_DEBUG("Received first acknowledgment after entering noack mode. Ignoring it."); - gdb_con->noack_mode = 2; - } - break; - case '-': - LOG_WARNING("negative acknowledgment, but no packet pending"); - break; - case 0x3: - gdb_con->ctrl_c = 1; - *len = 0; - return ERROR_OK; - default: - LOG_WARNING("ignoring character 0x%x", character); - break; - } - } while (character != '$'); - - int checksum_ok = 0; - /* explicit code expansion here to get faster inlined code in -O3 by not - * calculating checksum */ - if (gdb_con->noack_mode) { - retval = fetch_packet(connection, &checksum_ok, 1, len, buffer); - if (retval != ERROR_OK) - return retval; - } else { - retval = fetch_packet(connection, &checksum_ok, 0, len, buffer); - if (retval != ERROR_OK) - return retval; - } - - if (gdb_con->noack_mode) { - /* checksum is not checked in noack mode */ - break; - } - if (checksum_ok) { - retval = gdb_write(connection, "+", 1); - if (retval != ERROR_OK) - return retval; - break; - } - } - if (gdb_con->closed) - return ERROR_SERVER_REMOTE_CLOSED; - - return ERROR_OK; -} - -static int gdb_get_packet(struct connection *connection, char *buffer, int *len) -{ - struct gdb_connection *gdb_con = connection->priv; - gdb_con->busy = 1; - int retval = gdb_get_packet_inner(connection, buffer, len); - gdb_con->busy = 0; - return retval; -} - -static int gdb_output_con(struct connection *connection, const char *line) -{ - char *hex_buffer; - int bin_size; - - bin_size = strlen(line); - - hex_buffer = malloc(bin_size * 2 + 2); - if (hex_buffer == NULL) - return ERROR_GDB_BUFFER_TOO_SMALL; - - hex_buffer[0] = 'O'; - int pkt_len = hexify(hex_buffer + 1, line, bin_size, bin_size * 2 + 1); - int retval = gdb_put_packet(connection, hex_buffer, pkt_len + 1); - - free(hex_buffer); - return retval; -} - -static int gdb_output(struct command_context *context, const char *line) -{ - /* this will be dumped to the log and also sent as an O packet if possible */ - LOG_USER_N("%s", line); - return ERROR_OK; -} - -static void gdb_signal_reply(struct target *target, struct connection *connection) -{ - struct gdb_connection *gdb_connection = connection->priv; - char sig_reply[45]; - char stop_reason[20]; - char current_thread[25]; - int sig_reply_len; - int signal_var; - - rtos_update_threads(target); - - if (target->debug_reason == DBG_REASON_EXIT) { - sig_reply_len = snprintf(sig_reply, sizeof(sig_reply), "W00"); - } else { - if (gdb_connection->ctrl_c) { - signal_var = 0x2; - gdb_connection->ctrl_c = 0; - } else - signal_var = gdb_last_signal(target); - - stop_reason[0] = '\0'; - if (target->debug_reason == DBG_REASON_WATCHPOINT) { - enum watchpoint_rw hit_wp_type; - uint32_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); - break; - case WPT_READ: - snprintf(stop_reason, sizeof(stop_reason), - "rwatch:%08" PRIx32 ";", hit_wp_address); - break; - case WPT_ACCESS: - snprintf(stop_reason, sizeof(stop_reason), - "awatch:%08" PRIx32 ";", hit_wp_address); - break; - default: - break; - } - } - } - - current_thread[0] = '\0'; - if (target->rtos != NULL) { - snprintf(current_thread, sizeof(current_thread), "thread:%016" PRIx64 ";", target->rtos->current_thread); - target->rtos->current_threadid = target->rtos->current_thread; - } - - sig_reply_len = snprintf(sig_reply, sizeof(sig_reply), "T%2.2x%s%s", - signal_var, stop_reason, current_thread); - } - - gdb_put_packet(connection, sig_reply, sig_reply_len); - gdb_connection->frontend_state = TARGET_HALTED; -} - -static void gdb_fileio_reply(struct target *target, struct connection *connection) -{ - struct gdb_connection *gdb_connection = connection->priv; - char fileio_command[256]; - int command_len; - bool program_exited = false; - - if (strcmp(target->fileio_info->identifier, "open") == 0) - sprintf(fileio_command, "F%s,%" PRIx32 "/%" PRIx32 ",%" PRIx32 ",%" PRIx32, target->fileio_info->identifier, - target->fileio_info->param_1, - target->fileio_info->param_2, - target->fileio_info->param_3, - target->fileio_info->param_4); - else if (strcmp(target->fileio_info->identifier, "close") == 0) - sprintf(fileio_command, "F%s,%" PRIx32, target->fileio_info->identifier, - target->fileio_info->param_1); - else if (strcmp(target->fileio_info->identifier, "read") == 0) - sprintf(fileio_command, "F%s,%" PRIx32 ",%" PRIx32 ",%" PRIx32, target->fileio_info->identifier, - target->fileio_info->param_1, - target->fileio_info->param_2, - target->fileio_info->param_3); - else if (strcmp(target->fileio_info->identifier, "write") == 0) - sprintf(fileio_command, "F%s,%" PRIx32 ",%" PRIx32 ",%" PRIx32, target->fileio_info->identifier, - target->fileio_info->param_1, - target->fileio_info->param_2, - target->fileio_info->param_3); - else if (strcmp(target->fileio_info->identifier, "lseek") == 0) - sprintf(fileio_command, "F%s,%" PRIx32 ",%" PRIx32 ",%" PRIx32, target->fileio_info->identifier, - target->fileio_info->param_1, - target->fileio_info->param_2, - target->fileio_info->param_3); - else if (strcmp(target->fileio_info->identifier, "rename") == 0) - sprintf(fileio_command, "F%s,%" PRIx32 "/%" PRIx32 ",%" PRIx32 "/%" PRIx32, target->fileio_info->identifier, - target->fileio_info->param_1, - target->fileio_info->param_2, - target->fileio_info->param_3, - target->fileio_info->param_4); - else if (strcmp(target->fileio_info->identifier, "unlink") == 0) - sprintf(fileio_command, "F%s,%" PRIx32 "/%" PRIx32, target->fileio_info->identifier, - target->fileio_info->param_1, - target->fileio_info->param_2); - else if (strcmp(target->fileio_info->identifier, "stat") == 0) - sprintf(fileio_command, "F%s,%" PRIx32 "/%" PRIx32 ",%" PRIx32, target->fileio_info->identifier, - target->fileio_info->param_1, - target->fileio_info->param_2, - target->fileio_info->param_3); - else if (strcmp(target->fileio_info->identifier, "fstat") == 0) - sprintf(fileio_command, "F%s,%" PRIx32 ",%" PRIx32, target->fileio_info->identifier, - target->fileio_info->param_1, - target->fileio_info->param_2); - else if (strcmp(target->fileio_info->identifier, "gettimeofday") == 0) - sprintf(fileio_command, "F%s,%" PRIx32 ",%" PRIx32, target->fileio_info->identifier, - target->fileio_info->param_1, - target->fileio_info->param_2); - else if (strcmp(target->fileio_info->identifier, "isatty") == 0) - sprintf(fileio_command, "F%s,%" PRIx32, target->fileio_info->identifier, - target->fileio_info->param_1); - else if (strcmp(target->fileio_info->identifier, "system") == 0) - sprintf(fileio_command, "F%s,%" PRIx32 "/%" PRIx32, target->fileio_info->identifier, - target->fileio_info->param_1, - target->fileio_info->param_2); - else if (strcmp(target->fileio_info->identifier, "exit") == 0) { - /* If target hits exit syscall, report to GDB the program is terminated. - * In addition, let target run its own exit syscall handler. */ - program_exited = true; - sprintf(fileio_command, "W%02" PRIx32, target->fileio_info->param_1); - } else { - LOG_DEBUG("Unknown syscall: %s", target->fileio_info->identifier); - - /* encounter unknown syscall, continue */ - gdb_connection->frontend_state = TARGET_RUNNING; - target_resume(target, 1, 0x0, 0, 0); - return; - } - - command_len = strlen(fileio_command); - gdb_put_packet(connection, fileio_command, command_len); - - if (program_exited) { - /* Use target_resume() to let target run its own exit syscall handler. */ - gdb_connection->frontend_state = TARGET_RUNNING; - target_resume(target, 1, 0x0, 0, 0); - } else { - gdb_connection->frontend_state = TARGET_HALTED; - rtos_update_threads(target); - } -} - -static void gdb_frontend_halted(struct target *target, struct connection *connection) -{ - struct gdb_connection *gdb_connection = connection->priv; - - /* In the GDB protocol when we are stepping or continuing execution, - * we have a lingering reply. Upon receiving a halted event - * when we have that lingering packet, we reply to the original - * step or continue packet. - * - * Executing monitor commands can bring the target in and - * out of the running state so we'll see lots of TARGET_EVENT_XXX - * that are to be ignored. - */ - if (gdb_connection->frontend_state == TARGET_RUNNING) { - /* stop forwarding log packets! */ - log_remove_callback(gdb_log_callback, connection); - - /* check fileio first */ - if (target_get_gdb_fileio_info(target, target->fileio_info) == ERROR_OK) - gdb_fileio_reply(target, connection); - else - gdb_signal_reply(target, connection); - } -} - -static int gdb_target_callback_event_handler(struct target *target, - enum target_event event, void *priv) -{ - int retval; - struct connection *connection = priv; - struct gdb_service *gdb_service = connection->service->priv; - - if (gdb_service->target != target) - return ERROR_OK; - - switch (event) { - case TARGET_EVENT_GDB_HALT: - gdb_frontend_halted(target, connection); - break; - case TARGET_EVENT_HALTED: - target_call_event_callbacks(target, TARGET_EVENT_GDB_END); - break; - case TARGET_EVENT_GDB_FLASH_ERASE_START: - retval = jtag_execute_queue(); - if (retval != ERROR_OK) - return retval; - break; - default: - break; - } - - return ERROR_OK; -} - -static int gdb_new_connection(struct connection *connection) -{ - struct gdb_connection *gdb_connection = malloc(sizeof(struct gdb_connection)); - struct gdb_service *gdb_service = connection->service->priv; - int retval; - int initial_ack; - - connection->priv = gdb_connection; - - /* initialize gdb connection information */ - gdb_connection->buf_p = gdb_connection->buffer; - gdb_connection->buf_cnt = 0; - gdb_connection->ctrl_c = 0; - gdb_connection->frontend_state = TARGET_HALTED; - gdb_connection->vflash_image = NULL; - gdb_connection->closed = 0; - gdb_connection->busy = 0; - gdb_connection->noack_mode = 0; - gdb_connection->sync = false; - gdb_connection->mem_write_error = false; - gdb_connection->attached = true; - gdb_connection->target_desc.tdesc = NULL; - gdb_connection->target_desc.tdesc_length = 0; - - /* send ACK to GDB for debug request */ - gdb_write(connection, "+", 1); - - /* output goes through gdb connection */ - command_set_output_handler(connection->cmd_ctx, gdb_output, connection); - - /* we must remove all breakpoints registered to the target as a previous - * GDB session could leave dangling breakpoints if e.g. communication - * timed out. - */ - breakpoint_clear_target(gdb_service->target); - watchpoint_clear_target(gdb_service->target); - - /* clean previous rtos session if supported*/ - if ((gdb_service->target->rtos) && (gdb_service->target->rtos->type->clean)) - gdb_service->target->rtos->type->clean(gdb_service->target); - - /* remove the initial ACK from the incoming buffer */ - retval = gdb_get_char(connection, &initial_ack); - if (retval != ERROR_OK) - return retval; - - /* FIX!!!??? would we actually ever receive a + here??? - * Not observed. - */ - if (initial_ack != '+') - gdb_putback_char(connection, initial_ack); - target_call_event_callbacks(gdb_service->target, TARGET_EVENT_GDB_ATTACH); - - if (gdb_use_memory_map) { - /* Connect must fail if the memory map can't be set up correctly. - * - * This will cause an auto_probe to be invoked, which is either - * a no-op or it will fail when the target isn't ready(e.g. not halted). - */ - int i; - for (i = 0; i < flash_get_bank_count(); i++) { - struct flash_bank *p; - p = get_flash_bank_by_num_noprobe(i); - if (p->target != gdb_service->target) - continue; - retval = get_flash_bank_by_num(i, &p); - if (retval != ERROR_OK) { - LOG_ERROR("Connect failed. Consider setting up a gdb-attach event for the target " \ - "to prepare target for GDB connect, or use 'gdb_memory_map disable'."); - return retval; - } - } - } - - gdb_actual_connections++; - LOG_DEBUG("New GDB Connection: %d, Target %s, state: %s", - gdb_actual_connections, - target_name(gdb_service->target), - target_state_name(gdb_service->target)); - - /* DANGER! If we fail subsequently, we must remove this handler, - * otherwise we occasionally see crashes as the timer can invoke the - * callback fn. - * - * register callback to be informed about target events */ - target_register_event_callback(gdb_target_callback_event_handler, connection); - - return ERROR_OK; -} - -static int gdb_connection_closed(struct connection *connection) -{ - struct gdb_service *gdb_service = connection->service->priv; - struct gdb_connection *gdb_connection = connection->priv; - - /* we're done forwarding messages. Tear down callback before - * cleaning up connection. - */ - log_remove_callback(gdb_log_callback, connection); - - gdb_actual_connections--; - LOG_DEBUG("GDB Close, Target: %s, state: %s, gdb_actual_connections=%d", - target_name(gdb_service->target), - target_state_name(gdb_service->target), - gdb_actual_connections); - - /* see if an image built with vFlash commands is left */ - if (gdb_connection->vflash_image) { - image_close(gdb_connection->vflash_image); - free(gdb_connection->vflash_image); - gdb_connection->vflash_image = NULL; - } - - /* if this connection registered a debug-message receiver delete it */ - delete_debug_msg_receiver(connection->cmd_ctx, gdb_service->target); - - if (connection->priv) { - free(connection->priv); - connection->priv = NULL; - } else - LOG_ERROR("BUG: connection->priv == NULL"); - - target_unregister_event_callback(gdb_target_callback_event_handler, connection); - - target_call_event_callbacks(gdb_service->target, TARGET_EVENT_GDB_END); - - target_call_event_callbacks(gdb_service->target, TARGET_EVENT_GDB_DETACH); - - return ERROR_OK; -} - -static void gdb_send_error(struct connection *connection, uint8_t the_error) -{ - char err[4]; - snprintf(err, 4, "E%2.2X", the_error); - gdb_put_packet(connection, err, 3); -} - -static int gdb_last_signal_packet(struct connection *connection, - char const *packet, int packet_size) -{ - struct target *target = get_target_from_connection(connection); - struct gdb_connection *gdb_con = connection->priv; - char sig_reply[4]; - int signal_var; - - if (!gdb_con->attached) { - /* if we are here we have received a kill packet - * reply W stop reply otherwise gdb gets very unhappy */ - gdb_put_packet(connection, "W00", 3); - return ERROR_OK; - } - - signal_var = gdb_last_signal(target); - - snprintf(sig_reply, 4, "S%2.2x", signal_var); - gdb_put_packet(connection, sig_reply, 3); - - return ERROR_OK; -} - -static inline int gdb_reg_pos(struct target *target, int pos, int len) -{ - if (target->endianness == TARGET_LITTLE_ENDIAN) - return pos; - else - return len - 1 - pos; -} - -/* Convert register to string of bytes. NB! The # of bits in the - * register might be non-divisible by 8(a byte), in which - * case an entire byte is shown. - * - * NB! the format on the wire is the target endianness - * - * The format of reg->value is little endian - * - */ -static void gdb_str_to_target(struct target *target, - char *tstr, struct reg *reg) -{ - int i; - - uint8_t *buf; - int buf_len; - buf = reg->value; - buf_len = DIV_ROUND_UP(reg->size, 8); - - for (i = 0; i < buf_len; i++) { - int j = gdb_reg_pos(target, i, buf_len); - tstr += sprintf(tstr, "%02x", buf[j]); - } -} - -/* copy over in register buffer */ -static void gdb_target_to_reg(struct target *target, - char const *tstr, int str_len, uint8_t *bin) -{ - if (str_len % 2) { - LOG_ERROR("BUG: gdb value with uneven number of characters encountered"); - exit(-1); - } - - int i; - for (i = 0; i < str_len; i += 2) { - unsigned t; - if (sscanf(tstr + i, "%02x", &t) != 1) { - LOG_ERROR("BUG: unable to convert register value"); - exit(-1); - } - - int j = gdb_reg_pos(target, i/2, str_len/2); - bin[j] = t; - } -} - -static int gdb_get_registers_packet(struct connection *connection, - char const *packet, int packet_size) -{ - struct target *target = get_target_from_connection(connection); - struct reg **reg_list; - int reg_list_size; - int retval; - int reg_packet_size = 0; - char *reg_packet; - char *reg_packet_p; - int i; - -#ifdef _DEBUG_GDB_IO_ - LOG_DEBUG("-"); -#endif - - if ((target->rtos != NULL) && (ERROR_OK == rtos_get_gdb_reg_list(connection))) - return ERROR_OK; - - retval = target_get_gdb_reg_list(target, ®_list, ®_list_size, - REG_CLASS_GENERAL); - if (retval != ERROR_OK) - return gdb_error(connection, retval); - - for (i = 0; i < reg_list_size; i++) - reg_packet_size += DIV_ROUND_UP(reg_list[i]->size, 8) * 2; - - assert(reg_packet_size > 0); - - reg_packet = malloc(reg_packet_size + 1); /* plus one for string termination null */ - if (reg_packet == NULL) - return ERROR_FAIL; - - reg_packet_p = reg_packet; - - for (i = 0; i < reg_list_size; i++) { - 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); - } - } - gdb_str_to_target(target, reg_packet_p, reg_list[i]); - reg_packet_p += DIV_ROUND_UP(reg_list[i]->size, 8) * 2; - } - -#ifdef _DEBUG_GDB_IO_ - { - char *reg_packet_p_debug; - reg_packet_p_debug = strndup(reg_packet, reg_packet_size); - LOG_DEBUG("reg_packet: %s", reg_packet_p_debug); - free(reg_packet_p_debug); - } -#endif - - gdb_put_packet(connection, reg_packet, reg_packet_size); - free(reg_packet); - - free(reg_list); - - return ERROR_OK; -} - -static int gdb_set_registers_packet(struct connection *connection, - char const *packet, int packet_size) -{ - struct target *target = get_target_from_connection(connection); - int i; - struct reg **reg_list; - int reg_list_size; - int retval; - char const *packet_p; - -#ifdef _DEBUG_GDB_IO_ - LOG_DEBUG("-"); -#endif - - /* skip command character */ - packet++; - packet_size--; - - if (packet_size % 2) { - LOG_WARNING("GDB set_registers packet with uneven characters received, dropping connection"); - return ERROR_SERVER_REMOTE_CLOSED; - } - - retval = target_get_gdb_reg_list(target, ®_list, ®_list_size, - REG_CLASS_GENERAL); - if (retval != ERROR_OK) - return gdb_error(connection, retval); - - packet_p = packet; - for (i = 0; i < reg_list_size; i++) { - uint8_t *bin_buf; - int chars = (DIV_ROUND_UP(reg_list[i]->size, 8) * 2); - - if (packet_p + chars > packet + packet_size) - LOG_ERROR("BUG: register packet is too small for registers"); - - bin_buf = malloc(DIV_ROUND_UP(reg_list[i]->size, 8)); - gdb_target_to_reg(target, packet_p, chars, bin_buf); - - 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); - } - - /* advance packet pointer */ - packet_p += chars; - - free(bin_buf); - } - - /* free struct reg *reg_list[] array allocated by get_gdb_reg_list */ - free(reg_list); - - gdb_put_packet(connection, "OK", 2); - - return ERROR_OK; -} - -static int gdb_get_register_packet(struct connection *connection, - char const *packet, int packet_size) -{ - struct target *target = get_target_from_connection(connection); - char *reg_packet; - int reg_num = strtoul(packet + 1, NULL, 16); - struct reg **reg_list; - int reg_list_size; - int retval; - -#ifdef _DEBUG_GDB_IO_ - LOG_DEBUG("-"); -#endif - - retval = target_get_gdb_reg_list(target, ®_list, ®_list_size, - REG_CLASS_ALL); - if (retval != ERROR_OK) - return gdb_error(connection, retval); - - if (reg_list_size <= reg_num) { - LOG_ERROR("gdb requested a non-existing register"); - return ERROR_SERVER_REMOTE_CLOSED; - } - - 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); - } - } - - reg_packet = malloc(DIV_ROUND_UP(reg_list[reg_num]->size, 8) * 2 + 1); /* plus one for string termination null */ - - gdb_str_to_target(target, reg_packet, reg_list[reg_num]); - - gdb_put_packet(connection, reg_packet, DIV_ROUND_UP(reg_list[reg_num]->size, 8) * 2); - - free(reg_list); - free(reg_packet); - - return ERROR_OK; -} - -static int gdb_set_register_packet(struct connection *connection, - char const *packet, int packet_size) -{ - struct target *target = get_target_from_connection(connection); - char *separator; - uint8_t *bin_buf; - int reg_num = strtoul(packet + 1, &separator, 16); - struct reg **reg_list; - int reg_list_size; - int retval; - - LOG_DEBUG("-"); - - retval = target_get_gdb_reg_list(target, ®_list, ®_list_size, - REG_CLASS_ALL); - if (retval != ERROR_OK) - return gdb_error(connection, retval); - - if (reg_list_size <= reg_num) { - LOG_ERROR("gdb requested a non-existing register"); - return ERROR_SERVER_REMOTE_CLOSED; - } - - if (*separator != '=') { - LOG_ERROR("GDB 'set register packet', but no '=' following the register number"); - return ERROR_SERVER_REMOTE_CLOSED; - } - - /* convert from GDB-string (target-endian) to hex-string (big-endian) */ - bin_buf = malloc(DIV_ROUND_UP(reg_list[reg_num]->size, 8)); - int chars = (DIV_ROUND_UP(reg_list[reg_num]->size, 8) * 2); - - if ((unsigned int)chars != strlen(separator + 1)) { - LOG_ERROR("gdb sent a packet with wrong register size"); - free(bin_buf); - return ERROR_SERVER_REMOTE_CLOSED; - } - - gdb_target_to_reg(target, separator + 1, chars, bin_buf); - - 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); - } - - gdb_put_packet(connection, "OK", 2); - - free(bin_buf); - free(reg_list); - - return ERROR_OK; -} - -/* No attempt is made to translate the "retval" to - * GDB speak. This has to be done at the calling - * site as no mapping really exists. - */ -static int gdb_error(struct connection *connection, int retval) -{ - LOG_DEBUG("Reporting %i to GDB as generic error", retval); - gdb_send_error(connection, EFAULT); - return ERROR_OK; -} - -/* We don't have to worry about the default 2 second timeout for GDB packets, - * because GDB breaks up large memory reads into smaller reads. - * - * 8191 bytes by the looks of it. Why 8191 bytes instead of 8192????? - */ -static int gdb_read_memory_packet(struct connection *connection, - char const *packet, int packet_size) -{ - struct target *target = get_target_from_connection(connection); - char *separator; - uint32_t addr = 0; - uint32_t len = 0; - - uint8_t *buffer; - char *hex_buffer; - - int retval = ERROR_OK; - - /* skip command character */ - packet++; - - addr = strtoul(packet, &separator, 16); - - if (*separator != ',') { - LOG_ERROR("incomplete read memory packet received, dropping connection"); - return ERROR_SERVER_REMOTE_CLOSED; - } - - len = strtoul(separator + 1, NULL, 16); - - if (!len) { - LOG_WARNING("invalid read memory packet received (len == 0)"); - gdb_put_packet(connection, NULL, 0); - return ERROR_OK; - } - - buffer = malloc(len); - - LOG_DEBUG("addr: 0x%8.8" PRIx32 ", len: 0x%8.8" PRIx32 "", addr, len); - - retval = target_read_buffer(target, addr, len, buffer); - - if ((retval != ERROR_OK) && !gdb_report_data_abort) { - /* TODO : Here we have to lie and send back all zero's lest stack traces won't work. - * At some point this might be fixed in GDB, in which case this code can be removed. - * - * OpenOCD developers are acutely aware of this problem, but there is nothing - * gained by involving the user in this problem that hopefully will get resolved - * eventually - * - * http://sourceware.org/cgi-bin/gnatsweb.pl? \ - * cmd = view%20audit-trail&database = gdb&pr = 2395 - * - * For now, the default is to fix up things to make current GDB versions work. - * This can be overwritten using the gdb_report_data_abort <'enable'|'disable'> command. - */ - memset(buffer, 0, len); - retval = ERROR_OK; - } - - if (retval == ERROR_OK) { - hex_buffer = malloc(len * 2 + 1); - - int pkt_len = hexify(hex_buffer, (char *)buffer, len, len * 2 + 1); - - gdb_put_packet(connection, hex_buffer, pkt_len); - - free(hex_buffer); - } else - retval = gdb_error(connection, retval); - - free(buffer); - - return retval; -} - -static int gdb_write_memory_packet(struct connection *connection, - char const *packet, int packet_size) -{ - struct target *target = get_target_from_connection(connection); - char *separator; - uint32_t addr = 0; - uint32_t len = 0; - - uint8_t *buffer; - int retval; - - /* skip command character */ - packet++; - - addr = strtoul(packet, &separator, 16); - - if (*separator != ',') { - LOG_ERROR("incomplete write memory packet received, dropping connection"); - return ERROR_SERVER_REMOTE_CLOSED; - } - - len = strtoul(separator + 1, &separator, 16); - - if (*(separator++) != ':') { - LOG_ERROR("incomplete write memory packet received, dropping connection"); - return ERROR_SERVER_REMOTE_CLOSED; - } - - buffer = malloc(len); - - LOG_DEBUG("addr: 0x%8.8" PRIx32 ", len: 0x%8.8" PRIx32 "", addr, len); - - if (unhexify((char *)buffer, separator, len) != (int)len) - LOG_ERROR("unable to decode memory packet"); - - retval = target_write_buffer(target, addr, len, buffer); - - if (retval == ERROR_OK) - gdb_put_packet(connection, "OK", 2); - else - retval = gdb_error(connection, retval); - - free(buffer); - - return retval; -} - -static int gdb_write_memory_binary_packet(struct connection *connection, - char const *packet, int packet_size) -{ - struct target *target = get_target_from_connection(connection); - char *separator; - uint32_t addr = 0; - uint32_t len = 0; - - int retval = ERROR_OK; - - /* skip command character */ - packet++; - - addr = strtoul(packet, &separator, 16); - - if (*separator != ',') { - LOG_ERROR("incomplete write memory binary packet received, dropping connection"); - return ERROR_SERVER_REMOTE_CLOSED; - } - - len = strtoul(separator + 1, &separator, 16); - - if (*(separator++) != ':') { - LOG_ERROR("incomplete write memory binary packet received, dropping connection"); - return ERROR_SERVER_REMOTE_CLOSED; - } - - struct gdb_connection *gdb_connection = connection->priv; - - 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 { - retval = gdb_error(connection, retval); - if (retval != ERROR_OK) - return retval; - } - - if (len) { - LOG_DEBUG("addr: 0x%8.8" PRIx32 ", 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; - } - - return ERROR_OK; -} - -static int gdb_step_continue_packet(struct connection *connection, - char const *packet, int packet_size) -{ - struct target *target = get_target_from_connection(connection); - int current = 0; - uint32_t address = 0x0; - int retval = ERROR_OK; - - LOG_DEBUG("-"); - - if (packet_size > 1) - address = strtoul(packet + 1, NULL, 16); - else - current = 1; - - gdb_running_type = packet[0]; - if (packet[0] == 'c') { - LOG_DEBUG("continue"); - /* resume at current address, don't handle breakpoints, not debugging */ - retval = target_resume(target, current, address, 0, 0); - } else if (packet[0] == 's') { - LOG_DEBUG("step"); - /* step at current or address, don't handle breakpoints */ - retval = target_step(target, current, address, 0); - } - return retval; -} - -static int gdb_breakpoint_watchpoint_packet(struct connection *connection, - char const *packet, int packet_size) -{ - struct target *target = get_target_from_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; - uint32_t size; - char *separator; - int retval; - - LOG_DEBUG("-"); - - type = strtoul(packet + 1, &separator, 16); - - if (type == 0) /* memory breakpoint */ - bp_type = BKPT_SOFT; - else if (type == 1) /* hardware breakpoint */ - bp_type = BKPT_HARD; - else if (type == 2) /* write watchpoint */ - wp_type = WPT_WRITE; - else if (type == 3) /* read watchpoint */ - wp_type = WPT_READ; - else if (type == 4) /* access watchpoint */ - wp_type = WPT_ACCESS; - else { - LOG_ERROR("invalid gdb watch/breakpoint type(%d), dropping connection", type); - return ERROR_SERVER_REMOTE_CLOSED; - } - - if (gdb_breakpoint_override && ((bp_type == BKPT_SOFT) || (bp_type == BKPT_HARD))) - bp_type = gdb_breakpoint_override_type; - - if (*separator != ',') { - LOG_ERROR("incomplete breakpoint/watchpoint packet received, dropping connection"); - return ERROR_SERVER_REMOTE_CLOSED; - } - - address = strtoul(separator + 1, &separator, 16); - - if (*separator != ',') { - LOG_ERROR("incomplete breakpoint/watchpoint packet received, dropping connection"); - return ERROR_SERVER_REMOTE_CLOSED; - } - - size = strtoul(separator + 1, &separator, 16); - - switch (type) { - case 0: - case 1: - if (packet[0] == 'Z') { - retval = breakpoint_add(target, address, size, bp_type); - if (retval != ERROR_OK) { - retval = gdb_error(connection, retval); - if (retval != ERROR_OK) - return retval; - } else - gdb_put_packet(connection, "OK", 2); - } else { - breakpoint_remove(target, address); - gdb_put_packet(connection, "OK", 2); - } - break; - case 2: - case 3: - case 4: - { - if (packet[0] == 'Z') { - retval = watchpoint_add(target, address, size, wp_type, 0, 0xffffffffu); - if (retval != ERROR_OK) { - retval = gdb_error(connection, retval); - if (retval != ERROR_OK) - return retval; - } else - gdb_put_packet(connection, "OK", 2); - } else { - watchpoint_remove(target, address); - gdb_put_packet(connection, "OK", 2); - } - break; - } - default: - break; - } - - return ERROR_OK; -} - -/* print out a string and allocate more space as needed, - * mainly used for XML at this point - */ -static void xml_printf(int *retval, char **xml, int *pos, int *size, - const char *fmt, ...) -{ - if (*retval != ERROR_OK) - return; - int first = 1; - - for (;; ) { - if ((*xml == NULL) || (!first)) { - /* start by 0 to exercise all the code paths. - * Need minimum 2 bytes to fit 1 char and 0 terminator. */ - - *size = *size * 2 + 2; - char *t = *xml; - *xml = realloc(*xml, *size); - if (*xml == NULL) { - if (t) - free(t); - *retval = ERROR_SERVER_REMOTE_CLOSED; - return; - } - } - - va_list ap; - int ret; - va_start(ap, fmt); - ret = vsnprintf(*xml + *pos, *size - *pos, fmt, ap); - va_end(ap); - if ((ret > 0) && ((ret + 1) < *size - *pos)) { - *pos += ret; - return; - } - /* there was just enough or not enough space, allocate more. */ - first = 0; - } -} - -static int decode_xfer_read(char const *buf, char **annex, int *ofs, unsigned int *len) -{ - /* Locate the annex. */ - const char *annex_end = strchr(buf, ':'); - if (annex_end == NULL) - return ERROR_FAIL; - - /* After the read marker and annex, qXfer looks like a - * traditional 'm' packet. */ - char *separator; - *ofs = strtoul(annex_end + 1, &separator, 16); - - if (*separator != ',') - return ERROR_FAIL; - - *len = strtoul(separator + 1, NULL, 16); - - /* Extract the annex if needed */ - if (annex != NULL) { - *annex = strndup(buf, annex_end - buf); - if (*annex == NULL) - return ERROR_FAIL; - } - - return ERROR_OK; -} - -static int compare_bank(const void *a, const void *b) -{ - struct flash_bank *b1, *b2; - b1 = *((struct flash_bank **)a); - b2 = *((struct flash_bank **)b); - - if (b1->base == b2->base) - return 0; - else if (b1->base > b2->base) - return 1; - else - return -1; -} - -static int gdb_memory_map(struct connection *connection, - char const *packet, int packet_size) -{ - /* We get away with only specifying flash here. Regions that are not - * specified are treated as if we provided no memory map(if not we - * could detect the holes and mark them as RAM). - * Normally we only execute this code once, but no big deal if we - * have to regenerate it a couple of times. - */ - - struct target *target = get_target_from_connection(connection); - struct flash_bank *p; - char *xml = NULL; - int size = 0; - int pos = 0; - int retval = ERROR_OK; - struct flash_bank **banks; - int offset; - int length; - char *separator; - uint32_t ram_start = 0; - int i; - int target_flash_banks = 0; - - /* skip command character */ - packet += 23; - - offset = strtoul(packet, &separator, 16); - length = strtoul(separator + 1, &separator, 16); - - xml_printf(&retval, &xml, &pos, &size, "\n"); - - /* Sort banks in ascending order. We need to report non-flash - * memory as ram (or rather read/write) by default for GDB, since - * it has no concept of non-cacheable read/write memory (i/o etc). - * - * FIXME Most non-flash addresses are *NOT* RAM! Don't lie. - * Current versions of GDB assume unlisted addresses are RAM... - */ - banks = malloc(sizeof(struct flash_bank *)*flash_get_bank_count()); - - for (i = 0; i < flash_get_bank_count(); i++) { - p = get_flash_bank_by_num_noprobe(i); - if (p->target != target) - continue; - retval = get_flash_bank_by_num(i, &p); - if (retval != ERROR_OK) { - free(banks); - gdb_error(connection, retval); - return retval; - } - banks[target_flash_banks++] = p; - } - - qsort(banks, target_flash_banks, sizeof(struct flash_bank *), - compare_bank); - - for (i = 0; i < target_flash_banks; i++) { - int j; - unsigned sector_size = 0; - uint32_t start; - - p = banks[i]; - start = p->base; - - if (ram_start < p->base) - xml_printf(&retval, &xml, &pos, &size, - "\n", - ram_start, p->base - ram_start); - - /* Report adjacent groups of same-size sectors. So for - * example top boot CFI flash will list an initial region - * with several large sectors (maybe 128KB) and several - * smaller ones at the end (maybe 32KB). STR7 will have - * regions with 8KB, 32KB, and 64KB sectors; etc. - */ - for (j = 0; j < p->num_sectors; j++) { - unsigned group_len; - - /* Maybe start a new group of sectors. */ - if (sector_size == 0) { - start = p->base + p->sectors[j].offset; - xml_printf(&retval, &xml, &pos, &size, - "sectors[j].size; - } - - /* Does this finish a group of sectors? - * If not, continue an already-started group. - */ - if (j == p->num_sectors - 1) - group_len = (p->base + p->size) - start; - else if (p->sectors[j + 1].size != sector_size) - group_len = p->base + p->sectors[j + 1].offset - - start; - else - continue; - - xml_printf(&retval, &xml, &pos, &size, - "length=\"0x%x\">\n" - "" - "0x%x\n" - "\n", - group_len, - sector_size); - sector_size = 0; - } - - ram_start = p->base + p->size; - } - - if (ram_start != 0) - xml_printf(&retval, &xml, &pos, &size, - "\n", - ram_start, 0-ram_start); - /* ELSE a flash chip could be at the very end of the 32 bit address - * space, in which case ram_start will be precisely 0 - */ - - free(banks); - banks = NULL; - - xml_printf(&retval, &xml, &pos, &size, "\n"); - - if (retval != ERROR_OK) { - gdb_error(connection, retval); - return retval; - } - - if (offset + length > pos) - length = pos - offset; - - char *t = malloc(length + 1); - t[0] = 'l'; - memcpy(t + 1, xml + offset, length); - gdb_put_packet(connection, t, length + 1); - - free(t); - free(xml); - return ERROR_OK; -} - -static const char *gdb_get_reg_type_name(enum reg_type type) -{ - switch (type) { - case REG_TYPE_INT: - return "int"; - case REG_TYPE_INT8: - return "int8"; - case REG_TYPE_INT16: - return "int16"; - case REG_TYPE_INT32: - return "int32"; - case REG_TYPE_INT64: - return "int64"; - case REG_TYPE_INT128: - return "int128"; - case REG_TYPE_UINT8: - return "uint8"; - case REG_TYPE_UINT16: - return "uint16"; - case REG_TYPE_UINT32: - return "uint32"; - case REG_TYPE_UINT64: - return "uint64"; - case REG_TYPE_UINT128: - return "uint128"; - case REG_TYPE_CODE_PTR: - return "code_ptr"; - case REG_TYPE_DATA_PTR: - return "data_ptr"; - case REG_TYPE_FLOAT: - return "float"; - case REG_TYPE_IEEE_SINGLE: - return "ieee_single"; - case REG_TYPE_IEEE_DOUBLE: - return "ieee_double"; - case REG_TYPE_ARCH_DEFINED: - return "int"; /* return arbitrary string to avoid compile warning. */ - } - - return "int"; /* "int" as default value */ -} - -static int gdb_generate_reg_type_description(struct target *target, - char **tdesc, int *pos, int *size, struct reg_data_type *type) -{ - int retval = ERROR_OK; - - if (type->type_class == REG_TYPE_CLASS_VECTOR) { - /* */ - xml_printf(&retval, tdesc, pos, size, - "\n", - type->id, type->reg_type_vector->type->id, - type->reg_type_vector->count); - - } else if (type->type_class == REG_TYPE_CLASS_UNION) { - /* - * ... - * */ - xml_printf(&retval, tdesc, pos, size, - "\n", - type->id); - - struct reg_data_type_union_field *field; - field = type->reg_type_union->fields; - while (field != NULL) { - xml_printf(&retval, tdesc, pos, size, - "\n", - field->name, field->type->id); - - field = field->next; - } - - xml_printf(&retval, tdesc, pos, size, - "\n"); - - } else if (type->type_class == REG_TYPE_CLASS_STRUCT) { - struct reg_data_type_struct_field *field; - field = type->reg_type_struct->fields; - - if (field->use_bitfields) { - /* - * ... - * */ - xml_printf(&retval, tdesc, pos, size, - "\n", - type->id, type->reg_type_struct->size); - while (field != NULL) { - xml_printf(&retval, tdesc, pos, size, - "\n", - field->name, field->bitfield->start, - field->bitfield->end); - - field = field->next; - } - } else { - /* - * ... - * */ - xml_printf(&retval, tdesc, pos, size, - "\n", - type->id); - while (field != NULL) { - xml_printf(&retval, tdesc, pos, size, - "\n", - field->name, field->type->id); - - field = field->next; - } - } - - xml_printf(&retval, tdesc, pos, size, - "\n"); - - } else if (type->type_class == REG_TYPE_CLASS_FLAGS) { - /* - * ... - * */ - xml_printf(&retval, tdesc, pos, size, - "\n", - type->id, type->reg_type_flags->size); - - struct reg_data_type_flags_field *field; - field = type->reg_type_flags->fields; - while (field != NULL) { - xml_printf(&retval, tdesc, pos, size, - "\n", - field->name, field->bitfield->start, field->bitfield->end); - - field = field->next; - } - - xml_printf(&retval, tdesc, pos, size, - "\n"); - - } - - return ERROR_OK; -} - -/* Get a list of available target registers features. feature_list must - * be freed by caller. - */ -static int get_reg_features_list(struct target *target, char const **feature_list[], int *feature_list_size, - struct reg **reg_list, int reg_list_size) -{ - int tbl_sz = 0; - - /* Start with only one element */ - *feature_list = calloc(1, sizeof(char *)); - - for (int i = 0; i < reg_list_size; i++) { - if (reg_list[i]->exist == false) - continue; - - if (reg_list[i]->feature != NULL - && reg_list[i]->feature->name != NULL - && (strcmp(reg_list[i]->feature->name, ""))) { - /* We found a feature, check if the feature is already in the - * table. If not, allocate a new entry for the table and - * put the new feature in it. - */ - for (int j = 0; j < (tbl_sz + 1); j++) { - if (!((*feature_list)[j])) { - (*feature_list)[tbl_sz++] = reg_list[i]->feature->name; - *feature_list = realloc(*feature_list, sizeof(char *) * (tbl_sz + 1)); - (*feature_list)[tbl_sz] = NULL; - break; - } else { - if (!strcmp((*feature_list)[j], reg_list[i]->feature->name)) - break; - } - } - } - } - - if (feature_list_size) - *feature_list_size = tbl_sz; - - return ERROR_OK; -} - -static int gdb_generate_target_description(struct target *target, char **tdesc_out) -{ - int retval = ERROR_OK; - struct reg **reg_list = NULL; - int reg_list_size; - char const **features = NULL; - int feature_list_size = 0; - char *tdesc = NULL; - int pos = 0; - int size = 0; - - retval = target_get_gdb_reg_list(target, ®_list, - ®_list_size, REG_CLASS_ALL); - - if (retval != ERROR_OK) { - LOG_ERROR("get register list failed"); - retval = ERROR_FAIL; - goto error; - } - - if (reg_list_size <= 0) { - LOG_ERROR("get register list failed"); - retval = ERROR_FAIL; - goto error; - } - - /* Get a list of available target registers features */ - retval = get_reg_features_list(target, &features, &feature_list_size, reg_list, reg_list_size); - if (retval != ERROR_OK) { - LOG_ERROR("Can't get the registers feature list"); - retval = ERROR_FAIL; - goto error; - } - - /* If we found some features associated with registers, create sections */ - int current_feature = 0; - - xml_printf(&retval, &tdesc, &pos, &size, - "\n" - "\n" - "\n"); - - /* generate target description according to register list */ - if (features != NULL) { - while (features[current_feature]) { - - xml_printf(&retval, &tdesc, &pos, &size, - "\n", - features[current_feature]); - - int i; - for (i = 0; i < reg_list_size; i++) { - - if (reg_list[i]->exist == false) - continue; - - if (strcmp(reg_list[i]->feature->name, features[current_feature])) - continue; - - const char *type_str; - if (reg_list[i]->reg_data_type != NULL) { - if (reg_list[i]->reg_data_type->type == REG_TYPE_ARCH_DEFINED) { - /* generate reg_data_type); - - type_str = reg_list[i]->reg_data_type->id; - } else { - /* predefined type */ - type_str = gdb_get_reg_type_name( - reg_list[i]->reg_data_type->type); - } - } else { - /* Default type is "int" */ - type_str = "int"; - } - - xml_printf(&retval, &tdesc, &pos, &size, - "name); - xml_printf(&retval, &tdesc, &pos, &size, - " bitsize=\"%d\"", reg_list[i]->size); - xml_printf(&retval, &tdesc, &pos, &size, - " regnum=\"%d\"", reg_list[i]->number); - if (reg_list[i]->caller_save) - xml_printf(&retval, &tdesc, &pos, &size, - " save-restore=\"yes\""); - else - xml_printf(&retval, &tdesc, &pos, &size, - " save-restore=\"no\""); - - xml_printf(&retval, &tdesc, &pos, &size, - " type=\"%s\"", type_str); - - if (reg_list[i]->group != NULL) - xml_printf(&retval, &tdesc, &pos, &size, - " group=\"%s\"", reg_list[i]->group); - - xml_printf(&retval, &tdesc, &pos, &size, - "/>\n"); - } - - xml_printf(&retval, &tdesc, &pos, &size, - "\n"); - - current_feature++; - } - } - - xml_printf(&retval, &tdesc, &pos, &size, - "\n"); - -error: - free(features); - free(reg_list); - - if (retval == ERROR_OK) - *tdesc_out = tdesc; - else - free(tdesc); - - return retval; -} - -static int gdb_get_target_description_chunk(struct target *target, struct target_desc_format *target_desc, - char **chunk, int32_t offset, uint32_t length) -{ - if (target_desc == NULL) { - LOG_ERROR("Unable to Generate Target Description"); - return ERROR_FAIL; - } - - char *tdesc = target_desc->tdesc; - uint32_t tdesc_length = target_desc->tdesc_length; - - if (tdesc == NULL) { - int retval = gdb_generate_target_description(target, &tdesc); - if (retval != ERROR_OK) { - LOG_ERROR("Unable to Generate Target Description"); - return ERROR_FAIL; - } - - tdesc_length = strlen(tdesc); - } - - char transfer_type; - - if (length < (tdesc_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; - if (transfer_type == 'm') { - strncpy((*chunk) + 1, tdesc + offset, length); - (*chunk)[1 + length] = '\0'; - } else { - strncpy((*chunk) + 1, tdesc + offset, tdesc_length - offset); - (*chunk)[1 + (tdesc_length - offset)] = '\0'; - - /* After gdb-server sends out last chunk, invalidate tdesc. */ - free(tdesc); - tdesc = NULL; - tdesc_length = 0; - } - - target_desc->tdesc = tdesc; - target_desc->tdesc_length = tdesc_length; - - return ERROR_OK; -} - -static int gdb_target_description_supported(struct target *target, int *supported) -{ - int retval = ERROR_OK; - struct reg **reg_list = NULL; - int reg_list_size = 0; - char const **features = NULL; - int feature_list_size = 0; - - retval = target_get_gdb_reg_list(target, ®_list, - ®_list_size, REG_CLASS_ALL); - if (retval != ERROR_OK) { - LOG_ERROR("get register list failed"); - goto error; - } - - if (reg_list_size <= 0) { - LOG_ERROR("get register list failed"); - retval = ERROR_FAIL; - goto error; - } - - /* Get a list of available target registers features */ - retval = get_reg_features_list(target, &features, &feature_list_size, reg_list, reg_list_size); - if (retval != ERROR_OK) { - LOG_ERROR("Can't get the registers feature list"); - goto error; - } - - if (supported) { - if (feature_list_size) - *supported = 1; - else - *supported = 0; - } - -error: - free(features); - - free(reg_list); - - return retval; -} - -static int gdb_query_packet(struct connection *connection, - char const *packet, int packet_size) -{ - struct command_context *cmd_ctx = connection->cmd_ctx; - struct gdb_connection *gdb_connection = connection->priv; - struct target *target = get_target_from_connection(connection); - - if (strncmp(packet, "qRcmd,", 6) == 0) { - if (packet_size > 6) { - char *cmd; - cmd = malloc((packet_size - 6) / 2 + 1); - int len = unhexify(cmd, packet + 6, (packet_size - 6) / 2); - cmd[len] = 0; - - /* We want to print all debug output to GDB connection */ - log_add_callback(gdb_log_callback, connection); - target_call_timer_callbacks_now(); - /* some commands need to know the GDB connection, make note of current - * GDB connection. */ - current_gdb_connection = gdb_connection; - command_run_line(cmd_ctx, cmd); - current_gdb_connection = NULL; - target_call_timer_callbacks_now(); - log_remove_callback(gdb_log_callback, connection); - free(cmd); - } - gdb_put_packet(connection, "OK", 2); - return ERROR_OK; - } else if (strncmp(packet, "qCRC:", 5) == 0) { - if (packet_size > 5) { - int retval; - char gdb_reply[10]; - char *separator; - uint32_t checksum; - uint32_t addr = 0; - uint32_t len = 0; - - /* skip command character */ - packet += 5; - - addr = strtoul(packet, &separator, 16); - - if (*separator != ',') { - LOG_ERROR("incomplete read memory packet received, dropping connection"); - return ERROR_SERVER_REMOTE_CLOSED; - } - - len = strtoul(separator + 1, NULL, 16); - - retval = target_checksum_memory(target, addr, len, &checksum); - - if (retval == ERROR_OK) { - snprintf(gdb_reply, 10, "C%8.8" PRIx32 "", checksum); - gdb_put_packet(connection, gdb_reply, 9); - } else { - retval = gdb_error(connection, retval); - if (retval != ERROR_OK) - return retval; - } - - return ERROR_OK; - } - } else if (strncmp(packet, "qSupported", 10) == 0) { - /* we currently support packet size and qXfer:memory-map:read (if enabled) - * qXfer:features:read is supported for some targets */ - int retval = ERROR_OK; - char *buffer = NULL; - int pos = 0; - int size = 0; - int gdb_target_desc_supported = 0; - - /* we need to test that the target supports target descriptions */ - retval = gdb_target_description_supported(target, &gdb_target_desc_supported); - if (retval != ERROR_OK) { - LOG_INFO("Failed detecting Target Description Support, disabling"); - gdb_target_desc_supported = 0; - } - - /* support may be disabled globally */ - if (gdb_use_target_description == 0) { - if (gdb_target_desc_supported) - LOG_WARNING("Target Descriptions Supported, but disabled"); - gdb_target_desc_supported = 0; - } - - xml_printf(&retval, - &buffer, - &pos, - &size, - "PacketSize=%x;qXfer:memory-map:read%c;qXfer:features:read%c;QStartNoAckMode+", - (GDB_BUFFER_SIZE - 1), - ((gdb_use_memory_map == 1) && (flash_get_bank_count() > 0)) ? '+' : '-', - (gdb_target_desc_supported == 1) ? '+' : '-'); - - if (retval != ERROR_OK) { - gdb_send_error(connection, 01); - return ERROR_OK; - } - - gdb_put_packet(connection, buffer, strlen(buffer)); - free(buffer); - - return ERROR_OK; - } else if ((strncmp(packet, "qXfer:memory-map:read::", 23) == 0) - && (flash_get_bank_count() > 0)) - return gdb_memory_map(connection, packet, packet_size); - else if (strncmp(packet, "qXfer:features:read:", 20) == 0) { - char *xml = NULL; - int retval = ERROR_OK; - - int offset; - unsigned int length; - - /* skip command character */ - packet += 20; - - if (decode_xfer_read(packet, NULL, &offset, &length) < 0) { - gdb_send_error(connection, 01); - return ERROR_OK; - } - - /* Target should prepare correct target description 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_target_description_chunk(target, &gdb_connection->target_desc, - &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) { - gdb_connection->noack_mode = 1; - gdb_put_packet(connection, "OK", 2); - return ERROR_OK; - } - - gdb_put_packet(connection, "", 0); - return ERROR_OK; -} - -static int gdb_v_packet(struct connection *connection, - char const *packet, int packet_size) -{ - struct gdb_connection *gdb_connection = connection->priv; - struct gdb_service *gdb_service = connection->service->priv; - int result; - - /* if flash programming disabled - send a empty reply */ - - if (gdb_flash_program == 0) { - gdb_put_packet(connection, "", 0); - return ERROR_OK; - } - - if (strncmp(packet, "vFlashErase:", 12) == 0) { - unsigned long addr; - unsigned long length; - - char const *parse = packet + 12; - if (*parse == '\0') { - LOG_ERROR("incomplete vFlashErase packet received, dropping connection"); - return ERROR_SERVER_REMOTE_CLOSED; - } - - addr = strtoul(parse, (char **)&parse, 16); - - if (*(parse++) != ',' || *parse == '\0') { - LOG_ERROR("incomplete vFlashErase packet received, dropping connection"); - return ERROR_SERVER_REMOTE_CLOSED; - } - - length = strtoul(parse, (char **)&parse, 16); - - if (*parse != '\0') { - LOG_ERROR("incomplete vFlashErase packet received, dropping connection"); - return ERROR_SERVER_REMOTE_CLOSED; - } - - /* assume all sectors need erasing - stops any problems - * when flash_write is called multiple times */ - flash_set_dirty(); - - /* perform any target specific operations before the erase */ - target_call_event_callbacks(gdb_service->target, - TARGET_EVENT_GDB_FLASH_ERASE_START); - - /* vFlashErase:addr,length messages require region start and - * end to be "block" aligned ... if padding is ever needed, - * GDB will have become dangerously confused. - */ - result = flash_erase_address_range(gdb_service->target, - false, addr, length); - - /* perform any target specific operations after the erase */ - target_call_event_callbacks(gdb_service->target, - TARGET_EVENT_GDB_FLASH_ERASE_END); - - /* perform erase */ - if (result != ERROR_OK) { - /* GDB doesn't evaluate the actual error number returned, - * treat a failed erase as an I/O error - */ - gdb_send_error(connection, EIO); - LOG_ERROR("flash_erase returned %i", result); - } else - gdb_put_packet(connection, "OK", 2); - - return ERROR_OK; - } - - if (strncmp(packet, "vFlashWrite:", 12) == 0) { - int retval; - unsigned long addr; - unsigned long length; - char const *parse = packet + 12; - - if (*parse == '\0') { - LOG_ERROR("incomplete vFlashErase packet received, dropping connection"); - return ERROR_SERVER_REMOTE_CLOSED; - } - addr = strtoul(parse, (char **)&parse, 16); - if (*(parse++) != ':') { - LOG_ERROR("incomplete vFlashErase packet received, dropping connection"); - return ERROR_SERVER_REMOTE_CLOSED; - } - length = packet_size - (parse - packet); - - /* create a new image if there isn't already one */ - if (gdb_connection->vflash_image == NULL) { - gdb_connection->vflash_image = malloc(sizeof(struct image)); - image_open(gdb_connection->vflash_image, "", "build"); - } - - /* create new section with content from packet buffer */ - retval = image_add_section(gdb_connection->vflash_image, - addr, length, 0x0, (uint8_t const *)parse); - if (retval != ERROR_OK) - return retval; - - gdb_put_packet(connection, "OK", 2); - - return ERROR_OK; - } - - if (strncmp(packet, "vFlashDone", 10) == 0) { - uint32_t written; - - /* process the flashing buffer. No need to erase as GDB - * always issues a vFlashErase first. */ - target_call_event_callbacks(gdb_service->target, - TARGET_EVENT_GDB_FLASH_WRITE_START); - result = flash_write(gdb_service->target, gdb_connection->vflash_image, &written, 0); - target_call_event_callbacks(gdb_service->target, TARGET_EVENT_GDB_FLASH_WRITE_END); - if (result != ERROR_OK) { - if (result == ERROR_FLASH_DST_OUT_OF_BANK) - gdb_put_packet(connection, "E.memtype", 9); - else - gdb_send_error(connection, EIO); - } else { - LOG_DEBUG("wrote %u bytes from vFlash image to flash", (unsigned)written); - gdb_put_packet(connection, "OK", 2); - } - - image_close(gdb_connection->vflash_image); - free(gdb_connection->vflash_image); - gdb_connection->vflash_image = NULL; - - return ERROR_OK; - } - - gdb_put_packet(connection, "", 0); - return ERROR_OK; -} - -static int gdb_detach(struct connection *connection) -{ - struct gdb_service *gdb_service = connection->service->priv; - - target_call_event_callbacks(gdb_service->target, TARGET_EVENT_GDB_DETACH); - - return gdb_put_packet(connection, "OK", 2); -} - -/* The format of 'F' response packet is - * Fretcode,errno,Ctrl-C flag;call-specific attachment - */ -static int gdb_fileio_response_packet(struct connection *connection, - char const *packet, int packet_size) -{ - struct target *target = get_target_from_connection(connection); - char *separator; - char *parsing_point; - int fileio_retcode = strtoul(packet + 1, &separator, 16); - int fileio_errno = 0; - bool fileio_ctrl_c = false; - int retval; - - LOG_DEBUG("-"); - - if (*separator == ',') { - parsing_point = separator + 1; - fileio_errno = strtoul(parsing_point, &separator, 16); - if (*separator == ',') { - if (*(separator + 1) == 'C') { - /* TODO: process ctrl-c */ - fileio_ctrl_c = true; - } - } - } - - LOG_DEBUG("File-I/O response, retcode: 0x%x, errno: 0x%x, ctrl-c: %s", - fileio_retcode, fileio_errno, fileio_ctrl_c ? "true" : "false"); - - retval = target_gdb_fileio_end(target, fileio_retcode, fileio_errno, fileio_ctrl_c); - if (retval != ERROR_OK) - return ERROR_FAIL; - - /* After File-I/O ends, keep continue or step */ - if (gdb_running_type == 'c') - retval = target_resume(target, 1, 0x0, 0, 0); - else if (gdb_running_type == 's') - retval = target_step(target, 1, 0x0, 0); - else - retval = ERROR_FAIL; - - if (retval != ERROR_OK) - return ERROR_FAIL; - - return ERROR_OK; -} - -static void gdb_log_callback(void *priv, const char *file, unsigned line, - const char *function, const char *string) -{ - struct connection *connection = priv; - struct gdb_connection *gdb_con = connection->priv; - - if (gdb_con->busy) { - /* do not reply this using the O packet */ - return; - } - - gdb_output_con(connection, string); -} - -static void gdb_sig_halted(struct connection *connection) -{ - char sig_reply[4]; - snprintf(sig_reply, 4, "T%2.2x", 2); - gdb_put_packet(connection, sig_reply, 3); -} - -static int gdb_input_inner(struct connection *connection) -{ - /* Do not allocate this on the stack */ - static char gdb_packet_buffer[GDB_BUFFER_SIZE]; - - struct gdb_service *gdb_service = connection->service->priv; - struct target *target = gdb_service->target; - char const *packet = gdb_packet_buffer; - int packet_size; - int retval; - struct gdb_connection *gdb_con = connection->priv; - static int extended_protocol; - - /* drain input buffer. If one of the packets fail, then an error - * packet is replied, if applicable. - * - * This loop will terminate and the error code is returned. - * - * The calling fn will check if this error is something that - * can be recovered from, or if the connection must be closed. - * - * If the error is recoverable, this fn is called again to - * drain the rest of the buffer. - */ - do { - packet_size = GDB_BUFFER_SIZE-1; - retval = gdb_get_packet(connection, gdb_packet_buffer, &packet_size); - if (retval != ERROR_OK) - return retval; - - /* terminate with zero */ - gdb_packet_buffer[packet_size] = '\0'; - - if (LOG_LEVEL_IS(LOG_LVL_DEBUG)) { - if (packet[0] == 'X') { - /* binary packets spew junk into the debug log stream */ - char buf[50]; - int x; - for (x = 0; (x < 49) && (packet[x] != ':'); x++) - buf[x] = packet[x]; - buf[x] = 0; - LOG_DEBUG("received packet: '%s:'", buf); - } else - LOG_DEBUG("received packet: '%s'", packet); - } - - if (packet_size > 0) { - retval = ERROR_OK; - switch (packet[0]) { - case 'T': /* Is thread alive? */ - gdb_thread_packet(connection, packet, packet_size); - break; - case 'H': /* Set current thread ( 'c' for step and continue, - * 'g' for all other operations ) */ - gdb_thread_packet(connection, packet, packet_size); - break; - case 'q': - case 'Q': - retval = gdb_thread_packet(connection, packet, packet_size); - if (retval == GDB_THREAD_PACKET_NOT_CONSUMED) - retval = gdb_query_packet(connection, packet, packet_size); - break; - case 'g': - retval = gdb_get_registers_packet(connection, packet, packet_size); - break; - case 'G': - retval = gdb_set_registers_packet(connection, packet, packet_size); - break; - case 'p': - retval = gdb_get_register_packet(connection, packet, packet_size); - break; - case 'P': - retval = gdb_set_register_packet(connection, packet, packet_size); - break; - case 'm': - retval = gdb_read_memory_packet(connection, packet, packet_size); - break; - case 'M': - retval = gdb_write_memory_packet(connection, packet, packet_size); - break; - case 'z': - case 'Z': - retval = gdb_breakpoint_watchpoint_packet(connection, packet, packet_size); - break; - case '?': - gdb_last_signal_packet(connection, packet, packet_size); - break; - case 'c': - case 's': - { - gdb_thread_packet(connection, packet, packet_size); - log_add_callback(gdb_log_callback, connection); - - if (gdb_con->mem_write_error) { - LOG_ERROR("Memory write failure!"); - - /* now that we have reported the memory write error, - * we can clear the condition */ - gdb_con->mem_write_error = false; - } - - bool nostep = false; - bool already_running = false; - if (target->state == TARGET_RUNNING) { - LOG_WARNING("WARNING! The target is already running. " - "All changes GDB did to registers will be discarded! " - "Waiting for target to halt."); - already_running = true; - } else if (target->state != TARGET_HALTED) { - LOG_WARNING("The target is not in the halted nor running stated, " \ - "stepi/continue ignored."); - nostep = true; - } else if ((packet[0] == 's') && gdb_con->sync) { - /* Hmm..... when you issue a continue in GDB, then a "stepi" is - * sent by GDB first to OpenOCD, thus defeating the check to - * make only the single stepping have the sync feature... - */ - nostep = true; - LOG_WARNING("stepi ignored. GDB will now fetch the register state " \ - "from the target."); - } - gdb_con->sync = false; - - if (!already_running && nostep) { - /* Either the target isn't in the halted state, then we can't - * step/continue. This might be early setup, etc. - * - * Or we want to allow GDB to pick up a fresh set of - * register values without modifying the target state. - * - */ - gdb_sig_halted(connection); - - /* stop forwarding log packets! */ - log_remove_callback(gdb_log_callback, connection); - } else { - /* We're running/stepping, in which case we can - * forward log output until the target is halted - */ - gdb_con->frontend_state = TARGET_RUNNING; - target_call_event_callbacks(target, TARGET_EVENT_GDB_START); - - if (!already_running) { - /* Here we don't want packet processing to stop even if this fails, - * so we use a local variable instead of retval. */ - retval = gdb_step_continue_packet(connection, packet, packet_size); - if (retval != ERROR_OK) { - /* we'll never receive a halted - * condition... issue a false one.. - */ - gdb_frontend_halted(target, connection); - } - } - } - } - break; - case 'v': - retval = gdb_v_packet(connection, packet, packet_size); - break; - case 'D': - retval = gdb_detach(connection); - extended_protocol = 0; - break; - case 'X': - retval = gdb_write_memory_binary_packet(connection, packet, packet_size); - if (retval != ERROR_OK) - return retval; - break; - case 'k': - if (extended_protocol != 0) { - gdb_con->attached = false; - break; - } - gdb_put_packet(connection, "OK", 2); - return ERROR_SERVER_REMOTE_CLOSED; - case '!': - /* handle extended remote protocol */ - extended_protocol = 1; - gdb_put_packet(connection, "OK", 2); - break; - case 'R': - /* handle extended restart packet */ - breakpoint_clear_target(gdb_service->target); - watchpoint_clear_target(gdb_service->target); - command_run_linef(connection->cmd_ctx, "ocd_gdb_restart %s", - target_name(target)); - /* set connection as attached after reset */ - gdb_con->attached = true; - /* info rtos parts */ - gdb_thread_packet(connection, packet, packet_size); - break; - - case 'j': - /* packet supported only by smp target i.e cortex_a.c*/ - /* handle smp packet replying coreid played to gbd */ - gdb_read_smp_packet(connection, packet, packet_size); - break; - - case 'J': - /* packet supported only by smp target i.e cortex_a.c */ - /* handle smp packet setting coreid to be played at next - * resume to gdb */ - gdb_write_smp_packet(connection, packet, packet_size); - break; - - case 'F': - /* File-I/O extension */ - /* After gdb uses host-side syscall to complete target file - * I/O, gdb sends host-side syscall return value to target - * by 'F' packet. - * The format of 'F' response packet is - * Fretcode,errno,Ctrl-C flag;call-specific attachment - */ - gdb_con->frontend_state = TARGET_RUNNING; - log_add_callback(gdb_log_callback, connection); - gdb_fileio_response_packet(connection, packet, packet_size); - break; - - default: - /* ignore unknown packets */ - LOG_DEBUG("ignoring 0x%2.2x packet", packet[0]); - gdb_put_packet(connection, NULL, 0); - break; - } - - /* if a packet handler returned an error, exit input loop */ - if (retval != ERROR_OK) - return retval; - } - - if (gdb_con->ctrl_c) { - if (target->state == TARGET_RUNNING) { - retval = target_halt(target); - if (retval != ERROR_OK) - target_call_event_callbacks(target, TARGET_EVENT_GDB_HALT); - gdb_con->ctrl_c = 0; - } else { - LOG_INFO("The target is not running when halt was requested, stopping GDB."); - target_call_event_callbacks(target, TARGET_EVENT_GDB_HALT); - } - } - - } while (gdb_con->buf_cnt > 0); - - return ERROR_OK; -} - -static int gdb_input(struct connection *connection) -{ - int retval = gdb_input_inner(connection); - struct gdb_connection *gdb_con = connection->priv; - if (retval == ERROR_SERVER_REMOTE_CLOSED) - return retval; - - /* logging does not propagate the error, yet can set the gdb_con->closed flag */ - if (gdb_con->closed) - return ERROR_SERVER_REMOTE_CLOSED; - - /* we'll recover from any other errors(e.g. temporary timeouts, etc.) */ - return ERROR_OK; -} - -static int gdb_target_start(struct target *target, const char *port) -{ - struct gdb_service *gdb_service; - int ret; - gdb_service = malloc(sizeof(struct gdb_service)); - - if (NULL == gdb_service) - return -ENOMEM; - - gdb_service->target = target; - gdb_service->core[0] = -1; - gdb_service->core[1] = -1; - target->gdb_service = gdb_service; - - ret = add_service("gdb", - port, 1, &gdb_new_connection, &gdb_input, - &gdb_connection_closed, gdb_service); - /* initialialize all targets gdb service with the same pointer */ - { - struct target_list *head; - struct target *curr; - head = target->head; - while (head != (struct target_list *)NULL) { - curr = head->target; - if (curr != target) - curr->gdb_service = gdb_service; - head = head->next; - } - } - return ret; -} - -static int gdb_target_add_one(struct target *target) -{ - /* one gdb instance per smp list */ - if ((target->smp) && (target->gdb_service)) - return ERROR_OK; - int retval = gdb_target_start(target, gdb_port_next); - if (retval == ERROR_OK) { - long portnumber; - /* If we can parse the port number - * then we increment the port number for the next target. - */ - char *end; - portnumber = strtol(gdb_port_next, &end, 0); - if (!*end) { - if (parse_long(gdb_port_next, &portnumber) == ERROR_OK) { - free(gdb_port_next); - gdb_port_next = alloc_printf("%d", portnumber+1); - } - } - } - return retval; -} - -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; - } - - while (NULL != target) { - int retval = gdb_target_add_one(target); - if (ERROR_OK != retval) - return retval; - - target = target->next; - } - - return ERROR_OK; -} - -COMMAND_HANDLER(handle_gdb_sync_command) -{ - if (CMD_ARGC != 0) - return ERROR_COMMAND_SYNTAX_ERROR; - - if (current_gdb_connection == NULL) { - command_print(CMD_CTX, - "gdb_sync command can only be run from within gdb using \"monitor gdb_sync\""); - return ERROR_FAIL; - } - - current_gdb_connection->sync = true; - - return ERROR_OK; -} - -/* daemon configuration command gdb_port */ -COMMAND_HANDLER(handle_gdb_port_command) -{ - int retval = CALL_COMMAND_HANDLER(server_pipe_command, &gdb_port); - if (ERROR_OK == retval) { - free(gdb_port_next); - gdb_port_next = strdup(gdb_port); - } - return retval; -} - -COMMAND_HANDLER(handle_gdb_memory_map_command) -{ - if (CMD_ARGC != 1) - return ERROR_COMMAND_SYNTAX_ERROR; - - COMMAND_PARSE_ENABLE(CMD_ARGV[0], gdb_use_memory_map); - return ERROR_OK; -} - -COMMAND_HANDLER(handle_gdb_flash_program_command) -{ - if (CMD_ARGC != 1) - return ERROR_COMMAND_SYNTAX_ERROR; - - COMMAND_PARSE_ENABLE(CMD_ARGV[0], gdb_flash_program); - return ERROR_OK; -} - -COMMAND_HANDLER(handle_gdb_report_data_abort_command) -{ - if (CMD_ARGC != 1) - return ERROR_COMMAND_SYNTAX_ERROR; - - COMMAND_PARSE_ENABLE(CMD_ARGV[0], gdb_report_data_abort); - return ERROR_OK; -} - -/* gdb_breakpoint_override */ -COMMAND_HANDLER(handle_gdb_breakpoint_override_command) -{ - if (CMD_ARGC == 0) { - /* nothing */ - } else if (CMD_ARGC == 1) { - gdb_breakpoint_override = 1; - if (strcmp(CMD_ARGV[0], "hard") == 0) - gdb_breakpoint_override_type = BKPT_HARD; - else if (strcmp(CMD_ARGV[0], "soft") == 0) - gdb_breakpoint_override_type = BKPT_SOFT; - else if (strcmp(CMD_ARGV[0], "disable") == 0) - gdb_breakpoint_override = 0; - } else - return ERROR_COMMAND_SYNTAX_ERROR; - if (gdb_breakpoint_override) - LOG_USER("force %s breakpoints", - (gdb_breakpoint_override_type == BKPT_HARD) ? "hard" : "soft"); - else - LOG_USER("breakpoint type is not overridden"); - - return ERROR_OK; -} - -COMMAND_HANDLER(handle_gdb_target_description_command) -{ - if (CMD_ARGC != 1) - return ERROR_COMMAND_SYNTAX_ERROR; - - COMMAND_PARSE_ENABLE(CMD_ARGV[0], gdb_use_target_description); - return ERROR_OK; -} - -COMMAND_HANDLER(handle_gdb_save_tdesc_command) -{ - char *tdesc; - uint32_t tdesc_length; - struct target *target = get_current_target(CMD_CTX); - - int retval = gdb_generate_target_description(target, &tdesc); - if (retval != ERROR_OK) { - LOG_ERROR("Unable to Generate Target Description"); - return ERROR_FAIL; - } - - tdesc_length = strlen(tdesc); - - struct fileio *fileio; - size_t size_written; - - char *tdesc_filename = alloc_printf("%s.xml", target_type_name(target)); - if (tdesc_filename == NULL) { - retval = ERROR_FAIL; - goto out; - } - - retval = fileio_open(&fileio, tdesc_filename, FILEIO_WRITE, FILEIO_TEXT); - - if (retval != ERROR_OK) { - LOG_ERROR("Can't open %s for writing", tdesc_filename); - goto out; - } - - retval = fileio_write(fileio, tdesc_length, tdesc, &size_written); - - fileio_close(fileio); - - if (retval != ERROR_OK) - LOG_ERROR("Error while writing the tdesc file"); - -out: - free(tdesc_filename); - free(tdesc); - - return retval; -} - -static const struct command_registration gdb_command_handlers[] = { - { - .name = "gdb_sync", - .handler = handle_gdb_sync_command, - .mode = COMMAND_ANY, - .help = "next stepi will return immediately allowing " - "GDB to fetch register state without affecting " - "target state", - .usage = "" - }, - { - .name = "gdb_port", - .handler = handle_gdb_port_command, - .mode = COMMAND_ANY, - .help = "Normally gdb listens to a TCP/IP port. Each subsequent GDB " - "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 " - "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]", - }, - { - .name = "gdb_memory_map", - .handler = handle_gdb_memory_map_command, - .mode = COMMAND_CONFIG, - .help = "enable or disable memory map", - .usage = "('enable'|'disable')" - }, - { - .name = "gdb_flash_program", - .handler = handle_gdb_flash_program_command, - .mode = COMMAND_CONFIG, - .help = "enable or disable flash program", - .usage = "('enable'|'disable')" - }, - { - .name = "gdb_report_data_abort", - .handler = handle_gdb_report_data_abort_command, - .mode = COMMAND_CONFIG, - .help = "enable or disable reporting data aborts", - .usage = "('enable'|'disable')" - }, - { - .name = "gdb_breakpoint_override", - .handler = handle_gdb_breakpoint_override_command, - .mode = COMMAND_ANY, - .help = "Display or specify type of breakpoint " - "to be used by gdb 'break' commands.", - .usage = "('hard'|'soft'|'disable')" - }, - { - .name = "gdb_target_description", - .handler = handle_gdb_target_description_command, - .mode = COMMAND_CONFIG, - .help = "enable or disable target description", - .usage = "('enable'|'disable')" - }, - { - .name = "gdb_save_tdesc", - .handler = handle_gdb_save_tdesc_command, - .mode = COMMAND_EXEC, - .help = "Save the target description file", - }, - COMMAND_REGISTRATION_DONE -}; - -int gdb_register_commands(struct command_context *cmd_ctx) -{ - gdb_port = strdup("3333"); - gdb_port_next = strdup("3333"); - return register_commands(cmd_ctx, NULL, gdb_command_handlers); -} diff --git a/src/server/gdb_server.h b/src/server/gdb_server.h deleted file mode 100644 index 2b4ac4eaf..000000000 --- a/src/server/gdb_server.h +++ /dev/null @@ -1,51 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * Copyright (C) 2007-2009 Øyvind Harboe * - * oyvind.harboe@zylin.com * - * * - * Copyright (C) 2008 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * Copyright (C) 2011 by Broadcom Corporation * - * Evan Hunter - ehunter@broadcom.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifndef OPENOCD_SERVER_GDB_SERVER_H -#define OPENOCD_SERVER_GDB_SERVER_H - -struct image; -struct reg; -#include - -#define GDB_BUFFER_SIZE 16384 - -int gdb_target_add_all(struct target *target); -int gdb_register_commands(struct command_context *command_context); - -int gdb_put_packet(struct connection *connection, char *buffer, int len); - -static inline struct target *get_target_from_connection(struct connection *connection) -{ - struct gdb_service *gdb_service = connection->service->priv; - return gdb_service->target; -} - -#define ERROR_GDB_BUFFER_TOO_SMALL (-800) -#define ERROR_GDB_TIMEOUT (-801) - -#endif /* OPENOCD_SERVER_GDB_SERVER_H */ diff --git a/src/server/server.c b/src/server/server.c deleted file mode 100644 index f6889a01a..000000000 --- a/src/server/server.c +++ /dev/null @@ -1,751 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * Copyright (C) 2007-2010 Øyvind Harboe * - * oyvind.harboe@zylin.com * - * * - * Copyright (C) 2008 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "server.h" -#include -#include -#include -#include "openocd.h" -#include "tcl_server.h" -#include "telnet_server.h" - -#include - -#ifdef HAVE_NETDB_H -#include -#endif - -#ifndef _WIN32 -#include -#endif - -static struct service *services; - -/* shutdown_openocd == 1: exit the main event loop, and quit the - * debugger; 2: quit with non-zero return code */ -static int shutdown_openocd; - -/* store received signal to exit application by killing ourselves */ -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; - struct connection *c, **p; - int retval; - int flag = 1; - - c = malloc(sizeof(struct connection)); - c->fd = -1; - c->fd_out = -1; - memset(&c->sin, 0, sizeof(c->sin)); - c->cmd_ctx = copy_command_context(cmd_ctx); - c->service = service; - c->input_pending = 0; - c->priv = NULL; - c->next = NULL; - - if (service->type == CONNECTION_TCP) { - address_size = sizeof(c->sin); - - c->fd = accept(service->fd, (struct sockaddr *)&service->sin, &address_size); - c->fd_out = c->fd; - - /* This increases performance dramatically for e.g. GDB load which - * does not have a sliding window protocol. - * - * Ignore errors from this fn as it probably just means less performance - */ - setsockopt(c->fd, /* socket affected */ - IPPROTO_TCP, /* set option at TCP level */ - TCP_NODELAY, /* name of option */ - (char *)&flag, /* the cast is historical cruft */ - sizeof(int)); /* length of option value */ - - LOG_INFO("accepting '%s' connection on tcp/%s", service->name, service->port); - retval = service->new_connection(c); - if (retval != ERROR_OK) { - close_socket(c->fd); - LOG_ERROR("attempted '%s' connection rejected", service->name); - command_done(c->cmd_ctx); - free(c); - return retval; - } - } else if (service->type == CONNECTION_STDINOUT) { - c->fd = service->fd; - c->fd_out = fileno(stdout); - -#ifdef _WIN32 - /* we are using stdin/out so ignore ctrl-c under windoze */ - SetConsoleCtrlHandler(NULL, TRUE); -#endif - - /* do not check for new connections again on stdin */ - service->fd = -1; - - LOG_INFO("accepting '%s' connection from pipe", service->name); - retval = service->new_connection(c); - if (retval != ERROR_OK) { - LOG_ERROR("attempted '%s' connection rejected", service->name); - command_done(c->cmd_ctx); - free(c); - return retval; - } - } else if (service->type == CONNECTION_PIPE) { - c->fd = service->fd; - /* do not check for new connections again on stdin */ - service->fd = -1; - - char *out_file = alloc_printf("%so", service->port); - c->fd_out = open(out_file, O_WRONLY); - free(out_file); - if (c->fd_out == -1) { - LOG_ERROR("could not open %s", service->port); - exit(1); - } - - LOG_INFO("accepting '%s' connection from pipe %s", service->name, service->port); - retval = service->new_connection(c); - if (retval != ERROR_OK) { - LOG_ERROR("attempted '%s' connection rejected", service->name); - command_done(c->cmd_ctx); - free(c); - return retval; - } - } - - /* add to the end of linked list */ - for (p = &service->connections; *p; p = &(*p)->next) - ; - *p = c; - - if (service->max_connections != CONNECTION_LIMIT_UNLIMITED) - service->max_connections--; - - return ERROR_OK; -} - -static int remove_connection(struct service *service, struct connection *connection) -{ - struct connection **p = &service->connections; - struct connection *c; - - /* find connection */ - while ((c = *p)) { - if (c->fd == connection->fd) { - service->connection_closed(c); - if (service->type == CONNECTION_TCP) - close_socket(c->fd); - else if (service->type == CONNECTION_PIPE) { - /* The service will listen to the pipe again */ - c->service->fd = c->fd; - } - - command_done(c->cmd_ctx); - - /* delete connection */ - *p = c->next; - free(c); - - if (service->max_connections != CONNECTION_LIMIT_UNLIMITED) - service->max_connections++; - - break; - } - - /* redirect p to next list pointer */ - p = &(*p)->next; - } - - return ERROR_OK; -} - -/* FIX! make service return error instead of invoking exit() */ -int add_service(char *name, - const char *port, - int max_connections, - new_connection_handler_t new_connection_handler, - input_handler_t input_handler, - connection_closed_handler_t connection_closed_handler, - void *priv) -{ - struct service *c, **p; - struct hostent *hp; - int so_reuseaddr_option = 1; - - c = malloc(sizeof(struct service)); - - c->name = strdup(name); - c->port = strdup(port); - c->max_connections = 1; /* Only TCP/IP ports can support more than one connection */ - c->fd = -1; - c->connections = NULL; - c->new_connection = new_connection_handler; - c->input = input_handler; - c->connection_closed = connection_closed_handler; - c->priv = priv; - c->next = NULL; - long portnumber; - if (strcmp(c->port, "pipe") == 0) - c->type = CONNECTION_STDINOUT; - else { - char *end; - portnumber = strtol(c->port, &end, 0); - if (!*end && (parse_long(c->port, &portnumber) == ERROR_OK)) { - c->portnumber = portnumber; - c->type = CONNECTION_TCP; - } else - c->type = CONNECTION_PIPE; - } - - if (c->type == CONNECTION_TCP) { - c->max_connections = max_connections; - - c->fd = socket(AF_INET, SOCK_STREAM, 0); - if (c->fd == -1) { - LOG_ERROR("error creating socket: %s", strerror(errno)); - exit(-1); - } - - setsockopt(c->fd, - SOL_SOCKET, - SO_REUSEADDR, - (void *)&so_reuseaddr_option, - sizeof(int)); - - socket_nonblock(c->fd); - - memset(&c->sin, 0, sizeof(c->sin)); - c->sin.sin_family = AF_INET; - - 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); - exit(-1); - } - 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 %s to socket: %s", name, strerror(errno)); - exit(-1); - } - -#ifndef _WIN32 - int segsize = 65536; - setsockopt(c->fd, IPPROTO_TCP, TCP_MAXSEG, &segsize, sizeof(int)); -#endif - int window_size = 128 * 1024; - - /* These setsockopt()s must happen before the listen() */ - - setsockopt(c->fd, SOL_SOCKET, SO_SNDBUF, - (char *)&window_size, sizeof(window_size)); - setsockopt(c->fd, SOL_SOCKET, SO_RCVBUF, - (char *)&window_size, sizeof(window_size)); - - if (listen(c->fd, 1) == -1) { - LOG_ERROR("couldn't listen on socket: %s", strerror(errno)); - exit(-1); - } - } else if (c->type == CONNECTION_STDINOUT) { - c->fd = fileno(stdin); - -#ifdef _WIN32 - /* for win32 set stdin/stdout to binary mode */ - if (_setmode(_fileno(stdout), _O_BINARY) < 0) - LOG_WARNING("cannot change stdout mode to binary"); - if (_setmode(_fileno(stdin), _O_BINARY) < 0) - LOG_WARNING("cannot change stdin mode to binary"); - if (_setmode(_fileno(stderr), _O_BINARY) < 0) - LOG_WARNING("cannot change stderr mode to binary"); -#else - socket_nonblock(c->fd); -#endif - } else if (c->type == CONNECTION_PIPE) { -#ifdef _WIN32 - /* 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); -#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); - } -#endif - } - - /* add to the end of linked list */ - for (p = &services; *p; p = &(*p)->next) - ; - *p = c; - - return ERROR_OK; -} - -static int remove_services(void) -{ - struct service *c = services; - - /* loop service */ - while (c) { - struct service *next = c->next; - - if (c->name) - free(c->name); - - if (c->type == CONNECTION_PIPE) { - if (c->fd != -1) - close(c->fd); - } - if (c->port) - free(c->port); - - if (c->priv) - free(c->priv); - - /* delete service */ - free(c); - - /* remember the last service for unlinking */ - c = next; - } - - services = NULL; - - return ERROR_OK; -} - -int server_loop(struct command_context *command_context) -{ - struct service *service; - - bool poll_ok = true; - - /* used in select() */ - fd_set read_fds; - int fd_max; - - /* used in accept() */ - int retval; - -#ifndef _WIN32 - if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) - LOG_ERROR("couldn't set SIGPIPE to SIG_IGN"); -#endif - - while (!shutdown_openocd) { - /* monitor sockets for activity */ - fd_max = 0; - FD_ZERO(&read_fds); - - /* add service and connection fds to read_fds */ - for (service = services; service; service = service->next) { - if (service->fd != -1) { - /* listen for new connections */ - FD_SET(service->fd, &read_fds); - - if (service->fd > fd_max) - fd_max = service->fd; - } - - if (service->connections) { - struct connection *c; - - for (c = service->connections; c; c = c->next) { - /* check for activity on the connection */ - FD_SET(c->fd, &read_fds); - if (c->fd > fd_max) - fd_max = c->fd; - } - } - } - - struct timeval tv; - tv.tv_sec = 0; - if (poll_ok) { - /* we're just polling this iteration, this is faster on embedded - * hosts */ - tv.tv_usec = 0; - retval = socket_select(fd_max + 1, &read_fds, NULL, NULL, &tv); - } else { - /* Every 100ms, can be changed with "poll_period" command */ - tv.tv_usec = polling_period * 1000; - /* Only while we're sleeping we'll let others run */ - openocd_sleep_prelude(); - kept_alive(); - retval = socket_select(fd_max + 1, &read_fds, NULL, NULL, &tv); - openocd_sleep_postlude(); - } - - if (retval == -1) { -#ifdef _WIN32 - - errno = WSAGetLastError(); - - if (errno == WSAEINTR) - FD_ZERO(&read_fds); - else { - LOG_ERROR("error during select: %s", strerror(errno)); - exit(-1); - } -#else - - if (errno == EINTR) - FD_ZERO(&read_fds); - else { - LOG_ERROR("error during select: %s", strerror(errno)); - exit(-1); - } -#endif - } - - if (retval == 0) { - /* We only execute these callbacks when there was nothing to do or we timed - *out */ - target_call_timer_callbacks(); - process_jim_events(command_context); - - FD_ZERO(&read_fds); /* eCos leaves read_fds unchanged in this case! */ - - /* We timed out/there was nothing to do, timeout rather than poll next time - **/ - poll_ok = false; - } else { - /* There was something to do, next time we'll just poll */ - poll_ok = true; - } - - /* This is a simple back-off algorithm where we immediately - * re-poll if we did something this time around. - * - * This greatly improves performance of DCC. - */ - poll_ok = poll_ok || target_got_message(); - - for (service = services; service; service = service->next) { - /* handle new connections on listeners */ - if ((service->fd != -1) - && (FD_ISSET(service->fd, &read_fds))) { - if (service->max_connections != 0) - add_connection(service, command_context); - else { - if (service->type == CONNECTION_TCP) { - struct sockaddr_in sin; - socklen_t address_size = sizeof(sin); - int tmp_fd; - tmp_fd = accept(service->fd, - (struct sockaddr *)&service->sin, - &address_size); - close_socket(tmp_fd); - } - LOG_INFO( - "rejected '%s' connection, no more connections allowed", - service->name); - } - } - - /* handle activity on connections */ - if (service->connections) { - struct connection *c; - - for (c = service->connections; c; ) { - if ((FD_ISSET(c->fd, &read_fds)) || c->input_pending) { - retval = service->input(c); - if (retval != ERROR_OK) { - struct connection *next = c->next; - if (service->type == CONNECTION_PIPE || - service->type == CONNECTION_STDINOUT) { - /* if connection uses a pipe then - * shutdown openocd on error */ - shutdown_openocd = 1; - } - remove_connection(service, c); - LOG_INFO("dropped '%s' connection", - service->name); - c = next; - continue; - } - } - c = c->next; - } - } - } - -#ifdef _WIN32 - MSG msg; - while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { - if (msg.message == WM_QUIT) - shutdown_openocd = 1; - } -#endif - } - - return shutdown_openocd != 2 ? ERROR_OK : ERROR_FAIL; -} - -#ifdef _WIN32 -BOOL WINAPI ControlHandler(DWORD dwCtrlType) -{ - shutdown_openocd = 1; - return TRUE; -} -#endif - -void sig_handler(int sig) -{ - /* store only first signal that hits us */ - if (!last_signal) - last_signal = sig; - shutdown_openocd = 1; -} - -int server_preinit(void) -{ - /* this currently only calls WSAStartup on native win32 systems - * before any socket operations are performed. - * This is an issue if you call init in your config script */ - -#ifdef _WIN32 - WORD wVersionRequested; - WSADATA wsaData; - - wVersionRequested = MAKEWORD(2, 2); - - if (WSAStartup(wVersionRequested, &wsaData) != 0) { - LOG_ERROR("Failed to Open Winsock"); - exit(-1); - } - - /* register ctrl-c handler */ - SetConsoleCtrlHandler(ControlHandler, TRUE); - - signal(SIGBREAK, sig_handler); -#endif - signal(SIGINT, sig_handler); - signal(SIGTERM, sig_handler); - signal(SIGABRT, sig_handler); - - return ERROR_OK; -} - -int server_init(struct command_context *cmd_ctx) -{ - int ret = tcl_init(); - if (ERROR_OK != ret) - return ret; - - return telnet_init("Open On-Chip Debugger"); -} - -int server_quit(void) -{ - remove_services(); - target_quit(); - -#ifdef _WIN32 - WSACleanup(); - SetConsoleCtrlHandler(ControlHandler, FALSE); - - return ERROR_OK; -#endif - - /* return signal number so we can kill ourselves */ - return last_signal; -} - -void exit_on_signal(int sig) -{ -#ifndef _WIN32 - /* bring back default system handler and kill yourself */ - signal(sig, SIG_DFL); - kill(getpid(), sig); -#endif -} - -int connection_write(struct connection *connection, const void *data, int len) -{ - if (len == 0) { - /* successful no-op. Sockets and pipes behave differently here... */ - return 0; - } - if (connection->service->type == CONNECTION_TCP) - return write_socket(connection->fd_out, data, len); - else - return write(connection->fd_out, data, len); -} - -int connection_read(struct connection *connection, void *data, int len) -{ - if (connection->service->type == CONNECTION_TCP) - return read_socket(connection->fd, data, len); - else - return read(connection->fd, data, len); -} - -/* tell the server we want to shut down */ -COMMAND_HANDLER(handle_shutdown_command) -{ - LOG_USER("shutdown command invoked"); - - shutdown_openocd = 1; - - if (CMD_ARGC == 1) { - if (!strcmp(CMD_ARGV[0], "error")) { - shutdown_openocd = 2; - return ERROR_FAIL; - } - } - - return ERROR_COMMAND_CLOSE_CONNECTION; -} - -COMMAND_HANDLER(handle_poll_period_command) -{ - if (CMD_ARGC == 0) - LOG_WARNING("You need to set a period value"); - else - COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], polling_period); - - LOG_INFO("set servers polling period to %ums", polling_period); - - 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", - .handler = &handle_shutdown_command, - .mode = COMMAND_ANY, - .usage = "", - .help = "shut the server down", - }, - { - .name = "poll_period", - .handler = &handle_poll_period_command, - .mode = COMMAND_ANY, - .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 -}; - -int server_register_commands(struct command_context *cmd_ctx) -{ - int retval = telnet_register_commands(cmd_ctx); - if (ERROR_OK != retval) - return retval; - - retval = tcl_register_commands(cmd_ctx); - if (ERROR_OK != retval) - return retval; - - retval = jsp_register_commands(cmd_ctx); - if (ERROR_OK != retval) - return retval; - - return register_commands(cmd_ctx, NULL, server_command_handlers); -} - -COMMAND_HELPER(server_port_command, unsigned short *out) -{ - switch (CMD_ARGC) { - case 0: - command_print(CMD_CTX, "%d", *out); - break; - case 1: - { - uint16_t port; - COMMAND_PARSE_NUMBER(u16, CMD_ARGV[0], port); - *out = port; - break; - } - default: - return ERROR_COMMAND_SYNTAX_ERROR; - } - return ERROR_OK; -} - -COMMAND_HELPER(server_pipe_command, char **out) -{ - switch (CMD_ARGC) { - case 0: - command_print(CMD_CTX, "%s", *out); - break; - case 1: - { - if (CMD_CTX->mode == COMMAND_EXEC) { - LOG_WARNING("unable to change server port after init"); - return ERROR_COMMAND_ARGUMENT_INVALID; - } - free(*out); - *out = strdup(CMD_ARGV[0]); - break; - } - default: - return ERROR_COMMAND_SYNTAX_ERROR; - } - return ERROR_OK; -} diff --git a/src/server/server.h b/src/server/server.h deleted file mode 100644 index 68ad16d55..000000000 --- a/src/server/server.h +++ /dev/null @@ -1,112 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * Copyright (C) 2007,2008 Øyvind Harboe * - * oyvind.harboe@zylin.com * - * * - * Copyright (C) 2008 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 OPENOCD_SERVER_SERVER_H -#define OPENOCD_SERVER_SERVER_H - -#include - -#ifdef HAVE_NETINET_IN_H -#include -#endif - -enum connection_type { - CONNECTION_TCP, - CONNECTION_PIPE, - CONNECTION_STDINOUT -}; - -#define CONNECTION_LIMIT_UNLIMITED (-1) - -struct connection { - int fd; - int fd_out; /* When using pipes we're writing to a different fd */ - struct sockaddr_in sin; - struct command_context *cmd_ctx; - struct service *service; - int input_pending; - void *priv; - struct connection *next; -}; - -typedef int (*new_connection_handler_t)(struct connection *connection); -typedef int (*input_handler_t)(struct connection *connection); -typedef int (*connection_closed_handler_t)(struct connection *connection); - -struct service { - char *name; - enum connection_type type; - char *port; - unsigned short portnumber; - int fd; - struct sockaddr_in sin; - int max_connections; - struct connection *connections; - new_connection_handler_t new_connection; - input_handler_t input; - connection_closed_handler_t connection_closed; - void *priv; - struct service *next; -}; - -int add_service(char *name, const char *port, - int max_connections, new_connection_handler_t new_connection_handler, - input_handler_t in_handler, connection_closed_handler_t close_handler, - void *priv); - -int server_preinit(void); -int server_init(struct command_context *cmd_ctx); -int server_quit(void); -void exit_on_signal(int); - -int server_loop(struct command_context *command_context); - -int server_register_commands(struct command_context *context); - -int connection_write(struct connection *connection, const void *data, int len); -int connection_read(struct connection *connection, void *data, int len); - -/** - * Used by server_loop(), defined in server_stubs.c - */ -void openocd_sleep_prelude(void); -/** - * Used by server_loop(), defined in server_stubs.c - */ -void openocd_sleep_postlude(void); - -/** - * Defines an extended command handler function declaration to enable - * access to (and manipulation of) the server port number. - * Call server_port like a normal COMMAND_HANDLER with an extra @a out parameter - * to receive the specified port number. - */ -COMMAND_HELPER(server_pipe_command, char **out); - -COMMAND_HELPER(server_port_command, unsigned short *out); - -#define ERROR_SERVER_REMOTE_CLOSED (-400) -#define ERROR_CONNECTION_REJECTED (-401) - -#endif /* OPENOCD_SERVER_SERVER_H */ diff --git a/src/server/server_stubs.c b/src/server/server_stubs.c deleted file mode 100644 index a4c017289..000000000 --- a/src/server/server_stubs.c +++ /dev/null @@ -1,30 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2009 Zachary T Welch * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 -#include -#endif -#include "server.h" - -void openocd_sleep_prelude(void) -{ - /* no-op */ -} -void openocd_sleep_postlude(void) -{ - /* no-op */ -} diff --git a/src/server/startup.tcl b/src/server/startup.tcl deleted file mode 100644 index 64ace4079..000000000 --- a/src/server/startup.tcl +++ /dev/null @@ -1,10 +0,0 @@ -# Defines basic Tcl procs for OpenOCD server modules - -# Handle GDB 'R' packet. Can be overridden by configuration script, -# but it's not something one would expect target scripts to do -# normally -proc ocd_gdb_restart {target_id} { - # Fix!!! we're resetting all targets here! Really we should reset only - # one target - reset halt -} diff --git a/src/server/tcl_server.c b/src/server/tcl_server.c deleted file mode 100644 index 15a8736fe..000000000 --- a/src/server/tcl_server.c +++ /dev/null @@ -1,361 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2010 Øyvind Harboe * - * oyvind.harboe@zylin.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "tcl_server.h" -#include -#include - -#define TCL_SERVER_VERSION "TCL Server 0.1" -#define TCL_LINE_INITIAL (4*1024) -#define TCL_LINE_MAX (4*1024*1024) - -struct tcl_connection { - int tc_linedrop; - int tc_lineoffset; - int tc_line_size; - char *tc_line; - int tc_outerror;/* flag an output error */ - enum target_state tc_laststate; - bool tc_notify; - bool tc_trace; -}; - -static char *tcl_port; - -/* handlers */ -static int tcl_new_connection(struct connection *connection); -static int tcl_input(struct connection *connection); -static int tcl_output(struct connection *connection, const void *buf, ssize_t len); -static int tcl_closed(struct connection *connection); - -static int tcl_target_callback_event_handler(struct target *target, - enum target_event event, void *priv) -{ - struct connection *connection = priv; - struct tcl_connection *tclc; - char buf[256]; - - tclc = connection->priv; - - if (tclc->tc_notify) { - snprintf(buf, sizeof(buf), "type target_event event %s\r\n\x1a", target_event_name(event)); - tcl_output(connection, buf, strlen(buf)); - } - - if (tclc->tc_laststate != target->state) { - tclc->tc_laststate = target->state; - if (tclc->tc_notify) { - snprintf(buf, sizeof(buf), "type target_state state %s\r\n\x1a", target_state_name(target)); - tcl_output(connection, buf, strlen(buf)); - } - } - - return ERROR_OK; -} - -static int tcl_target_callback_reset_handler(struct target *target, - enum target_reset_mode reset_mode, void *priv) -{ - struct connection *connection = priv; - struct tcl_connection *tclc; - char buf[256]; - - tclc = connection->priv; - - if (tclc->tc_notify) { - snprintf(buf, sizeof(buf), "type target_reset mode %s\r\n\x1a", target_reset_mode_name(reset_mode)); - tcl_output(connection, buf, strlen(buf)); - } - - return ERROR_OK; -} - -static int tcl_target_callback_trace_handler(struct target *target, - size_t len, uint8_t *data, void *priv) -{ - struct connection *connection = priv; - struct tcl_connection *tclc; - char *header = "type target_trace data "; - char *trailer = "\r\n\x1a"; - size_t hex_len = len * 2 + 1; - size_t max_len = hex_len + strlen(header) + strlen(trailer); - char *buf, *hex; - - tclc = connection->priv; - - if (tclc->tc_trace) { - hex = malloc(hex_len); - buf = malloc(max_len); - hexify(hex, (const char *)data, len, hex_len); - snprintf(buf, max_len, "%s%s%s", header, hex, trailer); - tcl_output(connection, buf, strlen(buf)); - free(hex); - free(buf); - } - - return ERROR_OK; -} - -/* write data out to a socket. - * - * this is a blocking write, so the return value must equal the length, if - * that is not the case then flag the connection with an output error. - */ -int tcl_output(struct connection *connection, const void *data, ssize_t len) -{ - ssize_t wlen; - struct tcl_connection *tclc; - - tclc = connection->priv; - if (tclc->tc_outerror) - return ERROR_SERVER_REMOTE_CLOSED; - - wlen = connection_write(connection, data, len); - - if (wlen == len) - return ERROR_OK; - - LOG_ERROR("error during write: %d != %d", (int)wlen, (int)len); - tclc->tc_outerror = 1; - return ERROR_SERVER_REMOTE_CLOSED; -} - -/* connections */ -static int tcl_new_connection(struct connection *connection) -{ - struct tcl_connection *tclc; - - tclc = calloc(1, sizeof(struct tcl_connection)); - if (tclc == NULL) - return ERROR_CONNECTION_REJECTED; - - tclc->tc_line_size = TCL_LINE_INITIAL; - tclc->tc_line = malloc(tclc->tc_line_size); - if (tclc->tc_line == NULL) { - free(tclc); - return ERROR_CONNECTION_REJECTED; - } - - connection->priv = tclc; - - struct target *target = get_target_by_num(connection->cmd_ctx->current_target); - if (target != NULL) - tclc->tc_laststate = target->state; - - /* store the connection object on cmd_ctx so we can access it from command handlers */ - connection->cmd_ctx->output_handler_priv = connection; - - target_register_event_callback(tcl_target_callback_event_handler, connection); - target_register_reset_callback(tcl_target_callback_reset_handler, connection); - target_register_trace_callback(tcl_target_callback_trace_handler, connection); - - return ERROR_OK; -} - -static int tcl_input(struct connection *connection) -{ - Jim_Interp *interp = (Jim_Interp *)connection->cmd_ctx->interp; - int retval; - int i; - ssize_t rlen; - const char *result; - int reslen; - struct tcl_connection *tclc; - unsigned char in[256]; - char *tc_line_new; - int tc_line_size_new; - - rlen = connection_read(connection, &in, sizeof(in)); - if (rlen <= 0) { - if (rlen < 0) - LOG_ERROR("error during read: %s", strerror(errno)); - return ERROR_SERVER_REMOTE_CLOSED; - } - - tclc = connection->priv; - if (tclc == NULL) - return ERROR_CONNECTION_REJECTED; - - /* push as much data into the line as possible */ - for (i = 0; i < rlen; i++) { - /* buffer the data */ - tclc->tc_line[tclc->tc_lineoffset] = in[i]; - if (tclc->tc_lineoffset < tclc->tc_line_size) { - tclc->tc_lineoffset++; - } else if (tclc->tc_line_size >= TCL_LINE_MAX) { - /* maximum line size reached, drop line */ - tclc->tc_linedrop = 1; - } else { - /* grow line buffer: exponential below 1 MB, linear above */ - if (tclc->tc_line_size <= 1*1024*1024) - tc_line_size_new = tclc->tc_line_size * 2; - else - tc_line_size_new = tclc->tc_line_size + 1*1024*1024; - - if (tc_line_size_new > TCL_LINE_MAX) - tc_line_size_new = TCL_LINE_MAX; - - tc_line_new = realloc(tclc->tc_line, tc_line_size_new); - if (tc_line_new == NULL) { - tclc->tc_linedrop = 1; - } else { - tclc->tc_line = tc_line_new; - tclc->tc_line_size = tc_line_size_new; - tclc->tc_lineoffset++; - } - - } - - /* ctrl-z is end of command. When testing from telnet, just - * press ctrl-z a couple of times first to put telnet into the - * mode where it will send 0x1a in response to pressing ctrl-z - */ - if (in[i] != '\x1a') - continue; - - /* process the line */ - if (tclc->tc_linedrop) { -#define ESTR "line too long\n" - retval = tcl_output(connection, ESTR, sizeof(ESTR)); - if (retval != ERROR_OK) - return retval; -#undef ESTR - } else { - tclc->tc_line[tclc->tc_lineoffset-1] = '\0'; - command_run_line(connection->cmd_ctx, tclc->tc_line); - result = Jim_GetString(Jim_GetResult(interp), &reslen); - retval = tcl_output(connection, result, reslen); - if (retval != ERROR_OK) - return retval; - /* Always output ctrl-d as end of line to allow multiline results */ - tcl_output(connection, "\x1a", 1); - } - - tclc->tc_lineoffset = 0; - tclc->tc_linedrop = 0; - } - - return ERROR_OK; -} - -static int tcl_closed(struct connection *connection) -{ - struct tcl_connection *tclc; - tclc = connection->priv; - - /* cleanup connection context */ - if (tclc) { - free(tclc->tc_line); - free(tclc); - connection->priv = NULL; - } - - target_unregister_event_callback(tcl_target_callback_event_handler, connection); - target_unregister_reset_callback(tcl_target_callback_reset_handler, connection); - target_unregister_trace_callback(tcl_target_callback_trace_handler, connection); - - return ERROR_OK; -} - -int tcl_init(void) -{ - if (strcmp(tcl_port, "disabled") == 0) { - LOG_INFO("tcl server disabled"); - return ERROR_OK; - } - - return add_service("tcl", tcl_port, CONNECTION_LIMIT_UNLIMITED, - &tcl_new_connection, &tcl_input, - &tcl_closed, NULL); -} - -COMMAND_HANDLER(handle_tcl_port_command) -{ - return CALL_COMMAND_HANDLER(server_pipe_command, &tcl_port); -} - -COMMAND_HANDLER(handle_tcl_notifications_command) -{ - struct connection *connection = NULL; - struct tcl_connection *tclc = NULL; - - if (CMD_CTX->output_handler_priv != NULL) - connection = CMD_CTX->output_handler_priv; - - if (connection != NULL && !strcmp(connection->service->name, "tcl")) { - tclc = connection->priv; - return CALL_COMMAND_HANDLER(handle_command_parse_bool, &tclc->tc_notify, "Target Notification output "); - } else { - LOG_ERROR("%s: can only be called from the tcl server", CMD_NAME); - return ERROR_COMMAND_SYNTAX_ERROR; - } -} - -COMMAND_HANDLER(handle_tcl_trace_command) -{ - struct connection *connection = NULL; - struct tcl_connection *tclc = NULL; - - if (CMD_CTX->output_handler_priv != NULL) - connection = CMD_CTX->output_handler_priv; - - if (connection != NULL && !strcmp(connection->service->name, "tcl")) { - tclc = connection->priv; - return CALL_COMMAND_HANDLER(handle_command_parse_bool, &tclc->tc_trace, "Target trace output "); - } else { - LOG_ERROR("%s: can only be called from the tcl server", CMD_NAME); - return ERROR_COMMAND_SYNTAX_ERROR; - } -} - -static const struct command_registration tcl_command_handlers[] = { - { - .name = "tcl_port", - .handler = handle_tcl_port_command, - .mode = COMMAND_ANY, - .help = "Specify port on which to listen " - "for incoming Tcl syntax. " - "Read help on 'gdb_port'.", - .usage = "[port_num]", - }, - { - .name = "tcl_notifications", - .handler = handle_tcl_notifications_command, - .mode = COMMAND_EXEC, - .help = "Target Notification output", - .usage = "[on|off]", - }, - { - .name = "tcl_trace", - .handler = handle_tcl_trace_command, - .mode = COMMAND_EXEC, - .help = "Target trace output", - .usage = "[on|off]", - }, - COMMAND_REGISTRATION_DONE -}; - -int tcl_register_commands(struct command_context *cmd_ctx) -{ - tcl_port = strdup("6666"); - return register_commands(cmd_ctx, NULL, tcl_command_handlers); -} diff --git a/src/server/tcl_server.h b/src/server/tcl_server.h deleted file mode 100644 index 422c794ee..000000000 --- a/src/server/tcl_server.h +++ /dev/null @@ -1,26 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2008 * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#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 /* OPENOCD_SERVER_TCL_SERVER_H */ diff --git a/src/server/telnet_server.c b/src/server/telnet_server.c deleted file mode 100644 index 0f5769a20..000000000 --- a/src/server/telnet_server.c +++ /dev/null @@ -1,682 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * Copyright (C) 2007-2010 Øyvind Harboe * - * oyvind.harboe@zylin.com * - * * - * Copyright (C) 2008 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "telnet_server.h" -#include -#include - -static char *telnet_port; - -static char *negotiate = - "\xFF\xFB\x03" /* IAC WILL Suppress Go Ahead */ - "\xFF\xFB\x01" /* IAC WILL Echo */ - "\xFF\xFD\x03" /* IAC DO Suppress Go Ahead */ - "\xFF\xFE\x01"; /* IAC DON'T Echo */ - -#define CTRL(c) (c - '@') -#define TELNET_HISTORY ".openocd_history" - -/* The only way we can detect that the socket is closed is the first time - * we write to it, we will fail. Subsequent write operations will - * succeed. Shudder! - */ -static int telnet_write(struct connection *connection, const void *data, - int len) -{ - struct telnet_connection *t_con = connection->priv; - if (t_con->closed) - return ERROR_SERVER_REMOTE_CLOSED; - - if (connection_write(connection, data, len) == len) - return ERROR_OK; - t_con->closed = 1; - return ERROR_SERVER_REMOTE_CLOSED; -} - -static int telnet_prompt(struct connection *connection) -{ - struct telnet_connection *t_con = connection->priv; - - return telnet_write(connection, t_con->prompt, strlen(t_con->prompt)); -} - -static int telnet_outputline(struct connection *connection, const char *line) -{ - int len; - - /* process lines in buffer */ - while (*line) { - char *line_end = strchr(line, '\n'); - - if (line_end) - len = line_end-line; - else - len = strlen(line); - - telnet_write(connection, line, len); - if (line_end) { - telnet_write(connection, "\r\n", 2); - line += len + 1; - } else - line += len; - } - - return ERROR_OK; -} - -static int telnet_output(struct command_context *cmd_ctx, const char *line) -{ - struct connection *connection = cmd_ctx->output_handler_priv; - - return telnet_outputline(connection, line); -} - -static void telnet_log_callback(void *priv, const char *file, unsigned line, - const char *function, const char *string) -{ - struct connection *connection = priv; - struct telnet_connection *t_con = connection->priv; - int i; - - /* if there is no prompt, simply output the message */ - if (t_con->line_cursor < 0) { - telnet_outputline(connection, string); - return; - } - - /* clear the command line */ - for (i = strlen(t_con->prompt) + t_con->line_size; i > 0; i -= 16) - telnet_write(connection, "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b", i > 16 ? 16 : i); - for (i = strlen(t_con->prompt) + t_con->line_size; i > 0; i -= 16) - telnet_write(connection, " ", i > 16 ? 16 : i); - for (i = strlen(t_con->prompt) + t_con->line_size; i > 0; i -= 16) - telnet_write(connection, "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b", i > 16 ? 16 : i); - - /* output the message */ - telnet_outputline(connection, string); - - /* put the command line to its previous state */ - telnet_prompt(connection); - telnet_write(connection, t_con->line, t_con->line_size); - for (i = t_con->line_size; i > t_con->line_cursor; i--) - telnet_write(connection, "\b", 1); -} - -static void telnet_load_history(struct telnet_connection *t_con) -{ - FILE *histfp; - char buffer[TELNET_BUFFER_SIZE]; - int i = 0; - - char *history = get_home_dir(TELNET_HISTORY); - - if (history == NULL) { - LOG_INFO("unable to get user home directory, telnet history will be disabled"); - return; - } - - histfp = fopen(history, "rb"); - - if (histfp) { - - while (fgets(buffer, sizeof(buffer), histfp) != NULL) { - - char *p = strchr(buffer, '\n'); - if (p) - *p = '\0'; - if (buffer[0] && i < TELNET_LINE_HISTORY_SIZE) - t_con->history[i++] = strdup(buffer); - } - - t_con->next_history = i; - t_con->next_history %= TELNET_LINE_HISTORY_SIZE; - /* try to set to last entry - 1, that way we skip over any exit/shutdown cmds */ - t_con->current_history = t_con->next_history > 0 ? i - 1 : 0; - fclose(histfp); - } - - free(history); -} - -static void telnet_save_history(struct telnet_connection *t_con) -{ - FILE *histfp; - int i; - int num; - - char *history = get_home_dir(TELNET_HISTORY); - - if (history == NULL) { - LOG_INFO("unable to get user home directory, telnet history will be disabled"); - return; - } - - histfp = fopen(history, "wb"); - - if (histfp) { - - num = TELNET_LINE_HISTORY_SIZE; - i = t_con->current_history + 1; - i %= TELNET_LINE_HISTORY_SIZE; - - while (t_con->history[i] == NULL && num > 0) { - i++; - i %= TELNET_LINE_HISTORY_SIZE; - num--; - } - - if (num > 0) { - for (; num > 0; num--) { - fprintf(histfp, "%s\n", t_con->history[i]); - i++; - i %= TELNET_LINE_HISTORY_SIZE; - } - } - fclose(histfp); - } - - free(history); -} - -static int telnet_new_connection(struct connection *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 */ - telnet_connection->closed = 0; - telnet_connection->line_size = 0; - telnet_connection->line_cursor = 0; - telnet_connection->option_size = 0; - telnet_connection->prompt = strdup("> "); - telnet_connection->state = TELNET_STATE_DATA; - - /* output goes through telnet connection */ - command_set_output_handler(connection->cmd_ctx, telnet_output, connection); - - /* negotiate telnet options */ - telnet_write(connection, negotiate, strlen(negotiate)); - - /* print connection banner */ - if (telnet_service->banner) { - telnet_write(connection, telnet_service->banner, strlen(telnet_service->banner)); - telnet_write(connection, "\r\n", 2); - } - - /* the prompt is always placed at the line beginning */ - telnet_write(connection, "\r", 1); - telnet_prompt(connection); - - /* initialize history */ - for (i = 0; i < TELNET_LINE_HISTORY_SIZE; i++) - telnet_connection->history[i] = NULL; - telnet_connection->next_history = 0; - telnet_connection->current_history = 0; - telnet_load_history(telnet_connection); - - log_add_callback(telnet_log_callback, connection); - - return ERROR_OK; -} - -static void telnet_clear_line(struct connection *connection, - struct telnet_connection *t_con) -{ - /* move to end of line */ - if (t_con->line_cursor < t_con->line_size) - telnet_write(connection, - t_con->line + t_con->line_cursor, - t_con->line_size - t_con->line_cursor); - - /* backspace, overwrite with space, backspace */ - while (t_con->line_size > 0) { - telnet_write(connection, "\b \b", 3); - t_con->line_size--; - } - t_con->line_cursor = 0; -} - -static void telnet_history_go(struct connection *connection, int idx) -{ - struct telnet_connection *t_con = connection->priv; - - if (t_con->history[idx]) { - telnet_clear_line(connection, t_con); - t_con->line_size = strlen(t_con->history[idx]); - t_con->line_cursor = t_con->line_size; - memcpy(t_con->line, t_con->history[idx], t_con->line_size); - telnet_write(connection, t_con->line, t_con->line_size); - t_con->current_history = idx; - } - t_con->state = TELNET_STATE_DATA; -} - -static void telnet_history_up(struct connection *connection) -{ - struct telnet_connection *t_con = connection->priv; - - int last_history = (t_con->current_history > 0) ? - t_con->current_history - 1 : - TELNET_LINE_HISTORY_SIZE-1; - telnet_history_go(connection, last_history); -} - -static void telnet_history_down(struct connection *connection) -{ - struct telnet_connection *t_con = connection->priv; - - int next_history = (t_con->current_history + 1) % TELNET_LINE_HISTORY_SIZE; - telnet_history_go(connection, next_history); -} - -static int telnet_input(struct connection *connection) -{ - int bytes_read; - unsigned char buffer[TELNET_BUFFER_SIZE]; - unsigned char *buf_p; - struct telnet_connection *t_con = connection->priv; - struct command_context *command_context = connection->cmd_ctx; - - bytes_read = connection_read(connection, buffer, TELNET_BUFFER_SIZE); - - if (bytes_read == 0) - return ERROR_SERVER_REMOTE_CLOSED; - else if (bytes_read == -1) { - LOG_ERROR("error during read: %s", strerror(errno)); - return ERROR_SERVER_REMOTE_CLOSED; - } - - buf_p = buffer; - while (bytes_read) { - switch (t_con->state) { - case TELNET_STATE_DATA: - if (*buf_p == 0xff) - t_con->state = TELNET_STATE_IAC; - else { - if (isprint(*buf_p)) { /* printable character */ - /* watch buffer size leaving one spare character for - * string null termination */ - if (t_con->line_size == TELNET_LINE_MAX_SIZE-1) { - /* output audible bell if buffer is full - * "\a" does not work, at least on windows */ - telnet_write(connection, "\x07", 1); - } else if (t_con->line_cursor == t_con->line_size) { - telnet_write(connection, buf_p, 1); - t_con->line[t_con->line_size++] = *buf_p; - t_con->line_cursor++; - } else { - int i; - memmove(t_con->line + t_con->line_cursor + 1, - t_con->line + t_con->line_cursor, - t_con->line_size - t_con->line_cursor); - t_con->line[t_con->line_cursor] = *buf_p; - t_con->line_size++; - telnet_write(connection, - t_con->line + t_con->line_cursor, - t_con->line_size - t_con->line_cursor); - t_con->line_cursor++; - for (i = t_con->line_cursor; i < t_con->line_size; i++) - telnet_write(connection, "\b", 1); - } - } else { /* non-printable */ - if (*buf_p == 0x1b) { /* escape */ - t_con->state = TELNET_STATE_ESCAPE; - t_con->last_escape = '\x00'; - } else if ((*buf_p == 0xd) || (*buf_p == 0xa)) { /* CR/LF */ - int retval; - - /* skip over combinations with CR/LF and NUL characters */ - if ((bytes_read > 1) && ((*(buf_p + 1) == 0xa) || - (*(buf_p + 1) == 0xd))) { - buf_p++; - bytes_read--; - } - if ((bytes_read > 1) && (*(buf_p + 1) == 0)) { - buf_p++; - bytes_read--; - } - t_con->line[t_con->line_size] = 0; - - telnet_write(connection, "\r\n\x00", 3); - - if (strcmp(t_con->line, "history") == 0) { - int i; - for (i = 1; i < TELNET_LINE_HISTORY_SIZE; i++) { - /* the t_con->next_history line contains empty string - * (unless NULL), thus it is not printed */ - char *history_line = t_con->history[(t_con-> - next_history + i) % - TELNET_LINE_HISTORY_SIZE]; - if (history_line) { - telnet_write(connection, history_line, - strlen(history_line)); - telnet_write(connection, "\r\n\x00", 3); - } - } - t_con->line_size = 0; - t_con->line_cursor = 0; - continue; - } - - /* save only non-blank not repeating lines in the history */ - char *prev_line = t_con->history[(t_con->current_history > 0) ? - t_con->current_history - 1 : TELNET_LINE_HISTORY_SIZE-1]; - if (*t_con->line && (prev_line == NULL || - strcmp(t_con->line, prev_line))) { - /* if the history slot is already taken, free it */ - if (t_con->history[t_con->next_history]) - free(t_con->history[t_con->next_history]); - - /* add line to history */ - t_con->history[t_con->next_history] = strdup(t_con->line); - - /* wrap history at TELNET_LINE_HISTORY_SIZE */ - t_con->next_history = (t_con->next_history + 1) % - TELNET_LINE_HISTORY_SIZE; - - /* current history line starts at the new entry */ - t_con->current_history = - t_con->next_history; - - if (t_con->history[t_con->current_history]) - free(t_con->history[t_con->current_history]); - t_con->history[t_con->current_history] = strdup(""); - } - - t_con->line_size = 0; - - /* to suppress prompt in log callback during command execution */ - t_con->line_cursor = -1; - - if (strcmp(t_con->line, "shutdown") == 0) - telnet_save_history(t_con); - - retval = command_run_line(command_context, t_con->line); - - t_con->line_cursor = 0; - - if (retval == ERROR_COMMAND_CLOSE_CONNECTION) - return ERROR_SERVER_REMOTE_CLOSED; - - /* the prompt is always * placed at the line beginning */ - telnet_write(connection, "\r", 1); - - retval = telnet_prompt(connection); - if (retval == ERROR_SERVER_REMOTE_CLOSED) - return ERROR_SERVER_REMOTE_CLOSED; - - } else if ((*buf_p == 0x7f) || (*buf_p == 0x8)) { /* delete character */ - if (t_con->line_cursor > 0) { - if (t_con->line_cursor != t_con->line_size) { - int i; - telnet_write(connection, "\b", 1); - t_con->line_cursor--; - t_con->line_size--; - memmove(t_con->line + t_con->line_cursor, - t_con->line + t_con->line_cursor + 1, - t_con->line_size - - t_con->line_cursor); - - telnet_write(connection, - t_con->line + t_con->line_cursor, - t_con->line_size - - t_con->line_cursor); - telnet_write(connection, " \b", 2); - for (i = t_con->line_cursor; i < t_con->line_size; i++) - telnet_write(connection, "\b", 1); - } else { - t_con->line_size--; - t_con->line_cursor--; - /* back space: move the 'printer' head one char - * back, overwrite with space, move back again */ - telnet_write(connection, "\b \b", 3); - } - } - } else if (*buf_p == 0x15) /* clear line */ - telnet_clear_line(connection, t_con); - else if (*buf_p == CTRL('B')) { /* cursor left */ - if (t_con->line_cursor > 0) { - telnet_write(connection, "\b", 1); - t_con->line_cursor--; - } - t_con->state = TELNET_STATE_DATA; - } else if (*buf_p == CTRL('F')) { /* cursor right */ - if (t_con->line_cursor < t_con->line_size) - telnet_write(connection, t_con->line + t_con->line_cursor++, 1); - t_con->state = TELNET_STATE_DATA; - } else if (*buf_p == CTRL('P')) /* cursor up */ - telnet_history_up(connection); - else if (*buf_p == CTRL('N')) /* cursor down */ - telnet_history_down(connection); - else - LOG_DEBUG("unhandled nonprintable: %2.2x", *buf_p); - } - } - break; - case TELNET_STATE_IAC: - switch (*buf_p) { - case 0xfe: - t_con->state = TELNET_STATE_DONT; - break; - case 0xfd: - t_con->state = TELNET_STATE_DO; - break; - case 0xfc: - t_con->state = TELNET_STATE_WONT; - break; - case 0xfb: - t_con->state = TELNET_STATE_WILL; - break; - } - break; - case TELNET_STATE_SB: - break; - case TELNET_STATE_SE: - break; - case TELNET_STATE_WILL: - case TELNET_STATE_WONT: - case TELNET_STATE_DO: - case TELNET_STATE_DONT: - t_con->state = TELNET_STATE_DATA; - break; - case TELNET_STATE_ESCAPE: - if (t_con->last_escape == '[') { - if (*buf_p == 'D') { /* cursor left */ - if (t_con->line_cursor > 0) { - telnet_write(connection, "\b", 1); - t_con->line_cursor--; - } - t_con->state = TELNET_STATE_DATA; - } else if (*buf_p == 'C') { /* cursor right */ - if (t_con->line_cursor < t_con->line_size) - telnet_write(connection, - t_con->line + t_con->line_cursor++, 1); - t_con->state = TELNET_STATE_DATA; - } else if (*buf_p == 'A') { /* cursor up */ - telnet_history_up(connection); - } else if (*buf_p == 'B') { /* cursor down */ - telnet_history_down(connection); - } else if (*buf_p == '3') - t_con->last_escape = *buf_p; - else - t_con->state = TELNET_STATE_DATA; - } else if (t_con->last_escape == '3') { - /* Remove character */ - if (*buf_p == '~') { - if (t_con->line_cursor < t_con->line_size) { - int i; - t_con->line_size--; - /* remove char from line buffer */ - memmove(t_con->line + t_con->line_cursor, - t_con->line + t_con->line_cursor + 1, - t_con->line_size - t_con->line_cursor); - - /* print remainder of buffer */ - telnet_write(connection, t_con->line + t_con->line_cursor, - t_con->line_size - t_con->line_cursor); - /* overwrite last char with whitespace */ - telnet_write(connection, " \b", 2); - - /* move back to cursor position*/ - for (i = t_con->line_cursor; i < t_con->line_size; i++) - telnet_write(connection, "\b", 1); - } - - t_con->state = TELNET_STATE_DATA; - } else - t_con->state = TELNET_STATE_DATA; - } else if (t_con->last_escape == '\x00') { - if (*buf_p == '[') - t_con->last_escape = *buf_p; - else - t_con->state = TELNET_STATE_DATA; - } else { - LOG_ERROR("BUG: unexpected value in t_con->last_escape"); - t_con->state = TELNET_STATE_DATA; - } - - break; - default: - LOG_ERROR("unknown telnet state"); - exit(-1); - } - - bytes_read--; - buf_p++; - } - - return ERROR_OK; -} - -static int telnet_connection_closed(struct connection *connection) -{ - struct telnet_connection *t_con = connection->priv; - int i; - - log_remove_callback(telnet_log_callback, connection); - - if (t_con->prompt) { - free(t_con->prompt); - t_con->prompt = NULL; - } - - /* save telnet history */ - telnet_save_history(t_con); - - for (i = 0; i < TELNET_LINE_HISTORY_SIZE; i++) { - if (t_con->history[i]) { - free(t_con->history[i]); - t_con->history[i] = NULL; - } - } - - /* if this connection registered a debug-message receiver delete it */ - delete_debug_msg_receiver(connection->cmd_ctx, NULL); - - if (connection->priv) { - free(connection->priv); - connection->priv = NULL; - } else - LOG_ERROR("BUG: connection->priv == NULL"); - - return ERROR_OK; -} - -int telnet_init(char *banner) -{ - if (strcmp(telnet_port, "disabled") == 0) { - LOG_INFO("telnet server disabled"); - return ERROR_OK; - } - - struct telnet_service *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, - telnet_service); -} - -/* daemon configuration command telnet_port */ -COMMAND_HANDLER(handle_telnet_port_command) -{ - return CALL_COMMAND_HANDLER(server_pipe_command, &telnet_port); -} - -COMMAND_HANDLER(handle_exit_command) -{ - return ERROR_COMMAND_CLOSE_CONNECTION; -} - -static const struct command_registration telnet_command_handlers[] = { - { - .name = "exit", - .handler = handle_exit_command, - .mode = COMMAND_EXEC, - .usage = "", - .help = "exit telnet session", - }, - { - .name = "telnet_port", - .handler = handle_telnet_port_command, - .mode = COMMAND_ANY, - .help = "Specify port on which to listen " - "for incoming telnet connections. " - "Read help on 'gdb_port'.", - .usage = "[port_num]", - }, - COMMAND_REGISTRATION_DONE -}; - -int telnet_register_commands(struct command_context *cmd_ctx) -{ - telnet_port = strdup("4444"); - return register_commands(cmd_ctx, NULL, telnet_command_handlers); -} diff --git a/src/server/telnet_server.h b/src/server/telnet_server.h deleted file mode 100644 index 04ba96570..000000000 --- a/src/server/telnet_server.h +++ /dev/null @@ -1,70 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * Copyright (C) 2007,2008 Øyvind Harboe * - * oyvind.harboe@zylin.com * - * * - * Copyright (C) 2008 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 OPENOCD_SERVER_TELNET_SERVER_H -#define OPENOCD_SERVER_TELNET_SERVER_H - -#include - -#define TELNET_BUFFER_SIZE (1024) - -#define TELNET_OPTION_MAX_SIZE (128) -#define TELNET_LINE_HISTORY_SIZE (128) -#define TELNET_LINE_MAX_SIZE (256) - -enum telnet_states { - TELNET_STATE_DATA, - TELNET_STATE_IAC, - TELNET_STATE_SB, - TELNET_STATE_SE, - TELNET_STATE_WILL, - TELNET_STATE_WONT, - TELNET_STATE_DO, - TELNET_STATE_DONT, - TELNET_STATE_ESCAPE, -}; - -struct telnet_connection { - char *prompt; - enum telnet_states state; - char line[TELNET_LINE_MAX_SIZE]; - int line_size; - int line_cursor; - char option[TELNET_OPTION_MAX_SIZE]; - int option_size; - char last_escape; - char *history[TELNET_LINE_HISTORY_SIZE]; - int next_history; - int current_history; - int closed; -}; - -struct telnet_service { - char *banner; -}; - -int telnet_init(char *banner); -int telnet_register_commands(struct command_context *command_context); - -#endif /* OPENOCD_SERVER_TELNET_SERVER_H */ diff --git a/src/svf/Makefile.am b/src/svf/Makefile.am deleted file mode 100644 index 3a14d2087..000000000 --- a/src/svf/Makefile.am +++ /dev/null @@ -1,8 +0,0 @@ -include $(top_srcdir)/common.mk - -METASOURCES = AUTO -noinst_LTLIBRARIES = libsvf.la -noinst_HEADERS = svf.h -libsvf_la_SOURCES = svf.c - -MAINTAINERCLEANFILES = $(srcdir)/Makefile.in diff --git a/src/svf/svf.c b/src/svf/svf.c deleted file mode 100644 index e7e815c10..000000000 --- a/src/svf/svf.c +++ /dev/null @@ -1,1578 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2009 by Simon Qian * - * SimonQian@SimonQian.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -/* The specification for SVF is available here: - * http://www.asset-intertech.com/support/svf.pdf - * Below, this document is refered to as the "SVF spec". - * - * The specification for XSVF is available here: - * http://www.xilinx.com/support/documentation/application_notes/xapp503.pdf - * Below, this document is refered to as the "XSVF spec". - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include "svf.h" -#include - -/* SVF command */ -enum svf_command { - ENDDR, - ENDIR, - FREQUENCY, - HDR, - HIR, - PIO, - PIOMAP, - RUNTEST, - SDR, - SIR, - STATE, - TDR, - TIR, - TRST, -}; - -static const char *svf_command_name[14] = { - "ENDDR", - "ENDIR", - "FREQUENCY", - "HDR", - "HIR", - "PIO", - "PIOMAP", - "RUNTEST", - "SDR", - "SIR", - "STATE", - "TDR", - "TIR", - "TRST" -}; - -enum trst_mode { - TRST_ON, - TRST_OFF, - TRST_Z, - TRST_ABSENT -}; - -static const char *svf_trst_mode_name[4] = { - "ON", - "OFF", - "Z", - "ABSENT" -}; - -struct svf_statemove { - tap_state_t from; - tap_state_t to; - uint32_t num_of_moves; - tap_state_t paths[8]; -}; - -/* - * These paths are from the SVF specification for the STATE command, to be - * used when the STATE command only includes the final state. The first - * element of the path is the "from" (current) state, and the last one is - * the "to" (target) state. - * - * All specified paths are the shortest ones in the JTAG spec, and are thus - * not (!!) exact matches for the paths used elsewhere in OpenOCD. Note - * that PAUSE-to-PAUSE transitions all go through UPDATE and then CAPTURE, - * which has specific effects on the various registers; they are not NOPs. - * - * Paths to RESET are disabled here. As elsewhere in OpenOCD, and in XSVF - * and many SVF implementations, we don't want to risk missing that state. - * To get to RESET, always we ignore the current state. - */ -static const struct svf_statemove svf_statemoves[] = { - /* from to num_of_moves, paths[8] */ -/* {TAP_RESET, TAP_RESET, 1, {TAP_RESET}}, */ - {TAP_RESET, TAP_IDLE, 2, {TAP_RESET, TAP_IDLE} }, - {TAP_RESET, TAP_DRPAUSE, 6, {TAP_RESET, TAP_IDLE, TAP_DRSELECT, - TAP_DRCAPTURE, TAP_DREXIT1, TAP_DRPAUSE} }, - {TAP_RESET, TAP_IRPAUSE, 7, {TAP_RESET, TAP_IDLE, TAP_DRSELECT, - TAP_IRSELECT, TAP_IRCAPTURE, - TAP_IREXIT1, TAP_IRPAUSE} }, - -/* {TAP_IDLE, TAP_RESET, 4, {TAP_IDLE, - * TAP_DRSELECT, TAP_IRSELECT, TAP_RESET}}, */ - {TAP_IDLE, TAP_IDLE, 1, {TAP_IDLE} }, - {TAP_IDLE, TAP_DRPAUSE, 5, {TAP_IDLE, TAP_DRSELECT, TAP_DRCAPTURE, - TAP_DREXIT1, TAP_DRPAUSE} }, - {TAP_IDLE, TAP_IRPAUSE, 6, {TAP_IDLE, TAP_DRSELECT, TAP_IRSELECT, - TAP_IRCAPTURE, TAP_IREXIT1, TAP_IRPAUSE} }, - -/* {TAP_DRPAUSE, TAP_RESET, 6, {TAP_DRPAUSE, - * TAP_DREXIT2, TAP_DRUPDATE, TAP_DRSELECT, TAP_IRSELECT, TAP_RESET}}, */ - {TAP_DRPAUSE, TAP_IDLE, 4, {TAP_DRPAUSE, TAP_DREXIT2, TAP_DRUPDATE, - TAP_IDLE} }, - {TAP_DRPAUSE, TAP_DRPAUSE, 7, {TAP_DRPAUSE, TAP_DREXIT2, TAP_DRUPDATE, - TAP_DRSELECT, TAP_DRCAPTURE, - TAP_DREXIT1, TAP_DRPAUSE} }, - {TAP_DRPAUSE, TAP_IRPAUSE, 8, {TAP_DRPAUSE, TAP_DREXIT2, TAP_DRUPDATE, - TAP_DRSELECT, TAP_IRSELECT, - TAP_IRCAPTURE, TAP_IREXIT1, TAP_IRPAUSE} }, - -/* {TAP_IRPAUSE, TAP_RESET, 6, {TAP_IRPAUSE, - * TAP_IREXIT2, TAP_IRUPDATE, TAP_DRSELECT, TAP_IRSELECT, TAP_RESET}}, */ - {TAP_IRPAUSE, TAP_IDLE, 4, {TAP_IRPAUSE, TAP_IREXIT2, TAP_IRUPDATE, - TAP_IDLE} }, - {TAP_IRPAUSE, TAP_DRPAUSE, 7, {TAP_IRPAUSE, TAP_IREXIT2, TAP_IRUPDATE, - TAP_DRSELECT, TAP_DRCAPTURE, - TAP_DREXIT1, TAP_DRPAUSE} }, - {TAP_IRPAUSE, TAP_IRPAUSE, 8, {TAP_IRPAUSE, TAP_IREXIT2, TAP_IRUPDATE, - TAP_DRSELECT, TAP_IRSELECT, - TAP_IRCAPTURE, TAP_IREXIT1, TAP_IRPAUSE} } -}; - -#define XXR_TDI (1 << 0) -#define XXR_TDO (1 << 1) -#define XXR_MASK (1 << 2) -#define XXR_SMASK (1 << 3) -struct svf_xxr_para { - int len; - int data_mask; - uint8_t *tdi; - uint8_t *tdo; - uint8_t *mask; - uint8_t *smask; -}; - -struct svf_para { - float frequency; - tap_state_t ir_end_state; - tap_state_t dr_end_state; - tap_state_t runtest_run_state; - tap_state_t runtest_end_state; - enum trst_mode trst_mode; - - struct svf_xxr_para hir_para; - struct svf_xxr_para hdr_para; - struct svf_xxr_para tir_para; - struct svf_xxr_para tdr_para; - struct svf_xxr_para sir_para; - struct svf_xxr_para sdr_para; -}; - -static struct svf_para svf_para; -static const struct svf_para svf_para_init = { -/* frequency, ir_end_state, dr_end_state, runtest_run_state, runtest_end_state, trst_mode */ - 0, TAP_IDLE, TAP_IDLE, TAP_IDLE, TAP_IDLE, TRST_Z, -/* hir_para */ -/* {len, data_mask, tdi, tdo, mask, smask}, */ - {0, 0, NULL, NULL, NULL, NULL}, -/* hdr_para */ -/* {len, data_mask, tdi, tdo, mask, smask}, */ - {0, 0, NULL, NULL, NULL, NULL}, -/* tir_para */ -/* {len, data_mask, tdi, tdo, mask, smask}, */ - {0, 0, NULL, NULL, NULL, NULL}, -/* tdr_para */ -/* {len, data_mask, tdi, tdo, mask, smask}, */ - {0, 0, NULL, NULL, NULL, NULL}, -/* sir_para */ -/* {len, data_mask, tdi, tdo, mask, smask}, */ - {0, 0, NULL, NULL, NULL, NULL}, -/* sdr_para */ -/* {len, data_mask, tdi, tdo, mask, smask}, */ - {0, 0, NULL, NULL, NULL, NULL}, -}; - -struct svf_check_tdo_para { - int line_num; /* used to record line number of the check operation */ - /* so more information could be printed */ - int enabled; /* check is enabled or not */ - int buffer_offset; /* buffer_offset to buffers */ - int bit_len; /* bit length to check */ -}; - -#define SVF_CHECK_TDO_PARA_SIZE 1024 -static struct svf_check_tdo_para *svf_check_tdo_para; -static int svf_check_tdo_para_index; - -static int svf_read_command_from_file(FILE *fd); -static int svf_check_tdo(void); -static int svf_add_check_para(uint8_t enabled, int buffer_offset, int bit_len); -static int svf_run_command(struct command_context *cmd_ctx, char *cmd_str); -static int svf_execute_tap(void); - -static FILE *svf_fd; -static char *svf_read_line; -static size_t svf_read_line_size; -static char *svf_command_buffer; -static size_t svf_command_buffer_size; -static int svf_line_number; -static int svf_getline(char **lineptr, size_t *n, FILE *stream); - -#define SVF_MAX_BUFFER_SIZE_TO_COMMIT (1024 * 1024) -static uint8_t *svf_tdi_buffer, *svf_tdo_buffer, *svf_mask_buffer; -static int svf_buffer_index, svf_buffer_size ; -static int svf_quiet; -static int svf_nil; -static int svf_ignore_error; - -/* Targetting particular tap */ -static int svf_tap_is_specified; -static int svf_set_padding(struct svf_xxr_para *para, int len, unsigned char tdi); - -/* Progress Indicator */ -static int svf_progress_enabled; -static long svf_total_lines; -static int svf_percentage; -static int svf_last_printed_percentage = -1; - -/* - * macro is used to print the svf hex buffer at desired debug level - * DEBUG, INFO, ERROR, USER - */ -#define SVF_BUF_LOG(_lvl, _buf, _nbits, _desc) \ - svf_hexbuf_print(LOG_LVL_##_lvl , __FILE__, __LINE__, __func__, _buf, _nbits, _desc) - -static void svf_hexbuf_print(int dbg_lvl, const char *file, unsigned line, - const char *function, const uint8_t *buf, - int bit_len, const char *desc) -{ - int j, len = 0; - int byte_len = DIV_ROUND_UP(bit_len, 8); - int msbits = bit_len % 8; - - /* allocate 2 bytes per hex digit */ - char *prbuf = malloc((byte_len * 2) + 2 + 1); - if (!prbuf) - return; - - /* print correct number of bytes, mask excess bits where applicable */ - uint8_t msb = buf[byte_len - 1] & (msbits ? (1 << msbits) - 1 : 0xff); - len = sprintf(prbuf, msbits <= 4 ? "0x%01"PRIx8 : "0x%02"PRIx8, msb); - for (j = byte_len - 2; j >= 0; j--) - len += sprintf(prbuf + len, "%02"PRIx8, buf[j]); - - log_printf_lf(dbg_lvl, file, line, function, "%8s = %s", desc ? desc : " ", prbuf); - - free(prbuf); -} - -static int svf_realloc_buffers(size_t len) -{ - void *ptr; - - if (svf_execute_tap() != ERROR_OK) - return ERROR_FAIL; - - ptr = realloc(svf_tdi_buffer, len); - if (!ptr) - return ERROR_FAIL; - svf_tdi_buffer = ptr; - - ptr = realloc(svf_tdo_buffer, len); - if (!ptr) - return ERROR_FAIL; - svf_tdo_buffer = ptr; - - ptr = realloc(svf_mask_buffer, len); - if (!ptr) - return ERROR_FAIL; - svf_mask_buffer = ptr; - - svf_buffer_size = len; - - return ERROR_OK; -} - -static void svf_free_xxd_para(struct svf_xxr_para *para) -{ - if (NULL != para) { - if (para->tdi != NULL) { - free(para->tdi); - para->tdi = NULL; - } - if (para->tdo != NULL) { - free(para->tdo); - para->tdo = NULL; - } - if (para->mask != NULL) { - free(para->mask); - para->mask = NULL; - } - if (para->smask != NULL) { - free(para->smask); - para->smask = NULL; - } - } -} - -int svf_add_statemove(tap_state_t state_to) -{ - tap_state_t state_from = cmd_queue_cur_state; - unsigned index_var; - - /* when resetting, be paranoid and ignore current state */ - if (state_to == TAP_RESET) { - if (svf_nil) - return ERROR_OK; - - jtag_add_tlr(); - return ERROR_OK; - } - - for (index_var = 0; index_var < ARRAY_SIZE(svf_statemoves); index_var++) { - if ((svf_statemoves[index_var].from == state_from) - && (svf_statemoves[index_var].to == state_to)) { - if (svf_nil) - continue; - /* recorded path includes current state ... avoid - *extra TCKs! */ - if (svf_statemoves[index_var].num_of_moves > 1) - jtag_add_pathmove(svf_statemoves[index_var].num_of_moves - 1, - svf_statemoves[index_var].paths + 1); - else - jtag_add_pathmove(svf_statemoves[index_var].num_of_moves, - svf_statemoves[index_var].paths); - return ERROR_OK; - } - } - LOG_ERROR("SVF: can not move to %s", tap_state_name(state_to)); - return ERROR_FAIL; -} - -COMMAND_HANDLER(handle_svf_command) -{ -#define SVF_MIN_NUM_OF_OPTIONS 1 -#define SVF_MAX_NUM_OF_OPTIONS 5 - int command_num = 0; - int ret = ERROR_OK; - int64_t time_measure_ms; - int time_measure_s, time_measure_m; - - /* use NULL to indicate a "plain" svf file which accounts for - * any additional devices in the scan chain, otherwise the device - * that should be affected - */ - struct jtag_tap *tap = NULL; - - if ((CMD_ARGC < SVF_MIN_NUM_OF_OPTIONS) || (CMD_ARGC > SVF_MAX_NUM_OF_OPTIONS)) - return ERROR_COMMAND_SYNTAX_ERROR; - - /* parse command line */ - svf_quiet = 0; - svf_nil = 0; - svf_progress_enabled = 0; - svf_ignore_error = 0; - for (unsigned int i = 0; i < CMD_ARGC; i++) { - if (strcmp(CMD_ARGV[i], "-tap") == 0) { - tap = jtag_tap_by_string(CMD_ARGV[i+1]); - if (!tap) { - command_print(CMD_CTX, "Tap: %s unknown", CMD_ARGV[i+1]); - return ERROR_FAIL; - } - i++; - } else if ((strcmp(CMD_ARGV[i], - "quiet") == 0) || (strcmp(CMD_ARGV[i], "-quiet") == 0)) - svf_quiet = 1; - else if ((strcmp(CMD_ARGV[i], "nil") == 0) || (strcmp(CMD_ARGV[i], "-nil") == 0)) - svf_nil = 1; - else if ((strcmp(CMD_ARGV[i], - "progress") == 0) || (strcmp(CMD_ARGV[i], "-progress") == 0)) - svf_progress_enabled = 1; - else if ((strcmp(CMD_ARGV[i], - "ignore_error") == 0) || (strcmp(CMD_ARGV[i], "-ignore_error") == 0)) - svf_ignore_error = 1; - else { - svf_fd = fopen(CMD_ARGV[i], "r"); - if (svf_fd == NULL) { - int err = errno; - command_print(CMD_CTX, "open(\"%s\"): %s", CMD_ARGV[i], strerror(err)); - /* no need to free anything now */ - return ERROR_COMMAND_SYNTAX_ERROR; - } else - LOG_USER("svf processing file: \"%s\"", CMD_ARGV[i]); - } - } - - if (svf_fd == NULL) - return ERROR_COMMAND_SYNTAX_ERROR; - - /* get time */ - time_measure_ms = timeval_ms(); - - /* init */ - svf_line_number = 0; - svf_command_buffer_size = 0; - - svf_check_tdo_para_index = 0; - svf_check_tdo_para = malloc(sizeof(struct svf_check_tdo_para) * SVF_CHECK_TDO_PARA_SIZE); - if (NULL == svf_check_tdo_para) { - LOG_ERROR("not enough memory"); - ret = ERROR_FAIL; - goto free_all; - } - - svf_buffer_index = 0; - /* double the buffer size */ - /* in case current command cannot be committed, and next command is a bit scan command */ - /* here is 32K bits for this big scan command, it should be enough */ - /* buffer will be reallocated if buffer size is not enough */ - if (svf_realloc_buffers(2 * SVF_MAX_BUFFER_SIZE_TO_COMMIT) != ERROR_OK) { - ret = ERROR_FAIL; - goto free_all; - } - - memcpy(&svf_para, &svf_para_init, sizeof(svf_para)); - - if (!svf_nil) { - /* TAP_RESET */ - jtag_add_tlr(); - } - - if (tap) { - /* Tap is specified, set header/trailer paddings */ - int header_ir_len = 0, header_dr_len = 0, trailer_ir_len = 0, trailer_dr_len = 0; - struct jtag_tap *check_tap; - - svf_tap_is_specified = 1; - - for (check_tap = jtag_all_taps(); check_tap; check_tap = check_tap->next_tap) { - if (check_tap->abs_chain_position < tap->abs_chain_position) { - /* Header */ - header_ir_len += check_tap->ir_length; - header_dr_len++; - } else if (check_tap->abs_chain_position > tap->abs_chain_position) { - /* Trailer */ - trailer_ir_len += check_tap->ir_length; - trailer_dr_len++; - } - } - - /* HDR %d TDI (0) */ - if (ERROR_OK != svf_set_padding(&svf_para.hdr_para, header_dr_len, 0)) { - LOG_ERROR("failed to set data header"); - return ERROR_FAIL; - } - - /* HIR %d TDI (0xFF) */ - if (ERROR_OK != svf_set_padding(&svf_para.hir_para, header_ir_len, 0xFF)) { - LOG_ERROR("failed to set instruction header"); - return ERROR_FAIL; - } - - /* TDR %d TDI (0) */ - if (ERROR_OK != svf_set_padding(&svf_para.tdr_para, trailer_dr_len, 0)) { - LOG_ERROR("failed to set data trailer"); - return ERROR_FAIL; - } - - /* TIR %d TDI (0xFF) */ - if (ERROR_OK != svf_set_padding(&svf_para.tir_para, trailer_ir_len, 0xFF)) { - LOG_ERROR("failed to set instruction trailer"); - return ERROR_FAIL; - } - } - - if (svf_progress_enabled) { - /* Count total lines in file. */ - while (!feof(svf_fd)) { - svf_getline(&svf_command_buffer, &svf_command_buffer_size, svf_fd); - svf_total_lines++; - } - rewind(svf_fd); - } - while (ERROR_OK == svf_read_command_from_file(svf_fd)) { - /* Log Output */ - if (svf_quiet) { - if (svf_progress_enabled) { - svf_percentage = ((svf_line_number * 20) / svf_total_lines) * 5; - if (svf_last_printed_percentage != svf_percentage) { - LOG_USER_N("\r%d%% ", svf_percentage); - svf_last_printed_percentage = svf_percentage; - } - } - } else { - if (svf_progress_enabled) { - svf_percentage = ((svf_line_number * 20) / svf_total_lines) * 5; - LOG_USER_N("%3d%% %s", svf_percentage, svf_read_line); - } else - LOG_USER_N("%s", svf_read_line); - } - /* Run Command */ - if (ERROR_OK != svf_run_command(CMD_CTX, svf_command_buffer)) { - LOG_ERROR("fail to run command at line %d", svf_line_number); - ret = ERROR_FAIL; - break; - } - command_num++; - } - - if ((!svf_nil) && (ERROR_OK != jtag_execute_queue())) - ret = ERROR_FAIL; - else if (ERROR_OK != svf_check_tdo()) - ret = ERROR_FAIL; - - /* print time */ - time_measure_ms = timeval_ms() - time_measure_ms; - time_measure_s = time_measure_ms / 1000; - time_measure_ms %= 1000; - time_measure_m = time_measure_s / 60; - time_measure_s %= 60; - if (time_measure_ms < 1000) - command_print(CMD_CTX, - "\r\nTime used: %dm%ds%" PRId64 "ms ", - time_measure_m, - time_measure_s, - time_measure_ms); - -free_all: - - fclose(svf_fd); - svf_fd = 0; - - /* free buffers */ - if (svf_command_buffer) { - free(svf_command_buffer); - svf_command_buffer = NULL; - svf_command_buffer_size = 0; - } - if (svf_check_tdo_para) { - free(svf_check_tdo_para); - svf_check_tdo_para = NULL; - svf_check_tdo_para_index = 0; - } - if (svf_tdi_buffer) { - free(svf_tdi_buffer); - svf_tdi_buffer = NULL; - } - if (svf_tdo_buffer) { - free(svf_tdo_buffer); - svf_tdo_buffer = NULL; - } - if (svf_mask_buffer) { - free(svf_mask_buffer); - svf_mask_buffer = NULL; - } - svf_buffer_index = 0; - svf_buffer_size = 0; - - svf_free_xxd_para(&svf_para.hdr_para); - svf_free_xxd_para(&svf_para.hir_para); - svf_free_xxd_para(&svf_para.tdr_para); - svf_free_xxd_para(&svf_para.tir_para); - svf_free_xxd_para(&svf_para.sdr_para); - svf_free_xxd_para(&svf_para.sir_para); - - if (ERROR_OK == ret) - command_print(CMD_CTX, - "svf file programmed %s for %d commands with %d errors", - (svf_ignore_error > 1) ? "unsuccessfully" : "successfully", - command_num, - (svf_ignore_error > 1) ? (svf_ignore_error - 1) : 0); - else - command_print(CMD_CTX, "svf file programmed failed"); - - svf_ignore_error = 0; - return ret; -} - -static int svf_getline(char **lineptr, size_t *n, FILE *stream) -{ -#define MIN_CHUNK 16 /* Buffer is increased by this size each time as required */ - size_t i = 0; - - if (*lineptr == NULL) { - *n = MIN_CHUNK; - *lineptr = malloc(*n); - if (!*lineptr) - return -1; - } - - (*lineptr)[0] = fgetc(stream); - while ((*lineptr)[i] != '\n') { - (*lineptr)[++i] = fgetc(stream); - if (feof(stream)) { - (*lineptr)[0] = 0; - return -1; - } - if ((i + 2) > *n) { - *n += MIN_CHUNK; - *lineptr = realloc(*lineptr, *n); - } - } - - (*lineptr)[++i] = 0; - - return sizeof(*lineptr); -} - -#define SVFP_CMD_INC_CNT 1024 -static int svf_read_command_from_file(FILE *fd) -{ - unsigned char ch; - int i = 0; - size_t cmd_pos = 0; - int cmd_ok = 0, slash = 0; - - if (svf_getline(&svf_read_line, &svf_read_line_size, svf_fd) <= 0) - return ERROR_FAIL; - svf_line_number++; - ch = svf_read_line[0]; - while (!cmd_ok && (ch != 0)) { - switch (ch) { - case '!': - slash = 0; - if (svf_getline(&svf_read_line, &svf_read_line_size, svf_fd) <= 0) - return ERROR_FAIL; - svf_line_number++; - i = -1; - break; - case '/': - if (++slash == 2) { - slash = 0; - if (svf_getline(&svf_read_line, &svf_read_line_size, - svf_fd) <= 0) - return ERROR_FAIL; - svf_line_number++; - i = -1; - } - break; - case ';': - slash = 0; - cmd_ok = 1; - break; - case '\n': - svf_line_number++; - if (svf_getline(&svf_read_line, &svf_read_line_size, svf_fd) <= 0) - return ERROR_FAIL; - i = -1; - case '\r': - slash = 0; - /* Don't save '\r' and '\n' if no data is parsed */ - if (!cmd_pos) - break; - default: - /* The parsing code currently expects a space - * before parentheses -- "TDI (123)". Also a - * space afterwards -- "TDI (123) TDO(456)". - * But such spaces are optional... instead of - * parser updates, cope with that by adding the - * spaces as needed. - * - * Ensure there are 3 bytes available, for: - * - current character - * - added space. - * - terminating NUL ('\0') - */ - if (cmd_pos + 3 > svf_command_buffer_size) { - svf_command_buffer = realloc(svf_command_buffer, cmd_pos + 3); - svf_command_buffer_size = cmd_pos + 3; - if (svf_command_buffer == NULL) { - LOG_ERROR("not enough memory"); - return ERROR_FAIL; - } - } - - /* insert a space before '(' */ - if ('(' == ch) - svf_command_buffer[cmd_pos++] = ' '; - - svf_command_buffer[cmd_pos++] = (char)toupper(ch); - - /* insert a space after ')' */ - if (')' == ch) - svf_command_buffer[cmd_pos++] = ' '; - break; - } - ch = svf_read_line[++i]; - } - - if (cmd_ok) { - svf_command_buffer[cmd_pos] = '\0'; - return ERROR_OK; - } else - return ERROR_FAIL; -} - -static int svf_parse_cmd_string(char *str, int len, char **argus, int *num_of_argu) -{ - int pos = 0, num = 0, space_found = 1, in_bracket = 0; - - while (pos < len) { - switch (str[pos]) { - case '!': - case '/': - LOG_ERROR("fail to parse svf command"); - return ERROR_FAIL; - case '(': - in_bracket = 1; - goto parse_char; - case ')': - in_bracket = 0; - goto parse_char; - default: -parse_char: - if (!in_bracket && isspace((int) str[pos])) { - space_found = 1; - str[pos] = '\0'; - } else if (space_found) { - argus[num++] = &str[pos]; - space_found = 0; - } - break; - } - pos++; - } - - *num_of_argu = num; - - return ERROR_OK; -} - -bool svf_tap_state_is_stable(tap_state_t state) -{ - return (TAP_RESET == state) || (TAP_IDLE == state) - || (TAP_DRPAUSE == state) || (TAP_IRPAUSE == state); -} - -static int svf_find_string_in_array(char *str, char **strs, int num_of_element) -{ - int i; - - for (i = 0; i < num_of_element; i++) { - if (!strcmp(str, strs[i])) - return i; - } - return 0xFF; -} - -static int svf_adjust_array_length(uint8_t **arr, int orig_bit_len, int new_bit_len) -{ - int new_byte_len = (new_bit_len + 7) >> 3; - - if ((NULL == *arr) || (((orig_bit_len + 7) >> 3) < ((new_bit_len + 7) >> 3))) { - if (*arr != NULL) { - free(*arr); - *arr = NULL; - } - *arr = malloc(new_byte_len); - if (NULL == *arr) { - LOG_ERROR("not enough memory"); - return ERROR_FAIL; - } - memset(*arr, 0, new_byte_len); - } - return ERROR_OK; -} - -static int svf_set_padding(struct svf_xxr_para *para, int len, unsigned char tdi) -{ - int error = ERROR_OK; - error |= svf_adjust_array_length(¶->tdi, para->len, len); - memset(para->tdi, tdi, (len + 7) >> 3); - error |= svf_adjust_array_length(¶->tdo, para->len, len); - error |= svf_adjust_array_length(¶->mask, para->len, len); - para->len = len; - para->data_mask = XXR_TDI; - - return error; -} - -static int svf_copy_hexstring_to_binary(char *str, uint8_t **bin, int orig_bit_len, int bit_len) -{ - int i, str_len = strlen(str), str_hbyte_len = (bit_len + 3) >> 2; - uint8_t ch = 0; - - if (ERROR_OK != svf_adjust_array_length(bin, orig_bit_len, bit_len)) { - LOG_ERROR("fail to adjust length of array"); - return ERROR_FAIL; - } - - /* fill from LSB (end of str) to MSB (beginning of str) */ - for (i = 0; i < str_hbyte_len; i++) { - ch = 0; - while (str_len > 0) { - ch = str[--str_len]; - - /* Skip whitespace. The SVF specification (rev E) is - * deficient in terms of basic lexical issues like - * where whitespace is allowed. Long bitstrings may - * require line ends for correctness, since there is - * a hard limit on line length. - */ - if (!isspace(ch)) { - if ((ch >= '0') && (ch <= '9')) { - ch = ch - '0'; - break; - } else if ((ch >= 'A') && (ch <= 'F')) { - ch = ch - 'A' + 10; - break; - } else { - LOG_ERROR("invalid hex string"); - return ERROR_FAIL; - } - } - - ch = 0; - } - - /* write bin */ - if (i % 2) { - /* MSB */ - (*bin)[i / 2] |= ch << 4; - } else { - /* LSB */ - (*bin)[i / 2] = 0; - (*bin)[i / 2] |= ch; - } - } - - /* consume optional leading '0' MSBs or whitespace */ - while (str_len > 0 && ((str[str_len - 1] == '0') - || isspace((int) str[str_len - 1]))) - str_len--; - - /* check validity: we must have consumed everything */ - if (str_len > 0 || (ch & ~((2 << ((bit_len - 1) % 4)) - 1)) != 0) { - LOG_ERROR("value execeeds length"); - return ERROR_FAIL; - } - - return ERROR_OK; -} - -static int svf_check_tdo(void) -{ - int i, len, index_var; - - for (i = 0; i < svf_check_tdo_para_index; i++) { - index_var = svf_check_tdo_para[i].buffer_offset; - len = svf_check_tdo_para[i].bit_len; - if ((svf_check_tdo_para[i].enabled) - && buf_cmp_mask(&svf_tdi_buffer[index_var], &svf_tdo_buffer[index_var], - &svf_mask_buffer[index_var], len)) { - LOG_ERROR("tdo check error at line %d", - svf_check_tdo_para[i].line_num); - SVF_BUF_LOG(ERROR, &svf_tdi_buffer[index_var], len, "READ"); - SVF_BUF_LOG(ERROR, &svf_tdo_buffer[index_var], len, "WANT"); - SVF_BUF_LOG(ERROR, &svf_mask_buffer[index_var], len, "MASK"); - - if (svf_ignore_error == 0) - return ERROR_FAIL; - else - svf_ignore_error++; - } - } - svf_check_tdo_para_index = 0; - - return ERROR_OK; -} - -static int svf_add_check_para(uint8_t enabled, int buffer_offset, int bit_len) -{ - if (svf_check_tdo_para_index >= SVF_CHECK_TDO_PARA_SIZE) { - LOG_ERROR("toooooo many operation undone"); - return ERROR_FAIL; - } - - svf_check_tdo_para[svf_check_tdo_para_index].line_num = svf_line_number; - svf_check_tdo_para[svf_check_tdo_para_index].bit_len = bit_len; - svf_check_tdo_para[svf_check_tdo_para_index].enabled = enabled; - svf_check_tdo_para[svf_check_tdo_para_index].buffer_offset = buffer_offset; - svf_check_tdo_para_index++; - - return ERROR_OK; -} - -static int svf_execute_tap(void) -{ - if ((!svf_nil) && (ERROR_OK != jtag_execute_queue())) - return ERROR_FAIL; - else if (ERROR_OK != svf_check_tdo()) - return ERROR_FAIL; - - svf_buffer_index = 0; - - return ERROR_OK; -} - -static int svf_run_command(struct command_context *cmd_ctx, char *cmd_str) -{ - char *argus[256], command; - int num_of_argu = 0, i; - - /* tmp variable */ - int i_tmp; - - /* for RUNTEST */ - int run_count; - float min_time; - /* for XXR */ - struct svf_xxr_para *xxr_para_tmp; - uint8_t **pbuffer_tmp; - struct scan_field field; - /* for STATE */ - tap_state_t *path = NULL, state; - /* flag padding commands skipped due to -tap command */ - int padding_command_skipped = 0; - - if (ERROR_OK != svf_parse_cmd_string(cmd_str, strlen(cmd_str), argus, &num_of_argu)) - return ERROR_FAIL; - - /* NOTE: we're a bit loose here, because we ignore case in - * TAP state names (instead of insisting on uppercase). - */ - - command = svf_find_string_in_array(argus[0], - (char **)svf_command_name, ARRAY_SIZE(svf_command_name)); - switch (command) { - case ENDDR: - case ENDIR: - if (num_of_argu != 2) { - LOG_ERROR("invalid parameter of %s", argus[0]); - return ERROR_FAIL; - } - - i_tmp = tap_state_by_name(argus[1]); - - if (svf_tap_state_is_stable(i_tmp)) { - if (command == ENDIR) { - svf_para.ir_end_state = i_tmp; - LOG_DEBUG("\tIR end_state = %s", - tap_state_name(i_tmp)); - } else { - svf_para.dr_end_state = i_tmp; - LOG_DEBUG("\tDR end_state = %s", - tap_state_name(i_tmp)); - } - } else { - LOG_ERROR("%s: %s is not a stable state", - argus[0], argus[1]); - return ERROR_FAIL; - } - break; - case FREQUENCY: - if ((num_of_argu != 1) && (num_of_argu != 3)) { - LOG_ERROR("invalid parameter of %s", argus[0]); - return ERROR_FAIL; - } - if (1 == num_of_argu) { - /* TODO: set jtag speed to full speed */ - svf_para.frequency = 0; - } else { - if (strcmp(argus[2], "HZ")) { - LOG_ERROR("HZ not found in FREQUENCY command"); - return ERROR_FAIL; - } - if (ERROR_OK != svf_execute_tap()) - return ERROR_FAIL; - svf_para.frequency = atof(argus[1]); - /* TODO: set jtag speed to */ - if (svf_para.frequency > 0) { - command_run_linef(cmd_ctx, - "adapter_khz %d", - (int)svf_para.frequency / 1000); - LOG_DEBUG("\tfrequency = %f", svf_para.frequency); - } - } - break; - case HDR: - if (svf_tap_is_specified) { - padding_command_skipped = 1; - break; - } - xxr_para_tmp = &svf_para.hdr_para; - goto XXR_common; - case HIR: - if (svf_tap_is_specified) { - padding_command_skipped = 1; - break; - } - xxr_para_tmp = &svf_para.hir_para; - goto XXR_common; - case TDR: - if (svf_tap_is_specified) { - padding_command_skipped = 1; - break; - } - xxr_para_tmp = &svf_para.tdr_para; - goto XXR_common; - case TIR: - if (svf_tap_is_specified) { - padding_command_skipped = 1; - break; - } - xxr_para_tmp = &svf_para.tir_para; - goto XXR_common; - case SDR: - xxr_para_tmp = &svf_para.sdr_para; - goto XXR_common; - case SIR: - xxr_para_tmp = &svf_para.sir_para; - goto XXR_common; -XXR_common: - /* XXR length [TDI (tdi)] [TDO (tdo)][MASK (mask)] [SMASK (smask)] */ - if ((num_of_argu > 10) || (num_of_argu % 2)) { - LOG_ERROR("invalid parameter of %s", argus[0]); - return ERROR_FAIL; - } - i_tmp = xxr_para_tmp->len; - xxr_para_tmp->len = atoi(argus[1]); - /* If we are to enlarge the buffers, all parts of xxr_para_tmp - * need to be freed */ - if (i_tmp < xxr_para_tmp->len) { - free(xxr_para_tmp->tdi); - xxr_para_tmp->tdi = NULL; - free(xxr_para_tmp->tdo); - xxr_para_tmp->tdo = NULL; - free(xxr_para_tmp->mask); - xxr_para_tmp->mask = NULL; - free(xxr_para_tmp->smask); - xxr_para_tmp->smask = NULL; - } - - LOG_DEBUG("\tlength = %d", xxr_para_tmp->len); - xxr_para_tmp->data_mask = 0; - for (i = 2; i < num_of_argu; i += 2) { - if ((strlen(argus[i + 1]) < 3) || (argus[i + 1][0] != '(') || - (argus[i + 1][strlen(argus[i + 1]) - 1] != ')')) { - LOG_ERROR("data section error"); - return ERROR_FAIL; - } - argus[i + 1][strlen(argus[i + 1]) - 1] = '\0'; - /* TDI, TDO, MASK, SMASK */ - if (!strcmp(argus[i], "TDI")) { - /* TDI */ - pbuffer_tmp = &xxr_para_tmp->tdi; - xxr_para_tmp->data_mask |= XXR_TDI; - } else if (!strcmp(argus[i], "TDO")) { - /* TDO */ - pbuffer_tmp = &xxr_para_tmp->tdo; - xxr_para_tmp->data_mask |= XXR_TDO; - } else if (!strcmp(argus[i], "MASK")) { - /* MASK */ - pbuffer_tmp = &xxr_para_tmp->mask; - xxr_para_tmp->data_mask |= XXR_MASK; - } else if (!strcmp(argus[i], "SMASK")) { - /* SMASK */ - pbuffer_tmp = &xxr_para_tmp->smask; - xxr_para_tmp->data_mask |= XXR_SMASK; - } else { - LOG_ERROR("unknow parameter: %s", argus[i]); - return ERROR_FAIL; - } - if (ERROR_OK != - svf_copy_hexstring_to_binary(&argus[i + 1][1], pbuffer_tmp, i_tmp, - xxr_para_tmp->len)) { - LOG_ERROR("fail to parse hex value"); - return ERROR_FAIL; - } - SVF_BUF_LOG(DEBUG, *pbuffer_tmp, xxr_para_tmp->len, argus[i]); - } - /* If a command changes the length of the last scan of the same type and the - * MASK parameter is absent, */ - /* the mask pattern used is all cares */ - if (!(xxr_para_tmp->data_mask & XXR_MASK) && (i_tmp != xxr_para_tmp->len)) { - /* MASK not defined and length changed */ - if (ERROR_OK != - svf_adjust_array_length(&xxr_para_tmp->mask, i_tmp, - xxr_para_tmp->len)) { - LOG_ERROR("fail to adjust length of array"); - return ERROR_FAIL; - } - buf_set_ones(xxr_para_tmp->mask, xxr_para_tmp->len); - } - /* If TDO is absent, no comparison is needed, set the mask to 0 */ - if (!(xxr_para_tmp->data_mask & XXR_TDO)) { - if (NULL == xxr_para_tmp->tdo) { - if (ERROR_OK != - svf_adjust_array_length(&xxr_para_tmp->tdo, i_tmp, - xxr_para_tmp->len)) { - LOG_ERROR("fail to adjust length of array"); - return ERROR_FAIL; - } - } - if (NULL == xxr_para_tmp->mask) { - if (ERROR_OK != - svf_adjust_array_length(&xxr_para_tmp->mask, i_tmp, - xxr_para_tmp->len)) { - LOG_ERROR("fail to adjust length of array"); - return ERROR_FAIL; - } - } - memset(xxr_para_tmp->mask, 0, (xxr_para_tmp->len + 7) >> 3); - } - /* do scan if necessary */ - if (SDR == command) { - /* check buffer size first, reallocate if necessary */ - i = svf_para.hdr_para.len + svf_para.sdr_para.len + - svf_para.tdr_para.len; - if ((svf_buffer_size - svf_buffer_index) < ((i + 7) >> 3)) { - /* reallocate buffer */ - if (svf_realloc_buffers(svf_buffer_index + ((i + 7) >> 3)) != ERROR_OK) { - LOG_ERROR("not enough memory"); - return ERROR_FAIL; - } - } - - /* assemble dr data */ - i = 0; - buf_set_buf(svf_para.hdr_para.tdi, - 0, - &svf_tdi_buffer[svf_buffer_index], - i, - svf_para.hdr_para.len); - i += svf_para.hdr_para.len; - buf_set_buf(svf_para.sdr_para.tdi, - 0, - &svf_tdi_buffer[svf_buffer_index], - i, - svf_para.sdr_para.len); - i += svf_para.sdr_para.len; - buf_set_buf(svf_para.tdr_para.tdi, - 0, - &svf_tdi_buffer[svf_buffer_index], - i, - svf_para.tdr_para.len); - i += svf_para.tdr_para.len; - - /* add check data */ - if (svf_para.sdr_para.data_mask & XXR_TDO) { - /* assemble dr mask data */ - i = 0; - buf_set_buf(svf_para.hdr_para.mask, - 0, - &svf_mask_buffer[svf_buffer_index], - i, - svf_para.hdr_para.len); - i += svf_para.hdr_para.len; - buf_set_buf(svf_para.sdr_para.mask, - 0, - &svf_mask_buffer[svf_buffer_index], - i, - svf_para.sdr_para.len); - i += svf_para.sdr_para.len; - buf_set_buf(svf_para.tdr_para.mask, - 0, - &svf_mask_buffer[svf_buffer_index], - i, - svf_para.tdr_para.len); - - /* assemble dr check data */ - i = 0; - buf_set_buf(svf_para.hdr_para.tdo, - 0, - &svf_tdo_buffer[svf_buffer_index], - i, - svf_para.hdr_para.len); - i += svf_para.hdr_para.len; - buf_set_buf(svf_para.sdr_para.tdo, - 0, - &svf_tdo_buffer[svf_buffer_index], - i, - svf_para.sdr_para.len); - i += svf_para.sdr_para.len; - buf_set_buf(svf_para.tdr_para.tdo, - 0, - &svf_tdo_buffer[svf_buffer_index], - i, - svf_para.tdr_para.len); - i += svf_para.tdr_para.len; - - svf_add_check_para(1, svf_buffer_index, i); - } else - svf_add_check_para(0, svf_buffer_index, i); - field.num_bits = i; - field.out_value = &svf_tdi_buffer[svf_buffer_index]; - field.in_value = (xxr_para_tmp->data_mask & XXR_TDO) ? &svf_tdi_buffer[svf_buffer_index] : NULL; - if (!svf_nil) { - /* NOTE: doesn't use SVF-specified state paths */ - jtag_add_plain_dr_scan(field.num_bits, - field.out_value, - field.in_value, - svf_para.dr_end_state); - } - - svf_buffer_index += (i + 7) >> 3; - } else if (SIR == command) { - /* check buffer size first, reallocate if necessary */ - i = svf_para.hir_para.len + svf_para.sir_para.len + - svf_para.tir_para.len; - if ((svf_buffer_size - svf_buffer_index) < ((i + 7) >> 3)) { - if (svf_realloc_buffers(svf_buffer_index + ((i + 7) >> 3)) != ERROR_OK) { - LOG_ERROR("not enough memory"); - return ERROR_FAIL; - } - } - - /* assemble ir data */ - i = 0; - buf_set_buf(svf_para.hir_para.tdi, - 0, - &svf_tdi_buffer[svf_buffer_index], - i, - svf_para.hir_para.len); - i += svf_para.hir_para.len; - buf_set_buf(svf_para.sir_para.tdi, - 0, - &svf_tdi_buffer[svf_buffer_index], - i, - svf_para.sir_para.len); - i += svf_para.sir_para.len; - buf_set_buf(svf_para.tir_para.tdi, - 0, - &svf_tdi_buffer[svf_buffer_index], - i, - svf_para.tir_para.len); - i += svf_para.tir_para.len; - - /* add check data */ - if (svf_para.sir_para.data_mask & XXR_TDO) { - /* assemble dr mask data */ - i = 0; - buf_set_buf(svf_para.hir_para.mask, - 0, - &svf_mask_buffer[svf_buffer_index], - i, - svf_para.hir_para.len); - i += svf_para.hir_para.len; - buf_set_buf(svf_para.sir_para.mask, - 0, - &svf_mask_buffer[svf_buffer_index], - i, - svf_para.sir_para.len); - i += svf_para.sir_para.len; - buf_set_buf(svf_para.tir_para.mask, - 0, - &svf_mask_buffer[svf_buffer_index], - i, - svf_para.tir_para.len); - - /* assemble dr check data */ - i = 0; - buf_set_buf(svf_para.hir_para.tdo, - 0, - &svf_tdo_buffer[svf_buffer_index], - i, - svf_para.hir_para.len); - i += svf_para.hir_para.len; - buf_set_buf(svf_para.sir_para.tdo, - 0, - &svf_tdo_buffer[svf_buffer_index], - i, - svf_para.sir_para.len); - i += svf_para.sir_para.len; - buf_set_buf(svf_para.tir_para.tdo, - 0, - &svf_tdo_buffer[svf_buffer_index], - i, - svf_para.tir_para.len); - i += svf_para.tir_para.len; - - svf_add_check_para(1, svf_buffer_index, i); - } else - svf_add_check_para(0, svf_buffer_index, i); - field.num_bits = i; - field.out_value = &svf_tdi_buffer[svf_buffer_index]; - field.in_value = (xxr_para_tmp->data_mask & XXR_TDO) ? &svf_tdi_buffer[svf_buffer_index] : NULL; - if (!svf_nil) { - /* NOTE: doesn't use SVF-specified state paths */ - jtag_add_plain_ir_scan(field.num_bits, - field.out_value, - field.in_value, - svf_para.ir_end_state); - } - - svf_buffer_index += (i + 7) >> 3; - } - break; - case PIO: - case PIOMAP: - LOG_ERROR("PIO and PIOMAP are not supported"); - return ERROR_FAIL; - break; - case RUNTEST: - /* RUNTEST [run_state] run_count run_clk [min_time SEC [MAXIMUM max_time - * SEC]] [ENDSTATE end_state] */ - /* RUNTEST [run_state] min_time SEC [MAXIMUM max_time SEC] [ENDSTATE - * end_state] */ - if ((num_of_argu < 3) && (num_of_argu > 11)) { - LOG_ERROR("invalid parameter of %s", argus[0]); - return ERROR_FAIL; - } - /* init */ - run_count = 0; - min_time = 0; - i = 1; - - /* run_state */ - i_tmp = tap_state_by_name(argus[i]); - if (i_tmp != TAP_INVALID) { - if (svf_tap_state_is_stable(i_tmp)) { - svf_para.runtest_run_state = i_tmp; - - /* When a run_state is specified, the new - * run_state becomes the default end_state. - */ - svf_para.runtest_end_state = i_tmp; - LOG_DEBUG("\trun_state = %s", tap_state_name(i_tmp)); - i++; - } else { - LOG_ERROR("%s: %s is not a stable state", argus[0], tap_state_name(i_tmp)); - return ERROR_FAIL; - } - } - - /* run_count run_clk */ - if (((i + 2) <= num_of_argu) && strcmp(argus[i + 1], "SEC")) { - if (!strcmp(argus[i + 1], "TCK")) { - /* clock source is TCK */ - run_count = atoi(argus[i]); - LOG_DEBUG("\trun_count@TCK = %d", run_count); - } else { - LOG_ERROR("%s not supported for clock", argus[i + 1]); - return ERROR_FAIL; - } - i += 2; - } - /* min_time SEC */ - if (((i + 2) <= num_of_argu) && !strcmp(argus[i + 1], "SEC")) { - min_time = atof(argus[i]); - LOG_DEBUG("\tmin_time = %fs", min_time); - i += 2; - } - /* MAXIMUM max_time SEC */ - if (((i + 3) <= num_of_argu) && - !strcmp(argus[i], "MAXIMUM") && !strcmp(argus[i + 2], "SEC")) { - float max_time = 0; - max_time = atof(argus[i + 1]); - LOG_DEBUG("\tmax_time = %fs", max_time); - i += 3; - } - /* ENDSTATE end_state */ - if (((i + 2) <= num_of_argu) && !strcmp(argus[i], "ENDSTATE")) { - i_tmp = tap_state_by_name(argus[i + 1]); - - if (svf_tap_state_is_stable(i_tmp)) { - svf_para.runtest_end_state = i_tmp; - LOG_DEBUG("\tend_state = %s", tap_state_name(i_tmp)); - } else { - LOG_ERROR("%s: %s is not a stable state", argus[0], tap_state_name(i_tmp)); - return ERROR_FAIL; - } - i += 2; - } - - /* all parameter should be parsed */ - if (i == num_of_argu) { -#if 1 - /* FIXME handle statemove failures */ - uint32_t min_usec = 1000000 * min_time; - - /* enter into run_state if necessary */ - if (cmd_queue_cur_state != svf_para.runtest_run_state) - svf_add_statemove(svf_para.runtest_run_state); - - /* add clocks and/or min wait */ - if (run_count > 0) { - if (!svf_nil) - jtag_add_clocks(run_count); - } - - if (min_usec > 0) { - if (!svf_nil) - jtag_add_sleep(min_usec); - } - - /* move to end_state if necessary */ - if (svf_para.runtest_end_state != svf_para.runtest_run_state) - svf_add_statemove(svf_para.runtest_end_state); - -#else - if (svf_para.runtest_run_state != TAP_IDLE) { - LOG_ERROR("cannot runtest in %s state", - tap_state_name(svf_para.runtest_run_state)); - return ERROR_FAIL; - } - - if (!svf_nil) - jtag_add_runtest(run_count, svf_para.runtest_end_state); -#endif - } else { - LOG_ERROR("fail to parse parameter of RUNTEST, %d out of %d is parsed", - i, - num_of_argu); - return ERROR_FAIL; - } - break; - case STATE: - /* STATE [pathstate1 [pathstate2 ...[pathstaten]]] stable_state */ - if (num_of_argu < 2) { - LOG_ERROR("invalid parameter of %s", argus[0]); - return ERROR_FAIL; - } - if (num_of_argu > 2) { - /* STATE pathstate1 ... stable_state */ - path = malloc((num_of_argu - 1) * sizeof(tap_state_t)); - if (NULL == path) { - LOG_ERROR("not enough memory"); - return ERROR_FAIL; - } - num_of_argu--; /* num of path */ - i_tmp = 1; /* path is from parameter 1 */ - for (i = 0; i < num_of_argu; i++, i_tmp++) { - path[i] = tap_state_by_name(argus[i_tmp]); - if (path[i] == TAP_INVALID) { - LOG_ERROR("%s: %s is not a valid state", argus[0], argus[i_tmp]); - free(path); - return ERROR_FAIL; - } - /* OpenOCD refuses paths containing TAP_RESET */ - if (TAP_RESET == path[i]) { - /* FIXME last state MUST be stable! */ - if (i > 0) { - if (!svf_nil) - jtag_add_pathmove(i, path); - } - if (!svf_nil) - jtag_add_tlr(); - num_of_argu -= i + 1; - i = -1; - } - } - if (num_of_argu > 0) { - /* execute last path if necessary */ - if (svf_tap_state_is_stable(path[num_of_argu - 1])) { - /* last state MUST be stable state */ - if (!svf_nil) - jtag_add_pathmove(num_of_argu, path); - LOG_DEBUG("\tmove to %s by path_move", - tap_state_name(path[num_of_argu - 1])); - } else { - LOG_ERROR("%s: %s is not a stable state", - argus[0], - tap_state_name(path[num_of_argu - 1])); - free(path); - return ERROR_FAIL; - } - } - - free(path); - path = NULL; - } else { - /* STATE stable_state */ - state = tap_state_by_name(argus[1]); - if (svf_tap_state_is_stable(state)) { - LOG_DEBUG("\tmove to %s by svf_add_statemove", - tap_state_name(state)); - /* FIXME handle statemove failures */ - svf_add_statemove(state); - } else { - LOG_ERROR("%s: %s is not a stable state", - argus[0], tap_state_name(state)); - return ERROR_FAIL; - } - } - break; - case TRST: - /* TRST trst_mode */ - if (num_of_argu != 2) { - LOG_ERROR("invalid parameter of %s", argus[0]); - return ERROR_FAIL; - } - if (svf_para.trst_mode != TRST_ABSENT) { - if (ERROR_OK != svf_execute_tap()) - return ERROR_FAIL; - i_tmp = svf_find_string_in_array(argus[1], - (char **)svf_trst_mode_name, - ARRAY_SIZE(svf_trst_mode_name)); - switch (i_tmp) { - case TRST_ON: - if (!svf_nil) - jtag_add_reset(1, 0); - break; - case TRST_Z: - case TRST_OFF: - if (!svf_nil) - jtag_add_reset(0, 0); - break; - case TRST_ABSENT: - break; - default: - LOG_ERROR("unknown TRST mode: %s", argus[1]); - return ERROR_FAIL; - } - svf_para.trst_mode = i_tmp; - LOG_DEBUG("\ttrst_mode = %s", svf_trst_mode_name[svf_para.trst_mode]); - } else { - LOG_ERROR("can not accpet TRST command if trst_mode is ABSENT"); - return ERROR_FAIL; - } - break; - default: - LOG_ERROR("invalid svf command: %s", argus[0]); - return ERROR_FAIL; - break; - } - - if (!svf_quiet) { - if (padding_command_skipped) - LOG_USER("(Above Padding command skipped, as per -tap argument)"); - } - - if (debug_level >= LOG_LVL_DEBUG) { - /* for convenient debugging, execute tap if possible */ - if ((svf_buffer_index > 0) && \ - (((command != STATE) && (command != RUNTEST)) || \ - ((command == STATE) && (num_of_argu == 2)))) { - if (ERROR_OK != svf_execute_tap()) - return ERROR_FAIL; - - /* output debug info */ - if ((SIR == command) || (SDR == command)) { - SVF_BUF_LOG(DEBUG, svf_tdi_buffer, svf_check_tdo_para[0].bit_len, "TDO read"); - } - } - } else { - /* for fast executing, execute tap if necessary */ - /* half of the buffer is for the next command */ - if (((svf_buffer_index >= SVF_MAX_BUFFER_SIZE_TO_COMMIT) || - (svf_check_tdo_para_index >= SVF_CHECK_TDO_PARA_SIZE / 2)) && \ - (((command != STATE) && (command != RUNTEST)) || \ - ((command == STATE) && (num_of_argu == 2)))) - return svf_execute_tap(); - } - - return ERROR_OK; -} - -static const struct command_registration svf_command_handlers[] = { - { - .name = "svf", - .handler = handle_svf_command, - .mode = COMMAND_EXEC, - .help = "Runs a SVF file.", - .usage = "svf [-tap device.tap] [quiet] [nil] [progress] [ignore_error]", - }, - COMMAND_REGISTRATION_DONE -}; - -int svf_register_commands(struct command_context *cmd_ctx) -{ - return register_commands(cmd_ctx, NULL, svf_command_handlers); -} diff --git a/src/svf/svf.h b/src/svf/svf.h deleted file mode 100644 index 4101a3f85..000000000 --- a/src/svf/svf.h +++ /dev/null @@ -1,47 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2009 by Simon Qian * - * SimonQian@SimonQian.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifndef OPENOCD_SVF_SVF_H -#define OPENOCD_SVF_SVF_H - -#include - -int svf_register_commands(struct command_context *cmd_ctx); - -/** - * svf_add_statemove() moves from the current state to @a goal_state. - * - * @param goal_state The final TAP state. - * @return ERROR_OK on success, or an error code on failure. - * - * The current and goal states must satisfy svf_tap_state_is_stable(). - * State transition paths used by this routine are those given in the - * SVF specification for single-argument STATE commands (and also used - * for various other state transitions). - */ -int svf_add_statemove(tap_state_t goal_state); - -/** - * svf_tap_state_is_stable() returns true for stable non-SHIFT states - * - * @param state The TAP state in question - * @return true iff the state is stable and not a SHIFT state. - */ -bool svf_tap_state_is_stable(tap_state_t state); - -#endif /* OPENOCD_SVF_SVF_H */ diff --git a/src/target/Makefile.am b/src/target/Makefile.am deleted file mode 100644 index 44299fc15..000000000 --- a/src/target/Makefile.am +++ /dev/null @@ -1,219 +0,0 @@ -include $(top_srcdir)/common.mk - -if OOCD_TRACE -OOCD_TRACE_FILES = 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/*) - -DEBUG_HEADER = xscale_debug.inc -BUILT_SOURCES = $(DEBUG_HEADER) -CLEANFILES = $(DEBUG_HEADER) - -$(DEBUG_HEADER): $(DEBUG_HANDLER) $(BIN2C) - $(BIN2C) < $< > $@ || { rm -f $@; false; } - -METASOURCES = AUTO -noinst_LTLIBRARIES = libtarget.la -libtarget_la_SOURCES = \ - $(TARGET_CORE_SRC) \ - $(ARM_DEBUG_SRC) \ - $(ARMV4_5_SRC) \ - $(ARMV6_SRC) \ - $(ARMV7_SRC) \ - $(ARM_MISC_SRC) \ - $(AVR32_SRC) \ - $(MIPS32_SRC) \ - $(NDS32_SRC) \ - $(INTEL_IA32_SRC) \ - $(RISCV_SRC) \ - avrt.c \ - dsp563xx.c \ - dsp563xx_once.c \ - dsp5680xx.c \ - hla_target.c - -TARGET_CORE_SRC = \ - algorithm.c \ - register.c \ - image.c \ - breakpoints.c \ - target.c \ - target_request.c \ - testee.c \ - smp.c - -ARMV4_5_SRC = \ - armv4_5.c \ - armv4_5_mmu.c \ - 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 - -ARM_MISC_SRC = \ - fa526.c \ - xscale.c - -ARMV6_SRC = \ - arm11.c \ - arm11_dbgtap.c - -ARMV7_SRC = \ - armv7m.c \ - armv7m_trace.c \ - cortex_m.c \ - armv7a.c \ - cortex_a.c \ - ls1_sap.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 \ - $(OOCD_TRACE_FILES) \ - etm_dummy.c - -AVR32_SRC = \ - avr32_ap7k.c \ - avr32_jtag.c \ - avr32_mem.c \ - avr32_regs.c - -MIPS32_SRC = \ - mips32.c \ - mips_m4k.c \ - mips32_pracc.c \ - mips32_dmaacc.c \ - 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 - -INTEL_IA32_SRC = \ - quark_x10xx.c \ - quark_d20xx.c \ - lakemont.c \ - x86_32_common.c - -RISCV_SRC = \ - riscv/riscv-011.c \ - riscv/riscv-013.c \ - riscv/riscv.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 diff --git a/src/target/adi_v5_jtag.c b/src/target/adi_v5_jtag.c deleted file mode 100644 index 2717c9e36..000000000 --- a/src/target/adi_v5_jtag.c +++ /dev/null @@ -1,756 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2006 by Magnus Lundin - * lundin@mlu.mine.nu - * - * Copyright (C) 2008 by Spencer Oliver - * spen@spen-soft.co.uk - * - * Copyright (C) 2009 by Oyvind Harboe - * oyvind.harboe@zylin.com - * - * Copyright (C) 2009-2010 by David Brownell - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - ***************************************************************************/ - -/** - * @file - * This file implements JTAG transport support for cores implementing - the ARM Debug Interface version 5 (ADIv5). - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#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 -#define JTAG_DP_DPACC 0xA -#define JTAG_DP_APACC 0xB -#define JTAG_DP_IDCODE 0xE - -/* three-bit ACK values for DPACC and APACC reads */ -#define JTAG_ACK_OK_FAULT 0x2 -#define JTAG_ACK_WAIT 0x1 - -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 - * discusses operations which access these registers. - * - * Note that only one scan is performed. If RnW is set, a separate scan - * will be needed to collect the data which was read; the "invalue" collects - * the posted result of a preceding operation, not the current one. - * - * @param dap the DAP - * @param instr JTAG_DP_APACC (AP access) or JTAG_DP_DPACC (DP access) - * @param reg_addr two significant bits; A[3:2]; for APACC access, the - * SELECT register has more addressing bits. - * @param RnW false iff outvalue will be written to the DP or AP - * @param outvalue points to a 32-bit (little-endian) integer - * @param invalue NULL, or points to a 32-bit (little-endian) integer - * @param ack points to where the three bit JTAG_ACK_* code will be stored - * @param memaccess_tck number of idle cycles to add after AP access - */ - -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, - uint32_t memaccess_tck, uint8_t *ack) -{ - struct dap_cmd *cmd; - int retval; - - 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; - - retval = adi_jtag_dp_scan_cmd(dap, cmd, ack); - if (retval == ERROR_OK) - list_add_tail(&cmd->lh, &dap->cmd_journal); - - return retval; -} - -/** - * Scan DPACC or APACC out and in from host ordered uint32_t buffers. - * This is exactly like adi_jtag_dp_scan(), except that endianness - * conversions are performed (so the types of invalue and outvalue - * must be different). - */ -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, - uint32_t memaccess_tck, uint8_t *ack) -{ - uint8_t out_value_buf[4]; - int retval; - - 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, memaccess_tck, ack); - if (retval != ERROR_OK) - return retval; - - if (invalue) - jtag_add_callback(arm_le_to_h_u32, - (jtag_callback_data_t) invalue); - - return retval; -} - -static int adi_jtag_finish_read(struct adiv5_dap *dap) -{ - int retval = ERROR_OK; - - if (dap->last_read != NULL) { - 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, - uint8_t instr, uint8_t reg_addr, uint8_t RnW, - uint32_t outvalue, uint32_t *invalue, uint32_t memaccess_tck) -{ - int retval; - - /* Issue the read or write */ - retval = adi_jtag_dp_scan_u32(dap, instr, reg_addr, - 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)) { - retval = adi_jtag_dp_scan_u32(dap, JTAG_DP_DPACC, - DP_RDBUFF, DPAP_READ, 0, invalue, 0, NULL); - if (retval != ERROR_OK) - return retval; - } - - return jtag_execute_queue(); -} - -static int jtagdp_overrun_check(struct adiv5_dap *dap) -{ - int retval; - struct dap_cmd *el, *tmp, *prev = NULL; - int found_wait = 0; - int64_t time_now; - LIST_HEAD(replay_list); - - /* 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; - } - } - - /* - * 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; - } - } - - 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; - } - } - - /* we're done with this command, release it */ - free(tmp); - - if (retval != ERROR_OK) - goto done; - - } - /* 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; - } - } - - /* 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); - } - - /* we're done with the journal, flush it */ - flush_journal(&dap->cmd_journal); - - /* 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); - - 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 */ - 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"); - retval = ERROR_JTAG_DEVICE_ERROR; - goto done; - } - - 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) - goto done; - - if (ctrlstat & SSTICKYERR) { - retval = ERROR_JTAG_DEVICE_ERROR; - goto done; - } - } - - done: - flush_journal(&dap->cmd_journal); - return retval; -} - -/*--------------------------------------------------------------------------*/ - -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, 0, NULL); - dap->last_read = data; - return retval; -} - -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, 0, NULL); - dap->last_read = NULL; - return retval; -} - -/** Select the AP register bank matching bits 7:4 of reg. */ -static int jtag_ap_q_bankselect(struct adiv5_ap *ap, unsigned reg) -{ - struct adiv5_dap *dap = ap->dap; - uint32_t sel = ((uint32_t)ap->ap_num << 24) | (reg & 0x000000F0); - - if (sel == dap->select) - return ERROR_OK; - - dap->select = sel; - - return jtag_dp_q_write(dap, DP_SELECT, sel); -} - -static int jtag_ap_q_read(struct adiv5_ap *ap, unsigned reg, - uint32_t *data) -{ - int retval = jtag_ap_q_bankselect(ap, reg); - if (retval != ERROR_OK) - return retval; - - retval = adi_jtag_dp_scan_u32(ap->dap, JTAG_DP_APACC, reg, - DPAP_READ, 0, ap->dap->last_read, ap->memaccess_tck, NULL); - ap->dap->last_read = data; - - return retval; -} - -static int jtag_ap_q_write(struct adiv5_ap *ap, unsigned reg, - uint32_t data) -{ - int retval = jtag_ap_q_bankselect(ap, reg); - if (retval != ERROR_OK) - return retval; - - retval = adi_jtag_dp_scan_u32(ap->dap, JTAG_DP_APACC, reg, - DPAP_WRITE, data, ap->dap->last_read, ap->memaccess_tck, NULL); - ap->dap->last_read = NULL; - return retval; -} - -static int jtag_ap_q_abort(struct adiv5_dap *dap, uint8_t *ack) -{ - /* for JTAG, this is the only valid ABORT register operation */ - 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) -{ - 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 - * part of DAP setup -*/ -const struct dap_ops jtag_dp_ops = { - .queue_dp_read = jtag_dp_q_read, - .queue_dp_write = jtag_dp_q_write, - .queue_ap_read = jtag_ap_q_read, - .queue_ap_write = jtag_ap_q_write, - .queue_ap_abort = jtag_ap_q_abort, - .run = jtag_dp_run, - .sync = jtag_dp_sync, -}; - - -static const uint8_t swd2jtag_bitseq[] = { - /* More than 50 TCK/SWCLK cycles with TMS/SWDIO high, - * putting both JTAG and SWD logic into reset state. - */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - /* Switching equence disables SWD and enables JTAG - * NOTE: bits in the DP's IDCODE can expose the need for - * the old/deprecated sequence (0xae 0xde). - */ - 0x3c, 0xe7, - /* At least 50 TCK/SWCLK cycles with TMS/SWDIO high, - * putting both JTAG and SWD logic into reset state. - * NOTE: some docs say "at least 5". - */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -}; - -/** Put the debug link into JTAG mode, if the target supports it. - * The link's initial mode may be either SWD or JTAG. - * - * @param target Enters JTAG mode (if possible). - * - * Note that targets implemented with SW-DP do not support JTAG, and - * that some targets which could otherwise support it may have been - * configured to disable JTAG signaling - * - * @return ERROR_OK or else a fault code. - */ -int dap_to_jtag(struct target *target) -{ - int retval; - - LOG_DEBUG("Enter JTAG mode"); - - /* REVISIT it's nasty to need to make calls to a "jtag" - * subsystem if the link isn't in JTAG mode... - */ - - retval = jtag_add_tms_seq(8 * sizeof(swd2jtag_bitseq), - swd2jtag_bitseq, TAP_RESET); - if (retval == ERROR_OK) - retval = jtag_execute_queue(); - - /* REVISIT set up the DAP's ops vector for JTAG mode. */ - - return retval; -} diff --git a/src/target/adi_v5_swd.c b/src/target/adi_v5_swd.c deleted file mode 100644 index 41ddbd789..000000000 --- a/src/target/adi_v5_swd.c +++ /dev/null @@ -1,451 +0,0 @@ -/*************************************************************************** - * - * Copyright (C) 2010 by David Brownell - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - ***************************************************************************/ - -/** - * @file - * Utilities to support ARM "Serial Wire Debug" (SWD), a low pin-count debug - * link protocol used in cases where JTAG is not wanted. This is coupled to - * recent versions of ARM's "CoreSight" debug framework. This specific code - * is a transport level interface, with "target/arm_adi_v5.[hc]" code - * understanding operation semantics, shared with the JTAG transport. - * - * Single-DAP support only. - * - * for details, see "ARM IHI 0031A" - * ARM Debug Interface v5 Architecture Specification - * especially section 5.3 for SWD protocol - * - * On many chips (most current Cortex-M3 parts) SWD is a run-time alternative - * to JTAG. Boards may support one or both. There are also SWD-only chips, - * (using SW-DP not SWJ-DP). - * - * Even boards that also support JTAG can benefit from SWD support, because - * usually there's no way to access the SWO trace view mechanism in JTAG mode. - * That is, trace access may require SWD support. - * - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "arm.h" -#include "arm_adi_v5.h" -#include - -#include -#include - -#include - -/* YUK! - but this is currently a global.... */ -extern struct jtag_interface *jtag_interface; -static bool do_sync; - -static void swd_finish_read(struct adiv5_dap *dap) -{ - const struct swd_driver *swd = jtag_interface->swd; - if (dap->last_read != NULL) { - swd->read_reg(swd_cmd(true, false, DP_RDBUFF), dap->last_read, 0); - dap->last_read = NULL; - } -} - -static int swd_queue_dp_write(struct adiv5_dap *dap, unsigned reg, - uint32_t data); -static int swd_queue_dp_read(struct adiv5_dap *dap, unsigned reg, - uint32_t *data); - -static void swd_clear_sticky_errors(struct adiv5_dap *dap) -{ - const struct swd_driver *swd = jtag_interface->swd; - assert(swd); - - swd->write_reg(swd_cmd(false, false, DP_ABORT), - STKCMPCLR | STKERRCLR | WDERRCLR | ORUNERRCLR, 0); -} - -static int swd_run_inner(struct adiv5_dap *dap) -{ - const struct swd_driver *swd = jtag_interface->swd; - int retval; - - retval = swd->run(); - - if (retval != ERROR_OK) { - /* fault response */ - dap->do_reconnect = true; - } - - return retval; -} - -static int swd_connect(struct adiv5_dap *dap) -{ - uint32_t dpidr; - int status; - - /* FIXME validate transport config ... is the - * configured DAP present (check IDCODE)? - * Is *only* one DAP configured? - * - * 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); - - /* Clear link state, including the SELECT cache. */ - dap->do_reconnect = false; - dap->select = DP_SELECT_INVALID; - - swd_queue_dp_read(dap, DP_DPIDR, &dpidr); - - /* force clear all sticky faults */ - swd_clear_sticky_errors(dap); - - status = swd_run_inner(dap); - - if (status == ERROR_OK) { - LOG_INFO("SWD DPIDR %#8.8" PRIx32, dpidr); - dap->do_reconnect = false; - } else - dap->do_reconnect = true; - - return status; -} - -static inline int check_sync(struct adiv5_dap *dap) -{ - return do_sync ? swd_run_inner(dap) : ERROR_OK; -} - -static int swd_check_reconnect(struct adiv5_dap *dap) -{ - if (dap->do_reconnect) - return swd_connect(dap); - - return ERROR_OK; -} - -static int swd_queue_ap_abort(struct adiv5_dap *dap, uint8_t *ack) -{ - const struct swd_driver *swd = jtag_interface->swd; - assert(swd); - - swd->write_reg(swd_cmd(false, false, DP_ABORT), - DAPABORT | STKCMPCLR | STKERRCLR | WDERRCLR | ORUNERRCLR, 0); - return check_sync(dap); -} - -/** Select the DP register bank matching bits 7:4 of reg. */ -static void swd_queue_dp_bankselect(struct adiv5_dap *dap, unsigned reg) -{ - /* Only register address 4 is banked. */ - if ((reg & 0xf) != 4) - return; - - uint32_t select_dp_bank = (reg & 0x000000F0) >> 4; - uint32_t sel = select_dp_bank - | (dap->select & (DP_SELECT_APSEL | DP_SELECT_APBANK)); - - if (sel == dap->select) - return; - - dap->select = sel; - - swd_queue_dp_write(dap, DP_SELECT, sel); -} - -static int swd_queue_dp_read(struct adiv5_dap *dap, unsigned reg, - uint32_t *data) -{ - const struct swd_driver *swd = jtag_interface->swd; - assert(swd); - - int retval = swd_check_reconnect(dap); - if (retval != ERROR_OK) - return retval; - - swd_queue_dp_bankselect(dap, reg); - swd->read_reg(swd_cmd(true, false, reg), data, 0); - - return check_sync(dap); -} - -static int swd_queue_dp_write(struct adiv5_dap *dap, unsigned reg, - uint32_t data) -{ - const struct swd_driver *swd = jtag_interface->swd; - assert(swd); - - int retval = swd_check_reconnect(dap); - if (retval != ERROR_OK) - return retval; - - swd_finish_read(dap); - swd_queue_dp_bankselect(dap, reg); - swd->write_reg(swd_cmd(false, false, reg), data, 0); - - return check_sync(dap); -} - -/** Select the AP register bank matching bits 7:4 of reg. */ -static void swd_queue_ap_bankselect(struct adiv5_ap *ap, unsigned reg) -{ - struct adiv5_dap *dap = ap->dap; - uint32_t sel = ((uint32_t)ap->ap_num << 24) - | (reg & 0x000000F0) - | (dap->select & DP_SELECT_DPBANK); - - if (sel == dap->select) - return; - - dap->select = sel; - - swd_queue_dp_write(dap, DP_SELECT, sel); -} - -static int swd_queue_ap_read(struct adiv5_ap *ap, unsigned reg, - uint32_t *data) -{ - const struct swd_driver *swd = jtag_interface->swd; - assert(swd); - - struct adiv5_dap *dap = ap->dap; - - int retval = swd_check_reconnect(dap); - if (retval != ERROR_OK) - return retval; - - swd_queue_ap_bankselect(ap, reg); - swd->read_reg(swd_cmd(true, true, reg), dap->last_read, ap->memaccess_tck); - dap->last_read = data; - - return check_sync(dap); -} - -static int swd_queue_ap_write(struct adiv5_ap *ap, unsigned reg, - uint32_t data) -{ - const struct swd_driver *swd = jtag_interface->swd; - assert(swd); - - struct adiv5_dap *dap = ap->dap; - - int retval = swd_check_reconnect(dap); - if (retval != ERROR_OK) - return retval; - - swd_finish_read(dap); - swd_queue_ap_bankselect(ap, reg); - swd->write_reg(swd_cmd(false, true, reg), data, ap->memaccess_tck); - - return check_sync(dap); -} - -/** Executes all queued DAP operations. */ -static int swd_run(struct adiv5_dap *dap) -{ - swd_finish_read(dap); - return swd_run_inner(dap); -} - -const struct dap_ops swd_dap_ops = { - .queue_dp_read = swd_queue_dp_read, - .queue_dp_write = swd_queue_dp_write, - .queue_ap_read = swd_queue_ap_read, - .queue_ap_write = swd_queue_ap_write, - .queue_ap_abort = swd_queue_ap_abort, - .run = swd_run, -}; - -/* - * This represents the bits which must be sent out on TMS/SWDIO to - * switch a DAP implemented using an SWJ-DP module into SWD mode. - * These bits are stored (and transmitted) LSB-first. - * - * See the DAP-Lite specification, section 2.2.5 for information - * about making the debug link select SWD or JTAG. (Similar info - * is in a few other ARM documents.) - */ -static const uint8_t jtag2swd_bitseq[] = { - /* More than 50 TCK/SWCLK cycles with TMS/SWDIO high, - * putting both JTAG and SWD logic into reset state. - */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - /* Switching sequence enables SWD and disables JTAG - * NOTE: bits in the DP's IDCODE may expose the need for - * an old/obsolete/deprecated sequence (0xb6 0xed). - */ - 0x9e, 0xe7, - /* More than 50 TCK/SWCLK cycles with TMS/SWDIO high, - * putting both JTAG and SWD logic into reset state. - */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -}; - -/** - * Put the debug link into SWD mode, if the target supports it. - * The link's initial mode may be either JTAG (for example, - * with SWJ-DP after reset) or SWD. - * - * @param target Enters SWD mode (if possible). - * - * Note that targets using the JTAG-DP do not support SWD, and that - * some targets which could otherwise support it may have have been - * configured to disable SWD signaling - * - * @return ERROR_OK or else a fault code. - */ -int dap_to_swd(struct target *target) -{ - struct arm *arm = target_to_arm(target); - int retval; - - if (!arm->dap) { - LOG_ERROR("SWD mode is not available"); - return ERROR_FAIL; - } - - LOG_DEBUG("Enter SWD mode"); - - /* REVISIT it's ugly to need to make calls to a "jtag" - * subsystem if the link may not be in JTAG mode... - */ - - retval = jtag_add_tms_seq(8 * sizeof(jtag2swd_bitseq), - jtag2swd_bitseq, TAP_INVALID); - if (retval == ERROR_OK) - retval = jtag_execute_queue(); - - /* set up the DAP's ops vector for SWD mode. */ - arm->dap->ops = &swd_dap_ops; - - return retval; -} - -static const struct command_registration swd_commands[] = { - { - /* - * Set up SWD and JTAG targets identically, unless/until - * infrastructure improves ... meanwhile, ignore all - * JTAG-specific stuff like IR length for SWD. - * - * REVISIT can we verify "just one SWD DAP" here/early? - */ - .name = "newdap", - .jim_handler = jim_jtag_newtap, - .mode = COMMAND_CONFIG, - .help = "declare a new SWD DAP" - }, - COMMAND_REGISTRATION_DONE -}; - -static const struct command_registration swd_handlers[] = { - { - .name = "swd", - .mode = COMMAND_ANY, - .help = "SWD command group", - .chain = swd_commands, - }, - COMMAND_REGISTRATION_DONE -}; - -static int swd_select(struct command_context *ctx) -{ - int retval; - - retval = register_commands(ctx, NULL, swd_handlers); - - if (retval != ERROR_OK) - return retval; - - const struct swd_driver *swd = jtag_interface->swd; - - /* be sure driver is in SWD mode; start - * with hardware default TRN (1), it can be changed later - */ - if (!swd || !swd->read_reg || !swd->write_reg || !swd->init) { - LOG_DEBUG("no SWD driver?"); - return ERROR_FAIL; - } - - retval = swd->init(); - if (retval != ERROR_OK) { - LOG_DEBUG("can't init SWD driver"); - return retval; - } - - /* force DAP into SWD mode (not JTAG) */ - /*retval = dap_to_swd(target);*/ - - if (ctx->current_target) { - /* force DAP into SWD mode (not JTAG) */ - struct target *target = get_current_target(ctx); - retval = dap_to_swd(target); - } - - return retval; -} - -static int swd_init(struct command_context *ctx) -{ - struct target *target = get_current_target(ctx); - struct arm *arm = target_to_arm(target); - struct adiv5_dap *dap = arm->dap; - /* 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); -} - -static struct transport swd_transport = { - .name = "swd", - .select = swd_select, - .init = swd_init, -}; - -static void swd_constructor(void) __attribute__((constructor)); -static void swd_constructor(void) -{ - transport_register(&swd_transport); -} - -/** Returns true if the current debug session - * is using SWD as its transport. - */ -bool transport_is_swd(void) -{ - return get_current_transport() == &swd_transport; -} diff --git a/src/target/algorithm.c b/src/target/algorithm.c deleted file mode 100644 index 9fc938604..000000000 --- a/src/target/algorithm.c +++ /dev/null @@ -1,52 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "algorithm.h" -#include - -void init_mem_param(struct mem_param *param, uint32_t address, uint32_t size, enum param_direction direction) -{ - param->address = address; - param->size = size; - param->value = malloc(size); - param->direction = direction; -} - -void destroy_mem_param(struct mem_param *param) -{ - free(param->value); - param->value = NULL; -} - -void init_reg_param(struct reg_param *param, char *reg_name, uint32_t size, enum param_direction direction) -{ - param->reg_name = reg_name; - param->size = size; - param->value = malloc(DIV_ROUND_UP(size, 8)); - param->direction = direction; -} - -void destroy_reg_param(struct reg_param *param) -{ - free(param->value); - param->value = NULL; -} diff --git a/src/target/algorithm.h b/src/target/algorithm.h deleted file mode 100644 index d216a8244..000000000 --- a/src/target/algorithm.h +++ /dev/null @@ -1,50 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifndef OPENOCD_TARGET_ALGORITHM_H -#define OPENOCD_TARGET_ALGORITHM_H - -enum param_direction { - PARAM_IN, - PARAM_OUT, - PARAM_IN_OUT -}; - -struct mem_param { - uint32_t address; - uint32_t size; - uint8_t *value; - enum param_direction direction; -}; - -struct reg_param { - const char *reg_name; - uint32_t size; - uint8_t *value; - enum param_direction direction; -}; - -void init_mem_param(struct mem_param *param, - uint32_t address, uint32_t size, enum param_direction dir); -void destroy_mem_param(struct mem_param *param); - -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 /* OPENOCD_TARGET_ALGORITHM_H */ diff --git a/src/target/arm.h b/src/target/arm.h deleted file mode 100644 index 163db239a..000000000 --- a/src/target/arm.h +++ /dev/null @@ -1,243 +0,0 @@ -/* - * Copyright (C) 2005 by Dominic Rath - * Dominic.Rath@gmx.de - * - * Copyright (C) 2008 by Spencer Oliver - * spen@spen-soft.co.uk - * - * Copyright (C) 2009 by Øyvind Harboe - * oyvind.harboe@zylin.com - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef OPENOCD_TARGET_ARM_H -#define OPENOCD_TARGET_ARM_H - -#include -#include "target.h" - - -/** - * @file - * Holds the interface to ARM cores. - * - * At this writing, only "classic ARM" cores built on the ARMv4 register - * and mode model are supported. The Thumb2-only microcontroller profile - * support has not yet been integrated, affecting Cortex-M parts. - */ - -/** - * Represent state of an ARM core. - * - * Most numbers match the five low bits of the *PSR registers on - * "classic ARM" processors, which build on the ARMv4 processor - * modes and register set. - * - * ARM_MODE_ANY is a magic value, often used as a wildcard. - * - * Only the microcontroller cores (ARMv6-M, ARMv7-M) support ARM_MODE_THREAD, - * ARM_MODE_USER_THREAD, and ARM_MODE_HANDLER. Those are the only modes - * they support. - */ -enum arm_mode { - ARM_MODE_USR = 16, - ARM_MODE_FIQ = 17, - ARM_MODE_IRQ = 18, - ARM_MODE_SVC = 19, - 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, - - ARM_MODE_ANY = -1 -}; - -const char *arm_mode_name(unsigned psr_mode); -bool is_arm_mode(unsigned psr_mode); - -/** The PSR "T" and "J" bits define the mode of "classic ARM" cores. */ -enum arm_state { - ARM_STATE_ARM, - ARM_STATE_THUMB, - ARM_STATE_JAZELLE, - ARM_STATE_THUMB_EE, -}; - -#define ARM_COMMON_MAGIC 0x0A450A45 - -/** - * Represents a generic ARM core, with standard application registers. - * - * There are sixteen application registers (including PC, SP, LR) and a PSR. - * Cortex-M series cores do not support as many core states or shadowed - * registers as traditional ARM cores, and only support Thumb2 instructions. - */ -struct arm { - int common_magic; - struct reg_cache *core_cache; - - /** Handle to the PC; valid in all core modes. */ - struct reg *pc; - - /** Handle to the CPSR/xPSR; valid in all core modes. */ - struct reg *cpsr; - - /** Handle to the SPSR; valid only in core modes with an SPSR. */ - struct reg *spsr; - - /** Support for arm_reg_current() */ - const int *map; - - /** - * Indicates what registers are in the ARM state core register set. - * ARM_MODE_ANY indicates the standard set of 37 registers, - * seen on for example ARM7TDMI cores. ARM_MODE_MON indicates three - * more registers are shadowed, for "Secure Monitor" mode. - * ARM_MODE_THREAD indicates a microcontroller profile core, - * which only shadows SP. - */ - enum arm_mode core_type; - - /** Record the current core mode: SVC, USR, or some other mode. */ - enum arm_mode core_mode; - - /** Record the current core state: ARM, Thumb, or otherwise. */ - enum arm_state core_state; - - /** Flag reporting unavailability of the BKPT instruction. */ - bool is_armv4; - - /** Flag reporting armv6m based core. */ - bool is_armv6m; - - /** Flag reporting whether semihosting is active. */ - bool is_semihosting; - - /** Value to be returned by semihosting SYS_ERRNO request. */ - int semihosting_errno; - - int (*setup_semihosting)(struct target *target, int enable); - - /** Backpointer to the target. */ - struct target *target; - - /** Handle for the debug module, if one is present. */ - struct arm_dpm *dpm; - - /** Handle for the Embedded Trace Module, if one is present. */ - struct etm_context *etm; - - /* FIXME all these methods should take "struct arm *" not target */ - - /** Retrieve all core registers, for display. */ - int (*full_context)(struct target *target); - - /** Retrieve a single core register. */ - int (*read_core_reg)(struct target *target, struct reg *reg, - int num, enum arm_mode mode); - int (*write_core_reg)(struct target *target, struct reg *reg, - int num, enum arm_mode mode, uint8_t *value); - - /** Read coprocessor register. */ - int (*mrc)(struct target *target, int cpnum, - uint32_t op1, uint32_t op2, - uint32_t CRn, uint32_t CRm, - uint32_t *value); - - /** Write coprocessor register. */ - int (*mcr)(struct target *target, int cpnum, - uint32_t op1, uint32_t op2, - uint32_t CRn, uint32_t CRm, - uint32_t value); - - void *arch_info; - - /** For targets conforming to ARM Debug Interface v5, - * this handle references the Debug Access Port (DAP) - * used to make requests to the target. - */ - struct adiv5_dap *dap; -}; - -/** Convert target handle to generic ARM target state handle. */ -static inline struct arm *target_to_arm(struct target *target) -{ - assert(target != NULL); - return target->arch_info; -} - -static inline bool is_arm(struct arm *arm) -{ - assert(arm != NULL); - return arm->common_magic == ARM_COMMON_MAGIC; -} - -struct arm_algorithm { - int common_magic; - - enum arm_mode core_mode; - enum arm_state core_state; -}; - -struct arm_reg { - int num; - enum arm_mode mode; - struct target *target; - struct arm *arm; - uint8_t value[4]; -}; - -struct reg_cache *arm_build_reg_cache(struct target *target, struct arm *arm); - -extern const struct command_registration arm_command_handlers[]; - -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 arm_init_arch_info(struct target *target, struct arm *arm); - -/* REVISIT rename this once it's usable by ARMv7-M */ -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, - int timeout_ms, void *arch_info); -int armv4_5_run_algorithm_inner(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, - int (*run_it)(struct target *target, uint32_t exit_point, - int timeout_ms, void *arch_info)); - -int arm_checksum_memory(struct target *target, - uint32_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); - -void arm_set_cpsr(struct arm *arm, uint32_t cpsr); -struct reg *arm_reg_current(struct arm *arm, unsigned regnum); - -extern struct reg arm_gdb_dummy_fp_reg; -extern struct reg arm_gdb_dummy_fps_reg; - -#endif /* OPENOCD_TARGET_ARM_H */ diff --git a/src/target/arm11.c b/src/target/arm11.c deleted file mode 100644 index cbe4d4503..000000000 --- a/src/target/arm11.c +++ /dev/null @@ -1,1382 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2008 digenius technology GmbH. * - * Michael Bruck * - * * - * Copyright (C) 2008,2009 Oyvind Harboe oyvind.harboe@zylin.com * - * * - * Copyright (C) 2008 Georg Acher * - * * - * Copyright (C) 2009 David Brownell * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "etm.h" -#include "breakpoints.h" -#include "arm11_dbgtap.h" -#include "arm_simulator.h" -#include -#include "target_type.h" -#include "algorithm.h" -#include "register.h" -#include "arm_opcodes.h" - -#if 0 -#define _DEBUG_INSTRUCTION_EXECUTION_ -#endif - - -static int arm11_step(struct target *target, int current, - uint32_t address, int handle_breakpoints); - - -/** Check and if necessary take control of the system - * - * \param arm11 Target state variable. - */ -static int arm11_check_init(struct arm11_common *arm11) -{ - CHECK_RETVAL(arm11_read_DSCR(arm11)); - - if (!(arm11->dscr & DSCR_HALT_DBG_MODE)) { - LOG_DEBUG("DSCR %08x", (unsigned) arm11->dscr); - LOG_DEBUG("Bringing target into debug mode"); - - arm11->dscr |= DSCR_HALT_DBG_MODE; - CHECK_RETVAL(arm11_write_DSCR(arm11, arm11->dscr)); - - /* add further reset initialization here */ - - arm11->simulate_reset_on_next_halt = true; - - if (arm11->dscr & DSCR_CORE_HALTED) { - /** \todo TODO: this needs further scrutiny because - * arm11_debug_entry() never gets called. (WHY NOT?) - * As a result we don't read the actual register states from - * the target. - */ - - arm11->arm.target->state = TARGET_HALTED; - arm_dpm_report_dscr(arm11->arm.dpm, arm11->dscr); - } else { - arm11->arm.target->state = TARGET_RUNNING; - arm11->arm.target->debug_reason = DBG_REASON_NOTHALTED; - } - - CHECK_RETVAL(arm11_sc7_clear_vbw(arm11)); - } - - return ERROR_OK; -} - -/** - * Save processor state. This is called after a HALT instruction - * succeeds, and on other occasions the processor enters debug mode - * (breakpoint, watchpoint, etc). Caller has updated arm11->dscr. - */ -static int arm11_debug_entry(struct arm11_common *arm11) -{ - int retval; - - arm11->arm.target->state = TARGET_HALTED; - arm_dpm_report_dscr(arm11->arm.dpm, arm11->dscr); - - /* REVISIT entire cache should already be invalid !!! */ - register_cache_invalidate(arm11->arm.core_cache); - - /* See e.g. ARM1136 TRM, "14.8.4 Entering Debug state" */ - - /* maybe save wDTR (pending DCC write to debug SW, e.g. libdcc) */ - arm11->is_wdtr_saved = !!(arm11->dscr & DSCR_DTR_TX_FULL); - if (arm11->is_wdtr_saved) { - arm11_add_debug_SCAN_N(arm11, 0x05, ARM11_TAP_DEFAULT); - - arm11_add_IR(arm11, ARM11_INTEST, ARM11_TAP_DEFAULT); - - struct scan_field chain5_fields[3]; - - arm11_setup_field(arm11, 32, NULL, - &arm11->saved_wdtr, chain5_fields + 0); - arm11_setup_field(arm11, 1, NULL, NULL, chain5_fields + 1); - arm11_setup_field(arm11, 1, NULL, NULL, chain5_fields + 2); - - arm11_add_dr_scan_vc(arm11->arm.target->tap, ARRAY_SIZE( - chain5_fields), chain5_fields, TAP_DRPAUSE); - - } - - /* DSCR: set the Execute ARM instruction enable bit. - * - * ARM1176 spec says this is needed only for wDTR/rDTR's "ITR mode", - * but not to issue ITRs(?). The ARMv7 arch spec says it's required - * for executing instructions via ITR. - */ - CHECK_RETVAL(arm11_write_DSCR(arm11, DSCR_ITR_EN | arm11->dscr)); - - - /* From the spec: - Before executing any instruction in debug state you have to drain the write buffer. - This ensures that no imprecise Data Aborts can return at a later point:*/ - - /** \todo TODO: Test drain write buffer. */ - -#if 0 - while (1) { - /* MRC p14,0,R0,c5,c10,0 */ - /* arm11_run_instr_no_data1(arm11, / *0xee150e1a* /0xe320f000); */ - - /* mcr 15, 0, r0, cr7, cr10, {4} */ - arm11_run_instr_no_data1(arm11, 0xee070f9a); - - uint32_t dscr = arm11_read_DSCR(arm11); - - LOG_DEBUG("DRAIN, DSCR %08x", dscr); - - if (dscr & ARM11_DSCR_STICKY_IMPRECISE_DATA_ABORT) { - arm11_run_instr_no_data1(arm11, 0xe320f000); - - dscr = arm11_read_DSCR(arm11); - - LOG_DEBUG("DRAIN, DSCR %08x (DONE)", dscr); - - break; - } - } -#endif - - /* Save registers. - * - * NOTE: ARM1136 TRM suggests saving just R0 here now, then - * CPSR and PC after the rDTR stuff. We do it all at once. - */ - retval = arm_dpm_read_current_registers(&arm11->dpm); - if (retval != ERROR_OK) - LOG_ERROR("DPM REG READ -- fail"); - - retval = arm11_run_instr_data_prepare(arm11); - if (retval != ERROR_OK) - return retval; - - /* maybe save rDTR (pending DCC read from debug SW, e.g. libdcc) */ - arm11->is_rdtr_saved = !!(arm11->dscr & DSCR_DTR_RX_FULL); - if (arm11->is_rdtr_saved) { - /* MRC p14,0,R0,c0,c5,0 (move rDTR -> r0 (-> wDTR -> local var)) */ - retval = arm11_run_instr_data_from_core_via_r0(arm11, - 0xEE100E15, &arm11->saved_rdtr); - if (retval != ERROR_OK) - return retval; - } - - /* REVISIT Now that we've saved core state, there's may also - * be MMU and cache state to care about ... - */ - - if (arm11->simulate_reset_on_next_halt) { - arm11->simulate_reset_on_next_halt = false; - - LOG_DEBUG("Reset c1 Control Register"); - - /* Write 0 (reset value) to Control register 0 to disable MMU/Cache etc. */ - - /* MCR p15,0,R0,c1,c0,0 */ - retval = arm11_run_instr_data_to_core_via_r0(arm11, 0xee010f10, 0); - if (retval != ERROR_OK) - return retval; - - } - - if (arm11->arm.target->debug_reason == DBG_REASON_WATCHPOINT) { - uint32_t wfar; - - /* MRC p15, 0, , c6, c0, 1 ; Read WFAR */ - retval = arm11_run_instr_data_from_core_via_r0(arm11, - ARMV4_5_MRC(15, 0, 0, 6, 0, 1), - &wfar); - if (retval != ERROR_OK) - return retval; - arm_dpm_report_wfar(arm11->arm.dpm, wfar); - } - - - retval = arm11_run_instr_data_finish(arm11); - if (retval != ERROR_OK) - return retval; - - return ERROR_OK; -} - -/** - * Restore processor state. This is called in preparation for - * the RESTART function. - */ -static int arm11_leave_debug_state(struct arm11_common *arm11, bool bpwp) -{ - int retval; - - /* See e.g. ARM1136 TRM, "14.8.5 Leaving Debug state" */ - - /* NOTE: the ARM1136 TRM suggests restoring all registers - * except R0/PC/CPSR right now. Instead, we do them all - * at once, just a bit later on. - */ - - /* REVISIT once we start caring about MMU and cache state, - * address it here ... - */ - - /* spec says clear wDTR and rDTR; we assume they are clear as - otherwise our programming would be sloppy */ - { - CHECK_RETVAL(arm11_read_DSCR(arm11)); - - if (arm11->dscr & (DSCR_DTR_RX_FULL | DSCR_DTR_TX_FULL)) { - /* - The wDTR/rDTR two registers that are used to send/receive data to/from - the core in tandem with corresponding instruction codes that are - written into the core. The RDTR FULL/WDTR FULL flag indicates that the - registers hold data that was written by one side (CPU or JTAG) and not - read out by the other side. - */ - LOG_ERROR("wDTR/rDTR inconsistent (DSCR %08x)", - (unsigned) arm11->dscr); - return ERROR_FAIL; - } - } - - /* maybe restore original wDTR */ - if (arm11->is_wdtr_saved) { - retval = arm11_run_instr_data_prepare(arm11); - if (retval != ERROR_OK) - return retval; - - /* MCR p14,0,R0,c0,c5,0 */ - retval = arm11_run_instr_data_to_core_via_r0(arm11, - 0xee000e15, arm11->saved_wdtr); - if (retval != ERROR_OK) - return retval; - - retval = arm11_run_instr_data_finish(arm11); - if (retval != ERROR_OK) - return retval; - } - - /* restore CPSR, PC, and R0 ... after flushing any modified - * registers. - */ - CHECK_RETVAL(arm_dpm_write_dirty_registers(&arm11->dpm, bpwp)); - - CHECK_RETVAL(arm11_bpwp_flush(arm11)); - - register_cache_invalidate(arm11->arm.core_cache); - - /* restore DSCR */ - CHECK_RETVAL(arm11_write_DSCR(arm11, arm11->dscr)); - - /* maybe restore rDTR */ - if (arm11->is_rdtr_saved) { - arm11_add_debug_SCAN_N(arm11, 0x05, ARM11_TAP_DEFAULT); - - arm11_add_IR(arm11, ARM11_EXTEST, ARM11_TAP_DEFAULT); - - struct scan_field chain5_fields[3]; - - uint8_t Ready = 0; /* ignored */ - uint8_t Valid = 0; /* ignored */ - - arm11_setup_field(arm11, 32, &arm11->saved_rdtr, - NULL, chain5_fields + 0); - arm11_setup_field(arm11, 1, &Ready, NULL, chain5_fields + 1); - arm11_setup_field(arm11, 1, &Valid, NULL, chain5_fields + 2); - - arm11_add_dr_scan_vc(arm11->arm.target->tap, ARRAY_SIZE( - chain5_fields), chain5_fields, TAP_DRPAUSE); - } - - /* now processor is ready to RESTART */ - - return ERROR_OK; -} - -/* poll current target status */ -static int arm11_poll(struct target *target) -{ - int retval; - struct arm11_common *arm11 = target_to_arm11(target); - - CHECK_RETVAL(arm11_check_init(arm11)); - - if (arm11->dscr & DSCR_CORE_HALTED) { - if (target->state != TARGET_HALTED) { - enum target_state old_state = target->state; - - LOG_DEBUG("enter TARGET_HALTED"); - retval = arm11_debug_entry(arm11); - if (retval != ERROR_OK) - return retval; - - target_call_event_callbacks(target, - (old_state == TARGET_DEBUG_RUNNING) - ? TARGET_EVENT_DEBUG_HALTED - : TARGET_EVENT_HALTED); - } - } else { - if (target->state != TARGET_RUNNING && target->state != TARGET_DEBUG_RUNNING) { - LOG_DEBUG("enter TARGET_RUNNING"); - target->state = TARGET_RUNNING; - target->debug_reason = DBG_REASON_NOTHALTED; - } - } - - return ERROR_OK; -} -/* architecture specific status reply */ -static int arm11_arch_state(struct target *target) -{ - struct arm11_common *arm11 = target_to_arm11(target); - int retval; - - retval = arm_arch_state(target); - - /* REVISIT also display ARM11-specific MMU and cache status ... */ - - if (target->debug_reason == DBG_REASON_WATCHPOINT) - LOG_USER("Watchpoint triggered at PC %#08x", - (unsigned) arm11->dpm.wp_pc); - - return retval; -} - -/* target execution control */ -static int arm11_halt(struct target *target) -{ - struct arm11_common *arm11 = target_to_arm11(target); - - LOG_DEBUG("target->state: %s", - target_state_name(target)); - - if (target->state == TARGET_UNKNOWN) - arm11->simulate_reset_on_next_halt = true; - - if (target->state == TARGET_HALTED) { - LOG_DEBUG("target was already halted"); - return ERROR_OK; - } - - arm11_add_IR(arm11, ARM11_HALT, TAP_IDLE); - - CHECK_RETVAL(jtag_execute_queue()); - - int i = 0; - - while (1) { - CHECK_RETVAL(arm11_read_DSCR(arm11)); - - if (arm11->dscr & DSCR_CORE_HALTED) - break; - - - int64_t then = 0; - if (i == 1000) - then = timeval_ms(); - if (i >= 1000) { - if ((timeval_ms()-then) > 1000) { - LOG_WARNING("Timeout (1000ms) waiting for instructions to complete"); - return ERROR_FAIL; - } - } - i++; - } - - enum target_state old_state = target->state; - - CHECK_RETVAL(arm11_debug_entry(arm11)); - - CHECK_RETVAL( - target_call_event_callbacks(target, - old_state == - TARGET_DEBUG_RUNNING ? TARGET_EVENT_DEBUG_HALTED : TARGET_EVENT_HALTED)); - - return ERROR_OK; -} - -static uint32_t arm11_nextpc(struct arm11_common *arm11, int current, uint32_t address) -{ - void *value = arm11->arm.pc->value; - - /* 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) -{ - /* LOG_DEBUG("current %d address %08x handle_breakpoints %d debug_execution %d", */ - /* current, address, handle_breakpoints, debug_execution); */ - - struct arm11_common *arm11 = target_to_arm11(target); - - LOG_DEBUG("target->state: %s", - target_state_name(target)); - - - if (target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - address = arm11_nextpc(arm11, current, address); - - LOG_DEBUG("RESUME PC %08" PRIx32 "%s", address, !current ? "!" : ""); - - /* clear breakpoints/watchpoints and VCR*/ - CHECK_RETVAL(arm11_sc7_clear_vbw(arm11)); - - if (!debug_execution) - target_free_all_working_areas(target); - - /* Should we skip over breakpoints matching the PC? */ - if (handle_breakpoints) { - struct breakpoint *bp; - - for (bp = target->breakpoints; bp; bp = bp->next) { - if (bp->address == address) { - LOG_DEBUG("must step over %08" PRIx32 "", bp->address); - arm11_step(target, 1, 0, 0); - break; - } - } - } - - /* activate all breakpoints */ - if (true) { - struct breakpoint *bp; - unsigned brp_num = 0; - - for (bp = target->breakpoints; bp; bp = bp->next) { - struct arm11_sc7_action brp[2]; - - brp[0].write = 1; - brp[0].address = ARM11_SC7_BVR0 + brp_num; - brp[0].value = bp->address; - brp[1].write = 1; - brp[1].address = ARM11_SC7_BCR0 + brp_num; - brp[1].value = 0x1 | - (3 << - 1) | (0x0F << 5) | (0 << 14) | (0 << 16) | (0 << 20) | (0 << 21); - - CHECK_RETVAL(arm11_sc7_run(arm11, brp, ARRAY_SIZE(brp))); - - LOG_DEBUG("Add BP %d at %08" PRIx32, brp_num, - bp->address); - - brp_num++; - } - - if (arm11->vcr) - CHECK_RETVAL(arm11_sc7_set_vcr(arm11, arm11->vcr)); - } - - /* activate all watchpoints and breakpoints */ - CHECK_RETVAL(arm11_leave_debug_state(arm11, true)); - - arm11_add_IR(arm11, ARM11_RESTART, TAP_IDLE); - - CHECK_RETVAL(jtag_execute_queue()); - - int i = 0; - while (1) { - CHECK_RETVAL(arm11_read_DSCR(arm11)); - - LOG_DEBUG("DSCR %08x", (unsigned) arm11->dscr); - - if (arm11->dscr & DSCR_CORE_RESTARTED) - break; - - - int64_t then = 0; - if (i == 1000) - then = timeval_ms(); - if (i >= 1000) { - if ((timeval_ms()-then) > 1000) { - LOG_WARNING("Timeout (1000ms) waiting for instructions to complete"); - return ERROR_FAIL; - } - } - i++; - } - - target->debug_reason = DBG_REASON_NOTHALTED; - if (!debug_execution) - target->state = TARGET_RUNNING; - else - target->state = TARGET_DEBUG_RUNNING; - CHECK_RETVAL(target_call_event_callbacks(target, TARGET_EVENT_RESUMED)); - - return ERROR_OK; -} - -static int arm11_step(struct target *target, int current, - uint32_t address, int handle_breakpoints) -{ - LOG_DEBUG("target->state: %s", - target_state_name(target)); - - if (target->state != TARGET_HALTED) { - LOG_WARNING("target was not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - struct arm11_common *arm11 = target_to_arm11(target); - - address = arm11_nextpc(arm11, current, address); - - LOG_DEBUG("STEP PC %08" PRIx32 "%s", address, !current ? "!" : ""); - - - /** \todo TODO: Thumb not supported here */ - - uint32_t next_instruction; - - CHECK_RETVAL(arm11_read_memory_word(arm11, address, &next_instruction)); - - /* skip over BKPT */ - if ((next_instruction & 0xFFF00070) == 0xe1200070) { - address = arm11_nextpc(arm11, 0, address + 4); - LOG_DEBUG("Skipping BKPT %08" PRIx32, 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); - } - /* ignore B to self */ - else if ((next_instruction & 0xFEFFFFFF) == 0xeafffffe) - LOG_DEBUG("Not stepping jump to self"); - else { - /** \todo TODO: check if break-/watchpoints make any sense at all in combination - * with this. */ - - /** \todo TODO: check if disabling IRQs might be a good idea here. Alternatively - * the VCR might be something worth looking into. */ - - - /* Set up breakpoint for stepping */ - - struct arm11_sc7_action brp[2]; - - brp[0].write = 1; - brp[0].address = ARM11_SC7_BVR0; - brp[1].write = 1; - brp[1].address = ARM11_SC7_BCR0; - - if (arm11->hardware_step) { - /* Hardware single stepping ("instruction address - * mismatch") is used if enabled. It's not quite - * exactly "run one instruction"; "branch to here" - * loops won't break, neither will some other cases, - * but it's probably the best default. - * - * Hardware single stepping isn't supported on v6 - * debug modules. ARM1176 and v7 can support it... - * - * FIXME Thumb stepping likely needs to use 0x03 - * or 0xc0 byte masks, not 0x0f. - */ - brp[0].value = address; - brp[1].value = 0x1 | (3 << 1) | (0x0F << 5) - | (0 << 14) | (0 << 16) | (0 << 20) - | (2 << 21); - } else { - /* Sets a breakpoint on the next PC, as calculated - * by instruction set simulation. - * - * REVISIT stepping Thumb on ARM1156 requires Thumb2 - * support from the simulator. - */ - uint32_t next_pc; - int retval; - - retval = arm_simulate_step(target, &next_pc); - if (retval != ERROR_OK) - return retval; - - brp[0].value = next_pc; - brp[1].value = 0x1 | (3 << 1) | (0x0F << 5) - | (0 << 14) | (0 << 16) | (0 << 20) - | (0 << 21); - } - - CHECK_RETVAL(arm11_sc7_run(arm11, brp, ARRAY_SIZE(brp))); - - /* resume */ - - - if (arm11->step_irq_enable) - /* this disable should be redundant ... */ - arm11->dscr &= ~DSCR_INT_DIS; - else - arm11->dscr |= DSCR_INT_DIS; - - - CHECK_RETVAL(arm11_leave_debug_state(arm11, handle_breakpoints)); - - arm11_add_IR(arm11, ARM11_RESTART, TAP_IDLE); - - CHECK_RETVAL(jtag_execute_queue()); - - /* wait for halt */ - int i = 0; - - while (1) { - const uint32_t mask = DSCR_CORE_RESTARTED - | DSCR_CORE_HALTED; - - CHECK_RETVAL(arm11_read_DSCR(arm11)); - LOG_DEBUG("DSCR %08x e", (unsigned) arm11->dscr); - - if ((arm11->dscr & mask) == mask) - break; - - long long then = 0; - if (i == 1000) - then = timeval_ms(); - if (i >= 1000) { - if ((timeval_ms()-then) > 1000) { - LOG_WARNING( - "Timeout (1000ms) waiting for instructions to complete"); - return ERROR_FAIL; - } - } - i++; - } - - /* clear breakpoint */ - CHECK_RETVAL(arm11_sc7_clear_vbw(arm11)); - - /* save state */ - CHECK_RETVAL(arm11_debug_entry(arm11)); - - /* restore default state */ - arm11->dscr &= ~DSCR_INT_DIS; - - } - - target->debug_reason = DBG_REASON_SINGLESTEP; - - CHECK_RETVAL(target_call_event_callbacks(target, TARGET_EVENT_HALTED)); - - return ERROR_OK; -} - -static int arm11_assert_reset(struct target *target) -{ - struct arm11_common *arm11 = target_to_arm11(target); - - 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 { - - /* 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 */ - register_cache_invalidate(arm11->arm.core_cache); - - target->state = TARGET_RESET; - - return ERROR_OK; -} - -/* - * - There is another bug in the arm11 core. (iMX31 specific again?) - * When you generate an access to external logic (for example DDR - * controller via AHB bus) and that block is not configured (perhaps - * it is still held in reset), that transaction will never complete. - * This will hang arm11 core but it will also hang JTAG controller. - * Nothing short of srst assertion will bring it out of this. - */ - -static int arm11_deassert_reset(struct target *target) -{ - struct arm11_common *arm11 = target_to_arm11(target); - int retval; - - /* be certain SRST is off */ - jtag_add_reset(0, 0); - - /* WORKAROUND i.MX31 problems: SRST goofs the TAP, and resets - * at least DSCR. OMAP24xx doesn't show that problem, though - * SRST-only reset seems to be problematic for other reasons. - * (Secure boot sequences being one likelihood!) - */ - jtag_add_tlr(); - - CHECK_RETVAL(arm11_poll(target)); - - 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; - } - } - - /* maybe restore vector catch config */ - if (target->reset_halt && !(arm11->vcr & 1)) - CHECK_RETVAL(arm11_sc7_set_vcr(arm11, arm11->vcr)); - - return ERROR_OK; -} - -/* target memory access - * size: 1 = byte (8bit), 2 = half-word (16bit), 4 = word (32bit) - * count: number of items of - * - * arm11_config_memrw_no_increment - in the future we may want to be able - * to read/write a range of data to a "port". a "port" is an action on - * read memory address for some peripheral. - */ -static int arm11_read_memory_inner(struct target *target, - uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer, - bool arm11_config_memrw_no_increment) -{ - /** \todo TODO: check if buffer cast to uint32_t* and uint16_t* might cause alignment - *problems */ - int retval; - - if (target->state != TARGET_HALTED) { - LOG_WARNING("target was not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - LOG_DEBUG("ADDR %08" PRIx32 " SIZE %08" PRIx32 " COUNT %08" PRIx32 "", - address, - size, - count); - - struct arm11_common *arm11 = target_to_arm11(target); - - retval = arm11_run_instr_data_prepare(arm11); - if (retval != ERROR_OK) - return retval; - - /* MRC p14,0,r0,c0,c5,0 */ - retval = arm11_run_instr_data_to_core1(arm11, 0xee100e15, address); - if (retval != ERROR_OK) - return retval; - - switch (size) { - case 1: - arm11->arm.core_cache->reg_list[1].dirty = true; - - for (size_t i = 0; i < count; i++) { - /* ldrb r1, [r0], #1 */ - /* ldrb r1, [r0] */ - CHECK_RETVAL(arm11_run_instr_no_data1(arm11, - !arm11_config_memrw_no_increment ? 0xe4d01001 : 0xe5d01000)); - - uint32_t res; - /* MCR p14,0,R1,c0,c5,0 */ - CHECK_RETVAL(arm11_run_instr_data_from_core(arm11, 0xEE001E15, &res, 1)); - - *buffer++ = res; - } - - break; - - case 2: - { - arm11->arm.core_cache->reg_list[1].dirty = true; - - for (size_t i = 0; i < count; i++) { - /* ldrh r1, [r0], #2 */ - CHECK_RETVAL(arm11_run_instr_no_data1(arm11, - !arm11_config_memrw_no_increment ? 0xe0d010b2 : 0xe1d010b0)); - - uint32_t res; - - /* MCR p14,0,R1,c0,c5,0 */ - CHECK_RETVAL(arm11_run_instr_data_from_core(arm11, 0xEE001E15, &res, 1)); - - uint16_t svalue = res; - memcpy(buffer + i * sizeof(uint16_t), &svalue, sizeof(uint16_t)); - } - - break; - } - - case 4: - { - uint32_t instr = !arm11_config_memrw_no_increment ? 0xecb05e01 : 0xed905e00; - /** \todo TODO: buffer cast to uint32_t* causes alignment warnings */ - uint32_t *words = (uint32_t *)(void *)buffer; - - /* LDC p14,c5,[R0],#4 */ - /* LDC p14,c5,[R0] */ - CHECK_RETVAL(arm11_run_instr_data_from_core(arm11, instr, words, count)); - break; - } - } - - return arm11_run_instr_data_finish(arm11); -} - -static int arm11_read_memory(struct target *target, - uint32_t address, - uint32_t size, - uint32_t count, - uint8_t *buffer) -{ - return arm11_read_memory_inner(target, address, size, count, buffer, false); -} - -/* -* no_increment - in the future we may want to be able -* to read/write a range of data to a "port". a "port" is an action on -* read memory address for some peripheral. -*/ -static int arm11_write_memory_inner(struct target *target, - uint32_t address, uint32_t size, - uint32_t count, const uint8_t *buffer, - bool no_increment) -{ - int retval; - - if (target->state != TARGET_HALTED) { - LOG_WARNING("target was not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - LOG_DEBUG("ADDR %08" PRIx32 " SIZE %08" PRIx32 " COUNT %08" PRIx32 "", - address, - size, - count); - - struct arm11_common *arm11 = target_to_arm11(target); - - retval = arm11_run_instr_data_prepare(arm11); - if (retval != ERROR_OK) - return retval; - - /* load r0 with buffer address - * MRC p14,0,r0,c0,c5,0 */ - retval = arm11_run_instr_data_to_core1(arm11, 0xee100e15, address); - if (retval != ERROR_OK) - return retval; - - /* burst writes are not used for single words as those may well be - * reset init script writes. - * - * The other advantage is that as burst writes are default, we'll - * now exercise both burst and non-burst code paths with the - * default settings, increasing code coverage. - */ - bool burst = arm11->memwrite_burst && (count > 1); - - switch (size) { - case 1: - { - arm11->arm.core_cache->reg_list[1].dirty = true; - - for (size_t i = 0; i < count; i++) { - /* load r1 from DCC with byte data */ - /* MRC p14,0,r1,c0,c5,0 */ - retval = arm11_run_instr_data_to_core1(arm11, 0xee101e15, *buffer++); - if (retval != ERROR_OK) - return retval; - - /* write r1 to memory */ - /* strb r1, [r0], #1 */ - /* strb r1, [r0] */ - retval = arm11_run_instr_no_data1(arm11, - !no_increment ? 0xe4c01001 : 0xe5c01000); - if (retval != ERROR_OK) - return retval; - } - - break; - } - - case 2: - { - arm11->arm.core_cache->reg_list[1].dirty = true; - - for (size_t i = 0; i < count; i++) { - uint16_t value; - memcpy(&value, buffer + i * sizeof(uint16_t), sizeof(uint16_t)); - - /* load r1 from DCC with halfword data */ - /* MRC p14,0,r1,c0,c5,0 */ - retval = arm11_run_instr_data_to_core1(arm11, 0xee101e15, value); - if (retval != ERROR_OK) - return retval; - - /* write r1 to memory */ - /* strh r1, [r0], #2 */ - /* strh r1, [r0] */ - retval = arm11_run_instr_no_data1(arm11, - !no_increment ? 0xe0c010b2 : 0xe1c010b0); - if (retval != ERROR_OK) - return retval; - } - - break; - } - - case 4: { - /* stream word data through DCC directly to memory */ - /* increment: STC p14,c5,[R0],#4 */ - /* no increment: STC p14,c5,[R0]*/ - uint32_t instr = !no_increment ? 0xeca05e01 : 0xed805e00; - - /** \todo TODO: buffer cast to uint32_t* causes alignment warnings */ - uint32_t *words = (uint32_t *)(void *)buffer; - - /* "burst" here just means trusting each instruction executes - * fully before we run the next one: per-word roundtrips, to - * check the Ready flag, are not used. - */ - if (!burst) - retval = arm11_run_instr_data_to_core(arm11, - instr, words, count); - else - retval = arm11_run_instr_data_to_core_noack(arm11, - instr, words, count); - if (retval != ERROR_OK) - return retval; - - break; - } - } - - /* r0 verification */ - if (!no_increment) { - uint32_t r0; - - /* MCR p14,0,R0,c0,c5,0 */ - retval = arm11_run_instr_data_from_core(arm11, 0xEE000E15, &r0, 1); - if (retval != ERROR_OK) - return retval; - - if (address + size * count != r0) { - LOG_ERROR("Data transfer failed. Expected end " - "address 0x%08x, got 0x%08x", - (unsigned) (address + size * count), - (unsigned) r0); - - if (burst) - LOG_ERROR( - "use 'arm11 memwrite burst disable' to disable fast burst mode"); - - - if (arm11->memwrite_error_fatal) - return ERROR_FAIL; - } - } - - return arm11_run_instr_data_finish(arm11); -} - -static int arm11_write_memory(struct target *target, - uint32_t address, uint32_t size, - uint32_t count, const uint8_t *buffer) -{ - /* pointer increment matters only for multi-unit writes ... - * not e.g. to a "reset the chip" controller. - */ - return arm11_write_memory_inner(target, address, size, - count, buffer, count == 1); -} - -/* target break-/watchpoint control -* rw: 0 = write, 1 = read, 2 = access -*/ -static int arm11_add_breakpoint(struct target *target, - struct breakpoint *breakpoint) -{ - struct arm11_common *arm11 = target_to_arm11(target); - -#if 0 - if (breakpoint->type == BKPT_SOFT) { - LOG_INFO("sw breakpoint requested, but software breakpoints not enabled"); - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - } -#endif - - if (!arm11->free_brps) { - LOG_DEBUG("no breakpoint unit available for hardware breakpoint"); - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - } - - if (breakpoint->length != 4) { - LOG_DEBUG("only breakpoints of four bytes length supported"); - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - } - - arm11->free_brps--; - - return ERROR_OK; -} - -static int arm11_remove_breakpoint(struct target *target, - struct breakpoint *breakpoint) -{ - struct arm11_common *arm11 = target_to_arm11(target); - - arm11->free_brps++; - - return ERROR_OK; -} - -static int arm11_target_create(struct target *target, Jim_Interp *interp) -{ - struct arm11_common *arm11; - - if (target->tap == NULL) - return ERROR_FAIL; - - if (target->tap->ir_length != 5) { - LOG_ERROR("'target arm11' expects IR LENGTH = 5"); - return ERROR_COMMAND_SYNTAX_ERROR; - } - - arm11 = calloc(1, sizeof *arm11); - if (!arm11) - return ERROR_FAIL; - - arm11->arm.core_type = ARM_MODE_ANY; - arm_init_arch_info(target, &arm11->arm); - - arm11->jtag_info.tap = target->tap; - arm11->jtag_info.scann_size = 5; - arm11->jtag_info.scann_instr = ARM11_SCAN_N; - arm11->jtag_info.cur_scan_chain = ~0; /* invalid/unknown */ - arm11->jtag_info.intest_instr = ARM11_INTEST; - - arm11->memwrite_burst = true; - arm11->memwrite_error_fatal = true; - - return ERROR_OK; -} - -static int arm11_init_target(struct command_context *cmd_ctx, - struct target *target) -{ - /* Initialize anything we can set up without talking to the target */ - return ERROR_OK; -} - -/* talk to the target and set things up */ -static int arm11_examine(struct target *target) -{ - int retval; - char *type; - struct arm11_common *arm11 = target_to_arm11(target); - uint32_t didr, device_id; - uint8_t implementor; - - /* FIXME split into do-first-time and do-every-time logic ... */ - - /* check IDCODE */ - - arm11_add_IR(arm11, ARM11_IDCODE, ARM11_TAP_DEFAULT); - - struct scan_field idcode_field; - - arm11_setup_field(arm11, 32, NULL, &device_id, &idcode_field); - - arm11_add_dr_scan_vc(arm11->arm.target->tap, 1, &idcode_field, TAP_DRPAUSE); - - /* check DIDR */ - - arm11_add_debug_SCAN_N(arm11, 0x00, ARM11_TAP_DEFAULT); - - arm11_add_IR(arm11, ARM11_INTEST, ARM11_TAP_DEFAULT); - - struct scan_field chain0_fields[2]; - - arm11_setup_field(arm11, 32, NULL, &didr, chain0_fields + 0); - arm11_setup_field(arm11, 8, NULL, &implementor, chain0_fields + 1); - - arm11_add_dr_scan_vc(arm11->arm.target->tap, ARRAY_SIZE( - chain0_fields), chain0_fields, TAP_IDLE); - - CHECK_RETVAL(jtag_execute_queue()); - - /* assume the manufacturer id is ok; check the part # */ - switch ((device_id >> 12) & 0xFFFF) { - case 0x7B36: - type = "ARM1136"; - break; - case 0x7B37: - type = "ARM11 MPCore"; - break; - case 0x7B56: - type = "ARM1156"; - break; - case 0x7B76: - arm11->arm.core_type = ARM_MODE_MON; - /* NOTE: could default arm11->hardware_step to true */ - type = "ARM1176"; - break; - default: - LOG_ERROR("unexpected ARM11 ID code"); - return ERROR_FAIL; - } - LOG_INFO("found %s", type); - - /* unlikely this could ever fail, but ... */ - switch ((didr >> 16) & 0x0F) { - case ARM11_DEBUG_V6: - case ARM11_DEBUG_V61: /* supports security extensions */ - break; - default: - LOG_ERROR("Only ARM v6 and v6.1 debug supported."); - return ERROR_FAIL; - } - - arm11->brp = ((didr >> 24) & 0x0F) + 1; - - /** \todo TODO: reserve one brp slot if we allow breakpoints during step */ - arm11->free_brps = arm11->brp; - - LOG_DEBUG("IDCODE %08" PRIx32 " IMPLEMENTOR %02x DIDR %08" PRIx32, - device_id, implementor, didr); - - /* Build register cache "late", after target_init(), since we - * want to know if this core supports Secure Monitor mode. - */ - if (!target_was_examined(target)) - CHECK_RETVAL(arm11_dpm_init(arm11, didr)); - - /* as a side-effect this reads DSCR and thus - * clears the ARM11_DSCR_STICKY_PRECISE_DATA_ABORT / Sticky Precise Data Abort Flag - * as suggested by the spec. - */ - - retval = arm11_check_init(arm11); - if (retval != ERROR_OK) - return retval; - - /* ETM on ARM11 still uses original scanchain 6 access mode */ - if (arm11->arm.etm && !target_was_examined(target)) { - *register_get_last_cache_p(&target->reg_cache) = - etm_build_reg_cache(target, &arm11->jtag_info, - arm11->arm.etm); - CHECK_RETVAL(etm_setup(target)); - } - - target_set_examined(target); - - return ERROR_OK; -} - -#define ARM11_BOOL_WRAPPER(name, print_name) \ - COMMAND_HANDLER(arm11_handle_bool_ ## name) \ - { \ - struct target *target = get_current_target(CMD_CTX); \ - struct arm11_common *arm11 = target_to_arm11(target); \ - \ - return CALL_COMMAND_HANDLER(handle_command_parse_bool, \ - &arm11->name, print_name); \ - } - -ARM11_BOOL_WRAPPER(memwrite_burst, "memory write burst mode") -ARM11_BOOL_WRAPPER(memwrite_error_fatal, "fatal error mode for memory writes") -ARM11_BOOL_WRAPPER(step_irq_enable, "IRQs while stepping") -ARM11_BOOL_WRAPPER(hardware_step, "hardware single step") - -/* REVISIT handle the VCR bits like other ARMs: use symbols for - * input and output values. - */ - -COMMAND_HANDLER(arm11_handle_vcr) -{ - struct target *target = get_current_target(CMD_CTX); - struct arm11_common *arm11 = target_to_arm11(target); - - switch (CMD_ARGC) { - case 0: - break; - case 1: - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], arm11->vcr); - break; - default: - return ERROR_COMMAND_SYNTAX_ERROR; - } - - LOG_INFO("VCR 0x%08" PRIx32 "", arm11->vcr); - return ERROR_OK; -} - -static const struct command_registration arm11_mw_command_handlers[] = { - { - .name = "burst", - .handler = arm11_handle_bool_memwrite_burst, - .mode = COMMAND_ANY, - .help = "Display or modify flag controlling potentially " - "risky fast burst mode (default: enabled)", - .usage = "['enable'|'disable']", - }, - { - .name = "error_fatal", - .handler = arm11_handle_bool_memwrite_error_fatal, - .mode = COMMAND_ANY, - .help = "Display or modify flag controlling transfer " - "termination on transfer errors" - " (default: enabled)", - .usage = "['enable'|'disable']", - }, - COMMAND_REGISTRATION_DONE -}; -static const struct command_registration arm11_any_command_handlers[] = { - { - /* "hardware_step" is only here to check if the default - * simulate + breakpoint implementation is broken. - * TEMPORARY! NOT DOCUMENTED! */ - .name = "hardware_step", - .handler = arm11_handle_bool_hardware_step, - .mode = COMMAND_ANY, - .help = "DEBUG ONLY - Hardware single stepping" - " (default: disabled)", - .usage = "['enable'|'disable']", - }, - { - .name = "memwrite", - .mode = COMMAND_ANY, - .help = "memwrite command group", - .usage = "", - .chain = arm11_mw_command_handlers, - }, - { - .name = "step_irq_enable", - .handler = arm11_handle_bool_step_irq_enable, - .mode = COMMAND_ANY, - .help = "Display or modify flag controlling interrupt " - "enable while stepping (default: disabled)", - .usage = "['enable'|'disable']", - }, - { - .name = "vcr", - .handler = arm11_handle_vcr, - .mode = COMMAND_ANY, - .help = "Display or modify Vector Catch Register", - .usage = "[value]", - }, - COMMAND_REGISTRATION_DONE -}; - -static const struct command_registration arm11_command_handlers[] = { - { - .chain = arm_command_handlers, - }, - { - .chain = etm_command_handlers, - }, - { - .name = "arm11", - .mode = COMMAND_ANY, - .help = "ARM11 command group", - .usage = "", - .chain = arm11_any_command_handlers, - }, - COMMAND_REGISTRATION_DONE -}; - -/** Holds methods for ARM11xx targets. */ -struct target_type arm11_target = { - .name = "arm11", - - .poll = arm11_poll, - .arch_state = arm11_arch_state, - - .halt = arm11_halt, - .resume = arm11_resume, - .step = arm11_step, - - .assert_reset = arm11_assert_reset, - .deassert_reset = arm11_deassert_reset, - - .get_gdb_reg_list = arm_get_gdb_reg_list, - - .read_memory = arm11_read_memory, - .write_memory = arm11_write_memory, - - .checksum_memory = arm_checksum_memory, - .blank_check_memory = arm_blank_check_memory, - - .add_breakpoint = arm11_add_breakpoint, - .remove_breakpoint = arm11_remove_breakpoint, - - .run_algorithm = armv4_5_run_algorithm, - - .commands = arm11_command_handlers, - .target_create = arm11_target_create, - .init_target = arm11_init_target, - .examine = arm11_examine, -}; diff --git a/src/target/arm11.h b/src/target/arm11.h deleted file mode 100644 index 77cc2236d..000000000 --- a/src/target/arm11.h +++ /dev/null @@ -1,114 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2008 digenius technology GmbH. * - * Michael Bruck * - * * - * Copyright (C) 2008 Georg Acher * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 OPENOCD_TARGET_ARM11_H -#define OPENOCD_TARGET_ARM11_H - -#include "arm.h" -#include "arm_dpm.h" - -#define ARM11_TAP_DEFAULT TAP_INVALID - -#define CHECK_RETVAL(action) \ - do { \ - int __retval = (action); \ - if (__retval != ERROR_OK) { \ - LOG_DEBUG("error while calling \"%s\"", \ - # action); \ - return __retval; \ - } \ - } while (0) - -/* bits from ARMv7 DIDR */ -enum arm11_debug_version { - ARM11_DEBUG_V6 = 0x01, - ARM11_DEBUG_V61 = 0x02, - ARM11_DEBUG_V7 = 0x03, - ARM11_DEBUG_V7_CP14 = 0x04, -}; - -struct arm11_common { - struct arm arm; - - /** Debug module state. */ - struct arm_dpm dpm; - struct arm11_sc7_action *bpwp_actions; - unsigned bpwp_n; - - size_t brp; /**< Number of Breakpoint Register Pairs from DIDR */ - size_t free_brps; /**< Number of breakpoints allocated */ - - uint32_t dscr; /**< Last retrieved DSCR value. */ - - uint32_t saved_rdtr; - uint32_t saved_wdtr; - - bool is_rdtr_saved; - bool is_wdtr_saved; - - bool simulate_reset_on_next_halt; /**< Perform cleanups of the ARM state on next halt **/ - - /* Per-core configurable options. - * NOTE that several of these boolean options should not exist - * once the relevant code is known to work correctly. - */ - bool memwrite_burst; - bool memwrite_error_fatal; - bool step_irq_enable; - bool hardware_step; - - /** Configured Vector Catch Register settings. */ - uint32_t vcr; - - struct arm_jtag jtag_info; -}; - -static inline struct arm11_common *target_to_arm11(struct target *target) -{ - return container_of(target->arch_info, struct arm11_common, arm); -} - -/** - * ARM11 DBGTAP instructions - * - * http://infocenter.arm.com/help/topic/com.arm.doc.ddi0301f/I1006229.html - */ -enum arm11_instructions { - ARM11_EXTEST = 0x00, - ARM11_SCAN_N = 0x02, - ARM11_RESTART = 0x04, - ARM11_HALT = 0x08, - ARM11_INTEST = 0x0C, - ARM11_ITRSEL = 0x1D, - ARM11_IDCODE = 0x1E, - ARM11_BYPASS = 0x1F, -}; - -enum arm11_sc7 { - ARM11_SC7_NULL = 0, - ARM11_SC7_VCR = 7, - ARM11_SC7_PC = 8, - ARM11_SC7_BVR0 = 64, - ARM11_SC7_BCR0 = 80, - ARM11_SC7_WVR0 = 96, - ARM11_SC7_WCR0 = 112, -}; - -#endif /* OPENOCD_TARGET_ARM11_H */ diff --git a/src/target/arm11_dbgtap.c b/src/target/arm11_dbgtap.c deleted file mode 100644 index 2232b3ef6..000000000 --- a/src/target/arm11_dbgtap.c +++ /dev/null @@ -1,1195 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2008 digenius technology GmbH. * - * Michael Bruck * - * * - * Copyright (C) 2008,2009 Oyvind Harboe oyvind.harboe@zylin.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "arm_jtag.h" -#include "arm11_dbgtap.h" - -#include - -#if 0 -#define JTAG_DEBUG(expr ...) do { if (1) \ - LOG_DEBUG(expr); } while (0) -#else -#define JTAG_DEBUG(expr ...) do { if (0) \ - LOG_DEBUG(expr); } while (0) -#endif - -/* -This pathmove goes from Pause-IR to Shift-IR while avoiding RTI. The -behavior of the FTDI driver IIRC was to go via RTI. - -Conversely there may be other places in this code where the ARM11 code relies -on the driver to hit through RTI when coming from Update-?R. -*/ -static const tap_state_t arm11_move_pi_to_si_via_ci[] = { - TAP_IREXIT2, TAP_IRUPDATE, TAP_DRSELECT, TAP_IRSELECT, TAP_IRCAPTURE, TAP_IRSHIFT -}; - -/* REVISIT no error handling here! */ -static void arm11_add_ir_scan_vc(struct jtag_tap *tap, struct scan_field *fields, - tap_state_t state) -{ - if (cmd_queue_cur_state == TAP_IRPAUSE) - jtag_add_pathmove(ARRAY_SIZE(arm11_move_pi_to_si_via_ci), - arm11_move_pi_to_si_via_ci); - - jtag_add_ir_scan(tap, fields, state); -} - -static const tap_state_t arm11_move_pd_to_sd_via_cd[] = { - TAP_DREXIT2, TAP_DRUPDATE, TAP_DRSELECT, TAP_DRCAPTURE, TAP_DRSHIFT -}; - -/* REVISIT no error handling here! */ -void arm11_add_dr_scan_vc(struct jtag_tap *tap, int num_fields, struct scan_field *fields, - tap_state_t state) -{ - if (cmd_queue_cur_state == TAP_DRPAUSE) - jtag_add_pathmove(ARRAY_SIZE(arm11_move_pd_to_sd_via_cd), - arm11_move_pd_to_sd_via_cd); - - jtag_add_dr_scan(tap, num_fields, fields, state); -} - - -/** Code de-clutter: Construct struct scan_field to write out a value - * - * \param arm11 Target state variable. - * \param num_bits Length of the data field - * \param out_data pointer to the data that will be sent out - * (data is read when it is added to the JTAG queue) - * \param in_data pointer to the memory that will receive data that was clocked in - * (data is written when the JTAG queue is executed) - * \param field target data structure that will be initialized - */ -void arm11_setup_field(struct arm11_common *arm11, int num_bits, - void *out_data, void *in_data, struct scan_field *field) -{ - field->num_bits = num_bits; - field->out_value = out_data; - field->in_value = in_data; -} - -static const char *arm11_ir_to_string(uint8_t ir) -{ - const char *s = "unknown"; - - switch (ir) { - case ARM11_EXTEST: - s = "EXTEST"; - break; - case ARM11_SCAN_N: - s = "SCAN_N"; - break; - case ARM11_RESTART: - s = "RESTART"; - break; - case ARM11_HALT: - s = "HALT"; - break; - case ARM11_INTEST: - s = "INTEST"; - break; - case ARM11_ITRSEL: - s = "ITRSEL"; - break; - case ARM11_IDCODE: - s = "IDCODE"; - break; - case ARM11_BYPASS: - s = "BYPASS"; - break; - } - return s; -} - -/** Write JTAG instruction register - * - * \param arm11 Target state variable. - * \param instr An ARM11 DBGTAP instruction. Use enum #arm11_instructions. - * \param state Pass the final TAP state or ARM11_TAP_DEFAULT for the default value (Pause-IR). - * - * \remarks This adds to the JTAG command queue but does \em not execute it. - */ -void arm11_add_IR(struct arm11_common *arm11, uint8_t instr, tap_state_t state) -{ - struct jtag_tap *tap = arm11->arm.target->tap; - - if (buf_get_u32(tap->cur_instr, 0, 5) == instr) { - JTAG_DEBUG("IR <= 0x%02x SKIPPED", instr); - return; - } - - JTAG_DEBUG("IR <= %s (0x%02x)", arm11_ir_to_string(instr), instr); - - struct scan_field field; - - arm11_setup_field(arm11, 5, &instr, NULL, &field); - - arm11_add_ir_scan_vc(arm11->arm.target->tap, - &field, - state == ARM11_TAP_DEFAULT ? TAP_IRPAUSE : state); -} - -/** Verify data shifted out from Scan Chain Register (SCREG). */ -static void arm11_in_handler_SCAN_N(uint8_t *in_value) -{ - /* Don't expect JTAG layer to modify bits we didn't ask it to read */ - uint8_t v = *in_value & 0x1F; - - if (v != 0x10) { - LOG_ERROR("'arm11 target' JTAG error SCREG OUT 0x%02x", v); - jtag_set_error(ERROR_FAIL); - } -} - -/** Select and write to Scan Chain Register (SCREG) - * - * This function sets the instruction register to SCAN_N and writes - * the data register with the selected chain number. - * - * http://infocenter.arm.com/help/topic/com.arm.doc.ddi0301f/Cacbjhfg.html - * - * \param arm11 Target state variable. - * \param chain Scan chain that will be selected. - * \param state Pass the final TAP state or ARM11_TAP_DEFAULT for the default - * value (Pause-DR). - * - * Changes the current scan chain if needed, transitions to the specified - * TAP state, and leaves the IR undefined. - * - * The chain takes effect when Update-DR is passed (usually when subsequently - * the INTEXT/EXTEST instructions are written). - * - * \warning (Obsolete) Using this twice in a row will \em fail. The first - * call will end in Pause-DR. The second call, due to the IR - * caching, will not go through Capture-DR when shifting in the - * new scan chain number. As a result the verification in - * arm11_in_handler_SCAN_N() must fail. - * - * \remarks This adds to the JTAG command queue but does \em not execute it. - */ - -int arm11_add_debug_SCAN_N(struct arm11_common *arm11, - uint8_t chain, tap_state_t state) -{ - /* Don't needlessly switch the scan chain. - * NOTE: the ITRSEL instruction fakes SCREG changing; - * but leaves its actual value unchanged. - */ -#if 0 - /* FIX!!! the optimization below is broken because we do not */ - /* invalidate the cur_scan_chain upon a TRST/TMS. See arm_jtag.c */ - /* for example on how to invalidate cur_scan_chain. Tested patches gladly */ - /* accepted! */ - if (arm11->jtag_info.cur_scan_chain == chain) { - JTAG_DEBUG("SCREG <= %d SKIPPED", chain); - return jtag_add_statemove((state == ARM11_TAP_DEFAULT) - ? TAP_DRPAUSE : state); - } -#endif - JTAG_DEBUG("SCREG <= %d", chain); - - arm11_add_IR(arm11, ARM11_SCAN_N, ARM11_TAP_DEFAULT); - - struct scan_field field; - - uint8_t tmp[1]; - arm11_setup_field(arm11, 5, &chain, &tmp, &field); - - arm11_add_dr_scan_vc(arm11->arm.target->tap, - 1, - &field, - state == ARM11_TAP_DEFAULT ? TAP_DRPAUSE : state); - - jtag_execute_queue_noclear(); - - arm11_in_handler_SCAN_N(tmp); - - arm11->jtag_info.cur_scan_chain = chain; - - return jtag_execute_queue(); -} - -/** - * Queue a DR scan of the ITR register. Caller must have selected - * scan chain 4 (ITR), possibly using ITRSEL. - * - * \param arm11 Target state variable. - * \param inst An ARM11 processor instruction/opcode. - * \param flag Optional parameter to retrieve the Ready flag; - * this address will be written when the JTAG chain is scanned. - * \param state The TAP state to enter after the DR scan. - * - * Going through the TAP_DRUPDATE state writes ITR only if Ready was - * previously set. Only the Ready flag is readable by the scan. - * - * An instruction loaded into ITR is executed when going through the - * TAP_IDLE state only if Ready was previously set and the debug state - * is properly set up. Depending on the instruction, you may also need - * to ensure that the rDTR is ready before that Run-Test/Idle state. - */ -static void arm11_add_debug_INST(struct arm11_common *arm11, - uint32_t inst, uint8_t *flag, tap_state_t state) -{ - JTAG_DEBUG("INST <= 0x%08x", (unsigned) inst); - - struct scan_field itr[2]; - - arm11_setup_field(arm11, 32, &inst, NULL, itr + 0); - arm11_setup_field(arm11, 1, NULL, flag, itr + 1); - - arm11_add_dr_scan_vc(arm11->arm.target->tap, ARRAY_SIZE(itr), itr, state); -} - -/** - * Read and save the Debug Status and Control Register (DSCR). - * - * \param arm11 Target state variable. - * \return Error status; arm11->dscr is updated on success. - * - * \remarks This is a stand-alone function that executes the JTAG - * command queue. It does not require the ARM11 debug TAP to be - * in any particular state. - */ -int arm11_read_DSCR(struct arm11_common *arm11) -{ - int retval; - - retval = arm11_add_debug_SCAN_N(arm11, 0x01, ARM11_TAP_DEFAULT); - if (retval != ERROR_OK) - return retval; - - arm11_add_IR(arm11, ARM11_INTEST, ARM11_TAP_DEFAULT); - - uint32_t dscr; - struct scan_field chain1_field; - - arm11_setup_field(arm11, 32, NULL, &dscr, &chain1_field); - - arm11_add_dr_scan_vc(arm11->arm.target->tap, 1, &chain1_field, TAP_DRPAUSE); - - CHECK_RETVAL(jtag_execute_queue()); - - if (arm11->dscr != dscr) - JTAG_DEBUG("DSCR = %08x (OLD %08x)", - (unsigned) dscr, - (unsigned) arm11->dscr); - - arm11->dscr = dscr; - - return ERROR_OK; -} - -/** Write the Debug Status and Control Register (DSCR) - * - * same as CP14 c1 - * - * \param arm11 Target state variable. - * \param dscr DSCR content - * - * \remarks This is a stand-alone function that executes the JTAG command queue. - */ -int arm11_write_DSCR(struct arm11_common *arm11, uint32_t dscr) -{ - int retval; - retval = arm11_add_debug_SCAN_N(arm11, 0x01, ARM11_TAP_DEFAULT); - if (retval != ERROR_OK) - return retval; - - arm11_add_IR(arm11, ARM11_EXTEST, ARM11_TAP_DEFAULT); - - struct scan_field chain1_field; - - arm11_setup_field(arm11, 32, &dscr, NULL, &chain1_field); - - arm11_add_dr_scan_vc(arm11->arm.target->tap, 1, &chain1_field, TAP_DRPAUSE); - - CHECK_RETVAL(jtag_execute_queue()); - - JTAG_DEBUG("DSCR <= %08x (OLD %08x)", - (unsigned) dscr, - (unsigned) arm11->dscr); - - arm11->dscr = dscr; - - return ERROR_OK; -} - -/** Prepare the stage for ITR/DTR operations - * from the arm11_run_instr... group of functions. - * - * Put arm11_run_instr_data_prepare() and arm11_run_instr_data_finish() - * around a block of arm11_run_instr_... calls. - * - * Select scan chain 5 to allow quick access to DTR. When scan - * chain 4 is needed to put in a register the ITRSel instruction - * shortcut is used instead of actually changing the Scan_N - * register. - * - * \param arm11 Target state variable. - * - */ -int arm11_run_instr_data_prepare(struct arm11_common *arm11) -{ - return arm11_add_debug_SCAN_N(arm11, 0x05, ARM11_TAP_DEFAULT); -} - -/** Cleanup after ITR/DTR operations - * from the arm11_run_instr... group of functions - * - * Put arm11_run_instr_data_prepare() and arm11_run_instr_data_finish() - * around a block of arm11_run_instr_... calls. - * - * Any IDLE can lead to an instruction execution when - * scan chains 4 or 5 are selected and the IR holds - * INTEST or EXTEST. So we must disable that before - * any following activities lead to an IDLE. - * - * \param arm11 Target state variable. - * - */ -int arm11_run_instr_data_finish(struct arm11_common *arm11) -{ - return arm11_add_debug_SCAN_N(arm11, 0x00, ARM11_TAP_DEFAULT); -} - -/** - * Execute one or more instructions via ITR. - * Caller guarantees that processor is in debug state, that DSCR_ITR_EN - * is set, the ITR Ready flag is set (as seen on the previous entry to - * TAP_DRCAPTURE), and the DSCR sticky abort flag is clear. - * - * \pre arm11_run_instr_data_prepare() / arm11_run_instr_data_finish() block - * - * \param arm11 Target state variable. - * \param opcode Pointer to sequence of ARM opcodes - * \param count Number of opcodes to execute - * - */ -static -int arm11_run_instr_no_data(struct arm11_common *arm11, - uint32_t *opcode, size_t count) -{ - arm11_add_IR(arm11, ARM11_ITRSEL, ARM11_TAP_DEFAULT); - - while (count--) { - arm11_add_debug_INST(arm11, *opcode++, NULL, TAP_IDLE); - - int i = 0; - while (1) { - uint8_t flag; - - arm11_add_debug_INST(arm11, 0, &flag, count ? TAP_IDLE : TAP_DRPAUSE); - - CHECK_RETVAL(jtag_execute_queue()); - - if (flag) - break; - - int64_t then = 0; - - if (i == 1000) - then = timeval_ms(); - if (i >= 1000) { - if ((timeval_ms()-then) > 1000) { - LOG_WARNING( - "Timeout (1000ms) waiting for instructions to complete"); - return ERROR_FAIL; - } - } - - i++; - } - } - - return ERROR_OK; -} - -/** Execute one instruction via ITR - * - * \pre arm11_run_instr_data_prepare() / arm11_run_instr_data_finish() block - * - * \param arm11 Target state variable. - * \param opcode ARM opcode - * - */ -int arm11_run_instr_no_data1(struct arm11_common *arm11, uint32_t opcode) -{ - return arm11_run_instr_no_data(arm11, &opcode, 1); -} - - -/** Execute one instruction via ITR repeatedly while - * passing data to the core via DTR on each execution. - * - * Caller guarantees that processor is in debug state, that DSCR_ITR_EN - * is set, the ITR Ready flag is set (as seen on the previous entry to - * TAP_DRCAPTURE), and the DSCR sticky abort flag is clear. - * - * The executed instruction \em must read data from DTR. - * - * \pre arm11_run_instr_data_prepare() / arm11_run_instr_data_finish() block - * - * \param arm11 Target state variable. - * \param opcode ARM opcode - * \param data Pointer to the data words to be passed to the core - * \param count Number of data words and instruction repetitions - * - */ -int arm11_run_instr_data_to_core(struct arm11_common *arm11, - uint32_t opcode, - uint32_t *data, - size_t count) -{ - arm11_add_IR(arm11, ARM11_ITRSEL, ARM11_TAP_DEFAULT); - - arm11_add_debug_INST(arm11, opcode, NULL, TAP_DRPAUSE); - - arm11_add_IR(arm11, ARM11_EXTEST, ARM11_TAP_DEFAULT); - - struct scan_field chain5_fields[3]; - - uint32_t Data; - uint8_t Ready; - uint8_t nRetry; - - arm11_setup_field(arm11, 32, &Data, NULL, chain5_fields + 0); - arm11_setup_field(arm11, 1, NULL, &Ready, chain5_fields + 1); - arm11_setup_field(arm11, 1, NULL, &nRetry, chain5_fields + 2); - - while (count--) { - int i = 0; - do { - Data = *data; - - arm11_add_dr_scan_vc(arm11->arm.target->tap, ARRAY_SIZE( - chain5_fields), chain5_fields, TAP_IDLE); - - CHECK_RETVAL(jtag_execute_queue()); - - JTAG_DEBUG("DTR Ready %d nRetry %d", Ready, nRetry); - - int64_t then = 0; - - if (i == 1000) - then = timeval_ms(); - if (i >= 1000) { - if ((timeval_ms()-then) > 1000) { - LOG_WARNING( - "Timeout (1000ms) waiting for instructions to complete"); - return ERROR_FAIL; - } - } - - i++; - } while (!Ready); - - data++; - } - - arm11_add_IR(arm11, ARM11_INTEST, ARM11_TAP_DEFAULT); - - int i = 0; - do { - Data = 0; - - arm11_add_dr_scan_vc(arm11->arm.target->tap, ARRAY_SIZE( - chain5_fields), chain5_fields, TAP_DRPAUSE); - - CHECK_RETVAL(jtag_execute_queue()); - - JTAG_DEBUG("DTR Data %08x Ready %d nRetry %d", - (unsigned) Data, Ready, nRetry); - - int64_t then = 0; - - if (i == 1000) - then = timeval_ms(); - if (i >= 1000) { - if ((timeval_ms()-then) > 1000) { - LOG_WARNING("Timeout (1000ms) waiting for instructions to complete"); - return ERROR_FAIL; - } - } - - i++; - } while (!Ready); - - return ERROR_OK; -} - -/** JTAG path for arm11_run_instr_data_to_core_noack - * - * The repeated TAP_IDLE's do not cause a repeated execution - * if passed without leaving the state. - * - * Since this is more than 7 bits (adjustable via adding more - * TAP_IDLE's) it produces an artificial delay in the lower - * layer (FT2232) that is long enough to finish execution on - * the core but still shorter than any manually inducible delays. - * - * To disable this code, try "memwrite burst false" - * - * FIX!!! should we use multiple TAP_IDLE here or not??? - * - * https://lists.berlios.de/pipermail/openocd-development/2009-July/009698.html - * https://lists.berlios.de/pipermail/openocd-development/2009-August/009865.html - */ -static const tap_state_t arm11_MOVE_DRPAUSE_IDLE_DRPAUSE_with_delay[] = { - TAP_DREXIT2, TAP_DRUPDATE, TAP_IDLE, TAP_IDLE, TAP_IDLE, TAP_DRSELECT, TAP_DRCAPTURE, - TAP_DRSHIFT -}; - -/* This inner loop can be implemented by the minidriver, oftentimes in hardware... The - * minidriver can call the default implementation as a fallback or implement it - * from scratch. - */ -int arm11_run_instr_data_to_core_noack_inner_default(struct jtag_tap *tap, - uint32_t opcode, - uint32_t *data, - size_t count) -{ - struct scan_field chain5_fields[3]; - - chain5_fields[0].num_bits = 32; - chain5_fields[0].out_value = NULL; /*&Data*/ - chain5_fields[0].in_value = NULL; - - chain5_fields[1].num_bits = 1; - chain5_fields[1].out_value = NULL; - chain5_fields[1].in_value = NULL; /*&Ready*/ - - chain5_fields[2].num_bits = 1; - chain5_fields[2].out_value = NULL; - chain5_fields[2].in_value = NULL; - - uint8_t *Readies; - unsigned readiesNum = count; - unsigned bytes = sizeof(*Readies)*readiesNum; - - Readies = malloc(bytes); - if (Readies == NULL) { - LOG_ERROR("Out of memory allocating %u bytes", bytes); - return ERROR_FAIL; - } - - uint8_t *ReadyPos = Readies; - while (count--) { - chain5_fields[0].out_value = (uint8_t *)(data++); - chain5_fields[1].in_value = ReadyPos++; - - if (count > 0) { - jtag_add_dr_scan(tap, ARRAY_SIZE(chain5_fields), chain5_fields, - TAP_DRPAUSE); - jtag_add_pathmove(ARRAY_SIZE(arm11_MOVE_DRPAUSE_IDLE_DRPAUSE_with_delay), - arm11_MOVE_DRPAUSE_IDLE_DRPAUSE_with_delay); - } else - jtag_add_dr_scan(tap, ARRAY_SIZE(chain5_fields), chain5_fields, TAP_IDLE); - } - - int retval = jtag_execute_queue(); - if (retval == ERROR_OK) { - unsigned error_count = 0; - - for (size_t i = 0; i < readiesNum; i++) { - if (Readies[i] != 1) - error_count++; - } - - if (error_count > 0) { - LOG_ERROR("%u words out of %u not transferred", - error_count, readiesNum); - retval = ERROR_FAIL; - } - } - free(Readies); - - return retval; -} - -int arm11_run_instr_data_to_core_noack_inner(struct jtag_tap *tap, - uint32_t opcode, - uint32_t *data, - size_t count); - -#ifndef HAVE_JTAG_MINIDRIVER_H -int arm11_run_instr_data_to_core_noack_inner(struct jtag_tap *tap, - uint32_t opcode, - uint32_t *data, - size_t count) -{ - return arm11_run_instr_data_to_core_noack_inner_default(tap, opcode, data, count); -} -#endif - -/** Execute one instruction via ITR repeatedly while - * passing data to the core via DTR on each execution. - * - * Caller guarantees that processor is in debug state, that DSCR_ITR_EN - * is set, the ITR Ready flag is set (as seen on the previous entry to - * TAP_DRCAPTURE), and the DSCR sticky abort flag is clear. - * - * No Ready check during transmission. - * - * The executed instruction \em must read data from DTR. - * - * \pre arm11_run_instr_data_prepare() / arm11_run_instr_data_finish() block - * - * \param arm11 Target state variable. - * \param opcode ARM opcode - * \param data Pointer to the data words to be passed to the core - * \param count Number of data words and instruction repetitions - * - */ -int arm11_run_instr_data_to_core_noack(struct arm11_common *arm11, - uint32_t opcode, - uint32_t *data, - size_t count) -{ - arm11_add_IR(arm11, ARM11_ITRSEL, ARM11_TAP_DEFAULT); - - arm11_add_debug_INST(arm11, opcode, NULL, TAP_DRPAUSE); - - arm11_add_IR(arm11, ARM11_EXTEST, ARM11_TAP_DEFAULT); - - int retval = arm11_run_instr_data_to_core_noack_inner(arm11->arm.target->tap, - opcode, - data, - count); - - if (retval != ERROR_OK) - return retval; - - arm11_add_IR(arm11, ARM11_INTEST, ARM11_TAP_DEFAULT); - - struct scan_field chain5_fields[3]; - - arm11_setup_field(arm11, - 32, - NULL /*&Data*/, - NULL, - chain5_fields + 0); - arm11_setup_field(arm11, - 1, - NULL, - NULL /*&Ready*/, - chain5_fields + 1); - arm11_setup_field(arm11, - 1, - NULL, - NULL, - chain5_fields + 2); - - uint8_t ready_flag; - chain5_fields[1].in_value = &ready_flag; - - arm11_add_dr_scan_vc(arm11->arm.target->tap, ARRAY_SIZE( - chain5_fields), chain5_fields, TAP_DRPAUSE); - - retval = jtag_execute_queue(); - if (retval == ERROR_OK) { - if (ready_flag != 1) { - LOG_ERROR("last word not transferred"); - retval = ERROR_FAIL; - } - } - - return retval; -} - - -/** Execute an instruction via ITR while handing data into the core via DTR. - * - * The executed instruction \em must read data from DTR. - * - * \pre arm11_run_instr_data_prepare() / arm11_run_instr_data_finish() block - * - * \param arm11 Target state variable. - * \param opcode ARM opcode - * \param data Data word to be passed to the core via DTR - * - */ -int arm11_run_instr_data_to_core1(struct arm11_common *arm11, uint32_t opcode, uint32_t data) -{ - return arm11_run_instr_data_to_core(arm11, opcode, &data, 1); -} - - -/** Execute one instruction via ITR repeatedly while - * reading data from the core via DTR on each execution. - * - * Caller guarantees that processor is in debug state, that DSCR_ITR_EN - * is set, the ITR Ready flag is set (as seen on the previous entry to - * TAP_DRCAPTURE), and the DSCR sticky abort flag is clear. - * - * The executed instruction \em must write data to DTR. - * - * \pre arm11_run_instr_data_prepare() / arm11_run_instr_data_finish() block - * - * \param arm11 Target state variable. - * \param opcode ARM opcode - * \param data Pointer to an array that receives the data words from the core - * \param count Number of data words and instruction repetitions - * - */ -int arm11_run_instr_data_from_core(struct arm11_common *arm11, - uint32_t opcode, - uint32_t *data, - size_t count) -{ - arm11_add_IR(arm11, ARM11_ITRSEL, ARM11_TAP_DEFAULT); - - arm11_add_debug_INST(arm11, opcode, NULL, TAP_IDLE); - - arm11_add_IR(arm11, ARM11_INTEST, ARM11_TAP_DEFAULT); - - struct scan_field chain5_fields[3]; - - uint32_t Data; - uint8_t Ready; - uint8_t nRetry; - - arm11_setup_field(arm11, 32, NULL, &Data, chain5_fields + 0); - arm11_setup_field(arm11, 1, NULL, &Ready, chain5_fields + 1); - arm11_setup_field(arm11, 1, NULL, &nRetry, chain5_fields + 2); - - while (count--) { - int i = 0; - do { - arm11_add_dr_scan_vc(arm11->arm.target->tap, ARRAY_SIZE( - chain5_fields), chain5_fields, - count ? TAP_IDLE : TAP_DRPAUSE); - - CHECK_RETVAL(jtag_execute_queue()); - - JTAG_DEBUG("DTR Data %08x Ready %d nRetry %d", - (unsigned) Data, Ready, nRetry); - - int64_t then = 0; - - if (i == 1000) - then = timeval_ms(); - if (i >= 1000) { - if ((timeval_ms()-then) > 1000) { - LOG_WARNING( - "Timeout (1000ms) waiting for instructions to complete"); - return ERROR_FAIL; - } - } - - i++; - } while (!Ready); - - *data++ = Data; - } - - return ERROR_OK; -} - -/** Execute one instruction via ITR - * then load r0 into DTR and read DTR from core. - * - * The first executed instruction (\p opcode) should write data to r0. - * - * \pre arm11_run_instr_data_prepare() / arm11_run_instr_data_finish() block - * - * \param arm11 Target state variable. - * \param opcode ARM opcode to write r0 with the value of interest - * \param data Pointer to a data word that receives the value from r0 after \p opcode was executed. - * - */ -int arm11_run_instr_data_from_core_via_r0(struct arm11_common *arm11, - uint32_t opcode, - uint32_t *data) -{ - int retval; - retval = arm11_run_instr_no_data1(arm11, opcode); - if (retval != ERROR_OK) - return retval; - - /* MCR p14,0,R0,c0,c5,0 (move r0 -> wDTR -> local var) */ - arm11_run_instr_data_from_core(arm11, 0xEE000E15, data, 1); - - return ERROR_OK; -} - -/** Load data into core via DTR then move it to r0 then - * execute one instruction via ITR - * - * The final executed instruction (\p opcode) should read data from r0. - * - * \pre arm11_run_instr_data_prepare() / arm11_run_instr_data_finish() block - * - * \param arm11 Target state variable. - * \param opcode ARM opcode to read r0 act upon it - * \param data Data word that will be written to r0 before \p opcode is executed - * - */ -int arm11_run_instr_data_to_core_via_r0(struct arm11_common *arm11, uint32_t opcode, uint32_t data) -{ - int retval; - /* MRC p14,0,r0,c0,c5,0 */ - retval = arm11_run_instr_data_to_core1(arm11, 0xEE100E15, data); - if (retval != ERROR_OK) - return retval; - - retval = arm11_run_instr_no_data1(arm11, opcode); - if (retval != ERROR_OK) - return retval; - - return ERROR_OK; -} - -/** Apply reads and writes to scan chain 7 - * - * \see struct arm11_sc7_action - * - * \param arm11 Target state variable. - * \param actions A list of read and/or write instructions - * \param count Number of instructions in the list. - * - */ -int arm11_sc7_run(struct arm11_common *arm11, struct arm11_sc7_action *actions, size_t count) -{ - int retval; - - retval = arm11_add_debug_SCAN_N(arm11, 0x07, ARM11_TAP_DEFAULT); - if (retval != ERROR_OK) - return retval; - - arm11_add_IR(arm11, ARM11_EXTEST, ARM11_TAP_DEFAULT); - - struct scan_field chain7_fields[3]; - - uint8_t nRW; - uint32_t DataOut; - uint8_t AddressOut; - uint8_t Ready; - uint32_t DataIn; - uint8_t AddressIn; - - arm11_setup_field(arm11, 1, &nRW, &Ready, chain7_fields + 0); - arm11_setup_field(arm11, 32, &DataOut, &DataIn, chain7_fields + 1); - arm11_setup_field(arm11, 7, &AddressOut, &AddressIn, chain7_fields + 2); - - for (size_t i = 0; i < count + 1; i++) { - if (i < count) { - nRW = actions[i].write ? 1 : 0; - DataOut = actions[i].value; - AddressOut = actions[i].address; - } else { - nRW = 1; - DataOut = 0; - AddressOut = 0; - } - - /* Timeout here so we don't get stuck. */ - int i_n = 0; - while (1) { - JTAG_DEBUG("SC7 <= c%-3d Data %08x %s", - (unsigned) AddressOut, - (unsigned) DataOut, - nRW ? "write" : "read"); - - arm11_add_dr_scan_vc(arm11->arm.target->tap, ARRAY_SIZE(chain7_fields), - chain7_fields, TAP_DRPAUSE); - - CHECK_RETVAL(jtag_execute_queue()); - - /* 'nRW' is 'Ready' on read out */ - if (Ready) - break; - - int64_t then = 0; - - if (i_n == 1000) - then = timeval_ms(); - if (i_n >= 1000) { - if ((timeval_ms()-then) > 1000) { - LOG_WARNING( - "Timeout (1000ms) waiting for instructions to complete"); - return ERROR_FAIL; - } - } - - i_n++; - } - - if (!nRW) - JTAG_DEBUG("SC7 => Data %08x", (unsigned) DataIn); - - if (i > 0) { - if (actions[i - 1].address != AddressIn) - LOG_WARNING("Scan chain 7 shifted out unexpected address"); - - if (!actions[i - 1].write) - actions[i - 1].value = DataIn; - else { - if (actions[i - 1].value != DataIn) - LOG_WARNING("Scan chain 7 shifted out unexpected data"); - } - } - } - return ERROR_OK; -} - -/** Clear VCR and all breakpoints and watchpoints via scan chain 7 - * - * \param arm11 Target state variable. - * - */ -int arm11_sc7_clear_vbw(struct arm11_common *arm11) -{ - size_t clear_bw_size = arm11->brp + 1; - struct arm11_sc7_action *clear_bw = malloc(sizeof(struct arm11_sc7_action) * clear_bw_size); - struct arm11_sc7_action *pos = clear_bw; - - for (size_t i = 0; i < clear_bw_size; i++) { - clear_bw[i].write = true; - clear_bw[i].value = 0; - } - - for (size_t i = 0; i < arm11->brp; i++) - (pos++)->address = ARM11_SC7_BCR0 + i; - - (pos++)->address = ARM11_SC7_VCR; - - int retval; - retval = arm11_sc7_run(arm11, clear_bw, clear_bw_size); - - free(clear_bw); - - return retval; -} - -/** Write VCR register - * - * \param arm11 Target state variable. - * \param value Value to be written - */ -int arm11_sc7_set_vcr(struct arm11_common *arm11, uint32_t value) -{ - struct arm11_sc7_action set_vcr; - - set_vcr.write = true; - set_vcr.address = ARM11_SC7_VCR; - set_vcr.value = value; - - return arm11_sc7_run(arm11, &set_vcr, 1); -} - -/** Read word from address - * - * \param arm11 Target state variable. - * \param address Memory address to be read - * \param result Pointer where to store result - * - */ -int arm11_read_memory_word(struct arm11_common *arm11, uint32_t address, uint32_t *result) -{ - int retval; - retval = arm11_run_instr_data_prepare(arm11); - if (retval != ERROR_OK) - return retval; - - /* MRC p14,0,r0,c0,c5,0 (r0 = address) */ - CHECK_RETVAL(arm11_run_instr_data_to_core1(arm11, 0xee100e15, address)); - - /* LDC p14,c5,[R0],#4 (DTR = [r0]) */ - CHECK_RETVAL(arm11_run_instr_data_from_core(arm11, 0xecb05e01, result, 1)); - - return arm11_run_instr_data_finish(arm11); -} - -/************************************************************************/ - -/* - * ARM11 provider for the OpenOCD implementation of the standard - * architectural ARM v6/v7 "Debug Programmer's Model" (DPM). - */ - -static inline struct arm11_common *dpm_to_arm11(struct arm_dpm *dpm) -{ - return container_of(dpm, struct arm11_common, dpm); -} - -static int arm11_dpm_prepare(struct arm_dpm *dpm) -{ - return arm11_run_instr_data_prepare(dpm_to_arm11(dpm)); -} - -static int arm11_dpm_finish(struct arm_dpm *dpm) -{ - return arm11_run_instr_data_finish(dpm_to_arm11(dpm)); -} - -static int arm11_dpm_instr_write_data_dcc(struct arm_dpm *dpm, - uint32_t opcode, uint32_t data) -{ - return arm11_run_instr_data_to_core(dpm_to_arm11(dpm), - opcode, &data, 1); -} - -static int arm11_dpm_instr_write_data_r0(struct arm_dpm *dpm, - uint32_t opcode, uint32_t data) -{ - return arm11_run_instr_data_to_core_via_r0(dpm_to_arm11(dpm), - opcode, data); -} - -static int arm11_dpm_instr_read_data_dcc(struct arm_dpm *dpm, - uint32_t opcode, uint32_t *data) -{ - return arm11_run_instr_data_from_core(dpm_to_arm11(dpm), - opcode, data, 1); -} - -static int arm11_dpm_instr_read_data_r0(struct arm_dpm *dpm, - uint32_t opcode, uint32_t *data) -{ - return arm11_run_instr_data_from_core_via_r0(dpm_to_arm11(dpm), - opcode, data); -} - -/* Because arm11_sc7_run() takes a vector of actions, we batch breakpoint - * and watchpoint operations instead of running them right away. Since we - * pre-allocated our vector, we don't need to worry about space. - */ -static int arm11_bpwp_enable(struct arm_dpm *dpm, unsigned index_t, - uint32_t addr, uint32_t control) -{ - struct arm11_common *arm11 = dpm_to_arm11(dpm); - struct arm11_sc7_action *action; - - action = arm11->bpwp_actions + arm11->bpwp_n; - - /* Invariant: this bp/wp is disabled. - * It also happens that the core is halted here, but for - * DPM-based cores we don't actually care about that. - */ - - action[0].write = action[1].write = true; - - action[0].value = addr; - action[1].value = control; - - switch (index_t) { - case 0 ... 15: - action[0].address = ARM11_SC7_BVR0 + index_t; - action[1].address = ARM11_SC7_BCR0 + index_t; - break; - case 16 ... 32: - index_t -= 16; - action[0].address = ARM11_SC7_WVR0 + index_t; - action[1].address = ARM11_SC7_WCR0 + index_t; - break; - default: - return ERROR_FAIL; - } - - arm11->bpwp_n += 2; - - return ERROR_OK; -} - -static int arm11_bpwp_disable(struct arm_dpm *dpm, unsigned index_t) -{ - struct arm11_common *arm11 = dpm_to_arm11(dpm); - struct arm11_sc7_action *action; - - action = arm11->bpwp_actions + arm11->bpwp_n; - - action[0].write = true; - action[0].value = 0; - - switch (index_t) { - case 0 ... 15: - action[0].address = ARM11_SC7_BCR0 + index_t; - break; - case 16 ... 32: - index_t -= 16; - action[0].address = ARM11_SC7_WCR0 + index_t; - break; - default: - return ERROR_FAIL; - } - - arm11->bpwp_n += 1; - - return ERROR_OK; -} - -/** Flush any pending breakpoint and watchpoint updates. */ -int arm11_bpwp_flush(struct arm11_common *arm11) -{ - int retval; - - if (!arm11->bpwp_n) - return ERROR_OK; - - retval = arm11_sc7_run(arm11, arm11->bpwp_actions, arm11->bpwp_n); - arm11->bpwp_n = 0; - - return retval; -} - -/** Set up high-level debug module utilities */ -int arm11_dpm_init(struct arm11_common *arm11, uint32_t didr) -{ - struct arm_dpm *dpm = &arm11->dpm; - int retval; - - dpm->arm = &arm11->arm; - - dpm->didr = didr; - - dpm->prepare = arm11_dpm_prepare; - dpm->finish = arm11_dpm_finish; - - dpm->instr_write_data_dcc = arm11_dpm_instr_write_data_dcc; - dpm->instr_write_data_r0 = arm11_dpm_instr_write_data_r0; - - dpm->instr_read_data_dcc = arm11_dpm_instr_read_data_dcc; - dpm->instr_read_data_r0 = arm11_dpm_instr_read_data_r0; - - dpm->bpwp_enable = arm11_bpwp_enable; - dpm->bpwp_disable = arm11_bpwp_disable; - - retval = arm_dpm_setup(dpm); - if (retval != ERROR_OK) - return retval; - - /* alloc enough to enable all breakpoints and watchpoints at once */ - arm11->bpwp_actions = calloc(2 * (dpm->nbp + dpm->nwp), - sizeof *arm11->bpwp_actions); - if (!arm11->bpwp_actions) - return ERROR_FAIL; - - retval = arm_dpm_initialize(dpm); - if (retval != ERROR_OK) - return retval; - - return arm11_bpwp_flush(arm11); -} diff --git a/src/target/arm11_dbgtap.h b/src/target/arm11_dbgtap.h deleted file mode 100644 index 541434edc..000000000 --- a/src/target/arm11_dbgtap.h +++ /dev/null @@ -1,83 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2008 digenius technology GmbH. * - * Michael Bruck * - * * - * Copyright (C) 2008,2009 Oyvind Harboe oyvind.harboe@zylin.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifndef OPENOCD_TARGET_ARM11_DBGTAP_H -#define OPENOCD_TARGET_ARM11_DBGTAP_H - -#include "arm11.h" - -/* ARM11 internals */ - -void arm11_setup_field(struct arm11_common *arm11, int num_bits, - void *in_data, void *out_data, struct scan_field *field); -void arm11_add_IR(struct arm11_common *arm11, - uint8_t instr, tap_state_t state); -int arm11_add_debug_SCAN_N(struct arm11_common *arm11, - uint8_t chain, tap_state_t state); -int arm11_read_DSCR(struct arm11_common *arm11); -int arm11_write_DSCR(struct arm11_common *arm11, uint32_t dscr); - -int arm11_run_instr_data_prepare(struct arm11_common *arm11); -int arm11_run_instr_data_finish(struct arm11_common *arm11); -int arm11_run_instr_no_data1(struct arm11_common *arm11, uint32_t opcode); -int arm11_run_instr_data_to_core(struct arm11_common *arm11, - uint32_t opcode, uint32_t *data, size_t count); -int arm11_run_instr_data_to_core_noack(struct arm11_common *arm11, - uint32_t opcode, uint32_t *data, size_t count); -int arm11_run_instr_data_to_core1(struct arm11_common *arm11, - uint32_t opcode, uint32_t data); -int arm11_run_instr_data_from_core(struct arm11_common *arm11, - uint32_t opcode, uint32_t *data, size_t count); -int arm11_run_instr_data_from_core_via_r0(struct arm11_common *arm11, - uint32_t opcode, uint32_t *data); -int arm11_run_instr_data_to_core_via_r0(struct arm11_common *arm11, - uint32_t opcode, uint32_t data); - -void arm11_add_dr_scan_vc(struct jtag_tap *tap, int num_fields, struct scan_field *fields, - tap_state_t state); - -/** - * Used with arm11_sc7_run to make a list of read/write commands for - * scan chain 7 - */ -struct arm11_sc7_action { - bool write; /**< Access mode: true for write, false for read. */ - uint8_t address;/**< Register address mode. Use enum #arm11_sc7 */ - /** - * If write then set this to value to be written. In read mode - * this receives the read value when the function returns. - */ - uint32_t value; -}; - -int arm11_sc7_run(struct arm11_common *arm11, - struct arm11_sc7_action *actions, size_t count); - -/* Mid-level helper functions */ -int arm11_sc7_clear_vbw(struct arm11_common *arm11); -int arm11_sc7_set_vcr(struct arm11_common *arm11, uint32_t value); - -int arm11_read_memory_word(struct arm11_common *arm11, - uint32_t address, uint32_t *result); - -int arm11_dpm_init(struct arm11_common *arm11, uint32_t didr); -int arm11_bpwp_flush(struct arm11_common *arm11); - -#endif /* OPENOCD_TARGET_ARM11_DBGTAP_H */ diff --git a/src/target/arm720t.c b/src/target/arm720t.c deleted file mode 100644 index 3991e19f8..000000000 --- a/src/target/arm720t.c +++ /dev/null @@ -1,587 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * Copyright (C) 2009 by Øyvind Harboe * - * oyvind.harboe@zylin.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "arm720t.h" -#include -#include "target_type.h" -#include "register.h" -#include "arm_opcodes.h" - - -/* - * ARM720 is an ARM7TDMI-S with MMU and ETM7. For information, see - * ARM DDI 0229C especially Chapter 9 about debug support. - */ - -#if 0 -#define _DEBUG_INSTRUCTION_EXECUTION_ -#endif - -static int arm720t_scan_cp15(struct target *target, - uint32_t out, uint32_t *in, int instruction, int clock_arg) -{ - int retval; - struct arm720t_common *arm720t = target_to_arm720(target); - struct arm_jtag *jtag_info; - struct scan_field fields[2]; - uint8_t out_buf[4]; - uint8_t instruction_buf = instruction; - - jtag_info = &arm720t->arm7_9_common.jtag_info; - - buf_set_u32(out_buf, 0, 32, flip_u32(out, 32)); - - retval = arm_jtag_scann(jtag_info, 0xf, TAP_DRPAUSE); - if (retval != ERROR_OK) - return retval; - retval = arm_jtag_set_instr(jtag_info->tap, jtag_info->intest_instr, NULL, TAP_DRPAUSE); - if (retval != ERROR_OK) - return retval; - - fields[0].num_bits = 1; - fields[0].out_value = &instruction_buf; - fields[0].in_value = NULL; - - fields[1].num_bits = 32; - fields[1].out_value = out_buf; - fields[1].in_value = NULL; - - if (in) { - fields[1].in_value = (uint8_t *)in; - jtag_add_dr_scan(jtag_info->tap, 2, fields, TAP_DRPAUSE); - jtag_add_callback(arm7flip32, (jtag_callback_data_t)in); - } else - jtag_add_dr_scan(jtag_info->tap, 2, fields, TAP_DRPAUSE); - - if (clock_arg) - jtag_add_runtest(0, TAP_DRPAUSE); - -#ifdef _DEBUG_INSTRUCTION_EXECUTION_ - retval = jtag_execute_queue(); - if (retval != ERROR_OK) - return retval; - - if (in) - LOG_DEBUG("out: %8.8x, in: %8.8x, instruction: %i, clock: %i", out, *in, instruction, clock); - else - LOG_DEBUG("out: %8.8x, instruction: %i, clock: %i", out, instruction, clock_arg); -#else - LOG_DEBUG("out: %8.8" PRIx32 ", instruction: %i, clock: %i", out, instruction, clock_arg); -#endif - - return ERROR_OK; -} - -static int arm720t_read_cp15(struct target *target, uint32_t opcode, uint32_t *value) -{ - /* fetch CP15 opcode */ - arm720t_scan_cp15(target, opcode, NULL, 1, 1); - /* "DECODE" stage */ - arm720t_scan_cp15(target, ARMV4_5_NOP, NULL, 1, 1); - /* "EXECUTE" stage (1) */ - arm720t_scan_cp15(target, ARMV4_5_NOP, NULL, 1, 0); - arm720t_scan_cp15(target, 0x0, NULL, 0, 1); - /* "EXECUTE" stage (2) */ - arm720t_scan_cp15(target, 0x0, NULL, 0, 1); - /* "EXECUTE" stage (3), CDATA is read */ - arm720t_scan_cp15(target, ARMV4_5_NOP, value, 1, 1); - - return ERROR_OK; -} - -static int arm720t_write_cp15(struct target *target, uint32_t opcode, uint32_t value) -{ - /* fetch CP15 opcode */ - arm720t_scan_cp15(target, opcode, NULL, 1, 1); - /* "DECODE" stage */ - arm720t_scan_cp15(target, ARMV4_5_NOP, NULL, 1, 1); - /* "EXECUTE" stage (1) */ - arm720t_scan_cp15(target, ARMV4_5_NOP, NULL, 1, 0); - arm720t_scan_cp15(target, 0x0, NULL, 0, 1); - /* "EXECUTE" stage (2) */ - arm720t_scan_cp15(target, value, NULL, 0, 1); - arm720t_scan_cp15(target, ARMV4_5_NOP, NULL, 1, 1); - - return ERROR_OK; -} - -static int arm720t_get_ttb(struct target *target, uint32_t *result) -{ - uint32_t ttb = 0x0; - - int retval; - - retval = arm720t_read_cp15(target, 0xee120f10, &ttb); - if (retval != ERROR_OK) - return retval; - retval = jtag_execute_queue(); - if (retval != ERROR_OK) - return retval; - - ttb &= 0xffffc000; - - *result = ttb; - - return ERROR_OK; -} - -static int arm720t_disable_mmu_caches(struct target *target, - int mmu, int d_u_cache, int i_cache) -{ - uint32_t cp15_control; - int retval; - - /* read cp15 control register */ - retval = arm720t_read_cp15(target, 0xee110f10, &cp15_control); - if (retval != ERROR_OK) - return retval; - retval = jtag_execute_queue(); - if (retval != ERROR_OK) - return retval; - - if (mmu) - cp15_control &= ~0x1U; - - if (d_u_cache || i_cache) - cp15_control &= ~0x4U; - - retval = arm720t_write_cp15(target, 0xee010f10, cp15_control); - return retval; -} - -static int arm720t_enable_mmu_caches(struct target *target, - int mmu, int d_u_cache, int i_cache) -{ - uint32_t cp15_control; - int retval; - - /* read cp15 control register */ - retval = arm720t_read_cp15(target, 0xee110f10, &cp15_control); - if (retval != ERROR_OK) - return retval; - retval = jtag_execute_queue(); - if (retval != ERROR_OK) - return retval; - - if (mmu) - cp15_control |= 0x1U; - - if (d_u_cache || i_cache) - cp15_control |= 0x4U; - - retval = arm720t_write_cp15(target, 0xee010f10, cp15_control); - return retval; -} - -static int arm720t_post_debug_entry(struct target *target) -{ - struct arm720t_common *arm720t = target_to_arm720(target); - int retval; - - /* examine cp15 control reg */ - retval = arm720t_read_cp15(target, 0xee110f10, &arm720t->cp15_control_reg); - if (retval != ERROR_OK) - return retval; - retval = jtag_execute_queue(); - if (retval != ERROR_OK) - return retval; - LOG_DEBUG("cp15_control_reg: %8.8" PRIx32 "", arm720t->cp15_control_reg); - - arm720t->armv4_5_mmu.mmu_enabled = (arm720t->cp15_control_reg & 0x1U) ? 1 : 0; - arm720t->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled = (arm720t->cp15_control_reg & 0x4U) ? 1 : 0; - arm720t->armv4_5_mmu.armv4_5_cache.i_cache_enabled = 0; - - /* save i/d fault status and address register */ - retval = arm720t_read_cp15(target, 0xee150f10, &arm720t->fsr_reg); - if (retval != ERROR_OK) - return retval; - retval = arm720t_read_cp15(target, 0xee160f10, &arm720t->far_reg); - if (retval != ERROR_OK) - return retval; - retval = jtag_execute_queue(); - return retval; -} - -static void arm720t_pre_restore_context(struct target *target) -{ - struct arm720t_common *arm720t = target_to_arm720(target); - - /* restore i/d fault status and address register */ - arm720t_write_cp15(target, 0xee050f10, arm720t->fsr_reg); - arm720t_write_cp15(target, 0xee060f10, arm720t->far_reg); -} - -static int arm720t_verify_pointer(struct command_context *cmd_ctx, - struct arm720t_common *arm720t) -{ - if (arm720t->common_magic != ARM720T_COMMON_MAGIC) { - command_print(cmd_ctx, "target is not an ARM720"); - return ERROR_TARGET_INVALID; - } - return ERROR_OK; -} - -static int arm720t_arch_state(struct target *target) -{ - struct arm720t_common *arm720t = target_to_arm720(target); - - static const char *state[] = { - "disabled", "enabled" - }; - - arm_arch_state(target); - LOG_USER("MMU: %s, Cache: %s", - state[arm720t->armv4_5_mmu.mmu_enabled], - state[arm720t->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled]); - - return ERROR_OK; -} - -static int arm720_mmu(struct target *target, int *enabled) -{ - if (target->state != TARGET_HALTED) { - LOG_ERROR("%s: target not halted", __func__); - return ERROR_TARGET_INVALID; - } - - *enabled = target_to_arm720(target)->armv4_5_mmu.mmu_enabled; - return ERROR_OK; -} - -static int arm720_virt2phys(struct target *target, - uint32_t virtual, uint32_t *physical) -{ - uint32_t cb; - struct arm720t_common *arm720t = target_to_arm720(target); - - uint32_t ret; - int retval = armv4_5_mmu_translate_va(target, - &arm720t->armv4_5_mmu, virtual, &cb, &ret); - if (retval != ERROR_OK) - return retval; - *physical = ret; - return ERROR_OK; -} - -static int arm720t_read_memory(struct target *target, - uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer) -{ - int retval; - struct arm720t_common *arm720t = target_to_arm720(target); - - /* disable cache, but leave MMU enabled */ - if (arm720t->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled) { - retval = arm720t_disable_mmu_caches(target, 0, 1, 0); - if (retval != ERROR_OK) - return retval; - } - retval = arm7_9_read_memory(target, address, size, count, buffer); - - if (arm720t->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled) { - retval = arm720t_enable_mmu_caches(target, 0, 1, 0); - if (retval != ERROR_OK) - return retval; - } - - return retval; -} - -static int arm720t_read_phys_memory(struct target *target, - uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer) -{ - struct arm720t_common *arm720t = target_to_arm720(target); - - return armv4_5_mmu_read_physical(target, &arm720t->armv4_5_mmu, address, size, count, buffer); -} - -static int arm720t_write_phys_memory(struct target *target, - uint32_t address, uint32_t size, uint32_t count, const uint8_t *buffer) -{ - struct arm720t_common *arm720t = target_to_arm720(target); - - return armv4_5_mmu_write_physical(target, &arm720t->armv4_5_mmu, address, size, count, buffer); -} - -static int arm720t_soft_reset_halt(struct target *target) -{ - int retval = ERROR_OK; - struct arm720t_common *arm720t = target_to_arm720(target); - struct reg *dbg_stat = &arm720t->arm7_9_common - .eice_cache->reg_list[EICE_DBG_STAT]; - struct arm *arm = &arm720t->arm7_9_common.arm; - - retval = target_halt(target); - if (retval != ERROR_OK) - return retval; - - 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) { - embeddedice_read_reg(dbg_stat); - retval = jtag_execute_queue(); - if (retval != ERROR_OK) - return retval; - } else - break; - if (debug_level >= 3) - alive_sleep(100); - else - keep_alive(); - } - if (timeout) { - LOG_ERROR("Failed to halt CPU after 1 sec"); - return ERROR_TARGET_TIMEOUT; - } - - target->state = TARGET_HALTED; - - /* SVC, ARM state, IRQ and FIQ disabled */ - uint32_t cpsr; - - cpsr = buf_get_u32(arm->cpsr->value, 0, 32); - cpsr &= ~0xff; - cpsr |= 0xd3; - arm_set_cpsr(arm, cpsr); - arm->cpsr->dirty = 1; - - /* start fetching from 0x0 */ - buf_set_u32(arm->pc->value, 0, 32, 0x0); - arm->pc->dirty = 1; - arm->pc->valid = 1; - - retval = arm720t_disable_mmu_caches(target, 1, 1, 1); - if (retval != ERROR_OK) - return retval; - arm720t->armv4_5_mmu.mmu_enabled = 0; - arm720t->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled = 0; - arm720t->armv4_5_mmu.armv4_5_cache.i_cache_enabled = 0; - - retval = target_call_event_callbacks(target, TARGET_EVENT_HALTED); - if (retval != ERROR_OK) - return retval; - - return ERROR_OK; -} - -static int arm720t_init_target(struct command_context *cmd_ctx, struct target *target) -{ - return arm7tdmi_init_target(cmd_ctx, target); -} - -/* FIXME remove forward decls */ -static int arm720t_mrc(struct target *target, int cpnum, - uint32_t op1, uint32_t op2, - uint32_t CRn, uint32_t CRm, - uint32_t *value); -static int arm720t_mcr(struct target *target, int cpnum, - uint32_t op1, uint32_t op2, - uint32_t CRn, uint32_t CRm, - uint32_t value); - -static int arm720t_init_arch_info(struct target *target, - struct arm720t_common *arm720t, struct jtag_tap *tap) -{ - struct arm7_9_common *arm7_9 = &arm720t->arm7_9_common; - - arm7_9->arm.mrc = arm720t_mrc; - arm7_9->arm.mcr = arm720t_mcr; - - arm7tdmi_init_arch_info(target, arm7_9, tap); - - arm720t->common_magic = ARM720T_COMMON_MAGIC; - - arm7_9->post_debug_entry = arm720t_post_debug_entry; - arm7_9->pre_restore_context = arm720t_pre_restore_context; - - arm720t->armv4_5_mmu.armv4_5_cache.ctype = -1; - arm720t->armv4_5_mmu.get_ttb = arm720t_get_ttb; - arm720t->armv4_5_mmu.read_memory = arm7_9_read_memory; - arm720t->armv4_5_mmu.write_memory = arm7_9_write_memory; - arm720t->armv4_5_mmu.disable_mmu_caches = arm720t_disable_mmu_caches; - arm720t->armv4_5_mmu.enable_mmu_caches = arm720t_enable_mmu_caches; - arm720t->armv4_5_mmu.has_tiny_pages = 0; - arm720t->armv4_5_mmu.mmu_enabled = 0; - - return ERROR_OK; -} - -static int arm720t_target_create(struct target *target, Jim_Interp *interp) -{ - struct arm720t_common *arm720t = calloc(1, sizeof(*arm720t)); - - arm720t->arm7_9_common.arm.is_armv4 = true; - return arm720t_init_arch_info(target, arm720t, target->tap); -} - -COMMAND_HANDLER(arm720t_handle_cp15_command) -{ - int retval; - struct target *target = get_current_target(CMD_CTX); - struct arm720t_common *arm720t = target_to_arm720(target); - - retval = arm720t_verify_pointer(CMD_CTX, arm720t); - if (retval != ERROR_OK) - return retval; - - if (target->state != TARGET_HALTED) { - command_print(CMD_CTX, "target must be stopped for \"%s\" command", CMD_NAME); - return ERROR_OK; - } - - /* one or more argument, access a single register (write if second argument is given */ - if (CMD_ARGC >= 1) { - uint32_t opcode; - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], opcode); - - if (CMD_ARGC == 1) { - uint32_t value; - retval = arm720t_read_cp15(target, opcode, &value); - if (retval != ERROR_OK) { - command_print(CMD_CTX, "couldn't access cp15 with opcode 0x%8.8" PRIx32 "", opcode); - return ERROR_OK; - } - - retval = jtag_execute_queue(); - if (retval != ERROR_OK) - return retval; - - command_print(CMD_CTX, "0x%8.8" PRIx32 ": 0x%8.8" PRIx32 "", opcode, value); - } else if (CMD_ARGC == 2) { - uint32_t value; - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], value); - - retval = arm720t_write_cp15(target, opcode, value); - if (retval != ERROR_OK) { - command_print(CMD_CTX, "couldn't access cp15 with opcode 0x%8.8" PRIx32 "", opcode); - return ERROR_OK; - } - command_print(CMD_CTX, "0x%8.8" PRIx32 ": 0x%8.8" PRIx32 "", opcode, value); - } - } - - return ERROR_OK; -} - -static int arm720t_mrc(struct target *target, int cpnum, - uint32_t op1, uint32_t op2, - uint32_t CRn, uint32_t CRm, - uint32_t *value) -{ - if (cpnum != 15) { - LOG_ERROR("Only cp15 is supported"); - return ERROR_FAIL; - } - - /* read "to" r0 */ - return arm720t_read_cp15(target, - ARMV4_5_MRC(cpnum, op1, 0, CRn, CRm, op2), - value); - -} - -static int arm720t_mcr(struct target *target, int cpnum, - uint32_t op1, uint32_t op2, - uint32_t CRn, uint32_t CRm, - uint32_t value) -{ - if (cpnum != 15) { - LOG_ERROR("Only cp15 is supported"); - return ERROR_FAIL; - } - - /* write "from" r0 */ - return arm720t_write_cp15(target, - ARMV4_5_MCR(cpnum, op1, 0, CRn, CRm, op2), - value); -} - -static const struct command_registration arm720t_exec_command_handlers[] = { - { - .name = "cp15", - .handler = arm720t_handle_cp15_command, - .mode = COMMAND_EXEC, - /* prefer using less error-prone "arm mcr" or "arm mrc" */ - .help = "display/modify cp15 register using ARM opcode" - " (DEPRECATED)", - .usage = "instruction [value]", - }, - COMMAND_REGISTRATION_DONE -}; - -static const struct command_registration arm720t_command_handlers[] = { - { - .chain = arm7_9_command_handlers, - }, - { - .name = "arm720t", - .mode = COMMAND_ANY, - .help = "arm720t command group", - .usage = "", - .chain = arm720t_exec_command_handlers, - }, - COMMAND_REGISTRATION_DONE -}; - -/** Holds methods for ARM720 targets. */ -struct target_type arm720t_target = { - .name = "arm720t", - - .poll = arm7_9_poll, - .arch_state = arm720t_arch_state, - - .halt = arm7_9_halt, - .resume = arm7_9_resume, - .step = arm7_9_step, - - .assert_reset = arm7_9_assert_reset, - .deassert_reset = arm7_9_deassert_reset, - .soft_reset_halt = arm720t_soft_reset_halt, - - .get_gdb_reg_list = arm_get_gdb_reg_list, - - .read_memory = arm720t_read_memory, - .write_memory = arm7_9_write_memory_opt, - .read_phys_memory = arm720t_read_phys_memory, - .write_phys_memory = arm720t_write_phys_memory, - .mmu = arm720_mmu, - .virt2phys = arm720_virt2phys, - - .checksum_memory = arm_checksum_memory, - .blank_check_memory = arm_blank_check_memory, - - .run_algorithm = armv4_5_run_algorithm, - - .add_breakpoint = arm7_9_add_breakpoint, - .remove_breakpoint = arm7_9_remove_breakpoint, - .add_watchpoint = arm7_9_add_watchpoint, - .remove_watchpoint = arm7_9_remove_watchpoint, - - .commands = arm720t_command_handlers, - .target_create = arm720t_target_create, - .init_target = arm720t_init_target, - .examine = arm7_9_examine, - .check_reset = arm7_9_check_reset, -}; diff --git a/src/target/arm720t.h b/src/target/arm720t.h deleted file mode 100644 index 31dad9c76..000000000 --- a/src/target/arm720t.h +++ /dev/null @@ -1,41 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifndef OPENOCD_TARGET_ARM720T_H -#define OPENOCD_TARGET_ARM720T_H - -#include "arm7tdmi.h" -#include "armv4_5_mmu.h" - -#define ARM720T_COMMON_MAGIC 0xa720a720 - -struct arm720t_common { - struct arm7_9_common arm7_9_common; - uint32_t common_magic; - struct armv4_5_mmu_common armv4_5_mmu; - uint32_t cp15_control_reg; - uint32_t fsr_reg; - uint32_t far_reg; -}; - -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 /* OPENOCD_TARGET_ARM720T_H */ diff --git a/src/target/arm7_9_common.c b/src/target/arm7_9_common.c deleted file mode 100644 index c1d5c7944..000000000 --- a/src/target/arm7_9_common.c +++ /dev/null @@ -1,2903 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * Copyright (C) 2007-2010 Øyvind Harboe * - * oyvind.harboe@zylin.com * - * * - * Copyright (C) 2008 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * Copyright (C) 2008 by Hongtao Zheng * - * hontor@126.com * - * * - * Copyright (C) 2009 by David Brownell * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "breakpoints.h" -#include "embeddedice.h" -#include "target_request.h" -#include "etm.h" -#include -#include "arm_simulator.h" -#include "arm_semihosting.h" -#include "algorithm.h" -#include "register.h" -#include "armv4_5.h" - -/** - * @file - * Hold common code supporting the ARM7 and ARM9 core generations. - * - * While the ARM core implementations evolved substantially during these - * two generations, they look quite similar from the JTAG perspective. - * Both have similar debug facilities, based on the same two scan chains - * providing access to the core and to an EmbeddedICE module. Both can - * support similar ETM and ETB modules, for tracing. And both expose - * what could be viewed as "ARM Classic", with multiple processor modes, - * shadowed registers, and support for the Thumb instruction set. - * - * Processor differences include things like presence or absence of MMU - * and cache, pipeline sizes, use of a modified Harvard Architecure - * (with separate instruction and data busses from the CPU), support - * for cpu clock gating during idle, and more. - */ - -static int arm7_9_debug_entry(struct target *target); - -/** - * Clear watchpoints for an ARM7/9 target. - * - * @param arm7_9 Pointer to the common struct for an ARM7/9 target - * @return JTAG error status after executing queue - */ -static int arm7_9_clear_watchpoints(struct arm7_9_common *arm7_9) -{ - LOG_DEBUG("-"); - embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_VALUE], 0x0); - embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W1_CONTROL_VALUE], 0x0); - arm7_9->sw_breakpoint_count = 0; - arm7_9->sw_breakpoints_added = 0; - arm7_9->wp0_used = 0; - arm7_9->wp1_used = arm7_9->wp1_used_default; - arm7_9->wp_available = arm7_9->wp_available_max; - - return jtag_execute_queue(); -} - -/** - * Assign a watchpoint to one of the two available hardware comparators in an - * ARM7 or ARM9 target. - * - * @param arm7_9 Pointer to the common struct for an ARM7/9 target - * @param breakpoint Pointer to the breakpoint to be used as a watchpoint - */ -static void arm7_9_assign_wp(struct arm7_9_common *arm7_9, struct breakpoint *breakpoint) -{ - if (!arm7_9->wp0_used) { - arm7_9->wp0_used = 1; - breakpoint->set = 1; - arm7_9->wp_available--; - } else if (!arm7_9->wp1_used) { - arm7_9->wp1_used = 1; - breakpoint->set = 2; - arm7_9->wp_available--; - } else - LOG_ERROR("BUG: no hardware comparator available"); - LOG_DEBUG("BPID: %" PRId32 " (0x%08" PRIx32 ") using hw wp: %d", - breakpoint->unique_id, - breakpoint->address, - breakpoint->set); -} - -/** - * Setup an ARM7/9 target's embedded ICE registers for software breakpoints. - * - * @param arm7_9 Pointer to common struct for ARM7/9 targets - * @return Error codes if there is a problem finding a watchpoint or the result - * of executing the JTAG queue - */ -static int arm7_9_set_software_breakpoints(struct arm7_9_common *arm7_9) -{ - if (arm7_9->sw_breakpoints_added) - return ERROR_OK; - if (arm7_9->wp_available < 1) { - LOG_WARNING("can't enable sw breakpoints with no watchpoint unit available"); - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - } - arm7_9->wp_available--; - - /* pick a breakpoint unit */ - if (!arm7_9->wp0_used) { - arm7_9->sw_breakpoints_added = 1; - arm7_9->wp0_used = 3; - } else if (!arm7_9->wp1_used) { - arm7_9->sw_breakpoints_added = 2; - arm7_9->wp1_used = 3; - } else { - LOG_ERROR("BUG: both watchpoints used, but wp_available >= 1"); - return ERROR_FAIL; - } - - if (arm7_9->sw_breakpoints_added == 1) { - embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W0_DATA_VALUE], arm7_9->arm_bkpt); - embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W0_DATA_MASK], 0x0); - embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W0_ADDR_MASK], 0xffffffffu); - embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_MASK], ~EICE_W_CTRL_nOPC & 0xff); - embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_VALUE], EICE_W_CTRL_ENABLE); - } else if (arm7_9->sw_breakpoints_added == 2) { - embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W1_DATA_VALUE], arm7_9->arm_bkpt); - embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W1_DATA_MASK], 0x0); - embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W1_ADDR_MASK], 0xffffffffu); - embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W1_CONTROL_MASK], ~EICE_W_CTRL_nOPC & 0xff); - embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W1_CONTROL_VALUE], EICE_W_CTRL_ENABLE); - } else { - LOG_ERROR("BUG: both watchpoints used, but wp_available >= 1"); - return ERROR_FAIL; - } - LOG_DEBUG("SW BP using hw wp: %d", - arm7_9->sw_breakpoints_added); - - return jtag_execute_queue(); -} - -/** - * Setup the common pieces for an ARM7/9 target after reset or on startup. - * - * @param target Pointer to an ARM7/9 target to setup - * @return Result of clearing the watchpoints on the target - */ -static int arm7_9_setup(struct target *target) -{ - struct arm7_9_common *arm7_9 = target_to_arm7_9(target); - - return arm7_9_clear_watchpoints(arm7_9); -} - -/** - * Set either a hardware or software breakpoint on an ARM7/9 target. The - * breakpoint is set up even if it is already set. Some actions, e.g. reset, - * might have erased the values in Embedded ICE. - * - * @param target Pointer to the target device to set the breakpoints on - * @param breakpoint Pointer to the breakpoint to be set - * @return For hardware breakpoints, this is the result of executing the JTAG - * queue. For software breakpoints, this will be the status of the - * required memory reads and writes - */ -static int arm7_9_set_breakpoint(struct target *target, struct breakpoint *breakpoint) -{ - 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", - breakpoint->unique_id, - breakpoint->address, - breakpoint->type); - - if (target->state != TARGET_HALTED) { - LOG_WARNING("target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - if (breakpoint->type == BKPT_HARD) { - /* either an ARM (4 byte) or Thumb (2 byte) breakpoint */ - uint32_t mask = (breakpoint->length == 4) ? 0x3u : 0x1u; - - /* reassign a hw breakpoint */ - if (breakpoint->set == 0) - arm7_9_assign_wp(arm7_9, breakpoint); - - if (breakpoint->set == 1) { - embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W0_ADDR_VALUE], breakpoint->address); - embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W0_ADDR_MASK], mask); - embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W0_DATA_MASK], 0xffffffffu); - embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_MASK], ~EICE_W_CTRL_nOPC & 0xff); - embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_VALUE], EICE_W_CTRL_ENABLE); - } else if (breakpoint->set == 2) { - embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W1_ADDR_VALUE], breakpoint->address); - embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W1_ADDR_MASK], mask); - embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W1_DATA_MASK], 0xffffffffu); - embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W1_CONTROL_MASK], ~EICE_W_CTRL_nOPC & 0xff); - embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W1_CONTROL_VALUE], EICE_W_CTRL_ENABLE); - } else { - LOG_ERROR("BUG: no hardware comparator available"); - return ERROR_OK; - } - - retval = jtag_execute_queue(); - } else if (breakpoint->type == BKPT_SOFT) { - /* did we already set this breakpoint? */ - if (breakpoint->set) - return ERROR_OK; - - if (breakpoint->length == 4) { - uint32_t verify = 0xffffffff; - /* keep the original instruction in target endianness */ - retval = target_read_memory(target, breakpoint->address, 4, 1, breakpoint->orig_instr); - if (retval != ERROR_OK) - return retval; - /* write the breakpoint instruction in target - * endianness (arm7_9->arm_bkpt is host endian) */ - retval = target_write_u32(target, breakpoint->address, arm7_9->arm_bkpt); - if (retval != ERROR_OK) - return retval; - - retval = target_read_u32(target, breakpoint->address, &verify); - 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 - " - check that memory is read/writable", breakpoint->address); - return ERROR_OK; - } - } else { - uint16_t verify = 0xffff; - /* keep the original instruction in target endianness */ - retval = target_read_memory(target, breakpoint->address, 2, 1, breakpoint->orig_instr); - if (retval != ERROR_OK) - return retval; - /* write the breakpoint instruction in target - * endianness (arm7_9->thumb_bkpt is host endian) */ - retval = target_write_u16(target, breakpoint->address, arm7_9->thumb_bkpt); - if (retval != ERROR_OK) - return retval; - - retval = target_read_u16(target, breakpoint->address, &verify); - if (retval != ERROR_OK) - return retval; - if (verify != arm7_9->thumb_bkpt) { - LOG_ERROR("Unable to set thumb software breakpoint at address %08" PRIx32 - " - check that memory is read/writable", breakpoint->address); - return ERROR_OK; - } - } - - retval = arm7_9_set_software_breakpoints(arm7_9); - if (retval != ERROR_OK) - return retval; - - arm7_9->sw_breakpoint_count++; - - breakpoint->set = 1; - } - - return retval; -} - -/** - * Unsets an existing breakpoint on an ARM7/9 target. If it is a hardware - * breakpoint, the watchpoint used will be freed and the Embedded ICE registers - * will be updated. Otherwise, the software breakpoint will be restored to its - * original instruction if it hasn't already been modified. - * - * @param target Pointer to ARM7/9 target to unset the breakpoint from - * @param breakpoint Pointer to breakpoint to be unset - * @return For hardware breakpoints, this is the result of executing the JTAG - * queue. For software breakpoints, this will be the status of the - * required memory reads and writes - */ -static int arm7_9_unset_breakpoint(struct target *target, struct breakpoint *breakpoint) -{ - int retval = ERROR_OK; - struct arm7_9_common *arm7_9 = target_to_arm7_9(target); - - LOG_DEBUG("BPID: %" PRId32 ", Address: 0x%08" PRIx32, - breakpoint->unique_id, - breakpoint->address); - - if (!breakpoint->set) { - LOG_WARNING("breakpoint not set"); - return ERROR_OK; - } - - if (breakpoint->type == BKPT_HARD) { - LOG_DEBUG("BPID: %" PRId32 " Releasing hw wp: %d", - breakpoint->unique_id, - breakpoint->set); - if (breakpoint->set == 1) { - embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_VALUE], 0x0); - arm7_9->wp0_used = 0; - arm7_9->wp_available++; - } else if (breakpoint->set == 2) { - embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W1_CONTROL_VALUE], 0x0); - arm7_9->wp1_used = 0; - arm7_9->wp_available++; - } - retval = jtag_execute_queue(); - breakpoint->set = 0; - } else { - /* restore original instruction (kept in target endianness) */ - if (breakpoint->length == 4) { - uint32_t current_instr; - /* check that user program as not modified breakpoint instruction */ - retval = target_read_memory(target, - breakpoint->address, 4, 1, (uint8_t *)¤t_instr); - if (retval != ERROR_OK) - return retval; - current_instr = target_buffer_get_u32(target, (uint8_t *)¤t_instr); - if (current_instr == arm7_9->arm_bkpt) { - retval = target_write_memory(target, - breakpoint->address, 4, 1, breakpoint->orig_instr); - if (retval != ERROR_OK) - return retval; - } - - } else { - uint16_t current_instr; - /* check that user program as not modified breakpoint instruction */ - retval = target_read_memory(target, - breakpoint->address, 2, 1, (uint8_t *)¤t_instr); - if (retval != ERROR_OK) - return retval; - current_instr = target_buffer_get_u16(target, (uint8_t *)¤t_instr); - 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) { - /* We have removed the last sw breakpoint, clear the hw breakpoint we used - *to implement it */ - if (arm7_9->sw_breakpoints_added == 1) - embeddedice_set_reg(&arm7_9->eice_cache->reg_list[ - EICE_W0_CONTROL_VALUE], 0); - else if (arm7_9->sw_breakpoints_added == 2) - embeddedice_set_reg(&arm7_9->eice_cache->reg_list[ - EICE_W1_CONTROL_VALUE], 0); - } - - breakpoint->set = 0; - } - - return retval; -} - -/** - * Add a breakpoint to an ARM7/9 target. This makes sure that there are no - * dangling breakpoints and that the desired breakpoint can be added. - * - * @param target Pointer to the target ARM7/9 device to add a breakpoint to - * @param breakpoint Pointer to the breakpoint to be added - * @return An error status if there is a problem adding the breakpoint or the - * result of setting the breakpoint - */ -int arm7_9_add_breakpoint(struct target *target, struct breakpoint *breakpoint) -{ - struct arm7_9_common *arm7_9 = target_to_arm7_9(target); - - if (arm7_9->breakpoint_count == 0) { - /* make sure we don't have any dangling breakpoints. This is vital upon - * GDB connect/disconnect - */ - arm7_9_clear_watchpoints(arm7_9); - } - - if ((breakpoint->type == BKPT_HARD) && (arm7_9->wp_available < 1)) { - LOG_INFO("no watchpoint unit available for hardware breakpoint"); - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - } - - if ((breakpoint->length != 2) && (breakpoint->length != 4)) { - LOG_INFO("only breakpoints of two (Thumb) or four (ARM) bytes length supported"); - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - } - - if (breakpoint->type == BKPT_HARD) - arm7_9_assign_wp(arm7_9, breakpoint); - - arm7_9->breakpoint_count++; - - return arm7_9_set_breakpoint(target, breakpoint); -} - -/** - * Removes a breakpoint from an ARM7/9 target. This will make sure there are no - * dangling breakpoints and updates available watchpoints if it is a hardware - * breakpoint. - * - * @param target Pointer to the target to have a breakpoint removed - * @param breakpoint Pointer to the breakpoint to be removed - * @return Error status if there was a problem unsetting the breakpoint or the - * watchpoints could not be cleared - */ -int arm7_9_remove_breakpoint(struct target *target, struct breakpoint *breakpoint) -{ - int retval = ERROR_OK; - struct arm7_9_common *arm7_9 = target_to_arm7_9(target); - - retval = arm7_9_unset_breakpoint(target, breakpoint); - if (retval != ERROR_OK) - return retval; - - if (breakpoint->type == BKPT_HARD) - arm7_9->wp_available++; - - arm7_9->breakpoint_count--; - if (arm7_9->breakpoint_count == 0) { - /* make sure we don't have any dangling breakpoints */ - retval = arm7_9_clear_watchpoints(arm7_9); - if (retval != ERROR_OK) - return retval; - } - - return ERROR_OK; -} - -/** - * Sets a watchpoint for an ARM7/9 target in one of the watchpoint units. It is - * considered a bug to call this function when there are no available watchpoint - * units. - * - * @param target Pointer to an ARM7/9 target to set a watchpoint on - * @param watchpoint Pointer to the watchpoint to be set - * @return Error status if watchpoint set fails or the result of executing the - * JTAG queue - */ -static int arm7_9_set_watchpoint(struct target *target, struct watchpoint *watchpoint) -{ - int retval = ERROR_OK; - struct arm7_9_common *arm7_9 = target_to_arm7_9(target); - int rw_mask = 1; - uint32_t mask; - - mask = watchpoint->length - 1; - - if (target->state != TARGET_HALTED) { - LOG_WARNING("target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - if (watchpoint->rw == WPT_ACCESS) - rw_mask = 0; - else - rw_mask = 1; - - if (!arm7_9->wp0_used) { - embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W0_ADDR_VALUE], - watchpoint->address); - embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W0_ADDR_MASK], mask); - embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W0_DATA_MASK], - watchpoint->mask); - if (watchpoint->mask != 0xffffffffu) - embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W0_DATA_VALUE], - watchpoint->value); - embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_MASK], - 0xff & ~EICE_W_CTRL_nOPC & ~rw_mask); - embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_VALUE], - EICE_W_CTRL_ENABLE | EICE_W_CTRL_nOPC | (watchpoint->rw & 1)); - - retval = jtag_execute_queue(); - if (retval != ERROR_OK) - return retval; - watchpoint->set = 1; - arm7_9->wp0_used = 2; - } else if (!arm7_9->wp1_used) { - embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W1_ADDR_VALUE], - watchpoint->address); - embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W1_ADDR_MASK], mask); - embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W1_DATA_MASK], - watchpoint->mask); - if (watchpoint->mask != 0xffffffffu) - embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W1_DATA_VALUE], - watchpoint->value); - embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W1_CONTROL_MASK], - 0xff & ~EICE_W_CTRL_nOPC & ~rw_mask); - embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W1_CONTROL_VALUE], - EICE_W_CTRL_ENABLE | EICE_W_CTRL_nOPC | (watchpoint->rw & 1)); - - retval = jtag_execute_queue(); - if (retval != ERROR_OK) - return retval; - watchpoint->set = 2; - arm7_9->wp1_used = 2; - } else { - LOG_ERROR("BUG: no hardware comparator available"); - return ERROR_OK; - } - - return ERROR_OK; -} - -/** - * Unset an existing watchpoint and clear the used watchpoint unit. - * - * @param target Pointer to the target to have the watchpoint removed - * @param watchpoint Pointer to the watchpoint to be removed - * @return Error status while trying to unset the watchpoint or the result of - * executing the JTAG queue - */ -static int arm7_9_unset_watchpoint(struct target *target, struct watchpoint *watchpoint) -{ - int retval = ERROR_OK; - struct arm7_9_common *arm7_9 = target_to_arm7_9(target); - - if (target->state != TARGET_HALTED) { - LOG_WARNING("target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - if (!watchpoint->set) { - LOG_WARNING("breakpoint not set"); - return ERROR_OK; - } - - if (watchpoint->set == 1) { - embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_VALUE], 0x0); - retval = jtag_execute_queue(); - if (retval != ERROR_OK) - return retval; - arm7_9->wp0_used = 0; - } else if (watchpoint->set == 2) { - embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W1_CONTROL_VALUE], 0x0); - retval = jtag_execute_queue(); - if (retval != ERROR_OK) - return retval; - arm7_9->wp1_used = 0; - } - watchpoint->set = 0; - - return ERROR_OK; -} - -/** - * Add a watchpoint to an ARM7/9 target. If there are no watchpoint units - * available, an error response is returned. - * - * @param target Pointer to the ARM7/9 target to add a watchpoint to - * @param watchpoint Pointer to the watchpoint to be added - * @return Error status while trying to add the watchpoint - */ -int arm7_9_add_watchpoint(struct target *target, struct watchpoint *watchpoint) -{ - struct arm7_9_common *arm7_9 = target_to_arm7_9(target); - - if (arm7_9->wp_available < 1) - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - - if ((watchpoint->length != 1) && (watchpoint->length != 2) && (watchpoint->length != 4)) - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - - arm7_9->wp_available--; - - return ERROR_OK; -} - -/** - * Remove a watchpoint from an ARM7/9 target. The watchpoint will be unset and - * the used watchpoint unit will be reopened. - * - * @param target Pointer to the target to remove a watchpoint from - * @param watchpoint Pointer to the watchpoint to be removed - * @return Result of trying to unset the watchpoint - */ -int arm7_9_remove_watchpoint(struct target *target, struct watchpoint *watchpoint) -{ - int retval = ERROR_OK; - struct arm7_9_common *arm7_9 = target_to_arm7_9(target); - - if (watchpoint->set) { - retval = arm7_9_unset_watchpoint(target, watchpoint); - if (retval != ERROR_OK) - return retval; - } - - arm7_9->wp_available++; - - return ERROR_OK; -} - -/** - * Restarts the target by sending a RESTART instruction and moving the JTAG - * state to IDLE. This includes a timeout waiting for DBGACK and SYSCOMP to be - * asserted by the processor. - * - * @param target Pointer to target to issue commands to - * @return Error status if there is a timeout or a problem while executing the - * JTAG queue - */ -int arm7_9_execute_sys_speed(struct target *target) -{ - int retval; - struct arm7_9_common *arm7_9 = target_to_arm7_9(target); - struct arm_jtag *jtag_info = &arm7_9->jtag_info; - struct reg *dbg_stat = &arm7_9->eice_cache->reg_list[EICE_DBG_STAT]; - - /* set RESTART instruction */ - if (arm7_9->need_bypass_before_restart) { - arm7_9->need_bypass_before_restart = 0; - retval = arm_jtag_set_instr(jtag_info->tap, 0xf, NULL, TAP_IDLE); - if (retval != ERROR_OK) - return retval; - } - retval = arm_jtag_set_instr(jtag_info->tap, 0x4, NULL, TAP_IDLE); - if (retval != ERROR_OK) - return retval; - - int64_t then = timeval_ms(); - bool timeout; - while (!(timeout = ((timeval_ms()-then) > 1000))) { - /* read debug status register */ - embeddedice_read_reg(dbg_stat); - retval = jtag_execute_queue(); - if (retval != ERROR_OK) - return retval; - if ((buf_get_u32(dbg_stat->value, EICE_DBG_STATUS_DBGACK, 1)) - && (buf_get_u32(dbg_stat->value, EICE_DBG_STATUS_SYSCOMP, 1))) - break; - if (debug_level >= 3) - alive_sleep(100); - else - keep_alive(); - } - if (timeout) { - LOG_ERROR("timeout waiting for SYSCOMP & DBGACK, last DBG_STATUS: %" PRIx32 "", - buf_get_u32(dbg_stat->value, 0, dbg_stat->size)); - return ERROR_TARGET_TIMEOUT; - } - - return ERROR_OK; -} - -/** - * Restarts the target by sending a RESTART instruction and moving the JTAG - * state to IDLE. This validates that DBGACK and SYSCOMP are set without - * waiting until they are. - * - * @param target Pointer to the target to issue commands to - * @return Always ERROR_OK - */ -static int arm7_9_execute_fast_sys_speed(struct target *target) -{ - static int set; - static uint8_t check_value[4], check_mask[4]; - - struct arm7_9_common *arm7_9 = target_to_arm7_9(target); - struct arm_jtag *jtag_info = &arm7_9->jtag_info; - struct reg *dbg_stat = &arm7_9->eice_cache->reg_list[EICE_DBG_STAT]; - int retval; - - /* set RESTART instruction */ - if (arm7_9->need_bypass_before_restart) { - arm7_9->need_bypass_before_restart = 0; - retval = arm_jtag_set_instr(jtag_info->tap, 0xf, NULL, TAP_IDLE); - if (retval != ERROR_OK) - return retval; - } - retval = arm_jtag_set_instr(jtag_info->tap, 0x4, NULL, TAP_IDLE); - if (retval != ERROR_OK) - return retval; - - if (!set) { - /* check for DBGACK and SYSCOMP set (others don't care) */ - - /* NB! These are constants that must be available until after next jtag_execute() and - * we evaluate the values upon first execution in lieu of setting up these constants - * during early setup. - * */ - buf_set_u32(check_value, 0, 32, 0x9); - buf_set_u32(check_mask, 0, 32, 0x9); - set = 1; - } - - /* read debug status register */ - embeddedice_read_reg_w_check(dbg_stat, check_value, check_mask); - - return ERROR_OK; -} - -/** - * Get some data from the ARM7/9 target. - * - * @param target Pointer to the ARM7/9 target to read data from - * @param size The number of 32bit words to be read - * @param buffer Pointer to the buffer that will hold the data - * @return The result of receiving data from the Embedded ICE unit - */ -int arm7_9_target_request_data(struct target *target, uint32_t size, uint8_t *buffer) -{ - struct arm7_9_common *arm7_9 = target_to_arm7_9(target); - struct arm_jtag *jtag_info = &arm7_9->jtag_info; - uint32_t *data; - int retval = ERROR_OK; - uint32_t i; - - data = malloc(size * (sizeof(uint32_t))); - - retval = embeddedice_receive(jtag_info, data, size); - - /* return the 32-bit ints in the 8-bit array */ - for (i = 0; i < size; i++) - h_u32_to_le(buffer + (i * 4), data[i]); - - free(data); - - return retval; -} - -/** - * Handles requests to an ARM7/9 target. If debug messaging is enabled, the - * target is running and the DCC control register has the W bit high, this will - * execute the request on the target. - * - * @param priv Void pointer expected to be a struct target pointer - * @return ERROR_OK unless there are issues with the JTAG queue or when reading - * from the Embedded ICE unit - */ -static int arm7_9_handle_target_request(void *priv) -{ - int retval = ERROR_OK; - struct target *target = priv; - if (!target_was_examined(target)) - return ERROR_OK; - struct arm7_9_common *arm7_9 = target_to_arm7_9(target); - struct arm_jtag *jtag_info = &arm7_9->jtag_info; - struct reg *dcc_control = &arm7_9->eice_cache->reg_list[EICE_COMMS_CTRL]; - - if (!target->dbg_msg_enabled) - return ERROR_OK; - - if (target->state == TARGET_RUNNING) { - /* read DCC control register */ - embeddedice_read_reg(dcc_control); - retval = jtag_execute_queue(); - if (retval != ERROR_OK) - return retval; - - /* check W bit */ - if (buf_get_u32(dcc_control->value, 1, 1) == 1) { - uint32_t request; - - retval = embeddedice_receive(jtag_info, &request, 1); - if (retval != ERROR_OK) - return retval; - retval = target_request(target, request); - if (retval != ERROR_OK) - return retval; - } - } - - return ERROR_OK; -} - -/** - * Polls an ARM7/9 target for its current status. If DBGACK is set, the target - * is manipulated to the right halted state based on its current state. This is - * what happens: - * - * - * - * - * - * - * - * - *
State Action
TARGET_RUNNING | TARGET_RESET Enters debug mode. If TARGET_RESET, pc may be checked
TARGET_UNKNOWN Warning is logged
TARGET_DEBUG_RUNNING Enters debug mode
TARGET_HALTED Nothing
- * - * If the target does not end up in the halted state, a warning is produced. If - * DBGACK is cleared, then the target is expected to either be running or - * running in debug. - * - * @param target Pointer to the ARM7/9 target to poll - * @return ERROR_OK or an error status if a command fails - */ -int arm7_9_poll(struct target *target) -{ - int retval; - struct arm7_9_common *arm7_9 = target_to_arm7_9(target); - struct reg *dbg_stat = &arm7_9->eice_cache->reg_list[EICE_DBG_STAT]; - - /* read debug status register */ - embeddedice_read_reg(dbg_stat); - retval = jtag_execute_queue(); - if (retval != ERROR_OK) - return retval; - - if (buf_get_u32(dbg_stat->value, EICE_DBG_STATUS_DBGACK, 1)) { - /* LOG_DEBUG("DBGACK set, dbg_state->value: 0x%x", buf_get_u32(dbg_stat->value, 0, *32));*/ - if (target->state == TARGET_UNKNOWN) { - /* Starting OpenOCD with target in debug-halt */ - target->state = TARGET_RUNNING; - LOG_DEBUG("DBGACK already set during server startup."); - } - if ((target->state == TARGET_RUNNING) || (target->state == TARGET_RESET)) { - target->state = TARGET_HALTED; - - retval = arm7_9_debug_entry(target); - if (retval != ERROR_OK) - return retval; - - if (arm_semihosting(target, &retval) != 0) - return retval; - - retval = target_call_event_callbacks(target, TARGET_EVENT_HALTED); - if (retval != ERROR_OK) - return retval; - } - if (target->state == TARGET_DEBUG_RUNNING) { - target->state = TARGET_HALTED; - retval = arm7_9_debug_entry(target); - if (retval != ERROR_OK) - return retval; - - retval = target_call_event_callbacks(target, TARGET_EVENT_DEBUG_HALTED); - if (retval != ERROR_OK) - return retval; - } - if (target->state != TARGET_HALTED) - LOG_WARNING( - "DBGACK set, but the target did not end up in the halted state %d", - target->state); - } else { - if (target->state != TARGET_DEBUG_RUNNING) - target->state = TARGET_RUNNING; - } - - return ERROR_OK; -} - -/** - * Asserts the reset (SRST) on an ARM7/9 target. Some -S targets (ARM966E-S in - * the STR912 isn't affected, ARM926EJ-S in the LPC3180 and AT91SAM9260 is - * affected) completely stop the JTAG clock while the core is held in reset - * (SRST). It isn't possible to program the halt condition once reset is - * asserted, hence a hook that allows the target to set up its reset-halt - * condition is setup prior to asserting reset. - * - * @param target Pointer to an ARM7/9 target to assert reset on - * @return ERROR_FAIL if the JTAG device does not have SRST, otherwise ERROR_OK - */ -int arm7_9_assert_reset(struct target *target) -{ - struct arm7_9_common *arm7_9 = target_to_arm7_9(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)) - use_event = true; - else if (!(jtag_reset_config & RESET_HAS_SRST)) { - LOG_ERROR("%s: how to reset?", target_name(target)); - return ERROR_FAIL; - } - - /* At this point trst has been asserted/deasserted once. We would - * like to program EmbeddedICE while SRST is asserted, instead of - * depending on SRST to leave that module alone. However, many CPUs - * gate the JTAG clock while SRST is asserted; or JTAG may need - * clock stability guarantees (adaptive clocking might help). - * - * So we assume JTAG access during SRST is off the menu unless it's - * been specifically enabled. - */ - bool srst_asserted = false; - - if (!use_event && !(jtag_reset_config & RESET_SRST_PULLS_TRST) - && (jtag_reset_config & RESET_SRST_NO_GATING)) { - jtag_add_reset(0, 1); - srst_asserted = true; - } - - if (target->reset_halt) { - /* - * For targets that don't support communication while SRST is - * asserted, we need to set up the reset vector catch first. - * - * When we use TRST+SRST and that's equivalent to a power-up - * reset, these settings may well be reset anyway; so setting - * them here won't matter. - */ - if (arm7_9->has_vector_catch) { - /* program vector catch register to catch reset */ - embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_VEC_CATCH], 0x1); - - /* extra runtest added as issues were found with - * certain ARM9 cores (maybe more) - AT91SAM9260 - * and STR9 - */ - jtag_add_runtest(1, TAP_IDLE); - } else { - /* program watchpoint unit to match on reset vector - * address - */ - embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_ADDR_VALUE], 0x0); - embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_ADDR_MASK], 0x3); - embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_DATA_MASK], 0xffffffff); - embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_VALUE], EICE_W_CTRL_ENABLE); - embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_MASK], ~EICE_W_CTRL_nOPC & 0xff); - } - } - - if (use_event) - target_handle_event(target, TARGET_EVENT_RESET_ASSERT); - else { - /* If we use SRST ... we'd like to issue just SRST, but the - * board or chip may be set up so we have to assert TRST as - * well. On some chips that combination is equivalent to a - * power-up reset, and generally clobbers EICE state. - */ - if (jtag_reset_config & RESET_SRST_PULLS_TRST) - jtag_add_reset(1, 1); - else if (!srst_asserted) - jtag_add_reset(0, 1); - jtag_add_sleep(50000); - } - - target->state = TARGET_RESET; - register_cache_invalidate(arm7_9->arm.core_cache); - - /* REVISIT why isn't standard debug entry logic sufficient?? */ - if (target->reset_halt && (!(jtag_reset_config & RESET_SRST_PULLS_TRST) || use_event)) { - /* debug entry was prepared above */ - target->debug_reason = DBG_REASON_DBGRQ; - } - - return ERROR_OK; -} - -/** - * Deassert the reset (SRST) signal on an ARM7/9 target. If SRST pulls TRST - * and the target is being reset into a halt, a warning will be triggered - * because it is not possible to reset into a halted mode in this case. The - * target is halted using the target's functions. - * - * @param target Pointer to the target to have the reset deasserted - * @return ERROR_OK or an error from polling or halting the target - */ -int arm7_9_deassert_reset(struct target *target) -{ - int retval = ERROR_OK; - LOG_DEBUG("target->state: %s", target_state_name(target)); - - /* deassert reset lines */ - jtag_add_reset(0, 0); - - /* In case polling is disabled, we need to examine the - * target and poll here for this target to work correctly. - * - * Otherwise, e.g. halt will fail afterwards with bogus - * error messages as halt will believe that reset is - * still in effect. - */ - retval = target_examine_one(target); - if (retval != ERROR_OK) - return retval; - - retval = target_poll(target); - if (retval != ERROR_OK) - return retval; - - enum reset_types jtag_reset_config = jtag_get_reset_config(); - if (target->reset_halt && (jtag_reset_config & RESET_SRST_PULLS_TRST) != 0) { - LOG_WARNING( - "srst pulls trst - can not reset into halted mode. Issuing halt after reset."); - retval = target_halt(target); - if (retval != ERROR_OK) - return retval; - } - return retval; -} - -/** - * Clears the halt condition for an ARM7/9 target. If it isn't coming out of - * reset and if DBGRQ is used, it is progammed to be deasserted. If the reset - * vector catch was used, it is restored. Otherwise, the control value is - * restored and the watchpoint unit is restored if it was in use. - * - * @param target Pointer to the ARM7/9 target to have halt cleared - * @return Always ERROR_OK - */ -static int arm7_9_clear_halt(struct target *target) -{ - struct arm7_9_common *arm7_9 = target_to_arm7_9(target); - struct reg *dbg_ctrl = &arm7_9->eice_cache->reg_list[EICE_DBG_CTRL]; - - /* we used DBGRQ only if we didn't come out of reset */ - if (!arm7_9->debug_entry_from_reset && arm7_9->use_dbgrq) { - /* program EmbeddedICE Debug Control Register to deassert DBGRQ - */ - buf_set_u32(dbg_ctrl->value, EICE_DBG_CONTROL_DBGRQ, 1, 0); - embeddedice_store_reg(dbg_ctrl); - } else { - if (arm7_9->debug_entry_from_reset && arm7_9->has_vector_catch) { - /* if we came out of reset, and vector catch is supported, we used - * vector catch to enter debug state - * restore the register in that case - */ - embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_VEC_CATCH]); - } else { - /* restore registers if watchpoint unit 0 was in use - */ - if (arm7_9->wp0_used) { - if (arm7_9->debug_entry_from_reset) - embeddedice_store_reg(&arm7_9->eice_cache->reg_list[ - EICE_W0_ADDR_VALUE]); - embeddedice_store_reg(&arm7_9->eice_cache->reg_list[ - EICE_W0_ADDR_MASK]); - embeddedice_store_reg(&arm7_9->eice_cache->reg_list[ - EICE_W0_DATA_MASK]); - embeddedice_store_reg(&arm7_9->eice_cache->reg_list[ - EICE_W0_CONTROL_MASK]); - } - /* control value always has to be restored, as it was either disabled, - * or enabled with possibly different bits - */ - embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_VALUE]); - } - } - - return ERROR_OK; -} - -/** - * Issue a software reset and halt to an ARM7/9 target. The target is halted - * and then there is a wait until the processor shows the halt. This wait can - * timeout and results in an error being returned. The software reset involves - * clearing the halt, updating the debug control register, changing to ARM mode, - * reset of the program counter, and reset of all of the registers. - * - * @param target Pointer to the ARM7/9 target to be reset and halted by software - * @return Error status if any of the commands fail, otherwise ERROR_OK - */ -int arm7_9_soft_reset_halt(struct target *target) -{ - struct arm7_9_common *arm7_9 = target_to_arm7_9(target); - struct arm *arm = &arm7_9->arm; - struct reg *dbg_stat = &arm7_9->eice_cache->reg_list[EICE_DBG_STAT]; - struct reg *dbg_ctrl = &arm7_9->eice_cache->reg_list[EICE_DBG_CTRL]; - int i; - int retval; - - /* FIX!!! replace some of this code with tcl commands - * - * halt # the halt command is synchronous - * armv4_5 core_state arm - * - */ - - retval = target_halt(target); - if (retval != ERROR_OK) - return retval; - - long long then = timeval_ms(); - int timeout; - while (!(timeout = ((timeval_ms()-then) > 1000))) { - if (buf_get_u32(dbg_stat->value, EICE_DBG_STATUS_DBGACK, 1) != 0) - break; - embeddedice_read_reg(dbg_stat); - retval = jtag_execute_queue(); - if (retval != ERROR_OK) - return retval; - if (debug_level >= 3) - alive_sleep(100); - else - keep_alive(); - } - if (timeout) { - LOG_ERROR("Failed to halt CPU after 1 sec"); - return ERROR_TARGET_TIMEOUT; - } - target->state = TARGET_HALTED; - - /* program EmbeddedICE Debug Control Register to assert DBGACK and INTDIS - * ensure that DBGRQ is cleared - */ - buf_set_u32(dbg_ctrl->value, EICE_DBG_CONTROL_DBGACK, 1, 1); - buf_set_u32(dbg_ctrl->value, EICE_DBG_CONTROL_DBGRQ, 1, 0); - buf_set_u32(dbg_ctrl->value, EICE_DBG_CONTROL_INTDIS, 1, 1); - embeddedice_store_reg(dbg_ctrl); - - retval = arm7_9_clear_halt(target); - if (retval != ERROR_OK) - return retval; - - /* if the target is in Thumb state, change to ARM state */ - if (buf_get_u32(dbg_stat->value, EICE_DBG_STATUS_ITBIT, 1)) { - uint32_t r0_thumb, pc_thumb; - LOG_DEBUG("target entered debug from Thumb state, changing to ARM"); - /* Entered debug from Thumb mode */ - arm->core_state = ARM_STATE_THUMB; - arm7_9->change_to_arm(target, &r0_thumb, &pc_thumb); - } - - /* REVISIT likewise for bit 5 -- switch Jazelle-to-ARM */ - - /* all register content is now invalid */ - register_cache_invalidate(arm->core_cache); - - /* SVC, ARM state, IRQ and FIQ disabled */ - uint32_t cpsr; - - cpsr = buf_get_u32(arm->cpsr->value, 0, 32); - cpsr &= ~0xff; - cpsr |= 0xd3; - arm_set_cpsr(arm, cpsr); - arm->cpsr->dirty = 1; - - /* start fetching from 0x0 */ - buf_set_u32(arm->pc->value, 0, 32, 0x0); - arm->pc->dirty = 1; - arm->pc->valid = 1; - - /* reset registers */ - for (i = 0; i <= 14; i++) { - struct reg *r = arm_reg_current(arm, i); - - buf_set_u32(r->value, 0, 32, 0xffffffff); - r->dirty = 1; - r->valid = 1; - } - - retval = target_call_event_callbacks(target, TARGET_EVENT_HALTED); - if (retval != ERROR_OK) - return retval; - - return ERROR_OK; -} - -/** - * Halt an ARM7/9 target. This is accomplished by either asserting the DBGRQ - * line or by programming a watchpoint to trigger on any address. It is - * considered a bug to call this function while the target is in the - * TARGET_RESET state. - * - * @param target Pointer to the ARM7/9 target to be halted - * @return Always ERROR_OK - */ -int arm7_9_halt(struct target *target) -{ - if (target->state == TARGET_RESET) { - LOG_ERROR( - "BUG: arm7/9 does not support halt during reset. This is handled in arm7_9_assert_reset()"); - return ERROR_OK; - } - - struct arm7_9_common *arm7_9 = target_to_arm7_9(target); - struct reg *dbg_ctrl = &arm7_9->eice_cache->reg_list[EICE_DBG_CTRL]; - - LOG_DEBUG("target->state: %s", - target_state_name(target)); - - if (target->state == TARGET_HALTED) { - LOG_DEBUG("target was already halted"); - return ERROR_OK; - } - - if (target->state == TARGET_UNKNOWN) - LOG_WARNING("target was in unknown state when halt was requested"); - - if (arm7_9->use_dbgrq) { - /* program EmbeddedICE Debug Control Register to assert DBGRQ - */ - if (arm7_9->set_special_dbgrq) - arm7_9->set_special_dbgrq(target); - else { - buf_set_u32(dbg_ctrl->value, EICE_DBG_CONTROL_DBGRQ, 1, 1); - embeddedice_store_reg(dbg_ctrl); - } - } else { - /* program watchpoint unit to match on any address - */ - embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_ADDR_MASK], 0xffffffff); - embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_DATA_MASK], 0xffffffff); - embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_VALUE], - EICE_W_CTRL_ENABLE); - embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_MASK], - ~EICE_W_CTRL_nOPC & 0xff); - } - - target->debug_reason = DBG_REASON_DBGRQ; - - return ERROR_OK; -} - -/** - * Handle an ARM7/9 target's entry into debug mode. The halt is cleared on the - * ARM. The JTAG queue is then executed and the reason for debug entry is - * examined. Once done, the target is verified to be halted and the processor - * is forced into ARM mode. The core registers are saved for the current core - * mode and the program counter (register 15) is updated as needed. The core - * registers and CPSR and SPSR are saved for restoration later. - * - * @param target Pointer to target that is entering debug mode - * @return Error code if anything fails, otherwise ERROR_OK - */ -static int arm7_9_debug_entry(struct target *target) -{ - int i; - uint32_t context[16]; - uint32_t *context_p[16]; - uint32_t r0_thumb, pc_thumb; - uint32_t cpsr, cpsr_mask = 0; - int retval; - struct arm7_9_common *arm7_9 = target_to_arm7_9(target); - struct arm *arm = &arm7_9->arm; - struct reg *dbg_stat = &arm7_9->eice_cache->reg_list[EICE_DBG_STAT]; - struct reg *dbg_ctrl = &arm7_9->eice_cache->reg_list[EICE_DBG_CTRL]; - -#ifdef _DEBUG_ARM7_9_ - LOG_DEBUG("-"); -#endif - - /* program EmbeddedICE Debug Control Register to assert DBGACK and INTDIS - * ensure that DBGRQ is cleared - */ - buf_set_u32(dbg_ctrl->value, EICE_DBG_CONTROL_DBGACK, 1, 1); - buf_set_u32(dbg_ctrl->value, EICE_DBG_CONTROL_DBGRQ, 1, 0); - buf_set_u32(dbg_ctrl->value, EICE_DBG_CONTROL_INTDIS, 1, 1); - embeddedice_store_reg(dbg_ctrl); - - retval = arm7_9_clear_halt(target); - if (retval != ERROR_OK) - return retval; - - retval = jtag_execute_queue(); - if (retval != ERROR_OK) - return retval; - - retval = arm7_9->examine_debug_reason(target); - if (retval != ERROR_OK) - return retval; - - if (target->state != TARGET_HALTED) { - LOG_WARNING("target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - /* if the target is in Thumb state, change to ARM state */ - if (buf_get_u32(dbg_stat->value, EICE_DBG_STATUS_ITBIT, 1)) { - LOG_DEBUG("target entered debug from Thumb state"); - /* Entered debug from Thumb mode */ - arm->core_state = ARM_STATE_THUMB; - cpsr_mask = 1 << 5; - arm7_9->change_to_arm(target, &r0_thumb, &pc_thumb); - LOG_DEBUG("r0_thumb: 0x%8.8" PRIx32 - ", pc_thumb: 0x%8.8" PRIx32, r0_thumb, pc_thumb); - } else if (buf_get_u32(dbg_stat->value, 5, 1)) { - /* \todo Get some vaguely correct handling of Jazelle, if - * anyone ever uses it and full info becomes available. - * See ARM9EJS TRM B.7.1 for how to switch J->ARM; and - * B.7.3 for the reverse. That'd be the bare minimum... - */ - LOG_DEBUG("target entered debug from Jazelle state"); - arm->core_state = ARM_STATE_JAZELLE; - cpsr_mask = 1 << 24; - LOG_ERROR("Jazelle debug entry -- BROKEN!"); - } else { - LOG_DEBUG("target entered debug from ARM state"); - /* Entered debug from ARM mode */ - arm->core_state = ARM_STATE_ARM; - } - - for (i = 0; i < 16; i++) - context_p[i] = &context[i]; - /* save core registers (r0 - r15 of current core mode) */ - arm7_9->read_core_regs(target, 0xffff, context_p); - - arm7_9->read_xpsr(target, &cpsr, 0); - - retval = jtag_execute_queue(); - if (retval != ERROR_OK) - return retval; - - /* Sync our CPSR copy with J or T bits EICE reported, but - * which we then erased by putting the core into ARM mode. - */ - arm_set_cpsr(arm, cpsr | cpsr_mask); - - if (!is_arm_mode(arm->core_mode)) { - target->state = TARGET_UNKNOWN; - LOG_ERROR("cpsr contains invalid mode value - communication failure"); - return ERROR_TARGET_FAILURE; - } - - LOG_DEBUG("target entered debug state in %s mode", - arm_mode_name(arm->core_mode)); - - if (arm->core_state == ARM_STATE_THUMB) { - LOG_DEBUG("thumb state, applying fixups"); - context[0] = r0_thumb; - context[15] = pc_thumb; - } else if (arm->core_state == ARM_STATE_ARM) { - /* adjust value stored by STM */ - context[15] -= 3 * 4; - } - - if ((target->debug_reason != DBG_REASON_DBGRQ) || (!arm7_9->use_dbgrq)) - context[15] -= 3 * ((arm->core_state == ARM_STATE_ARM) ? 4 : 2); - else - context[15] -= arm7_9->dbgreq_adjust_pc * - ((arm->core_state == ARM_STATE_ARM) ? 4 : 2); - - for (i = 0; i <= 15; i++) { - struct reg *r = arm_reg_current(arm, i); - - LOG_DEBUG("r%i: 0x%8.8" PRIx32 "", i, context[i]); - - buf_set_u32(r->value, 0, 32, context[i]); - /* r0 and r15 (pc) have to be restored later */ - r->dirty = (i == 0) || (i == 15); - r->valid = 1; - } - - LOG_DEBUG("entered debug state at PC 0x%" PRIx32 "", context[15]); - - /* exceptions other than USR & SYS have a saved program status register */ - if (arm->spsr) { - uint32_t spsr; - arm7_9->read_xpsr(target, &spsr, 1); - retval = jtag_execute_queue(); - if (retval != ERROR_OK) - return retval; - buf_set_u32(arm->spsr->value, 0, 32, spsr); - arm->spsr->dirty = 0; - arm->spsr->valid = 1; - } - - retval = jtag_execute_queue(); - if (retval != ERROR_OK) - return retval; - - if (arm7_9->post_debug_entry) { - retval = arm7_9->post_debug_entry(target); - if (retval != ERROR_OK) - return retval; - } - - return ERROR_OK; -} - -/** - * Validate the full context for an ARM7/9 target in all processor modes. If - * there are any invalid registers for the target, they will all be read. This - * includes the PSR. - * - * @param target Pointer to the ARM7/9 target to capture the full context from - * @return Error if the target is not halted, has an invalid core mode, or if - * the JTAG queue fails to execute - */ -static int arm7_9_full_context(struct target *target) -{ - int i; - int retval; - struct arm7_9_common *arm7_9 = target_to_arm7_9(target); - struct arm *arm = &arm7_9->arm; - - LOG_DEBUG("-"); - - if (target->state != TARGET_HALTED) { - LOG_WARNING("target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - if (!is_arm_mode(arm->core_mode)) { - LOG_ERROR("not a valid arm core mode - communication failure?"); - return ERROR_FAIL; - } - - /* iterate through processor modes (User, FIQ, IRQ, SVC, ABT, UND) - * SYS shares registers with User, so we don't touch SYS - */ - for (i = 0; i < 6; i++) { - uint32_t mask = 0; - uint32_t *reg_p[16]; - int j; - int valid = 1; - - /* check if there are invalid registers in the current mode - */ - for (j = 0; j <= 16; j++) { - if (ARMV4_5_CORE_REG_MODE(arm->core_cache, armv4_5_number_to_mode(i), j).valid == 0) - valid = 0; - } - - if (!valid) { - uint32_t tmp_cpsr; - - /* change processor mode (and mask T bit) */ - tmp_cpsr = buf_get_u32(arm->cpsr->value, 0, 8) - & 0xe0; - tmp_cpsr |= armv4_5_number_to_mode(i); - tmp_cpsr &= ~0x20; - arm7_9->write_xpsr_im8(target, tmp_cpsr & 0xff, 0, 0); - - for (j = 0; j < 15; j++) { - if (ARMV4_5_CORE_REG_MODE(arm->core_cache, - armv4_5_number_to_mode(i), j).valid == 0) { - reg_p[j] = (uint32_t *)ARMV4_5_CORE_REG_MODE( - arm->core_cache, - armv4_5_number_to_mode(i), - j).value; - mask |= 1 << j; - ARMV4_5_CORE_REG_MODE(arm->core_cache, - armv4_5_number_to_mode(i), - j).valid = 1; - ARMV4_5_CORE_REG_MODE(arm->core_cache, - armv4_5_number_to_mode(i), - j).dirty = 0; - } - } - - /* if only the PSR is invalid, mask is all zeroes */ - if (mask) - arm7_9->read_core_regs(target, mask, reg_p); - - /* check if the PSR has to be read */ - if (ARMV4_5_CORE_REG_MODE(arm->core_cache, armv4_5_number_to_mode(i), - 16).valid == 0) { - arm7_9->read_xpsr(target, - (uint32_t *)ARMV4_5_CORE_REG_MODE(arm->core_cache, - armv4_5_number_to_mode(i), 16).value, 1); - ARMV4_5_CORE_REG_MODE(arm->core_cache, armv4_5_number_to_mode(i), - 16).valid = 1; - ARMV4_5_CORE_REG_MODE(arm->core_cache, armv4_5_number_to_mode(i), - 16).dirty = 0; - } - } - } - - /* restore processor mode (mask T bit) */ - arm7_9->write_xpsr_im8(target, - buf_get_u32(arm->cpsr->value, 0, 8) & ~0x20, 0, 0); - - retval = jtag_execute_queue(); - if (retval != ERROR_OK) - return retval; - return ERROR_OK; -} - -/** - * Restore the processor context on an ARM7/9 target. The full processor - * context is analyzed to see if any of the registers are dirty on this end, but - * have a valid new value. If this is the case, the processor is changed to the - * appropriate mode and the new register values are written out to the - * processor. If there happens to be a dirty register with an invalid value, an - * error will be logged. - * - * @param target Pointer to the ARM7/9 target to have its context restored - * @return Error status if the target is not halted or the core mode in the - * armv4_5 struct is invalid. - */ -static int arm7_9_restore_context(struct target *target) -{ - struct arm7_9_common *arm7_9 = target_to_arm7_9(target); - struct arm *arm = &arm7_9->arm; - struct reg *reg; - enum arm_mode current_mode = arm->core_mode; - int i, j; - int dirty; - int mode_change; - - LOG_DEBUG("-"); - - if (target->state != TARGET_HALTED) { - LOG_WARNING("target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - if (arm7_9->pre_restore_context) - arm7_9->pre_restore_context(target); - - if (!is_arm_mode(arm->core_mode)) { - LOG_ERROR("not a valid arm core mode - communication failure?"); - return ERROR_FAIL; - } - - /* iterate through processor modes (User, FIQ, IRQ, SVC, ABT, UND) - * SYS shares registers with User, so we don't touch SYS - */ - for (i = 0; i < 6; i++) { - LOG_DEBUG("examining %s mode", - arm_mode_name(arm->core_mode)); - dirty = 0; - mode_change = 0; - /* check if there are dirty registers in the current mode - */ - for (j = 0; j <= 16; j++) { - reg = &ARMV4_5_CORE_REG_MODE(arm->core_cache, armv4_5_number_to_mode(i), j); - if (reg->dirty == 1) { - if (reg->valid == 1) { - dirty = 1; - LOG_DEBUG("examining dirty reg: %s", reg->name); - struct arm_reg *reg_arch_info; - reg_arch_info = reg->arch_info; - if ((reg_arch_info->mode != ARM_MODE_ANY) - && (reg_arch_info->mode != current_mode) - && !((reg_arch_info->mode == ARM_MODE_USR) - && (arm->core_mode == ARM_MODE_SYS)) - && !((reg_arch_info->mode == ARM_MODE_SYS) - && (arm->core_mode == ARM_MODE_USR))) { - mode_change = 1; - LOG_DEBUG("require mode change"); - } - } else - LOG_ERROR("BUG: dirty register '%s', but no valid data", - reg->name); - } - } - - if (dirty) { - uint32_t mask = 0x0; - int num_regs = 0; - uint32_t regs[16]; - - if (mode_change) { - uint32_t tmp_cpsr; - - /* change processor mode (mask T bit) */ - tmp_cpsr = buf_get_u32(arm->cpsr->value, - 0, 8) & 0xe0; - tmp_cpsr |= armv4_5_number_to_mode(i); - tmp_cpsr &= ~0x20; - arm7_9->write_xpsr_im8(target, tmp_cpsr & 0xff, 0, 0); - current_mode = armv4_5_number_to_mode(i); - } - - for (j = 0; j <= 14; j++) { - reg = &ARMV4_5_CORE_REG_MODE(arm->core_cache, - armv4_5_number_to_mode(i), - j); - - if (reg->dirty == 1) { - regs[j] = buf_get_u32(reg->value, 0, 32); - mask |= 1 << j; - num_regs++; - reg->dirty = 0; - reg->valid = 1; - LOG_DEBUG("writing register %i mode %s " - "with value 0x%8.8" PRIx32, j, - arm_mode_name(arm->core_mode), - regs[j]); - } - } - - if (mask) - arm7_9->write_core_regs(target, mask, regs); - - reg = - &ARMV4_5_CORE_REG_MODE(arm->core_cache, armv4_5_number_to_mode( - i), 16); - struct arm_reg *reg_arch_info; - reg_arch_info = reg->arch_info; - if ((reg->dirty) && (reg_arch_info->mode != ARM_MODE_ANY)) { - LOG_DEBUG("writing SPSR of mode %i with value 0x%8.8" PRIx32 "", - i, - buf_get_u32(reg->value, 0, 32)); - arm7_9->write_xpsr(target, buf_get_u32(reg->value, 0, 32), 1); - } - } - } - - if (!arm->cpsr->dirty && (arm->core_mode != current_mode)) { - /* restore processor mode (mask T bit) */ - uint32_t tmp_cpsr; - - tmp_cpsr = buf_get_u32(arm->cpsr->value, 0, 8) & 0xE0; - tmp_cpsr |= armv4_5_number_to_mode(i); - tmp_cpsr &= ~0x20; - LOG_DEBUG("writing lower 8 bit of cpsr with value 0x%2.2x", (unsigned)(tmp_cpsr)); - arm7_9->write_xpsr_im8(target, tmp_cpsr & 0xff, 0, 0); - - } else if (arm->cpsr->dirty) { - /* CPSR has been changed, full restore necessary (mask T bit) */ - LOG_DEBUG("writing cpsr with value 0x%8.8" PRIx32, - buf_get_u32(arm->cpsr->value, 0, 32)); - arm7_9->write_xpsr(target, - buf_get_u32(arm->cpsr->value, 0, 32) - & ~0x20, 0); - arm->cpsr->dirty = 0; - arm->cpsr->valid = 1; - } - - /* restore PC */ - LOG_DEBUG("writing PC with value 0x%8.8" PRIx32, - buf_get_u32(arm->pc->value, 0, 32)); - arm7_9->write_pc(target, buf_get_u32(arm->pc->value, 0, 32)); - arm->pc->dirty = 0; - - return ERROR_OK; -} - -/** - * Restart the core of an ARM7/9 target. A RESTART command is sent to the - * instruction register and the JTAG state is set to TAP_IDLE causing a core - * restart. - * - * @param target Pointer to the ARM7/9 target to be restarted - * @return Result of executing the JTAG queue - */ -static int arm7_9_restart_core(struct target *target) -{ - struct arm7_9_common *arm7_9 = target_to_arm7_9(target); - struct arm_jtag *jtag_info = &arm7_9->jtag_info; - int retval; - - /* set RESTART instruction */ - if (arm7_9->need_bypass_before_restart) { - arm7_9->need_bypass_before_restart = 0; - - retval = arm_jtag_set_instr(jtag_info->tap, 0xf, NULL, TAP_IDLE); - if (retval != ERROR_OK) - return retval; - } - retval = arm_jtag_set_instr(jtag_info->tap, 0x4, NULL, TAP_IDLE); - if (retval != ERROR_OK) - return retval; - - jtag_add_runtest(1, TAP_IDLE); - return jtag_execute_queue(); -} - -/** - * Enable the watchpoints on an ARM7/9 target. The target's watchpoints are - * iterated through and are set on the target if they aren't already set. - * - * @param target Pointer to the ARM7/9 target to enable watchpoints on - */ -static void arm7_9_enable_watchpoints(struct target *target) -{ - struct watchpoint *watchpoint = target->watchpoints; - - while (watchpoint) { - if (watchpoint->set == 0) - arm7_9_set_watchpoint(target, watchpoint); - watchpoint = watchpoint->next; - } -} - -/** - * Enable the breakpoints on an ARM7/9 target. The target's breakpoints are - * iterated through and are set on the target. - * - * @param target Pointer to the ARM7/9 target to enable breakpoints on - */ -static void arm7_9_enable_breakpoints(struct target *target) -{ - struct breakpoint *breakpoint = target->breakpoints; - - /* set any pending breakpoints */ - while (breakpoint) { - arm7_9_set_breakpoint(target, breakpoint); - breakpoint = breakpoint->next; - } -} - -int arm7_9_resume(struct target *target, - int current, - uint32_t address, - int handle_breakpoints, - int debug_execution) -{ - struct arm7_9_common *arm7_9 = target_to_arm7_9(target); - struct arm *arm = &arm7_9->arm; - struct reg *dbg_ctrl = &arm7_9->eice_cache->reg_list[EICE_DBG_CTRL]; - int err, retval = ERROR_OK; - - LOG_DEBUG("-"); - - if (target->state != TARGET_HALTED) { - LOG_WARNING("target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - if (!debug_execution) - target_free_all_working_areas(target); - - /* current = 1: continue on current pc, otherwise continue at

*/ - if (!current) - buf_set_u32(arm->pc->value, 0, 32, address); - - uint32_t current_pc; - current_pc = buf_get_u32(arm->pc->value, 0, 32); - - /* the front-end may request us not to handle breakpoints */ - if (handle_breakpoints) { - struct breakpoint *breakpoint; - 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, - breakpoint->address, - breakpoint->unique_id); - retval = arm7_9_unset_breakpoint(target, breakpoint); - if (retval != ERROR_OK) - return retval; - - /* calculate PC of next instruction */ - uint32_t next_pc; - retval = arm_simulate_step(target, &next_pc); - if (retval != ERROR_OK) { - uint32_t current_opcode; - target_read_u32(target, current_pc, ¤t_opcode); - LOG_ERROR( - "Couldn't calculate PC of next instruction, current opcode was 0x%8.8" PRIx32 "", - current_opcode); - return retval; - } - - LOG_DEBUG("enable single-step"); - arm7_9->enable_single_step(target, next_pc); - - target->debug_reason = DBG_REASON_SINGLESTEP; - - retval = arm7_9_restore_context(target); - if (retval != ERROR_OK) - return retval; - - if (arm->core_state == ARM_STATE_ARM) - arm7_9->branch_resume(target); - else if (arm->core_state == ARM_STATE_THUMB) - arm7_9->branch_resume_thumb(target); - else { - LOG_ERROR("unhandled core state"); - return ERROR_FAIL; - } - - buf_set_u32(dbg_ctrl->value, EICE_DBG_CONTROL_DBGACK, 1, 0); - embeddedice_write_reg(dbg_ctrl, - buf_get_u32(dbg_ctrl->value, 0, dbg_ctrl->size)); - err = arm7_9_execute_sys_speed(target); - - LOG_DEBUG("disable single-step"); - arm7_9->disable_single_step(target); - - if (err != ERROR_OK) { - retval = arm7_9_set_breakpoint(target, breakpoint); - if (retval != ERROR_OK) - return retval; - target->state = TARGET_UNKNOWN; - return err; - } - - retval = arm7_9_debug_entry(target); - if (retval != ERROR_OK) - return retval; - 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); - retval = arm7_9_set_breakpoint(target, breakpoint); - if (retval != ERROR_OK) - return retval; - } - } - - /* enable any pending breakpoints and watchpoints */ - arm7_9_enable_breakpoints(target); - arm7_9_enable_watchpoints(target); - - retval = arm7_9_restore_context(target); - if (retval != ERROR_OK) - return retval; - - if (arm->core_state == ARM_STATE_ARM) - arm7_9->branch_resume(target); - else if (arm->core_state == ARM_STATE_THUMB) - arm7_9->branch_resume_thumb(target); - else { - LOG_ERROR("unhandled core state"); - return ERROR_FAIL; - } - - /* deassert DBGACK and INTDIS */ - buf_set_u32(dbg_ctrl->value, EICE_DBG_CONTROL_DBGACK, 1, 0); - /* INTDIS only when we really resume, not during debug execution */ - if (!debug_execution) - buf_set_u32(dbg_ctrl->value, EICE_DBG_CONTROL_INTDIS, 1, 0); - embeddedice_write_reg(dbg_ctrl, buf_get_u32(dbg_ctrl->value, 0, dbg_ctrl->size)); - - retval = arm7_9_restart_core(target); - if (retval != ERROR_OK) - return retval; - - target->debug_reason = DBG_REASON_NOTHALTED; - - if (!debug_execution) { - /* registers are now invalid */ - register_cache_invalidate(arm->core_cache); - target->state = TARGET_RUNNING; - retval = target_call_event_callbacks(target, TARGET_EVENT_RESUMED); - if (retval != ERROR_OK) - return retval; - } else { - target->state = TARGET_DEBUG_RUNNING; - retval = target_call_event_callbacks(target, TARGET_EVENT_DEBUG_RESUMED); - if (retval != ERROR_OK) - return retval; - } - - LOG_DEBUG("target resumed"); - - return ERROR_OK; -} - -void arm7_9_enable_eice_step(struct target *target, uint32_t next_pc) -{ - struct arm7_9_common *arm7_9 = target_to_arm7_9(target); - struct arm *arm = &arm7_9->arm; - uint32_t current_pc; - current_pc = buf_get_u32(arm->pc->value, 0, 32); - - if (next_pc != current_pc) { - /* setup an inverse breakpoint on the current PC - * - comparator 1 matches the current address - * - rangeout from comparator 1 is connected to comparator 0 rangein - * - comparator 0 matches any address, as long as rangein is low */ - embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_ADDR_MASK], 0xffffffff); - embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_DATA_MASK], 0xffffffff); - embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_VALUE], - EICE_W_CTRL_ENABLE); - embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_MASK], - ~(EICE_W_CTRL_RANGE | EICE_W_CTRL_nOPC) & 0xff); - embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W1_ADDR_VALUE], - current_pc); - embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W1_ADDR_MASK], 0); - embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W1_DATA_MASK], 0xffffffff); - embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W1_CONTROL_VALUE], 0x0); - embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W1_CONTROL_MASK], - ~EICE_W_CTRL_nOPC & 0xff); - } else { - embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_ADDR_MASK], 0xffffffff); - embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_DATA_MASK], 0xffffffff); - embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_VALUE], 0x0); - embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_MASK], 0xff); - embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W1_ADDR_VALUE], next_pc); - embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W1_ADDR_MASK], 0); - embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W1_DATA_MASK], 0xffffffff); - embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W1_CONTROL_VALUE], - EICE_W_CTRL_ENABLE); - embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W1_CONTROL_MASK], - ~EICE_W_CTRL_nOPC & 0xff); - } -} - -void arm7_9_disable_eice_step(struct target *target) -{ - struct arm7_9_common *arm7_9 = target_to_arm7_9(target); - - embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_W0_ADDR_MASK]); - embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_W0_DATA_MASK]); - embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_VALUE]); - embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_MASK]); - embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_W1_ADDR_VALUE]); - embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_W1_ADDR_MASK]); - embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_W1_DATA_MASK]); - embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_W1_CONTROL_MASK]); - 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) -{ - struct arm7_9_common *arm7_9 = target_to_arm7_9(target); - struct arm *arm = &arm7_9->arm; - struct breakpoint *breakpoint = NULL; - int err, retval; - - if (target->state != TARGET_HALTED) { - LOG_WARNING("target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - /* current = 1: continue on current pc, otherwise continue at
*/ - if (!current) - buf_set_u32(arm->pc->value, 0, 32, address); - - uint32_t current_pc = buf_get_u32(arm->pc->value, 0, 32); - - /* the front-end may request us not to handle breakpoints */ - if (handle_breakpoints) - breakpoint = breakpoint_find(target, current_pc); - if (breakpoint != NULL) { - retval = arm7_9_unset_breakpoint(target, breakpoint); - if (retval != ERROR_OK) - return retval; - } - - target->debug_reason = DBG_REASON_SINGLESTEP; - - /* calculate PC of next instruction */ - uint32_t next_pc; - retval = arm_simulate_step(target, &next_pc); - if (retval != ERROR_OK) { - uint32_t current_opcode; - target_read_u32(target, current_pc, ¤t_opcode); - LOG_ERROR( - "Couldn't calculate PC of next instruction, current opcode was 0x%8.8" PRIx32 "", - current_opcode); - return retval; - } - - retval = arm7_9_restore_context(target); - if (retval != ERROR_OK) - return retval; - - arm7_9->enable_single_step(target, next_pc); - - if (arm->core_state == ARM_STATE_ARM) - arm7_9->branch_resume(target); - else if (arm->core_state == ARM_STATE_THUMB) - arm7_9->branch_resume_thumb(target); - else { - LOG_ERROR("unhandled core state"); - return ERROR_FAIL; - } - - retval = target_call_event_callbacks(target, TARGET_EVENT_RESUMED); - if (retval != ERROR_OK) - return retval; - - err = arm7_9_execute_sys_speed(target); - arm7_9->disable_single_step(target); - - /* registers are now invalid */ - register_cache_invalidate(arm->core_cache); - - if (err != ERROR_OK) - target->state = TARGET_UNKNOWN; - else { - retval = arm7_9_debug_entry(target); - if (retval != ERROR_OK) - return retval; - retval = target_call_event_callbacks(target, TARGET_EVENT_HALTED); - if (retval != ERROR_OK) - return retval; - LOG_DEBUG("target stepped"); - } - - if (breakpoint) { - retval = arm7_9_set_breakpoint(target, breakpoint); - if (retval != ERROR_OK) - return retval; - } - - return err; -} - -static int arm7_9_read_core_reg(struct target *target, struct reg *r, - int num, enum arm_mode mode) -{ - uint32_t *reg_p[16]; - int retval; - struct arm_reg *areg = r->arch_info; - struct arm7_9_common *arm7_9 = target_to_arm7_9(target); - struct arm *arm = &arm7_9->arm; - - if (!is_arm_mode(arm->core_mode)) - return ERROR_FAIL; - if ((num < 0) || (num > 16)) - return ERROR_COMMAND_SYNTAX_ERROR; - - if ((mode != ARM_MODE_ANY) && (mode != arm->core_mode) - && (areg->mode != ARM_MODE_ANY)) { - uint32_t tmp_cpsr; - - /* change processor mode (mask T bit) */ - tmp_cpsr = buf_get_u32(arm->cpsr->value, 0, 8) & 0xE0; - tmp_cpsr |= mode; - tmp_cpsr &= ~0x20; - arm7_9->write_xpsr_im8(target, tmp_cpsr & 0xff, 0, 0); - } - - uint32_t value = 0; - if ((num >= 0) && (num <= 15)) { - /* read a normal core register */ - reg_p[num] = &value; - - arm7_9->read_core_regs(target, 1 << num, reg_p); - } else { - /* read a program status register - * if the register mode is MODE_ANY, we read the cpsr, otherwise a spsr - */ - arm7_9->read_xpsr(target, &value, areg->mode != ARM_MODE_ANY); - } - - retval = jtag_execute_queue(); - if (retval != ERROR_OK) - return retval; - - r->valid = 1; - r->dirty = 0; - buf_set_u32(r->value, 0, 32, value); - - if ((mode != ARM_MODE_ANY) && (mode != arm->core_mode) - && (areg->mode != ARM_MODE_ANY)) { - /* restore processor mode (mask T bit) */ - arm7_9->write_xpsr_im8(target, - buf_get_u32(arm->cpsr->value, 0, 8) & ~0x20, 0, 0); - } - - return ERROR_OK; -} - -static int arm7_9_write_core_reg(struct target *target, struct reg *r, - int num, enum arm_mode mode, uint8_t *value) -{ - uint32_t reg[16]; - struct arm_reg *areg = r->arch_info; - struct arm7_9_common *arm7_9 = target_to_arm7_9(target); - struct arm *arm = &arm7_9->arm; - - if (!is_arm_mode(arm->core_mode)) - return ERROR_FAIL; - if ((num < 0) || (num > 16)) - return ERROR_COMMAND_SYNTAX_ERROR; - - if ((mode != ARM_MODE_ANY) && (mode != arm->core_mode) - && (areg->mode != ARM_MODE_ANY)) { - uint32_t tmp_cpsr; - - /* change processor mode (mask T bit) */ - tmp_cpsr = buf_get_u32(arm->cpsr->value, 0, 8) & 0xE0; - tmp_cpsr |= mode; - tmp_cpsr &= ~0x20; - arm7_9->write_xpsr_im8(target, tmp_cpsr & 0xff, 0, 0); - } - - if ((num >= 0) && (num <= 15)) { - /* write a normal core register */ - reg[num] = buf_get_u32(value, 0, 32); - - arm7_9->write_core_regs(target, 1 << num, reg); - } else { - /* write a program status register - * if the register mode is MODE_ANY, we write the cpsr, otherwise a spsr - */ - int spsr = (areg->mode != ARM_MODE_ANY); - - uint32_t t = buf_get_u32(value, 0, 32); - /* if we're writing the CPSR, mask the T bit */ - if (!spsr) - t &= ~0x20; - - arm7_9->write_xpsr(target, t, spsr); - } - - r->valid = 1; - r->dirty = 0; - - if ((mode != ARM_MODE_ANY) && (mode != arm->core_mode) - && (areg->mode != ARM_MODE_ANY)) { - /* restore processor mode (mask T bit) */ - arm7_9->write_xpsr_im8(target, - buf_get_u32(arm->cpsr->value, 0, 8) & ~0x20, 0, 0); - } - - return jtag_execute_queue(); -} - -int arm7_9_read_memory(struct target *target, - uint32_t address, - uint32_t size, - uint32_t count, - uint8_t *buffer) -{ - struct arm7_9_common *arm7_9 = target_to_arm7_9(target); - struct arm *arm = &arm7_9->arm; - uint32_t reg[16]; - uint32_t num_accesses = 0; - int thisrun_accesses; - int i; - uint32_t cpsr; - int retval; - int last_reg = 0; - - LOG_DEBUG("address: 0x%8.8" PRIx32 ", size: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32 "", - address, size, count); - - if (target->state != TARGET_HALTED) { - LOG_WARNING("target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - /* sanitize arguments */ - if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer)) - return ERROR_COMMAND_SYNTAX_ERROR; - - if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u))) - return ERROR_TARGET_UNALIGNED_ACCESS; - - /* load the base register with the address of the first word */ - reg[0] = address; - arm7_9->write_core_regs(target, 0x1, reg); - - int j = 0; - - switch (size) { - case 4: - while (num_accesses < count) { - uint32_t reg_list; - thisrun_accesses = - ((count - num_accesses) >= 14) ? 14 : (count - num_accesses); - reg_list = (0xffff >> (15 - thisrun_accesses)) & 0xfffe; - - if (last_reg <= thisrun_accesses) - last_reg = thisrun_accesses; - - arm7_9->load_word_regs(target, reg_list); - - /* fast memory reads are only safe when the target is running - * from a sufficiently high clock (32 kHz is usually too slow) - */ - if (arm7_9->fast_memory_access) - retval = arm7_9_execute_fast_sys_speed(target); - else - retval = arm7_9_execute_sys_speed(target); - if (retval != ERROR_OK) - return retval; - - arm7_9->read_core_regs_target_buffer(target, reg_list, buffer, 4); - - /* advance buffer, count number of accesses */ - buffer += thisrun_accesses * 4; - num_accesses += thisrun_accesses; - - if ((j++%1024) == 0) - keep_alive(); - } - break; - case 2: - while (num_accesses < count) { - uint32_t reg_list; - thisrun_accesses = - ((count - num_accesses) >= 14) ? 14 : (count - num_accesses); - reg_list = (0xffff >> (15 - thisrun_accesses)) & 0xfffe; - - for (i = 1; i <= thisrun_accesses; i++) { - if (i > last_reg) - last_reg = i; - arm7_9->load_hword_reg(target, i); - /* fast memory reads are only safe when the target is running - * from a sufficiently high clock (32 kHz is usually too slow) - */ - if (arm7_9->fast_memory_access) - retval = arm7_9_execute_fast_sys_speed(target); - else - retval = arm7_9_execute_sys_speed(target); - if (retval != ERROR_OK) - return retval; - - } - - arm7_9->read_core_regs_target_buffer(target, reg_list, buffer, 2); - - /* advance buffer, count number of accesses */ - buffer += thisrun_accesses * 2; - num_accesses += thisrun_accesses; - - if ((j++%1024) == 0) - keep_alive(); - } - break; - case 1: - while (num_accesses < count) { - uint32_t reg_list; - thisrun_accesses = - ((count - num_accesses) >= 14) ? 14 : (count - num_accesses); - reg_list = (0xffff >> (15 - thisrun_accesses)) & 0xfffe; - - for (i = 1; i <= thisrun_accesses; i++) { - if (i > last_reg) - last_reg = i; - arm7_9->load_byte_reg(target, i); - /* fast memory reads are only safe when the target is running - * from a sufficiently high clock (32 kHz is usually too slow) - */ - if (arm7_9->fast_memory_access) - retval = arm7_9_execute_fast_sys_speed(target); - else - retval = arm7_9_execute_sys_speed(target); - if (retval != ERROR_OK) - return retval; - } - - arm7_9->read_core_regs_target_buffer(target, reg_list, buffer, 1); - - /* advance buffer, count number of accesses */ - buffer += thisrun_accesses * 1; - num_accesses += thisrun_accesses; - - if ((j++%1024) == 0) - keep_alive(); - } - break; - } - - if (!is_arm_mode(arm->core_mode)) - return ERROR_FAIL; - - for (i = 0; i <= last_reg; i++) { - struct reg *r = arm_reg_current(arm, i); - r->dirty = r->valid; - } - - arm7_9->read_xpsr(target, &cpsr, 0); - retval = jtag_execute_queue(); - if (retval != ERROR_OK) { - LOG_ERROR("JTAG error while reading cpsr"); - return ERROR_TARGET_DATA_ABORT; - } - - 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 ")", - address, - size, - count); - - arm7_9->write_xpsr_im8(target, - buf_get_u32(arm->cpsr->value, 0, 8) - & ~0x20, 0, 0); - - return ERROR_TARGET_DATA_ABORT; - } - - return ERROR_OK; -} - -int arm7_9_write_memory(struct target *target, - uint32_t address, - uint32_t size, - uint32_t count, - const uint8_t *buffer) -{ - struct arm7_9_common *arm7_9 = target_to_arm7_9(target); - struct arm *arm = &arm7_9->arm; - struct reg *dbg_ctrl = &arm7_9->eice_cache->reg_list[EICE_DBG_CTRL]; - - uint32_t reg[16]; - uint32_t num_accesses = 0; - int thisrun_accesses; - int i; - uint32_t cpsr; - int retval; - int last_reg = 0; - -#ifdef _DEBUG_ARM7_9_ - LOG_DEBUG("address: 0x%8.8x, size: 0x%8.8x, count: 0x%8.8x", address, size, count); -#endif - - if (target->state != TARGET_HALTED) { - LOG_WARNING("target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - /* sanitize arguments */ - if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer)) - return ERROR_COMMAND_SYNTAX_ERROR; - - if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u))) - return ERROR_TARGET_UNALIGNED_ACCESS; - - /* load the base register with the address of the first word */ - reg[0] = address; - arm7_9->write_core_regs(target, 0x1, reg); - - /* Clear DBGACK, to make sure memory fetches work as expected */ - buf_set_u32(dbg_ctrl->value, EICE_DBG_CONTROL_DBGACK, 1, 0); - embeddedice_store_reg(dbg_ctrl); - - switch (size) { - case 4: - while (num_accesses < count) { - uint32_t reg_list; - thisrun_accesses = - ((count - num_accesses) >= 14) ? 14 : (count - num_accesses); - reg_list = (0xffff >> (15 - thisrun_accesses)) & 0xfffe; - - for (i = 1; i <= thisrun_accesses; i++) { - if (i > last_reg) - last_reg = i; - reg[i] = target_buffer_get_u32(target, buffer); - buffer += 4; - } - - arm7_9->write_core_regs(target, reg_list, reg); - - arm7_9->store_word_regs(target, reg_list); - - /* fast memory writes are only safe when the target is running - * from a sufficiently high clock (32 kHz is usually too slow) - */ - if (arm7_9->fast_memory_access) - retval = arm7_9_execute_fast_sys_speed(target); - else { - retval = arm7_9_execute_sys_speed(target); - - /* - * if memory writes are made when the clock is running slow - * (i.e. 32 kHz) which is necessary in some scripts to reconfigure - * processor operations after a "reset halt" or "reset init", - * need to immediately stroke the keep alive or will end up with - * gdb "keep alive not sent error message" problem. - */ - - keep_alive(); - } - - if (retval != ERROR_OK) - return retval; - - num_accesses += thisrun_accesses; - } - break; - case 2: - while (num_accesses < count) { - uint32_t reg_list; - thisrun_accesses = - ((count - num_accesses) >= 14) ? 14 : (count - num_accesses); - reg_list = (0xffff >> (15 - thisrun_accesses)) & 0xfffe; - - for (i = 1; i <= thisrun_accesses; i++) { - if (i > last_reg) - last_reg = i; - reg[i] = target_buffer_get_u16(target, buffer) & 0xffff; - buffer += 2; - } - - arm7_9->write_core_regs(target, reg_list, reg); - - for (i = 1; i <= thisrun_accesses; i++) { - arm7_9->store_hword_reg(target, i); - - /* fast memory writes are only safe when the target is running - * from a sufficiently high clock (32 kHz is usually too slow) - */ - if (arm7_9->fast_memory_access) - retval = arm7_9_execute_fast_sys_speed(target); - else { - retval = arm7_9_execute_sys_speed(target); - - /* - * if memory writes are made when the clock is running slow - * (i.e. 32 kHz) which is necessary in some scripts to reconfigure - * processor operations after a "reset halt" or "reset init", - * need to immediately stroke the keep alive or will end up with - * gdb "keep alive not sent error message" problem. - */ - - keep_alive(); - } - - if (retval != ERROR_OK) - return retval; - } - - num_accesses += thisrun_accesses; - } - break; - case 1: - while (num_accesses < count) { - uint32_t reg_list; - thisrun_accesses = - ((count - num_accesses) >= 14) ? 14 : (count - num_accesses); - reg_list = (0xffff >> (15 - thisrun_accesses)) & 0xfffe; - - for (i = 1; i <= thisrun_accesses; i++) { - if (i > last_reg) - last_reg = i; - reg[i] = *buffer++ & 0xff; - } - - arm7_9->write_core_regs(target, reg_list, reg); - - for (i = 1; i <= thisrun_accesses; i++) { - arm7_9->store_byte_reg(target, i); - /* fast memory writes are only safe when the target is running - * from a sufficiently high clock (32 kHz is usually too slow) - */ - if (arm7_9->fast_memory_access) - retval = arm7_9_execute_fast_sys_speed(target); - else { - retval = arm7_9_execute_sys_speed(target); - - /* - * if memory writes are made when the clock is running slow - * (i.e. 32 kHz) which is necessary in some scripts to reconfigure - * processor operations after a "reset halt" or "reset init", - * need to immediately stroke the keep alive or will end up with - * gdb "keep alive not sent error message" problem. - */ - - keep_alive(); - } - - if (retval != ERROR_OK) - return retval; - - } - - num_accesses += thisrun_accesses; - } - break; - } - - /* Re-Set DBGACK */ - buf_set_u32(dbg_ctrl->value, EICE_DBG_CONTROL_DBGACK, 1, 1); - embeddedice_store_reg(dbg_ctrl); - - if (!is_arm_mode(arm->core_mode)) - return ERROR_FAIL; - - for (i = 0; i <= last_reg; i++) { - struct reg *r = arm_reg_current(arm, i); - r->dirty = r->valid; - } - - arm7_9->read_xpsr(target, &cpsr, 0); - retval = jtag_execute_queue(); - if (retval != ERROR_OK) { - LOG_ERROR("JTAG error while reading cpsr"); - return ERROR_TARGET_DATA_ABORT; - } - - 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 ")", - address, - size, - count); - - arm7_9->write_xpsr_im8(target, - buf_get_u32(arm->cpsr->value, 0, 8) - & ~0x20, 0, 0); - - return ERROR_TARGET_DATA_ABORT; - } - - return ERROR_OK; -} - -int arm7_9_write_memory_opt(struct target *target, - uint32_t address, - uint32_t size, - uint32_t count, - const uint8_t *buffer) -{ - struct arm7_9_common *arm7_9 = target_to_arm7_9(target); - int retval; - - if (size == 4 && count > 32 && arm7_9->bulk_write_memory) { - /* Attempt to do a bulk write */ - retval = arm7_9->bulk_write_memory(target, address, count, buffer); - - if (retval == ERROR_OK) - return ERROR_OK; - } - - return arm7_9->write_memory(target, address, size, count, buffer); -} - -int arm7_9_write_memory_no_opt(struct target *target, - uint32_t address, - uint32_t size, - uint32_t count, - const uint8_t *buffer) -{ - struct arm7_9_common *arm7_9 = target_to_arm7_9(target); - - return arm7_9->write_memory(target, address, size, count, buffer); -} - -static int dcc_count; -static const uint8_t *dcc_buffer; - -static int arm7_9_dcc_completion(struct target *target, - uint32_t exit_point, - int timeout_ms, - void *arch_info) -{ - int retval = ERROR_OK; - struct arm7_9_common *arm7_9 = target_to_arm7_9(target); - - retval = target_wait_state(target, TARGET_DEBUG_RUNNING, 500); - if (retval != ERROR_OK) - return retval; - - int little = target->endianness == TARGET_LITTLE_ENDIAN; - int count = dcc_count; - const uint8_t *buffer = dcc_buffer; - if (count > 2) { - /* Handle first & last using standard embeddedice_write_reg and the middle ones w/the - * core function repeated. */ - embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_COMMS_DATA], - fast_target_buffer_get_u32(buffer, little)); - buffer += 4; - - struct embeddedice_reg *ice_reg = - arm7_9->eice_cache->reg_list[EICE_COMMS_DATA].arch_info; - uint8_t reg_addr = ice_reg->addr & 0x1f; - struct jtag_tap *tap; - tap = ice_reg->jtag_info->tap; - - embeddedice_write_dcc(tap, reg_addr, buffer, little, count-2); - buffer += (count-2)*4; - - embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_COMMS_DATA], - fast_target_buffer_get_u32(buffer, little)); - } else { - int i; - for (i = 0; i < count; i++) { - embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_COMMS_DATA], - fast_target_buffer_get_u32(buffer, little)); - buffer += 4; - } - } - - retval = target_halt(target); - if (retval != ERROR_OK) - return retval; - return target_wait_state(target, TARGET_HALTED, 500); -} - -static const uint32_t dcc_code[] = { - /* r0 == input, points to memory buffer - * r1 == scratch - */ - - /* spin until DCC control (c0) reports data arrived */ - 0xee101e10, /* w: mrc p14, #0, r1, c0, c0 */ - 0xe3110001, /* tst r1, #1 */ - 0x0afffffc, /* bne w */ - - /* read word from DCC (c1), write to memory */ - 0xee111e10, /* mrc p14, #0, r1, c1, c0 */ - 0xe4801004, /* str r1, [r0], #4 */ - - /* repeat */ - 0xeafffff9 /* b w */ -}; - -int arm7_9_bulk_write_memory(struct target *target, - uint32_t address, - uint32_t count, - const uint8_t *buffer) -{ - int retval; - struct arm7_9_common *arm7_9 = target_to_arm7_9(target); - - if (address % 4 != 0) - return ERROR_TARGET_UNALIGNED_ACCESS; - - if (!arm7_9->dcc_downloads) - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - - /* regrab previously allocated working_area, or allocate a new one */ - if (!arm7_9->dcc_working_area) { - uint8_t dcc_code_buf[6 * 4]; - - /* make sure we have a working area */ - if (target_alloc_working_area(target, 24, &arm7_9->dcc_working_area) != ERROR_OK) { - LOG_INFO("no working area available, falling back to memory writes"); - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - } - - /* copy target instructions to target endianness */ - target_buffer_set_u32_array(target, dcc_code_buf, ARRAY_SIZE(dcc_code), dcc_code); - - /* write DCC code to working area, using the non-optimized - * memory write to avoid ending up here again */ - retval = arm7_9_write_memory_no_opt(target, - arm7_9->dcc_working_area->address, 4, 6, dcc_code_buf); - if (retval != ERROR_OK) - return retval; - } - - struct arm_algorithm arm_algo; - struct reg_param reg_params[1]; - - arm_algo.common_magic = ARM_COMMON_MAGIC; - arm_algo.core_mode = ARM_MODE_SVC; - arm_algo.core_state = ARM_STATE_ARM; - - init_reg_param(®_params[0], "r0", 32, PARAM_IN_OUT); - - buf_set_u32(reg_params[0].value, 0, 32, address); - - dcc_count = count; - dcc_buffer = buffer; - retval = armv4_5_run_algorithm_inner(target, 0, NULL, 1, reg_params, - arm7_9->dcc_working_area->address, - arm7_9->dcc_working_area->address + 6*4, - 20*1000, &arm_algo, arm7_9_dcc_completion); - - if (retval == ERROR_OK) { - 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 "", - (address + count*4), - endaddress); - retval = ERROR_FAIL; - } - } - - destroy_reg_param(®_params[0]); - - return retval; -} - -/** - * Perform per-target setup that requires JTAG access. - */ -int arm7_9_examine(struct target *target) -{ - struct arm7_9_common *arm7_9 = target_to_arm7_9(target); - int retval; - - if (!target_was_examined(target)) { - struct reg_cache *t, **cache_p; - - t = embeddedice_build_reg_cache(target, arm7_9); - if (t == NULL) - return ERROR_FAIL; - - cache_p = register_get_last_cache_p(&target->reg_cache); - (*cache_p) = t; - arm7_9->eice_cache = (*cache_p); - - if (arm7_9->arm.etm) - (*cache_p)->next = etm_build_reg_cache(target, - &arm7_9->jtag_info, - arm7_9->arm.etm); - - target_set_examined(target); - } - - retval = embeddedice_setup(target); - if (retval == ERROR_OK) - retval = arm7_9_setup(target); - if (retval == ERROR_OK && arm7_9->arm.etm) - retval = etm_setup(target); - return retval; -} - - -int arm7_9_check_reset(struct target *target) -{ - struct arm7_9_common *arm7_9 = target_to_arm7_9(target); - - if (get_target_reset_nag() && !arm7_9->dcc_downloads) - LOG_WARNING( - "NOTE! DCC downloads have not been enabled, defaulting to slow memory writes. Type 'help dcc'."); - - if (get_target_reset_nag() && (target->working_area_size == 0)) - LOG_WARNING("NOTE! Severe performance degradation without working memory enabled."); - - if (get_target_reset_nag() && !arm7_9->fast_memory_access) - LOG_WARNING( - "NOTE! Severe performance degradation without fast memory access enabled. Type 'help fast'."); - - return ERROR_OK; -} - -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) -{ - uint8_t *in = (uint8_t *)pu8_in; - int size = (int)i_size; - int be = (int)i_be; - int flip = (int)i_flip; - uint32_t readback; - - switch (size) { - case 4: - readback = le_to_h_u32(in); - if (flip) - readback = flip_u32(readback, 32); - if (be) - h_u32_to_be(in, readback); - else - h_u32_to_le(in, readback); - break; - case 2: - readback = le_to_h_u16(in); - if (flip) - readback = flip_u32(readback, 16); - if (be) - h_u16_to_be(in, readback & 0xffff); - else - h_u16_to_le(in, readback & 0xffff); - break; - case 1: - readback = *in; - if (flip) - readback = flip_u32(readback, 8); - *in = readback & 0xff; - break; - } - - return ERROR_OK; -} - -COMMAND_HANDLER(handle_arm7_9_dbgrq_command) -{ - struct target *target = get_current_target(CMD_CTX); - struct arm7_9_common *arm7_9 = target_to_arm7_9(target); - - if (!is_arm7_9(arm7_9)) { - command_print(CMD_CTX, "current target isn't an ARM7/ARM9 target"); - return ERROR_TARGET_INVALID; - } - - if (CMD_ARGC > 0) - COMMAND_PARSE_ENABLE(CMD_ARGV[0], arm7_9->use_dbgrq); - - command_print(CMD_CTX, - "use of EmbeddedICE dbgrq instead of breakpoint for target halt %s", - (arm7_9->use_dbgrq) ? "enabled" : "disabled"); - - return ERROR_OK; -} - -COMMAND_HANDLER(handle_arm7_9_fast_memory_access_command) -{ - struct target *target = get_current_target(CMD_CTX); - struct arm7_9_common *arm7_9 = target_to_arm7_9(target); - - if (!is_arm7_9(arm7_9)) { - command_print(CMD_CTX, "current target isn't an ARM7/ARM9 target"); - return ERROR_TARGET_INVALID; - } - - if (CMD_ARGC > 0) - COMMAND_PARSE_ENABLE(CMD_ARGV[0], arm7_9->fast_memory_access); - - command_print(CMD_CTX, - "fast memory access is %s", - (arm7_9->fast_memory_access) ? "enabled" : "disabled"); - - return ERROR_OK; -} - -COMMAND_HANDLER(handle_arm7_9_dcc_downloads_command) -{ - struct target *target = get_current_target(CMD_CTX); - struct arm7_9_common *arm7_9 = target_to_arm7_9(target); - - if (!is_arm7_9(arm7_9)) { - command_print(CMD_CTX, "current target isn't an ARM7/ARM9 target"); - return ERROR_TARGET_INVALID; - } - - if (CMD_ARGC > 0) - COMMAND_PARSE_ENABLE(CMD_ARGV[0], arm7_9->dcc_downloads); - - command_print(CMD_CTX, - "dcc downloads are %s", - (arm7_9->dcc_downloads) ? "enabled" : "disabled"); - - return ERROR_OK; -} - -static int arm7_9_setup_semihosting(struct target *target, int enable) -{ - struct arm7_9_common *arm7_9 = target_to_arm7_9(target); - - if (!is_arm7_9(arm7_9)) { - LOG_USER("current target isn't an ARM7/ARM9 target"); - return ERROR_TARGET_INVALID; - } - - if (arm7_9->has_vector_catch) { - struct reg *vector_catch = &arm7_9->eice_cache - ->reg_list[EICE_VEC_CATCH]; - - if (!vector_catch->valid) - embeddedice_read_reg(vector_catch); - buf_set_u32(vector_catch->value, 2, 1, enable); - embeddedice_store_reg(vector_catch); - } else { - /* TODO: allow optional high vectors and/or BKPT_HARD */ - if (enable) - breakpoint_add(target, 8, 4, BKPT_SOFT); - else - breakpoint_remove(target, 8); - } - - return ERROR_OK; -} - -int arm7_9_init_arch_info(struct target *target, struct arm7_9_common *arm7_9) -{ - int retval = ERROR_OK; - struct arm *arm = &arm7_9->arm; - - arm7_9->common_magic = ARM7_9_COMMON_MAGIC; - - retval = arm_jtag_setup_connection(&arm7_9->jtag_info); - if (retval != ERROR_OK) - return retval; - - /* caller must have allocated via calloc(), so everything's zeroed */ - - arm7_9->wp_available_max = 2; - - arm7_9->fast_memory_access = false; - arm7_9->dcc_downloads = false; - - arm->arch_info = arm7_9; - arm->core_type = ARM_MODE_ANY; - arm->read_core_reg = arm7_9_read_core_reg; - arm->write_core_reg = arm7_9_write_core_reg; - arm->full_context = arm7_9_full_context; - arm->setup_semihosting = arm7_9_setup_semihosting; - - retval = arm_init_arch_info(target, arm); - if (retval != ERROR_OK) - return retval; - - return target_register_timer_callback(arm7_9_handle_target_request, - 1, 1, target); -} - -static const struct command_registration arm7_9_any_command_handlers[] = { - { - "dbgrq", - .handler = handle_arm7_9_dbgrq_command, - .mode = COMMAND_ANY, - .usage = "['enable'|'disable']", - .help = "use EmbeddedICE dbgrq instead of breakpoint " - "for target halt requests", - }, - { - "fast_memory_access", - .handler = handle_arm7_9_fast_memory_access_command, - .mode = COMMAND_ANY, - .usage = "['enable'|'disable']", - .help = "use fast memory accesses instead of slower " - "but potentially safer accesses", - }, - { - "dcc_downloads", - .handler = handle_arm7_9_dcc_downloads_command, - .mode = COMMAND_ANY, - .usage = "['enable'|'disable']", - .help = "use DCC downloads for larger memory writes", - }, - COMMAND_REGISTRATION_DONE -}; -const struct command_registration arm7_9_command_handlers[] = { - { - .chain = arm_command_handlers, - }, - { - .chain = etm_command_handlers, - }, - { - .name = "arm7_9", - .mode = COMMAND_ANY, - .help = "arm7/9 specific commands", - .usage = "", - .chain = arm7_9_any_command_handlers, - }, - COMMAND_REGISTRATION_DONE -}; diff --git a/src/target/arm7_9_common.h b/src/target/arm7_9_common.h deleted file mode 100644 index 044384b20..000000000 --- a/src/target/arm7_9_common.h +++ /dev/null @@ -1,195 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * Copyright (C) 2007,2008 Øyvind Harboe * - * oyvind.harboe@zylin.com * - * * - * Copyright (C) 2008 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * Copyright (C) 2008 by Hongtao Zheng * - * hontor@126.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifndef OPENOCD_TARGET_ARM7_9_COMMON_H -#define OPENOCD_TARGET_ARM7_9_COMMON_H - -#include "arm.h" -#include "arm_jtag.h" - -#define ARM7_9_COMMON_MAGIC 0x0a790a79 /**< */ - -/** - * Structure for items that are common between both ARM7 and ARM9 targets. - */ -struct arm7_9_common { - struct arm arm; - uint32_t common_magic; - - struct arm_jtag jtag_info; /**< JTAG information for target */ - struct reg_cache *eice_cache; /**< Embedded ICE register cache */ - - uint32_t arm_bkpt; /**< ARM breakpoint instruction */ - uint16_t thumb_bkpt; /**< Thumb breakpoint instruction */ - - int sw_breakpoints_added; /**< Specifies which watchpoint software breakpoints are setup on */ - int sw_breakpoint_count; /**< keep track of number of software breakpoints we have set */ - int breakpoint_count; /**< Current number of set breakpoints */ - int wp_available; /**< Current number of available watchpoint units */ - int wp_available_max; /**< Maximum number of available watchpoint units */ - int wp0_used; /**< Specifies if and how watchpoint unit 0 is used */ - int wp1_used; /**< Specifies if and how watchpoint unit 1 is used */ - int wp1_used_default; /**< Specifies if and how watchpoint unit 1 is used by default */ - int dbgreq_adjust_pc; /**< Amount of PC adjustment caused by a DBGREQ */ - bool use_dbgrq; /**< Specifies if DBGRQ should be used to halt the target */ - bool need_bypass_before_restart; /**< Specifies if there should be a bypass before a JTAG restart */ - - bool has_single_step; - bool has_monitor_mode; - bool has_vector_catch; /**< Specifies if the target has a reset vector catch */ - - bool debug_entry_from_reset; /**< Specifies if debug entry was from a reset */ - - bool fast_memory_access; - bool dcc_downloads; - - struct working_area *dcc_working_area; - - int (*examine_debug_reason)(struct target *target); - /**< Function for determining why debug state was entered */ - - void (*change_to_arm)(struct target *target, uint32_t *r0, uint32_t *pc); - /**< Function for changing from Thumb to ARM mode */ - - void (*read_core_regs)(struct target *target, uint32_t mask, uint32_t *core_regs[16]); - /**< Function for reading the core registers */ - - void (*read_core_regs_target_buffer)(struct target *target, uint32_t mask, - void *buffer, int size); - void (*read_xpsr)(struct target *target, uint32_t *xpsr, int spsr); - /**< Function for reading CPSR or SPSR */ - - void (*write_xpsr)(struct target *target, uint32_t xpsr, int spsr); - /**< Function for writing to CPSR or SPSR */ - - void (*write_xpsr_im8)(struct target *target, uint8_t xpsr_im, int rot, int spsr); - /**< Function for writing an immediate value to CPSR or SPSR */ - - void (*write_core_regs)(struct target *target, uint32_t mask, uint32_t core_regs[16]); - - void (*load_word_regs)(struct target *target, uint32_t mask); - void (*load_hword_reg)(struct target *target, int num); - void (*load_byte_reg)(struct target *target, int num); - - void (*store_word_regs)(struct target *target, uint32_t mask); - void (*store_hword_reg)(struct target *target, int num); - void (*store_byte_reg)(struct target *target, int num); - - void (*write_pc)(struct target *target, uint32_t pc); - /**< Function for writing to the program counter */ - - void (*branch_resume)(struct target *target); - void (*branch_resume_thumb)(struct target *target); - - void (*enable_single_step)(struct target *target, uint32_t next_pc); - void (*disable_single_step)(struct target *target); - - void (*set_special_dbgrq)(struct target *target); - /**< Function for setting DBGRQ if the normal way won't work */ - - int (*post_debug_entry)(struct target *target); - /**< Callback function called after entering debug mode */ - - void (*pre_restore_context)(struct target *target); - /**< Callback function called before restoring the processor context */ - - /** - * Variant specific memory write function that does not dispatch to bulk_write_memory. - * 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, - 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, - uint32_t count, const uint8_t *buffer); -}; - -static inline struct arm7_9_common *target_to_arm7_9(struct target *target) -{ - return container_of(target->arch_info, struct arm7_9_common, arm); -} - -static inline bool is_arm7_9(struct arm7_9_common *arm7_9) -{ - return arm7_9->common_magic == ARM7_9_COMMON_MAGIC; -} - -extern const struct command_registration arm7_9_command_handlers[]; - -int arm7_9_poll(struct target *target); - -int arm7_9_target_request_data(struct target *target, uint32_t size, uint8_t *buffer); - -int arm7_9_assert_reset(struct target *target); -int arm7_9_deassert_reset(struct target *target); -int arm7_9_reset_request_halt(struct target *target); -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 handle_breakpoints, int debug_execution); -int arm7_9_step(struct target *target, int current, uint32_t address, - int handle_breakpoints); -int arm7_9_read_memory(struct target *target, uint32_t address, - uint32_t size, uint32_t count, uint8_t *buffer); -int arm7_9_write_memory(struct target *target, uint32_t address, - uint32_t size, uint32_t count, const uint8_t *buffer); -int arm7_9_write_memory_opt(struct target *target, uint32_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, - uint32_t count, const uint8_t *buffer); - -int arm7_9_run_algorithm(struct target *target, int num_mem_params, - struct mem_param *mem_params, int num_reg_prams, - struct reg_param *reg_param, uint32_t entry_point, void *arch_info); - -int arm7_9_add_breakpoint(struct target *target, struct breakpoint *breakpoint); -int arm7_9_remove_breakpoint(struct target *target, struct breakpoint *breakpoint); -int arm7_9_add_watchpoint(struct target *target, struct watchpoint *watchpoint); -int arm7_9_remove_watchpoint(struct target *target, struct watchpoint *watchpoint); - -void arm7_9_enable_eice_step(struct target *target, uint32_t next_pc); -void arm7_9_disable_eice_step(struct target *target); - -int arm7_9_execute_sys_speed(struct target *target); - -int arm7_9_init_arch_info(struct target *target, struct arm7_9_common *arm7_9); -int arm7_9_examine(struct target *target); -int arm7_9_check_reset(struct target *target); - -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 /* OPENOCD_TARGET_ARM7_9_COMMON_H */ diff --git a/src/target/arm7tdmi.c b/src/target/arm7tdmi.c deleted file mode 100644 index 58ab02796..000000000 --- a/src/target/arm7tdmi.c +++ /dev/null @@ -1,721 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * Copyright (C) 2008 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * Copyright (C) 2007,2008 Øyvind Harboe * - * oyvind.harboe@zylin.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "arm7tdmi.h" -#include "target_type.h" -#include "register.h" -#include "arm_opcodes.h" - -/* - * For information about ARM7TDMI, see ARM DDI 0210C (r4p1) - * or ARM DDI 0029G (r3). "Debug In Depth", Appendix B, - * covers JTAG support. - */ - -#if 0 -#define _DEBUG_INSTRUCTION_EXECUTION_ -#endif - -static int arm7tdmi_examine_debug_reason(struct target *target) -{ - int retval = ERROR_OK; - struct arm7_9_common *arm7_9 = target_to_arm7_9(target); - - /* only check the debug reason if we don't know it already */ - if ((target->debug_reason != DBG_REASON_DBGRQ) - && (target->debug_reason != DBG_REASON_SINGLESTEP)) { - struct scan_field fields[2]; - uint8_t databus[4]; - uint8_t breakpoint; - - fields[0].num_bits = 1; - fields[0].out_value = NULL; - fields[0].in_value = &breakpoint; - - fields[1].num_bits = 32; - fields[1].out_value = NULL; - fields[1].in_value = databus; - - retval = arm_jtag_scann(&arm7_9->jtag_info, 0x1, TAP_DRPAUSE); - if (retval != ERROR_OK) - return retval; - retval = arm_jtag_set_instr(arm7_9->jtag_info.tap, arm7_9->jtag_info.intest_instr, NULL, TAP_DRPAUSE); - if (retval != ERROR_OK) - return retval; - - jtag_add_dr_scan(arm7_9->jtag_info.tap, 2, fields, TAP_DRPAUSE); - retval = jtag_execute_queue(); - if (retval != ERROR_OK) - return retval; - - fields[0].in_value = NULL; - fields[0].out_value = &breakpoint; - fields[1].in_value = NULL; - fields[1].out_value = databus; - - jtag_add_dr_scan(arm7_9->jtag_info.tap, 2, fields, TAP_DRPAUSE); - - if (breakpoint & 1) - target->debug_reason = DBG_REASON_WATCHPOINT; - else - target->debug_reason = DBG_REASON_BREAKPOINT; - } - - return ERROR_OK; -} - -static const int arm7tdmi_num_bits[] = {1, 32}; - -static inline int arm7tdmi_clock_out_inner(struct arm_jtag *jtag_info, uint32_t out, int breakpoint) -{ - uint8_t bp = breakpoint ? 1 : 0; - uint8_t out_value[4]; - buf_set_u32(out_value, 0, 32, flip_u32(out, 32)); - - struct scan_field fields[2] = { - { .num_bits = arm7tdmi_num_bits[0], .out_value = &bp }, - { .num_bits = arm7tdmi_num_bits[1], .out_value = out_value }, - }; - - jtag_add_dr_scan(jtag_info->tap, - 2, - fields, - TAP_DRPAUSE); - - jtag_add_runtest(0, TAP_DRPAUSE); - - return ERROR_OK; -} - -/* put an instruction in the ARM7TDMI pipeline or write the data bus, - * and optionally read data - * - * FIXME remove the unused "deprecated" parameter - */ -static inline int arm7tdmi_clock_out(struct arm_jtag *jtag_info, - uint32_t out, uint32_t *deprecated, int breakpoint) -{ - int retval; - retval = arm_jtag_scann(jtag_info, 0x1, TAP_DRPAUSE); - if (retval != ERROR_OK) - return retval; - retval = arm_jtag_set_instr(jtag_info->tap, jtag_info->intest_instr, NULL, TAP_DRPAUSE); - if (retval != ERROR_OK) - return retval; - - return arm7tdmi_clock_out_inner(jtag_info, out, breakpoint); -} - -/* clock the target, reading the databus */ -static int arm7tdmi_clock_data_in(struct arm_jtag *jtag_info, uint32_t *in) -{ - int retval = ERROR_OK; - struct scan_field fields[2]; - - retval = arm_jtag_scann(jtag_info, 0x1, TAP_DRPAUSE); - if (retval != ERROR_OK) - return retval; - retval = arm_jtag_set_instr(jtag_info->tap, jtag_info->intest_instr, NULL, TAP_DRPAUSE); - if (retval != ERROR_OK) - return retval; - - fields[0].num_bits = 1; - fields[0].out_value = NULL; - fields[0].in_value = NULL; - - fields[1].num_bits = 32; - fields[1].out_value = NULL; - fields[1].in_value = (uint8_t *)in; - - jtag_add_dr_scan(jtag_info->tap, 2, fields, TAP_DRPAUSE); - - jtag_add_callback(arm7flip32, (jtag_callback_data_t)in); - - jtag_add_runtest(0, TAP_DRPAUSE); - -#ifdef _DEBUG_INSTRUCTION_EXECUTION_ - retval = jtag_execute_queue(); - if (retval != ERROR_OK) - return retval; - - if (in) - LOG_DEBUG("in: 0x%8.8x", *in); - else - LOG_ERROR("BUG: called with in == NULL"); -#endif - - return ERROR_OK; -} - -/* clock the target, and read the databus - * the *in pointer points to a buffer where elements of 'size' bytes - * are stored in big (be == 1) or little (be == 0) endianness - */ -static int arm7tdmi_clock_data_in_endianness(struct arm_jtag *jtag_info, - void *in, int size, int be) -{ - int retval = ERROR_OK; - struct scan_field fields[3]; - - retval = arm_jtag_scann(jtag_info, 0x1, TAP_DRPAUSE); - if (retval != ERROR_OK) - return retval; - retval = arm_jtag_set_instr(jtag_info->tap, jtag_info->intest_instr, NULL, TAP_DRPAUSE); - if (retval != ERROR_OK) - return retval; - - fields[0].num_bits = 1; - fields[0].out_value = NULL; - fields[0].in_value = NULL; - - if (size == 4) { - fields[1].num_bits = 32; - fields[1].out_value = NULL; - fields[1].in_value = in; - } else { - /* Discard irrelevant bits of the scan, making sure we don't write more - * than size bytes to in */ - fields[1].num_bits = 32 - size * 8; - fields[1].out_value = NULL; - fields[1].in_value = NULL; - - fields[2].num_bits = size * 8; - fields[2].out_value = NULL; - fields[2].in_value = in; - } - - jtag_add_dr_scan(jtag_info->tap, size == 4 ? 2 : 3, fields, TAP_DRPAUSE); - - jtag_add_callback4(arm7_9_endianness_callback, - (jtag_callback_data_t)in, - (jtag_callback_data_t)size, - (jtag_callback_data_t)be, - (jtag_callback_data_t)1); - - jtag_add_runtest(0, TAP_DRPAUSE); - -#ifdef _DEBUG_INSTRUCTION_EXECUTION_ -{ - retval = jtag_execute_queue(); - if (retval != ERROR_OK) - return retval; - - if (in) - LOG_DEBUG("in: 0x%8.8x", *(uint32_t *)in); - else - LOG_ERROR("BUG: called with in == NULL"); -} -#endif - - return ERROR_OK; -} - -static void arm7tdmi_change_to_arm(struct target *target, - uint32_t *r0, uint32_t *pc) -{ - struct arm7_9_common *arm7_9 = target_to_arm7_9(target); - struct arm_jtag *jtag_info = &arm7_9->jtag_info; - - /* save r0 before using it and put system in ARM state - * to allow common handling of ARM and THUMB debugging */ - - /* fetch STR r0, [r0] */ - arm7tdmi_clock_out(jtag_info, ARMV4_5_T_STR(0, 0), NULL, 0); - arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0); - arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0); - /* nothing fetched, STR r0, [r0] in Execute (2) */ - arm7tdmi_clock_data_in(jtag_info, r0); - - /* MOV r0, r15 fetched, STR in Decode */ - arm7tdmi_clock_out(jtag_info, ARMV4_5_T_MOV(0, 15), NULL, 0); - arm7tdmi_clock_out(jtag_info, ARMV4_5_T_STR(0, 0), NULL, 0); - arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0); - arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0); - /* nothing fetched, STR r0, [r0] in Execute (2) */ - arm7tdmi_clock_data_in(jtag_info, pc); - - /* use pc-relative LDR to clear r0[1:0] (for switch to ARM mode) */ - arm7tdmi_clock_out(jtag_info, ARMV4_5_T_LDR_PCREL(0), NULL, 0); - arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0); - arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0); - /* nothing fetched, data for LDR r0, [PC, #0] */ - arm7tdmi_clock_out(jtag_info, 0x0, NULL, 0); - /* nothing fetched, data from previous cycle is written to register */ - arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0); - - /* fetch BX */ - arm7tdmi_clock_out(jtag_info, ARMV4_5_T_BX(0), NULL, 0); - /* NOP fetched, BX in Decode, MOV in Execute */ - arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0); - /* NOP fetched, BX in Execute (1) */ - arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0); - - jtag_execute_queue(); - - /* fix program counter: - * MOV r0, r15 was the 4th instruction (+6) - * reading PC in Thumb state gives address of instruction + 4 - */ - *pc -= 0xa; -} - -/* FIX!!! is this a potential performance bottleneck w.r.t. requiring too many - * roundtrips when jtag_execute_queue() has a large overhead(e.g. for USB)s? - * - * The solution is to arrange for a large out/in scan in this loop and - * and convert data afterwards. - */ -static void arm7tdmi_read_core_regs(struct target *target, - uint32_t mask, uint32_t *core_regs[16]) -{ - int i; - struct arm7_9_common *arm7_9 = target_to_arm7_9(target); - struct arm_jtag *jtag_info = &arm7_9->jtag_info; - - /* STMIA r0-15, [r0] at debug speed - * register values will start to appear on 4th DCLK - */ - arm7tdmi_clock_out(jtag_info, ARMV4_5_STMIA(0, mask & 0xffff, 0, 0), NULL, 0); - - /* fetch NOP, STM in DECODE stage */ - arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0); - /* fetch NOP, STM in EXECUTE stage (1st cycle) */ - arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0); - - for (i = 0; i <= 15; i++) { - if (mask & (1 << i)) - /* nothing fetched, STM still in EXECUTE (1 + i cycle) */ - arm7tdmi_clock_data_in(jtag_info, core_regs[i]); - } -} - -static void arm7tdmi_read_core_regs_target_buffer(struct target *target, - uint32_t mask, void *buffer, int size) -{ - int i; - struct arm7_9_common *arm7_9 = target_to_arm7_9(target); - struct arm_jtag *jtag_info = &arm7_9->jtag_info; - int be = (target->endianness == TARGET_BIG_ENDIAN) ? 1 : 0; - uint32_t *buf_u32 = buffer; - uint16_t *buf_u16 = buffer; - uint8_t *buf_u8 = buffer; - - /* STMIA r0-15, [r0] at debug speed - * register values will start to appear on 4th DCLK - */ - arm7tdmi_clock_out(jtag_info, ARMV4_5_STMIA(0, mask & 0xffff, 0, 0), NULL, 0); - - /* fetch NOP, STM in DECODE stage */ - arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0); - /* fetch NOP, STM in EXECUTE stage (1st cycle) */ - arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0); - - for (i = 0; i <= 15; i++) { - /* nothing fetched, STM still in EXECUTE (1 + i cycle), read databus */ - if (mask & (1 << i)) { - switch (size) { - case 4: - arm7tdmi_clock_data_in_endianness(jtag_info, buf_u32++, 4, be); - break; - case 2: - arm7tdmi_clock_data_in_endianness(jtag_info, buf_u16++, 2, be); - break; - case 1: - arm7tdmi_clock_data_in_endianness(jtag_info, buf_u8++, 1, be); - break; - } - } - } -} - -static void arm7tdmi_read_xpsr(struct target *target, uint32_t *xpsr, int spsr) -{ - struct arm7_9_common *arm7_9 = target_to_arm7_9(target); - struct arm_jtag *jtag_info = &arm7_9->jtag_info; - - /* MRS r0, cpsr */ - arm7tdmi_clock_out(jtag_info, ARMV4_5_MRS(0, spsr & 1), NULL, 0); - - /* STR r0, [r15] */ - arm7tdmi_clock_out(jtag_info, ARMV4_5_STR(0, 15), NULL, 0); - /* fetch NOP, STR in DECODE stage */ - arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0); - /* fetch NOP, STR in EXECUTE stage (1st cycle) */ - arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0); - /* nothing fetched, STR still in EXECUTE (2nd cycle) */ - arm7tdmi_clock_data_in(jtag_info, xpsr); -} - -static void arm7tdmi_write_xpsr(struct target *target, uint32_t xpsr, int spsr) -{ - struct arm7_9_common *arm7_9 = target_to_arm7_9(target); - struct arm_jtag *jtag_info = &arm7_9->jtag_info; - - LOG_DEBUG("xpsr: %8.8" PRIx32 ", spsr: %i", xpsr, spsr); - - /* MSR1 fetched */ - arm7tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM(xpsr & 0xff, 0, 1, spsr), NULL, 0); - /* MSR2 fetched, MSR1 in DECODE */ - arm7tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM((xpsr & 0xff00) >> 8, 0xc, 2, spsr), NULL, 0); - /* MSR3 fetched, MSR1 in EXECUTE (1), MSR2 in DECODE */ - arm7tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM((xpsr & 0xff0000) >> 16, 0x8, 4, spsr), NULL, 0); - /* nothing fetched, MSR1 in EXECUTE (2) */ - arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0); - /* MSR4 fetched, MSR2 in EXECUTE (1), MSR3 in DECODE */ - arm7tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM((xpsr & 0xff000000) >> 24, 0x4, 8, spsr), NULL, 0); - /* nothing fetched, MSR2 in EXECUTE (2) */ - arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0); - /* NOP fetched, MSR3 in EXECUTE (1), MSR4 in DECODE */ - arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0); - /* nothing fetched, MSR3 in EXECUTE (2) */ - arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0); - /* NOP fetched, MSR4 in EXECUTE (1) */ - arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0); - /* nothing fetched, MSR4 in EXECUTE (2) */ - arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0); -} - -static void arm7tdmi_write_xpsr_im8(struct target *target, - uint8_t xpsr_im, int rot, int spsr) -{ - struct arm7_9_common *arm7_9 = target_to_arm7_9(target); - struct arm_jtag *jtag_info = &arm7_9->jtag_info; - - LOG_DEBUG("xpsr_im: %2.2x, rot: %i, spsr: %i", xpsr_im, rot, spsr); - - /* MSR fetched */ - arm7tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM(xpsr_im, rot, 1, spsr), NULL, 0); - /* NOP fetched, MSR in DECODE */ - arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0); - /* NOP fetched, MSR in EXECUTE (1) */ - arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0); - /* nothing fetched, MSR in EXECUTE (2) */ - arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0); -} - -static void arm7tdmi_write_core_regs(struct target *target, - uint32_t mask, uint32_t core_regs[16]) -{ - int i; - struct arm7_9_common *arm7_9 = target_to_arm7_9(target); - struct arm_jtag *jtag_info = &arm7_9->jtag_info; - - /* LDMIA r0-15, [r0] at debug speed - * register values will start to appear on 4th DCLK - */ - arm7tdmi_clock_out(jtag_info, ARMV4_5_LDMIA(0, mask & 0xffff, 0, 0), NULL, 0); - - /* fetch NOP, LDM in DECODE stage */ - arm7tdmi_clock_out_inner(jtag_info, ARMV4_5_NOP, 0); - /* fetch NOP, LDM in EXECUTE stage (1st cycle) */ - arm7tdmi_clock_out_inner(jtag_info, ARMV4_5_NOP, 0); - - for (i = 0; i <= 15; i++) { - if (mask & (1 << i)) - /* nothing fetched, LDM still in EXECUTE (1 + i cycle) */ - arm7tdmi_clock_out_inner(jtag_info, core_regs[i], 0); - } - arm7tdmi_clock_out_inner(jtag_info, ARMV4_5_NOP, 0); -} - -static void arm7tdmi_load_word_regs(struct target *target, uint32_t mask) -{ - struct arm7_9_common *arm7_9 = target_to_arm7_9(target); - struct arm_jtag *jtag_info = &arm7_9->jtag_info; - - /* put system-speed load-multiple into the pipeline */ - arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0); - arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 1); - arm7tdmi_clock_out(jtag_info, ARMV4_5_LDMIA(0, mask & 0xffff, 0, 1), NULL, 0); -} - -static void arm7tdmi_load_hword_reg(struct target *target, int num) -{ - struct arm7_9_common *arm7_9 = target_to_arm7_9(target); - struct arm_jtag *jtag_info = &arm7_9->jtag_info; - - /* put system-speed load half-word into the pipeline */ - arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0); - arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 1); - arm7tdmi_clock_out(jtag_info, ARMV4_5_LDRH_IP(num, 0), NULL, 0); -} - -static void arm7tdmi_load_byte_reg(struct target *target, int num) -{ - struct arm7_9_common *arm7_9 = target_to_arm7_9(target); - struct arm_jtag *jtag_info = &arm7_9->jtag_info; - - /* put system-speed load byte into the pipeline */ - arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0); - arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 1); - arm7tdmi_clock_out(jtag_info, ARMV4_5_LDRB_IP(num, 0), NULL, 0); -} - -static void arm7tdmi_store_word_regs(struct target *target, uint32_t mask) -{ - struct arm7_9_common *arm7_9 = target_to_arm7_9(target); - struct arm_jtag *jtag_info = &arm7_9->jtag_info; - - /* put system-speed store-multiple into the pipeline */ - arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0); - arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 1); - arm7tdmi_clock_out(jtag_info, ARMV4_5_STMIA(0, mask, 0, 1), NULL, 0); -} - -static void arm7tdmi_store_hword_reg(struct target *target, int num) -{ - struct arm7_9_common *arm7_9 = target_to_arm7_9(target); - struct arm_jtag *jtag_info = &arm7_9->jtag_info; - - /* put system-speed store half-word into the pipeline */ - arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0); - arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 1); - arm7tdmi_clock_out(jtag_info, ARMV4_5_STRH_IP(num, 0), NULL, 0); -} - -static void arm7tdmi_store_byte_reg(struct target *target, int num) -{ - struct arm7_9_common *arm7_9 = target_to_arm7_9(target); - struct arm_jtag *jtag_info = &arm7_9->jtag_info; - - /* put system-speed store byte into the pipeline */ - arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0); - arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 1); - arm7tdmi_clock_out(jtag_info, ARMV4_5_STRB_IP(num, 0), NULL, 0); -} - -static void arm7tdmi_write_pc(struct target *target, uint32_t pc) -{ - struct arm7_9_common *arm7_9 = target_to_arm7_9(target); - struct arm_jtag *jtag_info = &arm7_9->jtag_info; - - /* LDMIA r0-15, [r0] at debug speed - * register values will start to appear on 4th DCLK - */ - arm7tdmi_clock_out(jtag_info, ARMV4_5_LDMIA(0, 0x8000, 0, 0), NULL, 0); - /* fetch NOP, LDM in DECODE stage */ - arm7tdmi_clock_out_inner(jtag_info, ARMV4_5_NOP, 0); - /* fetch NOP, LDM in EXECUTE stage (1st cycle) */ - arm7tdmi_clock_out_inner(jtag_info, ARMV4_5_NOP, 0); - /* nothing fetched, LDM in EXECUTE stage (1st cycle) load register */ - arm7tdmi_clock_out_inner(jtag_info, pc, 0); - /* nothing fetched, LDM in EXECUTE stage (2nd cycle) load register */ - arm7tdmi_clock_out_inner(jtag_info, ARMV4_5_NOP, 0); - /* nothing fetched, LDM in EXECUTE stage (3rd cycle) load register */ - arm7tdmi_clock_out_inner(jtag_info, ARMV4_5_NOP, 0); - /* fetch NOP, LDM in EXECUTE stage (4th cycle) */ - arm7tdmi_clock_out_inner(jtag_info, ARMV4_5_NOP, 0); - /* fetch NOP, LDM in EXECUTE stage (5th cycle) */ - arm7tdmi_clock_out_inner(jtag_info, ARMV4_5_NOP, 0); -} - -static void arm7tdmi_branch_resume(struct target *target) -{ - struct arm7_9_common *arm7_9 = target_to_arm7_9(target); - struct arm_jtag *jtag_info = &arm7_9->jtag_info; - - arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 1); - arm7tdmi_clock_out_inner(jtag_info, ARMV4_5_B(0xfffffa, 0), 0); -} - -static void arm7tdmi_branch_resume_thumb(struct target *target) -{ - struct arm7_9_common *arm7_9 = target_to_arm7_9(target); - struct arm *arm = &arm7_9->arm; - struct arm_jtag *jtag_info = &arm7_9->jtag_info; - struct reg *dbg_stat = &arm7_9->eice_cache->reg_list[EICE_DBG_STAT]; - - LOG_DEBUG("-"); - - /* LDMIA r0, [r0] at debug speed - * register values will start to appear on 4th DCLK - */ - arm7tdmi_clock_out(jtag_info, ARMV4_5_LDMIA(0, 0x1, 0, 0), NULL, 0); - - /* fetch NOP, LDM in DECODE stage */ - arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0); - /* fetch NOP, LDM in EXECUTE stage (1st cycle) */ - arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0); - /* nothing fetched, LDM in EXECUTE stage (2nd cycle) */ - arm7tdmi_clock_out(jtag_info, - buf_get_u32(arm->pc->value, 0, 32) | 1, NULL, 0); - /* nothing fetched, LDM in EXECUTE stage (3rd cycle) */ - arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0); - - /* Branch and eXchange */ - arm7tdmi_clock_out(jtag_info, ARMV4_5_BX(0), NULL, 0); - - embeddedice_read_reg(dbg_stat); - - /* fetch NOP, BX in DECODE stage */ - arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0); - - /* target is now in Thumb state */ - embeddedice_read_reg(dbg_stat); - - /* fetch NOP, BX in EXECUTE stage (1st cycle) */ - arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0); - - /* target is now in Thumb state */ - embeddedice_read_reg(dbg_stat); - - /* load r0 value */ - arm7tdmi_clock_out(jtag_info, ARMV4_5_T_LDR_PCREL(0), NULL, 0); - /* fetch NOP, LDR in Decode */ - arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0); - /* fetch NOP, LDR in Execute */ - arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0); - /* nothing fetched, LDR in EXECUTE stage (2nd cycle) */ - arm7tdmi_clock_out(jtag_info, buf_get_u32(arm->core_cache->reg_list[0].value, 0, 32), NULL, 0); - /* nothing fetched, LDR in EXECUTE stage (3rd cycle) */ - arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0); - - arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0); - arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0); - - embeddedice_read_reg(dbg_stat); - - arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 1); - arm7tdmi_clock_out(jtag_info, ARMV4_5_T_B(0x7f8), NULL, 0); -} - -static void arm7tdmi_build_reg_cache(struct target *target) -{ - struct reg_cache **cache_p = register_get_last_cache_p(&target->reg_cache); - struct arm *arm = target_to_arm(target); - - (*cache_p) = arm_build_reg_cache(target, arm); -} - -int arm7tdmi_init_target(struct command_context *cmd_ctx, struct target *target) -{ - arm7tdmi_build_reg_cache(target); - - return ERROR_OK; -} - -int arm7tdmi_init_arch_info(struct target *target, - struct arm7_9_common *arm7_9, struct jtag_tap *tap) -{ - /* prepare JTAG information for the new target */ - arm7_9->jtag_info.tap = tap; - arm7_9->jtag_info.scann_size = 4; - - /* register arch-specific functions */ - arm7_9->examine_debug_reason = arm7tdmi_examine_debug_reason; - arm7_9->change_to_arm = arm7tdmi_change_to_arm; - arm7_9->read_core_regs = arm7tdmi_read_core_regs; - arm7_9->read_core_regs_target_buffer = arm7tdmi_read_core_regs_target_buffer; - arm7_9->read_xpsr = arm7tdmi_read_xpsr; - - arm7_9->write_xpsr = arm7tdmi_write_xpsr; - arm7_9->write_xpsr_im8 = arm7tdmi_write_xpsr_im8; - arm7_9->write_core_regs = arm7tdmi_write_core_regs; - - arm7_9->load_word_regs = arm7tdmi_load_word_regs; - arm7_9->load_hword_reg = arm7tdmi_load_hword_reg; - arm7_9->load_byte_reg = arm7tdmi_load_byte_reg; - - arm7_9->store_word_regs = arm7tdmi_store_word_regs; - arm7_9->store_hword_reg = arm7tdmi_store_hword_reg; - arm7_9->store_byte_reg = arm7tdmi_store_byte_reg; - - arm7_9->write_pc = arm7tdmi_write_pc; - arm7_9->branch_resume = arm7tdmi_branch_resume; - arm7_9->branch_resume_thumb = arm7tdmi_branch_resume_thumb; - - arm7_9->enable_single_step = arm7_9_enable_eice_step; - arm7_9->disable_single_step = arm7_9_disable_eice_step; - - arm7_9->write_memory = arm7_9_write_memory; - arm7_9->bulk_write_memory = arm7_9_bulk_write_memory; - - arm7_9->post_debug_entry = NULL; - - arm7_9->pre_restore_context = NULL; - - /* initialize arch-specific breakpoint handling */ - arm7_9->arm_bkpt = 0xdeeedeee; - arm7_9->thumb_bkpt = 0xdeee; - - arm7_9->dbgreq_adjust_pc = 2; - - arm7_9_init_arch_info(target, arm7_9); - - return ERROR_OK; -} - -static int arm7tdmi_target_create(struct target *target, Jim_Interp *interp) -{ - struct arm7_9_common *arm7_9; - - arm7_9 = calloc(1, sizeof(struct arm7_9_common)); - arm7tdmi_init_arch_info(target, arm7_9, target->tap); - arm7_9->arm.is_armv4 = true; - - return ERROR_OK; -} - -/** Holds methods for ARM7TDMI targets. */ -struct target_type arm7tdmi_target = { - .name = "arm7tdmi", - - .poll = arm7_9_poll, - .arch_state = arm_arch_state, - - .target_request_data = arm7_9_target_request_data, - - .halt = arm7_9_halt, - .resume = arm7_9_resume, - .step = arm7_9_step, - - .assert_reset = arm7_9_assert_reset, - .deassert_reset = arm7_9_deassert_reset, - .soft_reset_halt = arm7_9_soft_reset_halt, - - .get_gdb_reg_list = arm_get_gdb_reg_list, - - .read_memory = arm7_9_read_memory, - .write_memory = arm7_9_write_memory_opt, - - .checksum_memory = arm_checksum_memory, - .blank_check_memory = arm_blank_check_memory, - - .run_algorithm = armv4_5_run_algorithm, - - .add_breakpoint = arm7_9_add_breakpoint, - .remove_breakpoint = arm7_9_remove_breakpoint, - .add_watchpoint = arm7_9_add_watchpoint, - .remove_watchpoint = arm7_9_remove_watchpoint, - - .commands = arm7_9_command_handlers, - .target_create = arm7tdmi_target_create, - .init_target = arm7tdmi_init_target, - .examine = arm7_9_examine, - .check_reset = arm7_9_check_reset, -}; diff --git a/src/target/arm7tdmi.h b/src/target/arm7tdmi.h deleted file mode 100644 index 053f64df8..000000000 --- a/src/target/arm7tdmi.h +++ /dev/null @@ -1,32 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * Copyright (C) 2008 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifndef OPENOCD_TARGET_ARM7TDMI_H -#define OPENOCD_TARGET_ARM7TDMI_H - -#include "embeddedice.h" - -int arm7tdmi_init_arch_info(struct target *target, - struct arm7_9_common *arm7_9, struct jtag_tap *tap); -int arm7tdmi_init_target(struct command_context *cmd_ctx, - struct target *target); - -#endif /* OPENOCD_TARGET_ARM7TDMI_H */ diff --git a/src/target/arm920t.c b/src/target/arm920t.c deleted file mode 100644 index 2c96d1935..000000000 --- a/src/target/arm920t.c +++ /dev/null @@ -1,1720 +0,0 @@ - -/*************************************************************************** - * Copyright (C) 2005 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "arm920t.h" -#include -#include "target_type.h" -#include "register.h" -#include "arm_opcodes.h" - -/* - * For information about the ARM920T, see ARM DDI 0151C especially - * Chapter 9 about debug support, which shows how to manipulate each - * of the different scan chains: - * - * 0 ... ARM920 signals, e.g. to rest of SOC (unused here) - * 1 ... debugging; watchpoint and breakpoint status, etc; also - * MMU and cache access in conjunction with scan chain 15 - * 2 ... EmbeddedICE - * 3 ... external boundary scan (SoC-specific, unused here) - * 4 ... access to cache tag RAM - * 6 ... ETM9 - * 15 ... access coprocessor 15, "physical" or "interpreted" modes - * "interpreted" works with a few actual MRC/MCR instructions - * "physical" provides register-like behaviors. Section 9.6.7 - * covers these details. - * - * The ARM922T is similar, but with smaller caches (8K each, vs 16K). - */ - -#if 0 -#define _DEBUG_INSTRUCTION_EXECUTION_ -#endif - -/* Table 9-8 shows scan chain 15 format during physical access mode, using a - * dedicated 6-bit address space (encoded in bits 33:38). Writes use one - * JTAG scan, while reads use two. - * - * Table 9-9 lists the thirteen registers which support physical access. - * ARM920T_CP15_PHYS_ADDR() constructs the 6-bit reg_addr parameter passed - * to arm920t_read_cp15_physical() and arm920t_write_cp15_physical(). - * - * x == bit[38] - * y == bits[37:34] - * z == bit[33] - */ -#define ARM920T_CP15_PHYS_ADDR(x, y, z) ((x << 5) | (y << 1) << (z)) - -/* Registers supporting physical Read access (from table 9-9) */ -#define CP15PHYS_CACHETYPE ARM920T_CP15_PHYS_ADDR(0, 0x0, 1) -#define CP15PHYS_ICACHE_IDX ARM920T_CP15_PHYS_ADDR(1, 0xd, 1) -#define CP15PHYS_DCACHE_IDX ARM920T_CP15_PHYS_ADDR(1, 0xe, 1) -/* NOTE: several more registers support only physical read access */ - -/* Registers supporting physical Read/Write access (from table 9-9) */ -#define CP15PHYS_CTRL ARM920T_CP15_PHYS_ADDR(0, 0x1, 0) -#define CP15PHYS_PID ARM920T_CP15_PHYS_ADDR(0, 0xd, 0) -#define CP15PHYS_TESTSTATE ARM920T_CP15_PHYS_ADDR(0, 0xf, 0) -#define CP15PHYS_ICACHE ARM920T_CP15_PHYS_ADDR(1, 0x1, 1) -#define CP15PHYS_DCACHE ARM920T_CP15_PHYS_ADDR(1, 0x2, 1) - -static int arm920t_read_cp15_physical(struct target *target, - int reg_addr, uint32_t *value) -{ - struct arm920t_common *arm920t = target_to_arm920(target); - struct arm_jtag *jtag_info; - struct scan_field fields[4]; - uint8_t access_type_buf = 1; - uint8_t reg_addr_buf = reg_addr & 0x3f; - uint8_t nr_w_buf = 0; - int retval; - - jtag_info = &arm920t->arm7_9_common.jtag_info; - - retval = arm_jtag_scann(jtag_info, 0xf, TAP_IDLE); - if (retval != ERROR_OK) - return retval; - retval = arm_jtag_set_instr(jtag_info->tap, jtag_info->intest_instr, NULL, TAP_IDLE); - if (retval != ERROR_OK) - return retval; - - fields[0].num_bits = 1; - fields[0].out_value = &access_type_buf; - fields[0].in_value = NULL; - - fields[1].num_bits = 32; - fields[1].out_value = NULL; - fields[1].in_value = NULL; - - fields[2].num_bits = 6; - fields[2].out_value = ®_addr_buf; - fields[2].in_value = NULL; - - fields[3].num_bits = 1; - fields[3].out_value = &nr_w_buf; - fields[3].in_value = NULL; - - jtag_add_dr_scan(jtag_info->tap, 4, fields, TAP_IDLE); - - fields[1].in_value = (uint8_t *)value; - - jtag_add_dr_scan(jtag_info->tap, 4, fields, TAP_IDLE); - - jtag_add_callback(arm_le_to_h_u32, (jtag_callback_data_t)value); - -#ifdef _DEBUG_INSTRUCTION_EXECUTION_ - jtag_execute_queue(); - LOG_DEBUG("addr: 0x%x value: %8.8x", reg_addr, *value); -#endif - - return ERROR_OK; -} - -static int arm920t_write_cp15_physical(struct target *target, - int reg_addr, uint32_t value) -{ - struct arm920t_common *arm920t = target_to_arm920(target); - struct arm_jtag *jtag_info; - struct scan_field fields[4]; - uint8_t access_type_buf = 1; - uint8_t reg_addr_buf = reg_addr & 0x3f; - uint8_t nr_w_buf = 1; - uint8_t value_buf[4]; - int retval; - - jtag_info = &arm920t->arm7_9_common.jtag_info; - - buf_set_u32(value_buf, 0, 32, value); - - retval = arm_jtag_scann(jtag_info, 0xf, TAP_IDLE); - if (retval != ERROR_OK) - return retval; - retval = arm_jtag_set_instr(jtag_info->tap, jtag_info->intest_instr, NULL, TAP_IDLE); - if (retval != ERROR_OK) - return retval; - - fields[0].num_bits = 1; - fields[0].out_value = &access_type_buf; - fields[0].in_value = NULL; - - fields[1].num_bits = 32; - fields[1].out_value = value_buf; - fields[1].in_value = NULL; - - fields[2].num_bits = 6; - fields[2].out_value = ®_addr_buf; - fields[2].in_value = NULL; - - fields[3].num_bits = 1; - fields[3].out_value = &nr_w_buf; - fields[3].in_value = NULL; - - jtag_add_dr_scan(jtag_info->tap, 4, fields, TAP_IDLE); - -#ifdef _DEBUG_INSTRUCTION_EXECUTION_ - LOG_DEBUG("addr: 0x%x value: %8.8x", reg_addr, value); -#endif - - return ERROR_OK; -} - -/* See table 9-10 for scan chain 15 format during interpreted access mode. - * If the TESTSTATE register is set for interpreted access, certain CP15 - * MRC and MCR instructions may be executed through scan chain 15. - * - * Tables 9-11, 9-12, and 9-13 show which MRC and MCR instructions can be - * executed using scan chain 15 interpreted mode. - */ -static int arm920t_execute_cp15(struct target *target, uint32_t cp15_opcode, - uint32_t arm_opcode) -{ - int retval; - struct arm920t_common *arm920t = target_to_arm920(target); - struct arm_jtag *jtag_info; - struct scan_field fields[4]; - uint8_t access_type_buf = 0; /* interpreted access */ - uint8_t reg_addr_buf = 0x0; - uint8_t nr_w_buf = 0; - uint8_t cp15_opcode_buf[4]; - - jtag_info = &arm920t->arm7_9_common.jtag_info; - - retval = arm_jtag_scann(jtag_info, 0xf, TAP_IDLE); - if (retval != ERROR_OK) - return retval; - retval = arm_jtag_set_instr(jtag_info->tap, jtag_info->intest_instr, NULL, TAP_IDLE); - if (retval != ERROR_OK) - return retval; - - buf_set_u32(cp15_opcode_buf, 0, 32, cp15_opcode); - - fields[0].num_bits = 1; - fields[0].out_value = &access_type_buf; - fields[0].in_value = NULL; - - fields[1].num_bits = 32; - fields[1].out_value = cp15_opcode_buf; - fields[1].in_value = NULL; - - fields[2].num_bits = 6; - fields[2].out_value = ®_addr_buf; - fields[2].in_value = NULL; - - fields[3].num_bits = 1; - fields[3].out_value = &nr_w_buf; - fields[3].in_value = NULL; - - jtag_add_dr_scan(jtag_info->tap, 4, fields, TAP_IDLE); - - arm9tdmi_clock_out(jtag_info, arm_opcode, 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 1); - retval = arm7_9_execute_sys_speed(target); - if (retval != ERROR_OK) - return retval; - - retval = jtag_execute_queue(); - if (retval != ERROR_OK) { - LOG_ERROR("failed executing JTAG queue"); - return retval; - } - - return ERROR_OK; -} - -static int arm920t_read_cp15_interpreted(struct target *target, - uint32_t cp15_opcode, uint32_t address, uint32_t *value) -{ - struct arm *arm = target_to_arm(target); - uint32_t *regs_p[1]; - uint32_t regs[2]; - uint32_t cp15c15 = 0x0; - struct reg *r = arm->core_cache->reg_list; - - /* load address into R1 */ - regs[1] = address; - arm9tdmi_write_core_regs(target, 0x2, regs); - - /* read-modify-write CP15 test state register - * to enable interpreted access mode */ - arm920t_read_cp15_physical(target, CP15PHYS_TESTSTATE, &cp15c15); - jtag_execute_queue(); - cp15c15 |= 1; /* set interpret mode */ - arm920t_write_cp15_physical(target, CP15PHYS_TESTSTATE, cp15c15); - - /* execute CP15 instruction and ARM load (reading from coprocessor) */ - arm920t_execute_cp15(target, cp15_opcode, ARMV4_5_LDR(0, 1)); - - /* disable interpreted access mode */ - cp15c15 &= ~1U; /* clear interpret mode */ - arm920t_write_cp15_physical(target, CP15PHYS_TESTSTATE, cp15c15); - - /* retrieve value from R0 */ - regs_p[0] = value; - arm9tdmi_read_core_regs(target, 0x1, regs_p); - jtag_execute_queue(); - -#ifdef _DEBUG_INSTRUCTION_EXECUTION_ - LOG_DEBUG("cp15_opcode: %8.8x, address: %8.8x, value: %8.8x", - cp15_opcode, address, *value); -#endif - - if (!is_arm_mode(arm->core_mode)) { - LOG_ERROR("not a valid arm core mode - communication failure?"); - return ERROR_FAIL; - } - - r[0].dirty = 1; - r[1].dirty = 1; - - return ERROR_OK; -} - -static -int arm920t_write_cp15_interpreted(struct target *target, - uint32_t cp15_opcode, uint32_t value, uint32_t address) -{ - uint32_t cp15c15 = 0x0; - struct arm *arm = target_to_arm(target); - uint32_t regs[2]; - struct reg *r = arm->core_cache->reg_list; - - /* load value, address into R0, R1 */ - regs[0] = value; - regs[1] = address; - arm9tdmi_write_core_regs(target, 0x3, regs); - - /* read-modify-write CP15 test state register - * to enable interpreted access mode */ - arm920t_read_cp15_physical(target, CP15PHYS_TESTSTATE, &cp15c15); - jtag_execute_queue(); - cp15c15 |= 1; /* set interpret mode */ - arm920t_write_cp15_physical(target, CP15PHYS_TESTSTATE, cp15c15); - - /* execute CP15 instruction and ARM store (writing to coprocessor) */ - arm920t_execute_cp15(target, cp15_opcode, ARMV4_5_STR(0, 1)); - - /* disable interpreted access mode */ - cp15c15 &= ~1U; /* set interpret mode */ - arm920t_write_cp15_physical(target, CP15PHYS_TESTSTATE, cp15c15); - -#ifdef _DEBUG_INSTRUCTION_EXECUTION_ - LOG_DEBUG("cp15_opcode: %8.8x, value: %8.8x, address: %8.8x", - cp15_opcode, value, address); -#endif - - if (!is_arm_mode(arm->core_mode)) { - LOG_ERROR("not a valid arm core mode - communication failure?"); - return ERROR_FAIL; - } - - r[0].dirty = 1; - r[1].dirty = 1; - - return ERROR_OK; -} - -/* EXPORTED to FA256 */ -int arm920t_get_ttb(struct target *target, uint32_t *result) -{ - int retval; - uint32_t ttb = 0x0; - - retval = arm920t_read_cp15_interpreted(target, - /* FIXME use opcode macro */ - 0xeebf0f51, 0x0, &ttb); - if (retval != ERROR_OK) - return retval; - - *result = ttb; - return ERROR_OK; -} - -/* EXPORTED to FA256 */ -int arm920t_disable_mmu_caches(struct target *target, int mmu, - int d_u_cache, int i_cache) -{ - uint32_t cp15_control; - int retval; - - /* read cp15 control register */ - retval = arm920t_read_cp15_physical(target, CP15PHYS_CTRL, &cp15_control); - if (retval != ERROR_OK) - return retval; - retval = jtag_execute_queue(); - if (retval != ERROR_OK) - return retval; - - if (mmu) - cp15_control &= ~0x1U; - - if (d_u_cache) - cp15_control &= ~0x4U; - - if (i_cache) - cp15_control &= ~0x1000U; - - retval = arm920t_write_cp15_physical(target, CP15PHYS_CTRL, cp15_control); - return retval; -} - -/* EXPORTED to FA256 */ -int arm920t_enable_mmu_caches(struct target *target, int mmu, - int d_u_cache, int i_cache) -{ - uint32_t cp15_control; - int retval; - - /* read cp15 control register */ - retval = arm920t_read_cp15_physical(target, CP15PHYS_CTRL, &cp15_control); - if (retval != ERROR_OK) - return retval; - retval = jtag_execute_queue(); - if (retval != ERROR_OK) - return retval; - - if (mmu) - cp15_control |= 0x1U; - - if (d_u_cache) - cp15_control |= 0x4U; - - if (i_cache) - cp15_control |= 0x1000U; - - retval = arm920t_write_cp15_physical(target, CP15PHYS_CTRL, cp15_control); - return retval; -} - -/* EXPORTED to FA256 */ -int arm920t_post_debug_entry(struct target *target) -{ - uint32_t cp15c15; - struct arm920t_common *arm920t = target_to_arm920(target); - int retval; - - /* examine cp15 control reg */ - retval = arm920t_read_cp15_physical(target, - CP15PHYS_CTRL, &arm920t->cp15_control_reg); - if (retval != ERROR_OK) - return retval; - retval = jtag_execute_queue(); - if (retval != ERROR_OK) - return retval; - LOG_DEBUG("cp15_control_reg: %8.8" PRIx32, arm920t->cp15_control_reg); - - if (arm920t->armv4_5_mmu.armv4_5_cache.ctype == -1) { - uint32_t cache_type_reg; - /* identify caches */ - retval = arm920t_read_cp15_physical(target, - CP15PHYS_CACHETYPE, &cache_type_reg); - if (retval != ERROR_OK) - return retval; - retval = jtag_execute_queue(); - if (retval != ERROR_OK) - return retval; - armv4_5_identify_cache(cache_type_reg, - &arm920t->armv4_5_mmu.armv4_5_cache); - } - - arm920t->armv4_5_mmu.mmu_enabled = - (arm920t->cp15_control_reg & 0x1U) ? 1 : 0; - arm920t->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled = - (arm920t->cp15_control_reg & 0x4U) ? 1 : 0; - arm920t->armv4_5_mmu.armv4_5_cache.i_cache_enabled = - (arm920t->cp15_control_reg & 0x1000U) ? 1 : 0; - - /* save i/d fault status and address register - * FIXME use opcode macros */ - retval = arm920t_read_cp15_interpreted(target, 0xee150f10, 0x0, &arm920t->d_fsr); - if (retval != ERROR_OK) - return retval; - retval = arm920t_read_cp15_interpreted(target, 0xee150f30, 0x0, &arm920t->i_fsr); - if (retval != ERROR_OK) - return retval; - retval = arm920t_read_cp15_interpreted(target, 0xee160f10, 0x0, &arm920t->d_far); - if (retval != ERROR_OK) - return retval; - retval = arm920t_read_cp15_interpreted(target, 0xee160f30, 0x0, &arm920t->i_far); - if (retval != ERROR_OK) - return retval; - - LOG_DEBUG("D FSR: 0x%8.8" PRIx32 ", D FAR: 0x%8.8" PRIx32 - ", I FSR: 0x%8.8" PRIx32 ", I FAR: 0x%8.8" PRIx32, - arm920t->d_fsr, arm920t->d_far, arm920t->i_fsr, arm920t->i_far); - - if (arm920t->preserve_cache) { - /* read-modify-write CP15 test state register - * to disable I/D-cache linefills */ - retval = arm920t_read_cp15_physical(target, - CP15PHYS_TESTSTATE, &cp15c15); - if (retval != ERROR_OK) - return retval; - retval = jtag_execute_queue(); - if (retval != ERROR_OK) - return retval; - cp15c15 |= 0x600; - retval = arm920t_write_cp15_physical(target, - CP15PHYS_TESTSTATE, cp15c15); - if (retval != ERROR_OK) - return retval; - } - return ERROR_OK; -} - -/* EXPORTED to FA256 */ -void arm920t_pre_restore_context(struct target *target) -{ - uint32_t cp15c15; - struct arm920t_common *arm920t = target_to_arm920(target); - - /* restore i/d fault status and address register */ - arm920t_write_cp15_interpreted(target, 0xee050f10, arm920t->d_fsr, 0x0); - arm920t_write_cp15_interpreted(target, 0xee050f30, arm920t->i_fsr, 0x0); - arm920t_write_cp15_interpreted(target, 0xee060f10, arm920t->d_far, 0x0); - arm920t_write_cp15_interpreted(target, 0xee060f30, arm920t->i_far, 0x0); - - /* read-modify-write CP15 test state register - * to reenable I/D-cache linefills */ - if (arm920t->preserve_cache) { - arm920t_read_cp15_physical(target, - CP15PHYS_TESTSTATE, &cp15c15); - jtag_execute_queue(); - cp15c15 &= ~0x600U; - arm920t_write_cp15_physical(target, - CP15PHYS_TESTSTATE, cp15c15); - } -} - -static const char arm920_not[] = "target is not an ARM920"; - -static int arm920t_verify_pointer(struct command_context *cmd_ctx, - struct arm920t_common *arm920t) -{ - if (arm920t->common_magic != ARM920T_COMMON_MAGIC) { - command_print(cmd_ctx, arm920_not); - return ERROR_TARGET_INVALID; - } - - return ERROR_OK; -} - -/** Logs summary of ARM920 state for a halted target. */ -int arm920t_arch_state(struct target *target) -{ - static const char *state[] = { - "disabled", "enabled" - }; - - struct arm920t_common *arm920t = target_to_arm920(target); - - if (arm920t->common_magic != ARM920T_COMMON_MAGIC) { - LOG_ERROR("BUG: %s", arm920_not); - return ERROR_TARGET_INVALID; - } - - arm_arch_state(target); - LOG_USER("MMU: %s, D-Cache: %s, I-Cache: %s", - state[arm920t->armv4_5_mmu.mmu_enabled], - state[arm920t->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled], - state[arm920t->armv4_5_mmu.armv4_5_cache.i_cache_enabled]); - - return ERROR_OK; -} - -static int arm920_mmu(struct target *target, int *enabled) -{ - if (target->state != TARGET_HALTED) { - LOG_ERROR("%s: target not halted", __func__); - return ERROR_TARGET_INVALID; - } - - *enabled = target_to_arm920(target)->armv4_5_mmu.mmu_enabled; - return ERROR_OK; -} - -static int arm920_virt2phys(struct target *target, - uint32_t virt, uint32_t *phys) -{ - uint32_t cb; - struct arm920t_common *arm920t = target_to_arm920(target); - - uint32_t ret; - int retval = armv4_5_mmu_translate_va(target, - &arm920t->armv4_5_mmu, virt, &cb, &ret); - if (retval != ERROR_OK) - return retval; - *phys = ret; - return ERROR_OK; -} - -/** Reads a buffer, in the specified word size, with current MMU settings. */ -int arm920t_read_memory(struct target *target, uint32_t address, - uint32_t size, uint32_t count, uint8_t *buffer) -{ - int retval; - - retval = arm7_9_read_memory(target, address, size, count, buffer); - - return retval; -} - - -static int arm920t_read_phys_memory(struct target *target, - uint32_t address, uint32_t size, - uint32_t count, uint8_t *buffer) -{ - struct arm920t_common *arm920t = target_to_arm920(target); - - return armv4_5_mmu_read_physical(target, &arm920t->armv4_5_mmu, - address, size, count, buffer); -} - -static int arm920t_write_phys_memory(struct target *target, - uint32_t address, uint32_t size, - uint32_t count, const uint8_t *buffer) -{ - struct arm920t_common *arm920t = target_to_arm920(target); - - return armv4_5_mmu_write_physical(target, &arm920t->armv4_5_mmu, - address, size, count, buffer); -} - -/** Writes a buffer, in the specified word size, with current MMU settings. */ -int arm920t_write_memory(struct target *target, uint32_t address, - uint32_t size, uint32_t count, const uint8_t *buffer) -{ - int retval; - const uint32_t cache_mask = ~0x1f; /* cache line size : 32 byte */ - struct arm920t_common *arm920t = target_to_arm920(target); - - /* FIX!!!! this should be cleaned up and made much more general. The - * plan is to write up and test on arm920t specifically and - * then generalize and clean up afterwards. - * - * Also it should be moved to the callbacks that handle breakpoints - * specifically and not the generic memory write fn's. See XScale code. - */ - if (arm920t->armv4_5_mmu.mmu_enabled && (count == 1) && - ((size == 2) || (size == 4))) { - /* special case the handling of single word writes to - * bypass MMU, to allow implementation of breakpoints - * in memory marked read only - * by MMU - */ - uint32_t cb; - uint32_t pa; - - /* - * We need physical address and cb - */ - retval = armv4_5_mmu_translate_va(target, &arm920t->armv4_5_mmu, - address, &cb, &pa); - if (retval != ERROR_OK) - return retval; - - if (arm920t->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled) { - if (cb & 0x1) { - LOG_DEBUG("D-Cache buffered, " - "drain write buffer"); - /* - * Buffered ? - * Drain write buffer - MCR p15,0,Rd,c7,c10,4 - */ - - retval = arm920t_write_cp15_interpreted(target, - ARMV4_5_MCR(15, 0, 0, 7, 10, 4), - 0x0, 0); - if (retval != ERROR_OK) - return retval; - } - - if (cb == 0x3) { - /* - * Write back memory ? -> clean cache - * - * There is no way to clean cache lines using - * cp15 scan chain, so copy the full cache - * line from cache to physical memory. - */ - uint8_t data[32]; - - LOG_DEBUG("D-Cache in 'write back' mode, " - "flush cache line"); - - retval = target_read_memory(target, - address & cache_mask, 1, - sizeof(data), &data[0]); - if (retval != ERROR_OK) - return retval; - - retval = armv4_5_mmu_write_physical(target, - &arm920t->armv4_5_mmu, - pa & cache_mask, 1, - sizeof(data), &data[0]); - if (retval != ERROR_OK) - return retval; - } - - /* Cached ? */ - if (cb & 0x2) { - /* - * Cached ? -> Invalidate data cache using MVA - * - * MCR p15,0,Rd,c7,c6,1 - */ - LOG_DEBUG("D-Cache enabled, " - "invalidate cache line"); - - retval = arm920t_write_cp15_interpreted(target, - ARMV4_5_MCR(15, 0, 0, 7, 6, 1), 0x0, - address & cache_mask); - if (retval != ERROR_OK) - return retval; - } - } - - /* write directly to physical memory, - * bypassing any read only MMU bits, etc. - */ - retval = armv4_5_mmu_write_physical(target, - &arm920t->armv4_5_mmu, pa, size, - count, buffer); - if (retval != ERROR_OK) - return retval; - } else { - retval = arm7_9_write_memory(target, address, size, count, buffer); - if (retval != ERROR_OK) - return retval; - } - - /* If ICache is enabled, we have to invalidate affected ICache lines - * the DCache is forced to write-through, - * so we don't have to clean it here - */ - if (arm920t->armv4_5_mmu.armv4_5_cache.i_cache_enabled) { - if (count <= 1) { - /* invalidate ICache single entry with MVA - * mcr 15, 0, r0, cr7, cr5, {1} - */ - LOG_DEBUG("I-Cache enabled, " - "invalidating affected I-Cache line"); - retval = arm920t_write_cp15_interpreted(target, - ARMV4_5_MCR(15, 0, 0, 7, 5, 1), - 0x0, address & cache_mask); - if (retval != ERROR_OK) - return retval; - } else { - /* invalidate ICache - * mcr 15, 0, r0, cr7, cr5, {0} - */ - retval = arm920t_write_cp15_interpreted(target, - ARMV4_5_MCR(15, 0, 0, 7, 5, 0), - 0x0, 0x0); - if (retval != ERROR_OK) - return retval; - } - } - - return ERROR_OK; -} - -/* EXPORTED to FA256 */ -int arm920t_soft_reset_halt(struct target *target) -{ - int retval = ERROR_OK; - struct arm920t_common *arm920t = target_to_arm920(target); - struct arm7_9_common *arm7_9 = target_to_arm7_9(target); - struct arm *arm = &arm7_9->arm; - struct reg *dbg_stat = &arm7_9->eice_cache->reg_list[EICE_DBG_STAT]; - - retval = target_halt(target); - if (retval != ERROR_OK) - return retval; - - 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); - retval = jtag_execute_queue(); - if (retval != ERROR_OK) - return retval; - } else - break; - if (debug_level >= 3) { - /* do not eat all CPU, time out after 1 se*/ - alive_sleep(100); - } else - keep_alive(); - } - if (timeout) { - LOG_ERROR("Failed to halt CPU after 1 sec"); - return ERROR_TARGET_TIMEOUT; - } - - target->state = TARGET_HALTED; - - /* SVC, ARM state, IRQ and FIQ disabled */ - uint32_t cpsr; - - cpsr = buf_get_u32(arm->cpsr->value, 0, 32); - cpsr &= ~0xff; - cpsr |= 0xd3; - arm_set_cpsr(arm, cpsr); - arm->cpsr->dirty = 1; - - /* start fetching from 0x0 */ - buf_set_u32(arm->pc->value, 0, 32, 0x0); - arm->pc->dirty = 1; - arm->pc->valid = 1; - - arm920t_disable_mmu_caches(target, 1, 1, 1); - arm920t->armv4_5_mmu.mmu_enabled = 0; - arm920t->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled = 0; - arm920t->armv4_5_mmu.armv4_5_cache.i_cache_enabled = 0; - - return target_call_event_callbacks(target, TARGET_EVENT_HALTED); -} - -/* FIXME remove forward decls */ -static int arm920t_mrc(struct target *target, int cpnum, - uint32_t op1, uint32_t op2, - uint32_t CRn, uint32_t CRm, - uint32_t *value); -static int arm920t_mcr(struct target *target, int cpnum, - uint32_t op1, uint32_t op2, - uint32_t CRn, uint32_t CRm, - uint32_t value); - -static int arm920t_init_arch_info(struct target *target, - struct arm920t_common *arm920t, struct jtag_tap *tap) -{ - struct arm7_9_common *arm7_9 = &arm920t->arm7_9_common; - - arm7_9->arm.mrc = arm920t_mrc; - arm7_9->arm.mcr = arm920t_mcr; - - /* initialize arm7/arm9 specific info (including armv4_5) */ - arm9tdmi_init_arch_info(target, arm7_9, tap); - - arm920t->common_magic = ARM920T_COMMON_MAGIC; - - arm7_9->post_debug_entry = arm920t_post_debug_entry; - arm7_9->pre_restore_context = arm920t_pre_restore_context; - arm7_9->write_memory = arm920t_write_memory; - - arm920t->armv4_5_mmu.armv4_5_cache.ctype = -1; - arm920t->armv4_5_mmu.get_ttb = arm920t_get_ttb; - arm920t->armv4_5_mmu.read_memory = arm7_9_read_memory; - arm920t->armv4_5_mmu.write_memory = arm7_9_write_memory; - arm920t->armv4_5_mmu.disable_mmu_caches = arm920t_disable_mmu_caches; - arm920t->armv4_5_mmu.enable_mmu_caches = arm920t_enable_mmu_caches; - arm920t->armv4_5_mmu.has_tiny_pages = 1; - arm920t->armv4_5_mmu.mmu_enabled = 0; - - /* disabling linefills leads to lockups, so keep them enabled for now - * this doesn't affect correctness, but might affect timing issues, if - * important data is evicted from the cache during the debug session - * */ - arm920t->preserve_cache = 0; - - /* override hw single-step capability from ARM9TDMI */ - arm7_9->has_single_step = 1; - - return ERROR_OK; -} - -static int arm920t_target_create(struct target *target, Jim_Interp *interp) -{ - struct arm920t_common *arm920t; - - arm920t = calloc(1, sizeof(struct arm920t_common)); - return arm920t_init_arch_info(target, arm920t, target->tap); -} - -COMMAND_HANDLER(arm920t_handle_read_cache_command) -{ - int retval = ERROR_OK; - struct target *target = get_current_target(CMD_CTX); - struct arm920t_common *arm920t = target_to_arm920(target); - struct arm7_9_common *arm7_9 = target_to_arm7_9(target); - struct arm *arm = &arm7_9->arm; - uint32_t cp15c15; - uint32_t cp15_ctrl, cp15_ctrl_saved; - uint32_t regs[16]; - uint32_t *regs_p[16]; - uint32_t C15_C_D_Ind, C15_C_I_Ind; - int i; - FILE *output; - int segment, index_t; - struct reg *r; - - retval = arm920t_verify_pointer(CMD_CTX, arm920t); - if (retval != ERROR_OK) - return retval; - - if (CMD_ARGC != 1) - return ERROR_COMMAND_SYNTAX_ERROR; - - output = fopen(CMD_ARGV[0], "w"); - if (output == NULL) { - LOG_DEBUG("error opening cache content file"); - return ERROR_OK; - } - - for (i = 0; i < 16; i++) - regs_p[i] = ®s[i]; - - /* disable MMU and Caches */ - arm920t_read_cp15_physical(target, CP15PHYS_CTRL, &cp15_ctrl); - retval = jtag_execute_queue(); - if (retval != ERROR_OK) - return retval; - cp15_ctrl_saved = cp15_ctrl; - cp15_ctrl &= ~(ARMV4_5_MMU_ENABLED - | ARMV4_5_D_U_CACHE_ENABLED | ARMV4_5_I_CACHE_ENABLED); - arm920t_write_cp15_physical(target, CP15PHYS_CTRL, cp15_ctrl); - - /* read CP15 test state register */ - arm920t_read_cp15_physical(target, CP15PHYS_TESTSTATE, &cp15c15); - jtag_execute_queue(); - - /* read DCache content */ - fprintf(output, "DCache:\n"); - - /* go through segments 0 to nsets (8 on ARM920T, 4 on ARM922T) */ - for (segment = 0; - segment < arm920t->armv4_5_mmu.armv4_5_cache.d_u_size.nsets; - segment++) { - fprintf(output, "\nsegment: %i\n----------", segment); - - /* Ra: r0 = SBZ(31:8):segment(7:5):SBZ(4:0) */ - regs[0] = 0x0 | (segment << 5); - arm9tdmi_write_core_regs(target, 0x1, regs); - - /* set interpret mode */ - cp15c15 |= 0x1; - arm920t_write_cp15_physical(target, - CP15PHYS_TESTSTATE, cp15c15); - - /* D CAM Read, loads current victim into C15.C.D.Ind */ - arm920t_execute_cp15(target, - ARMV4_5_MCR(15, 2, 0, 15, 6, 2), ARMV4_5_LDR(1, 0)); - - /* read current victim */ - arm920t_read_cp15_physical(target, - CP15PHYS_DCACHE_IDX, &C15_C_D_Ind); - - /* clear interpret mode */ - cp15c15 &= ~0x1; - arm920t_write_cp15_physical(target, - CP15PHYS_TESTSTATE, cp15c15); - - for (index_t = 0; index_t < 64; index_t++) { - /* Ra: - * r0 = index(31:26):SBZ(25:8):segment(7:5):SBZ(4:0) - */ - regs[0] = 0x0 | (segment << 5) | (index_t << 26); - arm9tdmi_write_core_regs(target, 0x1, regs); - - /* set interpret mode */ - cp15c15 |= 0x1; - arm920t_write_cp15_physical(target, - CP15PHYS_TESTSTATE, cp15c15); - - /* Write DCache victim */ - arm920t_execute_cp15(target, - ARMV4_5_MCR(15, 0, 0, 9, 1, 0), ARMV4_5_LDR(1, 0)); - - /* Read D RAM */ - arm920t_execute_cp15(target, - ARMV4_5_MCR(15, 2, 0, 15, 10, 2), - ARMV4_5_LDMIA(0, 0x1fe, 0, 0)); - - /* Read D CAM */ - arm920t_execute_cp15(target, - ARMV4_5_MCR(15, 2, 0, 15, 6, 2), - ARMV4_5_LDR(9, 0)); - - /* clear interpret mode */ - cp15c15 &= ~0x1; - arm920t_write_cp15_physical(target, - CP15PHYS_TESTSTATE, cp15c15); - - /* read D RAM and CAM content */ - arm9tdmi_read_core_regs(target, 0x3fe, regs_p); - retval = jtag_execute_queue(); - if (retval != ERROR_OK) - return retval; - - /* mask LFSR[6] */ - regs[9] &= 0xfffffffe; - fprintf(output, "\nsegment: %i, index: %i, CAM: 0x%8.8" - PRIx32 ", content (%s):\n", - segment, index_t, regs[9], - (regs[9] & 0x10) ? "valid" : "invalid"); - - for (i = 1; i < 9; i++) { - fprintf(output, "%i: 0x%8.8" PRIx32 "\n", - i-1, regs[i]); - } - - } - - /* Ra: r0 = index(31:26):SBZ(25:8):segment(7:5):SBZ(4:0) */ - regs[0] = 0x0 | (segment << 5) | (C15_C_D_Ind << 26); - arm9tdmi_write_core_regs(target, 0x1, regs); - - /* set interpret mode */ - cp15c15 |= 0x1; - arm920t_write_cp15_physical(target, - CP15PHYS_TESTSTATE, cp15c15); - - /* Write DCache victim */ - arm920t_execute_cp15(target, - ARMV4_5_MCR(15, 0, 0, 9, 1, 0), ARMV4_5_LDR(1, 0)); - - /* clear interpret mode */ - cp15c15 &= ~0x1; - arm920t_write_cp15_physical(target, - CP15PHYS_TESTSTATE, cp15c15); - } - - /* read ICache content */ - fprintf(output, "ICache:\n"); - - /* go through segments 0 to nsets (8 on ARM920T, 4 on ARM922T) */ - for (segment = 0; - segment < arm920t->armv4_5_mmu.armv4_5_cache.d_u_size.nsets; - segment++) { - fprintf(output, "segment: %i\n----------", segment); - - /* Ra: r0 = SBZ(31:8):segment(7:5):SBZ(4:0) */ - regs[0] = 0x0 | (segment << 5); - arm9tdmi_write_core_regs(target, 0x1, regs); - - /* set interpret mode */ - cp15c15 |= 0x1; - arm920t_write_cp15_physical(target, - CP15PHYS_TESTSTATE, cp15c15); - - /* I CAM Read, loads current victim into C15.C.I.Ind */ - arm920t_execute_cp15(target, - ARMV4_5_MCR(15, 2, 0, 15, 5, 2), ARMV4_5_LDR(1, 0)); - - /* read current victim */ - arm920t_read_cp15_physical(target, CP15PHYS_ICACHE_IDX, - &C15_C_I_Ind); - - /* clear interpret mode */ - cp15c15 &= ~0x1; - arm920t_write_cp15_physical(target, - CP15PHYS_TESTSTATE, cp15c15); - - for (index_t = 0; index_t < 64; index_t++) { - /* Ra: - * r0 = index(31:26):SBZ(25:8):segment(7:5):SBZ(4:0) - */ - regs[0] = 0x0 | (segment << 5) | (index_t << 26); - arm9tdmi_write_core_regs(target, 0x1, regs); - - /* set interpret mode */ - cp15c15 |= 0x1; - arm920t_write_cp15_physical(target, - CP15PHYS_TESTSTATE, cp15c15); - - /* Write ICache victim */ - arm920t_execute_cp15(target, - ARMV4_5_MCR(15, 0, 0, 9, 1, 1), ARMV4_5_LDR(1, 0)); - - /* Read I RAM */ - arm920t_execute_cp15(target, - ARMV4_5_MCR(15, 2, 0, 15, 9, 2), - ARMV4_5_LDMIA(0, 0x1fe, 0, 0)); - - /* Read I CAM */ - arm920t_execute_cp15(target, - ARMV4_5_MCR(15, 2, 0, 15, 5, 2), - ARMV4_5_LDR(9, 0)); - - /* clear interpret mode */ - cp15c15 &= ~0x1; - arm920t_write_cp15_physical(target, - CP15PHYS_TESTSTATE, cp15c15); - - /* read I RAM and CAM content */ - arm9tdmi_read_core_regs(target, 0x3fe, regs_p); - retval = jtag_execute_queue(); - if (retval != ERROR_OK) - return retval; - - /* mask LFSR[6] */ - regs[9] &= 0xfffffffe; - fprintf(output, "\nsegment: %i, index: %i, " - "CAM: 0x%8.8" PRIx32 ", content (%s):\n", - segment, index_t, regs[9], - (regs[9] & 0x10) ? "valid" : "invalid"); - - for (i = 1; i < 9; i++) { - fprintf(output, "%i: 0x%8.8" PRIx32 "\n", - i-1, regs[i]); - } - } - - /* Ra: r0 = index(31:26):SBZ(25:8):segment(7:5):SBZ(4:0) */ - regs[0] = 0x0 | (segment << 5) | (C15_C_D_Ind << 26); - arm9tdmi_write_core_regs(target, 0x1, regs); - - /* set interpret mode */ - cp15c15 |= 0x1; - arm920t_write_cp15_physical(target, - CP15PHYS_TESTSTATE, cp15c15); - - /* Write ICache victim */ - arm920t_execute_cp15(target, - ARMV4_5_MCR(15, 0, 0, 9, 1, 1), ARMV4_5_LDR(1, 0)); - - /* clear interpret mode */ - cp15c15 &= ~0x1; - arm920t_write_cp15_physical(target, - CP15PHYS_TESTSTATE, cp15c15); - } - - /* restore CP15 MMU and Cache settings */ - arm920t_write_cp15_physical(target, CP15PHYS_CTRL, cp15_ctrl_saved); - - command_print(CMD_CTX, "cache content successfully output to %s", - CMD_ARGV[0]); - - fclose(output); - - if (!is_arm_mode(arm->core_mode)) { - LOG_ERROR("not a valid arm core mode - communication failure?"); - return ERROR_FAIL; - } - - /* force writeback of the valid data */ - r = arm->core_cache->reg_list; - r[0].dirty = r[0].valid; - r[1].dirty = r[1].valid; - r[2].dirty = r[2].valid; - r[3].dirty = r[3].valid; - r[4].dirty = r[4].valid; - r[5].dirty = r[5].valid; - r[6].dirty = r[6].valid; - r[7].dirty = r[7].valid; - - r = arm_reg_current(arm, 8); - r->dirty = r->valid; - - r = arm_reg_current(arm, 9); - r->dirty = r->valid; - - return ERROR_OK; -} - -COMMAND_HANDLER(arm920t_handle_read_mmu_command) -{ - int retval = ERROR_OK; - struct target *target = get_current_target(CMD_CTX); - struct arm920t_common *arm920t = target_to_arm920(target); - struct arm7_9_common *arm7_9 = target_to_arm7_9(target); - struct arm *arm = &arm7_9->arm; - uint32_t cp15c15; - uint32_t cp15_ctrl, cp15_ctrl_saved; - uint32_t regs[16]; - uint32_t *regs_p[16]; - int i; - FILE *output; - uint32_t Dlockdown, Ilockdown; - struct arm920t_tlb_entry d_tlb[64], i_tlb[64]; - int victim; - struct reg *r; - - retval = arm920t_verify_pointer(CMD_CTX, arm920t); - if (retval != ERROR_OK) - return retval; - - if (CMD_ARGC != 1) - return ERROR_COMMAND_SYNTAX_ERROR; - - output = fopen(CMD_ARGV[0], "w"); - if (output == NULL) { - LOG_DEBUG("error opening mmu content file"); - return ERROR_OK; - } - - for (i = 0; i < 16; i++) - regs_p[i] = ®s[i]; - - /* disable MMU and Caches */ - arm920t_read_cp15_physical(target, CP15PHYS_CTRL, &cp15_ctrl); - retval = jtag_execute_queue(); - if (retval != ERROR_OK) - return retval; - cp15_ctrl_saved = cp15_ctrl; - cp15_ctrl &= ~(ARMV4_5_MMU_ENABLED - | ARMV4_5_D_U_CACHE_ENABLED | ARMV4_5_I_CACHE_ENABLED); - arm920t_write_cp15_physical(target, CP15PHYS_CTRL, cp15_ctrl); - - /* read CP15 test state register */ - arm920t_read_cp15_physical(target, CP15PHYS_TESTSTATE, &cp15c15); - retval = jtag_execute_queue(); - if (retval != ERROR_OK) - return retval; - - /* prepare reading D TLB content - * */ - - /* set interpret mode */ - cp15c15 |= 0x1; - arm920t_write_cp15_physical(target, CP15PHYS_TESTSTATE, cp15c15); - - /* Read D TLB lockdown */ - arm920t_execute_cp15(target, - ARMV4_5_MRC(15, 0, 0, 10, 0, 0), ARMV4_5_LDR(1, 0)); - - /* clear interpret mode */ - cp15c15 &= ~0x1; - arm920t_write_cp15_physical(target, CP15PHYS_TESTSTATE, cp15c15); - - /* read D TLB lockdown stored to r1 */ - arm9tdmi_read_core_regs(target, 0x2, regs_p); - retval = jtag_execute_queue(); - if (retval != ERROR_OK) - return retval; - Dlockdown = regs[1]; - - for (victim = 0; victim < 64; victim += 8) { - /* new lockdown value: base[31:26]:victim[25:20]:SBZ[19:1]:p[0] - * base remains unchanged, victim goes through entries 0 to 63 - */ - regs[1] = (Dlockdown & 0xfc000000) | (victim << 20); - arm9tdmi_write_core_regs(target, 0x2, regs); - - /* set interpret mode */ - cp15c15 |= 0x1; - arm920t_write_cp15_physical(target, - CP15PHYS_TESTSTATE, cp15c15); - - /* Write D TLB lockdown */ - arm920t_execute_cp15(target, - ARMV4_5_MCR(15, 0, 0, 10, 0, 0), - ARMV4_5_STR(1, 0)); - - /* Read D TLB CAM */ - arm920t_execute_cp15(target, - ARMV4_5_MCR(15, 4, 0, 15, 6, 4), - ARMV4_5_LDMIA(0, 0x3fc, 0, 0)); - - /* clear interpret mode */ - cp15c15 &= ~0x1; - arm920t_write_cp15_physical(target, - CP15PHYS_TESTSTATE, cp15c15); - - /* read D TLB CAM content stored to r2-r9 */ - arm9tdmi_read_core_regs(target, 0x3fc, regs_p); - retval = jtag_execute_queue(); - if (retval != ERROR_OK) - return retval; - - for (i = 0; i < 8; i++) - d_tlb[victim + i].cam = regs[i + 2]; - } - - for (victim = 0; victim < 64; victim++) { - /* new lockdown value: base[31:26]:victim[25:20]:SBZ[19:1]:p[0] - * base remains unchanged, victim goes through entries 0 to 63 - */ - regs[1] = (Dlockdown & 0xfc000000) | (victim << 20); - arm9tdmi_write_core_regs(target, 0x2, regs); - - /* set interpret mode */ - cp15c15 |= 0x1; - arm920t_write_cp15_physical(target, - CP15PHYS_TESTSTATE, cp15c15); - - /* Write D TLB lockdown */ - arm920t_execute_cp15(target, - ARMV4_5_MCR(15, 0, 0, 10, 0, 0), ARMV4_5_STR(1, 0)); - - /* Read D TLB RAM1 */ - arm920t_execute_cp15(target, - ARMV4_5_MCR(15, 4, 0, 15, 10, 4), ARMV4_5_LDR(2, 0)); - - /* Read D TLB RAM2 */ - arm920t_execute_cp15(target, - ARMV4_5_MCR(15, 4, 0, 15, 2, 5), ARMV4_5_LDR(3, 0)); - - /* clear interpret mode */ - cp15c15 &= ~0x1; - arm920t_write_cp15_physical(target, - CP15PHYS_TESTSTATE, cp15c15); - - /* read D TLB RAM content stored to r2 and r3 */ - arm9tdmi_read_core_regs(target, 0xc, regs_p); - retval = jtag_execute_queue(); - if (retval != ERROR_OK) - return retval; - - d_tlb[victim].ram1 = regs[2]; - d_tlb[victim].ram2 = regs[3]; - } - - /* restore D TLB lockdown */ - regs[1] = Dlockdown; - arm9tdmi_write_core_regs(target, 0x2, regs); - - /* Write D TLB lockdown */ - arm920t_execute_cp15(target, - ARMV4_5_MCR(15, 0, 0, 10, 0, 0), ARMV4_5_STR(1, 0)); - - /* prepare reading I TLB content - * */ - - /* set interpret mode */ - cp15c15 |= 0x1; - arm920t_write_cp15_physical(target, CP15PHYS_TESTSTATE, cp15c15); - - /* Read I TLB lockdown */ - arm920t_execute_cp15(target, - ARMV4_5_MRC(15, 0, 0, 10, 0, 1), ARMV4_5_LDR(1, 0)); - - /* clear interpret mode */ - cp15c15 &= ~0x1; - arm920t_write_cp15_physical(target, CP15PHYS_TESTSTATE, cp15c15); - - /* read I TLB lockdown stored to r1 */ - arm9tdmi_read_core_regs(target, 0x2, regs_p); - retval = jtag_execute_queue(); - if (retval != ERROR_OK) - return retval; - Ilockdown = regs[1]; - - for (victim = 0; victim < 64; victim += 8) { - /* new lockdown value: base[31:26]:victim[25:20]:SBZ[19:1]:p[0] - * base remains unchanged, victim goes through entries 0 to 63 - */ - regs[1] = (Ilockdown & 0xfc000000) | (victim << 20); - arm9tdmi_write_core_regs(target, 0x2, regs); - - /* set interpret mode */ - cp15c15 |= 0x1; - arm920t_write_cp15_physical(target, - CP15PHYS_TESTSTATE, cp15c15); - - /* Write I TLB lockdown */ - arm920t_execute_cp15(target, - ARMV4_5_MCR(15, 0, 0, 10, 0, 1), - ARMV4_5_STR(1, 0)); - - /* Read I TLB CAM */ - arm920t_execute_cp15(target, - ARMV4_5_MCR(15, 4, 0, 15, 5, 4), - ARMV4_5_LDMIA(0, 0x3fc, 0, 0)); - - /* clear interpret mode */ - cp15c15 &= ~0x1; - arm920t_write_cp15_physical(target, - CP15PHYS_TESTSTATE, cp15c15); - - /* read I TLB CAM content stored to r2-r9 */ - arm9tdmi_read_core_regs(target, 0x3fc, regs_p); - retval = jtag_execute_queue(); - if (retval != ERROR_OK) - return retval; - - for (i = 0; i < 8; i++) - i_tlb[i + victim].cam = regs[i + 2]; - } - - for (victim = 0; victim < 64; victim++) { - /* new lockdown value: base[31:26]:victim[25:20]:SBZ[19:1]:p[0] - * base remains unchanged, victim goes through entries 0 to 63 - */ - regs[1] = (Dlockdown & 0xfc000000) | (victim << 20); - arm9tdmi_write_core_regs(target, 0x2, regs); - - /* set interpret mode */ - cp15c15 |= 0x1; - arm920t_write_cp15_physical(target, - CP15PHYS_TESTSTATE, cp15c15); - - /* Write I TLB lockdown */ - arm920t_execute_cp15(target, - ARMV4_5_MCR(15, 0, 0, 10, 0, 1), ARMV4_5_STR(1, 0)); - - /* Read I TLB RAM1 */ - arm920t_execute_cp15(target, - ARMV4_5_MCR(15, 4, 0, 15, 9, 4), ARMV4_5_LDR(2, 0)); - - /* Read I TLB RAM2 */ - arm920t_execute_cp15(target, - ARMV4_5_MCR(15, 4, 0, 15, 1, 5), ARMV4_5_LDR(3, 0)); - - /* clear interpret mode */ - cp15c15 &= ~0x1; - arm920t_write_cp15_physical(target, - CP15PHYS_TESTSTATE, cp15c15); - - /* read I TLB RAM content stored to r2 and r3 */ - arm9tdmi_read_core_regs(target, 0xc, regs_p); - retval = jtag_execute_queue(); - if (retval != ERROR_OK) - return retval; - - i_tlb[victim].ram1 = regs[2]; - i_tlb[victim].ram2 = regs[3]; - } - - /* restore I TLB lockdown */ - regs[1] = Ilockdown; - arm9tdmi_write_core_regs(target, 0x2, regs); - - /* Write I TLB lockdown */ - arm920t_execute_cp15(target, - ARMV4_5_MCR(15, 0, 0, 10, 0, 1), ARMV4_5_STR(1, 0)); - - /* restore CP15 MMU and Cache settings */ - arm920t_write_cp15_physical(target, CP15PHYS_CTRL, cp15_ctrl_saved); - - /* output data to file */ - fprintf(output, "D TLB content:\n"); - for (i = 0; i < 64; i++) { - fprintf(output, "%i: 0x%8.8" PRIx32 " 0x%8.8" PRIx32 - " 0x%8.8" PRIx32 " %s\n", - i, d_tlb[i].cam, d_tlb[i].ram1, d_tlb[i].ram2, - (d_tlb[i].cam & 0x20) ? "(valid)" : "(invalid)"); - } - - fprintf(output, "\n\nI TLB content:\n"); - for (i = 0; i < 64; i++) { - fprintf(output, "%i: 0x%8.8" PRIx32 " 0x%8.8" PRIx32 - " 0x%8.8" PRIx32 " %s\n", - i, i_tlb[i].cam, i_tlb[i].ram1, i_tlb[i].ram2, - (i_tlb[i].cam & 0x20) ? "(valid)" : "(invalid)"); - } - - command_print(CMD_CTX, "mmu content successfully output to %s", - CMD_ARGV[0]); - - fclose(output); - - if (!is_arm_mode(arm->core_mode)) { - LOG_ERROR("not a valid arm core mode - communication failure?"); - return ERROR_FAIL; - } - - /* force writeback of the valid data */ - r = arm->core_cache->reg_list; - r[0].dirty = r[0].valid; - r[1].dirty = r[1].valid; - r[2].dirty = r[2].valid; - r[3].dirty = r[3].valid; - r[4].dirty = r[4].valid; - r[5].dirty = r[5].valid; - r[6].dirty = r[6].valid; - r[7].dirty = r[7].valid; - - r = arm_reg_current(arm, 8); - r->dirty = r->valid; - - r = arm_reg_current(arm, 9); - r->dirty = r->valid; - - return ERROR_OK; -} - -COMMAND_HANDLER(arm920t_handle_cp15_command) -{ - int retval; - struct target *target = get_current_target(CMD_CTX); - struct arm920t_common *arm920t = target_to_arm920(target); - - retval = arm920t_verify_pointer(CMD_CTX, arm920t); - if (retval != ERROR_OK) - return retval; - - if (target->state != TARGET_HALTED) { - command_print(CMD_CTX, "target must be stopped for " - "\"%s\" command", CMD_NAME); - return ERROR_OK; - } - - /* one argument, read a register. - * two arguments, write it. - */ - if (CMD_ARGC >= 1) { - int address; - COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], address); - - if (CMD_ARGC == 1) { - uint32_t value; - retval = arm920t_read_cp15_physical(target, address, &value); - if (retval != ERROR_OK) { - command_print(CMD_CTX, - "couldn't access reg %i", address); - return ERROR_OK; - } - retval = jtag_execute_queue(); - if (retval != ERROR_OK) - return retval; - - command_print(CMD_CTX, "%i: %8.8" PRIx32, - address, value); - } else if (CMD_ARGC == 2) { - uint32_t value; - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], value); - retval = arm920t_write_cp15_physical(target, - address, value); - if (retval != ERROR_OK) { - command_print(CMD_CTX, - "couldn't access reg %i", address); - /* REVISIT why lie? "return retval"? */ - return ERROR_OK; - } - command_print(CMD_CTX, "%i: %8.8" PRIx32, - address, value); - } - } - - return ERROR_OK; -} - -COMMAND_HANDLER(arm920t_handle_cp15i_command) -{ - int retval; - struct target *target = get_current_target(CMD_CTX); - struct arm920t_common *arm920t = target_to_arm920(target); - - retval = arm920t_verify_pointer(CMD_CTX, arm920t); - if (retval != ERROR_OK) - return retval; - - - if (target->state != TARGET_HALTED) { - command_print(CMD_CTX, "target must be stopped for " - "\"%s\" command", CMD_NAME); - return ERROR_OK; - } - - /* one argument, read a register. - * two arguments, write it. - */ - if (CMD_ARGC >= 1) { - uint32_t opcode; - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], opcode); - - if (CMD_ARGC == 1) { - uint32_t value; - retval = arm920t_read_cp15_interpreted(target, - opcode, 0x0, &value); - if (retval != ERROR_OK) { - command_print(CMD_CTX, - "couldn't execute %8.8" PRIx32, - opcode); - /* REVISIT why lie? "return retval"? */ - return ERROR_OK; - } - - command_print(CMD_CTX, "%8.8" PRIx32 ": %8.8" PRIx32, - opcode, value); - } else if (CMD_ARGC == 2) { - uint32_t value; - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], value); - retval = arm920t_write_cp15_interpreted(target, - opcode, value, 0); - if (retval != ERROR_OK) { - command_print(CMD_CTX, - "couldn't execute %8.8" PRIx32, - opcode); - /* REVISIT why lie? "return retval"? */ - return ERROR_OK; - } - command_print(CMD_CTX, "%8.8" PRIx32 ": %8.8" PRIx32, - opcode, value); - } else if (CMD_ARGC == 3) { - uint32_t value; - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], value); - uint32_t address; - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], address); - retval = arm920t_write_cp15_interpreted(target, - opcode, value, address); - if (retval != ERROR_OK) { - command_print(CMD_CTX, - "couldn't execute %8.8" PRIx32, opcode); - /* REVISIT why lie? "return retval"? */ - return ERROR_OK; - } - command_print(CMD_CTX, "%8.8" PRIx32 ": %8.8" PRIx32 - " %8.8" PRIx32, opcode, value, address); - } - } else - return ERROR_COMMAND_SYNTAX_ERROR; - - return ERROR_OK; -} - -COMMAND_HANDLER(arm920t_handle_cache_info_command) -{ - int retval; - struct target *target = get_current_target(CMD_CTX); - struct arm920t_common *arm920t = target_to_arm920(target); - - retval = arm920t_verify_pointer(CMD_CTX, arm920t); - if (retval != ERROR_OK) - return retval; - - return armv4_5_handle_cache_info_command(CMD_CTX, - &arm920t->armv4_5_mmu.armv4_5_cache); -} - - -static int arm920t_mrc(struct target *target, int cpnum, - uint32_t op1, uint32_t op2, - uint32_t CRn, uint32_t CRm, - uint32_t *value) -{ - if (cpnum != 15) { - LOG_ERROR("Only cp15 is supported"); - return ERROR_FAIL; - } - - /* read "to" r0 */ - return arm920t_read_cp15_interpreted(target, - ARMV4_5_MRC(cpnum, op1, 0, CRn, CRm, op2), - 0, value); -} - -static int arm920t_mcr(struct target *target, int cpnum, - uint32_t op1, uint32_t op2, - uint32_t CRn, uint32_t CRm, - uint32_t value) -{ - if (cpnum != 15) { - LOG_ERROR("Only cp15 is supported"); - return ERROR_FAIL; - } - - /* write "from" r0 */ - return arm920t_write_cp15_interpreted(target, - ARMV4_5_MCR(cpnum, op1, 0, CRn, CRm, op2), - 0, value); -} - -static const struct command_registration arm920t_exec_command_handlers[] = { - { - .name = "cp15", - .handler = arm920t_handle_cp15_command, - .mode = COMMAND_EXEC, - .help = "display/modify cp15 register", - .usage = "regnum [value]", - }, - { - .name = "cp15i", - .handler = arm920t_handle_cp15i_command, - .mode = COMMAND_EXEC, - /* prefer using less error-prone "arm mcr" or "arm mrc" */ - .help = "display/modify cp15 register using ARM opcode" - " (DEPRECATED)", - .usage = "instruction [value [address]]", - }, - { - .name = "cache_info", - .handler = arm920t_handle_cache_info_command, - .mode = COMMAND_EXEC, - .usage = "", - .help = "display information about target caches", - }, - { - .name = "read_cache", - .handler = arm920t_handle_read_cache_command, - .mode = COMMAND_EXEC, - .help = "dump I/D cache content to file", - .usage = "filename", - }, - { - .name = "read_mmu", - .handler = arm920t_handle_read_mmu_command, - .mode = COMMAND_EXEC, - .help = "dump I/D mmu content to file", - .usage = "filename", - }, - COMMAND_REGISTRATION_DONE -}; -const struct command_registration arm920t_command_handlers[] = { - { - .chain = arm9tdmi_command_handlers, - }, - { - .name = "arm920t", - .mode = COMMAND_ANY, - .help = "arm920t command group", - .usage = "", - .chain = arm920t_exec_command_handlers, - }, - COMMAND_REGISTRATION_DONE -}; - -/** Holds methods for ARM920 targets. */ -struct target_type arm920t_target = { - .name = "arm920t", - - .poll = arm7_9_poll, - .arch_state = arm920t_arch_state, - - .target_request_data = arm7_9_target_request_data, - - .halt = arm7_9_halt, - .resume = arm7_9_resume, - .step = arm7_9_step, - - .assert_reset = arm7_9_assert_reset, - .deassert_reset = arm7_9_deassert_reset, - .soft_reset_halt = arm920t_soft_reset_halt, - - .get_gdb_reg_list = arm_get_gdb_reg_list, - - .read_memory = arm920t_read_memory, - .write_memory = arm7_9_write_memory_opt, - .read_phys_memory = arm920t_read_phys_memory, - .write_phys_memory = arm920t_write_phys_memory, - .mmu = arm920_mmu, - .virt2phys = arm920_virt2phys, - - .checksum_memory = arm_checksum_memory, - .blank_check_memory = arm_blank_check_memory, - - .run_algorithm = armv4_5_run_algorithm, - - .add_breakpoint = arm7_9_add_breakpoint, - .remove_breakpoint = arm7_9_remove_breakpoint, - .add_watchpoint = arm7_9_add_watchpoint, - .remove_watchpoint = arm7_9_remove_watchpoint, - - .commands = arm920t_command_handlers, - .target_create = arm920t_target_create, - .init_target = arm9tdmi_init_target, - .examine = arm7_9_examine, - .check_reset = arm7_9_check_reset, -}; diff --git a/src/target/arm920t.h b/src/target/arm920t.h deleted file mode 100644 index 3401b0945..000000000 --- a/src/target/arm920t.h +++ /dev/null @@ -1,71 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifndef OPENOCD_TARGET_ARM920T_H -#define OPENOCD_TARGET_ARM920T_H - -#include "arm9tdmi.h" -#include "armv4_5_mmu.h" - -#define ARM920T_COMMON_MAGIC 0xa920a920 - -struct arm920t_common { - struct arm7_9_common arm7_9_common; - uint32_t common_magic; - struct armv4_5_mmu_common armv4_5_mmu; - uint32_t cp15_control_reg; - uint32_t d_fsr; - uint32_t i_fsr; - uint32_t d_far; - uint32_t i_far; - int preserve_cache; -}; - -static inline struct arm920t_common *target_to_arm920(struct target *target) -{ - return container_of(target->arch_info, struct arm920t_common, arm7_9_common.arm); -} - -struct arm920t_cache_line { - uint32_t cam; - uint32_t data[8]; -}; - -struct arm920t_tlb_entry { - uint32_t cam; - uint32_t ram1; - uint32_t ram2; -}; - -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); -int arm920t_write_memory(struct target *target, - uint32_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); -int arm920t_disable_mmu_caches(struct target *target, - int mmu, int d_u_cache, int i_cache); -int arm920t_enable_mmu_caches(struct target *target, - int mmu, int d_u_cache, int i_cache); - -extern const struct command_registration arm920t_command_handlers[]; - -#endif /* OPENOCD_TARGET_ARM920T_H */ diff --git a/src/target/arm926ejs.c b/src/target/arm926ejs.c deleted file mode 100644 index d7c043e80..000000000 --- a/src/target/arm926ejs.c +++ /dev/null @@ -1,832 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * Copyright (C) 2007,2008,2009 by Øyvind Harboe * - * oyvind.harboe@zylin.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "arm926ejs.h" -#include -#include "target_type.h" -#include "register.h" -#include "arm_opcodes.h" - - -/* - * The ARM926 is built around the ARM9EJ-S core, and most JTAG docs - * are in the ARM9EJ-S Technical Reference Manual (ARM DDI 0222B) not - * the ARM926 manual (ARM DDI 0198E). The scan chains are: - * - * 1 ... core debugging - * 2 ... EmbeddedICE - * 3 ... external boundary scan (SoC-specific, unused here) - * 6 ... ETM - * 15 ... coprocessor 15 - */ - -#if 0 -#define _DEBUG_INSTRUCTION_EXECUTION_ -#endif - -#define ARM926EJS_CP15_ADDR(opcode_1, opcode_2, CRn, CRm) ((opcode_1 << 11) | (opcode_2 << 8) | (CRn << 4) | (CRm << 0)) - -static int arm926ejs_cp15_read(struct target *target, uint32_t op1, uint32_t op2, - uint32_t CRn, uint32_t CRm, uint32_t *value) -{ - int retval = ERROR_OK; - struct arm7_9_common *arm7_9 = target_to_arm7_9(target); - struct arm_jtag *jtag_info = &arm7_9->jtag_info; - uint32_t address = ARM926EJS_CP15_ADDR(op1, op2, CRn, CRm); - struct scan_field fields[4]; - uint8_t address_buf[2] = {0, 0}; - uint8_t nr_w_buf = 0; - uint8_t access_t = 1; - - buf_set_u32(address_buf, 0, 14, address); - - retval = arm_jtag_scann(jtag_info, 0xf, TAP_IDLE); - if (retval != ERROR_OK) - return retval; - retval = arm_jtag_set_instr(jtag_info->tap, jtag_info->intest_instr, NULL, TAP_IDLE); - if (retval != ERROR_OK) - return retval; - - fields[0].num_bits = 32; - fields[0].out_value = NULL; - fields[0].in_value = (uint8_t *)value; - - fields[1].num_bits = 1; - fields[1].out_value = &access_t; - fields[1].in_value = &access_t; - - fields[2].num_bits = 14; - fields[2].out_value = address_buf; - fields[2].in_value = NULL; - - fields[3].num_bits = 1; - fields[3].out_value = &nr_w_buf; - fields[3].in_value = NULL; - - jtag_add_dr_scan(jtag_info->tap, 4, fields, TAP_IDLE); - - int64_t then = timeval_ms(); - - for (;;) { - /* rescan with NOP, to wait for the access to complete */ - access_t = 0; - nr_w_buf = 0; - jtag_add_dr_scan(jtag_info->tap, 4, fields, TAP_IDLE); - - jtag_add_callback(arm_le_to_h_u32, (jtag_callback_data_t)value); - - retval = jtag_execute_queue(); - if (retval != ERROR_OK) - return retval; - - if (buf_get_u32(&access_t, 0, 1) == 1) - break; - - /* 10ms timeout */ - if ((timeval_ms()-then) > 10) { - LOG_ERROR("cp15 read operation timed out"); - return ERROR_FAIL; - } - } - -#ifdef _DEBUG_INSTRUCTION_EXECUTION_ - LOG_DEBUG("addr: 0x%x value: %8.8x", address, *value); -#endif - - retval = arm_jtag_set_instr(jtag_info->tap, 0xc, NULL, TAP_IDLE); - if (retval != ERROR_OK) - return retval; - - return ERROR_OK; -} - -static int arm926ejs_mrc(struct target *target, int cpnum, uint32_t op1, - uint32_t op2, uint32_t CRn, uint32_t CRm, uint32_t *value) -{ - if (cpnum != 15) { - LOG_ERROR("Only cp15 is supported"); - return ERROR_FAIL; - } - return arm926ejs_cp15_read(target, op1, op2, CRn, CRm, value); -} - -static int arm926ejs_cp15_write(struct target *target, uint32_t op1, uint32_t op2, - uint32_t CRn, uint32_t CRm, uint32_t value) -{ - int retval = ERROR_OK; - struct arm7_9_common *arm7_9 = target_to_arm7_9(target); - struct arm_jtag *jtag_info = &arm7_9->jtag_info; - uint32_t address = ARM926EJS_CP15_ADDR(op1, op2, CRn, CRm); - struct scan_field fields[4]; - uint8_t value_buf[4]; - uint8_t address_buf[2] = {0, 0}; - uint8_t nr_w_buf = 1; - uint8_t access_t = 1; - - buf_set_u32(address_buf, 0, 14, address); - buf_set_u32(value_buf, 0, 32, value); - - retval = arm_jtag_scann(jtag_info, 0xf, TAP_IDLE); - if (retval != ERROR_OK) - return retval; - retval = arm_jtag_set_instr(jtag_info->tap, jtag_info->intest_instr, NULL, TAP_IDLE); - if (retval != ERROR_OK) - return retval; - - fields[0].num_bits = 32; - fields[0].out_value = value_buf; - fields[0].in_value = NULL; - - fields[1].num_bits = 1; - fields[1].out_value = &access_t; - fields[1].in_value = &access_t; - - fields[2].num_bits = 14; - fields[2].out_value = address_buf; - fields[2].in_value = NULL; - - fields[3].num_bits = 1; - fields[3].out_value = &nr_w_buf; - fields[3].in_value = NULL; - - jtag_add_dr_scan(jtag_info->tap, 4, fields, TAP_IDLE); - - int64_t then = timeval_ms(); - - for (;;) { - /* rescan with NOP, to wait for the access to complete */ - access_t = 0; - nr_w_buf = 0; - jtag_add_dr_scan(jtag_info->tap, 4, fields, TAP_IDLE); - retval = jtag_execute_queue(); - if (retval != ERROR_OK) - return retval; - - if (buf_get_u32(&access_t, 0, 1) == 1) - break; - - /* 10ms timeout */ - if ((timeval_ms()-then) > 10) { - LOG_ERROR("cp15 write operation timed out"); - return ERROR_FAIL; - } - } - -#ifdef _DEBUG_INSTRUCTION_EXECUTION_ - LOG_DEBUG("addr: 0x%x value: %8.8x", address, value); -#endif - - retval = arm_jtag_set_instr(jtag_info->tap, 0xf, NULL, TAP_IDLE); - if (retval != ERROR_OK) - return retval; - - return ERROR_OK; -} - -static int arm926ejs_mcr(struct target *target, int cpnum, uint32_t op1, - uint32_t op2, uint32_t CRn, uint32_t CRm, uint32_t value) -{ - if (cpnum != 15) { - LOG_ERROR("Only cp15 is supported"); - return ERROR_FAIL; - } - return arm926ejs_cp15_write(target, op1, op2, CRn, CRm, value); -} - -static int arm926ejs_examine_debug_reason(struct target *target) -{ - struct arm7_9_common *arm7_9 = target_to_arm7_9(target); - struct reg *dbg_stat = &arm7_9->eice_cache->reg_list[EICE_DBG_STAT]; - int debug_reason; - int retval; - - embeddedice_read_reg(dbg_stat); - retval = jtag_execute_queue(); - if (retval != ERROR_OK) - return retval; - - /* Method-Of-Entry (MOE) field */ - debug_reason = buf_get_u32(dbg_stat->value, 6, 4); - - switch (debug_reason) { - case 0: - LOG_DEBUG("no *NEW* debug entry (?missed one?)"); - /* ... since last restart or debug reset ... */ - target->debug_reason = DBG_REASON_DBGRQ; - break; - case 1: - LOG_DEBUG("breakpoint from EICE unit 0"); - target->debug_reason = DBG_REASON_BREAKPOINT; - break; - case 2: - LOG_DEBUG("breakpoint from EICE unit 1"); - target->debug_reason = DBG_REASON_BREAKPOINT; - break; - case 3: - LOG_DEBUG("soft breakpoint (BKPT instruction)"); - target->debug_reason = DBG_REASON_BREAKPOINT; - break; - case 4: - LOG_DEBUG("vector catch breakpoint"); - target->debug_reason = DBG_REASON_BREAKPOINT; - break; - case 5: - LOG_DEBUG("external breakpoint"); - target->debug_reason = DBG_REASON_BREAKPOINT; - break; - case 6: - LOG_DEBUG("watchpoint from EICE unit 0"); - target->debug_reason = DBG_REASON_WATCHPOINT; - break; - case 7: - LOG_DEBUG("watchpoint from EICE unit 1"); - target->debug_reason = DBG_REASON_WATCHPOINT; - break; - case 8: - LOG_DEBUG("external watchpoint"); - target->debug_reason = DBG_REASON_WATCHPOINT; - break; - case 9: - LOG_DEBUG("internal debug request"); - target->debug_reason = DBG_REASON_DBGRQ; - break; - case 10: - LOG_DEBUG("external debug request"); - target->debug_reason = DBG_REASON_DBGRQ; - break; - case 11: - LOG_DEBUG("debug re-entry from system speed access"); - /* This is normal when connecting to something that's - * already halted, or in some related code paths, but - * otherwise is surprising (and presumably wrong). - */ - switch (target->debug_reason) { - case DBG_REASON_DBGRQ: - break; - default: - LOG_ERROR("unexpected -- debug re-entry"); - /* FALLTHROUGH */ - case DBG_REASON_UNDEFINED: - target->debug_reason = DBG_REASON_DBGRQ; - break; - } - break; - case 12: - /* FIX!!!! here be dragons!!! We need to fail here so - * the target will interpreted as halted but we won't - * try to talk to it right now... a resume + halt seems - * to sync things up again. Please send an email to - * openocd development mailing list if you have hardware - * to donate to look into this problem.... - */ - LOG_WARNING("WARNING: mystery debug reason MOE = 0xc. Try issuing a resume + halt."); - target->debug_reason = DBG_REASON_DBGRQ; - break; - default: - LOG_WARNING("WARNING: unknown debug reason: 0x%x", debug_reason); - /* Oh agony! should we interpret this as a halt request or - * that the target stopped on it's own accord? - */ - target->debug_reason = DBG_REASON_DBGRQ; - /* if we fail here, we won't talk to the target and it will - * be reported to be in the halted state */ - break; - } - - return ERROR_OK; -} - -static int arm926ejs_get_ttb(struct target *target, uint32_t *result) -{ - struct arm926ejs_common *arm926ejs = target_to_arm926(target); - int retval; - uint32_t ttb = 0x0; - - retval = arm926ejs->read_cp15(target, 0, 0, 2, 0, &ttb); - if (retval != ERROR_OK) - return retval; - - *result = ttb; - - return ERROR_OK; -} - -static int arm926ejs_disable_mmu_caches(struct target *target, int mmu, - int d_u_cache, int i_cache) -{ - struct arm926ejs_common *arm926ejs = target_to_arm926(target); - uint32_t cp15_control; - int retval; - - /* read cp15 control register */ - retval = arm926ejs->read_cp15(target, 0, 0, 1, 0, &cp15_control); - if (retval != ERROR_OK) - return retval; - retval = jtag_execute_queue(); - if (retval != ERROR_OK) - return retval; - - if (mmu) { - /* invalidate TLB */ - retval = arm926ejs->write_cp15(target, 0, 0, 8, 7, 0x0); - if (retval != ERROR_OK) - return retval; - - cp15_control &= ~0x1U; - } - - if (d_u_cache) { - uint32_t debug_override; - /* read-modify-write CP15 debug override register - * to enable "test and clean all" */ - retval = arm926ejs->read_cp15(target, 0, 0, 15, 0, &debug_override); - if (retval != ERROR_OK) - return retval; - debug_override |= 0x80000; - retval = arm926ejs->write_cp15(target, 0, 0, 15, 0, debug_override); - if (retval != ERROR_OK) - return retval; - - /* clean and invalidate DCache */ - retval = arm926ejs->write_cp15(target, 0, 0, 7, 5, 0x0); - if (retval != ERROR_OK) - return retval; - - /* write CP15 debug override register - * to disable "test and clean all" */ - debug_override &= ~0x80000; - retval = arm926ejs->write_cp15(target, 0, 0, 15, 0, debug_override); - if (retval != ERROR_OK) - return retval; - - cp15_control &= ~0x4U; - } - - if (i_cache) { - /* invalidate ICache */ - retval = arm926ejs->write_cp15(target, 0, 0, 7, 5, 0x0); - if (retval != ERROR_OK) - return retval; - - cp15_control &= ~0x1000U; - } - - retval = arm926ejs->write_cp15(target, 0, 0, 1, 0, cp15_control); - return retval; -} - -static int arm926ejs_enable_mmu_caches(struct target *target, int mmu, - int d_u_cache, int i_cache) -{ - struct arm926ejs_common *arm926ejs = target_to_arm926(target); - uint32_t cp15_control; - int retval; - - /* read cp15 control register */ - retval = arm926ejs->read_cp15(target, 0, 0, 1, 0, &cp15_control); - if (retval != ERROR_OK) - return retval; - retval = jtag_execute_queue(); - if (retval != ERROR_OK) - return retval; - - if (mmu) - cp15_control |= 0x1U; - - if (d_u_cache) - cp15_control |= 0x4U; - - if (i_cache) - cp15_control |= 0x1000U; - - retval = arm926ejs->write_cp15(target, 0, 0, 1, 0, cp15_control); - return retval; -} - -static int arm926ejs_post_debug_entry(struct target *target) -{ - struct arm926ejs_common *arm926ejs = target_to_arm926(target); - int retval; - - /* examine cp15 control reg */ - retval = arm926ejs->read_cp15(target, 0, 0, 1, 0, &arm926ejs->cp15_control_reg); - if (retval != ERROR_OK) - return retval; - retval = jtag_execute_queue(); - if (retval != ERROR_OK) - return retval; - LOG_DEBUG("cp15_control_reg: %8.8" PRIx32 "", arm926ejs->cp15_control_reg); - - if (arm926ejs->armv4_5_mmu.armv4_5_cache.ctype == -1) { - uint32_t cache_type_reg; - /* identify caches */ - retval = arm926ejs->read_cp15(target, 0, 1, 0, 0, &cache_type_reg); - if (retval != ERROR_OK) - return retval; - retval = jtag_execute_queue(); - if (retval != ERROR_OK) - return retval; - armv4_5_identify_cache(cache_type_reg, &arm926ejs->armv4_5_mmu.armv4_5_cache); - } - - arm926ejs->armv4_5_mmu.mmu_enabled = (arm926ejs->cp15_control_reg & 0x1U) ? 1 : 0; - arm926ejs->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled = (arm926ejs->cp15_control_reg & 0x4U) ? 1 : 0; - arm926ejs->armv4_5_mmu.armv4_5_cache.i_cache_enabled = (arm926ejs->cp15_control_reg & 0x1000U) ? 1 : 0; - - /* save i/d fault status and address register */ - retval = arm926ejs->read_cp15(target, 0, 0, 5, 0, &arm926ejs->d_fsr); - if (retval != ERROR_OK) - return retval; - retval = arm926ejs->read_cp15(target, 0, 1, 5, 0, &arm926ejs->i_fsr); - if (retval != ERROR_OK) - return retval; - retval = arm926ejs->read_cp15(target, 0, 0, 6, 0, &arm926ejs->d_far); - if (retval != ERROR_OK) - return retval; - - LOG_DEBUG("D FSR: 0x%8.8" PRIx32 ", D FAR: 0x%8.8" PRIx32 ", I FSR: 0x%8.8" PRIx32 "", - arm926ejs->d_fsr, arm926ejs->d_far, arm926ejs->i_fsr); - - uint32_t cache_dbg_ctrl; - - /* read-modify-write CP15 cache debug control register - * to disable I/D-cache linefills and force WT */ - retval = arm926ejs->read_cp15(target, 7, 0, 15, 0, &cache_dbg_ctrl); - if (retval != ERROR_OK) - return retval; - cache_dbg_ctrl |= 0x7; - retval = arm926ejs->write_cp15(target, 7, 0, 15, 0, cache_dbg_ctrl); - return retval; -} - -static void arm926ejs_pre_restore_context(struct target *target) -{ - struct arm926ejs_common *arm926ejs = target_to_arm926(target); - - /* restore i/d fault status and address register */ - arm926ejs->write_cp15(target, 0, 0, 5, 0, arm926ejs->d_fsr); - arm926ejs->write_cp15(target, 0, 1, 5, 0, arm926ejs->i_fsr); - arm926ejs->write_cp15(target, 0, 0, 6, 0, arm926ejs->d_far); - - uint32_t cache_dbg_ctrl; - - /* read-modify-write CP15 cache debug control register - * to reenable I/D-cache linefills and disable WT */ - arm926ejs->read_cp15(target, 7, 0, 15, 0, &cache_dbg_ctrl); - cache_dbg_ctrl &= ~0x7; - arm926ejs->write_cp15(target, 7, 0, 15, 0, cache_dbg_ctrl); -} - -static const char arm926_not[] = "target is not an ARM926"; - -static int arm926ejs_verify_pointer(struct command_context *cmd_ctx, - struct arm926ejs_common *arm926) -{ - if (arm926->common_magic != ARM926EJS_COMMON_MAGIC) { - command_print(cmd_ctx, arm926_not); - return ERROR_TARGET_INVALID; - } - return ERROR_OK; -} - -/** Logs summary of ARM926 state for a halted target. */ -int arm926ejs_arch_state(struct target *target) -{ - static const char *state[] = { - "disabled", "enabled" - }; - - struct arm926ejs_common *arm926ejs = target_to_arm926(target); - - if (arm926ejs->common_magic != ARM926EJS_COMMON_MAGIC) { - LOG_ERROR("BUG: %s", arm926_not); - return ERROR_TARGET_INVALID; - } - - arm_arch_state(target); - LOG_USER("MMU: %s, D-Cache: %s, I-Cache: %s", - state[arm926ejs->armv4_5_mmu.mmu_enabled], - state[arm926ejs->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled], - state[arm926ejs->armv4_5_mmu.armv4_5_cache.i_cache_enabled]); - - return ERROR_OK; -} - -int arm926ejs_soft_reset_halt(struct target *target) -{ - int retval = ERROR_OK; - struct arm926ejs_common *arm926ejs = target_to_arm926(target); - struct arm7_9_common *arm7_9 = target_to_arm7_9(target); - struct arm *arm = &arm7_9->arm; - struct reg *dbg_stat = &arm7_9->eice_cache->reg_list[EICE_DBG_STAT]; - - retval = target_halt(target); - if (retval != ERROR_OK) - return retval; - - 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) { - embeddedice_read_reg(dbg_stat); - retval = jtag_execute_queue(); - if (retval != ERROR_OK) - return retval; - } else - break; - if (debug_level >= 1) { - /* do not eat all CPU, time out after 1 se*/ - alive_sleep(100); - } else - keep_alive(); - } - if (timeout) { - LOG_ERROR("Failed to halt CPU after 1 sec"); - return ERROR_TARGET_TIMEOUT; - } - - target->state = TARGET_HALTED; - - /* SVC, ARM state, IRQ and FIQ disabled */ - uint32_t cpsr; - - cpsr = buf_get_u32(arm->cpsr->value, 0, 32); - cpsr &= ~0xff; - cpsr |= 0xd3; - arm_set_cpsr(arm, cpsr); - arm->cpsr->dirty = 1; - - /* start fetching from 0x0 */ - buf_set_u32(arm->pc->value, 0, 32, 0x0); - arm->pc->dirty = 1; - arm->pc->valid = 1; - - retval = arm926ejs_disable_mmu_caches(target, 1, 1, 1); - if (retval != ERROR_OK) - return retval; - arm926ejs->armv4_5_mmu.mmu_enabled = 0; - arm926ejs->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled = 0; - arm926ejs->armv4_5_mmu.armv4_5_cache.i_cache_enabled = 0; - - return target_call_event_callbacks(target, TARGET_EVENT_HALTED); -} - -/** Writes a buffer, in the specified word size, with current MMU settings. */ -int arm926ejs_write_memory(struct target *target, uint32_t address, - uint32_t size, uint32_t count, const uint8_t *buffer) -{ - int retval; - struct arm926ejs_common *arm926ejs = target_to_arm926(target); - - /* FIX!!!! this should be cleaned up and made much more general. The - * plan is to write up and test on arm926ejs specifically and - * then generalize and clean up afterwards. - * - * - * Also it should be moved to the callbacks that handle breakpoints - * specifically and not the generic memory write fn's. See XScale code. - **/ - if (arm926ejs->armv4_5_mmu.mmu_enabled && (count == 1) && ((size == 2) || (size == 4))) { - /* special case the handling of single word writes to bypass MMU - * to allow implementation of breakpoints in memory marked read only - * by MMU */ - if (arm926ejs->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled) { - /* flush and invalidate data cache - * - * MCR p15,0,p,c7,c10,1 - clean cache line using virtual address - * - */ - retval = arm926ejs->write_cp15(target, 0, 1, 7, 10, address&~0x3); - if (retval != ERROR_OK) - return retval; - } - - uint32_t pa; - retval = target->type->virt2phys(target, address, &pa); - if (retval != ERROR_OK) - return retval; - - /* write directly to physical memory bypassing any read only MMU bits, etc. */ - retval = armv4_5_mmu_write_physical(target, &arm926ejs->armv4_5_mmu, pa, size, count, buffer); - if (retval != ERROR_OK) - return retval; - } else { - retval = arm7_9_write_memory(target, address, size, count, buffer); - if (retval != ERROR_OK) - return retval; - } - - /* If ICache is enabled, we have to invalidate affected ICache lines - * the DCache is forced to write-through, so we don't have to clean it here - */ - if (arm926ejs->armv4_5_mmu.armv4_5_cache.i_cache_enabled) { - if (count <= 1) { - /* invalidate ICache single entry with MVA */ - arm926ejs->write_cp15(target, 0, 1, 7, 5, address); - } else { - /* invalidate ICache */ - arm926ejs->write_cp15(target, 0, 0, 7, 5, address); - } - } - - return retval; -} - -static int arm926ejs_write_phys_memory(struct target *target, - uint32_t address, uint32_t size, - uint32_t count, const uint8_t *buffer) -{ - struct arm926ejs_common *arm926ejs = target_to_arm926(target); - - return armv4_5_mmu_write_physical(target, &arm926ejs->armv4_5_mmu, - address, size, count, buffer); -} - -static int arm926ejs_read_phys_memory(struct target *target, - uint32_t address, uint32_t size, - uint32_t count, uint8_t *buffer) -{ - struct arm926ejs_common *arm926ejs = target_to_arm926(target); - - return armv4_5_mmu_read_physical(target, &arm926ejs->armv4_5_mmu, - address, size, count, buffer); -} - -int arm926ejs_init_arch_info(struct target *target, struct arm926ejs_common *arm926ejs, - struct jtag_tap *tap) -{ - struct arm7_9_common *arm7_9 = &arm926ejs->arm7_9_common; - - arm7_9->arm.mrc = arm926ejs_mrc; - arm7_9->arm.mcr = arm926ejs_mcr; - - /* initialize arm7/arm9 specific info (including armv4_5) */ - arm9tdmi_init_arch_info(target, arm7_9, tap); - - arm926ejs->common_magic = ARM926EJS_COMMON_MAGIC; - - arm7_9->post_debug_entry = arm926ejs_post_debug_entry; - arm7_9->pre_restore_context = arm926ejs_pre_restore_context; - arm7_9->write_memory = arm926ejs_write_memory; - - arm926ejs->read_cp15 = arm926ejs_cp15_read; - arm926ejs->write_cp15 = arm926ejs_cp15_write; - arm926ejs->armv4_5_mmu.armv4_5_cache.ctype = -1; - arm926ejs->armv4_5_mmu.get_ttb = arm926ejs_get_ttb; - arm926ejs->armv4_5_mmu.read_memory = arm7_9_read_memory; - arm926ejs->armv4_5_mmu.write_memory = arm7_9_write_memory; - arm926ejs->armv4_5_mmu.disable_mmu_caches = arm926ejs_disable_mmu_caches; - arm926ejs->armv4_5_mmu.enable_mmu_caches = arm926ejs_enable_mmu_caches; - arm926ejs->armv4_5_mmu.has_tiny_pages = 1; - arm926ejs->armv4_5_mmu.mmu_enabled = 0; - - arm7_9->examine_debug_reason = arm926ejs_examine_debug_reason; - - /* The ARM926EJ-S implements the ARMv5TE architecture which - * has the BKPT instruction, so we don't have to use a watchpoint comparator - */ - arm7_9->arm_bkpt = ARMV5_BKPT(0x0); - arm7_9->thumb_bkpt = ARMV5_T_BKPT(0x0) & 0xffff; - - return ERROR_OK; -} - -static int arm926ejs_target_create(struct target *target, Jim_Interp *interp) -{ - struct arm926ejs_common *arm926ejs = calloc(1, sizeof(struct arm926ejs_common)); - - /* ARM9EJ-S core always reports 0x1 in Capture-IR */ - target->tap->ir_capture_mask = 0x0f; - - return arm926ejs_init_arch_info(target, arm926ejs, target->tap); -} - -COMMAND_HANDLER(arm926ejs_handle_cache_info_command) -{ - int retval; - struct target *target = get_current_target(CMD_CTX); - struct arm926ejs_common *arm926ejs = target_to_arm926(target); - - retval = arm926ejs_verify_pointer(CMD_CTX, arm926ejs); - if (retval != ERROR_OK) - return retval; - - 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) -{ - uint32_t cb; - struct arm926ejs_common *arm926ejs = target_to_arm926(target); - - uint32_t ret; - int retval = armv4_5_mmu_translate_va(target, &arm926ejs->armv4_5_mmu, - virtual, &cb, &ret); - if (retval != ERROR_OK) - return retval; - *physical = ret; - return ERROR_OK; -} - -static int arm926ejs_mmu(struct target *target, int *enabled) -{ - struct arm926ejs_common *arm926ejs = target_to_arm926(target); - - if (target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_INVALID; - } - *enabled = arm926ejs->armv4_5_mmu.mmu_enabled; - return ERROR_OK; -} - -static const struct command_registration arm926ejs_exec_command_handlers[] = { - { - .name = "cache_info", - .handler = arm926ejs_handle_cache_info_command, - .mode = COMMAND_EXEC, - .usage = "", - .help = "display information about target caches", - - }, - COMMAND_REGISTRATION_DONE -}; -const struct command_registration arm926ejs_command_handlers[] = { - { - .chain = arm9tdmi_command_handlers, - }, - { - .name = "arm926ejs", - .mode = COMMAND_ANY, - .help = "arm926ejs command group", - .usage = "", - .chain = arm926ejs_exec_command_handlers, - }, - COMMAND_REGISTRATION_DONE -}; - -/** Holds methods for ARM926 targets. */ -struct target_type arm926ejs_target = { - .name = "arm926ejs", - - .poll = arm7_9_poll, - .arch_state = arm926ejs_arch_state, - - .target_request_data = arm7_9_target_request_data, - - .halt = arm7_9_halt, - .resume = arm7_9_resume, - .step = arm7_9_step, - - .assert_reset = arm7_9_assert_reset, - .deassert_reset = arm7_9_deassert_reset, - .soft_reset_halt = arm926ejs_soft_reset_halt, - - .get_gdb_reg_list = arm_get_gdb_reg_list, - - .read_memory = arm7_9_read_memory, - .write_memory = arm7_9_write_memory_opt, - - .checksum_memory = arm_checksum_memory, - .blank_check_memory = arm_blank_check_memory, - - .run_algorithm = armv4_5_run_algorithm, - - .add_breakpoint = arm7_9_add_breakpoint, - .remove_breakpoint = arm7_9_remove_breakpoint, - .add_watchpoint = arm7_9_add_watchpoint, - .remove_watchpoint = arm7_9_remove_watchpoint, - - .commands = arm926ejs_command_handlers, - .target_create = arm926ejs_target_create, - .init_target = arm9tdmi_init_target, - .examine = arm7_9_examine, - .check_reset = arm7_9_check_reset, - .virt2phys = arm926ejs_virt2phys, - .mmu = arm926ejs_mmu, - - .read_phys_memory = arm926ejs_read_phys_memory, - .write_phys_memory = arm926ejs_write_phys_memory, -}; diff --git a/src/target/arm926ejs.h b/src/target/arm926ejs.h deleted file mode 100644 index 02b4ef849..000000000 --- a/src/target/arm926ejs.h +++ /dev/null @@ -1,55 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifndef OPENOCD_TARGET_ARM926EJS_H -#define OPENOCD_TARGET_ARM926EJS_H - -#include "arm9tdmi.h" -#include "armv4_5_mmu.h" - -#define ARM926EJS_COMMON_MAGIC 0xa926a926 - -struct arm926ejs_common { - struct arm7_9_common arm7_9_common; - uint32_t common_magic; - struct armv4_5_mmu_common armv4_5_mmu; - int (*read_cp15)(struct target *target, uint32_t op1, uint32_t op2, - uint32_t CRn, uint32_t CRm, uint32_t *value); - int (*write_cp15)(struct target *target, uint32_t op1, uint32_t op2, - uint32_t CRn, uint32_t CRm, uint32_t value); - uint32_t cp15_control_reg; - uint32_t d_fsr; - uint32_t i_fsr; - uint32_t d_far; -}; - -static inline struct arm926ejs_common *target_to_arm926(struct target *target) -{ - return container_of(target->arch_info, struct arm926ejs_common, arm7_9_common.arm); -} - -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); -int arm926ejs_soft_reset_halt(struct target *target); - -extern const struct command_registration arm926ejs_command_handlers[]; - -#endif /* OPENOCD_TARGET_ARM926EJS_H */ diff --git a/src/target/arm946e.c b/src/target/arm946e.c deleted file mode 100644 index 5ee31cc2f..000000000 --- a/src/target/arm946e.c +++ /dev/null @@ -1,784 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * Copyright (C) 2008 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * Copyright (C) 2010 by Drasko DRASKOVIC * - * drasko.draskovic@gmail.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "arm946e.h" -#include "target_type.h" -#include "arm_opcodes.h" - -#include "breakpoints.h" - -#if 0 -#define _DEBUG_INSTRUCTION_EXECUTION_ -#endif - -#define NB_CACHE_WAYS 4 - -#define CP15_CTL 0x02 -#define CP15_CTL_DCACHE (1<<2) -#define CP15_CTL_ICACHE (1<<12) - -/** - * flag to give info about cache manipulation during debug : - * "0" - cache lines are invalidated "on the fly", for affected addresses. - * This is prefered from performance point of view. - * "1" - cache is invalidated and switched off on debug_entry, and switched back on on restore. - * It is kept off during debugging. - */ -static uint8_t arm946e_preserve_cache; - -int arm946e_post_debug_entry(struct target *target); -void arm946e_pre_restore_context(struct target *target); -static int arm946e_read_cp15(struct target *target, int reg_addr, uint32_t *value); - -int arm946e_init_arch_info(struct target *target, - struct arm946e_common *arm946e, - struct jtag_tap *tap) -{ - struct arm7_9_common *arm7_9 = &arm946e->arm7_9_common; - - /* initialize arm7/arm9 specific info (including armv4_5) */ - arm9tdmi_init_arch_info(target, arm7_9, tap); - - arm946e->common_magic = ARM946E_COMMON_MAGIC; - - /** - * The ARM946E-S implements the ARMv5TE architecture which - * has the BKPT instruction, so we don't have to use a watchpoint comparator - */ - arm7_9->arm_bkpt = ARMV5_BKPT(0x0); - arm7_9->thumb_bkpt = ARMV5_T_BKPT(0x0) & 0xffff; - - - arm7_9->post_debug_entry = arm946e_post_debug_entry; - arm7_9->pre_restore_context = arm946e_pre_restore_context; - - /** - * disabling linefills leads to lockups, so keep them enabled for now - * this doesn't affect correctness, but might affect timing issues, if - * important data is evicted from the cache during the debug session - */ - arm946e_preserve_cache = 0; - - /* override hw single-step capability from ARM9TDMI */ - /* arm7_9->has_single_step = 1; */ - - return ERROR_OK; -} - -static int arm946e_target_create(struct target *target, Jim_Interp *interp) -{ - struct arm946e_common *arm946e = calloc(1, sizeof(struct arm946e_common)); - - arm946e_init_arch_info(target, arm946e, target->tap); - - return ERROR_OK; -} - -static int arm946e_verify_pointer(struct command_context *cmd_ctx, - struct arm946e_common *arm946e) -{ - if (arm946e->common_magic != ARM946E_COMMON_MAGIC) { - command_print(cmd_ctx, "target is not an ARM946"); - return ERROR_TARGET_INVALID; - } - return ERROR_OK; -} - -/* - * Update cp15_control_reg, saved on debug_entry. - */ -static void arm946e_update_cp15_caches(struct target *target, uint32_t value) -{ - struct arm946e_common *arm946e = target_to_arm946(target); - arm946e->cp15_control_reg = (arm946e->cp15_control_reg & ~(CP15_CTL_DCACHE|CP15_CTL_ICACHE)) - | (value & (CP15_CTL_DCACHE|CP15_CTL_ICACHE)); -} - -/* - * REVISIT: The "read_cp15" and "write_cp15" commands could hook up - * to eventual mrc() and mcr() routines ... the reg_addr values being - * constructed (for CP15 only) from Opcode_1, Opcode_2, and CRn values. - * See section 7.3 of the ARM946E-S TRM. - */ -static int arm946e_read_cp15(struct target *target, int reg_addr, uint32_t *value) -{ - int retval = ERROR_OK; - struct arm7_9_common *arm7_9 = target_to_arm7_9(target); - struct arm_jtag *jtag_info = &arm7_9->jtag_info; - struct scan_field fields[3]; - uint8_t reg_addr_buf = reg_addr & 0x3f; - uint8_t nr_w_buf = 0; - - retval = arm_jtag_scann(jtag_info, 0xf, TAP_IDLE); - if (retval != ERROR_OK) - return retval; - retval = arm_jtag_set_instr(jtag_info->tap, jtag_info->intest_instr, NULL, TAP_IDLE); - if (retval != ERROR_OK) - return retval; - - fields[0].num_bits = 32; - /* REVISIT: table 7-2 shows that bits 31-31 need to be - * specified for accessing BIST registers ... - */ - fields[0].out_value = NULL; - fields[0].in_value = NULL; - - fields[1].num_bits = 6; - fields[1].out_value = ®_addr_buf; - fields[1].in_value = NULL; - - fields[2].num_bits = 1; - fields[2].out_value = &nr_w_buf; - fields[2].in_value = NULL; - - jtag_add_dr_scan(jtag_info->tap, 3, fields, TAP_IDLE); - - fields[0].in_value = (uint8_t *)value; - jtag_add_dr_scan(jtag_info->tap, 3, fields, TAP_IDLE); - - jtag_add_callback(arm_le_to_h_u32, (jtag_callback_data_t)value); - -#ifdef _DEBUG_INSTRUCTION_EXECUTION_ - LOG_DEBUG("addr: 0x%x value: %8.8x", reg_addr, *value); -#endif - - retval = jtag_execute_queue(); - if (retval != ERROR_OK) - return retval; - - return ERROR_OK; -} - -int arm946e_write_cp15(struct target *target, int reg_addr, uint32_t value) -{ - int retval = ERROR_OK; - struct arm7_9_common *arm7_9 = target_to_arm7_9(target); - struct arm_jtag *jtag_info = &arm7_9->jtag_info; - struct scan_field fields[3]; - uint8_t reg_addr_buf = reg_addr & 0x3f; - uint8_t nr_w_buf = 1; - uint8_t value_buf[4]; - - buf_set_u32(value_buf, 0, 32, value); - - retval = arm_jtag_scann(jtag_info, 0xf, TAP_IDLE); - if (retval != ERROR_OK) - return retval; - retval = arm_jtag_set_instr(jtag_info->tap, jtag_info->intest_instr, NULL, TAP_IDLE); - if (retval != ERROR_OK) - return retval; - - fields[0].num_bits = 32; - fields[0].out_value = value_buf; - fields[0].in_value = NULL; - - fields[1].num_bits = 6; - fields[1].out_value = ®_addr_buf; - fields[1].in_value = NULL; - - fields[2].num_bits = 1; - fields[2].out_value = &nr_w_buf; - fields[2].in_value = NULL; - - jtag_add_dr_scan(jtag_info->tap, 3, fields, TAP_IDLE); - -#ifdef _DEBUG_INSTRUCTION_EXECUTION_ - LOG_DEBUG("addr: 0x%x value: %8.8x", reg_addr, value); -#endif - - retval = jtag_execute_queue(); - if (retval != ERROR_OK) - return retval; - - return ERROR_OK; -} - -#define GET_ICACHE_SIZE 6 -#define GET_DCACHE_SIZE 18 - -/* - * \param target struct target pointer - * \param idsel select GET_ICACHE_SIZE or GET_DCACHE_SIZE - * \returns cache size, given in bytes - */ -static uint32_t arm946e_cp15_get_csize(struct target *target, int idsel) -{ - struct arm946e_common *arm946e = target_to_arm946(target); - uint32_t csize = arm946e->cp15_cache_info; - if (csize == 0) { - if (arm946e_read_cp15(target, 0x01, &csize) == ERROR_OK) - arm946e->cp15_cache_info = csize; - } - if (csize & (1<<(idsel-4))) /* cache absent */ - return 0; - csize = (csize >> idsel) & 0x0F; - return csize ? 1 << (12 + (csize-3)) : 0; -} - -uint32_t arm946e_invalidate_whole_dcache(struct target *target) -{ - uint32_t csize = arm946e_cp15_get_csize(target, GET_DCACHE_SIZE); - if (csize == 0) - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - - /* One line (index) is 32 bytes (8 words) long, 4-way assoc - * ARM DDI 0201D, Section 3.3.5 - */ - int nb_idx = (csize / (4*8*NB_CACHE_WAYS)); /* gives nb of lines (indexes) in the cache */ - - /* Loop for all segmentde (i.e. ways) */ - uint32_t seg; - for (seg = 0; seg < NB_CACHE_WAYS; seg++) { - /* Loop for all indexes */ - int idx; - for (idx = 0; idx < nb_idx; idx++) { - /* Form and write cp15 index (segment + line idx) */ - uint32_t cp15_idx = seg << 30 | idx << 5; - int retval = arm946e_write_cp15(target, 0x3a, cp15_idx); - if (retval != ERROR_OK) { - LOG_DEBUG("ERROR writing index"); - return retval; - } - - /* Read dtag */ - uint32_t dtag; - arm946e_read_cp15(target, 0x16, (uint32_t *) &dtag); - - /* Check cache line VALID bit */ - if (!(dtag >> 4 & 0x1)) - continue; - - /* Clean data cache line */ - retval = arm946e_write_cp15(target, 0x35, 0x1); - if (retval != ERROR_OK) { - LOG_DEBUG("ERROR cleaning cache line"); - return retval; - } - - /* Flush data cache line */ - retval = arm946e_write_cp15(target, 0x1a, 0x1); - if (retval != ERROR_OK) { - LOG_DEBUG("ERROR flushing cache line"); - return retval; - } - } - } - - return ERROR_OK; -} - -uint32_t arm946e_invalidate_whole_icache(struct target *target) -{ - /* Check cache presence before flushing - avoid undefined behavior */ - uint32_t csize = arm946e_cp15_get_csize(target, GET_ICACHE_SIZE); - if (csize == 0) - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - - LOG_DEBUG("FLUSHING I$"); - /** - * Invalidate (flush) I$ - * mcr 15, 0, r0, cr7, cr5, {0} - */ - int retval = arm946e_write_cp15(target, 0x0f, 0x1); - if (retval != ERROR_OK) { - LOG_DEBUG("ERROR flushing I$"); - return retval; - } - - return ERROR_OK; -} - -int arm946e_post_debug_entry(struct target *target) -{ - uint32_t ctr_reg = 0x0; - uint32_t retval = ERROR_OK; - struct arm946e_common *arm946e = target_to_arm946(target); - - /* See if CACHES are enabled, and save that info - * in the context bits, so that arm946e_pre_restore_context() can use them */ - arm946e_read_cp15(target, CP15_CTL, (uint32_t *) &ctr_reg); - - /* Save control reg in the context */ - arm946e->cp15_control_reg = ctr_reg; - - if (arm946e_preserve_cache) { - if (ctr_reg & CP15_CTL_DCACHE) { - /* Clean and flush D$ */ - arm946e_invalidate_whole_dcache(target); - - /* Disable D$ */ - ctr_reg &= ~CP15_CTL_DCACHE; - } - - if (ctr_reg & CP15_CTL_ICACHE) { - /* Flush I$ */ - arm946e_invalidate_whole_icache(target); - - /* Disable I$ */ - ctr_reg &= ~CP15_CTL_ICACHE; - } - - /* Write the new configuration */ - retval = arm946e_write_cp15(target, CP15_CTL, ctr_reg); - if (retval != ERROR_OK) { - LOG_DEBUG("ERROR disabling cache"); - return retval; - } - } /* if preserve_cache */ - - return ERROR_OK; -} - -void arm946e_pre_restore_context(struct target *target) -{ - uint32_t ctr_reg = 0x0; - uint32_t retval; - - if (arm946e_preserve_cache) { - struct arm946e_common *arm946e = target_to_arm946(target); - /* Get the contents of the CTR reg */ - arm946e_read_cp15(target, CP15_CTL, (uint32_t *) &ctr_reg); - - /** - * Read-modify-write CP15 control - * to reenable I/D-cache operation - * NOTE: It is not possible to disable cache by CP15. - * if arm946e_preserve_cache debugging flag enabled. - */ - ctr_reg |= arm946e->cp15_control_reg & (CP15_CTL_DCACHE|CP15_CTL_ICACHE); - - /* Write the new configuration */ - retval = arm946e_write_cp15(target, CP15_CTL, ctr_reg); - if (retval != ERROR_OK) - LOG_DEBUG("ERROR enabling cache"); - } /* if preserve_cache */ -} - -uint32_t arm946e_invalidate_dcache(struct target *target, uint32_t address, - uint32_t size, uint32_t count) -{ - uint32_t cur_addr = 0x0; - uint32_t cp15_idx, set, way, dtag; - uint32_t i = 0; - int retval; - - for (i = 0; i < count*size; i++) { - cur_addr = address + i; - - - set = (cur_addr >> 5) & 0xff; /* set field is 8 bits long */ - - for (way = 0; way < NB_CACHE_WAYS; way++) { - /** - * Find if the affected address is kept in the cache. - * Because JTAG Scan Chain 15 offers limited approach, - * we have to loop through all cache ways (segments) and - * read cache tags, then compare them with with address. - */ - - /* Form and write cp15 index (segment + line idx) */ - cp15_idx = way << 30 | set << 5; - retval = arm946e_write_cp15(target, 0x3a, cp15_idx); - if (retval != ERROR_OK) { - LOG_DEBUG("ERROR writing index"); - return retval; - } - - /* Read dtag */ - arm946e_read_cp15(target, 0x16, (uint32_t *) &dtag); - - /* Check cache line VALID bit */ - if (!(dtag >> 4 & 0x1)) - continue; - - /* If line is valid and corresponds to affected address - invalidate it */ - if (dtag >> 5 == cur_addr >> 5) { - /* Clean data cache line */ - retval = arm946e_write_cp15(target, 0x35, 0x1); - if (retval != ERROR_OK) { - LOG_DEBUG("ERROR cleaning cache line"); - return retval; - } - - /* Flush data cache line */ - retval = arm946e_write_cp15(target, 0x1c, 0x1); - if (retval != ERROR_OK) { - LOG_DEBUG("ERROR flushing cache line"); - return retval; - } - - break; - } - } /* loop through all 4 ways */ - } /* loop through all addresses */ - - return ERROR_OK; -} - -uint32_t arm946e_invalidate_icache(struct target *target, uint32_t address, - uint32_t size, uint32_t count) -{ - uint32_t cur_addr = 0x0; - uint32_t cp15_idx, set, way, itag; - uint32_t i = 0; - int retval; - - for (i = 0; i < count*size; i++) { - cur_addr = address + i; - - set = (cur_addr >> 5) & 0xff; /* set field is 8 bits long */ - - for (way = 0; way < NB_CACHE_WAYS; way++) { - /* Form and write cp15 index (segment + line idx) */ - cp15_idx = way << 30 | set << 5; - retval = arm946e_write_cp15(target, 0x3a, cp15_idx); - if (retval != ERROR_OK) { - LOG_DEBUG("ERROR writing index"); - return retval; - } - - /* Read itag */ - arm946e_read_cp15(target, 0x17, (uint32_t *) &itag); - - /* Check cache line VALID bit */ - if (!(itag >> 4 & 0x1)) - continue; - - /* If line is valid and corresponds to affected address - invalidate it */ - if (itag >> 5 == cur_addr >> 5) { - /* Flush I$ line */ - retval = arm946e_write_cp15(target, 0x1d, 0x0); - if (retval != ERROR_OK) { - LOG_DEBUG("ERROR flushing cache line"); - return retval; - } - - break; - } - } /* way loop */ - } /* addr loop */ - - return ERROR_OK; -} - -/** Writes a buffer, in the specified word size, with current MMU settings. */ -int arm946e_write_memory(struct target *target, uint32_t address, - uint32_t size, uint32_t count, const uint8_t *buffer) -{ - int retval; - - LOG_DEBUG("-"); - - struct arm946e_common *arm946e = target_to_arm946(target); - /* Invalidate D$ if it is ON */ - if (!arm946e_preserve_cache && (arm946e->cp15_control_reg & CP15_CTL_DCACHE)) - arm946e_invalidate_dcache(target, address, size, count); - - /** - * Write memory - */ - retval = arm7_9_write_memory_opt(target, address, size, count, buffer); - if (retval != ERROR_OK) - return retval; - - /* * - * Invalidate I$ if it is ON. - * - * D$ has been cleaned and flushed before mem write thus forcing it to behave like write-through, - * because arm7_9_write_memory() has seen non-valid bit in D$ - * and wrote data into physical RAM (without touching or allocating the cache line). - * From ARM946ES Technical Reference Manual we can see that it uses "allocate on read-miss" - * policy for both I$ and D$ (Chapter 3.2 and 3.3) - * - * Explanation : - * "ARM system developer's guide: designing and optimizing system software" by - * Andrew N. Sloss, Dominic Symes and Chris Wright, - * Chapter 12.3.3 Allocating Policy on a Cache Miss : - * A read allocate on cache miss policy allocates a cache line only during a read from main memory. - * If the victim cache line contains valid data, then it is written to main memory before the cache line - * is filled with new data. - * Under this strategy, a write of new data to memory does not update the contents of the cache memory - * unless a cache line was allocated on a previous read from main memory. - * If the cache line contains valid data, then the write updates the cache and may update the main memory if - * the cache write policy is write-through. - * If the data is not in the cache, the controller writes to main memory only. - */ - if (!arm946e_preserve_cache && (arm946e->cp15_control_reg & CP15_CTL_ICACHE)) - arm946e_invalidate_icache(target, address, size, count); - - return ERROR_OK; - -} - -int arm946e_read_memory(struct target *target, uint32_t address, - uint32_t size, uint32_t count, uint8_t *buffer) -{ - int retval; - - LOG_DEBUG("-"); - - retval = arm7_9_read_memory(target, address, size, count, buffer); - if (retval != ERROR_OK) - return retval; - - return ERROR_OK; -} - -static int jim_arm946e_cp15(Jim_Interp *interp, int argc, Jim_Obj * const *argv) -{ - /* one or two arguments, access a single register (write if second argument is given) */ - if (argc < 2 || argc > 3) { - Jim_WrongNumArgs(interp, 1, argv, "addr [value]"); - return JIM_ERR; - } - - struct command_context *cmd_ctx = current_command_context(interp); - assert(cmd_ctx != NULL); - - struct target *target = get_current_target(cmd_ctx); - if (target == NULL) { - LOG_ERROR("arm946e: no current target"); - return JIM_ERR; - } - - struct arm946e_common *arm946e = target_to_arm946(target); - int retval = arm946e_verify_pointer(cmd_ctx, arm946e); - if (retval != ERROR_OK) - return JIM_ERR; - - if (target->state != TARGET_HALTED) { - command_print(cmd_ctx, "target %s must be stopped for \"cp15\" command", target_name(target)); - return JIM_ERR; - } - - long l; - uint32_t address; - retval = Jim_GetLong(interp, argv[1], &l); - address = l; - if (JIM_OK != retval) - return retval; - - if (argc == 2) { - uint32_t value; - retval = arm946e_read_cp15(target, address, &value); - if (retval != ERROR_OK) { - command_print(cmd_ctx, "%s cp15 reg %" PRIi32 " access failed", target_name(target), address); - return JIM_ERR; - } - retval = jtag_execute_queue(); - if (retval != ERROR_OK) - return JIM_ERR; - char buf[20]; - sprintf(buf, "0x%08" PRIx32, value); - /* Return value in hex format */ - Jim_SetResultString(interp, buf, -1); - } else if (argc == 3) { - uint32_t value; - retval = Jim_GetLong(interp, argv[2], &l); - value = l; - if (JIM_OK != retval) - return retval; - retval = arm946e_write_cp15(target, address, value); - if (retval != ERROR_OK) { - command_print(cmd_ctx, "%s cp15 reg %" PRIi32 " access failed", target_name(target), address); - return JIM_ERR; - } - if (address == CP15_CTL) - arm946e_update_cp15_caches(target, value); - } - - return JIM_OK; -} - -COMMAND_HANDLER(arm946e_handle_idcache) -{ - if (CMD_ARGC > 1) - return ERROR_COMMAND_SYNTAX_ERROR; - - int retval; - struct target *target = get_current_target(CMD_CTX); - struct arm946e_common *arm946e = target_to_arm946(target); - - retval = arm946e_verify_pointer(CMD_CTX, arm946e); - if (retval != ERROR_OK) - return retval; - - if (target->state != TARGET_HALTED) { - command_print(CMD_CTX, "target must be stopped for \"%s\" command", CMD_NAME); - return ERROR_TARGET_NOT_HALTED; - } - - bool icache = (strcmp(CMD_NAME, "icache") == 0); - uint32_t csize = arm946e_cp15_get_csize(target, icache ? GET_ICACHE_SIZE : GET_DCACHE_SIZE) / 1024; - if (CMD_ARGC == 0) { - bool bena = ((arm946e->cp15_control_reg & (icache ? CP15_CTL_ICACHE : CP15_CTL_DCACHE)) != 0) - && (arm946e->cp15_control_reg & 0x1); - if (csize == 0) - command_print(CMD_CTX, "%s-cache absent", icache ? "I" : "D"); - else - command_print(CMD_CTX, "%s-cache size: %" PRIu32 "K, %s", - icache ? "I" : "D", csize, bena ? "enabled" : "disabled"); - return ERROR_OK; - } - - bool flush = false; - bool enable = false; - retval = command_parse_bool_arg(CMD_ARGV[0], &enable); - if (retval == ERROR_COMMAND_SYNTAX_ERROR) { - if (strcmp(CMD_ARGV[0], "flush") == 0) { - flush = true; - retval = ERROR_OK; - } else - return retval; - } - - /* Do not invalidate or change state, if cache is absent */ - if (csize == 0) { - command_print(CMD_CTX, "%s-cache absent, '%s' operation undefined", icache ? "I" : "D", CMD_ARGV[0]); - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - } - - /* NOTE: flushing entire cache will not preserve lock-down cache regions */ - if (icache) { - if ((arm946e->cp15_control_reg & CP15_CTL_ICACHE) && !enable) - retval = arm946e_invalidate_whole_icache(target); - } else { - if ((arm946e->cp15_control_reg & CP15_CTL_DCACHE) && !enable) - retval = arm946e_invalidate_whole_dcache(target); - } - - if (retval != ERROR_OK || flush) - return retval; - - uint32_t value; - retval = arm946e_read_cp15(target, CP15_CTL, &value); - if (retval != ERROR_OK) - return retval; - - uint32_t vnew = value; - uint32_t cmask = icache ? CP15_CTL_ICACHE : CP15_CTL_DCACHE; - if (enable) { - if ((value & 0x1) == 0) - LOG_WARNING("arm946e: MPU must be enabled for cache to operate"); - vnew |= cmask; - } else - vnew &= ~cmask; - - if (vnew == value) - return ERROR_OK; - - retval = arm946e_write_cp15(target, CP15_CTL, vnew); - if (retval != ERROR_OK) - return retval; - - arm946e_update_cp15_caches(target, vnew); - return ERROR_OK; -} - -static const struct command_registration arm946e_exec_command_handlers[] = { - { - .name = "cp15", - .jim_handler = jim_arm946e_cp15, - .mode = COMMAND_EXEC, - .usage = "regnum [value]", - .help = "read/modify cp15 register", - }, - { - .name = "icache", - .handler = arm946e_handle_idcache, - .mode = COMMAND_EXEC, - .usage = "['enable'|'disable'|'flush']", - .help = "I-cache info and operations", - }, - { - .name = "dcache", - .handler = arm946e_handle_idcache, - .mode = COMMAND_EXEC, - .usage = "['enable'|'disable'|'flush']", - .help = "D-cache info and operations", - }, - COMMAND_REGISTRATION_DONE -}; - -const struct command_registration arm946e_command_handlers[] = { - { - .chain = arm9tdmi_command_handlers, - }, - { - .name = "arm946e", - .mode = COMMAND_ANY, - .help = "arm946e command group", - .usage = "", - .chain = arm946e_exec_command_handlers, - }, - COMMAND_REGISTRATION_DONE -}; - -/** Holds methods for ARM946 targets. */ -struct target_type arm946e_target = { - .name = "arm946e", - - .poll = arm7_9_poll, - .arch_state = arm_arch_state, - - .target_request_data = arm7_9_target_request_data, - - .halt = arm7_9_halt, - .resume = arm7_9_resume, - .step = arm7_9_step, - - .assert_reset = arm7_9_assert_reset, - .deassert_reset = arm7_9_deassert_reset, - .soft_reset_halt = arm7_9_soft_reset_halt, - - .get_gdb_reg_list = arm_get_gdb_reg_list, - - /* .read_memory = arm7_9_read_memory, */ - /* .write_memory = arm7_9_write_memory, */ - .read_memory = arm946e_read_memory, - .write_memory = arm946e_write_memory, - - .checksum_memory = arm_checksum_memory, - .blank_check_memory = arm_blank_check_memory, - - .run_algorithm = armv4_5_run_algorithm, - - .add_breakpoint = arm7_9_add_breakpoint, - .remove_breakpoint = arm7_9_remove_breakpoint, - /* .add_breakpoint = arm946e_add_breakpoint, */ - /* .remove_breakpoint = arm946e_remove_breakpoint, */ - - .add_watchpoint = arm7_9_add_watchpoint, - .remove_watchpoint = arm7_9_remove_watchpoint, - - .commands = arm946e_command_handlers, - .target_create = arm946e_target_create, - .init_target = arm9tdmi_init_target, - .examine = arm7_9_examine, - .check_reset = arm7_9_check_reset, -}; diff --git a/src/target/arm946e.h b/src/target/arm946e.h deleted file mode 100644 index ee1ef3235..000000000 --- a/src/target/arm946e.h +++ /dev/null @@ -1,51 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * Copyright (C) 2008 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * Copyright (C) 2010 by Drasko DRASKOVIC * - * drasko.draskovic@gmail.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifndef OPENOCD_TARGET_ARM946E_H -#define OPENOCD_TARGET_ARM946E_H - -#include "arm9tdmi.h" - -#define ARM946E_COMMON_MAGIC 0x20f920f9 - -struct arm946e_common { - struct arm7_9_common arm7_9_common; - int common_magic; - uint32_t cp15_control_reg; - uint32_t cp15_cache_info; -}; - -static inline struct arm946e_common *target_to_arm946(struct target *target) -{ - return container_of(target->arch_info, struct arm946e_common, - arm7_9_common.arm); -} - -int arm946e_init_arch_info(struct target *target, - struct arm946e_common *arm946e, struct jtag_tap *tap); -int arm946e_write_cp15(struct target *target, int reg_addr, uint32_t value); - -extern const struct command_registration arm946e_command_handlers[]; - -#endif /* OPENOCD_TARGET_ARM946E_H */ diff --git a/src/target/arm966e.c b/src/target/arm966e.c deleted file mode 100644 index 0429c54b5..000000000 --- a/src/target/arm966e.c +++ /dev/null @@ -1,282 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * Copyright (C) 2008 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "arm966e.h" -#include "target_type.h" -#include "arm_opcodes.h" - -#if 0 -#define _DEBUG_INSTRUCTION_EXECUTION_ -#endif - -int arm966e_init_arch_info(struct target *target, struct arm966e_common *arm966e, struct jtag_tap *tap) -{ - struct arm7_9_common *arm7_9 = &arm966e->arm7_9_common; - - /* initialize arm7/arm9 specific info (including armv4_5) */ - arm9tdmi_init_arch_info(target, arm7_9, tap); - - arm966e->common_magic = ARM966E_COMMON_MAGIC; - - /* The ARM966E-S implements the ARMv5TE architecture which - * has the BKPT instruction, so we don't have to use a watchpoint comparator - */ - arm7_9->arm_bkpt = ARMV5_BKPT(0x0); - arm7_9->thumb_bkpt = ARMV5_T_BKPT(0x0) & 0xffff; - - return ERROR_OK; -} - -static int arm966e_target_create(struct target *target, Jim_Interp *interp) -{ - struct arm966e_common *arm966e = calloc(1, sizeof(struct arm966e_common)); - - return arm966e_init_arch_info(target, arm966e, target->tap); -} - -static int arm966e_verify_pointer(struct command_context *cmd_ctx, - struct arm966e_common *arm966e) -{ - if (arm966e->common_magic != ARM966E_COMMON_MAGIC) { - command_print(cmd_ctx, "target is not an ARM966"); - return ERROR_TARGET_INVALID; - } - return ERROR_OK; -} - -/* - * REVISIT: The "read_cp15" and "write_cp15" commands could hook up - * to eventual mrc() and mcr() routines ... the reg_addr values being - * constructed (for CP15 only) from Opcode_1, Opcode_2, and CRn values. - * See section 7.3 of the ARM966E-S TRM. - */ - -static int arm966e_read_cp15(struct target *target, int reg_addr, uint32_t *value) -{ - int retval = ERROR_OK; - struct arm7_9_common *arm7_9 = target_to_arm7_9(target); - struct arm_jtag *jtag_info = &arm7_9->jtag_info; - struct scan_field fields[3]; - uint8_t reg_addr_buf = reg_addr & 0x3f; - uint8_t nr_w_buf = 0; - - retval = arm_jtag_scann(jtag_info, 0xf, TAP_IDLE); - if (retval != ERROR_OK) - return retval; - retval = arm_jtag_set_instr(jtag_info->tap, jtag_info->intest_instr, NULL, TAP_IDLE); - if (retval != ERROR_OK) - return retval; - - fields[0].num_bits = 32; - /* REVISIT: table 7-2 shows that bits 31-31 need to be - * specified for accessing BIST registers ... - */ - fields[0].out_value = NULL; - fields[0].in_value = NULL; - - fields[1].num_bits = 6; - fields[1].out_value = ®_addr_buf; - fields[1].in_value = NULL; - - fields[2].num_bits = 1; - fields[2].out_value = &nr_w_buf; - fields[2].in_value = NULL; - - jtag_add_dr_scan(jtag_info->tap, 3, fields, TAP_IDLE); - - fields[1].in_value = (uint8_t *)value; - - jtag_add_dr_scan(jtag_info->tap, 3, fields, TAP_IDLE); - - jtag_add_callback(arm_le_to_h_u32, (jtag_callback_data_t)value); - - -#ifdef _DEBUG_INSTRUCTION_EXECUTION_ - retval = jtag_execute_queue(); - if (retval != ERROR_OK) - return retval; - LOG_DEBUG("addr: 0x%x value: %8.8x", reg_addr, *value); -#endif - - return ERROR_OK; -} - -/* EXPORTED to str9x (flash) */ -int arm966e_write_cp15(struct target *target, int reg_addr, uint32_t value) -{ - int retval = ERROR_OK; - struct arm7_9_common *arm7_9 = target_to_arm7_9(target); - struct arm_jtag *jtag_info = &arm7_9->jtag_info; - struct scan_field fields[3]; - uint8_t reg_addr_buf = reg_addr & 0x3f; - uint8_t nr_w_buf = 1; - uint8_t value_buf[4]; - - buf_set_u32(value_buf, 0, 32, value); - - retval = arm_jtag_scann(jtag_info, 0xf, TAP_IDLE); - if (retval != ERROR_OK) - return retval; - retval = arm_jtag_set_instr(jtag_info->tap, jtag_info->intest_instr, NULL, TAP_IDLE); - if (retval != ERROR_OK) - return retval; - - fields[0].num_bits = 32; - fields[0].out_value = value_buf; - fields[0].in_value = NULL; - - fields[1].num_bits = 6; - fields[1].out_value = ®_addr_buf; - fields[1].in_value = NULL; - - fields[2].num_bits = 1; - fields[2].out_value = &nr_w_buf; - fields[2].in_value = NULL; - - jtag_add_dr_scan(jtag_info->tap, 3, fields, TAP_IDLE); - -#ifdef _DEBUG_INSTRUCTION_EXECUTION_ - LOG_DEBUG("addr: 0x%x value: %8.8x", reg_addr, value); -#endif - - return ERROR_OK; -} - -COMMAND_HANDLER(arm966e_handle_cp15_command) -{ - int retval; - struct target *target = get_current_target(CMD_CTX); - struct arm966e_common *arm966e = target_to_arm966(target); - - retval = arm966e_verify_pointer(CMD_CTX, arm966e); - if (retval != ERROR_OK) - return retval; - - if (target->state != TARGET_HALTED) { - command_print(CMD_CTX, "target must be stopped for \"%s\" command", CMD_NAME); - return ERROR_OK; - } - - /* one or more argument, access a single register (write if second argument is given */ - if (CMD_ARGC >= 1) { - uint32_t address; - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], address); - - if (CMD_ARGC == 1) { - uint32_t value; - retval = arm966e_read_cp15(target, address, &value); - if (retval != ERROR_OK) { - command_print(CMD_CTX, - "couldn't access reg %" PRIi32, - address); - return ERROR_OK; - } - retval = jtag_execute_queue(); - if (retval != ERROR_OK) - return retval; - - command_print(CMD_CTX, "%" PRIi32 ": %8.8" PRIx32, - address, value); - } else if (CMD_ARGC == 2) { - uint32_t value; - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], value); - retval = arm966e_write_cp15(target, address, value); - if (retval != ERROR_OK) { - command_print(CMD_CTX, - "couldn't access reg %" PRIi32, - address); - return ERROR_OK; - } - command_print(CMD_CTX, "%" PRIi32 ": %8.8" PRIx32, - address, value); - } - } - - return ERROR_OK; -} - -static const struct command_registration arm966e_exec_command_handlers[] = { - { - .name = "cp15", - .handler = arm966e_handle_cp15_command, - .mode = COMMAND_EXEC, - .usage = "regnum [value]", - .help = "display/modify cp15 register", - }, - COMMAND_REGISTRATION_DONE -}; - -const struct command_registration arm966e_command_handlers[] = { - { - .chain = arm9tdmi_command_handlers, - }, - { - .name = "arm966e", - .mode = COMMAND_ANY, - .help = "arm966e command group", - .usage = "", - .chain = arm966e_exec_command_handlers, - }, - COMMAND_REGISTRATION_DONE -}; - -/** Holds methods for ARM966 targets. */ -struct target_type arm966e_target = { - .name = "arm966e", - - .poll = arm7_9_poll, - .arch_state = arm_arch_state, - - .target_request_data = arm7_9_target_request_data, - - .halt = arm7_9_halt, - .resume = arm7_9_resume, - .step = arm7_9_step, - - .assert_reset = arm7_9_assert_reset, - .deassert_reset = arm7_9_deassert_reset, - .soft_reset_halt = arm7_9_soft_reset_halt, - - .get_gdb_reg_list = arm_get_gdb_reg_list, - - .read_memory = arm7_9_read_memory, - .write_memory = arm7_9_write_memory_opt, - - .checksum_memory = arm_checksum_memory, - .blank_check_memory = arm_blank_check_memory, - - .run_algorithm = armv4_5_run_algorithm, - - .add_breakpoint = arm7_9_add_breakpoint, - .remove_breakpoint = arm7_9_remove_breakpoint, - .add_watchpoint = arm7_9_add_watchpoint, - .remove_watchpoint = arm7_9_remove_watchpoint, - - .commands = arm966e_command_handlers, - .target_create = arm966e_target_create, - .init_target = arm9tdmi_init_target, - .examine = arm7_9_examine, - .check_reset = arm7_9_check_reset, -}; diff --git a/src/target/arm966e.h b/src/target/arm966e.h deleted file mode 100644 index aa2e9bb27..000000000 --- a/src/target/arm966e.h +++ /dev/null @@ -1,48 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * Copyright (C) 2008 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifndef OPENOCD_TARGET_ARM966E_H -#define OPENOCD_TARGET_ARM966E_H - -#include "arm9tdmi.h" - -#define ARM966E_COMMON_MAGIC 0x20f920f9 - -struct arm966e_common { - struct arm7_9_common arm7_9_common; - int common_magic; - uint32_t cp15_control_reg; -}; - -static inline struct arm966e_common * -target_to_arm966(struct target *target) -{ - return container_of(target->arch_info, struct arm966e_common, - arm7_9_common.arm); -} - -int arm966e_init_arch_info(struct target *target, - struct arm966e_common *arm966e, struct jtag_tap *tap); -int arm966e_write_cp15(struct target *target, int reg_addr, uint32_t value); - -extern const struct command_registration arm966e_command_handlers[]; - -#endif /* OPENOCD_TARGET_ARM966E_H */ diff --git a/src/target/arm9tdmi.c b/src/target/arm9tdmi.c deleted file mode 100644 index eed965a37..000000000 --- a/src/target/arm9tdmi.c +++ /dev/null @@ -1,923 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * Copyright (C) 2008 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * Copyright (C) 2008 by Hongtao Zheng * - * hontor@126.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "arm9tdmi.h" -#include "target_type.h" -#include "register.h" -#include "arm_opcodes.h" - -/* - * NOTE: this holds code that's used with multiple ARM9 processors: - * - ARM9TDMI (ARMv4T) ... in ARM920, ARM922, and ARM940 cores - * - ARM9E-S (ARMv5TE) ... in ARM946, ARM966, and ARM968 cores - * - ARM9EJS (ARMv5TEJ) ... in ARM926 core - * - * In short, the file name is a misnomer ... it is NOT specific to - * that first generation ARM9 processor, or cores using it. - */ - -#if 0 -#define _DEBUG_INSTRUCTION_EXECUTION_ -#endif - -enum arm9tdmi_vector_bit { - ARM9TDMI_RESET_VECTOR = 0x01, - ARM9TDMI_UNDEF_VECTOR = 0x02, - ARM9TDMI_SWI_VECTOR = 0x04, - ARM9TDMI_PABT_VECTOR = 0x08, - ARM9TDMI_DABT_VECTOR = 0x10, - /* BIT(5) reserved -- must be zero */ - ARM9TDMI_IRQ_VECTOR = 0x40, - ARM9TDMI_FIQ_VECTOR = 0x80, -}; - -static const struct arm9tdmi_vector { - const char *name; - uint32_t value; -} arm9tdmi_vectors[] = { - {"reset", ARM9TDMI_RESET_VECTOR}, - {"undef", ARM9TDMI_UNDEF_VECTOR}, - {"swi", ARM9TDMI_SWI_VECTOR}, - {"pabt", ARM9TDMI_PABT_VECTOR}, - {"dabt", ARM9TDMI_DABT_VECTOR}, - {"irq", ARM9TDMI_IRQ_VECTOR}, - {"fiq", ARM9TDMI_FIQ_VECTOR}, - {0, 0}, -}; - -int arm9tdmi_examine_debug_reason(struct target *target) -{ - int retval = ERROR_OK; - struct arm7_9_common *arm7_9 = target_to_arm7_9(target); - - /* only check the debug reason if we don't know it already */ - if ((target->debug_reason != DBG_REASON_DBGRQ) - && (target->debug_reason != DBG_REASON_SINGLESTEP)) { - struct scan_field fields[3]; - uint8_t databus[4]; - uint8_t instructionbus[4]; - uint8_t debug_reason; - - fields[0].num_bits = 32; - fields[0].out_value = NULL; - fields[0].in_value = databus; - - fields[1].num_bits = 3; - fields[1].out_value = NULL; - fields[1].in_value = &debug_reason; - - fields[2].num_bits = 32; - fields[2].out_value = NULL; - fields[2].in_value = instructionbus; - - retval = arm_jtag_scann(&arm7_9->jtag_info, 0x1, TAP_DRPAUSE); - if (retval != ERROR_OK) - return retval; - retval = arm_jtag_set_instr(arm7_9->jtag_info.tap, arm7_9->jtag_info.intest_instr, NULL, TAP_DRPAUSE); - if (retval != ERROR_OK) - return retval; - - jtag_add_dr_scan(arm7_9->jtag_info.tap, 3, fields, TAP_DRPAUSE); - retval = jtag_execute_queue(); - if (retval != ERROR_OK) - return retval; - - fields[0].in_value = NULL; - fields[0].out_value = databus; - fields[1].in_value = NULL; - fields[1].out_value = &debug_reason; - fields[2].in_value = NULL; - fields[2].out_value = instructionbus; - - jtag_add_dr_scan(arm7_9->jtag_info.tap, 3, fields, TAP_DRPAUSE); - - if (debug_reason & 0x4) - if (debug_reason & 0x2) - target->debug_reason = DBG_REASON_WPTANDBKPT; - else - target->debug_reason = DBG_REASON_WATCHPOINT; - else - target->debug_reason = DBG_REASON_BREAKPOINT; - } - - return ERROR_OK; -} - -/* put an instruction in the ARM9TDMI pipeline or write the data bus, - * and optionally read data - */ -int arm9tdmi_clock_out(struct arm_jtag *jtag_info, uint32_t instr, - uint32_t out, uint32_t *in, int sysspeed) -{ - int retval = ERROR_OK; - struct scan_field fields[3]; - uint8_t out_buf[4]; - uint8_t instr_buf[4]; - uint8_t sysspeed_buf = 0x0; - - /* prepare buffer */ - buf_set_u32(out_buf, 0, 32, out); - - buf_set_u32(instr_buf, 0, 32, flip_u32(instr, 32)); - - if (sysspeed) - buf_set_u32(&sysspeed_buf, 2, 1, 1); - - retval = arm_jtag_scann(jtag_info, 0x1, TAP_DRPAUSE); - if (retval != ERROR_OK) - return retval; - - retval = arm_jtag_set_instr(jtag_info->tap, jtag_info->intest_instr, NULL, TAP_DRPAUSE); - if (retval != ERROR_OK) - return retval; - - fields[0].num_bits = 32; - fields[0].out_value = out_buf; - fields[0].in_value = NULL; - - fields[1].num_bits = 3; - fields[1].out_value = &sysspeed_buf; - fields[1].in_value = NULL; - - fields[2].num_bits = 32; - fields[2].out_value = instr_buf; - fields[2].in_value = NULL; - - if (in) { - fields[0].in_value = (uint8_t *)in; - jtag_add_dr_scan(jtag_info->tap, 3, fields, TAP_DRPAUSE); - - jtag_add_callback(arm_le_to_h_u32, (jtag_callback_data_t)in); - } else - jtag_add_dr_scan(jtag_info->tap, 3, fields, TAP_DRPAUSE); - - jtag_add_runtest(0, TAP_DRPAUSE); - -#ifdef _DEBUG_INSTRUCTION_EXECUTION_ - { - retval = jtag_execute_queue(); - if (retval != ERROR_OK) - return retval; - - if (in) - LOG_DEBUG("instr: 0x%8.8x, out: 0x%8.8x, in: 0x%8.8x", instr, out, *in); - else - LOG_DEBUG("instr: 0x%8.8x, out: 0x%8.8x", instr, out); - } -#endif - - return ERROR_OK; -} - -/* just read data (instruction and data-out = don't care) */ -int arm9tdmi_clock_data_in(struct arm_jtag *jtag_info, uint32_t *in) -{ - int retval = ERROR_OK; - struct scan_field fields[3]; - - retval = arm_jtag_scann(jtag_info, 0x1, TAP_DRPAUSE); - if (retval != ERROR_OK) - return retval; - - retval = arm_jtag_set_instr(jtag_info->tap, jtag_info->intest_instr, NULL, TAP_DRPAUSE); - if (retval != ERROR_OK) - return retval; - - fields[0].num_bits = 32; - fields[0].out_value = NULL; - fields[0].in_value = (uint8_t *)in; - - fields[1].num_bits = 3; - fields[1].out_value = NULL; - fields[1].in_value = NULL; - - fields[2].num_bits = 32; - fields[2].out_value = NULL; - fields[2].in_value = NULL; - - jtag_add_dr_scan(jtag_info->tap, 3, fields, TAP_DRPAUSE); - - jtag_add_callback(arm_le_to_h_u32, (jtag_callback_data_t)in); - - jtag_add_runtest(0, TAP_DRPAUSE); - -#ifdef _DEBUG_INSTRUCTION_EXECUTION_ - { - retval = jtag_execute_queue(); - if (retval != ERROR_OK) - return retval; - - if (in) - LOG_DEBUG("in: 0x%8.8x", *in); - else - LOG_ERROR("BUG: called with in == NULL"); - } -#endif - - return ERROR_OK; -} - -/* clock the target, and read the databus - * the *in pointer points to a buffer where elements of 'size' bytes - * are stored in big (be == 1) or little (be == 0) endianness - */ -int arm9tdmi_clock_data_in_endianness(struct arm_jtag *jtag_info, - void *in, int size, int be) -{ - int retval = ERROR_OK; - struct scan_field fields[2]; - - retval = arm_jtag_scann(jtag_info, 0x1, TAP_DRPAUSE); - if (retval != ERROR_OK) - return retval; - - retval = arm_jtag_set_instr(jtag_info->tap, jtag_info->intest_instr, NULL, TAP_DRPAUSE); - if (retval != ERROR_OK) - return retval; - - if (size == 4) { - fields[0].num_bits = 32; - fields[0].out_value = NULL; - fields[0].in_value = in; - - fields[1].num_bits = 3 + 32; - fields[1].out_value = NULL; - fields[1].in_value = NULL; - } else { - /* Discard irrelevant bits of the scan, making sure we don't write more - * than size bytes to in */ - fields[0].num_bits = size * 8; - fields[0].out_value = NULL; - fields[0].in_value = in; - - fields[1].num_bits = 3 + 32 + 32 - size * 8; - fields[1].out_value = NULL; - fields[1].in_value = NULL; - } - - jtag_add_dr_scan(jtag_info->tap, 2, fields, TAP_DRPAUSE); - - jtag_add_callback4(arm7_9_endianness_callback, - (jtag_callback_data_t)in, - (jtag_callback_data_t)size, - (jtag_callback_data_t)be, - (jtag_callback_data_t)0); - - jtag_add_runtest(0, TAP_DRPAUSE); - -#ifdef _DEBUG_INSTRUCTION_EXECUTION_ - { - retval = jtag_execute_queue(); - if (retval != ERROR_OK) - return retval; - - if (in) - LOG_DEBUG("in: 0x%8.8x", *(uint32_t *)in); - else - LOG_ERROR("BUG: called with in == NULL"); - } -#endif - - return ERROR_OK; -} - -static void arm9tdmi_change_to_arm(struct target *target, - uint32_t *r0, uint32_t *pc) -{ - int retval = ERROR_OK; - struct arm7_9_common *arm7_9 = target_to_arm7_9(target); - struct arm_jtag *jtag_info = &arm7_9->jtag_info; - - /* save r0 before using it and put system in ARM state - * to allow common handling of ARM and THUMB debugging */ - - /* fetch STR r0, [r0] */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_T_STR(0, 0), 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0); - /* STR r0, [r0] in Memory */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, r0, 0); - - /* MOV r0, r15 fetched, STR in Decode */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_T_MOV(0, 15), 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_T_STR(0, 0), 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0); - /* nothing fetched, STR r0, [r0] in Memory */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, pc, 0); - - /* use pc-relative LDR to clear r0[1:0] (for switch to ARM mode) */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_T_LDR_PCREL(0), 0, NULL, 0); - /* LDR in Decode */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0); - /* LDR in Execute */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0); - /* LDR in Memory (to account for interlock) */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0); - - /* fetch BX */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_T_BX(0), 0, NULL, 0); - /* NOP fetched, BX in Decode, MOV in Execute */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0); - /* NOP fetched, BX in Execute (1) */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0); - - retval = jtag_execute_queue(); - if (retval != ERROR_OK) - return; - - /* fix program counter: - * MOV r0, r15 was the 5th instruction (+8) - * reading PC in Thumb state gives address of instruction + 4 - */ - *pc -= 0xc; -} - -void arm9tdmi_read_core_regs(struct target *target, - uint32_t mask, uint32_t *core_regs[16]) -{ - int i; - struct arm7_9_common *arm7_9 = target_to_arm7_9(target); - struct arm_jtag *jtag_info = &arm7_9->jtag_info; - - /* STMIA r0-15, [r0] at debug speed - * register values will start to appear on 4th DCLK - */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_STMIA(0, mask & 0xffff, 0, 0), 0, NULL, 0); - - /* fetch NOP, STM in DECODE stage */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - /* fetch NOP, STM in EXECUTE stage (1st cycle) */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - - for (i = 0; i <= 15; i++) { - if (mask & (1 << i)) - /* nothing fetched, STM in MEMORY (i'th cycle) */ - arm9tdmi_clock_data_in(jtag_info, core_regs[i]); - } -} - -static void arm9tdmi_read_core_regs_target_buffer(struct target *target, - uint32_t mask, void *buffer, int size) -{ - int i; - struct arm7_9_common *arm7_9 = target_to_arm7_9(target); - struct arm_jtag *jtag_info = &arm7_9->jtag_info; - int be = (target->endianness == TARGET_BIG_ENDIAN) ? 1 : 0; - uint32_t *buf_u32 = buffer; - uint16_t *buf_u16 = buffer; - uint8_t *buf_u8 = buffer; - - /* STMIA r0-15, [r0] at debug speed - * register values will start to appear on 4th DCLK - */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_STMIA(0, mask & 0xffff, 0, 0), 0, NULL, 0); - - /* fetch NOP, STM in DECODE stage */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - /* fetch NOP, STM in EXECUTE stage (1st cycle) */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - - for (i = 0; i <= 15; i++) { - if (mask & (1 << i)) - /* nothing fetched, STM in MEMORY (i'th cycle) */ - switch (size) { - case 4: - arm9tdmi_clock_data_in_endianness(jtag_info, buf_u32++, 4, be); - break; - case 2: - arm9tdmi_clock_data_in_endianness(jtag_info, buf_u16++, 2, be); - break; - case 1: - arm9tdmi_clock_data_in_endianness(jtag_info, buf_u8++, 1, be); - break; - } - } -} - -static void arm9tdmi_read_xpsr(struct target *target, uint32_t *xpsr, int spsr) -{ - struct arm7_9_common *arm7_9 = target_to_arm7_9(target); - struct arm_jtag *jtag_info = &arm7_9->jtag_info; - - /* MRS r0, cpsr */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_MRS(0, spsr & 1), 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - - /* STR r0, [r15] */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_STR(0, 15), 0, NULL, 0); - /* fetch NOP, STR in DECODE stage */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - /* fetch NOP, STR in EXECUTE stage (1st cycle) */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - /* nothing fetched, STR in MEMORY */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, xpsr, 0); -} - -static void arm9tdmi_write_xpsr(struct target *target, uint32_t xpsr, int spsr) -{ - struct arm7_9_common *arm7_9 = target_to_arm7_9(target); - struct arm_jtag *jtag_info = &arm7_9->jtag_info; - - LOG_DEBUG("xpsr: %8.8" PRIx32 ", spsr: %i", xpsr, spsr); - - /* MSR1 fetched */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM(xpsr & 0xff, 0, 1, spsr), 0, NULL, 0); - /* MSR2 fetched, MSR1 in DECODE */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM((xpsr & 0xff00) >> 8, 0xc, 2, spsr), 0, NULL, 0); - /* MSR3 fetched, MSR1 in EXECUTE (1), MSR2 in DECODE */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM((xpsr & 0xff0000) >> 16, 0x8, 4, spsr), 0, NULL, 0); - /* nothing fetched, MSR1 in EXECUTE (2) */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - /* nothing fetched, MSR1 in EXECUTE (3) */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - /* MSR4 fetched, MSR2 in EXECUTE (1), MSR3 in DECODE */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM((xpsr & 0xff000000) >> 24, 0x4, 8, spsr), 0, NULL, 0); - /* nothing fetched, MSR2 in EXECUTE (2) */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - /* nothing fetched, MSR2 in EXECUTE (3) */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - /* NOP fetched, MSR3 in EXECUTE (1), MSR4 in DECODE */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - /* nothing fetched, MSR3 in EXECUTE (2) */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - /* nothing fetched, MSR3 in EXECUTE (3) */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - /* NOP fetched, MSR4 in EXECUTE (1) */ - /* last MSR writes flags, which takes only one cycle */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); -} - -static void arm9tdmi_write_xpsr_im8(struct target *target, - uint8_t xpsr_im, int rot, int spsr) -{ - struct arm7_9_common *arm7_9 = target_to_arm7_9(target); - struct arm_jtag *jtag_info = &arm7_9->jtag_info; - - LOG_DEBUG("xpsr_im: %2.2x, rot: %i, spsr: %i", xpsr_im, rot, spsr); - - /* MSR fetched */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM(xpsr_im, rot, 1, spsr), 0, NULL, 0); - /* NOP fetched, MSR in DECODE */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - /* NOP fetched, MSR in EXECUTE (1) */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - - /* rot == 4 writes flags, which takes only one cycle */ - if (rot != 4) { - /* nothing fetched, MSR in EXECUTE (2) */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - /* nothing fetched, MSR in EXECUTE (3) */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - } -} - -void arm9tdmi_write_core_regs(struct target *target, - uint32_t mask, uint32_t core_regs[16]) -{ - int i; - struct arm7_9_common *arm7_9 = target_to_arm7_9(target); - struct arm_jtag *jtag_info = &arm7_9->jtag_info; - - /* LDMIA r0-15, [r0] at debug speed - * register values will start to appear on 4th DCLK - */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_LDMIA(0, mask & 0xffff, 0, 0), 0, NULL, 0); - - /* fetch NOP, LDM in DECODE stage */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - /* fetch NOP, LDM in EXECUTE stage (1st cycle) */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - - for (i = 0; i <= 15; i++) { - if (mask & (1 << i)) - /* nothing fetched, LDM still in EXECUTE (1 + i cycle) */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, core_regs[i], NULL, 0); - } - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); -} - -void arm9tdmi_load_word_regs(struct target *target, uint32_t mask) -{ - struct arm7_9_common *arm7_9 = target_to_arm7_9(target); - struct arm_jtag *jtag_info = &arm7_9->jtag_info; - - /* put system-speed load-multiple into the pipeline */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_LDMIA(0, mask & 0xffff, 0, 1), 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 1); -} - -void arm9tdmi_load_hword_reg(struct target *target, int num) -{ - struct arm7_9_common *arm7_9 = target_to_arm7_9(target); - struct arm_jtag *jtag_info = &arm7_9->jtag_info; - - /* put system-speed load half-word into the pipeline */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_LDRH_IP(num, 0), 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 1); -} - -void arm9tdmi_load_byte_reg(struct target *target, int num) -{ - struct arm7_9_common *arm7_9 = target_to_arm7_9(target); - struct arm_jtag *jtag_info = &arm7_9->jtag_info; - - /* put system-speed load byte into the pipeline */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_LDRB_IP(num, 0), 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 1); -} - -void arm9tdmi_store_word_regs(struct target *target, uint32_t mask) -{ - struct arm7_9_common *arm7_9 = target_to_arm7_9(target); - struct arm_jtag *jtag_info = &arm7_9->jtag_info; - - /* put system-speed store-multiple into the pipeline */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_STMIA(0, mask, 0, 1), 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 1); -} - -void arm9tdmi_store_hword_reg(struct target *target, int num) -{ - struct arm7_9_common *arm7_9 = target_to_arm7_9(target); - struct arm_jtag *jtag_info = &arm7_9->jtag_info; - - /* put system-speed store half-word into the pipeline */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_STRH_IP(num, 0), 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 1); -} - -void arm9tdmi_store_byte_reg(struct target *target, int num) -{ - struct arm7_9_common *arm7_9 = target_to_arm7_9(target); - struct arm_jtag *jtag_info = &arm7_9->jtag_info; - - /* put system-speed store byte into the pipeline */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_STRB_IP(num, 0), 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 1); -} - -static void arm9tdmi_write_pc(struct target *target, uint32_t pc) -{ - struct arm7_9_common *arm7_9 = target_to_arm7_9(target); - struct arm_jtag *jtag_info = &arm7_9->jtag_info; - - /* LDMIA r0-15, [r0] at debug speed - * register values will start to appear on 4th DCLK - */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_LDMIA(0, 0x8000, 0, 0), 0, NULL, 0); - - /* fetch NOP, LDM in DECODE stage */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - /* fetch NOP, LDM in EXECUTE stage (1st cycle) */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - /* nothing fetched, LDM in EXECUTE stage (2nd cycle) (output data) */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, pc, NULL, 0); - /* nothing fetched, LDM in EXECUTE stage (3rd cycle) */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - /* fetch NOP, LDM in EXECUTE stage (4th cycle) */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - /* fetch NOP, LDM in EXECUTE stage (5th cycle) */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); -} - -void arm9tdmi_branch_resume(struct target *target) -{ - struct arm7_9_common *arm7_9 = target_to_arm7_9(target); - struct arm_jtag *jtag_info = &arm7_9->jtag_info; - - arm9tdmi_clock_out(jtag_info, ARMV4_5_B(0xfffffc, 0), 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 1); -} - -static void arm9tdmi_branch_resume_thumb(struct target *target) -{ - LOG_DEBUG("-"); - - struct arm7_9_common *arm7_9 = target_to_arm7_9(target); - struct arm *arm = &arm7_9->arm; - struct arm_jtag *jtag_info = &arm7_9->jtag_info; - struct reg *dbg_stat = &arm7_9->eice_cache->reg_list[EICE_DBG_STAT]; - - /* LDMIA r0-15, [r0] at debug speed - * register values will start to appear on 4th DCLK - */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_LDMIA(0, 0x1, 0, 0), 0, NULL, 0); - - /* fetch NOP, LDM in DECODE stage */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - /* fetch NOP, LDM in EXECUTE stage (1st cycle) */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - /* nothing fetched, LDM in EXECUTE stage (2nd cycle) */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, - buf_get_u32(arm->pc->value, 0, 32) | 1, NULL, 0); - /* nothing fetched, LDM in EXECUTE stage (3rd cycle) */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - - /* Branch and eXchange */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_BX(0), 0, NULL, 0); - - embeddedice_read_reg(dbg_stat); - - /* fetch NOP, BX in DECODE stage */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - - embeddedice_read_reg(dbg_stat); - - /* fetch NOP, BX in EXECUTE stage (1st cycle) */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - - /* target is now in Thumb state */ - embeddedice_read_reg(dbg_stat); - - /* load r0 value, MOV_IM in Decode*/ - arm9tdmi_clock_out(jtag_info, ARMV4_5_T_LDR_PCREL(0), 0, NULL, 0); - /* fetch NOP, LDR in Decode, MOV_IM in Execute */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0); - /* fetch NOP, LDR in Execute */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0); - /* nothing fetched, LDR in EXECUTE stage (2nd cycle) */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, - buf_get_u32(arm->core_cache->reg_list[0].value, 0, 32), NULL, 0); - /* nothing fetched, LDR in EXECUTE stage (3rd cycle) */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0); - - arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0); - - embeddedice_read_reg(dbg_stat); - - arm9tdmi_clock_out(jtag_info, ARMV4_5_T_B(0x7f7), 0, NULL, 1); - arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0); -} - -void arm9tdmi_enable_single_step(struct target *target, uint32_t next_pc) -{ - struct arm7_9_common *arm7_9 = target_to_arm7_9(target); - - if (arm7_9->has_single_step) { - buf_set_u32(arm7_9->eice_cache->reg_list[EICE_DBG_CTRL].value, 3, 1, 1); - embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_DBG_CTRL]); - } else - arm7_9_enable_eice_step(target, next_pc); -} - -void arm9tdmi_disable_single_step(struct target *target) -{ - struct arm7_9_common *arm7_9 = target_to_arm7_9(target); - - if (arm7_9->has_single_step) { - buf_set_u32(arm7_9->eice_cache->reg_list[EICE_DBG_CTRL].value, 3, 1, 0); - embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_DBG_CTRL]); - } else - arm7_9_disable_eice_step(target); -} - -static void arm9tdmi_build_reg_cache(struct target *target) -{ - struct reg_cache **cache_p = register_get_last_cache_p(&target->reg_cache); - struct arm *arm = target_to_arm(target); - - (*cache_p) = arm_build_reg_cache(target, arm); -} - -int arm9tdmi_init_target(struct command_context *cmd_ctx, - struct target *target) -{ - arm9tdmi_build_reg_cache(target); - return ERROR_OK; -} - -int arm9tdmi_init_arch_info(struct target *target, - struct arm7_9_common *arm7_9, struct jtag_tap *tap) -{ - /* prepare JTAG information for the new target */ - arm7_9->jtag_info.tap = tap; - arm7_9->jtag_info.scann_size = 5; - - /* register arch-specific functions */ - arm7_9->examine_debug_reason = arm9tdmi_examine_debug_reason; - arm7_9->change_to_arm = arm9tdmi_change_to_arm; - arm7_9->read_core_regs = arm9tdmi_read_core_regs; - arm7_9->read_core_regs_target_buffer = arm9tdmi_read_core_regs_target_buffer; - arm7_9->read_xpsr = arm9tdmi_read_xpsr; - - arm7_9->write_xpsr = arm9tdmi_write_xpsr; - arm7_9->write_xpsr_im8 = arm9tdmi_write_xpsr_im8; - arm7_9->write_core_regs = arm9tdmi_write_core_regs; - - arm7_9->load_word_regs = arm9tdmi_load_word_regs; - arm7_9->load_hword_reg = arm9tdmi_load_hword_reg; - arm7_9->load_byte_reg = arm9tdmi_load_byte_reg; - - arm7_9->store_word_regs = arm9tdmi_store_word_regs; - arm7_9->store_hword_reg = arm9tdmi_store_hword_reg; - arm7_9->store_byte_reg = arm9tdmi_store_byte_reg; - - arm7_9->write_pc = arm9tdmi_write_pc; - arm7_9->branch_resume = arm9tdmi_branch_resume; - arm7_9->branch_resume_thumb = arm9tdmi_branch_resume_thumb; - - arm7_9->enable_single_step = arm9tdmi_enable_single_step; - arm7_9->disable_single_step = arm9tdmi_disable_single_step; - - arm7_9->write_memory = arm7_9_write_memory; - arm7_9->bulk_write_memory = arm7_9_bulk_write_memory; - - arm7_9->post_debug_entry = NULL; - - arm7_9->pre_restore_context = NULL; - - /* initialize arch-specific breakpoint handling */ - arm7_9->arm_bkpt = 0xdeeedeee; - arm7_9->thumb_bkpt = 0xdeee; - - arm7_9->dbgreq_adjust_pc = 3; - - arm7_9_init_arch_info(target, arm7_9); - - /* override use of DBGRQ, this is safe on ARM9TDMI */ - arm7_9->use_dbgrq = 1; - - /* all ARM9s have the vector catch register */ - arm7_9->has_vector_catch = 1; - - return ERROR_OK; -} - -static int arm9tdmi_target_create(struct target *target, Jim_Interp *interp) -{ - struct arm7_9_common *arm7_9 = calloc(1, sizeof(struct arm7_9_common)); - - arm9tdmi_init_arch_info(target, arm7_9, target->tap); - arm7_9->arm.is_armv4 = true; - - return ERROR_OK; -} - -COMMAND_HANDLER(handle_arm9tdmi_catch_vectors_command) -{ - struct target *target = get_current_target(CMD_CTX); - struct arm7_9_common *arm7_9 = target_to_arm7_9(target); - struct reg *vector_catch; - uint32_t vector_catch_value; - - if (!target_was_examined(target)) { - LOG_ERROR("Target not examined yet"); - return ERROR_FAIL; - } - - /* it's uncommon, but some ARM7 chips can support this */ - if (arm7_9->common_magic != ARM7_9_COMMON_MAGIC - || !arm7_9->has_vector_catch) { - command_print(CMD_CTX, "target doesn't have EmbeddedICE " - "with vector_catch"); - return ERROR_TARGET_INVALID; - } - - vector_catch = &arm7_9->eice_cache->reg_list[EICE_VEC_CATCH]; - - /* read the vector catch register if necessary */ - if (!vector_catch->valid) - embeddedice_read_reg(vector_catch); - - /* get the current setting */ - vector_catch_value = buf_get_u32(vector_catch->value, 0, 8); - - if (CMD_ARGC > 0) { - vector_catch_value = 0x0; - if (strcmp(CMD_ARGV[0], "all") == 0) - vector_catch_value = 0xdf; - else if (strcmp(CMD_ARGV[0], "none") == 0) { - /* do nothing */ - } else { - for (unsigned i = 0; i < CMD_ARGC; i++) { - /* go through list of vectors */ - unsigned j; - for (j = 0; arm9tdmi_vectors[j].name; j++) { - if (strcmp(CMD_ARGV[i], arm9tdmi_vectors[j].name) == 0) { - vector_catch_value |= arm9tdmi_vectors[j].value; - break; - } - } - - /* complain if vector wasn't found */ - if (!arm9tdmi_vectors[j].name) { - command_print(CMD_CTX, "vector '%s' not found, leaving current setting unchanged", CMD_ARGV[i]); - - /* reread current setting */ - vector_catch_value = buf_get_u32( - vector_catch->value, - 0, 8); - break; - } - } - } - - /* store new settings */ - buf_set_u32(vector_catch->value, 0, 8, vector_catch_value); - embeddedice_store_reg(vector_catch); - } - - /* output current settings */ - for (unsigned i = 0; arm9tdmi_vectors[i].name; i++) { - command_print(CMD_CTX, "%s: %s", arm9tdmi_vectors[i].name, - (vector_catch_value & arm9tdmi_vectors[i].value) - ? "catch" : "don't catch"); - } - - return ERROR_OK; -} - -static const struct command_registration arm9tdmi_exec_command_handlers[] = { - { - .name = "vector_catch", - .handler = handle_arm9tdmi_catch_vectors_command, - .mode = COMMAND_EXEC, - .help = "Display, after optionally updating, configuration " - "of vector catch unit.", - .usage = "[all|none|(reset|undef|swi|pabt|dabt|irq|fiq)*]", - }, - COMMAND_REGISTRATION_DONE -}; -const struct command_registration arm9tdmi_command_handlers[] = { - { - .chain = arm7_9_command_handlers, - }, - { - .name = "arm9", - .mode = COMMAND_ANY, - .help = "arm9 command group", - .usage = "", - .chain = arm9tdmi_exec_command_handlers, - }, - COMMAND_REGISTRATION_DONE -}; - -/** Holds methods for ARM9TDMI targets. */ -struct target_type arm9tdmi_target = { - .name = "arm9tdmi", - - .poll = arm7_9_poll, - .arch_state = arm_arch_state, - - .target_request_data = arm7_9_target_request_data, - - .halt = arm7_9_halt, - .resume = arm7_9_resume, - .step = arm7_9_step, - - .assert_reset = arm7_9_assert_reset, - .deassert_reset = arm7_9_deassert_reset, - .soft_reset_halt = arm7_9_soft_reset_halt, - - .get_gdb_reg_list = arm_get_gdb_reg_list, - - .read_memory = arm7_9_read_memory, - .write_memory = arm7_9_write_memory_opt, - - .checksum_memory = arm_checksum_memory, - .blank_check_memory = arm_blank_check_memory, - - .run_algorithm = armv4_5_run_algorithm, - - .add_breakpoint = arm7_9_add_breakpoint, - .remove_breakpoint = arm7_9_remove_breakpoint, - .add_watchpoint = arm7_9_add_watchpoint, - .remove_watchpoint = arm7_9_remove_watchpoint, - - .commands = arm9tdmi_command_handlers, - .target_create = arm9tdmi_target_create, - .init_target = arm9tdmi_init_target, - .examine = arm7_9_examine, - .check_reset = arm7_9_check_reset, -}; diff --git a/src/target/arm9tdmi.h b/src/target/arm9tdmi.h deleted file mode 100644 index c6f0ccf0f..000000000 --- a/src/target/arm9tdmi.h +++ /dev/null @@ -1,56 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * Copyright (C) 2008 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifndef OPENOCD_TARGET_ARM9TDMI_H -#define OPENOCD_TARGET_ARM9TDMI_H - -#include "embeddedice.h" - -int arm9tdmi_init_target(struct command_context *cmd_ctx, - struct target *target); -int arm9tdmi_init_arch_info(struct target *target, - struct arm7_9_common *arm7_9, struct jtag_tap *tap); -extern const struct command_registration arm9tdmi_command_handlers[]; - -int arm9tdmi_clock_out(struct arm_jtag *jtag_info, - uint32_t instr, uint32_t out, uint32_t *in, int sysspeed); -int arm9tdmi_clock_data_in(struct arm_jtag *jtag_info, uint32_t *in); -int arm9tdmi_clock_data_in_endianness(struct arm_jtag *jtag_info, - void *in, int size, int be); -void arm9tdmi_read_core_regs(struct target *target, - uint32_t mask, uint32_t *core_regs[16]); -void arm9tdmi_write_core_regs(struct target *target, - uint32_t mask, uint32_t core_regs[16]); - -int arm9tdmi_examine_debug_reason(struct target *target); - -void arm9tdmi_load_word_regs(struct target *target, uint32_t mask); -void arm9tdmi_load_hword_reg(struct target *target, int num); -void arm9tdmi_load_byte_reg(struct target *target, int num); -void arm9tdmi_store_word_regs(struct target *target, uint32_t mask); -void arm9tdmi_store_hword_reg(struct target *target, int num); -void arm9tdmi_store_byte_reg(struct target *target, int num); - -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 /* OPENOCD_TARGET_ARM9TDMI_H */ diff --git a/src/target/arm_adi_v5.c b/src/target/arm_adi_v5.c deleted file mode 100644 index f58afdc0a..000000000 --- a/src/target/arm_adi_v5.c +++ /dev/null @@ -1,1700 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2006 by Magnus Lundin * - * lundin@mlu.mine.nu * - * * - * Copyright (C) 2008 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * Copyright (C) 2009-2010 by Oyvind Harboe * - * oyvind.harboe@zylin.com * - * * - * Copyright (C) 2009-2010 by David Brownell * - * * - * Copyright (C) 2013 by Andreas Fritiofson * - * andreas.fritiofson@gmail.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -/** - * @file - * This file implements support for the ARM Debug Interface version 5 (ADIv5) - * debugging architecture. Compared with previous versions, this includes - * a low pin-count Serial Wire Debug (SWD) alternative to JTAG for message - * transport, and focusses on memory mapped resources as defined by the - * CoreSight architecture. - * - * A key concept in ADIv5 is the Debug Access Port, or DAP. A DAP has two - * basic components: a Debug Port (DP) transporting messages to and from a - * debugger, and an Access Port (AP) accessing resources. Three types of DP - * are defined. One uses only JTAG for communication, and is called JTAG-DP. - * One uses only SWD for communication, and is called SW-DP. The third can - * use either SWD or JTAG, and is called SWJ-DP. The most common type of AP - * is used to access memory mapped resources and is called a MEM-AP. Also a - * JTAG-AP is also defined, bridging to JTAG resources; those are uncommon. - * - * This programming interface allows DAP pipelined operations through a - * transaction queue. This primarily affects AP operations (such as using - * a MEM-AP to access memory or registers). If the current transaction has - * not finished by the time the next one must begin, and the ORUNDETECT bit - * is set in the DP_CTRL_STAT register, the SSTICKYORUN status is set and - * further AP operations will fail. There are two basic methods to avoid - * such overrun errors. One involves polling for status instead of using - * transaction piplining. The other involves adding delays to ensure the - * AP has enough time to complete one operation before starting the next - * one. (For JTAG these delays are controlled by memaccess_tck.) - */ - -/* - * Relevant specifications from ARM include: - * - * ARM(tm) Debug Interface v5 Architecture Specification ARM IHI 0031A - * CoreSight(tm) v1.0 Architecture Specification ARM IHI 0029B - * - * CoreSight(tm) DAP-Lite TRM, ARM DDI 0316D - * Cortex-M3(tm) TRM, ARM DDI 0337G - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#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 */ - -/* - uint32_t tar_block_size(uint32_t address) - Return the largest block starting at address that does not cross a tar block size alignment boundary -*/ -static uint32_t max_tar_block_size(uint32_t tar_autoincr_block, uint32_t address) -{ - return tar_autoincr_block - ((tar_autoincr_block - 1) & address); -} - -/*************************************************************************** - * * - * DP and MEM-AP register access through APACC and DPACC * - * * -***************************************************************************/ - -static int mem_ap_setup_csw(struct adiv5_ap *ap, uint32_t csw) -{ - csw = csw | CSW_DBGSWENABLE | CSW_MASTER_DEBUG | CSW_HPROT | - ap->csw_default; - - if (csw != ap->csw_value) { - /* LOG_DEBUG("DAP: Set CSW %x",csw); */ - int retval = dap_queue_ap_write(ap, MEM_AP_REG_CSW, csw); - if (retval != ERROR_OK) - return retval; - ap->csw_value = csw; - } - return ERROR_OK; -} - -static int mem_ap_setup_tar(struct adiv5_ap *ap, uint32_t tar) -{ - if (tar != ap->tar_value || - (ap->csw_value & CSW_ADDRINC_MASK)) { - /* LOG_DEBUG("DAP: Set TAR %x",tar); */ - int retval = dap_queue_ap_write(ap, MEM_AP_REG_TAR, tar); - if (retval != ERROR_OK) - return retval; - ap->tar_value = tar; - } - return ERROR_OK; -} - -/** - * Queue transactions setting up transfer parameters for the - * currently selected MEM-AP. - * - * Subsequent transfers using registers like MEM_AP_REG_DRW or MEM_AP_REG_BD2 - * initiate data reads or writes using memory or peripheral addresses. - * If the CSW is configured for it, the TAR may be automatically - * incremented after each transfer. - * - * @param ap The MEM-AP. - * @param csw MEM-AP Control/Status Word (CSW) register to assign. If this - * matches the cached value, the register is not changed. - * @param tar MEM-AP Transfer Address Register (TAR) to assign. If this - * matches the cached address, the register is not changed. - * - * @return ERROR_OK if the transaction was properly queued, else a fault code. - */ -static int mem_ap_setup_transfer(struct adiv5_ap *ap, uint32_t csw, uint32_t tar) -{ - int retval; - retval = mem_ap_setup_csw(ap, csw); - if (retval != ERROR_OK) - return retval; - retval = mem_ap_setup_tar(ap, tar); - if (retval != ERROR_OK) - return retval; - return ERROR_OK; -} - -/** - * Asynchronous (queued) read of a word from memory or a system register. - * - * @param ap The MEM-AP to access. - * @param address Address of the 32-bit word to read; it must be - * readable by the currently selected MEM-AP. - * @param value points to where the word will be stored when the - * transaction queue is flushed (assuming no errors). - * - * @return ERROR_OK for success. Otherwise a fault code. - */ -int mem_ap_read_u32(struct adiv5_ap *ap, uint32_t address, - uint32_t *value) -{ - int retval; - - /* Use banked addressing (REG_BDx) to avoid some link traffic - * (updating TAR) when reading several consecutive addresses. - */ - retval = mem_ap_setup_transfer(ap, CSW_32BIT | CSW_ADDRINC_OFF, - address & 0xFFFFFFF0); - if (retval != ERROR_OK) - return retval; - - return dap_queue_ap_read(ap, MEM_AP_REG_BD0 | (address & 0xC), value); -} - -/** - * Synchronous read of a word from memory or a system register. - * As a side effect, this flushes any queued transactions. - * - * @param ap The MEM-AP to access. - * @param address Address of the 32-bit word to read; it must be - * readable by the currently selected MEM-AP. - * @param value points to where the result will be stored. - * - * @return ERROR_OK for success; *value holds the result. - * Otherwise a fault code. - */ -int mem_ap_read_atomic_u32(struct adiv5_ap *ap, uint32_t address, - uint32_t *value) -{ - int retval; - - retval = mem_ap_read_u32(ap, address, value); - if (retval != ERROR_OK) - return retval; - - return dap_run(ap->dap); -} - -/** - * Asynchronous (queued) write of a word to memory or a system register. - * - * @param ap The MEM-AP to access. - * @param address Address to be written; it must be writable by - * the currently selected MEM-AP. - * @param value Word that will be written to the address when transaction - * queue is flushed (assuming no errors). - * - * @return ERROR_OK for success. Otherwise a fault code. - */ -int mem_ap_write_u32(struct adiv5_ap *ap, uint32_t address, - uint32_t value) -{ - int retval; - - /* Use banked addressing (REG_BDx) to avoid some link traffic - * (updating TAR) when writing several consecutive addresses. - */ - retval = mem_ap_setup_transfer(ap, CSW_32BIT | CSW_ADDRINC_OFF, - address & 0xFFFFFFF0); - if (retval != ERROR_OK) - return retval; - - return dap_queue_ap_write(ap, MEM_AP_REG_BD0 | (address & 0xC), - value); -} - -/** - * Synchronous write of a word to memory or a system register. - * As a side effect, this flushes any queued transactions. - * - * @param ap The MEM-AP to access. - * @param address Address to be written; it must be writable by - * the currently selected MEM-AP. - * @param value Word that will be written. - * - * @return ERROR_OK for success; the data was written. Otherwise a fault code. - */ -int mem_ap_write_atomic_u32(struct adiv5_ap *ap, uint32_t address, - uint32_t value) -{ - int retval = mem_ap_write_u32(ap, address, value); - - if (retval != ERROR_OK) - return retval; - - return dap_run(ap->dap); -} - -/** - * Synchronous write of a block of memory, using a specific access size. - * - * @param ap The MEM-AP to access. - * @param buffer The data buffer to write. No particular alignment is assumed. - * @param size Which access size to use, in bytes. 1, 2 or 4. - * @param count The number of writes to do (in size units, not bytes). - * @param address Address to be written; it must be writable by the currently selected MEM-AP. - * @param addrinc Whether the target address should be increased for each write or not. This - * should normally be true, except when writing to e.g. a FIFO. - * @return ERROR_OK on success, otherwise an error code. - */ -static int mem_ap_write(struct adiv5_ap *ap, const uint8_t *buffer, uint32_t size, uint32_t count, - uint32_t address, bool addrinc) -{ - struct adiv5_dap *dap = ap->dap; - size_t nbytes = size * count; - const uint32_t csw_addrincr = addrinc ? CSW_ADDRINC_SINGLE : CSW_ADDRINC_OFF; - uint32_t csw_size; - uint32_t addr_xor; - int retval; - - /* TI BE-32 Quirks mode: - * Writes on big-endian TMS570 behave very strangely. Observed behavior: - * size write address bytes written in order - * 4 TAR ^ 0 (val >> 24), (val >> 16), (val >> 8), (val) - * 2 TAR ^ 2 (val >> 8), (val) - * 1 TAR ^ 3 (val) - * For example, if you attempt to write a single byte to address 0, the processor - * will actually write a byte to address 3. - * - * To make writes of size < 4 work as expected, we xor a value with the address before - * setting the TAP, and we set the TAP after every transfer rather then relying on - * address increment. */ - - if (size == 4) { - csw_size = CSW_32BIT; - addr_xor = 0; - } else if (size == 2) { - csw_size = CSW_16BIT; - addr_xor = dap->ti_be_32_quirks ? 2 : 0; - } else if (size == 1) { - csw_size = CSW_8BIT; - addr_xor = dap->ti_be_32_quirks ? 3 : 0; - } else { - return ERROR_TARGET_UNALIGNED_ACCESS; - } - - if (ap->unaligned_access_bad && (address % size != 0)) - return ERROR_TARGET_UNALIGNED_ACCESS; - - retval = mem_ap_setup_tar(ap, address ^ addr_xor); - if (retval != ERROR_OK) - return retval; - - while (nbytes > 0) { - uint32_t this_size = size; - - /* Select packed transfer if possible */ - if (addrinc && ap->packed_transfers && nbytes >= 4 - && max_tar_block_size(ap->tar_autoincr_block, address) >= 4) { - this_size = 4; - retval = mem_ap_setup_csw(ap, csw_size | CSW_ADDRINC_PACKED); - } else { - retval = mem_ap_setup_csw(ap, csw_size | csw_addrincr); - } - - if (retval != ERROR_OK) - break; - - /* How many source bytes each transfer will consume, and their location in the DRW, - * depends on the type of transfer and alignment. See ARM document IHI0031C. */ - uint32_t outvalue = 0; - if (dap->ti_be_32_quirks) { - switch (this_size) { - case 4: - outvalue |= (uint32_t)*buffer++ << 8 * (3 ^ (address++ & 3) ^ addr_xor); - outvalue |= (uint32_t)*buffer++ << 8 * (3 ^ (address++ & 3) ^ addr_xor); - outvalue |= (uint32_t)*buffer++ << 8 * (3 ^ (address++ & 3) ^ addr_xor); - outvalue |= (uint32_t)*buffer++ << 8 * (3 ^ (address++ & 3) ^ addr_xor); - break; - case 2: - outvalue |= (uint32_t)*buffer++ << 8 * (1 ^ (address++ & 3) ^ addr_xor); - outvalue |= (uint32_t)*buffer++ << 8 * (1 ^ (address++ & 3) ^ addr_xor); - break; - case 1: - outvalue |= (uint32_t)*buffer++ << 8 * (0 ^ (address++ & 3) ^ addr_xor); - break; - } - } else { - switch (this_size) { - case 4: - outvalue |= (uint32_t)*buffer++ << 8 * (address++ & 3); - outvalue |= (uint32_t)*buffer++ << 8 * (address++ & 3); - case 2: - outvalue |= (uint32_t)*buffer++ << 8 * (address++ & 3); - case 1: - outvalue |= (uint32_t)*buffer++ << 8 * (address++ & 3); - } - } - - nbytes -= this_size; - - retval = dap_queue_ap_write(ap, MEM_AP_REG_DRW, outvalue); - if (retval != ERROR_OK) - break; - - /* Rewrite TAR if it wrapped or we're xoring addresses */ - if (addrinc && (addr_xor || (address % ap->tar_autoincr_block < size && nbytes > 0))) { - retval = mem_ap_setup_tar(ap, address ^ addr_xor); - if (retval != ERROR_OK) - break; - } - } - - /* REVISIT: Might want to have a queued version of this function that does not run. */ - if (retval == ERROR_OK) - retval = dap_run(dap); - - if (retval != ERROR_OK) { - uint32_t tar; - if (dap_queue_ap_read(ap, MEM_AP_REG_TAR, &tar) == ERROR_OK - && dap_run(dap) == ERROR_OK) - LOG_ERROR("Failed to write memory at 0x%08"PRIx32, tar); - else - LOG_ERROR("Failed to write memory and, additionally, failed to find out where"); - } - - return retval; -} - -/** - * Synchronous read of a block of memory, using a specific access size. - * - * @param ap The MEM-AP to access. - * @param buffer The data buffer to receive the data. No particular alignment is assumed. - * @param size Which access size to use, in bytes. 1, 2 or 4. - * @param count The number of reads to do (in size units, not bytes). - * @param address Address to be read; it must be readable by the currently selected MEM-AP. - * @param addrinc Whether the target address should be increased after each read or not. This - * should normally be true, except when reading from e.g. a FIFO. - * @return ERROR_OK on success, otherwise an error code. - */ -static int mem_ap_read(struct adiv5_ap *ap, uint8_t *buffer, uint32_t size, uint32_t count, - uint32_t adr, bool addrinc) -{ - struct adiv5_dap *dap = ap->dap; - size_t nbytes = size * count; - const uint32_t csw_addrincr = addrinc ? CSW_ADDRINC_SINGLE : CSW_ADDRINC_OFF; - uint32_t csw_size; - uint32_t address = adr; - int retval; - - /* TI BE-32 Quirks mode: - * Reads on big-endian TMS570 behave strangely differently than writes. - * They read from the physical address requested, but with DRW byte-reversed. - * For example, a byte read from address 0 will place the result in the high bytes of DRW. - * Also, packed 8-bit and 16-bit transfers seem to sometimes return garbage in some bytes, - * so avoid them. */ - - if (size == 4) - csw_size = CSW_32BIT; - else if (size == 2) - csw_size = CSW_16BIT; - else if (size == 1) - csw_size = CSW_8BIT; - else - return ERROR_TARGET_UNALIGNED_ACCESS; - - if (ap->unaligned_access_bad && (adr % size != 0)) - return ERROR_TARGET_UNALIGNED_ACCESS; - - /* Allocate buffer to hold the sequence of DRW reads that will be made. This is a significant - * over-allocation if packed transfers are going to be used, but determining the real need at - * this point would be messy. */ - uint32_t *read_buf = malloc(count * sizeof(uint32_t)); - uint32_t *read_ptr = read_buf; - if (read_buf == NULL) { - LOG_ERROR("Failed to allocate read buffer"); - return ERROR_FAIL; - } - - retval = mem_ap_setup_tar(ap, address); - if (retval != ERROR_OK) { - free(read_buf); - return retval; - } - - /* Queue up all reads. Each read will store the entire DRW word in the read buffer. How many - * useful bytes it contains, and their location in the word, depends on the type of transfer - * and alignment. */ - while (nbytes > 0) { - uint32_t this_size = size; - - /* Select packed transfer if possible */ - if (addrinc && ap->packed_transfers && nbytes >= 4 - && max_tar_block_size(ap->tar_autoincr_block, address) >= 4) { - this_size = 4; - retval = mem_ap_setup_csw(ap, csw_size | CSW_ADDRINC_PACKED); - } else { - retval = mem_ap_setup_csw(ap, csw_size | csw_addrincr); - } - if (retval != ERROR_OK) - break; - - retval = dap_queue_ap_read(ap, MEM_AP_REG_DRW, read_ptr++); - if (retval != ERROR_OK) - break; - - nbytes -= this_size; - address += this_size; - - /* Rewrite TAR if it wrapped */ - if (addrinc && address % ap->tar_autoincr_block < size && nbytes > 0) { - retval = mem_ap_setup_tar(ap, address); - if (retval != ERROR_OK) - break; - } - } - - if (retval == ERROR_OK) - retval = dap_run(dap); - - /* Restore state */ - address = adr; - nbytes = size * count; - read_ptr = read_buf; - - /* If something failed, read TAR to find out how much data was successfully read, so we can - * at least give the caller what we have. */ - if (retval != ERROR_OK) { - uint32_t tar; - if (dap_queue_ap_read(ap, MEM_AP_REG_TAR, &tar) == ERROR_OK - && dap_run(dap) == ERROR_OK) { - LOG_ERROR("Failed to read memory at 0x%08"PRIx32, tar); - if (nbytes > tar - address) - nbytes = tar - address; - } else { - LOG_ERROR("Failed to read memory and, additionally, failed to find out where"); - nbytes = 0; - } - } - - /* Replay loop to populate caller's buffer from the correct word and byte lane */ - while (nbytes > 0) { - uint32_t this_size = size; - - if (addrinc && ap->packed_transfers && nbytes >= 4 - && max_tar_block_size(ap->tar_autoincr_block, address) >= 4) { - this_size = 4; - } - - if (dap->ti_be_32_quirks) { - switch (this_size) { - case 4: - *buffer++ = *read_ptr >> 8 * (3 - (address++ & 3)); - *buffer++ = *read_ptr >> 8 * (3 - (address++ & 3)); - case 2: - *buffer++ = *read_ptr >> 8 * (3 - (address++ & 3)); - case 1: - *buffer++ = *read_ptr >> 8 * (3 - (address++ & 3)); - } - } else { - switch (this_size) { - case 4: - *buffer++ = *read_ptr >> 8 * (address++ & 3); - *buffer++ = *read_ptr >> 8 * (address++ & 3); - case 2: - *buffer++ = *read_ptr >> 8 * (address++ & 3); - case 1: - *buffer++ = *read_ptr >> 8 * (address++ & 3); - } - } - - read_ptr++; - nbytes -= this_size; - } - - free(read_buf); - return retval; -} - -int mem_ap_read_buf(struct adiv5_ap *ap, - uint8_t *buffer, uint32_t size, uint32_t count, uint32_t address) -{ - return mem_ap_read(ap, buffer, size, count, address, true); -} - -int mem_ap_write_buf(struct adiv5_ap *ap, - const uint8_t *buffer, uint32_t size, uint32_t count, uint32_t address) -{ - return mem_ap_write(ap, buffer, size, count, address, true); -} - -int mem_ap_read_buf_noincr(struct adiv5_ap *ap, - uint8_t *buffer, uint32_t size, uint32_t count, uint32_t address) -{ - return mem_ap_read(ap, buffer, size, count, address, false); -} - -int mem_ap_write_buf_noincr(struct adiv5_ap *ap, - const uint8_t *buffer, uint32_t size, uint32_t count, uint32_t address) -{ - return mem_ap_write(ap, buffer, size, count, address, false); -} - -/*--------------------------------------------------------------------------*/ - - -#define DAP_POWER_DOMAIN_TIMEOUT (10) - -/* FIXME don't import ... just initialize as - * part of DAP transport setup -*/ -extern const struct dap_ops jtag_dp_ops; - -/*--------------------------------------------------------------------------*/ - -/** - * Create a new DAP - */ -struct adiv5_dap *dap_init(void) -{ - struct adiv5_dap *dap = calloc(1, sizeof(struct adiv5_dap)); - int i; - /* Set up with safe defaults */ - for (i = 0; i <= 255; i++) { - dap->ap[i].dap = dap; - dap->ap[i].ap_num = i; - /* memaccess_tck max is 255 */ - dap->ap[i].memaccess_tck = 255; - /* 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; -} - -/** - * Initialize a DAP. This sets up the power domains, prepares the DP - * for further use and activates overrun checking. - * - * @param dap The DAP being initialized. - */ -int dap_dp_init(struct adiv5_dap *dap) -{ - int retval; - - LOG_DEBUG(" "); - /* JTAG-DP or SWJ-DP, in JTAG mode - * ... for SWD mode this is patched as part - * of link switchover - * FIXME: This should already be setup by the respective transport specific DAP creation. - */ - if (!dap->ops) - dap->ops = &jtag_dp_ops; - - dap->select = DP_SELECT_INVALID; - dap->last_read = NULL; - - for (size_t i = 0; i < 10; 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_queue_dp_read(dap, DP_CTRL_STAT, NULL); - 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) - 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) - 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) - continue; - - retval = dap_queue_dp_read(dap, DP_CTRL_STAT, NULL); - 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) - continue; - retval = dap_queue_dp_read(dap, DP_CTRL_STAT, NULL); - if (retval != ERROR_OK) - continue; - - retval = dap_run(dap); - if (retval != ERROR_OK) - continue; - - break; - } - - return retval; -} - -/** - * Initialize a DAP. This sets up the power domains, prepares the DP - * for further use, and arranges to use AP #0 for all AP operations - * until dap_ap-select() changes that policy. - * - * @param ap The MEM-AP being initialized. - */ -int mem_ap_init(struct adiv5_ap *ap) -{ - /* check that we support packed transfers */ - uint32_t csw, cfg; - int retval; - struct adiv5_dap *dap = ap->dap; - - retval = mem_ap_setup_transfer(ap, CSW_8BIT | CSW_ADDRINC_PACKED, 0); - if (retval != ERROR_OK) - return retval; - - retval = dap_queue_ap_read(ap, MEM_AP_REG_CSW, &csw); - if (retval != ERROR_OK) - return retval; - - retval = dap_queue_ap_read(ap, MEM_AP_REG_CFG, &cfg); - if (retval != ERROR_OK) - return retval; - - retval = dap_run(dap); - if (retval != ERROR_OK) - return retval; - - if (csw & CSW_ADDRINC_PACKED) - ap->packed_transfers = true; - else - ap->packed_transfers = false; - - /* Packed transfers on TI BE-32 processors do not work correctly in - * many cases. */ - if (dap->ti_be_32_quirks) - ap->packed_transfers = false; - - LOG_DEBUG("MEM_AP Packed Transfers: %s", - ap->packed_transfers ? "enabled" : "disabled"); - - /* The ARM ADI spec leaves implementation-defined whether unaligned - * memory accesses work, only work partially, or cause a sticky error. - * On TI BE-32 processors, reads seem to return garbage in some bytes - * and unaligned writes seem to cause a sticky error. - * TODO: it would be nice to have a way to detect whether unaligned - * operations are supported on other processors. */ - ap->unaligned_access_bad = dap->ti_be_32_quirks; - - LOG_DEBUG("MEM_AP CFG: large data %d, long address %d, big-endian %d", - !!(cfg & 0x04), !!(cfg & 0x02), !!(cfg & 0x01)); - - return ERROR_OK; -} - -/* CID interpretation -- see ARM IHI 0029B section 3 - * and ARM IHI 0031A table 13-3. - */ -static const char *class_description[16] = { - "Reserved", "ROM table", "Reserved", "Reserved", - "Reserved", "Reserved", "Reserved", "Reserved", - "Reserved", "CoreSight component", "Reserved", "Peripheral Test Block", - "Reserved", "OptimoDE DESS", - "Generic IP component", "PrimeCell or System component" -}; - -static bool is_dap_cid_ok(uint32_t cid) -{ - return (cid & 0xffff0fff) == 0xb105000d; -} - -/* - * This function checks the ID for each access port to find the requested Access Port type - */ -int dap_find_ap(struct adiv5_dap *dap, enum ap_type type_to_find, struct adiv5_ap **ap_out) -{ - int ap_num; - - /* Maximum AP number is 255 since the SELECT register is 8 bits */ - for (ap_num = 0; ap_num <= 255; ap_num++) { - - /* read the IDR register of the Access Port */ - uint32_t id_val = 0; - - int retval = dap_queue_ap_read(dap_ap(dap, ap_num), AP_REG_IDR, &id_val); - if (retval != ERROR_OK) - return retval; - - retval = dap_run(dap); - - /* IDR bits: - * 31-28 : Revision - * 27-24 : JEDEC bank (0x4 for ARM) - * 23-17 : JEDEC code (0x3B for ARM) - * 16-13 : Class (0b1000=Mem-AP) - * 12-8 : Reserved - * 7-4 : AP Variant (non-zero for JTAG-AP) - * 3-0 : AP Type (0=JTAG-AP 1=AHB-AP 2=APB-AP 4=AXI-AP) - */ - - /* Reading register for a non-existant AP should not cause an error, - * but just to be sure, try to continue searching if an error does happen. - */ - if ((retval == ERROR_OK) && /* Register read success */ - ((id_val & IDR_JEP106) == IDR_JEP106_ARM) && /* Jedec codes match */ - ((id_val & IDR_TYPE) == type_to_find)) { /* type matches*/ - - LOG_DEBUG("Found %s at AP index: %d (IDR=0x%08" PRIX32 ")", - (type_to_find == AP_TYPE_AHB_AP) ? "AHB-AP" : - (type_to_find == AP_TYPE_APB_AP) ? "APB-AP" : - (type_to_find == AP_TYPE_AXI_AP) ? "AXI-AP" : - (type_to_find == AP_TYPE_JTAG_AP) ? "JTAG-AP" : "Unknown", - ap_num, id_val); - - *ap_out = &dap->ap[ap_num]; - return ERROR_OK; - } - } - - LOG_DEBUG("No %s found", - (type_to_find == AP_TYPE_AHB_AP) ? "AHB-AP" : - (type_to_find == AP_TYPE_APB_AP) ? "APB-AP" : - (type_to_find == AP_TYPE_AXI_AP) ? "AXI-AP" : - (type_to_find == AP_TYPE_JTAG_AP) ? "JTAG-AP" : "Unknown"); - return ERROR_FAIL; -} - -int dap_get_debugbase(struct adiv5_ap *ap, - uint32_t *dbgbase, uint32_t *apid) -{ - struct adiv5_dap *dap = ap->dap; - int retval; - - retval = dap_queue_ap_read(ap, MEM_AP_REG_BASE, dbgbase); - if (retval != ERROR_OK) - return retval; - retval = dap_queue_ap_read(ap, AP_REG_IDR, apid); - if (retval != ERROR_OK) - return retval; - retval = dap_run(dap); - if (retval != ERROR_OK) - return retval; - - return ERROR_OK; -} - -int dap_lookup_cs_component(struct adiv5_ap *ap, - uint32_t dbgbase, uint8_t type, uint32_t *addr, int32_t *idx) -{ - uint32_t romentry, entry_offset = 0, component_base, devtype; - int retval; - - *addr = 0; - - do { - retval = mem_ap_read_atomic_u32(ap, (dbgbase&0xFFFFF000) | - entry_offset, &romentry); - if (retval != ERROR_OK) - return retval; - - component_base = (dbgbase & 0xFFFFF000) - + (romentry & 0xFFFFF000); - - if (romentry & 0x1) { - uint32_t c_cid1; - retval = mem_ap_read_atomic_u32(ap, component_base | 0xff4, &c_cid1); - if (retval != ERROR_OK) { - LOG_ERROR("Can't read component with base address 0x%" PRIx32 - ", the corresponding core might be turned off", component_base); - return retval; - } - if (((c_cid1 >> 4) & 0x0f) == 1) { - retval = dap_lookup_cs_component(ap, component_base, - type, addr, idx); - if (retval == ERROR_OK) - break; - if (retval != ERROR_TARGET_RESOURCE_NOT_AVAILABLE) - return retval; - } - - retval = mem_ap_read_atomic_u32(ap, - (component_base & 0xfffff000) | 0xfcc, - &devtype); - if (retval != ERROR_OK) - return retval; - if ((devtype & 0xff) == type) { - if (!*idx) { - *addr = component_base; - break; - } else - (*idx)--; - } - } - entry_offset += 4; - } while (romentry > 0); - - if (!*addr) - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - - 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 - * a legacy ASCII Identity Code. - * bits 6:0 : JEP106 Identity Code (without parity) or legacy ASCII code according to bit 7. - * JEP106 is a standard available from jedec.org - */ - -/* Part number interpretations are from Cortex - * core specs, the CoreSight components TRM - * (ARM DDI 0314H), CoreSight System Design - * Guide (ARM DGI 0012D) and ETM specs; also - * from chip observation (e.g. TI SDTI). - */ - -/* The legacy code only used the part number field to identify CoreSight peripherals. - * This meant that the same part number from two different manufacturers looked the same. - * It is desirable for all future additions to identify with both part number and JEP106. - * "ANY_ID" is a wildcard (any JEP106) only to preserve legacy behavior for legacy entries. - */ - -#define ANY_ID 0x1000 - -#define ARM_ID 0x4BB - -static const struct { - uint16_t designer_id; - uint16_t part_num; - 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 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 */ -}; - -static int dap_rom_display(struct command_context *cmd_ctx, - struct adiv5_ap *ap, uint32_t dbgbase, int depth) -{ - int retval; - uint64_t pid; - uint32_t cid; - char tabs[7] = ""; - - if (depth > 16) { - command_print(cmd_ctx, "\tTables too deep"); - return ERROR_FAIL; - } - - if (depth) - snprintf(tabs, sizeof(tabs), "[L%02d] ", depth); - - uint32_t base_addr = dbgbase & 0xFFFFF000; - command_print(cmd_ctx, "\t\tComponent base address 0x%08" PRIx32, base_addr); - - 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(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)); - - 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; - - 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; - 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; - } 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"; - - 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; - } - 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 */ - } - - return ERROR_OK; -} - -static int dap_info_command(struct command_context *cmd_ctx, - struct adiv5_ap *ap) -{ - int retval; - uint32_t dbgbase, apid; - uint8_t mem_ap; - - /* Now we read ROM table ID registers, ref. ARM IHI 0029B sec */ - retval = dap_get_debugbase(ap, &dbgbase, &apid); - if (retval != ERROR_OK) - return retval; - - command_print(cmd_ctx, "AP ID register 0x%8.8" PRIx32, apid); - if (apid == 0) { - command_print(cmd_ctx, "No AP found at this ap 0x%x", ap->ap_num); - return ERROR_FAIL; - } - - switch (apid & (IDR_JEP106 | IDR_TYPE)) { - case IDR_JEP106_ARM | AP_TYPE_JTAG_AP: - command_print(cmd_ctx, "\tType is JTAG-AP"); - break; - case IDR_JEP106_ARM | AP_TYPE_AHB_AP: - command_print(cmd_ctx, "\tType is MEM-AP AHB"); - break; - case IDR_JEP106_ARM | AP_TYPE_APB_AP: - command_print(cmd_ctx, "\tType is MEM-AP APB"); - break; - case IDR_JEP106_ARM | AP_TYPE_AXI_AP: - command_print(cmd_ctx, "\tType is MEM-AP AXI"); - break; - default: - command_print(cmd_ctx, "\tUnknown AP type"); - break; - } - - /* NOTE: a MEM-AP may have a single CoreSight component that's - * not a ROM table ... or have no such components at all. - */ - mem_ap = (apid & IDR_CLASS) == AP_CLASS_MEM_AP; - if (mem_ap) { - command_print(cmd_ctx, "MEM-AP BASE 0x%8.8" PRIx32, dbgbase); - - 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; -} - -COMMAND_HANDLER(handle_dap_info_command) -{ - struct target *target = get_current_target(CMD_CTX); - struct arm *arm = target_to_arm(target); - struct adiv5_dap *dap = arm->dap; - uint32_t apsel; - - switch (CMD_ARGC) { - case 0: - apsel = dap->apsel; - break; - case 1: - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], apsel); - if (apsel >= 256) - return ERROR_COMMAND_SYNTAX_ERROR; - break; - default: - return ERROR_COMMAND_SYNTAX_ERROR; - } - - return dap_info_command(CMD_CTX, &dap->ap[apsel]); -} - -COMMAND_HANDLER(dap_baseaddr_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, baseaddr; - int retval; - - switch (CMD_ARGC) { - case 0: - apsel = dap->apsel; - break; - case 1: - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], apsel); - /* AP address is in bits 31:24 of DP_SELECT */ - if (apsel >= 256) - return ERROR_COMMAND_SYNTAX_ERROR; - break; - default: - return ERROR_COMMAND_SYNTAX_ERROR; - } - - /* NOTE: assumes we're talking to a MEM-AP, which - * has a base address. There are other kinds of AP, - * though they're not common for now. This should - * use the ID register to verify it's a MEM-AP. - */ - retval = dap_queue_ap_read(dap_ap(dap, apsel), MEM_AP_REG_BASE, &baseaddr); - if (retval != ERROR_OK) - return retval; - retval = dap_run(dap); - if (retval != ERROR_OK) - return retval; - - command_print(CMD_CTX, "0x%8.8" PRIx32, baseaddr); - - return retval; -} - -COMMAND_HANDLER(dap_memaccess_command) -{ - struct target *target = get_current_target(CMD_CTX); - struct arm *arm = target_to_arm(target); - struct adiv5_dap *dap = arm->dap; - - uint32_t memaccess_tck; - - switch (CMD_ARGC) { - case 0: - memaccess_tck = dap->ap[dap->apsel].memaccess_tck; - break; - case 1: - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], memaccess_tck); - break; - default: - return ERROR_COMMAND_SYNTAX_ERROR; - } - dap->ap[dap->apsel].memaccess_tck = memaccess_tck; - - command_print(CMD_CTX, "memory bus access delay set to %" PRIi32 " tck", - dap->ap[dap->apsel].memaccess_tck); - - return ERROR_OK; -} - -COMMAND_HANDLER(dap_apsel_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, apid; - int retval; - - switch (CMD_ARGC) { - case 0: - apsel = dap->apsel; - break; - case 1: - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], apsel); - /* AP address is in bits 31:24 of DP_SELECT */ - if (apsel >= 256) - return ERROR_COMMAND_SYNTAX_ERROR; - break; - default: - return ERROR_COMMAND_SYNTAX_ERROR; - } - - dap->apsel = apsel; - - retval = dap_queue_ap_read(dap_ap(dap, apsel), AP_REG_IDR, &apid); - if (retval != ERROR_OK) - return retval; - retval = dap_run(dap); - if (retval != ERROR_OK) - return retval; - - command_print(CMD_CTX, "ap %" PRIi32 " selected, identification register 0x%8.8" PRIx32, - apsel, apid); - - return retval; -} - -COMMAND_HANDLER(dap_apcsw_command) -{ - struct target *target = get_current_target(CMD_CTX); - struct arm *arm = target_to_arm(target); - struct adiv5_dap *dap = arm->dap; - - uint32_t apcsw = dap->ap[dap->apsel].csw_default, sprot = 0; - - switch (CMD_ARGC) { - case 0: - command_print(CMD_CTX, "apsel %" PRIi32 " selected, csw 0x%8.8" PRIx32, - (dap->apsel), apcsw); - break; - case 1: - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], sprot); - /* AP address is in bits 31:24 of DP_SELECT */ - if (sprot > 1) - return ERROR_COMMAND_SYNTAX_ERROR; - if (sprot) - apcsw |= CSW_SPROT; - else - apcsw &= ~CSW_SPROT; - break; - default: - return ERROR_COMMAND_SYNTAX_ERROR; - } - dap->ap[dap->apsel].csw_default = apcsw; - - return 0; -} - - - -COMMAND_HANDLER(dap_apid_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, apid; - int retval; - - switch (CMD_ARGC) { - case 0: - apsel = dap->apsel; - break; - case 1: - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], apsel); - /* AP address is in bits 31:24 of DP_SELECT */ - if (apsel >= 256) - return ERROR_COMMAND_SYNTAX_ERROR; - break; - default: - return ERROR_COMMAND_SYNTAX_ERROR; - } - - retval = dap_queue_ap_read(dap_ap(dap, apsel), AP_REG_IDR, &apid); - if (retval != ERROR_OK) - return retval; - retval = dap_run(dap); - if (retval != ERROR_OK) - return retval; - - command_print(CMD_CTX, "0x%8.8" PRIx32, apid); - - 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); - struct arm *arm = target_to_arm(target); - struct adiv5_dap *dap = arm->dap; - - uint32_t enable = dap->ti_be_32_quirks; - - switch (CMD_ARGC) { - case 0: - break; - case 1: - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], enable); - if (enable > 1) - return ERROR_COMMAND_SYNTAX_ERROR; - break; - default: - return ERROR_COMMAND_SYNTAX_ERROR; - } - dap->ti_be_32_quirks = enable; - command_print(CMD_CTX, "TI BE-32 quirks mode %s", - enable ? "enabled" : "disabled"); - - return 0; -} - -static const struct command_registration dap_commands[] = { - { - .name = "info", - .handler = handle_dap_info_command, - .mode = COMMAND_EXEC, - .help = "display ROM table for MEM-AP " - "(default currently selected AP)", - .usage = "[ap_num]", - }, - { - .name = "apsel", - .handler = dap_apsel_command, - .mode = COMMAND_EXEC, - .help = "Set the currently selected AP (default 0) " - "and display the result", - .usage = "[ap_num]", - }, - { - .name = "apcsw", - .handler = dap_apcsw_command, - .mode = COMMAND_EXEC, - .help = "Set csw access bit ", - .usage = "[sprot]", - }, - - { - .name = "apid", - .handler = dap_apid_command, - .mode = COMMAND_EXEC, - .help = "return ID register from AP " - "(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, - .mode = COMMAND_EXEC, - .help = "return debug base address from MEM-AP " - "(default currently selected AP)", - .usage = "[ap_num]", - }, - { - .name = "memaccess", - .handler = dap_memaccess_command, - .mode = COMMAND_EXEC, - .help = "set/get number of extra tck for MEM-AP memory " - "bus access [0-255]", - .usage = "[cycles]", - }, - { - .name = "ti_be_32_quirks", - .handler = dap_ti_be_32_quirks_command, - .mode = COMMAND_CONFIG, - .help = "set/get quirks mode for TI TMS450/TMS570 processors", - .usage = "[enable]", - }, - COMMAND_REGISTRATION_DONE -}; - -const struct command_registration dap_command_handlers[] = { - { - .name = "dap", - .mode = COMMAND_EXEC, - .help = "DAP command group", - .usage = "", - .chain = dap_commands, - }, - COMMAND_REGISTRATION_DONE -}; diff --git a/src/target/arm_adi_v5.h b/src/target/arm_adi_v5.h deleted file mode 100644 index 3220d8b6d..000000000 --- a/src/target/arm_adi_v5.h +++ /dev/null @@ -1,507 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2006 by Magnus Lundin * - * lundin@mlu.mine.nu * - * * - * Copyright (C) 2008 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifndef OPENOCD_TARGET_ARM_ADI_V5_H -#define OPENOCD_TARGET_ARM_ADI_V5_H - -/** - * @file - * This defines formats and data structures used to talk to ADIv5 entities. - * Those include a DAP, different types of Debug Port (DP), and memory mapped - * resources accessed through a MEM-AP. - */ - -#include -#include "arm_jtag.h" - -/* three-bit ACK values for SWD access (sent LSB first) */ -#define SWD_ACK_OK 0x1 -#define SWD_ACK_WAIT 0x2 -#define SWD_ACK_FAULT 0x4 - -#define DPAP_WRITE 0 -#define DPAP_READ 1 - -#define BANK_REG(bank, reg) (((bank) << 4) | (reg)) - -/* 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.DPBANKSEL - */ -#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) -#define STKCMPCLR (1UL << 1) /* SWD-only */ -#define STKERRCLR (1UL << 2) /* SWD-only */ -#define WDERRCLR (1UL << 3) /* SWD-only */ -#define ORUNERRCLR (1UL << 4) /* SWD-only */ - -/* Fields of the DP's CTRL/STAT register */ -#define CORUNDETECT (1UL << 0) -#define SSTICKYORUN (1UL << 1) -/* 3:2 - transaction mode (e.g. pushed compare) */ -#define SSTICKYCMP (1UL << 4) -#define SSTICKYERR (1UL << 5) -#define READOK (1UL << 6) /* SWD-only */ -#define WDATAERR (1UL << 7) /* SWD-only */ -/* 11:8 - mask lanes for pushed compare or verify ops */ -/* 21:12 - transaction counter */ -#define CDBGRSTREQ (1UL << 26) -#define CDBGRSTACK (1UL << 27) -#define CDBGPWRUPREQ (1UL << 28) -#define CDBGPWRUPACK (1UL << 29) -#define CSYSPWRUPREQ (1UL << 30) -#define CSYSPWRUPACK (1UL << 31) - -/* MEM-AP register addresses */ -#define MEM_AP_REG_CSW 0x00 -#define MEM_AP_REG_TAR 0x04 -#define MEM_AP_REG_TAR64 0x08 /* RW: Large Physical Address Extension */ -#define MEM_AP_REG_DRW 0x0C /* RW: Data Read/Write register */ -#define MEM_AP_REG_BD0 0x10 /* RW: Banked Data register 0-3 */ -#define MEM_AP_REG_BD1 0x14 -#define MEM_AP_REG_BD2 0x18 -#define MEM_AP_REG_BD3 0x1C -#define MEM_AP_REG_MBT 0x20 /* --: Memory Barrier Transfer register */ -#define MEM_AP_REG_BASE64 0xF0 /* RO: Debug Base Address (LA) register */ -#define MEM_AP_REG_CFG 0xF4 /* RO: Configuration register */ -#define MEM_AP_REG_BASE 0xF8 /* RO: Debug Base Address register */ -/* Generic AP register address */ -#define AP_REG_IDR 0xFC /* RO: Identification Register */ - -/* Fields of the MEM-AP's CSW register */ -#define CSW_8BIT 0 -#define CSW_16BIT 1 -#define CSW_32BIT 2 -#define CSW_ADDRINC_MASK (3UL << 4) -#define CSW_ADDRINC_OFF 0UL -#define CSW_ADDRINC_SINGLE (1UL << 4) -#define CSW_ADDRINC_PACKED (2UL << 4) -#define CSW_DEVICE_EN (1UL << 6) -#define CSW_TRIN_PROG (1UL << 7) -#define CSW_SPIDEN (1UL << 23) -/* 30:24 - implementation-defined! */ -#define CSW_HPROT (1UL << 25) /* ? */ -#define CSW_MASTER_DEBUG (1UL << 29) /* ? */ -#define CSW_SPROT (1UL << 30) -#define CSW_DBGSWENABLE (1UL << 31) - -/* Fields of the MEM-AP's IDR register */ -#define IDR_REV (0xFUL << 28) -#define IDR_JEP106 (0x7FFUL << 17) -#define IDR_CLASS (0xFUL << 13) -#define IDR_VARIANT (0xFUL << 4) -#define IDR_TYPE (0xFUL << 0) - -#define IDR_JEP106_ARM 0x04760000 - -#define DP_SELECT_APSEL 0xFF000000 -#define DP_SELECT_APBANK 0x000000F0 -#define DP_SELECT_DPBANK 0x0000000F -#define DP_SELECT_INVALID 0x00FFFF00 /* Reserved bits one */ - -/** - * This represents an ARM Debug Interface (v5) Access Port (AP). - * Most common is a MEM-AP, for memory access. - */ -struct adiv5_ap { - /** - * DAP this AP belongs to. - */ - struct adiv5_dap *dap; - - /** - * Number of this AP. - */ - uint8_t ap_num; - - /** - * Default value for (MEM-AP) AP_REG_CSW register. - */ - uint32_t csw_default; - - /** - * Cache for (MEM-AP) AP_REG_CSW register value. This is written to - * configure an access mode, such as autoincrementing AP_REG_TAR during - * word access. "-1" indicates no cached value. - */ - uint32_t csw_value; - - /** - * Cache for (MEM-AP) AP_REG_TAR register value This is written to - * configure the address being read or written - * "-1" indicates no cached value. - */ - uint32_t tar_value; - - /** - * Configures how many extra tck clocks are added after starting a - * MEM-AP access before we try to read its status (and/or result). - */ - uint32_t memaccess_tck; - - /* Size of TAR autoincrement block, ARM ADI Specification requires at least 10 bits */ - uint32_t tar_autoincr_block; - - /* true if packed transfers are supported by the MEM-AP */ - bool packed_transfers; - - /* true if unaligned memory access is not supported by the MEM-AP */ - bool unaligned_access_bad; -}; - - -/** - * This represents an ARM Debug Interface (v5) Debug Access Port (DAP). - * A DAP has two types of component: one Debug Port (DP), which is a - * transport agent; and at least one Access Port (AP), controlling - * resource access. - * - * There are two basic DP transports: JTAG, and ARM's low pin-count SWD. - * Accordingly, this interface is responsible for hiding the transport - * differences so upper layer code can largely ignore them. - * - * When the chip is implemented with JTAG-DP or SW-DP, the transport is - * fixed as JTAG or SWD, respectively. Chips incorporating SWJ-DP permit - * a choice made at board design time (by only using the SWD pins), or - * as part of setting up a debug session (if all the dual-role JTAG/SWD - * signals are available). - */ -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; - - struct adiv5_ap ap[256]; - - /* The current manually selected AP by the "dap apsel" command */ - uint32_t apsel; - - /** - * Cache for DP_SELECT register. A value of DP_SELECT_INVALID - * indicates no cached value and forces rewrite of the register. - */ - uint32_t select; - - /* information about current pending SWjDP-AHBAP transaction */ - uint8_t ack; - - /** - * Holds the pointer to the destination word for the last queued read, - * for use with posted AP read sequence optimization. - */ - uint32_t *last_read; - - /* The TI TMS470 and TMS570 series processors use a BE-32 memory ordering - * despite lack of support in the ARMv7 architecture. Memory access through - * the AHB-AP has strange byte ordering these processors, and we need to - * swizzle appropriately. */ - bool ti_be_32_quirks; - - /** - * Signals that an attempt to reestablish communication afresh - * should be performed before the next access. - */ - bool do_reconnect; -}; - -/** - * Transport-neutral representation of queued DAP transactions, supporting - * both JTAG and SWD transports. All submitted transactions are logically - * queued, until the queue is executed by run(). Some implementations might - * execute transactions as soon as they're submitted, but no status is made - * available until run(). - */ -struct dap_ops { - /** DP register read. */ - int (*queue_dp_read)(struct adiv5_dap *dap, unsigned reg, - uint32_t *data); - /** DP register write. */ - int (*queue_dp_write)(struct adiv5_dap *dap, unsigned reg, - uint32_t data); - - /** AP register read. */ - int (*queue_ap_read)(struct adiv5_ap *ap, unsigned reg, - uint32_t *data); - /** AP register write. */ - int (*queue_ap_write)(struct adiv5_ap *ap, unsigned reg, - uint32_t data); - - /** AP operation abort. */ - int (*queue_ap_abort)(struct adiv5_dap *dap, uint8_t *ack); - - /** 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); -}; - -/* - * Access Port classes - */ -enum ap_class { - AP_CLASS_NONE = 0x00000, /* No class defined */ - AP_CLASS_MEM_AP = 0x10000, /* MEM-AP */ -}; - -/* - * Access Port types - */ -enum ap_type { - AP_TYPE_JTAG_AP = 0x0, /* JTAG-AP - JTAG master for controlling other JTAG devices */ - AP_TYPE_AHB_AP = 0x1, /* AHB Memory-AP */ - AP_TYPE_APB_AP = 0x2, /* APB Memory-AP */ - AP_TYPE_AXI_AP = 0x4, /* AXI Memory-AP */ -}; - -/** - * Queue a DP register read. - * Note that not all DP registers are readable; also, that JTAG and SWD - * have slight differences in DP register support. - * - * @param dap The DAP used for reading. - * @param reg The two-bit number of the DP register being read. - * @param data Pointer saying where to store the register's value - * (in host endianness). - * - * @return ERROR_OK for success, else a fault code. - */ -static inline int dap_queue_dp_read(struct adiv5_dap *dap, - unsigned reg, uint32_t *data) -{ - assert(dap->ops != NULL); - return dap->ops->queue_dp_read(dap, reg, data); -} - -/** - * Queue a DP register write. - * Note that not all DP registers are writable; also, that JTAG and SWD - * have slight differences in DP register support. - * - * @param dap The DAP used for writing. - * @param reg The two-bit number of the DP register being written. - * @param data Value being written (host endianness) - * - * @return ERROR_OK for success, else a fault code. - */ -static inline int dap_queue_dp_write(struct adiv5_dap *dap, - unsigned reg, uint32_t data) -{ - assert(dap->ops != NULL); - return dap->ops->queue_dp_write(dap, reg, data); -} - -/** - * Queue an AP register read. - * - * @param ap The AP used for reading. - * @param reg The number of the AP register being read. - * @param data Pointer saying where to store the register's value - * (in host endianness). - * - * @return ERROR_OK for success, else a fault code. - */ -static inline int dap_queue_ap_read(struct adiv5_ap *ap, - unsigned reg, uint32_t *data) -{ - assert(ap->dap->ops != NULL); - return ap->dap->ops->queue_ap_read(ap, reg, data); -} - -/** - * Queue an AP register write. - * - * @param ap The AP used for writing. - * @param reg The number of the AP register being written. - * @param data Value being written (host endianness) - * - * @return ERROR_OK for success, else a fault code. - */ -static inline int dap_queue_ap_write(struct adiv5_ap *ap, - unsigned reg, uint32_t data) -{ - assert(ap->dap->ops != NULL); - return ap->dap->ops->queue_ap_write(ap, reg, data); -} - -/** - * Queue an AP abort operation. The current AP transaction is aborted, - * including any update of the transaction counter. The AP is left in - * an unknown state (so it must be re-initialized). For use only after - * the AP has reported WAIT status for an extended period. - * - * @param dap The DAP used for writing. - * @param ack Pointer to where transaction status will be stored. - * - * @return ERROR_OK for success, else a fault code. - */ -static inline int dap_queue_ap_abort(struct adiv5_dap *dap, uint8_t *ack) -{ - assert(dap->ops != NULL); - return dap->ops->queue_ap_abort(dap, ack); -} - -/** - * Perform all queued DAP operations, and clear any errors posted in the - * CTRL_STAT register when they are done. Note that if more than one AP - * operation will be queued, one of the first operations in the queue - * should probably enable CORUNDETECT in the CTRL/STAT register. - * - * @param dap The DAP used. - * - * @return ERROR_OK for success, else a fault code. - */ -static inline int dap_run(struct adiv5_dap *dap) -{ - assert(dap->ops != NULL); - 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) -{ - int retval; - - retval = dap_queue_dp_read(dap, reg, value); - if (retval != ERROR_OK) - return retval; - - return dap_run(dap); -} - -static inline int dap_dp_poll_register(struct adiv5_dap *dap, unsigned reg, - uint32_t mask, uint32_t value, int timeout) -{ - assert(timeout > 0); - assert((value & mask) == value); - - int ret; - uint32_t regval; - LOG_DEBUG("DAP: poll %x, mask 0x%08" PRIx32 ", value 0x%08" PRIx32, - reg, mask, value); - do { - ret = dap_dp_read_atomic(dap, reg, ®val); - if (ret != ERROR_OK) - return ret; - - if ((regval & mask) == value) - break; - - alive_sleep(10); - } while (--timeout); - - if (!timeout) { - LOG_DEBUG("DAP: poll %x timeout", reg); - return ERROR_WAIT; - } else { - return ERROR_OK; - } -} - -/* Queued MEM-AP memory mapped single word transfers. */ -int mem_ap_read_u32(struct adiv5_ap *ap, - uint32_t address, uint32_t *value); -int mem_ap_write_u32(struct adiv5_ap *ap, - uint32_t address, uint32_t value); - -/* Synchronous MEM-AP memory mapped single word transfers. */ -int mem_ap_read_atomic_u32(struct adiv5_ap *ap, - uint32_t address, uint32_t *value); -int mem_ap_write_atomic_u32(struct adiv5_ap *ap, - uint32_t address, uint32_t value); - -/* Synchronous MEM-AP memory mapped bus block transfers. */ -int mem_ap_read_buf(struct adiv5_ap *ap, - uint8_t *buffer, uint32_t size, uint32_t count, uint32_t address); -int mem_ap_write_buf(struct adiv5_ap *ap, - const uint8_t *buffer, uint32_t size, uint32_t count, uint32_t address); - -/* Synchronous, non-incrementing buffer functions for accessing fifos. */ -int mem_ap_read_buf_noincr(struct adiv5_ap *ap, - uint8_t *buffer, uint32_t size, uint32_t count, uint32_t address); -int mem_ap_write_buf_noincr(struct adiv5_ap *ap, - const uint8_t *buffer, uint32_t size, uint32_t count, uint32_t address); - -/* Create DAP struct */ -struct adiv5_dap *dap_init(void); - -/* Initialisation of the debug system, power domains and registers */ -int dap_dp_init(struct adiv5_dap *dap); -int mem_ap_init(struct adiv5_ap *ap); - -/* Probe the AP for ROM Table location */ -int dap_get_debugbase(struct adiv5_ap *ap, - uint32_t *dbgbase, uint32_t *apid); - -/* Probe Access Ports to find a particular type */ -int dap_find_ap(struct adiv5_dap *dap, - enum ap_type type_to_find, - struct adiv5_ap **ap_out); - -static inline struct adiv5_ap *dap_ap(struct adiv5_dap *dap, uint8_t ap_num) -{ - return &dap->ap[ap_num]; -} - -/* Lookup CoreSight component */ -int dap_lookup_cs_component(struct adiv5_ap *ap, - uint32_t dbgbase, uint8_t type, uint32_t *addr, int32_t *idx); - -struct target; - -/* Put debug link into SWD mode */ -int dap_to_swd(struct target *target); - -/* Put debug link into JTAG mode */ -int dap_to_jtag(struct target *target); - -extern const struct command_registration dap_command_handlers[]; - -#endif /* OPENOCD_TARGET_ARM_ADI_V5_H */ diff --git a/src/target/arm_disassembler.c b/src/target/arm_disassembler.c deleted file mode 100644 index 5277b94d8..000000000 --- a/src/target/arm_disassembler.c +++ /dev/null @@ -1,4465 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2006 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * Copyright (C) 2009 by David Brownell * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "target.h" -#include "arm_disassembler.h" -#include - -/* - * This disassembler supports two main functions for OpenOCD: - * - * - Various "disassemble" commands. OpenOCD can serve as a - * machine-language debugger, without help from GDB. - * - * - Single stepping. Not all ARM cores support hardware single - * stepping. To work without that support, the debugger must - * be able to decode instructions to find out where to put a - * "next instruction" breakpoint. - * - * In addition, interpretation of ETM trace data needs some of the - * decoding mechanisms. - * - * At this writing (September 2009) neither function is complete. - * - * - ARM decoding - * * Old-style syntax (not UAL) is generally used - * * VFP instructions are not understood (ARMv5 and later) - * except as coprocessor 10/11 operations - * * Most ARM instructions through ARMv6 are decoded, but some - * of the post-ARMv4 opcodes may not be handled yet - * CPS, SDIV, UDIV, LDREX*, STREX*, QASX, ... - * * NEON instructions are not understood (ARMv7-A) - * - * - Thumb/Thumb2 decoding - * * UAL syntax should be consistently used - * * Any Thumb2 instructions used in Cortex-M3 (ARMv7-M) should - * be handled properly. Accordingly, so should the subset - * used in Cortex-M0/M1; and "original" 16-bit Thumb from - * ARMv4T and ARMv5T. - * * Conditional effects of Thumb2 "IT" (if-then) instructions - * are not handled: the affected instructions are not shown - * with their now-conditional suffixes. - * * Some ARMv6 and ARMv7-M Thumb2 instructions may not be - * handled (minimally for coprocessor access). - * * SIMD instructions, and some other Thumb2 instructions - * from ARMv7-A, are not understood. - * - * - ThumbEE decoding - * * As a Thumb2 variant, the Thumb2 comments (above) apply. - * * Opcodes changed by ThumbEE mode are not handled; these - * instructions wrongly decode as LDM and STM. - * - * - Jazelle decoding ... no support whatsoever for Jazelle mode - * or decoding. ARM encourages use of the more generic ThumbEE - * mode, instead of Jazelle mode, in current chips. - * - * - Single-step/emulation ... spotty support, which is only weakly - * tested. Thumb2 is not supported. (Arguably a full simulator - * is not needed to support just single stepping. Recognizing - * branch vs non-branch instructions suffices, except when the - * instruction faults and triggers a synchronous exception which - * can be intercepted using other means.) - * - * ARM DDI 0406B "ARM Architecture Reference Manual, ARM v7-A and - * ARM v7-R edition" gives the most complete coverage of the various - * generations of ARM instructions. At this writing it is publicly - * accessible to anyone willing to create an account at the ARM - * web site; see http://www.arm.com/documentation/ for information. - * - * ARM DDI 0403C "ARMv7-M Architecture Reference Manual" provides - * more details relevant to the Thumb2-only processors (such as - * the Cortex-M implementations). - */ - -/* textual represenation of the condition field - * ALways (default) is ommitted (empty string) */ -static const char *arm_condition_strings[] = { - "EQ", "NE", "CS", "CC", "MI", "PL", "VS", "VC", "HI", "LS", "GE", "LT", "GT", "LE", "", "NV" -}; - -/* make up for C's missing ROR */ -static uint32_t ror(uint32_t value, int places) -{ - return (value >> places) | (value << (32 - places)); -} - -static int evaluate_unknown(uint32_t opcode, - uint32_t address, struct arm_instruction *instruction) -{ - instruction->type = ARM_UNDEFINED_INSTRUCTION; - snprintf(instruction->text, 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tUNDEFINED INSTRUCTION", address, opcode); - return ERROR_OK; -} - -static int evaluate_pld(uint32_t opcode, - uint32_t address, struct arm_instruction *instruction) -{ - /* PLD */ - if ((opcode & 0x0d70f000) == 0x0550f000) { - instruction->type = ARM_PLD; - - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tPLD ...TODO...", - address, - opcode); - - return ERROR_OK; - } - return evaluate_unknown(opcode, address, instruction); -} - -static int evaluate_srs(uint32_t opcode, - uint32_t address, struct arm_instruction *instruction) -{ - const char *wback = (opcode & (1 << 21)) ? "!" : ""; - const char *mode = ""; - - switch ((opcode >> 23) & 0x3) { - case 0: - mode = "DA"; - break; - case 1: - /* "IA" is default */ - break; - case 2: - mode = "DB"; - break; - case 3: - mode = "IB"; - break; - } - - switch (opcode & 0x0e500000) { - case 0x08400000: - snprintf(instruction->text, 128, "0x%8.8" PRIx32 - "\t0x%8.8" PRIx32 - "\tSRS%s\tSP%s, #%d", - address, opcode, - mode, wback, - (unsigned)(opcode & 0x1f)); - break; - case 0x08100000: - snprintf(instruction->text, 128, "0x%8.8" PRIx32 - "\t0x%8.8" PRIx32 - "\tRFE%s\tr%d%s", - address, opcode, - mode, - (unsigned)((opcode >> 16) & 0xf), wback); - break; - default: - return evaluate_unknown(opcode, address, instruction); - } - return ERROR_OK; -} - -static int evaluate_swi(uint32_t opcode, - uint32_t address, struct arm_instruction *instruction) -{ - instruction->type = ARM_SWI; - - snprintf(instruction->text, 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSVC %#6.6" PRIx32, - address, opcode, (opcode & 0xffffff)); - - return ERROR_OK; -} - -static int evaluate_blx_imm(uint32_t opcode, - uint32_t address, struct arm_instruction *instruction) -{ - int offset; - uint32_t immediate; - uint32_t target_address; - - instruction->type = ARM_BLX; - immediate = opcode & 0x00ffffff; - - /* sign extend 24-bit immediate */ - if (immediate & 0x00800000) - offset = 0xff000000 | immediate; - else - offset = immediate; - - /* shift two bits left */ - offset <<= 2; - - /* odd/event halfword */ - if (opcode & 0x01000000) - offset |= 0x2; - - target_address = address + 8 + offset; - - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tBLX 0x%8.8" PRIx32 "", - address, - opcode, - target_address); - - instruction->info.b_bl_bx_blx.reg_operand = -1; - instruction->info.b_bl_bx_blx.target_address = target_address; - - return ERROR_OK; -} - -static int evaluate_b_bl(uint32_t opcode, - uint32_t address, struct arm_instruction *instruction) -{ - uint8_t L; - uint32_t immediate; - int offset; - uint32_t target_address; - - immediate = opcode & 0x00ffffff; - L = (opcode & 0x01000000) >> 24; - - /* sign extend 24-bit immediate */ - if (immediate & 0x00800000) - offset = 0xff000000 | immediate; - else - offset = immediate; - - /* shift two bits left */ - offset <<= 2; - - target_address = address + 8 + offset; - - if (L) - instruction->type = ARM_BL; - else - instruction->type = ARM_B; - - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tB%s%s 0x%8.8" PRIx32, - address, - opcode, - (L) ? "L" : "", - COND(opcode), - target_address); - - instruction->info.b_bl_bx_blx.reg_operand = -1; - instruction->info.b_bl_bx_blx.target_address = target_address; - - return ERROR_OK; -} - -/* Coprocessor load/store and double register transfers - * both normal and extended instruction space (condition field b1111) */ -static int evaluate_ldc_stc_mcrr_mrrc(uint32_t opcode, - uint32_t address, struct arm_instruction *instruction) -{ - uint8_t cp_num = (opcode & 0xf00) >> 8; - - /* MCRR or MRRC */ - if (((opcode & 0x0ff00000) == 0x0c400000) || ((opcode & 0x0ff00000) == 0x0c500000)) { - uint8_t cp_opcode, Rd, Rn, CRm; - char *mnemonic; - - cp_opcode = (opcode & 0xf0) >> 4; - Rd = (opcode & 0xf000) >> 12; - Rn = (opcode & 0xf0000) >> 16; - CRm = (opcode & 0xf); - - /* MCRR */ - if ((opcode & 0x0ff00000) == 0x0c400000) { - instruction->type = ARM_MCRR; - mnemonic = "MCRR"; - } else if ((opcode & 0x0ff00000) == 0x0c500000) { - /* MRRC */ - instruction->type = ARM_MRRC; - mnemonic = "MRRC"; - } else { - LOG_ERROR("Unknown instruction"); - return ERROR_FAIL; - } - - snprintf(instruction->text, 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\t%s%s%s p%i, %x, r%i, r%i, c%i", - address, opcode, mnemonic, - ((opcode & 0xf0000000) == 0xf0000000) - ? "2" : COND(opcode), - COND(opcode), cp_num, cp_opcode, Rd, Rn, CRm); - } else {/* LDC or STC */ - uint8_t CRd, Rn, offset; - uint8_t U; - char *mnemonic; - char addressing_mode[32]; - - CRd = (opcode & 0xf000) >> 12; - Rn = (opcode & 0xf0000) >> 16; - offset = (opcode & 0xff) << 2; - - /* load/store */ - if (opcode & 0x00100000) { - instruction->type = ARM_LDC; - mnemonic = "LDC"; - } else { - instruction->type = ARM_STC; - mnemonic = "STC"; - } - - U = (opcode & 0x00800000) >> 23; - - /* addressing modes */ - if ((opcode & 0x01200000) == 0x01000000)/* offset */ - snprintf(addressing_mode, 32, "[r%i, #%s%d]", - Rn, U ? "" : "-", offset); - else if ((opcode & 0x01200000) == 0x01200000) /* pre-indexed */ - snprintf(addressing_mode, 32, "[r%i, #%s%d]!", - Rn, U ? "" : "-", offset); - else if ((opcode & 0x01200000) == 0x00200000) /* post-indexed */ - snprintf(addressing_mode, 32, "[r%i], #%s%d", - Rn, U ? "" : "-", offset); - else if ((opcode & 0x01200000) == 0x00000000) /* unindexed */ - snprintf(addressing_mode, 32, "[r%i], {%d}", - Rn, offset >> 2); - - snprintf(instruction->text, 128, "0x%8.8" PRIx32 - "\t0x%8.8" PRIx32 - "\t%s%s%s p%i, c%i, %s", - address, opcode, mnemonic, - ((opcode & 0xf0000000) == 0xf0000000) - ? "2" : COND(opcode), - (opcode & (1 << 22)) ? "L" : "", - cp_num, CRd, addressing_mode); - } - - return ERROR_OK; -} - -/* Coprocessor data processing instructions - * Coprocessor register transfer instructions - * both normal and extended instruction space (condition field b1111) */ -static int evaluate_cdp_mcr_mrc(uint32_t opcode, - uint32_t address, struct arm_instruction *instruction) -{ - const char *cond; - char *mnemonic; - uint8_t cp_num, opcode_1, CRd_Rd, CRn, CRm, opcode_2; - - cond = ((opcode & 0xf0000000) == 0xf0000000) ? "2" : COND(opcode); - cp_num = (opcode & 0xf00) >> 8; - CRd_Rd = (opcode & 0xf000) >> 12; - CRn = (opcode & 0xf0000) >> 16; - CRm = (opcode & 0xf); - opcode_2 = (opcode & 0xe0) >> 5; - - /* CDP or MRC/MCR */ - if (opcode & 0x00000010) { /* bit 4 set -> MRC/MCR */ - if (opcode & 0x00100000) { /* bit 20 set -> MRC */ - instruction->type = ARM_MRC; - mnemonic = "MRC"; - } else {/* bit 20 not set -> MCR */ - instruction->type = ARM_MCR; - mnemonic = "MCR"; - } - - opcode_1 = (opcode & 0x00e00000) >> 21; - - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s p%i, 0x%2.2x, r%i, c%i, c%i, 0x%2.2x", - address, - opcode, - mnemonic, - cond, - cp_num, - opcode_1, - CRd_Rd, - CRn, - CRm, - opcode_2); - } else {/* bit 4 not set -> CDP */ - instruction->type = ARM_CDP; - mnemonic = "CDP"; - - opcode_1 = (opcode & 0x00f00000) >> 20; - - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s p%i, 0x%2.2x, c%i, c%i, c%i, 0x%2.2x", - address, - opcode, - mnemonic, - cond, - cp_num, - opcode_1, - CRd_Rd, - CRn, - CRm, - opcode_2); - } - - return ERROR_OK; -} - -/* Load/store instructions */ -static int evaluate_load_store(uint32_t opcode, - uint32_t address, struct arm_instruction *instruction) -{ - uint8_t I, P, U, B, W, L; - uint8_t Rn, Rd; - char *operation;/* "LDR" or "STR" */ - char *suffix; /* "", "B", "T", "BT" */ - char offset[32]; - - /* examine flags */ - I = (opcode & 0x02000000) >> 25; - P = (opcode & 0x01000000) >> 24; - U = (opcode & 0x00800000) >> 23; - B = (opcode & 0x00400000) >> 22; - W = (opcode & 0x00200000) >> 21; - L = (opcode & 0x00100000) >> 20; - - /* target register */ - Rd = (opcode & 0xf000) >> 12; - - /* base register */ - Rn = (opcode & 0xf0000) >> 16; - - instruction->info.load_store.Rd = Rd; - instruction->info.load_store.Rn = Rn; - instruction->info.load_store.U = U; - - /* determine operation */ - if (L) - operation = "LDR"; - else - operation = "STR"; - - /* determine instruction type and suffix */ - if (B) { - if ((P == 0) && (W == 1)) { - if (L) - instruction->type = ARM_LDRBT; - else - instruction->type = ARM_STRBT; - suffix = "BT"; - } else { - if (L) - instruction->type = ARM_LDRB; - else - instruction->type = ARM_STRB; - suffix = "B"; - } - } else { - if ((P == 0) && (W == 1)) { - if (L) - instruction->type = ARM_LDRT; - else - instruction->type = ARM_STRT; - suffix = "T"; - } else { - if (L) - instruction->type = ARM_LDR; - else - instruction->type = ARM_STR; - suffix = ""; - } - } - - if (!I) { /* #+- */ - uint32_t offset_12 = (opcode & 0xfff); - if (offset_12) - snprintf(offset, 32, ", #%s0x%" PRIx32 "", (U) ? "" : "-", offset_12); - else - snprintf(offset, 32, "%s", ""); - - instruction->info.load_store.offset_mode = 0; - instruction->info.load_store.offset.offset = offset_12; - } else {/* either +- or +-, , # */ - uint8_t shift_imm, shift; - uint8_t Rm; - - shift_imm = (opcode & 0xf80) >> 7; - shift = (opcode & 0x60) >> 5; - Rm = (opcode & 0xf); - - /* LSR encodes a shift by 32 bit as 0x0 */ - if ((shift == 0x1) && (shift_imm == 0x0)) - shift_imm = 0x20; - - /* ASR encodes a shift by 32 bit as 0x0 */ - if ((shift == 0x2) && (shift_imm == 0x0)) - shift_imm = 0x20; - - /* ROR by 32 bit is actually a RRX */ - if ((shift == 0x3) && (shift_imm == 0x0)) - shift = 0x4; - - instruction->info.load_store.offset_mode = 1; - instruction->info.load_store.offset.reg.Rm = Rm; - instruction->info.load_store.offset.reg.shift = shift; - instruction->info.load_store.offset.reg.shift_imm = shift_imm; - - if ((shift_imm == 0x0) && (shift == 0x0)) /* +- */ - snprintf(offset, 32, ", %sr%i", (U) ? "" : "-", Rm); - else { /* +-, , # */ - switch (shift) { - case 0x0: /* LSL */ - snprintf(offset, 32, ", %sr%i, LSL #0x%x", (U) ? "" : "-", Rm, shift_imm); - break; - case 0x1: /* LSR */ - snprintf(offset, 32, ", %sr%i, LSR #0x%x", (U) ? "" : "-", Rm, shift_imm); - break; - case 0x2: /* ASR */ - snprintf(offset, 32, ", %sr%i, ASR #0x%x", (U) ? "" : "-", Rm, shift_imm); - break; - case 0x3: /* ROR */ - snprintf(offset, 32, ", %sr%i, ROR #0x%x", (U) ? "" : "-", Rm, shift_imm); - break; - case 0x4: /* RRX */ - snprintf(offset, 32, ", %sr%i, RRX", (U) ? "" : "-", Rm); - break; - } - } - } - - if (P == 1) { - if (W == 0) { /* offset */ - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i, [r%i%s]", - address, - opcode, - operation, - COND(opcode), - suffix, - Rd, - Rn, - offset); - - instruction->info.load_store.index_mode = 0; - } else {/* pre-indexed */ - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i, [r%i%s]!", - address, - opcode, - operation, - COND(opcode), - suffix, - Rd, - Rn, - offset); - - instruction->info.load_store.index_mode = 1; - } - } else {/* post-indexed */ - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i, [r%i]%s", - address, - opcode, - operation, - COND(opcode), - suffix, - Rd, - Rn, - offset); - - instruction->info.load_store.index_mode = 2; - } - - return ERROR_OK; -} - -static int evaluate_extend(uint32_t opcode, uint32_t address, char *cp) -{ - unsigned rm = (opcode >> 0) & 0xf; - unsigned rd = (opcode >> 12) & 0xf; - unsigned rn = (opcode >> 16) & 0xf; - char *type, *rot; - - switch ((opcode >> 24) & 0x3) { - case 0: - type = "B16"; - break; - case 1: - sprintf(cp, "UNDEFINED"); - return ARM_UNDEFINED_INSTRUCTION; - case 2: - type = "B"; - break; - default: - type = "H"; - break; - } - - switch ((opcode >> 10) & 0x3) { - case 0: - rot = ""; - break; - case 1: - rot = ", ROR #8"; - break; - case 2: - rot = ", ROR #16"; - break; - default: - rot = ", ROR #24"; - break; - } - - if (rn == 0xf) { - sprintf(cp, "%cXT%s%s\tr%d, r%d%s", - (opcode & (1 << 22)) ? 'U' : 'S', - type, COND(opcode), - rd, rm, rot); - return ARM_MOV; - } else { - sprintf(cp, "%cXTA%s%s\tr%d, r%d, r%d%s", - (opcode & (1 << 22)) ? 'U' : 'S', - type, COND(opcode), - rd, rn, rm, rot); - return ARM_ADD; - } -} - -static int evaluate_p_add_sub(uint32_t opcode, uint32_t address, char *cp) -{ - char *prefix; - char *op; - int type; - - switch ((opcode >> 20) & 0x7) { - case 1: - prefix = "S"; - break; - case 2: - prefix = "Q"; - break; - case 3: - prefix = "SH"; - break; - case 5: - prefix = "U"; - break; - case 6: - prefix = "UQ"; - break; - case 7: - prefix = "UH"; - break; - default: - goto undef; - } - - switch ((opcode >> 5) & 0x7) { - case 0: - op = "ADD16"; - type = ARM_ADD; - break; - case 1: - op = "ADDSUBX"; - type = ARM_ADD; - break; - case 2: - op = "SUBADDX"; - type = ARM_SUB; - break; - case 3: - op = "SUB16"; - type = ARM_SUB; - break; - case 4: - op = "ADD8"; - type = ARM_ADD; - break; - case 7: - op = "SUB8"; - type = ARM_SUB; - break; - default: - goto undef; - } - - sprintf(cp, "%s%s%s\tr%d, r%d, r%d", prefix, op, COND(opcode), - (int) (opcode >> 12) & 0xf, - (int) (opcode >> 16) & 0xf, - (int) (opcode >> 0) & 0xf); - return type; - -undef: - /* these opcodes might be used someday */ - sprintf(cp, "UNDEFINED"); - return ARM_UNDEFINED_INSTRUCTION; -} - -/* ARMv6 and later support "media" instructions (includes SIMD) */ -static int evaluate_media(uint32_t opcode, uint32_t address, - struct arm_instruction *instruction) -{ - char *cp = instruction->text; - char *mnemonic = NULL; - - sprintf(cp, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t", - address, opcode); - cp = strchr(cp, 0); - - /* parallel add/subtract */ - if ((opcode & 0x01800000) == 0x00000000) { - instruction->type = evaluate_p_add_sub(opcode, address, cp); - return ERROR_OK; - } - - /* halfword pack */ - if ((opcode & 0x01f00020) == 0x00800000) { - char *type, *shift; - unsigned imm = (unsigned) (opcode >> 7) & 0x1f; - - if (opcode & (1 << 6)) { - type = "TB"; - shift = "ASR"; - if (imm == 0) - imm = 32; - } else { - type = "BT"; - shift = "LSL"; - } - sprintf(cp, "PKH%s%s\tr%d, r%d, r%d, %s #%d", - type, COND(opcode), - (int) (opcode >> 12) & 0xf, - (int) (opcode >> 16) & 0xf, - (int) (opcode >> 0) & 0xf, - shift, imm); - return ERROR_OK; - } - - /* word saturate */ - if ((opcode & 0x01a00020) == 0x00a00000) { - char *shift; - unsigned imm = (unsigned) (opcode >> 7) & 0x1f; - - if (opcode & (1 << 6)) { - shift = "ASR"; - if (imm == 0) - imm = 32; - } else - shift = "LSL"; - - sprintf(cp, "%cSAT%s\tr%d, #%d, r%d, %s #%d", - (opcode & (1 << 22)) ? 'U' : 'S', - COND(opcode), - (int) (opcode >> 12) & 0xf, - (int) (opcode >> 16) & 0x1f, - (int) (opcode >> 0) & 0xf, - shift, imm); - return ERROR_OK; - } - - /* sign extension */ - if ((opcode & 0x018000f0) == 0x00800070) { - instruction->type = evaluate_extend(opcode, address, cp); - return ERROR_OK; - } - - /* multiplies */ - if ((opcode & 0x01f00080) == 0x01000000) { - unsigned rn = (opcode >> 12) & 0xf; - - if (rn != 0xf) - sprintf(cp, "SML%cD%s%s\tr%d, r%d, r%d, r%d", - (opcode & (1 << 6)) ? 'S' : 'A', - (opcode & (1 << 5)) ? "X" : "", - COND(opcode), - (int) (opcode >> 16) & 0xf, - (int) (opcode >> 0) & 0xf, - (int) (opcode >> 8) & 0xf, - rn); - else - sprintf(cp, "SMU%cD%s%s\tr%d, r%d, r%d", - (opcode & (1 << 6)) ? 'S' : 'A', - (opcode & (1 << 5)) ? "X" : "", - COND(opcode), - (int) (opcode >> 16) & 0xf, - (int) (opcode >> 0) & 0xf, - (int) (opcode >> 8) & 0xf); - return ERROR_OK; - } - if ((opcode & 0x01f00000) == 0x01400000) { - sprintf(cp, "SML%cLD%s%s\tr%d, r%d, r%d, r%d", - (opcode & (1 << 6)) ? 'S' : 'A', - (opcode & (1 << 5)) ? "X" : "", - COND(opcode), - (int) (opcode >> 12) & 0xf, - (int) (opcode >> 16) & 0xf, - (int) (opcode >> 0) & 0xf, - (int) (opcode >> 8) & 0xf); - return ERROR_OK; - } - if ((opcode & 0x01f00000) == 0x01500000) { - unsigned rn = (opcode >> 12) & 0xf; - - switch (opcode & 0xc0) { - case 3: - if (rn == 0xf) - goto undef; - /* FALL THROUGH */ - case 0: - break; - default: - goto undef; - } - - if (rn != 0xf) - sprintf(cp, "SMML%c%s%s\tr%d, r%d, r%d, r%d", - (opcode & (1 << 6)) ? 'S' : 'A', - (opcode & (1 << 5)) ? "R" : "", - COND(opcode), - (int) (opcode >> 16) & 0xf, - (int) (opcode >> 0) & 0xf, - (int) (opcode >> 8) & 0xf, - rn); - else - sprintf(cp, "SMMUL%s%s\tr%d, r%d, r%d", - (opcode & (1 << 5)) ? "R" : "", - COND(opcode), - (int) (opcode >> 16) & 0xf, - (int) (opcode >> 0) & 0xf, - (int) (opcode >> 8) & 0xf); - return ERROR_OK; - } - - /* simple matches against the remaining decode bits */ - switch (opcode & 0x01f000f0) { - case 0x00a00030: - case 0x00e00030: - /* parallel halfword saturate */ - sprintf(cp, "%cSAT16%s\tr%d, #%d, r%d", - (opcode & (1 << 22)) ? 'U' : 'S', - COND(opcode), - (int) (opcode >> 12) & 0xf, - (int) (opcode >> 16) & 0xf, - (int) (opcode >> 0) & 0xf); - return ERROR_OK; - case 0x00b00030: - mnemonic = "REV"; - break; - case 0x00b000b0: - mnemonic = "REV16"; - break; - case 0x00f000b0: - mnemonic = "REVSH"; - break; - case 0x008000b0: - /* select bytes */ - sprintf(cp, "SEL%s\tr%d, r%d, r%d", COND(opcode), - (int) (opcode >> 12) & 0xf, - (int) (opcode >> 16) & 0xf, - (int) (opcode >> 0) & 0xf); - return ERROR_OK; - case 0x01800010: - /* unsigned sum of absolute differences */ - if (((opcode >> 12) & 0xf) == 0xf) - sprintf(cp, "USAD8%s\tr%d, r%d, r%d", COND(opcode), - (int) (opcode >> 16) & 0xf, - (int) (opcode >> 0) & 0xf, - (int) (opcode >> 8) & 0xf); - else - sprintf(cp, "USADA8%s\tr%d, r%d, r%d, r%d", COND(opcode), - (int) (opcode >> 16) & 0xf, - (int) (opcode >> 0) & 0xf, - (int) (opcode >> 8) & 0xf, - (int) (opcode >> 12) & 0xf); - return ERROR_OK; - } - if (mnemonic) { - unsigned rm = (opcode >> 0) & 0xf; - unsigned rd = (opcode >> 12) & 0xf; - - sprintf(cp, "%s%s\tr%d, r%d", mnemonic, COND(opcode), rm, rd); - return ERROR_OK; - } - -undef: - /* these opcodes might be used someday */ - sprintf(cp, "UNDEFINED"); - return ERROR_OK; -} - -/* Miscellaneous load/store instructions */ -static int evaluate_misc_load_store(uint32_t opcode, - uint32_t address, struct arm_instruction *instruction) -{ - uint8_t P, U, I, W, L, S, H; - uint8_t Rn, Rd; - char *operation;/* "LDR" or "STR" */ - char *suffix; /* "H", "SB", "SH", "D" */ - char offset[32]; - - /* examine flags */ - P = (opcode & 0x01000000) >> 24; - U = (opcode & 0x00800000) >> 23; - I = (opcode & 0x00400000) >> 22; - W = (opcode & 0x00200000) >> 21; - L = (opcode & 0x00100000) >> 20; - S = (opcode & 0x00000040) >> 6; - H = (opcode & 0x00000020) >> 5; - - /* target register */ - Rd = (opcode & 0xf000) >> 12; - - /* base register */ - Rn = (opcode & 0xf0000) >> 16; - - instruction->info.load_store.Rd = Rd; - instruction->info.load_store.Rn = Rn; - instruction->info.load_store.U = U; - - /* determine instruction type and suffix */ - if (S) {/* signed */ - if (L) {/* load */ - if (H) { - operation = "LDR"; - instruction->type = ARM_LDRSH; - suffix = "SH"; - } else { - operation = "LDR"; - instruction->type = ARM_LDRSB; - suffix = "SB"; - } - } else {/* there are no signed stores, so this is used to encode double-register - *load/stores */ - suffix = "D"; - if (H) { - operation = "STR"; - instruction->type = ARM_STRD; - } else { - operation = "LDR"; - instruction->type = ARM_LDRD; - } - } - } else {/* unsigned */ - suffix = "H"; - if (L) {/* load */ - operation = "LDR"; - instruction->type = ARM_LDRH; - } else {/* store */ - operation = "STR"; - instruction->type = ARM_STRH; - } - } - - if (I) {/* Immediate offset/index (#+-)*/ - uint32_t offset_8 = ((opcode & 0xf00) >> 4) | (opcode & 0xf); - snprintf(offset, 32, "#%s0x%" PRIx32 "", (U) ? "" : "-", offset_8); - - instruction->info.load_store.offset_mode = 0; - instruction->info.load_store.offset.offset = offset_8; - } else {/* Register offset/index (+-) */ - uint8_t Rm; - Rm = (opcode & 0xf); - snprintf(offset, 32, "%sr%i", (U) ? "" : "-", Rm); - - instruction->info.load_store.offset_mode = 1; - instruction->info.load_store.offset.reg.Rm = Rm; - instruction->info.load_store.offset.reg.shift = 0x0; - instruction->info.load_store.offset.reg.shift_imm = 0x0; - } - - if (P == 1) { - if (W == 0) { /* offset */ - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i, [r%i, %s]", - address, - opcode, - operation, - COND(opcode), - suffix, - Rd, - Rn, - offset); - - instruction->info.load_store.index_mode = 0; - } else {/* pre-indexed */ - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i, [r%i, %s]!", - address, - opcode, - operation, - COND(opcode), - suffix, - Rd, - Rn, - offset); - - instruction->info.load_store.index_mode = 1; - } - } else {/* post-indexed */ - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i, [r%i], %s", - address, - opcode, - operation, - COND(opcode), - suffix, - Rd, - Rn, - offset); - - instruction->info.load_store.index_mode = 2; - } - - return ERROR_OK; -} - -/* Load/store multiples instructions */ -static int evaluate_ldm_stm(uint32_t opcode, - uint32_t address, struct arm_instruction *instruction) -{ - uint8_t P, U, S, W, L, Rn; - uint32_t register_list; - char *addressing_mode; - char *mnemonic; - char reg_list[69]; - char *reg_list_p; - int i; - int first_reg = 1; - - P = (opcode & 0x01000000) >> 24; - U = (opcode & 0x00800000) >> 23; - S = (opcode & 0x00400000) >> 22; - W = (opcode & 0x00200000) >> 21; - L = (opcode & 0x00100000) >> 20; - register_list = (opcode & 0xffff); - Rn = (opcode & 0xf0000) >> 16; - - instruction->info.load_store_multiple.Rn = Rn; - instruction->info.load_store_multiple.register_list = register_list; - instruction->info.load_store_multiple.S = S; - instruction->info.load_store_multiple.W = W; - - if (L) { - instruction->type = ARM_LDM; - mnemonic = "LDM"; - } else { - instruction->type = ARM_STM; - mnemonic = "STM"; - } - - if (P) { - if (U) { - instruction->info.load_store_multiple.addressing_mode = 1; - addressing_mode = "IB"; - } else { - instruction->info.load_store_multiple.addressing_mode = 3; - addressing_mode = "DB"; - } - } else { - if (U) { - instruction->info.load_store_multiple.addressing_mode = 0; - /* "IA" is the default in UAL syntax */ - addressing_mode = ""; - } else { - instruction->info.load_store_multiple.addressing_mode = 2; - addressing_mode = "DA"; - } - } - - reg_list_p = reg_list; - for (i = 0; i <= 15; i++) { - if ((register_list >> i) & 1) { - if (first_reg) { - first_reg = 0; - reg_list_p += snprintf(reg_list_p, - (reg_list + 69 - reg_list_p), - "r%i", - i); - } else - reg_list_p += snprintf(reg_list_p, - (reg_list + 69 - reg_list_p), - ", r%i", - i); - } - } - - snprintf(instruction->text, 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\t%s%s%s r%i%s, {%s}%s", - address, opcode, - mnemonic, addressing_mode, COND(opcode), - Rn, (W) ? "!" : "", reg_list, (S) ? "^" : ""); - - return ERROR_OK; -} - -/* Multiplies, extra load/stores */ -static int evaluate_mul_and_extra_ld_st(uint32_t opcode, - uint32_t address, struct arm_instruction *instruction) -{ - /* Multiply (accumulate) (long) and Swap/swap byte */ - if ((opcode & 0x000000f0) == 0x00000090) { - /* Multiply (accumulate) */ - if ((opcode & 0x0f800000) == 0x00000000) { - uint8_t Rm, Rs, Rn, Rd, S; - Rm = opcode & 0xf; - Rs = (opcode & 0xf00) >> 8; - Rn = (opcode & 0xf000) >> 12; - Rd = (opcode & 0xf0000) >> 16; - S = (opcode & 0x00100000) >> 20; - - /* examine A bit (accumulate) */ - if (opcode & 0x00200000) { - instruction->type = ARM_MLA; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tMLA%s%s r%i, r%i, r%i, r%i", - address, - opcode, - COND(opcode), - (S) ? "S" : "", - Rd, - Rm, - Rs, - Rn); - } else { - instruction->type = ARM_MUL; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tMUL%s%s r%i, r%i, r%i", - address, - opcode, - COND(opcode), - (S) ? "S" : "", - Rd, - Rm, - Rs); - } - - return ERROR_OK; - } - - /* Multiply (accumulate) long */ - if ((opcode & 0x0f800000) == 0x00800000) { - char *mnemonic = NULL; - uint8_t Rm, Rs, RdHi, RdLow, S; - Rm = opcode & 0xf; - Rs = (opcode & 0xf00) >> 8; - RdHi = (opcode & 0xf000) >> 12; - RdLow = (opcode & 0xf0000) >> 16; - S = (opcode & 0x00100000) >> 20; - - switch ((opcode & 0x00600000) >> 21) { - case 0x0: - instruction->type = ARM_UMULL; - mnemonic = "UMULL"; - break; - case 0x1: - instruction->type = ARM_UMLAL; - mnemonic = "UMLAL"; - break; - case 0x2: - instruction->type = ARM_SMULL; - mnemonic = "SMULL"; - break; - case 0x3: - instruction->type = ARM_SMLAL; - mnemonic = "SMLAL"; - break; - } - - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i, r%i, r%i, r%i", - address, - opcode, - mnemonic, - COND(opcode), - (S) ? "S" : "", - RdLow, - RdHi, - Rm, - Rs); - - return ERROR_OK; - } - - /* Swap/swap byte */ - if ((opcode & 0x0f800000) == 0x01000000) { - uint8_t Rm, Rd, Rn; - Rm = opcode & 0xf; - Rd = (opcode & 0xf000) >> 12; - Rn = (opcode & 0xf0000) >> 16; - - /* examine B flag */ - instruction->type = (opcode & 0x00400000) ? ARM_SWPB : ARM_SWP; - - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s r%i, r%i, [r%i]", - address, - opcode, - (opcode & 0x00400000) ? "SWPB" : "SWP", - COND(opcode), - Rd, - Rm, - Rn); - return ERROR_OK; - } - - } - - return evaluate_misc_load_store(opcode, address, instruction); -} - -static int evaluate_mrs_msr(uint32_t opcode, - uint32_t address, struct arm_instruction *instruction) -{ - int R = (opcode & 0x00400000) >> 22; - char *PSR = (R) ? "SPSR" : "CPSR"; - - /* Move register to status register (MSR) */ - if (opcode & 0x00200000) { - instruction->type = ARM_MSR; - - /* immediate variant */ - if (opcode & 0x02000000) { - uint8_t immediate = (opcode & 0xff); - uint8_t rotate = (opcode & 0xf00); - - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tMSR%s %s_%s%s%s%s, 0x%8.8" PRIx32, - address, - opcode, - COND(opcode), - PSR, - (opcode & 0x10000) ? "c" : "", - (opcode & 0x20000) ? "x" : "", - (opcode & 0x40000) ? "s" : "", - (opcode & 0x80000) ? "f" : "", - ror(immediate, (rotate * 2)) - ); - } else {/* register variant */ - uint8_t Rm = opcode & 0xf; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tMSR%s %s_%s%s%s%s, r%i", - address, - opcode, - COND(opcode), - PSR, - (opcode & 0x10000) ? "c" : "", - (opcode & 0x20000) ? "x" : "", - (opcode & 0x40000) ? "s" : "", - (opcode & 0x80000) ? "f" : "", - Rm - ); - } - - } else {/* Move status register to register (MRS) */ - uint8_t Rd; - - instruction->type = ARM_MRS; - Rd = (opcode & 0x0000f000) >> 12; - - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tMRS%s r%i, %s", - address, - opcode, - COND(opcode), - Rd, - PSR); - } - - return ERROR_OK; -} - -/* Miscellaneous instructions */ -static int evaluate_misc_instr(uint32_t opcode, - uint32_t address, struct arm_instruction *instruction) -{ - /* MRS/MSR */ - if ((opcode & 0x000000f0) == 0x00000000) - evaluate_mrs_msr(opcode, address, instruction); - - /* BX */ - if ((opcode & 0x006000f0) == 0x00200010) { - uint8_t Rm; - instruction->type = ARM_BX; - Rm = opcode & 0xf; - - snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tBX%s r%i", - address, opcode, COND(opcode), Rm); - - instruction->info.b_bl_bx_blx.reg_operand = Rm; - instruction->info.b_bl_bx_blx.target_address = -1; - } - - /* BXJ - "Jazelle" support (ARMv5-J) */ - if ((opcode & 0x006000f0) == 0x00200020) { - uint8_t Rm; - instruction->type = ARM_BX; - Rm = opcode & 0xf; - - snprintf(instruction->text, 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tBXJ%s r%i", - address, opcode, COND(opcode), Rm); - - instruction->info.b_bl_bx_blx.reg_operand = Rm; - instruction->info.b_bl_bx_blx.target_address = -1; - } - - /* CLZ */ - if ((opcode & 0x006000f0) == 0x00600010) { - uint8_t Rm, Rd; - instruction->type = ARM_CLZ; - Rm = opcode & 0xf; - Rd = (opcode & 0xf000) >> 12; - - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tCLZ%s r%i, r%i", - address, - opcode, - COND(opcode), - Rd, - Rm); - } - - /* BLX(2) */ - if ((opcode & 0x006000f0) == 0x00200030) { - uint8_t Rm; - instruction->type = ARM_BLX; - Rm = opcode & 0xf; - - snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tBLX%s r%i", - address, opcode, COND(opcode), Rm); - - instruction->info.b_bl_bx_blx.reg_operand = Rm; - instruction->info.b_bl_bx_blx.target_address = -1; - } - - /* Enhanced DSP add/subtracts */ - if ((opcode & 0x0000000f0) == 0x00000050) { - uint8_t Rm, Rd, Rn; - char *mnemonic = NULL; - Rm = opcode & 0xf; - Rd = (opcode & 0xf000) >> 12; - Rn = (opcode & 0xf0000) >> 16; - - switch ((opcode & 0x00600000) >> 21) { - case 0x0: - instruction->type = ARM_QADD; - mnemonic = "QADD"; - break; - case 0x1: - instruction->type = ARM_QSUB; - mnemonic = "QSUB"; - break; - case 0x2: - instruction->type = ARM_QDADD; - mnemonic = "QDADD"; - break; - case 0x3: - instruction->type = ARM_QDSUB; - mnemonic = "QDSUB"; - break; - } - - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s r%i, r%i, r%i", - address, - opcode, - mnemonic, - COND(opcode), - Rd, - Rm, - Rn); - } - - /* exception return */ - if ((opcode & 0x0000000f0) == 0x00000060) { - if (((opcode & 0x600000) >> 21) == 3) - instruction->type = ARM_ERET; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tERET", - address, - opcode); - } - - /* exception generate instructions */ - if ((opcode & 0x0000000f0) == 0x00000070) { - uint32_t immediate = 0; - char *mnemonic = NULL; - - switch ((opcode & 0x600000) >> 21) { - case 0x1: - instruction->type = ARM_BKPT; - mnemonic = "BRKT"; - immediate = ((opcode & 0x000fff00) >> 4) | (opcode & 0xf); - break; - case 0x2: - instruction->type = ARM_HVC; - mnemonic = "HVC"; - immediate = ((opcode & 0x000fff00) >> 4) | (opcode & 0xf); - break; - case 0x3: - instruction->type = ARM_SMC; - mnemonic = "SMC"; - immediate = (opcode & 0xf); - break; - } - - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s 0x%4.4" PRIx32 "", - address, - opcode, - mnemonic, - immediate); - } - - /* Enhanced DSP multiplies */ - if ((opcode & 0x000000090) == 0x00000080) { - int x = (opcode & 0x20) >> 5; - int y = (opcode & 0x40) >> 6; - - /* SMLA < x> */ - if ((opcode & 0x00600000) == 0x00000000) { - uint8_t Rd, Rm, Rs, Rn; - instruction->type = ARM_SMLAxy; - Rd = (opcode & 0xf0000) >> 16; - Rm = (opcode & 0xf); - Rs = (opcode & 0xf00) >> 8; - Rn = (opcode & 0xf000) >> 12; - - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSMLA%s%s%s r%i, r%i, r%i, r%i", - address, - opcode, - (x) ? "T" : "B", - (y) ? "T" : "B", - COND(opcode), - Rd, - Rm, - Rs, - Rn); - } - - /* SMLAL < x> */ - if ((opcode & 0x00600000) == 0x00400000) { - uint8_t RdLow, RdHi, Rm, Rs; - instruction->type = ARM_SMLAxy; - RdHi = (opcode & 0xf0000) >> 16; - RdLow = (opcode & 0xf000) >> 12; - Rm = (opcode & 0xf); - Rs = (opcode & 0xf00) >> 8; - - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSMLA%s%s%s r%i, r%i, r%i, r%i", - address, - opcode, - (x) ? "T" : "B", - (y) ? "T" : "B", - COND(opcode), - RdLow, - RdHi, - Rm, - Rs); - } - - /* SMLAW < y> */ - if (((opcode & 0x00600000) == 0x00100000) && (x == 0)) { - uint8_t Rd, Rm, Rs, Rn; - instruction->type = ARM_SMLAWy; - Rd = (opcode & 0xf0000) >> 16; - Rm = (opcode & 0xf); - Rs = (opcode & 0xf00) >> 8; - Rn = (opcode & 0xf000) >> 12; - - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSMLAW%s%s r%i, r%i, r%i, r%i", - address, - opcode, - (y) ? "T" : "B", - COND(opcode), - Rd, - Rm, - Rs, - Rn); - } - - /* SMUL < x> */ - if ((opcode & 0x00600000) == 0x00300000) { - uint8_t Rd, Rm, Rs; - instruction->type = ARM_SMULxy; - Rd = (opcode & 0xf0000) >> 16; - Rm = (opcode & 0xf); - Rs = (opcode & 0xf00) >> 8; - - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSMULW%s%s%s r%i, r%i, r%i", - address, - opcode, - (x) ? "T" : "B", - (y) ? "T" : "B", - COND(opcode), - Rd, - Rm, - Rs); - } - - /* SMULW < y> */ - if (((opcode & 0x00600000) == 0x00100000) && (x == 1)) { - uint8_t Rd, Rm, Rs; - instruction->type = ARM_SMULWy; - Rd = (opcode & 0xf0000) >> 16; - Rm = (opcode & 0xf); - Rs = (opcode & 0xf00) >> 8; - - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSMULW%s%s r%i, r%i, r%i", - address, - opcode, - (y) ? "T" : "B", - COND(opcode), - Rd, - Rm, - Rs); - } - } - - return ERROR_OK; -} - -static int evaluate_data_proc(uint32_t opcode, - uint32_t address, struct arm_instruction *instruction) -{ - uint8_t I, op, S, Rn, Rd; - char *mnemonic = NULL; - char shifter_operand[32]; - - I = (opcode & 0x02000000) >> 25; - op = (opcode & 0x01e00000) >> 21; - S = (opcode & 0x00100000) >> 20; - - Rd = (opcode & 0xf000) >> 12; - Rn = (opcode & 0xf0000) >> 16; - - instruction->info.data_proc.Rd = Rd; - instruction->info.data_proc.Rn = Rn; - instruction->info.data_proc.S = S; - - switch (op) { - case 0x0: - instruction->type = ARM_AND; - mnemonic = "AND"; - break; - case 0x1: - instruction->type = ARM_EOR; - mnemonic = "EOR"; - break; - case 0x2: - instruction->type = ARM_SUB; - mnemonic = "SUB"; - break; - case 0x3: - instruction->type = ARM_RSB; - mnemonic = "RSB"; - break; - case 0x4: - instruction->type = ARM_ADD; - mnemonic = "ADD"; - break; - case 0x5: - instruction->type = ARM_ADC; - mnemonic = "ADC"; - break; - case 0x6: - instruction->type = ARM_SBC; - mnemonic = "SBC"; - break; - case 0x7: - instruction->type = ARM_RSC; - mnemonic = "RSC"; - break; - case 0x8: - instruction->type = ARM_TST; - mnemonic = "TST"; - break; - case 0x9: - instruction->type = ARM_TEQ; - mnemonic = "TEQ"; - break; - case 0xa: - instruction->type = ARM_CMP; - mnemonic = "CMP"; - break; - case 0xb: - instruction->type = ARM_CMN; - mnemonic = "CMN"; - break; - case 0xc: - instruction->type = ARM_ORR; - mnemonic = "ORR"; - break; - case 0xd: - instruction->type = ARM_MOV; - mnemonic = "MOV"; - break; - case 0xe: - instruction->type = ARM_BIC; - mnemonic = "BIC"; - break; - case 0xf: - instruction->type = ARM_MVN; - mnemonic = "MVN"; - break; - } - - if (I) {/* immediate shifter operand (#)*/ - uint8_t immed_8 = opcode & 0xff; - uint8_t rotate_imm = (opcode & 0xf00) >> 8; - uint32_t immediate; - - immediate = ror(immed_8, rotate_imm * 2); - - snprintf(shifter_operand, 32, "#0x%" PRIx32 "", immediate); - - instruction->info.data_proc.variant = 0; - instruction->info.data_proc.shifter_operand.immediate.immediate = immediate; - } else {/* register-based shifter operand */ - uint8_t shift, Rm; - shift = (opcode & 0x60) >> 5; - Rm = (opcode & 0xf); - - if ((opcode & 0x10) != 0x10) { /* Immediate shifts ("" or ", - *#") */ - uint8_t shift_imm; - shift_imm = (opcode & 0xf80) >> 7; - - instruction->info.data_proc.variant = 1; - instruction->info.data_proc.shifter_operand.immediate_shift.Rm = Rm; - instruction->info.data_proc.shifter_operand.immediate_shift.shift_imm = - shift_imm; - instruction->info.data_proc.shifter_operand.immediate_shift.shift = shift; - - /* LSR encodes a shift by 32 bit as 0x0 */ - if ((shift == 0x1) && (shift_imm == 0x0)) - shift_imm = 0x20; - - /* ASR encodes a shift by 32 bit as 0x0 */ - if ((shift == 0x2) && (shift_imm == 0x0)) - shift_imm = 0x20; - - /* ROR by 32 bit is actually a RRX */ - if ((shift == 0x3) && (shift_imm == 0x0)) - shift = 0x4; - - if ((shift_imm == 0x0) && (shift == 0x0)) - snprintf(shifter_operand, 32, "r%i", Rm); - else { - if (shift == 0x0) /* LSL */ - snprintf(shifter_operand, - 32, - "r%i, LSL #0x%x", - Rm, - shift_imm); - else if (shift == 0x1) /* LSR */ - snprintf(shifter_operand, - 32, - "r%i, LSR #0x%x", - Rm, - shift_imm); - else if (shift == 0x2) /* ASR */ - snprintf(shifter_operand, - 32, - "r%i, ASR #0x%x", - Rm, - shift_imm); - else if (shift == 0x3) /* ROR */ - snprintf(shifter_operand, - 32, - "r%i, ROR #0x%x", - Rm, - shift_imm); - else if (shift == 0x4) /* RRX */ - snprintf(shifter_operand, 32, "r%i, RRX", Rm); - } - } else {/* Register shifts (", ") */ - uint8_t Rs = (opcode & 0xf00) >> 8; - - instruction->info.data_proc.variant = 2; - instruction->info.data_proc.shifter_operand.register_shift.Rm = Rm; - instruction->info.data_proc.shifter_operand.register_shift.Rs = Rs; - instruction->info.data_proc.shifter_operand.register_shift.shift = shift; - - if (shift == 0x0) /* LSL */ - snprintf(shifter_operand, 32, "r%i, LSL r%i", Rm, Rs); - else if (shift == 0x1) /* LSR */ - snprintf(shifter_operand, 32, "r%i, LSR r%i", Rm, Rs); - else if (shift == 0x2) /* ASR */ - snprintf(shifter_operand, 32, "r%i, ASR r%i", Rm, Rs); - else if (shift == 0x3) /* ROR */ - snprintf(shifter_operand, 32, "r%i, ROR r%i", Rm, Rs); - } - } - - if ((op < 0x8) || (op == 0xc) || (op == 0xe)) { /* {}{S} , , - * */ - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i, r%i, %s", - address, - opcode, - mnemonic, - COND(opcode), - (S) ? "S" : "", - Rd, - Rn, - shifter_operand); - } else if ((op == 0xd) || (op == 0xf)) { /* {}{S} , - * */ - if (opcode == 0xe1a00000) /* print MOV r0,r0 as NOP */ - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tNOP", - address, - opcode); - else - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i, %s", - address, - opcode, - mnemonic, - COND(opcode), - (S) ? "S" : "", - Rd, - shifter_operand); - } else {/* {} , */ - snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s r%i, %s", - address, opcode, mnemonic, COND(opcode), - Rn, shifter_operand); - } - - return ERROR_OK; -} - -int arm_evaluate_opcode(uint32_t opcode, uint32_t address, - struct arm_instruction *instruction) -{ - /* clear fields, to avoid confusion */ - memset(instruction, 0, sizeof(struct arm_instruction)); - instruction->opcode = opcode; - instruction->instruction_size = 4; - - /* catch opcodes with condition field [31:28] = b1111 */ - if ((opcode & 0xf0000000) == 0xf0000000) { - /* Undefined instruction (or ARMv5E cache preload PLD) */ - if ((opcode & 0x08000000) == 0x00000000) - return evaluate_pld(opcode, address, instruction); - - /* Undefined instruction (or ARMv6+ SRS/RFE) */ - if ((opcode & 0x0e000000) == 0x08000000) - return evaluate_srs(opcode, address, instruction); - - /* Branch and branch with link and change to Thumb */ - if ((opcode & 0x0e000000) == 0x0a000000) - return evaluate_blx_imm(opcode, address, instruction); - - /* Extended coprocessor opcode space (ARMv5 and higher) - * Coprocessor load/store and double register transfers */ - if ((opcode & 0x0e000000) == 0x0c000000) - return evaluate_ldc_stc_mcrr_mrrc(opcode, address, instruction); - - /* Coprocessor data processing */ - if ((opcode & 0x0f000100) == 0x0c000000) - return evaluate_cdp_mcr_mrc(opcode, address, instruction); - - /* Coprocessor register transfers */ - if ((opcode & 0x0f000010) == 0x0c000010) - return evaluate_cdp_mcr_mrc(opcode, address, instruction); - - /* Undefined instruction */ - if ((opcode & 0x0f000000) == 0x0f000000) { - instruction->type = ARM_UNDEFINED_INSTRUCTION; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION", - address, - opcode); - return ERROR_OK; - } - } - - /* catch opcodes with [27:25] = b000 */ - if ((opcode & 0x0e000000) == 0x00000000) { - /* Multiplies, extra load/stores */ - if ((opcode & 0x00000090) == 0x00000090) - return evaluate_mul_and_extra_ld_st(opcode, address, instruction); - - /* Miscellaneous instructions */ - if ((opcode & 0x0f900000) == 0x01000000) - return evaluate_misc_instr(opcode, address, instruction); - - return evaluate_data_proc(opcode, address, instruction); - } - - /* catch opcodes with [27:25] = b001 */ - if ((opcode & 0x0e000000) == 0x02000000) { - /* Undefined instruction */ - if ((opcode & 0x0fb00000) == 0x03000000) { - instruction->type = ARM_UNDEFINED_INSTRUCTION; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION", - address, - opcode); - return ERROR_OK; - } - - /* Move immediate to status register */ - if ((opcode & 0x0fb00000) == 0x03200000) - return evaluate_mrs_msr(opcode, address, instruction); - - return evaluate_data_proc(opcode, address, instruction); - - } - - /* catch opcodes with [27:25] = b010 */ - if ((opcode & 0x0e000000) == 0x04000000) { - /* Load/store immediate offset */ - return evaluate_load_store(opcode, address, instruction); - } - - /* catch opcodes with [27:25] = b011 */ - if ((opcode & 0x0e000000) == 0x06000000) { - /* Load/store register offset */ - if ((opcode & 0x00000010) == 0x00000000) - return evaluate_load_store(opcode, address, instruction); - - /* Architecturally Undefined instruction - * ... don't expect these to ever be used - */ - if ((opcode & 0x07f000f0) == 0x07f000f0) { - instruction->type = ARM_UNDEFINED_INSTRUCTION; - snprintf(instruction->text, 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEF", - address, opcode); - return ERROR_OK; - } - - /* "media" instructions */ - return evaluate_media(opcode, address, instruction); - } - - /* catch opcodes with [27:25] = b100 */ - if ((opcode & 0x0e000000) == 0x08000000) { - /* Load/store multiple */ - return evaluate_ldm_stm(opcode, address, instruction); - } - - /* catch opcodes with [27:25] = b101 */ - if ((opcode & 0x0e000000) == 0x0a000000) { - /* Branch and branch with link */ - return evaluate_b_bl(opcode, address, instruction); - } - - /* catch opcodes with [27:25] = b110 */ - if ((opcode & 0x0e000000) == 0x0c000000) { - /* Coprocessor load/store and double register transfers */ - return evaluate_ldc_stc_mcrr_mrrc(opcode, address, instruction); - } - - /* catch opcodes with [27:25] = b111 */ - if ((opcode & 0x0e000000) == 0x0e000000) { - /* Software interrupt */ - if ((opcode & 0x0f000000) == 0x0f000000) - return evaluate_swi(opcode, address, instruction); - - /* Coprocessor data processing */ - if ((opcode & 0x0f000010) == 0x0e000000) - return evaluate_cdp_mcr_mrc(opcode, address, instruction); - - /* Coprocessor register transfers */ - if ((opcode & 0x0f000010) == 0x0e000010) - return evaluate_cdp_mcr_mrc(opcode, address, instruction); - } - - LOG_ERROR("ARM: should never reach this point (opcode=%08x)", - (unsigned) opcode); - return -1; -} - -static int evaluate_b_bl_blx_thumb(uint16_t opcode, - uint32_t address, struct arm_instruction *instruction) -{ - uint32_t offset = opcode & 0x7ff; - uint32_t opc = (opcode >> 11) & 0x3; - uint32_t target_address; - char *mnemonic = NULL; - - /* sign extend 11-bit offset */ - if (((opc == 0) || (opc == 2)) && (offset & 0x00000400)) - offset = 0xfffff800 | offset; - - target_address = address + 4 + (offset << 1); - - switch (opc) { - /* unconditional branch */ - case 0: - instruction->type = ARM_B; - mnemonic = "B"; - break; - /* BLX suffix */ - case 1: - instruction->type = ARM_BLX; - mnemonic = "BLX"; - target_address &= 0xfffffffc; - break; - /* BL/BLX prefix */ - case 2: - instruction->type = ARM_UNKNOWN_INSTUCTION; - mnemonic = "prefix"; - target_address = offset << 12; - break; - /* BL suffix */ - case 3: - instruction->type = ARM_BL; - mnemonic = "BL"; - break; - } - - /* TODO: deal correctly with dual opcode (prefixed) BL/BLX; - * these are effectively 32-bit instructions even in Thumb1. For - * disassembly, it's simplest to always use the Thumb2 decoder. - * - * But some cores will evidently handle them as two instructions, - * where exceptions may occur between the two. The ETMv3.2+ ID - * register has a bit which exposes this behavior. - */ - - snprintf(instruction->text, 128, - "0x%8.8" PRIx32 " 0x%4.4x \t%s\t%#8.8" PRIx32, - address, opcode, mnemonic, target_address); - - instruction->info.b_bl_bx_blx.reg_operand = -1; - instruction->info.b_bl_bx_blx.target_address = target_address; - - return ERROR_OK; -} - -static int evaluate_add_sub_thumb(uint16_t opcode, - uint32_t address, struct arm_instruction *instruction) -{ - uint8_t Rd = (opcode >> 0) & 0x7; - uint8_t Rn = (opcode >> 3) & 0x7; - uint8_t Rm_imm = (opcode >> 6) & 0x7; - uint32_t opc = opcode & (1 << 9); - uint32_t reg_imm = opcode & (1 << 10); - char *mnemonic; - - if (opc) { - instruction->type = ARM_SUB; - mnemonic = "SUBS"; - } else { - /* REVISIT: if reg_imm == 0, display as "MOVS" */ - instruction->type = ARM_ADD; - mnemonic = "ADDS"; - } - - instruction->info.data_proc.Rd = Rd; - instruction->info.data_proc.Rn = Rn; - instruction->info.data_proc.S = 1; - - if (reg_imm) { - instruction->info.data_proc.variant = 0;/*immediate*/ - instruction->info.data_proc.shifter_operand.immediate.immediate = Rm_imm; - snprintf(instruction->text, 128, - "0x%8.8" PRIx32 " 0x%4.4x \t%s\tr%i, r%i, #%d", - address, opcode, mnemonic, Rd, Rn, Rm_imm); - } else { - instruction->info.data_proc.variant = 1;/*immediate shift*/ - instruction->info.data_proc.shifter_operand.immediate_shift.Rm = Rm_imm; - snprintf(instruction->text, 128, - "0x%8.8" PRIx32 " 0x%4.4x \t%s\tr%i, r%i, r%i", - address, opcode, mnemonic, Rd, Rn, Rm_imm); - } - - return ERROR_OK; -} - -static int evaluate_shift_imm_thumb(uint16_t opcode, - uint32_t address, struct arm_instruction *instruction) -{ - uint8_t Rd = (opcode >> 0) & 0x7; - uint8_t Rm = (opcode >> 3) & 0x7; - uint8_t imm = (opcode >> 6) & 0x1f; - uint8_t opc = (opcode >> 11) & 0x3; - char *mnemonic = NULL; - - switch (opc) { - case 0: - instruction->type = ARM_MOV; - mnemonic = "LSLS"; - instruction->info.data_proc.shifter_operand.immediate_shift.shift = 0; - break; - case 1: - instruction->type = ARM_MOV; - mnemonic = "LSRS"; - instruction->info.data_proc.shifter_operand.immediate_shift.shift = 1; - break; - case 2: - instruction->type = ARM_MOV; - mnemonic = "ASRS"; - instruction->info.data_proc.shifter_operand.immediate_shift.shift = 2; - break; - } - - if ((imm == 0) && (opc != 0)) - imm = 32; - - instruction->info.data_proc.Rd = Rd; - instruction->info.data_proc.Rn = -1; - instruction->info.data_proc.S = 1; - - instruction->info.data_proc.variant = 1;/*immediate_shift*/ - instruction->info.data_proc.shifter_operand.immediate_shift.Rm = Rm; - instruction->info.data_proc.shifter_operand.immediate_shift.shift_imm = imm; - - snprintf(instruction->text, 128, - "0x%8.8" PRIx32 " 0x%4.4x \t%s\tr%i, r%i, #%#2.2x", - address, opcode, mnemonic, Rd, Rm, imm); - - return ERROR_OK; -} - -static int evaluate_data_proc_imm_thumb(uint16_t opcode, - uint32_t address, struct arm_instruction *instruction) -{ - uint8_t imm = opcode & 0xff; - uint8_t Rd = (opcode >> 8) & 0x7; - uint32_t opc = (opcode >> 11) & 0x3; - char *mnemonic = NULL; - - instruction->info.data_proc.Rd = Rd; - instruction->info.data_proc.Rn = Rd; - instruction->info.data_proc.S = 1; - instruction->info.data_proc.variant = 0;/*immediate*/ - instruction->info.data_proc.shifter_operand.immediate.immediate = imm; - - switch (opc) { - case 0: - instruction->type = ARM_MOV; - mnemonic = "MOVS"; - instruction->info.data_proc.Rn = -1; - break; - case 1: - instruction->type = ARM_CMP; - mnemonic = "CMP"; - instruction->info.data_proc.Rd = -1; - break; - case 2: - instruction->type = ARM_ADD; - mnemonic = "ADDS"; - break; - case 3: - instruction->type = ARM_SUB; - mnemonic = "SUBS"; - break; - } - - snprintf(instruction->text, 128, - "0x%8.8" PRIx32 " 0x%4.4x \t%s\tr%i, #%#2.2x", - address, opcode, mnemonic, Rd, imm); - - return ERROR_OK; -} - -static int evaluate_data_proc_thumb(uint16_t opcode, - uint32_t address, struct arm_instruction *instruction) -{ - uint8_t high_reg, op, Rm, Rd, H1, H2; - char *mnemonic = NULL; - bool nop = false; - - high_reg = (opcode & 0x0400) >> 10; - op = (opcode & 0x03C0) >> 6; - - Rd = (opcode & 0x0007); - Rm = (opcode & 0x0038) >> 3; - H1 = (opcode & 0x0080) >> 7; - H2 = (opcode & 0x0040) >> 6; - - instruction->info.data_proc.Rd = Rd; - instruction->info.data_proc.Rn = Rd; - instruction->info.data_proc.S = (!high_reg || (instruction->type == ARM_CMP)); - instruction->info.data_proc.variant = 1 /*immediate shift*/; - instruction->info.data_proc.shifter_operand.immediate_shift.Rm = Rm; - - if (high_reg) { - Rd |= H1 << 3; - Rm |= H2 << 3; - op >>= 2; - - switch (op) { - case 0x0: - instruction->type = ARM_ADD; - mnemonic = "ADD"; - break; - case 0x1: - instruction->type = ARM_CMP; - mnemonic = "CMP"; - break; - case 0x2: - instruction->type = ARM_MOV; - mnemonic = "MOV"; - if (Rd == Rm) - nop = true; - break; - case 0x3: - if ((opcode & 0x7) == 0x0) { - instruction->info.b_bl_bx_blx.reg_operand = Rm; - if (H1) { - instruction->type = ARM_BLX; - snprintf(instruction->text, 128, - "0x%8.8" PRIx32 - " 0x%4.4x \tBLX\tr%i", - address, opcode, Rm); - } else { - instruction->type = ARM_BX; - snprintf(instruction->text, 128, - "0x%8.8" PRIx32 - " 0x%4.4x \tBX\tr%i", - address, opcode, Rm); - } - } else { - instruction->type = ARM_UNDEFINED_INSTRUCTION; - snprintf(instruction->text, 128, - "0x%8.8" PRIx32 - " 0x%4.4x \t" - "UNDEFINED INSTRUCTION", - address, opcode); - } - return ERROR_OK; - break; - } - } else { - switch (op) { - case 0x0: - instruction->type = ARM_AND; - mnemonic = "ANDS"; - break; - case 0x1: - instruction->type = ARM_EOR; - mnemonic = "EORS"; - break; - case 0x2: - instruction->type = ARM_MOV; - mnemonic = "LSLS"; - instruction->info.data_proc.variant = 2 /*register shift*/; - instruction->info.data_proc.shifter_operand.register_shift.shift = 0; - instruction->info.data_proc.shifter_operand.register_shift.Rm = Rd; - instruction->info.data_proc.shifter_operand.register_shift.Rs = Rm; - break; - case 0x3: - instruction->type = ARM_MOV; - mnemonic = "LSRS"; - instruction->info.data_proc.variant = 2 /*register shift*/; - instruction->info.data_proc.shifter_operand.register_shift.shift = 1; - instruction->info.data_proc.shifter_operand.register_shift.Rm = Rd; - instruction->info.data_proc.shifter_operand.register_shift.Rs = Rm; - break; - case 0x4: - instruction->type = ARM_MOV; - mnemonic = "ASRS"; - instruction->info.data_proc.variant = 2 /*register shift*/; - instruction->info.data_proc.shifter_operand.register_shift.shift = 2; - instruction->info.data_proc.shifter_operand.register_shift.Rm = Rd; - instruction->info.data_proc.shifter_operand.register_shift.Rs = Rm; - break; - case 0x5: - instruction->type = ARM_ADC; - mnemonic = "ADCS"; - break; - case 0x6: - instruction->type = ARM_SBC; - mnemonic = "SBCS"; - break; - case 0x7: - instruction->type = ARM_MOV; - mnemonic = "RORS"; - instruction->info.data_proc.variant = 2 /*register shift*/; - instruction->info.data_proc.shifter_operand.register_shift.shift = 3; - instruction->info.data_proc.shifter_operand.register_shift.Rm = Rd; - instruction->info.data_proc.shifter_operand.register_shift.Rs = Rm; - break; - case 0x8: - instruction->type = ARM_TST; - mnemonic = "TST"; - break; - case 0x9: - instruction->type = ARM_RSB; - mnemonic = "RSBS"; - instruction->info.data_proc.variant = 0 /*immediate*/; - instruction->info.data_proc.shifter_operand.immediate.immediate = 0; - instruction->info.data_proc.Rn = Rm; - break; - case 0xA: - instruction->type = ARM_CMP; - mnemonic = "CMP"; - break; - case 0xB: - instruction->type = ARM_CMN; - mnemonic = "CMN"; - break; - case 0xC: - instruction->type = ARM_ORR; - mnemonic = "ORRS"; - break; - case 0xD: - instruction->type = ARM_MUL; - mnemonic = "MULS"; - break; - case 0xE: - instruction->type = ARM_BIC; - mnemonic = "BICS"; - break; - case 0xF: - instruction->type = ARM_MVN; - mnemonic = "MVNS"; - break; - } - } - - if (nop) - snprintf(instruction->text, 128, - "0x%8.8" PRIx32 " 0x%4.4x \tNOP\t\t\t" - "; (%s r%i, r%i)", - address, opcode, mnemonic, Rd, Rm); - else - snprintf(instruction->text, 128, - "0x%8.8" PRIx32 " 0x%4.4x \t%s\tr%i, r%i", - address, opcode, mnemonic, Rd, Rm); - - return ERROR_OK; -} - -/* PC-relative data addressing is word-aligned even with Thumb */ -static inline uint32_t thumb_alignpc4(uint32_t addr) -{ - return (addr + 4) & ~3; -} - -static int evaluate_load_literal_thumb(uint16_t opcode, - uint32_t address, struct arm_instruction *instruction) -{ - uint32_t immediate; - uint8_t Rd = (opcode >> 8) & 0x7; - - instruction->type = ARM_LDR; - immediate = opcode & 0x000000ff; - immediate *= 4; - - instruction->info.load_store.Rd = Rd; - instruction->info.load_store.Rn = 15 /*PC*/; - instruction->info.load_store.index_mode = 0; /*offset*/ - instruction->info.load_store.offset_mode = 0; /*immediate*/ - instruction->info.load_store.offset.offset = immediate; - - snprintf(instruction->text, 128, - "0x%8.8" PRIx32 " 0x%4.4x \t" - "LDR\tr%i, [pc, #%#" PRIx32 "]\t; %#8.8" PRIx32, - address, opcode, Rd, immediate, - thumb_alignpc4(address) + immediate); - - return ERROR_OK; -} - -static int evaluate_load_store_reg_thumb(uint16_t opcode, - uint32_t address, struct arm_instruction *instruction) -{ - uint8_t Rd = (opcode >> 0) & 0x7; - uint8_t Rn = (opcode >> 3) & 0x7; - uint8_t Rm = (opcode >> 6) & 0x7; - uint8_t opc = (opcode >> 9) & 0x7; - char *mnemonic = NULL; - - switch (opc) { - case 0: - instruction->type = ARM_STR; - mnemonic = "STR"; - break; - case 1: - instruction->type = ARM_STRH; - mnemonic = "STRH"; - break; - case 2: - instruction->type = ARM_STRB; - mnemonic = "STRB"; - break; - case 3: - instruction->type = ARM_LDRSB; - mnemonic = "LDRSB"; - break; - case 4: - instruction->type = ARM_LDR; - mnemonic = "LDR"; - break; - case 5: - instruction->type = ARM_LDRH; - mnemonic = "LDRH"; - break; - case 6: - instruction->type = ARM_LDRB; - mnemonic = "LDRB"; - break; - case 7: - instruction->type = ARM_LDRSH; - mnemonic = "LDRSH"; - break; - } - - snprintf(instruction->text, 128, - "0x%8.8" PRIx32 " 0x%4.4x \t%s\tr%i, [r%i, r%i]", - address, opcode, mnemonic, Rd, Rn, Rm); - - instruction->info.load_store.Rd = Rd; - instruction->info.load_store.Rn = Rn; - instruction->info.load_store.index_mode = 0; /*offset*/ - instruction->info.load_store.offset_mode = 1; /*register*/ - instruction->info.load_store.offset.reg.Rm = Rm; - - return ERROR_OK; -} - -static int evaluate_load_store_imm_thumb(uint16_t opcode, - uint32_t address, struct arm_instruction *instruction) -{ - uint32_t offset = (opcode >> 6) & 0x1f; - uint8_t Rd = (opcode >> 0) & 0x7; - uint8_t Rn = (opcode >> 3) & 0x7; - uint32_t L = opcode & (1 << 11); - uint32_t B = opcode & (1 << 12); - char *mnemonic; - char suffix = ' '; - uint32_t shift = 2; - - if (L) { - instruction->type = ARM_LDR; - mnemonic = "LDR"; - } else { - instruction->type = ARM_STR; - mnemonic = "STR"; - } - - if ((opcode&0xF000) == 0x8000) { - suffix = 'H'; - shift = 1; - } else if (B) { - suffix = 'B'; - shift = 0; - } - - snprintf(instruction->text, 128, - "0x%8.8" PRIx32 " 0x%4.4x \t%s%c\tr%i, [r%i, #%#" PRIx32 "]", - address, opcode, mnemonic, suffix, Rd, Rn, offset << shift); - - instruction->info.load_store.Rd = Rd; - instruction->info.load_store.Rn = Rn; - instruction->info.load_store.index_mode = 0; /*offset*/ - instruction->info.load_store.offset_mode = 0; /*immediate*/ - instruction->info.load_store.offset.offset = offset << shift; - - return ERROR_OK; -} - -static int evaluate_load_store_stack_thumb(uint16_t opcode, - uint32_t address, struct arm_instruction *instruction) -{ - uint32_t offset = opcode & 0xff; - uint8_t Rd = (opcode >> 8) & 0x7; - uint32_t L = opcode & (1 << 11); - char *mnemonic; - - if (L) { - instruction->type = ARM_LDR; - mnemonic = "LDR"; - } else { - instruction->type = ARM_STR; - mnemonic = "STR"; - } - - snprintf(instruction->text, 128, - "0x%8.8" PRIx32 " 0x%4.4x \t%s\tr%i, [SP, #%#" PRIx32 "]", - address, opcode, mnemonic, Rd, offset*4); - - instruction->info.load_store.Rd = Rd; - instruction->info.load_store.Rn = 13 /*SP*/; - instruction->info.load_store.index_mode = 0; /*offset*/ - instruction->info.load_store.offset_mode = 0; /*immediate*/ - instruction->info.load_store.offset.offset = offset*4; - - return ERROR_OK; -} - -static int evaluate_add_sp_pc_thumb(uint16_t opcode, - uint32_t address, struct arm_instruction *instruction) -{ - uint32_t imm = opcode & 0xff; - uint8_t Rd = (opcode >> 8) & 0x7; - uint8_t Rn; - uint32_t SP = opcode & (1 << 11); - const char *reg_name; - - instruction->type = ARM_ADD; - - if (SP) { - reg_name = "SP"; - Rn = 13; - } else { - reg_name = "PC"; - Rn = 15; - } - - snprintf(instruction->text, 128, - "0x%8.8" PRIx32 " 0x%4.4x \tADD\tr%i, %s, #%#" PRIx32, - address, opcode, Rd, reg_name, imm * 4); - - instruction->info.data_proc.variant = 0 /* immediate */; - instruction->info.data_proc.Rd = Rd; - instruction->info.data_proc.Rn = Rn; - instruction->info.data_proc.shifter_operand.immediate.immediate = imm*4; - - return ERROR_OK; -} - -static int evaluate_adjust_stack_thumb(uint16_t opcode, - uint32_t address, struct arm_instruction *instruction) -{ - uint32_t imm = opcode & 0x7f; - uint8_t opc = opcode & (1 << 7); - char *mnemonic; - - - if (opc) { - instruction->type = ARM_SUB; - mnemonic = "SUB"; - } else { - instruction->type = ARM_ADD; - mnemonic = "ADD"; - } - - snprintf(instruction->text, 128, - "0x%8.8" PRIx32 " 0x%4.4x \t%s\tSP, #%#" PRIx32, - address, opcode, mnemonic, imm*4); - - instruction->info.data_proc.variant = 0 /* immediate */; - instruction->info.data_proc.Rd = 13 /*SP*/; - instruction->info.data_proc.Rn = 13 /*SP*/; - instruction->info.data_proc.shifter_operand.immediate.immediate = imm*4; - - return ERROR_OK; -} - -static int evaluate_breakpoint_thumb(uint16_t opcode, - uint32_t address, struct arm_instruction *instruction) -{ - uint32_t imm = opcode & 0xff; - - instruction->type = ARM_BKPT; - - snprintf(instruction->text, 128, - "0x%8.8" PRIx32 " 0x%4.4x \tBKPT\t%#2.2" PRIx32 "", - address, opcode, imm); - - return ERROR_OK; -} - -static int evaluate_load_store_multiple_thumb(uint16_t opcode, - uint32_t address, struct arm_instruction *instruction) -{ - uint32_t reg_list = opcode & 0xff; - uint32_t L = opcode & (1 << 11); - uint32_t R = opcode & (1 << 8); - uint8_t Rn = (opcode >> 8) & 7; - uint8_t addr_mode = 0 /* IA */; - char reg_names[40]; - char *reg_names_p; - char *mnemonic; - char ptr_name[7] = ""; - int i; - - /* REVISIT: in ThumbEE mode, there are no LDM or STM instructions. - * The STMIA and LDMIA opcodes are used for other instructions. - */ - - if ((opcode & 0xf000) == 0xc000) { /* generic load/store multiple */ - char *wback = "!"; - - if (L) { - instruction->type = ARM_LDM; - mnemonic = "LDM"; - if (opcode & (1 << Rn)) - wback = ""; - } else { - instruction->type = ARM_STM; - mnemonic = "STM"; - } - snprintf(ptr_name, sizeof ptr_name, "r%i%s, ", Rn, wback); - } else {/* push/pop */ - Rn = 13;/* SP */ - if (L) { - instruction->type = ARM_LDM; - mnemonic = "POP"; - if (R) - reg_list |= (1 << 15) /*PC*/; - } else { - instruction->type = ARM_STM; - mnemonic = "PUSH"; - addr_mode = 3; /*DB*/ - if (R) - reg_list |= (1 << 14) /*LR*/; - } - } - - reg_names_p = reg_names; - for (i = 0; i <= 15; i++) { - if (reg_list & (1 << i)) - reg_names_p += snprintf(reg_names_p, - (reg_names + 40 - reg_names_p), - "r%i, ", - i); - } - if (reg_names_p > reg_names) - reg_names_p[-2] = '\0'; - else /* invalid op : no registers */ - reg_names[0] = '\0'; - - snprintf(instruction->text, 128, - "0x%8.8" PRIx32 " 0x%4.4x \t%s\t%s{%s}", - address, opcode, mnemonic, ptr_name, reg_names); - - instruction->info.load_store_multiple.register_list = reg_list; - instruction->info.load_store_multiple.Rn = Rn; - instruction->info.load_store_multiple.addressing_mode = addr_mode; - - return ERROR_OK; -} - -static int evaluate_cond_branch_thumb(uint16_t opcode, - uint32_t address, struct arm_instruction *instruction) -{ - uint32_t offset = opcode & 0xff; - uint8_t cond = (opcode >> 8) & 0xf; - uint32_t target_address; - - if (cond == 0xf) { - instruction->type = ARM_SWI; - snprintf(instruction->text, 128, - "0x%8.8" PRIx32 " 0x%4.4x \tSVC\t%#2.2" PRIx32, - address, opcode, offset); - return ERROR_OK; - } else if (cond == 0xe) { - instruction->type = ARM_UNDEFINED_INSTRUCTION; - snprintf(instruction->text, 128, - "0x%8.8" PRIx32 " 0x%4.4x \tUNDEFINED INSTRUCTION", - address, opcode); - return ERROR_OK; - } - - /* sign extend 8-bit offset */ - if (offset & 0x00000080) - offset = 0xffffff00 | offset; - - target_address = address + 4 + (offset << 1); - - snprintf(instruction->text, 128, - "0x%8.8" PRIx32 " 0x%4.4x \tB%s\t%#8.8" PRIx32, - address, opcode, - arm_condition_strings[cond], target_address); - - instruction->type = ARM_B; - instruction->info.b_bl_bx_blx.reg_operand = -1; - instruction->info.b_bl_bx_blx.target_address = target_address; - - return ERROR_OK; -} - -static int evaluate_cb_thumb(uint16_t opcode, uint32_t address, - struct arm_instruction *instruction) -{ - unsigned offset; - - /* added in Thumb2 */ - offset = (opcode >> 3) & 0x1f; - offset |= (opcode & 0x0200) >> 4; - - snprintf(instruction->text, 128, - "0x%8.8" PRIx32 " 0x%4.4x \tCB%sZ\tr%d, %#8.8" PRIx32, - address, opcode, - (opcode & 0x0800) ? "N" : "", - opcode & 0x7, address + 4 + (offset << 1)); - - return ERROR_OK; -} - -static int evaluate_extend_thumb(uint16_t opcode, uint32_t address, - struct arm_instruction *instruction) -{ - /* added in ARMv6 */ - snprintf(instruction->text, 128, - "0x%8.8" PRIx32 " 0x%4.4x \t%cXT%c\tr%d, r%d", - address, opcode, - (opcode & 0x0080) ? 'U' : 'S', - (opcode & 0x0040) ? 'B' : 'H', - opcode & 0x7, (opcode >> 3) & 0x7); - - return ERROR_OK; -} - -static int evaluate_cps_thumb(uint16_t opcode, uint32_t address, - struct arm_instruction *instruction) -{ - /* added in ARMv6 */ - if ((opcode & 0x0ff0) == 0x0650) - snprintf(instruction->text, 128, - "0x%8.8" PRIx32 " 0x%4.4x \tSETEND %s", - address, opcode, - (opcode & 0x80) ? "BE" : "LE"); - else /* ASSUME (opcode & 0x0fe0) == 0x0660 */ - snprintf(instruction->text, 128, - "0x%8.8" PRIx32 " 0x%4.4x \tCPSI%c\t%s%s%s", - address, opcode, - (opcode & 0x0010) ? 'D' : 'E', - (opcode & 0x0004) ? "A" : "", - (opcode & 0x0002) ? "I" : "", - (opcode & 0x0001) ? "F" : ""); - - return ERROR_OK; -} - -static int evaluate_byterev_thumb(uint16_t opcode, uint32_t address, - struct arm_instruction *instruction) -{ - char *suffix; - - /* added in ARMv6 */ - switch ((opcode >> 6) & 3) { - case 0: - suffix = ""; - break; - case 1: - suffix = "16"; - break; - default: - suffix = "SH"; - break; - } - snprintf(instruction->text, 128, - "0x%8.8" PRIx32 " 0x%4.4x \tREV%s\tr%d, r%d", - address, opcode, suffix, - opcode & 0x7, (opcode >> 3) & 0x7); - - return ERROR_OK; -} - -static int evaluate_hint_thumb(uint16_t opcode, uint32_t address, - struct arm_instruction *instruction) -{ - char *hint; - - switch ((opcode >> 4) & 0x0f) { - case 0: - hint = "NOP"; - break; - case 1: - hint = "YIELD"; - break; - case 2: - hint = "WFE"; - break; - case 3: - hint = "WFI"; - break; - case 4: - hint = "SEV"; - break; - default: - hint = "HINT (UNRECOGNIZED)"; - break; - } - - snprintf(instruction->text, 128, - "0x%8.8" PRIx32 " 0x%4.4x \t%s", - address, opcode, hint); - - return ERROR_OK; -} - -static int evaluate_ifthen_thumb(uint16_t opcode, uint32_t address, - struct arm_instruction *instruction) -{ - unsigned cond = (opcode >> 4) & 0x0f; - char *x = "", *y = "", *z = ""; - - if (opcode & 0x01) - z = (opcode & 0x02) ? "T" : "E"; - if (opcode & 0x03) - y = (opcode & 0x04) ? "T" : "E"; - if (opcode & 0x07) - x = (opcode & 0x08) ? "T" : "E"; - - snprintf(instruction->text, 128, - "0x%8.8" PRIx32 " 0x%4.4x \tIT%s%s%s\t%s", - address, opcode, - x, y, z, arm_condition_strings[cond]); - - /* NOTE: strictly speaking, the next 1-4 instructions should - * now be displayed with the relevant conditional suffix... - */ - - return ERROR_OK; -} - -int thumb_evaluate_opcode(uint16_t opcode, uint32_t address, struct arm_instruction *instruction) -{ - /* clear fields, to avoid confusion */ - memset(instruction, 0, sizeof(struct arm_instruction)); - instruction->opcode = opcode; - instruction->instruction_size = 2; - - if ((opcode & 0xe000) == 0x0000) { - /* add/substract register or immediate */ - if ((opcode & 0x1800) == 0x1800) - return evaluate_add_sub_thumb(opcode, address, instruction); - /* shift by immediate */ - else - return evaluate_shift_imm_thumb(opcode, address, instruction); - } - - /* Add/substract/compare/move immediate */ - if ((opcode & 0xe000) == 0x2000) - return evaluate_data_proc_imm_thumb(opcode, address, instruction); - - /* Data processing instructions */ - if ((opcode & 0xf800) == 0x4000) - return evaluate_data_proc_thumb(opcode, address, instruction); - - /* Load from literal pool */ - if ((opcode & 0xf800) == 0x4800) - return evaluate_load_literal_thumb(opcode, address, instruction); - - /* Load/Store register offset */ - if ((opcode & 0xf000) == 0x5000) - return evaluate_load_store_reg_thumb(opcode, address, instruction); - - /* Load/Store immediate offset */ - if (((opcode & 0xe000) == 0x6000) - || ((opcode & 0xf000) == 0x8000)) - return evaluate_load_store_imm_thumb(opcode, address, instruction); - - /* Load/Store from/to stack */ - if ((opcode & 0xf000) == 0x9000) - return evaluate_load_store_stack_thumb(opcode, address, instruction); - - /* Add to SP/PC */ - if ((opcode & 0xf000) == 0xa000) - return evaluate_add_sp_pc_thumb(opcode, address, instruction); - - /* Misc */ - if ((opcode & 0xf000) == 0xb000) { - switch ((opcode >> 8) & 0x0f) { - case 0x0: - return evaluate_adjust_stack_thumb(opcode, address, instruction); - case 0x1: - case 0x3: - case 0x9: - case 0xb: - return evaluate_cb_thumb(opcode, address, instruction); - case 0x2: - return evaluate_extend_thumb(opcode, address, instruction); - case 0x4: - case 0x5: - case 0xc: - case 0xd: - return evaluate_load_store_multiple_thumb(opcode, address, - instruction); - case 0x6: - return evaluate_cps_thumb(opcode, address, instruction); - case 0xa: - if ((opcode & 0x00c0) == 0x0080) - break; - return evaluate_byterev_thumb(opcode, address, instruction); - case 0xe: - return evaluate_breakpoint_thumb(opcode, address, instruction); - case 0xf: - if (opcode & 0x000f) - return evaluate_ifthen_thumb(opcode, address, - instruction); - else - return evaluate_hint_thumb(opcode, address, - instruction); - } - - instruction->type = ARM_UNDEFINED_INSTRUCTION; - snprintf(instruction->text, 128, - "0x%8.8" PRIx32 " 0x%4.4x \tUNDEFINED INSTRUCTION", - address, opcode); - return ERROR_OK; - } - - /* Load/Store multiple */ - if ((opcode & 0xf000) == 0xc000) - return evaluate_load_store_multiple_thumb(opcode, address, instruction); - - /* Conditional branch + SWI */ - if ((opcode & 0xf000) == 0xd000) - return evaluate_cond_branch_thumb(opcode, address, instruction); - - if ((opcode & 0xe000) == 0xe000) { - /* Undefined instructions */ - if ((opcode & 0xf801) == 0xe801) { - instruction->type = ARM_UNDEFINED_INSTRUCTION; - snprintf(instruction->text, 128, - "0x%8.8" PRIx32 " 0x%8.8x\t" - "UNDEFINED INSTRUCTION", - address, opcode); - return ERROR_OK; - } else /* Branch to offset */ - return evaluate_b_bl_blx_thumb(opcode, address, instruction); - } - - LOG_ERROR("Thumb: should never reach this point (opcode=%04x)", opcode); - return -1; -} - -static int t2ev_b_bl(uint32_t opcode, uint32_t address, - struct arm_instruction *instruction, char *cp) -{ - unsigned offset; - unsigned b21 = 1 << 21; - unsigned b22 = 1 << 22; - - /* instead of combining two smaller 16-bit branch instructions, - * Thumb2 uses only one larger 32-bit instruction. - */ - offset = opcode & 0x7ff; - offset |= (opcode & 0x03ff0000) >> 5; - if (opcode & (1 << 26)) { - offset |= 0xff << 23; - if ((opcode & (1 << 11)) == 0) - b21 = 0; - if ((opcode & (1 << 13)) == 0) - b22 = 0; - } else { - if (opcode & (1 << 11)) - b21 = 0; - if (opcode & (1 << 13)) - b22 = 0; - } - offset |= b21; - offset |= b22; - - - address += 4; - address += offset << 1; - - instruction->type = (opcode & (1 << 14)) ? ARM_BL : ARM_B; - instruction->info.b_bl_bx_blx.reg_operand = -1; - instruction->info.b_bl_bx_blx.target_address = address; - sprintf(cp, "%s\t%#8.8" PRIx32, - (opcode & (1 << 14)) ? "BL" : "B.W", - address); - - return ERROR_OK; -} - -static int t2ev_cond_b(uint32_t opcode, uint32_t address, - struct arm_instruction *instruction, char *cp) -{ - unsigned offset; - unsigned b17 = 1 << 17; - unsigned b18 = 1 << 18; - unsigned cond = (opcode >> 22) & 0x0f; - - offset = opcode & 0x7ff; - offset |= (opcode & 0x003f0000) >> 5; - if (opcode & (1 << 26)) { - offset |= 0x1fff << 19; - if ((opcode & (1 << 11)) == 0) - b17 = 0; - if ((opcode & (1 << 13)) == 0) - b18 = 0; - } else { - if (opcode & (1 << 11)) - b17 = 0; - if (opcode & (1 << 13)) - b18 = 0; - } - offset |= b17; - offset |= b18; - - address += 4; - address += offset << 1; - - instruction->type = ARM_B; - instruction->info.b_bl_bx_blx.reg_operand = -1; - instruction->info.b_bl_bx_blx.target_address = address; - sprintf(cp, "B%s.W\t%#8.8" PRIx32, - arm_condition_strings[cond], - address); - - return ERROR_OK; -} - -static const char *special_name(int number) -{ - char *special = "(RESERVED)"; - - switch (number) { - case 0: - special = "apsr"; - break; - case 1: - special = "iapsr"; - break; - case 2: - special = "eapsr"; - break; - case 3: - special = "xpsr"; - break; - case 5: - special = "ipsr"; - break; - case 6: - special = "epsr"; - break; - case 7: - special = "iepsr"; - break; - case 8: - special = "msp"; - break; - case 9: - special = "psp"; - break; - case 16: - special = "primask"; - break; - case 17: - special = "basepri"; - break; - case 18: - special = "basepri_max"; - break; - case 19: - special = "faultmask"; - break; - case 20: - special = "control"; - break; - } - return special; -} - -static int t2ev_hint(uint32_t opcode, uint32_t address, - struct arm_instruction *instruction, char *cp) -{ - const char *mnemonic; - - if (opcode & 0x0700) { - instruction->type = ARM_UNDEFINED_INSTRUCTION; - strcpy(cp, "UNDEFINED"); - return ERROR_OK; - } - - if (opcode & 0x00f0) { - sprintf(cp, "DBG\t#%d", (int) opcode & 0xf); - return ERROR_OK; - } - - switch (opcode & 0x0f) { - case 0: - mnemonic = "NOP.W"; - break; - case 1: - mnemonic = "YIELD.W"; - break; - case 2: - mnemonic = "WFE.W"; - break; - case 3: - mnemonic = "WFI.W"; - break; - case 4: - mnemonic = "SEV.W"; - break; - default: - mnemonic = "HINT.W (UNRECOGNIZED)"; - break; - } - strcpy(cp, mnemonic); - return ERROR_OK; -} - -static int t2ev_misc(uint32_t opcode, uint32_t address, - struct arm_instruction *instruction, char *cp) -{ - const char *mnemonic; - - switch ((opcode >> 4) & 0x0f) { - case 0: - mnemonic = "LEAVEX"; - break; - case 1: - mnemonic = "ENTERX"; - break; - case 2: - mnemonic = "CLREX"; - break; - case 4: - mnemonic = "DSB"; - break; - case 5: - mnemonic = "DMB"; - break; - case 6: - mnemonic = "ISB"; - break; - default: - return ERROR_COMMAND_SYNTAX_ERROR; - } - strcpy(cp, mnemonic); - return ERROR_OK; -} - -static int t2ev_b_misc(uint32_t opcode, uint32_t address, - struct arm_instruction *instruction, char *cp) -{ - /* permanently undefined */ - if ((opcode & 0x07f07000) == 0x07f02000) { - instruction->type = ARM_UNDEFINED_INSTRUCTION; - strcpy(cp, "UNDEFINED"); - return ERROR_OK; - } - - switch ((opcode >> 12) & 0x5) { - case 0x1: - case 0x5: - return t2ev_b_bl(opcode, address, instruction, cp); - case 0x4: - goto undef; - case 0: - if (((opcode >> 23) & 0x07) != 0x07) - return t2ev_cond_b(opcode, address, instruction, cp); - if (opcode & (1 << 26)) - goto undef; - break; - } - - switch ((opcode >> 20) & 0x7f) { - case 0x38: - case 0x39: - sprintf(cp, "MSR\t%s, r%d", special_name(opcode & 0xff), - (int) (opcode >> 16) & 0x0f); - return ERROR_OK; - case 0x3a: - return t2ev_hint(opcode, address, instruction, cp); - case 0x3b: - return t2ev_misc(opcode, address, instruction, cp); - case 0x3c: - sprintf(cp, "BXJ\tr%d", (int) (opcode >> 16) & 0x0f); - return ERROR_OK; - case 0x3e: - case 0x3f: - sprintf(cp, "MRS\tr%d, %s", (int) (opcode >> 8) & 0x0f, - special_name(opcode & 0xff)); - return ERROR_OK; - } - -undef: - return ERROR_COMMAND_SYNTAX_ERROR; -} - -static int t2ev_data_mod_immed(uint32_t opcode, uint32_t address, - struct arm_instruction *instruction, char *cp) -{ - char *mnemonic = NULL; - int rn = (opcode >> 16) & 0xf; - int rd = (opcode >> 8) & 0xf; - unsigned immed = opcode & 0xff; - unsigned func; - bool one = false; - char *suffix = ""; - char *suffix2 = ""; - - /* ARMv7-M: A5.3.2 Modified immediate constants */ - func = (opcode >> 11) & 0x0e; - if (immed & 0x80) - func |= 1; - if (opcode & (1 << 26)) - func |= 0x10; - - /* "Modified" immediates */ - switch (func >> 1) { - case 0: - break; - case 2: - immed <<= 8; - /* FALLTHROUGH */ - case 1: - immed += immed << 16; - break; - case 3: - immed += immed << 8; - immed += immed << 16; - break; - default: - immed |= 0x80; - immed = ror(immed, func); - } - - if (opcode & (1 << 20)) - suffix = "S"; - - switch ((opcode >> 21) & 0xf) { - case 0: - if (rd == 0xf) { - instruction->type = ARM_TST; - mnemonic = "TST"; - one = true; - suffix = ""; - rd = rn; - } else { - instruction->type = ARM_AND; - mnemonic = "AND"; - } - break; - case 1: - instruction->type = ARM_BIC; - mnemonic = "BIC"; - break; - case 2: - if (rn == 0xf) { - instruction->type = ARM_MOV; - mnemonic = "MOV"; - one = true; - suffix2 = ".W"; - } else { - instruction->type = ARM_ORR; - mnemonic = "ORR"; - } - break; - case 3: - if (rn == 0xf) { - instruction->type = ARM_MVN; - mnemonic = "MVN"; - one = true; - } else { - /* instruction->type = ARM_ORN; */ - mnemonic = "ORN"; - } - break; - case 4: - if (rd == 0xf) { - instruction->type = ARM_TEQ; - mnemonic = "TEQ"; - one = true; - suffix = ""; - rd = rn; - } else { - instruction->type = ARM_EOR; - mnemonic = "EOR"; - } - break; - case 8: - if (rd == 0xf) { - instruction->type = ARM_CMN; - mnemonic = "CMN"; - one = true; - suffix = ""; - rd = rn; - } else { - instruction->type = ARM_ADD; - mnemonic = "ADD"; - suffix2 = ".W"; - } - break; - case 10: - instruction->type = ARM_ADC; - mnemonic = "ADC"; - suffix2 = ".W"; - break; - case 11: - instruction->type = ARM_SBC; - mnemonic = "SBC"; - break; - case 13: - if (rd == 0xf) { - instruction->type = ARM_CMP; - mnemonic = "CMP"; - one = true; - suffix = ""; - rd = rn; - } else { - instruction->type = ARM_SUB; - mnemonic = "SUB"; - } - suffix2 = ".W"; - break; - case 14: - instruction->type = ARM_RSB; - mnemonic = "RSB"; - suffix2 = ".W"; - break; - default: - return ERROR_COMMAND_SYNTAX_ERROR; - } - - if (one) - sprintf(cp, "%s%s\tr%d, #%d\t; %#8.8x", - mnemonic, suffix2, rd, immed, immed); - else - sprintf(cp, "%s%s%s\tr%d, r%d, #%d\t; %#8.8x", - mnemonic, suffix, suffix2, - rd, rn, immed, immed); - - return ERROR_OK; -} - -static int t2ev_data_immed(uint32_t opcode, uint32_t address, - struct arm_instruction *instruction, char *cp) -{ - char *mnemonic = NULL; - int rn = (opcode >> 16) & 0xf; - int rd = (opcode >> 8) & 0xf; - unsigned immed; - bool add = false; - bool is_signed = false; - - immed = (opcode & 0x0ff) | ((opcode & 0x7000) >> 4); - if (opcode & (1 << 26)) - immed |= (1 << 11); - - switch ((opcode >> 20) & 0x1f) { - case 0: - if (rn == 0xf) { - add = true; - goto do_adr; - } - mnemonic = "ADDW"; - break; - case 4: - immed |= (opcode >> 4) & 0xf000; - sprintf(cp, "MOVW\tr%d, #%d\t; %#3.3x", rd, immed, immed); - return ERROR_OK; - case 0x0a: - if (rn == 0xf) - goto do_adr; - mnemonic = "SUBW"; - break; - case 0x0c: - /* move constant to top 16 bits of register */ - immed |= (opcode >> 4) & 0xf000; - sprintf(cp, "MOVT\tr%d, #%d\t; %#4.4x", rd, immed, immed); - return ERROR_OK; - case 0x10: - case 0x12: - is_signed = true; - case 0x18: - case 0x1a: - /* signed/unsigned saturated add */ - immed = (opcode >> 6) & 0x03; - immed |= (opcode >> 10) & 0x1c; - sprintf(cp, "%sSAT\tr%d, #%d, r%d, %s #%d\t", - is_signed ? "S" : "U", - rd, (int) (opcode & 0x1f) + is_signed, rn, - (opcode & (1 << 21)) ? "ASR" : "LSL", - immed ? immed : 32); - return ERROR_OK; - case 0x14: - is_signed = true; - /* FALLTHROUGH */ - case 0x1c: - /* signed/unsigned bitfield extract */ - immed = (opcode >> 6) & 0x03; - immed |= (opcode >> 10) & 0x1c; - sprintf(cp, "%sBFX\tr%d, r%d, #%d, #%d\t", - is_signed ? "S" : "U", - rd, rn, immed, - (int) (opcode & 0x1f) + 1); - return ERROR_OK; - case 0x16: - immed = (opcode >> 6) & 0x03; - immed |= (opcode >> 10) & 0x1c; - if (rn == 0xf) /* bitfield clear */ - sprintf(cp, "BFC\tr%d, #%d, #%d\t", - rd, immed, - (int) (opcode & 0x1f) + 1 - immed); - else /* bitfield insert */ - sprintf(cp, "BFI\tr%d, r%d, #%d, #%d\t", - rd, rn, immed, - (int) (opcode & 0x1f) + 1 - immed); - return ERROR_OK; - default: - return ERROR_COMMAND_SYNTAX_ERROR; - } - - sprintf(cp, "%s\tr%d, r%d, #%d\t; %#3.3x", mnemonic, - rd, rn, immed, immed); - return ERROR_OK; - -do_adr: - address = thumb_alignpc4(address); - if (add) - address += immed; - else - address -= immed; - /* REVISIT "ADD/SUB Rd, PC, #const ; 0x..." might be better; - * not hiding the pc-relative stuff will sometimes be useful. - */ - sprintf(cp, "ADR.W\tr%d, %#8.8" PRIx32, rd, address); - return ERROR_OK; -} - -static int t2ev_store_single(uint32_t opcode, uint32_t address, - struct arm_instruction *instruction, char *cp) -{ - unsigned op = (opcode >> 20) & 0xf; - char *size = ""; - char *suffix = ""; - char *p1 = ""; - char *p2 = "]"; - unsigned immed; - unsigned rn = (opcode >> 16) & 0x0f; - unsigned rt = (opcode >> 12) & 0x0f; - - if (rn == 0xf) - return ERROR_COMMAND_SYNTAX_ERROR; - - if (opcode & 0x0800) - op |= 1; - switch (op) { - /* byte */ - case 0x8: - case 0x9: - size = "B"; - goto imm12; - case 0x1: - size = "B"; - goto imm8; - case 0x0: - size = "B"; - break; - /* halfword */ - case 0xa: - case 0xb: - size = "H"; - goto imm12; - case 0x3: - size = "H"; - goto imm8; - case 0x2: - size = "H"; - break; - /* word */ - case 0xc: - case 0xd: - goto imm12; - case 0x5: - goto imm8; - case 0x4: - break; - /* error */ - default: - return ERROR_COMMAND_SYNTAX_ERROR; - } - - sprintf(cp, "STR%s.W\tr%d, [r%d, r%d, LSL #%d]", - size, rt, rn, (int) opcode & 0x0f, - (int) (opcode >> 4) & 0x03); - return ERROR_OK; - -imm12: - immed = opcode & 0x0fff; - sprintf(cp, "STR%s.W\tr%d, [r%d, #%u]\t; %#3.3x", - size, rt, rn, immed, immed); - return ERROR_OK; - -imm8: - immed = opcode & 0x00ff; - - switch (opcode & 0x700) { - case 0x600: - suffix = "T"; - break; - case 0x000: - case 0x200: - return ERROR_COMMAND_SYNTAX_ERROR; - } - - /* two indexed modes will write back rn */ - if (opcode & 0x100) { - if (opcode & 0x400) /* pre-indexed */ - p2 = "]!"; - else { /* post-indexed */ - p1 = "]"; - p2 = ""; - } - } - - sprintf(cp, "STR%s%s\tr%d, [r%d%s, #%s%u%s\t; %#2.2x", - size, suffix, rt, rn, p1, - (opcode & 0x200) ? "" : "-", - immed, p2, immed); - return ERROR_OK; -} - -static int t2ev_mul32(uint32_t opcode, uint32_t address, - struct arm_instruction *instruction, char *cp) -{ - int ra = (opcode >> 12) & 0xf; - - switch (opcode & 0x007000f0) { - case 0: - if (ra == 0xf) - sprintf(cp, "MUL\tr%d, r%d, r%d", - (int) (opcode >> 8) & 0xf, - (int) (opcode >> 16) & 0xf, - (int) (opcode >> 0) & 0xf); - else - sprintf(cp, "MLA\tr%d, r%d, r%d, r%d", - (int) (opcode >> 8) & 0xf, - (int) (opcode >> 16) & 0xf, - (int) (opcode >> 0) & 0xf, ra); - break; - case 0x10: - sprintf(cp, "MLS\tr%d, r%d, r%d, r%d", - (int) (opcode >> 8) & 0xf, - (int) (opcode >> 16) & 0xf, - (int) (opcode >> 0) & 0xf, ra); - break; - default: - return ERROR_COMMAND_SYNTAX_ERROR; - } - return ERROR_OK; -} - -static int t2ev_mul64_div(uint32_t opcode, uint32_t address, - struct arm_instruction *instruction, char *cp) -{ - int op = (opcode >> 4) & 0xf; - char *infix = "MUL"; - - op += (opcode >> 16) & 0x70; - switch (op) { - case 0x40: - case 0x60: - infix = "MLA"; - /* FALLTHROUGH */ - case 0: - case 0x20: - sprintf(cp, "%c%sL\tr%d, r%d, r%d, r%d", - (op & 0x20) ? 'U' : 'S', - infix, - (int) (opcode >> 12) & 0xf, - (int) (opcode >> 8) & 0xf, - (int) (opcode >> 16) & 0xf, - (int) (opcode >> 0) & 0xf); - break; - case 0x1f: - case 0x3f: - sprintf(cp, "%cDIV\tr%d, r%d, r%d", - (op & 0x20) ? 'U' : 'S', - (int) (opcode >> 8) & 0xf, - (int) (opcode >> 16) & 0xf, - (int) (opcode >> 0) & 0xf); - break; - default: - return ERROR_COMMAND_SYNTAX_ERROR; - } - - return ERROR_OK; -} - -static int t2ev_ldm_stm(uint32_t opcode, uint32_t address, - struct arm_instruction *instruction, char *cp) -{ - int rn = (opcode >> 16) & 0xf; - int op = (opcode >> 22) & 0x6; - int t = (opcode >> 21) & 1; - unsigned registers = opcode & 0xffff; - char *mode = ""; - - if (opcode & (1 << 20)) - op |= 1; - - switch (op) { - case 0: - mode = "DB"; - /* FALL THROUGH */ - case 6: - sprintf(cp, "SRS%s\tsp%s, #%d", mode, - t ? "!" : "", - (unsigned) (opcode & 0x1f)); - return ERROR_OK; - case 1: - mode = "DB"; - /* FALL THROUGH */ - case 7: - sprintf(cp, "RFE%s\tr%d%s", mode, - (unsigned) ((opcode >> 16) & 0xf), - t ? "!" : ""); - return ERROR_OK; - case 2: - sprintf(cp, "STM.W\tr%d%s, ", rn, t ? "!" : ""); - break; - case 3: - if (rn == 13 && t) - sprintf(cp, "POP.W\t"); - else - sprintf(cp, "LDM.W\tr%d%s, ", rn, t ? "!" : ""); - break; - case 4: - if (rn == 13 && t) - sprintf(cp, "PUSH.W\t"); - else - sprintf(cp, "STMDB\tr%d%s, ", rn, t ? "!" : ""); - break; - case 5: - sprintf(cp, "LDMDB.W\tr%d%s, ", rn, t ? "!" : ""); - break; - default: - return ERROR_COMMAND_SYNTAX_ERROR; - } - - cp = strchr(cp, 0); - *cp++ = '{'; - for (t = 0; registers; t++, registers >>= 1) { - if ((registers & 1) == 0) - continue; - registers &= ~1; - sprintf(cp, "r%d%s", t, registers ? ", " : ""); - cp = strchr(cp, 0); - } - *cp++ = '}'; - *cp++ = 0; - - return ERROR_OK; -} - -/* load/store dual or exclusive, table branch */ -static int t2ev_ldrex_strex(uint32_t opcode, uint32_t address, - struct arm_instruction *instruction, char *cp) -{ - unsigned op1op2 = (opcode >> 20) & 0x3; - unsigned op3 = (opcode >> 4) & 0xf; - char *mnemonic; - unsigned rn = (opcode >> 16) & 0xf; - unsigned rt = (opcode >> 12) & 0xf; - unsigned rd = (opcode >> 8) & 0xf; - unsigned imm = opcode & 0xff; - char *p1 = ""; - char *p2 = "]"; - - op1op2 |= (opcode >> 21) & 0xc; - switch (op1op2) { - case 0: - mnemonic = "STREX"; - goto strex; - case 1: - mnemonic = "LDREX"; - goto ldrex; - case 2: - case 6: - case 8: - case 10: - case 12: - case 14: - mnemonic = "STRD"; - goto immediate; - case 3: - case 7: - case 9: - case 11: - case 13: - case 15: - mnemonic = "LDRD"; - if (rn == 15) - goto literal; - else - goto immediate; - case 4: - switch (op3) { - case 4: - mnemonic = "STREXB"; - break; - case 5: - mnemonic = "STREXH"; - break; - default: - return ERROR_COMMAND_SYNTAX_ERROR; - } - rd = opcode & 0xf; - imm = 0; - goto strex; - case 5: - switch (op3) { - case 0: - sprintf(cp, "TBB\t[r%u, r%u]", rn, imm & 0xf); - return ERROR_OK; - case 1: - sprintf(cp, "TBH\t[r%u, r%u, LSL #1]", rn, imm & 0xf); - return ERROR_OK; - case 4: - mnemonic = "LDREXB"; - break; - case 5: - mnemonic = "LDREXH"; - break; - default: - return ERROR_COMMAND_SYNTAX_ERROR; - } - imm = 0; - goto ldrex; - } - return ERROR_COMMAND_SYNTAX_ERROR; - -strex: - imm <<= 2; - if (imm) - sprintf(cp, "%s\tr%u, r%u, [r%u, #%u]\t; %#2.2x", - mnemonic, rd, rt, rn, imm, imm); - else - sprintf(cp, "%s\tr%u, r%u, [r%u]", - mnemonic, rd, rt, rn); - return ERROR_OK; - -ldrex: - imm <<= 2; - if (imm) - sprintf(cp, "%s\tr%u, [r%u, #%u]\t; %#2.2x", - mnemonic, rt, rn, imm, imm); - else - sprintf(cp, "%s\tr%u, [r%u]", - mnemonic, rt, rn); - return ERROR_OK; - -immediate: - /* two indexed modes will write back rn */ - if (opcode & (1 << 21)) { - if (opcode & (1 << 24)) /* pre-indexed */ - p2 = "]!"; - else { /* post-indexed */ - p1 = "]"; - p2 = ""; - } - } - - imm <<= 2; - sprintf(cp, "%s\tr%u, r%u, [r%u%s, #%s%u%s\t; %#2.2x", - mnemonic, rt, rd, rn, p1, - (opcode & (1 << 23)) ? "" : "-", - imm, p2, imm); - return ERROR_OK; - -literal: - address = thumb_alignpc4(address); - imm <<= 2; - if (opcode & (1 << 23)) - address += imm; - else - address -= imm; - sprintf(cp, "%s\tr%u, r%u, %#8.8" PRIx32, - mnemonic, rt, rd, address); - return ERROR_OK; -} - -static int t2ev_data_shift(uint32_t opcode, uint32_t address, - struct arm_instruction *instruction, char *cp) -{ - int op = (opcode >> 21) & 0xf; - int rd = (opcode >> 8) & 0xf; - int rn = (opcode >> 16) & 0xf; - int type = (opcode >> 4) & 0x3; - int immed = (opcode >> 6) & 0x3; - char *mnemonic; - char *suffix = ""; - - immed |= (opcode >> 10) & 0x1c; - if (opcode & (1 << 20)) - suffix = "S"; - - switch (op) { - case 0: - if (rd == 0xf) { - if (!(opcode & (1 << 20))) - return ERROR_COMMAND_SYNTAX_ERROR; - instruction->type = ARM_TST; - mnemonic = "TST"; - suffix = ""; - goto two; - } - instruction->type = ARM_AND; - mnemonic = "AND"; - break; - case 1: - instruction->type = ARM_BIC; - mnemonic = "BIC"; - break; - case 2: - if (rn == 0xf) { - instruction->type = ARM_MOV; - switch (type) { - case 0: - if (immed == 0) { - sprintf(cp, "MOV%s.W\tr%d, r%d", - suffix, rd, - (int) (opcode & 0xf)); - return ERROR_OK; - } - mnemonic = "LSL"; - break; - case 1: - mnemonic = "LSR"; - break; - case 2: - mnemonic = "ASR"; - break; - default: - if (immed == 0) { - sprintf(cp, "RRX%s\tr%d, r%d", - suffix, rd, - (int) (opcode & 0xf)); - return ERROR_OK; - } - mnemonic = "ROR"; - break; - } - goto immediate; - } else { - instruction->type = ARM_ORR; - mnemonic = "ORR"; - } - break; - case 3: - if (rn == 0xf) { - instruction->type = ARM_MVN; - mnemonic = "MVN"; - rn = rd; - goto two; - } else { - /* instruction->type = ARM_ORN; */ - mnemonic = "ORN"; - } - break; - case 4: - if (rd == 0xf) { - if (!(opcode & (1 << 20))) - return ERROR_COMMAND_SYNTAX_ERROR; - instruction->type = ARM_TEQ; - mnemonic = "TEQ"; - suffix = ""; - goto two; - } - instruction->type = ARM_EOR; - mnemonic = "EOR"; - break; - case 8: - if (rd == 0xf) { - if (!(opcode & (1 << 20))) - return ERROR_COMMAND_SYNTAX_ERROR; - instruction->type = ARM_CMN; - mnemonic = "CMN"; - suffix = ""; - goto two; - } - instruction->type = ARM_ADD; - mnemonic = "ADD"; - break; - case 0xa: - instruction->type = ARM_ADC; - mnemonic = "ADC"; - break; - case 0xb: - instruction->type = ARM_SBC; - mnemonic = "SBC"; - break; - case 0xd: - if (rd == 0xf) { - if (!(opcode & (1 << 21))) - return ERROR_COMMAND_SYNTAX_ERROR; - instruction->type = ARM_CMP; - mnemonic = "CMP"; - suffix = ""; - goto two; - } - instruction->type = ARM_SUB; - mnemonic = "SUB"; - break; - case 0xe: - instruction->type = ARM_RSB; - mnemonic = "RSB"; - break; - default: - return ERROR_COMMAND_SYNTAX_ERROR; - } - - sprintf(cp, "%s%s.W\tr%d, r%d, r%d", - mnemonic, suffix, rd, rn, (int) (opcode & 0xf)); - -shift: - cp = strchr(cp, 0); - - switch (type) { - case 0: - if (immed == 0) - return ERROR_OK; - suffix = "LSL"; - break; - case 1: - suffix = "LSR"; - if (immed == 32) - immed = 0; - break; - case 2: - suffix = "ASR"; - if (immed == 32) - immed = 0; - break; - case 3: - if (immed == 0) { - strcpy(cp, ", RRX"); - return ERROR_OK; - } - suffix = "ROR"; - break; - } - sprintf(cp, ", %s #%d", suffix, immed ? immed : 32); - return ERROR_OK; - -two: - sprintf(cp, "%s%s.W\tr%d, r%d", - mnemonic, suffix, rn, (int) (opcode & 0xf)); - goto shift; - -immediate: - sprintf(cp, "%s%s.W\tr%d, r%d, #%d", - mnemonic, suffix, rd, - (int) (opcode & 0xf), immed ? immed : 32); - return ERROR_OK; -} - -static int t2ev_data_reg(uint32_t opcode, uint32_t address, - struct arm_instruction *instruction, char *cp) -{ - char *mnemonic; - char *suffix = ""; - - if (((opcode >> 4) & 0xf) == 0) { - switch ((opcode >> 21) & 0x7) { - case 0: - mnemonic = "LSL"; - break; - case 1: - mnemonic = "LSR"; - break; - case 2: - mnemonic = "ASR"; - break; - case 3: - mnemonic = "ROR"; - break; - default: - return ERROR_COMMAND_SYNTAX_ERROR; - } - - instruction->type = ARM_MOV; - if (opcode & (1 << 20)) - suffix = "S"; - sprintf(cp, "%s%s.W\tr%d, r%d, r%d", - mnemonic, suffix, - (int) (opcode >> 8) & 0xf, - (int) (opcode >> 16) & 0xf, - (int) (opcode >> 0) & 0xf); - - } else if (opcode & (1 << 7)) { - switch ((opcode >> 20) & 0xf) { - case 0: - case 1: - case 4: - case 5: - switch ((opcode >> 4) & 0x3) { - case 1: - suffix = ", ROR #8"; - break; - case 2: - suffix = ", ROR #16"; - break; - case 3: - suffix = ", ROR #24"; - break; - } - sprintf(cp, "%cXT%c.W\tr%d, r%d%s", - (opcode & (1 << 24)) ? 'U' : 'S', - (opcode & (1 << 26)) ? 'B' : 'H', - (int) (opcode >> 8) & 0xf, - (int) (opcode >> 0) & 0xf, - suffix); - break; - case 8: - case 9: - case 0xa: - case 0xb: - if (opcode & (1 << 6)) - return ERROR_COMMAND_SYNTAX_ERROR; - if (((opcode >> 12) & 0xf) != 0xf) - return ERROR_COMMAND_SYNTAX_ERROR; - if (!(opcode & (1 << 20))) - return ERROR_COMMAND_SYNTAX_ERROR; - - switch (((opcode >> 19) & 0x04) - | ((opcode >> 4) & 0x3)) { - case 0: - mnemonic = "REV.W"; - break; - case 1: - mnemonic = "REV16.W"; - break; - case 2: - mnemonic = "RBIT"; - break; - case 3: - mnemonic = "REVSH.W"; - break; - case 4: - mnemonic = "CLZ"; - break; - default: - return ERROR_COMMAND_SYNTAX_ERROR; - } - sprintf(cp, "%s\tr%d, r%d", - mnemonic, - (int) (opcode >> 8) & 0xf, - (int) (opcode >> 0) & 0xf); - break; - default: - return ERROR_COMMAND_SYNTAX_ERROR; - } - } - - return ERROR_OK; -} - -static int t2ev_load_word(uint32_t opcode, uint32_t address, - struct arm_instruction *instruction, char *cp) -{ - int rn = (opcode >> 16) & 0xf; - int immed; - - instruction->type = ARM_LDR; - - if (rn == 0xf) { - immed = opcode & 0x0fff; - if ((opcode & (1 << 23)) == 0) - immed = -immed; - sprintf(cp, "LDR\tr%d, %#8.8" PRIx32, - (int) (opcode >> 12) & 0xf, - thumb_alignpc4(address) + immed); - return ERROR_OK; - } - - if (opcode & (1 << 23)) { - immed = opcode & 0x0fff; - sprintf(cp, "LDR.W\tr%d, [r%d, #%d]\t; %#3.3x", - (int) (opcode >> 12) & 0xf, - rn, immed, immed); - return ERROR_OK; - } - - if (!(opcode & (0x3f << 6))) { - sprintf(cp, "LDR.W\tr%d, [r%d, r%d, LSL #%d]", - (int) (opcode >> 12) & 0xf, - rn, - (int) (opcode >> 0) & 0xf, - (int) (opcode >> 4) & 0x3); - return ERROR_OK; - } - - - if (((opcode >> 8) & 0xf) == 0xe) { - immed = opcode & 0x00ff; - - sprintf(cp, "LDRT\tr%d, [r%d, #%d]\t; %#2.2x", - (int) (opcode >> 12) & 0xf, - rn, immed, immed); - return ERROR_OK; - } - - if (((opcode >> 8) & 0xf) == 0xc || (opcode & 0x0900) == 0x0900) { - char *p1 = "]", *p2 = ""; - - if (!(opcode & 0x0500)) - return ERROR_COMMAND_SYNTAX_ERROR; - - immed = opcode & 0x00ff; - - /* two indexed modes will write back rn */ - if (opcode & 0x100) { - if (opcode & 0x400) /* pre-indexed */ - p2 = "]!"; - else { /* post-indexed */ - p1 = "]"; - p2 = ""; - } - } - - sprintf(cp, "LDR\tr%d, [r%d%s, #%s%u%s\t; %#2.2x", - (int) (opcode >> 12) & 0xf, - rn, p1, - (opcode & 0x200) ? "" : "-", - immed, p2, immed); - return ERROR_OK; - } - - return ERROR_COMMAND_SYNTAX_ERROR; -} - -static int t2ev_load_byte_hints(uint32_t opcode, uint32_t address, - struct arm_instruction *instruction, char *cp) -{ - int rn = (opcode >> 16) & 0xf; - int rt = (opcode >> 12) & 0xf; - int op2 = (opcode >> 6) & 0x3f; - unsigned immed; - char *p1 = "", *p2 = "]"; - char *mnemonic; - - switch ((opcode >> 23) & 0x3) { - case 0: - if ((rn & rt) == 0xf) { -pld_literal: - immed = opcode & 0xfff; - address = thumb_alignpc4(address); - if (opcode & (1 << 23)) - address += immed; - else - address -= immed; - sprintf(cp, "PLD\tr%d, %#8.8" PRIx32, - rt, address); - return ERROR_OK; - } - if (rn == 0x0f && rt != 0x0f) { -ldrb_literal: - immed = opcode & 0xfff; - address = thumb_alignpc4(address); - if (opcode & (1 << 23)) - address += immed; - else - address -= immed; - sprintf(cp, "LDRB\tr%d, %#8.8" PRIx32, - rt, address); - return ERROR_OK; - } - if (rn == 0x0f) - break; - if ((op2 & 0x3c) == 0x38) { - immed = opcode & 0xff; - sprintf(cp, "LDRBT\tr%d, [r%d, #%d]\t; %#2.2x", - rt, rn, immed, immed); - return ERROR_OK; - } - if ((op2 & 0x3c) == 0x30) { - if (rt == 0x0f) { - immed = opcode & 0xff; - immed = -immed; -preload_immediate: - p1 = (opcode & (1 << 21)) ? "W" : ""; - sprintf(cp, "PLD%s\t[r%d, #%d]\t; %#6.6x", - p1, rn, immed, immed); - return ERROR_OK; - } - mnemonic = "LDRB"; -ldrxb_immediate_t3: - immed = opcode & 0xff; - if (!(opcode & 0x200)) - immed = -immed; - - /* two indexed modes will write back rn */ - if (opcode & 0x100) { - if (opcode & 0x400) /* pre-indexed */ - p2 = "]!"; - else { /* post-indexed */ - p1 = "]"; - p2 = ""; - } - } -ldrxb_immediate_t2: - sprintf(cp, "%s\tr%d, [r%d%s, #%d%s\t; %#8.8x", - mnemonic, rt, rn, p1, - immed, p2, immed); - return ERROR_OK; - } - if ((op2 & 0x24) == 0x24) { - mnemonic = "LDRB"; - goto ldrxb_immediate_t3; - } - if (op2 == 0) { - int rm = opcode & 0xf; - - if (rt == 0x0f) - sprintf(cp, "PLD\t"); - else - sprintf(cp, "LDRB.W\tr%d, ", rt); - immed = (opcode >> 4) & 0x3; - cp = strchr(cp, 0); - sprintf(cp, "[r%d, r%d, LSL #%d]", rn, rm, immed); - return ERROR_OK; - } - break; - case 1: - if ((rn & rt) == 0xf) - goto pld_literal; - if (rt == 0xf) { - immed = opcode & 0xfff; - goto preload_immediate; - } - if (rn == 0x0f) - goto ldrb_literal; - mnemonic = "LDRB.W"; - immed = opcode & 0xfff; - goto ldrxb_immediate_t2; - case 2: - if ((rn & rt) == 0xf) { - immed = opcode & 0xfff; - address = thumb_alignpc4(address); - if (opcode & (1 << 23)) - address += immed; - else - address -= immed; - sprintf(cp, "PLI\t%#8.8" PRIx32, address); - return ERROR_OK; - } - if (rn == 0xf && rt != 0xf) { -ldrsb_literal: - immed = opcode & 0xfff; - address = thumb_alignpc4(address); - if (opcode & (1 << 23)) - address += immed; - else - address -= immed; - sprintf(cp, "LDRSB\t%#8.8" PRIx32, address); - return ERROR_OK; - } - if (rn == 0xf) - break; - if ((op2 & 0x3c) == 0x38) { - immed = opcode & 0xff; - sprintf(cp, "LDRSBT\tr%d, [r%d, #%d]\t; %#2.2x", - rt, rn, immed, immed); - return ERROR_OK; - } - if ((op2 & 0x3c) == 0x30) { - if (rt == 0xf) { - immed = opcode & 0xff; - immed = -immed; /* pli */ - sprintf(cp, "PLI\t[r%d, #%d]\t; -%#2.2x", - rn, immed, -immed); - return ERROR_OK; - } - mnemonic = "LDRSB"; - goto ldrxb_immediate_t3; - } - if ((op2 & 0x24) == 0x24) { - mnemonic = "LDRSB"; - goto ldrxb_immediate_t3; - } - if (op2 == 0) { - int rm = opcode & 0xf; - - if (rt == 0x0f) - sprintf(cp, "PLI\t"); - else - sprintf(cp, "LDRSB.W\tr%d, ", rt); - immed = (opcode >> 4) & 0x3; - cp = strchr(cp, 0); - sprintf(cp, "[r%d, r%d, LSL #%d]", rn, rm, immed); - return ERROR_OK; - } - break; - case 3: - if (rt == 0xf) { - immed = opcode & 0xfff; - sprintf(cp, "PLI\t[r%d, #%d]\t; %#3.3x", - rn, immed, immed); - return ERROR_OK; - } - if (rn == 0xf) - goto ldrsb_literal; - immed = opcode & 0xfff; - mnemonic = "LDRSB"; - goto ldrxb_immediate_t2; - } - - return ERROR_COMMAND_SYNTAX_ERROR; -} - -static int t2ev_load_halfword(uint32_t opcode, uint32_t address, - struct arm_instruction *instruction, char *cp) -{ - int rn = (opcode >> 16) & 0xf; - int rt = (opcode >> 12) & 0xf; - int op2 = (opcode >> 6) & 0x3f; - char *sign = ""; - unsigned immed; - - if (rt == 0xf) { - sprintf(cp, "HINT (UNALLOCATED)"); - return ERROR_OK; - } - - if (opcode & (1 << 24)) - sign = "S"; - - if ((opcode & (1 << 23)) == 0) { - if (rn == 0xf) { -ldrh_literal: - immed = opcode & 0xfff; - address = thumb_alignpc4(address); - if (opcode & (1 << 23)) - address += immed; - else - address -= immed; - sprintf(cp, "LDR%sH\tr%d, %#8.8" PRIx32, - sign, rt, address); - return ERROR_OK; - } - if (op2 == 0) { - int rm = opcode & 0xf; - - immed = (opcode >> 4) & 0x3; - sprintf(cp, "LDR%sH.W\tr%d, [r%d, r%d, LSL #%d]", - sign, rt, rn, rm, immed); - return ERROR_OK; - } - if ((op2 & 0x3c) == 0x38) { - immed = opcode & 0xff; - sprintf(cp, "LDR%sHT\tr%d, [r%d, #%d]\t; %#2.2x", - sign, rt, rn, immed, immed); - return ERROR_OK; - } - if ((op2 & 0x3c) == 0x30 || (op2 & 0x24) == 0x24) { - char *p1 = "", *p2 = "]"; - - immed = opcode & 0xff; - if (!(opcode & 0x200)) - immed = -immed; - - /* two indexed modes will write back rn */ - if (opcode & 0x100) { - if (opcode & 0x400) /* pre-indexed */ - p2 = "]!"; - else { /* post-indexed */ - p1 = "]"; - p2 = ""; - } - } - sprintf(cp, "LDR%sH\tr%d, [r%d%s, #%d%s\t; %#8.8x", - sign, rt, rn, p1, immed, p2, immed); - return ERROR_OK; - } - } else { - if (rn == 0xf) - goto ldrh_literal; - - immed = opcode & 0xfff; - sprintf(cp, "LDR%sH%s\tr%d, [r%d, #%d]\t; %#6.6x", - sign, *sign ? "" : ".W", - rt, rn, immed, immed); - return ERROR_OK; - } - - return ERROR_COMMAND_SYNTAX_ERROR; -} - -/* - * REVISIT for Thumb2 instructions, instruction->type and friends aren't - * always set. That means eventual arm_simulate_step() support for Thumb2 - * will need work in this area. - */ -int thumb2_opcode(struct target *target, uint32_t address, struct arm_instruction *instruction) -{ - int retval; - uint16_t op; - uint32_t opcode; - char *cp; - - /* clear low bit ... it's set on function pointers */ - address &= ~1; - - /* clear fields, to avoid confusion */ - memset(instruction, 0, sizeof(struct arm_instruction)); - - /* read first halfword, see if this is the only one */ - retval = target_read_u16(target, address, &op); - if (retval != ERROR_OK) - return retval; - - switch (op & 0xf800) { - case 0xf800: - case 0xf000: - case 0xe800: - /* 32-bit instructions */ - instruction->instruction_size = 4; - opcode = op << 16; - retval = target_read_u16(target, address + 2, &op); - if (retval != ERROR_OK) - return retval; - opcode |= op; - instruction->opcode = opcode; - break; - default: - /* 16-bit: Thumb1 + IT + CBZ/CBNZ + ... */ - return thumb_evaluate_opcode(op, address, instruction); - } - - snprintf(instruction->text, 128, - "0x%8.8" PRIx32 " 0x%8.8" PRIx32 "\t", - address, opcode); - cp = strchr(instruction->text, 0); - retval = ERROR_FAIL; - - /* ARMv7-M: A5.3.1 Data processing (modified immediate) */ - if ((opcode & 0x1a008000) == 0x10000000) - retval = t2ev_data_mod_immed(opcode, address, instruction, cp); - - /* ARMv7-M: A5.3.3 Data processing (plain binary immediate) */ - else if ((opcode & 0x1a008000) == 0x12000000) - retval = t2ev_data_immed(opcode, address, instruction, cp); - - /* ARMv7-M: A5.3.4 Branches and miscellaneous control */ - else if ((opcode & 0x18008000) == 0x10008000) - retval = t2ev_b_misc(opcode, address, instruction, cp); - - /* ARMv7-M: A5.3.5 Load/store multiple */ - else if ((opcode & 0x1e400000) == 0x08000000) - retval = t2ev_ldm_stm(opcode, address, instruction, cp); - - /* ARMv7-M: A5.3.6 Load/store dual or exclusive, table branch */ - else if ((opcode & 0x1e400000) == 0x08400000) - retval = t2ev_ldrex_strex(opcode, address, instruction, cp); - - /* ARMv7-M: A5.3.7 Load word */ - else if ((opcode & 0x1f700000) == 0x18500000) - retval = t2ev_load_word(opcode, address, instruction, cp); - - /* ARMv7-M: A5.3.8 Load halfword, unallocated memory hints */ - else if ((opcode & 0x1e700000) == 0x18300000) - retval = t2ev_load_halfword(opcode, address, instruction, cp); - - /* ARMv7-M: A5.3.9 Load byte, memory hints */ - else if ((opcode & 0x1e700000) == 0x18100000) - retval = t2ev_load_byte_hints(opcode, address, instruction, cp); - - /* ARMv7-M: A5.3.10 Store single data item */ - else if ((opcode & 0x1f100000) == 0x18000000) - retval = t2ev_store_single(opcode, address, instruction, cp); - - /* ARMv7-M: A5.3.11 Data processing (shifted register) */ - else if ((opcode & 0x1e000000) == 0x0a000000) - retval = t2ev_data_shift(opcode, address, instruction, cp); - - /* ARMv7-M: A5.3.12 Data processing (register) - * and A5.3.13 Miscellaneous operations - */ - else if ((opcode & 0x1f000000) == 0x1a000000) - retval = t2ev_data_reg(opcode, address, instruction, cp); - - /* ARMv7-M: A5.3.14 Multiply, and multiply accumulate */ - else if ((opcode & 0x1f800000) == 0x1b000000) - retval = t2ev_mul32(opcode, address, instruction, cp); - - /* ARMv7-M: A5.3.15 Long multiply, long multiply accumulate, divide */ - else if ((opcode & 0x1f800000) == 0x1b800000) - retval = t2ev_mul64_div(opcode, address, instruction, cp); - - if (retval == ERROR_OK) - return retval; - - /* - * Thumb2 also supports coprocessor, ThumbEE, and DSP/Media (SIMD) - * instructions; not yet handled here. - */ - - if (retval == ERROR_COMMAND_SYNTAX_ERROR) { - instruction->type = ARM_UNDEFINED_INSTRUCTION; - strcpy(cp, "UNDEFINED OPCODE"); - return ERROR_OK; - } - - LOG_DEBUG("Can't decode 32-bit Thumb2 yet (opcode=%08" PRIx32 ")", - opcode); - - strcpy(cp, "(32-bit Thumb2 ...)"); - return ERROR_OK; -} - -int arm_access_size(struct arm_instruction *instruction) -{ - if ((instruction->type == ARM_LDRB) - || (instruction->type == ARM_LDRBT) - || (instruction->type == ARM_LDRSB) - || (instruction->type == ARM_STRB) - || (instruction->type == ARM_STRBT)) - return 1; - else if ((instruction->type == ARM_LDRH) - || (instruction->type == ARM_LDRSH) - || (instruction->type == ARM_STRH)) - return 2; - else if ((instruction->type == ARM_LDR) - || (instruction->type == ARM_LDRT) - || (instruction->type == ARM_STR) - || (instruction->type == ARM_STRT)) - return 4; - else if ((instruction->type == ARM_LDRD) - || (instruction->type == ARM_STRD)) - return 8; - else { - LOG_ERROR("BUG: instruction type %i isn't a load/store instruction", - instruction->type); - return 0; - } -} diff --git a/src/target/arm_disassembler.h b/src/target/arm_disassembler.h deleted file mode 100644 index 6f8f65d44..000000000 --- a/src/target/arm_disassembler.h +++ /dev/null @@ -1,204 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2006 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifndef OPENOCD_TARGET_ARM_DISASSEMBLER_H -#define OPENOCD_TARGET_ARM_DISASSEMBLER_H - -enum arm_instruction_type { - ARM_UNKNOWN_INSTUCTION, - - /* Branch instructions */ - ARM_B, - ARM_BL, - ARM_BX, - ARM_BLX, - - /* Data processing instructions */ - ARM_AND, - ARM_EOR, - ARM_SUB, - ARM_RSB, - ARM_ADD, - ARM_ADC, - ARM_SBC, - ARM_RSC, - ARM_TST, - ARM_TEQ, - ARM_CMP, - ARM_CMN, - ARM_ORR, - ARM_MOV, - ARM_BIC, - ARM_MVN, - - /* Load/store instructions */ - ARM_LDR, - ARM_LDRB, - ARM_LDRT, - ARM_LDRBT, - - ARM_LDRH, - ARM_LDRSB, - ARM_LDRSH, - - ARM_LDM, - - ARM_STR, - ARM_STRB, - ARM_STRT, - ARM_STRBT, - - ARM_STRH, - - ARM_STM, - - /* Status register access instructions */ - ARM_MRS, - ARM_MSR, - - /* Multiply instructions */ - ARM_MUL, - ARM_MLA, - ARM_SMULL, - ARM_SMLAL, - ARM_UMULL, - ARM_UMLAL, - - /* Miscellaneous instructions */ - ARM_CLZ, - - /* Exception return instructions */ - ARM_ERET, - - /* Exception generating instructions */ - ARM_BKPT, - ARM_SWI, - ARM_HVC, - ARM_SMC, - - /* Coprocessor instructions */ - ARM_CDP, - ARM_LDC, - ARM_STC, - ARM_MCR, - ARM_MRC, - - /* Semaphore instructions */ - ARM_SWP, - ARM_SWPB, - - /* Enhanced DSP extensions */ - ARM_MCRR, - ARM_MRRC, - ARM_PLD, - ARM_QADD, - ARM_QDADD, - ARM_QSUB, - ARM_QDSUB, - ARM_SMLAxy, - ARM_SMLALxy, - ARM_SMLAWy, - ARM_SMULxy, - ARM_SMULWy, - ARM_LDRD, - ARM_STRD, - - ARM_UNDEFINED_INSTRUCTION = 0xffffffff, -}; - -struct arm_b_bl_bx_blx_instr { - int reg_operand; - uint32_t target_address; -}; - -union arm_shifter_operand { - struct { - uint32_t immediate; - } immediate; - struct { - uint8_t Rm; - uint8_t shift; /* 0: LSL, 1: LSR, 2: ASR, 3: ROR, 4: RRX */ - uint8_t shift_imm; - } immediate_shift; - struct { - uint8_t Rm; - uint8_t shift; - uint8_t Rs; - } register_shift; -}; - -struct arm_data_proc_instr { - int variant; /* 0: immediate, 1: immediate_shift, 2: register_shift */ - uint8_t S; - uint8_t Rn; - uint8_t Rd; - union arm_shifter_operand shifter_operand; -}; - -struct arm_load_store_instr { - uint8_t Rd; - uint8_t Rn; - uint8_t U; - int index_mode; /* 0: offset, 1: pre-indexed, 2: post-indexed */ - int offset_mode; /* 0: immediate, 1: (scaled) register */ - union { - uint32_t offset; - struct { - uint8_t Rm; - uint8_t shift; /* 0: LSL, 1: LSR, 2: ASR, 3: ROR, 4: RRX */ - uint8_t shift_imm; - } reg; - } offset; -}; - -struct arm_load_store_multiple_instr { - uint8_t Rn; - uint32_t register_list; - uint8_t addressing_mode; /* 0: IA, 1: IB, 2: DA, 3: DB */ - uint8_t S; - uint8_t W; -}; - -struct arm_instruction { - enum arm_instruction_type type; - char text[128]; - uint32_t opcode; - - /* return value ... Thumb-2 sizes vary */ - unsigned instruction_size; - - union { - struct arm_b_bl_bx_blx_instr b_bl_bx_blx; - struct arm_data_proc_instr data_proc; - struct arm_load_store_instr load_store; - struct arm_load_store_multiple_instr load_store_multiple; - } info; - -}; - -int arm_evaluate_opcode(uint32_t opcode, uint32_t address, - struct arm_instruction *instruction); -int thumb_evaluate_opcode(uint16_t opcode, uint32_t address, - struct arm_instruction *instruction); -int thumb2_opcode(struct target *target, uint32_t address, - struct arm_instruction *instruction); -int arm_access_size(struct arm_instruction *instruction); - -#define COND(opcode) (arm_condition_strings[(opcode & 0xf0000000) >> 28]) - -#endif /* OPENOCD_TARGET_ARM_DISASSEMBLER_H */ diff --git a/src/target/arm_dpm.c b/src/target/arm_dpm.c deleted file mode 100644 index 8ad6575cf..000000000 --- a/src/target/arm_dpm.c +++ /dev/null @@ -1,1042 +0,0 @@ -/* - * Copyright (C) 2009 by David Brownell - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "arm.h" -#include "arm_dpm.h" -#include -#include "register.h" -#include "breakpoints.h" -#include "target_type.h" -#include "arm_opcodes.h" - - -/** - * @file - * Implements various ARM DPM operations using architectural debug registers. - * These routines layer over core-specific communication methods to cope with - * implementation differences between cores like ARM1136 and Cortex-A8. - * - * The "Debug Programmers' Model" (DPM) for ARMv6 and ARMv7 is defined by - * Part C (Debug Architecture) of the ARM Architecture Reference Manual, - * ARMv7-A and ARMv7-R edition (ARM DDI 0406B). In OpenOCD, DPM operations - * are abstracted through internal programming interfaces to share code and - * to minimize needless differences in debug behavior between cores. - */ - -/*----------------------------------------------------------------------*/ - -/* - * Coprocessor support - */ - -/* Read coprocessor */ -static int dpm_mrc(struct target *target, int cpnum, - uint32_t op1, uint32_t op2, uint32_t CRn, uint32_t CRm, - uint32_t *value) -{ - struct arm *arm = target_to_arm(target); - struct arm_dpm *dpm = arm->dpm; - int retval; - - retval = dpm->prepare(dpm); - if (retval != ERROR_OK) - return retval; - - LOG_DEBUG("MRC p%d, %d, r0, c%d, c%d, %d", cpnum, - (int) op1, (int) CRn, - (int) CRm, (int) op2); - - /* read coprocessor register into R0; return via DCC */ - retval = dpm->instr_read_data_r0(dpm, - ARMV4_5_MRC(cpnum, op1, 0, CRn, CRm, op2), - value); - - /* (void) */ dpm->finish(dpm); - return retval; -} - -static int dpm_mcr(struct target *target, int cpnum, - uint32_t op1, uint32_t op2, uint32_t CRn, uint32_t CRm, - uint32_t value) -{ - struct arm *arm = target_to_arm(target); - struct arm_dpm *dpm = arm->dpm; - int retval; - - retval = dpm->prepare(dpm); - if (retval != ERROR_OK) - return retval; - - LOG_DEBUG("MCR p%d, %d, r0, c%d, c%d, %d", cpnum, - (int) op1, (int) CRn, - (int) CRm, (int) op2); - - /* read DCC into r0; then write coprocessor register from R0 */ - retval = dpm->instr_write_data_r0(dpm, - ARMV4_5_MCR(cpnum, op1, 0, CRn, CRm, op2), - value); - - /* (void) */ dpm->finish(dpm); - return retval; -} - -/*----------------------------------------------------------------------*/ - -/* - * Register access utilities - */ - -/* Toggles between recorded core mode (USR, SVC, etc) and a temporary one. - * Routines *must* restore the original mode before returning!! - */ -int dpm_modeswitch(struct arm_dpm *dpm, enum arm_mode mode) -{ - int retval; - uint32_t cpsr; - - /* restore previous mode */ - if (mode == ARM_MODE_ANY) - cpsr = buf_get_u32(dpm->arm->cpsr->value, 0, 32); - - /* else force to the specified mode */ - else - cpsr = mode; - - retval = dpm->instr_write_data_r0(dpm, ARMV4_5_MSR_GP(0, 0xf, 0), cpsr); - if (retval != ERROR_OK) - return retval; - - if (dpm->instr_cpsr_sync) - retval = dpm->instr_cpsr_sync(dpm); - - return retval; -} - -/* just read the register -- rely on the core mode being right */ -static int dpm_read_reg(struct arm_dpm *dpm, struct reg *r, unsigned regnum) -{ - uint32_t value; - int retval; - - switch (regnum) { - case 0 ... 14: - /* return via DCC: "MCR p14, 0, Rnum, c0, c5, 0" */ - retval = dpm->instr_read_data_dcc(dpm, - ARMV4_5_MCR(14, 0, regnum, 0, 5, 0), - &value); - break; - case 15:/* PC - * "MOV r0, pc"; then return via DCC */ - retval = dpm->instr_read_data_r0(dpm, 0xe1a0000f, &value); - - /* NOTE: this seems like a slightly awkward place to update - * this value ... but if the PC gets written (the only way - * to change what we compute), the arch spec says subsequent - * reads return values which are "unpredictable". So this - * is always right except in those broken-by-intent cases. - */ - switch (dpm->arm->core_state) { - case ARM_STATE_ARM: - value -= 8; - break; - case ARM_STATE_THUMB: - case ARM_STATE_THUMB_EE: - value -= 4; - break; - case ARM_STATE_JAZELLE: - /* core-specific ... ? */ - LOG_WARNING("Jazelle PC adjustment unknown"); - break; - } - break; - default: - /* 16: "MRS r0, CPSR"; then return via DCC - * 17: "MRS r0, SPSR"; then return via DCC - */ - retval = dpm->instr_read_data_r0(dpm, - ARMV4_5_MRS(0, regnum & 1), - &value); - break; - } - - if (retval == ERROR_OK) { - buf_set_u32(r->value, 0, 32, value); - r->valid = true; - r->dirty = false; - LOG_DEBUG("READ: %s, %8.8x", r->name, (unsigned) value); - } - - return retval; -} - -/* just write the register -- rely on the core mode being right */ -static int dpm_write_reg(struct arm_dpm *dpm, struct reg *r, unsigned regnum) -{ - int retval; - uint32_t value = buf_get_u32(r->value, 0, 32); - - switch (regnum) { - case 0 ... 14: - /* load register from DCC: "MRC p14, 0, Rnum, c0, c5, 0" */ - retval = dpm->instr_write_data_dcc(dpm, - ARMV4_5_MRC(14, 0, regnum, 0, 5, 0), - value); - break; - case 15:/* PC - * read r0 from DCC; then "MOV pc, r0" */ - retval = dpm->instr_write_data_r0(dpm, 0xe1a0f000, value); - break; - default: - /* 16: read r0 from DCC, then "MSR r0, CPSR_cxsf" - * 17: read r0 from DCC, then "MSR r0, SPSR_cxsf" - */ - retval = dpm->instr_write_data_r0(dpm, - ARMV4_5_MSR_GP(0, 0xf, regnum & 1), - value); - if (retval != ERROR_OK) - return retval; - - if (regnum == 16 && dpm->instr_cpsr_sync) - retval = dpm->instr_cpsr_sync(dpm); - - break; - } - - if (retval == ERROR_OK) { - r->dirty = false; - LOG_DEBUG("WRITE: %s, %8.8x", r->name, (unsigned) value); - } - - 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). - * In normal operation this is called on entry to halting debug state, - * possibly after some other operations supporting restore of debug state - * or making sure the CPU is fully idle (drain write buffer, etc). - */ -int arm_dpm_read_current_registers(struct arm_dpm *dpm) -{ - struct arm *arm = dpm->arm; - uint32_t cpsr; - int retval; - struct reg *r; - - retval = dpm->prepare(dpm); - if (retval != ERROR_OK) - return retval; - - /* read R0 first (it's used for scratch), then CPSR */ - r = arm->core_cache->reg_list + 0; - if (!r->valid) { - retval = dpm_read_reg(dpm, r, 0); - if (retval != ERROR_OK) - goto fail; - } - r->dirty = true; - - retval = dpm->instr_read_data_r0(dpm, ARMV4_5_MRS(0, 0), &cpsr); - if (retval != ERROR_OK) - goto fail; - - /* update core mode and state, plus shadow mapping for R8..R14 */ - arm_set_cpsr(arm, cpsr); - - /* REVISIT we can probably avoid reading R1..R14, saving time... */ - for (unsigned i = 1; i < 16; i++) { - r = arm_reg_current(arm, i); - if (r->valid) - continue; - - retval = dpm_read_reg(dpm, r, i); - if (retval != ERROR_OK) - goto fail; - } - - /* NOTE: SPSR ignored (if it's even relevant). */ - - /* REVISIT the debugger can trigger various exceptions. See the - * ARMv7A architecture spec, section C5.7, for more info about - * what defenses are needed; v6 debug has the most issues. - */ - -fail: - /* (void) */ dpm->finish(dpm); - return retval; -} - -/* Avoid needless I/O ... leave breakpoints and watchpoints alone - * unless they're removed, or need updating because of single-stepping - * or running debugger code. - */ -static int dpm_maybe_update_bpwp(struct arm_dpm *dpm, bool bpwp, - struct dpm_bpwp *xp, int *set_p) -{ - int retval = ERROR_OK; - bool disable; - - if (!set_p) { - if (!xp->dirty) - goto done; - xp->dirty = false; - /* removed or startup; we must disable it */ - disable = true; - } else if (bpwp) { - if (!xp->dirty) - goto done; - /* disabled, but we must set it */ - xp->dirty = disable = false; - *set_p = true; - } else { - if (!*set_p) - goto done; - /* set, but we must temporarily disable it */ - xp->dirty = disable = true; - *set_p = false; - } - - if (disable) - retval = dpm->bpwp_disable(dpm, xp->number); - else - retval = dpm->bpwp_enable(dpm, xp->number, - xp->address, xp->control); - - if (retval != ERROR_OK) - LOG_ERROR("%s: can't %s HW %spoint %d", - disable ? "disable" : "enable", - target_name(dpm->arm->target), - (xp->number < 16) ? "break" : "watch", - xp->number & 0xf); -done: - return retval; -} - -static int dpm_add_breakpoint(struct target *target, struct breakpoint *bp); - -/** - * Writes all modified core registers for all processor modes. In normal - * operation this is called on exit from halting debug state. - * - * @param dpm: represents the processor - * @param bpwp: true ensures breakpoints and watchpoints are set, - * false ensures they are cleared - */ -int arm_dpm_write_dirty_registers(struct arm_dpm *dpm, bool bpwp) -{ - struct arm *arm = dpm->arm; - struct reg_cache *cache = arm->core_cache; - int retval; - bool did_write; - - retval = dpm->prepare(dpm); - if (retval != ERROR_OK) - goto done; - - /* If we're managing hardware breakpoints for this core, enable - * or disable them as requested. - * - * REVISIT We don't yet manage them for ANY cores. Eventually - * we should be able to assume we handle them; but until then, - * cope with the hand-crafted breakpoint code. - */ - if (arm->target->type->add_breakpoint == dpm_add_breakpoint) { - for (unsigned i = 0; i < dpm->nbp; i++) { - struct dpm_bp *dbp = dpm->dbp + i; - struct breakpoint *bp = dbp->bp; - - retval = dpm_maybe_update_bpwp(dpm, bpwp, &dbp->bpwp, - bp ? &bp->set : NULL); - if (retval != ERROR_OK) - goto done; - } - } - - /* enable/disable watchpoints */ - for (unsigned i = 0; i < dpm->nwp; i++) { - struct dpm_wp *dwp = dpm->dwp + i; - struct watchpoint *wp = dwp->wp; - - retval = dpm_maybe_update_bpwp(dpm, bpwp, &dwp->bpwp, - wp ? &wp->set : NULL); - if (retval != ERROR_OK) - goto done; - } - - /* NOTE: writes to breakpoint and watchpoint registers might - * be queued, and need (efficient/batched) flushing later. - */ - - /* Scan the registers until we find one that's both dirty and - * eligible for flushing. Flush that and everything else that - * shares the same core mode setting. Typically this won't - * actually find anything to do... - */ - do { - enum arm_mode mode = ARM_MODE_ANY; - - did_write = false; - - /* check everything except our scratch register R0 */ - for (unsigned i = 1; i < cache->num_regs; i++) { - struct arm_reg *r; - unsigned regnum; - - /* also skip PC, CPSR, and non-dirty */ - if (i == 15) - continue; - if (arm->cpsr == cache->reg_list + i) - continue; - if (!cache->reg_list[i].dirty) - continue; - - r = cache->reg_list[i].arch_info; - regnum = r->num; - - /* may need to pick and set a mode */ - if (!did_write) { - enum arm_mode tmode; - - did_write = true; - mode = tmode = r->mode; - - /* 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; - } - - /* REVISIT error checks */ - if (tmode != ARM_MODE_ANY) { - retval = dpm_modeswitch(dpm, tmode); - if (retval != ERROR_OK) - goto done; - } - } - if (r->mode != mode) - continue; - - retval = dpm_write_reg(dpm, - &cache->reg_list[i], - regnum); - if (retval != ERROR_OK) - goto done; - } - - } while (did_write); - - /* Restore original CPSR ... assuming either that we changed it, - * or it's dirty. Must write PC to ensure the return address is - * defined, and must not write it before CPSR. - */ - retval = dpm_modeswitch(dpm, ARM_MODE_ANY); - if (retval != ERROR_OK) - 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; - arm->pc->dirty = false; - - /* flush R0 -- it's *very* dirty by now */ - retval = dpm_write_reg(dpm, &cache->reg_list[0], 0); - if (retval != ERROR_OK) - goto done; - cache->reg_list[0].dirty = false; - - /* (void) */ dpm->finish(dpm); -done: - return retval; -} - -/* Returns ARM_MODE_ANY or temporary mode to use while reading the - * specified register ... works around flakiness from ARM core calls. - * Caller already filtered out SPSR access; mode is never MODE_SYS - * or MODE_ANY. - */ -static enum arm_mode dpm_mapmode(struct arm *arm, - unsigned num, enum arm_mode mode) -{ - enum arm_mode amode = arm->core_mode; - - /* don't switch if the mode is already correct */ - if (amode == ARM_MODE_SYS) - amode = ARM_MODE_USR; - if (mode == amode) - return ARM_MODE_ANY; - - switch (num) { - /* don't switch for non-shadowed registers (r0..r7, r15/pc, cpsr) */ - case 0 ... 7: - case 15: - case 16: - break; - /* r8..r12 aren't shadowed for anything except FIQ */ - case 8 ... 12: - if (mode == ARM_MODE_FIQ) - return mode; - break; - /* r13/sp, and r14/lr are always shadowed */ - case 13: - case 14: - return mode; - default: - LOG_WARNING("invalid register #%u", num); - break; - } - return ARM_MODE_ANY; -} - - -/* - * Standard ARM register accessors ... there are three methods - * in "struct arm", to support individual read/write and bulk read - * of registers. - */ - -static int arm_dpm_read_core_reg(struct target *target, struct reg *r, - int regnum, enum arm_mode mode) -{ - struct arm_dpm *dpm = target_to_arm(target)->dpm; - int retval; - - if (regnum < 0 || regnum > 16) - return ERROR_COMMAND_SYNTAX_ERROR; - - if (regnum == 16) { - if (mode != ARM_MODE_ANY) - regnum = 17; - } else - mode = dpm_mapmode(dpm->arm, regnum, mode); - - /* REVISIT what happens if we try to read SPSR in a core mode - * which has no such register? - */ - - retval = dpm->prepare(dpm); - if (retval != ERROR_OK) - return retval; - - if (mode != ARM_MODE_ANY) { - retval = dpm_modeswitch(dpm, mode); - if (retval != ERROR_OK) - goto fail; - } - - retval = dpm_read_reg(dpm, r, regnum); - if (retval != ERROR_OK) - goto fail; - /* always clean up, regardless of error */ - - if (mode != ARM_MODE_ANY) - /* (void) */ dpm_modeswitch(dpm, ARM_MODE_ANY); - -fail: - /* (void) */ dpm->finish(dpm); - return retval; -} - -static int arm_dpm_write_core_reg(struct target *target, struct reg *r, - int regnum, enum arm_mode mode, uint8_t *value) -{ - struct arm_dpm *dpm = target_to_arm(target)->dpm; - int retval; - - - if (regnum < 0 || regnum > 16) - return ERROR_COMMAND_SYNTAX_ERROR; - - if (regnum == 16) { - if (mode != ARM_MODE_ANY) - regnum = 17; - } else - mode = dpm_mapmode(dpm->arm, regnum, mode); - - /* REVISIT what happens if we try to write SPSR in a core mode - * which has no such register? - */ - - retval = dpm->prepare(dpm); - if (retval != ERROR_OK) - return retval; - - if (mode != ARM_MODE_ANY) { - retval = dpm_modeswitch(dpm, mode); - if (retval != ERROR_OK) - goto fail; - } - - retval = dpm_write_reg(dpm, r, regnum); - /* always clean up, regardless of error */ - - if (mode != ARM_MODE_ANY) - /* (void) */ dpm_modeswitch(dpm, ARM_MODE_ANY); - -fail: - /* (void) */ dpm->finish(dpm); - return retval; -} - -static int arm_dpm_full_context(struct target *target) -{ - struct arm *arm = target_to_arm(target); - struct arm_dpm *dpm = arm->dpm; - struct reg_cache *cache = arm->core_cache; - int retval; - bool did_read; - - retval = dpm->prepare(dpm); - if (retval != ERROR_OK) - goto done; - - do { - enum arm_mode mode = ARM_MODE_ANY; - - did_read = false; - - /* We "know" arm_dpm_read_current_registers() was called so - * the unmapped registers (R0..R7, PC, AND CPSR) and some - * view of R8..R14 are current. We also "know" oddities of - * register mapping: special cases for R8..R12 and SPSR. - * - * Pick some mode with unread registers and read them all. - * Repeat until done. - */ - for (unsigned i = 0; i < cache->num_regs; i++) { - struct arm_reg *r; - - if (cache->reg_list[i].valid) - continue; - r = cache->reg_list[i].arch_info; - - /* may need to pick a mode and set CPSR */ - if (!did_read) { - did_read = true; - mode = r->mode; - - /* For regular (ARM_MODE_ANY) R8..R12 - * in case we've entered debug state - * in FIQ mode we need to patch mode. - */ - if (mode != ARM_MODE_ANY) - retval = dpm_modeswitch(dpm, mode); - else - retval = dpm_modeswitch(dpm, ARM_MODE_USR); - - if (retval != ERROR_OK) - goto done; - } - if (r->mode != mode) - continue; - - /* CPSR was read, so "R16" must mean SPSR */ - retval = dpm_read_reg(dpm, - &cache->reg_list[i], - (r->num == 16) ? 17 : r->num); - if (retval != ERROR_OK) - goto done; - } - - } while (did_read); - - retval = dpm_modeswitch(dpm, ARM_MODE_ANY); - /* (void) */ dpm->finish(dpm); -done: - return retval; -} - - -/*----------------------------------------------------------------------*/ - -/* - * Breakpoint and Watchpoint support. - * - * Hardware {break,watch}points are usually left active, to minimize - * debug entry/exit costs. When they are set or cleared, it's done in - * batches. Also, DPM-conformant hardware can update debug registers - * regardless of whether the CPU is running or halted ... though that - * fact isn't currently leveraged. - */ - -static int dpm_bpwp_setup(struct arm_dpm *dpm, struct dpm_bpwp *xp, - uint32_t addr, uint32_t length) -{ - uint32_t control; - - control = (1 << 0) /* enable */ - | (3 << 1); /* both user and privileged access */ - - /* Match 1, 2, or all 4 byte addresses in this word. - * - * FIXME: v7 hardware allows lengths up to 2 GB for BP and WP. - * Support larger length, when addr is suitably aligned. In - * particular, allow watchpoints on 8 byte "double" values. - * - * REVISIT allow watchpoints on unaligned 2-bit values; and on - * v7 hardware, unaligned 4-byte ones too. - */ - switch (length) { - case 1: - control |= (1 << (addr & 3)) << 5; - break; - case 2: - /* require 2-byte alignment */ - if (!(addr & 1)) { - control |= (3 << (addr & 2)) << 5; - break; - } - /* FALL THROUGH */ - case 4: - /* require 4-byte alignment */ - if (!(addr & 3)) { - control |= 0xf << 5; - break; - } - /* FALL THROUGH */ - default: - LOG_ERROR("unsupported {break,watch}point length/alignment"); - return ERROR_COMMAND_SYNTAX_ERROR; - } - - /* other shared control bits: - * bits 15:14 == 0 ... both secure and nonsecure states (v6.1+ only) - * bit 20 == 0 ... not linked to a context ID - * bit 28:24 == 0 ... not ignoring N LSBs (v7 only) - */ - - xp->address = addr & ~3; - xp->control = control; - xp->dirty = true; - - LOG_DEBUG("BPWP: addr %8.8" PRIx32 ", control %" PRIx32 ", number %d", - xp->address, control, xp->number); - - /* hardware is updated in write_dirty_registers() */ - return ERROR_OK; -} - -static int dpm_add_breakpoint(struct target *target, struct breakpoint *bp) -{ - struct arm *arm = target_to_arm(target); - struct arm_dpm *dpm = arm->dpm; - int retval = ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - - if (bp->length < 2) - return ERROR_COMMAND_SYNTAX_ERROR; - if (!dpm->bpwp_enable) - return retval; - - /* FIXME we need a generic solution for software breakpoints. */ - if (bp->type == BKPT_SOFT) - LOG_DEBUG("using HW bkpt, not SW..."); - - for (unsigned i = 0; i < dpm->nbp; i++) { - if (!dpm->dbp[i].bp) { - retval = dpm_bpwp_setup(dpm, &dpm->dbp[i].bpwp, - bp->address, bp->length); - if (retval == ERROR_OK) - dpm->dbp[i].bp = bp; - break; - } - } - - return retval; -} - -static int dpm_remove_breakpoint(struct target *target, struct breakpoint *bp) -{ - struct arm *arm = target_to_arm(target); - struct arm_dpm *dpm = arm->dpm; - int retval = ERROR_COMMAND_SYNTAX_ERROR; - - for (unsigned i = 0; i < dpm->nbp; i++) { - if (dpm->dbp[i].bp == bp) { - dpm->dbp[i].bp = NULL; - dpm->dbp[i].bpwp.dirty = true; - - /* hardware is updated in write_dirty_registers() */ - retval = ERROR_OK; - break; - } - } - - return retval; -} - -static int dpm_watchpoint_setup(struct arm_dpm *dpm, unsigned index_t, - struct watchpoint *wp) -{ - int retval; - struct dpm_wp *dwp = dpm->dwp + index_t; - uint32_t control; - - /* this hardware doesn't support data value matching or masking */ - if (wp->value || wp->mask != ~(uint32_t)0) { - LOG_DEBUG("watchpoint values and masking not supported"); - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - } - - retval = dpm_bpwp_setup(dpm, &dwp->bpwp, wp->address, wp->length); - if (retval != ERROR_OK) - return retval; - - control = dwp->bpwp.control; - switch (wp->rw) { - case WPT_READ: - control |= 1 << 3; - break; - case WPT_WRITE: - control |= 2 << 3; - break; - case WPT_ACCESS: - control |= 3 << 3; - break; - } - dwp->bpwp.control = control; - - dpm->dwp[index_t].wp = wp; - - return retval; -} - -static int dpm_add_watchpoint(struct target *target, struct watchpoint *wp) -{ - struct arm *arm = target_to_arm(target); - struct arm_dpm *dpm = arm->dpm; - int retval = ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - - if (dpm->bpwp_enable) { - for (unsigned i = 0; i < dpm->nwp; i++) { - if (!dpm->dwp[i].wp) { - retval = dpm_watchpoint_setup(dpm, i, wp); - break; - } - } - } - - return retval; -} - -static int dpm_remove_watchpoint(struct target *target, struct watchpoint *wp) -{ - struct arm *arm = target_to_arm(target); - struct arm_dpm *dpm = arm->dpm; - int retval = ERROR_COMMAND_SYNTAX_ERROR; - - for (unsigned i = 0; i < dpm->nwp; i++) { - if (dpm->dwp[i].wp == wp) { - dpm->dwp[i].wp = NULL; - dpm->dwp[i].bpwp.dirty = true; - - /* hardware is updated in write_dirty_registers() */ - retval = ERROR_OK; - break; - } - } - - return retval; -} - -void arm_dpm_report_wfar(struct arm_dpm *dpm, uint32_t addr) -{ - switch (dpm->arm->core_state) { - case ARM_STATE_ARM: - addr -= 8; - break; - case ARM_STATE_THUMB: - case ARM_STATE_THUMB_EE: - addr -= 4; - break; - case ARM_STATE_JAZELLE: - /* ?? */ - break; - } - dpm->wp_pc = addr; -} - -/*----------------------------------------------------------------------*/ - -/* - * Other debug and support utilities - */ - -void arm_dpm_report_dscr(struct arm_dpm *dpm, uint32_t dscr) -{ - struct target *target = dpm->arm->target; - - dpm->dscr = 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 */ - target->debug_reason = DBG_REASON_DBGRQ; - break; - case 1: /* HW breakpoint */ - case 3: /* SW BKPT */ - case 5: /* vector catch */ - target->debug_reason = DBG_REASON_BREAKPOINT; - break; - case 2: /* asynch watchpoint */ - case 10:/* precise watchpoint */ - target->debug_reason = DBG_REASON_WATCHPOINT; - break; - default: - target->debug_reason = DBG_REASON_UNDEFINED; - break; - } -} - -/*----------------------------------------------------------------------*/ - -/* - * Setup and management support. - */ - -/** - * Hooks up this DPM to its associated target; call only once. - * Initially this only covers the register cache. - * - * Oh, and watchpoints. Yeah. - */ -int arm_dpm_setup(struct arm_dpm *dpm) -{ - struct arm *arm = dpm->arm; - struct target *target = arm->target; - struct reg_cache *cache; - - arm->dpm = dpm; - - /* register access setup */ - arm->full_context = arm_dpm_full_context; - 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; - - *register_get_last_cache_p(&target->reg_cache) = cache; - - /* coprocessor access setup */ - arm->mrc = dpm_mrc; - arm->mcr = dpm_mcr; - - /* breakpoint setup -- optional until it works everywhere */ - if (!target->type->add_breakpoint) { - target->type->add_breakpoint = dpm_add_breakpoint; - target->type->remove_breakpoint = dpm_remove_breakpoint; - } - - /* watchpoint setup */ - target->type->add_watchpoint = dpm_add_watchpoint; - target->type->remove_watchpoint = dpm_remove_watchpoint; - - /* 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->dwp = calloc(dpm->nwp, sizeof *dpm->dwp); - - if (!dpm->dbp || !dpm->dwp) { - free(dpm->dbp); - free(dpm->dwp); - return ERROR_FAIL; - } - - LOG_INFO("%s: hardware has %d breakpoints, %d watchpoints", - target_name(target), dpm->nbp, dpm->nwp); - - /* REVISIT ... and some of those breakpoints could match - * execution context IDs... - */ - - return ERROR_OK; -} - -/** - * Reinitializes DPM state at the beginning of a new debug session - * or after a reset which may have affected the debug module. - */ -int arm_dpm_initialize(struct arm_dpm *dpm) -{ - /* Disable all breakpoints and watchpoints at startup. */ - if (dpm->bpwp_disable) { - unsigned i; - - for (i = 0; i < dpm->nbp; i++) { - dpm->dbp[i].bpwp.number = i; - (void) dpm->bpwp_disable(dpm, i); - } - for (i = 0; i < dpm->nwp; i++) { - dpm->dwp[i].bpwp.number = 16 + i; - (void) dpm->bpwp_disable(dpm, 16 + i); - } - } else - LOG_WARNING("%s: can't disable breakpoints and watchpoints", - target_name(dpm->arm->target)); - - return ERROR_OK; -} diff --git a/src/target/arm_dpm.h b/src/target/arm_dpm.h deleted file mode 100644 index fa87baf40..000000000 --- a/src/target/arm_dpm.h +++ /dev/null @@ -1,201 +0,0 @@ -/* - * Copyright (C) 2009 by David Brownell - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef OPENOCD_TARGET_ARM_DPM_H -#define OPENOCD_TARGET_ARM_DPM_H - -/** - * @file - * This is the interface to the Debug Programmers Model for ARMv6 and - * ARMv7 processors. ARMv6 processors (such as ARM11xx implementations) - * introduced a model which became part of the ARMv7-AR architecture - * which is most familiar through the Cortex-A series parts. While - * specific details differ (like how to write the instruction register), - * the high level models easily support shared code because those - * registers are compatible. - */ - -struct dpm_bpwp { - unsigned number; - uint32_t address; - uint32_t control; - /* true if hardware state needs flushing */ - bool dirty; -}; - -struct dpm_bp { - struct breakpoint *bp; - struct dpm_bpwp bpwp; -}; - -struct dpm_wp { - struct watchpoint *wp; - struct dpm_bpwp bpwp; -}; - -/** - * This wraps an implementation of DPM primitives. Each interface - * provider supplies a structure like this, which is the glue between - * upper level code and the lower level hardware access. - * - * It is a PRELIMINARY AND INCOMPLETE set of primitives, starting with - * support for CPU register access. - */ -struct arm_dpm { - struct arm *arm; - - /** Cache of DIDR */ - uint32_t didr; - - /** Invoke before a series of instruction operations */ - int (*prepare)(struct arm_dpm *); - - /** Invoke after a series of instruction operations */ - int (*finish)(struct arm_dpm *); - - /* 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); - - /** Runs one instruction, writing data to R0 before execution. */ - int (*instr_write_data_r0)(struct arm_dpm *, - uint32_t opcode, uint32_t data); - - /** Optional core-specific operation invoked after CPSR writes. */ - int (*instr_cpsr_sync)(struct arm_dpm *dpm); - - /* READ FROM CPU */ - - /** Runs one instruction, reading data from dcc after execution. */ - int (*instr_read_data_dcc)(struct arm_dpm *, - uint32_t opcode, uint32_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); - - /* BREAKPOINT/WATCHPOINT SUPPORT */ - - /** - * Enables one breakpoint or watchpoint by writing to the - * hardware registers. The specified breakpoint/watchpoint - * must currently be disabled. Indices 0..15 are used for - * breakpoints; indices 16..31 are for watchpoints. - */ - int (*bpwp_enable)(struct arm_dpm *, unsigned index_value, - uint32_t addr, uint32_t control); - - /** - * Disables one breakpoint or watchpoint by clearing its - * hardware control registers. Indices are the same ones - * accepted by bpwp_enable(). - */ - int (*bpwp_disable)(struct arm_dpm *, unsigned index_value); - - /* The breakpoint and watchpoint arrays are private to the - * DPM infrastructure. There are nbp indices in the dbp - * array. There are nwp indices in the dwp array. - */ - - unsigned nbp; - unsigned nwp; - struct dpm_bp *dbp; - struct dpm_wp *dwp; - - /** Address of the instruction which triggered a watchpoint. */ - uint32_t wp_pc; - - /** Recent value of DSCR. */ - uint32_t dscr; - - /* FIXME -- read/write DCSR methods and symbols */ -}; - -int arm_dpm_setup(struct arm_dpm *dpm); -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); - -/* DSCR bits; see ARMv7a arch spec section C10.3.1. - * Not all v7 bits are valid in v6. - */ -#define DSCR_CORE_HALTED (0x1 << 0) -#define DSCR_CORE_RESTARTED (0x1 << 1) -#define DSCR_ENTRY_MASK (0xF << 2) -#define DSCR_STICKY_ABORT_PRECISE (0x1 << 6) -#define DSCR_STICKY_ABORT_IMPRECISE (0x1 << 7) -#define DSCR_STICKY_UNDEFINED (0x1 << 8) -#define DSCR_DBG_NOPWRDWN (0x1 << 9) /* v6 only */ -#define DSCR_DBG_ACK (0x1 << 10) -#define DSCR_INT_DIS (0x1 << 11) -#define DSCR_CP14_USR_COMMS (0x1 << 12) -#define DSCR_ITR_EN (0x1 << 13) -#define DSCR_HALT_DBG_MODE (0x1 << 14) -#define DSCR_MON_DBG_MODE (0x1 << 15) -#define DSCR_SEC_PRIV_INVASV_DIS (0x1 << 16) -#define DSCR_SEC_PRIV_NINVASV_DIS (0x1 << 17) -#define DSCR_NON_SECURE (0x1 << 18) -#define DSCR_DSCRD_IMPRECISE_ABORT (0x1 << 19) -#define DSCR_EXT_DCC_MASK (0x3 << 20) /* DTR mode */ /* bits 22, 23 are reserved */ -#define DSCR_INSTR_COMP (0x1 << 24) -#define DSCR_PIPE_ADVANCE (0x1 << 25) -#define DSCR_DTRTX_FULL_LATCHED (0x1 << 26) -#define DSCR_DTRRX_FULL_LATCHED (0x1 << 27) /* bit 28 is reserved */ -#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)) - - -/* 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) - -/* DTR modes */ -#define DSCR_EXT_DCC_NON_BLOCKING (0x0 << 20) -#define DSCR_EXT_DCC_STALL_MODE (0x1 << 20) -#define DSCR_EXT_DCC_FAST_MODE (0x2 << 20) /* bits 22, 23 are reserved */ - - - - - -/* DRCR (debug run control register) bits */ -#define DRCR_HALT (1 << 0) -#define DRCR_RESTART (1 << 1) -#define DRCR_CLEAR_EXCEPTIONS (1 << 2) - -void arm_dpm_report_dscr(struct arm_dpm *dpm, uint32_t dcsr); - -#endif /* OPENOCD_TARGET_ARM_DPM_H */ diff --git a/src/target/arm_jtag.c b/src/target/arm_jtag.c deleted file mode 100644 index 9b73d4ea8..000000000 --- a/src/target/arm_jtag.c +++ /dev/null @@ -1,94 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * Copyright (C) 2007,2008 Øyvind Harboe * - * oyvind.harboe@zylin.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "arm_jtag.h" - -#if 0 -#define _ARM_JTAG_SCAN_N_CHECK_ -#endif - -int arm_jtag_set_instr_inner(struct jtag_tap *tap, - uint32_t new_instr, void *no_verify_capture, tap_state_t end_state) -{ - struct scan_field field; - uint8_t t[4]; - - field.num_bits = tap->ir_length; - field.out_value = t; - buf_set_u32(t, 0, field.num_bits, new_instr); - field.in_value = NULL; - - if (no_verify_capture == NULL) - jtag_add_ir_scan(tap, &field, end_state); - else { - /* FIX!!!! this is a kludge!!! arm926ejs.c should reimplement this arm_jtag_set_instr to - * have special verification code. - */ - jtag_add_ir_scan_noverify(tap, &field, end_state); - } - - return ERROR_OK; -} - -int arm_jtag_scann_inner(struct arm_jtag *jtag_info, uint32_t new_scan_chain, tap_state_t end_state) -{ - int retval = ERROR_OK; - - uint8_t out_value[4]; - buf_set_u32(out_value, 0, jtag_info->scann_size, new_scan_chain); - struct scan_field field = { .num_bits = jtag_info->scann_size, .out_value = out_value, }; - - retval = arm_jtag_set_instr(jtag_info->tap, jtag_info->scann_instr, NULL, end_state); - if (retval != ERROR_OK) - return retval; - - jtag_add_dr_scan(jtag_info->tap, - 1, - &field, - end_state); - - jtag_info->cur_scan_chain = new_scan_chain; - - return retval; -} - -static int arm_jtag_reset_callback(enum jtag_event event, void *priv) -{ - struct arm_jtag *jtag_info = priv; - - if (event == JTAG_TRST_ASSERTED) - jtag_info->cur_scan_chain = 0; - - return ERROR_OK; -} - -int arm_jtag_setup_connection(struct arm_jtag *jtag_info) -{ - jtag_info->scann_instr = 0x2; - jtag_info->cur_scan_chain = 0; - jtag_info->intest_instr = 0xc; - - return jtag_register_event_callback(arm_jtag_reset_callback, jtag_info); -} diff --git a/src/target/arm_jtag.h b/src/target/arm_jtag.h deleted file mode 100644 index bb92abb84..000000000 --- a/src/target/arm_jtag.h +++ /dev/null @@ -1,78 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * Copyright (C) 2007-2010 Øyvind Harboe * - * oyvind.harboe@zylin.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifndef OPENOCD_TARGET_ARM_JTAG_H -#define OPENOCD_TARGET_ARM_JTAG_H - -#include - -struct arm_jtag { - struct jtag_tap *tap; - - uint32_t scann_size; - uint32_t scann_instr; - uint32_t cur_scan_chain; - - uint32_t intest_instr; -}; - -int arm_jtag_set_instr_inner(struct jtag_tap *tap, uint32_t new_instr, - void *no_verify_capture, - tap_state_t end_state); - -static inline int arm_jtag_set_instr(struct jtag_tap *tap, - uint32_t new_instr, void *no_verify_capture, tap_state_t end_state) -{ - /* inline most common code path */ - if (buf_get_u32(tap->cur_instr, 0, tap->ir_length) != new_instr) - return arm_jtag_set_instr_inner(tap, new_instr, no_verify_capture, end_state); - - return ERROR_OK; - -} - -int arm_jtag_scann_inner(struct arm_jtag *jtag_info, uint32_t new_scan_chain, tap_state_t end_state); -static inline int arm_jtag_scann(struct arm_jtag *jtag_info, uint32_t new_scan_chain, tap_state_t end_state) -{ - /* inline most common code path */ - int retval = ERROR_OK; - if (jtag_info->cur_scan_chain != new_scan_chain) - return arm_jtag_scann_inner(jtag_info, new_scan_chain, end_state); - - return retval; -} - -int arm_jtag_setup_connection(struct arm_jtag *jtag_info); - -/* use this as a static so we can inline it in -O3 and refer to it via a pointer */ -static inline void arm7flip32(jtag_callback_data_t arg) -{ - uint8_t *in = (uint8_t *)arg; - *((uint32_t *)arg) = flip_u32(le_to_h_u32(in), 32); -} - -static inline void arm_le_to_h_u32(jtag_callback_data_t arg) -{ - uint8_t *in = (uint8_t *)arg; - *((uint32_t *)arg) = le_to_h_u32(in); -} - -#endif /* OPENOCD_TARGET_ARM_JTAG_H */ diff --git a/src/target/arm_opcodes.h b/src/target/arm_opcodes.h deleted file mode 100644 index a53fee71e..000000000 --- a/src/target/arm_opcodes.h +++ /dev/null @@ -1,313 +0,0 @@ -/* - * Copyright (C) 2005 by Dominic Rath - * Dominic.Rath@gmx.de - * - * Copyright (C) 2006 by Magnus Lundin - * lundin@mlu.mine.nu - * - * Copyright (C) 2008 by Spencer Oliver - * spen@spen-soft.co.uk - * - * Copyright (C) 2009 by Øyvind Harboe - * oyvind.harboe@zylin.com - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef OPENOCD_TARGET_ARM_OPCODES_H -#define OPENOCD_TARGET_ARM_OPCODES_H - -/** - * @file - * Macros used to generate various ARM or Thumb opcodes. - */ - -/* ARM mode instructions */ - -/* Store multiple increment after - * Rn: base register - * List: for each bit in list: store register - * S: in priviledged mode: store user-mode registers - * W = 1: update the base register. W = 0: leave the base register untouched - */ -#define ARMV4_5_STMIA(Rn, List, S, W) \ - (0xe8800000 | ((S) << 22) | ((W) << 21) | ((Rn) << 16) | (List)) - -/* Load multiple increment after - * Rn: base register - * List: for each bit in list: store register - * S: in priviledged mode: store user-mode registers - * W = 1: update the base register. W = 0: leave the base register untouched - */ -#define ARMV4_5_LDMIA(Rn, List, S, W) \ - (0xe8900000 | ((S) << 22) | ((W) << 21) | ((Rn) << 16) | (List)) - -/* MOV r8, r8 */ -#define ARMV4_5_NOP (0xe1a08008) - -/* Move PSR to general purpose register - * R = 1: SPSR R = 0: CPSR - * Rn: target register - */ -#define ARMV4_5_MRS(Rn, R) (0xe10f0000 | ((R) << 22) | ((Rn) << 12)) - -/* Store register - * Rd: register to store - * Rn: base register - */ -#define ARMV4_5_STR(Rd, Rn) (0xe5800000 | ((Rd) << 12) | ((Rn) << 16)) - -/* Load register - * Rd: register to load - * Rn: base register - */ -#define ARMV4_5_LDR(Rd, Rn) (0xe5900000 | ((Rd) << 12) | ((Rn) << 16)) - -/* Move general purpose register to PSR - * R = 1: SPSR R = 0: CPSR - * Field: Field mask - * 1: control field 2: extension field 4: status field 8: flags field - * Rm: source register - */ -#define ARMV4_5_MSR_GP(Rm, Field, R) \ - (0xe120f000 | (Rm) | ((Field) << 16) | ((R) << 22)) -#define ARMV4_5_MSR_IM(Im, Rotate, Field, R) \ - (0xe320f000 | (Im) | ((Rotate) << 8) | ((Field) << 16) | ((R) << 22)) - -/* Load Register Word Immediate Post-Index - * Rd: register to load - * Rn: base register - */ -#define ARMV4_5_LDRW_IP(Rd, Rn) (0xe4900004 | ((Rd) << 12) | ((Rn) << 16)) - -/* Load Register Halfword Immediate Post-Index - * Rd: register to load - * Rn: base register - */ -#define ARMV4_5_LDRH_IP(Rd, Rn) (0xe0d000b2 | ((Rd) << 12) | ((Rn) << 16)) - -/* Load Register Byte Immediate Post-Index - * Rd: register to load - * Rn: base register - */ -#define ARMV4_5_LDRB_IP(Rd, Rn) (0xe4d00001 | ((Rd) << 12) | ((Rn) << 16)) - -/* Store register Word Immediate Post-Index - * Rd: register to store - * Rn: base register - */ -#define ARMV4_5_STRW_IP(Rd, Rn) (0xe4800004 | ((Rd) << 12) | ((Rn) << 16)) - -/* Store register Halfword Immediate Post-Index - * Rd: register to store - * Rn: base register - */ -#define ARMV4_5_STRH_IP(Rd, Rn) (0xe0c000b2 | ((Rd) << 12) | ((Rn) << 16)) - -/* Store register Byte Immediate Post-Index - * Rd: register to store - * Rn: base register - */ -#define ARMV4_5_STRB_IP(Rd, Rn) (0xe4c00001 | ((Rd) << 12) | ((Rn) << 16)) - -/* Branch (and Link) - * Im: Branch target (left-shifted by 2 bits, added to PC) - * L: 1: branch and link 0: branch only - */ -#define ARMV4_5_B(Im, L) (0xea000000 | (Im) | ((L) << 24)) - -/* Branch and exchange (ARM state) - * Rm: register holding branch target address - */ -#define ARMV4_5_BX(Rm) (0xe12fff10 | (Rm)) - -/* Store data from coprocessor to consecutive memory - * See Armv7-A arch doc section A8.6.187 - * P: 1=index mode (offset from Rn) - * U: 1=add, 0=subtract Rn address with imm - * D: Opcode D encoding - * W: write back the offset start address to the Rn register - * CP: Coprocessor number (4 bits) - * CRd: Coprocessor source register (4 bits) - * Rn: Base register for memory address (4 bits) - * imm: Immediate value (0 - 1020, must be divisible by 4) - */ -#define ARMV4_5_STC(P, U, D, W, CP, CRd, Rn, imm) \ - (0xec000000 | ((P) << 24) | ((U) << 23) | ((D) << 22) | \ - ((W) << 21) | ((Rn) << 16) | ((CRd) << 12) | ((CP) << 8) | ((imm)>>2)) - -/* Loads data from consecutive memory to coprocessor - * See Armv7-A arch doc section A8.6.51 - * P: 1=index mode (offset from Rn) - * U: 1=add, 0=subtract Rn address with imm - * D: Opcode D encoding - * W: write back the offset start address to the Rn register - * CP: Coprocessor number (4 bits) - * CRd: Coprocessor dest register (4 bits) - * Rn: Base register for memory address (4 bits) - * imm: Immediate value (0 - 1020, must be divisible by 4) - */ -#define ARMV4_5_LDC(P, U, D, W, CP, CRd, Rn, imm) \ - (0xec100000 | ((P) << 24) | ((U) << 23) | ((D) << 22) | \ - ((W) << 21) | ((Rn) << 16) | ((CRd) << 12) | ((CP) << 8) | ((imm) >> 2)) - -/* Move to ARM register from coprocessor - * CP: Coprocessor number - * op1: Coprocessor opcode - * Rd: destination register - * CRn: first coprocessor operand - * CRm: second coprocessor operand - * op2: Second coprocessor opcode - */ -#define ARMV4_5_MRC(CP, op1, Rd, CRn, CRm, op2) \ - (0xee100010 | (CRm) | ((op2) << 5) | ((CP) << 8) \ - | ((Rd) << 12) | ((CRn) << 16) | ((op1) << 21)) - -/* Move to coprocessor from ARM register - * CP: Coprocessor number - * op1: Coprocessor opcode - * Rd: destination register - * CRn: first coprocessor operand - * CRm: second coprocessor operand - * op2: Second coprocessor opcode - */ -#define ARMV4_5_MCR(CP, op1, Rd, CRn, CRm, op2) \ - (0xee000010 | (CRm) | ((op2) << 5) | ((CP) << 8) \ - | ((Rd) << 12) | ((CRn) << 16) | ((op1) << 21)) - -/* Breakpoint instruction (ARMv5) - * Im: 16-bit immediate - */ -#define ARMV5_BKPT(Im) (0xe1200070 | ((Im & 0xfff0) << 8) | (Im & 0xf)) - - -/* Thumb mode instructions - * - * NOTE: these 16-bit opcodes fill both halves of a word with the same - * value. The reason for this is that when we need to execute Thumb - * opcodes on ARM7/ARM9 cores (to switch to ARM state on debug entry), - * we must shift 32 bits to the bus using scan chain 1 ... if we write - * both halves, we don't need to track which half matters. On ARMv6 and - * ARMv7 we don't execute Thumb instructions in debug mode; the ITR - * register does not accept Thumb (or Thumb2) opcodes. - */ - -/* Store register (Thumb mode) - * Rd: source register - * Rn: base register - */ -#define ARMV4_5_T_STR(Rd, Rn) \ - ((0x6000 | (Rd) | ((Rn) << 3)) | \ - ((0x6000 | (Rd) | ((Rn) << 3)) << 16)) - -/* Load register (Thumb state) - * Rd: destination register - * Rn: base register - */ -#define ARMV4_5_T_LDR(Rd, Rn) \ - ((0x6800 | ((Rn) << 3) | (Rd)) \ - | ((0x6800 | ((Rn) << 3) | (Rd)) << 16)) - -/* Load multiple (Thumb state) - * Rn: base register - * List: for each bit in list: store register - */ -#define ARMV4_5_T_LDMIA(Rn, List) \ - ((0xc800 | ((Rn) << 8) | (List)) \ - | ((0xc800 | ((Rn) << 8) | (List)) << 16)) - -/* Load register with PC relative addressing - * Rd: register to load - */ -#define ARMV4_5_T_LDR_PCREL(Rd) \ - ((0x4800 | ((Rd) << 8)) \ - | ((0x4800 | ((Rd) << 8)) << 16)) - -/* Move hi register (Thumb mode) - * Rd: destination register - * Rm: source register - */ -#define ARMV4_5_T_MOV(Rd, Rm) \ - ((0x4600 | ((Rd) & 0x7) | (((Rd) & 0x8) << 4) | \ - (((Rm) & 0x7) << 3) | (((Rm) & 0x8) << 3)) \ - | ((0x4600 | ((Rd) & 0x7) | (((Rd) & 0x8) << 4) | \ - (((Rm) & 0x7) << 3) | (((Rm) & 0x8) << 3)) << 16)) - -/* No operation (Thumb mode) - * NOTE: this is "MOV r8, r8" ... Thumb2 adds two - * architected NOPs, 16-bit and 32-bit. - */ -#define ARMV4_5_T_NOP (0x46c0 | (0x46c0 << 16)) - -/* Move immediate to register (Thumb state) - * Rd: destination register - * Im: 8-bit immediate value - */ -#define ARMV4_5_T_MOV_IM(Rd, Im) \ - ((0x2000 | ((Rd) << 8) | (Im)) \ - | ((0x2000 | ((Rd) << 8) | (Im)) << 16)) - -/* Branch and Exchange - * Rm: register containing branch target - */ -#define ARMV4_5_T_BX(Rm) \ - ((0x4700 | ((Rm) << 3)) \ - | ((0x4700 | ((Rm) << 3)) << 16)) - -/* Branch (Thumb state) - * Imm: Branch target - */ -#define ARMV4_5_T_B(Imm) \ - ((0xe000 | (Imm)) \ - | ((0xe000 | (Imm)) << 16)) - -/* Breakpoint instruction (ARMv5) (Thumb state) - * Im: 8-bit immediate - */ -#define ARMV5_T_BKPT(Im) \ - ((0xbe00 | (Im)) \ - | ((0xbe00 | (Im)) << 16)) - -/* Move to Register from Special Register - * 32 bit Thumb2 instruction - * Rd: destination register - * SYSm: source special register - */ -#define ARM_T2_MRS(Rd, SYSm) \ - ((0xF3EF) | ((0x8000 | (Rd << 8) | SYSm) << 16)) - -/* Move from Register from Special Register - * 32 bit Thumb2 instruction - * Rd: source register - * SYSm: destination special register - */ -#define ARM_T2_MSR(SYSm, Rn) \ - ((0xF380 | (Rn << 8)) | ((0x8800 | SYSm) << 16)) - -/* Change Processor State. - * 16 bit Thumb2 instruction - * Rd: source register - * IF: A_FLAG and/or I_FLAG and/or F_FLAG - */ -#define A_FLAG 4 -#define I_FLAG 2 -#define F_FLAG 1 -#define ARM_T2_CPSID(IF) \ - ((0xB660 | (1 << 8) | ((IF)&0x3)) \ - | ((0xB660 | (1 << 8) | ((IF)&0x3)) << 16)) -#define ARM_T2_CPSIE(IF) \ - ((0xB660 | (0 << 8) | ((IF)&0x3)) \ - | ((0xB660 | (0 << 8) | ((IF)&0x3)) << 16)) - -#endif /* OPENOCD_TARGET_ARM_OPCODES_H */ diff --git a/src/target/arm_semihosting.c b/src/target/arm_semihosting.c deleted file mode 100644 index 2fd658014..000000000 --- a/src/target/arm_semihosting.c +++ /dev/null @@ -1,556 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2009 by Marvell Technology Group Ltd. * - * Written by Nicolas Pitre * - * * - * Copyright (C) 2010 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -/** - * @file - * Hold ARM semihosting support. - * - * Semihosting enables code running on an ARM target to use the I/O - * facilities on the host computer. The target application must be linked - * against a library that forwards operation requests by using the SVC - * instruction trapped at the Supervisor Call vector by the debugger. - * Details can be found in chapter 8 of DUI0203I_rvct_developer_guide.pdf - * from ARM Ltd. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "arm.h" -#include "armv4_5.h" -#include "arm7_9_common.h" -#include "armv7m.h" -#include "cortex_m.h" -#include "register.h" -#include "arm_semihosting.h" -#include -#include -#include - -static const int open_modeflags[12] = { - O_RDONLY, - O_RDONLY | O_BINARY, - O_RDWR, - O_RDWR | O_BINARY, - O_WRONLY | O_CREAT | O_TRUNC, - O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, - O_RDWR | O_CREAT | O_TRUNC, - O_RDWR | O_CREAT | O_TRUNC | O_BINARY, - O_WRONLY | O_CREAT | O_APPEND, - O_WRONLY | O_CREAT | O_APPEND | O_BINARY, - O_RDWR | O_CREAT | O_APPEND, - O_RDWR | O_CREAT | O_APPEND | O_BINARY -}; - -static int do_semihosting(struct target *target) -{ - struct arm *arm = target_to_arm(target); - 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; - - /* - * TODO: lots of security issues are not considered yet, such as: - * - no validation on target provided file descriptors - * - 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. - */ - switch (r0) { - case 0x01: /* SYS_OPEN */ - retval = target_read_memory(target, r1, 4, 3, params); - if (retval != ERROR_OK) - return retval; - else { - 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); - } - arm->semihosting_errno = errno; - } else { - result = -1; - arm->semihosting_errno = EINVAL; - } - } - break; - - case 0x02: /* SYS_CLOSE */ - 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); - result = close(fd); - arm->semihosting_errno = errno; - } - break; - - case 0x03: /* SYS_WRITEC */ - { - unsigned char c; - retval = target_read_memory(target, r1, 1, 1, &c); - if (retval != ERROR_OK) - return retval; - putchar(c); - 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; - break; - - case 0x05: /* SYS_WRITE */ - retval = target_read_memory(target, r1, 4, 3, params); - if (retval != ERROR_OK) - return retval; - else { - 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; - } else { - retval = target_read_buffer(target, a, l, buf); - if (retval != ERROR_OK) { - free(buf); - return retval; - } - result = write(fd, buf, l); - arm->semihosting_errno = errno; - if (result >= 0) - result = l - result; - free(buf); - } - } - break; - - case 0x06: /* SYS_READ */ - retval = target_read_memory(target, r1, 4, 3, params); - if (retval != ERROR_OK) - return retval; - else { - 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; - } 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; - } - result = l - result; - } - free(buf); - } - } - break; - - case 0x07: /* SYS_READC */ - 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); - 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)); - break; - - case 0x0a: /* SYS_SEEK */ - retval = target_read_memory(target, r1, 4, 2, params); - if (retval != ERROR_OK) - return retval; - 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; - } - break; - - case 0x0c: /* SYS_FLEN */ - 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_errno = errno; - result = -1; - break; - } - result = buf.st_size; - } - break; - - case 0x0e: /* SYS_REMOVE */ - retval = target_read_memory(target, r1, 4, 2, params); - if (retval != ERROR_OK) - return retval; - 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; - } else { - result = -1; - arm->semihosting_errno = EINVAL; - } - } - break; - - case 0x0f: /* SYS_RENAME */ - retval = target_read_memory(target, r1, 4, 4, params); - if (retval != ERROR_OK) - return retval; - else { - uint32_t a1 = target_buffer_get_u32(target, params+0); - 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; - } else { - result = -1; - arm->semihosting_errno = EINVAL; - } - } - break; - - case 0x11: /* SYS_TIME */ - result = time(NULL); - break; - - case 0x13: /* SYS_ERRNO */ - result = arm->semihosting_errno; - break; - - case 0x15: /* SYS_GET_CMDLINE */ - retval = target_read_memory(target, r1, 4, 2, params); - if (retval != ERROR_OK) - return retval; - else { - uint32_t a = target_buffer_get_u32(target, params+0); - uint32_t l = target_buffer_get_u32(target, params+4); - char *arg = "foobar"; - uint32_t s = strlen(arg) + 1; - if (l < s) - result = -1; - else { - retval = target_write_buffer(target, a, s, (uint8_t *)arg); - if (retval != ERROR_OK) - return retval; - result = 0; - } - } - break; - - case 0x16: /* SYS_HEAPINFO */ - retval = target_read_memory(target, r1, 4, 1, params); - if (retval != ERROR_OK) - return retval; - else { - uint32_t a = target_buffer_get_u32(target, params+0); - /* tell the remote we have no idea */ - memset(params, 0, 4*4); - retval = target_write_memory(target, a, 4, 4, params); - if (retval != ERROR_OK) - return retval; - result = 0; - } - break; - - case 0x18: /* angel_SWIreason_ReportException */ - switch (r1) { - case 0x20026: /* ADP_Stopped_ApplicationExit */ - fprintf(stderr, "semihosting: *** application exited ***\n"); - break; - case 0x20000: /* ADP_Stopped_BranchThroughZero */ - case 0x20001: /* ADP_Stopped_UndefinedInstr */ - case 0x20002: /* ADP_Stopped_SoftwareInterrupt */ - case 0x20003: /* ADP_Stopped_PrefetchAbort */ - case 0x20004: /* ADP_Stopped_DataAbort */ - case 0x20005: /* ADP_Stopped_AddressException */ - case 0x20006: /* ADP_Stopped_IRQ */ - case 0x20007: /* ADP_Stopped_FIQ */ - case 0x20020: /* ADP_Stopped_BreakPoint */ - case 0x20021: /* ADP_Stopped_WatchPoint */ - case 0x20022: /* ADP_Stopped_StepComplete */ - case 0x20023: /* ADP_Stopped_RunTimeErrorUnknown */ - case 0x20024: /* ADP_Stopped_InternalError */ - case 0x20025: /* ADP_Stopped_UserInterruption */ - case 0x20027: /* ADP_Stopped_StackOverflow */ - case 0x20028: /* ADP_Stopped_DivisionByZero */ - case 0x20029: /* ADP_Stopped_OSSpecific */ - default: - fprintf(stderr, "semihosting: exception %#x\n", - (unsigned) r1); - } - return target_call_event_callbacks(target, TARGET_EVENT_HALTED); - - case 0x12: /* SYS_SYSTEM */ - /* Provide SYS_SYSTEM functionality. Uses the - * libc system command, there may be a reason *NOT* - * to use this, but as I can't think of one, I - * implemented it this way. - */ - retval = target_read_memory(target, r1, 4, 2, params); - if (retval != ERROR_OK) - return retval; - 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; - } 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); - } - } - break; - case 0x0d: /* SYS_TMPNAM */ - case 0x10: /* SYS_CLOCK */ - case 0x17: /* angel_SWIreason_EnterSVC */ - case 0x30: /* SYS_ELAPSED */ - case 0x31: /* SYS_TICKFREQ */ - default: - fprintf(stderr, "semihosting: unsupported call %#x\n", - (unsigned) r0); - result = -1; - arm->semihosting_errno = ENOTSUP; - } - - /* resume execution to the original mode */ - - /* REVISIT this looks wrong ... ARM11 and Cortex-A8 - * should work this way at least sometimes. - */ - if (is_arm7_9(target_to_arm7_9(target))) { - uint32_t spsr; - - /* 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; - - /* 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, result); - arm->core_cache->reg_list[0].dirty = 1; - } - - return target_resume(target, 1, 0, 0, 0); -} - -/** - * Checks for and processes an ARM semihosting request. This is meant - * to be called when the target is stopped due to a debug mode entry. - * If the value 0 is returned then there was nothing to process. A non-zero - * return value signifies that a request was processed and the target resumed, - * or an error was encountered, in which case the caller must return - * immediately. - * - * @param target Pointer to the ARM target to process. This target must - * not represent an ARMv6-M or ARMv7-M processor. - * @param retval Pointer to a location where the return code will be stored - * @return non-zero value if a request was processed or an error encountered - */ -int arm_semihosting(struct target *target, int *retval) -{ - struct arm *arm = target_to_arm(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 (arm->core_mode != ARM_MODE_SVC) - return 0; - - /* 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) - return 0; - - r = arm_reg_current(arm, 14); - lr = buf_get_u32(r->value, 0, 32); - - /* Core-specific code should make sure SPSR is retrieved - * when the above checks pass... - */ - if (!arm->spsr->valid) { - LOG_ERROR("SPSR not valid!"); - *retval = ERROR_FAIL; - return 1; - } - - spsr = buf_get_u32(arm->spsr->value, 0, 32); - - /* check instruction that triggered this trap */ - if (spsr & (1 << 5)) { - /* was in Thumb (or ThumbEE) mode */ - uint8_t insn_buf[2]; - uint16_t insn; - - *retval = target_read_memory(target, lr-2, 2, 1, insn_buf); - if (*retval != ERROR_OK) - return 1; - insn = target_buffer_get_u16(target, insn_buf); - - /* SVC 0xab */ - if (insn != 0xDFAB) - return 0; - } else if (spsr & (1 << 24)) { - /* was in Jazelle mode */ - return 0; - } else { - /* was in ARM mode */ - uint8_t insn_buf[4]; - uint32_t insn; - - *retval = target_read_memory(target, lr-4, 4, 1, insn_buf); - if (*retval != ERROR_OK) - return 1; - insn = target_buffer_get_u32(target, insn_buf); - - /* SVC 0x123456 */ - if (insn != 0xEF123456) - return 0; - } - } else if (is_armv7m(target_to_armv7m(target))) { - uint16_t insn; - - if (target->debug_reason != DBG_REASON_BREAKPOINT) - return 0; - - r = arm->pc; - pc = buf_get_u32(r->value, 0, 32); - - pc &= ~1; - *retval = target_read_u16(target, pc, &insn); - if (*retval != ERROR_OK) - return 1; - - /* bkpt 0xAB */ - if (insn != 0xBEAB) - return 0; - } else { - LOG_ERROR("Unsupported semi-hosting Target"); - return 0; - } - - *retval = do_semihosting(target); - return 1; -} diff --git a/src/target/arm_semihosting.h b/src/target/arm_semihosting.h deleted file mode 100644 index 7b5c0b2de..000000000 --- a/src/target/arm_semihosting.h +++ /dev/null @@ -1,24 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2009 by Marvell Technology Group Ltd. * - * Written by Nicolas Pitre * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 OPENOCD_TARGET_ARM_SEMIHOSTING_H -#define OPENOCD_TARGET_ARM_SEMIHOSTING_H - -int arm_semihosting(struct target *target, int *retval); - -#endif /* OPENOCD_TARGET_ARM_SEMIHOSTING_H */ diff --git a/src/target/arm_simulator.c b/src/target/arm_simulator.c deleted file mode 100644 index 245e108ac..000000000 --- a/src/target/arm_simulator.c +++ /dev/null @@ -1,722 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2006 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * Copyright (C) 2008 by Hongtao Zheng * - * hontor@126.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "arm.h" -#include "armv4_5.h" -#include "arm_disassembler.h" -#include "arm_simulator.h" -#include -#include "register.h" -#include - -static uint32_t arm_shift(uint8_t shift, uint32_t Rm, - uint32_t shift_amount, uint8_t *carry) -{ - uint32_t return_value = 0; - shift_amount &= 0xff; - - if (shift == 0x0) { /* LSL */ - if ((shift_amount > 0) && (shift_amount <= 32)) { - return_value = Rm << shift_amount; - *carry = Rm >> (32 - shift_amount); - } else if (shift_amount > 32) { - return_value = 0x0; - *carry = 0x0; - } else /* (shift_amount == 0) */ - return_value = Rm; - } else if (shift == 0x1) { /* LSR */ - if ((shift_amount > 0) && (shift_amount <= 32)) { - return_value = Rm >> shift_amount; - *carry = (Rm >> (shift_amount - 1)) & 1; - } else if (shift_amount > 32) { - return_value = 0x0; - *carry = 0x0; - } else /* (shift_amount == 0) */ - return_value = Rm; - } else if (shift == 0x2) { /* ASR */ - if ((shift_amount > 0) && (shift_amount <= 32)) { - /* C right shifts of unsigned values are guaranteed to - * be logical (shift in zeroes); simulate an arithmetic - * shift (shift in signed-bit) by adding the sign bit - * manually - */ - return_value = Rm >> shift_amount; - if (Rm & 0x80000000) - return_value |= 0xffffffff << (32 - shift_amount); - } else if (shift_amount > 32) { - if (Rm & 0x80000000) { - return_value = 0xffffffff; - *carry = 0x1; - } else { - return_value = 0x0; - *carry = 0x0; - } - } else /* (shift_amount == 0) */ - return_value = Rm; - } else if (shift == 0x3) { /* ROR */ - if (shift_amount == 0) - return_value = Rm; - else { - shift_amount = shift_amount % 32; - return_value = (Rm >> shift_amount) | (Rm << (32 - shift_amount)); - *carry = (return_value >> 31) & 0x1; - } - } else if (shift == 0x4) { /* RRX */ - return_value = Rm >> 1; - if (*carry) - Rm |= 0x80000000; - *carry = Rm & 0x1; - } - - return return_value; -} - - -static uint32_t arm_shifter_operand(struct arm_sim_interface *sim, - int variant, union arm_shifter_operand shifter_operand, - uint8_t *shifter_carry_out) -{ - uint32_t return_value; - int instruction_size; - - if (sim->get_state(sim) == ARM_STATE_ARM) - instruction_size = 4; - else - instruction_size = 2; - - *shifter_carry_out = sim->get_cpsr(sim, 29, 1); - - if (variant == 0) /* 32-bit immediate */ - return_value = shifter_operand.immediate.immediate; - else if (variant == 1) {/* immediate shift */ - uint32_t Rm = sim->get_reg_mode(sim, shifter_operand.immediate_shift.Rm); - - /* adjust RM in case the PC is being read */ - if (shifter_operand.immediate_shift.Rm == 15) - Rm += 2 * instruction_size; - - return_value = arm_shift(shifter_operand.immediate_shift.shift, - Rm, shifter_operand.immediate_shift.shift_imm, - shifter_carry_out); - } else if (variant == 2) { /* register shift */ - uint32_t Rm = sim->get_reg_mode(sim, shifter_operand.register_shift.Rm); - uint32_t Rs = sim->get_reg_mode(sim, shifter_operand.register_shift.Rs); - - /* adjust RM in case the PC is being read */ - if (shifter_operand.register_shift.Rm == 15) - Rm += 2 * instruction_size; - - return_value = arm_shift(shifter_operand.immediate_shift.shift, - Rm, Rs, shifter_carry_out); - } else { - LOG_ERROR("BUG: shifter_operand.variant not 0, 1 or 2"); - return_value = 0xffffffff; - } - - return return_value; -} - -static int pass_condition(uint32_t cpsr, uint32_t opcode) -{ - switch ((opcode & 0xf0000000) >> 28) { - case 0x0: /* EQ */ - if (cpsr & 0x40000000) - return 1; - else - return 0; - case 0x1: /* NE */ - if (!(cpsr & 0x40000000)) - return 1; - else - return 0; - case 0x2: /* CS */ - if (cpsr & 0x20000000) - return 1; - else - return 0; - case 0x3: /* CC */ - if (!(cpsr & 0x20000000)) - return 1; - else - return 0; - case 0x4: /* MI */ - if (cpsr & 0x80000000) - return 1; - else - return 0; - case 0x5: /* PL */ - if (!(cpsr & 0x80000000)) - return 1; - else - return 0; - case 0x6: /* VS */ - if (cpsr & 0x10000000) - return 1; - else - return 0; - case 0x7: /* VC */ - if (!(cpsr & 0x10000000)) - return 1; - else - return 0; - case 0x8: /* HI */ - if ((cpsr & 0x20000000) && !(cpsr & 0x40000000)) - return 1; - else - return 0; - case 0x9: /* LS */ - if (!(cpsr & 0x20000000) || (cpsr & 0x40000000)) - return 1; - else - return 0; - case 0xa: /* GE */ - if (((cpsr & 0x80000000) && (cpsr & 0x10000000)) - || (!(cpsr & 0x80000000) && !(cpsr & 0x10000000))) - return 1; - else - return 0; - case 0xb: /* LT */ - if (((cpsr & 0x80000000) && !(cpsr & 0x10000000)) - || (!(cpsr & 0x80000000) && (cpsr & 0x10000000))) - return 1; - else - return 0; - case 0xc: /* GT */ - if (!(cpsr & 0x40000000) && - (((cpsr & 0x80000000) && (cpsr & 0x10000000)) - || (!(cpsr & 0x80000000) && !(cpsr & 0x10000000)))) - return 1; - else - return 0; - case 0xd: /* LE */ - if ((cpsr & 0x40000000) || - ((cpsr & 0x80000000) && !(cpsr & 0x10000000)) - || (!(cpsr & 0x80000000) && (cpsr & 0x10000000))) - return 1; - else - return 0; - case 0xe: - case 0xf: - return 1; - - } - - LOG_ERROR("BUG: should never get here"); - return 0; -} - -static int thumb_pass_branch_condition(uint32_t cpsr, uint16_t opcode) -{ - return pass_condition(cpsr, (opcode & 0x0f00) << 20); -} - -/* simulate a single step (if possible) - * if the dry_run_pc argument is provided, no state is changed, - * but the new pc is stored in the variable pointed at by the argument - */ -static int arm_simulate_step_core(struct target *target, - uint32_t *dry_run_pc, struct arm_sim_interface *sim) -{ - uint32_t current_pc = sim->get_reg(sim, 15); - struct arm_instruction instruction; - int instruction_size; - int retval = ERROR_OK; - - if (sim->get_state(sim) == ARM_STATE_ARM) { - uint32_t opcode; - - /* get current instruction, and identify it */ - retval = target_read_u32(target, current_pc, &opcode); - if (retval != ERROR_OK) - return retval; - retval = arm_evaluate_opcode(opcode, current_pc, &instruction); - if (retval != ERROR_OK) - return retval; - instruction_size = 4; - - /* check condition code (for all instructions) */ - if (!pass_condition(sim->get_cpsr(sim, 0, 32), opcode)) { - if (dry_run_pc) - *dry_run_pc = current_pc + instruction_size; - else - sim->set_reg(sim, 15, current_pc + instruction_size); - - return ERROR_OK; - } - } else { - uint16_t opcode; - - retval = target_read_u16(target, current_pc, &opcode); - if (retval != ERROR_OK) - return retval; - retval = thumb_evaluate_opcode(opcode, current_pc, &instruction); - if (retval != ERROR_OK) - return retval; - instruction_size = 2; - - /* check condition code (only for branch (1) instructions) */ - if ((opcode & 0xf000) == 0xd000 - && !thumb_pass_branch_condition( - sim->get_cpsr(sim, 0, 32), opcode)) { - if (dry_run_pc) - *dry_run_pc = current_pc + instruction_size; - else - sim->set_reg(sim, 15, current_pc + instruction_size); - - return ERROR_OK; - } - - /* Deal with 32-bit BL/BLX */ - if ((opcode & 0xf800) == 0xf000) { - uint32_t high = instruction.info.b_bl_bx_blx.target_address; - retval = target_read_u16(target, current_pc+2, &opcode); - if (retval != ERROR_OK) - return retval; - retval = thumb_evaluate_opcode(opcode, current_pc, &instruction); - if (retval != ERROR_OK) - return retval; - instruction.info.b_bl_bx_blx.target_address += high; - } - } - - /* examine instruction type */ - - /* branch instructions */ - if ((instruction.type >= ARM_B) && (instruction.type <= ARM_BLX)) { - uint32_t target_address; - - if (instruction.info.b_bl_bx_blx.reg_operand == -1) - target_address = instruction.info.b_bl_bx_blx.target_address; - else { - target_address = sim->get_reg_mode(sim, - instruction.info.b_bl_bx_blx.reg_operand); - if (instruction.info.b_bl_bx_blx.reg_operand == 15) - target_address += 2 * instruction_size; - } - - if (dry_run_pc) { - *dry_run_pc = target_address & ~1; - return ERROR_OK; - } else { - if (instruction.type == ARM_B) - sim->set_reg(sim, 15, target_address); - else if (instruction.type == ARM_BL) { - uint32_t old_pc = sim->get_reg(sim, 15); - int T = (sim->get_state(sim) == ARM_STATE_THUMB); - sim->set_reg_mode(sim, 14, old_pc + 4 + T); - sim->set_reg(sim, 15, target_address); - } else if (instruction.type == ARM_BX) { - if (target_address & 0x1) - sim->set_state(sim, ARM_STATE_THUMB); - else - sim->set_state(sim, ARM_STATE_ARM); - sim->set_reg(sim, 15, target_address & 0xfffffffe); - } else if (instruction.type == ARM_BLX) { - uint32_t old_pc = sim->get_reg(sim, 15); - int T = (sim->get_state(sim) == ARM_STATE_THUMB); - sim->set_reg_mode(sim, 14, old_pc + 4 + T); - - if (target_address & 0x1) - sim->set_state(sim, ARM_STATE_THUMB); - else - sim->set_state(sim, ARM_STATE_ARM); - sim->set_reg(sim, 15, target_address & 0xfffffffe); - } - - return ERROR_OK; - } - } - /* data processing instructions, except compare instructions (CMP, CMN, TST, TEQ) */ - else if (((instruction.type >= ARM_AND) && (instruction.type <= ARM_RSC)) - || ((instruction.type >= ARM_ORR) && (instruction.type <= ARM_MVN))) { - uint32_t Rd, Rn, shifter_operand; - uint8_t C = sim->get_cpsr(sim, 29, 1); - uint8_t carry_out; - - Rd = 0x0; - /* ARM_MOV and ARM_MVN does not use Rn */ - if ((instruction.type != ARM_MOV) && (instruction.type != ARM_MVN)) - Rn = sim->get_reg_mode(sim, instruction.info.data_proc.Rn); - else - Rn = 0; - - shifter_operand = arm_shifter_operand(sim, - instruction.info.data_proc.variant, - instruction.info.data_proc.shifter_operand, - &carry_out); - - /* adjust Rn in case the PC is being read */ - if (instruction.info.data_proc.Rn == 15) - Rn += 2 * instruction_size; - - if (instruction.type == ARM_AND) - Rd = Rn & shifter_operand; - else if (instruction.type == ARM_EOR) - Rd = Rn ^ shifter_operand; - else if (instruction.type == ARM_SUB) - Rd = Rn - shifter_operand; - else if (instruction.type == ARM_RSB) - Rd = shifter_operand - Rn; - else if (instruction.type == ARM_ADD) - Rd = Rn + shifter_operand; - else if (instruction.type == ARM_ADC) - Rd = Rn + shifter_operand + (C & 1); - else if (instruction.type == ARM_SBC) - Rd = Rn - shifter_operand - (C & 1) ? 0 : 1; - else if (instruction.type == ARM_RSC) - Rd = shifter_operand - Rn - (C & 1) ? 0 : 1; - else if (instruction.type == ARM_ORR) - Rd = Rn | shifter_operand; - else if (instruction.type == ARM_BIC) - Rd = Rn & ~(shifter_operand); - else if (instruction.type == ARM_MOV) - Rd = shifter_operand; - else if (instruction.type == ARM_MVN) - Rd = ~shifter_operand; - else - LOG_WARNING("unhandled instruction type"); - - if (dry_run_pc) { - if (instruction.info.data_proc.Rd == 15) - *dry_run_pc = Rd & ~1; - else - *dry_run_pc = current_pc + instruction_size; - - return ERROR_OK; - } else { - if (instruction.info.data_proc.Rd == 15) { - sim->set_reg_mode(sim, 15, Rd & ~1); - if (Rd & 1) - sim->set_state(sim, ARM_STATE_THUMB); - else - sim->set_state(sim, ARM_STATE_ARM); - return ERROR_OK; - } - sim->set_reg_mode(sim, instruction.info.data_proc.Rd, Rd); - LOG_WARNING("no updating of flags yet"); - } - } - /* compare instructions (CMP, CMN, TST, TEQ) */ - else if ((instruction.type >= ARM_TST) && (instruction.type <= ARM_CMN)) { - if (dry_run_pc) { - *dry_run_pc = current_pc + instruction_size; - return ERROR_OK; - } else - LOG_WARNING("no updating of flags yet"); - } - /* load register instructions */ - else if ((instruction.type >= ARM_LDR) && (instruction.type <= ARM_LDRSH)) { - uint32_t load_address = 0, modified_address = 0, load_value = 0; - uint32_t Rn = sim->get_reg_mode(sim, instruction.info.load_store.Rn); - - /* adjust Rn in case the PC is being read */ - if (instruction.info.load_store.Rn == 15) - Rn += 2 * instruction_size; - - if (instruction.info.load_store.offset_mode == 0) { - if (instruction.info.load_store.U) - modified_address = Rn + instruction.info.load_store.offset.offset; - else - modified_address = Rn - instruction.info.load_store.offset.offset; - } else if (instruction.info.load_store.offset_mode == 1) { - uint32_t offset; - uint32_t Rm = sim->get_reg_mode(sim, - instruction.info.load_store.offset.reg.Rm); - uint8_t shift = instruction.info.load_store.offset.reg.shift; - uint8_t shift_imm = instruction.info.load_store.offset.reg.shift_imm; - uint8_t carry = sim->get_cpsr(sim, 29, 1); - - offset = arm_shift(shift, Rm, shift_imm, &carry); - - if (instruction.info.load_store.U) - modified_address = Rn + offset; - else - modified_address = Rn - offset; - } else - LOG_ERROR("BUG: offset_mode neither 0 (offset) nor 1 (scaled register)"); - - if (instruction.info.load_store.index_mode == 0) { - /* offset mode - * we load from the modified address, but don't change - * the base address register - */ - load_address = modified_address; - modified_address = Rn; - } else if (instruction.info.load_store.index_mode == 1) { - /* pre-indexed mode - * we load from the modified address, and write it - * back to the base address register - */ - load_address = modified_address; - } else if (instruction.info.load_store.index_mode == 2) { - /* post-indexed mode - * we load from the unmodified address, and write the - * modified address back - */ - load_address = Rn; - } - - if ((!dry_run_pc) || (instruction.info.load_store.Rd == 15)) { - retval = target_read_u32(target, load_address, &load_value); - if (retval != ERROR_OK) - return retval; - } - - if (dry_run_pc) { - if (instruction.info.load_store.Rd == 15) - *dry_run_pc = load_value & ~1; - else - *dry_run_pc = current_pc + instruction_size; - return ERROR_OK; - } else { - if ((instruction.info.load_store.index_mode == 1) || - (instruction.info.load_store.index_mode == 2)) - sim->set_reg_mode(sim, - instruction.info.load_store.Rn, - modified_address); - - if (instruction.info.load_store.Rd == 15) { - sim->set_reg_mode(sim, 15, load_value & ~1); - if (load_value & 1) - sim->set_state(sim, ARM_STATE_THUMB); - else - sim->set_state(sim, ARM_STATE_ARM); - return ERROR_OK; - } - sim->set_reg_mode(sim, instruction.info.load_store.Rd, load_value); - } - } - /* load multiple instruction */ - else if (instruction.type == ARM_LDM) { - int i; - uint32_t Rn = sim->get_reg_mode(sim, instruction.info.load_store_multiple.Rn); - uint32_t load_values[16]; - int bits_set = 0; - - for (i = 0; i < 16; i++) { - if (instruction.info.load_store_multiple.register_list & (1 << i)) - bits_set++; - } - - switch (instruction.info.load_store_multiple.addressing_mode) { - case 0: /* Increment after */ - /* Rn = Rn; */ - break; - case 1: /* Increment before */ - Rn = Rn + 4; - break; - case 2: /* Decrement after */ - Rn = Rn - (bits_set * 4) + 4; - break; - case 3: /* Decrement before */ - Rn = Rn - (bits_set * 4); - break; - } - - for (i = 0; i < 16; i++) { - if (instruction.info.load_store_multiple.register_list & (1 << i)) { - if ((!dry_run_pc) || (i == 15)) - target_read_u32(target, Rn, &load_values[i]); - Rn += 4; - } - } - - if (dry_run_pc) { - if (instruction.info.load_store_multiple.register_list & 0x8000) { - *dry_run_pc = load_values[15] & ~1; - return ERROR_OK; - } - } else { - int update_cpsr = 0; - - if (instruction.info.load_store_multiple.S) { - if (instruction.info.load_store_multiple.register_list & 0x8000) - update_cpsr = 1; - } - - for (i = 0; i < 16; i++) { - if (instruction.info.load_store_multiple.register_list & (1 << i)) { - if (i == 15) { - uint32_t val = load_values[i]; - sim->set_reg_mode(sim, i, val & ~1); - if (val & 1) - sim->set_state(sim, ARM_STATE_THUMB); - else - sim->set_state(sim, ARM_STATE_ARM); - } else - sim->set_reg_mode(sim, i, load_values[i]); - } - } - - if (update_cpsr) { - uint32_t spsr = sim->get_reg_mode(sim, 16); - sim->set_reg(sim, ARMV4_5_CPSR, spsr); - } - - /* base register writeback */ - if (instruction.info.load_store_multiple.W) - sim->set_reg_mode(sim, instruction.info.load_store_multiple.Rn, Rn); - - - if (instruction.info.load_store_multiple.register_list & 0x8000) - return ERROR_OK; - } - } - /* store multiple instruction */ - else if (instruction.type == ARM_STM) { - int i; - - if (dry_run_pc) { - /* STM wont affect PC (advance by instruction size */ - } else { - uint32_t Rn = sim->get_reg_mode(sim, - instruction.info.load_store_multiple.Rn); - int bits_set = 0; - - for (i = 0; i < 16; i++) { - if (instruction.info.load_store_multiple.register_list & (1 << i)) - bits_set++; - } - - switch (instruction.info.load_store_multiple.addressing_mode) { - case 0: /* Increment after */ - /* Rn = Rn; */ - break; - case 1: /* Increment before */ - Rn = Rn + 4; - break; - case 2: /* Decrement after */ - Rn = Rn - (bits_set * 4) + 4; - break; - case 3: /* Decrement before */ - Rn = Rn - (bits_set * 4); - break; - } - - for (i = 0; i < 16; i++) { - if (instruction.info.load_store_multiple.register_list & (1 << i)) { - target_write_u32(target, Rn, sim->get_reg_mode(sim, i)); - Rn += 4; - } - } - - /* base register writeback */ - if (instruction.info.load_store_multiple.W) - sim->set_reg_mode(sim, - instruction.info.load_store_multiple.Rn, Rn); - - } - } else if (!dry_run_pc) { - /* the instruction wasn't handled, but we're supposed to simulate it - */ - LOG_ERROR("Unimplemented instruction, could not simulate it."); - return ERROR_FAIL; - } - - if (dry_run_pc) { - *dry_run_pc = current_pc + instruction_size; - return ERROR_OK; - } else { - sim->set_reg(sim, 15, current_pc + instruction_size); - return ERROR_OK; - } - -} - -static uint32_t armv4_5_get_reg(struct arm_sim_interface *sim, int reg) -{ - struct arm *arm = (struct arm *)sim->user_data; - - return buf_get_u32(arm->core_cache->reg_list[reg].value, 0, 32); -} - -static void armv4_5_set_reg(struct arm_sim_interface *sim, int reg, uint32_t value) -{ - struct arm *arm = (struct arm *)sim->user_data; - - buf_set_u32(arm->core_cache->reg_list[reg].value, 0, 32, value); -} - -static uint32_t armv4_5_get_reg_mode(struct arm_sim_interface *sim, int reg) -{ - struct arm *arm = (struct arm *)sim->user_data; - - return buf_get_u32(ARMV4_5_CORE_REG_MODE(arm->core_cache, - arm->core_mode, reg).value, 0, 32); -} - -static void armv4_5_set_reg_mode(struct arm_sim_interface *sim, int reg, uint32_t value) -{ - struct arm *arm = (struct arm *)sim->user_data; - - buf_set_u32(ARMV4_5_CORE_REG_MODE(arm->core_cache, - arm->core_mode, reg).value, 0, 32, value); -} - -static uint32_t armv4_5_get_cpsr(struct arm_sim_interface *sim, int pos, int bits) -{ - struct arm *arm = (struct arm *)sim->user_data; - - return buf_get_u32(arm->cpsr->value, pos, bits); -} - -static enum arm_state armv4_5_get_state(struct arm_sim_interface *sim) -{ - struct arm *arm = (struct arm *)sim->user_data; - - return arm->core_state; -} - -static void armv4_5_set_state(struct arm_sim_interface *sim, enum arm_state mode) -{ - struct arm *arm = (struct arm *)sim->user_data; - - arm->core_state = mode; -} - -static enum arm_mode armv4_5_get_mode(struct arm_sim_interface *sim) -{ - struct arm *arm = (struct arm *)sim->user_data; - - return arm->core_mode; -} - -int arm_simulate_step(struct target *target, uint32_t *dry_run_pc) -{ - struct arm *arm = target_to_arm(target); - struct arm_sim_interface sim; - - sim.user_data = arm; - sim.get_reg = &armv4_5_get_reg; - sim.set_reg = &armv4_5_set_reg; - sim.get_reg_mode = &armv4_5_get_reg_mode; - sim.set_reg_mode = &armv4_5_set_reg_mode; - sim.get_cpsr = &armv4_5_get_cpsr; - sim.get_mode = &armv4_5_get_mode; - sim.get_state = &armv4_5_get_state; - sim.set_state = &armv4_5_set_state; - - return arm_simulate_step_core(target, dry_run_pc, &sim); -} diff --git a/src/target/arm_simulator.h b/src/target/arm_simulator.h deleted file mode 100644 index 5bdbf562c..000000000 --- a/src/target/arm_simulator.h +++ /dev/null @@ -1,39 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2006 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifndef OPENOCD_TARGET_ARM_SIMULATOR_H -#define OPENOCD_TARGET_ARM_SIMULATOR_H - -struct target; - -struct arm_sim_interface { - void *user_data; - uint32_t (*get_reg)(struct arm_sim_interface *sim, int reg); - void (*set_reg)(struct arm_sim_interface *sim, int reg, uint32_t value); - uint32_t (*get_reg_mode)(struct arm_sim_interface *sim, int reg); - void (*set_reg_mode)(struct arm_sim_interface *sim, int reg, uint32_t value); - uint32_t (*get_cpsr)(struct arm_sim_interface *sim, int pos, int bits); - enum arm_state (*get_state)(struct arm_sim_interface *sim); - void (*set_state)(struct arm_sim_interface *sim, enum arm_state mode); - enum arm_mode (*get_mode)(struct arm_sim_interface *sim); -}; - -/* armv4_5 version */ -int arm_simulate_step(struct target *target, uint32_t *dry_run_pc); - -#endif /* OPENOCD_TARGET_ARM_SIMULATOR_H */ diff --git a/src/target/armv4_5.c b/src/target/armv4_5.c deleted file mode 100644 index e6ecfc884..000000000 --- a/src/target/armv4_5.c +++ /dev/null @@ -1,1612 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * Copyright (C) 2008 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * Copyright (C) 2008 by Oyvind Harboe * - * oyvind.harboe@zylin.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "arm.h" -#include "armv4_5.h" -#include "arm_jtag.h" -#include "breakpoints.h" -#include "arm_disassembler.h" -#include -#include "algorithm.h" -#include "register.h" - -/* offsets into armv4_5 core register cache */ -enum { -/* ARMV4_5_CPSR = 31, */ - ARMV4_5_SPSR_FIQ = 32, - ARMV4_5_SPSR_IRQ = 33, - ARMV4_5_SPSR_SVC = 34, - ARMV4_5_SPSR_ABT = 35, - ARMV4_5_SPSR_UND = 36, - ARM_SPSR_MON = 41, -}; - -static const uint8_t arm_usr_indices[17] = { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, ARMV4_5_CPSR, -}; - -static const uint8_t arm_fiq_indices[8] = { - 16, 17, 18, 19, 20, 21, 22, ARMV4_5_SPSR_FIQ, -}; - -static const uint8_t arm_irq_indices[3] = { - 23, 24, ARMV4_5_SPSR_IRQ, -}; - -static const uint8_t arm_svc_indices[3] = { - 25, 26, ARMV4_5_SPSR_SVC, -}; - -static const uint8_t arm_abt_indices[3] = { - 27, 28, ARMV4_5_SPSR_ABT, -}; - -static const uint8_t arm_und_indices[3] = { - 29, 30, ARMV4_5_SPSR_UND, -}; - -static const uint8_t arm_mon_indices[3] = { - 39, 40, ARM_SPSR_MON, -}; - -static const struct { - const char *name; - unsigned short psr; - /* For user and system modes, these list indices for all registers. - * otherwise they're just indices for the shadow registers and SPSR. - */ - unsigned short n_indices; - const uint8_t *indices; -} arm_mode_data[] = { - /* Seven modes are standard from ARM7 on. "System" and "User" share - * the same registers; other modes shadow from 3 to 8 registers. - */ - { - .name = "User", - .psr = ARM_MODE_USR, - .n_indices = ARRAY_SIZE(arm_usr_indices), - .indices = arm_usr_indices, - }, - { - .name = "FIQ", - .psr = ARM_MODE_FIQ, - .n_indices = ARRAY_SIZE(arm_fiq_indices), - .indices = arm_fiq_indices, - }, - { - .name = "Supervisor", - .psr = ARM_MODE_SVC, - .n_indices = ARRAY_SIZE(arm_svc_indices), - .indices = arm_svc_indices, - }, - { - .name = "Abort", - .psr = ARM_MODE_ABT, - .n_indices = ARRAY_SIZE(arm_abt_indices), - .indices = arm_abt_indices, - }, - { - .name = "IRQ", - .psr = ARM_MODE_IRQ, - .n_indices = ARRAY_SIZE(arm_irq_indices), - .indices = arm_irq_indices, - }, - { - .name = "Undefined instruction", - .psr = ARM_MODE_UND, - .n_indices = ARRAY_SIZE(arm_und_indices), - .indices = arm_und_indices, - }, - { - .name = "System", - .psr = ARM_MODE_SYS, - .n_indices = ARRAY_SIZE(arm_usr_indices), - .indices = arm_usr_indices, - }, - /* TrustZone "Security Extensions" add a secure monitor mode. - * This is distinct from a "debug monitor" which can support - * non-halting debug, in conjunction with some debuggers. - */ - { - .name = "Secure Monitor", - .psr = ARM_MODE_MON, - .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 */ - { - .name = "Thread", - .psr = ARM_MODE_THREAD, - }, - { - .name = "Thread (User)", - .psr = ARM_MODE_USER_THREAD, - }, - { - .name = "Handler", - .psr = ARM_MODE_HANDLER, - }, -}; - -/** Map PSR mode bits to the name of an ARM processor operating mode. */ -const char *arm_mode_name(unsigned psr_mode) -{ - for (unsigned i = 0; i < ARRAY_SIZE(arm_mode_data); i++) { - if (arm_mode_data[i].psr == psr_mode) - return arm_mode_data[i].name; - } - LOG_ERROR("unrecognized psr mode: %#02x", psr_mode); - return "UNRECOGNIZED"; -} - -/** Return true iff the parameter denotes a valid ARM processor mode. */ -bool is_arm_mode(unsigned psr_mode) -{ - for (unsigned i = 0; i < ARRAY_SIZE(arm_mode_data); i++) { - if (arm_mode_data[i].psr == psr_mode) - return true; - } - return false; -} - -/** Map PSR mode bits to linear number indexing armv4_5_core_reg_map */ -int arm_mode_to_number(enum arm_mode mode) -{ - switch (mode) { - case ARM_MODE_ANY: - /* map MODE_ANY to user mode */ - case ARM_MODE_USR: - return 0; - case ARM_MODE_FIQ: - return 1; - case ARM_MODE_IRQ: - return 2; - case ARM_MODE_SVC: - return 3; - case ARM_MODE_ABT: - return 4; - case ARM_MODE_UND: - return 5; - 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); - return -1; - } -} - -/** Map linear number indexing armv4_5_core_reg_map to PSR mode bits. */ -enum arm_mode armv4_5_number_to_mode(int number) -{ - switch (number) { - case 0: - return ARM_MODE_USR; - case 1: - return ARM_MODE_FIQ; - case 2: - return ARM_MODE_IRQ; - case 3: - return ARM_MODE_SVC; - case 4: - return ARM_MODE_ABT; - case 5: - return ARM_MODE_UND; - case 6: - return ARM_MODE_SYS; - case 7: - return ARM_MODE_MON; - default: - LOG_ERROR("mode index out of bounds %d", number); - return ARM_MODE_ANY; - } -} - -static const char *arm_state_strings[] = { - "ARM", "Thumb", "Jazelle", "ThumbEE", -}; - -/* Templates for ARM core registers. - * - * NOTE: offsets in this table are coupled to the arm_mode_data - * table above, the armv4_5_core_reg_map array below, and also to - * the ARMV4_5_CPSR symbol (which should vanish after ARM11 updates). - */ -static const struct { - /* The name is used for e.g. the "regs" command. */ - const char *name; - - /* The {cookie, mode} tuple uniquely identifies one register. - * In a given mode, cookies 0..15 map to registers R0..R15, - * with R13..R15 usually called SP, LR, PC. - * - * MODE_ANY is used as *input* to the mapping, and indicates - * various special cases (sigh) and errors. - * - * Cookie 16 is (currently) confusing, since it indicates - * CPSR -or- SPSR depending on whether 'mode' is MODE_ANY. - * (Exception modes have both CPSR and SPSR registers ...) - */ - unsigned cookie; - unsigned gdb_index; - enum arm_mode mode; -} arm_core_regs[] = { - /* IMPORTANT: we guarantee that the first eight cached registers - * correspond to r0..r7, and the fifteenth to PC, so that callers - * don't need to map them. - */ - { .name = "r0", .cookie = 0, .mode = ARM_MODE_ANY, .gdb_index = 0, }, - { .name = "r1", .cookie = 1, .mode = ARM_MODE_ANY, .gdb_index = 1, }, - { .name = "r2", .cookie = 2, .mode = ARM_MODE_ANY, .gdb_index = 2, }, - { .name = "r3", .cookie = 3, .mode = ARM_MODE_ANY, .gdb_index = 3, }, - { .name = "r4", .cookie = 4, .mode = ARM_MODE_ANY, .gdb_index = 4, }, - { .name = "r5", .cookie = 5, .mode = ARM_MODE_ANY, .gdb_index = 5, }, - { .name = "r6", .cookie = 6, .mode = ARM_MODE_ANY, .gdb_index = 6, }, - { .name = "r7", .cookie = 7, .mode = ARM_MODE_ANY, .gdb_index = 7, }, - - /* NOTE: regs 8..12 might be shadowed by FIQ ... flagging - * them as MODE_ANY creates special cases. (ANY means - * "not mapped" elsewhere; here it's "everything but FIQ".) - */ - { .name = "r8", .cookie = 8, .mode = ARM_MODE_ANY, .gdb_index = 8, }, - { .name = "r9", .cookie = 9, .mode = ARM_MODE_ANY, .gdb_index = 9, }, - { .name = "r10", .cookie = 10, .mode = ARM_MODE_ANY, .gdb_index = 10, }, - { .name = "r11", .cookie = 11, .mode = ARM_MODE_ANY, .gdb_index = 11, }, - { .name = "r12", .cookie = 12, .mode = ARM_MODE_ANY, .gdb_index = 12, }, - - /* Historical GDB mapping of indices: - * - 13-14 are sp and lr, but banked counterparts are used - * - 16-24 are left for deprecated 8 FPA + 1 FPS - * - 25 is the cpsr - */ - - /* NOTE all MODE_USR registers are equivalent to MODE_SYS ones */ - { .name = "sp_usr", .cookie = 13, .mode = ARM_MODE_USR, .gdb_index = 26, }, - { .name = "lr_usr", .cookie = 14, .mode = ARM_MODE_USR, .gdb_index = 27, }, - - /* guaranteed to be at index 15 */ - { .name = "pc", .cookie = 15, .mode = ARM_MODE_ANY, .gdb_index = 15, }, - { .name = "r8_fiq", .cookie = 8, .mode = ARM_MODE_FIQ, .gdb_index = 28, }, - { .name = "r9_fiq", .cookie = 9, .mode = ARM_MODE_FIQ, .gdb_index = 29, }, - { .name = "r10_fiq", .cookie = 10, .mode = ARM_MODE_FIQ, .gdb_index = 30, }, - { .name = "r11_fiq", .cookie = 11, .mode = ARM_MODE_FIQ, .gdb_index = 31, }, - { .name = "r12_fiq", .cookie = 12, .mode = ARM_MODE_FIQ, .gdb_index = 32, }, - - { .name = "sp_fiq", .cookie = 13, .mode = ARM_MODE_FIQ, .gdb_index = 33, }, - { .name = "lr_fiq", .cookie = 14, .mode = ARM_MODE_FIQ, .gdb_index = 34, }, - - { .name = "sp_irq", .cookie = 13, .mode = ARM_MODE_IRQ, .gdb_index = 35, }, - { .name = "lr_irq", .cookie = 14, .mode = ARM_MODE_IRQ, .gdb_index = 36, }, - - { .name = "sp_svc", .cookie = 13, .mode = ARM_MODE_SVC, .gdb_index = 37, }, - { .name = "lr_svc", .cookie = 14, .mode = ARM_MODE_SVC, .gdb_index = 38, }, - - { .name = "sp_abt", .cookie = 13, .mode = ARM_MODE_ABT, .gdb_index = 39, }, - { .name = "lr_abt", .cookie = 14, .mode = ARM_MODE_ABT, .gdb_index = 40, }, - - { .name = "sp_und", .cookie = 13, .mode = ARM_MODE_UND, .gdb_index = 41, }, - { .name = "lr_und", .cookie = 14, .mode = ARM_MODE_UND, .gdb_index = 42, }, - - { .name = "cpsr", .cookie = 16, .mode = ARM_MODE_ANY, .gdb_index = 25, }, - { .name = "spsr_fiq", .cookie = 16, .mode = ARM_MODE_FIQ, .gdb_index = 43, }, - { .name = "spsr_irq", .cookie = 16, .mode = ARM_MODE_IRQ, .gdb_index = 44, }, - { .name = "spsr_svc", .cookie = 16, .mode = ARM_MODE_SVC, .gdb_index = 45, }, - { .name = "spsr_abt", .cookie = 16, .mode = ARM_MODE_ABT, .gdb_index = 46, }, - { .name = "spsr_und", .cookie = 16, .mode = ARM_MODE_UND, .gdb_index = 47, }, - - /* These are only used for GDB target description, banked registers are accessed instead */ - { .name = "sp", .cookie = 13, .mode = ARM_MODE_ANY, .gdb_index = 13, }, - { .name = "lr", .cookie = 14, .mode = ARM_MODE_ANY, .gdb_index = 14, }, - - /* These exist only when the Security Extension (TrustZone) is present */ - { .name = "sp_mon", .cookie = 13, .mode = ARM_MODE_MON, .gdb_index = 48, }, - { .name = "lr_mon", .cookie = 14, .mode = ARM_MODE_MON, .gdb_index = 49, }, - { .name = "spsr_mon", .cookie = 16, .mode = ARM_MODE_MON, .gdb_index = 50, }, - -}; - -/* map core mode (USR, FIQ, ...) and register number to - * indices into the register cache - */ -const int armv4_5_core_reg_map[8][17] = { - { /* USR */ - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 31 - }, - { /* FIQ (8 shadows of USR, vs normal 3) */ - 0, 1, 2, 3, 4, 5, 6, 7, 16, 17, 18, 19, 20, 21, 22, 15, 32 - }, - { /* IRQ */ - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 23, 24, 15, 33 - }, - { /* SVC */ - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 25, 26, 15, 34 - }, - { /* ABT */ - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 27, 28, 15, 35 - }, - { /* UND */ - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 29, 30, 15, 36 - }, - { /* SYS (same registers as USR) */ - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 31 - }, - { /* MON */ - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 37, 38, 15, 39, - } -}; - -/** - * Configures host-side ARM records to reflect the specified CPSR. - * Later, code can use arm_reg_current() to map register numbers - * according to how they are exposed by this mode. - */ -void arm_set_cpsr(struct arm *arm, uint32_t cpsr) -{ - enum arm_mode mode = cpsr & 0x1f; - int num; - - /* NOTE: this may be called very early, before the register - * cache is set up. We can't defend against many errors, in - * particular against CPSRs that aren't valid *here* ... - */ - if (arm->cpsr) { - buf_set_u32(arm->cpsr->value, 0, 32, cpsr); - arm->cpsr->valid = 1; - arm->cpsr->dirty = 0; - } - - arm->core_mode = mode; - - /* mode_to_number() warned; set up a somewhat-sane mapping */ - num = arm_mode_to_number(mode); - if (num < 0) { - mode = ARM_MODE_USR; - num = 0; - } - - arm->map = &armv4_5_core_reg_map[num][0]; - arm->spsr = (mode == ARM_MODE_USR || mode == ARM_MODE_SYS) - ? NULL - : arm->core_cache->reg_list + arm->map[16]; - - /* Older ARMs won't have the J bit */ - enum arm_state state; - - if (cpsr & (1 << 5)) { /* T */ - if (cpsr & (1 << 24)) { /* J */ - LOG_WARNING("ThumbEE -- incomplete support"); - state = ARM_STATE_THUMB_EE; - } else - state = ARM_STATE_THUMB; - } else { - if (cpsr & (1 << 24)) { /* J */ - LOG_ERROR("Jazelle state handling is BROKEN!"); - state = ARM_STATE_JAZELLE; - } else - state = ARM_STATE_ARM; - } - arm->core_state = state; - - LOG_DEBUG("set CPSR %#8.8x: %s mode, %s state", (unsigned) cpsr, - arm_mode_name(mode), - arm_state_strings[arm->core_state]); -} - -/** - * Returns handle to the register currently mapped to a given number. - * Someone must have called arm_set_cpsr() before. - * - * \param arm This core's state and registers are used. - * \param regnum From 0..15 corresponding to R0..R14 and PC. - * Note that R0..R7 don't require mapping; you may access those - * as the first eight entries in the register cache. Likewise - * R15 (PC) doesn't need mapping; you may also access it directly. - * However, R8..R14, and SPSR (arm->spsr) *must* be mapped. - * CPSR (arm->cpsr) is also not mapped. - */ -struct reg *arm_reg_current(struct arm *arm, unsigned regnum) -{ - struct reg *r; - - if (regnum > 16) - return NULL; - - if (!arm->map) { - LOG_ERROR("Register map is not available yet, the target is not fully initialised"); - r = arm->core_cache->reg_list + regnum; - } else - r = arm->core_cache->reg_list + arm->map[regnum]; - - /* e.g. invalid CPSR said "secure monitor" mode on a core - * that doesn't support it... - */ - if (!r) { - LOG_ERROR("Invalid CPSR mode"); - r = arm->core_cache->reg_list + regnum; - } - - return r; -} - -static const uint8_t arm_gdb_dummy_fp_value[12]; - -static struct reg_feature arm_gdb_dummy_fp_features = { - .name = "net.sourceforge.openocd.fake_fpa" -}; - -/** - * Dummy FPA registers are required to support GDB on ARM. - * Register packets require eight obsolete FPA register values. - * Modern ARM cores use Vector Floating Point (VFP), if they - * have any floating point support. VFP is not FPA-compatible. - */ -struct reg arm_gdb_dummy_fp_reg = { - .name = "GDB dummy FPA register", - .value = (uint8_t *) arm_gdb_dummy_fp_value, - .valid = 1, - .size = 96, - .exist = false, - .number = 16, - .feature = &arm_gdb_dummy_fp_features, - .group = "fake_fpa", -}; - -static const uint8_t arm_gdb_dummy_fps_value[4]; - -/** - * Dummy FPA status registers are required to support GDB on ARM. - * Register packets require an obsolete FPA status register. - */ -struct reg arm_gdb_dummy_fps_reg = { - .name = "GDB dummy FPA status register", - .value = (uint8_t *) arm_gdb_dummy_fps_value, - .valid = 1, - .size = 32, - .exist = false, - .number = 24, - .feature = &arm_gdb_dummy_fp_features, - .group = "fake_fpa", -}; - -static void arm_gdb_dummy_init(void) __attribute__ ((constructor)); - -static void arm_gdb_dummy_init(void) -{ - register_init_dummy(&arm_gdb_dummy_fp_reg); - register_init_dummy(&arm_gdb_dummy_fps_reg); -} - -static int armv4_5_get_core_reg(struct reg *reg) -{ - int retval; - struct arm_reg *reg_arch_info = reg->arch_info; - struct target *target = reg_arch_info->target; - - if (target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - retval = reg_arch_info->arm->read_core_reg(target, reg, - reg_arch_info->num, reg_arch_info->mode); - if (retval == ERROR_OK) { - reg->valid = 1; - reg->dirty = 0; - } - - return retval; -} - -static int armv4_5_set_core_reg(struct reg *reg, uint8_t *buf) -{ - struct arm_reg *reg_arch_info = reg->arch_info; - struct target *target = reg_arch_info->target; - struct arm *armv4_5_target = target_to_arm(target); - uint32_t value = buf_get_u32(buf, 0, 32); - - if (target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - /* Except for CPSR, the "reg" command exposes a writeback model - * for the register cache. - */ - if (reg == armv4_5_target->cpsr) { - arm_set_cpsr(armv4_5_target, value); - - /* Older cores need help to be in ARM mode during halt - * mode debug, so we clear the J and T bits if we flush. - * For newer cores (v6/v7a/v7r) we don't need that, but - * it won't hurt since CPSR is always flushed anyway. - */ - if (armv4_5_target->core_mode != - (enum arm_mode)(value & 0x1f)) { - LOG_DEBUG("changing ARM core mode to '%s'", - arm_mode_name(value & 0x1f)); - value &= ~((1 << 24) | (1 << 5)); - uint8_t t[4]; - buf_set_u32(t, 0, 32, value); - armv4_5_target->write_core_reg(target, reg, - 16, ARM_MODE_ANY, t); - } - } else { - buf_set_u32(reg->value, 0, 32, value); - reg->valid = 1; - } - reg->dirty = 1; - - return ERROR_OK; -} - -static const struct reg_arch_type arm_reg_type = { - .get = armv4_5_get_core_reg, - .set = armv4_5_set_core_reg, -}; - -struct reg_cache *arm_build_reg_cache(struct target *target, struct arm *arm) -{ - int num_regs = ARRAY_SIZE(arm_core_regs); - struct reg_cache *cache = malloc(sizeof(struct reg_cache)); - struct reg *reg_list = calloc(num_regs, sizeof(struct reg)); - struct arm_reg *reg_arch_info = calloc(num_regs, sizeof(struct arm_reg)); - int i; - - if (!cache || !reg_list || !reg_arch_info) { - free(cache); - free(reg_list); - free(reg_arch_info); - return NULL; - } - - cache->name = "ARM registers"; - cache->next = NULL; - cache->reg_list = reg_list; - cache->num_regs = 0; - - for (i = 0; i < num_regs; i++) { - /* Skip registers this core doesn't expose */ - if (arm_core_regs[i].mode == ARM_MODE_MON - && arm->core_type != ARM_MODE_MON) - continue; - - /* REVISIT handle Cortex-M, which only shadows R13/SP */ - - reg_arch_info[i].num = arm_core_regs[i].cookie; - reg_arch_info[i].mode = arm_core_regs[i].mode; - reg_arch_info[i].target = target; - reg_arch_info[i].arm = arm; - - reg_list[i].name = arm_core_regs[i].name; - reg_list[i].number = arm_core_regs[i].gdb_index; - reg_list[i].size = 32; - reg_list[i].value = reg_arch_info[i].value; - reg_list[i].type = &arm_reg_type; - reg_list[i].arch_info = ®_arch_info[i]; - reg_list[i].exist = true; - - /* This really depends on the calling convention in use */ - reg_list[i].caller_save = false; - - /* Registers data type, as used by GDB target description */ - reg_list[i].reg_data_type = malloc(sizeof(struct reg_data_type)); - switch (arm_core_regs[i].cookie) { - case 13: - reg_list[i].reg_data_type->type = REG_TYPE_DATA_PTR; - break; - case 14: - case 15: - reg_list[i].reg_data_type->type = REG_TYPE_CODE_PTR; - break; - default: - reg_list[i].reg_data_type->type = REG_TYPE_UINT32; - break; - } - - /* let GDB shows banked registers only in "info all-reg" */ - reg_list[i].feature = malloc(sizeof(struct reg_feature)); - if (reg_list[i].number <= 15 || reg_list[i].number == 25) { - reg_list[i].feature->name = "org.gnu.gdb.arm.core"; - reg_list[i].group = "general"; - } else { - reg_list[i].feature->name = "net.sourceforge.openocd.banked"; - reg_list[i].group = "banked"; - } - - cache->num_regs++; - } - - arm->pc = reg_list + 15; - arm->cpsr = reg_list + ARMV4_5_CPSR; - arm->core_cache = cache; - return cache; -} - -int arm_arch_state(struct target *target) -{ - struct arm *arm = target_to_arm(target); - - if (arm->common_magic != ARM_COMMON_MAGIC) { - LOG_ERROR("BUG: called for a non-ARM target"); - return ERROR_FAIL; - } - - 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", - 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" : ""); - - return ERROR_OK; -} - -#define ARMV4_5_CORE_REG_MODENUM(cache, mode, num) \ - (cache->reg_list[armv4_5_core_reg_map[mode][num]]) - -COMMAND_HANDLER(handle_armv4_5_reg_command) -{ - struct target *target = get_current_target(CMD_CTX); - struct arm *arm = target_to_arm(target); - struct reg *regs; - - if (!is_arm(arm)) { - command_print(CMD_CTX, "current target isn't an ARM"); - return ERROR_FAIL; - } - - if (target->state != TARGET_HALTED) { - command_print(CMD_CTX, "error: target must be halted for register accesses"); - return ERROR_FAIL; - } - - if (arm->core_type != ARM_MODE_ANY) { - command_print(CMD_CTX, - "Microcontroller Profile not supported - use standard reg cmd"); - return ERROR_OK; - } - - if (!is_arm_mode(arm->core_mode)) { - LOG_ERROR("not a valid arm core mode - communication failure?"); - return ERROR_FAIL; - } - - if (!arm->full_context) { - command_print(CMD_CTX, "error: target doesn't support %s", - CMD_NAME); - return ERROR_FAIL; - } - - regs = arm->core_cache->reg_list; - - for (unsigned mode = 0; mode < ARRAY_SIZE(arm_mode_data); mode++) { - const char *name; - char *sep = "\n"; - char *shadow = ""; - - /* label this bank of registers (or shadows) */ - switch (arm_mode_data[mode].psr) { - case ARM_MODE_SYS: - continue; - case ARM_MODE_USR: - name = "System and User"; - sep = ""; - break; - case ARM_MODE_MON: - if (arm->core_type != ARM_MODE_MON) - continue; - /* FALLTHROUGH */ - default: - name = arm_mode_data[mode].name; - shadow = "shadow "; - break; - } - command_print(CMD_CTX, "%s%s mode %sregisters", - sep, name, shadow); - - /* display N rows of up to 4 registers each */ - for (unsigned i = 0; i < arm_mode_data[mode].n_indices; ) { - char output[80]; - int output_len = 0; - - for (unsigned j = 0; j < 4; j++, i++) { - uint32_t value; - struct reg *reg = regs; - - if (i >= arm_mode_data[mode].n_indices) - break; - - reg += arm_mode_data[mode].indices[i]; - - /* REVISIT be smarter about faults... */ - if (!reg->valid) - arm->full_context(target); - - value = buf_get_u32(reg->value, 0, 32); - output_len += snprintf(output + output_len, - sizeof(output) - output_len, - "%8s: %8.8" PRIx32 " ", - reg->name, value); - } - command_print(CMD_CTX, "%s", output); - } - } - - return ERROR_OK; -} - -COMMAND_HANDLER(handle_armv4_5_core_state_command) -{ - struct target *target = get_current_target(CMD_CTX); - 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->core_type == ARM_MODE_THREAD) { - /* armv7m not supported */ - command_print(CMD_CTX, "Unsupported Command"); - return ERROR_OK; - } - - if (CMD_ARGC > 0) { - if (strcmp(CMD_ARGV[0], "arm") == 0) - arm->core_state = ARM_STATE_ARM; - if (strcmp(CMD_ARGV[0], "thumb") == 0) - arm->core_state = ARM_STATE_THUMB; - } - - command_print(CMD_CTX, "core state: %s", arm_state_strings[arm->core_state]); - - return ERROR_OK; -} - -COMMAND_HANDLER(handle_arm_disassemble_command) -{ - int retval = ERROR_OK; - 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); - uint32_t address; - int count = 1; - int thumb = 0; - - if (!is_arm(arm)) { - command_print(CMD_CTX, "current target isn't an ARM"); - return ERROR_FAIL; - } - - if (arm->core_type == ARM_MODE_THREAD) { - /* armv7m is always thumb mode */ - thumb = 1; - } - - switch (CMD_ARGC) { - case 3: - if (strcmp(CMD_ARGV[2], "thumb") != 0) - goto usage; - thumb = 1; - /* FALL THROUGH */ - case 2: - COMMAND_PARSE_NUMBER(int, CMD_ARGV[1], count); - /* FALL THROUGH */ - case 1: - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], address); - if (address & 0x01) { - if (!thumb) { - command_print(CMD_CTX, "Disassemble as Thumb"); - thumb = 1; - } - address &= ~1; - } - break; - default: -usage: - count = 0; - retval = ERROR_COMMAND_SYNTAX_ERROR; - } - - while (count-- > 0) { - struct arm_instruction cur_instruction; - - if (thumb) { - /* Always use Thumb2 disassembly for best handling - * of 32-bit BL/BLX, and to work with newer cores - * (some ARMv6, all ARMv7) that use Thumb2. - */ - retval = thumb2_opcode(target, address, - &cur_instruction); - if (retval != ERROR_OK) - break; - } else { - uint32_t opcode; - - retval = target_read_u32(target, address, &opcode); - if (retval != ERROR_OK) - break; - retval = arm_evaluate_opcode(opcode, address, - &cur_instruction) != ERROR_OK; - if (retval != ERROR_OK) - break; - } - command_print(CMD_CTX, "%s", cur_instruction.text); - address += cur_instruction.instruction_size; - } - - return retval; -} - -static int jim_mcrmrc(Jim_Interp *interp, int argc, Jim_Obj * const *argv) -{ - struct command_context *context; - struct target *target; - struct arm *arm; - int retval; - - context = current_command_context(interp); - assert(context != NULL); - - target = get_current_target(context); - if (target == NULL) { - LOG_ERROR("%s: no current target", __func__); - return JIM_ERR; - } - if (!target_was_examined(target)) { - LOG_ERROR("%s: not yet examined", target_name(target)); - return JIM_ERR; - } - arm = target_to_arm(target); - if (!is_arm(arm)) { - LOG_ERROR("%s: not an ARM", target_name(target)); - return JIM_ERR; - } - - if ((argc < 6) || (argc > 7)) { - /* FIXME use the command name to verify # params... */ - LOG_ERROR("%s: wrong number of arguments", __func__); - return JIM_ERR; - } - - int cpnum; - uint32_t op1; - uint32_t op2; - uint32_t CRn; - uint32_t CRm; - uint32_t value; - long l; - - /* NOTE: parameter sequence matches ARM instruction set usage: - * MCR pNUM, op1, rX, CRn, CRm, op2 ; write CP from rX - * MRC pNUM, op1, rX, CRn, CRm, op2 ; read CP into rX - * The "rX" is necessarily omitted; it uses Tcl mechanisms. - */ - retval = Jim_GetLong(interp, argv[1], &l); - if (retval != JIM_OK) - return retval; - if (l & ~0xf) { - LOG_ERROR("%s: %s %d out of range", __func__, - "coprocessor", (int) l); - return JIM_ERR; - } - cpnum = l; - - retval = Jim_GetLong(interp, argv[2], &l); - if (retval != JIM_OK) - return retval; - if (l & ~0x7) { - LOG_ERROR("%s: %s %d out of range", __func__, - "op1", (int) l); - return JIM_ERR; - } - op1 = l; - - retval = Jim_GetLong(interp, argv[3], &l); - if (retval != JIM_OK) - return retval; - if (l & ~0xf) { - LOG_ERROR("%s: %s %d out of range", __func__, - "CRn", (int) l); - return JIM_ERR; - } - CRn = l; - - retval = Jim_GetLong(interp, argv[4], &l); - if (retval != JIM_OK) - return retval; - if (l & ~0xf) { - LOG_ERROR("%s: %s %d out of range", __func__, - "CRm", (int) l); - return JIM_ERR; - } - CRm = l; - - retval = Jim_GetLong(interp, argv[5], &l); - if (retval != JIM_OK) - return retval; - if (l & ~0x7) { - LOG_ERROR("%s: %s %d out of range", __func__, - "op2", (int) l); - return JIM_ERR; - } - op2 = l; - - value = 0; - - /* FIXME don't assume "mrc" vs "mcr" from the number of params; - * that could easily be a typo! Check both... - * - * FIXME change the call syntax here ... simplest to just pass - * the MRC() or MCR() instruction to be executed. That will also - * let us support the "mrc2" and "mcr2" opcodes (toggling one bit) - * if that's ever needed. - */ - if (argc == 7) { - retval = Jim_GetLong(interp, argv[6], &l); - if (retval != JIM_OK) - return retval; - value = l; - - /* NOTE: parameters reordered! */ - /* ARMV4_5_MCR(cpnum, op1, 0, CRn, CRm, op2) */ - retval = arm->mcr(target, cpnum, op1, op2, CRn, CRm, value); - if (retval != ERROR_OK) - return JIM_ERR; - } else { - /* NOTE: parameters reordered! */ - /* ARMV4_5_MRC(cpnum, op1, 0, CRn, CRm, op2) */ - retval = arm->mrc(target, cpnum, op1, op2, CRn, CRm, &value); - if (retval != ERROR_OK) - return JIM_ERR; - - Jim_SetResult(interp, Jim_NewIntObj(interp, value)); - } - - return JIM_OK; -} - -COMMAND_HANDLER(handle_arm_semihosting_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->setup_semihosting) { - command_print(CMD_CTX, "semihosting not supported for current target"); - return ERROR_FAIL; - } - - if (CMD_ARGC > 0) { - int semihosting; - - COMMAND_PARSE_ENABLE(CMD_ARGV[0], semihosting); - - if (!target_was_examined(target)) { - LOG_ERROR("Target not examined yet"); - return ERROR_FAIL; - } - - if (arm->setup_semihosting(target, semihosting) != ERROR_OK) { - LOG_ERROR("Failed to Configure semihosting"); - return ERROR_FAIL; - } - - /* FIXME never let that "catch" be dropped! */ - arm->is_semihosting = semihosting; - } - - command_print(CMD_CTX, "semihosting is %s", - arm->is_semihosting - ? "enabled" : "disabled"); - - return ERROR_OK; -} - -static const struct command_registration arm_exec_command_handlers[] = { - { - .name = "reg", - .handler = handle_armv4_5_reg_command, - .mode = COMMAND_EXEC, - .help = "display ARM core registers", - .usage = "", - }, - { - .name = "core_state", - .handler = handle_armv4_5_core_state_command, - .mode = COMMAND_EXEC, - .usage = "['arm'|'thumb']", - .help = "display/change ARM core state", - }, - { - .name = "disassemble", - .handler = handle_arm_disassemble_command, - .mode = COMMAND_EXEC, - .usage = "address [count ['thumb']]", - .help = "disassemble instructions ", - }, - { - .name = "mcr", - .mode = COMMAND_EXEC, - .jim_handler = &jim_mcrmrc, - .help = "write coprocessor register", - .usage = "cpnum op1 CRn CRm op2 value", - }, - { - .name = "mrc", - .jim_handler = &jim_mcrmrc, - .help = "read coprocessor register", - .usage = "cpnum op1 CRn CRm op2", - }, - { - "semihosting", - .handler = handle_arm_semihosting_command, - .mode = COMMAND_EXEC, - .usage = "['enable'|'disable']", - .help = "activate support for semihosting operations", - }, - - COMMAND_REGISTRATION_DONE -}; -const struct command_registration arm_command_handlers[] = { - { - .name = "arm", - .mode = COMMAND_ANY, - .help = "ARM command group", - .usage = "", - .chain = arm_exec_command_handlers, - }, - COMMAND_REGISTRATION_DONE -}; - -int arm_get_gdb_reg_list(struct target *target, - struct reg **reg_list[], int *reg_list_size, - enum target_register_class reg_class) -{ - struct arm *arm = target_to_arm(target); - unsigned int i; - - if (!is_arm_mode(arm->core_mode)) { - LOG_ERROR("not a valid arm core mode - communication failure?"); - return ERROR_FAIL; - } - - switch (reg_class) { - case REG_CLASS_GENERAL: - *reg_list_size = 26; - *reg_list = malloc(sizeof(struct reg *) * (*reg_list_size)); - - for (i = 0; i < 16; i++) - (*reg_list)[i] = arm_reg_current(arm, i); - - /* For GDB compatibility, take FPA registers size into account and zero-fill it*/ - for (i = 16; i < 24; i++) - (*reg_list)[i] = &arm_gdb_dummy_fp_reg; - (*reg_list)[24] = &arm_gdb_dummy_fps_reg; - - (*reg_list)[25] = arm->cpsr; - - return ERROR_OK; - break; - - case REG_CLASS_ALL: - *reg_list_size = (arm->core_type != ARM_MODE_MON ? 48 : 51); - *reg_list = malloc(sizeof(struct reg *) * (*reg_list_size)); - - for (i = 0; i < 16; i++) - (*reg_list)[i] = arm_reg_current(arm, i); - - for (i = 13; i < ARRAY_SIZE(arm_core_regs); i++) { - int reg_index = arm->core_cache->reg_list[i].number; - if (!(arm_core_regs[i].mode == ARM_MODE_MON - && arm->core_type != ARM_MODE_MON)) - (*reg_list)[reg_index] = &(arm->core_cache->reg_list[i]); - } - - /* When we supply the target description, there is no need for fake FPA */ - for (i = 16; i < 24; i++) { - (*reg_list)[i] = &arm_gdb_dummy_fp_reg; - (*reg_list)[i]->size = 0; - } - (*reg_list)[24] = &arm_gdb_dummy_fps_reg; - (*reg_list)[24]->size = 0; - - return ERROR_OK; - break; - - default: - LOG_ERROR("not a valid register class type in query."); - return ERROR_FAIL; - break; - } -} - -/* wait for execution to complete and check exit point */ -static int armv4_5_run_algorithm_completion(struct target *target, - uint32_t exit_point, - int timeout_ms, - void *arch_info) -{ - int retval; - struct arm *arm = target_to_arm(target); - - retval = target_wait_state(target, TARGET_HALTED, timeout_ms); - if (retval != ERROR_OK) - return retval; - if (target->state != TARGET_HALTED) { - retval = target_halt(target); - if (retval != ERROR_OK) - return retval; - retval = target_wait_state(target, TARGET_HALTED, 500); - if (retval != ERROR_OK) - return retval; - return ERROR_TARGET_TIMEOUT; - } - - /* fast exit: ARMv5+ code can use BKPT */ - if (exit_point && buf_get_u32(arm->pc->value, 0, 32) != exit_point) { - LOG_WARNING( - "target reentered debug state, but not at the desired exit point: 0x%4.4" PRIx32 "", - buf_get_u32(arm->pc->value, 0, 32)); - return ERROR_TARGET_TIMEOUT; - } - - return ERROR_OK; -} - -int armv4_5_run_algorithm_inner(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, - int (*run_it)(struct target *target, uint32_t exit_point, - int timeout_ms, void *arch_info)) -{ - struct arm *arm = target_to_arm(target); - struct arm_algorithm *arm_algorithm_info = arch_info; - enum arm_state core_state = arm->core_state; - uint32_t context[17]; - uint32_t cpsr; - int exit_breakpoint_size = 0; - int i; - int retval = ERROR_OK; - - LOG_DEBUG("Running algorithm"); - - if (arm_algorithm_info->common_magic != ARM_COMMON_MAGIC) { - LOG_ERROR("current target isn't an ARMV4/5 target"); - return ERROR_TARGET_INVALID; - } - - if (target->state != TARGET_HALTED) { - LOG_WARNING("target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - if (!is_arm_mode(arm->core_mode)) { - LOG_ERROR("not a valid arm core mode - communication failure?"); - return ERROR_FAIL; - } - - /* armv5 and later can terminate with BKPT instruction; less overhead */ - if (!exit_point && arm->is_armv4) { - LOG_ERROR("ARMv4 target needs HW breakpoint location"); - return ERROR_FAIL; - } - - /* save r0..pc, cpsr-or-spsr, and then cpsr-for-sure; - * they'll be restored later. - */ - for (i = 0; i <= 16; i++) { - struct reg *r; - - r = &ARMV4_5_CORE_REG_MODE(arm->core_cache, - arm_algorithm_info->core_mode, i); - if (!r->valid) - arm->read_core_reg(target, r, i, - arm_algorithm_info->core_mode); - context[i] = buf_get_u32(r->value, 0, 32); - } - cpsr = buf_get_u32(arm->cpsr->value, 0, 32); - - for (i = 0; i < num_mem_params; i++) { - retval = target_write_buffer(target, mem_params[i].address, mem_params[i].size, - mem_params[i].value); - if (retval != ERROR_OK) - return retval; - } - - for (i = 0; i < num_reg_params; i++) { - struct reg *reg = register_get_by_name(arm->core_cache, reg_params[i].reg_name, 0); - if (!reg) { - LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name); - return ERROR_COMMAND_SYNTAX_ERROR; - } - - if (reg->size != reg_params[i].size) { - LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size", - reg_params[i].reg_name); - return ERROR_COMMAND_SYNTAX_ERROR; - } - - retval = armv4_5_set_core_reg(reg, reg_params[i].value); - if (retval != ERROR_OK) - return retval; - } - - arm->core_state = arm_algorithm_info->core_state; - if (arm->core_state == ARM_STATE_ARM) - exit_breakpoint_size = 4; - else if (arm->core_state == ARM_STATE_THUMB) - exit_breakpoint_size = 2; - else { - LOG_ERROR("BUG: can't execute algorithms when not in ARM or Thumb state"); - return ERROR_COMMAND_SYNTAX_ERROR; - } - - if (arm_algorithm_info->core_mode != ARM_MODE_ANY) { - LOG_DEBUG("setting core_mode: 0x%2.2x", - arm_algorithm_info->core_mode); - buf_set_u32(arm->cpsr->value, 0, 5, - arm_algorithm_info->core_mode); - arm->cpsr->dirty = 1; - arm->cpsr->valid = 1; - } - - /* terminate using a hardware or (ARMv5+) software breakpoint */ - if (exit_point) { - retval = breakpoint_add(target, exit_point, - exit_breakpoint_size, BKPT_HARD); - if (retval != ERROR_OK) { - LOG_ERROR("can't add HW breakpoint to terminate algorithm"); - return ERROR_TARGET_FAILURE; - } - } - - retval = target_resume(target, 0, entry_point, 1, 1); - if (retval != ERROR_OK) - return retval; - retval = run_it(target, exit_point, timeout_ms, arch_info); - - if (exit_point) - breakpoint_remove(target, exit_point); - - if (retval != ERROR_OK) - return retval; - - for (i = 0; i < num_mem_params; i++) { - if (mem_params[i].direction != PARAM_OUT) { - int retvaltemp = target_read_buffer(target, mem_params[i].address, - mem_params[i].size, - mem_params[i].value); - if (retvaltemp != ERROR_OK) - retval = retvaltemp; - } - } - - for (i = 0; i < num_reg_params; i++) { - if (reg_params[i].direction != PARAM_OUT) { - - struct reg *reg = register_get_by_name(arm->core_cache, - reg_params[i].reg_name, - 0); - if (!reg) { - LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name); - retval = ERROR_COMMAND_SYNTAX_ERROR; - continue; - } - - if (reg->size != reg_params[i].size) { - LOG_ERROR( - "BUG: register '%s' size doesn't match reg_params[i].size", - reg_params[i].reg_name); - retval = ERROR_COMMAND_SYNTAX_ERROR; - continue; - } - - buf_set_u32(reg_params[i].value, 0, 32, buf_get_u32(reg->value, 0, 32)); - } - } - - /* restore everything we saved before (17 or 18 registers) */ - for (i = 0; i <= 16; i++) { - uint32_t regvalue; - regvalue = buf_get_u32(ARMV4_5_CORE_REG_MODE(arm->core_cache, - arm_algorithm_info->core_mode, i).value, 0, 32); - if (regvalue != context[i]) { - LOG_DEBUG("restoring register %s with value 0x%8.8" PRIx32 "", - ARMV4_5_CORE_REG_MODE(arm->core_cache, - arm_algorithm_info->core_mode, i).name, context[i]); - buf_set_u32(ARMV4_5_CORE_REG_MODE(arm->core_cache, - arm_algorithm_info->core_mode, i).value, 0, 32, context[i]); - ARMV4_5_CORE_REG_MODE(arm->core_cache, arm_algorithm_info->core_mode, - i).valid = 1; - ARMV4_5_CORE_REG_MODE(arm->core_cache, arm_algorithm_info->core_mode, - i).dirty = 1; - } - } - - arm_set_cpsr(arm, cpsr); - arm->cpsr->dirty = 1; - - arm->core_state = core_state; - - return retval; -} - -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, - int timeout_ms, - void *arch_info) -{ - return armv4_5_run_algorithm_inner(target, - num_mem_params, - mem_params, - num_reg_params, - reg_params, - entry_point, - exit_point, - timeout_ms, - arch_info, - armv4_5_run_algorithm_completion); -} - -/** - * Runs ARM code in the target to calculate a CRC32 checksum. - * - */ -int arm_checksum_memory(struct target *target, - uint32_t address, uint32_t count, uint32_t *checksum) -{ - struct working_area *crc_algorithm; - struct arm_algorithm arm_algo; - struct arm *arm = target_to_arm(target); - struct reg_param reg_params[2]; - int retval; - uint32_t i; - uint32_t exit_var = 0; - - 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_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_le) / 4; i++) { - retval = target_write_u32(target, - crc_algorithm->address + i * sizeof(uint32_t), - le_to_h_u32(&arm_crc_code_le[i * 4])); - if (retval != ERROR_OK) - goto cleanup; - } - - arm_algo.common_magic = ARM_COMMON_MAGIC; - arm_algo.core_mode = ARM_MODE_SVC; - arm_algo.core_state = ARM_STATE_ARM; - - init_reg_param(®_params[0], "r0", 32, PARAM_IN_OUT); - init_reg_param(®_params[1], "r1", 32, PARAM_OUT); - - buf_set_u32(reg_params[0].value, 0, 32, address); - buf_set_u32(reg_params[1].value, 0, 32, count); - - /* 20 second timeout/megabyte */ - int timeout = 20000 * (1 + (count / (1024 * 1024))); - - /* armv4 must exit using a hardware breakpoint */ - if (arm->is_armv4) - 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) - *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 retval; -} - -/** - * Runs ARM code in the target to check whether a memory block holds - * all ones. NOR flash which has been erased, and thus may be written, - * holds all ones. - * - */ -int arm_blank_check_memory(struct target *target, - uint32_t address, uint32_t count, uint32_t *blank) -{ - struct working_area *check_algorithm; - struct reg_param reg_params[3]; - struct arm_algorithm arm_algo; - struct arm *arm = target_to_arm(target); - int retval; - uint32_t i; - uint32_t exit_var = 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); - - /* make sure we have a working area */ - retval = target_alloc_working_area(target, - 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_le) / 4; i++) { - retval = target_write_u32(target, - check_algorithm->address - + i * sizeof(uint32_t), - le_to_h_u32(&check_code_le[i * 4])); - if (retval != ERROR_OK) - goto cleanup; - } - - arm_algo.common_magic = ARM_COMMON_MAGIC; - arm_algo.core_mode = ARM_MODE_SVC; - arm_algo.core_state = ARM_STATE_ARM; - - 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, 0xff); - - /* armv4 must exit using a hardware breakpoint */ - if (arm->is_armv4) - 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) - *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 retval; -} - -static int arm_full_context(struct target *target) -{ - struct arm *arm = target_to_arm(target); - unsigned num_regs = arm->core_cache->num_regs; - struct reg *reg = arm->core_cache->reg_list; - int retval = ERROR_OK; - - for (; num_regs && retval == ERROR_OK; num_regs--, reg++) { - if (reg->valid) - continue; - retval = armv4_5_get_core_reg(reg); - } - return retval; -} - -static int arm_default_mrc(struct target *target, int cpnum, - uint32_t op1, uint32_t op2, - uint32_t CRn, uint32_t CRm, - uint32_t *value) -{ - LOG_ERROR("%s doesn't implement MRC", target_type_name(target)); - return ERROR_FAIL; -} - -static int arm_default_mcr(struct target *target, int cpnum, - uint32_t op1, uint32_t op2, - uint32_t CRn, uint32_t CRm, - uint32_t value) -{ - LOG_ERROR("%s doesn't implement MCR", target_type_name(target)); - return ERROR_FAIL; -} - -int arm_init_arch_info(struct target *target, struct arm *arm) -{ - target->arch_info = arm; - arm->target = target; - - arm->common_magic = ARM_COMMON_MAGIC; - - /* core_type may be overridden by subtype logic */ - if (arm->core_type != ARM_MODE_THREAD) { - arm->core_type = ARM_MODE_ANY; - arm_set_cpsr(arm, ARM_MODE_USR); - } - - /* default full_context() has no core-specific optimizations */ - if (!arm->full_context && arm->read_core_reg) - arm->full_context = arm_full_context; - - if (!arm->mrc) - arm->mrc = arm_default_mrc; - if (!arm->mcr) - arm->mcr = arm_default_mcr; - - return ERROR_OK; -} diff --git a/src/target/armv4_5.h b/src/target/armv4_5.h deleted file mode 100644 index 3ce4ed0e5..000000000 --- a/src/target/armv4_5.h +++ /dev/null @@ -1,49 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * Copyright (C) 2008 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * Copyright (C) 2009 by Øyvind Harboe * - * oyvind.harboe@zylin.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#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. - * We want to phase it out so core code can be shared. - */ - -/* OBSOLETE, DO NOT USE IN NEW CODE! The "number" of an arm_mode is an - * index into the armv4_5_core_reg_map array. Its remaining users are - * remnants which could as easily walk * the register cache directly as - * use the expensive ARMV4_5_CORE_REG_MODE() macro. - */ -int arm_mode_to_number(enum arm_mode mode); -enum arm_mode armv4_5_number_to_mode(int number); - -extern const int armv4_5_core_reg_map[8][17]; - -#define ARMV4_5_CORE_REG_MODE(cache, mode, num) \ - (cache->reg_list[armv4_5_core_reg_map[arm_mode_to_number(mode)][num]]) - -/* offset into armv4_5 core register cache -- OBSOLETE, DO NOT USE! */ -enum { ARMV4_5_CPSR = 31, }; - -#endif /* OPENOCD_TARGET_ARMV4_5_H */ diff --git a/src/target/armv4_5_cache.c b/src/target/armv4_5_cache.c deleted file mode 100644 index bd0091d80..000000000 --- a/src/target/armv4_5_cache.c +++ /dev/null @@ -1,102 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "armv4_5_cache.h" -#include - -int armv4_5_identify_cache(uint32_t cache_type_reg, struct armv4_5_cache_common *cache) -{ - int size, assoc, M, len, multiplier; - - cache->ctype = (cache_type_reg & 0x1e000000U) >> 25; - cache->separate = (cache_type_reg & 0x01000000U) >> 24; - - size = (cache_type_reg & 0x1c0000) >> 18; - assoc = (cache_type_reg & 0x38000) >> 15; - M = (cache_type_reg & 0x4000) >> 14; - len = (cache_type_reg & 0x3000) >> 12; - multiplier = 2 + M; - - if ((assoc != 0) || (M != 1)) /* assoc 0 and M 1 means cache absent */ { - /* cache is present */ - cache->d_u_size.linelen = 1 << (len + 3); - cache->d_u_size.associativity = multiplier << (assoc - 1); - cache->d_u_size.nsets = 1 << (size + 6 - assoc - len); - cache->d_u_size.cachesize = multiplier << (size + 8); - } else { - /* cache is absent */ - cache->d_u_size.linelen = -1; - cache->d_u_size.associativity = -1; - cache->d_u_size.nsets = -1; - cache->d_u_size.cachesize = -1; - } - - if (cache->separate) { - size = (cache_type_reg & 0x1c0) >> 6; - assoc = (cache_type_reg & 0x38) >> 3; - M = (cache_type_reg & 0x4) >> 2; - len = (cache_type_reg & 0x3); - multiplier = 2 + M; - - if ((assoc != 0) || (M != 1)) /* assoc 0 and M 1 means cache absent */ { - /* cache is present */ - cache->i_size.linelen = 1 << (len + 3); - cache->i_size.associativity = multiplier << (assoc - 1); - cache->i_size.nsets = 1 << (size + 6 - assoc - len); - cache->i_size.cachesize = multiplier << (size + 8); - } else { - /* cache is absent */ - cache->i_size.linelen = -1; - cache->i_size.associativity = -1; - cache->i_size.nsets = -1; - cache->i_size.cachesize = -1; - } - } else - cache->i_size = cache->d_u_size; - - return ERROR_OK; -} - -int armv4_5_handle_cache_info_command(struct command_context *cmd_ctx, struct armv4_5_cache_common *armv4_5_cache) -{ - if (armv4_5_cache->ctype == -1) { - command_print(cmd_ctx, "cache not yet identified"); - return ERROR_OK; - } - - command_print(cmd_ctx, "cache type: 0x%1.1x, %s", armv4_5_cache->ctype, - (armv4_5_cache->separate) ? "separate caches" : "unified cache"); - - command_print(cmd_ctx, "D-Cache: linelen %i, associativity %i, nsets %i, cachesize 0x%x", - armv4_5_cache->d_u_size.linelen, - armv4_5_cache->d_u_size.associativity, - armv4_5_cache->d_u_size.nsets, - armv4_5_cache->d_u_size.cachesize); - - command_print(cmd_ctx, "I-Cache: linelen %i, associativity %i, nsets %i, cachesize 0x%x", - armv4_5_cache->i_size.linelen, - armv4_5_cache->i_size.associativity, - armv4_5_cache->i_size.nsets, - armv4_5_cache->i_size.cachesize); - - return ERROR_OK; -} diff --git a/src/target/armv4_5_cache.h b/src/target/armv4_5_cache.h deleted file mode 100644 index 2fd1ca387..000000000 --- a/src/target/armv4_5_cache.h +++ /dev/null @@ -1,55 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifndef OPENOCD_TARGET_ARMV4_5_CACHE_H -#define OPENOCD_TARGET_ARMV4_5_CACHE_H - -struct command_context; - -struct armv4_5_cachesize { - int linelen; - int associativity; - int nsets; - int cachesize; -}; - -struct armv4_5_cache_common { - int ctype; /* specify supported cache operations */ - int separate; /* separate caches or unified cache */ - struct armv4_5_cachesize d_u_size; /* data cache */ - struct armv4_5_cachesize i_size; /* instruction cache */ - int i_cache_enabled; - int d_u_cache_enabled; -}; - -int armv4_5_identify_cache(uint32_t cache_type_reg, - struct armv4_5_cache_common *cache); -int armv4_5_cache_state(uint32_t cp15_control_reg, - struct armv4_5_cache_common *cache); - -int armv4_5_handle_cache_info_command(struct command_context *cmd_ctx, - struct armv4_5_cache_common *armv4_5_cache); - -enum { - ARMV4_5_D_U_CACHE_ENABLED = 0x4, - ARMV4_5_I_CACHE_ENABLED = 0x1000, - ARMV4_5_WRITE_BUFFER_ENABLED = 0x8, - ARMV4_5_CACHE_RR_BIT = 0x5000, -}; - -#endif /* OPENOCD_TARGET_ARMV4_5_CACHE_H */ diff --git a/src/target/armv4_5_mmu.c b/src/target/armv4_5_mmu.c deleted file mode 100644 index 115a48950..000000000 --- a/src/target/armv4_5_mmu.c +++ /dev/null @@ -1,169 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include "target.h" -#include "armv4_5_mmu.h" - -int armv4_5_mmu_translate_va(struct target *target, - struct armv4_5_mmu_common *armv4_5_mmu, uint32_t va, uint32_t *cb, uint32_t *val) -{ - uint32_t first_lvl_descriptor = 0x0; - uint32_t second_lvl_descriptor = 0x0; - uint32_t ttb; - int retval; - retval = armv4_5_mmu->get_ttb(target, &ttb); - if (retval != ERROR_OK) - return retval; - - retval = armv4_5_mmu_read_physical(target, armv4_5_mmu, - (ttb & 0xffffc000) | ((va & 0xfff00000) >> 18), - 4, 1, (uint8_t *)&first_lvl_descriptor); - if (retval != ERROR_OK) - return retval; - first_lvl_descriptor = target_buffer_get_u32(target, (uint8_t *)&first_lvl_descriptor); - - LOG_DEBUG("1st lvl desc: %8.8" PRIx32 "", first_lvl_descriptor); - - if ((first_lvl_descriptor & 0x3) == 0) { - LOG_ERROR("Address translation failure"); - return ERROR_TARGET_TRANSLATION_FAULT; - } - - if (!armv4_5_mmu->has_tiny_pages && ((first_lvl_descriptor & 0x3) == 3)) { - LOG_ERROR("Address translation failure"); - return ERROR_TARGET_TRANSLATION_FAULT; - } - - if ((first_lvl_descriptor & 0x3) == 2) { - /* section descriptor */ - *cb = (first_lvl_descriptor & 0xc) >> 2; - *val = (first_lvl_descriptor & 0xfff00000) | (va & 0x000fffff); - return ERROR_OK; - } - - if ((first_lvl_descriptor & 0x3) == 1) { - /* coarse page table */ - retval = armv4_5_mmu_read_physical(target, armv4_5_mmu, - (first_lvl_descriptor & 0xfffffc00) | ((va & 0x000ff000) >> 10), - 4, 1, (uint8_t *)&second_lvl_descriptor); - if (retval != ERROR_OK) - return retval; - } else if ((first_lvl_descriptor & 0x3) == 3) { - /* fine page table */ - retval = armv4_5_mmu_read_physical(target, armv4_5_mmu, - (first_lvl_descriptor & 0xfffff000) | ((va & 0x000ffc00) >> 8), - 4, 1, (uint8_t *)&second_lvl_descriptor); - if (retval != ERROR_OK) - return retval; - } - - second_lvl_descriptor = target_buffer_get_u32(target, (uint8_t *)&second_lvl_descriptor); - - LOG_DEBUG("2nd lvl desc: %8.8" PRIx32 "", second_lvl_descriptor); - - if ((second_lvl_descriptor & 0x3) == 0) { - LOG_ERROR("Address translation failure"); - return ERROR_TARGET_TRANSLATION_FAULT; - } - - /* cacheable/bufferable is always specified in bits 3-2 */ - *cb = (second_lvl_descriptor & 0xc) >> 2; - - if ((second_lvl_descriptor & 0x3) == 1) { - /* large page descriptor */ - *val = (second_lvl_descriptor & 0xffff0000) | (va & 0x0000ffff); - return ERROR_OK; - } - - if ((second_lvl_descriptor & 0x3) == 2) { - /* small page descriptor */ - *val = (second_lvl_descriptor & 0xfffff000) | (va & 0x00000fff); - return ERROR_OK; - } - - if ((second_lvl_descriptor & 0x3) == 3) { - /* tiny page descriptor */ - *val = (second_lvl_descriptor & 0xfffffc00) | (va & 0x000003ff); - return ERROR_OK; - } - - /* should not happen */ - LOG_ERROR("Address translation failure"); - return ERROR_TARGET_TRANSLATION_FAULT; -} - -int armv4_5_mmu_read_physical(struct target *target, - struct armv4_5_mmu_common *armv4_5_mmu, uint32_t address, - uint32_t size, uint32_t count, uint8_t *buffer) -{ - int retval; - - if (target->state != TARGET_HALTED) - return ERROR_TARGET_NOT_HALTED; - - /* disable MMU and data (or unified) cache */ - retval = armv4_5_mmu->disable_mmu_caches(target, 1, 1, 0); - if (retval != ERROR_OK) - return retval; - - retval = armv4_5_mmu->read_memory(target, address, size, count, buffer); - if (retval != ERROR_OK) - return retval; - - /* reenable MMU / cache */ - retval = armv4_5_mmu->enable_mmu_caches(target, armv4_5_mmu->mmu_enabled, - armv4_5_mmu->armv4_5_cache.d_u_cache_enabled, - armv4_5_mmu->armv4_5_cache.i_cache_enabled); - if (retval != ERROR_OK) - return retval; - - return retval; -} - -int armv4_5_mmu_write_physical(struct target *target, - struct armv4_5_mmu_common *armv4_5_mmu, uint32_t address, - uint32_t size, uint32_t count, const uint8_t *buffer) -{ - int retval; - - if (target->state != TARGET_HALTED) - return ERROR_TARGET_NOT_HALTED; - - /* disable MMU and data (or unified) cache */ - retval = armv4_5_mmu->disable_mmu_caches(target, 1, 1, 0); - if (retval != ERROR_OK) - return retval; - - retval = armv4_5_mmu->write_memory(target, address, size, count, buffer); - if (retval != ERROR_OK) - return retval; - - /* reenable MMU / cache */ - retval = armv4_5_mmu->enable_mmu_caches(target, armv4_5_mmu->mmu_enabled, - armv4_5_mmu->armv4_5_cache.d_u_cache_enabled, - armv4_5_mmu->armv4_5_cache.i_cache_enabled); - if (retval != ERROR_OK) - return retval; - - return retval; -} diff --git a/src/target/armv4_5_mmu.h b/src/target/armv4_5_mmu.h deleted file mode 100644 index 0f5212142..000000000 --- a/src/target/armv4_5_mmu.h +++ /dev/null @@ -1,56 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifndef OPENOCD_TARGET_ARMV4_5_MMU_H -#define OPENOCD_TARGET_ARMV4_5_MMU_H - -#include "armv4_5_cache.h" - -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 (*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; - int has_tiny_pages; - int mmu_enabled; -}; - -int armv4_5_mmu_translate_va(struct target *target, - struct armv4_5_mmu_common *armv4_5_mmu, uint32_t va, - uint32_t *cb, uint32_t *val); - -int armv4_5_mmu_read_physical(struct target *target, - struct armv4_5_mmu_common *armv4_5_mmu, - uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer); - -int armv4_5_mmu_write_physical(struct target *target, - struct armv4_5_mmu_common *armv4_5_mmu, - uint32_t address, uint32_t size, uint32_t count, const uint8_t *buffer); - -enum { - ARMV4_5_MMU_ENABLED = 0x1, - ARMV4_5_ALIGNMENT_CHECK = 0x2, - ARMV4_5_MMU_S_BIT = 0x100, - ARMV4_5_MMU_R_BIT = 0x200 -}; - -#endif /* OPENOCD_TARGET_ARMV4_5_MMU_H */ diff --git a/src/target/armv7a.c b/src/target/armv7a.c deleted file mode 100644 index 37eb1b5f1..000000000 --- a/src/target/armv7a.c +++ /dev/null @@ -1,769 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2009 by David Brownell * - * * - * Copyright (C) ST-Ericsson SA 2011 michel.jaouen@stericsson.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include - -#include "armv7a.h" -#include "arm_disassembler.h" - -#include "register.h" -#include -#include - -#include -#include -#include - -#include "arm_opcodes.h" -#include "target.h" -#include "target_type.h" - -static void armv7a_show_fault_registers(struct target *target) -{ - uint32_t dfsr, ifsr, dfar, ifar; - struct armv7a_common *armv7a = target_to_armv7a(target); - struct arm_dpm *dpm = armv7a->arm.dpm; - int retval; - - retval = dpm->prepare(dpm); - if (retval != ERROR_OK) - return; - - /* ARMV4_5_MRC(cpnum, op1, r0, CRn, CRm, op2) */ - - /* c5/c0 - {data, instruction} fault status registers */ - retval = dpm->instr_read_data_r0(dpm, - ARMV4_5_MRC(15, 0, 0, 5, 0, 0), - &dfsr); - if (retval != ERROR_OK) - goto done; - - retval = dpm->instr_read_data_r0(dpm, - ARMV4_5_MRC(15, 0, 0, 5, 0, 1), - &ifsr); - if (retval != ERROR_OK) - goto done; - - /* c6/c0 - {data, instruction} fault address registers */ - retval = dpm->instr_read_data_r0(dpm, - ARMV4_5_MRC(15, 0, 0, 6, 0, 0), - &dfar); - if (retval != ERROR_OK) - goto done; - - retval = dpm->instr_read_data_r0(dpm, - ARMV4_5_MRC(15, 0, 0, 6, 0, 2), - &ifar); - if (retval != ERROR_OK) - goto done; - - LOG_USER("Data fault registers DFSR: %8.8" PRIx32 - ", DFAR: %8.8" PRIx32, dfsr, dfar); - LOG_USER("Instruction fault registers IFSR: %8.8" PRIx32 - ", IFAR: %8.8" PRIx32, ifsr, ifar); - -done: - /* (void) */ dpm->finish(dpm); -} - - -/* retrieve main id register */ -static int armv7a_read_midr(struct target *target) -{ - int retval = ERROR_FAIL; - struct armv7a_common *armv7a = target_to_armv7a(target); - struct arm_dpm *dpm = armv7a->arm.dpm; - uint32_t midr; - retval = dpm->prepare(dpm); - if (retval != ERROR_OK) - goto done; - /* MRC p15,0,,c0,c0,0; read main id register*/ - - retval = dpm->instr_read_data_r0(dpm, - ARMV4_5_MRC(15, 0, 0, 0, 0, 0), - &midr); - if (retval != ERROR_OK) - goto done; - - armv7a->rev = (midr & 0xf); - armv7a->partnum = (midr >> 4) & 0xfff; - armv7a->arch = (midr >> 16) & 0xf; - armv7a->variant = (midr >> 20) & 0xf; - armv7a->implementor = (midr >> 24) & 0xff; - LOG_INFO("%s rev %" PRIx32 ", partnum %" PRIx32 ", arch %" PRIx32 - ", variant %" PRIx32 ", implementor %" PRIx32, - target->cmd_name, - armv7a->rev, - armv7a->partnum, - armv7a->arch, - armv7a->variant, - armv7a->implementor); - -done: - dpm->finish(dpm); - return retval; -} - -static int armv7a_read_ttbcr(struct target *target) -{ - struct armv7a_common *armv7a = target_to_armv7a(target); - struct arm_dpm *dpm = armv7a->arm.dpm; - uint32_t ttbcr, ttbcr_n; - int retval = dpm->prepare(dpm); - if (retval != ERROR_OK) - goto done; - /* MRC p15,0,,c2,c0,2 ; Read CP15 Translation Table Base Control Register*/ - retval = dpm->instr_read_data_r0(dpm, - ARMV4_5_MRC(15, 0, 0, 2, 0, 2), - &ttbcr); - if (retval != ERROR_OK) - goto done; - - LOG_DEBUG("ttbcr %" PRIx32, ttbcr); - - ttbcr_n = ttbcr & 0x7; - armv7a->armv7a_mmu.ttbcr = ttbcr; - armv7a->armv7a_mmu.cached = 1; - - /* - * ARM Architecture Reference Manual (ARMv7-A and ARMv7-Redition), - * document # ARM DDI 0406C - */ - armv7a->armv7a_mmu.ttbr_range[0] = 0xffffffff >> ttbcr_n; - armv7a->armv7a_mmu.ttbr_range[1] = 0xffffffff; - armv7a->armv7a_mmu.ttbr_mask[0] = 0xffffffff << (14 - ttbcr_n); - armv7a->armv7a_mmu.ttbr_mask[1] = 0xffffffff << 14; - armv7a->armv7a_mmu.cached = 1; - - retval = armv7a_read_midr(target); - if (retval != ERROR_OK) - goto done; - - /* FIXME: why this special case based on part number? */ - if ((armv7a->partnum & 0xf) == 0) { - /* ARM DDI 0344H , ARM DDI 0407F */ - armv7a->armv7a_mmu.ttbr_mask[0] = 7 << (32 - ttbcr_n); - } - - LOG_DEBUG("ttbr1 %s, ttbr0_mask %" PRIx32 " ttbr1_mask %" PRIx32, - (ttbcr_n != 0) ? "used" : "not used", - armv7a->armv7a_mmu.ttbr_mask[0], - armv7a->armv7a_mmu.ttbr_mask[1]); - -done: - dpm->finish(dpm); - return retval; -} - -/* 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; - uint32_t second_lvl_descriptor = 0x0; - int retval; - struct armv7a_common *armv7a = target_to_armv7a(target); - struct arm_dpm *dpm = armv7a->arm.dpm; - uint32_t ttbidx = 0; /* default to ttbr0 */ - uint32_t ttb_mask; - uint32_t va_mask; - uint32_t ttbcr; - uint32_t ttb; - - retval = dpm->prepare(dpm); - if (retval != ERROR_OK) - goto done; - - /* MRC p15,0,,c2,c0,2 ; Read CP15 Translation Table Base Control Register*/ - retval = dpm->instr_read_data_r0(dpm, - ARMV4_5_MRC(15, 0, 0, 2, 0, 2), - &ttbcr); - if (retval != ERROR_OK) - goto done; - - /* if ttbcr has changed or was not read before, re-read the information */ - if ((armv7a->armv7a_mmu.cached == 0) || - (armv7a->armv7a_mmu.ttbcr != ttbcr)) { - armv7a_read_ttbcr(target); - } - - /* if va is above the range handled by ttbr0, select ttbr1 */ - if (va > armv7a->armv7a_mmu.ttbr_range[0]) { - /* select ttb 1 */ - ttbidx = 1; - } - /* MRC p15,0,,c2,c0,ttbidx */ - retval = dpm->instr_read_data_r0(dpm, - ARMV4_5_MRC(15, 0, 0, 2, 0, ttbidx), - &ttb); - if (retval != ERROR_OK) - return retval; - - ttb_mask = armv7a->armv7a_mmu.ttbr_mask[ttbidx]; - va_mask = 0xfff00000 & armv7a->armv7a_mmu.ttbr_range[ttbidx]; - - LOG_DEBUG("ttb_mask %" PRIx32 " va_mask %" PRIx32 " ttbidx %i", - ttb_mask, va_mask, ttbidx); - retval = armv7a->armv7a_mmu.read_physical_memory(target, - (ttb & ttb_mask) | ((va & va_mask) >> 18), - 4, 1, (uint8_t *)&first_lvl_descriptor); - if (retval != ERROR_OK) - return retval; - first_lvl_descriptor = target_buffer_get_u32(target, (uint8_t *) - &first_lvl_descriptor); - /* reuse armv4_5 piece of code, specific armv7a changes may come later */ - LOG_DEBUG("1st lvl desc: %8.8" PRIx32 "", first_lvl_descriptor); - - if ((first_lvl_descriptor & 0x3) == 0) { - LOG_ERROR("Address translation failure"); - return ERROR_TARGET_TRANSLATION_FAULT; - } - - - if ((first_lvl_descriptor & 0x40002) == 2) { - /* section descriptor */ - *val = (first_lvl_descriptor & 0xfff00000) | (va & 0x000fffff); - return ERROR_OK; - } else if ((first_lvl_descriptor & 0x40002) == 0x40002) { - /* supersection descriptor */ - if (first_lvl_descriptor & 0x00f001e0) { - LOG_ERROR("Physical address does not fit into 32 bits"); - return ERROR_TARGET_TRANSLATION_FAULT; - } - *val = (first_lvl_descriptor & 0xff000000) | (va & 0x00ffffff); - return ERROR_OK; - } - - /* page table */ - retval = armv7a->armv7a_mmu.read_physical_memory(target, - (first_lvl_descriptor & 0xfffffc00) | ((va & 0x000ff000) >> 10), - 4, 1, (uint8_t *)&second_lvl_descriptor); - if (retval != ERROR_OK) - return retval; - - second_lvl_descriptor = target_buffer_get_u32(target, (uint8_t *) - &second_lvl_descriptor); - - LOG_DEBUG("2nd lvl desc: %8.8" PRIx32 "", second_lvl_descriptor); - - if ((second_lvl_descriptor & 0x3) == 0) { - LOG_ERROR("Address translation failure"); - return ERROR_TARGET_TRANSLATION_FAULT; - } - - if ((second_lvl_descriptor & 0x3) == 1) { - /* large page descriptor */ - *val = (second_lvl_descriptor & 0xffff0000) | (va & 0x0000ffff); - } else { - /* small page descriptor */ - *val = (second_lvl_descriptor & 0xfffff000) | (va & 0x00000fff); - } - - return ERROR_OK; - -done: - return retval; -} - -/* V7 method VA TO PA */ -int armv7a_mmu_translate_va_pa(struct target *target, uint32_t va, - uint32_t *val, int meminfo) -{ - int retval = ERROR_FAIL; - struct armv7a_common *armv7a = target_to_armv7a(target); - struct arm_dpm *dpm = armv7a->arm.dpm; - uint32_t virt = va & ~0xfff; - uint32_t NOS, NS, INNER, OUTER; - *val = 0xdeadbeef; - retval = dpm->prepare(dpm); - if (retval != ERROR_OK) - goto done; - /* mmu must be enable in order to get a correct translation - * use VA to PA CP15 register for conversion */ - retval = dpm->instr_write_data_r0(dpm, - ARMV4_5_MCR(15, 0, 0, 7, 8, 0), - virt); - if (retval != ERROR_OK) - goto done; - retval = dpm->instr_read_data_r0(dpm, - ARMV4_5_MRC(15, 0, 0, 7, 4, 0), - val); - /* decode memory attribute */ - NOS = (*val >> 10) & 1; /* Not Outer shareable */ - NS = (*val >> 9) & 1; /* Non secure */ - INNER = (*val >> 4) & 0x7; - OUTER = (*val >> 2) & 0x3; - - if (retval != ERROR_OK) - goto done; - *val = (*val & ~0xfff) + (va & 0xfff); - if (*val == va) - LOG_WARNING("virt = phys : MMU disable !!"); - if (meminfo) { - LOG_INFO("%" PRIx32 " : %" PRIx32 " %s outer shareable %s secured", - va, *val, - NOS == 1 ? "not" : " ", - NS == 1 ? "not" : ""); - switch (OUTER) { - case 0: - LOG_INFO("outer: Non-Cacheable"); - break; - case 1: - LOG_INFO("outer: Write-Back, Write-Allocate"); - break; - case 2: - LOG_INFO("outer: Write-Through, No Write-Allocate"); - break; - case 3: - LOG_INFO("outer: Write-Back, no Write-Allocate"); - break; - } - switch (INNER) { - case 0: - LOG_INFO("inner: Non-Cacheable"); - break; - case 1: - LOG_INFO("inner: Strongly-ordered"); - break; - case 3: - LOG_INFO("inner: Device"); - break; - case 5: - LOG_INFO("inner: Write-Back, Write-Allocate"); - break; - case 6: - LOG_INFO("inner: Write-Through"); - break; - case 7: - LOG_INFO("inner: Write-Back, no Write-Allocate"); - - default: - LOG_INFO("inner: %" PRIx32 " ???", INNER); - } - } - -done: - dpm->finish(dpm); - - return retval; -} - -/* FIXME: remove it */ -static int armv7a_l2x_cache_init(struct target *target, uint32_t base, uint32_t way) -{ - struct armv7a_l2x_cache *l2x_cache; - struct target_list *head = target->head; - struct target *curr; - - struct armv7a_common *armv7a = target_to_armv7a(target); - l2x_cache = calloc(1, sizeof(struct armv7a_l2x_cache)); - l2x_cache->base = base; - l2x_cache->way = way; - /*LOG_INFO("cache l2 initialized base %x way %d", - l2x_cache->base,l2x_cache->way);*/ - if (armv7a->armv7a_mmu.armv7a_cache.outer_cache) - LOG_INFO("outer cache already initialized\n"); - armv7a->armv7a_mmu.armv7a_cache.outer_cache = l2x_cache; - /* initialize all target in this cluster (smp target) - * l2 cache must be configured after smp declaration */ - while (head != (struct target_list *)NULL) { - curr = head->target; - if (curr != target) { - armv7a = target_to_armv7a(curr); - if (armv7a->armv7a_mmu.armv7a_cache.outer_cache) - LOG_ERROR("smp target : outer cache already initialized\n"); - armv7a->armv7a_mmu.armv7a_cache.outer_cache = l2x_cache; - } - head = head->next; - } - return JIM_OK; -} - -/* FIXME: remove it */ -COMMAND_HANDLER(handle_cache_l2x) -{ - struct target *target = get_current_target(CMD_CTX); - uint32_t base, way; - - if (CMD_ARGC != 2) - return ERROR_COMMAND_SYNTAX_ERROR; - - /* command_print(CMD_CTX, "%s %s", CMD_ARGV[0], CMD_ARGV[1]); */ - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], base); - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], way); - - /* AP address is in bits 31:24 of DP_SELECT */ - armv7a_l2x_cache_init(target, base, way); - - return ERROR_OK; -} - -int armv7a_handle_cache_info_command(struct command_context *cmd_ctx, - struct armv7a_cache_common *armv7a_cache) -{ - struct armv7a_l2x_cache *l2x_cache = (struct armv7a_l2x_cache *) - (armv7a_cache->outer_cache); - - int cl; - - if (armv7a_cache->info == -1) { - command_print(cmd_ctx, "cache not yet identified"); - return ERROR_OK; - } - - for (cl = 0; cl < armv7a_cache->loc; cl++) { - struct armv7a_arch_cache *arch = &(armv7a_cache->arch[cl]); - - if (arch->ctype & 1) { - command_print(cmd_ctx, - "L%d I-Cache: linelen %" PRIi32 - ", associativity %" PRIi32 - ", nsets %" PRIi32 - ", cachesize %" PRId32 " KBytes", - cl+1, - arch->i_size.linelen, - arch->i_size.associativity, - arch->i_size.nsets, - arch->i_size.cachesize); - } - - if (arch->ctype >= 2) { - command_print(cmd_ctx, - "L%d D-Cache: linelen %" PRIi32 - ", associativity %" PRIi32 - ", nsets %" PRIi32 - ", cachesize %" PRId32 " KBytes", - cl+1, - arch->d_u_size.linelen, - arch->d_u_size.associativity, - arch->d_u_size.nsets, - arch->d_u_size.cachesize); - } - } - - if (l2x_cache != NULL) - command_print(cmd_ctx, "Outer unified cache Base Address 0x%" PRIx32 ", %" PRId32 " ways", - l2x_cache->base, l2x_cache->way); - - return ERROR_OK; -} - -/* retrieve core id cluster id */ -static int armv7a_read_mpidr(struct target *target) -{ - int retval = ERROR_FAIL; - struct armv7a_common *armv7a = target_to_armv7a(target); - struct arm_dpm *dpm = armv7a->arm.dpm; - uint32_t mpidr; - retval = dpm->prepare(dpm); - if (retval != ERROR_OK) - goto done; - /* MRC p15,0,,c0,c0,5; read Multiprocessor ID register*/ - - retval = dpm->instr_read_data_r0(dpm, - ARMV4_5_MRC(15, 0, 0, 0, 0, 5), - &mpidr); - if (retval != ERROR_OK) - goto done; - - /* ARMv7R uses a different format for MPIDR. - * When configured uniprocessor (most R cores) it reads as 0. - * This will need to be implemented for multiprocessor ARMv7R cores. */ - if (armv7a->is_armv7r) { - if (mpidr) - LOG_ERROR("MPIDR nonzero in ARMv7-R target"); - goto done; - } - - if (mpidr & 1<<31) { - armv7a->multi_processor_system = (mpidr >> 30) & 1; - armv7a->cluster_id = (mpidr >> 8) & 0xf; - armv7a->cpu_id = mpidr & 0x3; - LOG_INFO("%s cluster %x core %x %s", target_name(target), - armv7a->cluster_id, - armv7a->cpu_id, - armv7a->multi_processor_system == 0 ? "multi core" : "mono core"); - - } else - LOG_ERROR("MPIDR not in multiprocessor format"); - -done: - dpm->finish(dpm); - return retval; - - -} - -static int get_cache_info(struct arm_dpm *dpm, int cl, int ct, uint32_t *cache_reg) -{ - int retval = ERROR_OK; - - /* select cache level */ - retval = dpm->instr_write_data_r0(dpm, - ARMV4_5_MCR(15, 2, 0, 0, 0, 0), - (cl << 1) | (ct == 1 ? 1 : 0)); - if (retval != ERROR_OK) - goto done; - - retval = dpm->instr_read_data_r0(dpm, - ARMV4_5_MRC(15, 1, 0, 0, 0, 0), - cache_reg); - done: - return retval; -} - -static struct armv7a_cachesize decode_cache_reg(uint32_t cache_reg) -{ - struct armv7a_cachesize size; - int i = 0; - - size.linelen = 16 << (cache_reg & 0x7); - size.associativity = ((cache_reg >> 3) & 0x3ff) + 1; - size.nsets = ((cache_reg >> 13) & 0x7fff) + 1; - size.cachesize = size.linelen * size.associativity * size.nsets / 1024; - - /* compute info for set way operation on cache */ - size.index_shift = (cache_reg & 0x7) + 4; - size.index = (cache_reg >> 13) & 0x7fff; - size.way = ((cache_reg >> 3) & 0x3ff); - - while (((size.way << i) & 0x80000000) == 0) - i++; - size.way_shift = i; - - return size; -} - -int armv7a_identify_cache(struct target *target) -{ - /* read cache descriptor */ - int retval = ERROR_FAIL; - struct armv7a_common *armv7a = target_to_armv7a(target); - struct arm_dpm *dpm = armv7a->arm.dpm; - uint32_t csselr, clidr, ctr; - uint32_t cache_reg; - int cl, ctype; - struct armv7a_cache_common *cache = - &(armv7a->armv7a_mmu.armv7a_cache); - - if (!armv7a->is_armv7r) - armv7a_read_ttbcr(target); - - retval = dpm->prepare(dpm); - if (retval != ERROR_OK) - goto done; - - /* retrieve CTR - * mrc p15, 0, r0, c0, c0, 1 @ read ctr */ - retval = dpm->instr_read_data_r0(dpm, - ARMV4_5_MRC(15, 0, 0, 0, 0, 1), - &ctr); - if (retval != ERROR_OK) - goto done; - - cache->iminline = 4UL << (ctr & 0xf); - cache->dminline = 4UL << ((ctr & 0xf0000) >> 16); - LOG_DEBUG("ctr %" PRIx32 " ctr.iminline %" PRId32 " ctr.dminline %" PRId32, - ctr, cache->iminline, cache->dminline); - - /* retrieve CLIDR - * mrc p15, 1, r0, c0, c0, 1 @ read clidr */ - retval = dpm->instr_read_data_r0(dpm, - ARMV4_5_MRC(15, 1, 0, 0, 0, 1), - &clidr); - if (retval != ERROR_OK) - goto done; - - cache->loc = (clidr & 0x7000000) >> 24; - LOG_DEBUG("Number of cache levels to PoC %" PRId32, cache->loc); - - /* retrieve selected cache for later restore - * MRC p15, 2,, c0, c0, 0; Read CSSELR */ - retval = dpm->instr_read_data_r0(dpm, - ARMV4_5_MRC(15, 2, 0, 0, 0, 0), - &csselr); - if (retval != ERROR_OK) - goto done; - - /* retrieve all available inner caches */ - for (cl = 0; cl < cache->loc; clidr >>= 3, cl++) { - - /* isolate cache type at current level */ - ctype = clidr & 7; - - /* skip reserved values */ - if (ctype > CACHE_LEVEL_HAS_UNIFIED_CACHE) - continue; - - /* separate d or unified d/i cache at this level ? */ - if (ctype & (CACHE_LEVEL_HAS_UNIFIED_CACHE | CACHE_LEVEL_HAS_D_CACHE)) { - /* retrieve d-cache info */ - retval = get_cache_info(dpm, cl, 0, &cache_reg); - if (retval != ERROR_OK) - goto done; - cache->arch[cl].d_u_size = decode_cache_reg(cache_reg); - - LOG_DEBUG("data/unified cache index %d << %d, way %d << %d", - cache->arch[cl].d_u_size.index, - cache->arch[cl].d_u_size.index_shift, - cache->arch[cl].d_u_size.way, - cache->arch[cl].d_u_size.way_shift); - - LOG_DEBUG("cacheline %d bytes %d KBytes asso %d ways", - cache->arch[cl].d_u_size.linelen, - cache->arch[cl].d_u_size.cachesize, - cache->arch[cl].d_u_size.associativity); - } - - /* separate i-cache at this level ? */ - if (ctype & CACHE_LEVEL_HAS_I_CACHE) { - /* retrieve i-cache info */ - retval = get_cache_info(dpm, cl, 1, &cache_reg); - if (retval != ERROR_OK) - goto done; - cache->arch[cl].i_size = decode_cache_reg(cache_reg); - - LOG_DEBUG("instruction cache index %d << %d, way %d << %d", - cache->arch[cl].i_size.index, - cache->arch[cl].i_size.index_shift, - cache->arch[cl].i_size.way, - cache->arch[cl].i_size.way_shift); - - LOG_DEBUG("cacheline %d bytes %d KBytes asso %d ways", - cache->arch[cl].i_size.linelen, - cache->arch[cl].i_size.cachesize, - cache->arch[cl].i_size.associativity); - } - - cache->arch[cl].ctype = ctype; - } - - /* restore selected cache */ - dpm->instr_write_data_r0(dpm, - ARMV4_5_MRC(15, 2, 0, 0, 0, 0), - csselr); - - if (retval != ERROR_OK) - goto done; - - /* if no l2 cache initialize l1 data cache flush function function */ - if (armv7a->armv7a_mmu.armv7a_cache.flush_all_data_cache == NULL) { - armv7a->armv7a_mmu.armv7a_cache.flush_all_data_cache = - armv7a_cache_auto_flush_all_data; - } - - armv7a->armv7a_mmu.armv7a_cache.info = 1; -done: - dpm->finish(dpm); - armv7a_read_mpidr(target); - return retval; - -} - -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; - /* target is useful in all function arm v4 5 compatible */ - armv7a->arm.target = target; - armv7a->arm.common_magic = ARM_COMMON_MAGIC; - armv7a->common_magic = ARMV7_COMMON_MAGIC; - armv7a->armv7a_mmu.armv7a_cache.info = -1; - armv7a->armv7a_mmu.armv7a_cache.outer_cache = NULL; - armv7a->armv7a_mmu.armv7a_cache.flush_all_data_cache = NULL; - armv7a->armv7a_mmu.armv7a_cache.auto_cache_enabled = 1; - return ERROR_OK; -} - -int armv7a_arch_state(struct target *target) -{ - static const char *state[] = { - "disabled", "enabled" - }; - - struct armv7a_common *armv7a = target_to_armv7a(target); - struct arm *arm = &armv7a->arm; - - if (armv7a->common_magic != ARMV7_COMMON_MAGIC) { - LOG_ERROR("BUG: called for a non-ARMv7A target"); - return ERROR_COMMAND_SYNTAX_ERROR; - } - - arm_arch_state(target); - - if (armv7a->is_armv7r) { - LOG_USER("D-Cache: %s, I-Cache: %s", - state[armv7a->armv7a_mmu.armv7a_cache.d_u_cache_enabled], - state[armv7a->armv7a_mmu.armv7a_cache.i_cache_enabled]); - } else { - LOG_USER("MMU: %s, D-Cache: %s, I-Cache: %s", - state[armv7a->armv7a_mmu.mmu_enabled], - state[armv7a->armv7a_mmu.armv7a_cache.d_u_cache_enabled], - state[armv7a->armv7a_mmu.armv7a_cache.i_cache_enabled]); - } - - if (arm->core_mode == ARM_MODE_ABT) - armv7a_show_fault_registers(target); - if (target->debug_reason == DBG_REASON_WATCHPOINT) - LOG_USER("Watchpoint triggered at PC %#08x", - (unsigned) armv7a->dpm.wp_pc); - - return ERROR_OK; -} - -static const struct command_registration l2_cache_commands[] = { - { - .name = "l2x", - .handler = handle_cache_l2x, - .mode = COMMAND_EXEC, - .help = "configure l2x cache " - "", - .usage = "[base_addr] [number_of_way]", - }, - COMMAND_REGISTRATION_DONE - -}; - -const struct command_registration l2x_cache_command_handlers[] = { - { - .name = "cache_config", - .mode = COMMAND_EXEC, - .help = "cache configuration for a target", - .usage = "", - .chain = l2_cache_commands, - }, - COMMAND_REGISTRATION_DONE -}; - -const struct command_registration armv7a_command_handlers[] = { - { - .chain = dap_command_handlers, - }, - { - .chain = l2x_cache_command_handlers, - }, - { - .chain = arm7a_cache_command_handlers, - }, - COMMAND_REGISTRATION_DONE -}; diff --git a/src/target/armv7a.h b/src/target/armv7a.h deleted file mode 100644 index 6461ba905..000000000 --- a/src/target/armv7a.h +++ /dev/null @@ -1,187 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2009 by David Brownell * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifndef OPENOCD_TARGET_ARMV7A_H -#define OPENOCD_TARGET_ARMV7A_H - -#include "arm_adi_v5.h" -#include "armv7a_cache.h" -#include "arm.h" -#include "armv4_5_mmu.h" -#include "armv4_5_cache.h" -#include "arm_dpm.h" - -enum { - ARM_PC = 15, - ARM_CPSR = 16 -}; - -#define ARMV7_COMMON_MAGIC 0x0A450999 - -/* VA to PA translation operations opc2 values*/ -#define V2PCWPR 0 -#define V2PCWPW 1 -#define V2PCWUR 2 -#define V2PCWUW 3 -#define V2POWPR 4 -#define V2POWPW 5 -#define V2POWUR 6 -#define V2POWUW 7 -/* L210/L220 cache controller support */ -struct armv7a_l2x_cache { - uint32_t base; - uint32_t way; -}; - -struct armv7a_cachesize { - uint32_t level_num; - /* cache dimensionning */ - uint32_t linelen; - uint32_t associativity; - uint32_t nsets; - uint32_t cachesize; - /* info for set way operation on cache */ - uint32_t index; - uint32_t index_shift; - uint32_t way; - uint32_t way_shift; -}; - -/* information about one architecture cache at any level */ -struct armv7a_arch_cache { - int ctype; /* cache type, CLIDR encoding */ - struct armv7a_cachesize d_u_size; /* data cache */ - struct armv7a_cachesize i_size; /* instruction cache */ -}; - -/* common cache information */ -struct armv7a_cache_common { - int info; /* -1 invalid, else valid */ - int loc; /* level of coherency */ - uint32_t dminline; /* minimum d-cache linelen */ - uint32_t iminline; /* minimum i-cache linelen */ - struct armv7a_arch_cache arch[6]; /* cache info, L1 - L7 */ - int i_cache_enabled; - int d_u_cache_enabled; - int auto_cache_enabled; /* openocd automatic - * cache handling */ - /* outer unified cache if some */ - void *outer_cache; - int (*flush_all_data_cache)(struct target *target); -}; - -struct armv7a_mmu_common { - /* following field mmu working way */ - int32_t cached; /* 0: not initialized, 1: initialized */ - uint32_t ttbcr; /* cache for ttbcr register */ - uint32_t ttbr_mask[2]; - uint32_t ttbr_range[2]; - - int (*read_physical_memory)(struct target *target, uint32_t address, uint32_t size, - uint32_t count, uint8_t *buffer); - struct armv7a_cache_common armv7a_cache; - uint32_t mmu_enabled; -}; - -struct armv7a_common { - struct arm arm; - int common_magic; - struct reg_cache *core_cache; - - /* Core Debug Unit */ - struct arm_dpm dpm; - uint32_t debug_base; - struct adiv5_ap *debug_ap; - struct adiv5_ap *memory_ap; - bool memory_ap_available; - /* mdir */ - uint8_t multi_processor_system; - uint8_t cluster_id; - uint8_t cpu_id; - bool is_armv7r; - uint32_t rev; - uint32_t partnum; - uint32_t arch; - uint32_t variant; - uint32_t implementor; - - /* cache specific to V7 Memory Management Unit compatible with v4_5*/ - struct armv7a_mmu_common armv7a_mmu; - - int (*examine_debug_reason)(struct target *target); - int (*post_debug_entry)(struct target *target); - - void (*pre_restore_context)(struct target *target); -}; - -static inline struct armv7a_common * -target_to_armv7a(struct target *target) -{ - return container_of(target->arch_info, struct armv7a_common, arm); -} - -/* register offsets from armv7a.debug_base */ - -/* See ARMv7a arch spec section C10.2 */ -#define CPUDBG_DIDR 0x000 - -/* See ARMv7a arch spec section C10.3 */ -#define CPUDBG_WFAR 0x018 -/* PCSR at 0x084 -or- 0x0a0 -or- both ... based on flags in DIDR */ -#define CPUDBG_DSCR 0x088 -#define CPUDBG_DRCR 0x090 -#define CPUDBG_PRCR 0x310 -#define CPUDBG_PRSR 0x314 - -/* See ARMv7a arch spec section C10.4 */ -#define CPUDBG_DTRRX 0x080 -#define CPUDBG_ITR 0x084 -#define CPUDBG_DTRTX 0x08c - -/* See ARMv7a arch spec section C10.5 */ -#define CPUDBG_BVR_BASE 0x100 -#define CPUDBG_BCR_BASE 0x140 -#define CPUDBG_WVR_BASE 0x180 -#define CPUDBG_WCR_BASE 0x1C0 -#define CPUDBG_VCR 0x01C - -/* See ARMv7a arch spec section C10.6 */ -#define CPUDBG_OSLAR 0x300 -#define CPUDBG_OSLSR 0x304 -#define CPUDBG_OSSRR 0x308 -#define CPUDBG_ECR 0x024 - -/* See ARMv7a arch spec section C10.7 */ -#define CPUDBG_DSCCR 0x028 -#define CPUDBG_DSMCR 0x02C - -/* See ARMv7a arch spec section C10.8 */ -#define CPUDBG_AUTHSTATUS 0xFB8 - -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); -int armv7a_mmu_translate_va_pa(struct target *target, uint32_t va, - uint32_t *val, int meminfo); -int armv7a_mmu_translate_va(struct target *target, uint32_t va, uint32_t *val); - -int armv7a_handle_cache_info_command(struct command_context *cmd_ctx, - struct armv7a_cache_common *armv7a_cache); - -extern const struct command_registration armv7a_command_handlers[]; - -#endif /* OPENOCD_TARGET_ARMV7A_H */ diff --git a/src/target/armv7a_cache.c b/src/target/armv7a_cache.c deleted file mode 100644 index 7af3e6d4e..000000000 --- a/src/target/armv7a_cache.c +++ /dev/null @@ -1,610 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2015 by Oleksij Rempel * - * linux@rempel-privat.de * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "jtag/interface.h" -#include "arm.h" -#include "armv7a.h" -#include "armv7a_cache.h" -#include -#include "arm_opcodes.h" - -static int armv7a_l1_d_cache_sanity_check(struct target *target) -{ - struct armv7a_common *armv7a = target_to_armv7a(target); - - if (target->state != TARGET_HALTED) { - LOG_ERROR("%s: target not halted", __func__); - return ERROR_TARGET_NOT_HALTED; - } - - /* check that cache data is on at target halt */ - if (!armv7a->armv7a_mmu.armv7a_cache.d_u_cache_enabled) { - LOG_DEBUG("data cache is not enabled"); - return ERROR_TARGET_INVALID; - } - - return ERROR_OK; -} - -static int armv7a_l1_i_cache_sanity_check(struct target *target) -{ - struct armv7a_common *armv7a = target_to_armv7a(target); - - if (target->state != TARGET_HALTED) { - LOG_ERROR("%s: target not halted", __func__); - return ERROR_TARGET_NOT_HALTED; - } - - /* check that cache data is on at target halt */ - if (!armv7a->armv7a_mmu.armv7a_cache.i_cache_enabled) { - LOG_DEBUG("instruction cache is not enabled"); - return ERROR_TARGET_INVALID; - } - - return ERROR_OK; -} - -static int armv7a_l1_d_cache_flush_level(struct arm_dpm *dpm, struct armv7a_cachesize *size, int cl) -{ - int retval = ERROR_OK; - int32_t c_way, c_index = size->index; - - LOG_DEBUG("cl %" PRId32, cl); - do { - c_way = size->way; - do { - uint32_t value = (c_index << size->index_shift) - | (c_way << size->way_shift) | (cl << 1); - /* - * DCCISW - Clean and invalidate data cache - * line by Set/Way. - */ - retval = dpm->instr_write_data_r0(dpm, - ARMV4_5_MCR(15, 0, 0, 7, 14, 2), - value); - if (retval != ERROR_OK) - goto done; - c_way -= 1; - } while (c_way >= 0); - c_index -= 1; - } while (c_index >= 0); - - done: - return retval; -} - -static int armv7a_l1_d_cache_clean_inval_all(struct target *target) -{ - struct armv7a_common *armv7a = target_to_armv7a(target); - struct armv7a_cache_common *cache = &(armv7a->armv7a_mmu.armv7a_cache); - struct arm_dpm *dpm = armv7a->arm.dpm; - int cl; - int retval; - - retval = armv7a_l1_d_cache_sanity_check(target); - if (retval != ERROR_OK) - return retval; - - retval = dpm->prepare(dpm); - if (retval != ERROR_OK) - goto done; - - for (cl = 0; cl < cache->loc; cl++) { - /* skip i-only caches */ - if (cache->arch[cl].ctype < CACHE_LEVEL_HAS_D_CACHE) - continue; - - armv7a_l1_d_cache_flush_level(dpm, &cache->arch[cl].d_u_size, cl); - } - - retval = dpm->finish(dpm); - return retval; - -done: - LOG_ERROR("clean invalidate failed"); - dpm->finish(dpm); - - return retval; -} - -int armv7a_cache_auto_flush_all_data(struct target *target) -{ - int retval = ERROR_FAIL; - struct armv7a_common *armv7a = target_to_armv7a(target); - - if (!armv7a->armv7a_mmu.armv7a_cache.auto_cache_enabled) - return ERROR_OK; - - if (target->smp) { - struct target_list *head; - struct target *curr; - head = target->head; - while (head != (struct target_list *)NULL) { - curr = head->target; - if (curr->state == TARGET_HALTED) - retval = armv7a_l1_d_cache_clean_inval_all(curr); - - head = head->next; - } - } else - retval = armv7a_l1_d_cache_clean_inval_all(target); - - /* do outer cache flushing after inner caches have been flushed */ - retval = arm7a_l2x_flush_all_data(target); - - return retval; -} - - -int armv7a_l1_d_cache_inval_virt(struct target *target, uint32_t virt, - uint32_t size) -{ - struct armv7a_common *armv7a = target_to_armv7a(target); - struct arm_dpm *dpm = armv7a->arm.dpm; - struct armv7a_cache_common *armv7a_cache = &armv7a->armv7a_mmu.armv7a_cache; - uint32_t linelen = armv7a_cache->dminline; - uint32_t va_line, va_end; - int retval; - - retval = armv7a_l1_d_cache_sanity_check(target); - if (retval != ERROR_OK) - return retval; - - retval = dpm->prepare(dpm); - if (retval != ERROR_OK) - goto done; - - va_line = virt & (-linelen); - va_end = virt + size; - - /* handle unaligned start */ - if (virt != va_line) { - /* DCCIMVAC */ - retval = dpm->instr_write_data_r0(dpm, - ARMV4_5_MCR(15, 0, 0, 7, 14, 1), va_line); - if (retval != ERROR_OK) - goto done; - va_line += linelen; - } - - /* handle unaligned end */ - if ((va_end & (linelen-1)) != 0) { - va_end &= (-linelen); - /* DCCIMVAC */ - retval = dpm->instr_write_data_r0(dpm, - ARMV4_5_MCR(15, 0, 0, 7, 14, 1), va_end); - if (retval != ERROR_OK) - goto done; - } - - while (va_line < va_end) { - /* DCIMVAC - Invalidate data cache line by VA to PoC. */ - retval = dpm->instr_write_data_r0(dpm, - ARMV4_5_MCR(15, 0, 0, 7, 6, 1), va_line); - if (retval != ERROR_OK) - goto done; - va_line += linelen; - } - - dpm->finish(dpm); - return retval; - -done: - LOG_ERROR("d-cache invalidate failed"); - dpm->finish(dpm); - - return retval; -} - -int armv7a_l1_d_cache_clean_virt(struct target *target, uint32_t virt, - unsigned int size) -{ - struct armv7a_common *armv7a = target_to_armv7a(target); - struct arm_dpm *dpm = armv7a->arm.dpm; - struct armv7a_cache_common *armv7a_cache = &armv7a->armv7a_mmu.armv7a_cache; - uint32_t linelen = armv7a_cache->dminline; - uint32_t va_line, va_end; - int retval; - - retval = armv7a_l1_d_cache_sanity_check(target); - if (retval != ERROR_OK) - return retval; - - retval = dpm->prepare(dpm); - if (retval != ERROR_OK) - goto done; - - va_line = virt & (-linelen); - va_end = virt + size; - - while (va_line < va_end) { - /* DCCMVAC - Data Cache Clean by MVA to PoC */ - retval = dpm->instr_write_data_r0(dpm, - ARMV4_5_MCR(15, 0, 0, 7, 10, 1), va_line); - if (retval != ERROR_OK) - goto done; - va_line += linelen; - } - - dpm->finish(dpm); - return retval; - -done: - LOG_ERROR("d-cache invalidate failed"); - dpm->finish(dpm); - - return retval; -} - -int armv7a_l1_d_cache_flush_virt(struct target *target, uint32_t virt, - unsigned int size) -{ - struct armv7a_common *armv7a = target_to_armv7a(target); - struct arm_dpm *dpm = armv7a->arm.dpm; - struct armv7a_cache_common *armv7a_cache = &armv7a->armv7a_mmu.armv7a_cache; - uint32_t linelen = armv7a_cache->dminline; - uint32_t va_line, va_end; - int retval; - - retval = armv7a_l1_d_cache_sanity_check(target); - if (retval != ERROR_OK) - return retval; - - retval = dpm->prepare(dpm); - if (retval != ERROR_OK) - goto done; - - va_line = virt & (-linelen); - va_end = virt + size; - - while (va_line < va_end) { - /* DCCIMVAC */ - retval = dpm->instr_write_data_r0(dpm, - ARMV4_5_MCR(15, 0, 0, 7, 14, 1), va_line); - if (retval != ERROR_OK) - goto done; - va_line += linelen; - } - - dpm->finish(dpm); - return retval; - -done: - LOG_ERROR("d-cache invalidate failed"); - dpm->finish(dpm); - - return retval; -} - -int armv7a_l1_i_cache_inval_all(struct target *target) -{ - struct armv7a_common *armv7a = target_to_armv7a(target); - struct arm_dpm *dpm = armv7a->arm.dpm; - int retval; - - retval = armv7a_l1_i_cache_sanity_check(target); - if (retval != ERROR_OK) - return retval; - - retval = dpm->prepare(dpm); - if (retval != ERROR_OK) - goto done; - - if (target->smp) { - /* ICIALLUIS */ - retval = dpm->instr_write_data_r0(dpm, - ARMV4_5_MCR(15, 0, 0, 7, 1, 0), 0); - } else { - /* ICIALLU */ - retval = dpm->instr_write_data_r0(dpm, - ARMV4_5_MCR(15, 0, 0, 7, 5, 0), 0); - } - - if (retval != ERROR_OK) - goto done; - - dpm->finish(dpm); - return retval; - -done: - LOG_ERROR("i-cache invalidate failed"); - dpm->finish(dpm); - - return retval; -} - -int armv7a_l1_i_cache_inval_virt(struct target *target, uint32_t virt, - uint32_t size) -{ - struct armv7a_common *armv7a = target_to_armv7a(target); - struct arm_dpm *dpm = armv7a->arm.dpm; - struct armv7a_cache_common *armv7a_cache = - &armv7a->armv7a_mmu.armv7a_cache; - uint32_t linelen = armv7a_cache->iminline; - uint32_t va_line, va_end; - int retval; - - retval = armv7a_l1_i_cache_sanity_check(target); - if (retval != ERROR_OK) - return retval; - - retval = dpm->prepare(dpm); - if (retval != ERROR_OK) - goto done; - - va_line = virt & (-linelen); - va_end = virt + size; - - while (va_line < va_end) { - /* ICIMVAU - Invalidate instruction cache by VA to PoU. */ - retval = dpm->instr_write_data_r0(dpm, - ARMV4_5_MCR(15, 0, 0, 7, 5, 1), va_line); - if (retval != ERROR_OK) - goto done; - /* BPIMVA */ - retval = dpm->instr_write_data_r0(dpm, - ARMV4_5_MCR(15, 0, 0, 7, 5, 7), va_line); - if (retval != ERROR_OK) - goto done; - va_line += linelen; - } - return retval; - -done: - LOG_ERROR("i-cache invalidate failed"); - dpm->finish(dpm); - - return retval; -} - -int armv7a_cache_flush_virt(struct target *target, uint32_t virt, - uint32_t size) -{ - armv7a_l1_d_cache_flush_virt(target, virt, size); - armv7a_l2x_cache_flush_virt(target, virt, size); - - return ERROR_OK; -} - -/* - * We assume that target core was chosen correctly. It means if same data - * was handled by two cores, other core will loose the changes. Since it - * is impossible to know (FIXME) which core has correct data, keep in mind - * that some kind of data lost or korruption is possible. - * Possible scenario: - * - core1 loaded and changed data on 0x12345678 - * - we halted target and modified same data on core0 - * - data on core1 will be lost. - */ -int armv7a_cache_auto_flush_on_write(struct target *target, uint32_t virt, - uint32_t size) -{ - struct armv7a_common *armv7a = target_to_armv7a(target); - - if (!armv7a->armv7a_mmu.armv7a_cache.auto_cache_enabled) - return ERROR_OK; - - return armv7a_cache_flush_virt(target, virt, size); -} - -COMMAND_HANDLER(arm7a_l1_cache_info_cmd) -{ - struct target *target = get_current_target(CMD_CTX); - struct armv7a_common *armv7a = target_to_armv7a(target); - - return armv7a_handle_cache_info_command(CMD_CTX, - &armv7a->armv7a_mmu.armv7a_cache); -} - -COMMAND_HANDLER(armv7a_l1_d_cache_clean_inval_all_cmd) -{ - struct target *target = get_current_target(CMD_CTX); - - armv7a_l1_d_cache_clean_inval_all(target); - - return 0; -} - -COMMAND_HANDLER(arm7a_l1_d_cache_inval_virt_cmd) -{ - struct target *target = get_current_target(CMD_CTX); - uint32_t virt, size; - - if (CMD_ARGC == 0 || CMD_ARGC > 2) - return ERROR_COMMAND_SYNTAX_ERROR; - - if (CMD_ARGC == 2) - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], size); - else - size = 1; - - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], virt); - - return armv7a_l1_d_cache_inval_virt(target, virt, size); -} - -COMMAND_HANDLER(arm7a_l1_d_cache_clean_virt_cmd) -{ - struct target *target = get_current_target(CMD_CTX); - uint32_t virt, size; - - if (CMD_ARGC == 0 || CMD_ARGC > 2) - return ERROR_COMMAND_SYNTAX_ERROR; - - if (CMD_ARGC == 2) - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], size); - else - size = 1; - - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], virt); - - return armv7a_l1_d_cache_clean_virt(target, virt, size); -} - -COMMAND_HANDLER(armv7a_i_cache_clean_inval_all_cmd) -{ - struct target *target = get_current_target(CMD_CTX); - - armv7a_l1_i_cache_inval_all(target); - - return 0; -} - -COMMAND_HANDLER(arm7a_l1_i_cache_inval_virt_cmd) -{ - struct target *target = get_current_target(CMD_CTX); - uint32_t virt, size; - - if (CMD_ARGC == 0 || CMD_ARGC > 2) - return ERROR_COMMAND_SYNTAX_ERROR; - - if (CMD_ARGC == 2) - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], size); - else - size = 1; - - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], virt); - - return armv7a_l1_i_cache_inval_virt(target, virt, size); -} - -COMMAND_HANDLER(arm7a_cache_disable_auto_cmd) -{ - struct target *target = get_current_target(CMD_CTX); - struct armv7a_common *armv7a = target_to_armv7a(target); - - if (CMD_ARGC == 0) { - command_print(CMD_CTX, "auto cache is %s", - armv7a->armv7a_mmu.armv7a_cache.auto_cache_enabled ? "enabled" : "disabled"); - return ERROR_OK; - } - - if (CMD_ARGC == 1) { - uint32_t set; - - COMMAND_PARSE_ENABLE(CMD_ARGV[0], set); - armv7a->armv7a_mmu.armv7a_cache.auto_cache_enabled = !!set; - return ERROR_OK; - } - - return ERROR_COMMAND_SYNTAX_ERROR; -} - -static const struct command_registration arm7a_l1_d_cache_commands[] = { - { - .name = "flush_all", - .handler = armv7a_l1_d_cache_clean_inval_all_cmd, - .mode = COMMAND_ANY, - .help = "flush (clean and invalidate) complete l1 d-cache", - .usage = "", - }, - { - .name = "inval", - .handler = arm7a_l1_d_cache_inval_virt_cmd, - .mode = COMMAND_ANY, - .help = "invalidate l1 d-cache by virtual address offset and range size", - .usage = " [size]", - }, - { - .name = "clean", - .handler = arm7a_l1_d_cache_clean_virt_cmd, - .mode = COMMAND_ANY, - .help = "clean l1 d-cache by virtual address address offset and range size", - .usage = " [size]", - }, - COMMAND_REGISTRATION_DONE -}; - -static const struct command_registration arm7a_l1_i_cache_commands[] = { - { - .name = "inval_all", - .handler = armv7a_i_cache_clean_inval_all_cmd, - .mode = COMMAND_ANY, - .help = "invalidate complete l1 i-cache", - .usage = "", - }, - { - .name = "inval", - .handler = arm7a_l1_i_cache_inval_virt_cmd, - .mode = COMMAND_ANY, - .help = "invalidate l1 i-cache by virtual address offset and range size", - .usage = " [size]", - }, - COMMAND_REGISTRATION_DONE -}; - -const struct command_registration arm7a_l1_di_cache_group_handlers[] = { - { - .name = "info", - .handler = arm7a_l1_cache_info_cmd, - .mode = COMMAND_ANY, - .help = "print cache realted information", - .usage = "", - }, - { - .name = "d", - .mode = COMMAND_ANY, - .help = "l1 d-cache command group", - .usage = "", - .chain = arm7a_l1_d_cache_commands, - }, - { - .name = "i", - .mode = COMMAND_ANY, - .help = "l1 i-cache command group", - .usage = "", - .chain = arm7a_l1_i_cache_commands, - }, - COMMAND_REGISTRATION_DONE -}; - -const struct command_registration arm7a_cache_group_handlers[] = { - { - .name = "auto", - .handler = arm7a_cache_disable_auto_cmd, - .mode = COMMAND_ANY, - .help = "disable or enable automatic cache handling.", - .usage = "(1|0)", - }, - { - .name = "l1", - .mode = COMMAND_ANY, - .help = "l1 cache command group", - .usage = "", - .chain = arm7a_l1_di_cache_group_handlers, - }, - { - .chain = arm7a_l2x_cache_command_handler, - }, - COMMAND_REGISTRATION_DONE -}; - -const struct command_registration arm7a_cache_command_handlers[] = { - { - .name = "cache", - .mode = COMMAND_ANY, - .help = "cache command group", - .usage = "", - .chain = arm7a_cache_group_handlers, - }, - COMMAND_REGISTRATION_DONE -}; diff --git a/src/target/armv7a_cache.h b/src/target/armv7a_cache.h deleted file mode 100644 index e0f7eb3a5..000000000 --- a/src/target/armv7a_cache.h +++ /dev/null @@ -1,46 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2015 Oleksij Rempel * - * linux@rempel-privat.de * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifndef OPENOCD_TARGET_ARM7A_CACHE_H -#define OPENOCD_TARGET_ARM7A_CACHE_H - -#include "arm_jtag.h" -#include "armv7a_cache_l2x.h" - -int armv7a_l1_d_cache_clean_virt(struct target *target, uint32_t virt, - unsigned int size); -int armv7a_l1_d_cache_inval_virt(struct target *target, uint32_t virt, - unsigned int size); -int armv7a_l1_d_cache_flush_virt(struct target *target, uint32_t virt, - unsigned int size); -int armv7a_l1_i_cache_inval_all(struct target *target); -int armv7a_l1_i_cache_inval_virt(struct target *target, uint32_t virt, - uint32_t size); -int armv7a_cache_auto_flush_on_write(struct target *target, uint32_t virt, - uint32_t size); -int armv7a_cache_auto_flush_all_data(struct target *target); -int armv7a_cache_flush_virt(struct target *target, uint32_t virt, - uint32_t size); -extern const struct command_registration arm7a_cache_command_handlers[]; - -/* CLIDR cache types */ -#define CACHE_LEVEL_HAS_UNIFIED_CACHE 0x4 -#define CACHE_LEVEL_HAS_D_CACHE 0x2 -#define CACHE_LEVEL_HAS_I_CACHE 0x1 - -#endif /* OPENOCD_TARGET_ARM7A_CACHE_H */ diff --git a/src/target/armv7a_cache_l2x.c b/src/target/armv7a_cache_l2x.c deleted file mode 100644 index 798843835..000000000 --- a/src/target/armv7a_cache_l2x.c +++ /dev/null @@ -1,378 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2015 by Oleksij Rempel * - * linux@rempel-privat.de * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "jtag/interface.h" -#include "arm.h" -#include "armv7a.h" -#include "armv7a_cache.h" -#include -#include "target.h" -#include "target_type.h" - -static int arm7a_l2x_sanity_check(struct target *target) -{ - struct armv7a_common *armv7a = target_to_armv7a(target); - struct armv7a_l2x_cache *l2x_cache = (struct armv7a_l2x_cache *) - (armv7a->armv7a_mmu.armv7a_cache.outer_cache); - - if (target->state != TARGET_HALTED) { - LOG_ERROR("%s: target not halted", __func__); - return ERROR_TARGET_NOT_HALTED; - } - - if (!l2x_cache || !l2x_cache->base) { - LOG_DEBUG("l2x is not configured!"); - return ERROR_FAIL; - } - - return ERROR_OK; -} -/* - * clean and invalidate complete l2x cache - */ -int arm7a_l2x_flush_all_data(struct target *target) -{ - struct armv7a_common *armv7a = target_to_armv7a(target); - struct armv7a_l2x_cache *l2x_cache = (struct armv7a_l2x_cache *) - (armv7a->armv7a_mmu.armv7a_cache.outer_cache); - uint32_t l2_way_val; - int retval; - - retval = arm7a_l2x_sanity_check(target); - if (retval) - return retval; - - l2_way_val = (1 << l2x_cache->way) - 1; - - return target_write_phys_memory(target, - l2x_cache->base + L2X0_CLEAN_INV_WAY, - 4, 1, (uint8_t *)&l2_way_val); -} - -int armv7a_l2x_cache_flush_virt(struct target *target, uint32_t virt, - uint32_t size) -{ - struct armv7a_common *armv7a = target_to_armv7a(target); - struct armv7a_l2x_cache *l2x_cache = (struct armv7a_l2x_cache *) - (armv7a->armv7a_mmu.armv7a_cache.outer_cache); - /* FIXME: different controllers have different linelen? */ - uint32_t i, linelen = 32; - int retval; - - retval = arm7a_l2x_sanity_check(target); - if (retval) - return retval; - - for (i = 0; i < size; i += linelen) { - uint32_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); - if (retval != ERROR_OK) - goto done; - } - return retval; - -done: - LOG_ERROR("d-cache invalidate failed"); - - return retval; -} - -static int armv7a_l2x_cache_inval_virt(struct target *target, uint32_t virt, - uint32_t size) -{ - struct armv7a_common *armv7a = target_to_armv7a(target); - struct armv7a_l2x_cache *l2x_cache = (struct armv7a_l2x_cache *) - (armv7a->armv7a_mmu.armv7a_cache.outer_cache); - /* FIXME: different controllers have different linelen */ - uint32_t i, linelen = 32; - int retval; - - retval = arm7a_l2x_sanity_check(target); - if (retval) - return retval; - - for (i = 0; i < size; i += linelen) { - uint32_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); - if (retval != ERROR_OK) - goto done; - } - return retval; - -done: - LOG_ERROR("d-cache invalidate failed"); - - return retval; -} - -static int armv7a_l2x_cache_clean_virt(struct target *target, uint32_t virt, - unsigned int size) -{ - struct armv7a_common *armv7a = target_to_armv7a(target); - struct armv7a_l2x_cache *l2x_cache = (struct armv7a_l2x_cache *) - (armv7a->armv7a_mmu.armv7a_cache.outer_cache); - /* FIXME: different controllers have different linelen */ - uint32_t i, linelen = 32; - int retval; - - retval = arm7a_l2x_sanity_check(target); - if (retval) - return retval; - - for (i = 0; i < size; i += linelen) { - uint32_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); - if (retval != ERROR_OK) - goto done; - } - return retval; - -done: - LOG_ERROR("d-cache invalidate failed"); - - return retval; -} - -static int arm7a_handle_l2x_cache_info_command(struct command_context *cmd_ctx, - struct armv7a_cache_common *armv7a_cache) -{ - struct armv7a_l2x_cache *l2x_cache = (struct armv7a_l2x_cache *) - (armv7a_cache->outer_cache); - - if (armv7a_cache->info == -1) { - command_print(cmd_ctx, "cache not yet identified"); - return ERROR_OK; - } - - command_print(cmd_ctx, - "L2 unified cache Base Address 0x%" PRIx32 ", %" PRId32 " ways", - l2x_cache->base, l2x_cache->way); - - return ERROR_OK; -} - -static int armv7a_l2x_cache_init(struct target *target, uint32_t base, uint32_t way) -{ - struct armv7a_l2x_cache *l2x_cache; - struct target_list *head = target->head; - struct target *curr; - - struct armv7a_common *armv7a = target_to_armv7a(target); - if (armv7a->armv7a_mmu.armv7a_cache.outer_cache) { - LOG_ERROR("L2 cache was already initialised\n"); - return ERROR_FAIL; - } - - l2x_cache = calloc(1, sizeof(struct armv7a_l2x_cache)); - l2x_cache->base = base; - l2x_cache->way = way; - armv7a->armv7a_mmu.armv7a_cache.outer_cache = l2x_cache; - - /* initialize all targets in this cluster (smp target) - * l2 cache must be configured after smp declaration */ - while (head != (struct target_list *)NULL) { - curr = head->target; - if (curr != target) { - armv7a = target_to_armv7a(curr); - if (armv7a->armv7a_mmu.armv7a_cache.outer_cache) { - LOG_ERROR("smp target : cache l2 already initialized\n"); - return ERROR_FAIL; - } - armv7a->armv7a_mmu.armv7a_cache.outer_cache = l2x_cache; - } - head = head->next; - } - return ERROR_OK; -} - -COMMAND_HANDLER(arm7a_l2x_cache_info_command) -{ - struct target *target = get_current_target(CMD_CTX); - struct armv7a_common *armv7a = target_to_armv7a(target); - int retval; - - retval = arm7a_l2x_sanity_check(target); - if (retval) - return retval; - - return arm7a_handle_l2x_cache_info_command(CMD_CTX, - &armv7a->armv7a_mmu.armv7a_cache); -} - -COMMAND_HANDLER(arm7a_l2x_cache_flush_all_command) -{ - struct target *target = get_current_target(CMD_CTX); - - return arm7a_l2x_flush_all_data(target); -} - -COMMAND_HANDLER(arm7a_l2x_cache_flush_virt_cmd) -{ - struct target *target = get_current_target(CMD_CTX); - uint32_t virt, size; - - if (CMD_ARGC == 0 || CMD_ARGC > 2) - return ERROR_COMMAND_SYNTAX_ERROR; - - if (CMD_ARGC == 2) - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], size); - else - size = 1; - - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], virt); - - return armv7a_l2x_cache_flush_virt(target, virt, size); -} - -COMMAND_HANDLER(arm7a_l2x_cache_inval_virt_cmd) -{ - struct target *target = get_current_target(CMD_CTX); - uint32_t virt, size; - - if (CMD_ARGC == 0 || CMD_ARGC > 2) - return ERROR_COMMAND_SYNTAX_ERROR; - - if (CMD_ARGC == 2) - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], size); - else - size = 1; - - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], virt); - - return armv7a_l2x_cache_inval_virt(target, virt, size); -} - -COMMAND_HANDLER(arm7a_l2x_cache_clean_virt_cmd) -{ - struct target *target = get_current_target(CMD_CTX); - uint32_t virt, size; - - if (CMD_ARGC == 0 || CMD_ARGC > 2) - return ERROR_COMMAND_SYNTAX_ERROR; - - if (CMD_ARGC == 2) - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], size); - else - size = 1; - - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], virt); - - return armv7a_l2x_cache_clean_virt(target, virt, size); -} - -/* FIXME: should we configure way size? or controller type? */ -COMMAND_HANDLER(armv7a_l2x_cache_conf_cmd) -{ - struct target *target = get_current_target(CMD_CTX); - uint32_t base, way; - - if (CMD_ARGC != 2) - return ERROR_COMMAND_SYNTAX_ERROR; - - /* command_print(CMD_CTX, "%s %s", CMD_ARGV[0], CMD_ARGV[1]); */ - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], base); - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], way); - - /* AP address is in bits 31:24 of DP_SELECT */ - return armv7a_l2x_cache_init(target, base, way); -} - -static const struct command_registration arm7a_l2x_cache_commands[] = { - { - .name = "conf", - .handler = armv7a_l2x_cache_conf_cmd, - .mode = COMMAND_ANY, - .help = "configure l2x cache ", - .usage = " ", - }, - { - .name = "info", - .handler = arm7a_l2x_cache_info_command, - .mode = COMMAND_ANY, - .help = "print cache realted information", - .usage = "", - }, - { - .name = "flush_all", - .handler = arm7a_l2x_cache_flush_all_command, - .mode = COMMAND_ANY, - .help = "flush complete l2x cache", - .usage = "", - }, - { - .name = "flush", - .handler = arm7a_l2x_cache_flush_virt_cmd, - .mode = COMMAND_ANY, - .help = "flush (clean and invalidate) l2x cache by virtual address offset and range size", - .usage = " [size]", - }, - { - .name = "inval", - .handler = arm7a_l2x_cache_inval_virt_cmd, - .mode = COMMAND_ANY, - .help = "invalidate l2x cache by virtual address offset and range size", - .usage = " [size]", - }, - { - .name = "clean", - .handler = arm7a_l2x_cache_clean_virt_cmd, - .mode = COMMAND_ANY, - .help = "clean l2x cache by virtual address address offset and range size", - .usage = " [size]", - }, - COMMAND_REGISTRATION_DONE -}; - -const struct command_registration arm7a_l2x_cache_command_handler[] = { - { - .name = "l2x", - .mode = COMMAND_ANY, - .help = "l2x cache command group", - .usage = "", - .chain = arm7a_l2x_cache_commands, - }, - COMMAND_REGISTRATION_DONE -}; diff --git a/src/target/armv7a_cache_l2x.h b/src/target/armv7a_cache_l2x.h deleted file mode 100644 index 3d9ad8116..000000000 --- a/src/target/armv7a_cache_l2x.h +++ /dev/null @@ -1,158 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2015 Oleksij Rempel * - * linux@rempel-privat.de * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifndef OPENOCD_TARGET_ARM7A_CACHE_L2X_H -#define OPENOCD_TARGET_ARM7A_CACHE_L2X_H - -#define L2X0_CACHE_LINE_SIZE 32 - -/* source: linux/arch/arm/include/asm/hardware/cache-l2x0.h */ -#define L2X0_CACHE_ID 0x000 -#define L2X0_CACHE_TYPE 0x004 -#define L2X0_CTRL 0x100 -#define L2X0_AUX_CTRL 0x104 -#define L2X0_TAG_LATENCY_CTRL 0x108 -#define L2X0_DATA_LATENCY_CTRL 0x10C -#define L2X0_EVENT_CNT_CTRL 0x200 -#define L2X0_EVENT_CNT1_CFG 0x204 -#define L2X0_EVENT_CNT0_CFG 0x208 -#define L2X0_EVENT_CNT1_VAL 0x20C -#define L2X0_EVENT_CNT0_VAL 0x210 -#define L2X0_INTR_MASK 0x214 -#define L2X0_MASKED_INTR_STAT 0x218 -#define L2X0_RAW_INTR_STAT 0x21C -#define L2X0_INTR_CLEAR 0x220 -#define L2X0_CACHE_SYNC 0x730 -#define L2X0_DUMMY_REG 0x740 -#define L2X0_INV_LINE_PA 0x770 -#define L2X0_INV_WAY 0x77C -#define L2X0_CLEAN_LINE_PA 0x7B0 -#define L2X0_CLEAN_LINE_IDX 0x7B8 -#define L2X0_CLEAN_WAY 0x7BC -#define L2X0_CLEAN_INV_LINE_PA 0x7F0 -#define L2X0_CLEAN_INV_LINE_IDX 0x7F8 -#define L2X0_CLEAN_INV_WAY 0x7FC -/* - * The lockdown registers repeat 8 times for L310, the L210 has only one - * D and one I lockdown register at 0x0900 and 0x0904. - */ -#define L2X0_LOCKDOWN_WAY_D_BASE 0x900 -#define L2X0_LOCKDOWN_WAY_I_BASE 0x904 -#define L2X0_LOCKDOWN_STRIDE 0x08 -#define L2X0_ADDR_FILTER_START 0xC00 -#define L2X0_ADDR_FILTER_END 0xC04 -#define L2X0_TEST_OPERATION 0xF00 -#define L2X0_LINE_DATA 0xF10 -#define L2X0_LINE_TAG 0xF30 -#define L2X0_DEBUG_CTRL 0xF40 -#define L2X0_PREFETCH_CTRL 0xF60 -#define L2X0_POWER_CTRL 0xF80 -#define L2X0_DYNAMIC_CLK_GATING_EN (1 << 1) -#define L2X0_STNDBY_MODE_EN (1 << 0) - -/* Registers shifts and masks */ -#define L2X0_CACHE_ID_PART_MASK (0xf << 6) -#define L2X0_CACHE_ID_PART_L210 (1 << 6) -#define L2X0_CACHE_ID_PART_L310 (3 << 6) -#define L2X0_CACHE_ID_RTL_MASK 0x3f -#define L2X0_CACHE_ID_RTL_R0P0 0x0 -#define L2X0_CACHE_ID_RTL_R1P0 0x2 -#define L2X0_CACHE_ID_RTL_R2P0 0x4 -#define L2X0_CACHE_ID_RTL_R3P0 0x5 -#define L2X0_CACHE_ID_RTL_R3P1 0x6 -#define L2X0_CACHE_ID_RTL_R3P2 0x8 - -#define L2X0_AUX_CTRL_MASK 0xc0000fff -#define L2X0_AUX_CTRL_DATA_RD_LATENCY_SHIFT 0 -#define L2X0_AUX_CTRL_DATA_RD_LATENCY_MASK 0x7 -#define L2X0_AUX_CTRL_DATA_WR_LATENCY_SHIFT 3 -#define L2X0_AUX_CTRL_DATA_WR_LATENCY_MASK (0x7 << 3) -#define L2X0_AUX_CTRL_TAG_LATENCY_SHIFT 6 -#define L2X0_AUX_CTRL_TAG_LATENCY_MASK (0x7 << 6) -#define L2X0_AUX_CTRL_DIRTY_LATENCY_SHIFT 9 -#define L2X0_AUX_CTRL_DIRTY_LATENCY_MASK (0x7 << 9) -#define L2X0_AUX_CTRL_ASSOCIATIVITY_SHIFT 16 -#define L2X0_AUX_CTRL_WAY_SIZE_SHIFT 17 -#define L2X0_AUX_CTRL_WAY_SIZE_MASK (0x7 << 17) -#define L2X0_AUX_CTRL_SHARE_OVERRIDE_SHIFT 22 -#define L2X0_AUX_CTRL_NS_LOCKDOWN_SHIFT 26 -#define L2X0_AUX_CTRL_NS_INT_CTRL_SHIFT 27 -#define L2X0_AUX_CTRL_DATA_PREFETCH_SHIFT 28 -#define L2X0_AUX_CTRL_INSTR_PREFETCH_SHIFT 29 -#define L2X0_AUX_CTRL_EARLY_BRESP_SHIFT 30 - -#define L2X0_LATENCY_CTRL_SETUP_SHIFT 0 -#define L2X0_LATENCY_CTRL_RD_SHIFT 4 -#define L2X0_LATENCY_CTRL_WR_SHIFT 8 - -#define L2X0_ADDR_FILTER_EN 1 - -#define L2X0_CTRL_EN 1 - -#define L2X0_WAY_SIZE_SHIFT 3 - -struct l2x0_regs { - unsigned long phy_base; - unsigned long aux_ctrl; - /* - * Whether the following registers need to be saved/restored - * depends on platform - */ - unsigned long tag_latency; - unsigned long data_latency; - unsigned long filter_start; - unsigned long filter_end; - unsigned long prefetch_ctrl; - unsigned long pwr_ctrl; - unsigned long ctrl; - unsigned long aux2_ctrl; -}; - -struct outer_cache_fns { - void (*inv_range)(unsigned long, unsigned long); - void (*clean_range)(unsigned long, unsigned long); - void (*flush_range)(unsigned long, unsigned long); - void (*flush_all)(void); - void (*disable)(void); - - void (*resume)(void); - - /* This is an ARM L2C thing */ - void (*write_sec)(unsigned long, unsigned); - void (*configure)(const struct l2x0_regs *); -}; - -struct l2c_init_data { - const char *type; - unsigned way_size_0; - unsigned num_lock; - - void (*enable)(uint32_t, uint32_t, unsigned); - void (*fixup)(uint32_t, uint32_t, struct outer_cache_fns *); - void (*save)(uint32_t); - void (*configure)(uint32_t); - struct outer_cache_fns outer_cache; -}; - -extern const struct command_registration arm7a_l2x_cache_command_handler[]; - -int armv7a_l2x_cache_flush_virt(struct target *target, uint32_t virt, - uint32_t size); -int arm7a_l2x_flush_all_data(struct target *target); - -#endif /* OPENOCD_TARGET_ARM7A_CACHE_L2X_H */ diff --git a/src/target/armv7m.c b/src/target/armv7m.c deleted file mode 100644 index e2f710f14..000000000 --- a/src/target/armv7m.c +++ /dev/null @@ -1,829 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * Copyright (C) 2006 by Magnus Lundin * - * lundin@mlu.mine.nu * - * * - * Copyright (C) 2008 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * Copyright (C) 2007,2008 Øyvind Harboe * - * oyvind.harboe@zylin.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - * * - * ARMv7-M Architecture, Application Level Reference Manual * - * ARM DDI 0405C (September 2008) * - * * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "breakpoints.h" -#include "armv7m.h" -#include "algorithm.h" -#include "register.h" - -#if 0 -#define _DEBUG_INSTRUCTION_EXECUTION_ -#endif - -static const char * const armv7m_exception_strings[] = { - "", "Reset", "NMI", "HardFault", - "MemManage", "BusFault", "UsageFault", "RESERVED", - "RESERVED", "RESERVED", "RESERVED", "SVCall", - "DebugMonitor", "RESERVED", "PendSV", "SysTick" -}; - -/* PSP is used in some thread modes */ -const int armv7m_psp_reg_map[ARMV7M_NUM_CORE_REGS] = { - ARMV7M_R0, ARMV7M_R1, ARMV7M_R2, ARMV7M_R3, - ARMV7M_R4, ARMV7M_R5, ARMV7M_R6, ARMV7M_R7, - ARMV7M_R8, ARMV7M_R9, ARMV7M_R10, ARMV7M_R11, - ARMV7M_R12, ARMV7M_PSP, ARMV7M_R14, ARMV7M_PC, - ARMV7M_xPSR, -}; - -/* MSP is used in handler and some thread modes */ -const int armv7m_msp_reg_map[ARMV7M_NUM_CORE_REGS] = { - ARMV7M_R0, ARMV7M_R1, ARMV7M_R2, ARMV7M_R3, - ARMV7M_R4, ARMV7M_R5, ARMV7M_R6, ARMV7M_R7, - ARMV7M_R8, ARMV7M_R9, ARMV7M_R10, ARMV7M_R11, - ARMV7M_R12, ARMV7M_MSP, ARMV7M_R14, ARMV7M_PC, - ARMV7M_xPSR, -}; - -/* - * These registers are not memory-mapped. The ARMv7-M profile includes - * memory mapped registers too, such as for the NVIC (interrupt controller) - * and SysTick (timer) modules; those can mostly be treated as peripherals. - * - * The ARMv6-M profile is almost identical in this respect, except that it - * doesn't include basepri or faultmask registers. - */ -static const struct { - unsigned id; - const char *name; - unsigned bits; - enum reg_type type; - const char *group; - const char *feature; -} armv7m_regs[] = { - { ARMV7M_R0, "r0", 32, REG_TYPE_INT, "general", "org.gnu.gdb.arm.m-profile" }, - { ARMV7M_R1, "r1", 32, REG_TYPE_INT, "general", "org.gnu.gdb.arm.m-profile" }, - { ARMV7M_R2, "r2", 32, REG_TYPE_INT, "general", "org.gnu.gdb.arm.m-profile" }, - { ARMV7M_R3, "r3", 32, REG_TYPE_INT, "general", "org.gnu.gdb.arm.m-profile" }, - { ARMV7M_R4, "r4", 32, REG_TYPE_INT, "general", "org.gnu.gdb.arm.m-profile" }, - { ARMV7M_R5, "r5", 32, REG_TYPE_INT, "general", "org.gnu.gdb.arm.m-profile" }, - { ARMV7M_R6, "r6", 32, REG_TYPE_INT, "general", "org.gnu.gdb.arm.m-profile" }, - { ARMV7M_R7, "r7", 32, REG_TYPE_INT, "general", "org.gnu.gdb.arm.m-profile" }, - { ARMV7M_R8, "r8", 32, REG_TYPE_INT, "general", "org.gnu.gdb.arm.m-profile" }, - { ARMV7M_R9, "r9", 32, REG_TYPE_INT, "general", "org.gnu.gdb.arm.m-profile" }, - { ARMV7M_R10, "r10", 32, REG_TYPE_INT, "general", "org.gnu.gdb.arm.m-profile" }, - { ARMV7M_R11, "r11", 32, REG_TYPE_INT, "general", "org.gnu.gdb.arm.m-profile" }, - { ARMV7M_R12, "r12", 32, REG_TYPE_INT, "general", "org.gnu.gdb.arm.m-profile" }, - { ARMV7M_R13, "sp", 32, REG_TYPE_DATA_PTR, "general", "org.gnu.gdb.arm.m-profile" }, - { ARMV7M_R14, "lr", 32, REG_TYPE_INT, "general", "org.gnu.gdb.arm.m-profile" }, - { ARMV7M_PC, "pc", 32, REG_TYPE_CODE_PTR, "general", "org.gnu.gdb.arm.m-profile" }, - { ARMV7M_xPSR, "xPSR", 32, REG_TYPE_INT, "general", "org.gnu.gdb.arm.m-profile" }, - - { ARMV7M_MSP, "msp", 32, REG_TYPE_DATA_PTR, "system", "org.gnu.gdb.arm.m-system" }, - { ARMV7M_PSP, "psp", 32, REG_TYPE_DATA_PTR, "system", "org.gnu.gdb.arm.m-system" }, - - { ARMV7M_PRIMASK, "primask", 1, REG_TYPE_INT8, "system", "org.gnu.gdb.arm.m-system" }, - { ARMV7M_BASEPRI, "basepri", 8, REG_TYPE_INT8, "system", "org.gnu.gdb.arm.m-system" }, - { ARMV7M_FAULTMASK, "faultmask", 1, REG_TYPE_INT8, "system", "org.gnu.gdb.arm.m-system" }, - { ARMV7M_CONTROL, "control", 2, REG_TYPE_INT8, "system", "org.gnu.gdb.arm.m-system" }, - - { ARMV7M_D0, "d0", 64, REG_TYPE_IEEE_DOUBLE, "float", "org.gnu.gdb.arm.vfp" }, - { ARMV7M_D1, "d1", 64, REG_TYPE_IEEE_DOUBLE, "float", "org.gnu.gdb.arm.vfp" }, - { ARMV7M_D2, "d2", 64, REG_TYPE_IEEE_DOUBLE, "float", "org.gnu.gdb.arm.vfp" }, - { ARMV7M_D3, "d3", 64, REG_TYPE_IEEE_DOUBLE, "float", "org.gnu.gdb.arm.vfp" }, - { ARMV7M_D4, "d4", 64, REG_TYPE_IEEE_DOUBLE, "float", "org.gnu.gdb.arm.vfp" }, - { ARMV7M_D5, "d5", 64, REG_TYPE_IEEE_DOUBLE, "float", "org.gnu.gdb.arm.vfp" }, - { ARMV7M_D6, "d6", 64, REG_TYPE_IEEE_DOUBLE, "float", "org.gnu.gdb.arm.vfp" }, - { ARMV7M_D7, "d7", 64, REG_TYPE_IEEE_DOUBLE, "float", "org.gnu.gdb.arm.vfp" }, - { ARMV7M_D8, "d8", 64, REG_TYPE_IEEE_DOUBLE, "float", "org.gnu.gdb.arm.vfp" }, - { ARMV7M_D9, "d9", 64, REG_TYPE_IEEE_DOUBLE, "float", "org.gnu.gdb.arm.vfp" }, - { ARMV7M_D10, "d10", 64, REG_TYPE_IEEE_DOUBLE, "float", "org.gnu.gdb.arm.vfp" }, - { ARMV7M_D11, "d11", 64, REG_TYPE_IEEE_DOUBLE, "float", "org.gnu.gdb.arm.vfp" }, - { ARMV7M_D12, "d12", 64, REG_TYPE_IEEE_DOUBLE, "float", "org.gnu.gdb.arm.vfp" }, - { ARMV7M_D13, "d13", 64, REG_TYPE_IEEE_DOUBLE, "float", "org.gnu.gdb.arm.vfp" }, - { ARMV7M_D14, "d14", 64, REG_TYPE_IEEE_DOUBLE, "float", "org.gnu.gdb.arm.vfp" }, - { ARMV7M_D15, "d15", 64, REG_TYPE_IEEE_DOUBLE, "float", "org.gnu.gdb.arm.vfp" }, - - { ARMV7M_FPSCR, "fpscr", 32, REG_TYPE_INT, "float", "org.gnu.gdb.arm.vfp" }, -}; - -#define ARMV7M_NUM_REGS ARRAY_SIZE(armv7m_regs) - -/** - * Restores target context using the cache of core registers set up - * by armv7m_build_reg_cache(), calling optional core-specific hooks. - */ -int armv7m_restore_context(struct target *target) -{ - int i; - struct armv7m_common *armv7m = target_to_armv7m(target); - struct reg_cache *cache = armv7m->arm.core_cache; - - LOG_DEBUG(" "); - - if (armv7m->pre_restore_context) - armv7m->pre_restore_context(target); - - for (i = cache->num_regs - 1; i >= 0; i--) { - if (cache->reg_list[i].dirty) { - armv7m->arm.write_core_reg(target, &cache->reg_list[i], i, - ARM_MODE_ANY, cache->reg_list[i].value); - } - } - - return ERROR_OK; -} - -/* Core state functions */ - -/** - * Maps ISR number (from xPSR) to name. - * Note that while names and meanings for the first sixteen are standardized - * (with zero not a true exception), external interrupts are only numbered. - * They are assigned by vendors, which generally assign different numbers to - * peripherals (such as UART0 or a USB peripheral controller). - */ -const char *armv7m_exception_string(int number) -{ - static char enamebuf[32]; - - if ((number < 0) | (number > 511)) - return "Invalid exception"; - if (number < 16) - return armv7m_exception_strings[number]; - sprintf(enamebuf, "External Interrupt(%i)", number - 16); - return enamebuf; -} - -static int armv7m_get_core_reg(struct reg *reg) -{ - int retval; - struct arm_reg *armv7m_reg = reg->arch_info; - struct target *target = armv7m_reg->target; - struct arm *arm = target_to_arm(target); - - if (target->state != TARGET_HALTED) - return ERROR_TARGET_NOT_HALTED; - - retval = arm->read_core_reg(target, reg, armv7m_reg->num, arm->core_mode); - - return retval; -} - -static int armv7m_set_core_reg(struct reg *reg, uint8_t *buf) -{ - struct arm_reg *armv7m_reg = reg->arch_info; - struct target *target = armv7m_reg->target; - - if (target->state != TARGET_HALTED) - return ERROR_TARGET_NOT_HALTED; - - buf_cpy(buf, reg->value, reg->size); - reg->dirty = 1; - reg->valid = 1; - - return ERROR_OK; -} - -static int armv7m_read_core_reg(struct target *target, struct reg *r, - int num, enum arm_mode mode) -{ - uint32_t reg_value; - int retval; - struct arm_reg *armv7m_core_reg; - struct armv7m_common *armv7m = target_to_armv7m(target); - - assert(num < (int)armv7m->arm.core_cache->num_regs); - - armv7m_core_reg = armv7m->arm.core_cache->reg_list[num].arch_info; - - if ((armv7m_core_reg->num >= ARMV7M_D0) && (armv7m_core_reg->num <= ARMV7M_D15)) { - /* map D0..D15 to S0..S31 */ - size_t regidx = ARMV7M_S0 + 2 * (armv7m_core_reg->num - ARMV7M_D0); - retval = armv7m->load_core_reg_u32(target, regidx, ®_value); - if (retval != ERROR_OK) - return retval; - buf_set_u32(armv7m->arm.core_cache->reg_list[num].value, - 0, 32, reg_value); - retval = armv7m->load_core_reg_u32(target, regidx + 1, ®_value); - if (retval != ERROR_OK) - return retval; - buf_set_u32(armv7m->arm.core_cache->reg_list[num].value + 4, - 0, 32, reg_value); - } else { - retval = armv7m->load_core_reg_u32(target, - armv7m_core_reg->num, ®_value); - if (retval != ERROR_OK) - return retval; - buf_set_u32(armv7m->arm.core_cache->reg_list[num].value, 0, 32, reg_value); - } - - armv7m->arm.core_cache->reg_list[num].valid = 1; - armv7m->arm.core_cache->reg_list[num].dirty = 0; - - return retval; -} - -static int armv7m_write_core_reg(struct target *target, struct reg *r, - int num, enum arm_mode mode, uint8_t *value) -{ - int retval; - struct arm_reg *armv7m_core_reg; - struct armv7m_common *armv7m = target_to_armv7m(target); - - assert(num < (int)armv7m->arm.core_cache->num_regs); - - armv7m_core_reg = armv7m->arm.core_cache->reg_list[num].arch_info; - - if ((armv7m_core_reg->num >= ARMV7M_D0) && (armv7m_core_reg->num <= ARMV7M_D15)) { - /* map D0..D15 to S0..S31 */ - size_t regidx = ARMV7M_S0 + 2 * (armv7m_core_reg->num - ARMV7M_D0); - - uint32_t t = buf_get_u32(value, 0, 32); - retval = armv7m->store_core_reg_u32(target, regidx, t); - if (retval != ERROR_OK) - goto out_error; - - t = buf_get_u32(value + 4, 0, 32); - retval = armv7m->store_core_reg_u32(target, regidx + 1, t); - if (retval != ERROR_OK) - goto out_error; - } else { - uint32_t t = buf_get_u32(value, 0, 32); - - LOG_DEBUG("write core reg %i value 0x%" PRIx32 "", num, t); - retval = armv7m->store_core_reg_u32(target, armv7m_core_reg->num, t); - if (retval != ERROR_OK) - goto out_error; - } - - armv7m->arm.core_cache->reg_list[num].valid = 1; - armv7m->arm.core_cache->reg_list[num].dirty = 0; - - return ERROR_OK; - -out_error: - LOG_ERROR("Error setting register"); - armv7m->arm.core_cache->reg_list[num].dirty = armv7m->arm.core_cache->reg_list[num].valid; - return ERROR_JTAG_DEVICE_ERROR; -} - -/** - * Returns generic ARM userspace registers to GDB. - */ -int armv7m_get_gdb_reg_list(struct target *target, struct reg **reg_list[], - int *reg_list_size, enum target_register_class reg_class) -{ - struct armv7m_common *armv7m = target_to_armv7m(target); - int i; - - if (reg_class == REG_CLASS_ALL) - *reg_list_size = armv7m->arm.core_cache->num_regs; - else - *reg_list_size = ARMV7M_NUM_CORE_REGS; - - *reg_list = malloc(sizeof(struct reg *) * (*reg_list_size)); - if (*reg_list == NULL) - return ERROR_FAIL; - - for (i = 0; i < *reg_list_size; i++) - (*reg_list)[i] = &armv7m->arm.core_cache->reg_list[i]; - - return ERROR_OK; -} - -/** Runs a Thumb algorithm in the target. */ -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, - int timeout_ms, void *arch_info) -{ - int retval; - - retval = armv7m_start_algorithm(target, - num_mem_params, mem_params, - num_reg_params, reg_params, - entry_point, exit_point, - arch_info); - - if (retval == ERROR_OK) - retval = armv7m_wait_algorithm(target, - num_mem_params, mem_params, - num_reg_params, reg_params, - exit_point, timeout_ms, - arch_info); - - return retval; -} - -/** Starts a Thumb algorithm in the 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, - void *arch_info) -{ - struct armv7m_common *armv7m = target_to_armv7m(target); - struct armv7m_algorithm *armv7m_algorithm_info = arch_info; - enum arm_mode core_mode = armv7m->arm.core_mode; - int retval = ERROR_OK; - - /* NOTE: armv7m_run_algorithm requires that each algorithm uses a software breakpoint - * at the exit point */ - - if (armv7m_algorithm_info->common_magic != ARMV7M_COMMON_MAGIC) { - LOG_ERROR("current target isn't an ARMV7M target"); - return ERROR_TARGET_INVALID; - } - - if (target->state != TARGET_HALTED) { - LOG_WARNING("target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - /* refresh core register cache - * Not needed if core register cache is always consistent with target process state */ - for (unsigned i = 0; i < armv7m->arm.core_cache->num_regs; i++) { - - armv7m_algorithm_info->context[i] = buf_get_u32( - armv7m->arm.core_cache->reg_list[i].value, - 0, - 32); - } - - for (int i = 0; i < num_mem_params; i++) { - /* TODO: Write only out params */ - retval = target_write_buffer(target, mem_params[i].address, - mem_params[i].size, - mem_params[i].value); - if (retval != ERROR_OK) - return retval; - } - - for (int i = 0; i < num_reg_params; i++) { - struct reg *reg = - register_get_by_name(armv7m->arm.core_cache, reg_params[i].reg_name, 0); -/* uint32_t regvalue; */ - - if (!reg) { - LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name); - return ERROR_COMMAND_SYNTAX_ERROR; - } - - if (reg->size != reg_params[i].size) { - LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size", - reg_params[i].reg_name); - return ERROR_COMMAND_SYNTAX_ERROR; - } - -/* regvalue = buf_get_u32(reg_params[i].value, 0, 32); */ - armv7m_set_core_reg(reg, reg_params[i].value); - } - - if (armv7m_algorithm_info->core_mode != ARM_MODE_ANY && - armv7m_algorithm_info->core_mode != core_mode) { - - /* we cannot set ARM_MODE_HANDLER, so use ARM_MODE_THREAD instead */ - if (armv7m_algorithm_info->core_mode == ARM_MODE_HANDLER) { - armv7m_algorithm_info->core_mode = ARM_MODE_THREAD; - LOG_INFO("ARM_MODE_HANDLER not currently supported, using ARM_MODE_THREAD instead"); - } - - LOG_DEBUG("setting core_mode: 0x%2.2x", armv7m_algorithm_info->core_mode); - buf_set_u32(armv7m->arm.core_cache->reg_list[ARMV7M_CONTROL].value, - 0, 1, armv7m_algorithm_info->core_mode); - armv7m->arm.core_cache->reg_list[ARMV7M_CONTROL].dirty = 1; - armv7m->arm.core_cache->reg_list[ARMV7M_CONTROL].valid = 1; - } - - /* save previous core mode */ - armv7m_algorithm_info->core_mode = core_mode; - - retval = target_resume(target, 0, entry_point, 1, 1); - - return retval; -} - -/** Waits for an algorithm in the 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, - void *arch_info) -{ - struct armv7m_common *armv7m = target_to_armv7m(target); - struct armv7m_algorithm *armv7m_algorithm_info = arch_info; - int retval = ERROR_OK; - uint32_t pc; - - /* NOTE: armv7m_run_algorithm requires that each algorithm uses a software breakpoint - * at the exit point */ - - if (armv7m_algorithm_info->common_magic != ARMV7M_COMMON_MAGIC) { - LOG_ERROR("current target isn't an ARMV7M target"); - return ERROR_TARGET_INVALID; - } - - retval = target_wait_state(target, TARGET_HALTED, timeout_ms); - /* If the target fails to halt due to the breakpoint, force a halt */ - if (retval != ERROR_OK || target->state != TARGET_HALTED) { - retval = target_halt(target); - if (retval != ERROR_OK) - return retval; - retval = target_wait_state(target, TARGET_HALTED, 500); - if (retval != ERROR_OK) - return retval; - return ERROR_TARGET_TIMEOUT; - } - - 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, - pc, - exit_point); - return ERROR_TARGET_TIMEOUT; - } - - /* Read memory values to mem_params[] */ - for (int i = 0; i < num_mem_params; i++) { - if (mem_params[i].direction != PARAM_OUT) { - retval = target_read_buffer(target, mem_params[i].address, - mem_params[i].size, - mem_params[i].value); - if (retval != ERROR_OK) - return retval; - } - } - - /* Copy core register values to reg_params[] */ - for (int i = 0; i < num_reg_params; i++) { - if (reg_params[i].direction != PARAM_OUT) { - struct reg *reg = register_get_by_name(armv7m->arm.core_cache, - reg_params[i].reg_name, - 0); - - if (!reg) { - LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name); - return ERROR_COMMAND_SYNTAX_ERROR; - } - - if (reg->size != reg_params[i].size) { - LOG_ERROR( - "BUG: register '%s' size doesn't match reg_params[i].size", - reg_params[i].reg_name); - return ERROR_COMMAND_SYNTAX_ERROR; - } - - buf_set_u32(reg_params[i].value, 0, 32, buf_get_u32(reg->value, 0, 32)); - } - } - - for (int i = armv7m->arm.core_cache->num_regs - 1; i >= 0; i--) { - uint32_t regvalue; - regvalue = buf_get_u32(armv7m->arm.core_cache->reg_list[i].value, 0, 32); - if (regvalue != armv7m_algorithm_info->context[i]) { - LOG_DEBUG("restoring register %s with value 0x%8.8" PRIx32, - armv7m->arm.core_cache->reg_list[i].name, - armv7m_algorithm_info->context[i]); - buf_set_u32(armv7m->arm.core_cache->reg_list[i].value, - 0, 32, armv7m_algorithm_info->context[i]); - armv7m->arm.core_cache->reg_list[i].valid = 1; - armv7m->arm.core_cache->reg_list[i].dirty = 1; - } - } - - /* restore previous core mode */ - if (armv7m_algorithm_info->core_mode != armv7m->arm.core_mode) { - LOG_DEBUG("restoring core_mode: 0x%2.2x", armv7m_algorithm_info->core_mode); - buf_set_u32(armv7m->arm.core_cache->reg_list[ARMV7M_CONTROL].value, - 0, 1, armv7m_algorithm_info->core_mode); - armv7m->arm.core_cache->reg_list[ARMV7M_CONTROL].dirty = 1; - armv7m->arm.core_cache->reg_list[ARMV7M_CONTROL].valid = 1; - } - - armv7m->arm.core_mode = armv7m_algorithm_info->core_mode; - - return retval; -} - -/** Logs summary of ARMv7-M state for a halted target. */ -int armv7m_arch_state(struct target *target) -{ - struct armv7m_common *armv7m = target_to_armv7m(target); - struct arm *arm = &armv7m->arm; - uint32_t ctrl, sp; - - 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", - debug_reason_name(target), - arm_mode_name(arm->core_mode), - armv7m_exception_string(armv7m->exception_number), - buf_get_u32(arm->cpsr->value, 0, 32), - buf_get_u32(arm->pc->value, 0, 32), - (ctrl & 0x02) ? 'p' : 'm', - sp, - arm->is_semihosting ? ", semihosting" : ""); - - return ERROR_OK; -} - -static const struct reg_arch_type armv7m_reg_type = { - .get = armv7m_get_core_reg, - .set = armv7m_set_core_reg, -}; - -/** Builds cache of architecturally defined registers. */ -struct reg_cache *armv7m_build_reg_cache(struct target *target) -{ - struct armv7m_common *armv7m = target_to_armv7m(target); - struct arm *arm = &armv7m->arm; - int num_regs = ARMV7M_NUM_REGS; - struct reg_cache **cache_p = register_get_last_cache_p(&target->reg_cache); - struct reg_cache *cache = malloc(sizeof(struct reg_cache)); - struct reg *reg_list = calloc(num_regs, sizeof(struct reg)); - struct arm_reg *arch_info = calloc(num_regs, sizeof(struct arm_reg)); - struct reg_feature *feature; - int i; - - /* Build the process context cache */ - cache->name = "arm v7m registers"; - cache->next = NULL; - cache->reg_list = reg_list; - cache->num_regs = num_regs; - (*cache_p) = cache; - - for (i = 0; i < num_regs; i++) { - arch_info[i].num = armv7m_regs[i].id; - arch_info[i].target = target; - arch_info[i].arm = arm; - - reg_list[i].name = armv7m_regs[i].name; - reg_list[i].size = armv7m_regs[i].bits; - size_t storage_size = DIV_ROUND_UP(armv7m_regs[i].bits, 8); - if (storage_size < 4) - storage_size = 4; - reg_list[i].value = calloc(1, storage_size); - reg_list[i].dirty = 0; - reg_list[i].valid = 0; - reg_list[i].type = &armv7m_reg_type; - reg_list[i].arch_info = &arch_info[i]; - - reg_list[i].group = armv7m_regs[i].group; - reg_list[i].number = i; - reg_list[i].exist = true; - reg_list[i].caller_save = true; /* gdb defaults to true */ - - feature = calloc(1, sizeof(struct reg_feature)); - if (feature) { - feature->name = armv7m_regs[i].feature; - reg_list[i].feature = feature; - } else - LOG_ERROR("unable to allocate feature list"); - - reg_list[i].reg_data_type = calloc(1, sizeof(struct reg_data_type)); - if (reg_list[i].reg_data_type) - reg_list[i].reg_data_type->type = armv7m_regs[i].type; - else - LOG_ERROR("unable to allocate reg type list"); - } - - arm->cpsr = reg_list + ARMV7M_xPSR; - arm->pc = reg_list + ARMV7M_PC; - arm->core_cache = cache; - - return cache; -} - -void armv7m_free_reg_cache(struct target *target) -{ - struct armv7m_common *armv7m = target_to_armv7m(target); - struct arm *arm = &armv7m->arm; - struct reg_cache *cache; - struct reg *reg; - unsigned int i; - - cache = arm->core_cache; - - if (!cache) - return; - - for (i = 0; i < cache->num_regs; i++) { - reg = &cache->reg_list[i]; - - free(reg->feature); - free(reg->reg_data_type); - free(reg->value); - } - - free(cache->reg_list[0].arch_info); - free(cache->reg_list); - free(cache); - - arm->core_cache = NULL; -} - -static int armv7m_setup_semihosting(struct target *target, int enable) -{ - /* nothing todo for armv7m */ - return ERROR_OK; -} - -/** Sets up target as a generic ARMv7-M core */ -int armv7m_init_arch_info(struct target *target, struct armv7m_common *armv7m) -{ - struct arm *arm = &armv7m->arm; - - armv7m->common_magic = ARMV7M_COMMON_MAGIC; - armv7m->fp_feature = FP_NONE; - armv7m->trace_config.trace_bus_id = 1; - /* Enable stimulus port #0 by default */ - armv7m->trace_config.itm_ter[0] = 1; - - arm->core_type = ARM_MODE_THREAD; - arm->arch_info = armv7m; - arm->setup_semihosting = armv7m_setup_semihosting; - - arm->read_core_reg = armv7m_read_core_reg; - arm->write_core_reg = armv7m_write_core_reg; - - return arm_init_arch_info(target, arm); -} - -/** Generates a CRC32 checksum of a memory region. */ -int armv7m_checksum_memory(struct target *target, - uint32_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; - - static const uint8_t cortex_m_crc_code[] = { -#include "../../contrib/loaders/checksum/armv7m_crc.inc" - }; - - retval = target_alloc_working_area(target, sizeof(cortex_m_crc_code), &crc_algorithm); - if (retval != ERROR_OK) - return retval; - - retval = target_write_buffer(target, crc_algorithm->address, - sizeof(cortex_m_crc_code), (uint8_t *)cortex_m_crc_code); - if (retval != ERROR_OK) - goto cleanup; - - armv7m_info.common_magic = ARMV7M_COMMON_MAGIC; - armv7m_info.core_mode = ARM_MODE_THREAD; - - init_reg_param(®_params[0], "r0", 32, PARAM_IN_OUT); - init_reg_param(®_params[1], "r1", 32, PARAM_OUT); - - buf_set_u32(reg_params[0].value, 0, 32, address); - buf_set_u32(reg_params[1].value, 0, 32, count); - - int timeout = 20000 * (1 + (count / (1024 * 1024))); - - retval = target_run_algorithm(target, 0, NULL, 2, reg_params, crc_algorithm->address, - crc_algorithm->address + (sizeof(cortex_m_crc_code) - 6), - timeout, &armv7m_info); - - if (retval == ERROR_OK) - *checksum = buf_get_u32(reg_params[0].value, 0, 32); - else - LOG_ERROR("error executing cortex_m crc algorithm"); - - destroy_reg_param(®_params[0]); - destroy_reg_param(®_params[1]); - -cleanup: - target_free_working_area(target, crc_algorithm); - - return retval; -} - -/** Checks whether a memory region is zeroed. */ -int armv7m_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; - - static const uint8_t erase_check_code[] = { -#include "../../contrib/loaders/erase_check/armv7m_erase_check.inc" - }; - - /* 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) - goto cleanup; - - 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, 0xff); - - 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]); - -cleanup: - target_free_working_area(target, erase_check_algorithm); - - return retval; -} - -int armv7m_maybe_skip_bkpt_inst(struct target *target, bool *inst_found) -{ - struct armv7m_common *armv7m = target_to_armv7m(target); - struct reg *r = armv7m->arm.pc; - bool result = false; - - - /* if we halted last time due to a bkpt instruction - * then we have to manually step over it, otherwise - * the core will break again */ - - if (target->debug_reason == DBG_REASON_BREAKPOINT) { - uint16_t op; - uint32_t pc = buf_get_u32(r->value, 0, 32); - - pc &= ~1; - if (target_read_u16(target, pc, &op) == ERROR_OK) { - if ((op & 0xFF00) == 0xBE00) { - pc = buf_get_u32(r->value, 0, 32) + 2; - buf_set_u32(r->value, 0, 32, pc); - r->dirty = true; - r->valid = true; - result = true; - LOG_DEBUG("Skipping over BKPT instruction"); - } - } - } - - if (inst_found) - *inst_found = result; - - return ERROR_OK; -} - -const struct command_registration armv7m_command_handlers[] = { - { - .chain = arm_command_handlers, - }, - { - .chain = dap_command_handlers, - }, - COMMAND_REGISTRATION_DONE -}; diff --git a/src/target/armv7m.h b/src/target/armv7m.h deleted file mode 100644 index 90cad00c2..000000000 --- a/src/target/armv7m.h +++ /dev/null @@ -1,234 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * Copyright (C) 2006 by Magnus Lundin * - * lundin@mlu.mine.nu * - * * - * Copyright (C) 2008 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifndef OPENOCD_TARGET_ARMV7M_H -#define OPENOCD_TARGET_ARMV7M_H - -#include "arm_adi_v5.h" -#include "arm.h" -#include "armv7m_trace.h" - -extern const int armv7m_psp_reg_map[]; -extern const int armv7m_msp_reg_map[]; - -const char *armv7m_exception_string(int number); - -/* offsets into armv7m core register cache */ -enum { - /* for convenience, the first set of indices match - * the Cortex-M3/-M4 DCRSR selectors - */ - ARMV7M_R0, - ARMV7M_R1, - ARMV7M_R2, - ARMV7M_R3, - - ARMV7M_R4, - ARMV7M_R5, - ARMV7M_R6, - ARMV7M_R7, - - ARMV7M_R8, - ARMV7M_R9, - ARMV7M_R10, - ARMV7M_R11, - - ARMV7M_R12, - ARMV7M_R13, - ARMV7M_R14, - ARMV7M_PC = 15, - - ARMV7M_xPSR = 16, - ARMV7M_MSP, - ARMV7M_PSP, - - /* this next set of indices is arbitrary */ - ARMV7M_PRIMASK, - ARMV7M_BASEPRI, - ARMV7M_FAULTMASK, - ARMV7M_CONTROL, - - /* 32bit Floating-point registers */ - ARMV7M_S0, - ARMV7M_S1, - ARMV7M_S2, - ARMV7M_S3, - ARMV7M_S4, - ARMV7M_S5, - ARMV7M_S6, - ARMV7M_S7, - ARMV7M_S8, - ARMV7M_S9, - ARMV7M_S10, - ARMV7M_S11, - ARMV7M_S12, - ARMV7M_S13, - ARMV7M_S14, - ARMV7M_S15, - ARMV7M_S16, - ARMV7M_S17, - ARMV7M_S18, - ARMV7M_S19, - ARMV7M_S20, - ARMV7M_S21, - ARMV7M_S22, - ARMV7M_S23, - ARMV7M_S24, - ARMV7M_S25, - ARMV7M_S26, - ARMV7M_S27, - ARMV7M_S28, - ARMV7M_S29, - ARMV7M_S30, - ARMV7M_S31, - - /* 64bit Floating-point registers */ - ARMV7M_D0, - ARMV7M_D1, - ARMV7M_D2, - ARMV7M_D3, - ARMV7M_D4, - ARMV7M_D5, - ARMV7M_D6, - ARMV7M_D7, - ARMV7M_D8, - ARMV7M_D9, - ARMV7M_D10, - ARMV7M_D11, - ARMV7M_D12, - ARMV7M_D13, - ARMV7M_D14, - ARMV7M_D15, - - /* Floating-point status registers */ - ARMV7M_FPSID, - ARMV7M_FPSCR, - ARMV7M_FPEXC, - - ARMV7M_LAST_REG, -}; - -enum { - FP_NONE = 0, - FPv4_SP, - FPv5_SP, - FPv5_DP, -}; - -#define ARMV7M_NUM_CORE_REGS (ARMV7M_xPSR + 1) -#define ARMV7M_NUM_CORE_REGS_NOFP (ARMV7M_NUM_CORE_REGS + 6) - -#define ARMV7M_COMMON_MAGIC 0x2A452A45 - -struct armv7m_common { - struct arm arm; - - int common_magic; - int exception_number; - - /* AP this processor is connected to in the DAP */ - struct adiv5_ap *debug_ap; - - int fp_feature; - uint32_t demcr; - - /* stlink is a high level adapter, does not support all functions */ - bool stlink; - - struct armv7m_trace_config trace_config; - - /* Direct processor core register read and writes */ - int (*load_core_reg_u32)(struct target *target, uint32_t num, uint32_t *value); - int (*store_core_reg_u32)(struct target *target, uint32_t num, uint32_t value); - - int (*examine_debug_reason)(struct target *target); - int (*post_debug_entry)(struct target *target); - - void (*pre_restore_context)(struct target *target); -}; - -static inline struct armv7m_common * -target_to_armv7m(struct target *target) -{ - return container_of(target->arch_info, struct armv7m_common, arm); -} - -static inline bool is_armv7m(struct armv7m_common *armv7m) -{ - return armv7m->common_magic == ARMV7M_COMMON_MAGIC; -} - -struct armv7m_algorithm { - int common_magic; - - enum arm_mode core_mode; - - uint32_t context[ARMV7M_LAST_REG]; /* ARMV7M_NUM_REGS */ -}; - -struct reg_cache *armv7m_build_reg_cache(struct target *target); -void armv7m_free_reg_cache(struct target *target); - -enum armv7m_mode armv7m_number_to_mode(int number); -int armv7m_mode_to_number(enum armv7m_mode mode); - -int armv7m_arch_state(struct target *target); -int armv7m_get_gdb_reg_list(struct target *target, - struct reg **reg_list[], int *reg_list_size, - enum target_register_class reg_class); - -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, - 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, - 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, - void *arch_info); - -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); -int armv7m_blank_check_memory(struct target *target, - uint32_t address, uint32_t count, uint32_t *blank); - -int armv7m_maybe_skip_bkpt_inst(struct target *target, bool *inst_found); - -extern const struct command_registration armv7m_command_handlers[]; - -#endif /* OPENOCD_TARGET_ARMV7M_H */ diff --git a/src/target/armv7m_trace.c b/src/target/armv7m_trace.c deleted file mode 100644 index c1e4f5baa..000000000 --- a/src/target/armv7m_trace.c +++ /dev/null @@ -1,351 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2015 Paul Fertser * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 -#include "config.h" -#endif - -#include -#include -#include -#include -#include - -#define TRACE_BUF_SIZE 4096 - -static int armv7m_poll_trace(void *target) -{ - struct armv7m_common *armv7m = target_to_armv7m(target); - uint8_t buf[TRACE_BUF_SIZE]; - size_t size = sizeof(buf); - int retval; - - retval = adapter_poll_trace(buf, &size); - if (retval != ERROR_OK || !size) - return retval; - - target_call_trace_callbacks(target, size, buf); - - if (armv7m->trace_config.trace_file != NULL) { - if (fwrite(buf, 1, size, armv7m->trace_config.trace_file) == size) - fflush(armv7m->trace_config.trace_file); - else { - LOG_ERROR("Error writing to the trace destination file"); - return ERROR_FAIL; - } - } - - return ERROR_OK; -} - -int armv7m_trace_tpiu_config(struct target *target) -{ - struct armv7m_common *armv7m = target_to_armv7m(target); - struct armv7m_trace_config *trace_config = &armv7m->trace_config; - int prescaler; - int retval; - - target_unregister_timer_callback(armv7m_poll_trace, target); - - - retval = adapter_config_trace(trace_config->config_type == INTERNAL, - trace_config->pin_protocol, - trace_config->port_size, - &trace_config->trace_freq); - if (retval != ERROR_OK) - return retval; - - if (!trace_config->trace_freq) { - LOG_ERROR("Trace port frequency is 0, can't enable TPIU"); - return ERROR_FAIL; - } - - prescaler = trace_config->traceclkin_freq / trace_config->trace_freq; - - if (trace_config->traceclkin_freq % trace_config->trace_freq) { - prescaler++; - int trace_freq = trace_config->traceclkin_freq / prescaler; - LOG_INFO("Can not obtain %u trace port frequency from %u TRACECLKIN frequency, using %u instead", - trace_config->trace_freq, trace_config->traceclkin_freq, - trace_freq); - trace_config->trace_freq = trace_freq; - retval = adapter_config_trace(trace_config->config_type == INTERNAL, - trace_config->pin_protocol, - trace_config->port_size, - &trace_config->trace_freq); - if (retval != ERROR_OK) - return retval; - } - - retval = target_write_u32(target, TPIU_CSPSR, 1 << trace_config->port_size); - if (retval != ERROR_OK) - return retval; - - retval = target_write_u32(target, TPIU_ACPR, prescaler - 1); - if (retval != ERROR_OK) - return retval; - - retval = target_write_u32(target, TPIU_SPPR, trace_config->pin_protocol); - if (retval != ERROR_OK) - return retval; - - uint32_t ffcr; - retval = target_read_u32(target, TPIU_FFCR, &ffcr); - if (retval != ERROR_OK) - return retval; - if (trace_config->formatter) - ffcr |= (1 << 1); - else - ffcr &= ~(1 << 1); - retval = target_write_u32(target, TPIU_FFCR, ffcr); - if (retval != ERROR_OK) - return retval; - - if (trace_config->config_type == INTERNAL) - target_register_timer_callback(armv7m_poll_trace, 1, 1, target); - - target_call_event_callbacks(target, TARGET_EVENT_TRACE_CONFIG); - - return ERROR_OK; -} - -int armv7m_trace_itm_config(struct target *target) -{ - struct armv7m_common *armv7m = target_to_armv7m(target); - struct armv7m_trace_config *trace_config = &armv7m->trace_config; - int retval; - - retval = target_write_u32(target, ITM_LAR, ITM_LAR_KEY); - if (retval != ERROR_OK) - return retval; - - /* Enable ITM, TXENA, set TraceBusID and other parameters */ - retval = target_write_u32(target, ITM_TCR, (1 << 0) | (1 << 3) | - (trace_config->itm_diff_timestamps << 1) | - (trace_config->itm_synchro_packets << 2) | - (trace_config->itm_async_timestamps << 4) | - (trace_config->itm_ts_prescale << 8) | - (trace_config->trace_bus_id << 16)); - if (retval != ERROR_OK) - return retval; - - for (unsigned int i = 0; i < 8; i++) { - retval = target_write_u32(target, ITM_TER0 + i * 4, - trace_config->itm_ter[i]); - if (retval != ERROR_OK) - return retval; - } - - return ERROR_OK; -} - -static void close_trace_file(struct armv7m_common *armv7m) -{ - if (armv7m->trace_config.trace_file) - fclose(armv7m->trace_config.trace_file); - armv7m->trace_config.trace_file = NULL; -} - -COMMAND_HANDLER(handle_tpiu_config_command) -{ - struct target *target = get_current_target(CMD_CTX); - struct armv7m_common *armv7m = target_to_armv7m(target); - - unsigned int cmd_idx = 0; - - if (CMD_ARGC == cmd_idx) - return ERROR_COMMAND_SYNTAX_ERROR; - if (!strcmp(CMD_ARGV[cmd_idx], "disable")) { - if (CMD_ARGC == cmd_idx + 1) { - close_trace_file(armv7m); - - armv7m->trace_config.config_type = DISABLED; - if (CMD_CTX->mode == COMMAND_EXEC) - return armv7m_trace_tpiu_config(target); - else - return ERROR_OK; - } - } else if (!strcmp(CMD_ARGV[cmd_idx], "external") || - !strcmp(CMD_ARGV[cmd_idx], "internal")) { - close_trace_file(armv7m); - - armv7m->trace_config.config_type = EXTERNAL; - if (!strcmp(CMD_ARGV[cmd_idx], "internal")) { - cmd_idx++; - if (CMD_ARGC == cmd_idx) - return ERROR_COMMAND_SYNTAX_ERROR; - - armv7m->trace_config.config_type = INTERNAL; - - if (strcmp(CMD_ARGV[cmd_idx], "-") != 0) { - armv7m->trace_config.trace_file = fopen(CMD_ARGV[cmd_idx], "ab"); - if (!armv7m->trace_config.trace_file) { - LOG_ERROR("Can't open trace destination file"); - return ERROR_FAIL; - } - } - } - cmd_idx++; - if (CMD_ARGC == cmd_idx) - return ERROR_COMMAND_SYNTAX_ERROR; - - if (!strcmp(CMD_ARGV[cmd_idx], "sync")) { - armv7m->trace_config.pin_protocol = SYNC; - - cmd_idx++; - if (CMD_ARGC == cmd_idx) - return ERROR_COMMAND_SYNTAX_ERROR; - - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[cmd_idx], armv7m->trace_config.port_size); - } else { - if (!strcmp(CMD_ARGV[cmd_idx], "manchester")) - armv7m->trace_config.pin_protocol = ASYNC_MANCHESTER; - else if (!strcmp(CMD_ARGV[cmd_idx], "uart")) - armv7m->trace_config.pin_protocol = ASYNC_UART; - else - return ERROR_COMMAND_SYNTAX_ERROR; - - cmd_idx++; - if (CMD_ARGC == cmd_idx) - return ERROR_COMMAND_SYNTAX_ERROR; - - COMMAND_PARSE_ON_OFF(CMD_ARGV[cmd_idx], armv7m->trace_config.formatter); - } - - cmd_idx++; - if (CMD_ARGC == cmd_idx) - return ERROR_COMMAND_SYNTAX_ERROR; - - COMMAND_PARSE_NUMBER(uint, CMD_ARGV[cmd_idx], armv7m->trace_config.traceclkin_freq); - - cmd_idx++; - if (CMD_ARGC != cmd_idx) { - COMMAND_PARSE_NUMBER(uint, CMD_ARGV[cmd_idx], armv7m->trace_config.trace_freq); - cmd_idx++; - } else { - if (armv7m->trace_config.config_type != INTERNAL) { - LOG_ERROR("Trace port frequency can't be omitted in external capture mode"); - return ERROR_COMMAND_SYNTAX_ERROR; - } - armv7m->trace_config.trace_freq = 0; - } - - if (CMD_ARGC == cmd_idx) { - if (CMD_CTX->mode == COMMAND_EXEC) - return armv7m_trace_tpiu_config(target); - else - return ERROR_OK; - } - } - - return ERROR_COMMAND_SYNTAX_ERROR; -} - -COMMAND_HANDLER(handle_itm_port_command) -{ - struct target *target = get_current_target(CMD_CTX); - struct armv7m_common *armv7m = target_to_armv7m(target); - unsigned int reg_idx; - uint8_t port; - bool enable; - - if (CMD_ARGC != 2) - return ERROR_COMMAND_SYNTAX_ERROR; - - COMMAND_PARSE_NUMBER(u8, CMD_ARGV[0], port); - COMMAND_PARSE_ON_OFF(CMD_ARGV[1], enable); - reg_idx = port / 32; - port = port % 32; - if (enable) - armv7m->trace_config.itm_ter[reg_idx] |= (1 << port); - else - armv7m->trace_config.itm_ter[reg_idx] &= ~(1 << port); - - if (CMD_CTX->mode == COMMAND_EXEC) - return armv7m_trace_itm_config(target); - else - return ERROR_OK; -} - -COMMAND_HANDLER(handle_itm_ports_command) -{ - struct target *target = get_current_target(CMD_CTX); - struct armv7m_common *armv7m = target_to_armv7m(target); - bool enable; - - if (CMD_ARGC != 1) - return ERROR_COMMAND_SYNTAX_ERROR; - - COMMAND_PARSE_ON_OFF(CMD_ARGV[0], enable); - memset(armv7m->trace_config.itm_ter, enable ? 0xff : 0, - sizeof(armv7m->trace_config.itm_ter)); - - if (CMD_CTX->mode == COMMAND_EXEC) - return armv7m_trace_itm_config(target); - else - return ERROR_OK; -} - -static const struct command_registration tpiu_command_handlers[] = { - { - .name = "config", - .handler = handle_tpiu_config_command, - .mode = COMMAND_ANY, - .help = "Configure TPIU features", - .usage = "(disable | " - "((external | internal ) " - "(sync | ((manchester | uart) )) " - " []))", - }, - COMMAND_REGISTRATION_DONE -}; - -static const struct command_registration itm_command_handlers[] = { - { - .name = "port", - .handler = handle_itm_port_command, - .mode = COMMAND_ANY, - .help = "Enable or disable ITM stimulus port", - .usage = " (0|1|on|off)", - }, - { - .name = "ports", - .handler = handle_itm_ports_command, - .mode = COMMAND_ANY, - .help = "Enable or disable all ITM stimulus ports", - .usage = "(0|1|on|off)", - }, - COMMAND_REGISTRATION_DONE -}; - -const struct command_registration armv7m_trace_command_handlers[] = { - { - .name = "tpiu", - .mode = COMMAND_ANY, - .help = "tpiu command group", - .usage = "", - .chain = tpiu_command_handlers, - }, - { - .name = "itm", - .mode = COMMAND_ANY, - .help = "itm command group", - .usage = "", - .chain = itm_command_handlers, - }, - COMMAND_REGISTRATION_DONE -}; diff --git a/src/target/armv7m_trace.h b/src/target/armv7m_trace.h deleted file mode 100644 index 4f9939464..000000000 --- a/src/target/armv7m_trace.h +++ /dev/null @@ -1,91 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2015 Paul Fertser * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 OPENOCD_TARGET_ARMV7M_TRACE_H -#define OPENOCD_TARGET_ARMV7M_TRACE_H - -#include -#include - -/** - * @file - * Holds the interface to TPIU, ITM and DWT configuration functions. - */ - -enum trace_config_type { - DISABLED, /**< tracing is disabled */ - EXTERNAL, /**< trace output is captured externally */ - INTERNAL /**< trace output is handled by OpenOCD adapter driver */ -}; - -enum tpio_pin_protocol { - SYNC, /**< synchronous trace output */ - ASYNC_MANCHESTER, /**< asynchronous output with Manchester coding */ - ASYNC_UART /**< asynchronous output with NRZ coding */ -}; - -enum itm_ts_prescaler { - ITM_TS_PRESCALE1, /**< no prescaling for the timestamp counter */ - ITM_TS_PRESCALE4, /**< refclock divided by 4 for the timestamp counter */ - ITM_TS_PRESCALE16, /**< refclock divided by 16 for the timestamp counter */ - ITM_TS_PRESCALE64, /**< refclock divided by 64 for the timestamp counter */ -}; - -struct armv7m_trace_config { - /** Currently active trace capture mode */ - enum trace_config_type config_type; - - /** Currently active trace output mode */ - enum tpio_pin_protocol pin_protocol; - /** TPIU formatter enable/disable (in async mode) */ - bool formatter; - /** Synchronous output port width */ - uint32_t port_size; - - /** Bitmask of currenty enabled ITM stimuli */ - uint32_t itm_ter[8]; - /** Identifier for multi-source trace stream formatting */ - unsigned int trace_bus_id; - /** Prescaler for the timestamp counter */ - enum itm_ts_prescaler itm_ts_prescale; - /** Enable differential timestamps */ - bool itm_diff_timestamps; - /** Enable async timestamps model */ - bool itm_async_timestamps; - /** Enable synchronisation packet transmission (for sync port only) */ - bool itm_synchro_packets; - - /** Current frequency of TRACECLKIN (usually matches HCLK) */ - unsigned int traceclkin_freq; - /** Current frequency of trace port */ - unsigned int trace_freq; - /** Handle to output trace data in INTERNAL capture mode */ - FILE *trace_file; -}; - -extern const struct command_registration armv7m_trace_command_handlers[]; - -/** - * Configure hardware accordingly to the current TPIU target settings - */ -int armv7m_trace_tpiu_config(struct target *target); -/** - * Configure hardware accordingly to the current ITM target settings - */ -int armv7m_trace_itm_config(struct target *target); - -#endif /* OPENOCD_TARGET_ARMV7M_TRACE_H */ diff --git a/src/target/avr32_ap7k.c b/src/target/avr32_ap7k.c deleted file mode 100644 index e5634f2de..000000000 --- a/src/target/avr32_ap7k.c +++ /dev/null @@ -1,624 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2010 by Oleksandr Tymoshenko * - * Based on mips_m4k code: * - * Copyright (C) 2008 by Spencer Oliver * - * Copyright (C) 2008 by David T.L. Wong * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "jtag/jtag.h" -#include "register.h" -#include "algorithm.h" -#include "target.h" -#include "breakpoints.h" -#include "target_type.h" -#include "avr32_jtag.h" -#include "avr32_mem.h" -#include "avr32_regs.h" -#include "avr32_ap7k.h" - -static const char * const avr32_core_reg_list[] = { - "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", - "r9", "r10", "r11", "r12", "sp", "lr", "pc", "sr" -}; - -static const struct avr32_core_reg - avr32_core_reg_list_arch_info[AVR32NUMCOREREGS] = { - {0, NULL, NULL}, - {1, NULL, NULL}, - {2, NULL, NULL}, - {3, NULL, NULL}, - {4, NULL, NULL}, - {5, NULL, NULL}, - {6, NULL, NULL}, - {7, NULL, NULL}, - {8, NULL, NULL}, - {9, NULL, NULL}, - {10, NULL, NULL}, - {11, NULL, NULL}, - {12, NULL, NULL}, - {13, NULL, NULL}, - {14, NULL, NULL}, - {15, NULL, NULL}, - {16, NULL, NULL}, -}; - - -static int avr32_read_core_reg(struct target *target, int num); -static int avr32_write_core_reg(struct target *target, int num); - -int avr32_ap7k_save_context(struct target *target) -{ - int retval, i; - struct avr32_ap7k_common *ap7k = target_to_ap7k(target); - - retval = avr32_jtag_read_regs(&ap7k->jtag, ap7k->core_regs); - if (retval != ERROR_OK) - return retval; - - for (i = 0; i < AVR32NUMCOREREGS; i++) { - if (!ap7k->core_cache->reg_list[i].valid) - avr32_read_core_reg(target, i); - } - - return ERROR_OK; -} - -int avr32_ap7k_restore_context(struct target *target) -{ - int i; - - /* get pointers to arch-specific information */ - struct avr32_ap7k_common *ap7k = target_to_ap7k(target); - - for (i = 0; i < AVR32NUMCOREREGS; i++) { - if (ap7k->core_cache->reg_list[i].dirty) - avr32_write_core_reg(target, i); - } - - /* write core regs */ - avr32_jtag_write_regs(&ap7k->jtag, ap7k->core_regs); - - return ERROR_OK; -} - -static int avr32_read_core_reg(struct target *target, int num) -{ - uint32_t reg_value; - - /* get pointers to arch-specific information */ - struct avr32_ap7k_common *ap7k = target_to_ap7k(target); - - if ((num < 0) || (num >= AVR32NUMCOREREGS)) - return ERROR_COMMAND_SYNTAX_ERROR; - - reg_value = ap7k->core_regs[num]; - buf_set_u32(ap7k->core_cache->reg_list[num].value, 0, 32, reg_value); - ap7k->core_cache->reg_list[num].valid = 1; - ap7k->core_cache->reg_list[num].dirty = 0; - - return ERROR_OK; -} - -static int avr32_write_core_reg(struct target *target, int num) -{ - uint32_t reg_value; - - /* get pointers to arch-specific information */ - struct avr32_ap7k_common *ap7k = target_to_ap7k(target); - - if ((num < 0) || (num >= AVR32NUMCOREREGS)) - return ERROR_COMMAND_SYNTAX_ERROR; - - reg_value = buf_get_u32(ap7k->core_cache->reg_list[num].value, 0, 32); - ap7k->core_regs[num] = reg_value; - LOG_DEBUG("write core reg %i value 0x%" PRIx32 "", num, reg_value); - ap7k->core_cache->reg_list[num].valid = 1; - ap7k->core_cache->reg_list[num].dirty = 0; - - return ERROR_OK; -} - -static int avr32_get_core_reg(struct reg *reg) -{ - int retval; - struct avr32_core_reg *avr32_reg = reg->arch_info; - struct target *target = avr32_reg->target; - - if (target->state != TARGET_HALTED) - return ERROR_TARGET_NOT_HALTED; - - retval = avr32_read_core_reg(target, avr32_reg->num); - - return retval; -} - -static int avr32_set_core_reg(struct reg *reg, uint8_t *buf) -{ - struct avr32_core_reg *avr32_reg = reg->arch_info; - struct target *target = avr32_reg->target; - uint32_t value = buf_get_u32(buf, 0, 32); - - if (target->state != TARGET_HALTED) - return ERROR_TARGET_NOT_HALTED; - - buf_set_u32(reg->value, 0, 32, value); - reg->dirty = 1; - reg->valid = 1; - - return ERROR_OK; -} - -static const struct reg_arch_type avr32_reg_type = { - .get = avr32_get_core_reg, - .set = avr32_set_core_reg, -}; - -static struct reg_cache *avr32_build_reg_cache(struct target *target) -{ - int num_regs = AVR32NUMCOREREGS; - struct avr32_ap7k_common *ap7k = target_to_ap7k(target); - struct reg_cache **cache_p = register_get_last_cache_p(&target->reg_cache); - struct reg_cache *cache = malloc(sizeof(struct reg_cache)); - struct reg *reg_list = calloc(num_regs, sizeof(struct reg)); - struct avr32_core_reg *arch_info = - malloc(sizeof(struct avr32_core_reg) * num_regs); - int i; - - /* Build the process context cache */ - cache->name = "avr32 registers"; - cache->next = NULL; - cache->reg_list = reg_list; - cache->num_regs = num_regs; - (*cache_p) = cache; - ap7k->core_cache = cache; - - for (i = 0; i < num_regs; i++) { - arch_info[i] = avr32_core_reg_list_arch_info[i]; - arch_info[i].target = target; - arch_info[i].avr32_common = ap7k; - reg_list[i].name = avr32_core_reg_list[i]; - reg_list[i].size = 32; - reg_list[i].value = calloc(1, 4); - reg_list[i].dirty = 0; - reg_list[i].valid = 0; - reg_list[i].type = &avr32_reg_type; - reg_list[i].arch_info = &arch_info[i]; - } - - return cache; -} - -static int avr32_ap7k_debug_entry(struct target *target) -{ - - uint32_t dpc, dinst; - int retval; - struct avr32_ap7k_common *ap7k = target_to_ap7k(target); - - retval = avr32_jtag_nexus_read(&ap7k->jtag, AVR32_OCDREG_DPC, &dpc); - if (retval != ERROR_OK) - return retval; - - retval = avr32_jtag_nexus_read(&ap7k->jtag, AVR32_OCDREG_DINST, &dinst); - if (retval != ERROR_OK) - return retval; - - ap7k->jtag.dpc = dpc; - - avr32_ap7k_save_context(target); - - return ERROR_OK; -} - - -static int avr32_ap7k_poll(struct target *target) -{ - uint32_t ds; - int retval; - struct avr32_ap7k_common *ap7k = target_to_ap7k(target); - - retval = avr32_jtag_nexus_read(&ap7k->jtag, AVR32_OCDREG_DS, &ds); - if (retval != ERROR_OK) - return retval; - - /* check for processor halted */ - if (ds & OCDREG_DS_DBA) { - if ((target->state == TARGET_RUNNING) || (target->state == TARGET_RESET)) { - target->state = TARGET_HALTED; - - retval = avr32_ap7k_debug_entry(target); - if (retval != ERROR_OK) - return retval; - - target_call_event_callbacks(target, TARGET_EVENT_HALTED); - } else if (target->state == TARGET_DEBUG_RUNNING) { - target->state = TARGET_HALTED; - - retval = avr32_ap7k_debug_entry(target); - if (retval != ERROR_OK) - return retval; - - target_call_event_callbacks(target, TARGET_EVENT_DEBUG_HALTED); - } - } else - target->state = TARGET_RUNNING; - - - return ERROR_OK; -} - -static int avr32_ap7k_halt(struct target *target) -{ - struct avr32_ap7k_common *ap7k = target_to_ap7k(target); - - LOG_DEBUG("target->state: %s", - target_state_name(target)); - - if (target->state == TARGET_HALTED) { - LOG_DEBUG("target was already halted"); - return ERROR_OK; - } - - if (target->state == TARGET_UNKNOWN) - LOG_WARNING("target was in unknown state when halt was requested"); - - if (target->state == TARGET_RESET) { - if ((jtag_get_reset_config() & RESET_SRST_PULLS_TRST) && jtag_get_srst()) { - LOG_ERROR("can't request a halt while in reset if nSRST pulls nTRST"); - return ERROR_TARGET_FAILURE; - } else { - target->debug_reason = DBG_REASON_DBGRQ; - - return ERROR_OK; - } - } - - - avr32_ocd_setbits(&ap7k->jtag, AVR32_OCDREG_DC, OCDREG_DC_DBR); - target->debug_reason = DBG_REASON_DBGRQ; - - return ERROR_OK; -} - -static int avr32_ap7k_assert_reset(struct target *target) -{ - LOG_ERROR("%s: implement me", __func__); - - return ERROR_OK; -} - -static int avr32_ap7k_deassert_reset(struct target *target) -{ - LOG_ERROR("%s: implement me", __func__); - - return ERROR_OK; -} - -static int avr32_ap7k_resume(struct target *target, int current, - uint32_t address, int handle_breakpoints, int debug_execution) -{ - struct avr32_ap7k_common *ap7k = target_to_ap7k(target); - struct breakpoint *breakpoint = NULL; - uint32_t resume_pc; - int retval; - - if (target->state != TARGET_HALTED) { - LOG_WARNING("target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - if (!debug_execution) { - target_free_all_working_areas(target); - /* - avr32_ap7k_enable_breakpoints(target); - avr32_ap7k_enable_watchpoints(target); - */ - } - - /* current = 1: continue on current pc, otherwise continue at
*/ - if (!current) { -#if 0 - if (retval != ERROR_OK) - return retval; -#endif - } - - resume_pc = buf_get_u32(ap7k->core_cache->reg_list[AVR32_REG_PC].value, 0, 32); - avr32_ap7k_restore_context(target); - - /* the front-end may request us not to handle breakpoints */ - if (handle_breakpoints) { - /* 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); -#if 0 - avr32_ap7k_unset_breakpoint(target, breakpoint); - avr32_ap7k_single_step_core(target); - avr32_ap7k_set_breakpoint(target, breakpoint); -#endif - } - } - -#if 0 - /* enable interrupts if we are running */ - avr32_ap7k_enable_interrupts(target, !debug_execution); - - /* exit debug mode */ - mips_ejtag_exit_debug(ejtag_info); -#endif - - - retval = avr32_ocd_clearbits(&ap7k->jtag, AVR32_OCDREG_DC, - OCDREG_DC_DBR); - if (retval != ERROR_OK) - return retval; - - retval = avr32_jtag_exec(&ap7k->jtag, RETD); - if (retval != ERROR_OK) - return retval; - - target->debug_reason = DBG_REASON_NOTHALTED; - - /* registers are now invalid */ - register_cache_invalidate(ap7k->core_cache); - - if (!debug_execution) { - target->state = TARGET_RUNNING; - target_call_event_callbacks(target, TARGET_EVENT_RESUMED); - LOG_DEBUG("target resumed at 0x%" PRIx32 "", resume_pc); - } else { - target->state = TARGET_DEBUG_RUNNING; - target_call_event_callbacks(target, TARGET_EVENT_DEBUG_RESUMED); - LOG_DEBUG("target debug resumed at 0x%" PRIx32 "", resume_pc); - } - - return ERROR_OK; -} - -static int avr32_ap7k_step(struct target *target, int current, - uint32_t address, int handle_breakpoints) -{ - LOG_ERROR("%s: implement me", __func__); - - return ERROR_OK; -} - -static int avr32_ap7k_add_breakpoint(struct target *target, struct breakpoint *breakpoint) -{ - LOG_ERROR("%s: implement me", __func__); - - return ERROR_OK; -} - -static int avr32_ap7k_remove_breakpoint(struct target *target, - struct breakpoint *breakpoint) -{ - LOG_ERROR("%s: implement me", __func__); - - return ERROR_OK; -} - -static int avr32_ap7k_add_watchpoint(struct target *target, struct watchpoint *watchpoint) -{ - LOG_ERROR("%s: implement me", __func__); - - return ERROR_OK; -} - -static int avr32_ap7k_remove_watchpoint(struct target *target, - struct watchpoint *watchpoint) -{ - LOG_ERROR("%s: implement me", __func__); - - return ERROR_OK; -} - -static int avr32_ap7k_read_memory(struct target *target, uint32_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 "", - address, - size, - count); - - if (target->state != TARGET_HALTED) { - LOG_WARNING("target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - /* sanitize arguments */ - if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer)) - return ERROR_COMMAND_SYNTAX_ERROR; - - if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u))) - return ERROR_TARGET_UNALIGNED_ACCESS; - - switch (size) { - case 4: - return avr32_jtag_read_memory32(&ap7k->jtag, address, count, - (uint32_t *)(void *)buffer); - break; - case 2: - return avr32_jtag_read_memory16(&ap7k->jtag, address, count, - (uint16_t *)(void *)buffer); - break; - case 1: - return avr32_jtag_read_memory8(&ap7k->jtag, address, count, buffer); - break; - default: - break; - } - - return ERROR_OK; -} - -static int avr32_ap7k_write_memory(struct target *target, uint32_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 "", - address, - size, - count); - - if (target->state != TARGET_HALTED) { - LOG_WARNING("target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - /* sanitize arguments */ - if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer)) - return ERROR_COMMAND_SYNTAX_ERROR; - - if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u))) - return ERROR_TARGET_UNALIGNED_ACCESS; - - switch (size) { - case 4: - return avr32_jtag_write_memory32(&ap7k->jtag, address, count, - (uint32_t *)(void *)buffer); - break; - case 2: - return avr32_jtag_write_memory16(&ap7k->jtag, address, count, - (uint16_t *)(void *)buffer); - break; - case 1: - return avr32_jtag_write_memory8(&ap7k->jtag, address, count, buffer); - break; - default: - break; - } - - return ERROR_OK; -} - -static int avr32_ap7k_init_target(struct command_context *cmd_ctx, - struct target *target) -{ - struct avr32_ap7k_common *ap7k = target_to_ap7k(target); - - ap7k->jtag.tap = target->tap; - avr32_build_reg_cache(target); - return ERROR_OK; -} - -static int avr32_ap7k_target_create(struct target *target, Jim_Interp *interp) -{ - struct avr32_ap7k_common *ap7k = calloc(1, sizeof(struct - avr32_ap7k_common)); - - ap7k->common_magic = AP7k_COMMON_MAGIC; - target->arch_info = ap7k; - - return ERROR_OK; -} - -static int avr32_ap7k_examine(struct target *target) -{ - uint32_t devid, ds; - struct avr32_ap7k_common *ap7k = target_to_ap7k(target); - - if (!target_was_examined(target)) { - target_set_examined(target); - avr32_jtag_nexus_read(&ap7k->jtag, AVR32_OCDREG_DID, &devid); - LOG_INFO("device id: %08" PRIx32, devid); - avr32_ocd_setbits(&ap7k->jtag, AVR32_OCDREG_DC, OCDREG_DC_DBE); - avr32_jtag_nexus_read(&ap7k->jtag, AVR32_OCDREG_DS, &ds); - - /* check for processor halted */ - if (ds & OCDREG_DS_DBA) { - LOG_INFO("target is halted"); - target->state = TARGET_HALTED; - } else - target->state = TARGET_RUNNING; - } - - return ERROR_OK; -} - -int avr32_ap7k_arch_state(struct target *target) -{ - struct avr32_ap7k_common *ap7k = target_to_ap7k(target); - - LOG_USER("target halted due to %s, pc: 0x%8.8" PRIx32 "", - debug_reason_name(target), ap7k->jtag.dpc); - - return ERROR_OK; -} - -int avr32_ap7k_get_gdb_reg_list(struct target *target, struct reg **reg_list[], - int *reg_list_size, enum target_register_class reg_class) -{ -#if 0 - /* get pointers to arch-specific information */ - int i; - - /* include floating point registers */ - *reg_list_size = AVR32NUMCOREREGS + AVR32NUMFPREGS; - *reg_list = malloc(sizeof(struct reg *) * (*reg_list_size)); - - for (i = 0; i < AVR32NUMCOREREGS; i++) - (*reg_list)[i] = &mips32->core_cache->reg_list[i]; - - /* add dummy floating points regs */ - for (i = AVR32NUMCOREREGS; i < (AVR32NUMCOREREGS + AVR32NUMFPREGS); i++) - (*reg_list)[i] = &avr32_ap7k_gdb_dummy_fp_reg; - -#endif - - LOG_ERROR("%s: implement me", __func__); - return ERROR_FAIL; -} - -struct target_type avr32_ap7k_target = { - .name = "avr32_ap7k", - - .poll = avr32_ap7k_poll, - .arch_state = avr32_ap7k_arch_state, - - .halt = avr32_ap7k_halt, - .resume = avr32_ap7k_resume, - .step = avr32_ap7k_step, - - .assert_reset = avr32_ap7k_assert_reset, - .deassert_reset = avr32_ap7k_deassert_reset, - - .get_gdb_reg_list = avr32_ap7k_get_gdb_reg_list, - - .read_memory = avr32_ap7k_read_memory, - .write_memory = avr32_ap7k_write_memory, - /* .checksum_memory = avr32_ap7k_checksum_memory, */ - /* .blank_check_memory = avr32_ap7k_blank_check_memory, */ - - /* .run_algorithm = avr32_ap7k_run_algorithm, */ - - .add_breakpoint = avr32_ap7k_add_breakpoint, - .remove_breakpoint = avr32_ap7k_remove_breakpoint, - .add_watchpoint = avr32_ap7k_add_watchpoint, - .remove_watchpoint = avr32_ap7k_remove_watchpoint, - - .target_create = avr32_ap7k_target_create, - .init_target = avr32_ap7k_init_target, - .examine = avr32_ap7k_examine, -}; diff --git a/src/target/avr32_ap7k.h b/src/target/avr32_ap7k.h deleted file mode 100644 index 3f27534a3..000000000 --- a/src/target/avr32_ap7k.h +++ /dev/null @@ -1,43 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2010 by Oleksandr Tymoshenko * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 OPENOCD_TARGET_AVR32_AP7K_H -#define OPENOCD_TARGET_AVR32_AP7K_H - -struct target; - -#define AP7k_COMMON_MAGIC 0x4150374b -struct avr32_ap7k_common { - int common_magic; - struct avr32_jtag jtag; - struct reg_cache *core_cache; - uint32_t core_regs[AVR32NUMCOREREGS]; -}; - -static inline struct avr32_ap7k_common * -target_to_ap7k(struct target *target) -{ - return (struct avr32_ap7k_common *)target->arch_info; -} - -struct avr32_core_reg { - uint32_t num; - struct target *target; - struct avr32_ap7k_common *avr32_common; -}; - -#endif /* OPENOCD_TARGET_AVR32_AP7K_H */ diff --git a/src/target/avr32_jtag.c b/src/target/avr32_jtag.c deleted file mode 100644 index 6526810e2..000000000 --- a/src/target/avr32_jtag.c +++ /dev/null @@ -1,376 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2010 by Oleksandr Tymoshenko * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 -#include "config.h" -#endif - -#include "target.h" -#include "jtag/jtag.h" -#include "avr32_jtag.h" - -static int avr32_jtag_set_instr(struct avr32_jtag *jtag_info, int new_instr) -{ - struct jtag_tap *tap; - int busy = 0; - - tap = jtag_info->tap; - if (tap == NULL) - return ERROR_FAIL; - - if (buf_get_u32(tap->cur_instr, 0, tap->ir_length) != (uint32_t)new_instr) { - do { - struct scan_field field; - uint8_t t[4]; - uint8_t ret[4]; - - field.num_bits = tap->ir_length; - field.out_value = t; - buf_set_u32(t, 0, field.num_bits, new_instr); - field.in_value = ret; - - jtag_add_ir_scan(tap, &field, TAP_IDLE); - if (jtag_execute_queue() != ERROR_OK) { - LOG_ERROR("%s: setting address failed", __func__); - return ERROR_FAIL; - } - busy = buf_get_u32(ret, 2, 1); - } while (busy); /* check for busy bit */ - } - - return ERROR_OK; -} - -int avr32_jtag_nexus_set_address(struct avr32_jtag *jtag_info, - uint32_t addr, int mode) -{ - struct scan_field fields[2]; - uint8_t addr_buf[4]; - uint8_t busy_buf[4]; - int busy; - - memset(fields, 0, sizeof(fields)); - - do { - memset(addr_buf, 0, sizeof(addr_buf)); - memset(busy_buf, 0, sizeof(busy_buf)); - - buf_set_u32(addr_buf, 0, 1, mode); - buf_set_u32(addr_buf, 1, 7, addr); - - fields[0].num_bits = 26; - fields[0].in_value = NULL; - fields[0].out_value = NULL; - - fields[1].num_bits = 8; - fields[1].in_value = busy_buf; - fields[1].out_value = addr_buf; - - jtag_add_dr_scan(jtag_info->tap, 2, fields, TAP_IDLE); - if (jtag_execute_queue() != ERROR_OK) { - LOG_ERROR("%s: setting address failed", __func__); - return ERROR_FAIL; - } - busy = buf_get_u32(busy_buf, 6, 1); - } while (busy); - - return ERROR_OK; -} - - -int avr32_jtag_nexus_read_data(struct avr32_jtag *jtag_info, - uint32_t *pdata) -{ - - struct scan_field fields[2]; - uint8_t data_buf[4]; - uint8_t busy_buf[4]; - int busy; - - do { - memset(data_buf, 0, sizeof(data_buf)); - memset(busy_buf, 0, sizeof(busy_buf)); - - fields[0].num_bits = 32; - fields[0].out_value = NULL; - fields[0].in_value = data_buf; - - - fields[1].num_bits = 2; - fields[1].in_value = busy_buf; - fields[1].out_value = NULL; - - jtag_add_dr_scan(jtag_info->tap, 2, fields, TAP_IDLE); - - if (jtag_execute_queue() != ERROR_OK) { - LOG_ERROR("%s: reading data failed", __func__); - return ERROR_FAIL; - } - - busy = buf_get_u32(busy_buf, 0, 1); - } while (busy); - - *pdata = buf_get_u32(data_buf, 0, 32); - - return ERROR_OK; -} - -int avr32_jtag_nexus_write_data(struct avr32_jtag *jtag_info, - uint32_t data) -{ - - struct scan_field fields[2]; - uint8_t data_buf[4]; - uint8_t busy_buf[4]; - uint8_t dummy_buf[4]; - int busy; - - do { - memset(data_buf, 0, sizeof(data_buf)); - memset(busy_buf, 0, sizeof(busy_buf)); - memset(dummy_buf, 0, sizeof(dummy_buf)); - - fields[0].num_bits = 2; - fields[0].in_value = busy_buf; - fields[0].out_value = dummy_buf; - - - buf_set_u32(data_buf, 0, 32, data); - fields[1].num_bits = 32; - fields[1].in_value = NULL; - fields[1].out_value = data_buf; - - jtag_add_dr_scan(jtag_info->tap, 2, fields, TAP_IDLE); - - if (jtag_execute_queue() != ERROR_OK) { - LOG_ERROR("%s: reading data failed", __func__); - return ERROR_FAIL; - } - - busy = buf_get_u32(busy_buf, 0, 0); - } while (busy); - - - return ERROR_OK; -} - -int avr32_jtag_nexus_read(struct avr32_jtag *jtag_info, - uint32_t addr, uint32_t *value) -{ - avr32_jtag_set_instr(jtag_info, AVR32_INST_NEXUS_ACCESS); - avr32_jtag_nexus_set_address(jtag_info, addr, MODE_READ); - avr32_jtag_nexus_read_data(jtag_info, value); - - return ERROR_OK; - -} -int avr32_jtag_nexus_write(struct avr32_jtag *jtag_info, - uint32_t addr, uint32_t value) -{ - avr32_jtag_set_instr(jtag_info, AVR32_INST_NEXUS_ACCESS); - avr32_jtag_nexus_set_address(jtag_info, addr, MODE_WRITE); - avr32_jtag_nexus_write_data(jtag_info, value); - - return ERROR_OK; -} - -int avr32_jtag_mwa_set_address(struct avr32_jtag *jtag_info, int slave, - uint32_t addr, int mode) -{ - struct scan_field fields[2]; - uint8_t addr_buf[4]; - uint8_t slave_buf[4]; - uint8_t busy_buf[4]; - int busy; - - memset(fields, 0, sizeof(fields)); - - do { - memset(addr_buf, 0, sizeof(addr_buf)); - memset(busy_buf, 0, sizeof(busy_buf)); - memset(slave_buf, 0, sizeof(slave_buf)); - - buf_set_u32(slave_buf, 0, 4, slave); - buf_set_u32(addr_buf, 0, 1, mode); - buf_set_u32(addr_buf, 1, 30, addr >> 2); - - fields[0].num_bits = 31; - fields[0].in_value = NULL; - fields[0].out_value = addr_buf; - - fields[1].num_bits = 4; - fields[1].in_value = busy_buf; - fields[1].out_value = slave_buf; - - jtag_add_dr_scan(jtag_info->tap, 2, fields, TAP_IDLE); - if (jtag_execute_queue() != ERROR_OK) { - LOG_ERROR("%s: setting address failed", __func__); - return ERROR_FAIL; - } - busy = buf_get_u32(busy_buf, 1, 1); - } while (busy); - - return ERROR_OK; -} - -int avr32_jtag_mwa_read_data(struct avr32_jtag *jtag_info, - uint32_t *pdata) -{ - - struct scan_field fields[2]; - uint8_t data_buf[4]; - uint8_t busy_buf[4]; - int busy; - - do { - memset(data_buf, 0, sizeof(data_buf)); - memset(busy_buf, 0, sizeof(busy_buf)); - - fields[0].num_bits = 32; - fields[0].out_value = NULL; - fields[0].in_value = data_buf; - - - fields[1].num_bits = 3; - fields[1].in_value = busy_buf; - fields[1].out_value = NULL; - - jtag_add_dr_scan(jtag_info->tap, 2, fields, TAP_IDLE); - - if (jtag_execute_queue() != ERROR_OK) { - LOG_ERROR("%s: reading data failed", __func__); - return ERROR_FAIL; - } - - busy = buf_get_u32(busy_buf, 0, 1); - } while (busy); - - *pdata = buf_get_u32(data_buf, 0, 32); - - return ERROR_OK; -} - -int avr32_jtag_mwa_write_data(struct avr32_jtag *jtag_info, - uint32_t data) -{ - - struct scan_field fields[2]; - uint8_t data_buf[4]; - uint8_t busy_buf[4]; - uint8_t zero_buf[4]; - int busy; - - do { - memset(data_buf, 0, sizeof(data_buf)); - memset(busy_buf, 0, sizeof(busy_buf)); - memset(zero_buf, 0, sizeof(zero_buf)); - - buf_set_u32(data_buf, 0, 32, data); - fields[0].num_bits = 3; - fields[0].in_value = busy_buf; - fields[0].out_value = zero_buf; - - fields[1].num_bits = 32; - fields[1].out_value = data_buf; - fields[1].in_value = NULL; - - - jtag_add_dr_scan(jtag_info->tap, 2, fields, TAP_IDLE); - - if (jtag_execute_queue() != ERROR_OK) { - LOG_ERROR("%s: reading data failed", __func__); - return ERROR_FAIL; - } - - busy = buf_get_u32(busy_buf, 0, 1); - } while (busy); - - return ERROR_OK; -} - -int avr32_jtag_mwa_read(struct avr32_jtag *jtag_info, int slave, - uint32_t addr, uint32_t *value) -{ - avr32_jtag_set_instr(jtag_info, AVR32_INST_MW_ACCESS); - avr32_jtag_mwa_set_address(jtag_info, slave, addr, MODE_READ); - avr32_jtag_mwa_read_data(jtag_info, value); - - return ERROR_OK; -} - -int avr32_jtag_mwa_write(struct avr32_jtag *jtag_info, int slave, - uint32_t addr, uint32_t value) -{ - avr32_jtag_set_instr(jtag_info, AVR32_INST_MW_ACCESS); - avr32_jtag_mwa_set_address(jtag_info, slave, addr, MODE_WRITE); - avr32_jtag_mwa_write_data(jtag_info, value); - - return ERROR_OK; -} - -int avr32_jtag_exec(struct avr32_jtag *jtag_info, uint32_t inst) -{ - int retval; - uint32_t ds; - - retval = avr32_jtag_nexus_write(jtag_info, AVR32_OCDREG_DINST, inst); - if (retval != ERROR_OK) - return retval; - - do { - retval = avr32_jtag_nexus_read(jtag_info, AVR32_OCDREG_DS, &ds); - if (retval != ERROR_OK) - return retval; - } while ((ds & OCDREG_DS_DBA) && !(ds & OCDREG_DS_INC)); - - return ERROR_OK; -} - -int avr32_ocd_setbits(struct avr32_jtag *jtag, int reg, uint32_t bits) -{ - uint32_t value; - int res; - - res = avr32_jtag_nexus_read(jtag, reg, &value); - if (res) - return res; - - value |= bits; - res = avr32_jtag_nexus_write(jtag, reg, value); - if (res) - return res; - - return ERROR_OK; -} - -int avr32_ocd_clearbits(struct avr32_jtag *jtag, int reg, uint32_t bits) -{ - uint32_t value; - int res; - - res = avr32_jtag_nexus_read(jtag, reg, &value); - if (res) - return res; - - value &= ~bits; - res = avr32_jtag_nexus_write(jtag, reg, value); - if (res) - return res; - - return ERROR_OK; -} - diff --git a/src/target/avr32_jtag.h b/src/target/avr32_jtag.h deleted file mode 100644 index b431ef4c8..000000000 --- a/src/target/avr32_jtag.h +++ /dev/null @@ -1,103 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2010 by Oleksandr Tymoshenko * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 OPENOCD_TARGET_AVR32_JTAG_H -#define OPENOCD_TARGET_AVR32_JTAG_H - -#define AVR32NUMCOREREGS 17 - -/* tap instructions */ -#define AVR32_INST_IDCODE 0x01 -#define AVR32_INST_NEXUS_ACCESS 0x10 -#define AVR32_INST_MW_ACCESS 0x11 -#define AVR32_INST_MB_ACCESS 0x12 - -#define SLAVE_OCD 0x01 -#define SLAVE_HSB_CACHED 0x04 -#define SLAVE_HSB_UNCACHED 0x05 - -/* - * Registers - */ - -#define AVR32_OCDREG_DID 0x00 -#define AVR32_OCDREG_DC 0x02 -#define OCDREG_DC_SS (1 << 8) -#define OCDREG_DC_DBR (1 << 12) -#define OCDREG_DC_DBE (1 << 13) -#define OCDREG_DC_SQA (1 << 22) -#define OCDREG_DC_RES (1 << 30) -#define OCDREG_DC_ABORT (1 << 31) -#define AVR32_OCDREG_DS 0x04 -#define OCDREG_DS_SSS (1 << 0) -#define OCDREG_DS_SWB (1 << 1) -#define OCDREG_DS_HWB (1 << 2) -#define OCDREG_DS_STP (1 << 4) -#define OCDREG_DS_DBS (1 << 5) -#define OCDREG_DS_BP_SHIFT 8 -#define OCDREG_DS_BP_MASK 0xff -#define OCDREG_DS_INC (1 << 24) -#define OCDREG_DS_BOZ (1 << 25) -#define OCDREG_DS_DBA (1 << 26) -#define OCDREG_DS_EXB (1 << 27) -#define OCDREG_DS_NTBF (1 << 28) - -#define AVR32_OCDREG_DINST 0x41 -#define AVR32_OCDREG_DPC 0x42 -#define AVR32_OCDREG_DCCPU 0x44 -#define AVR32_OCDREG_DCEMU 0x45 -#define AVR32_OCDREG_DCSR 0x46 -#define OCDREG_DCSR_CPUD (1 << 0) -#define OCDREG_DCSR_EMUD (1 << 1) - -/* - * Direction bit - */ -#define MODE_WRITE 0x00 -#define MODE_READ 0x01 - -/* - * Some instructions - */ - -#define RETD 0xd703d623 -#define MTDR(dreg, reg) (0xe7b00044 | ((reg) << 16) | dreg) -#define MFDR(reg, dreg) (0xe5b00044 | ((reg) << 16) | dreg) -#define MTSR(sysreg, reg) (0xe3b00002 | ((reg) << 16) | sysreg) -#define MFSR(reg, sysreg) (0xe1b00002 | ((reg) << 16) | sysreg) - -struct avr32_jtag { - struct jtag_tap *tap; - uint32_t dpc; /* Debug PC value */ -}; - -int avr32_jtag_nexus_read(struct avr32_jtag *jtag_info, - uint32_t addr, uint32_t *value); -int avr32_jtag_nexus_write(struct avr32_jtag *jtag_info, - uint32_t addr, uint32_t value); - -int avr32_jtag_mwa_read(struct avr32_jtag *jtag_info, int slave, - uint32_t addr, uint32_t *value); -int avr32_jtag_mwa_write(struct avr32_jtag *jtag_info, int slave, - uint32_t addr, uint32_t value); - -int avr32_ocd_setbits(struct avr32_jtag *jtag, int reg, uint32_t bits); -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 /* OPENOCD_TARGET_AVR32_JTAG_H */ diff --git a/src/target/avr32_mem.c b/src/target/avr32_mem.c deleted file mode 100644 index 71ec0b431..000000000 --- a/src/target/avr32_mem.c +++ /dev/null @@ -1,317 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2010 by Oleksandr Tymoshenko * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 -#include "config.h" -#endif - -#include "target.h" -#include "jtag/jtag.h" -#include "avr32_jtag.h" -#include "avr32_mem.h" - -int avr32_jtag_read_memory32(struct avr32_jtag *jtag_info, - uint32_t addr, int count, uint32_t *buffer) -{ - int i, retval; - uint32_t data; - - for (i = 0; i < count; i++) { - retval = avr32_jtag_mwa_read(jtag_info, SLAVE_HSB_UNCACHED, - addr + i*4, &data); - - if (retval != ERROR_OK) - return retval; - - /* XXX: Assume AVR32 is BE */ - buffer[i] = be_to_h_u32((uint8_t *)&data); - } - - return ERROR_OK; -} - -int avr32_jtag_read_memory16(struct avr32_jtag *jtag_info, - uint32_t addr, int count, uint16_t *buffer) -{ - int i, retval; - uint32_t data; - - i = 0; - - /* any unaligned half-words? */ - if (addr & 3) { - retval = avr32_jtag_mwa_read(jtag_info, SLAVE_HSB_UNCACHED, - addr + i*2, &data); - - if (retval != ERROR_OK) - return retval; - - /* XXX: Assume AVR32 is BE */ - data = be_to_h_u32((uint8_t *)&data); - buffer[i] = (data >> 16) & 0xffff; - i++; - } - - /* read all complete words */ - for (; i < (count & ~1); i += 2) { - retval = avr32_jtag_mwa_read(jtag_info, SLAVE_HSB_UNCACHED, - addr + i*2, &data); - - if (retval != ERROR_OK) - return retval; - - /* XXX: Assume AVR32 is BE */ - data = be_to_h_u32((uint8_t *)&data); - buffer[i] = data & 0xffff; - buffer[i+1] = (data >> 16) & 0xffff; - } - - /* last halfword */ - if (i < count) { - retval = avr32_jtag_mwa_read(jtag_info, SLAVE_HSB_UNCACHED, - addr + i*2, &data); - - if (retval != ERROR_OK) - return retval; - - /* XXX: Assume AVR32 is BE */ - data = be_to_h_u32((uint8_t *)&data); - buffer[i] = data & 0xffff; - } - - return ERROR_OK; -} - -int avr32_jtag_read_memory8(struct avr32_jtag *jtag_info, - uint32_t addr, int count, uint8_t *buffer) -{ - int i, j, retval; - uint8_t data[4]; - i = 0; - - /* Do we have non-aligned bytes? */ - if (addr & 3) { - retval = avr32_jtag_mwa_read(jtag_info, SLAVE_HSB_UNCACHED, - addr + i, (uint32_t *)(void *)data); - - if (retval != ERROR_OK) - return retval; - - for (j = addr & 3; (j < 4) && (i < count); j++, i++) - buffer[i] = data[3-j]; - } - - /* read all complete words */ - for (; i < (count & ~3); i += 4) { - retval = avr32_jtag_mwa_read(jtag_info, SLAVE_HSB_UNCACHED, - addr + i, (uint32_t *)(void *)data); - - if (retval != ERROR_OK) - return retval; - - for (j = 0; j < 4; j++) - buffer[i+j] = data[3-j]; - } - - /* remaining bytes */ - if (i < count) { - retval = avr32_jtag_mwa_read(jtag_info, SLAVE_HSB_UNCACHED, - addr + i, (uint32_t *)(void *)data); - - if (retval != ERROR_OK) - return retval; - - for (j = 0; i + j < count; j++) - buffer[i+j] = data[3-j]; - } - - return ERROR_OK; -} - -int avr32_jtag_write_memory32(struct avr32_jtag *jtag_info, - uint32_t addr, int count, const uint32_t *buffer) -{ - int i, retval; - uint32_t data; - - for (i = 0; i < count; i++) { - /* XXX: Assume AVR32 is BE */ - h_u32_to_be((uint8_t *)&data, buffer[i]); - retval = avr32_jtag_mwa_write(jtag_info, SLAVE_HSB_UNCACHED, - addr + i*4, data); - - if (retval != ERROR_OK) - return retval; - - } - - return ERROR_OK; -} - -int avr32_jtag_write_memory16(struct avr32_jtag *jtag_info, - uint32_t addr, int count, const uint16_t *buffer) -{ - int i, retval; - uint32_t data; - uint32_t data_out; - - i = 0; - - /* - * Do we have any non-aligned half-words? - */ - if (addr & 3) { - /* - * mwa_read will read whole world, no nead to fiddle - * with address. It will be truncated in set_addr - */ - retval = avr32_jtag_mwa_read(jtag_info, SLAVE_HSB_UNCACHED, - addr, &data); - - if (retval != ERROR_OK) - return retval; - - data = be_to_h_u32((uint8_t *)&data); - data = (buffer[i] << 16) | (data & 0xffff); - h_u32_to_be((uint8_t *)&data_out, data); - - retval = avr32_jtag_mwa_write(jtag_info, SLAVE_HSB_UNCACHED, - addr, data_out); - - if (retval != ERROR_OK) - return retval; - - i++; - } - - /* write all complete words */ - for (; i < (count & ~1); i += 2) { - /* XXX: Assume AVR32 is BE */ - data = (buffer[i+1] << 16) | buffer[i]; - h_u32_to_be((uint8_t *)&data_out, data); - - retval = avr32_jtag_mwa_write(jtag_info, SLAVE_HSB_UNCACHED, - addr + i*2, data_out); - - if (retval != ERROR_OK) - return retval; - } - - /* last halfword */ - if (i < count) { - retval = avr32_jtag_mwa_read(jtag_info, SLAVE_HSB_UNCACHED, - addr + i*2, &data); - - if (retval != ERROR_OK) - return retval; - - data = be_to_h_u32((uint8_t *)&data); - data &= ~0xffff; - data |= buffer[i]; - h_u32_to_be((uint8_t *)&data_out, data); - - retval = avr32_jtag_mwa_write(jtag_info, SLAVE_HSB_UNCACHED, - addr + i*2, data_out); - - if (retval != ERROR_OK) - return retval; - } - - return ERROR_OK; -} - -int avr32_jtag_write_memory8(struct avr32_jtag *jtag_info, - uint32_t addr, int count, const uint8_t *buffer) -{ - int i, j, retval; - uint32_t data; - uint32_t data_out; - - i = 0; - - /* - * Do we have any non-aligned bytes? - */ - if (addr & 3) { - /* - * mwa_read will read whole world, no nead to fiddle - * with address. It will be truncated in set_addr - */ - retval = avr32_jtag_mwa_read(jtag_info, SLAVE_HSB_UNCACHED, - addr, &data); - - if (retval != ERROR_OK) - return retval; - - data = be_to_h_u32((uint8_t *)&data); - for (j = addr & 3; (j < 4) && (i < count); j++, i++) { - data &= ~(0xff << j*8); - data |= (buffer[i] << j*8); - } - - h_u32_to_be((uint8_t *)&data_out, data); - retval = avr32_jtag_mwa_write(jtag_info, SLAVE_HSB_UNCACHED, - addr, data_out); - - if (retval != ERROR_OK) - return retval; - } - - - /* write all complete words */ - for (; i < (count & ~3); i += 4) { - data = 0; - - for (j = 0; j < 4; j++) - data |= (buffer[j+i] << j*8); - - h_u32_to_be((uint8_t *)&data_out, data); - - retval = avr32_jtag_mwa_write(jtag_info, SLAVE_HSB_UNCACHED, - addr + i, data_out); - - if (retval != ERROR_OK) - return retval; - } - - /* - * Write trailing bytes - */ - if (i < count) { - retval = avr32_jtag_mwa_read(jtag_info, SLAVE_HSB_UNCACHED, - addr + i, &data); - - if (retval != ERROR_OK) - return retval; - - data = be_to_h_u32((uint8_t *)&data); - for (j = 0; i < count; j++, i++) { - data &= ~(0xff << j*8); - data |= (buffer[j+i] << j*8); - } - - h_u32_to_be((uint8_t *)&data_out, data); - - retval = avr32_jtag_mwa_write(jtag_info, SLAVE_HSB_UNCACHED, - addr+i, data_out); - - if (retval != ERROR_OK) - return retval; - } - - return ERROR_OK; -} diff --git a/src/target/avr32_mem.h b/src/target/avr32_mem.h deleted file mode 100644 index f60a12179..000000000 --- a/src/target/avr32_mem.h +++ /dev/null @@ -1,35 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2010 by Oleksandr Tymoshenko * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 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); -int avr32_jtag_read_memory16(struct avr32_jtag *jtag_info, - uint32_t addr, int count, uint16_t *buffer); -int avr32_jtag_read_memory8(struct avr32_jtag *jtag_info, - uint32_t addr, int count, uint8_t *buffer); - -int avr32_jtag_write_memory32(struct avr32_jtag *jtag_info, - uint32_t addr, int count, const uint32_t *buffer); -int avr32_jtag_write_memory16(struct avr32_jtag *jtag_info, - uint32_t addr, int count, const uint16_t *buffer); -int avr32_jtag_write_memory8(struct avr32_jtag *jtag_info, - uint32_t addr, int count, const uint8_t *buffer); - -#endif /* OPENOCD_TARGET_AVR32_MEM_H */ diff --git a/src/target/avr32_regs.c b/src/target/avr32_regs.c deleted file mode 100644 index 7273822c2..000000000 --- a/src/target/avr32_regs.c +++ /dev/null @@ -1,114 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2010 by Oleksandr Tymoshenko * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 -#include "config.h" -#endif - -#include "target.h" -#include "jtag/jtag.h" -#include "avr32_jtag.h" -#include "avr32_regs.h" - -static int avr32_jtag_read_reg(struct avr32_jtag *jtag_info, int reg, - uint32_t *val) -{ - int retval; - uint32_t dcsr; - - retval = avr32_jtag_exec(jtag_info, MTDR(AVR32_OCDREG_DCCPU, reg)); - if (retval != ERROR_OK) - return retval; - - do { - retval = avr32_jtag_nexus_read(jtag_info, - AVR32_OCDREG_DCSR, &dcsr); - - if (retval != ERROR_OK) - return retval; - } while (!(dcsr & OCDREG_DCSR_CPUD)); - - retval = avr32_jtag_nexus_read(jtag_info, - AVR32_OCDREG_DCCPU, val); - - return retval; -} - -static int avr32_jtag_write_reg(struct avr32_jtag *jtag_info, int reg, - uint32_t val) -{ - int retval; - uint32_t dcsr; - - /* Restore Status reg */ - retval = avr32_jtag_nexus_write(jtag_info, - AVR32_OCDREG_DCEMU, val); - if (retval != ERROR_OK) - return retval; - - retval = avr32_jtag_exec(jtag_info, MFDR(reg, AVR32_OCDREG_DCEMU)); - if (retval != ERROR_OK) - return retval; - do { - retval = avr32_jtag_nexus_read(jtag_info, - AVR32_OCDREG_DCSR, &dcsr); - } while (!(dcsr & OCDREG_DCSR_EMUD) && (retval == ERROR_OK)); - - return retval; -} - - - -int avr32_jtag_read_regs(struct avr32_jtag *jtag_info, uint32_t *regs) -{ - int i, retval; - - /* read core registers */ - for (i = 0; i < AVR32NUMCOREREGS - 1; i++) - avr32_jtag_read_reg(jtag_info, i, regs + i); - - /* read status register */ - retval = avr32_jtag_exec(jtag_info, MFSR(0, 0)); - if (retval != ERROR_OK) - return retval; - - retval = avr32_jtag_read_reg(jtag_info, 0, regs + AVR32_REG_SR); - - return retval; -} - -int avr32_jtag_write_regs(struct avr32_jtag *jtag_info, uint32_t *regs) -{ - int i, retval; - - retval = avr32_jtag_write_reg(jtag_info, 0, regs[AVR32_REG_SR]); - if (retval != ERROR_OK) - return retval; - - /* Restore Status reg */ - retval = avr32_jtag_exec(jtag_info, MTSR(0, 0)); - if (retval != ERROR_OK) - return retval; - - /* - * And now the rest of registers - */ - for (i = 0; i < AVR32NUMCOREREGS - 1; i++) - avr32_jtag_write_reg(jtag_info, i, regs[i]); - - return ERROR_OK; -} diff --git a/src/target/avr32_regs.h b/src/target/avr32_regs.h deleted file mode 100644 index cb492a9fe..000000000 --- a/src/target/avr32_regs.h +++ /dev/null @@ -1,44 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2010 by Oleksandr Tymoshenko * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 OPENOCD_TARGET_AVR32_REGS_H -#define OPENOCD_TARGET_AVR32_REGS_H - -enum avr32_reg_nums { - AVR32_REG_R0 = 0, - AVR32_REG_R1, - AVR32_REG_R2, - AVR32_REG_R3, - AVR32_REG_R4, - AVR32_REG_R5, - AVR32_REG_R6, - AVR32_REG_R7, - AVR32_REG_R8, - AVR32_REG_R9, - AVR32_REG_R10, - AVR32_REG_R11, - AVR32_REG_R12, - AVR32_REG_SP, - AVR32_REG_LR, - AVR32_REG_PC, - AVR32_REG_SR, -}; - -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 /* OPENOCD_TARGET_AVR32_REGS_H */ diff --git a/src/target/avrt.c b/src/target/avrt.c deleted file mode 100644 index 40a12974f..000000000 --- a/src/target/avrt.c +++ /dev/null @@ -1,223 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2009 by Simon Qian * - * SimonQian@SimonQian.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "avrt.h" -#include "target.h" -#include "target_type.h" - -#define AVR_JTAG_INS_LEN 4 - -/* forward declarations */ -static int avr_target_create(struct target *target, Jim_Interp *interp); -static int avr_init_target(struct command_context *cmd_ctx, struct target *target); - -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, - int handle_breakpoints, int debug_execution); -static int avr_step(struct target *target, int current, uint32_t address, - int handle_breakpoints); - -static int avr_assert_reset(struct target *target); -static int avr_deassert_reset(struct target *target); - -/* IR and DR functions */ -static int mcu_write_ir(struct jtag_tap *tap, uint8_t *ir_in, uint8_t *ir_out, int ir_len, int rti); -static int mcu_write_dr(struct jtag_tap *tap, uint8_t *dr_in, uint8_t *dr_out, int dr_len, int rti); -static int mcu_write_ir_u8(struct jtag_tap *tap, uint8_t *ir_in, uint8_t ir_out, int ir_len, int rti); -static int mcu_write_dr_u32(struct jtag_tap *tap, uint32_t *ir_in, uint32_t ir_out, int dr_len, int rti); - -struct target_type avr_target = { - .name = "avr", - - .poll = avr_poll, - .arch_state = avr_arch_state, - - .halt = avr_halt, - .resume = avr_resume, - .step = avr_step, - - .assert_reset = avr_assert_reset, - .deassert_reset = avr_deassert_reset, -/* - .get_gdb_reg_list = avr_get_gdb_reg_list, - - .read_memory = avr_read_memory, - .write_memory = avr_write_memory, - .bulk_write_memory = avr_bulk_write_memory, - .checksum_memory = avr_checksum_memory, - .blank_check_memory = avr_blank_check_memory, - - .run_algorithm = avr_run_algorithm, - - .add_breakpoint = avr_add_breakpoint, - .remove_breakpoint = avr_remove_breakpoint, - .add_watchpoint = avr_add_watchpoint, - .remove_watchpoint = avr_remove_watchpoint, -*/ - .target_create = avr_target_create, - .init_target = avr_init_target, -}; - -static int avr_target_create(struct target *target, Jim_Interp *interp) -{ - struct avr_common *avr = calloc(1, sizeof(struct avr_common)); - - avr->jtag_info.tap = target->tap; - target->arch_info = avr; - - return ERROR_OK; -} - -static int avr_init_target(struct command_context *cmd_ctx, struct target *target) -{ - LOG_DEBUG("%s", __func__); - return ERROR_OK; -} - -static int avr_arch_state(struct target *target) -{ - LOG_DEBUG("%s", __func__); - return ERROR_OK; -} - -static int avr_poll(struct target *target) -{ - if ((target->state == TARGET_RUNNING) || (target->state == TARGET_DEBUG_RUNNING)) - target->state = TARGET_HALTED; - - LOG_DEBUG("%s", __func__); - return ERROR_OK; -} - -static int avr_halt(struct target *target) -{ - LOG_DEBUG("%s", __func__); - return ERROR_OK; -} - -static int avr_resume(struct target *target, int current, uint32_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) -{ - LOG_DEBUG("%s", __func__); - return ERROR_OK; -} - -static int avr_assert_reset(struct target *target) -{ - target->state = TARGET_RESET; - - LOG_DEBUG("%s", __func__); - return ERROR_OK; -} - -static int avr_deassert_reset(struct target *target) -{ - target->state = TARGET_RUNNING; - - LOG_DEBUG("%s", __func__); - return ERROR_OK; -} - -int avr_jtag_senddat(struct jtag_tap *tap, uint32_t* dr_in, uint32_t dr_out, - int len) -{ - return mcu_write_dr_u32(tap, dr_in, dr_out, len, 1); -} - -int avr_jtag_sendinstr(struct jtag_tap *tap, uint8_t *ir_in, uint8_t ir_out) -{ - return mcu_write_ir_u8(tap, ir_in, ir_out, AVR_JTAG_INS_LEN, 1); -} - -/* IR and DR functions */ -static int mcu_write_ir(struct jtag_tap *tap, uint8_t *ir_in, uint8_t *ir_out, - int ir_len, int rti) -{ - if (NULL == tap) { - LOG_ERROR("invalid tap"); - return ERROR_FAIL; - } - if (ir_len != tap->ir_length) { - LOG_ERROR("invalid ir_len"); - return ERROR_FAIL; - } - - { - jtag_add_plain_ir_scan(tap->ir_length, ir_out, ir_in, TAP_IDLE); - } - - return ERROR_OK; -} - -static int mcu_write_dr(struct jtag_tap *tap, uint8_t *dr_in, uint8_t *dr_out, - int dr_len, int rti) -{ - if (NULL == tap) { - LOG_ERROR("invalid tap"); - return ERROR_FAIL; - } - - { - jtag_add_plain_dr_scan(dr_len, dr_out, dr_in, TAP_IDLE); - } - - return ERROR_OK; -} - -static int mcu_write_ir_u8(struct jtag_tap *tap, uint8_t *ir_in, - uint8_t ir_out, int ir_len, int rti) -{ - if (ir_len > 8) { - LOG_ERROR("ir_len overflow, maxium is 8"); - return ERROR_FAIL; - } - - mcu_write_ir(tap, ir_in, &ir_out, ir_len, rti); - - return ERROR_OK; -} - -static int mcu_write_dr_u32(struct jtag_tap *tap, uint32_t *dr_in, - uint32_t dr_out, int dr_len, int rti) -{ - if (dr_len > 32) { - LOG_ERROR("dr_len overflow, maxium is 32"); - return ERROR_FAIL; - } - - mcu_write_dr(tap, (uint8_t *)dr_in, (uint8_t *)&dr_out, dr_len, rti); - - return ERROR_OK; -} - -int mcu_execute_queue(void) -{ - return jtag_execute_queue(); -} diff --git a/src/target/avrt.h b/src/target/avrt.h deleted file mode 100644 index 3610eb5e3..000000000 --- a/src/target/avrt.h +++ /dev/null @@ -1,37 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2009 by Simon Qian * - * SimonQian@SimonQian.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifndef OPENOCD_TARGET_AVRT_H -#define OPENOCD_TARGET_AVRT_H - -#include - -struct mcu_jtag { - struct jtag_tap *tap; -}; - -struct avr_common { - struct mcu_jtag jtag_info; -}; - -int mcu_execute_queue(void); -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 /* OPENOCD_TARGET_AVRT_H */ diff --git a/src/target/breakpoints.c b/src/target/breakpoints.c deleted file mode 100644 index 959171460..000000000 --- a/src/target/breakpoints.c +++ /dev/null @@ -1,519 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * Copyright (C) ST-Ericsson SA 2011 * - * michel.jaouen@stericsson.com : smp minimum support * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "target.h" -#include -#include "breakpoints.h" - -static const char * const breakpoint_type_strings[] = { - "hardware", - "software" -}; - -static const char * const watchpoint_rw_strings[] = { - "read", - "write", - "access" -}; - -/* monotonic counter/id-number for breakpoints and watch points */ -static int bpwp_unique_id; - -int breakpoint_add_internal(struct target *target, - uint32_t address, - uint32_t length, - enum breakpoint_type type) -{ - struct breakpoint *breakpoint = target->breakpoints; - struct breakpoint **breakpoint_p = &target->breakpoints; - const char *reason; - int retval; - int n; - - n = 0; - while (breakpoint) { - n++; - if (breakpoint->address == address) { - /* FIXME don't assume "same address" means "same - * breakpoint" ... check all the parameters before - * succeeding. - */ - LOG_DEBUG("Duplicate Breakpoint address: 0x%08" PRIx32 " (BP %" PRIu32 ")", - address, breakpoint->unique_id); - return ERROR_OK; - } - breakpoint_p = &breakpoint->next; - breakpoint = breakpoint->next; - } - - (*breakpoint_p) = malloc(sizeof(struct breakpoint)); - (*breakpoint_p)->address = address; - (*breakpoint_p)->asid = 0; - (*breakpoint_p)->length = length; - (*breakpoint_p)->type = type; - (*breakpoint_p)->set = 0; - (*breakpoint_p)->orig_instr = malloc(length); - (*breakpoint_p)->next = NULL; - (*breakpoint_p)->unique_id = bpwp_unique_id++; - - retval = target_add_breakpoint(target, *breakpoint_p); - switch (retval) { - case ERROR_OK: - break; - case ERROR_TARGET_RESOURCE_NOT_AVAILABLE: - reason = "resource not available"; - goto fail; - case ERROR_TARGET_NOT_HALTED: - reason = "target running"; - goto fail; - default: - reason = "unknown reason"; -fail: - LOG_ERROR("can't add breakpoint: %s", reason); - free((*breakpoint_p)->orig_instr); - free(*breakpoint_p); - *breakpoint_p = NULL; - return retval; - } - - LOG_DEBUG("added %s breakpoint at 0x%8.8" PRIx32 " of length 0x%8.8x, (BPID: %" PRIu32 ")", - breakpoint_type_strings[(*breakpoint_p)->type], - (*breakpoint_p)->address, (*breakpoint_p)->length, - (*breakpoint_p)->unique_id); - - return ERROR_OK; -} - -int context_breakpoint_add_internal(struct target *target, - uint32_t asid, - uint32_t length, - enum breakpoint_type type) -{ - struct breakpoint *breakpoint = target->breakpoints; - struct breakpoint **breakpoint_p = &target->breakpoints; - int retval; - int n; - - n = 0; - while (breakpoint) { - n++; - if (breakpoint->asid == asid) { - /* FIXME don't assume "same address" means "same - * breakpoint" ... check all the parameters before - * succeeding. - */ - LOG_DEBUG("Duplicate Breakpoint asid: 0x%08" PRIx32 " (BP %" PRIu32 ")", - asid, breakpoint->unique_id); - return -1; - } - breakpoint_p = &breakpoint->next; - breakpoint = breakpoint->next; - } - - (*breakpoint_p) = malloc(sizeof(struct breakpoint)); - (*breakpoint_p)->address = 0; - (*breakpoint_p)->asid = asid; - (*breakpoint_p)->length = length; - (*breakpoint_p)->type = type; - (*breakpoint_p)->set = 0; - (*breakpoint_p)->orig_instr = malloc(length); - (*breakpoint_p)->next = NULL; - (*breakpoint_p)->unique_id = bpwp_unique_id++; - retval = target_add_context_breakpoint(target, *breakpoint_p); - if (retval != ERROR_OK) { - LOG_ERROR("could not add breakpoint"); - free((*breakpoint_p)->orig_instr); - free(*breakpoint_p); - *breakpoint_p = NULL; - return retval; - } - - LOG_DEBUG("added %s Context breakpoint at 0x%8.8" PRIx32 " of length 0x%8.8x, (BPID: %" PRIu32 ")", - breakpoint_type_strings[(*breakpoint_p)->type], - (*breakpoint_p)->asid, (*breakpoint_p)->length, - (*breakpoint_p)->unique_id); - - return ERROR_OK; -} - -int hybrid_breakpoint_add_internal(struct target *target, - uint32_t address, - uint32_t asid, - uint32_t length, - enum breakpoint_type type) -{ - struct breakpoint *breakpoint = target->breakpoints; - struct breakpoint **breakpoint_p = &target->breakpoints; - int retval; - int n; - n = 0; - while (breakpoint) { - n++; - if ((breakpoint->asid == asid) && (breakpoint->address == address)) { - /* FIXME don't assume "same address" means "same - * breakpoint" ... check all the parameters before - * succeeding. - */ - LOG_DEBUG("Duplicate Hybrid Breakpoint asid: 0x%08" PRIx32 " (BP %" PRIu32 ")", - asid, breakpoint->unique_id); - return -1; - } else if ((breakpoint->address == address) && (breakpoint->asid == 0)) { - LOG_DEBUG("Duplicate Breakpoint IVA: 0x%08" PRIx32 " (BP %" PRIu32 ")", - address, breakpoint->unique_id); - return -1; - - } - breakpoint_p = &breakpoint->next; - breakpoint = breakpoint->next; - } - (*breakpoint_p) = malloc(sizeof(struct breakpoint)); - (*breakpoint_p)->address = address; - (*breakpoint_p)->asid = asid; - (*breakpoint_p)->length = length; - (*breakpoint_p)->type = type; - (*breakpoint_p)->set = 0; - (*breakpoint_p)->orig_instr = malloc(length); - (*breakpoint_p)->next = NULL; - (*breakpoint_p)->unique_id = bpwp_unique_id++; - - - retval = target_add_hybrid_breakpoint(target, *breakpoint_p); - if (retval != ERROR_OK) { - LOG_ERROR("could not add breakpoint"); - free((*breakpoint_p)->orig_instr); - free(*breakpoint_p); - *breakpoint_p = NULL; - return retval; - } - LOG_DEBUG( - "added %s Hybrid breakpoint at address 0x%8.8" PRIx32 " of length 0x%8.8x, (BPID: %" PRIu32 ")", - breakpoint_type_strings[(*breakpoint_p)->type], - (*breakpoint_p)->address, - (*breakpoint_p)->length, - (*breakpoint_p)->unique_id); - - return ERROR_OK; -} - -int breakpoint_add(struct target *target, - uint32_t address, - uint32_t length, - enum breakpoint_type type) -{ - int retval = ERROR_OK; - if (target->smp) { - struct target_list *head; - struct target *curr; - head = target->head; - if (type == BKPT_SOFT) - return breakpoint_add_internal(head->target, address, length, type); - - while (head != (struct target_list *)NULL) { - curr = head->target; - retval = breakpoint_add_internal(curr, address, length, type); - if (retval != ERROR_OK) - return retval; - head = head->next; - } - return retval; - } else - return breakpoint_add_internal(target, address, length, type); -} -int context_breakpoint_add(struct target *target, - uint32_t asid, - uint32_t length, - enum breakpoint_type type) -{ - int retval = ERROR_OK; - if (target->smp) { - struct target_list *head; - struct target *curr; - head = target->head; - while (head != (struct target_list *)NULL) { - curr = head->target; - retval = context_breakpoint_add_internal(curr, asid, length, type); - if (retval != ERROR_OK) - return retval; - head = head->next; - } - return retval; - } else - return context_breakpoint_add_internal(target, asid, length, type); -} -int hybrid_breakpoint_add(struct target *target, - uint32_t address, - uint32_t asid, - uint32_t length, - enum breakpoint_type type) -{ - int retval = ERROR_OK; - if (target->smp) { - struct target_list *head; - struct target *curr; - head = target->head; - while (head != (struct target_list *)NULL) { - curr = head->target; - retval = hybrid_breakpoint_add_internal(curr, address, asid, length, type); - if (retval != ERROR_OK) - return retval; - head = head->next; - } - return retval; - } else - return hybrid_breakpoint_add_internal(target, address, asid, length, type); -} - -/* free up a breakpoint */ -static void breakpoint_free(struct target *target, struct breakpoint *breakpoint_to_remove) -{ - struct breakpoint *breakpoint = target->breakpoints; - struct breakpoint **breakpoint_p = &target->breakpoints; - int retval; - - while (breakpoint) { - if (breakpoint == breakpoint_to_remove) - break; - breakpoint_p = &breakpoint->next; - breakpoint = breakpoint->next; - } - - if (breakpoint == NULL) - return; - - retval = target_remove_breakpoint(target, breakpoint); - - LOG_DEBUG("free BPID: %" PRIu32 " --> %d", breakpoint->unique_id, retval); - (*breakpoint_p) = breakpoint->next; - free(breakpoint->orig_instr); - free(breakpoint); -} - -int breakpoint_remove_internal(struct target *target, uint32_t address) -{ - struct breakpoint *breakpoint = target->breakpoints; - - while (breakpoint) { - if ((breakpoint->address == address) && (breakpoint->asid == 0)) - break; - else if ((breakpoint->address == 0) && (breakpoint->asid == address)) - break; - else if ((breakpoint->address == address) && (breakpoint->asid != 0)) - break; - breakpoint = breakpoint->next; - } - - if (breakpoint) { - breakpoint_free(target, breakpoint); - return 1; - } else { - if (!target->smp) - LOG_ERROR("no breakpoint at address 0x%8.8" PRIx32 " found", address); - return 0; - } -} -void breakpoint_remove(struct target *target, uint32_t address) -{ - int found = 0; - if (target->smp) { - struct target_list *head; - struct target *curr; - head = target->head; - while (head != (struct target_list *)NULL) { - curr = head->target; - found += breakpoint_remove_internal(curr, address); - head = head->next; - } - if (found == 0) - LOG_ERROR("no breakpoint at address 0x%8.8" PRIx32 " found", address); - } else - breakpoint_remove_internal(target, address); -} - -void breakpoint_clear_target_internal(struct target *target) -{ - LOG_DEBUG("Delete all breakpoints for target: %s", - target_name(target)); - while (target->breakpoints != NULL) - breakpoint_free(target, target->breakpoints); -} - -void breakpoint_clear_target(struct target *target) -{ - if (target->smp) { - struct target_list *head; - struct target *curr; - head = target->head; - while (head != (struct target_list *)NULL) { - curr = head->target; - breakpoint_clear_target_internal(curr); - head = head->next; - } - } else - breakpoint_clear_target_internal(target); - -} - -struct breakpoint *breakpoint_find(struct target *target, uint32_t address) -{ - struct breakpoint *breakpoint = target->breakpoints; - - while (breakpoint) { - if (breakpoint->address == address) - return breakpoint; - breakpoint = breakpoint->next; - } - - return NULL; -} - -int watchpoint_add(struct target *target, uint32_t address, uint32_t length, - enum watchpoint_rw rw, uint32_t value, uint32_t mask) -{ - struct watchpoint *watchpoint = target->watchpoints; - struct watchpoint **watchpoint_p = &target->watchpoints; - int retval; - const char *reason; - - while (watchpoint) { - if (watchpoint->address == address) { - if (watchpoint->length != length - || watchpoint->value != value - || watchpoint->mask != mask - || watchpoint->rw != rw) { - LOG_ERROR("address 0x%8.8" PRIx32 - "already has watchpoint %d", - address, watchpoint->unique_id); - return ERROR_FAIL; - } - - /* ignore duplicate watchpoint */ - return ERROR_OK; - } - watchpoint_p = &watchpoint->next; - watchpoint = watchpoint->next; - } - - (*watchpoint_p) = calloc(1, sizeof(struct watchpoint)); - (*watchpoint_p)->address = address; - (*watchpoint_p)->length = length; - (*watchpoint_p)->value = value; - (*watchpoint_p)->mask = mask; - (*watchpoint_p)->rw = rw; - (*watchpoint_p)->unique_id = bpwp_unique_id++; - - retval = target_add_watchpoint(target, *watchpoint_p); - switch (retval) { - case ERROR_OK: - break; - case ERROR_TARGET_RESOURCE_NOT_AVAILABLE: - reason = "resource not available"; - goto bye; - case ERROR_TARGET_NOT_HALTED: - reason = "target running"; - goto bye; - default: - reason = "unrecognized error"; -bye: - LOG_ERROR("can't add %s watchpoint at 0x%8.8" PRIx32 ", %s", - watchpoint_rw_strings[(*watchpoint_p)->rw], - address, reason); - free(*watchpoint_p); - *watchpoint_p = NULL; - return retval; - } - - LOG_DEBUG("added %s watchpoint at 0x%8.8" PRIx32 - " of length 0x%8.8" PRIx32 " (WPID: %d)", - watchpoint_rw_strings[(*watchpoint_p)->rw], - (*watchpoint_p)->address, - (*watchpoint_p)->length, - (*watchpoint_p)->unique_id); - - return ERROR_OK; -} - -static void watchpoint_free(struct target *target, struct watchpoint *watchpoint_to_remove) -{ - struct watchpoint *watchpoint = target->watchpoints; - struct watchpoint **watchpoint_p = &target->watchpoints; - int retval; - - while (watchpoint) { - if (watchpoint == watchpoint_to_remove) - break; - watchpoint_p = &watchpoint->next; - watchpoint = watchpoint->next; - } - - if (watchpoint == NULL) - return; - retval = target_remove_watchpoint(target, watchpoint); - LOG_DEBUG("free WPID: %d --> %d", watchpoint->unique_id, retval); - (*watchpoint_p) = watchpoint->next; - free(watchpoint); -} - -void watchpoint_remove(struct target *target, uint32_t address) -{ - struct watchpoint *watchpoint = target->watchpoints; - - while (watchpoint) { - if (watchpoint->address == address) - break; - watchpoint = watchpoint->next; - } - - if (watchpoint) - watchpoint_free(target, watchpoint); - else - LOG_ERROR("no watchpoint at address 0x%8.8" PRIx32 " found", address); -} - -void watchpoint_clear_target(struct target *target) -{ - LOG_DEBUG("Delete all watchpoints for target: %s", - target_name(target)); - while (target->watchpoints != NULL) - watchpoint_free(target, target->watchpoints); -} - -int watchpoint_hit(struct target *target, enum watchpoint_rw *rw, uint32_t *address) -{ - int retval; - struct watchpoint *hit_watchpoint; - - retval = target_hit_watchpoint(target, &hit_watchpoint); - if (retval != ERROR_OK) - return ERROR_FAIL; - - *rw = hit_watchpoint->rw; - *address = hit_watchpoint->address; - - LOG_DEBUG("Found hit watchpoint at 0x%8.8" PRIx32 " (WPID: %d)", - hit_watchpoint->address, - hit_watchpoint->unique_id); - - return ERROR_OK; -} diff --git a/src/target/breakpoints.h b/src/target/breakpoints.h deleted file mode 100644 index 6e260abd8..000000000 --- a/src/target/breakpoints.h +++ /dev/null @@ -1,76 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifndef OPENOCD_TARGET_BREAKPOINTS_H -#define OPENOCD_TARGET_BREAKPOINTS_H - -struct target; - -enum breakpoint_type { - BKPT_HARD, - BKPT_SOFT, -}; - -enum watchpoint_rw { - WPT_READ = 0, WPT_WRITE = 1, WPT_ACCESS = 2 -}; - -struct breakpoint { - uint32_t address; - uint32_t asid; - int length; - enum breakpoint_type type; - int set; - uint8_t *orig_instr; - struct breakpoint *next; - uint32_t unique_id; - int linked_BRP; -}; - -struct watchpoint { - uint32_t address; - uint32_t length; - uint32_t mask; - uint32_t value; - enum watchpoint_rw rw; - int set; - struct watchpoint *next; - int unique_id; -}; - -void breakpoint_clear_target(struct target *target); -int breakpoint_add(struct target *target, - uint32_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); - -struct breakpoint *breakpoint_find(struct target *target, uint32_t address); - -void watchpoint_clear_target(struct target *target); -int watchpoint_add(struct target *target, - uint32_t address, uint32_t length, - enum watchpoint_rw rw, uint32_t value, uint32_t mask); -void watchpoint_remove(struct target *target, uint32_t address); - -/* report type and address of just hit watchpoint */ -int watchpoint_hit(struct target *target, enum watchpoint_rw *rw, uint32_t *address); - -#endif /* OPENOCD_TARGET_BREAKPOINTS_H */ diff --git a/src/target/cortex_a.c b/src/target/cortex_a.c deleted file mode 100644 index d1590f65f..000000000 --- a/src/target/cortex_a.c +++ /dev/null @@ -1,3591 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * Copyright (C) 2006 by Magnus Lundin * - * lundin@mlu.mine.nu * - * * - * Copyright (C) 2008 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * Copyright (C) 2009 by Dirk Behme * - * dirk.behme@gmail.com - copy from cortex_m3 * - * * - * Copyright (C) 2010 Øyvind Harboe * - * oyvind.harboe@zylin.com * - * * - * Copyright (C) ST-Ericsson SA 2011 * - * michel.jaouen@stericsson.com : smp minimum support * - * * - * Copyright (C) Broadcom 2012 * - * ehunter@broadcom.com : Cortex-R4 support * - * * - * Copyright (C) 2013 Kamal Dasu * - * kdasu.kdev@gmail.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - * * - * Cortex-A8(tm) TRM, ARM DDI 0344H * - * Cortex-A9(tm) TRM, ARM DDI 0407F * - * Cortex-A4(tm) TRM, ARM DDI 0363E * - * Cortex-A15(tm)TRM, ARM DDI 0438C * - * * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "breakpoints.h" -#include "cortex_a.h" -#include "register.h" -#include "target_request.h" -#include "target_type.h" -#include "arm_opcodes.h" -#include - -static int cortex_a_poll(struct target *target); -static int cortex_a_debug_entry(struct target *target); -static int cortex_a_restore_context(struct target *target, bool bpwp); -static int cortex_a_set_breakpoint(struct target *target, - struct breakpoint *breakpoint, uint8_t matchmode); -static int cortex_a_set_context_breakpoint(struct target *target, - struct breakpoint *breakpoint, uint8_t matchmode); -static int cortex_a_set_hybrid_breakpoint(struct target *target, - struct breakpoint *breakpoint); -static int cortex_a_unset_breakpoint(struct target *target, - struct breakpoint *breakpoint); -static int cortex_a_dap_read_coreregister_u32(struct target *target, - uint32_t *value, int regnum); -static int cortex_a_dap_write_coreregister_u32(struct target *target, - uint32_t value, int regnum); -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_cpu_memory(struct target *target, - uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer); - - -/* restore cp15_control_reg at resume */ -static int cortex_a_restore_cp15_control_reg(struct target *target) -{ - int retval = ERROR_OK; - struct cortex_a_common *cortex_a = target_to_cortex_a(target); - struct armv7a_common *armv7a = target_to_armv7a(target); - - if (cortex_a->cp15_control_reg != cortex_a->cp15_control_reg_curr) { - cortex_a->cp15_control_reg_curr = cortex_a->cp15_control_reg; - /* LOG_INFO("cp15_control_reg: %8.8" PRIx32, cortex_a->cp15_control_reg); */ - retval = armv7a->arm.mcr(target, 15, - 0, 0, /* op1, op2 */ - 1, 0, /* CRn, CRm */ - cortex_a->cp15_control_reg); - } - return retval; -} - -/* - * Set up ARM core for memory access. - * If !phys_access, switch to SVC mode and make sure MMU is on - * If phys_access, switch off mmu - */ -static int cortex_a_prep_memaccess(struct target *target, int phys_access) -{ - struct armv7a_common *armv7a = target_to_armv7a(target); - struct cortex_a_common *cortex_a = target_to_cortex_a(target); - int mmu_enabled = 0; - - if (phys_access == 0) { - dpm_modeswitch(&armv7a->dpm, ARM_MODE_SVC); - cortex_a_mmu(target, &mmu_enabled); - if (mmu_enabled) - cortex_a_mmu_modify(target, 1); - if (cortex_a->dacrfixup_mode == CORTEX_A_DACRFIXUP_ON) { - /* overwrite DACR to all-manager */ - armv7a->arm.mcr(target, 15, - 0, 0, 3, 0, - 0xFFFFFFFF); - } - } else { - cortex_a_mmu(target, &mmu_enabled); - if (mmu_enabled) - cortex_a_mmu_modify(target, 0); - } - return ERROR_OK; -} - -/* - * Restore ARM core after memory access. - * If !phys_access, switch to previous mode - * If phys_access, restore MMU setting - */ -static int cortex_a_post_memaccess(struct target *target, int phys_access) -{ - struct armv7a_common *armv7a = target_to_armv7a(target); - struct cortex_a_common *cortex_a = target_to_cortex_a(target); - - if (phys_access == 0) { - if (cortex_a->dacrfixup_mode == CORTEX_A_DACRFIXUP_ON) { - /* restore */ - armv7a->arm.mcr(target, 15, - 0, 0, 3, 0, - cortex_a->cp15_dacr_reg); - } - dpm_modeswitch(&armv7a->dpm, ARM_MODE_ANY); - } else { - int mmu_enabled = 0; - cortex_a_mmu(target, &mmu_enabled); - if (mmu_enabled) - cortex_a_mmu_modify(target, 1); - } - return ERROR_OK; -} - - -/* modify cp15_control_reg in order to enable or disable mmu for : - * - virt2phys address conversion - * - read or write memory in phys or virt address */ -static int cortex_a_mmu_modify(struct target *target, int enable) -{ - struct cortex_a_common *cortex_a = target_to_cortex_a(target); - struct armv7a_common *armv7a = target_to_armv7a(target); - int retval = ERROR_OK; - int need_write = 0; - - if (enable) { - /* if mmu enabled at target stop and mmu not enable */ - if (!(cortex_a->cp15_control_reg & 0x1U)) { - LOG_ERROR("trying to enable mmu on target stopped with mmu disable"); - return ERROR_FAIL; - } - if ((cortex_a->cp15_control_reg_curr & 0x1U) == 0) { - cortex_a->cp15_control_reg_curr |= 0x1U; - need_write = 1; - } - } else { - if ((cortex_a->cp15_control_reg_curr & 0x1U) == 0x1U) { - cortex_a->cp15_control_reg_curr &= ~0x1U; - need_write = 1; - } - } - - if (need_write) { - LOG_DEBUG("%s, writing cp15 ctrl: %" PRIx32, - enable ? "enable mmu" : "disable mmu", - cortex_a->cp15_control_reg_curr); - - retval = armv7a->arm.mcr(target, 15, - 0, 0, /* op1, op2 */ - 1, 0, /* CRn, CRm */ - cortex_a->cp15_control_reg_curr); - } - 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 - */ -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); - - if (retval != ERROR_OK) - return retval; - - /* Disable cacheline fills and force cache write-through in debug state */ - retval = mem_ap_write_atomic_u32(armv7a->debug_ap, - armv7a->debug_base + CPUDBG_DSCCR, 0); - if (retval != ERROR_OK) - return retval; - - /* Disable TLB lookup and refill/eviction in debug state */ - retval = mem_ap_write_atomic_u32(armv7a->debug_ap, - armv7a->debug_base + CPUDBG_DSMCR, 0); - if (retval != ERROR_OK) - return retval; - - /* Enabling of instruction execution in debug mode is done in debug_entry code */ - - /* Resync breakpoint registers */ - - /* Since this is likely called from init or reset, update target state information*/ - return cortex_a_poll(target); -} - -static int cortex_a_wait_instrcmpl(struct target *target, uint32_t *dscr, bool force) -{ - /* Waits until InstrCmpl_l becomes 1, indicating instruction is done. - * 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); - int64_t then = timeval_ms(); - while ((*dscr & DSCR_INSTR_COMP) == 0 || force) { - force = false; - int retval = mem_ap_read_atomic_u32(armv7a->debug_ap, - armv7a->debug_base + CPUDBG_DSCR, dscr); - if (retval != ERROR_OK) { - LOG_ERROR("Could not read DSCR register"); - return retval; - } - if (timeval_ms() > then + 1000) { - LOG_ERROR("Timeout waiting for InstrCompl=1"); - return ERROR_FAIL; - } - } - return ERROR_OK; -} - -/* To reduce needless round-trips, pass in a pointer to the current - * DSCR value. Initialize it to zero if you just need to know the - * value on return from this function; or DSCR_INSTR_COMP if you - * happen to know that no instruction is pending. - */ -static int cortex_a_exec_opcode(struct target *target, - uint32_t opcode, uint32_t *dscr_p) -{ - uint32_t dscr; - int retval; - struct armv7a_common *armv7a = target_to_armv7a(target); - - dscr = dscr_p ? *dscr_p : 0; - - LOG_DEBUG("exec opcode 0x%08" PRIx32, opcode); - - /* Wait for InstrCompl bit to be set */ - retval = cortex_a_wait_instrcmpl(target, dscr_p, false); - if (retval != ERROR_OK) - return retval; - - retval = mem_ap_write_u32(armv7a->debug_ap, - armv7a->debug_base + CPUDBG_ITR, opcode); - if (retval != ERROR_OK) - return retval; - - int64_t then = timeval_ms(); - do { - retval = mem_ap_read_atomic_u32(armv7a->debug_ap, - armv7a->debug_base + CPUDBG_DSCR, &dscr); - if (retval != ERROR_OK) { - LOG_ERROR("Could not read DSCR register"); - return retval; - } - if (timeval_ms() > then + 1000) { - LOG_ERROR("Timeout waiting for cortex_a_exec_opcode"); - return ERROR_FAIL; - } - } while ((dscr & DSCR_INSTR_COMP) == 0); /* Wait for InstrCompl bit to be set */ - - if (dscr_p) - *dscr_p = dscr; - - return retval; -} - -/************************************************************************** -Read core register with very few exec_opcode, fast but needs work_area. -This can cause problems with MMU active. -**************************************************************************/ -static int cortex_a_read_regs_through_mem(struct target *target, uint32_t address, - uint32_t *regfile) -{ - int retval = ERROR_OK; - struct armv7a_common *armv7a = target_to_armv7a(target); - - retval = cortex_a_dap_read_coreregister_u32(target, regfile, 0); - if (retval != ERROR_OK) - return retval; - retval = cortex_a_dap_write_coreregister_u32(target, address, 0); - if (retval != ERROR_OK) - return retval; - retval = cortex_a_exec_opcode(target, ARMV4_5_STMIA(0, 0xFFFE, 0, 0), NULL); - if (retval != ERROR_OK) - return retval; - - retval = mem_ap_read_buf(armv7a->memory_ap, - (uint8_t *)(®file[1]), 4, 15, address); - - return retval; -} - -static int cortex_a_dap_read_coreregister_u32(struct target *target, - uint32_t *value, int regnum) -{ - int retval = ERROR_OK; - uint8_t reg = regnum&0xFF; - uint32_t dscr = 0; - struct armv7a_common *armv7a = target_to_armv7a(target); - - if (reg > 17) - return retval; - - if (reg < 15) { - /* Rn to DCCTX, "MCR p14, 0, Rn, c0, c5, 0" 0xEE00nE15 */ - retval = cortex_a_exec_opcode(target, - ARMV4_5_MCR(14, 0, reg, 0, 5, 0), - &dscr); - if (retval != ERROR_OK) - return retval; - } else if (reg == 15) { - /* "MOV r0, r15"; then move r0 to DCCTX */ - retval = cortex_a_exec_opcode(target, 0xE1A0000F, &dscr); - if (retval != ERROR_OK) - return retval; - retval = cortex_a_exec_opcode(target, - ARMV4_5_MCR(14, 0, 0, 0, 5, 0), - &dscr); - if (retval != ERROR_OK) - return retval; - } else { - /* "MRS r0, CPSR" or "MRS r0, SPSR" - * then move r0 to DCCTX - */ - retval = cortex_a_exec_opcode(target, ARMV4_5_MRS(0, reg & 1), &dscr); - if (retval != ERROR_OK) - return retval; - retval = cortex_a_exec_opcode(target, - ARMV4_5_MCR(14, 0, 0, 0, 5, 0), - &dscr); - if (retval != ERROR_OK) - return retval; - } - - /* Wait for DTRRXfull then read DTRRTX */ - 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); - if (retval != ERROR_OK) - return retval; - if (timeval_ms() > then + 1000) { - LOG_ERROR("Timeout waiting for cortex_a_exec_opcode"); - return ERROR_FAIL; - } - } - - retval = mem_ap_read_atomic_u32(armv7a->debug_ap, - armv7a->debug_base + CPUDBG_DTRTX, value); - LOG_DEBUG("read DCC 0x%08" PRIx32, *value); - - return retval; -} - -static int cortex_a_dap_write_coreregister_u32(struct target *target, - uint32_t value, int regnum) -{ - int retval = ERROR_OK; - uint8_t Rd = regnum&0xFF; - uint32_t dscr; - struct armv7a_common *armv7a = target_to_armv7a(target); - - LOG_DEBUG("register %i, value 0x%08" PRIx32, regnum, value); - - /* Check that DCCRX is not full */ - retval = mem_ap_read_atomic_u32(armv7a->debug_ap, - armv7a->debug_base + CPUDBG_DSCR, &dscr); - if (retval != ERROR_OK) - return retval; - if (dscr & DSCR_DTR_RX_FULL) { - LOG_ERROR("DSCR_DTR_RX_FULL, dscr 0x%08" PRIx32, dscr); - /* Clear DCCRX with MRC(p14, 0, Rd, c0, c5, 0), opcode 0xEE100E15 */ - retval = cortex_a_exec_opcode(target, ARMV4_5_MRC(14, 0, 0, 0, 5, 0), - &dscr); - if (retval != ERROR_OK) - return retval; - } - - if (Rd > 17) - return retval; - - /* Write DTRRX ... sets DSCR.DTRRXfull but exec_opcode() won't care */ - LOG_DEBUG("write DCC 0x%08" PRIx32, value); - retval = mem_ap_write_u32(armv7a->debug_ap, - armv7a->debug_base + CPUDBG_DTRRX, value); - if (retval != ERROR_OK) - return retval; - - if (Rd < 15) { - /* DCCRX to Rn, "MRC p14, 0, Rn, c0, c5, 0", 0xEE10nE15 */ - retval = cortex_a_exec_opcode(target, ARMV4_5_MRC(14, 0, Rd, 0, 5, 0), - &dscr); - - if (retval != ERROR_OK) - return retval; - } else if (Rd == 15) { - /* DCCRX to R0, "MRC p14, 0, R0, c0, c5, 0", 0xEE100E15 - * then "mov r15, r0" - */ - retval = cortex_a_exec_opcode(target, ARMV4_5_MRC(14, 0, 0, 0, 5, 0), - &dscr); - if (retval != ERROR_OK) - return retval; - retval = cortex_a_exec_opcode(target, 0xE1A0F000, &dscr); - if (retval != ERROR_OK) - return retval; - } else { - /* DCCRX to R0, "MRC p14, 0, R0, c0, c5, 0", 0xEE100E15 - * then "MSR CPSR_cxsf, r0" or "MSR SPSR_cxsf, r0" (all fields) - */ - retval = cortex_a_exec_opcode(target, ARMV4_5_MRC(14, 0, 0, 0, 5, 0), - &dscr); - if (retval != ERROR_OK) - return retval; - retval = cortex_a_exec_opcode(target, ARMV4_5_MSR_GP(0, 0xF, Rd & 1), - &dscr); - if (retval != ERROR_OK) - return retval; - - /* "Prefetch flush" after modifying execution status in CPSR */ - if (Rd == 16) { - retval = cortex_a_exec_opcode(target, - ARMV4_5_MCR(15, 0, 0, 7, 5, 4), - &dscr); - if (retval != ERROR_OK) - return retval; - } - } - - return retval; -} - -/* Write to memory mapped registers directly with no cache or mmu handling */ -static int cortex_a_dap_write_memap_register_u32(struct target *target, - uint32_t address, - uint32_t value) -{ - int retval; - struct armv7a_common *armv7a = target_to_armv7a(target); - - retval = mem_ap_write_atomic_u32(armv7a->debug_ap, address, value); - - return retval; -} - -/* - * Cortex-A implementation of Debug Programmer's Model - * - * NOTE the invariant: these routines return with DSCR_INSTR_COMP set, - * so there's no need to poll for it before executing an instruction. - * - * NOTE that in several of these cases the "stall" mode might be useful. - * It'd let us queue a few operations together... prepare/finish might - * be the places to enable/disable that mode. - */ - -static inline struct cortex_a_common *dpm_to_a(struct arm_dpm *dpm) -{ - return container_of(dpm, struct cortex_a_common, armv7a_common.dpm); -} - -static int cortex_a_write_dcc(struct cortex_a_common *a, uint32_t data) -{ - LOG_DEBUG("write DCC 0x%08" PRIx32, data); - return mem_ap_write_u32(a->armv7a_common.debug_ap, - a->armv7a_common.debug_base + CPUDBG_DTRRX, data); -} - -static int cortex_a_read_dcc(struct cortex_a_common *a, uint32_t *data, - uint32_t *dscr_p) -{ - uint32_t dscr = DSCR_INSTR_COMP; - int retval; - - if (dscr_p) - dscr = *dscr_p; - - /* Wait for DTRRXfull */ - 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, - &dscr); - if (retval != ERROR_OK) - return retval; - if (timeval_ms() > then + 1000) { - LOG_ERROR("Timeout waiting for read dcc"); - return ERROR_FAIL; - } - } - - retval = mem_ap_read_atomic_u32(a->armv7a_common.debug_ap, - a->armv7a_common.debug_base + CPUDBG_DTRTX, data); - if (retval != ERROR_OK) - return retval; - /* LOG_DEBUG("read DCC 0x%08" PRIx32, *data); */ - - if (dscr_p) - *dscr_p = dscr; - - return retval; -} - -static int cortex_a_dpm_prepare(struct arm_dpm *dpm) -{ - struct cortex_a_common *a = dpm_to_a(dpm); - uint32_t dscr; - int retval; - - /* set up invariant: INSTR_COMP is set after ever DPM operation */ - int64_t then = timeval_ms(); - for (;; ) { - retval = mem_ap_read_atomic_u32(a->armv7a_common.debug_ap, - a->armv7a_common.debug_base + CPUDBG_DSCR, - &dscr); - if (retval != ERROR_OK) - return retval; - if ((dscr & DSCR_INSTR_COMP) != 0) - break; - if (timeval_ms() > then + 1000) { - LOG_ERROR("Timeout waiting for dpm prepare"); - return ERROR_FAIL; - } - } - - /* this "should never happen" ... */ - if (dscr & DSCR_DTR_RX_FULL) { - LOG_ERROR("DSCR_DTR_RX_FULL, dscr 0x%08" PRIx32, dscr); - /* Clear DCCRX */ - retval = cortex_a_exec_opcode( - a->armv7a_common.arm.target, - ARMV4_5_MRC(14, 0, 0, 0, 5, 0), - &dscr); - if (retval != ERROR_OK) - return retval; - } - - return retval; -} - -static int cortex_a_dpm_finish(struct arm_dpm *dpm) -{ - /* REVISIT what could be done here? */ - return ERROR_OK; -} - -static int cortex_a_instr_write_data_dcc(struct arm_dpm *dpm, - uint32_t opcode, uint32_t data) -{ - struct cortex_a_common *a = dpm_to_a(dpm); - int retval; - uint32_t dscr = DSCR_INSTR_COMP; - - retval = cortex_a_write_dcc(a, data); - if (retval != ERROR_OK) - return retval; - - return cortex_a_exec_opcode( - a->armv7a_common.arm.target, - opcode, - &dscr); -} - -static int cortex_a_instr_write_data_r0(struct arm_dpm *dpm, - uint32_t opcode, uint32_t data) -{ - struct cortex_a_common *a = dpm_to_a(dpm); - uint32_t dscr = DSCR_INSTR_COMP; - int retval; - - retval = cortex_a_write_dcc(a, data); - if (retval != ERROR_OK) - return retval; - - /* DCCRX to R0, "MCR p14, 0, R0, c0, c5, 0", 0xEE000E15 */ - retval = cortex_a_exec_opcode( - a->armv7a_common.arm.target, - ARMV4_5_MRC(14, 0, 0, 0, 5, 0), - &dscr); - if (retval != ERROR_OK) - return retval; - - /* then the opcode, taking data from R0 */ - retval = cortex_a_exec_opcode( - a->armv7a_common.arm.target, - opcode, - &dscr); - - return retval; -} - -static int cortex_a_instr_cpsr_sync(struct arm_dpm *dpm) -{ - struct target *target = dpm->arm->target; - uint32_t dscr = DSCR_INSTR_COMP; - - /* "Prefetch flush" after modifying execution status in CPSR */ - return cortex_a_exec_opcode(target, - ARMV4_5_MCR(15, 0, 0, 7, 5, 4), - &dscr); -} - -static int cortex_a_instr_read_data_dcc(struct arm_dpm *dpm, - uint32_t opcode, uint32_t *data) -{ - struct cortex_a_common *a = dpm_to_a(dpm); - int retval; - uint32_t dscr = DSCR_INSTR_COMP; - - /* the opcode, writing data to DCC */ - retval = cortex_a_exec_opcode( - a->armv7a_common.arm.target, - opcode, - &dscr); - if (retval != ERROR_OK) - return retval; - - return cortex_a_read_dcc(a, data, &dscr); -} - - -static int cortex_a_instr_read_data_r0(struct arm_dpm *dpm, - uint32_t opcode, uint32_t *data) -{ - struct cortex_a_common *a = dpm_to_a(dpm); - uint32_t dscr = DSCR_INSTR_COMP; - int retval; - - /* the opcode, writing data to R0 */ - retval = cortex_a_exec_opcode( - a->armv7a_common.arm.target, - opcode, - &dscr); - if (retval != ERROR_OK) - return retval; - - /* write R0 to DCC */ - retval = cortex_a_exec_opcode( - a->armv7a_common.arm.target, - ARMV4_5_MCR(14, 0, 0, 0, 5, 0), - &dscr); - if (retval != ERROR_OK) - return retval; - - return cortex_a_read_dcc(a, data, &dscr); -} - -static int cortex_a_bpwp_enable(struct arm_dpm *dpm, unsigned index_t, - uint32_t addr, uint32_t control) -{ - struct cortex_a_common *a = dpm_to_a(dpm); - uint32_t vr = a->armv7a_common.debug_base; - uint32_t cr = a->armv7a_common.debug_base; - int retval; - - switch (index_t) { - case 0 ... 15: /* breakpoints */ - vr += CPUDBG_BVR_BASE; - cr += CPUDBG_BCR_BASE; - break; - case 16 ... 31: /* watchpoints */ - vr += CPUDBG_WVR_BASE; - cr += CPUDBG_WCR_BASE; - index_t -= 16; - break; - default: - return ERROR_FAIL; - } - vr += 4 * index_t; - cr += 4 * index_t; - - LOG_DEBUG("A: bpwp enable, vr %08x cr %08x", - (unsigned) vr, (unsigned) cr); - - retval = cortex_a_dap_write_memap_register_u32(dpm->arm->target, - vr, addr); - if (retval != ERROR_OK) - return retval; - retval = cortex_a_dap_write_memap_register_u32(dpm->arm->target, - cr, control); - return retval; -} - -static int cortex_a_bpwp_disable(struct arm_dpm *dpm, unsigned index_t) -{ - struct cortex_a_common *a = dpm_to_a(dpm); - uint32_t cr; - - switch (index_t) { - case 0 ... 15: - cr = a->armv7a_common.debug_base + CPUDBG_BCR_BASE; - break; - case 16 ... 31: - cr = a->armv7a_common.debug_base + CPUDBG_WCR_BASE; - index_t -= 16; - break; - default: - return ERROR_FAIL; - } - cr += 4 * index_t; - - LOG_DEBUG("A: bpwp disable, cr %08x", (unsigned) cr); - - /* clear control register */ - return cortex_a_dap_write_memap_register_u32(dpm->arm->target, cr, 0); -} - -static int cortex_a_dpm_setup(struct cortex_a_common *a, uint32_t didr) -{ - struct arm_dpm *dpm = &a->armv7a_common.dpm; - int retval; - - dpm->arm = &a->armv7a_common.arm; - dpm->didr = didr; - - dpm->prepare = cortex_a_dpm_prepare; - dpm->finish = cortex_a_dpm_finish; - - dpm->instr_write_data_dcc = cortex_a_instr_write_data_dcc; - dpm->instr_write_data_r0 = cortex_a_instr_write_data_r0; - dpm->instr_cpsr_sync = cortex_a_instr_cpsr_sync; - - dpm->instr_read_data_dcc = cortex_a_instr_read_data_dcc; - dpm->instr_read_data_r0 = cortex_a_instr_read_data_r0; - - dpm->bpwp_enable = cortex_a_bpwp_enable; - dpm->bpwp_disable = cortex_a_bpwp_disable; - - retval = arm_dpm_setup(dpm); - if (retval == ERROR_OK) - retval = arm_dpm_initialize(dpm); - - return retval; -} -static struct target *get_cortex_a(struct target *target, int32_t coreid) -{ - struct target_list *head; - struct target *curr; - - head = target->head; - while (head != (struct target_list *)NULL) { - curr = head->target; - if ((curr->coreid == coreid) && (curr->state == TARGET_HALTED)) - return curr; - head = head->next; - } - return target; -} -static int cortex_a_halt(struct target *target); - -static int cortex_a_halt_smp(struct target *target) -{ - int retval = 0; - struct target_list *head; - struct target *curr; - head = target->head; - while (head != (struct target_list *)NULL) { - curr = head->target; - if ((curr != target) && (curr->state != TARGET_HALTED)) - retval += cortex_a_halt(curr); - head = head->next; - } - return retval; -} - -static int update_halt_gdb(struct target *target) -{ - int retval = 0; - if (target->gdb_service && target->gdb_service->core[0] == -1) { - target->gdb_service->target = target; - target->gdb_service->core[0] = target->coreid; - retval += cortex_a_halt_smp(target); - } - return retval; -} - -/* - * Cortex-A Run control - */ - -static int cortex_a_poll(struct target *target) -{ - int retval = ERROR_OK; - uint32_t dscr; - struct cortex_a_common *cortex_a = target_to_cortex_a(target); - struct armv7a_common *armv7a = &cortex_a->armv7a_common; - enum target_state prev_target_state = target->state; - /* toggle to another core is done by gdb as follow */ - /* maint packet J core_id */ - /* continue */ - /* the next polling trigger an halt event sent to gdb */ - if ((target->state == TARGET_HALTED) && (target->smp) && - (target->gdb_service) && - (target->gdb_service->target == NULL)) { - target->gdb_service->target = - get_cortex_a(target, target->gdb_service->core[1]); - target_call_event_callbacks(target, TARGET_EVENT_HALTED); - return retval; - } - retval = mem_ap_read_atomic_u32(armv7a->debug_ap, - armv7a->debug_base + CPUDBG_DSCR, &dscr); - if (retval != ERROR_OK) - return retval; - cortex_a->cpudbg_dscr = dscr; - - if (DSCR_RUN_MODE(dscr) == (DSCR_CORE_HALTED | DSCR_CORE_RESTARTED)) { - if (prev_target_state != TARGET_HALTED) { - /* We have a halting debug event */ - LOG_DEBUG("Target halted"); - target->state = TARGET_HALTED; - if ((prev_target_state == TARGET_RUNNING) - || (prev_target_state == TARGET_UNKNOWN) - || (prev_target_state == TARGET_RESET)) { - retval = cortex_a_debug_entry(target); - if (retval != ERROR_OK) - return retval; - if (target->smp) { - retval = update_halt_gdb(target); - if (retval != ERROR_OK) - return retval; - } - target_call_event_callbacks(target, - TARGET_EVENT_HALTED); - } - if (prev_target_state == TARGET_DEBUG_RUNNING) { - LOG_DEBUG(" "); - - retval = cortex_a_debug_entry(target); - if (retval != ERROR_OK) - return retval; - if (target->smp) { - retval = update_halt_gdb(target); - if (retval != ERROR_OK) - return retval; - } - - target_call_event_callbacks(target, - TARGET_EVENT_DEBUG_HALTED); - } - } - } else if (DSCR_RUN_MODE(dscr) == DSCR_CORE_RESTARTED) - target->state = TARGET_RUNNING; - else { - LOG_DEBUG("Unknown target state dscr = 0x%08" PRIx32, dscr); - target->state = TARGET_UNKNOWN; - } - - return retval; -} - -static int cortex_a_halt(struct target *target) -{ - int retval = ERROR_OK; - uint32_t dscr; - struct armv7a_common *armv7a = target_to_armv7a(target); - - /* - * Tell the core to be halted by writing DRCR with 0x1 - * and then wait for the core to be halted. - */ - retval = mem_ap_write_atomic_u32(armv7a->debug_ap, - armv7a->debug_base + CPUDBG_DRCR, DRCR_HALT); - if (retval != ERROR_OK) - return retval; - - /* - * enter halting debug mode - */ - retval = mem_ap_read_atomic_u32(armv7a->debug_ap, - armv7a->debug_base + CPUDBG_DSCR, &dscr); - if (retval != ERROR_OK) - return retval; - - retval = mem_ap_write_atomic_u32(armv7a->debug_ap, - armv7a->debug_base + CPUDBG_DSCR, dscr | DSCR_HALT_DBG_MODE); - if (retval != ERROR_OK) - return retval; - - int64_t then = timeval_ms(); - for (;; ) { - retval = mem_ap_read_atomic_u32(armv7a->debug_ap, - armv7a->debug_base + CPUDBG_DSCR, &dscr); - if (retval != ERROR_OK) - return retval; - if ((dscr & DSCR_CORE_HALTED) != 0) - break; - if (timeval_ms() > then + 1000) { - LOG_ERROR("Timeout waiting for halt"); - return ERROR_FAIL; - } - } - - target->debug_reason = DBG_REASON_DBGRQ; - - return ERROR_OK; -} - -static int cortex_a_internal_restore(struct target *target, int current, - uint32_t *address, int handle_breakpoints, int debug_execution) -{ - struct armv7a_common *armv7a = target_to_armv7a(target); - struct arm *arm = &armv7a->arm; - int retval; - uint32_t resume_pc; - - if (!debug_execution) - target_free_all_working_areas(target); - -#if 0 - if (debug_execution) { - /* Disable interrupts */ - /* We disable interrupts in the PRIMASK register instead of - * masking with C_MASKINTS, - * This is probably the same issue as Cortex-M3 Errata 377493: - * C_MASKINTS in parallel with disabled interrupts can cause - * local faults to not be taken. */ - buf_set_u32(armv7m->core_cache->reg_list[ARMV7M_PRIMASK].value, 0, 32, 1); - armv7m->core_cache->reg_list[ARMV7M_PRIMASK].dirty = 1; - armv7m->core_cache->reg_list[ARMV7M_PRIMASK].valid = 1; - - /* Make sure we are in Thumb mode */ - buf_set_u32(armv7m->core_cache->reg_list[ARMV7M_xPSR].value, 0, 32, - buf_get_u32(armv7m->core_cache->reg_list[ARMV7M_xPSR].value, 0, - 32) | (1 << 24)); - armv7m->core_cache->reg_list[ARMV7M_xPSR].dirty = 1; - armv7m->core_cache->reg_list[ARMV7M_xPSR].valid = 1; - } -#endif - - /* current = 1: continue on current pc, otherwise continue at
*/ - resume_pc = buf_get_u32(arm->pc->value, 0, 32); - if (!current) - resume_pc = *address; - else - *address = resume_pc; - - /* Make sure that the Armv7 gdb thumb fixups does not - * kill the return address - */ - switch (arm->core_state) { - case ARM_STATE_ARM: - resume_pc &= 0xFFFFFFFC; - break; - case ARM_STATE_THUMB: - case ARM_STATE_THUMB_EE: - /* When the return address is loaded into PC - * bit 0 must be 1 to stay in Thumb state - */ - resume_pc |= 0x1; - break; - case ARM_STATE_JAZELLE: - LOG_ERROR("How do I resume into Jazelle state??"); - return ERROR_FAIL; - } - LOG_DEBUG("resume pc = 0x%08" PRIx32, resume_pc); - buf_set_u32(arm->pc->value, 0, 32, resume_pc); - arm->pc->dirty = 1; - arm->pc->valid = 1; - - /* restore dpm_mode at system halt */ - dpm_modeswitch(&armv7a->dpm, ARM_MODE_ANY); - /* called it now before restoring context because it uses cpu - * register r0 for restoring cp15 control register */ - retval = cortex_a_restore_cp15_control_reg(target); - if (retval != ERROR_OK) - return retval; - retval = cortex_a_restore_context(target, handle_breakpoints); - if (retval != ERROR_OK) - return retval; - target->debug_reason = DBG_REASON_NOTHALTED; - target->state = TARGET_RUNNING; - - /* registers are now invalid */ - register_cache_invalidate(arm->core_cache); - -#if 0 - /* the front-end may request us not to handle breakpoints */ - if (handle_breakpoints) { - /* Single step past breakpoint at current address */ - breakpoint = breakpoint_find(target, resume_pc); - if (breakpoint) { - LOG_DEBUG("unset breakpoint at 0x%8.8x", breakpoint->address); - cortex_m3_unset_breakpoint(target, breakpoint); - cortex_m3_single_step_core(target); - cortex_m3_set_breakpoint(target, breakpoint); - } - } - -#endif - return retval; -} - -static int cortex_a_internal_restart(struct target *target) -{ - struct armv7a_common *armv7a = target_to_armv7a(target); - struct arm *arm = &armv7a->arm; - int retval; - uint32_t dscr; - /* - * * Restart core and wait for it to be started. Clear ITRen and sticky - * * exception flags: see ARMv7 ARM, C5.9. - * - * REVISIT: for single stepping, we probably want to - * disable IRQs by default, with optional override... - */ - - retval = mem_ap_read_atomic_u32(armv7a->debug_ap, - armv7a->debug_base + CPUDBG_DSCR, &dscr); - if (retval != ERROR_OK) - return retval; - - if ((dscr & DSCR_INSTR_COMP) == 0) - LOG_ERROR("DSCR InstrCompl must be set before leaving debug!"); - - retval = mem_ap_write_atomic_u32(armv7a->debug_ap, - armv7a->debug_base + CPUDBG_DSCR, dscr & ~DSCR_ITR_EN); - if (retval != ERROR_OK) - return retval; - - retval = mem_ap_write_atomic_u32(armv7a->debug_ap, - armv7a->debug_base + CPUDBG_DRCR, DRCR_RESTART | - DRCR_CLEAR_EXCEPTIONS); - if (retval != ERROR_OK) - return retval; - - int64_t then = timeval_ms(); - for (;; ) { - retval = mem_ap_read_atomic_u32(armv7a->debug_ap, - armv7a->debug_base + CPUDBG_DSCR, &dscr); - if (retval != ERROR_OK) - return retval; - if ((dscr & DSCR_CORE_RESTARTED) != 0) - break; - if (timeval_ms() > then + 1000) { - LOG_ERROR("Timeout waiting for resume"); - return ERROR_FAIL; - } - } - - target->debug_reason = DBG_REASON_NOTHALTED; - target->state = TARGET_RUNNING; - - /* registers are now invalid */ - register_cache_invalidate(arm->core_cache); - - return ERROR_OK; -} - -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; - head = target->head; - while (head != (struct target_list *)NULL) { - curr = head->target; - if ((curr != target) && (curr->state != TARGET_RUNNING)) { - /* resume current address , not in step mode */ - retval += cortex_a_internal_restore(curr, 1, &address, - handle_breakpoints, 0); - retval += cortex_a_internal_restart(curr); - } - head = head->next; - - } - return retval; -} - -static int cortex_a_resume(struct target *target, int current, - uint32_t address, int handle_breakpoints, int debug_execution) -{ - int retval = 0; - /* dummy resume for smp toggle in order to reduce gdb impact */ - if ((target->smp) && (target->gdb_service->core[1] != -1)) { - /* simulate a start and halt of target */ - target->gdb_service->target = NULL; - target->gdb_service->core[0] = target->gdb_service->core[1]; - /* fake resume at next poll we play the target core[1], see poll*/ - target_call_event_callbacks(target, TARGET_EVENT_RESUMED); - return 0; - } - cortex_a_internal_restore(target, current, &address, handle_breakpoints, debug_execution); - if (target->smp) { - target->gdb_service->core[0] = -1; - retval = cortex_a_restore_smp(target, handle_breakpoints); - if (retval != ERROR_OK) - return retval; - } - cortex_a_internal_restart(target); - - if (!debug_execution) { - target->state = TARGET_RUNNING; - target_call_event_callbacks(target, TARGET_EVENT_RESUMED); - LOG_DEBUG("target resumed at 0x%" PRIx32, 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); - } - - return ERROR_OK; -} - -static int cortex_a_debug_entry(struct target *target) -{ - int i; - uint32_t regfile[16], cpsr, dscr; - int retval = ERROR_OK; - struct working_area *regfile_working_area = NULL; - struct cortex_a_common *cortex_a = target_to_cortex_a(target); - struct armv7a_common *armv7a = target_to_armv7a(target); - struct arm *arm = &armv7a->arm; - struct reg *reg; - - LOG_DEBUG("dscr = 0x%08" PRIx32, cortex_a->cpudbg_dscr); - - /* REVISIT surely we should not re-read DSCR !! */ - retval = mem_ap_read_atomic_u32(armv7a->debug_ap, - armv7a->debug_base + CPUDBG_DSCR, &dscr); - if (retval != ERROR_OK) - return retval; - - /* REVISIT see A TRM 12.11.4 steps 2..3 -- make sure that any - * imprecise data aborts get discarded by issuing a Data - * Synchronization Barrier: ARMV4_5_MCR(15, 0, 0, 7, 10, 4). - */ - - /* Enable the ITR execution once we are in debug mode */ - dscr |= DSCR_ITR_EN; - retval = mem_ap_write_atomic_u32(armv7a->debug_ap, - armv7a->debug_base + CPUDBG_DSCR, dscr); - if (retval != ERROR_OK) - return retval; - - /* Examine debug reason */ - arm_dpm_report_dscr(&armv7a->dpm, cortex_a->cpudbg_dscr); - - /* save address of instruction that triggered the watchpoint? */ - if (target->debug_reason == DBG_REASON_WATCHPOINT) { - uint32_t wfar; - - retval = mem_ap_read_atomic_u32(armv7a->debug_ap, - armv7a->debug_base + CPUDBG_WFAR, - &wfar); - if (retval != ERROR_OK) - return retval; - arm_dpm_report_wfar(&armv7a->dpm, wfar); - } - - /* REVISIT fast_reg_read is never set ... */ - - /* Examine target state and mode */ - 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); - else { - retval = cortex_a_read_regs_through_mem(target, - regfile_working_area->address, regfile); - - target_free_working_area(target, regfile_working_area); - if (retval != ERROR_OK) - return retval; - - /* read Current PSR */ - retval = cortex_a_dap_read_coreregister_u32(target, &cpsr, 16); - /* store current cpsr */ - if (retval != ERROR_OK) - return retval; - - LOG_DEBUG("cpsr: %8.8" PRIx32, cpsr); - - arm_set_cpsr(arm, cpsr); - - /* update cache */ - for (i = 0; i <= ARM_PC; i++) { - reg = arm_reg_current(arm, i); - - buf_set_u32(reg->value, 0, 32, regfile[i]); - reg->valid = 1; - reg->dirty = 0; - } - - /* Fixup PC Resume Address */ - if (cpsr & (1 << 5)) { - /* T bit set for Thumb or ThumbEE state */ - regfile[ARM_PC] -= 4; - } else { - /* ARM state */ - regfile[ARM_PC] -= 8; - } - - reg = arm->pc; - buf_set_u32(reg->value, 0, 32, regfile[ARM_PC]); - reg->dirty = reg->valid; - } - -#if 0 -/* TODO, Move this */ - uint32_t cp15_control_register, cp15_cacr, cp15_nacr; - cortex_a_read_cp(target, &cp15_control_register, 15, 0, 1, 0, 0); - LOG_DEBUG("cp15_control_register = 0x%08x", cp15_control_register); - - cortex_a_read_cp(target, &cp15_cacr, 15, 0, 1, 0, 2); - LOG_DEBUG("cp15 Coprocessor Access Control Register = 0x%08x", cp15_cacr); - - cortex_a_read_cp(target, &cp15_nacr, 15, 0, 1, 1, 2); - LOG_DEBUG("cp15 Nonsecure Access Control Register = 0x%08x", cp15_nacr); -#endif - - /* Are we in an exception handler */ -/* armv4_5->exception_number = 0; */ - if (armv7a->post_debug_entry) { - retval = armv7a->post_debug_entry(target); - if (retval != ERROR_OK) - return retval; - } - - return retval; -} - -static int cortex_a_post_debug_entry(struct target *target) -{ - struct cortex_a_common *cortex_a = target_to_cortex_a(target); - struct armv7a_common *armv7a = &cortex_a->armv7a_common; - int retval; - - /* MRC p15,0,,c1,c0,0 ; Read CP15 System Control Register */ - retval = armv7a->arm.mrc(target, 15, - 0, 0, /* op1, op2 */ - 1, 0, /* CRn, CRm */ - &cortex_a->cp15_control_reg); - if (retval != ERROR_OK) - return retval; - LOG_DEBUG("cp15_control_reg: %8.8" PRIx32, cortex_a->cp15_control_reg); - cortex_a->cp15_control_reg_curr = cortex_a->cp15_control_reg; - - if (armv7a->armv7a_mmu.armv7a_cache.info == -1) - armv7a_identify_cache(target); - - if (armv7a->is_armv7r) { - armv7a->armv7a_mmu.mmu_enabled = 0; - } else { - armv7a->armv7a_mmu.mmu_enabled = - (cortex_a->cp15_control_reg & 0x1U) ? 1 : 0; - } - armv7a->armv7a_mmu.armv7a_cache.d_u_cache_enabled = - (cortex_a->cp15_control_reg & 0x4U) ? 1 : 0; - armv7a->armv7a_mmu.armv7a_cache.i_cache_enabled = - (cortex_a->cp15_control_reg & 0x1000U) ? 1 : 0; - cortex_a->curr_mode = armv7a->arm.core_mode; - - /* switch to SVC mode to read DACR */ - dpm_modeswitch(&armv7a->dpm, ARM_MODE_SVC); - armv7a->arm.mrc(target, 15, - 0, 0, 3, 0, - &cortex_a->cp15_dacr_reg); - - LOG_DEBUG("cp15_dacr_reg: %8.8" PRIx32, - cortex_a->cp15_dacr_reg); - - dpm_modeswitch(&armv7a->dpm, ARM_MODE_ANY); - return ERROR_OK; -} - -int cortex_a_set_dscr_bits(struct target *target, unsigned long bit_mask, unsigned long value) -{ - struct armv7a_common *armv7a = target_to_armv7a(target); - uint32_t dscr; - - /* Read DSCR */ - int retval = mem_ap_read_atomic_u32(armv7a->debug_ap, - armv7a->debug_base + CPUDBG_DSCR, &dscr); - if (ERROR_OK != retval) - return retval; - - /* clear bitfield */ - dscr &= ~bit_mask; - /* put new value */ - dscr |= value & bit_mask; - - /* write new DSCR */ - retval = mem_ap_write_atomic_u32(armv7a->debug_ap, - armv7a->debug_base + CPUDBG_DSCR, dscr); - return retval; -} - -static int cortex_a_step(struct target *target, int current, uint32_t address, - int handle_breakpoints) -{ - struct cortex_a_common *cortex_a = target_to_cortex_a(target); - struct armv7a_common *armv7a = target_to_armv7a(target); - struct arm *arm = &armv7a->arm; - struct breakpoint *breakpoint = NULL; - struct breakpoint stepbreakpoint; - struct reg *r; - int retval; - - if (target->state != TARGET_HALTED) { - LOG_WARNING("target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - /* current = 1: continue on current pc, otherwise continue at
*/ - r = arm->pc; - if (!current) - buf_set_u32(r->value, 0, 32, address); - else - address = buf_get_u32(r->value, 0, 32); - - /* The front-end may request us not to handle breakpoints. - * But since Cortex-A uses breakpoint for single step, - * we MUST handle breakpoints. - */ - handle_breakpoints = 1; - if (handle_breakpoints) { - breakpoint = breakpoint_find(target, address); - if (breakpoint) - cortex_a_unset_breakpoint(target, breakpoint); - } - - /* Setup single step breakpoint */ - stepbreakpoint.address = address; - stepbreakpoint.length = (arm->core_state == ARM_STATE_THUMB) - ? 2 : 4; - stepbreakpoint.type = BKPT_HARD; - stepbreakpoint.set = 0; - - /* Disable interrupts during single step if requested */ - if (cortex_a->isrmasking_mode == CORTEX_A_ISRMASK_ON) { - retval = cortex_a_set_dscr_bits(target, DSCR_INT_DIS, DSCR_INT_DIS); - if (ERROR_OK != retval) - return retval; - } - - /* Break on IVA mismatch */ - cortex_a_set_breakpoint(target, &stepbreakpoint, 0x04); - - target->debug_reason = DBG_REASON_SINGLESTEP; - - retval = cortex_a_resume(target, 1, address, 0, 0); - if (retval != ERROR_OK) - return retval; - - int64_t then = timeval_ms(); - while (target->state != TARGET_HALTED) { - retval = cortex_a_poll(target); - if (retval != ERROR_OK) - return retval; - if (timeval_ms() > then + 1000) { - LOG_ERROR("timeout waiting for target halt"); - return ERROR_FAIL; - } - } - - cortex_a_unset_breakpoint(target, &stepbreakpoint); - - /* Re-enable interrupts if they were disabled */ - if (cortex_a->isrmasking_mode == CORTEX_A_ISRMASK_ON) { - retval = cortex_a_set_dscr_bits(target, DSCR_INT_DIS, 0); - if (ERROR_OK != retval) - return retval; - } - - - target->debug_reason = DBG_REASON_BREAKPOINT; - - if (breakpoint) - cortex_a_set_breakpoint(target, breakpoint, 0); - - if (target->state != TARGET_HALTED) - LOG_DEBUG("target stepped"); - - return ERROR_OK; -} - -static int cortex_a_restore_context(struct target *target, bool bpwp) -{ - struct armv7a_common *armv7a = target_to_armv7a(target); - - LOG_DEBUG(" "); - - if (armv7a->pre_restore_context) - armv7a->pre_restore_context(target); - - return arm_dpm_write_dirty_registers(&armv7a->dpm, bpwp); -} - -/* - * Cortex-A Breakpoint and watchpoint functions - */ - -/* Setup hardware Breakpoint Register Pair */ -static int cortex_a_set_breakpoint(struct target *target, - struct breakpoint *breakpoint, uint8_t matchmode) -{ - int retval; - int brp_i = 0; - uint32_t control; - uint8_t byte_addr_select = 0x0F; - struct cortex_a_common *cortex_a = target_to_cortex_a(target); - struct armv7a_common *armv7a = &cortex_a->armv7a_common; - struct cortex_a_brp *brp_list = cortex_a->brp_list; - - if (breakpoint->set) { - LOG_WARNING("breakpoint already set"); - return ERROR_OK; - } - - if (breakpoint->type == BKPT_HARD) { - while (brp_list[brp_i].used && (brp_i < cortex_a->brp_num)) - brp_i++; - if (brp_i >= cortex_a->brp_num) { - LOG_ERROR("ERROR Can not find free Breakpoint Register Pair"); - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - } - breakpoint->set = brp_i + 1; - if (breakpoint->length == 2) - byte_addr_select = (3 << (breakpoint->address & 0x02)); - control = ((matchmode & 0x7) << 20) - | (byte_addr_select << 5) - | (3 << 1) | 1; - brp_list[brp_i].used = 1; - brp_list[brp_i].value = (breakpoint->address & 0xFFFFFFFC); - brp_list[brp_i].control = control; - retval = cortex_a_dap_write_memap_register_u32(target, armv7a->debug_base - + CPUDBG_BVR_BASE + 4 * brp_list[brp_i].BRPn, - brp_list[brp_i].value); - if (retval != ERROR_OK) - return retval; - retval = cortex_a_dap_write_memap_register_u32(target, armv7a->debug_base - + CPUDBG_BCR_BASE + 4 * brp_list[brp_i].BRPn, - brp_list[brp_i].control); - if (retval != ERROR_OK) - return retval; - LOG_DEBUG("brp %i control 0x%0" PRIx32 " value 0x%0" PRIx32, brp_i, - brp_list[brp_i].control, - brp_list[brp_i].value); - } else if (breakpoint->type == BKPT_SOFT) { - uint8_t code[4]; - if (breakpoint->length == 2) - buf_set_u32(code, 0, 32, ARMV5_T_BKPT(0x11)); - else - buf_set_u32(code, 0, 32, ARMV5_BKPT(0x11)); - retval = target_read_memory(target, - breakpoint->address & 0xFFFFFFFE, - breakpoint->length, 1, - breakpoint->orig_instr); - if (retval != ERROR_OK) - return retval; - - /* make sure data cache is cleaned & invalidated down to PoC */ - if (!armv7a->armv7a_mmu.armv7a_cache.auto_cache_enabled) { - armv7a_cache_flush_virt(target, breakpoint->address, - breakpoint->length); - } - - retval = target_write_memory(target, - breakpoint->address & 0xFFFFFFFE, - breakpoint->length, 1, code); - if (retval != ERROR_OK) - return retval; - - /* update i-cache at breakpoint location */ - armv7a_l1_d_cache_inval_virt(target, breakpoint->address, - breakpoint->length); - armv7a_l1_i_cache_inval_virt(target, breakpoint->address, - breakpoint->length); - - breakpoint->set = 0x11; /* Any nice value but 0 */ - } - - return ERROR_OK; -} - -static int cortex_a_set_context_breakpoint(struct target *target, - struct breakpoint *breakpoint, uint8_t matchmode) -{ - int retval = ERROR_FAIL; - int brp_i = 0; - uint32_t control; - uint8_t byte_addr_select = 0x0F; - struct cortex_a_common *cortex_a = target_to_cortex_a(target); - struct armv7a_common *armv7a = &cortex_a->armv7a_common; - struct cortex_a_brp *brp_list = cortex_a->brp_list; - - if (breakpoint->set) { - LOG_WARNING("breakpoint already set"); - return retval; - } - /*check available context BRPs*/ - while ((brp_list[brp_i].used || - (brp_list[brp_i].type != BRP_CONTEXT)) && (brp_i < cortex_a->brp_num)) - brp_i++; - - if (brp_i >= cortex_a->brp_num) { - LOG_ERROR("ERROR Can not find free Breakpoint Register Pair"); - return ERROR_FAIL; - } - - breakpoint->set = brp_i + 1; - control = ((matchmode & 0x7) << 20) - | (byte_addr_select << 5) - | (3 << 1) | 1; - brp_list[brp_i].used = 1; - brp_list[brp_i].value = (breakpoint->asid); - brp_list[brp_i].control = control; - retval = cortex_a_dap_write_memap_register_u32(target, armv7a->debug_base - + CPUDBG_BVR_BASE + 4 * brp_list[brp_i].BRPn, - brp_list[brp_i].value); - if (retval != ERROR_OK) - return retval; - retval = cortex_a_dap_write_memap_register_u32(target, armv7a->debug_base - + CPUDBG_BCR_BASE + 4 * brp_list[brp_i].BRPn, - brp_list[brp_i].control); - if (retval != ERROR_OK) - return retval; - LOG_DEBUG("brp %i control 0x%0" PRIx32 " value 0x%0" PRIx32, brp_i, - brp_list[brp_i].control, - brp_list[brp_i].value); - return ERROR_OK; - -} - -static int cortex_a_set_hybrid_breakpoint(struct target *target, struct breakpoint *breakpoint) -{ - int retval = ERROR_FAIL; - int brp_1 = 0; /* holds the contextID pair */ - int brp_2 = 0; /* holds the IVA pair */ - uint32_t control_CTX, control_IVA; - uint8_t CTX_byte_addr_select = 0x0F; - uint8_t IVA_byte_addr_select = 0x0F; - uint8_t CTX_machmode = 0x03; - uint8_t IVA_machmode = 0x01; - struct cortex_a_common *cortex_a = target_to_cortex_a(target); - struct armv7a_common *armv7a = &cortex_a->armv7a_common; - struct cortex_a_brp *brp_list = cortex_a->brp_list; - - if (breakpoint->set) { - LOG_WARNING("breakpoint already set"); - return retval; - } - /*check available context BRPs*/ - while ((brp_list[brp_1].used || - (brp_list[brp_1].type != BRP_CONTEXT)) && (brp_1 < cortex_a->brp_num)) - brp_1++; - - printf("brp(CTX) found num: %d\n", brp_1); - if (brp_1 >= cortex_a->brp_num) { - LOG_ERROR("ERROR Can not find free Breakpoint Register Pair"); - return ERROR_FAIL; - } - - while ((brp_list[brp_2].used || - (brp_list[brp_2].type != BRP_NORMAL)) && (brp_2 < cortex_a->brp_num)) - brp_2++; - - printf("brp(IVA) found num: %d\n", brp_2); - if (brp_2 >= cortex_a->brp_num) { - LOG_ERROR("ERROR Can not find free Breakpoint Register Pair"); - return ERROR_FAIL; - } - - breakpoint->set = brp_1 + 1; - breakpoint->linked_BRP = brp_2; - control_CTX = ((CTX_machmode & 0x7) << 20) - | (brp_2 << 16) - | (0 << 14) - | (CTX_byte_addr_select << 5) - | (3 << 1) | 1; - brp_list[brp_1].used = 1; - brp_list[brp_1].value = (breakpoint->asid); - brp_list[brp_1].control = control_CTX; - retval = cortex_a_dap_write_memap_register_u32(target, armv7a->debug_base - + CPUDBG_BVR_BASE + 4 * brp_list[brp_1].BRPn, - brp_list[brp_1].value); - if (retval != ERROR_OK) - return retval; - retval = cortex_a_dap_write_memap_register_u32(target, armv7a->debug_base - + CPUDBG_BCR_BASE + 4 * brp_list[brp_1].BRPn, - brp_list[brp_1].control); - if (retval != ERROR_OK) - return retval; - - control_IVA = ((IVA_machmode & 0x7) << 20) - | (brp_1 << 16) - | (IVA_byte_addr_select << 5) - | (3 << 1) | 1; - brp_list[brp_2].used = 1; - brp_list[brp_2].value = (breakpoint->address & 0xFFFFFFFC); - brp_list[brp_2].control = control_IVA; - retval = cortex_a_dap_write_memap_register_u32(target, armv7a->debug_base - + CPUDBG_BVR_BASE + 4 * brp_list[brp_2].BRPn, - brp_list[brp_2].value); - if (retval != ERROR_OK) - return retval; - retval = cortex_a_dap_write_memap_register_u32(target, armv7a->debug_base - + CPUDBG_BCR_BASE + 4 * brp_list[brp_2].BRPn, - brp_list[brp_2].control); - if (retval != ERROR_OK) - return retval; - - return ERROR_OK; -} - -static int cortex_a_unset_breakpoint(struct target *target, struct breakpoint *breakpoint) -{ - int retval; - struct cortex_a_common *cortex_a = target_to_cortex_a(target); - struct armv7a_common *armv7a = &cortex_a->armv7a_common; - struct cortex_a_brp *brp_list = cortex_a->brp_list; - - if (!breakpoint->set) { - LOG_WARNING("breakpoint not set"); - return ERROR_OK; - } - - if (breakpoint->type == BKPT_HARD) { - if ((breakpoint->address != 0) && (breakpoint->asid != 0)) { - int brp_i = breakpoint->set - 1; - int brp_j = breakpoint->linked_BRP; - if ((brp_i < 0) || (brp_i >= cortex_a->brp_num)) { - LOG_DEBUG("Invalid BRP number in breakpoint"); - return ERROR_OK; - } - LOG_DEBUG("rbp %i control 0x%0" PRIx32 " value 0x%0" PRIx32, brp_i, - brp_list[brp_i].control, brp_list[brp_i].value); - brp_list[brp_i].used = 0; - brp_list[brp_i].value = 0; - brp_list[brp_i].control = 0; - retval = cortex_a_dap_write_memap_register_u32(target, armv7a->debug_base - + CPUDBG_BCR_BASE + 4 * brp_list[brp_i].BRPn, - brp_list[brp_i].control); - if (retval != ERROR_OK) - return retval; - retval = cortex_a_dap_write_memap_register_u32(target, armv7a->debug_base - + CPUDBG_BVR_BASE + 4 * brp_list[brp_i].BRPn, - brp_list[brp_i].value); - if (retval != ERROR_OK) - return retval; - if ((brp_j < 0) || (brp_j >= cortex_a->brp_num)) { - LOG_DEBUG("Invalid BRP number in breakpoint"); - return ERROR_OK; - } - LOG_DEBUG("rbp %i control 0x%0" PRIx32 " value 0x%0" PRIx32, brp_j, - brp_list[brp_j].control, brp_list[brp_j].value); - brp_list[brp_j].used = 0; - brp_list[brp_j].value = 0; - brp_list[brp_j].control = 0; - retval = cortex_a_dap_write_memap_register_u32(target, armv7a->debug_base - + CPUDBG_BCR_BASE + 4 * brp_list[brp_j].BRPn, - brp_list[brp_j].control); - if (retval != ERROR_OK) - return retval; - retval = cortex_a_dap_write_memap_register_u32(target, armv7a->debug_base - + CPUDBG_BVR_BASE + 4 * brp_list[brp_j].BRPn, - brp_list[brp_j].value); - if (retval != ERROR_OK) - return retval; - breakpoint->linked_BRP = 0; - breakpoint->set = 0; - return ERROR_OK; - - } else { - int brp_i = breakpoint->set - 1; - if ((brp_i < 0) || (brp_i >= cortex_a->brp_num)) { - LOG_DEBUG("Invalid BRP number in breakpoint"); - return ERROR_OK; - } - LOG_DEBUG("rbp %i control 0x%0" PRIx32 " value 0x%0" PRIx32, brp_i, - brp_list[brp_i].control, brp_list[brp_i].value); - brp_list[brp_i].used = 0; - brp_list[brp_i].value = 0; - brp_list[brp_i].control = 0; - retval = cortex_a_dap_write_memap_register_u32(target, armv7a->debug_base - + CPUDBG_BCR_BASE + 4 * brp_list[brp_i].BRPn, - brp_list[brp_i].control); - if (retval != ERROR_OK) - return retval; - retval = cortex_a_dap_write_memap_register_u32(target, armv7a->debug_base - + CPUDBG_BVR_BASE + 4 * brp_list[brp_i].BRPn, - brp_list[brp_i].value); - if (retval != ERROR_OK) - return retval; - breakpoint->set = 0; - return ERROR_OK; - } - } else { - - /* make sure data cache is cleaned & invalidated down to PoC */ - if (!armv7a->armv7a_mmu.armv7a_cache.auto_cache_enabled) { - armv7a_cache_flush_virt(target, breakpoint->address, - breakpoint->length); - } - - /* restore original instruction (kept in target endianness) */ - if (breakpoint->length == 4) { - retval = target_write_memory(target, - breakpoint->address & 0xFFFFFFFE, - 4, 1, breakpoint->orig_instr); - if (retval != ERROR_OK) - return retval; - } else { - retval = target_write_memory(target, - breakpoint->address & 0xFFFFFFFE, - 2, 1, breakpoint->orig_instr); - if (retval != ERROR_OK) - return retval; - } - - /* update i-cache at breakpoint location */ - armv7a_l1_d_cache_inval_virt(target, breakpoint->address, - breakpoint->length); - armv7a_l1_i_cache_inval_virt(target, breakpoint->address, - breakpoint->length); - } - breakpoint->set = 0; - - return ERROR_OK; -} - -static int cortex_a_add_breakpoint(struct target *target, - struct breakpoint *breakpoint) -{ - struct cortex_a_common *cortex_a = target_to_cortex_a(target); - - if ((breakpoint->type == BKPT_HARD) && (cortex_a->brp_num_available < 1)) { - LOG_INFO("no hardware breakpoint available"); - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - } - - if (breakpoint->type == BKPT_HARD) - cortex_a->brp_num_available--; - - return cortex_a_set_breakpoint(target, breakpoint, 0x00); /* Exact match */ -} - -static int cortex_a_add_context_breakpoint(struct target *target, - struct breakpoint *breakpoint) -{ - struct cortex_a_common *cortex_a = target_to_cortex_a(target); - - if ((breakpoint->type == BKPT_HARD) && (cortex_a->brp_num_available < 1)) { - LOG_INFO("no hardware breakpoint available"); - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - } - - if (breakpoint->type == BKPT_HARD) - cortex_a->brp_num_available--; - - return cortex_a_set_context_breakpoint(target, breakpoint, 0x02); /* asid match */ -} - -static int cortex_a_add_hybrid_breakpoint(struct target *target, - struct breakpoint *breakpoint) -{ - struct cortex_a_common *cortex_a = target_to_cortex_a(target); - - if ((breakpoint->type == BKPT_HARD) && (cortex_a->brp_num_available < 1)) { - LOG_INFO("no hardware breakpoint available"); - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - } - - if (breakpoint->type == BKPT_HARD) - cortex_a->brp_num_available--; - - return cortex_a_set_hybrid_breakpoint(target, breakpoint); /* ??? */ -} - - -static int cortex_a_remove_breakpoint(struct target *target, struct breakpoint *breakpoint) -{ - struct cortex_a_common *cortex_a = target_to_cortex_a(target); - -#if 0 -/* It is perfectly possible to remove breakpoints while the target is running */ - if (target->state != TARGET_HALTED) { - LOG_WARNING("target not halted"); - return ERROR_TARGET_NOT_HALTED; - } -#endif - - if (breakpoint->set) { - cortex_a_unset_breakpoint(target, breakpoint); - if (breakpoint->type == BKPT_HARD) - cortex_a->brp_num_available++; - } - - - return ERROR_OK; -} - -/* - * Cortex-A Reset functions - */ - -static int cortex_a_assert_reset(struct target *target) -{ - struct armv7a_common *armv7a = target_to_armv7a(target); - - LOG_DEBUG(" "); - - /* 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); - else if (jtag_get_reset_config() & RESET_HAS_SRST) { - /* REVISIT handle "pulls" cases, if there's - * hardware that needs them to work. - */ - if (target->reset_halt) - if (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); - - target->state = TARGET_RESET; - - return ERROR_OK; -} - -static int cortex_a_deassert_reset(struct target *target) -{ - int retval; - - LOG_DEBUG(" "); - - /* be certain SRST is off */ - jtag_add_reset(0, 0); - - 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; - } - } - - return ERROR_OK; -} - -static int cortex_a_set_dcc_mode(struct target *target, uint32_t mode, uint32_t *dscr) -{ - /* Changes the mode of the DCC between non-blocking, stall, and fast mode. - * New desired mode must be in mode. Current value of DSCR must be in - * *dscr, which is updated with new value. - * - * This function elides actually sending the mode-change over the debug - * interface if the mode is already set as desired. - */ - uint32_t new_dscr = (*dscr & ~DSCR_EXT_DCC_MASK) | mode; - if (new_dscr != *dscr) { - struct armv7a_common *armv7a = target_to_armv7a(target); - int retval = mem_ap_write_atomic_u32(armv7a->debug_ap, - armv7a->debug_base + CPUDBG_DSCR, new_dscr); - if (retval == ERROR_OK) - *dscr = new_dscr; - return retval; - } else { - return ERROR_OK; - } -} - -static int cortex_a_wait_dscr_bits(struct target *target, uint32_t mask, - uint32_t value, uint32_t *dscr) -{ - /* Waits until the specified bit(s) of DSCR take on a specified value. */ - struct armv7a_common *armv7a = target_to_armv7a(target); - int64_t then = timeval_ms(); - int retval; - - while ((*dscr & mask) != value) { - retval = mem_ap_read_atomic_u32(armv7a->debug_ap, - armv7a->debug_base + CPUDBG_DSCR, dscr); - if (retval != ERROR_OK) - return retval; - if (timeval_ms() > then + 1000) { - LOG_ERROR("timeout waiting for DSCR bit change"); - return ERROR_FAIL; - } - } - return ERROR_OK; -} - -static int cortex_a_read_copro(struct target *target, uint32_t opcode, - uint32_t *data, uint32_t *dscr) -{ - int retval; - struct armv7a_common *armv7a = target_to_armv7a(target); - - /* Move from coprocessor to R0. */ - retval = cortex_a_exec_opcode(target, opcode, dscr); - if (retval != ERROR_OK) - return retval; - - /* Move from R0 to DTRTX. */ - retval = cortex_a_exec_opcode(target, ARMV4_5_MCR(14, 0, 0, 0, 5, 0), dscr); - if (retval != ERROR_OK) - return retval; - - /* Wait until DTRTX is full (according to ARMv7-A/-R architecture - * manual section C8.4.3, checking InstrCmpl_l is not sufficient; one - * must also check TXfull_l). Most of the time this will be free - * because TXfull_l will be set immediately and cached in dscr. */ - retval = cortex_a_wait_dscr_bits(target, DSCR_DTRTX_FULL_LATCHED, - DSCR_DTRTX_FULL_LATCHED, dscr); - if (retval != ERROR_OK) - return retval; - - /* Read the value transferred to DTRTX. */ - retval = mem_ap_read_atomic_u32(armv7a->debug_ap, - armv7a->debug_base + CPUDBG_DTRTX, data); - if (retval != ERROR_OK) - return retval; - - return ERROR_OK; -} - -static int cortex_a_read_dfar_dfsr(struct target *target, uint32_t *dfar, - uint32_t *dfsr, uint32_t *dscr) -{ - int retval; - - if (dfar) { - retval = cortex_a_read_copro(target, ARMV4_5_MRC(15, 0, 0, 6, 0, 0), dfar, dscr); - if (retval != ERROR_OK) - return retval; - } - - if (dfsr) { - retval = cortex_a_read_copro(target, ARMV4_5_MRC(15, 0, 0, 5, 0, 0), dfsr, dscr); - if (retval != ERROR_OK) - return retval; - } - - return ERROR_OK; -} - -static int cortex_a_write_copro(struct target *target, uint32_t opcode, - uint32_t data, uint32_t *dscr) -{ - int retval; - struct armv7a_common *armv7a = target_to_armv7a(target); - - /* Write the value into DTRRX. */ - retval = mem_ap_write_atomic_u32(armv7a->debug_ap, - armv7a->debug_base + CPUDBG_DTRRX, data); - if (retval != ERROR_OK) - return retval; - - /* Move from DTRRX to R0. */ - retval = cortex_a_exec_opcode(target, ARMV4_5_MRC(14, 0, 0, 0, 5, 0), dscr); - if (retval != ERROR_OK) - return retval; - - /* Move from R0 to coprocessor. */ - retval = cortex_a_exec_opcode(target, opcode, dscr); - if (retval != ERROR_OK) - return retval; - - /* 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. */ - retval = cortex_a_wait_dscr_bits(target, DSCR_DTRRX_FULL_LATCHED, 0, dscr); - if (retval != ERROR_OK) - return retval; - - return ERROR_OK; -} - -static int cortex_a_write_dfar_dfsr(struct target *target, uint32_t dfar, - uint32_t dfsr, uint32_t *dscr) -{ - int retval; - - retval = cortex_a_write_copro(target, ARMV4_5_MCR(15, 0, 0, 6, 0, 0), dfar, dscr); - if (retval != ERROR_OK) - return retval; - - retval = cortex_a_write_copro(target, ARMV4_5_MCR(15, 0, 0, 5, 0, 0), dfsr, dscr); - if (retval != ERROR_OK) - return retval; - - return ERROR_OK; -} - -static int cortex_a_dfsr_to_error_code(uint32_t dfsr) -{ - uint32_t status, upper4; - - if (dfsr & (1 << 9)) { - /* LPAE format. */ - status = dfsr & 0x3f; - upper4 = status >> 2; - if (upper4 == 1 || upper4 == 2 || upper4 == 3 || upper4 == 15) - return ERROR_TARGET_TRANSLATION_FAULT; - else if (status == 33) - return ERROR_TARGET_UNALIGNED_ACCESS; - else - return ERROR_TARGET_DATA_ABORT; - } else { - /* Normal format. */ - status = ((dfsr >> 6) & 0x10) | (dfsr & 0xf); - if (status == 1) - return ERROR_TARGET_UNALIGNED_ACCESS; - else if (status == 5 || status == 7 || status == 3 || status == 6 || - status == 9 || status == 11 || status == 13 || status == 15) - return ERROR_TARGET_TRANSLATION_FAULT; - else - return ERROR_TARGET_DATA_ABORT; - } -} - -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_cpu_memory_fast should be - * preferred. - * Preconditions: - * - Address is in R0. - * - R0 is marked dirty. - */ - struct armv7a_common *armv7a = target_to_armv7a(target); - struct arm *arm = &armv7a->arm; - int retval; - - /* Mark register R1 as dirty, to use for transferring data. */ - arm_reg_current(arm, 1)->dirty = true; - - /* Switch to non-blocking mode if not already in that mode. */ - retval = cortex_a_set_dcc_mode(target, DSCR_EXT_DCC_NON_BLOCKING, dscr); - if (retval != ERROR_OK) - return retval; - - /* Go through the objects. */ - while (count) { - /* Write the value to store into DTRRX. */ - uint32_t data, opcode; - if (size == 1) - data = *buffer; - else if (size == 2) - data = target_buffer_get_u16(target, buffer); - else - data = target_buffer_get_u32(target, buffer); - retval = mem_ap_write_atomic_u32(armv7a->debug_ap, - armv7a->debug_base + CPUDBG_DTRRX, data); - if (retval != ERROR_OK) - return retval; - - /* Transfer the value from DTRRX to R1. */ - retval = cortex_a_exec_opcode(target, ARMV4_5_MRC(14, 0, 1, 0, 5, 0), dscr); - if (retval != ERROR_OK) - return retval; - - /* Write the value transferred to R1 into memory. */ - if (size == 1) - opcode = ARMV4_5_STRB_IP(1, 0); - else if (size == 2) - opcode = ARMV4_5_STRH_IP(1, 0); - else - opcode = ARMV4_5_STRW_IP(1, 0); - retval = cortex_a_exec_opcode(target, opcode, dscr); - if (retval != ERROR_OK) - return retval; - - /* Check for faults and return early. */ - if (*dscr & (DSCR_STICKY_ABORT_PRECISE | DSCR_STICKY_ABORT_IMPRECISE)) - return ERROR_OK; /* A data fault is not considered a system failure. */ - - /* 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. */ - retval = cortex_a_wait_dscr_bits(target, DSCR_DTRRX_FULL_LATCHED, 0, dscr); - if (retval != ERROR_OK) - return retval; - - /* Advance. */ - buffer += size; - --count; - } - - return ERROR_OK; -} - -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 - * in *dscr; updated to new value. This is fast but only works for - * word-sized objects at aligned addresses. - * Preconditions: - * - Address is in R0 and must be a multiple of 4. - * - R0 is marked dirty. - */ - struct armv7a_common *armv7a = target_to_armv7a(target); - int retval; - - /* Switch to fast mode if not already in that mode. */ - retval = cortex_a_set_dcc_mode(target, DSCR_EXT_DCC_FAST_MODE, dscr); - if (retval != ERROR_OK) - return retval; - - /* Latch STC instruction. */ - retval = mem_ap_write_atomic_u32(armv7a->debug_ap, - armv7a->debug_base + CPUDBG_ITR, ARMV4_5_STC(0, 1, 0, 1, 14, 5, 0, 4)); - if (retval != ERROR_OK) - return retval; - - /* Transfer all the data and issue all the instructions. */ - return mem_ap_write_buf_noincr(armv7a->debug_ap, buffer, - 4, count, armv7a->debug_base + CPUDBG_DTRRX); -} - -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 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 CPU memory address 0x%" PRIx32 " size %" PRIu32 " count %" PRIu32, - address, size, count); - if (target->state != TARGET_HALTED) { - LOG_WARNING("target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - if (!count) - return ERROR_OK; - - /* Clear any abort. */ - retval = mem_ap_write_atomic_u32(armv7a->debug_ap, - armv7a->debug_base + CPUDBG_DRCR, DRCR_CLEAR_EXCEPTIONS); - if (retval != ERROR_OK) - return retval; - - /* Read DSCR. */ - retval = mem_ap_read_atomic_u32(armv7a->debug_ap, - armv7a->debug_base + CPUDBG_DSCR, &dscr); - if (retval != ERROR_OK) - return retval; - - /* Switch to non-blocking mode if not already in that mode. */ - retval = cortex_a_set_dcc_mode(target, DSCR_EXT_DCC_NON_BLOCKING, &dscr); - if (retval != ERROR_OK) - goto out; - - /* Mark R0 as dirty. */ - arm_reg_current(arm, 0)->dirty = true; - - /* Read DFAR and DFSR, as they will be modified in the event of a fault. */ - retval = cortex_a_read_dfar_dfsr(target, &orig_dfar, &orig_dfsr, &dscr); - if (retval != ERROR_OK) - goto out; - - /* Get the memory address into R0. */ - retval = mem_ap_write_atomic_u32(armv7a->debug_ap, - armv7a->debug_base + CPUDBG_DTRRX, address); - if (retval != ERROR_OK) - goto out; - retval = cortex_a_exec_opcode(target, ARMV4_5_MRC(14, 0, 0, 0, 5, 0), &dscr); - if (retval != ERROR_OK) - goto out; - - if (size == 4 && (address % 4) == 0) { - /* We are doing a word-aligned transfer, so use fast mode. */ - retval = cortex_a_write_cpu_memory_fast(target, count, buffer, &dscr); - } else { - /* Use slow path. */ - retval = cortex_a_write_cpu_memory_slow(target, size, count, buffer, &dscr); - } - -out: - final_retval = retval; - - /* Switch to non-blocking mode if not already in that mode. */ - retval = cortex_a_set_dcc_mode(target, DSCR_EXT_DCC_NON_BLOCKING, &dscr); - if (final_retval == ERROR_OK) - final_retval = retval; - - /* Wait for last issued instruction to complete. */ - retval = cortex_a_wait_instrcmpl(target, &dscr, true); - if (final_retval == ERROR_OK) - final_retval = retval; - - /* 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 - * if there is fault, because then the instruction might not have completed - * successfully. */ - if (!(dscr & DSCR_STICKY_ABORT_PRECISE)) { - retval = cortex_a_wait_dscr_bits(target, DSCR_DTRRX_FULL_LATCHED, 0, &dscr); - if (retval != ERROR_OK) - return retval; - } - - /* If there were any sticky abort flags, clear them. */ - if (dscr & (DSCR_STICKY_ABORT_PRECISE | DSCR_STICKY_ABORT_IMPRECISE)) { - fault_dscr = dscr; - mem_ap_write_atomic_u32(armv7a->debug_ap, - armv7a->debug_base + CPUDBG_DRCR, DRCR_CLEAR_EXCEPTIONS); - dscr &= ~(DSCR_STICKY_ABORT_PRECISE | DSCR_STICKY_ABORT_IMPRECISE); - } else { - fault_dscr = 0; - } - - /* Handle synchronous data faults. */ - if (fault_dscr & DSCR_STICKY_ABORT_PRECISE) { - if (final_retval == ERROR_OK) { - /* Final return value will reflect cause of fault. */ - retval = cortex_a_read_dfar_dfsr(target, &fault_dfar, &fault_dfsr, &dscr); - if (retval == ERROR_OK) { - LOG_ERROR("data abort at 0x%08" PRIx32 ", dfsr = 0x%08" PRIx32, fault_dfar, fault_dfsr); - final_retval = cortex_a_dfsr_to_error_code(fault_dfsr); - } else - final_retval = retval; - } - /* Fault destroyed DFAR/DFSR; restore them. */ - retval = cortex_a_write_dfar_dfsr(target, orig_dfar, orig_dfsr, &dscr); - if (retval != ERROR_OK) - LOG_ERROR("error restoring dfar/dfsr - dscr = 0x%08" PRIx32, dscr); - } - - /* Handle asynchronous data faults. */ - if (fault_dscr & DSCR_STICKY_ABORT_IMPRECISE) { - if (final_retval == ERROR_OK) - /* No other error has been recorded so far, so keep this one. */ - final_retval = ERROR_TARGET_DATA_ABORT; - } - - /* If the DCC is nonempty, clear it. */ - if (dscr & DSCR_DTRTX_FULL_LATCHED) { - uint32_t dummy; - retval = mem_ap_read_atomic_u32(armv7a->debug_ap, - armv7a->debug_base + CPUDBG_DTRTX, &dummy); - if (final_retval == ERROR_OK) - final_retval = retval; - } - if (dscr & DSCR_DTRRX_FULL_LATCHED) { - retval = cortex_a_exec_opcode(target, ARMV4_5_MRC(14, 0, 1, 0, 5, 0), &dscr); - if (final_retval == ERROR_OK) - final_retval = retval; - } - - /* Done. */ - return final_retval; -} - -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_cpu_memory_fast should be - * preferred. - * Preconditions: - * - Address is in R0. - * - R0 is marked dirty. - */ - struct armv7a_common *armv7a = target_to_armv7a(target); - struct arm *arm = &armv7a->arm; - int retval; - - /* Mark register R1 as dirty, to use for transferring data. */ - arm_reg_current(arm, 1)->dirty = true; - - /* Switch to non-blocking mode if not already in that mode. */ - retval = cortex_a_set_dcc_mode(target, DSCR_EXT_DCC_NON_BLOCKING, dscr); - if (retval != ERROR_OK) - return retval; - - /* Go through the objects. */ - while (count) { - /* Issue a load of the appropriate size to R1. */ - uint32_t opcode, data; - if (size == 1) - opcode = ARMV4_5_LDRB_IP(1, 0); - else if (size == 2) - opcode = ARMV4_5_LDRH_IP(1, 0); - else - opcode = ARMV4_5_LDRW_IP(1, 0); - retval = cortex_a_exec_opcode(target, opcode, dscr); - if (retval != ERROR_OK) - return retval; - - /* Issue a write of R1 to DTRTX. */ - retval = cortex_a_exec_opcode(target, ARMV4_5_MCR(14, 0, 1, 0, 5, 0), dscr); - if (retval != ERROR_OK) - return retval; - - /* Check for faults and return early. */ - if (*dscr & (DSCR_STICKY_ABORT_PRECISE | DSCR_STICKY_ABORT_IMPRECISE)) - return ERROR_OK; /* A data fault is not considered a system failure. */ - - /* Wait until DTRTX is full (according to ARMv7-A/-R architecture - * manual section C8.4.3, checking InstrCmpl_l is not sufficient; one - * must also check TXfull_l). Most of the time this will be free - * because TXfull_l will be set immediately and cached in dscr. */ - retval = cortex_a_wait_dscr_bits(target, DSCR_DTRTX_FULL_LATCHED, - DSCR_DTRTX_FULL_LATCHED, dscr); - if (retval != ERROR_OK) - return retval; - - /* Read the value transferred to DTRTX into the buffer. */ - retval = mem_ap_read_atomic_u32(armv7a->debug_ap, - armv7a->debug_base + CPUDBG_DTRTX, &data); - if (retval != ERROR_OK) - return retval; - if (size == 1) - *buffer = (uint8_t) data; - else if (size == 2) - target_buffer_set_u16(target, buffer, (uint16_t) data); - else - target_buffer_set_u32(target, buffer, data); - - /* Advance. */ - buffer += size; - --count; - } - - return ERROR_OK; -} - -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 - * *dscr; updated to new value. This is fast but only works for word-sized - * objects at aligned addresses. - * Preconditions: - * - Address is in R0 and must be a multiple of 4. - * - R0 is marked dirty. - */ - struct armv7a_common *armv7a = target_to_armv7a(target); - uint32_t u32; - int retval; - - /* Switch to non-blocking mode if not already in that mode. */ - retval = cortex_a_set_dcc_mode(target, DSCR_EXT_DCC_NON_BLOCKING, dscr); - if (retval != ERROR_OK) - return retval; - - /* Issue the LDC instruction via a write to ITR. */ - retval = cortex_a_exec_opcode(target, ARMV4_5_LDC(0, 1, 0, 1, 14, 5, 0, 4), dscr); - if (retval != ERROR_OK) - return retval; - - count--; - - if (count > 0) { - /* Switch to fast mode if not already in that mode. */ - retval = cortex_a_set_dcc_mode(target, DSCR_EXT_DCC_FAST_MODE, dscr); - if (retval != ERROR_OK) - return retval; - - /* Latch LDC instruction. */ - retval = mem_ap_write_atomic_u32(armv7a->debug_ap, - armv7a->debug_base + CPUDBG_ITR, ARMV4_5_LDC(0, 1, 0, 1, 14, 5, 0, 4)); - if (retval != ERROR_OK) - return retval; - - /* Read the value transferred to DTRTX into the buffer. Due to fast - * mode rules, this blocks until the instruction finishes executing and - * then reissues the read instruction to read the next word from - * memory. The last read of DTRTX in this call reads the second-to-last - * word from memory and issues the read instruction for the last word. - */ - retval = mem_ap_read_buf_noincr(armv7a->debug_ap, buffer, - 4, count, armv7a->debug_base + CPUDBG_DTRTX); - if (retval != ERROR_OK) - return retval; - - /* Advance. */ - buffer += count * 4; - } - - /* Wait for last issued instruction to complete. */ - retval = cortex_a_wait_instrcmpl(target, dscr, false); - if (retval != ERROR_OK) - return retval; - - /* Switch to non-blocking mode if not already in that mode. */ - retval = cortex_a_set_dcc_mode(target, DSCR_EXT_DCC_NON_BLOCKING, dscr); - if (retval != ERROR_OK) - return retval; - - /* Check for faults and return early. */ - if (*dscr & (DSCR_STICKY_ABORT_PRECISE | DSCR_STICKY_ABORT_IMPRECISE)) - return ERROR_OK; /* A data fault is not considered a system failure. */ - - /* Wait until DTRTX is full (according to ARMv7-A/-R architecture manual - * section C8.4.3, checking InstrCmpl_l is not sufficient; one must also - * check TXfull_l). Most of the time this will be free because TXfull_l - * will be set immediately and cached in dscr. */ - retval = cortex_a_wait_dscr_bits(target, DSCR_DTRTX_FULL_LATCHED, - DSCR_DTRTX_FULL_LATCHED, dscr); - if (retval != ERROR_OK) - return retval; - - /* Read the value transferred to DTRTX into the buffer. This is the last - * word. */ - retval = mem_ap_read_atomic_u32(armv7a->debug_ap, - armv7a->debug_base + CPUDBG_DTRTX, &u32); - if (retval != ERROR_OK) - return retval; - target_buffer_set_u32(target, buffer, u32); - - return ERROR_OK; -} - -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 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 CPU memory address 0x%" PRIx32 " size %" PRIu32 " count %" PRIu32, - address, size, count); - if (target->state != TARGET_HALTED) { - LOG_WARNING("target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - if (!count) - return ERROR_OK; - - /* Clear any abort. */ - retval = mem_ap_write_atomic_u32(armv7a->debug_ap, - armv7a->debug_base + CPUDBG_DRCR, DRCR_CLEAR_EXCEPTIONS); - if (retval != ERROR_OK) - return retval; - - /* Read DSCR */ - retval = mem_ap_read_atomic_u32(armv7a->debug_ap, - armv7a->debug_base + CPUDBG_DSCR, &dscr); - if (retval != ERROR_OK) - return retval; - - /* Switch to non-blocking mode if not already in that mode. */ - retval = cortex_a_set_dcc_mode(target, DSCR_EXT_DCC_NON_BLOCKING, &dscr); - if (retval != ERROR_OK) - goto out; - - /* Mark R0 as dirty. */ - arm_reg_current(arm, 0)->dirty = true; - - /* Read DFAR and DFSR, as they will be modified in the event of a fault. */ - retval = cortex_a_read_dfar_dfsr(target, &orig_dfar, &orig_dfsr, &dscr); - if (retval != ERROR_OK) - goto out; - - /* Get the memory address into R0. */ - retval = mem_ap_write_atomic_u32(armv7a->debug_ap, - armv7a->debug_base + CPUDBG_DTRRX, address); - if (retval != ERROR_OK) - goto out; - retval = cortex_a_exec_opcode(target, ARMV4_5_MRC(14, 0, 0, 0, 5, 0), &dscr); - if (retval != ERROR_OK) - goto out; - - if (size == 4 && (address % 4) == 0) { - /* We are doing a word-aligned transfer, so use fast mode. */ - retval = cortex_a_read_cpu_memory_fast(target, count, buffer, &dscr); - } else { - /* Use slow path. */ - retval = cortex_a_read_cpu_memory_slow(target, size, count, buffer, &dscr); - } - -out: - final_retval = retval; - - /* Switch to non-blocking mode if not already in that mode. */ - retval = cortex_a_set_dcc_mode(target, DSCR_EXT_DCC_NON_BLOCKING, &dscr); - if (final_retval == ERROR_OK) - final_retval = retval; - - /* Wait for last issued instruction to complete. */ - retval = cortex_a_wait_instrcmpl(target, &dscr, true); - if (final_retval == ERROR_OK) - final_retval = retval; - - /* If there were any sticky abort flags, clear them. */ - if (dscr & (DSCR_STICKY_ABORT_PRECISE | DSCR_STICKY_ABORT_IMPRECISE)) { - fault_dscr = dscr; - mem_ap_write_atomic_u32(armv7a->debug_ap, - armv7a->debug_base + CPUDBG_DRCR, DRCR_CLEAR_EXCEPTIONS); - dscr &= ~(DSCR_STICKY_ABORT_PRECISE | DSCR_STICKY_ABORT_IMPRECISE); - } else { - fault_dscr = 0; - } - - /* Handle synchronous data faults. */ - if (fault_dscr & DSCR_STICKY_ABORT_PRECISE) { - if (final_retval == ERROR_OK) { - /* Final return value will reflect cause of fault. */ - retval = cortex_a_read_dfar_dfsr(target, &fault_dfar, &fault_dfsr, &dscr); - if (retval == ERROR_OK) { - LOG_ERROR("data abort at 0x%08" PRIx32 ", dfsr = 0x%08" PRIx32, fault_dfar, fault_dfsr); - final_retval = cortex_a_dfsr_to_error_code(fault_dfsr); - } else - final_retval = retval; - } - /* Fault destroyed DFAR/DFSR; restore them. */ - retval = cortex_a_write_dfar_dfsr(target, orig_dfar, orig_dfsr, &dscr); - if (retval != ERROR_OK) - LOG_ERROR("error restoring dfar/dfsr - dscr = 0x%08" PRIx32, dscr); - } - - /* Handle asynchronous data faults. */ - if (fault_dscr & DSCR_STICKY_ABORT_IMPRECISE) { - if (final_retval == ERROR_OK) - /* No other error has been recorded so far, so keep this one. */ - final_retval = ERROR_TARGET_DATA_ABORT; - } - - /* If the DCC is nonempty, clear it. */ - if (dscr & DSCR_DTRTX_FULL_LATCHED) { - uint32_t dummy; - retval = mem_ap_read_atomic_u32(armv7a->debug_ap, - armv7a->debug_base + CPUDBG_DTRTX, &dummy); - if (final_retval == ERROR_OK) - final_retval = retval; - } - if (dscr & DSCR_DTRRX_FULL_LATCHED) { - retval = cortex_a_exec_opcode(target, ARMV4_5_MRC(14, 0, 1, 0, 5, 0), &dscr); - if (final_retval == ERROR_OK) - final_retval = retval; - } - - /* Done. */ - return final_retval; -} - - -/* - * Cortex-A Memory access - * - * 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, - uint32_t count, uint8_t *buffer) -{ - 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("Reading memory at real address 0x%" PRIx32 "; size %" PRId32 "; count %" PRId32, - address, size, count); - - 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, - 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); - - cortex_a_prep_memaccess(target, 0); - 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, - uint32_t size, uint32_t count, uint8_t *buffer) -{ - int mmu_enabled = 0; - uint32_t virt, phys; - int retval; - struct armv7a_common *armv7a = target_to_armv7a(target); - struct adiv5_dap *swjdp = armv7a->arm.dap; - uint8_t apsel = swjdp->apsel; - - if (!armv7a->memory_ap_available || (apsel != armv7a->memory_ap->ap_num)) - 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); - - /* determine if MMU was enabled on target stop */ - if (!armv7a->is_armv7r) { - retval = cortex_a_mmu(target, &mmu_enabled); - if (retval != ERROR_OK) - return retval; - } - - if (mmu_enabled) { - virt = address; - retval = cortex_a_virt2phys(target, virt, &phys); - if (retval != ERROR_OK) - return retval; - - LOG_DEBUG("Reading at virtual address. Translating v:0x%" PRIx32 " to r:0x%" PRIx32, - virt, phys); - address = phys; - } - - if (!count || !buffer) - return ERROR_COMMAND_SYNTAX_ERROR; - - retval = mem_ap_read_buf(armv7a->memory_ap, buffer, size, count, address); - - return retval; -} - -static int cortex_a_write_phys_memory(struct target *target, - uint32_t address, uint32_t size, - uint32_t count, const uint8_t *buffer) -{ - 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); - - 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, - 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); - - /* 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_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, - uint32_t size, uint32_t count, const uint8_t *buffer) -{ - int mmu_enabled = 0; - uint32_t virt, phys; - int retval; - struct armv7a_common *armv7a = target_to_armv7a(target); - struct adiv5_dap *swjdp = armv7a->arm.dap; - uint8_t apsel = swjdp->apsel; - - if (!armv7a->memory_ap_available || (apsel != armv7a->memory_ap->ap_num)) - 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); - - /* determine if MMU was enabled on target stop */ - if (!armv7a->is_armv7r) { - retval = cortex_a_mmu(target, &mmu_enabled); - if (retval != ERROR_OK) - return retval; - } - - if (mmu_enabled) { - virt = address; - retval = cortex_a_virt2phys(target, virt, &phys); - if (retval != ERROR_OK) - return retval; - - LOG_DEBUG("Writing to virtual address. Translating v:0x%" PRIx32 " to r:0x%" PRIx32, - virt, - phys); - address = phys; - } - - if (!count || !buffer) - return ERROR_COMMAND_SYNTAX_ERROR; - - retval = mem_ap_write_buf(armv7a->memory_ap, buffer, size, count, address); - - return retval; -} - -static int cortex_a_read_buffer(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 = cortex_a_read_memory_ahb(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 = cortex_a_read_memory_ahb(target, address, size, aligned / size, buffer); - if (retval != ERROR_OK) - return retval; - address += aligned; - count -= aligned; - buffer += aligned; - } - } - - return ERROR_OK; -} - -static int cortex_a_write_buffer(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 = cortex_a_write_memory_ahb(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 = cortex_a_write_memory_ahb(target, address, size, aligned / size, buffer); - if (retval != ERROR_OK) - return retval; - address += aligned; - count -= aligned; - buffer += aligned; - } - } - - return ERROR_OK; -} - -static int cortex_a_handle_target_request(void *priv) -{ - struct target *target = priv; - struct armv7a_common *armv7a = target_to_armv7a(target); - int retval; - - if (!target_was_examined(target)) - return ERROR_OK; - if (!target->dbg_msg_enabled) - return ERROR_OK; - - if (target->state == TARGET_RUNNING) { - uint32_t request; - uint32_t dscr; - retval = mem_ap_read_atomic_u32(armv7a->debug_ap, - 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); - if (retval == ERROR_OK) { - target_request(target, request); - 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; - } - } - } - - return ERROR_OK; -} - -/* - * Cortex-A target information and configuration - */ - -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; - - retval = dap_dp_init(swjdp); - if (retval != ERROR_OK) { - LOG_ERROR("Could not initialize the debug port"); - return retval; - } - - /* 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"); - return retval; - } - - retval = mem_ap_init(armv7a->debug_ap); - if (retval != ERROR_OK) { - LOG_ERROR("Could not initialize the APB-AP"); - return retval; - } - - armv7a->debug_ap->memaccess_tck = 80; - - /* Search for the AHB-AB. - * REVISIT: We should search for AXI-AP as well and make sure the AP's MEMTYPE says it - * can access system memory. */ - armv7a->memory_ap_available = false; - retval = dap_find_ap(swjdp, AP_TYPE_AHB_AP, &armv7a->memory_ap); - if (retval == ERROR_OK) { - retval = mem_ap_init(armv7a->memory_ap); - if (retval == ERROR_OK) - armv7a->memory_ap_available = true; - } - 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) { - uint32_t dbgbase; - /* Get ROM Table base */ - uint32_t apid; - int32_t coreidx = target->coreid; - LOG_DEBUG("%s's dbgbase is not set, trying to detect using the ROM table", - target->cmd_name); - retval = dap_get_debugbase(armv7a->debug_ap, &dbgbase, &apid); - if (retval != ERROR_OK) - return retval; - /* Lookup 0x15 -- Processor DAP */ - retval = dap_lookup_cs_component(armv7a->debug_ap, dbgbase, 0x15, - &armv7a->debug_base, &coreidx); - if (retval != ERROR_OK) { - LOG_ERROR("Can't detect %s's dbgbase from the ROM table; you need to specify it explicitly.", - target->cmd_name); - return retval; - } - LOG_DEBUG("Detected core %" PRId32 " dbgbase: %08" PRIx32, - target->coreid, armv7a->debug_base); - } else - 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); - if (retval != ERROR_OK) { - LOG_DEBUG("Examine %s failed", "TTYPR"); - return retval; - } - - retval = mem_ap_read_atomic_u32(armv7a->debug_ap, - armv7a->debug_base + CPUDBG_DIDR, &didr); - if (retval != ERROR_OK) { - LOG_DEBUG("Examine %s failed", "DIDR"); - 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); - - cortex_a->cpuid = cpuid; - cortex_a->ctypr = ctypr; - cortex_a->ttypr = ttypr; - cortex_a->didr = didr; - - /* 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; - - } - /* 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; - - } - 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); - - armv7a->arm.core_type = ARM_MODE_MON; - - /* Avoid recreating the registers cache */ - if (!target_was_examined(target)) { - retval = cortex_a_dpm_setup(cortex_a, didr); - if (retval != ERROR_OK) - return retval; - } - - /* Setup Breakpoint Register Pairs */ - cortex_a->brp_num = ((didr >> 24) & 0x0F) + 1; - cortex_a->brp_num_context = ((didr >> 20) & 0x0F) + 1; - cortex_a->brp_num_available = cortex_a->brp_num; - free(cortex_a->brp_list); - cortex_a->brp_list = calloc(cortex_a->brp_num, sizeof(struct cortex_a_brp)); -/* cortex_a->brb_enabled = ????; */ - for (i = 0; i < cortex_a->brp_num; i++) { - cortex_a->brp_list[i].used = 0; - if (i < (cortex_a->brp_num-cortex_a->brp_num_context)) - cortex_a->brp_list[i].type = BRP_NORMAL; - else - cortex_a->brp_list[i].type = BRP_CONTEXT; - cortex_a->brp_list[i].value = 0; - cortex_a->brp_list[i].control = 0; - cortex_a->brp_list[i].BRPn = i; - } - - LOG_DEBUG("Configured %i hw breakpoints", cortex_a->brp_num); - - /* select debug_ap as default */ - swjdp->apsel = armv7a->debug_ap->ap_num; - - target_set_examined(target); - return ERROR_OK; -} - -static int cortex_a_examine(struct target *target) -{ - int retval = ERROR_OK; - - /* Reestablish communication after target reset */ - retval = cortex_a_examine_first(target); - - /* Configure core debug access */ - if (retval == ERROR_OK) - retval = cortex_a_init_debug_access(target); - - return retval; -} - -/* - * Cortex-A target creation and initialization - */ - -static int cortex_a_init_target(struct command_context *cmd_ctx, - struct target *target) -{ - /* examine_first() does a bunch of this */ - return ERROR_OK; -} - -static int cortex_a_init_arch_info(struct target *target, - struct cortex_a_common *cortex_a, struct jtag_tap *tap) -{ - struct armv7a_common *armv7a = &cortex_a->armv7a_common; - - /* Setup struct cortex_a_common */ - cortex_a->common_magic = CORTEX_A_COMMON_MAGIC; - - /* tap has no dap initialized */ - if (!tap->dap) { - tap->dap = dap_init(); - - /* Leave (only) generic DAP stuff for debugport_init() */ - tap->dap->tap = tap; - } - - armv7a->arm.dap = tap->dap; - - cortex_a->fast_reg_read = 0; - - /* register arch-specific functions */ - armv7a->examine_debug_reason = NULL; - - armv7a->post_debug_entry = cortex_a_post_debug_entry; - - armv7a->pre_restore_context = NULL; - - armv7a->armv7a_mmu.read_physical_memory = cortex_a_read_phys_memory; - - -/* arm7_9->handle_target_request = cortex_a_handle_target_request; */ - - /* REVISIT v7a setup should be in a v7a-specific routine */ - armv7a_init_arch_info(target, armv7a); - target_register_timer_callback(cortex_a_handle_target_request, 1, 1, target); - - return ERROR_OK; -} - -static int cortex_a_target_create(struct target *target, Jim_Interp *interp) -{ - struct cortex_a_common *cortex_a = calloc(1, sizeof(struct cortex_a_common)); - - cortex_a->armv7a_common.is_armv7r = false; - - return cortex_a_init_arch_info(target, cortex_a, target->tap); -} - -static int cortex_r4_target_create(struct target *target, Jim_Interp *interp) -{ - struct cortex_a_common *cortex_a = calloc(1, sizeof(struct cortex_a_common)); - - cortex_a->armv7a_common.is_armv7r = true; - - return cortex_a_init_arch_info(target, cortex_a, target->tap); -} - -static void cortex_a_deinit_target(struct target *target) -{ - struct cortex_a_common *cortex_a = target_to_cortex_a(target); - struct arm_dpm *dpm = &cortex_a->armv7a_common.dpm; - - free(cortex_a->brp_list); - free(dpm->dbp); - free(dpm->dwp); - free(cortex_a); -} - -static int cortex_a_mmu(struct target *target, int *enabled) -{ - struct armv7a_common *armv7a = target_to_armv7a(target); - - if (target->state != TARGET_HALTED) { - LOG_ERROR("%s: target not halted", __func__); - return ERROR_TARGET_INVALID; - } - - if (armv7a->is_armv7r) - *enabled = 0; - else - *enabled = target_to_cortex_a(target)->armv7a_common.armv7a_mmu.mmu_enabled; - - return ERROR_OK; -} - -static int cortex_a_virt2phys(struct target *target, - uint32_t virt, uint32_t *phys) -{ - int retval = ERROR_FAIL; - struct armv7a_common *armv7a = target_to_armv7a(target); - struct adiv5_dap *swjdp = armv7a->arm.dap; - uint8_t apsel = swjdp->apsel; - if (armv7a->memory_ap_available && (apsel == armv7a->memory_ap->ap_num)) { - uint32_t ret; - retval = armv7a_mmu_translate_va(target, - virt, &ret); - if (retval != ERROR_OK) - goto done; - *phys = ret; - } else {/* use this method if armv7a->memory_ap not selected - * mmu must be enable in order to get a correct translation */ - retval = cortex_a_mmu_modify(target, 1); - if (retval != ERROR_OK) - goto done; - retval = armv7a_mmu_translate_va_pa(target, virt, phys, 1); - } -done: - return retval; -} - -COMMAND_HANDLER(cortex_a_handle_cache_info_command) -{ - struct target *target = get_current_target(CMD_CTX); - struct armv7a_common *armv7a = target_to_armv7a(target); - - return armv7a_handle_cache_info_command(CMD_CTX, - &armv7a->armv7a_mmu.armv7a_cache); -} - - -COMMAND_HANDLER(cortex_a_handle_dbginit_command) -{ - struct target *target = get_current_target(CMD_CTX); - if (!target_was_examined(target)) { - LOG_ERROR("target not examined yet"); - return ERROR_FAIL; - } - - return cortex_a_init_debug_access(target); -} -COMMAND_HANDLER(cortex_a_handle_smp_off_command) -{ - struct target *target = get_current_target(CMD_CTX); - /* check target is an smp target */ - struct target_list *head; - struct target *curr; - head = target->head; - target->smp = 0; - if (head != (struct target_list *)NULL) { - while (head != (struct target_list *)NULL) { - curr = head->target; - curr->smp = 0; - head = head->next; - } - /* fixes the target display to the debugger */ - target->gdb_service->target = target; - } - return ERROR_OK; -} - -COMMAND_HANDLER(cortex_a_handle_smp_on_command) -{ - struct target *target = get_current_target(CMD_CTX); - struct target_list *head; - struct target *curr; - head = target->head; - if (head != (struct target_list *)NULL) { - target->smp = 1; - while (head != (struct target_list *)NULL) { - curr = head->target; - curr->smp = 1; - head = head->next; - } - } - return ERROR_OK; -} - -COMMAND_HANDLER(cortex_a_handle_smp_gdb_command) -{ - struct target *target = get_current_target(CMD_CTX); - int retval = ERROR_OK; - struct target_list *head; - head = target->head; - if (head != (struct target_list *)NULL) { - if (CMD_ARGC == 1) { - int coreid = 0; - COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], coreid); - if (ERROR_OK != retval) - return retval; - target->gdb_service->core[1] = coreid; - - } - command_print(CMD_CTX, "gdb coreid %" PRId32 " -> %" PRId32, target->gdb_service->core[0] - , target->gdb_service->core[1]); - } - return ERROR_OK; -} - -COMMAND_HANDLER(handle_cortex_a_mask_interrupts_command) -{ - struct target *target = get_current_target(CMD_CTX); - struct cortex_a_common *cortex_a = target_to_cortex_a(target); - - static const Jim_Nvp nvp_maskisr_modes[] = { - { .name = "off", .value = CORTEX_A_ISRMASK_OFF }, - { .name = "on", .value = CORTEX_A_ISRMASK_ON }, - { .name = NULL, .value = -1 }, - }; - const Jim_Nvp *n; - - if (CMD_ARGC > 0) { - n = Jim_Nvp_name2value_simple(nvp_maskisr_modes, CMD_ARGV[0]); - 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; - } - - n = Jim_Nvp_value2name_simple(nvp_maskisr_modes, cortex_a->isrmasking_mode); - command_print(CMD_CTX, "cortex_a interrupt mask %s", n->name); - - return ERROR_OK; -} - -COMMAND_HANDLER(handle_cortex_a_dacrfixup_command) -{ - struct target *target = get_current_target(CMD_CTX); - struct cortex_a_common *cortex_a = target_to_cortex_a(target); - - static const Jim_Nvp nvp_dacrfixup_modes[] = { - { .name = "off", .value = CORTEX_A_DACRFIXUP_OFF }, - { .name = "on", .value = CORTEX_A_DACRFIXUP_ON }, - { .name = NULL, .value = -1 }, - }; - const Jim_Nvp *n; - - if (CMD_ARGC > 0) { - n = Jim_Nvp_name2value_simple(nvp_dacrfixup_modes, CMD_ARGV[0]); - if (n->name == NULL) - return ERROR_COMMAND_SYNTAX_ERROR; - cortex_a->dacrfixup_mode = n->value; - - } - - n = Jim_Nvp_value2name_simple(nvp_dacrfixup_modes, cortex_a->dacrfixup_mode); - command_print(CMD_CTX, "cortex_a domain access control fixup %s", n->name); - - return ERROR_OK; -} - -static const struct command_registration cortex_a_exec_command_handlers[] = { - { - .name = "cache_info", - .handler = cortex_a_handle_cache_info_command, - .mode = COMMAND_EXEC, - .help = "display information about target caches", - .usage = "", - }, - { - .name = "dbginit", - .handler = cortex_a_handle_dbginit_command, - .mode = COMMAND_EXEC, - .help = "Initialize core debug", - .usage = "", - }, - { .name = "smp_off", - .handler = cortex_a_handle_smp_off_command, - .mode = COMMAND_EXEC, - .help = "Stop smp handling", - .usage = "",}, - { - .name = "smp_on", - .handler = cortex_a_handle_smp_on_command, - .mode = COMMAND_EXEC, - .help = "Restart smp handling", - .usage = "", - }, - { - .name = "smp_gdb", - .handler = cortex_a_handle_smp_gdb_command, - .mode = COMMAND_EXEC, - .help = "display/fix current core played to gdb", - .usage = "", - }, - { - .name = "maskisr", - .handler = handle_cortex_a_mask_interrupts_command, - .mode = COMMAND_ANY, - .help = "mask cortex_a interrupts", - .usage = "['on'|'off']", - }, - { - .name = "dacrfixup", - .handler = handle_cortex_a_dacrfixup_command, - .mode = COMMAND_EXEC, - .help = "set domain access control (DACR) to all-manager " - "on memory access", - .usage = "['on'|'off']", - }, - - COMMAND_REGISTRATION_DONE -}; -static const struct command_registration cortex_a_command_handlers[] = { - { - .chain = arm_command_handlers, - }, - { - .chain = armv7a_command_handlers, - }, - { - .name = "cortex_a", - .mode = COMMAND_ANY, - .help = "Cortex-A command group", - .usage = "", - .chain = cortex_a_exec_command_handlers, - }, - COMMAND_REGISTRATION_DONE -}; - -struct target_type cortexa_target = { - .name = "cortex_a", - .deprecated_name = "cortex_a8", - - .poll = cortex_a_poll, - .arch_state = armv7a_arch_state, - - .halt = cortex_a_halt, - .resume = cortex_a_resume, - .step = cortex_a_step, - - .assert_reset = cortex_a_assert_reset, - .deassert_reset = cortex_a_deassert_reset, - - /* 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_buffer = cortex_a_read_buffer, - .write_buffer = cortex_a_write_buffer, - - .checksum_memory = arm_checksum_memory, - .blank_check_memory = arm_blank_check_memory, - - .run_algorithm = armv4_5_run_algorithm, - - .add_breakpoint = cortex_a_add_breakpoint, - .add_context_breakpoint = cortex_a_add_context_breakpoint, - .add_hybrid_breakpoint = cortex_a_add_hybrid_breakpoint, - .remove_breakpoint = cortex_a_remove_breakpoint, - .add_watchpoint = NULL, - .remove_watchpoint = NULL, - - .commands = cortex_a_command_handlers, - .target_create = cortex_a_target_create, - .init_target = cortex_a_init_target, - .examine = cortex_a_examine, - .deinit_target = cortex_a_deinit_target, - - .read_phys_memory = cortex_a_read_phys_memory, - .write_phys_memory = cortex_a_write_phys_memory, - .mmu = cortex_a_mmu, - .virt2phys = cortex_a_virt2phys, -}; - -static const struct command_registration cortex_r4_exec_command_handlers[] = { - { - .name = "cache_info", - .handler = cortex_a_handle_cache_info_command, - .mode = COMMAND_EXEC, - .help = "display information about target caches", - .usage = "", - }, - { - .name = "dbginit", - .handler = cortex_a_handle_dbginit_command, - .mode = COMMAND_EXEC, - .help = "Initialize core debug", - .usage = "", - }, - { - .name = "maskisr", - .handler = handle_cortex_a_mask_interrupts_command, - .mode = COMMAND_EXEC, - .help = "mask cortex_r4 interrupts", - .usage = "['on'|'off']", - }, - - COMMAND_REGISTRATION_DONE -}; -static const struct command_registration cortex_r4_command_handlers[] = { - { - .chain = arm_command_handlers, - }, - { - .chain = armv7a_command_handlers, - }, - { - .name = "cortex_r4", - .mode = COMMAND_ANY, - .help = "Cortex-R4 command group", - .usage = "", - .chain = cortex_r4_exec_command_handlers, - }, - COMMAND_REGISTRATION_DONE -}; - -struct target_type cortexr4_target = { - .name = "cortex_r4", - - .poll = cortex_a_poll, - .arch_state = armv7a_arch_state, - - .halt = cortex_a_halt, - .resume = cortex_a_resume, - .step = cortex_a_step, - - .assert_reset = cortex_a_assert_reset, - .deassert_reset = cortex_a_deassert_reset, - - /* 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, - - .checksum_memory = arm_checksum_memory, - .blank_check_memory = arm_blank_check_memory, - - .run_algorithm = armv4_5_run_algorithm, - - .add_breakpoint = cortex_a_add_breakpoint, - .add_context_breakpoint = cortex_a_add_context_breakpoint, - .add_hybrid_breakpoint = cortex_a_add_hybrid_breakpoint, - .remove_breakpoint = cortex_a_remove_breakpoint, - .add_watchpoint = NULL, - .remove_watchpoint = NULL, - - .commands = cortex_r4_command_handlers, - .target_create = cortex_r4_target_create, - .init_target = cortex_a_init_target, - .examine = cortex_a_examine, - .deinit_target = cortex_a_deinit_target, -}; diff --git a/src/target/cortex_a.h b/src/target/cortex_a.h deleted file mode 100644 index ea08c670f..000000000 --- a/src/target/cortex_a.h +++ /dev/null @@ -1,117 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * Copyright (C) 2006 by Magnus Lundin * - * lundin@mlu.mine.nu * - * * - * Copyright (C) 2008 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * Copyright (C) 2009 by Dirk Behme * - * dirk.behme@gmail.com - copy from cortex_m3 * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifndef OPENOCD_TARGET_CORTEX_A_H -#define OPENOCD_TARGET_CORTEX_A_H - -#include "armv7a.h" - -#define CORTEX_A_COMMON_MAGIC 0x411fc082 -#define CORTEX_A15_COMMON_MAGIC 0x413fc0f1 - -#define CORTEX_A5_PARTNUM 0xc05 -#define CORTEX_A7_PARTNUM 0xc07 -#define CORTEX_A8_PARTNUM 0xc08 -#define CORTEX_A9_PARTNUM 0xc09 -#define CORTEX_A15_PARTNUM 0xc0f -#define CORTEX_A_MIDR_PARTNUM_MASK 0x0000fff0 -#define CORTEX_A_MIDR_PARTNUM_SHIFT 4 - -#define CPUDBG_CPUID 0xD00 -#define CPUDBG_CTYPR 0xD04 -#define CPUDBG_TTYPR 0xD0C -#define CPUDBG_LOCKACCESS 0xFB0 -#define CPUDBG_LOCKSTATUS 0xFB4 -#define CPUDBG_OSLAR_LK_MASK (1 << 1) - -#define BRP_NORMAL 0 -#define BRP_CONTEXT 1 - -#define CORTEX_A_PADDRDBG_CPU_SHIFT 13 - -enum cortex_a_isrmasking_mode { - CORTEX_A_ISRMASK_OFF, - CORTEX_A_ISRMASK_ON, -}; - -enum cortex_a_dacrfixup_mode { - CORTEX_A_DACRFIXUP_OFF, - CORTEX_A_DACRFIXUP_ON -}; - -struct cortex_a_brp { - int used; - int type; - uint32_t value; - uint32_t control; - uint8_t BRPn; -}; - -struct cortex_a_common { - int common_magic; - - /* Context information */ - uint32_t cpudbg_dscr; - - /* Saved cp15 registers */ - uint32_t cp15_control_reg; - /* latest cp15 register value written and cpsr processor mode */ - uint32_t cp15_control_reg_curr; - /* auxiliary control reg */ - uint32_t cp15_aux_control_reg; - /* DACR */ - uint32_t cp15_dacr_reg; - enum arm_mode curr_mode; - - /* Breakpoint register pairs */ - int brp_num_context; - int brp_num; - int brp_num_available; - struct cortex_a_brp *brp_list; - - /* Use cortex_a_read_regs_through_mem for fast register reads */ - int fast_reg_read; - - uint32_t cpuid; - uint32_t ctypr; - uint32_t ttypr; - uint32_t didr; - - enum cortex_a_isrmasking_mode isrmasking_mode; - enum cortex_a_dacrfixup_mode dacrfixup_mode; - - struct armv7a_common armv7a_common; - -}; - -static inline struct cortex_a_common * -target_to_cortex_a(struct target *target) -{ - return container_of(target->arch_info, struct cortex_a_common, armv7a_common.arm); -} - -#endif /* OPENOCD_TARGET_CORTEX_A_H */ diff --git a/src/target/cortex_m.c b/src/target/cortex_m.c deleted file mode 100644 index a6a9309e2..000000000 --- a/src/target/cortex_m.c +++ /dev/null @@ -1,2429 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * Copyright (C) 2006 by Magnus Lundin * - * lundin@mlu.mine.nu * - * * - * Copyright (C) 2008 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - * * - * * - * Cortex-M3(tm) TRM, ARM DDI 0337E (r1p1) and 0337G (r2p0) * - * * - ***************************************************************************/ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "jtag/interface.h" -#include "breakpoints.h" -#include "cortex_m.h" -#include "target_request.h" -#include "target_type.h" -#include "arm_disassembler.h" -#include "register.h" -#include "arm_opcodes.h" -#include "arm_semihosting.h" -#include - -/* NOTE: most of this should work fine for the Cortex-M1 and - * Cortex-M0 cores too, although they're ARMv6-M not ARMv7-M. - * Some differences: M0/M1 doesn't have FBP remapping or the - * DWT tracing/profiling support. (So the cycle counter will - * not be usable; the other stuff isn't currently used here.) - * - * Although there are some workarounds for errata seen only in r0p0 - * silicon, such old parts are hard to find and thus not much tested - * any longer. - */ - -/** - * Returns the type of a break point required by address location - */ -#define BKPT_TYPE_BY_ADDR(addr) ((addr) < 0x20000000 ? BKPT_HARD : BKPT_SOFT) - -/* forward declarations */ -static int cortex_m_store_core_reg_u32(struct target *target, - uint32_t num, uint32_t value); -static void cortex_m_dwt_free(struct target *target); - -static int cortexm_dap_read_coreregister_u32(struct target *target, - uint32_t *value, int regnum) -{ - struct armv7m_common *armv7m = target_to_armv7m(target); - int retval; - uint32_t dcrdr; - - /* because the DCB_DCRDR is used for the emulated dcc channel - * we have to save/restore the DCB_DCRDR when used */ - if (target->dbg_msg_enabled) { - retval = mem_ap_read_u32(armv7m->debug_ap, DCB_DCRDR, &dcrdr); - if (retval != ERROR_OK) - return retval; - } - - retval = mem_ap_write_u32(armv7m->debug_ap, DCB_DCRSR, regnum); - if (retval != ERROR_OK) - return retval; - - retval = mem_ap_read_atomic_u32(armv7m->debug_ap, DCB_DCRDR, value); - if (retval != ERROR_OK) - return retval; - - if (target->dbg_msg_enabled) { - /* restore DCB_DCRDR - this needs to be in a separate - * transaction otherwise the emulated DCC channel breaks */ - if (retval == ERROR_OK) - retval = mem_ap_write_atomic_u32(armv7m->debug_ap, DCB_DCRDR, dcrdr); - } - - return retval; -} - -static int cortexm_dap_write_coreregister_u32(struct target *target, - uint32_t value, int regnum) -{ - struct armv7m_common *armv7m = target_to_armv7m(target); - int retval; - uint32_t dcrdr; - - /* because the DCB_DCRDR is used for the emulated dcc channel - * we have to save/restore the DCB_DCRDR when used */ - if (target->dbg_msg_enabled) { - retval = mem_ap_read_u32(armv7m->debug_ap, DCB_DCRDR, &dcrdr); - if (retval != ERROR_OK) - return retval; - } - - retval = mem_ap_write_u32(armv7m->debug_ap, DCB_DCRDR, value); - if (retval != ERROR_OK) - return retval; - - retval = mem_ap_write_atomic_u32(armv7m->debug_ap, DCB_DCRSR, regnum | DCRSR_WnR); - if (retval != ERROR_OK) - return retval; - - if (target->dbg_msg_enabled) { - /* restore DCB_DCRDR - this needs to be in a seperate - * transaction otherwise the emulated DCC channel breaks */ - if (retval == ERROR_OK) - retval = mem_ap_write_atomic_u32(armv7m->debug_ap, DCB_DCRDR, dcrdr); - } - - return retval; -} - -static int cortex_m_write_debug_halt_mask(struct target *target, - uint32_t mask_on, uint32_t mask_off) -{ - struct cortex_m_common *cortex_m = target_to_cm(target); - struct armv7m_common *armv7m = &cortex_m->armv7m; - - /* mask off status bits */ - cortex_m->dcb_dhcsr &= ~((0xFFFF << 16) | mask_off); - /* create new register mask */ - cortex_m->dcb_dhcsr |= DBGKEY | C_DEBUGEN | mask_on; - - return mem_ap_write_atomic_u32(armv7m->debug_ap, DCB_DHCSR, cortex_m->dcb_dhcsr); -} - -static int cortex_m_clear_halt(struct target *target) -{ - struct cortex_m_common *cortex_m = target_to_cm(target); - struct armv7m_common *armv7m = &cortex_m->armv7m; - int retval; - - /* clear step if any */ - cortex_m_write_debug_halt_mask(target, C_HALT, C_STEP); - - /* Read Debug Fault Status Register */ - retval = mem_ap_read_atomic_u32(armv7m->debug_ap, NVIC_DFSR, &cortex_m->nvic_dfsr); - if (retval != ERROR_OK) - return retval; - - /* Clear Debug Fault Status */ - retval = mem_ap_write_atomic_u32(armv7m->debug_ap, NVIC_DFSR, cortex_m->nvic_dfsr); - if (retval != ERROR_OK) - return retval; - LOG_DEBUG(" NVIC_DFSR 0x%" PRIx32 "", cortex_m->nvic_dfsr); - - return ERROR_OK; -} - -static int cortex_m_single_step_core(struct target *target) -{ - struct cortex_m_common *cortex_m = target_to_cm(target); - struct armv7m_common *armv7m = &cortex_m->armv7m; - uint32_t dhcsr_save; - int retval; - - /* backup dhcsr reg */ - dhcsr_save = cortex_m->dcb_dhcsr; - - /* Mask interrupts before clearing halt, if done already. This avoids - * Erratum 377497 (fixed in r1p0) where setting MASKINTS while clearing - * HALT can put the core into an unknown state. - */ - if (!(cortex_m->dcb_dhcsr & C_MASKINTS)) { - retval = mem_ap_write_atomic_u32(armv7m->debug_ap, DCB_DHCSR, - DBGKEY | C_MASKINTS | C_HALT | C_DEBUGEN); - if (retval != ERROR_OK) - return retval; - } - retval = mem_ap_write_atomic_u32(armv7m->debug_ap, DCB_DHCSR, - DBGKEY | C_MASKINTS | C_STEP | C_DEBUGEN); - if (retval != ERROR_OK) - return retval; - LOG_DEBUG(" "); - - /* restore dhcsr reg */ - cortex_m->dcb_dhcsr = dhcsr_save; - cortex_m_clear_halt(target); - - return ERROR_OK; -} - -static int cortex_m_enable_fpb(struct target *target) -{ - int retval = target_write_u32(target, FP_CTRL, 3); - if (retval != ERROR_OK) - return retval; - - /* check the fpb is actually enabled */ - uint32_t fpctrl; - retval = target_read_u32(target, FP_CTRL, &fpctrl); - if (retval != ERROR_OK) - return retval; - - if (fpctrl & 1) - return ERROR_OK; - - return ERROR_FAIL; -} - -static int cortex_m_endreset_event(struct target *target) -{ - int i; - int retval; - uint32_t dcb_demcr; - struct cortex_m_common *cortex_m = target_to_cm(target); - struct armv7m_common *armv7m = &cortex_m->armv7m; - struct adiv5_dap *swjdp = cortex_m->armv7m.arm.dap; - struct cortex_m_fp_comparator *fp_list = cortex_m->fp_comparator_list; - struct cortex_m_dwt_comparator *dwt_list = cortex_m->dwt_comparator_list; - - /* REVISIT The four debug monitor bits are currently ignored... */ - retval = mem_ap_read_atomic_u32(armv7m->debug_ap, DCB_DEMCR, &dcb_demcr); - if (retval != ERROR_OK) - return retval; - LOG_DEBUG("DCB_DEMCR = 0x%8.8" PRIx32 "", dcb_demcr); - - /* this register is used for emulated dcc channel */ - retval = mem_ap_write_u32(armv7m->debug_ap, DCB_DCRDR, 0); - if (retval != ERROR_OK) - return retval; - - /* Enable debug requests */ - 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)) { - retval = mem_ap_write_u32(armv7m->debug_ap, DCB_DHCSR, DBGKEY | C_DEBUGEN); - if (retval != ERROR_OK) - return retval; - } - - /* clear any interrupt masking */ - cortex_m_write_debug_halt_mask(target, 0, C_MASKINTS); - - /* Enable features controlled by ITM and DWT blocks, and catch only - * the vectors we were told to pay attention to. - * - * Target firmware is responsible for all fault handling policy - * choices *EXCEPT* explicitly scripted overrides like "vector_catch" - * or manual updates to the NVIC SHCSR and CCR registers. - */ - retval = mem_ap_write_u32(armv7m->debug_ap, DCB_DEMCR, TRCENA | armv7m->demcr); - if (retval != ERROR_OK) - return retval; - - /* Paranoia: evidently some (early?) chips don't preserve all the - * debug state (including FBP, DWT, etc) across reset... - */ - - /* Enable FPB */ - retval = cortex_m_enable_fpb(target); - if (retval != ERROR_OK) { - LOG_ERROR("Failed to enable the FPB"); - return retval; - } - - cortex_m->fpb_enabled = 1; - - /* Restore FPB registers */ - for (i = 0; i < cortex_m->fp_num_code + cortex_m->fp_num_lit; i++) { - retval = target_write_u32(target, fp_list[i].fpcr_address, fp_list[i].fpcr_value); - if (retval != ERROR_OK) - return retval; - } - - /* Restore DWT registers */ - for (i = 0; i < cortex_m->dwt_num_comp; i++) { - retval = target_write_u32(target, dwt_list[i].dwt_comparator_address + 0, - dwt_list[i].comp); - if (retval != ERROR_OK) - return retval; - retval = target_write_u32(target, dwt_list[i].dwt_comparator_address + 4, - dwt_list[i].mask); - if (retval != ERROR_OK) - return retval; - retval = target_write_u32(target, dwt_list[i].dwt_comparator_address + 8, - dwt_list[i].function); - if (retval != ERROR_OK) - return retval; - } - retval = dap_run(swjdp); - if (retval != ERROR_OK) - return retval; - - register_cache_invalidate(armv7m->arm.core_cache); - - /* make sure we have latest dhcsr flags */ - retval = mem_ap_read_atomic_u32(armv7m->debug_ap, DCB_DHCSR, &cortex_m->dcb_dhcsr); - - return retval; -} - -static int cortex_m_examine_debug_reason(struct target *target) -{ - struct cortex_m_common *cortex_m = target_to_cm(target); - - /* THIS IS NOT GOOD, TODO - better logic for detection of debug state reason - * only check the debug reason if we don't know it already */ - - if ((target->debug_reason != DBG_REASON_DBGRQ) - && (target->debug_reason != DBG_REASON_SINGLESTEP)) { - if (cortex_m->nvic_dfsr & DFSR_BKPT) { - target->debug_reason = DBG_REASON_BREAKPOINT; - if (cortex_m->nvic_dfsr & DFSR_DWTTRAP) - target->debug_reason = DBG_REASON_WPTANDBKPT; - } else if (cortex_m->nvic_dfsr & DFSR_DWTTRAP) - target->debug_reason = DBG_REASON_WATCHPOINT; - else if (cortex_m->nvic_dfsr & DFSR_VCATCH) - target->debug_reason = DBG_REASON_BREAKPOINT; - else /* EXTERNAL, HALTED */ - target->debug_reason = DBG_REASON_UNDEFINED; - } - - return ERROR_OK; -} - -static int cortex_m_examine_exception_reason(struct target *target) -{ - uint32_t shcsr = 0, except_sr = 0, cfsr = -1, except_ar = -1; - struct armv7m_common *armv7m = target_to_armv7m(target); - struct adiv5_dap *swjdp = armv7m->arm.dap; - int retval; - - retval = mem_ap_read_u32(armv7m->debug_ap, NVIC_SHCSR, &shcsr); - if (retval != ERROR_OK) - return retval; - switch (armv7m->exception_number) { - case 2: /* NMI */ - break; - case 3: /* Hard Fault */ - retval = mem_ap_read_atomic_u32(armv7m->debug_ap, NVIC_HFSR, &except_sr); - if (retval != ERROR_OK) - return retval; - if (except_sr & 0x40000000) { - retval = mem_ap_read_u32(armv7m->debug_ap, NVIC_CFSR, &cfsr); - if (retval != ERROR_OK) - return retval; - } - break; - case 4: /* Memory Management */ - retval = mem_ap_read_u32(armv7m->debug_ap, NVIC_CFSR, &except_sr); - if (retval != ERROR_OK) - return retval; - retval = mem_ap_read_u32(armv7m->debug_ap, NVIC_MMFAR, &except_ar); - if (retval != ERROR_OK) - return retval; - break; - case 5: /* Bus Fault */ - retval = mem_ap_read_u32(armv7m->debug_ap, NVIC_CFSR, &except_sr); - if (retval != ERROR_OK) - return retval; - retval = mem_ap_read_u32(armv7m->debug_ap, NVIC_BFAR, &except_ar); - if (retval != ERROR_OK) - return retval; - break; - case 6: /* Usage Fault */ - retval = mem_ap_read_u32(armv7m->debug_ap, NVIC_CFSR, &except_sr); - if (retval != ERROR_OK) - return retval; - break; - case 11: /* SVCall */ - break; - case 12: /* Debug Monitor */ - retval = mem_ap_read_u32(armv7m->debug_ap, NVIC_DFSR, &except_sr); - if (retval != ERROR_OK) - return retval; - break; - case 14: /* PendSV */ - break; - case 15: /* SysTick */ - break; - default: - except_sr = 0; - break; - } - retval = dap_run(swjdp); - if (retval == ERROR_OK) - LOG_DEBUG("%s SHCSR 0x%" PRIx32 ", SR 0x%" PRIx32 - ", CFSR 0x%" PRIx32 ", AR 0x%" PRIx32, - armv7m_exception_string(armv7m->exception_number), - shcsr, except_sr, cfsr, except_ar); - return retval; -} - -static int cortex_m_debug_entry(struct target *target) -{ - int i; - uint32_t xPSR; - int retval; - struct cortex_m_common *cortex_m = target_to_cm(target); - struct armv7m_common *armv7m = &cortex_m->armv7m; - struct arm *arm = &armv7m->arm; - struct reg *r; - - LOG_DEBUG(" "); - - cortex_m_clear_halt(target); - retval = mem_ap_read_atomic_u32(armv7m->debug_ap, DCB_DHCSR, &cortex_m->dcb_dhcsr); - if (retval != ERROR_OK) - return retval; - - retval = armv7m->examine_debug_reason(target); - if (retval != ERROR_OK) - return retval; - - /* Examine target state and mode - * First load register accessible through core debug port */ - int num_regs = arm->core_cache->num_regs; - - for (i = 0; i < num_regs; i++) { - r = &armv7m->arm.core_cache->reg_list[i]; - if (!r->valid) - arm->read_core_reg(target, r, i, ARM_MODE_ANY); - } - - r = arm->cpsr; - xPSR = buf_get_u32(r->value, 0, 32); - - /* For IT instructions xPSR must be reloaded on resume and clear on debug exec */ - if (xPSR & 0xf00) { - r->dirty = r->valid; - cortex_m_store_core_reg_u32(target, 16, xPSR & ~0xff); - } - - /* Are we in an exception handler */ - if (xPSR & 0x1FF) { - armv7m->exception_number = (xPSR & 0x1FF); - - arm->core_mode = ARM_MODE_HANDLER; - arm->map = armv7m_msp_reg_map; - } else { - unsigned control = buf_get_u32(arm->core_cache - ->reg_list[ARMV7M_CONTROL].value, 0, 2); - - /* is this thread privileged? */ - arm->core_mode = control & 1 - ? ARM_MODE_USER_THREAD - : ARM_MODE_THREAD; - - /* which stack is it using? */ - if (control & 2) - arm->map = armv7m_psp_reg_map; - else - arm->map = armv7m_msp_reg_map; - - armv7m->exception_number = 0; - } - - if (armv7m->exception_number) - cortex_m_examine_exception_reason(target); - - LOG_DEBUG("entered debug state in core mode: %s at PC 0x%" PRIx32 ", target->state: %s", - arm_mode_name(arm->core_mode), - buf_get_u32(arm->pc->value, 0, 32), - target_state_name(target)); - - if (armv7m->post_debug_entry) { - retval = armv7m->post_debug_entry(target); - if (retval != ERROR_OK) - return retval; - } - - return ERROR_OK; -} - -static int cortex_m_poll(struct target *target) -{ - int detected_failure = ERROR_OK; - int retval = ERROR_OK; - enum target_state prev_target_state = target->state; - struct cortex_m_common *cortex_m = target_to_cm(target); - struct armv7m_common *armv7m = &cortex_m->armv7m; - - /* Read from Debug Halting Control and Status Register */ - retval = mem_ap_read_atomic_u32(armv7m->debug_ap, DCB_DHCSR, &cortex_m->dcb_dhcsr); - if (retval != ERROR_OK) { - target->state = TARGET_UNKNOWN; - return retval; - } - - /* Recover from lockup. See ARMv7-M architecture spec, - * section B1.5.15 "Unrecoverable exception cases". - */ - if (cortex_m->dcb_dhcsr & S_LOCKUP) { - LOG_ERROR("%s -- clearing lockup after double fault", - target_name(target)); - cortex_m_write_debug_halt_mask(target, C_HALT, 0); - target->debug_reason = DBG_REASON_DBGRQ; - - /* We have to execute the rest (the "finally" equivalent, but - * still throw this exception again). - */ - detected_failure = ERROR_FAIL; - - /* refresh status bits */ - 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 & S_RESET_ST) { - target->state = TARGET_RESET; - return ERROR_OK; - } - - if (target->state == TARGET_RESET) { - /* Cannot switch context while running so endreset is - * called with target->state == TARGET_RESET - */ - LOG_DEBUG("Exit from reset with dcb_dhcsr 0x%" PRIx32, - cortex_m->dcb_dhcsr); - retval = cortex_m_endreset_event(target); - if (retval != ERROR_OK) { - target->state = TARGET_UNKNOWN; - return retval; - } - target->state = TARGET_RUNNING; - prev_target_state = TARGET_RUNNING; - } - - if (cortex_m->dcb_dhcsr & S_HALT) { - target->state = TARGET_HALTED; - - if ((prev_target_state == TARGET_RUNNING) || (prev_target_state == TARGET_RESET)) { - retval = cortex_m_debug_entry(target); - if (retval != ERROR_OK) - return retval; - - if (arm_semihosting(target, &retval) != 0) - return retval; - - target_call_event_callbacks(target, TARGET_EVENT_HALTED); - } - if (prev_target_state == TARGET_DEBUG_RUNNING) { - LOG_DEBUG(" "); - retval = cortex_m_debug_entry(target); - if (retval != ERROR_OK) - return retval; - - target_call_event_callbacks(target, TARGET_EVENT_DEBUG_HALTED); - } - } - - /* REVISIT when S_SLEEP is set, it's in a Sleep or DeepSleep state. - * How best to model low power modes? - */ - - if (target->state == TARGET_UNKNOWN) { - /* check if processor is retiring instructions */ - if (cortex_m->dcb_dhcsr & S_RETIRE_ST) { - target->state = TARGET_RUNNING; - retval = ERROR_OK; - } - } - - /* Did we detect a failure condition that we cleared? */ - if (detected_failure != ERROR_OK) - retval = detected_failure; - return retval; -} - -static int cortex_m_halt(struct target *target) -{ - LOG_DEBUG("target->state: %s", - target_state_name(target)); - - if (target->state == TARGET_HALTED) { - LOG_DEBUG("target was already halted"); - return ERROR_OK; - } - - if (target->state == TARGET_UNKNOWN) - LOG_WARNING("target was in unknown state when halt was requested"); - - if (target->state == TARGET_RESET) { - if ((jtag_get_reset_config() & RESET_SRST_PULLS_TRST) && jtag_get_srst()) { - LOG_ERROR("can't request a halt while in reset if nSRST pulls nTRST"); - return ERROR_TARGET_FAILURE; - } else { - /* we came here in a reset_halt or reset_init sequence - * debug entry was already prepared in cortex_m3_assert_reset() - */ - target->debug_reason = DBG_REASON_DBGRQ; - - return ERROR_OK; - } - } - - /* Write to Debug Halting Control and Status Register */ - cortex_m_write_debug_halt_mask(target, C_HALT, 0); - - target->debug_reason = DBG_REASON_DBGRQ; - - return ERROR_OK; -} - -static int cortex_m_soft_reset_halt(struct target *target) -{ - struct cortex_m_common *cortex_m = target_to_cm(target); - struct armv7m_common *armv7m = &cortex_m->armv7m; - uint32_t dcb_dhcsr = 0; - int retval, timeout = 0; - - /* soft_reset_halt is deprecated on cortex_m as the same functionality - * can be obtained by using 'reset halt' and 'cortex_m reset_config vectreset' - * As this reset only used VC_CORERESET it would only ever reset the cortex_m - * core, not the peripherals */ - LOG_WARNING("soft_reset_halt is deprecated, please use 'reset halt' instead."); - - /* Enter debug state on reset; restore DEMCR in endreset_event() */ - retval = mem_ap_write_u32(armv7m->debug_ap, DCB_DEMCR, - TRCENA | VC_HARDERR | VC_BUSERR | VC_CORERESET); - if (retval != ERROR_OK) - return retval; - - /* Request a core-only reset */ - retval = mem_ap_write_atomic_u32(armv7m->debug_ap, NVIC_AIRCR, - AIRCR_VECTKEY | AIRCR_VECTRESET); - if (retval != ERROR_OK) - return retval; - target->state = TARGET_RESET; - - /* registers are now invalid */ - register_cache_invalidate(cortex_m->armv7m.arm.core_cache); - - while (timeout < 100) { - retval = mem_ap_read_atomic_u32(armv7m->debug_ap, DCB_DHCSR, &dcb_dhcsr); - if (retval == ERROR_OK) { - retval = mem_ap_read_atomic_u32(armv7m->debug_ap, NVIC_DFSR, - &cortex_m->nvic_dfsr); - if (retval != ERROR_OK) - return retval; - if ((dcb_dhcsr & S_HALT) - && (cortex_m->nvic_dfsr & DFSR_VCATCH)) { - LOG_DEBUG("system reset-halted, DHCSR 0x%08x, " - "DFSR 0x%08x", - (unsigned) dcb_dhcsr, - (unsigned) cortex_m->nvic_dfsr); - cortex_m_poll(target); - /* FIXME restore user's vector catch config */ - return ERROR_OK; - } else - LOG_DEBUG("waiting for system reset-halt, " - "DHCSR 0x%08x, %d ms", - (unsigned) dcb_dhcsr, timeout); - } - timeout++; - alive_sleep(1); - } - - return ERROR_OK; -} - -void cortex_m_enable_breakpoints(struct target *target) -{ - struct breakpoint *breakpoint = target->breakpoints; - - /* set any pending breakpoints */ - while (breakpoint) { - if (!breakpoint->set) - cortex_m_set_breakpoint(target, breakpoint); - breakpoint = breakpoint->next; - } -} - -static int cortex_m_resume(struct target *target, int current, - uint32_t address, int handle_breakpoints, int debug_execution) -{ - struct armv7m_common *armv7m = target_to_armv7m(target); - struct breakpoint *breakpoint = NULL; - uint32_t resume_pc; - struct reg *r; - - if (target->state != TARGET_HALTED) { - LOG_WARNING("target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - if (!debug_execution) { - target_free_all_working_areas(target); - cortex_m_enable_breakpoints(target); - cortex_m_enable_watchpoints(target); - } - - if (debug_execution) { - r = armv7m->arm.core_cache->reg_list + ARMV7M_PRIMASK; - - /* Disable interrupts */ - /* We disable interrupts in the PRIMASK register instead of - * masking with C_MASKINTS. This is probably the same issue - * as Cortex-M3 Erratum 377493 (fixed in r1p0): C_MASKINTS - * in parallel with disabled interrupts can cause local faults - * to not be taken. - * - * REVISIT this clearly breaks non-debug execution, since the - * PRIMASK register state isn't saved/restored... workaround - * by never resuming app code after debug execution. - */ - buf_set_u32(r->value, 0, 1, 1); - r->dirty = true; - r->valid = true; - - /* Make sure we are in Thumb mode */ - r = armv7m->arm.cpsr; - buf_set_u32(r->value, 24, 1, 1); - r->dirty = true; - r->valid = true; - } - - /* current = 1: continue on current pc, otherwise continue at
*/ - r = armv7m->arm.pc; - if (!current) { - buf_set_u32(r->value, 0, 32, address); - r->dirty = true; - r->valid = true; - } - - /* if we halted last time due to a bkpt instruction - * then we have to manually step over it, otherwise - * the core will break again */ - - if (!breakpoint_find(target, buf_get_u32(r->value, 0, 32)) - && !debug_execution) - armv7m_maybe_skip_bkpt_inst(target, NULL); - - resume_pc = buf_get_u32(r->value, 0, 32); - - armv7m_restore_context(target); - - /* the front-end may request us not to handle breakpoints */ - if (handle_breakpoints) { - /* 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 ")", - breakpoint->address, - breakpoint->unique_id); - cortex_m_unset_breakpoint(target, breakpoint); - cortex_m_single_step_core(target); - cortex_m_set_breakpoint(target, breakpoint); - } - } - - /* Restart core */ - cortex_m_write_debug_halt_mask(target, 0, C_HALT); - - target->debug_reason = DBG_REASON_NOTHALTED; - - /* registers are now invalid */ - register_cache_invalidate(armv7m->arm.core_cache); - - if (!debug_execution) { - target->state = TARGET_RUNNING; - target_call_event_callbacks(target, TARGET_EVENT_RESUMED); - LOG_DEBUG("target resumed at 0x%" PRIx32 "", resume_pc); - } else { - target->state = TARGET_DEBUG_RUNNING; - target_call_event_callbacks(target, TARGET_EVENT_DEBUG_RESUMED); - LOG_DEBUG("target debug resumed at 0x%" PRIx32 "", resume_pc); - } - - return ERROR_OK; -} - -/* int irqstepcount = 0; */ -static int cortex_m_step(struct target *target, int current, - uint32_t address, int handle_breakpoints) -{ - struct cortex_m_common *cortex_m = target_to_cm(target); - struct armv7m_common *armv7m = &cortex_m->armv7m; - struct breakpoint *breakpoint = NULL; - struct reg *pc = armv7m->arm.pc; - bool bkpt_inst_found = false; - int retval; - bool isr_timed_out = false; - - if (target->state != TARGET_HALTED) { - LOG_WARNING("target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - /* current = 1: continue on current pc, otherwise continue at
*/ - if (!current) - buf_set_u32(pc->value, 0, 32, address); - - uint32_t pc_value = buf_get_u32(pc->value, 0, 32); - - /* the front-end may request us not to handle breakpoints */ - if (handle_breakpoints) { - breakpoint = breakpoint_find(target, pc_value); - if (breakpoint) - cortex_m_unset_breakpoint(target, breakpoint); - } - - armv7m_maybe_skip_bkpt_inst(target, &bkpt_inst_found); - - target->debug_reason = DBG_REASON_SINGLESTEP; - - armv7m_restore_context(target); - - target_call_event_callbacks(target, TARGET_EVENT_RESUMED); - - /* if no bkpt instruction is found at pc then we can perform - * a normal step, otherwise we have to manually step over the bkpt - * instruction - as such simulate a step */ - if (bkpt_inst_found == false) { - /* Automatic ISR masking mode off: Just step over the next instruction */ - if ((cortex_m->isrmasking_mode != CORTEX_M_ISRMASK_AUTO)) - cortex_m_write_debug_halt_mask(target, C_STEP, C_HALT); - else { - /* Process interrupts during stepping in a way they don't interfere - * debugging. - * - * Principle: - * - * Set a temporary break point at the current pc and let the core run - * with interrupts enabled. Pending interrupts get served and we run - * into the breakpoint again afterwards. Then we step over the next - * instruction with interrupts disabled. - * - * If the pending interrupts don't complete within time, we leave the - * core running. This may happen if the interrupts trigger faster - * than the core can process them or the handler doesn't return. - * - * If no more breakpoints are available we simply do a step with - * interrupts enabled. - * - */ - - /* 2012-09-29 ph - * - * If a break point is already set on the lower half word then a break point on - * the upper half word will not break again when the core is restarted. So we - * just step over the instruction with interrupts disabled. - * - * The documentation has no information about this, it was found by observation - * on STM32F1 and STM32F2. Proper explanation welcome. STM32F0 dosen't seem to - * suffer from this problem. - * - * To add some confusion: pc_value has bit 0 always set, while the breakpoint - * address has it always cleared. The former is done to indicate thumb mode - * to gdb. - * - */ - if ((pc_value & 0x02) && breakpoint_find(target, pc_value & ~0x03)) { - LOG_DEBUG("Stepping over next instruction with interrupts disabled"); - cortex_m_write_debug_halt_mask(target, C_HALT | C_MASKINTS, 0); - cortex_m_write_debug_halt_mask(target, C_STEP, C_HALT); - /* Re-enable interrupts */ - cortex_m_write_debug_halt_mask(target, C_HALT, C_MASKINTS); - } - else { - - /* Set a temporary break point */ - if (breakpoint) - retval = cortex_m_set_breakpoint(target, breakpoint); - else - retval = breakpoint_add(target, pc_value, 2, BKPT_TYPE_BY_ADDR(pc_value)); - bool tmp_bp_set = (retval == ERROR_OK); - - /* No more breakpoints left, just do a step */ - if (!tmp_bp_set) - cortex_m_write_debug_halt_mask(target, C_STEP, C_HALT); - else { - /* Start the core */ - LOG_DEBUG("Starting core to serve pending interrupts"); - int64_t t_start = timeval_ms(); - cortex_m_write_debug_halt_mask(target, 0, C_HALT | C_STEP); - - /* Wait for pending handlers to complete or timeout */ - do { - retval = mem_ap_read_atomic_u32(armv7m->debug_ap, - DCB_DHCSR, - &cortex_m->dcb_dhcsr); - if (retval != ERROR_OK) { - target->state = TARGET_UNKNOWN; - return retval; - } - isr_timed_out = ((timeval_ms() - t_start) > 500); - } while (!((cortex_m->dcb_dhcsr & S_HALT) || isr_timed_out)); - - /* only remove breakpoint if we created it */ - if (breakpoint) - cortex_m_unset_breakpoint(target, breakpoint); - else { - /* Remove the temporary breakpoint */ - breakpoint_remove(target, pc_value); - } - - if (isr_timed_out) { - LOG_DEBUG("Interrupt handlers didn't complete within time, " - "leaving target running"); - } else { - /* Step over next instruction with interrupts disabled */ - cortex_m_write_debug_halt_mask(target, - C_HALT | C_MASKINTS, - 0); - cortex_m_write_debug_halt_mask(target, C_STEP, C_HALT); - /* Re-enable interrupts */ - cortex_m_write_debug_halt_mask(target, C_HALT, C_MASKINTS); - } - } - } - } - } - - retval = mem_ap_read_atomic_u32(armv7m->debug_ap, DCB_DHCSR, &cortex_m->dcb_dhcsr); - if (retval != ERROR_OK) - return retval; - - /* registers are now invalid */ - register_cache_invalidate(armv7m->arm.core_cache); - - if (breakpoint) - cortex_m_set_breakpoint(target, breakpoint); - - if (isr_timed_out) { - /* Leave the core running. The user has to stop execution manually. */ - target->debug_reason = DBG_REASON_NOTHALTED; - target->state = TARGET_RUNNING; - return ERROR_OK; - } - - LOG_DEBUG("target stepped dcb_dhcsr = 0x%" PRIx32 - " nvic_icsr = 0x%" PRIx32, - cortex_m->dcb_dhcsr, cortex_m->nvic_icsr); - - retval = cortex_m_debug_entry(target); - if (retval != ERROR_OK) - return retval; - target_call_event_callbacks(target, TARGET_EVENT_HALTED); - - LOG_DEBUG("target stepped dcb_dhcsr = 0x%" PRIx32 - " nvic_icsr = 0x%" PRIx32, - cortex_m->dcb_dhcsr, cortex_m->nvic_icsr); - - return ERROR_OK; -} - -static int cortex_m_assert_reset(struct target *target) -{ - struct cortex_m_common *cortex_m = target_to_cm(target); - struct armv7m_common *armv7m = &cortex_m->armv7m; - enum cortex_m_soft_reset_config reset_config = cortex_m->soft_reset_config; - - LOG_DEBUG("target->state: %s", - target_state_name(target)); - - enum reset_types jtag_reset_config = jtag_get_reset_config(); - - if (target_has_event_action(target, TARGET_EVENT_RESET_ASSERT)) { - /* allow scripts to override the reset event */ - - target_handle_event(target, TARGET_EVENT_RESET_ASSERT); - register_cache_invalidate(cortex_m->armv7m.arm.core_cache); - target->state = TARGET_RESET; - - return ERROR_OK; - } - - /* some cores support connecting while srst is asserted - * use that mode is it has been configured */ - - bool srst_asserted = false; - - if ((jtag_reset_config & RESET_HAS_SRST) && - (jtag_reset_config & RESET_SRST_NO_GATING)) { - adapter_assert_reset(); - srst_asserted = true; - } - - /* Enable debug requests */ - int retval; - retval = mem_ap_read_atomic_u32(armv7m->debug_ap, DCB_DHCSR, &cortex_m->dcb_dhcsr); - /* 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 the processor is sleeping in a WFI or WFE instruction, the - * C_HALT bit must be asserted to regain control */ - 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); - - 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) - mem_ap_write_atomic_u32(armv7m->debug_ap, DCB_DHCSR, - DBGKEY | C_DEBUGEN | C_HALT); - - /* clear any debug flags before resuming */ - cortex_m_clear_halt(target); - - /* clear C_HALT in dhcsr reg */ - cortex_m_write_debug_halt_mask(target, 0, C_HALT); - } else { - /* Halt in debug on reset; endreset_event() restores DEMCR. - * - * REVISIT catching BUSERR presumably helps to defend against - * bad vector table entries. Should this include MMERR or - * other flags too? - */ - int retval2; - retval2 = mem_ap_write_atomic_u32(armv7m->debug_ap, DCB_DEMCR, - TRCENA | VC_HARDERR | VC_BUSERR | VC_CORERESET); - 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. - * This has the disadvantage of not resetting the peripherals, so a - * reset-init event handler is needed to perform any peripheral resets. - */ - LOG_DEBUG("Using Cortex-M %s", (reset_config == CORTEX_M_RESET_SYSRESETREQ) - ? "SYSRESETREQ" : "VECTRESET"); - - if (reset_config == CORTEX_M_RESET_VECTRESET) { - LOG_WARNING("Only resetting the Cortex-M core, use a reset-init event " - "handler to reset any peripherals or configure hardware srst support."); - } - - 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 (retval3 != ERROR_OK) - LOG_DEBUG("Ignoring AP write error right after reset"); - - retval3 = dap_dp_init(armv7m->debug_ap->dap); - if (retval3 != ERROR_OK) - LOG_ERROR("DP initialisation failed"); - - 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; - mem_ap_read_atomic_u32(armv7m->debug_ap, NVIC_AIRCR, &tmp); - } - } - - target->state = TARGET_RESET; - jtag_add_sleep(50000); - - 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) - return retval; - } - - return ERROR_OK; -} - -static int cortex_m_deassert_reset(struct target *target) -{ - struct armv7m_common *armv7m = &target_to_cm(target)->armv7m; - - LOG_DEBUG("target->state: %s", - target_state_name(target)); - - /* deassert reset lines */ - adapter_deassert_reset(); - - enum reset_types jtag_reset_config = jtag_get_reset_config(); - - if ((jtag_reset_config & RESET_HAS_SRST) && - !(jtag_reset_config & RESET_SRST_NO_GATING)) { - int retval = dap_dp_init(armv7m->debug_ap->dap); - if (retval != ERROR_OK) { - LOG_ERROR("DP initialisation failed"); - return retval; - } - } - - return ERROR_OK; -} - -int cortex_m_set_breakpoint(struct target *target, struct breakpoint *breakpoint) -{ - int retval; - int fp_num = 0; - struct cortex_m_common *cortex_m = target_to_cm(target); - struct cortex_m_fp_comparator *comparator_list = cortex_m->fp_comparator_list; - - if (breakpoint->set) { - LOG_WARNING("breakpoint (BPID: %" PRIu32 ") already set", breakpoint->unique_id); - return ERROR_OK; - } - - if (cortex_m->auto_bp_type) - breakpoint->type = BKPT_TYPE_BY_ADDR(breakpoint->address); - - if (breakpoint->type == BKPT_HARD) { - uint32_t fpcr_value; - while (comparator_list[fp_num].used && (fp_num < cortex_m->fp_num_code)) - fp_num++; - if (fp_num >= cortex_m->fp_num_code) { - LOG_ERROR("Can not find free FPB Comparator!"); - return ERROR_FAIL; - } - breakpoint->set = fp_num + 1; - fpcr_value = breakpoint->address | 1; - if (cortex_m->fp_rev == 0) { - uint32_t hilo; - hilo = (breakpoint->address & 0x2) ? FPCR_REPLACE_BKPT_HIGH : FPCR_REPLACE_BKPT_LOW; - fpcr_value = (fpcr_value & 0x1FFFFFFC) | hilo | 1; - } else if (cortex_m->fp_rev > 1) { - LOG_ERROR("Unhandled Cortex-M Flash Patch Breakpoint architecture revision"); - return ERROR_FAIL; - } - comparator_list[fp_num].used = 1; - comparator_list[fp_num].fpcr_value = fpcr_value; - target_write_u32(target, comparator_list[fp_num].fpcr_address, - comparator_list[fp_num].fpcr_value); - LOG_DEBUG("fpc_num %i fpcr_value 0x%" PRIx32 "", - fp_num, - comparator_list[fp_num].fpcr_value); - if (!cortex_m->fpb_enabled) { - LOG_DEBUG("FPB wasn't enabled, do it now"); - retval = cortex_m_enable_fpb(target); - if (retval != ERROR_OK) { - LOG_ERROR("Failed to enable the FPB"); - return retval; - } - - cortex_m->fpb_enabled = 1; - } - } else if (breakpoint->type == BKPT_SOFT) { - uint8_t code[4]; - - /* NOTE: on ARMv6-M and ARMv7-M, BKPT(0xab) is used for - * semihosting; don't use that. Otherwise the BKPT - * parameter is arbitrary. - */ - buf_set_u32(code, 0, 32, ARMV5_T_BKPT(0x11)); - retval = target_read_memory(target, - breakpoint->address & 0xFFFFFFFE, - breakpoint->length, 1, - breakpoint->orig_instr); - if (retval != ERROR_OK) - return retval; - retval = target_write_memory(target, - breakpoint->address & 0xFFFFFFFE, - breakpoint->length, 1, - code); - if (retval != ERROR_OK) - return retval; - breakpoint->set = true; - } - - LOG_DEBUG("BPID: %" PRIu32 ", Type: %d, Address: 0x%08" PRIx32 " Length: %d (set=%d)", - breakpoint->unique_id, - (int)(breakpoint->type), - breakpoint->address, - breakpoint->length, - breakpoint->set); - - return ERROR_OK; -} - -int cortex_m_unset_breakpoint(struct target *target, struct breakpoint *breakpoint) -{ - int retval; - struct cortex_m_common *cortex_m = target_to_cm(target); - struct cortex_m_fp_comparator *comparator_list = cortex_m->fp_comparator_list; - - if (!breakpoint->set) { - LOG_WARNING("breakpoint not set"); - return ERROR_OK; - } - - LOG_DEBUG("BPID: %" PRIu32 ", Type: %d, Address: 0x%08" PRIx32 " Length: %d (set=%d)", - breakpoint->unique_id, - (int)(breakpoint->type), - breakpoint->address, - breakpoint->length, - breakpoint->set); - - if (breakpoint->type == BKPT_HARD) { - int fp_num = breakpoint->set - 1; - if ((fp_num < 0) || (fp_num >= cortex_m->fp_num_code)) { - LOG_DEBUG("Invalid FP Comparator number in breakpoint"); - return ERROR_OK; - } - comparator_list[fp_num].used = 0; - comparator_list[fp_num].fpcr_value = 0; - target_write_u32(target, comparator_list[fp_num].fpcr_address, - comparator_list[fp_num].fpcr_value); - } else { - /* restore original instruction (kept in target endianness) */ - if (breakpoint->length == 4) { - retval = target_write_memory(target, breakpoint->address & 0xFFFFFFFE, 4, 1, - breakpoint->orig_instr); - if (retval != ERROR_OK) - return retval; - } else { - retval = target_write_memory(target, breakpoint->address & 0xFFFFFFFE, 2, 1, - breakpoint->orig_instr); - if (retval != ERROR_OK) - return retval; - } - } - breakpoint->set = false; - - return ERROR_OK; -} - -int cortex_m_add_breakpoint(struct target *target, struct breakpoint *breakpoint) -{ - struct cortex_m_common *cortex_m = target_to_cm(target); - - if (cortex_m->auto_bp_type) - breakpoint->type = BKPT_TYPE_BY_ADDR(breakpoint->address); - - if (breakpoint->type != BKPT_TYPE_BY_ADDR(breakpoint->address)) { - if (breakpoint->type == BKPT_HARD) { - LOG_INFO("flash patch comparator requested outside code memory region"); - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - } - - if (breakpoint->type == BKPT_SOFT) { - LOG_INFO("soft breakpoint requested in code (flash) memory region"); - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - } - } - - if ((breakpoint->type == BKPT_HARD) && (cortex_m->fp_code_available < 1)) { - LOG_INFO("no flash patch comparator unit available for hardware breakpoint"); - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - } - - if (breakpoint->length == 3) { - LOG_DEBUG("Using a two byte breakpoint for 32bit Thumb-2 request"); - breakpoint->length = 2; - } - - if ((breakpoint->length != 2)) { - LOG_INFO("only breakpoints of two bytes length supported"); - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - } - - if (breakpoint->type == BKPT_HARD) - cortex_m->fp_code_available--; - - return cortex_m_set_breakpoint(target, breakpoint); -} - -int cortex_m_remove_breakpoint(struct target *target, struct breakpoint *breakpoint) -{ - struct cortex_m_common *cortex_m = target_to_cm(target); - - /* REVISIT why check? FBP can be updated with core running ... */ - if (target->state != TARGET_HALTED) { - LOG_WARNING("target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - if (cortex_m->auto_bp_type) - breakpoint->type = BKPT_TYPE_BY_ADDR(breakpoint->address); - - if (breakpoint->set) - cortex_m_unset_breakpoint(target, breakpoint); - - if (breakpoint->type == BKPT_HARD) - cortex_m->fp_code_available++; - - return ERROR_OK; -} - -int cortex_m_set_watchpoint(struct target *target, struct watchpoint *watchpoint) -{ - int dwt_num = 0; - uint32_t mask, temp; - struct cortex_m_common *cortex_m = target_to_cm(target); - - /* watchpoint params were validated earlier */ - mask = 0; - temp = watchpoint->length; - while (temp) { - temp >>= 1; - mask++; - } - mask--; - - /* REVISIT Don't fully trust these "not used" records ... users - * may set up breakpoints by hand, e.g. dual-address data value - * watchpoint using comparator #1; comparator #0 matching cycle - * count; send data trace info through ITM and TPIU; etc - */ - struct cortex_m_dwt_comparator *comparator; - - for (comparator = cortex_m->dwt_comparator_list; - comparator->used && dwt_num < cortex_m->dwt_num_comp; - comparator++, dwt_num++) - continue; - if (dwt_num >= cortex_m->dwt_num_comp) { - LOG_ERROR("Can not find free DWT Comparator"); - return ERROR_FAIL; - } - comparator->used = 1; - watchpoint->set = dwt_num + 1; - - comparator->comp = watchpoint->address; - target_write_u32(target, comparator->dwt_comparator_address + 0, - comparator->comp); - - comparator->mask = mask; - target_write_u32(target, comparator->dwt_comparator_address + 4, - comparator->mask); - - switch (watchpoint->rw) { - case WPT_READ: - comparator->function = 5; - break; - case WPT_WRITE: - comparator->function = 6; - break; - case WPT_ACCESS: - comparator->function = 7; - break; - } - target_write_u32(target, comparator->dwt_comparator_address + 8, - comparator->function); - - LOG_DEBUG("Watchpoint (ID %d) DWT%d 0x%08x 0x%x 0x%05x", - watchpoint->unique_id, dwt_num, - (unsigned) comparator->comp, - (unsigned) comparator->mask, - (unsigned) comparator->function); - return ERROR_OK; -} - -int cortex_m_unset_watchpoint(struct target *target, struct watchpoint *watchpoint) -{ - struct cortex_m_common *cortex_m = target_to_cm(target); - struct cortex_m_dwt_comparator *comparator; - int dwt_num; - - if (!watchpoint->set) { - LOG_WARNING("watchpoint (wpid: %d) not set", - watchpoint->unique_id); - return ERROR_OK; - } - - dwt_num = watchpoint->set - 1; - - LOG_DEBUG("Watchpoint (ID %d) DWT%d address: 0x%08x clear", - watchpoint->unique_id, dwt_num, - (unsigned) watchpoint->address); - - if ((dwt_num < 0) || (dwt_num >= cortex_m->dwt_num_comp)) { - LOG_DEBUG("Invalid DWT Comparator number in watchpoint"); - return ERROR_OK; - } - - comparator = cortex_m->dwt_comparator_list + dwt_num; - comparator->used = 0; - comparator->function = 0; - target_write_u32(target, comparator->dwt_comparator_address + 8, - comparator->function); - - watchpoint->set = false; - - return ERROR_OK; -} - -int cortex_m_add_watchpoint(struct target *target, struct watchpoint *watchpoint) -{ - struct cortex_m_common *cortex_m = target_to_cm(target); - - if (cortex_m->dwt_comp_available < 1) { - LOG_DEBUG("no comparators?"); - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - } - - /* hardware doesn't support data value masking */ - if (watchpoint->mask != ~(uint32_t)0) { - LOG_DEBUG("watchpoint value masks not supported"); - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - } - - /* hardware allows address masks of up to 32K */ - unsigned mask; - - for (mask = 0; mask < 16; mask++) { - if ((1u << mask) == watchpoint->length) - break; - } - if (mask == 16) { - LOG_DEBUG("unsupported watchpoint length"); - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - } - if (watchpoint->address & ((1 << mask) - 1)) { - LOG_DEBUG("watchpoint address is unaligned"); - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - } - - /* Caller doesn't seem to be able to describe watching for data - * values of zero; that flags "no value". - * - * REVISIT This DWT may well be able to watch for specific data - * values. Requires comparator #1 to set DATAVMATCH and match - * the data, and another comparator (DATAVADDR0) matching addr. - */ - if (watchpoint->value) { - LOG_DEBUG("data value watchpoint not YET supported"); - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - } - - cortex_m->dwt_comp_available--; - LOG_DEBUG("dwt_comp_available: %d", cortex_m->dwt_comp_available); - - return ERROR_OK; -} - -int cortex_m_remove_watchpoint(struct target *target, struct watchpoint *watchpoint) -{ - struct cortex_m_common *cortex_m = target_to_cm(target); - - /* REVISIT why check? DWT can be updated with core running ... */ - if (target->state != TARGET_HALTED) { - LOG_WARNING("target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - if (watchpoint->set) - cortex_m_unset_watchpoint(target, watchpoint); - - cortex_m->dwt_comp_available++; - LOG_DEBUG("dwt_comp_available: %d", cortex_m->dwt_comp_available); - - return ERROR_OK; -} - -void cortex_m_enable_watchpoints(struct target *target) -{ - struct watchpoint *watchpoint = target->watchpoints; - - /* set any pending watchpoints */ - while (watchpoint) { - if (!watchpoint->set) - cortex_m_set_watchpoint(target, watchpoint); - watchpoint = watchpoint->next; - } -} - -static int cortex_m_load_core_reg_u32(struct target *target, - uint32_t num, uint32_t *value) -{ - int retval; - - /* NOTE: we "know" here that the register identifiers used - * in the v7m header match the Cortex-M3 Debug Core Register - * Selector values for R0..R15, xPSR, MSP, and PSP. - */ - switch (num) { - case 0 ... 18: - /* read a normal core register */ - retval = cortexm_dap_read_coreregister_u32(target, value, num); - - if (retval != ERROR_OK) { - LOG_ERROR("JTAG failure %i", retval); - return ERROR_JTAG_DEVICE_ERROR; - } - LOG_DEBUG("load from core reg %i value 0x%" PRIx32 "", (int)num, *value); - break; - - case ARMV7M_FPSCR: - /* Floating-point Status and Registers */ - retval = target_write_u32(target, DCB_DCRSR, 0x21); - if (retval != ERROR_OK) - return retval; - retval = target_read_u32(target, DCB_DCRDR, value); - if (retval != ERROR_OK) - return retval; - LOG_DEBUG("load from FPSCR value 0x%" PRIx32, *value); - break; - - case ARMV7M_S0 ... ARMV7M_S31: - /* Floating-point Status and Registers */ - retval = target_write_u32(target, DCB_DCRSR, num - ARMV7M_S0 + 0x40); - if (retval != ERROR_OK) - return retval; - retval = target_read_u32(target, DCB_DCRDR, value); - if (retval != ERROR_OK) - return retval; - LOG_DEBUG("load from FPU reg S%d value 0x%" PRIx32, - (int)(num - ARMV7M_S0), *value); - break; - - case ARMV7M_PRIMASK: - case ARMV7M_BASEPRI: - case ARMV7M_FAULTMASK: - case ARMV7M_CONTROL: - /* Cortex-M3 packages these four registers as bitfields - * in one Debug Core register. So say r0 and r2 docs; - * it was removed from r1 docs, but still works. - */ - cortexm_dap_read_coreregister_u32(target, value, 20); - - switch (num) { - case ARMV7M_PRIMASK: - *value = buf_get_u32((uint8_t *)value, 0, 1); - break; - - case ARMV7M_BASEPRI: - *value = buf_get_u32((uint8_t *)value, 8, 8); - break; - - case ARMV7M_FAULTMASK: - *value = buf_get_u32((uint8_t *)value, 16, 1); - break; - - case ARMV7M_CONTROL: - *value = buf_get_u32((uint8_t *)value, 24, 2); - break; - } - - LOG_DEBUG("load from special reg %i value 0x%" PRIx32 "", (int)num, *value); - break; - - default: - return ERROR_COMMAND_SYNTAX_ERROR; - } - - return ERROR_OK; -} - -static int cortex_m_store_core_reg_u32(struct target *target, - uint32_t num, uint32_t value) -{ - int retval; - uint32_t reg; - struct armv7m_common *armv7m = target_to_armv7m(target); - - /* NOTE: we "know" here that the register identifiers used - * in the v7m header match the Cortex-M3 Debug Core Register - * Selector values for R0..R15, xPSR, MSP, and PSP. - */ - switch (num) { - case 0 ... 18: - retval = cortexm_dap_write_coreregister_u32(target, value, num); - if (retval != ERROR_OK) { - struct reg *r; - - LOG_ERROR("JTAG failure"); - r = armv7m->arm.core_cache->reg_list + num; - r->dirty = r->valid; - return ERROR_JTAG_DEVICE_ERROR; - } - LOG_DEBUG("write core reg %i value 0x%" PRIx32 "", (int)num, value); - break; - - case ARMV7M_FPSCR: - /* Floating-point Status and Registers */ - retval = target_write_u32(target, DCB_DCRDR, value); - if (retval != ERROR_OK) - return retval; - retval = target_write_u32(target, DCB_DCRSR, 0x21 | (1<<16)); - if (retval != ERROR_OK) - return retval; - LOG_DEBUG("write FPSCR value 0x%" PRIx32, value); - break; - - case ARMV7M_S0 ... ARMV7M_S31: - /* Floating-point Status and Registers */ - retval = target_write_u32(target, DCB_DCRDR, value); - if (retval != ERROR_OK) - return retval; - retval = target_write_u32(target, DCB_DCRSR, (num - ARMV7M_S0 + 0x40) | (1<<16)); - if (retval != ERROR_OK) - return retval; - LOG_DEBUG("write FPU reg S%d value 0x%" PRIx32, - (int)(num - ARMV7M_S0), value); - break; - - case ARMV7M_PRIMASK: - case ARMV7M_BASEPRI: - case ARMV7M_FAULTMASK: - case ARMV7M_CONTROL: - /* Cortex-M3 packages these four registers as bitfields - * in one Debug Core register. So say r0 and r2 docs; - * it was removed from r1 docs, but still works. - */ - cortexm_dap_read_coreregister_u32(target, ®, 20); - - switch (num) { - case ARMV7M_PRIMASK: - buf_set_u32((uint8_t *)®, 0, 1, value); - break; - - case ARMV7M_BASEPRI: - buf_set_u32((uint8_t *)®, 8, 8, value); - break; - - case ARMV7M_FAULTMASK: - buf_set_u32((uint8_t *)®, 16, 1, value); - break; - - case ARMV7M_CONTROL: - buf_set_u32((uint8_t *)®, 24, 2, value); - break; - } - - cortexm_dap_write_coreregister_u32(target, reg, 20); - - LOG_DEBUG("write special reg %i value 0x%" PRIx32 " ", (int)num, value); - break; - - default: - return ERROR_COMMAND_SYNTAX_ERROR; - } - - return ERROR_OK; -} - -static int cortex_m_read_memory(struct target *target, uint32_t address, - uint32_t size, uint32_t count, uint8_t *buffer) -{ - struct armv7m_common *armv7m = target_to_armv7m(target); - - if (armv7m->arm.is_armv6m) { - /* armv6m does not handle unaligned memory access */ - if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u))) - return ERROR_TARGET_UNALIGNED_ACCESS; - } - - return mem_ap_read_buf(armv7m->debug_ap, buffer, size, count, address); -} - -static int cortex_m_write_memory(struct target *target, uint32_t address, - uint32_t size, uint32_t count, const uint8_t *buffer) -{ - struct armv7m_common *armv7m = target_to_armv7m(target); - - if (armv7m->arm.is_armv6m) { - /* armv6m does not handle unaligned memory access */ - if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u))) - return ERROR_TARGET_UNALIGNED_ACCESS; - } - - return mem_ap_write_buf(armv7m->debug_ap, buffer, size, count, address); -} - -static int cortex_m_init_target(struct command_context *cmd_ctx, - struct target *target) -{ - armv7m_build_reg_cache(target); - return ERROR_OK; -} - -void cortex_m_deinit_target(struct target *target) -{ - struct cortex_m_common *cortex_m = target_to_cm(target); - - free(cortex_m->fp_comparator_list); - - cortex_m_dwt_free(target); - armv7m_free_reg_cache(target); - - free(cortex_m); -} - -/* REVISIT cache valid/dirty bits are unmaintained. We could set "valid" - * on r/w if the core is not running, and clear on resume or reset ... or - * at least, in a post_restore_context() method. - */ - -struct dwt_reg_state { - struct target *target; - uint32_t addr; - uint8_t value[4]; /* scratch/cache */ -}; - -static int cortex_m_dwt_get_reg(struct reg *reg) -{ - struct dwt_reg_state *state = reg->arch_info; - - uint32_t tmp; - int retval = target_read_u32(state->target, state->addr, &tmp); - if (retval != ERROR_OK) - return retval; - - buf_set_u32(state->value, 0, 32, tmp); - return ERROR_OK; -} - -static int cortex_m_dwt_set_reg(struct reg *reg, uint8_t *buf) -{ - struct dwt_reg_state *state = reg->arch_info; - - return target_write_u32(state->target, state->addr, - buf_get_u32(buf, 0, reg->size)); -} - -struct dwt_reg { - uint32_t addr; - char *name; - unsigned size; -}; - -static struct dwt_reg dwt_base_regs[] = { - { DWT_CTRL, "dwt_ctrl", 32, }, - /* NOTE that Erratum 532314 (fixed r2p0) affects CYCCNT: it wrongly - * increments while the core is asleep. - */ - { DWT_CYCCNT, "dwt_cyccnt", 32, }, - /* plus some 8 bit counters, useful for profiling with TPIU */ -}; - -static struct dwt_reg dwt_comp[] = { -#define DWT_COMPARATOR(i) \ - { DWT_COMP0 + 0x10 * (i), "dwt_" #i "_comp", 32, }, \ - { DWT_MASK0 + 0x10 * (i), "dwt_" #i "_mask", 4, }, \ - { DWT_FUNCTION0 + 0x10 * (i), "dwt_" #i "_function", 32, } - DWT_COMPARATOR(0), - DWT_COMPARATOR(1), - DWT_COMPARATOR(2), - DWT_COMPARATOR(3), -#undef DWT_COMPARATOR -}; - -static const struct reg_arch_type dwt_reg_type = { - .get = cortex_m_dwt_get_reg, - .set = cortex_m_dwt_set_reg, -}; - -static void cortex_m_dwt_addreg(struct target *t, struct reg *r, struct dwt_reg *d) -{ - struct dwt_reg_state *state; - - state = calloc(1, sizeof *state); - if (!state) - return; - state->addr = d->addr; - state->target = t; - - r->name = d->name; - r->size = d->size; - r->value = state->value; - r->arch_info = state; - r->type = &dwt_reg_type; -} - -void cortex_m_dwt_setup(struct cortex_m_common *cm, struct target *target) -{ - uint32_t dwtcr; - struct reg_cache *cache; - struct cortex_m_dwt_comparator *comparator; - int reg, i; - - target_read_u32(target, DWT_CTRL, &dwtcr); - if (!dwtcr) { - LOG_DEBUG("no DWT"); - return; - } - - cm->dwt_num_comp = (dwtcr >> 28) & 0xF; - cm->dwt_comp_available = cm->dwt_num_comp; - cm->dwt_comparator_list = calloc(cm->dwt_num_comp, - sizeof(struct cortex_m_dwt_comparator)); - if (!cm->dwt_comparator_list) { -fail0: - cm->dwt_num_comp = 0; - LOG_ERROR("out of mem"); - return; - } - - cache = calloc(1, sizeof *cache); - if (!cache) { -fail1: - free(cm->dwt_comparator_list); - goto fail0; - } - cache->name = "Cortex-M DWT registers"; - cache->num_regs = 2 + cm->dwt_num_comp * 3; - cache->reg_list = calloc(cache->num_regs, sizeof *cache->reg_list); - if (!cache->reg_list) { - free(cache); - goto fail1; - } - - for (reg = 0; reg < 2; reg++) - cortex_m_dwt_addreg(target, cache->reg_list + reg, - dwt_base_regs + reg); - - comparator = cm->dwt_comparator_list; - for (i = 0; i < cm->dwt_num_comp; i++, comparator++) { - int j; - - comparator->dwt_comparator_address = DWT_COMP0 + 0x10 * i; - for (j = 0; j < 3; j++, reg++) - cortex_m_dwt_addreg(target, cache->reg_list + reg, - dwt_comp + 3 * i + j); - - /* make sure we clear any watchpoints enabled on the target */ - target_write_u32(target, comparator->dwt_comparator_address + 8, 0); - } - - *register_get_last_cache_p(&target->reg_cache) = cache; - cm->dwt_cache = cache; - - LOG_DEBUG("DWT dwtcr 0x%" PRIx32 ", comp %d, watch%s", - dwtcr, cm->dwt_num_comp, - (dwtcr & (0xf << 24)) ? " only" : "/trigger"); - - /* REVISIT: if num_comp > 1, check whether comparator #1 can - * implement single-address data value watchpoints ... so we - * won't need to check it later, when asked to set one up. - */ -} - -static void cortex_m_dwt_free(struct target *target) -{ - struct cortex_m_common *cm = target_to_cm(target); - struct reg_cache *cache = cm->dwt_cache; - - free(cm->dwt_comparator_list); - cm->dwt_comparator_list = NULL; - cm->dwt_num_comp = 0; - - if (cache) { - register_unlink_cache(&target->reg_cache, cache); - - if (cache->reg_list) { - for (size_t i = 0; i < cache->num_regs; i++) - free(cache->reg_list[i].arch_info); - free(cache->reg_list); - } - free(cache); - } - cm->dwt_cache = NULL; -} - -#define MVFR0 0xe000ef40 -#define MVFR1 0xe000ef44 - -#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; - uint32_t cpuid, fpcr, mvfr0, mvfr1; - int i; - struct cortex_m_common *cortex_m = target_to_cm(target); - struct adiv5_dap *swjdp = cortex_m->armv7m.arm.dap; - struct armv7m_common *armv7m = target_to_armv7m(target); - - /* stlink shares the examine handler but does not support - * all its calls */ - if (!armv7m->stlink) { - retval = dap_dp_init(swjdp); - if (retval != ERROR_OK) { - LOG_ERROR("Could not initialize the debug port"); - 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; - } - - /* Leave (only) generic DAP stuff for debugport_init(); */ - armv7m->debug_ap->memaccess_tck = 8; - - retval = mem_ap_init(armv7m->debug_ap); - if (retval != ERROR_OK) - return retval; - } - - if (!target_was_examined(target)) { - target_set_examined(target); - - /* Read from Device Identification Registers */ - retval = target_read_u32(target, CPUID, &cpuid); - if (retval != ERROR_OK) - return retval; - - /* Get CPU Type */ - i = (cpuid >> 4) & 0xf; - - 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); - - 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 == FP_NONE && - armv7m->arm.core_cache->num_regs > ARMV7M_NUM_CORE_REGS_NOFP) { - /* free unavailable FPU registers */ - size_t idx; - - for (idx = ARMV7M_NUM_CORE_REGS_NOFP; - idx < armv7m->arm.core_cache->num_regs; - idx++) { - free(armv7m->arm.core_cache->reg_list[idx].value); - free(armv7m->arm.core_cache->reg_list[idx].feature); - free(armv7m->arm.core_cache->reg_list[idx].reg_data_type); - } - armv7m->arm.core_cache->num_regs = ARMV7M_NUM_CORE_REGS_NOFP; - } - - if ((i == 3 || i == 4 || i == 7) && !armv7m->stlink) { - /* Cortex-M3/M4/M7 have at least 4096 bytes autoincrement range, - * s. ARM IHI 0031C: MEM-AP 7.2.2 */ - armv7m->debug_ap->tar_autoincr_block = (1 << 12); - } - - /* Configure trace modules */ - retval = target_write_u32(target, DCB_DEMCR, TRCENA | armv7m->demcr); - if (retval != ERROR_OK) - return retval; - - if (armv7m->trace_config.config_type != DISABLED) { - armv7m_trace_tpiu_config(target); - armv7m_trace_itm_config(target); - } - - /* NOTE: FPB and DWT are both optional. */ - - /* Setup FPB */ - target_read_u32(target, FP_CTRL, &fpcr); - cortex_m->auto_bp_type = 1; - /* bits [14:12] and [7:4] */ - cortex_m->fp_num_code = ((fpcr >> 8) & 0x70) | ((fpcr >> 4) & 0xF); - cortex_m->fp_num_lit = (fpcr >> 8) & 0xF; - cortex_m->fp_code_available = cortex_m->fp_num_code; - /* Detect flash patch revision, see RM DDI 0403E.b page C1-817. - Revision is zero base, fp_rev == 1 means Rev.2 ! */ - cortex_m->fp_rev = (fpcr >> 28) & 0xf; - free(cortex_m->fp_comparator_list); - cortex_m->fp_comparator_list = calloc( - cortex_m->fp_num_code + cortex_m->fp_num_lit, - sizeof(struct cortex_m_fp_comparator)); - cortex_m->fpb_enabled = fpcr & 1; - for (i = 0; i < cortex_m->fp_num_code + cortex_m->fp_num_lit; i++) { - cortex_m->fp_comparator_list[i].type = - (i < cortex_m->fp_num_code) ? FPCR_CODE : FPCR_LITERAL; - cortex_m->fp_comparator_list[i].fpcr_address = FP_COMP0 + 4 * i; - - /* make sure we clear any breakpoints enabled on the target */ - target_write_u32(target, cortex_m->fp_comparator_list[i].fpcr_address, 0); - } - LOG_DEBUG("FPB fpcr 0x%" PRIx32 ", numcode %i, numlit %i", - fpcr, - cortex_m->fp_num_code, - cortex_m->fp_num_lit); - - /* Setup DWT */ - cortex_m_dwt_free(target); - cortex_m_dwt_setup(cortex_m, target); - - /* These hardware breakpoints only work for code in flash! */ - LOG_INFO("%s: hardware has %d breakpoints, %d watchpoints", - target_name(target), - cortex_m->fp_num_code, - cortex_m->dwt_num_comp); - } - - return ERROR_OK; -} - -static int cortex_m_dcc_read(struct target *target, uint8_t *value, uint8_t *ctrl) -{ - struct armv7m_common *armv7m = target_to_armv7m(target); - uint16_t dcrdr; - uint8_t buf[2]; - int retval; - - retval = mem_ap_read_buf_noincr(armv7m->debug_ap, buf, 2, 1, DCB_DCRDR); - if (retval != ERROR_OK) - return retval; - - dcrdr = target_buffer_get_u16(target, buf); - *ctrl = (uint8_t)dcrdr; - *value = (uint8_t)(dcrdr >> 8); - - LOG_DEBUG("data 0x%x ctrl 0x%x", *value, *ctrl); - - /* write ack back to software dcc register - * signify we have read data */ - if (dcrdr & (1 << 0)) { - target_buffer_set_u16(target, buf, 0); - retval = mem_ap_write_buf_noincr(armv7m->debug_ap, buf, 2, 1, DCB_DCRDR); - if (retval != ERROR_OK) - return retval; - } - - return ERROR_OK; -} - -static int cortex_m_target_request_data(struct target *target, - uint32_t size, uint8_t *buffer) -{ - uint8_t data; - uint8_t ctrl; - uint32_t i; - - for (i = 0; i < (size * 4); i++) { - int retval = cortex_m_dcc_read(target, &data, &ctrl); - if (retval != ERROR_OK) - return retval; - buffer[i] = data; - } - - return ERROR_OK; -} - -static int cortex_m_handle_target_request(void *priv) -{ - struct target *target = priv; - if (!target_was_examined(target)) - return ERROR_OK; - - if (!target->dbg_msg_enabled) - return ERROR_OK; - - if (target->state == TARGET_RUNNING) { - uint8_t data; - uint8_t ctrl; - int retval; - - retval = cortex_m_dcc_read(target, &data, &ctrl); - if (retval != ERROR_OK) - return retval; - - /* check if we have data */ - if (ctrl & (1 << 0)) { - uint32_t request; - - /* we assume target is quick enough */ - request = data; - for (int i = 1; i <= 3; i++) { - retval = cortex_m_dcc_read(target, &data, &ctrl); - if (retval != ERROR_OK) - return retval; - request |= ((uint32_t)data << (i * 8)); - } - target_request(target, request); - } - } - - return ERROR_OK; -} - -static int cortex_m_init_arch_info(struct target *target, - struct cortex_m_common *cortex_m, struct jtag_tap *tap) -{ - struct armv7m_common *armv7m = &cortex_m->armv7m; - - armv7m_init_arch_info(target, armv7m); - - /* tap has no dap initialized */ - if (!tap->dap) { - tap->dap = dap_init(); - - /* Leave (only) generic DAP stuff for debugport_init() */ - tap->dap->tap = tap; - } - - /* default reset mode is to use srst if fitted - * if not it will use CORTEX_M3_RESET_VECTRESET */ - cortex_m->soft_reset_config = CORTEX_M_RESET_VECTRESET; - - armv7m->arm.dap = tap->dap; - - /* register arch-specific functions */ - armv7m->examine_debug_reason = cortex_m_examine_debug_reason; - - armv7m->post_debug_entry = NULL; - - armv7m->pre_restore_context = NULL; - - armv7m->load_core_reg_u32 = cortex_m_load_core_reg_u32; - armv7m->store_core_reg_u32 = cortex_m_store_core_reg_u32; - - target_register_timer_callback(cortex_m_handle_target_request, 1, 1, target); - - return ERROR_OK; -} - -static int cortex_m_target_create(struct target *target, Jim_Interp *interp) -{ - struct cortex_m_common *cortex_m = calloc(1, sizeof(struct cortex_m_common)); - - cortex_m->common_magic = CORTEX_M_COMMON_MAGIC; - cortex_m_init_arch_info(target, cortex_m, target->tap); - - return ERROR_OK; -} - -/*--------------------------------------------------------------------------*/ - -static int cortex_m_verify_pointer(struct command_context *cmd_ctx, - struct cortex_m_common *cm) -{ - if (cm->common_magic != CORTEX_M_COMMON_MAGIC) { - command_print(cmd_ctx, "target is not a Cortex-M"); - return ERROR_TARGET_INVALID; - } - return ERROR_OK; -} - -/* - * Only stuff below this line should need to verify that its target - * is a Cortex-M3. Everything else should have indirected through the - * cortexm3_target structure, which is only used with CM3 targets. - */ - -static const struct { - char name[10]; - unsigned mask; -} vec_ids[] = { - { "hard_err", VC_HARDERR, }, - { "int_err", VC_INTERR, }, - { "bus_err", VC_BUSERR, }, - { "state_err", VC_STATERR, }, - { "chk_err", VC_CHKERR, }, - { "nocp_err", VC_NOCPERR, }, - { "mm_err", VC_MMERR, }, - { "reset", VC_CORERESET, }, -}; - -COMMAND_HANDLER(handle_cortex_m_vector_catch_command) -{ - struct target *target = get_current_target(CMD_CTX); - struct cortex_m_common *cortex_m = target_to_cm(target); - struct armv7m_common *armv7m = &cortex_m->armv7m; - uint32_t demcr = 0; - int retval; - - retval = cortex_m_verify_pointer(CMD_CTX, cortex_m); - if (retval != ERROR_OK) - return retval; - - retval = mem_ap_read_atomic_u32(armv7m->debug_ap, DCB_DEMCR, &demcr); - if (retval != ERROR_OK) - return retval; - - if (CMD_ARGC > 0) { - unsigned catch = 0; - - if (CMD_ARGC == 1) { - if (strcmp(CMD_ARGV[0], "all") == 0) { - catch = VC_HARDERR | VC_INTERR | VC_BUSERR - | VC_STATERR | VC_CHKERR | VC_NOCPERR - | VC_MMERR | VC_CORERESET; - goto write; - } else if (strcmp(CMD_ARGV[0], "none") == 0) - goto write; - } - while (CMD_ARGC-- > 0) { - unsigned i; - for (i = 0; i < ARRAY_SIZE(vec_ids); i++) { - if (strcmp(CMD_ARGV[CMD_ARGC], vec_ids[i].name) != 0) - continue; - catch |= vec_ids[i].mask; - break; - } - if (i == ARRAY_SIZE(vec_ids)) { - LOG_ERROR("No CM3 vector '%s'", CMD_ARGV[CMD_ARGC]); - return ERROR_COMMAND_SYNTAX_ERROR; - } - } -write: - /* For now, armv7m->demcr only stores vector catch flags. */ - armv7m->demcr = catch; - - demcr &= ~0xffff; - demcr |= catch; - - /* write, but don't assume it stuck (why not??) */ - retval = mem_ap_write_u32(armv7m->debug_ap, DCB_DEMCR, demcr); - if (retval != ERROR_OK) - return retval; - retval = mem_ap_read_atomic_u32(armv7m->debug_ap, DCB_DEMCR, &demcr); - if (retval != ERROR_OK) - return retval; - - /* FIXME be sure to clear DEMCR on clean server shutdown. - * Otherwise the vector catch hardware could fire when there's - * no debugger hooked up, causing much confusion... - */ - } - - for (unsigned i = 0; i < ARRAY_SIZE(vec_ids); i++) { - command_print(CMD_CTX, "%9s: %s", vec_ids[i].name, - (demcr & vec_ids[i].mask) ? "catch" : "ignore"); - } - - return ERROR_OK; -} - -COMMAND_HANDLER(handle_cortex_m_mask_interrupts_command) -{ - struct target *target = get_current_target(CMD_CTX); - struct cortex_m_common *cortex_m = target_to_cm(target); - int retval; - - static const Jim_Nvp nvp_maskisr_modes[] = { - { .name = "auto", .value = CORTEX_M_ISRMASK_AUTO }, - { .name = "off", .value = CORTEX_M_ISRMASK_OFF }, - { .name = "on", .value = CORTEX_M_ISRMASK_ON }, - { .name = NULL, .value = -1 }, - }; - const Jim_Nvp *n; - - - retval = cortex_m_verify_pointer(CMD_CTX, cortex_m); - if (retval != ERROR_OK) - return retval; - - 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) - return ERROR_COMMAND_SYNTAX_ERROR; - cortex_m->isrmasking_mode = n->value; - - - if (cortex_m->isrmasking_mode == CORTEX_M_ISRMASK_ON) - cortex_m_write_debug_halt_mask(target, C_HALT | C_MASKINTS, 0); - else - cortex_m_write_debug_halt_mask(target, C_HALT, C_MASKINTS); - } - - n = Jim_Nvp_value2name_simple(nvp_maskisr_modes, cortex_m->isrmasking_mode); - command_print(CMD_CTX, "cortex_m interrupt mask %s", n->name); - - return ERROR_OK; -} - -COMMAND_HANDLER(handle_cortex_m_reset_config_command) -{ - struct target *target = get_current_target(CMD_CTX); - struct cortex_m_common *cortex_m = target_to_cm(target); - int retval; - char *reset_config; - - retval = cortex_m_verify_pointer(CMD_CTX, cortex_m); - if (retval != ERROR_OK) - return retval; - - if (CMD_ARGC > 0) { - if (strcmp(*CMD_ARGV, "sysresetreq") == 0) - cortex_m->soft_reset_config = CORTEX_M_RESET_SYSRESETREQ; - else if (strcmp(*CMD_ARGV, "vectreset") == 0) - cortex_m->soft_reset_config = CORTEX_M_RESET_VECTRESET; - } - - switch (cortex_m->soft_reset_config) { - case CORTEX_M_RESET_SYSRESETREQ: - reset_config = "sysresetreq"; - break; - - case CORTEX_M_RESET_VECTRESET: - reset_config = "vectreset"; - break; - - default: - reset_config = "unknown"; - break; - } - - command_print(CMD_CTX, "cortex_m reset_config %s", reset_config); - - return ERROR_OK; -} - -static const struct command_registration cortex_m_exec_command_handlers[] = { - { - .name = "maskisr", - .handler = handle_cortex_m_mask_interrupts_command, - .mode = COMMAND_EXEC, - .help = "mask cortex_m interrupts", - .usage = "['auto'|'on'|'off']", - }, - { - .name = "vector_catch", - .handler = handle_cortex_m_vector_catch_command, - .mode = COMMAND_EXEC, - .help = "configure hardware vectors to trigger debug entry", - .usage = "['all'|'none'|('bus_err'|'chk_err'|...)*]", - }, - { - .name = "reset_config", - .handler = handle_cortex_m_reset_config_command, - .mode = COMMAND_ANY, - .help = "configure software reset handling", - .usage = "['srst'|'sysresetreq'|'vectreset']", - }, - COMMAND_REGISTRATION_DONE -}; -static const struct command_registration cortex_m_command_handlers[] = { - { - .chain = armv7m_command_handlers, - }, - { - .chain = armv7m_trace_command_handlers, - }, - { - .name = "cortex_m", - .mode = COMMAND_EXEC, - .help = "Cortex-M command group", - .usage = "", - .chain = cortex_m_exec_command_handlers, - }, - COMMAND_REGISTRATION_DONE -}; - -struct target_type cortexm_target = { - .name = "cortex_m", - .deprecated_name = "cortex_m3", - - .poll = cortex_m_poll, - .arch_state = armv7m_arch_state, - - .target_request_data = cortex_m_target_request_data, - - .halt = cortex_m_halt, - .resume = cortex_m_resume, - .step = cortex_m_step, - - .assert_reset = cortex_m_assert_reset, - .deassert_reset = cortex_m_deassert_reset, - .soft_reset_halt = cortex_m_soft_reset_halt, - - .get_gdb_reg_list = armv7m_get_gdb_reg_list, - - .read_memory = cortex_m_read_memory, - .write_memory = cortex_m_write_memory, - .checksum_memory = armv7m_checksum_memory, - .blank_check_memory = armv7m_blank_check_memory, - - .run_algorithm = armv7m_run_algorithm, - .start_algorithm = armv7m_start_algorithm, - .wait_algorithm = armv7m_wait_algorithm, - - .add_breakpoint = cortex_m_add_breakpoint, - .remove_breakpoint = cortex_m_remove_breakpoint, - .add_watchpoint = cortex_m_add_watchpoint, - .remove_watchpoint = cortex_m_remove_watchpoint, - - .commands = cortex_m_command_handlers, - .target_create = cortex_m_target_create, - .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 deleted file mode 100644 index eabaac49f..000000000 --- a/src/target/cortex_m.h +++ /dev/null @@ -1,214 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * Copyright (C) 2006 by Magnus Lundin * - * lundin@mlu.mine.nu * - * * - * Copyright (C) 2008 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifndef OPENOCD_TARGET_CORTEX_M_H -#define OPENOCD_TARGET_CORTEX_M_H - -#include "armv7m.h" - -#define CORTEX_M_COMMON_MAGIC 0x1A451A45 - -#define SYSTEM_CONTROL_BASE 0x400FE000 - -#define ITM_TER0 0xE0000E00 -#define ITM_TPR 0xE0000E40 -#define ITM_TCR 0xE0000E80 -#define ITM_LAR 0xE0000FB0 -#define ITM_LAR_KEY 0xC5ACCE55 - -#define CPUID 0xE000ED00 -/* Debug Control Block */ -#define DCB_DHCSR 0xE000EDF0 -#define DCB_DCRSR 0xE000EDF4 -#define DCB_DCRDR 0xE000EDF8 -#define DCB_DEMCR 0xE000EDFC - -#define DCRSR_WnR (1 << 16) - -#define DWT_CTRL 0xE0001000 -#define DWT_CYCCNT 0xE0001004 -#define DWT_COMP0 0xE0001020 -#define DWT_MASK0 0xE0001024 -#define DWT_FUNCTION0 0xE0001028 - -#define FP_CTRL 0xE0002000 -#define FP_REMAP 0xE0002004 -#define FP_COMP0 0xE0002008 -#define FP_COMP1 0xE000200C -#define FP_COMP2 0xE0002010 -#define FP_COMP3 0xE0002014 -#define FP_COMP4 0xE0002018 -#define FP_COMP5 0xE000201C -#define FP_COMP6 0xE0002020 -#define FP_COMP7 0xE0002024 - -#define FPU_CPACR 0xE000ED88 -#define FPU_FPCCR 0xE000EF34 -#define FPU_FPCAR 0xE000EF38 -#define FPU_FPDSCR 0xE000EF3C - -#define TPIU_SSPSR 0xE0040000 -#define TPIU_CSPSR 0xE0040004 -#define TPIU_ACPR 0xE0040010 -#define TPIU_SPPR 0xE00400F0 -#define TPIU_FFSR 0xE0040300 -#define TPIU_FFCR 0xE0040304 -#define TPIU_FSCR 0xE0040308 - -/* DCB_DHCSR bit and field definitions */ -#define DBGKEY (0xA05F << 16) -#define C_DEBUGEN (1 << 0) -#define C_HALT (1 << 1) -#define C_STEP (1 << 2) -#define C_MASKINTS (1 << 3) -#define S_REGRDY (1 << 16) -#define S_HALT (1 << 17) -#define S_SLEEP (1 << 18) -#define S_LOCKUP (1 << 19) -#define S_RETIRE_ST (1 << 24) -#define S_RESET_ST (1 << 25) - -/* DCB_DEMCR bit and field definitions */ -#define TRCENA (1 << 24) -#define VC_HARDERR (1 << 10) -#define VC_INTERR (1 << 9) -#define VC_BUSERR (1 << 8) -#define VC_STATERR (1 << 7) -#define VC_CHKERR (1 << 6) -#define VC_NOCPERR (1 << 5) -#define VC_MMERR (1 << 4) -#define VC_CORERESET (1 << 0) - -#define NVIC_ICTR 0xE000E004 -#define NVIC_ISE0 0xE000E100 -#define NVIC_ICSR 0xE000ED04 -#define NVIC_AIRCR 0xE000ED0C -#define NVIC_SHCSR 0xE000ED24 -#define NVIC_CFSR 0xE000ED28 -#define NVIC_MMFSRb 0xE000ED28 -#define NVIC_BFSRb 0xE000ED29 -#define NVIC_USFSRh 0xE000ED2A -#define NVIC_HFSR 0xE000ED2C -#define NVIC_DFSR 0xE000ED30 -#define NVIC_MMFAR 0xE000ED34 -#define NVIC_BFAR 0xE000ED38 - -/* NVIC_AIRCR bits */ -#define AIRCR_VECTKEY (0x5FA << 16) -#define AIRCR_SYSRESETREQ (1 << 2) -#define AIRCR_VECTCLRACTIVE (1 << 1) -#define AIRCR_VECTRESET (1 << 0) -/* NVIC_SHCSR bits */ -#define SHCSR_BUSFAULTENA (1 << 17) -/* NVIC_DFSR bits */ -#define DFSR_HALTED 1 -#define DFSR_BKPT 2 -#define DFSR_DWTTRAP 4 -#define DFSR_VCATCH 8 - -#define FPCR_CODE 0 -#define FPCR_LITERAL 1 -#define FPCR_REPLACE_REMAP (0 << 30) -#define FPCR_REPLACE_BKPT_LOW (1 << 30) -#define FPCR_REPLACE_BKPT_HIGH (2 << 30) -#define FPCR_REPLACE_BKPT_BOTH (3 << 30) - -struct cortex_m_fp_comparator { - int used; - int type; - uint32_t fpcr_value; - uint32_t fpcr_address; -}; - -struct cortex_m_dwt_comparator { - int used; - uint32_t comp; - uint32_t mask; - uint32_t function; - uint32_t dwt_comparator_address; -}; - -enum cortex_m_soft_reset_config { - CORTEX_M_RESET_SYSRESETREQ, - CORTEX_M_RESET_VECTRESET, -}; - -enum cortex_m_isrmasking_mode { - CORTEX_M_ISRMASK_AUTO, - CORTEX_M_ISRMASK_OFF, - CORTEX_M_ISRMASK_ON, -}; - -struct cortex_m_common { - int common_magic; - - /* Context information */ - uint32_t dcb_dhcsr; - uint32_t nvic_dfsr; /* Debug Fault Status Register - shows reason for debug halt */ - uint32_t nvic_icsr; /* Interrupt Control State Register - shows active and pending IRQ */ - - /* Flash Patch and Breakpoint (FPB) */ - int fp_num_lit; - int fp_num_code; - int fp_code_available; - int fp_rev; - int fpb_enabled; - int auto_bp_type; - struct cortex_m_fp_comparator *fp_comparator_list; - - /* Data Watchpoint and Trace (DWT) */ - int dwt_num_comp; - int dwt_comp_available; - struct cortex_m_dwt_comparator *dwt_comparator_list; - struct reg_cache *dwt_cache; - - enum cortex_m_soft_reset_config soft_reset_config; - - enum cortex_m_isrmasking_mode isrmasking_mode; - - struct armv7m_common armv7m; -}; - -static inline struct cortex_m_common * -target_to_cm(struct target *target) -{ - return container_of(target->arch_info, - struct cortex_m_common, armv7m); -} - -int cortex_m_examine(struct target *target); -int cortex_m_set_breakpoint(struct target *target, struct breakpoint *breakpoint); -int cortex_m_unset_breakpoint(struct target *target, struct breakpoint *breakpoint); -int cortex_m_add_breakpoint(struct target *target, struct breakpoint *breakpoint); -int cortex_m_remove_breakpoint(struct target *target, struct breakpoint *breakpoint); -int cortex_m_set_watchpoint(struct target *target, struct watchpoint *watchpoint); -int cortex_m_unset_watchpoint(struct target *target, struct watchpoint *watchpoint); -int cortex_m_add_watchpoint(struct target *target, struct watchpoint *watchpoint); -int cortex_m_remove_watchpoint(struct target *target, struct watchpoint *watchpoint); -void cortex_m_enable_breakpoints(struct target *target); -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 /* OPENOCD_TARGET_CORTEX_M_H */ diff --git a/src/target/dsp563xx.c b/src/target/dsp563xx.c deleted file mode 100644 index 783a0198c..000000000 --- a/src/target/dsp563xx.c +++ /dev/null @@ -1,2339 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2009-2011 by Mathias Kuester * - * mkdorg@users.sourceforge.net * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include - -#include "target.h" -#include "breakpoints.h" -#include "target_type.h" -#include "algorithm.h" -#include "register.h" -#include "dsp563xx.h" -#include "dsp563xx_once.h" - -#define ASM_REG_W_R0 0x60F400 -#define ASM_REG_W_R1 0x61F400 -#define ASM_REG_W_R2 0x62F400 -#define ASM_REG_W_R3 0x63F400 -#define ASM_REG_W_R4 0x64F400 -#define ASM_REG_W_R5 0x65F400 -#define ASM_REG_W_R6 0x66F400 -#define ASM_REG_W_R7 0x67F400 - -#define ASM_REG_W_N0 0x70F400 -#define ASM_REG_W_N1 0x71F400 -#define ASM_REG_W_N2 0x72F400 -#define ASM_REG_W_N3 0x73F400 -#define ASM_REG_W_N4 0x74F400 -#define ASM_REG_W_N5 0x75F400 -#define ASM_REG_W_N6 0x76F400 -#define ASM_REG_W_N7 0x77F400 - -#define ASM_REG_W_M0 0x05F420 -#define ASM_REG_W_M1 0x05F421 -#define ASM_REG_W_M2 0x05F422 -#define ASM_REG_W_M3 0x05F423 -#define ASM_REG_W_M4 0x05F424 -#define ASM_REG_W_M5 0x05F425 -#define ASM_REG_W_M6 0x05F426 -#define ASM_REG_W_M7 0x05F427 - -#define ASM_REG_W_X0 0x44F400 -#define ASM_REG_W_X1 0x45F400 - -#define ASM_REG_W_Y0 0x46F400 -#define ASM_REG_W_Y1 0x47F400 - -#define ASM_REG_W_A0 0x50F400 -#define ASM_REG_W_A1 0x54F400 -#define ASM_REG_W_A2 0x52F400 - -#define ASM_REG_W_B0 0x51F400 -#define ASM_REG_W_B1 0x55F400 -#define ASM_REG_W_B2 0x53F400 - -#define ASM_REG_W_VBA 0x05F430 -#define ASM_REG_W_OMR 0x05F43A -#define ASM_REG_W_EP 0x05F42A -#define ASM_REG_W_SC 0x05F431 -#define ASM_REG_W_SZ 0x05F438 -#define ASM_REG_W_SR 0x05F439 -#define ASM_REG_W_SP 0x05F43B -#define ASM_REG_W_SSH 0x05F43C -#define ASM_REG_W_SSL 0x05F43D -#define ASM_REG_W_LA 0x05F43E -#define ASM_REG_W_LC 0x05F43F -#define ASM_REG_W_PC 0x000000 -#define ASM_REG_W_IPRC 0xFFFFFF -#define ASM_REG_W_IPRP 0xFFFFFE - -#define ASM_REG_W_BCR 0xFFFFFB -#define ASM_REG_W_DCR 0xFFFFFA -#define ASM_REG_W_AAR0 0xFFFFF9 -#define ASM_REG_W_AAR1 0xFFFFF8 -#define ASM_REG_W_AAR2 0xFFFFF7 -#define ASM_REG_W_AAR3 0xFFFFF6 - -/* - * OBCR Register bit definitions - */ -#define OBCR_b0_and_b1 ((0x0) << 10) -#define OBCR_b0_or_b1 ((0x1) << 10) -#define OBCR_b1_after_b0 ((0x2) << 10) -#define OBCR_b0_after_b1 ((0x3) << 10) - -#define OBCR_BP_DISABLED (0x0) -#define OBCR_BP_MEM_P (0x1) -#define OBCR_BP_MEM_X (0x2) -#define OBCR_BP_MEM_Y (0x3) -#define OBCR_BP_ON_READ ((0x2) << 0) -#define OBCR_BP_ON_WRITE ((0x1) << 0) -#define OBCR_BP_CC_NOT_EQUAL ((0x0) << 2) -#define OBCR_BP_CC_EQUAL ((0x1) << 2) -#define OBCR_BP_CC_LESS_THAN ((0x2) << 2) -#define OBCR_BP_CC_GREATER_THAN ((0x3) << 2) - -#define OBCR_BP_0(x) ((x)<<2) -#define OBCR_BP_1(x) ((x)<<6) - - -enum once_reg_idx { - ONCE_REG_IDX_OSCR = 0, - ONCE_REG_IDX_OMBC = 1, - ONCE_REG_IDX_OBCR = 2, - ONCE_REG_IDX_OMLR0 = 3, - ONCE_REG_IDX_OMLR1 = 4, - ONCE_REG_IDX_OGDBR = 5, - ONCE_REG_IDX_OPDBR = 6, - ONCE_REG_IDX_OPILR = 7, - ONCE_REG_IDX_PDB = 8, - ONCE_REG_IDX_OTC = 9, - ONCE_REG_IDX_OPABFR = 10, - ONCE_REG_IDX_OPABDR = 11, - ONCE_REG_IDX_OPABEX = 12, - ONCE_REG_IDX_OPABF0 = 13, - ONCE_REG_IDX_OPABF1 = 14, - ONCE_REG_IDX_OPABF2 = 15, - ONCE_REG_IDX_OPABF3 = 16, - ONCE_REG_IDX_OPABF4 = 17, - ONCE_REG_IDX_OPABF5 = 18, - ONCE_REG_IDX_OPABF6 = 19, - ONCE_REG_IDX_OPABF7 = 20, - ONCE_REG_IDX_OPABF8 = 21, - ONCE_REG_IDX_OPABF9 = 22, - ONCE_REG_IDX_OPABF10 = 23, - ONCE_REG_IDX_OPABF11 = 24, -}; - -static struct once_reg once_regs[] = { - {ONCE_REG_IDX_OSCR, DSP563XX_ONCE_OSCR, 24, "OSCR", 0}, - {ONCE_REG_IDX_OMBC, DSP563XX_ONCE_OMBC, 24, "OMBC", 0}, - {ONCE_REG_IDX_OBCR, DSP563XX_ONCE_OBCR, 24, "OBCR", 0}, - {ONCE_REG_IDX_OMLR0, DSP563XX_ONCE_OMLR0, 24, "OMLR0", 0}, - {ONCE_REG_IDX_OMLR1, DSP563XX_ONCE_OMLR1, 24, "OMLR1", 0}, - {ONCE_REG_IDX_OGDBR, DSP563XX_ONCE_OGDBR, 24, "OGDBR", 0}, - {ONCE_REG_IDX_OPDBR, DSP563XX_ONCE_OPDBR, 24, "OPDBR", 0}, - {ONCE_REG_IDX_OPILR, DSP563XX_ONCE_OPILR, 24, "OPILR", 0}, - {ONCE_REG_IDX_PDB, DSP563XX_ONCE_PDBGOTO, 24, "PDB", 0}, - {ONCE_REG_IDX_OTC, DSP563XX_ONCE_OTC, 24, "OTC", 0}, - {ONCE_REG_IDX_OPABFR, DSP563XX_ONCE_OPABFR, 24, "OPABFR", 0}, - {ONCE_REG_IDX_OPABDR, DSP563XX_ONCE_OPABDR, 24, "OPABDR", 0}, - {ONCE_REG_IDX_OPABEX, DSP563XX_ONCE_OPABEX, 24, "OPABEX", 0}, - {ONCE_REG_IDX_OPABF0, DSP563XX_ONCE_OPABF11, 25, "OPABF0", 0}, - {ONCE_REG_IDX_OPABF1, DSP563XX_ONCE_OPABF11, 25, "OPABF1", 0}, - {ONCE_REG_IDX_OPABF2, DSP563XX_ONCE_OPABF11, 25, "OPABF2", 0}, - {ONCE_REG_IDX_OPABF3, DSP563XX_ONCE_OPABF11, 25, "OPABF3", 0}, - {ONCE_REG_IDX_OPABF4, DSP563XX_ONCE_OPABF11, 25, "OPABF4", 0}, - {ONCE_REG_IDX_OPABF5, DSP563XX_ONCE_OPABF11, 25, "OPABF5", 0}, - {ONCE_REG_IDX_OPABF6, DSP563XX_ONCE_OPABF11, 25, "OPABF6", 0}, - {ONCE_REG_IDX_OPABF7, DSP563XX_ONCE_OPABF11, 25, "OPABF7", 0}, - {ONCE_REG_IDX_OPABF8, DSP563XX_ONCE_OPABF11, 25, "OPABF8", 0}, - {ONCE_REG_IDX_OPABF9, DSP563XX_ONCE_OPABF11, 25, "OPABF9", 0}, - {ONCE_REG_IDX_OPABF10, DSP563XX_ONCE_OPABF11, 25, "OPABF10", 0}, - {ONCE_REG_IDX_OPABF11, DSP563XX_ONCE_OPABF11, 25, "OPABF11", 0}, -/* {25,0x1f,24,"NRSEL",0}, */ -}; - -enum dsp563xx_reg_idx { - DSP563XX_REG_IDX_R0 = 0, - DSP563XX_REG_IDX_R1 = 1, - DSP563XX_REG_IDX_R2 = 2, - DSP563XX_REG_IDX_R3 = 3, - DSP563XX_REG_IDX_R4 = 4, - DSP563XX_REG_IDX_R5 = 5, - DSP563XX_REG_IDX_R6 = 6, - DSP563XX_REG_IDX_R7 = 7, - DSP563XX_REG_IDX_N0 = 8, - DSP563XX_REG_IDX_N1 = 9, - DSP563XX_REG_IDX_N2 = 10, - DSP563XX_REG_IDX_N3 = 11, - DSP563XX_REG_IDX_N4 = 12, - DSP563XX_REG_IDX_N5 = 13, - DSP563XX_REG_IDX_N6 = 14, - DSP563XX_REG_IDX_N7 = 15, - DSP563XX_REG_IDX_M0 = 16, - DSP563XX_REG_IDX_M1 = 17, - DSP563XX_REG_IDX_M2 = 18, - DSP563XX_REG_IDX_M3 = 19, - DSP563XX_REG_IDX_M4 = 20, - DSP563XX_REG_IDX_M5 = 21, - DSP563XX_REG_IDX_M6 = 22, - DSP563XX_REG_IDX_M7 = 23, - DSP563XX_REG_IDX_X0 = 24, - DSP563XX_REG_IDX_X1 = 25, - DSP563XX_REG_IDX_Y0 = 26, - DSP563XX_REG_IDX_Y1 = 27, - DSP563XX_REG_IDX_A0 = 28, - DSP563XX_REG_IDX_A1 = 29, - DSP563XX_REG_IDX_A2 = 30, - DSP563XX_REG_IDX_B0 = 31, - DSP563XX_REG_IDX_B1 = 32, - DSP563XX_REG_IDX_B2 = 33, - DSP563XX_REG_IDX_SSH = 34, - DSP563XX_REG_IDX_SSL = 35, - DSP563XX_REG_IDX_SP = 36, - DSP563XX_REG_IDX_EP = 37, - DSP563XX_REG_IDX_SZ = 38, - DSP563XX_REG_IDX_SC = 39, - DSP563XX_REG_IDX_PC = 40, - DSP563XX_REG_IDX_SR = 41, - DSP563XX_REG_IDX_OMR = 42, - DSP563XX_REG_IDX_LA = 43, - DSP563XX_REG_IDX_LC = 44, - DSP563XX_REG_IDX_VBA = 45, - DSP563XX_REG_IDX_IPRC = 46, - DSP563XX_REG_IDX_IPRP = 47, - DSP563XX_REG_IDX_BCR = 48, - DSP563XX_REG_IDX_DCR = 49, - DSP563XX_REG_IDX_AAR0 = 50, - DSP563XX_REG_IDX_AAR1 = 51, - DSP563XX_REG_IDX_AAR2 = 52, - DSP563XX_REG_IDX_AAR3 = 53, -}; - -static const struct { - unsigned id; - const char *name; - unsigned bits; - /* effective addressing mode encoding */ - uint8_t eame; - uint32_t instr_mask; -} dsp563xx_regs[] = { - /* *INDENT-OFF* */ - /* address registers */ - {DSP563XX_REG_IDX_R0, "r0", 24, 0x10, ASM_REG_W_R0}, - {DSP563XX_REG_IDX_R1, "r1", 24, 0x11, ASM_REG_W_R1}, - {DSP563XX_REG_IDX_R2, "r2", 24, 0x12, ASM_REG_W_R2}, - {DSP563XX_REG_IDX_R3, "r3", 24, 0x13, ASM_REG_W_R3}, - {DSP563XX_REG_IDX_R4, "r4", 24, 0x14, ASM_REG_W_R4}, - {DSP563XX_REG_IDX_R5, "r5", 24, 0x15, ASM_REG_W_R5}, - {DSP563XX_REG_IDX_R6, "r6", 24, 0x16, ASM_REG_W_R6}, - {DSP563XX_REG_IDX_R7, "r7", 24, 0x17, ASM_REG_W_R7}, - /* offset registers */ - {DSP563XX_REG_IDX_N0, "n0", 24, 0x18, ASM_REG_W_N0}, - {DSP563XX_REG_IDX_N1, "n1", 24, 0x19, ASM_REG_W_N1}, - {DSP563XX_REG_IDX_N2, "n2", 24, 0x1a, ASM_REG_W_N2}, - {DSP563XX_REG_IDX_N3, "n3", 24, 0x1b, ASM_REG_W_N3}, - {DSP563XX_REG_IDX_N4, "n4", 24, 0x1c, ASM_REG_W_N4}, - {DSP563XX_REG_IDX_N5, "n5", 24, 0x1d, ASM_REG_W_N5}, - {DSP563XX_REG_IDX_N6, "n6", 24, 0x1e, ASM_REG_W_N6}, - {DSP563XX_REG_IDX_N7, "n7", 24, 0x1f, ASM_REG_W_N7}, - /* modifier registers */ - {DSP563XX_REG_IDX_M0, "m0", 24, 0x20, ASM_REG_W_M0}, - {DSP563XX_REG_IDX_M1, "m1", 24, 0x21, ASM_REG_W_M1}, - {DSP563XX_REG_IDX_M2, "m2", 24, 0x22, ASM_REG_W_M2}, - {DSP563XX_REG_IDX_M3, "m3", 24, 0x23, ASM_REG_W_M3}, - {DSP563XX_REG_IDX_M4, "m4", 24, 0x24, ASM_REG_W_M4}, - {DSP563XX_REG_IDX_M5, "m5", 24, 0x25, ASM_REG_W_M5}, - {DSP563XX_REG_IDX_M6, "m6", 24, 0x26, ASM_REG_W_M6}, - {DSP563XX_REG_IDX_M7, "m7", 24, 0x27, ASM_REG_W_M7}, - /* data alu input register */ - {DSP563XX_REG_IDX_X0, "x0", 24, 0x04, ASM_REG_W_X0}, - {DSP563XX_REG_IDX_X1, "x1", 24, 0x05, ASM_REG_W_X1}, - {DSP563XX_REG_IDX_Y0, "y0", 24, 0x06, ASM_REG_W_Y0}, - {DSP563XX_REG_IDX_Y1, "y1", 24, 0x07, ASM_REG_W_Y1}, - /* data alu accumulator register */ - {DSP563XX_REG_IDX_A0, "a0", 24, 0x08, ASM_REG_W_A0}, - {DSP563XX_REG_IDX_A1, "a1", 24, 0x0c, ASM_REG_W_A1}, - {DSP563XX_REG_IDX_A2, "a2", 8, 0x0a, ASM_REG_W_A2}, - {DSP563XX_REG_IDX_B0, "b0", 24, 0x09, ASM_REG_W_B0}, - {DSP563XX_REG_IDX_B1, "b1", 24, 0x0d, ASM_REG_W_B1}, - {DSP563XX_REG_IDX_B2, "b2", 8, 0x0b, ASM_REG_W_B2}, - /* stack */ - {DSP563XX_REG_IDX_SSH, "ssh", 24, 0x3c, ASM_REG_W_SSH}, - {DSP563XX_REG_IDX_SSL, "ssl", 24, 0x3d, ASM_REG_W_SSL}, - {DSP563XX_REG_IDX_SP, "sp", 24, 0x3b, ASM_REG_W_SP}, - {DSP563XX_REG_IDX_EP, "ep", 24, 0x2a, ASM_REG_W_EP}, - {DSP563XX_REG_IDX_SZ, "sz", 24, 0x38, ASM_REG_W_SZ}, - {DSP563XX_REG_IDX_SC, "sc", 24, 0x31, ASM_REG_W_SC}, - /* system */ - {DSP563XX_REG_IDX_PC, "pc", 24, 0x00, ASM_REG_W_PC}, - {DSP563XX_REG_IDX_SR, "sr", 24, 0x39, ASM_REG_W_SR}, - {DSP563XX_REG_IDX_OMR, "omr", 24, 0x3a, ASM_REG_W_OMR}, - {DSP563XX_REG_IDX_LA, "la", 24, 0x3e, ASM_REG_W_LA}, - {DSP563XX_REG_IDX_LC, "lc", 24, 0x3f, ASM_REG_W_LC}, - /* interrupt */ - {DSP563XX_REG_IDX_VBA, "vba", 24, 0x30, ASM_REG_W_VBA}, - {DSP563XX_REG_IDX_IPRC, "iprc", 24, 0x00, ASM_REG_W_IPRC}, - {DSP563XX_REG_IDX_IPRP, "iprp", 24, 0x00, ASM_REG_W_IPRP}, - /* port a */ - {DSP563XX_REG_IDX_BCR, "bcr", 24, 0x00, ASM_REG_W_BCR}, - {DSP563XX_REG_IDX_DCR, "dcr", 24, 0x00, ASM_REG_W_DCR}, - {DSP563XX_REG_IDX_AAR0, "aar0", 24, 0x00, ASM_REG_W_AAR0}, - {DSP563XX_REG_IDX_AAR1, "aar1", 24, 0x00, ASM_REG_W_AAR1}, - {DSP563XX_REG_IDX_AAR2, "aar2", 24, 0x00, ASM_REG_W_AAR2}, - {DSP563XX_REG_IDX_AAR3, "aar3", 24, 0x00, ASM_REG_W_AAR3}, - /* *INDENT-ON* */ -}; - -enum memory_type { - MEM_X = 0, - MEM_Y = 1, - MEM_P = 2, - MEM_L = 3, -}; - -enum watchpoint_condition { - EQUAL, - NOT_EQUAL, - GREATER, - LESS_THAN -}; - -#define INSTR_JUMP 0x0AF080 -/* Effective Addressing Mode Encoding */ -#define EAME_R0 0x10 -/* instrcution encoder */ -/* movep - * s - peripheral space X/Y (X=0,Y=1) - * w - write/read - * d - source/destination register - * p - IO short address - */ -#define INSTR_MOVEP_REG_HIO(s, w, d, p) (0x084000 | \ - ((s & 1) << 16) | ((w & 1) << 15) | ((d & 0x3f) << 8) | (p & 0x3f)) - -/* the gdb register list is send in this order */ -static const uint8_t gdb_reg_list_idx[] = { - DSP563XX_REG_IDX_X1, DSP563XX_REG_IDX_X0, DSP563XX_REG_IDX_Y1, DSP563XX_REG_IDX_Y0, - DSP563XX_REG_IDX_A2, DSP563XX_REG_IDX_A1, DSP563XX_REG_IDX_A0, DSP563XX_REG_IDX_B2, - DSP563XX_REG_IDX_B1, DSP563XX_REG_IDX_B0, DSP563XX_REG_IDX_PC, DSP563XX_REG_IDX_SR, - DSP563XX_REG_IDX_OMR, DSP563XX_REG_IDX_LA, DSP563XX_REG_IDX_LC, DSP563XX_REG_IDX_SSH, - DSP563XX_REG_IDX_SSL, DSP563XX_REG_IDX_SP, DSP563XX_REG_IDX_EP, DSP563XX_REG_IDX_SZ, - DSP563XX_REG_IDX_SC, DSP563XX_REG_IDX_VBA, DSP563XX_REG_IDX_IPRC, DSP563XX_REG_IDX_IPRP, - DSP563XX_REG_IDX_BCR, DSP563XX_REG_IDX_DCR, DSP563XX_REG_IDX_AAR0, DSP563XX_REG_IDX_AAR1, - DSP563XX_REG_IDX_AAR2, DSP563XX_REG_IDX_AAR3, DSP563XX_REG_IDX_R0, DSP563XX_REG_IDX_R1, - DSP563XX_REG_IDX_R2, DSP563XX_REG_IDX_R3, DSP563XX_REG_IDX_R4, DSP563XX_REG_IDX_R5, - DSP563XX_REG_IDX_R6, DSP563XX_REG_IDX_R7, DSP563XX_REG_IDX_N0, DSP563XX_REG_IDX_N1, - DSP563XX_REG_IDX_N2, DSP563XX_REG_IDX_N3, DSP563XX_REG_IDX_N4, DSP563XX_REG_IDX_N5, - DSP563XX_REG_IDX_N6, DSP563XX_REG_IDX_N7, DSP563XX_REG_IDX_M0, DSP563XX_REG_IDX_M1, - DSP563XX_REG_IDX_M2, DSP563XX_REG_IDX_M3, DSP563XX_REG_IDX_M4, DSP563XX_REG_IDX_M5, - DSP563XX_REG_IDX_M6, DSP563XX_REG_IDX_M7, -}; - -static int dsp563xx_get_gdb_reg_list(struct target *target, - struct reg **reg_list[], - int *reg_list_size, - enum target_register_class reg_class) -{ - int i; - struct dsp563xx_common *dsp563xx = target_to_dsp563xx(target); - - if (target->state != TARGET_HALTED) - return ERROR_TARGET_NOT_HALTED; - - *reg_list_size = DSP563XX_NUMCOREREGS; - *reg_list = malloc(sizeof(struct reg *) * (*reg_list_size)); - - if (!*reg_list) - return ERROR_COMMAND_SYNTAX_ERROR; - - for (i = 0; i < DSP563XX_NUMCOREREGS; i++) - (*reg_list)[i] = &dsp563xx->core_cache->reg_list[gdb_reg_list_idx[i]]; - - return ERROR_OK; - -} - -static int dsp563xx_read_core_reg(struct target *target, int num) -{ - uint32_t reg_value; - struct dsp563xx_common *dsp563xx = target_to_dsp563xx(target); - - if ((num < 0) || (num >= DSP563XX_NUMCOREREGS)) - return ERROR_COMMAND_SYNTAX_ERROR; - - reg_value = dsp563xx->core_regs[num]; - buf_set_u32(dsp563xx->core_cache->reg_list[num].value, 0, 32, reg_value); - dsp563xx->core_cache->reg_list[num].valid = 1; - dsp563xx->core_cache->reg_list[num].dirty = 0; - - return ERROR_OK; -} - -static int dsp563xx_write_core_reg(struct target *target, int num) -{ - uint32_t reg_value; - struct dsp563xx_common *dsp563xx = target_to_dsp563xx(target); - - if ((num < 0) || (num >= DSP563XX_NUMCOREREGS)) - return ERROR_COMMAND_SYNTAX_ERROR; - - reg_value = buf_get_u32(dsp563xx->core_cache->reg_list[num].value, 0, 32); - dsp563xx->core_regs[num] = reg_value; - dsp563xx->core_cache->reg_list[num].valid = 1; - dsp563xx->core_cache->reg_list[num].dirty = 0; - - return ERROR_OK; -} - -static int dsp563xx_get_core_reg(struct reg *reg) -{ - struct dsp563xx_core_reg *dsp563xx_reg = reg->arch_info; - struct target *target = dsp563xx_reg->target; - struct dsp563xx_common *dsp563xx = target_to_dsp563xx(target); - - LOG_DEBUG("%s", __func__); - - if (target->state != TARGET_HALTED) - return ERROR_TARGET_NOT_HALTED; - - return dsp563xx->read_core_reg(target, dsp563xx_reg->num); -} - -static int dsp563xx_set_core_reg(struct reg *reg, uint8_t *buf) -{ - LOG_DEBUG("%s", __func__); - - struct dsp563xx_core_reg *dsp563xx_reg = reg->arch_info; - struct target *target = dsp563xx_reg->target; - uint32_t value = buf_get_u32(buf, 0, 32); - - if (target->state != TARGET_HALTED) - return ERROR_TARGET_NOT_HALTED; - - buf_set_u32(reg->value, 0, reg->size, value); - reg->dirty = 1; - reg->valid = 1; - - return ERROR_OK; -} - -static const struct reg_arch_type dsp563xx_reg_type = { - .get = dsp563xx_get_core_reg, - .set = dsp563xx_set_core_reg, -}; - -static void dsp563xx_build_reg_cache(struct target *target) -{ - struct dsp563xx_common *dsp563xx = target_to_dsp563xx(target); - - struct reg_cache **cache_p = register_get_last_cache_p(&target->reg_cache); - struct reg_cache *cache = malloc(sizeof(struct reg_cache)); - struct reg *reg_list = calloc(DSP563XX_NUMCOREREGS, sizeof(struct reg)); - struct dsp563xx_core_reg *arch_info = malloc( - sizeof(struct dsp563xx_core_reg) * DSP563XX_NUMCOREREGS); - int i; - - /* Build the process context cache */ - cache->name = "dsp563xx registers"; - cache->next = NULL; - cache->reg_list = reg_list; - cache->num_regs = DSP563XX_NUMCOREREGS; - (*cache_p) = cache; - dsp563xx->core_cache = cache; - - for (i = 0; i < DSP563XX_NUMCOREREGS; i++) { - arch_info[i].num = dsp563xx_regs[i].id; - arch_info[i].name = dsp563xx_regs[i].name; - arch_info[i].size = dsp563xx_regs[i].bits; - arch_info[i].eame = dsp563xx_regs[i].eame; - arch_info[i].instr_mask = dsp563xx_regs[i].instr_mask; - arch_info[i].target = target; - arch_info[i].dsp563xx_common = dsp563xx; - reg_list[i].name = dsp563xx_regs[i].name; - reg_list[i].size = 32; /* dsp563xx_regs[i].bits; */ - reg_list[i].value = calloc(1, 4); - reg_list[i].dirty = 0; - reg_list[i].valid = 0; - reg_list[i].type = &dsp563xx_reg_type; - reg_list[i].arch_info = &arch_info[i]; - } -} - -static int dsp563xx_read_register(struct target *target, int num, int force); -static int dsp563xx_write_register(struct target *target, int num, int force); - -static int dsp563xx_reg_read_high_io(struct target *target, uint32_t instr_mask, uint32_t *data) -{ - int err; - uint32_t instr; - struct dsp563xx_common *dsp563xx = target_to_dsp563xx(target); - - /* we use r0 to store temporary data */ - if (!dsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_R0].valid) - dsp563xx->read_core_reg(target, DSP563XX_REG_IDX_R0); - - /* move source memory to r0 */ - instr = INSTR_MOVEP_REG_HIO(MEM_X, 0, EAME_R0, instr_mask); - err = dsp563xx_once_execute_sw_ir(target->tap, 0, instr); - if (err != ERROR_OK) - return err; - /* move r0 to debug register */ - instr = INSTR_MOVEP_REG_HIO(MEM_X, 1, EAME_R0, 0xfffffc); - err = dsp563xx_once_execute_sw_ir(target->tap, 1, instr); - if (err != ERROR_OK) - return err; - /* read debug register */ - err = dsp563xx_once_reg_read(target->tap, 1, DSP563XX_ONCE_OGDBR, data); - if (err != ERROR_OK) - return err; - /* r0 is no longer valid on target */ - dsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_R0].dirty = 1; - - return ERROR_OK; -} - -static int dsp563xx_reg_write_high_io(struct target *target, uint32_t instr_mask, uint32_t data) -{ - int err; - uint32_t instr; - struct dsp563xx_common *dsp563xx = target_to_dsp563xx(target); - - /* we use r0 to store temporary data */ - if (!dsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_R0].valid) - dsp563xx->read_core_reg(target, DSP563XX_REG_IDX_R0); - - /* move data to r0 */ - err = dsp563xx_once_execute_dw_ir(target->tap, 0, 0x60F400, data); - if (err != ERROR_OK) - return err; - /* move r0 to destination memory */ - instr = INSTR_MOVEP_REG_HIO(MEM_X, 1, EAME_R0, instr_mask); - err = dsp563xx_once_execute_sw_ir(target->tap, 1, instr); - if (err != ERROR_OK) - return err; - - /* r0 is no longer valid on target */ - dsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_R0].dirty = 1; - - return ERROR_OK; -} - -static int dsp563xx_reg_read(struct target *target, uint32_t eame, uint32_t *data) -{ - int err; - uint32_t instr; - - instr = INSTR_MOVEP_REG_HIO(MEM_X, 1, eame, 0xfffffc); - err = dsp563xx_once_execute_sw_ir(target->tap, 0, instr); - if (err != ERROR_OK) - return err; - /* nop */ - err = dsp563xx_once_execute_sw_ir(target->tap, 1, 0x000000); - if (err != ERROR_OK) - return err; - /* read debug register */ - return dsp563xx_once_reg_read(target->tap, 1, DSP563XX_ONCE_OGDBR, data); -} - -static int dsp563xx_reg_write(struct target *target, uint32_t instr_mask, uint32_t data) -{ - int err; - - err = dsp563xx_once_execute_dw_ir(target->tap, 0, instr_mask, data); - if (err != ERROR_OK) - return err; - /* nop */ - return dsp563xx_once_execute_sw_ir(target->tap, 1, 0x000000); -} - -static int dsp563xx_reg_pc_read(struct target *target) -{ - struct dsp563xx_common *dsp563xx = target_to_dsp563xx(target); - - /* pc was changed, nothing todo */ - if (dsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_PC].dirty) - return ERROR_OK; - - /* conditional branch check */ - if (once_regs[ONCE_REG_IDX_OPABDR].reg == once_regs[ONCE_REG_IDX_OPABEX].reg) { - if ((once_regs[ONCE_REG_IDX_OPABF11].reg & 1) == 0) { - LOG_DEBUG("%s conditional branch not supported yet (0x%" PRIx32 " 0x%" PRIx32 " 0x%" PRIx32 ")", - __func__, - (once_regs[ONCE_REG_IDX_OPABF11].reg >> 1), - once_regs[ONCE_REG_IDX_OPABDR].reg, - once_regs[ONCE_REG_IDX_OPABEX].reg); - - /* TODO: use disassembly to set correct pc offset - * read 2 words from OPABF11 and disasm the instruction - */ - dsp563xx->core_regs[DSP563XX_REG_IDX_PC] = - (once_regs[ONCE_REG_IDX_OPABF11].reg >> 1) & 0x00FFFFFF; - } else { - if (once_regs[ONCE_REG_IDX_OPABEX].reg == - once_regs[ONCE_REG_IDX_OPABFR].reg) - dsp563xx->core_regs[DSP563XX_REG_IDX_PC] = - once_regs[ONCE_REG_IDX_OPABEX].reg; - else - dsp563xx->core_regs[DSP563XX_REG_IDX_PC] = - once_regs[ONCE_REG_IDX_OPABEX].reg - 1; - } - } else - dsp563xx->core_regs[DSP563XX_REG_IDX_PC] = once_regs[ONCE_REG_IDX_OPABEX].reg; - - dsp563xx->read_core_reg(target, DSP563XX_REG_IDX_PC); - - return ERROR_OK; -} - -static int dsp563xx_reg_ssh_read(struct target *target) -{ - int err; - uint32_t sp; - struct dsp563xx_core_reg *arch_info; - struct dsp563xx_common *dsp563xx = target_to_dsp563xx(target); - - arch_info = dsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_SSH].arch_info; - - /* get a valid stack pointer */ - err = dsp563xx_read_register(target, DSP563XX_REG_IDX_SP, 0); - if (err != ERROR_OK) - return err; - sp = dsp563xx->core_regs[DSP563XX_REG_IDX_SP]; - err = dsp563xx_write_register(target, DSP563XX_REG_IDX_SP, 0); - if (err != ERROR_OK) - return err; - - /* get a valid stack count */ - err = dsp563xx_read_register(target, DSP563XX_REG_IDX_SC, 0); - if (err != ERROR_OK) - return err; - - err = dsp563xx_write_register(target, DSP563XX_REG_IDX_SC, 0); - if (err != ERROR_OK) - return err; - - /* get a valid extended pointer */ - err = dsp563xx_read_register(target, DSP563XX_REG_IDX_EP, 0); - if (err != ERROR_OK) - return err; - - err = dsp563xx_write_register(target, DSP563XX_REG_IDX_EP, 0); - if (err != ERROR_OK) - return err; - - if (!sp) - sp = 0x00FFFFFF; - else { - err = dsp563xx_reg_read(target, arch_info->eame, &sp); - if (err != ERROR_OK) - return err; - - err = dsp563xx_write_register(target, DSP563XX_REG_IDX_SC, 1); - if (err != ERROR_OK) - return err; - err = dsp563xx_write_register(target, DSP563XX_REG_IDX_SP, 1); - if (err != ERROR_OK) - return err; - err = dsp563xx_write_register(target, DSP563XX_REG_IDX_EP, 1); - if (err != ERROR_OK) - return err; - } - - dsp563xx->core_regs[DSP563XX_REG_IDX_SSH] = sp; - dsp563xx->read_core_reg(target, DSP563XX_REG_IDX_SSH); - - return ERROR_OK; -} - -static int dsp563xx_reg_ssh_write(struct target *target) -{ - int err; - uint32_t sp; - struct dsp563xx_core_reg *arch_info; - struct dsp563xx_common *dsp563xx = target_to_dsp563xx(target); - - arch_info = dsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_SSH].arch_info; - - /* get a valid stack pointer */ - err = dsp563xx_read_register(target, DSP563XX_REG_IDX_SP, 0); - if (err != ERROR_OK) - return err; - sp = dsp563xx->core_regs[DSP563XX_REG_IDX_SP]; - - if (sp) { - sp--; - /* write new stackpointer */ - dsp563xx->core_regs[DSP563XX_REG_IDX_SP] = sp; - err = dsp563xx->read_core_reg(target, DSP563XX_REG_IDX_SP); - if (err != ERROR_OK) - return err; - err = dsp563xx_write_register(target, DSP563XX_REG_IDX_SP, 1); - if (err != ERROR_OK) - return err; - - err = dsp563xx_reg_write(target, arch_info->instr_mask, - dsp563xx->core_regs[DSP563XX_REG_IDX_SSH]); - if (err != ERROR_OK) - return err; - - err = dsp563xx_read_register(target, DSP563XX_REG_IDX_SP, 1); - if (err != ERROR_OK) - return err; - err = dsp563xx_read_register(target, DSP563XX_REG_IDX_SSH, 1); - if (err != ERROR_OK) - return err; - } - - return ERROR_OK; -} - -static int dsp563xx_reg_ssl_read(struct target *target) -{ - int err; - uint32_t sp; - struct dsp563xx_core_reg *arch_info; - struct dsp563xx_common *dsp563xx = target_to_dsp563xx(target); - - arch_info = dsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_SSL].arch_info; - - /* get a valid stack pointer */ - err = dsp563xx_read_register(target, DSP563XX_REG_IDX_SP, 0); - if (err != ERROR_OK) - return err; - sp = dsp563xx->core_regs[DSP563XX_REG_IDX_SP]; - - if (!sp) - sp = 0x00FFFFFF; - else { - err = dsp563xx_reg_read(target, arch_info->eame, &sp); - if (err != ERROR_OK) - return err; - } - - dsp563xx->core_regs[DSP563XX_REG_IDX_SSL] = sp; - dsp563xx->read_core_reg(target, DSP563XX_REG_IDX_SSL); - - return ERROR_OK; -} - -static int dsp563xx_read_register(struct target *target, int num, int force) -{ - int err = ERROR_OK; - uint32_t data = 0; - struct dsp563xx_common *dsp563xx = target_to_dsp563xx(target); - struct dsp563xx_core_reg *arch_info; - - if (force) - dsp563xx->core_cache->reg_list[num].valid = 0; - - if (!dsp563xx->core_cache->reg_list[num].valid) { - arch_info = dsp563xx->core_cache->reg_list[num].arch_info; - - switch (arch_info->num) { - case DSP563XX_REG_IDX_SSH: - err = dsp563xx_reg_ssh_read(target); - break; - case DSP563XX_REG_IDX_SSL: - err = dsp563xx_reg_ssl_read(target); - break; - case DSP563XX_REG_IDX_PC: - err = dsp563xx_reg_pc_read(target); - break; - case DSP563XX_REG_IDX_IPRC: - case DSP563XX_REG_IDX_IPRP: - case DSP563XX_REG_IDX_BCR: - case DSP563XX_REG_IDX_DCR: - case DSP563XX_REG_IDX_AAR0: - case DSP563XX_REG_IDX_AAR1: - case DSP563XX_REG_IDX_AAR2: - case DSP563XX_REG_IDX_AAR3: - err = dsp563xx_reg_read_high_io(target, - arch_info->instr_mask, &data); - if (err == ERROR_OK) { - dsp563xx->core_regs[num] = data; - dsp563xx->read_core_reg(target, num); - } - break; - default: - err = dsp563xx_reg_read(target, arch_info->eame, &data); - if (err == ERROR_OK) { - dsp563xx->core_regs[num] = data; - dsp563xx->read_core_reg(target, num); - } - break; - } - } - - return err; -} - -static int dsp563xx_write_register(struct target *target, int num, int force) -{ - int err = ERROR_OK; - struct dsp563xx_common *dsp563xx = target_to_dsp563xx(target); - struct dsp563xx_core_reg *arch_info; - - if (force) - dsp563xx->core_cache->reg_list[num].dirty = 1; - - if (dsp563xx->core_cache->reg_list[num].dirty) { - arch_info = dsp563xx->core_cache->reg_list[num].arch_info; - - dsp563xx->write_core_reg(target, num); - - switch (arch_info->num) { - case DSP563XX_REG_IDX_SSH: - err = dsp563xx_reg_ssh_write(target); - break; - case DSP563XX_REG_IDX_PC: - /* pc is updated on resume, no need to write it here */ - break; - case DSP563XX_REG_IDX_IPRC: - case DSP563XX_REG_IDX_IPRP: - case DSP563XX_REG_IDX_BCR: - case DSP563XX_REG_IDX_DCR: - case DSP563XX_REG_IDX_AAR0: - case DSP563XX_REG_IDX_AAR1: - case DSP563XX_REG_IDX_AAR2: - case DSP563XX_REG_IDX_AAR3: - err = dsp563xx_reg_write_high_io(target, - arch_info->instr_mask, - dsp563xx->core_regs[num]); - break; - default: - err = dsp563xx_reg_write(target, - arch_info->instr_mask, - dsp563xx->core_regs[num]); - - if ((err == ERROR_OK) && (arch_info->num == DSP563XX_REG_IDX_SP)) { - dsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_SSH].valid = - 0; - dsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_SSL].valid = - 0; - } - - break; - } - } - - return err; -} - -static int dsp563xx_save_context(struct target *target) -{ - int i, err = ERROR_OK; - - for (i = 0; i < DSP563XX_NUMCOREREGS; i++) { - err = dsp563xx_read_register(target, i, 0); - if (err != ERROR_OK) - break; - } - - return err; -} - -static int dsp563xx_restore_context(struct target *target) -{ - int i, err = ERROR_OK; - - for (i = 0; i < DSP563XX_NUMCOREREGS; i++) { - err = dsp563xx_write_register(target, i, 0); - if (err != ERROR_OK) - break; - } - - return err; -} - -static void dsp563xx_invalidate_x_context(struct target *target, - uint32_t addr_start, - uint32_t addr_end) -{ - int i; - struct dsp563xx_core_reg *arch_info; - struct dsp563xx_common *dsp563xx = target_to_dsp563xx(target); - - if (addr_start > ASM_REG_W_IPRC) - return; - if (addr_start < ASM_REG_W_AAR3) - return; - - for (i = DSP563XX_REG_IDX_IPRC; i < DSP563XX_NUMCOREREGS; i++) { - arch_info = dsp563xx->core_cache->reg_list[i].arch_info; - - if ((arch_info->instr_mask >= addr_start) && - (arch_info->instr_mask <= addr_end)) { - dsp563xx->core_cache->reg_list[i].valid = 0; - dsp563xx->core_cache->reg_list[i].dirty = 0; - } - } -} - -static int dsp563xx_target_create(struct target *target, Jim_Interp *interp) -{ - struct dsp563xx_common *dsp563xx = calloc(1, sizeof(struct dsp563xx_common)); - - if (!dsp563xx) - return ERROR_COMMAND_SYNTAX_ERROR; - - dsp563xx->jtag_info.tap = target->tap; - target->arch_info = dsp563xx; - dsp563xx->read_core_reg = dsp563xx_read_core_reg; - dsp563xx->write_core_reg = dsp563xx_write_core_reg; - - return ERROR_OK; -} - -static int dsp563xx_init_target(struct command_context *cmd_ctx, struct target *target) -{ - LOG_DEBUG("%s", __func__); - - dsp563xx_build_reg_cache(target); - struct dsp563xx_common *dsp563xx = target_to_dsp563xx(target); - - dsp563xx->hardware_breakpoints_cleared = 0; - dsp563xx->hardware_breakpoint[0].used = BPU_NONE; - - return ERROR_OK; -} - -static int dsp563xx_examine(struct target *target) -{ - uint32_t chip; - - if (target->tap->hasidcode == false) { - LOG_ERROR("no IDCODE present on device"); - return ERROR_COMMAND_SYNTAX_ERROR; - } - - if (!target_was_examined(target)) { - target_set_examined(target); - - /* examine core and chip derivate number */ - chip = (target->tap->idcode>>12) & 0x3ff; - /* core number 0 means DSP563XX */ - if (((chip>>5)&0x1f) == 0) - chip += 300; - - LOG_INFO("DSP56%03" PRId32 " device found", chip); - - /* Clear all breakpoints */ - dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_OBCR, 0); - } - - return ERROR_OK; -} - -static int dsp563xx_arch_state(struct target *target) -{ - LOG_DEBUG("%s", __func__); - return ERROR_OK; -} - -#define DSP563XX_SR_SA (1<<17) -#define DSP563XX_SR_SC (1<<13) - -static int dsp563xx_debug_once_init(struct target *target) -{ - return dsp563xx_once_read_register(target->tap, 1, once_regs, DSP563XX_NUMONCEREGS); -} - -static int dsp563xx_debug_init(struct target *target) -{ - int err; - uint32_t sr; - struct dsp563xx_common *dsp563xx = target_to_dsp563xx(target); - struct dsp563xx_core_reg *arch_info; - - err = dsp563xx_debug_once_init(target); - if (err != ERROR_OK) - return err; - - arch_info = dsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_SR].arch_info; - - /* check 24bit mode */ - err = dsp563xx_read_register(target, DSP563XX_REG_IDX_SR, 0); - if (err != ERROR_OK) - return err; - - sr = dsp563xx->core_regs[DSP563XX_REG_IDX_SR]; - - if (sr & (DSP563XX_SR_SA | DSP563XX_SR_SC)) { - sr &= ~(DSP563XX_SR_SA | DSP563XX_SR_SC); - - err = dsp563xx_once_execute_dw_ir(target->tap, 1, arch_info->instr_mask, sr); - if (err != ERROR_OK) - return err; - dsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_SR].dirty = 1; - } - - err = dsp563xx_read_register(target, DSP563XX_REG_IDX_N0, 0); - if (err != ERROR_OK) - return err; - err = dsp563xx_read_register(target, DSP563XX_REG_IDX_N1, 0); - if (err != ERROR_OK) - return err; - err = dsp563xx_read_register(target, DSP563XX_REG_IDX_M0, 0); - if (err != ERROR_OK) - return err; - err = dsp563xx_read_register(target, DSP563XX_REG_IDX_M1, 0); - if (err != ERROR_OK) - return err; - - if (dsp563xx->core_regs[DSP563XX_REG_IDX_N0] != 0x000000) { - arch_info = dsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_N0].arch_info; - err = dsp563xx_reg_write(target, arch_info->instr_mask, 0x000000); - if (err != ERROR_OK) - return err; - } - dsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_N0].dirty = 1; - - if (dsp563xx->core_regs[DSP563XX_REG_IDX_N1] != 0x000000) { - arch_info = dsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_N1].arch_info; - err = dsp563xx_reg_write(target, arch_info->instr_mask, 0x000000); - if (err != ERROR_OK) - return err; - } - dsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_N1].dirty = 1; - - if (dsp563xx->core_regs[DSP563XX_REG_IDX_M0] != 0xffffff) { - arch_info = dsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_M0].arch_info; - err = dsp563xx_reg_write(target, arch_info->instr_mask, 0xffffff); - if (err != ERROR_OK) - return err; - } - dsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_M0].dirty = 1; - - if (dsp563xx->core_regs[DSP563XX_REG_IDX_M1] != 0xffffff) { - arch_info = dsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_M1].arch_info; - err = dsp563xx_reg_write(target, arch_info->instr_mask, 0xffffff); - if (err != ERROR_OK) - return err; - } - dsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_M1].dirty = 1; - - err = dsp563xx_save_context(target); - if (err != ERROR_OK) - return err; - - return ERROR_OK; -} - -static int dsp563xx_jtag_debug_request(struct target *target) -{ - return dsp563xx_once_request_debug(target->tap, target->state == TARGET_RESET); -} - -static int dsp563xx_poll(struct target *target) -{ - int err; - struct dsp563xx_common *dsp563xx = target_to_dsp563xx(target); - uint32_t once_status = 0; - int state; - - state = dsp563xx_once_target_status(target->tap); - - if (state == TARGET_UNKNOWN) { - target->state = state; - LOG_ERROR("jtag status contains invalid mode value - communication failure"); - return ERROR_TARGET_FAILURE; - } - - err = dsp563xx_once_reg_read(target->tap, 1, DSP563XX_ONCE_OSCR, &once_status); - if (err != ERROR_OK) - return err; - - if ((once_status & DSP563XX_ONCE_OSCR_DEBUG_M) == DSP563XX_ONCE_OSCR_DEBUG_M) { - if (target->state != TARGET_HALTED) { - target->state = TARGET_HALTED; - - err = dsp563xx_debug_init(target); - if (err != ERROR_OK) - return err; - - if (once_status & (DSP563XX_ONCE_OSCR_MBO|DSP563XX_ONCE_OSCR_SWO)) - target_call_event_callbacks(target, TARGET_EVENT_DEBUG_HALTED); - else - target_call_event_callbacks(target, TARGET_EVENT_HALTED); - - LOG_DEBUG("target->state: %s (%" PRIx32 ")", target_state_name(target), once_status); - LOG_INFO("halted: PC: 0x%" PRIx32, dsp563xx->core_regs[DSP563XX_REG_IDX_PC]); - } - } - - if (!dsp563xx->hardware_breakpoints_cleared) { - err = dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_OBCR, 0); - err = dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_OMLR0, 0); - err = dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_OMLR1, 0); - dsp563xx->hardware_breakpoints_cleared = 1; - } - - return ERROR_OK; -} - -static int dsp563xx_halt(struct target *target) -{ - int err; - - LOG_DEBUG("%s", __func__); - - if (target->state == TARGET_HALTED) { - LOG_DEBUG("target was already halted"); - return ERROR_OK; - } - - if (target->state == TARGET_UNKNOWN) - LOG_WARNING("target was in unknown state when halt was requested"); - - err = dsp563xx_jtag_debug_request(target); - if (err != ERROR_OK) - return err; - - target->debug_reason = DBG_REASON_DBGRQ; - - return ERROR_OK; -} - -static int dsp563xx_resume(struct target *target, - int current, - uint32_t address, - int handle_breakpoints, - int debug_execution) -{ - int err; - struct dsp563xx_common *dsp563xx = target_to_dsp563xx(target); - - /* check if pc was changed and resume want to execute the next address - * if pc was changed from gdb or other interface we will - * jump to this address and don't execute the next address - * this will not affect the resume command with an address argument - * because current is set to zero then - */ - if (current && dsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_PC].dirty) { - dsp563xx_write_core_reg(target, DSP563XX_REG_IDX_PC); - address = dsp563xx->core_regs[DSP563XX_REG_IDX_PC]; - current = 0; - } - - LOG_DEBUG("%s %08X %08X", __func__, current, (unsigned) address); - - err = dsp563xx_restore_context(target); - if (err != ERROR_OK) - return err; - register_cache_invalidate(dsp563xx->core_cache); - - if (current) { - /* restore pipeline registers and go */ - err = dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_OPDBR, - once_regs[ONCE_REG_IDX_OPILR].reg); - if (err != ERROR_OK) - return err; - err = dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_OPDBR | - DSP563XX_ONCE_OCR_EX | DSP563XX_ONCE_OCR_GO, - once_regs[ONCE_REG_IDX_OPDBR].reg); - if (err != ERROR_OK) - return err; - } else { - /* set to go register and jump */ - err = dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_OPDBR, INSTR_JUMP); - if (err != ERROR_OK) - return err; - err = dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_PDBGOTO | - DSP563XX_ONCE_OCR_EX | DSP563XX_ONCE_OCR_GO, address); - if (err != ERROR_OK) - return err; - } - - target->state = TARGET_RUNNING; - - target_call_event_callbacks(target, TARGET_EVENT_DEBUG_RESUMED); - - return ERROR_OK; -} - -static int dsp563xx_step_ex(struct target *target, - int current, - uint32_t address, - int handle_breakpoints, - int steps) -{ - int err; - uint32_t once_status; - uint32_t dr_in, cnt; - struct dsp563xx_common *dsp563xx = target_to_dsp563xx(target); - - if (target->state != TARGET_HALTED) { - LOG_DEBUG("target was not halted"); - return ERROR_OK; - } - - /* check if pc was changed and step want to execute the next address - * if pc was changed from gdb or other interface we will - * jump to this address and don't execute the next address - * this will not affect the step command with an address argument - * because current is set to zero then - */ - if (current && dsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_PC].dirty) { - dsp563xx_write_core_reg(target, DSP563XX_REG_IDX_PC); - address = dsp563xx->core_regs[DSP563XX_REG_IDX_PC]; - current = 0; - } - - LOG_DEBUG("%s %08X %08X", __func__, current, (unsigned) address); - - err = dsp563xx_jtag_debug_request(target); - if (err != ERROR_OK) - return err; - err = dsp563xx_restore_context(target); - if (err != ERROR_OK) - return err; - - /* reset trace mode */ - err = dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_OSCR, 0x000000); - if (err != ERROR_OK) - return err; - /* enable trace mode */ - err = dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_OSCR, DSP563XX_ONCE_OSCR_TME); - if (err != ERROR_OK) - return err; - - cnt = steps; - - /* on JUMP we need one extra cycle */ - if (!current) - cnt++; - - /* load step counter with N-1 */ - err = dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_OTC, cnt); - if (err != ERROR_OK) - return err; - - if (current) { - /* restore pipeline registers and go */ - err = dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_OPDBR, - once_regs[ONCE_REG_IDX_OPILR].reg); - if (err != ERROR_OK) - return err; - err = dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_OPDBR | - DSP563XX_ONCE_OCR_EX | DSP563XX_ONCE_OCR_GO, - once_regs[ONCE_REG_IDX_OPDBR].reg); - if (err != ERROR_OK) - return err; - } else { - /* set to go register and jump */ - err = dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_OPDBR, INSTR_JUMP); - if (err != ERROR_OK) - return err; - err = dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_PDBGOTO | - DSP563XX_ONCE_OCR_EX | DSP563XX_ONCE_OCR_GO, - address); - if (err != ERROR_OK) - return err; - } - - while (1) { - err = dsp563xx_once_reg_read(target->tap, 1, DSP563XX_ONCE_OSCR, &once_status); - if (err != ERROR_OK) - return err; - - if (once_status & DSP563XX_ONCE_OSCR_TO) { - err = dsp563xx_once_reg_read(target->tap, 1, DSP563XX_ONCE_OPABFR, &dr_in); - if (err != ERROR_OK) - return err; - LOG_DEBUG("fetch: %08X", (unsigned) dr_in&0x00ffffff); - err = dsp563xx_once_reg_read(target->tap, 1, DSP563XX_ONCE_OPABDR, &dr_in); - if (err != ERROR_OK) - return err; - LOG_DEBUG("decode: %08X", (unsigned) dr_in&0x00ffffff); - err = dsp563xx_once_reg_read(target->tap, 1, DSP563XX_ONCE_OPABEX, &dr_in); - if (err != ERROR_OK) - return err; - LOG_DEBUG("execute: %08X", (unsigned) dr_in&0x00ffffff); - - /* reset trace mode */ - err = dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_OSCR, 0x000000); - if (err != ERROR_OK) - return err; - - register_cache_invalidate(dsp563xx->core_cache); - err = dsp563xx_debug_init(target); - if (err != ERROR_OK) - return err; - - break; - } - } - - return ERROR_OK; -} - -static int dsp563xx_step(struct target *target, - int current, - uint32_t address, - int handle_breakpoints) -{ - int err; - struct dsp563xx_common *dsp563xx = target_to_dsp563xx(target); - - if (target->state != TARGET_HALTED) { - LOG_WARNING("target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - err = dsp563xx_step_ex(target, current, address, handle_breakpoints, 0); - if (err != ERROR_OK) - return err; - - target->debug_reason = DBG_REASON_SINGLESTEP; - target_call_event_callbacks(target, TARGET_EVENT_HALTED); - - LOG_INFO("halted: PC: 0x%" PRIx32, dsp563xx->core_regs[DSP563XX_REG_IDX_PC]); - - return err; -} - -static int dsp563xx_assert_reset(struct target *target) -{ - int retval = 0; - struct dsp563xx_common *dsp563xx = target_to_dsp563xx(target); - enum reset_types jtag_reset_config = jtag_get_reset_config(); - - if (jtag_reset_config & RESET_HAS_SRST) { - /* default to asserting srst */ - if (jtag_reset_config & RESET_SRST_PULLS_TRST) - jtag_add_reset(1, 1); - else - jtag_add_reset(0, 1); - } - - target->state = TARGET_RESET; - jtag_add_sleep(5000); - - /* registers are now invalid */ - register_cache_invalidate(dsp563xx->core_cache); - - if (target->reset_halt) { - retval = target_halt(target); - if (retval != ERROR_OK) - return retval; - } - - LOG_DEBUG("%s", __func__); - return ERROR_OK; -} - -static int dsp563xx_deassert_reset(struct target *target) -{ - int err; - - /* deassert reset lines */ - jtag_add_reset(0, 0); - - err = dsp563xx_poll(target); - if (err != ERROR_OK) - return err; - - if (target->reset_halt) { - if (target->state == TARGET_HALTED) { - /* after a reset the cpu jmp to the - * reset vector and need 2 cycles to fill - * the cache (fetch,decode,excecute) - */ - err = dsp563xx_step_ex(target, 1, 0, 1, 1); - if (err != ERROR_OK) - return err; - } - } else - target->state = TARGET_RUNNING; - - LOG_DEBUG("%s", __func__); - return ERROR_OK; -} - -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, - int timeout_ms, void *arch_info) -{ - int i; - int retval = ERROR_OK; - struct dsp563xx_common *dsp563xx = target_to_dsp563xx(target); - - if (target->state != TARGET_HALTED) { - LOG_WARNING("target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - for (i = 0; i < num_mem_params; i++) { - retval = target_write_buffer(target, mem_params[i].address, - mem_params[i].size, mem_params[i].value); - if (retval != ERROR_OK) - return retval; - } - - for (i = 0; i < num_reg_params; i++) { - struct reg *reg = register_get_by_name(dsp563xx->core_cache, - reg_params[i].reg_name, - 0); - - if (!reg) { - LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name); - continue; - } - - if (reg->size != reg_params[i].size) { - LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size", - reg_params[i].reg_name); - continue; - } - - retval = dsp563xx_set_core_reg(reg, reg_params[i].value); - if (retval != ERROR_OK) - return retval; - } - - /* exec */ - retval = target_resume(target, 0, entry_point, 1, 1); - if (retval != ERROR_OK) - return retval; - - retval = target_wait_state(target, TARGET_HALTED, timeout_ms); - if (retval != ERROR_OK) - return retval; - - for (i = 0; i < num_mem_params; i++) { - if (mem_params[i].direction != PARAM_OUT) - retval = target_read_buffer(target, - mem_params[i].address, - mem_params[i].size, - mem_params[i].value); - if (retval != ERROR_OK) - return retval; - } - - for (i = 0; i < num_reg_params; i++) { - if (reg_params[i].direction != PARAM_OUT) { - - struct reg *reg = register_get_by_name(dsp563xx->core_cache, - reg_params[i].reg_name, - 0); - if (!reg) { - LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name); - continue; - } - - if (reg->size != reg_params[i].size) { - LOG_ERROR( - "BUG: register '%s' size doesn't match reg_params[i].size", - reg_params[i].reg_name); - continue; - } - - buf_set_u32(reg_params[i].value, 0, 32, buf_get_u32(reg->value, 0, 32)); - } - } - - return ERROR_OK; -} - -/* global command context from openocd.c */ -extern struct command_context *global_cmd_ctx; - -static int dsp563xx_get_default_memory(void) -{ - Jim_Interp *interp; - Jim_Obj *memspace; - char *c; - - if (!global_cmd_ctx) - return MEM_P; - - interp = global_cmd_ctx->interp; - - if (!interp) - return MEM_P; - - memspace = Jim_GetGlobalVariableStr(interp, "memspace", JIM_NONE); - - if (!memspace) - return MEM_P; - - c = (char *)Jim_GetString(memspace, NULL); - - if (!c) - return MEM_P; - - switch (c[0]) { - case '1': - return MEM_X; - case '2': - return MEM_Y; - case '3': - return MEM_L; - default: - break; - } - - return MEM_P; -} - -static int dsp563xx_read_memory_core(struct target *target, - int mem_type, - uint32_t address, - uint32_t size, - uint32_t count, - uint8_t *buffer) -{ - int err; - struct dsp563xx_common *dsp563xx = target_to_dsp563xx(target); - uint32_t i, x; - uint32_t data, move_cmd = 0; - uint8_t *b; - - LOG_DEBUG( - "memtype: %d address: 0x%8.8" PRIx32 ", size: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32 "", - mem_type, - address, - size, - count); - - if (target->state != TARGET_HALTED) { - LOG_WARNING("target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - switch (mem_type) { - case MEM_X: - /* TODO: mark effected queued registers */ - move_cmd = 0x61d800; - break; - case MEM_Y: - move_cmd = 0x69d800; - break; - case MEM_P: - move_cmd = 0x07d891; - break; - default: - return ERROR_COMMAND_SYNTAX_ERROR; - } - - /* we use r0 to store temporary data */ - if (!dsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_R0].valid) - dsp563xx->read_core_reg(target, DSP563XX_REG_IDX_R0); - /* we use r1 to store temporary data */ - if (!dsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_R1].valid) - dsp563xx->read_core_reg(target, DSP563XX_REG_IDX_R1); - - /* r0 is no longer valid on target */ - dsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_R0].dirty = 1; - /* r1 is no longer valid on target */ - dsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_R1].dirty = 1; - - x = count; - b = buffer; - - err = dsp563xx_once_execute_dw_ir(target->tap, 1, 0x60F400, address); - if (err != ERROR_OK) - return err; - - for (i = 0; i < x; i++) { - err = dsp563xx_once_execute_sw_ir(target->tap, 0, move_cmd); - if (err != ERROR_OK) - return err; - err = dsp563xx_once_execute_sw_ir(target->tap, 0, 0x08D13C); - if (err != ERROR_OK) - return err; - err = dsp563xx_once_reg_read(target->tap, 0, - DSP563XX_ONCE_OGDBR, (uint32_t *)(void *)b); - if (err != ERROR_OK) - return err; - b += 4; - } - - /* flush the jtag queue */ - err = jtag_execute_queue(); - if (err != ERROR_OK) - return err; - - /* walk over the buffer and fix target endianness */ - b = buffer; - - for (i = 0; i < x; i++) { - data = buf_get_u32(b, 0, 32) & 0x00FFFFFF; -/* LOG_DEBUG("R: %08X", *((uint32_t*)b)); */ - target_buffer_set_u32(target, b, data); - b += 4; - } - - return ERROR_OK; -} - -static int dsp563xx_read_memory(struct target *target, - int mem_type, - uint32_t address, - uint32_t size, - uint32_t count, - uint8_t *buffer) -{ - int err; - uint32_t i, i1; - uint8_t *buffer_y, *buffer_x; - - /* if size equals zero we are called from target read memory - * and have to handle the parameter here */ - if ((size == 0) && (count != 0)) { - size = count % 4; - - if (size) - LOG_DEBUG("size is not aligned to 4 byte"); - - count = (count - size) / 4; - size = 4; - } - - /* we only support 4 byte aligned data */ - if ((size != 4) || (!count)) - return ERROR_COMMAND_SYNTAX_ERROR; - - if (mem_type != MEM_L) - return dsp563xx_read_memory_core(target, mem_type, address, size, count, buffer); - - buffer_y = malloc(size * count); - if (!buffer_y) - return ERROR_COMMAND_SYNTAX_ERROR; - - buffer_x = malloc(size * count); - if (!buffer_x) { - free(buffer_y); - return ERROR_COMMAND_SYNTAX_ERROR; - } - - err = dsp563xx_read_memory_core(target, MEM_Y, address, size, count / 2, buffer_y); - - if (err != ERROR_OK) { - free(buffer_y); - free(buffer_x); - return err; - } - - err = dsp563xx_read_memory_core(target, MEM_X, address, size, count / 2, buffer_x); - - if (err != ERROR_OK) { - free(buffer_y); - free(buffer_x); - return err; - } - - for (i = 0, i1 = 0; i < count; i += 2, i1++) { - buf_set_u32(buffer + i*sizeof(uint32_t), 0, 32, - buf_get_u32(buffer_y + i1 * sizeof(uint32_t), 0, 32)); - buf_set_u32(buffer + (i + 1) * sizeof(uint32_t), 0, 32, - buf_get_u32(buffer_x + i1 * sizeof(uint32_t), 0, 32)); - } - - free(buffer_y); - free(buffer_x); - - return ERROR_OK; -} - -static int dsp563xx_read_memory_default(struct target *target, - uint32_t address, - uint32_t size, - uint32_t count, - uint8_t *buffer) -{ - - return dsp563xx_read_memory(target, - dsp563xx_get_default_memory(), address, size, count, buffer); -} - -static int dsp563xx_read_buffer_default(struct target *target, - uint32_t address, - uint32_t size, - uint8_t *buffer) -{ - - return dsp563xx_read_memory(target, dsp563xx_get_default_memory(), address, size, 0, - buffer); -} - -static int dsp563xx_write_memory_core(struct target *target, - int mem_type, - uint32_t address, - uint32_t size, - uint32_t count, - const uint8_t *buffer) -{ - int err; - struct dsp563xx_common *dsp563xx = target_to_dsp563xx(target); - uint32_t i, x; - uint32_t data, move_cmd = 0; - const uint8_t *b; - - LOG_DEBUG( - "memtype: %d address: 0x%8.8" PRIx32 ", size: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32 "", - mem_type, - address, - size, - count); - - if (target->state != TARGET_HALTED) { - LOG_WARNING("target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - switch (mem_type) { - case MEM_X: - /* invalidate affected x registers */ - dsp563xx_invalidate_x_context(target, address, address + count - 1); - move_cmd = 0x615800; - break; - case MEM_Y: - move_cmd = 0x695800; - break; - case MEM_P: - move_cmd = 0x075891; - break; - default: - return ERROR_COMMAND_SYNTAX_ERROR; - } - - /* we use r0 to store temporary data */ - if (!dsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_R0].valid) - dsp563xx->read_core_reg(target, DSP563XX_REG_IDX_R0); - /* we use r1 to store temporary data */ - if (!dsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_R1].valid) - dsp563xx->read_core_reg(target, DSP563XX_REG_IDX_R1); - - /* r0 is no longer valid on target */ - dsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_R0].dirty = 1; - /* r1 is no longer valid on target */ - dsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_R1].dirty = 1; - - x = count; - b = buffer; - - err = dsp563xx_once_execute_dw_ir(target->tap, 1, 0x60F400, address); - if (err != ERROR_OK) - return err; - - for (i = 0; i < x; i++) { - data = target_buffer_get_u32(target, b); - -/* LOG_DEBUG("W: %08X", data); */ - - data &= 0x00ffffff; - - err = dsp563xx_once_execute_dw_ir(target->tap, 0, 0x61F400, data); - if (err != ERROR_OK) - return err; - err = dsp563xx_once_execute_sw_ir(target->tap, 0, move_cmd); - if (err != ERROR_OK) - return err; - b += 4; - } - - /* flush the jtag queue */ - err = jtag_execute_queue(); - if (err != ERROR_OK) - return err; - - return ERROR_OK; -} - -static int dsp563xx_write_memory(struct target *target, - int mem_type, - uint32_t address, - uint32_t size, - uint32_t count, - const uint8_t *buffer) -{ - int err; - uint32_t i, i1; - uint8_t *buffer_y, *buffer_x; - - /* if size equals zero we are called from target write memory - * and have to handle the parameter here */ - if ((size == 0) && (count != 0)) { - size = count % 4; - - if (size) - LOG_DEBUG("size is not aligned to 4 byte"); - - count = (count - size) / 4; - size = 4; - } - - /* we only support 4 byte aligned data */ - if ((size != 4) || (!count)) - return ERROR_COMMAND_SYNTAX_ERROR; - - if (mem_type != MEM_L) - return dsp563xx_write_memory_core(target, mem_type, address, size, count, buffer); - - buffer_y = malloc(size * count); - if (!buffer_y) - return ERROR_COMMAND_SYNTAX_ERROR; - - buffer_x = malloc(size * count); - if (!buffer_x) { - free(buffer_y); - return ERROR_COMMAND_SYNTAX_ERROR; - } - - for (i = 0, i1 = 0; i < count; i += 2, i1++) { - buf_set_u32(buffer_y + i1 * sizeof(uint32_t), 0, 32, - buf_get_u32(buffer + i * sizeof(uint32_t), 0, 32)); - buf_set_u32(buffer_x + i1 * sizeof(uint32_t), 0, 32, - buf_get_u32(buffer + (i + 1) * sizeof(uint32_t), 0, 32)); - } - - err = dsp563xx_write_memory_core(target, MEM_Y, address, size, count / 2, buffer_y); - - if (err != ERROR_OK) { - free(buffer_y); - free(buffer_x); - return err; - } - - err = dsp563xx_write_memory_core(target, MEM_X, address, size, count / 2, buffer_x); - - if (err != ERROR_OK) { - free(buffer_y); - free(buffer_x); - return err; - } - - free(buffer_y); - free(buffer_x); - - return ERROR_OK; -} - -static int dsp563xx_write_memory_default(struct target *target, - uint32_t address, - uint32_t size, - uint32_t count, - const uint8_t *buffer) -{ - return dsp563xx_write_memory(target, - dsp563xx_get_default_memory(), address, size, count, buffer); -} - -static int dsp563xx_write_buffer_default(struct target *target, - uint32_t address, - uint32_t size, - const uint8_t *buffer) -{ - return dsp563xx_write_memory(target, dsp563xx_get_default_memory(), address, size, 0, - buffer); -} - -/* - * Exit with error here, because we support watchpoints over a custom command. - * This is because the DSP has separate X,Y,P memspace which is not compatible to the - * traditional watchpoint logic. - */ -static int dsp563xx_add_watchpoint(struct target *target, struct watchpoint *watchpoint) -{ - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; -} - -/* - * @see dsp563xx_add_watchpoint - */ -static int dsp563xx_remove_watchpoint(struct target *target, struct watchpoint *watchpoint) -{ - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; -} - -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)); - - 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; - } - } -} - -static int dsp563xx_add_custom_watchpoint(struct target *target, uint32_t address, uint32_t memType, - enum watchpoint_rw rw, enum watchpoint_condition cond) -{ - int err = ERROR_OK; - struct dsp563xx_common *dsp563xx = target_to_dsp563xx(target); - - bool wasRunning = false; - /* Only set breakpoint when halted */ - if (target->state != TARGET_HALTED) { - dsp563xx_halt(target); - wasRunning = true; - } - - if (dsp563xx->hardware_breakpoint[0].used) { - LOG_ERROR("Cannot add watchpoint. Hardware resource already used."); - err = ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - } - - uint32_t obcr_value = 0; - if (err == ERROR_OK) { - obcr_value |= OBCR_b0_or_b1; - switch (memType) { - case MEM_X: - obcr_value |= OBCR_BP_MEM_X; - break; - case MEM_Y: - obcr_value |= OBCR_BP_MEM_Y; - break; - case MEM_P: - obcr_value |= OBCR_BP_MEM_P; - break; - default: - LOG_ERROR("Unknown memType parameter (%" PRIu32 ")", memType); - err = ERROR_TARGET_INVALID; - } - } - - if (err == ERROR_OK) { - switch (rw) { - case WPT_READ: - obcr_value |= OBCR_BP_0(OBCR_BP_ON_READ); - break; - case WPT_WRITE: - obcr_value |= OBCR_BP_0(OBCR_BP_ON_WRITE); - break; - case WPT_ACCESS: - obcr_value |= OBCR_BP_0(OBCR_BP_ON_READ|OBCR_BP_ON_WRITE); - break; - default: - LOG_ERROR("Unsupported write mode (%d)", rw); - err = ERROR_TARGET_INVALID; - } - } - - if (err == ERROR_OK) { - switch (cond) { - case EQUAL: - obcr_value |= OBCR_BP_0(OBCR_BP_CC_EQUAL); - break; - case NOT_EQUAL: - obcr_value |= OBCR_BP_0(OBCR_BP_CC_NOT_EQUAL); - break; - case LESS_THAN: - obcr_value |= OBCR_BP_0(OBCR_BP_CC_LESS_THAN); - break; - case GREATER: - obcr_value |= OBCR_BP_0(OBCR_BP_CC_GREATER_THAN); - break; - default: - LOG_ERROR("Unsupported condition code (%d)", cond); - err = ERROR_TARGET_INVALID; - } - } - - if (err == ERROR_OK) - err = dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_OMLR0, address); - - if (err == ERROR_OK) - err = dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_OMLR1, 0x0); - - if (err == ERROR_OK) - err = dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_OBCR, obcr_value); - - if (err == ERROR_OK) { - /* You should write the memory breakpoint counter to 0 */ - err = dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_OMBC, 0); - } - - if (err == ERROR_OK) { - /* You should write the memory breakpoint counter to 0 */ - err = dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_OTC, 0); - } - - if (err == ERROR_OK) - dsp563xx->hardware_breakpoint[0].used = BPU_WATCHPOINT; - - if (err == ERROR_OK && wasRunning) { - /* Resume from current PC */ - err = dsp563xx_resume(target, 1, 0x0, 0, 0); - } - - return err; -} - -static int dsp563xx_remove_custom_watchpoint(struct target *target) -{ - int err = ERROR_OK; - struct dsp563xx_common *dsp563xx = target_to_dsp563xx(target); - - if (dsp563xx->hardware_breakpoint[0].used != BPU_WATCHPOINT) { - LOG_ERROR("Cannot remove watchpoint, as no watchpoint is currently configured!"); - err = ERROR_TARGET_INVALID; - } - - if (err == ERROR_OK) { - /* Clear watchpoint by clearing OBCR. */ - err = dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_OBCR, 0); - } - - if (err == ERROR_OK) - dsp563xx->hardware_breakpoint[0].used = BPU_NONE; - - return err; -} - -COMMAND_HANDLER(dsp563xx_add_watchpoint_command) -{ - int err = ERROR_OK; - struct target *target = get_current_target(CMD_CTX); - - uint32_t mem_type = 0; - switch (CMD_NAME[2]) { - case 'x': - mem_type = MEM_X; - break; - case 'y': - mem_type = MEM_Y; - break; - case 'p': - mem_type = MEM_P; - break; - default: - return ERROR_COMMAND_SYNTAX_ERROR; - } - - if (CMD_ARGC < 2) - return ERROR_COMMAND_SYNTAX_ERROR; - - uint32_t address = 0; - if (CMD_ARGC > 2) - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], address); - - enum watchpoint_condition cond; - switch (CMD_ARGV[0][0]) { - case '>': - cond = GREATER; - break; - case '<': - cond = LESS_THAN; - break; - case '=': - cond = EQUAL; - break; - case '!': - cond = NOT_EQUAL; - break; - default: - return ERROR_COMMAND_SYNTAX_ERROR; - } - - enum watchpoint_rw rw; - switch (CMD_ARGV[1][0]) { - case 'r': - rw = WPT_READ; - break; - case 'w': - rw = WPT_WRITE; - break; - case 'a': - rw = WPT_ACCESS; - break; - default: - return ERROR_COMMAND_SYNTAX_ERROR; - } - - err = dsp563xx_add_custom_watchpoint(target, address, mem_type, rw, cond); - - return err; -} - -/* Adding a breakpoint using the once breakpoint logic. - * Note that this mechanism is a true hw breakpoint and is share between the watchpoint logic. - * This means, you can only have one breakpoint/watchpoint at any time. - */ -static int dsp563xx_add_breakpoint(struct target *target, struct breakpoint *breakpoint) -{ - return dsp563xx_add_custom_watchpoint(target, breakpoint->address, MEM_P, WPT_READ, EQUAL); -} - -static int dsp563xx_remove_breakpoint(struct target *target, struct breakpoint *breakpoint) -{ - return dsp563xx_remove_custom_watchpoint(target); -} - -COMMAND_HANDLER(dsp563xx_remove_watchpoint_command) -{ - struct target *target = get_current_target(CMD_CTX); - - return dsp563xx_remove_custom_watchpoint(target); -} - -COMMAND_HANDLER(dsp563xx_mem_command) -{ - struct target *target = get_current_target(CMD_CTX); - int err = ERROR_OK; - int read_mem; - uint32_t address = 0; - uint32_t count = 1, i; - uint32_t pattern = 0; - uint32_t mem_type; - uint8_t *buffer, *b; - - switch (CMD_NAME[1]) { - case 'w': - read_mem = 0; - break; - case 'd': - read_mem = 1; - break; - default: - return ERROR_COMMAND_SYNTAX_ERROR; - } - - switch (CMD_NAME[3]) { - case 'x': - mem_type = MEM_X; - break; - case 'y': - mem_type = MEM_Y; - break; - case 'p': - mem_type = MEM_P; - break; - default: - return ERROR_COMMAND_SYNTAX_ERROR; - } - - if (CMD_ARGC > 0) - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], address); - - if (read_mem == 0) { - if (CMD_ARGC < 2) - return ERROR_COMMAND_SYNTAX_ERROR; - if (CMD_ARGC > 1) - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], pattern); - if (CMD_ARGC > 2) - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], count); - } - - if (read_mem == 1) { - if (CMD_ARGC < 1) - return ERROR_COMMAND_SYNTAX_ERROR; - if (CMD_ARGC > 1) - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], count); - } - - buffer = calloc(count, sizeof(uint32_t)); - - if (read_mem == 1) { - err = dsp563xx_read_memory(target, mem_type, address, sizeof(uint32_t), - count, buffer); - if (err == ERROR_OK) - handle_md_output(CMD_CTX, target, address, sizeof(uint32_t), count, buffer); - - } else { - b = buffer; - - for (i = 0; i < count; i++) { - target_buffer_set_u32(target, b, pattern); - b += 4; - } - - err = dsp563xx_write_memory(target, - mem_type, - address, - sizeof(uint32_t), - count, - buffer); - } - - free(buffer); - - return err; -} - -static const struct command_registration dsp563xx_command_handlers[] = { - { - .name = "mwwx", - .handler = dsp563xx_mem_command, - .mode = COMMAND_EXEC, - .help = "write x memory words", - .usage = "address value [count]", - }, - { - .name = "mwwy", - .handler = dsp563xx_mem_command, - .mode = COMMAND_EXEC, - .help = "write y memory words", - .usage = "address value [count]", - }, - { - .name = "mwwp", - .handler = dsp563xx_mem_command, - .mode = COMMAND_EXEC, - .help = "write p memory words", - .usage = "address value [count]", - }, - { - .name = "mdwx", - .handler = dsp563xx_mem_command, - .mode = COMMAND_EXEC, - .help = "display x memory words", - .usage = "address [count]", - }, - { - .name = "mdwy", - .handler = dsp563xx_mem_command, - .mode = COMMAND_EXEC, - .help = "display y memory words", - .usage = "address [count]", - }, - { - .name = "mdwp", - .handler = dsp563xx_mem_command, - .mode = COMMAND_EXEC, - .help = "display p memory words", - .usage = "address [count]", - }, - /* - * Watchpoint commands - */ - { - .name = "wpp", - .handler = dsp563xx_add_watchpoint_command, - .mode = COMMAND_EXEC, - .help = "Create p memspace watchpoint", - .usage = "(>|<|=|!) (r|w|a) address", - }, - { - .name = "wpx", - .handler = dsp563xx_add_watchpoint_command, - .mode = COMMAND_EXEC, - .help = "Create x memspace watchpoint", - .usage = "(>|<|=|!) (r|w|a) address", - }, - { - .name = "wpy", - .handler = dsp563xx_add_watchpoint_command, - .mode = COMMAND_EXEC, - .help = "Create y memspace watchpoint", - .usage = "(>|<|=|!) (r|w|a) address", - }, - { - .name = "rwpc", - .handler = dsp563xx_remove_watchpoint_command, - .mode = COMMAND_EXEC, - .help = "remove watchpoint custom", - .usage = " ", - }, - COMMAND_REGISTRATION_DONE -}; - -/** Holds methods for DSP563XX targets. */ -struct target_type dsp563xx_target = { - .name = "dsp563xx", - - .poll = dsp563xx_poll, - .arch_state = dsp563xx_arch_state, - - .get_gdb_reg_list = dsp563xx_get_gdb_reg_list, - - .halt = dsp563xx_halt, - .resume = dsp563xx_resume, - .step = dsp563xx_step, - - .assert_reset = dsp563xx_assert_reset, - .deassert_reset = dsp563xx_deassert_reset, - - .read_memory = dsp563xx_read_memory_default, - .write_memory = dsp563xx_write_memory_default, - - .read_buffer = dsp563xx_read_buffer_default, - .write_buffer = dsp563xx_write_buffer_default, - - .run_algorithm = dsp563xx_run_algorithm, - - .add_breakpoint = dsp563xx_add_breakpoint, - .remove_breakpoint = dsp563xx_remove_breakpoint, - .add_watchpoint = dsp563xx_add_watchpoint, - .remove_watchpoint = dsp563xx_remove_watchpoint, - - .commands = dsp563xx_command_handlers, - .target_create = dsp563xx_target_create, - .init_target = dsp563xx_init_target, - .examine = dsp563xx_examine, -}; diff --git a/src/target/dsp563xx.h b/src/target/dsp563xx.h deleted file mode 100644 index 4bb5aceaf..000000000 --- a/src/target/dsp563xx.h +++ /dev/null @@ -1,73 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2009-2011 by Mathias Kuester * - * mkdorg@users.sourceforge.net * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifndef OPENOCD_TARGET_DSP563XX_H -#define OPENOCD_TARGET_DSP563XX_H - -#include -#include - -#define DSP563XX_NUMCOREREGS 54 -#define DSP563XX_NUMONCEREGS 25 - -struct mcu_jtag { - struct jtag_tap *tap; -}; - -enum breakpoint_usage { - BPU_NONE = 0, - BPU_BREAKPOINT, - BPU_WATCHPOINT -}; - -struct hardware_breakpoint { - enum breakpoint_usage used; -}; - -struct dsp563xx_common { - struct mcu_jtag jtag_info; - struct reg_cache *core_cache; - uint32_t core_regs[DSP563XX_NUMCOREREGS]; - struct once_reg once_regs[DSP563XX_NUMONCEREGS]; - - /* register cache to processor synchronization */ - int (*read_core_reg) (struct target *target, int num); - int (*write_core_reg) (struct target *target, int num); - - struct hardware_breakpoint hardware_breakpoint[1]; - - /*Were the hardware breakpoints cleared on startup?*/ - int hardware_breakpoints_cleared; -}; - -struct dsp563xx_core_reg { - uint32_t num; - const char *name; - uint32_t size; - uint8_t eame; - uint32_t instr_mask; - struct target *target; - struct dsp563xx_common *dsp563xx_common; -}; - -static inline struct dsp563xx_common *target_to_dsp563xx(struct target *target) -{ - return target->arch_info; -} - -#endif /* OPENOCD_TARGET_DSP563XX_H */ diff --git a/src/target/dsp563xx_once.c b/src/target/dsp563xx_once.c deleted file mode 100644 index fe4927ba3..000000000 --- a/src/target/dsp563xx_once.c +++ /dev/null @@ -1,293 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2009 by Mathias Kuester * - * mkdorg@users.sourceforge.net * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include - -#include "target.h" -#include "target_type.h" -#include "register.h" -#include "dsp563xx.h" -#include "dsp563xx_once.h" - -#define JTAG_STATUS_STATIC_MASK 0x03 -#define JTAG_STATUS_STATIC_VALUE 0x01 - -#define JTAG_STATUS_NORMAL 0x01 -#define JTAG_STATUS_STOPWAIT 0x05 -#define JTAG_STATUS_BUSY 0x09 -#define JTAG_STATUS_DEBUG 0x0d - -#define JTAG_INSTR_EXTEST 0x00 -#define JTAG_INSTR_SAMPLE_PRELOAD 0x01 -#define JTAG_INSTR_IDCODE 0x02 -#define JTAG_INSTR_HIZ 0x04 -#define JTAG_INSTR_CLAMP 0x05 -#define JTAG_INSTR_ENABLE_ONCE 0x06 -#define JTAG_INSTR_DEBUG_REQUEST 0x07 -#define JTAG_INSTR_BYPASS 0x0F - -/** */ -static inline int dsp563xx_write_dr(struct jtag_tap *tap, uint8_t * dr_in, uint8_t * dr_out, int dr_len, int rti) -{ - jtag_add_plain_dr_scan(dr_len, dr_out, dr_in, TAP_IDLE); - - return ERROR_OK; -} - -/** */ -static inline int dsp563xx_write_dr_u8(struct jtag_tap *tap, uint8_t * dr_in, uint8_t dr_out, int dr_len, int rti) -{ - return dsp563xx_write_dr(tap, dr_in, &dr_out, dr_len, rti); -} - -/** */ -static inline int dsp563xx_write_dr_u32(struct jtag_tap *tap, uint32_t * dr_in, uint32_t dr_out, int dr_len, int rti) -{ - return dsp563xx_write_dr(tap, (uint8_t *) dr_in, (uint8_t *) &dr_out, dr_len, rti); -} - -/** single word instruction */ -static inline int dsp563xx_once_ir_exec(struct jtag_tap *tap, int flush, uint8_t instr, uint8_t rw, uint8_t go, uint8_t ex) -{ - int err; - - err = dsp563xx_write_dr_u8(tap, 0, instr | (ex << 5) | (go << 6) | (rw << 7), 8, 0); - if (err != ERROR_OK) - return err; - if (flush) - err = jtag_execute_queue(); - return err; -} - -/* IR and DR functions */ -static inline int dsp563xx_write_ir(struct jtag_tap *tap, uint8_t * ir_in, uint8_t * ir_out, int ir_len, int rti) -{ - jtag_add_plain_ir_scan(tap->ir_length, ir_out, ir_in, TAP_IDLE); - - return ERROR_OK; -} - -static inline int dsp563xx_write_ir_u8(struct jtag_tap *tap, uint8_t * ir_in, uint8_t ir_out, int ir_len, int rti) -{ - return dsp563xx_write_ir(tap, ir_in, &ir_out, ir_len, rti); -} - -static inline int dsp563xx_jtag_sendinstr(struct jtag_tap *tap, uint8_t * ir_in, uint8_t ir_out) -{ - return dsp563xx_write_ir_u8(tap, ir_in, ir_out, tap->ir_length, 1); -} - -/** */ -int dsp563xx_once_target_status(struct jtag_tap *tap) -{ - int err; - uint8_t jtag_status; - - err = dsp563xx_jtag_sendinstr(tap, &jtag_status, JTAG_INSTR_ENABLE_ONCE); - if (err != ERROR_OK) - return TARGET_UNKNOWN; - err = jtag_execute_queue(); - if (err != ERROR_OK) - return TARGET_UNKNOWN; - - /* verify correct static status pattern */ - if ((jtag_status & JTAG_STATUS_STATIC_MASK) != JTAG_STATUS_STATIC_VALUE) - return TARGET_UNKNOWN; - - if (jtag_status != JTAG_STATUS_DEBUG) - return TARGET_RUNNING; - - return TARGET_HALTED; -} - -/** */ -int dsp563xx_once_request_debug(struct jtag_tap *tap, int reset_state) -{ - int err; - uint8_t ir_in = 0, pattern = 0; - uint32_t retry = 0; - - /* in reset state we only get a ACK - * from the interface */ - if (reset_state) - pattern = 1; - else - pattern = JTAG_STATUS_DEBUG; - - /* wait until we get the ack */ - while (ir_in != pattern) { - err = dsp563xx_jtag_sendinstr(tap, &ir_in, JTAG_INSTR_DEBUG_REQUEST); - if (err != ERROR_OK) - return err; - err = jtag_execute_queue(); - if (err != ERROR_OK) - return err; - - LOG_DEBUG("debug request: %02X", ir_in); - - if (retry++ == 100) - return ERROR_TARGET_FAILURE; - } - - /* we cant enable the once in reset state */ - if (pattern == 1) - return ERROR_OK; - - /* try to enable once */ - retry = 0; - ir_in = 0; - while (ir_in != pattern) { - err = dsp563xx_jtag_sendinstr(tap, &ir_in, JTAG_INSTR_ENABLE_ONCE); - if (err != ERROR_OK) - return err; - err = jtag_execute_queue(); - if (err != ERROR_OK) - return err; - - LOG_DEBUG("enable once: %02X", ir_in); - - if (retry++ == 100) { - LOG_DEBUG("error"); - return ERROR_TARGET_FAILURE; - } - } - - if (ir_in != JTAG_STATUS_DEBUG) - return ERROR_TARGET_FAILURE; - - return ERROR_OK; -} - -/** once read registers */ -int dsp563xx_once_read_register(struct jtag_tap *tap, int flush, struct once_reg *regs, int len) -{ - int i; - int err = ERROR_OK; - - for (i = 0; i < len; i++) { - err = dsp563xx_once_reg_read_ex(tap, flush, regs[i].addr, regs[i].len, ®s[i].reg); - if (err != ERROR_OK) - return err; - } - - if (flush) - err = jtag_execute_queue(); - return err; -} - -/** once read register with register len */ -int dsp563xx_once_reg_read_ex(struct jtag_tap *tap, int flush, uint8_t reg, uint8_t len, uint32_t * data) -{ - int err; - - err = dsp563xx_once_ir_exec(tap, 1, reg, 1, 0, 0); - if (err != ERROR_OK) - return err; - err = dsp563xx_write_dr_u32(tap, data, 0x00, len, 0); - if (err != ERROR_OK) - return err; - if (flush) - err = jtag_execute_queue(); - - return err; -} - -/** once read register */ -int dsp563xx_once_reg_read(struct jtag_tap *tap, int flush, uint8_t reg, uint32_t * data) -{ - int err; - - err = dsp563xx_once_ir_exec(tap, flush, reg, 1, 0, 0); - if (err != ERROR_OK) - return err; - err = dsp563xx_write_dr_u32(tap, data, 0x00, 24, 0); - if (err != ERROR_OK) - return err; - if (flush) - err = jtag_execute_queue(); - - return err; -} - -/** once write register */ -int dsp563xx_once_reg_write(struct jtag_tap *tap, int flush, uint8_t reg, uint32_t data) -{ - int err; - - err = dsp563xx_once_ir_exec(tap, flush, reg, 0, 0, 0); - if (err != ERROR_OK) - return err; - err = dsp563xx_write_dr_u32(tap, 0x00, data, 24, 0); - if (err != ERROR_OK) - return err; - if (flush) - err = jtag_execute_queue(); - return err; -} - -/** single word instruction */ -int dsp563xx_once_execute_sw_ir(struct jtag_tap *tap, int flush, uint32_t opcode) -{ - int err; - - err = dsp563xx_once_ir_exec(tap, flush, DSP563XX_ONCE_OPDBR, 0, 1, 0); - if (err != ERROR_OK) - return err; - err = dsp563xx_write_dr_u32(tap, 0, opcode, 24, 0); - if (err != ERROR_OK) - return err; - if (flush) - err = jtag_execute_queue(); - return err; -} - -/** double word instruction */ -int dsp563xx_once_execute_dw_ir(struct jtag_tap *tap, int flush, uint32_t opcode, uint32_t operand) -{ - int err; - - err = dsp563xx_once_ir_exec(tap, flush, DSP563XX_ONCE_OPDBR, 0, 0, 0); - if (err != ERROR_OK) - return err; - err = dsp563xx_write_dr_u32(tap, 0, opcode, 24, 0); - if (err != ERROR_OK) - return err; - if (flush) { - err = jtag_execute_queue(); - if (err != ERROR_OK) - return err; - } - - err = dsp563xx_once_ir_exec(tap, flush, DSP563XX_ONCE_OPDBR, 0, 1, 0); - if (err != ERROR_OK) - return err; - err = dsp563xx_write_dr_u32(tap, 0, operand, 24, 0); - if (err != ERROR_OK) - return err; - if (flush) { - err = jtag_execute_queue(); - if (err != ERROR_OK) - return err; - } - - return ERROR_OK; -} diff --git a/src/target/dsp563xx_once.h b/src/target/dsp563xx_once.h deleted file mode 100644 index da7f5e9b8..000000000 --- a/src/target/dsp563xx_once.h +++ /dev/null @@ -1,89 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2009 by Mathias Kuester * - * mkdorg@users.sourceforge.net * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifndef OPENOCD_TARGET_DSP563XX_ONCE_H -#define OPENOCD_TARGET_DSP563XX_ONCE_H - -#include - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#define DSP563XX_ONCE_OCR_EX (1<<5) -#define DSP563XX_ONCE_OCR_GO (1<<6) -#define DSP563XX_ONCE_OCR_RW (1<<7) - -#define DSP563XX_ONCE_OSCR_OS1 (1<<7) -#define DSP563XX_ONCE_OSCR_OS0 (1<<6) -#define DSP563XX_ONCE_OSCR_HIT (1<<5) -#define DSP563XX_ONCE_OSCR_TO (1<<4) -#define DSP563XX_ONCE_OSCR_MBO (1<<3) -#define DSP563XX_ONCE_OSCR_SWO (1<<2) -#define DSP563XX_ONCE_OSCR_IME (1<<1) -#define DSP563XX_ONCE_OSCR_TME (1<<0) - -#define DSP563XX_ONCE_OSCR_NORMAL_M (0) -#define DSP563XX_ONCE_OSCR_STOPWAIT_M (DSP563XX_ONCE_OSCR_OS0) -#define DSP563XX_ONCE_OSCR_BUSY_M (DSP563XX_ONCE_OSCR_OS1) -#define DSP563XX_ONCE_OSCR_DEBUG_M (DSP563XX_ONCE_OSCR_OS0|DSP563XX_ONCE_OSCR_OS1) - -#define DSP563XX_ONCE_OSCR 0x000 /* status/ctrl reg. */ -#define DSP563XX_ONCE_OMBC 0x001 /* memory breakp. reg. */ -#define DSP563XX_ONCE_OBCR 0x002 /* breakp. ctrl reg */ -#define DSP563XX_ONCE_OMLR0 0x005 /* memory limit reg */ -#define DSP563XX_ONCE_OMLR1 0x006 /* memory limit reg */ -#define DSP563XX_ONCE_OGDBR 0x009 /* gdb reg */ -#define DSP563XX_ONCE_OPDBR 0x00A /* pdb reg */ -#define DSP563XX_ONCE_OPILR 0x00B /* pil reg */ -#define DSP563XX_ONCE_PDBGOTO 0x00C /* pdb to go reg */ -#define DSP563XX_ONCE_OTC 0x00D /* trace cnt */ -#define DSP563XX_ONCE_TAGB 0x00E /* tags buffer */ -#define DSP563XX_ONCE_OPABFR 0x00F /* pab fetch reg */ -#define DSP563XX_ONCE_OPABDR 0x010 /* pab decode reg */ -#define DSP563XX_ONCE_OPABEX 0x011 /* pab exec reg */ -#define DSP563XX_ONCE_OPABF11 0x012 /* trace buffer/inc ptr */ -#define DSP563XX_ONCE_NOREG 0x01F /* no register selected */ - -struct once_reg { - const uint8_t num; - const uint8_t addr; - const uint8_t len; - const char *name; - uint32_t reg; -}; - -/** */ -int dsp563xx_once_request_debug(struct jtag_tap *tap, int reset_state); -/** */ -int dsp563xx_once_target_status(struct jtag_tap *tap); - -/** once read registers */ -int dsp563xx_once_read_register(struct jtag_tap *tap, int flush, struct once_reg *regs, int len); -/** once read register */ -int dsp563xx_once_reg_read_ex(struct jtag_tap *tap, int flush, uint8_t reg, uint8_t len, uint32_t * data); -/** once read register */ -int dsp563xx_once_reg_read(struct jtag_tap *tap, int flush, uint8_t reg, uint32_t * data); -/** once write register */ -int dsp563xx_once_reg_write(struct jtag_tap *tap, int flush, uint8_t reg, uint32_t data); -/** single word instruction */ -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 /* OPENOCD_TARGET_DSP563XX_ONCE_H */ diff --git a/src/target/dsp5680xx.c b/src/target/dsp5680xx.c deleted file mode 100644 index 205d8fe43..000000000 --- a/src/target/dsp5680xx.c +++ /dev/null @@ -1,2297 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2011 by Rodrigo L. Rosa * - * rodrigorosa.LG@gmail.com * - * * - * Based on dsp563xx_once.h written by Mathias Kuester * - * mkdorg@users.sourceforge.net * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "target.h" -#include "target_type.h" -#include "dsp5680xx.h" - -struct dsp5680xx_common dsp5680xx_context; - -#define _E "DSP5680XX_ERROR:%d\nAt:%s:%d:%s" -#define err_check(r, c, m) if (r != ERROR_OK) {LOG_ERROR(_E, c, __func__, __LINE__, m); return r; } -#define err_check_propagate(retval) if (retval != ERROR_OK) return retval; -#define DEBUG_MSG "Debug mode be enabled to read mem." -#define DEBUG_FAIL { err_check(ERROR_FAIL, DSP5680XX_ERROR_NOT_IN_DEBUG, DEBUG_MSG) } -#define CHECK_DBG if (!dsp5680xx_context.debug_mode_enabled) DEBUG_FAIL -#define HALT_MSG "Target must be halted." -#define HALT_FAIL { err_check(ERROR_FAIL, DSP5680XX_ERROR_TARGET_RUNNING, HALT_MSG) } -#define CHECK_HALT(target) if (target->state != TARGET_HALTED) HALT_FAIL -#define check_halt_and_debug(target) { CHECK_HALT(target); CHECK_DBG; } - -int dsp5680xx_execute_queue(void) -{ - int retval; - - retval = jtag_execute_queue(); - return retval; -} - -/** - * Reset state machine - */ -static int reset_jtag(void) -{ - int retval; - - tap_state_t states[2]; - - const char *cp = "RESET"; - - states[0] = tap_state_by_name(cp); - retval = jtag_add_statemove(states[0]); - err_check_propagate(retval); - retval = jtag_execute_queue(); - err_check_propagate(retval); - jtag_add_pathmove(0, states + 1); - retval = jtag_execute_queue(); - return retval; -} - -static int dsp5680xx_drscan(struct target *target, uint8_t *d_in, - uint8_t *d_out, int len) -{ - /* -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - * - *Inputs: - * - d_in: This is the data that will be shifted into the JTAG DR reg. - * - d_out: The data that will be shifted out of the JTAG DR reg will stored here - * - len: Length of the data to be shifted to JTAG DR. - * - *Note: If d_out == NULL, discard incoming bits. - * - *-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - */ - int retval = ERROR_OK; - - if (NULL == target->tap) { - retval = ERROR_FAIL; - err_check(retval, DSP5680XX_ERROR_JTAG_INVALID_TAP, - "Invalid tap"); - } - if (len > 32) { - retval = ERROR_FAIL; - err_check(retval, DSP5680XX_ERROR_JTAG_DR_LEN_OVERFLOW, - "dr_len overflow, maxium is 32"); - } - /* TODO what values of len are valid for jtag_add_plain_dr_scan? */ - /* can i send as many bits as i want? */ - /* is the casting necessary? */ - jtag_add_plain_dr_scan(len, d_in, d_out, TAP_IDLE); - if (dsp5680xx_context.flush) { - retval = dsp5680xx_execute_queue(); - err_check(retval, DSP5680XX_ERROR_JTAG_DRSCAN, - "drscan failed!"); - } - if (d_out != NULL) - LOG_DEBUG("Data read (%d bits): 0x%04X", len, *d_out); - else - LOG_DEBUG("Data read was discarded."); - return retval; -} - -/** - * Test func - * - * @param target - * @param d_in This is the data that will be shifted into the JTAG IR reg. - * @param d_out The data that will be shifted out of the JTAG IR reg will be stored here. - * @apram ir_len Length of the data to be shifted to JTAG IR. - * - */ -static int dsp5680xx_irscan(struct target *target, uint32_t *d_in, - uint32_t *d_out, uint8_t ir_len) -{ - int retval = ERROR_OK; - - uint16_t tap_ir_len = DSP5680XX_JTAG_MASTER_TAP_IRLEN; - - if (NULL == target->tap) { - retval = ERROR_FAIL; - err_check(retval, DSP5680XX_ERROR_JTAG_INVALID_TAP, - "Invalid tap"); - } - if (ir_len != target->tap->ir_length) { - if (target->tap->enabled) { - retval = ERROR_FAIL; - err_check(retval, DSP5680XX_ERROR_INVALID_IR_LEN, - "Invalid irlen"); - } else { - struct jtag_tap *t = - jtag_tap_by_string("dsp568013.chp"); - if ((t == NULL) - || ((t->enabled) && (ir_len != tap_ir_len))) { - retval = ERROR_FAIL; - err_check(retval, - DSP5680XX_ERROR_INVALID_IR_LEN, - "Invalid irlen"); - } - } - } - jtag_add_plain_ir_scan(ir_len, (uint8_t *) d_in, (uint8_t *) d_out, - TAP_IDLE); - if (dsp5680xx_context.flush) { - retval = dsp5680xx_execute_queue(); - err_check(retval, DSP5680XX_ERROR_JTAG_IRSCAN, - "irscan failed!"); - } - return retval; -} - -static int dsp5680xx_jtag_status(struct target *target, uint8_t *status) -{ - uint32_t read_from_ir; - - uint32_t instr; - - int retval; - - instr = JTAG_INSTR_ENABLE_ONCE; - retval = - dsp5680xx_irscan(target, &instr, &read_from_ir, - DSP5680XX_JTAG_CORE_TAP_IRLEN); - err_check_propagate(retval); - if (status != NULL) - *status = (uint8_t) read_from_ir; - return ERROR_OK; -} - -static int jtag_data_read(struct target *target, uint8_t *data_read, - int num_bits) -{ - uint32_t bogus_instr = 0; - - int retval = - dsp5680xx_drscan(target, (uint8_t *) &bogus_instr, data_read, - num_bits); - LOG_DEBUG("Data read (%d bits): 0x%04X", num_bits, *data_read); - /** TODO remove this or move to jtagio? */ - return retval; -} - -#define jtag_data_read8(target, data_read) jtag_data_read(target, data_read, 8) -#define jtag_data_read16(target, data_read) jtag_data_read(target, data_read, 16) -#define jtag_data_read32(target, data_read) jtag_data_read(target, data_read, 32) - -static uint32_t data_read_dummy; - -static int jtag_data_write(struct target *target, uint32_t instr, int num_bits, - uint32_t *data_read) -{ - int retval; - - retval = - dsp5680xx_drscan(target, (uint8_t *) &instr, - (uint8_t *) &data_read_dummy, num_bits); - err_check_propagate(retval); - if (data_read != NULL) - *data_read = data_read_dummy; - return retval; -} - -#define jtag_data_write8(target, instr, data_read) jtag_data_write(target, instr, 8, data_read) -#define jtag_data_write16(target, instr, data_read) jtag_data_write(target, instr, 16, data_read) -#define jtag_data_write24(target, instr, data_read) jtag_data_write(target, instr, 24, data_read) -#define jtag_data_write32(target, instr, data_read) jtag_data_write(target, instr, 32, data_read) - -/** - * Executes EOnCE instruction. - * - * @param target - * @param instr Instruction to execute. - * @param rw - * @param go - * @param ex - * @param eonce_status Value read from the EOnCE status register. - * - * @return - */ -static int eonce_instruction_exec_single(struct target *target, uint8_t instr, - uint8_t rw, uint8_t go, uint8_t ex, - uint8_t *eonce_status) -{ - int retval; - - uint32_t dr_out_tmp; - - uint8_t instr_with_flags = instr | (rw << 7) | (go << 6) | (ex << 5); - - retval = jtag_data_write(target, instr_with_flags, 8, &dr_out_tmp); - err_check_propagate(retval); - if (eonce_status != NULL) - *eonce_status = (uint8_t) dr_out_tmp; - return retval; -} - -/* wrappers for multi opcode instructions */ -#define dsp5680xx_exe_1(target, oc1, oc2, oc3) dsp5680xx_exe1(target, oc1) -#define dsp5680xx_exe_2(target, oc1, oc2, oc3) dsp5680xx_exe2(target, oc1, oc2) -#define dsp5680xx_exe_3(target, oc1, oc2, oc3) dsp5680xx_exe3(target, oc1, oc2, oc3) -#define dsp5680xx_exe_generic(t, words, oc1, oc2, oc3) dsp5680xx_exe_##words(t, oc1, oc2, oc3) - -/* Executes one word DSP instruction */ -static int dsp5680xx_exe1(struct target *target, uint16_t opcode) -{ - int retval; - - retval = eonce_instruction_exec_single(target, 0x04, 0, 1, 0, NULL); - err_check_propagate(retval); - retval = jtag_data_write16(target, opcode, NULL); - err_check_propagate(retval); - return retval; -} - -/* Executes two word DSP instruction */ -static int dsp5680xx_exe2(struct target *target, uint16_t opcode1, - uint16_t opcode2) -{ - int retval; - - retval = eonce_instruction_exec_single(target, 0x04, 0, 0, 0, NULL); - err_check_propagate(retval); - retval = jtag_data_write16(target, opcode1, NULL); - err_check_propagate(retval); - retval = eonce_instruction_exec_single(target, 0x04, 0, 1, 0, NULL); - err_check_propagate(retval); - retval = jtag_data_write16(target, opcode2, NULL); - err_check_propagate(retval); - return retval; -} - -/* Executes three word DSP instruction */ -static int dsp5680xx_exe3(struct target *target, uint16_t opcode1, - uint16_t opcode2, uint16_t opcode3) -{ - int retval; - - retval = eonce_instruction_exec_single(target, 0x04, 0, 0, 0, NULL); - err_check_propagate(retval); - retval = jtag_data_write16(target, opcode1, NULL); - err_check_propagate(retval); - retval = eonce_instruction_exec_single(target, 0x04, 0, 0, 0, NULL); - err_check_propagate(retval); - retval = jtag_data_write16(target, opcode2, NULL); - err_check_propagate(retval); - retval = eonce_instruction_exec_single(target, 0x04, 0, 1, 0, NULL); - err_check_propagate(retval); - retval = jtag_data_write16(target, opcode3, NULL); - err_check_propagate(retval); - return retval; -} - -/* - *--------------- Real-time data exchange --------------- - * The EOnCE Transmit (OTX) and Receive (ORX) registers are data memory mapped, each with an upper - * and lower 16 bit word. - * Transmit and receive directions are defined from the core’s perspective. - * The core writes to the Transmit register and reads the Receive register, and the host through - * JTAG writes to the Receive register and reads the Transmit register. - * Both registers have a combined data memory mapped OTXRXSR which provides indication when - * each may be accessed. - * ref: eonce_rev.1.0_0208081.pdf@36 - */ - -/* writes data into upper ORx register of the target */ -static int core_tx_upper_data(struct target *target, uint16_t data, - uint32_t *eonce_status_low) -{ - int retval; - - retval = - eonce_instruction_exec_single(target, DSP5680XX_ONCE_ORX1, 0, 0, 0, - NULL); - err_check_propagate(retval); - retval = jtag_data_write16(target, data, eonce_status_low); - err_check_propagate(retval); - return retval; -} - -/* writes data into lower ORx register of the target */ -#define CMD1 eonce_instruction_exec_single(target, DSP5680XX_ONCE_ORX, 0, 0, 0, NULL); -#define CMD2 jtag_data_write16((t, data) -#define core_tx_lower_data(t, data) PT1\ PT2 - -/** - * - * @param target - * @param data_read: Returns the data read from the upper OTX register via JTAG. - * @return: Returns an error code (see error code documentation) - */ -static int core_rx_upper_data(struct target *target, uint8_t *data_read) -{ - int retval; - - retval = - eonce_instruction_exec_single(target, DSP5680XX_ONCE_OTX1, 1, 0, 0, - NULL); - err_check_propagate(retval); - retval = jtag_data_read16(target, data_read); - err_check_propagate(retval); - return retval; -} - -/** - * - * @param target - * @param data_read: Returns the data read from the lower OTX register via JTAG. - * @return: Returns an error code (see error code documentation) - */ -static int core_rx_lower_data(struct target *target, uint8_t *data_read) -{ - int retval; - - retval = - eonce_instruction_exec_single(target, DSP5680XX_ONCE_OTX, 1, 0, 0, - NULL); - err_check_propagate(retval); - retval = jtag_data_read16(target, data_read); - err_check_propagate(retval); - return retval; -} - -/* - *-- -- -- -- --- -- -- -- --- -- -- -- --- -- -- -- --- -- -- -- --- -- - *-- -- -- -- --- -- -- -Core Instructions- -- -- -- --- -- -- -- --- -- - *-- -- -- -- --- -- -- -- --- -- -- -- --- -- -- -- --- -- -- -- --- -- - */ - -#define exe(a, b, c, d, e) dsp5680xx_exe_generic(a, b, c, d, e) - -/* move.l #value, r0 */ -#define core_move_long_to_r0(target, value) exe(target, 3, 0xe418, value&0xffff, value>>16) - -/* move.l #value, n */ -#define core_move_long_to_n(target, value) exe(target, 3, 0xe41e, value&0xffff, value>>16) - -/* move x:(r0), y0 */ -#define core_move_at_r0_to_y0(target) exe(target, 1, 0xF514, 0, 0) - -/* move x:(r0), y1 */ -#define core_move_at_r0_to_y1(target) exe(target, 1, 0xF714, 0, 0) - -/* move.l x:(r0), y */ -#define core_move_long_at_r0_y(target) exe(target, 1, 0xF734, 0, 0) - -/* move y0, x:(r0) */ -#define core_move_y0_at_r0(target) exe(target, 1, 0xd514, 0, 0) - -/* bfclr #value, x:(r0) */ -#define eonce_bfclr_at_r0(target, value) exe(target, 2, 0x8040, value, 0) - -/* move #value, y0 */ -#define core_move_value_to_y0(target, value) exe(target, 2, 0x8745, value, 0) - -/* move.w y0, x:(r0)+ */ -#define core_move_y0_at_r0_inc(target) exe(target, 1, 0xd500, 0, 0) - -/* move.w y0, p:(r0)+ */ -#define core_move_y0_at_pr0_inc(target) exe(target, 1, 0x8560, 0, 0) - -/* move.w p:(r0)+, y0 */ -#define core_move_at_pr0_inc_to_y0(target) exe(target, 1, 0x8568, 0, 0) - -/* move.w p:(r0)+, y1 */ -#define core_move_at_pr0_inc_to_y1(target) exe(target, 1, 0x8768, 0, 0) - -/* move.l #value, r2 */ -#define core_move_long_to_r2(target, value) exe(target, 3, 0xe41A, value&0xffff, value>>16) - -/* move y0, x:(r2) */ -#define core_move_y0_at_r2(target) exe(target, 1, 0xd516, 0, 0) - -/* move.w #, x:(r2) */ -#define core_move_value_at_r2(target, value) exe(target, 2, 0x8642, value, 0) - -/* move.w #, x:(r0) */ -#define core_move_value_at_r0(target, value) exe(target, 2, 0x8640, value, 0) - -/* move.w #, x:(R2+) */ -#define core_move_value_at_r2_disp(target, value, disp) exe(target, 3, 0x8646, value, disp) - -/* move.w x:(r2), Y0 */ -#define core_move_at_r2_to_y0(target) exe(target, 1, 0xF516, 0, 0) - -/* move.w p:(r2)+, y0 */ -#define core_move_at_pr2_inc_to_y0(target) exe(target, 1, 0x856A, 0, 0) - -/* move.l #value, r3 */ -#define core_move_long_to_r1(target, value) exe(target, 3, 0xE419, value&0xffff, value>>16) - -/* move.l #value, r3 */ -#define core_move_long_to_r3(target, value) exe(target, 3, 0xE41B, value&0xffff, value>>16) - -/* move.w y0, p:(r3)+ */ -#define core_move_y0_at_pr3_inc(target) exe(target, 1, 0x8563, 0, 0) - -/* move.w y0, x:(r3) */ -#define core_move_y0_at_r3(target) exe(target, 1, 0xD503, 0, 0) - -/* move.l #value, r4 */ -#define core_move_long_to_r4(target, value) exe(target, 3, 0xE41C, value&0xffff, value>>16) - -/* move pc, r4 */ -#define core_move_pc_to_r4(target) exe(target, 1, 0xE716, 0, 0) - -/* move.l r4, y */ -#define core_move_r4_to_y(target) exe(target, 1, 0xe764, 0, 0) - -/* move.w p:(r0)+, y0 */ -#define core_move_at_pr0_inc_to_y0(target) exe(target, 1, 0x8568, 0, 0) - -/* move.w x:(r0)+, y0 */ -#define core_move_at_r0_inc_to_y0(target) exe(target, 1, 0xf500, 0, 0) - -/* move x:(r0), y0 */ -#define core_move_at_r0_y0(target) exe(target, 1, 0xF514, 0, 0) - -/* nop */ -#define eonce_nop(target) exe(target, 1, 0xe700, 0, 0) - -/* move.w x:(R2+), Y0 */ -#define core_move_at_r2_disp_to_y0(target, disp) exe(target, 2, 0xF542, disp, 0) - -/* move.w y1, x:(r2) */ -#define core_move_y1_at_r2(target) exe(target, 1, 0xd716, 0, 0) - -/* move.w y1, x:(r0) */ -#define core_move_y1_at_r0(target) exe(target, 1, 0xd714, 0, 0) - -/* move.bp y0, x:(r0)+ */ -#define core_move_byte_y0_at_r0(target) exe(target, 1, 0xd5a0, 0, 0) - -/* move.w y1, p:(r0)+ */ -#define core_move_y1_at_pr0_inc(target) exe(target, 1, 0x8760, 0, 0) - -/* move.w y1, x:(r0)+ */ -#define core_move_y1_at_r0_inc(target) exe(target, 1, 0xD700, 0, 0) - -/* move.l #value, y */ -#define core_move_long_to_y(target, value) exe(target, 3, 0xe417, value&0xffff, value>>16) - -static int core_move_value_to_pc(struct target *target, uint32_t value) -{ - check_halt_and_debug(target); - int retval; - - retval = - dsp5680xx_exe_generic(target, 3, 0xE71E, value & 0xffff, - value >> 16); - err_check_propagate(retval); - return retval; -} - -static int eonce_load_TX_RX_to_r0(struct target *target) -{ - int retval; - - retval = - core_move_long_to_r0(target, - ((MC568013_EONCE_TX_RX_ADDR) + - (MC568013_EONCE_OBASE_ADDR << 16))); - return retval; -} - -static int core_load_TX_RX_high_addr_to_r0(struct target *target) -{ - int retval = 0; - - retval = - core_move_long_to_r0(target, - ((MC568013_EONCE_TX1_RX1_HIGH_ADDR) + - (MC568013_EONCE_OBASE_ADDR << 16))); - return retval; -} - -static int dsp5680xx_read_core_reg(struct target *target, uint8_t reg_addr, - uint16_t *data_read) -{ - /* TODO implement a general version of this which matches what openocd uses. */ - int retval; - - uint32_t dummy_data_to_shift_into_dr; - - retval = eonce_instruction_exec_single(target, reg_addr, 1, 0, 0, NULL); - err_check_propagate(retval); - retval = - dsp5680xx_drscan(target, (uint8_t *) &dummy_data_to_shift_into_dr, - (uint8_t *) data_read, 8); - err_check_propagate(retval); - LOG_DEBUG("Reg. data: 0x%02X.", *data_read); - return retval; -} - -static int eonce_read_status_reg(struct target *target, uint16_t *data) -{ - int retval; - - retval = dsp5680xx_read_core_reg(target, DSP5680XX_ONCE_OSR, data); - err_check_propagate(retval); - return retval; -} - -/** - * Takes the core out of debug mode. - * - * @param target - * @param eonce_status Data read from the EOnCE status register. - * - * @return - */ -static int eonce_exit_debug_mode(struct target *target, uint8_t *eonce_status) -{ - int retval; - - retval = - eonce_instruction_exec_single(target, 0x1F, 0, 0, 1, eonce_status); - err_check_propagate(retval); - return retval; -} - -static int switch_tap(struct target *target, struct jtag_tap *master_tap, - struct jtag_tap *core_tap) -{ - int retval = ERROR_OK; - - uint32_t instr; - - uint32_t ir_out; /* not used, just to make jtag happy. */ - - if (master_tap == NULL) { - master_tap = jtag_tap_by_string("dsp568013.chp"); - if (master_tap == NULL) { - retval = ERROR_FAIL; - const char *msg = "Failed to get master tap."; - - err_check(retval, DSP5680XX_ERROR_JTAG_TAP_FIND_MASTER, - msg); - } - } - if (core_tap == NULL) { - core_tap = jtag_tap_by_string("dsp568013.cpu"); - if (core_tap == NULL) { - retval = ERROR_FAIL; - err_check(retval, DSP5680XX_ERROR_JTAG_TAP_FIND_CORE, - "Failed to get core tap."); - } - } - - if (!(((int)master_tap->enabled) ^ ((int)core_tap->enabled))) { - LOG_WARNING - ("Master:%d\nCore:%d\nOnly 1 should be enabled.\n", - (int)master_tap->enabled, (int)core_tap->enabled); - } - - if (master_tap->enabled) { - instr = 0x5; - retval = - dsp5680xx_irscan(target, &instr, &ir_out, - DSP5680XX_JTAG_MASTER_TAP_IRLEN); - err_check_propagate(retval); - instr = 0x2; - retval = - dsp5680xx_drscan(target, (uint8_t *) &instr, - (uint8_t *) &ir_out, 4); - err_check_propagate(retval); - core_tap->enabled = true; - master_tap->enabled = false; - } else { - instr = 0x08; - retval = - dsp5680xx_irscan(target, &instr, &ir_out, - DSP5680XX_JTAG_CORE_TAP_IRLEN); - err_check_propagate(retval); - instr = 0x1; - retval = - dsp5680xx_drscan(target, (uint8_t *) &instr, - (uint8_t *) &ir_out, 4); - err_check_propagate(retval); - core_tap->enabled = false; - master_tap->enabled = true; - } - return retval; -} - -/** - * Puts the core into debug mode, enabling the EOnCE module. - * This will not always work, eonce_enter_debug_mode executes much - * more complicated routine, which is guaranteed to work, but requires - * a reset. This will complicate comm with the flash module, since - * after a reset clock divisors must be set again. - * This implementation works most of the time, and is not accesible to the - * user. - * - * @param target - * @param eonce_status Data read from the EOnCE status register. - * - * @return - */ -static int eonce_enter_debug_mode_without_reset(struct target *target, - uint16_t *eonce_status) -{ - int retval; - - uint32_t instr = JTAG_INSTR_DEBUG_REQUEST; - - uint32_t ir_out; /* not used, just to make jtag happy.*/ - - /* Debug request #1 */ - retval = - dsp5680xx_irscan(target, &instr, &ir_out, - DSP5680XX_JTAG_CORE_TAP_IRLEN); - err_check_propagate(retval); - - /* Enable EOnCE module */ - instr = JTAG_INSTR_ENABLE_ONCE; - /* Two rounds of jtag 0x6 (enable eonce) to enable EOnCE. */ - retval = - dsp5680xx_irscan(target, &instr, &ir_out, - DSP5680XX_JTAG_CORE_TAP_IRLEN); - err_check_propagate(retval); - retval = - dsp5680xx_irscan(target, &instr, &ir_out, - DSP5680XX_JTAG_CORE_TAP_IRLEN); - err_check_propagate(retval); - if ((ir_out & JTAG_STATUS_MASK) == JTAG_STATUS_DEBUG) - target->state = TARGET_HALTED; - else { - retval = ERROR_FAIL; - err_check_propagate(retval); - } - /* Verify that debug mode is enabled */ - uint16_t data_read_from_dr; - - retval = eonce_read_status_reg(target, &data_read_from_dr); - err_check_propagate(retval); - if ((data_read_from_dr & 0x30) == 0x30) { - LOG_DEBUG("EOnCE successfully entered debug mode."); - dsp5680xx_context.debug_mode_enabled = true; - retval = ERROR_OK; - } else { - dsp5680xx_context.debug_mode_enabled = false; - retval = ERROR_TARGET_FAILURE; - /** - *No error msg here, since there is still hope with full halting sequence - */ - err_check_propagate(retval); - } - if (eonce_status != NULL) - *eonce_status = data_read_from_dr; - return retval; -} - -/** - * Puts the core into debug mode, enabling the EOnCE module. - * - * @param target - * @param eonce_status Data read from the EOnCE status register. - * - * @return - */ -static int eonce_enter_debug_mode(struct target *target, - uint16_t *eonce_status) -{ - int retval = ERROR_OK; - - uint32_t instr = JTAG_INSTR_DEBUG_REQUEST; - - uint32_t ir_out; /* not used, just to make jtag happy. */ - - uint16_t instr_16; - - uint16_t read_16; - - /* First try the easy way */ - retval = eonce_enter_debug_mode_without_reset(target, eonce_status); - if (retval == ERROR_OK) - return retval; - - struct jtag_tap *tap_chp; - - struct jtag_tap *tap_cpu; - - tap_chp = jtag_tap_by_string("dsp568013.chp"); - if (tap_chp == NULL) { - retval = ERROR_FAIL; - err_check(retval, DSP5680XX_ERROR_JTAG_TAP_FIND_MASTER, - "Failed to get master tap."); - } - tap_cpu = jtag_tap_by_string("dsp568013.cpu"); - if (tap_cpu == NULL) { - retval = ERROR_FAIL; - err_check(retval, DSP5680XX_ERROR_JTAG_TAP_FIND_CORE, - "Failed to get master tap."); - } - /* Enable master tap */ - tap_chp->enabled = true; - tap_cpu->enabled = false; - - instr = MASTER_TAP_CMD_IDCODE; - retval = - dsp5680xx_irscan(target, &instr, &ir_out, - DSP5680XX_JTAG_MASTER_TAP_IRLEN); - err_check_propagate(retval); - jtag_add_sleep(TIME_DIV_FREESCALE * 100 * 1000); - - /* Enable EOnCE module */ - jtag_add_reset(0, 1); - jtag_add_sleep(TIME_DIV_FREESCALE * 200 * 1000); - instr = 0x0606ffff; /* This was selected experimentally. */ - retval = - dsp5680xx_drscan(target, (uint8_t *) &instr, (uint8_t *) &ir_out, - 32); - err_check_propagate(retval); - /* ir_out now hold tap idcode */ - - /* Enable core tap */ - tap_chp->enabled = true; - retval = switch_tap(target, tap_chp, tap_cpu); - err_check_propagate(retval); - - instr = JTAG_INSTR_ENABLE_ONCE; - /* Two rounds of jtag 0x6 (enable eonce) to enable EOnCE. */ - retval = - dsp5680xx_irscan(target, &instr, &ir_out, - DSP5680XX_JTAG_CORE_TAP_IRLEN); - err_check_propagate(retval); - instr = JTAG_INSTR_DEBUG_REQUEST; - retval = - dsp5680xx_irscan(target, &instr, &ir_out, - DSP5680XX_JTAG_CORE_TAP_IRLEN); - err_check_propagate(retval); - instr_16 = 0x1; - retval = - dsp5680xx_drscan(target, (uint8_t *) &instr_16, - (uint8_t *) &read_16, 8); - err_check_propagate(retval); - instr_16 = 0x20; - retval = - dsp5680xx_drscan(target, (uint8_t *) &instr_16, - (uint8_t *) &read_16, 8); - err_check_propagate(retval); - jtag_add_sleep(TIME_DIV_FREESCALE * 100 * 1000); - jtag_add_reset(0, 0); - jtag_add_sleep(TIME_DIV_FREESCALE * 300 * 1000); - - instr = JTAG_INSTR_ENABLE_ONCE; - /* Two rounds of jtag 0x6 (enable eonce) to enable EOnCE. */ - for (int i = 0; i < 3; i++) { - retval = - dsp5680xx_irscan(target, &instr, &ir_out, - DSP5680XX_JTAG_CORE_TAP_IRLEN); - err_check_propagate(retval); - } - if ((ir_out & JTAG_STATUS_MASK) == JTAG_STATUS_DEBUG) - target->state = TARGET_HALTED; - else { - retval = ERROR_FAIL; - err_check(retval, DSP5680XX_ERROR_HALT, - "Failed to halt target."); - } - - for (int i = 0; i < 3; i++) { - instr_16 = 0x86; - dsp5680xx_drscan(target, (uint8_t *) &instr_16, - (uint8_t *) &read_16, 16); - instr_16 = 0xff; - dsp5680xx_drscan(target, (uint8_t *) &instr_16, - (uint8_t *) &read_16, 16); - } - - /* Verify that debug mode is enabled */ - uint16_t data_read_from_dr; - - retval = eonce_read_status_reg(target, &data_read_from_dr); - err_check_propagate(retval); - if ((data_read_from_dr & 0x30) == 0x30) { - LOG_DEBUG("EOnCE successfully entered debug mode."); - dsp5680xx_context.debug_mode_enabled = true; - retval = ERROR_OK; - } else { - const char *msg = "Failed to set EOnCE module to debug mode"; - - retval = ERROR_TARGET_FAILURE; - err_check(retval, DSP5680XX_ERROR_ENTER_DEBUG_MODE, msg); - } - if (eonce_status != NULL) - *eonce_status = data_read_from_dr; - return retval; -} - -/** - * Reads the current value of the program counter and stores it. - * - * @param target - * - * @return - */ -static int eonce_pc_store(struct target *target) -{ - uint8_t tmp[2]; - - int retval; - - retval = core_move_pc_to_r4(target); - err_check_propagate(retval); - retval = core_move_r4_to_y(target); - err_check_propagate(retval); - retval = eonce_load_TX_RX_to_r0(target); - err_check_propagate(retval); - retval = core_move_y0_at_r0(target); - err_check_propagate(retval); - retval = core_rx_lower_data(target, tmp); - err_check_propagate(retval); - LOG_USER("PC value: 0x%X%X\n", tmp[1], tmp[0]); - dsp5680xx_context.stored_pc = (tmp[0] | (tmp[1] << 8)); - return ERROR_OK; -} - -static int dsp5680xx_target_create(struct target *target, Jim_Interp *interp) -{ - struct dsp5680xx_common *dsp5680xx = - calloc(1, sizeof(struct dsp5680xx_common)); - target->arch_info = dsp5680xx; - return ERROR_OK; -} - -static int dsp5680xx_init_target(struct command_context *cmd_ctx, - struct target *target) -{ - dsp5680xx_context.stored_pc = 0; - dsp5680xx_context.flush = 1; - dsp5680xx_context.debug_mode_enabled = false; - LOG_DEBUG("target initiated!"); - /* TODO core tap must be enabled before running these commands, currently - * this is done in the .cfg tcl script. */ - return ERROR_OK; -} - -static int dsp5680xx_arch_state(struct target *target) -{ - LOG_USER("%s not implemented yet.", __func__); - return ERROR_OK; -} - -int dsp5680xx_target_status(struct target *target, uint8_t *jtag_st, - uint16_t *eonce_st) -{ - return target->state; -} - -static int dsp5680xx_assert_reset(struct target *target) -{ - target->state = TARGET_RESET; - return ERROR_OK; -} - -static int dsp5680xx_deassert_reset(struct target *target) -{ - target->state = TARGET_RUNNING; - return ERROR_OK; -} - -static int dsp5680xx_halt(struct target *target) -{ - int retval; - - uint16_t eonce_status = 0xbeef; - - if ((target->state == TARGET_HALTED) - && (dsp5680xx_context.debug_mode_enabled)) { - LOG_USER("Target already halted and in debug mode."); - return ERROR_OK; - } else { - if (target->state == TARGET_HALTED) - LOG_USER - ("Target already halted, re attempting to enter debug mode."); - } - retval = eonce_enter_debug_mode(target, &eonce_status); - err_check_propagate(retval); - retval = eonce_pc_store(target); - err_check_propagate(retval); - if (dsp5680xx_context.debug_mode_enabled) { - retval = eonce_pc_store(target); - err_check_propagate(retval); - } - return retval; -} - -static int dsp5680xx_poll(struct target *target) -{ - int retval; - - uint8_t jtag_status; - - uint8_t eonce_status; - - uint16_t read_tmp; - - retval = dsp5680xx_jtag_status(target, &jtag_status); - err_check_propagate(retval); - if (jtag_status == JTAG_STATUS_DEBUG) - if (target->state != TARGET_HALTED) { - retval = eonce_enter_debug_mode(target, &read_tmp); - err_check_propagate(retval); - eonce_status = (uint8_t) read_tmp; - if ((eonce_status & EONCE_STAT_MASK) != - DSP5680XX_ONCE_OSCR_DEBUG_M) { - const char *msg = - "%s: Failed to put EOnCE in debug mode.Flash locked?..."; - LOG_WARNING(msg, __func__); - return ERROR_TARGET_FAILURE; - } else { - target->state = TARGET_HALTED; - return ERROR_OK; - } - } - if (jtag_status == JTAG_STATUS_NORMAL) { - if (target->state == TARGET_RESET) { - retval = dsp5680xx_halt(target); - err_check_propagate(retval); - retval = eonce_exit_debug_mode(target, &eonce_status); - err_check_propagate(retval); - if ((eonce_status & EONCE_STAT_MASK) != - DSP5680XX_ONCE_OSCR_NORMAL_M) { - const char *msg = - "%s: JTAG running, but EOnCE run failed.Try resetting.."; - LOG_WARNING(msg, __func__); - return ERROR_TARGET_FAILURE; - } else { - target->state = TARGET_RUNNING; - return ERROR_OK; - } - } - if (target->state != TARGET_RUNNING) { - retval = eonce_read_status_reg(target, &read_tmp); - err_check_propagate(retval); - eonce_status = (uint8_t) read_tmp; - if ((eonce_status & EONCE_STAT_MASK) != - DSP5680XX_ONCE_OSCR_NORMAL_M) { - LOG_WARNING - ("Inconsistent target status. Restart!"); - return ERROR_TARGET_FAILURE; - } - } - target->state = TARGET_RUNNING; - return ERROR_OK; - } - if (jtag_status == JTAG_STATUS_DEAD) { - LOG_ERROR - ("%s: Cannot communicate with JTAG. Check connection...", - __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) -{ - if (target->state == TARGET_RUNNING) { - LOG_USER("Target already running."); - return ERROR_OK; - } - int retval; - - uint8_t eonce_status; - - uint8_t jtag_status; - - if (dsp5680xx_context.debug_mode_enabled) { - if (!current) { - retval = core_move_value_to_pc(target, address); - err_check_propagate(retval); - } - - int retry = 20; - - while (retry-- > 1) { - retval = eonce_exit_debug_mode(target, &eonce_status); - err_check_propagate(retval); - if (eonce_status == DSP5680XX_ONCE_OSCR_NORMAL_M) - break; - } - if (retry == 0) { - retval = ERROR_TARGET_FAILURE; - err_check(retval, DSP5680XX_ERROR_EXIT_DEBUG_MODE, - "Failed to exit debug mode..."); - } else { - target->state = TARGET_RUNNING; - dsp5680xx_context.debug_mode_enabled = false; - } - LOG_DEBUG("EOnCE status: 0x%02X.", eonce_status); - } else { - /* - * If debug mode was not enabled but target was halted, then it is most likely that - * access to eonce registers is locked. - * Reset target to make it run again. - */ - jtag_add_reset(0, 1); - jtag_add_sleep(TIME_DIV_FREESCALE * 200 * 1000); - - retval = reset_jtag(); - err_check(retval, DSP5680XX_ERROR_JTAG_RESET, - "Failed to reset JTAG state machine"); - jtag_add_sleep(TIME_DIV_FREESCALE * 100 * 1000); - jtag_add_reset(0, 0); - jtag_add_sleep(TIME_DIV_FREESCALE * 300 * 1000); - retval = dsp5680xx_jtag_status(target, &jtag_status); - err_check_propagate(retval); - if ((jtag_status & JTAG_STATUS_MASK) == JTAG_STATUS_NORMAL) { - target->state = TARGET_RUNNING; - dsp5680xx_context.debug_mode_enabled = false; - } else { - retval = ERROR_TARGET_FAILURE; - err_check(retval, DSP5680XX_ERROR_RESUME, - "Failed to resume target"); - } - } - return ERROR_OK; -} - -/** - * The value of @address determines if it corresponds to P: (program) or X: (dat) memory. - * If the address is over 0x200000 then it is considered X: memory, and @pmem = 0. - * The special case of 0xFFXXXX is not modified, since it allows to read out the - * memory mapped EOnCE registers. - * - * @param address - * @param pmem - * - * @return - */ -static int dsp5680xx_convert_address(uint32_t *address, int *pmem) -{ - /* - * Distinguish data memory (x) from program memory (p) by the address. - * Addresses over S_FILE_DATA_OFFSET are considered (x) memory. - */ - if (*address >= S_FILE_DATA_OFFSET) { - *pmem = 0; - if (((*address) & 0xff0000) != 0xff0000) - *address -= S_FILE_DATA_OFFSET; - } - return ERROR_OK; -} - -static int dsp5680xx_read_16_single(struct target *t, uint32_t a, - uint8_t *data_read, int r_pmem) -{ - struct target *target = t; - - uint32_t address = a; - - int retval; - - retval = core_move_long_to_r0(target, address); - err_check_propagate(retval); - if (r_pmem) - retval = core_move_at_pr0_inc_to_y0(target); - else - retval = core_move_at_r0_to_y0(target); - err_check_propagate(retval); - retval = eonce_load_TX_RX_to_r0(target); - err_check_propagate(retval); - retval = core_move_y0_at_r0(target); - err_check_propagate(retval); - /* at this point the data i want is at the reg eonce can read */ - retval = core_rx_lower_data(target, data_read); - err_check_propagate(retval); - LOG_DEBUG("%s:Data read from 0x%06" PRIX32 ": 0x%02X%02X", __func__, address, - data_read[1], data_read[0]); - return retval; -} - -static int dsp5680xx_read_32_single(struct target *t, uint32_t a, - uint8_t *data_read, int r_pmem) -{ - struct target *target = t; - - uint32_t address = a; - - int retval; - - address = (address & 0xFFFFF); - /* Get data to an intermediate register */ - retval = core_move_long_to_r0(target, address); - err_check_propagate(retval); - if (r_pmem) { - retval = core_move_at_pr0_inc_to_y0(target); - err_check_propagate(retval); - retval = core_move_at_pr0_inc_to_y1(target); - err_check_propagate(retval); - } else { - retval = core_move_at_r0_inc_to_y0(target); - err_check_propagate(retval); - retval = core_move_at_r0_to_y1(target); - err_check_propagate(retval); - } - /* Get lower part of data to TX/RX */ - retval = eonce_load_TX_RX_to_r0(target); - err_check_propagate(retval); - retval = core_move_y0_at_r0_inc(target); /* This also load TX/RX high to r0 */ - err_check_propagate(retval); - /* Get upper part of data to TX/RX */ - retval = core_move_y1_at_r0(target); - err_check_propagate(retval); - /* at this point the data i want is at the reg eonce can read */ - retval = core_rx_lower_data(target, data_read); - err_check_propagate(retval); - retval = core_rx_upper_data(target, data_read + 2); - err_check_propagate(retval); - return retval; -} - -static int dsp5680xx_read(struct target *t, uint32_t a, uint32_t size, - uint32_t count, uint8_t *buf) -{ - struct target *target = t; - - uint32_t address = a; - - uint8_t *buffer = buf; - - check_halt_and_debug(target); - - int retval = ERROR_OK; - - int pmem = 1; - - retval = dsp5680xx_convert_address(&address, &pmem); - err_check_propagate(retval); - - dsp5680xx_context.flush = 0; - int counter = FLUSH_COUNT_READ_WRITE; - - for (unsigned i = 0; i < count; i++) { - if (--counter == 0) { - dsp5680xx_context.flush = 1; - counter = FLUSH_COUNT_READ_WRITE; - } - switch (size) { - case 1: - if (!(i % 2)) - retval = - dsp5680xx_read_16_single(target, - address + i / 2, - buffer + i, pmem); - break; - case 2: - retval = - dsp5680xx_read_16_single(target, address + i, - buffer + 2 * i, pmem); - break; - case 4: - retval = - dsp5680xx_read_32_single(target, address + 2 * i, - buffer + 4 * i, pmem); - break; - default: - LOG_USER("%s: Invalid read size.", __func__); - break; - } - err_check_propagate(retval); - dsp5680xx_context.flush = 0; - } - - dsp5680xx_context.flush = 1; - retval = dsp5680xx_execute_queue(); - err_check_propagate(retval); - - return retval; -} - -static int dsp5680xx_write_16_single(struct target *t, uint32_t a, - uint16_t data, uint8_t w_pmem) -{ - struct target *target = t; - - uint32_t address = a; - - int retval = 0; - - retval = core_move_long_to_r0(target, address); - err_check_propagate(retval); - if (w_pmem) { - retval = core_move_value_to_y0(target, data); - err_check_propagate(retval); - retval = core_move_y0_at_pr0_inc(target); - err_check_propagate(retval); - } else { - retval = core_move_value_at_r0(target, data); - err_check_propagate(retval); - } - return retval; -} - -static int dsp5680xx_write_32_single(struct target *t, uint32_t a, - uint32_t data, int w_pmem) -{ - struct target *target = t; - - uint32_t address = a; - - int retval = ERROR_OK; - - retval = core_move_long_to_r0(target, address); - err_check_propagate(retval); - retval = core_move_long_to_y(target, data); - err_check_propagate(retval); - if (w_pmem) - retval = core_move_y0_at_pr0_inc(target); - else - retval = core_move_y0_at_r0_inc(target); - err_check_propagate(retval); - if (w_pmem) - retval = core_move_y1_at_pr0_inc(target); - else - retval = core_move_y1_at_r0_inc(target); - err_check_propagate(retval); - return retval; -} - -static int dsp5680xx_write_8(struct target *t, uint32_t a, uint32_t c, - const uint8_t *d, int pmem) -{ - struct target *target = t; - - uint32_t address = a; - - uint32_t count = c; - - const uint8_t *data = d; - - int retval = 0; - - uint16_t data_16; - - uint32_t iter; - - int counter = FLUSH_COUNT_READ_WRITE; - - for (iter = 0; iter < count / 2; iter++) { - if (--counter == 0) { - dsp5680xx_context.flush = 1; - counter = FLUSH_COUNT_READ_WRITE; - } - data_16 = (data[2 * iter] | (data[2 * iter + 1] << 8)); - retval = - dsp5680xx_write_16_single(target, address + iter, data_16, - pmem); - if (retval != ERROR_OK) { - LOG_ERROR("%s: Could not write to p:0x%04" PRIX32, __func__, - address); - dsp5680xx_context.flush = 1; - return retval; - } - dsp5680xx_context.flush = 0; - } - dsp5680xx_context.flush = 1; - - /* Only one byte left, let's not overwrite the other byte (mem is 16bit) */ - /* Need to retrieve the part we do not want to overwrite. */ - uint16_t data_old; - - if ((count == 1) || (count % 2)) { - retval = - dsp5680xx_read(target, address + iter, 1, 1, - (uint8_t *) &data_old); - err_check_propagate(retval); - if (count == 1) - data_old = (((data_old & 0xff) << 8) | data[0]); /* preserve upper byte */ - else - data_old = - (((data_old & 0xff) << 8) | data[2 * iter + 1]); - retval = - dsp5680xx_write_16_single(target, address + iter, data_old, - pmem); - err_check_propagate(retval); - } - return retval; -} - -static int dsp5680xx_write_16(struct target *t, uint32_t a, uint32_t c, - const uint8_t *d, int pmem) -{ - struct target *target = t; - - uint32_t address = a; - - uint32_t count = c; - - const uint8_t *data = d; - - int retval = ERROR_OK; - - uint32_t iter; - - int counter = FLUSH_COUNT_READ_WRITE; - - for (iter = 0; iter < count; iter++) { - if (--counter == 0) { - dsp5680xx_context.flush = 1; - counter = FLUSH_COUNT_READ_WRITE; - } - retval = - dsp5680xx_write_16_single(target, address + iter, - data[iter], pmem); - if (retval != ERROR_OK) { - LOG_ERROR("%s: Could not write to p:0x%04" PRIX32, __func__, - address); - dsp5680xx_context.flush = 1; - return retval; - } - dsp5680xx_context.flush = 0; - } - dsp5680xx_context.flush = 1; - return retval; -} - -static int dsp5680xx_write_32(struct target *t, uint32_t a, uint32_t c, - const uint8_t *d, int pmem) -{ - struct target *target = t; - - uint32_t address = a; - - uint32_t count = c; - - const uint8_t *data = d; - - int retval = ERROR_OK; - - uint32_t iter; - - int counter = FLUSH_COUNT_READ_WRITE; - - for (iter = 0; iter < count; iter++) { - if (--counter == 0) { - dsp5680xx_context.flush = 1; - counter = FLUSH_COUNT_READ_WRITE; - } - retval = - dsp5680xx_write_32_single(target, address + (iter << 1), - data[iter], pmem); - if (retval != ERROR_OK) { - LOG_ERROR("%s: Could not write to p:0x%04" PRIX32, __func__, - address); - dsp5680xx_context.flush = 1; - return retval; - } - dsp5680xx_context.flush = 0; - } - dsp5680xx_context.flush = 1; - return retval; -} - -/** - * Writes @buffer to memory. - * The parameter @address determines whether @buffer should be written to - * P: (program) memory or X: (dat) memory. - * - * @param target - * @param address - * @param size Bytes (1), Half words (2), Words (4). - * @param count In bytes. - * @param buffer - * - * @return - */ -static int dsp5680xx_write(struct target *t, uint32_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 */ - struct target *target = t; - - uint32_t address = a; - - uint32_t count = c; - - uint8_t const *buffer = b; - - uint32_t size = s; - - check_halt_and_debug(target); - - int retval = 0; - - int p_mem = 1; - - retval = dsp5680xx_convert_address(&address, &p_mem); - err_check_propagate(retval); - - switch (size) { - case 1: - retval = - dsp5680xx_write_8(target, address, count, buffer, p_mem); - break; - case 2: - retval = - dsp5680xx_write_16(target, address, count, buffer, p_mem); - break; - case 4: - retval = - dsp5680xx_write_32(target, address, count, buffer, p_mem); - break; - default: - retval = ERROR_TARGET_DATA_ABORT; - err_check(retval, DSP5680XX_ERROR_INVALID_DATA_SIZE_UNIT, - "Invalid data size."); - break; - } - return retval; -} - -static int dsp5680xx_write_buffer(struct target *t, uint32_t a, uint32_t size, - const uint8_t *b) -{ - check_halt_and_debug(t); - return dsp5680xx_write(t, a, 1, size, b); -} - -/** - * This function is called by verify_image, it is used to read data from memory. - * - * @param target - * @param address Word addressing. - * @param size In bytes. - * @param buffer - * - * @return - */ -static int dsp5680xx_read_buffer(struct target *t, uint32_t a, uint32_t size, - uint8_t *buf) -{ - check_halt_and_debug(t); - /* The "/2" solves the byte/word addressing issue.*/ - return dsp5680xx_read(t, a, 2, size / 2, buf); -} - -/** - * This function is not implemented. - * It returns an error in order to get OpenOCD to do read out the data - * and calculate the CRC, or try a binary comparison. - * - * @param target - * @param address Start address of the image. - * @param size In bytes. - * @param checksum - * - * @return - */ -static int dsp5680xx_checksum_memory(struct target *t, uint32_t a, uint32_t s, - uint32_t *checksum) -{ - return ERROR_FAIL; -} - -/** - * Calculates a signature over @word_count words in the data from @buff16. - * The algorithm used is the same the FM uses, so the @return may be used to compare - * with the one generated by the FM module, and check if flashing was successful. - * This algorithm is based on the perl script available from the Freescale website at FAQ 25630. - * - * @param buff16 - * @param word_count - * - * @return - */ -static int perl_crc(const uint8_t *buff8, uint32_t word_count) -{ - uint16_t checksum = 0xffff; - - uint16_t data, fbmisr; - - uint32_t i; - - for (i = 0; i < word_count; i++) { - data = (buff8[2 * i] | (buff8[2 * i + 1] << 8)); - fbmisr = - (checksum & 2) >> 1 ^ (checksum & 4) >> 2 ^ (checksum & 16) - >> 4 ^ (checksum & 0x8000) >> 15; - checksum = (data ^ ((checksum << 1) | fbmisr)); - } - i--; - for (; !(i & 0x80000000); i--) { - data = (buff8[2 * i] | (buff8[2 * i + 1] << 8)); - fbmisr = - (checksum & 2) >> 1 ^ (checksum & 4) >> 2 ^ (checksum & 16) - >> 4 ^ (checksum & 0x8000) >> 15; - checksum = (data ^ ((checksum << 1) | fbmisr)); - } - return checksum; -} - -/** - * Resets the SIM. (System Integration Modul). - * - * @param target - * - * @return - */ -int dsp5680xx_f_SIM_reset(struct target *target) -{ - int retval = ERROR_OK; - - uint16_t sim_cmd = SIM_CMD_RESET; - - uint32_t sim_addr; - - if (strcmp(target->tap->chip, "dsp568013") == 0) { - sim_addr = MC568013_SIM_BASE_ADDR + S_FILE_DATA_OFFSET; - retval = - dsp5680xx_write(target, sim_addr, 1, 2, - (const uint8_t *)&sim_cmd); - err_check_propagate(retval); - } - return retval; -} - -/** - * Halts the core and resets the SIM. (System Integration Modul). - * - * @param target - * - * @return - */ -static int dsp5680xx_soft_reset_halt(struct target *target) -{ - /* TODO is this what this function is expected to do...? */ - int retval; - - retval = dsp5680xx_halt(target); - err_check_propagate(retval); - retval = dsp5680xx_f_SIM_reset(target); - err_check_propagate(retval); - return retval; -} - -int dsp5680xx_f_protect_check(struct target *target, uint16_t *protected) -{ - int retval; - - check_halt_and_debug(target); - if (protected == NULL) { - const char *msg = "NULL pointer not valid."; - - err_check(ERROR_FAIL, - DSP5680XX_ERROR_PROTECT_CHECK_INVALID_ARGS, msg); - } - retval = - dsp5680xx_read_16_single(target, HFM_BASE_ADDR | HFM_PROT, - (uint8_t *) protected, 0); - err_check_propagate(retval); - return retval; -} - -/** - * Executes a command on the FM module. - * Some commands use the parameters @address and @data, others ignore them. - * - * @param target - * @param command Command to execute. - * @param address Command parameter. - * @param data Command parameter. - * @param hfm_ustat FM status register. - * @param pmem Address is P: (program) memory (@pmem == 1) or X: (dat) memory (@pmem == 0) - * - * @return - */ -static int dsp5680xx_f_ex(struct target *t, uint16_t c, uint32_t a, uint32_t d, - uint16_t *h, int p) -{ - struct target *target = t; - - uint32_t command = c; - - uint32_t address = a; - - uint32_t data = d; - - uint16_t *hfm_ustat = h; - - int pmem = p; - - int retval; - - retval = core_load_TX_RX_high_addr_to_r0(target); - err_check_propagate(retval); - retval = core_move_long_to_r2(target, HFM_BASE_ADDR); - err_check_propagate(retval); - uint8_t i[2]; - - int watchdog = 100; - - do { - retval = core_move_at_r2_disp_to_y0(target, HFM_USTAT); /* read HMF_USTAT */ - err_check_propagate(retval); - retval = core_move_y0_at_r0(target); - err_check_propagate(retval); - retval = core_rx_upper_data(target, i); - err_check_propagate(retval); - if ((watchdog--) == 1) { - retval = ERROR_TARGET_FAILURE; - const char *msg = - "Timed out waiting for FM to finish old command."; - err_check(retval, DSP5680XX_ERROR_FM_BUSY, msg); - } - } while (!(i[0] & 0x40)); /* wait until current command is complete */ - - dsp5680xx_context.flush = 0; - - /* write to HFM_CNFG (lock=0,select bank) - flash_desc.bank&0x03, 0x01 == 0x00, 0x01 ??? */ - retval = core_move_value_at_r2_disp(target, 0x00, HFM_CNFG); - err_check_propagate(retval); - /* write to HMF_USTAT, clear PVIOL, ACCERR &BLANK bits */ - retval = core_move_value_at_r2_disp(target, 0x04, HFM_USTAT); - err_check_propagate(retval); - /* clear only one bit at a time */ - retval = core_move_value_at_r2_disp(target, 0x10, HFM_USTAT); - err_check_propagate(retval); - retval = core_move_value_at_r2_disp(target, 0x20, HFM_USTAT); - err_check_propagate(retval); - /* write to HMF_PROT, clear protection */ - retval = core_move_value_at_r2_disp(target, 0x00, HFM_PROT); - err_check_propagate(retval); - /* write to HMF_PROTB, clear protection */ - retval = core_move_value_at_r2_disp(target, 0x00, HFM_PROTB); - err_check_propagate(retval); - retval = core_move_value_to_y0(target, data); - err_check_propagate(retval); - /* write to the flash block */ - retval = core_move_long_to_r3(target, address); - err_check_propagate(retval); - if (pmem) { - retval = core_move_y0_at_pr3_inc(target); - err_check_propagate(retval); - } else { - retval = core_move_y0_at_r3(target); - err_check_propagate(retval); - } - /* write command to the HFM_CMD reg */ - retval = core_move_value_at_r2_disp(target, command, HFM_CMD); - err_check_propagate(retval); - /* start the command */ - retval = core_move_value_at_r2_disp(target, 0x80, HFM_USTAT); - err_check_propagate(retval); - - dsp5680xx_context.flush = 1; - retval = dsp5680xx_execute_queue(); - err_check_propagate(retval); - - watchdog = 100; - do { - /* read HMF_USTAT */ - retval = core_move_at_r2_disp_to_y0(target, HFM_USTAT); - err_check_propagate(retval); - retval = core_move_y0_at_r0(target); - err_check_propagate(retval); - retval = core_rx_upper_data(target, i); - err_check_propagate(retval); - if ((watchdog--) == 1) { - retval = ERROR_TARGET_FAILURE; - err_check(retval, DSP5680XX_ERROR_FM_CMD_TIMED_OUT, - "FM execution did not finish."); - } - } while (!(i[0] & 0x40)); /* wait until the command is complete */ - *hfm_ustat = ((i[0] << 8) | (i[1])); - if (i[0] & HFM_USTAT_MASK_PVIOL_ACCER) { - retval = ERROR_TARGET_FAILURE; - const char *msg = - "pviol and/or accer bits set. HFM command execution error"; - err_check(retval, DSP5680XX_ERROR_FM_EXEC, msg); - } - return ERROR_OK; -} - -/** - * Prior to the execution of any Flash module command, the Flash module Clock Divider (CLKDIV) register must be initialized. The values of this register determine the speed of the internal Flash Clock (FCLK). FCLK must be in the range of 150kHz ≤ FCLK ≤ 200kHz for proper operation of the Flash module. (Running FCLK too slowly wears out the module, while running it too fast under programs Flash leading to bit errors.) - * - * @param target - * - * @return - */ -static int set_fm_ck_div(struct target *target) -{ - uint8_t i[2]; - - int retval; - - retval = core_move_long_to_r2(target, HFM_BASE_ADDR); - err_check_propagate(retval); - retval = core_load_TX_RX_high_addr_to_r0(target); - err_check_propagate(retval); - /* read HFM_CLKD */ - retval = core_move_at_r2_to_y0(target); - err_check_propagate(retval); - retval = core_move_y0_at_r0(target); - err_check_propagate(retval); - retval = core_rx_upper_data(target, i); - err_check_propagate(retval); - unsigned int hfm_at_wrong_value = 0; - - if ((i[0] & 0x7f) != HFM_CLK_DEFAULT) { - LOG_DEBUG("HFM CLK divisor contained incorrect value (0x%02X).", - i[0] & 0x7f); - hfm_at_wrong_value = 1; - } else { - LOG_DEBUG - ("HFM CLK divisor was already set to correct value (0x%02X).", - i[0] & 0x7f); - return ERROR_OK; - } - /* write HFM_CLKD */ - retval = core_move_value_at_r2(target, HFM_CLK_DEFAULT); - err_check_propagate(retval); - /* verify HFM_CLKD */ - retval = core_move_at_r2_to_y0(target); - err_check_propagate(retval); - retval = core_move_y0_at_r0(target); - err_check_propagate(retval); - retval = core_rx_upper_data(target, i); - err_check_propagate(retval); - if (i[0] != (0x80 | (HFM_CLK_DEFAULT & 0x7f))) { - retval = ERROR_TARGET_FAILURE; - err_check(retval, DSP5680XX_ERROR_FM_SET_CLK, - "Unable to set HFM CLK divisor."); - } - if (hfm_at_wrong_value) - LOG_DEBUG("HFM CLK divisor set to 0x%02x.", i[0] & 0x7f); - return ERROR_OK; -} - -/** - * Executes the FM calculate signature command. The FM will calculate over the data from @address to @address + @words -1. The result is written to a register, then read out by this function and returned in @signature. The value @signature may be compared to the the one returned by perl_crc to verify the flash was written correctly. - * - * @param target - * @param address Start of flash array where the signature should be calculated. - * @param words Number of words over which the signature should be calculated. - * @param signature Value calculated by the FM. - * - * @return - */ -static int dsp5680xx_f_signature(struct target *t, uint32_t a, uint32_t words, - uint16_t *signature) -{ - struct target *target = t; - - uint32_t address = a; - - int retval; - - uint16_t hfm_ustat; - - if (!dsp5680xx_context.debug_mode_enabled) { - retval = eonce_enter_debug_mode_without_reset(target, NULL); - /* - * Generate error here, since it is not done in eonce_enter_debug_mode_without_reset - */ - err_check(retval, DSP5680XX_ERROR_HALT, - "Failed to halt target."); - } - retval = - dsp5680xx_f_ex(target, HFM_CALCULATE_DATA_SIGNATURE, address, words, - &hfm_ustat, 1); - err_check_propagate(retval); - retval = - dsp5680xx_read_16_single(target, HFM_BASE_ADDR | HFM_DATA, - (uint8_t *) signature, 0); - return retval; -} - -int dsp5680xx_f_erase_check(struct target *target, uint8_t *erased, - uint32_t sector) -{ - int retval; - - uint16_t hfm_ustat; - - uint32_t tmp; - - if (!dsp5680xx_context.debug_mode_enabled) { - retval = dsp5680xx_halt(target); - err_check_propagate(retval); - } - retval = set_fm_ck_div(target); - err_check_propagate(retval); - /* - * Check if chip is already erased. - */ - tmp = HFM_FLASH_BASE_ADDR + sector * HFM_SECTOR_SIZE / 2; - retval = - dsp5680xx_f_ex(target, HFM_ERASE_VERIFY, tmp, 0, &hfm_ustat, 1); - err_check_propagate(retval); - if (erased != NULL) - *erased = (uint8_t) (hfm_ustat & HFM_USTAT_MASK_BLANK); - return retval; -} - -/** - * Executes the FM page erase command. - * - * @param target - * @param sector Page to erase. - * @param hfm_ustat FM module status register. - * - * @return - */ -static int erase_sector(struct target *target, int sector, uint16_t *hfm_ustat) -{ - int retval; - - uint32_t tmp = HFM_FLASH_BASE_ADDR + sector * HFM_SECTOR_SIZE / 2; - - retval = dsp5680xx_f_ex(target, HFM_PAGE_ERASE, tmp, 0, hfm_ustat, 1); - err_check_propagate(retval); - return retval; -} - -/** - * Executes the FM mass erase command. Erases the flash array completely. - * - * @param target - * @param hfm_ustat FM module status register. - * - * @return - */ -static int mass_erase(struct target *target, uint16_t *hfm_ustat) -{ - int retval; - - retval = dsp5680xx_f_ex(target, HFM_MASS_ERASE, 0, 0, hfm_ustat, 1); - return retval; -} - -int dsp5680xx_f_erase(struct target *target, int first, int last) -{ - int retval; - - if (!dsp5680xx_context.debug_mode_enabled) { - retval = dsp5680xx_halt(target); - err_check_propagate(retval); - } - /* - * Reset SIM - * - */ - retval = dsp5680xx_f_SIM_reset(target); - err_check_propagate(retval); - /* - * Set hfmdiv - * - */ - retval = set_fm_ck_div(target); - err_check_propagate(retval); - - uint16_t hfm_ustat; - - int do_mass_erase = ((!(first | last)) - || ((first == 0) - && (last == (HFM_SECTOR_COUNT - 1)))); - if (do_mass_erase) { - /* Mass erase */ - retval = mass_erase(target, &hfm_ustat); - err_check_propagate(retval); - } else { - for (int i = first; i <= last; i++) { - retval = erase_sector(target, i, &hfm_ustat); - err_check_propagate(retval); - } - } - return ERROR_OK; -} - -/* - * Algorithm for programming normal p: flash - * Follow state machine from "56F801x Peripheral Reference Manual"@163. - * Registers to set up before calling: - * r0: TX/RX high address. - * r2: FM module base address. - * r3: Destination address in flash. - * - * hfm_wait: // wait for buffer empty - * brclr #0x80, x:(r2+0x13), hfm_wait - * rx_check: // wait for input buffer full - * brclr #0x01, x:(r0-2), rx_check - * move.w x:(r0), y0 // read from Rx buffer - * move.w y0, p:(r3)+ - * move.w #0x20, x:(r2+0x14) // write PGM command - * move.w #0x80, x:(r2+0x13) // start the command - * move.w X:(R2+0x13), A // Read USTAT register - * brclr #0x20, A, accerr_check // protection violation check - * bfset #0x20, X:(R2+0x13) // clear pviol - * bra hfm_wait - * accerr_check: - * brclr #0x10, A, hfm_wait // access error check - * bfset #0x10, X:(R2+0x13) // clear accerr - * bra hfm_wait // loop - * 0x00000000 0x8A460013807D brclr #0x80, X:(R2+0x13),*+0 - * 0x00000003 0xE700 nop - * 0x00000004 0xE700 nop - * 0x00000005 0x8A44FFFE017B brclr #1, X:(R0-2),*-2 - * 0x00000008 0xE700 nop - * 0x00000009 0xF514 move.w X:(R0), Y0 - * 0x0000000A 0x8563 move.w Y0, P:(R3)+ - * 0x0000000B 0x864600200014 move.w #32, X:(R2+0x14) - * 0x0000000E 0x864600800013 move.w #128, X:(R2+0x13) - * 0x00000011 0xF0420013 move.w X:(R2+0x13), A - * 0x00000013 0x8B402004 brclr #0x20, A,*+6 - * 0x00000015 0x824600130020 bfset #0x20, X:(R2+0x13) - * 0x00000018 0xA967 bra *-24 - * 0x00000019 0x8B401065 brclr #0x10, A,*-25 - * 0x0000001B 0x824600130010 bfset #0x10, X:(R2+0x13) - * 0x0000001E 0xA961 bra *-30 - */ - -const uint16_t pgm_write_pflash[] = { 0x8A46, 0x0013, 0x807D, 0xE700, - 0xE700, 0x8A44, 0xFFFE, 0x017B, - 0xE700, 0xF514, 0x8563, 0x8646, - 0x0020, 0x0014, 0x8646, 0x0080, - 0x0013, 0xF042, 0x0013, 0x8B40, - 0x2004, 0x8246, 0x0013, 0x0020, - 0xA967, 0x8B40, 0x1065, 0x8246, - 0x0013, 0x0010, 0xA961 -}; - -const uint32_t pgm_write_pflash_length = 31; - -int dsp5680xx_f_wr(struct target *t, const uint8_t *b, uint32_t a, uint32_t count, - int is_flash_lock) -{ - struct target *target = t; - - uint32_t address = a; - - const uint8_t *buffer = b; - - int retval = ERROR_OK; - - if (!dsp5680xx_context.debug_mode_enabled) { - retval = eonce_enter_debug_mode(target, NULL); - err_check_propagate(retval); - } - /* - * Download the pgm that flashes. - * - */ - const uint32_t len = pgm_write_pflash_length; - - uint32_t ram_addr = 0x8700; - - /* - * This seems to be a safe address. - * This one is the one used by codewarrior in 56801x_flash.cfg - */ - if (!is_flash_lock) { - retval = - dsp5680xx_write(target, ram_addr, 1, len * 2, - (uint8_t *) pgm_write_pflash); - err_check_propagate(retval); - retval = dsp5680xx_execute_queue(); - err_check_propagate(retval); - } - /* - * Set hfmdiv - * - */ - retval = set_fm_ck_div(target); - err_check_propagate(retval); - /* - * Setup registers needed by pgm_write_pflash - * - */ - - dsp5680xx_context.flush = 0; - - retval = core_move_long_to_r3(target, address); /* Destination address to r3 */ - err_check_propagate(retval); - core_load_TX_RX_high_addr_to_r0(target); /* TX/RX reg address to r0 */ - err_check_propagate(retval); - retval = core_move_long_to_r2(target, HFM_BASE_ADDR); /* FM base address to r2 */ - err_check_propagate(retval); - /* - * Run flashing program. - * - */ - /* write to HFM_CNFG (lock=0, select bank) */ - retval = core_move_value_at_r2_disp(target, 0x00, HFM_CNFG); - err_check_propagate(retval); - /* write to HMF_USTAT, clear PVIOL, ACCERR &BLANK bits */ - retval = core_move_value_at_r2_disp(target, 0x04, HFM_USTAT); - err_check_propagate(retval); - /* clear only one bit at a time */ - retval = core_move_value_at_r2_disp(target, 0x10, HFM_USTAT); - err_check_propagate(retval); - retval = core_move_value_at_r2_disp(target, 0x20, HFM_USTAT); - err_check_propagate(retval); - /* write to HMF_PROT, clear protection */ - retval = core_move_value_at_r2_disp(target, 0x00, HFM_PROT); - err_check_propagate(retval); - /* write to HMF_PROTB, clear protection */ - retval = core_move_value_at_r2_disp(target, 0x00, HFM_PROTB); - err_check_propagate(retval); - if (count % 2) { - /* TODO implement handling of odd number of words. */ - retval = ERROR_FAIL; - const char *msg = "Cannot handle odd number of words."; - - err_check(retval, DSP5680XX_ERROR_FLASHING_INVALID_WORD_COUNT, - msg); - } - - dsp5680xx_context.flush = 1; - retval = dsp5680xx_execute_queue(); - err_check_propagate(retval); - - uint32_t drscan_data; - - uint16_t tmp = (buffer[0] | (buffer[1] << 8)); - - retval = core_tx_upper_data(target, tmp, &drscan_data); - err_check_propagate(retval); - - retval = dsp5680xx_resume(target, 0, ram_addr, 0, 0); - err_check_propagate(retval); - - int counter = FLUSH_COUNT_FLASH; - - dsp5680xx_context.flush = 0; - uint32_t i; - - for (i = 1; (i < count / 2) && (i < HFM_SIZE_WORDS); i++) { - if (--counter == 0) { - dsp5680xx_context.flush = 1; - counter = FLUSH_COUNT_FLASH; - } - tmp = (buffer[2 * i] | (buffer[2 * i + 1] << 8)); - retval = core_tx_upper_data(target, tmp, &drscan_data); - if (retval != ERROR_OK) { - dsp5680xx_context.flush = 1; - err_check_propagate(retval); - } - dsp5680xx_context.flush = 0; - } - dsp5680xx_context.flush = 1; - if (!is_flash_lock) { - /* - *Verify flash (skip when exec lock sequence) - * - */ - uint16_t signature; - - uint16_t pc_crc; - - retval = dsp5680xx_f_signature(target, address, i, &signature); - err_check_propagate(retval); - pc_crc = perl_crc(buffer, i); - if (pc_crc != signature) { - retval = ERROR_FAIL; - const char *msg = - "Flashed data failed CRC check, flash again!"; - err_check(retval, DSP5680XX_ERROR_FLASHING_CRC, msg); - } - } - return retval; -} - -int dsp5680xx_f_unlock(struct target *target) -{ - int retval = ERROR_OK; - - uint16_t eonce_status; - - uint32_t instr; - - uint32_t ir_out; - - struct jtag_tap *tap_chp; - - struct jtag_tap *tap_cpu; - - tap_chp = jtag_tap_by_string("dsp568013.chp"); - if (tap_chp == NULL) { - retval = ERROR_FAIL; - err_check(retval, DSP5680XX_ERROR_JTAG_TAP_ENABLE_MASTER, - "Failed to get master tap."); - } - tap_cpu = jtag_tap_by_string("dsp568013.cpu"); - if (tap_cpu == NULL) { - retval = ERROR_FAIL; - err_check(retval, DSP5680XX_ERROR_JTAG_TAP_ENABLE_CORE, - "Failed to get master tap."); - } - - retval = eonce_enter_debug_mode_without_reset(target, &eonce_status); - if (retval == ERROR_OK) - LOG_WARNING("Memory was not locked."); - - jtag_add_reset(0, 1); - jtag_add_sleep(TIME_DIV_FREESCALE * 200 * 1000); - - retval = reset_jtag(); - err_check(retval, DSP5680XX_ERROR_JTAG_RESET, - "Failed to reset JTAG state machine"); - jtag_add_sleep(150); - - /* Enable core tap */ - tap_chp->enabled = true; - retval = switch_tap(target, tap_chp, tap_cpu); - err_check_propagate(retval); - - instr = JTAG_INSTR_DEBUG_REQUEST; - retval = - dsp5680xx_irscan(target, &instr, &ir_out, - DSP5680XX_JTAG_CORE_TAP_IRLEN); - err_check_propagate(retval); - jtag_add_sleep(TIME_DIV_FREESCALE * 100 * 1000); - jtag_add_reset(0, 0); - jtag_add_sleep(TIME_DIV_FREESCALE * 300 * 1000); - - /* Enable master tap */ - tap_chp->enabled = false; - retval = switch_tap(target, tap_chp, tap_cpu); - err_check_propagate(retval); - - /* Execute mass erase to unlock */ - instr = MASTER_TAP_CMD_FLASH_ERASE; - retval = - dsp5680xx_irscan(target, &instr, &ir_out, - DSP5680XX_JTAG_MASTER_TAP_IRLEN); - err_check_propagate(retval); - - instr = HFM_CLK_DEFAULT; - retval = dsp5680xx_drscan(target, (uint8_t *) &instr, (uint8_t *) &ir_out, 16); - err_check_propagate(retval); - - jtag_add_sleep(TIME_DIV_FREESCALE * 150 * 1000); - jtag_add_reset(0, 1); - jtag_add_sleep(TIME_DIV_FREESCALE * 200 * 1000); - - retval = reset_jtag(); - err_check(retval, DSP5680XX_ERROR_JTAG_RESET, - "Failed to reset JTAG state machine"); - jtag_add_sleep(150); - - instr = 0x0606ffff; - retval = dsp5680xx_drscan(target, (uint8_t *) &instr, (uint8_t *) &ir_out, - 32); - err_check_propagate(retval); - - /* enable core tap */ - instr = 0x5; - retval = - dsp5680xx_irscan(target, &instr, &ir_out, - DSP5680XX_JTAG_MASTER_TAP_IRLEN); - err_check_propagate(retval); - instr = 0x2; - retval = dsp5680xx_drscan(target, (uint8_t *) &instr, (uint8_t *) &ir_out, - 4); - err_check_propagate(retval); - - tap_cpu->enabled = true; - tap_chp->enabled = false; - target->state = TARGET_RUNNING; - dsp5680xx_context.debug_mode_enabled = false; - return retval; -} - -int dsp5680xx_f_lock(struct target *target) -{ - int retval; - - struct jtag_tap *tap_chp; - - struct jtag_tap *tap_cpu; - uint16_t lock_word[] = { HFM_LOCK_FLASH }; - retval = dsp5680xx_f_wr(target, (uint8_t *) (lock_word), HFM_LOCK_ADDR_L, 2, 1); - err_check_propagate(retval); - - jtag_add_reset(0, 1); - jtag_add_sleep(TIME_DIV_FREESCALE * 200 * 1000); - - retval = reset_jtag(); - err_check(retval, DSP5680XX_ERROR_JTAG_RESET, - "Failed to reset JTAG state machine"); - jtag_add_sleep(TIME_DIV_FREESCALE * 100 * 1000); - jtag_add_reset(0, 0); - jtag_add_sleep(TIME_DIV_FREESCALE * 300 * 1000); - - tap_chp = jtag_tap_by_string("dsp568013.chp"); - if (tap_chp == NULL) { - retval = ERROR_FAIL; - err_check(retval, DSP5680XX_ERROR_JTAG_TAP_ENABLE_MASTER, - "Failed to get master tap."); - } - tap_cpu = jtag_tap_by_string("dsp568013.cpu"); - if (tap_cpu == NULL) { - retval = ERROR_FAIL; - err_check(retval, DSP5680XX_ERROR_JTAG_TAP_ENABLE_CORE, - "Failed to get master tap."); - } - target->state = TARGET_RUNNING; - dsp5680xx_context.debug_mode_enabled = false; - tap_cpu->enabled = false; - tap_chp->enabled = true; - retval = switch_tap(target, tap_chp, tap_cpu); - return retval; -} - -static int dsp5680xx_step(struct target *target, int current, uint32_t address, - int handle_breakpoints) -{ - err_check(ERROR_FAIL, DSP5680XX_ERROR_NOT_IMPLEMENTED_STEP, - "Not implemented yet."); -} - -/** Holds methods for dsp5680xx targets. */ -struct target_type dsp5680xx_target = { - .name = "dsp5680xx", - - .poll = dsp5680xx_poll, - .arch_state = dsp5680xx_arch_state, - - .halt = dsp5680xx_halt, - .resume = dsp5680xx_resume, - .step = dsp5680xx_step, - - .write_buffer = dsp5680xx_write_buffer, - .read_buffer = dsp5680xx_read_buffer, - - .assert_reset = dsp5680xx_assert_reset, - .deassert_reset = dsp5680xx_deassert_reset, - .soft_reset_halt = dsp5680xx_soft_reset_halt, - - .read_memory = dsp5680xx_read, - .write_memory = dsp5680xx_write, - - .checksum_memory = dsp5680xx_checksum_memory, - - .target_create = dsp5680xx_target_create, - .init_target = dsp5680xx_init_target, -}; diff --git a/src/target/dsp5680xx.h b/src/target/dsp5680xx.h deleted file mode 100644 index 842796bc7..000000000 --- a/src/target/dsp5680xx.h +++ /dev/null @@ -1,382 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2011 by Rodrigo L. Rosa * - * rodrigorosa.LG@gmail.com * - * * - * Based on dsp563xx_once.h written by Mathias Kuester * - * mkdorg@users.sourceforge.net * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifndef OPENOCD_TARGET_DSP5680XX_H -#define OPENOCD_TARGET_DSP5680XX_H - -#include - -/** - * @file dsp5680xx.h - * @author Rodrigo Rosa - * @date Thu Jun 9 18:54:38 2011 - * - * @brief Basic support for the 5680xx DSP from Freescale. - * The chip has two taps in the JTAG chain, the Master tap and the Core tap. - * In this code the Master tap is only used to unlock the flash memory by executing a JTAG instruction. - * - */ - -#define S_FILE_DATA_OFFSET 0x200000 -#define TIME_DIV_FREESCALE 0.3 - -/** ---------------------------------------------------------------- - * JTAG - *---------------------------------------------------------------- - */ -#define DSP5680XX_JTAG_CORE_TAP_IRLEN 4 -#define DSP5680XX_JTAG_MASTER_TAP_IRLEN 8 - -#define JTAG_STATUS_MASK 0x0F - -#define JTAG_STATUS_NORMAL 0x01 -#define JTAG_STATUS_STOPWAIT 0x05 -#define JTAG_STATUS_BUSY 0x09 -#define JTAG_STATUS_DEBUG 0x0D -#define JTAG_STATUS_DEAD 0x0f - -#define JTAG_INSTR_EXTEST 0x0 -#define JTAG_INSTR_SAMPLE_PRELOAD 0x1 -#define JTAG_INSTR_IDCODE 0x2 -#define JTAG_INSTR_EXTEST_PULLUP 0x3 -#define JTAG_INSTR_HIGHZ 0x4 -#define JTAG_INSTR_CLAMP 0x5 -#define JTAG_INSTR_ENABLE_ONCE 0x6 -#define JTAG_INSTR_DEBUG_REQUEST 0x7 -#define JTAG_INSTR_BYPASS 0xF - /** - * ---------------------------------------------------------------- - */ - -/** ---------------------------------------------------------------- - * Master TAP instructions from MC56F8000RM.pdf - * ---------------------------------------------------------------- - */ -#define MASTER_TAP_CMD_BYPASS 0xF -#define MASTER_TAP_CMD_IDCODE 0x2 -#define MASTER_TAP_CMD_TLM_SEL 0x5 -#define MASTER_TAP_CMD_FLASH_ERASE 0x8 - /** - * ---------------------------------------------------------------- - */ - - /** ---------------------------------------------------------------- - * EOnCE control register info - * ---------------------------------------------------------------- - */ -#define DSP5680XX_ONCE_OCR_EX (1<<5) -/* EX Bit Definition - 0 Remain in the Debug Processing State - 1 Leave the Debug Processing State */ -#define DSP5680XX_ONCE_OCR_GO (1<<6) -/* GO Bit Definition - 0 Inactive—No Action Taken - 1 Execute Controller Instruction */ -#define DSP5680XX_ONCE_OCR_RW (1<<7) -/** RW Bit Definition - * 0 Write To the Register Specified by the RS[4:0] Bits - * 1 ReadFrom the Register Specified by the RS[4:0] Bits - * ---------------------------------------------------------------- - */ - - /** ---------------------------------------------------------------- - * EOnCE Status Register - * ---------------------------------------------------------------- - */ -#define DSP5680XX_ONCE_OSCR_OS1 (1<<5) -#define DSP5680XX_ONCE_OSCR_OS0 (1<<4) - /** - * ---------------------------------------------------------------- - */ - - /** ---------------------------------------------------------------- - * EOnCE Core Status - Describes the operating status of the core controller - * ---------------------------------------------------------------- - */ -#define DSP5680XX_ONCE_OSCR_NORMAL_M (0) -/* 00 - Normal - Controller Core Executing Instructions or in Reset */ -#define DSP5680XX_ONCE_OSCR_STOPWAIT_M (DSP5680XX_ONCE_OSCR_OS0) -/* 01 - Stop/Wait - Controller Core in Stop or Wait Mode */ -#define DSP5680XX_ONCE_OSCR_BUSY_M (DSP5680XX_ONCE_OSCR_OS1) -/* 10 - Busy - Controller is Performing External or Peripheral Access (Wait States) */ -#define DSP5680XX_ONCE_OSCR_DEBUG_M (DSP5680XX_ONCE_OSCR_OS0|DSP5680XX_ONCE_OSCR_OS1) -/* 11 - Debug - Controller Core Halted and in Debug Mode */ -#define EONCE_STAT_MASK 0x30 - /** - * ---------------------------------------------------------------- - */ - - /** ---------------------------------------------------------------- - * Register Select Encoding (eonce_rev.1.0_0208081.pdf:14) - * ---------------------------------------------------------------- - */ -#define DSP5680XX_ONCE_NOREG 0x00 /* No register selected */ -#define DSP5680XX_ONCE_OCR 0x01 /* OnCE Debug Control Register */ -#define DSP5680XX_ONCE_OCNTR 0x02 /* OnCE Breakpoint and Trace Counter */ -#define DSP5680XX_ONCE_OSR 0x03 /* EOnCE status register */ -#define DSP5680XX_ONCE_OBAR 0x04 /* OnCE Breakpoint Address Register */ -#define DSP5680XX_ONCE_OBASE 0x05 /* EOnCE Peripheral Base Address register */ -#define DSP5680XX_ONCE_OTXRXSR 0x06 /* EOnCE TXRX Status and Control Register (OTXRXSR) */ -#define DSP5680XX_ONCE_OTX 0x07 /* EOnCE Transmit register (OTX) */ -#define DSP5680XX_ONCE_OPDBR 0x08 /* EOnCE Program Data Bus Register (OPDBR) */ -#define DSP5680XX_ONCE_OTX1 0x09 /* EOnCE Upper Transmit register (OTX1) */ -#define DSP5680XX_ONCE_OPABFR 0x0A /* OnCE Program Address Register—Fetch cycle */ -#define DSP5680XX_ONCE_ORX 0x0B /* EOnCE Receive register (ORX) */ -#define DSP5680XX_ONCE_OCNTR_C 0x0C /* Clear OCNTR */ -#define DSP5680XX_ONCE_ORX1 0x0D /* EOnCE Upper Receive register (ORX1) */ -#define DSP5680XX_ONCE_OTBCR 0x0E /* EOnCE Trace Buffer Control Reg (OTBCR) */ -#define DSP5680XX_ONCE_OPABER 0x10 /* OnCE Program Address Register—Execute cycle */ -#define DSP5680XX_ONCE_OPFIFO 0x11 /* OnCE Program address FIFO */ -#define DSP5680XX_ONCE_OBAR1 0x12 /* EOnCE Breakpoint 1 Unit 0 Address Reg.(OBAR1) */ -#define DSP5680XX_ONCE_OPABDR 0x13 /* OnCE Program Address Register—Decode cycle (OPABDR) */ - /** - * ---------------------------------------------------------------- - */ - -#define FLUSH_COUNT_READ_WRITE 8192 /* This value works, higher values (and lower...) may work as well. */ -#define FLUSH_COUNT_FLASH 8192 -/** ---------------------------------------------------------------- - * HFM (flash module) Commands (ref:MC56F801xRM.pdf:159) - * ---------------------------------------------------------------- - */ -#define HFM_ERASE_VERIFY 0x05 -#define HFM_CALCULATE_DATA_SIGNATURE 0x06 -#define HFM_WORD_PROGRAM 0x20 -#define HFM_PAGE_ERASE 0x40 -#define HFM_MASS_ERASE 0x41 -#define HFM_CALCULATE_IFR_BLOCK_SIGNATURE 0x66 - /** - * ---------------------------------------------------------------- - */ - -/** ---------------------------------------------------------------- - * Flashing (ref:MC56F801xRM.pdf:159) - * ---------------------------------------------------------------- - */ -#define HFM_BASE_ADDR 0x0F400 /** In x: mem. (write to S_FILE_DATA_OFFSET+HFM_BASE_ADDR - * to get data into x: mem.) - */ -/** - * The following are register addresses, not memory - * addresses (though all registers are memory mapped) - */ -#define HFM_CLK_DIV 0x00 /* r/w */ -#define HFM_CNFG 0x01 /* r/w */ -#define HFM_SECHI 0x03 /* r */ -#define HFM_SECLO 0x04 /* r */ -#define HFM_PROT 0x10 /* r/w */ -#define HFM_PROTB 0x11 /* r/w */ -#define HFM_USTAT 0x13 /* r/w */ -#define HFM_CMD 0x14 /* r/w */ -#define HFM_DATA 0x18 /* r */ -#define HFM_OPT1 0x1B /* r */ -#define HFM_TSTSIG 0x1D /* r */ - -#define HFM_EXEC_COMPLETE 0x40 - -/* User status register (USTAT) masks (MC56F80XXRM.pdf:6.7.5) */ -#define HFM_USTAT_MASK_BLANK 0x4 -#define HFM_USTAT_MASK_PVIOL_ACCER 0x30 - -/** - * The value used on for the FM clock is important to prevent flashing errors and to prevent deterioration of the FM. - * This value was calculated using a spreadsheet tool available on the Freescale website under FAQ 25464. - * - */ -#define HFM_CLK_DEFAULT 0x27 -/* 0x27 according to freescale cfg, but 0x40 according to freescale spreadsheet... */ -#define HFM_FLASH_BASE_ADDR 0x0 -#define HFM_SIZE_BYTES 0x4000 /* bytes */ -#define HFM_SIZE_WORDS 0x2000 /* words */ -#define HFM_SECTOR_SIZE 0x200 /* Size in bytes */ -#define HFM_SECTOR_COUNT 0x20 -/* A 16K block in pages of 256 words. */ - -/** - * Writing HFM_LOCK_FLASH to HFM_LOCK_ADDR_L and HFM_LOCK_ADDR_H will enable security on flash after the next reset. - */ -#define HFM_LOCK_FLASH 0xE70A -#define HFM_LOCK_ADDR_L 0x1FF7 -#define HFM_LOCK_ADDR_H 0x1FF8 - /** - * ---------------------------------------------------------------- - */ - -/** ---------------------------------------------------------------- - * Register Memory Map (eonce_rev.1.0_0208081.pdf:16) - * ---------------------------------------------------------------- - */ -#define MC568013_EONCE_OBASE_ADDR 0xFF -/* The following are relative to EONCE_OBASE_ADDR (EONCE_OBASE_ADDR<<16 + ...) */ -#define MC568013_EONCE_TX_RX_ADDR 0xFFFE -#define MC568013_EONCE_TX1_RX1_HIGH_ADDR 0xFFFF /* Relative to EONCE_OBASE_ADDR */ -#define MC568013_EONCE_OCR 0xFFA0 /* Relative to EONCE_OBASE_ADDR */ - /** - * ---------------------------------------------------------------- - */ - -/** ---------------------------------------------------------------- - * SIM addresses & commands (MC56F80xx.h from freescale) - * ---------------------------------------------------------------- - */ -#define MC568013_SIM_BASE_ADDR 0xF140 -#define MC56803x_2x_SIM_BASE_ADDR 0xF100 - -#define SIM_CMD_RESET 0x10 - /** - * ---------------------------------------------------------------- - */ - -/** - * ---------------------------------------------------------------- - * ERROR codes - enable automatic parsing of output - * ---------------------------------------------------------------- - */ -#define DSP5680XX_ERROR_UNKNOWN_OR_ERROR_OPENOCD -100 -#define DSP5680XX_ERROR_JTAG_COMM -1 -#define DSP5680XX_ERROR_JTAG_RESET -2 -#define DSP5680XX_ERROR_JTAG_INVALID_TAP -3 -#define DSP5680XX_ERROR_JTAG_DR_LEN_OVERFLOW -4 -#define DSP5680XX_ERROR_INVALID_IR_LEN -5 -#define DSP5680XX_ERROR_JTAG_TAP_ENABLE_MASTER -6 -#define DSP5680XX_ERROR_JTAG_TAP_ENABLE_CORE -7 -#define DSP5680XX_ERROR_JTAG_TAP_FIND_MASTER -8 -#define DSP5680XX_ERROR_JTAG_TAP_FIND_CORE -9 -#define DSP5680XX_ERROR_JTAG_DRSCAN -10 -#define DSP5680XX_ERROR_JTAG_IRSCAN -11 -#define DSP5680XX_ERROR_ENTER_DEBUG_MODE -12 -#define DSP5680XX_ERROR_RESUME -13 -#define DSP5680XX_ERROR_WRITE_WITH_TARGET_RUNNING -14 -#define DSP5680XX_ERROR_INVALID_DATA_SIZE_UNIT -15 -#define DSP5680XX_ERROR_PROTECT_CHECK_INVALID_ARGS -16 -#define DSP5680XX_ERROR_FM_BUSY -17 -#define DSP5680XX_ERROR_FM_CMD_TIMED_OUT -18 -#define DSP5680XX_ERROR_FM_EXEC -19 -#define DSP5680XX_ERROR_FM_SET_CLK -20 -#define DSP5680XX_ERROR_FLASHING_INVALID_WORD_COUNT -21 -#define DSP5680XX_ERROR_FLASHING_CRC -22 -#define DSP5680XX_ERROR_FLASHING -23 -#define DSP5680XX_ERROR_NOT_IMPLEMENTED_STEP -24 -#define DSP5680XX_ERROR_HALT -25 -#define DSP5680XX_ERROR_EXIT_DEBUG_MODE -26 -#define DSP5680XX_ERROR_TARGET_RUNNING -27 -#define DSP5680XX_ERROR_NOT_IN_DEBUG -28 -/** - * ---------------------------------------------------------------- - */ - -struct dsp5680xx_common { - uint32_t stored_pc; - int flush; - bool debug_mode_enabled; -}; - -extern struct dsp5680xx_common dsp5680xx_context; - -static inline struct dsp5680xx_common *target_to_dsp5680xx(struct target - *target) -{ - return target->arch_info; -} - -/** - * Writes to flash memory. - * Does not check if flash is erased, it's up to the user to erase the flash before running - * this function. - * The flashing algorithm runs from RAM, reading from a register to which this function - * writes to. The algorithm is open loop, there is no control to verify that the FM read - * the register before writing the next data. A closed loop approach was much slower, - * and the current implementation does not fail, and if it did the crc check would detect it, - * allowing to flash again. - * - * @param target - * @param buffer - * @param address Word addressing. - * @param count In bytes. - * @param is_flash_lock - * - * @return - */ -int dsp5680xx_f_wr(struct target *target, const uint8_t * buffer, uint32_t address, - uint32_t count, int is_flash_lock); - -/** - * The FM has the functionality of checking if the flash array is erased. This function - * executes it. It does not support individual sector analysis. - * - * @param target - * @param erased - * @param sector This parameter is ignored because the FM does not support checking if - * individual sectors are erased. - * - * @return - */ -int dsp5680xx_f_erase_check(struct target *target, uint8_t * erased, - uint32_t sector); - -/** - * Erases either a sector or the complete flash array. If either the range first-last covers - * the complete array or if first == 0 and last == 0 then a mass erase command is executed - * on the FM. If not, then individual sectors are erased. - * - * @param target - * @param first - * @param last - * - * @return - */ -int dsp5680xx_f_erase(struct target *target, int first, int last); - -/** - * Reads the memory mapped protection register. A 1 implies the sector is protected, - * a 0 implies the sector is not protected. - * - * @param target - * @param protected Data read from the protection register. - * - * @return - */ -int dsp5680xx_f_protect_check(struct target *target, uint16_t * protected); - -/** - * Writes the flash security words with a specific value. The chip's security will be - * enabled after the first reset following the execution of this function. - * - * @param target - * - * @return - */ -int dsp5680xx_f_lock(struct target *target); - -/** - * Executes a mass erase command. The must be done from the Master tap. - * It is up to the user to select the master tap (jtag tapenable dsp5680xx.chp) - * before running this function. - * The flash array will be unsecured (and erased) after the first reset following - * the execution of this function. - * - * @param target - * - * @return - */ -int dsp5680xx_f_unlock(struct target *target); - -#endif /* OPENOCD_TARGET_DSP5680XX_H */ diff --git a/src/target/embeddedice.c b/src/target/embeddedice.c deleted file mode 100644 index 09d6fc8a1..000000000 --- a/src/target/embeddedice.c +++ /dev/null @@ -1,648 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * Copyright (C) 2007-2010 Øyvind Harboe * - * oyvind.harboe@zylin.com * - * * - * Copyright (C) 2008 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "embeddedice.h" -#include "register.h" - -/** - * @file - * - * This provides lowlevel glue to the EmbeddedICE (or EmbeddedICE-RT) - * module found on scan chain 2 in ARM7, ARM9, and some other families - * of ARM cores. The module is called "EmbeddedICE-RT" if it has - * monitor mode support. - * - * EmbeddedICE provides basic watchpoint/breakpoint hardware and a Debug - * Communications Channel (DCC) used to read or write 32-bit words to - * OpenOCD-aware code running on the target CPU. - * Newer modules also include vector catch hardware. Some versions - * support hardware single-stepping, "monitor mode" debug (which is not - * currently supported by OpenOCD), or extended reporting on why the - * core entered debug mode. - */ - -static int embeddedice_set_reg_w_exec(struct reg *reg, uint8_t *buf); - -/* - * From: ARM9E-S TRM, DDI 0165, table C-4 (and similar, for other cores) - */ -static const struct { - const char *name; - unsigned short addr; - unsigned short width; -} eice_regs[] = { - [EICE_DBG_CTRL] = { - .name = "debug_ctrl", - .addr = 0, - /* width is assigned based on EICE version */ - }, - [EICE_DBG_STAT] = { - .name = "debug_status", - .addr = 1, - /* width is assigned based on EICE version */ - }, - [EICE_COMMS_CTRL] = { - .name = "comms_ctrl", - .addr = 4, - .width = 6, - }, - [EICE_COMMS_DATA] = { - .name = "comms_data", - .addr = 5, - .width = 32, - }, - [EICE_W0_ADDR_VALUE] = { - .name = "watch_0_addr_value", - .addr = 8, - .width = 32, - }, - [EICE_W0_ADDR_MASK] = { - .name = "watch_0_addr_mask", - .addr = 9, - .width = 32, - }, - [EICE_W0_DATA_VALUE] = { - .name = "watch_0_data_value", - .addr = 10, - .width = 32, - }, - [EICE_W0_DATA_MASK] = { - .name = "watch_0_data_mask", - .addr = 11, - .width = 32, - }, - [EICE_W0_CONTROL_VALUE] = { - .name = "watch_0_control_value", - .addr = 12, - .width = 9, - }, - [EICE_W0_CONTROL_MASK] = { - .name = "watch_0_control_mask", - .addr = 13, - .width = 8, - }, - [EICE_W1_ADDR_VALUE] = { - .name = "watch_1_addr_value", - .addr = 16, - .width = 32, - }, - [EICE_W1_ADDR_MASK] = { - .name = "watch_1_addr_mask", - .addr = 17, - .width = 32, - }, - [EICE_W1_DATA_VALUE] = { - .name = "watch_1_data_value", - .addr = 18, - .width = 32, - }, - [EICE_W1_DATA_MASK] = { - .name = "watch_1_data_mask", - .addr = 19, - .width = 32, - }, - [EICE_W1_CONTROL_VALUE] = { - .name = "watch_1_control_value", - .addr = 20, - .width = 9, - }, - [EICE_W1_CONTROL_MASK] = { - .name = "watch_1_control_mask", - .addr = 21, - .width = 8, - }, - /* vector_catch isn't always present */ - [EICE_VEC_CATCH] = { - .name = "vector_catch", - .addr = 2, - .width = 8, - }, -}; - -static int embeddedice_get_reg(struct reg *reg) -{ - int retval = embeddedice_read_reg(reg); - if (retval != ERROR_OK) { - LOG_ERROR("error queueing EmbeddedICE register read"); - return retval; - } - - retval = jtag_execute_queue(); - if (retval != ERROR_OK) - LOG_ERROR("EmbeddedICE register read failed"); - - return retval; -} - -static const struct reg_arch_type eice_reg_type = { - .get = embeddedice_get_reg, - .set = embeddedice_set_reg_w_exec, -}; - -/** - * Probe EmbeddedICE module and set up local records of its registers. - * Different versions of the modules have different capabilities, such as - * hardware support for vector_catch, single stepping, and monitor mode. - */ -struct reg_cache *embeddedice_build_reg_cache(struct target *target, - struct arm7_9_common *arm7_9) -{ - int retval; - struct reg_cache *reg_cache = malloc(sizeof(struct reg_cache)); - struct reg *reg_list = NULL; - struct embeddedice_reg *arch_info = NULL; - struct arm_jtag *jtag_info = &arm7_9->jtag_info; - int num_regs = ARRAY_SIZE(eice_regs); - int i; - int eice_version = 0; - - /* vector_catch isn't always present */ - if (!arm7_9->has_vector_catch) - num_regs--; - - /* the actual registers are kept in two arrays */ - reg_list = calloc(num_regs, sizeof(struct reg)); - arch_info = calloc(num_regs, sizeof(struct embeddedice_reg)); - - /* fill in values for the reg cache */ - reg_cache->name = "EmbeddedICE registers"; - reg_cache->next = NULL; - reg_cache->reg_list = reg_list; - reg_cache->num_regs = num_regs; - - /* FIXME the second watchpoint unit on Feroceon and Dragonite - * seems not to work ... we should have a way to not set up - * its four registers here! - */ - - /* set up registers */ - for (i = 0; i < num_regs; i++) { - reg_list[i].name = eice_regs[i].name; - reg_list[i].size = eice_regs[i].width; - reg_list[i].dirty = 0; - reg_list[i].valid = 0; - reg_list[i].value = calloc(1, 4); - reg_list[i].arch_info = &arch_info[i]; - reg_list[i].type = &eice_reg_type; - arch_info[i].addr = eice_regs[i].addr; - arch_info[i].jtag_info = jtag_info; - } - - /* identify EmbeddedICE version by reading DCC control register */ - embeddedice_read_reg(®_list[EICE_COMMS_CTRL]); - retval = jtag_execute_queue(); - if (retval != ERROR_OK) { - for (i = 0; i < num_regs; i++) - free(reg_list[i].value); - free(reg_list); - free(reg_cache); - free(arch_info); - return NULL; - } - - eice_version = buf_get_u32(reg_list[EICE_COMMS_CTRL].value, 28, 4); - LOG_INFO("Embedded ICE version %d", eice_version); - - switch (eice_version) { - case 1: - /* ARM7TDMI r3, ARM7TDMI-S r3 - * - * REVISIT docs say ARM7TDMI-S r4 uses version 1 but - * that it has 6-bit CTRL and 5-bit STAT... doc bug? - * ARM7TDMI r4 docs say EICE v4. - */ - reg_list[EICE_DBG_CTRL].size = 3; - reg_list[EICE_DBG_STAT].size = 5; - break; - case 2: - /* ARM9TDMI */ - reg_list[EICE_DBG_CTRL].size = 4; - reg_list[EICE_DBG_STAT].size = 5; - arm7_9->has_single_step = 1; - break; - case 3: - LOG_ERROR("EmbeddedICE v%d handling might be broken", - eice_version); - reg_list[EICE_DBG_CTRL].size = 6; - reg_list[EICE_DBG_STAT].size = 5; - arm7_9->has_single_step = 1; - arm7_9->has_monitor_mode = 1; - break; - case 4: - /* ARM7TDMI r4 */ - reg_list[EICE_DBG_CTRL].size = 6; - reg_list[EICE_DBG_STAT].size = 5; - arm7_9->has_monitor_mode = 1; - break; - case 5: - /* ARM9E-S rev 1 */ - reg_list[EICE_DBG_CTRL].size = 6; - reg_list[EICE_DBG_STAT].size = 5; - arm7_9->has_single_step = 1; - arm7_9->has_monitor_mode = 1; - break; - case 6: - /* ARM7EJ-S, ARM9E-S rev 2, ARM9EJ-S */ - reg_list[EICE_DBG_CTRL].size = 6; - reg_list[EICE_DBG_STAT].size = 10; - /* DBG_STAT has MOE bits */ - arm7_9->has_monitor_mode = 1; - break; - case 7: - LOG_ERROR("EmbeddedICE v%d handling might be broken", - eice_version); - reg_list[EICE_DBG_CTRL].size = 6; - reg_list[EICE_DBG_STAT].size = 5; - arm7_9->has_monitor_mode = 1; - break; - default: - /* - * The Feroceon implementation has the version number - * in some unusual bits. Let feroceon.c validate it - * and do the appropriate setup itself. - */ - if (strcmp(target_type_name(target), "feroceon") == 0 || - strcmp(target_type_name(target), "dragonite") == 0) - break; - LOG_ERROR("unknown EmbeddedICE version " - "(comms ctrl: 0x%8.8" PRIx32 ")", - buf_get_u32(reg_list[EICE_COMMS_CTRL].value, 0, 32)); - } - - /* On Feroceon and Dragonite the second unit is seemingly missing. */ - LOG_INFO("%s: hardware has %d breakpoint/watchpoint unit%s", - target_name(target), arm7_9->wp_available_max, - (arm7_9->wp_available_max != 1) ? "s" : ""); - - return reg_cache; -} - -/** - * Initialize EmbeddedICE module, if needed. - */ -int embeddedice_setup(struct target *target) -{ - int retval; - struct arm7_9_common *arm7_9 = target_to_arm7_9(target); - - /* Explicitly disable monitor mode. For now we only support halting - * debug ... we don't know how to talk with a resident debug monitor - * that manages break requests. ARM's "Angel Debug Monitor" is one - * common example of such code. - */ - if (arm7_9->has_monitor_mode) { - struct reg *dbg_ctrl = &arm7_9->eice_cache->reg_list[EICE_DBG_CTRL]; - - embeddedice_read_reg(dbg_ctrl); - retval = jtag_execute_queue(); - if (retval != ERROR_OK) - return retval; - buf_set_u32(dbg_ctrl->value, 4, 1, 0); - embeddedice_set_reg_w_exec(dbg_ctrl, dbg_ctrl->value); - } - return jtag_execute_queue(); -} - -/** - * Queue a read for an EmbeddedICE register into the register cache, - * optionally checking the value read. - * Note that at this level, all registers are 32 bits wide. - */ -int embeddedice_read_reg_w_check(struct reg *reg, - uint8_t *check_value, uint8_t *check_mask) -{ - struct embeddedice_reg *ice_reg = reg->arch_info; - uint8_t reg_addr = ice_reg->addr & 0x1f; - struct scan_field fields[3]; - uint8_t field1_out[1]; - uint8_t field2_out[1]; - int retval; - - retval = arm_jtag_scann(ice_reg->jtag_info, 0x2, TAP_IDLE); - if (retval != ERROR_OK) - return retval; - - retval = arm_jtag_set_instr(ice_reg->jtag_info->tap, - ice_reg->jtag_info->intest_instr, NULL, TAP_IDLE); - if (retval != ERROR_OK) - return retval; - - /* bits 31:0 -- data (ignored here) */ - fields[0].num_bits = 32; - fields[0].out_value = reg->value; - fields[0].in_value = NULL; - fields[0].check_value = NULL; - fields[0].check_mask = NULL; - - /* bits 36:32 -- register */ - fields[1].num_bits = 5; - fields[1].out_value = field1_out; - field1_out[0] = reg_addr; - fields[1].in_value = NULL; - fields[1].check_value = NULL; - fields[1].check_mask = NULL; - - /* bit 37 -- 0/read */ - fields[2].num_bits = 1; - fields[2].out_value = field2_out; - field2_out[0] = 0; - fields[2].in_value = NULL; - fields[2].check_value = NULL; - fields[2].check_mask = NULL; - - /* traverse Update-DR, setting address for the next read */ - jtag_add_dr_scan(ice_reg->jtag_info->tap, 3, fields, TAP_IDLE); - - /* bits 31:0 -- the data we're reading (and maybe checking) */ - fields[0].in_value = reg->value; - fields[0].check_value = check_value; - fields[0].check_mask = check_mask; - - /* when reading the DCC data register, leaving the address field set to - * EICE_COMMS_DATA would read the register twice - * reading the control register is safe - */ - field1_out[0] = eice_regs[EICE_COMMS_CTRL].addr; - - /* traverse Update-DR, reading but with no other side effects */ - jtag_add_dr_scan_check(ice_reg->jtag_info->tap, 3, fields, TAP_IDLE); - - return ERROR_OK; -} - -/** - * Receive a block of size 32-bit words from the DCC. - * We assume the target is always going to be fast enough (relative to - * the JTAG clock) that the debugger won't need to poll the handshake - * bit. The JTAG clock is usually at least six times slower than the - * functional clock, so the 50+ JTAG clocks needed to receive the word - * allow hundreds of instruction cycles (per word) in the target. - */ -int embeddedice_receive(struct arm_jtag *jtag_info, uint32_t *data, uint32_t size) -{ - struct scan_field fields[3]; - uint8_t field1_out[1]; - uint8_t field2_out[1]; - int retval; - - retval = arm_jtag_scann(jtag_info, 0x2, TAP_IDLE); - if (retval != ERROR_OK) - return retval; - retval = arm_jtag_set_instr(jtag_info->tap, jtag_info->intest_instr, NULL, TAP_IDLE); - if (retval != ERROR_OK) - return retval; - - fields[0].num_bits = 32; - fields[0].out_value = NULL; - fields[0].in_value = NULL; - - fields[1].num_bits = 5; - fields[1].out_value = field1_out; - field1_out[0] = eice_regs[EICE_COMMS_DATA].addr; - fields[1].in_value = NULL; - - fields[2].num_bits = 1; - fields[2].out_value = field2_out; - field2_out[0] = 0; - fields[2].in_value = NULL; - - jtag_add_dr_scan(jtag_info->tap, 3, fields, TAP_IDLE); - - while (size > 0) { - /* when reading the last item, set the register address to the DCC control reg, - * to avoid reading additional data from the DCC data reg - */ - if (size == 1) - field1_out[0] = eice_regs[EICE_COMMS_CTRL].addr; - - fields[0].in_value = (uint8_t *)data; - jtag_add_dr_scan(jtag_info->tap, 3, fields, TAP_IDLE); - jtag_add_callback(arm_le_to_h_u32, (jtag_callback_data_t)data); - - data++; - size--; - } - - return jtag_execute_queue(); -} - -/** - * Queue a read for an EmbeddedICE register into the register cache, - * not checking the value read. - */ -int embeddedice_read_reg(struct reg *reg) -{ - return embeddedice_read_reg_w_check(reg, NULL, NULL); -} - -/** - * Queue a write for an EmbeddedICE register, updating the register cache. - * Uses embeddedice_write_reg(). - */ -void embeddedice_set_reg(struct reg *reg, uint32_t value) -{ - embeddedice_write_reg(reg, value); - - buf_set_u32(reg->value, 0, reg->size, value); - reg->valid = 1; - reg->dirty = 0; - -} - -/** - * Write an EmbeddedICE register, updating the register cache. - * Uses embeddedice_set_reg(); not queued. - */ -static int embeddedice_set_reg_w_exec(struct reg *reg, uint8_t *buf) -{ - int retval; - - embeddedice_set_reg(reg, buf_get_u32(buf, 0, reg->size)); - retval = jtag_execute_queue(); - if (retval != ERROR_OK) - LOG_ERROR("register write failed"); - return retval; -} - -/** - * Queue a write for an EmbeddedICE register, bypassing the register cache. - */ -void embeddedice_write_reg(struct reg *reg, uint32_t value) -{ - struct embeddedice_reg *ice_reg = reg->arch_info; - - LOG_DEBUG("%i: 0x%8.8" PRIx32 "", ice_reg->addr, value); - - arm_jtag_scann(ice_reg->jtag_info, 0x2, TAP_IDLE); - - arm_jtag_set_instr(ice_reg->jtag_info->tap, ice_reg->jtag_info->intest_instr, NULL, TAP_IDLE); - - uint8_t reg_addr = ice_reg->addr & 0x1f; - embeddedice_write_reg_inner(ice_reg->jtag_info->tap, reg_addr, value); -} - -/** - * Queue a write for an EmbeddedICE register, using cached value. - * Uses embeddedice_write_reg(). - */ -void embeddedice_store_reg(struct reg *reg) -{ - embeddedice_write_reg(reg, buf_get_u32(reg->value, 0, reg->size)); -} - -/** - * Send a block of size 32-bit words to the DCC. - * We assume the target is always going to be fast enough (relative to - * the JTAG clock) that the debugger won't need to poll the handshake - * bit. The JTAG clock is usually at least six times slower than the - * functional clock, so the 50+ JTAG clocks needed to receive the word - * allow hundreds of instruction cycles (per word) in the target. - */ -int embeddedice_send(struct arm_jtag *jtag_info, uint32_t *data, uint32_t size) -{ - struct scan_field fields[3]; - uint8_t field0_out[4]; - uint8_t field1_out[1]; - uint8_t field2_out[1]; - int retval; - - retval = arm_jtag_scann(jtag_info, 0x2, TAP_IDLE); - if (retval != ERROR_OK) - return retval; - retval = arm_jtag_set_instr(jtag_info->tap, jtag_info->intest_instr, NULL, TAP_IDLE); - if (retval != ERROR_OK) - return retval; - - fields[0].num_bits = 32; - fields[0].out_value = field0_out; - fields[0].in_value = NULL; - - fields[1].num_bits = 5; - fields[1].out_value = field1_out; - field1_out[0] = eice_regs[EICE_COMMS_DATA].addr; - fields[1].in_value = NULL; - - fields[2].num_bits = 1; - fields[2].out_value = field2_out; - field2_out[0] = 1; - - fields[2].in_value = NULL; - - while (size > 0) { - buf_set_u32(field0_out, 0, 32, *data); - jtag_add_dr_scan(jtag_info->tap, 3, fields, TAP_IDLE); - - data++; - size--; - } - - /* call to jtag_execute_queue() intentionally omitted */ - return ERROR_OK; -} - -/** - * Poll DCC control register until read or write handshake completes. - */ -int embeddedice_handshake(struct arm_jtag *jtag_info, int hsbit, uint32_t timeout) -{ - struct scan_field fields[3]; - uint8_t field0_in[4]; - uint8_t field1_out[1]; - uint8_t field2_out[1]; - int retval; - uint32_t hsact; - struct timeval lap; - struct timeval now; - - if (hsbit == EICE_COMM_CTRL_WBIT) - hsact = 1; - else if (hsbit == EICE_COMM_CTRL_RBIT) - hsact = 0; - else { - LOG_ERROR("Invalid arguments"); - return ERROR_COMMAND_SYNTAX_ERROR; - } - - retval = arm_jtag_scann(jtag_info, 0x2, TAP_IDLE); - if (retval != ERROR_OK) - return retval; - retval = arm_jtag_set_instr(jtag_info->tap, jtag_info->intest_instr, NULL, TAP_IDLE); - if (retval != ERROR_OK) - return retval; - - fields[0].num_bits = 32; - fields[0].out_value = NULL; - fields[0].in_value = field0_in; - - fields[1].num_bits = 5; - fields[1].out_value = field1_out; - field1_out[0] = eice_regs[EICE_COMMS_DATA].addr; - fields[1].in_value = NULL; - - fields[2].num_bits = 1; - fields[2].out_value = field2_out; - field2_out[0] = 0; - fields[2].in_value = NULL; - - jtag_add_dr_scan(jtag_info->tap, 3, fields, TAP_IDLE); - gettimeofday(&lap, NULL); - do { - jtag_add_dr_scan(jtag_info->tap, 3, fields, TAP_IDLE); - retval = jtag_execute_queue(); - if (retval != ERROR_OK) - return retval; - - if (buf_get_u32(field0_in, hsbit, 1) == hsact) - return ERROR_OK; - - gettimeofday(&now, NULL); - } while ((uint32_t)((now.tv_sec - lap.tv_sec) * 1000 - + (now.tv_usec - lap.tv_usec) / 1000) <= timeout); - - LOG_ERROR("embeddedice handshake timeout"); - return ERROR_TARGET_TIMEOUT; -} - -#ifndef HAVE_JTAG_MINIDRIVER_H -/** - * This is an inner loop of the open loop DCC write of data to target - */ -void embeddedice_write_dcc(struct jtag_tap *tap, - int reg_addr, const uint8_t *buffer, int little, int count) -{ - int i; - - for (i = 0; i < count; i++) { - embeddedice_write_reg_inner(tap, reg_addr, - fast_target_buffer_get_u32(buffer, little)); - buffer += 4; - } -} -#else -/* provided by minidriver */ -#endif diff --git a/src/target/embeddedice.h b/src/target/embeddedice.h deleted file mode 100644 index 39902fb3e..000000000 --- a/src/target/embeddedice.h +++ /dev/null @@ -1,128 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005, 2006 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * Copyright (C) 2007,2008 Øyvind Harboe * - * oyvind.harboe@zylin.com * - * * - * Copyright (C) 2008 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 OPENOCD_TARGET_EMBEDDEDICE_H -#define OPENOCD_TARGET_EMBEDDEDICE_H - -#include "arm7_9_common.h" - -enum { - EICE_DBG_CTRL = 0, - EICE_DBG_STAT = 1, - EICE_COMMS_CTRL = 2, - EICE_COMMS_DATA = 3, - EICE_W0_ADDR_VALUE = 4, - EICE_W0_ADDR_MASK = 5, - EICE_W0_DATA_VALUE = 6, - EICE_W0_DATA_MASK = 7, - EICE_W0_CONTROL_VALUE = 8, - EICE_W0_CONTROL_MASK = 9, - EICE_W1_ADDR_VALUE = 10, - EICE_W1_ADDR_MASK = 11, - EICE_W1_DATA_VALUE = 12, - EICE_W1_DATA_MASK = 13, - EICE_W1_CONTROL_VALUE = 14, - EICE_W1_CONTROL_MASK = 15, - EICE_VEC_CATCH = 16 -}; - -enum { - EICE_DBG_CONTROL_ICEDIS = 5, - EICE_DBG_CONTROL_MONEN = 4, - EICE_DBG_CONTROL_INTDIS = 2, - EICE_DBG_CONTROL_DBGRQ = 1, - EICE_DBG_CONTROL_DBGACK = 0, -}; - -enum { - EICE_DBG_STATUS_IJBIT = 5, - EICE_DBG_STATUS_ITBIT = 4, - EICE_DBG_STATUS_SYSCOMP = 3, - EICE_DBG_STATUS_IFEN = 2, - EICE_DBG_STATUS_DBGRQ = 1, - EICE_DBG_STATUS_DBGACK = 0 -}; - -enum { - EICE_W_CTRL_ENABLE = 0x100, - EICE_W_CTRL_RANGE = 0x80, - EICE_W_CTRL_CHAIN = 0x40, - EICE_W_CTRL_EXTERN = 0x20, - EICE_W_CTRL_nTRANS = 0x10, - EICE_W_CTRL_nOPC = 0x8, - EICE_W_CTRL_MAS = 0x6, - EICE_W_CTRL_ITBIT = 0x2, - EICE_W_CTRL_nRW = 0x1 -}; - -enum { - EICE_COMM_CTRL_WBIT = 1, - EICE_COMM_CTRL_RBIT = 0 -}; - -struct embeddedice_reg { - int addr; - struct arm_jtag *jtag_info; -}; - -struct reg_cache *embeddedice_build_reg_cache(struct target *target, - struct arm7_9_common *arm7_9); - -int embeddedice_setup(struct target *target); - -int embeddedice_read_reg(struct reg *reg); -int embeddedice_read_reg_w_check(struct reg *reg, - uint8_t *check_value, uint8_t *check_mask); - -void embeddedice_write_reg(struct reg *reg, uint32_t value); -void embeddedice_store_reg(struct reg *reg); - -void embeddedice_set_reg(struct reg *reg, uint32_t value); - -int embeddedice_receive(struct arm_jtag *jtag_info, uint32_t *data, uint32_t size); -int embeddedice_send(struct arm_jtag *jtag_info, uint32_t *data, uint32_t size); - -int embeddedice_handshake(struct arm_jtag *jtag_info, int hsbit, uint32_t timeout); - -/* If many embeddedice_write_reg() follow eachother, then the >1 invocations can be - * this faster version of embeddedice_write_reg - */ -static inline void embeddedice_write_reg_inner(struct jtag_tap *tap, int reg_addr, uint32_t value) -{ - uint8_t out_reg_addr = (1 << 5) | reg_addr; - uint8_t out_value[4]; - buf_set_u32(out_value, 0, 32, value); - - struct scan_field fields[2] = { - { .num_bits = 32, .out_value = out_value }, - { .num_bits = 6, .out_value = &out_reg_addr }, - }; - - jtag_add_dr_scan(tap, 2, fields, TAP_IDLE); -} - -void embeddedice_write_dcc(struct jtag_tap *tap, int reg_addr, const uint8_t *buffer, - int little, int count); - -#endif /* OPENOCD_TARGET_EMBEDDEDICE_H */ diff --git a/src/target/etb.c b/src/target/etb.c deleted file mode 100644 index dc25844b9..000000000 --- a/src/target/etb.c +++ /dev/null @@ -1,703 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "arm.h" -#include "etm.h" -#include "etb.h" -#include "register.h" - -static const char * const etb_reg_list[] = { - "ETB_identification", - "ETB_ram_depth", - "ETB_ram_width", - "ETB_status", - "ETB_ram_data", - "ETB_ram_read_pointer", - "ETB_ram_write_pointer", - "ETB_trigger_counter", - "ETB_control", -}; - -static int etb_get_reg(struct reg *reg); - -static int etb_set_instr(struct etb *etb, uint32_t new_instr) -{ - struct jtag_tap *tap; - - tap = etb->tap; - if (tap == NULL) - return ERROR_FAIL; - - if (buf_get_u32(tap->cur_instr, 0, tap->ir_length) != new_instr) { - struct scan_field field; - - field.num_bits = tap->ir_length; - void *t = calloc(DIV_ROUND_UP(field.num_bits, 8), 1); - 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); - - free(t); - } - - return ERROR_OK; -} - -static int etb_scann(struct etb *etb, uint32_t new_scan_chain) -{ - if (etb->cur_scan_chain != new_scan_chain) { - struct scan_field field; - - field.num_bits = 5; - void *t = calloc(DIV_ROUND_UP(field.num_bits, 8), 1); - field.out_value = t; - buf_set_u32(t, 0, field.num_bits, new_scan_chain); - - field.in_value = NULL; - - /* select INTEST instruction */ - etb_set_instr(etb, 0x2); - jtag_add_dr_scan(etb->tap, 1, &field, TAP_IDLE); - - etb->cur_scan_chain = new_scan_chain; - - free(t); - } - - return ERROR_OK; -} - -static int etb_read_reg_w_check(struct reg *, uint8_t *, uint8_t *); -static int etb_set_reg_w_exec(struct reg *, uint8_t *); - -static int etb_read_reg(struct reg *reg) -{ - return etb_read_reg_w_check(reg, NULL, NULL); -} - -static int etb_get_reg(struct reg *reg) -{ - int retval; - - retval = etb_read_reg(reg); - if (retval != ERROR_OK) { - LOG_ERROR("BUG: error scheduling ETB register read"); - return retval; - } - - retval = jtag_execute_queue(); - if (retval != ERROR_OK) { - LOG_ERROR("ETB register read failed"); - return retval; - } - - return ERROR_OK; -} - -static const struct reg_arch_type etb_reg_type = { - .get = etb_get_reg, - .set = etb_set_reg_w_exec, -}; - -struct reg_cache *etb_build_reg_cache(struct etb *etb) -{ - struct reg_cache *reg_cache = malloc(sizeof(struct reg_cache)); - struct reg *reg_list = NULL; - struct etb_reg *arch_info = NULL; - int num_regs = 9; - int i; - - /* the actual registers are kept in two arrays */ - reg_list = calloc(num_regs, sizeof(struct reg)); - arch_info = calloc(num_regs, sizeof(struct etb_reg)); - - /* fill in values for the reg cache */ - reg_cache->name = "etb registers"; - reg_cache->next = NULL; - reg_cache->reg_list = reg_list; - reg_cache->num_regs = num_regs; - - /* set up registers */ - for (i = 0; i < num_regs; i++) { - reg_list[i].name = etb_reg_list[i]; - reg_list[i].size = 32; - reg_list[i].dirty = 0; - reg_list[i].valid = 0; - reg_list[i].value = calloc(1, 4); - reg_list[i].arch_info = &arch_info[i]; - reg_list[i].type = &etb_reg_type; - reg_list[i].size = 32; - arch_info[i].addr = i; - arch_info[i].etb = etb; - } - - return reg_cache; -} - -static void etb_getbuf(jtag_callback_data_t arg) -{ - uint8_t *in = (uint8_t *)arg; - - *((uint32_t *)arg) = buf_get_u32(in, 0, 32); -} - -static int etb_read_ram(struct etb *etb, uint32_t *data, int num_frames) -{ - struct scan_field fields[3]; - int i; - - etb_scann(etb, 0x0); - etb_set_instr(etb, 0xc); - - fields[0].num_bits = 32; - fields[0].out_value = NULL; - fields[0].in_value = NULL; - - fields[1].num_bits = 7; - uint8_t temp1; - fields[1].out_value = &temp1; - buf_set_u32(&temp1, 0, 7, 4); - fields[1].in_value = NULL; - - fields[2].num_bits = 1; - uint8_t temp2; - fields[2].out_value = &temp2; - buf_set_u32(&temp2, 0, 1, 0); - fields[2].in_value = NULL; - - jtag_add_dr_scan(etb->tap, 3, fields, TAP_IDLE); - - for (i = 0; i < num_frames; i++) { - /* ensure nR/W remains set to read */ - buf_set_u32(&temp2, 0, 1, 0); - - /* address remains set to 0x4 (RAM data) until we read the last frame */ - if (i < num_frames - 1) - buf_set_u32(&temp1, 0, 7, 4); - else - buf_set_u32(&temp1, 0, 7, 0); - - fields[0].in_value = (uint8_t *)(data + i); - jtag_add_dr_scan(etb->tap, 3, fields, TAP_IDLE); - - jtag_add_callback(etb_getbuf, (jtag_callback_data_t)(data + i)); - } - - jtag_execute_queue(); - - return ERROR_OK; -} - -static int etb_read_reg_w_check(struct reg *reg, - uint8_t *check_value, uint8_t *check_mask) -{ - struct etb_reg *etb_reg = reg->arch_info; - uint8_t reg_addr = etb_reg->addr & 0x7f; - struct scan_field fields[3]; - - LOG_DEBUG("%i", (int)(etb_reg->addr)); - - etb_scann(etb_reg->etb, 0x0); - etb_set_instr(etb_reg->etb, 0xc); - - fields[0].num_bits = 32; - fields[0].out_value = reg->value; - fields[0].in_value = NULL; - fields[0].check_value = NULL; - fields[0].check_mask = NULL; - - fields[1].num_bits = 7; - uint8_t temp1; - fields[1].out_value = &temp1; - buf_set_u32(&temp1, 0, 7, reg_addr); - fields[1].in_value = NULL; - fields[1].check_value = NULL; - fields[1].check_mask = NULL; - - fields[2].num_bits = 1; - uint8_t temp2; - fields[2].out_value = &temp2; - buf_set_u32(&temp2, 0, 1, 0); - fields[2].in_value = NULL; - fields[2].check_value = NULL; - fields[2].check_mask = NULL; - - jtag_add_dr_scan(etb_reg->etb->tap, 3, fields, TAP_IDLE); - - /* read the identification register in the second run, to make sure we - * don't read the ETB data register twice, skipping every second entry - */ - buf_set_u32(&temp1, 0, 7, 0x0); - fields[0].in_value = reg->value; - fields[0].check_value = check_value; - fields[0].check_mask = check_mask; - - jtag_add_dr_scan_check(etb_reg->etb->tap, 3, fields, TAP_IDLE); - - return ERROR_OK; -} - -static int etb_write_reg(struct reg *, uint32_t); - -static int etb_set_reg(struct reg *reg, uint32_t value) -{ - int retval; - - retval = etb_write_reg(reg, value); - if (retval != ERROR_OK) { - LOG_ERROR("BUG: error scheduling ETB register write"); - return retval; - } - - buf_set_u32(reg->value, 0, reg->size, value); - reg->valid = 1; - reg->dirty = 0; - - return ERROR_OK; -} - -static int etb_set_reg_w_exec(struct reg *reg, uint8_t *buf) -{ - int retval; - - etb_set_reg(reg, buf_get_u32(buf, 0, reg->size)); - - retval = jtag_execute_queue(); - if (retval != ERROR_OK) { - LOG_ERROR("ETB: register write failed"); - return retval; - } - return ERROR_OK; -} - -static int etb_write_reg(struct reg *reg, uint32_t value) -{ - struct etb_reg *etb_reg = reg->arch_info; - uint8_t reg_addr = etb_reg->addr & 0x7f; - struct scan_field fields[3]; - - LOG_DEBUG("%i: 0x%8.8" PRIx32 "", (int)(etb_reg->addr), value); - - etb_scann(etb_reg->etb, 0x0); - etb_set_instr(etb_reg->etb, 0xc); - - fields[0].num_bits = 32; - uint8_t temp0[4]; - fields[0].out_value = temp0; - buf_set_u32(temp0, 0, 32, value); - fields[0].in_value = NULL; - - fields[1].num_bits = 7; - uint8_t temp1; - fields[1].out_value = &temp1; - buf_set_u32(&temp1, 0, 7, reg_addr); - fields[1].in_value = NULL; - - fields[2].num_bits = 1; - uint8_t temp2; - fields[2].out_value = &temp2; - buf_set_u32(&temp2, 0, 1, 1); - fields[2].in_value = NULL; - - jtag_add_dr_scan(etb_reg->etb->tap, 3, fields, TAP_IDLE); - - return ERROR_OK; -} - -COMMAND_HANDLER(handle_etb_config_command) -{ - struct target *target; - struct jtag_tap *tap; - struct arm *arm; - - if (CMD_ARGC != 2) - return ERROR_COMMAND_SYNTAX_ERROR; - - target = get_target(CMD_ARGV[0]); - - if (!target) { - LOG_ERROR("ETB: target '%s' not defined", CMD_ARGV[0]); - return ERROR_FAIL; - } - - arm = target_to_arm(target); - if (!is_arm(arm)) { - command_print(CMD_CTX, "ETB: '%s' isn't an ARM", CMD_ARGV[0]); - return ERROR_FAIL; - } - - tap = jtag_tap_by_string(CMD_ARGV[1]); - if (tap == NULL) { - command_print(CMD_CTX, "ETB: TAP %s does not exist", CMD_ARGV[1]); - return ERROR_FAIL; - } - - if (arm->etm) { - struct etb *etb = malloc(sizeof(struct etb)); - - arm->etm->capture_driver_priv = etb; - - etb->tap = tap; - etb->cur_scan_chain = 0xffffffff; - etb->reg_cache = NULL; - etb->ram_width = 0; - etb->ram_depth = 0; - } else { - LOG_ERROR("ETM: target has no ETM defined, ETB left unconfigured"); - return ERROR_FAIL; - } - - return ERROR_OK; -} - -COMMAND_HANDLER(handle_etb_trigger_percent_command) -{ - struct target *target; - struct arm *arm; - struct etm_context *etm; - struct etb *etb; - - target = get_current_target(CMD_CTX); - arm = target_to_arm(target); - if (!is_arm(arm)) { - command_print(CMD_CTX, "ETB: current target isn't an ARM"); - return ERROR_FAIL; - } - - etm = arm->etm; - if (!etm) { - command_print(CMD_CTX, "ETB: target has no ETM configured"); - return ERROR_FAIL; - } - if (etm->capture_driver != &etb_capture_driver) { - command_print(CMD_CTX, "ETB: target not using ETB"); - return ERROR_FAIL; - } - etb = arm->etm->capture_driver_priv; - - if (CMD_ARGC > 0) { - uint32_t new_value; - - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], new_value); - if ((new_value < 2) || (new_value > 100)) - command_print(CMD_CTX, - "valid percentages are 2%% to 100%%"); - else - etb->trigger_percent = (unsigned) new_value; - } - - command_print(CMD_CTX, "%d percent of tracebuffer fills after trigger", - etb->trigger_percent); - - return ERROR_OK; -} - -static const struct command_registration etb_config_command_handlers[] = { - { - /* NOTE: with ADIv5, ETBs are accessed using DAP operations, - * possibly over SWD, not through separate TAPs... - */ - .name = "config", - .handler = handle_etb_config_command, - .mode = COMMAND_CONFIG, - .help = "Associate ETB with target and JTAG TAP.", - .usage = "target tap", - }, - { - .name = "trigger_percent", - .handler = handle_etb_trigger_percent_command, - .mode = COMMAND_EXEC, - .help = "Set percent of trace buffer to be filled " - "after the trigger occurs (2..100).", - .usage = "[percent]", - }, - COMMAND_REGISTRATION_DONE -}; -static const struct command_registration etb_command_handlers[] = { - { - .name = "etb", - .mode = COMMAND_ANY, - .help = "Embedded Trace Buffer command group", - .chain = etb_config_command_handlers, - }, - COMMAND_REGISTRATION_DONE -}; - -static int etb_init(struct etm_context *etm_ctx) -{ - struct etb *etb = etm_ctx->capture_driver_priv; - - etb->etm_ctx = etm_ctx; - - /* identify ETB RAM depth and width */ - etb_read_reg(&etb->reg_cache->reg_list[ETB_RAM_DEPTH]); - etb_read_reg(&etb->reg_cache->reg_list[ETB_RAM_WIDTH]); - jtag_execute_queue(); - - etb->ram_depth = buf_get_u32(etb->reg_cache->reg_list[ETB_RAM_DEPTH].value, 0, 32); - etb->ram_width = buf_get_u32(etb->reg_cache->reg_list[ETB_RAM_WIDTH].value, 0, 32); - - etb->trigger_percent = 50; - - return ERROR_OK; -} - -static trace_status_t etb_status(struct etm_context *etm_ctx) -{ - struct etb *etb = etm_ctx->capture_driver_priv; - struct reg *control = &etb->reg_cache->reg_list[ETB_CTRL]; - struct reg *status = &etb->reg_cache->reg_list[ETB_STATUS]; - trace_status_t retval = 0; - int etb_timeout = 100; - - etb->etm_ctx = etm_ctx; - - /* read control and status registers */ - etb_read_reg(control); - etb_read_reg(status); - jtag_execute_queue(); - - /* See if it's (still) active */ - retval = buf_get_u32(control->value, 0, 1) ? TRACE_RUNNING : TRACE_IDLE; - - /* check Full bit to identify wraparound/overflow */ - if (buf_get_u32(status->value, 0, 1) == 1) - retval |= TRACE_OVERFLOWED; - - /* check Triggered bit to identify trigger condition */ - if (buf_get_u32(status->value, 1, 1) == 1) - retval |= TRACE_TRIGGERED; - - /* check AcqComp to see if trigger counter dropped to zero */ - if (buf_get_u32(status->value, 2, 1) == 1) { - /* wait for DFEmpty */ - while (etb_timeout-- && buf_get_u32(status->value, 3, 1) == 0) - etb_get_reg(status); - - if (etb_timeout == 0) - LOG_ERROR("ETB: DFEmpty won't go high, status 0x%02x", - (unsigned) buf_get_u32(status->value, 0, 4)); - - if (!(etm_ctx->capture_status & TRACE_TRIGGERED)) - LOG_WARNING("ETB: trace complete without triggering?"); - - retval |= TRACE_COMPLETED; - } - - /* NOTE: using a trigger is optional; and at least ETB11 has a mode - * where it can ignore the trigger counter. - */ - - /* update recorded state */ - etm_ctx->capture_status = retval; - - return retval; -} - -static int etb_read_trace(struct etm_context *etm_ctx) -{ - struct etb *etb = etm_ctx->capture_driver_priv; - int first_frame = 0; - int num_frames = etb->ram_depth; - uint32_t *trace_data = NULL; - int i, j; - - etb_read_reg(&etb->reg_cache->reg_list[ETB_STATUS]); - etb_read_reg(&etb->reg_cache->reg_list[ETB_RAM_WRITE_POINTER]); - jtag_execute_queue(); - - /* check if we overflowed, and adjust first frame of the trace accordingly - * if we didn't overflow, read only up to the frame that would be written next, - * i.e. don't read invalid entries - */ - if (buf_get_u32(etb->reg_cache->reg_list[ETB_STATUS].value, 0, 1)) - first_frame = buf_get_u32(etb->reg_cache->reg_list[ETB_RAM_WRITE_POINTER].value, - 0, - 32); - else - num_frames = buf_get_u32(etb->reg_cache->reg_list[ETB_RAM_WRITE_POINTER].value, - 0, - 32); - - etb_write_reg(&etb->reg_cache->reg_list[ETB_RAM_READ_POINTER], first_frame); - - /* read data into temporary array for unpacking */ - trace_data = malloc(sizeof(uint32_t) * num_frames); - etb_read_ram(etb, trace_data, num_frames); - - if (etm_ctx->trace_depth > 0) - free(etm_ctx->trace_data); - - if ((etm_ctx->control & ETM_PORT_WIDTH_MASK) == ETM_PORT_4BIT) - etm_ctx->trace_depth = num_frames * 3; - else if ((etm_ctx->control & ETM_PORT_WIDTH_MASK) == ETM_PORT_8BIT) - etm_ctx->trace_depth = num_frames * 2; - else - etm_ctx->trace_depth = num_frames; - - etm_ctx->trace_data = malloc(sizeof(struct etmv1_trace_data) * etm_ctx->trace_depth); - - for (i = 0, j = 0; i < num_frames; i++) { - if ((etm_ctx->control & ETM_PORT_WIDTH_MASK) == ETM_PORT_4BIT) { - /* trace word j */ - etm_ctx->trace_data[j].pipestat = trace_data[i] & 0x7; - etm_ctx->trace_data[j].packet = (trace_data[i] & 0x78) >> 3; - etm_ctx->trace_data[j].flags = 0; - if ((trace_data[i] & 0x80) >> 7) - etm_ctx->trace_data[j].flags |= ETMV1_TRACESYNC_CYCLE; - if (etm_ctx->trace_data[j].pipestat == STAT_TR) { - etm_ctx->trace_data[j].pipestat = etm_ctx->trace_data[j].packet & - 0x7; - etm_ctx->trace_data[j].flags |= ETMV1_TRIGGER_CYCLE; - } - - /* trace word j + 1 */ - etm_ctx->trace_data[j + 1].pipestat = (trace_data[i] & 0x100) >> 8; - etm_ctx->trace_data[j + 1].packet = (trace_data[i] & 0x7800) >> 11; - etm_ctx->trace_data[j + 1].flags = 0; - if ((trace_data[i] & 0x8000) >> 15) - etm_ctx->trace_data[j + 1].flags |= ETMV1_TRACESYNC_CYCLE; - if (etm_ctx->trace_data[j + 1].pipestat == STAT_TR) { - etm_ctx->trace_data[j + - 1].pipestat = etm_ctx->trace_data[j + 1].packet & 0x7; - etm_ctx->trace_data[j + 1].flags |= ETMV1_TRIGGER_CYCLE; - } - - /* trace word j + 2 */ - etm_ctx->trace_data[j + 2].pipestat = (trace_data[i] & 0x10000) >> 16; - etm_ctx->trace_data[j + 2].packet = (trace_data[i] & 0x780000) >> 19; - etm_ctx->trace_data[j + 2].flags = 0; - if ((trace_data[i] & 0x800000) >> 23) - etm_ctx->trace_data[j + 2].flags |= ETMV1_TRACESYNC_CYCLE; - if (etm_ctx->trace_data[j + 2].pipestat == STAT_TR) { - etm_ctx->trace_data[j + - 2].pipestat = etm_ctx->trace_data[j + 2].packet & 0x7; - etm_ctx->trace_data[j + 2].flags |= ETMV1_TRIGGER_CYCLE; - } - - j += 3; - } else if ((etm_ctx->control & ETM_PORT_WIDTH_MASK) == ETM_PORT_8BIT) { - /* trace word j */ - etm_ctx->trace_data[j].pipestat = trace_data[i] & 0x7; - etm_ctx->trace_data[j].packet = (trace_data[i] & 0x7f8) >> 3; - etm_ctx->trace_data[j].flags = 0; - if ((trace_data[i] & 0x800) >> 11) - etm_ctx->trace_data[j].flags |= ETMV1_TRACESYNC_CYCLE; - if (etm_ctx->trace_data[j].pipestat == STAT_TR) { - etm_ctx->trace_data[j].pipestat = etm_ctx->trace_data[j].packet & - 0x7; - etm_ctx->trace_data[j].flags |= ETMV1_TRIGGER_CYCLE; - } - - /* trace word j + 1 */ - etm_ctx->trace_data[j + 1].pipestat = (trace_data[i] & 0x7000) >> 12; - etm_ctx->trace_data[j + 1].packet = (trace_data[i] & 0x7f8000) >> 15; - etm_ctx->trace_data[j + 1].flags = 0; - if ((trace_data[i] & 0x800000) >> 23) - etm_ctx->trace_data[j + 1].flags |= ETMV1_TRACESYNC_CYCLE; - if (etm_ctx->trace_data[j + 1].pipestat == STAT_TR) { - etm_ctx->trace_data[j + - 1].pipestat = etm_ctx->trace_data[j + 1].packet & 0x7; - etm_ctx->trace_data[j + 1].flags |= ETMV1_TRIGGER_CYCLE; - } - - j += 2; - } else { - /* trace word j */ - etm_ctx->trace_data[j].pipestat = trace_data[i] & 0x7; - etm_ctx->trace_data[j].packet = (trace_data[i] & 0x7fff8) >> 3; - etm_ctx->trace_data[j].flags = 0; - if ((trace_data[i] & 0x80000) >> 19) - etm_ctx->trace_data[j].flags |= ETMV1_TRACESYNC_CYCLE; - if (etm_ctx->trace_data[j].pipestat == STAT_TR) { - etm_ctx->trace_data[j].pipestat = etm_ctx->trace_data[j].packet & - 0x7; - etm_ctx->trace_data[j].flags |= ETMV1_TRIGGER_CYCLE; - } - - j += 1; - } - } - - free(trace_data); - - return ERROR_OK; -} - -static int etb_start_capture(struct etm_context *etm_ctx) -{ - struct etb *etb = etm_ctx->capture_driver_priv; - uint32_t etb_ctrl_value = 0x1; - uint32_t trigger_count; - - if ((etm_ctx->control & ETM_PORT_MODE_MASK) == ETM_PORT_DEMUXED) { - if ((etm_ctx->control & ETM_PORT_WIDTH_MASK) != ETM_PORT_8BIT) { - LOG_ERROR("ETB can't run in demultiplexed mode with a 4 or 16 bit port"); - return ERROR_ETM_PORTMODE_NOT_SUPPORTED; - } - etb_ctrl_value |= 0x2; - } - - if ((etm_ctx->control & ETM_PORT_MODE_MASK) == ETM_PORT_MUXED) { - LOG_ERROR("ETB: can't run in multiplexed mode"); - return ERROR_ETM_PORTMODE_NOT_SUPPORTED; - } - - trigger_count = (etb->ram_depth * etb->trigger_percent) / 100; - - etb_write_reg(&etb->reg_cache->reg_list[ETB_TRIGGER_COUNTER], trigger_count); - etb_write_reg(&etb->reg_cache->reg_list[ETB_RAM_WRITE_POINTER], 0x0); - etb_write_reg(&etb->reg_cache->reg_list[ETB_CTRL], etb_ctrl_value); - jtag_execute_queue(); - - /* we're starting a new trace, initialize capture status */ - etm_ctx->capture_status = TRACE_RUNNING; - - return ERROR_OK; -} - -static int etb_stop_capture(struct etm_context *etm_ctx) -{ - struct etb *etb = etm_ctx->capture_driver_priv; - struct reg *etb_ctrl_reg = &etb->reg_cache->reg_list[ETB_CTRL]; - - etb_write_reg(etb_ctrl_reg, 0x0); - jtag_execute_queue(); - - /* trace stopped, just clear running flag, but preserve others */ - etm_ctx->capture_status &= ~TRACE_RUNNING; - - return ERROR_OK; -} - -struct etm_capture_driver etb_capture_driver = { - .name = "etb", - .commands = etb_command_handlers, - .init = etb_init, - .status = etb_status, - .start_capture = etb_start_capture, - .stop_capture = etb_stop_capture, - .read_trace = etb_read_trace, -}; diff --git a/src/target/etb.h b/src/target/etb.h deleted file mode 100644 index 680c8a1ab..000000000 --- a/src/target/etb.h +++ /dev/null @@ -1,58 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifndef OPENOCD_TARGET_ETB_H -#define OPENOCD_TARGET_ETB_H - -/* ETB registers */ -enum { - ETB_ID = 0x00, - ETB_RAM_DEPTH = 0x01, - ETB_RAM_WIDTH = 0x02, - ETB_STATUS = 0x03, - ETB_RAM_DATA = 0x04, - ETB_RAM_READ_POINTER = 0x05, - ETB_RAM_WRITE_POINTER = 0x06, - ETB_TRIGGER_COUNTER = 0x07, - ETB_CTRL = 0x08, -}; - -struct etb { - struct etm_context *etm_ctx; - struct jtag_tap *tap; - uint32_t cur_scan_chain; - struct reg_cache *reg_cache; - - /* ETB parameters */ - uint32_t ram_depth; - uint32_t ram_width; - - /** how much trace buffer to fill after trigger */ - unsigned trigger_percent; -}; - -struct etb_reg { - uint32_t addr; - struct etb *etb; -}; - -extern struct etm_capture_driver etb_capture_driver; - -struct reg_cache *etb_build_reg_cache(struct etb *etb); - -#endif /* OPENOCD_TARGET_ETB_H */ diff --git a/src/target/etm.c b/src/target/etm.c deleted file mode 100644 index 6a00c23a8..000000000 --- a/src/target/etm.c +++ /dev/null @@ -1,2115 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "arm.h" -#include "etm.h" -#include "etb.h" -#include "image.h" -#include "arm_disassembler.h" -#include "register.h" -#include "etm_dummy.h" - -#if BUILD_OOCD_TRACE == 1 -#include "oocd_trace.h" -#endif - - -/* - * ARM "Embedded Trace Macrocell" (ETM) support -- direct JTAG access. - * - * ETM modules collect instruction and/or data trace information, compress - * it, and transfer it to a debugging host through either a (buffered) trace - * port (often a 38-pin Mictor connector) or an Embedded Trace Buffer (ETB). - * - * There are several generations of these modules. Original versions have - * JTAG access through a dedicated scan chain. Recent versions have added - * access via coprocessor instructions, memory addressing, and the ARM Debug - * Interface v5 (ADIv5); and phased out direct JTAG access. - * - * This code supports up to the ETMv1.3 architecture, as seen in ETM9 and - * most common ARM9 systems. Note: "CoreSight ETM9" implements ETMv3.2, - * implying non-JTAG connectivity options. - * - * Relevant documentation includes: - * ARM DDI 0157G ... ETM9 (r2p2) Technical Reference Manual - * ARM DDI 0315B ... CoreSight ETM9 (r0p1) Technical Reference Manual - * ARM IHI 0014O ... Embedded Trace Macrocell, Architecture Specification - */ - -enum { - RO, /* read/only */ - WO, /* write/only */ - RW, /* read/write */ -}; - -struct etm_reg_info { - uint8_t addr; - uint8_t size; /* low-N of 32 bits */ - uint8_t mode; /* RO, WO, RW */ - uint8_t bcd_vers; /* 1.0, 2.0, etc */ - const char *name; -}; - -/* - * Registers 0..0x7f are JTAG-addressable using scanchain 6. - * (Or on some processors, through coprocessor operations.) - * Newer versions of ETM make some W/O registers R/W, and - * provide definitions for some previously-unused bits. - */ - -/* core registers used to version/configure the ETM */ -static const struct etm_reg_info etm_core[] = { - /* NOTE: we "know" the order here ... */ - { ETM_CONFIG, 32, RO, 0x10, "ETM_config", }, - { ETM_ID, 32, RO, 0x20, "ETM_id", }, -}; - -/* basic registers that are always there given the right ETM version */ -static const struct etm_reg_info etm_basic[] = { - /* ETM Trace Registers */ - { ETM_CTRL, 32, RW, 0x10, "ETM_ctrl", }, - { ETM_TRIG_EVENT, 17, WO, 0x10, "ETM_trig_event", }, - { ETM_ASIC_CTRL, 8, WO, 0x10, "ETM_asic_ctrl", }, - { ETM_STATUS, 3, RO, 0x11, "ETM_status", }, - { ETM_SYS_CONFIG, 9, RO, 0x12, "ETM_sys_config", }, - - /* TraceEnable configuration */ - { ETM_TRACE_RESOURCE_CTRL, 32, WO, 0x12, "ETM_trace_resource_ctrl", }, - { ETM_TRACE_EN_CTRL2, 16, WO, 0x12, "ETM_trace_en_ctrl2", }, - { ETM_TRACE_EN_EVENT, 17, WO, 0x10, "ETM_trace_en_event", }, - { ETM_TRACE_EN_CTRL1, 26, WO, 0x10, "ETM_trace_en_ctrl1", }, - - /* ViewData configuration (data trace) */ - { ETM_VIEWDATA_EVENT, 17, WO, 0x10, "ETM_viewdata_event", }, - { ETM_VIEWDATA_CTRL1, 32, WO, 0x10, "ETM_viewdata_ctrl1", }, - { ETM_VIEWDATA_CTRL2, 32, WO, 0x10, "ETM_viewdata_ctrl2", }, - { ETM_VIEWDATA_CTRL3, 17, WO, 0x10, "ETM_viewdata_ctrl3", }, - - /* REVISIT exclude VIEWDATA_CTRL2 when it's not there */ - - { 0x78, 12, WO, 0x20, "ETM_sync_freq", }, - { 0x7a, 22, RO, 0x31, "ETM_config_code_ext", }, - { 0x7b, 32, WO, 0x31, "ETM_ext_input_select", }, - { 0x7c, 32, WO, 0x34, "ETM_trace_start_stop", }, - { 0x7d, 8, WO, 0x34, "ETM_behavior_control", }, -}; - -static const struct etm_reg_info etm_fifofull[] = { - /* FIFOFULL configuration */ - { ETM_FIFOFULL_REGION, 25, WO, 0x10, "ETM_fifofull_region", }, - { ETM_FIFOFULL_LEVEL, 8, WO, 0x10, "ETM_fifofull_level", }, -}; - -static const struct etm_reg_info etm_addr_comp[] = { - /* Address comparator register pairs */ -#define ADDR_COMPARATOR(i) \ - { ETM_ADDR_COMPARATOR_VALUE + (i) - 1, 32, WO, 0x10, \ - "ETM_addr_" #i "_comparator_value", }, \ - { ETM_ADDR_ACCESS_TYPE + (i) - 1, 7, WO, 0x10, \ - "ETM_addr_" #i "_access_type", } - ADDR_COMPARATOR(1), - ADDR_COMPARATOR(2), - ADDR_COMPARATOR(3), - ADDR_COMPARATOR(4), - ADDR_COMPARATOR(5), - ADDR_COMPARATOR(6), - ADDR_COMPARATOR(7), - ADDR_COMPARATOR(8), - - ADDR_COMPARATOR(9), - ADDR_COMPARATOR(10), - ADDR_COMPARATOR(11), - ADDR_COMPARATOR(12), - ADDR_COMPARATOR(13), - ADDR_COMPARATOR(14), - ADDR_COMPARATOR(15), - ADDR_COMPARATOR(16), - { 0, 0, 0, 0, NULL } -#undef ADDR_COMPARATOR -}; - -static const struct etm_reg_info etm_data_comp[] = { - /* Data Value Comparators (NOTE: odd addresses are reserved) */ -#define DATA_COMPARATOR(i) \ - { ETM_DATA_COMPARATOR_VALUE + 2*(i) - 1, 32, WO, 0x10, \ - "ETM_data_" #i "_comparator_value", }, \ - { ETM_DATA_COMPARATOR_MASK + 2*(i) - 1, 32, WO, 0x10, \ - "ETM_data_" #i "_comparator_mask", } - DATA_COMPARATOR(1), - DATA_COMPARATOR(2), - DATA_COMPARATOR(3), - DATA_COMPARATOR(4), - DATA_COMPARATOR(5), - DATA_COMPARATOR(6), - DATA_COMPARATOR(7), - DATA_COMPARATOR(8), - { 0, 0, 0, 0, NULL } -#undef DATA_COMPARATOR -}; - -static const struct etm_reg_info etm_counters[] = { -#define ETM_COUNTER(i) \ - { ETM_COUNTER_RELOAD_VALUE + (i) - 1, 16, WO, 0x10, \ - "ETM_counter_" #i "_reload_value", }, \ - { ETM_COUNTER_ENABLE + (i) - 1, 18, WO, 0x10, \ - "ETM_counter_" #i "_enable", }, \ - { ETM_COUNTER_RELOAD_EVENT + (i) - 1, 17, WO, 0x10, \ - "ETM_counter_" #i "_reload_event", }, \ - { ETM_COUNTER_VALUE + (i) - 1, 16, RO, 0x10, \ - "ETM_counter_" #i "_value", } - ETM_COUNTER(1), - ETM_COUNTER(2), - ETM_COUNTER(3), - ETM_COUNTER(4), - { 0, 0, 0, 0, NULL } -#undef ETM_COUNTER -}; - -static const struct etm_reg_info etm_sequencer[] = { -#define ETM_SEQ(i) \ - { ETM_SEQUENCER_EVENT + (i), 17, WO, 0x10, \ - "ETM_sequencer_event" #i, } - ETM_SEQ(0), /* 1->2 */ - ETM_SEQ(1), /* 2->1 */ - ETM_SEQ(2), /* 2->3 */ - ETM_SEQ(3), /* 3->1 */ - ETM_SEQ(4), /* 3->2 */ - ETM_SEQ(5), /* 1->3 */ -#undef ETM_SEQ - /* 0x66 reserved */ - { ETM_SEQUENCER_STATE, 2, RO, 0x10, "ETM_sequencer_state", }, -}; - -static const struct etm_reg_info etm_outputs[] = { -#define ETM_OUTPUT(i) \ - { ETM_EXTERNAL_OUTPUT + (i) - 1, 17, WO, 0x10, \ - "ETM_external_output" #i, } - - ETM_OUTPUT(1), - ETM_OUTPUT(2), - ETM_OUTPUT(3), - ETM_OUTPUT(4), - { 0, 0, 0, 0, NULL } -#undef ETM_OUTPUT -}; - -#if 0 - /* registers from 0x6c..0x7f were added after ETMv1.3 */ - - /* Context ID Comparators */ - { 0x6c, 32, RO, 0x20, "ETM_contextid_comparator_value1", } - { 0x6d, 32, RO, 0x20, "ETM_contextid_comparator_value2", } - { 0x6e, 32, RO, 0x20, "ETM_contextid_comparator_value3", } - { 0x6f, 32, RO, 0x20, "ETM_contextid_comparator_mask", } -#endif - -static int etm_get_reg(struct reg *reg); -static int etm_read_reg_w_check(struct reg *reg, - uint8_t *check_value, uint8_t *check_mask); -static int etm_register_user_commands(struct command_context *cmd_ctx); -static int etm_set_reg_w_exec(struct reg *reg, uint8_t *buf); -static int etm_write_reg(struct reg *reg, uint32_t value); - -static const struct reg_arch_type etm_scan6_type = { - .get = etm_get_reg, - .set = etm_set_reg_w_exec, -}; - -/* Look up register by ID ... most ETM instances only - * support a subset of the possible registers. - */ -static struct reg *etm_reg_lookup(struct etm_context *etm_ctx, unsigned id) -{ - struct reg_cache *cache = etm_ctx->reg_cache; - unsigned i; - - for (i = 0; i < cache->num_regs; i++) { - struct etm_reg *reg = cache->reg_list[i].arch_info; - - if (reg->reg_info->addr == id) - return &cache->reg_list[i]; - } - - /* caller asking for nonexistent register is a bug! - * REVISIT say which of the N targets was involved */ - LOG_ERROR("ETM: register 0x%02x not available", id); - return NULL; -} - -static void etm_reg_add(unsigned bcd_vers, struct arm_jtag *jtag_info, - struct reg_cache *cache, struct etm_reg *ereg, - const struct etm_reg_info *r, unsigned nreg) -{ - struct reg *reg = cache->reg_list; - - reg += cache->num_regs; - ereg += cache->num_regs; - - /* add up to "nreg" registers from "r", if supported by this - * version of the ETM, to the specified cache. - */ - for (; nreg--; r++) { - /* No more registers to add */ - if (!r->size) { - LOG_ERROR("etm_reg_add is requested to add non-existing registers, ETM config might be bogus"); - return; - } - - /* this ETM may be too old to have some registers */ - if (r->bcd_vers > bcd_vers) - continue; - - reg->name = r->name; - reg->size = r->size; - reg->value = &ereg->value; - reg->arch_info = ereg; - reg->type = &etm_scan6_type; - reg++; - cache->num_regs++; - - ereg->reg_info = r; - ereg->jtag_info = jtag_info; - ereg++; - } -} - -struct reg_cache *etm_build_reg_cache(struct target *target, - struct arm_jtag *jtag_info, struct etm_context *etm_ctx) -{ - struct reg_cache *reg_cache = malloc(sizeof(struct reg_cache)); - struct reg *reg_list = NULL; - struct etm_reg *arch_info = NULL; - unsigned bcd_vers, config; - - /* the actual registers are kept in two arrays */ - reg_list = calloc(128, sizeof(struct reg)); - arch_info = calloc(128, sizeof(struct etm_reg)); - - /* fill in values for the reg cache */ - reg_cache->name = "etm registers"; - reg_cache->next = NULL; - reg_cache->reg_list = reg_list; - reg_cache->num_regs = 0; - - /* add ETM_CONFIG, then parse its values to see - * which other registers exist in this ETM - */ - etm_reg_add(0x10, jtag_info, reg_cache, arch_info, - etm_core, 1); - - etm_get_reg(reg_list); - etm_ctx->config = buf_get_u32(arch_info->value, 0, 32); - config = etm_ctx->config; - - /* figure ETM version then add base registers */ - if (config & (1 << 31)) { - LOG_WARNING("ETMv2+ support is incomplete"); - - /* REVISIT more registers may exist; they may now be - * readable; more register bits have defined meanings; - * don't presume trace start/stop support is present; - * and include any context ID comparator registers. - */ - etm_reg_add(0x20, jtag_info, reg_cache, arch_info, - etm_core + 1, 1); - etm_get_reg(reg_list + 1); - etm_ctx->id = buf_get_u32( - arch_info[1].value, 0, 32); - LOG_DEBUG("ETM ID: %08x", (unsigned) etm_ctx->id); - bcd_vers = 0x10 + (((etm_ctx->id) >> 4) & 0xff); - - } else { - switch (config >> 28) { - case 7: - case 5: - case 3: - bcd_vers = 0x13; - break; - case 4: - case 2: - bcd_vers = 0x12; - break; - case 1: - bcd_vers = 0x11; - break; - case 0: - bcd_vers = 0x10; - break; - default: - LOG_WARNING("Bad ETMv1 protocol %d", config >> 28); - goto fail; - } - } - etm_ctx->bcd_vers = bcd_vers; - LOG_INFO("ETM v%d.%d", bcd_vers >> 4, bcd_vers & 0xf); - - etm_reg_add(bcd_vers, jtag_info, reg_cache, arch_info, - etm_basic, ARRAY_SIZE(etm_basic)); - - /* address and data comparators; counters; outputs */ - etm_reg_add(bcd_vers, jtag_info, reg_cache, arch_info, - etm_addr_comp, 4 * (0x0f & (config >> 0))); - etm_reg_add(bcd_vers, jtag_info, reg_cache, arch_info, - etm_data_comp, 2 * (0x0f & (config >> 4))); - etm_reg_add(bcd_vers, jtag_info, reg_cache, arch_info, - etm_counters, 4 * (0x07 & (config >> 13))); - etm_reg_add(bcd_vers, jtag_info, reg_cache, arch_info, - etm_outputs, (0x07 & (config >> 20))); - - /* FIFOFULL presence is optional - * REVISIT for ETMv1.2 and later, don't bother adding this - * unless ETM_SYS_CONFIG says it's also *supported* ... - */ - if (config & (1 << 23)) - etm_reg_add(bcd_vers, jtag_info, reg_cache, arch_info, - etm_fifofull, ARRAY_SIZE(etm_fifofull)); - - /* sequencer is optional (for state-dependant triggering) */ - if (config & (1 << 16)) - etm_reg_add(bcd_vers, jtag_info, reg_cache, arch_info, - etm_sequencer, ARRAY_SIZE(etm_sequencer)); - - /* REVISIT could realloc and likely save half the memory - * in the two chunks we allocated... - */ - - /* the ETM might have an ETB connected */ - if (strcmp(etm_ctx->capture_driver->name, "etb") == 0) { - struct etb *etb = etm_ctx->capture_driver_priv; - - if (!etb) { - LOG_ERROR("etb selected as etm capture driver, but no ETB configured"); - goto fail; - } - - reg_cache->next = etb_build_reg_cache(etb); - - etb->reg_cache = reg_cache->next; - } - - etm_ctx->reg_cache = reg_cache; - return reg_cache; - -fail: - free(reg_cache); - free(reg_list); - free(arch_info); - return NULL; -} - -static int etm_read_reg(struct reg *reg) -{ - return etm_read_reg_w_check(reg, NULL, NULL); -} - -static int etm_store_reg(struct reg *reg) -{ - return etm_write_reg(reg, buf_get_u32(reg->value, 0, reg->size)); -} - -int etm_setup(struct target *target) -{ - int retval; - uint32_t etm_ctrl_value; - struct arm *arm = target_to_arm(target); - struct etm_context *etm_ctx = arm->etm; - struct reg *etm_ctrl_reg; - - etm_ctrl_reg = etm_reg_lookup(etm_ctx, ETM_CTRL); - if (!etm_ctrl_reg) - return ERROR_OK; - - /* initialize some ETM control register settings */ - etm_get_reg(etm_ctrl_reg); - etm_ctrl_value = buf_get_u32(etm_ctrl_reg->value, 0, 32); - - /* clear the ETM powerdown bit (0) */ - etm_ctrl_value &= ~ETM_CTRL_POWERDOWN; - - /* configure port width (21,6:4), mode (13,17:16) and - * for older modules clocking (13) - */ - etm_ctrl_value = (etm_ctrl_value - & ~ETM_PORT_WIDTH_MASK - & ~ETM_PORT_MODE_MASK - & ~ETM_CTRL_DBGRQ - & ~ETM_PORT_CLOCK_MASK) - | etm_ctx->control; - - buf_set_u32(etm_ctrl_reg->value, 0, 32, etm_ctrl_value); - etm_store_reg(etm_ctrl_reg); - - etm_ctx->control = etm_ctrl_value; - - retval = jtag_execute_queue(); - if (retval != ERROR_OK) - return retval; - - /* REVISIT for ETMv3.0 and later, read ETM_sys_config to - * verify that those width and mode settings are OK ... - */ - - retval = etm_ctx->capture_driver->init(etm_ctx); - if (retval != ERROR_OK) { - LOG_ERROR("ETM capture driver initialization failed"); - return retval; - } - return ERROR_OK; -} - -static int etm_get_reg(struct reg *reg) -{ - int retval; - - retval = etm_read_reg(reg); - if (retval != ERROR_OK) { - LOG_ERROR("BUG: error scheduling etm register read"); - return retval; - } - - retval = jtag_execute_queue(); - if (retval != ERROR_OK) { - LOG_ERROR("register read failed"); - return retval; - } - - return ERROR_OK; -} - -static int etm_read_reg_w_check(struct reg *reg, - uint8_t *check_value, uint8_t *check_mask) -{ - struct etm_reg *etm_reg = reg->arch_info; - const struct etm_reg_info *r = etm_reg->reg_info; - uint8_t reg_addr = r->addr & 0x7f; - struct scan_field fields[3]; - int retval; - - if (etm_reg->reg_info->mode == WO) { - LOG_ERROR("BUG: can't read write-only register %s", r->name); - return ERROR_COMMAND_SYNTAX_ERROR; - } - - LOG_DEBUG("%s (%u)", r->name, reg_addr); - - retval = arm_jtag_scann(etm_reg->jtag_info, 0x6, TAP_IDLE); - if (retval != ERROR_OK) - return retval; - retval = arm_jtag_set_instr(etm_reg->jtag_info->tap, - etm_reg->jtag_info->intest_instr, - NULL, - TAP_IDLE); - if (retval != ERROR_OK) - return retval; - - fields[0].num_bits = 32; - fields[0].out_value = reg->value; - fields[0].in_value = NULL; - fields[0].check_value = NULL; - fields[0].check_mask = NULL; - - fields[1].num_bits = 7; - uint8_t temp1; - fields[1].out_value = &temp1; - buf_set_u32(&temp1, 0, 7, reg_addr); - fields[1].in_value = NULL; - fields[1].check_value = NULL; - fields[1].check_mask = NULL; - - fields[2].num_bits = 1; - uint8_t temp2; - fields[2].out_value = &temp2; - buf_set_u32(&temp2, 0, 1, 0); - fields[2].in_value = NULL; - fields[2].check_value = NULL; - fields[2].check_mask = NULL; - - jtag_add_dr_scan(etm_reg->jtag_info->tap, 3, fields, TAP_IDLE); - - fields[0].in_value = reg->value; - fields[0].check_value = check_value; - fields[0].check_mask = check_mask; - - jtag_add_dr_scan_check(etm_reg->jtag_info->tap, 3, fields, TAP_IDLE); - - return ERROR_OK; -} - -static int etm_set_reg(struct reg *reg, uint32_t value) -{ - int retval = etm_write_reg(reg, value); - if (retval != ERROR_OK) { - LOG_ERROR("BUG: error scheduling etm register write"); - return retval; - } - - buf_set_u32(reg->value, 0, reg->size, value); - reg->valid = 1; - reg->dirty = 0; - - return ERROR_OK; -} - -static int etm_set_reg_w_exec(struct reg *reg, uint8_t *buf) -{ - int retval; - - etm_set_reg(reg, buf_get_u32(buf, 0, reg->size)); - - retval = jtag_execute_queue(); - if (retval != ERROR_OK) { - LOG_ERROR("register write failed"); - return retval; - } - return ERROR_OK; -} - -static int etm_write_reg(struct reg *reg, uint32_t value) -{ - struct etm_reg *etm_reg = reg->arch_info; - const struct etm_reg_info *r = etm_reg->reg_info; - uint8_t reg_addr = r->addr & 0x7f; - struct scan_field fields[3]; - int retval; - - if (etm_reg->reg_info->mode == RO) { - LOG_ERROR("BUG: can't write read--only register %s", r->name); - return ERROR_COMMAND_SYNTAX_ERROR; - } - - LOG_DEBUG("%s (%u): 0x%8.8" PRIx32 "", r->name, reg_addr, value); - - retval = arm_jtag_scann(etm_reg->jtag_info, 0x6, TAP_IDLE); - if (retval != ERROR_OK) - return retval; - retval = arm_jtag_set_instr(etm_reg->jtag_info->tap, - etm_reg->jtag_info->intest_instr, - NULL, - TAP_IDLE); - if (retval != ERROR_OK) - return retval; - - fields[0].num_bits = 32; - uint8_t tmp1[4]; - fields[0].out_value = tmp1; - buf_set_u32(tmp1, 0, 32, value); - fields[0].in_value = NULL; - - fields[1].num_bits = 7; - uint8_t tmp2; - fields[1].out_value = &tmp2; - buf_set_u32(&tmp2, 0, 7, reg_addr); - fields[1].in_value = NULL; - - fields[2].num_bits = 1; - uint8_t tmp3; - fields[2].out_value = &tmp3; - buf_set_u32(&tmp3, 0, 1, 1); - fields[2].in_value = NULL; - - jtag_add_dr_scan(etm_reg->jtag_info->tap, 3, fields, TAP_IDLE); - - return ERROR_OK; -} - - -/* ETM trace analysis functionality */ - -static struct etm_capture_driver *etm_capture_drivers[] = { - &etb_capture_driver, - &etm_dummy_capture_driver, -#if BUILD_OOCD_TRACE == 1 - &oocd_trace_capture_driver, -#endif - NULL -}; - -static int etm_read_instruction(struct etm_context *ctx, struct arm_instruction *instruction) -{ - int i; - int section = -1; - size_t size_read; - uint32_t opcode; - int retval; - - if (!ctx->image) - return ERROR_TRACE_IMAGE_UNAVAILABLE; - - /* search for the section the current instruction belongs to */ - for (i = 0; i < ctx->image->num_sections; i++) { - if ((ctx->image->sections[i].base_address <= ctx->current_pc) && - (ctx->image->sections[i].base_address + ctx->image->sections[i].size > - ctx->current_pc)) { - section = i; - break; - } - } - - if (section == -1) { - /* current instruction couldn't be found in the image */ - return ERROR_TRACE_INSTRUCTION_UNAVAILABLE; - } - - if (ctx->core_state == ARM_STATE_ARM) { - uint8_t buf[4]; - retval = image_read_section(ctx->image, section, - ctx->current_pc - - ctx->image->sections[section].base_address, - 4, buf, &size_read); - if (retval != ERROR_OK) { - LOG_ERROR("error while reading instruction"); - return ERROR_TRACE_INSTRUCTION_UNAVAILABLE; - } - opcode = target_buffer_get_u32(ctx->target, buf); - arm_evaluate_opcode(opcode, ctx->current_pc, instruction); - } else if (ctx->core_state == ARM_STATE_THUMB) { - uint8_t buf[2]; - retval = image_read_section(ctx->image, section, - ctx->current_pc - - ctx->image->sections[section].base_address, - 2, buf, &size_read); - if (retval != ERROR_OK) { - LOG_ERROR("error while reading instruction"); - return ERROR_TRACE_INSTRUCTION_UNAVAILABLE; - } - opcode = target_buffer_get_u16(ctx->target, buf); - thumb_evaluate_opcode(opcode, ctx->current_pc, instruction); - } else if (ctx->core_state == ARM_STATE_JAZELLE) { - LOG_ERROR("BUG: tracing of jazelle code not supported"); - return ERROR_FAIL; - } else { - LOG_ERROR("BUG: unknown core state encountered"); - return ERROR_FAIL; - } - - return ERROR_OK; -} - -static int etmv1_next_packet(struct etm_context *ctx, uint8_t *packet, int apo) -{ - while (ctx->data_index < ctx->trace_depth) { - /* if the caller specified an address packet offset, skip until the - * we reach the n-th cycle marked with tracesync */ - if (apo > 0) { - if (ctx->trace_data[ctx->data_index].flags & ETMV1_TRACESYNC_CYCLE) - apo--; - - if (apo > 0) { - ctx->data_index++; - ctx->data_half = 0; - } - continue; - } - - /* no tracedata output during a TD cycle - * or in a trigger cycle */ - if ((ctx->trace_data[ctx->data_index].pipestat == STAT_TD) - || (ctx->trace_data[ctx->data_index].flags & ETMV1_TRIGGER_CYCLE)) { - ctx->data_index++; - ctx->data_half = 0; - continue; - } - - /* FIXME there are more port widths than these... */ - if ((ctx->control & ETM_PORT_WIDTH_MASK) == ETM_PORT_16BIT) { - if (ctx->data_half == 0) { - *packet = ctx->trace_data[ctx->data_index].packet & 0xff; - ctx->data_half = 1; - } else { - *packet = (ctx->trace_data[ctx->data_index].packet & 0xff00) >> 8; - ctx->data_half = 0; - ctx->data_index++; - } - } else if ((ctx->control & ETM_PORT_WIDTH_MASK) == ETM_PORT_8BIT) { - *packet = ctx->trace_data[ctx->data_index].packet & 0xff; - ctx->data_index++; - } else { - /* on a 4-bit port, a packet will be output during two consecutive cycles */ - if (ctx->data_index > (ctx->trace_depth - 2)) - return -1; - - *packet = ctx->trace_data[ctx->data_index].packet & 0xf; - *packet |= (ctx->trace_data[ctx->data_index + 1].packet & 0xf) << 4; - ctx->data_index += 2; - } - - return 0; - } - - return -1; -} - -static int etmv1_branch_address(struct etm_context *ctx) -{ - int retval; - uint8_t packet; - int shift = 0; - int apo; - uint32_t i; - - /* quit analysis if less than two cycles are left in the trace - * because we can't extract the APO */ - if (ctx->data_index > (ctx->trace_depth - 2)) - return -1; - - /* a BE could be output during an APO cycle, skip the current - * and continue with the new one */ - if (ctx->trace_data[ctx->pipe_index + 1].pipestat & 0x4) - return 1; - if (ctx->trace_data[ctx->pipe_index + 2].pipestat & 0x4) - return 2; - - /* address packet offset encoded in the next two cycles' pipestat bits */ - apo = ctx->trace_data[ctx->pipe_index + 1].pipestat & 0x3; - apo |= (ctx->trace_data[ctx->pipe_index + 2].pipestat & 0x3) << 2; - - /* count number of tracesync cycles between current pipe_index and data_index - * i.e. the number of tracesyncs that data_index already passed by - * to subtract them from the APO */ - for (i = ctx->pipe_index; i < ctx->data_index; i++) { - if (ctx->trace_data[ctx->pipe_index + 1].pipestat & ETMV1_TRACESYNC_CYCLE) - apo--; - } - - /* extract up to four 7-bit packets */ - do { - retval = etmv1_next_packet(ctx, &packet, (shift == 0) ? apo + 1 : 0); - if (retval != 0) - return -1; - ctx->last_branch &= ~(0x7f << shift); - ctx->last_branch |= (packet & 0x7f) << shift; - shift += 7; - } while ((packet & 0x80) && (shift < 28)); - - /* one last packet holding 4 bits of the address, plus the branch reason code */ - if ((shift == 28) && (packet & 0x80)) { - retval = etmv1_next_packet(ctx, &packet, 0); - if (retval != 0) - return -1; - ctx->last_branch &= 0x0fffffff; - ctx->last_branch |= (packet & 0x0f) << 28; - ctx->last_branch_reason = (packet & 0x70) >> 4; - shift += 4; - } else - ctx->last_branch_reason = 0; - - if (shift == 32) - ctx->pc_ok = 1; - - /* if a full address was output, we might have branched into Jazelle state */ - if ((shift == 32) && (packet & 0x80)) - ctx->core_state = ARM_STATE_JAZELLE; - else { - /* if we didn't branch into Jazelle state, the current processor state is - * encoded in bit 0 of the branch target address */ - if (ctx->last_branch & 0x1) { - ctx->core_state = ARM_STATE_THUMB; - ctx->last_branch &= ~0x1; - } else { - ctx->core_state = ARM_STATE_ARM; - ctx->last_branch &= ~0x3; - } - } - - return 0; -} - -static int etmv1_data(struct etm_context *ctx, int size, uint32_t *data) -{ - int j; - uint8_t buf[4]; - int retval; - - for (j = 0; j < size; j++) { - retval = etmv1_next_packet(ctx, &buf[j], 0); - if (retval != 0) - return -1; - } - - if (size == 8) { - LOG_ERROR("TODO: add support for 64-bit values"); - return -1; - } else if (size == 4) - *data = target_buffer_get_u32(ctx->target, buf); - else if (size == 2) - *data = target_buffer_get_u16(ctx->target, buf); - else if (size == 1) - *data = buf[0]; - else - return -1; - - return 0; -} - -static int etmv1_analyze_trace(struct etm_context *ctx, struct command_context *cmd_ctx) -{ - int retval; - struct arm_instruction instruction; - - /* read the trace data if it wasn't read already */ - if (ctx->trace_depth == 0) - ctx->capture_driver->read_trace(ctx); - - if (ctx->trace_depth == 0) { - command_print(cmd_ctx, "Trace is empty."); - return ERROR_OK; - } - - /* start at the beginning of the captured trace */ - ctx->pipe_index = 0; - ctx->data_index = 0; - ctx->data_half = 0; - - /* neither the PC nor the data pointer are valid */ - ctx->pc_ok = 0; - ctx->ptr_ok = 0; - - while (ctx->pipe_index < ctx->trace_depth) { - uint8_t pipestat = ctx->trace_data[ctx->pipe_index].pipestat; - uint32_t next_pc = ctx->current_pc; - uint32_t old_data_index = ctx->data_index; - uint32_t old_data_half = ctx->data_half; - uint32_t old_index = ctx->pipe_index; - uint32_t last_instruction = ctx->last_instruction; - uint32_t cycles = 0; - int current_pc_ok = ctx->pc_ok; - - if (ctx->trace_data[ctx->pipe_index].flags & ETMV1_TRIGGER_CYCLE) - command_print(cmd_ctx, "--- trigger ---"); - - /* instructions execute in IE/D or BE/D cycles */ - if ((pipestat == STAT_IE) || (pipestat == STAT_ID)) - ctx->last_instruction = ctx->pipe_index; - - /* if we don't have a valid pc skip until we reach an indirect branch */ - if ((!ctx->pc_ok) && (pipestat != STAT_BE)) { - ctx->pipe_index++; - continue; - } - - /* any indirect branch could have interrupted instruction flow - * - the branch reason code could indicate a trace discontinuity - * - a branch to the exception vectors indicates an exception - */ - if ((pipestat == STAT_BE) || (pipestat == STAT_BD)) { - /* backup current data index, to be able to consume the branch address - * before examining data address and values - */ - old_data_index = ctx->data_index; - old_data_half = ctx->data_half; - - ctx->last_instruction = ctx->pipe_index; - - retval = etmv1_branch_address(ctx); - if (retval != 0) { - /* negative return value from etmv1_branch_address means we ran out of packets, - * quit analysing the trace */ - if (retval < 0) - break; - - /* a positive return values means the current branch was abandoned, - * and a new branch was encountered in cycle ctx->pipe_index + retval; - */ - LOG_WARNING( - "abandoned branch encountered, correctness of analysis uncertain"); - ctx->pipe_index += retval; - continue; - } - - /* skip over APO cycles */ - ctx->pipe_index += 2; - - switch (ctx->last_branch_reason) { - case 0x0: /* normal PC change */ - next_pc = ctx->last_branch; - break; - case 0x1: /* tracing enabled */ - command_print(cmd_ctx, - "--- tracing enabled at 0x%8.8" PRIx32 " ---", - ctx->last_branch); - ctx->current_pc = ctx->last_branch; - ctx->pipe_index++; - continue; - break; - case 0x2: /* trace restarted after FIFO overflow */ - command_print(cmd_ctx, - "--- trace restarted after FIFO overflow at 0x%8.8" PRIx32 " ---", - ctx->last_branch); - ctx->current_pc = ctx->last_branch; - ctx->pipe_index++; - continue; - break; - case 0x3: /* exit from debug state */ - command_print(cmd_ctx, - "--- exit from debug state at 0x%8.8" PRIx32 " ---", - ctx->last_branch); - ctx->current_pc = ctx->last_branch; - ctx->pipe_index++; - continue; - break; - case 0x4: /* periodic synchronization point */ - next_pc = ctx->last_branch; - /* if we had no valid PC prior to this synchronization point, - * we have to move on with the next trace cycle - */ - if (!current_pc_ok) { - command_print(cmd_ctx, - "--- periodic synchronization point at 0x%8.8" PRIx32 " ---", - next_pc); - ctx->current_pc = next_pc; - ctx->pipe_index++; - continue; - } - break; - default: /* reserved */ - LOG_ERROR( - "BUG: branch reason code 0x%" PRIx32 " is reserved", - ctx->last_branch_reason); - return ERROR_FAIL; - } - - /* if we got here the branch was a normal PC change - * (or a periodic synchronization point, which means the same for that matter) - * if we didn't acquire a complete PC continue with the next cycle - */ - if (!ctx->pc_ok) - continue; - - /* indirect branch to the exception vector means an exception occurred */ - if ((ctx->last_branch <= 0x20) - || ((ctx->last_branch >= 0xffff0000) && - (ctx->last_branch <= 0xffff0020))) { - if ((ctx->last_branch & 0xff) == 0x10) - command_print(cmd_ctx, "data abort"); - else { - command_print(cmd_ctx, - "exception vector 0x%2.2" PRIx32 "", - ctx->last_branch); - ctx->current_pc = ctx->last_branch; - ctx->pipe_index++; - continue; - } - } - } - - /* an instruction was executed (or not, depending on the condition flags) - * retrieve it from the image for displaying */ - if (ctx->pc_ok && (pipestat != STAT_WT) && (pipestat != STAT_TD) && - !(((pipestat == STAT_BE) || (pipestat == STAT_BD)) && - ((ctx->last_branch_reason != 0x0) && (ctx->last_branch_reason != 0x4)))) { - retval = etm_read_instruction(ctx, &instruction); - if (retval != ERROR_OK) { - /* can't continue tracing with no image available */ - if (retval == ERROR_TRACE_IMAGE_UNAVAILABLE) - return retval; - else if (retval == ERROR_TRACE_INSTRUCTION_UNAVAILABLE) { - /* TODO: handle incomplete images - * for now we just quit the analysis*/ - return retval; - } - } - - cycles = old_index - last_instruction; - } - - if ((pipestat == STAT_ID) || (pipestat == STAT_BD)) { - uint32_t new_data_index = ctx->data_index; - uint32_t new_data_half = ctx->data_half; - - /* in case of a branch with data, the branch target address was consumed before - * we temporarily go back to the saved data index */ - if (pipestat == STAT_BD) { - ctx->data_index = old_data_index; - ctx->data_half = old_data_half; - } - - if (ctx->control & ETM_CTRL_TRACE_ADDR) { - uint8_t packet; - int shift = 0; - - do { - retval = etmv1_next_packet(ctx, &packet, 0); - if (retval != 0) - return ERROR_ETM_ANALYSIS_FAILED; - ctx->last_ptr &= ~(0x7f << shift); - ctx->last_ptr |= (packet & 0x7f) << shift; - shift += 7; - } while ((packet & 0x80) && (shift < 32)); - - if (shift >= 32) - ctx->ptr_ok = 1; - - if (ctx->ptr_ok) - command_print(cmd_ctx, - "address: 0x%8.8" PRIx32 "", - ctx->last_ptr); - } - - if (ctx->control & ETM_CTRL_TRACE_DATA) { - if ((instruction.type == ARM_LDM) || - (instruction.type == ARM_STM)) { - int i; - for (i = 0; i < 16; i++) { - if (instruction.info.load_store_multiple. - register_list & (1 << i)) { - uint32_t data; - if (etmv1_data(ctx, 4, &data) != 0) - return ERROR_ETM_ANALYSIS_FAILED; - command_print(cmd_ctx, - "data: 0x%8.8" PRIx32 "", - data); - } - } - } else if ((instruction.type >= ARM_LDR) && - (instruction.type <= ARM_STRH)) { - uint32_t data; - if (etmv1_data(ctx, arm_access_size(&instruction), - &data) != 0) - return ERROR_ETM_ANALYSIS_FAILED; - command_print(cmd_ctx, "data: 0x%8.8" PRIx32 "", data); - } - } - - /* restore data index after consuming BD address and data */ - if (pipestat == STAT_BD) { - ctx->data_index = new_data_index; - ctx->data_half = new_data_half; - } - } - - /* adjust PC */ - if ((pipestat == STAT_IE) || (pipestat == STAT_ID)) { - if (((instruction.type == ARM_B) || - (instruction.type == ARM_BL) || - (instruction.type == ARM_BLX)) && - (instruction.info.b_bl_bx_blx.target_address != 0xffffffff)) - next_pc = instruction.info.b_bl_bx_blx.target_address; - else - next_pc += (ctx->core_state == ARM_STATE_ARM) ? 4 : 2; - } else if (pipestat == STAT_IN) - next_pc += (ctx->core_state == ARM_STATE_ARM) ? 4 : 2; - - if ((pipestat != STAT_TD) && (pipestat != STAT_WT)) { - char cycles_text[32] = ""; - - /* if the trace was captured with cycle accurate tracing enabled, - * output the number of cycles since the last executed instruction - */ - if (ctx->control & ETM_CTRL_CYCLE_ACCURATE) { - snprintf(cycles_text, 32, " (%i %s)", - (int)cycles, - (cycles == 1) ? "cycle" : "cycles"); - } - - command_print(cmd_ctx, "%s%s%s", - instruction.text, - (pipestat == STAT_IN) ? " (not executed)" : "", - cycles_text); - - ctx->current_pc = next_pc; - - /* packets for an instruction don't start on or before the preceding - * functional pipestat (i.e. other than WT or TD) - */ - if (ctx->data_index <= ctx->pipe_index) { - ctx->data_index = ctx->pipe_index + 1; - ctx->data_half = 0; - } - } - - ctx->pipe_index += 1; - } - - return ERROR_OK; -} - -static COMMAND_HELPER(handle_etm_tracemode_command_update, - uint32_t *mode) -{ - uint32_t tracemode; - - /* what parts of data access are traced? */ - if (strcmp(CMD_ARGV[0], "none") == 0) - tracemode = 0; - else if (strcmp(CMD_ARGV[0], "data") == 0) - tracemode = ETM_CTRL_TRACE_DATA; - else if (strcmp(CMD_ARGV[0], "address") == 0) - tracemode = ETM_CTRL_TRACE_ADDR; - else if (strcmp(CMD_ARGV[0], "all") == 0) - tracemode = ETM_CTRL_TRACE_DATA | ETM_CTRL_TRACE_ADDR; - else { - command_print(CMD_CTX, "invalid option '%s'", CMD_ARGV[0]); - return ERROR_COMMAND_SYNTAX_ERROR; - } - - uint8_t context_id; - COMMAND_PARSE_NUMBER(u8, CMD_ARGV[1], context_id); - switch (context_id) { - case 0: - tracemode |= ETM_CTRL_CONTEXTID_NONE; - break; - case 8: - tracemode |= ETM_CTRL_CONTEXTID_8; - break; - case 16: - tracemode |= ETM_CTRL_CONTEXTID_16; - break; - case 32: - tracemode |= ETM_CTRL_CONTEXTID_32; - break; - default: - command_print(CMD_CTX, "invalid option '%s'", CMD_ARGV[1]); - return ERROR_COMMAND_SYNTAX_ERROR; - } - - bool etmv1_cycle_accurate; - COMMAND_PARSE_ENABLE(CMD_ARGV[2], etmv1_cycle_accurate); - if (etmv1_cycle_accurate) - tracemode |= ETM_CTRL_CYCLE_ACCURATE; - - bool etmv1_branch_output; - COMMAND_PARSE_ENABLE(CMD_ARGV[3], etmv1_branch_output); - if (etmv1_branch_output) - tracemode |= ETM_CTRL_BRANCH_OUTPUT; - - /* IGNORED: - * - CPRT tracing (coprocessor register transfers) - * - debug request (causes debug entry on trigger) - * - stall on FIFOFULL (preventing tracedata loss) - */ - *mode = tracemode; - - return ERROR_OK; -} - -COMMAND_HANDLER(handle_etm_tracemode_command) -{ - struct target *target = get_current_target(CMD_CTX); - struct arm *arm = target_to_arm(target); - struct etm_context *etm; - - if (!is_arm(arm)) { - command_print(CMD_CTX, "ETM: current target isn't an ARM"); - return ERROR_FAIL; - } - - etm = arm->etm; - if (!etm) { - command_print(CMD_CTX, "current target doesn't have an ETM configured"); - return ERROR_FAIL; - } - - uint32_t tracemode = etm->control; - - switch (CMD_ARGC) { - case 0: - break; - case 4: - CALL_COMMAND_HANDLER(handle_etm_tracemode_command_update, - &tracemode); - break; - default: - return ERROR_COMMAND_SYNTAX_ERROR; - } - - /** - * todo: fail if parameters were invalid for this hardware, - * or couldn't be written; display actual hardware state... - */ - - command_print(CMD_CTX, "current tracemode configuration:"); - - switch (tracemode & ETM_CTRL_TRACE_MASK) { - default: - command_print(CMD_CTX, "data tracing: none"); - break; - case ETM_CTRL_TRACE_DATA: - command_print(CMD_CTX, "data tracing: data only"); - break; - case ETM_CTRL_TRACE_ADDR: - command_print(CMD_CTX, "data tracing: address only"); - break; - case ETM_CTRL_TRACE_DATA | ETM_CTRL_TRACE_ADDR: - command_print(CMD_CTX, "data tracing: address and data"); - break; - } - - switch (tracemode & ETM_CTRL_CONTEXTID_MASK) { - case ETM_CTRL_CONTEXTID_NONE: - command_print(CMD_CTX, "contextid tracing: none"); - break; - case ETM_CTRL_CONTEXTID_8: - command_print(CMD_CTX, "contextid tracing: 8 bit"); - break; - case ETM_CTRL_CONTEXTID_16: - command_print(CMD_CTX, "contextid tracing: 16 bit"); - break; - case ETM_CTRL_CONTEXTID_32: - command_print(CMD_CTX, "contextid tracing: 32 bit"); - break; - } - - if (tracemode & ETM_CTRL_CYCLE_ACCURATE) - command_print(CMD_CTX, "cycle-accurate tracing enabled"); - else - command_print(CMD_CTX, "cycle-accurate tracing disabled"); - - if (tracemode & ETM_CTRL_BRANCH_OUTPUT) - command_print(CMD_CTX, "full branch address output enabled"); - else - command_print(CMD_CTX, "full branch address output disabled"); - -#define TRACEMODE_MASK ( \ - ETM_CTRL_CONTEXTID_MASK \ - | ETM_CTRL_BRANCH_OUTPUT \ - | ETM_CTRL_CYCLE_ACCURATE \ - | ETM_CTRL_TRACE_MASK \ - ) - - /* only update ETM_CTRL register if tracemode changed */ - if ((etm->control & TRACEMODE_MASK) != tracemode) { - struct reg *etm_ctrl_reg; - - etm_ctrl_reg = etm_reg_lookup(etm, ETM_CTRL); - if (!etm_ctrl_reg) - return ERROR_FAIL; - - etm->control &= ~TRACEMODE_MASK; - etm->control |= tracemode & TRACEMODE_MASK; - - buf_set_u32(etm_ctrl_reg->value, 0, 32, etm->control); - etm_store_reg(etm_ctrl_reg); - - /* invalidate old trace data */ - etm->capture_status = TRACE_IDLE; - if (etm->trace_depth > 0) { - free(etm->trace_data); - etm->trace_data = NULL; - } - etm->trace_depth = 0; - } - -#undef TRACEMODE_MASK - - return ERROR_OK; -} - -COMMAND_HANDLER(handle_etm_config_command) -{ - struct target *target; - struct arm *arm; - uint32_t portmode = 0x0; - struct etm_context *etm_ctx; - int i; - - if (CMD_ARGC != 5) - return ERROR_COMMAND_SYNTAX_ERROR; - - target = get_target(CMD_ARGV[0]); - if (!target) { - LOG_ERROR("target '%s' not defined", CMD_ARGV[0]); - return ERROR_FAIL; - } - - arm = target_to_arm(target); - if (!is_arm(arm)) { - command_print(CMD_CTX, "target '%s' is '%s'; not an ARM", - target_name(target), - target_type_name(target)); - return ERROR_FAIL; - } - - /* FIXME for ETMv3.0 and above -- and we don't yet know what ETM - * version we'll be using!! -- so we can't know how to validate - * params yet. "etm config" should likely be *AFTER* hookup... - * - * - Many more widths might be supported ... and we can easily - * check whether our setting "took". - * - * - The "clock" and "mode" bits are interpreted differently. - * See ARM IHI 0014O table 2-17 for the old behaviour, and - * table 2-18 for the new. With ETB it's best to specify - * "normal full" ... - */ - uint8_t port_width; - COMMAND_PARSE_NUMBER(u8, CMD_ARGV[1], port_width); - switch (port_width) { - /* before ETMv3.0 */ - case 4: - portmode |= ETM_PORT_4BIT; - break; - case 8: - portmode |= ETM_PORT_8BIT; - break; - case 16: - portmode |= ETM_PORT_16BIT; - break; - /* ETMv3.0 and later*/ - case 24: - portmode |= ETM_PORT_24BIT; - break; - case 32: - portmode |= ETM_PORT_32BIT; - break; - case 48: - portmode |= ETM_PORT_48BIT; - break; - case 64: - portmode |= ETM_PORT_64BIT; - break; - case 1: - portmode |= ETM_PORT_1BIT; - break; - case 2: - portmode |= ETM_PORT_2BIT; - break; - default: - command_print(CMD_CTX, - "unsupported ETM port width '%s'", CMD_ARGV[1]); - return ERROR_FAIL; - } - - if (strcmp("normal", CMD_ARGV[2]) == 0) - portmode |= ETM_PORT_NORMAL; - else if (strcmp("multiplexed", CMD_ARGV[2]) == 0) - portmode |= ETM_PORT_MUXED; - else if (strcmp("demultiplexed", CMD_ARGV[2]) == 0) - portmode |= ETM_PORT_DEMUXED; - else { - command_print(CMD_CTX, - "unsupported ETM port mode '%s', must be 'normal', 'multiplexed' or 'demultiplexed'", - CMD_ARGV[2]); - return ERROR_FAIL; - } - - if (strcmp("half", CMD_ARGV[3]) == 0) - portmode |= ETM_PORT_HALF_CLOCK; - else if (strcmp("full", CMD_ARGV[3]) == 0) - portmode |= ETM_PORT_FULL_CLOCK; - else { - command_print(CMD_CTX, - "unsupported ETM port clocking '%s', must be 'full' or 'half'", - CMD_ARGV[3]); - return ERROR_FAIL; - } - - etm_ctx = calloc(1, sizeof(struct etm_context)); - if (!etm_ctx) { - LOG_DEBUG("out of memory"); - return ERROR_FAIL; - } - - for (i = 0; etm_capture_drivers[i]; i++) { - if (strcmp(CMD_ARGV[4], etm_capture_drivers[i]->name) == 0) { - int retval = register_commands(CMD_CTX, NULL, - etm_capture_drivers[i]->commands); - if (ERROR_OK != retval) { - free(etm_ctx); - return retval; - } - - etm_ctx->capture_driver = etm_capture_drivers[i]; - - break; - } - } - - if (!etm_capture_drivers[i]) { - /* no supported capture driver found, don't register an ETM */ - free(etm_ctx); - LOG_ERROR("trace capture driver '%s' not found", CMD_ARGV[4]); - return ERROR_FAIL; - } - - etm_ctx->target = target; - etm_ctx->trace_data = NULL; - etm_ctx->control = portmode; - etm_ctx->core_state = ARM_STATE_ARM; - - arm->etm = etm_ctx; - - return etm_register_user_commands(CMD_CTX); -} - -COMMAND_HANDLER(handle_etm_info_command) -{ - struct target *target; - struct arm *arm; - struct etm_context *etm; - struct reg *etm_sys_config_reg; - int max_port_size; - uint32_t config; - - target = get_current_target(CMD_CTX); - arm = target_to_arm(target); - if (!is_arm(arm)) { - command_print(CMD_CTX, "ETM: current target isn't an ARM"); - return ERROR_FAIL; - } - - etm = arm->etm; - if (!etm) { - command_print(CMD_CTX, "current target doesn't have an ETM configured"); - return ERROR_FAIL; - } - - command_print(CMD_CTX, "ETM v%d.%d", - etm->bcd_vers >> 4, etm->bcd_vers & 0xf); - command_print(CMD_CTX, "pairs of address comparators: %i", - (int) (etm->config >> 0) & 0x0f); - command_print(CMD_CTX, "data comparators: %i", - (int) (etm->config >> 4) & 0x0f); - command_print(CMD_CTX, "memory map decoders: %i", - (int) (etm->config >> 8) & 0x1f); - command_print(CMD_CTX, "number of counters: %i", - (int) (etm->config >> 13) & 0x07); - command_print(CMD_CTX, "sequencer %spresent", - (int) (etm->config & (1 << 16)) ? "" : "not "); - command_print(CMD_CTX, "number of ext. inputs: %i", - (int) (etm->config >> 17) & 0x07); - command_print(CMD_CTX, "number of ext. outputs: %i", - (int) (etm->config >> 20) & 0x07); - command_print(CMD_CTX, "FIFO full %spresent", - (int) (etm->config & (1 << 23)) ? "" : "not "); - if (etm->bcd_vers < 0x20) - command_print(CMD_CTX, "protocol version: %i", - (int) (etm->config >> 28) & 0x07); - else { - command_print(CMD_CTX, - "coprocessor and memory access %ssupported", - (etm->config & (1 << 26)) ? "" : "not "); - command_print(CMD_CTX, "trace start/stop %spresent", - (etm->config & (1 << 26)) ? "" : "not "); - command_print(CMD_CTX, "number of context comparators: %i", - (int) (etm->config >> 24) & 0x03); - } - - /* SYS_CONFIG isn't present before ETMv1.2 */ - etm_sys_config_reg = etm_reg_lookup(etm, ETM_SYS_CONFIG); - if (!etm_sys_config_reg) - return ERROR_OK; - - etm_get_reg(etm_sys_config_reg); - config = buf_get_u32(etm_sys_config_reg->value, 0, 32); - - LOG_DEBUG("ETM SYS CONFIG %08x", (unsigned) config); - - max_port_size = config & 0x7; - if (etm->bcd_vers >= 0x30) - max_port_size |= (config >> 6) & 0x08; - switch (max_port_size) { - /* before ETMv3.0 */ - case 0: - max_port_size = 4; - break; - case 1: - max_port_size = 8; - break; - case 2: - max_port_size = 16; - break; - /* ETMv3.0 and later*/ - case 3: - max_port_size = 24; - break; - case 4: - max_port_size = 32; - break; - case 5: - max_port_size = 48; - break; - case 6: - max_port_size = 64; - break; - case 8: - max_port_size = 1; - break; - case 9: - max_port_size = 2; - break; - default: - LOG_ERROR("Illegal max_port_size"); - return ERROR_FAIL; - } - command_print(CMD_CTX, "max. port size: %i", max_port_size); - - if (etm->bcd_vers < 0x30) { - command_print(CMD_CTX, "half-rate clocking %ssupported", - (config & (1 << 3)) ? "" : "not "); - command_print(CMD_CTX, "full-rate clocking %ssupported", - (config & (1 << 4)) ? "" : "not "); - command_print(CMD_CTX, "normal trace format %ssupported", - (config & (1 << 5)) ? "" : "not "); - command_print(CMD_CTX, "multiplex trace format %ssupported", - (config & (1 << 6)) ? "" : "not "); - command_print(CMD_CTX, "demultiplex trace format %ssupported", - (config & (1 << 7)) ? "" : "not "); - } else { - /* REVISIT show which size and format are selected ... */ - command_print(CMD_CTX, "current port size %ssupported", - (config & (1 << 10)) ? "" : "not "); - command_print(CMD_CTX, "current trace format %ssupported", - (config & (1 << 11)) ? "" : "not "); - } - if (etm->bcd_vers >= 0x21) - command_print(CMD_CTX, "fetch comparisons %ssupported", - (config & (1 << 17)) ? "not " : ""); - command_print(CMD_CTX, "FIFO full %ssupported", - (config & (1 << 8)) ? "" : "not "); - - return ERROR_OK; -} - -COMMAND_HANDLER(handle_etm_status_command) -{ - struct target *target; - struct arm *arm; - struct etm_context *etm; - trace_status_t trace_status; - - target = get_current_target(CMD_CTX); - arm = target_to_arm(target); - if (!is_arm(arm)) { - command_print(CMD_CTX, "ETM: current target isn't an ARM"); - return ERROR_FAIL; - } - - etm = arm->etm; - if (!etm) { - command_print(CMD_CTX, "current target doesn't have an ETM configured"); - return ERROR_FAIL; - } - - /* ETM status */ - if (etm->bcd_vers >= 0x11) { - struct reg *reg; - - reg = etm_reg_lookup(etm, ETM_STATUS); - if (!reg) - return ERROR_FAIL; - if (etm_get_reg(reg) == ERROR_OK) { - unsigned s = buf_get_u32(reg->value, 0, reg->size); - - command_print(CMD_CTX, "etm: %s%s%s%s", - /* bit(1) == progbit */ - (etm->bcd_vers >= 0x12) - ? ((s & (1 << 1)) - ? "disabled" : "enabled") - : "?", - ((s & (1 << 3)) && etm->bcd_vers >= 0x31) - ? " triggered" : "", - ((s & (1 << 2)) && etm->bcd_vers >= 0x12) - ? " start/stop" : "", - ((s & (1 << 0)) && etm->bcd_vers >= 0x11) - ? " untraced-overflow" : ""); - } /* else ignore and try showing trace port status */ - } - - /* Trace Port Driver status */ - trace_status = etm->capture_driver->status(etm); - if (trace_status == TRACE_IDLE) - command_print(CMD_CTX, "%s: idle", etm->capture_driver->name); - else { - static char *completed = " completed"; - static char *running = " is running"; - static char *overflowed = ", overflowed"; - static char *triggered = ", triggered"; - - command_print(CMD_CTX, "%s: trace collection%s%s%s", - etm->capture_driver->name, - (trace_status & TRACE_RUNNING) ? running : completed, - (trace_status & TRACE_OVERFLOWED) ? overflowed : "", - (trace_status & TRACE_TRIGGERED) ? triggered : ""); - - if (etm->trace_depth > 0) { - command_print(CMD_CTX, "%i frames of trace data read", - (int)(etm->trace_depth)); - } - } - - return ERROR_OK; -} - -COMMAND_HANDLER(handle_etm_image_command) -{ - struct target *target; - struct arm *arm; - struct etm_context *etm_ctx; - - if (CMD_ARGC < 1) - return ERROR_COMMAND_SYNTAX_ERROR; - - target = get_current_target(CMD_CTX); - arm = target_to_arm(target); - if (!is_arm(arm)) { - command_print(CMD_CTX, "ETM: current target isn't an ARM"); - return ERROR_FAIL; - } - - etm_ctx = arm->etm; - if (!etm_ctx) { - command_print(CMD_CTX, "current target doesn't have an ETM configured"); - return ERROR_FAIL; - } - - if (etm_ctx->image) { - image_close(etm_ctx->image); - free(etm_ctx->image); - command_print(CMD_CTX, "previously loaded image found and closed"); - } - - etm_ctx->image = malloc(sizeof(struct image)); - etm_ctx->image->base_address_set = 0; - etm_ctx->image->start_address_set = 0; - - /* a base address isn't always necessary, default to 0x0 (i.e. don't relocate) */ - if (CMD_ARGC >= 2) { - etm_ctx->image->base_address_set = 1; - COMMAND_PARSE_NUMBER(llong, CMD_ARGV[1], etm_ctx->image->base_address); - } else - etm_ctx->image->base_address_set = 0; - - if (image_open(etm_ctx->image, CMD_ARGV[0], - (CMD_ARGC >= 3) ? CMD_ARGV[2] : NULL) != ERROR_OK) { - free(etm_ctx->image); - etm_ctx->image = NULL; - return ERROR_FAIL; - } - - return ERROR_OK; -} - -COMMAND_HANDLER(handle_etm_dump_command) -{ - struct fileio *file; - struct target *target; - struct arm *arm; - struct etm_context *etm_ctx; - uint32_t i; - - if (CMD_ARGC != 1) - return ERROR_COMMAND_SYNTAX_ERROR; - - target = get_current_target(CMD_CTX); - arm = target_to_arm(target); - if (!is_arm(arm)) { - command_print(CMD_CTX, "ETM: current target isn't an ARM"); - return ERROR_FAIL; - } - - etm_ctx = arm->etm; - if (!etm_ctx) { - command_print(CMD_CTX, "current target doesn't have an ETM configured"); - return ERROR_FAIL; - } - - if (etm_ctx->capture_driver->status == TRACE_IDLE) { - command_print(CMD_CTX, "trace capture wasn't enabled, no trace data captured"); - return ERROR_OK; - } - - if (etm_ctx->capture_driver->status(etm_ctx) & TRACE_RUNNING) { - /* TODO: if on-the-fly capture is to be supported, this needs to be changed */ - command_print(CMD_CTX, "trace capture not completed"); - return ERROR_FAIL; - } - - /* read the trace data if it wasn't read already */ - if (etm_ctx->trace_depth == 0) - etm_ctx->capture_driver->read_trace(etm_ctx); - - 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); - - 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_close(file); - - return ERROR_OK; -} - -COMMAND_HANDLER(handle_etm_load_command) -{ - struct fileio *file; - struct target *target; - struct arm *arm; - struct etm_context *etm_ctx; - uint32_t i; - - if (CMD_ARGC != 1) - return ERROR_COMMAND_SYNTAX_ERROR; - - target = get_current_target(CMD_CTX); - arm = target_to_arm(target); - if (!is_arm(arm)) { - command_print(CMD_CTX, "ETM: current target isn't an ARM"); - return ERROR_FAIL; - } - - etm_ctx = arm->etm; - if (!etm_ctx) { - command_print(CMD_CTX, "current target doesn't have an ETM configured"); - return ERROR_FAIL; - } - - if (etm_ctx->capture_driver->status(etm_ctx) & TRACE_RUNNING) { - command_print(CMD_CTX, "trace capture running, stop first"); - return ERROR_FAIL; - } - - if (fileio_open(&file, CMD_ARGV[0], FILEIO_READ, FILEIO_BINARY) != ERROR_OK) - return ERROR_FAIL; - - size_t filesize; - int retval = fileio_size(file, &filesize); - if (retval != ERROR_OK) { - 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); - return ERROR_FAIL; - } - - if (etm_ctx->trace_depth > 0) { - free(etm_ctx->trace_data); - etm_ctx->trace_data = NULL; - } - - { - 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); - } - 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); - 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); - 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); - - return ERROR_OK; -} - -COMMAND_HANDLER(handle_etm_start_command) -{ - struct target *target; - struct arm *arm; - struct etm_context *etm_ctx; - struct reg *etm_ctrl_reg; - - target = get_current_target(CMD_CTX); - arm = target_to_arm(target); - if (!is_arm(arm)) { - command_print(CMD_CTX, "ETM: current target isn't an ARM"); - return ERROR_FAIL; - } - - etm_ctx = arm->etm; - if (!etm_ctx) { - command_print(CMD_CTX, "current target doesn't have an ETM configured"); - return ERROR_FAIL; - } - - /* invalidate old tracing data */ - etm_ctx->capture_status = TRACE_IDLE; - if (etm_ctx->trace_depth > 0) { - free(etm_ctx->trace_data); - etm_ctx->trace_data = NULL; - } - etm_ctx->trace_depth = 0; - - etm_ctrl_reg = etm_reg_lookup(etm_ctx, ETM_CTRL); - if (!etm_ctrl_reg) - return ERROR_FAIL; - - etm_get_reg(etm_ctrl_reg); - - /* Clear programming bit (10), set port selection bit (11) */ - buf_set_u32(etm_ctrl_reg->value, 10, 2, 0x2); - - etm_store_reg(etm_ctrl_reg); - jtag_execute_queue(); - - etm_ctx->capture_driver->start_capture(etm_ctx); - - return ERROR_OK; -} - -COMMAND_HANDLER(handle_etm_stop_command) -{ - struct target *target; - struct arm *arm; - struct etm_context *etm_ctx; - struct reg *etm_ctrl_reg; - - target = get_current_target(CMD_CTX); - arm = target_to_arm(target); - if (!is_arm(arm)) { - command_print(CMD_CTX, "ETM: current target isn't an ARM"); - return ERROR_FAIL; - } - - etm_ctx = arm->etm; - if (!etm_ctx) { - command_print(CMD_CTX, "current target doesn't have an ETM configured"); - return ERROR_FAIL; - } - - etm_ctrl_reg = etm_reg_lookup(etm_ctx, ETM_CTRL); - if (!etm_ctrl_reg) - return ERROR_FAIL; - - etm_get_reg(etm_ctrl_reg); - - /* Set programming bit (10), clear port selection bit (11) */ - buf_set_u32(etm_ctrl_reg->value, 10, 2, 0x1); - - etm_store_reg(etm_ctrl_reg); - jtag_execute_queue(); - - etm_ctx->capture_driver->stop_capture(etm_ctx); - - return ERROR_OK; -} - -COMMAND_HANDLER(handle_etm_trigger_debug_command) -{ - struct target *target; - struct arm *arm; - struct etm_context *etm; - - target = get_current_target(CMD_CTX); - arm = target_to_arm(target); - if (!is_arm(arm)) { - command_print(CMD_CTX, "ETM: %s isn't an ARM", - target_name(target)); - return ERROR_FAIL; - } - - etm = arm->etm; - if (!etm) { - command_print(CMD_CTX, "ETM: no ETM configured for %s", - target_name(target)); - return ERROR_FAIL; - } - - if (CMD_ARGC == 1) { - struct reg *etm_ctrl_reg; - bool dbgrq; - - etm_ctrl_reg = etm_reg_lookup(etm, ETM_CTRL); - if (!etm_ctrl_reg) - return ERROR_FAIL; - - COMMAND_PARSE_ENABLE(CMD_ARGV[0], dbgrq); - if (dbgrq) - etm->control |= ETM_CTRL_DBGRQ; - else - etm->control &= ~ETM_CTRL_DBGRQ; - - /* etm->control will be written to hardware - * the next time an "etm start" is issued. - */ - buf_set_u32(etm_ctrl_reg->value, 0, 32, etm->control); - } - - command_print(CMD_CTX, "ETM: %s debug halt", - (etm->control & ETM_CTRL_DBGRQ) - ? "triggers" - : "does not trigger"); - return ERROR_OK; -} - -COMMAND_HANDLER(handle_etm_analyze_command) -{ - struct target *target; - struct arm *arm; - struct etm_context *etm_ctx; - int retval; - - target = get_current_target(CMD_CTX); - arm = target_to_arm(target); - if (!is_arm(arm)) { - command_print(CMD_CTX, "ETM: current target isn't an ARM"); - return ERROR_FAIL; - } - - etm_ctx = arm->etm; - if (!etm_ctx) { - command_print(CMD_CTX, "current target doesn't have an ETM configured"); - return ERROR_FAIL; - } - - retval = etmv1_analyze_trace(etm_ctx, CMD_CTX); - if (retval != ERROR_OK) { - /* FIX! error should be reported inside etmv1_analyze_trace() */ - switch (retval) { - case ERROR_ETM_ANALYSIS_FAILED: - command_print(CMD_CTX, - "further analysis failed (corrupted trace data or just end of data"); - break; - case ERROR_TRACE_INSTRUCTION_UNAVAILABLE: - command_print(CMD_CTX, - "no instruction for current address available, analysis aborted"); - break; - case ERROR_TRACE_IMAGE_UNAVAILABLE: - command_print(CMD_CTX, "no image available for trace analysis"); - break; - default: - command_print(CMD_CTX, "unknown error"); - } - } - - return retval; -} - -static const struct command_registration etm_config_command_handlers[] = { - { - /* NOTE: with ADIv5, ETMs are accessed by DAP operations, - * possibly over SWD, not JTAG scanchain 6 of 'target'. - * - * Also, these parameters don't match ETM v3+ modules... - */ - .name = "config", - .handler = handle_etm_config_command, - .mode = COMMAND_CONFIG, - .help = "Set up ETM output port.", - .usage = "target port_width port_mode clocking capture_driver", - }, - COMMAND_REGISTRATION_DONE -}; -const struct command_registration etm_command_handlers[] = { - { - .name = "etm", - .mode = COMMAND_ANY, - .help = "Embedded Trace Macrocell command group", - .usage = "", - .chain = etm_config_command_handlers, - }, - COMMAND_REGISTRATION_DONE -}; - -static const struct command_registration etm_exec_command_handlers[] = { - { - .name = "tracemode", - .handler = handle_etm_tracemode_command, - .mode = COMMAND_EXEC, - .help = "configure/display trace mode", - .usage = "('none'|'data'|'address'|'all') " - "context_id_bits " - "['enable'|'disable'] " - "['enable'|'disable']", - }, - { - .name = "info", - .handler = handle_etm_info_command, - .mode = COMMAND_EXEC, - .usage = "", - .help = "display info about the current target's ETM", - }, - { - .name = "status", - .handler = handle_etm_status_command, - .mode = COMMAND_EXEC, - .usage = "", - .help = "display current target's ETM status", - }, - { - .name = "start", - .handler = handle_etm_start_command, - .mode = COMMAND_EXEC, - .usage = "", - .help = "start ETM trace collection", - }, - { - .name = "stop", - .handler = handle_etm_stop_command, - .mode = COMMAND_EXEC, - .usage = "", - .help = "stop ETM trace collection", - }, - { - .name = "trigger_debug", - .handler = handle_etm_trigger_debug_command, - .mode = COMMAND_EXEC, - .help = "enable/disable debug entry on trigger", - .usage = "['enable'|'disable']", - }, - { - .name = "analyze", - .handler = handle_etm_analyze_command, - .mode = COMMAND_EXEC, - .usage = "", - .help = "analyze collected ETM trace", - }, - { - .name = "image", - .handler = handle_etm_image_command, - .mode = COMMAND_EXEC, - .help = "load image from file with optional offset", - .usage = " [base address] [type]", - }, - { - .name = "dump", - .handler = handle_etm_dump_command, - .mode = COMMAND_EXEC, - .help = "dump captured trace data to file", - .usage = "filename", - }, - { - .name = "load", - .handler = handle_etm_load_command, - .mode = COMMAND_EXEC, - .usage = "", - .help = "load trace data for analysis ", - }, - COMMAND_REGISTRATION_DONE -}; - -static int etm_register_user_commands(struct command_context *cmd_ctx) -{ - struct command *etm_cmd = command_find_in_context(cmd_ctx, "etm"); - return register_commands(cmd_ctx, etm_cmd, etm_exec_command_handlers); -} diff --git a/src/target/etm.h b/src/target/etm.h deleted file mode 100644 index 6a78b7564..000000000 --- a/src/target/etm.h +++ /dev/null @@ -1,224 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005, 2007 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * Copyright (C) 2007 by Vincent Palatin * - * vincent.palatin_openocd@m4x.org * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifndef OPENOCD_TARGET_ETM_H -#define OPENOCD_TARGET_ETM_H - -#include "trace.h" -#include "arm_jtag.h" - -struct image; - -/* ETM registers (JTAG protocol) */ -enum { - ETM_CTRL = 0x00, - ETM_CONFIG = 0x01, - ETM_TRIG_EVENT = 0x02, - ETM_ASIC_CTRL = 0x03, - ETM_STATUS = 0x04, - ETM_SYS_CONFIG = 0x05, - ETM_TRACE_RESOURCE_CTRL = 0x06, - ETM_TRACE_EN_CTRL2 = 0x07, - ETM_TRACE_EN_EVENT = 0x08, - ETM_TRACE_EN_CTRL1 = 0x09, - /* optional FIFOFULL */ - ETM_FIFOFULL_REGION = 0x0a, - ETM_FIFOFULL_LEVEL = 0x0b, - /* viewdata support */ - ETM_VIEWDATA_EVENT = 0x0c, - ETM_VIEWDATA_CTRL1 = 0x0d, - ETM_VIEWDATA_CTRL2 = 0x0e, /* optional */ - ETM_VIEWDATA_CTRL3 = 0x0f, - /* N pairs of ADDR_{COMPARATOR,ACCESS} registers */ - ETM_ADDR_COMPARATOR_VALUE = 0x10, - ETM_ADDR_ACCESS_TYPE = 0x20, - /* N pairs of DATA_COMPARATOR_{VALUE,MASK} registers */ - ETM_DATA_COMPARATOR_VALUE = 0x30, - ETM_DATA_COMPARATOR_MASK = 0x40, - /* N quads of COUNTER_{RELOAD_{VALUE,EVENT},ENABLE,VALUE} registers */ - ETM_COUNTER_RELOAD_VALUE = 0x50, - ETM_COUNTER_ENABLE = 0x54, - ETM_COUNTER_RELOAD_EVENT = 0x58, - ETM_COUNTER_VALUE = 0x5c, - /* 6 sequencer event transitions */ - ETM_SEQUENCER_EVENT = 0x60, - ETM_SEQUENCER_STATE = 0x67, - /* N triggered outputs */ - ETM_EXTERNAL_OUTPUT = 0x68, - /* N task contexts */ - ETM_CONTEXTID_COMPARATOR_VALUE = 0x6c, - ETM_CONTEXTID_COMPARATOR_MASK = 0x6f, - ETM_ID = 0x79, -}; - -struct etm_reg { - uint8_t value[4]; - const struct etm_reg_info *reg_info; - struct arm_jtag *jtag_info; -}; - -/* Subset of ETM_CTRL bit assignments. Many of these - * control the configuration of trace output, which - * hooks up either to ETB or to an external device. - * - * NOTE that these have evolved since the ~v1.3 defns ... - */ -enum { - ETM_CTRL_POWERDOWN = (1 << 0), - ETM_CTRL_MONITOR_CPRT = (1 << 1), - - /* bits 3:2 == trace type */ - ETM_CTRL_TRACE_DATA = (1 << 2), - ETM_CTRL_TRACE_ADDR = (2 << 2), - ETM_CTRL_TRACE_MASK = (3 << 2), - - /* Port width (bits 21 and 6:4) */ - ETM_PORT_4BIT = 0x00, - ETM_PORT_8BIT = 0x10, - ETM_PORT_16BIT = 0x20, - ETM_PORT_24BIT = 0x30, - ETM_PORT_32BIT = 0x40, - ETM_PORT_48BIT = 0x50, - ETM_PORT_64BIT = 0x60, - ETM_PORT_1BIT = 0x00 | (1 << 21), - ETM_PORT_2BIT = 0x10 | (1 << 21), - ETM_PORT_WIDTH_MASK = 0x70 | (1 << 21), - - ETM_CTRL_FIFOFULL_STALL = (1 << 7), - ETM_CTRL_BRANCH_OUTPUT = (1 << 8), - ETM_CTRL_DBGRQ = (1 << 9), - ETM_CTRL_ETM_PROG = (1 << 10), - ETM_CTRL_ETMEN = (1 << 11), - ETM_CTRL_CYCLE_ACCURATE = (1 << 12), - - /* Clocking modes -- up to v2.1, bit 13 */ - ETM_PORT_FULL_CLOCK = (0 << 13), - ETM_PORT_HALF_CLOCK = (1 << 13), - ETM_PORT_CLOCK_MASK = (1 << 13), - - /* bits 15:14 == context ID size used in tracing */ - ETM_CTRL_CONTEXTID_NONE = (0 << 14), - ETM_CTRL_CONTEXTID_8 = (1 << 14), - ETM_CTRL_CONTEXTID_16 = (2 << 14), - ETM_CTRL_CONTEXTID_32 = (3 << 14), - ETM_CTRL_CONTEXTID_MASK = (3 << 14), - - /* Port modes -- bits 17:16, tied to clocking mode */ - ETM_PORT_NORMAL = (0 << 16), - ETM_PORT_MUXED = (1 << 16), - ETM_PORT_DEMUXED = (2 << 16), - ETM_PORT_MODE_MASK = (3 << 16), - - /* bits 31:18 defined in v3.0 and later (e.g. ARM11+) */ -}; - -/* forward-declare ETM context */ -struct etm_context; - -struct etm_capture_driver { - const char *name; - const struct command_registration *commands; - int (*init)(struct etm_context *etm_ctx); - trace_status_t (*status)(struct etm_context *etm_ctx); - int (*read_trace)(struct etm_context *etm_ctx); - int (*start_capture)(struct etm_context *etm_ctx); - int (*stop_capture)(struct etm_context *etm_ctx); -}; - -enum { - ETMV1_TRACESYNC_CYCLE = 0x1, - ETMV1_TRIGGER_CYCLE = 0x2, -}; - -struct etmv1_trace_data { - uint8_t pipestat; /* bits 0-2 pipeline status */ - uint16_t packet; /* packet data (4, 8 or 16 bit) */ - int flags; /* ETMV1_TRACESYNC_CYCLE, ETMV1_TRIGGER_CYCLE */ -}; - -/* describe a trace context - * if support for ETMv2 or ETMv3 is to be implemented, - * this will have to be split into version independent elements - * and a version specific part - */ -struct etm_context { - struct target *target; /* target this ETM is connected to */ - struct reg_cache *reg_cache; /* ETM register cache */ - struct etm_capture_driver *capture_driver; /* driver used to access ETM data */ - void *capture_driver_priv; /* capture driver private data */ - trace_status_t capture_status; /* current state of capture run */ - struct etmv1_trace_data *trace_data; /* trace data */ - uint32_t trace_depth; /* number of cycles to be analyzed, 0 if no data available */ - uint32_t control; /* shadow of ETM_CTRL */ - int /*arm_state*/ core_state; /* current core state */ - struct image *image; /* source for target opcodes */ - uint32_t pipe_index; /* current trace cycle */ - uint32_t data_index; /* cycle holding next data packet */ - bool data_half; /* port half on a 16 bit port */ - bool pc_ok; /* full PC has been acquired */ - bool ptr_ok; /* whether last_ptr is valid */ - uint8_t bcd_vers; /* e.g. 0x13 == ETMv1.3 */ - uint32_t config; /* cache of ETM_CONFIG value */ - uint32_t id; /* cache of ETM_ID value, or 0 */ - uint32_t current_pc; /* current program counter */ - uint32_t last_branch; /* last branch address output */ - uint32_t last_branch_reason; /* type of last branch encountered */ - uint32_t last_ptr; /* address of the last data access */ - uint32_t last_instruction; /* index of last executed (to calc timings) */ -}; - -/* PIPESTAT values */ -typedef enum { - STAT_IE = 0x0, - STAT_ID = 0x1, - STAT_IN = 0x2, - STAT_WT = 0x3, - STAT_BE = 0x4, - STAT_BD = 0x5, - STAT_TR = 0x6, - STAT_TD = 0x7 -} etmv1_pipestat_t; - -/* branch reason values */ -typedef enum { - BR_NORMAL = 0x0, /* Normal PC change : periodic synchro (ETMv1.1) */ - BR_ENABLE = 0x1, /* Trace has been enabled */ - BR_RESTART = 0x2, /* Trace restarted after a FIFO overflow */ - BR_NODEBUG = 0x3, /* ARM has exited for debug state */ - BR_PERIOD = 0x4, /* Peridioc synchronization point (ETM >= v1.2)*/ - BR_RSVD5 = 0x5, /* reserved */ - BR_RSVD6 = 0x6, /* reserved */ - BR_RSVD7 = 0x7, /* reserved */ -} etmv1_branch_reason_t; - -struct reg_cache *etm_build_reg_cache(struct target *target, - struct arm_jtag *jtag_info, struct etm_context *etm_ctx); - -int etm_setup(struct target *target); - -extern const struct command_registration etm_command_handlers[]; - -#define ERROR_ETM_INVALID_DRIVER (-1300) -#define ERROR_ETM_PORTMODE_NOT_SUPPORTED (-1301) -#define ERROR_ETM_CAPTURE_INIT_FAILED (-1302) -#define ERROR_ETM_ANALYSIS_FAILED (-1303) - -#endif /* OPENOCD_TARGET_ETM_H */ diff --git a/src/target/etm_dummy.c b/src/target/etm_dummy.c deleted file mode 100644 index b18ce1744..000000000 --- a/src/target/etm_dummy.c +++ /dev/null @@ -1,106 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "arm.h" -#include "etm_dummy.h" - -COMMAND_HANDLER(handle_etm_dummy_config_command) -{ - struct target *target; - struct arm *arm; - - target = get_target(CMD_ARGV[0]); - - if (!target) { - LOG_ERROR("target '%s' not defined", CMD_ARGV[0]); - return ERROR_FAIL; - } - - arm = target_to_arm(target); - if (!is_arm(arm)) { - command_print(CMD_CTX, "target '%s' isn't an ARM", CMD_ARGV[0]); - return ERROR_FAIL; - } - - if (arm->etm) - arm->etm->capture_driver_priv = NULL; - else { - LOG_ERROR("target has no ETM defined, ETM dummy left unconfigured"); - return ERROR_FAIL; - } - - return ERROR_OK; -} - -static const struct command_registration etm_dummy_config_command_handlers[] = { - { - .name = "config", - .handler = handle_etm_dummy_config_command, - .mode = COMMAND_CONFIG, - .usage = "target", - }, - COMMAND_REGISTRATION_DONE -}; -static const struct command_registration etm_dummy_command_handlers[] = { - { - .name = "etm_dummy", - .mode = COMMAND_ANY, - .help = "Dummy ETM capture driver command group", - .chain = etm_dummy_config_command_handlers, - }, - COMMAND_REGISTRATION_DONE -}; - -static int etm_dummy_init(struct etm_context *etm_ctx) -{ - return ERROR_OK; -} - -static trace_status_t etm_dummy_status(struct etm_context *etm_ctx) -{ - return TRACE_IDLE; -} - -static int etm_dummy_read_trace(struct etm_context *etm_ctx) -{ - return ERROR_OK; -} - -static int etm_dummy_start_capture(struct etm_context *etm_ctx) -{ - return ERROR_ETM_PORTMODE_NOT_SUPPORTED; -} - -static int etm_dummy_stop_capture(struct etm_context *etm_ctx) -{ - return ERROR_OK; -} - -struct etm_capture_driver etm_dummy_capture_driver = { - .name = "dummy", - .commands = etm_dummy_command_handlers, - .init = etm_dummy_init, - .status = etm_dummy_status, - .start_capture = etm_dummy_start_capture, - .stop_capture = etm_dummy_stop_capture, - .read_trace = etm_dummy_read_trace, -}; diff --git a/src/target/etm_dummy.h b/src/target/etm_dummy.h deleted file mode 100644 index 5a1955f37..000000000 --- a/src/target/etm_dummy.h +++ /dev/null @@ -1,26 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#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 /* OPENOCD_TARGET_ETM_DUMMY_H */ diff --git a/src/target/fa526.c b/src/target/fa526.c deleted file mode 100644 index 9f6b80551..000000000 --- a/src/target/fa526.c +++ /dev/null @@ -1,387 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2009 by Paulius Zaleckas * - * paulius.zaleckas@gmail.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -/* - * FA526 is very similar to ARM920T with following differences: - * - * - execution pipeline is 6 steps - * - Unified TLB - * - has Branch Target Buffer - * - does not support reading of I/D cache contents - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "arm920t.h" -#include "target_type.h" -#include "arm_opcodes.h" - -static void fa526_change_to_arm(struct target *target, uint32_t *r0, uint32_t *pc) -{ - LOG_ERROR("%s: there is no Thumb state on FA526", __func__); -} - -static void fa526_read_core_regs(struct target *target, - uint32_t mask, uint32_t *core_regs[16]) -{ - int i; - struct arm7_9_common *arm7_9 = target_to_arm7_9(target); - struct arm_jtag *jtag_info = &arm7_9->jtag_info; - - /* STMIA r0-15, [r0] at debug speed - * register values will start to appear on 4th DCLK - */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_STMIA(0, mask & 0xffff, 0, 0), 0, NULL, 0); - - /* fetch NOP, STM in DECODE stage */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - /* fetch NOP, STM in SHIFT stage */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - /* fetch NOP, STM in EXECUTE stage (1st cycle) */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - - for (i = 0; i <= 15; i++) { - if (mask & (1 << i)) - /* nothing fetched, STM in MEMORY (i'th cycle) */ - arm9tdmi_clock_data_in(jtag_info, core_regs[i]); - } -} - -static void fa526_read_core_regs_target_buffer(struct target *target, - uint32_t mask, void *buffer, int size) -{ - int i; - struct arm7_9_common *arm7_9 = target_to_arm7_9(target); - struct arm_jtag *jtag_info = &arm7_9->jtag_info; - int be = (target->endianness == TARGET_BIG_ENDIAN) ? 1 : 0; - uint32_t *buf_u32 = buffer; - uint16_t *buf_u16 = buffer; - uint8_t *buf_u8 = buffer; - - /* STMIA r0-15, [r0] at debug speed - * register values will start to appear on 4th DCLK - */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_STMIA(0, mask & 0xffff, 0, 0), 0, NULL, 0); - - /* fetch NOP, STM in DECODE stage */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - /* fetch NOP, STM in SHIFT stage */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - /* fetch NOP, STM in EXECUTE stage (1st cycle) */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - - for (i = 0; i <= 15; i++) { - if (mask & (1 << i)) - /* nothing fetched, STM in MEMORY (i'th cycle) */ - switch (size) { - case 4: - arm9tdmi_clock_data_in_endianness(jtag_info, buf_u32++, 4, be); - break; - case 2: - arm9tdmi_clock_data_in_endianness(jtag_info, buf_u16++, 2, be); - break; - case 1: - arm9tdmi_clock_data_in_endianness(jtag_info, buf_u8++, 1, be); - break; - } - } -} - -static void fa526_read_xpsr(struct target *target, uint32_t *xpsr, int spsr) -{ - struct arm7_9_common *arm7_9 = target_to_arm7_9(target); - struct arm_jtag *jtag_info = &arm7_9->jtag_info; - - /* MRS r0, cpsr */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_MRS(0, spsr & 1), 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - - /* STR r0, [r15] */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_STR(0, 15), 0, NULL, 0); - /* fetch NOP, STR in DECODE stage */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - /* fetch NOP, STR in SHIFT stage */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - /* fetch NOP, STR in EXECUTE stage (1st cycle) */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - /* nothing fetched, STR in MEMORY */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, xpsr, 0); -} - -static void fa526_write_xpsr(struct target *target, uint32_t xpsr, int spsr) -{ - struct arm7_9_common *arm7_9 = target_to_arm7_9(target); - struct arm_jtag *jtag_info = &arm7_9->jtag_info; - - LOG_DEBUG("xpsr: %8.8" PRIx32 ", spsr: %i", xpsr, spsr); - - /* MSR1 fetched */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM(xpsr & 0xff, 0, 1, spsr), 0, NULL, 0); - /* MSR2 fetched, MSR1 in DECODE */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM((xpsr & 0xff00) >> 8, 0xc, 2, spsr), 0, NULL, 0); - /* MSR3 fetched, MSR1 in SHIFT, MSR2 in DECODE */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM((xpsr & 0xff0000) >> 16, 0x8, 4, spsr), 0, NULL, 0); - /* MSR4 fetched, MSR1 in EXECUTE (1), MSR2 in SHIFT, MSR3 in DECODE */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM((xpsr & 0xff000000) >> 24, 0x4, 8, spsr), 0, NULL, 0); - /* nothing fetched, MSR1 in EXECUTE (2) */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - /* nothing fetched, MSR1 in EXECUTE (3) */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - /* nothing fetched, MSR2 in EXECUTE (1), MSR3 in SHIFT, MSR4 in DECODE */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - /* nothing fetched, MSR2 in EXECUTE (2) */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - /* nothing fetched, MSR2 in EXECUTE (3) */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - /* NOP fetched, MSR3 in EXECUTE (1), MSR4 in SHIFT */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - /* nothing fetched, MSR3 in EXECUTE (2) */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - /* nothing fetched, MSR3 in EXECUTE (3) */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - /* NOP fetched, MSR4 in EXECUTE (1) */ - /* last MSR writes flags, which takes only one cycle */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); -} - -static void fa526_write_xpsr_im8(struct target *target, - uint8_t xpsr_im, int rot, int spsr) -{ - struct arm7_9_common *arm7_9 = target_to_arm7_9(target); - struct arm_jtag *jtag_info = &arm7_9->jtag_info; - - LOG_DEBUG("xpsr_im: %2.2x, rot: %i, spsr: %i", xpsr_im, rot, spsr); - - /* MSR fetched */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM(xpsr_im, rot, 1, spsr), 0, NULL, 0); - /* NOP fetched, MSR in DECODE */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - /* NOP fetched, MSR in SHIFT */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - /* NOP fetched, MSR in EXECUTE (1) */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - - /* rot == 4 writes flags, which takes only one cycle */ - if (rot != 4) { - /* nothing fetched, MSR in EXECUTE (2) */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - /* nothing fetched, MSR in EXECUTE (3) */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - } -} - -static void fa526_write_core_regs(struct target *target, - uint32_t mask, uint32_t core_regs[16]) -{ - int i; - struct arm7_9_common *arm7_9 = target_to_arm7_9(target); - struct arm_jtag *jtag_info = &arm7_9->jtag_info; - - /* LDMIA r0-15, [r0] at debug speed - * register values will start to appear on 4th DCLK - */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_LDMIA(0, mask & 0xffff, 0, 0), 0, NULL, 0); - - /* fetch NOP, LDM in DECODE stage */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - /* fetch NOP, LDM in SHIFT stage */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - /* fetch NOP, LDM in EXECUTE stage (1st cycle) */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - - for (i = 0; i <= 15; i++) { - if (mask & (1 << i)) - /* nothing fetched, LDM still in EXECUTE (1 + i cycle) */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, core_regs[i], NULL, 0); - } - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); -} - -static void fa526_write_pc(struct target *target, uint32_t pc) -{ - struct arm7_9_common *arm7_9 = target_to_arm7_9(target); - struct arm_jtag *jtag_info = &arm7_9->jtag_info; - - /* LDMIA r0-15, [r0] at debug speed - * register values will start to appear on 4th DCLK - */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_LDMIA(0, 0x8000, 0, 0), 0, NULL, 0); - - /* fetch NOP, LDM in DECODE stage */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - /* fetch NOP, LDM in SHIFT stage */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - /* fetch NOP, LDM in EXECUTE stage (1st cycle) */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - /* nothing fetched, LDM in EXECUTE stage (2nd cycle) (output data) */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, pc, NULL, 0); - /* nothing fetched, LDM in EXECUTE stage (3rd cycle) */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - /* fetch NOP, LDM in EXECUTE stage (4th cycle) */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - /* fetch NOP, LDM in EXECUTE stage (5th cycle) */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); -} - -static void fa526_branch_resume_thumb(struct target *target) -{ - LOG_ERROR("%s: there is no Thumb state on FA526", __func__); -} - -static int fa526_init_arch_info_2(struct target *target, - struct arm7_9_common *arm7_9, struct jtag_tap *tap) -{ - /* prepare JTAG information for the new target */ - arm7_9->jtag_info.tap = tap; - arm7_9->jtag_info.scann_size = 5; - - /* register arch-specific functions */ - arm7_9->examine_debug_reason = arm9tdmi_examine_debug_reason; - arm7_9->change_to_arm = fa526_change_to_arm; - arm7_9->read_core_regs = fa526_read_core_regs; - arm7_9->read_core_regs_target_buffer = fa526_read_core_regs_target_buffer; - arm7_9->read_xpsr = fa526_read_xpsr; - - arm7_9->write_xpsr = fa526_write_xpsr; - arm7_9->write_xpsr_im8 = fa526_write_xpsr_im8; - arm7_9->write_core_regs = fa526_write_core_regs; - - arm7_9->load_word_regs = arm9tdmi_load_word_regs; - arm7_9->load_hword_reg = arm9tdmi_load_hword_reg; - arm7_9->load_byte_reg = arm9tdmi_load_byte_reg; - - arm7_9->store_word_regs = arm9tdmi_store_word_regs; - arm7_9->store_hword_reg = arm9tdmi_store_hword_reg; - arm7_9->store_byte_reg = arm9tdmi_store_byte_reg; - - arm7_9->write_pc = fa526_write_pc; - arm7_9->branch_resume = arm9tdmi_branch_resume; - arm7_9->branch_resume_thumb = fa526_branch_resume_thumb; - - arm7_9->enable_single_step = arm9tdmi_enable_single_step; - arm7_9->disable_single_step = arm9tdmi_disable_single_step; - - arm7_9->write_memory = arm920t_write_memory; - arm7_9->bulk_write_memory = arm7_9_bulk_write_memory; - - arm7_9->post_debug_entry = NULL; - - arm7_9->pre_restore_context = NULL; - - /* initialize arch-specific breakpoint handling */ - arm7_9->arm_bkpt = 0xdeeedeee; - arm7_9->thumb_bkpt = 0xdeee; - - arm7_9->dbgreq_adjust_pc = 3; - - arm7_9_init_arch_info(target, arm7_9); - - /* override use of DBGRQ, this is safe on ARM9TDMI */ - arm7_9->use_dbgrq = 1; - - /* all ARM9s have the vector catch register */ - arm7_9->has_vector_catch = 1; - - return ERROR_OK; -} - -static int fa526_init_arch_info(struct target *target, - struct arm920t_common *arm920t, struct jtag_tap *tap) -{ - struct arm7_9_common *arm7_9 = &arm920t->arm7_9_common; - - /* initialize arm7/arm9 specific info (including armv4_5) */ - fa526_init_arch_info_2(target, arm7_9, tap); - - arm920t->common_magic = ARM920T_COMMON_MAGIC; - - arm7_9->post_debug_entry = arm920t_post_debug_entry; - arm7_9->pre_restore_context = arm920t_pre_restore_context; - - arm920t->armv4_5_mmu.armv4_5_cache.ctype = -1; - arm920t->armv4_5_mmu.get_ttb = arm920t_get_ttb; - arm920t->armv4_5_mmu.read_memory = arm7_9_read_memory; - arm920t->armv4_5_mmu.write_memory = arm7_9_write_memory; - arm920t->armv4_5_mmu.disable_mmu_caches = arm920t_disable_mmu_caches; - arm920t->armv4_5_mmu.enable_mmu_caches = arm920t_enable_mmu_caches; - arm920t->armv4_5_mmu.has_tiny_pages = 1; - arm920t->armv4_5_mmu.mmu_enabled = 0; - - /* disabling linefills leads to lockups, so keep them enabled for now - * this doesn't affect correctness, but might affect timing issues, if - * important data is evicted from the cache during the debug session - * */ - arm920t->preserve_cache = 0; - - /* override hw single-step capability from ARM9TDMI */ - arm7_9->has_single_step = 1; - - return ERROR_OK; -} - -static int fa526_target_create(struct target *target, Jim_Interp *interp) -{ - struct arm920t_common *arm920t = calloc(1, sizeof(struct arm920t_common)); - - return fa526_init_arch_info(target, arm920t, target->tap); -} - -/** Holds methods for FA526 targets. */ -struct target_type fa526_target = { - .name = "fa526", - - .poll = arm7_9_poll, - .arch_state = arm920t_arch_state, - - .target_request_data = arm7_9_target_request_data, - - .halt = arm7_9_halt, - .resume = arm7_9_resume, - .step = arm7_9_step, - - .assert_reset = arm7_9_assert_reset, - .deassert_reset = arm7_9_deassert_reset, - .soft_reset_halt = arm920t_soft_reset_halt, - - .get_gdb_reg_list = arm_get_gdb_reg_list, - - .read_memory = arm920t_read_memory, - .write_memory = arm7_9_write_memory_opt, - - .checksum_memory = arm_checksum_memory, - .blank_check_memory = arm_blank_check_memory, - - .run_algorithm = armv4_5_run_algorithm, - - .add_breakpoint = arm7_9_add_breakpoint, - .remove_breakpoint = arm7_9_remove_breakpoint, - .add_watchpoint = arm7_9_add_watchpoint, - .remove_watchpoint = arm7_9_remove_watchpoint, - - .commands = arm920t_command_handlers, - .target_create = fa526_target_create, - .init_target = arm9tdmi_init_target, - .examine = arm7_9_examine, - .check_reset = arm7_9_check_reset, -}; diff --git a/src/target/feroceon.c b/src/target/feroceon.c deleted file mode 100644 index f12e4e450..000000000 --- a/src/target/feroceon.c +++ /dev/null @@ -1,769 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2008-2009 by Marvell Semiconductors, Inc. * - * Written by Nicolas Pitre * - * * - * Copyright (C) 2008 by Hongtao Zheng * - * hontor@126.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -/* - * Marvell Feroceon/Dragonite support. - * - * The Feroceon core, as found in the Orion and Kirkwood SoCs amongst others, - * mimics the ARM926 ICE interface with the following differences: - * - * - the MOE (method of entry) reporting is not implemented - * - * - breakpoint/watchpoint comparator #1 is seemingly not implemented - * - * - due to a different pipeline implementation, some injected debug - * instruction sequences have to be somewhat different - * - * Other issues: - * - * - asserting DBGRQ doesn't work if target is looping on the undef vector - * - * - the EICE version signature in the COMMS_CTL reg is next to the flow bits - * not at the top, and rather meaningless due to existing discrepencies - * - * - the DCC channel is half duplex (only one FIFO for both directions) with - * seemingly no proper flow control. - * - * The Dragonite core is the non-mmu version based on the ARM966 model, and - * it shares the above issues as well. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "arm926ejs.h" -#include "arm966e.h" -#include "target_type.h" -#include "register.h" -#include "arm_opcodes.h" - -static int feroceon_assert_reset(struct target *target) -{ - struct arm *arm = target->arch_info; - 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); - arm7_9->use_dbgrq = ud; - return arm7_9_assert_reset(target); -} - -static int feroceon_dummy_clock_out(struct arm_jtag *jtag_info, uint32_t instr) -{ - struct scan_field fields[3]; - uint8_t out_buf[4]; - uint8_t instr_buf[4]; - uint8_t sysspeed_buf = 0x0; - int retval; - - /* prepare buffer */ - buf_set_u32(out_buf, 0, 32, 0); - - buf_set_u32(instr_buf, 0, 32, flip_u32(instr, 32)); - - retval = arm_jtag_scann(jtag_info, 0x1, TAP_DRPAUSE); - if (retval != ERROR_OK) - return retval; - - retval = arm_jtag_set_instr(jtag_info->tap, jtag_info->intest_instr, NULL, TAP_DRPAUSE); - if (retval != ERROR_OK) - return retval; - - fields[0].num_bits = 32; - fields[0].out_value = out_buf; - fields[0].in_value = NULL; - - fields[1].num_bits = 3; - fields[1].out_value = &sysspeed_buf; - fields[1].in_value = NULL; - - fields[2].num_bits = 32; - fields[2].out_value = instr_buf; - fields[2].in_value = NULL; - - jtag_add_dr_scan(jtag_info->tap, 3, fields, TAP_DRPAUSE); - - /* no jtag_add_runtest(0, TAP_DRPAUSE) here */ - - return ERROR_OK; -} - -static void feroceon_change_to_arm(struct target *target, uint32_t *r0, - uint32_t *pc) -{ - struct arm *arm = target->arch_info; - struct arm7_9_common *arm7_9 = arm->arch_info; - struct arm_jtag *jtag_info = &arm7_9->jtag_info; - - /* - * save r0 before using it and put system in ARM state - * to allow common handling of ARM and THUMB debugging - */ - - feroceon_dummy_clock_out(jtag_info, ARMV4_5_T_NOP); - feroceon_dummy_clock_out(jtag_info, ARMV4_5_T_NOP); - feroceon_dummy_clock_out(jtag_info, ARMV4_5_T_NOP); - - arm9tdmi_clock_out(jtag_info, ARMV4_5_T_STR(0, 0), 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, r0, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0); - - arm9tdmi_clock_out(jtag_info, ARMV4_5_T_MOV(0, 15), 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_T_STR(0, 0), 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, pc, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0); - - arm9tdmi_clock_out(jtag_info, ARMV4_5_T_BX(15), 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0); - - jtag_execute_queue(); - - /* - * fix program counter: - * MOV R0, PC was the 7th instruction (+12) - * reading PC in Thumb state gives address of instruction + 4 - */ - *pc -= (12 + 4); -} - -static void feroceon_read_core_regs(struct target *target, - uint32_t mask, uint32_t *core_regs[16]) -{ - int i; - struct arm *arm = target->arch_info; - struct arm7_9_common *arm7_9 = arm->arch_info; - struct arm_jtag *jtag_info = &arm7_9->jtag_info; - - arm9tdmi_clock_out(jtag_info, ARMV4_5_STMIA(0, mask & 0xffff, 0, 0), 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - - for (i = 0; i <= 15; i++) - if (mask & (1 << i)) - arm9tdmi_clock_data_in(jtag_info, core_regs[i]); - - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); -} - -static void feroceon_read_core_regs_target_buffer(struct target *target, - uint32_t mask, void *buffer, int size) -{ - int i; - struct arm *arm = target->arch_info; - struct arm7_9_common *arm7_9 = arm->arch_info; - struct arm_jtag *jtag_info = &arm7_9->jtag_info; - int be = (target->endianness == TARGET_BIG_ENDIAN) ? 1 : 0; - uint32_t *buf_u32 = buffer; - uint16_t *buf_u16 = buffer; - uint8_t *buf_u8 = buffer; - - arm9tdmi_clock_out(jtag_info, ARMV4_5_STMIA(0, mask & 0xffff, 0, 0), 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - - for (i = 0; i <= 15; i++) { - if (mask & (1 << i)) { - switch (size) { - case 4: - arm9tdmi_clock_data_in_endianness(jtag_info, buf_u32++, 4, be); - break; - case 2: - arm9tdmi_clock_data_in_endianness(jtag_info, buf_u16++, 2, be); - break; - case 1: - arm9tdmi_clock_data_in_endianness(jtag_info, buf_u8++, 1, be); - break; - } - } - } - - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); -} - -static void feroceon_read_xpsr(struct target *target, uint32_t *xpsr, int spsr) -{ - struct arm *arm = target->arch_info; - struct arm7_9_common *arm7_9 = arm->arch_info; - struct arm_jtag *jtag_info = &arm7_9->jtag_info; - - arm9tdmi_clock_out(jtag_info, ARMV4_5_MRS(0, spsr & 1), 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - - arm9tdmi_clock_out(jtag_info, ARMV4_5_STMIA(0, 1, 0, 0), 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, xpsr, 0); - - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); -} - -static void feroceon_write_xpsr(struct target *target, uint32_t xpsr, int spsr) -{ - struct arm *arm = target->arch_info; - struct arm7_9_common *arm7_9 = arm->arch_info; - struct arm_jtag *jtag_info = &arm7_9->jtag_info; - - LOG_DEBUG("xpsr: %8.8" PRIx32 ", spsr: %i", xpsr, spsr); - - arm9tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM(xpsr & 0xff, 0, 1, spsr), 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - - arm9tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM((xpsr & 0xff00) >> 8, 0xc, 2, spsr), 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - - arm9tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM((xpsr & 0xff0000) >> 16, 0x8, 4, spsr), 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - - arm9tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM((xpsr & 0xff000000) >> 24, 0x4, 8, spsr), 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); -} - -static void feroceon_write_xpsr_im8(struct target *target, - uint8_t xpsr_im, int rot, int spsr) -{ - struct arm *arm = target->arch_info; - struct arm7_9_common *arm7_9 = arm->arch_info; - struct arm_jtag *jtag_info = &arm7_9->jtag_info; - - LOG_DEBUG("xpsr_im: %2.2x, rot: %i, spsr: %i", xpsr_im, rot, spsr); - - arm9tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM(xpsr_im, rot, 1, spsr), 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); -} - -static void feroceon_write_core_regs(struct target *target, - uint32_t mask, uint32_t core_regs[16]) -{ - int i; - struct arm *arm = target->arch_info; - struct arm7_9_common *arm7_9 = arm->arch_info; - struct arm_jtag *jtag_info = &arm7_9->jtag_info; - - arm9tdmi_clock_out(jtag_info, ARMV4_5_LDMIA(0, mask & 0xffff, 0, 0), 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - - for (i = 0; i <= 15; i++) - if (mask & (1 << i)) - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, core_regs[i], NULL, 0); - - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); -} - -static void feroceon_branch_resume(struct target *target) -{ - struct arm *arm = target->arch_info; - struct arm7_9_common *arm7_9 = arm->arch_info; - struct arm_jtag *jtag_info = &arm7_9->jtag_info; - - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_B(0xfffff9, 0), 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 1); - - arm7_9->need_bypass_before_restart = 1; -} - -static void feroceon_branch_resume_thumb(struct target *target) -{ - LOG_DEBUG("-"); - - struct arm *arm = target->arch_info; - struct arm7_9_common *arm7_9 = arm->arch_info; - struct arm_jtag *jtag_info = &arm7_9->jtag_info; - uint32_t r0 = buf_get_u32(arm->core_cache->reg_list[0].value, 0, 32); - uint32_t pc = buf_get_u32(arm->pc->value, 0, 32); - - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - - arm9tdmi_clock_out(jtag_info, 0xE28F0001, 0, NULL, 0); /* add r0,pc,#1 */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_BX(0), 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - - arm9tdmi_clock_out(jtag_info, ARMV4_5_T_LDMIA(0, 0x1), 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0); - - arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, r0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0); - - pc = (pc & 2) >> 1; - arm9tdmi_clock_out(jtag_info, ARMV4_5_T_B(0x7e9 + pc), 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 1); - - arm7_9->need_bypass_before_restart = 1; -} - -static int feroceon_read_cp15(struct target *target, uint32_t op1, - uint32_t op2, uint32_t CRn, uint32_t CRm, uint32_t *value) -{ - struct arm *arm = target->arch_info; - struct arm7_9_common *arm7_9 = arm->arch_info; - struct arm_jtag *jtag_info = &arm7_9->jtag_info; - int err; - - arm9tdmi_clock_out(jtag_info, ARMV4_5_MRC(15, op1, 0, CRn, CRm, op2), 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 1); - err = arm7_9_execute_sys_speed(target); - if (err != ERROR_OK) - return err; - - arm9tdmi_clock_out(jtag_info, ARMV4_5_STMIA(0, 1, 0, 0), 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, value, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - return jtag_execute_queue(); -} - -static int feroceon_write_cp15(struct target *target, uint32_t op1, - uint32_t op2, uint32_t CRn, uint32_t CRm, uint32_t value) -{ - struct arm *arm = target->arch_info; - struct arm7_9_common *arm7_9 = arm->arch_info; - struct arm_jtag *jtag_info = &arm7_9->jtag_info; - - arm9tdmi_clock_out(jtag_info, ARMV4_5_LDMIA(0, 1, 0, 0), 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, value, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); - - arm9tdmi_clock_out(jtag_info, ARMV4_5_MCR(15, op1, 0, CRn, CRm, op2), 0, NULL, 0); - arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 1); - return arm7_9_execute_sys_speed(target); -} - -static void feroceon_set_dbgrq(struct target *target) -{ - struct arm *arm = target->arch_info; - struct arm7_9_common *arm7_9 = arm->arch_info; - struct reg *dbg_ctrl = &arm7_9->eice_cache->reg_list[EICE_DBG_CTRL]; - - buf_set_u32(dbg_ctrl->value, 0, 8, 2); - embeddedice_store_reg(dbg_ctrl); -} - -static void feroceon_enable_single_step(struct target *target, uint32_t next_pc) -{ - struct arm *arm = target->arch_info; - struct arm7_9_common *arm7_9 = arm->arch_info; - - /* set a breakpoint there */ - embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_ADDR_VALUE], next_pc); - embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_ADDR_MASK], 0); - embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_DATA_MASK], 0xffffffff); - embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_VALUE], 0x100); - embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_MASK], 0xf7); -} - -static void feroceon_disable_single_step(struct target *target) -{ - struct arm *arm = target->arch_info; - struct arm7_9_common *arm7_9 = arm->arch_info; - - embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_W0_ADDR_VALUE]); - embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_W0_ADDR_MASK]); - embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_W0_DATA_MASK]); - embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_MASK]); - embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_VALUE]); -} - -static int feroceon_examine_debug_reason(struct target *target) -{ - /* the MOE is not implemented */ - if (target->debug_reason != DBG_REASON_SINGLESTEP) - target->debug_reason = DBG_REASON_DBGRQ; - - return ERROR_OK; -} - -static int feroceon_bulk_write_memory(struct target *target, - uint32_t address, uint32_t count, const uint8_t *buffer) -{ - int retval; - struct arm *arm = target->arch_info; - struct arm7_9_common *arm7_9 = arm->arch_info; - enum arm_state core_state = arm->core_state; - uint32_t x, flip, shift, save[7]; - uint32_t i; - - /* - * We can't use the dcc flow control bits, so let's transfer data - * with 31 bits and flip the MSB each time a new data word is sent. - */ - static uint32_t dcc_code[] = { - 0xee115e10, /* 3: mrc p14, 0, r5, c1, c0, 0 */ - 0xe3a0301e, /* 1: mov r3, #30 */ - 0xe3a04002, /* mov r4, #2 */ - 0xee111e10, /* 2: mrc p14, 0, r1, c1, c0, 0 */ - 0xe1310005, /* teq r1, r5 */ - 0x0afffffc, /* beq 1b */ - 0xe1a05001, /* mov r5, r1 */ - 0xe1a01081, /* mov r1, r1, lsl #1 */ - 0xee112e10, /* 3: mrc p14, 0, r2, c1, c0, 0 */ - 0xe1320005, /* teq r2, r5 */ - 0x0afffffc, /* beq 3b */ - 0xe1a05002, /* mov r5, r2 */ - 0xe3c22102, /* bic r2, r2, #0x80000000 */ - 0xe1811332, /* orr r1, r1, r2, lsr r3 */ - 0xe2533001, /* subs r3, r3, #1 */ - 0xe4801004, /* str r1, [r0], #4 */ - 0xe1a01412, /* mov r1, r2, lsl r4 */ - 0xe2844001, /* add r4, r4, #1 */ - 0x4affffed, /* bmi 1b */ - 0xeafffff3, /* b 3b */ - }; - - uint32_t dcc_size = sizeof(dcc_code); - - if (address % 4 != 0) - return ERROR_TARGET_UNALIGNED_ACCESS; - - if (!arm7_9->dcc_downloads) - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - - /* regrab previously allocated working_area, or allocate a new one */ - if (!arm7_9->dcc_working_area) { - uint8_t dcc_code_buf[dcc_size]; - - /* make sure we have a working area */ - if (target_alloc_working_area(target, dcc_size, &arm7_9->dcc_working_area) != ERROR_OK) { - LOG_INFO("no working area available, falling back to memory writes"); - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - } - - /* copy target instructions to target endianness */ - target_buffer_set_u32_array(target, dcc_code_buf, ARRAY_SIZE(dcc_code), dcc_code); - - /* write DCC code to working area, using the non-optimized - * memory write to avoid ending up here again */ - retval = arm7_9_write_memory_no_opt(target, - arm7_9->dcc_working_area->address, 4, dcc_size/4, dcc_code_buf); - if (retval != ERROR_OK) - return retval; - } - - /* backup clobbered processor state */ - for (i = 0; i <= 5; i++) - save[i] = buf_get_u32(arm->core_cache->reg_list[i].value, 0, 32); - save[i] = buf_get_u32(arm->pc->value, 0, 32); - - /* set up target address in r0 */ - buf_set_u32(arm->core_cache->reg_list[0].value, 0, 32, address); - arm->core_cache->reg_list[0].valid = 1; - arm->core_cache->reg_list[0].dirty = 1; - arm->core_state = ARM_STATE_ARM; - - embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_COMMS_DATA], 0); - arm7_9_resume(target, 0, arm7_9->dcc_working_area->address, 1, 1); - - /* send data over */ - x = 0; - flip = 0; - shift = 1; - for (i = 0; i < count; i++) { - uint32_t y = target_buffer_get_u32(target, buffer); - uint32_t z = (x >> 1) | (y >> shift) | (flip ^= 0x80000000); - embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_COMMS_DATA], z); - x = y << (32 - shift); - if (++shift >= 32 || i + 1 >= count) { - z = (x >> 1) | (flip ^= 0x80000000); - embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_COMMS_DATA], z); - x = 0; - shift = 1; - } - buffer += 4; - } - - retval = target_halt(target); - if (retval == ERROR_OK) - retval = target_wait_state(target, TARGET_HALTED, 500); - if (retval == ERROR_OK) { - uint32_t endaddress = - 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 - " got 0x%0" PRIx32 "", - address + count*4, endaddress); - retval = ERROR_FAIL; - } - } - - /* restore target state */ - for (i = 0; i <= 5; i++) { - buf_set_u32(arm->core_cache->reg_list[i].value, 0, 32, save[i]); - arm->core_cache->reg_list[i].valid = 1; - arm->core_cache->reg_list[i].dirty = 1; - } - buf_set_u32(arm->pc->value, 0, 32, save[i]); - arm->pc->valid = 1; - arm->pc->dirty = 1; - arm->core_state = core_state; - - return retval; -} - -static int feroceon_init_target(struct command_context *cmd_ctx, - struct target *target) -{ - arm9tdmi_init_target(cmd_ctx, target); - return ERROR_OK; -} - -static void feroceon_common_setup(struct target *target) -{ - struct arm *arm = target->arch_info; - struct arm7_9_common *arm7_9 = arm->arch_info; - - /* override some insn sequence functions */ - arm7_9->change_to_arm = feroceon_change_to_arm; - arm7_9->read_core_regs = feroceon_read_core_regs; - arm7_9->read_core_regs_target_buffer = feroceon_read_core_regs_target_buffer; - arm7_9->read_xpsr = feroceon_read_xpsr; - arm7_9->write_xpsr = feroceon_write_xpsr; - arm7_9->write_xpsr_im8 = feroceon_write_xpsr_im8; - arm7_9->write_core_regs = feroceon_write_core_regs; - arm7_9->branch_resume = feroceon_branch_resume; - arm7_9->branch_resume_thumb = feroceon_branch_resume_thumb; - - /* must be implemented with only one comparator */ - arm7_9->enable_single_step = feroceon_enable_single_step; - arm7_9->disable_single_step = feroceon_disable_single_step; - - arm7_9->bulk_write_memory = feroceon_bulk_write_memory; - - /* MOE is not implemented */ - arm7_9->examine_debug_reason = feroceon_examine_debug_reason; - - /* Note: asserting DBGRQ might not win over the undef exception. - If that happens then just use "arm7_9 dbgrq disable". */ - arm7_9->use_dbgrq = 1; - arm7_9->set_special_dbgrq = feroceon_set_dbgrq; - - /* only one working comparator */ - arm7_9->wp_available_max = 1; - arm7_9->wp1_used_default = -1; -} - -static int feroceon_target_create(struct target *target, Jim_Interp *interp) -{ - struct arm926ejs_common *arm926ejs = calloc(1, sizeof(struct arm926ejs_common)); - - arm926ejs_init_arch_info(target, arm926ejs, target->tap); - feroceon_common_setup(target); - - struct arm *arm = target->arch_info; - struct arm7_9_common *arm7_9 = arm->arch_info; - arm7_9->write_memory = arm926ejs_write_memory; - - /* the standard ARM926 methods don't always work (don't ask...) */ - arm926ejs->read_cp15 = feroceon_read_cp15; - arm926ejs->write_cp15 = feroceon_write_cp15; - - return ERROR_OK; -} - -static int dragonite_target_create(struct target *target, Jim_Interp *interp) -{ - struct arm966e_common *arm966e = calloc(1, sizeof(struct arm966e_common)); - - arm966e_init_arch_info(target, arm966e, target->tap); - feroceon_common_setup(target); - - struct arm *arm = target->arch_info; - struct arm7_9_common *arm7_9 = arm->arch_info; - arm7_9->write_memory = arm7_9_write_memory; - - return ERROR_OK; -} - -static int feroceon_examine(struct target *target) -{ - struct arm *arm; - struct arm7_9_common *arm7_9; - int retval; - - retval = arm7_9_examine(target); - if (retval != ERROR_OK) - return retval; - - arm = target->arch_info; - arm7_9 = arm->arch_info; - - /* the COMMS_CTRL bits are all contiguous */ - if (buf_get_u32(arm7_9->eice_cache->reg_list[EICE_COMMS_CTRL].value, 2, 4) != 6) - LOG_ERROR("unexpected Feroceon EICE version signature"); - - arm7_9->eice_cache->reg_list[EICE_DBG_CTRL].size = 6; - arm7_9->eice_cache->reg_list[EICE_DBG_STAT].size = 5; - arm7_9->has_monitor_mode = 1; - - /* vector catch reg is not initialized on reset */ - embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_VEC_CATCH], 0); - - /* clear monitor mode, enable comparators */ - embeddedice_read_reg(&arm7_9->eice_cache->reg_list[EICE_DBG_CTRL]); - jtag_execute_queue(); - buf_set_u32(arm7_9->eice_cache->reg_list[EICE_DBG_CTRL].value, 4, 1, 0); - buf_set_u32(arm7_9->eice_cache->reg_list[EICE_DBG_CTRL].value, 5, 1, 0); - embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_DBG_CTRL]); - - return ERROR_OK; -} - -struct target_type feroceon_target = { - .name = "feroceon", - - .poll = arm7_9_poll, - .arch_state = arm926ejs_arch_state, - - .target_request_data = arm7_9_target_request_data, - - .halt = arm7_9_halt, - .resume = arm7_9_resume, - .step = arm7_9_step, - - .assert_reset = feroceon_assert_reset, - .deassert_reset = arm7_9_deassert_reset, - .soft_reset_halt = arm926ejs_soft_reset_halt, - - .get_gdb_reg_list = arm_get_gdb_reg_list, - - .read_memory = arm7_9_read_memory, - .write_memory = arm7_9_write_memory_opt, - - .checksum_memory = arm_checksum_memory, - .blank_check_memory = arm_blank_check_memory, - - .run_algorithm = armv4_5_run_algorithm, - - .add_breakpoint = arm7_9_add_breakpoint, - .remove_breakpoint = arm7_9_remove_breakpoint, - .add_watchpoint = arm7_9_add_watchpoint, - .remove_watchpoint = arm7_9_remove_watchpoint, - - .commands = arm926ejs_command_handlers, - .target_create = feroceon_target_create, - .init_target = feroceon_init_target, - .examine = feroceon_examine, -}; - -struct target_type dragonite_target = { - .name = "dragonite", - - .poll = arm7_9_poll, - .arch_state = arm_arch_state, - - .target_request_data = arm7_9_target_request_data, - - .halt = arm7_9_halt, - .resume = arm7_9_resume, - .step = arm7_9_step, - - .assert_reset = feroceon_assert_reset, - .deassert_reset = arm7_9_deassert_reset, - .soft_reset_halt = arm7_9_soft_reset_halt, - - .get_gdb_reg_list = arm_get_gdb_reg_list, - - .read_memory = arm7_9_read_memory, - .write_memory = arm7_9_write_memory_opt, - - .checksum_memory = arm_checksum_memory, - .blank_check_memory = arm_blank_check_memory, - - .run_algorithm = armv4_5_run_algorithm, - - .add_breakpoint = arm7_9_add_breakpoint, - .remove_breakpoint = arm7_9_remove_breakpoint, - .add_watchpoint = arm7_9_add_watchpoint, - .remove_watchpoint = arm7_9_remove_watchpoint, - - .commands = arm966e_command_handlers, - .target_create = dragonite_target_create, - .init_target = feroceon_init_target, - .examine = feroceon_examine, -}; diff --git a/src/target/hla_target.c b/src/target/hla_target.c deleted file mode 100644 index e02abc42e..000000000 --- a/src/target/hla_target.c +++ /dev/null @@ -1,815 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2011 by Mathias Kuester * - * Mathias Kuester * - * * - * Copyright (C) 2011 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * revised: 4/25/13 by brent@mbari.org [DCC target request support] * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "jtag/jtag.h" -#include "jtag/hla/hla_transport.h" -#include "jtag/hla/hla_interface.h" -#include "jtag/hla/hla_layout.h" -#include "register.h" -#include "algorithm.h" -#include "target.h" -#include "breakpoints.h" -#include "target_type.h" -#include "armv7m.h" -#include "cortex_m.h" -#include "arm_semihosting.h" -#include "target_request.h" - -#define savedDCRDR dbgbase /* FIXME: using target->dbgbase to preserve DCRDR */ - -#define ARMV7M_SCS_DCRSR DCB_DCRSR -#define ARMV7M_SCS_DCRDR DCB_DCRDR - -static inline struct hl_interface_s *target_to_adapter(struct target *target) -{ - return target->tap->priv; -} - -static int adapter_load_core_reg_u32(struct target *target, - uint32_t num, uint32_t *value) -{ - int retval; - struct hl_interface_s *adapter = target_to_adapter(target); - - LOG_DEBUG("%s", __func__); - - /* NOTE: we "know" here that the register identifiers used - * in the v7m header match the Cortex-M3 Debug Core Register - * Selector values for R0..R15, xPSR, MSP, and PSP. - */ - switch (num) { - case 0 ... 18: - /* read a normal core register */ - retval = adapter->layout->api->read_reg(adapter->handle, num, value); - - if (retval != ERROR_OK) { - LOG_ERROR("JTAG failure %i", retval); - return ERROR_JTAG_DEVICE_ERROR; - } - LOG_DEBUG("load from core reg %i value 0x%" PRIx32 "", (int)num, *value); - break; - - case ARMV7M_FPSCR: - /* Floating-point Status and Registers */ - retval = target_write_u32(target, ARMV7M_SCS_DCRSR, 33); - if (retval != ERROR_OK) - return retval; - retval = target_read_u32(target, ARMV7M_SCS_DCRDR, value); - if (retval != ERROR_OK) - return retval; - LOG_DEBUG("load from FPSCR value 0x%" PRIx32, *value); - break; - - case ARMV7M_S0 ... ARMV7M_S31: - /* Floating-point Status and Registers */ - retval = target_write_u32(target, ARMV7M_SCS_DCRSR, num-ARMV7M_S0+64); - if (retval != ERROR_OK) - return retval; - retval = target_read_u32(target, ARMV7M_SCS_DCRDR, value); - if (retval != ERROR_OK) - return retval; - LOG_DEBUG("load from FPU reg S%d value 0x%" PRIx32, - (int)(num - ARMV7M_S0), *value); - break; - - case ARMV7M_PRIMASK: - case ARMV7M_BASEPRI: - case ARMV7M_FAULTMASK: - case ARMV7M_CONTROL: - /* Cortex-M3 packages these four registers as bitfields - * in one Debug Core register. So say r0 and r2 docs; - * it was removed from r1 docs, but still works. - */ - retval = adapter->layout->api->read_reg(adapter->handle, 20, value); - if (retval != ERROR_OK) - return retval; - - switch (num) { - case ARMV7M_PRIMASK: - *value = buf_get_u32((uint8_t *) value, 0, 1); - break; - - case ARMV7M_BASEPRI: - *value = buf_get_u32((uint8_t *) value, 8, 8); - break; - - case ARMV7M_FAULTMASK: - *value = buf_get_u32((uint8_t *) value, 16, 1); - break; - - case ARMV7M_CONTROL: - *value = buf_get_u32((uint8_t *) value, 24, 2); - break; - } - - LOG_DEBUG("load from special reg %i value 0x%" PRIx32 "", - (int)num, *value); - break; - - default: - return ERROR_COMMAND_SYNTAX_ERROR; - } - - return ERROR_OK; -} - -static int adapter_store_core_reg_u32(struct target *target, - uint32_t num, uint32_t value) -{ - int retval; - uint32_t reg; - struct armv7m_common *armv7m = target_to_armv7m(target); - struct hl_interface_s *adapter = target_to_adapter(target); - - LOG_DEBUG("%s", __func__); - - /* NOTE: we "know" here that the register identifiers used - * in the v7m header match the Cortex-M3 Debug Core Register - * Selector values for R0..R15, xPSR, MSP, and PSP. - */ - switch (num) { - case 0 ... 18: - retval = adapter->layout->api->write_reg(adapter->handle, num, value); - - if (retval != ERROR_OK) { - struct reg *r; - - LOG_ERROR("JTAG failure"); - r = armv7m->arm.core_cache->reg_list + num; - r->dirty = r->valid; - return ERROR_JTAG_DEVICE_ERROR; - } - LOG_DEBUG("write core reg %i value 0x%" PRIx32 "", (int)num, value); - break; - - case ARMV7M_FPSCR: - /* Floating-point Status and Registers */ - retval = target_write_u32(target, ARMV7M_SCS_DCRDR, value); - if (retval != ERROR_OK) - return retval; - retval = target_write_u32(target, ARMV7M_SCS_DCRSR, 33 | (1<<16)); - if (retval != ERROR_OK) - return retval; - LOG_DEBUG("write FPSCR value 0x%" PRIx32, value); - break; - - case ARMV7M_S0 ... ARMV7M_S31: - /* Floating-point Status and Registers */ - retval = target_write_u32(target, ARMV7M_SCS_DCRDR, value); - if (retval != ERROR_OK) - return retval; - retval = target_write_u32(target, ARMV7M_SCS_DCRSR, (num-ARMV7M_S0+64) | (1<<16)); - if (retval != ERROR_OK) - return retval; - LOG_DEBUG("write FPU reg S%d value 0x%" PRIx32, - (int)(num - ARMV7M_S0), value); - break; - - case ARMV7M_PRIMASK: - case ARMV7M_BASEPRI: - case ARMV7M_FAULTMASK: - case ARMV7M_CONTROL: - /* Cortex-M3 packages these four registers as bitfields - * in one Debug Core register. So say r0 and r2 docs; - * it was removed from r1 docs, but still works. - */ - - adapter->layout->api->read_reg(adapter->handle, 20, ®); - - switch (num) { - case ARMV7M_PRIMASK: - buf_set_u32((uint8_t *) ®, 0, 1, value); - break; - - case ARMV7M_BASEPRI: - buf_set_u32((uint8_t *) ®, 8, 8, value); - break; - - case ARMV7M_FAULTMASK: - buf_set_u32((uint8_t *) ®, 16, 1, value); - break; - - case ARMV7M_CONTROL: - buf_set_u32((uint8_t *) ®, 24, 2, value); - break; - } - - adapter->layout->api->write_reg(adapter->handle, 20, reg); - - LOG_DEBUG("write special reg %i value 0x%" PRIx32 " ", (int)num, value); - break; - - default: - return ERROR_COMMAND_SYNTAX_ERROR; - } - - return ERROR_OK; -} - -static int adapter_examine_debug_reason(struct target *target) -{ - if ((target->debug_reason != DBG_REASON_DBGRQ) - && (target->debug_reason != DBG_REASON_SINGLESTEP)) { - target->debug_reason = DBG_REASON_BREAKPOINT; - } - - return ERROR_OK; -} - -static int hl_dcc_read(struct hl_interface_s *hl_if, uint8_t *value, uint8_t *ctrl) -{ - uint16_t dcrdr; - int retval = hl_if->layout->api->read_mem(hl_if->handle, - DCB_DCRDR, 1, sizeof(dcrdr), (uint8_t *)&dcrdr); - if (retval == ERROR_OK) { - *ctrl = (uint8_t)dcrdr; - *value = (uint8_t)(dcrdr >> 8); - - LOG_DEBUG("data 0x%x ctrl 0x%x", *value, *ctrl); - - if (dcrdr & 1) { - /* write ack back to software dcc register - * to signify we have read data */ - /* atomically clear just the byte containing the busy bit */ - static const uint8_t zero; - retval = hl_if->layout->api->write_mem(hl_if->handle, DCB_DCRDR, 1, 1, &zero); - } - } - return retval; -} - -static int hl_target_request_data(struct target *target, - uint32_t size, uint8_t *buffer) -{ - struct hl_interface_s *hl_if = target_to_adapter(target); - uint8_t data; - uint8_t ctrl; - uint32_t i; - - for (i = 0; i < (size * 4); i++) { - hl_dcc_read(hl_if, &data, &ctrl); - buffer[i] = data; - } - - return ERROR_OK; -} - -static int hl_handle_target_request(void *priv) -{ - struct target *target = priv; - if (!target_was_examined(target)) - return ERROR_OK; - struct hl_interface_s *hl_if = target_to_adapter(target); - - if (!target->dbg_msg_enabled) - return ERROR_OK; - - if (target->state == TARGET_RUNNING) { - uint8_t data; - uint8_t ctrl; - - hl_dcc_read(hl_if, &data, &ctrl); - - /* check if we have data */ - if (ctrl & (1 << 0)) { - uint32_t request; - - /* we assume target is quick enough */ - request = data; - hl_dcc_read(hl_if, &data, &ctrl); - request |= (data << 8); - hl_dcc_read(hl_if, &data, &ctrl); - request |= (data << 16); - hl_dcc_read(hl_if, &data, &ctrl); - request |= (data << 24); - target_request(target, request); - } - } - - return ERROR_OK; -} - -static int adapter_init_arch_info(struct target *target, - struct cortex_m_common *cortex_m, - struct jtag_tap *tap) -{ - struct armv7m_common *armv7m; - - LOG_DEBUG("%s", __func__); - - armv7m = &cortex_m->armv7m; - armv7m_init_arch_info(target, armv7m); - - armv7m->load_core_reg_u32 = adapter_load_core_reg_u32; - armv7m->store_core_reg_u32 = adapter_store_core_reg_u32; - - armv7m->examine_debug_reason = adapter_examine_debug_reason; - armv7m->stlink = true; - - target_register_timer_callback(hl_handle_target_request, 1, 1, target); - - return ERROR_OK; -} - -static int adapter_init_target(struct command_context *cmd_ctx, - struct target *target) -{ - LOG_DEBUG("%s", __func__); - - armv7m_build_reg_cache(target); - - return ERROR_OK; -} - -static int adapter_target_create(struct target *target, - Jim_Interp *interp) -{ - LOG_DEBUG("%s", __func__); - - struct cortex_m_common *cortex_m = calloc(1, sizeof(struct cortex_m_common)); - - if (!cortex_m) - return ERROR_COMMAND_SYNTAX_ERROR; - - adapter_init_arch_info(target, cortex_m, target->tap); - - return ERROR_OK; -} - -static int adapter_load_context(struct target *target) -{ - struct armv7m_common *armv7m = target_to_armv7m(target); - int num_regs = armv7m->arm.core_cache->num_regs; - - for (int i = 0; i < num_regs; i++) { - - struct reg *r = &armv7m->arm.core_cache->reg_list[i]; - if (!r->valid) - armv7m->arm.read_core_reg(target, r, i, ARM_MODE_ANY); - } - - return ERROR_OK; -} - -static int adapter_debug_entry(struct target *target) -{ - struct hl_interface_s *adapter = target_to_adapter(target); - struct armv7m_common *armv7m = target_to_armv7m(target); - struct arm *arm = &armv7m->arm; - struct reg *r; - uint32_t xPSR; - int retval; - - /* preserve the DCRDR across halts */ - retval = target_read_u32(target, DCB_DCRDR, &target->savedDCRDR); - if (retval != ERROR_OK) - return retval; - - retval = armv7m->examine_debug_reason(target); - if (retval != ERROR_OK) - return retval; - - adapter_load_context(target); - - /* make sure we clear the vector catch bit */ - adapter->layout->api->write_debug_reg(adapter->handle, DCB_DEMCR, TRCENA); - - r = arm->cpsr; - xPSR = buf_get_u32(r->value, 0, 32); - - /* Are we in an exception handler */ - if (xPSR & 0x1FF) { - armv7m->exception_number = (xPSR & 0x1FF); - - arm->core_mode = ARM_MODE_HANDLER; - arm->map = armv7m_msp_reg_map; - } else { - unsigned control = buf_get_u32(arm->core_cache - ->reg_list[ARMV7M_CONTROL].value, 0, 2); - - /* is this thread privileged? */ - arm->core_mode = control & 1 - ? ARM_MODE_USER_THREAD - : ARM_MODE_THREAD; - - /* which stack is it using? */ - if (control & 2) - arm->map = armv7m_psp_reg_map; - else - arm->map = armv7m_msp_reg_map; - - armv7m->exception_number = 0; - } - - LOG_DEBUG("entered debug state in core mode: %s at PC 0x%08" PRIx32 ", target->state: %s", - arm_mode_name(arm->core_mode), - buf_get_u32(arm->pc->value, 0, 32), - target_state_name(target)); - - return retval; -} - -static int adapter_poll(struct target *target) -{ - enum target_state state; - struct hl_interface_s *adapter = target_to_adapter(target); - struct armv7m_common *armv7m = target_to_armv7m(target); - enum target_state prev_target_state = target->state; - - state = adapter->layout->api->state(adapter->handle); - - if (state == TARGET_UNKNOWN) { - LOG_ERROR("jtag status contains invalid mode value - communication failure"); - return ERROR_TARGET_FAILURE; - } - - if (prev_target_state == state) - return ERROR_OK; - - target->state = state; - - if (state == TARGET_HALTED) { - - int retval = adapter_debug_entry(target); - if (retval != ERROR_OK) - return retval; - - if (prev_target_state == TARGET_DEBUG_RUNNING) { - target_call_event_callbacks(target, TARGET_EVENT_DEBUG_HALTED); - } else { - if (arm_semihosting(target, &retval) != 0) - return retval; - - target_call_event_callbacks(target, TARGET_EVENT_HALTED); - } - - LOG_DEBUG("halted: PC: 0x%08" PRIx32, buf_get_u32(armv7m->arm.pc->value, 0, 32)); - } - - return ERROR_OK; -} - -static int adapter_assert_reset(struct target *target) -{ - int res = ERROR_OK; - struct hl_interface_s *adapter = target_to_adapter(target); - struct armv7m_common *armv7m = target_to_armv7m(target); - bool use_srst_fallback = true; - - LOG_DEBUG("%s", __func__); - - enum reset_types jtag_reset_config = jtag_get_reset_config(); - - bool srst_asserted = false; - - if ((jtag_reset_config & RESET_HAS_SRST) && - (jtag_reset_config & RESET_SRST_NO_GATING)) { - jtag_add_reset(0, 1); - res = adapter->layout->api->assert_srst(adapter->handle, 0); - srst_asserted = true; - } - - adapter->layout->api->write_debug_reg(adapter->handle, DCB_DHCSR, DBGKEY|C_DEBUGEN); - - /* only set vector catch if halt is requested */ - if (target->reset_halt) - adapter->layout->api->write_debug_reg(adapter->handle, DCB_DEMCR, TRCENA|VC_CORERESET); - else - adapter->layout->api->write_debug_reg(adapter->handle, DCB_DEMCR, TRCENA); - - if (jtag_reset_config & RESET_HAS_SRST) { - if (!srst_asserted) { - jtag_add_reset(0, 1); - res = adapter->layout->api->assert_srst(adapter->handle, 0); - } - if (res == ERROR_COMMAND_NOTFOUND) - LOG_ERROR("Hardware srst not supported, falling back to software reset"); - else if (res == ERROR_OK) { - /* hardware srst supported */ - use_srst_fallback = false; - } - } - - if (use_srst_fallback) { - /* stlink v1 api does not support hardware srst, so we use a software reset fallback */ - adapter->layout->api->write_debug_reg(adapter->handle, NVIC_AIRCR, AIRCR_VECTKEY | AIRCR_SYSRESETREQ); - } - - res = adapter->layout->api->reset(adapter->handle); - - if (res != ERROR_OK) - return res; - - /* registers are now invalid */ - register_cache_invalidate(armv7m->arm.core_cache); - - if (target->reset_halt) { - target->state = TARGET_RESET; - target->debug_reason = DBG_REASON_DBGRQ; - } else { - target->state = TARGET_HALTED; - } - - return ERROR_OK; -} - -static int adapter_deassert_reset(struct target *target) -{ - struct hl_interface_s *adapter = target_to_adapter(target); - - enum reset_types jtag_reset_config = jtag_get_reset_config(); - - LOG_DEBUG("%s", __func__); - - if (jtag_reset_config & RESET_HAS_SRST) - adapter->layout->api->assert_srst(adapter->handle, 1); - - /* virtual deassert reset, we need it for the internal - * jtag state machine - */ - jtag_add_reset(0, 0); - - target->savedDCRDR = 0; /* clear both DCC busy bits on initial resume */ - - return target->reset_halt ? ERROR_OK : target_resume(target, 1, 0, 0, 0); -} - -static int adapter_halt(struct target *target) -{ - int res; - struct hl_interface_s *adapter = target_to_adapter(target); - - LOG_DEBUG("%s", __func__); - - if (target->state == TARGET_HALTED) { - LOG_DEBUG("target was already halted"); - return ERROR_OK; - } - - if (target->state == TARGET_UNKNOWN) - LOG_WARNING("target was in unknown state when halt was requested"); - - res = adapter->layout->api->halt(adapter->handle); - - if (res != ERROR_OK) - return res; - - target->debug_reason = DBG_REASON_DBGRQ; - - return ERROR_OK; -} - -static int adapter_resume(struct target *target, int current, - uint32_t address, int handle_breakpoints, - int debug_execution) -{ - int res; - struct hl_interface_s *adapter = target_to_adapter(target); - struct armv7m_common *armv7m = target_to_armv7m(target); - uint32_t resume_pc; - struct breakpoint *breakpoint = NULL; - struct reg *pc; - - LOG_DEBUG("%s %d 0x%08" PRIx32 " %d %d", __func__, current, address, - handle_breakpoints, debug_execution); - - if (target->state != TARGET_HALTED) { - LOG_WARNING("target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - if (!debug_execution) { - target_free_all_working_areas(target); - cortex_m_enable_breakpoints(target); - cortex_m_enable_watchpoints(target); - } - - pc = armv7m->arm.pc; - if (!current) { - buf_set_u32(pc->value, 0, 32, address); - pc->dirty = true; - pc->valid = true; - } - - if (!breakpoint_find(target, buf_get_u32(pc->value, 0, 32)) - && !debug_execution) { - armv7m_maybe_skip_bkpt_inst(target, NULL); - } - - resume_pc = buf_get_u32(pc->value, 0, 32); - - /* write any user vector flags */ - res = target_write_u32(target, DCB_DEMCR, TRCENA | armv7m->demcr); - if (res != ERROR_OK) - return res; - - armv7m_restore_context(target); - - /* restore savedDCRDR */ - res = target_write_u32(target, DCB_DCRDR, target->savedDCRDR); - if (res != ERROR_OK) - return res; - - /* registers are now invalid */ - register_cache_invalidate(armv7m->arm.core_cache); - - /* the front-end may request us not to handle breakpoints */ - if (handle_breakpoints) { - /* 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 ")", - breakpoint->address, - breakpoint->unique_id); - cortex_m_unset_breakpoint(target, breakpoint); - - res = adapter->layout->api->step(adapter->handle); - - if (res != ERROR_OK) - return res; - - cortex_m_set_breakpoint(target, breakpoint); - } - } - - res = adapter->layout->api->run(adapter->handle); - - if (res != ERROR_OK) - return res; - - target->debug_reason = DBG_REASON_NOTHALTED; - - if (!debug_execution) { - target->state = TARGET_RUNNING; - target_call_event_callbacks(target, TARGET_EVENT_RESUMED); - } else { - target->state = TARGET_DEBUG_RUNNING; - target_call_event_callbacks(target, TARGET_EVENT_DEBUG_RESUMED); - } - - return ERROR_OK; -} - -static int adapter_step(struct target *target, int current, - uint32_t address, int handle_breakpoints) -{ - int res; - struct hl_interface_s *adapter = target_to_adapter(target); - struct armv7m_common *armv7m = target_to_armv7m(target); - struct breakpoint *breakpoint = NULL; - struct reg *pc = armv7m->arm.pc; - bool bkpt_inst_found = false; - - LOG_DEBUG("%s", __func__); - - if (target->state != TARGET_HALTED) { - LOG_WARNING("target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - if (!current) { - buf_set_u32(pc->value, 0, 32, address); - pc->dirty = true; - pc->valid = true; - } - - uint32_t pc_value = buf_get_u32(pc->value, 0, 32); - - /* the front-end may request us not to handle breakpoints */ - if (handle_breakpoints) { - breakpoint = breakpoint_find(target, pc_value); - if (breakpoint) - cortex_m_unset_breakpoint(target, breakpoint); - } - - armv7m_maybe_skip_bkpt_inst(target, &bkpt_inst_found); - - target->debug_reason = DBG_REASON_SINGLESTEP; - - armv7m_restore_context(target); - - /* restore savedDCRDR */ - res = target_write_u32(target, DCB_DCRDR, target->savedDCRDR); - if (res != ERROR_OK) - return res; - - target_call_event_callbacks(target, TARGET_EVENT_RESUMED); - - res = adapter->layout->api->step(adapter->handle); - - if (res != ERROR_OK) - return res; - - /* registers are now invalid */ - register_cache_invalidate(armv7m->arm.core_cache); - - if (breakpoint) - cortex_m_set_breakpoint(target, breakpoint); - - adapter_debug_entry(target); - target_call_event_callbacks(target, TARGET_EVENT_HALTED); - - LOG_INFO("halted: PC: 0x%08" PRIx32, buf_get_u32(armv7m->arm.pc->value, 0, 32)); - - return ERROR_OK; -} - -static int adapter_read_memory(struct target *target, uint32_t address, - uint32_t size, uint32_t count, - uint8_t *buffer) -{ - struct hl_interface_s *adapter = target_to_adapter(target); - - if (!count || !buffer) - return ERROR_COMMAND_SYNTAX_ERROR; - - LOG_DEBUG("%s 0x%08" PRIx32 " %" 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, - uint32_t size, uint32_t count, - const uint8_t *buffer) -{ - struct hl_interface_s *adapter = target_to_adapter(target); - - if (!count || !buffer) - return ERROR_COMMAND_SYNTAX_ERROR; - - LOG_DEBUG("%s 0x%08" PRIx32 " %" PRIu32 " %" PRIu32, __func__, address, size, count); - - return adapter->layout->api->write_mem(adapter->handle, address, size, count, buffer); -} - -static const struct command_registration adapter_command_handlers[] = { - { - .chain = arm_command_handlers, - }, - { - .chain = armv7m_trace_command_handlers, - }, - COMMAND_REGISTRATION_DONE -}; - -struct target_type hla_target = { - .name = "hla_target", - .deprecated_name = "stm32_stlink", - - .init_target = adapter_init_target, - .deinit_target = cortex_m_deinit_target, - .target_create = adapter_target_create, - .examine = cortex_m_examine, - .commands = adapter_command_handlers, - - .poll = adapter_poll, - .arch_state = armv7m_arch_state, - - .target_request_data = hl_target_request_data, - .assert_reset = adapter_assert_reset, - .deassert_reset = adapter_deassert_reset, - - .halt = adapter_halt, - .resume = adapter_resume, - .step = adapter_step, - - .get_gdb_reg_list = armv7m_get_gdb_reg_list, - - .read_memory = adapter_read_memory, - .write_memory = adapter_write_memory, - .checksum_memory = armv7m_checksum_memory, - .blank_check_memory = armv7m_blank_check_memory, - - .run_algorithm = armv7m_run_algorithm, - .start_algorithm = armv7m_start_algorithm, - .wait_algorithm = armv7m_wait_algorithm, - - .add_breakpoint = cortex_m_add_breakpoint, - .remove_breakpoint = cortex_m_remove_breakpoint, - .add_watchpoint = cortex_m_add_watchpoint, - .remove_watchpoint = cortex_m_remove_watchpoint, -}; diff --git a/src/target/image.c b/src/target/image.c deleted file mode 100644 index 0612ea7e5..000000000 --- a/src/target/image.c +++ /dev/null @@ -1,1044 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * Copyright (C) 2007,2008 Øyvind Harboe * - * oyvind.harboe@zylin.com * - * * - * Copyright (C) 2008 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * Copyright (C) 2009 by Franck Hereson * - * franck.hereson@secad.fr * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 -#include "config.h" -#endif - -#include "image.h" -#include "target.h" -#include - -/* convert ELF header field to host endianness */ -#define field16(elf, field) \ - ((elf->endianness == ELFDATA2LSB) ? \ - le_to_h_u16((uint8_t *)&field) : be_to_h_u16((uint8_t *)&field)) - -#define field32(elf, field) \ - ((elf->endianness == ELFDATA2LSB) ? \ - le_to_h_u32((uint8_t *)&field) : be_to_h_u32((uint8_t *)&field)) - -static int autodetect_image_type(struct image *image, const char *url) -{ - int retval; - struct fileio *fileio; - size_t read_bytes; - uint8_t buffer[9]; - - /* read the first 4 bytes of image */ - retval = fileio_open(&fileio, url, FILEIO_READ, FILEIO_BINARY); - if (retval != ERROR_OK) - return retval; - retval = fileio_read(fileio, 9, buffer, &read_bytes); - - if (retval == ERROR_OK) { - if (read_bytes != 9) - retval = ERROR_FILEIO_OPERATION_FAILED; - } - fileio_close(fileio); - - if (retval != ERROR_OK) - return retval; - - /* check header against known signatures */ - if (strncmp((char *)buffer, ELFMAG, SELFMAG) == 0) { - LOG_DEBUG("ELF image detected."); - image->type = IMAGE_ELF; - } else if ((buffer[0] == ':') /* record start byte */ - && (isxdigit(buffer[1])) - && (isxdigit(buffer[2])) - && (isxdigit(buffer[3])) - && (isxdigit(buffer[4])) - && (isxdigit(buffer[5])) - && (isxdigit(buffer[6])) - && (buffer[7] == '0') /* record type : 00 -> 05 */ - && (buffer[8] >= '0') && (buffer[8] < '6')) { - LOG_DEBUG("IHEX image detected."); - image->type = IMAGE_IHEX; - } else if ((buffer[0] == 'S') /* record start byte */ - && (isxdigit(buffer[1])) - && (isxdigit(buffer[2])) - && (isxdigit(buffer[3])) - && (buffer[1] >= '0') && (buffer[1] < '9')) { - LOG_DEBUG("S19 image detected."); - image->type = IMAGE_SRECORD; - } else - image->type = IMAGE_BINARY; - - return ERROR_OK; -} - -static int identify_image_type(struct image *image, const char *type_string, const char *url) -{ - if (type_string) { - if (!strcmp(type_string, "bin")) - image->type = IMAGE_BINARY; - else if (!strcmp(type_string, "ihex")) - image->type = IMAGE_IHEX; - else if (!strcmp(type_string, "elf")) - image->type = IMAGE_ELF; - else if (!strcmp(type_string, "mem")) - image->type = IMAGE_MEMORY; - else if (!strcmp(type_string, "s19")) - image->type = IMAGE_SRECORD; - else if (!strcmp(type_string, "build")) - image->type = IMAGE_BUILDER; - else - return ERROR_IMAGE_TYPE_UNKNOWN; - } else - return autodetect_image_type(image, url); - - return ERROR_OK; -} - -static int image_ihex_buffer_complete_inner(struct image *image, - char *lpszLine, - struct imagesection *section) -{ - struct image_ihex *ihex = image->type_private; - struct fileio *fileio = ihex->fileio; - uint32_t full_address = 0x0; - uint32_t cooked_bytes; - int i; - - /* we can't determine the number of sections that we'll have to create ahead of time, - * so we locally hold them until parsing is finished */ - - size_t filesize; - int retval; - retval = fileio_size(fileio, &filesize); - if (retval != ERROR_OK) - return retval; - - ihex->buffer = malloc(filesize >> 1); - cooked_bytes = 0x0; - image->num_sections = 0; - section[image->num_sections].private = &ihex->buffer[cooked_bytes]; - section[image->num_sections].base_address = 0x0; - section[image->num_sections].size = 0x0; - section[image->num_sections].flags = 0; - - while (fileio_fgets(fileio, 1023, lpszLine) == ERROR_OK) { - uint32_t count; - uint32_t address; - uint32_t record_type; - uint32_t checksum; - uint8_t cal_checksum = 0; - size_t bytes_read = 0; - - if (lpszLine[0] == '#') - continue; - - if (sscanf(&lpszLine[bytes_read], ":%2" SCNx32 "%4" SCNx32 "%2" SCNx32, &count, - &address, &record_type) != 3) - return ERROR_IMAGE_FORMAT_ERROR; - bytes_read += 9; - - cal_checksum += (uint8_t)count; - cal_checksum += (uint8_t)(address >> 8); - cal_checksum += (uint8_t)address; - cal_checksum += (uint8_t)record_type; - - if (record_type == 0) { /* Data Record */ - if ((full_address & 0xffff) != address) { - /* we encountered a nonconsecutive location, create a new section, - * unless the current section has zero size, in which case this specifies - * the current section's base address - */ - if (section[image->num_sections].size != 0) { - image->num_sections++; - if (image->num_sections >= IMAGE_MAX_SECTIONS) { - /* too many sections */ - LOG_ERROR("Too many sections found in IHEX file"); - return ERROR_IMAGE_FORMAT_ERROR; - } - section[image->num_sections].size = 0x0; - section[image->num_sections].flags = 0; - section[image->num_sections].private = - &ihex->buffer[cooked_bytes]; - } - section[image->num_sections].base_address = - (full_address & 0xffff0000) | address; - full_address = (full_address & 0xffff0000) | address; - } - - while (count-- > 0) { - unsigned value; - sscanf(&lpszLine[bytes_read], "%2x", &value); - ihex->buffer[cooked_bytes] = (uint8_t)value; - cal_checksum += (uint8_t)ihex->buffer[cooked_bytes]; - bytes_read += 2; - cooked_bytes += 1; - section[image->num_sections].size += 1; - full_address++; - } - } else if (record_type == 1) { /* End of File Record */ - /* finish the current section */ - image->num_sections++; - - /* copy section information */ - image->sections = malloc(sizeof(struct imagesection) * image->num_sections); - for (i = 0; i < image->num_sections; i++) { - image->sections[i].private = section[i].private; - image->sections[i].base_address = section[i].base_address; - image->sections[i].size = section[i].size; - image->sections[i].flags = section[i].flags; - } - - return ERROR_OK; - } else if (record_type == 2) { /* Linear Address Record */ - uint16_t upper_address; - - sscanf(&lpszLine[bytes_read], "%4hx", &upper_address); - cal_checksum += (uint8_t)(upper_address >> 8); - cal_checksum += (uint8_t)upper_address; - bytes_read += 4; - - if ((full_address >> 4) != upper_address) { - /* we encountered a nonconsecutive location, create a new section, - * unless the current section has zero size, in which case this specifies - * the current section's base address - */ - if (section[image->num_sections].size != 0) { - image->num_sections++; - if (image->num_sections >= IMAGE_MAX_SECTIONS) { - /* too many sections */ - LOG_ERROR("Too many sections found in IHEX file"); - return ERROR_IMAGE_FORMAT_ERROR; - } - section[image->num_sections].size = 0x0; - section[image->num_sections].flags = 0; - section[image->num_sections].private = - &ihex->buffer[cooked_bytes]; - } - section[image->num_sections].base_address = - (full_address & 0xffff) | (upper_address << 4); - full_address = (full_address & 0xffff) | (upper_address << 4); - } - } else if (record_type == 3) { /* Start Segment Address Record */ - uint32_t dummy; - - /* "Start Segment Address Record" will not be supported - * but we must consume it, and do not create an error. */ - while (count-- > 0) { - sscanf(&lpszLine[bytes_read], "%2" SCNx32, &dummy); - cal_checksum += (uint8_t)dummy; - bytes_read += 2; - } - } else if (record_type == 4) { /* Extended Linear Address Record */ - uint16_t upper_address; - - sscanf(&lpszLine[bytes_read], "%4hx", &upper_address); - cal_checksum += (uint8_t)(upper_address >> 8); - cal_checksum += (uint8_t)upper_address; - bytes_read += 4; - - if ((full_address >> 16) != upper_address) { - /* we encountered a nonconsecutive location, create a new section, - * unless the current section has zero size, in which case this specifies - * the current section's base address - */ - if (section[image->num_sections].size != 0) { - image->num_sections++; - if (image->num_sections >= IMAGE_MAX_SECTIONS) { - /* too many sections */ - LOG_ERROR("Too many sections found in IHEX file"); - return ERROR_IMAGE_FORMAT_ERROR; - } - section[image->num_sections].size = 0x0; - section[image->num_sections].flags = 0; - section[image->num_sections].private = - &ihex->buffer[cooked_bytes]; - } - section[image->num_sections].base_address = - (full_address & 0xffff) | (upper_address << 16); - full_address = (full_address & 0xffff) | (upper_address << 16); - } - } else if (record_type == 5) { /* Start Linear Address Record */ - uint32_t start_address; - - sscanf(&lpszLine[bytes_read], "%8" SCNx32, &start_address); - cal_checksum += (uint8_t)(start_address >> 24); - cal_checksum += (uint8_t)(start_address >> 16); - cal_checksum += (uint8_t)(start_address >> 8); - cal_checksum += (uint8_t)start_address; - bytes_read += 8; - - image->start_address_set = 1; - image->start_address = be_to_h_u32((uint8_t *)&start_address); - } else { - LOG_ERROR("unhandled IHEX record type: %i", (int)record_type); - return ERROR_IMAGE_FORMAT_ERROR; - } - - sscanf(&lpszLine[bytes_read], "%2" SCNx32, &checksum); - - if ((uint8_t)checksum != (uint8_t)(~cal_checksum + 1)) { - /* checksum failed */ - LOG_ERROR("incorrect record checksum found in IHEX file"); - return ERROR_IMAGE_CHECKSUM; - } - } - - LOG_ERROR("premature end of IHEX file, no end-of-file record found"); - return ERROR_IMAGE_FORMAT_ERROR; -} - -/** - * Allocate memory dynamically instead of on the stack. This - * is important w/embedded hosts. - */ -static int image_ihex_buffer_complete(struct image *image) -{ - char *lpszLine = malloc(1023); - if (lpszLine == NULL) { - LOG_ERROR("Out of memory"); - return ERROR_FAIL; - } - struct imagesection *section = malloc(sizeof(struct imagesection) * IMAGE_MAX_SECTIONS); - if (section == NULL) { - free(lpszLine); - LOG_ERROR("Out of memory"); - return ERROR_FAIL; - } - int retval; - - retval = image_ihex_buffer_complete_inner(image, lpszLine, section); - - free(section); - free(lpszLine); - - return retval; -} - -static int image_elf_read_headers(struct image *image) -{ - struct image_elf *elf = image->type_private; - size_t read_bytes; - uint32_t i, j; - int retval; - uint32_t nload, load_to_vaddr = 0; - - elf->header = malloc(sizeof(Elf32_Ehdr)); - - if (elf->header == NULL) { - LOG_ERROR("insufficient memory to perform operation "); - return ERROR_FILEIO_OPERATION_FAILED; - } - - 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; - } - if (read_bytes != sizeof(Elf32_Ehdr)) { - LOG_ERROR("cannot read ELF file header, only partially read"); - return ERROR_FILEIO_OPERATION_FAILED; - } - - if (strncmp((char *)elf->header->e_ident, ELFMAG, SELFMAG) != 0) { - LOG_ERROR("invalid ELF file, bad magic number"); - return ERROR_IMAGE_FORMAT_ERROR; - } - if (elf->header->e_ident[EI_CLASS] != ELFCLASS32) { - LOG_ERROR("invalid ELF file, only 32bits files are supported"); - return ERROR_IMAGE_FORMAT_ERROR; - } - - elf->endianness = elf->header->e_ident[EI_DATA]; - if ((elf->endianness != ELFDATA2LSB) - && (elf->endianness != ELFDATA2MSB)) { - LOG_ERROR("invalid ELF file, unknown endianness setting"); - return ERROR_IMAGE_FORMAT_ERROR; - } - - elf->segment_count = field16(elf, elf->header->e_phnum); - if (elf->segment_count == 0) { - LOG_ERROR("invalid ELF file, no program headers"); - return ERROR_IMAGE_FORMAT_ERROR; - } - - 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; - } - - elf->segments = malloc(elf->segment_count*sizeof(Elf32_Phdr)); - if (elf->segments == NULL) { - LOG_ERROR("insufficient memory to perform operation "); - return ERROR_FILEIO_OPERATION_FAILED; - } - - 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"); - return retval; - } - if (read_bytes != elf->segment_count*sizeof(Elf32_Phdr)) { - LOG_ERROR("cannot read ELF segment headers, only partially read"); - return ERROR_FILEIO_OPERATION_FAILED; - } - - /* count useful segments (loadable), ignore BSS section */ - image->num_sections = 0; - for (i = 0; i < elf->segment_count; i++) - if ((field32(elf, - elf->segments[i].p_type) == PT_LOAD) && - (field32(elf, elf->segments[i].p_filesz) != 0)) - image->num_sections++; - - assert(image->num_sections > 0); - - /** - * some ELF linkers produce binaries with *all* the program header - * p_paddr fields zero (there can be however one loadable segment - * that has valid physical address 0x0). - * If we have such a binary with more than - * one PT_LOAD header, then use p_vaddr instead of p_paddr - * (ARM ELF standard demands p_paddr = 0 anyway, and BFD - * library uses this approach to workaround zero-initialized p_paddrs - * when obtaining lma - look at elf.c of BDF) - */ - for (nload = 0, i = 0; i < elf->segment_count; i++) - if (elf->segments[i].p_paddr != 0) - break; - else if ((field32(elf, - elf->segments[i].p_type) == PT_LOAD) && - (field32(elf, elf->segments[i].p_memsz) != 0)) - ++nload; - - if (i >= elf->segment_count && nload > 1) - load_to_vaddr = 1; - - /* alloc and fill sections array with loadable segments */ - image->sections = malloc(image->num_sections * sizeof(struct imagesection)); - for (i = 0, j = 0; i < elf->segment_count; i++) { - if ((field32(elf, - elf->segments[i].p_type) == PT_LOAD) && - (field32(elf, elf->segments[i].p_filesz) != 0)) { - image->sections[j].size = field32(elf, elf->segments[i].p_filesz); - if (load_to_vaddr) - image->sections[j].base_address = field32(elf, - elf->segments[i].p_vaddr); - else - image->sections[j].base_address = field32(elf, - elf->segments[i].p_paddr); - image->sections[j].private = &elf->segments[i]; - image->sections[j].flags = field32(elf, elf->segments[i].p_flags); - j++; - } - } - - image->start_address_set = 1; - image->start_address = field32(elf, elf->header->e_entry); - - return ERROR_OK; -} - -static int image_elf_read_section(struct image *image, - int section, - uint32_t offset, - uint32_t size, - uint8_t *buffer, - size_t *size_read) -{ - struct image_elf *elf = image->type_private; - Elf32_Phdr *segment = (Elf32_Phdr *)image->sections[section].private; - size_t read_size, really_read; - int retval; - - *size_read = 0; - - LOG_DEBUG("load segment %d at 0x%" PRIx32 " (sz = 0x%" PRIx32 ")", section, offset, size); - - /* read initialized data in current segment if any */ - if (offset < field32(elf, segment->p_filesz)) { - /* maximal size present in file for the current segment */ - read_size = MIN(size, field32(elf, segment->p_filesz) - offset); - 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); - 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); - if (retval != ERROR_OK) { - LOG_ERROR("cannot read ELF segment content, read failed"); - return retval; - } - size -= read_size; - *size_read += read_size; - /* need more data ? */ - if (!size) - return ERROR_OK; - } - - return ERROR_OK; -} - -static int image_mot_buffer_complete_inner(struct image *image, - char *lpszLine, - struct imagesection *section) -{ - struct image_mot *mot = image->type_private; - struct fileio *fileio = mot->fileio; - uint32_t full_address = 0x0; - uint32_t cooked_bytes; - int i; - - /* we can't determine the number of sections that we'll have to create ahead of time, - * so we locally hold them until parsing is finished */ - - int retval; - size_t filesize; - retval = fileio_size(fileio, &filesize); - if (retval != ERROR_OK) - return retval; - - mot->buffer = malloc(filesize >> 1); - cooked_bytes = 0x0; - image->num_sections = 0; - section[image->num_sections].private = &mot->buffer[cooked_bytes]; - section[image->num_sections].base_address = 0x0; - section[image->num_sections].size = 0x0; - section[image->num_sections].flags = 0; - - while (fileio_fgets(fileio, 1023, lpszLine) == ERROR_OK) { - uint32_t count; - uint32_t address; - uint32_t record_type; - uint32_t checksum; - uint8_t cal_checksum = 0; - uint32_t bytes_read = 0; - - /* get record type and record length */ - if (sscanf(&lpszLine[bytes_read], "S%1" SCNx32 "%2" SCNx32, &record_type, - &count) != 2) - return ERROR_IMAGE_FORMAT_ERROR; - - bytes_read += 4; - cal_checksum += (uint8_t)count; - - /* skip checksum byte */ - count -= 1; - - if (record_type == 0) { - /* S0 - starting record (optional) */ - int iValue; - - while (count-- > 0) { - sscanf(&lpszLine[bytes_read], "%2x", &iValue); - cal_checksum += (uint8_t)iValue; - bytes_read += 2; - } - } else if (record_type >= 1 && record_type <= 3) { - switch (record_type) { - case 1: - /* S1 - 16 bit address data record */ - sscanf(&lpszLine[bytes_read], "%4" SCNx32, &address); - cal_checksum += (uint8_t)(address >> 8); - cal_checksum += (uint8_t)address; - bytes_read += 4; - count -= 2; - break; - - case 2: - /* S2 - 24 bit address data record */ - sscanf(&lpszLine[bytes_read], "%6" SCNx32, &address); - cal_checksum += (uint8_t)(address >> 16); - cal_checksum += (uint8_t)(address >> 8); - cal_checksum += (uint8_t)address; - bytes_read += 6; - count -= 3; - break; - - case 3: - /* S3 - 32 bit address data record */ - sscanf(&lpszLine[bytes_read], "%8" SCNx32, &address); - cal_checksum += (uint8_t)(address >> 24); - cal_checksum += (uint8_t)(address >> 16); - cal_checksum += (uint8_t)(address >> 8); - cal_checksum += (uint8_t)address; - bytes_read += 8; - count -= 4; - break; - - } - - if (full_address != address) { - /* we encountered a nonconsecutive location, create a new section, - * unless the current section has zero size, in which case this specifies - * the current section's base address - */ - if (section[image->num_sections].size != 0) { - image->num_sections++; - section[image->num_sections].size = 0x0; - section[image->num_sections].flags = 0; - section[image->num_sections].private = - &mot->buffer[cooked_bytes]; - } - section[image->num_sections].base_address = address; - full_address = address; - } - - while (count-- > 0) { - unsigned value; - sscanf(&lpszLine[bytes_read], "%2x", &value); - mot->buffer[cooked_bytes] = (uint8_t)value; - cal_checksum += (uint8_t)mot->buffer[cooked_bytes]; - bytes_read += 2; - cooked_bytes += 1; - section[image->num_sections].size += 1; - full_address++; - } - } else if (record_type == 5) { - /* S5 is the data count record, we ignore it */ - uint32_t dummy; - - while (count-- > 0) { - sscanf(&lpszLine[bytes_read], "%2" SCNx32, &dummy); - cal_checksum += (uint8_t)dummy; - bytes_read += 2; - } - } else if (record_type >= 7 && record_type <= 9) { - /* S7, S8, S9 - ending records for 32, 24 and 16bit */ - image->num_sections++; - - /* copy section information */ - image->sections = malloc(sizeof(struct imagesection) * image->num_sections); - for (i = 0; i < image->num_sections; i++) { - image->sections[i].private = section[i].private; - image->sections[i].base_address = section[i].base_address; - image->sections[i].size = section[i].size; - image->sections[i].flags = section[i].flags; - } - - return ERROR_OK; - } else { - LOG_ERROR("unhandled S19 record type: %i", (int)(record_type)); - return ERROR_IMAGE_FORMAT_ERROR; - } - - /* account for checksum, will always be 0xFF */ - sscanf(&lpszLine[bytes_read], "%2" SCNx32, &checksum); - cal_checksum += (uint8_t)checksum; - - if (cal_checksum != 0xFF) { - /* checksum failed */ - LOG_ERROR("incorrect record checksum found in S19 file"); - return ERROR_IMAGE_CHECKSUM; - } - } - - LOG_ERROR("premature end of S19 file, no end-of-file record found"); - return ERROR_IMAGE_FORMAT_ERROR; -} - -/** - * Allocate memory dynamically instead of on the stack. This - * is important w/embedded hosts. - */ -static int image_mot_buffer_complete(struct image *image) -{ - char *lpszLine = malloc(1023); - if (lpszLine == NULL) { - LOG_ERROR("Out of memory"); - return ERROR_FAIL; - } - struct imagesection *section = malloc(sizeof(struct imagesection) * IMAGE_MAX_SECTIONS); - if (section == NULL) { - free(lpszLine); - LOG_ERROR("Out of memory"); - return ERROR_FAIL; - } - int retval; - - retval = image_mot_buffer_complete_inner(image, lpszLine, section); - - free(section); - free(lpszLine); - - return retval; -} - -int image_open(struct image *image, const char *url, const char *type_string) -{ - int retval = ERROR_OK; - - retval = identify_image_type(image, type_string, url); - if (retval != ERROR_OK) - return retval; - - if (image->type == IMAGE_BINARY) { - struct image_binary *image_binary; - - image_binary = image->type_private = malloc(sizeof(struct image_binary)); - - retval = fileio_open(&image_binary->fileio, url, FILEIO_READ, FILEIO_BINARY); - if (retval != ERROR_OK) - return retval; - size_t filesize; - retval = fileio_size(image_binary->fileio, &filesize); - if (retval != ERROR_OK) { - fileio_close(image_binary->fileio); - return retval; - } - - image->num_sections = 1; - image->sections = malloc(sizeof(struct imagesection)); - image->sections[0].base_address = 0x0; - image->sections[0].size = filesize; - image->sections[0].flags = 0; - } else if (image->type == IMAGE_IHEX) { - struct image_ihex *image_ihex; - - image_ihex = image->type_private = malloc(sizeof(struct image_ihex)); - - retval = fileio_open(&image_ihex->fileio, url, FILEIO_READ, FILEIO_TEXT); - if (retval != ERROR_OK) - return retval; - - 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); - return retval; - } - } else if (image->type == IMAGE_ELF) { - struct image_elf *image_elf; - - image_elf = image->type_private = malloc(sizeof(struct image_elf)); - - retval = fileio_open(&image_elf->fileio, url, FILEIO_READ, FILEIO_BINARY); - if (retval != ERROR_OK) - return retval; - - retval = image_elf_read_headers(image); - if (retval != ERROR_OK) { - fileio_close(image_elf->fileio); - return retval; - } - } else if (image->type == IMAGE_MEMORY) { - struct target *target = get_target(url); - - if (target == NULL) { - LOG_ERROR("target '%s' not defined", url); - return ERROR_FAIL; - } - - struct image_memory *image_memory; - - image->num_sections = 1; - image->sections = malloc(sizeof(struct imagesection)); - image->sections[0].base_address = 0x0; - image->sections[0].size = 0xffffffff; - image->sections[0].flags = 0; - - image_memory = image->type_private = malloc(sizeof(struct image_memory)); - - image_memory->target = target; - image_memory->cache = NULL; - image_memory->cache_address = 0x0; - } else if (image->type == IMAGE_SRECORD) { - struct image_mot *image_mot; - - image_mot = image->type_private = malloc(sizeof(struct image_mot)); - - retval = fileio_open(&image_mot->fileio, url, FILEIO_READ, FILEIO_TEXT); - if (retval != ERROR_OK) - return retval; - - 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); - return retval; - } - } else if (image->type == IMAGE_BUILDER) { - image->num_sections = 0; - image->base_address_set = 0; - image->sections = NULL; - image->type_private = NULL; - } - - if (image->base_address_set) { - /* relocate */ - int section; - for (section = 0; section < image->num_sections; section++) - image->sections[section].base_address += image->base_address; - /* we're done relocating. The two statements below are mainly - * for documenation purposes: stop anyone from empirically - * thinking they should use these values henceforth. */ - image->base_address = 0; - image->base_address_set = 0; - } - - return retval; -}; - -int image_read_section(struct image *image, - int section, - uint32_t offset, - uint32_t size, - uint8_t *buffer, - size_t *size_read) -{ - int retval; - - /* don't read past the end of a section */ - if (offset + size > image->sections[section].size) { - LOG_DEBUG( - "read past end of section: 0x%8.8" PRIx32 " + 0x%8.8" PRIx32 " > 0x%8.8" PRIx32 "", - offset, - size, - image->sections[section].size); - return ERROR_COMMAND_SYNTAX_ERROR; - } - - if (image->type == IMAGE_BINARY) { - struct image_binary *image_binary = image->type_private; - - /* only one section in a plain binary */ - if (section != 0) - return ERROR_COMMAND_SYNTAX_ERROR; - - /* seek to 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); - if (retval != ERROR_OK) - return retval; - } else if (image->type == IMAGE_IHEX) { - memcpy(buffer, (uint8_t *)image->sections[section].private + offset, size); - *size_read = size; - - return ERROR_OK; - } else if (image->type == IMAGE_ELF) - return image_elf_read_section(image, section, offset, size, buffer, size_read); - else if (image->type == IMAGE_MEMORY) { - struct image_memory *image_memory = image->type_private; - uint32_t address = image->sections[section].base_address + offset; - - *size_read = 0; - - while ((size - *size_read) > 0) { - uint32_t size_in_cache; - - if (!image_memory->cache - || (address < image_memory->cache_address) - || (address >= - (image_memory->cache_address + IMAGE_MEMORY_CACHE_SIZE))) { - if (!image_memory->cache) - image_memory->cache = malloc(IMAGE_MEMORY_CACHE_SIZE); - - if (target_read_buffer(image_memory->target, address & - ~(IMAGE_MEMORY_CACHE_SIZE - 1), - IMAGE_MEMORY_CACHE_SIZE, image_memory->cache) != ERROR_OK) { - free(image_memory->cache); - image_memory->cache = NULL; - return ERROR_IMAGE_TEMPORARILY_UNAVAILABLE; - } - image_memory->cache_address = address & - ~(IMAGE_MEMORY_CACHE_SIZE - 1); - } - - size_in_cache = - (image_memory->cache_address + IMAGE_MEMORY_CACHE_SIZE) - address; - - memcpy(buffer + *size_read, - image_memory->cache + (address - image_memory->cache_address), - (size_in_cache > size) ? size : size_in_cache - ); - - *size_read += (size_in_cache > size) ? size : size_in_cache; - address += (size_in_cache > size) ? size : size_in_cache; - } - } else if (image->type == IMAGE_SRECORD) { - memcpy(buffer, (uint8_t *)image->sections[section].private + offset, size); - *size_read = size; - - return ERROR_OK; - } else if (image->type == IMAGE_BUILDER) { - memcpy(buffer, (uint8_t *)image->sections[section].private + offset, size); - *size_read = size; - - return ERROR_OK; - } - - return ERROR_OK; -} - -int image_add_section(struct image *image, uint32_t base, uint32_t size, int flags, uint8_t const *data) -{ - struct imagesection *section; - - /* only image builder supports adding sections */ - if (image->type != IMAGE_BUILDER) - return ERROR_COMMAND_SYNTAX_ERROR; - - /* see if there's a previous section */ - if (image->num_sections) { - section = &image->sections[image->num_sections - 1]; - - /* see if it's enough to extend the last section, - * adding data to previous sections or merging is not supported */ - if (((section->base_address + section->size) == base) && - (section->flags == flags)) { - section->private = realloc(section->private, section->size + size); - memcpy((uint8_t *)section->private + section->size, data, size); - section->size += size; - return ERROR_OK; - } - } - - /* allocate new section */ - image->num_sections++; - image->sections = - realloc(image->sections, sizeof(struct imagesection) * image->num_sections); - section = &image->sections[image->num_sections - 1]; - section->base_address = base; - section->size = size; - section->flags = flags; - section->private = malloc(sizeof(uint8_t) * size); - memcpy((uint8_t *)section->private, data, size); - - return ERROR_OK; -} - -void image_close(struct image *image) -{ - if (image->type == IMAGE_BINARY) { - struct image_binary *image_binary = image->type_private; - - fileio_close(image_binary->fileio); - } else if (image->type == IMAGE_IHEX) { - struct image_ihex *image_ihex = image->type_private; - - fileio_close(image_ihex->fileio); - - if (image_ihex->buffer) { - free(image_ihex->buffer); - image_ihex->buffer = NULL; - } - } else if (image->type == IMAGE_ELF) { - struct image_elf *image_elf = image->type_private; - - fileio_close(image_elf->fileio); - - if (image_elf->header) { - free(image_elf->header); - image_elf->header = NULL; - } - - if (image_elf->segments) { - free(image_elf->segments); - image_elf->segments = NULL; - } - } else if (image->type == IMAGE_MEMORY) { - struct image_memory *image_memory = image->type_private; - - if (image_memory->cache) { - free(image_memory->cache); - image_memory->cache = NULL; - } - } else if (image->type == IMAGE_SRECORD) { - struct image_mot *image_mot = image->type_private; - - fileio_close(image_mot->fileio); - - if (image_mot->buffer) { - free(image_mot->buffer); - image_mot->buffer = NULL; - } - } else if (image->type == IMAGE_BUILDER) { - int i; - - for (i = 0; i < image->num_sections; i++) { - free(image->sections[i].private); - image->sections[i].private = NULL; - } - } - - if (image->type_private) { - free(image->type_private); - image->type_private = NULL; - } - - if (image->sections) { - free(image->sections); - image->sections = NULL; - } -} - -int image_calculate_checksum(uint8_t *buffer, uint32_t nbytes, uint32_t *checksum) -{ - uint32_t crc = 0xffffffff; - LOG_DEBUG("Calculating checksum"); - - static uint32_t crc32_table[256]; - - static bool first_init; - if (!first_init) { - /* Initialize the CRC table and the decoding table. */ - int i, j; - unsigned int c; - for (i = 0; i < 256; i++) { - /* as per gdb */ - for (c = i << 24, j = 8; j > 0; --j) - c = c & 0x80000000 ? (c << 1) ^ 0x04c11db7 : (c << 1); - crc32_table[i] = c; - } - - first_init = true; - } - - while (nbytes > 0) { - int run = nbytes; - if (run > 32768) - run = 32768; - nbytes -= run; - while (run--) { - /* as per gdb */ - crc = (crc << 8) ^ crc32_table[((crc >> 24) ^ *buffer++) & 255]; - } - keep_alive(); - } - - LOG_DEBUG("Calculating checksum done"); - - *checksum = crc; - return ERROR_OK; -} diff --git a/src/target/image.h b/src/target/image.h deleted file mode 100644 index 9bf7af35d..000000000 --- a/src/target/image.h +++ /dev/null @@ -1,110 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * Copyright (C) 2007,2008 Øyvind Harboe * - * oyvind.harboe@zylin.com * - * * - * Copyright (C) 2008 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 OPENOCD_TARGET_IMAGE_H -#define OPENOCD_TARGET_IMAGE_H - -#include - -#ifdef HAVE_ELF_H -#include -#endif - -#define IMAGE_MAX_ERROR_STRING (256) -#define IMAGE_MAX_SECTIONS (512) - -#define IMAGE_MEMORY_CACHE_SIZE (2048) - -enum image_type { - IMAGE_BINARY, /* plain binary */ - IMAGE_IHEX, /* intel hex-record format */ - IMAGE_MEMORY, /* target-memory pseudo-image */ - IMAGE_ELF, /* ELF binary */ - IMAGE_SRECORD, /* motorola s19 */ - IMAGE_BUILDER, /* when building a new image */ -}; - -struct imagesection { - uint32_t base_address; - uint32_t size; - int flags; - void *private; /* private data */ -}; - -struct image { - enum image_type type; /* image type (plain, ihex, ...) */ - void *type_private; /* type private data */ - int num_sections; /* number of sections contained in the image */ - struct imagesection *sections; /* array of sections */ - int base_address_set; /* whether the image has a base address set (for relocation purposes) */ - long long base_address; /* base address, if one is set */ - int start_address_set; /* whether the image has a start address (entry point) associated */ - uint32_t start_address; /* start address, if one is set */ -}; - -struct image_binary { - struct fileio *fileio; -}; - -struct image_ihex { - struct fileio *fileio; - uint8_t *buffer; -}; - -struct image_memory { - struct target *target; - uint8_t *cache; - uint32_t cache_address; -}; - -struct image_elf { - struct fileio *fileio; - Elf32_Ehdr *header; - Elf32_Phdr *segments; - uint32_t segment_count; - uint8_t endianness; -}; - -struct image_mot { - struct fileio *fileio; - uint8_t *buffer; -}; - -int image_open(struct image *image, const char *url, const char *type_string); -int image_read_section(struct image *image, int section, uint32_t offset, - uint32_t size, uint8_t *buffer, size_t *size_read); -void image_close(struct image *image); - -int image_add_section(struct image *image, uint32_t base, uint32_t size, - int flags, uint8_t const *data); - -int image_calculate_checksum(uint8_t *buffer, uint32_t nbytes, - uint32_t *checksum); - -#define ERROR_IMAGE_FORMAT_ERROR (-1400) -#define ERROR_IMAGE_TYPE_UNKNOWN (-1401) -#define ERROR_IMAGE_TEMPORARILY_UNAVAILABLE (-1402) -#define ERROR_IMAGE_CHECKSUM (-1403) - -#endif /* OPENOCD_TARGET_IMAGE_H */ diff --git a/src/target/lakemont.c b/src/target/lakemont.c deleted file mode 100644 index 27efc6946..000000000 --- a/src/target/lakemont.c +++ /dev/null @@ -1,1125 +0,0 @@ -/* - * 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 - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - * Contact Information: - * Intel Corporation - */ - -/* - * @file - * This implements the probemode operations for Lakemont 1 (LMT1). - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include - -#include "target.h" -#include "target_type.h" -#include "lakemont.h" -#include "register.h" -#include "breakpoints.h" -#include "x86_32_common.h" - -static int irscan(struct target *t, uint8_t *out, - uint8_t *in, uint8_t ir_len); -static int drscan(struct target *t, uint8_t *out, uint8_t *in, uint8_t len); -static int save_context(struct target *target); -static int restore_context(struct target *target); -static uint32_t get_tapstatus(struct target *t); -static int enter_probemode(struct target *t); -static int exit_probemode(struct target *t); -static int halt_prep(struct target *t); -static int do_halt(struct target *t); -static int do_resume(struct target *t); -static int read_all_core_hw_regs(struct target *t); -static int write_all_core_hw_regs(struct target *t); -static int read_hw_reg(struct target *t, - int reg, uint32_t *regval, uint8_t cache); -static int write_hw_reg(struct target *t, - int reg, uint32_t regval, uint8_t cache); -static struct reg_cache *lakemont_build_reg_cache - (struct target *target); -static int submit_reg_pir(struct target *t, int num); -static int submit_instruction_pir(struct target *t, int num); -static int submit_pir(struct target *t, uint64_t op); -static int lakemont_get_core_reg(struct reg *reg); -static int lakemont_set_core_reg(struct reg *reg, uint8_t *buf); - -static struct scan_blk scan; - -/* registers and opcodes for register access, pm_idx is used to identify the - * registers that are modified for lakemont probemode specific operations - */ -static const struct { - uint8_t id; - const char *name; - uint64_t op; - uint8_t pm_idx; - unsigned bits; - enum reg_type type; - const char *group; - const char *feature; -} regs[] = { - /* general purpose registers */ - { EAX, "eax", 0x000000D01D660000, 0, 32, REG_TYPE_INT32, "general", "org.gnu.gdb.i386.core" }, - { ECX, "ecx", 0x000000501D660000, 1, 32, REG_TYPE_INT32, "general", "org.gnu.gdb.i386.core" }, - { EDX, "edx", 0x000000901D660000, 2, 32, REG_TYPE_INT32, "general", "org.gnu.gdb.i386.core" }, - { EBX, "ebx", 0x000000101D660000, NOT_PMREG, 32, REG_TYPE_INT32, "general", "org.gnu.gdb.i386.core" }, - { ESP, "esp", 0x000000E01D660000, NOT_PMREG, 32, REG_TYPE_DATA_PTR, "general", "org.gnu.gdb.i386.core" }, - { EBP, "ebp", 0x000000601D660000, NOT_PMREG, 32, REG_TYPE_DATA_PTR, "general", "org.gnu.gdb.i386.core" }, - { ESI, "esi", 0x000000A01D660000, NOT_PMREG, 32, REG_TYPE_INT32, "general", "org.gnu.gdb.i386.core" }, - { EDI, "edi", 0x000000201D660000, NOT_PMREG, 32, REG_TYPE_INT32, "general", "org.gnu.gdb.i386.core" }, - - /* instruction pointer & flags */ - { EIP, "eip", 0x000000C01D660000, 3, 32, REG_TYPE_CODE_PTR, "general", "org.gnu.gdb.i386.core" }, - { EFLAGS, "eflags", 0x000000401D660000, 4, 32, REG_TYPE_INT32, "general", "org.gnu.gdb.i386.core" }, - - /* segment registers */ - { CS, "cs", 0x000000281D660000, 5, 32, REG_TYPE_INT32, "general", "org.gnu.gdb.i386.core" }, - { SS, "ss", 0x000000C81D660000, NOT_PMREG, 32, REG_TYPE_INT32, "general", "org.gnu.gdb.i386.core" }, - { DS, "ds", 0x000000481D660000, NOT_PMREG, 32, REG_TYPE_INT32, "general", "org.gnu.gdb.i386.core" }, - { ES, "es", 0x000000A81D660000, NOT_PMREG, 32, REG_TYPE_INT32, "general", "org.gnu.gdb.i386.core" }, - { FS, "fs", 0x000000881D660000, NOT_PMREG, 32, REG_TYPE_INT32, "general", "org.gnu.gdb.i386.core" }, - { GS, "gs", 0x000000081D660000, NOT_PMREG, 32, REG_TYPE_INT32, "general", "org.gnu.gdb.i386.core" }, - - /* floating point unit registers - not accessible via JTAG - here to satisfy GDB */ - { ST0, "st0", 0x0, NOT_AVAIL_REG, 32, REG_TYPE_INT32, "general", "org.gnu.gdb.i386.core" }, - { ST1, "st1", 0x0, NOT_AVAIL_REG, 32, REG_TYPE_INT32, "general", "org.gnu.gdb.i386.core" }, - { ST2, "st2", 0x0, NOT_AVAIL_REG, 32, REG_TYPE_INT32, "general", "org.gnu.gdb.i386.core" }, - { ST3, "st3", 0x0, NOT_AVAIL_REG, 32, REG_TYPE_INT32, "general", "org.gnu.gdb.i386.core" }, - { ST4, "st4", 0x0, NOT_AVAIL_REG, 32, REG_TYPE_INT32, "general", "org.gnu.gdb.i386.core" }, - { ST5, "st5", 0x0, NOT_AVAIL_REG, 32, REG_TYPE_INT32, "general", "org.gnu.gdb.i386.core" }, - { ST6, "st6", 0x0, NOT_AVAIL_REG, 32, REG_TYPE_INT32, "general", "org.gnu.gdb.i386.core" }, - { ST7, "st7", 0x0, NOT_AVAIL_REG, 32, REG_TYPE_INT32, "general", "org.gnu.gdb.i386.core" }, - { FCTRL, "fctrl", 0x0, NOT_AVAIL_REG, 32, REG_TYPE_INT32, "general", "org.gnu.gdb.i386.core" }, - { FSTAT, "fstat", 0x0, NOT_AVAIL_REG, 32, REG_TYPE_INT32, "general", "org.gnu.gdb.i386.core" }, - { FTAG, "ftag", 0x0, NOT_AVAIL_REG, 32, REG_TYPE_INT32, "general", "org.gnu.gdb.i386.core" }, - { FISEG, "fiseg", 0x0, NOT_AVAIL_REG, 32, REG_TYPE_INT32, "general", "org.gnu.gdb.i386.core" }, - { FIOFF, "fioff", 0x0, NOT_AVAIL_REG, 32, REG_TYPE_INT32, "general", "org.gnu.gdb.i386.core" }, - { FOSEG, "foseg", 0x0, NOT_AVAIL_REG, 32, REG_TYPE_INT32, "general", "org.gnu.gdb.i386.core" }, - { FOOFF, "fooff", 0x0, NOT_AVAIL_REG, 32, REG_TYPE_INT32, "general", "org.gnu.gdb.i386.core" }, - { FOP, "fop", 0x0, NOT_AVAIL_REG, 32, REG_TYPE_INT32, "general", "org.gnu.gdb.i386.core" }, - - /* control registers */ - { CR0, "cr0", 0x000000001D660000, 6, 32, REG_TYPE_INT32, "general", "org.gnu.gdb.i386.sys" }, - { CR2, "cr2", 0x000000BC1D660000, 7, 32, REG_TYPE_INT32, "general", "org.gnu.gdb.i386.sys" }, - { CR3, "cr3", 0x000000801D660000, 8, 32, REG_TYPE_INT32, "general", "org.gnu.gdb.i386.sys" }, - { CR4, "cr4", 0x0000002C1D660000, 9, 32, REG_TYPE_INT32, "general", "org.gnu.gdb.i386.sys" }, - - /* debug registers */ - { DR0, "dr0", 0x0000007C1D660000, NOT_PMREG, 32, REG_TYPE_INT32, "general", "org.gnu.gdb.i386.sys" }, - { DR1, "dr1", 0x000000FC1D660000, NOT_PMREG, 32, REG_TYPE_INT32, "general", "org.gnu.gdb.i386.sys" }, - { DR2, "dr2", 0x000000021D660000, NOT_PMREG, 32, REG_TYPE_INT32, "general", "org.gnu.gdb.i386.sys" }, - { DR3, "dr3", 0x000000821D660000, NOT_PMREG, 32, REG_TYPE_INT32, "general", "org.gnu.gdb.i386.sys" }, - { DR6, "dr6", 0x000000301D660000, 10, 32, REG_TYPE_INT32, "general", "org.gnu.gdb.i386.sys" }, - { DR7, "dr7", 0x000000B01D660000, 11, 32, REG_TYPE_INT32, "general", "org.gnu.gdb.i386.sys" }, - - /* descriptor tables */ - { IDTB, "idtbase", 0x000000581D660000, NOT_PMREG, 32, REG_TYPE_INT32, "general", "org.gnu.gdb.i386.sys" }, - { IDTL, "idtlimit", 0x000000D81D660000, NOT_PMREG, 32, REG_TYPE_INT32, "general", "org.gnu.gdb.i386.sys" }, - { IDTAR, "idtar", 0x000000981D660000, NOT_PMREG, 32, REG_TYPE_INT32, "general", "org.gnu.gdb.i386.sys" }, - { GDTB, "gdtbase", 0x000000B81D660000, NOT_PMREG, 32, REG_TYPE_INT32, "general", "org.gnu.gdb.i386.sys" }, - { GDTL, "gdtlimit", 0x000000781D660000, NOT_PMREG, 32, REG_TYPE_INT32, "general", "org.gnu.gdb.i386.sys" }, - { GDTAR, "gdtar", 0x000000381D660000, NOT_PMREG, 32, REG_TYPE_INT32, "general", "org.gnu.gdb.i386.sys" }, - { TR, "tr", 0x000000701D660000, NOT_PMREG, 32, REG_TYPE_INT32, "general", "org.gnu.gdb.i386.sys" }, - { LDTR, "ldtr", 0x000000F01D660000, NOT_PMREG, 32, REG_TYPE_INT32, "general", "org.gnu.gdb.i386.sys" }, - { LDTB, "ldbase", 0x000000041D660000, NOT_PMREG, 32, REG_TYPE_INT32, "general", "org.gnu.gdb.i386.sys" }, - { LDTL, "ldlimit", 0x000000841D660000, NOT_PMREG, 32, REG_TYPE_INT32, "general", "org.gnu.gdb.i386.sys" }, - { LDTAR, "ldtar", 0x000000F81D660000, NOT_PMREG, 32, REG_TYPE_INT32, "general", "org.gnu.gdb.i386.sys" }, - - /* segment registers */ - { CSB, "csbase", 0x000000F41D660000, NOT_PMREG, 32, REG_TYPE_INT32, "general", "org.gnu.gdb.i386.sys" }, - { CSL, "cslimit", 0x0000000C1D660000, NOT_PMREG, 32, REG_TYPE_INT32, "general", "org.gnu.gdb.i386.sys" }, - { CSAR, "csar", 0x000000741D660000, 12, 32, REG_TYPE_INT32, "general", "org.gnu.gdb.i386.sys" }, - { DSB, "dsbase", 0x000000941D660000, 13, 32, REG_TYPE_INT32, "general", "org.gnu.gdb.i386.sys" }, - { DSL, "dslimit", 0x000000541D660000, 14, 32, REG_TYPE_INT32, "general", "org.gnu.gdb.i386.sys" }, - { DSAR, "dsar", 0x000000141D660000, 15, 32, REG_TYPE_INT32, "general", "org.gnu.gdb.i386.sys" }, - { ESB, "esbase", 0x0000004C1D660000, NOT_PMREG, 32, REG_TYPE_INT32, "general", "org.gnu.gdb.i386.sys" }, - { ESL, "eslimit", 0x000000CC1D660000, NOT_PMREG, 32, REG_TYPE_INT32, "general", "org.gnu.gdb.i386.sys" }, - { ESAR, "esar", 0x0000008C1D660000, NOT_PMREG, 32, REG_TYPE_INT32, "general", "org.gnu.gdb.i386.sys" }, - { FSB, "fsbase", 0x000000641D660000, NOT_PMREG, 32, REG_TYPE_INT32, "general", "org.gnu.gdb.i386.sys" }, - { FSL, "fslimit", 0x000000E41D660000, NOT_PMREG, 32, REG_TYPE_INT32, "general", "org.gnu.gdb.i386.sys" }, - { FSAR, "fsar", 0x000000A41D660000, NOT_PMREG, 32, REG_TYPE_INT32, "general", "org.gnu.gdb.i386.sys" }, - { GSB, "gsbase", 0x000000C41D660000, NOT_PMREG, 32, REG_TYPE_INT32, "general", "org.gnu.gdb.i386.sys" }, - { GSL, "gslimit", 0x000000241D660000, NOT_PMREG, 32, REG_TYPE_INT32, "general", "org.gnu.gdb.i386.sys" }, - { GSAR, "gsar", 0x000000441D660000, NOT_PMREG, 32, REG_TYPE_INT32, "general", "org.gnu.gdb.i386.sys" }, - { SSB, "ssbase", 0x000000341D660000, NOT_PMREG, 32, REG_TYPE_INT32, "general", "org.gnu.gdb.i386.sys" }, - { SSL, "sslimit", 0x000000B41D660000, NOT_PMREG, 32, REG_TYPE_INT32, "general", "org.gnu.gdb.i386.sys" }, - { SSAR, "ssar", 0x000000D41D660000, 16, 32, REG_TYPE_INT32, "general", "org.gnu.gdb.i386.sys" }, - { TSSB, "tssbase", 0x000000E81D660000, NOT_PMREG, 32, REG_TYPE_INT32, "general", "org.gnu.gdb.i386.sys" }, - { TSSL, "tsslimit", 0x000000181D660000, NOT_PMREG, 32, REG_TYPE_INT32, "general", "org.gnu.gdb.i386.sys" }, - { TSSAR, "tssar", 0x000000681D660000, NOT_PMREG, 32, REG_TYPE_INT32, "general", "org.gnu.gdb.i386.sys" }, - /* probemode control register */ - { PMCR, "pmcr", 0x000000421D660000, 17, 32, REG_TYPE_INT32, "general", "org.gnu.gdb.i386.sys" }, -}; - -static const struct { - uint8_t id; - const char *name; - uint64_t op; -} instructions[] = { - /* memory read/write */ - { MEMRDB32, "MEMRDB32", 0x0909090909090851 }, - { MEMRDB16, "MEMRDB16", 0x09090909090851E6 }, - { MEMRDH32, "MEMRDH32", 0x090909090908D166 }, - { MEMRDH16, "MEMRDH16", 0x090909090908D1E6 }, - { MEMRDW32, "MEMRDW32", 0x09090909090908D1 }, - { MEMRDW16, "MEMRDW16", 0x0909090908D1E666 }, - { MEMWRB32, "MEMWRB32", 0x0909090909090811 }, - { MEMWRB16, "MEMWRB16", 0x09090909090811E6 }, - { MEMWRH32, "MEMWRH32", 0x0909090909089166 }, - { MEMWRH16, "MEMWRH16", 0x09090909090891E6 }, - { MEMWRW32, "MEMWRW32", 0x0909090909090891 }, - { MEMWRW16, "MEMWRW16", 0x090909090891E666 }, - /* IO read/write */ - { IORDB32, "IORDB32", 0x0909090909090937 }, - { IORDB16, "IORDB16", 0x09090909090937E6 }, - { IORDH32, "IORDH32", 0x090909090909B766 }, - { IORDH16, "IORDH16", 0x090909090909B7E6 }, - { IORDW32, "IORDW32", 0x09090909090909B7 }, - { IORDW16, "IORDW16", 0x0909090909B7E666 }, - { IOWRB32, "IOWRB32", 0x0909090909090977 }, - { IOWRB16, "IOWRB16", 0x09090909090977E6 }, - { IOWRH32, "IOWRH32", 0x090909090909F766 }, - { IOWRH16, "IOWRH16", 0x090909090909F7E6 }, - { IOWRW32, "IOWRW32", 0x09090909090909F7 }, - { IOWRW16, "IOWRW16", 0x0909090909F7E666 }, - /* lakemont1 core shadow ram access opcodes */ - { SRAMACCESS, "SRAMACCESS", 0x0000000E9D660000 }, - { SRAM2PDR, "SRAM2PDR", 0x4CF0000000000000 }, - { PDR2SRAM, "PDR2SRAM", 0x0CF0000000000000 }, - { WBINVD, "WBINVD", 0x09090909090990F0 }, -}; - -bool check_not_halted(const struct target *t) -{ - bool halted = t->state == TARGET_HALTED; - if (!halted) - LOG_ERROR("target running, halt it first"); - return !halted; -} - -static int irscan(struct target *t, uint8_t *out, - uint8_t *in, uint8_t ir_len) -{ - int retval = ERROR_OK; - struct x86_32_common *x86_32 = target_to_x86_32(t); - if (NULL == t->tap) { - retval = ERROR_FAIL; - LOG_ERROR("%s invalid target tap", __func__); - return retval; - } - if (ir_len != t->tap->ir_length) { - retval = ERROR_FAIL; - if (t->tap->enabled) - LOG_ERROR("%s tap enabled but tap irlen=%d", - __func__, t->tap->ir_length); - else - LOG_ERROR("%s tap not enabled and irlen=%d", - __func__, t->tap->ir_length); - return retval; - } - struct scan_field *fields = &scan.field; - fields->num_bits = ir_len; - fields->out_value = out; - fields->in_value = in; - jtag_add_ir_scan(x86_32->curr_tap, fields, TAP_IDLE); - if (x86_32->flush) { - retval = jtag_execute_queue(); - if (retval != ERROR_OK) - LOG_ERROR("%s failed to execute queue", __func__); - } - return retval; -} - -static int drscan(struct target *t, uint8_t *out, uint8_t *in, uint8_t len) -{ - int retval = ERROR_OK; - uint64_t data = 0; - struct x86_32_common *x86_32 = target_to_x86_32(t); - if (NULL == t->tap) { - retval = ERROR_FAIL; - LOG_ERROR("%s invalid target tap", __func__); - return retval; - } - if (len > MAX_SCAN_SIZE || 0 == len) { - retval = ERROR_FAIL; - LOG_ERROR("%s data len is %d bits, max is %d bits", - __func__, len, MAX_SCAN_SIZE); - return retval; - } - struct scan_field *fields = &scan.field; - fields->out_value = out; - fields->in_value = in; - fields->num_bits = len; - jtag_add_dr_scan(x86_32->curr_tap, 1, fields, TAP_IDLE); - if (x86_32->flush) { - retval = jtag_execute_queue(); - if (retval != ERROR_OK) { - LOG_ERROR("%s drscan failed to execute queue", __func__); - return retval; - } - } - if (in != NULL) { - if (len >= 8) { - for (int n = (len / 8) - 1 ; n >= 0; n--) - data = (data << 8) + *(in+n); - } else - LOG_DEBUG("dr in 0x%02" PRIx8, *in); - } else { - LOG_ERROR("%s no drscan data", __func__); - retval = ERROR_FAIL; - } - return retval; -} - -static int save_context(struct target *t) -{ - int err; - /* read core registers from lakemont sram */ - err = read_all_core_hw_regs(t); - if (err != ERROR_OK) { - LOG_ERROR("%s error reading regs", __func__); - return err; - } - return ERROR_OK; -} - -static int restore_context(struct target *t) -{ - int err = ERROR_OK; - uint32_t i; - struct x86_32_common *x86_32 = target_to_x86_32(t); - - /* write core regs into the core PM SRAM from the reg_cache */ - err = write_all_core_hw_regs(t); - if (err != ERROR_OK) { - LOG_ERROR("%s error writing regs", __func__); - return err; - } - - for (i = 0; i < (x86_32->cache->num_regs); i++) { - x86_32->cache->reg_list[i].dirty = 0; - x86_32->cache->reg_list[i].valid = 0; - } - return err; -} - -/* - * we keep reg_cache in sync with hardware at halt/resume time, we avoid - * writing to real hardware here bacause pm_regs reflects the hardware - * while we are halted then reg_cache syncs with hw on resume - * TODO - in order for "reg eip force" to work it assume get/set reads - * and writes from hardware, may be other reasons also because generally - * other openocd targets read/write from hardware in get/set - watch this! - */ -static int lakemont_get_core_reg(struct reg *reg) -{ - int retval = ERROR_OK; - struct lakemont_core_reg *lakemont_reg = reg->arch_info; - struct target *t = lakemont_reg->target; - if (check_not_halted(t)) - return ERROR_TARGET_NOT_HALTED; - LOG_DEBUG("reg=%s, value=0x%08" PRIx32, reg->name, - buf_get_u32(reg->value, 0, 32)); - return retval; -} - -static int lakemont_set_core_reg(struct reg *reg, uint8_t *buf) -{ - struct lakemont_core_reg *lakemont_reg = reg->arch_info; - struct target *t = lakemont_reg->target; - uint32_t value = buf_get_u32(buf, 0, 32); - LOG_DEBUG("reg=%s, newval=0x%08" PRIx32, reg->name, value); - if (check_not_halted(t)) - return ERROR_TARGET_NOT_HALTED; - buf_set_u32(reg->value, 0, 32, value); - reg->dirty = 1; - reg->valid = 1; - return ERROR_OK; -} - -static const struct reg_arch_type lakemont_reg_type = { - /* these get called if reg_cache doesnt have a "valid" value - * of an individual reg eg "reg eip" but not for "reg" block - */ - .get = lakemont_get_core_reg, - .set = lakemont_set_core_reg, -}; - -struct reg_cache *lakemont_build_reg_cache(struct target *t) -{ - struct x86_32_common *x86_32 = target_to_x86_32(t); - int num_regs = ARRAY_SIZE(regs); - struct reg_cache **cache_p = register_get_last_cache_p(&t->reg_cache); - struct reg_cache *cache = malloc(sizeof(struct reg_cache)); - struct reg *reg_list = calloc(num_regs, sizeof(struct reg)); - struct lakemont_core_reg *arch_info = malloc(sizeof(struct lakemont_core_reg) * num_regs); - struct reg_feature *feature; - int i; - - if (cache == NULL || reg_list == NULL || arch_info == NULL) { - free(cache); - free(reg_list); - free(arch_info); - LOG_ERROR("%s out of memory", __func__); - return NULL; - } - - /* Build the process context cache */ - cache->name = "lakemont registers"; - cache->next = NULL; - cache->reg_list = reg_list; - cache->num_regs = num_regs; - (*cache_p) = cache; - x86_32->cache = cache; - - for (i = 0; i < num_regs; i++) { - arch_info[i].target = t; - arch_info[i].x86_32_common = x86_32; - arch_info[i].op = regs[i].op; - arch_info[i].pm_idx = regs[i].pm_idx; - reg_list[i].name = regs[i].name; - reg_list[i].size = 32; - reg_list[i].value = calloc(1, 4); - reg_list[i].dirty = 0; - reg_list[i].valid = 0; - reg_list[i].type = &lakemont_reg_type; - reg_list[i].arch_info = &arch_info[i]; - - reg_list[i].group = regs[i].group; - reg_list[i].number = i; - reg_list[i].exist = true; - reg_list[i].caller_save = true; /* gdb defaults to true */ - - feature = calloc(1, sizeof(struct reg_feature)); - if (feature) { - feature->name = regs[i].feature; - reg_list[i].feature = feature; - } else - LOG_ERROR("%s unable to allocate feature list", __func__); - - reg_list[i].reg_data_type = calloc(1, sizeof(struct reg_data_type)); - if (reg_list[i].reg_data_type) - reg_list[i].reg_data_type->type = regs[i].type; - else - LOG_ERROR("%s unable to allocate reg type list", __func__); - } - return cache; -} - -static uint32_t get_tapstatus(struct target *t) -{ - scan.out[0] = TAPSTATUS; - if (irscan(t, scan.out, NULL, LMT_IRLEN) != ERROR_OK) - return 0; - if (drscan(t, NULL, scan.out, TS_SIZE) != ERROR_OK) - return 0; - return buf_get_u32(scan.out, 0, 32); -} - -static int enter_probemode(struct target *t) -{ - uint32_t tapstatus = 0; - tapstatus = get_tapstatus(t); - LOG_DEBUG("TS before PM enter = 0x%08" PRIx32, tapstatus); - if (tapstatus & TS_PM_BIT) { - LOG_DEBUG("core already in probemode"); - return ERROR_OK; - } - scan.out[0] = PROBEMODE; - if (irscan(t, scan.out, NULL, LMT_IRLEN) != ERROR_OK) - return ERROR_FAIL; - scan.out[0] = 1; - if (drscan(t, scan.out, scan.in, 1) != ERROR_OK) - return ERROR_FAIL; - tapstatus = get_tapstatus(t); - LOG_DEBUG("TS after PM enter = 0x%08" PRIx32, tapstatus); - if ((tapstatus & TS_PM_BIT) && (!(tapstatus & TS_EN_PM_BIT))) - return ERROR_OK; - else { - LOG_ERROR("%s PM enter error, tapstatus = 0x%08" PRIx32 - , __func__, tapstatus); - return ERROR_FAIL; - } -} - -static int exit_probemode(struct target *t) -{ - uint32_t tapstatus = get_tapstatus(t); - LOG_DEBUG("TS before PM exit = 0x%08" PRIx32, tapstatus); - - if (!(tapstatus & TS_PM_BIT)) { - LOG_USER("core not in PM"); - return ERROR_OK; - } - scan.out[0] = PROBEMODE; - if (irscan(t, scan.out, NULL, LMT_IRLEN) != ERROR_OK) - return ERROR_FAIL; - scan.out[0] = 0; - if (drscan(t, scan.out, scan.in, 1) != ERROR_OK) - return ERROR_FAIL; - return ERROR_OK; -} - -/* do whats needed to properly enter probemode for debug on lakemont */ -static int halt_prep(struct target *t) -{ - struct x86_32_common *x86_32 = target_to_x86_32(t); - if (write_hw_reg(t, DSB, PM_DSB, 0) != ERROR_OK) - return ERROR_FAIL; - LOG_DEBUG("write %s 0x%08" PRIx32, regs[DSB].name, PM_DSB); - if (write_hw_reg(t, DSL, PM_DSL, 0) != ERROR_OK) - return ERROR_FAIL; - LOG_DEBUG("write %s 0x%08" PRIx32, regs[DSL].name, PM_DSL); - 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); - - uint32_t eflags = buf_get_u32(x86_32->cache->reg_list[EFLAGS].value, 0, 32); - uint32_t csar = buf_get_u32(x86_32->cache->reg_list[CSAR].value, 0, 32); - uint32_t ssar = buf_get_u32(x86_32->cache->reg_list[SSAR].value, 0, 32); - uint32_t cr0 = buf_get_u32(x86_32->cache->reg_list[CR0].value, 0, 32); - - /* clear VM86 and IF bits if they are set */ - 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)) { - 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; - LOG_DEBUG("EFLAGS now = 0x%08" PRIx32 ", VM86 = %d, IF = %d", - x86_32->pm_regs[I(EFLAGS)], - x86_32->pm_regs[I(EFLAGS)] & EFLAGS_VM86 ? 1 : 0, - x86_32->pm_regs[I(EFLAGS)] & EFLAGS_IF ? 1 : 0); - } - - /* set CPL to 0 for memory access */ - if (csar & CSAR_DPL) { - x86_32->pm_regs[I(CSAR)] = csar & ~CSAR_DPL; - if (write_hw_reg(t, CSAR, x86_32->pm_regs[I(CSAR)], 0) != ERROR_OK) - return ERROR_FAIL; - 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 & ~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, 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; - if (write_hw_reg(t, CR0, x86_32->pm_regs[I(CR0)], 0) != ERROR_OK) - return ERROR_FAIL; - LOG_DEBUG("cleared paging CR0_PG = 0x%08" PRIx32, x86_32->pm_regs[I(CR0)]); - /* submit wbinvd to flush cache */ - if (submit_reg_pir(t, WBINVD) != ERROR_OK) - return ERROR_FAIL; - x86_32->pm_regs[I(CR0)] = - x86_32->pm_regs[I(CR0)] | (CR0_CD | CR0_NW | CR0_PG); - if (write_hw_reg(t, CR0, x86_32->pm_regs[I(CR0)], 0) != ERROR_OK) - return ERROR_FAIL; - LOG_DEBUG("set CD, NW and PG, CR0 = 0x%08" PRIx32, x86_32->pm_regs[I(CR0)]); - } - } - return ERROR_OK; -} - -static int do_halt(struct target *t) -{ - /* needs proper handling later if doing a halt errors out */ - 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) - return ERROR_FAIL; - t->state = TARGET_HALTED; - - return target_call_event_callbacks(t, TARGET_EVENT_HALTED); -} - -static int do_resume(struct target *t) -{ - /* needs proper handling later */ - t->state = TARGET_DEBUG_RUNNING; - if (restore_context(t) != ERROR_OK) - return ERROR_FAIL; - if (exit_probemode(t) != ERROR_OK) - return ERROR_FAIL; - t->state = TARGET_RUNNING; - - t->debug_reason = DBG_REASON_NOTHALTED; - LOG_USER("target running"); - - return target_call_event_callbacks(t, TARGET_EVENT_RESUMED); -} - -static int read_all_core_hw_regs(struct target *t) -{ - int err; - uint32_t regval; - unsigned i; - struct x86_32_common *x86_32 = target_to_x86_32(t); - for (i = 0; i < (x86_32->cache->num_regs); i++) { - if (NOT_AVAIL_REG == regs[i].pm_idx) - continue; - err = read_hw_reg(t, regs[i].id, ®val, 1); - if (err != ERROR_OK) { - LOG_ERROR("%s error saving reg %s", - __func__, x86_32->cache->reg_list[i].name); - return err; - } - } - LOG_DEBUG("read_all_core_hw_regs read %u registers ok", i); - return ERROR_OK; -} - -static int write_all_core_hw_regs(struct target *t) -{ - int err; - unsigned i; - struct x86_32_common *x86_32 = target_to_x86_32(t); - for (i = 0; i < (x86_32->cache->num_regs); i++) { - if (NOT_AVAIL_REG == regs[i].pm_idx) - continue; - err = write_hw_reg(t, i, 0, 1); - if (err != ERROR_OK) { - LOG_ERROR("%s error restoring reg %s", - __func__, x86_32->cache->reg_list[i].name); - return err; - } - } - LOG_DEBUG("write_all_core_hw_regs wrote %u registers ok", i); - return ERROR_OK; -} - -/* read reg from lakemont core shadow ram, update reg cache if needed */ -static int read_hw_reg(struct target *t, int reg, uint32_t *regval, uint8_t cache) -{ - struct x86_32_common *x86_32 = target_to_x86_32(t); - struct lakemont_core_reg *arch_info; - arch_info = x86_32->cache->reg_list[reg].arch_info; - x86_32->flush = 0; /* dont flush scans till we have a batch */ - if (submit_reg_pir(t, reg) != ERROR_OK) - return ERROR_FAIL; - if (submit_instruction_pir(t, SRAMACCESS) != ERROR_OK) - return ERROR_FAIL; - if (submit_instruction_pir(t, SRAM2PDR) != ERROR_OK) - return ERROR_FAIL; - x86_32->flush = 1; - scan.out[0] = RDWRPDR; - if (irscan(t, scan.out, NULL, LMT_IRLEN) != ERROR_OK) - return ERROR_FAIL; - if (drscan(t, NULL, scan.out, PDR_SIZE) != ERROR_OK) - return ERROR_FAIL; - - jtag_add_sleep(DELAY_SUBMITPIR); - *regval = buf_get_u32(scan.out, 0, 32); - if (cache) { - buf_set_u32(x86_32->cache->reg_list[reg].value, 0, 32, *regval); - x86_32->cache->reg_list[reg].valid = 1; - x86_32->cache->reg_list[reg].dirty = 0; - } - LOG_DEBUG("reg=%s, op=0x%016" PRIx64 ", val=0x%08" PRIx32, - x86_32->cache->reg_list[reg].name, - arch_info->op, - *regval); - return ERROR_OK; -} - -/* write lakemont core shadow ram reg, update reg cache if needed */ -static int write_hw_reg(struct target *t, int reg, uint32_t regval, uint8_t cache) -{ - struct x86_32_common *x86_32 = target_to_x86_32(t); - struct lakemont_core_reg *arch_info; - arch_info = x86_32->cache->reg_list[reg].arch_info; - - uint8_t reg_buf[4]; - if (cache) - regval = buf_get_u32(x86_32->cache->reg_list[reg].value, 0, 32); - buf_set_u32(reg_buf, 0, 32, regval); - LOG_DEBUG("reg=%s, op=0x%016" PRIx64 ", val=0x%08" PRIx32, - x86_32->cache->reg_list[reg].name, - arch_info->op, - regval); - - x86_32->flush = 0; /* dont flush scans till we have a batch */ - 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; - - /* we are writing from the cache so ensure we reset flags */ - if (cache) { - x86_32->cache->reg_list[reg].dirty = 0; - x86_32->cache->reg_list[reg].valid = 0; - } - return ERROR_OK; -} - -static bool is_paging_enabled(struct target *t) -{ - struct x86_32_common *x86_32 = target_to_x86_32(t); - if (x86_32->pm_regs[I(CR0)] & CR0_PG) - return true; - else - return false; -} - -static uint8_t get_num_user_regs(struct target *t) -{ - struct x86_32_common *x86_32 = target_to_x86_32(t); - return x86_32->cache->num_regs; -} -/* value of the CR0.PG (paging enabled) bit influences memory reads/writes */ -static int disable_paging(struct target *t) -{ - struct x86_32_common *x86_32 = target_to_x86_32(t); - x86_32->pm_regs[I(CR0)] = x86_32->pm_regs[I(CR0)] & ~CR0_PG; - int err = x86_32->write_hw_reg(t, CR0, x86_32->pm_regs[I(CR0)], 0); - if (err != ERROR_OK) { - LOG_ERROR("%s error disabling paging", __func__); - return err; - } - return err; -} - -static int enable_paging(struct target *t) -{ - struct x86_32_common *x86_32 = target_to_x86_32(t); - x86_32->pm_regs[I(CR0)] = (x86_32->pm_regs[I(CR0)] | CR0_PG); - int err = x86_32->write_hw_reg(t, CR0, x86_32->pm_regs[I(CR0)], 0); - if (err != ERROR_OK) { - LOG_ERROR("%s error enabling paging", __func__); - return err; - } - return err; -} - -static bool sw_bpts_supported(struct target *t) -{ - uint32_t tapstatus = get_tapstatus(t); - if (tapstatus & TS_SBP_BIT) - return true; - else - return false; -} - -static int transaction_status(struct target *t) -{ - uint32_t tapstatus = get_tapstatus(t); - if ((TS_EN_PM_BIT | TS_PRDY_BIT) & tapstatus) { - LOG_ERROR("%s transaction error tapstatus = 0x%08" PRIx32 - , __func__, tapstatus); - return ERROR_FAIL; - } else { - return ERROR_OK; - } -} - -static int submit_instruction(struct target *t, int num) -{ - int err = submit_instruction_pir(t, num); - if (err != ERROR_OK) { - LOG_ERROR("%s error submitting pir", __func__); - return err; - } - return err; -} - -static int submit_reg_pir(struct target *t, int num) -{ - LOG_DEBUG("reg %s op=0x%016" PRIx64, regs[num].name, regs[num].op); - int err = submit_pir(t, regs[num].op); - if (err != ERROR_OK) { - LOG_ERROR("%s error submitting pir", __func__); - return err; - } - return err; -} - -static int submit_instruction_pir(struct target *t, int num) -{ - LOG_DEBUG("%s op=0x%016" PRIx64, instructions[num].name, - instructions[num].op); - int err = submit_pir(t, instructions[num].op); - if (err != ERROR_OK) { - LOG_ERROR("%s error submitting pir", __func__); - return err; - } - return err; -} - -/* - * PIR (Probe Mode Instruction Register), SUBMITPIR is an "IR only" TAP - * command; there is no corresponding data register - */ -static int submit_pir(struct target *t, uint64_t op) -{ - struct x86_32_common *x86_32 = target_to_x86_32(t); - - uint8_t op_buf[8]; - buf_set_u64(op_buf, 0, 64, op); - int flush = x86_32->flush; - x86_32->flush = 0; - scan.out[0] = WRPIR; - if (irscan(t, scan.out, NULL, LMT_IRLEN) != ERROR_OK) - return ERROR_FAIL; - if (drscan(t, op_buf, scan.out, PIR_SIZE) != ERROR_OK) - return ERROR_FAIL; - scan.out[0] = SUBMITPIR; - x86_32->flush = flush; - if (irscan(t, scan.out, NULL, LMT_IRLEN) != ERROR_OK) - return ERROR_FAIL; - jtag_add_sleep(DELAY_SUBMITPIR); - return ERROR_OK; -} - -int lakemont_init_target(struct command_context *cmd_ctx, struct target *t) -{ - lakemont_build_reg_cache(t); - t->state = TARGET_RUNNING; - t->debug_reason = DBG_REASON_NOTHALTED; - return ERROR_OK; -} - -int lakemont_init_arch_info(struct target *t, struct x86_32_common *x86_32) -{ - x86_32->submit_instruction = submit_instruction; - x86_32->transaction_status = transaction_status; - x86_32->read_hw_reg = read_hw_reg; - x86_32->write_hw_reg = write_hw_reg; - x86_32->sw_bpts_supported = sw_bpts_supported; - x86_32->get_num_user_regs = get_num_user_regs; - x86_32->is_paging_enabled = is_paging_enabled; - x86_32->disable_paging = disable_paging; - x86_32->enable_paging = enable_paging; - return ERROR_OK; -} - -int lakemont_poll(struct target *t) -{ - /* LMT1 PMCR register currently allows code breakpoints, data breakpoints, - * single stepping and shutdowns to be redirected to PM but does not allow - * redirecting into PM as a result of SMM enter and SMM exit - */ - uint32_t ts = get_tapstatus(t); - - if (ts == 0xFFFFFFFF && t->state != TARGET_DEBUG_RUNNING) { - /* something is wrong here */ - LOG_ERROR("tapstatus invalid - scan_chain serialization or locked JTAG access issues"); - /* TODO: Give a hint that unlocking is wrong or maybe a - * 'jtag arp_init' helps - */ - t->state = TARGET_DEBUG_RUNNING; - return ERROR_OK; - } - - if (t->state == TARGET_HALTED && (!(ts & TS_PM_BIT))) { - LOG_INFO("target running for unknown reason"); - t->state = TARGET_RUNNING; - } - - if (t->state == TARGET_RUNNING && - t->state != TARGET_DEBUG_RUNNING) { - - if ((ts & TS_PM_BIT) && (ts & TS_PMCR_BIT)) { - - LOG_DEBUG("redirect to PM, tapstatus=0x%08" PRIx32, get_tapstatus(t)); - - t->state = TARGET_DEBUG_RUNNING; - if (save_context(t) != ERROR_OK) - return ERROR_FAIL; - if (halt_prep(t) != ERROR_OK) - return ERROR_FAIL; - t->state = TARGET_HALTED; - t->debug_reason = DBG_REASON_UNDEFINED; - - struct x86_32_common *x86_32 = target_to_x86_32(t); - uint32_t eip = buf_get_u32(x86_32->cache->reg_list[EIP].value, 0, 32); - uint32_t dr6 = buf_get_u32(x86_32->cache->reg_list[DR6].value, 0, 32); - uint32_t hwbreakpoint = (uint32_t)-1; - - if (dr6 & DR6_BRKDETECT_0) - hwbreakpoint = 0; - if (dr6 & DR6_BRKDETECT_1) - hwbreakpoint = 1; - if (dr6 & DR6_BRKDETECT_2) - hwbreakpoint = 2; - if (dr6 & DR6_BRKDETECT_3) - hwbreakpoint = 3; - - if (hwbreakpoint != (uint32_t)-1) { - uint32_t dr7 = buf_get_u32(x86_32->cache->reg_list[DR7].value, 0, 32); - uint32_t type = dr7 & (0x03 << (DR7_RW_SHIFT + hwbreakpoint*DR7_RW_LEN_SIZE)); - if (type == DR7_BP_EXECUTE) { - LOG_USER("hit hardware breakpoint (hwreg=%" PRIu32 ") at 0x%08" PRIx32, hwbreakpoint, eip); - } else { - uint32_t address = 0; - switch (hwbreakpoint) { - default: - case 0: - address = buf_get_u32(x86_32->cache->reg_list[DR0].value, 0, 32); - break; - case 1: - address = buf_get_u32(x86_32->cache->reg_list[DR1].value, 0, 32); - break; - case 2: - address = buf_get_u32(x86_32->cache->reg_list[DR2].value, 0, 32); - break; - case 3: - address = buf_get_u32(x86_32->cache->reg_list[DR3].value, 0, 32); - break; - } - LOG_USER("hit '%s' watchpoint for 0x%08" PRIx32 " (hwreg=%" PRIu32 ") at 0x%08" PRIx32, - type == DR7_BP_WRITE ? "write" : "access", address, - hwbreakpoint, eip); - } - t->debug_reason = DBG_REASON_BREAKPOINT; - } else { - /* Check if the target hit a software breakpoint. - * ! Watch out: EIP is currently pointing after the breakpoint opcode - */ - struct breakpoint *bp = NULL; - bp = breakpoint_find(t, eip-1); - if (bp != NULL) { - t->debug_reason = DBG_REASON_BREAKPOINT; - if (bp->type == BKPT_SOFT) { - /* The EIP is now pointing the the next byte after the - * breakpoint instruction. This needs to be corrected. - */ - buf_set_u32(x86_32->cache->reg_list[EIP].value, 0, 32, eip-1); - x86_32->cache->reg_list[EIP].dirty = 1; - x86_32->cache->reg_list[EIP].valid = 1; - LOG_USER("hit software breakpoint at 0x%08" PRIx32, eip-1); - } else { - /* it's not a hardware breakpoint (checked already in DR6 state) - * and it's also not a software breakpoint ... - */ - LOG_USER("hit unknown breakpoint at 0x%08" PRIx32, eip); - } - } else { - - /* There is also the case that we hit an breakpoint instruction, - * which was not set by us. This needs to be handled be the - * application that introduced the breakpoint. - */ - - LOG_USER("unknown break reason at 0x%08" PRIx32, eip); - } - } - - return target_call_event_callbacks(t, TARGET_EVENT_HALTED); - } - } - return ERROR_OK; -} - -int lakemont_arch_state(struct target *t) -{ - struct x86_32_common *x86_32 = target_to_x86_32(t); - - LOG_USER("target halted due to %s at 0x%08" PRIx32 " in %s mode", - debug_reason_name(t), - buf_get_u32(x86_32->cache->reg_list[EIP].value, 0, 32), - (buf_get_u32(x86_32->cache->reg_list[CR0].value, 0, 32) & CR0_PE) ? "protected" : "real"); - - return ERROR_OK; -} - -int lakemont_halt(struct target *t) -{ - if (t->state == TARGET_RUNNING) { - t->debug_reason = DBG_REASON_DBGRQ; - if (do_halt(t) != ERROR_OK) - return ERROR_FAIL; - return ERROR_OK; - } else { - LOG_ERROR("%s target not running", __func__); - return ERROR_FAIL; - } -} - -int lakemont_resume(struct target *t, int current, uint32_t address, - int handle_breakpoints, int debug_execution) -{ - struct breakpoint *bp = NULL; - struct x86_32_common *x86_32 = target_to_x86_32(t); - - if (check_not_halted(t)) - return ERROR_TARGET_NOT_HALTED; - /* TODO lakemont_enable_breakpoints(t); */ - if (t->state == TARGET_HALTED) { - - /* running away for a software breakpoint needs some special handling */ - uint32_t eip = buf_get_u32(x86_32->cache->reg_list[EIP].value, 0, 32); - bp = breakpoint_find(t, eip); - if (bp != NULL /*&& bp->type == BKPT_SOFT*/) { - /* the step will step over the breakpoint */ - if (lakemont_step(t, 0, 0, 1) != ERROR_OK) { - LOG_ERROR("%s stepping over a software breakpoint at 0x%08" PRIx32 " " - "failed to resume the target", __func__, eip); - return ERROR_FAIL; - } - } - - /* if breakpoints are enabled, we need to redirect these into probe mode */ - struct breakpoint *activeswbp = t->breakpoints; - while (activeswbp != NULL && activeswbp->set == 0) - activeswbp = activeswbp->next; - struct watchpoint *activehwbp = t->watchpoints; - while (activehwbp != NULL && activehwbp->set == 0) - activehwbp = activehwbp->next; - if (activeswbp != NULL || activehwbp != NULL) - buf_set_u32(x86_32->cache->reg_list[PMCR].value, 0, 32, 1); - if (do_resume(t) != ERROR_OK) - return ERROR_FAIL; - } else { - LOG_USER("target not halted"); - return ERROR_FAIL; - } - return ERROR_OK; -} - -int lakemont_step(struct target *t, int current, - uint32_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); - uint32_t eip = buf_get_u32(x86_32->cache->reg_list[EIP].value, 0, 32); - uint32_t pmcr = buf_get_u32(x86_32->cache->reg_list[PMCR].value, 0, 32); - struct breakpoint *bp = NULL; - int retval = ERROR_OK; - uint32_t tapstatus = 0; - - if (check_not_halted(t)) - return ERROR_TARGET_NOT_HALTED; - bp = breakpoint_find(t, eip); - if (retval == ERROR_OK && bp != NULL/*&& bp->type == BKPT_SOFT*/) { - /* TODO: This should only be done for software breakpoints. - * Stepping from hardware breakpoints should be possible with the resume flag - * Needs testing. - */ - retval = x86_32_common_remove_breakpoint(t, bp); - } - - /* Set EFLAGS[TF] and PMCR[IR], exit pm and wait for PRDY# */ - LOG_DEBUG("modifying PMCR = 0x%08" PRIx32 " and EFLAGS = 0x%08" PRIx32, pmcr, eflags); - eflags = eflags | (EFLAGS_TF | EFLAGS_RF); - buf_set_u32(x86_32->cache->reg_list[EFLAGS].value, 0, 32, eflags); - buf_set_u32(x86_32->cache->reg_list[PMCR].value, 0, 32, 1); - LOG_DEBUG("EFLAGS [TF] [RF] bits set=0x%08" PRIx32 ", PMCR=0x%08" PRIx32 ", EIP=0x%08" PRIx32, - eflags, pmcr, eip); - - tapstatus = get_tapstatus(t); - - t->debug_reason = DBG_REASON_SINGLESTEP; - t->state = TARGET_DEBUG_RUNNING; - if (restore_context(t) != ERROR_OK) - return ERROR_FAIL; - if (exit_probemode(t) != ERROR_OK) - return ERROR_FAIL; - - target_call_event_callbacks(t, TARGET_EVENT_RESUMED); - - tapstatus = get_tapstatus(t); - if (tapstatus & (TS_PM_BIT | TS_EN_PM_BIT | TS_PRDY_BIT | TS_PMCR_BIT)) { - /* target has stopped */ - if (save_context(t) != ERROR_OK) - return ERROR_FAIL; - if (halt_prep(t) != ERROR_OK) - return ERROR_FAIL; - t->state = TARGET_HALTED; - - LOG_USER("step done from EIP 0x%08" PRIx32 " to 0x%08" PRIx32, eip, - buf_get_u32(x86_32->cache->reg_list[EIP].value, 0, 32)); - target_call_event_callbacks(t, TARGET_EVENT_HALTED); - } else { - /* target didn't stop - * I hope the poll() will catch it, but the deleted breakpoint is gone - */ - LOG_ERROR("%s target didn't stop after executing a single step", __func__); - t->state = TARGET_RUNNING; - return ERROR_FAIL; - } - - /* try to re-apply the breakpoint, even of step failed - * TODO: When a bp was set, we should try to stop the target - fix the return above - */ - if (bp != NULL/*&& bp->type == BKPT_SOFT*/) { - /* TODO: This should only be done for software breakpoints. - * Stepping from hardware breakpoints should be possible with the resume flag - * Needs testing. - */ - retval = x86_32_common_add_breakpoint(t, bp); - } - - return retval; -} - -/* TODO - implement resetbreak fully through CLTAP registers */ -int lakemont_reset_assert(struct target *t) -{ - LOG_DEBUG("-"); - return ERROR_OK; -} - -int lakemont_reset_deassert(struct target *t) -{ - LOG_DEBUG("-"); - return ERROR_OK; -} diff --git a/src/target/lakemont.h b/src/target/lakemont.h deleted file mode 100644 index b07a05612..000000000 --- a/src/target/lakemont.h +++ /dev/null @@ -1,106 +0,0 @@ -/* - * 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) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - * Contact Information: - * Intel Corporation - */ - -/* - * @file - * This is the interface to the probemode operations for Lakemont 1 (LMT1). - */ - -#ifndef OPENOCD_TARGET_LAKEMONT_H -#define OPENOCD_TARGET_LAKEMONT_H - -#include -#include - -/* The Intel Quark SoC X1000 Core is codenamed lakemont */ - -#define LMT_IRLEN 8 - -/* lakemont tap instruction opcodes */ -#define IDCODE 2 -#define SUBMITPIR 3 -#define PROBEMODE 4 -#define WRPIR 6 -#define RDWRPDR 8 -#define TAPSTATUS 11 -#define BYPASS 255 -#define NOT_NULL 2 - -/* DR sizes */ -#define ID_SIZE 32 -#define PM_SIZE 1 -#define PIR_SIZE 64 -#define PDR_SIZE 32 -#define TS_SIZE 32 -#define BP_SIZE 1 -#define MAX_SCAN_SIZE PIR_SIZE - -/* needed during lakemont probemode */ -#define NOT_PMREG 0xfe -#define NOT_AVAIL_REG 0xff -#define PM_DSB ((uint32_t)0x00000000) -#define PM_DSL ((uint32_t)0xFFFFFFFF) -#define PM_DSAR ((uint32_t)0x004F9300) -#define PM_DR7 ((uint32_t)0x00000400) -#define DELAY_SUBMITPIR 0 /* for now 0 is working */ - -/* lakemont tapstatus bits */ -#define TS_PRDY_BIT ((uint32_t)0x00000001) -#define TS_EN_PM_BIT ((uint32_t)0x00000002) -#define TS_PM_BIT ((uint32_t)0x00000004) -#define TS_PMCR_BIT ((uint32_t)0x00000008) -#define TS_SBP_BIT ((uint32_t)0x00000010) - -struct lakemont_core_reg { - uint32_t num; - struct target *target; - struct x86_32_common *x86_32_common; - uint64_t op; - uint8_t pm_idx; -}; - -struct scan_blk { - uint8_t out[MAX_SCAN_SIZE]; /* scanned out to the tap */ - uint8_t in[MAX_SCAN_SIZE]; /* in to our capture buf */ - struct scan_field field; -}; - -#define I(name) (((struct lakemont_core_reg *)x86_32->cache->reg_list[name].arch_info)->pm_idx) - -int lakemont_init_target(struct command_context *cmd_ctx, struct target *t); -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 handle_breakpoints, int debug_execution); -int lakemont_step(struct target *t, int current, - uint32_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 /* OPENOCD_TARGET_LAKEMONT_H */ diff --git a/src/target/ls1_sap.c b/src/target/ls1_sap.c deleted file mode 100644 index 944e72520..000000000 --- a/src/target/ls1_sap.c +++ /dev/null @@ -1,243 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2015 by Esben Haabendal * - * eha@deif.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "target.h" -#include "target_type.h" - -#include - -struct ls1_sap { - struct jtag_tap *tap; -}; - -static int ls1_sap_target_create(struct target *target, Jim_Interp *interp) -{ - struct ls1_sap *ls1_sap = calloc(1, sizeof(struct ls1_sap)); - - ls1_sap->tap = target->tap; - target->arch_info = ls1_sap; - - return ERROR_OK; -} - -static int ls1_sap_init_target(struct command_context *cmd_ctx, struct target *target) -{ - LOG_DEBUG("%s", __func__); - return ERROR_OK; -} - -static int ls1_sap_arch_state(struct target *target) -{ - LOG_DEBUG("%s", __func__); - return ERROR_OK; -} - -static int ls1_sap_poll(struct target *target) -{ - if ((target->state == TARGET_UNKNOWN) || - (target->state == TARGET_RUNNING) || - (target->state == TARGET_DEBUG_RUNNING)) - target->state = TARGET_HALTED; - - return ERROR_OK; -} - -static int ls1_sap_halt(struct target *target) -{ - LOG_DEBUG("%s", __func__); - return ERROR_OK; -} - -static int ls1_sap_resume(struct target *target, int current, uint32_t address, - int handle_breakpoints, int debug_execution) -{ - LOG_DEBUG("%s", __func__); - return ERROR_OK; -} - -static int ls1_sap_step(struct target *target, int current, uint32_t address, - int handle_breakpoints) -{ - LOG_DEBUG("%s", __func__); - return ERROR_OK; -} - -static int ls1_sap_assert_reset(struct target *target) -{ - target->state = TARGET_RESET; - - LOG_DEBUG("%s", __func__); - return ERROR_OK; -} - -static int ls1_sap_deassert_reset(struct target *target) -{ - target->state = TARGET_RUNNING; - - LOG_DEBUG("%s", __func__); - return ERROR_OK; -} - -static void ls1_sap_set_instr(struct jtag_tap *tap, uint32_t new_instr) -{ - struct scan_field field; - - if (buf_get_u32(tap->cur_instr, 0, tap->ir_length) == new_instr) - return; - - field.num_bits = tap->ir_length; - uint8_t *t = calloc(DIV_ROUND_UP(field.num_bits, 8), 1); - 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); - free(t); -} - -static void ls1_sap_set_addr_high(struct jtag_tap *tap, uint16_t addr_high) -{ - struct scan_field field; - uint8_t buf[2]; - - ls1_sap_set_instr(tap, 0x21); - - field.num_bits = 16; - field.out_value = buf; - buf_set_u32(buf, 0, 16, addr_high); - field.in_value = NULL; - field.check_value = NULL; - field.check_mask = NULL; - jtag_add_dr_scan(tap, 1, &field, TAP_IDLE); -} - -static void ls1_sap_memory_cmd(struct jtag_tap *tap, uint32_t address, - int32_t size, int read) -{ - struct scan_field field; - uint8_t cmd[8]; - - ls1_sap_set_instr(tap, 0x24); - - field.num_bits = 64; - field.out_value = cmd; - buf_set_u64(cmd, 0, 9, 0); - buf_set_u64(cmd, 9, 3, size); - buf_set_u64(cmd, 12, 1, !!read); - buf_set_u64(cmd, 13, 3, 0); - buf_set_u64(cmd, 16, 32, address); - buf_set_u64(cmd, 48, 16, 0); - field.in_value = NULL; - field.check_value = NULL; - field.check_mask = NULL; - jtag_add_dr_scan(tap, 1, &field, TAP_IDLE); -} - -static void ls1_sap_memory_read(struct jtag_tap *tap, uint32_t size, - uint8_t *value) -{ - struct scan_field field; - - ls1_sap_set_instr(tap, 0x25); - - field.num_bits = 8 * size; - field.out_value = NULL; - field.in_value = value; - field.check_value = NULL; - field.check_mask = NULL; - jtag_add_dr_scan(tap, 1, &field, TAP_IDLE); -} - -static void ls1_sap_memory_write(struct jtag_tap *tap, uint32_t size, - const uint8_t *value) -{ - struct scan_field field; - - ls1_sap_set_instr(tap, 0x25); - - field.num_bits = 8 * size; - field.out_value = value; - field.in_value = NULL; - field.check_value = NULL; - field.check_mask = NULL; - jtag_add_dr_scan(tap, 1, &field, TAP_IDLE); -} - -static int ls1_sap_read_memory(struct target *target, uint32_t address, - uint32_t size, uint32_t count, uint8_t *buffer) -{ - LOG_DEBUG("Reading memory at physical address 0x%" PRIx32 - "; size %" PRId32 "; count %" PRId32, address, size, count); - - if (count == 0 || buffer == NULL) - return ERROR_COMMAND_SYNTAX_ERROR; - - ls1_sap_set_addr_high(target->tap, 0); - - while (count--) { - ls1_sap_memory_cmd(target->tap, address, size, 1); - ls1_sap_memory_read(target->tap, size, buffer); - address += size; - buffer += size; - } - - return jtag_execute_queue(); -} - -static int ls1_sap_write_memory(struct target *target, uint32_t address, - uint32_t size, uint32_t count, - const uint8_t *buffer) -{ - LOG_DEBUG("Writing memory at physical address 0x%" PRIx32 - "; size %" PRId32 "; count %" PRId32, address, size, count); - - - if (count == 0 || buffer == NULL) - return ERROR_COMMAND_SYNTAX_ERROR; - - ls1_sap_set_addr_high(target->tap, 0); - - while (count--) { - ls1_sap_memory_cmd(target->tap, address, size, 0); - ls1_sap_memory_write(target->tap, size, buffer); - address += size; - buffer += size; - } - - return jtag_execute_queue(); -} - -struct target_type ls1_sap_target = { - .name = "ls1_sap", - - .target_create = ls1_sap_target_create, - .init_target = ls1_sap_init_target, - - .poll = ls1_sap_poll, - .arch_state = ls1_sap_arch_state, - - .halt = ls1_sap_halt, - .resume = ls1_sap_resume, - .step = ls1_sap_step, - - .assert_reset = ls1_sap_assert_reset, - .deassert_reset = ls1_sap_deassert_reset, - - .read_memory = ls1_sap_read_memory, - .write_memory = ls1_sap_write_memory, -}; diff --git a/src/target/mips32.c b/src/target/mips32.c deleted file mode 100644 index 329244655..000000000 --- a/src/target/mips32.c +++ /dev/null @@ -1,952 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2008 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * Copyright (C) 2008 by David T.L. Wong * - * * - * Copyright (C) 2007,2008 Øyvind Harboe * - * oyvind.harboe@zylin.com * - * * - * Copyright (C) 2011 by Drasko DRASKOVIC * - * drasko.draskovic@gmail.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "mips32.h" -#include "breakpoints.h" -#include "algorithm.h" -#include "register.h" - -static const char *mips_isa_strings[] = { - "MIPS32", "MIPS16" -}; - -#define MIPS32_GDB_DUMMY_FP_REG 1 - -/* - * GDB registers - * based on gdb-7.6.2/gdb/features/mips-{fpu,cp0,cpu}.xml - */ -static const struct { - unsigned id; - const char *name; - enum reg_type type; - const char *group; - const char *feature; - int flag; -} mips32_regs[] = { - { 0, "r0", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 }, - { 1, "r1", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 }, - { 2, "r2", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 }, - { 3, "r3", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 }, - { 4, "r4", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 }, - { 5, "r5", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 }, - { 6, "r6", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 }, - { 7, "r7", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 }, - { 8, "r8", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 }, - { 9, "r9", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 }, - { 10, "r10", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 }, - { 11, "r11", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 }, - { 12, "r12", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 }, - { 13, "r13", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 }, - { 14, "r14", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 }, - { 15, "r15", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 }, - { 16, "r16", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 }, - { 17, "r17", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 }, - { 18, "r18", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 }, - { 19, "r19", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 }, - { 20, "r20", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 }, - { 21, "r21", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 }, - { 22, "r22", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 }, - { 23, "r23", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 }, - { 24, "r24", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 }, - { 25, "r25", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 }, - { 26, "r26", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 }, - { 27, "r27", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 }, - { 28, "r28", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 }, - { 29, "r29", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 }, - { 30, "r30", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 }, - { 31, "r31", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 }, - { 32, "status", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cp0", 0 }, - { 33, "lo", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 }, - { 34, "hi", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 }, - { 35, "badvaddr", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cp0", 0 }, - { 36, "cause", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cp0", 0 }, - { 37, "pc", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 }, - - { 38, "f0", REG_TYPE_IEEE_SINGLE, NULL, - "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG }, - { 39, "f1", REG_TYPE_IEEE_SINGLE, NULL, - "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG }, - { 40, "f2", REG_TYPE_IEEE_SINGLE, NULL, - "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG }, - { 41, "f3", REG_TYPE_IEEE_SINGLE, NULL, - "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG }, - { 42, "f4", REG_TYPE_IEEE_SINGLE, NULL, - "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG }, - { 43, "f5", REG_TYPE_IEEE_SINGLE, NULL, - "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG }, - { 44, "f6", REG_TYPE_IEEE_SINGLE, NULL, - "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG }, - { 45, "f7", REG_TYPE_IEEE_SINGLE, NULL, - "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG }, - { 46, "f8", REG_TYPE_IEEE_SINGLE, NULL, - "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG }, - { 47, "f9", REG_TYPE_IEEE_SINGLE, NULL, - "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG }, - { 48, "f10", REG_TYPE_IEEE_SINGLE, NULL, - "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG }, - { 49, "f11", REG_TYPE_IEEE_SINGLE, NULL, - "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG }, - { 50, "f12", REG_TYPE_IEEE_SINGLE, NULL, - "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG }, - { 51, "f13", REG_TYPE_IEEE_SINGLE, NULL, - "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG }, - { 52, "f14", REG_TYPE_IEEE_SINGLE, NULL, - "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG }, - { 53, "f15", REG_TYPE_IEEE_SINGLE, NULL, - "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG }, - { 54, "f16", REG_TYPE_IEEE_SINGLE, NULL, - "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG }, - { 55, "f17", REG_TYPE_IEEE_SINGLE, NULL, - "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG }, - { 56, "f18", REG_TYPE_IEEE_SINGLE, NULL, - "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG }, - { 57, "f19", REG_TYPE_IEEE_SINGLE, NULL, - "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG }, - { 58, "f20", REG_TYPE_IEEE_SINGLE, NULL, - "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG }, - { 59, "f21", REG_TYPE_IEEE_SINGLE, NULL, - "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG }, - { 60, "f22", REG_TYPE_IEEE_SINGLE, NULL, - "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG }, - { 61, "f23", REG_TYPE_IEEE_SINGLE, NULL, - "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG }, - { 62, "f24", REG_TYPE_IEEE_SINGLE, NULL, - "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG }, - { 63, "f25", REG_TYPE_IEEE_SINGLE, NULL, - "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG }, - { 64, "f26", REG_TYPE_IEEE_SINGLE, NULL, - "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG }, - { 65, "f27", REG_TYPE_IEEE_SINGLE, NULL, - "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG }, - { 66, "f28", REG_TYPE_IEEE_SINGLE, NULL, - "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG }, - { 67, "f29", REG_TYPE_IEEE_SINGLE, NULL, - "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG }, - { 68, "f30", REG_TYPE_IEEE_SINGLE, NULL, - "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG }, - { 69, "f31", REG_TYPE_IEEE_SINGLE, NULL, - "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG }, - { 70, "fcsr", REG_TYPE_INT, "float", - "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG }, - { 71, "fir", REG_TYPE_INT, "float", - "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG }, -}; - - -#define MIPS32_NUM_REGS ARRAY_SIZE(mips32_regs) - -static uint8_t mips32_gdb_dummy_fp_value[] = {0, 0, 0, 0}; - -static int mips32_get_core_reg(struct reg *reg) -{ - int retval; - struct mips32_core_reg *mips32_reg = reg->arch_info; - struct target *target = mips32_reg->target; - struct mips32_common *mips32_target = target_to_mips32(target); - - if (target->state != TARGET_HALTED) - return ERROR_TARGET_NOT_HALTED; - - retval = mips32_target->read_core_reg(target, mips32_reg->num); - - return retval; -} - -static int mips32_set_core_reg(struct reg *reg, uint8_t *buf) -{ - struct mips32_core_reg *mips32_reg = reg->arch_info; - struct target *target = mips32_reg->target; - uint32_t value = buf_get_u32(buf, 0, 32); - - if (target->state != TARGET_HALTED) - return ERROR_TARGET_NOT_HALTED; - - buf_set_u32(reg->value, 0, 32, value); - reg->dirty = 1; - reg->valid = 1; - - return ERROR_OK; -} - -static int mips32_read_core_reg(struct target *target, unsigned int num) -{ - uint32_t reg_value; - - /* get pointers to arch-specific information */ - struct mips32_common *mips32 = target_to_mips32(target); - - if (num >= MIPS32_NUM_REGS) - return ERROR_COMMAND_SYNTAX_ERROR; - - reg_value = mips32->core_regs[num]; - buf_set_u32(mips32->core_cache->reg_list[num].value, 0, 32, reg_value); - mips32->core_cache->reg_list[num].valid = 1; - mips32->core_cache->reg_list[num].dirty = 0; - - return ERROR_OK; -} - -static int mips32_write_core_reg(struct target *target, unsigned int num) -{ - uint32_t reg_value; - - /* get pointers to arch-specific information */ - struct mips32_common *mips32 = target_to_mips32(target); - - if (num >= MIPS32_NUM_REGS) - return ERROR_COMMAND_SYNTAX_ERROR; - - reg_value = buf_get_u32(mips32->core_cache->reg_list[num].value, 0, 32); - mips32->core_regs[num] = reg_value; - LOG_DEBUG("write core reg %i value 0x%" PRIx32 "", num , reg_value); - mips32->core_cache->reg_list[num].valid = 1; - mips32->core_cache->reg_list[num].dirty = 0; - - return ERROR_OK; -} - -int mips32_get_gdb_reg_list(struct target *target, struct reg **reg_list[], - int *reg_list_size, enum target_register_class reg_class) -{ - /* get pointers to arch-specific information */ - struct mips32_common *mips32 = target_to_mips32(target); - unsigned int i; - - /* include floating point registers */ - *reg_list_size = MIPS32_NUM_REGS; - *reg_list = malloc(sizeof(struct reg *) * (*reg_list_size)); - - for (i = 0; i < MIPS32_NUM_REGS; i++) - (*reg_list)[i] = &mips32->core_cache->reg_list[i]; - - return ERROR_OK; -} - -int mips32_save_context(struct target *target) -{ - unsigned int i; - - /* get pointers to arch-specific information */ - struct mips32_common *mips32 = target_to_mips32(target); - struct mips_ejtag *ejtag_info = &mips32->ejtag_info; - - /* read core registers */ - mips32_pracc_read_regs(ejtag_info, mips32->core_regs); - - for (i = 0; i < MIPS32_NUM_REGS; i++) { - if (!mips32->core_cache->reg_list[i].valid) - mips32->read_core_reg(target, i); - } - - return ERROR_OK; -} - -int mips32_restore_context(struct target *target) -{ - unsigned int i; - - /* get pointers to arch-specific information */ - struct mips32_common *mips32 = target_to_mips32(target); - struct mips_ejtag *ejtag_info = &mips32->ejtag_info; - - for (i = 0; i < MIPS32_NUM_REGS; i++) { - if (mips32->core_cache->reg_list[i].dirty) - mips32->write_core_reg(target, i); - } - - /* write core regs */ - mips32_pracc_write_regs(ejtag_info, mips32->core_regs); - - return ERROR_OK; -} - -int mips32_arch_state(struct target *target) -{ - struct mips32_common *mips32 = target_to_mips32(target); - - LOG_USER("target halted in %s mode due to %s, pc: 0x%8.8" PRIx32 "", - mips_isa_strings[mips32->isa_mode], - debug_reason_name(target), - buf_get_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 32)); - - return ERROR_OK; -} - -static const struct reg_arch_type mips32_reg_type = { - .get = mips32_get_core_reg, - .set = mips32_set_core_reg, -}; - -struct reg_cache *mips32_build_reg_cache(struct target *target) -{ - /* get pointers to arch-specific information */ - struct mips32_common *mips32 = target_to_mips32(target); - - int num_regs = MIPS32_NUM_REGS; - struct reg_cache **cache_p = register_get_last_cache_p(&target->reg_cache); - struct reg_cache *cache = malloc(sizeof(struct reg_cache)); - struct reg *reg_list = calloc(num_regs, sizeof(struct reg)); - struct mips32_core_reg *arch_info = malloc(sizeof(struct mips32_core_reg) * num_regs); - struct reg_feature *feature; - int i; - - /* Build the process context cache */ - cache->name = "mips32 registers"; - cache->next = NULL; - cache->reg_list = reg_list; - cache->num_regs = num_regs; - (*cache_p) = cache; - mips32->core_cache = cache; - - for (i = 0; i < num_regs; i++) { - arch_info[i].num = mips32_regs[i].id; - arch_info[i].target = target; - arch_info[i].mips32_common = mips32; - - reg_list[i].name = mips32_regs[i].name; - reg_list[i].size = 32; - - if (mips32_regs[i].flag == MIPS32_GDB_DUMMY_FP_REG) { - reg_list[i].value = mips32_gdb_dummy_fp_value; - reg_list[i].valid = 1; - reg_list[i].arch_info = NULL; - register_init_dummy(®_list[i]); - } else { - reg_list[i].value = calloc(1, 4); - reg_list[i].valid = 0; - reg_list[i].type = &mips32_reg_type; - reg_list[i].arch_info = &arch_info[i]; - - reg_list[i].reg_data_type = calloc(1, sizeof(struct reg_data_type)); - if (reg_list[i].reg_data_type) - reg_list[i].reg_data_type->type = mips32_regs[i].type; - else - LOG_ERROR("unable to allocate reg type list"); - } - - reg_list[i].dirty = 0; - - reg_list[i].group = mips32_regs[i].group; - reg_list[i].number = i; - reg_list[i].exist = true; - reg_list[i].caller_save = true; /* gdb defaults to true */ - - feature = calloc(1, sizeof(struct reg_feature)); - if (feature) { - feature->name = mips32_regs[i].feature; - reg_list[i].feature = feature; - } else - LOG_ERROR("unable to allocate feature list"); - } - - return cache; -} - -int mips32_init_arch_info(struct target *target, struct mips32_common *mips32, struct jtag_tap *tap) -{ - target->arch_info = mips32; - mips32->common_magic = MIPS32_COMMON_MAGIC; - mips32->fast_data_area = NULL; - - /* has breakpoint/watchpoint unit been scanned */ - mips32->bp_scanned = 0; - mips32->data_break_list = NULL; - - 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 */ - mips32->ejtag_info.mode = 0; /* Initial default value */ - - 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) -{ - uint32_t pc; - int retval; - /* This code relies on the target specific resume() and poll()->debug_entry() - * sequence to write register values to the processor and the read them back */ - retval = target_resume(target, 0, entry_point, 0, 1); - if (retval != ERROR_OK) - return retval; - - retval = target_wait_state(target, TARGET_HALTED, timeout_ms); - /* If the target fails to halt due to the breakpoint, force a halt */ - if (retval != ERROR_OK || target->state != TARGET_HALTED) { - retval = target_halt(target); - if (retval != ERROR_OK) - return retval; - retval = target_wait_state(target, TARGET_HALTED, 500); - if (retval != ERROR_OK) - return retval; - return ERROR_TARGET_TIMEOUT; - } - - pc = buf_get_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 32); - if (exit_point && (pc != exit_point)) { - LOG_DEBUG("failed algorithm halted at 0x%" PRIx32 " ", pc); - return ERROR_TARGET_TIMEOUT; - } - - return ERROR_OK; -} - -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 mips32_common *mips32 = target_to_mips32(target); - struct mips32_algorithm *mips32_algorithm_info = arch_info; - enum mips32_isa_mode isa_mode = mips32->isa_mode; - - uint32_t context[MIPS32_NUM_REGS]; - int retval = ERROR_OK; - - LOG_DEBUG("Running algorithm"); - - /* NOTE: mips32_run_algorithm requires that each algorithm uses a software breakpoint - * at the exit point */ - - if (mips32->common_magic != MIPS32_COMMON_MAGIC) { - LOG_ERROR("current target isn't a MIPS32 target"); - return ERROR_TARGET_INVALID; - } - - if (target->state != TARGET_HALTED) { - LOG_WARNING("target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - /* refresh core register cache */ - for (unsigned int i = 0; i < MIPS32_NUM_REGS; i++) { - if (!mips32->core_cache->reg_list[i].valid) - mips32->read_core_reg(target, i); - context[i] = buf_get_u32(mips32->core_cache->reg_list[i].value, 0, 32); - } - - for (int i = 0; i < num_mem_params; i++) { - retval = target_write_buffer(target, mem_params[i].address, - mem_params[i].size, mem_params[i].value); - if (retval != ERROR_OK) - return retval; - } - - for (int i = 0; i < num_reg_params; i++) { - struct reg *reg = register_get_by_name(mips32->core_cache, reg_params[i].reg_name, 0); - - if (!reg) { - LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name); - return ERROR_COMMAND_SYNTAX_ERROR; - } - - if (reg->size != reg_params[i].size) { - LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size", - reg_params[i].reg_name); - return ERROR_COMMAND_SYNTAX_ERROR; - } - - mips32_set_core_reg(reg, reg_params[i].value); - } - - mips32->isa_mode = mips32_algorithm_info->isa_mode; - - retval = mips32_run_and_wait(target, entry_point, timeout_ms, exit_point, mips32); - - if (retval != ERROR_OK) - return retval; - - for (int i = 0; i < num_mem_params; i++) { - if (mem_params[i].direction != PARAM_OUT) { - retval = target_read_buffer(target, mem_params[i].address, mem_params[i].size, - mem_params[i].value); - if (retval != ERROR_OK) - return retval; - } - } - - for (int i = 0; i < num_reg_params; i++) { - if (reg_params[i].direction != PARAM_OUT) { - struct reg *reg = register_get_by_name(mips32->core_cache, reg_params[i].reg_name, 0); - if (!reg) { - LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name); - return ERROR_COMMAND_SYNTAX_ERROR; - } - - if (reg->size != reg_params[i].size) { - LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size", - reg_params[i].reg_name); - return ERROR_COMMAND_SYNTAX_ERROR; - } - - buf_set_u32(reg_params[i].value, 0, 32, buf_get_u32(reg->value, 0, 32)); - } - } - - /* restore everything we saved before */ - for (unsigned int i = 0; i < MIPS32_NUM_REGS; i++) { - uint32_t regvalue; - regvalue = buf_get_u32(mips32->core_cache->reg_list[i].value, 0, 32); - if (regvalue != context[i]) { - LOG_DEBUG("restoring register %s with value 0x%8.8" PRIx32, - mips32->core_cache->reg_list[i].name, context[i]); - buf_set_u32(mips32->core_cache->reg_list[i].value, - 0, 32, context[i]); - mips32->core_cache->reg_list[i].valid = 1; - mips32->core_cache->reg_list[i].dirty = 1; - } - } - - mips32->isa_mode = isa_mode; - - return ERROR_OK; -} - -int mips32_examine(struct target *target) -{ - struct mips32_common *mips32 = target_to_mips32(target); - - if (!target_was_examined(target)) { - target_set_examined(target); - - /* we will configure later */ - mips32->bp_scanned = 0; - mips32->num_inst_bpoints = 0; - mips32->num_data_bpoints = 0; - mips32->num_inst_bpoints_avail = 0; - mips32->num_data_bpoints_avail = 0; - } - - return ERROR_OK; -} - -static int mips32_configure_ibs(struct target *target) -{ - struct mips32_common *mips32 = target_to_mips32(target); - struct mips_ejtag *ejtag_info = &mips32->ejtag_info; - int retval, i; - uint32_t bpinfo; - - /* get number of inst breakpoints */ - retval = target_read_u32(target, ejtag_info->ejtag_ibs_addr, &bpinfo); - if (retval != ERROR_OK) - return retval; - - mips32->num_inst_bpoints = (bpinfo >> 24) & 0x0F; - mips32->num_inst_bpoints_avail = mips32->num_inst_bpoints; - mips32->inst_break_list = calloc(mips32->num_inst_bpoints, - sizeof(struct mips32_comparator)); - - for (i = 0; i < mips32->num_inst_bpoints; i++) - mips32->inst_break_list[i].reg_address = - ejtag_info->ejtag_iba0_addr + - (ejtag_info->ejtag_iba_step_size * i); - - /* clear IBIS reg */ - retval = target_write_u32(target, ejtag_info->ejtag_ibs_addr, 0); - return retval; -} - -static int mips32_configure_dbs(struct target *target) -{ - struct mips32_common *mips32 = target_to_mips32(target); - struct mips_ejtag *ejtag_info = &mips32->ejtag_info; - int retval, i; - uint32_t bpinfo; - - /* get number of data breakpoints */ - retval = target_read_u32(target, ejtag_info->ejtag_dbs_addr, &bpinfo); - if (retval != ERROR_OK) - return retval; - - mips32->num_data_bpoints = (bpinfo >> 24) & 0x0F; - mips32->num_data_bpoints_avail = mips32->num_data_bpoints; - mips32->data_break_list = calloc(mips32->num_data_bpoints, - sizeof(struct mips32_comparator)); - - for (i = 0; i < mips32->num_data_bpoints; i++) - mips32->data_break_list[i].reg_address = - ejtag_info->ejtag_dba0_addr + - (ejtag_info->ejtag_dba_step_size * i); - - /* clear DBIS reg */ - retval = target_write_u32(target, ejtag_info->ejtag_dbs_addr, 0); - return retval; -} - -int mips32_configure_break_unit(struct target *target) -{ - /* get pointers to arch-specific information */ - struct mips32_common *mips32 = target_to_mips32(target); - struct mips_ejtag *ejtag_info = &mips32->ejtag_info; - int retval; - uint32_t dcr; - - if (mips32->bp_scanned) - return ERROR_OK; - - /* get info about breakpoint support */ - retval = target_read_u32(target, EJTAG_DCR, &dcr); - if (retval != ERROR_OK) - return retval; - - /* EJTAG 2.0 defines IB and DB bits in IMP instead of DCR. */ - if (ejtag_info->ejtag_version == EJTAG_VERSION_20) { - ejtag_info->debug_caps = dcr & EJTAG_DCR_ENM; - if (!(ejtag_info->impcode & EJTAG_V20_IMP_NOIB)) - ejtag_info->debug_caps |= EJTAG_DCR_IB; - if (!(ejtag_info->impcode & EJTAG_V20_IMP_NODB)) - ejtag_info->debug_caps |= EJTAG_DCR_DB; - } else - /* keep debug caps for later use */ - ejtag_info->debug_caps = dcr & (EJTAG_DCR_ENM - | EJTAG_DCR_IB | EJTAG_DCR_DB); - - - if (ejtag_info->debug_caps & EJTAG_DCR_IB) { - retval = mips32_configure_ibs(target); - if (retval != ERROR_OK) - return retval; - } - - if (ejtag_info->debug_caps & EJTAG_DCR_DB) { - retval = mips32_configure_dbs(target); - if (retval != ERROR_OK) - return retval; - } - - /* check if target endianness settings matches debug control register */ - if (((ejtag_info->debug_caps & EJTAG_DCR_ENM) - && (target->endianness == TARGET_LITTLE_ENDIAN)) || - (!(ejtag_info->debug_caps & EJTAG_DCR_ENM) - && (target->endianness == TARGET_BIG_ENDIAN))) - LOG_WARNING("DCR endianness settings does not match target settings"); - - LOG_DEBUG("DCR 0x%" PRIx32 " numinst %i numdata %i", dcr, mips32->num_inst_bpoints, - mips32->num_data_bpoints); - - mips32->bp_scanned = 1; - - return ERROR_OK; -} - -int mips32_enable_interrupts(struct target *target, int enable) -{ - int retval; - int update = 0; - uint32_t dcr; - - /* read debug control register */ - retval = target_read_u32(target, EJTAG_DCR, &dcr); - if (retval != ERROR_OK) - return retval; - - if (enable) { - if (!(dcr & EJTAG_DCR_INTE)) { - /* enable interrupts */ - dcr |= EJTAG_DCR_INTE; - update = 1; - } - } else { - if (dcr & EJTAG_DCR_INTE) { - /* disable interrupts */ - dcr &= ~EJTAG_DCR_INTE; - update = 1; - } - } - - if (update) { - retval = target_write_u32(target, EJTAG_DCR, dcr); - if (retval != ERROR_OK) - return retval; - } - - return ERROR_OK; -} - -int mips32_checksum_memory(struct target *target, uint32_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 */ - - 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 */ - /* 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 */ - }; - - /* 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; - - /* 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); - - mips32_info.common_magic = MIPS32_COMMON_MAGIC; - mips32_info.isa_mode = MIPS32_ISA_MIPS32; - - init_reg_param(®_params[0], "r4", 32, PARAM_IN_OUT); - buf_set_u32(reg_params[0].value, 0, 32, address); - - init_reg_param(®_params[1], "r5", 32, PARAM_OUT); - buf_set_u32(reg_params[1].value, 0, 32, count); - - 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); - - if (retval == ERROR_OK) - *checksum = buf_get_u32(reg_params[0].value, 0, 32); - - destroy_reg_param(®_params[0]); - destroy_reg_param(®_params[1]); - - target_free_working_area(target, crc_algorithm); - - return retval; -} - -/** Checks whether a memory region is zeroed. */ -int mips32_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 mips32_algorithm mips32_info; - - static const 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 */ - }; - - /* 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; - - /* 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); - - mips32_info.common_magic = MIPS32_COMMON_MAGIC; - mips32_info.isa_mode = MIPS32_ISA_MIPS32; - - init_reg_param(®_params[0], "r4", 32, PARAM_OUT); - buf_set_u32(reg_params[0].value, 0, 32, address); - - init_reg_param(®_params[1], "r5", 32, PARAM_OUT); - 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); - - 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); - - 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 mips32_verify_pointer(struct command_context *cmd_ctx, - struct mips32_common *mips32) -{ - if (mips32->common_magic != MIPS32_COMMON_MAGIC) { - command_print(cmd_ctx, "target is not an MIPS32"); - return ERROR_TARGET_INVALID; - } - return ERROR_OK; -} - -/** - * MIPS32 targets expose command interface - * to manipulate CP0 registers - */ -COMMAND_HANDLER(mips32_handle_cp0_command) -{ - int retval; - struct target *target = get_current_target(CMD_CTX); - struct mips32_common *mips32 = target_to_mips32(target); - struct mips_ejtag *ejtag_info = &mips32->ejtag_info; - - - retval = mips32_verify_pointer(CMD_CTX, mips32); - if (retval != ERROR_OK) - return retval; - - if (target->state != TARGET_HALTED) { - command_print(CMD_CTX, "target must be stopped for \"%s\" command", CMD_NAME); - return ERROR_OK; - } - - /* two or more argument, access a single register/select (write if third argument is given) */ - if (CMD_ARGC < 2) - return ERROR_COMMAND_SYNTAX_ERROR; - else { - uint32_t cp0_reg, cp0_sel; - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], cp0_reg); - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], cp0_sel); - - if (CMD_ARGC == 2) { - uint32_t value; - - retval = mips32_cp0_read(ejtag_info, &value, cp0_reg, cp0_sel); - if (retval != ERROR_OK) { - command_print(CMD_CTX, - "couldn't access reg %" PRIi32, - cp0_reg); - return ERROR_OK; - } - command_print(CMD_CTX, "cp0 reg %" PRIi32 ", select %" PRIi32 ": %8.8" PRIx32, - cp0_reg, cp0_sel, value); - - } else if (CMD_ARGC == 3) { - uint32_t value; - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], value); - retval = mips32_cp0_write(ejtag_info, value, cp0_reg, cp0_sel); - if (retval != ERROR_OK) { - command_print(CMD_CTX, - "couldn't access cp0 reg %" PRIi32 ", select %" PRIi32, - cp0_reg, cp0_sel); - return ERROR_OK; - } - command_print(CMD_CTX, "cp0 reg %" PRIi32 ", select %" PRIi32 ": %8.8" PRIx32, - cp0_reg, cp0_sel, value); - } - } - - return ERROR_OK; -} - -COMMAND_HANDLER(mips32_handle_scan_delay_command) -{ - struct target *target = get_current_target(CMD_CTX); - struct mips32_common *mips32 = target_to_mips32(target); - struct mips_ejtag *ejtag_info = &mips32->ejtag_info; - - if (CMD_ARGC == 1) - COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], ejtag_info->scan_delay); - else if (CMD_ARGC > 1) - return ERROR_COMMAND_SYNTAX_ERROR; - - command_print(CMD_CTX, "scan delay: %d nsec", ejtag_info->scan_delay); - if (ejtag_info->scan_delay >= 2000000) { - ejtag_info->mode = 0; - command_print(CMD_CTX, "running in legacy mode"); - } else { - ejtag_info->mode = 1; - command_print(CMD_CTX, "running in fast queued mode"); - } - - return ERROR_OK; -} - -static const struct command_registration mips32_exec_command_handlers[] = { - { - .name = "cp0", - .handler = mips32_handle_cp0_command, - .mode = COMMAND_EXEC, - .usage = "regnum select [value]", - .help = "display/modify cp0 register", - }, - { - .name = "scan_delay", - .handler = mips32_handle_scan_delay_command, - .mode = COMMAND_ANY, - .help = "display/set scan delay in nano seconds", - .usage = "[value]", - }, - COMMAND_REGISTRATION_DONE -}; - -const struct command_registration mips32_command_handlers[] = { - { - .name = "mips32", - .mode = COMMAND_ANY, - .help = "mips32 command group", - .usage = "", - .chain = mips32_exec_command_handlers, - }, - COMMAND_REGISTRATION_DONE -}; diff --git a/src/target/mips32.h b/src/target/mips32.h deleted file mode 100644 index bfd2cf56e..000000000 --- a/src/target/mips32.h +++ /dev/null @@ -1,252 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2008 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * Copyright (C) 2008 by David T.L. Wong * - * * - * Copyright (C) 2011 by Drasko DRASKOVIC * - * drasko.draskovic@gmail.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifndef OPENOCD_TARGET_MIPS32_H -#define OPENOCD_TARGET_MIPS32_H - -#include "target.h" -#include "mips32_pracc.h" - -#define MIPS32_COMMON_MAGIC 0xB320B320 - -/** - * Memory segments (32bit kernel mode addresses) - * These are the traditional names used in the 32-bit universe. - */ -#define KUSEG 0x00000000 -#define KSEG0 0x80000000 -#define KSEG1 0xa0000000 -#define KSEG2 0xc0000000 -#define KSEG3 0xe0000000 - -/** Returns the kernel segment base of a given address */ -#define KSEGX(a) ((a) & 0xe0000000) - -/** CP0 CONFIG regites fields */ -#define MIPS32_CONFIG0_KU_SHIFT 25 -#define MIPS32_CONFIG0_KU_MASK (0x7 << MIPS32_CONFIG0_KU_SHIFT) - -#define MIPS32_CONFIG0_K0_SHIFT 0 -#define MIPS32_CONFIG0_K0_MASK (0x7 << MIPS32_CONFIG0_K0_SHIFT) - -#define MIPS32_CONFIG0_K23_SHIFT 28 -#define MIPS32_CONFIG0_K23_MASK (0x7 << MIPS32_CONFIG0_K23_SHIFT) - -#define MIPS32_CONFIG0_AR_SHIFT 10 -#define MIPS32_CONFIG0_AR_MASK (0x7 << MIPS32_CONFIG0_AR_SHIFT) - -#define MIPS32_CONFIG1_DL_SHIFT 10 -#define MIPS32_CONFIG1_DL_MASK (0x7 << MIPS32_CONFIG1_DL_SHIFT) - -#define MIPS32_ARCH_REL1 0x0 -#define MIPS32_ARCH_REL2 0x1 - -/* offsets into mips32 core register cache */ -enum { - MIPS32_PC = 37, - MIPS32_FIR = 71, - MIPS32NUMCOREREGS -}; - -enum mips32_isa_mode { - MIPS32_ISA_MIPS32 = 0, - MIPS32_ISA_MIPS16E = 1, -}; - -struct mips32_comparator { - int used; - uint32_t bp_value; - uint32_t reg_address; -}; - -struct mips32_common { - uint32_t common_magic; - void *arch_info; - struct reg_cache *core_cache; - struct mips_ejtag ejtag_info; - uint32_t core_regs[MIPS32NUMCOREREGS]; - enum mips32_isa_mode isa_mode; - - /* working area for fastdata access */ - struct working_area *fast_data_area; - - int bp_scanned; - int num_inst_bpoints; - int num_data_bpoints; - int num_inst_bpoints_avail; - int num_data_bpoints_avail; - struct mips32_comparator *inst_break_list; - struct mips32_comparator *data_break_list; - - /* register cache to processor synchronization */ - int (*read_core_reg)(struct target *target, unsigned int num); - int (*write_core_reg)(struct target *target, unsigned int num); -}; - -static inline struct mips32_common * -target_to_mips32(struct target *target) -{ - return target->arch_info; -} - -struct mips32_core_reg { - uint32_t num; - struct target *target; - struct mips32_common *mips32_common; -}; - -struct mips32_algorithm { - int common_magic; - 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_R_INST(opcode, rs, rt, rd, shamt, funct) \ - (((opcode) << 26) | ((rs) << 21) | ((rt) << 16) | ((rd) << 11) | ((shamt) << 6) | (funct)) -#define MIPS32_I_INST(opcode, rs, rt, immd) \ - (((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 */ - -/** - * Cache operations definitions - * Operation field is 5 bits long : - * 1) bits 1..0 hold cache type - * 2) bits 4..2 hold operation code - */ -#define MIPS32_CACHE_D_HIT_WRITEBACK ((0x1 << 0) | (0x6 << 2)) -#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 - -extern const struct command_registration mips32_command_handlers[]; - -int mips32_arch_state(struct target *target); - -int mips32_init_arch_info(struct target *target, - struct mips32_common *mips32, struct jtag_tap *tap); - -int mips32_restore_context(struct target *target); -int mips32_save_context(struct target *target); - -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, - int timeout_ms, void *arch_info); - -int mips32_configure_break_unit(struct target *target); - -int mips32_enable_interrupts(struct target *target, int enable); - -int mips32_examine(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, - uint32_t count, uint32_t *checksum); -int mips32_blank_check_memory(struct target *target, - uint32_t address, uint32_t count, uint32_t *blank); - -#endif /* OPENOCD_TARGET_MIPS32_H */ diff --git a/src/target/mips32_dmaacc.c b/src/target/mips32_dmaacc.c deleted file mode 100644 index 220ea94f9..000000000 --- a/src/target/mips32_dmaacc.c +++ /dev/null @@ -1,462 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2008 by John McCarthy * - * jgmcc@magma.ca * - * * - * Copyright (C) 2008 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * Copyright (C) 2008 by David T.L. Wong * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "mips32_dmaacc.h" -#include - -static int mips32_dmaacc_read_mem8(struct mips_ejtag *ejtag_info, - uint32_t addr, int count, uint8_t *buf); -static int mips32_dmaacc_read_mem16(struct mips_ejtag *ejtag_info, - uint32_t addr, int count, uint16_t *buf); -static int mips32_dmaacc_read_mem32(struct mips_ejtag *ejtag_info, - uint32_t addr, int count, uint32_t *buf); - -static int mips32_dmaacc_write_mem8(struct mips_ejtag *ejtag_info, - uint32_t addr, int count, const uint8_t *buf); -static int mips32_dmaacc_write_mem16(struct mips_ejtag *ejtag_info, - uint32_t addr, int count, const uint16_t *buf); -static int mips32_dmaacc_write_mem32(struct mips_ejtag *ejtag_info, - uint32_t addr, int count, const uint32_t *buf); - -/* - * The following logic shamelessly cloned from HairyDairyMaid's wrt54g_debrick - * to support the Broadcom BCM5352 SoC in the Linksys WRT54GL wireless router - * (and any others that support EJTAG DMA transfers). - * Note: This only supports memory read/write. Since the BCM5352 doesn't - * appear to support PRACC accesses, all debug functions except halt - * do not work. Still, this does allow erasing/writing flash as well as - * displaying/modifying memory and memory mapped registers. - */ - -static int ejtag_dma_dstrt_poll(struct mips_ejtag *ejtag_info) -{ - uint32_t ejtag_ctrl; - int64_t start = timeval_ms(); - - do { - if (timeval_ms() - start > 1000) { - LOG_ERROR("DMA time out"); - return -ETIMEDOUT; - } - ejtag_ctrl = EJTAG_CTRL_DMAACC | ejtag_info->ejtag_ctrl; - mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl); - } while (ejtag_ctrl & EJTAG_CTRL_DSTRT); - return 0; -} - -static int ejtag_dma_read(struct mips_ejtag *ejtag_info, uint32_t addr, uint32_t *data) -{ - uint32_t v; - uint32_t ejtag_ctrl; - int retries = RETRY_ATTEMPTS; - -begin_ejtag_dma_read: - - /* Setup Address */ - v = addr; - mips_ejtag_set_instr(ejtag_info, EJTAG_INST_ADDRESS); - mips_ejtag_drscan_32(ejtag_info, &v); - - /* Initiate DMA Read & set DSTRT */ - mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL); - ejtag_ctrl = EJTAG_CTRL_DMAACC | EJTAG_CTRL_DRWN | EJTAG_CTRL_DMA_WORD | EJTAG_CTRL_DSTRT | ejtag_info->ejtag_ctrl; - mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl); - - /* Wait for DSTRT to Clear */ - ejtag_dma_dstrt_poll(ejtag_info); - - /* Read Data */ - mips_ejtag_set_instr(ejtag_info, EJTAG_INST_DATA); - mips_ejtag_drscan_32(ejtag_info, data); - - /* Clear DMA & Check DERR */ - mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL); - ejtag_ctrl = ejtag_info->ejtag_ctrl; - mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl); - if (ejtag_ctrl & EJTAG_CTRL_DERR) { - if (retries--) { - LOG_ERROR("DMA Read Addr = %08" PRIx32 " Data = ERROR ON READ (retrying)", addr); - goto begin_ejtag_dma_read; - } else - LOG_ERROR("DMA Read Addr = %08" PRIx32 " Data = ERROR ON READ", addr); - return ERROR_JTAG_DEVICE_ERROR; - } - - return ERROR_OK; -} - -static int ejtag_dma_read_h(struct mips_ejtag *ejtag_info, uint32_t addr, uint16_t *data) -{ - uint32_t v; - uint32_t ejtag_ctrl; - int retries = RETRY_ATTEMPTS; - -begin_ejtag_dma_read_h: - - /* Setup Address */ - v = addr; - mips_ejtag_set_instr(ejtag_info, EJTAG_INST_ADDRESS); - mips_ejtag_drscan_32(ejtag_info, &v); - - /* Initiate DMA Read & set DSTRT */ - mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL); - ejtag_ctrl = EJTAG_CTRL_DMAACC | EJTAG_CTRL_DRWN | EJTAG_CTRL_DMA_HALFWORD | - EJTAG_CTRL_DSTRT | ejtag_info->ejtag_ctrl; - mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl); - - /* Wait for DSTRT to Clear */ - ejtag_dma_dstrt_poll(ejtag_info); - - /* Read Data */ - mips_ejtag_set_instr(ejtag_info, EJTAG_INST_DATA); - mips_ejtag_drscan_32(ejtag_info, &v); - - /* Clear DMA & Check DERR */ - mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL); - ejtag_ctrl = ejtag_info->ejtag_ctrl; - mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl); - if (ejtag_ctrl & EJTAG_CTRL_DERR) { - if (retries--) { - LOG_ERROR("DMA Read Addr = %08" PRIx32 " Data = ERROR ON READ (retrying)", addr); - goto begin_ejtag_dma_read_h; - } else - LOG_ERROR("DMA Read Addr = %08" PRIx32 " Data = ERROR ON READ", addr); - return ERROR_JTAG_DEVICE_ERROR; - } - - /* Handle the bigendian/littleendian */ - if (addr & 0x2) - *data = (v >> 16) & 0xffff; - else - *data = (v & 0x0000ffff); - - return ERROR_OK; -} - -static int ejtag_dma_read_b(struct mips_ejtag *ejtag_info, uint32_t addr, uint8_t *data) -{ - uint32_t v; - uint32_t ejtag_ctrl; - int retries = RETRY_ATTEMPTS; - -begin_ejtag_dma_read_b: - - /* Setup Address */ - v = addr; - mips_ejtag_set_instr(ejtag_info, EJTAG_INST_ADDRESS); - mips_ejtag_drscan_32(ejtag_info, &v); - - /* Initiate DMA Read & set DSTRT */ - mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL); - ejtag_ctrl = EJTAG_CTRL_DMAACC | EJTAG_CTRL_DRWN | EJTAG_CTRL_DMA_BYTE | EJTAG_CTRL_DSTRT | ejtag_info->ejtag_ctrl; - mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl); - - /* Wait for DSTRT to Clear */ - ejtag_dma_dstrt_poll(ejtag_info); - - /* Read Data */ - mips_ejtag_set_instr(ejtag_info, EJTAG_INST_DATA); - mips_ejtag_drscan_32(ejtag_info, &v); - - /* Clear DMA & Check DERR */ - mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL); - ejtag_ctrl = ejtag_info->ejtag_ctrl; - mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl); - if (ejtag_ctrl & EJTAG_CTRL_DERR) { - if (retries--) { - LOG_ERROR("DMA Read Addr = %08" PRIx32 " Data = ERROR ON READ (retrying)", addr); - goto begin_ejtag_dma_read_b; - } else - LOG_ERROR("DMA Read Addr = %08" PRIx32 " Data = ERROR ON READ", addr); - return ERROR_JTAG_DEVICE_ERROR; - } - - /* Handle the bigendian/littleendian */ - switch (addr & 0x3) { - case 0: - *data = v & 0xff; - break; - case 1: - *data = (v >> 8) & 0xff; - break; - case 2: - *data = (v >> 16) & 0xff; - break; - case 3: - *data = (v >> 24) & 0xff; - break; - } - - return ERROR_OK; -} - -static int ejtag_dma_write(struct mips_ejtag *ejtag_info, uint32_t addr, uint32_t data) -{ - uint32_t v; - uint32_t ejtag_ctrl; - int retries = RETRY_ATTEMPTS; - -begin_ejtag_dma_write: - - /* Setup Address */ - v = addr; - mips_ejtag_set_instr(ejtag_info, EJTAG_INST_ADDRESS); - mips_ejtag_drscan_32(ejtag_info, &v); - - /* Setup Data */ - v = data; - mips_ejtag_set_instr(ejtag_info, EJTAG_INST_DATA); - mips_ejtag_drscan_32(ejtag_info, &v); - - /* Initiate DMA Write & set DSTRT */ - mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL); - ejtag_ctrl = EJTAG_CTRL_DMAACC | EJTAG_CTRL_DMA_WORD | EJTAG_CTRL_DSTRT | ejtag_info->ejtag_ctrl; - mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl); - - /* Wait for DSTRT to Clear */ - ejtag_dma_dstrt_poll(ejtag_info); - - /* Clear DMA & Check DERR */ - mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL); - ejtag_ctrl = ejtag_info->ejtag_ctrl; - mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl); - if (ejtag_ctrl & EJTAG_CTRL_DERR) { - if (retries--) { - LOG_ERROR("DMA Write Addr = %08" PRIx32 " Data = ERROR ON WRITE (retrying)", addr); - goto begin_ejtag_dma_write; - } else - LOG_ERROR("DMA Write Addr = %08" PRIx32 " Data = ERROR ON WRITE", addr); - return ERROR_JTAG_DEVICE_ERROR; - } - - return ERROR_OK; -} - -static int ejtag_dma_write_h(struct mips_ejtag *ejtag_info, uint32_t addr, uint32_t data) -{ - uint32_t v; - uint32_t ejtag_ctrl; - int retries = RETRY_ATTEMPTS; - - /* Handle the bigendian/littleendian */ - data &= 0xffff; - data |= data << 16; - -begin_ejtag_dma_write_h: - - /* Setup Address */ - v = addr; - mips_ejtag_set_instr(ejtag_info, EJTAG_INST_ADDRESS); - mips_ejtag_drscan_32(ejtag_info, &v); - - /* Setup Data */ - v = data; - mips_ejtag_set_instr(ejtag_info, EJTAG_INST_DATA); - mips_ejtag_drscan_32(ejtag_info, &v); - - /* Initiate DMA Write & set DSTRT */ - mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL); - ejtag_ctrl = EJTAG_CTRL_DMAACC | EJTAG_CTRL_DMA_HALFWORD | EJTAG_CTRL_DSTRT | ejtag_info->ejtag_ctrl; - mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl); - - /* Wait for DSTRT to Clear */ - ejtag_dma_dstrt_poll(ejtag_info); - - /* Clear DMA & Check DERR */ - mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL); - ejtag_ctrl = ejtag_info->ejtag_ctrl; - mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl); - if (ejtag_ctrl & EJTAG_CTRL_DERR) { - if (retries--) { - LOG_ERROR("DMA Write Addr = %08" PRIx32 " Data = ERROR ON WRITE (retrying)", addr); - goto begin_ejtag_dma_write_h; - } else - LOG_ERROR("DMA Write Addr = %08" PRIx32 " Data = ERROR ON WRITE", addr); - return ERROR_JTAG_DEVICE_ERROR; - } - - return ERROR_OK; -} - -static int ejtag_dma_write_b(struct mips_ejtag *ejtag_info, uint32_t addr, uint32_t data) -{ - uint32_t v; - uint32_t ejtag_ctrl; - int retries = RETRY_ATTEMPTS; - - /* Handle the bigendian/littleendian */ - data &= 0xff; - data |= data << 8; - data |= data << 16; - -begin_ejtag_dma_write_b: - - /* Setup Address*/ - v = addr; - mips_ejtag_set_instr(ejtag_info, EJTAG_INST_ADDRESS); - mips_ejtag_drscan_32(ejtag_info, &v); - - /* Setup Data */ - v = data; - mips_ejtag_set_instr(ejtag_info, EJTAG_INST_DATA); - mips_ejtag_drscan_32(ejtag_info, &v); - - /* Initiate DMA Write & set DSTRT */ - mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL); - ejtag_ctrl = EJTAG_CTRL_DMAACC | EJTAG_CTRL_DMA_BYTE | EJTAG_CTRL_DSTRT | ejtag_info->ejtag_ctrl; - mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl); - - /* Wait for DSTRT to Clear */ - ejtag_dma_dstrt_poll(ejtag_info); - - /* Clear DMA & Check DERR */ - mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL); - ejtag_ctrl = ejtag_info->ejtag_ctrl; - mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl); - if (ejtag_ctrl & EJTAG_CTRL_DERR) { - if (retries--) { - LOG_ERROR("DMA Write Addr = %08" PRIx32 " Data = ERROR ON WRITE (retrying)", addr); - goto begin_ejtag_dma_write_b; - } else - LOG_ERROR("DMA Write Addr = %08" PRIx32 " Data = ERROR ON WRITE", addr); - return ERROR_JTAG_DEVICE_ERROR; - } - - return ERROR_OK; -} - -int mips32_dmaacc_read_mem(struct mips_ejtag *ejtag_info, uint32_t addr, int size, int count, void *buf) -{ - switch (size) { - case 1: - return mips32_dmaacc_read_mem8(ejtag_info, addr, count, (uint8_t *)buf); - case 2: - return mips32_dmaacc_read_mem16(ejtag_info, addr, count, (uint16_t *)buf); - case 4: - return mips32_dmaacc_read_mem32(ejtag_info, addr, count, (uint32_t *)buf); - } - - return ERROR_OK; -} - -static int mips32_dmaacc_read_mem32(struct mips_ejtag *ejtag_info, uint32_t addr, int count, uint32_t *buf) -{ - int i; - int retval; - - for (i = 0; i < count; i++) { - retval = ejtag_dma_read(ejtag_info, addr + i * sizeof(*buf), &buf[i]); - if (retval != ERROR_OK) - return retval; - } - - return ERROR_OK; -} - -static int mips32_dmaacc_read_mem16(struct mips_ejtag *ejtag_info, uint32_t addr, int count, uint16_t *buf) -{ - int i; - int retval; - - for (i = 0; i < count; i++) { - retval = ejtag_dma_read_h(ejtag_info, addr + i * sizeof(*buf), &buf[i]); - if (retval != ERROR_OK) - return retval; - } - - return ERROR_OK; -} - -static int mips32_dmaacc_read_mem8(struct mips_ejtag *ejtag_info, uint32_t addr, int count, uint8_t *buf) -{ - int i; - int retval; - - for (i = 0; i < count; i++) { - retval = ejtag_dma_read_b(ejtag_info, addr + i * sizeof(*buf), &buf[i]); - if (retval != ERROR_OK) - return retval; - } - - return ERROR_OK; -} - -int mips32_dmaacc_write_mem(struct mips_ejtag *ejtag_info, uint32_t addr, int size, int count, const void *buf) -{ - switch (size) { - case 1: - return mips32_dmaacc_write_mem8(ejtag_info, addr, count, buf); - case 2: - return mips32_dmaacc_write_mem16(ejtag_info, addr, count, buf); - case 4: - return mips32_dmaacc_write_mem32(ejtag_info, addr, count, buf); - } - - return ERROR_OK; -} - -static int mips32_dmaacc_write_mem32(struct mips_ejtag *ejtag_info, uint32_t addr, int count, const uint32_t *buf) -{ - int i; - int retval; - - for (i = 0; i < count; i++) { - retval = ejtag_dma_write(ejtag_info, addr + i * sizeof(*buf), buf[i]); - if (retval != ERROR_OK) - return retval; - } - - return ERROR_OK; -} - -static int mips32_dmaacc_write_mem16(struct mips_ejtag *ejtag_info, uint32_t addr, int count, const uint16_t *buf) -{ - int i; - int retval; - - for (i = 0; i < count; i++) { - retval = ejtag_dma_write_h(ejtag_info, addr + i * sizeof(*buf), buf[i]); - if (retval != ERROR_OK) - return retval; - } - - return ERROR_OK; -} - -static int mips32_dmaacc_write_mem8(struct mips_ejtag *ejtag_info, uint32_t addr, int count, const uint8_t *buf) -{ - int i; - int retval; - - for (i = 0; i < count; i++) { - retval = ejtag_dma_write_b(ejtag_info, addr + i * sizeof(*buf), buf[i]); - if (retval != ERROR_OK) - return retval; - } - - return ERROR_OK; -} diff --git a/src/target/mips32_dmaacc.h b/src/target/mips32_dmaacc.h deleted file mode 100644 index 70fe2a77e..000000000 --- a/src/target/mips32_dmaacc.h +++ /dev/null @@ -1,41 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2008 by John McCarthy * - * jgmcc@magma.ca * - * * - * Copyright (C) 2008 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * Copyright (C) 2008 by David T.L. Wong * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifndef OPENOCD_TARGET_MIPS32_DMAACC_H -#define OPENOCD_TARGET_MIPS32_DMAACC_H - -#include "mips_ejtag.h" - -#define EJTAG_CTRL_DMA_BYTE 0x00000000 -#define EJTAG_CTRL_DMA_HALFWORD 0x00000080 -#define EJTAG_CTRL_DMA_WORD 0x00000100 -#define EJTAG_CTRL_DMA_TRIPLEBYTE 0x00000180 - -#define RETRY_ATTEMPTS 0 - -int mips32_dmaacc_read_mem(struct mips_ejtag *ejtag_info, - uint32_t addr, int size, int count, void *buf); -int mips32_dmaacc_write_mem(struct mips_ejtag *ejtag_info, - uint32_t addr, int size, int count, const void *buf); - -#endif /* OPENOCD_TARGET_MIPS32_DMAACC_H */ diff --git a/src/target/mips32_pracc.c b/src/target/mips32_pracc.c deleted file mode 100644 index 7cc0424fb..000000000 --- a/src/target/mips32_pracc.c +++ /dev/null @@ -1,1117 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2008 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * Copyright (C) 2008 by David T.L. Wong * - * * - * Copyright (C) 2009 by David N. Claffey * - * * - * Copyright (C) 2011 by Drasko DRASKOVIC * - * drasko.draskovic@gmail.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -/* - * This version has optimized assembly routines for 32 bit operations: - * - read word - * - write word - * - write array of words - * - * One thing to be aware of is that the MIPS32 cpu will execute the - * instruction after a branch instruction (one delay slot). - * - * For example: - * LW $2, ($5 +10) - * B foo - * LW $1, ($2 +100) - * - * The LW $1, ($2 +100) instruction is also executed. If this is - * not wanted a NOP can be inserted: - * - * LW $2, ($5 +10) - * B foo - * NOP - * LW $1, ($2 +100) - * - * or the code can be changed to: - * - * B foo - * LW $2, ($5 +10) - * LW $1, ($2 +100) - * - * The original code contained NOPs. I have removed these and moved - * the branches. - * - * These changes result in a 35% speed increase when programming an - * external flash. - * - * More improvement could be gained if the registers do no need - * to be preserved but in that case the routines should be aware - * OpenOCD is used as a flash programmer or as a debug tool. - * - * Nico Coesel - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include - -#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) -{ - uint32_t ejtag_ctrl; - 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); - if (retval != ERROR_OK) - return retval; - - if (ejtag_ctrl & EJTAG_CTRL_PRACC) - break; - - 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); - 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; -} - -/* Finish processor access */ -static int 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; - - /* 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); - if (retval != ERROR_OK) - return retval; - - /* Data or instruction out */ - mips_ejtag_set_instr(ejtag_info, EJTAG_INST_DATA); - uint32_t data = (i == 3) ? jt_code : MIPS32_NOP; - mips_ejtag_drscan_32_out(ejtag_info, data); - - /* finish pa */ - retval = mips32_pracc_finish(ejtag_info); - if (retval != ERROR_OK) - return retval; - } - - if (ejtag_info->mode != 0) /* async mode support only for MIPS ... */ - return ERROR_OK; - - for (int i = 0; i != 2; i++) { - 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); - retval = mips32_pracc_finish(ejtag_info); - if (retval != ERROR_OK) - return retval; - } else - break; - } - - return ERROR_OK; -} - -int mips32_pracc_exec(struct mips_ejtag *ejtag_info, struct pracc_queue_info *ctx, uint32_t *param_out) -{ - int code_count = 0; - int store_pending = 0; /* increases with every store instruction 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; - uint32_t instr = 0; - bool final_check = 0; /* set to 1 if in final checks after function code shifted out */ - bool pass = 0; /* to check the pass through pracc text after function code sent */ - int retval; - - while (1) { - if (restart) { - if (restart_count < 3) { /* max 3 restarts allowed */ - retval = mips32_pracc_clean_text_jump(ejtag_info); - if (retval != ERROR_OK) - return retval; - } else - return ERROR_JTAG_DEVICE_ERROR; - restart_count++; - restart = 0; - code_count = 0; - LOG_DEBUG("restarting code"); - } - - 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 */ - /* 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); - if (code_count < 2) { /* allow for restart */ - restart = 1; - continue; - } else - return ERROR_JTAG_DEVICE_ERROR; - } else { - /* check address */ - 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; - } - } - /* read data */ - uint32_t data = 0; - mips_ejtag_set_instr(ejtag_info, EJTAG_INST_DATA); - retval = mips_ejtag_drscan_32(ejtag_info, &data); - if (retval != ERROR_OK) - return retval; - - /* store data at param out, address based offset */ - param_out[(ejtag_info->pa_addr - MIPS32_PRACC_PARAM_OUT) / 4] = data; - store_pending--; - - } else { /* read/fetch access */ - if (!final_check) { /* executing function code */ - /* check address */ - if (ejtag_info->pa_addr != (MIPS32_PRACC_TEXT + code_count * 4)) { - LOG_DEBUG("reading at unexpected address %" PRIx32 ", expected %x", - 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) { - LOG_DEBUG("restarting, without clean jump"); - restart_count++; - code_count = 0; - continue; - } else if (code_count < 2) { - 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]; - if (store_addr != 0) { - if (store_addr > max_store_addr) - max_store_addr = store_addr; - store_pending++; - } - - instr = ctx->pracc_list[code_count++]; - if (code_count == ctx->code_count) /* last instruction, start final check */ - final_check = 1; - - } else { /* final check after function code shifted out */ - /* check address */ - if (ejtag_info->pa_addr == MIPS32_PRACC_TEXT) { - if (!pass) { /* first pass through pracc text */ - if (store_pending == 0) /* done, normal exit */ - return ERROR_OK; - pass = 1; /* pracc text passed */ - code_count = 0; /* restart code count */ - } else { - LOG_DEBUG("unexpected second pass through pracc text"); - return ERROR_JTAG_DEVICE_ERROR; - } - } 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); - return ERROR_JTAG_DEVICE_ERROR; - } - } - if (!pass) { - if ((code_count - ctx->code_count) > 1) { /* allow max 2 instruction delay slot */ - LOG_DEBUG("failed to jump back to pracc text"); - return ERROR_JTAG_DEVICE_ERROR; - } - } else - if (code_count > 10) { /* enough, abandone */ - LOG_DEBUG("execution abandoned, store pending: %d", store_pending); - return ERROR_JTAG_DEVICE_ERROR; - } - instr = MIPS32_NOP; /* shift out NOPs instructions */ - code_count++; - } - - /* Send instruction out */ - mips_ejtag_set_instr(ejtag_info, EJTAG_INST_DATA); - 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; - - if (instr == MIPS32_DRET) /* after leaving debug mode nothing to do */ - return ERROR_OK; - - if (store_pending == 0 && pass) { /* store access done, but after passing pracc text */ - LOG_DEBUG("warning: store access pass pracc text"); - return ERROR_OK; - } - } -} - -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; - } -} - -inline 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 (addr) - ctx->store_count++; -} - -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) -{ - if (ejtag_info->mode == 0) - return mips32_pracc_exec(ejtag_info, ctx, buf); - - union scan_in { - uint8_t scan_96[12]; - struct { - uint8_t ctrl[4]; - uint8_t data[4]; - uint8_t addr[4]; - } scan_32; - - } *scan_in = malloc(sizeof(union scan_in) * (ctx->code_count + ctx->store_count)); - if (scan_in == NULL) { - LOG_ERROR("Out of memory"); - return ERROR_FAIL; - } - - unsigned num_clocks = - ((uint64_t)(ejtag_info->scan_delay) * jtag_get_speed_khz() + 500000) / 1000000; - - uint32_t ejtag_ctrl = ejtag_info->ejtag_ctrl & ~EJTAG_CTRL_PRACC; - 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]; - - jtag_add_clocks(num_clocks); - mips_ejtag_add_scan_96(ejtag_info, ejtag_ctrl, data, scan_in[scan_count++].scan_96); - } - - int retval = jtag_execute_queue(); /* execute queued scans */ - if (retval != ERROR_OK) - goto exit; - - 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; - } - - ejtag_ctrl = buf_get_u32(scan_in[scan_count].scan_32.ctrl, 0, 32); - if (!(ejtag_ctrl & EJTAG_CTRL_PRACC)) { - LOG_ERROR("Error: access not pending count: %d", scan_count); - retval = ERROR_FAIL; - goto exit; - } - - uint32_t 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; - goto exit; - } - if (addr != store_addr) { - LOG_ERROR("Store address mismatch, read: %" PRIx32 " expected: %" PRIx32 " count: %d", - 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++; - } -exit: - free(scan_in); - return retval; -} - -int mips32_pracc_read_u32(struct mips_ejtag *ejtag_info, uint32_t addr, uint32_t *buf) -{ - struct pracc_queue_info ctx = {.max_code = 8}; - 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, 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 */ - - ctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, buf); -exit: - pracc_queue_free(&ctx); - return ctx.retval; -} - -int mips32_pracc_read_mem(struct mips_ejtag *ejtag_info, uint32_t addr, int size, int count, void *buf) -{ - 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 */ - pracc_queue_init(&ctx); - if (ctx.retval != ERROR_OK) - goto exit; - - if (size != 4) { - data = malloc(256 * sizeof(uint32_t)); - if (data == NULL) { - LOG_ERROR("Out of memory"); - goto exit; - } - } - - uint32_t *buf32 = buf; - uint16_t *buf16 = buf; - uint8_t *buf8 = buf; - - 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 */ - - 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)); - 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 */ - else if (size == 2) - pracc_add(&ctx, 0, MIPS32_LHU(8, LOWER16(addr), 9)); - else - pracc_add(&ctx, 0, MIPS32_LBU(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 */ - 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(&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 */ - - if (size == 4) { - ctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, buf32); - if (ctx.retval != ERROR_OK) - goto exit; - buf32 += this_round_count; - } else { - ctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, data); - if (ctx.retval != ERROR_OK) - goto exit; - - uint32_t *data_p = data; - for (int i = 0; i != this_round_count; i++) { - if (size == 2) - *buf16++ = *data_p++; - else - *buf8++ = *data_p++; - } - } - count -= this_round_count; - } -exit: - pracc_queue_free(&ctx); - if (data != NULL) - free(data); - return ctx.retval; -} - -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}; - 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, 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 */ - - ctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, val); -exit: - 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}; - 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(&ctx, 0, MIPS32_MTC0(15, 0, 0) | (cp0_reg << 11) | cp0_sel); /* write cp0 reg / sel */ - - 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: - 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 - **/ -} - -/** - * \b mips32_pracc_sync_cache - * - * Synchronize Caches to Make Instruction Writes Effective - * (ref. doc. MIPS32 Architecture For Programmers Volume II: The MIPS32 Instruction Set, - * Document Number: MD00086, Revision 2.00, June 9, 2003) - * - * When the instruction stream is written, the SYNCI instruction should be used - * in conjunction with other instructions to make the newly-written instructions effective. - * - * Explanation : - * A program that loads another program into memory is actually writing the D- side cache. - * The instructions it has loaded can't be executed until they reach the I-cache. - * - * After the instructions have been written, the loader should arrange - * to write back any containing D-cache line and invalidate any locations - * already in the I-cache. - * - * If the cache coherency attribute (CCA) is set to zero, it's a write through cache, there is no need - * to write back. - * - * In the latest MIPS32/64 CPUs, MIPS provides the synci instruction, - * which does the whole job for a cache-line-sized chunk of the memory you just loaded: - * That is, it arranges a D-cache write-back (if CCA = 3) and an I-cache invalidate. - * - * The line size is obtained with the rdhwr SYNCI_Step in release 2 or from cp0 config 1 register in release 1. - */ -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}; - 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_RDHWR(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 */ - - 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 */ - - ctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, &clsiz); - if (ctx.retval != ERROR_OK) - goto exit; - - } else { /* Release 1 (rel = 0) */ - uint32_t conf; - ctx.retval = mips32_cp0_read(ejtag_info, &conf, 16, 1); - if (ctx.retval != ERROR_OK) - goto exit; - - uint32_t dl = (conf & MIPS32_CONFIG1_DL_MASK) >> MIPS32_CONFIG1_DL_SHIFT; - - /* dl encoding : dl=1 => 4 bytes, dl=2 => 8 bytes, etc... max dl=6 => 128 bytes cache line size */ - clsiz = 0x2 << dl; - if (dl == 0) - clsiz = 0; - } - - if (clsiz == 0) - goto exit; /* Nothing to do */ - - /* make sure clsiz is power of 2 */ - if (clsiz & (clsiz - 1)) { - LOG_DEBUG("clsiz must be power of 2"); - ctx.retval = ERROR_FAIL; - goto exit; - } - - /* make sure start_addr and end_addr have the same offset inside de cache line */ - start_addr |= clsiz - 1; - end_addr |= clsiz - 1; - - ctx.code_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 */ - - 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)); - last_upper_base_addr = upper_base_addr; - } - if (rel) - pracc_add(&ctx, 0, MIPS32_SYNCI(LOWER16(start_addr), 15)); /* synci instruction, offset($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) */ - } - 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 */ - - ctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, NULL); - if (ctx.retval != ERROR_OK) - goto exit; - - ctx.code_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*/ - - ctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, NULL); -exit: - pracc_queue_free(&ctx); - return ctx.retval; -} - -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 */ - pracc_queue_init(&ctx); - if (ctx.retval != ERROR_OK) - goto exit; - - const uint32_t *buf32 = buf; - const uint16_t *buf16 = buf; - const uint8_t *buf8 = buf; - - 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 */ - - 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*/ - 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 */ - 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 */ - 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 */ - 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(&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 */ - - ctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, NULL); - if (ctx.retval != ERROR_OK) - goto exit; - count -= this_round_count; - } -exit: - pracc_queue_free(&ctx); - return ctx.retval; -} - -int mips32_pracc_write_mem(struct mips_ejtag *ejtag_info, uint32_t addr, int size, int count, const void *buf) -{ - int retval = mips32_pracc_write_mem_generic(ejtag_info, addr, size, count, buf); - if (retval != ERROR_OK) - return retval; - - /** - * If we are in the cacheable region and cache is activated, - * we must clean D$ (if Cache Coherency Attribute is set to 3) + invalidate I$ after we did the write, - * so that changes do not continue to live only in D$ (if CCA = 3), but to be - * replicated in I$ also (maybe we wrote the istructions) - */ - uint32_t conf = 0; - int cached = 0; - - if ((KSEGX(addr) == KSEG1) || ((addr >= 0xff200000) && (addr <= 0xff3fffff))) - return retval; /*Nothing to do*/ - - mips32_cp0_read(ejtag_info, &conf, 16, 0); - - switch (KSEGX(addr)) { - case KUSEG: - cached = (conf & MIPS32_CONFIG0_KU_MASK) >> MIPS32_CONFIG0_KU_SHIFT; - break; - case KSEG0: - cached = (conf & MIPS32_CONFIG0_K0_MASK) >> MIPS32_CONFIG0_K0_SHIFT; - break; - case KSEG2: - case KSEG3: - cached = (conf & MIPS32_CONFIG0_K23_MASK) >> MIPS32_CONFIG0_K23_SHIFT; - break; - default: - /* what ? */ - break; - } - - /** - * Check cachablitiy bits coherency algorithm - * is the region cacheable or uncached. - * If cacheable we have to synchronize the cache - */ - if (cached == 3 || cached == 0) { /* Write back cache or write through cache */ - uint32_t start_addr = addr; - uint32_t end_addr = addr + count * size; - uint32_t rel = (conf & MIPS32_CONFIG0_AR_MASK) >> MIPS32_CONFIG0_AR_SHIFT; - if (rel > 1) { - LOG_DEBUG("Unknown release in cache code"); - return ERROR_FAIL; - } - retval = mips32_pracc_synchronize_cache(ejtag_info, start_addr, end_addr, cached, rel); - } - - return retval; -} - -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}; - 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])))); - } - } - - 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(&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 */ - - ctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, NULL); - - 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}; - 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 */ - - 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)); - - 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)); - } - 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(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 */ - - 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); - - 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; -} - -/* fastdata upload/download requires an initialized working area - * to load the download code; it should not be called otherwise - * fetch order from the fastdata area - * 1. start addr - * 2. end addr - * 3. data ... - */ -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 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), - /* 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 */ - }; - - 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 */ - 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); - - jmp_code[0] |= UPPER16(source->address); - jmp_code[1] |= LOWER16(source->address); - - for (i = 0; i < (int) ARRAY_SIZE(jmp_code); i++) { - retval = wait_for_pracc_rw(ejtag_info, &ejtag_ctrl); - if (retval != ERROR_OK) - return retval; - - mips_ejtag_set_instr(ejtag_info, EJTAG_INST_DATA); - 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); - } - - /* wait PrAcc pending bit for FASTDATA write */ - retval = wait_for_pracc_rw(ejtag_info, &ejtag_ctrl); - 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) - return ERROR_FAIL; - - /* Send the load start address */ - 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); - if (retval != ERROR_OK) - return retval; - - /* Send the load end address */ - val = addr + (count - 1) * 4; - mips_ejtag_set_instr(ejtag_info, EJTAG_INST_FASTDATA); - mips_ejtag_fastdata_scan(ejtag_info, 1, &val); - - unsigned num_clocks = 0; /* like in legacy code */ - 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++) { - jtag_add_clocks(num_clocks); - retval = mips_ejtag_fastdata_scan(ejtag_info, write_t, buf++); - if (retval != ERROR_OK) - return retval; - } - - retval = jtag_execute_queue(); - if (retval != ERROR_OK) { - LOG_ERROR("fastdata load failed"); - 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); - if (retval != ERROR_OK) - return retval; - - if (address != 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 deleted file mode 100644 index 2ede5b288..000000000 --- a/src/target/mips32_pracc.h +++ /dev/null @@ -1,102 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2008 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * Copyright (C) 2008 by David T.L. Wong * - * * - * Copyright (C) 2011 by Drasko DRASKOVIC * - * drasko.draskovic@gmail.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifndef OPENOCD_TARGET_MIPS32_PRACC_H -#define OPENOCD_TARGET_MIPS32_PRACC_H - -#include -#include - -#define MIPS32_PRACC_FASTDATA_AREA 0xFF200000 -#define MIPS32_PRACC_FASTDATA_SIZE 16 -#define MIPS32_PRACC_BASE_ADDR 0xFF200000 -#define MIPS32_PRACC_TEXT 0xFF200200 -#define MIPS32_PRACC_PARAM_OUT 0xFF202000 - -#define PRACC_UPPER_BASE_ADDR (MIPS32_PRACC_BASE_ADDR >> 16) -#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 NEG18(v) (((~(v)) + 1) & 0x3FFFF)*/ - -struct pracc_queue_info { - int retval; - const int max_code; - int code_count; - int store_count; - uint32_t *pracc_list; /* Code and store addresses */ -}; -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_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); - -int mips32_pracc_read_mem(struct mips_ejtag *ejtag_info, - uint32_t addr, int size, int count, void *buf); -int mips32_pracc_write_mem(struct mips_ejtag *ejtag_info, - uint32_t addr, int size, int count, const void *buf); -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); - -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); - -/** - * \b mips32_cp0_read - * - * Simulates mfc0 ASM instruction (Move From C0), - * i.e. implements copro C0 Register read. - * - * @param[in] ejtag_info - * @param[in] val Storage to hold read value - * @param[in] cp0_reg Number of copro C0 register we want to read - * @param[in] cp0_sel Select for the given C0 register - * - * @return ERROR_OK on Sucess, ERROR_FAIL otherwise - */ -int mips32_cp0_read(struct mips_ejtag *ejtag_info, - uint32_t *val, uint32_t cp0_reg, uint32_t cp0_sel); - -/** - * \b mips32_cp0_write - * - * Simulates mtc0 ASM instruction (Move To C0), - * i.e. implements copro C0 Register read. - * - * @param[in] ejtag_info - * @param[in] val Value to be written - * @param[in] cp0_reg Number of copro C0 register we want to write to - * @param[in] cp0_sel Select for the given C0 register - * - * @return ERROR_OK on Sucess, ERROR_FAIL otherwise - */ -int mips32_cp0_write(struct mips_ejtag *ejtag_info, - uint32_t val, uint32_t cp0_reg, uint32_t cp0_sel); - -#endif /* OPENOCD_TARGET_MIPS32_PRACC_H */ diff --git a/src/target/mips_ejtag.c b/src/target/mips_ejtag.c deleted file mode 100644 index 594711fb5..000000000 --- a/src/target/mips_ejtag.c +++ /dev/null @@ -1,480 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2008 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * Copyright (C) 2008 by David T.L. Wong * - * * - * Copyright (C) 2009 by David N. Claffey * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 -#include "config.h" -#endif - -#include "mips32.h" -#include "mips_ejtag.h" -#include "mips32_dmaacc.h" - -void mips_ejtag_set_instr(struct mips_ejtag *ejtag_info, int new_instr) -{ - struct jtag_tap *tap; - - tap = ejtag_info->tap; - assert(tap != NULL); - - 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; - 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) -{ - 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; -} - -static int mips_ejtag_get_impcode(struct mips_ejtag *ejtag_info, uint32_t *impcode) -{ - 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; -} - -void mips_ejtag_add_scan_96(struct mips_ejtag *ejtag_info, uint32_t ctrl, uint32_t data, uint8_t *in_scan_buf) -{ - assert(ejtag_info->tap != NULL); - struct jtag_tap *tap = ejtag_info->tap; - - struct scan_field field; - uint8_t out_scan[12]; - - /* processor access "all" register 96 bit */ - field.num_bits = 96; - - field.out_value = out_scan; - buf_set_u32(out_scan, 0, 32, ctrl); - buf_set_u32(out_scan + 4, 0, 32, data); - buf_set_u32(out_scan + 8, 0, 32, 0); - - field.in_value = in_scan_buf; - - jtag_add_dr_scan(tap, 1, &field, TAP_IDLE); - - keep_alive(); -} - -int mips_ejtag_drscan_32(struct mips_ejtag *ejtag_info, uint32_t *data) -{ - struct jtag_tap *tap; - tap = ejtag_info->tap; - assert(tap != NULL); - - 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; - - jtag_add_dr_scan(tap, 1, &field, TAP_IDLE); - - 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(); - - 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); -} - -int mips_ejtag_drscan_8(struct mips_ejtag *ejtag_info, uint32_t *data) -{ - struct jtag_tap *tap; - tap = ejtag_info->tap; - assert(tap != NULL); - - 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; - - jtag_add_dr_scan(tap, 1, &field, TAP_IDLE); - - 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); - - struct scan_field field; - - field.num_bits = 8; - field.out_value = &data; - field.in_value = NULL; - - jtag_add_dr_scan(tap, 1, &field, TAP_IDLE); -} - -/* 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}; - 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 */ - if (!enable_step) - pracc_add(&ctx, 0, MIPS32_XORI(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 */ - - ctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, NULL); -exit: - pracc_queue_free(&ctx); - return ctx.retval; -} - -/* - * Disable memory protection for 0xFF20.0000–0xFF3F.FFFF - * It is needed by EJTAG 1.5-2.0, especially for BMIPS CPUs - * For example bcm7401 and others. At leas on some - * CPUs, DebugMode wont start if this bit is not removed. - */ -static int disable_dcr_mp(struct mips_ejtag *ejtag_info) -{ - uint32_t dcr; - int retval; - - retval = mips32_dmaacc_read_mem(ejtag_info, EJTAG_DCR, 4, 1, &dcr); - if (retval != ERROR_OK) - goto error; - - dcr &= ~EJTAG_DCR_MP; - retval = mips32_dmaacc_write_mem(ejtag_info, EJTAG_DCR, 4, 1, &dcr); - if (retval != ERROR_OK) - goto error; - return ERROR_OK; -error: - LOG_ERROR("Failed to remove DCR MPbit!"); - return retval; -} - -int mips_ejtag_enter_debug(struct mips_ejtag *ejtag_info) -{ - uint32_t ejtag_ctrl; - mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL); - - if (ejtag_info->ejtag_version == EJTAG_VERSION_20) { - if (disable_dcr_mp(ejtag_info) != ERROR_OK) - goto error; - } - - /* set debug break bit */ - ejtag_ctrl = ejtag_info->ejtag_ctrl | EJTAG_CTRL_JTAGBRK; - mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl); - - /* break bit will be cleared by hardware */ - ejtag_ctrl = ejtag_info->ejtag_ctrl; - mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl); - LOG_DEBUG("ejtag_ctrl: 0x%8.8" PRIx32 "", ejtag_ctrl); - if ((ejtag_ctrl & EJTAG_CTRL_BRKST) == 0) - goto error; - - return ERROR_OK; -error: - LOG_ERROR("Failed to enter Debug Mode!"); - return ERROR_FAIL; -} - -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}; - - /* execute our dret instruction */ - ctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, NULL); - - /* pic32mx workaround, false pending at low core clock */ - jtag_add_sleep(1000); - return ctx.retval; -} - -/* mips_ejtag_init_mmr - asign Memory-Mapped Registers depending - * on EJTAG version. - */ -static void mips_ejtag_init_mmr(struct mips_ejtag *ejtag_info) -{ - if (ejtag_info->ejtag_version == EJTAG_VERSION_20) { - ejtag_info->ejtag_ibs_addr = EJTAG_V20_IBS; - ejtag_info->ejtag_iba0_addr = EJTAG_V20_IBA0; - ejtag_info->ejtag_ibc_offs = EJTAG_V20_IBC_OFFS; - ejtag_info->ejtag_ibm_offs = EJTAG_V20_IBM_OFFS; - - ejtag_info->ejtag_dbs_addr = EJTAG_V20_DBS; - ejtag_info->ejtag_dba0_addr = EJTAG_V20_DBA0; - ejtag_info->ejtag_dbc_offs = EJTAG_V20_DBC_OFFS; - ejtag_info->ejtag_dbm_offs = EJTAG_V20_DBM_OFFS; - ejtag_info->ejtag_dbv_offs = EJTAG_V20_DBV_OFFS; - - ejtag_info->ejtag_iba_step_size = EJTAG_V20_IBAn_STEP; - ejtag_info->ejtag_dba_step_size = EJTAG_V20_DBAn_STEP; - } else { - ejtag_info->ejtag_ibs_addr = EJTAG_V25_IBS; - ejtag_info->ejtag_iba0_addr = EJTAG_V25_IBA0; - ejtag_info->ejtag_ibm_offs = EJTAG_V25_IBM_OFFS; - ejtag_info->ejtag_ibasid_offs = EJTAG_V25_IBASID_OFFS; - ejtag_info->ejtag_ibc_offs = EJTAG_V25_IBC_OFFS; - - ejtag_info->ejtag_dbs_addr = EJTAG_V25_DBS; - ejtag_info->ejtag_dba0_addr = EJTAG_V25_DBA0; - ejtag_info->ejtag_dbm_offs = EJTAG_V25_DBM_OFFS; - ejtag_info->ejtag_dbasid_offs = EJTAG_V25_DBASID_OFFS; - ejtag_info->ejtag_dbc_offs = EJTAG_V25_DBC_OFFS; - ejtag_info->ejtag_dbv_offs = EJTAG_V25_DBV_OFFS; - - ejtag_info->ejtag_iba_step_size = EJTAG_V25_IBAn_STEP; - ejtag_info->ejtag_dba_step_size = EJTAG_V25_DBAn_STEP; - } -} - -static void ejtag_v20_print_imp(struct mips_ejtag *ejtag_info) -{ - LOG_DEBUG("EJTAG v2.0: features:%s%s%s%s%s%s%s%s", - EJTAG_IMP_HAS(EJTAG_V20_IMP_SDBBP) ? " SDBBP_SPECIAL2" : " SDBBP", - EJTAG_IMP_HAS(EJTAG_V20_IMP_EADDR_NO32BIT) ? " EADDR>32bit" : " EADDR=32bit", - EJTAG_IMP_HAS(EJTAG_V20_IMP_COMPLEX_BREAK) ? " COMPLEX_BREAK" : "", - EJTAG_IMP_HAS(EJTAG_V20_IMP_DCACHE_COH) ? " DCACHE_COH" : " DCACHE_NOT_COH", - EJTAG_IMP_HAS(EJTAG_V20_IMP_ICACHE_COH) ? " ICACHE_COH" : " ICACHE_NOT_COH", - EJTAG_IMP_HAS(EJTAG_V20_IMP_NOPB) ? " noPB" : " PB", - EJTAG_IMP_HAS(EJTAG_V20_IMP_NODB) ? " noDB" : " DB", - EJTAG_IMP_HAS(EJTAG_V20_IMP_NOIB) ? " noIB" : " IB"); - LOG_DEBUG("EJTAG v2.0: Break Channels: %" PRIu8, - (uint8_t)((ejtag_info->impcode >> EJTAG_V20_IMP_BCHANNELS_SHIFT) & - EJTAG_V20_IMP_BCHANNELS_MASK)); -} - -static void ejtag_v26_print_imp(struct mips_ejtag *ejtag_info) -{ - LOG_DEBUG("EJTAG v2.6: features:%s%s", - EJTAG_IMP_HAS(EJTAG_V26_IMP_R3K) ? " R3k" : " R4k", - EJTAG_IMP_HAS(EJTAG_V26_IMP_DINT) ? " DINT" : ""); -} - -static void ejtag_main_print_imp(struct mips_ejtag *ejtag_info) -{ - LOG_DEBUG("EJTAG main: features:%s%s%s%s%s", - EJTAG_IMP_HAS(EJTAG_IMP_ASID8) ? " ASID_8" : "", - EJTAG_IMP_HAS(EJTAG_IMP_ASID6) ? " ASID_6" : "", - EJTAG_IMP_HAS(EJTAG_IMP_MIPS16) ? " MIPS16" : "", - EJTAG_IMP_HAS(EJTAG_IMP_NODMA) ? " noDMA" : " DMA", - EJTAG_IMP_HAS(EJTAG_DCR_MIPS64) ? " MIPS64" : " MIPS32"); - - switch (ejtag_info->ejtag_version) { - case EJTAG_VERSION_20: - ejtag_v20_print_imp(ejtag_info); - break; - case EJTAG_VERSION_25: - case EJTAG_VERSION_26: - case EJTAG_VERSION_31: - case EJTAG_VERSION_41: - case EJTAG_VERSION_51: - ejtag_v26_print_imp(ejtag_info); - break; - default: - break; - } -} - -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) - return retval; - LOG_DEBUG("impcode: 0x%8.8" PRIx32 "", ejtag_info->impcode); - - /* get ejtag version */ - ejtag_info->ejtag_version = ((ejtag_info->impcode >> 29) & 0x07); - - switch (ejtag_info->ejtag_version) { - case EJTAG_VERSION_20: - LOG_DEBUG("EJTAG: Version 1 or 2.0 Detected"); - break; - case EJTAG_VERSION_25: - LOG_DEBUG("EJTAG: Version 2.5 Detected"); - break; - case EJTAG_VERSION_26: - LOG_DEBUG("EJTAG: Version 2.6 Detected"); - break; - case EJTAG_VERSION_31: - LOG_DEBUG("EJTAG: Version 3.1 Detected"); - break; - case EJTAG_VERSION_41: - LOG_DEBUG("EJTAG: Version 4.1 Detected"); - break; - case EJTAG_VERSION_51: - LOG_DEBUG("EJTAG: Version 5.1 Detected"); - break; - default: - LOG_DEBUG("EJTAG: Unknown Version Detected"); - break; - } - ejtag_main_print_imp(ejtag_info); - - if ((ejtag_info->impcode & EJTAG_IMP_NODMA) == 0) { - LOG_DEBUG("EJTAG: DMA Access Mode detected. Disabling to " - "workaround current broken code."); - ejtag_info->impcode |= EJTAG_IMP_NODMA; - } - - ejtag_info->ejtag_ctrl = EJTAG_CTRL_PRACC | EJTAG_CTRL_PROBEN; - - if (ejtag_info->ejtag_version != EJTAG_VERSION_20) - ejtag_info->ejtag_ctrl |= EJTAG_CTRL_ROCC | EJTAG_CTRL_SETDEV; - - ejtag_info->fast_access_save = -1; - - mips_ejtag_init_mmr(ejtag_info); - - return ERROR_OK; -} - -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); - - 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; - fields[0].out_value = &spracc; - fields[0].in_value = NULL; - - /* processor access data register 32 bit */ - fields[1].num_bits = 32; - fields[1].out_value = t; - - if (write_t) { - fields[1].in_value = NULL; - buf_set_u32(t, 0, 32, *data); - } else - fields[1].in_value = (uint8_t *) data; - - jtag_add_dr_scan(tap, 2, fields, TAP_IDLE); - - if (!write_t && data) - jtag_add_callback(mips_le_to_h_u32, - (jtag_callback_data_t) data); - - keep_alive(); - - return ERROR_OK; -} diff --git a/src/target/mips_ejtag.h b/src/target/mips_ejtag.h deleted file mode 100644 index 6ef08675d..000000000 --- a/src/target/mips_ejtag.h +++ /dev/null @@ -1,235 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2008 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * Copyright (C) 2008 by David T.L. Wong * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifndef OPENOCD_TARGET_MIPS_EJTAG_H -#define OPENOCD_TARGET_MIPS_EJTAG_H - -#include - -/* tap instructions */ -#define EJTAG_INST_IDCODE 0x01 -#define EJTAG_INST_IMPCODE 0x03 -#define EJTAG_INST_ADDRESS 0x08 -#define EJTAG_INST_DATA 0x09 -#define EJTAG_INST_CONTROL 0x0A -#define EJTAG_INST_ALL 0x0B -#define EJTAG_INST_EJTAGBOOT 0x0C -#define EJTAG_INST_NORMALBOOT 0x0D -#define EJTAG_INST_FASTDATA 0x0E -#define EJTAG_INST_TCBCONTROLA 0x10 -#define EJTAG_INST_TCBCONTROLB 0x11 -#define EJTAG_INST_TCBDATA 0x12 -#define EJTAG_INST_BYPASS 0xFF - -/* microchip PIC32MX specific instructions */ -#define MTAP_SW_MTAP 0x04 -#define MTAP_SW_ETAP 0x05 -#define MTAP_COMMAND 0x07 - -/* microchip specific cmds */ -#define MCHP_ASERT_RST 0xd1 -#define MCHP_DE_ASSERT_RST 0xd0 -#define MCHP_ERASE 0xfc -#define MCHP_STATUS 0x00 - -/* ejtag control register bits ECR */ -#define EJTAG_CTRL_TOF (1 << 1) -#define EJTAG_CTRL_TIF (1 << 2) -#define EJTAG_CTRL_BRKST (1 << 3) -#define EJTAG_CTRL_DLOCK (1 << 5) -#define EJTAG_CTRL_DRWN (1 << 9) -#define EJTAG_CTRL_DERR (1 << 10) -#define EJTAG_CTRL_DSTRT (1 << 11) -#define EJTAG_CTRL_JTAGBRK (1 << 12) -#define EJTAG_CTRL_SETDEV (1 << 14) -#define EJTAG_CTRL_PROBEN (1 << 15) -#define EJTAG_CTRL_PRRST (1 << 16) -#define EJTAG_CTRL_DMAACC (1 << 17) -#define EJTAG_CTRL_PRACC (1 << 18) -#define EJTAG_CTRL_PRNW (1 << 19) -#define EJTAG_CTRL_PERRST (1 << 20) -#define EJTAG_CTRL_SYNC (1 << 23) -#define EJTAG_CTRL_DNM (1 << 28) -#define EJTAG_CTRL_ROCC (1 << 31) - -/* Debug Register (CP0 Register 23, Select 0) */ - -#define EJTAG_DEBUG_DSS (1 << 0) -#define EJTAG_DEBUG_DBP (1 << 1) -#define EJTAG_DEBUG_DDBL (1 << 2) -#define EJTAG_DEBUG_DDBS (1 << 3) -#define EJTAG_DEBUG_DIB (1 << 4) -#define EJTAG_DEBUG_DINT (1 << 5) -#define EJTAG_DEBUG_OFFLINE (1 << 7) -#define EJTAG_DEBUG_SST (1 << 8) -#define EJTAG_DEBUG_NOSST (1 << 9) -#define EJTAG_DEBUG_DDBLIMPR (1 << 18) -#define EJTAG_DEBUG_DDBSIMPR (1 << 19) -#define EJTAG_DEBUG_IEXI (1 << 20) -#define EJTAG_DEBUG_DBUSEP (1 << 21) -#define EJTAG_DEBUG_CACHEEP (1 << 22) -#define EJTAG_DEBUG_MCHECKP (1 << 23) -#define EJTAG_DEBUG_IBUSEP (1 << 24) -#define EJTAG_DEBUG_COUNTDM (1 << 25) -#define EJTAG_DEBUG_HALT (1 << 26) -#define EJTAG_DEBUG_DOZE (1 << 27) -#define EJTAG_DEBUG_LSNM (1 << 28) -#define EJTAG_DEBUG_NODCR (1 << 29) -#define EJTAG_DEBUG_DM (1 << 30) -#define EJTAG_DEBUG_DBD (1 << 31) - -/* implementation MIPS register bits. - * Bits marked with V20 or v2.0 mean that, this registers supported only - * by EJTAG v2.0. Bits marked with Lexra or BMIPS are different from the - * official EJATG. - * NOTE: Lexra or BMIPS use EJTAG v2.0 */ - -#define EJTAG_IMP_HAS(x) (ejtag_info->impcode & (x)) -/* v2.0(Lexra) 29 - 1’b1 - Lexra Internal Trace Buffer implemented. This bit - * overlaps with version bit of MIPS EJTAG specification. */ -#define EJTAG_V26_IMP_R3K (1 << 28) -/* v2.0 - 24:25 - 2’b00- No profiling support */ -#define EJTAG_V26_IMP_DINT (1 << 24) -#define EJTAG_V20_IMP_SDBBP (1 << 23) /* 1’b1 - sdbbp is Special2 Opcode */ -#define EJTAG_IMP_ASID8 (1 << 22) -#define EJTAG_IMP_ASID6 (1 << 21) -#define EJTAG_V20_IMP_COMPLEX_BREAK (1 << 20) /* Complex Breaks supported*/ -#define EJTAG_V20_IMP_EADDR_NO32BIT (1 << 19) /* EJTAG_ADDR > 32 bits wide */ -#define EJTAG_V20_IMP_DCACHE_COH (1 << 18) /* DCache does keep DMA coherent */ -#define EJTAG_V20_IMP_ICACHE_COH (1 << 17) /* DCache does keep DMA coherent */ -#define EJTAG_IMP_MIPS16 (1 << 16) -#define EJTAG_IMP_NODMA (1 << 14) -/* v2.0 - 11:13 external PC trace. Trace PC Width. */ -/* v2.0 - 8:10 external PC trace. PCST Width and DCLK Division Factor */ -#define EJTAG_V20_IMP_NOPB (1 << 7) /* no processor breaks */ -#define EJTAG_V20_IMP_NODB (1 << 6) /* no data breaks */ -#define EJTAG_V20_IMP_NOIB (1 << 5) /* no instruction breaks implemented */ -/* v2.0 - 1:4 Number of Break Channels. */ -#define EJTAG_V20_IMP_BCHANNELS_MASK 0xf -#define EJTAG_V20_IMP_BCHANNELS_SHIFT 1 -#define EJTAG_DCR_MIPS64 (1 << 0) - -/* Debug Control Register DCR */ -#define EJTAG_DCR 0xFF300000 -#define EJTAG_DCR_ENM (1 << 29) -#define EJTAG_DCR_DB (1 << 17) -#define EJTAG_DCR_IB (1 << 16) -#define EJTAG_DCR_INTE (1 << 4) -#define EJTAG_DCR_MP (1 << 2) - -/* breakpoint support */ -/* EJTAG_V20_* was tested on Broadcom BCM7401 - * and may or will differ with other hardware. For example EZ4021-FC. */ -#define EJTAG_V20_IBS 0xFF300004 -#define EJTAG_V20_IBA0 0xFF300100 -#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 0xFF300008 -#define EJTAG_V20_DBA0 0xFF300200 -#define EJTAG_V20_DBC_OFFS 0x4 -#define EJTAG_V20_DBM_OFFS 0x8 -#define EJTAG_V20_DBV_OFFS 0xc -#define EJTAG_V20_DBAn_STEP 0x10 - -#define EJTAG_V25_IBS 0xFF301000 -#define EJTAG_V25_IBA0 0xFF301100 -#define EJTAG_V25_IBM_OFFS 0x8 -#define EJTAG_V25_IBASID_OFFS 0x10 -#define EJTAG_V25_IBC_OFFS 0x18 -#define EJTAG_V25_IBAn_STEP 0x100 -#define EJTAG_V25_DBS 0xFF302000 -#define EJTAG_V25_DBA0 0xFF302100 -#define EJTAG_V25_DBM_OFFS 0x8 -#define EJTAG_V25_DBASID_OFFS 0x10 -#define EJTAG_V25_DBC_OFFS 0x18 -#define EJTAG_V25_DBV_OFFS 0x20 -#define EJTAG_V25_DBAn_STEP 0x100 - -#define EJTAG_DBCn_NOSB (1 << 13) -#define EJTAG_DBCn_NOLB (1 << 12) -#define EJTAG_DBCn_BLM_MASK 0xff -#define EJTAG_DBCn_BLM_SHIFT 4 -#define EJTAG_DBCn_BE (1 << 0) - -#define EJTAG_VERSION_20 0 -#define EJTAG_VERSION_25 1 -#define EJTAG_VERSION_26 2 -#define EJTAG_VERSION_31 3 -#define EJTAG_VERSION_41 4 -#define EJTAG_VERSION_51 5 - -struct mips_ejtag { - struct jtag_tap *tap; - uint32_t impcode; - uint32_t idcode; - uint32_t ejtag_ctrl; - int fast_access_save; - uint32_t reg8; - uint32_t reg9; - unsigned scan_delay; - int mode; - uint32_t pa_ctrl; - uint32_t pa_addr; - unsigned int ejtag_version; - - /* Memory-Mapped Registers. This addresses are not same on different - * EJTAG versions. */ - uint32_t debug_caps; - uint32_t ejtag_ibs_addr; /* Instruction Address Break Status */ - uint32_t ejtag_iba0_addr; /* IAB channel 0 */ - uint32_t ejtag_ibc_offs; /* IAB Control offset */ - uint32_t ejtag_ibm_offs; /* IAB Mask offset */ - uint32_t ejtag_ibasid_offs; /* IAB ASID (4Kc) */ - - uint32_t ejtag_dbs_addr; /* Data Address Break Status Register */ - uint32_t ejtag_dba0_addr; /* DAB channel 0 */ - uint32_t ejtag_dbc_offs; /* DAB Control offset */ - uint32_t ejtag_dbm_offs; /* DAB Mask offset */ - uint32_t ejtag_dbv_offs; /* DAB Value offset */ - uint32_t ejtag_dbasid_offs; /* DAB ASID (4Kc) */ - - uint32_t ejtag_iba_step_size; - 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); -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); -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_fastdata_scan(struct mips_ejtag *ejtag_info, int write_t, uint32_t *data); - -int mips_ejtag_init(struct mips_ejtag *ejtag_info); -int mips_ejtag_config_step(struct mips_ejtag *ejtag_info, int enable_step); - -static inline void mips_le_to_h_u32(jtag_callback_data_t arg) -{ - uint8_t *in = (uint8_t *)arg; - *((uint32_t *)arg) = le_to_h_u32(in); -} - -#endif /* OPENOCD_TARGET_MIPS_EJTAG_H */ diff --git a/src/target/mips_m4k.c b/src/target/mips_m4k.c deleted file mode 100644 index 0daa71c52..000000000 --- a/src/target/mips_m4k.c +++ /dev/null @@ -1,1437 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2008 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * Copyright (C) 2008 by David T.L. Wong * - * * - * Copyright (C) 2009 by David N. Claffey * - * * - * Copyright (C) 2011 by Drasko DRASKOVIC * - * drasko.draskovic@gmail.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "breakpoints.h" -#include "mips32.h" -#include "mips_m4k.h" -#include "mips32_dmaacc.h" -#include "target_type.h" -#include "register.h" - -static void mips_m4k_enable_breakpoints(struct target *target); -static void mips_m4k_enable_watchpoints(struct target *target); -static int mips_m4k_set_breakpoint(struct target *target, - struct breakpoint *breakpoint); -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, - int debug_execution); -static int mips_m4k_halt(struct target *target); -static int mips_m4k_bulk_write_memory(struct target *target, uint32_t address, - uint32_t count, const uint8_t *buffer); - -static int mips_m4k_examine_debug_reason(struct target *target) -{ - struct mips32_common *mips32 = target_to_mips32(target); - struct mips_ejtag *ejtag_info = &mips32->ejtag_info; - uint32_t break_status; - int retval; - - if ((target->debug_reason != DBG_REASON_DBGRQ) - && (target->debug_reason != DBG_REASON_SINGLESTEP)) { - if (ejtag_info->debug_caps & EJTAG_DCR_IB) { - /* get info about inst breakpoint support */ - retval = target_read_u32(target, - ejtag_info->ejtag_ibs_addr, &break_status); - if (retval != ERROR_OK) - return retval; - if (break_status & 0x1f) { - /* we have halted on a breakpoint */ - retval = target_write_u32(target, - ejtag_info->ejtag_ibs_addr, 0); - if (retval != ERROR_OK) - return retval; - target->debug_reason = DBG_REASON_BREAKPOINT; - } - } - - if (ejtag_info->debug_caps & EJTAG_DCR_DB) { - /* get info about data breakpoint support */ - retval = target_read_u32(target, - ejtag_info->ejtag_dbs_addr, &break_status); - if (retval != ERROR_OK) - return retval; - if (break_status & 0x1f) { - /* we have halted on a breakpoint */ - retval = target_write_u32(target, - ejtag_info->ejtag_dbs_addr, 0); - if (retval != ERROR_OK) - return retval; - target->debug_reason = DBG_REASON_WATCHPOINT; - } - } - } - - return ERROR_OK; -} - -static int mips_m4k_debug_entry(struct target *target) -{ - struct mips32_common *mips32 = target_to_mips32(target); - struct mips_ejtag *ejtag_info = &mips32->ejtag_info; - - mips32_save_context(target); - - /* make sure stepping disabled, SSt bit in CP0 debug register cleared */ - mips_ejtag_config_step(ejtag_info, 0); - - /* make sure break unit configured */ - mips32_configure_break_unit(target); - - /* attempt to find halt reason */ - mips_m4k_examine_debug_reason(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); - - 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), - target_state_name(target)); - - return ERROR_OK; -} - -static struct target *get_mips_m4k(struct target *target, int32_t coreid) -{ - struct target_list *head; - struct target *curr; - - head = target->head; - while (head != (struct target_list *)NULL) { - curr = head->target; - if ((curr->coreid == coreid) && (curr->state == TARGET_HALTED)) - return curr; - head = head->next; - } - return target; -} - -static int mips_m4k_halt_smp(struct target *target) -{ - int retval = ERROR_OK; - struct target_list *head; - struct target *curr; - head = target->head; - while (head != (struct target_list *)NULL) { - int ret = ERROR_OK; - curr = head->target; - if ((curr != target) && (curr->state != TARGET_HALTED)) - ret = mips_m4k_halt(curr); - - if (ret != ERROR_OK) { - LOG_ERROR("halt failed target->coreid: %" PRId32, curr->coreid); - retval = ret; - } - head = head->next; - } - return retval; -} - -static int update_halt_gdb(struct target *target) -{ - int retval = ERROR_OK; - if (target->gdb_service->core[0] == -1) { - target->gdb_service->target = target; - target->gdb_service->core[0] = target->coreid; - retval = mips_m4k_halt_smp(target); - } - return retval; -} - -static int mips_m4k_poll(struct target *target) -{ - int retval = ERROR_OK; - struct mips32_common *mips32 = target_to_mips32(target); - struct mips_ejtag *ejtag_info = &mips32->ejtag_info; - uint32_t ejtag_ctrl = ejtag_info->ejtag_ctrl; - enum target_state prev_target_state = target->state; - - /* toggle to another core is done by gdb as follow */ - /* maint packet J core_id */ - /* continue */ - /* the next polling trigger an halt event sent to gdb */ - if ((target->state == TARGET_HALTED) && (target->smp) && - (target->gdb_service) && - (target->gdb_service->target == NULL)) { - target->gdb_service->target = - get_mips_m4k(target, target->gdb_service->core[1]); - target_call_event_callbacks(target, TARGET_EVENT_HALTED); - return retval; - } - - /* read ejtag control reg */ - mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL); - retval = mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl); - if (retval != ERROR_OK) - return retval; - - /* clear this bit before handling polling - * as after reset registers will read zero */ - if (ejtag_ctrl & EJTAG_CTRL_ROCC) { - /* we have detected a reset, clear flag - * otherwise ejtag will not work */ - ejtag_ctrl = ejtag_info->ejtag_ctrl & ~EJTAG_CTRL_ROCC; - - mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL); - retval = mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl); - if (retval != ERROR_OK) - return retval; - LOG_DEBUG("Reset Detected"); - } - - /* check for processor halted */ - if (ejtag_ctrl & EJTAG_CTRL_BRKST) { - if ((target->state != TARGET_HALTED) - && (target->state != TARGET_DEBUG_RUNNING)) { - if (target->state == TARGET_UNKNOWN) - LOG_DEBUG("EJTAG_CTRL_BRKST already set during server startup."); - - /* OpenOCD was was probably started on the board with EJTAG_CTRL_BRKST already set - * (maybe put on by HALT-ing the board in the previous session). - * - * Force enable debug entry for this session. - */ - mips_ejtag_set_instr(ejtag_info, EJTAG_INST_NORMALBOOT); - target->state = TARGET_HALTED; - retval = mips_m4k_debug_entry(target); - if (retval != ERROR_OK) - return retval; - - if (target->smp && - ((prev_target_state == TARGET_RUNNING) - || (prev_target_state == TARGET_RESET))) { - retval = update_halt_gdb(target); - if (retval != ERROR_OK) - return retval; - } - target_call_event_callbacks(target, TARGET_EVENT_HALTED); - } else if (target->state == TARGET_DEBUG_RUNNING) { - target->state = TARGET_HALTED; - - retval = mips_m4k_debug_entry(target); - if (retval != ERROR_OK) - return retval; - - if (target->smp) { - retval = update_halt_gdb(target); - if (retval != ERROR_OK) - return retval; - } - - target_call_event_callbacks(target, TARGET_EVENT_DEBUG_HALTED); - } - } else - target->state = TARGET_RUNNING; - -/* LOG_DEBUG("ctrl = 0x%08X", ejtag_ctrl); */ - - return ERROR_OK; -} - -static int mips_m4k_halt(struct target *target) -{ - struct mips32_common *mips32 = target_to_mips32(target); - struct mips_ejtag *ejtag_info = &mips32->ejtag_info; - - LOG_DEBUG("target->state: %s", target_state_name(target)); - - if (target->state == TARGET_HALTED) { - LOG_DEBUG("target was already halted"); - return ERROR_OK; - } - - if (target->state == TARGET_UNKNOWN) - LOG_WARNING("target was in unknown state when halt was requested"); - - if (target->state == TARGET_RESET) { - if ((jtag_get_reset_config() & RESET_SRST_PULLS_TRST) && jtag_get_srst()) { - LOG_ERROR("can't request a halt while in reset if nSRST pulls nTRST"); - return ERROR_TARGET_FAILURE; - } else { - /* we came here in a reset_halt or reset_init sequence - * debug entry was already prepared in mips_m4k_assert_reset() - */ - target->debug_reason = DBG_REASON_DBGRQ; - - return ERROR_OK; - } - } - - /* break processor */ - mips_ejtag_enter_debug(ejtag_info); - - target->debug_reason = DBG_REASON_DBGRQ; - - return ERROR_OK; -} - -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)); - - enum reset_types jtag_reset_config = jtag_get_reset_config(); - - /* some cores support connecting while srst is asserted - * use that mode is it has been configured */ - - bool srst_asserted = false; - - if (!(jtag_reset_config & RESET_SRST_PULLS_TRST) && - (jtag_reset_config & RESET_SRST_NO_GATING)) { - jtag_add_reset(0, 1); - srst_asserted = true; - } - - - /* EJTAG before v2.5/2.6 does not support EJTAGBOOT or NORMALBOOT */ - if (ejtag_info->ejtag_version != EJTAG_VERSION_20) { - if (target->reset_halt) { - /* use hardware to catch reset */ - mips_ejtag_set_instr(ejtag_info, EJTAG_INST_EJTAGBOOT); - } else - mips_ejtag_set_instr(ejtag_info, EJTAG_INST_NORMALBOOT); - } - - if (jtag_reset_config & RESET_HAS_SRST) { - /* here we should issue a srst only, but we may have to assert trst as well */ - if (jtag_reset_config & RESET_SRST_PULLS_TRST) - jtag_add_reset(1, 1); - else if (!srst_asserted) - jtag_add_reset(0, 1); - } else { - if (mips_m4k->is_pic32mx) { - LOG_DEBUG("Using MTAP reset to reset processor..."); - - /* use microchip specific MTAP reset */ - mips_ejtag_set_instr(ejtag_info, MTAP_SW_MTAP); - mips_ejtag_set_instr(ejtag_info, MTAP_COMMAND); - - mips_ejtag_drscan_8_out(ejtag_info, MCHP_ASERT_RST); - mips_ejtag_drscan_8_out(ejtag_info, MCHP_DE_ASSERT_RST); - mips_ejtag_set_instr(ejtag_info, MTAP_SW_ETAP); - } else { - /* use ejtag reset - not supported by all cores */ - uint32_t ejtag_ctrl = ejtag_info->ejtag_ctrl | EJTAG_CTRL_PRRST | EJTAG_CTRL_PERRST; - LOG_DEBUG("Using EJTAG reset (PRRST) to reset processor..."); - mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL); - mips_ejtag_drscan_32_out(ejtag_info, ejtag_ctrl); - } - } - - target->state = TARGET_RESET; - jtag_add_sleep(50000); - - register_cache_invalidate(mips_m4k->mips32.core_cache); - - if (target->reset_halt) { - int retval = target_halt(target); - if (retval != ERROR_OK) - return retval; - } - - return ERROR_OK; -} - -static int mips_m4k_deassert_reset(struct target *target) -{ - LOG_DEBUG("target->state: %s", target_state_name(target)); - - /* deassert reset lines */ - jtag_add_reset(0, 0); - - return ERROR_OK; -} - -static int mips_m4k_single_step_core(struct target *target) -{ - struct mips32_common *mips32 = target_to_mips32(target); - struct mips_ejtag *ejtag_info = &mips32->ejtag_info; - - /* configure single step mode */ - mips_ejtag_config_step(ejtag_info, 1); - - /* disable interrupts while stepping */ - mips32_enable_interrupts(target, 0); - - /* exit debug mode */ - mips_ejtag_exit_debug(ejtag_info); - - mips_m4k_debug_entry(target); - - return ERROR_OK; -} - -static int mips_m4k_restore_smp(struct target *target, uint32_t address, int handle_breakpoints) -{ - int retval = ERROR_OK; - struct target_list *head; - struct target *curr; - - head = target->head; - while (head != (struct target_list *)NULL) { - int ret = ERROR_OK; - curr = head->target; - if ((curr != target) && (curr->state != TARGET_RUNNING)) { - /* resume current address , not in step mode */ - ret = mips_m4k_internal_restore(curr, 1, address, - handle_breakpoints, 0); - - if (ret != ERROR_OK) { - LOG_ERROR("target->coreid :%" PRId32 " failed to resume at address :0x%" PRIx32, - curr->coreid, address); - retval = ret; - } - } - head = head->next; - } - return retval; -} - -static int mips_m4k_internal_restore(struct target *target, int current, - uint32_t address, int handle_breakpoints, int debug_execution) -{ - struct mips32_common *mips32 = target_to_mips32(target); - struct mips_ejtag *ejtag_info = &mips32->ejtag_info; - struct breakpoint *breakpoint = NULL; - uint32_t resume_pc; - - if (target->state != TARGET_HALTED) { - LOG_WARNING("target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - if (!debug_execution) { - target_free_all_working_areas(target); - mips_m4k_enable_breakpoints(target); - mips_m4k_enable_watchpoints(target); - } - - /* current = 1: continue on current pc, otherwise continue at
*/ - if (!current) { - 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) - buf_set_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 1, mips32->isa_mode); - - if (!current) - resume_pc = address; - else - resume_pc = buf_get_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 32); - - mips32_restore_context(target); - - /* the front-end may request us not to handle breakpoints */ - if (handle_breakpoints) { - /* 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); - mips_m4k_unset_breakpoint(target, breakpoint); - mips_m4k_single_step_core(target); - mips_m4k_set_breakpoint(target, breakpoint); - } - } - - /* enable interrupts if we are running */ - mips32_enable_interrupts(target, !debug_execution); - - /* exit debug mode */ - mips_ejtag_exit_debug(ejtag_info); - target->debug_reason = DBG_REASON_NOTHALTED; - - /* registers are now invalid */ - register_cache_invalidate(mips32->core_cache); - - if (!debug_execution) { - target->state = TARGET_RUNNING; - target_call_event_callbacks(target, TARGET_EVENT_RESUMED); - LOG_DEBUG("target resumed at 0x%" PRIx32 "", resume_pc); - } else { - target->state = TARGET_DEBUG_RUNNING; - target_call_event_callbacks(target, TARGET_EVENT_DEBUG_RESUMED); - LOG_DEBUG("target debug resumed at 0x%" PRIx32 "", resume_pc); - } - - return ERROR_OK; -} - -static int mips_m4k_resume(struct target *target, int current, - uint32_t address, int handle_breakpoints, int debug_execution) -{ - int retval = ERROR_OK; - - /* dummy resume for smp toggle in order to reduce gdb impact */ - if ((target->smp) && (target->gdb_service->core[1] != -1)) { - /* simulate a start and halt of target */ - target->gdb_service->target = NULL; - target->gdb_service->core[0] = target->gdb_service->core[1]; - /* fake resume at next poll we play the target core[1], see poll*/ - target_call_event_callbacks(target, TARGET_EVENT_RESUMED); - return retval; - } - - retval = mips_m4k_internal_restore(target, current, address, - handle_breakpoints, - debug_execution); - - if (retval == ERROR_OK && target->smp) { - target->gdb_service->core[0] = -1; - retval = mips_m4k_restore_smp(target, address, handle_breakpoints); - } - - return retval; -} - -static int mips_m4k_step(struct target *target, int current, - uint32_t address, int handle_breakpoints) -{ - /* get pointers to arch-specific information */ - struct mips32_common *mips32 = target_to_mips32(target); - struct mips_ejtag *ejtag_info = &mips32->ejtag_info; - struct breakpoint *breakpoint = NULL; - - if (target->state != TARGET_HALTED) { - LOG_WARNING("target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - /* current = 1: continue on current pc, otherwise continue at
*/ - if (!current) { - 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; - } - - /* the front-end may request us not to handle breakpoints */ - if (handle_breakpoints) { - breakpoint = breakpoint_find(target, - buf_get_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 32)); - if (breakpoint) - mips_m4k_unset_breakpoint(target, breakpoint); - } - - /* restore context */ - mips32_restore_context(target); - - /* configure single step mode */ - mips_ejtag_config_step(ejtag_info, 1); - - target->debug_reason = DBG_REASON_SINGLESTEP; - - target_call_event_callbacks(target, TARGET_EVENT_RESUMED); - - /* disable interrupts while stepping */ - mips32_enable_interrupts(target, 0); - - /* exit debug mode */ - mips_ejtag_exit_debug(ejtag_info); - - /* registers are now invalid */ - register_cache_invalidate(mips32->core_cache); - - LOG_DEBUG("target stepped "); - mips_m4k_debug_entry(target); - - if (breakpoint) - mips_m4k_set_breakpoint(target, breakpoint); - - target_call_event_callbacks(target, TARGET_EVENT_HALTED); - - return ERROR_OK; -} - -static void mips_m4k_enable_breakpoints(struct target *target) -{ - struct breakpoint *breakpoint = target->breakpoints; - - /* set any pending breakpoints */ - while (breakpoint) { - if (breakpoint->set == 0) - mips_m4k_set_breakpoint(target, breakpoint); - breakpoint = breakpoint->next; - } -} - -static int mips_m4k_set_breakpoint(struct target *target, - struct breakpoint *breakpoint) -{ - struct mips32_common *mips32 = target_to_mips32(target); - struct mips_ejtag *ejtag_info = &mips32->ejtag_info; - struct mips32_comparator *comparator_list = mips32->inst_break_list; - int retval; - - if (breakpoint->set) { - LOG_WARNING("breakpoint already set"); - return ERROR_OK; - } - - if (breakpoint->type == BKPT_HARD) { - int bp_num = 0; - - while (comparator_list[bp_num].used && (bp_num < mips32->num_inst_bpoints)) - bp_num++; - if (bp_num >= mips32->num_inst_bpoints) { - LOG_ERROR("Can not find free FP Comparator(bpid: %" PRIu32 ")", - breakpoint->unique_id); - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - } - breakpoint->set = bp_num + 1; - comparator_list[bp_num].used = 1; - comparator_list[bp_num].bp_value = breakpoint->address; - - /* 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! :) */ - if (ejtag_info->ejtag_version == EJTAG_VERSION_20) - comparator_list[bp_num].bp_value &= 0xFFFFFFFC; - - target_write_u32(target, comparator_list[bp_num].reg_address, - comparator_list[bp_num].bp_value); - target_write_u32(target, comparator_list[bp_num].reg_address + - ejtag_info->ejtag_ibm_offs, 0x00000000); - target_write_u32(target, comparator_list[bp_num].reg_address + - ejtag_info->ejtag_ibc_offs, 1); - LOG_DEBUG("bpid: %" PRIu32 ", bp_num %i bp_value 0x%" PRIx32 "", - breakpoint->unique_id, - 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 verify = 0xffffffff; - - 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; - - 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); - return ERROR_OK; - } - } else { - uint16_t verify = 0xffff; - - retval = target_read_memory(target, breakpoint->address, breakpoint->length, 1, - breakpoint->orig_instr); - if (retval != ERROR_OK) - return retval; - retval = target_write_u16(target, breakpoint->address, MIPS16_SDBBP); - if (retval != ERROR_OK) - return retval; - - retval = target_read_u16(target, breakpoint->address, &verify); - if (retval != ERROR_OK) - return retval; - if (verify != MIPS16_SDBBP) { - LOG_ERROR("Unable to set 16bit breakpoint at address %08" PRIx32 - " - check that memory is read/writable", breakpoint->address); - return ERROR_OK; - } - } - - breakpoint->set = 20; /* Any nice value but 0 */ - } - - return ERROR_OK; -} - -static int mips_m4k_unset_breakpoint(struct target *target, - struct breakpoint *breakpoint) -{ - /* get pointers to arch-specific information */ - struct mips32_common *mips32 = target_to_mips32(target); - struct mips_ejtag *ejtag_info = &mips32->ejtag_info; - struct mips32_comparator *comparator_list = mips32->inst_break_list; - int retval; - - if (!breakpoint->set) { - LOG_WARNING("breakpoint not set"); - return ERROR_OK; - } - - if (breakpoint->type == BKPT_HARD) { - int bp_num = breakpoint->set - 1; - if ((bp_num < 0) || (bp_num >= mips32->num_inst_bpoints)) { - LOG_DEBUG("Invalid FP Comparator number in breakpoint (bpid: %" PRIu32 ")", - breakpoint->unique_id); - return ERROR_OK; - } - LOG_DEBUG("bpid: %" PRIu32 " - releasing hw: %d", - breakpoint->unique_id, - bp_num); - comparator_list[bp_num].used = 0; - comparator_list[bp_num].bp_value = 0; - target_write_u32(target, comparator_list[bp_num].reg_address + - ejtag_info->ejtag_ibc_offs, 0); - - } else { - /* restore original instruction (kept in target endianness) */ - 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 (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); - if (retval != ERROR_OK) - return retval; - current_instr = target_buffer_get_u16(target, (uint8_t *)¤t_instr); - if (current_instr == MIPS16_SDBBP) { - retval = target_write_memory(target, breakpoint->address, 2, 1, - breakpoint->orig_instr); - if (retval != ERROR_OK) - return retval; - } - } - } - breakpoint->set = 0; - - return ERROR_OK; -} - -static int mips_m4k_add_breakpoint(struct target *target, struct breakpoint *breakpoint) -{ - struct mips32_common *mips32 = target_to_mips32(target); - - if (breakpoint->type == BKPT_HARD) { - if (mips32->num_inst_bpoints_avail < 1) { - LOG_INFO("no hardware breakpoint available"); - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - } - - mips32->num_inst_bpoints_avail--; - } - - return mips_m4k_set_breakpoint(target, breakpoint); -} - -static int mips_m4k_remove_breakpoint(struct target *target, - struct breakpoint *breakpoint) -{ - /* get pointers to arch-specific information */ - struct mips32_common *mips32 = target_to_mips32(target); - - if (target->state != TARGET_HALTED) { - LOG_WARNING("target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - if (breakpoint->set) - mips_m4k_unset_breakpoint(target, breakpoint); - - if (breakpoint->type == BKPT_HARD) - mips32->num_inst_bpoints_avail++; - - return ERROR_OK; -} - -static int mips_m4k_set_watchpoint(struct target *target, - struct watchpoint *watchpoint) -{ - struct mips32_common *mips32 = target_to_mips32(target); - struct mips_ejtag *ejtag_info = &mips32->ejtag_info; - struct mips32_comparator *comparator_list = mips32->data_break_list; - int wp_num = 0; - /* - * watchpoint enabled, ignore all byte lanes in value register - * and exclude both load and store accesses from watchpoint - * condition evaluation - */ - int enable = EJTAG_DBCn_NOSB | EJTAG_DBCn_NOLB | EJTAG_DBCn_BE | - (0xff << EJTAG_DBCn_BLM_SHIFT); - - if (watchpoint->set) { - LOG_WARNING("watchpoint already set"); - return ERROR_OK; - } - - while (comparator_list[wp_num].used && (wp_num < mips32->num_data_bpoints)) - wp_num++; - if (wp_num >= mips32->num_data_bpoints) { - LOG_ERROR("Can not find free FP Comparator"); - return ERROR_FAIL; - } - - if (watchpoint->length != 4) { - LOG_ERROR("Only watchpoints of length 4 are supported"); - return ERROR_TARGET_UNALIGNED_ACCESS; - } - - if (watchpoint->address % 4) { - LOG_ERROR("Watchpoints address should be word aligned"); - return ERROR_TARGET_UNALIGNED_ACCESS; - } - - switch (watchpoint->rw) { - case WPT_READ: - enable &= ~EJTAG_DBCn_NOLB; - break; - case WPT_WRITE: - enable &= ~EJTAG_DBCn_NOSB; - break; - case WPT_ACCESS: - enable &= ~(EJTAG_DBCn_NOLB | EJTAG_DBCn_NOSB); - break; - default: - LOG_ERROR("BUG: watchpoint->rw neither read, write nor access"); - } - - watchpoint->set = wp_num + 1; - comparator_list[wp_num].used = 1; - comparator_list[wp_num].bp_value = watchpoint->address; - - /* EJTAG 2.0 uses 29bit DBA. First 3 bits are reserved. - * There is as well no ASID register support. */ - if (ejtag_info->ejtag_version == EJTAG_VERSION_20) - comparator_list[wp_num].bp_value &= 0xFFFFFFF8; - else - target_write_u32(target, comparator_list[wp_num].reg_address + - ejtag_info->ejtag_dbasid_offs, 0x00000000); - - target_write_u32(target, comparator_list[wp_num].reg_address, - comparator_list[wp_num].bp_value); - target_write_u32(target, comparator_list[wp_num].reg_address + - ejtag_info->ejtag_dbm_offs, 0x00000000); - - target_write_u32(target, comparator_list[wp_num].reg_address + - ejtag_info->ejtag_dbc_offs, enable); - /* TODO: probably this value is ignored on 2.0 */ - target_write_u32(target, comparator_list[wp_num].reg_address + - ejtag_info->ejtag_dbv_offs, 0); - LOG_DEBUG("wp_num %i bp_value 0x%" PRIx32 "", wp_num, comparator_list[wp_num].bp_value); - - return ERROR_OK; -} - -static int mips_m4k_unset_watchpoint(struct target *target, - struct watchpoint *watchpoint) -{ - /* get pointers to arch-specific information */ - struct mips32_common *mips32 = target_to_mips32(target); - struct mips_ejtag *ejtag_info = &mips32->ejtag_info; - struct mips32_comparator *comparator_list = mips32->data_break_list; - - if (!watchpoint->set) { - LOG_WARNING("watchpoint not set"); - return ERROR_OK; - } - - int wp_num = watchpoint->set - 1; - if ((wp_num < 0) || (wp_num >= mips32->num_data_bpoints)) { - LOG_DEBUG("Invalid FP Comparator number in watchpoint"); - return ERROR_OK; - } - comparator_list[wp_num].used = 0; - comparator_list[wp_num].bp_value = 0; - target_write_u32(target, comparator_list[wp_num].reg_address + - ejtag_info->ejtag_dbc_offs, 0); - watchpoint->set = 0; - - return ERROR_OK; -} - -static int mips_m4k_add_watchpoint(struct target *target, struct watchpoint *watchpoint) -{ - struct mips32_common *mips32 = target_to_mips32(target); - - if (mips32->num_data_bpoints_avail < 1) { - LOG_INFO("no hardware watchpoints available"); - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - } - - mips32->num_data_bpoints_avail--; - - mips_m4k_set_watchpoint(target, watchpoint); - return ERROR_OK; -} - -static int mips_m4k_remove_watchpoint(struct target *target, - struct watchpoint *watchpoint) -{ - /* get pointers to arch-specific information */ - struct mips32_common *mips32 = target_to_mips32(target); - - if (target->state != TARGET_HALTED) { - LOG_WARNING("target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - if (watchpoint->set) - mips_m4k_unset_watchpoint(target, watchpoint); - - mips32->num_data_bpoints_avail++; - - return ERROR_OK; -} - -static void mips_m4k_enable_watchpoints(struct target *target) -{ - struct watchpoint *watchpoint = target->watchpoints; - - /* set any pending watchpoints */ - while (watchpoint) { - if (watchpoint->set == 0) - mips_m4k_set_watchpoint(target, watchpoint); - watchpoint = watchpoint->next; - } -} - -static int mips_m4k_read_memory(struct target *target, uint32_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 "", - address, size, count); - - if (target->state != TARGET_HALTED) { - LOG_WARNING("target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - /* sanitize arguments */ - if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer)) - return ERROR_COMMAND_SYNTAX_ERROR; - - if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u))) - return ERROR_TARGET_UNALIGNED_ACCESS; - - /* since we don't know if buffer is aligned, we allocate new mem that is always aligned */ - void *t = NULL; - - if (size > 1) { - t = malloc(count * size * sizeof(uint8_t)); - if (t == NULL) { - LOG_ERROR("Out of memory"); - return ERROR_FAIL; - } - } else - t = buffer; - - /* if noDMA off, use DMAACC mode for memory read */ - int retval; - if (ejtag_info->impcode & EJTAG_IMP_NODMA) - retval = mips32_pracc_read_mem(ejtag_info, address, size, count, t); - else - retval = mips32_dmaacc_read_mem(ejtag_info, address, size, count, t); - - /* mips32_..._read_mem with size 4/2 returns uint32_t/uint16_t in host */ - /* endianness, but byte array should represent target endianness */ - if (ERROR_OK == retval) { - switch (size) { - case 4: - target_buffer_set_u32_array(target, buffer, count, t); - break; - case 2: - target_buffer_set_u16_array(target, buffer, count, t); - break; - } - } - - if ((size > 1) && (t != NULL)) - free(t); - - return retval; -} - -static int mips_m4k_write_memory(struct target *target, uint32_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 "", - address, size, count); - - if (target->state != TARGET_HALTED) { - LOG_WARNING("target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - if (size == 4 && count > 32) { - int retval = mips_m4k_bulk_write_memory(target, address, count, buffer); - if (retval == ERROR_OK) - return ERROR_OK; - LOG_WARNING("Falling back to non-bulk write"); - } - - /* sanitize arguments */ - if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer)) - return ERROR_COMMAND_SYNTAX_ERROR; - - if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u))) - return ERROR_TARGET_UNALIGNED_ACCESS; - - /** correct endianess if we have word or hword access */ - void *t = NULL; - if (size > 1) { - /* mips32_..._write_mem with size 4/2 requires uint32_t/uint16_t in host */ - /* endianness, but byte array represents target endianness */ - t = malloc(count * size * sizeof(uint8_t)); - if (t == NULL) { - LOG_ERROR("Out of memory"); - return ERROR_FAIL; - } - - switch (size) { - case 4: - target_buffer_get_u32_array(target, buffer, count, (uint32_t *)t); - break; - case 2: - target_buffer_get_u16_array(target, buffer, count, (uint16_t *)t); - break; - } - buffer = t; - } - - /* if noDMA off, use DMAACC mode for memory write */ - int retval; - if (ejtag_info->impcode & EJTAG_IMP_NODMA) - retval = mips32_pracc_write_mem(ejtag_info, address, size, count, buffer); - else - retval = mips32_dmaacc_write_mem(ejtag_info, address, size, count, buffer); - - if (t != NULL) - free(t); - - if (ERROR_OK != retval) - return retval; - - return ERROR_OK; -} - -static int mips_m4k_init_target(struct command_context *cmd_ctx, - struct target *target) -{ - mips32_build_reg_cache(target); - - return ERROR_OK; -} - -static int mips_m4k_init_arch_info(struct target *target, - struct mips_m4k_common *mips_m4k, struct jtag_tap *tap) -{ - struct mips32_common *mips32 = &mips_m4k->mips32; - - mips_m4k->common_magic = MIPSM4K_COMMON_MAGIC; - - /* initialize mips4k specific info */ - mips32_init_arch_info(target, mips32, tap); - mips32->arch_info = mips_m4k; - - return ERROR_OK; -} - -static int mips_m4k_target_create(struct target *target, Jim_Interp *interp) -{ - struct mips_m4k_common *mips_m4k = calloc(1, sizeof(struct mips_m4k_common)); - - mips_m4k_init_arch_info(target, mips_m4k, target->tap); - - return ERROR_OK; -} - -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) - return retval; - ejtag_info->idcode = idcode; - - if (((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"); - mips_m4k->is_pic32mx = true; - } - } - - /* init rest of ejtag interface */ - 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; -} - -static int mips_m4k_bulk_write_memory(struct target *target, uint32_t address, - uint32_t count, const uint8_t *buffer) -{ - struct mips32_common *mips32 = target_to_mips32(target); - struct mips_ejtag *ejtag_info = &mips32->ejtag_info; - struct working_area *fast_data_area; - int retval; - int write_t = 1; - - LOG_DEBUG("address: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32 "", address, count); - - /* check alignment */ - if (address & 0x3u) - return ERROR_TARGET_UNALIGNED_ACCESS; - - if (mips32->fast_data_area == NULL) { - /* Get memory for block write handler - * we preserve this area between calls and gain a speed increase - * of about 3kb/sec when writing flash - * this will be released/nulled by the system when the target is resumed or reset */ - retval = target_alloc_working_area(target, - MIPS32_FASTDATA_HANDLER_SIZE, - &mips32->fast_data_area); - if (retval != ERROR_OK) { - LOG_ERROR("No working area available"); - return retval; - } - - /* reset fastadata state so the algo get reloaded */ - ejtag_info->fast_access_save = -1; - } - - fast_data_area = mips32->fast_data_area; - - 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 ").", - fast_data_area->address, address, address + count); - LOG_ERROR("Change work-area-phys or load_image address!"); - return ERROR_FAIL; - } - - /* mips32_pracc_fastdata_xfer requires uint32_t in host endianness, */ - /* but byte array represents target endianness */ - uint32_t *t = NULL; - t = malloc(count * sizeof(uint32_t)); - if (t == NULL) { - LOG_ERROR("Out of memory"); - return ERROR_FAIL; - } - - target_buffer_get_u32_array(target, buffer, count, t); - - retval = mips32_pracc_fastdata_xfer(ejtag_info, mips32->fast_data_area, write_t, address, - count, t); - - if (t != NULL) - free(t); - - if (retval != ERROR_OK) - LOG_ERROR("Fastdata access Failed"); - - return retval; -} - -static int mips_m4k_verify_pointer(struct command_context *cmd_ctx, - struct mips_m4k_common *mips_m4k) -{ - if (mips_m4k->common_magic != MIPSM4K_COMMON_MAGIC) { - command_print(cmd_ctx, "target is not an MIPS_M4K"); - return ERROR_TARGET_INVALID; - } - return ERROR_OK; -} - -COMMAND_HANDLER(mips_m4k_handle_cp0_command) -{ - int retval; - struct target *target = get_current_target(CMD_CTX); - struct mips_m4k_common *mips_m4k = target_to_m4k(target); - struct mips_ejtag *ejtag_info = &mips_m4k->mips32.ejtag_info; - - retval = mips_m4k_verify_pointer(CMD_CTX, mips_m4k); - if (retval != ERROR_OK) - return retval; - - if (target->state != TARGET_HALTED) { - command_print(CMD_CTX, "target must be stopped for \"%s\" command", CMD_NAME); - return ERROR_OK; - } - - /* two or more argument, access a single register/select (write if third argument is given) */ - if (CMD_ARGC < 2) - return ERROR_COMMAND_SYNTAX_ERROR; - else { - uint32_t cp0_reg, cp0_sel; - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], cp0_reg); - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], cp0_sel); - - if (CMD_ARGC == 2) { - uint32_t value; - retval = mips32_cp0_read(ejtag_info, &value, cp0_reg, cp0_sel); - if (retval != ERROR_OK) { - command_print(CMD_CTX, - "couldn't access reg %" PRIi32, - cp0_reg); - return ERROR_OK; - } - command_print(CMD_CTX, "cp0 reg %" PRIi32 ", select %" PRIi32 ": %8.8" PRIx32, - cp0_reg, cp0_sel, value); - - } else if (CMD_ARGC == 3) { - uint32_t value; - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], value); - retval = mips32_cp0_write(ejtag_info, value, cp0_reg, cp0_sel); - if (retval != ERROR_OK) { - command_print(CMD_CTX, - "couldn't access cp0 reg %" PRIi32 ", select %" PRIi32, - cp0_reg, cp0_sel); - return ERROR_OK; - } - command_print(CMD_CTX, "cp0 reg %" PRIi32 ", select %" PRIi32 ": %8.8" PRIx32, - cp0_reg, cp0_sel, value); - } - } - - return ERROR_OK; -} - -COMMAND_HANDLER(mips_m4k_handle_smp_off_command) -{ - struct target *target = get_current_target(CMD_CTX); - /* check target is an smp target */ - struct target_list *head; - struct target *curr; - head = target->head; - target->smp = 0; - if (head != (struct target_list *)NULL) { - while (head != (struct target_list *)NULL) { - curr = head->target; - curr->smp = 0; - head = head->next; - } - /* fixes the target display to the debugger */ - target->gdb_service->target = target; - } - return ERROR_OK; -} - -COMMAND_HANDLER(mips_m4k_handle_smp_on_command) -{ - struct target *target = get_current_target(CMD_CTX); - struct target_list *head; - struct target *curr; - head = target->head; - if (head != (struct target_list *)NULL) { - target->smp = 1; - while (head != (struct target_list *)NULL) { - curr = head->target; - curr->smp = 1; - head = head->next; - } - } - return ERROR_OK; -} - -COMMAND_HANDLER(mips_m4k_handle_smp_gdb_command) -{ - struct target *target = get_current_target(CMD_CTX); - int retval = ERROR_OK; - struct target_list *head; - head = target->head; - if (head != (struct target_list *)NULL) { - if (CMD_ARGC == 1) { - int coreid = 0; - COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], coreid); - if (ERROR_OK != retval) - return retval; - target->gdb_service->core[1] = coreid; - - } - command_print(CMD_CTX, "gdb coreid %" PRId32 " -> %" PRId32, target->gdb_service->core[0] - , target->gdb_service->core[1]); - } - return ERROR_OK; -} - -COMMAND_HANDLER(mips_m4k_handle_scan_delay_command) -{ - struct target *target = get_current_target(CMD_CTX); - struct mips_m4k_common *mips_m4k = target_to_m4k(target); - struct mips_ejtag *ejtag_info = &mips_m4k->mips32.ejtag_info; - - if (CMD_ARGC == 1) - COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], ejtag_info->scan_delay); - else if (CMD_ARGC > 1) - return ERROR_COMMAND_SYNTAX_ERROR; - - command_print(CMD_CTX, "scan delay: %d nsec", ejtag_info->scan_delay); - if (ejtag_info->scan_delay >= 2000000) { - ejtag_info->mode = 0; - command_print(CMD_CTX, "running in legacy mode"); - } else { - ejtag_info->mode = 1; - command_print(CMD_CTX, "running in fast queued mode"); - } - - return ERROR_OK; -} - -static const struct command_registration mips_m4k_exec_command_handlers[] = { - { - .name = "cp0", - .handler = mips_m4k_handle_cp0_command, - .mode = COMMAND_EXEC, - .usage = "regnum [value]", - .help = "display/modify cp0 register", - }, - { - .name = "smp_off", - .handler = mips_m4k_handle_smp_off_command, - .mode = COMMAND_EXEC, - .help = "Stop smp handling", - .usage = "",}, - - { - .name = "smp_on", - .handler = mips_m4k_handle_smp_on_command, - .mode = COMMAND_EXEC, - .help = "Restart smp handling", - .usage = "", - }, - { - .name = "smp_gdb", - .handler = mips_m4k_handle_smp_gdb_command, - .mode = COMMAND_EXEC, - .help = "display/fix current core played to gdb", - .usage = "", - }, - { - .name = "scan_delay", - .handler = mips_m4k_handle_scan_delay_command, - .mode = COMMAND_ANY, - .help = "display/set scan delay in nano seconds", - .usage = "[value]", - }, - COMMAND_REGISTRATION_DONE -}; - -const struct command_registration mips_m4k_command_handlers[] = { - { - .chain = mips32_command_handlers, - }, - { - .name = "mips_m4k", - .mode = COMMAND_ANY, - .help = "mips_m4k command group", - .usage = "", - .chain = mips_m4k_exec_command_handlers, - }, - COMMAND_REGISTRATION_DONE -}; - -struct target_type mips_m4k_target = { - .name = "mips_m4k", - - .poll = mips_m4k_poll, - .arch_state = mips32_arch_state, - - .halt = mips_m4k_halt, - .resume = mips_m4k_resume, - .step = mips_m4k_step, - - .assert_reset = mips_m4k_assert_reset, - .deassert_reset = mips_m4k_deassert_reset, - - .get_gdb_reg_list = mips32_get_gdb_reg_list, - - .read_memory = mips_m4k_read_memory, - .write_memory = mips_m4k_write_memory, - .checksum_memory = mips32_checksum_memory, - .blank_check_memory = mips32_blank_check_memory, - - .run_algorithm = mips32_run_algorithm, - - .add_breakpoint = mips_m4k_add_breakpoint, - .remove_breakpoint = mips_m4k_remove_breakpoint, - .add_watchpoint = mips_m4k_add_watchpoint, - .remove_watchpoint = mips_m4k_remove_watchpoint, - - .commands = mips_m4k_command_handlers, - .target_create = mips_m4k_target_create, - .init_target = mips_m4k_init_target, - .examine = mips_m4k_examine, -}; diff --git a/src/target/mips_m4k.h b/src/target/mips_m4k.h deleted file mode 100644 index cf8266125..000000000 --- a/src/target/mips_m4k.h +++ /dev/null @@ -1,46 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2008 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * Copyright (C) 2008 by David T.L. Wong * - * * - * Copyright (C) 2011 by Drasko DRASKOVIC * - * drasko.draskovic@gmail.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifndef OPENOCD_TARGET_MIPS_M4K_H -#define OPENOCD_TARGET_MIPS_M4K_H - -struct target; - -#define MIPSM4K_COMMON_MAGIC 0xB321B321 - -struct mips_m4k_common { - uint32_t common_magic; - bool is_pic32mx; - struct mips32_common mips32; -}; - -static inline struct mips_m4k_common * -target_to_m4k(struct target *target) -{ - return container_of(target->arch_info, - struct mips_m4k_common, mips32); -} - -extern const struct command_registration mips_m4k_command_handlers[]; - -#endif /* OPENOCD_TARGET_MIPS_M4K_H */ diff --git a/src/target/nds32.c b/src/target/nds32.c deleted file mode 100644 index 2926b2367..000000000 --- a/src/target/nds32.c +++ /dev/null @@ -1,2628 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2013 Andes Technology * - * Hsiangkai Wang * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 -#include "config.h" -#endif - -#include -#include -#include "nds32.h" -#include "nds32_aice.h" -#include "nds32_tlb.h" -#include "nds32_disassembler.h" - -const int NDS32_BREAK_16 = 0x00EA; /* 0xEA00 */ -const int NDS32_BREAK_32 = 0x0A000064; /* 0x6400000A */ - -struct nds32_edm_operation nds32_edm_ops[NDS32_EDM_OPERATION_MAX_NUM]; -uint32_t nds32_edm_ops_num; - -const char *nds32_debug_type_name[11] = { - "SOFTWARE BREAK", - "SOFTWARE BREAK_16", - "HARDWARE BREAKPOINT", - "DATA ADDR WATCHPOINT PRECISE", - "DATA VALUE WATCHPOINT PRECISE", - "DATA VALUE WATCHPOINT IMPRECISE", - "DEBUG INTERRUPT", - "HARDWARE SINGLE STEP", - "DATA ADDR WATCHPOINT NEXT PRECISE", - "DATA VALUE WATCHPOINT NEXT PRECISE", - "LOAD STORE GLOBAL STOP", -}; - -static const int NDS32_LM_SIZE_TABLE[16] = { - 4 * 1024, - 8 * 1024, - 16 * 1024, - 32 * 1024, - 64 * 1024, - 128 * 1024, - 256 * 1024, - 512 * 1024, - 1024 * 1024, - 1 * 1024, - 2 * 1024, -}; - -static const int NDS32_LINE_SIZE_TABLE[6] = { - 0, - 8, - 16, - 32, - 64, - 128, -}; - -static int nds32_get_core_reg(struct reg *reg) -{ - int retval; - struct nds32_reg *reg_arch_info = reg->arch_info; - struct target *target = reg_arch_info->target; - struct nds32 *nds32 = target_to_nds32(target); - struct aice_port_s *aice = target_to_aice(target); - - if (target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - if (reg->valid) { - uint32_t val = buf_get_u32(reg_arch_info->value, 0, 32); - LOG_DEBUG("reading register(cached) %" PRIi32 "(%s), value: 0x%8.8" PRIx32, - reg_arch_info->num, reg->name, val); - return ERROR_OK; - } - - int mapped_regnum = nds32->register_map(nds32, reg_arch_info->num); - - if (reg_arch_info->enable == false) { - buf_set_u32(reg_arch_info->value, 0, 32, NDS32_REGISTER_DISABLE); - retval = ERROR_FAIL; - } else { - uint32_t val = 0; - if ((nds32->fpu_enable == false) - && (NDS32_REG_TYPE_FPU == nds32_reg_type(mapped_regnum))) { - retval = ERROR_OK; - } else if ((nds32->audio_enable == false) - && (NDS32_REG_TYPE_AUMR == nds32_reg_type(mapped_regnum))) { - retval = ERROR_OK; - } else { - retval = aice_read_register(aice, mapped_regnum, &val); - } - buf_set_u32(reg_arch_info->value, 0, 32, val); - - LOG_DEBUG("reading register %" PRIi32 "(%s), value: 0x%8.8" PRIx32, - reg_arch_info->num, reg->name, val); - } - - if (retval == ERROR_OK) { - reg->valid = true; - reg->dirty = false; - } - - return retval; -} - -static int nds32_get_core_reg_64(struct reg *reg) -{ - int retval; - struct nds32_reg *reg_arch_info = reg->arch_info; - struct target *target = reg_arch_info->target; - struct nds32 *nds32 = target_to_nds32(target); - struct aice_port_s *aice = target_to_aice(target); - - if (target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - if (reg->valid) - return ERROR_OK; - - if (reg_arch_info->enable == false) { - buf_set_u64(reg_arch_info->value, 0, 64, NDS32_REGISTER_DISABLE); - retval = ERROR_FAIL; - } else { - uint64_t val = 0; - if ((nds32->fpu_enable == false) - && ((FD0 <= reg_arch_info->num) && (reg_arch_info->num <= FD31))) { - retval = ERROR_OK; - } else { - retval = aice_read_reg_64(aice, reg_arch_info->num, &val); - } - buf_set_u64(reg_arch_info->value, 0, 64, val); - } - - if (retval == ERROR_OK) { - reg->valid = true; - reg->dirty = false; - } - - return retval; -} - -static int nds32_update_psw(struct nds32 *nds32) -{ - uint32_t value_ir0; - struct aice_port_s *aice = target_to_aice(nds32->target); - - nds32_get_mapped_reg(nds32, IR0, &value_ir0); - - /* Save data memory endian */ - if ((value_ir0 >> 5) & 0x1) { - nds32->data_endian = TARGET_BIG_ENDIAN; - aice_set_data_endian(aice, AICE_BIG_ENDIAN); - } else { - nds32->data_endian = TARGET_LITTLE_ENDIAN; - aice_set_data_endian(aice, AICE_LITTLE_ENDIAN); - } - - /* Save translation status */ - nds32->memory.address_translation = ((value_ir0 >> 7) & 0x1) ? true : false; - - return ERROR_OK; -} - -static int nds32_update_mmu_info(struct nds32 *nds32) -{ - uint32_t value; - - /* Update MMU control status */ - nds32_get_mapped_reg(nds32, MR0, &value); - nds32->mmu_config.default_min_page_size = value & 0x1; - nds32->mmu_config.multiple_page_size_in_use = (value >> 10) & 0x1; - - return ERROR_OK; -} - -static int nds32_update_cache_info(struct nds32 *nds32) -{ - uint32_t value; - - if (ERROR_OK == nds32_get_mapped_reg(nds32, MR8, &value)) { - if (value & 0x1) - nds32->memory.icache.enable = true; - else - nds32->memory.icache.enable = false; - - if (value & 0x2) - nds32->memory.dcache.enable = true; - else - nds32->memory.dcache.enable = false; - } else { - nds32->memory.icache.enable = false; - nds32->memory.dcache.enable = false; - } - - return ERROR_OK; -} - -static int nds32_update_lm_info(struct nds32 *nds32) -{ - struct nds32_memory *memory = &(nds32->memory); - uint32_t value_mr6; - uint32_t value_mr7; - - nds32_get_mapped_reg(nds32, MR6, &value_mr6); - if (value_mr6 & 0x1) - memory->ilm_enable = true; - else - memory->ilm_enable = false; - - if (memory->ilm_align_ver == 0) { /* 1MB aligned */ - memory->ilm_start = value_mr6 & 0xFFF00000; - memory->ilm_end = memory->ilm_start + memory->ilm_size; - } else if (memory->ilm_align_ver == 1) { /* aligned to local memory size */ - memory->ilm_start = value_mr6 & 0xFFFFFC00; - memory->ilm_end = memory->ilm_start + memory->ilm_size; - } else { - memory->ilm_start = -1; - memory->ilm_end = -1; - } - - nds32_get_mapped_reg(nds32, MR7, &value_mr7); - if (value_mr7 & 0x1) - memory->dlm_enable = true; - else - memory->dlm_enable = false; - - if (memory->dlm_align_ver == 0) { /* 1MB aligned */ - memory->dlm_start = value_mr7 & 0xFFF00000; - memory->dlm_end = memory->dlm_start + memory->dlm_size; - } else if (memory->dlm_align_ver == 1) { /* aligned to local memory size */ - memory->dlm_start = value_mr7 & 0xFFFFFC00; - memory->dlm_end = memory->dlm_start + memory->dlm_size; - } else { - memory->dlm_start = -1; - memory->dlm_end = -1; - } - - return ERROR_OK; -} - -/** - * If fpu/audio is disabled, to access fpu/audio registers will cause - * exceptions. So, we need to check if fpu/audio is enabled or not as - * target is halted. If fpu/audio is disabled, as users access fpu/audio - * registers, OpenOCD will return fake value 0 instead of accessing - * registers through DIM. - */ -static int nds32_check_extension(struct nds32 *nds32) -{ - uint32_t value; - - nds32_get_mapped_reg(nds32, FUCPR, &value); - if (value == NDS32_REGISTER_DISABLE) { - nds32->fpu_enable = false; - nds32->audio_enable = false; - return ERROR_OK; - } - - if (value & 0x1) - nds32->fpu_enable = true; - else - nds32->fpu_enable = false; - - if (value & 0x80000000) - nds32->audio_enable = true; - else - nds32->audio_enable = false; - - return ERROR_OK; -} - -static int nds32_set_core_reg(struct reg *reg, uint8_t *buf) -{ - struct nds32_reg *reg_arch_info = reg->arch_info; - struct target *target = reg_arch_info->target; - struct nds32 *nds32 = target_to_nds32(target); - struct aice_port_s *aice = target_to_aice(target); - uint32_t value = buf_get_u32(buf, 0, 32); - - if (target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - int mapped_regnum = nds32->register_map(nds32, reg_arch_info->num); - - /* ignore values that will generate exception */ - if (nds32_reg_exception(mapped_regnum, value)) - return ERROR_OK; - - LOG_DEBUG("writing register %" PRIi32 "(%s) with value 0x%8.8" PRIx32, - reg_arch_info->num, reg->name, value); - - if ((nds32->fpu_enable == false) && - (NDS32_REG_TYPE_FPU == nds32_reg_type(mapped_regnum))) { - - buf_set_u32(reg->value, 0, 32, 0); - } else if ((nds32->audio_enable == false) && - (NDS32_REG_TYPE_AUMR == nds32_reg_type(mapped_regnum))) { - - buf_set_u32(reg->value, 0, 32, 0); - } else { - buf_set_u32(reg->value, 0, 32, value); - uint32_t val = buf_get_u32(reg_arch_info->value, 0, 32); - aice_write_register(aice, mapped_regnum, val); - - /* After set value to registers, read the value from target - * to avoid W1C inconsistency. */ - aice_read_register(aice, mapped_regnum, &val); - buf_set_u32(reg_arch_info->value, 0, 32, val); - } - - reg->valid = true; - reg->dirty = false; - - /* update registers to take effect right now */ - if (IR0 == mapped_regnum) { - nds32_update_psw(nds32); - } else if (MR0 == mapped_regnum) { - nds32_update_mmu_info(nds32); - } else if ((MR6 == mapped_regnum) || (MR7 == mapped_regnum)) { - /* update lm information */ - nds32_update_lm_info(nds32); - } else if (MR8 == mapped_regnum) { - nds32_update_cache_info(nds32); - } else if (FUCPR == mapped_regnum) { - /* update audio/fpu setting */ - nds32_check_extension(nds32); - } - - return ERROR_OK; -} - -static int nds32_set_core_reg_64(struct reg *reg, uint8_t *buf) -{ - struct nds32_reg *reg_arch_info = reg->arch_info; - struct target *target = reg_arch_info->target; - struct nds32 *nds32 = target_to_nds32(target); - uint32_t low_part = buf_get_u32(buf, 0, 32); - uint32_t high_part = buf_get_u32(buf, 32, 32); - - if (target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - if ((nds32->fpu_enable == false) && - ((FD0 <= reg_arch_info->num) && (reg_arch_info->num <= FD31))) { - - buf_set_u32(reg->value, 0, 32, 0); - buf_set_u32(reg->value, 32, 32, 0); - - reg->valid = true; - reg->dirty = false; - } else { - buf_set_u32(reg->value, 0, 32, low_part); - buf_set_u32(reg->value, 32, 32, high_part); - - reg->valid = true; - reg->dirty = true; - } - - return ERROR_OK; -} - -static const struct reg_arch_type nds32_reg_access_type = { - .get = nds32_get_core_reg, - .set = nds32_set_core_reg, -}; - -static const struct reg_arch_type nds32_reg_access_type_64 = { - .get = nds32_get_core_reg_64, - .set = nds32_set_core_reg_64, -}; - -static struct reg_cache *nds32_build_reg_cache(struct target *target, - struct nds32 *nds32) -{ - struct reg_cache *cache = calloc(sizeof(struct reg_cache), 1); - struct reg *reg_list = calloc(TOTAL_REG_NUM, sizeof(struct reg)); - struct nds32_reg *reg_arch_info = calloc(TOTAL_REG_NUM, sizeof(struct nds32_reg)); - int i; - - if (!cache || !reg_list || !reg_arch_info) { - free(cache); - free(reg_list); - free(reg_arch_info); - return NULL; - } - - cache->name = "Andes registers"; - cache->next = NULL; - cache->reg_list = reg_list; - cache->num_regs = 0; - - for (i = 0; i < TOTAL_REG_NUM; i++) { - reg_arch_info[i].num = i; - reg_arch_info[i].target = target; - reg_arch_info[i].nds32 = nds32; - reg_arch_info[i].enable = false; - - reg_list[i].name = nds32_reg_simple_name(i); - reg_list[i].number = reg_arch_info[i].num; - reg_list[i].size = nds32_reg_size(i); - reg_list[i].arch_info = ®_arch_info[i]; - - reg_list[i].reg_data_type = calloc(sizeof(struct reg_data_type), 1); - - if (FD0 <= reg_arch_info[i].num && reg_arch_info[i].num <= FD31) { - reg_list[i].value = reg_arch_info[i].value; - reg_list[i].type = &nds32_reg_access_type_64; - - reg_list[i].reg_data_type->type = REG_TYPE_IEEE_DOUBLE; - reg_list[i].reg_data_type->id = "ieee_double"; - reg_list[i].group = "float"; - } else { - reg_list[i].value = reg_arch_info[i].value; - reg_list[i].type = &nds32_reg_access_type; - reg_list[i].group = "general"; - - if ((FS0 <= reg_arch_info[i].num) && (reg_arch_info[i].num <= FS31)) { - reg_list[i].reg_data_type->type = REG_TYPE_IEEE_SINGLE; - reg_list[i].reg_data_type->id = "ieee_single"; - reg_list[i].group = "float"; - } else if ((reg_arch_info[i].num == FPCSR) || - (reg_arch_info[i].num == FPCFG)) { - reg_list[i].group = "float"; - } else if ((reg_arch_info[i].num == R28) || - (reg_arch_info[i].num == R29) || - (reg_arch_info[i].num == R31)) { - reg_list[i].reg_data_type->type = REG_TYPE_DATA_PTR; - reg_list[i].reg_data_type->id = "data_ptr"; - } else if ((reg_arch_info[i].num == R30) || - (reg_arch_info[i].num == PC)) { - reg_list[i].reg_data_type->type = REG_TYPE_CODE_PTR; - reg_list[i].reg_data_type->id = "code_ptr"; - } else { - reg_list[i].reg_data_type->type = REG_TYPE_UINT32; - reg_list[i].reg_data_type->id = "uint32"; - } - } - - if (R16 <= reg_arch_info[i].num && reg_arch_info[i].num <= R25) - reg_list[i].caller_save = true; - else - reg_list[i].caller_save = false; - - reg_list[i].feature = malloc(sizeof(struct reg_feature)); - - if (R0 <= reg_arch_info[i].num && reg_arch_info[i].num <= IFC_LP) - reg_list[i].feature->name = "org.gnu.gdb.nds32.core"; - else if (CR0 <= reg_arch_info[i].num && reg_arch_info[i].num <= SECUR0) - reg_list[i].feature->name = "org.gnu.gdb.nds32.system"; - else if (D0L24 <= reg_arch_info[i].num && reg_arch_info[i].num <= CBE3) - reg_list[i].feature->name = "org.gnu.gdb.nds32.audio"; - else if (FPCSR <= reg_arch_info[i].num && reg_arch_info[i].num <= FD31) - reg_list[i].feature->name = "org.gnu.gdb.nds32.fpu"; - - cache->num_regs++; - } - - nds32->core_cache = cache; - - return cache; -} - -static int nds32_reg_cache_init(struct target *target, struct nds32 *nds32) -{ - struct reg_cache *cache; - - cache = nds32_build_reg_cache(target, nds32); - if (!cache) - return ERROR_FAIL; - - *register_get_last_cache_p(&target->reg_cache) = cache; - - return ERROR_OK; -} - -static struct reg *nds32_reg_current(struct nds32 *nds32, unsigned regnum) -{ - struct reg *r; - - r = nds32->core_cache->reg_list + regnum; - - return r; -} - -int nds32_full_context(struct nds32 *nds32) -{ - uint32_t value, value_ir0; - - /* save $pc & $psw */ - nds32_get_mapped_reg(nds32, PC, &value); - nds32_get_mapped_reg(nds32, IR0, &value_ir0); - - nds32_update_psw(nds32); - nds32_update_mmu_info(nds32); - nds32_update_cache_info(nds32); - nds32_update_lm_info(nds32); - - nds32_check_extension(nds32); - - return ERROR_OK; -} - -/* get register value internally */ -int nds32_get_mapped_reg(struct nds32 *nds32, unsigned regnum, uint32_t *value) -{ - struct reg_cache *reg_cache = nds32->core_cache; - struct reg *r; - - if (regnum > reg_cache->num_regs) - return ERROR_FAIL; - - r = nds32_reg_current(nds32, regnum); - - if (ERROR_OK != r->type->get(r)) - return ERROR_FAIL; - - *value = buf_get_u32(r->value, 0, 32); - - return ERROR_OK; -} - -/** set register internally */ -int nds32_set_mapped_reg(struct nds32 *nds32, unsigned regnum, uint32_t value) -{ - struct reg_cache *reg_cache = nds32->core_cache; - struct reg *r; - uint8_t set_value[4]; - - if (regnum > reg_cache->num_regs) - return ERROR_FAIL; - - r = nds32_reg_current(nds32, regnum); - - buf_set_u32(set_value, 0, 32, value); - - return r->type->set(r, set_value); -} - -/** get general register list */ -static int nds32_get_general_reg_list(struct nds32 *nds32, - struct reg **reg_list[], int *reg_list_size) -{ - struct reg *reg_current; - int i; - int current_idx; - - /** freed in gdb_server.c */ - *reg_list = malloc(sizeof(struct reg *) * (IFC_LP - R0 + 1)); - current_idx = 0; - - for (i = R0; i < IFC_LP + 1; i++) { - reg_current = nds32_reg_current(nds32, i); - if (((struct nds32_reg *)reg_current->arch_info)->enable) { - (*reg_list)[current_idx] = reg_current; - current_idx++; - } - } - *reg_list_size = current_idx; - - return ERROR_OK; -} - -/** get all register list */ -static int nds32_get_all_reg_list(struct nds32 *nds32, - struct reg **reg_list[], int *reg_list_size) -{ - struct reg_cache *reg_cache = nds32->core_cache; - struct reg *reg_current; - unsigned int i; - - *reg_list_size = reg_cache->num_regs; - - /** freed in gdb_server.c */ - *reg_list = malloc(sizeof(struct reg *) * (*reg_list_size)); - - for (i = 0; i < reg_cache->num_regs; i++) { - reg_current = nds32_reg_current(nds32, i); - reg_current->exist = ((struct nds32_reg *) - reg_current->arch_info)->enable; - (*reg_list)[i] = reg_current; - } - - return ERROR_OK; -} - -/** get all register list */ -int nds32_get_gdb_reg_list(struct target *target, - struct reg **reg_list[], int *reg_list_size, - enum target_register_class reg_class) -{ - struct nds32 *nds32 = target_to_nds32(target); - - switch (reg_class) { - case REG_CLASS_ALL: - return nds32_get_all_reg_list(nds32, reg_list, reg_list_size); - case REG_CLASS_GENERAL: - return nds32_get_general_reg_list(nds32, reg_list, reg_list_size); - default: - return ERROR_FAIL; - } - - return ERROR_FAIL; -} - -static int nds32_select_memory_mode(struct target *target, uint32_t address, - uint32_t length, uint32_t *end_address) -{ - struct nds32 *nds32 = target_to_nds32(target); - struct aice_port_s *aice = target_to_aice(target); - struct nds32_memory *memory = &(nds32->memory); - struct nds32_edm *edm = &(nds32->edm); - uint32_t dlm_start, dlm_end; - uint32_t ilm_start, ilm_end; - uint32_t address_end = address + length; - - /* init end_address */ - *end_address = address_end; - - if (NDS_MEMORY_ACC_CPU == memory->access_channel) - return ERROR_OK; - - if (edm->access_control == false) { - LOG_DEBUG("EDM does not support ACC_CTL"); - return ERROR_OK; - } - - if (edm->direct_access_local_memory == false) { - LOG_DEBUG("EDM does not support DALM"); - aice_memory_mode(aice, NDS_MEMORY_SELECT_MEM); - return ERROR_OK; - } - - if (NDS_MEMORY_SELECT_AUTO != memory->mode) { - LOG_DEBUG("Memory mode is not AUTO"); - return ERROR_OK; - } - - /* set default mode */ - aice_memory_mode(aice, NDS_MEMORY_SELECT_MEM); - - if ((memory->ilm_base != 0) && (memory->ilm_enable == true)) { - ilm_start = memory->ilm_start; - ilm_end = memory->ilm_end; - - /* case 1, address < ilm_start */ - if (address < ilm_start) { - if (ilm_start < address_end) { - /* update end_address to split non-ILM from ILM */ - *end_address = ilm_start; - } - /* MEM mode */ - aice_memory_mode(aice, NDS_MEMORY_SELECT_MEM); - } else if ((ilm_start <= address) && (address < ilm_end)) { - /* case 2, ilm_start <= address < ilm_end */ - if (ilm_end < address_end) { - /* update end_address to split non-ILM from ILM */ - *end_address = ilm_end; - } - /* ILM mode */ - aice_memory_mode(aice, NDS_MEMORY_SELECT_ILM); - } else { /* case 3, ilm_end <= address */ - /* MEM mode */ - aice_memory_mode(aice, NDS_MEMORY_SELECT_MEM); - } - - return ERROR_OK; - } else { - LOG_DEBUG("ILM is not enabled"); - } - - if ((memory->dlm_base != 0) && (memory->dlm_enable == true)) { - dlm_start = memory->dlm_start; - dlm_end = memory->dlm_end; - - /* case 1, address < dlm_start */ - if (address < dlm_start) { - if (dlm_start < address_end) { - /* update end_address to split non-DLM from DLM */ - *end_address = dlm_start; - } - /* MEM mode */ - aice_memory_mode(aice, NDS_MEMORY_SELECT_MEM); - } else if ((dlm_start <= address) && (address < dlm_end)) { - /* case 2, dlm_start <= address < dlm_end */ - if (dlm_end < address_end) { - /* update end_address to split non-DLM from DLM */ - *end_address = dlm_end; - } - /* DLM mode */ - aice_memory_mode(aice, NDS_MEMORY_SELECT_DLM); - } else { /* case 3, dlm_end <= address */ - /* MEM mode */ - aice_memory_mode(aice, NDS_MEMORY_SELECT_MEM); - } - - return ERROR_OK; - } else { - LOG_DEBUG("DLM is not enabled"); - } - - return ERROR_OK; -} - -int nds32_read_buffer(struct target *target, uint32_t address, - uint32_t size, uint8_t *buffer) -{ - struct nds32 *nds32 = target_to_nds32(target); - struct nds32_memory *memory = &(nds32->memory); - - if ((NDS_MEMORY_ACC_CPU == memory->access_channel) && - (target->state != TARGET_HALTED)) { - LOG_WARNING("target was not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - LOG_DEBUG("READ BUFFER: ADDR %08" PRIx32 " SIZE %08" PRIx32, - address, - size); - - int retval = ERROR_OK; - struct aice_port_s *aice = target_to_aice(target); - uint32_t end_address; - - if (((address % 2) == 0) && (size == 2)) { - nds32_select_memory_mode(target, address, 2, &end_address); - return aice_read_mem_unit(aice, address, 2, 1, buffer); - } - - /* handle unaligned head bytes */ - if (address % 4) { - uint32_t unaligned = 4 - (address % 4); - - if (unaligned > size) - unaligned = size; - - nds32_select_memory_mode(target, address, unaligned, &end_address); - retval = aice_read_mem_unit(aice, address, 1, unaligned, buffer); - if (retval != ERROR_OK) - return retval; - - buffer += unaligned; - address += unaligned; - size -= unaligned; - } - - /* handle aligned words */ - if (size >= 4) { - int aligned = size - (size % 4); - int read_len; - - do { - nds32_select_memory_mode(target, address, aligned, &end_address); - - read_len = end_address - address; - - if (read_len > 8) - retval = aice_read_mem_bulk(aice, address, read_len, buffer); - else - retval = aice_read_mem_unit(aice, address, 4, read_len / 4, buffer); - - if (retval != ERROR_OK) - return retval; - - buffer += read_len; - address += read_len; - size -= read_len; - aligned -= read_len; - - } while (aligned != 0); - } - - /*prevent byte access when possible (avoid AHB access limitations in some cases)*/ - if (size >= 2) { - int aligned = size - (size % 2); - nds32_select_memory_mode(target, address, aligned, &end_address); - retval = aice_read_mem_unit(aice, address, 2, aligned / 2, buffer); - if (retval != ERROR_OK) - return retval; - - buffer += aligned; - address += aligned; - size -= aligned; - } - /* handle tail writes of less than 4 bytes */ - if (size > 0) { - nds32_select_memory_mode(target, address, size, &end_address); - retval = aice_read_mem_unit(aice, address, 1, size, buffer); - if (retval != ERROR_OK) - return retval; - } - - return ERROR_OK; -} - -int nds32_read_memory(struct target *target, uint32_t address, - uint32_t size, uint32_t count, uint8_t *buffer) -{ - struct aice_port_s *aice = target_to_aice(target); - - return aice_read_mem_unit(aice, address, size, count, buffer); -} - -int nds32_read_phys_memory(struct target *target, uint32_t address, - uint32_t size, uint32_t count, uint8_t *buffer) -{ - struct aice_port_s *aice = target_to_aice(target); - struct nds32 *nds32 = target_to_nds32(target); - struct nds32_memory *memory = &(nds32->memory); - enum nds_memory_access orig_channel; - int result; - - /* switch to BUS access mode to skip MMU */ - orig_channel = memory->access_channel; - memory->access_channel = NDS_MEMORY_ACC_BUS; - aice_memory_access(aice, memory->access_channel); - - /* The input address is physical address. No need to do address translation. */ - result = aice_read_mem_unit(aice, address, size, count, buffer); - - /* restore to origin access mode */ - memory->access_channel = orig_channel; - aice_memory_access(aice, memory->access_channel); - - return result; -} - -int nds32_write_buffer(struct target *target, uint32_t address, - uint32_t size, const uint8_t *buffer) -{ - struct nds32 *nds32 = target_to_nds32(target); - struct nds32_memory *memory = &(nds32->memory); - - if ((NDS_MEMORY_ACC_CPU == memory->access_channel) && - (target->state != TARGET_HALTED)) { - LOG_WARNING("target was not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - LOG_DEBUG("WRITE BUFFER: ADDR %08" PRIx32 " SIZE %08" PRIx32, - address, - size); - - struct aice_port_s *aice = target_to_aice(target); - int retval = ERROR_OK; - uint32_t end_address; - - if (((address % 2) == 0) && (size == 2)) { - nds32_select_memory_mode(target, address, 2, &end_address); - return aice_write_mem_unit(aice, address, 2, 1, buffer); - } - - /* handle unaligned head bytes */ - if (address % 4) { - uint32_t unaligned = 4 - (address % 4); - - if (unaligned > size) - unaligned = size; - - nds32_select_memory_mode(target, address, unaligned, &end_address); - retval = aice_write_mem_unit(aice, address, 1, unaligned, buffer); - if (retval != ERROR_OK) - return retval; - - buffer += unaligned; - address += unaligned; - size -= unaligned; - } - - /* handle aligned words */ - if (size >= 4) { - int aligned = size - (size % 4); - int write_len; - - do { - nds32_select_memory_mode(target, address, aligned, &end_address); - - write_len = end_address - address; - if (write_len > 8) - retval = aice_write_mem_bulk(aice, address, write_len, buffer); - else - retval = aice_write_mem_unit(aice, address, 4, write_len / 4, buffer); - if (retval != ERROR_OK) - return retval; - - buffer += write_len; - address += write_len; - size -= write_len; - aligned -= write_len; - - } while (aligned != 0); - } - - /* handle tail writes of less than 4 bytes */ - if (size > 0) { - nds32_select_memory_mode(target, address, size, &end_address); - retval = aice_write_mem_unit(aice, address, 1, size, buffer); - if (retval != ERROR_OK) - return retval; - } - - return retval; -} - -int nds32_write_memory(struct target *target, uint32_t address, - uint32_t size, uint32_t count, const uint8_t *buffer) -{ - struct aice_port_s *aice = target_to_aice(target); - - return aice_write_mem_unit(aice, address, size, count, buffer); -} - -int nds32_write_phys_memory(struct target *target, uint32_t address, - uint32_t size, uint32_t count, const uint8_t *buffer) -{ - struct aice_port_s *aice = target_to_aice(target); - struct nds32 *nds32 = target_to_nds32(target); - struct nds32_memory *memory = &(nds32->memory); - enum nds_memory_access orig_channel; - int result; - - /* switch to BUS access mode to skip MMU */ - orig_channel = memory->access_channel; - memory->access_channel = NDS_MEMORY_ACC_BUS; - aice_memory_access(aice, memory->access_channel); - - /* The input address is physical address. No need to do address translation. */ - result = aice_write_mem_unit(aice, address, size, count, buffer); - - /* restore to origin access mode */ - memory->access_channel = orig_channel; - aice_memory_access(aice, memory->access_channel); - - return result; -} - -int nds32_mmu(struct target *target, int *enabled) -{ - if (target->state != TARGET_HALTED) { - LOG_ERROR("%s: target not halted", __func__); - return ERROR_TARGET_INVALID; - } - - struct nds32 *nds32 = target_to_nds32(target); - struct nds32_memory *memory = &(nds32->memory); - struct nds32_mmu_config *mmu_config = &(nds32->mmu_config); - - if ((mmu_config->memory_protection == 2) && (memory->address_translation == true)) - *enabled = 1; - else - *enabled = 0; - - return ERROR_OK; -} - -int nds32_arch_state(struct target *target) -{ - struct nds32 *nds32 = target_to_nds32(target); - - if (nds32->common_magic != NDS32_COMMON_MAGIC) { - LOG_ERROR("BUG: called for a non-Andes target"); - return ERROR_FAIL; - } - - uint32_t value_pc, value_psw; - - nds32_get_mapped_reg(nds32, PC, &value_pc); - nds32_get_mapped_reg(nds32, IR0, &value_psw); - - LOG_USER("target halted due to %s\n" - "psw: 0x%8.8" PRIx32 " pc: 0x%8.8" PRIx32 "%s", - debug_reason_name(target), - value_psw, - value_pc, - nds32->virtual_hosting ? ", virtual hosting" : ""); - - /* save pc value to pseudo register pc */ - struct reg *reg = register_get_by_name(target->reg_cache, "pc", 1); - buf_set_u32(reg->value, 0, 32, value_pc); - - return ERROR_OK; -} - -static void nds32_init_must_have_registers(struct nds32 *nds32) -{ - struct reg_cache *reg_cache = nds32->core_cache; - - /** MUST have general registers */ - ((struct nds32_reg *)reg_cache->reg_list[R0].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[R1].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[R2].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[R3].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[R4].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[R5].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[R6].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[R7].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[R8].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[R9].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[R10].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[R15].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[R28].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[R29].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[R30].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[R31].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[PC].arch_info)->enable = true; - - /** MUST have configuration system registers */ - ((struct nds32_reg *)reg_cache->reg_list[CR0].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[CR1].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[CR2].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[CR3].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[CR4].arch_info)->enable = true; - - /** MUST have interrupt system registers */ - ((struct nds32_reg *)reg_cache->reg_list[IR0].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[IR1].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[IR3].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[IR4].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[IR6].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[IR9].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[IR11].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[IR14].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[IR15].arch_info)->enable = true; - - /** MUST have MMU system registers */ - ((struct nds32_reg *)reg_cache->reg_list[MR0].arch_info)->enable = true; - - /** MUST have EDM system registers */ - ((struct nds32_reg *)reg_cache->reg_list[DR40].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[DR42].arch_info)->enable = true; -} - -static int nds32_init_memory_config(struct nds32 *nds32) -{ - uint32_t value_cr1; /* ICM_CFG */ - uint32_t value_cr2; /* DCM_CFG */ - struct nds32_memory *memory = &(nds32->memory); - - /* read $cr1 to init instruction memory information */ - nds32_get_mapped_reg(nds32, CR1, &value_cr1); - memory->icache.set = value_cr1 & 0x7; - memory->icache.way = (value_cr1 >> 3) & 0x7; - memory->icache.line_size = (value_cr1 >> 6) & 0x7; - memory->icache.lock_support = (value_cr1 >> 9) & 0x1; - - memory->ilm_base = (value_cr1 >> 10) & 0x7; - memory->ilm_align_ver = (value_cr1 >> 13) & 0x3; - - /* read $cr2 to init data memory information */ - nds32_get_mapped_reg(nds32, CR2, &value_cr2); - memory->dcache.set = value_cr2 & 0x7; - memory->dcache.way = (value_cr2 >> 3) & 0x7; - memory->dcache.line_size = (value_cr2 >> 6) & 0x7; - memory->dcache.lock_support = (value_cr2 >> 9) & 0x1; - - memory->dlm_base = (value_cr2 >> 10) & 0x7; - memory->dlm_align_ver = (value_cr2 >> 13) & 0x3; - - return ERROR_OK; -} - -static void nds32_init_config(struct nds32 *nds32) -{ - uint32_t value_cr0; - uint32_t value_cr3; - uint32_t value_cr4; - struct nds32_cpu_version *cpu_version = &(nds32->cpu_version); - struct nds32_mmu_config *mmu_config = &(nds32->mmu_config); - struct nds32_misc_config *misc_config = &(nds32->misc_config); - - nds32_get_mapped_reg(nds32, CR0, &value_cr0); - nds32_get_mapped_reg(nds32, CR3, &value_cr3); - nds32_get_mapped_reg(nds32, CR4, &value_cr4); - - /* config cpu version */ - cpu_version->performance_extension = value_cr0 & 0x1; - cpu_version->_16bit_extension = (value_cr0 >> 1) & 0x1; - cpu_version->performance_extension_2 = (value_cr0 >> 2) & 0x1; - cpu_version->cop_fpu_extension = (value_cr0 >> 3) & 0x1; - cpu_version->string_extension = (value_cr0 >> 4) & 0x1; - cpu_version->revision = (value_cr0 >> 16) & 0xFF; - cpu_version->cpu_id_family = (value_cr0 >> 24) & 0xF; - cpu_version->cpu_id_version = (value_cr0 >> 28) & 0xF; - - /* config MMU */ - mmu_config->memory_protection = value_cr3 & 0x3; - mmu_config->memory_protection_version = (value_cr3 >> 2) & 0x1F; - mmu_config->fully_associative_tlb = (value_cr3 >> 7) & 0x1; - if (mmu_config->fully_associative_tlb) { - mmu_config->tlb_size = (value_cr3 >> 8) & 0x7F; - } else { - mmu_config->tlb_ways = (value_cr3 >> 8) & 0x7; - mmu_config->tlb_sets = (value_cr3 >> 11) & 0x7; - } - mmu_config->_8k_page_support = (value_cr3 >> 15) & 0x1; - mmu_config->extra_page_size_support = (value_cr3 >> 16) & 0xFF; - mmu_config->tlb_lock = (value_cr3 >> 24) & 0x1; - mmu_config->hardware_page_table_walker = (value_cr3 >> 25) & 0x1; - mmu_config->default_endian = (value_cr3 >> 26) & 0x1; - mmu_config->partition_num = (value_cr3 >> 27) & 0x1; - mmu_config->invisible_tlb = (value_cr3 >> 28) & 0x1; - mmu_config->vlpt = (value_cr3 >> 29) & 0x1; - mmu_config->ntme = (value_cr3 >> 30) & 0x1; - mmu_config->drde = (value_cr3 >> 31) & 0x1; - - /* config misc */ - misc_config->edm = value_cr4 & 0x1; - misc_config->local_memory_dma = (value_cr4 >> 1) & 0x1; - misc_config->performance_monitor = (value_cr4 >> 2) & 0x1; - misc_config->high_speed_memory_port = (value_cr4 >> 3) & 0x1; - misc_config->debug_tracer = (value_cr4 >> 4) & 0x1; - misc_config->div_instruction = (value_cr4 >> 5) & 0x1; - misc_config->mac_instruction = (value_cr4 >> 6) & 0x1; - misc_config->audio_isa = (value_cr4 >> 7) & 0x3; - misc_config->L2_cache = (value_cr4 >> 9) & 0x1; - misc_config->reduce_register = (value_cr4 >> 10) & 0x1; - misc_config->addr_24 = (value_cr4 >> 11) & 0x1; - misc_config->interruption_level = (value_cr4 >> 12) & 0x1; - misc_config->baseline_instruction = (value_cr4 >> 13) & 0x7; - misc_config->no_dx_register = (value_cr4 >> 16) & 0x1; - misc_config->implement_dependant_register = (value_cr4 >> 17) & 0x1; - misc_config->implement_dependant_sr_encoding = (value_cr4 >> 18) & 0x1; - misc_config->ifc = (value_cr4 >> 19) & 0x1; - misc_config->mcu = (value_cr4 >> 20) & 0x1; - misc_config->shadow = (value_cr4 >> 21) & 0x7; - misc_config->ex9 = (value_cr4 >> 24) & 0x1; - - nds32_init_memory_config(nds32); -} - -static int nds32_init_option_registers(struct nds32 *nds32) -{ - struct reg_cache *reg_cache = nds32->core_cache; - struct nds32_cpu_version *cpu_version = &(nds32->cpu_version); - struct nds32_mmu_config *mmu_config = &(nds32->mmu_config); - struct nds32_misc_config *misc_config = &(nds32->misc_config); - struct nds32_memory *memory_config = &(nds32->memory); - - bool no_cr5; - bool mr10_exist; - bool no_racr0; - - if (((cpu_version->cpu_id_family == 0xC) || (cpu_version->cpu_id_family == 0xD)) && - ((cpu_version->revision & 0xFC) == 0)) { - no_cr5 = true; - mr10_exist = true; - no_racr0 = true; - } else { - no_cr5 = false; - mr10_exist = false; - no_racr0 = false; - } - - if (misc_config->reduce_register == false) { - ((struct nds32_reg *)reg_cache->reg_list[R11].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[R12].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[R13].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[R14].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[R16].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[R17].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[R18].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[R19].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[R20].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[R21].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[R22].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[R23].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[R24].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[R25].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[R26].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[R27].arch_info)->enable = true; - } - - if (misc_config->no_dx_register == false) { - ((struct nds32_reg *)reg_cache->reg_list[D0LO].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[D0HI].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[D1LO].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[D1HI].arch_info)->enable = true; - } - - if (misc_config->ex9) - ((struct nds32_reg *)reg_cache->reg_list[ITB].arch_info)->enable = true; - - if (no_cr5 == false) - ((struct nds32_reg *)reg_cache->reg_list[CR5].arch_info)->enable = true; - - if (cpu_version->cop_fpu_extension) { - ((struct nds32_reg *)reg_cache->reg_list[CR6].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[FPCSR].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[FPCFG].arch_info)->enable = true; - } - - if (mmu_config->memory_protection == 1) { - /* Secure MPU has no IPC, IPSW, P_ITYPE */ - ((struct nds32_reg *)reg_cache->reg_list[IR1].arch_info)->enable = false; - ((struct nds32_reg *)reg_cache->reg_list[IR9].arch_info)->enable = false; - } - - if (nds32->privilege_level != 0) - ((struct nds32_reg *)reg_cache->reg_list[IR3].arch_info)->enable = false; - - if (misc_config->mcu == true) - ((struct nds32_reg *)reg_cache->reg_list[IR4].arch_info)->enable = false; - - if (misc_config->interruption_level == false) { - ((struct nds32_reg *)reg_cache->reg_list[IR2].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[IR5].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[IR10].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[IR12].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[IR13].arch_info)->enable = true; - - /* Secure MPU has no IPC, IPSW, P_ITYPE */ - if (mmu_config->memory_protection != 1) - ((struct nds32_reg *)reg_cache->reg_list[IR7].arch_info)->enable = true; - } - - if ((cpu_version->cpu_id_family == 0x9) || - (cpu_version->cpu_id_family == 0xA) || - (cpu_version->cpu_id_family == 0xC) || - (cpu_version->cpu_id_family == 0xD)) - ((struct nds32_reg *)reg_cache->reg_list[IR8].arch_info)->enable = true; - - if (misc_config->shadow == 1) { - ((struct nds32_reg *)reg_cache->reg_list[IR16].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[IR17].arch_info)->enable = true; - } - - if (misc_config->ifc) - ((struct nds32_reg *)reg_cache->reg_list[IFC_LP].arch_info)->enable = true; - - if (nds32->privilege_level != 0) - ((struct nds32_reg *)reg_cache->reg_list[MR0].arch_info)->enable = false; - - if (mmu_config->memory_protection == 1) { - if (mmu_config->memory_protection_version == 24) - ((struct nds32_reg *)reg_cache->reg_list[MR4].arch_info)->enable = true; - - if (nds32->privilege_level == 0) { - if ((mmu_config->memory_protection_version == 16) || - (mmu_config->memory_protection_version == 24)) { - ((struct nds32_reg *)reg_cache->reg_list[MR11].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[SECUR0].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[IR20].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[IR22].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[IR24].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[IR30].arch_info)->enable = true; - - if (misc_config->shadow == 1) { - ((struct nds32_reg *)reg_cache->reg_list[IR21].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[IR23].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[IR25].arch_info)->enable = true; - } - } - } - } else if (mmu_config->memory_protection == 2) { - ((struct nds32_reg *)reg_cache->reg_list[MR1].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[MR4].arch_info)->enable = true; - - if ((cpu_version->cpu_id_family != 0xA) && (cpu_version->cpu_id_family != 0xC) && - (cpu_version->cpu_id_family != 0xD)) - ((struct nds32_reg *)reg_cache->reg_list[MR5].arch_info)->enable = true; - } - - if (mmu_config->memory_protection > 0) { - ((struct nds32_reg *)reg_cache->reg_list[MR2].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[MR3].arch_info)->enable = true; - } - - if (memory_config->ilm_base != 0) - if (nds32->privilege_level == 0) - ((struct nds32_reg *)reg_cache->reg_list[MR6].arch_info)->enable = true; - - if (memory_config->dlm_base != 0) - if (nds32->privilege_level == 0) - ((struct nds32_reg *)reg_cache->reg_list[MR7].arch_info)->enable = true; - - if ((memory_config->icache.line_size != 0) && (memory_config->dcache.line_size != 0)) - ((struct nds32_reg *)reg_cache->reg_list[MR8].arch_info)->enable = true; - - if (misc_config->high_speed_memory_port) - ((struct nds32_reg *)reg_cache->reg_list[MR9].arch_info)->enable = true; - - if (mr10_exist) - ((struct nds32_reg *)reg_cache->reg_list[MR10].arch_info)->enable = true; - - if (misc_config->edm) { - int dr_reg_n = nds32->edm.breakpoint_num * 5; - - for (int i = 0 ; i < dr_reg_n ; i++) - ((struct nds32_reg *)reg_cache->reg_list[DR0 + i].arch_info)->enable = true; - - ((struct nds32_reg *)reg_cache->reg_list[DR41].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[DR43].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[DR44].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[DR45].arch_info)->enable = true; - } - - if (misc_config->debug_tracer) { - ((struct nds32_reg *)reg_cache->reg_list[DR46].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[DR47].arch_info)->enable = true; - } - - if (misc_config->performance_monitor) { - ((struct nds32_reg *)reg_cache->reg_list[PFR0].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[PFR1].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[PFR2].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[PFR3].arch_info)->enable = true; - } - - if (misc_config->local_memory_dma) { - ((struct nds32_reg *)reg_cache->reg_list[DMAR0].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[DMAR1].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[DMAR2].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[DMAR3].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[DMAR4].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[DMAR5].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[DMAR6].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[DMAR7].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[DMAR8].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[DMAR9].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[DMAR10].arch_info)->enable = true; - } - - if ((misc_config->local_memory_dma || misc_config->performance_monitor) && - (no_racr0 == false)) - ((struct nds32_reg *)reg_cache->reg_list[RACR].arch_info)->enable = true; - - if (cpu_version->cop_fpu_extension || (misc_config->audio_isa != 0)) - ((struct nds32_reg *)reg_cache->reg_list[FUCPR].arch_info)->enable = true; - - if (misc_config->audio_isa != 0) { - if (misc_config->audio_isa > 1) { - ((struct nds32_reg *)reg_cache->reg_list[D0L24].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[D1L24].arch_info)->enable = true; - } - - ((struct nds32_reg *)reg_cache->reg_list[I0].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[I1].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[I2].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[I3].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[I4].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[I5].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[I6].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[I7].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[M1].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[M2].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[M3].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[M5].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[M6].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[M7].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[MOD].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[LBE].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[LE].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[LC].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[ADM_VBASE].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[SHFT_CTL0].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[SHFT_CTL1].arch_info)->enable = true; - - uint32_t value_mod; - uint32_t fucpr_backup; - /* enable fpu and get configuration */ - nds32_get_mapped_reg(nds32, FUCPR, &fucpr_backup); - if ((fucpr_backup & 0x80000000) == 0) - nds32_set_mapped_reg(nds32, FUCPR, fucpr_backup | 0x80000000); - nds32_get_mapped_reg(nds32, MOD, &value_mod); - /* restore origin fucpr value */ - if ((fucpr_backup & 0x80000000) == 0) - nds32_set_mapped_reg(nds32, FUCPR, fucpr_backup); - - if ((value_mod >> 6) & 0x1) { - ((struct nds32_reg *)reg_cache->reg_list[CB_CTL].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[CBB0].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[CBB1].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[CBB2].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[CBB3].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[CBE0].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[CBE1].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[CBE2].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[CBE3].arch_info)->enable = true; - } - } - - if ((cpu_version->cpu_id_family == 0x9) || - (cpu_version->cpu_id_family == 0xA) || - (cpu_version->cpu_id_family == 0xC)) { - - ((struct nds32_reg *)reg_cache->reg_list[IDR0].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[IDR1].arch_info)->enable = true; - - if ((cpu_version->cpu_id_family == 0xC) && (cpu_version->revision == 0x0C)) - ((struct nds32_reg *)reg_cache->reg_list[IDR0].arch_info)->enable = false; - } - - uint32_t ir3_value; - uint32_t ivb_prog_pri_lvl; - uint32_t ivb_ivic_ver; - - nds32_get_mapped_reg(nds32, IR3, &ir3_value); - ivb_prog_pri_lvl = ir3_value & 0x1; - ivb_ivic_ver = (ir3_value >> 11) & 0x3; - - if ((ivb_prog_pri_lvl == 1) || (ivb_ivic_ver >= 1)) { - ((struct nds32_reg *)reg_cache->reg_list[IR18].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[IR19].arch_info)->enable = true; - } - - if (ivb_ivic_ver >= 1) { - ((struct nds32_reg *)reg_cache->reg_list[IR26].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[IR27].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[IR28].arch_info)->enable = true; - ((struct nds32_reg *)reg_cache->reg_list[IR29].arch_info)->enable = true; - } - - return ERROR_OK; -} - -int nds32_init_register_table(struct nds32 *nds32) -{ - nds32_init_must_have_registers(nds32); - - return ERROR_OK; -} - -int nds32_add_software_breakpoint(struct target *target, - struct breakpoint *breakpoint) -{ - uint32_t data; - uint32_t check_data; - uint32_t break_insn; - - /* check the breakpoint size */ - target->type->read_buffer(target, breakpoint->address, 4, (uint8_t *)&data); - - /* backup origin instruction - * instruction is big-endian */ - if (*(char *)&data & 0x80) { /* 16-bits instruction */ - breakpoint->length = 2; - break_insn = NDS32_BREAK_16; - } else { /* 32-bits instruction */ - breakpoint->length = 4; - break_insn = NDS32_BREAK_32; - } - - if (breakpoint->orig_instr != NULL) - free(breakpoint->orig_instr); - - breakpoint->orig_instr = malloc(breakpoint->length); - memcpy(breakpoint->orig_instr, &data, breakpoint->length); - - /* self-modified code */ - target->type->write_buffer(target, breakpoint->address, breakpoint->length, (const uint8_t *)&break_insn); - /* write_back & invalidate dcache & invalidate icache */ - nds32_cache_sync(target, breakpoint->address, breakpoint->length); - - /* read back to check */ - target->type->read_buffer(target, breakpoint->address, breakpoint->length, (uint8_t *)&check_data); - if (memcmp(&check_data, &break_insn, breakpoint->length) == 0) - return ERROR_OK; - - return ERROR_FAIL; -} - -int nds32_remove_software_breakpoint(struct target *target, - struct breakpoint *breakpoint) -{ - uint32_t check_data; - uint32_t break_insn; - - if (breakpoint->length == 2) - break_insn = NDS32_BREAK_16; - else if (breakpoint->length == 4) - break_insn = NDS32_BREAK_32; - else - return ERROR_FAIL; - - target->type->read_buffer(target, breakpoint->address, breakpoint->length, - (uint8_t *)&check_data); - - /* break instruction is modified */ - if (memcmp(&check_data, &break_insn, breakpoint->length) != 0) - return ERROR_FAIL; - - /* self-modified code */ - target->type->write_buffer(target, breakpoint->address, breakpoint->length, - breakpoint->orig_instr); - - /* write_back & invalidate dcache & invalidate icache */ - nds32_cache_sync(target, breakpoint->address, breakpoint->length); - - return ERROR_OK; -} - -/** - * Restore the processor context on an Andes target. The full processor - * context is analyzed to see if any of the registers are dirty on this end, but - * have a valid new value. If this is the case, the processor is changed to the - * appropriate mode and the new register values are written out to the - * processor. If there happens to be a dirty register with an invalid value, an - * error will be logged. - * - * @param target Pointer to the Andes target to have its context restored - * @return Error status if the target is not halted. - */ -int nds32_restore_context(struct target *target) -{ - struct nds32 *nds32 = target_to_nds32(target); - struct aice_port_s *aice = target_to_aice(target); - struct reg_cache *reg_cache = nds32->core_cache; - struct reg *reg; - struct nds32_reg *reg_arch_info; - unsigned int i; - - LOG_DEBUG("-"); - - if (target->state != TARGET_HALTED) { - LOG_WARNING("target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - /* check if there are dirty registers */ - for (i = 0; i < reg_cache->num_regs; i++) { - reg = &(reg_cache->reg_list[i]); - if (reg->dirty == true) { - if (reg->valid == true) { - - LOG_DEBUG("examining dirty reg: %s", reg->name); - LOG_DEBUG("writing register %d with value 0x%8.8" PRIx32, - i, buf_get_u32(reg->value, 0, 32)); - - reg_arch_info = reg->arch_info; - if (FD0 <= reg_arch_info->num && reg_arch_info->num <= FD31) { - uint64_t val = buf_get_u64(reg_arch_info->value, 0, 64); - aice_write_reg_64(aice, reg_arch_info->num, val); - } else { - uint32_t val = buf_get_u32(reg_arch_info->value, 0, 32); - aice_write_register(aice, reg_arch_info->num, val); - } - - reg->valid = true; - reg->dirty = false; - } - } - } - - return ERROR_OK; -} - -int nds32_edm_config(struct nds32 *nds32) -{ - struct target *target = nds32->target; - struct aice_port_s *aice = target_to_aice(target); - uint32_t edm_cfg; - uint32_t edm_ctl; - - aice_read_debug_reg(aice, NDS_EDM_SR_EDM_CFG, &edm_cfg); - - nds32->edm.version = (edm_cfg >> 16) & 0xFFFF; - LOG_INFO("EDM version 0x%04x", nds32->edm.version); - - nds32->edm.breakpoint_num = (edm_cfg & 0x7) + 1; - - if ((nds32->edm.version & 0x1000) || (0x60 <= nds32->edm.version)) - nds32->edm.access_control = true; - else - nds32->edm.access_control = false; - - if ((edm_cfg >> 4) & 0x1) - nds32->edm.direct_access_local_memory = true; - else - nds32->edm.direct_access_local_memory = false; - - if (nds32->edm.version <= 0x20) - nds32->edm.direct_access_local_memory = false; - - aice_read_debug_reg(aice, NDS_EDM_SR_EDM_CTL, &edm_ctl); - if (edm_ctl & (0x1 << 29)) - nds32->edm.support_max_stop = true; - else - nds32->edm.support_max_stop = false; - - /* set passcode for secure MCU */ - nds32_login(nds32); - - return ERROR_OK; -} - -int nds32_config(struct nds32 *nds32) -{ - nds32_init_config(nds32); - - /* init optional system registers according to config registers */ - nds32_init_option_registers(nds32); - - /* get max interrupt level */ - if (nds32->misc_config.interruption_level) - nds32->max_interrupt_level = 2; - else - nds32->max_interrupt_level = 3; - - /* get ILM/DLM size from MR6/MR7 */ - uint32_t value_mr6, value_mr7; - uint32_t size_index; - nds32_get_mapped_reg(nds32, MR6, &value_mr6); - size_index = (value_mr6 >> 1) & 0xF; - nds32->memory.ilm_size = NDS32_LM_SIZE_TABLE[size_index]; - - nds32_get_mapped_reg(nds32, MR7, &value_mr7); - size_index = (value_mr7 >> 1) & 0xF; - nds32->memory.dlm_size = NDS32_LM_SIZE_TABLE[size_index]; - - return ERROR_OK; -} - -int nds32_init_arch_info(struct target *target, struct nds32 *nds32) -{ - target->arch_info = nds32; - nds32->target = target; - - nds32->common_magic = NDS32_COMMON_MAGIC; - nds32->init_arch_info_after_halted = false; - nds32->auto_convert_hw_bp = true; - nds32->global_stop = false; - nds32->soft_reset_halt = false; - nds32->edm_passcode = NULL; - nds32->privilege_level = 0; - nds32->boot_time = 1500; - nds32->reset_halt_as_examine = false; - nds32->keep_target_edm_ctl = false; - nds32->word_access_mem = false; - nds32->virtual_hosting = true; - nds32->hit_syscall = false; - nds32->active_syscall_id = NDS32_SYSCALL_UNDEFINED; - nds32->virtual_hosting_errno = 0; - nds32->virtual_hosting_ctrl_c = false; - nds32->attached = false; - - nds32->syscall_break.asid = 0; - nds32->syscall_break.length = 4; - nds32->syscall_break.set = 0; - nds32->syscall_break.orig_instr = NULL; - nds32->syscall_break.next = NULL; - nds32->syscall_break.unique_id = 0x515CAll + target->target_number; - nds32->syscall_break.linked_BRP = 0; - - nds32_reg_init(); - - if (ERROR_FAIL == nds32_reg_cache_init(target, nds32)) - return ERROR_FAIL; - - if (ERROR_OK != nds32_init_register_table(nds32)) - return ERROR_FAIL; - - return ERROR_OK; -} - -int nds32_virtual_to_physical(struct target *target, uint32_t address, uint32_t *physical) -{ - struct nds32 *nds32 = target_to_nds32(target); - - if (nds32->memory.address_translation == false) { - *physical = address; - return ERROR_OK; - } - - if (ERROR_OK == nds32_probe_tlb(nds32, address, physical)) - return ERROR_OK; - - if (ERROR_OK == nds32_walk_page_table(nds32, address, physical)) - return ERROR_OK; - - return ERROR_FAIL; -} - -int nds32_cache_sync(struct target *target, uint32_t address, uint32_t length) -{ - struct aice_port_s *aice = target_to_aice(target); - struct nds32 *nds32 = target_to_nds32(target); - struct nds32_cache *dcache = &(nds32->memory.dcache); - struct nds32_cache *icache = &(nds32->memory.icache); - uint32_t dcache_line_size = NDS32_LINE_SIZE_TABLE[dcache->line_size]; - uint32_t icache_line_size = NDS32_LINE_SIZE_TABLE[icache->line_size]; - uint32_t cur_address; - int result; - uint32_t start_line, end_line; - uint32_t cur_line; - - if ((dcache->line_size != 0) && (dcache->enable == true)) { - /* address / dcache_line_size */ - start_line = address >> (dcache->line_size + 2); - /* (address + length - 1) / dcache_line_size */ - end_line = (address + length - 1) >> (dcache->line_size + 2); - - for (cur_address = address, cur_line = start_line ; - cur_line <= end_line ; - cur_address += dcache_line_size, cur_line++) { - /* D$ write back */ - result = aice_cache_ctl(aice, AICE_CACHE_CTL_L1D_VA_WB, cur_address); - if (result != ERROR_OK) - return result; - - /* D$ invalidate */ - result = aice_cache_ctl(aice, AICE_CACHE_CTL_L1D_VA_INVAL, cur_address); - if (result != ERROR_OK) - return result; - } - } - - if ((icache->line_size != 0) && (icache->enable == true)) { - /* address / icache_line_size */ - start_line = address >> (icache->line_size + 2); - /* (address + length - 1) / icache_line_size */ - end_line = (address + length - 1) >> (icache->line_size + 2); - - for (cur_address = address, cur_line = start_line ; - cur_line <= end_line ; - cur_address += icache_line_size, cur_line++) { - /* Because PSW.IT is turned off under debug exception, address MUST - * be physical address. L1I_VA_INVALIDATE uses PSW.IT to decide - * address translation or not. */ - uint32_t physical_addr; - if (ERROR_FAIL == target->type->virt2phys(target, cur_address, - &physical_addr)) - return ERROR_FAIL; - - /* I$ invalidate */ - result = aice_cache_ctl(aice, AICE_CACHE_CTL_L1I_VA_INVAL, physical_addr); - if (result != ERROR_OK) - return result; - } - } - - return ERROR_OK; -} - -uint32_t nds32_nextpc(struct nds32 *nds32, int current, uint32_t address) -{ - if (!current) - nds32_set_mapped_reg(nds32, PC, address); - else - nds32_get_mapped_reg(nds32, PC, &address); - - return address; -} - -int nds32_step(struct target *target, int current, - uint32_t address, int handle_breakpoints) -{ - LOG_DEBUG("target->state: %s", - target_state_name(target)); - - if (target->state != TARGET_HALTED) { - LOG_WARNING("target was not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - struct nds32 *nds32 = target_to_nds32(target); - - address = nds32_nextpc(nds32, current, address); - - LOG_DEBUG("STEP PC %08" PRIx32 "%s", address, !current ? "!" : ""); - - /** set DSSIM */ - uint32_t ir14_value; - nds32_get_mapped_reg(nds32, IR14, &ir14_value); - if (nds32->step_isr_enable) - ir14_value |= (0x1 << 31); - else - ir14_value &= ~(0x1 << 31); - nds32_set_mapped_reg(nds32, IR14, ir14_value); - - /* check hit_syscall before leave_debug_state() because - * leave_debug_state() may clear hit_syscall flag */ - bool no_step = false; - if (nds32->hit_syscall) - /* step after hit_syscall should be ignored because - * leave_debug_state will step implicitly to skip the - * syscall */ - no_step = true; - - /********* TODO: maybe create another function to handle this part */ - CHECK_RETVAL(nds32->leave_debug_state(nds32, true)); - CHECK_RETVAL(target_call_event_callbacks(target, TARGET_EVENT_RESUMED)); - - if (no_step == false) { - struct aice_port_s *aice = target_to_aice(target); - if (ERROR_OK != aice_step(aice)) - return ERROR_FAIL; - } - - /* save state */ - CHECK_RETVAL(nds32->enter_debug_state(nds32, true)); - /********* TODO: maybe create another function to handle this part */ - - /* restore DSSIM */ - if (nds32->step_isr_enable) { - nds32_get_mapped_reg(nds32, IR14, &ir14_value); - ir14_value &= ~(0x1 << 31); - nds32_set_mapped_reg(nds32, IR14, ir14_value); - } - - CHECK_RETVAL(target_call_event_callbacks(target, TARGET_EVENT_HALTED)); - - return ERROR_OK; -} - -static int nds32_step_without_watchpoint(struct nds32 *nds32) -{ - struct target *target = nds32->target; - - if (target->state != TARGET_HALTED) { - LOG_WARNING("target was not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - /** set DSSIM */ - uint32_t ir14_value; - nds32_get_mapped_reg(nds32, IR14, &ir14_value); - if (nds32->step_isr_enable) - ir14_value |= (0x1 << 31); - else - ir14_value &= ~(0x1 << 31); - nds32_set_mapped_reg(nds32, IR14, ir14_value); - - /********* TODO: maybe create another function to handle this part */ - CHECK_RETVAL(nds32->leave_debug_state(nds32, false)); - - struct aice_port_s *aice = target_to_aice(target); - - if (ERROR_OK != aice_step(aice)) - return ERROR_FAIL; - - /* save state */ - CHECK_RETVAL(nds32->enter_debug_state(nds32, false)); - /********* TODO: maybe create another function to handle this part */ - - /* restore DSSIM */ - if (nds32->step_isr_enable) { - nds32_get_mapped_reg(nds32, IR14, &ir14_value); - ir14_value &= ~(0x1 << 31); - nds32_set_mapped_reg(nds32, IR14, ir14_value); - } - - return ERROR_OK; -} - -int nds32_target_state(struct nds32 *nds32, enum target_state *state) -{ - struct aice_port_s *aice = target_to_aice(nds32->target); - enum aice_target_state_s nds32_state; - - if (aice_state(aice, &nds32_state) != ERROR_OK) - return ERROR_FAIL; - - switch (nds32_state) { - case AICE_DISCONNECT: - LOG_INFO("USB is disconnected"); - return ERROR_FAIL; - case AICE_TARGET_DETACH: - LOG_INFO("Target is disconnected"); - return ERROR_FAIL; - case AICE_TARGET_UNKNOWN: - *state = TARGET_UNKNOWN; - break; - case AICE_TARGET_RUNNING: - *state = TARGET_RUNNING; - break; - case AICE_TARGET_HALTED: - *state = TARGET_HALTED; - break; - case AICE_TARGET_RESET: - *state = TARGET_RESET; - break; - case AICE_TARGET_DEBUG_RUNNING: - *state = TARGET_DEBUG_RUNNING; - break; - default: - return ERROR_FAIL; - } - - return ERROR_OK; -} - -int nds32_examine_debug_reason(struct nds32 *nds32) -{ - uint32_t reason; - struct target *target = nds32->target; - - if (nds32->hit_syscall == true) { - LOG_DEBUG("Hit syscall breakpoint"); - target->debug_reason = DBG_REASON_BREAKPOINT; - return ERROR_OK; - } - - nds32->get_debug_reason(nds32, &reason); - - LOG_DEBUG("nds32 examines debug reason: %s", nds32_debug_type_name[reason]); - - /* Examine debug reason */ - switch (reason) { - case NDS32_DEBUG_BREAK: - case NDS32_DEBUG_BREAK_16: - case NDS32_DEBUG_INST_BREAK: - { - uint32_t value_pc; - uint32_t opcode; - struct nds32_instruction instruction; - - nds32_get_mapped_reg(nds32, PC, &value_pc); - - if (ERROR_OK != nds32_read_opcode(nds32, value_pc, &opcode)) - return ERROR_FAIL; - if (ERROR_OK != nds32_evaluate_opcode(nds32, opcode, value_pc, - &instruction)) - return ERROR_FAIL; - - /* hit 'break 0x7FFF' */ - if ((instruction.info.opc_6 == 0x32) && - (instruction.info.sub_opc == 0xA) && - (instruction.info.imm == 0x7FFF)) { - target->debug_reason = DBG_REASON_EXIT; - } else - target->debug_reason = DBG_REASON_BREAKPOINT; - } - break; - case NDS32_DEBUG_DATA_ADDR_WATCHPOINT_PRECISE: - case NDS32_DEBUG_DATA_VALUE_WATCHPOINT_PRECISE: - case NDS32_DEBUG_LOAD_STORE_GLOBAL_STOP: /* GLOBAL_STOP is precise exception */ - { - int result; - - result = nds32->get_watched_address(nds32, - &(nds32->watched_address), reason); - /* do single step(without watchpoints) to skip the "watched" instruction */ - nds32_step_without_watchpoint(nds32); - - /* before single_step, save exception address */ - if (ERROR_OK != result) - return ERROR_FAIL; - - target->debug_reason = DBG_REASON_WATCHPOINT; - } - break; - case NDS32_DEBUG_DEBUG_INTERRUPT: - target->debug_reason = DBG_REASON_DBGRQ; - break; - case NDS32_DEBUG_HARDWARE_SINGLE_STEP: - target->debug_reason = DBG_REASON_SINGLESTEP; - break; - case NDS32_DEBUG_DATA_VALUE_WATCHPOINT_IMPRECISE: - case NDS32_DEBUG_DATA_ADDR_WATCHPOINT_NEXT_PRECISE: - case NDS32_DEBUG_DATA_VALUE_WATCHPOINT_NEXT_PRECISE: - if (ERROR_OK != nds32->get_watched_address(nds32, - &(nds32->watched_address), reason)) - return ERROR_FAIL; - - target->debug_reason = DBG_REASON_WATCHPOINT; - break; - default: - target->debug_reason = DBG_REASON_UNDEFINED; - break; - } - - return ERROR_OK; -} - -int nds32_login(struct nds32 *nds32) -{ - struct target *target = nds32->target; - struct aice_port_s *aice = target_to_aice(target); - uint32_t passcode_length; - char command_sequence[129]; - char command_str[33]; - char code_str[9]; - uint32_t copy_length; - uint32_t code; - uint32_t i; - - LOG_DEBUG("nds32_login"); - - if (nds32->edm_passcode != NULL) { - /* convert EDM passcode to command sequences */ - passcode_length = strlen(nds32->edm_passcode); - command_sequence[0] = '\0'; - for (i = 0; i < passcode_length; i += 8) { - if (passcode_length - i < 8) - copy_length = passcode_length - i; - else - copy_length = 8; - - strncpy(code_str, nds32->edm_passcode + i, copy_length); - code_str[copy_length] = '\0'; - code = strtoul(code_str, NULL, 16); - - sprintf(command_str, "write_misc gen_port0 0x%" PRIx32 ";", code); - strcat(command_sequence, command_str); - } - - if (ERROR_OK != aice_program_edm(aice, command_sequence)) - return ERROR_FAIL; - - /* get current privilege level */ - uint32_t value_edmsw; - aice_read_debug_reg(aice, NDS_EDM_SR_EDMSW, &value_edmsw); - nds32->privilege_level = (value_edmsw >> 16) & 0x3; - LOG_INFO("Current privilege level: %d", nds32->privilege_level); - } - - if (nds32_edm_ops_num > 0) { - const char *reg_name; - for (i = 0 ; i < nds32_edm_ops_num ; i++) { - code = nds32_edm_ops[i].value; - if (nds32_edm_ops[i].reg_no == 6) - reg_name = "gen_port0"; - else if (nds32_edm_ops[i].reg_no == 7) - reg_name = "gen_port1"; - else - return ERROR_FAIL; - - sprintf(command_str, "write_misc %s 0x%" PRIx32 ";", reg_name, code); - if (ERROR_OK != aice_program_edm(aice, command_str)) - return ERROR_FAIL; - } - } - - return ERROR_OK; -} - -int nds32_halt(struct target *target) -{ - struct nds32 *nds32 = target_to_nds32(target); - struct aice_port_s *aice = target_to_aice(target); - enum target_state state; - - LOG_DEBUG("target->state: %s", - target_state_name(target)); - - if (target->state == TARGET_HALTED) { - LOG_DEBUG("target was already halted"); - return ERROR_OK; - } - - if (nds32_target_state(nds32, &state) != ERROR_OK) - return ERROR_FAIL; - - if (TARGET_HALTED != state) - /* TODO: if state == TARGET_HALTED, check ETYPE is DBGI or not */ - if (ERROR_OK != aice_halt(aice)) - return ERROR_FAIL; - - CHECK_RETVAL(nds32->enter_debug_state(nds32, true)); - - CHECK_RETVAL(target_call_event_callbacks(target, TARGET_EVENT_HALTED)); - - return ERROR_OK; -} - -/* poll current target status */ -int nds32_poll(struct target *target) -{ - struct nds32 *nds32 = target_to_nds32(target); - enum target_state state; - - if (nds32_target_state(nds32, &state) != ERROR_OK) - return ERROR_FAIL; - - if (state == TARGET_HALTED) { - if (target->state != TARGET_HALTED) { - /* if false_hit, continue free_run */ - if (ERROR_OK != nds32->enter_debug_state(nds32, true)) { - struct aice_port_s *aice = target_to_aice(target); - aice_run(aice); - return ERROR_OK; - } - - LOG_DEBUG("Change target state to TARGET_HALTED."); - - target_call_event_callbacks(target, TARGET_EVENT_HALTED); - } - } else if (state == TARGET_RESET) { - if (target->state == TARGET_HALTED) { - /* similar to assert srst */ - register_cache_invalidate(nds32->core_cache); - target->state = TARGET_RESET; - - /* TODO: deassert srst */ - } else if (target->state == TARGET_RUNNING) { - /* reset as running */ - LOG_WARNING("<-- TARGET WARNING! The debug target has been reset. -->"); - } - } else { - if (target->state != TARGET_RUNNING && target->state != TARGET_DEBUG_RUNNING) { - LOG_DEBUG("Change target state to TARGET_RUNNING."); - target->state = TARGET_RUNNING; - target->debug_reason = DBG_REASON_NOTHALTED; - } - } - - return ERROR_OK; -} - -int nds32_resume(struct target *target, int current, - uint32_t address, int handle_breakpoints, int debug_execution) -{ - LOG_DEBUG("current %d address %08" PRIx32 - " handle_breakpoints %d" - " debug_execution %d", - current, address, handle_breakpoints, debug_execution); - - struct nds32 *nds32 = target_to_nds32(target); - - if (target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - address = nds32_nextpc(nds32, current, address); - - LOG_DEBUG("RESUME PC %08" PRIx32 "%s", address, !current ? "!" : ""); - - if (!debug_execution) - target_free_all_working_areas(target); - - /* Disable HSS to avoid users misuse HSS */ - if (nds32_reach_max_interrupt_level(nds32) == false) { - uint32_t value_ir0; - nds32_get_mapped_reg(nds32, IR0, &value_ir0); - value_ir0 &= ~(0x1 << 11); - nds32_set_mapped_reg(nds32, IR0, value_ir0); - } - - CHECK_RETVAL(nds32->leave_debug_state(nds32, true)); - CHECK_RETVAL(target_call_event_callbacks(target, TARGET_EVENT_RESUMED)); - - if (nds32->virtual_hosting_ctrl_c == false) { - struct aice_port_s *aice = target_to_aice(target); - aice_run(aice); - } else - nds32->virtual_hosting_ctrl_c = false; - - target->debug_reason = DBG_REASON_NOTHALTED; - if (!debug_execution) - target->state = TARGET_RUNNING; - else - target->state = TARGET_DEBUG_RUNNING; - - LOG_DEBUG("target->state: %s", - target_state_name(target)); - - return ERROR_OK; -} - -static int nds32_soft_reset_halt(struct target *target) -{ - /* TODO: test it */ - struct nds32 *nds32 = target_to_nds32(target); - struct aice_port_s *aice = target_to_aice(target); - - aice_assert_srst(aice, AICE_SRST); - - /* halt core and set pc to 0x0 */ - int retval = target_halt(target); - if (retval != ERROR_OK) - return retval; - - /* start fetching from IVB */ - uint32_t value_ir3; - nds32_get_mapped_reg(nds32, IR3, &value_ir3); - nds32_set_mapped_reg(nds32, PC, value_ir3 & 0xFFFF0000); - - return ERROR_OK; -} - -int nds32_assert_reset(struct target *target) -{ - struct nds32 *nds32 = target_to_nds32(target); - struct aice_port_s *aice = target_to_aice(target); - struct nds32_cpu_version *cpu_version = &(nds32->cpu_version); - - /* TODO: apply hw reset signal in not examined state */ - if (!(target_was_examined(target))) { - LOG_WARNING("Reset is not asserted because the target is not examined."); - LOG_WARNING("Use a reset button or power cycle the target."); - return ERROR_TARGET_NOT_EXAMINED; - } - - if (target->reset_halt) { - if ((nds32->soft_reset_halt) - || (nds32->edm.version < 0x51) - || ((nds32->edm.version == 0x51) - && (cpu_version->revision == 0x1C) - && (cpu_version->cpu_id_family == 0xC) - && (cpu_version->cpu_id_version == 0x0))) - nds32_soft_reset_halt(target); - else - aice_assert_srst(aice, AICE_RESET_HOLD); - } else { - aice_assert_srst(aice, AICE_SRST); - alive_sleep(nds32->boot_time); - } - - /* set passcode for secure MCU after core reset */ - nds32_login(nds32); - - /* registers are now invalid */ - register_cache_invalidate(nds32->core_cache); - - target->state = TARGET_RESET; - - return ERROR_OK; -} - -static int nds32_gdb_attach(struct nds32 *nds32) -{ - LOG_DEBUG("nds32_gdb_attach, target coreid: %" PRId32, nds32->target->coreid); - - if (nds32->attached == false) { - - if (nds32->keep_target_edm_ctl) { - /* backup target EDM_CTL */ - struct aice_port_s *aice = target_to_aice(nds32->target); - aice_read_debug_reg(aice, NDS_EDM_SR_EDM_CTL, &nds32->backup_edm_ctl); - } - - target_halt(nds32->target); - - nds32->attached = true; - } - - return ERROR_OK; -} - -static int nds32_gdb_detach(struct nds32 *nds32) -{ - LOG_DEBUG("nds32_gdb_detach"); - bool backup_virtual_hosting_setting; - - if (nds32->attached) { - - backup_virtual_hosting_setting = nds32->virtual_hosting; - /* turn off virtual hosting before resume as gdb-detach */ - nds32->virtual_hosting = false; - target_resume(nds32->target, 1, 0, 0, 0); - nds32->virtual_hosting = backup_virtual_hosting_setting; - - if (nds32->keep_target_edm_ctl) { - /* restore target EDM_CTL */ - struct aice_port_s *aice = target_to_aice(nds32->target); - aice_write_debug_reg(aice, NDS_EDM_SR_EDM_CTL, nds32->backup_edm_ctl); - } - - nds32->attached = false; - } - - return ERROR_OK; -} - -static int nds32_callback_event_handler(struct target *target, - enum target_event event, void *priv) -{ - int retval = ERROR_OK; - int target_number = *(int *)priv; - - if (target_number != target->target_number) - return ERROR_OK; - - struct nds32 *nds32 = target_to_nds32(target); - - switch (event) { - case TARGET_EVENT_GDB_ATTACH: - retval = nds32_gdb_attach(nds32); - break; - case TARGET_EVENT_GDB_DETACH: - retval = nds32_gdb_detach(nds32); - break; - default: - break; - } - - return retval; -} - -int nds32_init(struct nds32 *nds32) -{ - /* Initialize anything we can set up without talking to the target */ - nds32->memory.access_channel = NDS_MEMORY_ACC_CPU; - - /* register event callback */ - target_register_event_callback(nds32_callback_event_handler, - &(nds32->target->target_number)); - - return ERROR_OK; -} - -int nds32_get_gdb_fileio_info(struct target *target, struct gdb_fileio_info *fileio_info) -{ - /* fill syscall parameters to file-I/O info */ - if (NULL == fileio_info) { - LOG_ERROR("Target has not initial file-I/O data structure"); - return ERROR_FAIL; - } - - struct nds32 *nds32 = target_to_nds32(target); - uint32_t value_ir6; - uint32_t syscall_id; - - if (nds32->hit_syscall == false) - return ERROR_FAIL; - - nds32_get_mapped_reg(nds32, IR6, &value_ir6); - syscall_id = (value_ir6 >> 16) & 0x7FFF; - nds32->active_syscall_id = syscall_id; - - LOG_DEBUG("hit syscall ID: 0x%" PRIx32, syscall_id); - - /* free previous identifier storage */ - if (NULL != fileio_info->identifier) { - free(fileio_info->identifier); - fileio_info->identifier = NULL; - } - - switch (syscall_id) { - case NDS32_SYSCALL_EXIT: - fileio_info->identifier = malloc(5); - sprintf(fileio_info->identifier, "exit"); - nds32_get_mapped_reg(nds32, R0, &(fileio_info->param_1)); - break; - case NDS32_SYSCALL_OPEN: - { - uint8_t filename[256]; - fileio_info->identifier = malloc(5); - sprintf(fileio_info->identifier, "open"); - nds32_get_mapped_reg(nds32, R0, &(fileio_info->param_1)); - /* reserve fileio_info->param_2 for length of path */ - nds32_get_mapped_reg(nds32, R1, &(fileio_info->param_3)); - nds32_get_mapped_reg(nds32, R2, &(fileio_info->param_4)); - - target->type->read_buffer(target, fileio_info->param_1, - 256, filename); - fileio_info->param_2 = strlen((char *)filename) + 1; - } - break; - case NDS32_SYSCALL_CLOSE: - fileio_info->identifier = malloc(6); - sprintf(fileio_info->identifier, "close"); - nds32_get_mapped_reg(nds32, R0, &(fileio_info->param_1)); - break; - case NDS32_SYSCALL_READ: - fileio_info->identifier = malloc(5); - sprintf(fileio_info->identifier, "read"); - nds32_get_mapped_reg(nds32, R0, &(fileio_info->param_1)); - nds32_get_mapped_reg(nds32, R1, &(fileio_info->param_2)); - nds32_get_mapped_reg(nds32, R2, &(fileio_info->param_3)); - break; - case NDS32_SYSCALL_WRITE: - fileio_info->identifier = malloc(6); - sprintf(fileio_info->identifier, "write"); - nds32_get_mapped_reg(nds32, R0, &(fileio_info->param_1)); - nds32_get_mapped_reg(nds32, R1, &(fileio_info->param_2)); - nds32_get_mapped_reg(nds32, R2, &(fileio_info->param_3)); - break; - case NDS32_SYSCALL_LSEEK: - fileio_info->identifier = malloc(6); - sprintf(fileio_info->identifier, "lseek"); - nds32_get_mapped_reg(nds32, R0, &(fileio_info->param_1)); - nds32_get_mapped_reg(nds32, R1, &(fileio_info->param_2)); - nds32_get_mapped_reg(nds32, R2, &(fileio_info->param_3)); - break; - case NDS32_SYSCALL_UNLINK: - { - uint8_t filename[256]; - fileio_info->identifier = malloc(7); - sprintf(fileio_info->identifier, "unlink"); - nds32_get_mapped_reg(nds32, R0, &(fileio_info->param_1)); - /* reserve fileio_info->param_2 for length of path */ - - target->type->read_buffer(target, fileio_info->param_1, - 256, filename); - fileio_info->param_2 = strlen((char *)filename) + 1; - } - break; - case NDS32_SYSCALL_RENAME: - { - uint8_t filename[256]; - fileio_info->identifier = malloc(7); - sprintf(fileio_info->identifier, "rename"); - nds32_get_mapped_reg(nds32, R0, &(fileio_info->param_1)); - /* reserve fileio_info->param_2 for length of old path */ - nds32_get_mapped_reg(nds32, R1, &(fileio_info->param_3)); - /* reserve fileio_info->param_4 for length of new path */ - - target->type->read_buffer(target, fileio_info->param_1, - 256, filename); - fileio_info->param_2 = strlen((char *)filename) + 1; - - target->type->read_buffer(target, fileio_info->param_3, - 256, filename); - fileio_info->param_4 = strlen((char *)filename) + 1; - } - break; - case NDS32_SYSCALL_FSTAT: - fileio_info->identifier = malloc(6); - sprintf(fileio_info->identifier, "fstat"); - nds32_get_mapped_reg(nds32, R0, &(fileio_info->param_1)); - nds32_get_mapped_reg(nds32, R1, &(fileio_info->param_2)); - break; - case NDS32_SYSCALL_STAT: - { - uint8_t filename[256]; - fileio_info->identifier = malloc(5); - sprintf(fileio_info->identifier, "stat"); - nds32_get_mapped_reg(nds32, R0, &(fileio_info->param_1)); - /* reserve fileio_info->param_2 for length of old path */ - nds32_get_mapped_reg(nds32, R1, &(fileio_info->param_3)); - - target->type->read_buffer(target, fileio_info->param_1, - 256, filename); - fileio_info->param_2 = strlen((char *)filename) + 1; - } - break; - case NDS32_SYSCALL_GETTIMEOFDAY: - fileio_info->identifier = malloc(13); - sprintf(fileio_info->identifier, "gettimeofday"); - nds32_get_mapped_reg(nds32, R0, &(fileio_info->param_1)); - nds32_get_mapped_reg(nds32, R1, &(fileio_info->param_2)); - break; - case NDS32_SYSCALL_ISATTY: - fileio_info->identifier = malloc(7); - sprintf(fileio_info->identifier, "isatty"); - nds32_get_mapped_reg(nds32, R0, &(fileio_info->param_1)); - break; - case NDS32_SYSCALL_SYSTEM: - { - uint8_t command[256]; - fileio_info->identifier = malloc(7); - sprintf(fileio_info->identifier, "system"); - nds32_get_mapped_reg(nds32, R0, &(fileio_info->param_1)); - /* reserve fileio_info->param_2 for length of old path */ - - target->type->read_buffer(target, fileio_info->param_1, - 256, command); - fileio_info->param_2 = strlen((char *)command) + 1; - } - break; - case NDS32_SYSCALL_ERRNO: - fileio_info->identifier = malloc(6); - sprintf(fileio_info->identifier, "errno"); - nds32_set_mapped_reg(nds32, R0, nds32->virtual_hosting_errno); - break; - default: - fileio_info->identifier = malloc(8); - sprintf(fileio_info->identifier, "unknown"); - break; - } - - return ERROR_OK; -} - -int nds32_gdb_fileio_end(struct target *target, int retcode, int fileio_errno, bool ctrl_c) -{ - LOG_DEBUG("syscall return code: 0x%x, errno: 0x%x , ctrl_c: %s", - retcode, fileio_errno, ctrl_c ? "true" : "false"); - - struct nds32 *nds32 = target_to_nds32(target); - - nds32_set_mapped_reg(nds32, R0, (uint32_t)retcode); - - nds32->virtual_hosting_errno = fileio_errno; - nds32->virtual_hosting_ctrl_c = ctrl_c; - nds32->active_syscall_id = NDS32_SYSCALL_UNDEFINED; - - return ERROR_OK; -} - -int nds32_profiling(struct target *target, uint32_t *samples, - uint32_t max_num_samples, uint32_t *num_samples, uint32_t seconds) -{ - /* sample $PC every 10 milliseconds */ - uint32_t iteration = seconds * 100; - struct aice_port_s *aice = target_to_aice(target); - struct nds32 *nds32 = target_to_nds32(target); - - if (max_num_samples < iteration) - iteration = max_num_samples; - - int pc_regnum = nds32->register_map(nds32, PC); - aice_profiling(aice, 10, iteration, pc_regnum, samples, num_samples); - - register_cache_invalidate(nds32->core_cache); - - return ERROR_OK; -} - -int nds32_gdb_fileio_write_memory(struct nds32 *nds32, uint32_t address, - uint32_t size, const uint8_t *buffer) -{ - if ((NDS32_SYSCALL_FSTAT == nds32->active_syscall_id) || - (NDS32_SYSCALL_STAT == nds32->active_syscall_id)) { - /* If doing GDB file-I/O, target should convert 'struct stat' - * from gdb-format to target-format */ - uint8_t stat_buffer[NDS32_STRUCT_STAT_SIZE]; - /* st_dev 2 */ - stat_buffer[0] = buffer[3]; - stat_buffer[1] = buffer[2]; - /* st_ino 2 */ - stat_buffer[2] = buffer[7]; - stat_buffer[3] = buffer[6]; - /* st_mode 4 */ - stat_buffer[4] = buffer[11]; - stat_buffer[5] = buffer[10]; - stat_buffer[6] = buffer[9]; - stat_buffer[7] = buffer[8]; - /* st_nlink 2 */ - stat_buffer[8] = buffer[15]; - stat_buffer[9] = buffer[16]; - /* st_uid 2 */ - stat_buffer[10] = buffer[19]; - stat_buffer[11] = buffer[18]; - /* st_gid 2 */ - stat_buffer[12] = buffer[23]; - stat_buffer[13] = buffer[22]; - /* st_rdev 2 */ - stat_buffer[14] = buffer[27]; - stat_buffer[15] = buffer[26]; - /* st_size 4 */ - stat_buffer[16] = buffer[35]; - stat_buffer[17] = buffer[34]; - stat_buffer[18] = buffer[33]; - stat_buffer[19] = buffer[32]; - /* st_atime 4 */ - stat_buffer[20] = buffer[55]; - stat_buffer[21] = buffer[54]; - stat_buffer[22] = buffer[53]; - stat_buffer[23] = buffer[52]; - /* st_spare1 4 */ - stat_buffer[24] = 0; - stat_buffer[25] = 0; - stat_buffer[26] = 0; - stat_buffer[27] = 0; - /* st_mtime 4 */ - stat_buffer[28] = buffer[59]; - stat_buffer[29] = buffer[58]; - stat_buffer[30] = buffer[57]; - stat_buffer[31] = buffer[56]; - /* st_spare2 4 */ - stat_buffer[32] = 0; - stat_buffer[33] = 0; - stat_buffer[34] = 0; - stat_buffer[35] = 0; - /* st_ctime 4 */ - stat_buffer[36] = buffer[63]; - stat_buffer[37] = buffer[62]; - stat_buffer[38] = buffer[61]; - stat_buffer[39] = buffer[60]; - /* st_spare3 4 */ - stat_buffer[40] = 0; - stat_buffer[41] = 0; - stat_buffer[42] = 0; - stat_buffer[43] = 0; - /* st_blksize 4 */ - stat_buffer[44] = buffer[43]; - stat_buffer[45] = buffer[42]; - stat_buffer[46] = buffer[41]; - stat_buffer[47] = buffer[40]; - /* st_blocks 4 */ - stat_buffer[48] = buffer[51]; - stat_buffer[49] = buffer[50]; - stat_buffer[50] = buffer[49]; - stat_buffer[51] = buffer[48]; - /* st_spare4 8 */ - stat_buffer[52] = 0; - stat_buffer[53] = 0; - stat_buffer[54] = 0; - stat_buffer[55] = 0; - stat_buffer[56] = 0; - stat_buffer[57] = 0; - stat_buffer[58] = 0; - stat_buffer[59] = 0; - - return nds32_write_buffer(nds32->target, address, NDS32_STRUCT_STAT_SIZE, stat_buffer); - } else if (NDS32_SYSCALL_GETTIMEOFDAY == nds32->active_syscall_id) { - /* If doing GDB file-I/O, target should convert 'struct timeval' - * from gdb-format to target-format */ - uint8_t timeval_buffer[NDS32_STRUCT_TIMEVAL_SIZE]; - timeval_buffer[0] = buffer[3]; - timeval_buffer[1] = buffer[2]; - timeval_buffer[2] = buffer[1]; - timeval_buffer[3] = buffer[0]; - timeval_buffer[4] = buffer[11]; - timeval_buffer[5] = buffer[10]; - timeval_buffer[6] = buffer[9]; - timeval_buffer[7] = buffer[8]; - - return nds32_write_buffer(nds32->target, address, NDS32_STRUCT_TIMEVAL_SIZE, timeval_buffer); - } - - return nds32_write_buffer(nds32->target, address, size, buffer); -} - -int nds32_reset_halt(struct nds32 *nds32) -{ - LOG_INFO("reset halt as init"); - - struct aice_port_s *aice = target_to_aice(nds32->target); - aice_assert_srst(aice, AICE_RESET_HOLD); - - return ERROR_OK; -} diff --git a/src/target/nds32.h b/src/target/nds32.h deleted file mode 100644 index 88af4f3aa..000000000 --- a/src/target/nds32.h +++ /dev/null @@ -1,457 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2013 Andes Technology * - * Hsiangkai Wang * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 OPENOCD_TARGET_NDS32_H -#define OPENOCD_TARGET_NDS32_H - -#include -#include "target.h" -#include "target_type.h" -#include "register.h" -#include "breakpoints.h" -#include "nds32_reg.h" -#include "nds32_insn.h" -#include "nds32_edm.h" - -#define NDS32_EDM_OPERATION_MAX_NUM 64 - -#define CHECK_RETVAL(action) \ - do { \ - int __retval = (action); \ - if (__retval != ERROR_OK) { \ - LOG_DEBUG("error while calling \"%s\"", \ - # action); \ - return __retval; \ - } \ - } while (0) - -/** - * @file - * Holds the interface to Andes cores. - */ - -extern const char *nds32_debug_type_name[11]; - -enum nds32_debug_reason { - NDS32_DEBUG_BREAK = 0, - NDS32_DEBUG_BREAK_16, - NDS32_DEBUG_INST_BREAK, - NDS32_DEBUG_DATA_ADDR_WATCHPOINT_PRECISE, - NDS32_DEBUG_DATA_VALUE_WATCHPOINT_PRECISE, - NDS32_DEBUG_DATA_VALUE_WATCHPOINT_IMPRECISE, - NDS32_DEBUG_DEBUG_INTERRUPT, - NDS32_DEBUG_HARDWARE_SINGLE_STEP, - NDS32_DEBUG_DATA_ADDR_WATCHPOINT_NEXT_PRECISE, - NDS32_DEBUG_DATA_VALUE_WATCHPOINT_NEXT_PRECISE, - NDS32_DEBUG_LOAD_STORE_GLOBAL_STOP, -}; - -#define NDS32_STRUCT_STAT_SIZE 60 -#define NDS32_STRUCT_TIMEVAL_SIZE 8 - -enum nds32_syscall_id { - NDS32_SYSCALL_UNDEFINED = 0, - NDS32_SYSCALL_EXIT = 1, - NDS32_SYSCALL_OPEN = 2, - NDS32_SYSCALL_CLOSE = 3, - NDS32_SYSCALL_READ = 4, - NDS32_SYSCALL_WRITE = 5, - NDS32_SYSCALL_LSEEK = 6, - NDS32_SYSCALL_UNLINK = 7, - NDS32_SYSCALL_RENAME = 3001, - NDS32_SYSCALL_FSTAT = 10, - NDS32_SYSCALL_STAT = 15, - NDS32_SYSCALL_GETTIMEOFDAY = 19, - NDS32_SYSCALL_ISATTY = 3002, - NDS32_SYSCALL_SYSTEM = 3003, - NDS32_SYSCALL_ERRNO = 6001, -}; - -#define NDS32_COMMON_MAGIC (int)0xADE5ADE5 - -struct nds32_edm { - - /** EDM_CFG.VER, indicate the EDM version */ - int version; - - /** The number of hardware breakpoints */ - int breakpoint_num; - - /** EDM_CFG.DALM, indicate if direct local memory access - * feature is supported or not */ - bool direct_access_local_memory; - - /** Support ACC_CTL register */ - bool access_control; - - /** */ - bool support_max_stop; -}; - -struct nds32_cache { - - /** enable cache or not */ - bool enable; - - /** cache sets per way */ - int set; - - /** cache ways */ - int way; - - /** cache line size */ - int line_size; - - /** cache locking support */ - bool lock_support; -}; - -struct nds32_memory { - - /** ICache */ - struct nds32_cache icache; - - /** DCache */ - struct nds32_cache dcache; - - /** On-chip instruction local memory base */ - int ilm_base; - - /** On-chip instruction local memory size */ - int ilm_size; - - /** ILM base register alignment version */ - int ilm_align_ver; - - /** DLM is enabled or not */ - bool ilm_enable; - - /** DLM start address */ - int ilm_start; - - /** DLM end address */ - int ilm_end; - - /** On-chip data local memory base */ - int dlm_base; - - /** On-chip data local memory size */ - int dlm_size; - - /** DLM base register alignment version */ - int dlm_align_ver; - - /** DLM is enabled or not */ - bool dlm_enable; - - /** DLM start address */ - int dlm_start; - - /** DLM end address */ - int dlm_end; - - /** Memory access method */ - enum nds_memory_access access_channel; - - /** Memory access mode */ - enum nds_memory_select mode; - - /** Address translation */ - bool address_translation; -}; - -struct nds32_cpu_version { - bool performance_extension; - bool _16bit_extension; - bool performance_extension_2; - bool cop_fpu_extension; - bool string_extension; - - int revision; - int cpu_id_family; - int cpu_id_version; -}; - -struct nds32_mmu_config { - int memory_protection; - int memory_protection_version; - bool fully_associative_tlb; - int tlb_size; - int tlb_ways; - int tlb_sets; - bool _8k_page_support; - int extra_page_size_support; - bool tlb_lock; - bool hardware_page_table_walker; - bool default_endian; - int partition_num; - bool invisible_tlb; - bool vlpt; - bool ntme; - bool drde; - int default_min_page_size; - bool multiple_page_size_in_use; -}; - -struct nds32_misc_config { - bool edm; - bool local_memory_dma; - bool performance_monitor; - bool high_speed_memory_port; - bool debug_tracer; - bool div_instruction; - bool mac_instruction; - int audio_isa; - bool L2_cache; - bool reduce_register; - bool addr_24; - bool interruption_level; - int baseline_instruction; - bool no_dx_register; - bool implement_dependant_register; - bool implement_dependant_sr_encoding; - bool ifc; - bool mcu; - bool ex9; - int shadow; -}; - -/** - * Represents a generic Andes core. - */ -struct nds32 { - int common_magic; - struct reg_cache *core_cache; - - /** Handle for the debug module. */ - struct nds32_edm edm; - - /** Memory information */ - struct nds32_memory memory; - - /** cpu version */ - struct nds32_cpu_version cpu_version; - - /** MMU configuration */ - struct nds32_mmu_config mmu_config; - - /** Misc configuration */ - struct nds32_misc_config misc_config; - - /** Retrieve all core registers, for display. */ - int (*full_context)(struct nds32 *nds32); - - /** Register mappings */ - int (*register_map)(struct nds32 *nds32, int reg_no); - - /** Get debug exception virtual address */ - int (*get_debug_reason)(struct nds32 *nds32, uint32_t *reason); - - /** Restore target registers may be modified in debug state */ - int (*leave_debug_state)(struct nds32 *nds32, bool enable_watchpoint); - - /** Backup target registers may be modified in debug state */ - int (*enter_debug_state)(struct nds32 *nds32, bool enable_watchpoint); - - /** Get address hit watchpoint */ - int (*get_watched_address)(struct nds32 *nds32, uint32_t *address, uint32_t reason); - - /** maximum interrupt level */ - uint32_t max_interrupt_level; - - /** current interrupt level */ - uint32_t current_interrupt_level; - - uint32_t watched_address; - - /** Flag reporting whether virtual hosting is active. */ - bool virtual_hosting; - - /** Flag reporting whether continue/step hits syscall or not */ - bool hit_syscall; - - /** Value to be returned by virtual hosting SYS_ERRNO request. */ - int virtual_hosting_errno; - - /** Flag reporting whether syscall is aborted */ - bool virtual_hosting_ctrl_c; - - /** Record syscall ID for other operations to do special processing for target */ - int active_syscall_id; - - struct breakpoint syscall_break; - - /** Flag reporting whether global stop is active. */ - bool global_stop; - - /** Flag reporting whether to use soft-reset-halt or not as issuing reset-halt. */ - bool soft_reset_halt; - - /** reset-halt as target examine */ - bool reset_halt_as_examine; - - /** backup/restore target EDM_CTL value. As debugging target debug - * handler, it should be true. */ - bool keep_target_edm_ctl; - - /* Value of $EDM_CTL before target enters debug mode */ - uint32_t backup_edm_ctl; - - /** always use word-aligned address to access memory */ - bool word_access_mem; - - /** EDM passcode for debugging secure MCU */ - char *edm_passcode; - - /** current privilege_level if using secure MCU. value 0 is the highest level. */ - int privilege_level; - - /** Period to wait after SRST. */ - uint32_t boot_time; - - /** Flag to indicate HSS steps into ISR or not */ - bool step_isr_enable; - - /** Flag to indicate register table is ready or not */ - bool init_arch_info_after_halted; - - /** Flag to indicate audio-extension is enabled or not */ - bool audio_enable; - - /** Flag to indicate fpu-extension is enabled or not */ - bool fpu_enable; - - /* Andes Core has mixed endian model. Instruction is always big-endian. - * Data may be big or little endian. Device registers may have different - * endian from data and instruction. */ - /** Endian of data memory */ - enum target_endianness data_endian; - - /** Endian of device registers */ - enum target_endianness device_reg_endian; - - /** Flag to indicate if auto convert software breakpoints to - * hardware breakpoints or not in ROM */ - bool auto_convert_hw_bp; - - /* Flag to indicate the target is attached by debugger or not */ - bool attached; - - /** Backpointer to the target. */ - struct target *target; - - void *arch_info; -}; - -struct nds32_reg { - int32_t num; - uint8_t value[8]; - struct target *target; - struct nds32 *nds32; - bool enable; -}; - -struct nds32_edm_operation { - uint32_t reg_no; - uint32_t value; -}; - -extern int nds32_config(struct nds32 *nds32); -extern int nds32_init_arch_info(struct target *target, struct nds32 *nds32); -extern int nds32_full_context(struct nds32 *nds32); -extern int nds32_arch_state(struct target *target); -extern int nds32_add_software_breakpoint(struct target *target, - struct breakpoint *breakpoint); -extern int nds32_remove_software_breakpoint(struct target *target, - struct breakpoint *breakpoint); - -extern int nds32_get_gdb_reg_list(struct target *target, - struct reg **reg_list[], int *reg_list_size, - enum target_register_class reg_class); - -extern int nds32_write_buffer(struct target *target, uint32_t address, - uint32_t size, const uint8_t *buffer); -extern int nds32_read_buffer(struct target *target, uint32_t address, - uint32_t size, uint8_t *buffer); -extern int nds32_read_memory(struct target *target, uint32_t address, - uint32_t size, uint32_t count, uint8_t *buffer); -extern int nds32_write_memory(struct target *target, uint32_t address, - uint32_t size, uint32_t count, const uint8_t *buffer); - -extern int nds32_init_register_table(struct nds32 *nds32); -extern int nds32_init_memory_info(struct nds32 *nds32); -extern int nds32_restore_context(struct target *target); -extern int nds32_get_mapped_reg(struct nds32 *nds32, unsigned regnum, uint32_t *value); -extern int nds32_set_mapped_reg(struct nds32 *nds32, unsigned regnum, uint32_t value); - -extern int nds32_edm_config(struct nds32 *nds32); -extern int nds32_cache_sync(struct target *target, uint32_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, - uint32_t size, uint32_t count, uint8_t *buffer); -extern int nds32_write_phys_memory(struct target *target, uint32_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); -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); -extern int nds32_assert_reset(struct target *target); -extern int nds32_init(struct nds32 *nds32); -extern int nds32_get_gdb_fileio_info(struct target *target, struct gdb_fileio_info *fileio_info); -extern int nds32_gdb_fileio_write_memory(struct nds32 *nds32, uint32_t address, - uint32_t size, const uint8_t *buffer); -extern int nds32_gdb_fileio_end(struct target *target, int retcode, int fileio_errno, bool ctrl_c); -extern int nds32_reset_halt(struct nds32 *nds32); -extern int nds32_login(struct nds32 *nds32); -extern int nds32_profiling(struct target *target, uint32_t *samples, - uint32_t max_num_samples, uint32_t *num_samples, uint32_t seconds); - -/** Convert target handle to generic Andes target state handle. */ -static inline struct nds32 *target_to_nds32(struct target *target) -{ - assert(target != NULL); - return target->arch_info; -} - -/** */ -static inline struct aice_port_s *target_to_aice(struct target *target) -{ - assert(target != NULL); - return target->tap->priv; -} - -static inline bool is_nds32(struct nds32 *nds32) -{ - assert(nds32 != NULL); - return nds32->common_magic == NDS32_COMMON_MAGIC; -} - -static inline bool nds32_reach_max_interrupt_level(struct nds32 *nds32) -{ - assert(nds32 != NULL); - return nds32->max_interrupt_level == nds32->current_interrupt_level; -} - -#endif /* OPENOCD_TARGET_NDS32_H */ diff --git a/src/target/nds32_aice.c b/src/target/nds32_aice.c deleted file mode 100644 index bdfafb53a..000000000 --- a/src/target/nds32_aice.c +++ /dev/null @@ -1,158 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2013 Andes technology. * - * Hsiangkai Wang * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 -#include "config.h" -#endif - -#include -#include "nds32_aice.h" - -int aice_read_reg_64(struct aice_port_s *aice, uint32_t num, uint64_t *val) -{ - if (aice->port->api->read_reg_64 == NULL) { - LOG_WARNING("Not implemented: %s", __func__); - return ERROR_FAIL; - } - - return aice->port->api->read_reg_64(aice->coreid, num, val); -} - -int aice_write_reg_64(struct aice_port_s *aice, uint32_t num, uint64_t val) -{ - if (aice->port->api->write_reg_64 == NULL) { - LOG_WARNING("Not implemented: %s", __func__); - return ERROR_FAIL; - } - - return aice->port->api->write_reg_64(aice->coreid, num, val); -} - -int aice_read_tlb(struct aice_port_s *aice, uint32_t virtual_address, - uint32_t *physical_address) -{ - if (aice->port->api->read_tlb == NULL) { - LOG_WARNING("Not implemented: %s", __func__); - return ERROR_FAIL; - } - - return aice->port->api->read_tlb(aice->coreid, virtual_address, physical_address); -} - -int aice_cache_ctl(struct aice_port_s *aice, uint32_t subtype, uint32_t address) -{ - if (aice->port->api->cache_ctl == NULL) { - LOG_WARNING("Not implemented: %s", __func__); - return ERROR_FAIL; - } - - return aice->port->api->cache_ctl(aice->coreid, subtype, address); -} - -int aice_set_retry_times(struct aice_port_s *aice, uint32_t a_retry_times) -{ - if (aice->port->api->set_retry_times == NULL) { - LOG_WARNING("Not implemented: %s", __func__); - return ERROR_FAIL; - } - - return aice->port->api->set_retry_times(a_retry_times); -} - -int aice_program_edm(struct aice_port_s *aice, char *command_sequence) -{ - if (aice->port->api->program_edm == NULL) { - LOG_WARNING("Not implemented: %s", __func__); - return ERROR_FAIL; - } - - return aice->port->api->program_edm(aice->coreid, command_sequence); -} - -int aice_set_command_mode(struct aice_port_s *aice, - enum aice_command_mode command_mode) -{ - if (aice->port->api->set_command_mode == NULL) { - LOG_WARNING("Not implemented: %s", __func__); - return ERROR_FAIL; - } - - return aice->port->api->set_command_mode(command_mode); -} - -int aice_execute(struct aice_port_s *aice, uint32_t *instructions, - uint32_t instruction_num) -{ - if (aice->port->api->execute == NULL) { - LOG_WARNING("Not implemented: %s", __func__); - return ERROR_FAIL; - } - - return aice->port->api->execute(aice->coreid, instructions, instruction_num); -} - -int aice_set_custom_srst_script(struct aice_port_s *aice, const char *script) -{ - if (aice->port->api->set_custom_srst_script == NULL) { - LOG_WARNING("Not implemented: %s", __func__); - return ERROR_FAIL; - } - - return aice->port->api->set_custom_srst_script(script); -} - -int aice_set_custom_trst_script(struct aice_port_s *aice, const char *script) -{ - if (aice->port->api->set_custom_trst_script == NULL) { - LOG_WARNING("Not implemented: %s", __func__); - return ERROR_FAIL; - } - - return aice->port->api->set_custom_trst_script(script); -} - -int aice_set_custom_restart_script(struct aice_port_s *aice, const char *script) -{ - if (aice->port->api->set_custom_restart_script == NULL) { - LOG_WARNING("Not implemented: %s", __func__); - return ERROR_FAIL; - } - - return aice->port->api->set_custom_restart_script(script); -} - -int aice_set_count_to_check_dbger(struct aice_port_s *aice, uint32_t count_to_check) -{ - if (aice->port->api->set_count_to_check_dbger == NULL) { - LOG_WARNING("Not implemented: %s", __func__); - return ERROR_FAIL; - } - - return aice->port->api->set_count_to_check_dbger(count_to_check); -} - -int aice_profiling(struct aice_port_s *aice, uint32_t interval, uint32_t iteration, - uint32_t reg_no, uint32_t *samples, uint32_t *num_samples) -{ - if (aice->port->api->profiling == NULL) { - LOG_WARNING("Not implemented: %s", __func__); - return ERROR_FAIL; - } - - return aice->port->api->profiling(aice->coreid, interval, iteration, - reg_no, samples, num_samples); -} diff --git a/src/target/nds32_aice.h b/src/target/nds32_aice.h deleted file mode 100644 index ae801ed31..000000000 --- a/src/target/nds32_aice.h +++ /dev/null @@ -1,161 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2013 Andes technology. * - * Hsiangkai Wang * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 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_cache_ctl(struct aice_port_s *aice, uint32_t subtype, uint32_t address); -int aice_set_retry_times(struct aice_port_s *aice, uint32_t a_retry_times); -int aice_program_edm(struct aice_port_s *aice, char *command_sequence); -int aice_set_command_mode(struct aice_port_s *aice, - enum aice_command_mode command_mode); -int aice_execute(struct aice_port_s *aice, uint32_t *instructions, - uint32_t instruction_num); -int aice_set_custom_srst_script(struct aice_port_s *aice, const char *script); -int aice_set_custom_trst_script(struct aice_port_s *aice, const char *script); -int aice_set_custom_restart_script(struct aice_port_s *aice, const char *script); -int aice_set_count_to_check_dbger(struct aice_port_s *aice, uint32_t count_to_check); -int aice_profiling(struct aice_port_s *aice, uint32_t interval, uint32_t iteration, - uint32_t reg_no, uint32_t *samples, uint32_t *num_samples); - -static inline int aice_open(struct aice_port_s *aice, struct aice_port_param_s *param) -{ - return aice->port->api->open(param); -} - -static inline int aice_close(struct aice_port_s *aice) -{ - return aice->port->api->close(); -} - -static inline int aice_reset(struct aice_port_s *aice) -{ - return aice->port->api->reset(); -} - -static inline int aice_assert_srst(struct aice_port_s *aice, - enum aice_srst_type_s srst) -{ - return aice->port->api->assert_srst(aice->coreid, srst); -} - -static inline int aice_run(struct aice_port_s *aice) -{ - return aice->port->api->run(aice->coreid); -} - -static inline int aice_halt(struct aice_port_s *aice) -{ - return aice->port->api->halt(aice->coreid); -} - -static inline int aice_step(struct aice_port_s *aice) -{ - return aice->port->api->step(aice->coreid); -} - -static inline int aice_read_register(struct aice_port_s *aice, uint32_t num, - uint32_t *val) -{ - return aice->port->api->read_reg(aice->coreid, num, val); -} - -static inline int aice_write_register(struct aice_port_s *aice, uint32_t num, - uint32_t val) -{ - return aice->port->api->write_reg(aice->coreid, num, val); -} - -static inline int aice_read_debug_reg(struct aice_port_s *aice, uint32_t addr, - uint32_t *val) -{ - return aice->port->api->read_debug_reg(aice->coreid, addr, val); -} - -static inline int aice_write_debug_reg(struct aice_port_s *aice, uint32_t addr, - const uint32_t val) -{ - return aice->port->api->write_debug_reg(aice->coreid, addr, val); -} - -static inline int aice_read_mem_unit(struct aice_port_s *aice, uint32_t addr, - uint32_t size, uint32_t count, uint8_t *buffer) -{ - return aice->port->api->read_mem_unit(aice->coreid, addr, size, count, buffer); -} - -static inline int aice_write_mem_unit(struct aice_port_s *aice, uint32_t addr, - uint32_t size, uint32_t count, const uint8_t *buffer) -{ - return aice->port->api->write_mem_unit(aice->coreid, addr, size, count, buffer); -} - -static inline int aice_read_mem_bulk(struct aice_port_s *aice, uint32_t addr, - uint32_t length, uint8_t *buffer) -{ - return aice->port->api->read_mem_bulk(aice->coreid, addr, length, buffer); -} - -static inline int aice_write_mem_bulk(struct aice_port_s *aice, uint32_t addr, - uint32_t length, const uint8_t *buffer) -{ - return aice->port->api->write_mem_bulk(aice->coreid, addr, length, buffer); -} - -static inline int aice_idcode(struct aice_port_s *aice, uint32_t *idcode, - uint8_t *num_of_idcode) -{ - return aice->port->api->idcode(idcode, num_of_idcode); -} - -static inline int aice_state(struct aice_port_s *aice, - enum aice_target_state_s *state) -{ - return aice->port->api->state(aice->coreid, state); -} - -static inline int aice_set_jtag_clock(struct aice_port_s *aice, uint32_t a_clock) -{ - return aice->port->api->set_jtag_clock(a_clock); -} - -static inline int aice_memory_access(struct aice_port_s *aice, - enum nds_memory_access a_access) -{ - return aice->port->api->memory_access(aice->coreid, a_access); -} - -static inline int aice_memory_mode(struct aice_port_s *aice, - enum nds_memory_select mem_select) -{ - return aice->port->api->memory_mode(aice->coreid, mem_select); -} - -static inline int aice_set_data_endian(struct aice_port_s *aice, - enum aice_target_endian target_data_endian) -{ - return aice->port->api->set_data_endian(aice->coreid, target_data_endian); -} - -#endif /* OPENOCD_TARGET_NDS32_AICE_H */ diff --git a/src/target/nds32_cmd.c b/src/target/nds32_cmd.c deleted file mode 100644 index edb4872e4..000000000 --- a/src/target/nds32_cmd.c +++ /dev/null @@ -1,1126 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2013 Andes Technology * - * Hsiangkai Wang * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 -#include "config.h" -#endif - -#include -#include "nds32.h" -#include "nds32_aice.h" -#include "nds32_disassembler.h" - -extern struct nds32_edm_operation nds32_edm_ops[NDS32_EDM_OPERATION_MAX_NUM]; -extern uint32_t nds32_edm_ops_num; - -static const char *const NDS_MEMORY_ACCESS_NAME[] = { - "BUS", - "CPU", -}; - -static const char *const NDS_MEMORY_SELECT_NAME[] = { - "AUTO", - "MEM", - "ILM", - "DLM", -}; - -COMMAND_HANDLER(handle_nds32_dssim_command) -{ - struct target *target = get_current_target(CMD_CTX); - struct nds32 *nds32 = target_to_nds32(target); - - if (!is_nds32(nds32)) { - command_print(CMD_CTX, "current target isn't an Andes core"); - return ERROR_FAIL; - } - - if (CMD_ARGC > 0) { - if (strcmp(CMD_ARGV[0], "on") == 0) - nds32->step_isr_enable = true; - if (strcmp(CMD_ARGV[0], "off") == 0) - nds32->step_isr_enable = false; - } - - command_print(CMD_CTX, "%s: $INT_MASK.DSSIM: %d", target_name(target), - nds32->step_isr_enable); - - return ERROR_OK; -} - -COMMAND_HANDLER(handle_nds32_memory_access_command) -{ - struct target *target = get_current_target(CMD_CTX); - struct nds32 *nds32 = target_to_nds32(target); - struct aice_port_s *aice = target_to_aice(target); - struct nds32_memory *memory = &(nds32->memory); - - if (!is_nds32(nds32)) { - command_print(CMD_CTX, "current target isn't an Andes core"); - return ERROR_FAIL; - } - - if (CMD_ARGC > 0) { - if (strcmp(CMD_ARGV[0], "bus") == 0) - memory->access_channel = NDS_MEMORY_ACC_BUS; - else if (strcmp(CMD_ARGV[0], "cpu") == 0) - memory->access_channel = NDS_MEMORY_ACC_CPU; - else /* default access channel is NDS_MEMORY_ACC_CPU */ - memory->access_channel = NDS_MEMORY_ACC_CPU; - - LOG_DEBUG("memory access channel is changed to %s", - NDS_MEMORY_ACCESS_NAME[memory->access_channel]); - - aice_memory_access(aice, memory->access_channel); - } else { - command_print(CMD_CTX, "%s: memory access channel: %s", - target_name(target), - NDS_MEMORY_ACCESS_NAME[memory->access_channel]); - } - - return ERROR_OK; -} - -COMMAND_HANDLER(handle_nds32_memory_mode_command) -{ - struct target *target = get_current_target(CMD_CTX); - struct nds32 *nds32 = target_to_nds32(target); - struct aice_port_s *aice = target_to_aice(target); - - if (!is_nds32(nds32)) { - command_print(CMD_CTX, "current target isn't an Andes core"); - return ERROR_FAIL; - } - - if (CMD_ARGC > 0) { - - if (nds32->edm.access_control == false) { - command_print(CMD_CTX, "%s does not support ACC_CTL. " - "Set memory mode to MEMORY", target_name(target)); - nds32->memory.mode = NDS_MEMORY_SELECT_MEM; - } else if (nds32->edm.direct_access_local_memory == false) { - command_print(CMD_CTX, "%s does not support direct access " - "local memory. Set memory mode to MEMORY", - target_name(target)); - nds32->memory.mode = NDS_MEMORY_SELECT_MEM; - - /* set to ACC_CTL */ - aice_memory_mode(aice, nds32->memory.mode); - } else { - if (strcmp(CMD_ARGV[0], "auto") == 0) { - nds32->memory.mode = NDS_MEMORY_SELECT_AUTO; - } else if (strcmp(CMD_ARGV[0], "mem") == 0) { - nds32->memory.mode = NDS_MEMORY_SELECT_MEM; - } else if (strcmp(CMD_ARGV[0], "ilm") == 0) { - if (nds32->memory.ilm_base == 0) - command_print(CMD_CTX, "%s does not support ILM", - target_name(target)); - else - nds32->memory.mode = NDS_MEMORY_SELECT_ILM; - } else if (strcmp(CMD_ARGV[0], "dlm") == 0) { - if (nds32->memory.dlm_base == 0) - command_print(CMD_CTX, "%s does not support DLM", - target_name(target)); - else - nds32->memory.mode = NDS_MEMORY_SELECT_DLM; - } - - /* set to ACC_CTL */ - aice_memory_mode(aice, nds32->memory.mode); - } - } - - command_print(CMD_CTX, "%s: memory mode: %s", - target_name(target), - NDS_MEMORY_SELECT_NAME[nds32->memory.mode]); - - return ERROR_OK; -} - -COMMAND_HANDLER(handle_nds32_cache_command) -{ - struct target *target = get_current_target(CMD_CTX); - struct nds32 *nds32 = target_to_nds32(target); - struct aice_port_s *aice = target_to_aice(target); - struct nds32_cache *icache = &(nds32->memory.icache); - struct nds32_cache *dcache = &(nds32->memory.dcache); - int result; - - if (!is_nds32(nds32)) { - command_print(CMD_CTX, "current target isn't an Andes core"); - return ERROR_FAIL; - } - - if (CMD_ARGC > 0) { - - if (strcmp(CMD_ARGV[0], "invalidate") == 0) { - if ((dcache->line_size != 0) && (dcache->enable == true)) { - /* D$ write back */ - result = aice_cache_ctl(aice, AICE_CACHE_CTL_L1D_WBALL, 0); - if (result != ERROR_OK) { - command_print(CMD_CTX, "%s: Write back data cache...failed", - target_name(target)); - return result; - } - - command_print(CMD_CTX, "%s: Write back data cache...done", - target_name(target)); - - /* D$ invalidate */ - result = aice_cache_ctl(aice, AICE_CACHE_CTL_L1D_INVALALL, 0); - if (result != ERROR_OK) { - command_print(CMD_CTX, "%s: Invalidate data cache...failed", - target_name(target)); - return result; - } - - command_print(CMD_CTX, "%s: Invalidate data cache...done", - target_name(target)); - } else { - if (dcache->line_size == 0) - command_print(CMD_CTX, "%s: No data cache", - target_name(target)); - else - command_print(CMD_CTX, "%s: Data cache disabled", - target_name(target)); - } - - if ((icache->line_size != 0) && (icache->enable == true)) { - /* I$ invalidate */ - result = aice_cache_ctl(aice, AICE_CACHE_CTL_L1I_INVALALL, 0); - if (result != ERROR_OK) { - command_print(CMD_CTX, "%s: Invalidate instruction cache...failed", - target_name(target)); - return result; - } - - command_print(CMD_CTX, "%s: Invalidate instruction cache...done", - target_name(target)); - } else { - if (icache->line_size == 0) - command_print(CMD_CTX, "%s: No instruction cache", - target_name(target)); - else - command_print(CMD_CTX, "%s: Instruction cache disabled", - target_name(target)); - } - } else - command_print(CMD_CTX, "No valid parameter"); - } - - return ERROR_OK; -} - -COMMAND_HANDLER(handle_nds32_icache_command) -{ - struct target *target = get_current_target(CMD_CTX); - struct nds32 *nds32 = target_to_nds32(target); - struct aice_port_s *aice = target_to_aice(target); - struct nds32_cache *icache = &(nds32->memory.icache); - int result; - - if (!is_nds32(nds32)) { - command_print(CMD_CTX, "current target isn't an Andes core"); - return ERROR_FAIL; - } - - if (CMD_ARGC > 0) { - - if (icache->line_size == 0) { - command_print(CMD_CTX, "%s: No instruction cache", - target_name(target)); - return ERROR_OK; - } - - if (strcmp(CMD_ARGV[0], "invalidate") == 0) { - if (icache->enable == true) { - /* I$ invalidate */ - result = aice_cache_ctl(aice, AICE_CACHE_CTL_L1I_INVALALL, 0); - if (result != ERROR_OK) { - command_print(CMD_CTX, "%s: Invalidate instruction cache...failed", - target_name(target)); - return result; - } - - command_print(CMD_CTX, "%s: Invalidate instruction cache...done", - target_name(target)); - } else { - command_print(CMD_CTX, "%s: Instruction cache disabled", - target_name(target)); - } - } else if (strcmp(CMD_ARGV[0], "enable") == 0) { - uint32_t value; - nds32_get_mapped_reg(nds32, IR8, &value); - nds32_set_mapped_reg(nds32, IR8, value | 0x1); - } else if (strcmp(CMD_ARGV[0], "disable") == 0) { - uint32_t value; - nds32_get_mapped_reg(nds32, IR8, &value); - nds32_set_mapped_reg(nds32, IR8, value & ~0x1); - } else if (strcmp(CMD_ARGV[0], "dump") == 0) { - /* TODO: dump cache content */ - } else { - command_print(CMD_CTX, "%s: No valid parameter", target_name(target)); - } - } - - return ERROR_OK; -} - -COMMAND_HANDLER(handle_nds32_dcache_command) -{ - struct target *target = get_current_target(CMD_CTX); - struct nds32 *nds32 = target_to_nds32(target); - struct aice_port_s *aice = target_to_aice(target); - struct nds32_cache *dcache = &(nds32->memory.dcache); - int result; - - if (!is_nds32(nds32)) { - command_print(CMD_CTX, "current target isn't an Andes core"); - return ERROR_FAIL; - } - - if (CMD_ARGC > 0) { - - if (dcache->line_size == 0) { - command_print(CMD_CTX, "%s: No data cache", target_name(target)); - return ERROR_OK; - } - - if (strcmp(CMD_ARGV[0], "invalidate") == 0) { - if (dcache->enable == true) { - /* D$ write back */ - result = aice_cache_ctl(aice, AICE_CACHE_CTL_L1D_WBALL, 0); - if (result != ERROR_OK) { - command_print(CMD_CTX, "%s: Write back data cache...failed", - target_name(target)); - return result; - } - - command_print(CMD_CTX, "%s: Write back data cache...done", - target_name(target)); - - /* D$ invalidate */ - result = aice_cache_ctl(aice, AICE_CACHE_CTL_L1D_INVALALL, 0); - if (result != ERROR_OK) { - command_print(CMD_CTX, "%s: Invalidate data cache...failed", - target_name(target)); - return result; - } - - command_print(CMD_CTX, "%s: Invalidate data cache...done", - target_name(target)); - } else { - command_print(CMD_CTX, "%s: Data cache disabled", - target_name(target)); - } - } else if (strcmp(CMD_ARGV[0], "enable") == 0) { - uint32_t value; - nds32_get_mapped_reg(nds32, IR8, &value); - nds32_set_mapped_reg(nds32, IR8, value | 0x2); - } else if (strcmp(CMD_ARGV[0], "disable") == 0) { - uint32_t value; - nds32_get_mapped_reg(nds32, IR8, &value); - nds32_set_mapped_reg(nds32, IR8, value & ~0x2); - } else if (strcmp(CMD_ARGV[0], "dump") == 0) { - /* TODO: dump cache content */ - } else { - command_print(CMD_CTX, "%s: No valid parameter", target_name(target)); - } - } - - return ERROR_OK; -} - -COMMAND_HANDLER(handle_nds32_auto_break_command) -{ - struct target *target = get_current_target(CMD_CTX); - struct nds32 *nds32 = target_to_nds32(target); - - if (!is_nds32(nds32)) { - command_print(CMD_CTX, "current target isn't an Andes core"); - return ERROR_FAIL; - } - - if (CMD_ARGC > 0) { - if (strcmp(CMD_ARGV[0], "on") == 0) - nds32->auto_convert_hw_bp = true; - if (strcmp(CMD_ARGV[0], "off") == 0) - nds32->auto_convert_hw_bp = false; - } - - if (nds32->auto_convert_hw_bp) - command_print(CMD_CTX, "%s: convert sw break to hw break on ROM: on", - target_name(target)); - else - command_print(CMD_CTX, "%s: convert sw break to hw break on ROM: off", - target_name(target)); - - return ERROR_OK; -} - -COMMAND_HANDLER(handle_nds32_virtual_hosting_command) -{ - struct target *target = get_current_target(CMD_CTX); - struct nds32 *nds32 = target_to_nds32(target); - - if (!is_nds32(nds32)) { - command_print(CMD_CTX, "current target isn't an Andes core"); - return ERROR_FAIL; - } - - if (CMD_ARGC > 0) { - if (strcmp(CMD_ARGV[0], "on") == 0) - nds32->virtual_hosting = true; - if (strcmp(CMD_ARGV[0], "off") == 0) - nds32->virtual_hosting = false; - } - - if (nds32->virtual_hosting) - command_print(CMD_CTX, "%s: virtual hosting: on", target_name(target)); - else - command_print(CMD_CTX, "%s: virtual hosting: off", target_name(target)); - - return ERROR_OK; -} - -COMMAND_HANDLER(handle_nds32_global_stop_command) -{ - struct target *target = get_current_target(CMD_CTX); - struct nds32 *nds32 = target_to_nds32(target); - - if (!is_nds32(nds32)) { - command_print(CMD_CTX, "current target isn't an Andes core"); - return ERROR_FAIL; - } - - if (CMD_ARGC > 0) { - if (strcmp(CMD_ARGV[0], "on") == 0) - nds32->global_stop = true; - if (strcmp(CMD_ARGV[0], "off") == 0) - nds32->global_stop = false; - } - - if (nds32->global_stop) - LOG_INFO("%s: global stop: on", target_name(target)); - else - LOG_INFO("%s: global stop: off", target_name(target)); - - return ERROR_OK; -} - -COMMAND_HANDLER(handle_nds32_soft_reset_halt_command) -{ - struct target *target = get_current_target(CMD_CTX); - struct nds32 *nds32 = target_to_nds32(target); - - if (!is_nds32(nds32)) { - command_print(CMD_CTX, "current target isn't an Andes core"); - return ERROR_FAIL; - } - - if (CMD_ARGC > 0) { - if (strcmp(CMD_ARGV[0], "on") == 0) - nds32->soft_reset_halt = true; - if (strcmp(CMD_ARGV[0], "off") == 0) - nds32->soft_reset_halt = false; - } - - if (nds32->soft_reset_halt) - LOG_INFO("%s: soft-reset-halt: on", target_name(target)); - else - LOG_INFO("%s: soft-reset-halt: off", target_name(target)); - - return ERROR_OK; -} - -COMMAND_HANDLER(handle_nds32_boot_time_command) -{ - struct target *target = get_current_target(CMD_CTX); - struct nds32 *nds32 = target_to_nds32(target); - - if (!is_nds32(nds32)) { - command_print(CMD_CTX, "current target isn't an Andes core"); - return ERROR_FAIL; - } - - if (CMD_ARGC > 0) - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], nds32->boot_time); - - return ERROR_OK; -} - -COMMAND_HANDLER(handle_nds32_login_edm_passcode_command) -{ - struct target *target = get_current_target(CMD_CTX); - struct nds32 *nds32 = target_to_nds32(target); - - if (!is_nds32(nds32)) { - command_print(CMD_CTX, "current target isn't an Andes core"); - return ERROR_FAIL; - } - - nds32->edm_passcode = strdup(CMD_ARGV[0]); - - return ERROR_OK; -} - -COMMAND_HANDLER(handle_nds32_login_edm_operation_command) -{ - struct target *target = get_current_target(CMD_CTX); - struct nds32 *nds32 = target_to_nds32(target); - - if (!is_nds32(nds32)) { - command_print(CMD_CTX, "current target isn't an Andes core"); - return ERROR_FAIL; - } - - if (CMD_ARGC > 1) { - - uint32_t misc_reg_no; - uint32_t data; - - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], misc_reg_no); - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], data); - - if (nds32_edm_ops_num >= NDS32_EDM_OPERATION_MAX_NUM) - return ERROR_FAIL; - - /* Just save the operation. Execute it in nds32_login() */ - nds32_edm_ops[nds32_edm_ops_num].reg_no = misc_reg_no; - nds32_edm_ops[nds32_edm_ops_num].value = data; - nds32_edm_ops_num++; - } else - return ERROR_FAIL; - - return ERROR_OK; -} - -COMMAND_HANDLER(handle_nds32_reset_halt_as_init_command) -{ - struct target *target = get_current_target(CMD_CTX); - struct nds32 *nds32 = target_to_nds32(target); - - if (!is_nds32(nds32)) { - command_print(CMD_CTX, "current target isn't an Andes core"); - return ERROR_FAIL; - } - - if (CMD_ARGC > 0) { - if (strcmp(CMD_ARGV[0], "on") == 0) - nds32->reset_halt_as_examine = true; - if (strcmp(CMD_ARGV[0], "off") == 0) - nds32->reset_halt_as_examine = false; - } - - return ERROR_OK; -} - -COMMAND_HANDLER(handle_nds32_keep_target_edm_ctl_command) -{ - struct target *target = get_current_target(CMD_CTX); - struct nds32 *nds32 = target_to_nds32(target); - - if (!is_nds32(nds32)) { - command_print(CMD_CTX, "current target isn't an Andes core"); - return ERROR_FAIL; - } - - if (CMD_ARGC > 0) { - if (strcmp(CMD_ARGV[0], "on") == 0) - nds32->keep_target_edm_ctl = true; - if (strcmp(CMD_ARGV[0], "off") == 0) - nds32->keep_target_edm_ctl = false; - } - - return ERROR_OK; -} - -COMMAND_HANDLER(handle_nds32_decode_command) -{ - struct target *target = get_current_target(CMD_CTX); - struct nds32 *nds32 = target_to_nds32(target); - - if (!is_nds32(nds32)) { - command_print(CMD_CTX, "current target isn't an Andes core"); - return ERROR_FAIL; - } - - if (CMD_ARGC > 1) { - - uint32_t addr; - uint32_t insn_count; - uint32_t opcode; - uint32_t read_addr; - uint32_t i; - struct nds32_instruction instruction; - - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], addr); - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], insn_count); - - read_addr = addr; - i = 0; - while (i < insn_count) { - if (ERROR_OK != nds32_read_opcode(nds32, read_addr, &opcode)) - return ERROR_FAIL; - if (ERROR_OK != nds32_evaluate_opcode(nds32, opcode, - read_addr, &instruction)) - return ERROR_FAIL; - - command_print(CMD_CTX, "%s", instruction.text); - - read_addr += instruction.instruction_size; - i++; - } - } else if (CMD_ARGC == 1) { - - uint32_t addr; - uint32_t opcode; - struct nds32_instruction instruction; - - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], addr); - - if (ERROR_OK != nds32_read_opcode(nds32, addr, &opcode)) - return ERROR_FAIL; - if (ERROR_OK != nds32_evaluate_opcode(nds32, opcode, addr, &instruction)) - return ERROR_FAIL; - - command_print(CMD_CTX, "%s", instruction.text); - } else - return ERROR_FAIL; - - return ERROR_OK; -} - -COMMAND_HANDLER(handle_nds32_word_access_mem_command) -{ - struct target *target = get_current_target(CMD_CTX); - struct nds32 *nds32 = target_to_nds32(target); - - if (!is_nds32(nds32)) { - command_print(CMD_CTX, "current target isn't an Andes core"); - return ERROR_FAIL; - } - - if (CMD_ARGC > 0) { - if (strcmp(CMD_ARGV[0], "on") == 0) - nds32->word_access_mem = true; - if (strcmp(CMD_ARGV[0], "off") == 0) - nds32->word_access_mem = false; - } - - return ERROR_OK; -} - -COMMAND_HANDLER(handle_nds32_query_target_command) -{ - struct target *target = get_current_target(CMD_CTX); - struct nds32 *nds32 = target_to_nds32(target); - - if (!is_nds32(nds32)) { - command_print(CMD_CTX, "current target isn't an Andes core"); - return ERROR_FAIL; - } - - command_print(CMD_CTX, "OCD"); - - return ERROR_OK; -} - -COMMAND_HANDLER(handle_nds32_query_endian_command) -{ - struct target *target = get_current_target(CMD_CTX); - struct nds32 *nds32 = target_to_nds32(target); - - if (!is_nds32(nds32)) { - command_print(CMD_CTX, "current target isn't an Andes core"); - return ERROR_FAIL; - } - - uint32_t value_psw; - nds32_get_mapped_reg(nds32, IR0, &value_psw); - - if (value_psw & 0x20) - command_print(CMD_CTX, "%s: BE", target_name(target)); - else - command_print(CMD_CTX, "%s: LE", target_name(target)); - - return ERROR_OK; -} - -COMMAND_HANDLER(handle_nds32_query_cpuid_command) -{ - struct target *target = get_current_target(CMD_CTX); - struct nds32 *nds32 = target_to_nds32(target); - - if (!is_nds32(nds32)) { - command_print(CMD_CTX, "current target isn't an Andes core"); - return ERROR_FAIL; - } - - command_print(CMD_CTX, "CPUID: %s", target_name(target)); - - return ERROR_OK; -} - -static int jim_nds32_bulk_write(Jim_Interp *interp, int argc, Jim_Obj * const *argv) -{ - const char *cmd_name = Jim_GetString(argv[0], NULL); - - Jim_GetOptInfo goi; - Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1); - - if (goi.argc < 3) { - Jim_SetResultFormatted(goi.interp, - "usage: %s
", cmd_name); - return JIM_ERR; - } - - int e; - jim_wide address; - e = Jim_GetOpt_Wide(&goi, &address); - if (e != JIM_OK) - return e; - - jim_wide count; - e = Jim_GetOpt_Wide(&goi, &count); - if (e != JIM_OK) - return e; - - uint32_t *data = malloc(count * sizeof(uint32_t)); - if (data == NULL) - return JIM_ERR; - - jim_wide i; - for (i = 0; i < count; i++) { - jim_wide tmp; - e = Jim_GetOpt_Wide(&goi, &tmp); - if (e != JIM_OK) { - free(data); - return e; - } - data[i] = (uint32_t)tmp; - } - - /* all args must be consumed */ - if (goi.argc != 0) { - free(data); - return JIM_ERR; - } - - struct target *target = Jim_CmdPrivData(goi.interp); - int result; - - result = target_write_buffer(target, address, count * 4, (const uint8_t *)data); - - free(data); - - return result; -} - -static int jim_nds32_multi_write(Jim_Interp *interp, int argc, Jim_Obj * const *argv) -{ - const char *cmd_name = Jim_GetString(argv[0], NULL); - - Jim_GetOptInfo goi; - Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1); - - if (goi.argc < 3) { - Jim_SetResultFormatted(goi.interp, - "usage: %s # of pairs [
]+", cmd_name); - return JIM_ERR; - } - - int e; - jim_wide num_of_pairs; - e = Jim_GetOpt_Wide(&goi, &num_of_pairs); - if (e != JIM_OK) - return e; - - struct target *target = Jim_CmdPrivData(goi.interp); - struct aice_port_s *aice = target_to_aice(target); - int result; - uint32_t address; - uint32_t data; - jim_wide i; - - aice_set_command_mode(aice, AICE_COMMAND_MODE_PACK); - for (i = 0; i < num_of_pairs; i++) { - jim_wide tmp; - e = Jim_GetOpt_Wide(&goi, &tmp); - if (e != JIM_OK) - break; - address = (uint32_t)tmp; - - e = Jim_GetOpt_Wide(&goi, &tmp); - if (e != JIM_OK) - break; - data = (uint32_t)tmp; - - result = target_write_buffer(target, address, 4, (const uint8_t *)&data); - if (result != ERROR_OK) - break; - } - aice_set_command_mode(aice, AICE_COMMAND_MODE_NORMAL); - - /* all args must be consumed */ - if (goi.argc != 0) - return JIM_ERR; - - return ERROR_OK; -} - -static int jim_nds32_bulk_read(Jim_Interp *interp, int argc, Jim_Obj * const *argv) -{ - const char *cmd_name = Jim_GetString(argv[0], NULL); - - Jim_GetOptInfo goi; - Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1); - - if (goi.argc < 2) { - Jim_SetResultFormatted(goi.interp, - "usage: %s
", cmd_name); - return JIM_ERR; - } - - int e; - jim_wide address; - e = Jim_GetOpt_Wide(&goi, &address); - if (e != JIM_OK) - return e; - - jim_wide count; - e = Jim_GetOpt_Wide(&goi, &count); - if (e != JIM_OK) - return e; - - /* all args must be consumed */ - if (goi.argc != 0) - return JIM_ERR; - - struct target *target = Jim_CmdPrivData(goi.interp); - uint32_t *data = malloc(count * sizeof(uint32_t)); - int result; - result = target_read_buffer(target, address, count * 4, (uint8_t *)data); - char data_str[11]; - - jim_wide i; - Jim_SetResult(interp, Jim_NewEmptyStringObj(interp)); - for (i = 0; i < count; i++) { - sprintf(data_str, "0x%08" PRIx32 " ", data[i]); - Jim_AppendStrings(interp, Jim_GetResult(interp), data_str, NULL); - } - - free(data); - - return result; -} - -static int jim_nds32_read_edm_sr(Jim_Interp *interp, int argc, Jim_Obj * const *argv) -{ - const char *cmd_name = Jim_GetString(argv[0], NULL); - - Jim_GetOptInfo goi; - Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1); - - if (goi.argc < 1) { - Jim_SetResultFormatted(goi.interp, - "usage: %s ", cmd_name); - return JIM_ERR; - } - - int e; - const char *edm_sr_name; - int edm_sr_name_len; - e = Jim_GetOpt_String(&goi, &edm_sr_name, &edm_sr_name_len); - if (e != JIM_OK) - return e; - - /* all args must be consumed */ - if (goi.argc != 0) - return JIM_ERR; - - uint32_t edm_sr_number; - uint32_t edm_sr_value; - if (strncmp(edm_sr_name, "edm_dtr", edm_sr_name_len) == 0) - edm_sr_number = NDS_EDM_SR_EDM_DTR; - else if (strncmp(edm_sr_name, "edmsw", edm_sr_name_len) == 0) - edm_sr_number = NDS_EDM_SR_EDMSW; - else - return ERROR_FAIL; - - struct target *target = Jim_CmdPrivData(goi.interp); - struct aice_port_s *aice = target_to_aice(target); - char data_str[11]; - - aice_read_debug_reg(aice, edm_sr_number, &edm_sr_value); - - sprintf(data_str, "0x%08" PRIx32, edm_sr_value); - Jim_SetResult(interp, Jim_NewEmptyStringObj(interp)); - Jim_AppendStrings(interp, Jim_GetResult(interp), data_str, NULL); - - return ERROR_OK; -} - -static int jim_nds32_write_edm_sr(Jim_Interp *interp, int argc, Jim_Obj * const *argv) -{ - const char *cmd_name = Jim_GetString(argv[0], NULL); - - Jim_GetOptInfo goi; - Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1); - - if (goi.argc < 2) { - Jim_SetResultFormatted(goi.interp, - "usage: %s ", cmd_name); - return JIM_ERR; - } - - int e; - const char *edm_sr_name; - int edm_sr_name_len; - e = Jim_GetOpt_String(&goi, &edm_sr_name, &edm_sr_name_len); - if (e != JIM_OK) - return e; - - jim_wide value; - e = Jim_GetOpt_Wide(&goi, &value); - if (e != JIM_OK) - return e; - - /* all args must be consumed */ - if (goi.argc != 0) - return JIM_ERR; - - uint32_t edm_sr_number; - if (strncmp(edm_sr_name, "edm_dtr", edm_sr_name_len) == 0) - edm_sr_number = NDS_EDM_SR_EDM_DTR; - else - return ERROR_FAIL; - - struct target *target = Jim_CmdPrivData(goi.interp); - struct aice_port_s *aice = target_to_aice(target); - - aice_write_debug_reg(aice, edm_sr_number, value); - - return ERROR_OK; -} - -static const struct command_registration nds32_query_command_handlers[] = { - { - .name = "target", - .handler = handle_nds32_query_target_command, - .mode = COMMAND_EXEC, - .usage = "", - .help = "reply 'OCD' for gdb to identify server-side is OpenOCD", - }, - { - .name = "endian", - .handler = handle_nds32_query_endian_command, - .mode = COMMAND_EXEC, - .usage = "", - .help = "query target endian", - }, - { - .name = "cpuid", - .handler = handle_nds32_query_cpuid_command, - .mode = COMMAND_EXEC, - .usage = "", - .help = "query CPU ID", - }, - - COMMAND_REGISTRATION_DONE -}; - -static const struct command_registration nds32_exec_command_handlers[] = { - { - .name = "dssim", - .handler = handle_nds32_dssim_command, - .mode = COMMAND_EXEC, - .usage = "['on'|'off']", - .help = "display/change $INT_MASK.DSSIM status", - }, - { - .name = "mem_access", - .handler = handle_nds32_memory_access_command, - .mode = COMMAND_EXEC, - .usage = "['bus'|'cpu']", - .help = "display/change memory access channel", - }, - { - .name = "mem_mode", - .handler = handle_nds32_memory_mode_command, - .mode = COMMAND_EXEC, - .usage = "['auto'|'mem'|'ilm'|'dlm']", - .help = "display/change memory mode", - }, - { - .name = "cache", - .handler = handle_nds32_cache_command, - .mode = COMMAND_EXEC, - .usage = "['invalidate']", - .help = "cache control", - }, - { - .name = "icache", - .handler = handle_nds32_icache_command, - .mode = COMMAND_EXEC, - .usage = "['invalidate'|'enable'|'disable'|'dump']", - .help = "icache control", - }, - { - .name = "dcache", - .handler = handle_nds32_dcache_command, - .mode = COMMAND_EXEC, - .usage = "['invalidate'|'enable'|'disable'|'dump']", - .help = "dcache control", - }, - { - .name = "auto_break", - .handler = handle_nds32_auto_break_command, - .mode = COMMAND_EXEC, - .usage = "['on'|'off']", - .help = "convert software breakpoints to hardware breakpoints if needed", - }, - { - .name = "virtual_hosting", - .handler = handle_nds32_virtual_hosting_command, - .mode = COMMAND_ANY, - .usage = "['on'|'off']", - .help = "turn on/off virtual hosting", - }, - { - .name = "global_stop", - .handler = handle_nds32_global_stop_command, - .mode = COMMAND_ANY, - .usage = "['on'|'off']", - .help = "turn on/off global stop. After turning on, every load/store" \ - "instructions will be stopped to check memory access.", - }, - { - .name = "soft_reset_halt", - .handler = handle_nds32_soft_reset_halt_command, - .mode = COMMAND_ANY, - .usage = "['on'|'off']", - .help = "as issuing rest-halt, to use soft-reset-halt or not." \ - "the feature is for backward-compatible.", - }, - { - .name = "boot_time", - .handler = handle_nds32_boot_time_command, - .mode = COMMAND_CONFIG, - .usage = "milliseconds", - .help = "set the period to wait after srst.", - }, - { - .name = "login_edm_passcode", - .handler = handle_nds32_login_edm_passcode_command, - .mode = COMMAND_CONFIG, - .usage = "passcode", - .help = "set EDM passcode for secure MCU debugging.", - }, - { - .name = "login_edm_operation", - .handler = handle_nds32_login_edm_operation_command, - .mode = COMMAND_CONFIG, - .usage = "login_edm_operation misc_reg_no value", - .help = "add EDM operations for secure MCU debugging.", - }, - { - .name = "reset_halt_as_init", - .handler = handle_nds32_reset_halt_as_init_command, - .mode = COMMAND_CONFIG, - .usage = "['on'|'off']", - .help = "reset halt as openocd init.", - }, - { - .name = "keep_target_edm_ctl", - .handler = handle_nds32_keep_target_edm_ctl_command, - .mode = COMMAND_CONFIG, - .usage = "['on'|'off']", - .help = "Backup/Restore target EDM_CTL register.", - }, - { - .name = "decode", - .handler = handle_nds32_decode_command, - .mode = COMMAND_EXEC, - .usage = "address icount", - .help = "decode instruction.", - }, - { - .name = "word_access_mem", - .handler = handle_nds32_word_access_mem_command, - .mode = COMMAND_ANY, - .usage = "['on'|'off']", - .help = "Always use word-aligned address to access memory.", - }, - { - .name = "bulk_write", - .jim_handler = jim_nds32_bulk_write, - .mode = COMMAND_EXEC, - .help = "Write multiple 32-bit words to target memory", - .usage = "address count data", - }, - { - .name = "multi_write", - .jim_handler = jim_nds32_multi_write, - .mode = COMMAND_EXEC, - .help = "Write multiple addresses/words to target memory", - .usage = "num_of_pairs [address data]+", - }, - { - .name = "bulk_read", - .jim_handler = jim_nds32_bulk_read, - .mode = COMMAND_EXEC, - .help = "Read multiple 32-bit words from target memory", - .usage = "address count", - }, - { - .name = "read_edmsr", - .jim_handler = jim_nds32_read_edm_sr, - .mode = COMMAND_EXEC, - .help = "Read EDM system register", - .usage = "['edmsw'|'edm_dtr']", - }, - { - .name = "write_edmsr", - .jim_handler = jim_nds32_write_edm_sr, - .mode = COMMAND_EXEC, - .help = "Write EDM system register", - .usage = "['edm_dtr'] value", - }, - { - .name = "query", - .mode = COMMAND_EXEC, - .help = "Andes query command group", - .usage = "", - .chain = nds32_query_command_handlers, - }, - - COMMAND_REGISTRATION_DONE -}; - -const struct command_registration nds32_command_handlers[] = { - { - .name = "nds", - .mode = COMMAND_ANY, - .help = "Andes command group", - .usage = "", - .chain = nds32_exec_command_handlers, - }, - COMMAND_REGISTRATION_DONE -}; - diff --git a/src/target/nds32_cmd.h b/src/target/nds32_cmd.h deleted file mode 100644 index 543ba54c6..000000000 --- a/src/target/nds32_cmd.h +++ /dev/null @@ -1,26 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2013 Andes Technology * - * Hsiangkai Wang * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 OPENOCD_TARGET_NDS32_CMD_H -#define OPENOCD_TARGET_NDS32_CMD_H - -#include - -extern const struct command_registration nds32_command_handlers[]; - -#endif /* OPENOCD_TARGET_NDS32_CMD_H */ diff --git a/src/target/nds32_disassembler.c b/src/target/nds32_disassembler.c deleted file mode 100644 index f27aba2cc..000000000 --- a/src/target/nds32_disassembler.c +++ /dev/null @@ -1,3858 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2013 Andes Technology * - * Hsiangkai Wang * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 -#include "config.h" -#endif - -#include -#include -#include "nds32_disassembler.h" - -static const int enable4_bits[] = {0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4}; - -int nds32_read_opcode(struct nds32 *nds32, uint32_t address, uint32_t *value) -{ - struct target *target = nds32->target; - uint8_t value_buf[4]; - - if (!target_was_examined(target)) { - LOG_ERROR("Target not examined yet"); - return ERROR_FAIL; - } - - int retval = target_read_buffer(target, address, 4, value_buf); - - if (retval == ERROR_OK) { - /* instructions are always big-endian */ - *value = be_to_h_u32(value_buf); - - LOG_DEBUG("address: 0x%8.8" PRIx32 ", value: 0x%8.8" PRIx32 "", - address, - *value); - } else { - *value = 0x0; - LOG_DEBUG("address: 0x%8.8" PRIx32 " failed", - address); - } - - return retval; -} - -static int nds32_parse_type_0(uint32_t opcode, int32_t *imm) -{ - *imm = opcode & 0x1FFFFFF; - - return ERROR_OK; -} - -static int nds32_parse_type_1(uint32_t opcode, uint8_t *rt, int32_t *imm) -{ - *rt = (opcode >> 20) & 0x1F; - *imm = opcode & 0xFFFFF; - - return ERROR_OK; -} - -static int nds32_parse_type_2(uint32_t opcode, uint8_t *rt, uint8_t *ra, int32_t *imm) -{ - *rt = (opcode >> 20) & 0x1F; - *ra = (opcode >> 15) & 0x1F; - *imm = opcode & 0x7FFF; - - return ERROR_OK; -} - -static int nds32_parse_type_3(uint32_t opcode, uint8_t *rt, uint8_t *ra, - uint8_t *rb, int32_t *imm) -{ - *rt = (opcode >> 20) & 0x1F; - *ra = (opcode >> 15) & 0x1F; - *rb = (opcode >> 10) & 0x1F; - *imm = opcode & 0x3FF; - - return ERROR_OK; -} - -static int nds32_parse_type_4(uint32_t opcode, uint8_t *rt, uint8_t *ra, - uint8_t *rb, uint8_t *rd, uint8_t *sub_opc) -{ - *rt = (opcode >> 20) & 0x1F; - *ra = (opcode >> 15) & 0x1F; - *rb = (opcode >> 10) & 0x1F; - *rd = (opcode >> 5) & 0x1F; - *sub_opc = opcode & 0x1F; - - return ERROR_OK; -} - -/* LBI, LHI, LWI, LBI.bi, LHI.bi, LWI.bi */ -static int nds32_parse_group_0_insn(struct nds32 *nds32, uint32_t opcode, - uint32_t address, - struct nds32_instruction *instruction) -{ - uint8_t opc_6; - - opc_6 = instruction->info.opc_6; - - switch (opc_6 & 0x7) { - case 0: /* LBI */ - nds32_parse_type_2(opcode, &(instruction->info.rt), - &(instruction->info.ra), &(instruction->info.imm)); - instruction->info.imm = (instruction->info.imm << 17) >> 17; /* sign-extend */ - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, instruction->info.ra, - &(instruction->access_start)); - instruction->access_start += instruction->info.imm; - instruction->access_end = instruction->access_start + 1; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tLBI\t$r%" PRIu8 ",[$r%" PRIu8 "+#%" PRId32 "]", - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.imm); - break; - case 1: /* LHI */ - nds32_parse_type_2(opcode, &(instruction->info.rt), - &(instruction->info.ra), &(instruction->info.imm)); - instruction->info.imm = (instruction->info.imm << 17) >> 16; /* sign-extend */ - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, instruction->info.ra, - &(instruction->access_start)); - instruction->access_start += instruction->info.imm; - instruction->access_end = instruction->access_start + 2; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tLHI\t$r%" PRIu8 ",[$r%" PRIu8 "+#%" PRId32 "]", - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.imm); - break; - case 2: /* LWI */ - nds32_parse_type_2(opcode, &(instruction->info.rt), - &(instruction->info.ra), &(instruction->info.imm)); - instruction->info.imm = (instruction->info.imm << 17) >> 15; /* sign-extend */ - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, instruction->info.ra, - &(instruction->access_start)); - instruction->access_start += instruction->info.imm; - instruction->access_end = instruction->access_start + 4; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tLWI\t$r%" PRIu8 ",[$r%" PRIu8 "+#%" PRId32 "]", - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.imm); - break; - case 4: /* LBI.bi */ - nds32_parse_type_2(opcode, &(instruction->info.rt), - &(instruction->info.ra), &(instruction->info.imm)); - instruction->info.imm = (instruction->info.imm << 17) >> 17; /* sign-extend */ - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, instruction->info.ra, - &(instruction->access_start)); - instruction->access_end = instruction->access_start + 1; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tLBI.bi\t$r%" PRIu8 ",[$r%" PRIu8 "],#%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.imm); - break; - case 5: /* LHI.bi */ - nds32_parse_type_2(opcode, &(instruction->info.rt), - &(instruction->info.ra), &(instruction->info.imm)); - instruction->info.imm = (instruction->info.imm << 17) >> 16; /* sign-extend */ - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, instruction->info.ra, - &(instruction->access_start)); - instruction->access_end = instruction->access_start + 2; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tLHI.bi\t$r%" PRIu8 ",[$r%" PRIu8 "],#%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.imm); - break; - case 6: /* LWI.bi */ - nds32_parse_type_2(opcode, &(instruction->info.rt), - &(instruction->info.ra), &(instruction->info.imm)); - instruction->info.imm = (instruction->info.imm << 17) >> 15; /* sign-extend */ - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, instruction->info.ra, - &(instruction->access_start)); - instruction->access_end = instruction->access_start + 4; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tLWI.bi\t$r%" PRIu8 ",[$r%" PRIu8 "],#%" PRId32 "", - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.imm); - break; - default: - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION", - address, - opcode); - return ERROR_FAIL; - } - - return ERROR_OK; -} - -static int nds32_parse_group_1_insn(struct nds32 *nds32, uint32_t opcode, - uint32_t address, struct nds32_instruction *instruction) -{ - uint8_t opc_6; - - opc_6 = instruction->info.opc_6; - - switch (opc_6 & 0x7) { - case 0: /* SBI */ - nds32_parse_type_2(opcode, &(instruction->info.rt), - &(instruction->info.ra), &(instruction->info.imm)); - instruction->info.imm = (instruction->info.imm << 17) >> 17; /* sign-extend */ - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, instruction->info.ra, - &(instruction->access_start)); - instruction->access_start += instruction->info.imm; - instruction->access_end = instruction->access_start + 1; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tSBI\t$r%" PRIu8 ",[$r%" PRIu8 "+#%" PRId32 "]", - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.imm); - break; - case 1: /* SHI */ - nds32_parse_type_2(opcode, &(instruction->info.rt), - &(instruction->info.ra), &(instruction->info.imm)); - instruction->info.imm = (instruction->info.imm << 17) >> 16; /* sign-extend */ - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, instruction->info.ra, - &(instruction->access_start)); - instruction->access_start += instruction->info.imm; - instruction->access_end = instruction->access_start + 2; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tSHI\t$r%" PRIu8 ",[$r%" PRIu8 "+#%" PRId32 "]", - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.imm); - break; - case 2: /* SWI */ - nds32_parse_type_2(opcode, &(instruction->info.rt), - &(instruction->info.ra), &(instruction->info.imm)); - instruction->info.imm = (instruction->info.imm << 17) >> 15; /* sign-extend */ - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, instruction->info.ra, - &(instruction->access_start)); - instruction->access_start += instruction->info.imm; - instruction->access_end = instruction->access_start + 4; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tSWI\t$r%" PRIu8 ",[$r%" PRIu8 "+#%" PRId32 "]", - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.imm); - break; - case 4: /* SBI.bi */ - nds32_parse_type_2(opcode, &(instruction->info.rt), - &(instruction->info.ra), &(instruction->info.imm)); - instruction->info.imm = (instruction->info.imm << 17) >> 17; /* sign-extend */ - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, instruction->info.ra, - &(instruction->access_start)); - instruction->access_end = instruction->access_start + 1; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tSBI.bi\t$r%" PRIu8 ",[$r%" PRIu8 "],#%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.imm); - break; - case 5: /* SHI.bi */ - nds32_parse_type_2(opcode, &(instruction->info.rt), - &(instruction->info.ra), &(instruction->info.imm)); - instruction->info.imm = (instruction->info.imm << 17) >> 16; /* sign-extend */ - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, instruction->info.ra, - &(instruction->access_start)); - instruction->access_end = instruction->access_start + 2; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tSHI.bi\t$r%" PRIu8 ",[$r%" PRIu8 "],#%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.imm); - break; - case 6: /* SWI.bi */ - nds32_parse_type_2(opcode, &(instruction->info.rt), - &(instruction->info.ra), &(instruction->info.imm)); - instruction->info.imm = (instruction->info.imm << 17) >> 15; /* sign-extend */ - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, instruction->info.ra, - &(instruction->access_start)); - instruction->access_end = instruction->access_start + 4; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tSWI.bi\t$r%" PRIu8 ",[$r%" PRIu8 "],#%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.imm); - break; - default: - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION", - address, - opcode); - return ERROR_FAIL; - } - - return ERROR_OK; -} - -static int nds32_parse_group_2_insn(struct nds32 *nds32, uint32_t opcode, - uint32_t address, struct nds32_instruction *instruction) -{ - uint8_t opc_6; - - opc_6 = instruction->info.opc_6; - - switch (opc_6 & 0x7) { - case 0: /* LBSI */ - nds32_parse_type_2(opcode, &(instruction->info.rt), - &(instruction->info.ra), &(instruction->info.imm)); - instruction->info.imm = (instruction->info.imm << 17) >> 17; /* sign-extend */ - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, instruction->info.ra, - &(instruction->access_start)); - instruction->access_start += instruction->info.imm; - instruction->access_end = instruction->access_start + 1; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tLBSI\t$r%" PRIu8 ",[$r%" PRIu8 "+#%" PRId32 "]", - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.imm); - break; - case 1: /* LHSI */ - nds32_parse_type_2(opcode, &(instruction->info.rt), - &(instruction->info.ra), &(instruction->info.imm)); - instruction->info.imm = (instruction->info.imm << 17) >> 16; /* sign-extend */ - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, instruction->info.ra, - &(instruction->access_start)); - instruction->access_start += instruction->info.imm; - instruction->access_end = instruction->access_start + 2; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tLHSI\t$r%" PRIu8 ",[$r%" PRIu8 "+#%" PRId32 "]", - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.imm); - break; - case 3: { /* DPREFI */ - uint8_t sub_type; - nds32_parse_type_2(opcode, &sub_type, &(instruction->info.ra), - &(instruction->info.imm)); - instruction->info.sub_opc = sub_type & 0xF; - instruction->type = NDS32_INSN_MISC; - if (sub_type & 0x10) { /* DPREFI.d */ - /* sign-extend */ - instruction->info.imm = (instruction->info.imm << 17) >> 14; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tDPREFI.d\t%" PRIu8 ",[$r%" PRIu8 "+#%" PRId32 "]", - address, - opcode, instruction->info.sub_opc, - instruction->info.ra, instruction->info.imm); - } else { /* DPREFI.w */ - /* sign-extend */ - instruction->info.imm = (instruction->info.imm << 17) >> 15; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tDPREFI.w\t%" PRIu8 ",[$r%" PRIu8 "+#%" PRId32 "]", - address, - opcode, instruction->info.sub_opc, - instruction->info.ra, instruction->info.imm); - } - } - break; - case 4: /* LBSI.bi */ - nds32_parse_type_2(opcode, &(instruction->info.rt), - &(instruction->info.ra), &(instruction->info.imm)); - instruction->info.imm = (instruction->info.imm << 17) >> 17; /* sign-extend */ - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, instruction->info.ra, - &(instruction->access_start)); - instruction->access_end = instruction->access_start + 1; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tLBSI.bi\t$r%" PRIu8 ",[$r%" PRIu8 "],#%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.imm); - break; - case 5: /* LHSI.bi */ - nds32_parse_type_2(opcode, &(instruction->info.rt), - &(instruction->info.ra), &(instruction->info.imm)); - instruction->info.imm = (instruction->info.imm << 17) >> 16; /* sign-extend */ - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, instruction->info.ra, - &(instruction->access_start)); - instruction->access_end = instruction->access_start + 2; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tLHSI.bi\t$r%" PRIu8 ",[$r%" PRIu8 "],#%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.imm); - break; - case 6: /* LBGP */ - nds32_parse_type_1(opcode, &(instruction->info.rt), &(instruction->info.imm)); - instruction->type = NDS32_INSN_LOAD_STORE; - if ((instruction->info.imm >> 19) & 0x1) { /* LBSI.gp */ - instruction->info.imm = (instruction->info.imm << 13) >> 13; - nds32_get_mapped_reg(nds32, R29, &(instruction->access_start)); - instruction->access_start += instruction->info.imm; - instruction->access_end = instruction->access_start + 1; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tLBSI.gp\t$r%" PRIu8 ",[#%" PRId32 "]", - address, - opcode, instruction->info.rt, instruction->info.imm); - } else { /* LBI.gp */ - instruction->info.imm = (instruction->info.imm << 13) >> 13; - nds32_get_mapped_reg(nds32, R29, &(instruction->access_start)); - instruction->access_start += instruction->info.imm; - instruction->access_end = instruction->access_start + 1; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tLBI.gp\t$r%" PRIu8 ",[#%" PRId32 "]", - address, - opcode, instruction->info.rt, instruction->info.imm); - } - break; - default: - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION", - address, - opcode); - return ERROR_FAIL; - } - - return ERROR_OK; -} - -static int nds32_parse_mem(struct nds32 *nds32, uint32_t opcode, uint32_t address, - struct nds32_instruction *instruction) -{ - uint32_t sub_opcode = opcode & 0x3F; - uint32_t val_ra, val_rb; - switch (sub_opcode >> 3) { - case 0: - switch (sub_opcode & 0x7) { - case 0: /* LB */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), \ - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, instruction->info.ra, &val_ra); - nds32_get_mapped_reg(nds32, instruction->info.rb, &val_rb); - instruction->access_start = val_ra + - (val_rb << ((instruction->info.imm >> 8) & 0x3)); - instruction->access_end = instruction->access_start + 1; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tLB\t$r%" PRIu8 ",[$r%" PRIu8 "+($r%" PRIu8 "<<%" PRId32 ")]", - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb, - (instruction->info.imm >> 8) & 0x3); - break; - case 1: /* LH */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, instruction->info.ra, &val_ra); - nds32_get_mapped_reg(nds32, instruction->info.rb, &val_rb); - instruction->access_start = val_ra + - (val_rb << ((instruction->info.imm >> 8) & 0x3)); - instruction->access_end = instruction->access_start + 2; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tLH\t$r%" PRIu8 ",[$r%" PRIu8 "+($r%" PRIu8 "<<%" PRId32 ")]", - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb, - (instruction->info.imm >> 8) & 0x3); - break; - case 2: /* LW */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, instruction->info.ra, &val_ra); - nds32_get_mapped_reg(nds32, instruction->info.rb, &val_rb); - instruction->access_start = val_ra + - (val_rb << ((instruction->info.imm >> 8) & 0x3)); - instruction->access_end = instruction->access_start + 4; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tLW\t$r%" PRIu8 ",[$r%" PRIu8 "+($r%" PRIu8 "<<%" PRId32 ")]", - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb, - (instruction->info.imm >> 8) & 0x3); - break; - case 4: /* LB.bi */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, instruction->info.ra, - &(instruction->access_start)); - instruction->access_end = instruction->access_start + 1; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tLB.bi\t$r%" PRIu8 ",[$r%" PRIu8 "],($r%" PRIu8 "<<%" PRId32 ")", - address, - opcode, instruction->info.rt, - instruction->info.ra, instruction->info.rb, - (instruction->info.imm >> 8) & 0x3); - break; - case 5: /* LH.bi */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, instruction->info.ra, - &(instruction->access_start)); - instruction->access_end = instruction->access_start + 2; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tLH.bi\t$r%" PRIu8 ",[$r%" PRIu8 "],($r%" PRIu8 "<<%" PRId32 ")", - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb, - (instruction->info.imm >> 8) & 0x3); - break; - case 6: /* LW.bi */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, instruction->info.ra, - &(instruction->access_start)); - instruction->access_end = instruction->access_start + 4; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tLW.bi\t$r%" PRIu8 ",[$r%" PRIu8 "],($r%" PRIu8 "<<%" PRId32 ")", - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb, - (instruction->info.imm >> 8) & 0x3); - break; - } - break; - case 1: - switch (sub_opcode & 0x7) { - case 0: /* SB */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, instruction->info.ra, &val_ra); - nds32_get_mapped_reg(nds32, instruction->info.rb, &val_rb); - instruction->access_start = val_ra + - (val_rb << ((instruction->info.imm >> 8) & 0x3)); - instruction->access_end = instruction->access_start + 1; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tSB\t$r%" PRIu8 ",[$r%" PRIu8 "+($r%" PRIu8 "<<%" PRId32 ")]", - address, - opcode, instruction->info.rt, - instruction->info.ra, instruction->info.rb, - (instruction->info.imm >> 8) & 0x3); - break; - case 1: /* SH */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, instruction->info.ra, &val_ra); - nds32_get_mapped_reg(nds32, instruction->info.rb, &val_rb); - instruction->access_start = val_ra + - (val_rb << ((instruction->info.imm >> 8) & 0x3)); - instruction->access_end = instruction->access_start + 2; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tSH\t$r%" PRIu8 ",[$r%" PRIu8 "+($r%" PRIu8 "<<%" PRId32 ")]", - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb, - (instruction->info.imm >> 8) & 0x3); - break; - case 2: /* SW */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, instruction->info.ra, &val_ra); - nds32_get_mapped_reg(nds32, instruction->info.rb, &val_rb); - instruction->access_start = val_ra + - (val_rb << ((instruction->info.imm >> 8) & 0x3)); - instruction->access_end = instruction->access_start + 4; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tSW\t$r%" PRIu8 ",[$r%" PRIu8 "+($r%" PRIu8 "<<%" PRId32 ")]", - address, - opcode, instruction->info.rt, - instruction->info.ra, instruction->info.rb, - (instruction->info.imm >> 8) & 0x3); - break; - case 4: /* SB.bi */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, instruction->info.ra, - &(instruction->access_start)); - instruction->access_end = instruction->access_start + 1; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tSB.bi\t$r%" PRIu8 ",[$r%" PRIu8 "],($r%" PRIu8 "<<%" PRId32 ")", - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb, - (instruction->info.imm >> 8) & 0x3); - break; - case 5: /* SH.bi */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, instruction->info.ra, - &(instruction->access_start)); - instruction->access_end = instruction->access_start + 2; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tSH.bi\t$r%" PRIu8 ",[$r%" PRIu8 "],($r%" PRIu8 "<<%" PRId32 ")", - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb, - (instruction->info.imm >> 8) & 0x3); - break; - case 6: /* SW.bi */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, instruction->info.ra, - &(instruction->access_start)); - instruction->access_end = instruction->access_start + 4; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tSW.bi\t$r%" PRIu8 ",[$r%" PRIu8 "],($r%" PRIu8 "<<%" PRId32 ")", - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb, - (instruction->info.imm >> 8) & 0x3); - break; - } - break; - case 2: - switch (sub_opcode & 0x7) { - case 0: /* LBS */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, instruction->info.ra, &val_ra); - nds32_get_mapped_reg(nds32, instruction->info.rb, &val_rb); - instruction->access_start = val_ra + - (val_rb << ((instruction->info.imm >> 8) & 0x3)); - instruction->access_end = instruction->access_start + 1; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tLBS\t$r%" PRIu8 ",[$r%" PRIu8 "+($r%" PRIu8 "<<%" PRId32 ")]", - address, - opcode, instruction->info.rt, - instruction->info.ra, instruction->info.rb, - (instruction->info.imm >> 8) & 0x3); - break; - case 1: /* LHS */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, instruction->info.ra, &val_ra); - nds32_get_mapped_reg(nds32, instruction->info.rb, &val_rb); - instruction->access_start = val_ra + - (val_rb << ((instruction->info.imm >> 8) & 0x3)); - instruction->access_end = instruction->access_start + 2; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tLHS\t$r%" PRIu8 ",[$r%" PRIu8 "+($r%" PRIu8 "<<%" PRId32 ")]", - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb, - (instruction->info.imm >> 8) & 0x3); - break; - case 3: /* DPREF */ - nds32_parse_type_3(opcode, &(instruction->info.sub_opc), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_MISC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tDPREF\t#%" PRIu8 ",[$r%" PRIu8 "+($r%" PRIu8 "<<#%" PRId32 ")]", - address, - opcode, instruction->info.sub_opc, - instruction->info.ra, instruction->info.rb, - (instruction->info.imm >> 8) & 0x3); - break; - case 4: /* LBS.bi */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, instruction->info.ra, - &(instruction->access_start)); - instruction->access_end = instruction->access_start + 1; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tLBS.bi\t$r%" PRIu8 ",[$r%" PRIu8 "],($r%" PRIu8 "<<%" PRId32 ")", - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb, - (instruction->info.imm >> 8) & 0x3); - break; - case 5: /* LHS.bi */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, instruction->info.ra, - &(instruction->access_start)); - instruction->access_end = instruction->access_start + 2; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tLHS.bi\t$r%" PRIu8 ",[$r%" PRIu8 "],($r%" PRIu8 "<<%" PRId32 ")", - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb, - (instruction->info.imm >> 8) & 0x3); - break; - } - break; - case 3: - switch (sub_opcode & 0x7) { - case 0: /* LLW */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, instruction->info.ra, &val_ra); - nds32_get_mapped_reg(nds32, instruction->info.rb, &val_rb); - instruction->access_start = val_ra + - (val_rb << ((instruction->info.imm >> 8) & 0x3)); - instruction->access_end = instruction->access_start + 4; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tLLW\t$r%" PRIu8 ",[$r%" PRIu8 "+($r%" PRIu8 "<<%" PRId32 ")]", - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb, - (instruction->info.imm >> 8) & 0x3); - break; - case 1: /* SCW */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, instruction->info.ra, &val_ra); - nds32_get_mapped_reg(nds32, instruction->info.rb, &val_rb); - instruction->access_start = val_ra + - (val_rb << ((instruction->info.imm >> 8) & 0x3)); - instruction->access_end = instruction->access_start + 4; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tSCW\t$r%" PRIu8 ",[$r%" PRIu8 "+($r%" PRIu8 "<<%" PRId32 ")]", - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb, - (instruction->info.imm >> 8) & 0x3); - break; - } - break; - case 4: - switch (sub_opcode & 0x7) { - case 0: /* LBUP */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, instruction->info.ra, &val_ra); - nds32_get_mapped_reg(nds32, instruction->info.rb, &val_rb); - instruction->access_start = val_ra + - (val_rb << ((instruction->info.imm >> 8) & 0x3)); - instruction->access_end = instruction->access_start + 1; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tLBUP\t$r%" PRIu8 ",[$r%" PRIu8 "+($r%" PRIu8 "<<%" PRId32 ")]", - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb, - (instruction->info.imm >> 8) & 0x3); - break; - case 2: /* LWUP */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, instruction->info.ra, &val_ra); - nds32_get_mapped_reg(nds32, instruction->info.rb, &val_rb); - instruction->access_start = val_ra + - (val_rb << ((instruction->info.imm >> 8) & 0x3)); - instruction->access_end = instruction->access_start + 4; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tLWUP\t$r%" PRIu8 ",[$r%" PRIu8 "+($r%" PRIu8 "<<%" PRId32 ")]", - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb, - (instruction->info.imm >> 8) & 0x3); - break; - } - break; - case 5: - switch (sub_opcode & 0x7) { - case 0: /* SBUP */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, instruction->info.ra, &val_ra); - nds32_get_mapped_reg(nds32, instruction->info.rb, &val_rb); - instruction->access_start = val_ra + - (val_rb << ((instruction->info.imm >> 8) & 0x3)); - instruction->access_end = instruction->access_start + 1; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tSBUP\t$r%" PRIu8 ",[$r%" PRIu8 "+($r%" PRIu8 "<<%" PRId32 ")]", - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb, - (instruction->info.imm >> 8) & 0x3); - break; - case 2: /* SWUP */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, instruction->info.ra, &val_ra); - nds32_get_mapped_reg(nds32, instruction->info.rb, &val_rb); - instruction->access_start = val_ra + - (val_rb << ((instruction->info.imm >> 8) & 0x3)); - instruction->access_end = instruction->access_start + 4; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tSWUP\t$r%" PRIu8 ",[$r%" PRIu8 "+($r%" PRIu8 "<<%" PRId32 ")]", - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb, - (instruction->info.imm >> 8) & 0x3); - break; - } - break; - default: - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION", - address, - opcode); - return ERROR_FAIL; - } - - return ERROR_OK; -} - -static int nds32_calculate_lsmw_access_range(struct nds32 *nds32, - struct nds32_instruction *instruction) -{ - uint8_t ba; - uint8_t id; - uint8_t enable4; - - enable4 = (instruction->info.imm >> 6) & 0xF; - ba = (instruction->info.imm >> 4) & 0x1; - id = (instruction->info.imm >> 3) & 0x1; - - if (ba) { - nds32_get_mapped_reg(nds32, instruction->info.ra, &(instruction->access_start)); - if (id) { /* decrease */ - /* access_end is the (last_element+1), so no need to minus 4 */ - /* instruction->access_end -= 4; */ - instruction->access_end = instruction->access_start; - } else { /* increase */ - instruction->access_start += 4; - } - } else { - nds32_get_mapped_reg(nds32, instruction->info.ra, &(instruction->access_start)); - instruction->access_end = instruction->access_start - 4; - } - - if (id) { /* decrease */ - instruction->access_start = instruction->access_end - - 4 * (instruction->info.rd - instruction->info.rb + 1); - instruction->access_start -= (4 * enable4_bits[enable4]); - } else { /* increase */ - instruction->access_end = instruction->access_start + - 4 * (instruction->info.rd - instruction->info.rb + 1); - instruction->access_end += (4 * enable4_bits[enable4]); - } - - return ERROR_OK; -} - -static int nds32_parse_lsmw(struct nds32 *nds32, uint32_t opcode, uint32_t address, - struct nds32_instruction *instruction) -{ - if (opcode & 0x20) { /* SMW, SMWA, SMWZB */ - switch (opcode & 0x3) { - /* TODO */ - case 0: /* SMW */ - /* use rd as re */ - nds32_parse_type_3(opcode, &(instruction->info.rb), - &(instruction->info.ra), - &(instruction->info.rd), &(instruction->info.imm)); - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_calculate_lsmw_access_range(nds32, instruction); - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tSMW\t$r%" PRIu8 ",[$r%" PRIu8 "],$r%" PRIu8 ",%" PRId32, - address, - opcode, instruction->info.rb, instruction->info.ra, - instruction->info.rd, - (instruction->info.imm >> 6) & 0xF); - break; - case 1: /* SMWA */ - nds32_parse_type_3(opcode, &(instruction->info.rb), - &(instruction->info.ra), - &(instruction->info.rd), &(instruction->info.imm)); - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_calculate_lsmw_access_range(nds32, instruction); - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tSMWA\t$r%" PRIu8 ",[$r%" PRIu8 "],$r%" PRIu8 ",%" PRId32, - address, - opcode, instruction->info.rb, instruction->info.ra, - instruction->info.rd, - (instruction->info.imm >> 6) & 0xF); - break; - case 2: /* SMWZB */ - nds32_parse_type_3(opcode, &(instruction->info.rb), - &(instruction->info.ra), - &(instruction->info.rd), &(instruction->info.imm)); - instruction->type = NDS32_INSN_LOAD_STORE; - /* TODO: calculate access_start/access_end */ - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tSMWZB\t$r%" PRIu8 ",[$r%" PRIu8 "],$r%" PRIu8 ",%" PRId32, - address, - opcode, instruction->info.rb, instruction->info.ra, - instruction->info.rd, - (instruction->info.imm >> 6) & 0xF); - break; - default: - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION", - address, - opcode); - return ERROR_FAIL; - } - } else { /* LMW, LMWA, LMWZB */ - switch (opcode & 0x3) { - case 0: /* LMW */ - nds32_parse_type_3(opcode, &(instruction->info.rb), - &(instruction->info.ra), - &(instruction->info.rd), &(instruction->info.imm)); - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_calculate_lsmw_access_range(nds32, instruction); - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tLMW\t$r%" PRIu8 ",[$r%" PRIu8 "],$r%" PRIu8 ",%" PRId32, - address, - opcode, instruction->info.rb, instruction->info.ra, - instruction->info.rd, - (instruction->info.imm >> 6) & 0xF); - break; - case 1: /* LMWA */ - nds32_parse_type_3(opcode, &(instruction->info.rb), - &(instruction->info.ra), - &(instruction->info.rd), &(instruction->info.imm)); - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_calculate_lsmw_access_range(nds32, instruction); - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tLMWA\t$r%" PRIu8 ",[$r%" PRIu8 "],$r%" PRIu8 ",%" PRId32, - address, - opcode, instruction->info.rb, instruction->info.ra, - instruction->info.rd, - (instruction->info.imm >> 6) & 0xF); - break; - case 2: /* LMWZB */ - nds32_parse_type_3(opcode, &(instruction->info.rb), - &(instruction->info.ra), - &(instruction->info.rd), &(instruction->info.imm)); - instruction->type = NDS32_INSN_LOAD_STORE; - /* TODO: calculate access_start/access_end */ - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tLMWZB\t$r%" PRIu8 ",[$r%" PRIu8 "],$r%" PRIu8 ",%" PRId32, - address, - opcode, instruction->info.rb, instruction->info.ra, - instruction->info.rd, - (instruction->info.imm >> 6) & 0xF); - break; - default: - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION", - address, - opcode); - return ERROR_FAIL; - } - } - - return ERROR_OK; -} - -static int nds32_parse_hwgp(struct nds32 *nds32, uint32_t opcode, uint32_t address, - struct nds32_instruction *instruction) -{ - switch ((opcode >> 18) & 0x3) { - case 0: /* LHI.gp */ - nds32_parse_type_1(opcode, &(instruction->info.rt), &(instruction->info.imm)); - instruction->info.imm = (instruction->info.imm << 14) >> 13; /* sign-extend */ - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, R29, &(instruction->access_start)); - instruction->access_start += instruction->info.imm; - instruction->access_end = instruction->access_start + 2; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tLHI.gp\t$r%" PRIu8 ",[#%" PRId32"]", - address, - opcode, instruction->info.rt, instruction->info.imm); - break; - case 1: /* LHSI.gp */ - nds32_parse_type_1(opcode, &(instruction->info.rt), &(instruction->info.imm)); - instruction->info.imm = (instruction->info.imm << 14) >> 13; /* sign-extend */ - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, R29, &(instruction->access_start)); - instruction->access_start += instruction->info.imm; - instruction->access_end = instruction->access_start + 2; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tLHSI.gp\t$r%" PRIu8 ",[#%" PRId32 "]", - address, - opcode, instruction->info.rt, instruction->info.imm); - break; - case 2: /* SHI.gp */ - nds32_parse_type_1(opcode, &(instruction->info.rt), &(instruction->info.imm)); - instruction->info.imm = (instruction->info.imm << 14) >> 13; /* sign-extend */ - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, R29, &(instruction->access_start)); - instruction->access_start += instruction->info.imm; - instruction->access_end = instruction->access_start + 2; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tSHI.gp\t$r%" PRIu8 ",[#%" PRId32 "]", - address, - opcode, instruction->info.rt, instruction->info.imm); - break; - case 3: - instruction->type = NDS32_INSN_LOAD_STORE; - if ((opcode >> 17) & 0x1) { /* SWI.gp */ - nds32_parse_type_1(opcode, &(instruction->info.rt), - &(instruction->info.imm)); - /* sign-extend */ - instruction->info.imm = (instruction->info.imm << 15) >> 13; - nds32_get_mapped_reg(nds32, R29, &(instruction->access_start)); - instruction->access_start += instruction->info.imm; - instruction->access_end = instruction->access_start + 4; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tSWI.gp\t$r%" PRIu8 ",[#%" PRId32 "]", - address, - opcode, instruction->info.rt, instruction->info.imm); - } else { /* LWI.gp */ - nds32_parse_type_1(opcode, &(instruction->info.rt), - &(instruction->info.imm)); - /* sign-extend */ - instruction->info.imm = (instruction->info.imm << 15) >> 13; - nds32_get_mapped_reg(nds32, R29, &(instruction->access_start)); - instruction->access_start += instruction->info.imm; - instruction->access_end = instruction->access_start + 4; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tLWI.gp\t$r%" PRIu8 ",[#%" PRId32 "]", - address, - opcode, instruction->info.rt, instruction->info.imm); - } - - break; - default: - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION", - address, - opcode); - return ERROR_FAIL; - } - - return ERROR_OK; -} - -static int nds32_parse_sbgp(struct nds32 *nds32, uint32_t opcode, uint32_t address, - struct nds32_instruction *instruction) -{ - switch ((opcode >> 19) & 0x1) { - case 0: /* SBI.gp */ - nds32_parse_type_1(opcode, &(instruction->info.rt), &(instruction->info.imm)); - instruction->info.imm = (instruction->info.imm << 13) >> 13; /* sign-extend */ - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, R29, &(instruction->access_start)); - instruction->access_start += instruction->info.imm; - instruction->access_end = instruction->access_start + 1; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tSBI.gp\t$r%" PRIu8 ",[#%" PRId32 "]", - address, - opcode, instruction->info.rt, instruction->info.imm); - break; - case 1: /* ADDI.gp */ - nds32_parse_type_1(opcode, &(instruction->info.rt), &(instruction->info.imm)); - instruction->info.imm = (instruction->info.imm << 13) >> 13; /* sign-extend */ - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tADDI.gp\t$r%" PRIu8 ",#%" PRId32 "", - address, - opcode, instruction->info.rt, instruction->info.imm); - break; - default: - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION", - address, - opcode); - return ERROR_FAIL; - } - - return ERROR_OK; -} - -static int nds32_parse_group_3_insn(struct nds32 *nds32, uint32_t opcode, uint32_t address, - struct nds32_instruction *instruction) -{ - uint8_t opc_6; - - opc_6 = instruction->info.opc_6; - - switch (opc_6 & 0x7) { - case 4: /* MEM */ - nds32_parse_mem(nds32, opcode, address, instruction); - break; - case 5: /* LSMW */ - nds32_parse_lsmw(nds32, opcode, address, instruction); - break; - case 6: /* HWGP */ - nds32_parse_hwgp(nds32, opcode, address, instruction); - break; - case 7: /* SBGP */ - nds32_parse_sbgp(nds32, opcode, address, instruction); - break; - default: - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION", - address, - opcode); - return ERROR_FAIL; - } - - return ERROR_OK; -} - -static int nds32_parse_alu_1(uint32_t opcode, uint32_t address, - struct nds32_instruction *instruction) -{ - switch (opcode & 0x1F) { - case 0: /* ADD */ - nds32_parse_type_3(opcode, &(instruction->info.rt), &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_DATA_PROC; - instruction->info.imm = (instruction->info.imm >> 5) & 0x1F; - if (instruction->info.imm) - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tADD_SLLI\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8 ",%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb, - instruction->info.imm); - else - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tADD\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb); - break; - case 1: /* SUB */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_DATA_PROC; - instruction->info.imm = (instruction->info.imm >> 5) & 0x1F; - if (instruction->info.imm) - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tSUB_SLLI\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8 ",%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb, - instruction->info.imm); - else - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tSUB\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8 "", - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb); - break; - case 2: /* AND */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_DATA_PROC; - instruction->info.imm = (instruction->info.imm >> 5) & 0x1F; - if (instruction->info.imm) - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tAND_SLLI\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8 ",%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb, - instruction->info.imm); - else - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tAND\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8 "", - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb); - break; - case 3: /* XOR */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_DATA_PROC; - instruction->info.imm = (instruction->info.imm >> 5) & 0x1F; - if (instruction->info.imm) - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tXOR_SLLI\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8 ",%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb, - instruction->info.imm); - else - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tXOR\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb); - break; - case 4: /* OR */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_DATA_PROC; - instruction->info.imm = (instruction->info.imm >> 5) & 0x1F; - if (instruction->info.imm) - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tOR_SLLI\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8 ",%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb, - instruction->info.imm); - else - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tOR\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb); - break; - case 5: /* NOR */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tNOR\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb); - break; - case 6: /* SLT */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tSLT\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb); - break; - case 7: /* SLTS */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tSLTS\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb); - break; - case 8: { /* SLLI */ - uint8_t imm; - int32_t sub_op; - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &imm, &sub_op); - instruction->info.imm = imm; - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tSLLI\t$r%" PRIu8 ",$r%" PRIu8 ",#%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.imm); - } - break; - case 9: { /* SRLI */ - uint8_t imm; - int32_t sub_op; - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &imm, &sub_op); - instruction->info.imm = imm; - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tSRLI\t$r%" PRIu8 ",$r%" PRIu8 ",#%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.imm); - } - break; - case 10: { /* SRAI */ - uint8_t imm; - int32_t sub_op; - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &imm, &sub_op); - instruction->info.imm = imm; - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tSRAI\t$r%" PRIu8 ",$r%" PRIu8 ",#%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.imm); - } - break; - case 11: { /* ROTRI */ - uint8_t imm; - int32_t sub_op; - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &imm, &sub_op); - instruction->info.imm = imm; - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tROTRI\t$r%" PRIu8 ",$r%" PRIu8 ",#%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.imm); - } - break; - case 12: { /* SLL */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tSLL\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb); - } - break; - case 13: { /* SRL */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tSRL\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb); - } - break; - case 14: { /* SRA */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tSRA\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb); - } - break; - case 15: { /* ROTR */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tROTR\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb); - } - break; - case 16: { /* SEB */ - nds32_parse_type_2(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.imm)); - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tSEB\t$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra); - } - break; - case 17: { /* SEH */ - nds32_parse_type_2(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.imm)); - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tSEH\t$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra); - } - break; - case 18: /* BITC */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tBITC\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb); - break; - case 19: { /* ZEH */ - nds32_parse_type_2(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.imm)); - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tZEH\t$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra); - } - break; - case 20: { /* WSBH */ - nds32_parse_type_2(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.imm)); - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tWSBH\t$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra); - } - break; - case 21: /* OR_SRLI */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_DATA_PROC; - instruction->info.imm = (instruction->info.imm >> 5) & 0x1F; - if (instruction->info.imm) - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tOR_SRLI\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8 ",%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb, - instruction->info.imm); - else - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tOR\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb); - break; - case 22: { /* DIVSR */ - nds32_parse_type_4(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.rd), - &(instruction->info.sub_opc)); - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tDIVSR\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb, - instruction->info.rd); - } - break; - case 23: { /* DIVR */ - nds32_parse_type_4(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.rd), - &(instruction->info.sub_opc)); - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tDIVR\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb, - instruction->info.rd); - } - break; - case 24: { /* SVA */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tSVA\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb); - } - break; - case 25: { /* SVS */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tSVS\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb); - } - break; - case 26: { /* CMOVZ */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_MISC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tCMOVZ\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb); - } - break; - case 27: { /* CMOVN */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_MISC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tCMOVN\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb); - } - break; - case 28: /* ADD_SRLI */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_DATA_PROC; - instruction->info.imm = (instruction->info.imm >> 5) & 0x1F; - if (instruction->info.imm) - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tADD_SRLI\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8 ",%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb, - instruction->info.imm); - else - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tADD\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb); - break; - case 29: /* SUB_SRLI */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_DATA_PROC; - instruction->info.imm = (instruction->info.imm >> 5) & 0x1F; - if (instruction->info.imm) - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tSUB_SRLI\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8 ",%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb, - instruction->info.imm); - else - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tSUB\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb); - break; - case 30: /* AND_SRLI */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_DATA_PROC; - instruction->info.imm = (instruction->info.imm >> 5) & 0x1F; - if (instruction->info.imm) - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tAND_SRLI\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8 ",%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb, - instruction->info.imm); - else - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tAND\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb); - break; - case 31: /* XOR_SRLI */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_DATA_PROC; - instruction->info.imm = (instruction->info.imm >> 5) & 0x1F; - if (instruction->info.imm) - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tXOR_SRLI\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8 ",%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb, - instruction->info.imm); - else - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tXOR\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb); - break; - default: - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION", - address, - opcode); - return ERROR_FAIL; - } - - return ERROR_OK; -} - -static int nds32_parse_alu_2(uint32_t opcode, uint32_t address, - struct nds32_instruction *instruction) -{ - switch (opcode & 0x3F) { - case 0: /* MAX */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tMAX\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb); - break; - case 1: /* MIN */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tMIN\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb); - break; - case 2: /* AVE */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tAVE\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb); - break; - case 3: /* ABS */ - nds32_parse_type_2(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.imm)); - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tAVE\t$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra); - break; - case 4: { /* CLIPS */ - uint8_t imm; - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &imm, &(instruction->info.imm)); - instruction->info.imm = imm; - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tCLIPS\t$r%" PRIu8 ",$r%" PRIu8 ",#%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.imm); - } - break; - case 5: { /* CLIP */ - uint8_t imm; - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &imm, &(instruction->info.imm)); - instruction->info.imm = imm; - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tCLIP\t$r%" PRIu8 ",$r%" PRIu8 ",#%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.imm); - } - break; - case 6: /* CLO */ - nds32_parse_type_2(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.imm)); - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tCLO\t$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra); - break; - case 7: /* CLZ */ - nds32_parse_type_2(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.imm)); - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tCLZ\t$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra); - break; - case 8: { /* BSET */ - uint8_t imm; - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &imm, &(instruction->info.imm)); - instruction->info.imm = imm; - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tBSET\t$r%" PRIu8 ",$r%" PRIu8 ",#%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.imm); - } - break; - case 9: { /* BCLR */ - uint8_t imm; - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &imm, &(instruction->info.imm)); - instruction->info.imm = imm; - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tBCLR\t$r%" PRIu8 ",$r%" PRIu8 ",#%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.imm); - } - break; - case 10: { /* BTGL */ - uint8_t imm; - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &imm, &(instruction->info.imm)); - instruction->info.imm = imm; - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tBTGL\t$r%" PRIu8 ",$r%" PRIu8 ",#%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.imm); - } - break; - case 11: { /* BTST */ - uint8_t imm; - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &imm, &(instruction->info.imm)); - instruction->info.imm = imm; - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tBTST\t$r%" PRIu8 ",$r%" PRIu8 ",#%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.imm); - } - break; - case 12: /* BSE */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tBSE\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb); - break; - case 13: /* BSP */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tBSP\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb); - break; - case 14: /* FFB */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tFFB\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb); - break; - case 15: /* FFMISM */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tFFMISM\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb); - break; - case 23: /* FFZMISM */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tFFZMISM\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb); - break; - case 32: /* MFUSR */ - nds32_parse_type_1(opcode, &(instruction->info.rt), - &(instruction->info.imm)); - instruction->type = NDS32_INSN_RESOURCE_ACCESS; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tMFUSR\t$r%" PRIu8 ",#%" PRId32, - address, - opcode, instruction->info.rt, - (instruction->info.imm >> 10) & 0x3FF); - break; - case 33: /* MTUSR */ - nds32_parse_type_1(opcode, &(instruction->info.rt), - &(instruction->info.imm)); - instruction->type = NDS32_INSN_RESOURCE_ACCESS; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tMTUSR\t$r%" PRIu8 ",#%" PRId32, - address, - opcode, instruction->info.rt, - (instruction->info.imm >> 10) & 0x3FF); - break; - case 36: /* MUL */ - nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tMUL\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb); - break; - case 40: { /* MULTS64 */ - uint8_t dt_val; - nds32_parse_type_3(opcode, &dt_val, - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tMULTS64\t$D%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, (uint8_t)((dt_val >> 1) & 0x1), instruction->info.ra, - instruction->info.rb); - } - break; - case 41: { /* MULT64 */ - uint8_t dt_val; - nds32_parse_type_3(opcode, &dt_val, - &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tMULT64\t$D%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, (uint8_t)((dt_val >> 1) & 0x1), instruction->info.ra, - instruction->info.rb); - } - break; - case 42: { /* MADDS64 */ - uint8_t dt_val; - nds32_parse_type_3(opcode, &dt_val, &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tMADDS64\t$D%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, (uint8_t)((dt_val >> 1) & 0x1), instruction->info.ra, - instruction->info.rb); - } - break; - case 43: { /* MADD64 */ - uint8_t dt_val; - nds32_parse_type_3(opcode, &dt_val, &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tMADD64\t$D%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, (uint8_t)((dt_val >> 1) & 0x1), instruction->info.ra, - instruction->info.rb); - } - break; - case 44: { /* MSUBS64 */ - uint8_t dt_val; - nds32_parse_type_3(opcode, &dt_val, &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tMSUBS64\t$D%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, (uint8_t)((dt_val >> 1) & 0x1), instruction->info.ra, - instruction->info.rb); - } - break; - case 45: { /* MSUB64 */ - uint8_t dt_val; - nds32_parse_type_3(opcode, &dt_val, &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tMSUB64\t$D%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, (uint8_t)((dt_val >> 1) & 0x1), instruction->info.ra, - instruction->info.rb); - } - break; - case 46: { /* DIVS */ - uint8_t dt_val; - nds32_parse_type_3(opcode, &dt_val, &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tDIVS\t$D%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, (uint8_t)((dt_val >> 1) & 0x1), instruction->info.ra, - instruction->info.rb); - } - break; - case 47: { /* DIV */ - uint8_t dt_val; - nds32_parse_type_3(opcode, &dt_val, &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tDIV\t$D%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, (uint8_t)((dt_val >> 1) & 0x1), instruction->info.ra, - instruction->info.rb); - } - break; - case 49: { /* MULT32 */ - uint8_t dt_val; - nds32_parse_type_3(opcode, &dt_val, &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tMULT32\t$D%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, (uint8_t)((dt_val >> 1) & 0x1), instruction->info.ra, - instruction->info.rb); - } - break; - case 51: { /* MADD32 */ - uint8_t dt_val; - nds32_parse_type_3(opcode, &dt_val, &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tMADD32\t$D%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, (uint8_t)((dt_val >> 1) & 0x1), instruction->info.ra, - instruction->info.rb); - } - break; - case 53: { /* MSUB32 */ - uint8_t dt_val; - nds32_parse_type_3(opcode, &dt_val, &(instruction->info.ra), - &(instruction->info.rb), &(instruction->info.imm)); - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tMSUB32\t$D%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, (uint8_t)((dt_val >> 1) & 0x1), instruction->info.ra, - instruction->info.rb); - } - break; - default: - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION", - address, - opcode); - return ERROR_FAIL; - } - - return ERROR_OK; -} - -static int nds32_parse_group_4_insn(struct nds32 *nds32, uint32_t opcode, - uint32_t address, struct nds32_instruction *instruction) -{ - uint8_t opc_6; - - opc_6 = instruction->info.opc_6; - - switch (opc_6 & 0x7) { - case 0: /* ALU_1 */ - nds32_parse_alu_1(opcode, address, instruction); - break; - case 1: /* ALU_2 */ - nds32_parse_alu_2(opcode, address, instruction); - break; - case 2: /* MOVI */ - nds32_parse_type_1(opcode, &(instruction->info.rt), - &(instruction->info.imm)); - /* sign-extend */ - instruction->info.imm = (instruction->info.imm << 12) >> 12; - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tMOVI\t$r%" PRIu8 ",#%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.imm); - break; - case 3: /* SETHI */ - nds32_parse_type_1(opcode, &(instruction->info.rt), - &(instruction->info.imm)); - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tSETHI\t$r%" PRIu8 ",0x%8.8" PRIx32, - address, - opcode, instruction->info.rt, instruction->info.imm); - break; - case 4: /* JI */ - nds32_parse_type_0(opcode, &(instruction->info.imm)); - /* sign-extend */ - instruction->info.imm = (instruction->info.imm << 8) >> 8; - instruction->type = NDS32_INSN_JUMP_BRANCH; - if ((instruction->info.imm >> 24) & 0x1) { /* JAL */ - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tJAL\t#%" PRId32, - address, - opcode, instruction->info.imm); - } else { /* J */ - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tJ\t#%" PRId32, - address, - opcode, instruction->info.imm); - } - break; - case 5: { /* JREG */ - int32_t imm; - nds32_parse_type_0(opcode, &imm); - instruction->info.rb = (imm >> 10) & 0x1F; - instruction->type = NDS32_INSN_JUMP_BRANCH; - switch (imm & 0x1F) { - /* TODO */ - case 0: /* JR */ - if (imm & 0x20) { /* RET */ - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tRET\t$r%" PRIu8, - address, - opcode, instruction->info.rb); - } else { /* JR */ - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tJR\t$r%" PRIu8, - address, - opcode, instruction->info.rb); - } - break; - case 1: /* JRAL */ - instruction->info.rt = (imm >> 20) & 0x1F; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tJRAL\t$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.rb); - break; - case 2: /* JRNEZ */ - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tJRNEZ\t$r%" PRIu8, - address, - opcode, instruction->info.rb); - break; - case 3: /* JRALNEZ */ - instruction->info.rt = (imm >> 20) & 0x1F; - if (instruction->info.rt == R30) - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tJRALNEZ\t$r%" PRIu8, - address, - opcode, instruction->info.rb); - else - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tJRALNEZ\t$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, - instruction->info.rt, - instruction->info.rb); - break; - } - } - break; - case 6: { /* BR1 */ - int32_t imm; - - nds32_parse_type_0(opcode, &imm); - instruction->type = NDS32_INSN_JUMP_BRANCH; - if ((imm >> 14) & 0x1) { /* BNE */ - nds32_parse_type_2(opcode, &(instruction->info.rt), - &(instruction->info.ra), &(instruction->info.imm)); - /* sign-extend */ - instruction->info.imm = (instruction->info.imm << 18) >> 18; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tBNE\t$r%" PRIu8 ",$r%" PRIu8 ",#%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.imm); - } else { /* BEQ */ - nds32_parse_type_2(opcode, &(instruction->info.rt), - &(instruction->info.ra), &(instruction->info.imm)); - /* sign-extend */ - instruction->info.imm = (instruction->info.imm << 18) >> 18; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tBEQ\t$r%" PRIu8 ",$r%" PRIu8 ",#%" PRId32, - address, - opcode, instruction->info.rt, - instruction->info.ra, - instruction->info.imm); - } - } - break; - case 7: { /* BR2 */ - int32_t imm; - - nds32_parse_type_0(opcode, &imm); - instruction->type = NDS32_INSN_JUMP_BRANCH; - switch ((imm >> 16) & 0xF) { - case 2: /* BEQZ */ - nds32_parse_type_1(opcode, &(instruction->info.rt), - &(instruction->info.imm)); - instruction->info.imm = (instruction->info.imm << 16) >> 16; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tBEQZ\t$r%" PRIu8 ",#%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.imm); - break; - case 3: /* BNEZ */ - nds32_parse_type_1(opcode, &(instruction->info.rt), - &(instruction->info.imm)); - instruction->info.imm = (instruction->info.imm << 16) >> 16; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tBNEZ\t$r%" PRIu8 ",#%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.imm); - break; - case 4: /* BGEZ */ - nds32_parse_type_1(opcode, &(instruction->info.rt), - &(instruction->info.imm)); - instruction->info.imm = (instruction->info.imm << 16) >> 16; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tBGEZ\t$r%" PRIu8 ",#%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.imm); - break; - case 5: /* BLTZ */ - nds32_parse_type_1(opcode, &(instruction->info.rt), - &(instruction->info.imm)); - instruction->info.imm = (instruction->info.imm << 16) >> 16; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tBLTZ\t$r%" PRIu8 ",#%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.imm); - break; - case 6: /* BGTZ */ - nds32_parse_type_1(opcode, &(instruction->info.rt), - &(instruction->info.imm)); - instruction->info.imm = (instruction->info.imm << 16) >> 16; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tBGTZ\t$r%" PRIu8 ",#%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.imm); - break; - case 7: /* BLEZ */ - nds32_parse_type_1(opcode, &(instruction->info.rt), - &(instruction->info.imm)); - instruction->info.imm = (instruction->info.imm << 16) >> 16; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tBLEZ\t$r%" PRIu8 ",#%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.imm); - break; - case 12: /* BGEZAL */ - nds32_parse_type_1(opcode, &(instruction->info.rt), - &(instruction->info.imm)); - instruction->info.imm = (instruction->info.imm << 16) >> 16; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tBGEZAL\t$r%" PRIu8 ",#%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.imm); - break; - case 13: /* BLTZAL */ - nds32_parse_type_1(opcode, &(instruction->info.rt), - &(instruction->info.imm)); - instruction->info.imm = (instruction->info.imm << 16) >> 16; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tBLTZAL\t$r%" PRIu8 ",#%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.imm); - break; - } - } - break; - default: - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION", - address, - opcode); - return ERROR_FAIL; - } - - return ERROR_OK; -} - -static int nds32_parse_group_5_insn(struct nds32 *nds32, uint32_t opcode, - uint32_t address, struct nds32_instruction *instruction) -{ - uint8_t opc_6; - - opc_6 = instruction->info.opc_6; - - switch (opc_6 & 0x7) { - case 0: /* ADDI */ - nds32_parse_type_2(opcode, &(instruction->info.rt), - &(instruction->info.ra), &(instruction->info.imm)); - instruction->info.imm = (instruction->info.imm << 17) >> 17; /* sign-extend */ - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tADDI\t$r%" PRIu8 ",$r%" PRIu8 ",#%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.imm); - break; - case 1: /* SUBRI */ - nds32_parse_type_2(opcode, &(instruction->info.rt), - &(instruction->info.ra), &(instruction->info.imm)); - instruction->info.imm = (instruction->info.imm << 17) >> 17; /* sign-extend */ - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tSUBRI\t$r%" PRIu8 ",$r%" PRIu8 ",#%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.imm); - break; - case 2: /* ANDI */ - nds32_parse_type_2(opcode, &(instruction->info.rt), - &(instruction->info.ra), &(instruction->info.imm)); - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tANDI\t$r%" PRIu8 ",$r%" PRIu8 ",#%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.imm); - break; - case 3: /* XORI */ - nds32_parse_type_2(opcode, &(instruction->info.rt), - &(instruction->info.ra), &(instruction->info.imm)); - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tXORI\t$r%" PRIu8 ",$r%" PRIu8 ",#%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.imm); - break; - case 4: /* ORI */ - nds32_parse_type_2(opcode, &(instruction->info.rt), - &(instruction->info.ra), &(instruction->info.imm)); - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tORI\t$r%" PRIu8 ",$r%" PRIu8 ",0x%8.8" PRIx32, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.imm); - break; - case 6: /* SLTI */ - nds32_parse_type_2(opcode, &(instruction->info.rt), - &(instruction->info.ra), &(instruction->info.imm)); - instruction->info.imm = (instruction->info.imm << 17) >> 17; /* sign-extend */ - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tSLTI\t$r%" PRIu8 ",$r%" PRIu8 ",#%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.imm); - break; - case 7: /* SLTSI */ - nds32_parse_type_2(opcode, &(instruction->info.rt), - &(instruction->info.ra), &(instruction->info.imm)); - instruction->info.imm = (instruction->info.imm << 17) >> 17; /* sign-extend */ - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tSLTSI\t$r%" PRIu8 ",$r%" PRIu8 ",#%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.imm); - break; - default: - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION", - address, - opcode); - return ERROR_FAIL; - } - - return ERROR_OK; -} - -static int nds32_parse_group_6_insn(struct nds32 *nds32, uint32_t opcode, - uint32_t address, struct nds32_instruction *instruction) -{ - uint8_t opc_6; - - opc_6 = instruction->info.opc_6; - - switch (opc_6 & 0x7) { - case 2: { /* MISC */ - int32_t imm; - uint8_t sub_opc; - - nds32_parse_type_0(opcode, &imm); - - sub_opc = imm & 0x1F; - switch (sub_opc) { - case 0: /* STANDBY */ - instruction->type = NDS32_INSN_MISC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tSTANDBY\t#%" PRIu32, - address, - opcode, (opcode >> 5) & 0x3); - break; - case 1: /* CCTL */ - /* TODO */ - nds32_parse_type_2(opcode, &(instruction->info.rt), - &(instruction->info.ra), &(instruction->info.imm)); - instruction->type = NDS32_INSN_MISC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tCCTL", - address, - opcode); - break; - case 2: /* MFSR */ - nds32_parse_type_1(opcode, &(instruction->info.rt), - &(instruction->info.imm)); - instruction->type = NDS32_INSN_RESOURCE_ACCESS; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tMFSR\t$r%" PRIu8 ",#%" PRId32, - address, - opcode, instruction->info.rt, - (instruction->info.imm >> 10) & 0x3FF); - break; - case 3: /* MTSR */ - nds32_parse_type_1(opcode, &(instruction->info.ra), - &(instruction->info.imm)); - instruction->type = NDS32_INSN_RESOURCE_ACCESS; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tMTSR\t$r%" PRIu8 ",#%" PRId32, - address, - opcode, instruction->info.ra, - (instruction->info.imm >> 10) & 0x3FF); - break; - case 4: /* IRET */ - instruction->type = NDS32_INSN_MISC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tIRET", - address, - opcode); - break; - case 5: /* TRAP */ - instruction->type = NDS32_INSN_MISC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tTRAP\t#%" PRId32, - address, - opcode, (imm >> 5) & 0x7FFF); - break; - case 6: /* TEQZ */ - nds32_parse_type_1(opcode, &(instruction->info.ra), - &(instruction->info.imm)); - instruction->type = NDS32_INSN_MISC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tTEQZ\t$r%" PRIu8 ",#%" PRId32, - address, - opcode, instruction->info.ra, - (instruction->info.imm >> 5) & 0x7FFF); - break; - case 7: /* TNEZ */ - nds32_parse_type_1(opcode, &(instruction->info.ra), - &(instruction->info.imm)); - instruction->type = NDS32_INSN_MISC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tTNEZ\t$r%" PRIu8 ",#%" PRId32, - address, - opcode, instruction->info.ra, - (instruction->info.imm >> 5) & 0x7FFF); - break; - case 8: /* DSB */ - instruction->type = NDS32_INSN_MISC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tDSB", - address, - opcode); - break; - case 9: /* ISB */ - instruction->type = NDS32_INSN_MISC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tISB", - address, - opcode); - break; - case 10: /* BREAK */ - instruction->type = NDS32_INSN_MISC; - instruction->info.sub_opc = imm & 0x1F; - instruction->info.imm = (imm >> 5) & 0x7FFF; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tBREAK\t#%" PRId32, - address, - opcode, instruction->info.imm); - break; - case 11: /* SYSCALL */ - instruction->type = NDS32_INSN_MISC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tSYSCALL\t#%" PRId32, - address, - opcode, (imm >> 5) & 0x7FFF); - break; - case 12: /* MSYNC */ - instruction->type = NDS32_INSN_MISC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tMSYNC\t#%" PRId32, - address, - opcode, (imm >> 5) & 0x7); - break; - case 13: /* ISYNC */ - nds32_parse_type_1(opcode, &(instruction->info.ra), - &(instruction->info.imm)); - instruction->type = NDS32_INSN_MISC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 - "\tISYNC\t$r%" PRIu8, - address, - opcode, instruction->info.ra); - break; - case 14: /* TLBOP */ - /* TODO */ - nds32_parse_type_2(opcode, &(instruction->info.rt), - &(instruction->info.ra), &(instruction->info.imm)); - instruction->type = NDS32_INSN_RESOURCE_ACCESS; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tTLBOP", - address, - opcode); - break; - } - - break; - } - default: - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION", - address, - opcode); - return ERROR_FAIL; - } - - return ERROR_OK; -} - -static uint32_t field_mask[9] = { - 0x0, - 0x1, - 0x3, - 0x7, - 0xF, - 0x1F, - 0x3F, - 0x7F, - 0xFF, -}; - -static uint8_t nds32_extract_field_8u(uint16_t opcode, uint32_t start, uint32_t length) -{ - if (0 < length && length < 9) - return (opcode >> start) & field_mask[length]; - - return 0; -} - -static int nds32_parse_group_0_insn_16(struct nds32 *nds32, uint16_t opcode, - uint32_t address, struct nds32_instruction *instruction) -{ - switch ((opcode >> 10) & 0x7) { - case 0: /* MOV55 */ - instruction->info.rt = nds32_extract_field_8u(opcode, 5, 5); - instruction->info.ra = nds32_extract_field_8u(opcode, 0, 5); - instruction->type = NDS32_INSN_MISC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tMOV55\t$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra); - break; - case 1: /* MOVI55 */ - instruction->info.rt = nds32_extract_field_8u(opcode, 5, 5); - instruction->info.imm = nds32_extract_field_8u(opcode, 0, 5); - instruction->info.imm = (instruction->info.imm << 27) >> 27; - instruction->type = NDS32_INSN_MISC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tMOVI55\t$r%" PRIu8 ",#%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.imm); - break; - case 2: /* ADD45, SUB45 */ - instruction->info.rt = nds32_extract_field_8u(opcode, 5, 4); - instruction->info.rb = nds32_extract_field_8u(opcode, 0, 5); - instruction->type = NDS32_INSN_DATA_PROC; - if (nds32_extract_field_8u(opcode, 9, 1) == 0) { /* ADD45 */ - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tADD45\t$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.rb); - } else { /* SUB45 */ - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tSUB45\t$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.rb); - } - - break; - case 3: /* ADDI45, SUBI45 */ - instruction->info.rt = nds32_extract_field_8u(opcode, 5, 4); - instruction->info.imm = nds32_extract_field_8u(opcode, 0, 5); - instruction->type = NDS32_INSN_DATA_PROC; - if (nds32_extract_field_8u(opcode, 9, 1) == 0) { /* ADDI45 */ - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tADDI45\t$r%" PRIu8 ",#%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.imm); - } else { /* SUBI45 */ - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tSUBI45\t$r%" PRIu8 ",#%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.imm); - } - break; - case 4: /* SRAI45, SRLI45 */ - instruction->info.rt = nds32_extract_field_8u(opcode, 5, 4); - instruction->info.imm = nds32_extract_field_8u(opcode, 0, 5); - instruction->type = NDS32_INSN_DATA_PROC; - if (nds32_extract_field_8u(opcode, 9, 1) == 0) { /* SRAI45 */ - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tSRAI45\t$r%" PRIu8 ",#%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.imm); - } else { /* SRLI45 */ - if ((instruction->info.rt == 0) && (instruction->info.imm == 0)) { - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 "\t\tNOP", - address, - opcode); - } else { - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tSRLI45\t$r%" PRIu8 ",#%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.imm); - } - } - break; - case 5: - instruction->info.rt = nds32_extract_field_8u(opcode, 6, 3); - instruction->info.ra = nds32_extract_field_8u(opcode, 3, 3); - instruction->type = NDS32_INSN_DATA_PROC; - if (nds32_extract_field_8u(opcode, 9, 1) == 0) { /* SLLI333 */ - instruction->info.imm = nds32_extract_field_8u(opcode, 0, 3); - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tSLLI333\t$r%" PRIu8 ",$r%" PRIu8 ",#%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.imm); - } else { - instruction->info.sub_opc = nds32_extract_field_8u(opcode, 0, 3); - switch (instruction->info.sub_opc) { - case 0: /* ZEB33 */ - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tZEB33\t$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra); - break; - case 1: /* ZEH33 */ - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tZEH33\t$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra); - break; - case 2: /* SEB33 */ - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tSEB33\t$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra); - break; - case 3: /* SEH33 */ - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tSEH33\t$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra); - break; - case 4: /* XLSB33 */ - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tXLSB33\t$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra); - break; - case 5: /* XLLB33 */ - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tXLLB33\t$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra); - break; - case 6: /* BMSKI33 */ - instruction->info.ra = 0; - instruction->info.imm = nds32_extract_field_8u(opcode, 3, 3); - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tBMSKI33\t$r%" PRIu8 ",$r%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.imm); - break; - case 7: /* FEXTI33 */ - instruction->info.ra = 0; - instruction->info.imm = nds32_extract_field_8u(opcode, 3, 3); - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tFEXTI33\t$r%" PRIu8 ",$r%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.imm); - break; - default: - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx16 - "\tUNDEFINED INSTRUCTION", - address, - opcode); - return ERROR_FAIL; - } - } - break; - case 6: /* ADD333, SUB333 */ - instruction->info.rt = nds32_extract_field_8u(opcode, 6, 3); - instruction->info.ra = nds32_extract_field_8u(opcode, 3, 3); - instruction->info.rb = nds32_extract_field_8u(opcode, 0, 3); - instruction->type = NDS32_INSN_DATA_PROC; - if (nds32_extract_field_8u(opcode, 9, 1) == 0) { /* ADD333 */ - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tADD333\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb); - } else { /* SUB333 */ - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tSUB333\t$r%" PRIu8 ",$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.rb); - } - break; - case 7: /* ADDI333, SUBI333 */ - instruction->info.rt = nds32_extract_field_8u(opcode, 6, 3); - instruction->info.ra = nds32_extract_field_8u(opcode, 3, 3); - instruction->info.imm = nds32_extract_field_8u(opcode, 0, 3); - instruction->type = NDS32_INSN_DATA_PROC; - if (nds32_extract_field_8u(opcode, 9, 1) == 0) { /* ADDI333 */ - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tADDI333\t$r%" PRIu8 ",$r%" PRIu8 ",#%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.imm); - } else { /* SUBI333 */ - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tSUBI333\t$r%" PRIu8 ",$r%" PRIu8 ",#%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.imm); - } - break; - default: - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx16 "\tUNDEFINED INSTRUCTION", - address, - opcode); - return ERROR_FAIL; - } - - return ERROR_OK; -} - -static int nds32_parse_group_1_insn_16(struct nds32 *nds32, uint16_t opcode, - uint32_t address, struct nds32_instruction *instruction) -{ - switch ((opcode >> 9) & 0xF) { - case 0: /* LWI333 */ - instruction->info.rt = nds32_extract_field_8u(opcode, 6, 3); - instruction->info.ra = nds32_extract_field_8u(opcode, 3, 3); - instruction->info.imm = nds32_extract_field_8u(opcode, 0, 3) << 2; - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, instruction->info.ra, - &(instruction->access_start)); - instruction->access_start += instruction->info.imm; - instruction->access_end = instruction->access_start + 4; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tLWI333\t$r%" PRIu8 ",[$r%" PRIu8 "+(#%" PRId32 ")]", - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.imm); - break; - case 1: /* LWI333.BI */ - instruction->info.rt = nds32_extract_field_8u(opcode, 6, 3); - instruction->info.ra = nds32_extract_field_8u(opcode, 3, 3); - instruction->info.imm = nds32_extract_field_8u(opcode, 0, 3); - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, instruction->info.ra, - &(instruction->access_start)); - instruction->access_end = instruction->access_start + 4; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tLWI333.BI\t$r%" PRIu8 ",[$r%" PRIu8 "],#%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.imm << 2); - break; - case 2: /* LHI333 */ - instruction->info.rt = nds32_extract_field_8u(opcode, 6, 3); - instruction->info.ra = nds32_extract_field_8u(opcode, 3, 3); - instruction->info.imm = nds32_extract_field_8u(opcode, 0, 3) << 1; - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, instruction->info.ra, - &(instruction->access_start)); - instruction->access_start += instruction->info.imm; - instruction->access_end = instruction->access_start + 2; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tLHI333\t$r%" PRIu8 ",[$r%" PRIu8 "+(#%" PRId32 ")]", - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.imm); - break; - case 3: /* LBI333 */ - instruction->info.rt = nds32_extract_field_8u(opcode, 6, 3); - instruction->info.ra = nds32_extract_field_8u(opcode, 3, 3); - instruction->info.imm = nds32_extract_field_8u(opcode, 0, 3); - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, instruction->info.ra, - &(instruction->access_start)); - instruction->access_start += instruction->info.imm; - instruction->access_end = instruction->access_start + 1; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tLBI333\t$r%" PRIu8 ",[$r%" PRIu8 "+(#%" PRId32 ")]", - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.imm); - break; - case 4: /* SWI333 */ - instruction->info.rt = nds32_extract_field_8u(opcode, 6, 3); - instruction->info.ra = nds32_extract_field_8u(opcode, 3, 3); - instruction->info.imm = nds32_extract_field_8u(opcode, 0, 3) << 2; - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, instruction->info.ra, - &(instruction->access_start)); - instruction->access_start += instruction->info.imm; - instruction->access_end = instruction->access_start + 4; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tSWI333\t$r%" PRIu8 ",[$r%" PRIu8 "+(#%" PRId32 ")]", - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.imm); - break; - case 5: /* SWI333.BI */ - instruction->info.rt = nds32_extract_field_8u(opcode, 6, 3); - instruction->info.ra = nds32_extract_field_8u(opcode, 3, 3); - instruction->info.imm = nds32_extract_field_8u(opcode, 0, 3) << 2; - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, instruction->info.ra, - &(instruction->access_start)); - instruction->access_end = instruction->access_start + 4; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tSWI333.BI\t$r%" PRIu8 ",[$r%" PRIu8 "],#%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.imm); - break; - case 6: /* SHI333 */ - instruction->info.rt = nds32_extract_field_8u(opcode, 6, 3); - instruction->info.ra = nds32_extract_field_8u(opcode, 3, 3); - instruction->info.imm = nds32_extract_field_8u(opcode, 0, 3) << 1; - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, instruction->info.ra, - &(instruction->access_start)); - instruction->access_start += instruction->info.imm; - instruction->access_end = instruction->access_start + 2; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tSHI333\t$r%" PRIu8 ",[$r%" PRIu8 "+(#%" PRId32 ")]", - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.imm); - break; - case 7: /* SBI333 */ - instruction->info.rt = nds32_extract_field_8u(opcode, 6, 3); - instruction->info.ra = nds32_extract_field_8u(opcode, 3, 3); - instruction->info.imm = nds32_extract_field_8u(opcode, 0, 3); - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, instruction->info.ra, - &(instruction->access_start)); - instruction->access_start += instruction->info.imm; - instruction->access_end = instruction->access_start + 1; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tSHI333\t$r%" PRIu8 ",[$r%" PRIu8 "+(#%" PRId32 ")]", - address, - opcode, instruction->info.rt, instruction->info.ra, - instruction->info.imm); - break; - case 8: /* ADDRI36.SP */ - instruction->info.rt = nds32_extract_field_8u(opcode, 6, 3); - instruction->info.imm = nds32_extract_field_8u(opcode, 0, 6) << 2; - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tADDRI36.SP\t$r%" PRIu8 ",#%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.imm); - break; - case 9: /* LWI45.FE */ - instruction->info.rt = nds32_extract_field_8u(opcode, 5, 4); - instruction->info.imm = nds32_extract_field_8u(opcode, 0, 5); - instruction->info.imm -= 32; - instruction->info.imm <<= 2; - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, R8, &(instruction->access_start)); - instruction->access_start += instruction->info.imm; - instruction->access_end = instruction->access_start + 4; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tLWI45.FE\t$r%" PRIu8 ",[#%" PRId32 "]", - address, - opcode, instruction->info.rt, instruction->info.imm); - break; - case 10: /* LWI450 */ - instruction->info.rt = nds32_extract_field_8u(opcode, 5, 4); - instruction->info.ra = nds32_extract_field_8u(opcode, 0, 5); - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, instruction->info.ra, - &(instruction->access_start)); - instruction->access_end = instruction->access_start + 4; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tLWI450\t$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra); - break; - case 11: /* SWI450 */ - instruction->info.rt = nds32_extract_field_8u(opcode, 5, 4); - instruction->info.ra = nds32_extract_field_8u(opcode, 0, 5); - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, instruction->info.ra, - &(instruction->access_start)); - instruction->access_end = instruction->access_start + 4; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tSWI450\t$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra); - break; - case 12: - case 13: - case 14: - case 15: /* LWI37, SWI37 */ - instruction->info.rt = nds32_extract_field_8u(opcode, 8, 3); - instruction->info.imm = nds32_extract_field_8u(opcode, 0, 7) << 2; - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, R28, &(instruction->access_start)); - instruction->access_start += instruction->info.imm; - instruction->access_end = instruction->access_start + 4; - if (nds32_extract_field_8u(opcode, 7, 1) == 0) { /* LWI37 */ - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tLWI37\t$r%" PRIu8 ",[fp+#%" PRId32 "]", - address, - opcode, instruction->info.rt, instruction->info.imm); - } else { /* SWI37 */ - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tSWI37\t$r%" PRIu8 ",[fp+#%" PRId32 "]", - address, - opcode, instruction->info.rt, instruction->info.imm); - } - break; - default: /* ERROR */ - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx16 "\tUNDEFINED INSTRUCTION", - address, - opcode); - return ERROR_FAIL; - } - - return ERROR_OK; -} - -static int nds32_parse_group_2_insn_16(struct nds32 *nds32, uint16_t opcode, - uint32_t address, struct nds32_instruction *instruction) -{ - switch ((opcode >> 11) & 0x3) { - case 0: /* BEQZ38 */ - instruction->info.rt = nds32_extract_field_8u(opcode, 8, 3); - instruction->info.imm = nds32_extract_field_8u(opcode, 0, 8); - instruction->info.imm = (instruction->info.imm << 24) >> 24; - instruction->type = NDS32_INSN_JUMP_BRANCH; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tBEQZ38\t$r%" PRIu8 ",#%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.imm); - break; - case 1: /* BNEZ38 */ - instruction->info.rt = nds32_extract_field_8u(opcode, 8, 3); - instruction->info.imm = nds32_extract_field_8u(opcode, 0, 8); - instruction->info.imm = (instruction->info.imm << 24) >> 24; - instruction->type = NDS32_INSN_JUMP_BRANCH; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tBNEZ38\t$r%" PRIu8 ",#%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.imm); - break; - case 2: /* BEQS38,J8 */ - instruction->info.rt = nds32_extract_field_8u(opcode, 8, 3); - instruction->info.imm = nds32_extract_field_8u(opcode, 0, 8); - instruction->info.imm = (instruction->info.imm << 24) >> 24; - instruction->type = NDS32_INSN_JUMP_BRANCH; - if (instruction->info.rt == 5) { /* J8 */ - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tJ8\t#%" PRId32, - address, - opcode, instruction->info.imm); - } else { /* BEQS38 */ - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tBEQS38\t$r%" PRIu8 ",#%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.imm); - } - break; - case 3: /* BNES38, JR5, RET5, JRAL5 */ - instruction->info.rt = nds32_extract_field_8u(opcode, 8, 3); - instruction->info.imm = nds32_extract_field_8u(opcode, 0, 8); - instruction->info.imm = (instruction->info.imm << 24) >> 24; - instruction->type = NDS32_INSN_JUMP_BRANCH; - if (instruction->info.rt == 5) { - instruction->info.imm = 0; - instruction->info.rb = nds32_extract_field_8u(opcode, 0, 5); - switch (nds32_extract_field_8u(opcode, 5, 3)) { - case 0: /* JR5 */ - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tJR5\t$r%" PRIu8, - address, - opcode, instruction->info.rb); - break; - case 1: /* JRAL5 */ - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tJRAL5\t$r%" PRIu8, - address, - opcode, instruction->info.rb); - break; - case 2: /* EX9.IT */ - instruction->info.rb = 0; - instruction->info.imm = nds32_extract_field_8u(opcode, 0, 5); - /* TODO: implement real instruction semantics */ - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tEX9.IT\t#%" PRId32, - address, - opcode, instruction->info.imm); - break; - case 4: /* RET5 */ - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tRET5\t$r%" PRIu8, - address, - opcode, instruction->info.rb); - break; - case 5: /* ADD5.PC */ - instruction->info.rt = 0; - instruction->info.rt = nds32_extract_field_8u(opcode, 0, 5); - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tADD5.PC\t$r%" PRIu8, - address, - opcode, instruction->info.rt); - break; - default: - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx16 - "\tUNDEFINED INSTRUCTION", - address, - opcode); - return ERROR_FAIL; - } - } else { /* BNES38 */ - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tBNES38\t$r%" PRIu8 ",#%" PRId32, - address, - opcode, instruction->info.rt, instruction->info.imm); - } - break; - } - - return ERROR_OK; -} - -static int nds32_parse_group_3_insn_16(struct nds32 *nds32, uint16_t opcode, - uint32_t address, struct nds32_instruction *instruction) -{ - switch ((opcode >> 11) & 0x3) { - case 0: - switch ((opcode >> 9) & 0x3) { - case 0: /* SLTS45 */ - instruction->info.ra = nds32_extract_field_8u(opcode, 5, 4); - instruction->info.rb = nds32_extract_field_8u(opcode, 0, 5); - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tSLTS45\t$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.ra, instruction->info.rb); - break; - case 1: /* SLT45 */ - instruction->info.ra = nds32_extract_field_8u(opcode, 5, 4); - instruction->info.rb = nds32_extract_field_8u(opcode, 0, 5); - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tSLT45\t$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.ra, instruction->info.rb); - break; - case 2: /* SLTSI45 */ - instruction->info.ra = nds32_extract_field_8u(opcode, 5, 4); - instruction->info.imm = nds32_extract_field_8u(opcode, 0, 5); - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tSLTSI45\t$r%" PRIu8 ",#%" PRId32, - address, - opcode, instruction->info.ra, instruction->info.imm); - break; - case 3: /* SLTI45 */ - instruction->info.ra = nds32_extract_field_8u(opcode, 5, 4); - instruction->info.imm = nds32_extract_field_8u(opcode, 0, 5); - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tSLTI45\t$r%" PRIu8 ",#%" PRId32, - address, - opcode, instruction->info.ra, instruction->info.imm); - break; - } - break; - case 1: - switch ((opcode >> 9) & 0x3) { - case 0: - instruction->info.imm = nds32_extract_field_8u(opcode, 0, 8); - instruction->info.imm = (instruction->info.imm << 24) >> 24; - instruction->type = NDS32_INSN_JUMP_BRANCH; - if (nds32_extract_field_8u(opcode, 8, 1) == 0) { /* BEQZS8 */ - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tBEQZS8\t#%" PRId32, - address, - opcode, instruction->info.imm); - } else { /* BNEZS8 */ - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tBNEZS8\t#%" PRId32, - address, - opcode, instruction->info.imm); - } - break; - case 1: /* BREAK16 */ - if (((opcode >> 5) & 0xF) == 0) { - instruction->type = NDS32_INSN_MISC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tBREAK16\t#%" PRId16, - address, - opcode, (int16_t)(opcode & 0x1F)); - } else { /* EX9.IT */ - instruction->type = NDS32_INSN_MISC; - /* TODO: implement real instruction semantics */ - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tEX9.IT\t#%" PRId16, - address, - opcode, (int16_t)(opcode & 0x1FF)); - } - break; - case 2: /* ADDI10S */ - case 3: - instruction->info.imm = opcode & 0x3FF; - instruction->info.imm = (instruction->info.imm << 22) >> 22; - instruction->type = NDS32_INSN_DATA_PROC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tADDI10.SP\t#%" PRId32, - address, - opcode, instruction->info.imm); - break; - } - break; - case 2: - instruction->info.rt = nds32_extract_field_8u(opcode, 8, 3); - instruction->info.imm = nds32_extract_field_8u(opcode, 0, 7) << 2; - instruction->type = NDS32_INSN_LOAD_STORE; - nds32_get_mapped_reg(nds32, R31, &(instruction->access_start)); - instruction->access_start += instruction->info.imm; - instruction->access_end = instruction->access_start + 4; - if (nds32_extract_field_8u(opcode, 7, 1) == 0) { /* LWI37.SP */ - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tLWI37.SP\t$r%" PRIu8 ",[+#%" PRId32 "]", - address, - opcode, instruction->info.rt, instruction->info.imm); - } else { /* SWI37.SP */ - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tSWI37.SP\t$r%" PRIu8 ",[+#%" PRId32 "]", - address, - opcode, instruction->info.rt, instruction->info.imm); - } - break; - case 3: - switch ((opcode >> 9) & 0x3) { - case 0: /* IFCALL9 */ - instruction->info.imm = opcode & 0x1FF; - instruction->type = NDS32_INSN_JUMP_BRANCH; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tIFCALL9\t#%" PRId32 "", - address, - opcode, instruction->info.imm); - break; - case 1: /* MOVPI45 */ - instruction->info.imm = nds32_extract_field_8u(opcode, 0, 5) + 16; - instruction->info.rt = nds32_extract_field_8u(opcode, 5, 4); - instruction->type = NDS32_INSN_MISC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tMOVPI45\t$r%" PRIu8 ",#%" PRId32 "", - address, - opcode, instruction->info.rt, instruction->info.imm); - break; - case 2: /* PUSH25, POP25, MOVD44 */ - switch ((opcode >> 7) & 0x3) { - case 0: /* PUSH25 */ - { - uint8_t re; - uint8_t gpr_count; - - instruction->type = NDS32_INSN_LOAD_STORE; - instruction->info.imm = - nds32_extract_field_8u(opcode, 0, 5) << 3; - re = nds32_extract_field_8u(opcode, 5, 2); - - if (re == 0) - re = 6; - else if (re == 1) - re = 8; - else if (re == 2) - re = 10; - else if (re == 3) - re = 14; - - instruction->info.rd = re; - /* GPRs list: R6 ~ Re and fp, gp, lp */ - gpr_count = 3 + (re - 5); - - nds32_get_mapped_reg(nds32, R31, - &(instruction->access_end)); - instruction->access_start = - instruction->access_end - (gpr_count * 4); - - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tPUSH25\t$r%" PRIu8 ",#%" PRId32, - address, - opcode, instruction->info.rd, - instruction->info.imm); - } - break; - case 1: /* POP25 */ - { - uint8_t re; - uint8_t gpr_count; - - instruction->type = NDS32_INSN_LOAD_STORE; - instruction->info.imm = - nds32_extract_field_8u(opcode, 0, 5) << 3; - re = nds32_extract_field_8u(opcode, 5, 2); - - if (re == 0) - re = 6; - else if (re == 1) - re = 8; - else if (re == 2) - re = 10; - else if (re == 3) - re = 14; - - instruction->info.rd = re; - /* GPRs list: R6 ~ Re and fp, gp, lp */ - gpr_count = 3 + (re - 5); - - nds32_get_mapped_reg(nds32, R31, - &(instruction->access_start)); - instruction->access_start += instruction->info.imm; - instruction->access_end = - instruction->access_start + (gpr_count * 4); - - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tPOP25\t$r%" PRIu8 ",#%" PRId32, - address, - opcode, instruction->info.rd, - instruction->info.imm); - } - break; - case 2: /* MOVD44 */ - case 3: - instruction->info.ra = - nds32_extract_field_8u(opcode, 0, 4) * 2; - instruction->info.rt = - nds32_extract_field_8u(opcode, 4, 4) * 2; - instruction->type = NDS32_INSN_MISC; - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tMOVD44\t$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra); - break; - } - break; - case 3: /* NEG33, NOT33, MUL33, XOR33, AND33, OR33 */ - instruction->info.ra = nds32_extract_field_8u(opcode, 3, 3); - instruction->info.rt = nds32_extract_field_8u(opcode, 6, 3); - instruction->type = NDS32_INSN_DATA_PROC; - switch (opcode & 0x7) { - case 2: /* NEG33 */ - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tNEG33\t$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra); - break; - case 3: /* NOT33 */ - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tNOT33\t$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra); - break; - case 4: /* MUL33 */ - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tMUL33\t$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra); - break; - case 5: /* XOR33 */ - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tXOR33\t$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra); - break; - case 6: /* AND33 */ - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tAND33\t$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra); - break; - case 7: /* OR33 */ - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%4.4" PRIx16 - "\t\tOR33\t$r%" PRIu8 ",$r%" PRIu8, - address, - opcode, instruction->info.rt, instruction->info.ra); - break; - } - break; - } - break; - default: - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx16 "\tUNDEFINED INSTRUCTION", - address, - opcode); - return ERROR_FAIL; - } - - return ERROR_OK; -} - -int nds32_evaluate_opcode(struct nds32 *nds32, uint32_t opcode, uint32_t address, - struct nds32_instruction *instruction) -{ - int retval = ERROR_OK; - - /* clear fields, to avoid confusion */ - memset(instruction, 0, sizeof(struct nds32_instruction)); - - if (opcode >> 31) { - /* 16 bits instruction */ - instruction->instruction_size = 2; - opcode = (opcode >> 16) & 0xFFFF; - instruction->opcode = opcode; - - switch ((opcode >> 13) & 0x3) { - case 0: - retval = nds32_parse_group_0_insn_16(nds32, opcode, address, instruction); - break; - case 1: - retval = nds32_parse_group_1_insn_16(nds32, opcode, address, instruction); - break; - case 2: - retval = nds32_parse_group_2_insn_16(nds32, opcode, address, instruction); - break; - case 3: - retval = nds32_parse_group_3_insn_16(nds32, opcode, address, instruction); - break; - default: - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION", - address, - opcode); - return ERROR_FAIL; - } - } else { - /* 32 bits instruction */ - instruction->instruction_size = 4; - instruction->opcode = opcode; - - uint8_t opc_6; - opc_6 = opcode >> 25; - instruction->info.opc_6 = opc_6; - - switch ((opc_6 >> 3) & 0x7) { - case 0: /* LBI, LHI, LWI, LBI.bi, LHI.bi, LWI.bi */ - retval = nds32_parse_group_0_insn(nds32, opcode, address, instruction); - break; - case 1: /* SBI, SHI, SWI, SBI.bi, SHI.bi, SWI.bi */ - retval = nds32_parse_group_1_insn(nds32, opcode, address, instruction); - break; - case 2: /* LBSI, LHSI, DPREFI, LBSI.bi, LHSI.bi, LBGP */ - retval = nds32_parse_group_2_insn(nds32, opcode, address, instruction); - break; - case 3: /* MEM, LSMW, HWGP, SBGP */ - retval = nds32_parse_group_3_insn(nds32, opcode, address, instruction); - break; - case 4: /* ALU_1, ALU_2, MOVI, SETHI, JI, JREG, BR1, BR2 */ - retval = nds32_parse_group_4_insn(nds32, opcode, address, instruction); - break; - case 5: /* ADDI, SUBRI, ANDI, XORI, ORI, SLTI, SLTSI */ - retval = nds32_parse_group_5_insn(nds32, opcode, address, instruction); - break; - case 6: /* MISC */ - retval = nds32_parse_group_6_insn(nds32, opcode, address, instruction); - break; - default: /* ERROR */ - snprintf(instruction->text, - 128, - "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION", - address, - opcode); - return ERROR_FAIL; - } - } - - return retval; -} diff --git a/src/target/nds32_disassembler.h b/src/target/nds32_disassembler.h deleted file mode 100644 index 9117cbb08..000000000 --- a/src/target/nds32_disassembler.h +++ /dev/null @@ -1,56 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2013 Andes Technology * - * Hsiangkai Wang * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 OPENOCD_TARGET_NDS32_DISASSEMBLER_H -#define OPENOCD_TARGET_NDS32_DISASSEMBLER_H - -#include - -enum nds32_instruction_type { - NDS32_INSN_DATA_PROC = 0, - NDS32_INSN_LOAD_STORE, - NDS32_INSN_JUMP_BRANCH, - NDS32_INSN_RESOURCE_ACCESS, - NDS32_INSN_MISC, -}; - -struct nds32_instruction { - enum nds32_instruction_type type; - char text[128]; - uint32_t opcode; - uint8_t instruction_size; - uint32_t access_start; - uint32_t access_end; - - struct { - uint8_t opc_6; - uint8_t rt; - uint8_t ra; - uint8_t rb; - uint8_t rd; - uint8_t sub_opc; - int32_t imm; - } info; - -}; - -int nds32_read_opcode(struct nds32 *nds32, uint32_t address, uint32_t *value); -int nds32_evaluate_opcode(struct nds32 *nds32, uint32_t opcode, uint32_t address, - struct nds32_instruction *instruction); - -#endif /* OPENOCD_TARGET_NDS32_DISASSEMBLER_H */ diff --git a/src/target/nds32_edm.h b/src/target/nds32_edm.h deleted file mode 100644 index 1dec190f1..000000000 --- a/src/target/nds32_edm.h +++ /dev/null @@ -1,115 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2013 Andes Technology * - * Hsiangkai Wang * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 OPENOCD_TARGET_NDS32_EDM_H -#define OPENOCD_TARGET_NDS32_EDM_H - -/** - * @file - * This is the interface to the Embedded Debug Module for Andes cores. - */ - -/* EDM misc registers */ -enum nds_edm_misc_reg { - NDS_EDM_MISC_DIMIR = 0x0, - NDS_EDM_MISC_SBAR, - NDS_EDM_MISC_EDM_CMDR, - NDS_EDM_MISC_DBGER, - NDS_EDM_MISC_ACC_CTL, - NDS_EDM_MISC_EDM_PROBE, - NDS_EDM_MISC_GEN_PORT0, - NDS_EDM_MISC_GEN_PORT1, -}; - -/* EDM system registers */ -enum nds_edm_system_reg { - NDS_EDM_SR_BPC0 = 0x00, - NDS_EDM_SR_BPC1, - NDS_EDM_SR_BPC2, - NDS_EDM_SR_BPC3, - NDS_EDM_SR_BPC4, - NDS_EDM_SR_BPC5, - NDS_EDM_SR_BPC6, - NDS_EDM_SR_BPC7, - NDS_EDM_SR_BPA0 = 0x08, - NDS_EDM_SR_BPA1, - NDS_EDM_SR_BPA2, - NDS_EDM_SR_BPA3, - NDS_EDM_SR_BPA4, - NDS_EDM_SR_BPA5, - NDS_EDM_SR_BPA6, - NDS_EDM_SR_BPA7, - NDS_EDM_SR_BPAM0 = 0x10, - NDS_EDM_SR_BPAM1, - NDS_EDM_SR_BPAM2, - NDS_EDM_SR_BPAM3, - NDS_EDM_SR_BPAM4, - NDS_EDM_SR_BPAM5, - NDS_EDM_SR_BPAM6, - NDS_EDM_SR_BPAM7, - NDS_EDM_SR_BPV0 = 0x18, - NDS_EDM_SR_BPV1, - NDS_EDM_SR_BPV2, - NDS_EDM_SR_BPV3, - NDS_EDM_SR_BPV4, - NDS_EDM_SR_BPV5, - NDS_EDM_SR_BPV6, - NDS_EDM_SR_BPV7, - NDS_EDM_SR_BPCID0 = 0x20, - NDS_EDM_SR_BPCID1, - NDS_EDM_SR_BPCID2, - NDS_EDM_SR_BPCID3, - NDS_EDM_SR_BPCID4, - NDS_EDM_SR_BPCID5, - NDS_EDM_SR_BPCID6, - NDS_EDM_SR_BPCID7, - NDS_EDM_SR_EDM_CFG = 0x28, - NDS_EDM_SR_EDMSW = 0x30, - NDS_EDM_SR_EDM_CTL = 0x38, - NDS_EDM_SR_EDM_DTR = 0x40, - NDS_EDM_SR_BPMTV = 0x48, - NDS_EDM_SR_DIMBR = 0x50, - NDS_EDM_SR_TECR0 = 0x70, - NDS_EDM_SR_TECR1 = 0x71, -}; - -enum nds_memory_access { - NDS_MEMORY_ACC_BUS = 0, - NDS_MEMORY_ACC_CPU, -}; - -enum nds_memory_select { - NDS_MEMORY_SELECT_AUTO = 0, - NDS_MEMORY_SELECT_MEM = 1, - NDS_MEMORY_SELECT_ILM = 2, - NDS_MEMORY_SELECT_DLM = 3, -}; - -#define NDS_DBGER_DEX (0x1) -#define NDS_DBGER_DPED (0x2) -#define NDS_DBGER_CRST (0x4) -#define NDS_DBGER_AT_MAX (0x8) -#define NDS_DBGER_ILL_SEC_ACC (0x10) -#define NDS_DBGER_ALL_SUPRS_EX (0x40000000) -#define NDS_DBGER_RESACC (0x80000000) -#define NDS_DBGER_CLEAR_ALL (0x1F) - -#define NDS_EDMSW_WDV (1 << 0) -#define NDS_EDMSW_RDV (1 << 1) - -#endif /* OPENOCD_TARGET_NDS32_EDM_H */ diff --git a/src/target/nds32_insn.h b/src/target/nds32_insn.h deleted file mode 100644 index eb6664517..000000000 --- a/src/target/nds32_insn.h +++ /dev/null @@ -1,78 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2013 Andes Technology * - * Hsiangkai Wang * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 OPENOCD_TARGET_NDS32_INSN_H -#define OPENOCD_TARGET_NDS32_INSN_H - -#define NOP (0x40000009) -#define DSB (0x64000008) -#define ISB (0x64000009) -#define BEQ_MINUS_12 (0x4C000000 | 0x3FFA) -#define MTSR_DTR(a) (0x64000003 | (((0x03 << 7) | (0x08 << 3) | (0x00 << 0)) << 10) | (((a) & 0x1F) << 20)) -#define MFSR_DTR(a) (0x64000002 | (((0x03 << 7) | (0x08 << 3) | (0x00 << 0)) << 10) | (((a) & 0x1F) << 20)) -#define SETHI(a, b) (0x46000000 | ((a) << 20) | (b)) -#define ORI(a, b, c) (0x58000000 | ((a) << 20) | ((b) << 15) | (c)) -#define LWI_BI(a, b) (0x0C000001 | (a << 20) | (b << 15)) -#define LHI_BI(a, b) (0x0A000001 | (a << 20) | (b << 15)) -#define LBI_BI(a, b) (0x08000001 | (a << 20) | (b << 15)) -#define SWI_BI(a, b) (0x1C000001 | (a << 20) | (b << 15)) -#define SHI_BI(a, b) (0x1A000001 | (a << 20) | (b << 15)) -#define SBI_BI(a, b) (0x18000001 | (a << 20) | (b << 15)) -#define IRET (0x64000004) -#define L1D_IX_WB(a) (0x64000021 | ((a) << 15)) -#define L1D_IX_INVAL(a) (0x64000001 | ((a) << 15)) -#define L1D_VA_INVAL(a) (0x64000101 | ((a) << 15)) -#define L1D_VA_WB(a) (0x64000121 | ((a) << 15)) -#define L1D_IX_RTAG(a) (0x64000061 | ((a) << 15)) -#define L1D_IX_RWD(a) (0x64000081 | ((a) << 15)) -#define L1I_IX_INVAL(a) (0x64000201 | ((a) << 15)) -#define L1I_VA_INVAL(a) (0x64000301 | ((a) << 15)) -#define L1I_IX_RTAG(a) (0x64000261 | ((a) << 15)) -#define L1I_IX_RWD(a) (0x64000281 | ((a) << 15)) -#define L1I_VA_FILLCK(a) (0x64000361 | ((a) << 15)) -#define ISYNC(a) (0x6400000d | ((a) << 20)) -#define MSYNC_STORE (0x6400002c) -#define MSYNC_ALL (0x6400000c) -#define TLBOP_TARGET_READ(a) (0x6400000e | ((a) << 15)) -#define TLBOP_TARGET_PROBE(a, b) (0x640000AE | ((a) << 20) | ((b) << 15)) -#define MFCPD(a, b, c) (0x6A000041 | (a << 20) | (b << 8) | (c << 4)) -#define MFCPW(a, b, c) (0x6A000001 | (a << 20) | (b << 8) | (c << 4)) -#define MTCPD(a, b, c) (0x6A000049 | (a << 20) | (b << 8) | (c << 4)) -#define MTCPW(a, b, c) (0x6A000009 | (a << 20) | (b << 8) | (c << 4)) -#define MOVI_(a, b) (0x44000000 | (a << 20) | (b & 0xFFFFF)) -#define MFUSR_G0(a, b) (0x42000020 | (a << 20) | (b << 15)) -#define MTUSR_G0(a, b) (0x42000021 | (a << 20) | (b << 15)) -#define MFSR(a, b) (0x64000002 | (b << 10) | (a << 20)) -#define MTSR(a, b) (0x64000003 | (b << 10) | (a << 20)) -#define AMFAR(a, b) (0x60300060 | (a << 15) | b) -#define AMTAR(a, b) (0x60300040 | (a << 15) | b) -#define AMFAR2(a, b) (0x60300260 | (a << 15) | b) -#define AMTAR2(a, b) (0x60300240 | (a << 15) | b) -#define FMFCSR (0x6A000701) -#define FMTCSR (0x6A000709) -#define FMFCFG (0x6A000301) -#define FMFSR(a, b) (0x6A000001 | ((a) << 20) | ((b) << 15)) -#define FMTSR(a, b) (0x6A000009 | ((a) << 20) | ((b) << 15)) -#define FMFDR(a, b) (0x6A000041 | ((a) << 20) | ((b) << 15)) -#define FMTDR(a, b) (0x6A000049 | ((a) << 20) | ((b) << 15)) - -/* break instructions */ -extern const int NDS32_BREAK_16; -extern const int NDS32_BREAK_32; - -#endif /* OPENOCD_TARGET_NDS32_INSN_H */ diff --git a/src/target/nds32_reg.c b/src/target/nds32_reg.c deleted file mode 100644 index 7cefcb1a2..000000000 --- a/src/target/nds32_reg.c +++ /dev/null @@ -1,380 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2013 Andes Technology * - * Hsiangkai Wang * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 -#include "config.h" -#endif - -#include -#include "nds32_reg.h" - -static bool nds32_reg_init_done; -static struct nds32_reg_s nds32_regs[TOTAL_REG_NUM]; -static const struct nds32_reg_exception_s nds32_ex_reg_values[] = { - {IR0, 3, 0x3, 2}, - {IR0, 3, 0x3, 3}, - {IR1, 3, 0x3, 2}, - {IR1, 3, 0x3, 3}, - {IR2, 3, 0x3, 2}, - {IR2, 3, 0x3, 3}, - {MR3, 1, 0x7, 0}, - {MR3, 1, 0x7, 4}, - {MR3, 1, 0x7, 6}, - {MR3, 8, 0x7, 3}, - {0, 0, 0, 0}, -}; - -static inline void nds32_reg_set(uint32_t number, const char *simple_mnemonic, - const char *symbolic_mnemonic, uint32_t sr_index, - enum nds32_reg_type_s type, uint8_t size) -{ - nds32_regs[number].simple_mnemonic = simple_mnemonic; - nds32_regs[number].symbolic_mnemonic = symbolic_mnemonic; - nds32_regs[number].sr_index = sr_index; - nds32_regs[number].type = type; - nds32_regs[number].size = size; -} - -void nds32_reg_init(void) -{ - if (nds32_reg_init_done == true) - return; - - nds32_reg_set(R0, "r0", "r0", 0, NDS32_REG_TYPE_GPR, 32); - nds32_reg_set(R1, "r1", "r1", 0, NDS32_REG_TYPE_GPR, 32); - nds32_reg_set(R2, "r2", "r2", 0, NDS32_REG_TYPE_GPR, 32); - nds32_reg_set(R3, "r3", "r3", 0, NDS32_REG_TYPE_GPR, 32); - nds32_reg_set(R4, "r4", "r4", 0, NDS32_REG_TYPE_GPR, 32); - nds32_reg_set(R5, "r5", "r5", 0, NDS32_REG_TYPE_GPR, 32); - nds32_reg_set(R6, "r6", "r6", 0, NDS32_REG_TYPE_GPR, 32); - nds32_reg_set(R7, "r7", "r7", 0, NDS32_REG_TYPE_GPR, 32); - nds32_reg_set(R8, "r8", "r8", 0, NDS32_REG_TYPE_GPR, 32); - nds32_reg_set(R9, "r9", "r9", 0, NDS32_REG_TYPE_GPR, 32); - nds32_reg_set(R10, "r10", "r10", 0, NDS32_REG_TYPE_GPR, 32); - nds32_reg_set(R11, "r11", "r11", 0, NDS32_REG_TYPE_GPR, 32); - nds32_reg_set(R12, "r12", "r12", 0, NDS32_REG_TYPE_GPR, 32); - nds32_reg_set(R13, "r13", "r13", 0, NDS32_REG_TYPE_GPR, 32); - nds32_reg_set(R14, "r14", "r14", 0, NDS32_REG_TYPE_GPR, 32); - nds32_reg_set(R15, "r15", "r15", 0, NDS32_REG_TYPE_GPR, 32); - nds32_reg_set(R16, "r16", "r16", 0, NDS32_REG_TYPE_GPR, 32); - nds32_reg_set(R17, "r17", "r17", 0, NDS32_REG_TYPE_GPR, 32); - nds32_reg_set(R18, "r18", "r18", 0, NDS32_REG_TYPE_GPR, 32); - nds32_reg_set(R19, "r19", "r19", 0, NDS32_REG_TYPE_GPR, 32); - nds32_reg_set(R20, "r20", "r20", 0, NDS32_REG_TYPE_GPR, 32); - nds32_reg_set(R21, "r21", "r21", 0, NDS32_REG_TYPE_GPR, 32); - nds32_reg_set(R22, "r22", "r22", 0, NDS32_REG_TYPE_GPR, 32); - nds32_reg_set(R23, "r23", "r23", 0, NDS32_REG_TYPE_GPR, 32); - nds32_reg_set(R24, "r24", "r24", 0, NDS32_REG_TYPE_GPR, 32); - nds32_reg_set(R25, "r25", "r25", 0, NDS32_REG_TYPE_GPR, 32); - nds32_reg_set(R26, "r26", "p0", 0, NDS32_REG_TYPE_GPR, 32); - nds32_reg_set(R27, "r27", "p1", 0, NDS32_REG_TYPE_GPR, 32); - nds32_reg_set(R28, "fp", "fp", 0, NDS32_REG_TYPE_GPR, 32); - nds32_reg_set(R29, "gp", "gp", 0, NDS32_REG_TYPE_GPR, 32); - nds32_reg_set(R30, "lp", "lp", 0, NDS32_REG_TYPE_GPR, 32); - nds32_reg_set(R31, "sp", "sp", 0, NDS32_REG_TYPE_GPR, 32); - nds32_reg_set(PC, "pc", "pc", 31, NDS32_REG_TYPE_SPR, 32); - - nds32_reg_set(D0LO, "d0lo", "d0lo", 0, NDS32_REG_TYPE_SPR, 32); - nds32_reg_set(D0HI, "d0hi", "d0hi", 1, NDS32_REG_TYPE_SPR, 32); - nds32_reg_set(D1LO, "d1lo", "d1lo", 2, NDS32_REG_TYPE_SPR, 32); - nds32_reg_set(D1HI, "d1hi", "d1hi", 3, NDS32_REG_TYPE_SPR, 32); - nds32_reg_set(ITB, "itb", "itb", 28, NDS32_REG_TYPE_SPR, 32); - nds32_reg_set(IFC_LP, "ifc_lp", "ifc_lp", 29, NDS32_REG_TYPE_SPR, 32); - - nds32_reg_set(CR0, "cr0", "CPU_VER", SRIDX(0, 0, 0), NDS32_REG_TYPE_CR, 32); - nds32_reg_set(CR1, "cr1", "ICM_CFG", SRIDX(0, 1, 0), NDS32_REG_TYPE_CR, 32); - nds32_reg_set(CR2, "cr2", "DCM_CFG", SRIDX(0, 2, 0), NDS32_REG_TYPE_CR, 32); - nds32_reg_set(CR3, "cr3", "MMU_CFG", SRIDX(0, 3, 0), NDS32_REG_TYPE_CR, 32); - nds32_reg_set(CR4, "cr4", "MSC_CFG", SRIDX(0, 4, 0), NDS32_REG_TYPE_CR, 32); - nds32_reg_set(CR5, "cr5", "CORE_ID", SRIDX(0, 0, 1), NDS32_REG_TYPE_CR, 32); - nds32_reg_set(CR6, "cr6", "FUCOP_EXIST", SRIDX(0, 5, 0), NDS32_REG_TYPE_CR, 32); - - nds32_reg_set(IR0, "ir0", "PSW", SRIDX(1, 0, 0), NDS32_REG_TYPE_IR, 32); - nds32_reg_set(IR1, "ir1", "IPSW", SRIDX(1, 0, 1), NDS32_REG_TYPE_IR, 32); - nds32_reg_set(IR2, "ir2", "P_IPSW", SRIDX(1, 0, 2), NDS32_REG_TYPE_IR, 32); - nds32_reg_set(IR3, "ir3", "IVB", SRIDX(1, 1, 1), NDS32_REG_TYPE_IR, 32); - nds32_reg_set(IR4, "ir4", "EVA", SRIDX(1, 2, 1), NDS32_REG_TYPE_IR, 32); - nds32_reg_set(IR5, "ir5", "P_EVA", SRIDX(1, 2, 2), NDS32_REG_TYPE_IR, 32); - nds32_reg_set(IR6, "ir6", "ITYPE", SRIDX(1, 3, 1), NDS32_REG_TYPE_IR, 32); - nds32_reg_set(IR7, "ir7", "P_ITYPE", SRIDX(1, 3, 2), NDS32_REG_TYPE_IR, 32); - nds32_reg_set(IR8, "ir8", "MERR", SRIDX(1, 4, 1), NDS32_REG_TYPE_IR, 32); - nds32_reg_set(IR9, "ir9", "IPC", SRIDX(1, 5, 1), NDS32_REG_TYPE_IR, 32); - nds32_reg_set(IR10, "ir10", "P_IPC", SRIDX(1, 5, 2), NDS32_REG_TYPE_IR, 32); - nds32_reg_set(IR11, "ir11", "OIPC", SRIDX(1, 5, 3), NDS32_REG_TYPE_IR, 32); - nds32_reg_set(IR12, "ir12", "P_P0", SRIDX(1, 6, 2), NDS32_REG_TYPE_IR, 32); - nds32_reg_set(IR13, "ir13", "P_P1", SRIDX(1, 7, 2), NDS32_REG_TYPE_IR, 32); - nds32_reg_set(IR14, "ir14", "INT_MASK", SRIDX(1, 8, 0), NDS32_REG_TYPE_IR, 32); - nds32_reg_set(IR15, "ir15", "INT_PEND", SRIDX(1, 9, 0), NDS32_REG_TYPE_IR, 32); - nds32_reg_set(IR16, "ir16", "", SRIDX(1, 10, 0), NDS32_REG_TYPE_IR, 32); - nds32_reg_set(IR17, "ir17", "", SRIDX(1, 10, 1), NDS32_REG_TYPE_IR, 32); - nds32_reg_set(IR18, "ir18", "", SRIDX(1, 11, 0), NDS32_REG_TYPE_IR, 32); - nds32_reg_set(IR19, "ir19", "", SRIDX(1, 1, 2), NDS32_REG_TYPE_IR, 32); - nds32_reg_set(IR20, "ir20", "", SRIDX(1, 10, 2), NDS32_REG_TYPE_IR, 32); - nds32_reg_set(IR21, "ir21", "", SRIDX(1, 10, 3), NDS32_REG_TYPE_IR, 32); - nds32_reg_set(IR22, "ir22", "", SRIDX(1, 10, 4), NDS32_REG_TYPE_IR, 32); - nds32_reg_set(IR23, "ir23", "", SRIDX(1, 10, 5), NDS32_REG_TYPE_IR, 32); - nds32_reg_set(IR24, "ir24", "", SRIDX(1, 10, 6), NDS32_REG_TYPE_IR, 32); - nds32_reg_set(IR25, "ir25", "", SRIDX(1, 10, 7), NDS32_REG_TYPE_IR, 32); - nds32_reg_set(IR26, "ir26", "", SRIDX(1, 8, 1), NDS32_REG_TYPE_IR, 32); - nds32_reg_set(IR27, "ir27", "", SRIDX(1, 9, 1), NDS32_REG_TYPE_IR, 32); - nds32_reg_set(IR28, "ir28", "", SRIDX(1, 11, 1), NDS32_REG_TYPE_IR, 32); - nds32_reg_set(IR29, "ir29", "", SRIDX(1, 9, 4), NDS32_REG_TYPE_IR, 32); - nds32_reg_set(IR30, "ir30", "", SRIDX(1, 1, 3), NDS32_REG_TYPE_IR, 32); - - nds32_reg_set(MR0, "mr0", "MMU_CTL", SRIDX(2, 0, 0), NDS32_REG_TYPE_MR, 32); - nds32_reg_set(MR1, "mr1", "L1_PPTB", SRIDX(2, 1, 0), NDS32_REG_TYPE_MR, 32); - nds32_reg_set(MR2, "mr2", "TLB_VPN", SRIDX(2, 2, 0), NDS32_REG_TYPE_MR, 32); - nds32_reg_set(MR3, "mr3", "TLB_DATA", SRIDX(2, 3, 0), NDS32_REG_TYPE_MR, 32); - nds32_reg_set(MR4, "mr4", "TLB_MISC", SRIDX(2, 4, 0), NDS32_REG_TYPE_MR, 32); - nds32_reg_set(MR5, "mr5", "VLPT_IDX", SRIDX(2, 5, 0), NDS32_REG_TYPE_MR, 32); - nds32_reg_set(MR6, "mr6", "ILMB", SRIDX(2, 6, 0), NDS32_REG_TYPE_MR, 32); - nds32_reg_set(MR7, "mr7", "DLMB", SRIDX(2, 7, 0), NDS32_REG_TYPE_MR, 32); - nds32_reg_set(MR8, "mr8", "CACHE_CTL", SRIDX(2, 8, 0), NDS32_REG_TYPE_MR, 32); - nds32_reg_set(MR9, "mr9", "HSMP_SADDR", SRIDX(2, 9, 0), NDS32_REG_TYPE_MR, 32); - nds32_reg_set(MR10, "mr10", "HSMP_EADDR", SRIDX(2, 9, 1), NDS32_REG_TYPE_MR, 32); - nds32_reg_set(MR11, "mr11", "", SRIDX(2, 0, 1), NDS32_REG_TYPE_MR, 32); - - nds32_reg_set(DR0, "dr0", "BPC0", SRIDX(3, 0, 0), NDS32_REG_TYPE_DR, 32); - nds32_reg_set(DR1, "dr1", "BPA0", SRIDX(3, 1, 0), NDS32_REG_TYPE_DR, 32); - nds32_reg_set(DR2, "dr2", "BPAM0", SRIDX(3, 2, 0), NDS32_REG_TYPE_DR, 32); - nds32_reg_set(DR3, "dr3", "BPV0", SRIDX(3, 3, 0), NDS32_REG_TYPE_DR, 32); - nds32_reg_set(DR4, "dr4", "BPCID0", SRIDX(3, 4, 0), NDS32_REG_TYPE_DR, 32); - nds32_reg_set(DR5, "dr5", "BPC1", SRIDX(3, 0, 1), NDS32_REG_TYPE_DR, 32); - nds32_reg_set(DR6, "dr6", "BPA1", SRIDX(3, 1, 1), NDS32_REG_TYPE_DR, 32); - nds32_reg_set(DR7, "dr7", "BPAM1", SRIDX(3, 2, 1), NDS32_REG_TYPE_DR, 32); - nds32_reg_set(DR8, "dr8", "BPV1", SRIDX(3, 3, 1), NDS32_REG_TYPE_DR, 32); - nds32_reg_set(DR9, "dr9", "BPCID1", SRIDX(3, 4, 1), NDS32_REG_TYPE_DR, 32); - nds32_reg_set(DR10, "dr10", "BPC2", SRIDX(3, 0, 2), NDS32_REG_TYPE_DR, 32); - nds32_reg_set(DR11, "dr11", "BPA2", SRIDX(3, 1, 2), NDS32_REG_TYPE_DR, 32); - nds32_reg_set(DR12, "dr12", "BPAM2", SRIDX(3, 2, 2), NDS32_REG_TYPE_DR, 32); - nds32_reg_set(DR13, "dr13", "BPV2", SRIDX(3, 3, 2), NDS32_REG_TYPE_DR, 32); - nds32_reg_set(DR14, "dr14", "BPCID2", SRIDX(3, 4, 2), NDS32_REG_TYPE_DR, 32); - nds32_reg_set(DR15, "dr15", "BPC3", SRIDX(3, 0, 3), NDS32_REG_TYPE_DR, 32); - nds32_reg_set(DR16, "dr16", "BPA3", SRIDX(3, 1, 3), NDS32_REG_TYPE_DR, 32); - nds32_reg_set(DR17, "dr17", "BPAM3", SRIDX(3, 2, 3), NDS32_REG_TYPE_DR, 32); - nds32_reg_set(DR18, "dr18", "BPV3", SRIDX(3, 3, 3), NDS32_REG_TYPE_DR, 32); - nds32_reg_set(DR19, "dr19", "BPCID3", SRIDX(3, 4, 3), NDS32_REG_TYPE_DR, 32); - nds32_reg_set(DR20, "dr20", "BPC4", SRIDX(3, 0, 4), NDS32_REG_TYPE_DR, 32); - nds32_reg_set(DR21, "dr21", "BPA4", SRIDX(3, 1, 4), NDS32_REG_TYPE_DR, 32); - nds32_reg_set(DR22, "dr22", "BPAM4", SRIDX(3, 2, 4), NDS32_REG_TYPE_DR, 32); - nds32_reg_set(DR23, "dr23", "BPV4", SRIDX(3, 3, 4), NDS32_REG_TYPE_DR, 32); - nds32_reg_set(DR24, "dr24", "BPCID4", SRIDX(3, 4, 4), NDS32_REG_TYPE_DR, 32); - nds32_reg_set(DR25, "dr25", "BPC5", SRIDX(3, 0, 5), NDS32_REG_TYPE_DR, 32); - nds32_reg_set(DR26, "dr26", "BPA5", SRIDX(3, 1, 5), NDS32_REG_TYPE_DR, 32); - nds32_reg_set(DR27, "dr27", "BPAM5", SRIDX(3, 2, 5), NDS32_REG_TYPE_DR, 32); - nds32_reg_set(DR28, "dr28", "BPV5", SRIDX(3, 3, 5), NDS32_REG_TYPE_DR, 32); - nds32_reg_set(DR29, "dr29", "BPCID5", SRIDX(3, 4, 5), NDS32_REG_TYPE_DR, 32); - nds32_reg_set(DR30, "dr30", "BPC6", SRIDX(3, 0, 6), NDS32_REG_TYPE_DR, 32); - nds32_reg_set(DR31, "dr31", "BPA6", SRIDX(3, 1, 6), NDS32_REG_TYPE_DR, 32); - nds32_reg_set(DR32, "dr32", "BPAM6", SRIDX(3, 2, 6), NDS32_REG_TYPE_DR, 32); - nds32_reg_set(DR33, "dr33", "BPV6", SRIDX(3, 3, 6), NDS32_REG_TYPE_DR, 32); - nds32_reg_set(DR34, "dr34", "BPCID6", SRIDX(3, 4, 6), NDS32_REG_TYPE_DR, 32); - nds32_reg_set(DR35, "dr35", "BPC7", SRIDX(3, 0, 7), NDS32_REG_TYPE_DR, 32); - nds32_reg_set(DR36, "dr36", "BPA7", SRIDX(3, 1, 7), NDS32_REG_TYPE_DR, 32); - nds32_reg_set(DR37, "dr37", "BPAM7", SRIDX(3, 2, 7), NDS32_REG_TYPE_DR, 32); - nds32_reg_set(DR38, "dr38", "BPV7", SRIDX(3, 3, 7), NDS32_REG_TYPE_DR, 32); - nds32_reg_set(DR39, "dr39", "BPCID7", SRIDX(3, 4, 7), NDS32_REG_TYPE_DR, 32); - nds32_reg_set(DR40, "dr40", "EDM_CFG", SRIDX(3, 5, 0), NDS32_REG_TYPE_DR, 32); - nds32_reg_set(DR41, "dr41", "EDMSW", SRIDX(3, 6, 0), NDS32_REG_TYPE_DR, 32); - nds32_reg_set(DR42, "dr42", "EDM_CTL", SRIDX(3, 7, 0), NDS32_REG_TYPE_DR, 32); - nds32_reg_set(DR43, "dr43", "EDM_DTR", SRIDX(3, 8, 0), NDS32_REG_TYPE_DR, 32); - nds32_reg_set(DR44, "dr44", "BPMTC", SRIDX(3, 9, 0), NDS32_REG_TYPE_DR, 32); - nds32_reg_set(DR45, "dr45", "DIMBR", SRIDX(3, 10, 0), NDS32_REG_TYPE_DR, 32); - nds32_reg_set(DR46, "dr46", "TECR0", SRIDX(3, 14, 0), NDS32_REG_TYPE_DR, 32); - nds32_reg_set(DR47, "dr47", "TECR1", SRIDX(3, 14, 1), NDS32_REG_TYPE_DR, 32); - nds32_reg_set(DR48, "dr48", "", SRIDX(3, 11, 0), NDS32_REG_TYPE_DR, 32); - - nds32_reg_set(PFR0, "pfr0", "PFMC0", SRIDX(4, 0, 0), NDS32_REG_TYPE_PFR, 32); - nds32_reg_set(PFR1, "pfr1", "PFMC1", SRIDX(4, 0, 1), NDS32_REG_TYPE_PFR, 32); - nds32_reg_set(PFR2, "pfr2", "PFMC2", SRIDX(4, 0, 2), NDS32_REG_TYPE_PFR, 32); - nds32_reg_set(PFR3, "pfr3", "PFM_CTL", SRIDX(4, 1, 0), NDS32_REG_TYPE_PFR, 32); - - nds32_reg_set(DMAR0, "dmar0", "DMA_CFG", SRIDX(5, 0, 0), NDS32_REG_TYPE_DMAR, 32); - nds32_reg_set(DMAR1, "dmar1", "DMA_GCSW", SRIDX(5, 1, 0), NDS32_REG_TYPE_DMAR, 32); - nds32_reg_set(DMAR2, "dmar2", "DMA_CHNSEL", SRIDX(5, 2, 0), NDS32_REG_TYPE_DMAR, 32); - nds32_reg_set(DMAR3, "dmar3", "DMA_ACT", SRIDX(5, 3, 0), NDS32_REG_TYPE_DMAR, 32); - nds32_reg_set(DMAR4, "dmar4", "DMA_SETUP", SRIDX(5, 4, 0), NDS32_REG_TYPE_DMAR, 32); - nds32_reg_set(DMAR5, "dmar5", "DMA_ISADDR", SRIDX(5, 5, 0), NDS32_REG_TYPE_DMAR, 32); - nds32_reg_set(DMAR6, "dmar6", "DMA_ESADDR", SRIDX(5, 6, 0), NDS32_REG_TYPE_DMAR, 32); - nds32_reg_set(DMAR7, "dmar7", "DMA_TCNT", SRIDX(5, 7, 0), NDS32_REG_TYPE_DMAR, 32); - nds32_reg_set(DMAR8, "dmar8", "DMA_STATUS", SRIDX(5, 8, 0), NDS32_REG_TYPE_DMAR, 32); - nds32_reg_set(DMAR9, "dmar9", "DMA_2DSET", SRIDX(5, 9, 0), NDS32_REG_TYPE_DMAR, 32); - nds32_reg_set(DMAR10, "dmar10", "DMA_2DSCTL", SRIDX(5, 9, 1), NDS32_REG_TYPE_DMAR, 32); - - nds32_reg_set(RACR, "racr", "PRUSR_ACC_CTL", SRIDX(4, 4, 0), NDS32_REG_TYPE_RACR, 32); - nds32_reg_set(FUCPR, "fucpr", "FUCOP_CTL", SRIDX(4, 5, 0), NDS32_REG_TYPE_RACR, 32); - - nds32_reg_set(IDR0, "idr0", "SDZ_CTL", SRIDX(2, 15, 0), NDS32_REG_TYPE_IDR, 32); - nds32_reg_set(IDR1, "idr1", "MISC_CTL", SRIDX(2, 15, 1), NDS32_REG_TYPE_IDR, 32); - - nds32_reg_set(SECUR0, "secur0", "", SRIDX(6, 0, 0), NDS32_REG_TYPE_SECURE, 32); - - nds32_reg_set(D0L24, "D0L24", "D0L24", 0x10, NDS32_REG_TYPE_AUMR, 32); - nds32_reg_set(D1L24, "D1L24", "D1L24", 0x11, NDS32_REG_TYPE_AUMR, 32); - nds32_reg_set(I0, "I0", "I0", 0x0, NDS32_REG_TYPE_AUMR, 32); - nds32_reg_set(I1, "I1", "I1", 0x1, NDS32_REG_TYPE_AUMR, 32); - nds32_reg_set(I2, "I2", "I2", 0x2, NDS32_REG_TYPE_AUMR, 32); - nds32_reg_set(I3, "I3", "I3", 0x3, NDS32_REG_TYPE_AUMR, 32); - nds32_reg_set(I4, "I4", "I4", 0x4, NDS32_REG_TYPE_AUMR, 32); - nds32_reg_set(I5, "I5", "I5", 0x5, NDS32_REG_TYPE_AUMR, 32); - nds32_reg_set(I6, "I6", "I6", 0x6, NDS32_REG_TYPE_AUMR, 32); - nds32_reg_set(I7, "I7", "I7", 0x7, NDS32_REG_TYPE_AUMR, 32); - nds32_reg_set(M1, "M1", "M1", 0x9, NDS32_REG_TYPE_AUMR, 32); - nds32_reg_set(M2, "M2", "M2", 0xA, NDS32_REG_TYPE_AUMR, 32); - nds32_reg_set(M3, "M3", "M3", 0xB, NDS32_REG_TYPE_AUMR, 32); - nds32_reg_set(M5, "M5", "M5", 0xD, NDS32_REG_TYPE_AUMR, 32); - nds32_reg_set(M6, "M6", "M6", 0xE, NDS32_REG_TYPE_AUMR, 32); - nds32_reg_set(M7, "M7", "M7", 0xF, NDS32_REG_TYPE_AUMR, 32); - - nds32_reg_set(MOD, "MOD", "MOD", 0x8, NDS32_REG_TYPE_AUMR, 32); - nds32_reg_set(LBE, "LBE", "LBE", 0x18, NDS32_REG_TYPE_AUMR, 32); - nds32_reg_set(LE, "LE", "LE", 0x19, NDS32_REG_TYPE_AUMR, 32); - nds32_reg_set(LC, "LC", "LC", 0x1A, NDS32_REG_TYPE_AUMR, 32); - nds32_reg_set(ADM_VBASE, "ADM_VBASE", "ADM_VBASE", 0x1B, NDS32_REG_TYPE_AUMR, 32); - nds32_reg_set(SHFT_CTL0, "SHFT_CTL0", "SHFT_CTL0", 0x12, NDS32_REG_TYPE_AUMR, 32); - nds32_reg_set(SHFT_CTL1, "SHFT_CTL1", "SHFT_CTL1", 0x13, NDS32_REG_TYPE_AUMR, 32); - - nds32_reg_set(CB_CTL, "CB_CTL", "CB_CTL", 0x1F, NDS32_REG_TYPE_AUMR, 32); - nds32_reg_set(CBB0, "CBB0", "CBB0", 0x0, NDS32_REG_TYPE_AUMR, 32); - nds32_reg_set(CBB1, "CBB1", "CBB1", 0x1, NDS32_REG_TYPE_AUMR, 32); - nds32_reg_set(CBB2, "CBB2", "CBB2", 0x2, NDS32_REG_TYPE_AUMR, 32); - nds32_reg_set(CBB3, "CBB3", "CBB3", 0x3, NDS32_REG_TYPE_AUMR, 32); - nds32_reg_set(CBE0, "CBE0", "CBE0", 0x4, NDS32_REG_TYPE_AUMR, 32); - nds32_reg_set(CBE1, "CBE1", "CBE1", 0x5, NDS32_REG_TYPE_AUMR, 32); - nds32_reg_set(CBE2, "CBE2", "CBE2", 0x6, NDS32_REG_TYPE_AUMR, 32); - nds32_reg_set(CBE3, "CBE3", "CBE3", 0x7, NDS32_REG_TYPE_AUMR, 32); - - nds32_reg_set(FPCSR, "fpcsr", "FPCSR", 0x7, NDS32_REG_TYPE_FPU, 32); - nds32_reg_set(FPCFG, "fpcfg", "FPCFG", 0x7, NDS32_REG_TYPE_FPU, 32); - nds32_reg_set(FS0, "fs0", "FS0", 0, NDS32_REG_TYPE_FPU, 32); - nds32_reg_set(FS1, "fs1", "FS1", 1, NDS32_REG_TYPE_FPU, 32); - nds32_reg_set(FS2, "fs2", "FS2", 2, NDS32_REG_TYPE_FPU, 32); - nds32_reg_set(FS3, "fs3", "FS3", 3, NDS32_REG_TYPE_FPU, 32); - nds32_reg_set(FS4, "fs4", "FS4", 4, NDS32_REG_TYPE_FPU, 32); - nds32_reg_set(FS5, "fs5", "FS5", 5, NDS32_REG_TYPE_FPU, 32); - nds32_reg_set(FS6, "fs6", "FS6", 6, NDS32_REG_TYPE_FPU, 32); - nds32_reg_set(FS7, "fs7", "FS7", 7, NDS32_REG_TYPE_FPU, 32); - nds32_reg_set(FS8, "fs8", "FS8", 8, NDS32_REG_TYPE_FPU, 32); - nds32_reg_set(FS9, "fs9", "FS9", 9, NDS32_REG_TYPE_FPU, 32); - nds32_reg_set(FS10, "fs10", "FS10", 10, NDS32_REG_TYPE_FPU, 32); - nds32_reg_set(FS11, "fs11", "FS11", 11, NDS32_REG_TYPE_FPU, 32); - nds32_reg_set(FS12, "fs12", "FS12", 12, NDS32_REG_TYPE_FPU, 32); - nds32_reg_set(FS13, "fs13", "FS13", 13, NDS32_REG_TYPE_FPU, 32); - nds32_reg_set(FS14, "fs14", "FS14", 14, NDS32_REG_TYPE_FPU, 32); - nds32_reg_set(FS15, "fs15", "FS15", 15, NDS32_REG_TYPE_FPU, 32); - nds32_reg_set(FS16, "fs16", "FS16", 16, NDS32_REG_TYPE_FPU, 32); - nds32_reg_set(FS17, "fs17", "FS17", 17, NDS32_REG_TYPE_FPU, 32); - nds32_reg_set(FS18, "fs18", "FS18", 18, NDS32_REG_TYPE_FPU, 32); - nds32_reg_set(FS19, "fs19", "FS19", 19, NDS32_REG_TYPE_FPU, 32); - nds32_reg_set(FS20, "fs20", "FS20", 20, NDS32_REG_TYPE_FPU, 32); - nds32_reg_set(FS21, "fs21", "FS21", 21, NDS32_REG_TYPE_FPU, 32); - nds32_reg_set(FS22, "fs22", "FS22", 22, NDS32_REG_TYPE_FPU, 32); - nds32_reg_set(FS23, "fs23", "FS23", 23, NDS32_REG_TYPE_FPU, 32); - nds32_reg_set(FS24, "fs24", "FS24", 24, NDS32_REG_TYPE_FPU, 32); - nds32_reg_set(FS25, "fs25", "FS25", 25, NDS32_REG_TYPE_FPU, 32); - nds32_reg_set(FS26, "fs26", "FS26", 26, NDS32_REG_TYPE_FPU, 32); - nds32_reg_set(FS27, "fs27", "FS27", 27, NDS32_REG_TYPE_FPU, 32); - nds32_reg_set(FS28, "fs28", "FS28", 28, NDS32_REG_TYPE_FPU, 32); - nds32_reg_set(FS29, "fs29", "FS29", 29, NDS32_REG_TYPE_FPU, 32); - nds32_reg_set(FS30, "fs30", "FS30", 30, NDS32_REG_TYPE_FPU, 32); - nds32_reg_set(FS31, "fs31", "FS31", 31, NDS32_REG_TYPE_FPU, 32); - nds32_reg_set(FD0, "fd0", "FD0", 0, NDS32_REG_TYPE_FPU, 64); - nds32_reg_set(FD1, "fd1", "FD1", 1, NDS32_REG_TYPE_FPU, 64); - nds32_reg_set(FD2, "fd2", "FD2", 2, NDS32_REG_TYPE_FPU, 64); - nds32_reg_set(FD3, "fd3", "FD3", 3, NDS32_REG_TYPE_FPU, 64); - nds32_reg_set(FD4, "fd4", "FD4", 4, NDS32_REG_TYPE_FPU, 64); - nds32_reg_set(FD5, "fd5", "FD5", 5, NDS32_REG_TYPE_FPU, 64); - nds32_reg_set(FD6, "fd6", "FD6", 6, NDS32_REG_TYPE_FPU, 64); - nds32_reg_set(FD7, "fd7", "FD7", 7, NDS32_REG_TYPE_FPU, 64); - nds32_reg_set(FD8, "fd8", "FD8", 8, NDS32_REG_TYPE_FPU, 64); - nds32_reg_set(FD9, "fd9", "FD9", 9, NDS32_REG_TYPE_FPU, 64); - nds32_reg_set(FD10, "fd10", "FD10", 10, NDS32_REG_TYPE_FPU, 64); - nds32_reg_set(FD11, "fd11", "FD11", 11, NDS32_REG_TYPE_FPU, 64); - nds32_reg_set(FD12, "fd12", "FD12", 12, NDS32_REG_TYPE_FPU, 64); - nds32_reg_set(FD13, "fd13", "FD13", 13, NDS32_REG_TYPE_FPU, 64); - nds32_reg_set(FD14, "fd14", "FD14", 14, NDS32_REG_TYPE_FPU, 64); - nds32_reg_set(FD15, "fd15", "FD15", 15, NDS32_REG_TYPE_FPU, 64); - nds32_reg_set(FD16, "fd16", "FD16", 16, NDS32_REG_TYPE_FPU, 64); - nds32_reg_set(FD17, "fd17", "FD17", 17, NDS32_REG_TYPE_FPU, 64); - nds32_reg_set(FD18, "fd18", "FD18", 18, NDS32_REG_TYPE_FPU, 64); - nds32_reg_set(FD19, "fd19", "FD19", 19, NDS32_REG_TYPE_FPU, 64); - nds32_reg_set(FD20, "fd20", "FD20", 20, NDS32_REG_TYPE_FPU, 64); - nds32_reg_set(FD21, "fd21", "FD21", 21, NDS32_REG_TYPE_FPU, 64); - nds32_reg_set(FD22, "fd22", "FD22", 22, NDS32_REG_TYPE_FPU, 64); - nds32_reg_set(FD23, "fd23", "FD23", 23, NDS32_REG_TYPE_FPU, 64); - nds32_reg_set(FD24, "fd24", "FD24", 24, NDS32_REG_TYPE_FPU, 64); - nds32_reg_set(FD25, "fd25", "FD25", 25, NDS32_REG_TYPE_FPU, 64); - nds32_reg_set(FD26, "fd26", "FD26", 26, NDS32_REG_TYPE_FPU, 64); - nds32_reg_set(FD27, "fd27", "FD27", 27, NDS32_REG_TYPE_FPU, 64); - nds32_reg_set(FD28, "fd28", "FD28", 28, NDS32_REG_TYPE_FPU, 64); - nds32_reg_set(FD29, "fd29", "FD29", 29, NDS32_REG_TYPE_FPU, 64); - nds32_reg_set(FD30, "fd30", "FD30", 30, NDS32_REG_TYPE_FPU, 64); - nds32_reg_set(FD31, "fd31", "FD31", 31, NDS32_REG_TYPE_FPU, 64); - - nds32_reg_init_done = true; -} - -uint32_t nds32_reg_sr_index(uint32_t number) -{ - return nds32_regs[number].sr_index; -} - -enum nds32_reg_type_s nds32_reg_type(uint32_t number) -{ - return nds32_regs[number].type; -} - -uint8_t nds32_reg_size(uint32_t number) -{ - return nds32_regs[number].size; -} - -const char *nds32_reg_simple_name(uint32_t number) -{ - return nds32_regs[number].simple_mnemonic; -} - -const char *nds32_reg_symbolic_name(uint32_t number) -{ - return nds32_regs[number].symbolic_mnemonic; -} - -bool nds32_reg_exception(uint32_t number, uint32_t value) -{ - int i; - const struct nds32_reg_exception_s *ex_reg_value; - uint32_t field_value; - - i = 0; - while (nds32_ex_reg_values[i].reg_num != 0) { - ex_reg_value = nds32_ex_reg_values + i; - - if (ex_reg_value->reg_num == number) { - field_value = (value >> ex_reg_value->ex_value_bit_pos) & - ex_reg_value->ex_value_mask; - if (field_value == ex_reg_value->ex_value) { - LOG_WARNING("It will generate exceptions as setting %" PRId32 " to %s", - value, nds32_regs[number].simple_mnemonic); - return true; - } - } - - i++; - } - - return false; -} diff --git a/src/target/nds32_reg.h b/src/target/nds32_reg.h deleted file mode 100644 index 8808cd244..000000000 --- a/src/target/nds32_reg.h +++ /dev/null @@ -1,325 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2013 Andes Technology * - * Hsiangkai Wang * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 OPENOCD_TARGET_NDS32_REG_H -#define OPENOCD_TARGET_NDS32_REG_H - -#define SRIDX(a, b, c) ((a << 7) | (b << 3) | c) -#define NDS32_REGISTER_DISABLE (0x0) - -enum nds32_reg_number_s { - R0 = 0, /* general registers */ - R1, - R2, - R3, - R4, - R5, - R6, - R7, - R8, - R9, - R10, - R11, - R12, - R13, - R14, - R15, - R16, - R17, - R18, - R19, - R20, - R21, - R22, - R23, - R24, - R25, - R26, - R27, - R28, - R29, - R30, - R31, - PC, - D0LO, - D0HI, - D1LO, - D1HI, - ITB, - IFC_LP, - CR0, /* system registers */ - CR1, - CR2, - CR3, - CR4, - CR5, - CR6, - IR0, - IR1, - IR2, - IR3, - IR4, - IR5, - IR6, - IR7, - IR8, - IR9, - IR10, - IR11, - IR12, - IR13, - IR14, - IR15, - IR16, - IR17, - IR18, - IR19, - IR20, - IR21, - IR22, - IR23, - IR24, - IR25, - IR26, - IR27, - IR28, - IR29, - IR30, - MR0, - MR1, - MR2, - MR3, - MR4, - MR5, - MR6, - MR7, - MR8, - MR9, - MR10, - MR11, - DR0, - DR1, - DR2, - DR3, - DR4, - DR5, - DR6, - DR7, - DR8, - DR9, - DR10, - DR11, - DR12, - DR13, - DR14, - DR15, - DR16, - DR17, - DR18, - DR19, - DR20, - DR21, - DR22, - DR23, - DR24, - DR25, - DR26, - DR27, - DR28, - DR29, - DR30, - DR31, - DR32, - DR33, - DR34, - DR35, - DR36, - DR37, - DR38, - DR39, - DR40, - DR41, - DR42, - DR43, - DR44, - DR45, - DR46, - DR47, - DR48, - PFR0, - PFR1, - PFR2, - PFR3, - DMAR0, - DMAR1, - DMAR2, - DMAR3, - DMAR4, - DMAR5, - DMAR6, - DMAR7, - DMAR8, - DMAR9, - DMAR10, - RACR, - FUCPR, - IDR0, - IDR1, - SECUR0, - D0L24, /* audio registers */ - D1L24, - I0, - I1, - I2, - I3, - I4, - I5, - I6, - I7, - M1, - M2, - M3, - M5, - M6, - M7, - MOD, - LBE, - LE, - LC, - ADM_VBASE, - SHFT_CTL0, - SHFT_CTL1, - CB_CTL, - CBB0, - CBB1, - CBB2, - CBB3, - CBE0, - CBE1, - CBE2, - CBE3, - FPCSR, /* fpu */ - FPCFG, - FS0, - FS1, - FS2, - FS3, - FS4, - FS5, - FS6, - FS7, - FS8, - FS9, - FS10, - FS11, - FS12, - FS13, - FS14, - FS15, - FS16, - FS17, - FS18, - FS19, - FS20, - FS21, - FS22, - FS23, - FS24, - FS25, - FS26, - FS27, - FS28, - FS29, - FS30, - FS31, - FD0, - FD1, - FD2, - FD3, - FD4, - FD5, - FD6, - FD7, - FD8, - FD9, - FD10, - FD11, - FD12, - FD13, - FD14, - FD15, - FD16, - FD17, - FD18, - FD19, - FD20, - FD21, - FD22, - FD23, - FD24, - FD25, - FD26, - FD27, - FD28, - FD29, - FD30, - FD31, - - TOTAL_REG_NUM, -}; - -enum nds32_reg_type_s { - NDS32_REG_TYPE_GPR = 0, - NDS32_REG_TYPE_SPR, - NDS32_REG_TYPE_CR, - NDS32_REG_TYPE_IR, - NDS32_REG_TYPE_MR, - NDS32_REG_TYPE_DR, - NDS32_REG_TYPE_PFR, - NDS32_REG_TYPE_DMAR, - NDS32_REG_TYPE_RACR, - NDS32_REG_TYPE_IDR, - NDS32_REG_TYPE_AUMR, - NDS32_REG_TYPE_SECURE, - NDS32_REG_TYPE_FPU, -}; - -struct nds32_reg_s { - const char *simple_mnemonic; - const char *symbolic_mnemonic; - uint32_t sr_index; - enum nds32_reg_type_s type; - uint8_t size; -}; - -struct nds32_reg_exception_s { - uint32_t reg_num; - uint32_t ex_value_bit_pos; - uint32_t ex_value_mask; - uint32_t ex_value; -}; - -void nds32_reg_init(void); -uint32_t nds32_reg_sr_index(uint32_t number); -enum nds32_reg_type_s nds32_reg_type(uint32_t number); -uint8_t nds32_reg_size(uint32_t number); -const char *nds32_reg_simple_name(uint32_t number); -const char *nds32_reg_symbolic_name(uint32_t number); -bool nds32_reg_exception(uint32_t number, uint32_t value); - -#endif /* OPENOCD_TARGET_NDS32_REG_H */ diff --git a/src/target/nds32_tlb.c b/src/target/nds32_tlb.c deleted file mode 100644 index 6a91a0f88..000000000 --- a/src/target/nds32_tlb.c +++ /dev/null @@ -1,78 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2013 Andes Technology * - * Hsiangkai Wang * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 -#include "config.h" -#endif - -#include "nds32_aice.h" -#include "nds32_tlb.h" - -int nds32_probe_tlb(struct nds32 *nds32, const uint32_t virtual_address, - uint32_t *physical_address) -{ - struct target *target = nds32->target; - struct aice_port_s *aice = target_to_aice(target); - - return aice_read_tlb(aice, virtual_address, physical_address); -} - -struct page_table_walker_info_s page_table_info[PAGE_SIZE_NUM] = { - /* 4K page */ - {0xFFC00000, 20, 0x003FF000, 10, 0x00000FFF, 0xFFFFF000, 0xFFFFF000, 0xFFFFF000}, - /* 8K page */ - {0xFF000000, 22, 0x00FFE000, 11, 0x00001FFF, 0xFFFFF000, 0xFFFFE000, 0xFFFFE000}, -}; - -int nds32_walk_page_table(struct nds32 *nds32, const uint32_t virtual_address, - uint32_t *physical_address) -{ - struct target *target = nds32->target; - uint32_t value_mr1; - uint32_t load_address; - uint32_t L1_page_table_entry; - uint32_t L2_page_table_entry; - uint32_t page_size_index = nds32->mmu_config.default_min_page_size; - struct page_table_walker_info_s *page_table_info_p = - &(page_table_info[page_size_index]); - - /* Read L1 Physical Page Table */ - nds32_get_mapped_reg(nds32, MR1, &value_mr1); - load_address = (value_mr1 & page_table_info_p->L1_base_mask) | - ((virtual_address & page_table_info_p->L1_offset_mask) >> - page_table_info_p->L1_offset_shift); - /* load_address is physical address */ - nds32_read_buffer(target, load_address, 4, (uint8_t *)&L1_page_table_entry); - - /* Read L2 Physical Page Table */ - if (L1_page_table_entry & 0x1) /* L1_PTE not present */ - return ERROR_FAIL; - - load_address = (L1_page_table_entry & page_table_info_p->L2_base_mask) | - ((virtual_address & page_table_info_p->L2_offset_mask) >> - page_table_info_p->L2_offset_shift); - /* load_address is physical address */ - nds32_read_buffer(target, load_address, 4, (uint8_t *)&L2_page_table_entry); - - if ((L2_page_table_entry & 0x1) != 0x1) /* L2_PTE not valid */ - return ERROR_FAIL; - - *physical_address = (L2_page_table_entry & page_table_info_p->ppn_mask) | - (virtual_address & page_table_info_p->va_offset_mask); - - return ERROR_OK; -} diff --git a/src/target/nds32_tlb.h b/src/target/nds32_tlb.h deleted file mode 100644 index ada2c198b..000000000 --- a/src/target/nds32_tlb.h +++ /dev/null @@ -1,47 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2013 Andes Technology * - * Hsiangkai Wang * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 OPENOCD_TARGET_NDS32_TLB_H -#define OPENOCD_TARGET_NDS32_TLB_H - -#include "nds32.h" - -enum { - PAGE_SIZE_4K = 0, - PAGE_SIZE_8K, - PAGE_SIZE_NUM, -}; - -struct page_table_walker_info_s { - - uint32_t L1_offset_mask; - uint32_t L1_offset_shift; - uint32_t L2_offset_mask; - uint32_t L2_offset_shift; - uint32_t va_offset_mask; - uint32_t L1_base_mask; - uint32_t L2_base_mask; - uint32_t ppn_mask; -}; - -extern int nds32_probe_tlb(struct nds32 *nds32, const 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); - -#endif /* OPENOCD_TARGET_NDS32_TLB_H */ diff --git a/src/target/nds32_v2.c b/src/target/nds32_v2.c deleted file mode 100644 index da8bbbc95..000000000 --- a/src/target/nds32_v2.c +++ /dev/null @@ -1,785 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2013 Andes Technology * - * Hsiangkai Wang * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 -#include "config.h" -#endif - -#include -#include -#include "breakpoints.h" -#include "nds32_insn.h" -#include "nds32_reg.h" -#include "nds32_edm.h" -#include "nds32_cmd.h" -#include "nds32_v2.h" -#include "nds32_aice.h" -#include "target_type.h" - -static int nds32_v2_register_mapping(struct nds32 *nds32, int reg_no) -{ - uint32_t max_level = nds32->max_interrupt_level; - uint32_t cur_level = nds32->current_interrupt_level; - - if ((1 <= cur_level) && (cur_level < max_level)) { - if (IR0 == reg_no) { - LOG_DEBUG("Map PSW to IPSW"); - return IR1; - } else if (PC == reg_no) { - LOG_DEBUG("Map PC to IPC"); - return IR9; - } - } else if ((2 <= cur_level) && (cur_level < max_level)) { - if (R26 == reg_no) { - LOG_DEBUG("Mapping P0 to P_P0"); - return IR12; - } else if (R27 == reg_no) { - LOG_DEBUG("Mapping P1 to P_P1"); - return IR13; - } else if (IR1 == reg_no) { - LOG_DEBUG("Mapping IPSW to P_IPSW"); - return IR2; - } else if (IR4 == reg_no) { - LOG_DEBUG("Mapping EVA to P_EVA"); - return IR5; - } else if (IR6 == reg_no) { - LOG_DEBUG("Mapping ITYPE to P_ITYPE"); - return IR7; - } else if (IR9 == reg_no) { - LOG_DEBUG("Mapping IPC to P_IPC"); - return IR10; - } - } else if (cur_level == max_level) { - if (PC == reg_no) { - LOG_DEBUG("Mapping PC to O_IPC"); - return IR11; - } - } - - return reg_no; -} - -static int nds32_v2_get_debug_reason(struct nds32 *nds32, uint32_t *reason) -{ - uint32_t val_itype; - struct aice_port_s *aice = target_to_aice(nds32->target); - - aice_read_register(aice, IR6, &val_itype); - - *reason = val_itype & 0x0F; - - return ERROR_OK; -} - -static int nds32_v2_activate_hardware_breakpoint(struct target *target) -{ - struct nds32_v2_common *nds32_v2 = target_to_nds32_v2(target); - struct aice_port_s *aice = target_to_aice(target); - struct breakpoint *bp; - int32_t hbr_index = 0; - - for (bp = target->breakpoints; bp; bp = bp->next) { - if (bp->type == BKPT_SOFT) { - /* already set at nds32_v2_add_breakpoint() */ - continue; - } else if (bp->type == BKPT_HARD) { - /* set address */ - aice_write_debug_reg(aice, NDS_EDM_SR_BPA0 + hbr_index, bp->address); - /* set mask */ - aice_write_debug_reg(aice, NDS_EDM_SR_BPAM0 + hbr_index, 0); - /* set value */ - aice_write_debug_reg(aice, NDS_EDM_SR_BPV0 + hbr_index, 0); - - if (nds32_v2->nds32.memory.address_translation) - /* enable breakpoint (virtual address) */ - aice_write_debug_reg(aice, NDS_EDM_SR_BPC0 + hbr_index, 0x2); - else - /* enable breakpoint (physical address) */ - aice_write_debug_reg(aice, NDS_EDM_SR_BPC0 + hbr_index, 0xA); - - LOG_DEBUG("Add hardware BP %" PRId32 " at %08" PRIx32, hbr_index, - bp->address); - - hbr_index++; - } else { - return ERROR_FAIL; - } - } - - return ERROR_OK; -} - -static int nds32_v2_deactivate_hardware_breakpoint(struct target *target) -{ - struct aice_port_s *aice = target_to_aice(target); - struct breakpoint *bp; - int32_t hbr_index = 0; - - for (bp = target->breakpoints; bp; bp = bp->next) { - if (bp->type == BKPT_SOFT) - continue; - else if (bp->type == BKPT_HARD) - /* disable breakpoint */ - aice_write_debug_reg(aice, NDS_EDM_SR_BPC0 + hbr_index, 0x0); - else - return ERROR_FAIL; - - LOG_DEBUG("Remove hardware BP %" PRId32 " at %08" PRIx32, hbr_index, - bp->address); - - hbr_index++; - } - - return ERROR_OK; -} - -static int nds32_v2_activate_hardware_watchpoint(struct target *target) -{ - struct aice_port_s *aice = target_to_aice(target); - struct nds32_v2_common *nds32_v2 = target_to_nds32_v2(target); - struct watchpoint *wp; - int32_t wp_num = nds32_v2->next_hbr_index; - uint32_t wp_config = 0; - - for (wp = target->watchpoints; wp; wp = wp->next) { - - wp_num--; - wp->mask = wp->length - 1; - if ((wp->address % wp->length) != 0) - wp->mask = (wp->mask << 1) + 1; - - if (wp->rw == WPT_READ) - wp_config = 0x3; - else if (wp->rw == WPT_WRITE) - wp_config = 0x5; - else if (wp->rw == WPT_ACCESS) - wp_config = 0x7; - - /* set/unset physical address bit of BPCn according to PSW.DT */ - if (nds32_v2->nds32.memory.address_translation == false) - wp_config |= 0x8; - - /* set address */ - aice_write_debug_reg(aice, NDS_EDM_SR_BPA0 + wp_num, - wp->address - (wp->address % wp->length)); - /* set mask */ - aice_write_debug_reg(aice, NDS_EDM_SR_BPAM0 + wp_num, wp->mask); - /* enable watchpoint */ - aice_write_debug_reg(aice, NDS_EDM_SR_BPC0 + wp_num, wp_config); - /* set value */ - aice_write_debug_reg(aice, NDS_EDM_SR_BPV0 + wp_num, 0); - - LOG_DEBUG("Add hardware wathcpoint %" PRId32 " at %08" PRIx32 " mask %08" PRIx32, wp_num, - wp->address, wp->mask); - - } - - return ERROR_OK; -} - -static int nds32_v2_deactivate_hardware_watchpoint(struct target *target) -{ - struct aice_port_s *aice = target_to_aice(target); - struct nds32_v2_common *nds32_v2 = target_to_nds32_v2(target); - int32_t wp_num = nds32_v2->next_hbr_index; - struct watchpoint *wp; - - for (wp = target->watchpoints; wp; wp = wp->next) { - wp_num--; - /* disable watchpoint */ - aice_write_debug_reg(aice, NDS_EDM_SR_BPC0 + wp_num, 0x0); - - LOG_DEBUG("Remove hardware wathcpoint %" PRId32 " at %08" PRIx32 " mask %08" PRIx32, - wp_num, wp->address, wp->mask); - } - - return ERROR_OK; -} - -static int nds32_v2_check_interrupt_stack(struct nds32_v2_common *nds32_v2) -{ - struct nds32 *nds32 = &(nds32_v2->nds32); - struct aice_port_s *aice = target_to_aice(nds32->target); - uint32_t val_ir0; - uint32_t val_ir1; - uint32_t val_ir2; - uint32_t modified_psw; - - /* Save interrupt level */ - aice_read_register(aice, IR0, &val_ir0); /* get $IR0 directly */ - - /* backup $IR0 */ - nds32_v2->backup_ir0 = val_ir0; - - nds32->current_interrupt_level = (val_ir0 >> 1) & 0x3; - - if (nds32_reach_max_interrupt_level(nds32)) { - LOG_ERROR("<-- TARGET ERROR! Reaching the max interrupt stack level %" PRIu32 ". -->", - nds32->current_interrupt_level); - - /* decrease interrupt level */ - modified_psw = val_ir0 - 0x2; - - /* disable GIE, IT, DT, HSS */ - modified_psw &= (~0x8C1); - - aice_write_register(aice, IR0, modified_psw); - - return ERROR_OK; - } - - /* There is a case that single step also trigger another interrupt, - then HSS bit in psw(ir0) will push to ipsw(ir1). - Then hit debug interrupt HSS bit in ipsw(ir1) will push to (p_ipsw)ir2 - Therefore, HSS bit in p_ipsw(ir2) also need clear. - - Only update $ir2 as current interrupt level is 2, because $ir2 will be random - value if the target never reaches interrupt level 2. */ - if ((nds32->max_interrupt_level == 3) && (nds32->current_interrupt_level == 2)) { - aice_read_register(aice, IR2, &val_ir2); /* get $IR2 directly */ - val_ir2 &= ~(0x01 << 11); - aice_write_register(aice, IR2, val_ir2); - } - - /* get origianl DT bit and set to current state let debugger has same memory view - PSW.IT MUST be turned off. Otherwise, DIM could not operate normally. */ - aice_read_register(aice, IR1, &val_ir1); - modified_psw = val_ir0 | (val_ir1 & 0x80); - aice_write_register(aice, IR0, modified_psw); - - return ERROR_OK; -} - -static int nds32_v2_restore_interrupt_stack(struct nds32_v2_common *nds32_v2) -{ - struct nds32 *nds32 = &(nds32_v2->nds32); - struct aice_port_s *aice = target_to_aice(nds32->target); - - /* restore origin $IR0 */ - aice_write_register(aice, IR0, nds32_v2->backup_ir0); - - return ERROR_OK; -} - -/** - * Save processor state. This is called after a HALT instruction - * succeeds, and on other occasions the processor enters debug mode - * (breakpoint, watchpoint, etc). - */ -static int nds32_v2_debug_entry(struct nds32 *nds32, bool enable_watchpoint) -{ - LOG_DEBUG("nds32_v2_debug_entry"); - - if (nds32->virtual_hosting) - LOG_WARNING("<-- TARGET WARNING! Virtual hosting is not supported " - "under V1/V2 architecture. -->"); - - enum target_state backup_state = nds32->target->state; - nds32->target->state = TARGET_HALTED; - - if (nds32->init_arch_info_after_halted == false) { - /* init architecture info according to config registers */ - CHECK_RETVAL(nds32_config(nds32)); - - nds32->init_arch_info_after_halted = true; - } - - /* REVISIT entire cache should already be invalid !!! */ - register_cache_invalidate(nds32->core_cache); - - /* deactivate all hardware breakpoints */ - CHECK_RETVAL(nds32_v2_deactivate_hardware_breakpoint(nds32->target)); - - if (enable_watchpoint) - CHECK_RETVAL(nds32_v2_deactivate_hardware_watchpoint(nds32->target)); - - if (ERROR_OK != nds32_examine_debug_reason(nds32)) { - nds32->target->state = backup_state; - - /* re-activate all hardware breakpoints & watchpoints */ - CHECK_RETVAL(nds32_v2_activate_hardware_breakpoint(nds32->target)); - - if (enable_watchpoint) { - /* activate all watchpoints */ - CHECK_RETVAL(nds32_v2_activate_hardware_watchpoint(nds32->target)); - } - - return ERROR_FAIL; - } - - /* check interrupt level before .full_context(), because - * get_mapped_reg() in nds32_full_context() needs current_interrupt_level - * information */ - struct nds32_v2_common *nds32_v2 = target_to_nds32_v2(nds32->target); - nds32_v2_check_interrupt_stack(nds32_v2); - - /* Save registers. */ - nds32_full_context(nds32); - - return ERROR_OK; -} - -/* target request support */ -static int nds32_v2_target_request_data(struct target *target, - uint32_t size, uint8_t *buffer) -{ - /* AndesCore could use DTR register to communicate with OpenOCD - * to output messages - * Target data will be put in buffer - * The format of DTR is as follow - * DTR[31:16] => length, DTR[15:8] => size, DTR[7:0] => target_req_cmd - * target_req_cmd has three possible values: - * TARGET_REQ_TRACEMSG - * TARGET_REQ_DEBUGMSG - * TARGET_REQ_DEBUGCHAR - * if size == 0, target will call target_asciimsg(), - * else call target_hexmsg() - */ - LOG_WARNING("Not implemented: %s", __func__); - - return ERROR_OK; -} - -/** - * Restore processor state. - */ -static int nds32_v2_leave_debug_state(struct nds32 *nds32, bool enable_watchpoint) -{ - LOG_DEBUG("nds32_v2_leave_debug_state"); - - struct target *target = nds32->target; - - /* activate all hardware breakpoints */ - CHECK_RETVAL(nds32_v2_activate_hardware_breakpoint(nds32->target)); - - if (enable_watchpoint) { - /* activate all watchpoints */ - CHECK_RETVAL(nds32_v2_activate_hardware_watchpoint(nds32->target)); - } - - /* restore interrupt stack */ - struct nds32_v2_common *nds32_v2 = target_to_nds32_v2(nds32->target); - nds32_v2_restore_interrupt_stack(nds32_v2); - - /* restore PSW, PC, and R0 ... after flushing any modified - * registers. - */ - CHECK_RETVAL(nds32_restore_context(target)); - - register_cache_invalidate(nds32->core_cache); - - return ERROR_OK; -} - -static int nds32_v2_deassert_reset(struct target *target) -{ - int retval; - - CHECK_RETVAL(nds32_poll(target)); - - if (target->state != TARGET_HALTED) { - /* reset only */ - LOG_WARNING("%s: ran after reset and before halt ...", - target_name(target)); - retval = target_halt(target); - if (retval != ERROR_OK) - return retval; - } - - return ERROR_OK; -} - -static int nds32_v2_checksum_memory(struct target *target, - uint32_t address, uint32_t count, uint32_t *checksum) -{ - LOG_WARNING("Not implemented: %s", __func__); - - return ERROR_FAIL; -} - -static int nds32_v2_add_breakpoint(struct target *target, - struct breakpoint *breakpoint) -{ - struct nds32_v2_common *nds32_v2 = target_to_nds32_v2(target); - struct nds32 *nds32 = &(nds32_v2->nds32); - int result; - - if (breakpoint->type == BKPT_HARD) { - /* check hardware resource */ - if (nds32_v2->n_hbr <= nds32_v2->next_hbr_index) { - LOG_WARNING("<-- TARGET WARNING! Insert too many hardware " - "breakpoints/watchpoints! The limit of " - "combined hardware breakpoints/watchpoints " - "is %" PRId32 ". -->", nds32_v2->n_hbr); - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - } - - /* update next place to put hardware breakpoint */ - nds32_v2->next_hbr_index++; - - /* hardware breakpoint insertion occurs before 'continue' actually */ - return ERROR_OK; - } else if (breakpoint->type == BKPT_SOFT) { - result = nds32_add_software_breakpoint(target, breakpoint); - if (ERROR_OK != result) { - /* auto convert to hardware breakpoint if failed */ - if (nds32->auto_convert_hw_bp) { - /* convert to hardware breakpoint */ - breakpoint->type = BKPT_HARD; - - return nds32_v2_add_breakpoint(target, breakpoint); - } - } - - return result; - } else /* unrecognized breakpoint type */ - return ERROR_FAIL; - - return ERROR_OK; -} - -static int nds32_v2_remove_breakpoint(struct target *target, - struct breakpoint *breakpoint) -{ - struct nds32_v2_common *nds32_v2 = target_to_nds32_v2(target); - - if (breakpoint->type == BKPT_HARD) { - if (nds32_v2->next_hbr_index <= 0) - return ERROR_FAIL; - - /* update next place to put hardware breakpoint */ - nds32_v2->next_hbr_index--; - - /* hardware breakpoint removal occurs after 'halted' actually */ - return ERROR_OK; - } else if (breakpoint->type == BKPT_SOFT) { - return nds32_remove_software_breakpoint(target, breakpoint); - } else /* unrecognized breakpoint type */ - return ERROR_FAIL; - - return ERROR_OK; -} - -static int nds32_v2_add_watchpoint(struct target *target, - struct watchpoint *watchpoint) -{ - struct nds32_v2_common *nds32_v2 = target_to_nds32_v2(target); - - /* check hardware resource */ - if (nds32_v2->n_hbr <= nds32_v2->next_hbr_index) { - LOG_WARNING("<-- TARGET WARNING! Insert too many hardware " - "breakpoints/watchpoints! The limit of " - "combined hardware breakpoints/watchpoints is %" PRId32 ". -->", nds32_v2->n_hbr); - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - } - - /* update next place to put hardware watchpoint */ - nds32_v2->next_hbr_index++; - - return ERROR_OK; -} - -static int nds32_v2_remove_watchpoint(struct target *target, - struct watchpoint *watchpoint) -{ - struct nds32_v2_common *nds32_v2 = target_to_nds32_v2(target); - - if (nds32_v2->next_hbr_index <= 0) - return ERROR_FAIL; - - /* update next place to put hardware breakpoint */ - nds32_v2->next_hbr_index--; - - return ERROR_OK; -} - -static int nds32_v2_get_exception_address(struct nds32 *nds32, - uint32_t *address, uint32_t reason) -{ - struct aice_port_s *aice = target_to_aice(nds32->target); - - aice_read_register(aice, IR4, address); /* read $EVA directly */ - - /* TODO: hit multiple watchpoints */ - - return ERROR_OK; -} - -/** - * find out which watchpoint hits - * get exception address and compare the address to watchpoints - */ -static int nds32_v2_hit_watchpoint(struct target *target, - struct watchpoint **hit_watchpoint) -{ - uint32_t exception_address; - struct watchpoint *wp; - static struct watchpoint scan_all_watchpoint; - struct nds32 *nds32 = target_to_nds32(target); - - scan_all_watchpoint.address = 0; - scan_all_watchpoint.rw = WPT_WRITE; - scan_all_watchpoint.next = 0; - scan_all_watchpoint.unique_id = 0x5CA8; - - exception_address = nds32->watched_address; - - if (exception_address == 0) { - /* send watch:0 to tell GDB to do software scan for hitting multiple watchpoints */ - *hit_watchpoint = &scan_all_watchpoint; - return ERROR_OK; - } - - for (wp = target->watchpoints; wp; wp = wp->next) { - if (((exception_address ^ wp->address) & (~wp->mask)) == 0) { - /* TODO: dispel false match */ - *hit_watchpoint = wp; - return ERROR_OK; - } - } - - return ERROR_FAIL; -} - -static int nds32_v2_run_algorithm(struct target *target, - int num_mem_params, - struct mem_param *mem_params, - int num_reg_params, - struct reg_param *reg_params, - uint32_t entry_point, - uint32_t exit_point, - int timeout_ms, - void *arch_info) -{ - LOG_WARNING("Not implemented: %s", __func__); - - return ERROR_FAIL; -} - -static int nds32_v2_target_create(struct target *target, Jim_Interp *interp) -{ - struct nds32_v2_common *nds32_v2; - - nds32_v2 = calloc(1, sizeof(*nds32_v2)); - if (!nds32_v2) - return ERROR_FAIL; - - nds32_v2->nds32.register_map = nds32_v2_register_mapping; - nds32_v2->nds32.get_debug_reason = nds32_v2_get_debug_reason; - nds32_v2->nds32.enter_debug_state = nds32_v2_debug_entry; - nds32_v2->nds32.leave_debug_state = nds32_v2_leave_debug_state; - nds32_v2->nds32.get_watched_address = nds32_v2_get_exception_address; - - nds32_init_arch_info(target, &(nds32_v2->nds32)); - - return ERROR_OK; -} - -static int nds32_v2_init_target(struct command_context *cmd_ctx, - struct target *target) -{ - /* Initialize anything we can set up without talking to the target */ - - struct nds32 *nds32 = target_to_nds32(target); - - nds32_init(nds32); - - return ERROR_OK; -} - -/* talk to the target and set things up */ -static int nds32_v2_examine(struct target *target) -{ - struct nds32_v2_common *nds32_v2 = target_to_nds32_v2(target); - struct nds32 *nds32 = &(nds32_v2->nds32); - struct aice_port_s *aice = target_to_aice(target); - - if (!target_was_examined(target)) { - CHECK_RETVAL(nds32_edm_config(nds32)); - - if (nds32->reset_halt_as_examine) - CHECK_RETVAL(nds32_reset_halt(nds32)); - } - - uint32_t edm_cfg; - aice_read_debug_reg(aice, NDS_EDM_SR_EDM_CFG, &edm_cfg); - - /* get the number of hardware breakpoints */ - nds32_v2->n_hbr = (edm_cfg & 0x7) + 1; - - nds32_v2->next_hbr_index = 0; - - LOG_INFO("%s: total hardware breakpoint %" PRId32, target_name(target), - nds32_v2->n_hbr); - - nds32->target->state = TARGET_RUNNING; - nds32->target->debug_reason = DBG_REASON_NOTHALTED; - - target_set_examined(target); - - return ERROR_OK; -} - -static int nds32_v2_translate_address(struct target *target, uint32_t *address) -{ - struct nds32 *nds32 = target_to_nds32(target); - struct nds32_memory *memory = &(nds32->memory); - uint32_t physical_address; - - /* Following conditions need to do address translation - * 1. BUS mode - * 2. CPU mode under maximum interrupt level */ - if ((NDS_MEMORY_ACC_BUS == memory->access_channel) || - ((NDS_MEMORY_ACC_CPU == memory->access_channel) && - nds32_reach_max_interrupt_level(nds32))) { - if (ERROR_OK == target->type->virt2phys(target, *address, &physical_address)) - *address = physical_address; - else - return ERROR_FAIL; - } - - return ERROR_OK; -} - -static int nds32_v2_read_buffer(struct target *target, uint32_t address, - uint32_t size, uint8_t *buffer) -{ - struct nds32 *nds32 = target_to_nds32(target); - struct nds32_memory *memory = &(nds32->memory); - - if ((NDS_MEMORY_ACC_CPU == memory->access_channel) && - (target->state != TARGET_HALTED)) { - LOG_WARNING("target was not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - /* BUG: If access range crosses multiple pages, the translation will not correct - * for second page or so. */ - - nds32_v2_translate_address(target, &address); - - return nds32_read_buffer(target, address, size, buffer); -} - -static int nds32_v2_write_buffer(struct target *target, uint32_t address, - uint32_t size, const uint8_t *buffer) -{ - struct nds32 *nds32 = target_to_nds32(target); - struct nds32_memory *memory = &(nds32->memory); - - if ((NDS_MEMORY_ACC_CPU == memory->access_channel) && - (target->state != TARGET_HALTED)) { - LOG_WARNING("target was not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - /* BUG: If access range crosses multiple pages, the translation will not correct - * for second page or so. */ - - nds32_v2_translate_address(target, &address); - - return nds32_write_buffer(target, address, size, buffer); -} - -static int nds32_v2_read_memory(struct target *target, uint32_t address, - uint32_t size, uint32_t count, uint8_t *buffer) -{ - struct nds32 *nds32 = target_to_nds32(target); - struct nds32_memory *memory = &(nds32->memory); - - if ((NDS_MEMORY_ACC_CPU == memory->access_channel) && - (target->state != TARGET_HALTED)) { - LOG_WARNING("target was not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - /* BUG: If access range crosses multiple pages, the translation will not correct - * for second page or so. */ - - nds32_v2_translate_address(target, &address); - - return nds32_read_memory(target, address, size, count, buffer); -} - -static int nds32_v2_write_memory(struct target *target, uint32_t address, - uint32_t size, uint32_t count, const uint8_t *buffer) -{ - struct nds32 *nds32 = target_to_nds32(target); - struct nds32_memory *memory = &(nds32->memory); - - if ((NDS_MEMORY_ACC_CPU == memory->access_channel) && - (target->state != TARGET_HALTED)) { - LOG_WARNING("target was not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - /* BUG: If access range crosses multiple pages, the translation will not correct - * for second page or so. */ - - nds32_v2_translate_address(target, &address); - - return nds32_write_memory(target, address, size, count, buffer); -} - -/** Holds methods for V2 targets. */ -struct target_type nds32_v2_target = { - .name = "nds32_v2", - - .poll = nds32_poll, - .arch_state = nds32_arch_state, - - .target_request_data = nds32_v2_target_request_data, - - .halt = nds32_halt, - .resume = nds32_resume, - .step = nds32_step, - - .assert_reset = nds32_assert_reset, - .deassert_reset = nds32_v2_deassert_reset, - - /* register access */ - .get_gdb_reg_list = nds32_get_gdb_reg_list, - - /* memory access */ - .read_buffer = nds32_v2_read_buffer, - .write_buffer = nds32_v2_write_buffer, - .read_memory = nds32_v2_read_memory, - .write_memory = nds32_v2_write_memory, - - .checksum_memory = nds32_v2_checksum_memory, - - /* breakpoint/watchpoint */ - .add_breakpoint = nds32_v2_add_breakpoint, - .remove_breakpoint = nds32_v2_remove_breakpoint, - .add_watchpoint = nds32_v2_add_watchpoint, - .remove_watchpoint = nds32_v2_remove_watchpoint, - .hit_watchpoint = nds32_v2_hit_watchpoint, - - /* MMU */ - .mmu = nds32_mmu, - .virt2phys = nds32_virtual_to_physical, - .read_phys_memory = nds32_read_phys_memory, - .write_phys_memory = nds32_write_phys_memory, - - .run_algorithm = nds32_v2_run_algorithm, - - .commands = nds32_command_handlers, - .target_create = nds32_v2_target_create, - .init_target = nds32_v2_init_target, - .examine = nds32_v2_examine, -}; diff --git a/src/target/nds32_v2.h b/src/target/nds32_v2.h deleted file mode 100644 index dcc08c29e..000000000 --- a/src/target/nds32_v2.h +++ /dev/null @@ -1,42 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2013 Andes Technology * - * Hsiangkai Wang * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 OPENOCD_TARGET_NDS32_V2_H -#define OPENOCD_TARGET_NDS32_V2_H - -#include "nds32.h" - -struct nds32_v2_common { - struct nds32 nds32; - - uint32_t backup_ir0; - - /** number of hardware breakpoints */ - int32_t n_hbr; - - /** next hardware breakpoint index */ - /** increase from low index to high index */ - int32_t next_hbr_index; -}; - -static inline struct nds32_v2_common *target_to_nds32_v2(struct target *target) -{ - return container_of(target->arch_info, struct nds32_v2_common, nds32); -} - -#endif /* OPENOCD_TARGET_NDS32_V2_H */ diff --git a/src/target/nds32_v3.c b/src/target/nds32_v3.c deleted file mode 100644 index 43d7054c9..000000000 --- a/src/target/nds32_v3.c +++ /dev/null @@ -1,521 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2013 Andes Technology * - * Hsiangkai Wang * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 -#include "config.h" -#endif - -#include "breakpoints.h" -#include "nds32_cmd.h" -#include "nds32_aice.h" -#include "nds32_v3.h" -#include "nds32_v3_common.h" - -static int nds32_v3_activate_hardware_breakpoint(struct target *target) -{ - struct nds32_v3_common *nds32_v3 = target_to_nds32_v3(target); - struct aice_port_s *aice = target_to_aice(target); - struct breakpoint *bp; - int32_t hbr_index = nds32_v3->next_hbr_index; - - for (bp = target->breakpoints; bp; bp = bp->next) { - if (bp->type == BKPT_SOFT) { - /* already set at nds32_v3_add_breakpoint() */ - continue; - } else if (bp->type == BKPT_HARD) { - hbr_index--; - /* set address */ - aice_write_debug_reg(aice, NDS_EDM_SR_BPA0 + hbr_index, bp->address); - /* set mask */ - aice_write_debug_reg(aice, NDS_EDM_SR_BPAM0 + hbr_index, 0); - /* set value */ - aice_write_debug_reg(aice, NDS_EDM_SR_BPV0 + hbr_index, 0); - - if (nds32_v3->nds32.memory.address_translation) - /* enable breakpoint (virtual address) */ - aice_write_debug_reg(aice, NDS_EDM_SR_BPC0 + hbr_index, 0x2); - else - /* enable breakpoint (physical address) */ - aice_write_debug_reg(aice, NDS_EDM_SR_BPC0 + hbr_index, 0xA); - - LOG_DEBUG("Add hardware BP %" PRId32 " at %08" PRIx32, hbr_index, - bp->address); - } else { - return ERROR_FAIL; - } - } - - return ERROR_OK; -} - -static int nds32_v3_deactivate_hardware_breakpoint(struct target *target) -{ - struct nds32_v3_common *nds32_v3 = target_to_nds32_v3(target); - struct aice_port_s *aice = target_to_aice(target); - struct breakpoint *bp; - int32_t hbr_index = nds32_v3->next_hbr_index; - - for (bp = target->breakpoints; bp; bp = bp->next) { - if (bp->type == BKPT_SOFT) { - continue; - } else if (bp->type == BKPT_HARD) { - hbr_index--; - /* disable breakpoint */ - aice_write_debug_reg(aice, NDS_EDM_SR_BPC0 + hbr_index, 0x0); - } else { - return ERROR_FAIL; - } - - LOG_DEBUG("Remove hardware BP %" PRId32 " at %08" PRIx32, hbr_index, - bp->address); - } - - return ERROR_OK; -} - -static int nds32_v3_activate_hardware_watchpoint(struct target *target) -{ - struct aice_port_s *aice = target_to_aice(target); - struct nds32_v3_common *nds32_v3 = target_to_nds32_v3(target); - struct watchpoint *wp; - int32_t wp_num = 0; - uint32_t wp_config = 0; - bool ld_stop, st_stop; - - if (nds32_v3->nds32.global_stop) - ld_stop = st_stop = false; - - for (wp = target->watchpoints; wp; wp = wp->next) { - - if (wp_num < nds32_v3->used_n_wp) { - wp->mask = wp->length - 1; - if ((wp->address % wp->length) != 0) - wp->mask = (wp->mask << 1) + 1; - - if (wp->rw == WPT_READ) - wp_config = 0x3; - else if (wp->rw == WPT_WRITE) - wp_config = 0x5; - else if (wp->rw == WPT_ACCESS) - wp_config = 0x7; - - /* set/unset physical address bit of BPCn according to PSW.DT */ - if (nds32_v3->nds32.memory.address_translation == false) - wp_config |= 0x8; - - /* set address */ - aice_write_debug_reg(aice, NDS_EDM_SR_BPA0 + wp_num, - wp->address - (wp->address % wp->length)); - /* set mask */ - aice_write_debug_reg(aice, NDS_EDM_SR_BPAM0 + wp_num, wp->mask); - /* enable watchpoint */ - aice_write_debug_reg(aice, NDS_EDM_SR_BPC0 + wp_num, wp_config); - /* set value */ - aice_write_debug_reg(aice, NDS_EDM_SR_BPV0 + wp_num, 0); - - LOG_DEBUG("Add hardware wathcpoint %" PRId32 " at %08" PRIx32 " mask %08" PRIx32, - wp_num, wp->address, wp->mask); - - wp_num++; - } else if (nds32_v3->nds32.global_stop) { - if (wp->rw == WPT_READ) - ld_stop = true; - else if (wp->rw == WPT_WRITE) - st_stop = true; - else if (wp->rw == WPT_ACCESS) - ld_stop = st_stop = true; - } - } - - if (nds32_v3->nds32.global_stop) { - uint32_t edm_ctl; - aice_read_debug_reg(aice, NDS_EDM_SR_EDM_CTL, &edm_ctl); - if (ld_stop) - edm_ctl |= 0x10; - if (st_stop) - edm_ctl |= 0x20; - aice_write_debug_reg(aice, NDS_EDM_SR_EDM_CTL, edm_ctl); - } - - return ERROR_OK; -} - -static int nds32_v3_deactivate_hardware_watchpoint(struct target *target) -{ - struct aice_port_s *aice = target_to_aice(target); - struct nds32_v3_common *nds32_v3 = target_to_nds32_v3(target); - int32_t wp_num = 0; - struct watchpoint *wp; - bool clean_global_stop = false; - - for (wp = target->watchpoints; wp; wp = wp->next) { - - if (wp_num < nds32_v3->used_n_wp) { - /* disable watchpoint */ - aice_write_debug_reg(aice, NDS_EDM_SR_BPC0 + wp_num, 0x0); - - LOG_DEBUG("Remove hardware wathcpoint %" PRId32 " at %08" PRIx32 - " mask %08" PRIx32, wp_num, - wp->address, wp->mask); - wp_num++; - } else if (nds32_v3->nds32.global_stop) { - clean_global_stop = true; - } - } - - if (clean_global_stop) { - uint32_t edm_ctl; - aice_read_debug_reg(aice, NDS_EDM_SR_EDM_CTL, &edm_ctl); - edm_ctl = edm_ctl & (~0x30); - aice_write_debug_reg(aice, NDS_EDM_SR_EDM_CTL, edm_ctl); - } - - return ERROR_OK; -} - -static int nds32_v3_check_interrupt_stack(struct nds32 *nds32) -{ - uint32_t val_ir0; - uint32_t value; - - /* Save interrupt level */ - nds32_get_mapped_reg(nds32, IR0, &val_ir0); - nds32->current_interrupt_level = (val_ir0 >> 1) & 0x3; - - if (nds32_reach_max_interrupt_level(nds32)) - LOG_ERROR("<-- TARGET ERROR! Reaching the max interrupt stack level %" PRIu32 ". -->", - nds32->current_interrupt_level); - - /* backup $ir4 & $ir6 to avoid suppressed exception overwrite */ - nds32_get_mapped_reg(nds32, IR4, &value); - nds32_get_mapped_reg(nds32, IR6, &value); - - return ERROR_OK; -} - -static int nds32_v3_restore_interrupt_stack(struct nds32 *nds32) -{ - uint32_t value; - - /* get backup value from cache */ - /* then set back to make the register dirty */ - nds32_get_mapped_reg(nds32, IR0, &value); - nds32_set_mapped_reg(nds32, IR0, value); - - nds32_get_mapped_reg(nds32, IR4, &value); - nds32_set_mapped_reg(nds32, IR4, value); - - nds32_get_mapped_reg(nds32, IR6, &value); - nds32_set_mapped_reg(nds32, IR6, value); - - return ERROR_OK; -} - -static int nds32_v3_deassert_reset(struct target *target) -{ - int retval; - struct aice_port_s *aice = target_to_aice(target); - bool switch_to_v3_stack = false; - uint32_t value_edm_ctl; - - aice_read_debug_reg(aice, NDS_EDM_SR_EDM_CTL, &value_edm_ctl); - if (((value_edm_ctl >> 6) & 0x1) == 0) { /* reset to V2 EDM mode */ - aice_write_debug_reg(aice, NDS_EDM_SR_EDM_CTL, value_edm_ctl | (0x1 << 6)); - aice_read_debug_reg(aice, NDS_EDM_SR_EDM_CTL, &value_edm_ctl); - if (((value_edm_ctl >> 6) & 0x1) == 1) - switch_to_v3_stack = true; - } else - switch_to_v3_stack = false; - - CHECK_RETVAL(nds32_poll(target)); - - if (target->state != TARGET_HALTED) { - /* reset only */ - LOG_WARNING("%s: ran after reset and before halt ...", - target_name(target)); - retval = target_halt(target); - if (retval != ERROR_OK) - return retval; - - } else { - /* reset-halt */ - struct nds32_v3_common *nds32_v3 = target_to_nds32_v3(target); - struct nds32 *nds32 = &(nds32_v3->nds32); - uint32_t value; - uint32_t interrupt_level; - - if (switch_to_v3_stack == true) { - /* PSW.INTL-- */ - nds32_get_mapped_reg(nds32, IR0, &value); - interrupt_level = (value >> 1) & 0x3; - interrupt_level--; - value &= ~(0x6); - value |= (interrupt_level << 1); - value |= 0x400; /* set PSW.DEX */ - nds32_set_mapped_reg(nds32, IR0, value); - - /* copy IPC to OIPC */ - if ((interrupt_level + 1) < nds32->max_interrupt_level) { - nds32_get_mapped_reg(nds32, IR9, &value); - nds32_set_mapped_reg(nds32, IR11, value); - } - } - } - - return ERROR_OK; -} - -static int nds32_v3_add_breakpoint(struct target *target, - struct breakpoint *breakpoint) -{ - struct nds32_v3_common *nds32_v3 = target_to_nds32_v3(target); - struct nds32 *nds32 = &(nds32_v3->nds32); - int result; - - if (breakpoint->type == BKPT_HARD) { - /* check hardware resource */ - if (nds32_v3->n_hbr <= nds32_v3->next_hbr_index) { - LOG_WARNING("<-- TARGET WARNING! Insert too many " - "hardware breakpoints/watchpoints! " - "The limit of combined hardware " - "breakpoints/watchpoints is %" PRId32 ". -->", - nds32_v3->n_hbr); - LOG_WARNING("<-- TARGET STATUS: Inserted number of " - "hardware breakpoint: %" PRId32 ", hardware " - "watchpoints: %" PRId32 ". -->", - nds32_v3->next_hbr_index - nds32_v3->used_n_wp, - nds32_v3->used_n_wp); - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - } - - /* update next place to put hardware breakpoint */ - nds32_v3->next_hbr_index++; - - /* hardware breakpoint insertion occurs before 'continue' actually */ - return ERROR_OK; - } else if (breakpoint->type == BKPT_SOFT) { - result = nds32_add_software_breakpoint(target, breakpoint); - if (ERROR_OK != result) { - /* auto convert to hardware breakpoint if failed */ - if (nds32->auto_convert_hw_bp) { - /* convert to hardware breakpoint */ - breakpoint->type = BKPT_HARD; - - return nds32_v3_add_breakpoint(target, breakpoint); - } - } - - return result; - } else /* unrecognized breakpoint type */ - return ERROR_FAIL; - - return ERROR_OK; -} - -static int nds32_v3_remove_breakpoint(struct target *target, - struct breakpoint *breakpoint) -{ - struct nds32_v3_common *nds32_v3 = target_to_nds32_v3(target); - - if (breakpoint->type == BKPT_HARD) { - if (nds32_v3->next_hbr_index <= 0) - return ERROR_FAIL; - - /* update next place to put hardware breakpoint */ - nds32_v3->next_hbr_index--; - - /* hardware breakpoint removal occurs after 'halted' actually */ - return ERROR_OK; - } else if (breakpoint->type == BKPT_SOFT) { - return nds32_remove_software_breakpoint(target, breakpoint); - } else /* unrecognized breakpoint type */ - return ERROR_FAIL; - - return ERROR_OK; -} - -static int nds32_v3_add_watchpoint(struct target *target, - struct watchpoint *watchpoint) -{ - struct nds32_v3_common *nds32_v3 = target_to_nds32_v3(target); - - /* check hardware resource */ - if (nds32_v3->n_hbr <= nds32_v3->next_hbr_index) { - /* No hardware resource */ - if (nds32_v3->nds32.global_stop) { - LOG_WARNING("<-- TARGET WARNING! The number of " - "watchpoints exceeds the hardware " - "resources. Stop at every load/store " - "instruction to check for watchpoint matches. -->"); - return ERROR_OK; - } - - LOG_WARNING("<-- TARGET WARNING! Insert too many hardware " - "breakpoints/watchpoints! The limit of combined " - "hardware breakpoints/watchpoints is %" PRId32 ". -->", - nds32_v3->n_hbr); - LOG_WARNING("<-- TARGET STATUS: Inserted number of " - "hardware breakpoint: %" PRId32 ", hardware " - "watchpoints: %" PRId32 ". -->", - nds32_v3->next_hbr_index - nds32_v3->used_n_wp, - nds32_v3->used_n_wp); - - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - } - - /* update next place to put hardware watchpoint */ - nds32_v3->next_hbr_index++; - nds32_v3->used_n_wp++; - - return ERROR_OK; -} - -static int nds32_v3_remove_watchpoint(struct target *target, - struct watchpoint *watchpoint) -{ - struct nds32_v3_common *nds32_v3 = target_to_nds32_v3(target); - - if (nds32_v3->next_hbr_index <= 0) { - if (nds32_v3->nds32.global_stop) - return ERROR_OK; - - return ERROR_FAIL; - } - - /* update next place to put hardware breakpoint */ - nds32_v3->next_hbr_index--; - nds32_v3->used_n_wp--; - - return ERROR_OK; -} - -struct nds32_v3_common_callback nds32_v3_common_callback = { - .check_interrupt_stack = nds32_v3_check_interrupt_stack, - .restore_interrupt_stack = nds32_v3_restore_interrupt_stack, - .activate_hardware_breakpoint = nds32_v3_activate_hardware_breakpoint, - .activate_hardware_watchpoint = nds32_v3_activate_hardware_watchpoint, - .deactivate_hardware_breakpoint = nds32_v3_deactivate_hardware_breakpoint, - .deactivate_hardware_watchpoint = nds32_v3_deactivate_hardware_watchpoint, -}; - -static int nds32_v3_target_create(struct target *target, Jim_Interp *interp) -{ - struct nds32_v3_common *nds32_v3; - - nds32_v3 = calloc(1, sizeof(*nds32_v3)); - if (!nds32_v3) - return ERROR_FAIL; - - nds32_v3_common_register_callback(&nds32_v3_common_callback); - nds32_v3_target_create_common(target, &(nds32_v3->nds32)); - - return ERROR_OK; -} - -/* talk to the target and set things up */ -static int nds32_v3_examine(struct target *target) -{ - struct nds32_v3_common *nds32_v3 = target_to_nds32_v3(target); - struct nds32 *nds32 = &(nds32_v3->nds32); - struct aice_port_s *aice = target_to_aice(target); - - if (!target_was_examined(target)) { - CHECK_RETVAL(nds32_edm_config(nds32)); - - if (nds32->reset_halt_as_examine) - CHECK_RETVAL(nds32_reset_halt(nds32)); - } - - uint32_t edm_cfg; - aice_read_debug_reg(aice, NDS_EDM_SR_EDM_CFG, &edm_cfg); - - /* get the number of hardware breakpoints */ - nds32_v3->n_hbr = (edm_cfg & 0x7) + 1; - - /* low interference profiling */ - if (edm_cfg & 0x100) - nds32_v3->low_interference_profile = true; - else - nds32_v3->low_interference_profile = false; - - nds32_v3->next_hbr_index = 0; - nds32_v3->used_n_wp = 0; - - LOG_INFO("%s: total hardware breakpoint %" PRId32, target_name(target), - nds32_v3->n_hbr); - - nds32->target->state = TARGET_RUNNING; - nds32->target->debug_reason = DBG_REASON_NOTHALTED; - - target_set_examined(target); - - return ERROR_OK; -} - -/** Holds methods for Andes1337 targets. */ -struct target_type nds32_v3_target = { - .name = "nds32_v3", - - .poll = nds32_poll, - .arch_state = nds32_arch_state, - - .target_request_data = nds32_v3_target_request_data, - - .halt = nds32_halt, - .resume = nds32_resume, - .step = nds32_step, - - .assert_reset = nds32_assert_reset, - .deassert_reset = nds32_v3_deassert_reset, - - /* register access */ - .get_gdb_reg_list = nds32_get_gdb_reg_list, - - /* memory access */ - .read_buffer = nds32_v3_read_buffer, - .write_buffer = nds32_v3_write_buffer, - .read_memory = nds32_v3_read_memory, - .write_memory = nds32_v3_write_memory, - - .checksum_memory = nds32_v3_checksum_memory, - - /* breakpoint/watchpoint */ - .add_breakpoint = nds32_v3_add_breakpoint, - .remove_breakpoint = nds32_v3_remove_breakpoint, - .add_watchpoint = nds32_v3_add_watchpoint, - .remove_watchpoint = nds32_v3_remove_watchpoint, - .hit_watchpoint = nds32_v3_hit_watchpoint, - - /* MMU */ - .mmu = nds32_mmu, - .virt2phys = nds32_virtual_to_physical, - .read_phys_memory = nds32_read_phys_memory, - .write_phys_memory = nds32_write_phys_memory, - - .run_algorithm = nds32_v3_run_algorithm, - - .commands = nds32_command_handlers, - .target_create = nds32_v3_target_create, - .init_target = nds32_v3_init_target, - .examine = nds32_v3_examine, - - .get_gdb_fileio_info = nds32_get_gdb_fileio_info, - .gdb_fileio_end = nds32_gdb_fileio_end, - - .profiling = nds32_profiling, -}; diff --git a/src/target/nds32_v3.h b/src/target/nds32_v3.h deleted file mode 100644 index a5df8fe52..000000000 --- a/src/target/nds32_v3.h +++ /dev/null @@ -1,45 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2013 Andes Technology * - * Hsiangkai Wang * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 OPENOCD_TARGET_NDS32_V3_H -#define OPENOCD_TARGET_NDS32_V3_H - -#include "nds32.h" - -struct nds32_v3_common { - struct nds32 nds32; - - /** number of hardware breakpoints */ - int32_t n_hbr; - - /** number of used hardware watchpoints */ - int32_t used_n_wp; - - /** next hardware breakpoint index */ - int32_t next_hbr_index; - - /** low interference profiling */ - bool low_interference_profile; -}; - -static inline struct nds32_v3_common *target_to_nds32_v3(struct target *target) -{ - return container_of(target->arch_info, struct nds32_v3_common, nds32); -} - -#endif /* OPENOCD_TARGET_NDS32_V3_H */ diff --git a/src/target/nds32_v3_common.c b/src/target/nds32_v3_common.c deleted file mode 100644 index 191f4b5cc..000000000 --- a/src/target/nds32_v3_common.c +++ /dev/null @@ -1,675 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2013 Andes Technology * - * Hsiangkai Wang * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 -#include "config.h" -#endif - -#include "breakpoints.h" -#include "nds32_reg.h" -#include "nds32_disassembler.h" -#include "nds32.h" -#include "nds32_aice.h" -#include "nds32_v3_common.h" - -static struct nds32_v3_common_callback *v3_common_callback; - -static int nds32_v3_register_mapping(struct nds32 *nds32, int reg_no) -{ - if (reg_no == PC) - return IR11; - - return reg_no; -} - -static int nds32_v3_get_debug_reason(struct nds32 *nds32, uint32_t *reason) -{ - uint32_t edmsw; - struct aice_port_s *aice = target_to_aice(nds32->target); - aice_read_debug_reg(aice, NDS_EDM_SR_EDMSW, &edmsw); - - *reason = (edmsw >> 12) & 0x0F; - - return ERROR_OK; -} - -/** - * Save processor state. This is called after a HALT instruction - * succeeds, and on other occasions the processor enters debug mode - * (breakpoint, watchpoint, etc). - */ -static int nds32_v3_debug_entry(struct nds32 *nds32, bool enable_watchpoint) -{ - LOG_DEBUG("nds32_v3_debug_entry"); - - enum target_state backup_state = nds32->target->state; - nds32->target->state = TARGET_HALTED; - - if (nds32->init_arch_info_after_halted == false) { - /* init architecture info according to config registers */ - CHECK_RETVAL(nds32_config(nds32)); - - nds32->init_arch_info_after_halted = true; - } - - /* REVISIT entire cache should already be invalid !!! */ - register_cache_invalidate(nds32->core_cache); - - /* deactivate all hardware breakpoints */ - CHECK_RETVAL(v3_common_callback->deactivate_hardware_breakpoint(nds32->target)); - - if (enable_watchpoint) - CHECK_RETVAL(v3_common_callback->deactivate_hardware_watchpoint(nds32->target)); - - struct breakpoint *syscall_break = &(nds32->syscall_break); - if (nds32->virtual_hosting) { - if (syscall_break->set) { - /** disable virtual hosting */ - - /* remove breakpoint at syscall entry */ - target_remove_breakpoint(nds32->target, syscall_break); - syscall_break->set = 0; - - uint32_t value_pc; - nds32_get_mapped_reg(nds32, PC, &value_pc); - if (value_pc == syscall_break->address) - /** process syscall for virtual hosting */ - nds32->hit_syscall = true; - } - } - - if (ERROR_OK != nds32_examine_debug_reason(nds32)) { - nds32->target->state = backup_state; - - /* re-activate all hardware breakpoints & watchpoints */ - CHECK_RETVAL(v3_common_callback->activate_hardware_breakpoint(nds32->target)); - - if (enable_watchpoint) - CHECK_RETVAL(v3_common_callback->activate_hardware_watchpoint(nds32->target)); - - return ERROR_FAIL; - } - - /* Save registers. */ - nds32_full_context(nds32); - - /* check interrupt level */ - v3_common_callback->check_interrupt_stack(nds32); - - return ERROR_OK; -} - -/** - * Restore processor state. - */ -static int nds32_v3_leave_debug_state(struct nds32 *nds32, bool enable_watchpoint) -{ - LOG_DEBUG("nds32_v3_leave_debug_state"); - - struct target *target = nds32->target; - - /* activate all hardware breakpoints */ - CHECK_RETVAL(v3_common_callback->activate_hardware_breakpoint(target)); - - if (enable_watchpoint) { - /* activate all watchpoints */ - CHECK_RETVAL(v3_common_callback->activate_hardware_watchpoint(target)); - } - - /* restore interrupt stack */ - v3_common_callback->restore_interrupt_stack(nds32); - - /* REVISIT once we start caring about MMU and cache state, - * address it here ... - */ - - /* restore PSW, PC, and R0 ... after flushing any modified - * registers. - */ - CHECK_RETVAL(nds32_restore_context(target)); - - if (nds32->virtual_hosting) { - /** enable virtual hosting */ - uint32_t value_ir3; - uint32_t entry_size; - uint32_t syscall_address; - - /* get syscall entry address */ - nds32_get_mapped_reg(nds32, IR3, &value_ir3); - entry_size = 0x4 << (((value_ir3 >> 14) & 0x3) << 1); - syscall_address = (value_ir3 & 0xFFFF0000) + entry_size * 8; /* The index of SYSCALL is 8 */ - - if (nds32->hit_syscall) { - /* single step to skip syscall entry */ - /* use IRET to skip syscall */ - struct aice_port_s *aice = target_to_aice(target); - uint32_t value_ir9; - uint32_t value_ir6; - uint32_t syscall_id; - - nds32_get_mapped_reg(nds32, IR6, &value_ir6); - syscall_id = (value_ir6 >> 16) & 0x7FFF; - - if (syscall_id == NDS32_SYSCALL_EXIT) { - /* If target hits exit syscall, do not use IRET to skip handler. */ - aice_step(aice); - } else { - /* use api->read/write_reg to skip nds32 register cache */ - uint32_t value_dimbr; - aice_read_debug_reg(aice, NDS_EDM_SR_DIMBR, &value_dimbr); - aice_write_register(aice, IR11, value_dimbr + 0xC); - - aice_read_register(aice, IR9, &value_ir9); - value_ir9 += 4; /* syscall is always 4 bytes */ - aice_write_register(aice, IR9, value_ir9); - - /* backup hardware breakpoint 0 */ - uint32_t backup_bpa, backup_bpam, backup_bpc; - aice_read_debug_reg(aice, NDS_EDM_SR_BPA0, &backup_bpa); - aice_read_debug_reg(aice, NDS_EDM_SR_BPAM0, &backup_bpam); - aice_read_debug_reg(aice, NDS_EDM_SR_BPC0, &backup_bpc); - - /* use hardware breakpoint 0 to stop cpu after skipping syscall */ - aice_write_debug_reg(aice, NDS_EDM_SR_BPA0, value_ir9); - aice_write_debug_reg(aice, NDS_EDM_SR_BPAM0, 0); - aice_write_debug_reg(aice, NDS_EDM_SR_BPC0, 0xA); - - /* Execute two IRET. - * First IRET is used to quit debug mode. - * Second IRET is used to quit current syscall. */ - uint32_t dim_inst[4] = {NOP, NOP, IRET, IRET}; - aice_execute(aice, dim_inst, 4); - - /* restore origin hardware breakpoint 0 */ - aice_write_debug_reg(aice, NDS_EDM_SR_BPA0, backup_bpa); - aice_write_debug_reg(aice, NDS_EDM_SR_BPAM0, backup_bpam); - aice_write_debug_reg(aice, NDS_EDM_SR_BPC0, backup_bpc); - } - - nds32->hit_syscall = false; - } - - /* insert breakpoint at syscall entry */ - struct breakpoint *syscall_break = &(nds32->syscall_break); - - syscall_break->address = syscall_address; - syscall_break->type = BKPT_SOFT; - syscall_break->set = 1; - target_add_breakpoint(target, syscall_break); - } - - return ERROR_OK; -} - -static int nds32_v3_get_exception_address(struct nds32 *nds32, - uint32_t *address, uint32_t reason) -{ - LOG_DEBUG("nds32_v3_get_exception_address"); - - struct aice_port_s *aice = target_to_aice(nds32->target); - struct target *target = nds32->target; - uint32_t edmsw; - uint32_t edm_cfg; - uint32_t match_bits; - uint32_t match_count; - int32_t i; - static int32_t number_of_hard_break; - uint32_t bp_control; - - if (number_of_hard_break == 0) { - aice_read_debug_reg(aice, NDS_EDM_SR_EDM_CFG, &edm_cfg); - number_of_hard_break = (edm_cfg & 0x7) + 1; - } - - aice_read_debug_reg(aice, NDS_EDM_SR_EDMSW, &edmsw); - /* clear matching bits (write-one-clear) */ - aice_write_debug_reg(aice, NDS_EDM_SR_EDMSW, edmsw); - match_bits = (edmsw >> 4) & 0xFF; - match_count = 0; - for (i = 0 ; i < number_of_hard_break ; i++) { - if (match_bits & (1 << i)) { - aice_read_debug_reg(aice, NDS_EDM_SR_BPA0 + i, address); - match_count++; - - /* If target hits multiple read/access watchpoint, - * select the first one. */ - aice_read_debug_reg(aice, NDS_EDM_SR_BPC0 + i, &bp_control); - if (0x3 == (bp_control & 0x3)) { - match_count = 1; - break; - } - } - } - - if (match_count > 1) { /* multiple hits */ - *address = 0; - return ERROR_OK; - } else if (match_count == 1) { - uint32_t val_pc; - uint32_t opcode; - struct nds32_instruction instruction; - struct watchpoint *wp; - bool hit; - - nds32_get_mapped_reg(nds32, PC, &val_pc); - - if ((NDS32_DEBUG_DATA_ADDR_WATCHPOINT_NEXT_PRECISE == reason) || - (NDS32_DEBUG_DATA_VALUE_WATCHPOINT_NEXT_PRECISE == reason)) { - if (edmsw & 0x4) /* check EDMSW.IS_16BIT */ - val_pc -= 2; - else - val_pc -= 4; - } - - nds32_read_opcode(nds32, val_pc, &opcode); - nds32_evaluate_opcode(nds32, opcode, val_pc, &instruction); - - LOG_DEBUG("PC: 0x%08" PRIx32 ", access start: 0x%08" PRIx32 ", end: 0x%08" PRIx32, - val_pc, instruction.access_start, instruction.access_end); - - /* check if multiple hits in the access range */ - uint32_t in_range_watch_count = 0; - for (wp = target->watchpoints; wp; wp = wp->next) { - if ((instruction.access_start <= wp->address) && - (wp->address < instruction.access_end)) - in_range_watch_count++; - } - if (in_range_watch_count > 1) { - /* Hit LSMW instruction. */ - *address = 0; - return ERROR_OK; - } - - /* dispel false match */ - hit = false; - for (wp = target->watchpoints; wp; wp = wp->next) { - if (((*address ^ wp->address) & (~wp->mask)) == 0) { - uint32_t watch_start; - uint32_t watch_end; - - watch_start = wp->address; - watch_end = wp->address + wp->length; - - if ((watch_end <= instruction.access_start) || - (instruction.access_end <= watch_start)) - continue; - - hit = true; - break; - } - } - - if (hit) - return ERROR_OK; - else - return ERROR_FAIL; - } else if (match_count == 0) { - /* global stop is precise exception */ - if ((NDS32_DEBUG_LOAD_STORE_GLOBAL_STOP == reason) && nds32->global_stop) { - /* parse instruction to get correct access address */ - uint32_t val_pc; - uint32_t opcode; - struct nds32_instruction instruction; - - nds32_get_mapped_reg(nds32, PC, &val_pc); - nds32_read_opcode(nds32, val_pc, &opcode); - nds32_evaluate_opcode(nds32, opcode, val_pc, &instruction); - - *address = instruction.access_start; - - return ERROR_OK; - } - } - - *address = 0xFFFFFFFF; - return ERROR_FAIL; -} - -void nds32_v3_common_register_callback(struct nds32_v3_common_callback *callback) -{ - v3_common_callback = callback; -} - -/** target_type functions: */ -/* target request support */ -int nds32_v3_target_request_data(struct target *target, - uint32_t size, uint8_t *buffer) -{ - /* AndesCore could use DTR register to communicate with OpenOCD - * to output messages - * Target data will be put in buffer - * The format of DTR is as follow - * DTR[31:16] => length, DTR[15:8] => size, DTR[7:0] => target_req_cmd - * target_req_cmd has three possible values: - * TARGET_REQ_TRACEMSG - * TARGET_REQ_DEBUGMSG - * TARGET_REQ_DEBUGCHAR - * if size == 0, target will call target_asciimsg(), - * else call target_hexmsg() - */ - LOG_WARNING("Not implemented: %s", __func__); - - return ERROR_OK; -} - -int nds32_v3_checksum_memory(struct target *target, - uint32_t address, uint32_t count, uint32_t *checksum) -{ - LOG_WARNING("Not implemented: %s", __func__); - - return ERROR_FAIL; -} - -/** - * find out which watchpoint hits - * get exception address and compare the address to watchpoints - */ -int nds32_v3_hit_watchpoint(struct target *target, - struct watchpoint **hit_watchpoint) -{ - static struct watchpoint scan_all_watchpoint; - - uint32_t exception_address; - struct watchpoint *wp; - struct nds32 *nds32 = target_to_nds32(target); - - exception_address = nds32->watched_address; - - if (exception_address == 0xFFFFFFFF) - return ERROR_FAIL; - - if (exception_address == 0) { - scan_all_watchpoint.address = 0; - scan_all_watchpoint.rw = WPT_WRITE; - scan_all_watchpoint.next = 0; - scan_all_watchpoint.unique_id = 0x5CA8; - - *hit_watchpoint = &scan_all_watchpoint; - return ERROR_OK; - } - - for (wp = target->watchpoints; wp; wp = wp->next) { - if (((exception_address ^ wp->address) & (~wp->mask)) == 0) { - *hit_watchpoint = wp; - - return ERROR_OK; - } - } - - return ERROR_FAIL; -} - -int nds32_v3_target_create_common(struct target *target, struct nds32 *nds32) -{ - nds32->register_map = nds32_v3_register_mapping; - nds32->get_debug_reason = nds32_v3_get_debug_reason; - nds32->enter_debug_state = nds32_v3_debug_entry; - nds32->leave_debug_state = nds32_v3_leave_debug_state; - nds32->get_watched_address = nds32_v3_get_exception_address; - - /* Init target->arch_info in nds32_init_arch_info(). - * After this, user could use target_to_nds32() to get nds32 object */ - nds32_init_arch_info(target, nds32); - - return ERROR_OK; -} - -int nds32_v3_run_algorithm(struct target *target, - int num_mem_params, - struct mem_param *mem_params, - int num_reg_params, - struct reg_param *reg_params, - uint32_t entry_point, - uint32_t exit_point, - int timeout_ms, - void *arch_info) -{ - LOG_WARNING("Not implemented: %s", __func__); - - return ERROR_FAIL; -} - -int nds32_v3_read_buffer(struct target *target, uint32_t address, - uint32_t size, uint8_t *buffer) -{ - struct nds32 *nds32 = target_to_nds32(target); - struct nds32_memory *memory = &(nds32->memory); - - if ((NDS_MEMORY_ACC_CPU == memory->access_channel) && - (target->state != TARGET_HALTED)) { - LOG_WARNING("target was not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - uint32_t physical_address; - /* BUG: If access range crosses multiple pages, the translation will not correct - * for second page or so. */ - - /* When DEX is set to one, hardware will enforce the following behavior without - * modifying the corresponding control bits in PSW. - * - * Disable all interrupts - * Become superuser mode - * Turn off IT/DT - * Use MMU_CFG.DE as the data access endian - * Use MMU_CFG.DRDE as the device register access endian if MMU_CTL.DREE is asserted - * Disable audio special features - * Disable inline function call - * - * Because hardware will turn off IT/DT by default, it MUST translate virtual address - * to physical address. - */ - if (ERROR_OK == target->type->virt2phys(target, address, &physical_address)) - address = physical_address; - else - return ERROR_FAIL; - - int result; - struct aice_port_s *aice = target_to_aice(target); - /* give arbitrary initial value to avoid warning messages */ - enum nds_memory_access origin_access_channel = NDS_MEMORY_ACC_CPU; - - if (nds32->hit_syscall) { - /* Use bus mode to access memory during virtual hosting */ - origin_access_channel = memory->access_channel; - memory->access_channel = NDS_MEMORY_ACC_BUS; - aice_memory_access(aice, NDS_MEMORY_ACC_BUS); - } - - result = nds32_read_buffer(target, address, size, buffer); - - if (nds32->hit_syscall) { - /* Restore access_channel after virtual hosting */ - memory->access_channel = origin_access_channel; - aice_memory_access(aice, origin_access_channel); - } - - return result; -} - -int nds32_v3_write_buffer(struct target *target, uint32_t address, - uint32_t size, const uint8_t *buffer) -{ - struct nds32 *nds32 = target_to_nds32(target); - struct nds32_memory *memory = &(nds32->memory); - - if ((NDS_MEMORY_ACC_CPU == memory->access_channel) && - (target->state != TARGET_HALTED)) { - LOG_WARNING("target was not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - uint32_t physical_address; - /* BUG: If access range crosses multiple pages, the translation will not correct - * for second page or so. */ - - /* When DEX is set to one, hardware will enforce the following behavior without - * modifying the corresponding control bits in PSW. - * - * Disable all interrupts - * Become superuser mode - * Turn off IT/DT - * Use MMU_CFG.DE as the data access endian - * Use MMU_CFG.DRDE as the device register access endian if MMU_CTL.DREE is asserted - * Disable audio special features - * Disable inline function call - * - * Because hardware will turn off IT/DT by default, it MUST translate virtual address - * to physical address. - */ - if (ERROR_OK == target->type->virt2phys(target, address, &physical_address)) - address = physical_address; - else - return ERROR_FAIL; - - if (nds32->hit_syscall) { - struct aice_port_s *aice = target_to_aice(target); - enum nds_memory_access origin_access_channel; - origin_access_channel = memory->access_channel; - - /* If target has no cache, use BUS mode to access memory. */ - if ((memory->dcache.line_size == 0) - || (memory->dcache.enable == false)) { - /* There is no Dcache or Dcache is disabled. */ - memory->access_channel = NDS_MEMORY_ACC_BUS; - aice_memory_access(aice, NDS_MEMORY_ACC_BUS); - } - - int result; - result = nds32_gdb_fileio_write_memory(nds32, address, size, buffer); - - if (NDS_MEMORY_ACC_CPU == origin_access_channel) { - memory->access_channel = NDS_MEMORY_ACC_CPU; - aice_memory_access(aice, NDS_MEMORY_ACC_CPU); - } - - return result; - } - - return nds32_write_buffer(target, address, size, buffer); -} - -int nds32_v3_read_memory(struct target *target, uint32_t address, - uint32_t size, uint32_t count, uint8_t *buffer) -{ - struct nds32 *nds32 = target_to_nds32(target); - struct nds32_memory *memory = &(nds32->memory); - - if ((NDS_MEMORY_ACC_CPU == memory->access_channel) && - (target->state != TARGET_HALTED)) { - LOG_WARNING("target was not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - uint32_t physical_address; - /* BUG: If access range crosses multiple pages, the translation will not correct - * for second page or so. */ - - /* When DEX is set to one, hardware will enforce the following behavior without - * modifying the corresponding control bits in PSW. - * - * Disable all interrupts - * Become superuser mode - * Turn off IT/DT - * Use MMU_CFG.DE as the data access endian - * Use MMU_CFG.DRDE as the device register access endian if MMU_CTL.DREE is asserted - * Disable audio special features - * Disable inline function call - * - * Because hardware will turn off IT/DT by default, it MUST translate virtual address - * to physical address. - */ - if (ERROR_OK == target->type->virt2phys(target, address, &physical_address)) - address = physical_address; - else - return ERROR_FAIL; - - struct aice_port_s *aice = target_to_aice(target); - /* give arbitrary initial value to avoid warning messages */ - enum nds_memory_access origin_access_channel = NDS_MEMORY_ACC_CPU; - int result; - - if (nds32->hit_syscall) { - /* Use bus mode to access memory during virtual hosting */ - origin_access_channel = memory->access_channel; - memory->access_channel = NDS_MEMORY_ACC_BUS; - aice_memory_access(aice, NDS_MEMORY_ACC_BUS); - } - - result = nds32_read_memory(target, address, size, count, buffer); - - if (nds32->hit_syscall) { - /* Restore access_channel after virtual hosting */ - memory->access_channel = origin_access_channel; - aice_memory_access(aice, origin_access_channel); - } - - return result; -} - -int nds32_v3_write_memory(struct target *target, uint32_t address, - uint32_t size, uint32_t count, const uint8_t *buffer) -{ - struct nds32 *nds32 = target_to_nds32(target); - struct nds32_memory *memory = &(nds32->memory); - - if ((NDS_MEMORY_ACC_CPU == memory->access_channel) && - (target->state != TARGET_HALTED)) { - LOG_WARNING("target was not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - uint32_t physical_address; - /* BUG: If access range crosses multiple pages, the translation will not correct - * for second page or so. */ - - /* When DEX is set to one, hardware will enforce the following behavior without - * modifying the corresponding control bits in PSW. - * - * Disable all interrupts - * Become superuser mode - * Turn off IT/DT - * Use MMU_CFG.DE as the data access endian - * Use MMU_CFG.DRDE as the device register access endian if MMU_CTL.DREE is asserted - * Disable audio special features - * Disable inline function call - * - * Because hardware will turn off IT/DT by default, it MUST translate virtual address - * to physical address. - */ - if (ERROR_OK == target->type->virt2phys(target, address, &physical_address)) - address = physical_address; - else - return ERROR_FAIL; - - return nds32_write_memory(target, address, size, count, buffer); -} - -int nds32_v3_init_target(struct command_context *cmd_ctx, - struct target *target) -{ - /* Initialize anything we can set up without talking to the target */ - struct nds32 *nds32 = target_to_nds32(target); - - nds32_init(nds32); - - target->fileio_info = malloc(sizeof(struct gdb_fileio_info)); - target->fileio_info->identifier = NULL; - - return ERROR_OK; -} diff --git a/src/target/nds32_v3_common.h b/src/target/nds32_v3_common.h deleted file mode 100644 index 1f5df1995..000000000 --- a/src/target/nds32_v3_common.h +++ /dev/null @@ -1,61 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2013 Andes Technology * - * Hsiangkai Wang * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 OPENOCD_TARGET_NDS32_V3_COMMON_H -#define OPENOCD_TARGET_NDS32_V3_COMMON_H - -#include "target.h" - -struct nds32_v3_common_callback { - int (*check_interrupt_stack)(struct nds32 *nds32); - int (*restore_interrupt_stack)(struct nds32 *nds32); - int (*activate_hardware_breakpoint)(struct target *target); - int (*activate_hardware_watchpoint)(struct target *target); - int (*deactivate_hardware_breakpoint)(struct target *target); - int (*deactivate_hardware_watchpoint)(struct target *target); -}; - -void nds32_v3_common_register_callback(struct nds32_v3_common_callback *callback); -int nds32_v3_target_request_data(struct target *target, - uint32_t size, uint8_t *buffer); -int nds32_v3_checksum_memory(struct target *target, - uint32_t address, uint32_t count, uint32_t *checksum); -int nds32_v3_hit_watchpoint(struct target *target, - struct watchpoint **hit_watchpoint); -int nds32_v3_target_create_common(struct target *target, struct nds32 *nds32); -int nds32_v3_run_algorithm(struct target *target, - int num_mem_params, - struct mem_param *mem_params, - int num_reg_params, - struct reg_param *reg_params, - uint32_t entry_point, - uint32_t exit_point, - int timeout_ms, - void *arch_info); -int nds32_v3_read_buffer(struct target *target, uint32_t address, - uint32_t size, uint8_t *buffer); -int nds32_v3_write_buffer(struct target *target, uint32_t address, - uint32_t size, const uint8_t *buffer); -int nds32_v3_read_memory(struct target *target, uint32_t address, - uint32_t size, uint32_t count, uint8_t *buffer); -int nds32_v3_write_memory(struct target *target, uint32_t address, - uint32_t size, uint32_t count, const uint8_t *buffer); -int nds32_v3_init_target(struct command_context *cmd_ctx, - struct target *target); - -#endif /* OPENOCD_TARGET_NDS32_V3_COMMON_H */ diff --git a/src/target/nds32_v3m.c b/src/target/nds32_v3m.c deleted file mode 100644 index 919c0c828..000000000 --- a/src/target/nds32_v3m.c +++ /dev/null @@ -1,506 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2013 Andes Technology * - * Hsiangkai Wang * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 -#include "config.h" -#endif - -#include "breakpoints.h" -#include "nds32_cmd.h" -#include "nds32_aice.h" -#include "nds32_v3m.h" -#include "nds32_v3_common.h" - -static int nds32_v3m_activate_hardware_breakpoint(struct target *target) -{ - struct nds32_v3m_common *nds32_v3m = target_to_nds32_v3m(target); - struct aice_port_s *aice = target_to_aice(target); - struct breakpoint *bp; - unsigned brp_num = nds32_v3m->n_hbr - 1; - - for (bp = target->breakpoints; bp; bp = bp->next) { - if (bp->type == BKPT_SOFT) { - /* already set at nds32_v3m_add_breakpoint() */ - continue; - } else if (bp->type == BKPT_HARD) { - /* set address */ - aice_write_debug_reg(aice, NDS_EDM_SR_BPA0 + brp_num, bp->address); - /* set mask */ - aice_write_debug_reg(aice, NDS_EDM_SR_BPAM0 + brp_num, 0); - - if (nds32_v3m->nds32.memory.address_translation) - /* enable breakpoint (virtual address) */ - aice_write_debug_reg(aice, NDS_EDM_SR_BPC0 + brp_num, 0x2); - else - /* enable breakpoint (physical address) */ - aice_write_debug_reg(aice, NDS_EDM_SR_BPC0 + brp_num, 0xA); - - LOG_DEBUG("Add hardware BP %u at %08" PRIx32, brp_num, - bp->address); - - brp_num--; - } else { - return ERROR_FAIL; - } - } - - return ERROR_OK; -} - -static int nds32_v3m_deactivate_hardware_breakpoint(struct target *target) -{ - struct nds32_v3m_common *nds32_v3m = target_to_nds32_v3m(target); - struct aice_port_s *aice = target_to_aice(target); - struct breakpoint *bp; - unsigned brp_num = nds32_v3m->n_hbr - 1; - - for (bp = target->breakpoints; bp; bp = bp->next) { - if (bp->type == BKPT_SOFT) - continue; - else if (bp->type == BKPT_HARD) - /* disable breakpoint */ - aice_write_debug_reg(aice, NDS_EDM_SR_BPC0 + brp_num, 0x0); - else - return ERROR_FAIL; - - LOG_DEBUG("Remove hardware BP %u at %08" PRIx32, brp_num, - bp->address); - - brp_num--; - } - - return ERROR_OK; -} - -static int nds32_v3m_activate_hardware_watchpoint(struct target *target) -{ - struct aice_port_s *aice = target_to_aice(target); - struct nds32_v3m_common *nds32_v3m = target_to_nds32_v3m(target); - struct watchpoint *wp; - int32_t wp_num = 0; - uint32_t wp_config = 0; - bool ld_stop, st_stop; - - if (nds32_v3m->nds32.global_stop) - ld_stop = st_stop = false; - - for (wp = target->watchpoints; wp; wp = wp->next) { - - if (wp_num < nds32_v3m->used_n_wp) { - wp->mask = wp->length - 1; - if ((wp->address % wp->length) != 0) - wp->mask = (wp->mask << 1) + 1; - - if (wp->rw == WPT_READ) - wp_config = 0x3; - else if (wp->rw == WPT_WRITE) - wp_config = 0x5; - else if (wp->rw == WPT_ACCESS) - wp_config = 0x7; - - /* set/unset physical address bit of BPCn according to PSW.DT */ - if (nds32_v3m->nds32.memory.address_translation == false) - wp_config |= 0x8; - - /* set address */ - aice_write_debug_reg(aice, NDS_EDM_SR_BPA0 + wp_num, - wp->address - (wp->address % wp->length)); - /* set mask */ - aice_write_debug_reg(aice, NDS_EDM_SR_BPAM0 + wp_num, wp->mask); - /* enable watchpoint */ - aice_write_debug_reg(aice, NDS_EDM_SR_BPC0 + wp_num, wp_config); - - LOG_DEBUG("Add hardware wathcpoint %" PRId32 " at %08" PRIx32 - " mask %08" PRIx32, wp_num, wp->address, wp->mask); - - wp_num++; - } else if (nds32_v3m->nds32.global_stop) { - if (wp->rw == WPT_READ) - ld_stop = true; - else if (wp->rw == WPT_WRITE) - st_stop = true; - else if (wp->rw == WPT_ACCESS) - ld_stop = st_stop = true; - } - } - - if (nds32_v3m->nds32.global_stop) { - uint32_t edm_ctl; - aice_read_debug_reg(aice, NDS_EDM_SR_EDM_CTL, &edm_ctl); - if (ld_stop) - edm_ctl |= 0x10; - if (st_stop) - edm_ctl |= 0x20; - aice_write_debug_reg(aice, NDS_EDM_SR_EDM_CTL, edm_ctl); - } - - return ERROR_OK; -} - -static int nds32_v3m_deactivate_hardware_watchpoint(struct target *target) -{ - struct nds32_v3m_common *nds32_v3m = target_to_nds32_v3m(target); - struct aice_port_s *aice = target_to_aice(target); - struct watchpoint *wp; - int32_t wp_num = 0; - bool clean_global_stop = false; - - for (wp = target->watchpoints; wp; wp = wp->next) { - - if (wp_num < nds32_v3m->used_n_wp) { - /* disable watchpoint */ - aice_write_debug_reg(aice, NDS_EDM_SR_BPC0 + wp_num, 0x0); - - LOG_DEBUG("Remove hardware wathcpoint %" PRId32 " at %08" PRIx32 - " mask %08" PRIx32, wp_num, wp->address, wp->mask); - wp_num++; - } else if (nds32_v3m->nds32.global_stop) { - clean_global_stop = true; - } - } - - if (clean_global_stop) { - uint32_t edm_ctl; - aice_read_debug_reg(aice, NDS_EDM_SR_EDM_CTL, &edm_ctl); - edm_ctl = edm_ctl & (~0x30); - aice_write_debug_reg(aice, NDS_EDM_SR_EDM_CTL, edm_ctl); - } - - return ERROR_OK; -} - -static int nds32_v3m_check_interrupt_stack(struct nds32 *nds32) -{ - uint32_t val_ir0; - uint32_t value; - - /* Save interrupt level */ - nds32_get_mapped_reg(nds32, IR0, &val_ir0); - nds32->current_interrupt_level = (val_ir0 >> 1) & 0x3; - - if (nds32_reach_max_interrupt_level(nds32)) - LOG_ERROR("<-- TARGET ERROR! Reaching the max interrupt stack level %" PRIu32 ". -->", - nds32->current_interrupt_level); - - /* backup $ir6 to avoid suppressed exception overwrite */ - nds32_get_mapped_reg(nds32, IR6, &value); - - return ERROR_OK; -} - -static int nds32_v3m_restore_interrupt_stack(struct nds32 *nds32) -{ - uint32_t value; - - /* get backup value from cache */ - /* then set back to make the register dirty */ - nds32_get_mapped_reg(nds32, IR0, &value); - nds32_set_mapped_reg(nds32, IR0, value); - - nds32_get_mapped_reg(nds32, IR6, &value); - nds32_set_mapped_reg(nds32, IR6, value); - - return ERROR_OK; -} - -static int nds32_v3m_deassert_reset(struct target *target) -{ - int retval; - - CHECK_RETVAL(nds32_poll(target)); - - if (target->state != TARGET_HALTED) { - /* reset only */ - LOG_WARNING("%s: ran after reset and before halt ...", - target_name(target)); - retval = target_halt(target); - if (retval != ERROR_OK) - return retval; - - } - - return ERROR_OK; -} - -static int nds32_v3m_add_breakpoint(struct target *target, - struct breakpoint *breakpoint) -{ - struct nds32_v3m_common *nds32_v3m = target_to_nds32_v3m(target); - struct nds32 *nds32 = &(nds32_v3m->nds32); - int result; - - if (breakpoint->type == BKPT_HARD) { - /* check hardware resource */ - if (nds32_v3m->next_hbr_index < nds32_v3m->next_hwp_index) { - LOG_WARNING("<-- TARGET WARNING! Insert too many " - "hardware breakpoints/watchpoints! " - "The limit of combined hardware " - "breakpoints/watchpoints is %" PRId32 ". -->", - nds32_v3m->n_hbr); - LOG_WARNING("<-- TARGET STATUS: Inserted number of " - "hardware breakpoint: %" PRId32 ", hardware " - "watchpoints: %" PRId32 ". -->", - nds32_v3m->n_hbr - nds32_v3m->next_hbr_index - 1, - nds32_v3m->used_n_wp); - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - } - - /* update next place to put hardware breakpoint */ - nds32_v3m->next_hbr_index--; - - /* hardware breakpoint insertion occurs before 'continue' actually */ - return ERROR_OK; - } else if (breakpoint->type == BKPT_SOFT) { - result = nds32_add_software_breakpoint(target, breakpoint); - if (ERROR_OK != result) { - /* auto convert to hardware breakpoint if failed */ - if (nds32->auto_convert_hw_bp) { - /* convert to hardware breakpoint */ - breakpoint->type = BKPT_HARD; - - return nds32_v3m_add_breakpoint(target, breakpoint); - } - } - - return result; - } else /* unrecognized breakpoint type */ - return ERROR_FAIL; - - return ERROR_OK; -} - -static int nds32_v3m_remove_breakpoint(struct target *target, - struct breakpoint *breakpoint) -{ - struct nds32_v3m_common *nds32_v3m = target_to_nds32_v3m(target); - - if (breakpoint->type == BKPT_HARD) { - if (nds32_v3m->next_hbr_index >= nds32_v3m->n_hbr - 1) - return ERROR_FAIL; - - /* update next place to put hardware breakpoint */ - nds32_v3m->next_hbr_index++; - - /* hardware breakpoint removal occurs after 'halted' actually */ - return ERROR_OK; - } else if (breakpoint->type == BKPT_SOFT) { - return nds32_remove_software_breakpoint(target, breakpoint); - } else /* unrecognized breakpoint type */ - return ERROR_FAIL; - - return ERROR_OK; -} - -static int nds32_v3m_add_watchpoint(struct target *target, - struct watchpoint *watchpoint) -{ - struct nds32_v3m_common *nds32_v3m = target_to_nds32_v3m(target); - - /* check hardware resource */ - if (nds32_v3m->next_hwp_index >= nds32_v3m->n_hwp) { - /* No hardware resource */ - if (nds32_v3m->nds32.global_stop) { - LOG_WARNING("<-- TARGET WARNING! The number of " - "watchpoints exceeds the hardware " - "resources. Stop at every load/store " - "instruction to check for watchpoint matches. -->"); - return ERROR_OK; - } - - LOG_WARNING("<-- TARGET WARNING! Insert too many hardware " - "watchpoints! The limit of hardware watchpoints " - "is %" PRId32 ". -->", nds32_v3m->n_hwp); - LOG_WARNING("<-- TARGET STATUS: Inserted number of " - "hardware watchpoint: %" PRId32 ". -->", - nds32_v3m->used_n_wp); - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - } - - if (nds32_v3m->next_hwp_index > nds32_v3m->next_hbr_index) { - /* No hardware resource */ - if (nds32_v3m->nds32.global_stop) { - LOG_WARNING("<-- TARGET WARNING! The number of " - "watchpoints exceeds the hardware " - "resources. Stop at every load/store " - "instruction to check for watchpoint matches. -->"); - return ERROR_OK; - } - - LOG_WARNING("<-- TARGET WARNING! Insert too many hardware " - "breakpoints/watchpoints! The limit of combined " - "hardware breakpoints/watchpoints is %" PRId32 ". -->", - nds32_v3m->n_hbr); - LOG_WARNING("<-- TARGET STATUS: Inserted number of " - "hardware breakpoint: %" PRId32 ", hardware " - "watchpoints: %" PRId32 ". -->", - nds32_v3m->n_hbr - nds32_v3m->next_hbr_index - 1, - nds32_v3m->used_n_wp); - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - } - - /* update next place to put hardware watchpoint */ - nds32_v3m->next_hwp_index++; - nds32_v3m->used_n_wp++; - - return ERROR_OK; -} - -static int nds32_v3m_remove_watchpoint(struct target *target, - struct watchpoint *watchpoint) -{ - struct nds32_v3m_common *nds32_v3m = target_to_nds32_v3m(target); - - if (nds32_v3m->next_hwp_index <= 0) { - if (nds32_v3m->nds32.global_stop) - return ERROR_OK; - - return ERROR_FAIL; - } - - /* update next place to put hardware watchpoint */ - nds32_v3m->next_hwp_index--; - nds32_v3m->used_n_wp--; - - return ERROR_OK; -} - -struct nds32_v3_common_callback nds32_v3m_common_callback = { - .check_interrupt_stack = nds32_v3m_check_interrupt_stack, - .restore_interrupt_stack = nds32_v3m_restore_interrupt_stack, - .activate_hardware_breakpoint = nds32_v3m_activate_hardware_breakpoint, - .activate_hardware_watchpoint = nds32_v3m_activate_hardware_watchpoint, - .deactivate_hardware_breakpoint = nds32_v3m_deactivate_hardware_breakpoint, - .deactivate_hardware_watchpoint = nds32_v3m_deactivate_hardware_watchpoint, -}; - -static int nds32_v3m_target_create(struct target *target, Jim_Interp *interp) -{ - struct nds32_v3m_common *nds32_v3m; - - nds32_v3m = calloc(1, sizeof(*nds32_v3m)); - if (!nds32_v3m) - return ERROR_FAIL; - - nds32_v3_common_register_callback(&nds32_v3m_common_callback); - nds32_v3_target_create_common(target, &(nds32_v3m->nds32)); - - return ERROR_OK; -} - -/* talk to the target and set things up */ -static int nds32_v3m_examine(struct target *target) -{ - struct nds32_v3m_common *nds32_v3m = target_to_nds32_v3m(target); - struct nds32 *nds32 = &(nds32_v3m->nds32); - struct aice_port_s *aice = target_to_aice(target); - - if (!target_was_examined(target)) { - CHECK_RETVAL(nds32_edm_config(nds32)); - - if (nds32->reset_halt_as_examine) - CHECK_RETVAL(nds32_reset_halt(nds32)); - } - - uint32_t edm_cfg; - aice_read_debug_reg(aice, NDS_EDM_SR_EDM_CFG, &edm_cfg); - - /* get the number of hardware breakpoints */ - nds32_v3m->n_hbr = (edm_cfg & 0x7) + 1; - nds32_v3m->used_n_wp = 0; - - /* get the number of hardware watchpoints */ - /* If the WP field is hardwired to zero, it means this is a - * simple breakpoint. Otherwise, if the WP field is writable - * then it means this is a regular watchpoints. */ - nds32_v3m->n_hwp = 0; - for (int32_t i = 0 ; i < nds32_v3m->n_hbr ; i++) { - /** check the hardware breakpoint is simple or not */ - uint32_t tmp_value; - aice_write_debug_reg(aice, NDS_EDM_SR_BPC0 + i, 0x1); - aice_read_debug_reg(aice, NDS_EDM_SR_BPC0 + i, &tmp_value); - - if (tmp_value) - nds32_v3m->n_hwp++; - } - /* hardware breakpoint is inserted from high index to low index */ - nds32_v3m->next_hbr_index = nds32_v3m->n_hbr - 1; - /* hardware watchpoint is inserted from low index to high index */ - nds32_v3m->next_hwp_index = 0; - - LOG_INFO("%s: total hardware breakpoint %" PRId32 " (simple breakpoint %" PRId32 ")", - target_name(target), nds32_v3m->n_hbr, nds32_v3m->n_hbr - nds32_v3m->n_hwp); - LOG_INFO("%s: total hardware watchpoint %" PRId32, target_name(target), nds32_v3m->n_hwp); - - nds32->target->state = TARGET_RUNNING; - nds32->target->debug_reason = DBG_REASON_NOTHALTED; - - target_set_examined(target); - - return ERROR_OK; -} - -/** Holds methods for NDS32 V3m targets. */ -struct target_type nds32_v3m_target = { - .name = "nds32_v3m", - - .poll = nds32_poll, - .arch_state = nds32_arch_state, - - .target_request_data = nds32_v3_target_request_data, - - .halt = nds32_halt, - .resume = nds32_resume, - .step = nds32_step, - - .assert_reset = nds32_assert_reset, - .deassert_reset = nds32_v3m_deassert_reset, - - /* register access */ - .get_gdb_reg_list = nds32_get_gdb_reg_list, - - /* memory access */ - .read_buffer = nds32_v3_read_buffer, - .write_buffer = nds32_v3_write_buffer, - .read_memory = nds32_v3_read_memory, - .write_memory = nds32_v3_write_memory, - - .checksum_memory = nds32_v3_checksum_memory, - - /* breakpoint/watchpoint */ - .add_breakpoint = nds32_v3m_add_breakpoint, - .remove_breakpoint = nds32_v3m_remove_breakpoint, - .add_watchpoint = nds32_v3m_add_watchpoint, - .remove_watchpoint = nds32_v3m_remove_watchpoint, - .hit_watchpoint = nds32_v3_hit_watchpoint, - - /* MMU */ - .mmu = nds32_mmu, - .virt2phys = nds32_virtual_to_physical, - .read_phys_memory = nds32_read_phys_memory, - .write_phys_memory = nds32_write_phys_memory, - - .run_algorithm = nds32_v3_run_algorithm, - - .commands = nds32_command_handlers, - .target_create = nds32_v3m_target_create, - .init_target = nds32_v3_init_target, - .examine = nds32_v3m_examine, - - .get_gdb_fileio_info = nds32_get_gdb_fileio_info, - .gdb_fileio_end = nds32_gdb_fileio_end, -}; diff --git a/src/target/nds32_v3m.h b/src/target/nds32_v3m.h deleted file mode 100644 index 1e7427c48..000000000 --- a/src/target/nds32_v3m.h +++ /dev/null @@ -1,51 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2013 Andes Technology * - * Hsiangkai Wang * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 OPENOCD_TARGET_NDS32_V3M_H -#define OPENOCD_TARGET_NDS32_V3M_H - -#include "nds32.h" - -struct nds32_v3m_common { - struct nds32 nds32; - - /** number of hardware breakpoints */ - int32_t n_hbr; - - /** number of hardware watchpoints */ - int32_t n_hwp; - - /** number of used hardware watchpoints */ - int32_t used_n_wp; - - /** next hardware breakpoint index */ - /** for simple breakpoints, hardware breakpoints are inserted - * from high index to low index */ - int32_t next_hbr_index; - - /** next hardware watchpoint index */ - /** increase from low index to high index */ - int32_t next_hwp_index; -}; - -static inline struct nds32_v3m_common *target_to_nds32_v3m(struct target *target) -{ - return container_of(target->arch_info, struct nds32_v3m_common, nds32); -} - -#endif /* OPENOCD_TARGET_NDS32_V3M_H */ diff --git a/src/target/oocd_trace.c b/src/target/oocd_trace.c deleted file mode 100644 index 627366d5d..000000000 --- a/src/target/oocd_trace.c +++ /dev/null @@ -1,417 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "arm.h" -#include "etm.h" -#include "oocd_trace.h" - -/* - * This is "proof of concept" code, for prototype hardware: - * https://lists.berlios.de/pipermail/openocd-development/2007-September/000336.html - */ - -static int oocd_trace_read_reg(struct oocd_trace *oocd_trace, int reg, uint32_t *value) -{ - size_t bytes_written, bytes_read, bytes_to_read; - uint8_t cmd; - - cmd = 0x10 | (reg & 0x7); - bytes_written = write(oocd_trace->tty_fd, &cmd, 1); - if (bytes_written < 1) - return ERROR_FAIL; - - bytes_to_read = 4; - while (bytes_to_read > 0) { - bytes_read = read(oocd_trace->tty_fd, ((uint8_t *)value) + 4 - bytes_to_read, bytes_to_read); - bytes_to_read -= bytes_read; - } - - LOG_DEBUG("reg #%i: 0x%8.8x", reg, *value); - - return ERROR_OK; -} - -static int oocd_trace_write_reg(struct oocd_trace *oocd_trace, int reg, uint32_t value) -{ - size_t bytes_written; - uint8_t data[5]; - - data[0] = 0x18 | (reg & 0x7); - data[1] = value & 0xff; - data[2] = (value & 0xff00) >> 8; - data[3] = (value & 0xff0000) >> 16; - data[4] = (value & 0xff000000) >> 24; - - bytes_written = write(oocd_trace->tty_fd, data, 5); - if (bytes_written < 5) - return ERROR_FAIL; - - LOG_DEBUG("reg #%i: 0x%8.8x", reg, value); - - return ERROR_OK; -} - -static int oocd_trace_read_memory(struct oocd_trace *oocd_trace, uint8_t *data, uint32_t address, uint32_t size) -{ - size_t bytes_written, bytes_to_read; - ssize_t bytes_read; - uint8_t cmd; - - oocd_trace_write_reg(oocd_trace, OOCD_TRACE_ADDRESS, address); - oocd_trace_write_reg(oocd_trace, OOCD_TRACE_SDRAM_COUNTER, size); - - cmd = 0x20; - bytes_written = write(oocd_trace->tty_fd, &cmd, 1); - if (bytes_written < 1) - return ERROR_FAIL; - - bytes_to_read = size * 16; - while (bytes_to_read > 0) { - bytes_read = read(oocd_trace->tty_fd, - ((uint8_t *)data) + (size * 16) - bytes_to_read, bytes_to_read); - if (bytes_read < 0) - LOG_DEBUG("read() returned %zi (%s)", bytes_read, strerror(errno)); - else - bytes_to_read -= bytes_read; - } - - return ERROR_OK; -} - -static int oocd_trace_init(struct etm_context *etm_ctx) -{ - uint8_t trash[256]; - struct oocd_trace *oocd_trace = etm_ctx->capture_driver_priv; - size_t bytes_read; - - oocd_trace->tty_fd = open(oocd_trace->tty, O_RDWR | O_NOCTTY | O_NONBLOCK); - - if (oocd_trace->tty_fd < 0) { - LOG_ERROR("can't open tty"); - return ERROR_ETM_CAPTURE_INIT_FAILED; - } - - /* clear input & output buffers, then switch to "blocking mode" */ - tcflush(oocd_trace->tty_fd, TCOFLUSH); - tcflush(oocd_trace->tty_fd, TCIFLUSH); - fcntl(oocd_trace->tty_fd, F_SETFL, fcntl(oocd_trace->tty_fd, F_GETFL) & ~O_NONBLOCK); - - tcgetattr(oocd_trace->tty_fd, &oocd_trace->oldtio); /* save current port settings */ - - bzero(&oocd_trace->newtio, sizeof(oocd_trace->newtio)); - oocd_trace->newtio.c_cflag = CS8 | CLOCAL | CREAD | B2500000; - - oocd_trace->newtio.c_iflag = IGNPAR | IGNBRK | IXON | IXOFF; - oocd_trace->newtio.c_oflag = 0; - - /* set input mode (non-canonical, no echo,...) */ - oocd_trace->newtio.c_lflag = 0; - - cfmakeraw(&oocd_trace->newtio); - oocd_trace->newtio.c_cc[VTIME] = 1; /* inter-character timer used */ - oocd_trace->newtio.c_cc[VMIN] = 0; /* blocking read until 0 chars received */ - - tcflush(oocd_trace->tty_fd, TCIFLUSH); - tcsetattr(oocd_trace->tty_fd, TCSANOW, &oocd_trace->newtio); - - /* occasionally one bogus character is left in the input buffer - * read up any leftover characters to ensure communication is in sync */ - do { - bytes_read = read(oocd_trace->tty_fd, trash, sizeof(trash)); - if (bytes_read) - LOG_DEBUG("%zi bytes read", bytes_read); - } while (bytes_read > 0); - - return ERROR_OK; -} - -static trace_status_t oocd_trace_status(struct etm_context *etm_ctx) -{ - struct oocd_trace *oocd_trace = etm_ctx->capture_driver_priv; - uint32_t status; - - oocd_trace_read_reg(oocd_trace, OOCD_TRACE_STATUS, &status); - - /* if tracing is currently idle, return this information */ - if (etm_ctx->capture_status == TRACE_IDLE) - return etm_ctx->capture_status; - else if (etm_ctx->capture_status & TRACE_RUNNING) { - /* check Full bit to identify an overflow */ - if (status & 0x4) - etm_ctx->capture_status |= TRACE_OVERFLOWED; - - /* check Triggered bit to identify trigger condition */ - if (status & 0x2) - etm_ctx->capture_status |= TRACE_TRIGGERED; - - if (status & 0x1) { - etm_ctx->capture_status &= ~TRACE_RUNNING; - etm_ctx->capture_status |= TRACE_COMPLETED; - } - } - - return etm_ctx->capture_status; -} - -static int oocd_trace_read_trace(struct etm_context *etm_ctx) -{ - struct oocd_trace *oocd_trace = etm_ctx->capture_driver_priv; - uint32_t status, address; - uint32_t first_frame = 0x0; - uint32_t num_frames = 1048576; - uint8_t *trace_data; - uint32_t i; - - oocd_trace_read_reg(oocd_trace, OOCD_TRACE_STATUS, &status); - oocd_trace_read_reg(oocd_trace, OOCD_TRACE_ADDRESS, &address); - - /* check if we overflowed, and adjust first frame of the trace accordingly - * if we didn't overflow, read only up to the frame that would be written next, - * i.e. don't read invalid entries - */ - if (status & 0x4) - first_frame = address; - else - num_frames = address; - - /* read data into temporary array for unpacking - * one frame from OpenOCD + trace corresponds to 16 trace cycles - */ - trace_data = malloc(sizeof(uint8_t) * num_frames * 16); - oocd_trace_read_memory(oocd_trace, trace_data, first_frame, num_frames); - - if (etm_ctx->trace_depth > 0) - free(etm_ctx->trace_data); - - etm_ctx->trace_depth = num_frames * 16; - etm_ctx->trace_data = malloc(sizeof(struct etmv1_trace_data) * etm_ctx->trace_depth); - - for (i = 0; i < num_frames * 16; i++) { - etm_ctx->trace_data[i].pipestat = (trace_data[i] & 0x7); - etm_ctx->trace_data[i].packet = (trace_data[i] & 0x78) >> 3; - etm_ctx->trace_data[i].flags = 0; - - if ((trace_data[i] & 0x80) >> 7) - etm_ctx->trace_data[i].flags |= ETMV1_TRACESYNC_CYCLE; - - if (etm_ctx->trace_data[i].pipestat == STAT_TR) { - etm_ctx->trace_data[i].pipestat = etm_ctx->trace_data[i].packet & 0x7; - etm_ctx->trace_data[i].flags |= ETMV1_TRIGGER_CYCLE; - } - } - - free(trace_data); - - return ERROR_OK; -} - -static int oocd_trace_start_capture(struct etm_context *etm_ctx) -{ - struct oocd_trace *oocd_trace = etm_ctx->capture_driver_priv; - uint32_t control = 0x1; /* 0x1: enabled */ - uint32_t trigger_count; - - if (((etm_ctx->control & ETM_PORT_MODE_MASK) != ETM_PORT_NORMAL) - || ((etm_ctx->control & ETM_PORT_WIDTH_MASK) != ETM_PORT_4BIT)) { - LOG_DEBUG("OpenOCD + trace only supports normal 4-bit ETM mode"); - return ERROR_ETM_PORTMODE_NOT_SUPPORTED; - } - - if ((etm_ctx->control & ETM_PORT_CLOCK_MASK) == ETM_PORT_HALF_CLOCK) - control |= 0x2; /* half rate clock, capture at twice the clock rate */ - - /* OpenOCD + trace holds up to 16 million samples, - * but trigger counts is set in multiples of 16 */ - trigger_count = (1048576 * /* trigger_percent */ 50) / 100; - - /* capturing always starts at address zero */ - oocd_trace_write_reg(oocd_trace, OOCD_TRACE_ADDRESS, 0x0); - oocd_trace_write_reg(oocd_trace, OOCD_TRACE_TRIGGER_COUNTER, trigger_count); - oocd_trace_write_reg(oocd_trace, OOCD_TRACE_CONTROL, control); - - /* we're starting a new trace, initialize capture status */ - etm_ctx->capture_status = TRACE_RUNNING; - - return ERROR_OK; -} - -static int oocd_trace_stop_capture(struct etm_context *etm_ctx) -{ - struct oocd_trace *oocd_trace = etm_ctx->capture_driver_priv; - - /* trace stopped, just clear running flag, but preserve others */ - etm_ctx->capture_status &= ~TRACE_RUNNING; - - oocd_trace_write_reg(oocd_trace, OOCD_TRACE_CONTROL, 0x0); - - return ERROR_OK; -} - -COMMAND_HANDLER(handle_oocd_trace_config_command) -{ - struct target *target; - struct arm *arm; - - if (CMD_ARGC != 2) - return ERROR_COMMAND_SYNTAX_ERROR; - - target = get_current_target(CMD_CTX); - arm = target_to_arm(target); - if (!is_arm(arm)) { - command_print(CMD_CTX, "current target isn't an ARM"); - return ERROR_FAIL; - } - - if (arm->etm) { - struct oocd_trace *oocd_trace = malloc(sizeof(struct oocd_trace)); - - arm->etm->capture_driver_priv = oocd_trace; - oocd_trace->etm_ctx = arm->etm; - - /* copy name of TTY device used to communicate with OpenOCD + trace */ - oocd_trace->tty = strndup(CMD_ARGV[1], 256); - } else - LOG_ERROR("target has no ETM defined, OpenOCD + trace left unconfigured"); - - return ERROR_OK; -} - -COMMAND_HANDLER(handle_oocd_trace_status_command) -{ - struct target *target; - struct arm *arm; - struct oocd_trace *oocd_trace; - uint32_t status; - - target = get_current_target(CMD_CTX); - - arm = target_to_arm(target); - if (!is_arm(arm)) { - command_print(CMD_CTX, "current target isn't an ARM"); - return ERROR_FAIL; - } - - if (!arm->etm) { - command_print(CMD_CTX, "current target doesn't have an ETM configured"); - return ERROR_FAIL; - } - - if (strcmp(arm->etm->capture_driver->name, "oocd_trace") != 0) { - command_print(CMD_CTX, "current target's ETM capture driver isn't 'oocd_trace'"); - return ERROR_FAIL; - } - - oocd_trace = (struct oocd_trace *)arm->etm->capture_driver_priv; - - oocd_trace_read_reg(oocd_trace, OOCD_TRACE_STATUS, &status); - - if (status & 0x8) - command_print(CMD_CTX, "trace clock locked"); - else - command_print(CMD_CTX, "no trace clock"); - - return ERROR_OK; -} - -COMMAND_HANDLER(handle_oocd_trace_resync_command) -{ - struct target *target; - struct arm *arm; - struct oocd_trace *oocd_trace; - size_t bytes_written; - uint8_t cmd_array[1]; - - target = get_current_target(CMD_CTX); - - arm = target_to_arm(target); - if (!is_arm(arm)) { - command_print(CMD_CTX, "current target isn't an ARM"); - return ERROR_FAIL; - } - - if (!arm->etm) { - command_print(CMD_CTX, "current target doesn't have an ETM configured"); - return ERROR_FAIL; - } - - if (strcmp(arm->etm->capture_driver->name, "oocd_trace") != 0) { - command_print(CMD_CTX, "current target's ETM capture driver isn't 'oocd_trace'"); - return ERROR_FAIL; - } - - oocd_trace = (struct oocd_trace *)arm->etm->capture_driver_priv; - - cmd_array[0] = 0xf0; - - bytes_written = write(oocd_trace->tty_fd, cmd_array, 1); - if (bytes_written < 1) - return ERROR_FAIL; - - command_print(CMD_CTX, "requesting traceclock resync"); - LOG_DEBUG("resyncing traceclk pll"); - - return ERROR_OK; -} - -static const struct command_registration oocd_trace_all_command_handlers[] = { - { - .name = "config", - .handler = handle_oocd_trace_config_command, - .mode = COMMAND_CONFIG, - .usage = " ", - }, - { - .name = "status", - .handler = handle_oocd_trace_status_command, - .mode = COMMAND_EXEC, - .usage = "", - .help = "display OpenOCD + trace status", - }, - { - .name = "resync", - .handler = handle_oocd_trace_resync_command, - .mode = COMMAND_EXEC, - .usage = "", - .help = "resync OpenOCD + trace capture clock", - }, - COMMAND_REGISTRATION_DONE -}; -static const struct command_registration oocd_trace_command_handlers[] = { - { - .name = "oocd_trace", - .mode = COMMAND_ANY, - .help = "OpenOCD trace capture driver command group", - .usage = "", - .chain = oocd_trace_all_command_handlers, - }, - COMMAND_REGISTRATION_DONE -}; - -struct etm_capture_driver oocd_trace_capture_driver = { - .name = "oocd_trace", - .commands = oocd_trace_command_handlers, - .init = oocd_trace_init, - .status = oocd_trace_status, - .start_capture = oocd_trace_start_capture, - .stop_capture = oocd_trace_stop_capture, - .read_trace = oocd_trace_read_trace, -}; diff --git a/src/target/oocd_trace.h b/src/target/oocd_trace.h deleted file mode 100644 index e7584e4c9..000000000 --- a/src/target/oocd_trace.h +++ /dev/null @@ -1,53 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifndef OPENOCD_TARGET_OOCD_TRACE_H -#define OPENOCD_TARGET_OOCD_TRACE_H - -#include - -/* registers */ -enum { - OOCD_TRACE_ID = 0x7, - OOCD_TRACE_ADDRESS = 0x0, - OOCD_TRACE_TRIGGER_COUNTER = 0x01, - OOCD_TRACE_CONTROL = 0x2, - OOCD_TRACE_STATUS = 0x3, - OOCD_TRACE_SDRAM_COUNTER = 0x4, -}; - -/* commands */ -enum { - OOCD_TRACE_NOP = 0x0, - OOCD_TRACE_READ_REG = 0x10, - OOCD_TRACE_WRITE_REG = 0x18, - OOCD_TRACE_READ_RAM = 0x20, -/* OOCD_TRACE_WRITE_RAM = 0x28, */ - OOCD_TRACE_RESYNC = 0xf0, -}; - -struct oocd_trace { - struct etm_context *etm_ctx; - char *tty; - int tty_fd; - struct termios oldtio, newtio; -}; - -extern struct etm_capture_driver oocd_trace_capture_driver; - -#endif /* OPENOCD_TARGET_OOCD_TRACE_H */ diff --git a/src/target/openrisc/Makefile.am b/src/target/openrisc/Makefile.am deleted file mode 100644 index b00a30d6f..000000000 --- a/src/target/openrisc/Makefile.am +++ /dev/null @@ -1,18 +0,0 @@ -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 diff --git a/src/target/openrisc/jsp_server.c b/src/target/openrisc/jsp_server.c deleted file mode 100644 index e581fb870..000000000 --- a/src/target/openrisc/jsp_server.c +++ /dev/null @@ -1,245 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2014 by Franck Jullien * - * franck.jullien@gmail.com * - * * - * Based on ./src/server/telnet_server.c * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include - -#include "or1k_tap.h" -#include "or1k_du.h" -#include "jsp_server.h" - -static char *jsp_port; - -/**A skim of the relevant RFCs suggests that if my application simply sent the - * characters IAC DONT LINEMODE (\377\376\042) as soon as the client connects, - * the client should be forced into character mode. However it doesn't make any difference. - */ - -static const char * const negotiate = - "\xFF\xFB\x03" /* IAC WILL Suppress Go Ahead */ - "\xFF\xFB\x01" /* IAC WILL Echo */ - "\xFF\xFD\x03" /* IAC DO Suppress Go Ahead */ - "\xFF\xFE\x01"; /* IAC DON'T Echo */ - -/* The only way we can detect that the socket is closed is the first time - * we write to it, we will fail. Subsequent write operations will - * succeed. Shudder! - */ -static int telnet_write(struct connection *connection, const void *data, int len) -{ - struct telnet_connection *t_con = connection->priv; - if (t_con->closed) - return ERROR_SERVER_REMOTE_CLOSED; - - if (connection_write(connection, data, len) == len) - return ERROR_OK; - t_con->closed = 1; - return ERROR_SERVER_REMOTE_CLOSED; -} - -int jsp_poll_read(void *priv) -{ - struct jsp_service *jsp_service = (struct jsp_service *)priv; - unsigned char out_buffer[10]; - unsigned char in_buffer[10]; - int out_len = 0; - int in_len; - - if (!jsp_service->connection) - return ERROR_FAIL; - - memset(out_buffer, 0, 10); - - or1k_adv_jtag_jsp_xfer(jsp_service->jtag_info, &out_len, out_buffer, &in_len, in_buffer); - if (in_len) - telnet_write(jsp_service->connection, in_buffer, in_len); - - return ERROR_OK; -} - -static int jsp_new_connection(struct connection *connection) -{ - struct telnet_connection *telnet_connection = malloc(sizeof(struct telnet_connection)); - struct jsp_service *jsp_service = connection->service->priv; - - connection->priv = telnet_connection; - - /* initialize telnet connection information */ - telnet_connection->closed = 0; - telnet_connection->line_size = 0; - telnet_connection->line_cursor = 0; - telnet_connection->option_size = 0; - telnet_connection->state = TELNET_STATE_DATA; - - /* negotiate telnet options */ - telnet_write(connection, negotiate, strlen(negotiate)); - - /* print connection banner */ - if (jsp_service->banner) { - telnet_write(connection, jsp_service->banner, strlen(jsp_service->banner)); - telnet_write(connection, "\r\n", 2); - } - - jsp_service->connection = connection; - - int retval = target_register_timer_callback(&jsp_poll_read, 1, 1, jsp_service); - if (ERROR_OK != retval) - return retval; - - return ERROR_OK; -} - -static int jsp_input(struct connection *connection) -{ - int bytes_read; - unsigned char buffer[TELNET_BUFFER_SIZE]; - unsigned char *buf_p; - struct telnet_connection *t_con = connection->priv; - struct jsp_service *jsp_service = connection->service->priv; - - bytes_read = connection_read(connection, buffer, TELNET_BUFFER_SIZE); - - if (bytes_read == 0) - return ERROR_SERVER_REMOTE_CLOSED; - else if (bytes_read == -1) { - LOG_ERROR("error during read: %s", strerror(errno)); - return ERROR_SERVER_REMOTE_CLOSED; - } - - buf_p = buffer; - while (bytes_read) { - switch (t_con->state) { - case TELNET_STATE_DATA: - if (*buf_p == 0xff) - t_con->state = TELNET_STATE_IAC; - else { - int out_len = 1; - int in_len; - unsigned char in_buffer[10]; - or1k_adv_jtag_jsp_xfer(jsp_service->jtag_info, - &out_len, buf_p, &in_len, - in_buffer); - if (in_len) - telnet_write(connection, - in_buffer, in_len); - } - break; - case TELNET_STATE_IAC: - switch (*buf_p) { - case 0xfe: - t_con->state = TELNET_STATE_DONT; - break; - case 0xfd: - t_con->state = TELNET_STATE_DO; - break; - case 0xfc: - t_con->state = TELNET_STATE_WONT; - break; - case 0xfb: - t_con->state = TELNET_STATE_WILL; - break; - } - break; - case TELNET_STATE_SB: - break; - case TELNET_STATE_SE: - break; - case TELNET_STATE_WILL: - case TELNET_STATE_WONT: - case TELNET_STATE_DO: - case TELNET_STATE_DONT: - t_con->state = TELNET_STATE_DATA; - break; - default: - LOG_ERROR("unknown telnet state"); - exit(-1); - } - - bytes_read--; - buf_p++; - } - - return ERROR_OK; -} - -static int jsp_connection_closed(struct connection *connection) -{ - struct telnet_connection *t_con = connection->priv; - struct jsp_service *jsp_service = connection->service->priv; - - if (t_con->prompt) { - free(t_con->prompt); - t_con->prompt = NULL; - } - - int retval = target_unregister_timer_callback(&jsp_poll_read, jsp_service); - if (ERROR_OK != retval) - return retval; - - if (connection->priv) { - free(connection->priv); - connection->priv = NULL; - } else - LOG_ERROR("BUG: connection->priv == NULL"); - - return ERROR_OK; -} - -int jsp_init(struct or1k_jtag *jtag_info, char *banner) -{ - struct jsp_service *jsp_service = malloc(sizeof(struct jsp_service)); - jsp_service->banner = banner; - jsp_service->jtag_info = jtag_info; - - return add_service("jsp", - jsp_port, - 1, - jsp_new_connection, - jsp_input, - jsp_connection_closed, - jsp_service); -} - -COMMAND_HANDLER(handle_jsp_port_command) -{ - return CALL_COMMAND_HANDLER(server_pipe_command, &jsp_port); -} - -static const struct command_registration jsp_command_handlers[] = { - { - .name = "jsp_port", - .handler = handle_jsp_port_command, - .mode = COMMAND_ANY, - .help = "Specify port on which to listen " - "for incoming JSP telnet connections.", - .usage = "[port_num]", - }, - COMMAND_REGISTRATION_DONE -}; - -int jsp_register_commands(struct command_context *cmd_ctx) -{ - jsp_port = strdup("7777"); - return register_commands(cmd_ctx, NULL, jsp_command_handlers); -} - diff --git a/src/target/openrisc/jsp_server.h b/src/target/openrisc/jsp_server.h deleted file mode 100644 index f8e71215a..000000000 --- a/src/target/openrisc/jsp_server.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef OPENOCD_TARGET_OPENRISC_JSP_SERVER_H -#define OPENOCD_TARGET_OPENRISC_JSP_SERVER_H - -#include "or1k_tap.h" -#include "or1k.h" -#include "or1k_du.h" - -struct jsp_service { - char *banner; - struct or1k_jtag *jtag_info; - struct connection *connection; -}; - -int jsp_init(struct or1k_jtag *jtag_info, char *banner); -int jsp_register_commands(struct command_context *cmd_ctx); - -#endif /* OPENOCD_TARGET_OPENRISC_JSP_SERVER_H */ diff --git a/src/target/openrisc/or1k.c b/src/target/openrisc/or1k.c deleted file mode 100644 index 2cc869f9a..000000000 --- a/src/target/openrisc/or1k.c +++ /dev/null @@ -1,1462 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2011 by Julius Baxter * - * julius@opencores.org * - * * - * Copyright (C) 2013 by Marek Czerski * - * ma.czerski@gmail.com * - * * - * Copyright (C) 2013 by Franck Jullien * - * elec4fun@gmail.com * - * * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include -#include -#include -#include -#include -#include "or1k_tap.h" -#include "or1k.h" -#include "or1k_du.h" - -LIST_HEAD(tap_list); -LIST_HEAD(du_list); - -static int or1k_remove_breakpoint(struct target *target, - struct breakpoint *breakpoint); - -static int or1k_read_core_reg(struct target *target, int num); -static int or1k_write_core_reg(struct target *target, int num); - -static struct or1k_core_reg *or1k_core_reg_list_arch_info; - -static const struct or1k_core_reg_init or1k_init_reg_list[] = { - {"r0" , GROUP0 + 1024, "org.gnu.gdb.or1k.group0", NULL}, - {"r1" , GROUP0 + 1025, "org.gnu.gdb.or1k.group0", NULL}, - {"r2" , GROUP0 + 1026, "org.gnu.gdb.or1k.group0", NULL}, - {"r3" , GROUP0 + 1027, "org.gnu.gdb.or1k.group0", NULL}, - {"r4" , GROUP0 + 1028, "org.gnu.gdb.or1k.group0", NULL}, - {"r5" , GROUP0 + 1029, "org.gnu.gdb.or1k.group0", NULL}, - {"r6" , GROUP0 + 1030, "org.gnu.gdb.or1k.group0", NULL}, - {"r7" , GROUP0 + 1031, "org.gnu.gdb.or1k.group0", NULL}, - {"r8" , GROUP0 + 1032, "org.gnu.gdb.or1k.group0", NULL}, - {"r9" , GROUP0 + 1033, "org.gnu.gdb.or1k.group0", NULL}, - {"r10" , GROUP0 + 1034, "org.gnu.gdb.or1k.group0", NULL}, - {"r11" , GROUP0 + 1035, "org.gnu.gdb.or1k.group0", NULL}, - {"r12" , GROUP0 + 1036, "org.gnu.gdb.or1k.group0", NULL}, - {"r13" , GROUP0 + 1037, "org.gnu.gdb.or1k.group0", NULL}, - {"r14" , GROUP0 + 1038, "org.gnu.gdb.or1k.group0", NULL}, - {"r15" , GROUP0 + 1039, "org.gnu.gdb.or1k.group0", NULL}, - {"r16" , GROUP0 + 1040, "org.gnu.gdb.or1k.group0", NULL}, - {"r17" , GROUP0 + 1041, "org.gnu.gdb.or1k.group0", NULL}, - {"r18" , GROUP0 + 1042, "org.gnu.gdb.or1k.group0", NULL}, - {"r19" , GROUP0 + 1043, "org.gnu.gdb.or1k.group0", NULL}, - {"r20" , GROUP0 + 1044, "org.gnu.gdb.or1k.group0", NULL}, - {"r21" , GROUP0 + 1045, "org.gnu.gdb.or1k.group0", NULL}, - {"r22" , GROUP0 + 1046, "org.gnu.gdb.or1k.group0", NULL}, - {"r23" , GROUP0 + 1047, "org.gnu.gdb.or1k.group0", NULL}, - {"r24" , GROUP0 + 1048, "org.gnu.gdb.or1k.group0", NULL}, - {"r25" , GROUP0 + 1049, "org.gnu.gdb.or1k.group0", NULL}, - {"r26" , GROUP0 + 1050, "org.gnu.gdb.or1k.group0", NULL}, - {"r27" , GROUP0 + 1051, "org.gnu.gdb.or1k.group0", NULL}, - {"r28" , GROUP0 + 1052, "org.gnu.gdb.or1k.group0", NULL}, - {"r29" , GROUP0 + 1053, "org.gnu.gdb.or1k.group0", NULL}, - {"r30" , GROUP0 + 1054, "org.gnu.gdb.or1k.group0", NULL}, - {"r31" , GROUP0 + 1055, "org.gnu.gdb.or1k.group0", NULL}, - {"ppc" , GROUP0 + 18, "org.gnu.gdb.or1k.group0", NULL}, - {"npc" , GROUP0 + 16, "org.gnu.gdb.or1k.group0", NULL}, - {"sr" , GROUP0 + 17, "org.gnu.gdb.or1k.group0", NULL}, - {"vr" , GROUP0 + 0, "org.gnu.gdb.or1k.group0", "system"}, - {"upr" , GROUP0 + 1, "org.gnu.gdb.or1k.group0", "system"}, - {"cpucfgr" , GROUP0 + 2, "org.gnu.gdb.or1k.group0", "system"}, - {"dmmucfgr" , GROUP0 + 3, "org.gnu.gdb.or1k.group0", "system"}, - {"immucfgr" , GROUP0 + 4, "org.gnu.gdb.or1k.group0", "system"}, - {"dccfgr" , GROUP0 + 5, "org.gnu.gdb.or1k.group0", "system"}, - {"iccfgr" , GROUP0 + 6, "org.gnu.gdb.or1k.group0", "system"}, - {"dcfgr" , GROUP0 + 7, "org.gnu.gdb.or1k.group0", "system"}, - {"pccfgr" , GROUP0 + 8, "org.gnu.gdb.or1k.group0", "system"}, - {"fpcsr" , GROUP0 + 20, "org.gnu.gdb.or1k.group0", "system"}, - {"epcr0" , GROUP0 + 32, "org.gnu.gdb.or1k.group0", "system"}, - {"epcr1" , GROUP0 + 33, "org.gnu.gdb.or1k.group0", "system"}, - {"epcr2" , GROUP0 + 34, "org.gnu.gdb.or1k.group0", "system"}, - {"epcr3" , GROUP0 + 35, "org.gnu.gdb.or1k.group0", "system"}, - {"epcr4" , GROUP0 + 36, "org.gnu.gdb.or1k.group0", "system"}, - {"epcr5" , GROUP0 + 37, "org.gnu.gdb.or1k.group0", "system"}, - {"epcr6" , GROUP0 + 38, "org.gnu.gdb.or1k.group0", "system"}, - {"epcr7" , GROUP0 + 39, "org.gnu.gdb.or1k.group0", "system"}, - {"epcr8" , GROUP0 + 40, "org.gnu.gdb.or1k.group0", "system"}, - {"epcr9" , GROUP0 + 41, "org.gnu.gdb.or1k.group0", "system"}, - {"epcr10" , GROUP0 + 42, "org.gnu.gdb.or1k.group0", "system"}, - {"epcr11" , GROUP0 + 43, "org.gnu.gdb.or1k.group0", "system"}, - {"epcr12" , GROUP0 + 44, "org.gnu.gdb.or1k.group0", "system"}, - {"epcr13" , GROUP0 + 45, "org.gnu.gdb.or1k.group0", "system"}, - {"epcr14" , GROUP0 + 46, "org.gnu.gdb.or1k.group0", "system"}, - {"epcr15" , GROUP0 + 47, "org.gnu.gdb.or1k.group0", "system"}, - {"eear0" , GROUP0 + 48, "org.gnu.gdb.or1k.group0", "system"}, - {"eear1" , GROUP0 + 49, "org.gnu.gdb.or1k.group0", "system"}, - {"eear2" , GROUP0 + 50, "org.gnu.gdb.or1k.group0", "system"}, - {"eear3" , GROUP0 + 51, "org.gnu.gdb.or1k.group0", "system"}, - {"eear4" , GROUP0 + 52, "org.gnu.gdb.or1k.group0", "system"}, - {"eear5" , GROUP0 + 53, "org.gnu.gdb.or1k.group0", "system"}, - {"eear6" , GROUP0 + 54, "org.gnu.gdb.or1k.group0", "system"}, - {"eear7" , GROUP0 + 55, "org.gnu.gdb.or1k.group0", "system"}, - {"eear8" , GROUP0 + 56, "org.gnu.gdb.or1k.group0", "system"}, - {"eear9" , GROUP0 + 57, "org.gnu.gdb.or1k.group0", "system"}, - {"eear10" , GROUP0 + 58, "org.gnu.gdb.or1k.group0", "system"}, - {"eear11" , GROUP0 + 59, "org.gnu.gdb.or1k.group0", "system"}, - {"eear12" , GROUP0 + 60, "org.gnu.gdb.or1k.group0", "system"}, - {"eear13" , GROUP0 + 61, "org.gnu.gdb.or1k.group0", "system"}, - {"eear14" , GROUP0 + 62, "org.gnu.gdb.or1k.group0", "system"}, - {"eear15" , GROUP0 + 63, "org.gnu.gdb.or1k.group0", "system"}, - {"esr0" , GROUP0 + 64, "org.gnu.gdb.or1k.group0", "system"}, - {"esr1" , GROUP0 + 65, "org.gnu.gdb.or1k.group0", "system"}, - {"esr2" , GROUP0 + 66, "org.gnu.gdb.or1k.group0", "system"}, - {"esr3" , GROUP0 + 67, "org.gnu.gdb.or1k.group0", "system"}, - {"esr4" , GROUP0 + 68, "org.gnu.gdb.or1k.group0", "system"}, - {"esr5" , GROUP0 + 69, "org.gnu.gdb.or1k.group0", "system"}, - {"esr6" , GROUP0 + 70, "org.gnu.gdb.or1k.group0", "system"}, - {"esr7" , GROUP0 + 71, "org.gnu.gdb.or1k.group0", "system"}, - {"esr8" , GROUP0 + 72, "org.gnu.gdb.or1k.group0", "system"}, - {"esr9" , GROUP0 + 73, "org.gnu.gdb.or1k.group0", "system"}, - {"esr10" , GROUP0 + 74, "org.gnu.gdb.or1k.group0", "system"}, - {"esr11" , GROUP0 + 75, "org.gnu.gdb.or1k.group0", "system"}, - {"esr12" , GROUP0 + 76, "org.gnu.gdb.or1k.group0", "system"}, - {"esr13" , GROUP0 + 77, "org.gnu.gdb.or1k.group0", "system"}, - {"esr14" , GROUP0 + 78, "org.gnu.gdb.or1k.group0", "system"}, - {"esr15" , GROUP0 + 79, "org.gnu.gdb.or1k.group0", "system"}, - - {"dmmuucr" , GROUP1 + 0, "org.gnu.gdb.or1k.group1", "dmmu"}, - {"dmmuupr" , GROUP1 + 1, "org.gnu.gdb.or1k.group1", "dmmu"}, - {"dtlbeir" , GROUP1 + 2, "org.gnu.gdb.or1k.group1", "dmmu"}, - {"datbmr0" , GROUP1 + 4, "org.gnu.gdb.or1k.group1", "dmmu"}, - {"datbmr1" , GROUP1 + 5, "org.gnu.gdb.or1k.group1", "dmmu"}, - {"datbmr2" , GROUP1 + 6, "org.gnu.gdb.or1k.group1", "dmmu"}, - {"datbmr3" , GROUP1 + 7, "org.gnu.gdb.or1k.group1", "dmmu"}, - {"datbtr0" , GROUP1 + 8, "org.gnu.gdb.or1k.group1", "dmmu"}, - {"datbtr1" , GROUP1 + 9, "org.gnu.gdb.or1k.group1", "dmmu"}, - {"datbtr2" , GROUP1 + 10, "org.gnu.gdb.or1k.group1", "dmmu"}, - {"datbtr3" , GROUP1 + 11, "org.gnu.gdb.or1k.group1", "dmmu"}, - - {"immucr" , GROUP2 + 0, "org.gnu.gdb.or1k.group2", "immu"}, - {"immupr" , GROUP2 + 1, "org.gnu.gdb.or1k.group2", "immu"}, - {"itlbeir" , GROUP2 + 2, "org.gnu.gdb.or1k.group2", "immu"}, - {"iatbmr0" , GROUP2 + 4, "org.gnu.gdb.or1k.group2", "immu"}, - {"iatbmr1" , GROUP2 + 5, "org.gnu.gdb.or1k.group2", "immu"}, - {"iatbmr2" , GROUP2 + 6, "org.gnu.gdb.or1k.group2", "immu"}, - {"iatbmr3" , GROUP2 + 7, "org.gnu.gdb.or1k.group2", "immu"}, - {"iatbtr0" , GROUP2 + 8, "org.gnu.gdb.or1k.group2", "immu"}, - {"iatbtr1" , GROUP2 + 9, "org.gnu.gdb.or1k.group2", "immu"}, - {"iatbtr2" , GROUP2 + 10, "org.gnu.gdb.or1k.group2", "immu"}, - {"iatbtr3" , GROUP2 + 11, "org.gnu.gdb.or1k.group2", "immu"}, - - {"dccr" , GROUP3 + 0, "org.gnu.gdb.or1k.group3", "dcache"}, - {"dcbpr" , GROUP3 + 1, "org.gnu.gdb.or1k.group3", "dcache"}, - {"dcbfr" , GROUP3 + 2, "org.gnu.gdb.or1k.group3", "dcache"}, - {"dcbir" , GROUP3 + 3, "org.gnu.gdb.or1k.group3", "dcache"}, - {"dcbwr" , GROUP3 + 4, "org.gnu.gdb.or1k.group3", "dcache"}, - {"dcblr" , GROUP3 + 5, "org.gnu.gdb.or1k.group3", "dcache"}, - - {"iccr" , GROUP4 + 0, "org.gnu.gdb.or1k.group4", "icache"}, - {"icbpr" , GROUP4 + 1, "org.gnu.gdb.or1k.group4", "icache"}, - {"icbir" , GROUP4 + 2, "org.gnu.gdb.or1k.group4", "icache"}, - {"icblr" , GROUP4 + 3, "org.gnu.gdb.or1k.group4", "icache"}, - - {"maclo" , GROUP5 + 0, "org.gnu.gdb.or1k.group5", "mac"}, - {"machi" , GROUP5 + 1, "org.gnu.gdb.or1k.group5", "mac"}, - - {"dvr0" , GROUP6 + 0, "org.gnu.gdb.or1k.group6", "debug"}, - {"dvr1" , GROUP6 + 1, "org.gnu.gdb.or1k.group6", "debug"}, - {"dvr2" , GROUP6 + 2, "org.gnu.gdb.or1k.group6", "debug"}, - {"dvr3" , GROUP6 + 3, "org.gnu.gdb.or1k.group6", "debug"}, - {"dvr4" , GROUP6 + 4, "org.gnu.gdb.or1k.group6", "debug"}, - {"dvr5" , GROUP6 + 5, "org.gnu.gdb.or1k.group6", "debug"}, - {"dvr6" , GROUP6 + 6, "org.gnu.gdb.or1k.group6", "debug"}, - {"dvr7" , GROUP6 + 7, "org.gnu.gdb.or1k.group6", "debug"}, - {"dcr0" , GROUP6 + 8, "org.gnu.gdb.or1k.group6", "debug"}, - {"dcr1" , GROUP6 + 9, "org.gnu.gdb.or1k.group6", "debug"}, - {"dcr2" , GROUP6 + 10, "org.gnu.gdb.or1k.group6", "debug"}, - {"dcr3" , GROUP6 + 11, "org.gnu.gdb.or1k.group6", "debug"}, - {"dcr4" , GROUP6 + 12, "org.gnu.gdb.or1k.group6", "debug"}, - {"dcr5" , GROUP6 + 13, "org.gnu.gdb.or1k.group6", "debug"}, - {"dcr6" , GROUP6 + 14, "org.gnu.gdb.or1k.group6", "debug"}, - {"dcr7" , GROUP6 + 15, "org.gnu.gdb.or1k.group6", "debug"}, - {"dmr1" , GROUP6 + 16, "org.gnu.gdb.or1k.group6", "debug"}, - {"dmr2" , GROUP6 + 17, "org.gnu.gdb.or1k.group6", "debug"}, - {"dcwr0" , GROUP6 + 18, "org.gnu.gdb.or1k.group6", "debug"}, - {"dcwr1" , GROUP6 + 19, "org.gnu.gdb.or1k.group6", "debug"}, - {"dsr" , GROUP6 + 20, "org.gnu.gdb.or1k.group6", "debug"}, - {"drr" , GROUP6 + 21, "org.gnu.gdb.or1k.group6", "debug"}, - - {"pccr0" , GROUP7 + 0, "org.gnu.gdb.or1k.group7", "perf"}, - {"pccr1" , GROUP7 + 1, "org.gnu.gdb.or1k.group7", "perf"}, - {"pccr2" , GROUP7 + 2, "org.gnu.gdb.or1k.group7", "perf"}, - {"pccr3" , GROUP7 + 3, "org.gnu.gdb.or1k.group7", "perf"}, - {"pccr4" , GROUP7 + 4, "org.gnu.gdb.or1k.group7", "perf"}, - {"pccr5" , GROUP7 + 5, "org.gnu.gdb.or1k.group7", "perf"}, - {"pccr6" , GROUP7 + 6, "org.gnu.gdb.or1k.group7", "perf"}, - {"pccr7" , GROUP7 + 7, "org.gnu.gdb.or1k.group7", "perf"}, - {"pcmr0" , GROUP7 + 8, "org.gnu.gdb.or1k.group7", "perf"}, - {"pcmr1" , GROUP7 + 9, "org.gnu.gdb.or1k.group7", "perf"}, - {"pcmr2" , GROUP7 + 10, "org.gnu.gdb.or1k.group7", "perf"}, - {"pcmr3" , GROUP7 + 11, "org.gnu.gdb.or1k.group7", "perf"}, - {"pcmr4" , GROUP7 + 12, "org.gnu.gdb.or1k.group7", "perf"}, - {"pcmr5" , GROUP7 + 13, "org.gnu.gdb.or1k.group7", "perf"}, - {"pcmr6" , GROUP7 + 14, "org.gnu.gdb.or1k.group7", "perf"}, - {"pcmr7" , GROUP7 + 15, "org.gnu.gdb.or1k.group7", "perf"}, - - {"pmr" , GROUP8 + 0, "org.gnu.gdb.or1k.group8", "power"}, - - {"picmr" , GROUP9 + 0, "org.gnu.gdb.or1k.group9", "pic"}, - {"picsr" , GROUP9 + 2, "org.gnu.gdb.or1k.group9", "pic"}, - - {"ttmr" , GROUP10 + 0, "org.gnu.gdb.or1k.group10", "timer"}, - {"ttcr" , GROUP10 + 1, "org.gnu.gdb.or1k.group10", "timer"}, -}; - -static int or1k_add_reg(struct target *target, struct or1k_core_reg *new_reg) -{ - struct or1k_common *or1k = target_to_or1k(target); - int reg_list_size = or1k->nb_regs * sizeof(struct or1k_core_reg); - - or1k_core_reg_list_arch_info = realloc(or1k_core_reg_list_arch_info, - reg_list_size + sizeof(struct or1k_core_reg)); - - memcpy(&or1k_core_reg_list_arch_info[or1k->nb_regs], new_reg, - sizeof(struct or1k_core_reg)); - - or1k_core_reg_list_arch_info[or1k->nb_regs].list_num = or1k->nb_regs; - - or1k->nb_regs++; - - return ERROR_OK; -} - -static int or1k_create_reg_list(struct target *target) -{ - struct or1k_common *or1k = target_to_or1k(target); - - LOG_DEBUG("-"); - - or1k_core_reg_list_arch_info = malloc(ARRAY_SIZE(or1k_init_reg_list) * - sizeof(struct or1k_core_reg)); - - for (int i = 0; i < (int)ARRAY_SIZE(or1k_init_reg_list); i++) { - or1k_core_reg_list_arch_info[i].name = or1k_init_reg_list[i].name; - or1k_core_reg_list_arch_info[i].spr_num = or1k_init_reg_list[i].spr_num; - or1k_core_reg_list_arch_info[i].group = or1k_init_reg_list[i].group; - or1k_core_reg_list_arch_info[i].feature = or1k_init_reg_list[i].feature; - or1k_core_reg_list_arch_info[i].list_num = i; - or1k_core_reg_list_arch_info[i].target = NULL; - or1k_core_reg_list_arch_info[i].or1k_common = NULL; - } - - or1k->nb_regs = ARRAY_SIZE(or1k_init_reg_list); - - struct or1k_core_reg new_reg; - new_reg.target = NULL; - new_reg.or1k_common = NULL; - - char name[32]; - for (int way = 0; way < 4; way++) { - for (int i = 0; i < 128; i++) { - - sprintf(name, "dtlbw%dmr%d", way, i); - new_reg.name = strdup(name); - new_reg.spr_num = GROUP1 + 512 + i + (way * 256); - new_reg.feature = "org.gnu.gdb.or1k.group1"; - new_reg.group = "dmmu"; - or1k_add_reg(target, &new_reg); - - sprintf(name, "dtlbw%dtr%d", way, i); - new_reg.name = strdup(name); - new_reg.spr_num = GROUP1 + 640 + i + (way * 256); - new_reg.feature = "org.gnu.gdb.or1k.group1"; - new_reg.group = "dmmu"; - or1k_add_reg(target, &new_reg); - - - sprintf(name, "itlbw%dmr%d", way, i); - new_reg.name = strdup(name); - new_reg.spr_num = GROUP2 + 512 + i + (way * 256); - new_reg.feature = "org.gnu.gdb.or1k.group2"; - new_reg.group = "immu"; - or1k_add_reg(target, &new_reg); - - - sprintf(name, "itlbw%dtr%d", way, i); - new_reg.name = strdup(name); - new_reg.spr_num = GROUP2 + 640 + i + (way * 256); - new_reg.feature = "org.gnu.gdb.or1k.group2"; - new_reg.group = "immu"; - or1k_add_reg(target, &new_reg); - - } - } - - return ERROR_OK; -} - -static int or1k_jtag_read_regs(struct or1k_common *or1k, uint32_t *regs) -{ - struct or1k_du *du_core = or1k_jtag_to_du(&or1k->jtag); - - LOG_DEBUG("-"); - - return du_core->or1k_jtag_read_cpu(&or1k->jtag, - or1k->arch_info[OR1K_REG_R0].spr_num, OR1K_REG_R31 + 1, - regs + OR1K_REG_R0); -} - -static int or1k_jtag_write_regs(struct or1k_common *or1k, uint32_t *regs) -{ - struct or1k_du *du_core = or1k_jtag_to_du(&or1k->jtag); - - LOG_DEBUG("-"); - - return du_core->or1k_jtag_write_cpu(&or1k->jtag, - or1k->arch_info[OR1K_REG_R0].spr_num, OR1K_REG_R31 + 1, - ®s[OR1K_REG_R0]); -} - -static int or1k_save_context(struct target *target) -{ - struct or1k_common *or1k = target_to_or1k(target); - struct or1k_du *du_core = or1k_to_du(or1k); - int regs_read = 0; - int retval; - - LOG_DEBUG("-"); - - for (int i = 0; i < OR1KNUMCOREREGS; i++) { - if (!or1k->core_cache->reg_list[i].valid) { - if (i == OR1K_REG_PPC || i == OR1K_REG_NPC || i == OR1K_REG_SR) { - retval = du_core->or1k_jtag_read_cpu(&or1k->jtag, - or1k->arch_info[i].spr_num, 1, - &or1k->core_regs[i]); - if (retval != ERROR_OK) - return retval; - } else if (!regs_read) { - /* read gpr registers at once (but only one time in this loop) */ - retval = or1k_jtag_read_regs(or1k, or1k->core_regs); - if (retval != ERROR_OK) - return retval; - /* prevent next reads in this loop */ - regs_read = 1; - } - /* We've just updated the core_reg[i], now update - the core cache */ - or1k_read_core_reg(target, i); - } - } - - return ERROR_OK; -} - -static int or1k_restore_context(struct target *target) -{ - struct or1k_common *or1k = target_to_or1k(target); - struct or1k_du *du_core = or1k_to_du(or1k); - int reg_write = 0; - int retval; - - LOG_DEBUG("-"); - - for (int i = 0; i < OR1KNUMCOREREGS; i++) { - if (or1k->core_cache->reg_list[i].dirty) { - or1k_write_core_reg(target, i); - - if (i == OR1K_REG_PPC || i == OR1K_REG_NPC || i == OR1K_REG_SR) { - retval = du_core->or1k_jtag_write_cpu(&or1k->jtag, - or1k->arch_info[i].spr_num, 1, - &or1k->core_regs[i]); - if (retval != ERROR_OK) { - LOG_ERROR("Error while restoring context"); - return retval; - } - } else - reg_write = 1; - } - } - - if (reg_write) { - /* read gpr registers at once (but only one time in this loop) */ - retval = or1k_jtag_write_regs(or1k, or1k->core_regs); - if (retval != ERROR_OK) { - LOG_ERROR("Error while restoring context"); - return retval; - } - } - - return ERROR_OK; -} - -static int or1k_read_core_reg(struct target *target, int num) -{ - struct or1k_common *or1k = target_to_or1k(target); - struct or1k_du *du_core = or1k_to_du(or1k); - uint32_t reg_value; - - LOG_DEBUG("-"); - - if ((num < 0) || (num >= or1k->nb_regs)) - return ERROR_COMMAND_SYNTAX_ERROR; - - if ((num >= 0) && (num < OR1KNUMCOREREGS)) { - reg_value = or1k->core_regs[num]; - buf_set_u32(or1k->core_cache->reg_list[num].value, 0, 32, reg_value); - LOG_DEBUG("Read core reg %i value 0x%08" PRIx32, num , reg_value); - or1k->core_cache->reg_list[num].valid = 1; - or1k->core_cache->reg_list[num].dirty = 0; - } else { - /* This is an spr, always read value from HW */ - int retval = du_core->or1k_jtag_read_cpu(&or1k->jtag, - or1k->arch_info[num].spr_num, 1, ®_value); - if (retval != ERROR_OK) { - LOG_ERROR("Error while reading spr 0x%08" PRIx32, or1k->arch_info[num].spr_num); - return retval; - } - buf_set_u32(or1k->core_cache->reg_list[num].value, 0, 32, reg_value); - LOG_DEBUG("Read spr reg %i value 0x%08" PRIx32, num , reg_value); - } - - return ERROR_OK; -} - -static int or1k_write_core_reg(struct target *target, int num) -{ - struct or1k_common *or1k = target_to_or1k(target); - - LOG_DEBUG("-"); - - if ((num < 0) || (num >= OR1KNUMCOREREGS)) - return ERROR_COMMAND_SYNTAX_ERROR; - - uint32_t reg_value = buf_get_u32(or1k->core_cache->reg_list[num].value, 0, 32); - or1k->core_regs[num] = reg_value; - LOG_DEBUG("Write core reg %i value 0x%08" PRIx32, num , reg_value); - or1k->core_cache->reg_list[num].valid = 1; - or1k->core_cache->reg_list[num].dirty = 0; - - return ERROR_OK; -} - -static int or1k_get_core_reg(struct reg *reg) -{ - struct or1k_core_reg *or1k_reg = reg->arch_info; - struct target *target = or1k_reg->target; - - LOG_DEBUG("-"); - - if (target->state != TARGET_HALTED) - return ERROR_TARGET_NOT_HALTED; - - return or1k_read_core_reg(target, or1k_reg->list_num); -} - -static int or1k_set_core_reg(struct reg *reg, uint8_t *buf) -{ - struct or1k_core_reg *or1k_reg = reg->arch_info; - struct target *target = or1k_reg->target; - struct or1k_common *or1k = target_to_or1k(target); - struct or1k_du *du_core = or1k_to_du(or1k); - uint32_t value = buf_get_u32(buf, 0, 32); - - LOG_DEBUG("-"); - - if (target->state != TARGET_HALTED) - return ERROR_TARGET_NOT_HALTED; - - if (or1k_reg->list_num < OR1KNUMCOREREGS) { - buf_set_u32(reg->value, 0, 32, value); - reg->dirty = 1; - reg->valid = 1; - } else { - /* This is an spr, write it to the HW */ - int retval = du_core->or1k_jtag_write_cpu(&or1k->jtag, - or1k_reg->spr_num, 1, &value); - if (retval != ERROR_OK) { - LOG_ERROR("Error while writing spr 0x%08" PRIx32, or1k_reg->spr_num); - return retval; - } - } - - return ERROR_OK; -} - -static const struct reg_arch_type or1k_reg_type = { - .get = or1k_get_core_reg, - .set = or1k_set_core_reg, -}; - -static struct reg_cache *or1k_build_reg_cache(struct target *target) -{ - struct or1k_common *or1k = target_to_or1k(target); - struct reg_cache **cache_p = register_get_last_cache_p(&target->reg_cache); - struct reg_cache *cache = malloc(sizeof(struct reg_cache)); - struct reg *reg_list = calloc(or1k->nb_regs, sizeof(struct reg)); - struct or1k_core_reg *arch_info = - malloc((or1k->nb_regs) * sizeof(struct or1k_core_reg)); - struct reg_feature *feature; - - LOG_DEBUG("-"); - - /* Build the process context cache */ - cache->name = "OpenRISC 1000 registers"; - cache->next = NULL; - cache->reg_list = reg_list; - cache->num_regs = or1k->nb_regs; - (*cache_p) = cache; - or1k->core_cache = cache; - or1k->arch_info = arch_info; - - for (int i = 0; i < or1k->nb_regs; i++) { - arch_info[i] = or1k_core_reg_list_arch_info[i]; - arch_info[i].target = target; - arch_info[i].or1k_common = or1k; - reg_list[i].name = or1k_core_reg_list_arch_info[i].name; - - feature = malloc(sizeof(struct reg_feature)); - feature->name = or1k_core_reg_list_arch_info[i].feature; - reg_list[i].feature = feature; - - reg_list[i].group = or1k_core_reg_list_arch_info[i].group; - reg_list[i].size = 32; - reg_list[i].value = calloc(1, 4); - reg_list[i].dirty = 0; - reg_list[i].valid = 0; - reg_list[i].type = &or1k_reg_type; - reg_list[i].arch_info = &arch_info[i]; - reg_list[i].number = i; - reg_list[i].exist = true; - } - - return cache; -} - -static int or1k_debug_entry(struct target *target) -{ - LOG_DEBUG("-"); - - int retval = or1k_save_context(target); - if (retval != ERROR_OK) { - LOG_ERROR("Error while calling or1k_save_context"); - return retval; - } - - struct or1k_common *or1k = target_to_or1k(target); - uint32_t addr = or1k->core_regs[OR1K_REG_NPC]; - - if (breakpoint_find(target, addr)) - /* Halted on a breakpoint, step back to permit executing the instruction there */ - retval = or1k_set_core_reg(&or1k->core_cache->reg_list[OR1K_REG_NPC], - (uint8_t *)&addr); - - return retval; -} - -static int or1k_halt(struct target *target) -{ - struct or1k_common *or1k = target_to_or1k(target); - struct or1k_du *du_core = or1k_to_du(or1k); - - LOG_DEBUG("target->state: %s", - target_state_name(target)); - - if (target->state == TARGET_HALTED) { - LOG_DEBUG("Target was already halted"); - return ERROR_OK; - } - - if (target->state == TARGET_UNKNOWN) - LOG_WARNING("Target was in unknown state when halt was requested"); - - if (target->state == TARGET_RESET) { - if ((jtag_get_reset_config() & RESET_SRST_PULLS_TRST) && - jtag_get_srst()) { - LOG_ERROR("Can't request a halt while in reset if nSRST pulls nTRST"); - return ERROR_TARGET_FAILURE; - } else { - target->debug_reason = DBG_REASON_DBGRQ; - return ERROR_OK; - } - } - - int retval = du_core->or1k_cpu_stall(&or1k->jtag, CPU_STALL); - if (retval != ERROR_OK) { - LOG_ERROR("Impossible to stall the CPU"); - return retval; - } - - target->debug_reason = DBG_REASON_DBGRQ; - - return ERROR_OK; -} - -static int or1k_is_cpu_running(struct target *target, int *running) -{ - struct or1k_common *or1k = target_to_or1k(target); - struct or1k_du *du_core = or1k_to_du(or1k); - int retval; - int tries = 0; - const int RETRIES_MAX = 5; - - /* Have a retry loop to determine of the CPU is running. - If target has been hard reset for any reason, it might take a couple - of goes before it's ready again. - */ - while (tries < RETRIES_MAX) { - - tries++; - - retval = du_core->or1k_is_cpu_running(&or1k->jtag, running); - if (retval != ERROR_OK) { - LOG_WARNING("Debug IF CPU control reg read failure."); - /* Try once to restart the JTAG infrastructure - - quite possibly the board has just been reset. */ - LOG_WARNING("Resetting JTAG TAP state and reconnectiong to debug IF."); - du_core->or1k_jtag_init(&or1k->jtag); - - LOG_WARNING("...attempt %d of %d", tries, RETRIES_MAX); - - alive_sleep(2); - - continue; - } else - return ERROR_OK; - } - - LOG_ERROR("Could not re-establish communication with target"); - return retval; -} - -static int or1k_poll(struct target *target) -{ - int retval; - int running; - - retval = or1k_is_cpu_running(target, &running); - if (retval != ERROR_OK) { - LOG_ERROR("Error while calling or1k_is_cpu_running"); - return retval; - } - - /* check for processor halted */ - if (!running) { - /* It's actually stalled, so update our software's state */ - if ((target->state == TARGET_RUNNING) || - (target->state == TARGET_RESET)) { - - target->state = TARGET_HALTED; - - retval = or1k_debug_entry(target); - if (retval != ERROR_OK) { - LOG_ERROR("Error while calling or1k_debug_entry"); - return retval; - } - - target_call_event_callbacks(target, - TARGET_EVENT_HALTED); - } else if (target->state == TARGET_DEBUG_RUNNING) { - target->state = TARGET_HALTED; - - retval = or1k_debug_entry(target); - if (retval != ERROR_OK) { - LOG_ERROR("Error while calling or1k_debug_entry"); - return retval; - } - - target_call_event_callbacks(target, - TARGET_EVENT_DEBUG_HALTED); - } - } else { /* ... target is running */ - - /* If target was supposed to be stalled, stall it again */ - if (target->state == TARGET_HALTED) { - - target->state = TARGET_RUNNING; - - retval = or1k_halt(target); - if (retval != ERROR_OK) { - LOG_ERROR("Error while calling or1k_halt"); - return retval; - } - - retval = or1k_debug_entry(target); - if (retval != ERROR_OK) { - LOG_ERROR("Error while calling or1k_debug_entry"); - return retval; - } - - target_call_event_callbacks(target, - TARGET_EVENT_DEBUG_HALTED); - } - - target->state = TARGET_RUNNING; - - } - - return ERROR_OK; -} - -static int or1k_assert_reset(struct target *target) -{ - struct or1k_common *or1k = target_to_or1k(target); - struct or1k_du *du_core = or1k_to_du(or1k); - - LOG_DEBUG("-"); - - int retval = du_core->or1k_cpu_reset(&or1k->jtag, CPU_RESET); - if (retval != ERROR_OK) { - LOG_ERROR("Error while asserting RESET"); - return retval; - } - - return ERROR_OK; -} - -static int or1k_deassert_reset(struct target *target) -{ - struct or1k_common *or1k = target_to_or1k(target); - struct or1k_du *du_core = or1k_to_du(or1k); - - LOG_DEBUG("-"); - - int retval = du_core->or1k_cpu_reset(&or1k->jtag, CPU_NOT_RESET); - if (retval != ERROR_OK) { - LOG_ERROR("Error while desasserting RESET"); - return retval; - } - - return ERROR_OK; -} - -static int or1k_soft_reset_halt(struct target *target) -{ - struct or1k_common *or1k = target_to_or1k(target); - struct or1k_du *du_core = or1k_to_du(or1k); - - LOG_DEBUG("-"); - - int retval = du_core->or1k_cpu_stall(&or1k->jtag, CPU_STALL); - if (retval != ERROR_OK) { - LOG_ERROR("Error while stalling the CPU"); - return retval; - } - - retval = or1k_assert_reset(target); - if (retval != ERROR_OK) - return retval; - - retval = or1k_deassert_reset(target); - if (retval != ERROR_OK) - return retval; - - return ERROR_OK; -} - -static bool is_any_soft_breakpoint(struct target *target) -{ - struct breakpoint *breakpoint = target->breakpoints; - - LOG_DEBUG("-"); - - while (breakpoint) - if (breakpoint->type == BKPT_SOFT) - return true; - - return false; -} - -static int or1k_resume_or_step(struct target *target, int current, - uint32_t address, int handle_breakpoints, - int debug_execution, int step) -{ - struct or1k_common *or1k = target_to_or1k(target); - struct or1k_du *du_core = or1k_to_du(or1k); - struct breakpoint *breakpoint = NULL; - uint32_t resume_pc; - uint32_t debug_reg_list[OR1K_DEBUG_REG_NUM]; - - LOG_DEBUG("Addr: 0x%" PRIx32 ", stepping: %s, handle breakpoints %s\n", - address, step ? "yes" : "no", handle_breakpoints ? "yes" : "no"); - - if (target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - if (!debug_execution) - target_free_all_working_areas(target); - - /* current ? continue on current pc : continue at
*/ - if (!current) - buf_set_u32(or1k->core_cache->reg_list[OR1K_REG_NPC].value, 0, - 32, address); - - int retval = or1k_restore_context(target); - if (retval != ERROR_OK) { - LOG_ERROR("Error while calling or1k_restore_context"); - return retval; - } - - /* read debug registers (starting from DMR1 register) */ - retval = du_core->or1k_jtag_read_cpu(&or1k->jtag, OR1K_DMR1_CPU_REG_ADD, - OR1K_DEBUG_REG_NUM, debug_reg_list); - if (retval != ERROR_OK) { - LOG_ERROR("Error while reading debug registers"); - return retval; - } - - /* Clear Debug Reason Register (DRR) */ - debug_reg_list[OR1K_DEBUG_REG_DRR] = 0; - - /* Clear watchpoint break generation in Debug Mode Register 2 (DMR2) */ - debug_reg_list[OR1K_DEBUG_REG_DMR2] &= ~OR1K_DMR2_WGB; - if (step) - /* Set the single step trigger in Debug Mode Register 1 (DMR1) */ - debug_reg_list[OR1K_DEBUG_REG_DMR1] |= OR1K_DMR1_ST | OR1K_DMR1_BT; - else - /* Clear the single step trigger in Debug Mode Register 1 (DMR1) */ - debug_reg_list[OR1K_DEBUG_REG_DMR1] &= ~(OR1K_DMR1_ST | OR1K_DMR1_BT); - - /* Set traps to be handled by the debug unit in the Debug Stop - Register (DSR). Check if we have any software breakpoints in - place before setting this value - the kernel, for instance, - relies on l.trap instructions not stalling the processor ! */ - if (is_any_soft_breakpoint(target) == true) - debug_reg_list[OR1K_DEBUG_REG_DSR] |= OR1K_DSR_TE; - - /* Write debug registers (starting from DMR1 register) */ - retval = du_core->or1k_jtag_write_cpu(&or1k->jtag, OR1K_DMR1_CPU_REG_ADD, - OR1K_DEBUG_REG_NUM, debug_reg_list); - if (retval != ERROR_OK) { - LOG_ERROR("Error while writing back debug registers"); - return retval; - } - - resume_pc = buf_get_u32(or1k->core_cache->reg_list[OR1K_REG_NPC].value, - 0, 32); - - /* The front-end may request us not to handle breakpoints */ - if (handle_breakpoints) { - /* 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); - retval = or1k_remove_breakpoint(target, breakpoint); - if (retval != ERROR_OK) - return retval; - } - } - - /* Unstall time */ - retval = du_core->or1k_cpu_stall(&or1k->jtag, CPU_UNSTALL); - if (retval != ERROR_OK) { - LOG_ERROR("Error while unstalling the CPU"); - return retval; - } - - if (step) - target->debug_reason = DBG_REASON_SINGLESTEP; - else - target->debug_reason = DBG_REASON_NOTHALTED; - - /* Registers are now invalid */ - register_cache_invalidate(or1k->core_cache); - - if (!debug_execution) { - target->state = TARGET_RUNNING; - target_call_event_callbacks(target, TARGET_EVENT_RESUMED); - LOG_DEBUG("Target resumed at 0x%08" PRIx32, resume_pc); - } else { - target->state = TARGET_DEBUG_RUNNING; - target_call_event_callbacks(target, TARGET_EVENT_DEBUG_RESUMED); - LOG_DEBUG("Target debug resumed at 0x%08" PRIx32, resume_pc); - } - - return ERROR_OK; -} - -static int or1k_resume(struct target *target, int current, - uint32_t address, int handle_breakpoints, int debug_execution) -{ - return or1k_resume_or_step(target, current, address, - handle_breakpoints, - debug_execution, - NO_SINGLE_STEP); -} - -static int or1k_step(struct target *target, int current, - uint32_t address, int handle_breakpoints) -{ - return or1k_resume_or_step(target, current, address, - handle_breakpoints, - 0, - SINGLE_STEP); - -} - -static int or1k_add_breakpoint(struct target *target, - struct breakpoint *breakpoint) -{ - struct or1k_common *or1k = target_to_or1k(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, - breakpoint->address, breakpoint->length, breakpoint->type, - breakpoint->set, breakpoint->unique_id); - - /* Only support SW breakpoints for now. */ - if (breakpoint->type == BKPT_HARD) - LOG_ERROR("HW breakpoints not supported for now. Doing SW breakpoint."); - - /* Read and save the instruction */ - int retval = du_core->or1k_jtag_read_memory(&or1k->jtag, - breakpoint->address, - 4, - 1, - &data); - if (retval != ERROR_OK) { - LOG_ERROR("Error while reading the instruction at 0x%08" PRIx32, - breakpoint->address); - return retval; - } - - if (breakpoint->orig_instr != NULL) - free(breakpoint->orig_instr); - - breakpoint->orig_instr = malloc(breakpoint->length); - memcpy(breakpoint->orig_instr, &data, breakpoint->length); - - /* Sub in the OR1K trap instruction */ - uint8_t or1k_trap_insn[4]; - target_buffer_set_u32(target, or1k_trap_insn, OR1K_TRAP_INSTR); - retval = du_core->or1k_jtag_write_memory(&or1k->jtag, - breakpoint->address, - 4, - 1, - or1k_trap_insn); - - if (retval != ERROR_OK) { - LOG_ERROR("Error while writing OR1K_TRAP_INSTR at 0x%08" PRIx32, - breakpoint->address); - return retval; - } - - /* invalidate instruction cache */ - retval = du_core->or1k_jtag_write_cpu(&or1k->jtag, - OR1K_ICBIR_CPU_REG_ADD, 1, &breakpoint->address); - if (retval != ERROR_OK) { - LOG_ERROR("Error while invalidating the ICACHE"); - return retval; - } - - return ERROR_OK; -} - -static int or1k_remove_breakpoint(struct target *target, - struct breakpoint *breakpoint) -{ - 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, - breakpoint->address, breakpoint->length, breakpoint->type, - breakpoint->set, breakpoint->unique_id); - - /* Only support SW breakpoints for now. */ - if (breakpoint->type == BKPT_HARD) - LOG_ERROR("HW breakpoints not supported for now. Doing SW breakpoint."); - - /* Replace the removed instruction */ - int retval = du_core->or1k_jtag_write_memory(&or1k->jtag, - breakpoint->address, - 4, - 1, - breakpoint->orig_instr); - - if (retval != ERROR_OK) { - LOG_ERROR("Error while writing back the instruction at 0x%08" PRIx32, - breakpoint->address); - return retval; - } - - /* invalidate instruction cache */ - retval = du_core->or1k_jtag_write_cpu(&or1k->jtag, - OR1K_ICBIR_CPU_REG_ADD, 1, &breakpoint->address); - if (retval != ERROR_OK) { - LOG_ERROR("Error while invalidating the ICACHE"); - return retval; - } - - return ERROR_OK; -} - -static int or1k_add_watchpoint(struct target *target, - struct watchpoint *watchpoint) -{ - LOG_ERROR("%s: implement me", __func__); - return ERROR_OK; -} - -static int or1k_remove_watchpoint(struct target *target, - struct watchpoint *watchpoint) -{ - LOG_ERROR("%s: implement me", __func__); - return ERROR_OK; -} - -static int or1k_read_memory(struct target *target, uint32_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); - - if (target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - /* Sanitize arguments */ - if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !buffer) { - LOG_ERROR("Bad arguments"); - return ERROR_COMMAND_SYNTAX_ERROR; - } - - if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u))) { - LOG_ERROR("Can't handle unaligned memory access"); - return ERROR_TARGET_UNALIGNED_ACCESS; - } - - return du_core->or1k_jtag_read_memory(&or1k->jtag, address, size, count, buffer); -} - -static int or1k_write_memory(struct target *target, uint32_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); - - if (target->state != TARGET_HALTED) { - LOG_WARNING("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - /* Sanitize arguments */ - if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !buffer) { - LOG_ERROR("Bad arguments"); - return ERROR_COMMAND_SYNTAX_ERROR; - } - - if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u))) { - LOG_ERROR("Can't handle unaligned memory access"); - return ERROR_TARGET_UNALIGNED_ACCESS; - } - - return du_core->or1k_jtag_write_memory(&or1k->jtag, address, size, count, buffer); -} - -static int or1k_init_target(struct command_context *cmd_ctx, - struct target *target) -{ - struct or1k_common *or1k = target_to_or1k(target); - struct or1k_du *du_core = or1k_to_du(or1k); - struct or1k_jtag *jtag = &or1k->jtag; - - if (du_core == NULL) { - LOG_ERROR("No debug unit selected"); - return ERROR_FAIL; - } - - if (jtag->tap_ip == NULL) { - LOG_ERROR("No tap selected"); - return ERROR_FAIL; - } - - or1k->jtag.tap = target->tap; - or1k->jtag.or1k_jtag_inited = 0; - or1k->jtag.or1k_jtag_module_selected = -1; - or1k->jtag.target = target; - - or1k_build_reg_cache(target); - - return ERROR_OK; -} - -static int or1k_target_create(struct target *target, Jim_Interp *interp) -{ - if (target->tap == NULL) - return ERROR_FAIL; - - struct or1k_common *or1k = calloc(1, sizeof(struct or1k_common)); - - target->arch_info = or1k; - - or1k_create_reg_list(target); - - or1k_tap_vjtag_register(); - or1k_tap_xilinx_bscan_register(); - or1k_tap_mohor_register(); - - or1k_du_adv_register(); - - return ERROR_OK; -} - -static int or1k_examine(struct target *target) -{ - struct or1k_common *or1k = target_to_or1k(target); - struct or1k_du *du_core = or1k_to_du(or1k); - - if (!target_was_examined(target)) { - - target_set_examined(target); - - int running; - - int retval = du_core->or1k_is_cpu_running(&or1k->jtag, &running); - if (retval != ERROR_OK) { - LOG_ERROR("Couldn't read the CPU state"); - return retval; - } else { - if (running) - target->state = TARGET_RUNNING; - else { - LOG_DEBUG("Target is halted"); - - /* This is the first time we examine the target, - * it is stalled and we don't know why. Let's - * assume this is because of a debug reason. - */ - if (target->state == TARGET_UNKNOWN) - target->debug_reason = DBG_REASON_DBGRQ; - - target->state = TARGET_HALTED; - } - } - } - - return ERROR_OK; -} - -static int or1k_arch_state(struct target *target) -{ - return ERROR_OK; -} - -static int or1k_get_gdb_reg_list(struct target *target, struct reg **reg_list[], - int *reg_list_size, enum target_register_class reg_class) -{ - struct or1k_common *or1k = target_to_or1k(target); - - if (reg_class == REG_CLASS_GENERAL) { - /* We will have this called whenever GDB connects. */ - int retval = or1k_save_context(target); - if (retval != ERROR_OK) { - LOG_ERROR("Error while calling or1k_save_context"); - return retval; - } - *reg_list_size = OR1KNUMCOREREGS; - /* this is free()'d back in gdb_server.c's gdb_get_register_packet() */ - *reg_list = malloc((*reg_list_size) * sizeof(struct reg *)); - - for (int i = 0; i < OR1KNUMCOREREGS; i++) - (*reg_list)[i] = &or1k->core_cache->reg_list[i]; - } else { - *reg_list_size = or1k->nb_regs; - *reg_list = malloc((*reg_list_size) * sizeof(struct reg *)); - - for (int i = 0; i < or1k->nb_regs; i++) - (*reg_list)[i] = &or1k->core_cache->reg_list[i]; - } - - return ERROR_OK; - -} - -int or1k_get_gdb_fileio_info(struct target *target, struct gdb_fileio_info *fileio_info) -{ - return ERROR_FAIL; -} - -static int or1k_checksum_memory(struct target *target, uint32_t address, - uint32_t count, uint32_t *checksum) { - - return ERROR_FAIL; -} - -static int or1k_profiling(struct target *target, uint32_t *samples, - uint32_t max_num_samples, uint32_t *num_samples, uint32_t seconds) -{ - struct timeval timeout, now; - struct or1k_common *or1k = target_to_or1k(target); - struct or1k_du *du_core = or1k_to_du(or1k); - int retval = ERROR_OK; - - gettimeofday(&timeout, NULL); - timeval_add_time(&timeout, seconds, 0); - - LOG_INFO("Starting or1k profiling. Sampling npc as fast as we can..."); - - /* Make sure the target is running */ - target_poll(target); - if (target->state == TARGET_HALTED) - retval = target_resume(target, 1, 0, 0, 0); - - if (retval != ERROR_OK) { - LOG_ERROR("Error while resuming target"); - return retval; - } - - uint32_t sample_count = 0; - - for (;;) { - uint32_t reg_value; - retval = du_core->or1k_jtag_read_cpu(&or1k->jtag, GROUP0 + 16 /* NPC */, 1, ®_value); - if (retval != ERROR_OK) { - LOG_ERROR("Error while reading NPC"); - return retval; - } - - samples[sample_count++] = reg_value; - - 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; -} - -COMMAND_HANDLER(or1k_tap_select_command_handler) -{ - struct target *target = get_current_target(CMD_CTX); - struct or1k_common *or1k = target_to_or1k(target); - struct or1k_jtag *jtag = &or1k->jtag; - struct or1k_tap_ip *or1k_tap; - - if (CMD_ARGC != 1) - return ERROR_COMMAND_SYNTAX_ERROR; - - list_for_each_entry(or1k_tap, &tap_list, list) { - if (or1k_tap->name) { - if (!strcmp(CMD_ARGV[0], or1k_tap->name)) { - jtag->tap_ip = or1k_tap; - LOG_INFO("%s tap selected", or1k_tap->name); - return ERROR_OK; - } - } - } - - LOG_ERROR("%s unknown, no tap selected", CMD_ARGV[0]); - return ERROR_COMMAND_SYNTAX_ERROR; -} - -COMMAND_HANDLER(or1k_tap_list_command_handler) -{ - struct or1k_tap_ip *or1k_tap; - - if (CMD_ARGC != 0) - return ERROR_COMMAND_SYNTAX_ERROR; - - list_for_each_entry(or1k_tap, &tap_list, list) { - if (or1k_tap->name) - command_print(CMD_CTX, "%s", or1k_tap->name); - } - - return ERROR_OK; -} - -COMMAND_HANDLER(or1k_du_select_command_handler) -{ - struct target *target = get_current_target(CMD_CTX); - struct or1k_common *or1k = target_to_or1k(target); - struct or1k_jtag *jtag = &or1k->jtag; - struct or1k_du *or1k_du; - - if (CMD_ARGC > 2) - return ERROR_COMMAND_SYNTAX_ERROR; - - list_for_each_entry(or1k_du, &du_list, list) { - if (or1k_du->name) { - if (!strcmp(CMD_ARGV[0], or1k_du->name)) { - jtag->du_core = or1k_du; - LOG_INFO("%s debug unit selected", or1k_du->name); - - if (CMD_ARGC == 2) { - int options; - COMMAND_PARSE_NUMBER(int, CMD_ARGV[1], options); - or1k_du->options = options; - LOG_INFO("Option %x is passed to %s debug unit" - , options, or1k_du->name); - } - - return ERROR_OK; - } - } - } - - LOG_ERROR("%s unknown, no debug unit selected", CMD_ARGV[0]); - return ERROR_COMMAND_SYNTAX_ERROR; -} - -COMMAND_HANDLER(or1k_du_list_command_handler) -{ - struct or1k_du *or1k_du; - - if (CMD_ARGC != 0) - return ERROR_COMMAND_SYNTAX_ERROR; - - list_for_each_entry(or1k_du, &du_list, list) { - if (or1k_du->name) - command_print(CMD_CTX, "%s", or1k_du->name); - } - - return ERROR_OK; -} - -COMMAND_HANDLER(or1k_addreg_command_handler) -{ - struct target *target = get_current_target(CMD_CTX); - struct or1k_core_reg new_reg; - - if (CMD_ARGC != 4) - return ERROR_COMMAND_SYNTAX_ERROR; - - new_reg.target = NULL; - new_reg.or1k_common = NULL; - - uint32_t addr; - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], addr); - - new_reg.name = strdup(CMD_ARGV[0]); - new_reg.spr_num = addr; - new_reg.feature = strdup(CMD_ARGV[2]); - new_reg.group = strdup(CMD_ARGV[3]); - - or1k_add_reg(target, &new_reg); - - LOG_DEBUG("Add reg \"%s\" @ 0x%08" PRIx32 ", group \"%s\", feature \"%s\"", - new_reg.name, addr, new_reg.group, new_reg.feature); - - return ERROR_OK; -} - -static const struct command_registration or1k_hw_ip_command_handlers[] = { - { - "tap_select", - .handler = or1k_tap_select_command_handler, - .mode = COMMAND_ANY, - .usage = "tap_select name", - .help = "Select the TAP core to use", - }, - { - "tap_list", - .handler = or1k_tap_list_command_handler, - .mode = COMMAND_ANY, - .usage = "tap_list", - .help = "Display available TAP core", - }, - { - "du_select", - .handler = or1k_du_select_command_handler, - .mode = COMMAND_ANY, - .usage = "du_select name", - .help = "Select the Debug Unit core to use", - }, - { - "du_list", - .handler = or1k_du_list_command_handler, - .mode = COMMAND_ANY, - .usage = "select_tap name", - .help = "Display available Debug Unit core", - }, - COMMAND_REGISTRATION_DONE -}; - -static const struct command_registration or1k_reg_command_handlers[] = { - { - "addreg", - .handler = or1k_addreg_command_handler, - .mode = COMMAND_ANY, - .usage = "addreg name addr feature group", - .help = "Add a register to the register list", - }, - COMMAND_REGISTRATION_DONE -}; - -static const struct command_registration or1k_command_handlers[] = { - { - .chain = or1k_reg_command_handlers, - }, - { - .chain = or1k_hw_ip_command_handlers, - }, - COMMAND_REGISTRATION_DONE -}; - - -struct target_type or1k_target = { - .name = "or1k", - - .poll = or1k_poll, - .arch_state = or1k_arch_state, - - .target_request_data = NULL, - - .halt = or1k_halt, - .resume = or1k_resume, - .step = or1k_step, - - .assert_reset = or1k_assert_reset, - .deassert_reset = or1k_deassert_reset, - .soft_reset_halt = or1k_soft_reset_halt, - - .get_gdb_reg_list = or1k_get_gdb_reg_list, - - .read_memory = or1k_read_memory, - .write_memory = or1k_write_memory, - .checksum_memory = or1k_checksum_memory, - - .commands = or1k_command_handlers, - .add_breakpoint = or1k_add_breakpoint, - .remove_breakpoint = or1k_remove_breakpoint, - .add_watchpoint = or1k_add_watchpoint, - .remove_watchpoint = or1k_remove_watchpoint, - - .target_create = or1k_target_create, - .init_target = or1k_init_target, - .examine = or1k_examine, - - .get_gdb_fileio_info = or1k_get_gdb_fileio_info, - - .profiling = or1k_profiling, -}; diff --git a/src/target/openrisc/or1k.h b/src/target/openrisc/or1k.h deleted file mode 100644 index c456ccbe2..000000000 --- a/src/target/openrisc/or1k.h +++ /dev/null @@ -1,158 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2011 by Julius Baxter * - * julius@opencores.org * - * * - * Copyright (C) 2013 by Marek Czerski * - * ma.czerski@gmail.com * - * * - * Copyright (C) 2013 by Franck Jullien * - * elec4fun@gmail.com * - * * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifndef OPENOCD_TARGET_OPENRISC_OR1K_H -#define OPENOCD_TARGET_OPENRISC_OR1K_H - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include - -/* SPR groups start address */ -#define GROUP0 (0 << 11) -#define GROUP1 (1 << 11) -#define GROUP2 (2 << 11) -#define GROUP3 (3 << 11) -#define GROUP4 (4 << 11) -#define GROUP5 (5 << 11) -#define GROUP6 (6 << 11) -#define GROUP7 (7 << 11) -#define GROUP8 (8 << 11) -#define GROUP9 (9 << 11) -#define GROUP10 (10 << 11) - -/* OR1K registers */ -enum or1k_reg_nums { - OR1K_REG_R0 = 0, - OR1K_REG_R1, - OR1K_REG_R2, - OR1K_REG_R3, - OR1K_REG_R4, - OR1K_REG_R5, - OR1K_REG_R6, - OR1K_REG_R7, - OR1K_REG_R8, - OR1K_REG_R9, - OR1K_REG_R10, - OR1K_REG_R11, - OR1K_REG_R12, - OR1K_REG_R13, - OR1K_REG_R14, - OR1K_REG_R15, - OR1K_REG_R16, - OR1K_REG_R17, - OR1K_REG_R18, - OR1K_REG_R19, - OR1K_REG_R20, - OR1K_REG_R21, - OR1K_REG_R22, - OR1K_REG_R23, - OR1K_REG_R24, - OR1K_REG_R25, - OR1K_REG_R26, - OR1K_REG_R27, - OR1K_REG_R28, - OR1K_REG_R29, - OR1K_REG_R30, - OR1K_REG_R31, - OR1K_REG_PPC, - OR1K_REG_NPC, - OR1K_REG_SR, - OR1KNUMCOREREGS -}; - -struct or1k_jtag { - struct jtag_tap *tap; - int or1k_jtag_inited; - int or1k_jtag_module_selected; - uint8_t *current_reg_idx; - struct or1k_tap_ip *tap_ip; - struct or1k_du *du_core; - struct target *target; -}; - -struct or1k_common { - struct or1k_jtag jtag; - struct reg_cache *core_cache; - uint32_t core_regs[OR1KNUMCOREREGS]; - int nb_regs; - struct or1k_core_reg *arch_info; -}; - -static inline struct or1k_common * -target_to_or1k(struct target *target) -{ - return (struct or1k_common *)target->arch_info; -} - -struct or1k_core_reg { - const char *name; - uint32_t list_num; /* Index in register cache */ - uint32_t spr_num; /* Number in architecture's SPR space */ - struct target *target; - struct or1k_common *or1k_common; - const char *feature; /* feature name in XML tdesc file */ - const char *group; /* register group in XML tdesc file */ -}; - -struct or1k_core_reg_init { - const char *name; - uint32_t spr_num; /* Number in architecture's SPR space */ - const char *feature; /* feature name in XML tdesc file */ - const char *group; /* register group in XML tdesc file */ -}; - -/* ORBIS32 Trap instruction */ -#define OR1K_TRAP_INSTR 0x21000001 - -enum or1k_debug_reg_nums { - OR1K_DEBUG_REG_DMR1 = 0, - OR1K_DEBUG_REG_DMR2, - OR1K_DEBUG_REG_DCWR0, - OR1K_DEBUG_REG_DCWR1, - OR1K_DEBUG_REG_DSR, - OR1K_DEBUG_REG_DRR, - OR1K_DEBUG_REG_NUM -}; - -#define NO_SINGLE_STEP 0 -#define SINGLE_STEP 1 - -/* OR1K Debug registers and bits needed for resuming */ -#define OR1K_DEBUG_REG_BASE GROUP6 /* Debug registers Base address */ -#define OR1K_DMR1_CPU_REG_ADD (OR1K_DEBUG_REG_BASE + 16) /* Debug Mode Register 1 0x3010 */ -#define OR1K_DMR1_ST 0x00400000 /* Single-step trace */ -#define OR1K_DMR1_BT 0x00800000 /* Branch trace */ -#define OR1K_DMR2_WGB 0x003ff000 /* Watchpoints generating breakpoint */ -#define OR1K_DSR_TE 0x00002000 /* Trap exception */ - -/* OR1K Instruction cache registers needed for invalidating instruction - * memory during adding and removing breakpoints. - */ -#define OR1K_ICBIR_CPU_REG_ADD ((4 << 11) + 2) /* IC Block Invalidate Register 0x2002 */ - -#endif /* OPENOCD_TARGET_OPENRISC_OR1K_H */ diff --git a/src/target/openrisc/or1k_du.h b/src/target/openrisc/or1k_du.h deleted file mode 100644 index 9828b0d22..000000000 --- a/src/target/openrisc/or1k_du.h +++ /dev/null @@ -1,78 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2013 Franck Jullien * - * elec4fun@gmail.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifndef OPENOCD_TARGET_OPENRISC_OR1K_DU_H -#define OPENOCD_TARGET_OPENRISC_OR1K_DU_H - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#define CPU_STALL 0 -#define CPU_UNSTALL 1 - -#define CPU_RESET 0 -#define CPU_NOT_RESET 1 - -int or1k_du_adv_register(void); - -/* Linear list over all available or1k debug unit */ -extern struct list_head du_list; - -struct or1k_du { - const char *name; - struct list_head list; - int options; - - int (*or1k_jtag_init)(struct or1k_jtag *jtag_info); - - int (*or1k_is_cpu_running)(struct or1k_jtag *jtag_info, int *running); - - int (*or1k_cpu_stall)(struct or1k_jtag *jtag_info, int action); - - int (*or1k_cpu_reset)(struct or1k_jtag *jtag_info, int action); - - int (*or1k_jtag_read_cpu)(struct or1k_jtag *jtag_info, - uint32_t addr, int count, uint32_t *value); - - int (*or1k_jtag_write_cpu)(struct or1k_jtag *jtag_info, - uint32_t addr, int count, const uint32_t *value); - - int (*or1k_jtag_read_memory)(struct or1k_jtag *jtag_info, uint32_t addr, uint32_t size, - int count, uint8_t *buffer); - - int (*or1k_jtag_write_memory)(struct or1k_jtag *jtag_info, uint32_t addr, uint32_t size, - int count, const uint8_t *buffer); -}; - -static inline struct or1k_du *or1k_jtag_to_du(struct or1k_jtag *jtag_info) -{ - return (struct or1k_du *)jtag_info->du_core; -} - -static inline struct or1k_du *or1k_to_du(struct or1k_common *or1k) -{ - struct or1k_jtag *jtag = &or1k->jtag; - return (struct or1k_du *)jtag->du_core; -} - -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 /* OPENOCD_TARGET_OPENRISC_OR1K_DU_H */ diff --git a/src/target/openrisc/or1k_du_adv.c b/src/target/openrisc/or1k_du_adv.c deleted file mode 100644 index bdd6fc8cb..000000000 --- a/src/target/openrisc/or1k_du_adv.c +++ /dev/null @@ -1,1098 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2013-2014 by Franck Jullien * - * elec4fun@gmail.com * - * * - * Inspired from adv_jtag_bridge which is: * - * Copyright (C) 2008-2010 Nathan Yawn * - * nyawn@opencores.net * - * * - * And the Mohor interface version of this file which is: * - * Copyright (C) 2011 by Julius Baxter * - * julius@opencores.org * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "or1k_tap.h" -#include "or1k.h" -#include "or1k_du.h" -#include "jsp_server.h" - -#include -#include - -#define JSP_BANNER "\n\r" \ - "******************************\n\r" \ - "** JTAG Serial Port **\n\r" \ - "******************************\n\r" \ - "\n\r" - -#define NO_OPTION 0 - -/* This an option to the adv debug unit. - * If this is defined, status bits will be skipped on burst - * reads and writes to improve download speeds. - * This option must match the RTL configured option. - */ -#define ADBG_USE_HISPEED 1 - -/* This an option to the adv debug unit. - * If this is defined, the JTAG Serial Port Server is started. - * This option must match the RTL configured option. - */ -#define ENABLE_JSP_SERVER 2 - -/* Define this if you intend to use the JSP in a system with multiple - * devices on the JTAG chain - */ -#define ENABLE_JSP_MULTI 4 - -/* Definitions for the top-level debug unit. This really just consists - * of a single register, used to select the active debug module ("chain"). - */ -#define DBG_MODULE_SELECT_REG_SIZE 2 -#define DBG_MAX_MODULES 4 - -#define DC_NONE -1 -#define DC_WISHBONE 0 -#define DC_CPU0 1 -#define DC_CPU1 2 -#define DC_JSP 3 - -/* CPU control register bits mask */ -#define DBG_CPU_CR_STALL 0x01 -#define DBG_CPU_CR_RESET 0x02 - -/* Polynomial for the CRC calculation - * Yes, it's backwards. Yes, this is on purpose. - * The hardware is designed this way to save on logic and routing, - * and it's really all the same to us here. - */ -#define ADBG_CRC_POLY 0xedb88320 - -/* These are for the internal registers in the Wishbone module - * The first is the length of the index register, - * the indexes of the various registers are defined after that. - */ -#define DBG_WB_REG_SEL_LEN 1 -#define DBG_WB_REG_ERROR 0 - -/* Opcode definitions for the Wishbone module. */ -#define DBG_WB_OPCODE_LEN 4 -#define DBG_WB_CMD_NOP 0x0 -#define DBG_WB_CMD_BWRITE8 0x1 -#define DBG_WB_CMD_BWRITE16 0x2 -#define DBG_WB_CMD_BWRITE32 0x3 -#define DBG_WB_CMD_BREAD8 0x5 -#define DBG_WB_CMD_BREAD16 0x6 -#define DBG_WB_CMD_BREAD32 0x7 -#define DBG_WB_CMD_IREG_WR 0x9 -#define DBG_WB_CMD_IREG_SEL 0xd - -/* Internal register definitions for the CPU0 module. */ -#define DBG_CPU0_REG_SEL_LEN 1 -#define DBG_CPU0_REG_STATUS 0 - -/* Opcode definitions for the first CPU module. */ -#define DBG_CPU0_OPCODE_LEN 4 -#define DBG_CPU0_CMD_NOP 0x0 -#define DBG_CPU0_CMD_BWRITE32 0x3 -#define DBG_CPU0_CMD_BREAD32 0x7 -#define DBG_CPU0_CMD_IREG_WR 0x9 -#define DBG_CPU0_CMD_IREG_SEL 0xd - -/* Internal register definitions for the CPU1 module. */ -#define DBG_CPU1_REG_SEL_LEN 1 -#define DBG_CPU1_REG_STATUS 0 - -/* Opcode definitions for the second CPU module. */ -#define DBG_CPU1_OPCODE_LEN 4 -#define DBG_CPU1_CMD_NOP 0x0 -#define DBG_CPU1_CMD_BWRITE32 0x3 -#define DBG_CPU1_CMD_BREAD32 0x7 -#define DBG_CPU1_CMD_IREG_WR 0x9 -#define DBG_CPU1_CMD_IREG_SEL 0xd - -#define MAX_READ_STATUS_WAIT 10 -#define MAX_READ_BUSY_RETRY 2 -#define MAX_READ_CRC_RETRY 2 -#define MAX_WRITE_CRC_RETRY 2 -#define BURST_READ_READY 1 -#define MAX_BUS_ERRORS 2 - -#define MAX_BURST_SIZE (4 * 1024) - -#define STATUS_BYTES 1 -#define CRC_LEN 4 - -static struct or1k_du or1k_du_adv; - -static const char * const chain_name[] = {"WISHBONE", "CPU0", "CPU1", "JSP"}; - -static uint32_t adbg_compute_crc(uint32_t crc, uint32_t data_in, - int length_bits) -{ - for (int i = 0; i < length_bits; i++) { - uint32_t d, c; - d = ((data_in >> i) & 0x1) ? 0xffffffff : 0; - c = (crc & 0x1) ? 0xffffffff : 0; - crc = crc >> 1; - crc = crc ^ ((d ^ c) & ADBG_CRC_POLY); - } - - return crc; -} - -static int find_status_bit(void *_buf, int len) -{ - int i = 0; - int count = 0; - int ret = -1; - uint8_t *buf = _buf; - - while (!(buf[i] & (1 << count++)) && (i < len)) { - if (count == 8) { - count = 0; - i++; - } - } - - if (i < len) - ret = (i * 8) + count; - - return ret; -} - -static int or1k_adv_jtag_init(struct or1k_jtag *jtag_info) -{ - struct or1k_tap_ip *tap_ip = jtag_info->tap_ip; - - int retval = tap_ip->init(jtag_info); - if (retval != ERROR_OK) { - LOG_ERROR("TAP initialization failed"); - return retval; - } - - /* TAP is now configured to communicate with debug interface */ - jtag_info->or1k_jtag_inited = 1; - - /* TAP reset - not sure what state debug module chain is in now */ - jtag_info->or1k_jtag_module_selected = DC_NONE; - - jtag_info->current_reg_idx = malloc(DBG_MAX_MODULES * sizeof(uint8_t)); - memset(jtag_info->current_reg_idx, 0, DBG_MAX_MODULES * sizeof(uint8_t)); - - if (or1k_du_adv.options & ADBG_USE_HISPEED) - LOG_INFO("adv debug unit is configured with option ADBG_USE_HISPEED"); - - if (or1k_du_adv.options & ENABLE_JSP_SERVER) { - if (or1k_du_adv.options & ENABLE_JSP_MULTI) - LOG_INFO("adv debug unit is configured with option ENABLE_JSP_MULTI"); - LOG_INFO("adv debug unit is configured with option ENABLE_JSP_SERVER"); - retval = jsp_init(jtag_info, JSP_BANNER); - if (retval != ERROR_OK) { - LOG_ERROR("Couldn't start the JSP server"); - return retval; - } - } - - LOG_DEBUG("Init done"); - - return ERROR_OK; - -} - -/* Selects one of the modules in the debug unit - * (e.g. wishbone unit, CPU0, etc.) - */ -static int adbg_select_module(struct or1k_jtag *jtag_info, int chain) -{ - if (jtag_info->or1k_jtag_module_selected == chain) - return ERROR_OK; - - /* MSB of the data out must be set to 1, indicating a module - * select command - */ - uint8_t data = chain | (1 << DBG_MODULE_SELECT_REG_SIZE); - - LOG_DEBUG("Select module: %s", chain_name[chain]); - - struct scan_field field; - - field.num_bits = (DBG_MODULE_SELECT_REG_SIZE + 1); - field.out_value = &data; - field.in_value = NULL; - jtag_add_dr_scan(jtag_info->tap, 1, &field, TAP_IDLE); - - int retval = jtag_execute_queue(); - if (retval != ERROR_OK) - return retval; - - jtag_info->or1k_jtag_module_selected = chain; - - return ERROR_OK; -} - -/* Set the index of the desired register in the currently selected module - * 1 bit module select command - * 4 bits opcode - * n bits index - */ -static int adbg_select_ctrl_reg(struct or1k_jtag *jtag_info, uint8_t regidx) -{ - int index_len; - uint32_t opcode; - uint32_t opcode_len; - - /* If this reg is already selected, don't do a JTAG transaction */ - if (jtag_info->current_reg_idx[jtag_info->or1k_jtag_module_selected] == regidx) - return ERROR_OK; - - switch (jtag_info->or1k_jtag_module_selected) { - case DC_WISHBONE: - index_len = DBG_WB_REG_SEL_LEN; - opcode = DBG_WB_CMD_IREG_SEL; - opcode_len = DBG_WB_OPCODE_LEN; - break; - case DC_CPU0: - index_len = DBG_CPU0_REG_SEL_LEN; - opcode = DBG_CPU0_CMD_IREG_SEL; - opcode_len = DBG_CPU0_OPCODE_LEN; - break; - case DC_CPU1: - index_len = DBG_CPU1_REG_SEL_LEN; - opcode = DBG_CPU1_CMD_IREG_SEL; - opcode_len = DBG_CPU1_OPCODE_LEN; - break; - default: - LOG_ERROR("Illegal debug chain selected (%i) while selecting control register", - jtag_info->or1k_jtag_module_selected); - return ERROR_FAIL; - } - - /* MSB must be 0 to access modules */ - uint32_t data = (opcode & ~(1 << opcode_len)) << index_len; - data |= regidx; - - struct scan_field field; - - field.num_bits = (opcode_len + 1) + index_len; - field.out_value = (uint8_t *)&data; - field.in_value = NULL; - jtag_add_dr_scan(jtag_info->tap, 1, &field, TAP_IDLE); - - int retval = jtag_execute_queue(); - if (retval != ERROR_OK) - return retval; - - jtag_info->current_reg_idx[jtag_info->or1k_jtag_module_selected] = regidx; - - return ERROR_OK; -} - -/* Write control register (internal to the debug unit) */ -static int adbg_ctrl_write(struct or1k_jtag *jtag_info, uint8_t regidx, - uint32_t *cmd_data, int length_bits) -{ - int index_len; - uint32_t opcode; - uint32_t opcode_len; - - LOG_DEBUG("Write control register %" PRId8 ": 0x%08" PRIx32, regidx, cmd_data[0]); - - int retval = adbg_select_ctrl_reg(jtag_info, regidx); - if (retval != ERROR_OK) { - LOG_ERROR("Error while calling adbg_select_ctrl_reg"); - return retval; - } - - switch (jtag_info->or1k_jtag_module_selected) { - case DC_WISHBONE: - index_len = DBG_WB_REG_SEL_LEN; - opcode = DBG_WB_CMD_IREG_WR; - opcode_len = DBG_WB_OPCODE_LEN; - break; - case DC_CPU0: - index_len = DBG_CPU0_REG_SEL_LEN; - opcode = DBG_CPU0_CMD_IREG_WR; - opcode_len = DBG_CPU0_OPCODE_LEN; - break; - case DC_CPU1: - index_len = DBG_CPU1_REG_SEL_LEN; - opcode = DBG_CPU1_CMD_IREG_WR; - opcode_len = DBG_CPU1_OPCODE_LEN; - break; - default: - LOG_ERROR("Illegal debug chain selected (%i) while doing control write", - jtag_info->or1k_jtag_module_selected); - return ERROR_FAIL; - } - - struct scan_field field[2]; - - /* MSB must be 0 to access modules */ - uint32_t data = (opcode & ~(1 << opcode_len)) << index_len; - data |= regidx; - - field[0].num_bits = length_bits; - field[0].out_value = (uint8_t *)cmd_data; - field[0].in_value = NULL; - - field[1].num_bits = (opcode_len + 1) + index_len; - field[1].out_value = (uint8_t *)&data; - field[1].in_value = NULL; - - jtag_add_dr_scan(jtag_info->tap, 2, field, TAP_IDLE); - - return jtag_execute_queue(); -} - -/* Reads control register (internal to the debug unit) */ -static int adbg_ctrl_read(struct or1k_jtag *jtag_info, uint32_t regidx, - uint32_t *data, int length_bits) -{ - - int retval = adbg_select_ctrl_reg(jtag_info, regidx); - if (retval != ERROR_OK) { - LOG_ERROR("Error while calling adbg_select_ctrl_reg"); - return retval; - } - - int opcode_len; - uint32_t opcode; - - /* There is no 'read' command, We write a NOP to read */ - switch (jtag_info->or1k_jtag_module_selected) { - case DC_WISHBONE: - opcode = DBG_WB_CMD_NOP; - opcode_len = DBG_WB_OPCODE_LEN; - break; - case DC_CPU0: - opcode = DBG_CPU0_CMD_NOP; - opcode_len = DBG_CPU0_OPCODE_LEN; - break; - case DC_CPU1: - opcode = DBG_CPU1_CMD_NOP; - opcode_len = DBG_CPU1_OPCODE_LEN; - break; - default: - LOG_ERROR("Illegal debug chain selected (%i) while doing control read", - jtag_info->or1k_jtag_module_selected); - return ERROR_FAIL; - } - - /* Zero MSB = op for module, not top-level debug unit */ - uint32_t outdata = opcode & ~(0x1 << opcode_len); - - struct scan_field field[2]; - - field[0].num_bits = length_bits; - field[0].out_value = NULL; - field[0].in_value = (uint8_t *)data; - - field[1].num_bits = opcode_len + 1; - field[1].out_value = (uint8_t *)&outdata; - field[1].in_value = NULL; - - jtag_add_dr_scan(jtag_info->tap, 2, field, TAP_IDLE); - - return jtag_execute_queue(); -} - -/* sends out a burst command to the selected module in the debug unit (MSB to LSB): - * 1-bit module command - * 4-bit opcode - * 32-bit address - * 16-bit length (of the burst, in words) - */ -static int adbg_burst_command(struct or1k_jtag *jtag_info, uint32_t opcode, - uint32_t address, uint16_t length_words) -{ - uint32_t data[2]; - - /* Set up the data */ - data[0] = length_words | (address << 16); - /* MSB must be 0 to access modules */ - data[1] = ((address >> 16) | ((opcode & 0xf) << 16)) & ~(0x1 << 20); - - struct scan_field field; - - field.num_bits = 53; - field.out_value = (uint8_t *)&data[0]; - field.in_value = NULL; - - jtag_add_dr_scan(jtag_info->tap, 1, &field, TAP_IDLE); - - return jtag_execute_queue(); -} - -static int adbg_wb_burst_read(struct or1k_jtag *jtag_info, int size, - int count, uint32_t start_address, uint8_t *data) -{ - int retry_full_crc = 0; - int retry_full_busy = 0; - int retval; - uint8_t opcode; - - LOG_DEBUG("Doing burst read, word size %d, word count %d, start address 0x%08" PRIx32, - size, count, start_address); - - /* Select the appropriate opcode */ - switch (jtag_info->or1k_jtag_module_selected) { - case DC_WISHBONE: - if (size == 1) - opcode = DBG_WB_CMD_BREAD8; - else if (size == 2) - opcode = DBG_WB_CMD_BREAD16; - else if (size == 4) - opcode = DBG_WB_CMD_BREAD32; - else { - LOG_WARNING("Tried burst read with invalid word size (%d)," - "defaulting to 4-byte words", size); - opcode = DBG_WB_CMD_BREAD32; - } - break; - case DC_CPU0: - if (size == 4) - opcode = DBG_CPU0_CMD_BREAD32; - else { - LOG_WARNING("Tried burst read with invalid word size (%d)," - "defaulting to 4-byte words", size); - opcode = DBG_CPU0_CMD_BREAD32; - } - break; - case DC_CPU1: - if (size == 4) - opcode = DBG_CPU1_CMD_BREAD32; - else { - LOG_WARNING("Tried burst read with invalid word size (%d)," - "defaulting to 4-byte words", size); - opcode = DBG_CPU0_CMD_BREAD32; - } - break; - default: - LOG_ERROR("Illegal debug chain selected (%i) while doing burst read", - jtag_info->or1k_jtag_module_selected); - return ERROR_FAIL; - } - - int total_size_bytes = count * size; - struct scan_field field; - uint8_t *in_buffer = malloc(total_size_bytes + CRC_LEN + STATUS_BYTES); - -retry_read_full: - - /* Send the BURST READ command, returns TAP to idle state */ - retval = adbg_burst_command(jtag_info, opcode, start_address, count); - if (retval != ERROR_OK) - goto out; - - field.num_bits = (total_size_bytes + CRC_LEN + STATUS_BYTES) * 8; - field.out_value = NULL; - field.in_value = in_buffer; - - jtag_add_dr_scan(jtag_info->tap, 1, &field, TAP_IDLE); - - retval = jtag_execute_queue(); - if (retval != ERROR_OK) - goto out; - - /* Look for the start bit in the first (STATUS_BYTES * 8) bits */ - int shift = find_status_bit(in_buffer, STATUS_BYTES); - - /* We expect the status bit to be in the first byte */ - if (shift < 0) { - if (retry_full_busy++ < MAX_READ_BUSY_RETRY) { - LOG_WARNING("Burst read timed out"); - goto retry_read_full; - } else { - LOG_ERROR("Burst read failed"); - retval = ERROR_FAIL; - goto out; - } - } - - buffer_shr(in_buffer, total_size_bytes + CRC_LEN + STATUS_BYTES, shift); - - uint32_t crc_read; - memcpy(data, in_buffer, total_size_bytes); - memcpy(&crc_read, &in_buffer[total_size_bytes], 4); - - uint32_t crc_calc = 0xffffffff; - for (int i = 0; i < total_size_bytes; i++) - crc_calc = adbg_compute_crc(crc_calc, data[i], 8); - - if (crc_calc != crc_read) { - LOG_WARNING("CRC ERROR! Computed 0x%08" PRIx32 ", read CRC 0x%08" PRIx32, crc_calc, crc_read); - if (retry_full_crc++ < MAX_READ_CRC_RETRY) - goto retry_read_full; - else { - LOG_ERROR("Burst read failed"); - retval = ERROR_FAIL; - goto out; - } - } else - LOG_DEBUG("CRC OK!"); - - /* Now, read the error register, and retry/recompute as necessary */ - if (jtag_info->or1k_jtag_module_selected == DC_WISHBONE && - !(or1k_du_adv.options & ADBG_USE_HISPEED)) { - - uint32_t err_data[2] = {0, 0}; - uint32_t addr; - int bus_error_retries = 0; - - /* First, just get 1 bit...read address only if necessary */ - retval = adbg_ctrl_read(jtag_info, DBG_WB_REG_ERROR, err_data, 1); - if (retval != ERROR_OK) - goto out; - - /* Then we have a problem */ - if (err_data[0] & 0x1) { - - retval = adbg_ctrl_read(jtag_info, DBG_WB_REG_ERROR, err_data, 33); - if (retval != ERROR_OK) - goto out; - - addr = (err_data[0] >> 1) | (err_data[1] << 31); - LOG_WARNING("WB bus error during burst read, address 0x%08" PRIx32 ", retrying!", addr); - - bus_error_retries++; - if (bus_error_retries > MAX_BUS_ERRORS) { - LOG_ERROR("Max WB bus errors reached during burst read"); - retval = ERROR_FAIL; - goto out; - } - - /* Don't call retry_do(), a JTAG reset won't help a WB bus error */ - /* Write 1 bit, to reset the error register */ - err_data[0] = 1; - retval = adbg_ctrl_write(jtag_info, DBG_WB_REG_ERROR, err_data, 1); - if (retval != ERROR_OK) - goto out; - - goto retry_read_full; - } - } - -out: - free(in_buffer); - - return retval; -} - -/* Set up and execute a burst write to a contiguous set of addresses */ -static int adbg_wb_burst_write(struct or1k_jtag *jtag_info, const uint8_t *data, int size, - int count, unsigned long start_address) -{ - int retry_full_crc = 0; - int retval; - uint8_t opcode; - - LOG_DEBUG("Doing burst write, word size %d, word count %d," - "start address 0x%08lx", size, count, start_address); - - /* Select the appropriate opcode */ - switch (jtag_info->or1k_jtag_module_selected) { - case DC_WISHBONE: - if (size == 1) - opcode = DBG_WB_CMD_BWRITE8; - else if (size == 2) - opcode = DBG_WB_CMD_BWRITE16; - else if (size == 4) - opcode = DBG_WB_CMD_BWRITE32; - else { - LOG_DEBUG("Tried WB burst write with invalid word size (%d)," - "defaulting to 4-byte words", size); - opcode = DBG_WB_CMD_BWRITE32; - } - break; - case DC_CPU0: - if (size == 4) - opcode = DBG_CPU0_CMD_BWRITE32; - else { - LOG_DEBUG("Tried CPU0 burst write with invalid word size (%d)," - "defaulting to 4-byte words", size); - opcode = DBG_CPU0_CMD_BWRITE32; - } - break; - case DC_CPU1: - if (size == 4) - opcode = DBG_CPU1_CMD_BWRITE32; - else { - LOG_DEBUG("Tried CPU1 burst write with invalid word size (%d)," - "defaulting to 4-byte words", size); - opcode = DBG_CPU0_CMD_BWRITE32; - } - break; - default: - LOG_ERROR("Illegal debug chain selected (%i) while doing burst write", - jtag_info->or1k_jtag_module_selected); - return ERROR_FAIL; - } - -retry_full_write: - - /* Send the BURST WRITE command, returns TAP to idle state */ - retval = adbg_burst_command(jtag_info, opcode, start_address, count); - if (retval != ERROR_OK) - return retval; - - struct scan_field field[3]; - - /* Write a start bit so it knows when to start counting */ - uint8_t value = 1; - field[0].num_bits = 1; - field[0].out_value = &value; - field[0].in_value = NULL; - - uint32_t crc_calc = 0xffffffff; - for (int i = 0; i < (count * size); i++) - crc_calc = adbg_compute_crc(crc_calc, data[i], 8); - - field[1].num_bits = count * size * 8; - field[1].out_value = data; - field[1].in_value = NULL; - - field[2].num_bits = 32; - field[2].out_value = (uint8_t *)&crc_calc; - field[2].in_value = NULL; - - jtag_add_dr_scan(jtag_info->tap, 3, field, TAP_DRSHIFT); - - /* Read the 'CRC match' bit, and go to idle */ - field[0].num_bits = 1; - field[0].out_value = NULL; - field[0].in_value = &value; - jtag_add_dr_scan(jtag_info->tap, 1, field, TAP_IDLE); - - retval = jtag_execute_queue(); - if (retval != ERROR_OK) - return retval; - - if (!value) { - LOG_WARNING("CRC ERROR! match bit after write is %" PRIi8 " (computed CRC 0x%08" PRIx32 ")", value, crc_calc); - if (retry_full_crc++ < MAX_WRITE_CRC_RETRY) - goto retry_full_write; - else - return ERROR_FAIL; - } else - LOG_DEBUG("CRC OK!\n"); - - /* Now, read the error register, and retry/recompute as necessary */ - if (jtag_info->or1k_jtag_module_selected == DC_WISHBONE && - !(or1k_du_adv.options & ADBG_USE_HISPEED)) { - uint32_t addr; - int bus_error_retries = 0; - uint32_t err_data[2] = {0, 0}; - - /* First, just get 1 bit...read address only if necessary */ - retval = adbg_ctrl_read(jtag_info, DBG_WB_REG_ERROR, err_data, 1); - if (retval != ERROR_OK) - return retval; - - /* Then we have a problem */ - if (err_data[0] & 0x1) { - - retval = adbg_ctrl_read(jtag_info, DBG_WB_REG_ERROR, err_data, 33); - if (retval != ERROR_OK) - return retval; - - addr = (err_data[0] >> 1) | (err_data[1] << 31); - LOG_WARNING("WB bus error during burst write, address 0x%08" PRIx32 ", retrying!", addr); - - bus_error_retries++; - if (bus_error_retries > MAX_BUS_ERRORS) { - LOG_ERROR("Max WB bus errors reached during burst read"); - retval = ERROR_FAIL; - return retval; - } - - /* Don't call retry_do(), a JTAG reset won't help a WB bus error */ - /* Write 1 bit, to reset the error register */ - err_data[0] = 1; - retval = adbg_ctrl_write(jtag_info, DBG_WB_REG_ERROR, err_data, 1); - if (retval != ERROR_OK) - return retval; - - goto retry_full_write; - } - } - - return ERROR_OK; -} - -/* Currently hard set in functions to 32-bits */ -static int or1k_adv_jtag_read_cpu(struct or1k_jtag *jtag_info, - uint32_t addr, int count, uint32_t *value) -{ - int retval; - if (!jtag_info->or1k_jtag_inited) { - retval = or1k_adv_jtag_init(jtag_info); - if (retval != ERROR_OK) - return retval; - } - - retval = adbg_select_module(jtag_info, DC_CPU0); - if (retval != ERROR_OK) - return retval; - - return adbg_wb_burst_read(jtag_info, 4, count, addr, (uint8_t *)value); -} - -static int or1k_adv_jtag_write_cpu(struct or1k_jtag *jtag_info, - uint32_t addr, int count, const uint32_t *value) -{ - int retval; - if (!jtag_info->or1k_jtag_inited) { - retval = or1k_adv_jtag_init(jtag_info); - if (retval != ERROR_OK) - return retval; - } - - retval = adbg_select_module(jtag_info, DC_CPU0); - if (retval != ERROR_OK) - return retval; - - return adbg_wb_burst_write(jtag_info, (uint8_t *)value, 4, count, addr); -} - -static int or1k_adv_cpu_stall(struct or1k_jtag *jtag_info, int action) -{ - int retval; - if (!jtag_info->or1k_jtag_inited) { - retval = or1k_adv_jtag_init(jtag_info); - if (retval != ERROR_OK) - return retval; - } - - retval = adbg_select_module(jtag_info, DC_CPU0); - if (retval != ERROR_OK) - return retval; - - uint32_t cpu_cr; - retval = adbg_ctrl_read(jtag_info, DBG_CPU0_REG_STATUS, &cpu_cr, 2); - if (retval != ERROR_OK) - return retval; - - if (action == CPU_STALL) - cpu_cr |= DBG_CPU_CR_STALL; - else - cpu_cr &= ~DBG_CPU_CR_STALL; - - retval = adbg_select_module(jtag_info, DC_CPU0); - if (retval != ERROR_OK) - return retval; - - return adbg_ctrl_write(jtag_info, DBG_CPU0_REG_STATUS, &cpu_cr, 2); -} - -static int or1k_adv_is_cpu_running(struct or1k_jtag *jtag_info, int *running) -{ - int retval; - if (!jtag_info->or1k_jtag_inited) { - retval = or1k_adv_jtag_init(jtag_info); - if (retval != ERROR_OK) - return retval; - } - - int current = jtag_info->or1k_jtag_module_selected; - - retval = adbg_select_module(jtag_info, DC_CPU0); - if (retval != ERROR_OK) - return retval; - - uint32_t cpu_cr = 0; - retval = adbg_ctrl_read(jtag_info, DBG_CPU0_REG_STATUS, &cpu_cr, 2); - if (retval != ERROR_OK) - return retval; - - if (cpu_cr & DBG_CPU_CR_STALL) - *running = 0; - else - *running = 1; - - if (current != DC_NONE) { - retval = adbg_select_module(jtag_info, current); - if (retval != ERROR_OK) - return retval; - } - - return ERROR_OK; -} - -static int or1k_adv_cpu_reset(struct or1k_jtag *jtag_info, int action) -{ - int retval; - if (!jtag_info->or1k_jtag_inited) { - retval = or1k_adv_jtag_init(jtag_info); - if (retval != ERROR_OK) - return retval; - } - - retval = adbg_select_module(jtag_info, DC_CPU0); - if (retval != ERROR_OK) - return retval; - - uint32_t cpu_cr; - retval = adbg_ctrl_read(jtag_info, DBG_CPU0_REG_STATUS, &cpu_cr, 2); - if (retval != ERROR_OK) - return retval; - - if (action == CPU_RESET) - cpu_cr |= DBG_CPU_CR_RESET; - else - cpu_cr &= ~DBG_CPU_CR_RESET; - - retval = adbg_select_module(jtag_info, DC_CPU0); - if (retval != ERROR_OK) - return retval; - - return adbg_ctrl_write(jtag_info, DBG_CPU0_REG_STATUS, &cpu_cr, 2); -} - -static int or1k_adv_jtag_read_memory(struct or1k_jtag *jtag_info, - uint32_t addr, uint32_t size, int count, uint8_t *buffer) -{ - LOG_DEBUG("Reading WB%" PRId32 " at 0x%08" PRIx32, size * 8, addr); - - int retval; - if (!jtag_info->or1k_jtag_inited) { - retval = or1k_adv_jtag_init(jtag_info); - if (retval != ERROR_OK) - return retval; - } - - retval = adbg_select_module(jtag_info, DC_WISHBONE); - if (retval != ERROR_OK) - return retval; - - int block_count_left = count; - uint32_t block_count_address = addr; - uint8_t *block_count_buffer = buffer; - - while (block_count_left) { - - int blocks_this_round = (block_count_left > MAX_BURST_SIZE) ? - MAX_BURST_SIZE : block_count_left; - - retval = adbg_wb_burst_read(jtag_info, size, blocks_this_round, - block_count_address, block_count_buffer); - if (retval != ERROR_OK) - return retval; - - block_count_left -= blocks_this_round; - block_count_address += size * MAX_BURST_SIZE; - block_count_buffer += size * MAX_BURST_SIZE; - } - - /* The adv_debug_if always return words and half words in - * little-endian order no matter what the target endian is. - * So if the target endian is big, change the order. - */ - - struct target *target = jtag_info->target; - if ((target->endianness == TARGET_BIG_ENDIAN) && (size != 1)) { - switch (size) { - case 4: - buf_bswap32(buffer, buffer, size * count); - break; - case 2: - buf_bswap16(buffer, buffer, size * count); - break; - } - } - - return ERROR_OK; -} - -static int or1k_adv_jtag_write_memory(struct or1k_jtag *jtag_info, - uint32_t addr, uint32_t size, int count, const uint8_t *buffer) -{ - LOG_DEBUG("Writing WB%" PRId32 " at 0x%08" PRIx32, size * 8, addr); - - int retval; - if (!jtag_info->or1k_jtag_inited) { - retval = or1k_adv_jtag_init(jtag_info); - if (retval != ERROR_OK) - return retval; - } - - retval = adbg_select_module(jtag_info, DC_WISHBONE); - if (retval != ERROR_OK) - return retval; - - /* The adv_debug_if wants words and half words in little-endian - * order no matter what the target endian is. So if the target - * endian is big, change the order. - */ - - void *t = NULL; - struct target *target = jtag_info->target; - if ((target->endianness == TARGET_BIG_ENDIAN) && (size != 1)) { - t = malloc(count * size * sizeof(uint8_t)); - if (t == NULL) { - LOG_ERROR("Out of memory"); - return ERROR_FAIL; - } - - switch (size) { - case 4: - buf_bswap32(t, buffer, size * count); - break; - case 2: - buf_bswap16(t, buffer, size * count); - break; - } - buffer = t; - } - - int block_count_left = count; - uint32_t block_count_address = addr; - uint8_t *block_count_buffer = (uint8_t *)buffer; - - while (block_count_left) { - - int blocks_this_round = (block_count_left > MAX_BURST_SIZE) ? - MAX_BURST_SIZE : block_count_left; - - retval = adbg_wb_burst_write(jtag_info, block_count_buffer, - size, blocks_this_round, - block_count_address); - if (retval != ERROR_OK) { - if (t != NULL) - free(t); - return retval; - } - - block_count_left -= blocks_this_round; - block_count_address += size * MAX_BURST_SIZE; - block_count_buffer += size * MAX_BURST_SIZE; - } - - if (t != NULL) - free(t); - - return ERROR_OK; -} - -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) -{ - LOG_DEBUG("JSP transfert"); - - int retval; - if (!jtag_info->or1k_jtag_inited) - return ERROR_OK; - - retval = adbg_select_module(jtag_info, DC_JSP); - if (retval != ERROR_OK) - return retval; - - /* return nb char xmit */ - int xmitsize; - if (*out_len > 8) - xmitsize = 8; - else - xmitsize = *out_len; - - uint8_t out_data[10]; - uint8_t in_data[10]; - struct scan_field field; - int startbit, stopbit, wrapbit; - - memset(out_data, 0, 10); - - if (or1k_du_adv.options & ENABLE_JSP_MULTI) { - - startbit = 1; - wrapbit = (xmitsize >> 3) & 0x1; - out_data[0] = (xmitsize << 5) | 0x1; /* set the start bit */ - - int i; - /* don't copy off the end of the input array */ - for (i = 0; i < xmitsize; i++) { - out_data[i + 1] = (out_buffer[i] << 1) | wrapbit; - wrapbit = (out_buffer[i] >> 7) & 0x1; - } - - if (i < 8) - out_data[i + 1] = wrapbit; - else - out_data[9] = wrapbit; - - /* If the last data bit is a '1', then we need to append a '0' so the top-level module - * won't treat the burst as a 'module select' command. - */ - stopbit = !!(out_data[9] & 0x01); - - } else { - startbit = 0; - /* First byte out has write count in upper nibble */ - out_data[0] = 0x0 | (xmitsize << 4); - if (xmitsize > 0) - memcpy(&out_data[1], out_buffer, xmitsize); - - /* If the last data bit is a '1', then we need to append a '0' so the top-level module - * won't treat the burst as a 'module select' command. - */ - stopbit = !!(out_data[8] & 0x80); - } - - field.num_bits = 72 + startbit + stopbit; - field.out_value = out_data; - field.in_value = in_data; - - jtag_add_dr_scan(jtag_info->tap, 1, &field, TAP_IDLE); - - retval = jtag_execute_queue(); - if (retval != ERROR_OK) - return retval; - - /* bytes available is in the upper nibble */ - *in_len = (in_data[0] >> 4) & 0xF; - memcpy(in_buffer, &in_data[1], *in_len); - - int bytes_free = in_data[0] & 0x0F; - *out_len = (bytes_free < xmitsize) ? bytes_free : xmitsize; - - return ERROR_OK; -} - -static struct or1k_du or1k_du_adv = { - .name = "adv", - .options = NO_OPTION, - .or1k_jtag_init = or1k_adv_jtag_init, - - .or1k_is_cpu_running = or1k_adv_is_cpu_running, - .or1k_cpu_stall = or1k_adv_cpu_stall, - .or1k_cpu_reset = or1k_adv_cpu_reset, - - .or1k_jtag_read_cpu = or1k_adv_jtag_read_cpu, - .or1k_jtag_write_cpu = or1k_adv_jtag_write_cpu, - - .or1k_jtag_read_memory = or1k_adv_jtag_read_memory, - .or1k_jtag_write_memory = or1k_adv_jtag_write_memory -}; - -int or1k_du_adv_register(void) -{ - list_add_tail(&or1k_du_adv.list, &du_list); - return 0; -} diff --git a/src/target/openrisc/or1k_tap.h b/src/target/openrisc/or1k_tap.h deleted file mode 100644 index 2cf7da804..000000000 --- a/src/target/openrisc/or1k_tap.h +++ /dev/null @@ -1,42 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2012 by Franck Jullien * - * elec4fun@gmail.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifndef OPENOCD_TARGET_OPENRISC_OR1K_TAP_H -#define OPENOCD_TARGET_OPENRISC_OR1K_TAP_H - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include "or1k.h" - -int or1k_tap_vjtag_register(void); -int or1k_tap_xilinx_bscan_register(void); -int or1k_tap_mohor_register(void); - -/* Linear list over all available or1k taps */ -extern struct list_head tap_list; - -struct or1k_tap_ip { - struct list_head list; - int (*init)(struct or1k_jtag *jtag_info); - const char *name; -}; - -#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 deleted file mode 100644 index 1415e321c..000000000 --- a/src/target/openrisc/or1k_tap_mohor.c +++ /dev/null @@ -1,63 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2013 by Franck Jullien * - * elec4fun@gmail.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "or1k_tap.h" -#include "or1k.h" - -#include - -#define OR1K_TAP_INST_DEBUG 0x8 - -static int or1k_tap_mohor_init(struct or1k_jtag *jtag_info) -{ - LOG_DEBUG("Initialising OpenCores JTAG TAP"); - - /* Put TAP into state where it can talk to the debug interface - * by shifting in correct value to IR. - */ - - /* Ensure TAP is reset - maybe not necessary*/ - jtag_add_tlr(); - - struct jtag_tap *tap = jtag_info->tap; - struct scan_field field; - uint8_t ir_value = OR1K_TAP_INST_DEBUG; - - field.num_bits = tap->ir_length; - field.out_value = &ir_value; - field.in_value = NULL; - - jtag_add_ir_scan(tap, &field, TAP_IDLE); - - return jtag_execute_queue(); -} - -static struct or1k_tap_ip mohor_tap = { - .name = "mohor", - .init = or1k_tap_mohor_init, -}; - -int or1k_tap_mohor_register(void) -{ - list_add_tail(&mohor_tap.list, &tap_list); - return 0; -} diff --git a/src/target/openrisc/or1k_tap_vjtag.c b/src/target/openrisc/or1k_tap_vjtag.c deleted file mode 100644 index 607451a7c..000000000 --- a/src/target/openrisc/or1k_tap_vjtag.c +++ /dev/null @@ -1,309 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2013 by Franck Jullien * - * elec4fun@gmail.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "or1k_tap.h" -#include "or1k.h" - -#include - -/* Contains constants relevant to the Altera Virtual JTAG - * device, which are not included in the BSDL. - * As of this writing, these are constant across every - * device which supports virtual JTAG. - */ - -/* These are commands for the FPGA's IR. */ -#define ALTERA_CYCLONE_CMD_USER1 0x0E -#define ALTERA_CYCLONE_CMD_USER0 0x0C - -/* These defines are for the virtual IR (not the FPGA's) - * The virtual TAP was defined in hardware to match the OpenCores native - * TAP in both IR size and DEBUG command. - */ -#define ALT_VJTAG_IR_SIZE 4 -#define ALT_VJTAG_CMD_DEBUG 0x8 - -/* SLD node ID. */ -#define JTAG_TO_AVALON_NODE_ID 0x84 -#define VJTAG_NODE_ID 0x08 -#define SIGNAL_TAP_NODE_ID 0x00 -#define SERIAL_FLASH_LOADER_NODE_ID 0x04 - -#define VER(x) ((x >> 27) & 0x1f) -#define NB_NODES(x) ((x >> 19) & 0xff) -#define ID(x) ((x >> 19) & 0xff) -#define MANUF(x) ((x >> 8) & 0x7ff) -#define M_WIDTH(x) ((x >> 0) & 0xff) -#define INST_ID(x) ((x >> 0) & 0xff) - -/* tap instructions - Mohor JTAG TAP */ -#define OR1K_TAP_INST_IDCODE 0x2 -#define OR1K_TAP_INST_DEBUG 0x8 - -static const char *id_to_string(unsigned char id) -{ - switch (id) { - case VJTAG_NODE_ID: - return "Virtual JTAG"; - case JTAG_TO_AVALON_NODE_ID: - return "JTAG to avalon bridge"; - case SIGNAL_TAP_NODE_ID: - return "Signal TAP"; - case SERIAL_FLASH_LOADER_NODE_ID: - return "Serial Flash Loader"; - } - return "unknown"; -} - -static unsigned char guess_addr_width(unsigned char number_of_nodes) -{ - unsigned char width = 0; - - while (number_of_nodes) { - number_of_nodes >>= 1; - width++; - } - - return width; -} - -static int or1k_tap_vjtag_init(struct or1k_jtag *jtag_info) -{ - LOG_DEBUG("Initialising Altera Virtual JTAG TAP"); - - /* Put TAP into state where it can talk to the debug interface - * by shifting in correct value to IR. - */ - - /* Ensure TAP is reset - maybe not necessary*/ - jtag_add_tlr(); - - /* You can use a custom JTAG controller to discover transactions - * necessary to enumerate all Virtual JTAG megafunction instances - * from your design atruntime. All SLD nodes and the virtual JTAG - * registers that they contain are targeted by two Instruction Register - * values, USER0 and USER1. - * - * The USER1 instruction targets the virtual IR of either the sld_hub - * or a SLD node. That is,when the USER1 instruction is issued to - * the device, the subsequent DR scans target a specific virtual - * IR chain based on an address field contained within the DR scan. - * The table below shows how the virtual IR, the DR target of the - * USER1 instruction is interpreted. - * - * The VIR_VALUE in the table below is the virtual IR value for the - * target SLD node. The width of this field is m bits in length, - * where m is the length of the largest VIR for all of the SLD nodes - * in the design. All SLD nodes with VIR lengths of fewer than m - * bits must pad VIR_VALUE with zeros up to a length of m. - * - * -------------------------------+------------------------------- - * m + n - 1 m | m -1 0 - * -------------------------------+------------------------------- - * ADDR [(n – 1)..0] | VIR_VALUE [(m – 1)..0] - * -------------------------------+------------------------------- - * - * The ADDR bits act as address values to signal the active SLD node - * that the virtual IR shift targets. ADDR is n bits in length, where - * n bits must be long enough to encode all SLD nodes within the design, - * as shown below. - * - * n = CEIL(log2(Number of SLD_nodes +1)) - * - * The SLD hub is always 0 in the address map. - * - * Discovery and enumeration of the SLD instances within a design - * requires interrogation of the sld_hub to determine the dimensions - * of the USER1 DR (m and n) and associating each SLD instance, specifically - * the Virtual JTAG megafunction instances, with an address value - * contained within the ADDR bits of the USER1 DR. - * - * The SLD hub contains the HUB IP Configuration Register and SLD_NODE_INFO - * register for each SLD node in the design. The HUB IP configuration register provides - * information needed to determine the dimensions of the USER1 DR chain. The - * SLD_NODE_INFO register is used to determine the address mapping for Virtual - * JTAG instance in your design. This register set is shifted out by issuing the - * HUB_INFO instruction. Both the ADDR bits for the SLD hub and the HUB_INFO - * instruction is 0 × 0. - * Because m and n are unknown at this point, the DR register - * (ADDR bits + VIR_VALUE) must be filled with zeros. Shifting a sequence of 64 zeroes - * into the USER1 DR is sufficient to cover the most conservative case for m and n. - */ - - uint8_t t[4]; - struct scan_field field; - struct jtag_tap *tap = jtag_info->tap; - - /* Select VIR */ - buf_set_u32(t, 0, tap->ir_length, ALTERA_CYCLONE_CMD_USER1); - field.num_bits = tap->ir_length; - field.out_value = t; - field.in_value = NULL; - jtag_add_ir_scan(tap, &field, TAP_IDLE); - - /* Select the SLD Hub */ - field.num_bits = 64; - field.out_value = NULL; - field.in_value = NULL; - jtag_add_dr_scan(tap, 1, &field, TAP_IDLE); - - /* HUB IP Configuration Register - * - * When the USER1 and HUB_INFO instruction sequence is issued, the - * USER0 instruction must be applied to enable the target register - * of the HUB_INFO instruction. The HUB IP configuration register - * is shifted out using eight four-bit nibble scans of the DR register. - * Each four-bit scan must pass through the UPDATE_DR state before - * the next four-bit scan. The 8 scans are assembled into a 32-bit - * value with the definitions shown in the table below. - * - * -------------------------------------------------------------------------------- - * NIBBLE7 | NIBBLE6 | NIBBLE5 | NIBBLE4 | NIBBLE3 | NIBBLE2 | NIBBLE1 | NIBBLE0 - * ----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----- - * | | | | | | | | | | | | | | | - * ----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----- - * HUB IP version| N | ALTERA_MFG_ID (0x06E) | SUM (m, n) - * --------------+-------------------+------------------------+-------------------- - */ - - /* Select VDR */ - buf_set_u32(t, 0, tap->ir_length, ALTERA_CYCLONE_CMD_USER0); - field.num_bits = tap->ir_length; - field.out_value = t; - field.in_value = NULL; - jtag_add_ir_scan(tap, &field, TAP_IDLE); - - int retval = jtag_execute_queue(); - if (retval != ERROR_OK) - return retval; - - uint8_t nibble; - uint32_t hub_info = 0; - - for (int i = 0; i < 8; i++) { - field.num_bits = 4; - field.out_value = NULL; - field.in_value = &nibble; - jtag_add_dr_scan(tap, 1, &field, TAP_IDLE); - retval = jtag_execute_queue(); - if (retval != ERROR_OK) - return retval; - hub_info = ((hub_info >> 4) | ((nibble & 0xf) << 28)); - } - - int nb_nodes = NB_NODES(hub_info); - int m_width = M_WIDTH(hub_info); - - LOG_DEBUG("SLD HUB Configuration register"); - LOG_DEBUG("------------------------------"); - LOG_DEBUG("m_width = %d", m_width); - LOG_DEBUG("manufacturer_id = 0x%02" PRIx32, MANUF(hub_info)); - LOG_DEBUG("nb_of_node = %d", nb_nodes); - LOG_DEBUG("version = %" PRId32, VER(hub_info)); - LOG_DEBUG("VIR length = %d", guess_addr_width(nb_nodes) + m_width); - - /* Because the number of SLD nodes is now known, the Nodes on the hub can be - * enumerated by repeating the 8 four-bit nibble scans, once for each Node, - * to yield the SLD_NODE_INFO register of each Node. The DR nibble shifts - * are a continuation of the HUB_INFO DR shift used to shift out the Hub IP - * Configuration register. - * - * The order of the Nodes as they are shifted out determines the ADDR - * values for the Nodes, beginning with, for the first Node SLD_NODE_INFO - * shifted out, up to and including, for the last node on the hub. The - * tables below show the SLD_NODE_INFO register and a their functional descriptions. - * - * --------------+-----------+---------------+---------------- - * 31 27 | 26 19 | 18 8 | 7 0 - * --------------+-----------+---------------+---------------- - * Node Version | NODE ID | NODE MFG_ID | NODE INST ID - * - */ - - int vjtag_node_address = -1; - int node_index; - uint32_t node_info = 0; - for (node_index = 0; node_index < nb_nodes; node_index++) { - - for (int i = 0; i < 8; i++) { - field.num_bits = 4; - field.out_value = NULL; - field.in_value = &nibble; - jtag_add_dr_scan(tap, 1, &field, TAP_IDLE); - retval = jtag_execute_queue(); - if (retval != ERROR_OK) - return retval; - node_info = ((node_info >> 4) | ((nibble & 0xf) << 28)); - } - - LOG_DEBUG("Node info register"); - LOG_DEBUG("--------------------"); - LOG_DEBUG("instance_id = %" PRId32, ID(node_info)); - LOG_DEBUG("manufacturer_id = 0x%02" PRIx32, MANUF(node_info)); - LOG_DEBUG("node_id = %" PRId32 " (%s)", ID(node_info), - id_to_string(ID(node_info))); - LOG_DEBUG("version = %" PRId32, VER(node_info)); - - if (ID(node_info) == VJTAG_NODE_ID) - vjtag_node_address = node_index + 1; - } - - if (vjtag_node_address < 0) { - LOG_ERROR("No VJTAG TAP instance found !"); - return ERROR_FAIL; - } - - /* Select VIR */ - buf_set_u32(t, 0, tap->ir_length, ALTERA_CYCLONE_CMD_USER1); - field.num_bits = tap->ir_length; - field.out_value = t; - field.in_value = NULL; - jtag_add_ir_scan(tap, &field, TAP_IDLE); - - /* Send the DEBUG command to the VJTAG IR */ - int dr_length = guess_addr_width(nb_nodes) + m_width; - buf_set_u32(t, 0, dr_length, (vjtag_node_address << m_width) | ALT_VJTAG_CMD_DEBUG); - field.num_bits = dr_length; - field.out_value = t; - field.in_value = NULL; - jtag_add_dr_scan(tap, 1, &field, TAP_IDLE); - - /* Select the VJTAG DR */ - buf_set_u32(t, 0, tap->ir_length, ALTERA_CYCLONE_CMD_USER0); - field.num_bits = tap->ir_length; - field.out_value = t; - field.in_value = NULL; - jtag_add_ir_scan(tap, &field, TAP_IDLE); - - return jtag_execute_queue(); -} - -static struct or1k_tap_ip vjtag_tap = { - .name = "vjtag", - .init = or1k_tap_vjtag_init, -}; - -int or1k_tap_vjtag_register(void) -{ - list_add_tail(&vjtag_tap.list, &tap_list); - return 0; -} diff --git a/src/target/openrisc/or1k_tap_xilinx_bscan.c b/src/target/openrisc/or1k_tap_xilinx_bscan.c deleted file mode 100644 index a77c65ef8..000000000 --- a/src/target/openrisc/or1k_tap_xilinx_bscan.c +++ /dev/null @@ -1,63 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2013 by Sergio Chico * - * sergio.chico@gmail.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "or1k_tap.h" -#include "or1k.h" - -#include - -#define OR1K_XILINX_TAP_INST_USER1 0x02 - -static int or1k_tap_xilinx_bscan_init(struct or1k_jtag *jtag_info) -{ - LOG_DEBUG("Initialising Xilinx Internal JTAG TAP"); - - /* Put TAP into state where it can talk to the debug interface - * by shifting in correct value to IR. - */ - - /* Ensure TAP is reset - maybe not necessary*/ - jtag_add_tlr(); - - struct jtag_tap *tap = jtag_info->tap; - struct scan_field field; - uint8_t ir_value = OR1K_XILINX_TAP_INST_USER1; - - field.num_bits = tap->ir_length; - field.out_value = &ir_value; - field.in_value = NULL; - - jtag_add_ir_scan(tap, &field, TAP_IDLE); - - return jtag_execute_queue(); -} - -static struct or1k_tap_ip xilinx_bscan_tap = { - .name = "xilinx_bscan", - .init = or1k_tap_xilinx_bscan_init, -}; - -int or1k_tap_xilinx_bscan_register(void) -{ - list_add_tail(&xilinx_bscan_tap.list, &tap_list); - return 0; -} diff --git a/src/target/quark_d20xx.c b/src/target/quark_d20xx.c deleted file mode 100644 index 42d3b8c73..000000000 --- a/src/target/quark_d20xx.c +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright(c) 2015-2016 Intel Corporation. - * - * Jessica Gomez (jessica.gomez.hernandez@intel.com) - * Ivan De Cesaris (ivan.de.cesaris@intel.com) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - * Contact Information: - * Intel Corporation - */ - -/* - * @file - * Debugger for Intel Quark D20xx - * The CPU TAP (Lakemont TAP) is used for software debug and the CLTAP is - * used for SoC level operations. - * - * Reference document: - * Intel Quark microcontroller D2000 Debug Operations (web search for doc num 333241) - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include - -#include "target.h" -#include "target_type.h" -#include "breakpoints.h" -#include "lakemont.h" -#include "x86_32_common.h" - -int quark_d20xx_target_create(struct target *t, Jim_Interp *interp) -{ - struct x86_32_common *x86_32 = calloc(1, sizeof(struct x86_32_common)); - if (x86_32 == NULL) { - LOG_ERROR("%s out of memory", __func__); - return ERROR_FAIL; - } - x86_32_common_init_arch_info(t, x86_32); - lakemont_init_arch_info(t, x86_32); - x86_32->core_type = LMT3_5; - return ERROR_OK; -} - -int quark_d20xx_init_target(struct command_context *cmd_ctx, struct target *t) -{ - return lakemont_init_target(cmd_ctx, t); -} - -static int quark_d20xx_reset_deassert(struct target *t) -{ - int retval; - - /* Can't detect if a warm reset happened while halted but we can make the - * openocd and target state consistent here if in probe mode already - */ - if (!check_not_halted(t)) { - retval = lakemont_update_after_probemode_entry(t); - if (retval != ERROR_OK) { - LOG_ERROR("%s core state update fail", __func__); - return retval; - } - /* resume target if reset mode is run */ - if (!t->reset_halt) { - retval = lakemont_resume(t, 1, 0, 0, 0); - if (retval != ERROR_OK) { - LOG_ERROR("%s could not resume target", __func__); - return retval; - } - } - } - - return ERROR_OK; -} - -struct target_type quark_d20xx_target = { - .name = "quark_d20xx", - .target_create = quark_d20xx_target_create, - .init_target = quark_d20xx_init_target, - /* lakemont probemode specific code */ - .poll = lakemont_poll, - .arch_state = lakemont_arch_state, - .halt = lakemont_halt, - .resume = lakemont_resume, - .step = lakemont_step, - .assert_reset = lakemont_reset_assert, - .deassert_reset = quark_d20xx_reset_deassert, - /* common x86 code */ - .commands = x86_32_command_handlers, - .get_gdb_reg_list = x86_32_get_gdb_reg_list, - .read_memory = x86_32_common_read_memory, - .write_memory = x86_32_common_write_memory, - .add_breakpoint = x86_32_common_add_breakpoint, - .remove_breakpoint = x86_32_common_remove_breakpoint, - .add_watchpoint = x86_32_common_add_watchpoint, - .remove_watchpoint = x86_32_common_remove_watchpoint, - .virt2phys = x86_32_common_virt2phys, - .read_phys_memory = x86_32_common_read_phys_mem, - .write_phys_memory = x86_32_common_write_phys_mem, - .mmu = x86_32_common_mmu, -}; diff --git a/src/target/quark_x10xx.c b/src/target/quark_x10xx.c deleted file mode 100644 index 189f6cc65..000000000 --- a/src/target/quark_x10xx.c +++ /dev/null @@ -1,98 +0,0 @@ -/* - * 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) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - * Contact Information: - * Intel Corporation - */ - -/* - * @file - * Debugger for Intel Quark SoC X1000 - * Intel Quark X10xx is the first product in the Quark family of SoCs. - * It is an IA-32 (Pentium x86 ISA) compatible SoC. The core CPU in the - * X10xx is codenamed Lakemont. Lakemont version 1 (LMT1) is used in X10xx. - * The CPU TAP (Lakemont TAP) is used for software debug and the CLTAP is - * used for SoC level operations. - * Useful docs are here: https://communities.intel.com/community/makers/documentation - * Intel Quark SoC X1000 OpenOCD/GDB/Eclipse App Note (web search for doc num 330015) - * Intel Quark SoC X1000 Debug Operations User Guide (web search for doc num 329866) - * Intel Quark SoC X1000 Datasheet (web search for doc num 329676) - * - * This file implements any Quark SoC specific features such as resetbreak (TODO) - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include - -#include "target.h" -#include "target_type.h" -#include "lakemont.h" -#include "x86_32_common.h" - -int quark_x10xx_target_create(struct target *t, Jim_Interp *interp) -{ - struct x86_32_common *x86_32 = calloc(1, sizeof(struct x86_32_common)); - if (x86_32 == NULL) { - LOG_ERROR("%s out of memory", __func__); - return ERROR_FAIL; - } - x86_32_common_init_arch_info(t, x86_32); - lakemont_init_arch_info(t, x86_32); - x86_32->core_type = LMT1; - return ERROR_OK; -} - -int quark_x10xx_init_target(struct command_context *cmd_ctx, struct target *t) -{ - return lakemont_init_target(cmd_ctx, t); -} - -struct target_type quark_x10xx_target = { - .name = "quark_x10xx", - /* Quark X1000 SoC */ - .target_create = quark_x10xx_target_create, - .init_target = quark_x10xx_init_target, - /* lakemont probemode specific code */ - .poll = lakemont_poll, - .arch_state = lakemont_arch_state, - .halt = lakemont_halt, - .resume = lakemont_resume, - .step = lakemont_step, - .assert_reset = lakemont_reset_assert, - .deassert_reset = lakemont_reset_deassert, - /* common x86 code */ - .commands = x86_32_command_handlers, - .get_gdb_reg_list = x86_32_get_gdb_reg_list, - .read_memory = x86_32_common_read_memory, - .write_memory = x86_32_common_write_memory, - .add_breakpoint = x86_32_common_add_breakpoint, - .remove_breakpoint = x86_32_common_remove_breakpoint, - .add_watchpoint = x86_32_common_add_watchpoint, - .remove_watchpoint = x86_32_common_remove_watchpoint, - .virt2phys = x86_32_common_virt2phys, - .read_phys_memory = x86_32_common_read_phys_mem, - .write_phys_memory = x86_32_common_write_phys_mem, - .mmu = x86_32_common_mmu, -}; diff --git a/src/target/register.c b/src/target/register.c deleted file mode 100644 index 1d63e12f7..000000000 --- a/src/target/register.c +++ /dev/null @@ -1,113 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * Copyright (C) 2007,2008 Øyvind Harboe * - * oyvind.harboe@zylin.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "register.h" -#include - -/** - * @file - * Holds utilities to work with register caches. - * - * OpenOCD uses machine registers internally, and exposes them by name - * to Tcl scripts. Sets of related registers are grouped into caches. - * For example, a CPU core will expose a set of registers, and there - * may be separate registers associated with debug or trace modules. - */ - -struct reg *register_get_by_name(struct reg_cache *first, - const char *name, bool search_all) -{ - unsigned i; - struct reg_cache *cache = first; - - while (cache) { - for (i = 0; i < cache->num_regs; i++) { - if (strcmp(cache->reg_list[i].name, name) == 0) - return &(cache->reg_list[i]); - } - - if (search_all) - cache = cache->next; - else - break; - } - - return NULL; -} - -struct reg_cache **register_get_last_cache_p(struct reg_cache **first) -{ - struct reg_cache **cache_p = first; - - if (*cache_p) - while (*cache_p) - cache_p = &((*cache_p)->next); - else - return first; - - return cache_p; -} - -void register_unlink_cache(struct reg_cache **cache_p, const struct reg_cache *cache) -{ - while (*cache_p && *cache_p != cache) - cache_p = &((*cache_p)->next); - if (*cache_p) - *cache_p = cache->next; -} - -/** Marks the contents of the register cache as invalid (and clean). */ -void register_cache_invalidate(struct reg_cache *cache) -{ - struct reg *reg = cache->reg_list; - - for (unsigned n = cache->num_regs; n != 0; n--, reg++) { - reg->valid = 0; - reg->dirty = 0; - } -} - -static int register_get_dummy_core_reg(struct reg *reg) -{ - return ERROR_OK; -} - -static int register_set_dummy_core_reg(struct reg *reg, uint8_t *buf) -{ - reg->dirty = 1; - reg->valid = 1; - - return ERROR_OK; -} - -static const struct reg_arch_type dummy_type = { - .get = register_get_dummy_core_reg, - .set = register_set_dummy_core_reg, -}; - -void register_init_dummy(struct reg *reg) -{ - reg->type = &dummy_type; -} diff --git a/src/target/register.h b/src/target/register.h deleted file mode 100644 index d4c328160..000000000 --- a/src/target/register.h +++ /dev/null @@ -1,167 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * Copyright (C) 2007,2008 Øyvind Harboe * - * oyvind.harboe@zylin.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifndef OPENOCD_TARGET_REGISTER_H -#define OPENOCD_TARGET_REGISTER_H - -struct target; - -enum reg_type { - REG_TYPE_INT, - REG_TYPE_INT8, - REG_TYPE_INT16, - REG_TYPE_INT32, - REG_TYPE_INT64, - REG_TYPE_INT128, - REG_TYPE_UINT8, - REG_TYPE_UINT16, - REG_TYPE_UINT32, - REG_TYPE_UINT64, - REG_TYPE_UINT128, - REG_TYPE_CODE_PTR, - REG_TYPE_DATA_PTR, - REG_TYPE_FLOAT, - REG_TYPE_IEEE_SINGLE, - REG_TYPE_IEEE_DOUBLE, - REG_TYPE_ARCH_DEFINED, -}; - -struct reg_feature { - const char *name; -}; - -struct reg_data_type_vector { - struct reg_data_type *type; - uint32_t count; -}; - -struct reg_data_type_union_field { - const char *name; - struct reg_data_type *type; - struct reg_data_type_union_field *next; -}; - -struct reg_data_type_union { - struct reg_data_type_union_field *fields; -}; - -struct reg_data_type_bitfield { - uint32_t start; - uint32_t end; -}; - -struct reg_data_type_struct_field { - const char *name; - bool use_bitfields; - union { - struct reg_data_type_bitfield *bitfield; - struct reg_data_type *type; - }; - struct reg_data_type_struct_field *next; -}; - -struct reg_data_type_struct { - uint32_t size; - struct reg_data_type_struct_field *fields; -}; - -struct reg_data_type_flags_field { - const char *name; - struct reg_data_type_bitfield *bitfield; - struct reg_data_type_flags_field *next; -}; - -struct reg_data_type_flags { - uint32_t size; - struct reg_data_type_flags_field *fields; -}; - -enum reg_data_type_class { - REG_TYPE_CLASS_VECTOR, - REG_TYPE_CLASS_UNION, - REG_TYPE_CLASS_STRUCT, - REG_TYPE_CLASS_FLAGS, -}; - -struct reg_data_type { - enum reg_type type; - const char *id; - enum reg_data_type_class type_class; - union { - struct reg_data_type_vector *reg_type_vector; - struct reg_data_type_union *reg_type_union; - struct reg_data_type_struct *reg_type_struct; - struct reg_data_type_flags *reg_type_flags; - }; -}; - -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; -}; - -struct reg_cache { - const char *name; - struct reg_cache *next; - struct reg *reg_list; - unsigned num_regs; -}; - -struct reg_arch_type { - int (*get)(struct reg *reg); - int (*set)(struct reg *reg, uint8_t *buf); -}; - -struct reg *register_get_by_name(struct reg_cache *first, - const char *name, bool search_all); -struct reg_cache **register_get_last_cache_p(struct reg_cache **first); -void register_unlink_cache(struct reg_cache **cache_p, const struct reg_cache *cache); -void register_cache_invalidate(struct reg_cache *cache); - -void register_init_dummy(struct reg *reg); - -#endif /* OPENOCD_TARGET_REGISTER_H */ diff --git a/src/target/riscv/asm.h b/src/target/riscv/asm.h deleted file mode 100644 index 051e0f918..000000000 --- a/src/target/riscv/asm.h +++ /dev/null @@ -1,36 +0,0 @@ -#ifndef TARGET__RISCV__ASM_H -#define TARGET__RISCV__ASM_H - -#include "riscv.h" - -/*** Version-independent functions that we don't want in the main address space. ***/ - -static uint32_t load(const struct target *target, unsigned int rd, - unsigned int base, uint16_t offset) __attribute__ ((unused)); -static uint32_t load(const struct target *target, unsigned int rd, - unsigned int base, uint16_t offset) -{ - switch (riscv_xlen(target)) { - case 32: - return lw(rd, base, offset); - case 64: - return ld(rd, base, offset); - } - assert(0); -} - -static uint32_t store(const struct target *target, unsigned int src, - unsigned int base, uint16_t offset) __attribute__ ((unused)); -static uint32_t store(const struct target *target, unsigned int src, - unsigned int base, uint16_t offset) -{ - switch (riscv_xlen(target)) { - case 32: - return sw(src, base, offset); - case 64: - return sd(src, base, offset); - } - assert(0); -} - -#endif diff --git a/src/target/riscv/debug_defines.h b/src/target/riscv/debug_defines.h deleted file mode 100644 index ec535dbb6..000000000 --- a/src/target/riscv/debug_defines.h +++ /dev/null @@ -1,1501 +0,0 @@ -#define DTM_IDCODE 0x01 -/* -* Identifies the release version of this part. - */ -#define DTM_IDCODE_VERSION_OFFSET 28 -#define DTM_IDCODE_VERSION_LENGTH 4 -#define DTM_IDCODE_VERSION (0xf << DTM_IDCODE_VERSION_OFFSET) -/* -* Identifies the designer's part number of this part. - */ -#define DTM_IDCODE_PARTNUMBER_OFFSET 12 -#define DTM_IDCODE_PARTNUMBER_LENGTH 16 -#define DTM_IDCODE_PARTNUMBER (0xffff << DTM_IDCODE_PARTNUMBER_OFFSET) -/* -* Identifies the designer/manufacturer of this part. Bits 6:0 must be -* bits 6:0 of the designer/manufacturer's Identification Code as -* assigned by JEDEC Standard JEP106. Bits 10:7 contain the modulo-16 -* count of the number of continuation characters (0x7f) in that same -* Identification Code. - */ -#define DTM_IDCODE_MANUFID_OFFSET 1 -#define DTM_IDCODE_MANUFID_LENGTH 11 -#define DTM_IDCODE_MANUFID (0x7ff << DTM_IDCODE_MANUFID_OFFSET) -#define DTM_IDCODE_1_OFFSET 0 -#define DTM_IDCODE_1_LENGTH 1 -#define DTM_IDCODE_1 (0x1 << DTM_IDCODE_1_OFFSET) -#define DTM_DTMCS 0x10 -/* -* Writing 1 to this bit resets the DMI controller, clearing any -* sticky error state. - */ -#define DTM_DTMCS_DMIRESET_OFFSET 16 -#define DTM_DTMCS_DMIRESET_LENGTH 1 -#define DTM_DTMCS_DMIRESET (0x1 << DTM_DTMCS_DMIRESET_OFFSET) -/* -* This is the minimum number of cycles a debugger should spend in -* Run-Test/Idle after every DMI scan to avoid a 'busy' -* return code (\Fdmistat of 3). A debugger must still -* check \Fdmistat when necessary. -* -* 0: It is not necessary to enter Run-Test/Idle at all. -* -* 1: Enter Run-Test/Idle and leave it immediately. -* -* 2: Enter Run-Test/Idle and stay there for 1 cycle before leaving. -* -* And so on. - */ -#define DTM_DTMCS_IDLE_OFFSET 12 -#define DTM_DTMCS_IDLE_LENGTH 3 -#define DTM_DTMCS_IDLE (0x7 << DTM_DTMCS_IDLE_OFFSET) -/* -* 0: No error. -* -* 1: Reserved. Interpret the same as 2. -* -* 2: An operation failed (resulted in \Fop of 2). -* -* 3: An operation was attempted while a DMI access was still in -* progress (resulted in \Fop of 3). - */ -#define DTM_DTMCS_DMISTAT_OFFSET 10 -#define DTM_DTMCS_DMISTAT_LENGTH 2 -#define DTM_DTMCS_DMISTAT (0x3 << DTM_DTMCS_DMISTAT_OFFSET) -/* -* The size of \Faddress in \Rdmi. - */ -#define DTM_DTMCS_ABITS_OFFSET 4 -#define DTM_DTMCS_ABITS_LENGTH 6 -#define DTM_DTMCS_ABITS (0x3f << DTM_DTMCS_ABITS_OFFSET) -/* -* 0: Version described in spec version 0.11. -* -* 1: Version described in spec version 0.12 (and later?), which -* reduces the DMI data width to 32 bits. -* -* Other values are reserved for future use. - */ -#define DTM_DTMCS_VERSION_OFFSET 0 -#define DTM_DTMCS_VERSION_LENGTH 4 -#define DTM_DTMCS_VERSION (0xf << DTM_DTMCS_VERSION_OFFSET) -#define DTM_DMI 0x11 -/* -* Address used for DMI access. In Update-DR this value is used -* to access the DM over the DMI. - */ -#define DTM_DMI_ADDRESS_OFFSET 34 -#define DTM_DMI_ADDRESS_LENGTH abits -#define DTM_DMI_ADDRESS (((1L<> lo) & ((1 << (hi+1-lo)) - 1); -} - -static uint32_t bit(uint32_t value, unsigned int b) { - return (value >> b) & 1; -} - -static uint32_t jal(unsigned int rd, uint32_t imm) __attribute__ ((unused)); -static uint32_t jal(unsigned int rd, uint32_t imm) { - return (bit(imm, 20) << 31) | - (bits(imm, 10, 1) << 21) | - (bit(imm, 11) << 20) | - (bits(imm, 19, 12) << 12) | - (rd << 7) | - MATCH_JAL; -} - -static uint32_t csrsi(unsigned int csr, uint16_t imm) __attribute__ ((unused)); -static uint32_t csrsi(unsigned int csr, uint16_t imm) { - return (csr << 20) | - (bits(imm, 4, 0) << 15) | - MATCH_CSRRSI; -} - -static uint32_t sw(unsigned int src, unsigned int base, uint16_t offset) __attribute__ ((unused)); -static uint32_t sw(unsigned int src, unsigned int base, uint16_t offset) -{ - return (bits(offset, 11, 5) << 25) | - (src << 20) | - (base << 15) | - (bits(offset, 4, 0) << 7) | - MATCH_SW; -} - -static uint32_t sd(unsigned int src, unsigned int base, uint16_t offset) __attribute__ ((unused)); -static uint32_t sd(unsigned int src, unsigned int base, uint16_t offset) -{ - return (bits(offset, 11, 5) << 25) | - (src << 20) | - (base << 15) | - (bits(offset, 4, 0) << 7) | - MATCH_SD; -} - -static uint32_t sh(unsigned int src, unsigned int base, uint16_t offset) __attribute__ ((unused)); -static uint32_t sh(unsigned int src, unsigned int base, uint16_t offset) -{ - return (bits(offset, 11, 5) << 25) | - (src << 20) | - (base << 15) | - (bits(offset, 4, 0) << 7) | - MATCH_SH; -} - -static uint32_t sb(unsigned int src, unsigned int base, uint16_t offset) __attribute__ ((unused)); -static uint32_t sb(unsigned int src, unsigned int base, uint16_t offset) -{ - return (bits(offset, 11, 5) << 25) | - (src << 20) | - (base << 15) | - (bits(offset, 4, 0) << 7) | - MATCH_SB; -} - -static uint32_t ld(unsigned int rd, unsigned int base, uint16_t offset) __attribute__ ((unused)); -static uint32_t ld(unsigned int rd, unsigned int base, uint16_t offset) -{ - return (bits(offset, 11, 0) << 20) | - (base << 15) | - (bits(rd, 4, 0) << 7) | - MATCH_LD; -} - -static uint32_t lw(unsigned int rd, unsigned int base, uint16_t offset) __attribute__ ((unused)); -static uint32_t lw(unsigned int rd, unsigned int base, uint16_t offset) -{ - return (bits(offset, 11, 0) << 20) | - (base << 15) | - (bits(rd, 4, 0) << 7) | - MATCH_LW; -} - -static uint32_t lh(unsigned int rd, unsigned int base, uint16_t offset) __attribute__ ((unused)); -static uint32_t lh(unsigned int rd, unsigned int base, uint16_t offset) -{ - return (bits(offset, 11, 0) << 20) | - (base << 15) | - (bits(rd, 4, 0) << 7) | - MATCH_LH; -} - -static uint32_t lb(unsigned int rd, unsigned int base, uint16_t offset) __attribute__ ((unused)); -static uint32_t lb(unsigned int rd, unsigned int base, uint16_t offset) -{ - return (bits(offset, 11, 0) << 20) | - (base << 15) | - (bits(rd, 4, 0) << 7) | - MATCH_LB; -} - -static uint32_t csrw(unsigned int source, unsigned int csr) __attribute__ ((unused)); -static uint32_t csrw(unsigned int source, unsigned int csr) { - return (csr << 20) | (source << 15) | MATCH_CSRRW; -} - -static uint32_t addi(unsigned int dest, unsigned int src, uint16_t imm) __attribute__ ((unused)); -static uint32_t addi(unsigned int dest, unsigned int src, uint16_t imm) -{ - return (bits(imm, 11, 0) << 20) | - (src << 15) | - (dest << 7) | - MATCH_ADDI; -} - -static uint32_t csrr(unsigned int rd, unsigned int csr) __attribute__ ((unused)); -static uint32_t csrr(unsigned int rd, unsigned int csr) { - return (csr << 20) | (rd << 7) | MATCH_CSRRS; -} - -static uint32_t fsw(unsigned int src, unsigned int base, uint16_t offset) __attribute__ ((unused)); -static uint32_t fsw(unsigned int src, unsigned int base, uint16_t offset) -{ - return (bits(offset, 11, 5) << 25) | - (bits(src, 4, 0) << 20) | - (base << 15) | - (bits(offset, 4, 0) << 7) | - MATCH_FSW; -} - -static uint32_t fsd(unsigned int src, unsigned int base, uint16_t offset) __attribute__ ((unused)); -static uint32_t fsd(unsigned int src, unsigned int base, uint16_t offset) -{ - return (bits(offset, 11, 5) << 25) | - (bits(src, 4, 0) << 20) | - (base << 15) | - (bits(offset, 4, 0) << 7) | - MATCH_FSD; -} - -static uint32_t flw(unsigned int dest, unsigned int base, uint16_t offset) __attribute__ ((unused)); -static uint32_t flw(unsigned int dest, unsigned int base, uint16_t offset) -{ - return (bits(offset, 11, 0) << 20) | - (base << 15) | - (bits(dest, 4, 0) << 7) | - MATCH_FLW; -} - -static uint32_t fld(unsigned int dest, unsigned int base, uint16_t offset) __attribute__ ((unused)); -static uint32_t fld(unsigned int dest, unsigned int base, uint16_t offset) -{ - return (bits(offset, 11, 0) << 20) | - (base << 15) | - (bits(dest, 4, 0) << 7) | - MATCH_FLD; -} - -static uint32_t fmv_x_s(unsigned dest, unsigned src) __attribute__ ((unused)); -static uint32_t fmv_x_s(unsigned dest, unsigned src) -{ - return src << 15 | - dest << 7 | - MATCH_FMV_X_S; -} - -static uint32_t fmv_x_d(unsigned dest, unsigned src) __attribute__ ((unused)); -static uint32_t fmv_x_d(unsigned dest, unsigned src) -{ - return src << 15 | - dest << 7 | - MATCH_FMV_X_D; -} - -static uint32_t fmv_s_x(unsigned dest, unsigned src) __attribute__ ((unused)); -static uint32_t fmv_s_x(unsigned dest, unsigned src) -{ - return src << 15 | - dest << 7 | - MATCH_FMV_S_X; -} - -static uint32_t fmv_d_x(unsigned dest, unsigned src) __attribute__ ((unused)); -static uint32_t fmv_d_x(unsigned dest, unsigned src) -{ - return src << 15 | - dest << 7 | - MATCH_FMV_D_X; -} - -static uint32_t ebreak(void) __attribute__ ((unused)); -static uint32_t ebreak(void) { return MATCH_EBREAK; } -static uint32_t ebreak_c(void) __attribute__ ((unused)); -static uint32_t ebreak_c(void) { return MATCH_C_EBREAK; } - -static uint32_t fence_i(void) __attribute__ ((unused)); -static uint32_t fence_i(void) -{ - return MATCH_FENCE_I; -} - -/* -static uint32_t lui(unsigned int dest, uint32_t imm) __attribute__ ((unused)); -static uint32_t lui(unsigned int dest, uint32_t imm) -{ - return (bits(imm, 19, 0) << 12) | - (dest << 7) | - MATCH_LUI; -} - -static uint32_t csrci(unsigned int csr, uint16_t imm) __attribute__ ((unused)); -static uint32_t csrci(unsigned int csr, uint16_t imm) { - return (csr << 20) | - (bits(imm, 4, 0) << 15) | - MATCH_CSRRCI; -} - -static uint32_t li(unsigned int dest, uint16_t imm) __attribute__ ((unused)); -static uint32_t li(unsigned int dest, uint16_t imm) -{ - return addi(dest, 0, imm); -} - -static uint32_t fsd(unsigned int src, unsigned int base, uint16_t offset) __attribute__ ((unused)); -static uint32_t fsd(unsigned int src, unsigned int base, uint16_t offset) -{ - return (bits(offset, 11, 5) << 25) | - (bits(src, 4, 0) << 20) | - (base << 15) | - (bits(offset, 4, 0) << 7) | - MATCH_FSD; -} - -static uint32_t ori(unsigned int dest, unsigned int src, uint16_t imm) __attribute__ ((unused)); -static uint32_t ori(unsigned int dest, unsigned int src, uint16_t imm) -{ - return (bits(imm, 11, 0) << 20) | - (src << 15) | - (dest << 7) | - MATCH_ORI; -} - -static uint32_t nop(void) __attribute__ ((unused)); -static uint32_t nop(void) -{ - return addi(0, 0, 0); -} -*/ - -static uint32_t xori(unsigned int dest, unsigned int src, uint16_t imm) __attribute__ ((unused)); -static uint32_t xori(unsigned int dest, unsigned int src, uint16_t imm) -{ - return (bits(imm, 11, 0) << 20) | - (src << 15) | - (dest << 7) | - MATCH_XORI; -} - -static uint32_t srli(unsigned int dest, unsigned int src, uint8_t shamt) __attribute__ ((unused)); -static uint32_t srli(unsigned int dest, unsigned int src, uint8_t shamt) -{ - return (bits(shamt, 4, 0) << 20) | - (src << 15) | - (dest << 7) | - MATCH_SRLI; -} - -static uint32_t fence(void) __attribute__((unused)); -static uint32_t fence(void) -{ - return MATCH_FENCE; -} diff --git a/src/target/riscv/riscv-011.c b/src/target/riscv/riscv-011.c deleted file mode 100644 index ed2a057ea..000000000 --- a/src/target/riscv/riscv-011.c +++ /dev/null @@ -1,2603 +0,0 @@ -/* - * Support for RISC-V, debug version 0.11. This was never an officially adopted - * spec, but SiFive made some silicon that uses it. - */ - -#include -#include -#include - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "target.h" -#include "target/algorithm.h" -#include "target_type.h" -#include "log.h" -#include "jtag/jtag.h" -#include "register.h" -#include "breakpoints.h" -#include "helper/time_support.h" -#include "riscv.h" -#include "asm.h" - -/** - * Since almost everything can be accomplish by scanning the dbus register, all - * functions here assume dbus is already selected. The exception are functions - * called directly by OpenOCD, which can't assume anything about what's - * currently in IR. They should set IR to dbus explicitly. - */ - -/** - * Code structure - * - * At the bottom of the stack are the OpenOCD JTAG functions: - * jtag_add_[id]r_scan - * jtag_execute_query - * jtag_add_runtest - * - * There are a few functions to just instantly shift a register and get its - * value: - * dtmcontrol_scan - * idcode_scan - * dbus_scan - * - * Because doing one scan and waiting for the result is slow, most functions - * batch up a bunch of dbus writes and then execute them all at once. They use - * the scans "class" for this: - * scans_new - * scans_delete - * scans_execute - * scans_add_... - * Usually you new(), call a bunch of add functions, then execute() and look - * at the results by calling scans_get...() - * - * Optimized functions will directly use the scans class above, but slightly - * lazier code will use the cache functions that in turn use the scans - * functions: - * cache_get... - * cache_set... - * cache_write - * cache_set... update a local structure, which is then synced to the target - * with cache_write(). Only Debug RAM words that are actually changed are sent - * to the target. Afterwards use cache_get... to read results. - */ - -#define get_field(reg, mask) (((reg) & (mask)) / ((mask) & ~((mask) << 1))) -#define set_field(reg, mask, val) (((reg) & ~(mask)) | (((val) * ((mask) & ~((mask) << 1))) & (mask))) - -#define DIM(x) (sizeof(x)/sizeof(*x)) - -// Constants for legacy SiFive hardware breakpoints. -#define CSR_BPCONTROL_X (1<<0) -#define CSR_BPCONTROL_W (1<<1) -#define CSR_BPCONTROL_R (1<<2) -#define CSR_BPCONTROL_U (1<<3) -#define CSR_BPCONTROL_S (1<<4) -#define CSR_BPCONTROL_H (1<<5) -#define CSR_BPCONTROL_M (1<<6) -#define CSR_BPCONTROL_BPMATCH (0xf<<7) -#define CSR_BPCONTROL_BPACTION (0xff<<11) - -#define DEBUG_ROM_START 0x800 -#define DEBUG_ROM_RESUME (DEBUG_ROM_START + 4) -#define DEBUG_ROM_EXCEPTION (DEBUG_ROM_START + 8) -#define DEBUG_RAM_START 0x400 - -#define SETHALTNOT 0x10c - -/*** JTAG registers. ***/ - -#define DTMCONTROL 0x10 -#define DTMCONTROL_DBUS_RESET (1<<16) -#define DTMCONTROL_IDLE (7<<10) -#define DTMCONTROL_ADDRBITS (0xf<<4) -#define DTMCONTROL_VERSION (0xf) - -#define DBUS 0x11 -#define DBUS_OP_START 0 -#define DBUS_OP_SIZE 2 -typedef enum { - DBUS_OP_NOP = 0, - DBUS_OP_READ = 1, - DBUS_OP_WRITE = 2 -} dbus_op_t; -typedef enum { - DBUS_STATUS_SUCCESS = 0, - DBUS_STATUS_FAILED = 2, - DBUS_STATUS_BUSY = 3 -} dbus_status_t; -#define DBUS_DATA_START 2 -#define DBUS_DATA_SIZE 34 -#define DBUS_ADDRESS_START 36 - -typedef enum { - RE_OK, - RE_FAIL, - RE_AGAIN -} riscv_error_t; - -typedef enum slot { - SLOT0, - SLOT1, - SLOT_LAST, -} slot_t; - -/*** Debug Bus registers. ***/ - -#define DMCONTROL 0x10 -#define DMCONTROL_INTERRUPT (((uint64_t)1)<<33) -#define DMCONTROL_HALTNOT (((uint64_t)1)<<32) -#define DMCONTROL_BUSERROR (7<<19) -#define DMCONTROL_SERIAL (3<<16) -#define DMCONTROL_AUTOINCREMENT (1<<15) -#define DMCONTROL_ACCESS (7<<12) -#define DMCONTROL_HARTID (0x3ff<<2) -#define DMCONTROL_NDRESET (1<<1) -#define DMCONTROL_FULLRESET 1 - -#define DMINFO 0x11 -#define DMINFO_ABUSSIZE (0x7fU<<25) -#define DMINFO_SERIALCOUNT (0xf<<21) -#define DMINFO_ACCESS128 (1<<20) -#define DMINFO_ACCESS64 (1<<19) -#define DMINFO_ACCESS32 (1<<18) -#define DMINFO_ACCESS16 (1<<17) -#define DMINFO_ACCESS8 (1<<16) -#define DMINFO_DRAMSIZE (0x3f<<10) -#define DMINFO_AUTHENTICATED (1<<5) -#define DMINFO_AUTHBUSY (1<<4) -#define DMINFO_AUTHTYPE (3<<2) -#define DMINFO_VERSION 3 - -/*** Info about the core being debugged. ***/ - -#define DBUS_ADDRESS_UNKNOWN 0xffff -#define WALL_CLOCK_TIMEOUT 2 - -// gdb's register list is defined in riscv_gdb_reg_names gdb/riscv-tdep.c in -// its source tree. We must interpret the numbers the same here. -enum { - REG_XPR0 = 0, - REG_XPR31 = 31, - REG_PC = 32, - REG_FPR0 = 33, - REG_FPR31 = 64, - REG_CSR0 = 65, - REG_MSTATUS = CSR_MSTATUS + REG_CSR0, - REG_CSR4095 = 4160, - REG_PRIV = 4161, - REG_COUNT -}; - -#define MAX_HWBPS 16 -#define DRAM_CACHE_SIZE 16 - -struct trigger { - uint64_t address; - uint32_t length; - uint64_t mask; - uint64_t value; - bool read, write, execute; - int unique_id; -}; - -struct memory_cache_line { - uint32_t data; - bool valid; - bool dirty; -}; - -typedef struct { - /* Number of address bits in the dbus register. */ - uint8_t addrbits; - /* Number of words in Debug RAM. */ - unsigned int dramsize; - uint64_t dcsr; - uint64_t dpc; - uint64_t misa; - uint64_t tselect; - bool tselect_dirty; - /* The value that mstatus actually has on the target right now. This is not - * the value we present to the user. That one may be stored in the - * reg_cache. */ - uint64_t mstatus_actual; - - struct memory_cache_line dram_cache[DRAM_CACHE_SIZE]; - - /* Single buffer that contains all register names, instead of calling - * malloc for each register. Needs to be freed when reg_list is freed. */ - char *reg_names; - /* Single buffer that contains all register values. */ - void *reg_values; - - // For each physical trigger, contains -1 if the hwbp is available, or the - // unique_id of the breakpoint/watchpoint that is using it. - int trigger_unique_id[MAX_HWBPS]; - - unsigned int trigger_count; - - // Number of run-test/idle cycles the target requests we do after each dbus - // access. - unsigned int dtmcontrol_idle; - - // This value is incremented every time a dbus access comes back as "busy". - // It's used to determine how many run-test/idle cycles to feed the target - // in between accesses. - unsigned int dbus_busy_delay; - - // This value is incremented every time we read the debug interrupt as - // high. It's used to add extra run-test/idle cycles after setting debug - // interrupt high, so ideally we never have to perform a whole extra scan - // before the interrupt is cleared. - unsigned int interrupt_high_delay; - - bool need_strict_step; - bool never_halted; -} riscv011_info_t; - -typedef struct { - bool haltnot; - bool interrupt; -} bits_t; - -/*** Necessary prototypes. ***/ - -static int poll_target(struct target *target, bool announce); -static int riscv011_poll(struct target *target); -static int register_get(struct reg *reg); - -/*** Utility functions. ***/ - -#define DEBUG_LENGTH 264 - -static riscv011_info_t *get_info(const struct target *target) -{ - riscv_info_t *info = (riscv_info_t *) target->arch_info; - return (riscv011_info_t *) info->version_specific; -} - -static unsigned int slot_offset(const struct target *target, slot_t slot) -{ - riscv011_info_t *info = get_info(target); - switch (riscv_xlen(target)) { - case 32: - switch (slot) { - case SLOT0: return 4; - case SLOT1: return 5; - case SLOT_LAST: return info->dramsize-1; - } - case 64: - switch (slot) { - case SLOT0: return 4; - case SLOT1: return 6; - case SLOT_LAST: return info->dramsize-2; - } - } - LOG_ERROR("slot_offset called with xlen=%d, slot=%d", - riscv_xlen(target), slot); - assert(0); -} - -static uint32_t load_slot(const struct target *target, unsigned int dest, - slot_t slot) -{ - unsigned int offset = DEBUG_RAM_START + 4 * slot_offset(target, slot); - return load(target, dest, ZERO, offset); -} - -static uint32_t store_slot(const struct target *target, unsigned int src, - slot_t slot) -{ - unsigned int offset = DEBUG_RAM_START + 4 * slot_offset(target, slot); - return store(target, src, ZERO, offset); -} - -static uint16_t dram_address(unsigned int index) -{ - if (index < 0x10) - return index; - else - return 0x40 + index - 0x10; -} - -static uint32_t dtmcontrol_scan(struct target *target, uint32_t out) -{ - struct scan_field field; - uint8_t in_value[4]; - uint8_t out_value[4]; - - buf_set_u32(out_value, 0, 32, out); - - jtag_add_ir_scan(target->tap, &select_dtmcontrol, TAP_IDLE); - - field.num_bits = 32; - field.out_value = out_value; - field.in_value = in_value; - jtag_add_dr_scan(target->tap, 1, &field, TAP_IDLE); - - /* Always return to dbus. */ - jtag_add_ir_scan(target->tap, &select_dbus, TAP_IDLE); - - int retval = jtag_execute_queue(); - if (retval != ERROR_OK) { - LOG_ERROR("failed jtag scan: %d", retval); - return retval; - } - - uint32_t in = buf_get_u32(field.in_value, 0, 32); - LOG_DEBUG("DTMCONTROL: 0x%x -> 0x%x", out, in); - - return in; -} - -static uint32_t idcode_scan(struct target *target) -{ - struct scan_field field; - uint8_t in_value[4]; - - jtag_add_ir_scan(target->tap, &select_idcode, TAP_IDLE); - - field.num_bits = 32; - field.out_value = NULL; - field.in_value = in_value; - jtag_add_dr_scan(target->tap, 1, &field, TAP_IDLE); - - int retval = jtag_execute_queue(); - if (retval != ERROR_OK) { - LOG_ERROR("failed jtag scan: %d", retval); - return retval; - } - - /* Always return to dbus. */ - jtag_add_ir_scan(target->tap, &select_dbus, TAP_IDLE); - - uint32_t in = buf_get_u32(field.in_value, 0, 32); - LOG_DEBUG("IDCODE: 0x0 -> 0x%x", in); - - return in; -} - -static void increase_dbus_busy_delay(struct target *target) -{ - riscv011_info_t *info = get_info(target); - info->dbus_busy_delay += info->dbus_busy_delay / 10 + 1; - LOG_INFO("dtmcontrol_idle=%d, dbus_busy_delay=%d, interrupt_high_delay=%d", - info->dtmcontrol_idle, info->dbus_busy_delay, - info->interrupt_high_delay); - - dtmcontrol_scan(target, DTMCONTROL_DBUS_RESET); -} - -static void increase_interrupt_high_delay(struct target *target) -{ - riscv011_info_t *info = get_info(target); - info->interrupt_high_delay += info->interrupt_high_delay / 10 + 1; - LOG_INFO("dtmcontrol_idle=%d, dbus_busy_delay=%d, interrupt_high_delay=%d", - info->dtmcontrol_idle, info->dbus_busy_delay, - info->interrupt_high_delay); -} - -static void add_dbus_scan(const struct target *target, struct scan_field *field, - uint8_t *out_value, uint8_t *in_value, dbus_op_t op, - uint16_t address, uint64_t data) -{ - riscv011_info_t *info = get_info(target); - - field->num_bits = info->addrbits + DBUS_OP_SIZE + DBUS_DATA_SIZE; - field->in_value = in_value; - field->out_value = out_value; - - buf_set_u64(out_value, DBUS_OP_START, DBUS_OP_SIZE, op); - buf_set_u64(out_value, DBUS_DATA_START, DBUS_DATA_SIZE, data); - buf_set_u64(out_value, DBUS_ADDRESS_START, info->addrbits, address); - - jtag_add_dr_scan(target->tap, 1, field, TAP_IDLE); - - int idle_count = info->dtmcontrol_idle + info->dbus_busy_delay; - if (data & DMCONTROL_INTERRUPT) { - idle_count += info->interrupt_high_delay; - } - - if (idle_count) { - jtag_add_runtest(idle_count, TAP_IDLE); - } -} - -static void dump_field(const struct scan_field *field) -{ - static const char *op_string[] = {"nop", "r", "w", "?"}; - static const char *status_string[] = {"+", "?", "F", "b"}; - - if (debug_level < LOG_LVL_DEBUG) - return; - - uint64_t out = buf_get_u64(field->out_value, 0, field->num_bits); - unsigned int out_op = (out >> DBUS_OP_START) & ((1 << DBUS_OP_SIZE) - 1); - char out_interrupt = ((out >> DBUS_DATA_START) & DMCONTROL_INTERRUPT) ? 'i' : '.'; - char out_haltnot = ((out >> DBUS_DATA_START) & DMCONTROL_HALTNOT) ? 'h' : '.'; - unsigned int out_data = out >> 2; - unsigned int out_address = out >> DBUS_ADDRESS_START; - uint64_t in = buf_get_u64(field->in_value, 0, field->num_bits); - unsigned int in_op = (in >> DBUS_OP_START) & ((1 << DBUS_OP_SIZE) - 1); - char in_interrupt = ((in >> DBUS_DATA_START) & DMCONTROL_INTERRUPT) ? 'i' : '.'; - char in_haltnot = ((in >> DBUS_DATA_START) & DMCONTROL_HALTNOT) ? 'h' : '.'; - unsigned int in_data = in >> 2; - unsigned int in_address = in >> DBUS_ADDRESS_START; - - log_printf_lf(LOG_LVL_DEBUG, - __FILE__, __LINE__, "scan", - "%db %s %c%c:%08x @%02x -> %s %c%c:%08x @%02x", - field->num_bits, - op_string[out_op], out_interrupt, out_haltnot, out_data, - out_address, - status_string[in_op], in_interrupt, in_haltnot, in_data, - in_address); -} - -static dbus_status_t dbus_scan(struct target *target, uint16_t *address_in, - uint64_t *data_in, dbus_op_t op, uint16_t address_out, uint64_t data_out) -{ - riscv011_info_t *info = get_info(target); - uint8_t in[8] = {0}; - uint8_t out[8]; - struct scan_field field = { - .num_bits = info->addrbits + DBUS_OP_SIZE + DBUS_DATA_SIZE, - .out_value = out, - .in_value = in - }; - - assert(info->addrbits != 0); - - buf_set_u64(out, DBUS_OP_START, DBUS_OP_SIZE, op); - buf_set_u64(out, DBUS_DATA_START, DBUS_DATA_SIZE, data_out); - buf_set_u64(out, DBUS_ADDRESS_START, info->addrbits, address_out); - - /* Assume dbus is already selected. */ - jtag_add_dr_scan(target->tap, 1, &field, TAP_IDLE); - - int idle_count = info->dtmcontrol_idle + info->dbus_busy_delay; - - if (idle_count) { - jtag_add_runtest(idle_count, TAP_IDLE); - } - - int retval = jtag_execute_queue(); - if (retval != ERROR_OK) { - LOG_ERROR("dbus_scan failed jtag scan"); - return retval; - } - - if (data_in) { - *data_in = buf_get_u64(in, DBUS_DATA_START, DBUS_DATA_SIZE); - } - - if (address_in) { - *address_in = buf_get_u32(in, DBUS_ADDRESS_START, info->addrbits); - } - - dump_field(&field); - - return buf_get_u32(in, DBUS_OP_START, DBUS_OP_SIZE); -} - -static uint64_t dbus_read(struct target *target, uint16_t address) -{ - uint64_t value; - dbus_status_t status; - uint16_t address_in; - - unsigned i = 0; - do { - status = dbus_scan(target, &address_in, &value, DBUS_OP_READ, address, 0); - if (status == DBUS_STATUS_BUSY) { - increase_dbus_busy_delay(target); - } - } while (((status == DBUS_STATUS_BUSY) || (address_in != address)) && - i++ < 256); - - if (status != DBUS_STATUS_SUCCESS) { - LOG_ERROR("failed read from 0x%x; value=0x%" PRIx64 ", status=%d\n", address, value, status); - } - - return value; -} - -static void dbus_write(struct target *target, uint16_t address, uint64_t value) -{ - dbus_status_t status = DBUS_STATUS_BUSY; - unsigned i = 0; - while (status == DBUS_STATUS_BUSY && i++ < 256) { - status = dbus_scan(target, NULL, NULL, DBUS_OP_WRITE, address, value); - if (status == DBUS_STATUS_BUSY) { - increase_dbus_busy_delay(target); - } - } - if (status != DBUS_STATUS_SUCCESS) { - LOG_ERROR("failed to write 0x%" PRIx64 " to 0x%x; status=%d\n", value, address, status); - } -} - -/*** scans "class" ***/ - -typedef struct { - // Number of scans that space is reserved for. - unsigned int scan_count; - // Size reserved in memory for each scan, in bytes. - unsigned int scan_size; - unsigned int next_scan; - uint8_t *in; - uint8_t *out; - struct scan_field *field; - const struct target *target; -} scans_t; - -static scans_t *scans_new(struct target *target, unsigned int scan_count) -{ - scans_t *scans = malloc(sizeof(scans_t)); - scans->scan_count = scan_count; - // This code also gets called before xlen is detected. - if (riscv_xlen(target)) - scans->scan_size = 2 + riscv_xlen(target) / 8; - else - scans->scan_size = 2 + 128 / 8; - scans->next_scan = 0; - scans->in = calloc(scans->scan_size, scans->scan_count); - scans->out = calloc(scans->scan_size, scans->scan_count); - scans->field = calloc(scans->scan_count, sizeof(struct scan_field)); - scans->target = target; - return scans; -} - -static scans_t *scans_delete(scans_t *scans) -{ - assert(scans); - free(scans->field); - free(scans->out); - free(scans->in); - free(scans); - return NULL; -} - -static void scans_reset(scans_t *scans) -{ - scans->next_scan = 0; -} - -static void scans_dump(scans_t *scans) -{ - for (unsigned int i = 0; i < scans->next_scan; i++) { - dump_field(&scans->field[i]); - } -} - -static int scans_execute(scans_t *scans) -{ - int retval = jtag_execute_queue(); - if (retval != ERROR_OK) { - LOG_ERROR("failed jtag scan: %d", retval); - return retval; - } - - scans_dump(scans); - - return ERROR_OK; -} - -/** Add a 32-bit dbus write to the scans structure. */ -static void scans_add_write32(scans_t *scans, uint16_t address, uint32_t data, - bool set_interrupt) -{ - const unsigned int i = scans->next_scan; - int data_offset = scans->scan_size * i; - add_dbus_scan(scans->target, &scans->field[i], scans->out + data_offset, - scans->in + data_offset, DBUS_OP_WRITE, address, - (set_interrupt ? DMCONTROL_INTERRUPT : 0) | DMCONTROL_HALTNOT | data); - scans->next_scan++; - assert(scans->next_scan <= scans->scan_count); -} - -/** Add a 32-bit dbus write for an instruction that jumps to the beginning of - * debug RAM. */ -static void scans_add_write_jump(scans_t *scans, uint16_t address, - bool set_interrupt) -{ - scans_add_write32(scans, address, - jal(0, (uint32_t) (DEBUG_ROM_RESUME - (DEBUG_RAM_START + 4*address))), - set_interrupt); -} - -/** Add a 32-bit dbus write for an instruction that loads from the indicated - * slot. */ -static void scans_add_write_load(scans_t *scans, uint16_t address, - unsigned int reg, slot_t slot, bool set_interrupt) -{ - scans_add_write32(scans, address, load_slot(scans->target, reg, slot), - set_interrupt); -} - -/** Add a 32-bit dbus write for an instruction that stores to the indicated - * slot. */ -static void scans_add_write_store(scans_t *scans, uint16_t address, - unsigned int reg, slot_t slot, bool set_interrupt) -{ - scans_add_write32(scans, address, store_slot(scans->target, reg, slot), - set_interrupt); -} - -/** Add a 32-bit dbus read. */ -static void scans_add_read32(scans_t *scans, uint16_t address, bool set_interrupt) -{ - assert(scans->next_scan < scans->scan_count); - const unsigned int i = scans->next_scan; - int data_offset = scans->scan_size * i; - add_dbus_scan(scans->target, &scans->field[i], scans->out + data_offset, - scans->in + data_offset, DBUS_OP_READ, address, - (set_interrupt ? DMCONTROL_INTERRUPT : 0) | DMCONTROL_HALTNOT); - scans->next_scan++; -} - -/** Add one or more scans to read the indicated slot. */ -static void scans_add_read(scans_t *scans, slot_t slot, bool set_interrupt) -{ - const struct target *target = scans->target; - switch (riscv_xlen(target)) { - case 32: - scans_add_read32(scans, slot_offset(target, slot), set_interrupt); - break; - case 64: - scans_add_read32(scans, slot_offset(target, slot), false); - scans_add_read32(scans, slot_offset(target, slot) + 1, set_interrupt); - break; - } -} - -static uint32_t scans_get_u32(scans_t *scans, unsigned int index, - unsigned first, unsigned num) -{ - return buf_get_u32(scans->in + scans->scan_size * index, first, num); -} - -static uint64_t scans_get_u64(scans_t *scans, unsigned int index, - unsigned first, unsigned num) -{ - return buf_get_u64(scans->in + scans->scan_size * index, first, num); -} - -/*** end of scans class ***/ - -static uint32_t dram_read32(struct target *target, unsigned int index) -{ - uint16_t address = dram_address(index); - uint32_t value = dbus_read(target, address); - return value; -} - -static void dram_write32(struct target *target, unsigned int index, uint32_t value, - bool set_interrupt) -{ - uint64_t dbus_value = DMCONTROL_HALTNOT | value; - if (set_interrupt) - dbus_value |= DMCONTROL_INTERRUPT; - dbus_write(target, dram_address(index), dbus_value); -} - -/** Read the haltnot and interrupt bits. */ -static bits_t read_bits(struct target *target) -{ - uint64_t value; - dbus_status_t status; - uint16_t address_in; - riscv011_info_t *info = get_info(target); - - bits_t err_result = { - .haltnot = 0, - .interrupt = 0 - }; - - do { - unsigned i = 0; - do { - status = dbus_scan(target, &address_in, &value, DBUS_OP_READ, 0, 0); - if (status == DBUS_STATUS_BUSY) { - if (address_in == (1<addrbits) - 1 && - value == (1ULL<= 256) { - LOG_ERROR("Failed to read from 0x%x; status=%d", address_in, status); - return err_result; - } - } while (address_in > 0x10 && address_in != DMCONTROL); - - bits_t result = { - .haltnot = get_field(value, DMCONTROL_HALTNOT), - .interrupt = get_field(value, DMCONTROL_INTERRUPT) - }; - return result; -} - -static int wait_for_debugint_clear(struct target *target, bool ignore_first) -{ - time_t start = time(NULL); - if (ignore_first) { - // Throw away the results of the first read, since they'll contain the - // result of the read that happened just before debugint was set. - // (Assuming the last scan before calling this function was one that - // sets debugint.) - read_bits(target); - } - while (1) { - bits_t bits = read_bits(target); - if (!bits.interrupt) { - return ERROR_OK; - } - if (time(NULL) - start > WALL_CLOCK_TIMEOUT) { - LOG_ERROR("Timed out waiting for debug int to clear."); - return ERROR_FAIL; - } - } -} - -static int dram_check32(struct target *target, unsigned int index, - uint32_t expected) -{ - uint16_t address = dram_address(index); - uint32_t actual = dbus_read(target, address); - if (expected != actual) { - LOG_ERROR("Wrote 0x%x to Debug RAM at %d, but read back 0x%x", - expected, index, actual); - return ERROR_FAIL; - } - return ERROR_OK; -} - -static void cache_set32(struct target *target, unsigned int index, uint32_t data) -{ - riscv011_info_t *info = get_info(target); - if (info->dram_cache[index].valid && - info->dram_cache[index].data == data) { - // This is already preset on the target. - LOG_DEBUG("cache[0x%x] = 0x%x (hit)", index, data); - return; - } - LOG_DEBUG("cache[0x%x] = 0x%x", index, data); - info->dram_cache[index].data = data; - info->dram_cache[index].valid = true; - info->dram_cache[index].dirty = true; -} - -static void cache_set(struct target *target, slot_t slot, uint64_t data) -{ - unsigned int offset = slot_offset(target, slot); - cache_set32(target, offset, data); - if (riscv_xlen(target) > 32) { - cache_set32(target, offset + 1, data >> 32); - } -} - -static void cache_set_jump(struct target *target, unsigned int index) -{ - cache_set32(target, index, - jal(0, (uint32_t) (DEBUG_ROM_RESUME - (DEBUG_RAM_START + 4*index)))); -} - -static void cache_set_load(struct target *target, unsigned int index, - unsigned int reg, slot_t slot) -{ - uint16_t offset = DEBUG_RAM_START + 4 * slot_offset(target, slot); - cache_set32(target, index, load(target, reg, ZERO, offset)); -} - -static void cache_set_store(struct target *target, unsigned int index, - unsigned int reg, slot_t slot) -{ - uint16_t offset = DEBUG_RAM_START + 4 * slot_offset(target, slot); - cache_set32(target, index, store(target, reg, ZERO, offset)); -} - -static void dump_debug_ram(struct target *target) -{ - for (unsigned int i = 0; i < DRAM_CACHE_SIZE; i++) { - uint32_t value = dram_read32(target, i); - LOG_ERROR("Debug RAM 0x%x: 0x%08x", i, value); - } -} - -/* Call this if the code you just ran writes to debug RAM entries 0 through 3. */ -static void cache_invalidate(struct target *target) -{ - riscv011_info_t *info = get_info(target); - for (unsigned int i = 0; i < info->dramsize; i++) { - info->dram_cache[i].valid = false; - info->dram_cache[i].dirty = false; - } -} - -/* Called by cache_write() after the program has run. Also call this if you're - * running programs without calling cache_write(). */ -static void cache_clean(struct target *target) -{ - riscv011_info_t *info = get_info(target); - for (unsigned int i = 0; i < info->dramsize; i++) { - if (i >= 4) { - info->dram_cache[i].valid = false; - } - info->dram_cache[i].dirty = false; - } -} - -static int cache_check(struct target *target) -{ - riscv011_info_t *info = get_info(target); - int error = 0; - - for (unsigned int i = 0; i < info->dramsize; i++) { - if (info->dram_cache[i].valid && !info->dram_cache[i].dirty) { - if (dram_check32(target, i, info->dram_cache[i].data) != ERROR_OK) { - error++; - } - } - } - - if (error) { - dump_debug_ram(target); - return ERROR_FAIL; - } - - return ERROR_OK; -} - -/** Write cache to the target, and optionally run the program. - * Then read the value at address into the cache, assuming address < 128. */ -#define CACHE_NO_READ 128 -static int cache_write(struct target *target, unsigned int address, bool run) -{ - LOG_DEBUG("enter"); - riscv011_info_t *info = get_info(target); - scans_t *scans = scans_new(target, info->dramsize + 2); - - unsigned int last = info->dramsize; - for (unsigned int i = 0; i < info->dramsize; i++) { - if (info->dram_cache[i].dirty) { - last = i; - } - } - - if (last == info->dramsize) { - // Nothing needs to be written to RAM. - dbus_write(target, DMCONTROL, DMCONTROL_HALTNOT | DMCONTROL_INTERRUPT); - - } else { - for (unsigned int i = 0; i < info->dramsize; i++) { - if (info->dram_cache[i].dirty) { - bool set_interrupt = (i == last && run); - scans_add_write32(scans, i, info->dram_cache[i].data, - set_interrupt); - } - } - } - - if (run || address < CACHE_NO_READ) { - // Throw away the results of the first read, since it'll contain the - // result of the read that happened just before debugint was set. - scans_add_read32(scans, address, false); - - // This scan contains the results of the read the caller requested, as - // well as an interrupt bit worth looking at. - scans_add_read32(scans, address, false); - } - - int retval = scans_execute(scans); - if (retval != ERROR_OK) { - LOG_ERROR("JTAG execute failed."); - return retval; - } - - int errors = 0; - for (unsigned int i = 0; i < scans->next_scan; i++) { - dbus_status_t status = scans_get_u32(scans, i, DBUS_OP_START, - DBUS_OP_SIZE); - switch (status) { - case DBUS_STATUS_SUCCESS: - break; - case DBUS_STATUS_FAILED: - LOG_ERROR("Debug RAM write failed. Hardware error?"); - return ERROR_FAIL; - case DBUS_STATUS_BUSY: - errors++; - break; - default: - LOG_ERROR("Got invalid bus access status: %d", status); - return ERROR_FAIL; - } - } - - if (errors) { - increase_dbus_busy_delay(target); - - // Try again, using the slow careful code. - // Write all RAM, just to be extra cautious. - for (unsigned int i = 0; i < info->dramsize; i++) { - if (i == last && run) { - dram_write32(target, last, info->dram_cache[last].data, true); - } else { - dram_write32(target, i, info->dram_cache[i].data, false); - } - info->dram_cache[i].dirty = false; - } - if (run) { - cache_clean(target); - } - - if (wait_for_debugint_clear(target, true) != ERROR_OK) { - LOG_ERROR("Debug interrupt didn't clear."); - dump_debug_ram(target); - return ERROR_FAIL; - } - - } else { - if (run) { - cache_clean(target); - } else { - for (unsigned int i = 0; i < info->dramsize; i++) { - info->dram_cache[i].dirty = false; - } - } - - if (run || address < CACHE_NO_READ) { - int interrupt = scans_get_u32(scans, scans->next_scan-1, - DBUS_DATA_START + 33, 1); - if (interrupt) { - increase_interrupt_high_delay(target); - // Slow path wait for it to clear. - if (wait_for_debugint_clear(target, false) != ERROR_OK) { - LOG_ERROR("Debug interrupt didn't clear."); - dump_debug_ram(target); - return ERROR_FAIL; - } - } else { - // We read a useful value in that last scan. - unsigned int read_addr = scans_get_u32(scans, scans->next_scan-1, - DBUS_ADDRESS_START, info->addrbits); - if (read_addr != address) { - LOG_INFO("Got data from 0x%x but expected it from 0x%x", - read_addr, address); - } - info->dram_cache[read_addr].data = - scans_get_u32(scans, scans->next_scan-1, DBUS_DATA_START, 32); - info->dram_cache[read_addr].valid = true; - } - } - } - - scans_delete(scans); - LOG_DEBUG("exit"); - - return ERROR_OK; -} - -static uint32_t cache_get32(struct target *target, unsigned int address) -{ - riscv011_info_t *info = get_info(target); - if (!info->dram_cache[address].valid) { - info->dram_cache[address].data = dram_read32(target, address); - info->dram_cache[address].valid = true; - } - return info->dram_cache[address].data; -} - -static uint64_t cache_get(struct target *target, slot_t slot) -{ - unsigned int offset = slot_offset(target, slot); - uint64_t value = cache_get32(target, offset); - if (riscv_xlen(target) > 32) { - value |= ((uint64_t) cache_get32(target, offset + 1)) << 32; - } - return value; -} - -/* Write instruction that jumps from the specified word in Debug RAM to resume - * in Debug ROM. */ -static void dram_write_jump(struct target *target, unsigned int index, - bool set_interrupt) -{ - dram_write32(target, index, - jal(0, (uint32_t) (DEBUG_ROM_RESUME - (DEBUG_RAM_START + 4*index))), - set_interrupt); -} - -static int wait_for_state(struct target *target, enum target_state state) -{ - time_t start = time(NULL); - while (1) { - int result = riscv011_poll(target); - if (result != ERROR_OK) { - return result; - } - if (target->state == state) { - return ERROR_OK; - } - if (time(NULL) - start > WALL_CLOCK_TIMEOUT) { - LOG_ERROR("Timed out waiting for state %d.", state); - return ERROR_FAIL; - } - } -} - -static int read_csr(struct target *target, uint64_t *value, uint32_t csr) -{ - cache_set32(target, 0, csrr(S0, csr)); - cache_set_store(target, 1, S0, SLOT0); - cache_set_jump(target, 2); - if (cache_write(target, 4, true) != ERROR_OK) { - return ERROR_FAIL; - } - *value = cache_get(target, SLOT0); - LOG_DEBUG("csr 0x%x = 0x%" PRIx64, csr, *value); - - return ERROR_OK; -} - -static int write_csr(struct target *target, uint32_t csr, uint64_t value) -{ - LOG_DEBUG("csr 0x%x <- 0x%" PRIx64, csr, value); - cache_set_load(target, 0, S0, SLOT0); - cache_set32(target, 1, csrw(S0, csr)); - cache_set_jump(target, 2); - cache_set(target, SLOT0, value); - if (cache_write(target, 4, true) != ERROR_OK) { - return ERROR_FAIL; - } - - return ERROR_OK; -} - -static int write_gpr(struct target *target, unsigned int gpr, uint64_t value) -{ - cache_set_load(target, 0, gpr, SLOT0); - cache_set_jump(target, 1); - cache_set(target, SLOT0, value); - if (cache_write(target, 4, true) != ERROR_OK) { - return ERROR_FAIL; - } - return ERROR_OK; -} - -static int maybe_read_tselect(struct target *target) -{ - riscv011_info_t *info = get_info(target); - - if (info->tselect_dirty) { - int result = read_csr(target, &info->tselect, CSR_TSELECT); - if (result != ERROR_OK) - return result; - info->tselect_dirty = false; - } - - return ERROR_OK; -} - -static int maybe_write_tselect(struct target *target) -{ - riscv011_info_t *info = get_info(target); - - if (!info->tselect_dirty) { - int result = write_csr(target, CSR_TSELECT, info->tselect); - if (result != ERROR_OK) - return result; - info->tselect_dirty = true; - } - - return ERROR_OK; -} - -static int execute_resume(struct target *target, bool step) -{ - riscv011_info_t *info = get_info(target); - - LOG_DEBUG("step=%d", step); - - maybe_write_tselect(target); - - // TODO: check if dpc is dirty (which also is true if an exception was hit - // at any time) - cache_set_load(target, 0, S0, SLOT0); - cache_set32(target, 1, csrw(S0, CSR_DPC)); - cache_set_jump(target, 2); - cache_set(target, SLOT0, info->dpc); - if (cache_write(target, 4, true) != ERROR_OK) { - return ERROR_FAIL; - } - - struct reg *mstatus_reg = &target->reg_cache->reg_list[REG_MSTATUS]; - if (mstatus_reg->valid) { - uint64_t mstatus_user = buf_get_u64(mstatus_reg->value, 0, riscv_xlen(target)); - if (mstatus_user != info->mstatus_actual) { - cache_set_load(target, 0, S0, SLOT0); - cache_set32(target, 1, csrw(S0, CSR_MSTATUS)); - cache_set_jump(target, 2); - cache_set(target, SLOT0, mstatus_user); - if (cache_write(target, 4, true) != ERROR_OK) { - return ERROR_FAIL; - } - } - } - - info->dcsr |= DCSR_EBREAKM | DCSR_EBREAKH | DCSR_EBREAKS | DCSR_EBREAKU; - info->dcsr &= ~DCSR_HALT; - - if (step) { - info->dcsr |= DCSR_STEP; - } else { - info->dcsr &= ~DCSR_STEP; - } - - dram_write32(target, 0, lw(S0, ZERO, DEBUG_RAM_START + 16), false); - dram_write32(target, 1, csrw(S0, CSR_DCSR), false); - dram_write32(target, 2, fence_i(), false); - dram_write_jump(target, 3, false); - - // Write DCSR value, set interrupt and clear haltnot. - uint64_t dbus_value = DMCONTROL_INTERRUPT | info->dcsr; - dbus_write(target, dram_address(4), dbus_value); - - cache_invalidate(target); - - if (wait_for_debugint_clear(target, true) != ERROR_OK) { - LOG_ERROR("Debug interrupt didn't clear."); - return ERROR_FAIL; - } - - target->state = TARGET_RUNNING; - register_cache_invalidate(target->reg_cache); - - return ERROR_OK; -} - -// Execute a step, and wait for reentry into Debug Mode. -static int full_step(struct target *target, bool announce) -{ - int result = execute_resume(target, true); - if (result != ERROR_OK) - return result; - time_t start = time(NULL); - while (1) { - result = poll_target(target, announce); - if (result != ERROR_OK) - return result; - if (target->state != TARGET_DEBUG_RUNNING) - break; - if (time(NULL) - start > WALL_CLOCK_TIMEOUT) { - LOG_ERROR("Timed out waiting for step to complete."); - return ERROR_FAIL; - } - } - return ERROR_OK; -} - -static int resume(struct target *target, int debug_execution, bool step) -{ - if (debug_execution) { - LOG_ERROR("TODO: debug_execution is true"); - return ERROR_FAIL; - } - - return execute_resume(target, step); -} - -/** Update register sizes based on xlen. */ -static void update_reg_list(struct target *target) -{ - riscv011_info_t *info = get_info(target); - if (info->reg_values) { - free(info->reg_values); - } - info->reg_values = malloc(REG_COUNT * riscv_xlen(target) / 4); - - for (unsigned int i = 0; i < REG_COUNT; i++) { - struct reg *r = &target->reg_cache->reg_list[i]; - r->value = info->reg_values + i * riscv_xlen(target) / 4; - if (r->dirty) { - LOG_ERROR("Register %d was dirty. Its value is lost.", i); - } - if (i == REG_PRIV) { - r->size = 8; - } else { - r->size = riscv_xlen(target); - } - r->valid = false; - } -} - -static uint64_t reg_cache_get(struct target *target, unsigned int number) -{ - struct reg *r = &target->reg_cache->reg_list[number]; - if (!r->valid) { - LOG_ERROR("Register cache entry for %d is invalid!", number); - assert(r->valid); - } - uint64_t value = buf_get_u64(r->value, 0, r->size); - LOG_DEBUG("%s = 0x%" PRIx64, r->name, value); - return value; -} - -static void reg_cache_set(struct target *target, unsigned int number, - uint64_t value) -{ - struct reg *r = &target->reg_cache->reg_list[number]; - LOG_DEBUG("%s <= 0x%" PRIx64, r->name, value); - r->valid = true; - buf_set_u64(r->value, 0, r->size, value); -} - -static int update_mstatus_actual(struct target *target) -{ - struct reg *mstatus_reg = &target->reg_cache->reg_list[REG_MSTATUS]; - if (mstatus_reg->valid) { - // We previously made it valid. - return ERROR_OK; - } - - // Force reading the register. In that process mstatus_actual will be - // updated. - return register_get(&target->reg_cache->reg_list[REG_MSTATUS]); -} - -/*** OpenOCD target functions. ***/ - -static int register_get(struct reg *reg) -{ - struct target *target = (struct target *) reg->arch_info; - riscv011_info_t *info = get_info(target); - - maybe_write_tselect(target); - - if (reg->number <= REG_XPR31) { - buf_set_u64(reg->value, 0, riscv_xlen(target), reg_cache_get(target, reg->number)); - LOG_DEBUG("%s=0x%" PRIx64, reg->name, reg_cache_get(target, reg->number)); - return ERROR_OK; - } else if (reg->number == REG_PC) { - buf_set_u32(reg->value, 0, 32, info->dpc); - reg->valid = true; - LOG_DEBUG("%s=0x%" PRIx64 " (cached)", reg->name, info->dpc); - return ERROR_OK; - } else if (reg->number >= REG_FPR0 && reg->number <= REG_FPR31) { - int result = update_mstatus_actual(target); - if (result != ERROR_OK) { - return result; - } - unsigned i = 0; - if ((info->mstatus_actual & MSTATUS_FS) == 0) { - info->mstatus_actual = set_field(info->mstatus_actual, MSTATUS_FS, 1); - cache_set_load(target, i++, S0, SLOT1); - cache_set32(target, i++, csrw(S0, CSR_MSTATUS)); - cache_set(target, SLOT1, info->mstatus_actual); - } - - if (riscv_xlen(target) == 32) { - cache_set32(target, i++, fsw(reg->number - REG_FPR0, 0, DEBUG_RAM_START + 16)); - } else { - cache_set32(target, i++, fsd(reg->number - REG_FPR0, 0, DEBUG_RAM_START + 16)); - } - cache_set_jump(target, i++); - } else if (reg->number >= REG_CSR0 && reg->number <= REG_CSR4095) { - cache_set32(target, 0, csrr(S0, reg->number - REG_CSR0)); - cache_set_store(target, 1, S0, SLOT0); - cache_set_jump(target, 2); - } else if (reg->number == REG_PRIV) { - buf_set_u64(reg->value, 0, 8, get_field(info->dcsr, DCSR_PRV)); - LOG_DEBUG("%s=%d (cached)", reg->name, - (int) get_field(info->dcsr, DCSR_PRV)); - return ERROR_OK; - } else { - LOG_ERROR("Don't know how to read register %d (%s)", reg->number, reg->name); - return ERROR_FAIL; - } - - if (cache_write(target, 4, true) != ERROR_OK) { - return ERROR_FAIL; - } - - uint32_t exception = cache_get32(target, info->dramsize-1); - if (exception) { - LOG_ERROR("Got exception 0x%x when reading register %d", exception, - reg->number); - buf_set_u64(reg->value, 0, riscv_xlen(target), ~0); - return ERROR_FAIL; - } - - uint64_t value = cache_get(target, SLOT0); - LOG_DEBUG("%s=0x%" PRIx64, reg->name, value); - buf_set_u64(reg->value, 0, riscv_xlen(target), value); - - if (reg->number == REG_MSTATUS) { - info->mstatus_actual = value; - reg->valid = true; - } - - return ERROR_OK; -} - -static int register_write(struct target *target, unsigned int number, - uint64_t value) -{ - riscv011_info_t *info = get_info(target); - - maybe_write_tselect(target); - - if (number == S0) { - cache_set_load(target, 0, S0, SLOT0); - cache_set32(target, 1, csrw(S0, CSR_DSCRATCH)); - cache_set_jump(target, 2); - } else if (number == S1) { - cache_set_load(target, 0, S0, SLOT0); - cache_set_store(target, 1, S0, SLOT_LAST); - cache_set_jump(target, 2); - } else if (number <= REG_XPR31) { - cache_set_load(target, 0, number - REG_XPR0, SLOT0); - cache_set_jump(target, 1); - } else if (number == REG_PC) { - info->dpc = value; - return ERROR_OK; - } else if (number >= REG_FPR0 && number <= REG_FPR31) { - int result = update_mstatus_actual(target); - if (result != ERROR_OK) { - return result; - } - unsigned i = 0; - if ((info->mstatus_actual & MSTATUS_FS) == 0) { - info->mstatus_actual = set_field(info->mstatus_actual, MSTATUS_FS, 1); - cache_set_load(target, i++, S0, SLOT1); - cache_set32(target, i++, csrw(S0, CSR_MSTATUS)); - cache_set(target, SLOT1, info->mstatus_actual); - } - - if (riscv_xlen(target) == 32) { - cache_set32(target, i++, flw(number - REG_FPR0, 0, DEBUG_RAM_START + 16)); - } else { - cache_set32(target, i++, fld(number - REG_FPR0, 0, DEBUG_RAM_START + 16)); - } - cache_set_jump(target, i++); - } else if (number >= REG_CSR0 && number <= REG_CSR4095) { - cache_set_load(target, 0, S0, SLOT0); - cache_set32(target, 1, csrw(S0, number - REG_CSR0)); - cache_set_jump(target, 2); - - if (number == REG_MSTATUS) { - info->mstatus_actual = value; - } - } else if (number == REG_PRIV) { - info->dcsr = set_field(info->dcsr, DCSR_PRV, value); - return ERROR_OK; - } else { - LOG_ERROR("Don't know how to write register %d", number); - return ERROR_FAIL; - } - - cache_set(target, SLOT0, value); - if (cache_write(target, info->dramsize - 1, true) != ERROR_OK) { - return ERROR_FAIL; - } - - uint32_t exception = cache_get32(target, info->dramsize-1); - if (exception) { - LOG_ERROR("Got exception 0x%x when writing register %d", exception, - number); - return ERROR_FAIL; - } - - return ERROR_OK; -} - -static int register_set(struct reg *reg, uint8_t *buf) -{ - struct target *target = (struct target *) reg->arch_info; - - uint64_t value = buf_get_u64(buf, 0, riscv_xlen(target)); - - LOG_DEBUG("write 0x%" PRIx64 " to %s", value, reg->name); - struct reg *r = &target->reg_cache->reg_list[reg->number]; - r->valid = true; - memcpy(r->value, buf, (r->size + 7) / 8); - - return register_write(target, reg->number, value); -} - -static struct reg_arch_type riscv_reg_arch_type = { - .get = register_get, - .set = register_set -}; - -static int halt(struct target *target) -{ - LOG_DEBUG("riscv_halt()"); - jtag_add_ir_scan(target->tap, &select_dbus, TAP_IDLE); - - cache_set32(target, 0, csrsi(CSR_DCSR, DCSR_HALT)); - cache_set32(target, 1, csrr(S0, CSR_MHARTID)); - cache_set32(target, 2, sw(S0, ZERO, SETHALTNOT)); - cache_set_jump(target, 3); - - if (cache_write(target, 4, true) != ERROR_OK) { - LOG_ERROR("cache_write() failed."); - return ERROR_FAIL; - } - - return ERROR_OK; -} - -static int init_target(struct command_context *cmd_ctx, - struct target *target) -{ - LOG_DEBUG("init"); - riscv_info_t *generic_info = (riscv_info_t *) target->arch_info; - generic_info->get_register = NULL; - generic_info->version_specific = calloc(1, sizeof(riscv011_info_t)); - if (!generic_info->version_specific) - return ERROR_FAIL; - riscv011_info_t *info = get_info(target); - - target->reg_cache = calloc(1, sizeof(*target->reg_cache)); - target->reg_cache->name = "RISC-V registers"; - target->reg_cache->num_regs = REG_COUNT; - - target->reg_cache->reg_list = calloc(REG_COUNT, sizeof(struct reg)); - - const unsigned int max_reg_name_len = 12; - info->reg_names = calloc(1, REG_COUNT * max_reg_name_len); - char *reg_name = info->reg_names; - info->reg_values = NULL; - - for (unsigned int i = 0; i < REG_COUNT; i++) { - struct reg *r = &target->reg_cache->reg_list[i]; - r->number = i; - r->caller_save = true; - r->dirty = false; - r->valid = false; - r->exist = true; - r->type = &riscv_reg_arch_type; - r->arch_info = target; - if (i <= REG_XPR31) { - sprintf(reg_name, "x%d", i); - } else if (i == REG_PC) { - sprintf(reg_name, "pc"); - } else if (i >= REG_FPR0 && i <= REG_FPR31) { - sprintf(reg_name, "f%d", i - REG_FPR0); - } else if (i >= REG_CSR0 && i <= REG_CSR4095) { - sprintf(reg_name, "csr%d", i - REG_CSR0); - } else if (i == REG_PRIV) { - sprintf(reg_name, "priv"); - } - if (reg_name[0]) { - r->name = reg_name; - } - reg_name += strlen(reg_name) + 1; - assert(reg_name < info->reg_names + REG_COUNT * max_reg_name_len); - } - update_reg_list(target); - - memset(info->trigger_unique_id, 0xff, sizeof(info->trigger_unique_id)); - - return ERROR_OK; -} - -static void deinit_target(struct target *target) -{ - LOG_DEBUG("riscv_deinit_target()"); - riscv_info_t *info = (riscv_info_t *) target->arch_info; - free(info->version_specific); - info->version_specific = NULL; -} - -static int add_trigger(struct target *target, struct trigger *trigger) -{ - riscv011_info_t *info = get_info(target); - - maybe_read_tselect(target); - - unsigned int i; - for (i = 0; i < info->trigger_count; i++) { - if (info->trigger_unique_id[i] != -1) { - continue; - } - - write_csr(target, CSR_TSELECT, i); - - uint64_t tdata1; - read_csr(target, &tdata1, CSR_TDATA1); - int type = get_field(tdata1, MCONTROL_TYPE(riscv_xlen(target))); - - if (type != 2) { - continue; - } - - if (tdata1 & (MCONTROL_EXECUTE | MCONTROL_STORE | MCONTROL_LOAD)) { - // Trigger is already in use, presumably by user code. - continue; - } - - // address/data match trigger - tdata1 |= MCONTROL_DMODE(riscv_xlen(target)); - tdata1 = set_field(tdata1, MCONTROL_ACTION, - MCONTROL_ACTION_DEBUG_MODE); - tdata1 = set_field(tdata1, MCONTROL_MATCH, MCONTROL_MATCH_EQUAL); - tdata1 |= MCONTROL_M; - if (info->misa & (1 << ('H' - 'A'))) - tdata1 |= MCONTROL_H; - if (info->misa & (1 << ('S' - 'A'))) - tdata1 |= MCONTROL_S; - if (info->misa & (1 << ('U' - 'A'))) - tdata1 |= MCONTROL_U; - - if (trigger->execute) - tdata1 |= MCONTROL_EXECUTE; - if (trigger->read) - tdata1 |= MCONTROL_LOAD; - if (trigger->write) - tdata1 |= MCONTROL_STORE; - - write_csr(target, CSR_TDATA1, tdata1); - - uint64_t tdata1_rb; - read_csr(target, &tdata1_rb, CSR_TDATA1); - LOG_DEBUG("tdata1=0x%" PRIx64, tdata1_rb); - - if (tdata1 != tdata1_rb) { - LOG_DEBUG("Trigger %d doesn't support what we need; After writing 0x%" - PRIx64 " to tdata1 it contains 0x%" PRIx64, - i, tdata1, tdata1_rb); - write_csr(target, CSR_TDATA1, 0); - continue; - } - - write_csr(target, CSR_TDATA2, trigger->address); - - LOG_DEBUG("Using resource %d for bp %d", i, - trigger->unique_id); - info->trigger_unique_id[i] = trigger->unique_id; - break; - } - if (i >= info->trigger_count) { - LOG_ERROR("Couldn't find an available hardware trigger."); - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - } - - return ERROR_OK; -} - -static int remove_trigger(struct target *target, struct trigger *trigger) -{ - riscv011_info_t *info = get_info(target); - - maybe_read_tselect(target); - - unsigned int i; - for (i = 0; i < info->trigger_count; i++) { - if (info->trigger_unique_id[i] == trigger->unique_id) { - break; - } - } - if (i >= info->trigger_count) { - LOG_ERROR("Couldn't find the hardware resources used by hardware " - "trigger."); - return ERROR_FAIL; - } - LOG_DEBUG("Stop using resource %d for bp %d", i, trigger->unique_id); - write_csr(target, CSR_TSELECT, i); - write_csr(target, CSR_TDATA1, 0); - info->trigger_unique_id[i] = -1; - - return ERROR_OK; -} - -static void trigger_from_breakpoint(struct trigger *trigger, - const struct breakpoint *breakpoint) -{ - trigger->address = breakpoint->address; - trigger->length = breakpoint->length; - trigger->mask = ~0LL; - trigger->read = false; - trigger->write = false; - trigger->execute = true; - // unique_id is unique across both breakpoints and watchpoints. - trigger->unique_id = breakpoint->unique_id; -} - -static void trigger_from_watchpoint(struct trigger *trigger, - const struct watchpoint *watchpoint) -{ - trigger->address = watchpoint->address; - trigger->length = watchpoint->length; - trigger->mask = watchpoint->mask; - trigger->value = watchpoint->value; - trigger->read = (watchpoint->rw == WPT_READ || watchpoint->rw == WPT_ACCESS); - trigger->write = (watchpoint->rw == WPT_WRITE || watchpoint->rw == WPT_ACCESS); - trigger->execute = false; - // unique_id is unique across both breakpoints and watchpoints. - trigger->unique_id = watchpoint->unique_id; -} - -static int add_breakpoint(struct target *target, - struct breakpoint *breakpoint) -{ - if (breakpoint->type == BKPT_SOFT) { - if (target_read_memory(target, breakpoint->address, breakpoint->length, 1, - breakpoint->orig_instr) != ERROR_OK) { - LOG_ERROR("Failed to read original instruction at 0x%x", - breakpoint->address); - return ERROR_FAIL; - } - - int retval; - if (breakpoint->length == 4) { - retval = target_write_u32(target, breakpoint->address, ebreak()); - } else { - retval = target_write_u16(target, breakpoint->address, ebreak_c()); - } - if (retval != ERROR_OK) { - LOG_ERROR("Failed to write %d-byte breakpoint instruction at 0x%x", - breakpoint->length, breakpoint->address); - return ERROR_FAIL; - } - - } else if (breakpoint->type == BKPT_HARD) { - struct trigger trigger; - trigger_from_breakpoint(&trigger, breakpoint); - int result = add_trigger(target, &trigger); - if (result != ERROR_OK) { - return result; - } - - } else { - LOG_INFO("OpenOCD only supports hardware and software breakpoints."); - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - } - - breakpoint->set = true; - - return ERROR_OK; -} - -static int remove_breakpoint(struct target *target, - struct breakpoint *breakpoint) -{ - if (breakpoint->type == BKPT_SOFT) { - if (target_write_memory(target, breakpoint->address, breakpoint->length, 1, - breakpoint->orig_instr) != ERROR_OK) { - LOG_ERROR("Failed to restore instruction for %d-byte breakpoint at " - "0x%x", breakpoint->length, breakpoint->address); - return ERROR_FAIL; - } - - } else if (breakpoint->type == BKPT_HARD) { - struct trigger trigger; - trigger_from_breakpoint(&trigger, breakpoint); - int result = remove_trigger(target, &trigger); - if (result != ERROR_OK) { - return result; - } - - } else { - LOG_INFO("OpenOCD only supports hardware and software breakpoints."); - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - } - - breakpoint->set = false; - - return ERROR_OK; -} - -static int add_watchpoint(struct target *target, - struct watchpoint *watchpoint) -{ - struct trigger trigger; - trigger_from_watchpoint(&trigger, watchpoint); - - int result = add_trigger(target, &trigger); - if (result != ERROR_OK) { - return result; - } - watchpoint->set = true; - - return ERROR_OK; -} - -static int remove_watchpoint(struct target *target, - struct watchpoint *watchpoint) -{ - struct trigger trigger; - trigger_from_watchpoint(&trigger, watchpoint); - - int result = remove_trigger(target, &trigger); - if (result != ERROR_OK) { - return result; - } - watchpoint->set = false; - - return ERROR_OK; -} - -static int strict_step(struct target *target, bool announce) -{ - riscv011_info_t *info = get_info(target); - - LOG_DEBUG("enter"); - - struct breakpoint *breakpoint = target->breakpoints; - while (breakpoint) { - remove_breakpoint(target, breakpoint); - breakpoint = breakpoint->next; - } - - struct watchpoint *watchpoint = target->watchpoints; - while (watchpoint) { - remove_watchpoint(target, watchpoint); - watchpoint = watchpoint->next; - } - - int result = full_step(target, announce); - if (result != ERROR_OK) - return result; - - breakpoint = target->breakpoints; - while (breakpoint) { - add_breakpoint(target, breakpoint); - breakpoint = breakpoint->next; - } - - watchpoint = target->watchpoints; - while (watchpoint) { - add_watchpoint(target, watchpoint); - watchpoint = watchpoint->next; - } - - info->need_strict_step = false; - - return ERROR_OK; -} - -static int step(struct target *target, int current, uint32_t address, - int handle_breakpoints) -{ - riscv011_info_t *info = get_info(target); - - jtag_add_ir_scan(target->tap, &select_dbus, TAP_IDLE); - - if (!current) { - if (riscv_xlen(target) > 32) { - LOG_WARNING("Asked to resume at 32-bit PC on %d-bit target.", - riscv_xlen(target)); - } - int result = register_write(target, REG_PC, address); - if (result != ERROR_OK) - return result; - } - - if (info->need_strict_step || handle_breakpoints) { - int result = strict_step(target, true); - if (result != ERROR_OK) - return result; - } else { - return resume(target, 0, true); - } - - return ERROR_OK; -} - -static int examine(struct target *target) -{ - // Don't need to select dbus, since the first thing we do is read dtmcontrol. - - uint32_t dtmcontrol = dtmcontrol_scan(target, 0); - LOG_DEBUG("dtmcontrol=0x%x", dtmcontrol); - LOG_DEBUG(" addrbits=%d", get_field(dtmcontrol, DTMCONTROL_ADDRBITS)); - LOG_DEBUG(" version=%d", get_field(dtmcontrol, DTMCONTROL_VERSION)); - LOG_DEBUG(" idle=%d", get_field(dtmcontrol, DTMCONTROL_IDLE)); - if (dtmcontrol == 0) { - LOG_ERROR("dtmcontrol is 0. Check JTAG connectivity/board power."); - return ERROR_FAIL; - } - if (get_field(dtmcontrol, DTMCONTROL_VERSION) != 0) { - LOG_ERROR("Unsupported DTM version %d. (dtmcontrol=0x%x)", - get_field(dtmcontrol, DTMCONTROL_VERSION), dtmcontrol); - return ERROR_FAIL; - } - - riscv011_info_t *info = get_info(target); - info->addrbits = get_field(dtmcontrol, DTMCONTROL_ADDRBITS); - info->dtmcontrol_idle = get_field(dtmcontrol, DTMCONTROL_IDLE); - if (info->dtmcontrol_idle == 0) { - // Some old SiFive cores don't set idle but need it to be 1. - uint32_t idcode = idcode_scan(target); - if (idcode == 0x10e31913) - info->dtmcontrol_idle = 1; - } - - uint32_t dminfo = dbus_read(target, DMINFO); - LOG_DEBUG("dminfo: 0x%08x", dminfo); - LOG_DEBUG(" abussize=0x%x", get_field(dminfo, DMINFO_ABUSSIZE)); - LOG_DEBUG(" serialcount=0x%x", get_field(dminfo, DMINFO_SERIALCOUNT)); - LOG_DEBUG(" access128=%d", get_field(dminfo, DMINFO_ACCESS128)); - LOG_DEBUG(" access64=%d", get_field(dminfo, DMINFO_ACCESS64)); - LOG_DEBUG(" access32=%d", get_field(dminfo, DMINFO_ACCESS32)); - LOG_DEBUG(" access16=%d", get_field(dminfo, DMINFO_ACCESS16)); - LOG_DEBUG(" access8=%d", get_field(dminfo, DMINFO_ACCESS8)); - LOG_DEBUG(" dramsize=0x%x", get_field(dminfo, DMINFO_DRAMSIZE)); - LOG_DEBUG(" authenticated=0x%x", get_field(dminfo, DMINFO_AUTHENTICATED)); - LOG_DEBUG(" authbusy=0x%x", get_field(dminfo, DMINFO_AUTHBUSY)); - LOG_DEBUG(" authtype=0x%x", get_field(dminfo, DMINFO_AUTHTYPE)); - LOG_DEBUG(" version=0x%x", get_field(dminfo, DMINFO_VERSION)); - - if (get_field(dminfo, DMINFO_VERSION) != 1) { - LOG_ERROR("OpenOCD only supports Debug Module version 1, not %d " - "(dminfo=0x%x)", get_field(dminfo, DMINFO_VERSION), dminfo); - return ERROR_FAIL; - } - - info->dramsize = get_field(dminfo, DMINFO_DRAMSIZE) + 1; - - if (get_field(dminfo, DMINFO_AUTHTYPE) != 0) { - LOG_ERROR("Authentication required by RISC-V core but not " - "supported by OpenOCD. dminfo=0x%x", dminfo); - return ERROR_FAIL; - } - - // Figure out XLEN, and test writing all of Debug RAM while we're at it. - cache_set32(target, 0, xori(S1, ZERO, -1)); - // 0xffffffff 0xffffffff:ffffffff 0xffffffff:ffffffff:ffffffff:ffffffff - cache_set32(target, 1, srli(S1, S1, 31)); - // 0x00000001 0x00000001:ffffffff 0x00000001:ffffffff:ffffffff:ffffffff - cache_set32(target, 2, sw(S1, ZERO, DEBUG_RAM_START)); - cache_set32(target, 3, srli(S1, S1, 31)); - // 0x00000000 0x00000000:00000003 0x00000000:00000003:ffffffff:ffffffff - cache_set32(target, 4, sw(S1, ZERO, DEBUG_RAM_START + 4)); - cache_set_jump(target, 5); - for (unsigned i = 6; i < info->dramsize; i++) { - cache_set32(target, i, i * 0x01020304); - } - - cache_write(target, 0, false); - - // Check that we can actually read/write dram. - if (cache_check(target) != ERROR_OK) { - return ERROR_FAIL; - } - - cache_write(target, 0, true); - cache_invalidate(target); - - uint32_t word0 = cache_get32(target, 0); - uint32_t word1 = cache_get32(target, 1); - riscv_info_t *generic_info = (riscv_info_t *) target->arch_info; - if (word0 == 1 && word1 == 0) { - generic_info->xlen[0] = 32; - } else if (word0 == 0xffffffff && word1 == 3) { - generic_info->xlen[0] = 64; - } else if (word0 == 0xffffffff && word1 == 0xffffffff) { - generic_info->xlen[0] = 128; - } else { - uint32_t exception = cache_get32(target, info->dramsize-1); - LOG_ERROR("Failed to discover xlen; word0=0x%x, word1=0x%x, exception=0x%x", - word0, word1, exception); - dump_debug_ram(target); - return ERROR_FAIL; - } - LOG_DEBUG("Discovered XLEN is %d", riscv_xlen(target)); - - // Update register list to match discovered XLEN. - update_reg_list(target); - - if (read_csr(target, &info->misa, CSR_MISA) != ERROR_OK) { - LOG_ERROR("Failed to read misa."); - return ERROR_FAIL; - } - - info->never_halted = true; - - int result = riscv011_poll(target); - if (result != ERROR_OK) { - return result; - } - - target_set_examined(target); - LOG_INFO("Examined RISCV core; XLEN=%d, misa=0x%" PRIx64, riscv_xlen(target), info->misa); - - return ERROR_OK; -} - -static riscv_error_t handle_halt_routine(struct target *target) -{ - riscv011_info_t *info = get_info(target); - - scans_t *scans = scans_new(target, 256); - - // Read all GPRs as fast as we can, because gdb is going to ask for them - // anyway. Reading them one at a time is much slower. - - // Write the jump back to address 1. - scans_add_write_jump(scans, 1, false); - for (int reg = 1; reg < 32; reg++) { - if (reg == S0 || reg == S1) { - continue; - } - - // Write store instruction. - scans_add_write_store(scans, 0, reg, SLOT0, true); - - // Read value. - scans_add_read(scans, SLOT0, false); - } - - // Write store of s0 at index 1. - scans_add_write_store(scans, 1, S0, SLOT0, false); - // Write jump at index 2. - scans_add_write_jump(scans, 2, false); - - // Read S1 from debug RAM - scans_add_write_load(scans, 0, S0, SLOT_LAST, true); - // Read value. - scans_add_read(scans, SLOT0, false); - - // Read S0 from dscratch - unsigned int csr[] = {CSR_DSCRATCH, CSR_DPC, CSR_DCSR}; - for (unsigned int i = 0; i < DIM(csr); i++) { - scans_add_write32(scans, 0, csrr(S0, csr[i]), true); - scans_add_read(scans, SLOT0, false); - } - - // Final read to get the last value out. - scans_add_read32(scans, 4, false); - - int retval = scans_execute(scans); - if (retval != ERROR_OK) { - LOG_ERROR("JTAG execute failed: %d", retval); - goto error; - } - - unsigned int dbus_busy = 0; - unsigned int interrupt_set = 0; - unsigned result = 0; - uint64_t value = 0; - reg_cache_set(target, 0, 0); - // The first scan result is the result from something old we don't care - // about. - for (unsigned int i = 1; i < scans->next_scan && dbus_busy == 0; i++) { - dbus_status_t status = scans_get_u32(scans, i, DBUS_OP_START, - DBUS_OP_SIZE); - uint64_t data = scans_get_u64(scans, i, DBUS_DATA_START, DBUS_DATA_SIZE); - uint32_t address = scans_get_u32(scans, i, DBUS_ADDRESS_START, - info->addrbits); - switch (status) { - case DBUS_STATUS_SUCCESS: - break; - case DBUS_STATUS_FAILED: - LOG_ERROR("Debug access failed. Hardware error?"); - goto error; - case DBUS_STATUS_BUSY: - dbus_busy++; - break; - default: - LOG_ERROR("Got invalid bus access status: %d", status); - return ERROR_FAIL; - } - if (data & DMCONTROL_INTERRUPT) { - interrupt_set++; - break; - } - if (address == 4 || address == 5) { - unsigned int reg; - switch (result) { - case 0: reg = 1; break; - case 1: reg = 2; break; - case 2: reg = 3; break; - case 3: reg = 4; break; - case 4: reg = 5; break; - case 5: reg = 6; break; - case 6: reg = 7; break; - // S0 - // S1 - case 7: reg = 10; break; - case 8: reg = 11; break; - case 9: reg = 12; break; - case 10: reg = 13; break; - case 11: reg = 14; break; - case 12: reg = 15; break; - case 13: reg = 16; break; - case 14: reg = 17; break; - case 15: reg = 18; break; - case 16: reg = 19; break; - case 17: reg = 20; break; - case 18: reg = 21; break; - case 19: reg = 22; break; - case 20: reg = 23; break; - case 21: reg = 24; break; - case 22: reg = 25; break; - case 23: reg = 26; break; - case 24: reg = 27; break; - case 25: reg = 28; break; - case 26: reg = 29; break; - case 27: reg = 30; break; - case 28: reg = 31; break; - case 29: reg = S1; break; - case 30: reg = S0; break; - case 31: reg = CSR_DPC; break; - case 32: reg = CSR_DCSR; break; - default: - assert(0); - } - if (riscv_xlen(target) == 32) { - reg_cache_set(target, reg, data & 0xffffffff); - result++; - } else if (riscv_xlen(target) == 64) { - if (address == 4) { - value = data & 0xffffffff; - } else if (address == 5) { - reg_cache_set(target, reg, ((data & 0xffffffff) << 32) | value); - value = 0; - result++; - } - } - } - } - - if (dbus_busy) { - increase_dbus_busy_delay(target); - return RE_AGAIN; - } - if (interrupt_set) { - increase_interrupt_high_delay(target); - return RE_AGAIN; - } - - // TODO: get rid of those 2 variables and talk to the cache directly. - info->dpc = reg_cache_get(target, CSR_DPC); - info->dcsr = reg_cache_get(target, CSR_DCSR); - - scans = scans_delete(scans); - - cache_invalidate(target); - - return RE_OK; - -error: - scans = scans_delete(scans); - return RE_FAIL; -} - -static int handle_halt(struct target *target, bool announce) -{ - riscv011_info_t *info = get_info(target); - target->state = TARGET_HALTED; - - riscv_error_t re; - do { - re = handle_halt_routine(target); - } while (re == RE_AGAIN); - if (re != RE_OK) { - LOG_ERROR("handle_halt_routine failed"); - return ERROR_FAIL; - } - - int cause = get_field(info->dcsr, DCSR_CAUSE); - switch (cause) { - case DCSR_CAUSE_SWBP: - target->debug_reason = DBG_REASON_BREAKPOINT; - break; - case DCSR_CAUSE_HWBP: - target->debug_reason = DBG_REASON_WPTANDBKPT; - // If we halted because of a data trigger, gdb doesn't know to do - // the disable-breakpoints-step-enable-breakpoints dance. - info->need_strict_step = true; - break; - case DCSR_CAUSE_DEBUGINT: - target->debug_reason = DBG_REASON_DBGRQ; - break; - case DCSR_CAUSE_STEP: - target->debug_reason = DBG_REASON_SINGLESTEP; - break; - case DCSR_CAUSE_HALT: - default: - LOG_ERROR("Invalid halt cause %d in DCSR (0x%" PRIx64 ")", - cause, info->dcsr); - } - - if (info->never_halted) { - info->never_halted = false; - - // Disable any hardware triggers that have dmode set. We can't have set - // them ourselves. Maybe they're left over from some killed debug - // session. - // Count the number of triggers while we're at it. - - int result = maybe_read_tselect(target); - if (result != ERROR_OK) - return result; - for (info->trigger_count = 0; info->trigger_count < MAX_HWBPS; info->trigger_count++) { - write_csr(target, CSR_TSELECT, info->trigger_count); - uint64_t tselect_rb; - read_csr(target, &tselect_rb, CSR_TSELECT); - if (info->trigger_count != tselect_rb) - break; - uint64_t tdata1; - read_csr(target, &tdata1, CSR_TDATA1); - if ((tdata1 & MCONTROL_DMODE(riscv_xlen(target))) && - (tdata1 & (MCONTROL_EXECUTE | MCONTROL_STORE | MCONTROL_LOAD))) { - write_csr(target, CSR_TDATA1, 0); - } - } - } - - if (announce) { - target_call_event_callbacks(target, TARGET_EVENT_HALTED); - } - - const char *cause_string[] = { - "none", - "software breakpoint", - "hardware trigger", - "debug interrupt", - "step", - "halt" - }; - // This is logged to the user so that gdb will show it when a user types - // 'monitor reset init'. At that time gdb appears to have the pc cached - // still so if a user manually inspects the pc it will still have the old - // value. - LOG_USER("halted at 0x%" PRIx64 " due to %s", info->dpc, cause_string[cause]); - - return ERROR_OK; -} - -static int poll_target(struct target *target, bool announce) -{ - jtag_add_ir_scan(target->tap, &select_dbus, TAP_IDLE); - - // Inhibit debug logging during poll(), which isn't usually interesting and - // just fills up the screen/logs with clutter. - int old_debug_level = debug_level; - if (debug_level >= LOG_LVL_DEBUG) { - debug_level = LOG_LVL_INFO; - } - bits_t bits = read_bits(target); - debug_level = old_debug_level; - - if (bits.haltnot && bits.interrupt) { - target->state = TARGET_DEBUG_RUNNING; - LOG_DEBUG("debug running"); - } else if (bits.haltnot && !bits.interrupt) { - if (target->state != TARGET_HALTED) { - return handle_halt(target, announce); - } - } else if (!bits.haltnot && bits.interrupt) { - // Target is halting. There is no state for that, so don't change anything. - LOG_DEBUG("halting"); - } else if (!bits.haltnot && !bits.interrupt) { - target->state = TARGET_RUNNING; - } - - return ERROR_OK; -} - -static int riscv011_poll(struct target *target) -{ - return poll_target(target, true); -} - -static int riscv011_resume(struct target *target, int current, uint32_t address, - int handle_breakpoints, int debug_execution) -{ - riscv011_info_t *info = get_info(target); - - jtag_add_ir_scan(target->tap, &select_dbus, TAP_IDLE); - - if (!current) { - if (riscv_xlen(target) > 32) { - LOG_WARNING("Asked to resume at 32-bit PC on %d-bit target.", - riscv_xlen(target)); - } - int result = register_write(target, REG_PC, address); - if (result != ERROR_OK) - return result; - } - - if (info->need_strict_step || handle_breakpoints) { - int result = strict_step(target, false); - if (result != ERROR_OK) - return result; - } - - return resume(target, debug_execution, false); -} - -static int assert_reset(struct target *target) -{ - riscv011_info_t *info = get_info(target); - // TODO: Maybe what I implemented here is more like soft_reset_halt()? - - jtag_add_ir_scan(target->tap, &select_dbus, TAP_IDLE); - - // The only assumption we can make is that the TAP was reset. - if (wait_for_debugint_clear(target, true) != ERROR_OK) { - LOG_ERROR("Debug interrupt didn't clear."); - return ERROR_FAIL; - } - - // Not sure what we should do when there are multiple cores. - // Here just reset the single hart we're talking to. - info->dcsr |= DCSR_EBREAKM | DCSR_EBREAKH | DCSR_EBREAKS | - DCSR_EBREAKU | DCSR_HALT; - if (target->reset_halt) { - info->dcsr |= DCSR_NDRESET; - } else { - info->dcsr |= DCSR_FULLRESET; - } - dram_write32(target, 0, lw(S0, ZERO, DEBUG_RAM_START + 16), false); - dram_write32(target, 1, csrw(S0, CSR_DCSR), false); - // We shouldn't actually need the jump because a reset should happen. - dram_write_jump(target, 2, false); - dram_write32(target, 4, info->dcsr, true); - cache_invalidate(target); - - target->state = TARGET_RESET; - - return ERROR_OK; -} - -static int deassert_reset(struct target *target) -{ - jtag_add_ir_scan(target->tap, &select_dbus, TAP_IDLE); - if (target->reset_halt) { - return wait_for_state(target, TARGET_HALTED); - } else { - return wait_for_state(target, TARGET_RUNNING); - } -} - -static int read_memory(struct target *target, uint32_t address, - uint32_t size, uint32_t count, uint8_t *buffer) -{ - jtag_add_ir_scan(target->tap, &select_dbus, TAP_IDLE); - - cache_set32(target, 0, lw(S0, ZERO, DEBUG_RAM_START + 16)); - switch (size) { - case 1: - cache_set32(target, 1, lb(S1, S0, 0)); - cache_set32(target, 2, sw(S1, ZERO, DEBUG_RAM_START + 16)); - break; - case 2: - cache_set32(target, 1, lh(S1, S0, 0)); - cache_set32(target, 2, sw(S1, ZERO, DEBUG_RAM_START + 16)); - break; - case 4: - cache_set32(target, 1, lw(S1, S0, 0)); - cache_set32(target, 2, sw(S1, ZERO, DEBUG_RAM_START + 16)); - break; - default: - LOG_ERROR("Unsupported size: %d", size); - return ERROR_FAIL; - } - cache_set_jump(target, 3); - cache_write(target, CACHE_NO_READ, false); - - riscv011_info_t *info = get_info(target); - const int max_batch_size = 256; - scans_t *scans = scans_new(target, max_batch_size); - - uint32_t result_value = 0x777; - uint32_t i = 0; - while (i < count + 3) { - unsigned int batch_size = MIN(count + 3 - i, max_batch_size); - scans_reset(scans); - - for (unsigned int j = 0; j < batch_size; j++) { - if (i + j == count) { - // Just insert a read so we can scan out the last value. - scans_add_read32(scans, 4, false); - } else if (i + j >= count + 1) { - // And check for errors. - scans_add_read32(scans, info->dramsize-1, false); - } else { - // Write the next address and set interrupt. - uint32_t offset = size * (i + j); - scans_add_write32(scans, 4, address + offset, true); - } - } - - int retval = scans_execute(scans); - if (retval != ERROR_OK) { - LOG_ERROR("JTAG execute failed: %d", retval); - goto error; - } - - int dbus_busy = 0; - int execute_busy = 0; - for (unsigned int j = 0; j < batch_size; j++) { - dbus_status_t status = scans_get_u32(scans, j, DBUS_OP_START, - DBUS_OP_SIZE); - switch (status) { - case DBUS_STATUS_SUCCESS: - break; - case DBUS_STATUS_FAILED: - LOG_ERROR("Debug RAM write failed. Hardware error?"); - goto error; - case DBUS_STATUS_BUSY: - dbus_busy++; - break; - default: - LOG_ERROR("Got invalid bus access status: %d", status); - return ERROR_FAIL; - } - uint64_t data = scans_get_u64(scans, j, DBUS_DATA_START, - DBUS_DATA_SIZE); - if (data & DMCONTROL_INTERRUPT) { - execute_busy++; - } - if (i + j == count + 2) { - result_value = data; - } else if (i + j > 1) { - uint32_t offset = size * (i + j - 2); - switch (size) { - case 1: - buffer[offset] = data; - break; - case 2: - buffer[offset] = data; - buffer[offset+1] = data >> 8; - break; - case 4: - buffer[offset] = data; - buffer[offset+1] = data >> 8; - buffer[offset+2] = data >> 16; - buffer[offset+3] = data >> 24; - break; - } - } - LOG_DEBUG("j=%d status=%d data=%09" PRIx64, j, status, data); - } - if (dbus_busy) { - increase_dbus_busy_delay(target); - } - if (execute_busy) { - increase_interrupt_high_delay(target); - } - if (dbus_busy || execute_busy) { - wait_for_debugint_clear(target, false); - - // Retry. - LOG_INFO("Retrying memory read starting from 0x%x with more delays", - address + size * i); - } else { - i += batch_size; - } - } - - if (result_value != 0) { - LOG_USER("Core got an exception (0x%x) while reading from 0x%x", - result_value, address + size * (count-1)); - if (count > 1) { - LOG_USER("(It may have failed between 0x%x and 0x%x as well, but we " - "didn't check then.)", - address, address + size * (count-2) + size - 1); - } - goto error; - } - - scans_delete(scans); - cache_clean(target); - return ERROR_OK; - -error: - scans_delete(scans); - cache_clean(target); - return ERROR_FAIL; -} - -static int setup_write_memory(struct target *target, uint32_t size) -{ - switch (size) { - case 1: - cache_set32(target, 0, lb(S0, ZERO, DEBUG_RAM_START + 16)); - cache_set32(target, 1, sb(S0, T0, 0)); - break; - case 2: - cache_set32(target, 0, lh(S0, ZERO, DEBUG_RAM_START + 16)); - cache_set32(target, 1, sh(S0, T0, 0)); - break; - case 4: - cache_set32(target, 0, lw(S0, ZERO, DEBUG_RAM_START + 16)); - cache_set32(target, 1, sw(S0, T0, 0)); - break; - default: - LOG_ERROR("Unsupported size: %d", size); - return ERROR_FAIL; - } - cache_set32(target, 2, addi(T0, T0, size)); - cache_set_jump(target, 3); - cache_write(target, 4, false); - - return ERROR_OK; -} - -static int write_memory(struct target *target, uint32_t address, - uint32_t size, uint32_t count, const uint8_t *buffer) -{ - riscv011_info_t *info = get_info(target); - jtag_add_ir_scan(target->tap, &select_dbus, TAP_IDLE); - - // Set up the address. - cache_set_store(target, 0, T0, SLOT1); - cache_set_load(target, 1, T0, SLOT0); - cache_set_jump(target, 2); - cache_set(target, SLOT0, address); - if (cache_write(target, 5, true) != ERROR_OK) { - return ERROR_FAIL; - } - - uint64_t t0 = cache_get(target, SLOT1); - LOG_DEBUG("t0 is 0x%" PRIx64, t0); - - if (setup_write_memory(target, size) != ERROR_OK) { - return ERROR_FAIL; - } - - const int max_batch_size = 256; - scans_t *scans = scans_new(target, max_batch_size); - - uint32_t result_value = 0x777; - uint32_t i = 0; - while (i < count + 2) { - unsigned int batch_size = MIN(count + 2 - i, max_batch_size); - scans_reset(scans); - - for (unsigned int j = 0; j < batch_size; j++) { - if (i + j >= count) { - // Check for an exception. - scans_add_read32(scans, info->dramsize-1, false); - } else { - // Write the next value and set interrupt. - uint32_t value; - uint32_t offset = size * (i + j); - switch (size) { - case 1: - value = buffer[offset]; - break; - case 2: - value = buffer[offset] | - (buffer[offset+1] << 8); - break; - case 4: - value = buffer[offset] | - ((uint32_t) buffer[offset+1] << 8) | - ((uint32_t) buffer[offset+2] << 16) | - ((uint32_t) buffer[offset+3] << 24); - break; - default: - goto error; - } - - scans_add_write32(scans, 4, value, true); - } - } - - int retval = scans_execute(scans); - if (retval != ERROR_OK) { - LOG_ERROR("JTAG execute failed: %d", retval); - goto error; - } - - int dbus_busy = 0; - int execute_busy = 0; - for (unsigned int j = 0; j < batch_size; j++) { - dbus_status_t status = scans_get_u32(scans, j, DBUS_OP_START, - DBUS_OP_SIZE); - switch (status) { - case DBUS_STATUS_SUCCESS: - break; - case DBUS_STATUS_FAILED: - LOG_ERROR("Debug RAM write failed. Hardware error?"); - goto error; - case DBUS_STATUS_BUSY: - dbus_busy++; - break; - default: - LOG_ERROR("Got invalid bus access status: %d", status); - return ERROR_FAIL; - } - int interrupt = scans_get_u32(scans, j, DBUS_DATA_START + 33, 1); - if (interrupt) { - execute_busy++; - } - if (i + j == count + 1) { - result_value = scans_get_u32(scans, j, DBUS_DATA_START, 32); - } - } - if (dbus_busy) { - increase_dbus_busy_delay(target); - } - if (execute_busy) { - increase_interrupt_high_delay(target); - } - if (dbus_busy || execute_busy) { - wait_for_debugint_clear(target, false); - - // Retry. - // Set t0 back to what it should have been at the beginning of this - // batch. - LOG_INFO("Retrying memory write starting from 0x%x with more delays", - address + size * i); - - cache_clean(target); - - if (write_gpr(target, T0, address + size * i) != ERROR_OK) { - goto error; - } - - if (setup_write_memory(target, size) != ERROR_OK) { - goto error; - } - } else { - i += batch_size; - } - } - - if (result_value != 0) { - LOG_ERROR("Core got an exception (0x%x) while writing to 0x%x", - result_value, address + size * (count-1)); - if (count > 1) { - LOG_ERROR("(It may have failed between 0x%x and 0x%x as well, but we " - "didn't check then.)", - address, address + size * (count-2) + size - 1); - } - goto error; - } - - cache_clean(target); - return register_write(target, T0, t0); - -error: - scans_delete(scans); - cache_clean(target); - return ERROR_FAIL; -} - -static int arch_state(struct target *target) -{ - return ERROR_OK; -} - -struct target_type riscv011_target = -{ - .name = "riscv", - - .init_target = init_target, - .deinit_target = deinit_target, - .examine = examine, - - /* poll current target status */ - .poll = riscv011_poll, - - .halt = halt, - .resume = riscv011_resume, - .step = step, - - .assert_reset = assert_reset, - .deassert_reset = deassert_reset, - - .read_memory = read_memory, - .write_memory = write_memory, - - .add_breakpoint = add_breakpoint, - .remove_breakpoint = remove_breakpoint, - - .add_watchpoint = add_watchpoint, - .remove_watchpoint = remove_watchpoint, - - .arch_state = arch_state, -}; diff --git a/src/target/riscv/riscv-013.c b/src/target/riscv/riscv-013.c deleted file mode 100644 index 2eb28bf47..000000000 --- a/src/target/riscv/riscv-013.c +++ /dev/null @@ -1,1634 +0,0 @@ -/* - * Support for RISC-V, debug version 0.13, which is currently (2/4/17) the - * latest draft. - */ - -#include -#include -#include - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "target.h" -#include "target/algorithm.h" -#include "target_type.h" -#include "log.h" -#include "jtag/jtag.h" -#include "register.h" -#include "breakpoints.h" -#include "helper/time_support.h" -#include "riscv.h" -#include "debug_defines.h" -#include "rtos/rtos.h" - -static void riscv013_on_step_or_resume(struct target *target, bool step); -static void riscv013_step_or_resume_current_hart(struct target *target, bool step); - -/* Implementations of the functions in riscv_info_t. */ -static riscv_reg_t riscv013_get_register(struct target *target, int hartid, int regid); -static void riscv013_set_register(struct target *target, int hartid, int regid, uint64_t value); -static void riscv013_select_current_hart(struct target *target); -static void riscv013_halt_current_hart(struct target *target); -static void riscv013_resume_current_hart(struct target *target); -static void riscv013_step_current_hart(struct target *target); -static void riscv013_on_halt(struct target *target); -static void riscv013_on_step(struct target *target); -static void riscv013_on_resume(struct target *target); -static bool riscv013_is_halted(struct target *target); -static enum riscv_halt_reason riscv013_halt_reason(struct target *target); - -/** - * Since almost everything can be accomplish by scanning the dbus register, all - * functions here assume dbus is already selected. The exception are functions - * called directly by OpenOCD, which can't assume anything about what's - * currently in IR. They should set IR to dbus explicitly. - */ - -#define get_field(reg, mask) (((reg) & (mask)) / ((mask) & ~((mask) << 1))) -#define set_field(reg, mask, val) (((reg) & ~(mask)) | (((val) * ((mask) & ~((mask) << 1))) & (mask))) - -#define DIM(x) (sizeof(x)/sizeof(*x)) - -#define CSR_DCSR_CAUSE_SWBP 1 -#define CSR_DCSR_CAUSE_TRIGGER 2 -#define CSR_DCSR_CAUSE_DEBUGINT 3 -#define CSR_DCSR_CAUSE_STEP 4 -#define CSR_DCSR_CAUSE_HALT 5 - -/*** JTAG registers. ***/ - -typedef enum { - DMI_OP_NOP = 0, - DMI_OP_READ = 1, - DMI_OP_WRITE = 2 -} dmi_op_t; -typedef enum { - DMI_STATUS_SUCCESS = 0, - DMI_STATUS_FAILED = 2, - DMI_STATUS_BUSY = 3 -} dmi_status_t; - -typedef enum { - RE_OK, - RE_FAIL, - RE_AGAIN -} riscv_error_t; - -typedef enum slot { - SLOT0, - SLOT1, - SLOT_LAST, -} slot_t; - -/*** Debug Bus registers. ***/ - -#define CMDERR_NONE 0 -#define CMDERR_BUSY 1 -#define CMDERR_NOT_SUPPORTED 2 -#define CMDERR_EXCEPTION 3 -#define CMDERR_HALT_RESUME 4 -#define CMDERR_OTHER 7 - -/*** Info about the core being debugged. ***/ - -#define WALL_CLOCK_TIMEOUT 2 - -#define MAX_HWBPS 16 - -struct trigger { - uint64_t address; - uint32_t length; - uint64_t mask; - uint64_t value; - bool read, write, execute; - int unique_id; -}; - -struct memory_cache_line { - uint32_t data; - bool valid; - bool dirty; -}; - -typedef struct { - /* Number of address bits in the dbus register. */ - unsigned abits; - /* Number of abstract command data registers. */ - unsigned datacount; - /* Number of words in the Program Buffer. */ - unsigned progsize; - /* Number of Program Buffer registers. */ - /* Number of words in Debug RAM. */ - uint64_t misa; - uint64_t tselect; - bool tselect_dirty; - /* The value that mstatus actually has on the target right now. This is not - * the value we present to the user. That one may be stored in the - * reg_cache. */ - uint64_t mstatus_actual; - - /* Single buffer that contains all register names, instead of calling - * malloc for each register. Needs to be freed when reg_list is freed. */ - char *reg_names; - /* Single buffer that contains all register values. */ - void *reg_values; - - // For each physical trigger, contains -1 if the hwbp is available, or the - // unique_id of the breakpoint/watchpoint that is using it. - int trigger_unique_id[MAX_HWBPS]; - - unsigned int trigger_count; - - // Number of run-test/idle cycles the target requests we do after each dbus - // access. - unsigned int dtmcontrol_idle; - - // This value is incremented every time a dbus access comes back as "busy". - // It's used to determine how many run-test/idle cycles to feed the target - // in between accesses. - unsigned int dmi_busy_delay; - - // This value is increased every time we tried to execute two commands - // consecutively, and the second one failed because the previous hadn't - // completed yet. It's used to add extra run-test/idle cycles after - // starting a command, so we don't have to waste time checking for busy to - // go low. - unsigned int ac_busy_delay; - - bool need_strict_step; -} riscv013_info_t; - -static void dump_field(const struct scan_field *field) -{ - static const char *op_string[] = {"-", "r", "w", "?"}; - static const char *status_string[] = {"+", "?", "F", "b"}; - - if (debug_level < LOG_LVL_DEBUG) - return; - - uint64_t out = buf_get_u64(field->out_value, 0, field->num_bits); - unsigned int out_op = get_field(out, DTM_DMI_OP); - unsigned int out_data = get_field(out, DTM_DMI_DATA); - unsigned int out_address = out >> DTM_DMI_ADDRESS_OFFSET; - - if (field->in_value) { - uint64_t in = buf_get_u64(field->in_value, 0, field->num_bits); - unsigned int in_op = get_field(in, DTM_DMI_OP); - unsigned int in_data = get_field(in, DTM_DMI_DATA); - unsigned int in_address = in >> DTM_DMI_ADDRESS_OFFSET; - - log_printf_lf(LOG_LVL_DEBUG, - __FILE__, __LINE__, "scan", - "%db %s %08x @%02x -> %s %08x @%02x", - field->num_bits, - op_string[out_op], out_data, out_address, - status_string[in_op], in_data, in_address); - } else { - log_printf_lf(LOG_LVL_DEBUG, - __FILE__, __LINE__, "scan", "%db %s %08x @%02x -> ?", - field->num_bits, op_string[out_op], out_data, out_address); - } -} - -static riscv013_info_t *get_info(const struct target *target) -{ - riscv_info_t *info = (riscv_info_t *) target->arch_info; - return (riscv013_info_t *) info->version_specific; -} - -/*** Necessary prototypes. ***/ - -static int register_get(struct reg *reg); - -/*** Utility functions. ***/ - -bool supports_extension(struct target *target, char letter) -{ - riscv013_info_t *info = get_info(target); - unsigned num; - if (letter >= 'a' && letter <= 'z') { - num = letter - 'a'; - } else if (letter >= 'A' && letter <= 'Z') { - num = letter - 'A'; - } else { - return false; - } - return info->misa & (1 << num); -} - -static void select_dmi(struct target *target) -{ - static uint8_t ir_dmi[1] = {DTM_DMI}; - struct scan_field field = { - .num_bits = target->tap->ir_length, - .out_value = ir_dmi, - .in_value = NULL, - .check_value = NULL, - .check_mask = NULL - }; - - jtag_add_ir_scan(target->tap, &field, TAP_IDLE); -} - -static uint32_t dtmcontrol_scan(struct target *target, uint32_t out) -{ - struct scan_field field; - uint8_t in_value[4]; - uint8_t out_value[4]; - - buf_set_u32(out_value, 0, 32, out); - - jtag_add_ir_scan(target->tap, &select_dtmcontrol, TAP_IDLE); - - field.num_bits = 32; - field.out_value = out_value; - field.in_value = in_value; - jtag_add_dr_scan(target->tap, 1, &field, TAP_IDLE); - - /* Always return to dmi. */ - select_dmi(target); - - int retval = jtag_execute_queue(); - if (retval != ERROR_OK) { - LOG_ERROR("failed jtag scan: %d", retval); - return retval; - } - - uint32_t in = buf_get_u32(field.in_value, 0, 32); - LOG_DEBUG("DTMCS: 0x%x -> 0x%x", out, in); - - return in; -} - -static void increase_dmi_busy_delay(struct target *target) -{ - riscv013_info_t *info = get_info(target); - info->dmi_busy_delay += info->dmi_busy_delay / 10 + 1; - LOG_INFO("dtmcontrol_idle=%d, dmi_busy_delay=%d, ac_busy_delay=%d", - info->dtmcontrol_idle, info->dmi_busy_delay, - info->ac_busy_delay); - - dtmcontrol_scan(target, DTM_DTMCS_DMIRESET); -} - -/** - * exec: If this is set, assume the scan results in an execution, so more - * run-test/idle cycles may be required. - */ -static dmi_status_t dmi_scan(struct target *target, uint16_t *address_in, - uint64_t *data_in, dmi_op_t op, uint16_t address_out, uint64_t data_out, - bool exec) -{ - riscv013_info_t *info = get_info(target); - uint8_t in[8] = {0}; - uint8_t out[8]; - struct scan_field field = { - .num_bits = info->abits + DTM_DMI_OP_LENGTH + DTM_DMI_DATA_LENGTH, - .out_value = out, - }; - - if (address_in || data_in) { - field.in_value = in; - } - - assert(info->abits != 0); - - buf_set_u64(out, DTM_DMI_OP_OFFSET, DTM_DMI_OP_LENGTH, op); - buf_set_u64(out, DTM_DMI_DATA_OFFSET, DTM_DMI_DATA_LENGTH, data_out); - buf_set_u64(out, DTM_DMI_ADDRESS_OFFSET, info->abits, address_out); - - /* Assume dbus is already selected. */ - jtag_add_dr_scan(target->tap, 1, &field, TAP_IDLE); - - int idle_count = info->dtmcontrol_idle + info->dmi_busy_delay; - if (exec) - idle_count += info->ac_busy_delay; - - if (idle_count) { - jtag_add_runtest(idle_count, TAP_IDLE); - } - - int retval = jtag_execute_queue(); - if (retval != ERROR_OK) { - LOG_ERROR("dmi_scan failed jtag scan"); - return DMI_STATUS_FAILED; - } - - if (data_in) { - *data_in = buf_get_u64(in, DTM_DMI_DATA_OFFSET, DTM_DMI_DATA_LENGTH); - } - - if (address_in) { - *address_in = buf_get_u32(in, DTM_DMI_ADDRESS_OFFSET, info->abits); - } - - dump_field(&field); - - return buf_get_u32(in, DTM_DMI_OP_OFFSET, DTM_DMI_OP_LENGTH); -} - -static uint64_t dmi_read(struct target *target, uint16_t address) -{ - select_dmi(target); - - uint64_t value; - dmi_status_t status; - uint16_t address_in; - - unsigned i = 0; - for (i = 0; i < 256; i++) { - status = dmi_scan(target, NULL, NULL, DMI_OP_READ, address, 0, - false); - if (status == DMI_STATUS_BUSY) { - increase_dmi_busy_delay(target); - } else { - break; - } - } - - status = dmi_scan(target, &address_in, &value, DMI_OP_NOP, address, 0, - false); - - if (status != DMI_STATUS_SUCCESS) { - LOG_ERROR("failed read from 0x%x; value=0x%" PRIx64 ", status=%d\n", - address, value, status); - } - - return value; -} - -static void dmi_write(struct target *target, uint16_t address, uint64_t value) -{ - select_dmi(target); - dmi_status_t status = DMI_STATUS_BUSY; - unsigned i = 0; - while (status == DMI_STATUS_BUSY && i++ < 256) { - dmi_scan(target, NULL, NULL, DMI_OP_WRITE, address, value, - address == DMI_COMMAND); - status = dmi_scan(target, NULL, NULL, DMI_OP_NOP, 0, 0, false); - if (status == DMI_STATUS_BUSY) { - increase_dmi_busy_delay(target); - } - } - if (status != DMI_STATUS_SUCCESS) { - LOG_ERROR("failed to write 0x%" PRIx64 " to 0x%x; status=%d\n", value, address, status); - } -} - -/** Convert register number (internal OpenOCD number) to the number expected by - * the abstract command interface. */ -static unsigned reg_number_to_no(unsigned reg_num) -{ - if (reg_num <= GDB_REGNO_XPR31) { - return reg_num + 0x1000 - GDB_REGNO_XPR0; - } else if (reg_num >= GDB_REGNO_CSR0 && reg_num <= GDB_REGNO_CSR4095) { - return reg_num - GDB_REGNO_CSR0; - } else if (reg_num >= GDB_REGNO_FPR0 && reg_num <= GDB_REGNO_FPR31) { - return reg_num + 0x1020 - GDB_REGNO_FPR0; - } else { - return ~0; - } -} - -uint32_t abstract_register_size(unsigned width) -{ - switch (width) { - case 32: - return set_field(0, AC_ACCESS_REGISTER_SIZE, 2); - case 64: - return set_field(0, AC_ACCESS_REGISTER_SIZE, 3); - break; - case 128: - return set_field(0, AC_ACCESS_REGISTER_SIZE, 4); - break; - default: - LOG_ERROR("Unsupported register width: %d", width); - return 0; - } -} - -static int wait_for_idle(struct target *target, uint32_t *abstractcs) -{ - time_t start = time(NULL); - while (1) { - *abstractcs = dmi_read(target, DMI_ABSTRACTCS); - - if (get_field(*abstractcs, DMI_ABSTRACTCS_BUSY) == 0) { - return ERROR_OK; - } - - if (time(NULL) - start > WALL_CLOCK_TIMEOUT) { - if (get_field(*abstractcs, DMI_ABSTRACTCS_CMDERR) != CMDERR_NONE) { - const char *errors[8] = { - "none", - "busy", - "not supported", - "exception", - "halt/resume", - "reserved", - "reserved", - "other" }; - - LOG_ERROR("Abstract command ended in error '%s' (abstractcs=0x%x)", - errors[get_field(*abstractcs, DMI_ABSTRACTCS_CMDERR)], - *abstractcs); - } - - LOG_ERROR("Timed out waiting for busy to go low. (abstractcs=0x%x)", - *abstractcs); - return ERROR_FAIL; - } - } -} - -static int execute_abstract_command(struct target *target, uint32_t command) -{ - dmi_write(target, DMI_COMMAND, command); - - uint32_t abstractcs; - if (wait_for_idle(target, &abstractcs) != ERROR_OK) - return ERROR_FAIL; - - if (get_field(abstractcs, DMI_ABSTRACTCS_CMDERR) != CMDERR_NONE) { - const char *errors[8] = { - "none", - "busy", - "not supported", - "exception", - "halt/resume", - "reserved", - "reserved", - "other" }; - LOG_DEBUG("Abstract command 0x%x ended in error '%s' (abstractcs=0x%x)", - command, errors[get_field(abstractcs, DMI_ABSTRACTCS_CMDERR)], - abstractcs); - // Clear the error. - dmi_write(target, DMI_ABSTRACTCS, DMI_ABSTRACTCS_CMDERR); - return ERROR_FAIL; - } - - return ERROR_OK; -} - -/*** program "class" ***/ -/* This class allows a debug program to be built up piecemeal, and then be - * executed. If necessary, the program is split up to fit in the program - * buffer. */ - -typedef struct { - uint8_t code[12 * 4]; - unsigned length; - bool write; - unsigned regno; - uint64_t write_value; -} program_t; - -static void program_add32(program_t *program, uint32_t instruction); - -static program_t *program_new(void) -{ - program_t *program = malloc(sizeof(program_t)); - if (program) { - program->length = 0; - // Default to read zero. - program->write = false; - program->regno = 0x1000; - } - program_add32(program, fence_i()); - return program; -} - -static void program_delete(program_t *program) -{ - free(program); -} - -static void program_add32(program_t *program, uint32_t instruction) -{ - assert(program->length + 4 < sizeof(program->code)); - program->code[program->length++] = instruction & 0xff; - program->code[program->length++] = (instruction >> 8) & 0xff; - program->code[program->length++] = (instruction >> 16) & 0xff; - program->code[program->length++] = (instruction >> 24) & 0xff; -} - -static void program_set_read(program_t *program, unsigned reg_num) -{ - program->write = false; - program->regno = reg_number_to_no(reg_num); -} - -static void program_set_write(program_t *program, unsigned reg_num, uint64_t value) -{ - program->write = true; - program->regno = reg_number_to_no(reg_num); - program->write_value = value; -} - -/*** end of program class ***/ - -static void write_program(struct target *target, const program_t *program) -{ - riscv013_info_t *info = get_info(target); - - assert(program->length <= info->progsize * 4); - for (unsigned i = 0; i < program->length; i += 4) { - uint32_t value = - program->code[i] | - ((uint32_t) program->code[i+1] << 8) | - ((uint32_t) program->code[i+2] << 16) | - ((uint32_t) program->code[i+3] << 24); - dmi_write(target, DMI_PROGBUF0 + i / 4, value); - } -} - -static int execute_program(struct target *target, const program_t *program) -{ - write_program(target, program); - - uint32_t command = 0; - if (program->write) { - if (get_field(command, AC_ACCESS_REGISTER_SIZE) > 2) { - dmi_write(target, DMI_DATA1, program->write_value >> 32); - } - dmi_write(target, DMI_DATA0, program->write_value); - command |= AC_ACCESS_REGISTER_WRITE | AC_ACCESS_REGISTER_POSTEXEC; - } else { - command |= AC_ACCESS_REGISTER_PREEXEC; - } - command |= abstract_register_size(riscv_xlen(target)); - command |= program->regno; - - return execute_abstract_command(target, command); -} - -static int abstract_read_register(struct target *target, - uint64_t *value, - uint32_t reg_number, - unsigned width) -{ - uint32_t command = abstract_register_size(width); - - command |= reg_number_to_no(reg_number); - - int result = execute_abstract_command(target, command); - if (result != ERROR_OK) { - return result; - } - - if (value) { - *value = 0; - switch (width) { - case 128: - LOG_ERROR("Ignoring top 64 bits from 128-bit register read."); - case 64: - *value |= ((uint64_t) dmi_read(target, DMI_DATA1)) << 32; - case 32: - *value |= dmi_read(target, DMI_DATA0); - break; - } - } - - return ERROR_OK; -} - -static int abstract_write_register(struct target *target, - unsigned reg_number, - unsigned width, - uint64_t value) -{ - uint32_t command = abstract_register_size(width); - - command |= reg_number_to_no(reg_number); - command |= AC_ACCESS_REGISTER_WRITE; - - switch (width) { - case 128: - LOG_ERROR("Ignoring top 64 bits from 128-bit register write."); - case 64: - dmi_write(target, DMI_DATA1, value >> 32); - case 32: - dmi_write(target, DMI_DATA0, value); - break; - } - - int result = execute_abstract_command(target, command); - if (result != ERROR_OK) { - return result; - } - - return ERROR_OK; -} - -static int update_mstatus_actual(struct target *target) -{ - struct reg *mstatus_reg = &target->reg_cache->reg_list[GDB_REGNO_MSTATUS]; - if (mstatus_reg->valid) { - // We previously made it valid. - return ERROR_OK; - } - - LOG_DEBUG("Reading mstatus"); - - // Force reading the register. In that process mstatus_actual will be - // updated. - return register_get(&target->reg_cache->reg_list[GDB_REGNO_MSTATUS]); -} - -static int register_write_direct(struct target *target, unsigned number, - uint64_t value) -{ - riscv013_info_t *info = get_info(target); - LOG_DEBUG("register 0x%x <- 0x%" PRIx64, number, value); - - if (number == GDB_REGNO_MSTATUS) { - info->mstatus_actual = value; - } - - int result = abstract_write_register(target, number, riscv_xlen(target), value); - if (result == ERROR_OK) - return result; - - // Fall back to program buffer. - if (number >= GDB_REGNO_FPR0 && number <= GDB_REGNO_FPR31) { - result = update_mstatus_actual(target); - if (result != ERROR_OK) { - return result; - } - if ((info->mstatus_actual & MSTATUS_FS) == 0) { - result = register_write_direct(target, GDB_REGNO_MSTATUS, - set_field(info->mstatus_actual, MSTATUS_FS, 1)); - if (result != ERROR_OK) - return result; - } - - program_t *program = program_new(); - // TODO: Fully support D extension on RV32. - if (supports_extension(target, 'D') && riscv_xlen(target) >= 64) { - program_add32(program, fmv_d_x(number - GDB_REGNO_FPR0, S0)); - } else { - program_add32(program, fmv_s_x(number - GDB_REGNO_FPR0, S0)); - } - program_add32(program, ebreak()); - program_set_write(program, S0, value); - result = execute_program(target, program); - program_delete(program); - } else if (number >= GDB_REGNO_CSR0 && number <= GDB_REGNO_CSR4095) { - program_t *program = program_new(); - program_add32(program, csrw(S0, number - GDB_REGNO_CSR0)); - program_add32(program, ebreak()); - program_set_write(program, S0, value); - result = execute_program(target, program); - program_delete(program); - } else { - return result; - } - - return result; -} - -/** Actually read registers from the target right now. */ -static int register_read_direct(struct target *target, uint64_t *value, uint32_t number) -{ - riscv013_info_t *info = get_info(target); - int result = abstract_read_register(target, value, number, riscv_xlen(target)); - if (result == ERROR_OK) - return result; - - // Fall back to program buffer. - if (number >= GDB_REGNO_FPR0 && number <= GDB_REGNO_FPR31) { - result = update_mstatus_actual(target); - if (result != ERROR_OK) { - return result; - } - if ((info->mstatus_actual & MSTATUS_FS) == 0) { - result = register_write_direct(target, GDB_REGNO_MSTATUS, - set_field(info->mstatus_actual, MSTATUS_FS, 1)); - if (result != ERROR_OK) - return result; - } - LOG_DEBUG("mstatus_actual=0x%lx", info->mstatus_actual); - - program_t *program = program_new(); - if (supports_extension(target, 'D') && riscv_xlen(target) >= 64) { - program_add32(program, fmv_x_d(S0, number - GDB_REGNO_FPR0)); - } else { - program_add32(program, fmv_x_s(S0, number - GDB_REGNO_FPR0)); - } - program_add32(program, ebreak()); - program_set_read(program, S0); - result = execute_program(target, program); - program_delete(program); - } else if (number >= GDB_REGNO_CSR0 && number <= GDB_REGNO_CSR4095) { - program_t *program = program_new(); - program_add32(program, csrr(S0, number - GDB_REGNO_CSR0)); - program_add32(program, ebreak()); - program_set_read(program, S0); - result = execute_program(target, program); - program_delete(program); - } else { - return result; - } - - if (result != ERROR_OK) - return result; - - result = register_read_direct(target, value, S0); - if (result != ERROR_OK) - return result; - - LOG_DEBUG("register 0x%x = 0x%" PRIx64, number, *value); - - return ERROR_OK; -} - -static int maybe_read_tselect(struct target *target) -{ - riscv013_info_t *info = get_info(target); - - if (info->tselect_dirty) { - int result = register_read_direct(target, &info->tselect, GDB_REGNO_TSELECT); - if (result != ERROR_OK) - return result; - info->tselect_dirty = false; - } - - return ERROR_OK; -} - -static int maybe_write_tselect(struct target *target) -{ - riscv013_info_t *info = get_info(target); - - if (!info->tselect_dirty) { - int result = register_write_direct(target, GDB_REGNO_TSELECT, info->tselect); - if (result != ERROR_OK) - return result; - info->tselect_dirty = true; - } - - return ERROR_OK; -} - -/*** OpenOCD target functions. ***/ - -static int register_get(struct reg *reg) -{ - struct target *target = (struct target *) reg->arch_info; - riscv013_info_t *info = get_info(target); - - maybe_write_tselect(target); - - if (reg->number <= GDB_REGNO_XPR31) { - register_read_direct(target, reg->value, reg->number); - return ERROR_OK; - } else if (reg->number == GDB_REGNO_PC) { - buf_set_u32(reg->value, 0, 32, riscv_peek_register(target, GDB_REGNO_DPC)); - reg->valid = true; - return ERROR_OK; - } else if (reg->number == GDB_REGNO_PRIV) { - uint64_t dcsr = riscv_peek_register(target, CSR_DCSR); - buf_set_u64(reg->value, 0, 8, get_field(dcsr, CSR_DCSR_PRV)); - riscv_overwrite_register(target, CSR_DCSR, dcsr); - return ERROR_OK; - } else { - uint64_t value; - int result = register_read_direct(target, &value, reg->number); - if (result != ERROR_OK) { - return result; - } - LOG_DEBUG("%s=0x%" PRIx64, reg->name, value); - buf_set_u64(reg->value, 0, riscv_xlen(target), value); - - if (reg->number == GDB_REGNO_MSTATUS) { - info->mstatus_actual = value; - reg->valid = true; - } - } - - return ERROR_OK; -} - -static int register_write(struct target *target, unsigned int number, - uint64_t value) -{ - maybe_write_tselect(target); - - if (number == GDB_REGNO_PC) { - riscv_overwrite_register(target, GDB_REGNO_DPC, value); - } else if (number == GDB_REGNO_PRIV) { - uint64_t dcsr = riscv_peek_register(target, CSR_DCSR); - dcsr = set_field(dcsr, CSR_DCSR_PRV, value); - riscv_overwrite_register(target, GDB_REGNO_DCSR, dcsr); - } else { - return register_write_direct(target, number, value); - } - - return ERROR_OK; -} - -static int register_set(struct reg *reg, uint8_t *buf) -{ - struct target *target = (struct target *) reg->arch_info; - - uint64_t value = buf_get_u64(buf, 0, riscv_xlen(target)); - - LOG_DEBUG("write 0x%" PRIx64 " to %s", value, reg->name); - struct reg *r = &target->reg_cache->reg_list[reg->number]; - r->valid = true; - memcpy(r->value, buf, (r->size + 7) / 8); - - return register_write(target, reg->number, value); -} - -static struct reg_arch_type riscv_reg_arch_type = { - .get = register_get, - .set = register_set -}; - -static int init_target(struct command_context *cmd_ctx, - struct target *target) -{ - LOG_DEBUG("init"); - riscv_info_t *generic_info = (riscv_info_t *) target->arch_info; - - riscv_info_init(generic_info); - generic_info->get_register = &riscv013_get_register; - generic_info->set_register = &riscv013_set_register; - generic_info->select_current_hart = &riscv013_select_current_hart; - generic_info->is_halted = &riscv013_is_halted; - generic_info->halt_current_hart = &riscv013_halt_current_hart; - generic_info->resume_current_hart = &riscv013_resume_current_hart; - generic_info->step_current_hart = &riscv013_step_current_hart; - generic_info->on_halt = &riscv013_on_halt; - generic_info->on_resume = &riscv013_on_resume; - generic_info->on_step = &riscv013_on_step; - generic_info->halt_reason = &riscv013_halt_reason; - - generic_info->version_specific = calloc(1, sizeof(riscv013_info_t)); - if (!generic_info->version_specific) - return ERROR_FAIL; - riscv013_info_t *info = get_info(target); - - target->reg_cache = calloc(1, sizeof(*target->reg_cache)); - target->reg_cache->name = "RISC-V registers"; - target->reg_cache->num_regs = GDB_REGNO_COUNT; - - target->reg_cache->reg_list = calloc(GDB_REGNO_COUNT, sizeof(struct reg)); - - const unsigned int max_reg_name_len = 12; - info->reg_names = calloc(1, GDB_REGNO_COUNT * max_reg_name_len); - char *reg_name = info->reg_names; - info->reg_values = NULL; - - for (unsigned int i = 0; i < GDB_REGNO_COUNT; i++) { - struct reg *r = &target->reg_cache->reg_list[i]; - r->number = i; - r->caller_save = true; - r->dirty = false; - r->valid = false; - r->exist = true; - r->type = &riscv_reg_arch_type; - r->arch_info = target; - if (i <= GDB_REGNO_XPR31) { - sprintf(reg_name, "x%d", i); - } else if (i == GDB_REGNO_PC) { - sprintf(reg_name, "pc"); - } else if (i >= GDB_REGNO_FPR0 && i <= GDB_REGNO_FPR31) { - sprintf(reg_name, "f%d", i - GDB_REGNO_FPR0); - } else if (i >= GDB_REGNO_CSR0 && i <= GDB_REGNO_CSR4095) { - sprintf(reg_name, "csr%d", i - GDB_REGNO_CSR0); - } else if (i == GDB_REGNO_PRIV) { - sprintf(reg_name, "priv"); - } - if (reg_name[0]) { - r->name = reg_name; - } - reg_name += strlen(reg_name) + 1; - assert(reg_name < info->reg_names + GDB_REGNO_COUNT * max_reg_name_len); - } -#if 0 - update_reg_list(target); -#endif - - memset(info->trigger_unique_id, 0xff, sizeof(info->trigger_unique_id)); - - return ERROR_OK; -} - -static void deinit_target(struct target *target) -{ - LOG_DEBUG("riscv_deinit_target()"); - riscv_info_t *info = (riscv_info_t *) target->arch_info; - free(info->version_specific); - info->version_specific = NULL; -} - -static int add_trigger(struct target *target, struct trigger *trigger) -{ - riscv013_info_t *info = get_info(target); - - maybe_read_tselect(target); - - unsigned int i; - for (i = 0; i < info->trigger_count; i++) { - if (info->trigger_unique_id[i] != -1) { - continue; - } - - register_write_direct(target, GDB_REGNO_TSELECT, i); - - uint64_t tdata1; - register_read_direct(target, &tdata1, GDB_REGNO_TDATA1); - int type = get_field(tdata1, MCONTROL_TYPE(riscv_xlen(target))); - - if (type != 2) { - continue; - } - - if (tdata1 & (MCONTROL_EXECUTE | MCONTROL_STORE | MCONTROL_LOAD)) { - // Trigger is already in use, presumably by user code. - continue; - } - - // address/data match trigger - tdata1 |= MCONTROL_DMODE(riscv_xlen(target)); - tdata1 = set_field(tdata1, MCONTROL_ACTION, - MCONTROL_ACTION_DEBUG_MODE); - tdata1 = set_field(tdata1, MCONTROL_MATCH, MCONTROL_MATCH_EQUAL); - tdata1 |= MCONTROL_M; - if (info->misa & (1 << ('H' - 'A'))) - tdata1 |= MCONTROL_H; - if (info->misa & (1 << ('S' - 'A'))) - tdata1 |= MCONTROL_S; - if (info->misa & (1 << ('U' - 'A'))) - tdata1 |= MCONTROL_U; - - if (trigger->execute) - tdata1 |= MCONTROL_EXECUTE; - if (trigger->read) - tdata1 |= MCONTROL_LOAD; - if (trigger->write) - tdata1 |= MCONTROL_STORE; - - register_write_direct(target, GDB_REGNO_TDATA1, tdata1); - - uint64_t tdata1_rb; - register_read_direct(target, &tdata1_rb, GDB_REGNO_TDATA1); - LOG_DEBUG("tdata1=0x%" PRIx64, tdata1_rb); - - if (tdata1 != tdata1_rb) { - LOG_DEBUG("Trigger %d doesn't support what we need; After writing 0x%" - PRIx64 " to tdata1 it contains 0x%" PRIx64, - i, tdata1, tdata1_rb); - register_write_direct(target, GDB_REGNO_TDATA1, 0); - continue; - } - - register_write_direct(target, GDB_REGNO_TDATA2, trigger->address); - - LOG_DEBUG("Using resource %d for bp %d", i, - trigger->unique_id); - info->trigger_unique_id[i] = trigger->unique_id; - break; - } - if (i >= info->trigger_count) { - LOG_ERROR("Couldn't find an available hardware trigger."); - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - } - - return ERROR_OK; -} - -static int remove_trigger(struct target *target, struct trigger *trigger) -{ - riscv013_info_t *info = get_info(target); - - maybe_read_tselect(target); - - unsigned int i; - for (i = 0; i < info->trigger_count; i++) { - if (info->trigger_unique_id[i] == trigger->unique_id) { - break; - } - } - if (i >= info->trigger_count) { - LOG_ERROR("Couldn't find the hardware resources used by hardware " - "trigger."); - return ERROR_FAIL; - } - LOG_DEBUG("Stop using resource %d for bp %d", i, trigger->unique_id); - register_write_direct(target, GDB_REGNO_TSELECT, i); - register_write_direct(target, GDB_REGNO_TDATA1, 0); - info->trigger_unique_id[i] = -1; - - return ERROR_OK; -} - -static void trigger_from_breakpoint(struct trigger *trigger, - const struct breakpoint *breakpoint) -{ - trigger->address = breakpoint->address; - trigger->length = breakpoint->length; - trigger->mask = ~0LL; - trigger->read = false; - trigger->write = false; - trigger->execute = true; - // unique_id is unique across both breakpoints and watchpoints. - trigger->unique_id = breakpoint->unique_id; -} - -static void trigger_from_watchpoint(struct trigger *trigger, - const struct watchpoint *watchpoint) -{ - trigger->address = watchpoint->address; - trigger->length = watchpoint->length; - trigger->mask = watchpoint->mask; - trigger->value = watchpoint->value; - trigger->read = (watchpoint->rw == WPT_READ || watchpoint->rw == WPT_ACCESS); - trigger->write = (watchpoint->rw == WPT_WRITE || watchpoint->rw == WPT_ACCESS); - trigger->execute = false; - // unique_id is unique across both breakpoints and watchpoints. - trigger->unique_id = watchpoint->unique_id; -} - -static int add_breakpoint(struct target *target, - struct breakpoint *breakpoint) -{ - if (breakpoint->type == BKPT_SOFT) { - if (target_read_memory(target, breakpoint->address, breakpoint->length, 1, - breakpoint->orig_instr) != ERROR_OK) { - LOG_ERROR("Failed to read original instruction at 0x%x", - breakpoint->address); - return ERROR_FAIL; - } - - int retval; - if (breakpoint->length == 4) { - retval = target_write_u32(target, breakpoint->address, ebreak()); - } else { - retval = target_write_u16(target, breakpoint->address, ebreak_c()); - } - if (retval != ERROR_OK) { - LOG_ERROR("Failed to write %d-byte breakpoint instruction at 0x%x", - breakpoint->length, breakpoint->address); - return ERROR_FAIL; - } - - } else if (breakpoint->type == BKPT_HARD) { - struct trigger trigger; - trigger_from_breakpoint(&trigger, breakpoint); - int result = add_trigger(target, &trigger); - if (result != ERROR_OK) { - return result; - } - } else { - LOG_INFO("OpenOCD only supports hardware and software breakpoints."); - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - } - - breakpoint->set = true; - - return ERROR_OK; -} - -static int remove_breakpoint(struct target *target, - struct breakpoint *breakpoint) -{ - if (breakpoint->type == BKPT_SOFT) { - if (target_write_memory(target, breakpoint->address, breakpoint->length, 1, - breakpoint->orig_instr) != ERROR_OK) { - LOG_ERROR("Failed to restore instruction for %d-byte breakpoint at " - "0x%x", breakpoint->length, breakpoint->address); - return ERROR_FAIL; - } - - } else if (breakpoint->type == BKPT_HARD) { - struct trigger trigger; - trigger_from_breakpoint(&trigger, breakpoint); - int result = remove_trigger(target, &trigger); - if (result != ERROR_OK) { - return result; - } - } else { - LOG_INFO("OpenOCD only supports hardware and software breakpoints."); - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - } - - breakpoint->set = false; - - return ERROR_OK; -} - -static int add_watchpoint(struct target *target, - struct watchpoint *watchpoint) -{ - struct trigger trigger; - trigger_from_watchpoint(&trigger, watchpoint); - - int result = add_trigger(target, &trigger); - if (result != ERROR_OK) { - return result; - } - watchpoint->set = true; - - return ERROR_OK; -} - -static int remove_watchpoint(struct target *target, - struct watchpoint *watchpoint) -{ - struct trigger trigger; - trigger_from_watchpoint(&trigger, watchpoint); - - int result = remove_trigger(target, &trigger); - if (result != ERROR_OK) { - return result; - } - watchpoint->set = false; - - return ERROR_OK; -} - -static int examine(struct target *target) -{ - // Don't need to select dbus, since the first thing we do is read dtmcontrol. - - uint32_t dtmcontrol = dtmcontrol_scan(target, 0); - LOG_DEBUG("dtmcontrol=0x%x", dtmcontrol); - LOG_DEBUG(" dmireset=%d", get_field(dtmcontrol, DTM_DTMCS_DMIRESET)); - LOG_DEBUG(" idle=%d", get_field(dtmcontrol, DTM_DTMCS_IDLE)); - LOG_DEBUG(" dmistat=%d", get_field(dtmcontrol, DTM_DTMCS_DMISTAT)); - LOG_DEBUG(" abits=%d", get_field(dtmcontrol, DTM_DTMCS_ABITS)); - LOG_DEBUG(" version=%d", get_field(dtmcontrol, DTM_DTMCS_VERSION)); - if (dtmcontrol == 0) { - LOG_ERROR("dtmcontrol is 0. Check JTAG connectivity/board power."); - return ERROR_FAIL; - } - if (get_field(dtmcontrol, DTM_DTMCS_VERSION) != 1) { - LOG_ERROR("Unsupported DTM version %d. (dtmcontrol=0x%x)", - get_field(dtmcontrol, DTM_DTMCS_VERSION), dtmcontrol); - return ERROR_FAIL; - } - - riscv013_info_t *info = get_info(target); - info->abits = get_field(dtmcontrol, DTM_DTMCS_ABITS); - info->dtmcontrol_idle = get_field(dtmcontrol, DTM_DTMCS_IDLE); - - uint32_t dmcontrol = dmi_read(target, DMI_DMCONTROL); - uint32_t dmstatus = dmi_read(target, DMI_DMSTATUS); - if (get_field(dmstatus, DMI_DMSTATUS_VERSIONLO) != 2) { - LOG_ERROR("OpenOCD only supports Debug Module version 2, not %d " - "(dmstatus=0x%x)", get_field(dmstatus, DMI_DMSTATUS_VERSIONLO), dmstatus); - return ERROR_FAIL; - } - - // Reset the Debug Module. - dmi_write(target, DMI_DMCONTROL, 0); - dmi_write(target, DMI_DMCONTROL, DMI_DMCONTROL_DMACTIVE); - dmcontrol = dmi_read(target, DMI_DMCONTROL); - - LOG_DEBUG("dmcontrol: 0x%08x", dmcontrol); - LOG_DEBUG("dmstatus: 0x%08x", dmstatus); - - if (!get_field(dmcontrol, DMI_DMCONTROL_DMACTIVE)) { - LOG_ERROR("Debug Module did not become active. dmcontrol=0x%x", - dmcontrol); - return ERROR_FAIL; - } - - if (!get_field(dmstatus, DMI_DMSTATUS_AUTHENTICATED)) { - LOG_ERROR("Authentication required by RISC-V core but not " - "supported by OpenOCD. dmcontrol=0x%x", dmcontrol); - return ERROR_FAIL; - } - - if (get_field(dmstatus, DMI_DMSTATUS_ANYUNAVAIL)) { - LOG_ERROR("The hart is unavailable."); - return ERROR_FAIL; - } - - if (get_field(dmstatus, DMI_DMSTATUS_ANYNONEXISTENT)) { - LOG_ERROR("The hart doesn't exist."); - return ERROR_FAIL; - } - - // Check that abstract data registers are accessible. - uint32_t abstractcs = dmi_read(target, DMI_ABSTRACTCS); - info->datacount = get_field(abstractcs, DMI_ABSTRACTCS_DATACOUNT); - info->progsize = get_field(abstractcs, DMI_ABSTRACTCS_PROGSIZE); - - /* Halt every hart so we can probe them. */ - riscv_halt_all_harts(target); - - /* Examines every hart, first checking XLEN. */ - for (int i = 0; i < riscv_count_harts(target); ++i) { - RISCV_INFO(r); - riscv_set_current_hartid(target, i); - - if (abstract_read_register(target, NULL, S0, 128) == ERROR_OK) { - r->xlen[i] = 128; - } else if (abstract_read_register(target, NULL, S0, 64) == ERROR_OK) { - r->xlen[i] = 64; - } else if (abstract_read_register(target, NULL, S0, 32) == ERROR_OK) { - r->xlen[i] = 32; - } else { - LOG_ERROR("Failed to discover size using abstract register reads."); - return ERROR_FAIL; - } - } - - /* FIXME: Are there 2 triggers? */ - info->trigger_count = 2; - - /* Resumes all the harts, so the debugger can later pause them. */ - riscv_resume_all_harts(target); - target_set_examined(target); - return ERROR_OK; -} - -static int assert_reset(struct target *target) -{ - return ERROR_FAIL; -} - -static int deassert_reset(struct target *target) -{ - return ERROR_FAIL; -} - -/** - * If there was a DMI error, clear that error and return 1. - * Otherwise return 0. - */ -static int check_dmi_error(struct target *target) -{ - dmi_status_t status = dmi_scan(target, NULL, NULL, DMI_OP_NOP, 0, 0, - false); - if (status != DMI_STATUS_SUCCESS) { - // Clear errors. - dtmcontrol_scan(target, DTM_DTMCS_DMIRESET); - increase_dmi_busy_delay(target); - return 1; - } - return 0; -} - -static int read_memory(struct target *target, uint32_t address, - uint32_t size, uint32_t count, uint8_t *buffer) -{ - select_dmi(target); - riscv_set_current_hartid(target, 0); - - for (uint32_t i = 0; i < count; ++i) { - uint32_t offset = i*size; - uint32_t t_addr = address + offset; - uint8_t *t_buffer = buffer + offset; - - abstract_write_register(target, S0, riscv_xlen(target), t_addr); - - program_t *program = program_new(); - switch (size) { - case 1: - program_add32(program, lb(S1, S0, 0)); - break; - case 2: - program_add32(program, lh(S1, S0, 0)); - break; - case 4: - program_add32(program, lw(S1, S0, 0)); - break; - default: - LOG_ERROR("Unsupported size: %d", size); - return ERROR_FAIL; - } - program_add32(program, fence()); - program_add32(program, ebreak()); - program_set_read(program, S1); - write_program(target, program); - execute_program(target, program); - uint32_t abstractcs; - wait_for_idle(target, &abstractcs); - program_delete(program); - - uint32_t value = dmi_read(target, DMI_DATA0); - switch (size) { - case 1: - t_buffer[0] = value; - break; - case 2: - t_buffer[0] = value; - t_buffer[1] = value >> 8; - break; - case 4: - t_buffer[0] = value; - t_buffer[1] = value >> 8; - t_buffer[2] = value >> 16; - t_buffer[3] = value >> 24; - break; - default: - return ERROR_FAIL; - } - - LOG_INFO("read 0x%08x from 0x%08x", value, t_addr); - - if (check_dmi_error(target)) { - LOG_ERROR("DMI error"); - return ERROR_FAIL; - } - } - - program_t *program = program_new(); - program_add32(program, ebreak()); - program_add32(program, ebreak()); - program_add32(program, ebreak()); - program_add32(program, ebreak()); - write_program(target, program); - program_delete(program); - - return ERROR_OK; -} - -static int write_memory(struct target *target, uint32_t address, - uint32_t size, uint32_t count, const uint8_t *buffer) -{ - select_dmi(target); - riscv_set_current_hartid(target, 0); - - for (uint32_t i = 0; i < count; ++i) { - uint32_t offset = size*i; - uint32_t t_addr = address + offset; - const uint8_t *t_buffer = buffer + offset; - - abstract_write_register(target, S0, riscv_xlen(target), t_addr); - program_t *program = program_new(); - switch (size) { - case 1: - program_add32(program, sb(S1, S0, 0)); - break; - case 2: - program_add32(program, sh(S1, S0, 0)); - break; - case 4: - program_add32(program, sw(S1, S0, 0)); - break; - default: - LOG_ERROR("Unsupported size: %d", size); - return ERROR_FAIL; - } - program_add32(program, fence()); - program_add32(program, ebreak()); - - uint32_t value; - switch (size) { - case 1: - value = t_buffer[0]; - break; - case 2: - value = t_buffer[0] | ((uint32_t) t_buffer[1] << 8); - break; - case 4: - value = t_buffer[0] | - ((uint32_t) t_buffer[1] << 8) | - ((uint32_t) t_buffer[2] << 16) | - ((uint32_t) t_buffer[3] << 24); - break; - default: - return ERROR_FAIL; - } - abstract_write_register(target, S1, riscv_xlen(target), value); - program_set_write(program, S1, value); - - LOG_INFO("writing 0x%08x to 0x%08x", value, t_addr); - - write_program(target, program); - execute_program(target, program); - uint32_t abstractcs; - wait_for_idle(target, &abstractcs); - program_delete(program); - - if (check_dmi_error(target)) { - LOG_ERROR("DMI error"); - return ERROR_FAIL; - } - } - - program_t *program = program_new(); - program_add32(program, ebreak()); - program_add32(program, ebreak()); - program_add32(program, ebreak()); - program_add32(program, ebreak()); - write_program(target, program); - program_delete(program); - return ERROR_OK; -} - -static int arch_state(struct target *target) -{ - return ERROR_OK; -} - -struct target_type riscv013_target = -{ - .name = "riscv", - - .init_target = init_target, - .deinit_target = deinit_target, - .examine = examine, - - .poll = &riscv_openocd_poll, - .halt = &riscv_openocd_halt, - .resume = &riscv_openocd_resume, - .step = &riscv_openocd_step, - - .assert_reset = assert_reset, - .deassert_reset = deassert_reset, - - .read_memory = read_memory, - .write_memory = write_memory, - - .add_breakpoint = add_breakpoint, - .remove_breakpoint = remove_breakpoint, - - .add_watchpoint = add_watchpoint, - .remove_watchpoint = remove_watchpoint, - - .arch_state = arch_state, -}; - -/*** 0.13-specific implementations of various RISC-V hepler functions. ***/ -static riscv_reg_t riscv013_get_register(struct target *target, int hid, int rid) -{ - riscv_set_current_hartid(target, hid); - - uint64_t out; - register_read_direct(target, &out, rid); - return out; -} - -static void riscv013_set_register(struct target *target, int hid, int rid, uint64_t value) -{ - riscv_set_current_hartid(target, hid); - - register_write_direct(target, rid, value); -} - -static void riscv013_select_current_hart(struct target *target) -{ - RISCV_INFO(r); - - uint64_t dmcontrol = dmi_read(target, DMI_DMCONTROL); - dmcontrol = set_field(dmcontrol, DMI_DMCONTROL_HARTSEL, r->current_hartid); - dmi_write(target, DMI_DMCONTROL, dmcontrol); -} - -static void riscv013_halt_current_hart(struct target *target) -{ - RISCV_INFO(r); - LOG_DEBUG("halting hart %d", r->current_hartid); - assert(!riscv_is_halted(target)); - - /* Issue the halt command, and then wait for the current hart to halt. */ - uint32_t dmcontrol = dmi_read(target, DMI_DMCONTROL); - dmcontrol = set_field(dmcontrol, DMI_DMCONTROL_HALTREQ, 1); - dmi_write(target, DMI_DMCONTROL, dmcontrol); - for (size_t i = 0; i < 256; ++i) - if (riscv_is_halted(target)) - break; - - if (!riscv_is_halted(target)) { - uint32_t dmstatus = dmi_read(target, DMI_DMSTATUS); - dmcontrol = dmi_read(target, DMI_DMCONTROL); - - LOG_ERROR("unable to halt hart %d", r->current_hartid); - LOG_ERROR(" dmcontrol=0x%08x", dmcontrol); - LOG_ERROR(" dmstatus =0x%08x", dmstatus); - abort(); - } - - dmcontrol = set_field(dmcontrol, DMI_DMCONTROL_HALTREQ, 0); - dmi_write(target, DMI_DMCONTROL, dmcontrol); -} - -static void riscv013_resume_current_hart(struct target *target) -{ - return riscv013_step_or_resume_current_hart(target, false); -} - -static void riscv013_step_current_hart(struct target *target) -{ - return riscv013_step_or_resume_current_hart(target, true); -} - -static void riscv013_on_resume(struct target *target) -{ - return riscv013_on_step_or_resume(target, false); -} - -static void riscv013_on_step(struct target *target) -{ - return riscv013_on_step_or_resume(target, true); -} - -static void riscv013_on_halt(struct target *target) -{ - RISCV_INFO(r); - LOG_DEBUG("saving register state for hart %d", r->current_hartid); - riscv_save_register(target, GDB_REGNO_S0); - riscv_save_register(target, GDB_REGNO_S1); - riscv_save_register(target, GDB_REGNO_DPC); - riscv_save_register(target, GDB_REGNO_DCSR); -} - -static bool riscv013_is_halted(struct target *target) -{ - uint32_t dmstatus = dmi_read(target, DMI_DMSTATUS); - return get_field(dmstatus, DMI_DMSTATUS_ALLHALTED); -} - -static enum riscv_halt_reason riscv013_halt_reason(struct target *target) -{ - uint64_t dcsr = riscv_peek_register(target, GDB_REGNO_DCSR); - switch (get_field(dcsr, CSR_DCSR_CAUSE)) { - case CSR_DCSR_CAUSE_SWBP: - case CSR_DCSR_CAUSE_TRIGGER: - return RISCV_HALT_BREAKPOINT; - case CSR_DCSR_CAUSE_STEP: - return RISCV_HALT_SINGLESTEP; - case CSR_DCSR_CAUSE_DEBUGINT: - case CSR_DCSR_CAUSE_HALT: - return RISCV_HALT_INTERRUPT; - } - - LOG_ERROR("Unknown DCSR cause field: %x", (int)get_field(dcsr, CSR_DCSR_CAUSE)); - abort(); -} - -/* Helper Functions. */ -static void riscv013_on_step_or_resume(struct target *target, bool step) -{ - RISCV_INFO(r); - LOG_DEBUG("restoring register state for hart %d", r->current_hartid); - - program_t *program = program_new(); - program_add32(program, fence_i()); - program_add32(program, ebreak()); - write_program(target, program); - if (execute_program(target, program) != ERROR_OK) { - LOG_ERROR("Unable to execute fence.i"); - } - program_delete(program); - - /* We want to twiddle some bits in the debug CSR so debugging works. */ - uint64_t dcsr = riscv_peek_register(target, GDB_REGNO_DCSR); - dcsr = set_field(dcsr, CSR_DCSR_STEP, step); - dcsr = set_field(dcsr, CSR_DCSR_EBREAKM, 1); - dcsr = set_field(dcsr, CSR_DCSR_EBREAKH, 1); - dcsr = set_field(dcsr, CSR_DCSR_EBREAKS, 1); - dcsr = set_field(dcsr, CSR_DCSR_EBREAKU, 1); - riscv_overwrite_register(target, GDB_REGNO_DCSR, dcsr); - - riscv_restore_register(target, GDB_REGNO_DCSR); - riscv_restore_register(target, GDB_REGNO_DPC); - riscv_restore_register(target, GDB_REGNO_S1); - riscv_restore_register(target, GDB_REGNO_S0); -} - -static void riscv013_step_or_resume_current_hart(struct target *target, bool step) -{ - RISCV_INFO(r); - LOG_DEBUG("resuming hart %d", r->current_hartid); - assert(riscv_is_halted(target)); - - /* Issue the halt command, and then wait for the current hart to halt. */ - uint32_t dmcontrol = dmi_read(target, DMI_DMCONTROL); - dmcontrol = set_field(dmcontrol, DMI_DMCONTROL_RESUMEREQ, 1); - dmi_write(target, DMI_DMCONTROL, dmcontrol); - -#if 1 - /* FIXME: ... well, after a short time. */ - usleep(100); -#else - /* FIXME: there's a race condition in stepping now, so just return - * right away... */ - for (size_t i = 0; i < 256; ++i) { - if (!riscv_is_halted(target)) - break; - } - - if (riscv_is_halted(target)) { - uint32_t dmstatus = dmi_read(target, DMI_DMSTATUS); - dmcontrol = dmi_read(target, DMI_DMCONTROL); - - LOG_ERROR("unable to resume hart %d", r->current_hartid); - LOG_ERROR(" dmcontrol=0x%08x", dmcontrol); - LOG_ERROR(" dmstatus =0x%08x", dmstatus); - abort(); - } -#endif - - dmcontrol = set_field(dmcontrol, DMI_DMCONTROL_RESUMEREQ, 0); - dmi_write(target, DMI_DMCONTROL, dmcontrol); -} diff --git a/src/target/riscv/riscv.c b/src/target/riscv/riscv.c deleted file mode 100644 index 13410bdb0..000000000 --- a/src/target/riscv/riscv.c +++ /dev/null @@ -1,1007 +0,0 @@ -#include -#include -#include - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "target.h" -#include "target/algorithm.h" -#include "target_type.h" -#include "log.h" -#include "jtag/jtag.h" -#include "register.h" -#include "breakpoints.h" -#include "helper/time_support.h" -#include "riscv.h" -#include "gdb_regs.h" -#include "rtos/rtos.h" - -/** - * Since almost everything can be accomplish by scanning the dbus register, all - * functions here assume dbus is already selected. The exception are functions - * called directly by OpenOCD, which can't assume anything about what's - * currently in IR. They should set IR to dbus explicitly. - */ - -/** - * Code structure - * - * At the bottom of the stack are the OpenOCD JTAG functions: - * jtag_add_[id]r_scan - * jtag_execute_query - * jtag_add_runtest - * - * There are a few functions to just instantly shift a register and get its - * value: - * dtmcontrol_scan - * idcode_scan - * dbus_scan - * - * Because doing one scan and waiting for the result is slow, most functions - * batch up a bunch of dbus writes and then execute them all at once. They use - * the scans "class" for this: - * scans_new - * scans_delete - * scans_execute - * scans_add_... - * Usually you new(), call a bunch of add functions, then execute() and look - * at the results by calling scans_get...() - * - * Optimized functions will directly use the scans class above, but slightly - * lazier code will use the cache functions that in turn use the scans - * functions: - * cache_get... - * cache_set... - * cache_write - * cache_set... update a local structure, which is then synced to the target - * with cache_write(). Only Debug RAM words that are actually changed are sent - * to the target. Afterwards use cache_get... to read results. - */ - -#define get_field(reg, mask) (((reg) & (mask)) / ((mask) & ~((mask) << 1))) -#define set_field(reg, mask, val) (((reg) & ~(mask)) | (((val) * ((mask) & ~((mask) << 1))) & (mask))) - -#define DIM(x) (sizeof(x)/sizeof(*x)) - -// Constants for legacy SiFive hardware breakpoints. -#define CSR_BPCONTROL_X (1<<0) -#define CSR_BPCONTROL_W (1<<1) -#define CSR_BPCONTROL_R (1<<2) -#define CSR_BPCONTROL_U (1<<3) -#define CSR_BPCONTROL_S (1<<4) -#define CSR_BPCONTROL_H (1<<5) -#define CSR_BPCONTROL_M (1<<6) -#define CSR_BPCONTROL_BPMATCH (0xf<<7) -#define CSR_BPCONTROL_BPACTION (0xff<<11) - -#define DEBUG_ROM_START 0x800 -#define DEBUG_ROM_RESUME (DEBUG_ROM_START + 4) -#define DEBUG_ROM_EXCEPTION (DEBUG_ROM_START + 8) -#define DEBUG_RAM_START 0x400 - -#define SETHALTNOT 0x10c - -/*** JTAG registers. ***/ - -#define DTMCONTROL 0x10 -#define DTMCONTROL_DBUS_RESET (1<<16) -#define DTMCONTROL_IDLE (7<<10) -#define DTMCONTROL_ADDRBITS (0xf<<4) -#define DTMCONTROL_VERSION (0xf) - -#define DBUS 0x11 -#define DBUS_OP_START 0 -#define DBUS_OP_SIZE 2 -typedef enum { - DBUS_OP_NOP = 0, - DBUS_OP_READ = 1, - DBUS_OP_WRITE = 2 -} dbus_op_t; -typedef enum { - DBUS_STATUS_SUCCESS = 0, - DBUS_STATUS_FAILED = 2, - DBUS_STATUS_BUSY = 3 -} dbus_status_t; -#define DBUS_DATA_START 2 -#define DBUS_DATA_SIZE 34 -#define DBUS_ADDRESS_START 36 - -typedef enum { - RE_OK, - RE_FAIL, - RE_AGAIN -} riscv_error_t; - -typedef enum slot { - SLOT0, - SLOT1, - SLOT_LAST, -} slot_t; - -/*** Debug Bus registers. ***/ - -#define DMCONTROL 0x10 -#define DMCONTROL_INTERRUPT (((uint64_t)1)<<33) -#define DMCONTROL_HALTNOT (((uint64_t)1)<<32) -#define DMCONTROL_BUSERROR (7<<19) -#define DMCONTROL_SERIAL (3<<16) -#define DMCONTROL_AUTOINCREMENT (1<<15) -#define DMCONTROL_ACCESS (7<<12) -#define DMCONTROL_HARTID (0x3ff<<2) -#define DMCONTROL_NDRESET (1<<1) -#define DMCONTROL_FULLRESET 1 - -#define DMINFO 0x11 -#define DMINFO_ABUSSIZE (0x7fU<<25) -#define DMINFO_SERIALCOUNT (0xf<<21) -#define DMINFO_ACCESS128 (1<<20) -#define DMINFO_ACCESS64 (1<<19) -#define DMINFO_ACCESS32 (1<<18) -#define DMINFO_ACCESS16 (1<<17) -#define DMINFO_ACCESS8 (1<<16) -#define DMINFO_DRAMSIZE (0x3f<<10) -#define DMINFO_AUTHENTICATED (1<<5) -#define DMINFO_AUTHBUSY (1<<4) -#define DMINFO_AUTHTYPE (3<<2) -#define DMINFO_VERSION 3 - -/*** Info about the core being debugged. ***/ - -#define DBUS_ADDRESS_UNKNOWN 0xffff -#define WALL_CLOCK_TIMEOUT 2 - -// gdb's register list is defined in riscv_gdb_reg_names gdb/riscv-tdep.c in -// its source tree. We must interpret the numbers the same here. -enum { - REG_XPR0 = 0, - REG_XPR31 = 31, - REG_PC = 32, - REG_FPR0 = 33, - REG_FPR31 = 64, - REG_CSR0 = 65, - REG_MSTATUS = CSR_MSTATUS + REG_CSR0, - REG_CSR4095 = 4160, - REG_PRIV = 4161, - REG_COUNT -}; - -#define MAX_HWBPS 16 -#define DRAM_CACHE_SIZE 16 - -uint8_t ir_dtmcontrol[1] = {DTMCONTROL}; -struct scan_field select_dtmcontrol = { - .in_value = NULL, - .out_value = ir_dtmcontrol -}; -uint8_t ir_dbus[1] = {DBUS}; -struct scan_field select_dbus = { - .in_value = NULL, - .out_value = ir_dbus -}; -uint8_t ir_idcode[1] = {0x1}; -struct scan_field select_idcode = { - .in_value = NULL, - .out_value = ir_idcode -}; - -struct trigger { - uint64_t address; - uint32_t length; - uint64_t mask; - uint64_t value; - bool read, write, execute; - int unique_id; -}; - -static uint32_t dtmcontrol_scan(struct target *target, uint32_t out) -{ - struct scan_field field; - uint8_t in_value[4]; - uint8_t out_value[4]; - - buf_set_u32(out_value, 0, 32, out); - - jtag_add_ir_scan(target->tap, &select_dtmcontrol, TAP_IDLE); - - field.num_bits = 32; - field.out_value = out_value; - field.in_value = in_value; - jtag_add_dr_scan(target->tap, 1, &field, TAP_IDLE); - - /* Always return to dbus. */ - jtag_add_ir_scan(target->tap, &select_dbus, TAP_IDLE); - - int retval = jtag_execute_queue(); - if (retval != ERROR_OK) { - LOG_ERROR("failed jtag scan: %d", retval); - return retval; - } - - uint32_t in = buf_get_u32(field.in_value, 0, 32); - LOG_DEBUG("DTMCONTROL: 0x%x -> 0x%x", out, in); - - return in; -} - -static struct target_type *get_target_type(struct target *target) -{ - riscv_info_t *info = (riscv_info_t *) target->arch_info; - - switch (info->dtm_version) { - case 0: - return &riscv011_target; - case 1: - return &riscv013_target; - default: - LOG_ERROR("Unsupported DTM version: %d", info->dtm_version); - return NULL; - } -} - -static int riscv_init_target(struct command_context *cmd_ctx, - struct target *target) -{ - LOG_DEBUG("riscv_init_target()"); - target->arch_info = calloc(1, sizeof(riscv_info_t)); - if (!target->arch_info) - return ERROR_FAIL; - riscv_info_t *info = (riscv_info_t *) target->arch_info; - info->cmd_ctx = cmd_ctx; - - select_dtmcontrol.num_bits = target->tap->ir_length; - select_dbus.num_bits = target->tap->ir_length; - select_idcode.num_bits = target->tap->ir_length; - - return ERROR_OK; -} - -static void riscv_deinit_target(struct target *target) -{ - LOG_DEBUG("riscv_deinit_target()"); - struct target_type *tt = get_target_type(target); - tt->deinit_target(target); - riscv_info_t *info = (riscv_info_t *) target->arch_info; - free(info); - target->arch_info = NULL; -} - -static int riscv_halt(struct target *target) -{ - struct target_type *tt = get_target_type(target); - return tt->halt(target); -} - -static int riscv_add_breakpoint(struct target *target, - struct breakpoint *breakpoint) -{ - struct target_type *tt = get_target_type(target); - return tt->add_breakpoint(target, breakpoint); -} - -static int riscv_remove_breakpoint(struct target *target, - struct breakpoint *breakpoint) -{ - struct target_type *tt = get_target_type(target); - return tt->remove_breakpoint(target, breakpoint); -} - -static int riscv_add_watchpoint(struct target *target, - struct watchpoint *watchpoint) -{ - struct target_type *tt = get_target_type(target); - return tt->add_watchpoint(target, watchpoint); -} - -static int riscv_remove_watchpoint(struct target *target, - struct watchpoint *watchpoint) -{ - struct target_type *tt = get_target_type(target); - return tt->remove_watchpoint(target, watchpoint); -} - -static int riscv_step(struct target *target, int current, uint32_t address, - int handle_breakpoints) -{ - struct target_type *tt = get_target_type(target); - return tt->step(target, current, address, handle_breakpoints); -} - -static int riscv_examine(struct target *target) -{ - LOG_DEBUG("riscv_examine()"); - if (target_was_examined(target)) { - return ERROR_OK; - } - - // Don't need to select dbus, since the first thing we do is read dtmcontrol. - - riscv_info_t *info = (riscv_info_t *) target->arch_info; - uint32_t dtmcontrol = dtmcontrol_scan(target, 0); - LOG_DEBUG("dtmcontrol=0x%x", dtmcontrol); - info->dtm_version = get_field(dtmcontrol, DTMCONTROL_VERSION); - LOG_DEBUG(" version=0x%x", info->dtm_version); - - struct target_type *tt = get_target_type(target); - if (tt == NULL) - return ERROR_FAIL; - - int result = tt->init_target(info->cmd_ctx, target); - if (result != ERROR_OK) - return result; - - return tt->examine(target); -} - -static int oldriscv_poll(struct target *target) -{ - struct target_type *tt = get_target_type(target); - return tt->poll(target); -} - -static int riscv_resume(struct target *target, int current, uint32_t address, - int handle_breakpoints, int debug_execution) -{ - struct target_type *tt = get_target_type(target); - return tt->resume(target, current, address, handle_breakpoints, - debug_execution); -} - -static int riscv_assert_reset(struct target *target) -{ - struct target_type *tt = get_target_type(target); - return tt->assert_reset(target); -} - -static int riscv_deassert_reset(struct target *target) -{ - struct target_type *tt = get_target_type(target); - return tt->deassert_reset(target); -} - -static int riscv_read_memory(struct target *target, uint32_t address, - uint32_t size, uint32_t count, uint8_t *buffer) -{ - struct target_type *tt = get_target_type(target); - return tt->read_memory(target, address, size, count, buffer); -} - -static int riscv_write_memory(struct target *target, uint32_t address, - uint32_t size, uint32_t count, const uint8_t *buffer) -{ - struct target_type *tt = get_target_type(target); - return tt->write_memory(target, address, size, count, buffer); -} - -static int riscv_get_gdb_reg_list(struct target *target, - struct reg **reg_list[], int *reg_list_size, - enum target_register_class reg_class) -{ - RISCV_INFO(r); - LOG_DEBUG("reg_class=%d", reg_class); - LOG_DEBUG("riscv_get_gdb_reg_list: rtos_hartid=%d current_hartid=%d", r->rtos_hartid, r->current_hartid); - if (r->rtos_hartid != -1) - riscv_set_current_hartid(target, r->rtos_hartid); - else - riscv_set_current_hartid(target, 0); - - switch (reg_class) { - case REG_CLASS_GENERAL: - *reg_list_size = 32; - break; - case REG_CLASS_ALL: - *reg_list_size = REG_COUNT; - break; - default: - LOG_ERROR("Unsupported reg_class: %d", reg_class); - return ERROR_FAIL; - } - - *reg_list = calloc(*reg_list_size, sizeof(struct reg *)); - if (!*reg_list) { - return ERROR_FAIL; - } - for (int i = 0; i < *reg_list_size; i++) { - assert(target->reg_cache->reg_list[i].size > 0); - (*reg_list)[i] = &target->reg_cache->reg_list[i]; - } - - return ERROR_OK; -} - -static int riscv_arch_state(struct target *target) -{ - struct target_type *tt = get_target_type(target); - return tt->arch_state(target); -} - -// Algorithm must end with a software breakpoint instruction. -static int riscv_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) -{ - riscv_info_t *info = (riscv_info_t *) target->arch_info; - - if (num_mem_params > 0) { - LOG_ERROR("Memory parameters are not supported for RISC-V algorithms."); - return ERROR_FAIL; - } - - if (target->state != TARGET_HALTED) { - LOG_WARNING("target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - /// Save registers - struct reg *reg_pc = register_get_by_name(target->reg_cache, "pc", 1); - if (!reg_pc || reg_pc->type->get(reg_pc) != ERROR_OK) { - return ERROR_FAIL; - } - uint64_t saved_pc = buf_get_u64(reg_pc->value, 0, reg_pc->size); - - uint64_t saved_regs[32]; - for (int i = 0; i < num_reg_params; i++) { - LOG_DEBUG("save %s", reg_params[i].reg_name); - struct reg *r = register_get_by_name(target->reg_cache, reg_params[i].reg_name, 0); - if (!r) { - LOG_ERROR("Couldn't find register named '%s'", reg_params[i].reg_name); - return ERROR_FAIL; - } - - if (r->size != reg_params[i].size) { - LOG_ERROR("Register %s is %d bits instead of %d bits.", - reg_params[i].reg_name, r->size, reg_params[i].size); - return ERROR_FAIL; - } - - if (r->number > REG_XPR31) { - LOG_ERROR("Only GPRs can be use as argument registers."); - return ERROR_FAIL; - } - - if (r->type->get(r) != ERROR_OK) { - return ERROR_FAIL; - } - saved_regs[r->number] = buf_get_u64(r->value, 0, r->size); - if (r->type->set(r, reg_params[i].value) != ERROR_OK) { - return ERROR_FAIL; - } - } - - - // Disable Interrupts before attempting to run the algorithm. - uint64_t current_mstatus; - uint8_t mstatus_bytes[8]; - - LOG_DEBUG("Disabling Interrupts"); - char mstatus_name[20]; - sprintf(mstatus_name, "csr%d", CSR_MSTATUS); - struct reg *reg_mstatus = register_get_by_name(target->reg_cache, - mstatus_name, 1); - reg_mstatus->type->get(reg_mstatus); - current_mstatus = buf_get_u64(reg_mstatus->value, 0, reg_mstatus->size); - uint64_t ie_mask = MSTATUS_MIE | MSTATUS_HIE | MSTATUS_SIE | MSTATUS_UIE; - buf_set_u64(mstatus_bytes, 0, info->xlen[0], set_field(current_mstatus, - ie_mask, 0)); - - reg_mstatus->type->set(reg_mstatus, mstatus_bytes); - - /// Run algorithm - LOG_DEBUG("resume at 0x%x", entry_point); - if (riscv_resume(target, 0, entry_point, 0, 0) != ERROR_OK) { - return ERROR_FAIL; - } - - int64_t start = timeval_ms(); - while (target->state != TARGET_HALTED) { - LOG_DEBUG("poll()"); - int64_t now = timeval_ms(); - if (now - start > timeout_ms) { - LOG_ERROR("Algorithm timed out after %d ms.", timeout_ms); - riscv_halt(target); - oldriscv_poll(target); - return ERROR_TARGET_TIMEOUT; - } - - int result = oldriscv_poll(target); - if (result != ERROR_OK) { - return result; - } - } - - if (reg_pc->type->get(reg_pc) != ERROR_OK) { - return ERROR_FAIL; - } - uint64_t final_pc = buf_get_u64(reg_pc->value, 0, reg_pc->size); - if (final_pc != exit_point) { - LOG_ERROR("PC ended up at 0x%" PRIx64 " instead of 0x%" PRIx32, - final_pc, exit_point); - return ERROR_FAIL; - } - - // Restore Interrupts - LOG_DEBUG("Restoring Interrupts"); - buf_set_u64(mstatus_bytes, 0, info->xlen[0], current_mstatus); - reg_mstatus->type->set(reg_mstatus, mstatus_bytes); - - /// Restore registers - uint8_t buf[8]; - buf_set_u64(buf, 0, info->xlen[0], saved_pc); - if (reg_pc->type->set(reg_pc, buf) != ERROR_OK) { - return ERROR_FAIL; - } - - for (int i = 0; i < num_reg_params; i++) { - LOG_DEBUG("restore %s", reg_params[i].reg_name); - struct reg *r = register_get_by_name(target->reg_cache, reg_params[i].reg_name, 0); - buf_set_u64(buf, 0, info->xlen[0], saved_regs[r->number]); - if (r->type->set(r, buf) != ERROR_OK) { - return ERROR_FAIL; - } - } - - return ERROR_OK; -} - -/* Should run code on the target to perform CRC of -memory. Not yet implemented. -*/ - -static int riscv_checksum_memory(struct target *target, - uint32_t address, uint32_t count, - uint32_t* checksum) -{ - *checksum = 0xFFFFFFFF; - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; -} - -/* Should run code on the target to check whether a memory -block holds all-ones (because this is generally called on -NOR flash which is 1 when "blank") -Not yet implemented. -*/ -int riscv_blank_check_memory(struct target * target, - uint32_t address, - uint32_t count, - uint32_t * blank) -{ - *blank = 0; - - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; -} - -struct target_type riscv_target = -{ - .name = "riscv", - - .init_target = riscv_init_target, - .deinit_target = riscv_deinit_target, - .examine = riscv_examine, - - /* poll current target status */ - .poll = oldriscv_poll, - - .halt = riscv_halt, - .resume = riscv_resume, - .step = riscv_step, - - .assert_reset = riscv_assert_reset, - .deassert_reset = riscv_deassert_reset, - - .read_memory = riscv_read_memory, - .write_memory = riscv_write_memory, - - .blank_check_memory = riscv_blank_check_memory, - .checksum_memory = riscv_checksum_memory, - - .get_gdb_reg_list = riscv_get_gdb_reg_list, - - .add_breakpoint = riscv_add_breakpoint, - .remove_breakpoint = riscv_remove_breakpoint, - - .add_watchpoint = riscv_add_watchpoint, - .remove_watchpoint = riscv_remove_watchpoint, - - .arch_state = riscv_arch_state, - - .run_algorithm = riscv_run_algorithm, -}; - -/*** OpenOCD Helper Functions ***/ - -/* 0 means nothing happened, 1 means the hart's state changed (and thus the - * poll should terminate), and -1 means there was an error. */ -static int riscv_poll_hart(struct target *target, int hartid) -{ - RISCV_INFO(r); - LOG_DEBUG("polling hart %d", hartid); - - /* If there's no new event then there's nothing to do. */ - riscv_set_current_hartid(target, hartid); - assert((riscv_was_halted(target) && riscv_is_halted(target)) || !riscv_was_halted(target)); - if (riscv_was_halted(target) || !riscv_is_halted(target)) - return 0; - - /* If we got here then this must be the first poll during which this - * hart halted. We need to synchronize the hart's state with the - * debugger, and inform the outer polling loop that there's something - * to do. */ - r->hart_state[hartid] = RISCV_HART_HALTED; - r->on_halt(target); - return 1; -} - -/*** OpenOCD Interface ***/ -int riscv_openocd_poll(struct target *target) -{ - LOG_DEBUG("polling all harts"); - if (riscv_rtos_enabled(target)) { - /* Check every hart for an event. */ - int triggered_hart = -1; - for (int i = 0; i < riscv_count_harts(target); ++i) { - int out = riscv_poll_hart(target, i); - switch (out) { - case 0: - continue; - case 1: - triggered_hart = i; - break; - case -1: - return ERROR_FAIL; - } - } - if (triggered_hart == -1) { - LOG_DEBUG(" no harts halted"); - return ERROR_OK; - } - LOG_DEBUG(" hart %d halted", triggered_hart); - - /* If we're here then at least one hart triggered. That means - * we want to go and halt _every_ hart in the system, as that's - * the invariant we hold here. Some harts might have already - * halted (as we're either in single-step mode or they also - * triggered a breakpoint), so don't attempt to halt those - * harts. */ - for (int i = 0; i < riscv_count_harts(target); ++i) - riscv_halt_one_hart(target, i); - - target->state = TARGET_HALTED; - switch (riscv_halt_reason(target, triggered_hart)) { - case RISCV_HALT_BREAKPOINT: - target->debug_reason = DBG_REASON_BREAKPOINT; - break; - case RISCV_HALT_INTERRUPT: - target->debug_reason = DBG_REASON_DBGRQ; - break; - case RISCV_HALT_SINGLESTEP: - target->debug_reason = DBG_REASON_SINGLESTEP; - break; - } - - target->rtos->current_threadid = triggered_hart + 1; - target->rtos->current_thread = triggered_hart + 1; - - target_call_event_callbacks(target, TARGET_EVENT_HALTED); - return ERROR_OK; - } else { - return riscv_poll_hart(target, riscv_current_hartid(target)); - } -} - -int riscv_openocd_halt(struct target *target) -{ - int out = riscv_halt_all_harts(target); - if (out != ERROR_OK) - return out; - - target->state = TARGET_HALTED; - return out; -} - -int riscv_openocd_resume( - struct target *target, - int current, - uint32_t address, - int handle_breakpoints, - int debug_execution -) { - if (!current) { - LOG_ERROR("resume-at-pc unimplemented"); - return ERROR_FAIL; - } - - int out = riscv_resume_all_harts(target); - if (out != ERROR_OK) - return out; - - target->state = TARGET_RUNNING; - return out; -} - -int riscv_openocd_step( - struct target *target, - int current, - uint32_t address, - int handle_breakpoints -) { - if (!current) { - LOG_ERROR("step-at-pc unimplemented"); - return ERROR_FAIL; - } - - int out = riscv_step_rtos_hart(target); - if (out != ERROR_OK) - return out; - - target->state = TARGET_RUNNING; - return out; -} - -/*** RISC-V Interface ***/ - -void riscv_info_init(riscv_info_t *r) -{ - memset(r, 0, sizeof(*r)); - r->dtm_version = 1; - - /* FIXME: The RTOS gets enabled before the target gets initialized. */ - r->rtos_enabled = true; - - for (size_t h = 0; h < RISCV_MAX_HARTS; ++h) { - /* FIXME: I need to rip out Tim's probing sequence, as it - * disrupts the running code. For now, I'm just hard-coding - * XLEN to 64 for all cores at reset. */ - r->xlen[h] = 64; - r->hart_state[h] = RISCV_HART_UNKNOWN; - - for (size_t e = 0; e < RISCV_MAX_REGISTERS; ++e) - r->valid_saved_registers[h][e] = false; - } -} - -void riscv_save_register(struct target *target, int regno) -{ - RISCV_INFO(r); - int hartno = r->current_hartid; - LOG_DEBUG("riscv_save_register(%d, %d)", hartno, regno); - assert(r->valid_saved_registers[hartno][regno] == false); - r->valid_saved_registers[hartno][regno] = true; - r->saved_registers[hartno][regno] = riscv_get_register(target, hartno, regno); -} - -uint64_t riscv_peek_register(struct target *target, int regno) -{ - RISCV_INFO(r); - int hartno = r->current_hartid; - LOG_DEBUG("riscv_peek_register(%d, %d)", hartno, regno); - assert(r->valid_saved_registers[hartno][regno] == true); - return r->saved_registers[hartno][regno]; -} - -void riscv_overwrite_register(struct target *target, int regno, uint64_t newval) -{ - RISCV_INFO(r); - int hartno = r->current_hartid; - LOG_DEBUG("riscv_overwrite_register(%d, %d)", hartno, regno); - assert(r->valid_saved_registers[hartno][regno] == true); - r->saved_registers[hartno][regno] = newval; -} - -void riscv_restore_register(struct target *target, int regno) -{ - RISCV_INFO(r); - int hartno = r->current_hartid; - LOG_DEBUG("riscv_restore_register(%d, %d)", hartno, regno); - assert(r->valid_saved_registers[hartno][regno] == true); - r->valid_saved_registers[hartno][regno] = false; - riscv_set_register(target, hartno, regno, r->saved_registers[hartno][regno]); -} - -int riscv_halt_all_harts(struct target *target) -{ - if (riscv_rtos_enabled(target)) { - for (int i = 0; i < riscv_count_harts(target); ++i) - riscv_halt_one_hart(target, i); - } else { - riscv_halt_one_hart(target, riscv_current_hartid(target)); - } - - return ERROR_OK; -} - -int riscv_halt_one_hart(struct target *target, int hartid) -{ - RISCV_INFO(r); - LOG_DEBUG("halting hart %d", hartid); - riscv_set_current_hartid(target, hartid); - - if (r->hart_state[hartid] == RISCV_HART_UNKNOWN) { - r->hart_state[hartid] = riscv_is_halted(target) ? RISCV_HART_HALTED : RISCV_HART_RUNNING; - if (riscv_was_halted(target)) { - LOG_WARNING("Connected to hart %d, which was halted. s0, s1, and pc were overwritten by your previous debugger session and cannot be restored.", hartid); - r->on_halt(target); - } - } - - if (riscv_was_halted(target)) { - LOG_DEBUG(" hart %d requested halt, but was already halted", hartid); - return ERROR_OK; - } - - r->halt_current_hart(target); - return ERROR_OK; -} - -int riscv_resume_all_harts(struct target *target) -{ - if (riscv_rtos_enabled(target)) { - for (int i = 0; i < riscv_count_harts(target); ++i) - riscv_resume_one_hart(target, i); - } else { - riscv_resume_one_hart(target, riscv_current_hartid(target)); - } - - return ERROR_OK; -} - -int riscv_resume_one_hart(struct target *target, int hartid) -{ - RISCV_INFO(r); - LOG_DEBUG("resuming hart %d", hartid); - riscv_set_current_hartid(target, hartid); - - if (r->hart_state[hartid] == RISCV_HART_UNKNOWN) { - r->hart_state[hartid] = riscv_is_halted(target) ? RISCV_HART_HALTED : RISCV_HART_RUNNING; - if (!riscv_was_halted(target)) { - LOG_ERROR("Asked to resume hart %d, which was in an unknown state", hartid); - r->on_resume(target); - } - } - - if (!riscv_was_halted(target)) { - LOG_DEBUG(" hart %d requested resume, but was already resumed", hartid); - return ERROR_OK; - } - - r->on_resume(target); - r->resume_current_hart(target); - r->hart_state[hartid] = RISCV_HART_RUNNING; - return ERROR_OK; -} - -int riscv_step_rtos_hart(struct target *target) -{ - RISCV_INFO(r); - int hartid = r->current_hartid; - if (riscv_rtos_enabled(target)) { - hartid = r->rtos_hartid; - if (hartid == -1) { - LOG_USER("GDB has asked me to step \"any\" thread, so I'm stepping hart 0."); - hartid = 0; - } - } - riscv_set_current_hartid(target, hartid); - LOG_DEBUG("stepping hart %d", hartid); - - assert(r->hart_state[hartid] == RISCV_HART_HALTED); - r->on_step(target); - r->step_current_hart(target); - /* FIXME: There's a race condition with step. */ - r->hart_state[hartid] = RISCV_HART_RUNNING; - return ERROR_OK; -} - -int riscv_xlen(const struct target *target) -{ - return riscv_xlen_of_hart(target, riscv_current_hartid(target)); -} - -int riscv_xlen_of_hart(const struct target *target, int hartid) -{ - RISCV_INFO(r); - assert(r->xlen[hartid] != -1); - return r->xlen[hartid]; -} - -void riscv_enable_rtos(struct target *target) -{ - RISCV_INFO(r); - r->rtos_enabled = true; -} - -bool riscv_rtos_enabled(const struct target *target) -{ - RISCV_INFO(r); - return r->rtos_enabled; -} - -void riscv_set_current_hartid(struct target *target, int hartid) -{ - RISCV_INFO(r); - register_cache_invalidate(target->reg_cache); - r->current_hartid = hartid; - r->select_current_hart(target); - - /* Update the register list's widths. */ - for (size_t i = 0; i < GDB_REGNO_COUNT; ++i) { - struct reg *reg = &target->reg_cache->reg_list[i]; - - reg->value = &r->reg_cache_values[i]; - reg->valid = false; - - switch (i) { - case GDB_REGNO_PRIV: - reg->size = 8; - break; - default: - reg->size = riscv_xlen(target); - break; - } - } -} - -int riscv_current_hartid(const struct target *target) -{ - RISCV_INFO(r); - assert(riscv_rtos_enabled(target) || target->coreid == r->current_hartid); - return r->current_hartid; -} - -void riscv_set_all_rtos_harts(struct target *target) -{ - RISCV_INFO(r); - r->rtos_hartid = -1; -} - -void riscv_set_rtos_hartid(struct target *target, int hartid) -{ - RISCV_INFO(r); - r->rtos_hartid = hartid; -} - -int riscv_count_harts(struct target *target) -{ - return 3; -} - -bool riscv_has_register(struct target *target, int hartid, int regid) -{ - return 1; -} - -void riscv_set_register(struct target *target, int hartid, enum gdb_regno regid, uint64_t value) -{ - RISCV_INFO(r); - LOG_DEBUG("writing register %d on hart %d", regid, hartid); - return r->set_register(target, hartid, regid, value); -} - -uint64_t riscv_get_register(struct target *target, int hartid, enum gdb_regno regid) -{ - RISCV_INFO(r); - LOG_DEBUG("reading register %d on hart %d", regid, hartid); - return r->get_register(target, hartid, regid); -} - -bool riscv_is_halted(struct target *target) -{ - RISCV_INFO(r); - return r->is_halted(target); -} - -bool riscv_was_halted(struct target *target) -{ - RISCV_INFO(r); - assert(r->hart_state[r->current_hartid] != RISCV_HART_UNKNOWN); - return r->hart_state[r->current_hartid] == RISCV_HART_HALTED; -} - -enum riscv_halt_reason riscv_halt_reason(struct target *target, int hartid) -{ - RISCV_INFO(r); - riscv_set_current_hartid(target, hartid); - assert(riscv_is_halted(target)); - return r->halt_reason(target); -} diff --git a/src/target/riscv/riscv.h b/src/target/riscv/riscv.h deleted file mode 100644 index 7ce26228e..000000000 --- a/src/target/riscv/riscv.h +++ /dev/null @@ -1,177 +0,0 @@ -#ifndef RISCV_H -#define RISCV_H - -#include "opcodes.h" -#include "gdb_regs.h" - -/* The register cache is staticly allocated. */ -#define RISCV_MAX_HARTS 32 -#define RISCV_MAX_REGISTERS 5000 - -extern struct target_type riscv011_target; -extern struct target_type riscv013_target; - -/* - * Definitions shared by code supporting all RISC-V versions. - */ -typedef uint64_t riscv_reg_t; - -enum riscv_hart_state { - RISCV_HART_UNKNOWN, - RISCV_HART_HALTED, - RISCV_HART_RUNNING, -}; - -enum riscv_halt_reason { - RISCV_HALT_INTERRUPT, - RISCV_HALT_BREAKPOINT, - RISCV_HALT_SINGLESTEP, -}; - -typedef struct { - unsigned dtm_version; - struct command_context *cmd_ctx; - void *version_specific; - - /* When the RTOS is enabled this target is expected to handle all the - * harts in the system. When it's disabled this just uses the regular - * multi-target mode. */ - bool rtos_enabled; - - /* The hart that the RTOS thinks is currently being debugged. */ - int rtos_hartid; - - /* The hart that is currently being debugged. Note that this is - * different than the hartid that the RTOS is expected to use. This - * one will change all the time, it's more of a global argument to - * every function than an actual */ - int current_hartid; - - /* Enough space to store all the registers we might need to save. */ - /* FIXME: This should probably be a bunch of register caches. */ - uint64_t saved_registers[RISCV_MAX_HARTS][RISCV_MAX_REGISTERS]; - bool valid_saved_registers[RISCV_MAX_HARTS][RISCV_MAX_REGISTERS]; - - /* The register cache points into here. */ - uint64_t reg_cache_values[RISCV_MAX_REGISTERS]; - - /* It's possible that each core has a different supported ISA set. */ - int xlen[RISCV_MAX_HARTS]; - - /* The state of every hart. */ - enum riscv_hart_state hart_state[RISCV_MAX_HARTS]; - - /* Helper functions that target the various RISC-V debug spec - * implementations. */ - riscv_reg_t (*get_register)(struct target *, int, int); - void (*set_register)(struct target *, int, int, uint64_t); - void (*select_current_hart)(struct target *); - bool (*is_halted)(struct target *target); - void (*halt_current_hart)(struct target *); - void (*resume_current_hart)(struct target *target); - void (*step_current_hart)(struct target *target); - void (*on_halt)(struct target *target); - void (*on_resume)(struct target *target); - void (*on_step)(struct target *target); - enum riscv_halt_reason (*halt_reason)(struct target *target); -} riscv_info_t; - -/* Everything needs the RISC-V specific info structure, so here's a nice macro - * that provides that. */ -static inline riscv_info_t *riscv_info(const struct target *target) __attribute__((unused)); -static inline riscv_info_t *riscv_info(const struct target *target) -{ return target->arch_info; } -#define RISCV_INFO(R) riscv_info_t *R = riscv_info(target); - -extern uint8_t ir_dtmcontrol[1]; -extern struct scan_field select_dtmcontrol; -extern uint8_t ir_dbus[1]; -extern struct scan_field select_dbus; -extern uint8_t ir_idcode[1]; -extern struct scan_field select_idcode; - -/*** OpenOCD Interface */ -int riscv_openocd_poll(struct target *target); - -int riscv_openocd_halt(struct target *target); - -int riscv_openocd_resume( - struct target *target, - int current, - uint32_t address, - int handle_breakpoints, - int debug_execution -); - -int riscv_openocd_step( - struct target *target, - int current, - uint32_t address, - int handle_breakpoints -); - -/*** RISC-V Interface ***/ - -/* Initializes the shared RISC-V structure. */ -void riscv_info_init(riscv_info_t *r); - -/* Functions that save and restore registers. */ -void riscv_save_register(struct target *target, int regno); -uint64_t riscv_peek_register(struct target *target, int regno); -void riscv_overwrite_register(struct target *target, int regno, uint64_t newval); -void riscv_restore_register(struct target *target, int regno); - -/* Run control, possibly for multiple harts. The _all_harts versions resume - * all the enabled harts, which when running in RTOS mode is all the harts on - * the system. */ -int riscv_halt_all_harts(struct target *target); -int riscv_halt_one_hart(struct target *target, int hartid); -int riscv_resume_all_harts(struct target *target); -int riscv_resume_one_hart(struct target *target, int hartid); - -/* Steps the hart that's currently selected in the RTOS, or if there is no RTOS - * then the only hart. */ -int riscv_step_rtos_hart(struct target *target); - -/* Returns XLEN for the given (or current) hart. */ -int riscv_xlen(const struct target *target); -int riscv_xlen_of_hart(const struct target *target, int hartid); - -/* Enables RISC-V RTOS support for this target. This causes the coreid field - * of the generic target struct to be ignored, and instead for operations to - * apply to all the harts in the system. */ -void riscv_enable_rtos(struct target *target); -bool riscv_rtos_enabled(const struct target *target); - -/* Sets the current hart, which is the hart that will actually be used when - * issuing debug commands. */ -void riscv_set_current_hartid(struct target *target, int hartid); -int riscv_current_hartid(const struct target *target); - -/*** Support functions for the RISC-V 'RTOS', which provides multihart support - * without requiring multiple targets. */ - -/* When using the RTOS to debug, this selects the hart that is currently being - * debugged. This doesn't propogate to the hardware. */ -void riscv_set_all_rtos_harts(struct target *target); -void riscv_set_rtos_hartid(struct target *target, int hartid); - -/* Lists the number of harts in the system, which are assumed to be - * concecutive and start with mhartid=0. */ -int riscv_count_harts(struct target *target); - -/* Returns TRUE if the target has the given register on the given hart. */ -bool riscv_has_register(struct target *target, int hartid, int regid); - -/* Returns the value of the given register on the given hart. 32-bit registers - * are zero extended to 64 bits. */ -void riscv_set_register(struct target *target, int hid, enum gdb_regno rid, uint64_t v); -riscv_reg_t riscv_get_register(struct target *target, int hid, enum gdb_regno rid); - -/* Checks the state of the current hart -- "is_halted" checks the actual - * on-device register, while "was_halted" checks the machine's state. */ -bool riscv_is_halted(struct target *target); -bool riscv_was_halted(struct target *target); -enum riscv_halt_reason riscv_halt_reason(struct target *target, int hartid); - -#endif diff --git a/src/target/smp.c b/src/target/smp.c deleted file mode 100644 index 3dc6f6d5b..000000000 --- a/src/target/smp.c +++ /dev/null @@ -1,97 +0,0 @@ -/*************************************************************************** - * * - * Copyright (C) ST-Ericsson SA 2011 * - * Author: Michel Jaouen for ST-Ericsson. * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "server/server.h" - -#include "target/target.h" - -#include "server/gdb_server.h" -#include "smp.h" -#include "helper/binarybuffer.h" - -/* implementation of new packet in gdb interface for smp feature */ -/* */ -/* j : smp status request */ -/* J : smp set request */ -/* */ -/* jc :read core id displayed by gdb connection */ -/* reply XXXXXXXX core id is int32_t , 8 hex digits */ -/* */ -/* Reply ENN error not supported (target not smp) */ -/* */ -/* JcXX set core id displayed at next gdb continue */ -/* maximum 8 bytes described core id int32_t (8 hex digits) */ -/* (core id -1 , reserved for returning to normal continue mode) */ -/* Reply ENN error not supported(target not smp,core id out of range) */ -/* Reply OK : for success */ -/* */ -/* handling of this packet within gdb can be done by the creation */ -/* internal variable by mean of function allocate_computed_value */ -/* set $_core 1 => Jc01 packet is sent */ -/* print $_core => jc packet is sent and result is affected in $ */ -/* Another way to test this packet is the usage of maintenance packet */ -/* maint packet Jc01 */ -/* maint packet jc */ - -/* packet j :smp status request */ -int gdb_read_smp_packet(struct connection *connection, - char const *packet, int packet_size) -{ - struct target *target = get_target_from_connection(connection); - int retval = ERROR_OK; - if (target->smp) { - if (strncmp(packet, "jc", 2) == 0) { - const uint32_t len = sizeof(target->gdb_service->core[0]); - char hex_buffer[len * 2 + 1]; - uint8_t buffer[len]; - buf_set_u32(buffer, 0, len * 8, target->gdb_service->core[0]); - int pkt_len = hexify(hex_buffer, (char *)buffer, sizeof(buffer), sizeof(hex_buffer)); - - retval = gdb_put_packet(connection, hex_buffer, pkt_len); - } - } else - retval = gdb_put_packet(connection, "E01", 3); - return retval; -} - -/* J : smp set request */ -int gdb_write_smp_packet(struct connection *connection, - char const *packet, int packet_size) -{ - struct target *target = get_target_from_connection(connection); - char *separator; - int coreid = 0; - int retval = ERROR_OK; - - /* skip command character */ - if (target->smp) { - if (strncmp(packet, "Jc", 2) == 0) { - packet += 2; - coreid = strtoul(packet, &separator, 16); - target->gdb_service->core[1] = coreid; - retval = gdb_put_packet(connection, "OK", 2); - } - } else - retval = gdb_put_packet(connection, "E01", 3); - - return retval; -} diff --git a/src/target/smp.h b/src/target/smp.h deleted file mode 100644 index c3e6c6cea..000000000 --- a/src/target/smp.h +++ /dev/null @@ -1,29 +0,0 @@ -/*************************************************************************** - * * - * Copyright (C) ST-Ericsson SA 2011 * - * Author: Michel Jaouen for ST-Ericsson. * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifndef OPENOCD_TARGET_SMP_H -#define OPENOCD_TARGET_SMP_H - -#include "server/server.h" - -int gdb_read_smp_packet(struct connection *connection, - char const *packet, int packet_size); -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 deleted file mode 100644 index cf2813ba8..000000000 --- a/src/target/startup.tcl +++ /dev/null @@ -1,210 +0,0 @@ -# Defines basic Tcl procs for OpenOCD target module - -proc new_target_name { } { - return [target number [expr [target count] - 1 ]] -} - -global in_process_reset -set in_process_reset 0 - -# Catch reset recursion -proc ocd_process_reset { MODE } { - global in_process_reset - if {$in_process_reset} { - set in_process_reset 0 - return -code error "'reset' can not be invoked recursively" - } - - set in_process_reset 1 - set success [expr [catch {ocd_process_reset_inner $MODE} result]==0] - set in_process_reset 0 - - if {$success} { - return $result - } else { - return -code error $result - } -} - -proc ocd_process_reset_inner { MODE } { - set targets [target names] - - # If this target must be halted... - set halt -1 - if { 0 == [string compare $MODE halt] } { - set halt 1 - } - if { 0 == [string compare $MODE init] } { - set halt 1; - } - if { 0 == [string compare $MODE run ] } { - set halt 0; - } - if { $halt < 0 } { - return -code error "Invalid mode: $MODE, must be one of: halt, init, or run"; - } - - # Target event handlers *might* change which TAPs are enabled - # or disabled, so we fire all of them. But don't issue any - # target "arp_*" commands, which may issue JTAG transactions, - # unless we know the underlying TAP is active. - # - # NOTE: ARP == "Advanced Reset Process" ... "advanced" is - # relative to a previous restrictive scheme - - foreach t $targets { - # New event script. - $t invoke-event reset-start - } - - # Use TRST or TMS/TCK operations to reset all the tap controllers. - # TAP reset events get reported; they might enable some taps. - init_reset $MODE - - # Examine all targets on enabled taps. - foreach t $targets { - if {![using_jtag] || [jtag tapisenabled [$t cget -chain-position]]} { - $t invoke-event examine-start - set err [catch "$t arp_examine"] - if { $err == 0 } { - $t invoke-event examine-end - } - } - } - - # Assert SRST, and report the pre/post events. - # Note: no target sees SRST before "pre" or after "post". - foreach t $targets { - $t invoke-event reset-assert-pre - } - foreach t $targets { - # C code needs to know if we expect to 'halt' - if {![using_jtag] || [jtag tapisenabled [$t cget -chain-position]]} { - $t arp_reset assert $halt - } - } - foreach t $targets { - $t invoke-event reset-assert-post - } - - # Now de-assert SRST, and report the pre/post events. - # Note: no target sees !SRST before "pre" or after "post". - foreach t $targets { - $t invoke-event reset-deassert-pre - } - foreach t $targets { - # Again, de-assert code needs to know if we 'halt' - if {![using_jtag] || [jtag tapisenabled [$t cget -chain-position]]} { - $t arp_reset deassert $halt - } - } - foreach t $targets { - $t invoke-event reset-deassert-post - } - - # Pass 1 - Now wait for any halt (requested as part of reset - # assert/deassert) to happen. Ideally it takes effect without - # first executing any instructions. - if { $halt } { - foreach t $targets { - if {[using_jtag] && ![jtag tapisenabled [$t cget -chain-position]]} { - 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 - # to charge - - # Catch, but ignore any errors. - catch { $t arp_waitstate halted 1000 } - - # Did we succeed? - set s [$t curstate] - - if { 0 != [string compare $s "halted" ] } { - return -code error [format "TARGET: %s - Not halted" $t] - } - } - } - - #Pass 2 - if needed "init" - if { 0 == [string compare init $MODE] } { - foreach t $targets { - if {[using_jtag] && ![jtag tapisenabled [$t cget -chain-position]]} { - continue - } - - set err [catch "$t arp_waitstate halted 5000"] - # Did it halt? - if { $err == 0 } { - $t invoke-event reset-init - } - } - } - - foreach t $targets { - $t invoke-event reset-end - } -} - -proc using_jtag {} { - set _TRANSPORT [ transport select ] - expr { [ string first "jtag" $_TRANSPORT ] != -1 } -} - -proc using_swd {} { - set _TRANSPORT [ transport select ] - expr { [ string first "swd" $_TRANSPORT ] != -1 } -} - -proc using_hla {} { - set _TRANSPORT [ transport select ] - expr { [ string first "hla" $_TRANSPORT ] != -1 } -} - -######### - -# Temporary migration aid. May be removed starting in January 2011. -proc armv4_5 params { - echo "DEPRECATED! use 'arm $params' not 'armv4_5 $params'" - arm $params -} - -# Target/chain configuration scripts can either execute commands directly -# or define a procedure which is executed once all configuration -# scripts have completed. -# -# By default(classic) the config scripts will set up the target configuration -proc init_targets {} { -} - -proc set_default_target_event {t e s} { - if {[$t cget -event $e] == ""} { - $t configure -event $e $s - } -} - -proc init_target_events {} { - set targets [target names] - - foreach t $targets { - set_default_target_event $t gdb-flash-erase-start "reset init" - set_default_target_event $t gdb-flash-write-end "reset halt" - } -} - -# Additionally board config scripts can define a procedure init_board that will be executed after init and init_targets -proc init_board {} { -} - -# deprecated target name cmds -proc cortex_m3 args { - echo "DEPRECATED! use 'cortex_m' not 'cortex_m3'" - eval cortex_m $args -} - -proc cortex_a8 args { - echo "DEPRECATED! use 'cortex_a' not 'cortex_a8'" - eval cortex_a $args -} diff --git a/src/target/target.c b/src/target/target.c deleted file mode 100644 index 42a8caca8..000000000 --- a/src/target/target.c +++ /dev/null @@ -1,6228 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * Copyright (C) 2007-2010 Øyvind Harboe * - * oyvind.harboe@zylin.com * - * * - * Copyright (C) 2008, Duane Ellis * - * openocd@duaneeellis.com * - * * - * Copyright (C) 2008 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * Copyright (C) 2008 by Rick Altherr * - * kc8apf@kc8apf.net> * - * * - * Copyright (C) 2011 by Broadcom Corporation * - * Evan Hunter - ehunter@broadcom.com * - * * - * Copyright (C) ST-Ericsson SA 2011 * - * michel.jaouen@stericsson.com : smp minimum support * - * * - * Copyright (C) 2011 Andreas Fritiofson * - * andreas.fritiofson@gmail.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include - -#include "target.h" -#include "target_type.h" -#include "target_request.h" -#include "breakpoints.h" -#include "register.h" -#include "trace.h" -#include "image.h" -#include "rtos/rtos.h" -#include "transport/transport.h" - -/* 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_array2mem(Jim_Interp *interp, struct target *target, - int argc, Jim_Obj * const *argv); -static int target_mem2array(Jim_Interp *interp, struct target *target, - 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); -static int target_gdb_fileio_end_default(struct target *target, int retcode, - 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); - -/* targets */ -extern struct target_type arm7tdmi_target; -extern struct target_type arm720t_target; -extern struct target_type arm9tdmi_target; -extern struct target_type arm920t_target; -extern struct target_type arm966e_target; -extern struct target_type arm946e_target; -extern struct target_type arm926ejs_target; -extern struct target_type fa526_target; -extern struct target_type feroceon_target; -extern struct target_type dragonite_target; -extern struct target_type xscale_target; -extern struct target_type cortexm_target; -extern struct target_type cortexa_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; -extern struct target_type dsp5680xx_target; -extern struct target_type testee_target; -extern struct target_type avr32_ap7k_target; -extern struct target_type hla_target; -extern struct target_type nds32_v2_target; -extern struct target_type nds32_v3_target; -extern struct target_type nds32_v3m_target; -extern struct target_type or1k_target; -extern struct target_type quark_x10xx_target; -extern struct target_type quark_d20xx_target; -extern struct target_type riscv_target; - -static struct target_type *target_types[] = { - &arm7tdmi_target, - &arm9tdmi_target, - &arm920t_target, - &arm720t_target, - &arm966e_target, - &arm946e_target, - &arm926ejs_target, - &fa526_target, - &feroceon_target, - &dragonite_target, - &xscale_target, - &cortexm_target, - &cortexa_target, - &cortexr4_target, - &arm11_target, - &ls1_sap_target, - &mips_m4k_target, - &avr_target, - &dsp563xx_target, - &dsp5680xx_target, - &testee_target, - &avr32_ap7k_target, - &hla_target, - &nds32_v2_target, - &nds32_v3_target, - &nds32_v3m_target, - &or1k_target, - &quark_x10xx_target, - &quark_d20xx_target, - &riscv_target, - NULL, -}; - -struct target *all_targets; -static struct target_event_callback *target_event_callbacks; -static struct target_timer_callback *target_timer_callbacks; -LIST_HEAD(target_reset_callback_list); -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 } -}; - -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 } -}; - -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; -} - -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 } -}; - -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 }, -}; - -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 }, -}; - -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 }, -}; - -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 }, -}; - -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 *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 *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 *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; -} - -/* 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; -} - -/* 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); -} - -/* 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); -} - -/* 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); -} - -/* 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); -} - -/* 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; -} - -/* 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); -} - -/* 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); -} - -/* 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); -} - -/* 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); -} - -/* 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; -} - -/* 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]); -} - -/* 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]); -} - -/* 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]); -} - -/* 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]); -} - -/* 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]); -} - -/* 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]); -} - -/* 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; -} - -/* 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 *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; -} - -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 { - 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; -} - -/** - * Make the target (re)start executing using its saved execution - * context (possibly with some modifications). - * - * @param target Which target should start executing. - * @param current True to use the target's saved program counter instead - * of the address parameter - * @param address Optionally used as the program counter. - * @param handle_breakpoints True iff breakpoints at the resumption PC - * should be skipped. (For example, maybe execution was stopped by - * such a breakpoint, in which case it would be counterprodutive to - * let it re-trigger. - * @param debug_execution False if all working areas allocated by OpenOCD - * should be released and/or restored to their original contents. - * (This would for example be true to run some downloaded "helper" - * algorithm code, which resides in one such working buffer and uses - * another for data storage.) - * - * @todo Resolve the ambiguity about what the "debug_execution" flag - * signifies. For example, Target implementations don't agree on how - * it relates to invalidation of the register cache, or to whether - * breakpoints and watchpoints should be enabled. (It would seem wrong - * to enable breakpoints when running downloaded "helper" algorithms - * (debug_execution true), since the breakpoints would be set to match - * target firmware being debugged, not the helper algorithm.... and - * enabling them could cause such helpers to malfunction (for example, - * by overwriting data with a breakpoint instruction. On the other - * 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; -} - -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; -} - -static int identity_virt2phys(struct target *target, - uint32_t virtual, uint32_t *physical) -{ - *physical = virtual; - return ERROR_OK; -} - -static int no_mmu(struct target *target, int *enabled) -{ - *enabled = 0; - return ERROR_OK; -} - -static int default_examine(struct target *target) -{ - target_set_examined(target); - return ERROR_OK; -} - -/* no check by default */ -static int default_check_reset(struct target *target) -{ - 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; -} - -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); -} - -/* Targets that correctly implement init + examine, i.e. - * no communication with target during init: - * - * XScale - */ -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; -} - -const char *target_type_name(struct target *target) -{ - 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); -} - -/** - * Downloads a target-specific native code algorithm to the target, - * and executes it. * Note that some targets may need to set up, enable, - * and tear down a breakpoint (hard or * soft) to detect algorithm - * termination, while others may support lower overhead schemes where - * soft breakpoints embedded in the algorithm automatically terminate the - * algorithm. - * - * @param target used to run the algorithm - * @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; - -done: - return retval; -} - -/** - * Downloads a target-specific native code algorithm to the target, - * executes and leaves it running. - * - * @param target used to run the algorithm - * @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); - -done: - return retval; -} - -/** - * Waits for an algorithm started with target_start_algorithm() to complete. - * - * @param target used to run the algorithm - * @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; - -done: - return retval; -} - -/** - * Executes a target-specific native code algorithm in the target. - * It differs from target_run_algorithm in that the algorithm is asynchronous. - * Because of this it requires an compliant algorithm: - * see contrib/loaders/flash/stm32f1x.S for example. - * - * @param target used to run the algorithm - */ - -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; - } - - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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); -} - -int target_add_context_breakpoint(struct target *target, - 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); -} - -int target_add_hybrid_breakpoint(struct target *target, - 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); -} - -int target_remove_breakpoint(struct target *target, - struct breakpoint *breakpoint) -{ - return target->type->remove_breakpoint(target, breakpoint); -} - -int target_add_watchpoint(struct target *target, - 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); -} -int target_remove_watchpoint(struct target *target, - struct watchpoint *watchpoint) -{ - return target->type->remove_watchpoint(target, watchpoint); -} -int target_hit_watchpoint(struct target *target, - 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); -} - -int target_get_gdb_reg_list(struct target *target, - 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); -} -int target_step(struct target *target, - int current, uint32_t address, int 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); -} - -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); -} - -int target_profiling(struct target *target, uint32_t *samples, - 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); -} - -/** - * Reset the @c examined flag for the given target. - * Pure paranoia -- targets are zeroed on allocation. - */ -static void target_reset_examined(struct target *target) -{ - 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; -} - -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; -} - -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 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; -} - -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; -} - -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; -} - -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; -} - -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; -} - -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; -} - -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; -} - -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; -} - -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; -} - -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; -} - -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; -} - -static int target_timer_callback_periodic_restart( - 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; -} - -static int target_call_timer_callback(struct target_timer_callback *cb, - 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); -} - -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; -} - -int target_call_timer_callbacks(void) -{ - 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); -} - -/* 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; - } -} - -/* 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; - } - } -} - -/* 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; - } - } -} - -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; -} - -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; - -} - -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; -} - -/* 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 target_free_working_area(struct target *target, struct working_area *area) -{ - return target_free_working_area_restore(target, area, 1); -} - -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); - } -} - -/* free resources and restore memory, if restoring memory fails, - * free up resources anyway - */ -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); -} - -void target_free_all_working_areas(struct target *target) -{ - 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; -} - -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; - - 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) -{ - /* 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) -{ - 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; -} - -/* 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; -} - -/* 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; -} - -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; -} - - -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; -} - -/* every 300ms we check for reset & powerdropout and issue a "reset halt" if so. */ - -static int powerDropout; -static int srstAsserted; - -static int runPowerRestore; -static int runPowerDropout; -static int runSrstAsserted; -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; - - 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; -} - -COMMAND_HANDLER(handle_reg_command) -{ - struct target *target; - struct reg *reg = NULL; - unsigned count = 0; - char *value; - int retval; - - 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) { - retval = reg->type->get(reg); - if (retval != ERROR_OK) { - LOG_DEBUG("Couldn't get register %s.", reg->name); - return retval; - } - } - 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); - - retval = reg->type->set(reg, buf); - if (retval != ERROR_OK) { - LOG_DEBUG("Couldn't set register %s.", reg->name); - free (buf); - return retval; - } - - 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; -} - -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); -} - -/* wait for target state to change. The trick here is to have a low - * latency for short waits and not to suck up all the CPU time - * on longer waits. - * - * After 500ms, keep_alive() is invoked - */ -int target_wait_state(struct target *target, enum target_state state, int ms) -{ - 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); -} - -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; -} - -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); -} - - -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); -} - -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); -} - -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; - } - } -} - -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; -} - -typedef int (*target_write_fn)(struct target *target, - uint32_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; -} - - -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); -} - -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; -} - -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; - -} - -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)); - } - - image_close(&image); - - return retval; -} - -COMMAND_HANDLER(handle_verify_image_command) -{ - return CALL_COMMAND_HANDLER(handle_verify_image_command_internal, 1); -} - -COMMAND_HANDLER(handle_test_image_command) -{ - return CALL_COMMAND_HANDLER(handle_verify_image_command_internal, 0); -} - -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; -} - -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; -} - -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; - } -} - -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; -} - -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; -} - -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; -} - -/** - * Translate a virtual address to a physical address. - * - * The low-level target implementation must have logged a detailed error - * which is forwarded to telnet/GDB session. - */ -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; -} - -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)); -} - -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); -} - -static void writeString(FILE *f, char *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); -} - -/* 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; -} - -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; -} - -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); -} - -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; - 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%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; -} - -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; -} - -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); -} - -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; - 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%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; - - 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%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; -} - -/* FIX? should we propagate errors here rather than printing them - * and continuing? - */ -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)); - } - } - } -} - -/** - * Returns true only if the target has a handler for the specified event. - */ -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; -} - -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, -}; - -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 } -}; - -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; -} - -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->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; - 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 = 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; - 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 = "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); -} diff --git a/src/target/target.h b/src/target/target.h deleted file mode 100644 index 0cee1170f..000000000 --- a/src/target/target.h +++ /dev/null @@ -1,686 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * Copyright (C) 2007-2010 Øyvind Harboe * - * oyvind.harboe@zylin.com * - * * - * Copyright (C) 2008 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * Copyright (C) 2011 by Broadcom Corporation * - * Evan Hunter - ehunter@broadcom.com * - * * - * Copyright (C) ST-Ericsson SA 2011 * - * michel.jaouen@stericsson.com : smp minimum support * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifndef OPENOCD_TARGET_TARGET_H -#define OPENOCD_TARGET_TARGET_H - -#include - -struct reg; -struct trace; -struct command_context; -struct breakpoint; -struct watchpoint; -struct mem_param; -struct reg_param; -struct target_list; -struct gdb_fileio_info; - -/* - * TARGET_UNKNOWN = 0: we don't know anything about the target yet - * TARGET_RUNNING = 1: the target is executing user code - * TARGET_HALTED = 2: the target is not executing code, and ready to talk to the - * debugger. on an xscale it means that the debug handler is executing - * TARGET_RESET = 3: the target is being held in reset (only a temporary state, - * not sure how this is used with all the recent changes) - * TARGET_DEBUG_RUNNING = 4: the target is running, but it is executing code on - * behalf of the debugger (e.g. algorithm for flashing) - * - * also see: target_state_name(); - */ - -enum target_state { - TARGET_UNKNOWN = 0, - TARGET_RUNNING = 1, - TARGET_HALTED = 2, - TARGET_RESET = 3, - TARGET_DEBUG_RUNNING = 4, -}; - -enum nvp_assert { - NVP_DEASSERT, - NVP_ASSERT, -}; - -enum target_reset_mode { - RESET_UNKNOWN = 0, - RESET_RUN = 1, /* reset and let target run */ - RESET_HALT = 2, /* reset and halt target out of reset */ - RESET_INIT = 3, /* reset and halt target out of reset, then run init script */ -}; - -enum target_debug_reason { - DBG_REASON_DBGRQ = 0, - DBG_REASON_BREAKPOINT = 1, - DBG_REASON_WATCHPOINT = 2, - DBG_REASON_WPTANDBKPT = 3, - DBG_REASON_SINGLESTEP = 4, - DBG_REASON_NOTHALTED = 5, - DBG_REASON_EXIT = 6, - DBG_REASON_UNDEFINED = 7, -}; - -enum target_endianness { - TARGET_ENDIAN_UNKNOWN = 0, - TARGET_BIG_ENDIAN = 1, TARGET_LITTLE_ENDIAN = 2 -}; - -struct working_area { - uint32_t address; - uint32_t size; - bool free; - uint8_t *backup; - struct working_area **user; - struct working_area *next; -}; - -struct gdb_service { - struct target *target; - /* field for smp display */ - /* element 0 coreid currently displayed ( 1 till n) */ - /* element 1 coreid to be displayed at next resume 1 till n 0 means resume - * all cores core displayed */ - int32_t core[2]; -}; - -/* target back off timer */ -struct backoff_timer { - int times; - int count; -}; - -/* split target registers into multiple class */ -enum target_register_class { - REG_CLASS_ALL, - REG_CLASS_GENERAL, -}; - -/* 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 */ - 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? */ - - /** - * Indicates whether this target has been examined. - * - * Do @b not access this field directly, use target_was_examined() - * or target_set_examined(). - */ - bool examined; - - /** - * true if the target is currently running a downloaded - * "algorithm" instead of arbitrary user code. OpenOCD code - * invoking algorithms is trusted to maintain correctness of - * any cached state (e.g. for flash status), which arbitrary - * code will have no reason to know about. - */ - bool running_alg; - - struct target_event_action *event_action; - - int reset_halt; /* attempt resetting the CPU into the halted mode? */ - 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 */ - 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 */ - enum target_debug_reason debug_reason;/* reason why the target entered debug state */ - enum target_endianness endianness; /* target endianness */ - /* also see: target_state_name() */ - enum target_state state; /* the current backend-state (running, halted, ...) */ - struct reg_cache *reg_cache; /* the first register cache of the target (core regs) */ - struct breakpoint *breakpoints; /* list of breakpoints */ - struct watchpoint *watchpoints; /* list of watchpoints */ - struct trace *trace_info; /* generic trace information */ - struct debug_msg_receiver *dbgmsg; /* list of debug message receivers */ - uint32_t dbg_msg_enabled; /* debug message status */ - void *arch_info; /* architecture specific information */ - 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? */ - 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. */ - 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 */ - struct backoff_timer backoff; - int smp; /* add some target attributes for smp support */ - struct target_list *head; - /* the gdb service is there in case of smp, we have only one gdb server - * for all smp target - * the target attached to the gdb is changing dynamically by changing - * gdb_service->target pointer */ - struct gdb_service *gdb_service; - - /* file-I/O information for host to do syscall */ - struct gdb_fileio_info *fileio_info; -}; - -struct target_list { - struct target *target; - struct target_list *next; -}; - -struct gdb_fileio_info { - char *identifier; - uint32_t param_1; - uint32_t param_2; - uint32_t param_3; - uint32_t param_4; -}; - -/** Returns the instance-specific name of the specified target. */ -static inline const char *target_name(struct target *target) -{ - return target->cmd_name; -} - -const char *debug_reason_name(struct target *t); - -enum target_event { - - /* allow GDB to do stuff before others handle the halted event, - * this is in lieu of defining ordering of invocation of events, - * which would be more complicated - * - * Telling GDB to halt does not mean that the target stopped running, - * simply that we're dropping out of GDB's waiting for step or continue. - * - * This can be useful when e.g. detecting power dropout. - */ - TARGET_EVENT_GDB_HALT, - TARGET_EVENT_HALTED, /* target entered debug state from normal execution or reset */ - TARGET_EVENT_RESUMED, /* target resumed to normal execution */ - TARGET_EVENT_RESUME_START, - TARGET_EVENT_RESUME_END, - - TARGET_EVENT_GDB_START, /* debugger started execution (step/run) */ - TARGET_EVENT_GDB_END, /* debugger stopped execution (step/run) */ - - TARGET_EVENT_RESET_START, - TARGET_EVENT_RESET_ASSERT_PRE, - TARGET_EVENT_RESET_ASSERT, /* C code uses this instead of SRST */ - TARGET_EVENT_RESET_ASSERT_POST, - TARGET_EVENT_RESET_DEASSERT_PRE, - TARGET_EVENT_RESET_DEASSERT_POST, - TARGET_EVENT_RESET_HALT_PRE, - TARGET_EVENT_RESET_HALT_POST, - TARGET_EVENT_RESET_WAIT_PRE, - TARGET_EVENT_RESET_WAIT_POST, - TARGET_EVENT_RESET_INIT, - TARGET_EVENT_RESET_END, - - TARGET_EVENT_DEBUG_HALTED, /* target entered debug state, but was executing on behalf of the debugger */ - TARGET_EVENT_DEBUG_RESUMED, /* target resumed to execute on behalf of the debugger */ - - TARGET_EVENT_EXAMINE_START, - TARGET_EVENT_EXAMINE_END, - - TARGET_EVENT_GDB_ATTACH, - TARGET_EVENT_GDB_DETACH, - - TARGET_EVENT_GDB_FLASH_ERASE_START, - TARGET_EVENT_GDB_FLASH_ERASE_END, - TARGET_EVENT_GDB_FLASH_WRITE_START, - TARGET_EVENT_GDB_FLASH_WRITE_END, - - TARGET_EVENT_TRACE_CONFIG, -}; - -struct target_event_action { - enum target_event event; - struct Jim_Interp *interp; - struct Jim_Obj *body; - int has_percent; - struct target_event_action *next; -}; - -bool target_has_event_action(struct target *target, enum target_event event); - -struct target_event_callback { - int (*callback)(struct target *target, enum target_event event, void *priv); - void *priv; - struct target_event_callback *next; -}; - -struct target_reset_callback { - struct list_head list; - void *priv; - int (*callback)(struct target *target, enum target_reset_mode reset_mode, void *priv); -}; - -struct target_trace_callback { - struct list_head list; - void *priv; - int (*callback)(struct target *target, size_t len, uint8_t *data, void *priv); -}; - -struct target_timer_callback { - int (*callback)(void *priv); - int time_ms; - int periodic; - bool removed; - struct timeval when; - void *priv; - struct target_timer_callback *next; -}; - -int target_register_commands(struct command_context *cmd_ctx); -int target_examine(void); - -int target_register_event_callback( - int (*callback)(struct target *target, - enum target_event event, void *priv), - void *priv); -int target_unregister_event_callback( - int (*callback)(struct target *target, - enum target_event event, void *priv), - void *priv); - -int target_register_reset_callback( - int (*callback)(struct target *target, - enum target_reset_mode reset_mode, void *priv), - void *priv); -int target_unregister_reset_callback( - int (*callback)(struct target *target, - enum target_reset_mode reset_mode, void *priv), - void *priv); - -int target_register_trace_callback( - int (*callback)(struct target *target, - size_t len, uint8_t *data, void *priv), - void *priv); -int target_unregister_trace_callback( - int (*callback)(struct target *target, - size_t len, uint8_t *data, void *priv), - void *priv); - -/* Poll the status of the target, detect any error conditions and report them. - * - * Also note that this fn will clear such error conditions, so a subsequent - * invocation will then succeed. - * - * These error conditions can be "sticky" error conditions. E.g. writing - * to memory could be implemented as an open loop and if memory writes - * fails, then a note is made of it, the error is sticky, but the memory - * write loop still runs to completion. This improves performance in the - * normal case as there is no need to verify that every single write succeed, - * 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 handle_breakpoints, int debug_execution); -int target_halt(struct target *target); -int target_call_event_callbacks(struct target *target, enum target_event event); -int target_call_reset_callbacks(struct target *target, enum target_reset_mode reset_mode); -int target_call_trace_callbacks(struct target *target, size_t len, uint8_t *data); - -/** - * The period is very approximate, the callback can happen much more often - * or much more rarely than specified - */ -int target_register_timer_callback(int (*callback)(void *priv), - int time_ms, int periodic, void *priv); -int target_unregister_timer_callback(int (*callback)(void *priv), void *priv); -int target_call_timer_callbacks(void); -/** - * Invoke this to ensure that e.g. polling timer callbacks happen before - * a synchronous command completes. - */ -int target_call_timer_callbacks_now(void); - -struct target *get_target_by_num(int num); -struct target *get_current_target(struct command_context *cmd_ctx); -struct target *get_target(const char *id); - -/** - * Get the target type name. - * - * This routine is a wrapper for the target->type->name field. - * Note that this is not an instance-specific name for his target. - */ -const char *target_type_name(struct target *target); - -/** - * Examine the specified @a target, letting it perform any - * Initialisation that requires JTAG access. - * - * This routine is a wrapper for target->type->examine. - */ -int target_examine_one(struct target *target); - -/** @returns @c true if target_set_examined() has been called. */ -static inline bool target_was_examined(struct target *target) -{ - return target->examined; -} - -/** Sets the @c examined flag for the given target. */ -/** Use in target->type->examine() after one-time setup is done. */ -static inline void target_set_examined(struct target *target) -{ - target->examined = true; -} - -/** - * Add the @a breakpoint for @a target. - * - * This routine is a wrapper for target->type->add_breakpoint. - */ -int target_add_breakpoint(struct target *target, - struct breakpoint *breakpoint); -/** - * Add the @a ContextID breakpoint for @a target. - * - * This routine is a wrapper for target->type->add_context_breakpoint. - */ -int target_add_context_breakpoint(struct target *target, - struct breakpoint *breakpoint); -/** - * Add the @a ContextID & IVA breakpoint for @a target. - * - * This routine is a wrapper for target->type->add_hybrid_breakpoint. - */ -int target_add_hybrid_breakpoint(struct target *target, - struct breakpoint *breakpoint); -/** - * Remove the @a breakpoint for @a target. - * - * This routine is a wrapper for target->type->remove_breakpoint. - */ - -int target_remove_breakpoint(struct target *target, - struct breakpoint *breakpoint); -/** - * Add the @a watchpoint for @a target. - * - * This routine is a wrapper for target->type->add_watchpoint. - */ -int target_add_watchpoint(struct target *target, - struct watchpoint *watchpoint); -/** - * Remove the @a watchpoint for @a target. - * - * This routine is a wrapper for target->type->remove_watchpoint. - */ -int target_remove_watchpoint(struct target *target, - struct watchpoint *watchpoint); - -/** - * Find out the just hit @a watchpoint for @a target. - * - * This routine is a wrapper for target->type->hit_watchpoint. - */ -int target_hit_watchpoint(struct target *target, - struct watchpoint **watchpoint); - -/** - * Obtain the registers for GDB. - * - * This routine is a wrapper for target->type->get_gdb_reg_list. - */ -int target_get_gdb_reg_list(struct target *target, - struct reg **reg_list[], int *reg_list_size, - enum target_register_class reg_class); - -/** - * Step the target. - * - * This routine is a wrapper for target->type->step. - */ -int target_step(struct target *target, - int current, uint32_t address, int handle_breakpoints); -/** - * Run an algorithm on the @a target given. - * - * This routine is a wrapper for target->type->run_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); - -/** - * Starts an algorithm in the background on the @a target given. - * - * This routine is a wrapper for target->type->start_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); - -/** - * Wait for an algorithm on the @a target given. - * - * This routine is a wrapper for target->type->wait_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); - -/** - * This routine is a wrapper for asynchronous algorithms. - * - */ -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); - -/** - * Read @a count items of @a size bytes from the memory of @a target at - * the @a address given. - * - * 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); -int target_read_phys_memory(struct target *target, - uint32_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 - * in target memory. - * - * The endianness is the same in the host and target memory for this - * function. - * - * \todo TODO: - * Really @a buffer should have been defined as "const void *" and - * @a buffer should have been aligned to @a size in the host memory. - * - * This is not enforced via e.g. assert's today and e.g. the - * target_write_buffer fn breaks this assumption. - * - * 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); -int target_write_phys_memory(struct target *target, - uint32_t address, uint32_t size, uint32_t count, const uint8_t *buffer); - -/* - * Write to target memory using the virtual address. - * - * Note that this fn is used to implement software breakpoints. Targets - * can implement support for software breakpoints to memory marked as read - * only by making this fn write to ram even if it is read only(MMU or - * MPUs). - * - * It is sufficient to implement for writing a single word(16 or 32 in - * ARM32/16 bit case) to write the breakpoint to ram. - * - * The target should also take care of "other things" to make sure that - * software breakpoints can be written using this function. E.g. - * when there is a separate instruction and data cache, this fn must - * make sure that the instruction cache is synced up to the potential - * code change that can happen as a result of the memory write(typically - * by invalidating the cache). - * - * The high level wrapper fn in target.c will break down this memory write - * request to multiple write requests to the target driver to e.g. guarantee - * that writing 4 bytes to an aligned address happens with a single 32 bit - * write operation, thus making this fn suitable to e.g. write to special - * 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); -int target_read_buffer(struct target *target, - uint32_t address, uint32_t size, uint8_t *buffer); -int target_checksum_memory(struct target *target, - uint32_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); -int target_wait_state(struct target *target, enum target_state state, int ms); - -/** - * Obtain file-I/O information from target for GDB to do syscall. - * - * This routine is a wrapper for target->type->get_gdb_fileio_info. - */ -int target_get_gdb_fileio_info(struct target *target, struct gdb_fileio_info *fileio_info); - -/** - * Pass GDB file-I/O response to target after finishing host syscall. - * - * This routine is a wrapper for target->type->gdb_fileio_end. - */ -int target_gdb_fileio_end(struct target *target, int retcode, int fileio_errno, bool ctrl_c); - - - -/** Return the *name* of this targets current state */ -const char *target_state_name(struct target *target); - -/** Return the *name* of a target event enumeration value */ -const char *target_event_name(enum target_event event); - -/** Return the *name* of a target reset reason enumeration value */ -const char *target_reset_mode_name(enum target_reset_mode reset_mode); - -/* DANGER!!!!! - * - * if "area" passed in to target_alloc_working_area() points to a memory - * location that goes out of scope (e.g. a pointer on the stack), then - * the caller of target_alloc_working_area() is responsible for invoking - * target_free_working_area() before "area" goes out of scope. - * - * target_free_all_working_areas() will NULL out the "area" pointer - * upon resuming or resetting the CPU. - * - */ -int target_alloc_working_area(struct target *target, - uint32_t size, struct working_area **area); -/* Same as target_alloc_working_area, except that no error is logged - * when ERROR_TARGET_RESOURCE_NOT_AVAILABLE is returned. - * - * This allows the calling code to *try* to allocate target memory - * and have a fallback to another behaviour(slower?). - */ -int target_alloc_working_area_try(struct target *target, - uint32_t size, struct working_area **area); -int target_free_working_area(struct target *target, struct working_area *area); -void target_free_all_working_areas(struct target *target); -uint32_t target_get_working_area_avail(struct target *target); - -/** - * Free all the resources allocated by targets and the target layer - */ -void target_quit(void); - -extern struct target *all_targets; - -uint64_t target_buffer_get_u64(struct target *target, const uint8_t *buffer); -uint32_t target_buffer_get_u32(struct target *target, const uint8_t *buffer); -uint32_t target_buffer_get_u24(struct target *target, const uint8_t *buffer); -uint16_t target_buffer_get_u16(struct target *target, const uint8_t *buffer); -void target_buffer_set_u64(struct target *target, uint8_t *buffer, uint64_t value); -void target_buffer_set_u32(struct target *target, uint8_t *buffer, uint32_t value); -void target_buffer_set_u24(struct target *target, uint8_t *buffer, uint32_t value); -void target_buffer_set_u16(struct target *target, uint8_t *buffer, uint16_t value); - -void target_buffer_get_u64_array(struct target *target, const uint8_t *buffer, uint32_t count, uint64_t *dstbuf); -void target_buffer_get_u32_array(struct target *target, const uint8_t *buffer, uint32_t count, uint32_t *dstbuf); -void target_buffer_get_u16_array(struct target *target, const uint8_t *buffer, uint32_t count, uint16_t *dstbuf); -void target_buffer_set_u64_array(struct target *target, uint8_t *buffer, uint32_t count, const uint64_t *srcbuf); -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); - -/* Issues USER() statements with target state information */ -int target_arch_state(struct target *target); - -void target_handle_event(struct target *t, enum target_event e); - -#define ERROR_TARGET_INVALID (-300) -#define ERROR_TARGET_INIT_FAILED (-301) -#define ERROR_TARGET_TIMEOUT (-302) -#define ERROR_TARGET_NOT_HALTED (-304) -#define ERROR_TARGET_FAILURE (-305) -#define ERROR_TARGET_UNALIGNED_ACCESS (-306) -#define ERROR_TARGET_DATA_ABORT (-307) -#define ERROR_TARGET_RESOURCE_NOT_AVAILABLE (-308) -#define ERROR_TARGET_TRANSLATION_FAULT (-309) -#define ERROR_TARGET_NOT_RUNNING (-310) -#define ERROR_TARGET_NOT_EXAMINED (-311) - -extern bool get_target_reset_nag(void); - -#endif /* OPENOCD_TARGET_TARGET_H */ diff --git a/src/target/target_request.c b/src/target/target_request.c deleted file mode 100644 index 6ca204b50..000000000 --- a/src/target/target_request.c +++ /dev/null @@ -1,315 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * Copyright (C) 2007,2008 Øyvind Harboe * - * oyvind.harboe@zylin.com * - * * - * Copyright (C) 2008 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 -#include "config.h" -#endif - -#include -#include - -#include "target.h" -#include "target_request.h" -#include "target_type.h" -#include "trace.h" - -static bool got_message; - -bool target_got_message(void) -{ - bool t = got_message; - got_message = false; - return t; -} - -static int charmsg_mode; - -static int target_asciimsg(struct target *target, uint32_t length) -{ - char *msg = malloc(DIV_ROUND_UP(length + 1, 4) * 4); - struct debug_msg_receiver *c = target->dbgmsg; - - target->type->target_request_data(target, DIV_ROUND_UP(length, 4), (uint8_t *)msg); - msg[length] = 0; - - LOG_DEBUG("%s", msg); - - while (c) { - command_print(c->cmd_ctx, "%s", msg); - c = c->next; - } - - return ERROR_OK; -} - -static int target_charmsg(struct target *target, uint8_t msg) -{ - LOG_USER_N("%c", msg); - - return ERROR_OK; -} - -static int target_hexmsg(struct target *target, int size, uint32_t length) -{ - uint8_t *data = malloc(DIV_ROUND_UP(length * size, 4) * 4); - char line[128]; - int line_len; - struct debug_msg_receiver *c = target->dbgmsg; - uint32_t i; - - LOG_DEBUG("size: %i, length: %i", (int)size, (int)length); - - target->type->target_request_data(target, DIV_ROUND_UP(length * size, 4), (uint8_t *)data); - - line_len = 0; - for (i = 0; i < length; i++) { - switch (size) { - case 4: - line_len += snprintf(line + line_len, 128 - line_len, "%8.8" PRIx32 " ", le_to_h_u32(data + (4*i))); - break; - case 2: - line_len += snprintf(line + line_len, 128 - line_len, "%4.4x ", le_to_h_u16(data + (2*i))); - break; - case 1: - line_len += snprintf(line + line_len, 128 - line_len, "%2.2x ", data[i]); - break; - } - - if ((i%8 == 7) || (i == length - 1)) { - LOG_DEBUG("%s", line); - - while (c) { - command_print(c->cmd_ctx, "%s", line); - c = c->next; - } - c = target->dbgmsg; - line_len = 0; - } - } - - free(data); - - return ERROR_OK; -} - -/* handle requests from the target received by a target specific - * side-band channel (e.g. ARM7/9 DCC) - */ -int target_request(struct target *target, uint32_t request) -{ - target_req_cmd_t target_req_cmd = request & 0xff; - - assert(target->type->target_request_data); - - /* Record that we got a target message for back-off algorithm */ - got_message = true; - - if (charmsg_mode) { - target_charmsg(target, target_req_cmd); - return ERROR_OK; - } - - switch (target_req_cmd) { - case TARGET_REQ_TRACEMSG: - trace_point(target, (request & 0xffffff00) >> 8); - break; - case TARGET_REQ_DEBUGMSG: - if (((request & 0xff00) >> 8) == 0) - target_asciimsg(target, (request & 0xffff0000) >> 16); - else - target_hexmsg(target, (request & 0xff00) >> 8, (request & 0xffff0000) >> 16); - break; - case TARGET_REQ_DEBUGCHAR: - target_charmsg(target, (request & 0x00ff0000) >> 16); - break; -/* case TARGET_REQ_SEMIHOSTING: - * break; - */ - default: - LOG_ERROR("unknown target request: %2.2x", target_req_cmd); - break; - } - - return ERROR_OK; -} - -static int add_debug_msg_receiver(struct command_context *cmd_ctx, struct target *target) -{ - struct debug_msg_receiver **p = &target->dbgmsg; - - if (target == NULL) - return ERROR_COMMAND_SYNTAX_ERROR; - - /* see if there's already a list */ - if (*p) { - /* find end of linked list */ - while ((*p)->next) - p = &((*p)->next); - p = &((*p)->next); - } - - /* add new debug message receiver */ - (*p) = malloc(sizeof(struct debug_msg_receiver)); - (*p)->cmd_ctx = cmd_ctx; - (*p)->next = NULL; - - /* enable callback */ - target->dbg_msg_enabled = 1; - - return ERROR_OK; -} - -static struct debug_msg_receiver *find_debug_msg_receiver(struct command_context *cmd_ctx, - struct target *target) -{ - int do_all_targets = 0; - - /* if no target has been specified search all of them */ - if (target == NULL) { - /* if no targets haven been specified */ - if (all_targets == NULL) - return NULL; - - target = all_targets; - do_all_targets = 1; - } - - /* so we target != null */ - struct debug_msg_receiver **p = &target->dbgmsg; - do { - while (*p) { - if ((*p)->cmd_ctx == cmd_ctx) - return *p; - p = &((*p)->next); - } - - target = target->next; - } while (target && do_all_targets); - - return NULL; -} - -int delete_debug_msg_receiver(struct command_context *cmd_ctx, struct target *target) -{ - struct debug_msg_receiver **p; - struct debug_msg_receiver *c; - int do_all_targets = 0; - - /* if no target has been specified search all of them */ - if (target == NULL) { - /* if no targets haven been specified */ - if (all_targets == NULL) - return ERROR_OK; - - target = all_targets; - do_all_targets = 1; - } - - do { - p = &target->dbgmsg; - c = *p; - while (c) { - struct debug_msg_receiver *next = c->next; - if (c->cmd_ctx == cmd_ctx) { - *p = next; - free(c); - if (*p == NULL) { - /* disable callback */ - target->dbg_msg_enabled = 0; - } - return ERROR_OK; - } else - p = &(c->next); - c = next; - } - - target = target->next; - } while (target && do_all_targets); - - return ERROR_OK; -} - -COMMAND_HANDLER(handle_target_request_debugmsgs_command) -{ - struct target *target = get_current_target(CMD_CTX); - - int receiving = 0; - - if (target->type->target_request_data == NULL) { - LOG_ERROR("Target %s does not support target requests", target_name(target)); - return ERROR_OK; - } - - /* see if reciever is already registered */ - if (find_debug_msg_receiver(CMD_CTX, target) != NULL) - receiving = 1; - - if (CMD_ARGC > 0) { - if (!strcmp(CMD_ARGV[0], "enable") || !strcmp(CMD_ARGV[0], "charmsg")) { - /* don't register if this command context is already receiving */ - if (!receiving) { - receiving = 1; - add_debug_msg_receiver(CMD_CTX, target); - } - charmsg_mode = !strcmp(CMD_ARGV[0], "charmsg"); - } else if (!strcmp(CMD_ARGV[0], "disable")) { - /* no need to delete a receiver if none is registered */ - if (receiving) { - receiving = 0; - delete_debug_msg_receiver(CMD_CTX, target); - } - } else - return ERROR_COMMAND_SYNTAX_ERROR; - } - - command_print(CMD_CTX, "receiving debug messages from current target %s", - (receiving) ? (charmsg_mode ? "charmsg" : "enabled") : "disabled"); - return ERROR_OK; -} - -static const struct command_registration target_req_exec_command_handlers[] = { - { - .name = "debugmsgs", - .handler = handle_target_request_debugmsgs_command, - .mode = COMMAND_EXEC, - .help = "display and/or modify reception of debug messages from target", - .usage = "['enable'|'charmsg'|'disable']", - }, - COMMAND_REGISTRATION_DONE -}; -static const struct command_registration target_req_command_handlers[] = { - { - .name = "target_request", - .mode = COMMAND_ANY, - .help = "target request command group", - .usage = "", - .chain = target_req_exec_command_handlers, - }, - COMMAND_REGISTRATION_DONE -}; - -int target_request_register_commands(struct command_context *cmd_ctx) -{ - return register_commands(cmd_ctx, NULL, target_req_command_handlers); -} diff --git a/src/target/target_request.h b/src/target/target_request.h deleted file mode 100644 index 1b1317338..000000000 --- a/src/target/target_request.h +++ /dev/null @@ -1,55 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * Copyright (C) 2007,2008 Øyvind Harboe * - * oyvind.harboe@zylin.com * - * * - * Copyright (C) 2008 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 OPENOCD_TARGET_TARGET_REQUEST_H -#define OPENOCD_TARGET_TARGET_REQUEST_H - -struct target; -struct command_context; - -typedef enum target_req_cmd { - TARGET_REQ_TRACEMSG, - TARGET_REQ_DEBUGMSG, - TARGET_REQ_DEBUGCHAR, -/* TARGET_REQ_SEMIHOSTING, */ -} target_req_cmd_t; - -struct debug_msg_receiver { - struct command_context *cmd_ctx; - struct debug_msg_receiver *next; -}; - -int target_request(struct target *target, uint32_t request); -int delete_debug_msg_receiver(struct command_context *cmd_ctx, - struct target *target); -int target_request_register_commands(struct command_context *cmd_ctx); -/** - * Read and clear the flag as to whether we got a message. - * - * This is used to implement the back-off algorithm on - * sleeping in idle mode. - */ -bool target_got_message(void); - -#endif /* OPENOCD_TARGET_TARGET_REQUEST_H */ diff --git a/src/target/target_type.h b/src/target/target_type.h deleted file mode 100644 index 95c0fef11..000000000 --- a/src/target/target_type.h +++ /dev/null @@ -1,280 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * Copyright (C) 2007-2010 Øyvind Harboe * - * oyvind.harboe@zylin.com * - * * - * Copyright (C) 2008 by Spencer Oliver * - * spen@spen-soft.co.uk * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifndef OPENOCD_TARGET_TARGET_TYPE_H -#define OPENOCD_TARGET_TARGET_TYPE_H - -#include - -struct target; - -/** - * This holds methods shared between all instances of a given target - * type. For example, all Cortex-M3 targets on a scan chain share - * the same method table. - */ -struct target_type { - /** - * Name of this type of target. Do @b not access this - * field directly, use target_type_name() instead. - */ - const char *name; - const char *deprecated_name; - - /* poll current target status */ - int (*poll)(struct target *target); - /* Invoked only from target_arch_state(). - * Issue USER() w/architecture specific status. */ - int (*arch_state)(struct target *target); - - /* target request support */ - int (*target_request_data)(struct target *target, uint32_t size, uint8_t *buffer); - - /* halt will log a warning, but return ERROR_OK if the target is already halted. */ - int (*halt)(struct target *target); - /* See target.c target_resume() for documentation. */ - int (*resume)(struct target *target, int current, uint32_t address, - int handle_breakpoints, int debug_execution); - int (*step)(struct target *target, int current, uint32_t address, - int handle_breakpoints); - - /* target reset control. assert reset can be invoked when OpenOCD and - * the target is out of sync. - * - * A typical example is that the target was power cycled while OpenOCD - * thought the target was halted or running. - * - * assert_reset() can therefore make no assumptions whatsoever about the - * state of the target - * - * Before assert_reset() for the target is invoked, a TRST/tms and - * chain validation is executed. TRST should not be asserted - * during target assert unless there is no way around it due to - * the way reset's are configured. - * - */ - int (*assert_reset)(struct target *target); - /** - * The implementation is responsible for polling the - * target such that target->state reflects the - * state correctly. - * - * Otherwise the following would fail, as there will not - * be any "poll" invoked inbetween the "reset run" and - * "halt". - * - * reset run; halt - */ - int (*deassert_reset)(struct target *target); - int (*soft_reset_halt)(struct target *target); - - /** - * Target register access for GDB. Do @b not call this function - * directly, use target_get_gdb_reg_list() instead. - * - * Danger! this function will succeed even if the target is running - * and return a register list with dummy values. - * - * The reason is that GDB connection will fail without a valid register - * list, however it is after GDB is connected that monitor commands can - * be run to properly initialize the target - */ - int (*get_gdb_reg_list)(struct target *target, struct reg **reg_list[], - int *reg_list_size, enum target_register_class reg_class); - - /* target memory access - * size: 1 = byte (8bit), 2 = half-word (16bit), 4 = word (32bit) - * count: number of items of - */ - - /** - * 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, - 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, - 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, - 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, - uint32_t size, const uint8_t *buffer); - - int (*checksum_memory)(struct target *target, uint32_t address, - uint32_t count, uint32_t *checksum); - int (*blank_check_memory)(struct target *target, uint32_t address, - uint32_t count, uint32_t *blank); - - /* - * target break-/watchpoint control - * rw: 0 = write, 1 = read, 2 = access - * - * Target must be halted while this is invoked as this - * will actually set up breakpoints on target. - * - * The breakpoint hardware will be set up upon adding the - * first breakpoint. - * - * Upon GDB connection all breakpoints/watchpoints are cleared. - */ - int (*add_breakpoint)(struct target *target, struct breakpoint *breakpoint); - int (*add_context_breakpoint)(struct target *target, struct breakpoint *breakpoint); - int (*add_hybrid_breakpoint)(struct target *target, struct breakpoint *breakpoint); - - /* remove breakpoint. hw will only be updated if the target - * is currently halted. - * However, this method can be invoked on unresponsive targets. - */ - int (*remove_breakpoint)(struct target *target, struct breakpoint *breakpoint); - - /* add watchpoint ... see add_breakpoint() comment above. */ - int (*add_watchpoint)(struct target *target, struct watchpoint *watchpoint); - - /* remove watchpoint. hw will only be updated if the target - * is currently halted. - * However, this method can be invoked on unresponsive targets. - */ - int (*remove_watchpoint)(struct target *target, struct watchpoint *watchpoint); - - /* Find out just hit watchpoint. After the target hits a watchpoint, the - * information could assist gdb to locate where the modified/accessed memory is. - */ - int (*hit_watchpoint)(struct target *target, struct watchpoint **hit_watchpoint); - - /** - * Target algorithm support. Do @b not call this method directly, - * use target_run_algorithm() instead. - */ - 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); - 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); - 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, - int timeout_ms, void *arch_info); - - const struct command_registration *commands; - - /* called when target is created */ - int (*target_create)(struct target *target, Jim_Interp *interp); - - /* called for various config parameters */ - /* returns JIM_CONTINUE - if option not understood */ - /* otherwise: JIM_OK, or JIM_ERR, */ - int (*target_jim_configure)(struct target *target, Jim_GetOptInfo *goi); - - /* target commands specifically handled by the target */ - /* returns JIM_OK, or JIM_ERR, or JIM_CONTINUE - if option not understood */ - int (*target_jim_commands)(struct target *target, Jim_GetOptInfo *goi); - - /** - * This method is used to perform target setup that requires - * JTAG access. - * - * This may be called multiple times. It is called after the - * scan chain is initially validated, or later after the target - * is enabled by a JRC. It may also be called during some - * parts of the reset sequence. - * - * For one-time initialization tasks, use target_was_examined() - * and target_set_examined(). For example, probe the hardware - * before setting up chip-specific state, and then set that - * flag so you don't do that again. - */ - int (*examine)(struct target *target); - - /* Set up structures for target. - * - * It is illegal to talk to the target at this stage as this fn is invoked - * before the JTAG chain has been examined/verified - * */ - int (*init_target)(struct command_context *cmd_ctx, struct target *target); - - /** - * Free all the resources allocated by the target. - * - * @param target The target to deinit - */ - void (*deinit_target)(struct target *target); - - /* 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); - - /* read directly from physical memory. caches are bypassed and untouched. - * - * If the target does not support disabling caches, leaving them untouched, - * then minimally the actual physical memory location will be read even - * if cache states are unchanged, flushed, etc. - * - * Default implementation is to call read_memory. - */ - int (*read_phys_memory)(struct target *target, uint32_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, - uint32_t size, uint32_t count, const uint8_t *buffer); - - int (*mmu)(struct target *target, int *enabled); - - /* after reset is complete, the target can check if things are properly set up. - * - * This can be used to check if e.g. DCC memory writes have been enabled for - * arm7/9 targets, which they really should except in the most contrived - * circumstances. - */ - int (*check_reset)(struct target *target); - - /* get GDB file-I/O parameters from target - */ - int (*get_gdb_fileio_info)(struct target *target, struct gdb_fileio_info *fileio_info); - - /* pass GDB file-I/O response to target - */ - int (*gdb_fileio_end)(struct target *target, int retcode, int fileio_errno, bool ctrl_c); - - /* do target profiling - */ - int (*profiling)(struct target *target, uint32_t *samples, - uint32_t max_num_samples, uint32_t *num_samples, uint32_t seconds); -}; - -#endif /* OPENOCD_TARGET_TARGET_TYPE_H */ diff --git a/src/target/testee.c b/src/target/testee.c deleted file mode 100644 index 5b6ccedd8..000000000 --- a/src/target/testee.c +++ /dev/null @@ -1,73 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2009 Zachary T Welch * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General 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 -#include "config.h" -#endif - -#include - -#include "target.h" -#include "target_type.h" -#include "hello.h" - -static const struct command_registration testee_command_handlers[] = { - { - .name = "testee", - .mode = COMMAND_ANY, - .help = "testee target commands", - - .chain = hello_command_handlers, - }, - COMMAND_REGISTRATION_DONE -}; - -static int testee_init(struct command_context *cmd_ctx, struct target *target) -{ - return ERROR_OK; -} -static int testee_poll(struct target *target) -{ - if ((target->state == TARGET_RUNNING) || (target->state == TARGET_DEBUG_RUNNING)) - target->state = TARGET_HALTED; - return ERROR_OK; -} -static int testee_halt(struct target *target) -{ - target->state = TARGET_HALTED; - return ERROR_OK; -} -static int testee_reset_assert(struct target *target) -{ - target->state = TARGET_RESET; - return ERROR_OK; -} -static int testee_reset_deassert(struct target *target) -{ - target->state = TARGET_RUNNING; - return ERROR_OK; -} -struct target_type testee_target = { - .name = "testee", - .commands = testee_command_handlers, - - .init_target = &testee_init, - .poll = &testee_poll, - .halt = &testee_halt, - .assert_reset = &testee_reset_assert, - .deassert_reset = &testee_reset_deassert, -}; diff --git a/src/target/trace.c b/src/target/trace.c deleted file mode 100644 index 63c477fbf..000000000 --- a/src/target/trace.c +++ /dev/null @@ -1,175 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005, 2007 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include "trace.h" -#include "target.h" - -int trace_point(struct target *target, uint32_t number) -{ - struct trace *trace = target->trace_info; - - LOG_DEBUG("tracepoint: %i", (int)number); - - if (number < trace->num_trace_points) - trace->trace_points[number].hit_counter++; - - if (trace->trace_history_size) { - trace->trace_history[trace->trace_history_pos++] = number; - if (trace->trace_history_pos == trace->trace_history_size) { - trace->trace_history_pos = 0; - trace->trace_history_overflowed = 1; - } - } - - return ERROR_OK; -} - -COMMAND_HANDLER(handle_trace_point_command) -{ - struct target *target = get_current_target(CMD_CTX); - struct trace *trace = target->trace_info; - - if (CMD_ARGC == 0) { - uint32_t i; - - for (i = 0; i < trace->num_trace_points; i++) { - command_print(CMD_CTX, "trace point 0x%8.8" PRIx32 " (%lld times hit)", - trace->trace_points[i].address, - (long long)trace->trace_points[i].hit_counter); - } - - return ERROR_OK; - } - - if (!strcmp(CMD_ARGV[0], "clear")) { - if (trace->trace_points) { - free(trace->trace_points); - trace->trace_points = NULL; - } - trace->num_trace_points = 0; - trace->trace_points_size = 0; - - return ERROR_OK; - } - - /* resize array if necessary */ - if (!trace->trace_points || (trace->trace_points_size == trace->num_trace_points)) { - trace->trace_points = realloc(trace->trace_points, - sizeof(struct trace_point) * (trace->trace_points_size + 32)); - trace->trace_points_size += 32; - } - - uint32_t address; - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], address); - trace->trace_points[trace->num_trace_points].address = address; - trace->trace_points[trace->num_trace_points].hit_counter = 0; - trace->num_trace_points++; - - return ERROR_OK; -} - -COMMAND_HANDLER(handle_trace_history_command) -{ - struct target *target = get_current_target(CMD_CTX); - struct trace *trace = target->trace_info; - - if (CMD_ARGC > 0) { - trace->trace_history_pos = 0; - trace->trace_history_overflowed = 0; - - if (!strcmp(CMD_ARGV[0], "clear")) { - /* clearing is implicit, we've just reset position anyway */ - return ERROR_OK; - } - - if (trace->trace_history) - free(trace->trace_history); - - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], trace->trace_history_size); - trace->trace_history = malloc(sizeof(uint32_t) * trace->trace_history_size); - - command_print(CMD_CTX, "new trace history size: %i", (int)(trace->trace_history_size)); - } else { - uint32_t i; - uint32_t first = 0; - uint32_t last = trace->trace_history_pos; - - if (!trace->trace_history_size) { - command_print(CMD_CTX, "trace history buffer is not allocated"); - return ERROR_OK; - } - - if (trace->trace_history_overflowed) { - first = trace->trace_history_pos; - last = trace->trace_history_pos - 1; - } - - for (i = first; (i % trace->trace_history_size) != last; i++) { - if (trace->trace_history[i % trace->trace_history_size] < trace->num_trace_points) { - uint32_t address; - address = trace->trace_points[trace->trace_history[i % trace->trace_history_size]].address; - command_print(CMD_CTX, "trace point %i: 0x%8.8" PRIx32 "", - (int)(trace->trace_history[i % trace->trace_history_size]), - address); - } else - command_print(CMD_CTX, "trace point %i: -not defined-", - (int)(trace->trace_history[i % trace->trace_history_size])); - } - } - - return ERROR_OK; -} - -static const struct command_registration trace_exec_command_handlers[] = { - { - .name = "history", - .handler = handle_trace_history_command, - .mode = COMMAND_EXEC, - .help = "display trace history, clear history or set size", - .usage = "['clear'|size]", - }, - { - .name = "point", - .handler = handle_trace_point_command, - .mode = COMMAND_EXEC, - .help = "display trace points, clear list of trace points, " - "or add new tracepoint at address", - .usage = "['clear'|address]", - }, - COMMAND_REGISTRATION_DONE -}; -static const struct command_registration trace_command_handlers[] = { - { - .name = "trace", - .mode = COMMAND_EXEC, - .help = "trace command group", - .usage = "", - .chain = trace_exec_command_handlers, - }, - COMMAND_REGISTRATION_DONE -}; - -int trace_register_commands(struct command_context *cmd_ctx) -{ - return register_commands(cmd_ctx, NULL, trace_command_handlers); -} diff --git a/src/target/trace.h b/src/target/trace.h deleted file mode 100644 index 2966bbd94..000000000 --- a/src/target/trace.h +++ /dev/null @@ -1,59 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifndef OPENOCD_TARGET_TRACE_H -#define OPENOCD_TARGET_TRACE_H - -struct target; -struct command_context; - -struct trace_point { - uint32_t address; - uint64_t hit_counter; -}; - -struct trace { - uint32_t num_trace_points; - uint32_t trace_points_size; - struct trace_point *trace_points; - uint32_t trace_history_size; - uint32_t *trace_history; - uint32_t trace_history_pos; - int trace_history_overflowed; -}; - -/** - * \todo This enum is one of the few things in this file related - * to *hardware* tracing ... split such "real" tracing out from - * the contrib/libdcc support. - */ -typedef enum trace_status { - TRACE_IDLE = 0x0, - TRACE_RUNNING = 0x1, - TRACE_TRIGGERED = 0x2, - TRACE_COMPLETED = 0x4, - TRACE_OVERFLOWED = 0x8, -} trace_status_t; - -int trace_point(struct target *target, uint32_t number); -int trace_register_commands(struct command_context *cmd_ctx); - -#define ERROR_TRACE_IMAGE_UNAVAILABLE (-1500) -#define ERROR_TRACE_INSTRUCTION_UNAVAILABLE (-1501) - -#endif /* OPENOCD_TARGET_TRACE_H */ diff --git a/src/target/x86_32_common.c b/src/target/x86_32_common.c deleted file mode 100644 index 3f4c7aa0a..000000000 --- a/src/target/x86_32_common.c +++ /dev/null @@ -1,1497 +0,0 @@ -/* - * Copyright(c) 2013 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) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - * Contact Information: - * Intel Corporation - */ - -/* - * @file - * This implements generic x86 32 bit memory and breakpoint operations. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include - -#include "target.h" -#include "target_type.h" -#include "register.h" -#include "breakpoints.h" -#include "x86_32_common.h" - -static int set_debug_regs(struct target *t, uint32_t address, - uint8_t bp_num, uint8_t bp_type, uint8_t bp_length); -static int unset_debug_regs(struct target *t, uint8_t bp_num); -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 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, - uint32_t size, uint32_t count, const uint8_t *buffer); -static int set_breakpoint(struct target *target, - struct breakpoint *breakpoint); -static int unset_breakpoint(struct target *target, - struct breakpoint *breakpoint); -static int set_watchpoint(struct target *target, - struct watchpoint *watchpoint); -static int unset_watchpoint(struct target *target, - struct watchpoint *watchpoint); -static int read_hw_reg_to_cache(struct target *t, int num); -static int write_hw_reg_from_cache(struct target *t, int num); - -int x86_32_get_gdb_reg_list(struct target *t, - struct reg **reg_list[], int *reg_list_size, - enum target_register_class reg_class) -{ - - struct x86_32_common *x86_32 = target_to_x86_32(t); - int i; - *reg_list_size = x86_32->cache->num_regs; - LOG_DEBUG("num_regs=%d, reg_class=%d", (*reg_list_size), reg_class); - *reg_list = malloc(sizeof(struct reg *) * (*reg_list_size)); - if (*reg_list == NULL) { - LOG_ERROR("%s out of memory", __func__); - return ERROR_FAIL; - } - /* this will copy the values from our reg list to gdbs */ - for (i = 0; i < (*reg_list_size); i++) { - (*reg_list)[i] = &x86_32->cache->reg_list[i]; - LOG_DEBUG("value %s = %08" PRIx32, x86_32->cache->reg_list[i].name, - buf_get_u32(x86_32->cache->reg_list[i].value, 0, 32)); - } - return ERROR_OK; -} - -int x86_32_common_init_arch_info(struct target *t, struct x86_32_common *x86_32) -{ - t->arch_info = x86_32; - x86_32->common_magic = X86_32_COMMON_MAGIC; - x86_32->num_hw_bpoints = MAX_DEBUG_REGS; - x86_32->hw_break_list = calloc(x86_32->num_hw_bpoints, - sizeof(struct x86_32_dbg_reg)); - if (x86_32->hw_break_list == NULL) { - LOG_ERROR("%s out of memory", __func__); - return ERROR_FAIL; - } - x86_32->curr_tap = t->tap; - x86_32->fast_data_area = NULL; - x86_32->flush = 1; - x86_32->read_hw_reg_to_cache = read_hw_reg_to_cache; - x86_32->write_hw_reg_from_cache = write_hw_reg_from_cache; - return ERROR_OK; -} - -int x86_32_common_mmu(struct target *t, int *enabled) -{ - *enabled = true; - return ERROR_OK; -} - -int x86_32_common_virt2phys(struct target *t, uint32_t address, uint32_t *physical) -{ - struct x86_32_common *x86_32 = target_to_x86_32(t); - - /* - * We need to ignore 'segmentation' for now, as OpenOCD can't handle - * segmented addresses. - * In protected mode that is almost OK, as (almost) any known OS is using - * flat segmentation. In real mode we use use the base of the DS segment, - * as we don't know better ... - */ - - uint32_t cr0 = buf_get_u32(x86_32->cache->reg_list[CR0].value, 0, 32); - if (!(cr0 & CR0_PG)) { - /* target halted in real mode */ - /* TODO: needs validation !!! */ - uint32_t dsb = buf_get_u32(x86_32->cache->reg_list[DSB].value, 0, 32); - *physical = dsb + address; - - } 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, - __func__, address); - return ERROR_FAIL; - } - } - return ERROR_OK; -} - -int x86_32_common_read_phys_mem(struct target *t, uint32_t phys_address, - uint32_t size, uint32_t count, uint8_t *buffer) -{ - struct x86_32_common *x86_32 = target_to_x86_32(t); - int error; - - error = read_phys_mem(t, phys_address, size, count, buffer); - if (error != ERROR_OK) - return error; - - /* After reading memory from target, we must replace software breakpoints - * with the original instructions again. - */ - struct swbp_mem_patch *iter = x86_32->swbbp_mem_patch_list; - while (iter != NULL) { - if (iter->physaddr >= phys_address && iter->physaddr < phys_address+(size*count)) { - uint32_t offset = iter->physaddr - phys_address; - buffer[offset] = iter->orig_byte; - } - iter = iter->next; - } - return ERROR_OK; -} - -static int read_phys_mem(struct target *t, uint32_t phys_address, - uint32_t size, uint32_t count, uint8_t *buffer) -{ - int retval = ERROR_OK; - bool pg_disabled = false; - LOG_DEBUG("addr=0x%08" PRIx32 ", size=%" PRIu32 ", count=0x%" PRIx32 ", buf=%p", - phys_address, size, count, buffer); - struct x86_32_common *x86_32 = target_to_x86_32(t); - - if (check_not_halted(t)) - return ERROR_TARGET_NOT_HALTED; - if (!count || !buffer || !phys_address) { - LOG_ERROR("%s invalid params count=0x%" PRIx32 ", buf=%p, addr=0x%08" PRIx32, - __func__, count, buffer, phys_address); - return ERROR_COMMAND_ARGUMENT_INVALID; - } - - /* to access physical memory, switch off the CR0.PG bit */ - if (x86_32->is_paging_enabled(t)) { - retval = x86_32->disable_paging(t); - if (retval != ERROR_OK) { - LOG_ERROR("%s could not disable paging", __func__); - return retval; - } - pg_disabled = true; - } - - for (uint32_t i = 0; i < count; i++) { - switch (size) { - case BYTE: - retval = read_mem(t, size, phys_address + i, buffer + i); - break; - case WORD: - retval = read_mem(t, size, phys_address + i * 2, buffer + i * 2); - break; - case DWORD: - retval = read_mem(t, size, phys_address + i * 4, buffer + i * 4); - break; - default: - LOG_ERROR("%s invalid read size", __func__); - break; - } - } - /* restore CR0.PG bit if needed (regardless of retval) */ - if (pg_disabled) { - retval = x86_32->enable_paging(t); - if (retval != ERROR_OK) { - LOG_ERROR("%s could not enable paging", __func__); - return retval; - } - pg_disabled = true; - } - /* TODO: After reading memory from target, we must replace - * software breakpoints with the original instructions again. - * Solve this with the breakpoint fix - */ - return retval; -} - -int x86_32_common_write_phys_mem(struct target *t, uint32_t phys_address, - uint32_t size, uint32_t count, const uint8_t *buffer) -{ - struct x86_32_common *x86_32 = target_to_x86_32(t); - int error = ERROR_OK; - uint8_t *newbuffer = NULL; - - check_not_halted(t); - if (!count || !buffer || !phys_address) { - LOG_ERROR("%s invalid params count=0x%" PRIx32 ", buf=%p, addr=0x%08" PRIx32, - __func__, count, buffer, phys_address); - return ERROR_COMMAND_ARGUMENT_INVALID; - } - /* Before writing memory to target, we must update software breakpoints - * with the new instructions and patch the memory buffer with the - * breakpoint instruction. - */ - newbuffer = malloc(size*count); - if (newbuffer == NULL) { - LOG_ERROR("%s out of memory", __func__); - return ERROR_FAIL; - } - memcpy(newbuffer, buffer, size*count); - struct swbp_mem_patch *iter = x86_32->swbbp_mem_patch_list; - while (iter != NULL) { - if (iter->physaddr >= phys_address && iter->physaddr < phys_address+(size*count)) { - uint32_t offset = iter->physaddr - phys_address; - newbuffer[offset] = SW_BP_OPCODE; - - /* update the breakpoint */ - struct breakpoint *pbiter = t->breakpoints; - while (pbiter != NULL && pbiter->unique_id != iter->swbp_unique_id) - pbiter = pbiter->next; - if (pbiter) - pbiter->orig_instr[0] = buffer[offset]; - } - iter = iter->next; - } - - error = write_phys_mem(t, phys_address, size, count, newbuffer); - free(newbuffer); - return error; -} - -static int write_phys_mem(struct target *t, uint32_t phys_address, - uint32_t size, uint32_t count, const uint8_t *buffer) -{ - int retval = ERROR_OK; - bool pg_disabled = false; - struct x86_32_common *x86_32 = target_to_x86_32(t); - LOG_DEBUG("addr=0x%08" PRIx32 ", size=%" PRIu32 ", count=0x%" PRIx32 ", buf=%p", - phys_address, size, count, buffer); - - check_not_halted(t); - if (!count || !buffer || !phys_address) { - LOG_ERROR("%s invalid params count=0x%" PRIx32 ", buf=%p, addr=0x%08" PRIx32, - __func__, count, buffer, phys_address); - return ERROR_COMMAND_ARGUMENT_INVALID; - } - /* TODO: Before writing memory to target, we must update - * software breakpoints with the new instructions and - * patch the memory buffer with the breakpoint instruction. - * Solve this with the breakpoint fix - */ - - /* to access physical memory, switch off the CR0.PG bit */ - if (x86_32->is_paging_enabled(t)) { - retval = x86_32->disable_paging(t); - if (retval != ERROR_OK) { - LOG_ERROR("%s could not disable paging", __func__); - return retval; - } - pg_disabled = true; - } - for (uint32_t i = 0; i < count; i++) { - switch (size) { - case BYTE: - retval = write_mem(t, size, phys_address + i, buffer + i); - break; - case WORD: - retval = write_mem(t, size, phys_address + i * 2, buffer + i * 2); - break; - case DWORD: - retval = write_mem(t, size, phys_address + i * 4, buffer + i * 4); - break; - default: - LOG_DEBUG("invalid read size"); - break; - } - } - /* restore CR0.PG bit if needed (regardless of retval) */ - if (pg_disabled) { - retval = x86_32->enable_paging(t); - if (retval != ERROR_OK) { - LOG_ERROR("%s could not enable paging", __func__); - return retval; - } - } - return retval; -} - -static int read_mem(struct target *t, uint32_t size, - uint32_t addr, uint8_t *buf) -{ - struct x86_32_common *x86_32 = target_to_x86_32(t); - - /* if CS.D bit=1 then its a 32 bit code segment, else 16 */ - bool use32 = (buf_get_u32(x86_32->cache->reg_list[CSAR].value, 0, 32)) & CSAR_D; - int retval = x86_32->write_hw_reg(t, EAX, addr, 0); - if (retval != ERROR_OK) { - LOG_ERROR("%s error write EAX", __func__); - return retval; - } - - switch (size) { - case BYTE: - if (use32) - retval = x86_32->submit_instruction(t, MEMRDB32); - else - retval = x86_32->submit_instruction(t, MEMRDB16); - break; - case WORD: - if (use32) - retval = x86_32->submit_instruction(t, MEMRDH32); - else - retval = x86_32->submit_instruction(t, MEMRDH16); - break; - case DWORD: - if (use32) - retval = x86_32->submit_instruction(t, MEMRDW32); - else - retval = x86_32->submit_instruction(t, MEMRDW16); - break; - default: - LOG_ERROR("%s invalid read mem size", __func__); - break; - } - - /* read_hw_reg() will write to 4 bytes (uint32_t) - * Watch out, the buffer passed into read_mem() might be 1 or 2 bytes. - */ - uint32_t regval; - retval = x86_32->read_hw_reg(t, EDX, ®val, 0); - - if (retval != ERROR_OK) { - LOG_ERROR("%s error read EDX", __func__); - return retval; - } - for (uint8_t i = 0; i < size; i++) - buf[i] = (regval >> (i*8)) & 0x000000FF; - - retval = x86_32->transaction_status(t); - if (retval != ERROR_OK) { - LOG_ERROR("%s error on mem read", __func__); - return retval; - } - return retval; -} - -static int write_mem(struct target *t, uint32_t size, - uint32_t addr, const uint8_t *buf) -{ - uint32_t i = 0; - uint32_t buf4bytes = 0; - int retval = ERROR_OK; - struct x86_32_common *x86_32 = target_to_x86_32(t); - - for (i = 0; i < size; ++i) { - buf4bytes = buf4bytes << 8; /* first time we only shift 0s */ - buf4bytes += buf[(size-1)-i]; /* it was hard to write, should be hard to read! */ - } - /* if CS.D bit=1 then its a 32 bit code segment, else 16 */ - bool use32 = (buf_get_u32(x86_32->cache->reg_list[CSAR].value, 0, 32)) & CSAR_D; - retval = x86_32->write_hw_reg(t, EAX, addr, 0); - if (retval != ERROR_OK) { - LOG_ERROR("%s error write EAX", __func__); - return retval; - } - - /* write_hw_reg() will write to 4 bytes (uint32_t) - * Watch out, the buffer passed into write_mem() might be 1 or 2 bytes. - */ - retval = x86_32->write_hw_reg(t, EDX, buf4bytes, 0); - if (retval != ERROR_OK) { - LOG_ERROR("%s error write EDX", __func__); - return retval; - } - switch (size) { - case BYTE: - if (use32) - retval = x86_32->submit_instruction(t, MEMWRB32); - else - retval = x86_32->submit_instruction(t, MEMWRB16); - break; - case WORD: - if (use32) - retval = x86_32->submit_instruction(t, MEMWRH32); - else - retval = x86_32->submit_instruction(t, MEMWRH16); - break; - case DWORD: - if (use32) - retval = x86_32->submit_instruction(t, MEMWRW32); - else - retval = x86_32->submit_instruction(t, MEMWRW16); - break; - default: - LOG_ERROR("%s invalid write mem size", __func__); - return ERROR_FAIL; - } - retval = x86_32->transaction_status(t); - if (retval != ERROR_OK) { - LOG_ERROR("%s error on mem write", __func__); - return retval; - } - return retval; -} - -int calcaddr_pyhsfromlin(struct target *t, uint32_t addr, uint32_t *physaddr) -{ - uint8_t entry_buffer[8]; - - if (physaddr == NULL || t == NULL) - return ERROR_FAIL; - - struct x86_32_common *x86_32 = target_to_x86_32(t); - - /* The 'user-visible' CR0.PG should be set - otherwise the function shouldn't be called - * (Don't check the CR0.PG on the target, this might be temporally disabled at this point) - */ - uint32_t cr0 = buf_get_u32(x86_32->cache->reg_list[CR0].value, 0, 32); - if (!(cr0 & CR0_PG)) { - /* you are wrong in this function, never mind */ - *physaddr = addr; - return ERROR_OK; - } - - uint32_t cr4 = buf_get_u32(x86_32->cache->reg_list[CR4].value, 0, 32); - bool isPAE = cr4 & 0x00000020; /* PAE - Physical Address Extension */ - - uint32_t cr3 = buf_get_u32(x86_32->cache->reg_list[CR3].value, 0, 32); - if (isPAE) { - uint32_t pdpt_base = cr3 & 0xFFFFF000; /* lower 12 bits of CR3 must always be 0 */ - uint32_t pdpt_index = (addr & 0xC0000000) >> 30; /* A[31:30] index to PDPT */ - uint32_t pdpt_addr = pdpt_base + (8 * pdpt_index); - if (x86_32_common_read_phys_mem(t, pdpt_addr, 4, 2, entry_buffer) != ERROR_OK) { - LOG_ERROR("%s couldn't read page directory pointer table entry at 0x%08" PRIx32, - __func__, pdpt_addr); - return ERROR_FAIL; - } - uint64_t pdpt_entry = target_buffer_get_u64(t, entry_buffer); - if (!(pdpt_entry & 0x0000000000000001)) { - LOG_ERROR("%s page directory pointer table entry at 0x%08" PRIx32 " is not present", - __func__, pdpt_addr); - return ERROR_FAIL; - } - - uint32_t pd_base = pdpt_entry & 0xFFFFF000; /* A[31:12] is PageTable/Page Base Address */ - uint32_t pd_index = (addr & 0x3FE00000) >> 21; /* A[29:21] index to PD entry with PAE */ - uint32_t pd_addr = pd_base + (8 * pd_index); - if (x86_32_common_read_phys_mem(t, pd_addr, 4, 2, entry_buffer) != ERROR_OK) { - LOG_ERROR("%s couldn't read page directory entry at 0x%08" PRIx32, - __func__, pd_addr); - return ERROR_FAIL; - } - uint64_t pd_entry = target_buffer_get_u64(t, entry_buffer); - if (!(pd_entry & 0x0000000000000001)) { - LOG_ERROR("%s page directory entry at 0x%08" PRIx32 " is not present", - __func__, pd_addr); - return ERROR_FAIL; - } - - /* PS bit in PD entry is indicating 4KB or 2MB page size */ - if (pd_entry & 0x0000000000000080) { - - uint32_t page_base = (uint32_t)(pd_entry & 0x00000000FFE00000); /* [31:21] */ - uint32_t offset = addr & 0x001FFFFF; /* [20:0] */ - *physaddr = page_base + offset; - return ERROR_OK; - - } else { - - uint32_t pt_base = (uint32_t)(pd_entry & 0x00000000FFFFF000); /*[31:12]*/ - uint32_t pt_index = (addr & 0x001FF000) >> 12; /*[20:12]*/ - uint32_t pt_addr = pt_base + (8 * pt_index); - if (x86_32_common_read_phys_mem(t, pt_addr, 4, 2, entry_buffer) != ERROR_OK) { - LOG_ERROR("%s couldn't read page table entry at 0x%08" PRIx32, __func__, pt_addr); - return ERROR_FAIL; - } - uint64_t pt_entry = target_buffer_get_u64(t, entry_buffer); - if (!(pt_entry & 0x0000000000000001)) { - LOG_ERROR("%s page table entry at 0x%08" PRIx32 " is not present", __func__, pt_addr); - return ERROR_FAIL; - } - - uint32_t page_base = (uint32_t)(pt_entry & 0x00000000FFFFF000); /*[31:12]*/ - uint32_t offset = addr & 0x00000FFF; /*[11:0]*/ - *physaddr = page_base + offset; - return ERROR_OK; - } - } else { - uint32_t pd_base = cr3 & 0xFFFFF000; /* lower 12 bits of CR3 must always be 0 */ - uint32_t pd_index = (addr & 0xFFC00000) >> 22; /* A[31:22] index to PD entry */ - uint32_t pd_addr = pd_base + (4 * pd_index); - if (x86_32_common_read_phys_mem(t, pd_addr, 4, 1, entry_buffer) != ERROR_OK) { - LOG_ERROR("%s couldn't read page directory entry at 0x%08" PRIx32, __func__, pd_addr); - return ERROR_FAIL; - } - uint32_t pd_entry = target_buffer_get_u32(t, entry_buffer); - if (!(pd_entry & 0x00000001)) { - LOG_ERROR("%s page directory entry at 0x%08" PRIx32 " is not present", __func__, pd_addr); - return ERROR_FAIL; - } - - /* Bit 7 in page directory entry is page size. - */ - if (pd_entry & 0x00000080) { - /* 4MB pages */ - uint32_t page_base = pd_entry & 0xFFC00000; - *physaddr = page_base + (addr & 0x003FFFFF); - - } else { - /* 4KB pages */ - uint32_t pt_base = pd_entry & 0xFFFFF000; /* A[31:12] is PageTable/Page Base Address */ - uint32_t pt_index = (addr & 0x003FF000) >> 12; /* A[21:12] index to page table entry */ - uint32_t pt_addr = pt_base + (4 * pt_index); - if (x86_32_common_read_phys_mem(t, pt_addr, 4, 1, entry_buffer) != ERROR_OK) { - LOG_ERROR("%s couldn't read page table entry at 0x%08" PRIx32, __func__, pt_addr); - return ERROR_FAIL; - } - uint32_t pt_entry = target_buffer_get_u32(t, entry_buffer); - if (!(pt_entry & 0x00000001)) { - LOG_ERROR("%s page table entry at 0x%08" PRIx32 " is not present", __func__, pt_addr); - return ERROR_FAIL; - } - uint32_t page_base = pt_entry & 0xFFFFF000; /* A[31:12] is PageTable/Page Base Address */ - *physaddr = page_base + (addr & 0x00000FFF); /* A[11:0] offset to 4KB page in linear address */ - } - } - return ERROR_OK; -} - -int x86_32_common_read_memory(struct target *t, uint32_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", - 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, - __func__, count, buf, addr); - return ERROR_COMMAND_ARGUMENT_INVALID; - } - - if (x86_32->is_paging_enabled(t)) { - /* all memory accesses from debugger must be physical (CR0.PG == 0) - * conversion to physical address space needed - */ - retval = x86_32->disable_paging(t); - if (retval != ERROR_OK) { - 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); - retval = ERROR_FAIL; - } - /* TODO: !!! Watch out for page boundaries - * for every 4kB, the physical address has to be re-calculated - * This should be fixed together with bulk memory reads - */ - - 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); - retval = ERROR_FAIL; - } - /* restore PG bit if it was cleared prior (regardless of retval) */ - retval = x86_32->enable_paging(t); - if (retval != ERROR_OK) { - LOG_ERROR("%s could not enable paging", __func__); - return retval; - } - } 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); - retval = ERROR_FAIL; - } - } - - return retval; -} - -int x86_32_common_write_memory(struct target *t, uint32_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", - 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, - __func__, count, buf, addr); - return ERROR_COMMAND_ARGUMENT_INVALID; - } - if (x86_32->is_paging_enabled(t)) { - /* all memory accesses from debugger must be physical (CR0.PG == 0) - * conversion to physical address space needed - */ - retval = x86_32->disable_paging(t); - if (retval != ERROR_OK) { - 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); - retval = ERROR_FAIL; - } - /* TODO: !!! Watch out for page boundaries - * for every 4kB, the physical address has to be re-calculated - * This should be fixed together with bulk memory reads - */ - 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, - __func__, physaddr); - retval = ERROR_FAIL; - } - /* restore PG bit if it was cleared prior (regardless of retval) */ - retval = x86_32->enable_paging(t); - if (retval != ERROR_OK) { - LOG_ERROR("%s could not enable paging", __func__); - return retval; - } - } else { - - /* 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, - __func__, addr); - retval = ERROR_FAIL; - } - } - return retval; -} - -int x86_32_common_read_io(struct target *t, uint32_t addr, - uint32_t size, uint8_t *buf) -{ - struct x86_32_common *x86_32 = target_to_x86_32(t); - /* if CS.D bit=1 then its a 32 bit code segment, else 16 */ - bool use32 = (buf_get_u32(x86_32->cache->reg_list[CSAR].value, 0, 32)) & CSAR_D; - int retval = ERROR_FAIL; - bool pg_disabled = false; - LOG_DEBUG("addr=0x%08" PRIx32 ", size=%" PRIu32 ", buf=%p", addr, size, buf); - check_not_halted(t); - if (!buf || !addr) { - LOG_ERROR("%s invalid params buf=%p, addr=%08" PRIx32, __func__, buf, addr); - return retval; - } - retval = x86_32->write_hw_reg(t, EDX, addr, 0); - if (retval != ERROR_OK) { - LOG_ERROR("%s error EDX write", __func__); - return retval; - } - /* to access physical memory, switch off the CR0.PG bit */ - if (x86_32->is_paging_enabled(t)) { - retval = x86_32->disable_paging(t); - if (retval != ERROR_OK) { - LOG_ERROR("%s could not disable paging", __func__); - return retval; - } - pg_disabled = true; - } - switch (size) { - case BYTE: - if (use32) - retval = x86_32->submit_instruction(t, IORDB32); - else - retval = x86_32->submit_instruction(t, IORDB16); - break; - case WORD: - if (use32) - retval = x86_32->submit_instruction(t, IORDH32); - else - retval = x86_32->submit_instruction(t, IORDH16); - break; - case DWORD: - if (use32) - retval = x86_32->submit_instruction(t, IORDW32); - else - retval = x86_32->submit_instruction(t, IORDW16); - break; - default: - LOG_ERROR("%s invalid read io size", __func__); - return ERROR_FAIL; - } - /* restore CR0.PG bit if needed */ - if (pg_disabled) { - retval = x86_32->enable_paging(t); - if (retval != ERROR_OK) { - LOG_ERROR("%s could not enable paging", __func__); - return retval; - } - pg_disabled = false; - } - uint32_t regval = 0; - retval = x86_32->read_hw_reg(t, EAX, ®val, 0); - if (retval != ERROR_OK) { - LOG_ERROR("%s error on read EAX", __func__); - return retval; - } - for (uint8_t i = 0; i < size; i++) - buf[i] = (regval >> (i*8)) & 0x000000FF; - retval = x86_32->transaction_status(t); - if (retval != ERROR_OK) { - LOG_ERROR("%s error on io read", __func__); - return retval; - } - return retval; -} - -int x86_32_common_write_io(struct target *t, uint32_t addr, - uint32_t size, const uint8_t *buf) -{ - struct x86_32_common *x86_32 = target_to_x86_32(t); - /* if CS.D bit=1 then its a 32 bit code segment, else 16 */ - bool use32 = (buf_get_u32(x86_32->cache->reg_list[CSAR].value, 0, 32)) & CSAR_D; - LOG_DEBUG("addr=0x%08" PRIx32 ", size=%" PRIu32 ", buf=%p", addr, size, buf); - check_not_halted(t); - int retval = ERROR_FAIL; - bool pg_disabled = false; - if (!buf || !addr) { - LOG_ERROR("%s invalid params buf=%p, addr=0x%08" PRIx32, __func__, buf, addr); - return retval; - } - /* no do the write */ - retval = x86_32->write_hw_reg(t, EDX, addr, 0); - if (retval != ERROR_OK) { - LOG_ERROR("%s error on EDX write", __func__); - return retval; - } - uint32_t regval = 0; - for (uint8_t i = 0; i < size; i++) - regval += (buf[i] << (i*8)); - retval = x86_32->write_hw_reg(t, EAX, regval, 0); - if (retval != ERROR_OK) { - LOG_ERROR("%s error on EAX write", __func__); - return retval; - } - /* to access physical memory, switch off the CR0.PG bit */ - if (x86_32->is_paging_enabled(t)) { - retval = x86_32->disable_paging(t); - if (retval != ERROR_OK) { - LOG_ERROR("%s could not disable paging", __func__); - return retval; - } - pg_disabled = true; - } - switch (size) { - case BYTE: - if (use32) - retval = x86_32->submit_instruction(t, IOWRB32); - else - retval = x86_32->submit_instruction(t, IOWRB16); - break; - case WORD: - if (use32) - retval = x86_32->submit_instruction(t, IOWRH32); - else - retval = x86_32->submit_instruction(t, IOWRH16); - break; - case DWORD: - if (use32) - retval = x86_32->submit_instruction(t, IOWRW32); - else - retval = x86_32->submit_instruction(t, IOWRW16); - break; - default: - LOG_ERROR("%s invalid write io size", __func__); - return ERROR_FAIL; - } - /* restore CR0.PG bit if needed */ - if (pg_disabled) { - retval = x86_32->enable_paging(t); - if (retval != ERROR_OK) { - LOG_ERROR("%s could not enable paging", __func__); - return retval; - } - pg_disabled = false; - } - retval = x86_32->transaction_status(t); - if (retval != ERROR_OK) { - LOG_ERROR("%s error on io write", __func__); - return retval; - } - return retval; -} - -int x86_32_common_add_watchpoint(struct target *t, struct watchpoint *wp) -{ - check_not_halted(t); - /* set_watchpoint() will return ERROR_TARGET_RESOURCE_NOT_AVAILABLE if all - * hardware registers are gone - */ - return set_watchpoint(t, wp); -} - -int x86_32_common_remove_watchpoint(struct target *t, struct watchpoint *wp) -{ - if (check_not_halted(t)) - return ERROR_TARGET_NOT_HALTED; - if (wp->set) - unset_watchpoint(t, wp); - return ERROR_OK; -} - -int x86_32_common_add_breakpoint(struct target *t, struct breakpoint *bp) -{ - LOG_DEBUG("type=%d, addr=0x%08" PRIx32, 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 - * hardware registers are gone (for hardware breakpoints) - */ - return set_breakpoint(t, 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); - if (check_not_halted(t)) - return ERROR_TARGET_NOT_HALTED; - if (bp->set) - unset_breakpoint(t, bp); - - return ERROR_OK; -} - -static int set_debug_regs(struct target *t, uint32_t address, - uint8_t bp_num, uint8_t bp_type, uint8_t bp_length) -{ - struct x86_32_common *x86_32 = target_to_x86_32(t); - LOG_DEBUG("addr=0x%08" PRIx32 ", bp_num=%" PRIu8 ", bp_type=%" PRIu8 ", pb_length=%" PRIu8, - address, bp_num, bp_type, bp_length); - - /* DR7 - set global enable */ - uint32_t dr7 = buf_get_u32(x86_32->cache->reg_list[DR7].value, 0, 32); - - if (bp_length != 1 && bp_length != 2 && bp_length != 4) - return ERROR_FAIL; - - if (DR7_BP_FREE(dr7, bp_num)) - DR7_GLOBAL_ENABLE(dr7, bp_num); - else { - LOG_ERROR("%s dr7 error, already enabled, val=%08" PRIx32, __func__, dr7); - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - } - - switch (bp_type) { - case 0: - /* 00 - only on instruction execution */ - DR7_SET_EXE(dr7, bp_num); - DR7_SET_LENGTH(dr7, bp_num, bp_length); - break; - case 1: - /* 01 - only on data writes */ - DR7_SET_WRITE(dr7, bp_num); - DR7_SET_LENGTH(dr7, bp_num, bp_length); - break; - case 2: - /* 10 UNSUPPORTED - an I/O read and I/O write */ - LOG_ERROR("%s unsupported feature bp_type=%d", __func__, bp_type); - return ERROR_FAIL; - break; - case 3: - /* on data read or data write */ - DR7_SET_ACCESS(dr7, bp_num); - DR7_SET_LENGTH(dr7, bp_num, bp_length); - break; - default: - LOG_ERROR("%s invalid request [only 0-3] bp_type=%d", __func__, bp_type); - return ERROR_FAIL; - } - - /* update regs in the reg cache ready to be written to hardware - * when we exit PM - */ - buf_set_u32(x86_32->cache->reg_list[bp_num+DR0].value, 0, 32, address); - x86_32->cache->reg_list[bp_num+DR0].dirty = 1; - x86_32->cache->reg_list[bp_num+DR0].valid = 1; - buf_set_u32(x86_32->cache->reg_list[DR6].value, 0, 32, PM_DR6); - x86_32->cache->reg_list[DR6].dirty = 1; - x86_32->cache->reg_list[DR6].valid = 1; - buf_set_u32(x86_32->cache->reg_list[DR7].value, 0, 32, dr7); - x86_32->cache->reg_list[DR7].dirty = 1; - x86_32->cache->reg_list[DR7].valid = 1; - return ERROR_OK; -} - -static int unset_debug_regs(struct target *t, uint8_t bp_num) -{ - struct x86_32_common *x86_32 = target_to_x86_32(t); - LOG_DEBUG("bp_num=%" PRIu8, bp_num); - - uint32_t dr7 = buf_get_u32(x86_32->cache->reg_list[DR7].value, 0, 32); - - if (!(DR7_BP_FREE(dr7, bp_num))) { - DR7_GLOBAL_DISABLE(dr7, bp_num); - } else { - LOG_ERROR("%s dr7 error, not enabled, val=0x%08" PRIx32, __func__, dr7); - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - } - /* this will clear rw and len bits */ - DR7_RESET_RWLEN_BITS(dr7, bp_num); - - /* update regs in the reg cache ready to be written to hardware - * when we exit PM - */ - buf_set_u32(x86_32->cache->reg_list[bp_num+DR0].value, 0, 32, 0); - x86_32->cache->reg_list[bp_num+DR0].dirty = 1; - x86_32->cache->reg_list[bp_num+DR0].valid = 1; - buf_set_u32(x86_32->cache->reg_list[DR6].value, 0, 32, PM_DR6); - x86_32->cache->reg_list[DR6].dirty = 1; - x86_32->cache->reg_list[DR6].valid = 1; - buf_set_u32(x86_32->cache->reg_list[DR7].value, 0, 32, dr7); - x86_32->cache->reg_list[DR7].dirty = 1; - x86_32->cache->reg_list[DR7].valid = 1; - return ERROR_OK; -} - -static int set_hwbp(struct target *t, struct breakpoint *bp) -{ - struct x86_32_common *x86_32 = target_to_x86_32(t); - struct x86_32_dbg_reg *debug_reg_list = x86_32->hw_break_list; - uint8_t hwbp_num = 0; - - while (debug_reg_list[hwbp_num].used && (hwbp_num < x86_32->num_hw_bpoints)) - hwbp_num++; - if (hwbp_num >= x86_32->num_hw_bpoints) { - LOG_ERROR("%s no free hw breakpoint bpid=0x%" PRIx32, __func__, bp->unique_id); - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - } - if (set_debug_regs(t, bp->address, hwbp_num, DR7_BP_EXECUTE, 1) != ERROR_OK) - return ERROR_FAIL; - bp->set = hwbp_num + 1; - debug_reg_list[hwbp_num].used = 1; - debug_reg_list[hwbp_num].bp_value = bp->address; - LOG_USER("%s hardware breakpoint %" PRIu32 " set at 0x%08" PRIx32 " (hwreg=%" PRIu8 ")", __func__, - bp->unique_id, debug_reg_list[hwbp_num].bp_value, hwbp_num); - return ERROR_OK; -} - -static int unset_hwbp(struct target *t, struct breakpoint *bp) -{ - 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 hwbp_num = bp->set - 1; - - if ((hwbp_num < 0) || (hwbp_num >= x86_32->num_hw_bpoints)) { - LOG_ERROR("%s invalid breakpoint number=%d, bpid=%" PRIu32, - __func__, hwbp_num, bp->unique_id); - return ERROR_OK; - } - - if (unset_debug_regs(t, hwbp_num) != ERROR_OK) - return ERROR_FAIL; - 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)", - __func__, bp->unique_id, bp->address, hwbp_num); - return ERROR_OK; -} - -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; - uint8_t opcode = SW_BP_OPCODE; - uint8_t readback; - - if (calcaddr_pyhsfromlin(t, bp->address, &physaddr) != ERROR_OK) - return ERROR_FAIL; - if (read_phys_mem(t, physaddr, 1, 1, bp->orig_instr)) - return ERROR_FAIL; - - LOG_DEBUG("set software breakpoint - orig byte=0x%02" PRIx8 "", *bp->orig_instr); - - /* just write the instruction trap byte */ - if (write_phys_mem(t, physaddr, 1, 1, &opcode)) - return ERROR_FAIL; - - /* verify that this is not invalid/read-only memory */ - if (read_phys_mem(t, physaddr, 1, 1, &readback)) - return ERROR_FAIL; - - if (readback != SW_BP_OPCODE) { - LOG_ERROR("%s software breakpoint error at 0x%08" PRIx32 ", check memory", - __func__, bp->address); - LOG_ERROR("%s readback=0x%02" PRIx8 " orig=0x%02" PRIx8 "", - __func__, readback, *bp->orig_instr); - return ERROR_FAIL; - } - bp->set = SW_BP_OPCODE; /* just non 0 */ - - /* add the memory patch */ - struct swbp_mem_patch *new_patch = malloc(sizeof(struct swbp_mem_patch)); - if (new_patch == NULL) { - LOG_ERROR("%s out of memory", __func__); - return ERROR_FAIL; - } - new_patch->next = NULL; - new_patch->orig_byte = *bp->orig_instr; - new_patch->physaddr = physaddr; - new_patch->swbp_unique_id = bp->unique_id; - - struct swbp_mem_patch *addto = x86_32->swbbp_mem_patch_list; - if (addto == NULL) - x86_32->swbbp_mem_patch_list = new_patch; - else { - while (addto->next != NULL) - addto = addto->next; - addto->next = new_patch; - } - LOG_USER("%s software breakpoint %" PRIu32 " set at 0x%08" PRIx32, - __func__, bp->unique_id, bp->address); - return ERROR_OK; -} - -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; - uint8_t current_instr; - - /* check that user program has not modified breakpoint instruction */ - if (calcaddr_pyhsfromlin(t, bp->address, &physaddr) != ERROR_OK) - return ERROR_FAIL; - if (read_phys_mem(t, physaddr, 1, 1, ¤t_instr)) - return ERROR_FAIL; - - if (current_instr == SW_BP_OPCODE) { - 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", - __func__, bp->address); - LOG_ERROR("%s current=0x%02" PRIx8 " orig=0x%02" PRIx8 "", - __func__, current_instr, *bp->orig_instr); - return ERROR_FAIL; - } - - /* remove from patch */ - struct swbp_mem_patch *iter = x86_32->swbbp_mem_patch_list; - if (iter != NULL) { - if (iter->swbp_unique_id == bp->unique_id) { - /* it's the first item */ - x86_32->swbbp_mem_patch_list = iter->next; - free(iter); - } else { - while (iter->next != NULL && iter->next->swbp_unique_id != bp->unique_id) - iter = iter->next; - if (iter->next != NULL) { - /* it's the next one */ - struct swbp_mem_patch *freeme = iter->next; - iter->next = iter->next->next; - free(freeme); - } - } - } - - LOG_USER("%s software breakpoint %" PRIu32 " removed from 0x%08" PRIx32, - __func__, bp->unique_id, bp->address); - return ERROR_OK; -} - -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); - if (bp->set) { - LOG_ERROR("breakpoint already set"); - return error; - } - 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, - __func__, bp->address); - return error; - } - } else { - 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, - __func__, bp->address); - return error; - } - } else { - LOG_ERROR("%s core doesn't support SW breakpoints", __func__); - error = ERROR_FAIL; - return ERROR_FAIL; - } - } - return error; -} - -static int unset_breakpoint(struct target *t, struct breakpoint *bp) -{ - LOG_DEBUG("type=%d, addr=0x%08" PRIx32, bp->type, bp->address); - if (!bp->set) { - LOG_WARNING("breakpoint not set"); - return ERROR_OK; - } - - if (bp->type == BKPT_HARD) { - if (unset_hwbp(t, bp) != ERROR_OK) { - LOG_ERROR("%s error removing hardware breakpoint at 0x%08" PRIx32, - __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, - __func__, bp->address); - return ERROR_FAIL; - } - } - bp->set = 0; - return ERROR_OK; -} - -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); - - if (wp->set) { - LOG_ERROR("%s watchpoint already set", __func__); - return ERROR_OK; - } - - if (wp->rw == WPT_READ) { - LOG_ERROR("%s no support for 'read' watchpoints, use 'access' or 'write'" - , __func__); - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - } - - while (debug_reg_list[wp_num].used && (wp_num < x86_32->num_hw_bpoints)) - wp_num++; - if (wp_num >= x86_32->num_hw_bpoints) { - LOG_ERROR("%s no debug registers left", __func__); - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - } - - if (wp->length != 4 && wp->length != 2 && wp->length != 1) { - LOG_ERROR("%s only watchpoints of length 1, 2 or 4 are supported", __func__); - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - } - - switch (wp->rw) { - case WPT_WRITE: - if (set_debug_regs(t, wp->address, wp_num, - DR7_BP_WRITE, wp->length) != ERROR_OK) { - return ERROR_FAIL; - } - break; - case WPT_ACCESS: - if (set_debug_regs(t, wp->address, wp_num, DR7_BP_READWRITE, - wp->length) != ERROR_OK) { - return ERROR_FAIL; - } - break; - default: - LOG_ERROR("%s only 'access' or 'write' watchpoints are supported", __func__); - break; - } - 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)", - wp->rw == WPT_READ ? "read" : wp->rw == WPT_WRITE ? - "write" : wp->rw == WPT_ACCESS ? "access" : "?", - wp->unique_id, wp->address, wp->length, wp_num); - return ERROR_OK; -} - -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); - if (!wp->set) { - LOG_WARNING("watchpoint not set"); - return ERROR_OK; - } - - int wp_num = wp->set - 1; - if ((wp_num < 0) || (wp_num >= x86_32->num_hw_bpoints)) { - LOG_DEBUG("Invalid FP Comparator number in watchpoint"); - return ERROR_OK; - } - if (unset_debug_regs(t, wp_num) != ERROR_OK) - return ERROR_FAIL; - - debug_reg_list[wp_num].used = 0; - 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)", - wp->rw == WPT_READ ? "read" : wp->rw == WPT_WRITE ? - "write" : wp->rw == WPT_ACCESS ? "access" : "?", - wp->unique_id, wp->address, wp->length, wp_num); - - return ERROR_OK; -} - -static int read_hw_reg_to_cache(struct target *t, int num) -{ - uint32_t reg_value; - struct x86_32_common *x86_32 = target_to_x86_32(t); - - if (check_not_halted(t)) - return ERROR_TARGET_NOT_HALTED; - if ((num < 0) || (num >= x86_32->get_num_user_regs(t))) - return ERROR_COMMAND_SYNTAX_ERROR; - if (x86_32->read_hw_reg(t, num, ®_value, 1) != ERROR_OK) { - LOG_ERROR("%s fail for %s", x86_32->cache->reg_list[num].name, __func__); - return ERROR_FAIL; - } - LOG_DEBUG("reg %s value 0x%08" PRIx32, - x86_32->cache->reg_list[num].name, reg_value); - return ERROR_OK; -} - -static int write_hw_reg_from_cache(struct target *t, int num) -{ - struct x86_32_common *x86_32 = target_to_x86_32(t); - if (check_not_halted(t)) - return ERROR_TARGET_NOT_HALTED; - if ((num < 0) || (num >= x86_32->get_num_user_regs(t))) - return ERROR_COMMAND_SYNTAX_ERROR; - if (x86_32->write_hw_reg(t, num, 0, 1) != ERROR_OK) { - LOG_ERROR("%s fail for %s", x86_32->cache->reg_list[num].name, __func__); - return ERROR_FAIL; - } - LOG_DEBUG("reg %s value 0x%08" PRIx32, x86_32->cache->reg_list[num].name, - buf_get_u32(x86_32->cache->reg_list[num].value, 0, 32)); - return ERROR_OK; -} - -/* x86 32 commands */ -static void handle_iod_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("%s invalid memory read size: %u", __func__, 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; - } - } -} - -COMMAND_HANDLER(handle_iod_command) -{ - if (CMD_ARGC != 1) - return ERROR_COMMAND_SYNTAX_ERROR; - - uint32_t address; - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], address); - if (address > 0xffff) { - LOG_ERROR("%s IA-32 I/O space is 2^16, 0x%08" PRIx32 " exceeds max", __func__, address); - 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; - } - unsigned count = 1; - uint8_t *buffer = calloc(count, size); - struct target *target = get_current_target(CMD_CTX); - int retval = x86_32_common_read_io(target, address, size, buffer); - if (ERROR_OK == retval) - handle_iod_output(CMD_CTX, target, address, size, count, buffer); - free(buffer); - return retval; -} - -static int target_fill_io(struct target *target, - uint32_t address, - unsigned data_size, - /* value */ - uint32_t b) -{ - LOG_DEBUG("address=0x%08" PRIx32 ", data_size=%u, b=0x%08" PRIx32, - address, data_size, b); - uint8_t target_buf[data_size]; - switch (data_size) { - case 4: - target_buffer_set_u32(target, target_buf, b); - break; - case 2: - target_buffer_set_u16(target, target_buf, b); - break; - case 1: - target_buf[0] = (b & 0x0ff); - break; - default: - exit(-1); - } - return x86_32_common_write_io(target, address, data_size, target_buf); -} - -COMMAND_HANDLER(handle_iow_command) -{ - if (CMD_ARGC != 2) - 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); - 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_io(target, address, wordsize, value); -} - -static const struct command_registration x86_32_exec_command_handlers[] = { - { - .name = "iww", - .mode = COMMAND_EXEC, - .handler = handle_iow_command, - .help = "write I/O port word", - .usage = "port data[word]", - }, - { - .name = "iwh", - .mode = COMMAND_EXEC, - .handler = handle_iow_command, - .help = "write I/O port halfword", - .usage = "port data[halfword]", - }, - { - .name = "iwb", - .mode = COMMAND_EXEC, - .handler = handle_iow_command, - .help = "write I/O port byte", - .usage = "port data[byte]", - }, - { - .name = "idw", - .mode = COMMAND_EXEC, - .handler = handle_iod_command, - .help = "display I/O port word", - .usage = "port", - }, - { - .name = "idh", - .mode = COMMAND_EXEC, - .handler = handle_iod_command, - .help = "display I/O port halfword", - .usage = "port", - }, - { - .name = "idb", - .mode = COMMAND_EXEC, - .handler = handle_iod_command, - .help = "display I/O port byte", - .usage = "port", - }, - - COMMAND_REGISTRATION_DONE -}; - -const struct command_registration x86_32_command_handlers[] = { - { - .name = "x86_32", - .mode = COMMAND_ANY, - .help = "x86_32 target commands", - .usage = "", - .chain = x86_32_exec_command_handlers, - }, - COMMAND_REGISTRATION_DONE -}; diff --git a/src/target/x86_32_common.h b/src/target/x86_32_common.h deleted file mode 100644 index b5877da4a..000000000 --- a/src/target/x86_32_common.h +++ /dev/null @@ -1,330 +0,0 @@ -/* - * 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) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - * Contact Information: - * Intel Corporation - */ - -/* - * @file - * This is the interface to the x86 32 bit memory and breakpoint operations. - */ - -#ifndef OPENOCD_TARGET_X86_32_COMMON_H -#define OPENOCD_TARGET_X86_32_COMMON_H - -#include -#include -#include - -extern const struct command_registration x86_32_command_handlers[]; - -/* for memory access */ -#define BYTE 1 -#define WORD 2 -#define DWORD 4 - -#define EFLAGS_TF ((uint32_t)0x00000100) /* Trap Flag */ -#define EFLAGS_IF ((uint32_t)0x00000200) /* Interrupt Flag */ -#define EFLAGS_RF ((uint32_t)0x00010000) /* Resume Flag */ -#define EFLAGS_VM86 ((uint32_t)0x00020000) /* Virtual 8086 Mode */ - -#define CSAR_DPL ((uint32_t)0x00006000) -#define CSAR_D ((uint32_t)0x00400000) -#define SSAR_DPL ((uint32_t)0x00006000) - -#define CR0_PE ((uint32_t)0x00000001) /* Protected Mode Enable */ -#define CR0_NW ((uint32_t)0x20000000) /* Non Write-Through */ -#define CR0_CD ((uint32_t)0x40000000) /* Cache Disable */ -#define CR0_PG ((uint32_t)0x80000000) /* Paging Enable */ - -/* TODO - move back to PM specific file */ -#define PM_DR6 ((uint32_t)0xFFFF0FF0) - -#define DR6_BRKDETECT_0 ((uint32_t)0x00000001) /* B0 through B3 */ -#define DR6_BRKDETECT_1 ((uint32_t)0x00000002) /* breakpoint condition detected */ -#define DR6_BRKDETECT_2 ((uint32_t)0x00000004) -#define DR6_BRKDETECT_3 ((uint32_t)0x00000008) - -enum { - /* general purpose registers */ - EAX = 0, - ECX, - EDX, - EBX, - ESP, - EBP, - ESI, - EDI, - /* instruction pointer & flags */ - EIP, - EFLAGS, - - /* segment registers */ - CS, - SS, - DS, - ES, - FS, - GS, - - /* floating point unit registers */ - ST0, - ST1, - ST2, - ST3, - ST4, - ST5, - ST6, - ST7, - FCTRL, - FSTAT, - FTAG, - FISEG, - FIOFF, - FOSEG, - FOOFF, - FOP, - - /* control registers */ - CR0, - CR2, - CR3, - CR4, - - /* debug registers */ - DR0, - DR1, - DR2, - DR3, - DR6, - DR7, - - /* descriptor tables */ - IDTB, - IDTL, - IDTAR, - GDTB, - GDTL, - GDTAR, - TR, - LDTR, - LDTB, - LDTL, - LDTAR, - - /* segment registers */ - CSB, - CSL, - CSAR, - DSB, - DSL, - DSAR, - ESB, - ESL, - ESAR, - FSB, - FSL, - FSAR, - GSB, - GSL, - GSAR, - SSB, - SSL, - SSAR, - TSSB, - TSSL, - TSSAR, - - /* PM control reg */ - PMCR, -}; - -#define X86_32_COMMON_MAGIC 0x86328632 - -enum { - /* memory read/write */ - MEMRDB32 = 0, - MEMRDB16, - MEMRDH32, - MEMRDH16, - MEMRDW32, - MEMRDW16, - MEMWRB32, - MEMWRB16, - MEMWRH32, - MEMWRH16, - MEMWRW32, - MEMWRW16, - /* IO read/write */ - IORDB32, - IORDB16, - IORDH32, - IORDH16, - IORDW32, - IORDW16, - IOWRB32, - IOWRB16, - IOWRH32, - IOWRH16, - IOWRW32, - IOWRW16, - /* lakemont1 core shadow ram access opcodes */ - SRAMACCESS, - SRAM2PDR, - PDR2SRAM, - WBINVD, -}; - -enum x86_core_type { - LMT1, - LMT3_5 -}; - -struct swbp_mem_patch { - uint8_t orig_byte; - uint32_t swbp_unique_id; - uint32_t physaddr; - struct swbp_mem_patch *next; -}; - -/* TODO - probemode specific - consider removing */ -#define NUM_PM_REGS 18 /* regs used in save/restore */ - -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; - int flush; - - /* pm_regs are for probemode save/restore state */ - uint32_t pm_regs[NUM_PM_REGS]; - - /* working area for fastdata access */ - struct working_area *fast_data_area; - - int num_hw_bpoints; - struct x86_32_dbg_reg *hw_break_list; - struct swbp_mem_patch *swbbp_mem_patch_list; - - /* core probemode implementation dependent functions */ - uint8_t (*get_num_user_regs)(struct target *t); - bool (*is_paging_enabled)(struct target *t); - int (*disable_paging)(struct target *t); - int (*enable_paging)(struct target *t); - bool (*sw_bpts_supported)(struct target *t); - int (*transaction_status)(struct target *t); - int (*submit_instruction)(struct target *t, int num); - int (*read_hw_reg)(struct target *t, int reg, uint32_t *regval, uint8_t cache); - int (*write_hw_reg)(struct target *t, int reg, - uint32_t regval, uint8_t cache); - - /* register cache to processor synchronization */ - int (*read_hw_reg_to_cache)(struct target *target, int num); - int (*write_hw_reg_from_cache)(struct target *target, int num); -}; - -static inline struct x86_32_common * -target_to_x86_32(struct target *target) -{ - return target->arch_info; -} -bool check_not_halted(const struct target *t); - -/* breakpoint defines */ -#define MAX_DEBUG_REGS 4 -#define SW_BP_OPCODE 0xf1 -#define MAX_SW_BPTS 20 - -struct x86_32_dbg_reg { - int used; - uint32_t bp_value; -}; - -#define DR7_G_ENABLE_SHIFT 1 -#define DR7_ENABLE_SIZE 2 /* 2 bits per debug reg */ -#define DR7_RW_SHIFT 16 -#define DR7_LENGTH_SHIFT 18 -#define DR7_RW_LEN_SIZE 4 -#define DR7_BP_EXECUTE 0 /* 00 - only on instruction execution*/ -#define DR7_BP_WRITE 1 /* 01 - only on data writes */ -/*#define DR7_RW_IORW 2 UNSUPPORTED 10 - an I/O read and I/O write */ -#define DR7_BP_READWRITE 3 /* on data read or data write */ -#define DR7_BP_LENGTH_1 0 /* 00 - 1 byte length */ -#define DR7_BP_LENGTH_2 1 /* 01 - 2 byte length */ -#define DR7_BP_LENGTH_4 3 /* 11 - 4 byte length */ - -#define DR7_GLOBAL_ENABLE(val, regnum) \ - (val |= (1 << (DR7_G_ENABLE_SHIFT + (DR7_ENABLE_SIZE * (regnum))))) - -#define DR7_GLOBAL_DISABLE(val, regnum) \ - (val &= ~(3 << (DR7_ENABLE_SIZE * (regnum)))) - -#define DR7_BP_FREE(val, regnum) \ - ((val & (3 << (DR7_ENABLE_SIZE * (regnum)))) == 0) - -#define DR7_RESET_RWLEN_BITS(val, regnum) \ - (val &= ~(0x0f << (DR7_RW_SHIFT + DR7_RW_LEN_SIZE * (regnum)))) - -#define DR7_SET_EXE(val, regnum) \ - (val &= ~(0x0f << (DR7_RW_SHIFT + DR7_RW_LEN_SIZE * (regnum)))) - -#define DR7_SET_WRITE(val, regnum) \ - (val |= (DR7_BP_WRITE << (DR7_RW_SHIFT + DR7_RW_LEN_SIZE * (regnum)))) - -#define DR7_SET_ACCESS(val, regnum) \ - (val |= (DR7_BP_READWRITE << (DR7_RW_SHIFT + DR7_RW_LEN_SIZE * (regnum)))) - -#define DR7_SET_LENGTH(val, regnum, len) \ - (val |= (len == 1) ? (DR7_BP_LENGTH_1 << (DR7_LENGTH_SHIFT + DR7_RW_LEN_SIZE * (regnum))) : \ - (len == 2) ? (DR7_BP_LENGTH_2 << (DR7_LENGTH_SHIFT + DR7_RW_LEN_SIZE * (regnum))) : \ - (DR7_BP_LENGTH_4 << (DR7_LENGTH_SHIFT + DR7_RW_LEN_SIZE * (regnum)))) - -/* public interface */ -int x86_32_get_gdb_reg_list(struct target *t, - struct reg **reg_list[], int *reg_list_size, - enum target_register_class reg_class); -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, - uint32_t size, uint32_t count, uint8_t *buffer); -int x86_32_common_write_phys_mem(struct target *t, uint32_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, - uint32_t size, uint32_t count, uint8_t *buf); -int x86_32_common_write_memory(struct target *t, uint32_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); -int x86_32_common_write_io(struct target *t, uint32_t addr, - uint32_t size, const uint8_t *buf); -int x86_32_common_add_breakpoint(struct target *t, struct breakpoint *bp); -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 /* OPENOCD_TARGET_X86_32_COMMON_H */ diff --git a/src/target/xscale.c b/src/target/xscale.c deleted file mode 100644 index 140ea586b..000000000 --- a/src/target/xscale.c +++ /dev/null @@ -1,3728 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2006, 2007 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * Copyright (C) 2007,2008 Øyvind Harboe * - * oyvind.harboe@zylin.com * - * * - * Copyright (C) 2009 Michael Schwingen * - * michael@schwingen.org * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "breakpoints.h" -#include "xscale.h" -#include "target_type.h" -#include "arm_jtag.h" -#include "arm_simulator.h" -#include "arm_disassembler.h" -#include -#include "register.h" -#include "image.h" -#include "arm_opcodes.h" -#include "armv4_5.h" - -/* - * Important XScale documents available as of October 2009 include: - * - * Intel XScale® Core Developer’s Manual, January 2004 - * Order Number: 273473-002 - * This has a chapter detailing debug facilities, and punts some - * details to chip-specific microarchitecture documents. - * - * Hot-Debug for Intel XScale® Core Debug White Paper, May 2005 - * Document Number: 273539-005 - * Less detailed than the developer's manual, but summarizes those - * missing details (for most XScales) and gives LOTS of notes about - * debugger/handler interaction issues. Presents a simpler reset - * and load-handler sequence than the arch doc. (Note, OpenOCD - * doesn't currently support "Hot-Debug" as defined there.) - * - * Chip-specific microarchitecture documents may also be useful. - */ - -/* forward declarations */ -static int xscale_resume(struct target *, int current, - uint32_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); -static int xscale_set_reg(struct reg *reg, uint8_t *buf); -static int xscale_set_breakpoint(struct target *, struct breakpoint *); -static int xscale_set_watchpoint(struct target *, struct watchpoint *); -static int xscale_unset_breakpoint(struct target *, struct breakpoint *); -static int xscale_read_trace(struct target *); - -/* This XScale "debug handler" is loaded into the processor's - * mini-ICache, which is 2K of code writable only via JTAG. - */ -static const uint8_t xscale_debug_handler[] = { -#include "xscale_debug.inc" -}; - -static const char *const xscale_reg_list[] = { - "XSCALE_MAINID", /* 0 */ - "XSCALE_CACHETYPE", - "XSCALE_CTRL", - "XSCALE_AUXCTRL", - "XSCALE_TTB", - "XSCALE_DAC", - "XSCALE_FSR", - "XSCALE_FAR", - "XSCALE_PID", - "XSCALE_CPACCESS", - "XSCALE_IBCR0", /* 10 */ - "XSCALE_IBCR1", - "XSCALE_DBR0", - "XSCALE_DBR1", - "XSCALE_DBCON", - "XSCALE_TBREG", - "XSCALE_CHKPT0", - "XSCALE_CHKPT1", - "XSCALE_DCSR", - "XSCALE_TX", - "XSCALE_RX", /* 20 */ - "XSCALE_TXRXCTRL", -}; - -static const struct xscale_reg xscale_reg_arch_info[] = { - {XSCALE_MAINID, NULL}, - {XSCALE_CACHETYPE, NULL}, - {XSCALE_CTRL, NULL}, - {XSCALE_AUXCTRL, NULL}, - {XSCALE_TTB, NULL}, - {XSCALE_DAC, NULL}, - {XSCALE_FSR, NULL}, - {XSCALE_FAR, NULL}, - {XSCALE_PID, NULL}, - {XSCALE_CPACCESS, NULL}, - {XSCALE_IBCR0, NULL}, - {XSCALE_IBCR1, NULL}, - {XSCALE_DBR0, NULL}, - {XSCALE_DBR1, NULL}, - {XSCALE_DBCON, NULL}, - {XSCALE_TBREG, NULL}, - {XSCALE_CHKPT0, NULL}, - {XSCALE_CHKPT1, NULL}, - {XSCALE_DCSR, NULL}, /* DCSR accessed via JTAG or SW */ - {-1, NULL}, /* TX accessed via JTAG */ - {-1, NULL}, /* RX accessed via JTAG */ - {-1, NULL}, /* TXRXCTRL implicit access via JTAG */ -}; - -/* convenience wrapper to access XScale specific registers */ -static int xscale_set_reg_u32(struct reg *reg, uint32_t value) -{ - uint8_t buf[4]; - - buf_set_u32(buf, 0, 32, value); - - return xscale_set_reg(reg, buf); -} - -static const char xscale_not[] = "target is not an XScale"; - -static int xscale_verify_pointer(struct command_context *cmd_ctx, - struct xscale_common *xscale) -{ - if (xscale->common_magic != XSCALE_COMMON_MAGIC) { - command_print(cmd_ctx, xscale_not); - return ERROR_TARGET_INVALID; - } - return ERROR_OK; -} - -static int xscale_jtag_set_instr(struct jtag_tap *tap, uint32_t new_instr, tap_state_t end_state) -{ - assert(tap != NULL); - - if (buf_get_u32(tap->cur_instr, 0, tap->ir_length) != new_instr) { - struct scan_field field; - uint8_t scratch[4]; - - memset(&field, 0, sizeof field); - field.num_bits = tap->ir_length; - field.out_value = scratch; - buf_set_u32(scratch, 0, field.num_bits, new_instr); - - jtag_add_ir_scan(tap, &field, end_state); - } - - return ERROR_OK; -} - -static int xscale_read_dcsr(struct target *target) -{ - struct xscale_common *xscale = target_to_xscale(target); - int retval; - struct scan_field fields[3]; - uint8_t field0 = 0x0; - uint8_t field0_check_value = 0x2; - uint8_t field0_check_mask = 0x7; - uint8_t field2 = 0x0; - uint8_t field2_check_value = 0x0; - uint8_t field2_check_mask = 0x1; - - xscale_jtag_set_instr(target->tap, - XSCALE_SELDCSR << xscale->xscale_variant, - TAP_DRPAUSE); - - buf_set_u32(&field0, 1, 1, xscale->hold_rst); - buf_set_u32(&field0, 2, 1, xscale->external_debug_break); - - memset(&fields, 0, sizeof fields); - - fields[0].num_bits = 3; - fields[0].out_value = &field0; - uint8_t tmp; - fields[0].in_value = &tmp; - - fields[1].num_bits = 32; - fields[1].in_value = xscale->reg_cache->reg_list[XSCALE_DCSR].value; - - fields[2].num_bits = 1; - fields[2].out_value = &field2; - uint8_t tmp2; - fields[2].in_value = &tmp2; - - jtag_add_dr_scan(target->tap, 3, fields, TAP_DRPAUSE); - - jtag_check_value_mask(fields + 0, &field0_check_value, &field0_check_mask); - jtag_check_value_mask(fields + 2, &field2_check_value, &field2_check_mask); - - retval = jtag_execute_queue(); - if (retval != ERROR_OK) { - LOG_ERROR("JTAG error while reading DCSR"); - return retval; - } - - xscale->reg_cache->reg_list[XSCALE_DCSR].dirty = 0; - xscale->reg_cache->reg_list[XSCALE_DCSR].valid = 1; - - /* write the register with the value we just read - * on this second pass, only the first bit of field0 is guaranteed to be 0) - */ - field0_check_mask = 0x1; - fields[1].out_value = xscale->reg_cache->reg_list[XSCALE_DCSR].value; - fields[1].in_value = NULL; - - jtag_add_dr_scan(target->tap, 3, fields, TAP_DRPAUSE); - - /* DANGER!!! this must be here. It will make sure that the arguments - * to jtag_set_check_value() does not go out of scope! */ - return jtag_execute_queue(); -} - - -static void xscale_getbuf(jtag_callback_data_t arg) -{ - uint8_t *in = (uint8_t *)arg; - *((uint32_t *)arg) = buf_get_u32(in, 0, 32); -} - -static int xscale_receive(struct target *target, uint32_t *buffer, int num_words) -{ - if (num_words == 0) - return ERROR_COMMAND_SYNTAX_ERROR; - - struct xscale_common *xscale = target_to_xscale(target); - int retval = ERROR_OK; - tap_state_t path[3]; - struct scan_field fields[3]; - uint8_t *field0 = malloc(num_words * 1); - uint8_t field0_check_value = 0x2; - uint8_t field0_check_mask = 0x6; - uint32_t *field1 = malloc(num_words * 4); - uint8_t field2_check_value = 0x0; - uint8_t field2_check_mask = 0x1; - int words_done = 0; - int words_scheduled = 0; - int i; - - path[0] = TAP_DRSELECT; - path[1] = TAP_DRCAPTURE; - path[2] = TAP_DRSHIFT; - - memset(&fields, 0, sizeof fields); - - fields[0].num_bits = 3; - uint8_t tmp; - fields[0].in_value = &tmp; - fields[0].check_value = &field0_check_value; - fields[0].check_mask = &field0_check_mask; - - fields[1].num_bits = 32; - - fields[2].num_bits = 1; - uint8_t tmp2; - fields[2].in_value = &tmp2; - fields[2].check_value = &field2_check_value; - fields[2].check_mask = &field2_check_mask; - - xscale_jtag_set_instr(target->tap, - XSCALE_DBGTX << xscale->xscale_variant, - TAP_IDLE); - jtag_add_runtest(1, TAP_IDLE); /* ensures that we're in the TAP_IDLE state as the above - *could be a no-op */ - - /* repeat until all words have been collected */ - int attempts = 0; - while (words_done < num_words) { - /* schedule reads */ - words_scheduled = 0; - for (i = words_done; i < num_words; i++) { - fields[0].in_value = &field0[i]; - - jtag_add_pathmove(3, path); - - fields[1].in_value = (uint8_t *)(field1 + i); - - jtag_add_dr_scan_check(target->tap, 3, fields, TAP_IDLE); - - jtag_add_callback(xscale_getbuf, (jtag_callback_data_t)(field1 + i)); - - words_scheduled++; - } - - retval = jtag_execute_queue(); - if (retval != ERROR_OK) { - LOG_ERROR("JTAG error while receiving data from debug handler"); - break; - } - - /* examine results */ - for (i = words_done; i < num_words; i++) { - if (!(field0[i] & 1)) { - /* move backwards if necessary */ - int j; - for (j = i; j < num_words - 1; j++) { - field0[j] = field0[j + 1]; - field1[j] = field1[j + 1]; - } - words_scheduled--; - } - } - if (words_scheduled == 0) { - if (attempts++ == 1000) { - LOG_ERROR( - "Failed to receiving data from debug handler after 1000 attempts"); - retval = ERROR_TARGET_TIMEOUT; - break; - } - } - - words_done += words_scheduled; - } - - for (i = 0; i < num_words; i++) - *(buffer++) = buf_get_u32((uint8_t *)&field1[i], 0, 32); - - free(field1); - - return retval; -} - -static int xscale_read_tx(struct target *target, int consume) -{ - struct xscale_common *xscale = target_to_xscale(target); - tap_state_t path[3]; - tap_state_t noconsume_path[6]; - int retval; - struct timeval timeout, now; - struct scan_field fields[3]; - uint8_t field0_in = 0x0; - uint8_t field0_check_value = 0x2; - uint8_t field0_check_mask = 0x6; - uint8_t field2_check_value = 0x0; - uint8_t field2_check_mask = 0x1; - - xscale_jtag_set_instr(target->tap, - XSCALE_DBGTX << xscale->xscale_variant, - TAP_IDLE); - - path[0] = TAP_DRSELECT; - path[1] = TAP_DRCAPTURE; - path[2] = TAP_DRSHIFT; - - noconsume_path[0] = TAP_DRSELECT; - noconsume_path[1] = TAP_DRCAPTURE; - noconsume_path[2] = TAP_DREXIT1; - noconsume_path[3] = TAP_DRPAUSE; - noconsume_path[4] = TAP_DREXIT2; - noconsume_path[5] = TAP_DRSHIFT; - - memset(&fields, 0, sizeof fields); - - fields[0].num_bits = 3; - fields[0].in_value = &field0_in; - - fields[1].num_bits = 32; - fields[1].in_value = xscale->reg_cache->reg_list[XSCALE_TX].value; - - fields[2].num_bits = 1; - uint8_t tmp; - fields[2].in_value = &tmp; - - gettimeofday(&timeout, NULL); - timeval_add_time(&timeout, 1, 0); - - for (;; ) { - /* if we want to consume the register content (i.e. clear TX_READY), - * we have to go straight from Capture-DR to Shift-DR - * otherwise, we go from Capture-DR to Exit1-DR to Pause-DR - */ - if (consume) - jtag_add_pathmove(3, path); - else - jtag_add_pathmove(ARRAY_SIZE(noconsume_path), noconsume_path); - - jtag_add_dr_scan(target->tap, 3, fields, TAP_IDLE); - - jtag_check_value_mask(fields + 0, &field0_check_value, &field0_check_mask); - jtag_check_value_mask(fields + 2, &field2_check_value, &field2_check_mask); - - retval = jtag_execute_queue(); - if (retval != ERROR_OK) { - LOG_ERROR("JTAG error while reading TX"); - return ERROR_TARGET_TIMEOUT; - } - - gettimeofday(&now, NULL); - if ((now.tv_sec > timeout.tv_sec) || - ((now.tv_sec == timeout.tv_sec) && (now.tv_usec > timeout.tv_usec))) { - LOG_ERROR("time out reading TX register"); - return ERROR_TARGET_TIMEOUT; - } - if (!((!(field0_in & 1)) && consume)) - goto done; - if (debug_level >= 3) { - LOG_DEBUG("waiting 100ms"); - alive_sleep(100); /* avoid flooding the logs */ - } else - keep_alive(); - } -done: - - if (!(field0_in & 1)) - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - - return ERROR_OK; -} - -static int xscale_write_rx(struct target *target) -{ - struct xscale_common *xscale = target_to_xscale(target); - int retval; - struct timeval timeout, now; - struct scan_field fields[3]; - uint8_t field0_out = 0x0; - uint8_t field0_in = 0x0; - uint8_t field0_check_value = 0x2; - uint8_t field0_check_mask = 0x6; - uint8_t field2 = 0x0; - uint8_t field2_check_value = 0x0; - uint8_t field2_check_mask = 0x1; - - xscale_jtag_set_instr(target->tap, - XSCALE_DBGRX << xscale->xscale_variant, - TAP_IDLE); - - memset(&fields, 0, sizeof fields); - - fields[0].num_bits = 3; - fields[0].out_value = &field0_out; - fields[0].in_value = &field0_in; - - fields[1].num_bits = 32; - fields[1].out_value = xscale->reg_cache->reg_list[XSCALE_RX].value; - - fields[2].num_bits = 1; - fields[2].out_value = &field2; - uint8_t tmp; - fields[2].in_value = &tmp; - - gettimeofday(&timeout, NULL); - timeval_add_time(&timeout, 1, 0); - - /* poll until rx_read is low */ - LOG_DEBUG("polling RX"); - for (;;) { - jtag_add_dr_scan(target->tap, 3, fields, TAP_IDLE); - - jtag_check_value_mask(fields + 0, &field0_check_value, &field0_check_mask); - jtag_check_value_mask(fields + 2, &field2_check_value, &field2_check_mask); - - retval = jtag_execute_queue(); - if (retval != ERROR_OK) { - LOG_ERROR("JTAG error while writing RX"); - return retval; - } - - gettimeofday(&now, NULL); - if ((now.tv_sec > timeout.tv_sec) || - ((now.tv_sec == timeout.tv_sec) && (now.tv_usec > timeout.tv_usec))) { - LOG_ERROR("time out writing RX register"); - return ERROR_TARGET_TIMEOUT; - } - if (!(field0_in & 1)) - goto done; - if (debug_level >= 3) { - LOG_DEBUG("waiting 100ms"); - alive_sleep(100); /* avoid flooding the logs */ - } else - keep_alive(); - } -done: - - /* set rx_valid */ - field2 = 0x1; - jtag_add_dr_scan(target->tap, 3, fields, TAP_IDLE); - - retval = jtag_execute_queue(); - if (retval != ERROR_OK) { - LOG_ERROR("JTAG error while writing RX"); - return retval; - } - - return ERROR_OK; -} - -/* send count elements of size byte to the debug handler */ -static int xscale_send(struct target *target, const uint8_t *buffer, int count, int size) -{ - struct xscale_common *xscale = target_to_xscale(target); - int retval; - int done_count = 0; - - xscale_jtag_set_instr(target->tap, - XSCALE_DBGRX << xscale->xscale_variant, - TAP_IDLE); - - static const uint8_t t0; - uint8_t t1[4]; - static const uint8_t t2 = 1; - struct scan_field fields[3] = { - { .num_bits = 3, .out_value = &t0 }, - { .num_bits = 32, .out_value = t1 }, - { .num_bits = 1, .out_value = &t2 }, - }; - - int endianness = target->endianness; - while (done_count++ < count) { - uint32_t t; - - switch (size) { - case 4: - if (endianness == TARGET_LITTLE_ENDIAN) - t = le_to_h_u32(buffer); - else - t = be_to_h_u32(buffer); - break; - case 2: - if (endianness == TARGET_LITTLE_ENDIAN) - t = le_to_h_u16(buffer); - else - t = be_to_h_u16(buffer); - break; - case 1: - t = buffer[0]; - break; - default: - LOG_ERROR("BUG: size neither 4, 2 nor 1"); - return ERROR_COMMAND_SYNTAX_ERROR; - } - - buf_set_u32(t1, 0, 32, t); - - jtag_add_dr_scan(target->tap, - 3, - fields, - TAP_IDLE); - buffer += size; - } - - retval = jtag_execute_queue(); - if (retval != ERROR_OK) { - LOG_ERROR("JTAG error while sending data to debug handler"); - return retval; - } - - return ERROR_OK; -} - -static int xscale_send_u32(struct target *target, uint32_t value) -{ - struct xscale_common *xscale = target_to_xscale(target); - - buf_set_u32(xscale->reg_cache->reg_list[XSCALE_RX].value, 0, 32, value); - return xscale_write_rx(target); -} - -static int xscale_write_dcsr(struct target *target, int hold_rst, int ext_dbg_brk) -{ - struct xscale_common *xscale = target_to_xscale(target); - int retval; - struct scan_field fields[3]; - uint8_t field0 = 0x0; - uint8_t field0_check_value = 0x2; - uint8_t field0_check_mask = 0x7; - uint8_t field2 = 0x0; - uint8_t field2_check_value = 0x0; - uint8_t field2_check_mask = 0x1; - - if (hold_rst != -1) - xscale->hold_rst = hold_rst; - - if (ext_dbg_brk != -1) - xscale->external_debug_break = ext_dbg_brk; - - xscale_jtag_set_instr(target->tap, - XSCALE_SELDCSR << xscale->xscale_variant, - TAP_IDLE); - - buf_set_u32(&field0, 1, 1, xscale->hold_rst); - buf_set_u32(&field0, 2, 1, xscale->external_debug_break); - - memset(&fields, 0, sizeof fields); - - fields[0].num_bits = 3; - fields[0].out_value = &field0; - uint8_t tmp; - fields[0].in_value = &tmp; - - fields[1].num_bits = 32; - fields[1].out_value = xscale->reg_cache->reg_list[XSCALE_DCSR].value; - - fields[2].num_bits = 1; - fields[2].out_value = &field2; - uint8_t tmp2; - fields[2].in_value = &tmp2; - - jtag_add_dr_scan(target->tap, 3, fields, TAP_IDLE); - - jtag_check_value_mask(fields + 0, &field0_check_value, &field0_check_mask); - jtag_check_value_mask(fields + 2, &field2_check_value, &field2_check_mask); - - retval = jtag_execute_queue(); - if (retval != ERROR_OK) { - LOG_ERROR("JTAG error while writing DCSR"); - return retval; - } - - xscale->reg_cache->reg_list[XSCALE_DCSR].dirty = 0; - xscale->reg_cache->reg_list[XSCALE_DCSR].valid = 1; - - return ERROR_OK; -} - -/* parity of the number of bits 0 if even; 1 if odd. for 32 bit words */ -static unsigned int parity(unsigned int v) -{ - /* unsigned int ov = v; */ - v ^= v >> 16; - v ^= v >> 8; - v ^= v >> 4; - v &= 0xf; - /* LOG_DEBUG("parity of 0x%x is %i", ov, (0x6996 >> v) & 1); */ - return (0x6996 >> v) & 1; -} - -static int xscale_load_ic(struct target *target, uint32_t va, uint32_t buffer[8]) -{ - struct xscale_common *xscale = target_to_xscale(target); - uint8_t packet[4]; - uint8_t cmd; - int word; - struct scan_field fields[2]; - - LOG_DEBUG("loading miniIC at 0x%8.8" PRIx32 "", va); - - /* LDIC into IR */ - xscale_jtag_set_instr(target->tap, - XSCALE_LDIC << xscale->xscale_variant, - TAP_IDLE); - - /* CMD is b011 to load a cacheline into the Mini ICache. - * Loading into the main ICache is deprecated, and unused. - * It's followed by three zero bits, and 27 address bits. - */ - buf_set_u32(&cmd, 0, 6, 0x3); - - /* virtual address of desired cache line */ - buf_set_u32(packet, 0, 27, va >> 5); - - memset(&fields, 0, sizeof fields); - - fields[0].num_bits = 6; - fields[0].out_value = &cmd; - - fields[1].num_bits = 27; - fields[1].out_value = packet; - - jtag_add_dr_scan(target->tap, 2, fields, TAP_IDLE); - - /* rest of packet is a cacheline: 8 instructions, with parity */ - fields[0].num_bits = 32; - fields[0].out_value = packet; - - fields[1].num_bits = 1; - fields[1].out_value = &cmd; - - for (word = 0; word < 8; word++) { - buf_set_u32(packet, 0, 32, buffer[word]); - - uint32_t value; - memcpy(&value, packet, sizeof(uint32_t)); - cmd = parity(value); - - jtag_add_dr_scan(target->tap, 2, fields, TAP_IDLE); - } - - return jtag_execute_queue(); -} - -static int xscale_invalidate_ic_line(struct target *target, uint32_t va) -{ - struct xscale_common *xscale = target_to_xscale(target); - uint8_t packet[4]; - uint8_t cmd; - struct scan_field fields[2]; - - xscale_jtag_set_instr(target->tap, - XSCALE_LDIC << xscale->xscale_variant, - TAP_IDLE); - - /* CMD for invalidate IC line b000, bits [6:4] b000 */ - buf_set_u32(&cmd, 0, 6, 0x0); - - /* virtual address of desired cache line */ - buf_set_u32(packet, 0, 27, va >> 5); - - memset(&fields, 0, sizeof fields); - - fields[0].num_bits = 6; - fields[0].out_value = &cmd; - - fields[1].num_bits = 27; - fields[1].out_value = packet; - - jtag_add_dr_scan(target->tap, 2, fields, TAP_IDLE); - - return ERROR_OK; -} - -static int xscale_update_vectors(struct target *target) -{ - struct xscale_common *xscale = target_to_xscale(target); - int i; - int retval; - - uint32_t low_reset_branch, high_reset_branch; - - for (i = 1; i < 8; i++) { - /* if there's a static vector specified for this exception, override */ - if (xscale->static_high_vectors_set & (1 << i)) - xscale->high_vectors[i] = xscale->static_high_vectors[i]; - else { - retval = target_read_u32(target, 0xffff0000 + 4*i, &xscale->high_vectors[i]); - if (retval == ERROR_TARGET_TIMEOUT) - return retval; - if (retval != ERROR_OK) { - /* Some of these reads will fail as part of normal execution */ - xscale->high_vectors[i] = ARMV4_5_B(0xfffffe, 0); - } - } - } - - for (i = 1; i < 8; i++) { - if (xscale->static_low_vectors_set & (1 << i)) - xscale->low_vectors[i] = xscale->static_low_vectors[i]; - else { - retval = target_read_u32(target, 0x0 + 4*i, &xscale->low_vectors[i]); - if (retval == ERROR_TARGET_TIMEOUT) - return retval; - if (retval != ERROR_OK) { - /* Some of these reads will fail as part of normal execution */ - xscale->low_vectors[i] = ARMV4_5_B(0xfffffe, 0); - } - } - } - - /* calculate branches to debug handler */ - low_reset_branch = (xscale->handler_address + 0x20 - 0x0 - 0x8) >> 2; - high_reset_branch = (xscale->handler_address + 0x20 - 0xffff0000 - 0x8) >> 2; - - xscale->low_vectors[0] = ARMV4_5_B((low_reset_branch & 0xffffff), 0); - xscale->high_vectors[0] = ARMV4_5_B((high_reset_branch & 0xffffff), 0); - - /* invalidate and load exception vectors in mini i-cache */ - xscale_invalidate_ic_line(target, 0x0); - xscale_invalidate_ic_line(target, 0xffff0000); - - xscale_load_ic(target, 0x0, xscale->low_vectors); - xscale_load_ic(target, 0xffff0000, xscale->high_vectors); - - return ERROR_OK; -} - -static int xscale_arch_state(struct target *target) -{ - struct xscale_common *xscale = target_to_xscale(target); - struct arm *arm = &xscale->arm; - - static const char *state[] = { - "disabled", "enabled" - }; - - static const char *arch_dbg_reason[] = { - "", "\n(processor reset)", "\n(trace buffer full)" - }; - - if (arm->common_magic != ARM_COMMON_MAGIC) { - LOG_ERROR("BUG: called for a non-ARMv4/5 target"); - return ERROR_COMMAND_SYNTAX_ERROR; - } - - arm_arch_state(target); - LOG_USER("MMU: %s, D-Cache: %s, I-Cache: %s%s", - state[xscale->armv4_5_mmu.mmu_enabled], - state[xscale->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled], - state[xscale->armv4_5_mmu.armv4_5_cache.i_cache_enabled], - arch_dbg_reason[xscale->arch_debug_reason]); - - return ERROR_OK; -} - -static int xscale_poll(struct target *target) -{ - int retval = ERROR_OK; - - if ((target->state == TARGET_RUNNING) || (target->state == TARGET_DEBUG_RUNNING)) { - enum target_state previous_state = target->state; - retval = xscale_read_tx(target, 0); - if (retval == ERROR_OK) { - - /* there's data to read from the tx register, we entered debug state */ - target->state = TARGET_HALTED; - - /* process debug entry, fetching current mode regs */ - retval = xscale_debug_entry(target); - } else if (retval != ERROR_TARGET_RESOURCE_NOT_AVAILABLE) { - LOG_USER("error while polling TX register, reset CPU"); - /* here we "lie" so GDB won't get stuck and a reset can be perfomed */ - target->state = TARGET_HALTED; - } - - /* debug_entry could have overwritten target state (i.e. immediate resume) - * don't signal event handlers in that case - */ - if (target->state != TARGET_HALTED) - return ERROR_OK; - - /* if target was running, signal that we halted - * otherwise we reentered from debug execution */ - if (previous_state == TARGET_RUNNING) - target_call_event_callbacks(target, TARGET_EVENT_HALTED); - else - target_call_event_callbacks(target, TARGET_EVENT_DEBUG_HALTED); - } - - return retval; -} - -static int xscale_debug_entry(struct target *target) -{ - struct xscale_common *xscale = target_to_xscale(target); - struct arm *arm = &xscale->arm; - uint32_t pc; - uint32_t buffer[10]; - unsigned i; - int retval; - uint32_t moe; - - /* clear external dbg break (will be written on next DCSR read) */ - xscale->external_debug_break = 0; - retval = xscale_read_dcsr(target); - if (retval != ERROR_OK) - return retval; - - /* get r0, pc, r1 to r7 and cpsr */ - retval = xscale_receive(target, buffer, 10); - if (retval != ERROR_OK) - return retval; - - /* move r0 from buffer to register cache */ - buf_set_u32(arm->core_cache->reg_list[0].value, 0, 32, buffer[0]); - arm->core_cache->reg_list[0].dirty = 1; - arm->core_cache->reg_list[0].valid = 1; - LOG_DEBUG("r0: 0x%8.8" PRIx32 "", buffer[0]); - - /* move pc from buffer to register cache */ - buf_set_u32(arm->pc->value, 0, 32, buffer[1]); - arm->pc->dirty = 1; - arm->pc->valid = 1; - LOG_DEBUG("pc: 0x%8.8" PRIx32 "", buffer[1]); - - /* move data from buffer to register cache */ - for (i = 1; i <= 7; i++) { - buf_set_u32(arm->core_cache->reg_list[i].value, 0, 32, buffer[1 + i]); - arm->core_cache->reg_list[i].dirty = 1; - arm->core_cache->reg_list[i].valid = 1; - LOG_DEBUG("r%i: 0x%8.8" PRIx32 "", i, buffer[i + 1]); - } - - arm_set_cpsr(arm, buffer[9]); - LOG_DEBUG("cpsr: 0x%8.8" PRIx32 "", buffer[9]); - - if (!is_arm_mode(arm->core_mode)) { - target->state = TARGET_UNKNOWN; - LOG_ERROR("cpsr contains invalid mode value - communication failure"); - return ERROR_TARGET_FAILURE; - } - LOG_DEBUG("target entered debug state in %s mode", - arm_mode_name(arm->core_mode)); - - /* get banked registers, r8 to r14, and spsr if not in USR/SYS mode */ - if (arm->spsr) { - xscale_receive(target, buffer, 8); - buf_set_u32(arm->spsr->value, 0, 32, buffer[7]); - arm->spsr->dirty = false; - arm->spsr->valid = true; - } else { - /* r8 to r14, but no spsr */ - xscale_receive(target, buffer, 7); - } - - /* move data from buffer to right banked register in cache */ - for (i = 8; i <= 14; i++) { - struct reg *r = arm_reg_current(arm, i); - - buf_set_u32(r->value, 0, 32, buffer[i - 8]); - r->dirty = false; - r->valid = true; - } - - /* mark xscale regs invalid to ensure they are retrieved from the - * debug handler if requested */ - for (i = 0; i < xscale->reg_cache->num_regs; i++) - xscale->reg_cache->reg_list[i].valid = 0; - - /* examine debug reason */ - xscale_read_dcsr(target); - moe = buf_get_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 2, 3); - - /* stored PC (for calculating fixup) */ - pc = buf_get_u32(arm->pc->value, 0, 32); - - switch (moe) { - case 0x0: /* Processor reset */ - target->debug_reason = DBG_REASON_DBGRQ; - xscale->arch_debug_reason = XSCALE_DBG_REASON_RESET; - pc -= 4; - break; - case 0x1: /* Instruction breakpoint hit */ - target->debug_reason = DBG_REASON_BREAKPOINT; - xscale->arch_debug_reason = XSCALE_DBG_REASON_GENERIC; - pc -= 4; - break; - case 0x2: /* Data breakpoint hit */ - target->debug_reason = DBG_REASON_WATCHPOINT; - xscale->arch_debug_reason = XSCALE_DBG_REASON_GENERIC; - pc -= 4; - break; - case 0x3: /* BKPT instruction executed */ - target->debug_reason = DBG_REASON_BREAKPOINT; - xscale->arch_debug_reason = XSCALE_DBG_REASON_GENERIC; - pc -= 4; - break; - case 0x4: /* Ext. debug event */ - target->debug_reason = DBG_REASON_DBGRQ; - xscale->arch_debug_reason = XSCALE_DBG_REASON_GENERIC; - pc -= 4; - break; - case 0x5: /* Vector trap occured */ - target->debug_reason = DBG_REASON_BREAKPOINT; - xscale->arch_debug_reason = XSCALE_DBG_REASON_GENERIC; - pc -= 4; - break; - case 0x6: /* Trace buffer full break */ - target->debug_reason = DBG_REASON_DBGRQ; - xscale->arch_debug_reason = XSCALE_DBG_REASON_TB_FULL; - pc -= 4; - break; - case 0x7: /* Reserved (may flag Hot-Debug support) */ - default: - LOG_ERROR("Method of Entry is 'Reserved'"); - exit(-1); - break; - } - - /* apply PC fixup */ - buf_set_u32(arm->pc->value, 0, 32, pc); - - /* on the first debug entry, identify cache type */ - if (xscale->armv4_5_mmu.armv4_5_cache.ctype == -1) { - uint32_t cache_type_reg; - - /* read cp15 cache type register */ - xscale_get_reg(&xscale->reg_cache->reg_list[XSCALE_CACHETYPE]); - cache_type_reg = buf_get_u32(xscale->reg_cache->reg_list[XSCALE_CACHETYPE].value, - 0, - 32); - - armv4_5_identify_cache(cache_type_reg, &xscale->armv4_5_mmu.armv4_5_cache); - } - - /* examine MMU and Cache settings - * read cp15 control register */ - xscale_get_reg(&xscale->reg_cache->reg_list[XSCALE_CTRL]); - xscale->cp15_control_reg = - buf_get_u32(xscale->reg_cache->reg_list[XSCALE_CTRL].value, 0, 32); - xscale->armv4_5_mmu.mmu_enabled = (xscale->cp15_control_reg & 0x1U) ? 1 : 0; - xscale->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled = - (xscale->cp15_control_reg & 0x4U) ? 1 : 0; - xscale->armv4_5_mmu.armv4_5_cache.i_cache_enabled = - (xscale->cp15_control_reg & 0x1000U) ? 1 : 0; - - /* tracing enabled, read collected trace data */ - if (xscale->trace.mode != XSCALE_TRACE_DISABLED) { - xscale_read_trace(target); - - /* Resume if entered debug due to buffer fill and we're still collecting - * trace data. Note that a debug exception due to trace buffer full - * can only happen in fill mode. */ - if (xscale->arch_debug_reason == XSCALE_DBG_REASON_TB_FULL) { - if (--xscale->trace.fill_counter > 0) - xscale_resume(target, 1, 0x0, 1, 0); - } else /* entered debug for other reason; reset counter */ - xscale->trace.fill_counter = 0; - } - - return ERROR_OK; -} - -static int xscale_halt(struct target *target) -{ - struct xscale_common *xscale = target_to_xscale(target); - - LOG_DEBUG("target->state: %s", - target_state_name(target)); - - if (target->state == TARGET_HALTED) { - LOG_DEBUG("target was already halted"); - return ERROR_OK; - } else if (target->state == TARGET_UNKNOWN) { - /* this must not happen for a xscale target */ - LOG_ERROR("target was in unknown state when halt was requested"); - return ERROR_TARGET_INVALID; - } else if (target->state == TARGET_RESET) - LOG_DEBUG("target->state == TARGET_RESET"); - else { - /* assert external dbg break */ - xscale->external_debug_break = 1; - xscale_read_dcsr(target); - - target->debug_reason = DBG_REASON_DBGRQ; - } - - return ERROR_OK; -} - -static int xscale_enable_single_step(struct target *target, uint32_t next_pc) -{ - struct xscale_common *xscale = target_to_xscale(target); - struct reg *ibcr0 = &xscale->reg_cache->reg_list[XSCALE_IBCR0]; - int retval; - - if (xscale->ibcr0_used) { - struct breakpoint *ibcr0_bp = - breakpoint_find(target, buf_get_u32(ibcr0->value, 0, 32) & 0xfffffffe); - - if (ibcr0_bp) - xscale_unset_breakpoint(target, ibcr0_bp); - else { - LOG_ERROR( - "BUG: xscale->ibcr0_used is set, but no breakpoint with that address found"); - exit(-1); - } - } - - retval = xscale_set_reg_u32(ibcr0, next_pc | 0x1); - if (retval != ERROR_OK) - return retval; - - return ERROR_OK; -} - -static int xscale_disable_single_step(struct target *target) -{ - struct xscale_common *xscale = target_to_xscale(target); - struct reg *ibcr0 = &xscale->reg_cache->reg_list[XSCALE_IBCR0]; - int retval; - - retval = xscale_set_reg_u32(ibcr0, 0x0); - if (retval != ERROR_OK) - return retval; - - return ERROR_OK; -} - -static void xscale_enable_watchpoints(struct target *target) -{ - struct watchpoint *watchpoint = target->watchpoints; - - while (watchpoint) { - if (watchpoint->set == 0) - xscale_set_watchpoint(target, watchpoint); - watchpoint = watchpoint->next; - } -} - -static void xscale_enable_breakpoints(struct target *target) -{ - struct breakpoint *breakpoint = target->breakpoints; - - /* set any pending breakpoints */ - while (breakpoint) { - if (breakpoint->set == 0) - xscale_set_breakpoint(target, breakpoint); - breakpoint = breakpoint->next; - } -} - -static void xscale_free_trace_data(struct xscale_common *xscale) -{ - struct xscale_trace_data *td = xscale->trace.data; - while (td) { - struct xscale_trace_data *next_td = td->next; - if (td->entries) - free(td->entries); - free(td); - td = next_td; - } - xscale->trace.data = NULL; -} - -static int xscale_resume(struct target *target, int current, - uint32_t address, int handle_breakpoints, int debug_execution) -{ - struct xscale_common *xscale = target_to_xscale(target); - struct arm *arm = &xscale->arm; - uint32_t current_pc; - int retval; - int i; - - LOG_DEBUG("-"); - - if (target->state != TARGET_HALTED) { - LOG_WARNING("target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - if (!debug_execution) - target_free_all_working_areas(target); - - /* update vector tables */ - retval = xscale_update_vectors(target); - if (retval != ERROR_OK) - return retval; - - /* current = 1: continue on current pc, otherwise continue at
*/ - if (!current) - buf_set_u32(arm->pc->value, 0, 32, address); - - current_pc = buf_get_u32(arm->pc->value, 0, 32); - - /* if we're at the reset vector, we have to simulate the branch */ - if (current_pc == 0x0) { - arm_simulate_step(target, NULL); - current_pc = buf_get_u32(arm->pc->value, 0, 32); - } - - /* the front-end may request us not to handle breakpoints */ - if (handle_breakpoints) { - struct breakpoint *breakpoint; - breakpoint = breakpoint_find(target, - buf_get_u32(arm->pc->value, 0, 32)); - if (breakpoint != NULL) { - uint32_t next_pc; - 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); - xscale_unset_breakpoint(target, breakpoint); - - /* calculate PC of next instruction */ - retval = arm_simulate_step(target, &next_pc); - if (retval != ERROR_OK) { - uint32_t current_opcode; - target_read_u32(target, current_pc, ¤t_opcode); - LOG_ERROR( - "BUG: couldn't calculate PC of next instruction, current opcode was 0x%8.8" PRIx32 "", - current_opcode); - } - - LOG_DEBUG("enable single-step"); - xscale_enable_single_step(target, next_pc); - - /* restore banked registers */ - retval = xscale_restore_banked(target); - if (retval != ERROR_OK) - return retval; - - /* send resume request */ - xscale_send_u32(target, 0x30); - - /* send CPSR */ - xscale_send_u32(target, - buf_get_u32(arm->cpsr->value, 0, 32)); - LOG_DEBUG("writing cpsr with value 0x%8.8" PRIx32, - buf_get_u32(arm->cpsr->value, 0, 32)); - - for (i = 7; i >= 0; i--) { - /* send register */ - xscale_send_u32(target, - buf_get_u32(arm->core_cache->reg_list[i].value, 0, 32)); - LOG_DEBUG("writing r%i with value 0x%8.8" PRIx32 "", - i, buf_get_u32(arm->core_cache->reg_list[i].value, 0, 32)); - } - - /* send PC */ - xscale_send_u32(target, - buf_get_u32(arm->pc->value, 0, 32)); - LOG_DEBUG("writing PC with value 0x%8.8" PRIx32, - buf_get_u32(arm->pc->value, 0, 32)); - - /* disable trace data collection in xscale_debug_entry() */ - saved_trace_mode = xscale->trace.mode; - xscale->trace.mode = XSCALE_TRACE_DISABLED; - - /* wait for and process debug entry */ - xscale_debug_entry(target); - - /* re-enable trace buffer, if enabled previously */ - xscale->trace.mode = saved_trace_mode; - - LOG_DEBUG("disable single-step"); - xscale_disable_single_step(target); - - LOG_DEBUG("set breakpoint at 0x%8.8" PRIx32 "", breakpoint->address); - xscale_set_breakpoint(target, breakpoint); - } - } - - /* enable any pending breakpoints and watchpoints */ - xscale_enable_breakpoints(target); - xscale_enable_watchpoints(target); - - /* restore banked registers */ - retval = xscale_restore_banked(target); - if (retval != ERROR_OK) - return retval; - - /* send resume request (command 0x30 or 0x31) - * clean the trace buffer if it is to be enabled (0x62) */ - if (xscale->trace.mode != XSCALE_TRACE_DISABLED) { - if (xscale->trace.mode == XSCALE_TRACE_FILL) { - /* If trace enabled in fill mode and starting collection of new set - * of buffers, initialize buffer counter and free previous buffers */ - if (xscale->trace.fill_counter == 0) { - xscale->trace.fill_counter = xscale->trace.buffer_fill; - xscale_free_trace_data(xscale); - } - } else /* wrap mode; free previous buffer */ - xscale_free_trace_data(xscale); - - xscale_send_u32(target, 0x62); - xscale_send_u32(target, 0x31); - } else - xscale_send_u32(target, 0x30); - - /* send CPSR */ - xscale_send_u32(target, buf_get_u32(arm->cpsr->value, 0, 32)); - LOG_DEBUG("writing cpsr with value 0x%8.8" PRIx32, - buf_get_u32(arm->cpsr->value, 0, 32)); - - for (i = 7; i >= 0; i--) { - /* send register */ - xscale_send_u32(target, buf_get_u32(arm->core_cache->reg_list[i].value, 0, 32)); - LOG_DEBUG("writing r%i with value 0x%8.8" PRIx32 "", - i, buf_get_u32(arm->core_cache->reg_list[i].value, 0, 32)); - } - - /* send PC */ - xscale_send_u32(target, buf_get_u32(arm->pc->value, 0, 32)); - LOG_DEBUG("wrote PC with value 0x%8.8" PRIx32, - buf_get_u32(arm->pc->value, 0, 32)); - - target->debug_reason = DBG_REASON_NOTHALTED; - - if (!debug_execution) { - /* registers are now invalid */ - register_cache_invalidate(arm->core_cache); - target->state = TARGET_RUNNING; - target_call_event_callbacks(target, TARGET_EVENT_RESUMED); - } else { - target->state = TARGET_DEBUG_RUNNING; - target_call_event_callbacks(target, TARGET_EVENT_DEBUG_RESUMED); - } - - LOG_DEBUG("target resumed"); - - return ERROR_OK; -} - -static int xscale_step_inner(struct target *target, int current, - uint32_t address, int handle_breakpoints) -{ - struct xscale_common *xscale = target_to_xscale(target); - struct arm *arm = &xscale->arm; - uint32_t next_pc; - int retval; - int i; - - target->debug_reason = DBG_REASON_SINGLESTEP; - - /* calculate PC of next instruction */ - retval = arm_simulate_step(target, &next_pc); - if (retval != ERROR_OK) { - uint32_t current_opcode, current_pc; - current_pc = buf_get_u32(arm->pc->value, 0, 32); - - target_read_u32(target, current_pc, ¤t_opcode); - LOG_ERROR( - "BUG: couldn't calculate PC of next instruction, current opcode was 0x%8.8" PRIx32 "", - current_opcode); - return retval; - } - - LOG_DEBUG("enable single-step"); - retval = xscale_enable_single_step(target, next_pc); - if (retval != ERROR_OK) - return retval; - - /* restore banked registers */ - retval = xscale_restore_banked(target); - if (retval != ERROR_OK) - return retval; - - /* send resume request (command 0x30 or 0x31) - * clean the trace buffer if it is to be enabled (0x62) */ - if (xscale->trace.mode != XSCALE_TRACE_DISABLED) { - retval = xscale_send_u32(target, 0x62); - if (retval != ERROR_OK) - return retval; - retval = xscale_send_u32(target, 0x31); - if (retval != ERROR_OK) - return retval; - } else { - retval = xscale_send_u32(target, 0x30); - if (retval != ERROR_OK) - return retval; - } - - /* send CPSR */ - retval = xscale_send_u32(target, - buf_get_u32(arm->cpsr->value, 0, 32)); - if (retval != ERROR_OK) - return retval; - LOG_DEBUG("writing cpsr with value 0x%8.8" PRIx32, - buf_get_u32(arm->cpsr->value, 0, 32)); - - for (i = 7; i >= 0; i--) { - /* send register */ - retval = xscale_send_u32(target, - buf_get_u32(arm->core_cache->reg_list[i].value, 0, 32)); - if (retval != ERROR_OK) - return retval; - LOG_DEBUG("writing r%i with value 0x%8.8" PRIx32 "", i, - buf_get_u32(arm->core_cache->reg_list[i].value, 0, 32)); - } - - /* send PC */ - retval = xscale_send_u32(target, - buf_get_u32(arm->pc->value, 0, 32)); - if (retval != ERROR_OK) - return retval; - LOG_DEBUG("wrote PC with value 0x%8.8" PRIx32, - buf_get_u32(arm->pc->value, 0, 32)); - - target_call_event_callbacks(target, TARGET_EVENT_RESUMED); - - /* registers are now invalid */ - register_cache_invalidate(arm->core_cache); - - /* wait for and process debug entry */ - retval = xscale_debug_entry(target); - if (retval != ERROR_OK) - return retval; - - LOG_DEBUG("disable single-step"); - retval = xscale_disable_single_step(target); - if (retval != ERROR_OK) - return retval; - - target_call_event_callbacks(target, TARGET_EVENT_HALTED); - - return ERROR_OK; -} - -static int xscale_step(struct target *target, int current, - uint32_t address, int handle_breakpoints) -{ - struct arm *arm = target_to_arm(target); - struct breakpoint *breakpoint = NULL; - - uint32_t current_pc; - int retval; - - if (target->state != TARGET_HALTED) { - LOG_WARNING("target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - /* current = 1: continue on current pc, otherwise continue at
*/ - if (!current) - buf_set_u32(arm->pc->value, 0, 32, address); - - current_pc = buf_get_u32(arm->pc->value, 0, 32); - - /* if we're at the reset vector, we have to simulate the step */ - if (current_pc == 0x0) { - retval = arm_simulate_step(target, NULL); - if (retval != ERROR_OK) - return retval; - current_pc = buf_get_u32(arm->pc->value, 0, 32); - LOG_DEBUG("current pc %" PRIx32, current_pc); - - target->debug_reason = DBG_REASON_SINGLESTEP; - target_call_event_callbacks(target, TARGET_EVENT_HALTED); - - return ERROR_OK; - } - - /* the front-end may request us not to handle breakpoints */ - if (handle_breakpoints) - breakpoint = breakpoint_find(target, - buf_get_u32(arm->pc->value, 0, 32)); - if (breakpoint != NULL) { - retval = xscale_unset_breakpoint(target, breakpoint); - if (retval != ERROR_OK) - return retval; - } - - retval = xscale_step_inner(target, current, address, handle_breakpoints); - if (retval != ERROR_OK) - return retval; - - if (breakpoint) - xscale_set_breakpoint(target, breakpoint); - - LOG_DEBUG("target stepped"); - - return ERROR_OK; - -} - -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)); - - /* assert reset */ - jtag_add_reset(0, 1); - - /* sleep 1ms, to be sure we fulfill any requirements */ - jtag_add_sleep(1000); - jtag_execute_queue(); - - /* select DCSR instruction (set endstate to R-T-I to ensure we don't - * end up in T-L-R, which would reset JTAG - */ - xscale_jtag_set_instr(target->tap, - XSCALE_SELDCSR << xscale->xscale_variant, - TAP_IDLE); - - /* set Hold reset, Halt mode and Trap Reset */ - buf_set_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 30, 1, 0x1); - buf_set_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 16, 1, 0x1); - xscale_write_dcsr(target, 1, 0); - - /* select BYPASS, because having DCSR selected caused problems on the PXA27x */ - xscale_jtag_set_instr(target->tap, ~0, TAP_IDLE); - jtag_execute_queue(); - - target->state = TARGET_RESET; - - if (target->reset_halt) { - int retval = target_halt(target); - if (retval != ERROR_OK) - return retval; - } - - return ERROR_OK; -} - -static int xscale_deassert_reset(struct target *target) -{ - struct xscale_common *xscale = target_to_xscale(target); - struct breakpoint *breakpoint = target->breakpoints; - - LOG_DEBUG("-"); - - xscale->ibcr_available = 2; - xscale->ibcr0_used = 0; - xscale->ibcr1_used = 0; - - xscale->dbr_available = 2; - xscale->dbr0_used = 0; - xscale->dbr1_used = 0; - - /* mark all hardware breakpoints as unset */ - while (breakpoint) { - if (breakpoint->type == BKPT_HARD) - breakpoint->set = 0; - breakpoint = breakpoint->next; - } - - xscale->trace.mode = XSCALE_TRACE_DISABLED; - xscale_free_trace_data(xscale); - - register_cache_invalidate(xscale->arm.core_cache); - - /* FIXME mark hardware watchpoints got unset too. Also, - * at least some of the XScale registers are invalid... - */ - - /* - * REVISIT: *assumes* we had a SRST+TRST reset so the mini-icache - * contents got invalidated. Safer to force that, so writing new - * contents can't ever fail.. - */ - { - uint32_t address; - unsigned buf_cnt; - const uint8_t *buffer = xscale_debug_handler; - int retval; - - /* release SRST */ - jtag_add_reset(0, 0); - - /* wait 300ms; 150 and 100ms were not enough */ - jtag_add_sleep(300*1000); - - jtag_add_runtest(2030, TAP_IDLE); - jtag_execute_queue(); - - /* set Hold reset, Halt mode and Trap Reset */ - buf_set_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 30, 1, 0x1); - buf_set_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 16, 1, 0x1); - xscale_write_dcsr(target, 1, 0); - - /* Load the debug handler into the mini-icache. Since - * it's using halt mode (not monitor mode), it runs in - * "Special Debug State" for access to registers, memory, - * coprocessors, trace data, etc. - */ - address = xscale->handler_address; - for (unsigned binary_size = sizeof xscale_debug_handler; - binary_size > 0; - binary_size -= buf_cnt, buffer += buf_cnt) { - uint32_t cache_line[8]; - unsigned i; - - buf_cnt = binary_size; - if (buf_cnt > 32) - buf_cnt = 32; - - for (i = 0; i < buf_cnt; i += 4) { - /* convert LE buffer to host-endian uint32_t */ - cache_line[i / 4] = le_to_h_u32(&buffer[i]); - } - - for (; i < 32; i += 4) - cache_line[i / 4] = 0xe1a08008; - - /* only load addresses other than the reset vectors */ - if ((address % 0x400) != 0x0) { - retval = xscale_load_ic(target, address, - cache_line); - if (retval != ERROR_OK) - return retval; - } - - address += buf_cnt; - } - - retval = xscale_load_ic(target, 0x0, - xscale->low_vectors); - if (retval != ERROR_OK) - return retval; - retval = xscale_load_ic(target, 0xffff0000, - xscale->high_vectors); - if (retval != ERROR_OK) - return retval; - - jtag_add_runtest(30, TAP_IDLE); - - jtag_add_sleep(100000); - - /* set Hold reset, Halt mode and Trap Reset */ - buf_set_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 30, 1, 0x1); - buf_set_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 16, 1, 0x1); - xscale_write_dcsr(target, 1, 0); - - /* clear Hold reset to let the target run (should enter debug handler) */ - xscale_write_dcsr(target, 0, 1); - target->state = TARGET_RUNNING; - - if (!target->reset_halt) { - jtag_add_sleep(10000); - - /* we should have entered debug now */ - xscale_debug_entry(target); - target->state = TARGET_HALTED; - - /* resume the target */ - xscale_resume(target, 1, 0x0, 1, 0); - } - } - - return ERROR_OK; -} - -static int xscale_read_core_reg(struct target *target, struct reg *r, - int num, enum arm_mode mode) -{ - /** \todo add debug handler support for core register reads */ - LOG_ERROR("not implemented"); - return ERROR_OK; -} - -static int xscale_write_core_reg(struct target *target, struct reg *r, - int num, enum arm_mode mode, uint8_t *value) -{ - /** \todo add debug handler support for core register writes */ - LOG_ERROR("not implemented"); - return ERROR_OK; -} - -static int xscale_full_context(struct target *target) -{ - struct arm *arm = target_to_arm(target); - - uint32_t *buffer; - - int i, j; - - LOG_DEBUG("-"); - - if (target->state != TARGET_HALTED) { - LOG_WARNING("target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - buffer = malloc(4 * 8); - - /* iterate through processor modes (FIQ, IRQ, SVC, ABT, UND and SYS) - * we can't enter User mode on an XScale (unpredictable), - * but User shares registers with SYS - */ - for (i = 1; i < 7; i++) { - enum arm_mode mode = armv4_5_number_to_mode(i); - bool valid = true; - struct reg *r; - - if (mode == ARM_MODE_USR) - continue; - - /* check if there are invalid registers in the current mode - */ - for (j = 0; valid && j <= 16; j++) { - if (!ARMV4_5_CORE_REG_MODE(arm->core_cache, - mode, j).valid) - valid = false; - } - if (valid) - continue; - - /* request banked registers */ - xscale_send_u32(target, 0x0); - - /* send CPSR for desired bank mode */ - xscale_send_u32(target, mode | 0xc0 /* I/F bits */); - - /* get banked registers: r8 to r14; and SPSR - * except in USR/SYS mode - */ - if (mode != ARM_MODE_SYS) { - /* SPSR */ - r = &ARMV4_5_CORE_REG_MODE(arm->core_cache, - mode, 16); - - xscale_receive(target, buffer, 8); - - buf_set_u32(r->value, 0, 32, buffer[7]); - r->dirty = false; - r->valid = true; - } else - xscale_receive(target, buffer, 7); - - /* move data from buffer to register cache */ - for (j = 8; j <= 14; j++) { - r = &ARMV4_5_CORE_REG_MODE(arm->core_cache, - mode, j); - - buf_set_u32(r->value, 0, 32, buffer[j - 8]); - r->dirty = false; - r->valid = true; - } - } - - free(buffer); - - return ERROR_OK; -} - -static int xscale_restore_banked(struct target *target) -{ - struct arm *arm = target_to_arm(target); - - int i, j; - - if (target->state != TARGET_HALTED) { - LOG_WARNING("target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - /* iterate through processor modes (FIQ, IRQ, SVC, ABT, UND and SYS) - * and check if any banked registers need to be written. Ignore - * USR mode (number 0) in favor of SYS; we can't enter User mode on - * an XScale (unpredictable), but they share all registers. - */ - for (i = 1; i < 7; i++) { - enum arm_mode mode = armv4_5_number_to_mode(i); - struct reg *r; - - if (mode == ARM_MODE_USR) - continue; - - /* check if there are dirty registers in this mode */ - for (j = 8; j <= 14; j++) { - if (ARMV4_5_CORE_REG_MODE(arm->core_cache, - mode, j).dirty) - goto dirty; - } - - /* if not USR/SYS, check if the SPSR needs to be written */ - if (mode != ARM_MODE_SYS) { - if (ARMV4_5_CORE_REG_MODE(arm->core_cache, - mode, 16).dirty) - goto dirty; - } - - /* there's nothing to flush for this mode */ - continue; - -dirty: - /* command 0x1: "send banked registers" */ - xscale_send_u32(target, 0x1); - - /* send CPSR for desired mode */ - xscale_send_u32(target, mode | 0xc0 /* I/F bits */); - - /* send r8 to r14/lr ... only FIQ needs more than r13..r14, - * but this protocol doesn't understand that nuance. - */ - for (j = 8; j <= 14; j++) { - r = &ARMV4_5_CORE_REG_MODE(arm->core_cache, - mode, j); - xscale_send_u32(target, buf_get_u32(r->value, 0, 32)); - r->dirty = false; - } - - /* send spsr if not in USR/SYS mode */ - if (mode != ARM_MODE_SYS) { - r = &ARMV4_5_CORE_REG_MODE(arm->core_cache, - mode, 16); - xscale_send_u32(target, buf_get_u32(r->value, 0, 32)); - r->dirty = false; - } - } - - return ERROR_OK; -} - -static int xscale_read_memory(struct target *target, uint32_t address, - uint32_t size, uint32_t count, uint8_t *buffer) -{ - struct xscale_common *xscale = target_to_xscale(target); - uint32_t *buf32; - uint32_t i; - int retval; - - LOG_DEBUG("address: 0x%8.8" PRIx32 ", size: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32, - address, - size, - count); - - if (target->state != TARGET_HALTED) { - LOG_WARNING("target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - /* sanitize arguments */ - if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer)) - return ERROR_COMMAND_SYNTAX_ERROR; - - if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u))) - return ERROR_TARGET_UNALIGNED_ACCESS; - - /* send memory read request (command 0x1n, n: access size) */ - retval = xscale_send_u32(target, 0x10 | size); - if (retval != ERROR_OK) - return retval; - - /* send base address for read request */ - retval = xscale_send_u32(target, address); - if (retval != ERROR_OK) - return retval; - - /* send number of requested data words */ - retval = xscale_send_u32(target, count); - if (retval != ERROR_OK) - return retval; - - /* receive data from target (count times 32-bit words in host endianness) */ - buf32 = malloc(4 * count); - retval = xscale_receive(target, buf32, count); - if (retval != ERROR_OK) { - free(buf32); - return retval; - } - - /* extract data from host-endian buffer into byte stream */ - for (i = 0; i < count; i++) { - switch (size) { - case 4: - target_buffer_set_u32(target, buffer, buf32[i]); - buffer += 4; - break; - case 2: - target_buffer_set_u16(target, buffer, buf32[i] & 0xffff); - buffer += 2; - break; - case 1: - *buffer++ = buf32[i] & 0xff; - break; - default: - LOG_ERROR("invalid read size"); - return ERROR_COMMAND_SYNTAX_ERROR; - } - } - - free(buf32); - - /* examine DCSR, to see if Sticky Abort (SA) got set */ - retval = xscale_read_dcsr(target); - if (retval != ERROR_OK) - return retval; - if (buf_get_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 5, 1) == 1) { - /* clear SA bit */ - retval = xscale_send_u32(target, 0x60); - if (retval != ERROR_OK) - return retval; - - return ERROR_TARGET_DATA_ABORT; - } - - return ERROR_OK; -} - -static int xscale_read_phys_memory(struct target *target, uint32_t address, - uint32_t size, uint32_t count, uint8_t *buffer) -{ - struct xscale_common *xscale = target_to_xscale(target); - - /* with MMU inactive, there are only physical addresses */ - if (!xscale->armv4_5_mmu.mmu_enabled) - return xscale_read_memory(target, address, size, count, buffer); - - /** \todo: provide a non-stub implementation of this routine. */ - LOG_ERROR("%s: %s is not implemented. Disable MMU?", - target_name(target), __func__); - return ERROR_FAIL; -} - -static int xscale_write_memory(struct target *target, uint32_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, - address, - size, - count); - - if (target->state != TARGET_HALTED) { - LOG_WARNING("target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - /* sanitize arguments */ - if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer)) - return ERROR_COMMAND_SYNTAX_ERROR; - - if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u))) - return ERROR_TARGET_UNALIGNED_ACCESS; - - /* send memory write request (command 0x2n, n: access size) */ - retval = xscale_send_u32(target, 0x20 | size); - if (retval != ERROR_OK) - return retval; - - /* send base address for read request */ - retval = xscale_send_u32(target, address); - if (retval != ERROR_OK) - return retval; - - /* send number of requested data words to be written*/ - retval = xscale_send_u32(target, count); - if (retval != ERROR_OK) - return retval; - - /* extract data from host-endian buffer into byte stream */ -#if 0 - for (i = 0; i < count; i++) { - switch (size) { - case 4: - value = target_buffer_get_u32(target, buffer); - xscale_send_u32(target, value); - buffer += 4; - break; - case 2: - value = target_buffer_get_u16(target, buffer); - xscale_send_u32(target, value); - buffer += 2; - break; - case 1: - value = *buffer; - xscale_send_u32(target, value); - buffer += 1; - break; - default: - LOG_ERROR("should never get here"); - exit(-1); - } - } -#endif - retval = xscale_send(target, buffer, count, size); - if (retval != ERROR_OK) - return retval; - - /* examine DCSR, to see if Sticky Abort (SA) got set */ - retval = xscale_read_dcsr(target); - if (retval != ERROR_OK) - return retval; - if (buf_get_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 5, 1) == 1) { - /* clear SA bit */ - retval = xscale_send_u32(target, 0x60); - if (retval != ERROR_OK) - return retval; - - LOG_ERROR("data abort writing memory"); - return ERROR_TARGET_DATA_ABORT; - } - - return ERROR_OK; -} - -static int xscale_write_phys_memory(struct target *target, uint32_t address, - uint32_t size, uint32_t count, const uint8_t *buffer) -{ - struct xscale_common *xscale = target_to_xscale(target); - - /* with MMU inactive, there are only physical addresses */ - if (!xscale->armv4_5_mmu.mmu_enabled) - return xscale_write_memory(target, address, size, count, buffer); - - /** \todo: provide a non-stub implementation of this routine. */ - LOG_ERROR("%s: %s is not implemented. Disable MMU?", - target_name(target), __func__); - return ERROR_FAIL; -} - -static int xscale_get_ttb(struct target *target, uint32_t *result) -{ - struct xscale_common *xscale = target_to_xscale(target); - uint32_t ttb; - int retval; - - retval = xscale_get_reg(&xscale->reg_cache->reg_list[XSCALE_TTB]); - if (retval != ERROR_OK) - return retval; - ttb = buf_get_u32(xscale->reg_cache->reg_list[XSCALE_TTB].value, 0, 32); - - *result = ttb; - - return ERROR_OK; -} - -static int xscale_disable_mmu_caches(struct target *target, int mmu, - int d_u_cache, int i_cache) -{ - struct xscale_common *xscale = target_to_xscale(target); - uint32_t cp15_control; - int retval; - - /* read cp15 control register */ - retval = xscale_get_reg(&xscale->reg_cache->reg_list[XSCALE_CTRL]); - if (retval != ERROR_OK) - return retval; - cp15_control = buf_get_u32(xscale->reg_cache->reg_list[XSCALE_CTRL].value, 0, 32); - - if (mmu) - cp15_control &= ~0x1U; - - if (d_u_cache) { - /* clean DCache */ - retval = xscale_send_u32(target, 0x50); - if (retval != ERROR_OK) - return retval; - retval = xscale_send_u32(target, xscale->cache_clean_address); - if (retval != ERROR_OK) - return retval; - - /* invalidate DCache */ - retval = xscale_send_u32(target, 0x51); - if (retval != ERROR_OK) - return retval; - - cp15_control &= ~0x4U; - } - - if (i_cache) { - /* invalidate ICache */ - retval = xscale_send_u32(target, 0x52); - if (retval != ERROR_OK) - return retval; - cp15_control &= ~0x1000U; - } - - /* write new cp15 control register */ - retval = xscale_set_reg_u32(&xscale->reg_cache->reg_list[XSCALE_CTRL], cp15_control); - if (retval != ERROR_OK) - return retval; - - /* execute cpwait to ensure outstanding operations complete */ - retval = xscale_send_u32(target, 0x53); - return retval; -} - -static int xscale_enable_mmu_caches(struct target *target, int mmu, - int d_u_cache, int i_cache) -{ - struct xscale_common *xscale = target_to_xscale(target); - uint32_t cp15_control; - int retval; - - /* read cp15 control register */ - retval = xscale_get_reg(&xscale->reg_cache->reg_list[XSCALE_CTRL]); - if (retval != ERROR_OK) - return retval; - cp15_control = buf_get_u32(xscale->reg_cache->reg_list[XSCALE_CTRL].value, 0, 32); - - if (mmu) - cp15_control |= 0x1U; - - if (d_u_cache) - cp15_control |= 0x4U; - - if (i_cache) - cp15_control |= 0x1000U; - - /* write new cp15 control register */ - retval = xscale_set_reg_u32(&xscale->reg_cache->reg_list[XSCALE_CTRL], cp15_control); - if (retval != ERROR_OK) - return retval; - - /* execute cpwait to ensure outstanding operations complete */ - retval = xscale_send_u32(target, 0x53); - return retval; -} - -static int xscale_set_breakpoint(struct target *target, - struct breakpoint *breakpoint) -{ - int retval; - struct xscale_common *xscale = target_to_xscale(target); - - if (target->state != TARGET_HALTED) { - LOG_WARNING("target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - if (breakpoint->set) { - LOG_WARNING("breakpoint already set"); - return ERROR_OK; - } - - if (breakpoint->type == BKPT_HARD) { - uint32_t value = breakpoint->address | 1; - if (!xscale->ibcr0_used) { - xscale_set_reg_u32(&xscale->reg_cache->reg_list[XSCALE_IBCR0], value); - xscale->ibcr0_used = 1; - breakpoint->set = 1; /* breakpoint set on first breakpoint register */ - } else if (!xscale->ibcr1_used) { - xscale_set_reg_u32(&xscale->reg_cache->reg_list[XSCALE_IBCR1], value); - xscale->ibcr1_used = 1; - breakpoint->set = 2; /* breakpoint set on second breakpoint register */ - } else {/* bug: availability previously verified in xscale_add_breakpoint() */ - LOG_ERROR("BUG: no hardware comparator available"); - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - } - } else if (breakpoint->type == BKPT_SOFT) { - if (breakpoint->length == 4) { - /* keep the original instruction in target endianness */ - retval = target_read_memory(target, breakpoint->address, 4, 1, - breakpoint->orig_instr); - if (retval != ERROR_OK) - return retval; - /* write the bkpt instruction in target endianness - *(arm7_9->arm_bkpt is host endian) */ - retval = target_write_u32(target, breakpoint->address, - xscale->arm_bkpt); - if (retval != ERROR_OK) - return retval; - } else { - /* keep the original instruction in target endianness */ - retval = target_read_memory(target, breakpoint->address, 2, 1, - breakpoint->orig_instr); - if (retval != ERROR_OK) - return retval; - /* write the bkpt instruction in target endianness - *(arm7_9->arm_bkpt is host endian) */ - retval = target_write_u16(target, breakpoint->address, - xscale->thumb_bkpt); - if (retval != ERROR_OK) - return retval; - } - breakpoint->set = 1; - - xscale_send_u32(target, 0x50); /* clean dcache */ - xscale_send_u32(target, xscale->cache_clean_address); - xscale_send_u32(target, 0x51); /* invalidate dcache */ - xscale_send_u32(target, 0x52); /* invalidate icache and flush fetch buffers */ - } - - return ERROR_OK; -} - -static int xscale_add_breakpoint(struct target *target, - struct breakpoint *breakpoint) -{ - struct xscale_common *xscale = target_to_xscale(target); - - if ((breakpoint->type == BKPT_HARD) && (xscale->ibcr_available < 1)) { - LOG_ERROR("no breakpoint unit available for hardware breakpoint"); - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - } - - if ((breakpoint->length != 2) && (breakpoint->length != 4)) { - LOG_ERROR("only breakpoints of two (Thumb) or four (ARM) bytes length supported"); - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - } - - if (breakpoint->type == BKPT_HARD) - xscale->ibcr_available--; - - return xscale_set_breakpoint(target, breakpoint); -} - -static int xscale_unset_breakpoint(struct target *target, - struct breakpoint *breakpoint) -{ - int retval; - struct xscale_common *xscale = target_to_xscale(target); - - if (target->state != TARGET_HALTED) { - LOG_WARNING("target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - if (!breakpoint->set) { - LOG_WARNING("breakpoint not set"); - return ERROR_OK; - } - - if (breakpoint->type == BKPT_HARD) { - if (breakpoint->set == 1) { - xscale_set_reg_u32(&xscale->reg_cache->reg_list[XSCALE_IBCR0], 0x0); - xscale->ibcr0_used = 0; - } else if (breakpoint->set == 2) { - xscale_set_reg_u32(&xscale->reg_cache->reg_list[XSCALE_IBCR1], 0x0); - xscale->ibcr1_used = 0; - } - breakpoint->set = 0; - } else { - /* restore original instruction (kept in target endianness) */ - if (breakpoint->length == 4) { - retval = target_write_memory(target, breakpoint->address, 4, 1, - breakpoint->orig_instr); - if (retval != ERROR_OK) - return retval; - } else { - retval = target_write_memory(target, breakpoint->address, 2, 1, - breakpoint->orig_instr); - if (retval != ERROR_OK) - return retval; - } - breakpoint->set = 0; - - xscale_send_u32(target, 0x50); /* clean dcache */ - xscale_send_u32(target, xscale->cache_clean_address); - xscale_send_u32(target, 0x51); /* invalidate dcache */ - xscale_send_u32(target, 0x52); /* invalidate icache and flush fetch buffers */ - } - - return ERROR_OK; -} - -static int xscale_remove_breakpoint(struct target *target, struct breakpoint *breakpoint) -{ - struct xscale_common *xscale = target_to_xscale(target); - - if (target->state != TARGET_HALTED) { - LOG_ERROR("target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - if (breakpoint->set) - xscale_unset_breakpoint(target, breakpoint); - - if (breakpoint->type == BKPT_HARD) - xscale->ibcr_available++; - - return ERROR_OK; -} - -static int xscale_set_watchpoint(struct target *target, - struct watchpoint *watchpoint) -{ - struct xscale_common *xscale = target_to_xscale(target); - uint32_t enable = 0; - struct reg *dbcon = &xscale->reg_cache->reg_list[XSCALE_DBCON]; - uint32_t dbcon_value = buf_get_u32(dbcon->value, 0, 32); - - if (target->state != TARGET_HALTED) { - LOG_ERROR("target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - switch (watchpoint->rw) { - case WPT_READ: - enable = 0x3; - break; - case WPT_ACCESS: - enable = 0x2; - break; - case WPT_WRITE: - enable = 0x1; - break; - default: - LOG_ERROR("BUG: watchpoint->rw neither read, write nor access"); - } - - /* For watchpoint across more than one word, both DBR registers must - be enlisted, with the second used as a mask. */ - if (watchpoint->length > 4) { - if (xscale->dbr0_used || xscale->dbr1_used) { - LOG_ERROR("BUG: sufficient hardware comparators unavailable"); - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - } - - /* Write mask value to DBR1, based on the length argument. - * Address bits ignored by the comparator are those set in mask. */ - xscale_set_reg_u32(&xscale->reg_cache->reg_list[XSCALE_DBR1], - watchpoint->length - 1); - xscale->dbr1_used = 1; - enable |= 0x100; /* DBCON[M] */ - } - - if (!xscale->dbr0_used) { - xscale_set_reg_u32(&xscale->reg_cache->reg_list[XSCALE_DBR0], watchpoint->address); - dbcon_value |= enable; - xscale_set_reg_u32(dbcon, dbcon_value); - watchpoint->set = 1; - xscale->dbr0_used = 1; - } else if (!xscale->dbr1_used) { - xscale_set_reg_u32(&xscale->reg_cache->reg_list[XSCALE_DBR1], watchpoint->address); - dbcon_value |= enable << 2; - xscale_set_reg_u32(dbcon, dbcon_value); - watchpoint->set = 2; - xscale->dbr1_used = 1; - } else { - LOG_ERROR("BUG: no hardware comparator available"); - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - } - - return ERROR_OK; -} - -static int xscale_add_watchpoint(struct target *target, - struct watchpoint *watchpoint) -{ - struct xscale_common *xscale = target_to_xscale(target); - - if (xscale->dbr_available < 1) { - LOG_ERROR("no more watchpoint registers available"); - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - } - - if (watchpoint->value) - LOG_WARNING("xscale does not support value, mask arguments; ignoring"); - - /* check that length is a power of two */ - for (uint32_t len = watchpoint->length; len != 1; len /= 2) { - if (len % 2) { - LOG_ERROR("xscale requires that watchpoint length is a power of two"); - return ERROR_COMMAND_ARGUMENT_INVALID; - } - } - - if (watchpoint->length == 4) { /* single word watchpoint */ - xscale->dbr_available--;/* one DBR reg used */ - return ERROR_OK; - } - - /* watchpoints across multiple words require both DBR registers */ - if (xscale->dbr_available < 2) { - LOG_ERROR("insufficient watchpoint registers available"); - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - } - - if (watchpoint->length > watchpoint->address) { - LOG_ERROR("xscale does not support watchpoints with length " - "greater than address"); - return ERROR_COMMAND_ARGUMENT_INVALID; - } - - xscale->dbr_available = 0; - return ERROR_OK; -} - -static int xscale_unset_watchpoint(struct target *target, - struct watchpoint *watchpoint) -{ - struct xscale_common *xscale = target_to_xscale(target); - struct reg *dbcon = &xscale->reg_cache->reg_list[XSCALE_DBCON]; - uint32_t dbcon_value = buf_get_u32(dbcon->value, 0, 32); - - if (target->state != TARGET_HALTED) { - LOG_WARNING("target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - if (!watchpoint->set) { - LOG_WARNING("breakpoint not set"); - return ERROR_OK; - } - - if (watchpoint->set == 1) { - if (watchpoint->length > 4) { - dbcon_value &= ~0x103; /* clear DBCON[M] as well */ - xscale->dbr1_used = 0; /* DBR1 was used for mask */ - } else - dbcon_value &= ~0x3; - - xscale_set_reg_u32(dbcon, dbcon_value); - xscale->dbr0_used = 0; - } else if (watchpoint->set == 2) { - dbcon_value &= ~0xc; - xscale_set_reg_u32(dbcon, dbcon_value); - xscale->dbr1_used = 0; - } - watchpoint->set = 0; - - return ERROR_OK; -} - -static int xscale_remove_watchpoint(struct target *target, struct watchpoint *watchpoint) -{ - struct xscale_common *xscale = target_to_xscale(target); - - if (target->state != TARGET_HALTED) { - LOG_ERROR("target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - if (watchpoint->set) - xscale_unset_watchpoint(target, watchpoint); - - if (watchpoint->length > 4) - xscale->dbr_available++;/* both DBR regs now available */ - - xscale->dbr_available++; - - return ERROR_OK; -} - -static int xscale_get_reg(struct reg *reg) -{ - struct xscale_reg *arch_info = reg->arch_info; - struct target *target = arch_info->target; - struct xscale_common *xscale = target_to_xscale(target); - - /* DCSR, TX and RX are accessible via JTAG */ - if (strcmp(reg->name, "XSCALE_DCSR") == 0) - return xscale_read_dcsr(arch_info->target); - else if (strcmp(reg->name, "XSCALE_TX") == 0) { - /* 1 = consume register content */ - return xscale_read_tx(arch_info->target, 1); - } else if (strcmp(reg->name, "XSCALE_RX") == 0) { - /* can't read from RX register (host -> debug handler) */ - return ERROR_OK; - } else if (strcmp(reg->name, "XSCALE_TXRXCTRL") == 0) { - /* can't (explicitly) read from TXRXCTRL register */ - return ERROR_OK; - } else {/* Other DBG registers have to be transfered by the debug handler - * send CP read request (command 0x40) */ - xscale_send_u32(target, 0x40); - - /* send CP register number */ - xscale_send_u32(target, arch_info->dbg_handler_number); - - /* read register value */ - xscale_read_tx(target, 1); - buf_cpy(xscale->reg_cache->reg_list[XSCALE_TX].value, reg->value, 32); - - reg->dirty = 0; - reg->valid = 1; - } - - return ERROR_OK; -} - -static int xscale_set_reg(struct reg *reg, uint8_t *buf) -{ - struct xscale_reg *arch_info = reg->arch_info; - struct target *target = arch_info->target; - struct xscale_common *xscale = target_to_xscale(target); - uint32_t value = buf_get_u32(buf, 0, 32); - - /* DCSR, TX and RX are accessible via JTAG */ - if (strcmp(reg->name, "XSCALE_DCSR") == 0) { - buf_set_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 0, 32, value); - return xscale_write_dcsr(arch_info->target, -1, -1); - } else if (strcmp(reg->name, "XSCALE_RX") == 0) { - buf_set_u32(xscale->reg_cache->reg_list[XSCALE_RX].value, 0, 32, value); - return xscale_write_rx(arch_info->target); - } else if (strcmp(reg->name, "XSCALE_TX") == 0) { - /* can't write to TX register (debug-handler -> host) */ - return ERROR_OK; - } else if (strcmp(reg->name, "XSCALE_TXRXCTRL") == 0) { - /* can't (explicitly) write to TXRXCTRL register */ - return ERROR_OK; - } else {/* Other DBG registers have to be transfered by the debug handler - * send CP write request (command 0x41) */ - xscale_send_u32(target, 0x41); - - /* send CP register number */ - xscale_send_u32(target, arch_info->dbg_handler_number); - - /* send CP register value */ - xscale_send_u32(target, value); - buf_set_u32(reg->value, 0, 32, value); - } - - return ERROR_OK; -} - -static int xscale_write_dcsr_sw(struct target *target, uint32_t value) -{ - struct xscale_common *xscale = target_to_xscale(target); - struct reg *dcsr = &xscale->reg_cache->reg_list[XSCALE_DCSR]; - struct xscale_reg *dcsr_arch_info = dcsr->arch_info; - - /* send CP write request (command 0x41) */ - xscale_send_u32(target, 0x41); - - /* send CP register number */ - xscale_send_u32(target, dcsr_arch_info->dbg_handler_number); - - /* send CP register value */ - xscale_send_u32(target, value); - buf_set_u32(dcsr->value, 0, 32, value); - - return ERROR_OK; -} - -static int xscale_read_trace(struct target *target) -{ - struct xscale_common *xscale = target_to_xscale(target); - struct arm *arm = &xscale->arm; - struct xscale_trace_data **trace_data_p; - - /* 258 words from debug handler - * 256 trace buffer entries - * 2 checkpoint addresses - */ - uint32_t trace_buffer[258]; - int is_address[256]; - int i, j; - unsigned int num_checkpoints = 0; - - if (target->state != TARGET_HALTED) { - LOG_WARNING("target must be stopped to read trace data"); - return ERROR_TARGET_NOT_HALTED; - } - - /* send read trace buffer command (command 0x61) */ - xscale_send_u32(target, 0x61); - - /* receive trace buffer content */ - xscale_receive(target, trace_buffer, 258); - - /* parse buffer backwards to identify address entries */ - for (i = 255; i >= 0; i--) { - /* also count number of checkpointed entries */ - if ((trace_buffer[i] & 0xe0) == 0xc0) - num_checkpoints++; - - is_address[i] = 0; - if (((trace_buffer[i] & 0xf0) == 0x90) || - ((trace_buffer[i] & 0xf0) == 0xd0)) { - if (i > 0) - is_address[--i] = 1; - if (i > 0) - is_address[--i] = 1; - if (i > 0) - is_address[--i] = 1; - if (i > 0) - is_address[--i] = 1; - } - } - - - /* search first non-zero entry that is not part of an address */ - for (j = 0; (j < 256) && (trace_buffer[j] == 0) && (!is_address[j]); j++) - ; - - if (j == 256) { - LOG_DEBUG("no trace data collected"); - return ERROR_XSCALE_NO_TRACE_DATA; - } - - /* account for possible partial address at buffer start (wrap mode only) */ - if (is_address[0]) { /* first entry is address; complete set of 4? */ - i = 1; - while (i < 4) - if (!is_address[i++]) - break; - if (i < 4) - j += i; /* partial address; can't use it */ - } - - /* if first valid entry is indirect branch, can't use that either (no address) */ - if (((trace_buffer[j] & 0xf0) == 0x90) || ((trace_buffer[j] & 0xf0) == 0xd0)) - j++; - - /* walk linked list to terminating entry */ - for (trace_data_p = &xscale->trace.data; *trace_data_p; - trace_data_p = &(*trace_data_p)->next) - ; - - *trace_data_p = malloc(sizeof(struct xscale_trace_data)); - (*trace_data_p)->next = NULL; - (*trace_data_p)->chkpt0 = trace_buffer[256]; - (*trace_data_p)->chkpt1 = trace_buffer[257]; - (*trace_data_p)->last_instruction = buf_get_u32(arm->pc->value, 0, 32); - (*trace_data_p)->entries = malloc(sizeof(struct xscale_trace_entry) * (256 - j)); - (*trace_data_p)->depth = 256 - j; - (*trace_data_p)->num_checkpoints = num_checkpoints; - - for (i = j; i < 256; i++) { - (*trace_data_p)->entries[i - j].data = trace_buffer[i]; - if (is_address[i]) - (*trace_data_p)->entries[i - j].type = XSCALE_TRACE_ADDRESS; - else - (*trace_data_p)->entries[i - j].type = XSCALE_TRACE_MESSAGE; - } - - return ERROR_OK; -} - -static int xscale_read_instruction(struct target *target, uint32_t pc, - struct arm_instruction *instruction) -{ - struct xscale_common *const xscale = target_to_xscale(target); - int i; - int section = -1; - size_t size_read; - uint32_t opcode; - int retval; - - if (!xscale->trace.image) - return ERROR_TRACE_IMAGE_UNAVAILABLE; - - /* search for the section the current instruction belongs to */ - for (i = 0; i < xscale->trace.image->num_sections; i++) { - if ((xscale->trace.image->sections[i].base_address <= pc) && - (xscale->trace.image->sections[i].base_address + - xscale->trace.image->sections[i].size > pc)) { - section = i; - break; - } - } - - if (section == -1) { - /* current instruction couldn't be found in the image */ - return ERROR_TRACE_INSTRUCTION_UNAVAILABLE; - } - - if (xscale->trace.core_state == ARM_STATE_ARM) { - uint8_t buf[4]; - retval = image_read_section(xscale->trace.image, section, - pc - xscale->trace.image->sections[section].base_address, - 4, buf, &size_read); - if (retval != ERROR_OK) { - LOG_ERROR("error while reading instruction"); - return ERROR_TRACE_INSTRUCTION_UNAVAILABLE; - } - opcode = target_buffer_get_u32(target, buf); - arm_evaluate_opcode(opcode, pc, instruction); - } else if (xscale->trace.core_state == ARM_STATE_THUMB) { - uint8_t buf[2]; - retval = image_read_section(xscale->trace.image, section, - pc - xscale->trace.image->sections[section].base_address, - 2, buf, &size_read); - if (retval != ERROR_OK) { - LOG_ERROR("error while reading instruction"); - return ERROR_TRACE_INSTRUCTION_UNAVAILABLE; - } - opcode = target_buffer_get_u16(target, buf); - thumb_evaluate_opcode(opcode, pc, instruction); - } else { - LOG_ERROR("BUG: unknown core state encountered"); - exit(-1); - } - - return ERROR_OK; -} - -/* Extract address encoded into trace data. - * Write result to address referenced by argument 'target', or 0 if incomplete. */ -static inline void xscale_branch_address(struct xscale_trace_data *trace_data, - int i, uint32_t *target) -{ - /* if there are less than four entries prior to the indirect branch message - * we can't extract the address */ - if (i < 4) - *target = 0; - else { - *target = (trace_data->entries[i-1].data) | (trace_data->entries[i-2].data << 8) | - (trace_data->entries[i-3].data << 16) | (trace_data->entries[i-4].data << 24); - } -} - -static inline void xscale_display_instruction(struct target *target, uint32_t pc, - struct arm_instruction *instruction, - struct command_context *cmd_ctx) -{ - int retval = xscale_read_instruction(target, pc, instruction); - if (retval == ERROR_OK) - command_print(cmd_ctx, "%s", instruction->text); - else - command_print(cmd_ctx, "0x%8.8" PRIx32 "\t", pc); -} - -static int xscale_analyze_trace(struct target *target, struct command_context *cmd_ctx) -{ - struct xscale_common *xscale = target_to_xscale(target); - struct xscale_trace_data *trace_data = xscale->trace.data; - int i, retval; - uint32_t breakpoint_pc = 0; - struct arm_instruction instruction; - uint32_t current_pc = 0;/* initialized when address determined */ - - if (!xscale->trace.image) - LOG_WARNING("No trace image loaded; use 'xscale trace_image'"); - - /* loop for each trace buffer that was loaded from target */ - while (trace_data) { - int chkpt = 0; /* incremented as checkpointed entries found */ - int j; - - /* FIXME: set this to correct mode when trace buffer is first enabled */ - xscale->trace.core_state = ARM_STATE_ARM; - - /* loop for each entry in this trace buffer */ - for (i = 0; i < trace_data->depth; i++) { - int exception = 0; - uint32_t chkpt_reg = 0x0; - uint32_t branch_target = 0; - int count; - - /* trace entry type is upper nybble of 'message byte' */ - int trace_msg_type = (trace_data->entries[i].data & 0xf0) >> 4; - - /* Target addresses of indirect branches are written into buffer - * before the message byte representing the branch. Skip past it */ - if (trace_data->entries[i].type == XSCALE_TRACE_ADDRESS) - continue; - - switch (trace_msg_type) { - case 0: /* Exceptions */ - case 1: - case 2: - case 3: - case 4: - case 5: - case 6: - case 7: - exception = (trace_data->entries[i].data & 0x70) >> 4; - - /* FIXME: vector table may be at ffff0000 */ - branch_target = (trace_data->entries[i].data & 0xf0) >> 2; - break; - - case 8: /* Direct Branch */ - break; - - case 9: /* Indirect Branch */ - xscale_branch_address(trace_data, i, &branch_target); - break; - - case 13: /* Checkpointed Indirect Branch */ - xscale_branch_address(trace_data, i, &branch_target); - if ((trace_data->num_checkpoints == 2) && (chkpt == 0)) - chkpt_reg = trace_data->chkpt1; /* 2 chkpts, this is - *oldest */ - else - chkpt_reg = trace_data->chkpt0; /* 1 chkpt, or 2 and - *newest */ - - chkpt++; - break; - - case 12: /* Checkpointed Direct Branch */ - if ((trace_data->num_checkpoints == 2) && (chkpt == 0)) - chkpt_reg = trace_data->chkpt1; /* 2 chkpts, this is - *oldest */ - else - chkpt_reg = trace_data->chkpt0; /* 1 chkpt, or 2 and - *newest */ - - /* if no current_pc, checkpoint will be starting point */ - if (current_pc == 0) - branch_target = chkpt_reg; - - chkpt++; - break; - - case 15:/* Roll-over */ - break; - - default:/* Reserved */ - LOG_WARNING("trace is suspect: invalid trace message byte"); - continue; - - } - - /* If we don't have the current_pc yet, but we did get the branch target - * (either from the trace buffer on indirect branch, or from a checkpoint reg), - * then we can start displaying instructions at the next iteration, with - * branch_target as the starting point. - */ - if (current_pc == 0) { - current_pc = branch_target; /* remains 0 unless branch_target *obtained */ - continue; - } - - /* We have current_pc. Read and display the instructions from the image. - * First, display count instructions (lower nybble of message byte). */ - count = trace_data->entries[i].data & 0x0f; - for (j = 0; j < count; j++) { - xscale_display_instruction(target, current_pc, &instruction, - cmd_ctx); - current_pc += xscale->trace.core_state == ARM_STATE_ARM ? 4 : 2; - } - - /* An additional instruction is implicitly added to count for - * rollover and some exceptions: undef, swi, prefetch abort. */ - if ((trace_msg_type == 15) || (exception > 0 && exception < 4)) { - xscale_display_instruction(target, current_pc, &instruction, - cmd_ctx); - current_pc += xscale->trace.core_state == ARM_STATE_ARM ? 4 : 2; - } - - if (trace_msg_type == 15) /* rollover */ - continue; - - if (exception) { - command_print(cmd_ctx, "--- exception %i ---", exception); - continue; - } - - /* not exception or rollover; next instruction is a branch and is - * not included in the count */ - xscale_display_instruction(target, current_pc, &instruction, cmd_ctx); - - /* for direct branches, extract branch destination from instruction */ - if ((trace_msg_type == 8) || (trace_msg_type == 12)) { - retval = xscale_read_instruction(target, current_pc, &instruction); - if (retval == ERROR_OK) - current_pc = instruction.info.b_bl_bx_blx.target_address; - else - current_pc = 0; /* branch destination unknown */ - - /* direct branch w/ checkpoint; can also get from checkpoint reg */ - if (trace_msg_type == 12) { - if (current_pc == 0) - current_pc = chkpt_reg; - else if (current_pc != chkpt_reg) /* sanity check */ - LOG_WARNING("trace is suspect: checkpoint register " - "inconsistent with adddress from image"); - } - - if (current_pc == 0) - command_print(cmd_ctx, "address unknown"); - - continue; - } - - /* indirect branch; the branch destination was read from trace buffer */ - if ((trace_msg_type == 9) || (trace_msg_type == 13)) { - current_pc = branch_target; - - /* sanity check (checkpoint reg is redundant) */ - if ((trace_msg_type == 13) && (chkpt_reg != branch_target)) - LOG_WARNING("trace is suspect: checkpoint register " - "inconsistent with address from trace buffer"); - } - - } /* END: for (i = 0; i < trace_data->depth; i++) */ - - breakpoint_pc = trace_data->last_instruction; /* used below */ - trace_data = trace_data->next; - - } /* END: while (trace_data) */ - - /* Finally... display all instructions up to the value of the pc when the - * debug break occurred (saved when trace data was collected from target). - * This is necessary because the trace only records execution branches and 16 - * consecutive instructions (rollovers), so last few typically missed. - */ - if (current_pc == 0) - return ERROR_OK;/* current_pc was never found */ - - /* how many instructions remaining? */ - int gap_count = (breakpoint_pc - current_pc) / - (xscale->trace.core_state == ARM_STATE_ARM ? 4 : 2); - - /* should never be negative or over 16, but verify */ - if (gap_count < 0 || gap_count > 16) { - LOG_WARNING("trace is suspect: excessive gap at end of trace"); - return ERROR_OK;/* bail; large number or negative value no good */ - } - - /* display remaining instructions */ - for (i = 0; i < gap_count; i++) { - xscale_display_instruction(target, current_pc, &instruction, cmd_ctx); - current_pc += xscale->trace.core_state == ARM_STATE_ARM ? 4 : 2; - } - - return ERROR_OK; -} - -static const struct reg_arch_type xscale_reg_type = { - .get = xscale_get_reg, - .set = xscale_set_reg, -}; - -static void xscale_build_reg_cache(struct target *target) -{ - struct xscale_common *xscale = target_to_xscale(target); - struct arm *arm = &xscale->arm; - struct reg_cache **cache_p = register_get_last_cache_p(&target->reg_cache); - struct xscale_reg *arch_info = malloc(sizeof(xscale_reg_arch_info)); - int i; - int num_regs = ARRAY_SIZE(xscale_reg_arch_info); - - (*cache_p) = arm_build_reg_cache(target, arm); - - (*cache_p)->next = malloc(sizeof(struct reg_cache)); - cache_p = &(*cache_p)->next; - - /* fill in values for the xscale reg cache */ - (*cache_p)->name = "XScale registers"; - (*cache_p)->next = NULL; - (*cache_p)->reg_list = malloc(num_regs * sizeof(struct reg)); - (*cache_p)->num_regs = num_regs; - - for (i = 0; i < num_regs; i++) { - (*cache_p)->reg_list[i].name = xscale_reg_list[i]; - (*cache_p)->reg_list[i].value = calloc(4, 1); - (*cache_p)->reg_list[i].dirty = 0; - (*cache_p)->reg_list[i].valid = 0; - (*cache_p)->reg_list[i].size = 32; - (*cache_p)->reg_list[i].arch_info = &arch_info[i]; - (*cache_p)->reg_list[i].type = &xscale_reg_type; - arch_info[i] = xscale_reg_arch_info[i]; - arch_info[i].target = target; - } - - xscale->reg_cache = (*cache_p); -} - -static int xscale_init_target(struct command_context *cmd_ctx, - struct target *target) -{ - xscale_build_reg_cache(target); - return ERROR_OK; -} - -static int xscale_init_arch_info(struct target *target, - struct xscale_common *xscale, struct jtag_tap *tap) -{ - struct arm *arm; - uint32_t high_reset_branch, low_reset_branch; - int i; - - arm = &xscale->arm; - - /* store architecture specfic data */ - xscale->common_magic = XSCALE_COMMON_MAGIC; - - /* PXA3xx with 11 bit IR shifts the JTAG instructions */ - if (tap->ir_length == 11) - xscale->xscale_variant = XSCALE_PXA3XX; - else - xscale->xscale_variant = XSCALE_IXP4XX_PXA2XX; - - /* the debug handler isn't installed (and thus not running) at this time */ - xscale->handler_address = 0xfe000800; - - /* clear the vectors we keep locally for reference */ - memset(xscale->low_vectors, 0, sizeof(xscale->low_vectors)); - memset(xscale->high_vectors, 0, sizeof(xscale->high_vectors)); - - /* no user-specified vectors have been configured yet */ - xscale->static_low_vectors_set = 0x0; - xscale->static_high_vectors_set = 0x0; - - /* calculate branches to debug handler */ - low_reset_branch = (xscale->handler_address + 0x20 - 0x0 - 0x8) >> 2; - high_reset_branch = (xscale->handler_address + 0x20 - 0xffff0000 - 0x8) >> 2; - - xscale->low_vectors[0] = ARMV4_5_B((low_reset_branch & 0xffffff), 0); - xscale->high_vectors[0] = ARMV4_5_B((high_reset_branch & 0xffffff), 0); - - for (i = 1; i <= 7; i++) { - xscale->low_vectors[i] = ARMV4_5_B(0xfffffe, 0); - xscale->high_vectors[i] = ARMV4_5_B(0xfffffe, 0); - } - - /* 64kB aligned region used for DCache cleaning */ - xscale->cache_clean_address = 0xfffe0000; - - xscale->hold_rst = 0; - xscale->external_debug_break = 0; - - xscale->ibcr_available = 2; - xscale->ibcr0_used = 0; - xscale->ibcr1_used = 0; - - xscale->dbr_available = 2; - xscale->dbr0_used = 0; - xscale->dbr1_used = 0; - - LOG_INFO("%s: hardware has 2 breakpoints and 2 watchpoints", - target_name(target)); - - xscale->arm_bkpt = ARMV5_BKPT(0x0); - xscale->thumb_bkpt = ARMV5_T_BKPT(0x0) & 0xffff; - - xscale->vector_catch = 0x1; - - xscale->trace.data = NULL; - xscale->trace.image = NULL; - xscale->trace.mode = XSCALE_TRACE_DISABLED; - xscale->trace.buffer_fill = 0; - xscale->trace.fill_counter = 0; - - /* prepare ARMv4/5 specific information */ - arm->arch_info = xscale; - arm->core_type = ARM_MODE_ANY; - arm->read_core_reg = xscale_read_core_reg; - arm->write_core_reg = xscale_write_core_reg; - arm->full_context = xscale_full_context; - - arm_init_arch_info(target, arm); - - xscale->armv4_5_mmu.armv4_5_cache.ctype = -1; - xscale->armv4_5_mmu.get_ttb = xscale_get_ttb; - xscale->armv4_5_mmu.read_memory = xscale_read_memory; - xscale->armv4_5_mmu.write_memory = xscale_write_memory; - xscale->armv4_5_mmu.disable_mmu_caches = xscale_disable_mmu_caches; - xscale->armv4_5_mmu.enable_mmu_caches = xscale_enable_mmu_caches; - xscale->armv4_5_mmu.has_tiny_pages = 1; - xscale->armv4_5_mmu.mmu_enabled = 0; - - return ERROR_OK; -} - -static int xscale_target_create(struct target *target, Jim_Interp *interp) -{ - struct xscale_common *xscale; - - if (sizeof xscale_debug_handler > 0x800) { - LOG_ERROR("debug_handler.bin: larger than 2kb"); - return ERROR_FAIL; - } - - xscale = calloc(1, sizeof(*xscale)); - if (!xscale) - return ERROR_FAIL; - - return xscale_init_arch_info(target, xscale, target->tap); -} - -COMMAND_HANDLER(xscale_handle_debug_handler_command) -{ - struct target *target = NULL; - struct xscale_common *xscale; - int retval; - uint32_t handler_address; - - if (CMD_ARGC < 2) - return ERROR_COMMAND_SYNTAX_ERROR; - - target = get_target(CMD_ARGV[0]); - if (target == NULL) { - LOG_ERROR("target '%s' not defined", CMD_ARGV[0]); - return ERROR_FAIL; - } - - xscale = target_to_xscale(target); - retval = xscale_verify_pointer(CMD_CTX, xscale); - if (retval != ERROR_OK) - return retval; - - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], handler_address); - - if (((handler_address >= 0x800) && (handler_address <= 0x1fef800)) || - ((handler_address >= 0xfe000800) && (handler_address <= 0xfffff800))) - xscale->handler_address = handler_address; - else { - LOG_ERROR( - "xscale debug_handler
must be between 0x800 and 0x1fef800 or between 0xfe000800 and 0xfffff800"); - return ERROR_FAIL; - } - - return ERROR_OK; -} - -COMMAND_HANDLER(xscale_handle_cache_clean_address_command) -{ - struct target *target = NULL; - struct xscale_common *xscale; - int retval; - uint32_t cache_clean_address; - - if (CMD_ARGC < 2) - return ERROR_COMMAND_SYNTAX_ERROR; - - target = get_target(CMD_ARGV[0]); - if (target == NULL) { - LOG_ERROR("target '%s' not defined", CMD_ARGV[0]); - return ERROR_FAIL; - } - xscale = target_to_xscale(target); - retval = xscale_verify_pointer(CMD_CTX, xscale); - if (retval != ERROR_OK) - return retval; - - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], cache_clean_address); - - if (cache_clean_address & 0xffff) - LOG_ERROR("xscale cache_clean_address
must be 64kb aligned"); - else - xscale->cache_clean_address = cache_clean_address; - - return ERROR_OK; -} - -COMMAND_HANDLER(xscale_handle_cache_info_command) -{ - struct target *target = get_current_target(CMD_CTX); - struct xscale_common *xscale = target_to_xscale(target); - int retval; - - retval = xscale_verify_pointer(CMD_CTX, xscale); - if (retval != ERROR_OK) - return retval; - - return armv4_5_handle_cache_info_command(CMD_CTX, &xscale->armv4_5_mmu.armv4_5_cache); -} - -static int xscale_virt2phys(struct target *target, - uint32_t virtual, uint32_t *physical) -{ - struct xscale_common *xscale = target_to_xscale(target); - uint32_t cb; - - if (xscale->common_magic != XSCALE_COMMON_MAGIC) { - LOG_ERROR(xscale_not); - return ERROR_TARGET_INVALID; - } - - uint32_t ret; - int retval = armv4_5_mmu_translate_va(target, &xscale->armv4_5_mmu, - virtual, &cb, &ret); - if (retval != ERROR_OK) - return retval; - *physical = ret; - return ERROR_OK; -} - -static int xscale_mmu(struct target *target, int *enabled) -{ - struct xscale_common *xscale = target_to_xscale(target); - - if (target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_INVALID; - } - *enabled = xscale->armv4_5_mmu.mmu_enabled; - return ERROR_OK; -} - -COMMAND_HANDLER(xscale_handle_mmu_command) -{ - struct target *target = get_current_target(CMD_CTX); - struct xscale_common *xscale = target_to_xscale(target); - int retval; - - retval = xscale_verify_pointer(CMD_CTX, xscale); - if (retval != ERROR_OK) - return retval; - - if (target->state != TARGET_HALTED) { - command_print(CMD_CTX, "target must be stopped for \"%s\" command", CMD_NAME); - return ERROR_OK; - } - - if (CMD_ARGC >= 1) { - bool enable; - COMMAND_PARSE_ENABLE(CMD_ARGV[0], enable); - if (enable) - xscale_enable_mmu_caches(target, 1, 0, 0); - else - xscale_disable_mmu_caches(target, 1, 0, 0); - xscale->armv4_5_mmu.mmu_enabled = enable; - } - - command_print(CMD_CTX, "mmu %s", - (xscale->armv4_5_mmu.mmu_enabled) ? "enabled" : "disabled"); - - return ERROR_OK; -} - -COMMAND_HANDLER(xscale_handle_idcache_command) -{ - struct target *target = get_current_target(CMD_CTX); - struct xscale_common *xscale = target_to_xscale(target); - - int retval = xscale_verify_pointer(CMD_CTX, xscale); - if (retval != ERROR_OK) - return retval; - - if (target->state != TARGET_HALTED) { - command_print(CMD_CTX, "target must be stopped for \"%s\" command", CMD_NAME); - return ERROR_OK; - } - - bool icache = false; - if (strcmp(CMD_NAME, "icache") == 0) - icache = true; - if (CMD_ARGC >= 1) { - bool enable; - COMMAND_PARSE_ENABLE(CMD_ARGV[0], enable); - if (icache) { - xscale->armv4_5_mmu.armv4_5_cache.i_cache_enabled = enable; - if (enable) - xscale_enable_mmu_caches(target, 0, 0, 1); - else - xscale_disable_mmu_caches(target, 0, 0, 1); - } else { - xscale->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled = enable; - if (enable) - xscale_enable_mmu_caches(target, 0, 1, 0); - else - xscale_disable_mmu_caches(target, 0, 1, 0); - } - } - - bool enabled = icache ? - xscale->armv4_5_mmu.armv4_5_cache.i_cache_enabled : - xscale->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled; - const char *msg = enabled ? "enabled" : "disabled"; - command_print(CMD_CTX, "%s %s", CMD_NAME, msg); - - return ERROR_OK; -} - -static const struct { - char name[15]; - unsigned mask; -} vec_ids[] = { - { "fiq", DCSR_TF, }, - { "irq", DCSR_TI, }, - { "dabt", DCSR_TD, }, - { "pabt", DCSR_TA, }, - { "swi", DCSR_TS, }, - { "undef", DCSR_TU, }, - { "reset", DCSR_TR, }, -}; - -COMMAND_HANDLER(xscale_handle_vector_catch_command) -{ - struct target *target = get_current_target(CMD_CTX); - struct xscale_common *xscale = target_to_xscale(target); - int retval; - uint32_t dcsr_value; - uint32_t catch = 0; - struct reg *dcsr_reg = &xscale->reg_cache->reg_list[XSCALE_DCSR]; - - retval = xscale_verify_pointer(CMD_CTX, xscale); - if (retval != ERROR_OK) - return retval; - - dcsr_value = buf_get_u32(dcsr_reg->value, 0, 32); - if (CMD_ARGC > 0) { - if (CMD_ARGC == 1) { - if (strcmp(CMD_ARGV[0], "all") == 0) { - catch = DCSR_TRAP_MASK; - CMD_ARGC--; - } else if (strcmp(CMD_ARGV[0], "none") == 0) { - catch = 0; - CMD_ARGC--; - } - } - while (CMD_ARGC-- > 0) { - unsigned i; - for (i = 0; i < ARRAY_SIZE(vec_ids); i++) { - if (strcmp(CMD_ARGV[CMD_ARGC], vec_ids[i].name)) - continue; - catch |= vec_ids[i].mask; - break; - } - if (i == ARRAY_SIZE(vec_ids)) { - LOG_ERROR("No vector '%s'", CMD_ARGV[CMD_ARGC]); - return ERROR_COMMAND_SYNTAX_ERROR; - } - } - buf_set_u32(dcsr_reg->value, 0, 32, - (buf_get_u32(dcsr_reg->value, 0, 32) & ~DCSR_TRAP_MASK) | catch); - xscale_write_dcsr(target, -1, -1); - } - - dcsr_value = buf_get_u32(dcsr_reg->value, 0, 32); - for (unsigned i = 0; i < ARRAY_SIZE(vec_ids); i++) { - command_print(CMD_CTX, "%15s: %s", vec_ids[i].name, - (dcsr_value & vec_ids[i].mask) ? "catch" : "ignore"); - } - - return ERROR_OK; -} - - -COMMAND_HANDLER(xscale_handle_vector_table_command) -{ - struct target *target = get_current_target(CMD_CTX); - struct xscale_common *xscale = target_to_xscale(target); - int err = 0; - int retval; - - retval = xscale_verify_pointer(CMD_CTX, xscale); - if (retval != ERROR_OK) - return retval; - - if (CMD_ARGC == 0) { /* print current settings */ - int idx; - - command_print(CMD_CTX, "active user-set static vectors:"); - for (idx = 1; idx < 8; idx++) - if (xscale->static_low_vectors_set & (1 << idx)) - command_print(CMD_CTX, - "low %d: 0x%" PRIx32, - idx, - xscale->static_low_vectors[idx]); - for (idx = 1; idx < 8; idx++) - if (xscale->static_high_vectors_set & (1 << idx)) - command_print(CMD_CTX, - "high %d: 0x%" PRIx32, - idx, - xscale->static_high_vectors[idx]); - return ERROR_OK; - } - - if (CMD_ARGC != 3) - err = 1; - else { - int idx; - COMMAND_PARSE_NUMBER(int, CMD_ARGV[1], idx); - uint32_t vec; - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], vec); - - if (idx < 1 || idx >= 8) - err = 1; - - if (!err && strcmp(CMD_ARGV[0], "low") == 0) { - xscale->static_low_vectors_set |= (1<static_low_vectors[idx] = vec; - } else if (!err && (strcmp(CMD_ARGV[0], "high") == 0)) { - xscale->static_high_vectors_set |= (1<static_high_vectors[idx] = vec; - } else - err = 1; - } - - if (err) - return ERROR_COMMAND_SYNTAX_ERROR; - - return ERROR_OK; -} - - -COMMAND_HANDLER(xscale_handle_trace_buffer_command) -{ - struct target *target = get_current_target(CMD_CTX); - struct xscale_common *xscale = target_to_xscale(target); - uint32_t dcsr_value; - int retval; - - retval = xscale_verify_pointer(CMD_CTX, xscale); - if (retval != ERROR_OK) - return retval; - - if (target->state != TARGET_HALTED) { - command_print(CMD_CTX, "target must be stopped for \"%s\" command", CMD_NAME); - return ERROR_OK; - } - - if (CMD_ARGC >= 1) { - if (strcmp("enable", CMD_ARGV[0]) == 0) - xscale->trace.mode = XSCALE_TRACE_WRAP; /* default */ - else if (strcmp("disable", CMD_ARGV[0]) == 0) - xscale->trace.mode = XSCALE_TRACE_DISABLED; - else - return ERROR_COMMAND_SYNTAX_ERROR; - } - - if (CMD_ARGC >= 2 && xscale->trace.mode != XSCALE_TRACE_DISABLED) { - if (strcmp("fill", CMD_ARGV[1]) == 0) { - int buffcount = 1; /* default */ - if (CMD_ARGC >= 3) - COMMAND_PARSE_NUMBER(int, CMD_ARGV[2], buffcount); - if (buffcount < 1) { /* invalid */ - command_print(CMD_CTX, "fill buffer count must be > 0"); - xscale->trace.mode = XSCALE_TRACE_DISABLED; - return ERROR_COMMAND_SYNTAX_ERROR; - } - xscale->trace.buffer_fill = buffcount; - xscale->trace.mode = XSCALE_TRACE_FILL; - } else if (strcmp("wrap", CMD_ARGV[1]) == 0) - xscale->trace.mode = XSCALE_TRACE_WRAP; - else { - xscale->trace.mode = XSCALE_TRACE_DISABLED; - return ERROR_COMMAND_SYNTAX_ERROR; - } - } - - if (xscale->trace.mode != XSCALE_TRACE_DISABLED) { - char fill_string[12]; - sprintf(fill_string, "fill %d", xscale->trace.buffer_fill); - command_print(CMD_CTX, "trace buffer enabled (%s)", - (xscale->trace.mode == XSCALE_TRACE_FILL) - ? fill_string : "wrap"); - } else - command_print(CMD_CTX, "trace buffer disabled"); - - dcsr_value = buf_get_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 0, 32); - if (xscale->trace.mode == XSCALE_TRACE_FILL) - xscale_write_dcsr_sw(target, (dcsr_value & 0xfffffffc) | 2); - else - xscale_write_dcsr_sw(target, dcsr_value & 0xfffffffc); - - return ERROR_OK; -} - -COMMAND_HANDLER(xscale_handle_trace_image_command) -{ - struct target *target = get_current_target(CMD_CTX); - struct xscale_common *xscale = target_to_xscale(target); - int retval; - - if (CMD_ARGC < 1) - return ERROR_COMMAND_SYNTAX_ERROR; - - retval = xscale_verify_pointer(CMD_CTX, xscale); - if (retval != ERROR_OK) - return retval; - - if (xscale->trace.image) { - image_close(xscale->trace.image); - free(xscale->trace.image); - command_print(CMD_CTX, "previously loaded image found and closed"); - } - - xscale->trace.image = malloc(sizeof(struct image)); - xscale->trace.image->base_address_set = 0; - xscale->trace.image->start_address_set = 0; - - /* a base address isn't always necessary, default to 0x0 (i.e. don't relocate) */ - if (CMD_ARGC >= 2) { - xscale->trace.image->base_address_set = 1; - COMMAND_PARSE_NUMBER(llong, CMD_ARGV[1], xscale->trace.image->base_address); - } else - xscale->trace.image->base_address_set = 0; - - if (image_open(xscale->trace.image, CMD_ARGV[0], - (CMD_ARGC >= 3) ? CMD_ARGV[2] : NULL) != ERROR_OK) { - free(xscale->trace.image); - xscale->trace.image = NULL; - return ERROR_OK; - } - - return ERROR_OK; -} - -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; - int retval; - - retval = xscale_verify_pointer(CMD_CTX, xscale); - if (retval != ERROR_OK) - return retval; - - if (target->state != TARGET_HALTED) { - command_print(CMD_CTX, "target must be stopped for \"%s\" command", CMD_NAME); - return ERROR_OK; - } - - if (CMD_ARGC < 1) - return ERROR_COMMAND_SYNTAX_ERROR; - - trace_data = xscale->trace.data; - - if (!trace_data) { - command_print(CMD_CTX, "no trace data collected"); - return ERROR_OK; - } - - if (fileio_open(&file, CMD_ARGV[0], FILEIO_WRITE, FILEIO_BINARY) != ERROR_OK) - return ERROR_OK; - - 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); - - for (i = 0; i < trace_data->depth; i++) - fileio_write_u32(file, trace_data->entries[i].data | - ((trace_data->entries[i].type & 0xffff) << 16)); - - trace_data = trace_data->next; - } - - fileio_close(file); - - return ERROR_OK; -} - -COMMAND_HANDLER(xscale_handle_analyze_trace_buffer_command) -{ - struct target *target = get_current_target(CMD_CTX); - struct xscale_common *xscale = target_to_xscale(target); - int retval; - - retval = xscale_verify_pointer(CMD_CTX, xscale); - if (retval != ERROR_OK) - return retval; - - xscale_analyze_trace(target, CMD_CTX); - - return ERROR_OK; -} - -COMMAND_HANDLER(xscale_handle_cp15) -{ - struct target *target = get_current_target(CMD_CTX); - struct xscale_common *xscale = target_to_xscale(target); - int retval; - - retval = xscale_verify_pointer(CMD_CTX, xscale); - if (retval != ERROR_OK) - return retval; - - if (target->state != TARGET_HALTED) { - command_print(CMD_CTX, "target must be stopped for \"%s\" command", CMD_NAME); - return ERROR_OK; - } - uint32_t reg_no = 0; - struct reg *reg = NULL; - if (CMD_ARGC > 0) { - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], reg_no); - /*translate from xscale cp15 register no to openocd register*/ - switch (reg_no) { - case 0: - reg_no = XSCALE_MAINID; - break; - case 1: - reg_no = XSCALE_CTRL; - break; - case 2: - reg_no = XSCALE_TTB; - break; - case 3: - reg_no = XSCALE_DAC; - break; - case 5: - reg_no = XSCALE_FSR; - break; - case 6: - reg_no = XSCALE_FAR; - break; - case 13: - reg_no = XSCALE_PID; - break; - case 15: - reg_no = XSCALE_CPACCESS; - break; - default: - command_print(CMD_CTX, "invalid register number"); - return ERROR_COMMAND_SYNTAX_ERROR; - } - reg = &xscale->reg_cache->reg_list[reg_no]; - - } - if (CMD_ARGC == 1) { - uint32_t value; - - /* read cp15 control register */ - xscale_get_reg(reg); - value = buf_get_u32(reg->value, 0, 32); - command_print(CMD_CTX, "%s (/%i): 0x%" PRIx32 "", reg->name, (int)(reg->size), - value); - } else if (CMD_ARGC == 2) { - uint32_t value; - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], value); - - /* send CP write request (command 0x41) */ - xscale_send_u32(target, 0x41); - - /* send CP register number */ - xscale_send_u32(target, reg_no); - - /* send CP register value */ - xscale_send_u32(target, value); - - /* execute cpwait to ensure outstanding operations complete */ - xscale_send_u32(target, 0x53); - } else - return ERROR_COMMAND_SYNTAX_ERROR; - - return ERROR_OK; -} - -static const struct command_registration xscale_exec_command_handlers[] = { - { - .name = "cache_info", - .handler = xscale_handle_cache_info_command, - .mode = COMMAND_EXEC, - .help = "display information about CPU caches", - }, - { - .name = "mmu", - .handler = xscale_handle_mmu_command, - .mode = COMMAND_EXEC, - .help = "enable or disable the MMU", - .usage = "['enable'|'disable']", - }, - { - .name = "icache", - .handler = xscale_handle_idcache_command, - .mode = COMMAND_EXEC, - .help = "display ICache state, optionally enabling or " - "disabling it", - .usage = "['enable'|'disable']", - }, - { - .name = "dcache", - .handler = xscale_handle_idcache_command, - .mode = COMMAND_EXEC, - .help = "display DCache state, optionally enabling or " - "disabling it", - .usage = "['enable'|'disable']", - }, - { - .name = "vector_catch", - .handler = xscale_handle_vector_catch_command, - .mode = COMMAND_EXEC, - .help = "set or display mask of vectors " - "that should trigger debug entry", - .usage = "['all'|'none'|'fiq'|'irq'|'dabt'|'pabt'|'swi'|'undef'|'reset']", - }, - { - .name = "vector_table", - .handler = xscale_handle_vector_table_command, - .mode = COMMAND_EXEC, - .help = "set vector table entry in mini-ICache, " - "or display current tables", - .usage = "[('high'|'low') index code]", - }, - { - .name = "trace_buffer", - .handler = xscale_handle_trace_buffer_command, - .mode = COMMAND_EXEC, - .help = "display trace buffer status, enable or disable " - "tracing, and optionally reconfigure trace mode", - .usage = "['enable'|'disable' ['fill' [number]|'wrap']]", - }, - { - .name = "dump_trace", - .handler = xscale_handle_dump_trace_command, - .mode = COMMAND_EXEC, - .help = "dump content of trace buffer to file", - .usage = "filename", - }, - { - .name = "analyze_trace", - .handler = xscale_handle_analyze_trace_buffer_command, - .mode = COMMAND_EXEC, - .help = "analyze content of trace buffer", - .usage = "", - }, - { - .name = "trace_image", - .handler = xscale_handle_trace_image_command, - .mode = COMMAND_EXEC, - .help = "load image from file to address (default 0)", - .usage = "filename [offset [filetype]]", - }, - { - .name = "cp15", - .handler = xscale_handle_cp15, - .mode = COMMAND_EXEC, - .help = "Read or write coprocessor 15 register.", - .usage = "register [value]", - }, - COMMAND_REGISTRATION_DONE -}; -static const struct command_registration xscale_any_command_handlers[] = { - { - .name = "debug_handler", - .handler = xscale_handle_debug_handler_command, - .mode = COMMAND_ANY, - .help = "Change address used for debug handler.", - .usage = "
", - }, - { - .name = "cache_clean_address", - .handler = xscale_handle_cache_clean_address_command, - .mode = COMMAND_ANY, - .help = "Change address used for cleaning data cache.", - .usage = "address", - }, - { - .chain = xscale_exec_command_handlers, - }, - COMMAND_REGISTRATION_DONE -}; -static const struct command_registration xscale_command_handlers[] = { - { - .chain = arm_command_handlers, - }, - { - .name = "xscale", - .mode = COMMAND_ANY, - .help = "xscale command group", - .usage = "", - .chain = xscale_any_command_handlers, - }, - COMMAND_REGISTRATION_DONE -}; - -struct target_type xscale_target = { - .name = "xscale", - - .poll = xscale_poll, - .arch_state = xscale_arch_state, - - .halt = xscale_halt, - .resume = xscale_resume, - .step = xscale_step, - - .assert_reset = xscale_assert_reset, - .deassert_reset = xscale_deassert_reset, - - /* REVISIT on some cores, allow exporting iwmmxt registers ... */ - .get_gdb_reg_list = arm_get_gdb_reg_list, - - .read_memory = xscale_read_memory, - .read_phys_memory = xscale_read_phys_memory, - .write_memory = xscale_write_memory, - .write_phys_memory = xscale_write_phys_memory, - - .checksum_memory = arm_checksum_memory, - .blank_check_memory = arm_blank_check_memory, - - .run_algorithm = armv4_5_run_algorithm, - - .add_breakpoint = xscale_add_breakpoint, - .remove_breakpoint = xscale_remove_breakpoint, - .add_watchpoint = xscale_add_watchpoint, - .remove_watchpoint = xscale_remove_watchpoint, - - .commands = xscale_command_handlers, - .target_create = xscale_target_create, - .init_target = xscale_init_target, - - .virt2phys = xscale_virt2phys, - .mmu = xscale_mmu -}; diff --git a/src/target/xscale.h b/src/target/xscale.h deleted file mode 100644 index a86edb2fb..000000000 --- a/src/target/xscale.h +++ /dev/null @@ -1,188 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * Copyright (C) 2007,2008 Øyvind Harboe * - * oyvind.harboe@zylin.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifndef OPENOCD_TARGET_XSCALE_H -#define OPENOCD_TARGET_XSCALE_H - -#include "arm.h" -#include "armv4_5_mmu.h" -#include "trace.h" - -#define XSCALE_COMMON_MAGIC 0x58534341 - -/* These four JTAG instructions are architecturally defined. - * Lengths are core-specific; originally 5 bits, later 7. - */ -#define XSCALE_DBGRX 0x02 -#define XSCALE_DBGTX 0x10 -#define XSCALE_LDIC 0x07 -#define XSCALE_SELDCSR 0x09 - -/* Possible CPU types */ -#define XSCALE_IXP4XX_PXA2XX 0x0 -#define XSCALE_PXA3XX 0x4 - -enum xscale_debug_reason { - XSCALE_DBG_REASON_GENERIC, - XSCALE_DBG_REASON_RESET, - XSCALE_DBG_REASON_TB_FULL, -}; - -enum xscale_trace_entry_type { - XSCALE_TRACE_MESSAGE = 0x0, - XSCALE_TRACE_ADDRESS = 0x1, -}; - -struct xscale_trace_entry { - uint8_t data; - enum xscale_trace_entry_type type; -}; - -struct xscale_trace_data { - struct xscale_trace_entry *entries; - int depth; - uint32_t chkpt0; - uint32_t chkpt1; - uint32_t last_instruction; - unsigned int num_checkpoints; - struct xscale_trace_data *next; -}; - -enum trace_mode { - XSCALE_TRACE_DISABLED, - XSCALE_TRACE_FILL, - XSCALE_TRACE_WRAP -}; - -struct xscale_trace { - struct image *image; /* source for target opcodes */ - struct xscale_trace_data *data; /* linked list of collected trace data */ - int buffer_fill; /* maximum number of trace runs to read */ - int fill_counter; /* running count during trace collection */ - enum trace_mode mode; - enum arm_state core_state; /* current core state (ARM, Thumb) */ -}; - -struct xscale_common { - /* armv4/5 common stuff */ - struct arm arm; - - int common_magic; - - /* XScale registers (CP15, DBG) */ - struct reg_cache *reg_cache; - - /* current state of the debug handler */ - uint32_t handler_address; - - /* target-endian buffers with exception vectors */ - uint32_t low_vectors[8]; - uint32_t high_vectors[8]; - - /* static low vectors */ - uint8_t static_low_vectors_set; /* bit field with static vectors set by the user */ - uint8_t static_high_vectors_set; /* bit field with static vectors set by the user */ - uint32_t static_low_vectors[8]; - uint32_t static_high_vectors[8]; - - /* DCache cleaning */ - uint32_t cache_clean_address; - - /* whether hold_rst and ext_dbg_break should be set */ - int hold_rst; - int external_debug_break; - - /* breakpoint / watchpoint handling */ - int dbr_available; - int dbr0_used; - int dbr1_used; - int ibcr_available; - int ibcr0_used; - int ibcr1_used; - uint32_t arm_bkpt; - uint16_t thumb_bkpt; - - uint8_t vector_catch; - - struct xscale_trace trace; - - int arch_debug_reason; - - /* MMU/Caches */ - struct armv4_5_mmu_common armv4_5_mmu; - uint32_t cp15_control_reg; - - int fast_memory_access; - - /* CPU variant */ - int xscale_variant; -}; - -static inline struct xscale_common * -target_to_xscale(struct target *target) -{ - return container_of(target->arch_info, struct xscale_common, arm); -} - -struct xscale_reg { - int dbg_handler_number; - struct target *target; -}; - -enum { - XSCALE_MAINID, /* 0 */ - XSCALE_CACHETYPE, - XSCALE_CTRL, - XSCALE_AUXCTRL, - XSCALE_TTB, - XSCALE_DAC, - XSCALE_FSR, - XSCALE_FAR, - XSCALE_PID, - XSCALE_CPACCESS, - XSCALE_IBCR0, /* 10 */ - XSCALE_IBCR1, - XSCALE_DBR0, - XSCALE_DBR1, - XSCALE_DBCON, - XSCALE_TBREG, - XSCALE_CHKPT0, - XSCALE_CHKPT1, - XSCALE_DCSR, - XSCALE_TX, - XSCALE_RX, /* 20 */ - XSCALE_TXRXCTRL, -}; - -#define ERROR_XSCALE_NO_TRACE_DATA (-700) - -/* DCSR bit and field definitions */ -#define DCSR_TR (1 << 16) -#define DCSR_TU (1 << 17) -#define DCSR_TS (1 << 18) -#define DCSR_TA (1 << 19) -#define DCSR_TD (1 << 20) -#define DCSR_TI (1 << 22) -#define DCSR_TF (1 << 23) -#define DCSR_TRAP_MASK \ - (DCSR_TF | DCSR_TI | DCSR_TD | DCSR_TA | DCSR_TS | DCSR_TU | DCSR_TR) - -#endif /* OPENOCD_TARGET_XSCALE_H */ diff --git a/src/target/xscale/build.sh b/src/target/xscale/build.sh deleted file mode 100755 index fc828b2c2..000000000 --- a/src/target/xscale/build.sh +++ /dev/null @@ -1,7 +0,0 @@ -arm-none-eabi-gcc -c debug_handler.S -o debug_handler.o -arm-none-eabi-ld -EL -n -Tdebug_handler.cmd debug_handler.o -o debug_handler.out -arm-none-eabi-objcopy -O binary debug_handler.out debug_handler.bin - -#arm-none-eabi-gcc -mbig-endian -c debug_handler.S -o debug_handler_be.o -#arm-none-eabi-ld -EB -n -Tdebug_handler.cmd debug_handler_be.o -o debug_handler_be.out -#arm-none-eabi-objcopy -O binary debug_handler_be.out debug_handler_be.bin diff --git a/src/target/xscale/debug_handler.S b/src/target/xscale/debug_handler.S deleted file mode 100644 index 66dfa8891..000000000 --- a/src/target/xscale/debug_handler.S +++ /dev/null @@ -1,716 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2006 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ -#include "protocol.h" - - .text - .align 4 - -@ Disable thumb mode - .code 32 - -@ send word to debugger -.macro m_send_to_debugger reg -1: - mrc p14, 0, r15, c14, c0, 0 - bvs 1b - mcr p14, 0, \reg, c8, c0, 0 -.endm - -@ receive word from debugger -.macro m_receive_from_debugger reg -1: - mrc p14, 0, r15, c14, c0, 0 - bpl 1b - mrc p14, 0, \reg, c9, c0, 0 -.endm - -@ save register on debugger, small -.macro m_small_save_reg reg - mov r0, \reg - bl send_to_debugger -.endm - -@ save status register on debugger, small -.macro m_small_save_psr - mrs r0, spsr - bl send_to_debugger -.endm - -@ wait for all outstanding coprocessor accesses to complete -.macro m_cpwait - mrc p15, 0, r0, c2, c0, 0 - mov r0, r0 - sub pc, pc, #4 -.endm - -.global reset_handler -.global undef_handler -.global swi_handler -.global prefetch_abort_handler -.global data_abort_handler -.global irq_handler -.global fiq_handler - -.section .part1 , "ax" - -reset_handler: - @ read DCSR - mrc p14, 0, r13, c10, c0 - @ check if global enable bit (GE) is set - ands r13, r13, #0x80000000 - - bne debug_handler - - @ set global enable bit (GE) - mov r13, #0xc0000000 - mcr p14, 0, r13, c10, c0 - -debug_handler: - - @ save r0 without modifying other registers - m_send_to_debugger r0 - - @ save lr (program PC) without branching (use macro) - m_send_to_debugger r14 - - @ save non-banked registers and spsr (program CPSR) - m_small_save_reg r1 - m_small_save_reg r2 - m_small_save_reg r3 - m_small_save_reg r4 - m_small_save_reg r5 - m_small_save_reg r6 - m_small_save_reg r7 - m_small_save_psr - - mrs r0, spsr - - @ prepare program PSR for debug use (clear Thumb, set I/F to disable interrupts) - bic r0, r0, #PSR_T - orr r0, r0, #(PSR_I | PSR_F) - - @ examine mode bits - and r1, r0, #MODE_MASK - cmp r1, #MODE_USR - - bne not_user_mode - - @ replace USR mode with SYS - bic r0, r0, #MODE_MASK - orr r0, r0, #MODE_SYS - -not_user_mode: - - b save_banked_registers - -@ command loop -@ wait for command from debugger, than execute desired function -get_command: - bl receive_from_debugger - - @ 0x0n - register access - cmp r0, #0x0 - beq get_banked_registers - - cmp r0, #0x1 - beq set_banked_registers - - @ 0x1n - read memory - cmp r0, #0x11 - beq read_byte - - cmp r0, #0x12 - beq read_half_word - - cmp r0, #0x14 - beq read_word - - @ 0x2n - write memory - cmp r0, #0x21 - beq write_byte - - cmp r0, #0x22 - beq write_half_word - - cmp r0, #0x24 - beq write_word - - @ 0x3n - program execution - cmp r0, #0x30 - beq resume - - cmp r0, #0x31 - beq resume_w_trace - - @ 0x4n - coprocessor access - cmp r0, #0x40 - beq read_cp_reg - - cmp r0, #0x41 - beq write_cp_reg - - @ 0x5n - cache and mmu functions - cmp r0, #0x50 - beq clean_d_cache - - cmp r0, #0x51 - beq invalidate_d_cache - - cmp r0, #0x52 - beq invalidate_i_cache - - cmp r0, #0x53 - beq cpwait - - @ 0x6n - misc functions - cmp r0, #0x60 - beq clear_sa - - cmp r0, #0x61 - beq read_trace_buffer - - cmp r0, #0x62 - beq clean_trace_buffer - - @ return (back to get_command) - b get_command - -@ ---- - -@ resume program execution -resume: - @ restore CPSR (SPSR_dbg) - bl receive_from_debugger - msr spsr, r0 - - @ restore registers (r7 - r0) - bl receive_from_debugger @ r7 - mov r7, r0 - bl receive_from_debugger @ r6 - mov r6, r0 - bl receive_from_debugger @ r5 - mov r5, r0 - bl receive_from_debugger @ r4 - mov r4, r0 - bl receive_from_debugger @ r3 - mov r3, r0 - bl receive_from_debugger @ r2 - mov r2, r0 - bl receive_from_debugger @ r1 - mov r1, r0 - bl receive_from_debugger @ r0 - - @ resume addresss - m_receive_from_debugger lr - - @ branch back to application code, restoring CPSR - subs pc, lr, #0 - -@ get banked registers -@ receive mode bits from host, then run into save_banked_registers to - -get_banked_registers: - bl receive_from_debugger - -@ save banked registers -@ r0[4:0]: desired mode bits -save_banked_registers: - @ backup CPSR - mrs r7, cpsr - msr cpsr_c, r0 - nop - - @ keep current mode bits in r1 for later use - and r1, r0, #MODE_MASK - - @ backup banked registers - m_send_to_debugger r8 - m_send_to_debugger r9 - m_send_to_debugger r10 - m_send_to_debugger r11 - m_send_to_debugger r12 - m_send_to_debugger r13 - m_send_to_debugger r14 - - @ if not in SYS mode (or USR, which we replaced with SYS before) - cmp r1, #MODE_SYS - - beq no_spsr_to_save - - @ backup SPSR - mrs r0, spsr - m_send_to_debugger r0 - -no_spsr_to_save: - - @ restore CPSR for SDS - msr cpsr_c, r7 - nop - - @ return - b get_command - -@ ---- - - -@ set banked registers -@ receive mode bits from host, then run into save_banked_registers to - -set_banked_registers: - bl receive_from_debugger - -@ restore banked registers -@ r0[4:0]: desired mode bits -restore_banked_registers: - @ backup CPSR - mrs r7, cpsr - msr cpsr_c, r0 - nop - - @ keep current mode bits in r1 for later use - and r1, r0, #MODE_MASK - - @ set banked registers - m_receive_from_debugger r8 - m_receive_from_debugger r9 - m_receive_from_debugger r10 - m_receive_from_debugger r11 - m_receive_from_debugger r12 - m_receive_from_debugger r13 - m_receive_from_debugger r14 - - @ if not in SYS mode (or USR, which we replaced with SYS before) - cmp r1, #MODE_SYS - - beq no_spsr_to_restore - - @ set SPSR - m_receive_from_debugger r0 - msr spsr, r0 - -no_spsr_to_restore: - - @ restore CPSR for SDS - msr cpsr_c, r7 - nop - - @ return - b get_command - -@ ---- - -read_byte: - @ r2: address - bl receive_from_debugger - mov r2, r0 - - @ r1: count - bl receive_from_debugger - mov r1, r0 - -rb_loop: - ldrb r0, [r2], #1 - - @ drain write- (and fill-) buffer to work around XScale errata - mcr p15, 0, r8, c7, c10, 4 - - bl send_to_debugger - - subs r1, r1, #1 - bne rb_loop - - @ return - b get_command - -@ ---- - -read_half_word: - @ r2: address - bl receive_from_debugger - mov r2, r0 - - @ r1: count - bl receive_from_debugger - mov r1, r0 - -rh_loop: - ldrh r0, [r2], #2 - - @ drain write- (and fill-) buffer to work around XScale errata - mcr p15, 0, r8, c7, c10, 4 - - bl send_to_debugger - - subs r1, r1, #1 - bne rh_loop - - @ return - b get_command - -@ ---- - -read_word: - @ r2: address - bl receive_from_debugger - mov r2, r0 - - @ r1: count - bl receive_from_debugger - mov r1, r0 - -rw_loop: - ldr r0, [r2], #4 - - @ drain write- (and fill-) buffer to work around XScale errata - mcr p15, 0, r8, c7, c10, 4 - - bl send_to_debugger - - subs r1, r1, #1 - bne rw_loop - - @ return - b get_command - -@ ---- - -write_byte: - @ r2: address - bl receive_from_debugger - mov r2, r0 - - @ r1: count - bl receive_from_debugger - mov r1, r0 - -wb_loop: - bl receive_from_debugger - strb r0, [r2], #1 - - @ drain write- (and fill-) buffer to work around XScale errata - mcr p15, 0, r8, c7, c10, 4 - - subs r1, r1, #1 - bne wb_loop - - @ return - b get_command - -@ ---- - -write_half_word: - @ r2: address - bl receive_from_debugger - mov r2, r0 - - @ r1: count - bl receive_from_debugger - mov r1, r0 - -wh_loop: - bl receive_from_debugger - strh r0, [r2], #2 - - @ drain write- (and fill-) buffer to work around XScale errata - mcr p15, 0, r8, c7, c10, 4 - - subs r1, r1, #1 - bne wh_loop - - @ return - b get_command - -@ ---- - -write_word: - @ r2: address - bl receive_from_debugger - mov r2, r0 - - @ r1: count - bl receive_from_debugger - mov r1, r0 - -ww_loop: - bl receive_from_debugger - str r0, [r2], #4 - - @ drain write- (and fill-) buffer to work around XScale errata - mcr p15, 0, r8, c7, c10, 4 - - subs r1, r1, #1 - bne ww_loop - - @ return - b get_command - -@ ---- - -clear_sa: - @ read DCSR - mrc p14, 0, r0, c10, c0 - - @ clear SA bit - bic r0, r0, #0x20 - - @ write DCSR - mcr p14, 0, r0, c10, c0 - - @ return - b get_command - -@ ---- - -clean_d_cache: - @ r0: cache clean area - bl receive_from_debugger - - mov r1, #1024 -clean_loop: - mcr p15, 0, r0, c7, c2, 5 - add r0, r0, #32 - subs r1, r1, #1 - bne clean_loop - - @ return - b get_command - -@ ---- - -invalidate_d_cache: - mcr p15, 0, r0, c7, c6, 0 - - @ return - b get_command - -@ ---- - -invalidate_i_cache: - mcr p15, 0, r0, c7, c5, 0 - - @ return - b get_command - -@ ---- - -cpwait: - m_cpwait - - @return - b get_command - -@ ---- - -.section .part2 , "ax" - -read_cp_reg: - @ requested cp register - bl receive_from_debugger - - adr r1, read_cp_table - add pc, r1, r0, lsl #3 - -read_cp_table: - mrc p15, 0, r0, c0, c0, 0 @ XSCALE_MAINID - b read_cp_reg_reply - mrc p15, 0, r0, c0, c0, 1 @ XSCALE_CACHETYPE - b read_cp_reg_reply - mrc p15, 0, r0, c1, c0, 0 @ XSCALE_CTRL - b read_cp_reg_reply - mrc p15, 0, r0, c1, c0, 1 @ XSCALE_AUXCTRL - b read_cp_reg_reply - mrc p15, 0, r0, c2, c0, 0 @ XSCALE_TTB - b read_cp_reg_reply - mrc p15, 0, r0, c3, c0, 0 @ XSCALE_DAC - b read_cp_reg_reply - mrc p15, 0, r0, c5, c0, 0 @ XSCALE_FSR - b read_cp_reg_reply - mrc p15, 0, r0, c6, c0, 0 @ XSCALE_FAR - b read_cp_reg_reply - mrc p15, 0, r0, c13, c0, 0 @ XSCALE_PID - b read_cp_reg_reply - mrc p15, 0, r0, c15, c0, 0 @ XSCALE_CP_ACCESS - b read_cp_reg_reply - mrc p15, 0, r0, c14, c8, 0 @ XSCALE_IBCR0 - b read_cp_reg_reply - mrc p15, 0, r0, c14, c9, 0 @ XSCALE_IBCR1 - b read_cp_reg_reply - mrc p15, 0, r0, c14, c0, 0 @ XSCALE_DBR0 - b read_cp_reg_reply - mrc p15, 0, r0, c14, c3, 0 @ XSCALE_DBR1 - b read_cp_reg_reply - mrc p15, 0, r0, c14, c4, 0 @ XSCALE_DBCON - b read_cp_reg_reply - mrc p14, 0, r0, c11, c0, 0 @ XSCALE_TBREG - b read_cp_reg_reply - mrc p14, 0, r0, c12, c0, 0 @ XSCALE_CHKPT0 - b read_cp_reg_reply - mrc p14, 0, r0, c13, c0, 0 @ XSCALE_CHKPT1 - b read_cp_reg_reply - mrc p14, 0, r0, c10, c0, 0 @ XSCALE_DCSR - b read_cp_reg_reply - -read_cp_reg_reply: - bl send_to_debugger - - @ return - b get_command - -@ ---- - -write_cp_reg: - @ requested cp register - bl receive_from_debugger - mov r1, r0 - - @ value to be written - bl receive_from_debugger - - adr r2, write_cp_table - add pc, r2, r1, lsl #3 - -write_cp_table: - mcr p15, 0, r0, c0, c0, 0 @ XSCALE_MAINID (0x0) - b get_command - mcr p15, 0, r0, c0, c0, 1 @ XSCALE_CACHETYPE (0x1) - b get_command - mcr p15, 0, r0, c1, c0, 0 @ XSCALE_CTRL (0x2) - b get_command - mcr p15, 0, r0, c1, c0, 1 @ XSCALE_AUXCTRL (0x3) - b get_command - mcr p15, 0, r0, c2, c0, 0 @ XSCALE_TTB (0x4) - b get_command - mcr p15, 0, r0, c3, c0, 0 @ XSCALE_DAC (0x5) - b get_command - mcr p15, 0, r0, c5, c0, 0 @ XSCALE_FSR (0x6) - b get_command - mcr p15, 0, r0, c6, c0, 0 @ XSCALE_FAR (0x7) - b get_command - mcr p15, 0, r0, c13, c0, 0 @ XSCALE_PID (0x8) - b get_command - mcr p15, 0, r0, c15, c0, 0 @ XSCALE_CP_ACCESS (0x9) - b get_command - mcr p15, 0, r0, c14, c8, 0 @ XSCALE_IBCR0 (0xa) - b get_command - mcr p15, 0, r0, c14, c9, 0 @ XSCALE_IBCR1 (0xb) - b get_command - mcr p15, 0, r0, c14, c0, 0 @ XSCALE_DBR0 (0xc) - b get_command - mcr p15, 0, r0, c14, c3, 0 @ XSCALE_DBR1 (0xd) - b get_command - mcr p15, 0, r0, c14, c4, 0 @ XSCALE_DBCON (0xe) - b get_command - mcr p14, 0, r0, c11, c0, 0 @ XSCALE_TBREG (0xf) - b get_command - mcr p14, 0, r0, c12, c0, 0 @ XSCALE_CHKPT0 (0x10) - b get_command - mcr p14, 0, r0, c13, c0, 0 @ XSCALE_CHKPT1 (0x11) - b get_command - mcr p14, 0, r0, c10, c0, 0 @ XSCALE_DCSR (0x12) - b get_command - -@ ---- - -read_trace_buffer: - - @ dump 256 entries from trace buffer - mov r1, #256 -read_tb_loop: - mrc p14, 0, r0, c11, c0, 0 @ XSCALE_TBREG - bl send_to_debugger - subs r1, r1, #1 - bne read_tb_loop - - @ dump checkpoint register 0 - mrc p14, 0, r0, c12, c0, 0 @ XSCALE_CHKPT0 (0x10) - bl send_to_debugger - - @ dump checkpoint register 1 - mrc p14, 0, r0, c13, c0, 0 @ XSCALE_CHKPT1 (0x11) - bl send_to_debugger - - @ return - b get_command - -@ ---- - -clean_trace_buffer: - - @ clean 256 entries from trace buffer - mov r1, #256 -clean_tb_loop: - mrc p14, 0, r0, c11, c0, 0 @ XSCALE_TBREG - subs r1, r1, #1 - bne clean_tb_loop - - @ return - b get_command - -@ ---- - - -@ resume program execution with trace buffer enabled -resume_w_trace: - @ restore CPSR (SPSR_dbg) - bl receive_from_debugger - msr spsr, r0 - - @ restore registers (r7 - r0) - bl receive_from_debugger @ r7 - mov r7, r0 - bl receive_from_debugger @ r6 - mov r6, r0 - bl receive_from_debugger @ r5 - mov r5, r0 - bl receive_from_debugger @ r4 - mov r4, r0 - bl receive_from_debugger @ r3 - mov r3, r0 - bl receive_from_debugger @ r2 - mov r2, r0 - bl receive_from_debugger @ r1 - mov r1, r0 - bl receive_from_debugger @ r0 - - @ resume addresss - m_receive_from_debugger lr - - mrc p14, 0, r13, c10, c0, 0 @ XSCALE_DCSR - orr r13, r13, #1 - mcr p14, 0, r13, c10, c0, 0 @ XSCALE_DCSR - - @ branch back to application code, restoring CPSR - subs pc, lr, #0 - -undef_handler: -swi_handler: -prefetch_abort_handler: -data_abort_handler: -irq_handler: -fiq_handler: -1: - b 1b - -send_to_debugger: - m_send_to_debugger r0 - mov pc, lr - -receive_from_debugger: - m_receive_from_debugger r0 - mov pc, lr - diff --git a/src/target/xscale/debug_handler.bin b/src/target/xscale/debug_handler.bin deleted file mode 100755 index 2dde18531648415e9ab588ea1bd3f743e3732e5e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1592 zcmaKsO-NKx6vyv#)Ui?DyE>yeqvL2vL|=@3EP?{twsFkb3?U{F8WGaA7HZ2#p;i^x zgNQa||RBHLW=u+9^N`(xS%BH~z@H$ut-UK7yEwB;1 z3+@6RfKA{dFbPJ$W^liuLM`AM_@}^CFa0$7IscYzUbKA&Gc z%K7DboWsms+etDzZRZd(WjhC$Ew;0dnY5j~%m&-p!_>CZ1iJN2Yl@P}bz~B})@wN` z*XStJOlsrxV9?itVV^zXv&Ve)w9j7j+2~&a^$y@%+z)?`gYI`9;(Y7szqzFKVAQ)0 zX+7+-M|}2}&z|<#i#{9Y_Hy}G3zKWn<9NB;KrRcM3u-sdMC}YU_vQXjkY?Z;x-Ii7 zpO0OGj(yfmxw=s`x5T=)K3z9-?6Ypt)fK8cvfpc;t^+#uS@+7-z2tQ@AzJUdXQ6xH z>Yls0XW*!skZ*gs)6n6r$$pPr9quUJ%)plYTAsE5b?eY z@A(^NK8Cew#EyVfU^D;MswBQUg}K(uLHOIh`pwlo$!RFlx7NR;Els=e29sbTsI3b0 ziTw(Si(g5#!Z1aJRkTxBO;y4;g@p;K0BfvzvcM=2W%}0!kh7vStR=x8ptcNJ72lv0@eAm?FhJjg zMf6ozOj%($IYNs*gEf{(pTH>iQQ{^ofMNLaU36`Rc(*pN=)_= diff --git a/src/target/xscale/debug_handler.cmd b/src/target/xscale/debug_handler.cmd deleted file mode 100644 index d943b13b3..000000000 --- a/src/target/xscale/debug_handler.cmd +++ /dev/null @@ -1,49 +0,0 @@ -/* identify the Entry Point */ -ENTRY(reset_handler) - -/* specify the mini-ICache memory areas */ -MEMORY -{ - mini_icache_0 (x) : ORIGIN = 0x0, LENGTH = 1024 /* first part of mini icache (sets 0-31) */ - mini_icache_1 (x) : ORIGIN = 0x400, LENGTH = 1024 /* second part of mini icache (sets 0-31) */ -} - -/* now define the output sections */ -SECTIONS -{ - .part1 : - { - LONG(0) - LONG(0) - LONG(0) - LONG(0) - LONG(0) - LONG(0) - LONG(0) - LONG(0) - *(.part1) - } >mini_icache_0 - - .part2 : - { - LONG(0) - LONG(0) - LONG(0) - LONG(0) - LONG(0) - LONG(0) - LONG(0) - LONG(0) - *(.part2) - FILL(0x0) - } >mini_icache_1 - - /DISCARD/ : - { - *(.text) - *(.glue_7) - *(.glue_7t) - *(.data) - *(.bss) - } -} diff --git a/src/target/xscale/protocol.h b/src/target/xscale/protocol.h deleted file mode 100644 index cb01655ee..000000000 --- a/src/target/xscale/protocol.h +++ /dev/null @@ -1,68 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2006 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#define REG_R0 0 -#define REG_R1 1 -#define REG_R2 2 -#define REG_R3 3 -#define REG_R4 4 -#define REG_R5 5 -#define REG_R6 6 -#define REG_R7 7 -#define REG_R8 8 -#define REG_R9 9 -#define REG_R10 10 -#define REG_R11 11 -#define REG_R12 12 -#define REG_R13 13 -#define REG_R14 14 -#define REG_R15 15 -#define REG_CPSR 16 -#define REG_SPSR 17 - -#define MODE_USR 0x10 -#define MODE_FIQ 0x11 -#define MODE_IRQ 0x12 -#define MODE_SVC 0x13 -#define MODE_ABT 0x17 -#define MODE_UND 0x1b -#define MODE_SYS 0x1f - -#define MODE_ANY 0x40 -#define MODE_CURRENT 0x80 - -#define MODE_MASK 0x1f -#define PSR_I 0x80 -#define PSR_F 0x40 -#define PSR_T 0x20 - -#define XSCALE_DBG_MAINID 0x0 -#define XSCALE_DBG_CACHETYPE 0x1 -#define XSCALE_DBG_CTRL 0x2 -#define XSCALE_DBG_AUXCTRL 0x3 -#define XSCALE_DBG_TTB 0x4 -#define XSCALE_DBG_DAC 0x5 -#define XSCALE_DBG_FSR 0x6 -#define XSCALE_DBG_FAR 0x7 -#define XSCALE_DBG_PID 0x8 -#define XSCALE_DBG_CPACCESS 0x9 -#define XSCALE_DBG_IBCR0 0xa -#define XSCALE_DBG_IBCR1 0xb -#define XSCALE_DBG_DBR0 0xc -#define XSCALE_DBG_DBR1 0xd -#define XSCALE_DBG_DBCON 0xe diff --git a/src/transport/Makefile.am b/src/transport/Makefile.am deleted file mode 100644 index 7c6224a48..000000000 --- a/src/transport/Makefile.am +++ /dev/null @@ -1,11 +0,0 @@ -include $(top_srcdir)/common.mk - -#METASOURCES = AUTO -noinst_LTLIBRARIES = libtransport.la -libtransport_la_SOURCES = \ - transport.c - -noinst_HEADERS = \ - transport.h - -MAINTAINERCLEANFILES = $(srcdir)/Makefile.in diff --git a/src/transport/transport.c b/src/transport/transport.c deleted file mode 100644 index 708594712..000000000 --- a/src/transport/transport.c +++ /dev/null @@ -1,380 +0,0 @@ -/* - * Copyright (c) 2010 by David Brownell - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -/** @file - * Infrastructure for specifying and managing the transport protocol - * used in a given debug or programming session. - * - * Examples of "debug-capable" transports are JTAG or SWD. - * Additionally, JTAG supports boundary scan testing. - * - * Examples of "programming-capable" transports include SPI or UART; - * those are used (often mediated by a ROM bootloader) for ISP style - * programming, to perform an initial load of code into flash, or - * sometimes into SRAM. Target code could use "variant" options to - * decide how to use such protocols. For example, Cortex-M3 cores - * from TI/Luminary and from NXP use different protocols for for - * UART or SPI based firmware loading. - * - * As a rule, there are protocols layered on top of the transport. - * For example, different chip families use JTAG in different ways - * for debugging. Also, each family that supports programming over - * a UART link for initial firmware loading tends to define its own - * messaging and error handling. - */ - -#include -#include - -extern struct command_context *global_cmd_ctx; - -/*-----------------------------------------------------------------------*/ - -/* - * Infrastructure internals - */ - -/** List of transports known to OpenOCD. */ -static struct transport *transport_list; - -/** - * NULL-terminated Vector of names of transports which the - * currently selected debug adapter supports. This is declared - * by the time that adapter is fully set up. - */ -static const char * const *allowed_transports; - -/** * The transport being used for the current OpenOCD session. */ -static struct transport *session; - -static int transport_select(struct command_context *ctx, const char *name) -{ - /* name may only identify a known transport; - * caller guarantees session's transport isn't yet set.*/ - for (struct transport *t = transport_list; t; t = t->next) { - if (strcmp(t->name, name) == 0) { - int retval = t->select(ctx); - /* select() registers commands specific to this - * transport, and may also reset the link, e.g. - * forcing it to JTAG or SWD mode. - */ - if (retval == ERROR_OK) - session = t; - else - LOG_ERROR("Error selecting '%s' as transport", t->name); - return retval; - } - } - - LOG_ERROR("No transport named '%s' is available.", name); - return ERROR_FAIL; -} - -/** - * Called by debug adapter drivers, or affiliated Tcl config scripts, - * to declare the set of transports supported by an adapter. When - * there is only one member of that set, it is automatically selected. - */ -int allow_transports(struct command_context *ctx, const char * const *vector) -{ - /* NOTE: caller is required to provide only a list - * of *valid* transport names - * - * REVISIT should we validate that? and insist there's - * at least one non-NULL element in that list? - * - * ... allow removals, e.g. external strapping prevents use - * of one transport; C code should be definitive about what - * can be used when all goes well. - */ - if (allowed_transports != NULL || session) { - LOG_ERROR("Can't modify the set of allowed transports."); - return ERROR_FAIL; - } - - allowed_transports = vector; - - /* autoselect if there's no choice ... */ - if (!vector[1]) { - LOG_INFO("only one transport option; autoselect '%s'", vector[0]); - return transport_select(ctx, vector[0]); - } - - return ERROR_OK; -} - -/** - * Used to verify corrrect adapter driver initialization. - * - * @returns true iff the adapter declared one or more transports. - */ -bool transports_are_declared(void) -{ - return allowed_transports != NULL; -} - -/** - * Registers a transport. There are general purpose transports - * (such as JTAG), as well as relatively proprietary ones which are - * specific to a given chip (or chip family). - * - * Code implementing a transport needs to register it before it can - * be selected and then activated. This is a dynamic process, so - * that chips (and families) can define transports as needed (without - * nneeding error-prone static tables). - * - * @param new_transport the transport being registered. On a - * successful return, this memory is owned by the transport framework. - * - * @returns ERROR_OK on success, else a fault code. - */ -int transport_register(struct transport *new_transport) -{ - struct transport *t; - - for (t = transport_list; t; t = t->next) { - if (strcmp(t->name, new_transport->name) == 0) { - LOG_ERROR("transport name already used"); - return ERROR_FAIL; - } - } - - if (!new_transport->select || !new_transport->init) - LOG_ERROR("invalid transport %s", new_transport->name); - - /* splice this into the list */ - new_transport->next = transport_list; - transport_list = new_transport; - LOG_DEBUG("register '%s'", new_transport->name); - - return ERROR_OK; -} - -/** - * Returns the transport currently being used by this debug or - * programming session. - * - * @returns handle to the read-only transport entity. - */ -struct transport *get_current_transport(void) -{ - /* REVISIT -- constify */ - return session; -} - -/*-----------------------------------------------------------------------*/ - -/* - * Infrastructure for Tcl interface to transports. - */ - -/** - * Makes and stores a copy of a set of transports passed as - * parameters to a command. - * - * @param vector where the resulting copy is stored, as an argv-style - * NULL-terminated vector. - */ -COMMAND_HELPER(transport_list_parse, char ***vector) -{ - char **argv; - unsigned n = CMD_ARGC; - unsigned j = 0; - - *vector = NULL; - - if (n < 1) - return ERROR_COMMAND_SYNTAX_ERROR; - - /* our return vector must be NULL terminated */ - argv = calloc(n + 1, sizeof(char *)); - if (argv == NULL) - return ERROR_FAIL; - - for (unsigned i = 0; i < n; i++) { - struct transport *t; - - for (t = transport_list; t; t = t->next) { - if (strcmp(t->name, CMD_ARGV[i]) != 0) - continue; - argv[j++] = strdup(CMD_ARGV[i]); - break; - } - if (!t) { - LOG_ERROR("no such transport '%s'", CMD_ARGV[i]); - goto fail; - } - } - - *vector = argv; - return ERROR_OK; - -fail: - for (unsigned i = 0; i < n; i++) - free(argv[i]); - free(argv); - return ERROR_FAIL; -} - -COMMAND_HANDLER(handle_transport_init) -{ - LOG_DEBUG("%s", __func__); - if (!session) { - LOG_ERROR("session transport was not selected. Use 'transport select '"); - - /* no session transport configured, print transports then fail */ - LOG_ERROR("Transports available:"); - const char * const *vector = allowed_transports; - while (*vector) { - LOG_ERROR("%s", *vector); - vector++; - } - return ERROR_FAIL; - } - - return session->init(CMD_CTX); -} - -COMMAND_HANDLER(handle_transport_list) -{ - if (CMD_ARGC != 0) - return ERROR_COMMAND_SYNTAX_ERROR; - - command_print(CMD_CTX, "The following transports are available:"); - - for (struct transport *t = transport_list; t; t = t->next) - command_print(CMD_CTX, "\t%s", t->name); - - return ERROR_OK; -} - -/** - * Implements the Tcl "transport select" command, choosing the - * transport to be used in this debug session from among the - * set supported by the debug adapter being used. Return value - * is scriptable (allowing "if swd then..." etc). - */ -static int jim_transport_select(Jim_Interp *interp, int argc, Jim_Obj * const *argv) -{ - int res; - switch (argc) { - case 1: /* autoselect if necessary, then return/display current config */ - if (!session) { - if (!allowed_transports) { - LOG_ERROR("Debug adapter does not support any transports? Check config file order."); - return JIM_ERR; - } - LOG_INFO("auto-selecting first available session transport \"%s\". " - "To override use 'transport select '.", allowed_transports[0]); - res = transport_select(global_cmd_ctx, allowed_transports[0]); - if (res != JIM_OK) - return res; - } - Jim_SetResultString(interp, session->name, -1); - return JIM_OK; - break; - case 2: /* assign */ - if (session) { - if (!strcmp(session->name, argv[1]->bytes)) { - LOG_WARNING("Transport \"%s\" was already selected", session->name); - Jim_SetResultString(interp, session->name, -1); - return JIM_OK; - } else { - LOG_ERROR("Can't change session's transport after the initial selection was made"); - return JIM_ERR; - } - } - - /* Is this transport supported by our debug adapter? - * Example, "JTAG-only" means SWD is not supported. - * - * NOTE: requires adapter to have been set up, with - * transports declared via C. - */ - if (!allowed_transports) { - LOG_ERROR("Debug adapter doesn't support any transports?"); - return JIM_ERR; - } - - for (unsigned i = 0; allowed_transports[i]; i++) { - - if (strcmp(allowed_transports[i], argv[1]->bytes) == 0) { - if (transport_select(global_cmd_ctx, argv[1]->bytes) == ERROR_OK) { - Jim_SetResultString(interp, session->name, -1); - return JIM_OK; - } - return JIM_ERR; - } - } - - LOG_ERROR("Debug adapter doesn't support '%s' transport", argv[1]->bytes); - return JIM_ERR; - break; - default: - Jim_WrongNumArgs(interp, 1, argv, "[too many parameters]"); - return JIM_ERR; - } -} - -static const struct command_registration transport_commands[] = { - { - .name = "init", - .handler = handle_transport_init, - /* this would be COMMAND_CONFIG ... except that - * it needs to trigger event handlers that may - * require COMMAND_EXEC ... - */ - .mode = COMMAND_ANY, - .help = "Initialize this session's transport", - .usage = "" - }, - { - .name = "list", - .handler = handle_transport_list, - .mode = COMMAND_ANY, - .help = "list all built-in transports", - .usage = "" - }, - { - .name = "select", - .jim_handler = jim_transport_select, - .mode = COMMAND_ANY, - .help = "Select this session's transport", - .usage = "[transport_name]", - }, - COMMAND_REGISTRATION_DONE -}; - -static const struct command_registration transport_group[] = { - { - .name = "transport", - .mode = COMMAND_ANY, - .help = "Transport command group", - .chain = transport_commands, - .usage = "" - }, - COMMAND_REGISTRATION_DONE -}; - -int transport_register_commands(struct command_context *ctx) -{ - return register_commands(ctx, NULL, transport_group); -} diff --git a/src/transport/transport.h b/src/transport/transport.h deleted file mode 100644 index 6c57067a3..000000000 --- a/src/transport/transport.h +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright (c) 2010 by David Brownell - * Copyright (C) 2011 Tomasz Boleslaw CEDRO (http://www.tomek.cedro.info) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef OPENOCD_TRANSPORT_TRANSPORT_H -#define OPENOCD_TRANSPORT_TRANSPORT_H - -#include "helper/command.h" - -/** - * Wrapper for transport lifecycle operations. - * - * OpenOCD talks to targets through some kind of debugging - * or programming adapter, using some protocol that probably - * has target-specific aspects. - * - * A "transport" reflects electrical protocol to the target, - * e..g jtag, swd, spi, uart, ... NOT the messaging protocols - * layered over it (e.g. JTAG has eICE, CoreSight, Nexus, OnCE, - * and more). - * - * In addition to the lifecycle operations packaged by this - * structure, a transport also involves an interface supported - * by debug adapters and used by components such as debug targets. - * For non-debug transports, there may be interfaces used to - * write to flash chips. - */ -struct transport { - /** - * Each transport has a unique name, used to select it - * from among the alternatives. Examples might include - * "jtag", * "swd", "AVR_ISP" and more. - */ - const char *name; - - /** - * When a transport is selected, this method registers - * its commands and activates the transport (e.g. resets - * the link). - * - * After those commands are registered, they will often - * be used for further configuration of the debug link. - */ - int (*select)(struct command_context *ctx); - - /** - * server startup uses this method to validate transport - * configuration. (For example, with JTAG this interrogates - * the scan chain against the list of expected TAPs.) - */ - int (*init)(struct command_context *ctx); - - /** - * Optional. If defined, allows transport to override target - * name prior to initialisation. - * - * @returns ERROR_OK on success, or an error code on failure. - */ - int (*override_target)(const char **targetname); - - /** - * Transports are stored in a singly linked list. - */ - struct transport *next; -}; - -int transport_register(struct transport *new_transport); - -struct transport *get_current_transport(void); - -int transport_register_commands(struct command_context *ctx); - -COMMAND_HELPER(transport_list_parse, char ***vector); - -int allow_transports(struct command_context *ctx, const char * const *vector); - -bool transports_are_declared(void); - -#endif /* OPENOCD_TRANSPORT_TRANSPORT_H */ diff --git a/src/xsvf/Makefile.am b/src/xsvf/Makefile.am deleted file mode 100644 index 1b9cfab00..000000000 --- a/src/xsvf/Makefile.am +++ /dev/null @@ -1,8 +0,0 @@ -include $(top_srcdir)/common.mk - -METASOURCES = AUTO -noinst_LTLIBRARIES = libxsvf.la -noinst_HEADERS = xsvf.h -libxsvf_la_SOURCES = xsvf.c - -MAINTAINERCLEANFILES = $(srcdir)/Makefile.in diff --git a/src/xsvf/xsvf.c b/src/xsvf/xsvf.c deleted file mode 100644 index 63c891511..000000000 --- a/src/xsvf/xsvf.c +++ /dev/null @@ -1,1113 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * Copyright (C) 2007,2008 Øyvind Harboe * - * oyvind.harboe@zylin.com * - * * - * Copyright (C) 2008 Peter Hettkamp * - * peter.hettkamp@htp-tel.de * - * * - * Copyright (C) 2009 SoftPLC Corporation. http://softplc.com * - * Dick Hollenbeck * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -/* The specification for SVF is available here: - * http://www.asset-intertech.com/support/svf.pdf - * Below, this document is refered to as the "SVF spec". - * - * The specification for XSVF is available here: - * http://www.xilinx.com/support/documentation/application_notes/xapp503.pdf - * Below, this document is refered to as the "XSVF spec". - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "xsvf.h" -#include -#include - -/* XSVF commands, from appendix B of xapp503.pdf */ -#define XCOMPLETE 0x00 -#define XTDOMASK 0x01 -#define XSIR 0x02 -#define XSDR 0x03 -#define XRUNTEST 0x04 -#define XREPEAT 0x07 -#define XSDRSIZE 0x08 -#define XSDRTDO 0x09 -#define XSETSDRMASKS 0x0A -#define XSDRINC 0x0B -#define XSDRB 0x0C -#define XSDRC 0x0D -#define XSDRE 0x0E -#define XSDRTDOB 0x0F -#define XSDRTDOC 0x10 -#define XSDRTDOE 0x11 -#define XSTATE 0x12 -#define XENDIR 0x13 -#define XENDDR 0x14 -#define XSIR2 0x15 -#define XCOMMENT 0x16 -#define XWAIT 0x17 - -/* XWAITSTATE is not in the xilinx XSVF spec, but the svf2xsvf.py translator - * generates this. Arguably it is needed because the XSVF XRUNTEST command - * was ill conceived and does not directly flow out of the SVF RUNTEST command. - * This XWAITSTATE does map directly from the SVF RUNTEST command. - */ -#define XWAITSTATE 0x18 - -/* Lattice has extended the SVF file format, and Dick Hollenbeck's python based - * SVF2XSVF converter supports these 3 additional XSVF opcodes, LCOUNT, LDELAY, LSDR. - * Here is an example of usage of the 3 lattice opcode extensions: - -! Set the maximum loop count to 25. -LCOUNT 25; -! Step to DRPAUSE give 5 clocks and wait for 1.00e + 000 SEC. -LDELAY DRPAUSE 5 TCK 1.00E-003 SEC; -! Test for the completed status. Match means pass. -! Loop back to LDELAY line if not match and loop count less than 25. - -LSDR 1 TDI (0) -TDO (1); -*/ - -#define LCOUNT 0x19 -#define LDELAY 0x1A -#define LSDR 0x1B -#define XTRST 0x1C - -/* XSVF valid state values for the XSTATE command, from appendix B of xapp503.pdf */ -#define XSV_RESET 0x00 -#define XSV_IDLE 0x01 -#define XSV_DRSELECT 0x02 -#define XSV_DRCAPTURE 0x03 -#define XSV_DRSHIFT 0x04 -#define XSV_DREXIT1 0x05 -#define XSV_DRPAUSE 0x06 -#define XSV_DREXIT2 0x07 -#define XSV_DRUPDATE 0x08 -#define XSV_IRSELECT 0x09 -#define XSV_IRCAPTURE 0x0A -#define XSV_IRSHIFT 0x0B -#define XSV_IREXIT1 0x0C -#define XSV_IRPAUSE 0x0D -#define XSV_IREXIT2 0x0E -#define XSV_IRUPDATE 0x0F - -/* arguments to XTRST */ -#define XTRST_ON 0 -#define XTRST_OFF 1 -#define XTRST_Z 2 -#define XTRST_ABSENT 3 - -#define XSTATE_MAX_PATH 12 - -static int xsvf_fd; - -/* map xsvf tap state to an openocd "tap_state_t" */ -static tap_state_t xsvf_to_tap(int xsvf_state) -{ - tap_state_t ret; - - switch (xsvf_state) { - case XSV_RESET: - ret = TAP_RESET; - break; - case XSV_IDLE: - ret = TAP_IDLE; - break; - case XSV_DRSELECT: - ret = TAP_DRSELECT; - break; - case XSV_DRCAPTURE: - ret = TAP_DRCAPTURE; - break; - case XSV_DRSHIFT: - ret = TAP_DRSHIFT; - break; - case XSV_DREXIT1: - ret = TAP_DREXIT1; - break; - case XSV_DRPAUSE: - ret = TAP_DRPAUSE; - break; - case XSV_DREXIT2: - ret = TAP_DREXIT2; - break; - case XSV_DRUPDATE: - ret = TAP_DRUPDATE; - break; - case XSV_IRSELECT: - ret = TAP_IRSELECT; - break; - case XSV_IRCAPTURE: - ret = TAP_IRCAPTURE; - break; - case XSV_IRSHIFT: - ret = TAP_IRSHIFT; - break; - case XSV_IREXIT1: - ret = TAP_IREXIT1; - break; - case XSV_IRPAUSE: - ret = TAP_IRPAUSE; - break; - case XSV_IREXIT2: - ret = TAP_IREXIT2; - break; - case XSV_IRUPDATE: - ret = TAP_IRUPDATE; - break; - default: - LOG_ERROR("UNKNOWN XSVF STATE 0x%02X", xsvf_state); - exit(1); - } - - return ret; -} - -static int xsvf_read_buffer(int num_bits, int fd, uint8_t *buf) -{ - int num_bytes; - - for (num_bytes = (num_bits + 7) / 8; num_bytes > 0; num_bytes--) { - /* reverse the order of bytes as they are read sequentially from file */ - if (read(fd, buf + num_bytes - 1, 1) < 0) - return ERROR_XSVF_EOF; - } - - return ERROR_OK; -} - -COMMAND_HANDLER(handle_xsvf_command) -{ - uint8_t *dr_out_buf = NULL; /* from host to device (TDI) */ - uint8_t *dr_in_buf = NULL; /* from device to host (TDO) */ - uint8_t *dr_in_mask = NULL; - - int xsdrsize = 0; - int xruntest = 0; /* number of TCK cycles OR *microseconds */ - int xrepeat = 0; /* number of retries */ - - tap_state_t xendir = TAP_IDLE; /* see page 8 of the SVF spec, initial - *xendir to be TAP_IDLE */ - tap_state_t xenddr = TAP_IDLE; - - uint8_t opcode; - uint8_t uc = 0; - long file_offset = 0; - - int loop_count = 0; - tap_state_t loop_state = TAP_IDLE; - int loop_clocks = 0; - int loop_usecs = 0; - - int do_abort = 0; - int unsupported = 0; - int tdo_mismatch = 0; - int result; - int verbose = 1; - - bool collecting_path = false; - tap_state_t path[XSTATE_MAX_PATH]; - unsigned pathlen = 0; - - /* a flag telling whether to clock TCK during waits, - * or simply sleep, controled by virt2 - */ - int runtest_requires_tck = 0; - - /* use NULL to indicate a "plain" xsvf file which accounts for - * additional devices in the scan chain, otherwise the device - * that should be affected - */ - struct jtag_tap *tap = NULL; - - if (CMD_ARGC < 2) - return ERROR_COMMAND_SYNTAX_ERROR; - - /* we mess with CMD_ARGV starting point below, snapshot filename here */ - const char *filename = CMD_ARGV[1]; - - if (strcmp(CMD_ARGV[0], "plain") != 0) { - tap = jtag_tap_by_string(CMD_ARGV[0]); - if (!tap) { - command_print(CMD_CTX, "Tap: %s unknown", CMD_ARGV[0]); - return ERROR_FAIL; - } - } - - xsvf_fd = open(filename, O_RDONLY); - if (xsvf_fd < 0) { - command_print(CMD_CTX, "file \"%s\" not found", filename); - return ERROR_FAIL; - } - - /* if this argument is present, then interpret xruntest counts as TCK cycles rather than as - *usecs */ - if ((CMD_ARGC > 2) && (strcmp(CMD_ARGV[2], "virt2") == 0)) { - runtest_requires_tck = 1; - --CMD_ARGC; - ++CMD_ARGV; - } - - if ((CMD_ARGC > 2) && (strcmp(CMD_ARGV[2], "quiet") == 0)) - verbose = 0; - - LOG_WARNING("XSVF support in OpenOCD is limited. Consider using SVF instead"); - LOG_USER("xsvf processing file: \"%s\"", filename); - - while (read(xsvf_fd, &opcode, 1) > 0) { - /* record the position of this opcode within the file */ - file_offset = lseek(xsvf_fd, 0, SEEK_CUR) - 1; - - /* maybe collect another state for a pathmove(); - * or terminate a path. - */ - if (collecting_path) { - tap_state_t mystate; - - switch (opcode) { - case XCOMMENT: - /* ignore/show comments between XSTATE ops */ - break; - case XSTATE: - /* try to collect another transition */ - if (pathlen == XSTATE_MAX_PATH) { - LOG_ERROR("XSVF: path too long"); - do_abort = 1; - break; - } - - if (read(xsvf_fd, &uc, 1) < 0) { - do_abort = 1; - break; - } - - mystate = xsvf_to_tap(uc); - path[pathlen++] = mystate; - - LOG_DEBUG("XSTATE 0x%02X %s", uc, - tap_state_name(mystate)); - - /* If path is incomplete, collect more */ - if (!svf_tap_state_is_stable(mystate)) - continue; - - /* Else execute the path transitions we've - * collected so far. - * - * NOTE: Punting on the saved path is not - * strictly correct, but we must to do this - * unless jtag_add_pathmove() stops rejecting - * paths containing RESET. This is probably - * harmless, since there aren't many options - * for going from a stable state to reset; - * at the worst, we may issue extra clocks - * once we get to RESET. - */ - if (mystate == TAP_RESET) { - LOG_WARNING("XSVF: dodgey RESET"); - path[0] = mystate; - } - - /* FALL THROUGH */ - default: - /* Execute the path we collected - * - * NOTE: OpenOCD requires something that XSVF - * doesn't: the last TAP state in the path - * must be stable. In practice, tools that - * create XSVF seem to follow that rule too. - */ - collecting_path = false; - - if (path[0] == TAP_RESET) - jtag_add_tlr(); - else - jtag_add_pathmove(pathlen, path); - - result = jtag_execute_queue(); - if (result != ERROR_OK) { - LOG_ERROR("XSVF: pathmove error %d", result); - do_abort = 1; - break; - } - continue; - } - } - - switch (opcode) { - case XCOMPLETE: - LOG_DEBUG("XCOMPLETE"); - - result = jtag_execute_queue(); - if (result != ERROR_OK) { - tdo_mismatch = 1; - break; - } - break; - - case XTDOMASK: - LOG_DEBUG("XTDOMASK"); - if (dr_in_mask && - (xsvf_read_buffer(xsdrsize, xsvf_fd, dr_in_mask) != ERROR_OK)) - do_abort = 1; - break; - - case XRUNTEST: - { - uint8_t xruntest_buf[4]; - - if (read(xsvf_fd, xruntest_buf, 4) < 0) { - do_abort = 1; - break; - } - - xruntest = be_to_h_u32(xruntest_buf); - LOG_DEBUG("XRUNTEST %d 0x%08X", xruntest, xruntest); - } - break; - - case XREPEAT: - { - uint8_t myrepeat; - - if (read(xsvf_fd, &myrepeat, 1) < 0) - do_abort = 1; - else { - xrepeat = myrepeat; - LOG_DEBUG("XREPEAT %d", xrepeat); - } - } - break; - - case XSDRSIZE: - { - uint8_t xsdrsize_buf[4]; - - if (read(xsvf_fd, xsdrsize_buf, 4) < 0) { - do_abort = 1; - break; - } - - xsdrsize = be_to_h_u32(xsdrsize_buf); - LOG_DEBUG("XSDRSIZE %d", xsdrsize); - - if (dr_out_buf) - free(dr_out_buf); - if (dr_in_buf) - free(dr_in_buf); - if (dr_in_mask) - free(dr_in_mask); - - dr_out_buf = malloc((xsdrsize + 7) / 8); - dr_in_buf = malloc((xsdrsize + 7) / 8); - dr_in_mask = malloc((xsdrsize + 7) / 8); - } - break; - - case XSDR: /* these two are identical except for the dr_in_buf */ - case XSDRTDO: - { - int limit = xrepeat; - int matched = 0; - int attempt; - - const char *op_name = (opcode == XSDR ? "XSDR" : "XSDRTDO"); - - if (xsvf_read_buffer(xsdrsize, xsvf_fd, dr_out_buf) != ERROR_OK) { - do_abort = 1; - break; - } - - if (opcode == XSDRTDO) { - if (xsvf_read_buffer(xsdrsize, xsvf_fd, - dr_in_buf) != ERROR_OK) { - do_abort = 1; - break; - } - } - - if (limit < 1) - limit = 1; - - LOG_DEBUG("%s %d", op_name, xsdrsize); - - for (attempt = 0; attempt < limit; ++attempt) { - struct scan_field field; - - if (attempt > 0) { - /* perform the XC9500 exception handling sequence shown in xapp067.pdf and - * illustrated in psuedo code at end of this file. We start from state - * DRPAUSE: - * go to Exit2-DR - * go to Shift-DR - * go to Exit1-DR - * go to Update-DR - * go to Run-Test/Idle - * - * This sequence should be harmless for other devices, and it - * will be skipped entirely if xrepeat is set to zero. - */ - - static tap_state_t exception_path[] = { - TAP_DREXIT2, - TAP_DRSHIFT, - TAP_DREXIT1, - TAP_DRUPDATE, - TAP_IDLE, - }; - - jtag_add_pathmove(ARRAY_SIZE(exception_path), exception_path); - - if (verbose) - LOG_USER("%s mismatch, xsdrsize=%d retry=%d", - op_name, - xsdrsize, - attempt); - } - - field.num_bits = xsdrsize; - field.out_value = dr_out_buf; - field.in_value = calloc(DIV_ROUND_UP(field.num_bits, 8), 1); - - if (tap == NULL) - jtag_add_plain_dr_scan(field.num_bits, - field.out_value, - field.in_value, - TAP_DRPAUSE); - else - jtag_add_dr_scan(tap, 1, &field, TAP_DRPAUSE); - - jtag_check_value_mask(&field, dr_in_buf, dr_in_mask); - - free(field.in_value); - - /* LOG_DEBUG("FLUSHING QUEUE"); */ - result = jtag_execute_queue(); - if (result == ERROR_OK) { - matched = 1; - break; - } - } - - if (!matched) { - LOG_USER("%s mismatch", op_name); - tdo_mismatch = 1; - break; - } - - /* See page 19 of XSVF spec regarding opcode "XSDR" */ - if (xruntest) { - result = svf_add_statemove(TAP_IDLE); - if (result != ERROR_OK) - return result; - - if (runtest_requires_tck) - jtag_add_clocks(xruntest); - else - jtag_add_sleep(xruntest); - } else if (xendir != TAP_DRPAUSE) { - /* we are already in TAP_DRPAUSE */ - result = svf_add_statemove(xenddr); - if (result != ERROR_OK) - return result; - } - } - break; - - case XSETSDRMASKS: - LOG_ERROR("unsupported XSETSDRMASKS"); - unsupported = 1; - break; - - case XSDRINC: - LOG_ERROR("unsupported XSDRINC"); - unsupported = 1; - break; - - case XSDRB: - LOG_ERROR("unsupported XSDRB"); - unsupported = 1; - break; - - case XSDRC: - LOG_ERROR("unsupported XSDRC"); - unsupported = 1; - break; - - case XSDRE: - LOG_ERROR("unsupported XSDRE"); - unsupported = 1; - break; - - case XSDRTDOB: - LOG_ERROR("unsupported XSDRTDOB"); - unsupported = 1; - break; - - case XSDRTDOC: - LOG_ERROR("unsupported XSDRTDOC"); - unsupported = 1; - break; - - case XSDRTDOE: - LOG_ERROR("unsupported XSDRTDOE"); - unsupported = 1; - break; - - case XSTATE: - { - tap_state_t mystate; - - if (read(xsvf_fd, &uc, 1) < 0) { - do_abort = 1; - break; - } - - mystate = xsvf_to_tap(uc); - - LOG_DEBUG("XSTATE 0x%02X %s", uc, tap_state_name(mystate)); - - if (mystate == TAP_INVALID) { - LOG_ERROR("XSVF: bad XSTATE %02x", uc); - do_abort = 1; - break; - } - - /* NOTE: the current state is SVF-stable! */ - - /* no change == NOP */ - if (mystate == cmd_queue_cur_state - && mystate != TAP_RESET) - break; - - /* Hand off to SVF? */ - if (svf_tap_state_is_stable(mystate)) { - result = svf_add_statemove(mystate); - if (result != ERROR_OK) - unsupported = 1; - break; - } - - /* - * A sequence of XSTATE transitions, each TAP - * state adjacent to the previous one. Start - * collecting them. - */ - collecting_path = true; - pathlen = 1; - path[0] = mystate; - } - break; - - case XENDIR: - - if (read(xsvf_fd, &uc, 1) < 0) { - do_abort = 1; - break; - } - - /* see page 22 of XSVF spec */ - if (uc == 0) - xendir = TAP_IDLE; - else if (uc == 1) - xendir = TAP_IRPAUSE; - else { - LOG_ERROR("illegial XENDIR argument: 0x%02X", uc); - unsupported = 1; - break; - } - - LOG_DEBUG("XENDIR 0x%02X %s", uc, tap_state_name(xendir)); - break; - - case XENDDR: - - if (read(xsvf_fd, &uc, 1) < 0) { - do_abort = 1; - break; - } - - /* see page 22 of XSVF spec */ - if (uc == 0) - xenddr = TAP_IDLE; - else if (uc == 1) - xenddr = TAP_DRPAUSE; - else { - LOG_ERROR("illegial XENDDR argument: 0x%02X", uc); - unsupported = 1; - break; - } - - LOG_DEBUG("XENDDR %02X %s", uc, tap_state_name(xenddr)); - break; - - case XSIR: - case XSIR2: - { - uint8_t short_buf[2]; - uint8_t *ir_buf; - int bitcount; - tap_state_t my_end_state = xruntest ? TAP_IDLE : xendir; - - if (opcode == XSIR) { - /* one byte bitcount */ - if (read(xsvf_fd, short_buf, 1) < 0) { - do_abort = 1; - break; - } - bitcount = short_buf[0]; - LOG_DEBUG("XSIR %d", bitcount); - } else { - if (read(xsvf_fd, short_buf, 2) < 0) { - do_abort = 1; - break; - } - bitcount = be_to_h_u16(short_buf); - LOG_DEBUG("XSIR2 %d", bitcount); - } - - ir_buf = malloc((bitcount + 7) / 8); - - if (xsvf_read_buffer(bitcount, xsvf_fd, ir_buf) != ERROR_OK) - do_abort = 1; - else { - struct scan_field field; - - field.num_bits = bitcount; - field.out_value = ir_buf; - - field.in_value = NULL; - - if (tap == NULL) - jtag_add_plain_ir_scan(field.num_bits, - field.out_value, field.in_value, my_end_state); - else - jtag_add_ir_scan(tap, &field, my_end_state); - - if (xruntest) { - if (runtest_requires_tck) - jtag_add_clocks(xruntest); - else - jtag_add_sleep(xruntest); - } - - /* Note that an -irmask of non-zero in your config file - * can cause this to fail. Setting -irmask to zero cand work - * around the problem. - */ - - /* LOG_DEBUG("FLUSHING QUEUE"); */ - result = jtag_execute_queue(); - if (result != ERROR_OK) - tdo_mismatch = 1; - } - free(ir_buf); - } - break; - - case XCOMMENT: - { - unsigned int ndx = 0; - char comment[128]; - - do { - if (read(xsvf_fd, &uc, 1) < 0) { - do_abort = 1; - break; - } - - if (ndx < sizeof(comment)-1) - comment[ndx++] = uc; - - } while (uc != 0); - - comment[sizeof(comment)-1] = 0; /* regardless, terminate */ - if (verbose) - LOG_USER("# %s", comment); - } - break; - - case XWAIT: - { - /* expected in stream: - XWAIT - */ - - uint8_t wait_local; - uint8_t end; - uint8_t delay_buf[4]; - - tap_state_t wait_state; - tap_state_t end_state; - int delay; - - if (read(xsvf_fd, &wait_local, 1) < 0 - || read(xsvf_fd, &end, 1) < 0 - || read(xsvf_fd, delay_buf, 4) < 0) { - do_abort = 1; - break; - } - - wait_state = xsvf_to_tap(wait_local); - end_state = xsvf_to_tap(end); - delay = be_to_h_u32(delay_buf); - - LOG_DEBUG("XWAIT %s %s usecs:%d", tap_state_name( - wait_state), tap_state_name(end_state), delay); - - if (runtest_requires_tck && wait_state == TAP_IDLE) - jtag_add_runtest(delay, end_state); - else { - /* FIXME handle statemove errors ... */ - result = svf_add_statemove(wait_state); - if (result != ERROR_OK) - return result; - jtag_add_sleep(delay); - result = svf_add_statemove(end_state); - if (result != ERROR_OK) - return result; - } - } - break; - - case XWAITSTATE: - { - /* expected in stream: - * XWAITSTATE - * - */ - - uint8_t clock_buf[4]; - uint8_t usecs_buf[4]; - uint8_t wait_local; - uint8_t end; - tap_state_t wait_state; - tap_state_t end_state; - int clock_count; - int usecs; - - if (read(xsvf_fd, &wait_local, 1) < 0 - || read(xsvf_fd, &end, 1) < 0 - || read(xsvf_fd, clock_buf, 4) < 0 - || read(xsvf_fd, usecs_buf, 4) < 0) { - do_abort = 1; - break; - } - - wait_state = xsvf_to_tap(wait_local); - end_state = xsvf_to_tap(end); - - clock_count = be_to_h_u32(clock_buf); - usecs = be_to_h_u32(usecs_buf); - - LOG_DEBUG("XWAITSTATE %s %s clocks:%i usecs:%i", - tap_state_name(wait_state), - tap_state_name(end_state), - clock_count, usecs); - - /* the following states are 'stable', meaning that they have a transition - * in the state diagram back to themselves. This is necessary because we will - * be issuing a number of clocks in this state. This set of allowed states is also - * determined by the SVF RUNTEST command's allowed states. - */ - if (!svf_tap_state_is_stable(wait_state)) { - LOG_ERROR("illegal XWAITSTATE wait_state: \"%s\"", - tap_state_name(wait_state)); - unsupported = 1; - /* REVISIT "break" so we won't run? */ - } - - /* FIXME handle statemove errors ... */ - result = svf_add_statemove(wait_state); - if (result != ERROR_OK) - return result; - - jtag_add_clocks(clock_count); - jtag_add_sleep(usecs); - - result = svf_add_statemove(end_state); - if (result != ERROR_OK) - return result; - } - break; - - case LCOUNT: - { - /* expected in stream: - * LCOUNT - */ - uint8_t count_buf[4]; - - if (read(xsvf_fd, count_buf, 4) < 0) { - do_abort = 1; - break; - } - - loop_count = be_to_h_u32(count_buf); - LOG_DEBUG("LCOUNT %d", loop_count); - } - break; - - case LDELAY: - { - /* expected in stream: - * LDELAY - */ - uint8_t state; - uint8_t clock_buf[4]; - uint8_t usecs_buf[4]; - - if (read(xsvf_fd, &state, 1) < 0 - || read(xsvf_fd, clock_buf, 4) < 0 - || read(xsvf_fd, usecs_buf, 4) < 0) { - do_abort = 1; - break; - } - - /* NOTE: loop_state must be stable! */ - loop_state = xsvf_to_tap(state); - loop_clocks = be_to_h_u32(clock_buf); - loop_usecs = be_to_h_u32(usecs_buf); - - LOG_DEBUG("LDELAY %s clocks:%d usecs:%d", tap_state_name( - loop_state), loop_clocks, loop_usecs); - } - break; - - /* LSDR is more like XSDRTDO than it is like XSDR. It uses LDELAY which - * comes with clocks !AND! sleep requirements. - */ - case LSDR: - { - int limit = loop_count; - int matched = 0; - int attempt; - - LOG_DEBUG("LSDR"); - - if (xsvf_read_buffer(xsdrsize, xsvf_fd, dr_out_buf) != ERROR_OK - || xsvf_read_buffer(xsdrsize, xsvf_fd, dr_in_buf) != ERROR_OK) { - do_abort = 1; - break; - } - - if (limit < 1) - limit = 1; - - for (attempt = 0; attempt < limit; ++attempt) { - struct scan_field field; - - result = svf_add_statemove(loop_state); - if (result != ERROR_OK) - return result; - jtag_add_clocks(loop_clocks); - jtag_add_sleep(loop_usecs); - - field.num_bits = xsdrsize; - field.out_value = dr_out_buf; - field.in_value = calloc(DIV_ROUND_UP(field.num_bits, 8), 1); - - if (attempt > 0 && verbose) - LOG_USER("LSDR retry %d", attempt); - - if (tap == NULL) - jtag_add_plain_dr_scan(field.num_bits, - field.out_value, - field.in_value, - TAP_DRPAUSE); - else - jtag_add_dr_scan(tap, 1, &field, TAP_DRPAUSE); - - jtag_check_value_mask(&field, dr_in_buf, dr_in_mask); - - free(field.in_value); - - - /* LOG_DEBUG("FLUSHING QUEUE"); */ - result = jtag_execute_queue(); - if (result == ERROR_OK) { - matched = 1; - break; - } - } - - if (!matched) { - LOG_USER("LSDR mismatch"); - tdo_mismatch = 1; - break; - } - } - break; - - case XTRST: - { - uint8_t trst_mode; - - if (read(xsvf_fd, &trst_mode, 1) < 0) { - do_abort = 1; - break; - } - - switch (trst_mode) { - case XTRST_ON: - jtag_add_reset(1, 0); - break; - case XTRST_OFF: - case XTRST_Z: - jtag_add_reset(0, 0); - break; - case XTRST_ABSENT: - break; - default: - LOG_ERROR("XTRST mode argument (0x%02X) out of range", trst_mode); - do_abort = 1; - } - } - break; - - default: - LOG_ERROR("unknown xsvf command (0x%02X)", uc); - unsupported = 1; - } - - if (do_abort || unsupported || tdo_mismatch) { - LOG_DEBUG("xsvf failed, setting taps to reasonable state"); - - /* upon error, return the TAPs to a reasonable state */ - result = svf_add_statemove(TAP_IDLE); - if (result != ERROR_OK) - return result; - result = jtag_execute_queue(); - if (result != ERROR_OK) - return result; - break; - } - } - - if (tdo_mismatch) { - command_print(CMD_CTX, - "TDO mismatch, somewhere near offset %lu in xsvf file, aborting", - file_offset); - - return ERROR_FAIL; - } - - if (unsupported) { - off_t offset = lseek(xsvf_fd, 0, SEEK_CUR) - 1; - command_print(CMD_CTX, - "unsupported xsvf command (0x%02X) at offset %jd, aborting", - uc, (intmax_t)offset); - return ERROR_FAIL; - } - - if (do_abort) { - command_print(CMD_CTX, "premature end of xsvf file detected, aborting"); - return ERROR_FAIL; - } - - if (dr_out_buf) - free(dr_out_buf); - - if (dr_in_buf) - free(dr_in_buf); - - if (dr_in_mask) - free(dr_in_mask); - - close(xsvf_fd); - - command_print(CMD_CTX, "XSVF file programmed successfully"); - - return ERROR_OK; -} - -static const struct command_registration xsvf_command_handlers[] = { - { - .name = "xsvf", - .handler = handle_xsvf_command, - .mode = COMMAND_EXEC, - .help = "Runs a XSVF file. If 'virt2' is given, xruntest " - "counts are interpreted as TCK cycles rather than " - "as microseconds. Without the 'quiet' option, all " - "comments, retries, and mismatches will be reported.", - .usage = "(tapname|'plain') filename ['virt2'] ['quiet']", - }, - COMMAND_REGISTRATION_DONE -}; - -int xsvf_register_commands(struct command_context *cmd_ctx) -{ - return register_commands(cmd_ctx, NULL, xsvf_command_handlers); -} - -/* - -PSUEDO-Code from Xilinx Appnote XAPP067.pdf : - -the following pseudo code clarifies the intent of the xrepeat support.The -flow given is for the entire processing of an SVF file, not an XSVF file. -No idea if this is just for the XC9500/XL/XV devices or all Xilinx parts. - -"Pseudo-Code Algorithm for SVF-Based ISP" - -1. Go to Test-Logic-Reset state -2. Go to Run-Test Idle state -3. Read SVF record - -4. if SIR record then -go to Shift-IR state -Scan in - -5. else if SDR record then -set to 0 -store as -store as -6. go to Shift-DR state -scan in -if < current TDO value > is specified then -if < current TDO value > does not equal then -if < repeat count > > 32 then -LOG ERROR -go to Run-Test Idle state -go to Step 3 -end if -go to Pause-DR -go to Exit2-DR -go to Shift-DR -go to Exit1-DR -go to Update-DR -go to Run-Test/Idle -increment by 1 -pause microseconds -go to Step 6) -end if -else - go to Run-Test Idle state - go to Step 3 - endif - else if RUNTEST record then - pause tester for < TCK value > microseconds - store as - end if - -*/ diff --git a/src/xsvf/xsvf.h b/src/xsvf/xsvf.h deleted file mode 100644 index aa0f4f040..000000000 --- a/src/xsvf/xsvf.h +++ /dev/null @@ -1,29 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005 by Dominic Rath * - * Dominic.Rath@gmx.de * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifndef OPENOCD_XSVF_XSVF_H -#define OPENOCD_XSVF_XSVF_H - -#include - -int xsvf_register_commands(struct command_context *cmd_ctx); - -#define ERROR_XSVF_EOF (-200) -#define ERROR_XSVF_FAILED (-201) - -#endif /* OPENOCD_XSVF_XSVF_H */ diff --git a/tcl/bitsbytes.tcl b/tcl/bitsbytes.tcl deleted file mode 100644 index 2c4fd2907..000000000 --- a/tcl/bitsbytes.tcl +++ /dev/null @@ -1,61 +0,0 @@ -#---------------------------------------- -# Purpose - Create some $BIT variables -# Create $K and $M variables -# and some bit field extraction variables. -# Creat helper variables ... -# BIT0.. BIT31 - -for { set x 0 } { $x < 32 } { set x [expr $x + 1]} { - set vn [format "BIT%d" $x] - global $vn - set $vn [expr (1 << $x)] -} - -# Create K bytes values -# __1K ... to __2048K -for { set x 1 } { $x < 2048 } { set x [expr $x * 2]} { - set vn [format "__%dK" $x] - global $vn - set $vn [expr (1024 * $x)] -} - -# Create M bytes values -# __1M ... to __2048K -for { set x 1 } { $x < 2048 } { set x [expr $x * 2]} { - set vn [format "__%dM" $x] - global $vn - set $vn [expr (1024 * 1024 * $x)] -} - -proc create_mask { MSB LSB } { - return [expr (((1 << ($MSB - $LSB + 1))-1) << $LSB)] -} - -# Cut Bits $MSB to $LSB out of this value. -# Example: % format "0x%08x" [extract_bitfield 0x12345678 27 16] -# Result: 0x02340000 - -proc extract_bitfield { VALUE MSB LSB } { - return [expr [create_mask $MSB $LSB] & $VALUE] -} - - -# Cut bits $MSB to $LSB out of this value -# and shift (normalize) them down to bit 0. -# -# Example: % format "0x%08x" [normalize_bitfield 0x12345678 27 16] -# Result: 0x00000234 -# -proc normalize_bitfield { VALUE MSB LSB } { - return [expr [extract_bitfield $VALUE $MSB $LSB ] >> $LSB] -} - -proc show_normalize_bitfield { VALUE MSB LSB } { - set m [create_mask $MSB $LSB] - set mr [expr $VALUE & $m] - set sr [expr $mr >> $LSB] - echo [format "((0x%08x & 0x%08x) -> 0x%08x) >> %2d => (0x%x) %5d " $VALUE $m $mr $LSB $sr $sr] - return $sr -} - - diff --git a/tcl/board/actux3.cfg b/tcl/board/actux3.cfg deleted file mode 100644 index 5435ff885..000000000 --- a/tcl/board/actux3.cfg +++ /dev/null @@ -1,69 +0,0 @@ -# board config file for AcTux3/XBA IXP42x board -# Date: 2010-12-16 -# Author: Michael Schwingen - -reset_config trst_and_srst separate - -adapter_nsrst_delay 100 -jtag_ntrst_delay 100 - -source [find target/ixp42x.cfg] - -$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size 0x10000 -work-area-backup 0 - -$_TARGETNAME configure -event reset-init { init_actux3 } - -proc init_actux3 { } { - ########################################################################## - # setup expansion bus CS - ########################################################################## - mww 0xc4000000 0xbd113842 ;#CS0 : Flash, write enabled @0x50000000 - mww 0xc4000004 0x94d10013 ;#CS1 - mww 0xc4000008 0x95960003 ;#CS2 - mww 0xc400000c 0x00000000 ;#CS3 - mww 0xc4000010 0x80900003 ;#CS4 - mww 0xc4000014 0x9d520003 ;#CS5 - mww 0xc4000018 0x81860001 ;#CS6 - mww 0xc400001c 0x80900003 ;#CS7 - - ixp42x_init_sdram $::IXP42x_SDRAM_16MB_4Mx16_1BANK 2100 3 - - #mww 0xc4000020 0xffffee ;# CFG0: remove expansion bus boot flash mirror at 0x00000000 - - ixp42x_set_bigendian - - flash probe 0 -} - -proc flash_boot { {FILE "/tftpboot/actux3/u-boot.bin"} } { - echo "writing bootloader: $FILE" - flash write_image erase $FILE 0x50000000 bin -} - -set _FLASHNAME $_CHIPNAME.flash -flash bank $_FLASHNAME cfi 0x50000000 0x400000 2 2 $_TARGETNAME - -init -reset init - -# setup to debug u-boot in flash -proc uboot_debug {} { - gdb_breakpoint_override hard - xscale vector_catch 0xFF - - xscale vector_table low 1 0xe59ff018 - xscale vector_table low 2 0xe59ff018 - xscale vector_table low 3 0xe59ff018 - xscale vector_table low 4 0xe59ff018 - xscale vector_table low 5 0xe59ff018 - xscale vector_table low 6 0xe59ff018 - xscale vector_table low 7 0xe59ff018 - - xscale vector_table high 1 0xe59ff018 - xscale vector_table high 2 0xe59ff018 - xscale vector_table high 3 0xe59ff018 - xscale vector_table high 4 0xe59ff018 - xscale vector_table high 5 0xe59ff018 - xscale vector_table high 6 0xe59ff018 - xscale vector_table high 7 0xe59ff018 -} diff --git a/tcl/board/adapteva_parallella1.cfg b/tcl/board/adapteva_parallella1.cfg deleted file mode 100644 index 83d1cd44b..000000000 --- a/tcl/board/adapteva_parallella1.cfg +++ /dev/null @@ -1,7 +0,0 @@ -# -# Adapteva Parallella-I board (via Porcupine-1 adapter board) -# - -reset_config srst_only - -source [find target/zynq_7000.cfg] diff --git a/tcl/board/alphascale_asm9260_ek.cfg b/tcl/board/alphascale_asm9260_ek.cfg deleted file mode 100644 index 46e8a5b5b..000000000 --- a/tcl/board/alphascale_asm9260_ek.cfg +++ /dev/null @@ -1,69 +0,0 @@ -source [find target/alphascale_asm9260t.cfg] - -reset_config trst_and_srst - -$_TARGETNAME configure -event reset-init { - echo "Configure clock" - # Enable SRAM clk - mww 0x80040024 0x4 - # Enable IRQ clk - mww 0x80040034 0x100 - # Enable DMA0,1 clk - mww 0x80040024 0x600 - # Make sysre syspll is enabled - mww 0x80040238 0x750 - #CPU = PLLCLK/2 - mww 0x8004017C 0x2 - #SYSAHBCLK = CPUCLK/2 - mww 0x80040180 0x2 - # Set PLL freq to 480MHz - mww 0x80040100 480 - # normally we shoul waiting here until we get 0x1 (0x80040104)&0x1)==0x0) - sleep 100 - - # select PLL as main source - mww 0x80040120 0x1 - # disable and enble main clk to update changes? - mww 0x80040124 0x0 - mww 0x80040124 0x1 - - echo "Configure memory" - #enable EMI CLK - mww 0x80040024 0x40 - - # configure memory controller for internal SRAM - mww 0x80700000 0x1188 - # change default emi clk delay - mww 0x8004034C 0xA0503 - # make sure chip_select_register2_low has correct value (why?) - mww 0x8070001c 0x20000000 - # set type to sdram and size to 32MB - mww 0x8070005c 0xa - # configure internal SDRAM timing - mww 0x80700004 0x024996d9 - # configure Static Memory timing - mww 0x80700094 0x00542b4f - - echo "Configure uart4" - # enable pinctrl clk - mww 0x80040024 0x2000000 - # mux GPIO3_0 and GPIO3_1 to UART4 - mww 0x80044060 0x2 - mww 0x80044064 0x2 - # configure UART4CLKDIV - mww 0x800401a8 0x1 - # enable uart4 clk - mww 0x80040024 0x8000 - # clear softrst and clkgate on uart4 - mww 0x80010008 0xC0000000 - # set bandrate 115200 12M - mww 0x80010030 0x00062070 - # enable Rx&Tx - mww 0x80010024 0x301 - # clear hw control - mww 0x80010028 0xc000 -} - -$_TARGETNAME configure -work-area-phys 0x21ffe000 -work-area-virt 0xc1ffe000 -work-area-size 0x1000 -$_TARGETNAME arm7_9 fast_memory_access enable -$_TARGETNAME arm7_9 dcc_downloads enable diff --git a/tcl/board/altera_sockit.cfg b/tcl/board/altera_sockit.cfg deleted file mode 100644 index 569414331..000000000 --- a/tcl/board/altera_sockit.cfg +++ /dev/null @@ -1,19 +0,0 @@ -# -# Cyclone V SocKit board -# http://www.altera.com/b/arrow-sockit.html -# -# Software support page: -# http://www.rocketboards.org/ - -# openocd does not currently support the on-board USB Blaster II. -# Install the JTAG header and use a USB Blaster instead. -interface usb_blaster - -source [find target/altera_fpgasoc.cfg] - -# If the USB Blaster II were supported, these settings would be needed -#usb_blaster_vid_pid 0x6810 0x09fb -#usb_blaster_device_desc "USB-Blaster II" - -adapter_khz 100 - diff --git a/tcl/board/am3517evm.cfg b/tcl/board/am3517evm.cfg deleted file mode 100644 index 2bff51246..000000000 --- a/tcl/board/am3517evm.cfg +++ /dev/null @@ -1,21 +0,0 @@ -# DANGER!!!! early work in progress for this PCB/target. -# -# The most basic operations work well enough that it is -# useful to have this in the repository for cooperation -# alpha testing purposes. -# -# TI AM3517 -# -# http://focus.ti.com/docs/prod/folders/print/am3517.html -# http://processors.wiki.ti.com/index.php/Debug_Access_Port_(DAP) -# http://processors.wiki.ti.com/index.php?title=How_to_Find_the_Silicon_Revision_of_your_OMAP35x - -set CHIPTYPE "am35x" -source [find target/amdm37x.cfg] - -# The TI-14 JTAG connector does not have srst. CPU reset is handled in -# hardware. -reset_config trst_only - -# "amdm37x_dbginit am35x.cpu" needs to be run after init. - diff --git a/tcl/board/arm_evaluator7t.cfg b/tcl/board/arm_evaluator7t.cfg deleted file mode 100644 index 52de57afe..000000000 --- a/tcl/board/arm_evaluator7t.cfg +++ /dev/null @@ -1,10 +0,0 @@ -# This board is from ARM and has an samsung s3c45101x01 chip - -source [find target/samsung_s3c4510.cfg] - -# -# FIXME: -# Add (A) sdram configuration -# Add (B) flash cfi programing configuration -# - diff --git a/tcl/board/asus-rt-n16.cfg b/tcl/board/asus-rt-n16.cfg deleted file mode 100644 index 78f111d38..000000000 --- a/tcl/board/asus-rt-n16.cfg +++ /dev/null @@ -1,15 +0,0 @@ -# -# http://wikidevi.com/wiki/ASUS_RT-N16 -# - -set partition_list { - CFE { Bootloader 0xbc000000 0x00040000 } - firmware { "Kernel+rootfs" 0xbc040000 0x01fa0000 } - nvram { "Config space" 0xbdfe0000 0x00020000 } -} - -source [find target/bcm4718.cfg] - -# External 32MB NOR Flash (Macronix MX29GL256EHTI2I-90Q) -set _FLASHNAME $_CHIPNAME.flash -flash bank $_FLASHNAME cfi 0xbc000000 0x02000000 1 1 $_TARGETNAME x16_as_x8 diff --git a/tcl/board/asus-rt-n66u.cfg b/tcl/board/asus-rt-n66u.cfg deleted file mode 100644 index 4b255cf94..000000000 --- a/tcl/board/asus-rt-n66u.cfg +++ /dev/null @@ -1,19 +0,0 @@ -# -# http://wikidevi.com/wiki/Asus_RT-N66U -# - -echo "ATTENTION: you need to solder a 4.7-10k pullup resistor to pin 21 of flash IC" -echo "to enable JTAG, see http://wl500g.info/album.php?albumid=28&attachmentid=8991 ," -echo "there is an unpopulated footprint near U8.\n" - -set partition_list { - CFE { Bootloader 0xbc000000 0x00040000 } - firmware { "Kernel+rootfs" 0xbc040000 0x01fa0000 } - nvram { "Config space" 0xbdfe0000 0x00020000 } -} - -source [find target/bcm4706.cfg] - -# External 32MB NOR Flash (Spansion S29GL256P10TF101 -set _FLASHNAME $_CHIPNAME.flash -flash bank $_FLASHNAME cfi 0xbc000000 0x02000000 2 2 $_TARGETNAME diff --git a/tcl/board/at91cap7a-stk-sdram.cfg b/tcl/board/at91cap7a-stk-sdram.cfg deleted file mode 100644 index 9bc02e8c0..000000000 --- a/tcl/board/at91cap7a-stk-sdram.cfg +++ /dev/null @@ -1,165 +0,0 @@ -# http://www.atmel.com/dyn/products/tools_card.asp?tool_id=4394 -# -# use combined on interfaces or targets that can't set TRST/SRST separately -reset_config trst_and_srst srst_pulls_trst - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME cap7 -} - -if { [info exists ENDIAN] } { - set _ENDIAN $ENDIAN -} else { - set _ENDIAN little -} - -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - set _CPUTAPID 0x40700f0f -} - -jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID - -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME arm7tdmi -endian $_ENDIAN -chain-position $_TARGETNAME - -$_TARGETNAME configure -event reset-start { - # start off real slow when we're running off internal RC oscillator - adapter_khz 32 -} - -proc peek32 {address} { - mem2array t 32 $address 1 - return $t(0) -} - -# Wait for an expression to be true with a timeout -proc wait_state {expression} { - for {set i 0} {$i < 1000} {set i [expr $i + 1]} { - if {[uplevel 1 $expression] == 0} { - return - } - } - return -code 1 "Timed out" -} - -# Use a global variable here to be able to tinker interactively with -# post reset jtag frequency. -global post_reset_khz -# Danger!!!! Even 16MHz kinda works with this target, but -# it needs to be as low as 2000kHz to be stable. -set post_reset_khz 2000 - -$_TARGETNAME configure -event reset-init { - echo "Configuring master clock" - # disable watchdog - mww 0xfffffd44 0xff008000 - # enable user reset - mww 0xfffffd08 0xa5000001 - # Enable main oscillator - mww 0xFFFFFc20 0x00000f01 - wait_state {expr {([peek32 0xFFFFFC68] & 0x1) == 0}} - - # Set PLLA to 96MHz - mww 0xFFFFFc28 0x20072801 - wait_state {expr {([peek32 0xFFFFFC68] & 0x2) == 0}} - - # Select prescaler - mww 0xFFFFFC30 0x00000004 - wait_state {expr {([peek32 0xFFFFFC68] & 0x8) == 0}} - - # Select master clock to 48MHz - mww 0xFFFFFC30 0x00000006 - wait_state {expr {([peek32 0xFFFFFC68] & 0x8) == 0}} - - echo "Master clock ok." - - # Now that we're up and running, crank up speed! - global post_reset_khz ; adapter_khz $post_reset_khz - - echo "Configuring the SDRAM controller..." - - # Configure EBI Chip select for SDRAM - mww 0xFFFFEF30 0x00000102 - - # Enable clock on EBI PIOs - mww 0xFFFFFC10 0x00000004 - - # Configure PIO for SDRAM - mww 0xFFFFF470 0xFFFF0000 - mww 0xFFFFF474 0x00000000 - mww 0xFFFFF404 0xFFFF0000 - - # Configure SDRAMC CR - mww 0xFFFFEA08 0xA63392F9 - - # NOP command - mww 0xFFFFEA00 0x1 - mww 0x20000000 0 - - # Precharge All Banks command - mww 0xFFFFEA00 0x2 - mww 0x20000000 0 - - # Set 1st CBR - mww 0xFFFFEA00 0x00000004 - mww 0x20000010 0x00000001 - - # Set 2nd CBR - mww 0xFFFFEA00 0x00000004 - mww 0x20000020 0x00000002 - - # Set 3rd CBR - mww 0xFFFFEA00 0x00000004 - mww 0x20000030 0x00000003 - - # Set 4th CBR - mww 0xFFFFEA00 0x00000004 - mww 0x20000040 0x00000004 - - # Set 5th CBR - mww 0xFFFFEA00 0x00000004 - mww 0x20000050 0x00000005 - - # Set 6th CBR - mww 0xFFFFEA00 0x00000004 - mww 0x20000060 0x00000006 - - # Set 7th CBR - mww 0xFFFFEA00 0x00000004 - mww 0x20000070 0x00000007 - - # Set 8th CBR - mww 0xFFFFEA00 0x00000004 - mww 0x20000080 0x00000008 - - # Set LMR operation - mww 0xFFFFEA00 0x00000003 - - # Perform LMR burst=1, lat=2 - mww 0x20000020 0xCAFEDEDE - - # Set Refresh Timer - mww 0xFFFFEA04 0x00000203 - - # Set Normal mode - mww 0xFFFFEA00 0x00000000 - mww 0x20000000 0x00000000 - - #remap internal memory at address 0x0 - mww 0xffffef00 0x3 - - echo "SDRAM configuration ok." -} - -$_TARGETNAME configure -work-area-phys 0x00200000 -work-area-size 0x4000 -work-area-backup 0 - -arm7_9 dcc_downloads enable -arm7_9 fast_memory_access enable - -#set _FLASHNAME $_CHIPNAME.flash -#flash bank $_FLASHNAME at91sam7 0 0 0 0 $_TARGETNAME 0 0 0 0 0 0 0 18432 - diff --git a/tcl/board/at91eb40a.cfg b/tcl/board/at91eb40a.cfg deleted file mode 100644 index d8a82a59d..000000000 --- a/tcl/board/at91eb40a.cfg +++ /dev/null @@ -1,67 +0,0 @@ -#Script for AT91EB40a - -# FIXME use some standard target config, maybe create one from this -# -# source [find target/...cfg] - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME at91eb40a -} - -if { [info exists ENDIAN] } { - set _ENDIAN $ENDIAN -} else { - set _ENDIAN little -} - -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - set _CPUTAPID 0x1f0f0f0f -} - - -#Atmel ties SRST & TRST together, at which point it makes -#no sense to use TRST, but use TMS instead. -# -#The annoying thing with tying SRST & TRST together is that -#there is no way to halt the CPU *before and during* the -#SRST reset, which means that the CPU will run a number -#of cycles before it can be halted(as much as milliseconds). -reset_config srst_only srst_pulls_trst - -#jtag scan chain -jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID - -#target configuration -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME arm7tdmi -endian $_ENDIAN -chain-position $_TARGETNAME - -# speed up memory downloads -arm7_9 fast_memory_access enable -arm7_9 dcc_downloads enable - -#flash driver -set _FLASHNAME $_CHIPNAME.flash -flash bank $_FLASHNAME cfi 0x01000000 0x200000 2 2 $_TARGETNAME - -# required for usable performance. Used for lots of -# other things than flash programming. -$_TARGETNAME configure -work-area-phys 0x00030000 -work-area-size 0x10000 -work-area-backup 0 - -$_TARGETNAME configure -event reset-init { - echo "Running reset init script for AT91EB40A" - # Reset script for AT91EB40a - reg cpsr 0x000000D3 - mww 0xFFE00020 0x1 - mww 0xFFE00024 0x00000000 - mww 0xFFE00000 0x01002539 - mww 0xFFFFF124 0xFFFFFFFF - mww 0xffff0010 0x100 - mww 0xffff0034 0x100 -} - -# This target is pretty snappy... -adapter_khz 16000 diff --git a/tcl/board/at91rm9200-dk.cfg b/tcl/board/at91rm9200-dk.cfg deleted file mode 100644 index f484fded1..000000000 --- a/tcl/board/at91rm9200-dk.cfg +++ /dev/null @@ -1,82 +0,0 @@ -# -# This is for the "at91rm9200-DK" (not the EK) eval board. -# -# The two are probably very simular.... I have DK... -# -# It has atmel at91rm9200 chip. -source [find target/at91rm9200.cfg] - -reset_config trst_and_srst - -$_TARGETNAME configure -event gdb-attach { reset init } -$_TARGETNAME configure -event reset-init { at91rm9200_dk_init } - -#flash bank -set _FLASHNAME $_CHIPNAME.flash -flash bank $_FLASHNAME cfi 0x10000000 0x00200000 2 2 $_TARGETNAME - - -proc at91rm9200_dk_init { } { - # Try to run at 1khz... Yea, that slow! - # Chip is really running @ 32khz - adapter_khz 8 - - mww 0xfffffc64 0xffffffff - ## disable all clocks but system clock - mww 0xfffffc04 0xfffffffe - ## disable all clocks to pioa and piob - mww 0xfffffc14 0xffffffc3 - ## master clock = slow cpu = slow - ## (means the CPU is running at 32khz!) - mww 0xfffffc30 0 - ## main osc enable - mww 0xfffffc20 0x0000ff01 - ## program pllA - mww 0xfffffc28 0x20263e04 - ## program pllB - mww 0xfffffc2c 0x10483e0e - ## let pll settle... sleep 100msec - sleep 100 - ## switch to fast clock - mww 0xfffffc30 0x202 - ## Sleep some - (go read) - sleep 100 - - #======================================== - # CPU now runs at 180mhz - # SYS runs at 60mhz. - adapter_khz 40000 - #======================================== - - - ## set memc for all memories - mww 0xffffff60 0x02 - ## program smc controller - mww 0xffffff70 0x3284 - ## init sdram - mww 0xffffff98 0x7fffffd0 - ## all banks precharge - mww 0xffffff80 0x02 - ## touch sdram chip to make it work - mww 0x20000000 0 - ## sdram controller mode register - mww 0xffffff90 0x04 - mww 0x20000000 0 - mww 0x20000000 0 - mww 0x20000000 0 - mww 0x20000000 0 - mww 0x20000000 0 - mww 0x20000000 0 - mww 0x20000000 0 - mww 0x20000000 0 - ## sdram controller mode register - ## Refresh, etc.... - mww 0xffffff90 0x03 - mww 0x20000080 0 - mww 0xffffff94 0x1f4 - mww 0x20000080 0 - mww 0xffffff90 0x10 - mww 0x20000000 0 - mww 0xffffff00 0x01 - -} diff --git a/tcl/board/at91rm9200-ek.cfg b/tcl/board/at91rm9200-ek.cfg deleted file mode 100644 index a3f253a26..000000000 --- a/tcl/board/at91rm9200-ek.cfg +++ /dev/null @@ -1,114 +0,0 @@ -# -# Copyright 2010 Jean-Christophe PLAGNIOL-VILLARD -# -# under GPLv2 Only -# -# This is for the "at91rm9200-ek" eval board. -# -# -# It has atmel at91rm9200 chip. -source [find target/at91rm9200.cfg] - -reset_config trst_and_srst - -$_TARGETNAME configure -event gdb-attach { reset init } -$_TARGETNAME configure -event reset-init { at91rm9200_ek_init } - -## flash bank -set _FLASHNAME $_CHIPNAME.flash -flash bank $_FLASHNAME cfi 0x10000000 0x00800000 2 2 $_TARGETNAME - -# The chip may run @ 32khz, so set a really low JTAG speed -adapter_khz 8 - -proc at91rm9200_ek_init { } { - # Try to run at 1khz... Yea, that slow! - # Chip is really running @ 32khz - adapter_khz 8 - - mww 0xfffffc64 0xffffffff - ## disable all clocks but system clock - mww 0xfffffc04 0xfffffffe - ## disable all clocks to pioa and piob - mww 0xfffffc14 0xffffffc3 - ## master clock = slow cpu = slow - ## (means the CPU is running at 32khz!) - mww 0xfffffc30 0 - ## main osc enable - mww 0xfffffc20 0x0000ff01 - ## MC_PUP - mww 0xFFFFFF50 0x00000000 - ## MC_PUER: Memory controller protection unit disable - mww 0xFFFFFF54 0x00000000 - ## EBI_CFGR - mww 0xFFFFFF64 0x00000000 - ## SMC2_CSR[0]: 16bit, 2 TDF, 4 WS - mww 0xFFFFFF70 0x00003284 - - ## Init Clocks - ## CKGR_PLLAR - mww 0xFFFFFC28 0x2000BF05 - ## PLLAR: 179,712000 MHz for PCK - mww 0xFFFFFC28 0x20263E04 - sleep 100 - ## PMC_MCKR - mww 0xFFFFFC30 0x00000100 - sleep 100 - ## ;MCKR : PCK/3 = MCK Master Clock = 59,904000MHz from PLLA - mww 0xFFFFFC30 0x00000202 - sleep 100 - - #======================================== - # CPU now runs at 180mhz - # SYS runs at 60mhz. - adapter_khz 40000 - #======================================== - - ## Init SDRAM - ## PIOC_ASR: Configure PIOC as peripheral (D16/D31) - mww 0xFFFFF870 0xFFFF0000 - ## PIOC_BSR: - mww 0xFFFFF874 0x00000000 - ## PIOC_PDR: - mww 0xFFFFF804 0xFFFF0000 - ## EBI_CSA : CS1=SDRAM - mww 0xFFFFFF60 0x00000002 - ## EBI_CFGR: - mww 0xFFFFFF64 0x00000000 - ## SDRC_CR : - mww 0xFFFFFF98 0x2188c155 - ## SDRC_MR : Precharge All - mww 0xFFFFFF90 0x00000002 - ## access SDRAM - mww 0x20000000 0x00000000 - ## SDRC_MR : Refresh - mww 0xFFFFFF90 0x00000004 - ## access SDRAM - mww 0x20000000 0x00000000 - ## access SDRAM - mww 0x20000000 0x00000000 - ## access SDRAM - mww 0x20000000 0x00000000 - ## access SDRAM - mww 0x20000000 0x00000000 - ## access SDRAM - mww 0x20000000 0x00000000 - ## access SDRAM - mww 0x20000000 0x00000000 - ## access SDRAM - mww 0x20000000 0x00000000 - ## access SDRAM - mww 0x20000000 0x00000000 - ## SDRC_MR : Load Mode Register - mww 0xFFFFFF90 0x00000003 - ## access SDRAM - mww 0x20000080 0x00000000 - ## SDRC_TR : Write refresh rate - mww 0xFFFFFF94 0x000002E0 - ## access SDRAM - mww 0x20000000 0x00000000 - ## SDRC_MR : Normal Mode - mww 0xFFFFFF90 0x00000000 - ## access SDRAM - mww 0x20000000 0x00000000 -} diff --git a/tcl/board/at91sam9261-ek.cfg b/tcl/board/at91sam9261-ek.cfg deleted file mode 100644 index 3963e9373..000000000 --- a/tcl/board/at91sam9261-ek.cfg +++ /dev/null @@ -1,63 +0,0 @@ -################################################################################ -# Atmel AT91SAM9261-EK eval board -################################################################################ - -source [find mem_helper.tcl] -source [find target/at91sam9261.cfg] -uplevel #0 [list source [find chip/atmel/at91/hardware.cfg]] -uplevel #0 [list source [find chip/atmel/at91/at91sam9261.cfg]] -uplevel #0 [list source [find chip/atmel/at91/at91sam9261_matrix.cfg]] -uplevel #0 [list source [find chip/atmel/at91/at91sam9_init.cfg]] - -# By default S1 is open and this means that NTRST is not connected. -# The reset_config in target/at91sam9261.cfg is overridden here. -# (or S1 must be populated with a 0 Ohm resistor) -reset_config srst_only - -scan_chain -$_TARGETNAME configure -event gdb-attach { reset init } -$_TARGETNAME configure -event reset-init { at91sam9261ek_reset_init } -$_TARGETNAME configure -event reset-start { at91sam9_reset_start } - -proc at91sam9261ek_reset_init { } { - - ;# for ppla at 199 Mhz - set config(master_pll_div) 15 - set config(master_pll_mul) 162 - - ;# for ppla at 239 Mhz - ;# set master_pll_div 1 - ;# set master_pll_mul 13 - - set val [expr $::AT91_WDT_WDV] ;# Counter Value - set val [expr ($val | $::AT91_WDT_WDDIS)] ;# Watchdog Disable - set val [expr ($val | $::AT91_WDT_WDD)] ;# Delta Value - set val [expr ($val | $::AT91_WDT_WDDBGHLT)] ;# Debug Halt - set val [expr ($val | $::AT91_WDT_WDIDLEHLT)] ;# Idle Halt - - set config(wdt_mr_val) $val - - ;# EBI_CSA, no pull-ups for D[15:0], CS1 SDRAM, CS3 NAND Flash - set config(matrix_ebicsa_addr) $::AT91_MATRIX_EBICSA - set config(matrix_ebicsa_val) [expr ($::AT91_MATRIX_DBPUC | $::AT91_MATRIX_CS1A_SDRAMC)] - - ;# SDRAMC_CR - Configuration register - set val [expr $::AT91_SDRAMC_NC_9] - set val [expr ($val | $::AT91_SDRAMC_NR_13)] - set val [expr ($val | $::AT91_SDRAMC_NB_4)] - set val [expr ($val | $::AT91_SDRAMC_CAS_3)] - set val [expr ($val | $::AT91_SDRAMC_DBW_32)] - set val [expr ($val | (2 << 8))] ;# Write Recovery Delay - set val [expr ($val | (7 << 12))] ;# Row Cycle Delay - set val [expr ($val | (3 << 16))] ;# Row Precharge Delay - set val [expr ($val | (2 << 20))] ;# Row to Column Delay - set val [expr ($val | (5 << 24))] ;# Active to Precharge Delay - set val [expr ($val | (8 << 28))] ;# Exit Self Refresh to Active Delay - - set config(sdram_cr_val) $val - - set config(sdram_tr_val) 0x13c - - set config(sdram_base) $::AT91_CHIPSELECT_1 - at91sam9_reset_init $config -} diff --git a/tcl/board/at91sam9263-ek.cfg b/tcl/board/at91sam9263-ek.cfg deleted file mode 100644 index 645b1a7bd..000000000 --- a/tcl/board/at91sam9263-ek.cfg +++ /dev/null @@ -1,63 +0,0 @@ -################################################################################ -# Atmel AT91SAM9263-EK eval board -################################################################################ - -source [find mem_helper.tcl] -source [find target/at91sam9263.cfg] -uplevel #0 [list source [find chip/atmel/at91/hardware.cfg]] -uplevel #0 [list source [find chip/atmel/at91/at91sam9263.cfg]] -uplevel #0 [list source [find chip/atmel/at91/at91sam9263_matrix.cfg]] -uplevel #0 [list source [find chip/atmel/at91/at91sam9_init.cfg]] - -# By default S1 is open and this means that NTRST is not connected. -# The reset_config in target/at91sam9263.cfg is overridden here. -# (or S1 must be populated with a 0 Ohm resistor) -reset_config srst_only - -scan_chain -$_TARGETNAME configure -event gdb-attach { reset init } -$_TARGETNAME configure -event reset-init { at91sam9263ek_reset_init } -$_TARGETNAME configure -event reset-start { at91sam9_reset_start } - -proc at91sam9263ek_reset_init { } { - - set config(master_pll_div) 14 - set config(master_pll_mul) 171 - - set val [expr $::AT91_WDT_WDV] ;# Counter Value - set val [expr ($val | $::AT91_WDT_WDDIS)] ;# Watchdog Disable - set val [expr ($val | $::AT91_WDT_WDD)] ;# Delta Value - set val [expr ($val | $::AT91_WDT_WDDBGHLT)] ;# Debug Halt - set val [expr ($val | $::AT91_WDT_WDIDLEHLT)] ;# Idle Halt - - set config(wdt_mr_val) $val - - set config(sdram_piod) 1 - ;# EBI_CSA, no pull-ups for D[15:0], CS1 SDRAM, CS3 NAND Flash - set config(matrix_ebicsa_addr) $::AT91_MATRIX_EBI0CSA - - set val [expr $::AT91_MATRIX_EBI0_DBPUC] - set val [expr ($val | $::AT91_MATRIX_EBI0_VDDIOMSEL_3_3V)] - set val [expr ($val | $::AT91_MATRIX_EBI0_CS1A_SDRAMC)] - set config(matrix_ebicsa_val) $val - - ;# SDRAMC_CR - Configuration register - set val [expr $::AT91_SDRAMC_NC_9] - set val [expr ($val | $::AT91_SDRAMC_NR_13)] - set val [expr ($val | $::AT91_SDRAMC_NB_4)] - set val [expr ($val | $::AT91_SDRAMC_CAS_3)] - set val [expr ($val | $::AT91_SDRAMC_DBW_32)] - set val [expr ($val | (1 << 8))] ;# Write Recovery Delay - set val [expr ($val | (7 << 12))] ;# Row Cycle Delay - set val [expr ($val | (2 << 16))] ;# Row Precharge Delay - set val [expr ($val | (2 << 20))] ;# Row to Column Delay - set val [expr ($val | (5 << 24))] ;# Active to Precharge Delay - set val [expr ($val | (1 << 28))] ;# Exit Self Refresh to Active Delay - - set config(sdram_cr_val) $val - - set config(sdram_tr_val) 0x13c - - set config(sdram_base) $::AT91_CHIPSELECT_1 - at91sam9_reset_init $config -} diff --git a/tcl/board/at91sam9g20-ek.cfg b/tcl/board/at91sam9g20-ek.cfg deleted file mode 100644 index 741d6018d..000000000 --- a/tcl/board/at91sam9g20-ek.cfg +++ /dev/null @@ -1,219 +0,0 @@ -################################################################################################# -# # -# Author: Gary Carlson (gcarlson@carlson-minot.com) # -# Generated for Atmel AT91SAM9G20-EK evaluation board using Atmel SAM-ICE (J-Link) version 8. # -# # -################################################################################################# - -# FIXME use some standard target config, maybe create one from this -# -# source [find target/...cfg] - -source [find target/at91sam9g20.cfg] - -set _FLASHTYPE nandflash_cs3 - -# Set reset type. Note that the AT91SAM9G20-EK board has the trst signal disconnected. Therefore -# the reset needs to be configured for "srst_only". If for some reason, a zero-ohm jumper is -# added to the board to connect the trst signal, then this parameter may need to be changed. - -reset_config srst_only - -adapter_nsrst_delay 200 -jtag_ntrst_delay 200 - -# If you don't want to execute built-in boot rom code (and there are good reasons at times not to do that) in the -# AT91SAM9 family, the microcontroller is a lump on a log without initialization. Because this family has -# some powerful features, we want to have a special function that handles "reset init". To do this we declare -# an event handler where these special activities can take place. - -scan_chain -$_TARGETNAME configure -event reset-init {at91sam9g20_reset_init} -$_TARGETNAME configure -event reset-start {at91sam9g20_reset_start} - -# NandFlash configuration and definition - -nand device nandflash_cs3 at91sam9 $_TARGETNAME 0x40000000 0xfffffe800 -at91sam9 cle 0 22 -at91sam9 ale 0 21 -at91sam9 rdy_busy 0 0xfffff800 13 -at91sam9 ce 0 0xfffff800 14 - -proc read_register {register} { - set result "" - mem2array result 32 $register 1 - return $result(0) -} - -proc at91sam9g20_reset_start { } { - - # Make sure that the the jtag is running slow, since there are a number of different ways the board - # can be configured coming into this state that can cause communication problems with the jtag - # adapter. Also since this call can be made following a "reset init" where fast memory accesses - # are enabled, need to temporarily shut this down so that the RSTC_MR register can be written at slower - # jtag speed without causing GDB keep alive problem. - - arm7_9 fast_memory_access disable - adapter_khz 2 ;# Slow-speed oscillator enabled at reset, so run jtag speed slow. - halt ;# Make sure processor is halted, or error will result in following steps. - wait_halt 10000 - mww 0xfffffd08 0xa5000501 ;# RSTC_MR : enable user reset. -} - -proc at91sam9g20_reset_init { } { - - # At reset AT91SAM9G20 chip runs on slow clock (32.768 kHz). To shift over to a normal clock requires - # a number of steps that must be carefully performed. The process outline below follows the - # recommended procedure outlined in the AT91SAM9G20 technical manual. - # - # Several key and very important things to keep in mind: - # The SDRAM parts used currently on the Atmel evaluation board are -75 grade parts. This - # means the master clock (MCLK) must be at or below 133 MHz or timing errors will occur. The processor - # core can operate up to 400 MHz and therefore PCLK must be at or below this to function properly. - - mww 0xfffffd44 0x00008000 ;# WDT_MR : disable watchdog. - - # Enable the main 18.432 MHz oscillator in CKGR_MOR register. - # Wait for MOSCS in PMC_SR to assert indicating oscillator is again stable after change to CKGR_MOR. - - mww 0xfffffc20 0x00004001 - while { [expr [read_register 0xfffffc68] & 0x01] != 1 } { sleep 1 } - - # Set PLLA Register for 792.576 MHz (divider: bypass, multiplier: 43). - # Wait for LOCKA signal in PMC_SR to assert indicating PLLA is stable. - - mww 0xfffffc28 0x202a3f01 - while { [expr [read_register 0xfffffc68] & 0x02] != 2 } { sleep 1 } - - # Set master system clock prescaler divide by 6 and processor clock divide by 2 in PMC_MCKR. - # Wait for MCKRDY signal from PMC_SR to assert. - - mww 0xfffffc30 0x00000101 - while { [expr [read_register 0xfffffc68] & 0x08] != 8 } { sleep 1 } - - # Now change PMC_MCKR register to select PLLA. - # Wait for MCKRDY signal from PMC_SR to assert. - - mww 0xfffffc30 0x00001302 - while { [expr [read_register 0xfffffc68] & 0x08] != 8 } { sleep 1 } - - # Processor and master clocks are now operating and stable at maximum frequency possible: - # -> MCLK = 132.096 MHz - # -> PCLK = 396.288 MHz - - # Switch over to adaptive clocking. - - adapter_khz 0 - - # Enable faster DCC downloads and memory accesses. - - arm7_9 dcc_downloads enable - arm7_9 fast_memory_access enable - - # To be able to use external SDRAM, several peripheral configuration registers must - # be modified. The first change is made to PIO_ASR to select peripheral functions - # for D15 through D31. The second change is made to the PIO_PDR register to disable - # this for D15 through D31. - - mww 0xfffff870 0xffff0000 - mww 0xfffff804 0xffff0000 - - # The EBI chip select register EBI_CS must be specifically configured to enable the internal SDRAM controller - # using CS1. Additionally we want CS3 assigned to NandFlash. Also VDDIO is connected physically on - # the board to the 3.3 VDC power supply so set the appropriate register bit to notify the micrcontroller. - - mww 0xffffef1c 0x000100a - - # The AT91SAM9G20-EK evaluation board has built-in NandFlash. The exact physical timing characteristics - # for the memory type used on the current board (MT29F2G08AACWP) can be established by setting - # a number of registers. The first step involves setting up the general I/O pins on the processor - # to be able to interface and support the external memory. - - mww 0xfffffc10 0x00000010 ;# PMC_PCER : enable PIOC clock - mww 0xfffff800 0x00006000 ;# PIOC_PER : enable PIO function for 13(RDY/~BSY) and 14(~CS) - mww 0xfffff810 0x00004000 ;# PIOC_OER : enable output on 14 - mww 0xfffff814 0x00002000 ;# PIOC_ODR : disable output on 13 - mww 0xfffff830 0x00004000 ;# PIOC_SODR : set 14 to disable NAND - - # The exact physical timing characteristics for the memory type used on the current board - # (MT29F2G08AACWP) can be established by setting four registers in order: SMC_SETUP3, - # SMC_PULSE3, SMC_CYCLE3, and SMC_MODE3. Computing the exact values of these registers - # is a little tedious to do here. If you have questions about how to do this, Atmel has - # a decent application note #6255B that covers this process. - - mww 0xffffec30 0x00020002 ;# SMC_SETUP3 : 2 clock cycle setup for NRD and NWE - mww 0xffffec34 0x04040404 ;# SMC_PULSE3 : 4 clock cycle pulse for all signals - mww 0xffffec38 0x00070006 ;# SMC_CYCLE3 : 7 clock cycle NRD and 6 NWE cycle - mww 0xffffec3C 0x00020003 ;# SMC_MODE3 : NRD and NWE control, no NWAIT, 8-bit DBW, - - mww 0xffffe800 0x00000001 ;# ECC_CR : reset the ECC parity registers - mww 0xffffe804 0x00000002 ;# ECC_MR : page size is 2112 words (word is 8 bits) - - # Identify NandFlash bank 0. - - nand probe nandflash_cs3 - - # The AT91SAM9G20-EK evaluation board has build-in serial data flash also. - - # Now setup SDRAM. This is tricky and configuration is very important for reliability! The current calculations - # are based on 2 x Micron MT48LC16M16A2-75 memory (4 M x 16 bit x 4 banks). If you use this file as a reference - # for a new board that uses different SDRAM devices or clock rates, you need to recalculate the value inserted - # into the SDRAM_CR register. Using the memory datasheet for the -75 grade part and assuming a master clock - # of 132.096 MHz then the SDCLK period is equal to 7.6 ns. This means the device requires: - # - # CAS latency = 3 cycles - # TXSR = 10 cycles - # TRAS = 6 cycles - # TRCD = 3 cycles - # TRP = 3 cycles - # TRC = 9 cycles - # TWR = 2 cycles - # 9 column, 13 row, 4 banks - # refresh equal to or less then 7.8 us for commerical/industrial rated devices - # - # Thus SDRAM_CR = 0xa6339279 - - mww 0xffffea08 0xa6339279 - - # Next issue a 'NOP' command through the SDRAMC_MR register followed by writing a zero value into - # the starting memory location for the SDRAM. - - mww 0xffffea00 0x00000001 - mww 0x20000000 0 - - # Issue an 'All Banks Precharge' command through the SDRAMC_MR register followed by writing a zero - # value into the starting memory location for the SDRAM. - - mww 0xffffea00 0x00000002 - mww 0x20000000 0 - - # Now issue an 'Auto-Refresh' command through the SDRAMC_MR register. Follow this operation by writing - # zero values eight times into the starting memory location for the SDRAM. - - mww 0xffffea00 0x4 - mww 0x20000000 0 - mww 0x20000000 0 - mww 0x20000000 0 - mww 0x20000000 0 - mww 0x20000000 0 - mww 0x20000000 0 - mww 0x20000000 0 - mww 0x20000000 0 - - # Almost done, so next issue a 'Load Mode Register' command followed by a zero value write to the - # the starting memory location for the SDRAM. - - mww 0xffffea00 0x3 - mww 0x20000000 0 - - # Signal normal mode using the SDRAMC_MR register and follow with a zero value write the the starting - # memory location for the SDRAM. - - mww 0xffffea00 0x0 - mww 0x20000000 0 - - # Finally set the refresh rate to about every 7 us (7.5 ns x 924 cycles). - - mww 0xffffea04 0x0000039c -} - diff --git a/tcl/board/atmel_at91sam7s-ek.cfg b/tcl/board/atmel_at91sam7s-ek.cfg deleted file mode 100644 index d7e848654..000000000 --- a/tcl/board/atmel_at91sam7s-ek.cfg +++ /dev/null @@ -1,8 +0,0 @@ -# Atmel AT91SAM7S-EK -# http://www.atmel.com/dyn/products/tools_card.asp?tool_id=3784 - -set CHIPNAME at91sam7s256 - -source [find target/at91sam7sx.cfg] - - diff --git a/tcl/board/atmel_at91sam9260-ek.cfg b/tcl/board/atmel_at91sam9260-ek.cfg deleted file mode 100644 index a37f1f5d8..000000000 --- a/tcl/board/atmel_at91sam9260-ek.cfg +++ /dev/null @@ -1,81 +0,0 @@ -################################################################################ -# Atmel AT91SAM9260-EK eval board -# -# http://www.atmel.com/dyn/products/tools_card.asp?tool_id=3933 -# -# Atmel AT91SAM9260 : PLLA = 198.656 MHz, MCK = 99.328 MHz -# OSCSEL configured for external 32.768 kHz crystal -# -# 32-bit SDRAM : 2 x Micron MT48LC16M16A2, 4M x 16Bit x 4 Banks -# -################################################################################ - -# We add to the minimal configuration. -source [find target/at91sam9260.cfg] - -# By default S1 is open and this means that NTRST is not connected. -# The reset_config in target/at91sam9260.cfg is overridden here. -# (or S1 must be populated with a 0 Ohm resistor) -reset_config srst_only - -$_TARGETNAME configure -event reset-start { - # At reset CPU runs at 32.768 kHz. - # JTAG Frequency must be 6 times slower if RCLK is not supported. - jtag_rclk 5 - halt - # RSTC_MR : enable user reset, MMU may be enabled... use physical address - mww phys 0xfffffd08 0xa5000501 -} - -$_TARGETNAME configure -event reset-init { - mww 0xfffffd44 0x00008000 ;# WDT_MR : disable watchdog - - mww 0xfffffc20 0x00004001 ;# CKGR_MOR : enable the main oscillator - sleep 20 ;# wait 20 ms - mww 0xfffffc30 0x00000001 ;# PMC_MCKR : switch to main oscillator - sleep 10 ;# wait 10 ms - mww 0xfffffc28 0x2060bf09 ;# CKGR_PLLAR: Set PLLA Register for 198.656 MHz - sleep 20 ;# wait 20 ms - mww 0xfffffc30 0x00000101 ;# PMC_MCKR : Select prescaler (divide by 2) - sleep 10 ;# wait 10 ms - mww 0xfffffc30 0x00000102 ;# PMC_MCKR : Clock from PLLA is selected (99.328 MHz) - sleep 10 ;# wait 10 ms - - # Increase JTAG Speed to 6 MHz if RCLK is not supported - jtag_rclk 6000 - - arm7_9 dcc_downloads enable ;# Enable faster DCC downloads - - mww 0xfffff870 0xffff0000 ;# PIO_ASR : Select peripheral function for D15..D31 - mww 0xfffff804 0xffff0000 ;# PIO_PDR : Disable PIO function for D15..D31 - - mww 0xffffef1c 0x00010002 ;# EBI_CSA : Assign EBI Chip Select 1 to SDRAM, VDDIOMSEL set for +3V3 memory - - mww 0xffffea08 0x85227259 ;# SDRAMC_CR : Configure SDRAM (2 x Micron MT48LC16M16A2 : 4M x 16Bit x 4 Banks) - - mww 0xffffea00 0x1 ;# SDRAMC_MR : issue a NOP command - mww 0x20000000 0 - mww 0xffffea00 0x2 ;# SDRAMC_MR : issue an 'All Banks Precharge' command - mww 0x20000000 0 - mww 0xffffea00 0x4 ;# SDRAMC_MR : issue 8 x 'Auto-Refresh' Command - mww 0x20000000 0 - mww 0xffffea00 0x4 - mww 0x20000000 0 - mww 0xffffea00 0x4 - mww 0x20000000 0 - mww 0xffffea00 0x4 - mww 0x20000000 0 - mww 0xffffea00 0x4 - mww 0x20000000 0 - mww 0xffffea00 0x4 - mww 0x20000000 0 - mww 0xffffea00 0x4 - mww 0x20000000 0 - mww 0xffffea00 0x4 - mww 0x20000000 0 - mww 0xffffea00 0x3 ;# SDRAMC_MR : issue a 'Load Mode Register' command - mww 0x20000000 0 - mww 0xffffea00 0x0 ;# SDRAMC_MR : normal mode - mww 0x20000000 0 - mww 0xffffea04 0x2b6 ;# SDRAMC_TR : Set refresh timer count to 7us -} diff --git a/tcl/board/atmel_at91sam9rl-ek.cfg b/tcl/board/atmel_at91sam9rl-ek.cfg deleted file mode 100644 index e18d1fdf3..000000000 --- a/tcl/board/atmel_at91sam9rl-ek.cfg +++ /dev/null @@ -1,75 +0,0 @@ -################################################################################ -# -# Generated for Atmel AT91SAM9RL-EK evaluation board using Atmel SAM-ICE (J-Link) V6 -# -# Atmel AT91SAM9RL : PLL = 200 MHz, MCK = 100 MHz -# OSCSEL configured for external 32.768 kHz crystal -# -# 32-bit SDRAM : 2 x Micron MT48LC16M16A2, 4M x 16Bit x 4 Banks -# -################################################################################ - -# We add to the minimal configuration. -source [find target/at91sam9rl.cfg] - -$_TARGETNAME configure -event reset-start { - # At reset CPU runs at 32.768 kHz. - # JTAG Frequency must be 6 times slower if RCLK is not supported. - jtag_rclk 5 - halt - # RSTC_MR : enable user reset, MMU may be enabled... use physical address - mww phys 0xfffffd08 0xa5000501 -} - -$_TARGETNAME configure -event reset-init { - mww 0xfffffd44 0x00008000 ;# WDT_MR : disable watchdog - - mww 0xfffffc20 0x00004001 ;# CKGR_MOR : enable the main oscillator - sleep 20 ;# wait 20 ms - mww 0xfffffc30 0x00000001 ;# PMC_MCKR : switch to main oscillator - sleep 10 ;# wait 10 ms - mww 0xfffffc28 0x2031bf03 ;# CKGR_PLLR: Set PLL Register for 200 MHz - sleep 20 ;# wait 20 ms - mww 0xfffffc30 0x00000101 ;# PMC_MCKR : Select prescaler (divide by 2) - sleep 10 ;# wait 10 ms - mww 0xfffffc30 0x00000102 ;# PMC_MCKR : Clock from PLL is selected (100 MHz) - sleep 10 ;# wait 10 ms - - # Increase JTAG Speed to 6 MHz if RCLK is not supported - jtag_rclk 6000 - - arm7_9 dcc_downloads enable ;# Enable faster DCC downloads - - mww 0xfffff670 0xffff0000 ;# PIO_ASR : Select peripheral function for D16..D31 (PIOB) - mww 0xfffff604 0xffff0000 ;# PIO_PDR : Disable PIO function for D16..D31 (PIOB) - - mww 0xffffef20 0x00010002 ;# EBI_CSA : Assign EBI Chip Select 1 to SDRAM, VDDIOMSEL set for +3V3 memory - - mww 0xffffea08 0x85227259 ;# SDRAMC_CR : Configure SDRAM (2 x Micron MT48LC16M16A2 : 4M x 16Bit x 4 Banks) - - mww 0xffffea00 0x1 ;# SDRAMC_MR : issue a NOP command - mww 0x20000000 0 - mww 0xffffea00 0x2 ;# SDRAMC_MR : issue an 'All Banks Precharge' command - mww 0x20000000 0 - mww 0xffffea00 0x4 ;# SDRAMC_MR : issue 8 x 'Auto-Refresh' Command - mww 0x20000000 0 - mww 0xffffea00 0x4 - mww 0x20000000 0 - mww 0xffffea00 0x4 - mww 0x20000000 0 - mww 0xffffea00 0x4 - mww 0x20000000 0 - mww 0xffffea00 0x4 - mww 0x20000000 0 - mww 0xffffea00 0x4 - mww 0x20000000 0 - mww 0xffffea00 0x4 - mww 0x20000000 0 - mww 0xffffea00 0x4 - mww 0x20000000 0 - mww 0xffffea00 0x3 ;# SDRAMC_MR : issue a 'Load Mode Register' command - mww 0x20000000 0 - mww 0xffffea00 0x0 ;# SDRAMC_MR : normal mode - mww 0x20000000 0 - mww 0xffffea04 0x2b6 ;# SDRAMC_TR : Set refresh timer count to 7us -} diff --git a/tcl/board/atmel_sam3n_ek.cfg b/tcl/board/atmel_sam3n_ek.cfg deleted file mode 100644 index 2ae73ebfa..000000000 --- a/tcl/board/atmel_sam3n_ek.cfg +++ /dev/null @@ -1,12 +0,0 @@ - -# -# Board configuration for Atmel's SAM3N-EK -# - -reset_config srst_only - -set CHIPNAME at91sam3n4c - -adapter_khz 32 - -source [find target/at91sam3nXX.cfg] diff --git a/tcl/board/atmel_sam3s_ek.cfg b/tcl/board/atmel_sam3s_ek.cfg deleted file mode 100644 index 38b54b7b0..000000000 --- a/tcl/board/atmel_sam3s_ek.cfg +++ /dev/null @@ -1,3 +0,0 @@ -source [find target/at91sam3sXX.cfg] - -$_TARGETNAME configure -event gdb-attach { reset init } diff --git a/tcl/board/atmel_sam3u_ek.cfg b/tcl/board/atmel_sam3u_ek.cfg deleted file mode 100644 index 13d930b1d..000000000 --- a/tcl/board/atmel_sam3u_ek.cfg +++ /dev/null @@ -1,4 +0,0 @@ -source [find target/at91sam3u4e.cfg] - -reset_config srst_only - diff --git a/tcl/board/atmel_sam3x_ek.cfg b/tcl/board/atmel_sam3x_ek.cfg deleted file mode 100644 index bb8cd1713..000000000 --- a/tcl/board/atmel_sam3x_ek.cfg +++ /dev/null @@ -1,3 +0,0 @@ -source [find target/at91sam3ax_8x.cfg] - -reset_config srst_only diff --git a/tcl/board/atmel_sam4e_ek.cfg b/tcl/board/atmel_sam4e_ek.cfg deleted file mode 100644 index 75e67a94f..000000000 --- a/tcl/board/atmel_sam4e_ek.cfg +++ /dev/null @@ -1,7 +0,0 @@ -# This is an SAM4E-EK board with a single SAM4E16 chip. -# http://www.atmel.com/tools/sam4e-ek.aspx - -# chip name -set CHIPNAME SAM4E16E - -source [find target/at91sam4sXX.cfg] diff --git a/tcl/board/atmel_sam4l8_xplained_pro.cfg b/tcl/board/atmel_sam4l8_xplained_pro.cfg deleted file mode 100644 index 80ccc9f19..000000000 --- a/tcl/board/atmel_sam4l8_xplained_pro.cfg +++ /dev/null @@ -1,11 +0,0 @@ -# -# Atmel SAM4L8 Xplained Pro evaluation kit. -# http://www.atmel.com/tools/ATSAM4L8-XPRO.aspx -# - -source [find interface/cmsis-dap.cfg] - -# chip name -set CHIPNAME ATSAM4LC8CA - -source [find target/at91sam4lXX.cfg] diff --git a/tcl/board/atmel_sam4s_ek.cfg b/tcl/board/atmel_sam4s_ek.cfg deleted file mode 100644 index dcfa900dc..000000000 --- a/tcl/board/atmel_sam4s_ek.cfg +++ /dev/null @@ -1,3 +0,0 @@ -source [find target/at91sam4sXX.cfg] - -$_TARGETNAME configure -event gdb-attach { reset init } diff --git a/tcl/board/atmel_sam4s_xplained_pro.cfg b/tcl/board/atmel_sam4s_xplained_pro.cfg deleted file mode 100644 index d2acc487e..000000000 --- a/tcl/board/atmel_sam4s_xplained_pro.cfg +++ /dev/null @@ -1,11 +0,0 @@ -# -# Atmel SAM4S Xplained Pro evaluation kit. -# http://www.atmel.com/tools/ATSAM4S-XPRO.aspx -# - -source [find interface/cmsis-dap.cfg] - -# chip name -set CHIPNAME ATSAM4SD32C - -source [find target/at91sam4sd32x.cfg] diff --git a/tcl/board/atmel_samc20_xplained_pro.cfg b/tcl/board/atmel_samc20_xplained_pro.cfg deleted file mode 100644 index 1278eb7f1..000000000 --- a/tcl/board/atmel_samc20_xplained_pro.cfg +++ /dev/null @@ -1,10 +0,0 @@ -# -# Atmel SAMC20 Xplained Pro evaluation kit. -# - -source [find interface/cmsis-dap.cfg] - -# chip name -set CHIPNAME at91samc20j18 - -source [find target/at91samdXX.cfg] diff --git a/tcl/board/atmel_samc21_xplained_pro.cfg b/tcl/board/atmel_samc21_xplained_pro.cfg deleted file mode 100644 index ac269305c..000000000 --- a/tcl/board/atmel_samc21_xplained_pro.cfg +++ /dev/null @@ -1,11 +0,0 @@ -# -# Atmel SAMC21 Xplained Pro evaluation kit. -# http://www.atmel.com/tools/ATSAMC21-XPRO.aspx -# - -source [find interface/cmsis-dap.cfg] - -# chip name -set CHIPNAME at91samc21j18 - -source [find target/at91samdXX.cfg] diff --git a/tcl/board/atmel_samd20_xplained_pro.cfg b/tcl/board/atmel_samd20_xplained_pro.cfg deleted file mode 100644 index 525aee069..000000000 --- a/tcl/board/atmel_samd20_xplained_pro.cfg +++ /dev/null @@ -1,11 +0,0 @@ -# -# Atmel SAMD20 Xplained Pro evaluation kit. -# http://www.atmel.com/tools/ATSAMD20-XPRO.aspx -# - -source [find interface/cmsis-dap.cfg] - -# chip name -set CHIPNAME at91samd20j18 - -source [find target/at91samdXX.cfg] diff --git a/tcl/board/atmel_samd21_xplained_pro.cfg b/tcl/board/atmel_samd21_xplained_pro.cfg deleted file mode 100644 index 843b0ce21..000000000 --- a/tcl/board/atmel_samd21_xplained_pro.cfg +++ /dev/null @@ -1,10 +0,0 @@ -# -# Atmel SAMD21 Xplained Pro evaluation kit. -# - -source [find interface/cmsis-dap.cfg] - -# chip name -set CHIPNAME at91samd21j18 - -source [find target/at91samdXX.cfg] diff --git a/tcl/board/atmel_same70_xplained.cfg b/tcl/board/atmel_same70_xplained.cfg deleted file mode 100644 index a22e801a2..000000000 --- a/tcl/board/atmel_same70_xplained.cfg +++ /dev/null @@ -1,12 +0,0 @@ -# -# Atmel SAME70 Xplained evaluation kit. -# http://www.atmel.com/tools/ATSAME70-XPLD.aspx -# -# Connect using the EDBG chip on the dev kit over USB -source [find interface/cmsis-dap.cfg] - -set CHIPNAME atsame70q21 - -source [find target/atsamv.cfg] - -reset_config srst_only diff --git a/tcl/board/atmel_samg53_xplained_pro.cfg b/tcl/board/atmel_samg53_xplained_pro.cfg deleted file mode 100644 index 06638cf56..000000000 --- a/tcl/board/atmel_samg53_xplained_pro.cfg +++ /dev/null @@ -1,11 +0,0 @@ -# -# Atmel SAMG53 Xplained Pro evaluation kit. -# http://www.atmel.com/tools/ATSAMG53-XPRO.aspx -# - -source [find interface/cmsis-dap.cfg] - -# chip name -set CHIPNAME ATSAMG53N19 - -source [find target/at91samg5x.cfg] diff --git a/tcl/board/atmel_saml21_xplained_pro.cfg b/tcl/board/atmel_saml21_xplained_pro.cfg deleted file mode 100644 index 054bda4da..000000000 --- a/tcl/board/atmel_saml21_xplained_pro.cfg +++ /dev/null @@ -1,10 +0,0 @@ -# -# Atmel SAML21 Xplained Pro evaluation kit. -# - -source [find interface/cmsis-dap.cfg] - -# chip name -set CHIPNAME at91saml21j18 - -source [find target/at91samdXX.cfg] diff --git a/tcl/board/atmel_samr21_xplained_pro.cfg b/tcl/board/atmel_samr21_xplained_pro.cfg deleted file mode 100644 index 308e2bdb7..000000000 --- a/tcl/board/atmel_samr21_xplained_pro.cfg +++ /dev/null @@ -1,10 +0,0 @@ -# -# Atmel SAMR21 Xplained Pro evaluation kit. -# - -source [find interface/cmsis-dap.cfg] - -# chip name -set CHIPNAME at91samr21g18 - -source [find target/at91samdXX.cfg] diff --git a/tcl/board/atmel_samv71_xplained_ultra.cfg b/tcl/board/atmel_samv71_xplained_ultra.cfg deleted file mode 100644 index 4e0865d99..000000000 --- a/tcl/board/atmel_samv71_xplained_ultra.cfg +++ /dev/null @@ -1,12 +0,0 @@ -# -# Atmel SAMV71 Xplained Ultra evaluation kit. -# http://www.atmel.com/tools/ATSAMV71-XULT.aspx -# -# To connect using the EDBG chip on the dev kit over USB, you will -# first need to source [find interface/cmsis-dap.cfg] -# however, since this board also has a SWD+ETM connector, we don't -# automatically source that file here. - -set CHIPNAME samv71 - -source [find target/atsamv.cfg] diff --git a/tcl/board/balloon3-cpu.cfg b/tcl/board/balloon3-cpu.cfg deleted file mode 100644 index 468b867b2..000000000 --- a/tcl/board/balloon3-cpu.cfg +++ /dev/null @@ -1,14 +0,0 @@ -# Config for balloon3 board, cpu JTAG port. http://balloonboard.org/ -# The board has separate JTAG ports for cpu and CPLD/FPGA devices -# Chaining is done on IO interfaces if desired. - -source [find target/pxa270.cfg] - -# The board supports separate reset lines -# Override this in the interface config for parallel dongles -reset_config trst_and_srst separate - -# flash bank -# 29LV650 64Mbit Flash -set _FLASHNAME $_CHIPNAME.flash -flash bank $_FLASHNAME cfi 0x00000000 0x800000 2 2 $_TARGETNAME diff --git a/tcl/board/bcm28155_ap.cfg b/tcl/board/bcm28155_ap.cfg deleted file mode 100644 index fb729e191..000000000 --- a/tcl/board/bcm28155_ap.cfg +++ /dev/null @@ -1,9 +0,0 @@ -# BCM28155_AP - -adapter_khz 20000 - -set CHIPNAME bcm28155 -source [find target/bcm281xx.cfg] - -reset_config trst_and_srst - diff --git a/tcl/board/bt-homehubv1.cfg b/tcl/board/bt-homehubv1.cfg deleted file mode 100644 index c50c7d2b6..000000000 --- a/tcl/board/bt-homehubv1.cfg +++ /dev/null @@ -1,15 +0,0 @@ -# -# BT HomeHub v1 -# - -set partition_list { - CFE { Bootloader 0xbe400000 0x00020000 } - firmware { "Kernel+rootfs" 0xbe420000 0x007d0000 } - fisdir { "FIS Directory" 0xbebf0000 0x0000f000 } - nvram { "Config space" 0xbebff000 0x00001000 } -} - -source [find target/bcm6348.cfg] - -set _FLASHNAME $_CHIPNAME.norflash -flash bank $_FLASHNAME cfi 0xbe400000 0x00800000 2 2 $_TARGETNAME diff --git a/tcl/board/colibri.cfg b/tcl/board/colibri.cfg deleted file mode 100644 index 7c1f1cb51..000000000 --- a/tcl/board/colibri.cfg +++ /dev/null @@ -1,13 +0,0 @@ -# Toradex Colibri PXA270 -source [find target/pxa270.cfg] -reset_config trst_and_srst srst_push_pull -adapter_nsrst_assert_width 40 - -# CS0 -- one bank of CFI flash, 32 MBytes -# the bank is 32-bits wide, two 16-bit chips in parallel -set _FLASHNAME $_CHIPNAME.flash -flash bank $_FLASHNAME cfi 0x00000000 0x02000000 2 4 $_TARGETNAME - - - - diff --git a/tcl/board/crossbow_tech_imote2.cfg b/tcl/board/crossbow_tech_imote2.cfg deleted file mode 100644 index 002b5372f..000000000 --- a/tcl/board/crossbow_tech_imote2.cfg +++ /dev/null @@ -1,13 +0,0 @@ -# Crossbow Technology iMote2 - -set CHIPNAME imote2 -source [find target/pxa270.cfg] - -# longer-than-normal reset delay -adapter_nsrst_delay 800 - -reset_config trst_and_srst separate - -# works for P30 flash -set _FLASHNAME $_CHIPNAME.flash -flash bank $_FLASHNAME cfi 0x00000000 0x2000000 2 2 $_TARGETNAME diff --git a/tcl/board/csb337.cfg b/tcl/board/csb337.cfg deleted file mode 100644 index 5e225f5f5..000000000 --- a/tcl/board/csb337.cfg +++ /dev/null @@ -1,117 +0,0 @@ -# Cogent CSB337 -# http://cogcomp.com/csb_csb337.htm - -source [find target/at91rm9200.cfg] - -# boots from NOR on CS0: 8 MBytes CFI flash, 16-bit bus -set _FLASHNAME $_CHIPNAME.flash -flash bank $_FLASHNAME cfi 0x10000000 0x00800000 2 2 $_TARGETNAME - -# ETM9 trace port connector present on this board, 16 data pins. -if { [info exists ETM_DRIVER] } { - etm config $_TARGETNAME 16 normal half $ETM_DRIVER - # OpenOCD may someday support a real trace port driver... - # system config file would need to configure it. -} else { - etm config $_TARGETNAME 16 normal half dummy - etm_dummy config $_TARGETNAME -} - -proc csb337_clk_init { } { - # CPU is in Slow Clock Mode (32KiHz) ... needs slow JTAG clock - adapter_khz 8 - - # CKGR_MOR: start main oscillator (3.6864 MHz) - mww 0xfffffc20 0xff01 - sleep 10 - - # CKGR_PLLAR: start PLL A for CPU and peripherals (184.32 MHz) - mww 0xfffffc28 0x20313e01 - # CKGR_PLLBR: start PLL B for USB timing (96 MHz, with div2) - mww 0xfffffc2c 0x12703e18 - # let PLLs lock - sleep 10 - - # PMC_MCKR: switch to CPU clock = PLLA, master clock = CPU/4 - mww 0xfffffc30 0x0302 - sleep 20 - - # CPU is in Normal Mode ... allows faster JTAG clock speed - adapter_khz 40000 -} - -proc csb337_nor_init { } { - # SMC_CSR0: adjust timings (10 wait states) - mww 0xffffff70 0x1100318a - - flash probe 0 -} - -proc csb337_sdram_init { } { - # enable PIOC clock - mww 0xfffffc10 0x0010 - # PC31..PC16 are D31..D16, with internal pullups like D15..D0 - mww 0xfffff870 0xffff0000 - mww 0xfffff874 0x0 - mww 0xfffff804 0xffff0000 - - # SDRC_CR: set timings - mww 0xffffff98 0x2188b0d5 - - # SDRC_MR: issue all banks precharge to SDRAM - mww 0xffffff90 2 - mww 0x20000000 0 - - # SDRC_MR: 8 autorefresh cycles - mww 0xffffff90 4 - mww 0x20000000 0 - mww 0x20000000 0 - mww 0x20000000 0 - mww 0x20000000 0 - mww 0x20000000 0 - mww 0x20000000 0 - mww 0x20000000 0 - mww 0x20000000 0 - - # SDRC_MR: set SDRAM mode registers (CAS, burst len, etc) - mww 0xffffff90 3 - mww 0x20000080 0 - - # SDRC_TR: set refresh rate - mww 0xffffff94 0x200 - mww 0x20000000 0 - - # SDRC_MR: normal mode, 32 bit bus - mww 0xffffff90 0 - mww 0x20000000 0 -} - -# The rm9200 chip has just been reset. Bring it up far enough -# that we can write flash or run code from SDRAM. -proc csb337_reset_init { } { - csb337_clk_init - - # EBI_CSA: CS0 = NOR, CS1 = SDRAM - mww 0xffffff60 0x02 - - csb337_nor_init - csb337_sdram_init - - # Update CP15 control register ... we don't seem to be able to - # read/modify/write its value through a TCL variable, so just - # write it. Fields are zero unless listed here ... and note - # that OpenOCD numbers this register "2", not "1" (!). - # - # - Core to use Async Clocking mode (so it uses 184 MHz most - # of the time instead of limiting to the master clock rate): - # iA(31) = 1, nF(30) = 1 - # - Icache on (it's disabled now, slowing i-fetches) - # I(12) = 1 - # - Reserved/ones - # 6:3 = 1 - arm920t cp15 2 0xc0001078 -} - -$_TARGETNAME configure -event reset-init {csb337_reset_init} - -arm7_9 fast_memory_access enable diff --git a/tcl/board/csb732.cfg b/tcl/board/csb732.cfg deleted file mode 100644 index 4d6f0e489..000000000 --- a/tcl/board/csb732.cfg +++ /dev/null @@ -1,71 +0,0 @@ -# The Cogent CSB732 board has a single i.MX35 chip -source [find target/imx35.cfg] - -# Determined by trial and error -reset_config trst_and_srst combined -adapter_nsrst_delay 200 -jtag_ntrst_delay 200 - -$_TARGETNAME configure -event gdb-attach { reset init } -$_TARGETNAME configure -event reset-init { csb732_init } - -# Bare-bones initialization of core clocks and SDRAM -proc csb732_init { } { - - # Disable fast writing only for init - memwrite burst disable - - # All delay loops are omitted. - # We assume the interpreter latency is enough. - - # Allow access to all coprocessors - arm mcr 15 0 15 1 0 0x2001 - - # Disable MMU, caches, write buffer - arm mcr 15 0 1 0 0 0x78 - - # Grant manager access to all domains - arm mcr 15 0 3 0 0 0xFFFFFFFF - - # Set ARM clock to 532 MHz, AHB to 133 MHz - mww 0x53F80004 0x1000 - - # Set core clock to 2 * 24 MHz * (11 + 1/12) = 532 MHz - mww 0x53F8001C 0xB2C01 - - set ESDMISC 0xB8001010 - set ESDCFG0 0xB8001004 - set ESDCTL0 0xB8001000 - - # Enable DDR - mww $ESDMISC 0x4 - - # Timing - mww $ESDCFG0 0x007fff3f - - # CS0 - mww $ESDCTL0 0x92120080 - - # Precharge all dummy write - mww 0x80000400 0 - - # Enable CS) auto-refresh - mww $ESDCTL0 0xA2120080 - - # Refresh twice (dummy writes) - mww 0x80000000 0 - mww 0x80000000 0 - - # Enable CS0 load mode register - mww $ESDCTL0 0xB2120080 - - # Dummy writes - mwb 0x80000033 0x01 - mwb 0x81000000 0x01 - - mww $ESDCTL0 0x82226080 - mww 0x80000000 0 - - # Re-enable fast writing - memwrite burst enable -} diff --git a/tcl/board/da850evm.cfg b/tcl/board/da850evm.cfg deleted file mode 100644 index fbec60921..000000000 --- a/tcl/board/da850evm.cfg +++ /dev/null @@ -1,10 +0,0 @@ -#DA850 EVM board -# http://focus.ti.com/dsp/docs/thirdparty/catalog/devtoolsproductfolder.tsp?actionPerformed=productFolder&productId=5939 -# http://www.logicpd.com/products/development-kits/zoom-omap-l138-evm-development-kit - -source [find target/omapl138.cfg] - -reset_config trst_and_srst separate - -#currently any pinmux/timing must be setup by UBL before openocd can do debug -#TODO: implement pinmux/timing on reset like in board/dm365evm.cfg diff --git a/tcl/board/digi_connectcore_wi-9c.cfg b/tcl/board/digi_connectcore_wi-9c.cfg deleted file mode 100644 index 8a8d4c3bf..000000000 --- a/tcl/board/digi_connectcore_wi-9c.cfg +++ /dev/null @@ -1,130 +0,0 @@ -###################################### -# Target: DIGI ConnectCore Wi-9C -###################################### - -reset_config trst_and_srst - -# FIXME use some standard target config, maybe create one from this -# -# source [find target/...cfg] - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME ns9360 -} - -if { [info exists ENDIAN] } { - set _ENDIAN $ENDIAN -} else { - # This config file was defaulting to big endian.. - set _ENDIAN big -} - - -# What's a good fallback frequency for this board if RCLK is -# not available?? -jtag_rclk 1000 - - -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - set _CPUTAPID 0x07926031 -} - -set _TARGETNAME $_CHIPNAME.cpu -jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID - -adapter_nsrst_delay 200 -jtag_ntrst_delay 0 - - -###################### -# Target configuration -###################### - -target create $_TARGETNAME arm926ejs -endian $_ENDIAN -chain-position $_TARGETNAME - -$_TARGETNAME configure -event reset-init { - mww 0x90600104 0x33313333 - mww 0xA0700000 0x00000001 ;# Enable the memory controller. - mww 0xA0700024 0x00000006 ;# Set the refresh counter 6 - mww 0xA0700028 0x00000001 ;# - mww 0xA0700030 0x00000001 ;# Set the precharge period - mww 0xA0700034 0x00000004 ;# Active to precharge command period is 16 clock cycles - mww 0xA070003C 0x00000001 ;# tAPR - mww 0xA0700040 0x00000005 ;# tDAL - mww 0xA0700044 0x00000001 ;# tWR - mww 0xA0700048 0x00000006 ;# tRC 32 clock cycles - mww 0xA070004C 0x00000006 ;# tRFC 32 clock cycles - mww 0xA0700054 0x00000001 ;# tRRD - mww 0xA0700058 0x00000001 ;# tMRD - mww 0xA0700100 0x00004280 ;# Dynamic Config 0 (cs4) - mww 0xA0700120 0x00004280 ;# Dynamic Config 1 (cs5) - mww 0xA0700140 0x00004280 ;# Dynamic Config 2 (cs6) - mww 0xA0700160 0x00004280 ;# Dynamic Config 3 (cs7) - # - mww 0xA0700104 0x00000203 ;# CAS latency is 2 at 100 MHz - mww 0xA0700124 0x00000203 ;# CAS latency is 2 at 100 MHz - mww 0xA0700144 0x00000203 ;# CAS latency is 2 at 100 MHz - mww 0xA0700164 0x00000203 ;# CAS latency is 2 at 100 MHz - # - mww 0xA0700020 0x00000103 ;# issue SDRAM PALL command - # - mww 0xA0700024 0x00000001 ;# Set the refresh counter to be as small as possible - # - # Add some dummy writes to give the SDRAM time to settle, it needs two - # AHB clock cycles, here we poke in the debugger flag, this lets - # the software know that we are in the debugger - mww 0xA0900000 0x00000002 - mww 0xA0900000 0x00000002 - mww 0xA0900000 0x00000002 - mww 0xA0900000 0x00000002 - mww 0xA0900000 0x00000002 - # - mdw 0xA0900000 - mdw 0xA0900000 - mdw 0xA0900000 - mdw 0xA0900000 - mdw 0xA0900000 - # - mww 0xA0700024 0x00000030 ;# Set the refresh counter to 30 - mww 0xA0700020 0x00000083 ;# Issue SDRAM MODE command - # - # Next we perform a read of RAM. - # mw = move word. - mdw 0x00022000 - # mw 0x00022000:P, r3 # 22000 for cas2 latency, 32000 for cas 3 - # - mww 0xA0700020 0x00000003 ;# issue SDRAM NORMAL command - mww 0xA0700100 0x00084280 ;# Enable buffer access - mww 0xA0700120 0x00084280 ;# Enable buffer access - mww 0xA0700140 0x00084280 ;# Enable buffer access - mww 0xA0700160 0x00084280 ;# Enable buffer access - - #Set byte lane state (static mem 1)" - mww 0xA0700220 0x00000082 - #Flash Start - mww 0xA09001F8 0x50000000 - #Flash Mask Reg - mww 0xA09001FC 0xFF000001 - mww 0xA0700028 0x00000001 - - # RAMAddr = 0x00020000 - # RAMSize = 0x00004000 - - # Set the processor mode - reg cpsr 0xd3 -} - -$_TARGETNAME configure -work-area-phys 0x00000000 -work-area-size 0x1000 -work-area-backup 1 - -##################### -# Flash configuration -##################### - -#M29DW323DB - not working -#flash bank cfi -set _FLASHNAME $_CHIPNAME.flash -flash bank $_FLASHNAME cfi 0x50000000 0x0400000 2 2 $_TARGETNAME diff --git a/tcl/board/digilent_analog_discovery.cfg b/tcl/board/digilent_analog_discovery.cfg deleted file mode 100644 index d356fc0f4..000000000 --- a/tcl/board/digilent_analog_discovery.cfg +++ /dev/null @@ -1,18 +0,0 @@ -# -# Digilent Analog Discovery -# -# http://www.digilentinc.com/Products/Detail.cfm?NavPath=2,842,1018&Prod=ANALOG-DISCOVERY -# -# Config is based on data from -# https://github.com/bvanheu/urjtag-ad/commit/8bd883ee01d134f94b79cbbd00df42cd03bafd71 -# - -interface ftdi -ftdi_device_desc "Digilent USB Device" -ftdi_vid_pid 0x0403 0x6014 - -ftdi_layout_init 0x8008 0x800b - -adapter_khz 25000 - -source [find cpld/xilinx-xc6s.cfg] diff --git a/tcl/board/digilent_atlys.cfg b/tcl/board/digilent_atlys.cfg deleted file mode 100644 index f298e3d73..000000000 --- a/tcl/board/digilent_atlys.cfg +++ /dev/null @@ -1,17 +0,0 @@ -# http://digilentinc.com/atlys/ -# -# The Digilent Atlys normally requires proprietary tools to program and will -# enumerate as: -# ID 1443:0007 Digilent Development board JTAG -# -# However, the ixo-usb-jtag project provides an alternative open firmware for -# the on board programmer. When using thie firmware the board will then -# enumerate as: -# ID 16c0:06ad Van Ooijen Technische Informatica -# (With SerialNumber == hw_nexys) -# -# See the interface/usb-jtag.cfg for more information. - -source [find interface/usb-jtag.cfg] -source [find cpld/xilinx-xc6s.cfg] -source [find cpld/jtagspi.cfg] diff --git a/tcl/board/digilent_zedboard.cfg b/tcl/board/digilent_zedboard.cfg deleted file mode 100644 index 08d1a612f..000000000 --- a/tcl/board/digilent_zedboard.cfg +++ /dev/null @@ -1,11 +0,0 @@ -# -# Digilent Zedboard Rev.C, Rev.D with Xilinx Zynq chip -# -# http://zedboard.com/product/zedboard -# - -source [find interface/ftdi/digilent_jtag_smt2.cfg] - -reset_config srst_only srst_push_pull - -source [find target/zynq_7000.cfg] diff --git a/tcl/board/diolan_lpc4350-db1.cfg b/tcl/board/diolan_lpc4350-db1.cfg deleted file mode 100644 index bd48d9ba0..000000000 --- a/tcl/board/diolan_lpc4350-db1.cfg +++ /dev/null @@ -1,9 +0,0 @@ -# -# Diolan LPC-4350-DB1 development board -# - -set CHIPNAME lpc4350 - -source [find target/lpc4350.cfg] - -flash bank $_CHIPNAME.nor cfi 0x1C000000 0x00200000 2 2 $_CHIPNAME.m4 diff --git a/tcl/board/diolan_lpc4357-db1.cfg b/tcl/board/diolan_lpc4357-db1.cfg deleted file mode 100644 index d24cfd02c..000000000 --- a/tcl/board/diolan_lpc4357-db1.cfg +++ /dev/null @@ -1,9 +0,0 @@ -# -# Diolan LPC-4357-DB1 development board -# - -set CHIPNAME lpc4357 - -source [find target/lpc4357.cfg] - -flash bank $_CHIPNAME.nor cfi 0x1C000000 0x00200000 2 2 $_CHIPNAME.m4 diff --git a/tcl/board/dk-tm4c129.cfg b/tcl/board/dk-tm4c129.cfg deleted file mode 100755 index f1171af12..000000000 --- a/tcl/board/dk-tm4c129.cfg +++ /dev/null @@ -1,14 +0,0 @@ -# -# TI Tiva C DK-TM4C129X Connected Development Kit -# -# http://www.ti.com/tool/dk-tm4c129x -# - -source [find interface/ti-icdi.cfg] - -transport select hla_jtag - -set WORKAREASIZE 0x8000 -set CHIPNAME tm4c129xnczad - -source [find target/stellaris.cfg] diff --git a/tcl/board/dm355evm.cfg b/tcl/board/dm355evm.cfg deleted file mode 100644 index 0c971e9a0..000000000 --- a/tcl/board/dm355evm.cfg +++ /dev/null @@ -1,201 +0,0 @@ -# DM355 EVM board -# http://focus.ti.com/docs/toolsw/folders/print/tmdsevm355.html -# http://c6000.spectrumdigital.com/evmdm355/ - -source [find target/ti_dm355.cfg] - -reset_config trst_and_srst separate - -# NOTE: disable or replace this call to dm355evm_init if you're -# debugging new UBL code from SRAM. -$_TARGETNAME configure -event reset-init { dm355evm_init } - -# -# This post-reset init is called when the MMU isn't active, all IRQs -# are disabled, etc. It should do most of what a UBL does, except for -# loading code (like U-Boot) into DRAM and running it. -# -proc dm355evm_init {} { - global dm355 - - echo "Initialize DM355 EVM board" - - # CLKIN = 24 MHz ... can't talk quickly to ARM yet - jtag_rclk 1500 - - ######################## - # PLL1 = 432 MHz (/8, x144) - # ...SYSCLK1 = 216 MHz (/2) ... ARM, MJCP - # ...SYSCLK2 = 108 MHz (/4) ... Peripherals - # ...SYSCLK3 = 27 MHz (/16) ... VPBE, DAC - # ...SYSCLK4 = 108 MHz (/4) ... VPSS - # pll1.{prediv,div1,div2} are fixed - # pll1.postdiv set in MISC (for *this* speed grade) - - set addr [dict get $dm355 pllc1] - set pll_divs [dict create] - dict set pll_divs div3 16 - dict set pll_divs div4 4 - pll_v02_setup $addr 144 $pll_divs - - # ARM is now running at 216 MHz, so JTAG can go faster - jtag_rclk 20000 - - ######################## - # PLL2 = 342 MHz (/8, x114) - # ....SYSCLK1 = 342 MHz (/1) ... DDR PHY at 171 MHz, 2x clock - # pll2.{postdiv,div1} are fixed - - set addr [dict get $dm355 pllc2] - set pll_divs [dict create] - dict set pll_divs div1 1 - dict set pll_divs prediv 8 - pll_v02_setup $addr 114 $pll_divs - - ######################## - # PINMUX - - # All Video Inputs - davinci_pinmux $dm355 0 0x00007f55 - # All Video Outputs - davinci_pinmux $dm355 1 0x00145555 - # EMIFA (NOTE: more could be set up for use as GPIOs) - davinci_pinmux $dm355 2 0x00000c08 - # SPI0, SPI1, UART1, I2C, SD0, SD1, McBSP0, CLKOUTs - davinci_pinmux $dm355 3 0x1bff55ff - # MMC/SD0 instead of MS; SPI0 - davinci_pinmux $dm355 4 0x00000000 - - ######################## - # PSC setup (minimal) - - # DDR EMIF/13, AEMIF/14, UART0/19 - psc_enable 13 - psc_enable 14 - psc_enable 19 - psc_go - - ######################## - # DDR2 EMIF - - # VTPIOCR impedance calibration - set addr [dict get $dm355 sysbase] - set addr [expr $addr + 0x70] - - # clear CLR, LOCK, PWRDN; wait a clock; set CLR - mmw $addr 0 0x20c0 - mmw $addr 0x2000 0 - - # wait for READY - while { [expr [mrw $addr] & 0x8000] == 0 } { sleep 1 } - - # set IO_READY; then LOCK and PWRSAVE; then PWRDN - mmw $addr 0x4000 0 - mmw $addr 0x0180 0 - mmw $addr 0x0040 0 - - # NOTE: this DDR2 initialization sequence borrows from - # both UBL 1.50 and the SPRUEH7D DDR2 EMIF spec. - - # reset (then re-enable) DDR controller - psc_reset 13 - psc_go - psc_enable 13 - psc_go - - # now set it up for Micron MT47H64M16HR-37E @ 171 MHz - - set addr [dict get $dm355 ddr_emif] - - # DDRPHYCR1 - mww [expr $addr + 0xe4] 0x50006404 - - # PBBPR -- burst priority - mww [expr $addr + 0x20] 0xfe - - # SDCR -- unlock boot config; init for DDR2, relock, unlock SDTIM* - mmw [expr $addr + 0x08] 0x00800000 0 - mmw [expr $addr + 0x08] 0x0013c632 0x03870fff - - # SDTIMR0, SDTIMR1 - mww [expr $addr + 0x10] 0x2a923249 - mww [expr $addr + 0x14] 0x4c17c763 - - # SDCR -- relock SDTIM* - mmw [expr $addr + 0x08] 0 0x00008000 - - # SDRCR -- refresh rate (171 MHz * 7.8usec) - mww [expr $addr + 0x0c] 1336 - - ######################## - # ASYNC EMIF - - set addr [dict get $dm355 a_emif] - - # slow/pessimistic timings - set nand_timings 0x40400204 - # fast (25% faster page reads) - #set nand_timings 0x0400008c - - # AWCCR - mww [expr $addr + 0x04] 0xff - # CS0 == socketed NAND (default MT29F16G08FAA, 2GByte) - mww [expr $addr + 0x10] $nand_timings - # CS1 == dm9000 Ethernet - mww [expr $addr + 0x14] 0x00a00505 - # NANDFCR -- only CS0 has NAND - mww [expr $addr + 0x60] 0x01 - - # default: both chipselects to the NAND socket are used - nand probe 0 - nand probe 1 - - ######################## - # UART0 - - set addr [dict get $dm355 uart0] - - # PWREMU_MGNT -- rx + tx in reset - mww [expr $addr + 0x30] 0 - - # DLL, DLH -- 115200 baud - mwb [expr $addr + 0x20] 0x0d - mwb [expr $addr + 0x24] 0x00 - - # FCR - clear and disable FIFOs - mwb [expr $addr + 0x08] 0x07 - mwb [expr $addr + 0x08] 0x00 - - # IER - disable IRQs - mwb [expr $addr + 0x04] 0x00 - - # LCR - 8-N-1 - mwb [expr $addr + 0x0c] 0x03 - - # MCR - no flow control or loopback - mwb [expr $addr + 0x10] 0x00 - - # PWREMU_MGNT -- rx + tx normal, free running during JTAG halt - mww [expr $addr + 0x30] 0xe001 - - - ######################## - - # turn on icache - set I bit in cp15 register c1 - arm mcr 15 0 0 1 0 0x00051078 -} - -# NAND -- socket has two chipselects, MT29F16G08FAA puts 1GByte on each one. -# -# NOTE: "hwecc4" here presumes that if you're using the standard 2GB NAND -# you either (a) have 'new' DM355 chips, with boot ROMs that don't need to -# use "hwecc4_infix" for the UBL; or else (b) aren't updating anything that -# needs infix layout ... like an old UBL, old U-Boot, old MVL kernel, etc. -set _FLASHNAME $_CHIPNAME.boot -nand device $_FLASHNAME davinci $_TARGETNAME 0x02000000 hwecc4 0x01e10000 -set _FLASHNAME $_CHIPNAME.flash -nand device $_FLASHNAME davinci $_TARGETNAME 0x02004000 hwecc4 0x01e10000 - -# FIXME -# - support writing UBL with its header (new layout only with new ROMs) -# - support writing ABL/U-Boot with its header (new layout) diff --git a/tcl/board/dm365evm.cfg b/tcl/board/dm365evm.cfg deleted file mode 100644 index 8f268c455..000000000 --- a/tcl/board/dm365evm.cfg +++ /dev/null @@ -1,147 +0,0 @@ -# DM365 EVM board -- Beta -# http://focus.ti.com/docs/toolsw/folders/print/tmdxevm365.html -# http://support.spectrumdigital.com/boards/evmdm365 - -source [find target/ti_dm365.cfg] - -# NOTE: in Rev C boards, the CPLD ignores SRST from the ARM-20 JTAG -# connector, so it doesn't affect generation of the reset signal. -# Accordingly, resets require something else. ICEpick could do it; -# but its docs aren't generally available. -# -# At this writing, newer boards aren't available ... so assume no SRST. -# Also ICEpick docs aren't available ... so we must use watchdog reset, -# and hope the CPU isn't wedged or in a WFI loop (either of which can -# block access to CPU and thus watchdog registers). - -reset_config trst_only -$_TARGETNAME configure -event reset-assert "davinci_wdog_reset" - -# SW5.1 routes CS0: NAND vs OneNAND. -# SW4.6:4 controls AEMIF width (8 for NAND, 16 for OneNand) -# for boot-from-flash, those must agree with SW4.3:1 settings. - -if { [info exists CS0MODE] } { - # NAND or OneNAND - set CS0 $CS0MODE -} else { - set CS0 "" - echo "WARNING: CS0 configuration not known" - proc cs0_setup {a_emif} {} - proc flashprobe {} {} -} - -set a_emif [dict get $dm365 a_emif] - -# As shipped: boot from NAND. -if { $CS0 == "NAND" } { - echo "CS0 NAND" - - # NAND socket has two chipselects. Default MT29F16G08FAA chip - # has 1GByte on each one. - # NOTE: "hwecc4" here presumes that you're not updating anything - # that needs infix layout (e.g. UBL, old U-Boot, etc) - nand device low davinci $_TARGETNAME 0x02000000 hwecc4 $a_emif - nand device high davinci $_TARGETNAME 0x02004000 hwecc4 $a_emif - - proc cs0_setup {a_emif} { - global dm365 - - # 8 bit EMIF - davinci_pinmux $dm365 2 0x00000016 - - # slow/pessimistic timings - set nand_timings 0x40400204 - # fast (25% faster page reads) - #set nand_timings 0x0400008c - - # CS0 == socketed NAND (default MT29F16G08FAA, 2 GBytes) - mww [expr $a_emif + 0x10] $nand_timings - - # NANDFCR -- CS0 has NAND - mww [expr $a_emif + 0x60] 0x01 - } - proc flashprobe {} { - nand probe 0 - nand probe 1 - } - -} elseif { $CS0 == "OneNAND" } { - echo "CS0 OneNAND" - - # No support for this OneNAND in OpenOCD (yet) or Linux ... - # REVISIT OneNAND timings not verified to work! - echo "WARNING -- OneNAND not yet tested!" - - proc cs0_setup {a_emif} { - global dm365 - - # 16 bit EMIF - davinci_pinmux $dm365 2 0x00000055 - - # CS0 == OneNAND (KFG1G16U2B-DIB6, 128 KBytes) - mww [expr $a_emif + 0x10] 0x00000001 - - # ONENANDCTRL -- CS0 has OneNAND, enable sync reads - mww [expr $a_emif + 0x5c] 0x0441 - } - proc flashprobe {} { } -} - -# NOTE: disable or replace this call to dm365evm_init if you're -# debugging new UBL/NANDboot code from SRAM. -$_TARGETNAME configure -event reset-init { dm365evm_init } - -# -# This post-reset init is called when the MMU isn't active, all IRQs -# are disabled, etc. It should do most of what a UBL does, except for -# loading code (like U-Boot) into DRAM and running it. -# -proc dm365evm_init {} { - global dm365 - - echo "Initialize DM365 EVM board" - - # CLKIN = 24 MHz ... can't talk quickly to ARM yet - adapter_khz 1500 - - # FIXME -- PLL init - - ######################## - # PINMUX setup - - davinci_pinmux $dm365 0 0x00fd0000 - davinci_pinmux $dm365 1 0x00145555 - # mux2 controls AEMIF ... 8 bit for NAND, 16 for OneNand - davinci_pinmux $dm365 3 0x375affff - davinci_pinmux $dm365 4 0x55556555 - - ######################## - # PSC setup (minimal) - - # DDR EMIF/13, AEMIF/14, UART0/19 - psc_enable 13 - psc_enable 14 - psc_enable 19 - psc_go - - # FIXME setup DDR2 (needs PLL) - - ######################## - # ASYNC EMIF - - set a_emif [dict get $dm365 a_emif] - - # AWCCR - mww [expr $a_emif + 0x04] 0xff - # CS0 == NAND or OneNAND - cs0_setup $a_emif - # CS1 == CPLD - mww [expr $a_emif + 0x14] 0x00a00505 - - # FIXME setup UART0 - - flashprobe -} - - diff --git a/tcl/board/dm6446evm.cfg b/tcl/board/dm6446evm.cfg deleted file mode 100644 index 0d2f6a4d2..000000000 --- a/tcl/board/dm6446evm.cfg +++ /dev/null @@ -1,75 +0,0 @@ -# DM6446 EVM board -# http://focus.ti.com/docs/toolsw/folders/print/tmdsevm6446.html -# http://c6000.spectrumdigital.com/davincievm/ -# EVM is just the board; buy that at Spectrum. -# The "kit" from TI also has: video camera, LCD video monitor, more. - -source [find target/ti_dm6446.cfg] - -# J4 controls what CS2 hooks up to, usually NOR or NAND flash. -# S3.1/S3.2 controls boot mode, which may force J4 and S3.3 settings. -# S3.3 controls AEMIF bus width. - -if { [info exists J4_OPTION] } { - # NOR, NAND, SRAM, ... - set CS2_MODE $J4_OPTION -} else { - set CS2_MODE "" -} - -# ARM boot: -# S3.1 = 0, S3.2 = 0 ==> ROM/UBL boot via NAND (J4 == NAND) -# S3.1 = 1, S3.2 = 0 ==> AEMIF boot (J4 == NOR or SRAM) -# S3.1 = 0, S3.2 = 1 ==> ROM/UBL boot via HPI -# S3.1 = 1, S3.2 = 1 ==> ROM/UBL boot via UART (J4 == don't care) -# AEMIF bus width: -# S3.3 = 0 ==> 8 bit bus width -# S3.3 = 1 ==> 16 bit bus width -# DSP boot: -# S3.4 = 0 ==> controlled by ARM - -if { $CS2_MODE == "NOR" } { - # 16 Mbytes address space; 16 bit bus width - # (older boards used 32MB parts, with upper 16 MB unusable) - set _FLASHNAME $_CHIPNAME.flash - flash bank $_FLASHNAME cfi 0x02000000 0x01000000 2 2 $_TARGETNAME - proc flashprobe {} { flash probe 0 } -} elseif { $CS2_MODE == "NAND" } { - # 64 Mbyte small page; 8 bit bus width - nand device davinci $_TARGETNAME 0x02000000 hwecc1 0x01e00000 - proc flashprobe {} { nand probe 0 } -} elseif { $CS2_MODE == "SRAM" } { - # 4 Mbyte address space; 16 bit bus width - # loaded via JTAG or HPI - proc flashprobe {} {} -} else { - # maybe it's HPI boot? can't tell... - echo "WARNING: CS2/flash configuration not recognized" - proc flashprobe {} {} -} - -# NOTE: disable or replace this call to dm6446evm_init if you're -# debugging new UBL code from SRAM (for NAND boot). -$_TARGETNAME configure -event reset-init { dm6446evm_init } - -# -# This post-reset init is called when the MMU isn't active, all IRQs -# are disabled, etc. It should do most of what a UBL does, except for -# loading code (like U-Boot) into DRAM and running it. -# -proc dm6446evm_init {} { - - echo "Initialize DM6446 EVM board" - - # FIXME initialize everything: - # - PLL1 - # - PLL2 - # - PINMUX - # - PSC - # - DDR - # - AEMIF - # - UART0 - # - icache - - flashprobe -} diff --git a/tcl/board/dp_busblaster_v3.cfg b/tcl/board/dp_busblaster_v3.cfg deleted file mode 100644 index f21197b73..000000000 --- a/tcl/board/dp_busblaster_v3.cfg +++ /dev/null @@ -1,13 +0,0 @@ -# -# Dangerous Prototypes - Bus Blaster -# -# http://dangerousprototypes.com/docs/Bus_Blaster -# -# To reprogram the on-board CPLD do: -# openocd -f board/dp_busblaster_v3.cfg -c "adapter_khz 1000; init; svf ; shutdown" -# - -source [find interface/ftdi/dp_busblaster.cfg] -ftdi_channel 1 - -jtag newtap xc2c32a tap -expected-id 0x06e1c093 -irlen 8 diff --git a/tcl/board/efikamx.cfg b/tcl/board/efikamx.cfg deleted file mode 100644 index 007b312be..000000000 --- a/tcl/board/efikamx.cfg +++ /dev/null @@ -1,10 +0,0 @@ -# Genesi USA EfikaMX -# http://www.genesi-usa.com/products/efika - -# Fall back to 6MHz if RTCK is not supported -jtag_rclk 6000 -$_TARGETNAME configure -event "reset-start" { jtag_rclk 6000 } - -source [find target/imx51.cfg] - -reset_config trst_only diff --git a/tcl/board/efm32.cfg b/tcl/board/efm32.cfg deleted file mode 100644 index d2bc9a611..000000000 --- a/tcl/board/efm32.cfg +++ /dev/null @@ -1,11 +0,0 @@ -# Configuration for EFM32 boards with on-board SEGGER J-Link -# -# Tested with Tiny, Giant and Zero Gecko Starter Kit. -# - -source [find interface/jlink.cfg] -transport select swd -adapter_khz 1000 - -set CHIPNAME efm32 -source [find target/efm32.cfg] diff --git a/tcl/board/eir.cfg b/tcl/board/eir.cfg deleted file mode 100644 index a014e116b..000000000 --- a/tcl/board/eir.cfg +++ /dev/null @@ -1,94 +0,0 @@ -# Elector Internet Radio board -# http://www.ethernut.de/en/hardware/eir/index.html - -source [find target/sam7se512.cfg] - -$_TARGETNAME configure -event reset-init { - # WDT_MR, disable watchdog - mww 0xFFFFFD44 0x00008000 - - # RSTC_MR, enable user reset - mww 0xfffffd08 0xa5000001 - - # CKGR_MOR - mww 0xFFFFFC20 0x00000601 - sleep 10 - - # CKGR_PLLR - mww 0xFFFFFC2C 0x00481c0e - sleep 10 - - # PMC_MCKR - mww 0xFFFFFC30 0x00000007 - sleep 10 - - # PMC_IER - mww 0xFFFFFF60 0x00480100 - - # - # Enable SDRAM interface. - # - - # Enable SDRAM control at PIO A. - mww 0xfffff474 0x3f800000 ;# PIO_BSR_OFF - mww 0xfffff404 0x3f800000 ;# PIO_PDR_OFF - - # Enable address bus (A0, A2-A11, A13-A17) at PIO B - mww 0xfffff674 0x0003effd ;# PIO_BSR_OFF - mww 0xfffff604 0x0003effd ;# PIO_PDR_OFF - - # Enable 16 bit data bus at PIO C - mww 0xfffff870 0x0000ffff ;# PIO_ASR_OFF - mww 0xfffff804 0x0000ffff ;# PIO_PDR_OFF - - # Enable SDRAM chip select - mww 0xffffff80 0x00000002 ;# EBI_CSA_OFF - - # Set SDRAM characteristics in configuration register. - # Hard coded values for MT48LC32M16A2 with 48MHz CPU. - mww 0xffffffb8 0x2192215a ;# SDRAMC_CR_OFF - sleep 10 - - # Issue 16 bit SDRAM command: NOP - mww 0xffffffb0 0x00000011 ;# SDRAMC_MR_OFF - mww 0x20000000 0x00000000 - - # Issue 16 bit SDRAM command: Precharge all - mww 0xffffffb0 0x00000012 ;# SDRAMC_MR_OFF - mww 0x20000000 0x00000000 - - # Issue 8 auto-refresh cycles - mww 0xffffffb0 0x00000014 ;# SDRAMC_MR_OFF - mww 0x20000000 0x00000000 - mww 0xffffffb0 0x00000014 ;# SDRAMC_MR_OFF - mww 0x20000000 0x00000000 - mww 0xffffffb0 0x00000014 ;# SDRAMC_MR_OFF - mww 0x20000000 0x00000000 - mww 0xffffffb0 0x00000014 ;# SDRAMC_MR_OFF - mww 0x20000000 0x00000000 - mww 0xffffffb0 0x00000014 ;# SDRAMC_MR_OFF - mww 0x20000000 0x00000000 - mww 0xffffffb0 0x00000014 ;# SDRAMC_MR_OFF - mww 0x20000000 0x00000000 - mww 0xffffffb0 0x00000014 ;# SDRAMC_MR_OFF - mww 0x20000000 0x00000000 - mww 0xffffffb0 0x00000014 ;# SDRAMC_MR_OFF - mww 0x20000000 0x00000000 - - # Issue 16 bit SDRAM command: Set mode register - mww 0xffffffb0 0x00000013 ;# SDRAMC_MR_OFF - mww 0x20000014 0xcafedede - - # Set refresh rate count ??? - mww 0xffffffb4 0x00000013 ;# SDRAMC_TR_OFF - - # Issue 16 bit SDRAM command: Normal mode - mww 0xffffffb0 0x00000010 ;# SDRAMC_MR_OFF - mww 0x20000000 0x00000180 - - # - # Enable external reset key. - # - mww 0xfffffd08 0xa5000001 -} - diff --git a/tcl/board/ek-lm3s1968.cfg b/tcl/board/ek-lm3s1968.cfg deleted file mode 100644 index 8d990b198..000000000 --- a/tcl/board/ek-lm3s1968.cfg +++ /dev/null @@ -1,19 +0,0 @@ -# -# TI/Luminary Stellaris LM3S1968 Evaluation Kits -# -# http://www.ti.com/tool/ek-lm3s1968 -# - -# NOTE: to use J-Link instead of the on-board interface, -# you may also need to reduce adapter_khz to be about 1200. -# source [find interface/jlink.cfg] - -# include the FT2232 interface config for on-board JTAG interface -# NOTE: using the on-board FT2232 JTAG/SWD/SWO interface is optional! -# so is using in JTAG mode, as done here. -source [find interface/ftdi/luminary.cfg] - -# include the target config -set WORKAREASIZE 0x2000 -set CHIPNAME lm3s1968 -source [find target/stellaris.cfg] diff --git a/tcl/board/ek-lm3s3748.cfg b/tcl/board/ek-lm3s3748.cfg deleted file mode 100644 index 36ecfcd32..000000000 --- a/tcl/board/ek-lm3s3748.cfg +++ /dev/null @@ -1,14 +0,0 @@ -# -# TI/Luminary Stellaris lm3s3748 Evaluation Kits -# -# http://www.ti.com/tool/ek-lm3s3748 -# - -# NOTE: using the on-board FT2232 JTAG/SWD/SWO interface is optional! -# so is using it in JTAG mode, as done here. -source [find interface/ftdi/luminary.cfg] - -# 20k working area -set WORKAREASIZE 0x4000 -set CHIPNAME lm3s3748 -source [find target/stellaris.cfg] diff --git a/tcl/board/ek-lm3s6965.cfg b/tcl/board/ek-lm3s6965.cfg deleted file mode 100644 index c7696690d..000000000 --- a/tcl/board/ek-lm3s6965.cfg +++ /dev/null @@ -1,15 +0,0 @@ -# -# TI/Luminary Stellaris LM3S6965 Evaluation Kits -# -# http://www.ti.com/tool/ek-lm3s6965 -# - -# NOTE: using the on-board FT2232 JTAG/SWD/SWO interface is optional! -# so is using it in JTAG mode, as done here. -source [find interface/ftdi/luminary.cfg] - -# 20k working area -set WORKAREASIZE 0x5000 -set CHIPNAME lm3s6965 -# include the target config -source [find target/stellaris.cfg] diff --git a/tcl/board/ek-lm3s811-revb.cfg b/tcl/board/ek-lm3s811-revb.cfg deleted file mode 100644 index 8729f1596..000000000 --- a/tcl/board/ek-lm3s811-revb.cfg +++ /dev/null @@ -1,14 +0,0 @@ -# -# TI/Luminary Stellaris LM3S811 Evaluation Kits (rev B and earlier) -# -# http://www.ti.com/tool/ek-lm3s811 -# - -# NOTE: newer 811-EK boards (rev C and above) shouldn't use this. -# use board/ek-lm3s811.cfg -source [find interface/ftdi/luminary-lm3s811.cfg] - -# include the target config -set WORKAREASIZE 0x2000 -set CHIPNAME lm3s811 -source [find target/stellaris.cfg] diff --git a/tcl/board/ek-lm3s811.cfg b/tcl/board/ek-lm3s811.cfg deleted file mode 100644 index d7fe243e6..000000000 --- a/tcl/board/ek-lm3s811.cfg +++ /dev/null @@ -1,15 +0,0 @@ -# -# TI/Luminary Stellaris LM3S811 Evaluation Kits -# -# http://www.ti.com/tool/ek-lm3s811 -# - -# NOTE: using the on-board FT2232 JTAG/SWD/SWO interface is optional! -# so is using it in JTAG mode, as done here. -# NOTE: older '811-EK boards (before rev C) shouldn't use this. -source [find interface/ftdi/luminary.cfg] - -# include the target config -set WORKAREASIZE 0x2000 -set CHIPNAME lm3s811 -source [find target/stellaris.cfg] diff --git a/tcl/board/ek-lm3s8962.cfg b/tcl/board/ek-lm3s8962.cfg deleted file mode 100644 index d02ce449a..000000000 --- a/tcl/board/ek-lm3s8962.cfg +++ /dev/null @@ -1,15 +0,0 @@ -# -# TI/Luminary Stellaris LM3S8962 Evaluation Kits -# -# http://www.ti.com/tool/ek-lm3s8962 -# - -# NOTE: using the on-board FT2232 JTAG/SWD/SWO interface is optional! -# so is using it in JTAG mode, as done here. -source [find interface/ftdi/luminary.cfg] - -# 64k working area -set WORKAREASIZE 0x10000 -set CHIPNAME lm3s8962 -# include the target config -source [find target/stellaris.cfg] diff --git a/tcl/board/ek-lm3s9b9x.cfg b/tcl/board/ek-lm3s9b9x.cfg deleted file mode 100644 index 6dd7b31a8..000000000 --- a/tcl/board/ek-lm3s9b9x.cfg +++ /dev/null @@ -1,14 +0,0 @@ -# -# TI/Luminary Stellaris LM3S9B9x Evaluation Kits -# -# http://www.ti.com/tool/ek-lm3s9b90 -# http://www.ti.com/tool/ek-lm3s9b92 -# - -# NOTE: using the bundled FT2232 JTAG/SWD/SWO interface is optional! -# so is using in JTAG mode, as done here. -source [find interface/ftdi/luminary-icdi.cfg] - -set WORKAREASIZE 0x4000 -set CHIPNAME lm3s9b9x -source [find target/stellaris.cfg] diff --git a/tcl/board/ek-lm3s9d92.cfg b/tcl/board/ek-lm3s9d92.cfg deleted file mode 100644 index a0253d646..000000000 --- a/tcl/board/ek-lm3s9d92.cfg +++ /dev/null @@ -1,14 +0,0 @@ -# -# TI/Luminary Stellaris LM3S9D92 Evaluation Kits -# -# http://www.ti.com/tool/ek-lm3s9d92 -# - -# NOTE: using the bundled FT2232 JTAG/SWD/SWO interface is optional! -# so is using in JTAG mode, as done here. -source [find interface/ftdi/luminary-icdi.cfg] - -# 64k working area -set WORKAREASIZE 0x10000 -set CHIPNAME lm3s9d92 -source [find target/stellaris.cfg] diff --git a/tcl/board/ek-lm4f120xl.cfg b/tcl/board/ek-lm4f120xl.cfg deleted file mode 100644 index b2ebfa8cf..000000000 --- a/tcl/board/ek-lm4f120xl.cfg +++ /dev/null @@ -1,17 +0,0 @@ -# -# TI Stellaris Launchpad ek-lm4f120xl Evaluation Kits -# -# http://www.ti.com/tool/ek-lm4f120xl -# - -# -# NOTE: using the bundled ICDI interface is optional! -# This interface is not ftdi based as previous boards were -# -source [find interface/ti-icdi.cfg] - -transport select hla_jtag - -set WORKAREASIZE 0x8000 -set CHIPNAME lm4f120h5qr -source [find target/stellaris.cfg] diff --git a/tcl/board/ek-lm4f232.cfg b/tcl/board/ek-lm4f232.cfg deleted file mode 100644 index 2e3fc7ca1..000000000 --- a/tcl/board/ek-lm4f232.cfg +++ /dev/null @@ -1,17 +0,0 @@ -# -# TI Stellaris LM4F232 Evaluation Kits -# -# http://www.ti.com/tool/ek-lm4f232 -# - -# -# NOTE: using the bundled ICDI interface is optional! -# This interface is not ftdi based as previous boards were -# -source [find interface/ti-icdi.cfg] - -transport select hla_jtag - -set WORKAREASIZE 0x8000 -set CHIPNAME lm4f23x -source [find target/stellaris.cfg] diff --git a/tcl/board/ek-tm4c123gxl.cfg b/tcl/board/ek-tm4c123gxl.cfg deleted file mode 100644 index 4fc1050c7..000000000 --- a/tcl/board/ek-tm4c123gxl.cfg +++ /dev/null @@ -1,13 +0,0 @@ -# -# TI Tiva C Series ek-tm4c123gxl Launchpad Evaluation Kit -# -# http://www.ti.com/tool/ek-tm4c123gxl -# - -source [find interface/ti-icdi.cfg] - -transport select hla_jtag - -set WORKAREASIZE 0x8000 -set CHIPNAME tm4c123gh6pm -source [find target/stellaris.cfg] diff --git a/tcl/board/ek-tm4c1294xl.cfg b/tcl/board/ek-tm4c1294xl.cfg deleted file mode 100644 index b3f384c0e..000000000 --- a/tcl/board/ek-tm4c1294xl.cfg +++ /dev/null @@ -1,14 +0,0 @@ -# -# TI Tiva C Series ek-tm4c1294xl Launchpad Evaluation Kit -# -# http://www.ti.com/tool/ek-tm4c1294xl -# - -source [find interface/ti-icdi.cfg] - -transport select hla_jtag - -set WORKAREASIZE 0x8000 -set CHIPNAME tm4c1294ncpdt - -source [find target/stellaris.cfg] diff --git a/tcl/board/embedded-artists_lpc2478-32.cfg b/tcl/board/embedded-artists_lpc2478-32.cfg deleted file mode 100644 index b036cd69c..000000000 --- a/tcl/board/embedded-artists_lpc2478-32.cfg +++ /dev/null @@ -1,154 +0,0 @@ -# Embedded Artists eval board for LPC2478 -# http://www.embeddedartists.com/ - -# Target device: LPC2478 -set CCLK 72000 -source [find target/lpc2478.cfg] - -# Helper -# -proc read_register {register} { - set result "" - mem2array result 32 $register 1 - return $result(0) -} - -proc init_board {} { - # Delays on reset lines - adapter_nsrst_delay 500 - jtag_ntrst_delay 1 - - # Adaptive JTAG clocking through RTCK. - # - jtag_rclk 20 - - global _TARGETNAME - global _CHIPNAME - - # A working area will help speeding the flash programming - $_TARGETNAME configure -work-area-phys 0x40000200 -work-area-size [expr 0x10000-0x200-0x20] -work-area-backup 0 - - # External 16-bit flash at chip select CS0 (SST39VF3201-70, 4 MiB) - flash bank $_CHIPNAME.extflash cfi 0x80000000 0x400000 2 2 $_TARGETNAME jedec_probe - - # Event handlers - # - $_TARGETNAME configure -event reset-start { - # Back to the slow JTAG clock - jtag_rclk 20 - } - - $_TARGETNAME configure -event reset-init { - arm core_state arm - arm7_9 dcc_downloads enable ;# Speed up downloads by using DCC transfer - arm7_9 fast_memory_access enable - - # Peripheral clocks - mww 0xE01FC0C4 0x04280FFE ;# PCONP: (reset value) - - # Map the user flash to the vector table area (0x00...0x3F) - mww 0xE01FC040 0x00000001 ;# MEMMAP: User flash - - # Memory accelerator module - mww 0xE01FC004 0x00000003 ;# MAMTIM: 3 clock cycles - mww 0xE01FC000 0x00000002 ;# MAMCR: fully enabled - - # Enable external memory bus (32-bit SDRAM at DYCS0, 16-bit flash at CS0) - mww 0xE002C014 0x55010115 ;# PINSEL5: P2.16=CAS, P2.17=RAS, P2.18=CLKOUT0, - # P2.20=DYCS0, P2.24=CKEOUT0, P2.28=DQMOUT0, - # P2.29=DQMOUT1, P2.30=DQMOUT2, P2.31=DQMOUT3 - mww 0xE002C018 0x55555555 ;# PINSEL6: P3.0...P3.15=D0...D15 - mww 0xE002C01C 0x55555555 ;# PINSEL7: P3.16...P3.31=D16...D31 - mww 0xE002C020 0x55555555 ;# PINSEL8: P4.0...P4.15=A0...A15 - mww 0xE002C024 0x50051555 ;# PINSEL9: P4.16...P4.22=A16...A22, P4.24=OE, - # P4.25=WE, P4.30=CS0, P4.31=CS1 - mww 0xFFE08000 0x00000001 ;# EMCControl: Enable EMC - - # Start PLL, then use faster JTAG clock - enable_pll - jtag_rclk 3000 - - # 16-bit flash @ CS0 (SST39VF3201-70) - mww 0xFFE08200 0x00080081 ;# EMCStaticConfig0: 16 bit, PB=1, buffers on - mww 0xFFE08204 0x00000000 ;# EMCStaticWaitWen0 - mww 0xFFE08208 0x00000000 ;# EMCStaticWaitOen0 - mww 0xFFE0820C 0x00000005 ;# EMCStaticWaitRd0 - mww 0xFFE08210 0x00000005 ;# EMCStaticWaitPage0 - mww 0xFFE08214 0x00000003 ;# EMCStaticWaitWr0 - mww 0xFFE08218 0x00000001 ;# EMCStaticWaitTurn0 - - # 8-bit NAND @ CS1 - # TODO - - # 32-bit SDRAM @ DYCS0 (K4M563233G-HN75) - mww 0xFFE08028 0x00000001 ;# EMCDynamicReadConfig - mww 0xFFE08030 0x00000001 ;# EMCDynamicRP - mww 0xFFE08034 0x00000003 ;# EMCDynamicRAS - mww 0xFFE08038 0x00000005 ;# EMCDynamicSREX - mww 0xFFE0803C 0x00000001 ;# EMCDynamicAPR - mww 0xFFE08040 0x00000005 ;# EMCDynamicDAL - mww 0xFFE08044 0x00000001 ;# EMCDynamicWR - mww 0xFFE08048 0x00000005 ;# EMCDynamicRC - mww 0xFFE0804C 0x00000005 ;# EMCDynamicRFC - mww 0xFFE08050 0x00000005 ;# EMCDynamicXSR - mww 0xFFE08054 0x00000001 ;# EMCDynamicRRD - mww 0xFFE08058 0x00000001 ;# EMCDynamicMRD - # - mww 0xFFE08104 0x00000202 ;# EMCDynamicRasCas0 - mww 0xFFE08100 0x00005488 ;# EMCDynamicConfig0 - sleep 100 - mww 0xFFE08020 0x00000183 ;# EMCDynamicControl: Clock on continuously, NOP - sleep 10 - mww 0xFFE08020 0x00000103 ;# EMCDynamicControl: PRECHARGE-ALL - mww 0xFFE08024 0x00000046 ;# EMCDynamicRefresh - sleep 100 - mww 0xFFE08020 0x00000083 ;# EMCDynamicControl: MODE - mdw 0xA0011000 1 ;# Set SDRAM mode register - mww 0xFFE08020 0x00000000 ;# EMCDynamicControl: NORMAL - mww 0xFFE08100 0x00085488 ;# EMCDynamicConfig0: Enable buffers - } - - $_TARGETNAME configure -event gdb-attach { - # Without this gdb-attach will first time as probe will fail - reset init - } -} - -# Enable the PLL. -# Generate maximum CPU clock (72 MHz) Run from internal RC oscillator. -# Note: The PLL output runs at a frequency N times the desired CPU clock. -# It in unavoidable that the CPU clock drops down to (4 MHz/N) during -# the initialization! -# Here: N=4 -# Note that if the PLL is already active at the time this script is -# called, the effective value of N is the value of CCLKCFG at that time! -# -proc enable_pll {} { - # Disconnect PLL in case it is already connected - if {[expr [read_register 0xE01FC080] & 0x03] == 3} { - # Disconnect it, but leave it enabled - # (This MUST be done in two steps) - mww 0xE01FC080 0x00000001 ;# PLLCON: disconnect PLL - mww 0xE01FC08C 0x000000AA ;# PLLFEED - mww 0xE01FC08C 0x00000055 ;# PLLFEED - } - # Disable PLL (as it might already be enabled at this time!) - mww 0xE01FC080 0x00000000 ;# PLLCON: disable PLL - mww 0xE01FC08C 0x000000AA ;# PLLFEED - mww 0xE01FC08C 0x00000055 ;# PLLFEED - - # Setup PLL to generate 288 MHz from internal RC oscillator - mww 0xE01FC10C 0x00000000 ;# CLKSRCSEL: IRC - mww 0xE01FC084 0x00000023 ;# PLLCFG: N=1, M=36 - mww 0xE01FC08C 0x000000AA ;# PLLFEED - mww 0xE01FC08C 0x00000055 ;# PLLFEED - mww 0xE01FC080 0x00000001 ;# PLLCON: enable PLL - mww 0xE01FC08C 0x000000AA ;# PLLFEED - mww 0xE01FC08C 0x00000055 ;# PLLFEED - sleep 100 - mww 0xE01FC104 0x00000003 ;# CCLKCFG: divide by 4 (72 MHz) - mww 0xE01FC080 0x00000003 ;# PLLCON: connect PLL - mww 0xE01FC08C 0x000000AA ;# PLLFEED - mww 0xE01FC08C 0x00000055 ;# PLLFEED -} - diff --git a/tcl/board/emcraft_twr-vf6-som-bsb.cfg b/tcl/board/emcraft_twr-vf6-som-bsb.cfg deleted file mode 100644 index 3818b6793..000000000 --- a/tcl/board/emcraft_twr-vf6-som-bsb.cfg +++ /dev/null @@ -1,9 +0,0 @@ -# -# EmCraft Systems TWR-VF6-SOM-BSB -# -# http://www.emcraft.com/products/259#twr-kit -# - -source [find board/emcraft_vf6-som.cfg] - -reset_config srst_only srst_nogate diff --git a/tcl/board/emcraft_vf6-som.cfg b/tcl/board/emcraft_vf6-som.cfg deleted file mode 100644 index 558651683..000000000 --- a/tcl/board/emcraft_vf6-som.cfg +++ /dev/null @@ -1,8 +0,0 @@ -# -# EmCraft Systems Vybrid VF6 SOM -# -# http://www.emcraft.com/products/259#som -# - -set CHIPNAME vf610 -source [find target/vybrid_vf6xx.cfg] diff --git a/tcl/board/ethernut3.cfg b/tcl/board/ethernut3.cfg deleted file mode 100644 index ad4552733..000000000 --- a/tcl/board/ethernut3.cfg +++ /dev/null @@ -1,86 +0,0 @@ -# -# Ethernut 3 board configuration file -# -# http://www.ethernut.de/en/hardware/enut3/ - - -# AT91R40008-66AU ARM7TDMI Microcontroller -# 256kB internal RAM -source [find target/at91r40008.cfg] - - -# AT49BV322A-70TU NOR Flash -# 2M x 16 mode at address 0x10000000 -# Common flash interface supported -# -set _FLASHNAME $_CHIPNAME.flash -flash bank $_FLASHNAME cfi 0x10000000 0x400000 2 2 $_TARGETNAME - - -# Micrel MIC2775-29YM5 Supervisor -# Reset output will remain active for 280ms (maximum) -# -adapter_nsrst_delay 300 -jtag_ntrst_delay 300 - - -arm7_9 fast_memory_access enable -arm7_9 dcc_downloads enable -adapter_khz 16000 - - -# Target events -# -$_TARGETNAME configure -event reset-init { board_init } - -# Initialize board hardware -# -proc board_init { } { - board_remap - flash probe 0 -} - -# Memory remap -# -proc board_remap {{VERBOSE 0}} { - # CS0: NOR flash - # 16MB @ 0x10000000 - # 16-bit data bus - # 4 wait states - # - mww 0xffe00000 0x1000212d - - # CS1: Ethernet controller - # 1MB @ 0x20000000 - # 16-bit data bus - # 2 wait states - # Byte select access - # - mww 0xffe00004 0x20003025 - - # CS2: CPLD registers - # 1MB @ 0x21000000 - # 8-bit data bus - # 2 wait states - # - mww 0xffe00008 0x21002026 - - # CS3: Expansion bus - # 1MB @ 0x22000000 - # 8-bit data bus - # 8 wait states - # - mww 0xffe00010 0x22002e3e - - # Remap command - # - mww 0xffe00020 0x00000001 - - if {$VERBOSE != 0} { - echo "0x00000000 RAM" - echo "0x10000000 Flash" - echo "0x20000000 Ethernet" - echo "0x21000000 CPLD" - echo "0x22000000 Expansion" - } -} diff --git a/tcl/board/frdm-kl25z.cfg b/tcl/board/frdm-kl25z.cfg deleted file mode 100644 index 89ee32dee..000000000 --- a/tcl/board/frdm-kl25z.cfg +++ /dev/null @@ -1,15 +0,0 @@ -# This is an Freescale Freedom eval board with a single MKL25Z128VLK4 chip. -# http://www.freescale.com/webapp/sps/site/prod_summary.jsp?code=FRDM-KL25Z -# - -source [find interface/cmsis-dap.cfg] - -# increase working area to 16KB -set WORKAREASIZE 0x4000 - -# chip name -set CHIPNAME MKL25Z128VLK4 - -reset_config srst_only - -source [find target/kl25.cfg] diff --git a/tcl/board/frdm-kl46z.cfg b/tcl/board/frdm-kl46z.cfg deleted file mode 100644 index eee4d8ead..000000000 --- a/tcl/board/frdm-kl46z.cfg +++ /dev/null @@ -1,15 +0,0 @@ -# This is an Freescale Freedom eval board with a single MKL46Z256VLL4 chip. -# http://www.freescale.com/webapp/sps/site/prod_summary.jsp?code=FRDM-KL46Z -# - -source [find interface/cmsis-dap.cfg] - -# increase working area to 16KB -set WORKAREASIZE 0x4000 - -# chip name -set CHIPNAME MKL46Z256VLL4 - -reset_config srst_only - -source [find target/kl46.cfg] diff --git a/tcl/board/fsl_imx6q_sabresd.cfg b/tcl/board/fsl_imx6q_sabresd.cfg deleted file mode 100644 index 797e2de5f..000000000 --- a/tcl/board/fsl_imx6q_sabresd.cfg +++ /dev/null @@ -1,149 +0,0 @@ -# -# Board configuration file for the Freescale IMX6Q Sabre SD EVM -# -# This board does not have an embedded JTAG adapter, you must source -# a suitable adapter configuration before sourcing this file. - -# Sabre SD has a standard ARM-20 JTAG connector with -# nTRST and nSRST available. -reset_config trst_and_srst - -# the only possible transport is JTAG -transport select jtag - -# iMX6Q POR gates JTAG and the chip is completely incommunicado -# over JTAG for at least 10ms after nSRST is deasserted -adapter_nsrst_delay 11 - -# Source generic iMX6Q target configuration -set CHIPNAME imx6q -source [find target/imx6.cfg] - -# function to apply initial configuration after a reset. It -# provides a basic pad configuration and also DDR memory and clocks -# sufficient to load and execute a boot loader (e.g. barebox) from -# DDR memory. This list is extracted from the barebox flash image -# header. -proc apply_dcd { } { - mww 0x020e05a8 0x00000030 - mww 0x020e05b0 0x00000030 - mww 0x020e0524 0x00000030 - mww 0x020e051c 0x00000030 - mww 0x020e0518 0x00000030 - mww 0x020e050c 0x00000030 - mww 0x020e05b8 0x00000030 - mww 0x020e05c0 0x00000030 - mww 0x020e05ac 0x00020030 - mww 0x020e05b4 0x00020030 - mww 0x020e0528 0x00020030 - mww 0x020e0520 0x00020030 - mww 0x020e0514 0x00020030 - mww 0x020e0510 0x00020030 - mww 0x020e05bc 0x00020030 - mww 0x020e05c4 0x00020030 - mww 0x020e056c 0x00020030 - mww 0x020e0578 0x00020030 - mww 0x020e0588 0x00020030 - mww 0x020e0594 0x00020030 - mww 0x020e057c 0x00020030 - mww 0x020e0590 0x00003000 - mww 0x020e0598 0x00003000 - mww 0x020e058c 0x00000000 - mww 0x020e059c 0x00003030 - mww 0x020e05a0 0x00003030 - mww 0x020e0784 0x00000030 - mww 0x020e0788 0x00000030 - mww 0x020e0794 0x00000030 - mww 0x020e079c 0x00000030 - mww 0x020e07a0 0x00000030 - mww 0x020e07a4 0x00000030 - mww 0x020e07a8 0x00000030 - mww 0x020e0748 0x00000030 - mww 0x020e074c 0x00000030 - mww 0x020e0750 0x00020000 - mww 0x020e0758 0x00000000 - mww 0x020e0774 0x00020000 - mww 0x020e078c 0x00000030 - mww 0x020e0798 0x000c0000 - mww 0x021b081c 0x33333333 - mww 0x021b0820 0x33333333 - mww 0x021b0824 0x33333333 - mww 0x021b0828 0x33333333 - mww 0x021b481c 0x33333333 - mww 0x021b4820 0x33333333 - mww 0x021b4824 0x33333333 - mww 0x021b4828 0x33333333 - mww 0x021b0018 0x00081740 - mww 0x021b001c 0x00008000 - mww 0x021b000c 0x555a7975 - mww 0x021b0010 0xff538e64 - mww 0x021b0014 0x01ff00db - mww 0x021b002c 0x000026d2 - mww 0x021b0030 0x005b0e21 - mww 0x021b0008 0x09444040 - mww 0x021b0004 0x00025576 - mww 0x021b0040 0x00000027 - mww 0x021b0000 0x831a0000 - mww 0x021b001c 0x04088032 - mww 0x021b001c 0x0408803a - mww 0x021b001c 0x00008033 - mww 0x021b001c 0x0000803b - mww 0x021b001c 0x00428031 - mww 0x021b001c 0x00428039 - mww 0x021b001c 0x09408030 - mww 0x021b001c 0x09408038 - mww 0x021b001c 0x04008040 - mww 0x021b001c 0x04008048 - mww 0x021b0800 0xa1380003 - mww 0x021b4800 0xa1380003 - mww 0x021b0020 0x00005800 - mww 0x021b0818 0x00022227 - mww 0x021b4818 0x00022227 - mww 0x021b083c 0x434b0350 - mww 0x021b0840 0x034c0359 - mww 0x021b483c 0x434b0350 - mww 0x021b4840 0x03650348 - mww 0x021b0848 0x4436383b - mww 0x021b4848 0x39393341 - mww 0x021b0850 0x35373933 - mww 0x021b4850 0x48254A36 - mww 0x021b080c 0x001f001f - mww 0x021b0810 0x001f001f - mww 0x021b480c 0x00440044 - mww 0x021b4810 0x00440044 - mww 0x021b08b8 0x00000800 - mww 0x021b48b8 0x00000800 - mww 0x021b001c 0x00000000 - mww 0x021b0404 0x00011006 - mww 0x020c4068 0x00c03f3f - mww 0x020c406c 0x0030fc03 - mww 0x020c4070 0x0fffc000 - mww 0x020c4074 0x3ff00000 - mww 0x020c4078 0x00fff300 - mww 0x020c407c 0x0f0000c3 - mww 0x020c4080 0x000003ff - mww 0x020e0010 0xf00000cf - mww 0x020e0018 0x007f007f - mww 0x020e001c 0x007f007f -} - -# disable watchdog -proc disable_wdog { } { - mwh 0x020bc000 0x30 -} - -# This function applies the initial configuration after a "reset init" -# command -proc imx6q_sabresd_init { } { - disable_wdog - apply_dcd -} - -# prevent cortex-a code from asserting SRST again -$_TARGETNAME.0 configure -event reset-assert { } -# hook the init function into the reset-init event -$_TARGETNAME.0 configure -event reset-init { imx6q_sabresd_init } -# make sure target is halted when gdb attaches -$_TARGETNAME.0 configure -event gdb-attach { halt } -# set a slow default JTAG clock, can be overridden later -adapter_khz 1000 diff --git a/tcl/board/glyn_tonga2.cfg b/tcl/board/glyn_tonga2.cfg deleted file mode 100644 index 17ed3cf20..000000000 --- a/tcl/board/glyn_tonga2.cfg +++ /dev/null @@ -1,200 +0,0 @@ -# -# Glyn Tonga2 SO-DIMM CPU module (Toshiba TMPA900CMXBG, ARM9) -# -# http://toshiba-mikrocontroller.de/sites/TMPA900CPUBOARDStarter.htm -# -# Hardware on the S0-DIMM module: -# - Toshiba TMPA900CMXBG (ARM9, ARM926EJ-S, max. 200MHz) -# - DDR SDRAM: Hynix H5MS5162DFR-J3M (64Mbyte, x16, 1.8V, 166/83MHz at CL3/2) -# - NAND flash: Samsung K9F2G08U0B-PIB0 (256M x 8 Bit, 3.3V) -# - Ethernet: SMSC LAN9221I-ABZJ (10/100Mbit, Non-PCI, 16 bit interface) -# - -source [find target/tmpa900.cfg] - -######################## -# Target configuration # -######################## - -# Initial JTAG speed should not exceed 1/6 of the initial CPU clock -# frequency (24MHz). Be conservative and use 1/8 of the frequency. -# (24MHz / 8 = 3MHz) -adapter_khz 3000 - -$_TARGETNAME configure -event reset-start { - # Upon reset, set the JTAG frequency to 3MHz again, see above. - echo "Setting JTAG speed to 3MHz until clocks are initialized." - adapter_khz 3000 - - # Halt the CPU. - halt - - # Disable faster memory access for now. - arm7_9 fast_memory_access disable -} - -$_TARGETNAME configure -event reset-init { - # Setup clocks, and initialize SRAM and DDR SDRAM. - tonga2_init - - # At this point the CPU is running at 192MHz, increase JTAG speed. - # Tests showed that 15MHz works OK, higher speeds can cause problems, - # though. Not sure if this is a CPU issue or JTAG adapter issue. - echo "Increasing JTAG speed to 15MHz." - adapter_khz 15000 - - # Enable faster memory access. - arm7_9 fast_memory_access enable -} - -proc tonga2_init { } { - ###################### - # PLL initialization # - ###################### - - # Clock overview (see datasheet chapter 3.5.2, page 57): - # - fs: Low-frequency oscillator - # - fOSCH: High-frequency oscillator (24MHz on this board) - # - fPLL = fOSCH * multiplier (where multiplier can be 6 or 8) - # - fFCLK = fPLL / gear (where gear can be 1/2/4/8) - # - fHCLK is always fFCLK/2. fPCLK is also fFCLK/2. - # - # We select multiplier = 8 and gear = 1, so - # fFCLK = fOSCH * 8 / 1 = 192MHz. - - # SYSCR3 (System Control Register 3): Disable and configure PLL. - # - PLL operation control: off - # - PLL constant value setting 1: always 0, as per datasheet - # - PLL constant value setting 2: x8 (multiplier = 8) - mww 0xf005000c 0x00000007 - - # SYSCR4 (System Control Register 4): Configure PLL. - # - PLL constant value setting 3: 140MHz or more - # - PLL constant value setting 4: always 1, as per datasheet - # - PLL constant value setting 5: 140MHz or more - mww 0xf0050010 0x00000065 - - # SYSCR3 (System Control Register 3): Enable PLL. - # - PLL operation control: on - # - All other bits remain set as above. - mww 0xf005000c 0x00000087 - - # Wait for PLL to stabilize. - sleep 10 - - # SYSCR2 (System Control Register 2): Switch from fOSCH to fPLL. - # - Selection of the PLL output clock: fPLL - mww 0xf0050008 0x00000002 - - # SYSCR1 (System Control Register 1): - # - Clock gear programming: fc/1 (i.e., gear = 1, don't divide). - mww 0xf0050004 0x00000000 - - # CLKCR5 (Clock Control Register 5): Set bits 3 and 6. The datasheet - # says the bits are reserved, but also recommends "Write as one". - mww 0xf0050054 0x00000048 - - - ############################################################## - # Dynamic Memory Controller (DMC) / DDR SDRAM initialization # - ############################################################## - - # PMC (Power Management Controller): - # PMCDRV (External Port "Driverbility" control register): - # Bits DRV_MEM0/DRV_MEM1 (memory relation port drive power): - mww 0xf0020260 0x00000003 ;# Select 1.8V +/- 0.1V - - # Setup DDR SDRAM timing parameters for our specific chip. - mww 0xf4310014 0x00000004 ;# cas_latency = 2 - mww 0xf4310018 0x00000001 ;# t_dqss = 1 - mww 0xf431001c 0x00000002 ;# t_mrd = 2 - mww 0xf4310020 0x0000000a ;# t_ras = 10 - mww 0xf4310024 0x0000000a ;# t_rc = 10 - mww 0xf4310028 0x00000013 ;# t_rcd = 3, schedule_rcd = 2 - mww 0xf431002c 0x0000010a ;# t_rfc = 10, schedule_rfc = 8 - mww 0xf4310030 0x00000013 ;# t_rp = 3, schedule_rp = 2 - mww 0xf4310034 0x00000002 ;# t_rrd = 2 - mww 0xf4310038 0x00000002 ;# t_wr = 2 - mww 0xf431003c 0x00000001 ;# t_wtr = 1 - mww 0xf4310040 0x0000000a ;# t_xp = 10 - mww 0xf4310044 0x0000000c ;# t_xsr = 12 - mww 0xf4310048 0x00000014 ;# t_esr = 20 - - # dmc_memory_cfg_5 (DMC Memory Configuration register): - # Set memory configuration: - # column_bits = 10, row_bits = 13, ap-bit = 10, power_down_prd = 0, - # auto_power_down = disable, stop_mem_clock = disable, memory_burst = 4 - mww 0xf431000c 0x00010012 - - # dmc_user_config_5 (DMC user_config register): - # Data bus width of DDR SDRAM: 16 bit - mww 0xf4310304 0x00000058 - - # dmc_refresh_prd_5 (DMC Refresh Period register): - # Auto refresh: every 2656 (0xa60) DMCSCLK periods. - mww 0xf4310010 0x00000a60 - - # dmc_chip_0_cfg_5 (DMC chip_0_cfg registers): - # - SDRAM address structure: bank, row, column - # - address_match = 01000000 (start address [31:24]) - # - address_mask = 11111100 (start address [31:24] mask value) - mww 0xf4310200 0x000140fc - - # Initialize the DDR SDRAM chip. - # dmc_direct_cmd_5 (DMC Direct Command register). - # See datasheet chapter 3.10.5.1, page 268. - mww 0xf4310008 0x000c0000 ;# RAM init: NOP - mww 0xf4310008 0x00000000 ;# RAM init: Precharge all - mww 0xf4310008 0x00040000 ;# RAM init: Autorefresh - mww 0xf4310008 0x00040000 ;# RAM init: Autorefresh - mww 0xf4310008 0x00080032 ;# RAM init: addr_13_to_0 = 0x32 - mww 0xf4310008 0x000c0000 ;# RAM init: NOP - mww 0xf4310008 0x000a0000 ;# RAM init: bank_addr = bank 2 - - # dmc_id_<0-5>_cfg_5 (DMC id_<0-5>_cfg registers): - # Set min./max. QoS values. - # - 0x5: Enable QoS, max. QoS = 1 - # - 0xb: Enable QoS, min. QoS = 2 - mww 0xf4310100 0x00000005 ;# AHB0: CPU Data - mww 0xf4310104 0x00000005 ;# AHB1: CPU Inst - mww 0xf4310108 0x0000000b ;# AHB2: LCDC - mww 0xf431010c 0x00000005 ;# AHB3: LCDDA, USB - mww 0xf4310110 0x00000005 ;# AHB4: DMA1 - mww 0xf4310114 0x00000005 ;# AHB5: DMA2 - - # dmc_memc_cmd_5 (DMC Memory Controller Command register): - # Change DMC state to ready. - mww 0xf4310004 0x00000000 ;# memc_cmd = "Go" - - # EBI: SMC Timeout register - mww 0xf00a0050 0x00000001 ;# smc_timeout = 1 - - - ######################################################## - # Static Memory Controller (SMC) / SRAM initialization # - ######################################################## - - # smc_set_cycles_5 (SMC Set Cycles register): - # tRC = 10, tWC = 10, tCEOE = 7, tWP = 5, tPC=2, tTR=2 - mww 0xf4311014 0x0004afaa - - # smc_set_opmode_5 (SMC Set Opmode register): - # Memory data bus width = 16 bits, async read mode, read burst - # length = 1 beat, async write mode, write burst length = 1 beat, - # byte enable (SMCBE0-1) timing = SMCCSn timing, memory burst boundary - # split setting = burst can cross any address boundary - mww 0xf4311018 0x00000001 - - # smc_direct_cmd_5 (SMC Direct Command register): - # cmd_type = UpdateRegs, chip_select = CS1 - mww 0xf4311010 0x00c00000 - - echo "Clocks, SRAM, and DDR SDRAM are now initialized." -} - -####################### -# Flash configuration # -####################### - -# TODO: Implement NAND support. - diff --git a/tcl/board/gumstix-aerocore.cfg b/tcl/board/gumstix-aerocore.cfg deleted file mode 100644 index ba217c043..000000000 --- a/tcl/board/gumstix-aerocore.cfg +++ /dev/null @@ -1,10 +0,0 @@ -# JTAG for the STM32F4x chip used on the Gumstix AeroCore is available on -# the first interface of a Quad FTDI chip. nTRST is bit 4. -interface ftdi -ftdi_vid_pid 0x0403 0x6011 - -ftdi_layout_init 0x0000 0x001b -ftdi_layout_signal nTRST -data 0x0010 - -source [find target/stm32f4x.cfg] -reset_config trst_only diff --git a/tcl/board/hammer.cfg b/tcl/board/hammer.cfg deleted file mode 100644 index ea3da8123..000000000 --- a/tcl/board/hammer.cfg +++ /dev/null @@ -1,37 +0,0 @@ -# Target Configuration for the TinCanTools S3C2410 Based Hammer Module -# http://www.tincantools.com - -source [find target/samsung_s3c2410.cfg] - -$_TARGETNAME configure -event reset-init { - # Reset Script for the TinCanTools S3C2410 Based Hammer Module - # http://www.tincantools.com - # - # Setup primary clocks and initialize the SDRAM - mww 0x53000000 0x00000000 - mww 0x4a000008 0xffffffff - mww 0x4a00000c 0x000007ff - mww 0x4c000000 0x00ffffff - mww 0x4c000014 0x00000003 - mww 0x4c000004 0x000a1031 - mww 0x48000000 0x11111122 - mww 0x48000004 0x00000700 - mww 0x48000008 0x00000700 - mww 0x4800000c 0x00000700 - mww 0x48000010 0x00000700 - mww 0x48000014 0x00000700 - mww 0x48000018 0x00000700 - mww 0x4800001c 0x00018005 - mww 0x48000020 0x00018005 - mww 0x48000024 0x009c0459 - mww 0x48000028 0x000000b2 - mww 0x4800002c 0x00000030 - mww 0x48000030 0x00000030 - flash probe 0 -} - - -#flash configuration -#flash bank [driver_options ...] -set _FLASHNAME $_CHIPNAME.flash -flash bank $_FLASHNAME cfi 0x00000000 0x1000000 2 2 $_TARGETNAME diff --git a/tcl/board/hilscher_nxdb500sys.cfg b/tcl/board/hilscher_nxdb500sys.cfg deleted file mode 100644 index 77073e729..000000000 --- a/tcl/board/hilscher_nxdb500sys.cfg +++ /dev/null @@ -1,40 +0,0 @@ -################################################################################ -# Author: Michael Trensch (MTrensch@googlemail.com) -################################################################################ - -source [find target/hilscher_netx500.cfg] - -reset_config trst_and_srst -adapter_nsrst_delay 500 -jtag_ntrst_delay 500 - -$_TARGETNAME configure -work-area-virt 0x1000 -work-area-phys 0x1000 -work-area-size 0x4000 -work-area-backup 1 - -$_TARGETNAME configure -event reset-init { - halt - - arm7_9 fast_memory_access enable - arm7_9 dcc_downloads enable - - sdram_fix - - puts "Configuring SDRAM controller for paired K4S561632C (64MB) " - mww 0x00100140 0 - mww 0x00100144 0x03C13261 - mww 0x00100140 0x030D0121 - - puts "Configuring SRAM nCS0 for 150ns paired Par. Flash (x32)" - mww 0x00100100 0x0201000E - - flash probe 0 -} - -##################### -# Flash configuration -##################### - -#flash bank -flash bank parflash cfi 0xC0000000 0x02000000 4 4 $_TARGETNAME - -init -reset init diff --git a/tcl/board/hilscher_nxeb500hmi.cfg b/tcl/board/hilscher_nxeb500hmi.cfg deleted file mode 100644 index 64391561e..000000000 --- a/tcl/board/hilscher_nxeb500hmi.cfg +++ /dev/null @@ -1,40 +0,0 @@ -################################################################################ -# Author: Michael Trensch (MTrensch@googlemail.com) -################################################################################ - -source [find target/hilscher_netx500.cfg] - -reset_config trst_and_srst -adapter_nsrst_delay 500 -jtag_ntrst_delay 500 - -$_TARGETNAME configure -work-area-virt 0x1000 -work-area-phys 0x1000 -work-area-size 0x4000 -work-area-backup 1 - -$_TARGETNAME configure -event reset-init { - halt - - arm7_9 fast_memory_access enable - arm7_9 dcc_downloads disable - - sdram_fix - - puts "Configuring SDRAM controller for MT48LC8M32 (32MB) " - mww 0x00100140 0 - mww 0x00100144 0x03C23251 - mww 0x00100140 0x030D0111 - - puts "Configuring SRAM nCS0 for 150ns Par. Flash (x16)" - mww 0x00100100 0x0101000E - - flash probe 0 -} - -##################### -# Flash configuration -##################### - -#flash bank -flash bank parflash cfi 0xC0000000 0x01000000 2 2 $_TARGETNAME - -init -reset init diff --git a/tcl/board/hilscher_nxhx10.cfg b/tcl/board/hilscher_nxhx10.cfg deleted file mode 100644 index 4ef2f3b96..000000000 --- a/tcl/board/hilscher_nxhx10.cfg +++ /dev/null @@ -1,82 +0,0 @@ -################################################################################ -# Author: Michael Trensch (MTrensch@googlemail.com) -################################################################################ - -source [find target/hilscher_netx10.cfg] - -# Usually it is not needed to set srst_pulls_trst -# but sometimes it does not work without it. If you encounter -# problems try to line below -# reset_config trst_and_srst srst_pulls_trst -reset_config trst_and_srst -adapter_nsrst_delay 500 -jtag_ntrst_delay 500 - -$_TARGETNAME configure -work-area-virt 0x08000000 -work-area-phys 0x08000000 -work-area-size 0x4000 -work-area-backup 1 - -# Par. Flash can only be accessed if DIP switch on the board is set in proper -# position and init_sdrambus was called. Don't call these functions if the DIP -# switch is in invalid position, as some outputs may collide. This is why this -# function is not called automatically -proc flash_init { } { - puts "Configuring SRAM nCS0 for 90ns Par. Flash (x16)" - mww 0x101C0100 0x01010008 - - flash probe 0 -} - -proc mread32 {addr} { - set value(0) 0 - mem2array value 32 $addr 1 - return $value(0) -} - -proc init_clocks { } { - puts "Enabling all clocks " - set accesskey [mread32 0x101c0070] - mww 0x101c0070 [expr $accesskey] - - mww 0x101c0028 0x00007511 -} - -proc init_sdrambus { } { - puts "Initializing external SDRAM Bus 16 Bit " - set accesskey [mread32 0x101c0070] - mww 0x101c0070 [expr $accesskey] - mww 0x101c0C40 0x00000050 - - puts "Configuring SDRAM controller for K4S561632E (32MB) " - mww 0x101C0140 0 - sleep 100 - #mww 0x101C0144 0x00a13262 - mww 0x101C0144 0x00a13251 - mww 0x101C0148 0x00000033 - mww 0x101C0140 0x030d0121 -} - -$_TARGETNAME configure -event reset-init { - halt - wait_halt 1000 - - arm7_9 fast_memory_access enable - arm7_9 dcc_downloads enable - - init_clocks -# init_sdrambus - - puts "" - puts "-------------------------------------------------" - puts "Call 'init_clocks' to enable all clocks" - puts "Call 'init_sdrambus' to enable external SDRAM bus" - puts "-------------------------------------------------" -} - -##################### -# Flash configuration -##################### - -#flash bank -#flash bank parflash cfi 0xC0000000 0x01000000 2 2 $_TARGETNAME - -init -reset init \ No newline at end of file diff --git a/tcl/board/hilscher_nxhx50.cfg b/tcl/board/hilscher_nxhx50.cfg deleted file mode 100644 index eebb16524..000000000 --- a/tcl/board/hilscher_nxhx50.cfg +++ /dev/null @@ -1,40 +0,0 @@ -################################################################################ -# Author: Michael Trensch (MTrensch@googlemail.com) -################################################################################ - -source [find target/hilscher_netx50.cfg] - -reset_config trst_and_srst -adapter_nsrst_delay 500 -jtag_ntrst_delay 500 - -$_TARGETNAME configure -work-area-virt 0x10000000 -work-area-phys 0x10000000 -work-area-size 0x4000 -work-area-backup 1 - -$_TARGETNAME configure -event reset-init { - halt - - arm7_9 fast_memory_access enable - arm7_9 dcc_downloads enable - - sdram_fix - - puts "Configuring SDRAM controller for MT48LC2M32 (8MB) " - mww 0x1C000140 0 - mww 0x1C000144 0x00A12151 - mww 0x1C000140 0x030D0001 - - puts "Configuring SRAM nCS0 for 90ns Par. Flash (x16)" - mww 0x1C000100 0x01010008 - - flash probe 0 -} - -##################### -# Flash configuration -##################### - -#flash bank -flash bank parflash cfi 0xC0000000 0x01000000 2 2 $_TARGETNAME - -init -reset init diff --git a/tcl/board/hilscher_nxhx500.cfg b/tcl/board/hilscher_nxhx500.cfg deleted file mode 100644 index dd3a9514d..000000000 --- a/tcl/board/hilscher_nxhx500.cfg +++ /dev/null @@ -1,42 +0,0 @@ -################################################################################ -# Author: Michael Trensch (MTrensch@googlemail.com) -################################################################################ - -source [find target/hilscher_netx500.cfg] - -reset_config trst_and_srst -adapter_nsrst_delay 500 -jtag_ntrst_delay 500 - -$_TARGETNAME configure -work-area-virt 0x1000 -work-area-phys 0x1000 -work-area-size 0x4000 -work-area-backup 1 - -$_TARGETNAME configure -event reset-init { - halt - - arm7_9 fast_memory_access enable - arm7_9 dcc_downloads enable - - sleep 100 - - sdram_fix - - puts "Configuring SDRAM controller for MT48LC2M32 (8MB) " - mww 0x00100140 0 - mww 0x00100144 0x03C23251 - mww 0x00100140 0x030D0001 - - puts "Configuring SRAM nCS0 for 90ns Par. Flash (x16)" - mww 0x00100100 0x01010008 - - flash probe 0 -} - -##################### -# Flash configuration -##################### - -#flash bank -flash bank parflash cfi 0xC0000000 0x01000000 2 2 $_TARGETNAME - -init -reset init diff --git a/tcl/board/hilscher_nxsb100.cfg b/tcl/board/hilscher_nxsb100.cfg deleted file mode 100644 index efb091b10..000000000 --- a/tcl/board/hilscher_nxsb100.cfg +++ /dev/null @@ -1,29 +0,0 @@ -################################################################################ -# Author: Michael Trensch (MTrensch@googlemail.com) -################################################################################ - -source [find target/hilscher_netx500.cfg] - -reset_config trst_and_srst -adapter_nsrst_delay 500 -jtag_ntrst_delay 500 - -$_TARGETNAME configure -work-area-virt 0x1000 -work-area-phys 0x1000 -work-area-size 0x4000 -work-area-backup 1 - -$_TARGETNAME configure -event reset-init { - halt - - arm7_9 fast_memory_access enable - arm7_9 dcc_downloads enable - - sdram_fix - - puts "Configuring SDRAM controller for MT48LC2M32 (8MB) " - mww 0x00100140 0 - mww 0x00100144 0x03C23251 - mww 0x00100140 0x030D0001 - -} - -init -reset init diff --git a/tcl/board/hitex_lpc1768stick.cfg b/tcl/board/hitex_lpc1768stick.cfg deleted file mode 100644 index 161e9654a..000000000 --- a/tcl/board/hitex_lpc1768stick.cfg +++ /dev/null @@ -1,15 +0,0 @@ -# Hitex LPC1768 Stick -# -# http://www.hitex.com/?id=1602 -# - -reset_config trst_and_srst - -source [find interface/ftdi/hitex_lpc1768stick.cfg] - -source [find target/lpc17xx.cfg] - - -# startup @ 500kHz -adapter_khz 500 - diff --git a/tcl/board/hitex_lpc2929.cfg b/tcl/board/hitex_lpc2929.cfg deleted file mode 100644 index d2515371d..000000000 --- a/tcl/board/hitex_lpc2929.cfg +++ /dev/null @@ -1,106 +0,0 @@ -# Hitex eval board for LPC2929/LPC2939 -# http://www.hitex.com/ - -# Delays on reset lines -adapter_nsrst_delay 50 -jtag_ntrst_delay 1 - -# Maximum of 1/8 of clock frequency (XTAL = 16 MHz). -# Adaptive clocking through RTCK is not supported. -adapter_khz 2000 - -# Target device: LPC29xx with ETB -# The following variables are used by the LPC2900 script: -# HAS_ETB Must be set to 1. The CPU on this board has ETB. -# FLASH_CLOCK CPU frequency at the time of flash programming (in kHz) -set HAS_ETB 1 -set FLASH_CLOCK 112000 -source [find target/lpc2900.cfg] - -# A working area will help speeding the flash programming -#$_TARGETNAME configure -work-area-phys 0x80000000 -work-area-size 0x2000 -work-area-backup 0 -$_TARGETNAME configure -work-area-phys 0x58000000 -work-area-size 0x10000 -work-area-backup 0 - -# Event handlers -$_TARGETNAME configure -event reset-start { - # Back to the slow JTAG clock - adapter_khz 2000 -} - -# External 16-bit flash at chip select CS7 (SST39VF3201-70, 4 MiB) -set _FLASHNAME $_CHIPNAME.extflash -flash bank $_FLASHNAME cfi 0x5C000000 0x400000 2 2 $_TARGETNAME jedec_probe - - -$_TARGETNAME configure -event reset-init { - # Flash - mww 0x20200010 0x00000007 ;# FBWST: 7 wait states, not chached - - # Use PLL - mww 0xFFFF8020 0x00000001 ;# XTAL_OSC_CONTROL: enable, 1-20 MHz - mww 0xFFFF8070 0x01000000 ;# SYS_CLK_CONF: Crystal - mww 0xFFFF8028 0x00000005 ;# PLL: (power down) - mww 0xFFFF8028 0x01060004 ;# PLL: M=7, 2P=2 (power up) - # --> f=112 MHz, fcco=224 MHz - sleep 100 - mww 0xFFFF8070 0x02000000 ;# SYS_CLK_CONF: PLL - - # Increase JTAG speed - adapter_khz 6000 - - # Enable external memory bus (16-bit SRAM at CS6, 16-bit flash at CS7) - mww 0xE0001138 0x0000001F ;# P1.14 = D0 - mww 0xE000113C 0x0000001F ;# P1.15 = D1 - mww 0xE0001140 0x0000001F ;# P1.16 = D2 - mww 0xE0001144 0x0000001F ;# P1.17 = D3 - mww 0xE0001148 0x0000001F ;# P1.18 = D4 - mww 0xE000114C 0x0000001F ;# P1.19 = D5 - mww 0xE0001150 0x0000001F ;# P1.20 = D6 - mww 0xE0001154 0x0000001F ;# P1.21 = D7 - mww 0xE0001200 0x0000001F ;# P2.0 = D8 - mww 0xE0001204 0x0000001F ;# P2.1 = D9 - mww 0xE0001208 0x0000001F ;# P2.2 = D10 - mww 0xE000120C 0x0000001F ;# P2.3 = D11 - mww 0xE0001210 0x0000001F ;# P2.4 = D12 - mww 0xE0001214 0x0000001F ;# P2.5 = D13 - mww 0xE0001218 0x0000001F ;# P2.6 = D14 - mww 0xE000121C 0x0000001F ;# P2.7 = D15 - mww 0xE0001104 0x00000007 ;# P1.1 = A1 - mww 0xE0001108 0x00000007 ;# P1.2 = A2 - mww 0xE000110C 0x00000007 ;# P1.3 = A3 - mww 0xE0001110 0x00000007 ;# P1.4 = A4 - mww 0xE0001114 0x00000007 ;# P1.5 = A5 - mww 0xE0001118 0x00000007 ;# P1.6 = A6 - mww 0xE000111C 0x00000007 ;# P1.7 = A7 - mww 0xE0001028 0x00000007 ;# P0.10 = A8 - mww 0xE000102C 0x00000007 ;# P0.11 = A9 - mww 0xE0001030 0x00000007 ;# P0.12 = A10 - mww 0xE0001034 0x00000007 ;# P0.13 = A11 - mww 0xE0001038 0x00000007 ;# P0.14 = A12 - mww 0xE000103C 0x00000007 ;# P0.15 = A13 - mww 0xE0001048 0x00000007 ;# P0.18 = A14 - mww 0xE000104C 0x00000007 ;# P0.19 = A15 - mww 0xE0001050 0x00000007 ;# P0.20 = A16 - mww 0xE0001054 0x00000007 ;# P0.21 = A17 - mww 0xE0001058 0x00000007 ;# P0.22 = A18 - mww 0xE000105C 0x00000007 ;# P0.23 = A19 - mww 0xE0001238 0x00000007 ;# P2.14 = BLS0 - mww 0xE000123C 0x00000007 ;# P2.15 = BLS1 - mww 0xE0001300 0x00000007 ;# P3.0 = CS6 - mww 0xE0001304 0x00000007 ;# P3.1 = CS7 - mww 0xE0001130 0x00000007 ;# P1.12 = OE_N - mww 0xE0001134 0x00000007 ;# P1.13 = WE_N - mww 0x600000BC 0x00000041 ;# Bank6 16-bit mode, RBLE=1 - mww 0x600000B4 0x00000000 ;# Bank6 WSTOEN=0 - mww 0x600000AC 0x00000005 ;# Bank6 WST1=5 - mww 0x600000B8 0x00000001 ;# Bank6 WSTWEN=1 - mww 0x600000B0 0x00000006 ;# Bank6 WST2=6 - mww 0x600000A8 0x00000002 ;# Bank6 IDCY=2 - mww 0x600000D8 0x00000041 ;# Bank7 16-bit mode, RBLE=1 - mww 0x600000D0 0x00000000 ;# Bank7 WSTOEN=0 - mww 0x600000C8 0x0000000A ;# Bank7 WST1=10 - mww 0x600000D4 0x00000001 ;# Bank7 WSTWEN=1 - mww 0x600000CC 0x0000000C ;# Bank7 WST2=8 - mww 0x600000C4 0x00000002 ;# Bank7 IDCY=2 -} - diff --git a/tcl/board/hitex_stm32-performancestick.cfg b/tcl/board/hitex_stm32-performancestick.cfg deleted file mode 100644 index 82fb16961..000000000 --- a/tcl/board/hitex_stm32-performancestick.cfg +++ /dev/null @@ -1,16 +0,0 @@ -# Hitex stm32 performance stick - -reset_config trst_and_srst - -source [find interface/ftdi/stm32-stick.cfg] - -set CHIPNAME stm32_hitex -source [find target/stm32f1x.cfg] - -# configure str750 connected to jtag chain -# FIXME -- source [find target/str750.cfg] after cleaning that up -jtag newtap str750 cpu -irlen 4 -ircapture 0x1 -irmask 0x0f -expected-id 0x4f1f0041 - -# for some reason this board like to startup @ 500kHz -adapter_khz 500 - diff --git a/tcl/board/hitex_str9-comstick.cfg b/tcl/board/hitex_str9-comstick.cfg deleted file mode 100644 index be153314f..000000000 --- a/tcl/board/hitex_str9-comstick.cfg +++ /dev/null @@ -1,79 +0,0 @@ -# Hitex STR9-comStick -# http://www.hitex.com/index.php?id=383 -# This works for the STR9-comStick revisions STR912CS-A1 and STR912CS-A2. - -source [find interface/ftdi/hitex_str9-comstick.cfg] - -# set jtag speed -adapter_khz 3000 - -adapter_nsrst_delay 100 -jtag_ntrst_delay 100 -#use combined on interfaces or targets that can't set TRST/SRST separately -reset_config trst_and_srst - -# -# FIXME use the standard str912 target config; that script might need -# updating to "-ignore-version" for the boundary scan TAP -# -# source [find target/str912.cfg] -# - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME str912 -} - -if { [info exists ENDIAN] } { - set _ENDIAN $ENDIAN -} else { - set _ENDIAN little -} - -if { [info exists FLASHTAPID] } { - set _FLASHTAPID $FLASHTAPID -} else { - set _FLASHTAPID 0x04570041 -} -jtag newtap $_CHIPNAME flash -irlen 8 -ircapture 0x1 -irmask 0x1 -expected-id $_FLASHTAPID - -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - set _CPUTAPID 0x25966041 -} -jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID - -if { [info exists BSTAPID] } { - set _BSTAPID $BSTAPID -} else { - # Found on STR9-comStick, revision STR912CS-A1 - set _BSTAPID1 0x1457f041 - # Found on STR9-comStick, revision STR912CS-A2 - set _BSTAPID2 0x2457f041 -} -jtag newtap $_CHIPNAME bs -irlen 5 -ircapture 0x1 -irmask 0x1 -expected-id $_BSTAPID1 -expected-id $_BSTAPID2 - -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME arm966e -endian $_ENDIAN -chain-position $_TARGETNAME - -$_TARGETNAME configure -event reset-init { - # We can increase speed now that we know the target is halted. - #jtag_rclk 3000 - - # -- Enable 96K RAM - # PFQBC enabled / DTCM & AHB wait-states disabled - mww 0x5C002034 0x0191 - - str9x flash_config 0 4 2 0 0x80000 - flash protect 0 0 7 off -} - -$_TARGETNAME configure -work-area-phys 0x50000000 -work-area-size 16384 -work-area-backup 0 - -#flash bank -set _FLASHNAME $_CHIPNAME.flash0 -flash bank $_FLASHNAME str9x 0x00000000 0x00080000 0 0 0 -set _FLASHNAME $_CHIPNAME.flash1 -flash bank $_FLASHNAME str9x 0x00080000 0x00008000 0 0 0 diff --git a/tcl/board/iar_lpc1768.cfg b/tcl/board/iar_lpc1768.cfg deleted file mode 100644 index d8c8c2d71..000000000 --- a/tcl/board/iar_lpc1768.cfg +++ /dev/null @@ -1,17 +0,0 @@ -# Board from IAR KickStart Kit for LPC1768 -# See www.iar.com and also -# http://www.olimex.com/dev/lpc-1766stk.html -# - -source [find target/lpc17xx.cfg] - -# The chip has just been reset. -# -$_TARGETNAME configure -event reset-init { - # FIXME update the core clock to run at 100 MHz; - # and update JTAG clocking similarly; then - # make CCLK match, - - flash probe 0 -} - diff --git a/tcl/board/iar_str912_sk.cfg b/tcl/board/iar_str912_sk.cfg deleted file mode 100644 index ba060a046..000000000 --- a/tcl/board/iar_str912_sk.cfg +++ /dev/null @@ -1,3 +0,0 @@ -# The IAR str912-sk evaluation kick start board has an str912 - -source [find target/str912.cfg] \ No newline at end of file diff --git a/tcl/board/icnova_imx53_sodimm.cfg b/tcl/board/icnova_imx53_sodimm.cfg deleted file mode 100644 index aa6a148a0..000000000 --- a/tcl/board/icnova_imx53_sodimm.cfg +++ /dev/null @@ -1,448 +0,0 @@ -################################################################################################# -# Author: Benjamin Tietz ;# -# based on work from: Wjatscheslaw Stoljarski (Slawa) ;# -# Kiwigrid GmbH ;# -# Generated for In-Circuit i.MX53 SO-Dimm ;# -################################################################################################# - -# The In-Circuit ICnova IMX53SODIMM board has a single IMX53 chip -source [find target/imx53.cfg] -# Helper for common memory read/modify/write procedures -source [find mem_helper.tcl] - -echo "i.MX53 SO-Dimm board lodaded." - -# Set reset type -#reset_config srst_only - -adapter_khz 3000 - -# Slow speed to be sure it will work -jtag_rclk 1000 -$_TARGETNAME configure -event "reset-start" { jtag_rclk 1000 } - -$_TARGETNAME configure -event "reset-assert" { - echo "Reseting ...." - #cortex_a dbginit -} - -$_TARGETNAME configure -event reset-init { sodimm_init } - -global AIPS1_BASE_ADDR -set AIPS1_BASE_ADDR 0x53F00000 -global AIPS2_BASE_ADDR -set AIPS2_BASE_ADDR 0x63F00000 - -proc sodimm_init { } { - echo "Reset-init..." - ; # halt the CPU - halt - - echo "HW version [format %x [mrw 0x48]]" - - dap apsel 1 - DCD - - ; # ARM errata ID #468414 - set tR [arm mrc 15 0 1 0 1] - arm mcr 15 0 1 0 1 [expr $tR | (1<<5)] ; # enable L1NEON bit - - init_l2cc - init_aips - init_clock - - dap apsel 0 - - ; # Force ARM state - ; #reg cpsr 0x000001D3 - arm core_state arm - - jtag_rclk 3000 -# adapter_khz 3000 -} - - -# L2CC Cache setup/invalidation/disable -proc init_l2cc { } { - ; #/* explicitly disable L2 cache */ - ; #mrc 15, 0, r0, c1, c0, 1 - set tR [arm mrc 15 0 1 0 1] - ; #bic r0, r0, #0x2 - ; #mcr 15, 0, r0, c1, c0, 1 - arm mcr 15 0 1 0 1 [expr $tR & ~(1<<2)] - - ; #/* reconfigure L2 cache aux control reg */ - ; #mov r0, #0xC0 /* tag RAM */ - ; #add r0, r0, #0x4 /* data RAM */ - ; #orr r0, r0, #(1 << 24) /* disable write allocate delay */ - ; #orr r0, r0, #(1 << 23) /* disable write allocate combine */ - ; #orr r0, r0, #(1 << 22) /* disable write allocate */ - - ; #mcr 15, 1, r0, c9, c0, 2 - arm mcr 15 1 9 0 2 [expr 0xC4 | (1<<24) | (1<<23) | (1<22)] -} - - -# AIPS setup - Only setup MPROTx registers. -# The PACR default values are good. -proc init_aips { } { - ; # Set all MPROTx to be non-bufferable, trusted for R/W, - ; # not forced to user-mode. - global AIPS1_BASE_ADDR - global AIPS2_BASE_ADDR - set VAL 0x77777777 - -# dap apsel 1 - mww [expr $AIPS1_BASE_ADDR + 0x0] $VAL - mww [expr $AIPS1_BASE_ADDR + 0x4] $VAL - mww [expr $AIPS2_BASE_ADDR + 0x0] $VAL - mww [expr $AIPS2_BASE_ADDR + 0x4] $VAL -# dap apsel 0 -} - - -proc init_clock { } { - global AIPS1_BASE_ADDR - global AIPS2_BASE_ADDR - set CCM_BASE_ADDR [expr $AIPS1_BASE_ADDR + 0x000D4000] - set CLKCTL_CCSR 0x0C - set CLKCTL_CBCDR 0x14 - set CLKCTL_CBCMR 0x18 - set PLL1_BASE_ADDR [expr $AIPS2_BASE_ADDR + 0x00080000] - set PLL2_BASE_ADDR [expr $AIPS2_BASE_ADDR + 0x00084000] - set PLL3_BASE_ADDR [expr $AIPS2_BASE_ADDR + 0x00088000] - set PLL4_BASE_ADDR [expr $AIPS2_BASE_ADDR + 0x0008C000] - set CLKCTL_CSCMR1 0x1C - set CLKCTL_CDHIPR 0x48 - set PLATFORM_BASE_ADDR [expr $AIPS2_BASE_ADDR + 0x000A0000] - set CLKCTL_CSCDR1 0x24 - set CLKCTL_CCDR 0x04 - - ; # Switch ARM to step clock - mww [expr $CCM_BASE_ADDR + $CLKCTL_CCSR] 0x4 - - return - echo "not returned" - setup_pll $PLL1_BASE_ADDR 800 - setup_pll $PLL3_BASE_ADDR 400 - - ; # Switch peripheral to PLL3 - mww [expr $CCM_BASE_ADDR + $CLKCTL_CBCMR] 0x00015154 - mww [expr $CCM_BASE_ADDR + $CLKCTL_CBCDR] [expr 0x02888945 | (1<<16)] - while {[mrw [expr $CCM_BASE_ADDR + $CLKCTL_CDHIPR]] != 0} { sleep 1 } - - setup_pll $PLL2_BASE_ADDR 400 - - ; # Switch peripheral to PLL2 - mww [expr $CCM_BASE_ADDR + $CLKCTL_CBCDR] [expr 0x00808145 | (2<<10) | (9<<16) | (1<<19)] - - mww [expr $CCM_BASE_ADDR + $CLKCTL_CBCMR] 0x00016154 - - ; # change uart clk parent to pll2 - mww [expr $CCM_BASE_ADDR + $CLKCTL_CSCMR1] [expr [mrw [expr $CCM_BASE_ADDR + $CLKCTL_CSCMR1]] & 0xfcffffff | 0x01000000] - - ; # make sure change is effective - while {[mrw [expr $CCM_BASE_ADDR + $CLKCTL_CDHIPR]] != 0} { sleep 1 } - - setup_pll $PLL3_BASE_ADDR 216 - - setup_pll $PLL4_BASE_ADDR 455 - - ; # Set the platform clock dividers - mww [expr $PLATFORM_BASE_ADDR + 0x14] 0x00000124 - - mww [expr $CCM_BASE_ADDR + 0x10] 0 - - ; # Switch ARM back to PLL 1. - mww [expr $CCM_BASE_ADDR + $CLKCTL_CCSR] 0x0 - - ; # make uart div=6 - mww [expr $CCM_BASE_ADDR + $CLKCTL_CSCDR1] [expr [mrw [expr $CCM_BASE_ADDR + $CLKCTL_CSCDR1]] & 0xffffffc0 | 0x0a] - - ; # Restore the default values in the Gate registers - mww [expr $CCM_BASE_ADDR + 0x68] 0xFFFFFFFF - mww [expr $CCM_BASE_ADDR + 0x6C] 0xFFFFFFFF - mww [expr $CCM_BASE_ADDR + 0x70] 0xFFFFFFFF - mww [expr $CCM_BASE_ADDR + 0x74] 0xFFFFFFFF - mww [expr $CCM_BASE_ADDR + 0x78] 0xFFFFFFFF - mww [expr $CCM_BASE_ADDR + 0x7C] 0xFFFFFFFF - mww [expr $CCM_BASE_ADDR + 0x80] 0xFFFFFFFF - mww [expr $CCM_BASE_ADDR + 0x84] 0xFFFFFFFF - - mww [expr $CCM_BASE_ADDR + $CLKCTL_CCDR] 0x00000 - - ; # for cko - for ARM div by 8 - mww [expr $CCM_BASE_ADDR + 0x60] [expr 0x000A0000 & 0x00000F0] -} - - -proc setup_pll { PLL_ADDR CLK } { - set PLL_DP_CTL 0x00 - set PLL_DP_CONFIG 0x04 - set PLL_DP_OP 0x08 - set PLL_DP_HFS_OP 0x1C - set PLL_DP_MFD 0x0C - set PLL_DP_HFS_MFD 0x20 - set PLL_DP_MFN 0x10 - set PLL_DP_HFS_MFN 0x24 - - if {$CLK == 1000} { - set DP_OP [expr (10 << 4) + ((1 - 1) << 0)] - set DP_MFD [expr (12 - 1)] - set DP_MFN 5 - } elseif {$CLK == 850} { - set DP_OP [expr (8 << 4) + ((1 - 1) << 0)] - set DP_MFD [expr (48 - 1)] - set DP_MFN 41 - } elseif {$CLK == 800} { - set DP_OP [expr (8 << 4) + ((1 - 1) << 0)] - set DP_MFD [expr (3 - 1)] - set DP_MFN 1 - } elseif {$CLK == 700} { - set DP_OP [expr (7 << 4) + ((1 - 1) << 0)] - set DP_MFD [expr (24 - 1)] - set DP_MFN 7 - } elseif {$CLK == 600} { - set DP_OP [expr (6 << 4) + ((1 - 1) << 0)] - set DP_MFD [expr (4 - 1)] - set DP_MFN 1 - } elseif {$CLK == 665} { - set DP_OP [expr (6 << 4) + ((1 - 1) << 0)] - set DP_MFD [expr (96 - 1)] - set DP_MFN 89 - } elseif {$CLK == 532} { - set DP_OP [expr (5 << 4) + ((1 - 1) << 0)] - set DP_MFD [expr (24 - 1)] - set DP_MFN 13 - } elseif {$CLK == 455} { - set DP_OP [expr (8 << 4) + ((2 - 1) << 0)] - set DP_MFD [expr (48 - 1)] - set DP_MFN 71 - } elseif {$CLK == 400} { - set DP_OP [expr (8 << 4) + ((2 - 1) << 0)] - set DP_MFD [expr (3 - 1)] - set DP_MFN 1 - } elseif {$CLK == 216} { - set DP_OP [expr (6 << 4) + ((3 - 1) << 0)] - set DP_MFD [expr (4 - 1)] - set DP_MFN 3 - } else { - error "Error (setup_dll): clock not found!" - } - - mww [expr $PLL_ADDR + $PLL_DP_CTL] 0x00001232 - mww [expr $PLL_ADDR + $PLL_DP_CONFIG] 0x2 - - mww [expr $PLL_ADDR + $PLL_DP_OP] $DP_OP - mww [expr $PLL_ADDR + $PLL_DP_HFS_MFD] $DP_OP - - mww [expr $PLL_ADDR + $PLL_DP_MFD] $DP_MFD - mww [expr $PLL_ADDR + $PLL_DP_HFS_MFD] $DP_MFD - - mww [expr $PLL_ADDR + $PLL_DP_MFN] $DP_MFN - mww [expr $PLL_ADDR + $PLL_DP_HFS_MFN] $DP_MFN - - mww [expr $PLL_ADDR + $PLL_DP_CTL] 0x00001232 - while {[expr [mrw [expr $PLL_ADDR + $PLL_DP_CTL]] & 0x1] == 0} { sleep 1 } -} - - -proc CPU_2_BE_32 { L } { - return [expr (($L & 0x000000FF) << 24) | (($L & 0x0000FF00) << 8) | (($L & 0x00FF0000) >> 8) | (($L & 0xFF000000) >> 24)] -} - - -# Device Configuration Data -proc DCD { } { -# dap apsel 1 -#*========================================================================================== ====== -# Initialization script for 32 bit DDR3 (CS0+CS1) -#*========================================================================================== ====== -# Remux D24/D25 to perform Flash-access - mww 0x53fa818C 0x00000000 ; #EIM_RW - mww 0x53fa8180 0x00000000 ; #EIM_CS0 - mww 0x53fa8188 0x00000000 ; #EIM_OE - mww 0x53fa817C 0x00000000 ; #A16 - mww 0x53fa8178 0x00000000 ; #A17 - mww 0x53fa8174 0x00000000 ; #A18 - mww 0x53fa8170 0x00000000 ; #A19 - mww 0x53fa816C 0x00000000 ; #A20 - mww 0x53fa8168 0x00000000 ; #A21 - mww 0x53fa819C 0x00000000 ; #DA0 - mww 0x53fa81A0 0x00000000 ; #DA1 - mww 0x53fa81A4 0x00000000 ; #DA2 - mww 0x53fa81A8 0x00000000 ; #DA3 - mww 0x53fa81AC 0x00000000 ; #DA4 - mww 0x53fa81B0 0x00000000 ; #DA5 - mww 0x53fa81B4 0x00000000 ; #DA6 - mww 0x53fa81B8 0x00000000 ; #DA7 - mww 0x53fa81BC 0x00000000 ; #DA8 - mww 0x53fa81C0 0x00000000 ; #DA9 - mww 0x53fa81C4 0x00000000 ; #DA10 - mww 0x53fa81C8 0x00000000 ; #DA11 - mww 0x53fa81CC 0x00000000 ; #DA12 - mww 0x53fa81D0 0x00000000 ; #DA13 - mww 0x53fa81D4 0x00000000 ; #DA14 - mww 0x53fa81D8 0x00000000 ; #DA15 - mww 0x53fa8118 0x00000000 ; #D16 - mww 0x53fa811C 0x00000000 ; #D17 - mww 0x53fa8120 0x00000000 ; #D18 - mww 0x53fa8124 0x00000000 ; #D19 - mww 0x53fa8128 0x00000000 ; #D20 - mww 0x53fa812C 0x00000000 ; #D21 - mww 0x53fa8130 0x00000000 ; #D22 - mww 0x53fa8134 0x00000000 ; #D23 - mww 0x53fa813c 0x00000000 ; #IOMUXC_SW_PAD_CTL_PAD_EIM_D24 - mww 0x53fa8140 0x00000000 ; #IOMUXC_SW_PAD_CTL_PAD_EIM_D25 - mww 0x53fa8144 0x00000000 ; #D26 - mww 0x53fa8148 0x00000000 ; #D27 - mww 0x53fa814C 0x00000000 ; #D28 - mww 0x53fa8150 0x00000000 ; #D29 - mww 0x53fa8154 0x00000000 ; #D30 - mww 0x53fa8158 0x00000000 ; #D31 - -# DDR3 IOMUX configuration -#* Global pad control options */ - mww 0x53fa8554 0x00380000 ; #IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM3 - mww 0x53fa8558 0x00380040 ; #IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS3 - mww 0x53fa8560 0x00380000 ; #IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM2 - mww 0x53fa8564 0x00380040 ; #IOMUXC_SW_PAD_CTL_PAD_DRAM_SDODT1 - mww 0x53fa8568 0x00380040 ; #IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS2 - mww 0x53fa8570 0x00200000 ; #IOMUXC_SW_PAD_CTL_PAD_DRAM_SDCLK_1 - boazp: weaker sdclk EVK DDR max frequency - mww 0x53fa8574 0x00380000 ; #IOMUXC_SW_PAD_CTL_PAD_DRAM_CAS - mww 0x53fa8578 0x00200000 ; #IOMUXC_SW_PAD_CTL_PAD_DRAM_SDCLK_0 - boazp: weaker sdclk EVK DDR max frequency - mww 0x53fa857c 0x00380040 ; #IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS0 - mww 0x53fa8580 0x00380040 ; #IOMUXC_SW_PAD_CTL_PAD_DRAM_SDODT0 - mww 0x53fa8584 0x00380000 ; #IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM0 - mww 0x53fa8588 0x00380000 ; #IOMUXC_SW_PAD_CTL_PAD_DRAM_RAS - mww 0x53fa8590 0x00380040 ; #IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS1 - mww 0x53fa8594 0x00380000 ; #IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM1 - mww 0x53fa86f0 0x00380000 ; #IOMUXC_SW_PAD_CTL_GRP_ADDDS - mww 0x53fa86f4 0x00000200 ; #IOMUXC_SW_PAD_CTL_GRP_DDRMODE_CTL - mww 0x53fa86fc 0x00000000 ; #IOMUXC_SW_PAD_CTL_GRP_DDRPKE -# mww 0x53fa8714 0x00000200 ; #IOMUXC_SW_PAD_CTL_GRP_DDRMODE - CMOS mode XXX - mww 0x53fa8714 0x00000000 ; #IOMUXC_SW_PAD_CTL_GRP_DDRMODE - CMOS mode XXX - mww 0x53fa8718 0x00380000 ; #IOMUXC_SW_PAD_CTL_GRP_B0DS - mww 0x53fa871c 0x00380000 ; #IOMUXC_SW_PAD_CTL_GRP_B1DS - mww 0x53fa8720 0x00380000 ; #IOMUXC_SW_PAD_CTL_GRP_CTLDS - mww 0x53fa8724 0x00000000 ; #IOMUXC_SW_PAD_CTL_GRP_DDR_TYPE - DDR_SEL=0 XXX - mww 0x53fa8728 0x00380000 ; #IOMUXC_SW_PAD_CTL_GRP_B2DS - mww 0x53fa872c 0x00380000 ; #IOMUXC_SW_PAD_CTL_GRP_B3DS -# mww 0x53fa86f4 0x00000000 ;IOMUXC_SW_PAD_CTL_GRP_DDRMODE_CTL for sDQS[3:0], 1=DDR2, 0=CMOS mode -# mww 0x53fa8714 0x00000000 ;IOMUXC_SW_PAD_CTL_GRP_DDRMODE for D[31:0], 1=DDR2, 0=CMOS mode -# mww 0x53fa86fc 0x00000000 ;IOMUXC_SW_PAD_CTL_GRP_DDRPKE -# mww 0x53fa8724 0x00000000 ;IOMUXC_SW_PAD_CTL_GRP_DDR_TYPE - DDR_SEL=00 - -#* Data bus byte lane pad drive strength control options */ -# mww 0x53fa872c 0x00300000 ;IOMUXC_SW_PAD_CTL_GRP_B3DS -# mww 0x53fa8554 0x00300000 ;IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM3 -# mww 0x53fa8558 0x00300040 ;IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS3 -# mww 0x53fa8728 0x00300000 ;IOMUXC_SW_PAD_CTL_GRP_B2DS -# mww 0x53fa8560 0x00300000 ;IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM2 -# mww 0x53fa8568 0x00300040 ;IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS2 -# mww 0x53fa871c 0x00300000 ;IOMUXC_SW_PAD_CTL_GRP_B1DS -# mww 0x53fa8594 0x00300000 ;IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM1 -# mww 0x53fa8590 0x00300040 ;IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS1 -# mww 0x53fa8718 0x00300000 ;IOMUXC_SW_PAD_CTL_GRP_B0DS -# mww 0x53fa8584 0x00300000 ;IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM0 -# mww 0x53fa857c 0x00300040 ;IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS0 - -#* SDCLK pad drive strength control options */ -# mww 0x53fa8578 0x00300000 ;IOMUXC_SW_PAD_CTL_PAD_DRAM_SDCLK_0 -# mww 0x53fa8570 0x00300000 ;IOMUXC_SW_PAD_CTL_PAD_DRAM_SDCLK_1 - -#* Control and addr bus pad drive strength control options */ -# mww 0x53fa8574 0x00300000 ;IOMUXC_SW_PAD_CTL_PAD_DRAM_CAS -# mww 0x53fa8588 0x00300000 ;IOMUXC_SW_PAD_CTL_PAD_DRAM_RAS -# mww 0x53fa86f0 0x00300000 ;IOMUXC_SW_PAD_CTL_GRP_ADDDS for DDR addr bus -# mww 0x53fa8720 0x00300000 ;IOMUXC_SW_PAD_CTL_GRP_CTLDS for CSD0, CSD1, SDCKE0, SDCKE1, SDWE - -# mww 0x53fa8564 0x00300040 ;IOMUXC_SW_PAD_CTL_PAD_DRAM_SDODT1 -# mww 0x53fa8580 0x00300040 ;IOMUXC_SW_PAD_CTL_PAD_DRAM_SDODT0 - -# Initialize DDR3 memory - Micron MT41J128M16-187Er -#** Keep for now, same setting as CPU3 board **# - mww 0x63fd901c 0x00008000 -# mww 0x63fd904c 0x01680172 ; #write leveling reg 0 -# mww 0x63fd9050 0x0021017f ; #write leveling reg 1 - mww 0x63fd9088 0x32383535 ; #read delay lines - mww 0x63fd9090 0x40383538 ; #write delay lines -# mww 0x63fd90F8 0x00000800 ; #Measure unit - mww 0x63fd907c 0x0136014d ; #DQS gating 0 - mww 0x63fd9080 0x01510141 ; #DQS gating 1 -#* CPU3 Board settingr -# Enable bank interleaving, Address mirror on, WALAT 0x1, RALAT = 0x5, DDR2_EN = 0 -# mww 0x63fd9018 0x00091740 ; #Misc register: -#* Quick Silver board setting -# Enable bank interleaving, Address mirror off, WALAT 0x1, RALAT = 0x5, DDR2_EN = 0 - mww 0x63fd9018 0x00011740 ; #Misc register - -# Enable CSD0 and CSD1, row width = 14, column width = 10, burst length = 8, data width = 32bit -# mww 0x63fd9000 0xc3190000 ; #Main control register -# Enable CSD0 and CSD1, row width = 14, column width = 10, burst length = 8, data width = 32bit - mww 0x63fd9000 0x83190000 ; #Main control register -# tRFC=64ck;tXS=68;tXP=3;tXPDLL=10;tFAW=15;CAS=6ck - mww 0x63fd900C 0x555952E3 ; #timing configuration Reg 0 -# tRCD=6;tRP=6;tRC=21;tRAS=15;tRPA=1;tWR=6;tMRD=4;tCWL=5ck - mww 0x63fd9010 0xb68e8b63 ; #timing configuration Reg 1 -# tDLLK(tXSRD)=512 cycles; tRTP=4;tWTR=4;tRRD=4 - mww 0x63fd9014 0x01ff00db ; #timing configuration Reg 2 - mww 0x63fd902c 0x000026d2 ; #command delay (default) - mww 0x63fd9030 0x009f0e21 ; #out of reset delays -# Keep tAOFPD, tAONPD, tANPD, and tAXPD as default since they are bigger than calc values - mww 0x63fd9008 0x12273030 ; #ODT timings -# tCKE=3; tCKSRX=5; tCKSRE=5 - mww 0x63fd9004 0x0002002d -#Power down control -#********************************** -#DDR device configuration: -#********************************** -#********************************** -# CS0: -#********************************** - mww 0x63fd901c 0x00008032 ; #write mode reg MR2 with cs0 (see below for settings) -# Full array self refresh -# Rtt_WR disabled (no ODT at IO CMOS operation) -# Manual self refresh -# CWS=5 - mww 0x63fd901c 0x00008033 ; #write mode reg MR3 with cs0. - mww 0x63fd901c 0x00028031 ; #write mode reg MR1 with cs0. ODS=01: out buff= RZQ/7 (see below for settings) -# out impedance = RZQ/7 -# Rtt_nom disabled (no ODT at IO CMOS operation) -# Aditive latency off -# write leveling disabled -# tdqs (differential?) disabled - - mww 0x63fd901c 0x09208030 ; #write mode reg MR0 with cs0 , with dll_rst0 - mww 0x63fd901c 0x04008040 ; #ZQ calibration with cs0 (A10 high indicates ZQ cal long ZQCL) -#********************************** -# CS1: -#********************************** -# mww 0x63fd901c 0x0000803a ; #write mode reg MR2 with cs1. -# mww 0x63fd901c 0x0000803b ; #write mode reg MR3 with cs1. -# mww 0x63fd901c 0x00028039 ; #write mode reg MR1 with cs1. ODS=01: out buff= RZQ/7 -# mww 0x63fd901c 0x09208138 ; #write mode reg MR0 with cs1. -# mww 0x63fd901c 0x04008048 ; #ZQ calibration with cs1(A10 high indicates ZQ cal long ZQCL) -#********************************** - - - mww 0x63fd9020 0x00001800 ; # Refresh control register - mww 0x63fd9040 0x04b80003 ; # ZQ HW control - mww 0x63fd9058 0x00022227 ; # ODT control register - - mww 0x63fd901c 0x00000000 - -# CLKO muxing (comment out for now till needed to avoid conflicts with intended usage of signals) -# mww 0x53FA8314 = 0 -# mww 0x53FA8320 0x4 -# mww 0x53FD4060 0x01e900f0 - -# dap apsel 0 -} - -# IRAM -$_TARGETNAME configure -work-area-phys 0xF8000000 -work-area-size 0x20000 -work-area-backup 1 - -flash bank mx535_nor cfi 0xf0000000 0x800000 2 2 $_TARGETNAME - -# vim:filetype=tcl diff --git a/tcl/board/icnova_sam9g45_sodimm.cfg b/tcl/board/icnova_sam9g45_sodimm.cfg deleted file mode 100644 index 84dab3899..000000000 --- a/tcl/board/icnova_sam9g45_sodimm.cfg +++ /dev/null @@ -1,278 +0,0 @@ -################################################################################################# -# # -# Author: Lars Poeschel (larsi@wh2.tu-dresden.de) # -# Generated for In-Circuit ICnova SAM9G45 SODIMM # -# http://www.ic-board.de/product_info.php?info=p214_ICnova-SAM9G45-SODIMM.html|ICnova # -# # -################################################################################################# - -# FIXME use some standard target config, maybe create one from this -# -# source [find target/...cfg] - -source [find target/at91sam9g45.cfg] - -# Set reset type. -# reset_config trst_and_srst - -# adapter_nsrst_delay 200 -# jtag_ntrst_delay 200 - - -# If you don't want to execute built-in boot rom code (and there are good reasons at times not to do that) in the -# AT91SAM9 family, the microcontroller is a lump on a log without initialization. Because this family has -# some powerful features, we want to have a special function that handles "reset init". To do this we declare -# an event handler where these special activities can take place. - -scan_chain -$_TARGETNAME configure -event reset-init {at91sam9g45_init} - -# Set fallback clock to 1/6 of worst-case clock speed (which would be the 32.768 kHz slow clock). -# Slow-speed oscillator enabled at reset, so run jtag speed slow. -$_TARGETNAME configure -event reset-start {at91sam9g45_start} - - -# NandFlash configuration and definition -# Future TBD -# Flash configuration -# flash bank cfi -set _FLASHNAME $_CHIPNAME.flash -# set _NANDNAME $_CHIPNAME.nand -flash bank $_FLASHNAME cfi 0x10000000 0x00800000 2 2 $_TARGETNAME -# nand device $_NANDNAME at91sam9 $_TARGETNAME 0x40000000 0xFFFFE800 - - -proc read_register {register} { - set result "" - mem2array result 32 $register 1 - return $result(0) -} - -proc at91sam9g45_start { } { - - # Make sure that the the jtag is running slow, since there are a number of different ways the board - # can be configured coming into this state that can cause communication problems with the jtag - # adapter. Also since this call can be made following a "reset init" where fast memory accesses - # are enabled, need to temporarily shut this down so that the RSTC_MR register can be written at slower - # jtag speed without causing GDB keep alive problem. - - arm7_9 fast_memory_access disable - # Slow-speed oscillator enabled at reset, so run jtag speed slow. - adapter_khz 4 - # Make sure processor is halted, or error will result in following steps. - halt - wait_halt 10000 - # RSTC_MR : enable user reset. - mww 0xfffffd08 0xa5000501 -} - - -proc at91sam9g45_init { } { - - # At reset AT91SAM9G45 chip runs on slow clock (32.768 kHz). To shift over to a normal clock requires - # a number of steps that must be carefully performed. The process outline below follows the - # recommended procedure outlined in the AT91SAM9G45 technical manual. - # - # Several key and very important things to keep in mind: - # The SDRAM parts used currently on the board are -75 grade parts. This - # means the master clock (MCLK) must be at or below 133 MHz or timing errors will occur. The processor - # core can operate up to 400 MHz and therefore PCLK must be at or below this to function properly. - - # Make sure processor is halted, or error will result in following steps. - halt - # RSTC_MR : enable user reset. - mww 0xfffffd08 0xa5000501 - # WDT_MR : disable watchdog. - mww 0xfffffd44 0x00008000 - - # Enable the main 15.000 MHz oscillator in CKGR_MOR register. - # Wait for MOSCS in PMC_SR to assert indicating oscillator is again stable after change to CKGR_MOR. - - mww 0xfffffc20 0x00004001 - while { [expr [read_register 0xfffffc68] & 0x01] != 1 } { sleep 1 } - - # Set PLLA Register for 792.576 MHz (divider: bypass, multiplier: 43). - # Wait for LOCKA signal in PMC_SR to assert indicating PLLA is stable. - - #mww 0xfffffc28 0x202a3f01 - mww 0xfffffc28 0x20c73f03 - while { [expr [read_register 0xfffffc68] & 0x02] != 2 } { sleep 1 } - - # Set master system clock prescaler divide by 6 and processor clock divide by 2 in PMC_MCKR. - # Wait for MCKRDY signal from PMC_SR to assert. - - #mww 0xfffffc30 0x00000101 - mww 0xfffffc30 0x00001301 - while { [expr [read_register 0xfffffc68] & 0x08] != 8 } { sleep 1 } - - # Now change PMC_MCKR register to select PLLA. - # Wait for MCKRDY signal from PMC_SR to assert. - - mww 0xfffffc30 0x00001302 - while { [expr [read_register 0xfffffc68] & 0x08] != 8 } { sleep 1 } - - # Processor and master clocks are now operating and stable at maximum frequency possible: - # -> MCLK = 132.096 MHz - # -> PCLK = 396.288 MHz - - # Switch over to adaptive clocking. - - adapter_khz 6000 - - # Enable faster DCC downloads. - - arm7_9 dcc_downloads enable - - # To be able to use external SDRAM, several peripheral configuration registers must - # be modified. The first change is made to PIO_ASR to select peripheral functions - # for D15 through D31. The second change is made to the PIO_PDR register to disable - # this for D15 through D31. - -# mww 0xfffff870 0xffff0000 -# mww 0xfffff804 0xffff0000 - - # The EBI chip select register EBI_CS must be specifically configured to enable the internal SDRAM controller - # using CS1. Additionally we want CS3 assigned to NandFlash. Also VDDIO is connected physically on - # the board to the 3.3 VDC power supply so set the appropriate register bit to notify the micrcontroller. - - # mww 0xffffef1c 0x000100a - - # The ICnova SAM9G45 SODIMM has built-in NandFlash. The exact physical timing characteristics - # for the memory type used on the current board (MT29F2G08AACWP) can be established by setting - # four registers in order: SMC_SETUP3, SMC_PULSE3, SMC_CYCLE3, and SMC_MODE3. - - # mww 0xffffec30 0x00020002 - # mww 0xffffec34 0x04040404 - # mww 0xffffec38 0x00070007 - # mww 0xffffec3c 0x00030003 - - # Identify NandFlash bank 0. Disabled at the moment because a memory driver is not yet complete. - -# nand probe 0 - - # SMC_SETUP0 : Setup SMC for NOR Flash - mww 0xffffe800 0x0012000a - # SMC_PULSE0 - mww 0xffffe804 0x3b38343b - # SMC_CYCLE0 - mww 0xffffe808 0x003f003f - # SMC_MODE0 - mww 0xffffe80c 0x00001000 - # Identify flash bank 0 - flash probe 0 - - # Now setup SDRAM. This is tricky and configuration is very important for reliability! The current calculations - # are based on 2 x Samsung K4T51083QG memory. - - # 0. Enable DDR2 Clock - mww 0xfffffc00 0x4 - # 1. Program memory device type - # 1.1 configure the DDR controller - mww 0xffffe620 0x16 - # 1.2 program the DDR controller - mww 0xffffe608 0x3d - - # 2. program memory device features - # 2.1 assume timings for 7.5ns min clock period - mww 0xffffe60c 0x21128226 - # 2.2 pSDDRC->HDDRSDRC2_T1PR - mww 0xffffe610 0x02c8100e - # 2.3 pSDDRC->HDDRSDRC2_T2PR - mww 0xffffe614 0x01000702 - # 3. NOP - mww 0xffffe600 0x1 - mww 0x70000000 0x1 - # 3.1 delay 200us - sleep 1 - # jim tcl alternative: after ms - # after 0.2 - - # 4. NOP - mww 0xffffe600 0x1 - mww 0x70000000 0x1 - # 4.1 delay 400ns - - # 5. set all bank precharge - mww 0xffffe600 0x2 - mww 0x70000000 0x1 - # 5.1 delay 400ns - - # 6. set EMR operation (EMRS2) - mww 0xffffe600 0x5 - mww 0x74000000 0x1 - # 6.1 delay 2 cycles - - # 7. set EMR operation (EMRS3) - mww 0xffffe600 0x5 - mww 0x76000000 0x1 - # 7.1 delay 2 cycles - - # 8. set EMR operation (EMRS1) - mww 0xffffe600 0x5 - mww 0x72000000 0x1 - # 8.1 delay 200 cycles (400Mhz -> 5 * 10^-7s) - sleep 1 - - # 9. Enable DLL Reset (set DLL bit) - set CR [expr [read_register 0xffffe608] | 0x80] - mww 0xffffe608 $CR - - # 10. mode register cycle to reset the DLL - mww 0xffffe600 0x5 - mww 0x70000000 0x1 - # 10.1 delay 2 cycles - - # 11. set all bank precharge - mww 0xffffe600 0x2 - mww 0x70000000 0x1 - # 11.1 delay 400 ns - - # 12. two auto-refresh (CBR) cycles are provided. - mww 0xffffe600 0x4 - mww 0x70000000 0x1 - # 12.1 delay 10 cycles - # 12.2 2nd cycle (schreiben des Mode Register sparen wir uns) - mww 0x70000000 0x1 - # 12.3 delay 10 cycles - - # 13. disable DLL reset (clear DLL bit) - set CR [expr [read_register 0xffffe608] & 0xffffff7f] - mww 0xffffe608 $CR - - # 14. mode register set cycle - mww 0xffffe600 0x3 - mww 0x70000000 0x1 - - # 15. program OCD field (set OCD bits) - set CR [expr [read_register 0xffffe608] | 0x7000] - mww 0xffffe608 $CR - - # 16. (EMRS1) - mww 0xffffe600 0x5 - mww 0x72000000 0x1 - # 16.1 delay 2 cycles - - # 17. disable OCD field (clear OCD bits) - set CR [expr [read_register 0xffffe608] & 0xffff8fff] - mww 0xffffe608 $CR - - # 18. (EMRS1) - mww 0xffffe600 0x5 - mww 0x76000000 0x1 - # 18.1 delay 2 cycles - - # 19. normal mode command - mww 0xffffe600 0x0 - mww 0x70000000 0x1 - - # 20. perform write to any address - #mww 0x70000000 0x1 - - # 21. write refresh rate into the count field of the refresh rate register - mww 0xffffe604 0x24b - # 21.1 delay (500 * 6 cycles) - - arm7_9 fast_memory_access enable -} - - diff --git a/tcl/board/imx27ads.cfg b/tcl/board/imx27ads.cfg deleted file mode 100644 index e705b1e16..000000000 --- a/tcl/board/imx27ads.cfg +++ /dev/null @@ -1,76 +0,0 @@ -# The IMX27 ADS eval board has a single IMX27 chip -# Note: tested on IMX27ADS Board REV-2.6 and REV-2.8 -source [find target/imx27.cfg] -$_TARGETNAME configure -event gdb-attach { reset init } -$_TARGETNAME configure -event reset-init { imx27ads_init } - -# The IMX27 ADS board has a NOR flash on CS0 -set _FLASHNAME $_CHIPNAME.flash -flash bank $_FLASHNAME cfi 0xc0000000 0x00200000 2 2 $_TARGETNAME - -proc imx27ads_init { } { - # This setup puts RAM at 0xA0000000 - - # reset the board correctly - reset run - reset halt - - mww 0x10000000 0x20040304 - mww 0x10020000 0x00000000 - mww 0x10000004 0xDFFBFCFB - mww 0x10020004 0xFFFFFFFF - - sleep 100 - - # ======================================== - # Configure DDR on CSD0 -- initial reset - # ======================================== - mww 0xD8001010 0x00000008 - - # ======================================== - # Configure PSRAM on CS5 - # ======================================== - mww 0xd8002050 0x0000dcf6 - mww 0xd8002054 0x444a4541 - mww 0xd8002058 0x44443302 - - # ======================================== - # Configure16 bit NorFlash on CS0 - # ======================================== - mww 0xd8002000 0x0000CC03 - mww 0xd8002004 0xa0330D01 - mww 0xd8002008 0x00220800 - - # ======================================== - # Configure CPLD on CS4 - # ======================================== - mww 0xd8002040 0x0000DCF6 - mww 0xd8002044 0x444A4541 - mww 0xd8002048 0x44443302 - - # ======================================== - # Configure DDR on CSD0 -- wait 5000 cycle - # ======================================== - mww 0x10027828 0x55555555 - mww 0x10027830 0x55555555 - mww 0x10027834 0x55555555 - mww 0x10027838 0x00005005 - mww 0x1002783C 0x15555555 - - mww 0xD8001010 0x00000004 - - mww 0xD8001004 0x00795729 - - mww 0xD8001000 0x92200000 - mww 0xA0000F00 0x0 - - mww 0xD8001000 0xA2200000 - mww 0xA0000F00 0x0 - mww 0xA0000F00 0x0 - - mww 0xD8001000 0xB2200000 - mwb 0xA0000033 0xFF - mwb 0xA1000000 0xAA - - mww 0xD8001000 0x82228085 -} diff --git a/tcl/board/imx27lnst.cfg b/tcl/board/imx27lnst.cfg deleted file mode 100644 index e0ed05794..000000000 --- a/tcl/board/imx27lnst.cfg +++ /dev/null @@ -1,59 +0,0 @@ -# The Linuxstamp-mx27 is board has a single IMX27 chip -# For further info see http://opencircuits.com/Linuxstamp_mx27#OpenOCD -source [find target/imx27.cfg] -$_TARGETNAME configure -event gdb-attach { reset init } -$_TARGETNAME configure -event reset-init { imx27lnst_init } - -proc imx27lnst_init { } { - # This setup puts RAM at 0xA0000000 - - # reset the board correctly - adapter_khz 500 - reset run - reset halt - - mww 0x10000000 0x20040304 - mww 0x10020000 0x00000000 - mww 0x10000004 0xDFFBFCFB - mww 0x10020004 0xFFFFFFFF - - sleep 100 - - # ======================================== - # Configure DDR on CSD0 -- initial reset - # ======================================== - mww 0xD8001010 0x00000008 - - sleep 100 - - # ======================================== - # Configure DDR on CSD0 -- wait 5000 cycle - # ======================================== - mww 0x10027828 0x55555555 - mww 0x10027830 0x55555555 - mww 0x10027834 0x55555555 - mww 0x10027838 0x00005005 - mww 0x1002783C 0x15555555 - - mww 0xD8001010 0x00000004 - - mww 0xD8001004 0x00795729 - - #mww 0xD8001000 0x92200000 - mww 0xD8001000 0x91120000 - mww 0xA0000F00 0x0 - - #mww 0xD8001000 0xA2200000 - mww 0xD8001000 0xA1120000 - mww 0xA0000F00 0x0 - mww 0xA0000F00 0x0 - - #mww 0xD8001000 0xB2200000 - mww 0xD8001000 0xB1120000 - mwb 0xA0000033 0xFF - mwb 0xA1000000 0xAA - - #mww 0xD8001000 0x82228085 - mww 0xD8001000 0x81128080 - -} diff --git a/tcl/board/imx28evk.cfg b/tcl/board/imx28evk.cfg deleted file mode 100644 index a85c2ca67..000000000 --- a/tcl/board/imx28evk.cfg +++ /dev/null @@ -1,168 +0,0 @@ -# The IMX28EVK eval board has a IMX28 chip -# Tested on SCH-26241 Rev D board with Olimex ARM-USB-OCD -# Date: 201-02-01 -# Authors: James Robinson & Fabio Estevam - -source [find target/imx28.cfg] -$_TARGETNAME configure -event gdb-attach { imx28evk_init } -$_TARGETNAME configure -event reset-init { imx28evk_init } - -proc imx28evk_init { } { - - halt - - #**************************** - # VDDD setting - #**************************** - # set VDDD =1.55V =(0.8v + TRIG x 0.025v), TRIG=0x1e - mww 0x80044010 0x0003F503 - mww 0x80044040 0x0002041E - - #**************************** - # CLOCK set up - #**************************** - # Power up PLL0 HW_CLKCTRL_PLL0CTRL0 - mww 0x80040000 0x00020000 - # Set up fractional dividers for CPU and EMI - HW_CLKCTRL_FRAC0 - # EMI - first set DIV_EMI to div-by-2 before programming frac divider - mww 0x800400F0 0x80000002 - - - # CPU: CPUFRAC=19 480*18/29=454.7MHz, EMI: EMIFRAC=22, (480/2)*18/22=196.4MHz - mww 0x800401B0 0x92921613 - # Clear the bypass bits for CPU and EMI clocks in HW_CLKCTRL_CLKSEQ_CLR - mww 0x800401D8 0x00040080 - # HCLK = 227MHz,HW_CLKCTRL_HBUS DIV =0x2 - mww 0x80040060 0x00000002 - - #**************************** - # POWER up DCDD_VDDA (DDR2) - #**************************** - # Now set the voltage level to 1.8V HW_POWER_VDDACTRL bits TRC=0xC - mww 0x80044050 0x0000270C - - #**************************** - # DDR2 DCDD_VDDA - #**************************** - # First set up pin muxing and drive strength - # Ungate module clock and bring out of reset HW_PINCTRL_CTRL_CLR - mww 0x80018008 0xC0000000 - - #**************************** - # EMI PAD setting - #**************************** - # Set up drive strength for EMI pins - mww 0x80019B80 0x00030000 - #IOMUXC_SW_PAD_CTL_GRP_CTLDS - - # Set up pin muxing for EMI, HW_PINCTRL_MUXSEL10, 11, 12, 13 - mww 0x800181A8 0xFFFFFFFF - mww 0x800181B8 0xFFFFFFFF - mww 0x800181C8 0xFFFFFFFF - mww 0x800181D8 0xFFFFFFFF - - #** Ungate EMI clock in CCM - mww 0x800400F0 0x00000002 - - #============================================================================ - # DDR Controller Registers - #============================================================================ - # Manufacturer: Elpida - # Device Part Number: EDE1116AEBG - # Clock Freq.: 200MHz - # Density: 1Gb - # Chip Selects: 1 - # Number of Banks: 8 - # Row address: 13 - # Column address: 10 - #============================================================================ - mww 0x800E0000 0x00000000 - mww 0x800E0040 0x00000000 - mww 0x800E0054 0x00000000 - mww 0x800E0058 0x00000000 - mww 0x800E005C 0x00000000 - mww 0x800E0060 0x00000000 - mww 0x800E0064 0x00000000 - mww 0x800E0068 0x00010101 - mww 0x800E006C 0x01010101 - mww 0x800E0070 0x000f0f01 - mww 0x800E0074 0x0102020A - mww 0x800E007C 0x00010101 - mww 0x800E0080 0x00000100 - mww 0x800E0084 0x00000100 - mww 0x800E0088 0x00000000 - mww 0x800E008C 0x00000002 - mww 0x800E0090 0x01010000 - mww 0x800E0094 0x07080403 - mww 0x800E0098 0x06005003 - mww 0x800E009C 0x0A0000C8 - mww 0x800E00A0 0x02009C40 - mww 0x800E00A4 0x0002030C - mww 0x800E00A8 0x0036B009 - mww 0x800E00AC 0x031A0612 - mww 0x800E00B0 0x02030202 - mww 0x800E00B4 0x00C8001C - mww 0x800E00C0 0x00011900 - mww 0x800E00C4 0xffff0303 - mww 0x800E00C8 0x00012100 - mww 0x800E00CC 0xffff0303 - mww 0x800E00D0 0x00012100 - mww 0x800E00D4 0xffff0303 - mww 0x800E00D8 0x00012100 - mww 0x800E00DC 0xffff0303 - mww 0x800E00E0 0x00000003 - mww 0x800E00E8 0x00000000 - mww 0x800E0108 0x00000612 - mww 0x800E010C 0x01000f02 - mww 0x800E0114 0x00000200 - mww 0x800E0118 0x00020007 - mww 0x800E011C 0xf4004a27 - mww 0x800E0120 0xf4004a27 - mww 0x800E012C 0x07400300 - mww 0x800E0130 0x07400300 - mww 0x800E013C 0x00000005 - mww 0x800E0140 0x00000000 - mww 0x800E0144 0x00000000 - mww 0x800E0148 0x01000000 - mww 0x800E014C 0x01020408 - mww 0x800E0150 0x08040201 - mww 0x800E0154 0x000f1133 - mww 0x800E015C 0x00001f04 - mww 0x800E0160 0x00001f04 - mww 0x800E016C 0x00001f04 - mww 0x800E0170 0x00001f04 - mww 0x800E0288 0x00010000 - mww 0x800E028C 0x00030404 - mww 0x800E0290 0x00000003 - mww 0x800E02AC 0x01010000 - mww 0x800E02B0 0x01000000 - mww 0x800E02B4 0x03030000 - mww 0x800E02B8 0x00010303 - mww 0x800E02BC 0x01020202 - mww 0x800E02C0 0x00000000 - mww 0x800E02C4 0x02030303 - mww 0x800E02C8 0x21002103 - mww 0x800E02CC 0x00061200 - mww 0x800E02D0 0x06120612 - mww 0x800E02D4 0x04420442 - # Mode register 0 for CS1 and CS0, ok to program CS1 even if not used - mww 0x800E02D8 0x00000000 - # Mode register 0 for CS2 and CS3, not supported in this processor - mww 0x800E02DC 0x00040004 - # Mode register 1 for CS1 and CS0, ok to program CS1 even if not used - mww 0x800E02E0 0x00000000 - # Mode register 1 for CS2 and CS3, not supported in this processor - mww 0x800E02E4 0x00000000 - # Mode register 2 for CS1 and CS0, ok to program CS1 even if not used - mww 0x800E02E8 0x00000000 - # Mode register 2 for CS2 and CS3, not supported in this processor - mww 0x800E02EC 0x00000000 - # Mode register 3 for CS1 and CS0, ok to program CS1 even if not used - mww 0x800E02F0 0x00000000 - # Mode register 3 for CS2 and CS3, not supported in this processor - mww 0x800E02F4 0xffffffff - - #** start controller **# - mww 0x800E0040 0x00000001 - # bit[0]: start -} diff --git a/tcl/board/imx31pdk.cfg b/tcl/board/imx31pdk.cfg deleted file mode 100644 index 502d40774..000000000 --- a/tcl/board/imx31pdk.cfg +++ /dev/null @@ -1,99 +0,0 @@ -# The IMX31PDK eval board has a single IMX31 chip -source [find target/imx31.cfg] -source [find target/imx.cfg] -$_TARGETNAME configure -event reset-init { imx31pdk_init } - -proc self_test {} { - echo "Running 100 iterations of test." - dump_image /ram/test 0x80000000 0x40000 - for {set i 0} {$i < 100} {set i [expr $i+1]} { - echo "Iteration $i" - reset init - mww 0x80000000 0x12345678 0x10000 - load_image /ram/test 0x80000000 bin - verify_image /ram/test 0x80000000 bin - } -} - - -# Slow fallback frequency -# measure_clk indicates ca. 3-4MHz. -jtag_rclk 1000 - -proc imx31pdk_init { } { - - imx3x_reset - - # This setup puts RAM at 0x80000000 - - mww 0x53FC0000 0x040 - mww 0x53F80000 0x074B0B7D - - # 399MHz - 26MHz input, PD=1,MFI=7, MFN=27, MFD=40 - #mww 0x53F80004 0xFF871D50 - #mww 0x53F80010 0x00271C1B - - # Start 16 bit NorFlash Initialization on CS0 - mww 0xb8002000 0x0000CC03 - mww 0xb8002004 0xa0330D01 - mww 0xb8002008 0x00220800 - - # Configure CPLD on CS4 - mww 0xb8002040 0x0000DCF6 - mww 0xb8002044 0x444A4541 - mww 0xb8002048 0x44443302 - - # SDCLK - mww 0x43FAC26C 0 - - # CAS - mww 0x43FAC270 0 - - # RAS - mww 0x43FAC274 0 - - # CS2 (CSD0) - mww 0x43FAC27C 0x1000 - - # DQM3 - mww 0x43FAC284 0 - - # DQM2, DQM1, DQM0, SD31-SD0, A25-A0, MA10 (0x288..0x2DC) - mww 0x43FAC288 0 - mww 0x43FAC28C 0 - mww 0x43FAC290 0 - mww 0x43FAC294 0 - mww 0x43FAC298 0 - mww 0x43FAC29C 0 - mww 0x43FAC2A0 0 - mww 0x43FAC2A4 0 - mww 0x43FAC2A8 0 - mww 0x43FAC2AC 0 - mww 0x43FAC2B0 0 - mww 0x43FAC2B4 0 - mww 0x43FAC2B8 0 - mww 0x43FAC2BC 0 - mww 0x43FAC2C0 0 - mww 0x43FAC2C4 0 - mww 0x43FAC2C8 0 - mww 0x43FAC2CC 0 - mww 0x43FAC2D0 0 - mww 0x43FAC2D4 0 - mww 0x43FAC2D8 0 - mww 0x43FAC2DC 0 - - # Initialization script for 32 bit DDR on MX31 ADS - mww 0xB8001010 0x00000004 - mww 0xB8001004 0x006ac73a - mww 0xB8001000 0x92100000 - mww 0x80000f00 0x12344321 - mww 0xB8001000 0xa2100000 - mww 0x80000000 0x12344321 - mww 0x80000000 0x12344321 - mww 0xB8001000 0xb2100000 - mwb 0x80000033 0xda - mwb 0x81000000 0xff - mww 0xB8001000 0x82226080 - mww 0x80000000 0xDEADBEEF - mww 0xB8001010 0x0000000c -} diff --git a/tcl/board/imx35pdk.cfg b/tcl/board/imx35pdk.cfg deleted file mode 100644 index b5aa752fa..000000000 --- a/tcl/board/imx35pdk.cfg +++ /dev/null @@ -1,252 +0,0 @@ -# The IMX35PDK eval board has a single IMX35 chip -source [find target/imx35.cfg] -source [find target/imx.cfg] -$_TARGETNAME configure -event reset-init { imx35pdk_init } - -# Stick to *really* low clock rate or reset will fail -# without RTCK / RCLK -jtag_rclk 10 - -proc imx35pdk_init { } { - - imx3x_reset - - mww 0x43f00040 0x00000000 - mww 0x43f00044 0x00000000 - mww 0x43f00048 0x00000000 - mww 0x43f0004C 0x00000000 - mww 0x43f00050 0x00000000 - mww 0x43f00000 0x77777777 - mww 0x43f00004 0x77777777 - mww 0x53f00040 0x00000000 - mww 0x53f00044 0x00000000 - mww 0x53f00048 0x00000000 - mww 0x53f0004C 0x00000000 - mww 0x53f00050 0x00000000 - mww 0x53f00000 0x77777777 - mww 0x53f00004 0x77777777 - - # clock setup - mww 0x53F80004 0x00821000 ;# first need to set IPU_HND_BYP - mww 0x53F80004 0x00821000 ;#arm clock is 399Mhz and ahb clock is 133Mhz. - - #================================================= - # WEIM config - #================================================= - # CS0U - mww 0xB8002000 0x0000CC03 - # CS0L - mww 0xB8002004 0xA0330D01 - # CS0A - mww 0xB8002008 0x00220800 - # CS5U - mww 0xB8002050 0x0000dcf6 - # CS5L - mww 0xB8002054 0x444a4541 - # CS5A - mww 0xB8002058 0x44443302 - - # IO SW PAD Control registers - setting of 0x0002 is high drive, mDDR - mww 0x43FAC368 0x00000006 - mww 0x43FAC36C 0x00000006 - mww 0x43FAC370 0x00000006 - mww 0x43FAC374 0x00000006 - mww 0x43FAC378 0x00000006 - mww 0x43FAC37C 0x00000006 - mww 0x43FAC380 0x00000006 - mww 0x43FAC384 0x00000006 - mww 0x43FAC388 0x00000006 - mww 0x43FAC38C 0x00000006 - mww 0x43FAC390 0x00000006 - mww 0x43FAC394 0x00000006 - mww 0x43FAC398 0x00000006 - mww 0x43FAC39C 0x00000006 - mww 0x43FAC3A0 0x00000006 - mww 0x43FAC3A4 0x00000006 - mww 0x43FAC3A8 0x00000006 - mww 0x43FAC3AC 0x00000006 - mww 0x43FAC3B0 0x00000006 - mww 0x43FAC3B4 0x00000006 - mww 0x43FAC3B8 0x00000006 - mww 0x43FAC3BC 0x00000006 - mww 0x43FAC3C0 0x00000006 - mww 0x43FAC3C4 0x00000006 - mww 0x43FAC3C8 0x00000006 - mww 0x43FAC3CC 0x00000006 - mww 0x43FAC3D0 0x00000006 - mww 0x43FAC3D4 0x00000006 - mww 0x43FAC3D8 0x00000006 - - # DDR data bus SD 0 through 31 - mww 0x43FAC3DC 0x00000082 - mww 0x43FAC3E0 0x00000082 - mww 0x43FAC3E4 0x00000082 - mww 0x43FAC3E8 0x00000082 - mww 0x43FAC3EC 0x00000082 - mww 0x43FAC3F0 0x00000082 - mww 0x43FAC3F4 0x00000082 - mww 0x43FAC3F8 0x00000082 - mww 0x43FAC3FC 0x00000082 - mww 0x43FAC400 0x00000082 - mww 0x43FAC404 0x00000082 - mww 0x43FAC408 0x00000082 - mww 0x43FAC40C 0x00000082 - mww 0x43FAC410 0x00000082 - mww 0x43FAC414 0x00000082 - mww 0x43FAC418 0x00000082 - mww 0x43FAC41c 0x00000082 - mww 0x43FAC420 0x00000082 - mww 0x43FAC424 0x00000082 - mww 0x43FAC428 0x00000082 - mww 0x43FAC42c 0x00000082 - mww 0x43FAC430 0x00000082 - mww 0x43FAC434 0x00000082 - mww 0x43FAC438 0x00000082 - mww 0x43FAC43c 0x00000082 - mww 0x43FAC440 0x00000082 - mww 0x43FAC444 0x00000082 - mww 0x43FAC448 0x00000082 - mww 0x43FAC44c 0x00000082 - mww 0x43FAC450 0x00000082 - mww 0x43FAC454 0x00000082 - mww 0x43FAC458 0x00000082 - - # DQM setup - mww 0x43FAC45c 0x00000082 - mww 0x43FAC460 0x00000082 - mww 0x43FAC464 0x00000082 - mww 0x43FAC468 0x00000082 - - mww 0x43FAC46c 0x00000006 - mww 0x43FAC470 0x00000006 - mww 0x43FAC474 0x00000006 - mww 0x43FAC478 0x00000006 - mww 0x43FAC47c 0x00000006 - mww 0x43FAC480 0x00000006 ;# CSD0 - mww 0x43FAC484 0x00000006 ;# CSD1 - mww 0x43FAC488 0x00000006 - mww 0x43FAC48c 0x00000006 - mww 0x43FAC490 0x00000006 - mww 0x43FAC494 0x00000006 - mww 0x43FAC498 0x00000006 - mww 0x43FAC49c 0x00000006 - mww 0x43FAC4A0 0x00000006 - mww 0x43FAC4A4 0x00000006 ;# RAS - mww 0x43FAC4A8 0x00000006 ;# CAS - mww 0x43FAC4Ac 0x00000006 ;# SDWE - mww 0x43FAC4B0 0x00000006 ;# SDCKE0 - mww 0x43FAC4B4 0x00000006 ;# SDCKE1 - mww 0x43FAC4B8 0x00000002 ;# SDCLK - - # SDQS0 through SDQS3 - mww 0x43FAC4Bc 0x00000082 - mww 0x43FAC4C0 0x00000082 - mww 0x43FAC4C4 0x00000082 - mww 0x43FAC4C8 0x00000082 - - - # *================================================== - # Initialization script for 32 bit DDR2 on RINGO 3DS - # *================================================== - - #-------------------------------------------- - # Init CCM - #-------------------------------------------- - mww 0x53F80028 0x7D000028 - - #-------------------------------------------- - # Init IOMUX for JTAG - #-------------------------------------------- - mww 0x43FAC5EC 0x000000C3 - mww 0x43FAC5F0 0x000000C3 - mww 0x43FAC5F4 0x000000F3 - mww 0x43FAC5F8 0x000000F3 - mww 0x43FAC5FC 0x000000F3 - mww 0x43FAC600 0x000000F3 - mww 0x43FAC604 0x000000F3 - - - # ESD_MISC : enable DDR2 - mww 0xB8001010 0x00000304 - - #-------------------------------------------- - # Init 32-bit DDR2 memeory on CSD0 - # COL=10-bit, ROW=13-bit, BA[1:0]=Addr[26:25] - #-------------------------------------------- - - # ESD_ESDCFG0 : set timing paramters - mww 0xB8001004 0x007ffC2f - - # ESD_ESDCTL0 : select Prechare-All mode - mww 0xB8001000 0x92220000 - # DDR2 : Prechare-All - mww 0x80000400 0x12345678 - - # ESD_ESDCTL0 : select Load-Mode-Register mode - mww 0xB8001000 0xB2220000 - # DDR2 : Load reg EMR2 - mwb 0x84000000 0xda - # DDR2 : Load reg EMR3 - mwb 0x86000000 0xda - # DDR2 : Load reg EMR1 -- enable DLL - mwb 0x82000400 0xda - # DDR2 : Load reg MR -- reset DLL - mwb 0x80000333 0xda - - # ESD_ESDCTL0 : select Prechare-All mode - mww 0xB8001000 0x92220000 - # DDR2 : Prechare-All - mwb 0x80000400 0x12345678 - - # ESD_ESDCTL0 : select Manual-Refresh mode - mww 0xB8001000 0xA2220000 - # DDR2 : Manual-Refresh 2 times - mww 0x80000000 0x87654321 - mww 0x80000000 0x87654321 - - # ESD_ESDCTL0 : select Load-Mode-Register mode - mww 0xB8001000 0xB2220000 - # DDR2 : Load reg MR -- CL=3, BL=8, end DLL reset - mwb 0x80000233 0xda - # DDR2 : Load reg EMR1 -- OCD default - mwb 0x82000780 0xda - # DDR2 : Load reg EMR1 -- OCD exit - mwb 0x82000400 0xda ;# ODT disabled - - # ESD_ESDCTL0 : select normal-operation mode - # DSIZ=32-bit, BL=8, COL=10-bit, ROW=13-bit - # disable PWT & PRCT - # disable Auto-Refresh - mww 0xB8001000 0x82220080 - - ## ESD_ESDCTL0 : enable Auto-Refresh - mww 0xB8001000 0x82228080 - ## ESD_ESDCTL1 : enable Auto-Refresh - mww 0xB8001008 0x00002000 - - - #*********************************************** - # Adjust the ESDCDLY5 register - #*********************************************** - # Vary DQS_ABS_OFFSET5 for writes - mww 0xB8001020 0x00F48000 ;# this is the default value - mww 0xB8001024 0x00F48000 ;# this is the default value - mww 0xB8001028 0x00F48000 ;# this is the default value - mww 0xB800102c 0x00F48000 ;# this is the default value - - - #Then you can make force measure with the dedicated bit (Bit 7 at ESDMISC) - mww 0xB8001010 0x00000384 - # wait a while - sleep 1000 - # now clear the force measurement bit - mww 0xB8001010 0x00000304 - - # dummy write to DDR memory to set DQS low - mww 0x80000000 0x00000000 - - mww 0x30000100 0x0 - mww 0x30000104 0x31024 - - -} diff --git a/tcl/board/imx53-m53evk.cfg b/tcl/board/imx53-m53evk.cfg deleted file mode 100644 index eada27ab6..000000000 --- a/tcl/board/imx53-m53evk.cfg +++ /dev/null @@ -1,318 +0,0 @@ -####################################### -# DENX M53EVK # -# http://www.denx-cs.de/?q=M53EVK # -# Author: Marek Vasut # -# Based on imx53loco.cfg # -####################################### - -# The DENX M53EVK has on-board JTAG adapter -source [find interface/ftdi/m53evk.cfg] -# The DENX M53EVK board has a single i.MX53 chip -source [find target/imx53.cfg] -# Helper for common memory read/modify/write procedures -source [find mem_helper.tcl] - -echo "iMX53 M53EVK board lodaded." - -# Set reset type -reset_config trst_and_srst separate trst_open_drain srst_open_drain - -# Run at 6 MHz -adapter_khz 6000 - -$_TARGETNAME configure -event "reset-assert" { - echo "Reseting ...." - #cortex_a dbginit -} - -$_TARGETNAME configure -event reset-init { m53evk_init } - -global AIPS1_BASE_ADDR -set AIPS1_BASE_ADDR 0x53F00000 -global AIPS2_BASE_ADDR -set AIPS2_BASE_ADDR 0x63F00000 - -proc m53evk_init { } { - echo "Reset-init..." - ; # halt the CPU - halt - - echo "HW version [format %x [mrw 0x48]]" - - dap apsel 1 - DCD - - ; # ARM errata ID #468414 - set tR [arm mrc 15 0 1 0 1] - arm mcr 15 0 1 0 1 [expr $tR | (1<<5)] ; # enable L1NEON bit - - init_l2cc - init_aips - init_clock - - dap apsel 0 - - ; # Force ARM state - ; #reg cpsr 0x000001D3 - arm core_state arm -} - - -# L2CC Cache setup/invalidation/disable -proc init_l2cc { } { - ; #/* explicitly disable L2 cache */ - ; #mrc 15, 0, r0, c1, c0, 1 - set tR [arm mrc 15 0 1 0 1] - ; #bic r0, r0, #0x2 - ; #mcr 15, 0, r0, c1, c0, 1 - arm mcr 15 0 1 0 1 [expr $tR & ~(1<<2)] - - ; #/* reconfigure L2 cache aux control reg */ - ; #mov r0, #0xC0 /* tag RAM */ - ; #add r0, r0, #0x4 /* data RAM */ - ; #orr r0, r0, #(1 << 24) /* disable write allocate delay */ - ; #orr r0, r0, #(1 << 23) /* disable write allocate combine */ - ; #orr r0, r0, #(1 << 22) /* disable write allocate */ - - ; #mcr 15, 1, r0, c9, c0, 2 - arm mcr 15 1 9 0 2 [expr 0xC4 | (1<<24) | (1<<23) | (1<22)] -} - - -# AIPS setup - Only setup MPROTx registers. -# The PACR default values are good. -proc init_aips { } { - ; # Set all MPROTx to be non-bufferable, trusted for R/W, - ; # not forced to user-mode. - global AIPS1_BASE_ADDR - global AIPS2_BASE_ADDR - set VAL 0x77777777 - -# dap apsel 1 - mww [expr $AIPS1_BASE_ADDR + 0x0] $VAL - mww [expr $AIPS1_BASE_ADDR + 0x4] $VAL - mww [expr $AIPS2_BASE_ADDR + 0x0] $VAL - mww [expr $AIPS2_BASE_ADDR + 0x4] $VAL -# dap apsel 0 -} - - -proc init_clock { } { - global AIPS1_BASE_ADDR - global AIPS2_BASE_ADDR - set CCM_BASE_ADDR [expr $AIPS1_BASE_ADDR + 0x000D4000] - set CLKCTL_CCSR 0x0C - set CLKCTL_CBCDR 0x14 - set CLKCTL_CBCMR 0x18 - set PLL1_BASE_ADDR [expr $AIPS2_BASE_ADDR + 0x00080000] - set PLL2_BASE_ADDR [expr $AIPS2_BASE_ADDR + 0x00084000] - set PLL3_BASE_ADDR [expr $AIPS2_BASE_ADDR + 0x00088000] - set PLL4_BASE_ADDR [expr $AIPS2_BASE_ADDR + 0x0008C000] - set CLKCTL_CSCMR1 0x1C - set CLKCTL_CDHIPR 0x48 - set PLATFORM_BASE_ADDR [expr $AIPS2_BASE_ADDR + 0x000A0000] - set CLKCTL_CSCDR1 0x24 - set CLKCTL_CCDR 0x04 - - ; # Switch ARM to step clock - mww [expr $CCM_BASE_ADDR + $CLKCTL_CCSR] 0x4 - - return - echo "not returned" - setup_pll $PLL1_BASE_ADDR 800 - setup_pll $PLL3_BASE_ADDR 400 - - ; # Switch peripheral to PLL3 - mww [expr $CCM_BASE_ADDR + $CLKCTL_CBCMR] 0x00015154 - mww [expr $CCM_BASE_ADDR + $CLKCTL_CBCDR] [expr 0x02888945 | (1<<16)] - while {[mrw [expr $CCM_BASE_ADDR + $CLKCTL_CDHIPR]] != 0} { sleep 1 } - - setup_pll $PLL2_BASE_ADDR 400 - - ; # Switch peripheral to PLL2 - mww [expr $CCM_BASE_ADDR + $CLKCTL_CBCDR] [expr 0x00808145 | (2<<10) | (9<<16) | (1<<19)] - - mww [expr $CCM_BASE_ADDR + $CLKCTL_CBCMR] 0x00016154 - - ; # change uart clk parent to pll2 - mww [expr $CCM_BASE_ADDR + $CLKCTL_CSCMR1] [expr [mrw [expr $CCM_BASE_ADDR + $CLKCTL_CSCMR1]] & 0xfcffffff | 0x01000000] - - ; # make sure change is effective - while {[mrw [expr $CCM_BASE_ADDR + $CLKCTL_CDHIPR]] != 0} { sleep 1 } - - setup_pll $PLL3_BASE_ADDR 216 - - setup_pll $PLL4_BASE_ADDR 455 - - ; # Set the platform clock dividers - mww [expr $PLATFORM_BASE_ADDR + 0x14] 0x00000124 - - mww [expr $CCM_BASE_ADDR + 0x10] 0 - - ; # Switch ARM back to PLL 1. - mww [expr $CCM_BASE_ADDR + $CLKCTL_CCSR] 0x0 - - ; # make uart div=6 - mww [expr $CCM_BASE_ADDR + $CLKCTL_CSCDR1] [expr [mrw [expr $CCM_BASE_ADDR + $CLKCTL_CSCDR1]] & 0xffffffc0 | 0x0a] - - ; # Restore the default values in the Gate registers - mww [expr $CCM_BASE_ADDR + 0x68] 0xFFFFFFFF - mww [expr $CCM_BASE_ADDR + 0x6C] 0xFFFFFFFF - mww [expr $CCM_BASE_ADDR + 0x70] 0xFFFFFFFF - mww [expr $CCM_BASE_ADDR + 0x74] 0xFFFFFFFF - mww [expr $CCM_BASE_ADDR + 0x78] 0xFFFFFFFF - mww [expr $CCM_BASE_ADDR + 0x7C] 0xFFFFFFFF - mww [expr $CCM_BASE_ADDR + 0x80] 0xFFFFFFFF - mww [expr $CCM_BASE_ADDR + 0x84] 0xFFFFFFFF - - mww [expr $CCM_BASE_ADDR + $CLKCTL_CCDR] 0x00000 - - ; # for cko - for ARM div by 8 - mww [expr $CCM_BASE_ADDR + 0x60] [expr 0x000A0000 & 0x00000F0] -} - - -proc setup_pll { PLL_ADDR CLK } { - set PLL_DP_CTL 0x00 - set PLL_DP_CONFIG 0x04 - set PLL_DP_OP 0x08 - set PLL_DP_HFS_OP 0x1C - set PLL_DP_MFD 0x0C - set PLL_DP_HFS_MFD 0x20 - set PLL_DP_MFN 0x10 - set PLL_DP_HFS_MFN 0x24 - - if {$CLK == 1000} { - set DP_OP [expr (10 << 4) + ((1 - 1) << 0)] - set DP_MFD [expr (12 - 1)] - set DP_MFN 5 - } elseif {$CLK == 850} { - set DP_OP [expr (8 << 4) + ((1 - 1) << 0)] - set DP_MFD [expr (48 - 1)] - set DP_MFN 41 - } elseif {$CLK == 800} { - set DP_OP [expr (8 << 4) + ((1 - 1) << 0)] - set DP_MFD [expr (3 - 1)] - set DP_MFN 1 - } elseif {$CLK == 700} { - set DP_OP [expr (7 << 4) + ((1 - 1) << 0)] - set DP_MFD [expr (24 - 1)] - set DP_MFN 7 - } elseif {$CLK == 600} { - set DP_OP [expr (6 << 4) + ((1 - 1) << 0)] - set DP_MFD [expr (4 - 1)] - set DP_MFN 1 - } elseif {$CLK == 665} { - set DP_OP [expr (6 << 4) + ((1 - 1) << 0)] - set DP_MFD [expr (96 - 1)] - set DP_MFN 89 - } elseif {$CLK == 532} { - set DP_OP [expr (5 << 4) + ((1 - 1) << 0)] - set DP_MFD [expr (24 - 1)] - set DP_MFN 13 - } elseif {$CLK == 455} { - set DP_OP [expr (8 << 4) + ((2 - 1) << 0)] - set DP_MFD [expr (48 - 1)] - set DP_MFN 71 - } elseif {$CLK == 400} { - set DP_OP [expr (8 << 4) + ((2 - 1) << 0)] - set DP_MFD [expr (3 - 1)] - set DP_MFN 1 - } elseif {$CLK == 216} { - set DP_OP [expr (6 << 4) + ((3 - 1) << 0)] - set DP_MFD [expr (4 - 1)] - set DP_MFN 3 - } else { - error "Error (setup_dll): clock not found!" - } - - mww [expr $PLL_ADDR + $PLL_DP_CTL] 0x00001232 - mww [expr $PLL_ADDR + $PLL_DP_CONFIG] 0x2 - - mww [expr $PLL_ADDR + $PLL_DP_OP] $DP_OP - mww [expr $PLL_ADDR + $PLL_DP_HFS_MFD] $DP_OP - - mww [expr $PLL_ADDR + $PLL_DP_MFD] $DP_MFD - mww [expr $PLL_ADDR + $PLL_DP_HFS_MFD] $DP_MFD - - mww [expr $PLL_ADDR + $PLL_DP_MFN] $DP_MFN - mww [expr $PLL_ADDR + $PLL_DP_HFS_MFN] $DP_MFN - - mww [expr $PLL_ADDR + $PLL_DP_CTL] 0x00001232 - while {[expr [mrw [expr $PLL_ADDR + $PLL_DP_CTL]] & 0x1] == 0} { sleep 1 } -} - - -proc CPU_2_BE_32 { L } { - return [expr (($L & 0x000000FF) << 24) | (($L & 0x0000FF00) << 8) | (($L & 0x00FF0000) >> 8) | (($L & 0xFF000000) >> 24)] -} - - -# Device Configuration Data -proc DCD { } { -# dap apsel 1 - mww 0x53fa86f4 0x00000000 ;# GRP_DDRMODE_CTL - mww 0x53fa8714 0x00000000 ;# GRP_DDRMODE - mww 0x53fa86fc 0x00000000 ;# GRP_DDRPKE - mww 0x53fa8724 0x04000000 ;# GRP_DDR_TYPE - - mww 0x53fa872c 0x00300000 ;# GRP_B3DS - mww 0x53fa8554 0x00300000 ;# DRAM_DQM3 - mww 0x53fa8558 0x00300040 ;# DRAM_SDQS3 - - mww 0x53fa8728 0x00300000 ;# GRP_B2DS - mww 0x53fa8560 0x00300000 ;# DRAM_DQM2 - mww 0x53fa8568 0x00300040 ;# DRAM_SDQS2 - - mww 0x53fa871c 0x00300000 ;# GRP_B1DS - mww 0x53fa8594 0x00300000 ;# DRAM_DQM1 - mww 0x53fa8590 0x00300040 ;# DRAM_SDQS1 - - mww 0x53fa8718 0x00300000 ;# GRP_B0DS - mww 0x53fa8584 0x00300000 ;# DRAM_DQM0 - mww 0x53fa857c 0x00300040 ;# DRAM_SDQS0 - - mww 0x53fa8578 0x00300000 ;# DRAM_SDCLK_0 - mww 0x53fa8570 0x00300000 ;# DRAM_SDCLK_1 - - mww 0x53fa8574 0x00300000 ;# DRAM_CAS - mww 0x53fa8588 0x00300000 ;# DRAM_RAS - mww 0x53fa86f0 0x00300000 ;# GRP_ADDDS - mww 0x53fa8720 0x00300000 ;# GRP_CTLDS - - mww 0x53fa8564 0x00300040 ;# DRAM_SDODT1 - mww 0x53fa8580 0x00300040 ;# DRAM_SDODT0 - - # Initialize DDR2 memory - mww 0x63fd9088 0x32383535 - mww 0x63fd9090 0x40383538 - mww 0x63fd907c 0x0136014d - mww 0x63fd9080 0x01510141 - - mww 0x63fd9018 0x00011740 - mww 0x63fd9000 0xc3190000 - mww 0x63fd900c 0x555952e3 - mww 0x63fd9010 0xb68e8b63 - mww 0x63fd9014 0x01ff00db - mww 0x63fd902c 0x000026d2 - mww 0x63fd9030 0x009f0e21 - mww 0x63fd9008 0x12273030 - mww 0x63fd9004 0x0002002d - mww 0x63fd901c 0x00008032 - mww 0x63fd901c 0x00008033 - mww 0x63fd901c 0x00028031 - mww 0x63fd901c 0x092080b0 - mww 0x63fd901c 0x04008040 - mww 0x63fd901c 0x0000803a - mww 0x63fd901c 0x0000803b - mww 0x63fd901c 0x00028039 - mww 0x63fd901c 0x09208138 - mww 0x63fd901c 0x04008048 - mww 0x63fd9020 0x00001800 - mww 0x63fd9040 0x04b80003 - mww 0x63fd9058 0x00022227 - mww 0x63fd901c 0x00000000 -# dap apsel 0 -} - -# vim:filetype=tcl diff --git a/tcl/board/imx53loco.cfg b/tcl/board/imx53loco.cfg deleted file mode 100644 index 06c399378..000000000 --- a/tcl/board/imx53loco.cfg +++ /dev/null @@ -1,315 +0,0 @@ -################################################################################## -# Author: Wjatscheslaw Stoljarski (Slawa) # -# Kiwigrid GmbH # -################################################################################## - -# The IMX53LOCO (QSB) board has a single IMX53 chip -source [find target/imx53.cfg] -# Helper for common memory read/modify/write procedures -source [find mem_helper.tcl] - -echo "iMX53 Loco board lodaded." - -# Set reset type -#reset_config srst_only - -adapter_khz 3000 - -# Slow speed to be sure it will work -jtag_rclk 1000 -$_TARGETNAME configure -event "reset-start" { jtag_rclk 1000 } - -#jtag_nsrst_delay 200 -#jtag_ntrst_delay 200 - -$_TARGETNAME configure -event "reset-assert" { - echo "Reseting ...." - #cortex_a dbginit -} - -$_TARGETNAME configure -event reset-init { loco_init } - -global AIPS1_BASE_ADDR -set AIPS1_BASE_ADDR 0x53F00000 -global AIPS2_BASE_ADDR -set AIPS2_BASE_ADDR 0x63F00000 - -proc loco_init { } { - echo "Reset-init..." - ; # halt the CPU - halt - - echo "HW version [format %x [mrw 0x48]]" - - dap apsel 1 - DCD - - ; # ARM errata ID #468414 - set tR [arm mrc 15 0 1 0 1] - arm mcr 15 0 1 0 1 [expr $tR | (1<<5)] ; # enable L1NEON bit - - init_l2cc - init_aips - init_clock - - dap apsel 0 - - ; # Force ARM state - ; #reg cpsr 0x000001D3 - arm core_state arm - - jtag_rclk 3000 -# adapter_khz 3000 -} - - -# L2CC Cache setup/invalidation/disable -proc init_l2cc { } { - ; #/* explicitly disable L2 cache */ - ; #mrc 15, 0, r0, c1, c0, 1 - set tR [arm mrc 15 0 1 0 1] - ; #bic r0, r0, #0x2 - ; #mcr 15, 0, r0, c1, c0, 1 - arm mcr 15 0 1 0 1 [expr $tR & ~(1<<2)] - - ; #/* reconfigure L2 cache aux control reg */ - ; #mov r0, #0xC0 /* tag RAM */ - ; #add r0, r0, #0x4 /* data RAM */ - ; #orr r0, r0, #(1 << 24) /* disable write allocate delay */ - ; #orr r0, r0, #(1 << 23) /* disable write allocate combine */ - ; #orr r0, r0, #(1 << 22) /* disable write allocate */ - - ; #mcr 15, 1, r0, c9, c0, 2 - arm mcr 15 1 9 0 2 [expr 0xC4 | (1<<24) | (1<<23) | (1<22)] -} - - -# AIPS setup - Only setup MPROTx registers. -# The PACR default values are good. -proc init_aips { } { - ; # Set all MPROTx to be non-bufferable, trusted for R/W, - ; # not forced to user-mode. - global AIPS1_BASE_ADDR - global AIPS2_BASE_ADDR - set VAL 0x77777777 - -# dap apsel 1 - mww [expr $AIPS1_BASE_ADDR + 0x0] $VAL - mww [expr $AIPS1_BASE_ADDR + 0x4] $VAL - mww [expr $AIPS2_BASE_ADDR + 0x0] $VAL - mww [expr $AIPS2_BASE_ADDR + 0x4] $VAL -# dap apsel 0 -} - - -proc init_clock { } { - global AIPS1_BASE_ADDR - global AIPS2_BASE_ADDR - set CCM_BASE_ADDR [expr $AIPS1_BASE_ADDR + 0x000D4000] - set CLKCTL_CCSR 0x0C - set CLKCTL_CBCDR 0x14 - set CLKCTL_CBCMR 0x18 - set PLL1_BASE_ADDR [expr $AIPS2_BASE_ADDR + 0x00080000] - set PLL2_BASE_ADDR [expr $AIPS2_BASE_ADDR + 0x00084000] - set PLL3_BASE_ADDR [expr $AIPS2_BASE_ADDR + 0x00088000] - set PLL4_BASE_ADDR [expr $AIPS2_BASE_ADDR + 0x0008C000] - set CLKCTL_CSCMR1 0x1C - set CLKCTL_CDHIPR 0x48 - set PLATFORM_BASE_ADDR [expr $AIPS2_BASE_ADDR + 0x000A0000] - set CLKCTL_CSCDR1 0x24 - set CLKCTL_CCDR 0x04 - - ; # Switch ARM to step clock - mww [expr $CCM_BASE_ADDR + $CLKCTL_CCSR] 0x4 - - return - echo "not returned" - setup_pll $PLL1_BASE_ADDR 800 - setup_pll $PLL3_BASE_ADDR 400 - - ; # Switch peripheral to PLL3 - mww [expr $CCM_BASE_ADDR + $CLKCTL_CBCMR] 0x00015154 - mww [expr $CCM_BASE_ADDR + $CLKCTL_CBCDR] [expr 0x02888945 | (1<<16)] - while {[mrw [expr $CCM_BASE_ADDR + $CLKCTL_CDHIPR]] != 0} { sleep 1 } - - setup_pll $PLL2_BASE_ADDR 400 - - ; # Switch peripheral to PLL2 - mww [expr $CCM_BASE_ADDR + $CLKCTL_CBCDR] [expr 0x00808145 | (2<<10) | (9<<16) | (1<<19)] - - mww [expr $CCM_BASE_ADDR + $CLKCTL_CBCMR] 0x00016154 - - ; # change uart clk parent to pll2 - mww [expr $CCM_BASE_ADDR + $CLKCTL_CSCMR1] [expr [mrw [expr $CCM_BASE_ADDR + $CLKCTL_CSCMR1]] & 0xfcffffff | 0x01000000] - - ; # make sure change is effective - while {[mrw [expr $CCM_BASE_ADDR + $CLKCTL_CDHIPR]] != 0} { sleep 1 } - - setup_pll $PLL3_BASE_ADDR 216 - - setup_pll $PLL4_BASE_ADDR 455 - - ; # Set the platform clock dividers - mww [expr $PLATFORM_BASE_ADDR + 0x14] 0x00000124 - - mww [expr $CCM_BASE_ADDR + 0x10] 0 - - ; # Switch ARM back to PLL 1. - mww [expr $CCM_BASE_ADDR + $CLKCTL_CCSR] 0x0 - - ; # make uart div=6 - mww [expr $CCM_BASE_ADDR + $CLKCTL_CSCDR1] [expr [mrw [expr $CCM_BASE_ADDR + $CLKCTL_CSCDR1]] & 0xffffffc0 | 0x0a] - - ; # Restore the default values in the Gate registers - mww [expr $CCM_BASE_ADDR + 0x68] 0xFFFFFFFF - mww [expr $CCM_BASE_ADDR + 0x6C] 0xFFFFFFFF - mww [expr $CCM_BASE_ADDR + 0x70] 0xFFFFFFFF - mww [expr $CCM_BASE_ADDR + 0x74] 0xFFFFFFFF - mww [expr $CCM_BASE_ADDR + 0x78] 0xFFFFFFFF - mww [expr $CCM_BASE_ADDR + 0x7C] 0xFFFFFFFF - mww [expr $CCM_BASE_ADDR + 0x80] 0xFFFFFFFF - mww [expr $CCM_BASE_ADDR + 0x84] 0xFFFFFFFF - - mww [expr $CCM_BASE_ADDR + $CLKCTL_CCDR] 0x00000 - - ; # for cko - for ARM div by 8 - mww [expr $CCM_BASE_ADDR + 0x60] [expr 0x000A0000 & 0x00000F0] -} - - -proc setup_pll { PLL_ADDR CLK } { - set PLL_DP_CTL 0x00 - set PLL_DP_CONFIG 0x04 - set PLL_DP_OP 0x08 - set PLL_DP_HFS_OP 0x1C - set PLL_DP_MFD 0x0C - set PLL_DP_HFS_MFD 0x20 - set PLL_DP_MFN 0x10 - set PLL_DP_HFS_MFN 0x24 - - if {$CLK == 1000} { - set DP_OP [expr (10 << 4) + ((1 - 1) << 0)] - set DP_MFD [expr (12 - 1)] - set DP_MFN 5 - } elseif {$CLK == 850} { - set DP_OP [expr (8 << 4) + ((1 - 1) << 0)] - set DP_MFD [expr (48 - 1)] - set DP_MFN 41 - } elseif {$CLK == 800} { - set DP_OP [expr (8 << 4) + ((1 - 1) << 0)] - set DP_MFD [expr (3 - 1)] - set DP_MFN 1 - } elseif {$CLK == 700} { - set DP_OP [expr (7 << 4) + ((1 - 1) << 0)] - set DP_MFD [expr (24 - 1)] - set DP_MFN 7 - } elseif {$CLK == 600} { - set DP_OP [expr (6 << 4) + ((1 - 1) << 0)] - set DP_MFD [expr (4 - 1)] - set DP_MFN 1 - } elseif {$CLK == 665} { - set DP_OP [expr (6 << 4) + ((1 - 1) << 0)] - set DP_MFD [expr (96 - 1)] - set DP_MFN 89 - } elseif {$CLK == 532} { - set DP_OP [expr (5 << 4) + ((1 - 1) << 0)] - set DP_MFD [expr (24 - 1)] - set DP_MFN 13 - } elseif {$CLK == 455} { - set DP_OP [expr (8 << 4) + ((2 - 1) << 0)] - set DP_MFD [expr (48 - 1)] - set DP_MFN 71 - } elseif {$CLK == 400} { - set DP_OP [expr (8 << 4) + ((2 - 1) << 0)] - set DP_MFD [expr (3 - 1)] - set DP_MFN 1 - } elseif {$CLK == 216} { - set DP_OP [expr (6 << 4) + ((3 - 1) << 0)] - set DP_MFD [expr (4 - 1)] - set DP_MFN 3 - } else { - error "Error (setup_dll): clock not found!" - } - - mww [expr $PLL_ADDR + $PLL_DP_CTL] 0x00001232 - mww [expr $PLL_ADDR + $PLL_DP_CONFIG] 0x2 - - mww [expr $PLL_ADDR + $PLL_DP_OP] $DP_OP - mww [expr $PLL_ADDR + $PLL_DP_HFS_MFD] $DP_OP - - mww [expr $PLL_ADDR + $PLL_DP_MFD] $DP_MFD - mww [expr $PLL_ADDR + $PLL_DP_HFS_MFD] $DP_MFD - - mww [expr $PLL_ADDR + $PLL_DP_MFN] $DP_MFN - mww [expr $PLL_ADDR + $PLL_DP_HFS_MFN] $DP_MFN - - mww [expr $PLL_ADDR + $PLL_DP_CTL] 0x00001232 - while {[expr [mrw [expr $PLL_ADDR + $PLL_DP_CTL]] & 0x1] == 0} { sleep 1 } -} - - -proc CPU_2_BE_32 { L } { - return [expr (($L & 0x000000FF) << 24) | (($L & 0x0000FF00) << 8) | (($L & 0x00FF0000) >> 8) | (($L & 0xFF000000) >> 24)] -} - - -# Device Configuration Data -proc DCD { } { -# dap apsel 1 - mww 0x53FA8554 0x00300000 ;# IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM3 - mww 0x53FA8558 0x00300040 ;# IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS3 - mww 0x53FA8560 0x00300000 ;# IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM2 - mww 0x53FA8564 0x00300040 ;# IOMUXC_SW_PAD_CTL_PAD_DRAM_SDODT - mww 0x53FA8568 0x00300040 ;# IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS2 - mww 0x53FA8570 0x00300000 ;# IOMUXC_SW_PAD_CTL_PAD_DRAM_SDCLK_1 - mww 0x53FA8574 0x00300000 ;# IOMUXC_SW_PAD_CTL_PAD_DRAM_CAS - mww 0x53FA8578 0x00300000 ;# IOMUXC_SW_PAD_CTL_PAD_DRAM_SDCLK_0 - mww 0x53FA857c 0x00300040 ;# IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS0 - mww 0x53FA8580 0x00300040 ;# IOMUXC_SW_PAD_CTL_PAD_DRAM_SDODT0 - mww 0x53FA8584 0x00300000 ;# IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM0 - mww 0x53FA8588 0x00300000 ;# IOMUXC_SW_PAD_CTL_PAD_DRAM_RAS - mww 0x53FA8590 0x00300040 ;# IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS1 - mww 0x53FA8594 0x00300000 ;# IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM1 - mww 0x53FA86f0 0x00300000 ;# IOMUXC_SW_PAD_CTL_GRP_ADDDS - mww 0x53FA86f4 0x00000000 ;# IOMUXC_SW_PAD_CTL_GRP_DDRMODE_CTL - mww 0x53FA86fc 0x00000000 ;# IOMUXC_SW_PAD_CTL_GRP_DDRPKE - mww 0x53FA8714 0x00000000 ;# IOMUXC_SW_PAD_CTL_GRP_DDRMODE - CMOS mode - mww 0x53FA8718 0x00300000 ;# IOMUXC_SW_PAD_CTL_GRP_B0DS - mww 0x53FA871c 0x00300000 ;# IOMUXC_SW_PAD_CTL_GRP_B1DS - mww 0x53FA8720 0x00300000 ;# IOMUXC_SW_PAD_CTL_GRP_CTLDS - mww 0x53FA8724 0x04000000 ;# IOMUXC_SW_PAD_CTL_GRP_DDR_TYPE - DDR_SEL0= - mww 0x53FA8728 0x00300000 ;# IOMUXC_SW_PAD_CTL_GRP_B2DS - mww 0x53FA872c 0x00300000 ;# IOMUXC_SW_PAD_CTL_GRP_B3DS - - # Initialize DDR2 memory - mww 0x63FD9088 0x35343535 ;# ESDCTL_RDDLCTL - mww 0x63FD9090 0x4d444c44 ;# ESDCTL_WRDLCTL - mww 0x63FD907c 0x01370138 ;# ESDCTL_DGCTRL0 - mww 0x63FD9080 0x013b013c ;# ESDCTL_DGCTRL1 - mww 0x63FD9018 0x00011740 ;# ESDCTL_ESDMISC - mww 0x63FD9000 0xc3190000 ;# ESDCTL_ESDCTL - mww 0x63FD900c 0x9f5152e3 ;# ESDCTL_ESDCFG0 - mww 0x63FD9010 0xb68e8a63 ;# ESDCTL_ESDCFG1 - mww 0x63FD9014 0x01ff00db ;# ESDCTL_ESDCFG2 - mww 0x63FD902c 0x000026d2 ;# ESDCTL_ESDRWD - mww 0x63FD9030 0x009f0e21 ;# ESDCTL_ESDOR - mww 0x63FD9008 0x12273030 ;# ESDCTL_ESDOTC - mww 0x63FD9004 0x0002002d ;# ESDCTL_ESDPDC - mww 0x63FD901c 0x00008032 ;# ESDCTL_ESDSCR - mww 0x63FD901c 0x00008033 ;# ESDCTL_ESDSCR - mww 0x63FD901c 0x00028031 ;# ESDCTL_ESDSCR - mww 0x63FD901c 0x052080b0 ;# ESDCTL_ESDSCR - mww 0x63FD901c 0x04008040 ;# ESDCTL_ESDSCR - mww 0x63FD901c 0x0000803a ;# ESDCTL_ESDSCR - mww 0x63FD901c 0x0000803b ;# ESDCTL_ESDSCR - mww 0x63FD901c 0x00028039 ;# ESDCTL_ESDSCR - mww 0x63FD901c 0x05208138 ;# ESDCTL_ESDSCR - mww 0x63FD901c 0x04008048 ;# ESDCTL_ESDSCR - mww 0x63FD9020 0x00005800 ;# ESDCTL_ESDREF - mww 0x63FD9040 0x04b80003 ;# ESDCTL_ZQHWCTRL - mww 0x63FD9058 0x00022227 ;# ESDCTL_ODTCTRL - mww 0x63FD901C 0x00000000 ;# ESDCTL_ESDSCR -# dap apsel 0 -} - -# vim:filetype=tcl diff --git a/tcl/board/insignal_arndale.cfg b/tcl/board/insignal_arndale.cfg deleted file mode 100644 index 25c123e7b..000000000 --- a/tcl/board/insignal_arndale.cfg +++ /dev/null @@ -1,8 +0,0 @@ -# -# InSignal Arndale board -# - -source [find target/exynos5250.cfg] - -# Experimentally determined highest working speed -adapter_khz 200 diff --git a/tcl/board/kc705.cfg b/tcl/board/kc705.cfg deleted file mode 100644 index 39f7fa39c..000000000 --- a/tcl/board/kc705.cfg +++ /dev/null @@ -1,15 +0,0 @@ -# http://www.xilinx.com/products/boards-and-kits/ek-k7-kc705-g.html - -source [find interface/ftdi/digilent-hs1.cfg] -source [find cpld/xilinx-xc7.cfg] -source [find cpld/jtagspi.cfg] -adapter_khz 25000 - -# example command to write bitstream, soft-cpu bios and runtime: -# openocd -f board/kc705.cfg -c "init;\ -# jtagspi_init 0 bscan_spi_xc7k325t.bit;\ -# jtagspi_program bitstream-kc705.bin 0;\ -# jtagspi_program bios.bin 0xaf0000;\ -# jtagspi_program runtime.fbi 0xb00000;\ -# xc7_program xc7.tap;\ -# exit" diff --git a/tcl/board/keil_mcb1700.cfg b/tcl/board/keil_mcb1700.cfg deleted file mode 100644 index d63d3ede9..000000000 --- a/tcl/board/keil_mcb1700.cfg +++ /dev/null @@ -1,8 +0,0 @@ -# -# Keil MCB1700 eval board -# -# http://www.keil.com/mcb1700/picture.asp -# - -source [find target/lpc17xx.cfg] - diff --git a/tcl/board/keil_mcb2140.cfg b/tcl/board/keil_mcb2140.cfg deleted file mode 100644 index db81efad5..000000000 --- a/tcl/board/keil_mcb2140.cfg +++ /dev/null @@ -1,8 +0,0 @@ -# -# Keil MCB2140 eval board -# -# http://www.keil.com/mcb2140/picture.asp -# - -source [find target/lpc2148.cfg] - diff --git a/tcl/board/kwikstik.cfg b/tcl/board/kwikstik.cfg deleted file mode 100644 index f936d6e92..000000000 --- a/tcl/board/kwikstik.cfg +++ /dev/null @@ -1,12 +0,0 @@ -# -# Freescale KwikStik development board -# - -# -# JLINK interface is onboard -# -source [find interface/jlink.cfg] - -source [find target/k40.cfg] - -reset_config trst_and_srst diff --git a/tcl/board/la_fonera-fon2200.cfg b/tcl/board/la_fonera-fon2200.cfg deleted file mode 100644 index f46b04200..000000000 --- a/tcl/board/la_fonera-fon2200.cfg +++ /dev/null @@ -1,3 +0,0 @@ -source [find target/atheros_ar2315.cfg] - -reset_config trst_and_srst diff --git a/tcl/board/linksys-wrt54gl.cfg b/tcl/board/linksys-wrt54gl.cfg deleted file mode 100644 index ffe53ffbb..000000000 --- a/tcl/board/linksys-wrt54gl.cfg +++ /dev/null @@ -1,15 +0,0 @@ -# -# Linksys WRT54GL v1.1 -# - -source [find target/bcm5352e.cfg] - -set partition_list { - CFE { Bootloader 0x1c000000 0x00040000 } - firmware { "Kernel+rootfs" 0x1c040000 0x003b0000 } - nvram { "Config space" 0x1c3f0000 0x00010000 } -} - -# External 4MB NOR Flash (Intel TE28F320C3BD90 or similar) -set _FLASHNAME $_CHIPNAME.flash -flash bank $_FLASHNAME cfi 0x1c000000 0x00400000 2 2 $_TARGETNAME diff --git a/tcl/board/linksys_nslu2.cfg b/tcl/board/linksys_nslu2.cfg deleted file mode 100644 index e605fc19e..000000000 --- a/tcl/board/linksys_nslu2.cfg +++ /dev/null @@ -1,8 +0,0 @@ -# This is for the LinkSys (CISCO) NSLU2 board -# It is an Intel XSCALE IXP420 CPU. - -source [find target/ixp42x.cfg] -# The _TARGETNAME is set by the above. - -$_TARGETNAME configure -work-area-phys 0x00020000 -work-area-size 0x10000 -work-area-backup 0 - diff --git a/tcl/board/lisa-l.cfg b/tcl/board/lisa-l.cfg deleted file mode 100644 index 73f51a26d..000000000 --- a/tcl/board/lisa-l.cfg +++ /dev/null @@ -1,7 +0,0 @@ -# the Lost Illusions Serendipitous Autopilot -# http://paparazzi.enac.fr/wiki/Lisa - -# Work-area size (RAM size) = 20kB for STM32F103RB device -set WORKAREASIZE 0x5000 - -source [find target/stm32f1x.cfg] diff --git a/tcl/board/logicpd_imx27.cfg b/tcl/board/logicpd_imx27.cfg deleted file mode 100644 index da0b46223..000000000 --- a/tcl/board/logicpd_imx27.cfg +++ /dev/null @@ -1,13 +0,0 @@ -# The LogicPD Eval IMX27 eval board has a single IMX27 chip -source [find target/imx27.cfg] - -# The Logic PD board has a NOR flash on CS0 -set _FLASHNAME $_CHIPNAME.flash -flash bank $_FLASHNAME cfi 0xc0000000 0x00200000 2 2 $_TARGETNAME - -# -# FIX ME, Add support to -# -# (A) hard reset the board. -# (B) Initialize the SDRAM on the board -# diff --git a/tcl/board/lpc1850_spifi_generic.cfg b/tcl/board/lpc1850_spifi_generic.cfg deleted file mode 100644 index bff4af605..000000000 --- a/tcl/board/lpc1850_spifi_generic.cfg +++ /dev/null @@ -1,18 +0,0 @@ -# -# Generic LPC1850 board w/ SPIFI flash. -# This config file is intended as an example of how to -# use the lpcspifi flash driver, but it should be functional -# for most LPC1850 boards utilizing SPIFI flash. - -set CHIPNAME lpc1850 - -source [find target/lpc1850.cfg] - -#A large working area greatly reduces flash write times -set _WORKAREASIZE 0x4000 - -$_CHIPNAME.m3 configure -work-area-phys 0x10000000 -work-area-size $_WORKAREASIZE - -#Configure the flash bank; 0x14000000 is the base address for -#lpc43xx/lpc18xx family micros. -flash bank SPIFI_FLASH lpcspifi 0x14000000 0 0 0 $_CHIPNAME.m3 diff --git a/tcl/board/lpc4350_spifi_generic.cfg b/tcl/board/lpc4350_spifi_generic.cfg deleted file mode 100644 index b363f1eff..000000000 --- a/tcl/board/lpc4350_spifi_generic.cfg +++ /dev/null @@ -1,13 +0,0 @@ -# -# Generic LPC4350 board w/ SPIFI flash. -# This config file is intended as an example of how to -# use the lpcspifi flash driver, but it should be functional -# for most LPC4350 boards utilizing SPIFI flash. - -set CHIPNAME lpc4350 - -source [find target/lpc4350.cfg] - -#Configure the flash bank; 0x14000000 is the base address for -#lpc43xx/lpc18xx family micros. -flash bank SPIFI_FLASH lpcspifi 0x14000000 0 0 0 $_CHIPNAME.m4 diff --git a/tcl/board/lubbock.cfg b/tcl/board/lubbock.cfg deleted file mode 100644 index 298954cc0..000000000 --- a/tcl/board/lubbock.cfg +++ /dev/null @@ -1,112 +0,0 @@ -# Intel "Lubbock" Development Board with PXA255 (dbpxa255) -# Obsolete; this was Intel's original PXA255 development system -# Board also had CPU cards for SA1100, PXA210, PXA250, and more. - -source [find target/pxa255.cfg] - -adapter_nsrst_delay 250 -jtag_ntrst_delay 250 - -# NOTE: until after pinmux and such are set up, only CS0 is -# available ... not 2nd bank of CFI, or FPGA, SRAM, ENET, etc. - -# CS0, CS1 -- two banks of CFI flash, 32 MBytes each -# each bank is 32-bits wide, two 16-bit chips in parallel -set _FLASHNAME $_CHIPNAME.flash0 -flash bank $_FLASHNAME cfi 0x00000000 0x02000000 2 4 $_TARGETNAME -set _FLASHNAME $_CHIPNAME.flash1 -flash bank $_FLASHNAME cfi 0x04000000 0x02000000 2 4 $_TARGETNAME - -# CS2 low -- FPGA registers -# CS2 high -- 1 MByte SRAM at 0x0a00.0000 ... last 64K for scratch -$_TARGETNAME configure -work-area-phys 0x0a0f0000 - -$_TARGETNAME configure -event reset-assert-pre \ - "$_TARGETNAME configure -work-area-size 0" - -# Make the hex led display a number, assuming CS2 is set up -# and all digits have been enabled through the FPGA. -proc hexled {u32} { - mww 0x08000010 $u32 -} - -# CS3 -- Ethernet -# CS4 -- SA1111 -# CS5 -- PCMCIA - -# NOTE: system console normally uses the FF UART connector - -proc lubbock_init {target} { - - echo "Initialize PXA255 Lubbock board" - - # (1) pinmux - - # GPSR0..GPSR2 - mww 0x40e00018 0x00008000 - mww 0x40e0001c 0x00FC0382 - mww 0x40e00020 0x0001FFFF - # GPDR0..GPDR2 - mww 0x40e0000c 0x0060A800 - mww 0x40e00010 0x00FF0382 - mww 0x40e00014 0x0001C000 - # GAFR0_[LU]..GAFR2_[LU] - mww 0x40e00054 0x98400000 - mww 0x40e00058 0x00002950 - mww 0x40e0005c 0x000A9558 - mww 0x40e00060 0x0005AAAA - mww 0x40e00064 0xA0000000 - mww 0x40e00068 0x00000002 - - # write PSSR, enable GPIOs - mww 0x40f00000 0x00000020 - - # write LED ctrl register ... ones disable - # high byte, 8 hex leds; low byte, 8 discretes - mwh 0x08000040 0xf0ff - - hexled 0x0000 - - # (2) Address space setup - - # MSC0/MSC1/MSC2 - mww 0x48000008 0x23f223f2 - mww 0x4800000c 0x3ff1a441 - mww 0x48000010 0x7ff97ff1 - # pcmcia/cf - mww 0x48000014 0x00000000 - mww 0x48000028 0x00010504 - mww 0x4800002c 0x00010504 - mww 0x48000030 0x00010504 - mww 0x48000034 0x00010504 - mww 0x48000038 0x00004715 - mww 0x4800003c 0x00004715 - - hexled 0x1111 - - # (3) SDRAM setup - # REVISIT this looks dubious ... no refresh cycles - mww 0x48000004 0x03CA4018 - mww 0x48000004 0x004B4018 - mww 0x48000004 0x000B4018 - mww 0x48000004 0x000BC018 - mww 0x48000000 0x00001AC8 - mww 0x48000000 0x00001AC9 - - mww 0x48000040 0x00000000 - - # FIXME -- setup: - # CLOCKS (and faster JTAG) - # enable icache - - # FIXME SRAM isn't working - # $target configure -work-area-size 0x10000 - - hexled 0x2222 - - flash probe 0 - flash probe 1 - - hexled 0xcafe -} -$_TARGETNAME configure -event reset-init "lubbock_init $_TARGETNAME" diff --git a/tcl/board/marsohod.cfg b/tcl/board/marsohod.cfg deleted file mode 100644 index 681f575cc..000000000 --- a/tcl/board/marsohod.cfg +++ /dev/null @@ -1,13 +0,0 @@ -# -# Marsohod CPLD Development and Education board -# -# http://marsohod.org/howtostart/plata -# - -# Recommended MBFTDI programmer -source [find interface/ftdi/mbftdi.cfg] -adapter_khz 2000 -transport select jtag - -# Altera MAXII EPM240T100C CPLD -source [find cpld/altera-epm240.cfg] diff --git a/tcl/board/marsohod2.cfg b/tcl/board/marsohod2.cfg deleted file mode 100644 index d4897c3c3..000000000 --- a/tcl/board/marsohod2.cfg +++ /dev/null @@ -1,13 +0,0 @@ -# -# Marsohod2 FPGA Development and Education board -# -# http://www.marsohod.org/prodmarsohod2 -# - -# Built-in MBFTDI programmer -source [find interface/ftdi/mbftdi.cfg] -adapter_khz 2000 -transport select jtag - -# Cyclone III EP3C10E144 FPGA -source [find fpga/altera-ep3c10.cfg] diff --git a/tcl/board/marsohod3.cfg b/tcl/board/marsohod3.cfg deleted file mode 100644 index bb3c74f28..000000000 --- a/tcl/board/marsohod3.cfg +++ /dev/null @@ -1,13 +0,0 @@ -# -# Marsohod3 FPGA Development and Education board -# -# http://www.marsohod.org/plata-marsokhod3 -# - -# Built-in MBFTDI programmer -source [find interface/ftdi/mbftdi.cfg] -adapter_khz 2000 -transport select jtag - -# MAX10 10M50SAE144C8GES FPGA -source [find fpga/altera-10m50.cfg] diff --git a/tcl/board/mbed-lpc11u24.cfg b/tcl/board/mbed-lpc11u24.cfg deleted file mode 100644 index b1ec2a519..000000000 --- a/tcl/board/mbed-lpc11u24.cfg +++ /dev/null @@ -1,10 +0,0 @@ -# This is an mbed eval board with a single NXP LPC11U24 chip. -# http://mbed.org/handbook/mbed-NXP-LPC11U24 -# - -source [find interface/cmsis-dap.cfg] - -# NXP LPC11U24 Cortex-M0 with 32kB Flash and 8kB SRAM -set WORKAREASIZE 0x2000 - -source [find target/lpc11xx.cfg] diff --git a/tcl/board/mbed-lpc1768.cfg b/tcl/board/mbed-lpc1768.cfg deleted file mode 100644 index 67f834011..000000000 --- a/tcl/board/mbed-lpc1768.cfg +++ /dev/null @@ -1,7 +0,0 @@ -# This is an mbed eval board with a single NXP LPC1768 chip. -# http://mbed.org/handbook/mbed-NXP-LPC1768 -# - -source [find interface/cmsis-dap.cfg] - -source [find target/lpc17xx.cfg] diff --git a/tcl/board/mcb1700.cfg b/tcl/board/mcb1700.cfg deleted file mode 100644 index 068a19b24..000000000 --- a/tcl/board/mcb1700.cfg +++ /dev/null @@ -1,75 +0,0 @@ -# Keil MCB1700 PCB with 1768 -# -# Reset init script sets it to 100MHz -set CCLK 100000 - -source [find target/lpc17xx.cfg] - -global MCB1700_CCLK -set MCB1700_CCLK $CCLK - -$_TARGETNAME configure -event reset-start { - # Start *real slow* as we do not know the - # state the boot rom left the clock in - adapter_khz 10 -} - -# Set up 100MHz clock to CPU -$_TARGETNAME configure -event reset-init { - # PLL0CON: Disable PLL - mww 0x400FC080 0x00000000 - # PLLFEED - mww 0x400FC08C 0x000000AA - # PLLFEED - mww 0x400FC08C 0x00000055 - - # CCLK=PLL/4 (=100 MHz) - mww 0x400FC104 0x00000003 - # CLKSRCSEL: Clock source = internal RC oscillator - mww 0x400FC10C 0x00000000 - - # PLL0CFG: M=50,N=1 -> PLL=400 MHz - mww 0x400FC084 0x00000031 - # PLLFEED - mww 0x400FC08C 0x000000AA - # PLLFEED - mww 0x400FC08C 0x00000055 - - # PLL0CON: Enable PLL - mww 0x400FC080 0x00000001 - # PLLFEED - mww 0x400FC08C 0x000000AA - # PLLFEED - mww 0x400FC08C 0x00000055 - - sleep 50 - - # PLL0CON: Connect PLL - mww 0x400FC080 0x00000003 - # PLLFEED - mww 0x400FC08C 0x000000AA - # PLLFEED - mww 0x400FC08C 0x00000055 - - # Dividing CPU clock by 8 should be pretty conservative - # - # - global MCB1700_CCLK - adapter_khz [expr $MCB1700_CCLK / 8] - - # Do not remap 0x0000-0x0020 to anything but the flash (i.e. select - # "User Flash Mode" where interrupt vectors are _not_ remapped, - # and reside in flash instead). - # - # See Table 612. Memory Mapping Control register (MEMMAP - 0x400F C040) bit description - # Bit Symbol Value Description Reset - # value - # 0 MAP Memory map control. 0 - # 0 Boot mode. A portion of the Boot ROM is mapped to address 0. - # 1 User mode. The on-chip Flash memory is mapped to address 0. - # 31:1 - Reserved. The value read from a reserved bit is not defined. NA - # - # http://ics.nxp.com/support/documents/microcontrollers/?scope=LPC1768&type=user - - mww 0x400FC040 0x01 -} diff --git a/tcl/board/microchip_explorer16.cfg b/tcl/board/microchip_explorer16.cfg deleted file mode 100644 index 7c036c665..000000000 --- a/tcl/board/microchip_explorer16.cfg +++ /dev/null @@ -1,10 +0,0 @@ -# Microchip Explorer 16 with PIC32MX360F512L PIM module. -# http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=1406&dDocName=en024858 - -# TAPID for PIC32MX360F512L -set CPUTAPID 0x30938053 - -# use 32k working area -set WORKAREASIZE 32768 - -source [find target/pic32mx.cfg] diff --git a/tcl/board/mini2440.cfg b/tcl/board/mini2440.cfg deleted file mode 100644 index 874f829ab..000000000 --- a/tcl/board/mini2440.cfg +++ /dev/null @@ -1,320 +0,0 @@ -#------------------------------------------------------------------------- -# Mini2440 Samsung s3c2440A Processor with 64MB DRAM, 64MB NAND, 2 MB N0R -# NOTE: Configured for NAND boot (switch S2 in NANDBOOT) -# 64 MB NAND (Samsung K9D1208V0M) -# B Findlay 08/09 -# -# ----------- Important notes to help you on your way ---------- -# README: -# NOR/NAND Boot Switch - I have not read the vivi source, but from -# what I could tell from reading the registers it appears that vivi -# loads itself into DRAM and then flips NFCONT (0x4E000004) bits -# Mode (bit 0 = 1), and REG_nCE (bit 1 = 0) which maps the NAND -# FLASH at the bottom 64MB of memory. This essentially takes the -# NOR Flash out of the circuit so you can't trash it. -# -# I adapted the samsung_s3c2440.cfg file which is why I did not -# include "source [find target/samsung_s3c2440.cfg]". I believe -# the -work-area-phys 0x200000 is incorrect, but also had to pad -# some additional resets. I didn't modify it as if it is working -# for someone, the work-area-phys is not used by most. -# -# JTAG ADAPTER SPECIFIC -# IMPORTANT! Any JTAG device that uses ADAPTIVE CLOCKING will likely -# FAIL as the pin RTCK on the mini2440 10 pin JTAG Conn doesn't exist. -# This is Pin 11 (RTCK) on 20 pin JTAG connector. Therefore it is -# necessary to FORCE setting the clock. Normally this should be configured -# in the openocd.cfg file, but was placed here as it can be a tough -# problem to figure out. THIS MAY NOT FIX YOUR PROBLEM.. I modified -# the openOCD driver jlink.c and posted it here. It may eventually end -# up changed in openOCD, but its a hack in the driver and really should -# be in the jtag layer (core.c me thinks), but haven't done it yet. My -# hack for jlink.c may be found here. -# -# http://forum.sparkfun.com/viewtopic.php?t=16763&sid=946e65abdd3bab39cc7d90dee33ff135 -# -# Note: Also if you have a USB JTAG, you will need the USB library installed -# on your system "libusb-dev" or the make of openocd will fail. I *think* -# it's apt-get install libusb-dev. When I made my config I only included -# --enable-jlink and --enable-usbdevs -# -# I HAVE NOT Tested this throughly, so there could still be problems. -# But it should get you way ahead of the game from where I started. -# If you find problems (and fixes) please post them to -# openocd-development@lists.berlios.de and join the developers and -# check in fixes to this and anything else you find. I do not -# provide support, but if you ask really nice and I see anything -# obvious I will tell you.. mostly just dig, fix, and submit to openocd. -# -# best! brfindla@yahoo.com Nashua, NH USA -# -# Recommended resources: -# - first two are the best Mini2440 resources anywhere -# - maintained by buserror... thanks guy! -# -# http://bliterness.blogspot.com/ -# http://code.google.com/p/mini2440/ -# -# others.... -# -# http://forum.sparkfun.com/viewforum.php?f=18 -# http://labs.kernelconcepts.de/Publications/Micro24401/ -# http://www.friendlyarm.net/home -# http://www.amontec.com/jtag_pinout.shtml -# -#------------------------------------------------------------------------- -# -# -# Your openocd.cfg file should contain: -# source [find interface/.cfg] -# source [find board/mini2440.cfg] -# -# -# - -# FIXME use some standard target config, maybe create one from this -# -# source [find target/...cfg] - -#------------------------------------------------------------------------- -# Target configuration for the Samsung 2440 system on chip -# Tested on a S3C2440 Evaluation board by keesj -# Processor : ARM920Tid(wb) rev 0 (v4l) -# Info: JTAG tap: s3c2440.cpu tap/device found: 0x0032409d -# (Manufacturer: 0x04e, Part: 0x0324, Version: 0x0) -#------------------------------------------------------------------------- - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME s3c2440 -} - -if { [info exists ENDIAN] } { - set _ENDIAN $ENDIAN -} else { - # this defaults to a bigendian - set _ENDIAN little -} - -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - set _CPUTAPID 0x0032409d -} - -#jtag scan chain -jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0x0f -expected-id $_CPUTAPID - -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME arm920t -endian $_ENDIAN -chain-position $_TARGETNAME -$_TARGETNAME configure -work-area-phys 0x40000000 -work-area-size 0x4000 -work-area-backup 1 - -#reset configuration -adapter_nsrst_delay 100 -jtag_ntrst_delay 100 -reset_config trst_and_srst - -#------------------------------------------------------------------------- -# JTAG ADAPTER SPECIFIC -# IMPORTANT! See README at top of this file. -#------------------------------------------------------------------------- - - adapter_khz 12000 - jtag interface - -#------------------------------------------------------------------------- -# GDB Setup -#------------------------------------------------------------------------- - - gdb_breakpoint_override hard - -#------------------------------------------------ -# ARM SPECIFIC -#------------------------------------------------ - - targets - # arm7_9 dcc_downloads enable - # arm7_9 fast_memory_access enable - - - nand device s3c2440 0 - - adapter_nsrst_delay 100 - jtag_ntrst_delay 100 - reset_config trst_and_srst - init - - echo " " - echo "-------------------------------------------" - echo "--- login with - telnet localhost 4444 ---" - echo "--- then type help_2440 ---" - echo "-------------------------------------------" - echo " " - - - -#------------------------------------------------ -# Processor Initialialization -# Note: Processor writes can only occur when -# the state is in SYSTEM. When you call init_2440 -# one of the first lines will tell you what state -# you are in. If a linux image is booting -# when you run this, it will not work -# a vivi boot loader will run with this just -# fine. The reg values were obtained by a combination -# of figuring them out fromt the manual, and looking -# at post vivi values with the debugger. Don't -# place too much faith in them, but seem to work. -#------------------------------------------------ - -proc init_2440 { } { - - halt - s3c2440.cpu curstate - - #----------------------------------------------- - # Set Processor Clocks - mini2440 xtal=12mHz - # we set main clock for 405mHZ - # we set the USB Clock for 48mHz - # OM2 OM3 pulled to ground so main clock and - # usb clock are off 12mHz xtal - #----------------------------------------------- - - mww phys 0x4C000014 0x00000005 ;# Clock Divider control Reg - mww phys 0x4C000000 0xFFFFFFFF ;# LOCKTIME count register - mww phys 0x4C000008 0x00038022 ;# UPPLCON USB clock config Reg - mww phys 0x4C000004 0x0007F021 ;# MPPLCON Proc clock config Reg - - #----------------------------------------------- - # Configure Memory controller - # BWSCON configures all banks, NAND, NOR, DRAM - # DRAM - 64MB - 32 bit bus, uses BANKCON6 BANKCON7 - #----------------------------------------------- - - mww phys 0x48000000 0x22111112 ;# BWSCON - Bank and Bus Width - mww phys 0x48000010 0x00001112 ;# BANKCON4 - ? - mww phys 0x4800001c 0x00018009 ;# BANKCON6 - DRAM - mww phys 0x48000020 0x00018009 ;# BANKCON7 - DRAM - mww phys 0x48000024 0x008E04EB ;# REFRESH - DRAM - mww phys 0x48000028 0x000000B2 ;# BANKSIZE - DRAM - mww phys 0x4800002C 0x00000030 ;# MRSRB6 - DRAM - mww phys 0x48000030 0x00000030 ;# MRSRB7 - DRAM - - #----------------------------------------------- - # Now port configuration for enables for memory - # and other stuff. - #----------------------------------------------- - - mww phys 0x56000000 0x007FFFFF ;# GPACON - - mww phys 0x56000010 0x00295559 ;# GPBCON - mww phys 0x56000018 0x000003FF ;# GPBUP (PULLUP ENABLE) - mww phys 0x56000014 0x000007C2 ;# GPBDAT - - mww phys 0x56000020 0xAAAAA6AA ;# GPCCON - mww phys 0x56000028 0x0000FFFF ;# GPCUP - mww phys 0x56000024 0x00000020 ;# GPCDAT - - mww phys 0x56000030 0xAAAAAAAA ;# GPDCON - mww phys 0x56000038 0x0000FFFF ;# GPDUP - - mww phys 0x56000040 0xAAAAAAAA ;# GPECON - mww phys 0x56000048 0x0000FFFF ;# GPEUP - - mww phys 0x56000050 0x00001555 ;# GPFCON - mww phys 0x56000058 0x0000007F ;# GPFUP - mww phys 0x56000054 0x00000000 ;# GPFDAT - - mww phys 0x56000060 0x00150114 ;# GPGCON - mww phys 0x56000068 0x0000007F ;# GPGUP - - mww phys 0x56000070 0x0015AAAA ;# GPHCON - mww phys 0x56000078 0x000003FF ;# GPGUP - -} - - - -proc flash_config { } { - - #----------------------------------------- - # Finish Flash Configuration - #----------------------------------------- - - halt - - #flash configuration (K9D1208V0M: 512Mbit, x8, 3.3V, Mode: Normal, 1st gen) - nand probe 0 - nand list -} - -proc flash_uboot { } { - - # flash the u-Boot binary and reboot into it - init_2440 - flash_config - nand erase 0 0x0 0x40000 - nand write 0 /tftpboot/u-boot-nand512.bin 0 oob_softecc_kw - resume -} - - -proc load_uboot { } { - echo " " - echo " " - echo "----------------------------------------------------------" - echo "---- Load U-Boot into RAM and execute it. ---" - echo "---- NOTE: loads, partially runs, and hangs ---" - echo "---- U-Boot is fine, this image runs from vivi. ---" - echo "---- I burned u-boot into NAND so I didn't finish ---" - echo "---- debugging it. I am leaving this here as it is ---" - echo "---- part of the way there if you want to fix it. ---" - echo "---- ---" - echo "---- mini2440 U-boot here: ---" - echo "---- http://repo.or.cz/w/u-boot-openmoko/mini2440.git ---" - echo "---- Also this: ---" - echo "---- http://code.google.com/p/mini2440/wiki/MiniBringup --" - echo "----------------------------------------------------------" - - init_2440 - echo "Loading /tftpboot/u-boot-nand512.bin" - load_image /tftpboot/u-boot-nand512.bin 0x33f80000 bin - echo "Verifying image...." - verify_image /tftpboot/u-boot-nand512.bin 0x33f80000 bin - echo "jumping to u-boot" - #bp 0x33f80068 4 hw - reg 0 0 - reg 1 0 - reg 2 0 - reg 3 0 - reg 4 0x33f80000 - resume 0x33f80000 -} - - # this may help a little bit debugging the load_uboot -proc s {} { - step - reg - arm disassemble 0x33F80068 0x10 -} - -proc help_2440 {} { - echo " " - echo " " - echo "-----------------------------------------------------------" - echo "---- The following mini2440 funcs are supported ----" - echo "---- init_2440 - initialize clocks, DRAM, IO ----" - echo "---- flash_config - configures nand flash ----" - echo "---- load_uboot - loads uboot into ram ----" - echo "---- flash_uboot - flashes uboot to nand (untested) ----" - echo "---- help_2440 - this help display ----" - echo "-----------------------------------------------------------" - echo " " - echo " " -} - - -#---------------------------------------------------------------------------- -#----------------------------------- END ------------------------------------ -#---------------------------------------------------------------------------- diff --git a/tcl/board/mini6410.cfg b/tcl/board/mini6410.cfg deleted file mode 100644 index d00ce1f8c..000000000 --- a/tcl/board/mini6410.cfg +++ /dev/null @@ -1,112 +0,0 @@ -# Target configuration for the Samsung s3c6410 system on chip -# Tested on a tiny6410 -# Processor : ARM1176 -# Info : JTAG tap: s3c6410.etb tap/device found: 0x2b900f0f (mfg: 0x787, part: 0xb900, ver: 0x2) -# Info : JTAG tap: s3c6410.cpu tap/device found: 0x07b76f0f (mfg: 0x787, part: 0x7b76, ver: 0x0) - -source [find target/samsung_s3c6410.cfg] - -proc init_6410 {} { - halt - reg cpsr 0x1D3 - arm mcr 15 0 15 2 4 0x70000013 - - #----------------------------------------------- - # Clock and Timer Setting - #----------------------------------------------- - mww 0x7e004000 0 ;# WATCHDOG - Disable - mww 0x7E00F120 0x0003 ;# MEM_SYS_CFG - CS0:8 bit, Mem1:32bit, CS2=NAND - #mww 0x7E00F120 0x1000 ;# MEM_SYS_CFG - CS0:16bit, Mem1:32bit, CS2=SROMC - #mww 0x7E00F120 0x1002 ;# MEM_SYS_CFG - CS0:16bit, Mem1:32bit, CS2=OND - mww 0x7E00F900 0x805e ;# OTHERS - Change SYNCMUX[6] to “1” - sleep 1000 - mww 0x7E00F900 0x80de ;# OTHERS - Assert SYNCREQ&VICSYNCEN to “1”(rb1004modify) - sleep 1000 ;# - Others[11:8] to 0xF - mww 0x7E00F000 0xffff ;# APLL_LOCK - APLL LockTime - mww 0x7E00F004 0xffff ;# MPLL_LOCK - MPLL LockTime - mww 0x7E00F020 0x1047310 ;# CLK_DIV0 - ARMCLK:HCLK:PCLK = 1:4:16 - mww 0x7E00F00c 0x81900302 ;# APLL_CON - A:400, P:3, S:2 => 400MHz - mww 0x7E00F010 0x81900303 ;# MPLL_CON - M:400, P:3, S:3 => 200MHz - mww 0x7E00F01c 0x3 ;# CLK_SRC - APLL,MPLL Clock Select - - #----------------------------------------------- - # DRAM initialization - #----------------------------------------------- - mww 0x7e001004 0x4 ;# P1MEMCCMD - Enter the config state - mww 0x7e001010 0x30C ;# P1REFRESH - Refresh Period register (7800ns), 100MHz -# mww 0x7e001010 0x40e ;# P1REFRESH - Refresh Period register (7800ns), 133MHz - mww 0x7e001014 0x6 ;# P1CASLAT - CAS Latency = 3 - mww 0x7e001018 0x1 ;# P1T_DQSS - mww 0x7e00101c 0x2 ;# P1T_MRD - mww 0x7e001020 0x7 ;# P1T_RAS - 45 ns - mww 0x7e001024 0xA ;# P1T_RC - 67.5 ns - mww 0x7e001028 0xC ;# P1T_RCD - 22.5 ns - mww 0x7e00102C 0x10B ;# P1T_RFC - 80 ns - mww 0x7e001030 0xC ;# P1T_RP - 22.5 ns - mww 0x7e001034 0x3 ;# P1T_RRD - 15 ns - mww 0x7e001038 0x3 ;# P1T_WR - 15 ns - mww 0x7e00103C 0x2 ;# P1T_WTR - mww 0x7e001040 0x2 ;# P1T_XP - mww 0x7e001044 0x11 ;# P1T_XSR - 120 ns - mww 0x7e001048 0x11 ;# P1T_ESR - - #----------------------------------------------- - # Memory Configuration Registers - #----------------------------------------------- - mww 0x7e00100C 0x00010012 ;# P1MEMCFG - 1 CKE, 1Chip, 4burst, Alw, AP[10],ROW/Column bit - mww 0x7e00104C 0x0B41 ;# P1MEMCFG2 - Read delay 1 Cycle, mDDR, 32bit, Sync. - mww 0x7e001200 0x150F0 ;# CHIP_N_CFG - 0x150F0 for 256M, 0x150F8 for 128M - - #----------------------------------------------- - # Memory Direct Commands - #----------------------------------------------- - mww 0x7e001008 0xc0000 ;# Chip0 Direct Command :NOP5 - mww 0x7e001008 0x0 ;# Chip0 Direct Command :PreCharge al - mww 0x7e001008 0x40000 ;# Chip0 Direct Command :AutoRefresh - mww 0x7e001008 0x40000 ;# Chip0 Direct Command :AutoRefresh - mww 0x7e001008 0xA0000 ;# EMRS, DS:Full, PASR:Full - mww 0x7e001008 0x80032 ;# MRS, CAS3, BL4 - mww 0x7e001004 0x0 ;# Enable DMC1 -} - -proc install_6410_uboot {} { - # write U-boot magic number - mww 0x50000000 0x24564236 - mww 0x50000004 0x20764316 - load_image u-boot_nand-ram256.bin 0x50008000 bin - load_image u-boot_nand-ram256.bin 0x57E00000 bin - - #Kick in - reg pc 0x57E00000 - resume -} - -proc init_6410_flash {} { - halt - nand probe 0 - nand list -} - - -adapter_khz 1000 -adapter_nsrst_delay 100 -jtag_ntrst_delay 100 -reset_config trst_and_srst - -gdb_breakpoint_override hard - -targets -nand device $_CHIPNAME.flash s3c6400 $_CHIPNAME.cpu - -init -echo " " -echo " " -echo "-------------------------------------------------------------------" -echo "---- The following mini6410/tiny6410 functions are available: ----" -echo "---- init_6410 - initialize clock, timer, DRAM ----" -echo "---- init_6410_flash - initializes NAND flash support ----" -echo "---- install_6410_uboot - copies u-boot image into RAM and ----" -echo "---- runs it ----" -echo "-------------------------------------------------------------------" -echo " " -echo " " diff --git a/tcl/board/minispartan6.cfg b/tcl/board/minispartan6.cfg deleted file mode 100644 index 3de9e99d4..000000000 --- a/tcl/board/minispartan6.cfg +++ /dev/null @@ -1,24 +0,0 @@ -# https://www.scarabhardware.com/minispartan6/ - -source [find interface/ftdi/minispartan6.cfg] -source [find cpld/xilinx-xc6s.cfg] -source [find cpld/jtagspi.cfg] - -# example command to read the device dna of the FPGA on the board; -# openocd -f board/minispartan6.cfg -c "init;xc6s_print_dna xc6s.tap;shutdown" - -# example command to write bitstream -# openocd -f board/minispartan6.cfg -c "init;\ -# jtagspi_init 0 bscan_spi_xc6slx??.bit;\ -# jtagspi_program bitstream.bin 0;\ -# xc6s_program xc6s.tap;\ -# shutdown" -# -# jtagspi flash procies can be found in the contrib/loaders/flash/fpga/ -# directory, with prebuilt versions available at -# https://github.com/jordens/bscan_spi_bitstreams -# -# For the SLX25 variant, use -# - https://github.com/jordens/bscan_spi_bitstreams/raw/master/bscan_spi_xc6slx25.bit -# For the SLX9 variant, use -# - https://github.com/jordens/bscan_spi_bitstreams/raw/master/bscan_spi_xc6slx9.bit diff --git a/tcl/board/nds32_xc5.cfg b/tcl/board/nds32_xc5.cfg deleted file mode 100644 index 7d86996bd..000000000 --- a/tcl/board/nds32_xc5.cfg +++ /dev/null @@ -1,5 +0,0 @@ -set _CPUTAPID 0x1000063d -set _CHIPNAME nds32 -source [find target/nds32v3.cfg] - -jtag init diff --git a/tcl/board/netgear-dg834v3.cfg b/tcl/board/netgear-dg834v3.cfg deleted file mode 100644 index 48d23daf9..000000000 --- a/tcl/board/netgear-dg834v3.cfg +++ /dev/null @@ -1,20 +0,0 @@ -# -# Netgear DG834v3 Router -# Internal 4Kb RAM (@0x80000000) -# Flash is located at 0x90000000 (CS0) and RAM is located at 0x94000000 (CS1) -# - -set partition_list { - loader { "Bootloader (ADAM2)" 0x90000000 0x00020000 } - firmware { "Kernel+rootfs" 0x90020000 0x003d0000 } - config { "Bootloader config space" 0x903f0000 0x00010000 } -} - -source [find target/ti-ar7.cfg] - -# External 16MB SDRAM - disabled as we use internal sram -#$_TARGETNAME configure -work-area-phys 0x80000000 -work-area-size 0x00001000 - -# External 4MB NOR Flash -set _FLASHNAME $_CHIPNAME.norflash -flash bank $_FLASHNAME cfi 0x90000000 0x00400000 2 2 $_TARGETNAME diff --git a/tcl/board/netgear-wg102.cfg b/tcl/board/netgear-wg102.cfg deleted file mode 100644 index 232d2e423..000000000 --- a/tcl/board/netgear-wg102.cfg +++ /dev/null @@ -1,35 +0,0 @@ -source [find target/atheros_ar2313.cfg] - -reset_config trst_and_srst - -$_TARGETNAME configure -event reset-init { - mips32 cp0 12 0 0x10400000 - - # configure sdram controller - mww 0xb8300004 0x0e03 - sleep 100 - mww 0xb8300004 0x0e01 - mww 0xb8300008 0x10 - sleep 500 - mww 0xb8300004 0x0e02 - - mww 0xb8300000 0x6c0088 - mww 0xb8300008 0x57e - mww 0xb8300004 0x0e00 - mww 0xb8300004 0xb00 - - # configure flash - # 0x00000001 - 0x01 << FLASHCTL_IDCY_S - # 0x000000e0 - 0x07 << FLASHCTL_WST1_S - # FLASHCTL_RBLE 0x00000400 - Read byte lane enable - # 0x00003800 - 0x07 << FLASHCTL_WST2_S - # FLASHCTL_AC_8M 0x00060000 - Size of flash - # FLASHCTL_E 0x00080000 - Flash bank enable (added) - # FLASHCTL_WP 0x04000000 - write protect. If used, CFI mode wont work!! - # FLASHCTL_MWx16 0x10000000 - 16bit mode. Do not use it!! - # FLASHCTL_MWx8 0x00000000 - 8bit mode. - mww 0xb8400000 0x000d3ce1 -} - -set _FLASHNAME $_CHIPNAME.flash -flash bank $_FLASHNAME cfi 0xbe000000 0x00400000 1 1 $_TARGETNAME x16_as_x8 diff --git a/tcl/board/nordic_nrf51822_mkit.cfg b/tcl/board/nordic_nrf51822_mkit.cfg deleted file mode 100644 index aa6161f5d..000000000 --- a/tcl/board/nordic_nrf51822_mkit.cfg +++ /dev/null @@ -1,6 +0,0 @@ -# -# Nordic Semiconductor PCA10024 board (aka nRF51822-mKIT) -# - -source [find interface/cmsis-dap.cfg] -source [find target/nrf51.cfg] diff --git a/tcl/board/numato_opsis.cfg b/tcl/board/numato_opsis.cfg deleted file mode 100644 index e54a4eca8..000000000 --- a/tcl/board/numato_opsis.cfg +++ /dev/null @@ -1,10 +0,0 @@ -# http://opsis.hdmi2usb.tv -# -# The Numato Opsis is an FPGA based, open video platform. -# -# The board is supported via ixo-usb-jtag project. See the -# interface/usb-jtag.cfg for more information. - -source [find interface/usb-jtag.cfg] -source [find cpld/xilinx-xc6s.cfg] -source [find cpld/jtagspi.cfg] diff --git a/tcl/board/nxp_lpc-link2.cfg b/tcl/board/nxp_lpc-link2.cfg deleted file mode 100644 index 593fa599a..000000000 --- a/tcl/board/nxp_lpc-link2.cfg +++ /dev/null @@ -1,12 +0,0 @@ -# -# NXP LPC-Link2 -# -# http://www.nxp.com/board/OM13054.html -# https://www.lpcware.com/lpclink2 -# http://embeddedartists.com/products/lpcxpresso/lpclink2.php -# - -source [find target/lpc4370.cfg] - -# W25Q80BVSSIG w/ 1 MB flash -flash bank SPIFI_FLASH lpcspifi 0x14000000 0 0 0 $_CHIPNAME.m4 diff --git a/tcl/board/olimex_LPC2378STK.cfg b/tcl/board/olimex_LPC2378STK.cfg deleted file mode 100644 index a4b422dcc..000000000 --- a/tcl/board/olimex_LPC2378STK.cfg +++ /dev/null @@ -1,11 +0,0 @@ -##################################################### -# Olimex LPC2378STK eval board -# -# http://olimex.com/dev/lpc-2378stk.html -# -# Author: Sten, debian@sansys-electronic.com -##################################################### -# - -source [find target/lpc2378.cfg] - diff --git a/tcl/board/olimex_lpc_h2148.cfg b/tcl/board/olimex_lpc_h2148.cfg deleted file mode 100644 index 7833fdec6..000000000 --- a/tcl/board/olimex_lpc_h2148.cfg +++ /dev/null @@ -1,8 +0,0 @@ -# -# Olimex LPC-H2148 eval board -# -# http://www.olimex.com/dev/lpc-h2148.html -# - -source [find target/lpc2148.cfg] - diff --git a/tcl/board/olimex_sam7_ex256.cfg b/tcl/board/olimex_sam7_ex256.cfg deleted file mode 100644 index 5f83629de..000000000 --- a/tcl/board/olimex_sam7_ex256.cfg +++ /dev/null @@ -1,4 +0,0 @@ -# Olimex SAM7-EX256 has a single Atmel at91sam7ex256 on it. - -source [find target/sam7x256.cfg] - diff --git a/tcl/board/olimex_sam7_la2.cfg b/tcl/board/olimex_sam7_la2.cfg deleted file mode 100644 index 89d2b5a59..000000000 --- a/tcl/board/olimex_sam7_la2.cfg +++ /dev/null @@ -1,76 +0,0 @@ -source [find target/at91sam7a2.cfg] - -# delays needed to get stable reads of cpu state -jtag_ntrst_delay 10 -adapter_nsrst_delay 200 - -# board uses pullup and connects only srst -reset_config srst_open_drain - -# srst is connected to NRESET of CPU and fully resets everything... -reset_config srst_only srst_pulls_trst - -adapter_khz 1 -$_TARGETNAME configure -event reset-start { - adapter_khz 1 -} - -$_TARGETNAME configure -event reset-init { - # init script from http://www.mikrocontroller.net/topic/107462 - # AT91SAM7A2 - # AMC (advanced memory controller) - - echo "setting up AMC" - # AMC_CS0 - FLASH 1MB (0x40000000-0x400FFFFF) + DM9000E (0x40100000) - mww 0xFFE00000 0x40003EBD - - # AMC_CS1 - RAM low 2MB (0x40400000-0x405FFFFF) - mww 0xFFE00004 0x404030A9 - - # AMC_CS2 - RAM high 2MB (0x40800000-0x405FFFFF) - #mww 0xFFE00008 0x404030A9 - # changed to 0x40_8_ - mww 0xFFE00008 0x408030A9 - - # AMC_MCR - mww 0xFFE00024 0x00000004 - - # AMC_RCR force remap - mww 0xFFE00020 0x00000001 - - echo "set up AMC" - sleep 100 - - # the following base addresses from the original script did not correspond to those from datasheet - # changed bases from 0xFF000000 to 0xFFF00000 - - # disable watchdog, to prevent unwanted resets - mww 0xFFFA0068 0x00000000 - echo "disabled watchdog" - - sleep 50 - - # disable PLL - mww 0xFFFEC004 0x18070004 - - # PLL = 10 ==> Coreclock = 6Mhz*10/2 = 30 Mhz - mww 0xFFFEC010 0x762D800A - - # enable PLL - mww 0xFFFEC000 0x23050004 - echo "set up pll" - - sleep 100 - adapter_khz 5000 -} - -$_TARGETNAME arm7_9 dcc_downloads enable -$_TARGETNAME arm7_9 fast_memory_access enable - -# remap: ram at 0, flash at 0x40000000, like reset-init above does -$_TARGETNAME configure -work-area-phys 0x00000000 -work-area-size 0x4000 -work-area-backup 1 -flash bank onboard.flash cfi 0x40000000 0x00100000 2 2 at91sam7a2.cpu - -# boot: ram at 0x300000, flash at 0x0, useful if board is in funny configuration -#$_TARGETNAME configure -work-area-phys 0x00300000 -work-area-size 0x4000 -work-area-backup 1 -#flash bank onboard1.flash cfi 0x00000000 0x00100000 2 2 at91sam7a2.cpu diff --git a/tcl/board/olimex_sam9_l9260.cfg b/tcl/board/olimex_sam9_l9260.cfg deleted file mode 100644 index ad2f850a1..000000000 --- a/tcl/board/olimex_sam9_l9260.cfg +++ /dev/null @@ -1,141 +0,0 @@ -################################################################################ -# Olimex SAM9-L9260 Development Board -# -# http://www.olimex.com/dev/sam9-L9260.html -# -# Atmel AT91SAM9260 : PLLA = 198.656 MHz, MCK = 99.328 MHz -# PMC configured for external 18.432 MHz crystal -# -# 32-bit SDRAM : 2 x Samsung K4S561632J-UC75, 4M x 16Bit x 4 Banks -# 8-bit NAND Flash : 1 x Samsung K9F4G08U0M, 512M x 8Bit -# Dataflash : 1 x Atmel AT45DB161D, 16Mbit -# -################################################################################ - -source [find target/at91sam9260.cfg] - -# NTRST_E jumper is enabled by default, so we don't need to override the reset -# config. -#reset_config srst_only - -$_TARGETNAME configure -event reset-start { - # At reset, CPU runs at 32.768 kHz. JTAG frequency must be 6 times slower if - # RCLK is not supported. - jtag_rclk 5 - halt - - # RSTC_MR : enable user reset, reset length is 64 slow clock cycles. MMU may - # be enabled... use physical address. - mww phys 0xfffffd08 0xa5000501 -} - -$_TARGETNAME configure -event reset-init { - mww 0xfffffd44 0x00008000 ;# WDT_MR : disable watchdog - - ## - # Clock configuration for 99.328 MHz main clock. - ## - echo "Setting up clock" - mww 0xfffffc20 0x00004001 ;# CKGR_MOR : enable main oscillator, 512 slow clock startup - sleep 20 ;# wait 20 ms (need 15.6 ms for startup) - mww 0xfffffc30 0x00000001 ;# PMC_MCKR : switch to main oscillator (18.432 MHz) - sleep 10 ;# wait 10 ms - mww 0xfffffc28 0x2060bf09 ;# CKGR_PLLAR : 18.432 MHz / 9 * 97 = 198.656 MHz, 63 slow clock startup - sleep 20 ;# wait 20 ms (need 1.9 ms for startup) - mww 0xfffffc30 0x00000101 ;# PMC_MCKR : no scale on proc clock, master is proc / 2 - sleep 10 ;# wait 10 ms - mww 0xfffffc30 0x00000102 ;# PMC_MCKR : switch to PLLA (99.328 MHz) - - # Increase JTAG speed to 6 MHz if RCLK is not supported. - jtag_rclk 6000 - - arm7_9 dcc_downloads enable ;# Enable faster DCC downloads. - - ## - # SDRAM configuration for 2 x Samsung K4S561632J-UC75, 4M x 16Bit x 4 Banks. - ## - echo "Configuring SDRAM" - mww 0xfffff870 0xffff0000 ;# PIOC_ASR : select peripheral function for D15..D31 - mww 0xfffff804 0xffff0000 ;# PIOC_PDR : disable PIO function for D15..D31 - - mww 0xffffef1c 0x00010002 ;# EBI_CSA : assign EBI CS1 to SDRAM, VDDIOMSEL set for +3V3 memory - - mww 0xffffea08 0x85237259 ;# SDRAMC_CR : configure SDRAM for Samsung chips - - mww 0xffffea00 0x1 ;# SDRAMC_MR : issue NOP command - mww 0x20000000 0 - mww 0xffffea00 0x2 ;# SDRAMC_MR : issue an 'All Banks Precharge' command - mww 0x20000000 0 - mww 0xffffea00 0x4 ;# SDRAMC_MR : issue 8 x 'Auto-Refresh' command - mww 0x20000000 0 - mww 0xffffea00 0x4 - mww 0x20000000 0 - mww 0xffffea00 0x4 - mww 0x20000000 0 - mww 0xffffea00 0x4 - mww 0x20000000 0 - mww 0xffffea00 0x4 - mww 0x20000000 0 - mww 0xffffea00 0x4 - mww 0x20000000 0 - mww 0xffffea00 0x4 - mww 0x20000000 0 - mww 0xffffea00 0x4 - mww 0x20000000 0 - mww 0xffffea00 0x3 ;# SDRAMC_MR : issue a 'Load Mode Register' command - mww 0x20000000 0 - mww 0xffffea00 0x0 ;# SDRAMC_MR : normal mode - mww 0x20000000 0 - - mww 0xffffea04 0x2b6 ;# SDRAMC_TR : set refresh timer count to 7 us - - ## - # NAND Flash Configuration for 1 x Samsung K9F4G08U0M, 512M x 8Bit. - ## - echo "Configuring NAND flash" - mww 0xfffffc10 0x00000010 ;# PMC_PCER : enable PIOC clock - mww 0xfffff800 0x00006000 ;# PIOC_PER : enable PIO function for 13(RDY/~BSY) and 14(~CS) - mww 0xfffff810 0x00004000 ;# PIOC_OER : enable output on 14 - mww 0xfffff814 0x00002000 ;# PIOC_ODR : disable output on 13 - mww 0xfffff830 0x00004000 ;# PIOC_SODR : set 14 to disable NAND - mww 0xfffff864 0x00002000 ;# PIOC_PUER : enable pull-up on 13 - - mww 0xffffef1c 0x0001000A ;# EBI_CSA : assign EBI CS3 to NAND, same settings as before - - mww 0xffffec30 0x00010001 ;# SMC_SETUP3 : 1 clock cycle setup for NRD and NWE - mww 0xffffec34 0x03030303 ;# SMC_PULSE3 : 3 clock cycle pulse for all signals - mww 0xffffec38 0x00050005 ;# SMC_CYCLE3 : 5 clock cycle NRD and NWE cycle - mww 0xffffec3C 0x00020003 ;# SMC_MODE3 : NRD and NWE control, no NWAIT, 8-bit DBW, - # 3 TDF cycles, no optimization - - mww 0xffffe800 0x00000001 ;# ECC_CR : reset the ECC parity registers - mww 0xffffe804 0x00000002 ;# ECC_MR : page size is 2112 words (word is 8 bits) - - nand probe at91sam9260.flash - - ## - # Dataflash configuration for 1 x Atmel AT45DB161D, 16Mbit - ## - echo "Setting up dataflash" - mww 0xfffff404 0x00000807 ;# PIOA_PDR : disable PIO function for 0(SPI0_MISO), 1(SPI0_MOSI), - # 2(SPI0_SPCK), and 11(SPI0_NPCS1) - mww 0xfffff470 0x00000007 ;# PIOA_ASR : select peripheral A function for 0, 1, and 2 - mww 0xfffff474 0x00000800 ;# PIOA_BSR : select peripheral B function for 11 - mww 0xfffffc10 0x00001000 ;# PMC_PCER : enable SPI0 clock - - mww 0xfffc8000 0x00000080 ;# SPI0_CR : software reset SPI0 - mww 0xfffc8000 0x00000080 ;# SPI0_CR : again to be sure - mww 0xfffc8004 0x000F0011 ;# SPI0_MR : master mode with nothing selected - - mww 0xfffc8034 0x011a0302 ;# SPI0_CSR1 : capture on leading edge, 8-bits/tx. 33MHz baud, - # 250ns delay before SPCK, 250ns b/n tx - - mww 0xfffc8004 0x000D0011 ;# SPI0_MR : same config, select NPCS1 - mww 0xfffc8000 0x00000001 ;# SPI0_CR : enable SPI0 -} - -nand device at91sam9260.flash at91sam9 at91sam9260.cpu 0x40000000 0xffffe800 -at91sam9 cle 0 22 -at91sam9 ale 0 21 -at91sam9 rdy_busy 0 0xfffff800 13 -at91sam9 ce 0 0xfffff800 14 diff --git a/tcl/board/olimex_stm32_h103.cfg b/tcl/board/olimex_stm32_h103.cfg deleted file mode 100644 index ec03034c1..000000000 --- a/tcl/board/olimex_stm32_h103.cfg +++ /dev/null @@ -1,7 +0,0 @@ -# Olimex STM32-H103 eval board -# http://olimex.com/dev/stm32-h103.html - -# Work-area size (RAM size) = 20kB for STM32F103RB device -set WORKAREASIZE 0x5000 - -source [find target/stm32f1x.cfg] diff --git a/tcl/board/olimex_stm32_h107.cfg b/tcl/board/olimex_stm32_h107.cfg deleted file mode 100644 index e54fb4e70..000000000 --- a/tcl/board/olimex_stm32_h107.cfg +++ /dev/null @@ -1,10 +0,0 @@ -# -# Olimex STM32-H107 -# -# http://olimex.com/dev/stm32-h107.html -# - -# Work-area size (RAM size) = 64kB for STM32F107VC device -set WORKAREASIZE 0x10000 - -source [find target/stm32f1x.cfg] diff --git a/tcl/board/olimex_stm32_p107.cfg b/tcl/board/olimex_stm32_p107.cfg deleted file mode 100644 index 98c72a6e7..000000000 --- a/tcl/board/olimex_stm32_p107.cfg +++ /dev/null @@ -1,10 +0,0 @@ -# -# Olimex STM32-P107 -# -# http://olimex.com/dev/stm32-p107.html -# - -# Work-area size (RAM size) = 64kB for STM32F107VC device -set WORKAREASIZE 0x10000 - -source [find target/stm32f1x.cfg] diff --git a/tcl/board/omap2420_h4.cfg b/tcl/board/omap2420_h4.cfg deleted file mode 100644 index d789e2531..000000000 --- a/tcl/board/omap2420_h4.cfg +++ /dev/null @@ -1,12 +0,0 @@ -# OMAP2420 SDP board ("H4") - -source [find target/omap2420.cfg] - -# NOTE: this assumes you're *NOT* using a TI-14 connector. -reset_config trst_and_srst separate - -# Board configs can vary a *LOT* ... parts, jumpers, etc. -# This GP board boots from cs0 using NOR (2x32M), and also -# has 64M NAND on cs6. -flash bank h4.u10 cfi 0x04000000 0x02000000 2 2 $_TARGETNAME -flash bank h4.u11 cfi 0x06000000 0x02000000 2 2 $_TARGETNAME diff --git a/tcl/board/open-bldc.cfg b/tcl/board/open-bldc.cfg deleted file mode 100644 index da8654c8d..000000000 --- a/tcl/board/open-bldc.cfg +++ /dev/null @@ -1,7 +0,0 @@ -# Open Source Brush Less DC Motor Controller -# http://open-bldc.org - -# Work-area size (RAM size) = 20kB for STM32F103RB device -set WORKAREASIZE 0x5000 - -source [find target/stm32.cfg] diff --git a/tcl/board/openrd.cfg b/tcl/board/openrd.cfg deleted file mode 100644 index 1051c25d9..000000000 --- a/tcl/board/openrd.cfg +++ /dev/null @@ -1,123 +0,0 @@ -# Marvell OpenRD - -source [find interface/ftdi/openrd.cfg] -source [find target/feroceon.cfg] - -$_TARGETNAME configure \ - -work-area-phys 0x10000000 \ - -work-area-size 65536 \ - -work-area-backup 0 - -arm7_9 dcc_downloads enable - -# this assumes the hardware default peripherals location before u-Boot moves it -set _FLASHNAME $_CHIPNAME.flash -nand device $_FLASHNAME orion 0 0xd8000000 - -proc openrd_init { } { - - # We need to assert DBGRQ while holding nSRST down. - # However DBGACK will be set only when nSRST is released. - # Furthermore, the JTAG interface doesn't respond at all when - # the CPU is in the WFI (wait for interrupts) state, so it is - # possible that initial tap examination failed. So let's - # re-examine the target again here when nSRST is asserted which - # should then succeed. - jtag_reset 0 1 - feroceon.cpu arp_examine - halt 0 - jtag_reset 0 0 - wait_halt - - arm mcr 15 0 0 1 0 0x00052078 - - mww 0xD0001400 0x43000C30 ;# DDR SDRAM Configuration Register - mww 0xD0001404 0x37543000 ;# Dunit Control Low Register - mww 0xD0001408 0x22125451 ;# DDR SDRAM Timing (Low) Register - mww 0xD000140C 0x00000A33 ;# DDR SDRAM Timing (High) Register - mww 0xD0001410 0x000000CC ;# DDR SDRAM Address Control Register - mww 0xD0001414 0x00000000 ;# DDR SDRAM Open Pages Control Register - mww 0xD0001418 0x00000000 ;# DDR SDRAM Operation Register - mww 0xD000141C 0x00000C52 ;# DDR SDRAM Mode Register - mww 0xD0001420 0x00000004 ;# DDR SDRAM Extended Mode Register - mww 0xD0001424 0x0000F17F ;# Dunit Control High Register - mww 0xD0001428 0x00085520 ;# Dunit Control High Register - mww 0xD000147c 0x00008552 ;# Dunit Control High Register - mww 0xD0001504 0x0FFFFFF1 ;# CS0n Size Register - mww 0xD0001508 0x10000000 ;# CS1n Base Register - mww 0xD000150C 0x0FFFFFF5 ;# CS1n Size Register - mww 0xD0001514 0x00000000 ;# CS2n Size Register - mww 0xD000151C 0x00000000 ;# CS3n Size Register - mww 0xD0001494 0x00120012 ;# DDR2 SDRAM ODT Control (Low) Register - mww 0xD0001498 0x00000000 ;# DDR2 SDRAM ODT Control (High) REgister - mww 0xD000149C 0x0000E40F ;# DDR2 Dunit ODT Control Register - mww 0xD0001480 0x00000001 ;# DDR SDRAM Initialization Control Register - mww 0xD0020204 0x00000000 ;# Main IRQ Interrupt Mask Register - mww 0xD0020204 0x00000000 ;# " - mww 0xD0020204 0x00000000 ;# " - mww 0xD0020204 0x00000000 ;# " - mww 0xD0020204 0x00000000 ;# " - mww 0xD0020204 0x00000000 ;# " - mww 0xD0020204 0x00000000 ;# " - mww 0xD0020204 0x00000000 ;# " - mww 0xD0020204 0x00000000 ;# " - mww 0xD0020204 0x00000000 ;# " - mww 0xD0020204 0x00000000 ;# " - mww 0xD0020204 0x00000000 ;# " - mww 0xD0020204 0x00000000 ;# " - mww 0xD0020204 0x00000000 ;# " - mww 0xD0020204 0x00000000 ;# " - mww 0xD0020204 0x00000000 ;# " - mww 0xD0020204 0x00000000 ;# " - mww 0xD0020204 0x00000000 ;# " - mww 0xD0020204 0x00000000 ;# " - mww 0xD0020204 0x00000000 ;# " - mww 0xD0020204 0x00000000 ;# " - mww 0xD0020204 0x00000000 ;# " - mww 0xD0020204 0x00000000 ;# " - mww 0xD0020204 0x00000000 ;# " - mww 0xD0020204 0x00000000 ;# " - mww 0xD0020204 0x00000000 ;# " - mww 0xD0020204 0x00000000 ;# " - mww 0xD0020204 0x00000000 ;# " - mww 0xD0020204 0x00000000 ;# " - mww 0xD0020204 0x00000000 ;# " - mww 0xD0020204 0x00000000 ;# " - mww 0xD0020204 0x00000000 ;# " - mww 0xD0020204 0x00000000 ;# " - mww 0xD0020204 0x00000000 ;# " - mww 0xD0020204 0x00000000 ;# " - mww 0xD0020204 0x00000000 ;# " - mww 0xD0020204 0x00000000 ;# " - - mww 0xD0010000 0x01111111 ;# MPP 0 to 7 - mww 0xD0010004 0x11113322 ;# MPP 8 to 15 - mww 0xD0010008 0x00001111 ;# MPP 16 to 23 - - mww 0xD0010418 0x003E07CF ;# NAND Read Parameters REgister - mww 0xD001041C 0x000F0F0F ;# NAND Write Parameters Register - mww 0xD0010470 0x01C7D943 ;# NAND Flash Control Register - -} - -proc openrd_reflash_uboot { } { - - # reflash the u-Boot binary and reboot into it - openrd_init - nand probe 0 - nand erase 0 0x0 0xa0000 - nand write 0 uboot.bin 0 oob_softecc_kw - resume - -} - -proc openrd_load_uboot { } { - - # load u-Boot into RAM and execute it - openrd_init - load_image uboot.elf - verify_image uboot.elf - resume 0x00600000 - -} - diff --git a/tcl/board/or1k_generic.cfg b/tcl/board/or1k_generic.cfg deleted file mode 100644 index c543ebe25..000000000 --- a/tcl/board/or1k_generic.cfg +++ /dev/null @@ -1,51 +0,0 @@ -# If you want to use the VJTAG TAP or the XILINX BSCAN, -# you must set your FPGA TAP ID here - -set FPGATAPID 0x020b30dd - -# Choose your TAP core (VJTAG , MOHOR or XILINX_BSCAN) -if { [info exists TAP_TYPE] == 0} { - set TAP_TYPE VJTAG -} - -# Set your chip name -set CHIPNAME or1200 - -source [find target/or1k.cfg] - -# Set the servers polling period to 1ms (needed to JSP Server) -poll_period 1 - -# Set the adapter speed -adapter_khz 3000 - -# Enable the target description feature -gdb_target_description enable - -# Add a new register in the cpu register list. This register will be -# included in the generated target descriptor file. -# format is addreg [name] [address] [feature] [reg_group] -addreg rtest 0x1234 org.gnu.gdb.or1k.group0 system - -# Override default init_reset -proc init_reset {mode} { - soft_reset_halt - resume -} - -# Target initialization -init -echo "Halting processor" -halt - -foreach name [target names] { - set y [$name cget -endian] - set z [$name cget -type] - puts [format "Chip is %s, Endian: %s, type: %s" \ - $name $y $z] -} - -set c_blue "\033\[01;34m" -set c_reset "\033\[0m" - -puts [format "%sTarget ready...%s" $c_blue $c_reset] diff --git a/tcl/board/osk5912.cfg b/tcl/board/osk5912.cfg deleted file mode 100644 index f4378f8cf..000000000 --- a/tcl/board/osk5912.cfg +++ /dev/null @@ -1,34 +0,0 @@ -# http://omap.spectrumdigital.com/osk5912/ - -source [find target/omap5912.cfg] - -# NOTE: this assumes you're using the ARM 20-pin ("Multi-ICE") -# JTAG connector, and accordingly have J1 connecting pins 1 & 2. -# The TI-14 pin needs "trst_only", and J1 connecting 2 & 3. -reset_config trst_and_srst separate - -# NOTE: boards with XOMAP parts wire nSRST to nPWRON_RESET. -# That resets everything -- including JTAG and EmbeddedICE. -# So they must use "reset_config srst_pulls_trst". - -# NOTE: an expansion board could add a trace connector ... if -# it does, change this appropriately. And reset_config too, -# assuming JTAG_DIS reroutes JTAG to that connector. -etm config $_TARGETNAME 8 demultiplexed full dummy -etm_dummy config $_TARGETNAME - -# standard boards populate two 16 MB chips, but manufacturing -# options or an expansion board could change this config. -flash bank osk.u1 cfi 0x00000000 0x01000000 2 2 $_TARGETNAME -flash bank osk.u2 cfi 0x01000000 0x01000000 2 2 $_TARGETNAME - -proc osk5912_init {} { - omap5912_reset - - # detect flash - flash probe 0 - flash probe 1 -} -$_TARGETNAME configure -event reset-init { osk5912_init } - -arm7_9 dcc_downloads enable diff --git a/tcl/board/phone_se_j100i.cfg b/tcl/board/phone_se_j100i.cfg deleted file mode 100644 index 632659027..000000000 --- a/tcl/board/phone_se_j100i.cfg +++ /dev/null @@ -1,12 +0,0 @@ -# -# Sony Ericsson J100I Phone -# -# more informations can be found on -# http://bb.osmocom.org/trac/wiki/SonyEricssonJ100i -# -source [find target/ti_calypso.cfg] - -# external flash - -set _FLASHNAME $_CHIPNAME.flash -flash bank $_FLASHNAME cfi 0x00000000 0x400000 2 2 $_TARGETNAME diff --git a/tcl/board/phytec_lpc3250.cfg b/tcl/board/phytec_lpc3250.cfg deleted file mode 100644 index 6a7e8e923..000000000 --- a/tcl/board/phytec_lpc3250.cfg +++ /dev/null @@ -1,88 +0,0 @@ -source [find target/lpc3250.cfg] - -adapter_nsrst_delay 200 -jtag_ntrst_delay 1 -adapter_khz 200 -reset_config trst_and_srst separate - -arm7_9 dcc_downloads enable - -$_TARGETNAME configure -event gdb-attach { reset init } - -$_TARGETNAME configure -event reset-start { - arm7_9 fast_memory_access disable - adapter_khz 200 -} - -$_TARGETNAME configure -event reset-end { - adapter_khz 6000 - arm7_9 fast_memory_access enable -} - -$_TARGETNAME configure -event reset-init { phytec_lpc3250_init } - -# Bare-bones initialization of core clocks and SDRAM -proc phytec_lpc3250_init { } { - # Set clock dividers - # ARMCLK = 266.5 MHz - # HCLK = 133.25 MHz - # PERIPHCLK = 13.325 MHz - mww 0x400040BC 0 - mww 0x40004050 0x140 - mww 0x40004040 0x4D - mww 0x40004058 0x16250 - - # Init PLLs - mww 0x40004044 0x006 - sleep 1 busy - mww 0x40004044 0x106 - sleep 1 busy - mww 0x40004044 0x006 - sleep 1 busy - mww 0x40004048 0x2 - - # Init SDRAM with 133 MHz timings - mww 0x40028134 0x00FFFFFF - mww 0x4002802C 0x00000008 - - mww 0x31080000 1 - mww 0x31080008 0 - mww 0x40004068 0x1C000 - mww 0x31080028 0x11 - - mww 0x31080400 0 - mww 0x31080440 0 - mww 0x31080460 0 - mww 0x31080480 0 - - # Delays - mww 0x31080030 1 - mww 0x31080034 6 - mww 0x31080038 10 - mww 0x31080044 1 - mww 0x31080048 9 - mww 0x3108004C 12 - mww 0x31080050 10 - mww 0x31080054 1 - mww 0x31080058 1 - mww 0x3108005C 0 - - mww 0x31080100 0x5680 - mww 0x31080104 0x302 - - # Init sequence - mww 0x31080020 0x193 - sleep 1 busy - mww 0x31080024 1 - mww 0x31080020 0x113 - sleep 1 busy - mww 0x31080020 0x013 - sleep 1 busy - mww 0x31080024 65 - mww 0x31080020 0x093 - mdw 0x80020000 - mww 0x31080020 0x013 - - # SYS_CTRL remapping - mww 0x40004014 1 -} diff --git a/tcl/board/pic-p32mx.cfg b/tcl/board/pic-p32mx.cfg deleted file mode 100644 index 661e3d63f..000000000 --- a/tcl/board/pic-p32mx.cfg +++ /dev/null @@ -1,4 +0,0 @@ -# The Olimex PIC-P32MX has a PIC32MX - -set CPUTAPID 0x40916053 -source [find target/pic32mx.cfg] diff --git a/tcl/board/pipistrello.cfg b/tcl/board/pipistrello.cfg deleted file mode 100644 index 87193b4a1..000000000 --- a/tcl/board/pipistrello.cfg +++ /dev/null @@ -1,14 +0,0 @@ -# http://pipistrello.saanlima.com/ - -source [find interface/ftdi/pipistrello.cfg] -source [find cpld/xilinx-xc6s.cfg] -source [find cpld/jtagspi.cfg] - -# example command to write bitstream, soft-cpu bios and runtime: -# openocd -f board/pipistrello.cfg -c "init;\ -# jtagspi_init 0 bscan_spi_xc6slx45.bit;\ -# jtagspi_program bitstream-pistrello.bin 0;\ -# jtagspi_program bios.bin 0x170000;\ -# jtagspi_program runtime.fbi 0x180000;\ -# xc6s_program xc6s.tap;\ -# exit" diff --git a/tcl/board/propox_mmnet1001.cfg b/tcl/board/propox_mmnet1001.cfg deleted file mode 100644 index 39ae5cbc1..000000000 --- a/tcl/board/propox_mmnet1001.cfg +++ /dev/null @@ -1,83 +0,0 @@ - -## Chip: -set CHIPNAME at91sam9260 -set CPUTAPID 0x0792603f -set ENDIAN little -source [find target/at91sam9260.cfg] - -$_TARGETNAME configure -event reset-init {at91sam_init} - - -proc at91sam_init { } { - - # at reset chip runs at 32 kHz => 1/8 * 32 kHz = 4 kHz - jtag_rclk 4 - - # Enable user reset and disable watchdog - mww 0xfffffd08 0xa5000501 ;# RSTC_MR : enable user reset - mww 0xfffffd44 0x00008000 ;# WDT_MR : disable watchdog - - # Oscillator setup - mww 0xfffffc20 0x00004001 ;# CKGR_MOR : enable the main oscillator (18.432 MHz) - sleep 20 ;# wait 20 ms - mww 0xfffffc30 0x00000001 ;# PMC_MCKR : switch to main oscillator - sleep 10 ;# wait 10 ms - - # now we are running at 18.432 MHz kHz => 1/8 * 18.432 MHz = 2.304 MHz - jtag_rclk 2000 - - mww 0xfffffc28 0x2060bf09 ;# CKGR_PLLAR: Set PLLA Register for 198,656MHz - sleep 20 ;# wait 20 ms - mww 0xfffffc2c 0x207c3f0c ;# CKGR_PLLBR: Set PLLB Register for USB usage (USB_CLK = 48 MHz) - sleep 10 ;# wait 10 ms - mww 0xfffffc30 0x00000101 ;# PMC_MCKR : Select prescaler - sleep 10 ;# wait 10 ms - mww 0xfffffc30 0x00000102 ;# PMC_MCKR : Clock from PLLA is selected - sleep 10 ;# wait 10 ms - - # now we are running at 198.656 MHz kHz => full speed jtag - jtag_rclk 30000 - - arm7_9 dcc_downloads enable ;# Enable faster DCC downloads - - # Configure PIO Controller for SDRAM data-lines D16-D31 - # PC16-PC31 = Peripheral A: D16-D32 - mww 0xfffff844 0xffff0000 ;# Interrupt Disable - mww 0xfffff854 0xffff0000 ;# Multi-Drive Disable - mww 0xfffff860 0xffff0000 ;# Pull-Up Disable - mww 0xfffff870 0xffff0000 ;# PIO_ASR : Select peripheral A function for D15..D31 - mww 0xfffff804 0xffff0000 ;# PIO_PDR : Disable PIO function for D15..D31 (Peripheral function enable) - mww 0xfffffc10 0x00000010 ;# Enable PIO-C Clock in PMC (PID=4) - - # SD-Ram setup - mww 0xffffef1c 0x2 ;# EBI_CSA : Assign EBI Chip Select 1 to SDRAM - mww 0xffffea08 0x85227259 ;# SDRAMC_CR : Configure SDRAM (IS42S32160A: 4M Words x 32 Bits x 4 Banks (512-Mbit)) - mww 0xffffea00 0x1 ;# SDRAMC_MR : issue a NOP command - mww 0x20000000 0 - mww 0xffffea00 0x2 ;# SDRAMC_MR : issue an 'All Banks Precharge' command - mww 0x20000000 0 - mww 0xffffea00 0x4 ;# SDRAMC_MR : issue an 'Auto-Refresh' command (1st) - mww 0x20000000 0 - mww 0xffffea00 0x4 ;# SDRAMC_MR : issue an 'Auto-Refresh' command (2nd) - mww 0x20000000 0 - mww 0xffffea00 0x4 ;# SDRAMC_MR : issue an 'Auto-Refresh' command (3th) - mww 0x20000000 0 - mww 0xffffea00 0x4 ;# SDRAMC_MR : issue an 'Auto-Refresh' command (4th) - mww 0x20000000 0 - mww 0xffffea00 0x4 ;# SDRAMC_MR : issue an 'Auto-Refresh' command (5th) - mww 0x20000000 0 - mww 0xffffea00 0x4 ;# SDRAMC_MR : issue an 'Auto-Refresh' command (6th) - mww 0x20000000 0 - mww 0xffffea00 0x4 ;# SDRAMC_MR : issue an 'Auto-Refresh' command (7th) - mww 0x20000000 0 - mww 0xffffea00 0x4 ;# SDRAMC_MR : issue an 'Auto-Refresh' command (8th) - mww 0x20000000 0 - mww 0xffffea00 0x3 ;# SDRAMC_MR : issue a 'Load Mode Register' command - mww 0x20000000 0 - mww 0xffffea00 0x0 ;# SDRAMC_MR : Normal Mode - mww 0x20000000 0 - mww 0xFFFFEA04 0x30d ;# SDRAM Refresh Time Register - # datasheet: 8k refresh cycles / 64 ms - # MCLK / (8*1024 / 64e-3) = 100e6 / 128000 = 781 = 0x30d - -} diff --git a/tcl/board/pxa255_sst.cfg b/tcl/board/pxa255_sst.cfg deleted file mode 100644 index 49cad5db7..000000000 --- a/tcl/board/pxa255_sst.cfg +++ /dev/null @@ -1,99 +0,0 @@ -# A PXA255 test board with SST 39LF400A flash -# -# At reset the memory map is as follows. Note that -# the memory map changes later on as the application -# starts... -# -# RAM at 0x4000000 -# Flash at 0x00000000 -# -source [find target/pxa255.cfg] - -# Target name is set by above -$_TARGETNAME configure -work-area-phys 0x4000000 -work-area-size 0x4000 -work-area-backup 0 - -# flash bank [options] -set _FLASHNAME $_CHIPNAME.flash -flash bank $_FLASHNAME cfi 0x00000000 0x80000 2 2 $_TARGETNAME jedec_probe - -proc pxa255_sst_init {} { - xscale cp15 15 0x00002001 ;#Enable CP0 and CP13 access - # - # setup GPIO - # - mww 0x40E00018 0x00008000 ;#CPSR0 - sleep 20 - mww 0x40E0001C 0x00000002 ;#GPSR1 - sleep 20 - mww 0x40E00020 0x00000008 ;#GPSR2 - sleep 20 - mww 0x40E0000C 0x00008000 ;#GPDR0 - sleep 20 - mww 0x40E00054 0x80000000 ;#GAFR0_L - sleep 20 - mww 0x40E00058 0x00188010 ;#GAFR0_H - sleep 20 - mww 0x40E0005C 0x60908018 ;#GAFR1_L - sleep 20 - mww 0x40E0000C 0x0280E000 ;#GPDR0 - sleep 20 - mww 0x40E00010 0x821C88B2 ;#GPDR1 - sleep 20 - mww 0x40E00014 0x000F03DB ;#GPDR2 - sleep 20 - mww 0x40E00000 0x000F03DB ;#GPLR0 - sleep 20 - - - mww 0x40F00004 0x00000020 ;#PSSR - sleep 20 - - # - # setup memory controller - # - mww 0x48000008 0x01111998 ;#MSC0 - sleep 20 - mww 0x48000010 0x00047ff0 ;#MSC2 - sleep 20 - mww 0x48000014 0x00000000 ;#MECR - sleep 20 - mww 0x48000028 0x00010504 ;#MCMEM0 - sleep 20 - mww 0x4800002C 0x00010504 ;#MCMEM1 - sleep 20 - mww 0x48000030 0x00010504 ;#MCATT0 - sleep 20 - mww 0x48000034 0x00010504 ;#MCATT1 - sleep 20 - mww 0x48000038 0x00004715 ;#MCIO0 - sleep 20 - mww 0x4800003C 0x00004715 ;#MCIO1 - sleep 20 - # - mww 0x48000004 0x03CA4018 ;#MDREF - sleep 20 - mww 0x48000004 0x004B4018 ;#MDREF - sleep 20 - mww 0x48000004 0x000B4018 ;#MDREF - sleep 20 - mww 0x48000004 0x000BC018 ;#MDREF - sleep 20 - mww 0x48000000 0x00001AC8 ;#MDCNFG - sleep 20 - - sleep 20 - - mww 0x48000000 0x00001AC9 ;#MDCNFG - sleep 20 - mww 0x48000040 0x00000000 ;#MDMRS - sleep 20 -} - -$_TARGETNAME configure -event reset-init {pxa255_sst_init} - -reset_config trst_and_srst - -adapter_nsrst_delay 200 -jtag_ntrst_delay 200 - -#xscale debug_handler 0 0xFFFF0800 ;# debug handler base address diff --git a/tcl/board/quark_d2000_refboard.cfg b/tcl/board/quark_d2000_refboard.cfg deleted file mode 100644 index d1388bbaa..000000000 --- a/tcl/board/quark_d2000_refboard.cfg +++ /dev/null @@ -1,15 +0,0 @@ -# Intel Quark microcontroller D2000 Reference Board (web search for doc num 333582) - -# the board has an onboard FTDI FT232H chip -interface ftdi -ftdi_vid_pid 0x0403 0x6014 -ftdi_channel 0 - -ftdi_layout_init 0x0000 0x030b -ftdi_layout_signal nTRST -data 0x0100 -noe 0x0100 - -source [find target/quark_d20xx.cfg] - -adapter_khz 1000 - -reset_config trst_only diff --git a/tcl/board/quark_x10xx_board.cfg b/tcl/board/quark_x10xx_board.cfg deleted file mode 100644 index 8dc600b80..000000000 --- a/tcl/board/quark_x10xx_board.cfg +++ /dev/null @@ -1,9 +0,0 @@ -# There are many Quark boards that can host the quark_x10xx SoC -# Galileo is an example board - -source [find target/quark_x10xx.cfg] - -#default frequency but this can be adjusted at runtime -adapter_khz 4000 - -reset_config trst_only diff --git a/tcl/board/redbee.cfg b/tcl/board/redbee.cfg deleted file mode 100644 index 046e7a478..000000000 --- a/tcl/board/redbee.cfg +++ /dev/null @@ -1 +0,0 @@ -source [find target/mc13224v.cfg] diff --git a/tcl/board/renesas_dk-s7g2.cfg b/tcl/board/renesas_dk-s7g2.cfg deleted file mode 100644 index 3f29ec3ae..000000000 --- a/tcl/board/renesas_dk-s7g2.cfg +++ /dev/null @@ -1,13 +0,0 @@ -# -# Renesas Synergy DK-S7G2 -# - -source [find interface/jlink.cfg] -transport select swd - -# XXX 19-pin SWD+TRACE connector also available - -# Synergy R7FS7G27H2A01CBD -source [find target/renesas_s7g2.cfg] - -# 32 MB QSPI flash (Micron N25Q256A13EF840E) diff --git a/tcl/board/rsc-w910.cfg b/tcl/board/rsc-w910.cfg deleted file mode 100644 index 636a05399..000000000 --- a/tcl/board/rsc-w910.cfg +++ /dev/null @@ -1,66 +0,0 @@ -# Avalue RSC-W8910 sbc -# http://www.avalue.com.tw/products/RSC-W910.cfm -# 2MB NOR Flash -# 64MB SDRAM -# 128MB NAND Flash - -# Based on Nuvoton nuc910 -source [find target/nuc910.cfg] - -# -# reset only behaves correctly if we use srst_pulls_trst -# -reset_config trst_and_srst srst_pulls_trst - -adapter_khz 1000 -adapter_nsrst_delay 100 -jtag_ntrst_delay 100 - -$_TARGETNAME configure -work-area-phys 0x00000000 -work-area-size 0x04000000 -work-area-backup 0 - -set _FLASHNAME $_CHIPNAME.flash -flash bank $_FLASHNAME cfi 0x20000000 0x00200000 2 2 $_TARGETNAME - -set _NANDNAME $_CHIPNAME.nand -nand device $_NANDNAME nuc910 $_TARGETNAME - -# -# Target events -# - -$_TARGETNAME configure -event reset-start {adapter_khz 1000} - -$_TARGETNAME configure -event reset-init { - # switch on PLL for 200MHz operation - # running from 15MHz input clock - - mww 0xB0000200 0x00000030 ;# CLKEN - mww 0xB0000204 0x00000f3c ;# CLKSEL - mww 0xB0000208 0x05007000 ;# CLKDIV - mww 0xB000020C 0x00004f24 ;# PLLCON0 - mww 0xB0000210 0x00002b63 ;# PLLCON1 - mww 0xB000000C 0x08817fa6 ;# MFSEL - sleep 10 - - # we are now running @ 200MHz - # enable all openocd speed tweaks - - arm7_9 dcc_downloads enable - arm7_9 fast_memory_access enable - adapter_khz 15000 - - # map nor flash to 0x20000000 - # map sdram to 0x00000000 - - mww 0xb0001000 0x000530c1 ;# EBICON - mww 0xb0001004 0x40030084 ;# ROMCON - mww 0xb0001008 0x000010ee ;# SDCONF0 - mww 0xb000100C 0x00000000 ;# SDCONF1 - mww 0xb0001010 0x0000015b ;# SDTIME0 - mww 0xb0001014 0x0000015b ;# SDTIME1 - mww 0xb0001018 0x00000000 ;# EXT0CON - mww 0xb000101C 0x00000000 ;# EXT1CON - mww 0xb0001020 0x00000000 ;# EXT2CON - mww 0xb0001024 0x00000000 ;# EXT3CON - mww 0xb000102c 0x00ff0048 ;# CKSKEW -} diff --git a/tcl/board/sheevaplug.cfg b/tcl/board/sheevaplug.cfg deleted file mode 100644 index ff333ca77..000000000 --- a/tcl/board/sheevaplug.cfg +++ /dev/null @@ -1,136 +0,0 @@ -# Marvell SheevaPlug - -source [find interface/ftdi/sheevaplug.cfg] -source [find target/feroceon.cfg] - -adapter_khz 2000 - -$_TARGETNAME configure \ - -work-area-phys 0x10000000 \ - -work-area-size 65536 \ - -work-area-backup 0 - -arm7_9 dcc_downloads enable - -# this assumes the hardware default peripherals location before u-Boot moves it -set _FLASHNAME $_CHIPNAME.flash -nand device $_FLASHNAME orion 0 0xd8000000 - -proc sheevaplug_init { } { - - # We need to assert DBGRQ while holding nSRST down. - # However DBGACK will be set only when nSRST is released. - # Furthermore, the JTAG interface doesn't respond at all when - # the CPU is in the WFI (wait for interrupts) state, so it is - # possible that initial tap examination failed. So let's - # re-examine the target again here when nSRST is asserted which - # should then succeed. - jtag_reset 0 1 - feroceon.cpu arp_examine - halt 0 - jtag_reset 0 0 - wait_halt - - arm mcr 15 0 0 1 0 0x00052078 - - mww 0xD0001400 0x43000C30 ;# DDR SDRAM Configuration Register - mww 0xD0001404 0x39543000 ;# Dunit Control Low Register - mww 0xD0001408 0x22125451 ;# DDR SDRAM Timing (Low) Register - mww 0xD000140C 0x00000833 ;# DDR SDRAM Timing (High) Register - mww 0xD0001410 0x000000CC ;# DDR SDRAM Address Control Register - mww 0xD0001414 0x00000000 ;# DDR SDRAM Open Pages Control Register - mww 0xD0001418 0x00000000 ;# DDR SDRAM Operation Register - mww 0xD000141C 0x00000C52 ;# DDR SDRAM Mode Register - mww 0xD0001420 0x00000042 ;# DDR SDRAM Extended Mode Register - mww 0xD0001424 0x0000F17F ;# Dunit Control High Register - mww 0xD0001428 0x00085520 ;# Dunit Control High Register - mww 0xD000147c 0x00008552 ;# Dunit Control High Register - mww 0xD0001504 0x0FFFFFF1 ;# CS0n Size Register - mww 0xD0001508 0x10000000 ;# CS1n Base Register - mww 0xD000150C 0x0FFFFFF5 ;# CS1n Size Register - mww 0xD0001514 0x00000000 ;# CS2n Size Register - mww 0xD000151C 0x00000000 ;# CS3n Size Register - mww 0xD0001494 0x003C0000 ;# DDR2 SDRAM ODT Control (Low) Register - mww 0xD0001498 0x00000000 ;# DDR2 SDRAM ODT Control (High) REgister - mww 0xD000149C 0x0000F80F ;# DDR2 Dunit ODT Control Register - mww 0xD0001480 0x00000001 ;# DDR SDRAM Initialization Control Register - mww 0xD0020204 0x00000000 ;# Main IRQ Interrupt Mask Register - mww 0xD0020204 0x00000000 ;# " - mww 0xD0020204 0x00000000 ;# " - mww 0xD0020204 0x00000000 ;# " - mww 0xD0020204 0x00000000 ;# " - mww 0xD0020204 0x00000000 ;# " - mww 0xD0020204 0x00000000 ;# " - mww 0xD0020204 0x00000000 ;# " - mww 0xD0020204 0x00000000 ;# " - mww 0xD0020204 0x00000000 ;# " - mww 0xD0020204 0x00000000 ;# " - mww 0xD0020204 0x00000000 ;# " - mww 0xD0020204 0x00000000 ;# " - mww 0xD0020204 0x00000000 ;# " - mww 0xD0020204 0x00000000 ;# " - mww 0xD0020204 0x00000000 ;# " - mww 0xD0020204 0x00000000 ;# " - mww 0xD0020204 0x00000000 ;# " - mww 0xD0020204 0x00000000 ;# " - mww 0xD0020204 0x00000000 ;# " - mww 0xD0020204 0x00000000 ;# " - mww 0xD0020204 0x00000000 ;# " - mww 0xD0020204 0x00000000 ;# " - mww 0xD0020204 0x00000000 ;# " - mww 0xD0020204 0x00000000 ;# " - mww 0xD0020204 0x00000000 ;# " - mww 0xD0020204 0x00000000 ;# " - mww 0xD0020204 0x00000000 ;# " - mww 0xD0020204 0x00000000 ;# " - mww 0xD0020204 0x00000000 ;# " - mww 0xD0020204 0x00000000 ;# " - mww 0xD0020204 0x00000000 ;# " - mww 0xD0020204 0x00000000 ;# " - mww 0xD0020204 0x00000000 ;# " - mww 0xD0020204 0x00000000 ;# " - mww 0xD0020204 0x00000000 ;# " - mww 0xD0020204 0x00000000 ;# " - - mww 0xD0010000 0x01111111 ;# MPP 0 to 7 - mww 0xD0010004 0x11113322 ;# MPP 8 to 15 - mww 0xD0010008 0x00001111 ;# MPP 16 to 23 - - mww 0xD0010418 0x003E07CF ;# NAND Read Parameters REgister - mww 0xD001041C 0x000F0F0F ;# NAND Write Parameters Register - mww 0xD0010470 0x01C7D943 ;# NAND Flash Control Register - -} - -proc sheevaplug_reflash_uboot { } { - - # reflash the u-Boot binary and reboot into it - sheevaplug_init - nand probe 0 - nand erase 0 0x0 0xa0000 - nand write 0 uboot.bin 0 oob_softecc_kw - resume - -} - -proc sheevaplug_reflash_uboot_env { } { - - # reflash the u-Boot environment variables area - sheevaplug_init - nand probe 0 - nand erase 0 0xa0000 0x40000 - nand write 0 uboot-env.bin 0xa0000 oob_softecc_kw - resume - -} - -proc sheevaplug_load_uboot { } { - - # load u-Boot into RAM and execute it - sheevaplug_init - load_image uboot.elf - verify_image uboot.elf - resume 0x00600000 - -} - diff --git a/tcl/board/smdk6410.cfg b/tcl/board/smdk6410.cfg deleted file mode 100644 index dd8bf87ad..000000000 --- a/tcl/board/smdk6410.cfg +++ /dev/null @@ -1,9 +0,0 @@ -# Target configuration for the Samsung s3c6410 system on chip -# Tested on a SMDK6410 -# Processor : ARM1176 -# Info: JTAG device found: 0x0032409d (Manufacturer: 0x04e, Part: 0x0324, Version: 0x0) - -source [find target/samsung_s3c6410.cfg] - -set _FLASHNAME $_CHIPNAME.flash -flash bank $_FLASHNAME cfi 0x00000000 0x00100000 2 2 $_TARGETNAME jedec_probe diff --git a/tcl/board/spansion_sk-fm4-176l-s6e2cc.cfg b/tcl/board/spansion_sk-fm4-176l-s6e2cc.cfg deleted file mode 100644 index 2855c5d41..000000000 --- a/tcl/board/spansion_sk-fm4-176l-s6e2cc.cfg +++ /dev/null @@ -1,20 +0,0 @@ -# -# Spansion SK-FM4-176L-S6E2CC -# - -# -# FM3 MB9AF312K -# -source [find interface/cmsis-dap.cfg] - -# There's also an unpopulated 10-pin 0.05" pinout. - -# -# FM4 S6E2CCAJ0A w/ 192 KB SRAM0 -# -set CHIPNAME s6e2cc -set CHIPSERIES S6E2CCAJ0A -set WORKAREASIZE 0x30000 -source [find target/fm4_s6e2cc.cfg] - -reset_config srst_only diff --git a/tcl/board/spansion_sk-fm4-u120-9b560.cfg b/tcl/board/spansion_sk-fm4-u120-9b560.cfg deleted file mode 100644 index 38ad4a883..000000000 --- a/tcl/board/spansion_sk-fm4-u120-9b560.cfg +++ /dev/null @@ -1,18 +0,0 @@ -# -# Spansion SK-FM4-U120-9B560 -# - -# -# FM3 MB9AF312K -# -# source [find interface/cmsis-dap.cfg] - -# -# FM4 MB9BF568R w/ 64 KB SRAM0 -# -set CHIPNAME mb9bf568 -set CHIPSERIES MB9BF568R -set WORKAREASIZE 0x10000 -source [find target/fm4_mb9bf.cfg] - -reset_config srst_only diff --git a/tcl/board/spear300evb.cfg b/tcl/board/spear300evb.cfg deleted file mode 100644 index 9f957038d..000000000 --- a/tcl/board/spear300evb.cfg +++ /dev/null @@ -1,44 +0,0 @@ -# Configuration for the ST SPEAr300 Evaluation board -# EVALSPEAr300 Rev. 1.0 -# http://www.st.com/spear -# -# Date: 2010-11-27 -# Author: Antonio Borneo - -# The standard board has JTAG SRST not connected. -# This script targets such boards using quirky code to bypass the issue. - - -source [find mem_helper.tcl] -source [find target/spear3xx.cfg] -source [find chip/st/spear/spear3xx_ddr.tcl] -source [find chip/st/spear/spear3xx.tcl] - -arm7_9 dcc_downloads enable -arm7_9 fast_memory_access enable - - -# Serial NOR on SMI CS0. 8Mbyte. -set _FLASHNAME1 $_CHIPNAME.snor -flash bank $_FLASHNAME1 stmsmi 0xf8000000 0 0 0 $_TARGETNAME - -if { [info exists BOARD_HAS_SRST] } { - # Modified board has SRST on JTAG connector - reset_config trst_and_srst separate srst_gates_jtag \ - trst_push_pull srst_open_drain -} else { - # Standard board has no SRST on JTAG connector - reset_config trst_only separate srst_gates_jtag trst_push_pull - source [find chip/st/spear/quirk_no_srst.tcl] -} - -$_TARGETNAME configure -event reset-init { spear300evb_init } - -proc spear300evb_init {} { - reg pc 0xffff0020; # loop forever - - sp3xx_clock_default - sp3xx_common_init - sp3xx_ddr_init "mt47h64m16_3_333_cl5_async" - sp300_init -} diff --git a/tcl/board/spear300evb_mod.cfg b/tcl/board/spear300evb_mod.cfg deleted file mode 100644 index 91cad5f19..000000000 --- a/tcl/board/spear300evb_mod.cfg +++ /dev/null @@ -1,26 +0,0 @@ -# Configuration for the ST SPEAr300 Evaluation board -# EVALSPEAr300 Rev. 1.0, modified to enable SRST on JTAG connector -# http://www.st.com/spear -# -# List of board modifications to enable SRST, as reported in -# ST Application Note (FIXME: add reference). -# - Modifications on the top layer: -# 1. replace reset chip U4 with a STM6315SDW13F; -# - Modifications on the bottom layer: -# 2. add 0 ohm resistor R10. It is located close to JTAG connector. -# 3. add a 10K ohm pull-up resistor on the reset wire named as -# POWERGOOD in the schematic. -# -# The easier way to do modification 3, is to use a resistor in package -# 0603 and solder it between R10 and R54: -# - one pad soldered with the pad of R54 connected to 3.3V (this -# is the pad of R54 far from JTAG connector J4) -# - the other pad soldered with the nearest pad of R10. -# -# Date: 2011-11-18 -# Author: Antonio Borneo - - -# Modified boards has SRST on JTAG connector -set BOARD_HAS_SRST 1 -source [find board/spear300evb.cfg] diff --git a/tcl/board/spear310evb20.cfg b/tcl/board/spear310evb20.cfg deleted file mode 100644 index c45873ca9..000000000 --- a/tcl/board/spear310evb20.cfg +++ /dev/null @@ -1,51 +0,0 @@ -# Configuration for the ST SPEAr310 Evaluation board -# EVALSPEAr310 Rev. 2.0 -# http://www.st.com/spear -# -# Date: 2010-08-17 -# Author: Antonio Borneo - -# The standard board has JTAG SRST not connected. -# This script targets such boards using quirky code to bypass the issue. -# -# Check ST Application Note AN3321 on how to fix SRST on -# the board, then use the script board/spear310evb20_mod.cfg - - -source [find mem_helper.tcl] -source [find target/spear3xx.cfg] -source [find chip/st/spear/spear3xx_ddr.tcl] -source [find chip/st/spear/spear3xx.tcl] - -arm7_9 dcc_downloads enable -arm7_9 fast_memory_access enable - -# CFI parallel NOR on EMI CS0. 2x 16bit 8M devices = 16Mbyte. -set _FLASHNAME0 $_CHIPNAME.pnor -flash bank $_FLASHNAME0 cfi 0x50000000 0x01000000 2 4 $_TARGETNAME - -# Serial NOR on SMI CS0. 8Mbyte. -set _FLASHNAME1 $_CHIPNAME.snor -flash bank $_FLASHNAME1 stmsmi 0xf8000000 0 0 0 $_TARGETNAME - -if { [info exists BOARD_HAS_SRST] } { - # Modified board has SRST on JTAG connector - reset_config trst_and_srst separate srst_gates_jtag \ - trst_push_pull srst_open_drain -} else { - # Standard board has no SRST on JTAG connector - reset_config trst_only separate srst_gates_jtag trst_push_pull - source [find chip/st/spear/quirk_no_srst.tcl] -} - -$_TARGETNAME configure -event reset-init { spear310evb20_init } - -proc spear310evb20_init {} { - reg pc 0xffff0020 ;# loop forever - - sp3xx_clock_default - sp3xx_common_init - sp3xx_ddr_init "mt47h64m16_3_333_cl5_async" - sp310_init - sp310_emi_init -} diff --git a/tcl/board/spear310evb20_mod.cfg b/tcl/board/spear310evb20_mod.cfg deleted file mode 100644 index a7bac55a5..000000000 --- a/tcl/board/spear310evb20_mod.cfg +++ /dev/null @@ -1,25 +0,0 @@ -# Configuration for the ST SPEAr310 Evaluation board -# EVALSPEAr310 Rev. 2.0, modified to enable SRST on JTAG connector -# http://www.st.com/spear -# -# List of board modifications to enable SRST, as reported in -# ST Application Note AN3321. -# - Modifications on the top layer: -# 1. remove R137 and C57, located near the SMII PHY U18; -# 2. remove R172 and C75, located near the SMII PHY U19; -# 3. remove R207 and C90, located near the SMII PHY U20; -# 4. remove C236, located near the SMII PHY U21; -# 5. remove U12, located near the JTAG connector; -# 6. solder together pins 7, 8 and 9 of U12; -# 7. solder together pins 11, 12, 13, 14, 15, 16, 17 and 18 of U12. -# - Modifications on the bottom layer: -# 8. replace reset chip U11 with a STM6315SDW13F; -# 9. add 0 ohm resistor R329. It is located close to JTAG connector. -# -# Date: 2009-10-31 -# Author: Antonio Borneo - - -# Modified boards has SRST on JTAG connector -set BOARD_HAS_SRST 1 -source [find board/spear310evb20.cfg] diff --git a/tcl/board/spear320cpu.cfg b/tcl/board/spear320cpu.cfg deleted file mode 100644 index e21db3412..000000000 --- a/tcl/board/spear320cpu.cfg +++ /dev/null @@ -1,51 +0,0 @@ -# Configuration for the ST SPEAr320 CPU board -# EVAL_SPEAr320CPU Rev. 2.0 -# http://www.st.com/spear -# -# Date: 2011-11-18 -# Author: Antonio Borneo - -# The standard board has JTAG SRST not connected. -# This script targets such boards using quirky code to bypass the issue. - - -source [find mem_helper.tcl] -source [find target/spear3xx.cfg] -source [find chip/st/spear/spear3xx_ddr.tcl] -source [find chip/st/spear/spear3xx.tcl] - -arm7_9 dcc_downloads enable -arm7_9 fast_memory_access enable - - -# Serial NOR on SMI CS0. 8Mbyte. -set _FLASHNAME1 $_CHIPNAME.snor -flash bank $_FLASHNAME1 stmsmi 0xf8000000 0 0 0 $_TARGETNAME - -if { [info exists BOARD_HAS_SRST] } { - # Modified board has SRST on JTAG connector - reset_config trst_and_srst separate srst_gates_jtag \ - trst_push_pull srst_open_drain -} else { - # Standard board has no SRST on JTAG connector - reset_config trst_only separate srst_gates_jtag trst_push_pull - source [find chip/st/spear/quirk_no_srst.tcl] -} - -$_TARGETNAME configure -event reset-init { spear320cpu_init } - -if { [info exists DDR_CHIPS] } { - set _DDR_CHIPS $DDR_CHIPS -} else { - set _DDR_CHIPS 1 -} - -proc spear320cpu_init {} { - global _DDR_CHIPS - reg pc 0xffff0020; # loop forever - - sp3xx_clock_default - sp3xx_common_init - sp3xx_ddr_init "mt47h64m16_3_333_cl5_async" $_DDR_CHIPS - sp320_init -} diff --git a/tcl/board/spear320cpu_mod.cfg b/tcl/board/spear320cpu_mod.cfg deleted file mode 100644 index 1d62e3b55..000000000 --- a/tcl/board/spear320cpu_mod.cfg +++ /dev/null @@ -1,25 +0,0 @@ -# Configuration for the ST SPEAr320 Evaluation board -# EVAL_SPEAr320CPU Rev. 2.0, modified to enable SRST on JTAG connector -# http://www.st.com/spear -# -# List of board modifications to enable SRST, as reported in -# ST Application Note (FIXME: add reference). -# - Modifications on the bottom layer: -# 1. replace reset chip U7 with a STM6315SDW13F; -# 2. add 0 ohm resistor R45. It is located close to JTAG connector. -# 3. add a 10K ohm pull-up resistor on the reset wire named as -# POWERGOOD in the schematic. -# -# The easier way to do modification 3, is to use a resistor in package -# 0603 or 0402 and solder it between R15 and R45: -# - one pad soldered with the pad of R15 connected to 3.3V (this -# is the pad of R15 closer to R45) -# - the other pad soldered with the nearest pad of R45. -# -# Date: 2011-11-18 -# Author: Antonio Borneo - - -# Modified boards has SRST on JTAG connector -set BOARD_HAS_SRST 1 -source [find board/spear320cpu.cfg] diff --git a/tcl/board/st_nucleo_f0.cfg b/tcl/board/st_nucleo_f0.cfg deleted file mode 100644 index e9fda19a6..000000000 --- a/tcl/board/st_nucleo_f0.cfg +++ /dev/null @@ -1,15 +0,0 @@ -# This is for all ST NUCLEO with any STM32F0. Known boards at the moment: -# STM32F030R8 -# http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/LN1847/PF259997 -# NUCLEO-F072RB -# http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/LN1847/PF259997 -# STM32F091RC -# http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/LN1847/PF260944 - -source [find interface/stlink-v2-1.cfg] - -transport select hla_swd - -source [find target/stm32f0x.cfg] - -reset_config srst_only diff --git a/tcl/board/st_nucleo_f103rb.cfg b/tcl/board/st_nucleo_f103rb.cfg deleted file mode 100644 index 71a92f704..000000000 --- a/tcl/board/st_nucleo_f103rb.cfg +++ /dev/null @@ -1,10 +0,0 @@ -# This is an ST NUCLEO F103RB board with a single STM32F103RBT6 chip. -# http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/LN1847/PF259875 - -source [find interface/stlink-v2-1.cfg] - -transport select hla_swd - -source [find target/stm32f1x.cfg] - -reset_config srst_only diff --git a/tcl/board/st_nucleo_f3.cfg b/tcl/board/st_nucleo_f3.cfg deleted file mode 100644 index 9dffdcbbd..000000000 --- a/tcl/board/st_nucleo_f3.cfg +++ /dev/null @@ -1,10 +0,0 @@ -# This is an ST NUCLEO F334R8 board with a single STM32F334R8T6 chip. -# http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/LN1847/PF260004 - -source [find interface/stlink-v2-1.cfg] - -transport select hla_swd - -source [find target/stm32f3x.cfg] - -reset_config srst_only diff --git a/tcl/board/st_nucleo_f4.cfg b/tcl/board/st_nucleo_f4.cfg deleted file mode 100644 index b5a78c1c0..000000000 --- a/tcl/board/st_nucleo_f4.cfg +++ /dev/null @@ -1,13 +0,0 @@ -# This is for all ST NUCLEO with any STM32F4. Known boards at the moment: -# STM32F401RET6 -# http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/LN1847/PF260000 -# STM32F411RET6 -# http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/LN1847/PF260320 - -source [find interface/stlink-v2-1.cfg] - -transport select hla_swd - -source [find target/stm32f4x.cfg] - -reset_config srst_only diff --git a/tcl/board/st_nucleo_l1.cfg b/tcl/board/st_nucleo_l1.cfg deleted file mode 100644 index 56e275627..000000000 --- a/tcl/board/st_nucleo_l1.cfg +++ /dev/null @@ -1,10 +0,0 @@ -# This is an ST NUCLEO L152RE board with a single STM32L152RET6 chip. -# http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/LN1847/PF260002 - -source [find interface/stlink-v2-1.cfg] - -transport select hla_swd - -source [find target/stm32l1.cfg] - -reset_config srst_only diff --git a/tcl/board/st_nucleo_l476rg.cfg b/tcl/board/st_nucleo_l476rg.cfg deleted file mode 100644 index 2baa34e76..000000000 --- a/tcl/board/st_nucleo_l476rg.cfg +++ /dev/null @@ -1,12 +0,0 @@ -# This is a ST NUCLEO L476RG board with a single STM32L476RGT6 chip. -# http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/LN1847/PF261636 - -source [find interface/stlink-v2-1.cfg] - -transport select hla_swd - -source [find target/stm32l4x.cfg] - -# use hardware reset -reset_config srst_only srst_nogate - diff --git a/tcl/board/steval_pcc010.cfg b/tcl/board/steval_pcc010.cfg deleted file mode 100644 index ddfdbb36f..000000000 --- a/tcl/board/steval_pcc010.cfg +++ /dev/null @@ -1,9 +0,0 @@ -# Use for the STM207VG plug-in board (1 MiB Flash and 112+16 KiB Ram -# comming with the STEVAL-PCC010 board -# http://www.st.com/internet/evalboard/product/251530.jsp -# or any other board with only a STM32F2x in the JTAG chain - -# increase working area to 32KB for faster flash programming -set WORKAREASIZE 0x8000 - -source [find target/stm32f2x.cfg] diff --git a/tcl/board/stm320518_eval.cfg b/tcl/board/stm320518_eval.cfg deleted file mode 100644 index 6f1f32271..000000000 --- a/tcl/board/stm320518_eval.cfg +++ /dev/null @@ -1,12 +0,0 @@ -# STM320518-EVAL: This is an STM32F0 eval board with a single STM32F051R8T6 -# (64KB) chip. -# http://www.st.com/internet/evalboard/product/252994.jsp -# - -# increase working area to 8KB -set WORKAREASIZE 0x2000 - -# chip name -set CHIPNAME STM32F051R8T6 - -source [find target/stm32f0x.cfg] diff --git a/tcl/board/stm320518_eval_stlink.cfg b/tcl/board/stm320518_eval_stlink.cfg deleted file mode 100644 index ce074cbf2..000000000 --- a/tcl/board/stm320518_eval_stlink.cfg +++ /dev/null @@ -1,19 +0,0 @@ -# STM320518-EVAL: This is an STM32F0 eval board with a single STM32F051R8T6 -# (64KB) chip. -# http://www.st.com/internet/evalboard/product/252994.jsp -# -# This is for using the onboard STLINK/V2 - -source [find interface/stlink-v2.cfg] - -transport select hla_swd - -# increase working area to 8KB -set WORKAREASIZE 0x2000 - -# chip name -set CHIPNAME STM32F051R8T6 - -source [find target/stm32f0x.cfg] - -reset_config srst_only diff --git a/tcl/board/stm32100b_eval.cfg b/tcl/board/stm32100b_eval.cfg deleted file mode 100644 index 41153e555..000000000 --- a/tcl/board/stm32100b_eval.cfg +++ /dev/null @@ -1,7 +0,0 @@ -# This is an STM32 eval board with a single STM32F100VBT6 chip. -# http://www.st.com/internet/evalboard/product/247099.jsp - -# The chip has only 8KB sram -set WORKAREASIZE 0x2000 - -source [find target/stm32f1x.cfg] diff --git a/tcl/board/stm3210b_eval.cfg b/tcl/board/stm3210b_eval.cfg deleted file mode 100644 index ff3f7771a..000000000 --- a/tcl/board/stm3210b_eval.cfg +++ /dev/null @@ -1,7 +0,0 @@ -# This is an STM32 eval board with a single STM32F10x (128KB) chip. -# http://www.st.com/internet/evalboard/product/176090.jsp - -# increase working area to 32KB for faster flash programming -set WORKAREASIZE 0x8000 - -source [find target/stm32f1x.cfg] diff --git a/tcl/board/stm3210c_eval.cfg b/tcl/board/stm3210c_eval.cfg deleted file mode 100644 index e069c0499..000000000 --- a/tcl/board/stm3210c_eval.cfg +++ /dev/null @@ -1,7 +0,0 @@ -# This is an STM32 eval board with a single STM32F107VCT chip. -# http://www.st.com/internet/evalboard/product/217965.jsp - -# increase working area to 32KB for faster flash programming -set WORKAREASIZE 0x8000 - -source [find target/stm32f1x.cfg] diff --git a/tcl/board/stm3210e_eval.cfg b/tcl/board/stm3210e_eval.cfg deleted file mode 100644 index 91807ce30..000000000 --- a/tcl/board/stm3210e_eval.cfg +++ /dev/null @@ -1,63 +0,0 @@ -# This is an STM32 eval board with a single STM32F103ZET6 chip. -# http://www.st.com/internet/evalboard/product/204176.jsp - -# increase working area to 32KB for faster flash programming -set WORKAREASIZE 0x8000 - -source [find target/stm32f1x.cfg] - -# -# configure FSMC Bank 1 (NOR/PSRAM Bank 2) NOR flash -# M29W128GL70ZA6E -# - -set _FLASHNAME $_CHIPNAME.norflash -flash bank $_FLASHNAME cfi 0x64000000 0x01000000 2 2 $_TARGETNAME - -proc stm32_enable_fsmc {} { - - echo "Enabling FSMC Bank 1 (NOR/PSRAM Bank 2)" - - # enable gpio (defg) clocks for fsmc - # RCC_APB2ENR - mww 0x40021018 0x000001E0 - - # enable fsmc clock - # RCC_AHBENR - mww 0x40021014 0x00000114 - - # configure gpio to alternate function - # GPIOD_CRL - mww 0x40011400 0x44BB44BB - # GPIOD_CRH - mww 0x40011404 0xBBBBBBBB - - # GPIOE_CRL - mww 0x40011800 0xBBBBB444 - # GPIOE_CRH - mww 0x40011804 0xBBBBBBBB - - # GPIOF_CRL - mww 0x40011C00 0x44BBBBBB - # GPIOF_CRH - mww 0x40011C04 0xBBBB4444 - - # GPIOG_CRL - mww 0x40012000 0x44BBBBBB - # GPIOG_CRH - mww 0x40012004 0x444444B4 - - # setup fsmc timings - # FSMC_BCR1 - mww 0xA0000008 0x00001058 - - # FSMC_BTR1 - mww 0xA000000C 0x10000502 - - # FSMC_BCR1 - enable fsmc - mww 0xA0000008 0x00001059 -} - -$_TARGETNAME configure -event reset-init { - stm32_enable_fsmc -} diff --git a/tcl/board/stm3220g_eval.cfg b/tcl/board/stm3220g_eval.cfg deleted file mode 100644 index 472843298..000000000 --- a/tcl/board/stm3220g_eval.cfg +++ /dev/null @@ -1,11 +0,0 @@ -# STM3220G-EVAL: This is an STM32F2 eval board with a single STM32F207IGH6 -# (128KB) chip. -# http://www.st.com/internet/evalboard/product/250374.jsp - -# increase working area to 128KB -set WORKAREASIZE 0x20000 - -# chip name -set CHIPNAME STM32F207IGH6 - -source [find target/stm32f2x.cfg] diff --git a/tcl/board/stm3220g_eval_stlink.cfg b/tcl/board/stm3220g_eval_stlink.cfg deleted file mode 100644 index 43a4df986..000000000 --- a/tcl/board/stm3220g_eval_stlink.cfg +++ /dev/null @@ -1,19 +0,0 @@ -# STM3220G-EVAL: This is an STM32F2 eval board with a single STM32F207IGH6 -# (128KB) chip. -# http://www.st.com/internet/evalboard/product/250374.jsp -# -# This is for using the onboard STLINK/V2 - -source [find interface/stlink-v2.cfg] - -transport select hla_swd - -# increase working area to 128KB -set WORKAREASIZE 0x20000 - -# chip name -set CHIPNAME STM32F207IGH6 - -source [find target/stm32f2x.cfg] - -reset_config srst_only diff --git a/tcl/board/stm3241g_eval.cfg b/tcl/board/stm3241g_eval.cfg deleted file mode 100644 index 5f1c449d3..000000000 --- a/tcl/board/stm3241g_eval.cfg +++ /dev/null @@ -1,11 +0,0 @@ -# STM3241G-EVAL: This is an STM32F4 eval board with a single STM32F417IGH6 -# (1024KB) chip. -# http://www.st.com/internet/evalboard/product/252216.jsp - -# increase working area to 128KB -set WORKAREASIZE 0x20000 - -# chip name -set CHIPNAME STM32F417IGH6 - -source [find target/stm32f4x.cfg] diff --git a/tcl/board/stm3241g_eval_stlink.cfg b/tcl/board/stm3241g_eval_stlink.cfg deleted file mode 100644 index 9c7ad5d95..000000000 --- a/tcl/board/stm3241g_eval_stlink.cfg +++ /dev/null @@ -1,19 +0,0 @@ -# STM3241G-EVAL: This is an STM32F4 eval board with a single STM32F417IGH6 -# (1024KB) chip. -# http://www.st.com/internet/evalboard/product/252216.jsp -# -# This is for using the onboard STLINK/V2 - -source [find interface/stlink-v2.cfg] - -transport select hla_swd - -# increase working area to 128KB -set WORKAREASIZE 0x20000 - -# chip name -set CHIPNAME STM32F417IGH6 - -source [find target/stm32f4x.cfg] - -reset_config srst_only diff --git a/tcl/board/stm32429i_eval.cfg b/tcl/board/stm32429i_eval.cfg deleted file mode 100644 index a5d3f53c9..000000000 --- a/tcl/board/stm32429i_eval.cfg +++ /dev/null @@ -1,11 +0,0 @@ -# STM32429I-EVAL: This is an STM32F4 eval board with a single STM32F429NIH6 -# (2048KB) chip. -# http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/LN1199/PF259093 - -# increase working area to 128KB -set WORKAREASIZE 0x20000 - -# chip name -set CHIPNAME STM32F429NIH6 - -source [find target/stm32f4x.cfg] diff --git a/tcl/board/stm32429i_eval_stlink.cfg b/tcl/board/stm32429i_eval_stlink.cfg deleted file mode 100644 index 2b51cea67..000000000 --- a/tcl/board/stm32429i_eval_stlink.cfg +++ /dev/null @@ -1,19 +0,0 @@ -# STM32429I-EVAL: This is an STM32F4 eval board with a single STM32F429NIH6 -# (2048KB) chip. -# http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/LN1199/PF259093 -# -# This is for using the onboard STLINK/V2 - -source [find interface/stlink-v2.cfg] - -transport select hla_swd - -# increase working area to 128KB -set WORKAREASIZE 0x20000 - -# chip name -set CHIPNAME STM32F429NIH6 - -source [find target/stm32f4x.cfg] - -reset_config srst_only diff --git a/tcl/board/stm32439i_eval.cfg b/tcl/board/stm32439i_eval.cfg deleted file mode 100644 index 8ebdc8267..000000000 --- a/tcl/board/stm32439i_eval.cfg +++ /dev/null @@ -1,11 +0,0 @@ -# STM32439I-EVAL: This is an STM32F4 eval board with a single STM32F439NIH6 -# (2048KB) chip. -# http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/LN1199/PF259094 - -# increase working area to 128KB -set WORKAREASIZE 0x20000 - -# chip name -set CHIPNAME STM32F439NIH6 - -source [find target/stm32f4x.cfg] diff --git a/tcl/board/stm32439i_eval_stlink.cfg b/tcl/board/stm32439i_eval_stlink.cfg deleted file mode 100644 index 5995fb1d2..000000000 --- a/tcl/board/stm32439i_eval_stlink.cfg +++ /dev/null @@ -1,19 +0,0 @@ -# STM32439I-EVAL: This is an STM32F4 eval board with a single STM32F439NIH6 -# (2048KB) chip. -# http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/LN1199/PF259094 -# -# This is for using the onboard STLINK/V2 - -source [find interface/stlink-v2.cfg] - -transport select hla_swd - -# increase working area to 128KB -set WORKAREASIZE 0x20000 - -# chip name -set CHIPNAME STM32F439NIH6 - -source [find target/stm32f4x.cfg] - -reset_config srst_only diff --git a/tcl/board/stm327x6g_eval.cfg b/tcl/board/stm327x6g_eval.cfg deleted file mode 100644 index a5e5896b3..000000000 --- a/tcl/board/stm327x6g_eval.cfg +++ /dev/null @@ -1,10 +0,0 @@ -# STM327[4|5]6G-EVAL: This is for the STM32F7 eval boards. -# STM32746G-EVAL -# http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/LN1199/PF261639 -# STM32756G-EVAL -# http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/LN1199/PF261640 - -# increase working area to 256KB -set WORKAREASIZE 0x40000 - -source [find target/stm32f7x.cfg] diff --git a/tcl/board/stm32f0discovery.cfg b/tcl/board/stm32f0discovery.cfg deleted file mode 100644 index bae9a69ba..000000000 --- a/tcl/board/stm32f0discovery.cfg +++ /dev/null @@ -1,11 +0,0 @@ -# This is an STM32F0 discovery board with a single STM32F051R8T6 chip. -# http://www.st.com/internet/evalboard/product/253215.jsp - -source [find interface/stlink-v2.cfg] - -transport select hla_swd - -set WORKAREASIZE 0x2000 -source [find target/stm32f0x.cfg] - -reset_config srst_only diff --git a/tcl/board/stm32f334discovery.cfg b/tcl/board/stm32f334discovery.cfg deleted file mode 100644 index be817d716..000000000 --- a/tcl/board/stm32f334discovery.cfg +++ /dev/null @@ -1,6 +0,0 @@ -# This is an STM32F334 discovery board with a single STM32F334C8T6 chip. -# As it is one of the few boards with stlink V.2-1, we source the corresponding -# nucleo file. -# http://www.st.com/web/en/catalog/tools/FM116/SC959/SS1532/LN1848/PF260318 - -source [find board/st_nucleo_f3.cfg] diff --git a/tcl/board/stm32f3discovery.cfg b/tcl/board/stm32f3discovery.cfg deleted file mode 100644 index 5a17b4c99..000000000 --- a/tcl/board/stm32f3discovery.cfg +++ /dev/null @@ -1,10 +0,0 @@ -# This is an STM32F3 discovery board with a single STM32F303VCT6 chip. -# http://www.st.com/internet/evalboard/product/254044.jsp - -source [find interface/stlink-v2.cfg] - -transport select hla_swd - -source [find target/stm32f3x.cfg] - -reset_config srst_only diff --git a/tcl/board/stm32f429disc1.cfg b/tcl/board/stm32f429disc1.cfg deleted file mode 100644 index 9d3cdd757..000000000 --- a/tcl/board/stm32f429disc1.cfg +++ /dev/null @@ -1,12 +0,0 @@ -# -# This is an STM32F429 discovery board with a single STM32F429ZI chip. -# http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/PF259090 -# - -source [find interface/stlink-v2-1.cfg] - -transport select hla_swd - -source [find target/stm32f4x.cfg] - -reset_config srst_only diff --git a/tcl/board/stm32f429discovery.cfg b/tcl/board/stm32f429discovery.cfg deleted file mode 100644 index e06d2a51c..000000000 --- a/tcl/board/stm32f429discovery.cfg +++ /dev/null @@ -1,15 +0,0 @@ -# -# This is an STM32F429 discovery board with a single STM32F429ZI chip. -# http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/PF259090 -# - -source [find interface/stlink-v2.cfg] - -transport select hla_swd - -# increase working area to 128KB -set WORKAREASIZE 0x20000 - -source [find target/stm32f4x.cfg] - -reset_config srst_only diff --git a/tcl/board/stm32f469discovery.cfg b/tcl/board/stm32f469discovery.cfg deleted file mode 100644 index 63b13638a..000000000 --- a/tcl/board/stm32f469discovery.cfg +++ /dev/null @@ -1,15 +0,0 @@ -# -# This is an STM32F469 discovery board with a single STM32F469NI chip. -# http://www.st.com/web/catalog/tools/FM116/CL1620/SC959/SS1532/LN1848/PF262395 -# - -source [find interface/stlink-v2-1.cfg] - -transport select hla_swd - -# increase working area to 128KB -set WORKAREASIZE 0x20000 - -source [find target/stm32f4x.cfg] - -reset_config srst_only diff --git a/tcl/board/stm32f4discovery.cfg b/tcl/board/stm32f4discovery.cfg deleted file mode 100644 index 963e0f959..000000000 --- a/tcl/board/stm32f4discovery.cfg +++ /dev/null @@ -1,13 +0,0 @@ -# This is an STM32F4 discovery board with a single STM32F407VGT6 chip. -# http://www.st.com/internet/evalboard/product/252419.jsp - -source [find interface/stlink-v2.cfg] - -transport select hla_swd - -# increase working area to 64KB -set WORKAREASIZE 0x10000 - -source [find target/stm32f4x.cfg] - -reset_config srst_only diff --git a/tcl/board/stm32f7discovery.cfg b/tcl/board/stm32f7discovery.cfg deleted file mode 100755 index 085340f30..000000000 --- a/tcl/board/stm32f7discovery.cfg +++ /dev/null @@ -1,12 +0,0 @@ -# This is an STM32F7 discovery board with a single STM32F756NGH6 chip. -# http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/LN1848/PF261641 - -# This is for using the onboard STLINK/V2-1 -source [find interface/stlink-v2-1.cfg] - -transport select hla_swd - -# increase working area to 256KB -set WORKAREASIZE 0x40000 - -source [find target/stm32f7x.cfg] diff --git a/tcl/board/stm32l0discovery.cfg b/tcl/board/stm32l0discovery.cfg deleted file mode 100644 index a03506224..000000000 --- a/tcl/board/stm32l0discovery.cfg +++ /dev/null @@ -1,11 +0,0 @@ -# This is an STM32L053 discovery board with a single STM32L053 chip. -# http://www.st.com/web/en/catalog/tools/PF260319 - -source [find interface/stlink-v2-1.cfg] - -transport select hla_swd - -set WORKAREASIZE 0x2000 -source [find target/stm32l0.cfg] - -reset_config srst_only diff --git a/tcl/board/stm32l4discovery.cfg b/tcl/board/stm32l4discovery.cfg deleted file mode 100644 index eb1933116..000000000 --- a/tcl/board/stm32l4discovery.cfg +++ /dev/null @@ -1,13 +0,0 @@ -# Explicitly for the STM32L476 discovery board: -# http://www.st.com/web/en/catalog/tools/PF261635 -# but perfectly functional for any other STM32L4 board connected via -# an stlink-v2-1 interface. -# This is for STM32L4 boards that are connected via stlink-v2-1. - -source [find interface/stlink-v2-1.cfg] - -transport select hla_swd - -source [find target/stm32l4x.cfg] - -reset_config srst_only diff --git a/tcl/board/stm32ldiscovery.cfg b/tcl/board/stm32ldiscovery.cfg deleted file mode 100644 index 8678d290b..000000000 --- a/tcl/board/stm32ldiscovery.cfg +++ /dev/null @@ -1,11 +0,0 @@ -# This is an STM32L discovery board with a single STM32L152RBT6 chip. -# http://www.st.com/internet/evalboard/product/250990.jsp - -source [find interface/stlink-v2.cfg] - -transport select hla_swd - -set WORKAREASIZE 0x4000 -source [find target/stm32l1.cfg] - -reset_config srst_only diff --git a/tcl/board/stm32vldiscovery.cfg b/tcl/board/stm32vldiscovery.cfg deleted file mode 100644 index 970b5101e..000000000 --- a/tcl/board/stm32vldiscovery.cfg +++ /dev/null @@ -1,11 +0,0 @@ -# This is an STM32VL discovery board with a single STM32F100RB chip. -# http://www.st.com/internet/evalboard/product/250863.jsp - -source [find interface/stlink-v1.cfg] - -transport select hla_swd - -set WORKAREASIZE 0x2000 -source [find target/stm32f1x.cfg] - -reset_config srst_only diff --git a/tcl/board/str910-eval.cfg b/tcl/board/str910-eval.cfg deleted file mode 100644 index 5fe7a4e73..000000000 --- a/tcl/board/str910-eval.cfg +++ /dev/null @@ -1,64 +0,0 @@ -# str910-eval eval board -# -# Need reset scripts -reset_config trst_and_srst - -# FIXME use some standard target config, maybe create one from this -# -# source [find target/...cfg] - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME str912 -} - -if { [info exists ENDIAN] } { - set _ENDIAN $ENDIAN -} else { - set _ENDIAN little -} - -if { [info exists FLASHTAPID] } { - set _FLASHTAPID $FLASHTAPID -} else { - set _FLASHTAPID 0x04570041 -} -jtag newtap $_CHIPNAME flash -irlen 8 -ircapture 0x1 -irmask 0x1 -expected-id $_FLASHTAPID - - -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - set _CPUTAPID 0x25966041 -} -jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID - -if { [info exists BSTAPID] } { - set _BSTAPID $BSTAPID -} else { - set _BSTAPID 0x1457f041 -} -jtag newtap $_CHIPNAME bs -irlen 5 -ircapture 0x1 -irmask 0x1 -expected-id $_BSTAPID - -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME arm966e -endian $_ENDIAN -chain-position $_TARGETNAME -$_TARGETNAME configure -work-area-phys 0x50000000 -work-area-size 16384 -work-area-backup 1 - -$_TARGETNAME configure -event reset-init { - # We can increase speed now that we know the target is halted. - #jtag_rclk 3000 - - # -- Enable 96K RAM - # PFQBC enabled / DTCM & AHB wait-states disabled - mww 0x5C002034 0x0191 - - str9x flash_config 0 4 2 0 0x80000 - flash protect 0 0 7 off -} - -#flash bank str9x 0 0 -set _FLASHNAME $_CHIPNAME.flash0 -flash bank $_FLASHNAME str9x 0x00000000 0x00080000 0 0 0 -set _FLASHNAME $_CHIPNAME.flash1 -flash bank $_FLASHNAME str9x 0x00080000 0x00008000 0 0 0 diff --git a/tcl/board/telo.cfg b/tcl/board/telo.cfg deleted file mode 100644 index 126f388f2..000000000 --- a/tcl/board/telo.cfg +++ /dev/null @@ -1,61 +0,0 @@ -source [find target/c100.cfg] -# basic register defintion for C100 -source [find target/c100regs.tcl] -# board-config info -source [find target/c100config.tcl] -# C100 helper functions -source [find target/c100helper.tcl] - - -# Telo board & C100 support trst and srst -# Note that libftd2xx.so tries to assert srst -# which break this script -# use libftdi.so library instead with this script -# make the reset asserted to -# allow RC circuit to discharge for: [ms] -adapter_nsrst_assert_width 100 -jtag_ntrst_assert_width 100 -# don't talk to JTAG after reset for: [ms] -adapter_nsrst_delay 100 -jtag_ntrst_delay 100 -reset_config trst_and_srst separate - - - - -# issue telnet: reset init -# issue gdb: monitor reset init -$_TARGETNAME configure -event reset-init { - adapter_khz 100 - # this will setup Telo board - setupTelo - #turn up the JTAG speed - adapter_khz 3000 - echo "JTAG speek now 3MHz" - echo "type helpC100 to get help on C100" -} - -$_TARGETNAME configure -event reset-deassert-post { - # Force target into ARM state. -# soft_reset_halt ;# not implemented on ARM11 - echo "Detected SRSRT asserted on C100.CPU" - -} - -$_TARGETNAME configure -event reset-assert-post { - echo "Assering reset" - #sleep 10 -} - -proc power_restore {} { echo "Sensed power restore. No action." } -proc srst_deasserted {} { echo "Sensed nSRST deasserted. No action." } - - -# boots from NOR on CS0: 8 MBytes CFI flash, 16-bit bus -# it's really 16MB but the upper 8mb is controller via gpio -# openocd does not support 'complex reads/writes' to NOR -set _FLASHNAME $_CHIPNAME.flash -flash bank $_FLASHNAME cfi 0x20000000 0x01000000 2 2 $_TARGETNAME - -# writing data to memory does not work without this -arm11 memwrite burst disable diff --git a/tcl/board/ti-cc3200-launchxl.cfg b/tcl/board/ti-cc3200-launchxl.cfg deleted file mode 100644 index fd80c5310..000000000 --- a/tcl/board/ti-cc3200-launchxl.cfg +++ /dev/null @@ -1,18 +0,0 @@ -# -# TI SimpleLink Wi-Fi CC3200 LaunchPad -# -# http://www.ti.com/tool/cc3200-launchxl -# - -source [find interface/ftdi/ti-icdi.cfg] - -if { [info exists TRANSPORT] } { - transport select $TRANSPORT -} else { - transport select jtag -} - -set WORKAREASIZE 0x40000 -source [find target/cc32xx.cfg] - -reset_config srst_only diff --git a/tcl/board/ti_am335xevm.cfg b/tcl/board/ti_am335xevm.cfg deleted file mode 100644 index 3e2ee3ff9..000000000 --- a/tcl/board/ti_am335xevm.cfg +++ /dev/null @@ -1,10 +0,0 @@ -# -# TI AM335x Evaluation Module -# -# For more information please see http://www.ti.com/tool/tmdxevm3358 -# -jtag_rclk 6000 - -source [find target/am335x.cfg] - -reset_config trst_and_srst diff --git a/tcl/board/ti_am437x_idk.cfg b/tcl/board/ti_am437x_idk.cfg deleted file mode 100644 index 65e2094e8..000000000 --- a/tcl/board/ti_am437x_idk.cfg +++ /dev/null @@ -1,12 +0,0 @@ -# Texas Instruments AM437x Industrial Development Kit - -# The JTAG interface is built directly on the board. -source [find interface/ftdi/xds100v2.cfg] - -transport select jtag -adapter_khz 30000 - -source [find target/am437x.cfg] -$_TARGETNAME configure -event reset-init { init_platform 0x61a11b32 } - -reset_config trst_and_srst diff --git a/tcl/board/ti_am43xx_evm.cfg b/tcl/board/ti_am43xx_evm.cfg deleted file mode 100644 index d536314ba..000000000 --- a/tcl/board/ti_am43xx_evm.cfg +++ /dev/null @@ -1,7 +0,0 @@ -# Works on both AM437x GP EVM and AM438x ePOS EVM -transport select jtag -adapter_khz 16000 - -source [find target/am437x.cfg] - -reset_config trst_and_srst diff --git a/tcl/board/ti_beagleboard.cfg b/tcl/board/ti_beagleboard.cfg deleted file mode 100644 index 9b3b8b016..000000000 --- a/tcl/board/ti_beagleboard.cfg +++ /dev/null @@ -1,12 +0,0 @@ -# OMAP3 BeagleBoard -# http://beagleboard.org - -# Fall back to 6MHz if RTCK is not supported -jtag_rclk 6000 - -source [find target/omap3530.cfg] - -# TI-14 JTAG connector -reset_config trst_only - -# Later run: omap3_dbginit diff --git a/tcl/board/ti_beagleboard_xm.cfg b/tcl/board/ti_beagleboard_xm.cfg deleted file mode 100644 index e4e93e333..000000000 --- a/tcl/board/ti_beagleboard_xm.cfg +++ /dev/null @@ -1,12 +0,0 @@ -# BeagleBoard xM (DM37x) -# http://beagleboard.org - -set CHIPTYPE "dm37x" -source [find target/amdm37x.cfg] - -# The TI-14 JTAG connector does not have srst. CPU reset is handled in -# hardware. -reset_config trst_only - -# "amdm37x_dbginit dm37x.cpu" needs to be run after init. - diff --git a/tcl/board/ti_beaglebone.cfg b/tcl/board/ti_beaglebone.cfg deleted file mode 100644 index 5d31d1d97..000000000 --- a/tcl/board/ti_beaglebone.cfg +++ /dev/null @@ -1,13 +0,0 @@ -# AM335x Beaglebone -# http://beagleboard.org/bone - -# The JTAG interface is built directly on the board. -source [find interface/ftdi/xds100v2.cfg] - -adapter_khz 16000 - -source [find target/am335x.cfg] - -reset_config trst_and_srst - - diff --git a/tcl/board/ti_blaze.cfg b/tcl/board/ti_blaze.cfg deleted file mode 100644 index c9bbe25c0..000000000 --- a/tcl/board/ti_blaze.cfg +++ /dev/null @@ -1,6 +0,0 @@ -jtag_rclk 6000 - -source [find target/omap4430.cfg] - -reset_config trst_and_srst - diff --git a/tcl/board/ti_pandaboard.cfg b/tcl/board/ti_pandaboard.cfg deleted file mode 100644 index bd2cd3703..000000000 --- a/tcl/board/ti_pandaboard.cfg +++ /dev/null @@ -1,6 +0,0 @@ -jtag_rclk 6000 - -source [find target/omap4430.cfg] - -reset_config trst_only - diff --git a/tcl/board/ti_pandaboard_es.cfg b/tcl/board/ti_pandaboard_es.cfg deleted file mode 100644 index 2abd7e97a..000000000 --- a/tcl/board/ti_pandaboard_es.cfg +++ /dev/null @@ -1,6 +0,0 @@ -jtag_rclk 6000 - -source [find target/omap4460.cfg] - -reset_config trst_only - diff --git a/tcl/board/ti_tmdx570ls20susb.cfg b/tcl/board/ti_tmdx570ls20susb.cfg deleted file mode 100644 index 87cab2690..000000000 --- a/tcl/board/ti_tmdx570ls20susb.cfg +++ /dev/null @@ -1,16 +0,0 @@ -# TMS570 Microcontroller USB Kit -# http://www.ti.com/tool/TMDX570LS20SUSB - -# Board uses a FT2232H to emulate an XDS100v2 JTAG debugger -# TODO: board also supports an SCI UART on the 2232's B Bus -source [find interface/ftdi/xds100v2.cfg] - -# Processor is TMS570LS20216 -source [find target/ti_tms570ls20xxx.cfg] - -reset_config trst_only - -# xds100v2 config says add this to the end -init -ftdi_set_signal PWR_RST 1 -jtag arp_init diff --git a/tcl/board/ti_tmdx570ls31usb.cfg b/tcl/board/ti_tmdx570ls31usb.cfg deleted file mode 100644 index 550244429..000000000 --- a/tcl/board/ti_tmdx570ls31usb.cfg +++ /dev/null @@ -1,6 +0,0 @@ -adapter_khz 1500 - -source [find interface/ftdi/xds100v2.cfg] -source [find target/ti_tms570.cfg] - -reset_config trst_only diff --git a/tcl/board/topas910.cfg b/tcl/board/topas910.cfg deleted file mode 100644 index 90c18c484..000000000 --- a/tcl/board/topas910.cfg +++ /dev/null @@ -1,119 +0,0 @@ -###################################### -# Target: Toshiba TOPAS910 -- TMPA910 Starterkit -# -###################################### - -# We add to the minimal configuration. -source [find target/tmpa910.cfg] - -###################### -# Target configuration -###################### - -#$_TARGETNAME configure -event gdb-attach { reset init } -$_TARGETNAME configure -event reset-init { topas910_init } - -proc topas910_init { } { -# Init PLL -# my settings - mww 0xf005000c 0x00000007 - mww 0xf0050010 0x00000065 - mww 0xf005000c 0x000000a7 - sleep 10 - mdw 0xf0050008 - mww 0xf0050008 0x00000002 - mww 0xf0050004 0x00000000 -# NEW: set CLKCR5 - mww 0xf0050054 0x00000040 -# - sleep 10 -# Init SDRAM -# _PMCDRV = 0x00000071; -# // -# // Initialize SDRAM timing paramater -# // -# _DMC_CAS_LATENCY = 0x00000006; -# _DMC_T_DQSS = 0x00000000; -# _DMC_T_MRD = 0x00000002; -# _DMC_T_RAS = 0x00000007; -# -# _DMC_T_RC = 0x0000000A; -# _DMC_T_RCD = 0x00000013; -# -# _DMC_T_RFC = 0x0000010A; -# -# _DMC_T_RP = 0x00000013; -# _DMC_T_RRD = 0x00000002; -# _DMC_T_WR = 0x00000002; -# _DMC_T_WTR = 0x00000001; -# _DMC_T_XP = 0x0000000A; -# _DMC_T_XSR = 0x0000000B; -# _DMC_T_ESR = 0x00000014; -# -# // -# // Configure SDRAM type parameter -# _DMC_MEMORY_CFG = 0x00008011; -# _DMC_USER_CONFIG = 0x00000011; -# // 32 bit memory interface -# -# -# _DMC_REFRESH_PRD = 0x00000A60; -# _DMC_CHIP_0_CFG = 0x000140FC; -# -# _DMC_DIRECT_CMD = 0x000C0000; -# _DMC_DIRECT_CMD = 0x00000000; -# -# _DMC_DIRECT_CMD = 0x00040000; -# _DMC_DIRECT_CMD = 0x00040000; -# _DMC_DIRECT_CMD = 0x00080031; -# // -# // Finally start SDRAM -# // -# _DMC_MEMC_CMD = MEMC_CMD_GO; -# */ - - mww 0xf0020260 0x00000071 - mww 0xf4300014 0x00000006 - mww 0xf4300018 0x00000000 - mww 0xf430001C 0x00000002 - mww 0xf4300020 0x00000007 - mww 0xf4300024 0x0000000A - mww 0xf4300028 0x00000013 - mww 0xf430002C 0x0000010A - mww 0xf4300030 0x00000013 - mww 0xf4300034 0x00000002 - mww 0xf4300038 0x00000002 - mww 0xf430003C 0x00000001 - mww 0xf4300040 0x0000000A - mww 0xf4300044 0x0000000B - mww 0xf4300048 0x00000014 - mww 0xf430000C 0x00008011 - mww 0xf4300304 0x00000011 - mww 0xf4300010 0x00000A60 - mww 0xf4300200 0x000140FC - mww 0xf4300008 0x000C0000 - mww 0xf4300008 0x00000000 - mww 0xf4300008 0x00040000 - mww 0xf4300008 0x00040000 - mww 0xf4300008 0x00080031 - mww 0xf4300004 0x00000000 - - sleep 10 -# adapter_khz NNNN - -# remap off in case of IROM boot - mww 0xf0000004 0x00000001 - -} - -# comment the following out if usinf J-Link, it soes not support DCC -arm7_9 dcc_downloads enable ;# Enable faster DCC downloads - - -##################### -# Flash configuration -##################### - -#flash bank cfi -set _FLASHNAME $_CHIPNAME.flash -flash bank $_FLASHNAME cfi 0x20000000 0x2000000 2 2 $_TARGETNAME diff --git a/tcl/board/topasa900.cfg b/tcl/board/topasa900.cfg deleted file mode 100644 index 2a388d511..000000000 --- a/tcl/board/topasa900.cfg +++ /dev/null @@ -1,126 +0,0 @@ -# Thanks to Pieter Conradie for this script! -# Target: Toshiba TOPAS900 -- TMPA900 Starterkit -###################################### - -# We add to the minimal configuration. -source [find target/tmpa900.cfg] - -###################### -# Target configuration -###################### - -#$_TARGETNAME configure -event gdb-attach { reset init } -$_TARGETNAME configure -event reset-init { topasa900_init } - -proc topasa900_init { } { -# Init PLL -# my settings - mww 0xf005000c 0x00000007 - mww 0xf0050010 0x00000065 - mww 0xf005000c 0x000000a7 - sleep 10 - mdw 0xf0050008 - mww 0xf0050008 0x00000002 - mww 0xf0050004 0x00000000 -# NEW: set CLKCR5 - mww 0xf0050054 0x00000040 -# -# bplan settings -# mww 0xf0050004 0x00000000 -# mww 0xf005000c 0x000000a7 -# sleep 10 -# mdw 0xf0050008 -# mww 0xf0050008 0x00000002 -# mww 0xf0050010 0x00000065 -# mww 0xf0050054 0x00000040 - sleep 10 -# Init SDRAM -# _PMCDRV = 0x00000071; -# // -# // Initialize SDRAM timing paramater -# // -# _DMC_CAS_LATENCY = 0x00000006; -# _DMC_T_DQSS = 0x00000000; -# _DMC_T_MRD = 0x00000002; -# _DMC_T_RAS = 0x00000007; -# -# _DMC_T_RC = 0x0000000A; -# _DMC_T_RCD = 0x00000013; -# -# _DMC_T_RFC = 0x0000010A; -# -# _DMC_T_RP = 0x00000013; -# _DMC_T_RRD = 0x00000002; -# _DMC_T_WR = 0x00000002; -# _DMC_T_WTR = 0x00000001; -# _DMC_T_XP = 0x0000000A; -# _DMC_T_XSR = 0x0000000B; -# _DMC_T_ESR = 0x00000014; -# -# // -# // Configure SDRAM type parameter -# _DMC_MEMORY_CFG = 0x00008011; -# _DMC_USER_CONFIG = 0x00000011; // 32 bit memory interface -# -# -# _DMC_REFRESH_PRD = 0x00000A60; -# _DMC_CHIP_0_CFG = 0x000140FC; -# -# _DMC_DIRECT_CMD = 0x000C0000; -# _DMC_DIRECT_CMD = 0x00000000; -# -# _DMC_DIRECT_CMD = 0x00040000; -# _DMC_DIRECT_CMD = 0x00040000; -# _DMC_DIRECT_CMD = 0x00080031; -# // -# // Finally start SDRAM -# // -# _DMC_MEMC_CMD = MEMC_CMD_GO; -# */ - - mww 0xf0020260 0x00000071 - mww 0xf4300014 0x00000006 - mww 0xf4300018 0x00000000 - mww 0xf430001C 0x00000002 - mww 0xf4300020 0x00000007 - mww 0xf4300024 0x0000000A - mww 0xf4300028 0x00000013 - mww 0xf430002C 0x0000010A - mww 0xf4300030 0x00000013 - mww 0xf4300034 0x00000002 - mww 0xf4300038 0x00000002 - mww 0xf430003C 0x00000001 - mww 0xf4300040 0x0000000A - mww 0xf4300044 0x0000000B - mww 0xf4300048 0x00000014 - mww 0xf430000C 0x00008011 - mww 0xf4300304 0x00000011 - mww 0xf4300010 0x00000A60 - mww 0xf4300200 0x000140FC - mww 0xf4300008 0x000C0000 - mww 0xf4300008 0x00000000 - mww 0xf4300008 0x00040000 - mww 0xf4300008 0x00040000 - mww 0xf4300008 0x00080031 - mww 0xf4300004 0x00000000 - - sleep 10 -# adapter_khz NNNN - -# remap off in case of IROM boot - mww 0xf0000004 0x00000001 - -} - -# comment the following out if usinf J-Link, it soes not support DCC -arm7_9 dcc_downloads enable ;# Enable faster DCC downloads - - -##################### -# Flash configuration -##################### - -#flash bank cfi -set _FLASHNAME $_CHIPNAME.flash -flash bank $_FLASHNAME cfi 0x20000000 0x1000000 2 2 $_TARGETNAME - diff --git a/tcl/board/tp-link_tl-mr3020.cfg b/tcl/board/tp-link_tl-mr3020.cfg deleted file mode 100644 index b7d8d5b61..000000000 --- a/tcl/board/tp-link_tl-mr3020.cfg +++ /dev/null @@ -1,44 +0,0 @@ -source [find target/atheros_ar9331.cfg] - -proc ar9331_25mhz_pll_init {} { - mww 0xb8050008 0x00018004 ;# bypass PLL; AHB_POST_DIV - ratio 4 - mww 0xb8050004 0x00000352 ;# 34000(ns)/40ns(25MHz) = 0x352 (850) - mww 0xb8050000 0x40818000 ;# Power down control for CPU PLL - ;# OUTDIV | REFDIV | DIV_INT - mww 0xb8050010 0x001003e8 ;# CPU PLL Dither FRAC Register - ;# (disabled?) - mww 0xb8050000 0x00818000 ;# Power on | OUTDIV | REFDIV | DIV_INT - mww 0xb8050008 0x00008000 ;# remove bypass; - ;# AHB_POST_DIV - ratio 2 -} - -proc ar9331_ddr1_init {} { - mww 0xb8000000 0x7fbc8cd0 ;# DDR_CONFIG - lots of DRAM confs - mww 0xb8000004 0x9dd0e6a8 ;# DDR_CONFIG2 - more DRAM confs - - mww 0xb8000010 0x8 ;# Forces a PRECHARGE ALL cycle - mww 0xb8000008 0x133 ;# mode reg: 0x133 - default - mww 0xb8000010 0x1 ;# Forces an MRS update cycl - mww 0xb800000c 0x2 ;# Extended mode register value. - ;# default 0x2 - Reset to weak driver, DLL on - mww 0xb8000010 0x2 ;# Forces an EMRS update cycle - mww 0xb8000010 0x8 ;# Forces a PRECHARGE ALL cycle - mww 0xb8000008 0x33 ;# mode reg: remove some bit? - mww 0xb8000010 0x1 ;# Forces an MRS update cycl - mww 0xb8000014 0x4186 ;# enable refres: bit(14) - set refresh rate - mww 0xb800001c 0x8 ;# This register is used along with DQ Lane 0, - ;# DQ[7:0], DQS_0 - mww 0xb8000020 0x9 ;# This register is used along with DQ Lane 1, - ;# DQ[15:8], DQS_1. - mww 0xb8000018 0xff ;# DDR read and capture bit mask. - ;# Each bit represents a cycle of valid data. -} - -$_TARGETNAME configure -event reset-init { - ar9331_25mhz_pll_init - sleep 1 - ar9331_ddr1_init -} - -set ram_boot_address 0xa0000000 -$_TARGETNAME configure -work-area-phys 0xa1FFE000 -work-area-size 0x1000 diff --git a/tcl/board/twr-k60f120m.cfg b/tcl/board/twr-k60f120m.cfg deleted file mode 100644 index e96d04526..000000000 --- a/tcl/board/twr-k60f120m.cfg +++ /dev/null @@ -1,17 +0,0 @@ -# -# Freescale TWRK60F120M development board -# - -source [find target/k60.cfg] - -$_TARGETNAME configure -event reset-init { - puts "-event reset-init occured" -} - -# -# Definitions for the additional 'program flash' banks -# (instructions and/or data) -# -flash bank pflash.1 kinetis 0x00040000 0x40000 0 4 $_TARGETNAME -flash bank pflash.2 kinetis 0x00080000 0x40000 0 4 $_TARGETNAME -flash bank pflash.3 kinetis 0x000c0000 0x40000 0 4 $_TARGETNAME diff --git a/tcl/board/twr-k60n512.cfg b/tcl/board/twr-k60n512.cfg deleted file mode 100644 index d2312cf14..000000000 --- a/tcl/board/twr-k60n512.cfg +++ /dev/null @@ -1,15 +0,0 @@ -# -# Freescale TWRK60N512 development board -# - -source [find target/k60.cfg] - -$_TARGETNAME configure -event reset-init { - puts "-event reset-init occured" -} - -# -# Definitions for the additional 'program flash' bank -# (instructions and/or data) -# -flash bank pflash.1 kinetis 0x00040000 0x40000 0 4 $_TARGETNAME diff --git a/tcl/board/tx25_stk5.cfg b/tcl/board/tx25_stk5.cfg deleted file mode 100644 index 846bf58f5..000000000 --- a/tcl/board/tx25_stk5.cfg +++ /dev/null @@ -1,158 +0,0 @@ -# ------------------------------------------------------------------------- -# KaRo TX25 CPU Module on a StarterkitV base board -# http://www.karo-electronics.com/tx25.html -# ------------------------------------------------------------------------- - - -source [find tcl/target/imx25.cfg] - - #------------------------------------------------------------------------- - # Declare Nand - #------------------------------------------------------------------------- - - nand device K9F1G08UOC mxc imx25.cpu mx25 hwecc biswap - - -$_TARGETNAME configure -event gdb-attach { reset init } -$_TARGETNAME configure -event reset-init { tx25_init } - - -proc tx25_init { } { - - #------------------------------------------------------------------------- - # AIPS setup - Only setup MPROTx registers. The PACR default values are good. - # Set all MPROTx to be non-bufferable, trusted for R/W, - # not forced to user-mode. - #------------------------------------------------------------------------- - - mww 0x43f00000 0x77777777 - mww 0x43f00004 0x77777777 - mww 0x53f00000 0x77777777 - mww 0x53f00004 0x77777777 - - sleep 100 - - #------------------------------------------------------------------------- - # MAX (Multi-Layer AHB Crossbar Switch) setup - # MPR - priority for MX25 is (SDHC2/SDMA)>USBOTG>RTIC>IAHB>DAHB - #------------------------------------------------------------------------- - - mww 0x43f04000 0x00043210 - mww 0x43f04100 0x00043210 - mww 0x43f04200 0x00043210 - mww 0x43f04300 0x00043210 - mww 0x43f04400 0x00043210 - - # SGPCR - always park on last master - mww 0x43f04010 0x10 - mww 0x43f04110 0x10 - mww 0x43f04210 0x10 - mww 0x43f04310 0x10 - mww 0x43f04410 0x10 - - # MGPCR - restore default values - mww 0x43f04800 0x0 - mww 0x43f04900 0x0 - mww 0x43f04a00 0x0 - mww 0x43f04b00 0x0 - mww 0x43f04c00 0x0 - - # Configure M3IF registers - # M3IF Control Register (M3IFCTL) for MX25 - # MRRP[0] = LCDC on priority list (1 << 0) = 0x00000001 - # MRRP[1] = MAX1 not on priority list (0 << 1) = 0x00000000 - # MRRP[2] = MAX0 not on priority list (0 << 2) = 0x00000000 - # MRRP[3] = USB HOST not on priority list (0 << 3) = 0x00000000 - # MRRP[4] = SDMA not on priority list (0 << 4) = 0x00000000 - # MRRP[5] = SD/ATA/FEC not on priority list (0 << 5) = 0x00000000 - # MRRP[6] = SCMFBC not on priority list (0 << 6) = 0x00000000 - # MRRP[7] = CSI not on priority list (0 << 7) = 0x00000000 - # ---------- - # 0x00000001 - mww 0xb8003000 0x00000001 - - #------------------------------------------------------------------------- - # configure ARM CLK - #------------------------------------------------------------------------- - - # Set the Clock CTL (HRM p. 355) - mww 0x53F80008 0x20034000 - - # Setup Clock Gating CTL 0-2 (HRM p. 357) - mww 0x53F8000C 0x1fffffff - mww 0x53F80010 0xffffffff - mww 0x53F80014 0x000fdfff - - #------------------------------------------------------------------------- - # SDRAM initialization - #------------------------------------------------------------------------- - - # set to 3.3v SDRAM - mww 0x43FAC454 0x00000800 - - # reset (set up ESDMISC) - mww 0xB8001010 0x00000002 - - # Setup for SDRAM Bank 0 - #------------------------------------------------------------------------- - - # Write ESDCFG0 - mww 0xB8001004 0x00095728 - - # CTL SMode = Precharge command - mww 0xB8001000 0x92116480 - mww 0x80000400 0x00000000 - - # CTL SMode = Auto Refresh command - mww 0xB8001000 0xA2116480 - mww 0x80000000 0x0 - mww 0x80000000 0x0 - mww 0x80000000 0x0 - mww 0x80000000 0x0 - mww 0x80000000 0x0 - mww 0x80000000 0x0 - mww 0x80000000 0x0 - mww 0x80000000 0x0 - - # CTL SMode = Load Mode Register command - mww 0xB8001000 0xB2116480 - mwb 0x80000033 0x00 - - # CTL SMode = normal - mww 0xB8001000 0x82116480 - - # Setup for SDRAM Bank 1 - #------------------------------------------------------------------------- - - # Write ESDCFG1 - mww 0xB800100C 0x00095728 - - # CTL SMode = Precharge command - mww 0xB8001008 0x92116480 - mww 0x90000400 0x00000000 - - # CTL SMode = Auto Refresh command - mww 0xB8001008 0xA2116480 - mww 0x90000000 0x00000000 - mww 0x90000000 0x00000000 - mww 0x90000000 0x00000000 - mww 0x90000000 0x00000000 - mww 0x90000000 0x00000000 - mww 0x90000000 0x00000000 - mww 0x90000000 0x00000000 - mww 0x90000000 0x00000000 - - # CTL SMode = Load Mode Register command - mww 0xB8001008 0xB2116480 - mwb 0x90000033 0x00 - - # CTL SMode = normal - mww 0xB8001008 0x82116480 - - # GPIO configuration - #------------------------------------------------------------------------- - - mww 0x43FAC02C 0x00000015 - mww 0x53FD0000 0x01000000 - mww 0x53FD0004 0x00000080 -} diff --git a/tcl/board/tx27_stk5.cfg b/tcl/board/tx27_stk5.cfg deleted file mode 100644 index bb933e149..000000000 --- a/tcl/board/tx27_stk5.cfg +++ /dev/null @@ -1,64 +0,0 @@ -# KaRo TX27 CPU Module on a StarterkitV base board -# -# http://www.karo-electronics.com/tx27.html -# -source [find target/imx27.cfg] - -$_TARGETNAME configure -event gdb-attach { reset init } -$_TARGETNAME configure -event reset-init { tx27_init } - -proc tx27_init { } { - # This setup puts RAM at 0xA0000000 - # init_aipi (AIPI1.PSR0, AIPI2.PSR0, AIPI1.PSR1 and AIPI2.PSR1) - mww 0x10000000 0x20040304 - mww 0x10020000 0x00000000 - mww 0x10000004 0xDFFBFCFB - mww 0x10020004 0xFFFFFFFF - - sleep 100 - - #init_max ( PORT0.MPR, #PORT0.AMPR, #PORT1.MPR, #PORT1.AMPR, #PORT2.MPR, #PORT2.AMPR) - mww 0x1003F000 0x00302145 - mww 0x1003F004 0x00302145 - mww 0x1003F100 0x00302145 - mww 0x1003F104 0x00302145 - mww 0x1003F200 0x00302145 - mww 0x1003F204 0x00302145 - - #init_drive_strength (#DSCR3, #DSCR5, #DSCR6, #DSCR7, #DSCR8 ) - mww 0x10027828 0x55555555 - mww 0x10027830 0x55555555 - mww 0x10027834 0x55555555 - mww 0x10027838 0x00005005 - mww 0x1002783C 0x15555555 - - #init_sdram_speed - #mww 0xD8001010 0x00000004 - mww 0xD8001010 0x00000024 - - mww 0xD8001004 0x00395729 - - mww 0xD8001000 0x92120000 - mww 0xA0000400 0x0 - - mww 0xD8001000 0xA2120000 - mww 0xA0000000 0x0 - mww 0xA0000000 0x0 - - mww 0xD8001000 0xB2120000 - mdb 0xA0000000 - mdb 0xA0000033 - - mww 0xD8001000 0x82126485 - - # ============================================= - # Sync mode (AHB Clk = 133MHz ; BCLK = 44.3MHz) - # ============================================= - mww 0xD8002000 0x23524E80 - mww 0xD8002004 0x10000D03 - mww 0xD8002008 0x00720900 - - nand probe 0 -} - -nand device tx27.nand mxc $_TARGETNAME mx27 hwecc biswap diff --git a/tcl/board/unknown_at91sam9260.cfg b/tcl/board/unknown_at91sam9260.cfg deleted file mode 100644 index de49a69f5..000000000 --- a/tcl/board/unknown_at91sam9260.cfg +++ /dev/null @@ -1,97 +0,0 @@ -# Thanks to Pieter Conradie for this script! -# -# Unknown vendor board contains: -# -# Atmel AT91SAM9260 : PLLA = 192.512MHz, MCK = 96.256 MHz -# OSCSEL configured for internal RC oscillator (22 to 42 kHz) -# -# 16-bit NOR FLASH : Intel JS28F128P30T85 128MBit -# 32-bit SDRAM : 2 x Samsung K4S561632H-UC75, 4M x 16Bit x 4 Banks -################################################################## - -# We add to the minimal configuration. -source [find target/at91sam9260.cfg] - -$_TARGETNAME configure -event reset-start { - # At reset CPU runs at 22 to 42 kHz. - # JTAG Frequency must be 6 times slower. - jtag_rclk 3 - halt - # RSTC_MR : enable user reset, MMU may be enabled... use physical address - mww phys 0xfffffd08 0xa5000501 -} - - -$_TARGETNAME configure -event reset-init { - mww 0xfffffd44 0x00008000 ;# WDT_MR : disable watchdog - - mww 0xfffffc20 0x00004001 ;# CKGR_MOR : enable the main oscillator - sleep 20 ;# wait 20 ms - mww 0xfffffc30 0x00000001 ;# PMC_MCKR : switch to main oscillator - sleep 10 ;# wait 10 ms - mww 0xfffffc28 0x205dbf09 ;# CKGR_PLLAR: Set PLLA Register for 192.512MHz - sleep 20 ;# wait 20 ms - mww 0xfffffc30 0x00000101 ;# PMC_MCKR : Select prescaler (divide by 2) - sleep 10 ;# wait 10 ms - mww 0xfffffc30 0x00000102 ;# PMC_MCKR : Clock from PLLA is selected (96.256 MHz) - sleep 10 ;# wait 10 ms - - # Increase JTAG Speed to 6 MHz if RCLK is not supported - jtag_rclk 6000 - - arm7_9 dcc_downloads enable ;# Enable faster DCC downloads - - mww 0xffffec00 0x01020102 ;# SMC_SETUP0 : Setup SMC for Intel NOR Flash JS28F128P30T85 128MBit - mww 0xffffec04 0x09070806 ;# SMC_PULSE0 - mww 0xffffec08 0x000d000b ;# SMC_CYCLE0 - mww 0xffffec0c 0x00001003 ;# SMC_MODE0 - - flash probe 0 ;# Identify flash bank 0 - - mww 0xfffff870 0xffff0000 ;# PIO_ASR : Select peripheral function for D15..D31 - mww 0xfffff804 0xffff0000 ;# PIO_PDR : Disable PIO function for D15..D31 - mww 0xfffff860 0xffff0000 ;# PIO_PUDR : Disable D15..D31 pull-ups - - mww 0xffffef1c 0x00010102 ;# EBI_CSA : Assign EBI Chip Select 1 to SDRAM - # VDDIOMSEL set for +3V3 memory - # Disable D0..D15 pull-ups - - mww 0xffffea08 0x85227259 ;# SDRAMC_CR : Configure SDRAM (2 x Samsung K4S561632H-UC75 : 4M x 16Bit x 4 Banks) - - mww 0xffffea00 0x1 ;# SDRAMC_MR : issue a NOP command - mww 0x20000000 0 - mww 0xffffea00 0x2 ;# SDRAMC_MR : issue an 'All Banks Precharge' command - mww 0x20000000 0 - mww 0xffffea00 0x4 ;# SDRAMC_MR : issue 8 x 'Auto-Refresh' Command - mww 0x20000000 0 - mww 0xffffea00 0x4 - mww 0x20000000 0 - mww 0xffffea00 0x4 - mww 0x20000000 0 - mww 0xffffea00 0x4 - mww 0x20000000 0 - mww 0xffffea00 0x4 - mww 0x20000000 0 - mww 0xffffea00 0x4 - mww 0x20000000 0 - mww 0xffffea00 0x4 - mww 0x20000000 0 - mww 0xffffea00 0x4 - mww 0x20000000 0 - mww 0xffffea00 0x3 ;# SDRAMC_MR : issue a 'Load Mode Register' command - mww 0x20000000 0 - mww 0xffffea00 0x0 ;# SDRAMC_MR : normal mode - mww 0x20000000 0 - mww 0xffffea04 0x2a2 ;# SDRAMC_TR : Set refresh timer count to 7us -} - - -##################### -# Flash configuration -##################### - -#flash bank cfi -set _FLASHNAME $_CHIPNAME.flash -flash bank $_FLASHNAME cfi 0x10000000 0x01000000 2 2 $_TARGETNAME - - diff --git a/tcl/board/uptech_2410.cfg b/tcl/board/uptech_2410.cfg deleted file mode 100644 index 950f2a7c1..000000000 --- a/tcl/board/uptech_2410.cfg +++ /dev/null @@ -1,65 +0,0 @@ -# Target Configuration for the Uptech 2410 board. -# This configuration hould also work on smdk2410, but I havn't tested it yet. -# Author: xionglingfeng@Gmail.com - -source [find target/samsung_s3c2410.cfg] - -$_TARGETNAME configure -event reset-init { uptech2410_init } -$_TARGETNAME configure -event gdb-attach { reset init } - -proc init_pll_sdram { } { - #echo "---------- Initializing PLL and SDRAM ---------" - #watchdog timer disable - mww phys 0x53000000 0x00000000 - - #disable all interrupts - mww phys 0x4a000008 0xffffffff - - #disable all sub-interrupts - mww phys 0x4a00001c 0x000007ff - - #clear all source pending bits - mww phys 0x4a000000 0xffffffff - - #clear all sub-source pending bits - mww phys 0x4a000018 0x000007ff - - #clear interrupt pending bit - mww phys 0x4a000010 0xffffffff - - #PLL locktime counter - mww phys 0x4c000000 0x00ffffff - - #Fin=12MHz Fout=202.8MHz - #mww phys 0x4c000004 0x000a1031 - - #FCLK:HCLK:PCLK = 1:2:4 - mww phys 0x4c000014 0x00000003 - - - mww phys 0x48000000 0x11111110 - mww phys 0x48000004 0x00007FFC - mww phys 0x48000008 0x00007FFC - mww phys 0x4800000c 0x00000700 - mww phys 0x48000010 0x00000700 - mww phys 0x48000014 0x00002E50 - mww phys 0x48000018 0x00002E50 - mww phys 0x4800001c 0x00018005 - mww phys 0x48000020 0x00018005 - mww phys 0x48000024 0x008c04e9 - mww phys 0x48000028 0x000000b2 - mww phys 0x4800002c 0x00000030 - mww phys 0x48000030 0x00000030 -} - -proc uptech2410_init { } { - init_pll_sdram - #echo "---------- Probing Nand flash ----------" - nand probe 0 - #echo "---------- Enable some functions ----------" -} - -set _NANDNAME $_CHIPNAME.nand -nand device $_NANDNAME s3c2410 $_TARGETNAME - - diff --git a/tcl/board/verdex.cfg b/tcl/board/verdex.cfg deleted file mode 100644 index 6da987528..000000000 --- a/tcl/board/verdex.cfg +++ /dev/null @@ -1,17 +0,0 @@ -# Config for Gumstix Verdex XM4 and XL6P (PXA270) - -set CHIPNAME verdex -source [find target/pxa270.cfg] - -# The board supports separate reset lines -# Override this in the interface config for parallel dongles -reset_config trst_and_srst separate - -# XM4 = 400MHz, XL6P = 600MHz...let's run at 0.1*400MHz=40MHz -adapter_khz 40000 - -# flash bank -# XL6P has 32 MB flash -flash bank $_CHIPNAME.flash0 cfi 0x00000000 0x02000000 2 2 $_TARGETNAME -# XM4 has 16 MB flash -#flash bank $_CHIPNAME.flash0 cfi 0x00000000 0x01000000 2 2 $_TARGETNAME diff --git a/tcl/board/voipac.cfg b/tcl/board/voipac.cfg deleted file mode 100644 index c59277ec4..000000000 --- a/tcl/board/voipac.cfg +++ /dev/null @@ -1,12 +0,0 @@ -# Config for Voipac PXA270/PXA270M module. - -set CHIPNAME voipac -source [find target/pxa270.cfg] - -# The board supports separate reset lines -# Override this in the interface config for parallel dongles -reset_config trst_and_srst separate - -# flash bank -flash bank $_CHIPNAME.flash0 cfi 0x00000000 0x2000000 2 2 $_TARGETNAME -flash bank $_CHIPNAME.flash1 cfi 0x02000000 0x2000000 2 2 $_TARGETNAME diff --git a/tcl/board/voltcraft_dso-3062c.cfg b/tcl/board/voltcraft_dso-3062c.cfg deleted file mode 100644 index 01e37e9a4..000000000 --- a/tcl/board/voltcraft_dso-3062c.cfg +++ /dev/null @@ -1,31 +0,0 @@ -# -# Voltcraft DSO-3062C digital oscilloscope (uses a Samsung S3C2440) -# -# http://www.eevblog.com/forum/general-chat/hantek-tekway-dso-hack-get-200mhz-bw-for-free/ -# http://www.mikrocontroller.net/topic/249628 -# http://elinux.org/Das_Oszi -# http://randomprojects.org/wiki/Voltcraft_DSO-3062C -# - -# Enable this if your JTAG adapter supports multiple transports (JTAG or SWD). -# Otherwise comment it out, as it will cause an OpenOCD error. -### transport select jtag - -source [find target/samsung_s3c2440.cfg] - -adapter_khz 16000 - -# Samsung K9F1208U0C NAND flash chip (64MiB, 3.3V, 8-bit) -nand device $_CHIPNAME.nand s3c2440 $_TARGETNAME - -# arm7_9 fast_memory_access enable -# arm7_9 dcc_downloads enable - -init -reset -halt -scan_chain -targets -nand probe 0 -nand list - diff --git a/tcl/board/x300t.cfg b/tcl/board/x300t.cfg deleted file mode 100644 index 9d9a320fb..000000000 --- a/tcl/board/x300t.cfg +++ /dev/null @@ -1,31 +0,0 @@ -# This is for the T-Home X300T / X301T IPTV box, -# which are based on IPTV reference designs from Kiss/Cisco KMM-3*** -# -# It has Sigma Designs SMP8634 chip. -source [find target/smp8634.cfg] - -$_TARGETNAME configure -event reset-init { x300t_init } - -# 1MB CFI capable flash -# flash bank -set _FLASHNAME $_CHIPNAME.flash -flash bank $_FLASHNAME cfi 0xac000000 0x100000 2 2 $_TARGETNAME - -proc x300t_init { } { - # Setup SDRAM config and flash mapping - # initialize ram - mww 0xa003fffc 3 - mww 0xa003fffc 2 - mww 0xa0030000 0xE34111BA - mww 0xa003fffc 0xa4444 - mww 0xa003fffc 0 - - # remap boot vector in CPU local RAM - mww 0xa006f000 0x60000 - - # map flash to CPU address space REG_BASE_cpu_block+CPU_remap4 - mww 0x0006f010 0x48000000 - - # map flash addr to REG_BASE_cpu_block + LR_XENV_LOCATION (normally done by XOS) - mww 0x00061ff0 0x48000000 -} diff --git a/tcl/board/xmc-2go.cfg b/tcl/board/xmc-2go.cfg deleted file mode 100644 index 90dbf4366..000000000 --- a/tcl/board/xmc-2go.cfg +++ /dev/null @@ -1,15 +0,0 @@ -# -# Infineon XMC 2Go -# - -# -# Segger J-Link Lite XMC4200 on-board -# -source [find interface/jlink.cfg] -transport select swd - -set CHIPNAME xmc1100 -set WORKAREASIZE 0x4000 -source [find target/xmc1xxx.cfg] - -reset_config srst_only srst_nogate diff --git a/tcl/board/xmc1100-boot-kit.cfg b/tcl/board/xmc1100-boot-kit.cfg deleted file mode 100644 index 5e7c60734..000000000 --- a/tcl/board/xmc1100-boot-kit.cfg +++ /dev/null @@ -1,15 +0,0 @@ -# -# Infineon XMC1100 Boot Kit -# - -# -# Segger J-Link Lite XMC4200 on-board -# -source [find interface/jlink.cfg] -transport select swd - -set CHIPNAME xmc1100 -set WORKAREASIZE 0x4000 -source [find target/xmc1xxx.cfg] - -reset_config srst_only srst_nogate diff --git a/tcl/board/xmc4200-application-kit-actuator.cfg b/tcl/board/xmc4200-application-kit-actuator.cfg deleted file mode 100644 index 4e3dde8d7..000000000 --- a/tcl/board/xmc4200-application-kit-actuator.cfg +++ /dev/null @@ -1,12 +0,0 @@ -# -# Infineon XMC4200 Application Kit - Actuator -# - -# -# Segger J-Link Lite XMC4200 on-board -# -source [find interface/jlink.cfg] -transport select swd - -set CHIPNAME xmc4200 -source [find target/xmc4xxx.cfg] diff --git a/tcl/board/xmc4500-application-kit-general.cfg b/tcl/board/xmc4500-application-kit-general.cfg deleted file mode 100644 index 47c8b9982..000000000 --- a/tcl/board/xmc4500-application-kit-general.cfg +++ /dev/null @@ -1,8 +0,0 @@ -# -# Infineon XMC4500 Application Kit - General Purpose -# - -set CHIPNAME xmc4500 -source [find target/xmc4xxx.cfg] - -reset_config srst_only diff --git a/tcl/board/xmc4500-application-kit-sdram.cfg b/tcl/board/xmc4500-application-kit-sdram.cfg deleted file mode 100644 index fe44d01a9..000000000 --- a/tcl/board/xmc4500-application-kit-sdram.cfg +++ /dev/null @@ -1,10 +0,0 @@ -# -# Infineon XMC4500 Application Kit - SDRAM -# - -# -# Segger J-Link Lite XMC4200 on-board -# - -set CHIPNAME xmc4500 -source [find target/xmc4xxx.cfg] diff --git a/tcl/board/xmc4500-relax.cfg b/tcl/board/xmc4500-relax.cfg deleted file mode 100644 index 1753b24c1..000000000 --- a/tcl/board/xmc4500-relax.cfg +++ /dev/null @@ -1,14 +0,0 @@ -# -# Infineon XMC4500 Relax Kit / Relax Lite Kit -# - -# -# Segger J-Link Lite XMC4500 on-board -# -source [find interface/jlink.cfg] -transport select swd - -# There's also an unpopulated 10-pin 0.05" pinout. - -set CHIPNAME xmc4500 -source [find target/xmc4xxx.cfg] diff --git a/tcl/board/xmc4700-relax.cfg b/tcl/board/xmc4700-relax.cfg deleted file mode 100644 index 29953f634..000000000 --- a/tcl/board/xmc4700-relax.cfg +++ /dev/null @@ -1,16 +0,0 @@ -# -# Infineon XMC4700 Relax Lite Kit / Relax Kit for 5V Shields / Relax Kit -# - -# -# Segger J-Link Lite XMC4200 on-board -# -source [find interface/jlink.cfg] -transport select swd - -# There's also an unpopulated 10-pin 0.05" pinout. - -set CHIPNAME xmc4700 -source [find target/xmc4xxx.cfg] - -# Relax Kit only: N25Q032A qSPI flash diff --git a/tcl/board/xmc4800-relax.cfg b/tcl/board/xmc4800-relax.cfg deleted file mode 100644 index fa3fc8f3f..000000000 --- a/tcl/board/xmc4800-relax.cfg +++ /dev/null @@ -1,16 +0,0 @@ -# -# Infineon XMC4800 Relax EtherCAT Kit -# - -# -# Segger J-Link Lite XMC4200 on-board -# -source [find interface/jlink.cfg] -transport select swd - -# There's also an unpopulated 10-pin 0.05" pinout. - -set CHIPNAME xmc4800 -source [find target/xmc4xxx.cfg] - -# N25Q032A qSPI flash diff --git a/tcl/board/xmos_xk-xac-xa8_arm.cfg b/tcl/board/xmos_xk-xac-xa8_arm.cfg deleted file mode 100644 index 3d12afb2c..000000000 --- a/tcl/board/xmos_xk-xac-xa8_arm.cfg +++ /dev/null @@ -1,16 +0,0 @@ -# -# xCORE-XA Core Module -# -# https://www.xmos.com/support/boards?product=17940 -# - -# -# J-Link OB STM32F103 -# -source [find interface/jlink.cfg] -transport select swd - -# -# XS1-XAU8A-10 -# -source [find target/xmos_xs1-xau8a-10_arm.cfg] diff --git a/tcl/board/zy1000.cfg b/tcl/board/zy1000.cfg deleted file mode 100644 index 57deaa837..000000000 --- a/tcl/board/zy1000.cfg +++ /dev/null @@ -1,117 +0,0 @@ -#Script for ZY1000 - -#Atmel ties SRST & TRST together, at which point it makes -#no sense to use TRST, but use TMS instead. -# -#The annoying thing with tying SRST & TRST together is that -#there is no way to halt the CPU *before and during* the -#SRST reset, which means that the CPU will run a number -#of cycles before it can be halted(as much as milliseconds). -reset_config srst_only srst_pulls_trst - - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME zy1000 -} - -if { [info exists ENDIAN] } { - set _ENDIAN $ENDIAN -} else { - set _ENDIAN little -} - - -#jtag scan chain -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - set _CPUTAPID 0x1f0f0f0f -} -jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID - -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME arm7tdmi -endian $_ENDIAN -chain-position $_TARGETNAME - -# at CPU CLK <32kHz this must be disabled -arm7_9 fast_memory_access enable -arm7_9 dcc_downloads enable - -set _FLASHNAME $_CHIPNAME.flash -flash bank $_FLASHNAME cfi 0x01000000 0x200000 2 2 $_TARGETNAME - -$_TARGETNAME configure -event reset-init { - # Set up chip selects & timings - mww 0xFFE00000 0x0100273D - mww 0xFFE00004 0x08002125 - mww 0xFFEe0008 0x02002125 - mww 0xFFE0000c 0x03002125 - mww 0xFFE00010 0x40000000 - mww 0xFFE00014 0x50000000 - mww 0xFFE00018 0x60000000 - mww 0xFFE0001c 0x70000000 - mww 0xFFE00020 0x00000001 - mww 0xFFE00024 0x00000000 - - # remap - mww 0xFFFFF124 0xFFFFFFFF - mww 0xffff0010 0x100 - mww 0xffff0034 0x100 - - #disable 16x5x UART interrupts - mww 0x08020004 0 -} - -$_TARGETNAME configure -event gdb-attach { - # Without this gdb-attach will first time as probe will fail - reset init -} - -# required for usable performance. Used for lots of -# other things than flash programming. -$_TARGETNAME configure -work-area-phys 0x00020000 -work-area-size 0x20000 -work-area-backup 0 - -adapter_khz 16000 - - -proc production_info {} { - return "Serial number is official MAC number. Format XXXXXXXXXXXX" -} - -# There is no return value from this procedure. If it is -# successful it does not throw an exception -# -# Progress messages are output via puts -proc production {firmwarefile serialnumber} { - if {[string length $serialnumber]!=12} { - echo "Invalid serial number" - return - } - - echo "Power cycling target" - power off - sleep 3000 - power on - sleep 1000 - reset init - flash write_image erase $firmwarefile 0x1000000 bin - verify_image $firmwarefile 0x1000000 bin - - # Big endian... weee!!!! - echo "Setting MAC number to $serialnumber" - flash fillw [expr 0x1030000-0x8] "0x[string range $serialnumber 2 3][string range $serialnumber 0 1]0000" 1 - flash fillw [expr 0x1030000-0x4] "0x[string range $serialnumber 10 11][string range $serialnumber 8 9][string range $serialnumber 6 7][string range $serialnumber 4 5]" 1 - echo "Production successful" -} - - -proc production_test {} { - power on - sleep 1000 - target_request debugmsgs enable - reset run - sleep 25000 - target_request debugmsgs disable - return "See IP address above..." -} diff --git a/tcl/chip/atmel/at91/aic.tcl b/tcl/chip/atmel/at91/aic.tcl deleted file mode 100644 index 6dae36ad6..000000000 --- a/tcl/chip/atmel/at91/aic.tcl +++ /dev/null @@ -1,101 +0,0 @@ -set AIC_SMR [expr $AT91C_BASE_AIC + 0x00000000 ] -global AIC_SMR -set AIC_SVR [expr $AT91C_BASE_AIC + 0x00000080 ] -global AIC_SVR -set AIC_IVR [expr $AT91C_BASE_AIC + 0x00000100 ] -global AIC_IVR -set AIC_FVR [expr $AT91C_BASE_AIC + 0x00000104 ] -global AIC_FVR -set AIC_ISR [expr $AT91C_BASE_AIC + 0x00000108 ] -global AIC_ISR -set AIC_IPR [expr $AT91C_BASE_AIC + 0x0000010C ] -global AIC_IPR -set AIC_IMR [expr $AT91C_BASE_AIC + 0x00000110 ] -global AIC_IMR -set AIC_CISR [expr $AT91C_BASE_AIC + 0x00000114 ] -global AIC_CISR -set AIC_IECR [expr $AT91C_BASE_AIC + 0x00000120 ] -global AIC_IECR -set AIC_IDCR [expr $AT91C_BASE_AIC + 0x00000124 ] -global AIC_IDCR -set AIC_ICCR [expr $AT91C_BASE_AIC + 0x00000128 ] -global AIC_ICCR -set AIC_ISCR [expr $AT91C_BASE_AIC + 0x0000012C ] -global AIC_ISCR -set AIC_EOICR [expr $AT91C_BASE_AIC + 0x00000130 ] -global AIC_EOICR -set AIC_SPU [expr $AT91C_BASE_AIC + 0x00000134 ] -global AIC_SPU -set AIC_DCR [expr $AT91C_BASE_AIC + 0x00000138 ] -global AIC_DCR -set AIC_FFER [expr $AT91C_BASE_AIC + 0x00000140 ] -global AIC_FFER -set AIC_FFDR [expr $AT91C_BASE_AIC + 0x00000144 ] -global AIC_FFDR -set AIC_FFSR [expr $AT91C_BASE_AIC + 0x00000148 ] -global AIC_FFSR - - -proc aic_enable_disable_list { VAL ENAME DNAME } { - global AT91C_ID - - show_mmr32_bits AT91C_ID $VAL - -} - -proc show_AIC_IPR_helper { NAME ADDR VAL } { - aic_enable_disable_list $VAL "IRQ PENDING" "irq not-pending" -} - -proc show_AIC_IMR_helper { NAME ADDR VAL } { - aic_enable_disable_list $VAL "IRQ ENABLED" "irq disabled" -} - - -proc show_AIC { } { - global AIC_SMR - if [catch { mem2array aaa 32 $AIC_SMR [expr 32 * 4] } msg ] { - error [format "%s (%s)" $msg AIC_SMR] - } - echo "AIC_SMR: Mode & Type" - global AT91C_ID - for { set x 0 } { $x < 32 } { } { - echo -n " " - echo -n [format "%2d: %5s 0x%08x | " $x $AT91C_ID($x) $aaa($x)] - incr x - echo -n [format "%2d: %5s 0x%08x | " $x $AT91C_ID($x) $aaa($x)] - incr x - echo -n [format "%2d: %5s 0x%08x | " $x $AT91C_ID($x) $aaa($x)] - incr x - echo [format "%2d: %5s 0x%08x" $x $AT91C_ID($x) $aaa($x)] - incr x - } - global AIC_SVR - if [catch { mem2array aaa 32 $AIC_SVR [expr 32 * 4] } msg ] { - error [format "%s (%s)" $msg AIC_SVR] - } - echo "AIC_SVR: Vectors" - for { set x 0 } { $x < 32 } { } { - echo -n " " - echo -n [format "%2d: %5s 0x%08x | " $x $AT91C_ID($x) $aaa($x)] - incr x - echo -n [format "%2d: %5s 0x%08x | " $x $AT91C_ID($x) $aaa($x)] - incr x - echo -n [format "%2d: %5s 0x%08x | " $x $AT91C_ID($x) $aaa($x)] - incr x - echo [format "%2d: %5s 0x%08x" $x $AT91C_ID($x) $aaa($x)] - incr x - } - - foreach REG { - AIC_IVR AIC_FVR AIC_ISR - AIC_IPR AIC_IMR AIC_CISR AIC_IECR AIC_IDCR - AIC_ICCR AIC_ISCR AIC_EOICR AIC_SPU AIC_DCR - AIC_FFER AIC_FFDR AIC_FFSR } { - if [catch { show_mmr32_reg $REG } msg ] { - error $msg - break - } - } -} - diff --git a/tcl/chip/atmel/at91/at91_pio.cfg b/tcl/chip/atmel/at91/at91_pio.cfg deleted file mode 100644 index 2373c19fe..000000000 --- a/tcl/chip/atmel/at91/at91_pio.cfg +++ /dev/null @@ -1,29 +0,0 @@ -set PIO_PER 0x00 ;# Enable Register -set PIO_PDR 0x04 ;# Disable Register -set PIO_PSR 0x08 ;# Status Register -set PIO_OER 0x10 ;# Output Enable Register -set PIO_ODR 0x14 ;# Output Disable Register -set PIO_OSR 0x18 ;# Output Status Register -set PIO_IFER 0x20 ;# Glitch Input Filter Enable -set PIO_IFDR 0x24 ;# Glitch Input Filter Disable -set PIO_IFSR 0x28 ;# Glitch Input Filter Status -set PIO_SODR 0x30 ;# Set Output Data Register -set PIO_CODR 0x34 ;# Clear Output Data Register -set PIO_ODSR 0x38 ;# Output Data Status Register -set PIO_PDSR 0x3c ;# Pin Data Status Register -set PIO_IER 0x40 ;# Interrupt Enable Register -set PIO_IDR 0x44 ;# Interrupt Disable Register -set PIO_IMR 0x48 ;# Interrupt Mask Register -set PIO_ISR 0x4c ;# Interrupt Status Register -set PIO_MDER 0x50 ;# Multi-driver Enable Register -set PIO_MDDR 0x54 ;# Multi-driver Disable Register -set PIO_MDSR 0x58 ;# Multi-driver Status Register -set PIO_PUDR 0x60 ;# Pull-up Disable Register -set PIO_PUER 0x64 ;# Pull-up Enable Register -set PIO_PUSR 0x68 ;# Pull-up Status Register -set PIO_ASR 0x70 ;# Peripheral A Select Register -set PIO_BSR 0x74 ;# Peripheral B Select Register -set PIO_ABSR 0x78 ;# AB Status Register -set PIO_OWER 0xa0 ;# Output Write Enable Register -set PIO_OWDR 0xa4 ;# Output Write Disable Register -set PIO_OWSR 0xa8 ;# Output Write Status Register diff --git a/tcl/chip/atmel/at91/at91_pmc.cfg b/tcl/chip/atmel/at91/at91_pmc.cfg deleted file mode 100644 index 88b137024..000000000 --- a/tcl/chip/atmel/at91/at91_pmc.cfg +++ /dev/null @@ -1,113 +0,0 @@ -set AT91_PMC_SCER [expr ($AT91_PMC + 0x00)] ;# System Clock Enable Register -set AT91_PMC_SCDR [expr ($AT91_PMC + 0x04)] ;# System Clock Disable Register - -set AT91_PMC_SCSR [expr ($AT91_PMC + 0x08)] ;# System Clock Status Register -set AT91_PMC_PCK [expr (1 << 0)] ;# Processor Clock -set AT91RM9200_PMC_UDP [expr (1 << 1)] ;# USB Devcice Port Clock [AT91RM9200 only] -set AT91RM9200_PMC_MCKUDP [expr (1 << 2)] ;# USB Device Port Master Clock Automatic Disable on Suspend [AT91RM9200 only] -set AT91CAP9_PMC_DDR [expr (1 << 2)] ;# DDR Clock [CAP9 revC & some SAM9 only] -set AT91RM9200_PMC_UHP [expr (1 << 4)] ;# USB Host Port Clock [AT91RM9200 only] -set AT91SAM926x_PMC_UHP [expr (1 << 6)] ;# USB Host Port Clock [AT91SAM926x only] -set AT91CAP9_PMC_UHP [expr (1 << 6)] ;# USB Host Port Clock [AT91CAP9 only] -set AT91SAM926x_PMC_UDP [expr (1 << 7)] ;# USB Devcice Port Clock [AT91SAM926x only] -set AT91_PMC_PCK0 [expr (1 << 8)] ;# Programmable Clock 0 -set AT91_PMC_PCK1 [expr (1 << 9)] ;# Programmable Clock 1 -set AT91_PMC_PCK2 [expr (1 << 10)] ;# Programmable Clock 2 -set AT91_PMC_PCK3 [expr (1 << 11)] ;# Programmable Clock 3 -set AT91_PMC_HCK0 [expr (1 << 16)] ;# AHB Clock (USB host) [AT91SAM9261 only] -set AT91_PMC_HCK1 [expr (1 << 17)] ;# AHB Clock (LCD) [AT91SAM9261 only] - -set AT91_PMC_PCER [expr ($AT91_PMC + 0x10)] ;# Peripheral Clock Enable Register -set AT91_PMC_PCDR [expr ($AT91_PMC + 0x14)] ;# Peripheral Clock Disable Register -set AT91_PMC_PCSR [expr ($AT91_PMC + 0x18)] ;# Peripheral Clock Status Register - -set AT91_CKGR_UCKR [expr ($AT91_PMC + 0x1C)] ;# UTMI Clock Register [some SAM9, CAP9] -set AT91_PMC_UPLLEN [expr (1 << 16)] ;# UTMI PLL Enable -set AT91_PMC_UPLLCOUNT [expr (0xf << 20)] ;# UTMI PLL Start-up Time -set AT91_PMC_BIASEN [expr (1 << 24)] ;# UTMI BIAS Enable -set AT91_PMC_BIASCOUNT [expr (0xf << 28)] ;# UTMI BIAS Start-up Time - -set AT91_CKGR_MOR [expr ($AT91_PMC + 0x20)] ;# Main Oscillator Register [not on SAM9RL] -set AT91_PMC_MOSCEN [expr (1 << 0)] ;# Main Oscillator Enable -set AT91_PMC_OSCBYPASS [expr (1 << 1)] ;# Oscillator Bypass [SAM9x, CAP9] -set AT91_PMC_OSCOUNT [expr (0xff << 8)] ;# Main Oscillator Start-up Time - -set AT91_CKGR_MCFR [expr ($AT91_PMC + 0x24)] ;# Main Clock Frequency Register -set AT91_PMC_MAINF [expr (0xffff << 0)] ;# Main Clock Frequency -set AT91_PMC_MAINRDY [expr (1 << 16)] ;# Main Clock Ready - -set AT91_CKGR_PLLAR [expr ($AT91_PMC + 0x28)] ;# PLL A Register -set AT91_CKGR_PLLBR [expr ($AT91_PMC + 0x2c)] ;# PLL B Register -set AT91_PMC_DIV [expr (0xff << 0)] ;# Divider -set AT91_PMC_PLLCOUNT [expr (0x3f << 8)] ;# PLL Counter -set AT91_PMC_OUT [expr (3 << 14)] ;# PLL Clock Frequency Range -set AT91_PMC_MUL [expr (0x7ff << 16)] ;# PLL Multiplier -set AT91_PMC_USBDIV [expr (3 << 28)] ;# USB Divisor (PLLB only) -set AT91_PMC_USBDIV_1 [expr (0 << 28)] -set AT91_PMC_USBDIV_2 [expr (1 << 28)] -set AT91_PMC_USBDIV_4 [expr (2 << 28)] -set AT91_PMC_USB96M [expr (1 << 28)] ;# Divider by 2 Enable (PLLB only) -set AT91_PMC_PLLA_WR_ERRATA [expr (1 << 29)] ;# Bit 29 must always be set to 1 when programming the CKGR_PLLAR register - -set AT91_PMC_MCKR [expr ($AT91_PMC + 0x30)] ;# Master Clock Register -set AT91_PMC_CSS [expr (3 << 0)] ;# Master Clock Selection -set AT91_PMC_CSS_SLOW [expr (0 << 0)] -set AT91_PMC_CSS_MAIN [expr (1 << 0)] -set AT91_PMC_CSS_PLLA [expr (2 << 0)] -set AT91_PMC_CSS_PLLB [expr (3 << 0)] -set AT91_PMC_CSS_UPLL [expr (3 << 0)] ;# [some SAM9 only] -set AT91_PMC_PRES [expr (7 << 2)] ;# Master Clock Prescaler -set AT91_PMC_PRES_1 [expr (0 << 2)] -set AT91_PMC_PRES_2 [expr (1 << 2)] -set AT91_PMC_PRES_4 [expr (2 << 2)] -set AT91_PMC_PRES_8 [expr (3 << 2)] -set AT91_PMC_PRES_16 [expr (4 << 2)] -set AT91_PMC_PRES_32 [expr (5 << 2)] -set AT91_PMC_PRES_64 [expr (6 << 2)] -set AT91_PMC_MDIV [expr (3 << 8)] ;# Master Clock Division -set AT91RM9200_PMC_MDIV_1 [expr (0 << 8)] ;# [AT91RM9200 only] -set AT91RM9200_PMC_MDIV_2 [expr (1 << 8)] -set AT91RM9200_PMC_MDIV_3 [expr (2 << 8)] -set AT91RM9200_PMC_MDIV_4 [expr (3 << 8)] -set AT91SAM9_PMC_MDIV_1 [expr (0 << 8)] ;# [SAM9,CAP9 only] -set AT91SAM9_PMC_MDIV_2 [expr (1 << 8)] -set AT91SAM9_PMC_MDIV_4 [expr (2 << 8)] -set AT91SAM9_PMC_MDIV_6 [expr (3 << 8)] ;# [some SAM9 only] -set AT91SAM9_PMC_MDIV_3 [expr (3 << 8)] ;# [some SAM9 only] -set AT91_PMC_PDIV [expr (1 << 12)] ;# Processor Clock Division [some SAM9 only] -set AT91_PMC_PDIV_1 [expr (0 << 12)] -set AT91_PMC_PDIV_2 [expr (1 << 12)] -set AT91_PMC_PLLADIV2 [expr (1 << 12)] ;# PLLA divisor by 2 [some SAM9 only] -set AT91_PMC_PLLADIV2_OFF [expr (0 << 12)] -set AT91_PMC_PLLADIV2_ON [expr (1 << 12)] - -set AT91_PMC_USB [expr ($AT91_PMC + 0x38)] ;# USB Clock Register [some SAM9 only] -set AT91_PMC_USBS [expr (0x1 << 0)] ;# USB OHCI Input clock selection -set AT91_PMC_USBS_PLLA [expr (0 << 0)] -set AT91_PMC_USBS_UPLL [expr (1 << 0)] -set AT91_PMC_OHCIUSBDIV [expr (0xF << 8)] ;# Divider for USB OHCI Clock - -;# set AT91_PMC_PCKR(n) [expr ($AT91_PMC + 0x40 + ((n) * 4))] ;# Programmable Clock 0-N Registers -set AT91_PMC_CSSMCK [expr (0x1 << 8)] ;# CSS or Master Clock Selection -set AT91_PMC_CSSMCK_CSS [expr (0 << 8)] -set AT91_PMC_CSSMCK_MCK [expr (1 << 8)] - -set AT91_PMC_IER [expr ($AT91_PMC + 0x60)] ;# Interrupt Enable Register -set AT91_PMC_IDR [expr ($AT91_PMC + 0x64)] ;# Interrupt Disable Register -set AT91_PMC_SR [expr ($AT91_PMC + 0x68)] ;# Status Register -set AT91_PMC_MOSCS [expr (1 << 0)] ;# MOSCS Flag -set AT91_PMC_LOCKA [expr (1 << 1)] ;# PLLA Lock -set AT91_PMC_LOCKB [expr (1 << 2)] ;# PLLB Lock -set AT91_PMC_MCKRDY [expr (1 << 3)] ;# Master Clock -set AT91_PMC_LOCKU [expr (1 << 6)] ;# UPLL Lock [some SAM9, AT91CAP9 only] -set AT91_PMC_OSCSEL [expr (1 << 7)] ;# Slow Clock Oscillator [AT91CAP9 revC only] -set AT91_PMC_PCK0RDY [expr (1 << 8)] ;# Programmable Clock 0 -set AT91_PMC_PCK1RDY [expr (1 << 9)] ;# Programmable Clock 1 -set AT91_PMC_PCK2RDY [expr (1 << 10)] ;# Programmable Clock 2 -set AT91_PMC_PCK3RDY [expr (1 << 11)] ;# Programmable Clock 3 -set AT91_PMC_IMR [expr ($AT91_PMC + 0x6c)] ;# Interrupt Mask Register - -set AT91_PMC_PROT [expr ($AT91_PMC + 0xe4)] ;# Protect Register [AT91CAP9 revC only] -set AT91_PMC_PROTKEY 0x504d4301 ;# Activation Code - -set AT91_PMC_VER [expr ($AT91_PMC + 0xfc)] ;# PMC Module Version [AT91CAP9 only] diff --git a/tcl/chip/atmel/at91/at91_rstc.cfg b/tcl/chip/atmel/at91/at91_rstc.cfg deleted file mode 100644 index ed6082227..000000000 --- a/tcl/chip/atmel/at91/at91_rstc.cfg +++ /dev/null @@ -1,21 +0,0 @@ -set AT91_RSTC_CR [expr ($AT91_RSTC + 0x00)] ;# Reset Controller Control Register -set AT91_RSTC_PROCRST [expr (1 << 0)] ;# Processor Reset -set AT91_RSTC_PERRST [expr (1 << 2)] ;# Peripheral Reset -set AT91_RSTC_EXTRST [expr (1 << 3)] ;# External Reset -set AT91_RSTC_KEY [expr (0xa5 << 24)] ;# KEY Password - -set AT91_RSTC_SR [expr ($AT91_RSTC + 0x04)] ;# Reset Controller Status Register -set AT91_RSTC_URSTS [expr (1 << 0)] ;# User Reset Status -set AT91_RSTC_RSTTYP [expr (7 << 8)] ;# Reset Type -set AT91_RSTC_RSTTYP_GENERAL [expr (0 << 8)] -set AT91_RSTC_RSTTYP_WAKEUP [expr (1 << 8)] -set AT91_RSTC_RSTTYP_WATCHDOG [expr (2 << 8)] -set AT91_RSTC_RSTTYP_SOFTWARE [expr (3 << 8)] -set AT91_RSTC_RSTTYP_USER [expr (4 << 8)] -set AT91_RSTC_NRSTL [expr (1 << 16)] ;# NRST Pin Level -set AT91_RSTC_SRCMP [expr (1 << 17)] ;# Software Reset Command in Progress - -set AT91_RSTC_MR [expr ($AT91_RSTC + 0x08)] ;# Reset Controller Mode Register -set AT91_RSTC_URSTEN [expr (1 << 0)] ;# User Reset Enable -set AT91_RSTC_URSTIEN [expr (1 << 4)] ;# User Reset Interrupt Enable -set AT91_RSTC_ERSTL [expr (0xf << 8)] ;# External Reset Length diff --git a/tcl/chip/atmel/at91/at91_wdt.cfg b/tcl/chip/atmel/at91/at91_wdt.cfg deleted file mode 100644 index a263cc7f6..000000000 --- a/tcl/chip/atmel/at91/at91_wdt.cfg +++ /dev/null @@ -1,17 +0,0 @@ -set AT91_WDT_CR [expr ($AT91_WDT + 0x00)] ;# Watchdog Control Register -set AT91_WDT_WDRSTT [expr (1 << 0)] ;# Restart -set AT91_WDT_KEY [expr (0xa5 << 24)] ;# KEY Password - -set AT91_WDT_MR [expr ($AT91_WDT + 0x04)] ;# Watchdog Mode Register -set AT91_WDT_WDV [expr (0xfff << 0)] ;# Counter Value -set AT91_WDT_WDFIEN [expr (1 << 12)] ;# Fault Interrupt Enable -set AT91_WDT_WDRSTEN [expr (1 << 13)] ;# Reset Processor -set AT91_WDT_WDRPROC [expr (1 << 14)] ;# Timer Restart -set AT91_WDT_WDDIS [expr (1 << 15)] ;# Watchdog Disable -set AT91_WDT_WDD [expr (0xfff << 16)] ;# Delta Value -set AT91_WDT_WDDBGHLT [expr (1 << 28)] ;# Debug Halt -set AT91_WDT_WDIDLEHLT [expr (1 << 29)] ;# Idle Halt - -set AT91_WDT_SR [expr ($AT91_WDT + 0x08)] ;# Watchdog Status Register -set AT91_WDT_WDUNF [expr (1 << 0)] ;# Watchdog Underflow -set AT91_WDT_WDERR [expr (1 << 1)] ;# Watchdog Error diff --git a/tcl/chip/atmel/at91/at91sam7x128.tcl b/tcl/chip/atmel/at91/at91sam7x128.tcl deleted file mode 100644 index ce33cf009..000000000 --- a/tcl/chip/atmel/at91/at91sam7x128.tcl +++ /dev/null @@ -1,128 +0,0 @@ -source [find bitsbytes.tcl] -source [find cpu/arm/arm7tdmi.tcl] -source [find memory.tcl] -source [find mmr_helpers.tcl] - -set CHIP_MAKER atmel -set CHIP_FAMILY at91sam7 -set CHIP_NAME at91sam7x128 -# how many flash regions. -set N_FLASH 1 -set FLASH(0,CHIPSELECT) -1 -set FLASH(0,BASE) 0x00100000 -set FLASH(0,LEN) $__128K -set FLASH(0,HUMAN) "internal flash" -set FLASH(0,TYPE) "flash" -set FLASH(0,RWX) $RWX_R_X -set FLASH(0,ACCESS_WIDTH) $ACCESS_WIDTH_ANY -# how many ram regions. -set N_RAM 1 -set RAM(0,CHIPSELECT) -1 -set RAM(0,BASE) 0x00200000 -set RAM(0,LEN) $__32K -set RAM(0,HUMAN) "internal ram" -set RAM(0,TYPE) "ram" -set RAM(0,RWX) $RWX_RWX -set RAM(0,ACCESS_WIDTH) $ACCESS_WIDTH_ANY - -# I AM LAZY... I create 1 region for all MMRs. -set N_MMREGS 1 -set MMREGS(0,CHIPSELECT) -1 -set MMREGS(0,BASE) 0xfff00000 -set MMREGS(0,LEN) 0x000fffff -set MMREGS(0,HUMAN) "mm-regs" -set MMREGS(0,TYPE) "mmr" -set MMREGS(0,RWX) $RWX_RW -set MMREGS(0,ACCESS_WIDTH) $ACCESS_WIDTH_ANY - -# no external memory -set N_XMEM 0 - - - - -set AT91C_BASE_SYS 0xFFFFF000 -set AT91C_BASE_AIC 0xFFFFF000 -set AT91C_BASE_PDC_DBGU 0xFFFFF300 -set AT91C_BASE_DBGU 0xFFFFF200 -set AT91C_BASE_PIOA 0xFFFFF400 -set AT91C_BASE_PIOB 0xFFFFF600 -set AT91C_BASE_CKGR 0xFFFFFC20 -set AT91C_BASE_PMC 0xFFFFFC00 -set AT91C_BASE_RSTC 0xFFFFFD00 -set AT91C_BASE_RTTC 0xFFFFFD20 -set AT91C_BASE_PITC 0xFFFFFD30 -set AT91C_BASE_WDTC 0xFFFFFD40 -set AT91C_BASE_VREG 0xFFFFFD60 -set AT91C_BASE_MC 0xFFFFFF00 -set AT91C_BASE_PDC_SPI1 0xFFFE4100 -set AT91C_BASE_SPI1 0xFFFE4000 -set AT91C_BASE_PDC_SPI0 0xFFFE0100 -set AT91C_BASE_SPI0 0xFFFE0000 -set AT91C_BASE_PDC_US1 0xFFFC4100 -set AT91C_BASE_US1 0xFFFC4000 -set AT91C_BASE_PDC_US0 0xFFFC0100 -set AT91C_BASE_US0 0xFFFC0000 -set AT91C_BASE_PDC_SSC 0xFFFD4100 -set AT91C_BASE_SSC 0xFFFD4000 -set AT91C_BASE_TWI 0xFFFB8000 -set AT91C_BASE_PWMC_CH3 0xFFFCC260 -set AT91C_BASE_PWMC_CH2 0xFFFCC240 -set AT91C_BASE_PWMC_CH1 0xFFFCC220 -set AT91C_BASE_PWMC_CH0 0xFFFCC200 -set AT91C_BASE_PWMC 0xFFFCC000 -set AT91C_BASE_UDP 0xFFFB0000 -set AT91C_BASE_TC0 0xFFFA0000 -set AT91C_BASE_TC1 0xFFFA0040 -set AT91C_BASE_TC2 0xFFFA0080 -set AT91C_BASE_TCB 0xFFFA0000 -set AT91C_BASE_CAN_MB0 0xFFFD0200 -set AT91C_BASE_CAN_MB1 0xFFFD0220 -set AT91C_BASE_CAN_MB2 0xFFFD0240 -set AT91C_BASE_CAN_MB3 0xFFFD0260 -set AT91C_BASE_CAN_MB4 0xFFFD0280 -set AT91C_BASE_CAN_MB5 0xFFFD02A0 -set AT91C_BASE_CAN_MB6 0xFFFD02C0 -set AT91C_BASE_CAN_MB7 0xFFFD02E0 -set AT91C_BASE_CAN 0xFFFD0000 -set AT91C_BASE_EMAC 0xFFFDC000 -set AT91C_BASE_PDC_ADC 0xFFFD8100 -set AT91C_BASE_ADC 0xFFFD8000 - -set AT91C_ID(0) FIQ -set AT91C_ID(1) SYS -set AT91C_ID(2) PIOA -set AT91C_ID(3) PIOB -set AT91C_ID(4) SPI0 -set AT91C_ID(5) SPI1 -set AT91C_ID(6) US0 -set AT91C_ID(7) US1 -set AT91C_ID(8) SSC -set AT91C_ID(9) TWI -set AT91C_ID(10) PWMC -set AT91C_ID(11) UDP -set AT91C_ID(12) TC0 -set AT91C_ID(13) TC1 -set AT91C_ID(14) TC2 -set AT91C_ID(15) CAN -set AT91C_ID(16) EMAC -set AT91C_ID(17) ADC -set AT91C_ID(18) "" -set AT91C_ID(19) "" -set AT91C_ID(20) "" -set AT91C_ID(21) "" -set AT91C_ID(22) "" -set AT91C_ID(23) "" -set AT91C_ID(24) "" -set AT91C_ID(25) "" -set AT91C_ID(26) "" -set AT91C_ID(27) "" -set AT91C_ID(28) "" -set AT91C_ID(29) "" -set AT91C_ID(30) IRQ0 -set AT91C_ID(31) IRQ1 - -source [find chip/atmel/at91/aic.tcl] -source [find chip/atmel/at91/usarts.tcl] -source [find chip/atmel/at91/pmc.tcl] -source [find chip/atmel/at91/rtt.tcl] diff --git a/tcl/chip/atmel/at91/at91sam7x256.tcl b/tcl/chip/atmel/at91/at91sam7x256.tcl deleted file mode 100644 index dc4918ab1..000000000 --- a/tcl/chip/atmel/at91/at91sam7x256.tcl +++ /dev/null @@ -1,126 +0,0 @@ -source [find bitsbytes.tcl] -source [find cpu/arm/arm7tdmi.tcl] -source [find memory.tcl] -source [find mmr_helpers.tcl] - -set CHIP_MAKER atmel -set CHIP_FAMILY at91sam7 -set CHIP_NAME at91sam7x256 -# how many flash regions. -set N_FLASH 1 -set FLASH(0,CHIPSELECT) -1 -set FLASH(0,BASE) 0x00100000 -set FLASH(0,LEN) $__256K -set FLASH(0,HUMAN) "internal flash" -set FLASH(0,TYPE) "flash" -set FLASH(0,RWX) $RWX_R_X -set FLASH(0,ACCESS_WIDTH) $ACCESS_WIDTH_ANY -# how many ram regions. -set N_RAM 1 -set RAM(0,CHIPSELECT) -1 -set RAM(0,BASE) 0x00200000 -set RAM(0,LEN) $__64K -set RAM(0,HUMAN) "internal ram" -set RAM(0,TYPE) "ram" -set RAM(0,RWX) $RWX_RWX -set RAM(0,ACCESS_WIDTH) $ACCESS_WIDTH_ANY - -# I AM LAZY... I create 1 region for all MMRs. -set N_MMREGS 1 -set MMREGS(0,CHIPSELECT) -1 -set MMREGS(0,BASE) 0xfff00000 -set MMREGS(0,LEN) 0x000fffff -set MMREGS(0,HUMAN) "mm-regs" -set MMREGS(0,TYPE) "mmr" -set MMREGS(0,RWX) $RWX_RW -set MMREGS(0,ACCESS_WIDTH) $ACCESS_WIDTH_ANY - -# no external memory -set N_XMEM 0 - -set AT91C_BASE_SYS 0xFFFFF000 -set AT91C_BASE_AIC 0xFFFFF000 -set AT91C_BASE_PDC_DBGU 0xFFFFF300 -set AT91C_BASE_DBGU 0xFFFFF200 -set AT91C_BASE_PIOA 0xFFFFF400 -set AT91C_BASE_PIOB 0xFFFFF600 -set AT91C_BASE_CKGR 0xFFFFFC20 -set AT91C_BASE_PMC 0xFFFFFC00 -set AT91C_BASE_RSTC 0xFFFFFD00 -set AT91C_BASE_RTTC 0xFFFFFD20 -set AT91C_BASE_PITC 0xFFFFFD30 -set AT91C_BASE_WDTC 0xFFFFFD40 -set AT91C_BASE_VREG 0xFFFFFD60 -set AT91C_BASE_MC 0xFFFFFF00 -set AT91C_BASE_PDC_SPI1 0xFFFE4100 -set AT91C_BASE_SPI1 0xFFFE4000 -set AT91C_BASE_PDC_SPI0 0xFFFE0100 -set AT91C_BASE_SPI0 0xFFFE0000 -set AT91C_BASE_PDC_US1 0xFFFC4100 -set AT91C_BASE_US1 0xFFFC4000 -set AT91C_BASE_PDC_US0 0xFFFC0100 -set AT91C_BASE_US0 0xFFFC0000 -set AT91C_BASE_PDC_SSC 0xFFFD4100 -set AT91C_BASE_SSC 0xFFFD4000 -set AT91C_BASE_TWI 0xFFFB8000 -set AT91C_BASE_PWMC_CH3 0xFFFCC260 -set AT91C_BASE_PWMC_CH2 0xFFFCC240 -set AT91C_BASE_PWMC_CH1 0xFFFCC220 -set AT91C_BASE_PWMC_CH0 0xFFFCC200 -set AT91C_BASE_PWMC 0xFFFCC000 -set AT91C_BASE_UDP 0xFFFB0000 -set AT91C_BASE_TC0 0xFFFA0000 -set AT91C_BASE_TC1 0xFFFA0040 -set AT91C_BASE_TC2 0xFFFA0080 -set AT91C_BASE_TCB 0xFFFA0000 -set AT91C_BASE_CAN_MB0 0xFFFD0200 -set AT91C_BASE_CAN_MB1 0xFFFD0220 -set AT91C_BASE_CAN_MB2 0xFFFD0240 -set AT91C_BASE_CAN_MB3 0xFFFD0260 -set AT91C_BASE_CAN_MB4 0xFFFD0280 -set AT91C_BASE_CAN_MB5 0xFFFD02A0 -set AT91C_BASE_CAN_MB6 0xFFFD02C0 -set AT91C_BASE_CAN_MB7 0xFFFD02E0 -set AT91C_BASE_CAN 0xFFFD0000 -set AT91C_BASE_EMAC 0xFFFDC000 -set AT91C_BASE_PDC_ADC 0xFFFD8100 -set AT91C_BASE_ADC 0xFFFD8000 - -set AT91C_ID(0) "FIQ" -set AT91C_ID(1) "SYS" -set AT91C_ID(2) "PIOA" -set AT91C_ID(3) "PIOB" -set AT91C_ID(4) "SPI0" -set AT91C_ID(5) "SPI1" -set AT91C_ID(6) "US0" -set AT91C_ID(7) "US1" -set AT91C_ID(8) "SSC" -set AT91C_ID(9) "TWI" -set AT91C_ID(10) "PWMC" -set AT91C_ID(11) "UDP" -set AT91C_ID(12) "TC0" -set AT91C_ID(13) "TC1" -set AT91C_ID(14) "TC2" -set AT91C_ID(15) "CAN" -set AT91C_ID(16) "EMAC" -set AT91C_ID(17) "ADC" -set AT91C_ID(18) "" -set AT91C_ID(19) "" -set AT91C_ID(20) "" -set AT91C_ID(21) "" -set AT91C_ID(22) "" -set AT91C_ID(23) "" -set AT91C_ID(24) "" -set AT91C_ID(25) "" -set AT91C_ID(26) "" -set AT91C_ID(27) "" -set AT91C_ID(28) "" -set AT91C_ID(29) "" -set AT91C_ID(30) "IRQ0" -set AT91C_ID(31) "IRQ1" - - -source [find chip/atmel/at91/aic.tcl] -source [find chip/atmel/at91/usarts.tcl] -source [find chip/atmel/at91/pmc.tcl] -source [find chip/atmel/at91/rtt.tcl] diff --git a/tcl/chip/atmel/at91/at91sam9261.cfg b/tcl/chip/atmel/at91/at91sam9261.cfg deleted file mode 100644 index 61b0c0bf3..000000000 --- a/tcl/chip/atmel/at91/at91sam9261.cfg +++ /dev/null @@ -1,90 +0,0 @@ -# -# Peripheral identifiers/interrupts. -# -set AT91_ID_FIQ 0 ;# Advanced Interrupt Controller (FIQ) -set AT91_ID_SYS 1 ;# System Peripherals -set AT91SAM9261_ID_PIOA 2 ;# Parallel IO Controller A -set AT91SAM9261_ID_PIOB 3 ;# Parallel IO Controller B -set AT91SAM9261_ID_PIOC 4 ;# Parallel IO Controller C -set AT91SAM9261_ID_US0 6 ;# USART 0 -set AT91SAM9261_ID_US1 7 ;# USART 1 -set AT91SAM9261_ID_US2 8 ;# USART 2 -set AT91SAM9261_ID_MCI 9 ;# Multimedia Card Interface -set AT91SAM9261_ID_UDP 10 ;# USB Device Port -set AT91SAM9261_ID_TWI 11 ;# Two-Wire Interface -set AT91SAM9261_ID_SPI0 12 ;# Serial Peripheral Interface 0 -set AT91SAM9261_ID_SPI1 13 ;# Serial Peripheral Interface 1 -set AT91SAM9261_ID_SSC0 14 ;# Serial Synchronous Controller 0 -set AT91SAM9261_ID_SSC1 15 ;# Serial Synchronous Controller 1 -set AT91SAM9261_ID_SSC2 16 ;# Serial Synchronous Controller 2 -set AT91SAM9261_ID_TC0 17 ;# Timer Counter 0 -set AT91SAM9261_ID_TC1 18 ;# Timer Counter 1 -set AT91SAM9261_ID_TC2 19 ;# Timer Counter 2 -set AT91SAM9261_ID_UHP 20 ;# USB Host port -set AT91SAM9261_ID_LCDC 21 ;# LDC Controller -set AT91SAM9261_ID_IRQ0 29 ;# Advanced Interrupt Controller (IRQ0) -set AT91SAM9261_ID_IRQ1 30 ;# Advanced Interrupt Controller (IRQ1) -set AT91SAM9261_ID_IRQ2 31 ;# Advanced Interrupt Controller (IRQ2) - - -# -# User Peripheral physical base addresses. -# -set AT91SAM9261_BASE_TCB0 0xfffa0000 -set AT91SAM9261_BASE_TC0 0xfffa0000 -set AT91SAM9261_BASE_TC1 0xfffa0040 -set AT91SAM9261_BASE_TC2 0xfffa0080 -set AT91SAM9261_BASE_UDP 0xfffa4000 -set AT91SAM9261_BASE_MCI 0xfffa8000 -set AT91SAM9261_BASE_TWI 0xfffac000 -set AT91SAM9261_BASE_US0 0xfffb0000 -set AT91SAM9261_BASE_US1 0xfffb4000 -set AT91SAM9261_BASE_US2 0xfffb8000 -set AT91SAM9261_BASE_SSC0 0xfffbc000 -set AT91SAM9261_BASE_SSC1 0xfffc0000 -set AT91SAM9261_BASE_SSC2 0xfffc4000 -set AT91SAM9261_BASE_SPI0 0xfffc8000 -set AT91SAM9261_BASE_SPI1 0xfffcc000 -set AT91_BASE_SYS 0xffffea00 - - -# -# System Peripherals (offset from AT91_BASE_SYS) -# -set AT91_SDRAMC 0xffffea00 -set AT91_SMC 0xffffec00 -set AT91_MATRIX 0xffffee00 -set AT91_AIC 0xfffff000 -set AT91_DBGU 0xfffff200 -set AT91_PIOA 0xfffff400 -set AT91_PIOB 0xfffff600 -set AT91_PIOC 0xfffff800 -set AT91_PMC 0xfffffc00 -set AT91_RSTC 0xfffffd00 -set AT91_SHDWC 0xfffffd10 -set AT91_RTT 0xfffffd20 -set AT91_PIT 0xfffffd30 -set AT91_WDT 0xfffffd40 -set AT91_GPBR 0xfffffd50 - -set AT91_USART0 $AT91SAM9261_BASE_US0 -set AT91_USART1 $AT91SAM9261_BASE_US1 -set AT91_USART2 $AT91SAM9261_BASE_US2 - - -# -# Internal Memory. -# -set AT91SAM9261_SRAM_BASE 0x00300000 ;# Internal SRAM base address -set AT91SAM9261_SRAM_SIZE 0x00028000 ;# Internal SRAM size (160Kb) - -set AT91SAM9261_ROM_BASE 0x00400000 ;# Internal ROM base address -set AT91SAM9261_ROM_SIZE 0x00008000 ;# Internal ROM size (32Kb) - -set AT91SAM9261_UHP_BASE 0x00500000 ;# USB Host controller -set AT91SAM9261_LCDC_BASE 0x00600000 ;# LDC controller - -# -# Cpu Name -# -set AT91_CPU_NAME "AT91SAM9261" diff --git a/tcl/chip/atmel/at91/at91sam9261_matrix.cfg b/tcl/chip/atmel/at91/at91sam9261_matrix.cfg deleted file mode 100644 index dc8de2376..000000000 --- a/tcl/chip/atmel/at91/at91sam9261_matrix.cfg +++ /dev/null @@ -1,46 +0,0 @@ - -set AT91_MATRIX_MCFG [expr ($AT91_MATRIX + 0x00)] ;# Master Configuration Register # -set AT91_MATRIX_RCB0 [expr (1 << 0)] ;# Remap Command for AHB Master 0 (ARM926EJ-S Instruction Master) -set AT91_MATRIX_RCB1 [expr (1 << 1)] ;# Remap Command for AHB Master 1 (ARM926EJ-S Data Master) - -set AT91_MATRIX_SCFG0 [expr ($AT91_MATRIX + 0x04)] ;# Slave Configuration Register 0 -set AT91_MATRIX_SCFG1 [expr ($AT91_MATRIX + 0x08)] ;# Slave Configuration Register 1 -set AT91_MATRIX_SCFG2 [expr ($AT91_MATRIX + 0x0C)] ;# Slave Configuration Register 2 -set AT91_MATRIX_SCFG3 [expr ($AT91_MATRIX + 0x10)] ;# Slave Configuration Register 3 -set AT91_MATRIX_SCFG4 [expr ($AT91_MATRIX + 0x14)] ;# Slave Configuration Register 4 -set AT91_MATRIX_SLOT_CYCLE [expr (0xff << 0)] ;# Maximum Number of Allowed Cycles for a Burst -set AT91_MATRIX_DEFMSTR_TYPE [expr (3 << 16)] ;# Default Master Type -set AT91_MATRIX_DEFMSTR_TYPE_NONE [expr (0 << 16)] -set AT91_MATRIX_DEFMSTR_TYPE_LAST [expr (1 << 16)] -set AT91_MATRIX_DEFMSTR_TYPE_FIXED [expr (2 << 16)] -set AT91_MATRIX_FIXED_DEFMSTR [expr (7 << 18)] ;# Fixed Index of Default Master - -set AT91_MATRIX_TCR [expr ($AT91_MATRIX + 0x24)] ;# TCM Configuration Register -set AT91_MATRIX_ITCM_SIZE [expr (0xf << 0)] ;# Size of ITCM enabled memory block -set AT91_MATRIX_ITCM_0 [expr (0 << 0)] -set AT91_MATRIX_ITCM_16 [expr (5 << 0)] -set AT91_MATRIX_ITCM_32 [expr (6 << 0)] -set AT91_MATRIX_ITCM_64 [expr (7 << 0)] -set AT91_MATRIX_DTCM_SIZE [expr (0xf << 4)] ;# Size of DTCM enabled memory block -set AT91_MATRIX_DTCM_0 [expr (0 << 4)] -set AT91_MATRIX_DTCM_16 [expr (5 << 4)] -set AT91_MATRIX_DTCM_32 [expr (6 << 4)] -set AT91_MATRIX_DTCM_64 [expr (7 << 4)] - -set AT91_MATRIX_EBICSA [expr ($AT91_MATRIX + 0x30)] ;# EBI Chip Select Assignment Register -set AT91_MATRIX_CS1A [expr (1 << 1)] ;# Chip Select 1 Assignment -set AT91_MATRIX_CS1A_SMC [expr (0 << 1)] -set AT91_MATRIX_CS1A_SDRAMC [expr (1 << 1)] -set AT91_MATRIX_CS3A [expr (1 << 3)] ;# Chip Select 3 Assignment -set AT91_MATRIX_CS3A_SMC [expr (0 << 3)] -set AT91_MATRIX_CS3A_SMC_SMARTMEDIA [expr (1 << 3)] -set AT91_MATRIX_CS4A [expr (1 << 4)] ;# Chip Select 4 Assignment -set AT91_MATRIX_CS4A_SMC [expr (0 << 4)] -set AT91_MATRIX_CS4A_SMC_CF1 [expr (1 << 4)] -set AT91_MATRIX_CS5A [expr (1 << 5)] ;# Chip Select 5 Assignment -set AT91_MATRIX_CS5A_SMC [expr (0 << 5)] -set AT91_MATRIX_CS5A_SMC_CF2 [expr (1 << 5)] -set AT91_MATRIX_DBPUC [expr (1 << 8)] ;# Data Bus Pull-up Configuration - -set AT91_MATRIX_USBPUCR [expr ($AT91_MATRIX + 0x34)] ;# USB Pad Pull-Up Control Register -set AT91_MATRIX_USBPUCR_PUON [expr (1 << 30)] ;# USB Device PAD Pull-up Enable diff --git a/tcl/chip/atmel/at91/at91sam9263.cfg b/tcl/chip/atmel/at91/at91sam9263.cfg deleted file mode 100644 index 8e22eb2db..000000000 --- a/tcl/chip/atmel/at91/at91sam9263.cfg +++ /dev/null @@ -1,113 +0,0 @@ -# -# Peripheral identifiers/interrupts. -# -set AT91_ID_FIQ 0 ;# Advanced Interrupt Controller (FIQ) -set AT91_ID_SYS 1 ;# System Peripherals -set AT91SAM9263_ID_PIOA 2 ;# Parallel IO Controller A -set AT91SAM9263_ID_PIOB 3 ;# Parallel IO Controller B -set AT91SAM9263_ID_PIOCDE 4 ;# Parallel IO Controller C, D and E -set AT91SAM9263_ID_US0 7 ;# USART 0 -set AT91SAM9263_ID_US1 8 ;# USART 1 -set AT91SAM9263_ID_US2 9 ;# USART 2 -set AT91SAM9263_ID_MCI0 10 ;# Multimedia Card Interface 0 -set AT91SAM9263_ID_MCI1 11 ;# Multimedia Card Interface 1 -set AT91SAM9263_ID_CAN 12 ;# CAN -set AT91SAM9263_ID_TWI 13 ;# Two-Wire Interface -set AT91SAM9263_ID_SPI0 14 ;# Serial Peripheral Interface 0 -set AT91SAM9263_ID_SPI1 15 ;# Serial Peripheral Interface 1 -set AT91SAM9263_ID_SSC0 16 ;# Serial Synchronous Controller 0 -set AT91SAM9263_ID_SSC1 17 ;# Serial Synchronous Controller 1 -set AT91SAM9263_ID_AC97C 18 ;# AC97 Controller -set AT91SAM9263_ID_TCB 19 ;# Timer Counter 0, 1 and 2 -set AT91SAM9263_ID_PWMC 20 ;# Pulse Width Modulation Controller -set AT91SAM9263_ID_EMAC 21 ;# Ethernet -set AT91SAM9263_ID_2DGE 23 ;# 2D Graphic Engine -set AT91SAM9263_ID_UDP 24 ;# USB Device Port -set AT91SAM9263_ID_ISI 25 ;# Image Sensor Interface -set AT91SAM9263_ID_LCDC 26 ;# LCD Controller -set AT91SAM9263_ID_DMA 27 ;# DMA Controller -set AT91SAM9263_ID_UHP 29 ;# USB Host port -set AT91SAM9263_ID_IRQ0 30 ;# Advanced Interrupt Controller (IRQ0) -set AT91SAM9263_ID_IRQ1 31 ;# Advanced Interrupt Controller (IRQ1) - - -# -# User Peripheral physical base addresses. -# -set AT91SAM9263_BASE_UDP 0xfff78000 -set AT91SAM9263_BASE_TCB0 0xfff7c000 -set AT91SAM9263_BASE_TC0 0xfff7c000 -set AT91SAM9263_BASE_TC1 0xfff7c040 -set AT91SAM9263_BASE_TC2 0xfff7c080 -set AT91SAM9263_BASE_MCI0 0xfff80000 -set AT91SAM9263_BASE_MCI1 0xfff84000 -set AT91SAM9263_BASE_TWI 0xfff88000 -set AT91SAM9263_BASE_US0 0xfff8c000 -set AT91SAM9263_BASE_US1 0xfff90000 -set AT91SAM9263_BASE_US2 0xfff94000 -set AT91SAM9263_BASE_SSC0 0xfff98000 -set AT91SAM9263_BASE_SSC1 0xfff9c000 -set AT91SAM9263_BASE_AC97C 0xfffa0000 -set AT91SAM9263_BASE_SPI0 0xfffa4000 -set AT91SAM9263_BASE_SPI1 0xfffa8000 -set AT91SAM9263_BASE_CAN 0xfffac000 -set AT91SAM9263_BASE_PWMC 0xfffb8000 -set AT91SAM9263_BASE_EMAC 0xfffbc000 -set AT91SAM9263_BASE_ISI 0xfffc4000 -set AT91SAM9263_BASE_2DGE 0xfffc8000 -set AT91_BASE_SYS 0xffffe000 - -# -# System Peripherals (offset from AT91_BASE_SYS) -# -set AT91_ECC0 0xffffe000 -set AT91_SDRAMC0 0xffffe200 -set AT91_SMC0 0xffffe400 -set AT91_ECC1 0xffffe600 -set AT91_SDRAMC1 0xffffe800 -set AT91_SMC1 0xffffea00 -set AT91_MATRIX 0xffffec00 -set AT91_CCFG 0xffffed10 -set AT91_DBGU 0xffffee00 -set AT91_AIC 0xfffff000 -set AT91_PIOA 0xfffff200 -set AT91_PIOB 0xfffff400 -set AT91_PIOC 0xfffff600 -set AT91_PIOD 0xfffff800 -set AT91_PIOE 0xfffffa00 -set AT91_PMC 0xfffffc00 -set AT91_RSTC 0xfffffd00 -set AT91_SHDWC 0xfffffd10 -set AT91_RTT0 0xfffffd20 -set AT91_PIT 0xfffffd30 -set AT91_WDT 0xfffffd40 -set AT91_RTT1 0xfffffd50 -set AT91_GPBR 0xfffffd60 - -set AT91_USART0 $AT91SAM9263_BASE_US0 -set AT91_USART1 $AT91SAM9263_BASE_US1 -set AT91_USART2 $AT91SAM9263_BASE_US2 - -set AT91_SMC $AT91_SMC0 -set AT91_SDRAMC $AT91_SDRAMC0 - -# -# Internal Memory. -# -set AT91SAM9263_SRAM0_BASE 0x00300000 ;# Internal SRAM 0 base address -set AT91SAM9263_SRAM0_SIZE 0x00014000 ;# Internal SRAM 0 size (80Kb) - -set AT91SAM9263_ROM_BASE 0x00400000 ;# Internal ROM base address -set AT91SAM9263_ROM_SIZE 0x00020000 ;# Internal ROM size (128Kb) - -set AT91SAM9263_SRAM1_BASE 0x00500000 ;# Internal SRAM 1 base address -set AT91SAM9263_SRAM1_SIZE 0x00004000 ;# Internal SRAM 1 size (16Kb) - -set AT91SAM9263_LCDC_BASE 0x00700000 ;# LCD Controller -set AT91SAM9263_DMAC_BASE 0x00800000 ;# DMA Controller -set AT91SAM9263_UHP_BASE 0x00a00000 ;# USB Host controller - -# -# Cpu Name -# -set AT91_CPU_NAME "AT91SAM9263" diff --git a/tcl/chip/atmel/at91/at91sam9263_matrix.cfg b/tcl/chip/atmel/at91/at91sam9263_matrix.cfg deleted file mode 100644 index ad3d9a2a3..000000000 --- a/tcl/chip/atmel/at91/at91sam9263_matrix.cfg +++ /dev/null @@ -1,112 +0,0 @@ -set AT91_MATRIX_MCFG0 [expr ($AT91_MATRIX + 0x00)] ;# Master Configuration Register 0 -set AT91_MATRIX_MCFG1 [expr ($AT91_MATRIX + 0x04)] ;# Master Configuration Register 1 -set AT91_MATRIX_MCFG2 [expr ($AT91_MATRIX + 0x08)] ;# Master Configuration Register 2 -set AT91_MATRIX_MCFG3 [expr ($AT91_MATRIX + 0x0C)] ;# Master Configuration Register 3 -set AT91_MATRIX_MCFG4 [expr ($AT91_MATRIX + 0x10)] ;# Master Configuration Register 4 -set AT91_MATRIX_MCFG5 [expr ($AT91_MATRIX + 0x14)] ;# Master Configuration Register 5 -set AT91_MATRIX_MCFG6 [expr ($AT91_MATRIX + 0x18)] ;# Master Configuration Register 6 -set AT91_MATRIX_MCFG7 [expr ($AT91_MATRIX + 0x1C)] ;# Master Configuration Register 7 -set AT91_MATRIX_MCFG8 [expr ($AT91_MATRIX + 0x20)] ;# Master Configuration Register 8 -set AT91_MATRIX_ULBT [expr (7 << 0)] ;# Undefined Length Burst Type -set AT91_MATRIX_ULBT_INFINITE [expr (0 << 0)] -set AT91_MATRIX_ULBT_SINGLE [expr (1 << 0)] -set AT91_MATRIX_ULBT_FOUR [expr (2 << 0)] -set AT91_MATRIX_ULBT_EIGHT [expr (3 << 0)] -set AT91_MATRIX_ULBT_SIXTEEN [expr (4 << 0)] - -set AT91_MATRIX_SCFG0 [expr ($AT91_MATRIX + 0x40)] ;# Slave Configuration Register 0 -set AT91_MATRIX_SCFG1 [expr ($AT91_MATRIX + 0x44)] ;# Slave Configuration Register 1 -set AT91_MATRIX_SCFG2 [expr ($AT91_MATRIX + 0x48)] ;# Slave Configuration Register 2 -set AT91_MATRIX_SCFG3 [expr ($AT91_MATRIX + 0x4C)] ;# Slave Configuration Register 3 -set AT91_MATRIX_SCFG4 [expr ($AT91_MATRIX + 0x50)] ;# Slave Configuration Register 4 -set AT91_MATRIX_SCFG5 [expr ($AT91_MATRIX + 0x54)] ;# Slave Configuration Register 5 -set AT91_MATRIX_SCFG6 [expr ($AT91_MATRIX + 0x58)] ;# Slave Configuration Register 6 -set AT91_MATRIX_SCFG7 [expr ($AT91_MATRIX + 0x5C)] ;# Slave Configuration Register 7 -set AT91_MATRIX_SLOT_CYCLE [expr (0xff << 0)] ;# Maximum Number of Allowed Cycles for a Burst -set AT91_MATRIX_DEFMSTR_TYPE [expr (3 << 16)] ;# Default Master Type -set AT91_MATRIX_DEFMSTR_TYPE_NONE [expr (0 << 16)] -set AT91_MATRIX_DEFMSTR_TYPE_LAST [expr (1 << 16)] -set AT91_MATRIX_DEFMSTR_TYPE_FIXED [expr (2 << 16)] -set AT91_MATRIX_FIXED_DEFMSTR [expr (0xf << 18)] ;# Fixed Index of Default Master -set AT91_MATRIX_ARBT [expr (3 << 24)] ;# Arbitration Type -set AT91_MATRIX_ARBT_ROUND_ROBIN [expr (0 << 24)] -set AT91_MATRIX_ARBT_FIXED_PRIORITY [expr (1 << 24)] - -set AT91_MATRIX_PRAS0 [expr ($AT91_MATRIX + 0x80)] ;# Priority Register A for Slave 0 -set AT91_MATRIX_PRBS0 [expr ($AT91_MATRIX + 0x84)] ;# Priority Register B for Slave 0 -set AT91_MATRIX_PRAS1 [expr ($AT91_MATRIX + 0x88)] ;# Priority Register A for Slave 1 -set AT91_MATRIX_PRBS1 [expr ($AT91_MATRIX + 0x8C)] ;# Priority Register B for Slave 1 -set AT91_MATRIX_PRAS2 [expr ($AT91_MATRIX + 0x90)] ;# Priority Register A for Slave 2 -set AT91_MATRIX_PRBS2 [expr ($AT91_MATRIX + 0x94)] ;# Priority Register B for Slave 2 -set AT91_MATRIX_PRAS3 [expr ($AT91_MATRIX + 0x98)] ;# Priority Register A for Slave 3 -set AT91_MATRIX_PRBS3 [expr ($AT91_MATRIX + 0x9C)] ;# Priority Register B for Slave 3 -set AT91_MATRIX_PRAS4 [expr ($AT91_MATRIX + 0xA0)] ;# Priority Register A for Slave 4 -set AT91_MATRIX_PRBS4 [expr ($AT91_MATRIX + 0xA4)] ;# Priority Register B for Slave 4 -set AT91_MATRIX_PRAS5 [expr ($AT91_MATRIX + 0xA8)] ;# Priority Register A for Slave 5 -set AT91_MATRIX_PRBS5 [expr ($AT91_MATRIX + 0xAC)] ;# Priority Register B for Slave 5 -set AT91_MATRIX_PRAS6 [expr ($AT91_MATRIX + 0xB0)] ;# Priority Register A for Slave 6 -set AT91_MATRIX_PRBS6 [expr ($AT91_MATRIX + 0xB4)] ;# Priority Register B for Slave 6 -set AT91_MATRIX_PRAS7 [expr ($AT91_MATRIX + 0xB8)] ;# Priority Register A for Slave 7 -set AT91_MATRIX_PRBS7 [expr ($AT91_MATRIX + 0xBC)] ;# Priority Register B for Slave 7 -set AT91_MATRIX_M0PR [expr (3 << 0)] ;# Master 0 Priority -set AT91_MATRIX_M1PR [expr (3 << 4)] ;# Master 1 Priority -set AT91_MATRIX_M2PR [expr (3 << 8)] ;# Master 2 Priority -set AT91_MATRIX_M3PR [expr (3 << 12)] ;# Master 3 Priority -set AT91_MATRIX_M4PR [expr (3 << 16)] ;# Master 4 Priority -set AT91_MATRIX_M5PR [expr (3 << 20)] ;# Master 5 Priority -set AT91_MATRIX_M6PR [expr (3 << 24)] ;# Master 6 Priority -set AT91_MATRIX_M7PR [expr (3 << 28)] ;# Master 7 Priority -set AT91_MATRIX_M8PR [expr (3 << 0)] ;# Master 8 Priority (in Register B) - -set AT91_MATRIX_MRCR [expr ($AT91_MATRIX + 0x100)] ;# Master Remap Control Register -set AT91_MATRIX_RCB0 [expr (1 << 0)] ;# Remap Command for AHB Master 0 (ARM926EJ-S Instruction Master) -set AT91_MATRIX_RCB1 [expr (1 << 1)] ;# Remap Command for AHB Master 1 (ARM926EJ-S Data Master) -set AT91_MATRIX_RCB2 [expr (1 << 2)] -set AT91_MATRIX_RCB3 [expr (1 << 3)] -set AT91_MATRIX_RCB4 [expr (1 << 4)] -set AT91_MATRIX_RCB5 [expr (1 << 5)] -set AT91_MATRIX_RCB6 [expr (1 << 6)] -set AT91_MATRIX_RCB7 [expr (1 << 7)] -set AT91_MATRIX_RCB8 [expr (1 << 8)] - -set AT91_MATRIX_TCMR [expr ($AT91_MATRIX + 0x114)] ;# TCM Configuration Register -set AT91_MATRIX_ITCM_SIZE [expr (0xf << 0)] ;# Size of ITCM enabled memory block -set AT91_MATRIX_ITCM_0 [expr (0 << 0)] -set AT91_MATRIX_ITCM_16 [expr (5 << 0)] -set AT91_MATRIX_ITCM_32 [expr (6 << 0)] -set AT91_MATRIX_DTCM_SIZE [expr (0xf << 4)] ;# Size of DTCM enabled memory block -set AT91_MATRIX_DTCM_0 [expr (0 << 4)] -set AT91_MATRIX_DTCM_16 [expr (5 << 4)] -set AT91_MATRIX_DTCM_32 [expr (6 << 4)] - -set AT91_MATRIX_EBI0CSA [expr ($AT91_MATRIX + 0x120)] ;# EBI0 Chip Select Assignment Register -set AT91_MATRIX_EBI0_CS1A [expr (1 << 1)] ;# Chip Select 1 Assignment -set AT91_MATRIX_EBI0_CS1A_SMC [expr (0 << 1)] -set AT91_MATRIX_EBI0_CS1A_SDRAMC [expr (1 << 1)] -set AT91_MATRIX_EBI0_CS3A [expr (1 << 3)] ;# Chip Select 3 Assignmen -set AT91_MATRIX_EBI0_CS3A_SMC [expr (0 << 3)] -set AT91_MATRIX_EBI0_CS3A_SMC_SMARTMEDIA [expr (1 << 3)] -set AT91_MATRIX_EBI0_CS4A [expr (1 << 4)] ;# Chip Select 4 Assignment -set AT91_MATRIX_EBI0_CS4A_SMC [expr (0 << 4)] -set AT91_MATRIX_EBI0_CS4A_SMC_CF1 [expr (1 << 4)] -set AT91_MATRIX_EBI0_CS5A [expr (1 << 5)] ;# Chip Select 5 Assignment -set AT91_MATRIX_EBI0_CS5A_SMC [expr (0 << 5)] -set AT91_MATRIX_EBI0_CS5A_SMC_CF2 [expr (1 << 5)] -set AT91_MATRIX_EBI0_DBPUC [expr (1 << 8)] ;# Data Bus Pull-up Configuration -set AT91_MATRIX_EBI0_VDDIOMSEL [expr (1 << 16)] ;# Memory voltage selection -set AT91_MATRIX_EBI0_VDDIOMSEL_1_8V [expr (0 << 16)] -set AT91_MATRIX_EBI0_VDDIOMSEL_3_3V [expr (1 << 16)] - -set AT91_MATRIX_EBI1CSA [expr ($AT91_MATRIX + 0x124)] ;# EBI1 Chip Select Assignment Register -set AT91_MATRIX_EBI1_CS1A [expr (1 << 1)] ;# Chip Select 1 Assignment -set AT91_MATRIX_EBI1_CS1A_SMC [expr (0 << 1)] -set AT91_MATRIX_EBI1_CS1A_SDRAMC [expr (1 << 1)] -set AT91_MATRIX_EBI1_CS2A [expr (1 << 3)] ;# Chip Select 3 Assignment -set AT91_MATRIX_EBI1_CS2A_SMC [expr (0 << 3)] -set AT91_MATRIX_EBI1_CS2A_SMC_SMARTMEDIA [expr (1 << 3)] -set AT91_MATRIX_EBI1_DBPUC [expr (1 << 8)] ;# Data Bus Pull-up Configuration -set AT91_MATRIX_EBI1_VDDIOMSEL [expr (1 << 16)] ;# Memory voltage selection -set AT91_MATRIX_EBI1_VDDIOMSEL_1_8V [expr (0 << 16)] -set AT91_MATRIX_EBI1_VDDIOMSEL_3_3V [expr (1 << 16)] - - diff --git a/tcl/chip/atmel/at91/at91sam9_init.cfg b/tcl/chip/atmel/at91/at91sam9_init.cfg deleted file mode 100644 index 2d78d241d..000000000 --- a/tcl/chip/atmel/at91/at91sam9_init.cfg +++ /dev/null @@ -1,95 +0,0 @@ -uplevel #0 [list source [find chip/atmel/at91/at91sam9_sdramc.cfg]] -uplevel #0 [list source [find chip/atmel/at91/at91_pmc.cfg]] -uplevel #0 [list source [find chip/atmel/at91/at91_pio.cfg]] -uplevel #0 [list source [find chip/atmel/at91/at91_rstc.cfg]] -uplevel #0 [list source [find chip/atmel/at91/at91_wdt.cfg]] - -proc at91sam9_reset_start { } { - - arm7_9 fast_memory_access disable - - jtag_rclk 8 - halt - wait_halt 10000 - set rstc_mr_val [expr $::AT91_RSTC_KEY] - set rstc_mr_val [expr ($rstc_mr_val | (5 << 8))] - set rstc_mr_val [expr ($rstc_mr_val | $::AT91_RSTC_URSTEN)] - mww $::AT91_RSTC_MR $rstc_mr_val ;# RSTC_MR : enable user reset. -} - -proc at91sam9_reset_init { config } { - - mww $::AT91_WDT_MR $config(wdt_mr_val) ;# disable watchdog - - set ckgr_mor [expr ($::AT91_PMC_MOSCEN | (255 << 8))] - - mww $::AT91_CKGR_MOR $ckgr_mor ;# CKGR_MOR - enable main osc. - while { [expr [mrw $::AT91_PMC_SR] & $::AT91_PMC_MOSCS] != $::AT91_PMC_MOSCS } { sleep 1 } - - set pllar_val [expr $::AT91_PMC_PLLA_WR_ERRATA] ;# Bit 29 must be 1 when prog - set pllar_val [expr ($pllar_val | $::AT91_PMC_OUT)] - set pllar_val [expr ($pllar_val | $::AT91_PMC_PLLCOUNT)] - set pllar_val [expr ($pllar_val | ($config(master_pll_mul) - 1) << 16)] - set pllar_val [expr ($pllar_val | $config(master_pll_div))] - - mww $::AT91_CKGR_PLLAR $pllar_val ;# CKGR_PLLA - (18.432MHz/13)*141 = 199.9 MHz - while { [expr [mrw $::AT91_PMC_SR] & $::AT91_PMC_LOCKA] != $::AT91_PMC_LOCKA } { sleep 1 } - - ;# PCK/2 = MCK Master Clock from PLLA - set mckr_val [expr $::AT91_PMC_CSS_PLLA] - set mckr_val [expr ($mckr_val | $::AT91_PMC_PRES_1)] - set mckr_val [expr ($mckr_val | $::AT91SAM9_PMC_MDIV_2)] - set mckr_val [expr ($mckr_val | $::AT91_PMC_PDIV_1)] - - mww $::AT91_PMC_MCKR $mckr_val ;# PMC_MCKR (MCLK: 0x102 - (CLK/2)MHZ, 0x202 - (CLK/3)MHz) - while { [expr [mrw $::AT91_PMC_SR] & $::AT91_PMC_MCKRDY] != $::AT91_PMC_MCKRDY } { sleep 1 } - - ## switch JTAG clock to highspeed clock - jtag_rclk 0 - - arm7_9 dcc_downloads enable ;# Enable faster DCC downloads - arm7_9 fast_memory_access enable - - set rstc_mr_val [expr ($::AT91_RSTC_KEY)] - set rstc_mr_val [expr ($rstc_mr_val | $::AT91_RSTC_URSTEN)] - mww $::AT91_RSTC_MR $rstc_mr_val ;# user reset enable - - if { [info exists config(sdram_piod)] } { - set pdr_addr [expr ($::AT91_PIOD + $::PIO_PDR)] - set pudr_addr [expr ($::AT91_PIOD + $::PIO_PUDR)] - set asr_addr [expr ($::AT91_PIOD + $::PIO_ASR)] - mww $pdr_addr 0xffff0000 ;# define PDC[31:16] as DATA[31:16] - mww $pudr_addr 0xffff0000 ;# no pull-up for D[31:16] - mww $asr_addr 0xffff0000 - } else { - set pdr_addr [expr ($::AT91_PIOC + $::PIO_PDR)] - set pudr_addr [expr ($::AT91_PIOC + $::PIO_PUDR)] - mww $pdr_addr 0xffff0000 ;# define PDC[31:16] as DATA[31:16] - mww $pudr_addr 0xffff0000 ;# no pull-up for D[31:16] - } - - mww $config(matrix_ebicsa_addr) $config(matrix_ebicsa_val) - mww $::AT91_SDRAMC_MR $::AT91_SDRAMC_MODE_NORMAL ;# SDRAMC_MR Mode register - mww $::AT91_SDRAMC_TR $config(sdram_tr_val) ;# SDRAMC_TR - Refresh Timer register - mww $::AT91_SDRAMC_CR $config(sdram_cr_val) ;# SDRAMC_CR - Configuration register - mww $::AT91_SDRAMC_MDR $::AT91_SDRAMC_MD_SDRAM ;# Memory Device Register -> SDRAM - mww $::AT91_SDRAMC_MR $::AT91_SDRAMC_MODE_PRECHARGE ;# SDRAMC_MR - mww $config(sdram_base) 0 ;# SDRAM_BASE - mww $::AT91_SDRAMC_MR $::AT91_SDRAMC_MODE_REFRESH ;# SDRC_MR - mww $config(sdram_base) 0 ;# SDRAM_BASE - mww $config(sdram_base) 0 ;# SDRAM_BASE - mww $config(sdram_base) 0 ;# SDRAM_BASE - mww $config(sdram_base) 0 ;# SDRAM_BASE - mww $config(sdram_base) 0 ;# SDRAM_BASE - mww $config(sdram_base) 0 ;# SDRAM_BASE - mww $config(sdram_base) 0 ;# SDRAM_BASE - mww $config(sdram_base) 0 ;# SDRAM_BASE - mww $::AT91_SDRAMC_MR $::AT91_SDRAMC_MODE_LMR ;# SDRC_MR - mww $config(sdram_base) 0 ;# SDRAM_BASE - mww $::AT91_SDRAMC_MR $::AT91_SDRAMC_MODE_NORMAL ;# SDRC_MR - mww $config(sdram_base) 0 ;# SDRAM_BASE - mww $::AT91_SDRAMC_TR 1200 ;# SDRAM_TR - mww $config(sdram_base) 0 ;# SDRAM_BASE - - mww $::AT91_MATRIX 0xf ;# MATRIX_MCFG - REMAP all masters -} diff --git a/tcl/chip/atmel/at91/at91sam9_sdramc.cfg b/tcl/chip/atmel/at91/at91sam9_sdramc.cfg deleted file mode 100644 index dbca497b2..000000000 --- a/tcl/chip/atmel/at91/at91sam9_sdramc.cfg +++ /dev/null @@ -1,66 +0,0 @@ - -# SDRAM Controller (SDRAMC) registers -set AT91_SDRAMC_MR [expr ($AT91_SDRAMC + 0x00)] ;# SDRAM Controller Mode Register -set AT91_SDRAMC_MODE [expr (0xf << 0)] ;# Command Mode -set AT91_SDRAMC_MODE_NORMAL 0 -set AT91_SDRAMC_MODE_NOP 1 -set AT91_SDRAMC_MODE_PRECHARGE 2 -set AT91_SDRAMC_MODE_LMR 3 -set AT91_SDRAMC_MODE_REFRESH 4 -set AT91_SDRAMC_MODE_EXT_LMR 5 -set AT91_SDRAMC_MODE_DEEP 6 - -set AT91_SDRAMC_TR [expr ($AT91_SDRAMC + 0x04)] ;# SDRAM Controller Refresh Timer Register -set AT91_SDRAMC_COUNT [expr (0xfff << 0)] ;# Refresh Timer Counter - -set AT91_SDRAMC_CR [expr ($AT91_SDRAMC + 0x08)] ;# SDRAM Controller Configuration Register -set AT91_SDRAMC_NC [expr (3 << 0)] ;# Number of Column Bits -set AT91_SDRAMC_NC_8 [expr (0 << 0)] -set AT91_SDRAMC_NC_9 [expr (1 << 0)] -set AT91_SDRAMC_NC_10 [expr (2 << 0)] -set AT91_SDRAMC_NC_11 [expr (3 << 0)] -set AT91_SDRAMC_NR [expr (3 << 2)] ;# Number of Row Bits -set AT91_SDRAMC_NR_11 [expr (0 << 2)] -set AT91_SDRAMC_NR_12 [expr (1 << 2)] -set AT91_SDRAMC_NR_13 [expr (2 << 2)] -set AT91_SDRAMC_NB [expr (1 << 4)] ;# Number of Banks -set AT91_SDRAMC_NB_2 [expr (0 << 4)] -set AT91_SDRAMC_NB_4 [expr (1 << 4)] -set AT91_SDRAMC_CAS [expr (3 << 5)] ;# CAS Latency -set AT91_SDRAMC_CAS_1 [expr (1 << 5)] -set AT91_SDRAMC_CAS_2 [expr (2 << 5)] -set AT91_SDRAMC_CAS_3 [expr (3 << 5)] -set AT91_SDRAMC_DBW [expr (1 << 7)] ;# Data Bus Width -set AT91_SDRAMC_DBW_32 [expr (0 << 7)] -set AT91_SDRAMC_DBW_16 [expr (1 << 7)] -set AT91_SDRAMC_TWR [expr (0xf << 8)] ;# Write Recovery Delay -set AT91_SDRAMC_TRC [expr (0xf << 12)] ;# Row Cycle Delay -set AT91_SDRAMC_TRP [expr (0xf << 16)] ;# Row Precharge Delay -set AT91_SDRAMC_TRCD [expr (0xf << 20)] ;# Row to Column Delay -set AT91_SDRAMC_TRAS [expr (0xf << 24)] ;# Active to Precharge Delay -set AT91_SDRAMC_TXSR [expr (0xf << 28)] ;# Exit Self Refresh to Active Delay - -set AT91_SDRAMC_LPR [expr ($AT91_SDRAMC + 0x10)] ;# SDRAM Controller Low Power Register -set AT91_SDRAMC_LPCB [expr (3 << 0)] ;# Low-power Configurations -set AT91_SDRAMC_LPCB_DISABLE 0 -set AT91_SDRAMC_LPCB_SELF_REFRESH 1 -set AT91_SDRAMC_LPCB_POWER_DOWN 2 -set AT91_SDRAMC_LPCB_DEEP_POWER_DOWN 3 -set AT91_SDRAMC_PASR [expr (7 << 4)] ;# Partial Array Self Refresh -set AT91_SDRAMC_TCSR [expr (3 << 8)] ;# Temperature Compensated Self Refresh -set AT91_SDRAMC_DS [expr (3 << 10)] ;# Drive Strength -set AT91_SDRAMC_TIMEOUT [expr (3 << 12)] ;# Time to define when Low Power Mode is enabled -set AT91_SDRAMC_TIMEOUT_0_CLK_CYCLES [expr (0 << 12)] -set AT91_SDRAMC_TIMEOUT_64_CLK_CYCLES [expr (1 << 12)] -set AT91_SDRAMC_TIMEOUT_128_CLK_CYCLES [expr (2 << 12)] - -set AT91_SDRAMC_IER [expr ($AT91_SDRAMC + 0x14)] ;# SDRAM Controller Interrupt Enable Register -set AT91_SDRAMC_IDR [expr ($AT91_SDRAMC + 0x18)] ;# SDRAM Controller Interrupt Disable Register -set AT91_SDRAMC_IMR [expr ($AT91_SDRAMC + 0x1C)] ;# SDRAM Controller Interrupt Mask Register -set AT91_SDRAMC_ISR [expr ($AT91_SDRAMC + 0x20)] ;# SDRAM Controller Interrupt Status Register -set AT91_SDRAMC_RES [expr (1 << 0)] ;# Refresh Error Status - -set AT91_SDRAMC_MDR [expr ($AT91_SDRAMC + 0x24)] ;# SDRAM Memory Device Register -set AT91_SDRAMC_MD [expr (3 << 0)] ;# Memory Device Type -set AT91_SDRAMC_MD_SDRAM 0 -set AT91_SDRAMC_MD_LOW_POWER_SDRAM 1 diff --git a/tcl/chip/atmel/at91/at91sam9_smc.cfg b/tcl/chip/atmel/at91/at91sam9_smc.cfg deleted file mode 100644 index 7dc763858..000000000 --- a/tcl/chip/atmel/at91/at91sam9_smc.cfg +++ /dev/null @@ -1,20 +0,0 @@ -set AT91_SMC_READMODE [expr (1 << 0)] ;# Read Mode -set AT91_SMC_WRITEMODE [expr (1 << 1)] ;# Write Mode -set AT91_SMC_EXNWMODE [expr (3 << 4)] ;# NWAIT Mode -set AT91_SMC_EXNWMODE_DISABLE [expr (0 << 4)] -set AT91_SMC_EXNWMODE_FROZEN [expr (2 << 4)] -set AT91_SMC_EXNWMODE_READY [expr (3 << 4)] -set AT91_SMC_BAT [expr (1 << 8)] ;# Byte Access Type -set AT91_SMC_BAT_SELECT [expr (0 << 8)] -set AT91_SMC_BAT_WRITE [expr (1 << 8)] -set AT91_SMC_DBW [expr (3 << 12)] ;# Data Bus Width */ -set AT91_SMC_DBW_8 [expr (0 << 12)] -set AT91_SMC_DBW_16 [expr (1 << 12)] -set AT91_SMC_DBW_32 [expr (2 << 12)] -set AT91_SMC_TDFMODE [expr (1 << 20)] ;# TDF Optimization - Enabled -set AT91_SMC_PMEN [expr (1 << 24)] ;# Page Mode Enabled -set AT91_SMC_PS [expr (3 << 28)] ;# Page Size -set AT91_SMC_PS_4 [expr (0 << 28)] -set AT91_SMC_PS_8 [expr (1 << 28)] -set AT91_SMC_PS_16 [expr (2 << 28)] -set AT91_SMC_PS_32 [expr (3 << 28)] diff --git a/tcl/chip/atmel/at91/hardware.cfg b/tcl/chip/atmel/at91/hardware.cfg deleted file mode 100644 index a25eab975..000000000 --- a/tcl/chip/atmel/at91/hardware.cfg +++ /dev/null @@ -1,9 +0,0 @@ -# External Memory Map -set AT91_CHIPSELECT_0 0x10000000 -set AT91_CHIPSELECT_1 0x20000000 -set AT91_CHIPSELECT_2 0x30000000 -set AT91_CHIPSELECT_3 0x40000000 -set AT91_CHIPSELECT_4 0x50000000 -set AT91_CHIPSELECT_5 0x60000000 -set AT91_CHIPSELECT_6 0x70000000 -set AT91_CHIPSELECT_7 0x80000000 diff --git a/tcl/chip/atmel/at91/pmc.tcl b/tcl/chip/atmel/at91/pmc.tcl deleted file mode 100644 index 584acb80b..000000000 --- a/tcl/chip/atmel/at91/pmc.tcl +++ /dev/null @@ -1,17 +0,0 @@ - -if [info exists AT91C_MAINOSC_FREQ] { - # user set this... let it be. -} { - # 18.432mhz is a common thing... - set AT91C_MAINOSC_FREQ 18432000 -} -global AT91C_MAINOSC_FREQ - -if [info exists AT91C_SLOWOSC_FREQ] { - # user set this... let it be. -} { - # 32khz is the norm - set AT91C_SLOWOSC_FREQ 32768 -} -global AT91C_SLOWOSC_FREQ - diff --git a/tcl/chip/atmel/at91/rtt.tcl b/tcl/chip/atmel/at91/rtt.tcl deleted file mode 100644 index 8be6a56b0..000000000 --- a/tcl/chip/atmel/at91/rtt.tcl +++ /dev/null @@ -1,56 +0,0 @@ - -set RTTC_RTMR [expr $AT91C_BASE_RTTC + 0x00] -set RTTC_RTAR [expr $AT91C_BASE_RTTC + 0x04] -set RTTC_RTVR [expr $AT91C_BASE_RTTC + 0x08] -set RTTC_RTSR [expr $AT91C_BASE_RTTC + 0x0c] -global RTTC_RTMR -global RTTC_RTAR -global RTTC_RTVR -global RTTC_RTSR - -proc show_RTTC_RTMR_helper { NAME ADDR VAL } { - set rtpres [expr $VAL & 0x0ffff] - global BIT16 BIT17 - if { $rtpres == 0 } { - set rtpres 65536; - } - global AT91C_SLOWOSC_FREQ - # Nasty hack, make this a float by tacking a .0 on the end - # otherwise, jim makes the value an integer - set f [expr $AT91C_SLOWOSC_FREQ.0 / $rtpres.0] - echo [format "\tPrescale value: 0x%04x (%5d) => %f Hz" $rtpres $rtpres $f] - if { $VAL & $BIT16 } { - echo "\tBit16 -> Alarm IRQ Enabled" - } else { - echo "\tBit16 -> Alarm IRQ Disabled" - } - if { $VAL & $BIT17 } { - echo "\tBit17 -> RTC Inc IRQ Enabled" - } else { - echo "\tBit17 -> RTC Inc IRQ Disabled" - } - # Bit 18 is write only. -} - -proc show_RTTC_RTSR_helper { NAME ADDR VAL } { - global BIT0 BIT1 - if { $VAL & $BIT0 } { - echo "\tBit0 -> ALARM PENDING" - } else { - echo "\tBit0 -> alarm not pending" - } - if { $VAL & $BIT1 } { - echo "\tBit0 -> RTINC PENDING" - } else { - echo "\tBit0 -> rtinc not pending" - } -} - -proc show_RTTC { } { - - show_mmr32_reg RTTC_RTMR - show_mmr32_reg RTTC_RTAR - show_mmr32_reg RTTC_RTVR - show_mmr32_reg RTTC_RTSR -} - diff --git a/tcl/chip/atmel/at91/sam9_smc.cfg b/tcl/chip/atmel/at91/sam9_smc.cfg deleted file mode 100644 index db943cb24..000000000 --- a/tcl/chip/atmel/at91/sam9_smc.cfg +++ /dev/null @@ -1,55 +0,0 @@ -# Setup register -# -# ncs_read_setup -# nrd_setup -# ncs_write_setup -# set nwe_setup -# -# -# Pulse register -# -# ncs_read_pulse -# nrd_pulse -# ncs_write_pulse -# nwe_pulse -# -# -# Cycle register -# -# read_cycle 0 -# write_cycle 0 -# -# -# Mode register -# -# mode -# tdf_cycles -proc sam9_smc_config { cs smc_config } { - ;# Setup Register for CS n - set AT91_SMC_SETUP [expr ($::AT91_SMC + 0x00 + ((cs)*0x10))] - set val [expr ($smc_config(nwe_setup) << 0)] - set val [expr ($val | $smc_config(ncs_write_setup) << 8] - set val [expr ($val | $smc_config(nrd_setup)) << 16] - set val [expr ($val | $smc_config(ncs_read_setup) << 24] - mww $AT91_SMC_SETUP $val - - ;# Pulse Register for CS n - set AT91_SMC_PULSE [expr ($::AT91_SMC + 0x04 + ((cs)*0x10))] - set val [expr ($smc_config(nwe_pulse) << 0)] - set val [expr ($val | $smc_config(ncs_write_pulse) << 8] - set val [expr ($val | $smc_config(nrd_pulse) << 16] - set val [expr ($val | $smc_config(ncs_read_pulse) << 24] - mww $AT91_SMC_PULSE $val - - ;# Cycle Register for CS n - set AT91_SMC_CYCLE [expr ($::AT91_SMC + 0x08 + ((cs)*0x10))] - set val [expr ($smc_config(write_cycle) << 0)] - set val [expr ($val | $smc_config(read_cycle) << 16] - mww $AT91_SMC_CYCLE $val - - ;# Mode Register for CS n - set AT91_SMC_MODE [expr ($::AT91_SMC + 0x0c + ((cs)*0x10))] - set val [expr ($smc_config(mode) << 0)] - set val [expr ($val | $smc_config(tdf_cycles) << 16] - mww $AT91_SMC_MODE $val -} diff --git a/tcl/chip/atmel/at91/usarts.tcl b/tcl/chip/atmel/at91/usarts.tcl deleted file mode 100644 index 68420292e..000000000 --- a/tcl/chip/atmel/at91/usarts.tcl +++ /dev/null @@ -1,135 +0,0 @@ -# the DBGU and USARTs are 'almost' indentical' -set DBGU_CR [expr $AT91C_BASE_DBGU + 0x00000000] -set DBGU_MR [expr $AT91C_BASE_DBGU + 0x00000004] -set DBGU_IER [expr $AT91C_BASE_DBGU + 0x00000008] -set DBGU_IDR [expr $AT91C_BASE_DBGU + 0x0000000C] -set DBGU_IMR [expr $AT91C_BASE_DBGU + 0x00000010] -set DBGU_CSR [expr $AT91C_BASE_DBGU + 0x00000014] -set DBGU_RHR [expr $AT91C_BASE_DBGU + 0x00000018] -set DBGU_THR [expr $AT91C_BASE_DBGU + 0x0000001C] -set DBGU_BRGR [expr $AT91C_BASE_DBGU + 0x00000020] -# no RTOR -# no TTGR -# no FIDI -# no NER -set DBGU_CIDR [expr $AT91C_BASE_DBGU + 0x00000040] -set DBGU_EXID [expr $AT91C_BASE_DBGU + 0x00000044] -set DBGU_FNTR [expr $AT91C_BASE_DBGU + 0x00000048] - - -set USx_CR 0x00000000 -set USx_MR 0x00000004 -set USx_IER 0x00000008 -set USx_IDR 0x0000000C -set USx_IMR 0x00000010 -set USx_CSR 0x00000014 -set USx_RHR 0x00000018 -set USx_THR 0x0000001C -set USx_BRGR 0x00000020 -set USx_RTOR 0x00000024 -set USx_TTGR 0x00000028 -set USx_FIDI 0x00000040 -set USx_NER 0x00000044 -set USx_IF 0x0000004C - -# Create all the uarts that exist.. -# we blow up if there are >9 - - -proc show_mmr_USx_MR_helper { NAME ADDR VAL } { - # First - just print it - - set x [show_normalize_bitfield $VAL 3 0] - if { $x == 0 } { - echo "\tNormal operation" - } else { - echo [format "\tNon Normal operation mode: 0x%02x" $x] - } - - set x [show_normalize_bitfield $VAL 11 9] - set s "unknown" - switch -exact $x { - 0 { set s "Even" } - 1 { set s "Odd" } - 2 { set s "Force=0" } - 3 { set s "Force=1" } - * { - set $x [expr $x & 6] - switch -exact $x { - 4 { set s "None" } - 6 { set s "Multidrop Mode" } - } - } - } - echo [format "\tParity: %s " $s] - - set x [expr 5 + [show_normalize_bitfield $VAL 7 6]] - echo [format "\tDatabits: %d" $x] - - set x [show_normalize_bitfield $VAL 13 12] - switch -exact $x { - 0 { echo "\tStop bits: 1" } - 1 { echo "\tStop bits: 1.5" } - 2 { echo "\tStop bits: 2" } - 3 { echo "\tStop bits: Illegal/Reserved" } - } -} - -# For every possbile usart... -foreach WHO { US0 US1 US2 US3 US4 US5 US6 US7 US8 US9 } { - set n AT91C_BASE_[set WHO] - set str "" - - # Only if it exists on the chip - if [ info exists $n ] { - # Hence: $n - is like AT91C_BASE_USx - # For every sub-register - foreach REG {CR MR IER IDR IMR CSR RHR THR BRGR RTOR TTGR FIDI NER IF} { - # vn = variable name - set vn [set WHO]_[set REG] - # vn = USx_IER - # vv = variable value - set vv [expr $$n + [set USx_[set REG]]] - # And VV is the address in memory of that register - - - # make that VN a GLOBAL so others can find it - global $vn - set $vn $vv - - # Create a command for this specific register. - proc show_$vn { } "show_mmr32_reg $vn" - - # Add this command to the Device(as a whole) command - set str "$str\nshow_$vn" - } - # Now - create the DEVICE(as a whole) command - set fn show_$WHO - proc $fn { } $str - } -} - -# The Debug Uart is special.. -set str "" - - -# For every sub-register -foreach REG {DBGU_CR DBGU_MR DBGU_IER DBGU_IDR DBGU_IMR - DBGU_CSR DBGU_RHR DBGU_THR DBGU_BRGR DBGU_CIDR DBGU_EXID DBGU_FNTR} { - - # Create a command for this specific register. - proc show_$REG { } "show_mmr32_reg $REG" - - # Add this command to the Device(as a whole) command - set str "$str\nshow_$REG" -} - -# Now - create the DEVICE(as a whole) command -proc show_DBGU { } $str - -unset str - -proc show_DBGU_MR_helper { NAME ADDR VAL } { show_mmr_USx_MR_helper $NAME $ADDR $VAL } - - - diff --git a/tcl/chip/st/spear/quirk_no_srst.tcl b/tcl/chip/st/spear/quirk_no_srst.tcl deleted file mode 100644 index fd02d07c1..000000000 --- a/tcl/chip/st/spear/quirk_no_srst.tcl +++ /dev/null @@ -1,75 +0,0 @@ -# Quirks to bypass missing SRST on JTAG connector -# EVALSPEAr310 Rev. 2.0 -# http://www.st.com/spear -# -# Date: 2010-08-17 -# Author: Antonio Borneo - -# For boards that have JTAG SRST not connected. -# We use "arm9 vector_catch reset" to catch button reset event. - - -$_TARGETNAME configure -event reset-assert sp_reset_assert -$_TARGETNAME configure -event reset-deassert-post sp_reset_deassert_post - -# keeps the name of the SPEAr target -global sp_target_name -set sp_target_name $_TARGETNAME - -# Keeps the argument of "reset" command (run, init, halt). -global sp_reset_mode -set sp_reset_mode "" - -# Helper procedure. Returns 0 is target is halted. -proc sp_is_halted {} { - global sp_target_name - - return [expr [string compare [$sp_target_name curstate] "halted" ] == 0] -} - -# wait for reset button to be pressed, causing CPU to get halted -proc sp_reset_deassert_post {} { - global sp_reset_mode - - set bar(0) | - set bar(1) / - set bar(2) - - set bar(3) \\ - - poll on - echo "====> Press reset button on the board <====" - for {set i 0} { [sp_is_halted] == 0 } { set i [expr $i + 1]} { - echo -n "$bar([expr $i & 3])\r" - sleep 200 - } - - # Remove catch reset event - arm9 vector_catch none - - # CPU is halted, but we typed "reset run" ... - if { [string compare $sp_reset_mode "run"] == 0 } { - resume - } -} - -# Override reset-assert, since no SRST available -# Catch reset event -proc sp_reset_assert {} { - arm9 vector_catch reset -} - -# Override default init_reset{mode} to catch parameter "mode" -proc init_reset {mode} { - global sp_reset_mode - - set sp_reset_mode $mode - - # We need to detect CPU get halted, so exit from halt - if { [sp_is_halted] } { - echo "Resuming CPU to detect reset" - resume - } - - # Execute default init_reset{mode} - jtag arp_init-reset -} diff --git a/tcl/chip/st/spear/spear3xx.tcl b/tcl/chip/st/spear/spear3xx.tcl deleted file mode 100644 index ef3884137..000000000 --- a/tcl/chip/st/spear/spear3xx.tcl +++ /dev/null @@ -1,129 +0,0 @@ -# Generic init scripts for all ST SPEAr3xx family -# http://www.st.com/spear -# -# Date: 2010-09-23 -# Author: Antonio Borneo - - -# Initialize internal clock -# Default: -# - Crystal = 24 MHz -# - PLL1 = 332 MHz -# - PLL2 = 332 MHz -# - CPU_CLK = 332 MHz -# - DDR_CLK = 332 MHz async -# - HCLK = 166 MHz -# - PCLK = 83 MHz -proc sp3xx_clock_default {} { - mww 0xfca00000 0x00000002 ;# set sysclk slow - mww 0xfca00014 0x0ffffff8 ;# set pll timeout to minimum (100us ?!?) - - # DDRCORE disable to change frequency - set val [expr ([mrw 0xfca8002c] & ~0x20000000) | 0x40000000] - mww 0xfca8002c $val - mww 0xfca8002c $val ;# Yes, write twice! - - # programming PLL1 - mww 0xfca8000c 0xa600010c ;# M=166 P=1 N=12 - mww 0xfca80008 0x00001c0a ;# power down - mww 0xfca80008 0x00001c0e ;# enable - mww 0xfca80008 0x00001c06 ;# strobe - mww 0xfca80008 0x00001c0e - while { [expr [mrw 0xfca80008] & 0x01] == 0x00 } { sleep 1 } - - # programming PLL2 - mww 0xfca80018 0xa600010c ;# M=166, P=1, N=12 - mww 0xfca80014 0x00001c0a ;# power down - mww 0xfca80014 0x00001c0e ;# enable - mww 0xfca80014 0x00001c06 ;# strobe - mww 0xfca80014 0x00001c0e - while { [expr [mrw 0xfca80014] & 0x01] == 0x00 } { sleep 1 } - - mww 0xfca80028 0x00000082 ;# enable plltimeen - mww 0xfca80024 0x00000511 ;# set hclkdiv="/2" & pclkdiv="/2" - - mww 0xfca00000 0x00000004 ;# setting SYSCTL to NORMAL mode - while { [expr [mrw 0xfca00000] & 0x20] != 0x20 } { sleep 1 } - - # Select source of DDR clock - #mmw 0xfca80020 0x10000000 0x70000000 ;# PLL1 - mmw 0xfca80020 0x30000000 0x70000000 ;# PLL2 - - # DDRCORE enable after change frequency - mmw 0xfca8002c 0x20000000 0x00000000 -} - -proc sp3xx_common_init {} { - mww 0xfca8002c 0xfffffff8 ;# enable clock of all peripherals - mww 0xfca80038 0x00000000 ;# remove reset of all peripherals - - mww 0xfca80034 0x0000ffff ;# enable all RAS clocks - mww 0xfca80040 0x00000000 ;# remove all RAS resets - - mww 0xfca800e4 0x78000008 ;# COMP1V8_REG - mww 0xfca800ec 0x78000008 ;# COMP3V3_REG - - mww 0xfc000000 0x10000f5f ;# init SMI and set HW mode - mww 0xfc000000 0x00000f5f - - # Initialize Bus Interconnection Matrix - # All ports Round-Robin and lowest priority - mww 0xfca8007c 0x80000007 - mww 0xfca80080 0x80000007 - mww 0xfca80084 0x80000007 - mww 0xfca80088 0x80000007 - mww 0xfca8008c 0x80000007 - mww 0xfca80090 0x80000007 - mww 0xfca80094 0x80000007 - mww 0xfca80098 0x80000007 - mww 0xfca8009c 0x80000007 -} - - -# Specific init scripts for ST SPEAr300 -proc sp300_init {} { - mww 0x99000000 0x00003fff ;# RAS function enable -} - - -# Specific init scripts for ST SPEAr310 -proc sp310_init {} { - mww 0xb4000008 0x00002ff4 ;# RAS function enable - - mww 0xfca80050 0x00000001 ;# Enable clk mem port 1 - - mww 0xfca8013c 0x2f7bc210 ;# plgpio_pad_drv - mww 0xfca80140 0x017bdef6 -} - -proc sp310_emi_init {} { - # set EMI pad strength - mmw 0xfca80134 0x0e000000 0x00000000 - mmw 0xfca80138 0x0e739ce7 0x00000000 - mmw 0xfca8013c 0x00039ce7 0x00000000 - - # set safe EMI timing as in BootROM - #mww 0x4f000000 0x0000000f ;# tAP_0_reg - #mww 0x4f000004 0x00000000 ;# tSDP_0_reg - #mww 0x4f000008 0x000000ff ;# tDPw_0_reg - #mww 0x4f00000c 0x00000111 ;# tDPr_0_reg - #mww 0x4f000010 0x00000002 ;# tDCS_0_reg - - # set fast EMI timing as in Linux - mww 0x4f000000 0x00000010 ;# tAP_0_reg - mww 0x4f000004 0x00000005 ;# tSDP_0_reg - mww 0x4f000008 0x0000000a ;# tDPw_0_reg - mww 0x4f00000c 0x0000000a ;# tDPr_0_reg - mww 0x4f000010 0x00000005 ;# tDCS_0_re - - # 32bit wide, 8/16/32bit access - mww 0x4f000014 0x0000000e ;# control_0_reg - mww 0x4f000094 0x0000003f ;# ack_reg -} - - -# Specific init scripts for ST SPEAr320 -proc sp320_init {} { - mww 0xb300000c 0xffffac04 ;# RAS function enable - mww 0xb3000010 0x00000001 ;# RAS mode select -} diff --git a/tcl/chip/st/spear/spear3xx_ddr.tcl b/tcl/chip/st/spear/spear3xx_ddr.tcl deleted file mode 100644 index a9787d11d..000000000 --- a/tcl/chip/st/spear/spear3xx_ddr.tcl +++ /dev/null @@ -1,127 +0,0 @@ -# Init scripts to configure DDR controller of SPEAr3xx -# http://www.st.com/spear -# Original values taken from XLoader source code -# -# Date: 2010-09-23 -# Author: Antonio Borneo - - -proc sp3xx_ddr_init {ddr_type {ddr_chips 1}} { - if { $ddr_chips != 1 && $ddr_chips != 2 } { - error "Only 1 or 2 DDR chips permitted. Wrong value "$ddr_chips - } - - if { $ddr_type == "mt47h64m16_3_333_cl5_async" } { - ddr_spr3xx_mt47h64m16_3_333_cl5_async $ddr_chips - set ddr_size 0x08000000 - ## add here new DDR chip definition. Prototype: - #} elseif { $ddr_type == "?????" } { - # ????? $ddr_chips - # set ddr_size 0x????? - } else { - error "sp3xx_ddr_init: unrecognized DDR type "$ddr_type - } - - # MPMC START - mww 0xfc60001c 0x01000100 - - if { $ddr_chips == 2 } { - echo [format \ - "Double chip DDR memory. Total memory size 0x%08x byte" \ - [expr 2 * $ddr_size]] - } else { - echo [format \ - "Single chip DDR memory. Memory size 0x%08x byte" \ - $ddr_size] - } -} - - -# from Xloader file ddr/spr300_mt47h64m16_3_333_cl5_async.S -proc ddr_spr3xx_mt47h64m16_3_333_cl5_async {ddr_chips} { - # DDR_PAD_REG - mww 0xfca800f0 0x00003aa5 - - # Use "1:2 sync" only when DDR clock source is PLL1 and - # HCLK is half of PLL1 - mww 0xfc600000 0x00000001 ;# MEMCTL_AHB_SET_00 # This is async - mww 0xfc600004 0x00000000 ;# MEMCTL_AHB_SET_01 -# mww 0xfc600000 0x02020201 ;# MEMCTL_AHB_SET_00 # This is 1:2 sync -# mww 0xfc600004 0x02020202 ;# MEMCTL_AHB_SET_01 - - mww 0xfc600008 0x01000000 ;# MEMCTL_RFSH_SET_00 - mww 0xfc60000c 0x00000101 ;# MEMCTL_DLL_SET_00 - mww 0xfc600010 0x00000101 ;# MEMCTL_GP_00 - mww 0xfc600014 0x01000000 ;# MEMCTL_GP_01 - mww 0xfc600018 0x00010001 ;# MEMCTL_GP_02 - mww 0xfc60001c 0x00000100 ;# MEMCTL_GP_03 - mww 0xfc600020 0x00010001 ;# MEMCTL_GP_04 - if { $ddr_chips == 2 } { - mww 0xfc600024 0x01020203 ;# MEMCTL_GP_05 - mww 0xfc600028 0x01000102 ;# MEMCTL_GP_06 - mww 0xfc60002c 0x02000202 ;# MEMCTL_AHB_SET_02 - } else { - mww 0xfc600024 0x00000201 ;# MEMCTL_GP_05 - mww 0xfc600028 0x02000001 ;# MEMCTL_GP_06 - mww 0xfc60002c 0x02000201 ;# MEMCTL_AHB_SET_02 - } - mww 0xfc600030 0x04040105 ;# MEMCTL_AHB_SET_03 - mww 0xfc600034 0x03030302 ;# MEMCTL_AHB_SET_04 - mww 0xfc600038 0x02040101 ;# MEMCTL_AHB_SET_05 - mww 0xfc60003c 0x00000002 ;# MEMCTL_AHB_SET_06 - mww 0xfc600044 0x03000405 ;# MEMCTL_DQS_SET_0 - mww 0xfc600048 0x03040002 ;# MEMCTL_TIME_SET_01 - mww 0xfc60004c 0x04000305 ;# MEMCTL_TIME_SET_02 - mww 0xfc600050 0x0505053f ;# MEMCTL_AHB_RELPR_00 - mww 0xfc600054 0x05050505 ;# MEMCTL_AHB_RELPR_01 - mww 0xfc600058 0x04040405 ;# MEMCTL_AHB_RELPR_02 - mww 0xfc60005c 0x04040404 ;# MEMCTL_AHB_RELPR_03 - mww 0xfc600060 0x03030304 ;# MEMCTL_AHB_RELPR_04 - mww 0xfc600064 0x03030303 ;# MEMCTL_AHB_RELPR_05 - mww 0xfc600068 0x02020203 ;# MEMCTL_AHB_RELPR_06 - mww 0xfc60006c 0x02020202 ;# MEMCTL_AHB_RELPR_07 - mww 0xfc600070 0x01010102 ;# MEMCTL_AHB_RELPR_08 - mww 0xfc600074 0x01010101 ;# MEMCTL_AHB_RELPR_09 - mww 0xfc600078 0x00000001 ;# MEMCTL_AHB_RELPR_10 - mww 0xfc600088 0x0a0c0a00 ;# MEMCTL_DQS_SET_1 - mww 0xfc60008c 0x0000023f ;# MEMCTL_GP_07 - mww 0xfc600090 0x00050a00 ;# MEMCTL_GP_08 - mww 0xfc600094 0x11000000 ;# MEMCTL_GP_09 - mww 0xfc600098 0x00001302 ;# MEMCTL_GP_10 - mww 0xfc60009c 0x00001c1c ;# MEMCTL_DLL_SET_01 - mww 0xfc6000a0 0x7c000000 ;# MEMCTL_DQS_OUT_SHIFT - mww 0xfc6000a4 0x005c0000 ;# MEMCTL_WR_DQS_SHIFT - mww 0xfc6000a8 0x2b050e00 ;# MEMCTL_TIME_SET_03 - mww 0xfc6000ac 0x00640064 ;# MEMCTL_AHB_PRRLX_00 - mww 0xfc6000b0 0x00640064 ;# MEMCTL_AHB_PRRLX_01 - mww 0xfc6000b4 0x00000064 ;# MEMCTL_AHB_PRRLX_02 - mww 0xfc6000b8 0x00000000 ;# MEMCTL_OUTRANGE_LGTH - mww 0xfc6000bc 0x00200020 ;# MEMCTL_AHB_RW_SET_00 - mww 0xfc6000c0 0x00200020 ;# MEMCTL_AHB_RW_SET_01 - mww 0xfc6000c4 0x00200020 ;# MEMCTL_AHB_RW_SET_02 - mww 0xfc6000c8 0x00200020 ;# MEMCTL_AHB_RW_SET_03 - mww 0xfc6000cc 0x00200020 ;# MEMCTL_AHB_RW_SET_04 - mww 0xfc6000d8 0x00000a24 ;# MEMCTL_TREF - mww 0xfc6000dc 0x00000000 ;# MEMCTL_EMRS3_DATA - mww 0xfc6000e0 0x5b1c00c8 ;# MEMCTL_TIME_SET_04 - mww 0xfc6000e4 0x00c8002e ;# MEMCTL_TIME_SET_05 - mww 0xfc6000e8 0x00000000 ;# MEMCTL_VERSION - mww 0xfc6000ec 0x0001046b ;# MEMCTL_TINIT - mww 0xfc6000f0 0x00000000 ;# MEMCTL_OUTRANGE_ADDR_01 - mww 0xfc6000f4 0x00000000 ;# MEMCTL_OUTRANGE_ADDR_02 - mww 0xfc600104 0x001c0000 ;# MEMCTL_DLL_DQS_DELAY_BYPASS_0 - mww 0xfc600108 0x0019001c ;# MEMCTL_DLL_SET_02 - mww 0xfc60010c 0x00100000 ;# MEMCTL_DLL_SET_03 - mww 0xfc600110 0x001e007a ;# MEMCTL_DQS_SET_2 - mww 0xfc600188 0x00000000 ;# MEMCTL_USER_DEF_REG_0 - mww 0xfc60018c 0x00000000 ;# MEMCTL_USER_DEF_REG_1 - mww 0xfc600190 0x01010001 ;# MEMCTL_GP_11 - mww 0xfc600194 0x01000000 ;# MEMCTL_GP_12 - mww 0xfc600198 0x00000001 ;# MEMCTL_GP_13 - mww 0xfc60019c 0x00400000 ;# MEMCTL_GP_14 - mww 0xfc6001a0 0x00000000 ;# MEMCTL_EMRS2_DATA_X - mww 0xfc6001a4 0x00000000 ;# MEMCTL_LWPWR_CNT - mww 0xfc6001a8 0x00000000 ;# MEMCTL_LWPWR_REG - mww 0xfc6001ac 0x00860000 ;# MEMCTL_GP_15 - mww 0xfc6001b0 0x00000002 ;# MEMCTL_TPDEX -} diff --git a/tcl/chip/st/stm32/stm32.tcl b/tcl/chip/st/stm32/stm32.tcl deleted file mode 100644 index 94b1935dd..000000000 --- a/tcl/chip/st/stm32/stm32.tcl +++ /dev/null @@ -1,7 +0,0 @@ -source [find bitsbytes.tcl] -source [find cpu/arm/cortex_m3.tcl] -source [find memory.tcl] -source [find mmr_helpers.tcl] - -source [find chip/st/stm32/stm32_regs.tcl] -source [find chip/st/stm32/stm32_rcc.tcl] diff --git a/tcl/chip/st/stm32/stm32_rcc.tcl b/tcl/chip/st/stm32/stm32_rcc.tcl deleted file mode 100644 index 07718b649..000000000 --- a/tcl/chip/st/stm32/stm32_rcc.tcl +++ /dev/null @@ -1,290 +0,0 @@ - -set RCC_CR [expr $RCC_BASE + 0x00] -set RCC_CFGR [expr $RCC_BASE + 0x04] -set RCC_CIR [expr $RCC_BASE + 0x08] -set RCC_APB2RSTR [expr $RCC_BASE + 0x0c] -set RCC_APB1RSTR [expr $RCC_BASE + 0x10] -set RCC_AHBENR [expr $RCC_BASE + 0x14] -set RCC_APB2ENR [expr $RCC_BASE + 0x18] -set RCC_APB1ENR [expr $RCC_BASE + 0x1c] -set RCC_BDCR [expr $RCC_BASE + 0x20] -set RCC_CSR [expr $RCC_BASE + 0x24] - - -proc show_RCC_CR { } { - if [ catch { set val [show_mmr32_reg RCC_CR] } msg ] { - error $msg - } - - show_mmr_bitfield 0 0 $val HSI { OFF ON } - show_mmr_bitfield 1 1 $val HSIRDY { NOTRDY RDY } - show_mmr_bitfield 7 3 $val HSITRIM { _NUMBER_ } - show_mmr_bitfield 15 8 $val HSICAL { _NUMBER_ } - show_mmr_bitfield 16 16 $val HSEON { OFF ON } - show_mmr_bitfield 17 17 $val HSERDY { NOTRDY RDY } - show_mmr_bitfield 18 18 $val HSEBYP { NOTBYPASSED BYPASSED } - show_mmr_bitfield 19 19 $val CSSON { OFF ON } - show_mmr_bitfield 24 24 $val PLLON { OFF ON } - show_mmr_bitfield 25 25 $val PLLRDY { NOTRDY RDY } -} - -proc show_RCC_CFGR { } { - if [ catch { set val [show_mmr32_reg RCC_CFGR] } msg ] { - error $msg - } - - - show_mmr_bitfield 1 0 $val SW { HSI HSE PLL ILLEGAL } - show_mmr_bitfield 3 2 $val SWS { HSI HSE PLL ILLEGAL } - show_mmr_bitfield 7 4 $val HPRE { sysclk_div_1 sysclk_div_1 sysclk_div_1 sysclk_div_1 sysclk_div_1 sysclk_div_1 sysclk_div_1 sysclk_div_1 sysclk_div_2 sysclk_div_4 sysclk_div_8 sysclk_div_16 sysclk_div_64 sysclk_div_128 sysclk_div_256 sysclk_div_512 } - show_mmr_bitfield 10 8 $val PPRE1 { hclk_div1 hclk_div1 hclk_div1 hclk_div1 hclk_div2 hclk_div4 hclk_div8 hclk_div16 } - show_mmr_bitfield 13 11 $val PPRE2 { hclk_div1 hclk_div1 hclk_div1 hclk_div1 hclk_div2 hclk_div4 hclk_div8 hclk_div16 } - show_mmr_bitfield 15 14 $val ADCPRE { pclk2_div1 pclk2_div1 pclk2_div1 pclk2_div1 pclk2_div2 pclk2_div4 pclk2_div8 pclk2_div16 } - show_mmr_bitfield 16 16 $val PLLSRC { HSI_div_2 HSE } - show_mmr_bitfield 17 17 $val PLLXTPRE { hse_div1 hse_div2 } - show_mmr_bitfield 21 18 $val PLLMUL { x2 x3 x4 x5 x6 x7 x8 x9 x10 x11 x12 x13 x14 x15 x16 x16 } - show_mmr_bitfield 22 22 $val USBPRE { div1 div1_5 } - show_mmr_bitfield 26 24 $val MCO { none none none none SysClk HSI HSE PLL_div2 } -} - - -proc show_RCC_CIR { } { - if [ catch { set val [show_mmr32_reg RCC_CIR] } msg ] { - error $msg - } - -} - -proc show_RCC_APB2RSTR { } { - if [ catch { set val [ show_mmr32_reg RCC_APB2RSTR] } msg ] { - error $msg - } - for { set x 0 } { $x < 32 } { incr x } { - set bits($x) xxx - } - set bits(15) adc3 - set bits(14) usart1 - set bits(13) tim8 - set bits(12) spi1 - set bits(11) tim1 - set bits(10) adc2 - set bits(9) adc1 - set bits(8) iopg - set bits(7) iopf - set bits(6) iope - set bits(5) iopd - set bits(4) iopc - set bits(3) iopb - set bits(2) iopa - set bits(1) xxx - set bits(0) afio - show_mmr32_bits bits $val -} - -proc show_RCC_APB1RSTR { } { - if [ catch { set val [ show_mmr32_reg RCC_APB1RSTR] } msg ] { - error $msg - } - set bits(31) xxx - set bits(30) xxx - set bits(29) dac - set bits(28) pwr - set bits(27) bkp - set bits(26) xxx - set bits(25) can - set bits(24) xxx - set bits(23) usb - set bits(22) i2c2 - set bits(21) i2c1 - set bits(20) uart5 - set bits(19) uart4 - set bits(18) uart3 - set bits(17) uart2 - set bits(16) xxx - set bits(15) spi3 - set bits(14) spi2 - set bits(13) xxx - set bits(12) xxx - set bits(11) wwdg - set bits(10) xxx - set bits(9) xxx - set bits(8) xxx - set bits(7) xxx - set bits(6) xxx - set bits(5) tim7 - set bits(4) tim6 - set bits(3) tim5 - set bits(2) tim4 - set bits(1) tim3 - set bits(0) tim2 - show_mmr32_bits bits $val - -} - -proc show_RCC_AHBENR { } { - if [ catch { set val [ show_mmr32_reg RCC_AHBENR ] } msg ] { - error $msg - } - set bits(31) xxx - set bits(30) xxx - set bits(29) xxx - set bits(28) xxx - set bits(27) xxx - set bits(26) xxx - set bits(25) xxx - set bits(24) xxx - set bits(23) xxx - set bits(22) xxx - set bits(21) xxx - set bits(20) xxx - set bits(19) xxx - set bits(18) xxx - set bits(17) xxx - set bits(16) xxx - set bits(15) xxx - set bits(14) xxx - set bits(13) xxx - set bits(12) xxx - set bits(11) xxx - set bits(10) sdio - set bits(9) xxx - set bits(8) fsmc - set bits(7) xxx - set bits(6) crce - set bits(5) xxx - set bits(4) flitf - set bits(3) xxx - set bits(2) sram - set bits(1) dma2 - set bits(0) dma1 - show_mmr32_bits bits $val -} - -proc show_RCC_APB2ENR { } { - if [ catch { set val [ show_mmr32_reg RCC_APB2ENR ] } msg ] { - error $msg - } - set bits(31) xxx - set bits(30) xxx - set bits(29) xxx - set bits(28) xxx - set bits(27) xxx - set bits(26) xxx - set bits(25) xxx - set bits(24) xxx - set bits(23) xxx - set bits(22) xxx - set bits(21) xxx - set bits(20) xxx - set bits(19) xxx - set bits(18) xxx - set bits(17) xxx - set bits(16) xxx - set bits(15) adc3 - set bits(14) usart1 - set bits(13) tim8 - set bits(12) spi1 - set bits(11) tim1 - set bits(10) adc2 - set bits(9) adc1 - set bits(8) iopg - set bits(7) iopf - set bits(6) iope - set bits(5) iopd - set bits(4) iopc - set bits(3) iopb - set bits(2) iopa - set bits(1) xxx - set bits(0) afio - show_mmr32_bits bits $val - -} - -proc show_RCC_APB1ENR { } { - if [ catch { set val [ show_mmr32_reg RCC_APB1ENR ] } msg ] { - error $msg - } - set bits(31) xxx - set bits(30) xxx - set bits(29) dac - set bits(28) pwr - set bits(27) bkp - set bits(26) xxx - set bits(25) can - set bits(24) xxx - set bits(23) usb - set bits(22) i2c2 - set bits(21) i2c1 - set bits(20) usart5 - set bits(19) usart4 - set bits(18) usart3 - set bits(17) usart2 - set bits(16) xxx - set bits(15) spi3 - set bits(14) spi2 - set bits(13) xxx - set bits(12) xxx - set bits(11) wwdg - set bits(10) xxx - set bits(9) xxx - set bits(8) xxx - set bits(7) xxx - set bits(6) xxx - set bits(5) tim7 - set bits(4) tim6 - set bits(3) tim5 - set bits(2) tim4 - set bits(1) tim3 - set bits(0) tim2 - show_mmr32_bits bits $val -} - -proc show_RCC_BDCR { } { - if [ catch { set val [ show_mmr32_reg RCC_BDCR ] } msg ] { - error $msg - } - for { set x 0 } { $x < 32 } { incr x } { - set bits($x) xxx - } - set bits(0) lseon - set bits(1) lserdy - set bits(2) lsebyp - set bits(8) rtcsel0 - set bits(9) rtcsel1 - set bits(15) rtcen - set bits(16) bdrst - show_mmr32_bits bits $val -} - -proc show_RCC_CSR { } { - if [ catch { set val [ show_mmr32_reg RCC_CSR ] } msg ] { - error $msg - } - for { set x 0 } { $x < 32 } { incr x } { - set bits($x) xxx - } - set bits(0) lsion - set bits(1) lsirdy - set bits(24) rmvf - set bits(26) pin - set bits(27) por - set bits(28) sft - set bits(29) iwdg - set bits(30) wwdg - set bits(31) lpwr - show_mmr32_bits bits $val -} - -proc show_RCC { } { - - show_RCC_CR - show_RCC_CFGR - show_RCC_CIR - show_RCC_APB2RSTR - show_RCC_APB1RSTR - show_RCC_AHBENR - show_RCC_APB2ENR - show_RCC_APB1ENR - show_RCC_BDCR - show_RCC_CSR -} diff --git a/tcl/chip/st/stm32/stm32_regs.tcl b/tcl/chip/st/stm32/stm32_regs.tcl deleted file mode 100644 index 0c1f6257c..000000000 --- a/tcl/chip/st/stm32/stm32_regs.tcl +++ /dev/null @@ -1,95 +0,0 @@ -# /* Peripheral and SRAM base address in the alias region */ -set PERIPH_BB_BASE 0x42000000 -set SRAM_BB_BASE 0x22000000 - -# /*Peripheral and SRAM base address in the bit-band region */ -set SRAM_BASE 0x20000000 -set PERIPH_BASE 0x40000000 - -# /*FSMC registers base address */ -set FSMC_R_BASE 0xA0000000 - -# /*Peripheral memory map */ -set APB1PERIPH_BASE [set PERIPH_BASE] -set APB2PERIPH_BASE [expr $PERIPH_BASE + 0x10000] -set AHBPERIPH_BASE [expr $PERIPH_BASE + 0x20000] - -set TIM2_BASE [expr $APB1PERIPH_BASE + 0x0000] -set TIM3_BASE [expr $APB1PERIPH_BASE + 0x0400] -set TIM4_BASE [expr $APB1PERIPH_BASE + 0x0800] -set TIM5_BASE [expr $APB1PERIPH_BASE + 0x0C00] -set TIM6_BASE [expr $APB1PERIPH_BASE + 0x1000] -set TIM7_BASE [expr $APB1PERIPH_BASE + 0x1400] -set RTC_BASE [expr $APB1PERIPH_BASE + 0x2800] -set WWDG_BASE [expr $APB1PERIPH_BASE + 0x2C00] -set IWDG_BASE [expr $APB1PERIPH_BASE + 0x3000] -set SPI2_BASE [expr $APB1PERIPH_BASE + 0x3800] -set SPI3_BASE [expr $APB1PERIPH_BASE + 0x3C00] -set USART2_BASE [expr $APB1PERIPH_BASE + 0x4400] -set USART3_BASE [expr $APB1PERIPH_BASE + 0x4800] -set UART4_BASE [expr $APB1PERIPH_BASE + 0x4C00] -set UART5_BASE [expr $APB1PERIPH_BASE + 0x5000] -set I2C1_BASE [expr $APB1PERIPH_BASE + 0x5400] -set I2C2_BASE [expr $APB1PERIPH_BASE + 0x5800] -set CAN_BASE [expr $APB1PERIPH_BASE + 0x6400] -set BKP_BASE [expr $APB1PERIPH_BASE + 0x6C00] -set PWR_BASE [expr $APB1PERIPH_BASE + 0x7000] -set DAC_BASE [expr $APB1PERIPH_BASE + 0x7400] - -set AFIO_BASE [expr $APB2PERIPH_BASE + 0x0000] -set EXTI_BASE [expr $APB2PERIPH_BASE + 0x0400] -set GPIOA_BASE [expr $APB2PERIPH_BASE + 0x0800] -set GPIOB_BASE [expr $APB2PERIPH_BASE + 0x0C00] -set GPIOC_BASE [expr $APB2PERIPH_BASE + 0x1000] -set GPIOD_BASE [expr $APB2PERIPH_BASE + 0x1400] -set GPIOE_BASE [expr $APB2PERIPH_BASE + 0x1800] -set GPIOF_BASE [expr $APB2PERIPH_BASE + 0x1C00] -set GPIOG_BASE [expr $APB2PERIPH_BASE + 0x2000] -set ADC1_BASE [expr $APB2PERIPH_BASE + 0x2400] -set ADC2_BASE [expr $APB2PERIPH_BASE + 0x2800] -set TIM1_BASE [expr $APB2PERIPH_BASE + 0x2C00] -set SPI1_BASE [expr $APB2PERIPH_BASE + 0x3000] -set TIM8_BASE [expr $APB2PERIPH_BASE + 0x3400] -set USART1_BASE [expr $APB2PERIPH_BASE + 0x3800] -set ADC3_BASE [expr $APB2PERIPH_BASE + 0x3C00] - -set SDIO_BASE [expr $PERIPH_BASE + 0x18000] - -set DMA1_BASE [expr $AHBPERIPH_BASE + 0x0000] -set DMA1_Channel1_BASE [expr $AHBPERIPH_BASE + 0x0008] -set DMA1_Channel2_BASE [expr $AHBPERIPH_BASE + 0x001C] -set DMA1_Channel3_BASE [expr $AHBPERIPH_BASE + 0x0030] -set DMA1_Channel4_BASE [expr $AHBPERIPH_BASE + 0x0044] -set DMA1_Channel5_BASE [expr $AHBPERIPH_BASE + 0x0058] -set DMA1_Channel6_BASE [expr $AHBPERIPH_BASE + 0x006C] -set DMA1_Channel7_BASE [expr $AHBPERIPH_BASE + 0x0080] -set DMA2_BASE [expr $AHBPERIPH_BASE + 0x0400] -set DMA2_Channel1_BASE [expr $AHBPERIPH_BASE + 0x0408] -set DMA2_Channel2_BASE [expr $AHBPERIPH_BASE + 0x041C] -set DMA2_Channel3_BASE [expr $AHBPERIPH_BASE + 0x0430] -set DMA2_Channel4_BASE [expr $AHBPERIPH_BASE + 0x0444] -set DMA2_Channel5_BASE [expr $AHBPERIPH_BASE + 0x0458] -set RCC_BASE [expr $AHBPERIPH_BASE + 0x1000] -set CRC_BASE [expr $AHBPERIPH_BASE + 0x3000] - -# /*Flash registers base address */ -set FLASH_R_BASE [expr $AHBPERIPH_BASE + 0x2000] -# /*Flash Option Bytes base address */ -set OB_BASE 0x1FFFF800 - -# /*FSMC Bankx registers base address */ -set FSMC_Bank1_R_BASE [expr $FSMC_R_BASE + 0x0000] -set FSMC_Bank1E_R_BASE [expr $FSMC_R_BASE + 0x0104] -set FSMC_Bank2_R_BASE [expr $FSMC_R_BASE + 0x0060] -set FSMC_Bank3_R_BASE [expr $FSMC_R_BASE + 0x0080] -set FSMC_Bank4_R_BASE [expr $FSMC_R_BASE + 0x00A0] - -# /*Debug MCU registers base address */ -set DBGMCU_BASE 0xE0042000 - -# /*System Control Space memory map */ -set SCS_BASE 0xE000E000 - -set SysTick_BASE [expr $SCS_BASE + 0x0010] -set NVIC_BASE [expr $SCS_BASE + 0x0100] -set SCB_BASE [expr $SCS_BASE + 0x0D00] diff --git a/tcl/chip/ti/lm3s/lm3s.tcl b/tcl/chip/ti/lm3s/lm3s.tcl deleted file mode 100644 index 42da8c668..000000000 --- a/tcl/chip/ti/lm3s/lm3s.tcl +++ /dev/null @@ -1 +0,0 @@ -source [find chip/ti/lm3s/lm3s_regs.tcl] diff --git a/tcl/chip/ti/lm3s/lm3s_regs.tcl b/tcl/chip/ti/lm3s/lm3s_regs.tcl deleted file mode 100644 index cb20812db..000000000 --- a/tcl/chip/ti/lm3s/lm3s_regs.tcl +++ /dev/null @@ -1,84 +0,0 @@ -#***************************************************************************** -# -# The following are defines for the System Control register addresses. -# -#***************************************************************************** - -set SYSCTL_DID0 0x400FE000 ;# Device Identification 0 -set SYSCTL_DID1 0x400FE004 ;# Device Identification 1 -set SYSCTL_DC0 0x400FE008 ;# Device Capabilities 0 -set SYSCTL_DC1 0x400FE010 ;# Device Capabilities 1 -set SYSCTL_DC2 0x400FE014 ;# Device Capabilities 2 -set SYSCTL_DC3 0x400FE018 ;# Device Capabilities 3 -set SYSCTL_DC4 0x400FE01C ;# Device Capabilities 4 -set SYSCTL_DC5 0x400FE020 ;# Device Capabilities 5 -set SYSCTL_DC6 0x400FE024 ;# Device Capabilities 6 -set SYSCTL_DC7 0x400FE028 ;# Device Capabilities 7 -set SYSCTL_DC8 0x400FE02C ;# Device Capabilities 8 ADC - ;# Channels -set SYSCTL_PBORCTL 0x400FE030 ;# Brown-Out Reset Control -set SYSCTL_LDOPCTL 0x400FE034 ;# LDO Power Control -set SYSCTL_SRCR0 0x400FE040 ;# Software Reset Control 0 -set SYSCTL_SRCR1 0x400FE044 ;# Software Reset Control 1 -set SYSCTL_SRCR2 0x400FE048 ;# Software Reset Control 2 -set SYSCTL_RIS 0x400FE050 ;# Raw Interrupt Status -set SYSCTL_IMC 0x400FE054 ;# Interrupt Mask Control -set SYSCTL_MISC 0x400FE058 ;# Masked Interrupt Status and - ;# Clear -set SYSCTL_RESC 0x400FE05C ;# Reset Cause -set SYSCTL_RCC 0x400FE060 ;# Run-Mode Clock Configuration -set SYSCTL_PLLCFG 0x400FE064 ;# XTAL to PLL Translation -set SYSCTL_GPIOHSCTL 0x400FE06C ;# GPIO High-Speed Control -set SYSCTL_GPIOHBCTL 0x400FE06C ;# GPIO High-Performance Bus - ;# Control -set SYSCTL_RCC2 0x400FE070 ;# Run-Mode Clock Configuration 2 -set SYSCTL_MOSCCTL 0x400FE07C ;# Main Oscillator Control -set SYSCTL_RCGC0 0x400FE100 ;# Run Mode Clock Gating Control - ;# Register 0 -set SYSCTL_RCGC1 0x400FE104 ;# Run Mode Clock Gating Control - ;# Register 1 -set SYSCTL_RCGC2 0x400FE108 ;# Run Mode Clock Gating Control - ;# Register 2 -set SYSCTL_SCGC0 0x400FE110 ;# Sleep Mode Clock Gating Control - ;# Register 0 -set SYSCTL_SCGC1 0x400FE114 ;# Sleep Mode Clock Gating Control - ;# Register 1 -set SYSCTL_SCGC2 0x400FE118 ;# Sleep Mode Clock Gating Control - ;# Register 2 -set SYSCTL_DCGC0 0x400FE120 ;# Deep Sleep Mode Clock Gating - ;# Control Register 0 -set SYSCTL_DCGC1 0x400FE124 ;# Deep-Sleep Mode Clock Gating - ;# Control Register 1 -set SYSCTL_DCGC2 0x400FE128 ;# Deep Sleep Mode Clock Gating - ;# Control Register 2 -set SYSCTL_DSLPCLKCFG 0x400FE144 ;# Deep Sleep Clock Configuration -set SYSCTL_CLKVCLR 0x400FE150 ;# Clock Verification Clear -set SYSCTL_PIOSCCAL 0x400FE150 ;# Precision Internal Oscillator - ;# Calibration -set SYSCTL_PIOSCSTAT 0x400FE154 ;# Precision Internal Oscillator - ;# Statistics -set SYSCTL_LDOARST 0x400FE160 ;# Allow Unregulated LDO to Reset - ;# the Part -set SYSCTL_I2SMCLKCFG 0x400FE170 ;# I2S MCLK Configuration -set SYSCTL_DC9 0x400FE190 ;# Device Capabilities 9 ADC - ;# Digital Comparators -set SYSCTL_NVMSTAT 0x400FE1A0 ;# Non-Volatile Memory Information - -set SYSCTL_RCC_USESYSDIV 0x00400000 ;# Enable System Clock Divider -set SYSCTL_RCC2_BYPASS2 0x00000800 ;# PLL Bypass 2 -set SYSCTL_RCC_MOSCDIS 0x00000001 ;# Main Oscillator Disable - -set SYSCTL_SRCR0 0x400FE040 ;# Software Reset Control 0 -set SYSCTL_SRCR1 0x400FE044 ;# Software Reset Control 1 -set SYSCTL_SRCR2 0x400FE048 ;# Software Reset Control 2 - -set SYSCTL_MISC 0x400FE058 ;# Masked Interrupt Status and Clear - -set FLASH_FMA 0x400FD000 ;# Flash Memory Address -set FLASH_FMD 0x400FD004 ;# Flash Memory Data -set FLASH_FMC 0x400FD008 ;# Flash Memory Control -set FLASH_FCRIS 0x400FD00C ;# Flash Controller Raw Interrupt Status -set FLASH_FCIM 0x400FD010 ;# Flash Controller Interrupt Mask -set FLASH_FCMISC 0x400FD014 ;# Flash Controller Masked Interrupt Status and Clear -set FLASH_FMC2 0x400FD020 ;# Flash Memory Control 2 -set FLASH_FWBVAL 0x400FD030 ;# Flash Write Buffer Valid diff --git a/tcl/cpld/altera-epm240.cfg b/tcl/cpld/altera-epm240.cfg deleted file mode 100644 index 62f2b73b7..000000000 --- a/tcl/cpld/altera-epm240.cfg +++ /dev/null @@ -1,6 +0,0 @@ -# Altera MAXII EPM240T100C CPLD -# see MAX II Device Handbook -# Table 3-3: 32-Bit MAX II Device IDCODE -# Version Part Number Manuf. ID LSB -# 0000 0010 0000 1010 0001 000 0110 1110 1 -jtag newtap epm240 tap -expected-id 0x020a10dd -irlen 10 diff --git a/tcl/cpld/jtagspi.cfg b/tcl/cpld/jtagspi.cfg deleted file mode 100644 index 60c3cb109..000000000 --- a/tcl/cpld/jtagspi.cfg +++ /dev/null @@ -1,43 +0,0 @@ -set _USER1 0x02 - -if { [info exists JTAGSPI_IR] } { - set _JTAGSPI_IR $JTAGSPI_IR -} else { - set _JTAGSPI_IR $_USER1 -} - -if { [info exists DR_LENGTH] } { - set _DR_LENGTH $DR_LENGTH -} else { - set _DR_LENGTH 1 -} - -if { [info exists TARGETNAME] } { - set _TARGETNAME $TARGETNAME -} else { - set _TARGETNAME $_CHIPNAME.proxy -} - -if { [info exists FLASHNAME] } { - set _FLASHNAME $FLASHNAME -} else { - set _FLASHNAME $_CHIPNAME.spi -} - -target create $_TARGETNAME testee -chain-position $_CHIPNAME.tap -flash bank $_FLASHNAME jtagspi 0 0 0 0 $_TARGETNAME $_JTAGSPI_IR $_DR_LENGTH - -proc jtagspi_init {chain_id proxy_bit} { - # load proxy bitstream $proxy_bit and probe spi flash - global _FLASHNAME - pld load $chain_id $proxy_bit - reset halt - flash probe $_FLASHNAME -} - -proc jtagspi_program {bin addr} { - # write and verify binary file $bin at offset $addr - global _FLASHNAME - flash write_image erase $bin $addr - flash verify_bank $_FLASHNAME $bin $addr -} diff --git a/tcl/cpld/lattice-lc4032ze.cfg b/tcl/cpld/lattice-lc4032ze.cfg deleted file mode 100644 index d4a85eb79..000000000 --- a/tcl/cpld/lattice-lc4032ze.cfg +++ /dev/null @@ -1,3 +0,0 @@ -# Lattice ispMACH 4000ZE family, device LC4032ZE -# just configure a tap -jtag newtap LC4032ZE tap -irlen 8 -expected-id 0x01806043 diff --git a/tcl/cpld/xilinx-xc6s.cfg b/tcl/cpld/xilinx-xc6s.cfg deleted file mode 100644 index 9ce7ad491..000000000 --- a/tcl/cpld/xilinx-xc6s.cfg +++ /dev/null @@ -1,90 +0,0 @@ -# xilinx spartan6 -# http://www.xilinx.com/support/documentation/user_guides/ug380.pdf - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME xc6s -} - -# the 4 top bits (28:31) are the die stepping. ignore it. -jtag newtap $_CHIPNAME tap -irlen 6 -ignore-version \ - -expected-id 0x04000093 \ - -expected-id 0x04001093 \ - -expected-id 0x04002093 \ - -expected-id 0x04004093 \ - -expected-id 0x04024093 \ - -expected-id 0x04008093 \ - -expected-id 0x04028093 \ - -expected-id 0x0400E093 \ - -expected-id 0x0402E093 \ - -expected-id 0x04011093 \ - -expected-id 0x04031093 \ - -expected-id 0x0401D093 \ - -expected-id 0x0403D093 - -pld device virtex2 $_CHIPNAME.tap - -set XC6S_CFG_IN 0x05 -set XC6S_JSHUTDOWN 0x0d -set XC6S_JPROGRAM 0x0b -set XC6S_JSTART 0x0c -set XC6S_BYPASS 0x3f - -proc xc6s_program {tap} { - global XC6S_JSHUTDOWN XC6S_JPROGRAM XC6S_JSTART XC6S_BYPASS - irscan $tap $XC6S_JSHUTDOWN - irscan $tap $XC6S_JPROGRAM - irscan $tap $XC6S_JSTART - irscan $tap $XC6S_BYPASS -} - -#xtp038 and xc3sprog approach -proc xc6s_program_iprog {tap} { - global XC6S_JSHUTDOWN XC6S_JSTART XC6S_BYPASS XC6S_CFG_IN - irscan $tap $XC6S_JSHUTDOWN - runtest 16 - irscan $tap $XC6S_CFG_IN - # xtp038 IPROG 16bit flipped - drscan $tap 16 0xffff 16 0x9955 16 0x66aa 16 0x850c 16 0x7000 16 0x0004 - irscan $tap $XC6S_JSTART - runtest 32 - irscan $tap $XC6S_BYPASS - runtest 1 -} - -set XC6S_ISC_ENABLE 0x10 -set XC6S_ISC_DISABLE 0x16 -set XC6S_ISC_DNA 0x30 - -# Get the "Device DNA" from the Spartan 6. -# Most Xilinx FPGA devices contain an embedded, unique device identifier called -# the "Device DNA". The identifier is nonvolatile, permanently programmed into -# the FPGA, and is unchangeable providing a great serial / tracking number. -proc xc6s_get_dna {tap} { - global XC6S_ISC_ENABLE XC6S_ISC_DISABLE XC6S_ISC_DNA - irscan $tap $XC6S_ISC_ENABLE - runtest 64 - irscan $tap $XC6S_ISC_DNA - # Device DNA is 57 bits long, but we can only read 32bits at a time - # with OpenOCD. - set dna [drscan $tap 16 0 16 0 16 0 9 0] - runtest 64 - irscan $tap $XC6S_ISC_DISABLE - runtest 64 - - # Convert the binary data into the order impact uses - scan $dna "%x %x %x %x" v1 v2 v3 v4 - set bin_dna [string reverse [concat [format "%09b" $v4][format "%016b" $v3][format "%016b" $v2][format "%016b" $v1]]] - - # Return a hex version of binary - scan [format "0b%s" $bin_dna] "%i" hex_dna - return $hex_dna -} - -# Print out the "Device DNA" in the same format that impact uses. -proc xc6s_print_dna {tap} { - set hex_dna [xc6s_get_dna $tap] - - puts [format "DNA = %57b (0x%x)\n" $hex_dna $hex_dna] -} diff --git a/tcl/cpld/xilinx-xc7.cfg b/tcl/cpld/xilinx-xc7.cfg deleted file mode 100644 index d5824f8a1..000000000 --- a/tcl/cpld/xilinx-xc7.cfg +++ /dev/null @@ -1,57 +0,0 @@ -# xilinx series 7 (artix, kintex, virtex) -# http://www.xilinx.com/support/documentation/user_guides/ug470_7Series_Config.pdf - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME xc7 -} - -# the 4 top bits (28:31) are the die stepping/revisions. ignore it. -jtag newtap $_CHIPNAME tap -irlen 6 -ignore-version \ - -expected-id 0x0362E093 \ - -expected-id 0x0362D093 \ - -expected-id 0x0362C093 \ - -expected-id 0x03632093 \ - -expected-id 0x03631093 \ - -expected-id 0x03636093 \ - -expected-id 0x03647093 \ - -expected-id 0x0364C093 \ - -expected-id 0x03651093 \ - -expected-id 0x03747093 \ - -expected-id 0x03656093 \ - -expected-id 0x03752093 \ - -expected-id 0x03751093 \ - -expected-id 0x03671093 \ - -expected-id 0x036B3093 \ - -expected-id 0x036B7093 \ - -expected-id 0x036BB093 \ - -expected-id 0x036BF093 \ - -expected-id 0x03667093 \ - -expected-id 0x03682093 \ - -expected-id 0x03687093 \ - -expected-id 0x03692093 \ - -expected-id 0x03691093 \ - -expected-id 0x03696093 \ - -expected-id 0x036D5093 \ - -expected-id 0x036D9093 \ - -expected-id 0x036DB093 - -pld device virtex2 $_CHIPNAME.tap 1 - -set XC7_JSHUTDOWN 0x0d -set XC7_JPROGRAM 0x0b -set XC7_JSTART 0x0c -set XC7_BYPASS 0x3f - -proc xc7_program {tap} { - global XC7_JSHUTDOWN XC7_JPROGRAM XC7_JSTART XC7_BYPASS - irscan $tap $XC7_JSHUTDOWN - irscan $tap $XC7_JPROGRAM - runtest 60000 - #JSTART prevents this from working... - #irscan $tap $XC7_JSTART - runtest 2000 - irscan $tap $XC7_BYPASS - runtest 2000 -} diff --git a/tcl/cpld/xilinx-xcr3256.cfg b/tcl/cpld/xilinx-xcr3256.cfg deleted file mode 100644 index e5611f1ec..000000000 --- a/tcl/cpld/xilinx-xcr3256.cfg +++ /dev/null @@ -1,3 +0,0 @@ -#xilinx coolrunner xcr3256 -#simple device - just configure a tap -jtag newtap xcr tap -irlen 5 -ircapture 0x01 -irmask 0x1f -expected-id 0x0494c093 diff --git a/tcl/cpu/arm/arm7tdmi.tcl b/tcl/cpu/arm/arm7tdmi.tcl deleted file mode 100644 index 37db26618..000000000 --- a/tcl/cpu/arm/arm7tdmi.tcl +++ /dev/null @@ -1,6 +0,0 @@ -set CPU_TYPE arm -set CPU_NAME arm7tdmi -set CPU_ARCH armv4t -set CPU_MAX_ADDRESS 0xFFFFFFFF -set CPU_NBITS 32 - diff --git a/tcl/cpu/arm/arm920.tcl b/tcl/cpu/arm/arm920.tcl deleted file mode 100644 index f19b20b3c..000000000 --- a/tcl/cpu/arm/arm920.tcl +++ /dev/null @@ -1,6 +0,0 @@ -set CPU_TYPE arm -set CPU_NAME arm920 -set CPU_ARCH armv4t -set CPU_MAX_ADDRESS 0xFFFFFFFF -set CPU_NBITS 32 - diff --git a/tcl/cpu/arm/arm946.tcl b/tcl/cpu/arm/arm946.tcl deleted file mode 100644 index 520410178..000000000 --- a/tcl/cpu/arm/arm946.tcl +++ /dev/null @@ -1,6 +0,0 @@ -set CPU_TYPE arm -set CPU_NAME arm946 -set CPU_ARCH armv5te -set CPU_MAX_ADDRESS 0xFFFFFFFF -set CPU_NBITS 32 - diff --git a/tcl/cpu/arm/arm966.tcl b/tcl/cpu/arm/arm966.tcl deleted file mode 100644 index 83ce0f673..000000000 --- a/tcl/cpu/arm/arm966.tcl +++ /dev/null @@ -1,6 +0,0 @@ -set CPU_TYPE arm -set CPU_NAME arm966 -set CPU_ARCH armv5te -set CPU_MAX_ADDRESS 0xFFFFFFFF -set CPU_NBITS 32 - diff --git a/tcl/cpu/arm/cortex_m3.tcl b/tcl/cpu/arm/cortex_m3.tcl deleted file mode 100644 index 166af847d..000000000 --- a/tcl/cpu/arm/cortex_m3.tcl +++ /dev/null @@ -1,6 +0,0 @@ -set CPU_TYPE arm -set CPU_NAME cortex_m3 -set CPU_ARCH armv7 -set CPU_MAX_ADDRESS 0xFFFFFFFF -set CPU_NBITS 32 - diff --git a/tcl/fpga/altera-10m50.cfg b/tcl/fpga/altera-10m50.cfg deleted file mode 100644 index 9d00daa83..000000000 --- a/tcl/fpga/altera-10m50.cfg +++ /dev/null @@ -1,6 +0,0 @@ -# Altera MAX10 10M50SAE144C8GES FPGA -# see MAX 10 FPGA Device Architecture -# Table 3-1: IDCODE Information for MAX 10 Devices -# Version Part Number Manuf. ID LSB -# 0000 0011 0001 1000 0101 000 0110 1110 1 -jtag newtap 10m50 tap -expected-id 0x031850dd -irlen 10 diff --git a/tcl/fpga/altera-ep3c10.cfg b/tcl/fpga/altera-ep3c10.cfg deleted file mode 100644 index 6e8962a53..000000000 --- a/tcl/fpga/altera-ep3c10.cfg +++ /dev/null @@ -1,4 +0,0 @@ -# Altera Cyclone III EP3C10 -# see Cyclone III Device Handbook, Volume 1; -# Table 14–5. 32-Bit Cyclone III Device IDCODE -jtag newtap ep3c10 tap -expected-id 0x020f10dd -irlen 10 diff --git a/tcl/interface/altera-usb-blaster.cfg b/tcl/interface/altera-usb-blaster.cfg deleted file mode 100644 index f19abfebe..000000000 --- a/tcl/interface/altera-usb-blaster.cfg +++ /dev/null @@ -1,10 +0,0 @@ -# -# Altera USB-Blaster -# -# http://www.altera.com/literature/ug/ug_usb_blstr.pdf -# - -interface usb_blaster -# These are already the defaults. -# usb_blaster_vid_pid 0x09FB 0x6001 -# usb_blaster_device_desc "USB-Blaster" diff --git a/tcl/interface/altera-usb-blaster2.cfg b/tcl/interface/altera-usb-blaster2.cfg deleted file mode 100644 index c35be1970..000000000 --- a/tcl/interface/altera-usb-blaster2.cfg +++ /dev/null @@ -1,8 +0,0 @@ -# -# Altera USB-Blaster II -# - -interface usb_blaster -usb_blaster_vid_pid 0x09fb 0x6010 0x09fb 0x6810 -usb_blaster_lowlevel_driver ublast2 -usb_blaster_firmware /path/to/quartus/blaster_6810.hex diff --git a/tcl/interface/arm-jtag-ew.cfg b/tcl/interface/arm-jtag-ew.cfg deleted file mode 100644 index 2e8b57e4c..000000000 --- a/tcl/interface/arm-jtag-ew.cfg +++ /dev/null @@ -1,8 +0,0 @@ -# -# Olimex ARM-JTAG-EW -# -# http://www.olimex.com/dev/arm-jtag-ew.html -# - -interface arm-jtag-ew - diff --git a/tcl/interface/at91rm9200.cfg b/tcl/interface/at91rm9200.cfg deleted file mode 100644 index 20826478d..000000000 --- a/tcl/interface/at91rm9200.cfg +++ /dev/null @@ -1,9 +0,0 @@ -# -# Various Atmel AT91RM9200 boards -# -# TODO: URL? -# - -interface at91rm9200 -at91rm9200_device rea_ecr - diff --git a/tcl/interface/axm0432.cfg b/tcl/interface/axm0432.cfg deleted file mode 100644 index d2a2aaa82..000000000 --- a/tcl/interface/axm0432.cfg +++ /dev/null @@ -1,11 +0,0 @@ -# -# Axiom axm0432 -# -# http://www.axman.com -# - -interface ft2232 -ft2232_device_desc "Symphony SoundBite" -ft2232_layout "axm0432_jtag" -ft2232_vid_pid 0x0403 0x6010 - diff --git a/tcl/interface/busblaster.cfg b/tcl/interface/busblaster.cfg deleted file mode 100644 index f87a482e3..000000000 --- a/tcl/interface/busblaster.cfg +++ /dev/null @@ -1,14 +0,0 @@ -# -# Dangerous Prototypes - Bus Blaster -# -# The Bus Blaster has a configurable buffer between the FTDI FT2232H and the -# JTAG header which allows it to emulate various debugger types. It comes -# configured as a JTAGkey device. -# -# http://dangerousprototypes.com/docs/Bus_Blaster -# - -interface ft2232 -ft2232_device_desc "Dual RS232-HS" -ft2232_layout jtagkey -ft2232_vid_pid 0x0403 0x6010 diff --git a/tcl/interface/buspirate.cfg b/tcl/interface/buspirate.cfg deleted file mode 100644 index 2b68538bf..000000000 --- a/tcl/interface/buspirate.cfg +++ /dev/null @@ -1,26 +0,0 @@ -# -# Buspirate with OpenOCD support -# -# http://dangerousprototypes.com/bus-pirate-manual/ -# - -interface buspirate - -# you need to specify port on which BP lives -#buspirate_port /dev/ttyUSB0 - -# communication speed setting -buspirate_speed normal ;# or fast - -# voltage regulator Enabled = 1 Disabled = 0 -#buspirate_vreg 0 - -# pin mode normal or open-drain -#buspirate_mode normal - -# pullup state Enabled = 1 Disabled = 0 -#buspirate_pullup 0 - -# this depends on the cable, you are safe with this option -reset_config srst_only - diff --git a/tcl/interface/calao-usb-a9260-c01.cfg b/tcl/interface/calao-usb-a9260-c01.cfg deleted file mode 100644 index c6606710e..000000000 --- a/tcl/interface/calao-usb-a9260-c01.cfg +++ /dev/null @@ -1,13 +0,0 @@ -# -# CALAO Systems USB-A9260-C01 -# -# http://www.calao-systems.com/ -# - -interface ft2232 -ft2232_layout jtagkey -ft2232_device_desc "USB-A9260" -ft2232_vid_pid 0x0403 0x6010 -script interface/calao-usb-a9260.cfg -script target/at91sam9260minimal.cfg - diff --git a/tcl/interface/calao-usb-a9260-c02.cfg b/tcl/interface/calao-usb-a9260-c02.cfg deleted file mode 100644 index 2461b70dc..000000000 --- a/tcl/interface/calao-usb-a9260-c02.cfg +++ /dev/null @@ -1,13 +0,0 @@ -# -# CALAO Systems USB-A9260-C02 -# -# http://www.calao-systems.com/ -# - -interface ft2232 -ft2232_layout jtagkey -ft2232_device_desc "USB-A9260" -ft2232_vid_pid 0x0403 0x6001 -script interface/calao-usb-a9260.cfg -script target/at91sam9260minimal.cfg - diff --git a/tcl/interface/calao-usb-a9260.cfg b/tcl/interface/calao-usb-a9260.cfg deleted file mode 100644 index 5fae2f3b3..000000000 --- a/tcl/interface/calao-usb-a9260.cfg +++ /dev/null @@ -1,11 +0,0 @@ -# -# CALAO Systems USB-A9260 common -C01 -C02 setup -# -# http://www.calao-systems.com/ -# -# See calao-usb-a9260-c01.cfg and calao-usb-a9260-c02.cfg. -# - -adapter_nsrst_delay 200 -jtag_ntrst_delay 200 - diff --git a/tcl/interface/chameleon.cfg b/tcl/interface/chameleon.cfg deleted file mode 100644 index 2fb74681c..000000000 --- a/tcl/interface/chameleon.cfg +++ /dev/null @@ -1,9 +0,0 @@ -# -# Amontec Chameleon POD -# -# http://www.amontec.com/chameleon.shtml -# - -interface parport -parport_cable chameleon - diff --git a/tcl/interface/cmsis-dap.cfg b/tcl/interface/cmsis-dap.cfg deleted file mode 100644 index ab5c187eb..000000000 --- a/tcl/interface/cmsis-dap.cfg +++ /dev/null @@ -1,10 +0,0 @@ -# -# ARM CMSIS-DAP compliant adapter -# -# http://www.keil.com/support/man/docs/dapdebug/ -# - -interface cmsis-dap - -# Optionally specify the serial number of CMSIS-DAP usb device. -#cmsis_dap_serial 02200201E6661E601B98E3B9 diff --git a/tcl/interface/cortino.cfg b/tcl/interface/cortino.cfg deleted file mode 100644 index e2b230110..000000000 --- a/tcl/interface/cortino.cfg +++ /dev/null @@ -1,11 +0,0 @@ -# -# Hitex Cortino -# -# http://www.hitex.com/index.php?id=cortino -# - -interface ft2232 -ft2232_device_desc "Cortino" -ft2232_layout cortino -ft2232_vid_pid 0x0640 0x0032 - diff --git a/tcl/interface/digilent-hs1.cfg b/tcl/interface/digilent-hs1.cfg deleted file mode 100644 index e35f0cfc7..000000000 --- a/tcl/interface/digilent-hs1.cfg +++ /dev/null @@ -1,15 +0,0 @@ -# -# Digilent HS1 -# -# The Digilent HS1 is a high-speed FT2232H-based adapter, compliant with the -# Xilinx JTAG 14-pin pinout. -# It does not support ARM reset signals (SRST and TRST) but can still be used for -# hardware debugging, with some limitations. -# -# http://www.digilentinc.com/Products/Detail.cfm?NavPath=2,395,922&Prod=JTAG-HS1 -# - -interface ft2232 -ft2232_device_desc "Digilent Adept USB Device" -ft2232_layout digilent-hs1 -ft2232_vid_pid 0x0403 0x6010 diff --git a/tcl/interface/dlp-usb1232h.cfg b/tcl/interface/dlp-usb1232h.cfg deleted file mode 100644 index 743241380..000000000 --- a/tcl/interface/dlp-usb1232h.cfg +++ /dev/null @@ -1,14 +0,0 @@ -# -# DLP Design DLP-USB1232H USB-to-UART/FIFO interface module -# -# http://www.dlpdesign.com/usb/usb1232h.shtml -# -# Schematics for OpenOCD usage: -# http://randomprojects.org/wiki/DLP-USB1232H_and_OpenOCD_based_JTAG_adapter -# - -interface ft2232 -ft2232_device_desc "Dual RS232-HS" -ft2232_layout usbjtag -ft2232_vid_pid 0x0403 0x6010 - diff --git a/tcl/interface/dummy.cfg b/tcl/interface/dummy.cfg deleted file mode 100644 index 1c148c0cb..000000000 --- a/tcl/interface/dummy.cfg +++ /dev/null @@ -1,6 +0,0 @@ -# -# Dummy interface (for testing purposes) -# - -interface dummy - diff --git a/tcl/interface/estick.cfg b/tcl/interface/estick.cfg deleted file mode 100644 index adefcb73f..000000000 --- a/tcl/interface/estick.cfg +++ /dev/null @@ -1,7 +0,0 @@ -# -# eStick -# -# http://code.google.com/p/estick-jtag/ -# - -interface opendous diff --git a/tcl/interface/flashlink.cfg b/tcl/interface/flashlink.cfg deleted file mode 100644 index 56dc35e20..000000000 --- a/tcl/interface/flashlink.cfg +++ /dev/null @@ -1,16 +0,0 @@ -# -# ST FlashLINK JTAG parallel cable -# -# http://www.st.com/internet/evalboard/product/94023.jsp -# http://www.st.com/stonline/products/literature/um/7889.pdf -# - -if { [info exists PARPORTADDR] } { - set _PARPORTADDR $PARPORTADDR -} else { - set _PARPORTADDR 0 -} - -interface parport -parport_port $_PARPORTADDR -parport_cable flashlink diff --git a/tcl/interface/flossjtag-noeeprom.cfg b/tcl/interface/flossjtag-noeeprom.cfg deleted file mode 100644 index 66c010bc0..000000000 --- a/tcl/interface/flossjtag-noeeprom.cfg +++ /dev/null @@ -1,19 +0,0 @@ -# -# FlossJTAG -# -# http://github.com/esden/floss-jtag -# -# This is the pre v0.3 Floss-JTAG compatible config file. It can also be used -# for newer versions of Floss-JTAG with empty or not populated EEPROM. If you -# have several Floss-JTAG connected you have to use the USB ID to select a -# specific one. -# -# If you have a Floss-JTAG WITH EEPROM that is programmed, use the -# flossjtag.cfg file. -# - -interface ft2232 -ft2232_vid_pid 0x0403 0x6010 -ft2232_device_desc "Dual RS232-HS" -ft2232_layout "usbjtag" -ft2232_latency 2 diff --git a/tcl/interface/flossjtag.cfg b/tcl/interface/flossjtag.cfg deleted file mode 100644 index fbbabc105..000000000 --- a/tcl/interface/flossjtag.cfg +++ /dev/null @@ -1,20 +0,0 @@ -# -# FlossJTAG -# -# http://github.com/esden/floss-jtag -# -# This is the v0.3 and v1.0 Floss-JTAG compatible config file. It relies on the -# existence of an EEPROM on Floss-JTAG containing a name. If you have several -# Floss-JTAG adapters connected you can use the serial number to select a -# specific device. -# -# If your Floss-JTAG does not have an EEPROM, or the EEPROM is empty, use the -# flossjtag-noeeprom.cfg file. -# - -interface ft2232 -ft2232_vid_pid 0x0403 0x6010 -ft2232_device_desc "FLOSS-JTAG" -#ft2232_serial "FJ000001" -ft2232_layout "flossjtag" -ft2232_latency 2 diff --git a/tcl/interface/flyswatter.cfg b/tcl/interface/flyswatter.cfg deleted file mode 100644 index 5bac05b61..000000000 --- a/tcl/interface/flyswatter.cfg +++ /dev/null @@ -1,10 +0,0 @@ -# -# TinCanTools Flyswatter -# -# http://www.tincantools.com/product.php?productid=16134 -# - -interface ft2232 -ft2232_device_desc "Flyswatter" -ft2232_layout "flyswatter" -ft2232_vid_pid 0x0403 0x6010 diff --git a/tcl/interface/flyswatter2.cfg b/tcl/interface/flyswatter2.cfg deleted file mode 100644 index 21e7fedc8..000000000 --- a/tcl/interface/flyswatter2.cfg +++ /dev/null @@ -1,10 +0,0 @@ -# -# TinCanTools Flyswatter 2 -# -# http://www.tincantools.com/product.php?productid=16153 -# - -interface ft2232 -ft2232_device_desc "Flyswatter2" -ft2232_layout "flyswatter2" -ft2232_vid_pid 0x0403 0x6010 diff --git a/tcl/interface/ftdi/100ask-openjtag.cfg b/tcl/interface/ftdi/100ask-openjtag.cfg deleted file mode 100644 index 01ae2f7ea..000000000 --- a/tcl/interface/ftdi/100ask-openjtag.cfg +++ /dev/null @@ -1,16 +0,0 @@ -# -# www.100ask.org OpenJTAG -# -# http://www.100ask.net/OpenJTAG.html -# -# Schematics are available from -# https://blog.matthiasbock.net/wp-content/uploads/2015/04/100ask-JTAGv3.pdf -# - -interface ftdi -ftdi_device_desc "USB<=>JTAG&RS232" -ftdi_vid_pid 0x1457 0x5118 - -ftdi_layout_init 0x0f08 0x0f1b -ftdi_layout_signal nSRST -data 0x0200 -noe 0x0800 -ftdi_layout_signal nTRST -data 0x0100 -noe 0x0400 diff --git a/tcl/interface/ftdi/axm0432.cfg b/tcl/interface/ftdi/axm0432.cfg deleted file mode 100644 index 0c24a333e..000000000 --- a/tcl/interface/ftdi/axm0432.cfg +++ /dev/null @@ -1,18 +0,0 @@ -# -# Axiom axm0432 -# -# http://www.axman.com -# - -echo "WARNING!" -echo "This file was not tested with real interface, it is based on code in ft2232.c." -echo "Please report your experience with this file to openocd-devel mailing list," -echo "so it could be marked as working or fixed." - -interface ftdi -ftdi_device_desc "Symphony SoundBite" -ftdi_vid_pid 0x0403 0x6010 - -ftdi_layout_init 0x0c08 0x0c2b -ftdi_layout_signal nTRST -data 0x0800 -ftdi_layout_signal nSRST -data 0x0400 diff --git a/tcl/interface/ftdi/calao-usb-a9260-c01.cfg b/tcl/interface/ftdi/calao-usb-a9260-c01.cfg deleted file mode 100644 index d3da6b7ec..000000000 --- a/tcl/interface/ftdi/calao-usb-a9260-c01.cfg +++ /dev/null @@ -1,22 +0,0 @@ -# -# CALAO Systems USB-A9260-C01 -# -# http://www.calao-systems.com/ -# - -echo "WARNING!" -echo "This file was not tested with real interface, but is assumed to work as this" -echo "interface uses the same layout as configs that were verified. Please report your" -echo "experience with this file to openocd-devel mailing list, so it could be marked" -echo "as working or fixed." - -interface ftdi -ftdi_device_desc "USB-A9260" -ftdi_vid_pid 0x0403 0x6010 - -ftdi_layout_init 0x0c08 0x0f1b -ftdi_layout_signal nTRST -data 0x0100 -noe 0x0400 -ftdi_layout_signal nSRST -data 0x0200 -noe 0x0800 - -script interface/calao-usb-a9260.cfg -script target/at91sam9260minimal.cfg diff --git a/tcl/interface/ftdi/calao-usb-a9260-c02.cfg b/tcl/interface/ftdi/calao-usb-a9260-c02.cfg deleted file mode 100644 index dc4dca8f7..000000000 --- a/tcl/interface/ftdi/calao-usb-a9260-c02.cfg +++ /dev/null @@ -1,22 +0,0 @@ -# -# CALAO Systems USB-A9260-C02 -# -# http://www.calao-systems.com/ -# - -echo "WARNING!" -echo "This file was not tested with real interface, but is assumed to work as this" -echo "interface uses the same layout as configs that were verified. Please report your" -echo "experience with this file to openocd-devel mailing list, so it could be marked" -echo "as working or fixed." - -interface ftdi -ftdi_device_desc "USB-A9260" -ftdi_vid_pid 0x0403 0x6001 - -ftdi_layout_init 0x0c08 0x0f1b -ftdi_layout_signal nTRST -data 0x0100 -noe 0x0400 -ftdi_layout_signal nSRST -data 0x0200 -noe 0x0800 - -script interface/calao-usb-a9260.cfg -script target/at91sam9260minimal.cfg diff --git a/tcl/interface/ftdi/cortino.cfg b/tcl/interface/ftdi/cortino.cfg deleted file mode 100644 index 16ede6129..000000000 --- a/tcl/interface/ftdi/cortino.cfg +++ /dev/null @@ -1,13 +0,0 @@ -# -# Hitex Cortino -# -# http://www.hitex.com/index.php?id=cortino -# - -interface ftdi -ftdi_device_desc "Cortino" -ftdi_vid_pid 0x0640 0x0032 - -ftdi_layout_init 0x0108 0x010b -ftdi_layout_signal nTRST -data 0x0100 -ftdi_layout_signal nSRST -data 0x0200 -oe 0x0200 diff --git a/tcl/interface/ftdi/digilent-hs1.cfg b/tcl/interface/ftdi/digilent-hs1.cfg deleted file mode 100644 index e27249b3b..000000000 --- a/tcl/interface/ftdi/digilent-hs1.cfg +++ /dev/null @@ -1,11 +0,0 @@ -# this supports JTAG-HS1 and JTAG-SMT1 -# (the later being the OEM on-board version) - -interface ftdi -ftdi_device_desc "Digilent Adept USB Device" -ftdi_vid_pid 0x0403 0x6010 -# channel 1 does not have any functionality -ftdi_channel 0 -# just TCK TDI TDO TMS, no reset -ftdi_layout_init 0x0088 0x008b -reset_config none diff --git a/tcl/interface/ftdi/digilent-hs2.cfg b/tcl/interface/ftdi/digilent-hs2.cfg deleted file mode 100644 index 2005b66af..000000000 --- a/tcl/interface/ftdi/digilent-hs2.cfg +++ /dev/null @@ -1,10 +0,0 @@ -# this supports JTAG-HS2 (and apparently Nexys4 as well) - -interface ftdi -ftdi_device_desc "Digilent Adept USB Device" -ftdi_vid_pid 0x0403 0x6014 - -ftdi_channel 0 -ftdi_layout_init 0x00e8 0x60eb - -reset_config none diff --git a/tcl/interface/ftdi/digilent_jtag_hs3.cfg b/tcl/interface/ftdi/digilent_jtag_hs3.cfg deleted file mode 100644 index f7b8e570c..000000000 --- a/tcl/interface/ftdi/digilent_jtag_hs3.cfg +++ /dev/null @@ -1,13 +0,0 @@ -# -# Digilent JTAG-HS3 -# - -interface ftdi -ftdi_vid_pid 0x0403 0x6014 -ftdi_device_desc "Digilent USB Device" - -# From Digilent support: -# The SRST pin is [...] 0x20 and 0x10 is the /OE (active low output enable) - -ftdi_layout_init 0x2088 0x308b -ftdi_layout_signal nSRST -data 0x2000 -noe 0x1000 diff --git a/tcl/interface/ftdi/digilent_jtag_smt2.cfg b/tcl/interface/ftdi/digilent_jtag_smt2.cfg deleted file mode 100644 index 014fe1475..000000000 --- a/tcl/interface/ftdi/digilent_jtag_smt2.cfg +++ /dev/null @@ -1,17 +0,0 @@ -# -# Digilent JTAG-SMT2 -# -# http://www.digilentinc.com/Products/Detail.cfm?NavPath=2,395,1053&Prod=JTAG-SMT2 -# -# Config is based on data from -# http://electronix.ru/forum/index.php?showtopic=114633&view=findpost&p=1215497 and ZedBoard schematics -# - -interface ftdi -ftdi_vid_pid 0x0403 0x6014 - -ftdi_layout_init 0x2088 0x3f8b -ftdi_layout_signal nSRST -data 0x2000 -ftdi_layout_signal GPIO2 -data 0x2000 -ftdi_layout_signal GPIO1 -data 0x0200 -ftdi_layout_signal GPIO0 -data 0x0100 diff --git a/tcl/interface/ftdi/dlp-usb1232h.cfg b/tcl/interface/ftdi/dlp-usb1232h.cfg deleted file mode 100644 index f447771e3..000000000 --- a/tcl/interface/ftdi/dlp-usb1232h.cfg +++ /dev/null @@ -1,21 +0,0 @@ -# -# DLP Design DLP-USB1232H USB-to-UART/FIFO interface module -# -# http://www.dlpdesign.com/usb/usb1232h.shtml -# -# Schematics for OpenOCD usage: -# http://randomprojects.org/wiki/DLP-USB1232H_and_OpenOCD_based_JTAG_adapter -# - -echo "WARNING!" -echo "This file was not tested with real interface, it is based on schematics and code" -echo "in ft2232.c. Please report your experience with this file to openocd-devel" -echo "mailing list, so it could be marked as working or fixed." - -interface ftdi -ftdi_device_desc "Dual RS232-HS" -ftdi_vid_pid 0x0403 0x6010 - -ftdi_layout_init 0x0008 0x000b -ftdi_layout_signal nTRST -data 0x0010 -oe 0x0010 -ftdi_layout_signal nSRST -data 0x0040 -oe 0x0040 diff --git a/tcl/interface/ftdi/dp_busblaster.cfg b/tcl/interface/ftdi/dp_busblaster.cfg deleted file mode 100644 index 73827cfb8..000000000 --- a/tcl/interface/ftdi/dp_busblaster.cfg +++ /dev/null @@ -1,20 +0,0 @@ -# -# Dangerous Prototypes - Bus Blaster -# -# The Bus Blaster has a configurable buffer between the FTDI FT2232H and the -# JTAG header which allows it to emulate various debugger types. It comes -# configured as a JTAGkey device. -# -# http://dangerousprototypes.com/docs/Bus_Blaster -# - -echo "Info : If you need SWD support, flash KT-Link buffer from https://github.com/bharrisau/busblaster -and use dp_busblaster_kt-link.cfg instead" - -interface ftdi -ftdi_device_desc "Dual RS232-HS" -ftdi_vid_pid 0x0403 0x6010 - -ftdi_layout_init 0x0c08 0x0f1b -ftdi_layout_signal nTRST -data 0x0100 -noe 0x0400 -ftdi_layout_signal nSRST -data 0x0200 -noe 0x0800 diff --git a/tcl/interface/ftdi/dp_busblaster_kt-link.cfg b/tcl/interface/ftdi/dp_busblaster_kt-link.cfg deleted file mode 100644 index 2d27519d4..000000000 --- a/tcl/interface/ftdi/dp_busblaster_kt-link.cfg +++ /dev/null @@ -1,21 +0,0 @@ -# -# Dangerous Prototypes - Bus Blaster (with KT-Link buffer) -# -# The Bus Blaster has a configurable buffer between the FTDI FT2232H -# and the JTAG header which allows it to emulate various debugger -# types. This config works with KT-Link compatible implementation from -# https://github.com/bharrisau/busblaster and is SWD-enabled. -# -# http://dangerousprototypes.com/docs/Bus_Blaster -# - -interface ftdi -ftdi_device_desc "Dual RS232-HS" -ftdi_vid_pid 0x0403 0x6010 - -ftdi_layout_init 0x8c28 0xff3b -ftdi_layout_signal nTRST -data 0x0100 -noe 0x0400 -ftdi_layout_signal nSRST -data 0x0200 -noe 0x0800 -ftdi_layout_signal LED -ndata 0x8000 -ftdi_layout_signal SWD_EN -ndata 0x0020 -oe 0x2000 -ftdi_layout_signal SWDIO_OE -ndata 0x1000 diff --git a/tcl/interface/ftdi/flossjtag-noeeprom.cfg b/tcl/interface/ftdi/flossjtag-noeeprom.cfg deleted file mode 100644 index 18046e742..000000000 --- a/tcl/interface/ftdi/flossjtag-noeeprom.cfg +++ /dev/null @@ -1,26 +0,0 @@ -# -# FlossJTAG -# -# http://github.com/esden/floss-jtag -# -# This is the pre v0.3 Floss-JTAG compatible config file. It can also be used -# for newer versions of Floss-JTAG with empty or not populated EEPROM. If you -# have several Floss-JTAG connected you have to use the USB ID to select a -# specific one. -# -# If you have a Floss-JTAG WITH EEPROM that is programmed, use the -# flossjtag.cfg file. -# - -echo "WARNING!" -echo "This file was not tested with real interface, it is based on code in ft2232.c." -echo "Please report your experience with this file to openocd-devel mailing list," -echo "so it could be marked as working or fixed." - -interface ftdi -ftdi_device_desc "Dual RS232-HS" -ftdi_vid_pid 0x0403 0x6010 - -ftdi_layout_init 0x0008 0x000b -ftdi_layout_signal nTRST -data 0x0010 -oe 0x0010 -ftdi_layout_signal nSRST -data 0x0040 -oe 0x0040 diff --git a/tcl/interface/ftdi/flossjtag.cfg b/tcl/interface/ftdi/flossjtag.cfg deleted file mode 100644 index 13e1f0bb7..000000000 --- a/tcl/interface/ftdi/flossjtag.cfg +++ /dev/null @@ -1,29 +0,0 @@ -# -# FlossJTAG -# -# http://github.com/esden/floss-jtag -# -# This is the v0.3 and v1.0 Floss-JTAG compatible config file. It relies on the -# existence of an EEPROM on Floss-JTAG containing a name. If you have several -# Floss-JTAG adapters connected you can use the serial number to select a -# specific device. -# -# If your Floss-JTAG does not have an EEPROM, or the EEPROM is empty, use the -# flossjtag-noeeprom.cfg file. -# - -echo "WARNING!" -echo "This file was not tested with real interface, it is based on code in ft2232.c." -echo "Please report your experience with this file to openocd-devel mailing list," -echo "so it could be marked as working or fixed." - -interface ftdi -ftdi_vid_pid 0x0403 0x6010 -ftdi_device_desc "FLOSS-JTAG" -#ftdi_serial "FJ000001" - -ftdi_layout_init 0x0008 0x180b -ftdi_layout_signal nTRST -data 0x0010 -oe 0x0010 -ftdi_layout_signal nSRST -data 0x0040 -oe 0x0040 -ftdi_layout_signal LED -data 0x0800 -ftdi_layout_signal LED2 -data 0x1000 diff --git a/tcl/interface/ftdi/flyswatter.cfg b/tcl/interface/ftdi/flyswatter.cfg deleted file mode 100644 index 56dab1f33..000000000 --- a/tcl/interface/ftdi/flyswatter.cfg +++ /dev/null @@ -1,14 +0,0 @@ -# -# TinCanTools Flyswatter -# -# http://www.tincantools.com/product.php?productid=16134 -# - -interface ftdi -ftdi_device_desc "Flyswatter" -ftdi_vid_pid 0x0403 0x6010 - -ftdi_layout_init 0x0818 0x0cfb -ftdi_layout_signal nTRST -data 0x0010 -ftdi_layout_signal nSRST -oe 0x0020 -ftdi_layout_signal LED -data 0x0c00 diff --git a/tcl/interface/ftdi/flyswatter2.cfg b/tcl/interface/ftdi/flyswatter2.cfg deleted file mode 100644 index 8bd4db4b7..000000000 --- a/tcl/interface/ftdi/flyswatter2.cfg +++ /dev/null @@ -1,14 +0,0 @@ -# -# TinCanTools Flyswatter2 -# -# http://www.tincantools.com/product.php?productid=16153 -# - -interface ftdi -ftdi_device_desc "Flyswatter2" -ftdi_vid_pid 0x0403 0x6010 - -ftdi_layout_init 0x0538 0x057b -ftdi_layout_signal LED -ndata 0x0400 -ftdi_layout_signal nTRST -data 0x0010 -ftdi_layout_signal nSRST -data 0x0020 -noe 0x0100 diff --git a/tcl/interface/ftdi/gw16042.cfg b/tcl/interface/ftdi/gw16042.cfg deleted file mode 100644 index 90c6f7c12..000000000 --- a/tcl/interface/ftdi/gw16042.cfg +++ /dev/null @@ -1,26 +0,0 @@ -# -# Gateworks GW16042 JTAG Dongle -# -# http://www.gateworks.com/ -# -# Layout: FTDI FT2232H -# ADBUS0 TCK -# ADBUS1 TDI -# ADBUS2 TDO (input) -# ADBUS3 TMS -# ADBUS4 nTRST -# ADBUS5 nSRST -# ADBUS6 OE (active high) for TRST, TDI, TMS, TCK -# ADBUS7 NC -# ACBUS0-7 NC -# BDBUS0 RXD -# BDBUS1 TXD (input) -# - -interface ftdi -ftdi_device_desc "USB-JTAG" -ftdi_vid_pid 0x0403 0x6010 - -ftdi_layout_init 0x0058 0x007b -ftdi_layout_signal nTRST -data 0x0010 -ftdi_layout_signal nSRST -oe 0x0020 diff --git a/tcl/interface/ftdi/hilscher_nxhx10_etm.cfg b/tcl/interface/ftdi/hilscher_nxhx10_etm.cfg deleted file mode 100644 index b682333ed..000000000 --- a/tcl/interface/ftdi/hilscher_nxhx10_etm.cfg +++ /dev/null @@ -1,18 +0,0 @@ -# -# Hilscher NXHX 10-ETM -# -# http://de.hilscher.com/products_details_hardware.html?p_id=P_4ce145a5983e6 -# - -echo "WARNING!" -echo "This file was not tested with real interface, it is based on code in ft2232.c." -echo "Please report your experience with this file to openocd-devel mailing list," -echo "so it could be marked as working or fixed." - -interface ftdi -ftdi_device_desc "NXHX 10-ETM" -ftdi_vid_pid 0x0640 0x0028 - -ftdi_layout_init 0x0308 0x030b -ftdi_layout_signal nTRST -data 0x0100 -ftdi_layout_signal nSRST -data 0x0200 diff --git a/tcl/interface/ftdi/hilscher_nxhx500_etm.cfg b/tcl/interface/ftdi/hilscher_nxhx500_etm.cfg deleted file mode 100644 index 3483030c6..000000000 --- a/tcl/interface/ftdi/hilscher_nxhx500_etm.cfg +++ /dev/null @@ -1,18 +0,0 @@ -# -# Hilscher NXHX 500-ETM -# -# http://de.hilscher.com/files_design/8/NXHX500-ETM_description_Rev01_EN.pdf -# - -echo "WARNING!" -echo "This file was not tested with real interface, it is based on code in ft2232.c." -echo "Please report your experience with this file to openocd-devel mailing list," -echo "so it could be marked as working or fixed." - -interface ftdi -ftdi_device_desc "NXHX 500-ETM" -ftdi_vid_pid 0x0640 0x0028 - -ftdi_layout_init 0x0308 0x030b -ftdi_layout_signal nTRST -data 0x0100 -ftdi_layout_signal nSRST -data 0x0200 diff --git a/tcl/interface/ftdi/hilscher_nxhx500_re.cfg b/tcl/interface/ftdi/hilscher_nxhx500_re.cfg deleted file mode 100644 index b4cada055..000000000 --- a/tcl/interface/ftdi/hilscher_nxhx500_re.cfg +++ /dev/null @@ -1,18 +0,0 @@ -# -# Hilscher NXHX 500-RE -# -# http://de.hilscher.com/products_details_hardware.html?p_id=P_461ff2053bad1&bs=20 -# - -echo "WARNING!" -echo "This file was not tested with real interface, it is based on code in ft2232.c." -echo "Please report your experience with this file to openocd-devel mailing list," -echo "so it could be marked as working or fixed." - -interface ftdi -ftdi_device_desc "NXHX 500-RE" -ftdi_vid_pid 0x0640 0x0028 - -ftdi_layout_init 0x0308 0x030b -ftdi_layout_signal nTRST -data 0x0100 -ftdi_layout_signal nSRST -data 0x0200 diff --git a/tcl/interface/ftdi/hilscher_nxhx50_etm.cfg b/tcl/interface/ftdi/hilscher_nxhx50_etm.cfg deleted file mode 100644 index 67074a263..000000000 --- a/tcl/interface/ftdi/hilscher_nxhx50_etm.cfg +++ /dev/null @@ -1,18 +0,0 @@ -# -# Hilscher NXHX 50-ETM -# -# http://de.hilscher.com/files_design/8/NXHX50-ETM_description_Rev01_EN.pdf -# - -echo "WARNING!" -echo "This file was not tested with real interface, it is based on code in ft2232.c." -echo "Please report your experience with this file to openocd-devel mailing list," -echo "so it could be marked as working or fixed." - -interface ftdi -ftdi_device_desc "NXHX 50-ETM" -ftdi_vid_pid 0x0640 0x0028 - -ftdi_layout_init 0x0308 0x030b -ftdi_layout_signal nTRST -data 0x0100 -ftdi_layout_signal nSRST -data 0x0200 diff --git a/tcl/interface/ftdi/hilscher_nxhx50_re.cfg b/tcl/interface/ftdi/hilscher_nxhx50_re.cfg deleted file mode 100644 index 966dcd812..000000000 --- a/tcl/interface/ftdi/hilscher_nxhx50_re.cfg +++ /dev/null @@ -1,18 +0,0 @@ -# -# Hilscher NXHX 50-RE -# -# http://de.hilscher.com/products_details_hardware.html?p_id=P_483c0f582ad36&bs=20 -# - -echo "WARNING!" -echo "This file was not tested with real interface, it is based on code in ft2232.c." -echo "Please report your experience with this file to openocd-devel mailing list," -echo "so it could be marked as working or fixed." - -interface ftdi -ftdi_device_desc "NXHX50-RE" -ftdi_vid_pid 0x0640 0x0028 - -ftdi_layout_init 0x0308 0x030b -ftdi_layout_signal nTRST -data 0x0100 -ftdi_layout_signal nSRST -data 0x0200 diff --git a/tcl/interface/ftdi/hitex_lpc1768stick.cfg b/tcl/interface/ftdi/hitex_lpc1768stick.cfg deleted file mode 100644 index f22d4f7b2..000000000 --- a/tcl/interface/ftdi/hitex_lpc1768stick.cfg +++ /dev/null @@ -1,15 +0,0 @@ -# -# Hitex LPC1768-Stick -# -# http://www.hitex.com/?id=1602 -# - - -interface ftdi -ftdi_device_desc "LPC1768-Stick" -ftdi_vid_pid 0x0640 0x0026 - -ftdi_layout_init 0x0388 0x038b -ftdi_layout_signal nTRST -data 0x0100 -ftdi_layout_signal nSRST -data 0x0080 -noe 0x200 - diff --git a/tcl/interface/ftdi/hitex_str9-comstick.cfg b/tcl/interface/ftdi/hitex_str9-comstick.cfg deleted file mode 100644 index c46f0322c..000000000 --- a/tcl/interface/ftdi/hitex_str9-comstick.cfg +++ /dev/null @@ -1,13 +0,0 @@ -# -# Hitex STR9-comStick -# -# http://www.hitex.com/index.php?id=383 -# - -interface ftdi -ftdi_device_desc "STR9-comStick" -ftdi_vid_pid 0x0640 0x002c - -ftdi_layout_init 0x0108 0x010b -ftdi_layout_signal nTRST -data 0x0100 -ftdi_layout_signal nSRST -data 0x0200 -oe 0x0200 diff --git a/tcl/interface/ftdi/icebear.cfg b/tcl/interface/ftdi/icebear.cfg deleted file mode 100644 index 2c03d417b..000000000 --- a/tcl/interface/ftdi/icebear.cfg +++ /dev/null @@ -1,18 +0,0 @@ -# -# Section5 ICEBear -# -# http://section5.ch/icebear -# - -echo "WARNING!" -echo "This file was not tested with real interface, it is based on code in ft2232.c." -echo "Please report your experience with this file to openocd-devel mailing list," -echo "so it could be marked as working or fixed." - -interface ftdi -ftdi_device_desc "ICEbear JTAG adapter" -ftdi_vid_pid 0x0403 0xc140 - -ftdi_layout_init 0x0028 0x002b -ftdi_layout_signal nTRST -data 0x0010 -oe 0x0010 -ftdi_layout_signal nSRST -data 0x0020 diff --git a/tcl/interface/ftdi/iotlab-usb.cfg b/tcl/interface/ftdi/iotlab-usb.cfg deleted file mode 100644 index fbbad0c86..000000000 --- a/tcl/interface/ftdi/iotlab-usb.cfg +++ /dev/null @@ -1,11 +0,0 @@ -# -# This is the integrated adapter as found on the IoT-LAB boards -# https://github.com/iot-lab/iot-lab/wiki -# - -interface ftdi -ftdi_vid_pid 0x0403 0x6010 - -ftdi_layout_init 0x0008 0x000b -ftdi_layout_signal nTRST -data 0x0010 -oe 0x0010 -ftdi_layout_signal nSRST -data 0x0040 -oe 0x0040 diff --git a/tcl/interface/ftdi/jtag-lock-pick_tiny_2.cfg b/tcl/interface/ftdi/jtag-lock-pick_tiny_2.cfg deleted file mode 100644 index c5e5db420..000000000 --- a/tcl/interface/ftdi/jtag-lock-pick_tiny_2.cfg +++ /dev/null @@ -1,16 +0,0 @@ -# -# DISTORTEC JTAG-lock-pick Tiny 2 -# -# http://www.distortec.com -# - -interface ftdi -ftdi_device_desc "JTAG-lock-pick Tiny 2" -ftdi_vid_pid 0x0403 0x8220 - -ftdi_layout_init 0x8c28 0xff3b -ftdi_layout_signal SWD_EN -ndata 0x0020 -oe 0x2000 -ftdi_layout_signal nTRST -data 0x0100 -noe 0x0400 -ftdi_layout_signal nSRST -data 0x0200 -noe 0x0800 -ftdi_layout_signal SWDIO_OE -ndata 0x1000 -ftdi_layout_signal LED -ndata 0x8000 diff --git a/tcl/interface/ftdi/jtagkey.cfg b/tcl/interface/ftdi/jtagkey.cfg deleted file mode 100644 index 7b87e6df1..000000000 --- a/tcl/interface/ftdi/jtagkey.cfg +++ /dev/null @@ -1,13 +0,0 @@ -# -# Amontec JTAGkey -# -# http://www.amontec.com/jtagkey.shtml -# - -interface ftdi -ftdi_device_desc "Amontec JTAGkey" -ftdi_vid_pid 0x0403 0xcff8 - -ftdi_layout_init 0x0c08 0x0f1b -ftdi_layout_signal nTRST -data 0x0100 -noe 0x0400 -ftdi_layout_signal nSRST -data 0x0200 -noe 0x0800 diff --git a/tcl/interface/ftdi/jtagkey2.cfg b/tcl/interface/ftdi/jtagkey2.cfg deleted file mode 100644 index c6c2b32f4..000000000 --- a/tcl/interface/ftdi/jtagkey2.cfg +++ /dev/null @@ -1,13 +0,0 @@ -# -# Amontec JTAGkey2 -# -# http://www.amontec.com/jtagkey2.shtml -# - -interface ftdi -ftdi_device_desc "Amontec JTAGkey-2" -ftdi_vid_pid 0x0403 0xcff8 - -ftdi_layout_init 0x0c08 0x0f1b -ftdi_layout_signal nTRST -data 0x0100 -noe 0x0400 -ftdi_layout_signal nSRST -data 0x0200 -noe 0x0800 diff --git a/tcl/interface/ftdi/jtagkey2p.cfg b/tcl/interface/ftdi/jtagkey2p.cfg deleted file mode 100644 index dc9c4565e..000000000 --- a/tcl/interface/ftdi/jtagkey2p.cfg +++ /dev/null @@ -1,13 +0,0 @@ -# -# Amontec JTAGkey2P -# -# http://www.amontec.com/jtagkey2p.shtml -# - -interface ftdi -ftdi_device_desc "Amontec JTAGkey-2P" -ftdi_vid_pid 0x0403 0xcff8 - -ftdi_layout_init 0x0c08 0x0f1b -ftdi_layout_signal nTRST -data 0x0100 -noe 0x0400 -ftdi_layout_signal nSRST -data 0x0200 -noe 0x0800 diff --git a/tcl/interface/ftdi/kt-link.cfg b/tcl/interface/ftdi/kt-link.cfg deleted file mode 100644 index 1f28d3a10..000000000 --- a/tcl/interface/ftdi/kt-link.cfg +++ /dev/null @@ -1,16 +0,0 @@ -# -# Kristech KT-Link -# -# http://www.kristech.eu -# - -interface ftdi -ftdi_device_desc "KT-LINK" -ftdi_vid_pid 0x0403 0xbbe2 - -ftdi_layout_init 0x8c28 0xff3b -ftdi_layout_signal nTRST -data 0x0100 -noe 0x0400 -ftdi_layout_signal nSRST -data 0x0200 -noe 0x0800 -ftdi_layout_signal LED -data 0x8000 -ftdi_layout_signal SWD_EN -ndata 0x0020 -oe 0x2000 -ftdi_layout_signal SWDIO_OE -ndata 0x1000 diff --git a/tcl/interface/ftdi/lisa-l.cfg b/tcl/interface/ftdi/lisa-l.cfg deleted file mode 100644 index 67002bb96..000000000 --- a/tcl/interface/ftdi/lisa-l.cfg +++ /dev/null @@ -1,20 +0,0 @@ -# -# Lisa/L -# -# http://paparazzi.enac.fr/wiki/Lisa -# - -echo "WARNING!" -echo "This file was not tested with real interface, it is based on schematics and code" -echo "in ft2232.c. Please report your experience with this file to openocd-devel" -echo "mailing list, so it could be marked as working or fixed." - -interface ftdi -ftdi_device_desc "Lisa/L" -ftdi_vid_pid 0x0403 0x6010 -ftdi_channel 1 - -ftdi_layout_init 0x0008 0x180b -ftdi_layout_signal nTRST -data 0x0010 -oe 0x0010 -ftdi_layout_signal nSRST -data 0x0040 -oe 0x0040 -ftdi_layout_signal LED -data 0x1800 diff --git a/tcl/interface/ftdi/luminary-icdi.cfg b/tcl/interface/ftdi/luminary-icdi.cfg deleted file mode 100644 index 2eea806d6..000000000 --- a/tcl/interface/ftdi/luminary-icdi.cfg +++ /dev/null @@ -1,25 +0,0 @@ -# -# Luminary Micro Stellaris LM3S9B9x Evaluation Kits -# In-Circuit Debug Interface (ICDI) Board -# -# Essentially all Luminary debug hardware is the same, (with both -# JTAG and SWD support compatible with ICDI boards. This ICDI adapter -# configuration is JTAG-only, but the same hardware handles SWD too. -# -# This is a discrete ftdi based debug board which supports ARM's -# JTAG/SWD connectors in both backwards-compatible 20-pin format and -# in the new-style compact 10-pin. There's also an 8-pin connector -# with serial port support. It's included with LM3S9B9x eval boards. -# -# http://www.luminarymicro.com/products/ek-lm3s9b90.html -# http://www.luminarymicro.com/products/ek-lm3s9b92.html -# - -interface ftdi -ftdi_device_desc "Luminary Micro ICDI Board" -ftdi_vid_pid 0x0403 0xbcda - -ftdi_layout_init 0x00a8 0x00eb -ftdi_layout_signal nSRST -noe 0x0020 -ftdi_layout_signal SWD_EN -ndata 0x0080 -ftdi_layout_signal SWDIO_OE -data 0x0008 diff --git a/tcl/interface/ftdi/luminary-lm3s811.cfg b/tcl/interface/ftdi/luminary-lm3s811.cfg deleted file mode 100644 index 543b1e08f..000000000 --- a/tcl/interface/ftdi/luminary-lm3s811.cfg +++ /dev/null @@ -1,21 +0,0 @@ -# -# Luminary Micro Stellaris LM3S811 Evaluation Kit -# -# http://www.luminarymicro.com/products/stellaris_811_evaluation_kits.html -# -# NOTE: this is only for boards *before* Rev C, which adds support -# for SWO tracing with ADBUS_6 DBG_ENn and BDBUS_4 SWO_EN signals. -# The "evb_lm3s811" layout doesn't set up those signals. -# -# Rev C boards work more like the other Stellaris eval boards. They -# need to use the "luminary_icdi" layout to work correctly. -# - -interface ftdi -ftdi_device_desc "LM3S811 Evaluation Board" -ftdi_vid_pid 0x0403 0xbcd9 - -ftdi_layout_init 0x0088 0x008b -ftdi_layout_signal nSRST -data 0x0020 -oe 0x0020 -ftdi_layout_signal SWD_EN -ndata 0x0080 -ftdi_layout_signal SWDIO_OE -data 0x0008 diff --git a/tcl/interface/ftdi/luminary.cfg b/tcl/interface/ftdi/luminary.cfg deleted file mode 100644 index 20b54220e..000000000 --- a/tcl/interface/ftdi/luminary.cfg +++ /dev/null @@ -1,34 +0,0 @@ -# -# Luminary Micro Stellaris Evaluation Kits -# -# http://www.luminarymicro.com/products/evaluation_kits.html -# -# There are a number of evaluation kits for Stellaris Cortex-M3 chips. -# Currently they all bundle ftdi based debug support. When that is -# used (instead of an external adapter), use this config file in one -# of these two modes: -# -# - Eval board debug ... debug of the Stellaris chip via port A. -# -# - Other board debug ... same thing, but the board acts as a debug -# adapter for another board (using a standard ARM JTAG connector). -# The Stellaris chip stays in reset. -# -# Those support both JTAG and SWD. SWD is an ARM-only two-wire debug -# protocol; in 2009, OpenOCD does not support SWD. -# -# Port B of the ftdi chip is normally used as a serial link to the -# Stellaris chip. On most boards (but not older LM3S811 eval boards), -# when SWD is used Port B may instead be used to read low-bandwidth -# "SWO trace" data, including so-called "printf style" output from -# firmware via the ITM module as well as profile data. -# - -interface ftdi -ftdi_device_desc "Stellaris Evaluation Board" -ftdi_vid_pid 0x0403 0xbcd9 - -ftdi_layout_init 0x00a8 0x00eb -ftdi_layout_signal nSRST -noe 0x0020 -ftdi_layout_signal SWD_EN -ndata 0x0080 -ftdi_layout_signal SWDIO_OE -data 0x0008 diff --git a/tcl/interface/ftdi/m53evk.cfg b/tcl/interface/ftdi/m53evk.cfg deleted file mode 100644 index 2b9727049..000000000 --- a/tcl/interface/ftdi/m53evk.cfg +++ /dev/null @@ -1,14 +0,0 @@ -# -# DENX M53EVK -# -# http://www.denx-cs.de/?q=M53EVK -# - -interface ftdi -ftdi_device_desc "Dual RS232-HS" -ftdi_vid_pid 0x0403 0x6010 - -ftdi_channel 0 -ftdi_layout_init 0x0008 0x000b -ftdi_layout_signal nTRST -data 0x0010 -oe 0x0010 -ftdi_layout_signal nSRST -data 0x0020 -oe 0x0020 diff --git a/tcl/interface/ftdi/mbftdi.cfg b/tcl/interface/ftdi/mbftdi.cfg deleted file mode 100644 index d051cccb0..000000000 --- a/tcl/interface/ftdi/mbftdi.cfg +++ /dev/null @@ -1,16 +0,0 @@ -# -# MBFTDI -# -# http://www.marsohod.org/prodmbftdi -# -# Also the Marsohod2 and the Marsohod3 boards -# include a built-in MBFTDI for FPGA programming. -# See http://www.marsohod.org/prodmarsohod2 -# and http://www.marsohod.org/plata-marsokhod3 for details. -# - -interface ftdi -ftdi_device_desc "Dual RS232-HS" -ftdi_vid_pid 0x0403 0x6010 - -ftdi_layout_init 0x0008 0x000b diff --git a/tcl/interface/ftdi/minimodule.cfg b/tcl/interface/ftdi/minimodule.cfg deleted file mode 100644 index 57249dfc1..000000000 --- a/tcl/interface/ftdi/minimodule.cfg +++ /dev/null @@ -1,17 +0,0 @@ -# -# FTDI MiniModule -# -# http://www.ftdichip.com/Support/Documents/DataSheets/Modules/DS_FT2232H_Mini_Module.pdf -# - -echo "WARNING!" -echo "This file was not tested with real interface, it is based on code in ft2232.c." -echo "Please report your experience with this file to openocd-devel mailing list," -echo "so it could be marked as working or fixed." - -interface ftdi -ftdi_device_desc "FT2232H MiniModule" -ftdi_vid_pid 0x0403 0x6010 - -ftdi_layout_init 0x0018 0x05fb -ftdi_layout_signal nSRST -data 0x0020 diff --git a/tcl/interface/ftdi/minispartan6.cfg b/tcl/interface/ftdi/minispartan6.cfg deleted file mode 100644 index 8f1601192..000000000 --- a/tcl/interface/ftdi/minispartan6.cfg +++ /dev/null @@ -1,15 +0,0 @@ -# https://www.scarabhardware.com/minispartan6/ -# https://github.com/scarabhardware/miniSpartan6-plus/raw/master/miniSpartan6%2B_Rev_B.pdf -interface ftdi -# The miniSpartan6+ sadly doesn't have a custom device description, so we just -# have to hope you got it right. -#ftdi_device_desc "Dual RS232-HS" -ftdi_vid_pid 0x0403 0x6010 -# interface 1 is the uart -ftdi_channel 0 -# just TCK TDI TDO TMS, no reset -ftdi_layout_init 0x0008 0x000b -reset_config none -# this generally works fast: the fpga can handle 30MHz, the spi flash can handle -# 54MHz with simple read, no dummy cycles, and wait-for-write-completion -adapter_khz 30000 diff --git a/tcl/interface/ftdi/neodb.cfg b/tcl/interface/ftdi/neodb.cfg deleted file mode 100644 index 6cc8ccf71..000000000 --- a/tcl/interface/ftdi/neodb.cfg +++ /dev/null @@ -1,14 +0,0 @@ -# -# Openmoko USB JTAG/RS232 adapter -# -# http://wiki.openmoko.org/wiki/Debug_Board_v3 -# - -interface ftdi -ftdi_device_desc "Debug Board for Neo1973" -ftdi_vid_pid 0x1457 0x5118 - -ftdi_layout_init 0x0508 0x0f1b -ftdi_layout_signal nTRST -data 0x0200 -noe 0x0100 -ftdi_layout_signal nSRST -data 0x0800 -noe 0x0400 -ftdi_layout_signal nNOR_WP -data 0x0010 -oe 0x0010 diff --git a/tcl/interface/ftdi/ngxtech.cfg b/tcl/interface/ftdi/ngxtech.cfg deleted file mode 100644 index 9eaa3c5bc..000000000 --- a/tcl/interface/ftdi/ngxtech.cfg +++ /dev/null @@ -1,19 +0,0 @@ -# -# NGX ARM USB JTAG -# -# http://shop.ngxtechnologies.com/product_info.php?cPath=26&products_id=30 -# - -echo "WARNING!" -echo "This file was not tested with real interface, but is assumed to work as this" -echo "interface uses the same layout as configs that were verified. Please report your" -echo "experience with this file to openocd-devel mailing list, so it could be marked" -echo "as working or fixed." - -interface ftdi -ftdi_device_desc "NGX JTAG" -ftdi_vid_pid 0x0403 0x6010 - -ftdi_layout_init 0x0508 0x0f1b -ftdi_layout_signal nTRST -data 0x0200 -noe 0x0100 -ftdi_layout_signal nSRST -data 0x0800 -noe 0x0400 diff --git a/tcl/interface/ftdi/olimex-arm-jtag-swd.cfg b/tcl/interface/ftdi/olimex-arm-jtag-swd.cfg deleted file mode 100644 index 2153fd65f..000000000 --- a/tcl/interface/ftdi/olimex-arm-jtag-swd.cfg +++ /dev/null @@ -1,9 +0,0 @@ -# -# Olimex ARM JTAG SWD adapter -# https://www.olimex.com/Products/ARM/JTAG/ARM-JTAG-SWD/ -# - -transport select swd - -ftdi_layout_signal SWD_EN -nalias nTRST -ftdi_layout_signal SWDIO_OE -alias TMS diff --git a/tcl/interface/ftdi/olimex-arm-usb-ocd-h.cfg b/tcl/interface/ftdi/olimex-arm-usb-ocd-h.cfg deleted file mode 100644 index 5b27d38ba..000000000 --- a/tcl/interface/ftdi/olimex-arm-usb-ocd-h.cfg +++ /dev/null @@ -1,14 +0,0 @@ -# -# Olimex ARM-USB-OCD-H -# -# http://www.olimex.com/dev/arm-usb-ocd-h.html -# - -interface ftdi -ftdi_device_desc "Olimex OpenOCD JTAG ARM-USB-OCD-H" -ftdi_vid_pid 0x15ba 0x002b - -ftdi_layout_init 0x0908 0x0b1b -ftdi_layout_signal nSRST -oe 0x0200 -ftdi_layout_signal nTRST -data 0x0100 -ftdi_layout_signal LED -data 0x0800 diff --git a/tcl/interface/ftdi/olimex-arm-usb-ocd.cfg b/tcl/interface/ftdi/olimex-arm-usb-ocd.cfg deleted file mode 100644 index e1aeeeab6..000000000 --- a/tcl/interface/ftdi/olimex-arm-usb-ocd.cfg +++ /dev/null @@ -1,14 +0,0 @@ -# -# Olimex ARM-USB-OCD -# -# http://www.olimex.com/dev/arm-usb-ocd.html -# - -interface ftdi -ftdi_device_desc "Olimex OpenOCD JTAG" -ftdi_vid_pid 0x15ba 0x0003 - -ftdi_layout_init 0x0c08 0x0f1b -ftdi_layout_signal nSRST -oe 0x0200 -ftdi_layout_signal nTRST -data 0x0100 -noe 0x0400 -ftdi_layout_signal LED -data 0x0800 diff --git a/tcl/interface/ftdi/olimex-arm-usb-tiny-h.cfg b/tcl/interface/ftdi/olimex-arm-usb-tiny-h.cfg deleted file mode 100644 index f77c24b2c..000000000 --- a/tcl/interface/ftdi/olimex-arm-usb-tiny-h.cfg +++ /dev/null @@ -1,14 +0,0 @@ -# -# Olimex ARM-USB-TINY-H -# -# http://www.olimex.com/dev/arm-usb-tiny-h.html -# - -interface ftdi -ftdi_device_desc "Olimex OpenOCD JTAG ARM-USB-TINY-H" -ftdi_vid_pid 0x15ba 0x002a - -ftdi_layout_init 0x0808 0x0a1b -ftdi_layout_signal nSRST -oe 0x0200 -ftdi_layout_signal nTRST -data 0x0100 -oe 0x0100 -ftdi_layout_signal LED -data 0x0800 diff --git a/tcl/interface/ftdi/olimex-jtag-tiny.cfg b/tcl/interface/ftdi/olimex-jtag-tiny.cfg deleted file mode 100644 index b3c6a716e..000000000 --- a/tcl/interface/ftdi/olimex-jtag-tiny.cfg +++ /dev/null @@ -1,14 +0,0 @@ -# -# Olimex ARM-USB-TINY -# -# http://www.olimex.com/dev/arm-usb-tiny.html -# - -interface ftdi -ftdi_device_desc "Olimex OpenOCD JTAG TINY" -ftdi_vid_pid 0x15ba 0x0004 - -ftdi_layout_init 0x0808 0x0a1b -ftdi_layout_signal nSRST -oe 0x0200 -ftdi_layout_signal nTRST -data 0x0100 -oe 0x0100 -ftdi_layout_signal LED -data 0x0800 diff --git a/tcl/interface/ftdi/oocdlink.cfg b/tcl/interface/ftdi/oocdlink.cfg deleted file mode 100644 index fc09a1636..000000000 --- a/tcl/interface/ftdi/oocdlink.cfg +++ /dev/null @@ -1,19 +0,0 @@ -# -# Joern Kaipf's OOCDLink -# -# http://www.joernonline.de/contrexx2/cms/index.php?page=126 -# - -echo "WARNING!" -echo "This file was not tested with real interface, but is assumed to work as this" -echo "interface uses the same layout as configs that were verified. Please report your" -echo "experience with this file to openocd-devel mailing list, so it could be marked" -echo "as working or fixed." - -interface ftdi -ftdi_device_desc "OOCDLink" -ftdi_vid_pid 0x0403 0xbaf8 - -ftdi_layout_init 0x0508 0x0f1b -ftdi_layout_signal nTRST -data 0x0200 -noe 0x0100 -ftdi_layout_signal nSRST -data 0x0800 -noe 0x0400 diff --git a/tcl/interface/ftdi/opendous_ftdi.cfg b/tcl/interface/ftdi/opendous_ftdi.cfg deleted file mode 100644 index 6a12d7212..000000000 --- a/tcl/interface/ftdi/opendous_ftdi.cfg +++ /dev/null @@ -1,17 +0,0 @@ -# -# Opendous -# -# http://code.google.com/p/opendous/wiki/JTAG -# -# According to the website, it is similar to jtagkey, but it uses channel B -# (and it has a different pid number). -# - -interface ftdi -ftdi_device_desc "Dual RS232-HS" -ftdi_vid_pid 0x0403 0x6010 -ftdi_channel 1 - -ftdi_layout_init 0x0c08 0x0f1b -ftdi_layout_signal nTRST -data 0x0100 -noe 0x0400 -ftdi_layout_signal nSRST -data 0x0200 -noe 0x0800 diff --git a/tcl/interface/ftdi/openocd-usb-hs.cfg b/tcl/interface/ftdi/openocd-usb-hs.cfg deleted file mode 100644 index 37a717dc5..000000000 --- a/tcl/interface/ftdi/openocd-usb-hs.cfg +++ /dev/null @@ -1,13 +0,0 @@ -# -# embedded projects openocd usb adapter v3 -# -# http://shop.embedded-projects.net/index.php?module=artikel&action=artikel&id=14 -# - -interface ftdi -ftdi_device_desc "Dual RS232-HS" -ftdi_vid_pid 0x0403 0x6010 - -ftdi_layout_init 0x0508 0x0f1b -ftdi_layout_signal nTRST -data 0x0200 -noe 0x0100 -ftdi_layout_signal nSRST -data 0x0800 -noe 0x0400 diff --git a/tcl/interface/ftdi/openocd-usb.cfg b/tcl/interface/ftdi/openocd-usb.cfg deleted file mode 100644 index ff537c7b6..000000000 --- a/tcl/interface/ftdi/openocd-usb.cfg +++ /dev/null @@ -1,13 +0,0 @@ -# -# Hubert Hoegl's USB to JTAG -# -# http://www.hs-augsburg.de/~hhoegl/proj/usbjtag/usbjtag.html -# - -interface ftdi -ftdi_device_desc "Dual RS232" -ftdi_vid_pid 0x0403 0x6010 - -ftdi_layout_init 0x0508 0x0f1b -ftdi_layout_signal nTRST -data 0x0200 -noe 0x0100 -ftdi_layout_signal nSRST -data 0x0800 -noe 0x0400 diff --git a/tcl/interface/ftdi/openrd.cfg b/tcl/interface/ftdi/openrd.cfg deleted file mode 100644 index 8c1a80596..000000000 --- a/tcl/interface/ftdi/openrd.cfg +++ /dev/null @@ -1,19 +0,0 @@ -# -# Marvell OpenRD -# -# http://www.marvell.com/products/embedded_processors/developer/kirkwood/openrd.jsp -# - -echo "WARNING!" -echo "This file was not tested with real interface, it is based on code in ft2232.c." -echo "Please report your experience with this file to openocd-devel mailing list," -echo "so it could be marked as working or fixed." - -interface ftdi -ftdi_device_desc "OpenRD JTAGKey FT2232D" -ftdi_vid_pid 0x0403 0x9e90 -ftdi_channel 1 - -ftdi_layout_init 0x0608 0x0f1b -ftdi_layout_signal nTRST -data 0x0200 -ftdi_layout_signal nSRST -noe 0x0400 diff --git a/tcl/interface/ftdi/pipistrello.cfg b/tcl/interface/ftdi/pipistrello.cfg deleted file mode 100644 index b51405a2d..000000000 --- a/tcl/interface/ftdi/pipistrello.cfg +++ /dev/null @@ -1,13 +0,0 @@ -# http://pipistrello.saanlima.com/ -# http://www.saanlima.com/download/pipistrello-v2.0/pipistrello_v2_schematic.pdf -interface ftdi -ftdi_device_desc "Pipistrello LX45" -ftdi_vid_pid 0x0403 0x6010 -# interface 1 is the uart -ftdi_channel 0 -# just TCK TDI TDO TMS, no reset -ftdi_layout_init 0x0008 0x000b -reset_config none -# this generally works fast: the fpga can handle 30MHz, the spi flash can handle -# 54MHz with simple read, no dummy cycles, and wait-for-write-completion -adapter_khz 30000 diff --git a/tcl/interface/ftdi/redbee-econotag.cfg b/tcl/interface/ftdi/redbee-econotag.cfg deleted file mode 100644 index 70c30d658..000000000 --- a/tcl/interface/ftdi/redbee-econotag.cfg +++ /dev/null @@ -1,21 +0,0 @@ -# -# Redwire Redbee-Econotag -# -# http://www.redwirellc.com/store/node/1 -# -# The Redbee-Econotag has an onboard FT2232H with: -# - FT2232H channel A wired to mc13224v JTAG -# - FT2232H channel B wired to mc13224v UART1 -# - -echo "WARNING!" -echo "This file was not tested with real interface, it is based on code in ft2232.c." -echo "Please report your experience with this file to openocd-devel mailing list," -echo "so it could be marked as working or fixed." - -interface ftdi -ftdi_vid_pid 0x0403 0x6010 - -ftdi_layout_init 0x0c08 0x0c2b -ftdi_layout_signal nTRST -data 0x0800 -ftdi_layout_signal nSRST -data 0x0400 diff --git a/tcl/interface/ftdi/redbee-usb.cfg b/tcl/interface/ftdi/redbee-usb.cfg deleted file mode 100644 index b79300d53..000000000 --- a/tcl/interface/ftdi/redbee-usb.cfg +++ /dev/null @@ -1,22 +0,0 @@ -# -# Redwire Redbee-USB -# -# http://www.redwirellc.com -# -# The Redbee-USB has an onboard FT2232H with: -# - FT2232H channel B wired to mc13224v JTAG -# - FT2232H channel A wired to mc13224v UART1 -# - -echo "WARNING!" -echo "This file was not tested with real interface, it is based on code in ft2232.c." -echo "Please report your experience with this file to openocd-devel mailing list," -echo "so it could be marked as working or fixed." - -interface ftdi -ftdi_vid_pid 0x0403 0x6010 -ftdi_channel 1 - -ftdi_layout_init 0x0c08 0x0c2b -ftdi_layout_signal nTRST -data 0x0800 -ftdi_layout_signal nSRST -data 0x0400 diff --git a/tcl/interface/ftdi/rowley-cc-arm-swd.cfg b/tcl/interface/ftdi/rowley-cc-arm-swd.cfg deleted file mode 100644 index 9a96dbd92..000000000 --- a/tcl/interface/ftdi/rowley-cc-arm-swd.cfg +++ /dev/null @@ -1,10 +0,0 @@ -# -# Rowley ARM SWD Adapter -# http://sites.fastspring.com/rowley/product/armswdadapter -# https://drive.google.com/file/d/0Bzv7UpKpOQhnTUNNdzI5OUR4WGs/edit?usp=sharing -# - -transport select swd - -ftdi_layout_signal SWD_EN -nalias nTRST -ftdi_layout_signal SWDIO_OE -alias TMS diff --git a/tcl/interface/ftdi/sheevaplug.cfg b/tcl/interface/ftdi/sheevaplug.cfg deleted file mode 100644 index f299f27a9..000000000 --- a/tcl/interface/ftdi/sheevaplug.cfg +++ /dev/null @@ -1,14 +0,0 @@ -# -# Marvel SheevaPlug Development Kit -# -# http://www.marvell.com/products/embedded_processors/developer/kirkwood/sheevaplug.jsp -# - -interface ftdi -ftdi_device_desc "SheevaPlug JTAGKey FT2232D B" -ftdi_vid_pid 0x9e88 0x9e8f -ftdi_channel 1 - -ftdi_layout_init 0x0608 0x0f1b -ftdi_layout_signal nTRST -data 0x0200 -ftdi_layout_signal nSRST -noe 0x0400 diff --git a/tcl/interface/ftdi/signalyzer-lite.cfg b/tcl/interface/ftdi/signalyzer-lite.cfg deleted file mode 100644 index 4988a3bfd..000000000 --- a/tcl/interface/ftdi/signalyzer-lite.cfg +++ /dev/null @@ -1,18 +0,0 @@ -# -# Xverve Signalyzer LITE (DT-USB-SLITE) -# -# http://www.signalyzer.com -# - -echo "WARNING!" -echo "This file was not tested with real interface, it is based on code in ft2232.c." -echo "Please report your experience with this file to openocd-devel mailing list," -echo "so it could be marked as working or fixed." - -interface ftdi -ftdi_device_desc "Signalyzer LITE" -ftdi_vid_pid 0x0403 0xbca1 - -ftdi_layout_init 0x0008 0x000b -ftdi_layout_signal nTRST -data 0x0010 -oe 0x0010 -ftdi_layout_signal nSRST -data 0x0020 -oe 0x0020 diff --git a/tcl/interface/ftdi/signalyzer.cfg b/tcl/interface/ftdi/signalyzer.cfg deleted file mode 100644 index e2629beec..000000000 --- a/tcl/interface/ftdi/signalyzer.cfg +++ /dev/null @@ -1,18 +0,0 @@ -# -# Xverve Signalyzer Tool (DT-USB-ST) -# -# http://www.signalyzer.com -# - -echo "WARNING!" -echo "This file was not tested with real interface, it is based on code in ft2232.c." -echo "Please report your experience with this file to openocd-devel mailing list," -echo "so it could be marked as working or fixed." - -interface ftdi -ftdi_device_desc "Signalyzer" -ftdi_vid_pid 0x0403 0xbca0 - -ftdi_layout_init 0x0008 0x000b -ftdi_layout_signal nTRST -data 0x0010 -oe 0x0010 -ftdi_layout_signal nSRST -data 0x0020 -oe 0x0020 diff --git a/tcl/interface/ftdi/stm32-stick.cfg b/tcl/interface/ftdi/stm32-stick.cfg deleted file mode 100644 index 2aff1fe8f..000000000 --- a/tcl/interface/ftdi/stm32-stick.cfg +++ /dev/null @@ -1,13 +0,0 @@ -# -# Hitex STM32-PerformanceStick -# -# http://www.hitex.com/index.php?id=340 -# - -interface ftdi -ftdi_device_desc "STM32-PerformanceStick" -ftdi_vid_pid 0x0640 0x002d - -ftdi_layout_init 0x0388 0x038b -ftdi_layout_signal nTRST -data 0x0100 -ftdi_layout_signal nSRST -data 0x0080 -noe 0x200 diff --git a/tcl/interface/ftdi/swd-resistor-hack.cfg b/tcl/interface/ftdi/swd-resistor-hack.cfg deleted file mode 100644 index 04f3a7397..000000000 --- a/tcl/interface/ftdi/swd-resistor-hack.cfg +++ /dev/null @@ -1,26 +0,0 @@ -# -# Connect TDI to SWDIO via a suitable series resistor (220-470 Ohm or -# so depending on the drive capability of the target and adapter); -# connect TDO directly to SWDIO. -# -# You also need to have reliable GND connection between the target and -# adapter. Vref of the adapter should be supplied with a voltage equal -# to the target's (preferrably connect it to Vcc). You can also -# optionally connect nSRST. Leave everything else unconnected. -# -# FTDI Target -# ---- ------ -# 1 - Vref ----------------- Vcc -# 3 - nTRST - -# 4 - GND ----------------- GND -# 5 - TDI ---/\470 Ohm/\--- SWDIO -# 7 - TMS - -# 9 - TCK ----------------- SWCLK -# 11 - RTCK - -# 13 - TDO ----------------- SWDIO -# 15 - nSRST - - - - - - - - - nRESET -# - -transport select swd - -ftdi_layout_signal SWD_EN -data 0 diff --git a/tcl/interface/ftdi/ti-icdi.cfg b/tcl/interface/ftdi/ti-icdi.cfg deleted file mode 100644 index 6af809cd9..000000000 --- a/tcl/interface/ftdi/ti-icdi.cfg +++ /dev/null @@ -1,15 +0,0 @@ -# -# This is an FTDI-based debugging solution as found on some TI boards, -# e.g. CC3200 LaunchPad. -# -# The schematics are identical to luminary-icdi (including SWD -# support) but the USB IDs are different. -# - -interface ftdi -ftdi_vid_pid 0x0451 0xc32a - -ftdi_layout_init 0x00a8 0x00eb -ftdi_layout_signal nSRST -noe 0x0020 -ftdi_layout_signal SWD_EN -ndata 0x0080 -ftdi_layout_signal SWDIO_OE -data 0x0008 diff --git a/tcl/interface/ftdi/tumpa-lite.cfg b/tcl/interface/ftdi/tumpa-lite.cfg deleted file mode 100644 index 657515a91..000000000 --- a/tcl/interface/ftdi/tumpa-lite.cfg +++ /dev/null @@ -1,12 +0,0 @@ -# -# TIAO USB Multi-Protocol Adapter (TUMPA) Lite -# -# http://www.diygadget.com/tiao-usb-multi-protocol-adapter-lite-jtag-spi-i2c-serial.html -# - -interface ftdi -ftdi_vid_pid 0x0403 0x8a99 - -ftdi_layout_init 0x0038 0x087b -ftdi_layout_signal nTRST -data 0x0020 -oe 0x0020 -ftdi_layout_signal nSRST -data 0x0010 -oe 0x0010 diff --git a/tcl/interface/ftdi/tumpa.cfg b/tcl/interface/ftdi/tumpa.cfg deleted file mode 100644 index e4b59b118..000000000 --- a/tcl/interface/ftdi/tumpa.cfg +++ /dev/null @@ -1,14 +0,0 @@ -# -# TIAO USB Multi-Protocol Adapter (TUMPA) -# -# http://www.diygadget.com/tiao-usb-multi-protocol-adapter-jtag-spi-i2c-serial.html -# - -interface ftdi -ftdi_vid_pid 0x0403 0x8a98 0x0403 0x6010 - -ftdi_layout_init 0x0038 0x087b -ftdi_layout_signal nTRST -data 0x0020 -ftdi_layout_signal nSRST -data 0x0010 - -reset_config srst_push_pull diff --git a/tcl/interface/ftdi/turtelizer2-revB.cfg b/tcl/interface/ftdi/turtelizer2-revB.cfg deleted file mode 100644 index 45840402a..000000000 --- a/tcl/interface/ftdi/turtelizer2-revB.cfg +++ /dev/null @@ -1,18 +0,0 @@ -# -# egnite Turtelizer 2 rev B (with SRST only) -# -# http://www.ethernut.de/en/hardware/turtelizer/index.html -# - -echo "WARNING!" -echo "This file was not tested with real interface, it is based on schematics and code" -echo "in ft2232.c. Please report your experience with this file to openocd-devel" -echo "mailing list, so it could be marked as working or fixed." - -interface ftdi -ftdi_device_desc "Turtelizer JTAG/RS232 Adapter" -ftdi_vid_pid 0x0403 0xbdc8 - -ftdi_layout_init 0x0008 0x0c5b -ftdi_layout_signal nSRST -oe 0x0040 -ftdi_layout_signal LED -data 0x0c00 diff --git a/tcl/interface/ftdi/turtelizer2-revC.cfg b/tcl/interface/ftdi/turtelizer2-revC.cfg deleted file mode 100644 index 918ac497b..000000000 --- a/tcl/interface/ftdi/turtelizer2-revC.cfg +++ /dev/null @@ -1,14 +0,0 @@ -# -# egnite Turtelizer 2 revC (with TRST and SRST) -# -# http://www.ethernut.de/en/hardware/turtelizer/index.html -# - -interface ftdi -ftdi_device_desc "Turtelizer JTAG/RS232 Adapter" -ftdi_vid_pid 0x0403 0xbdc8 - -ftdi_layout_init 0x0008 0x0c7b -ftdi_layout_signal nTRST -oe 0x0020 -ftdi_layout_signal nSRST -oe 0x0040 -ftdi_layout_signal LED -ndata 0x0c00 diff --git a/tcl/interface/ftdi/um232h.cfg b/tcl/interface/ftdi/um232h.cfg deleted file mode 100644 index 6ba6f43b2..000000000 --- a/tcl/interface/ftdi/um232h.cfg +++ /dev/null @@ -1,35 +0,0 @@ -# -# FTDI UM232H as a JTAG interface -# -# http://www.ftdichip.com/Products/Modules/DevelopmentModules.htm#UM232H -# -# This should also work with a UM232H-B, but that has not been tested. -# Note that UM232H and UM232H-B are 3.3V only. -# - -interface ftdi -#ftdi_device_desc "UM232H" -ftdi_vid_pid 0x0403 0x6014 - -ftdi_layout_init 0xfff8 0xfffb -ftdi_layout_signal nTRST -data 0x0100 -oe 0x0100 -ftdi_layout_signal nSRST -data 0x0200 -oe 0x0200 - -# UM232H FT232H JTAG -# Name Pin Name Func -# AD0 J2-6 ADBUS0 TCK -# AD1 J2-7 ADBUS1 TDI -# AD2 J2-8 ADBUS2 TDO -# AD3 J2-9 ADBUS3 TMS -# AD4 J2-10 ADBUS4 (GPIOL0) -# AD5 J2-11 ADBUS5 (GPIOL1) -# AD6 J2-12 ADBUS6 (GPIOL2) -# AD7 J2-13 ADBUS7 (GPIOL3) -# AD0 J1-14 ACBUS0 /TRST -# AD1 J1-13 ACBUS1 /SRST -# AD2 J1-12 ACBUS2 (GPIOH2) -# AD3 J1-11 ACBUS3 (GPIOH3) -# AD4 J1-10 ACBUS4 (GPIOH4) -# AD5 J1-9 ACBUS5 (GPIOH5) -# AD6 J1-8 ACBUS6 (GPIOH6) -# AD7 J1-7 ACBUS7 (GPIOH7) diff --git a/tcl/interface/ftdi/vpaclink.cfg b/tcl/interface/ftdi/vpaclink.cfg deleted file mode 100644 index 205761964..000000000 --- a/tcl/interface/ftdi/vpaclink.cfg +++ /dev/null @@ -1,19 +0,0 @@ -# -# Voipac VPACLink -# -# http://voipac.com/27M-JTG-000 -# - -echo "WARNING!" -echo "This file was not tested with real interface, but is assumed to work as this" -echo "interface uses the same layout as configs that were verified. Please report your" -echo "experience with this file to openocd-devel mailing list, so it could be marked" -echo "as working or fixed." - -interface ftdi -ftdi_device_desc "VPACLink" -ftdi_vid_pid 0x0403 0x6010 - -ftdi_layout_init 0x0508 0x0f1b -ftdi_layout_signal nTRST -data 0x0200 -noe 0x0100 -ftdi_layout_signal nSRST -data 0x0800 -noe 0x0400 diff --git a/tcl/interface/ftdi/xds100v2.cfg b/tcl/interface/ftdi/xds100v2.cfg deleted file mode 100644 index 2628aa086..000000000 --- a/tcl/interface/ftdi/xds100v2.cfg +++ /dev/null @@ -1,58 +0,0 @@ -# -# Texas Instruments XDS100v2 -# -# http://processors.wiki.ti.com/index.php/XDS100#XDS100v2_Features -# -# Detailed documentation is available only as CPLD verilog source code -# to the registered TI users. -# - -interface ftdi -ftdi_vid_pid 0x0403 0xa6d0 0x0403 0x6010 - -ftdi_layout_init 0x0038 0x597b - -# 8000 z - unused -# 4000 0 > CPLD loopback (all target side pins high-Z) -# 2000 z < !( cable connected ) (open drain on CPLD side for $reasons) -# 1000 0 > EMU1_oe -# -# 800 0 > PWR_RST = clear power-loss flag on rising edge -# 400 z < !( power-loss flag ) -# 200 z < nSRST -# 100 0 > nSRST_oe -# -# 80 z < RTCK -# 40 0 > EMU0_oe -# 20 1 > EMU_EN -# 10 1 > nTRST -# -# 8 1 > TMS -# 4 z < TDO -# 2 0 > TDI -# 1 0 > TCK -# -# As long as the power-loss flag is set, all target-side pins are -# high-Z except the EMU-pins for which the opposite holds unless -# EMU_EN is high. -# -# To use wait-in-reset, drive EMU0 low at power-on reset. If the -# target normally reuses EMU0 for other purposes, clear EMU_EN to -# keep the EMU pins high-Z until the target is power-cycled. -# -# The LED only turns off at USB suspend, which is also the only way to -# set the power-loss flag manually. (Can be done in software e.g. by -# changing the USB configuration to zero.) -# - -ftdi_layout_signal nTRST -data 0x0010 -ftdi_layout_signal nSRST -oe 0x0100 -ftdi_layout_signal EMU_EN -data 0x0020 -ftdi_layout_signal EMU0 -oe 0x0040 -ftdi_layout_signal EMU1 -oe 0x1000 -ftdi_layout_signal PWR_RST -data 0x0800 -ftdi_layout_signal LOOPBACK -data 0x4000 - -echo "\nInfo : to use this adapter you MUST add ``init; ftdi_set_signal PWR_RST 1; jtag arp_init'' to the end of your config file!\n" -# note: rising edge on PWR_RST is also needed after power-cycling the -# target diff --git a/tcl/interface/ftdi/xds100v3.cfg b/tcl/interface/ftdi/xds100v3.cfg deleted file mode 100644 index 6c705823a..000000000 --- a/tcl/interface/ftdi/xds100v3.cfg +++ /dev/null @@ -1,11 +0,0 @@ -# -# Texas Instruments XDS100 ver 3.0 -# -# http://processors.wiki.ti.com/index.php/XDS100 -# - -# Version 3.0 is the same as 2.0 as far as OpenOCD is concerned -source [find interface/ftdi/xds100v2.cfg] - -# The USB ids are different. -ftdi_vid_pid 0x0403 0xa6d1 diff --git a/tcl/interface/hilscher_nxhx10_etm.cfg b/tcl/interface/hilscher_nxhx10_etm.cfg deleted file mode 100644 index b16ed1a53..000000000 --- a/tcl/interface/hilscher_nxhx10_etm.cfg +++ /dev/null @@ -1,11 +0,0 @@ -# -# Hilscher NXHX 10-ETM -# -# http://de.hilscher.com/products_details_hardware.html?p_id=P_4ce145a5983e6 -# - -interface ft2232 -ft2232_device_desc "NXHX 10-ETM" -ft2232_layout comstick -ft2232_vid_pid 0x0640 0x0028 -adapter_khz 6000 diff --git a/tcl/interface/hilscher_nxhx500_etm.cfg b/tcl/interface/hilscher_nxhx500_etm.cfg deleted file mode 100644 index 840ffaf6c..000000000 --- a/tcl/interface/hilscher_nxhx500_etm.cfg +++ /dev/null @@ -1,11 +0,0 @@ -# -# Hilscher NXHX 500-ETM -# -# http://de.hilscher.com/files_design/8/NXHX500-ETM_description_Rev01_EN.pdf -# - -interface ft2232 -ft2232_device_desc "NXHX 500-ETM" -ft2232_layout comstick -ft2232_vid_pid 0x0640 0x0028 -adapter_khz 6000 diff --git a/tcl/interface/hilscher_nxhx500_re.cfg b/tcl/interface/hilscher_nxhx500_re.cfg deleted file mode 100644 index 1d1b75426..000000000 --- a/tcl/interface/hilscher_nxhx500_re.cfg +++ /dev/null @@ -1,11 +0,0 @@ -# -# Hilscher NXHX 500-RE -# -# http://de.hilscher.com/products_details_hardware.html?p_id=P_461ff2053bad1&bs=20 -# - -interface ft2232 -ft2232_device_desc "NXHX 500-RE" -ft2232_layout comstick -ft2232_vid_pid 0x0640 0x0028 -adapter_khz 6000 diff --git a/tcl/interface/hilscher_nxhx50_etm.cfg b/tcl/interface/hilscher_nxhx50_etm.cfg deleted file mode 100644 index ff98c2800..000000000 --- a/tcl/interface/hilscher_nxhx50_etm.cfg +++ /dev/null @@ -1,11 +0,0 @@ -# -# Hilscher NXHX 50-ETM -# -# http://de.hilscher.com/files_design/8/NXHX50-ETM_description_Rev01_EN.pdf -# - -interface ft2232 -ft2232_device_desc "NXHX 50-ETM" -ft2232_layout comstick -ft2232_vid_pid 0x0640 0x0028 -adapter_khz 6000 diff --git a/tcl/interface/hilscher_nxhx50_re.cfg b/tcl/interface/hilscher_nxhx50_re.cfg deleted file mode 100644 index 0573e0311..000000000 --- a/tcl/interface/hilscher_nxhx50_re.cfg +++ /dev/null @@ -1,11 +0,0 @@ -# -# Hilscher NXHX 50-RE -# -# http://de.hilscher.com/products_details_hardware.html?p_id=P_483c0f582ad36&bs=20 -# - -interface ft2232 -ft2232_device_desc "NXHX50-RE" -ft2232_layout comstick -ft2232_vid_pid 0x0640 0x0028 -adapter_khz 6000 diff --git a/tcl/interface/hitex_str9-comstick.cfg b/tcl/interface/hitex_str9-comstick.cfg deleted file mode 100644 index a38be78a2..000000000 --- a/tcl/interface/hitex_str9-comstick.cfg +++ /dev/null @@ -1,11 +0,0 @@ -# -# Hitex STR9-comStick -# -# http://www.hitex.com/index.php?id=383 -# - -interface ft2232 -ft2232_device_desc "STR9-comStick" -ft2232_layout comstick -ft2232_vid_pid 0x0640 0x002c - diff --git a/tcl/interface/icebear.cfg b/tcl/interface/icebear.cfg deleted file mode 100644 index 88b5e36a2..000000000 --- a/tcl/interface/icebear.cfg +++ /dev/null @@ -1,11 +0,0 @@ -# -# Section5 ICEBear -# -# http://section5.ch/icebear -# - -interface ft2232 -ft2232_device_desc "ICEbear JTAG adapter" -ft2232_layout icebear -ft2232_vid_pid 0x0403 0xc140 - diff --git a/tcl/interface/jlink.cfg b/tcl/interface/jlink.cfg deleted file mode 100644 index a4f9dddd7..000000000 --- a/tcl/interface/jlink.cfg +++ /dev/null @@ -1,14 +0,0 @@ -# -# SEGGER J-Link -# -# http://www.segger.com/jlink.html -# - -interface jlink - -# The serial number can be used to select a specific device in case more than -# one is connected to the host. -# -# Example: Select J-Link with serial number 123456789 -# -# jlink serial 123456789 diff --git a/tcl/interface/jtag-lock-pick_tiny_2.cfg b/tcl/interface/jtag-lock-pick_tiny_2.cfg deleted file mode 100644 index 539f0f992..000000000 --- a/tcl/interface/jtag-lock-pick_tiny_2.cfg +++ /dev/null @@ -1,10 +0,0 @@ -# -# DISTORTEC JTAG-lock-pick Tiny 2 -# -# http://www.distortec.com -# - -interface ft2232 -ft2232_device_desc "JTAG-lock-pick Tiny 2" -ft2232_layout ktlink -ft2232_vid_pid 0x0403 0x8220 diff --git a/tcl/interface/jtag_vpi.cfg b/tcl/interface/jtag_vpi.cfg deleted file mode 100644 index a37a11ed0..000000000 --- a/tcl/interface/jtag_vpi.cfg +++ /dev/null @@ -1,18 +0,0 @@ -interface jtag_vpi - -# Set the VPI JTAG server port -if { [info exists VPI_PORT] } { - set _VPI_PORT $VPI_PORT -} else { - set _VPI_PORT 5555 -} - -# Set the VPI JTAG server address -if { [info exists VPI_ADDRESS] } { - set _VPI_ADDRESS $VPI_ADDRESS -} else { - set _VPI_ADDRESS "127.0.0.1" -} - -jtag_vpi_set_port $_VPI_PORT -jtag_vpi_set_address $_VPI_ADDRESS diff --git a/tcl/interface/jtagkey-tiny.cfg b/tcl/interface/jtagkey-tiny.cfg deleted file mode 100644 index 633fdda8a..000000000 --- a/tcl/interface/jtagkey-tiny.cfg +++ /dev/null @@ -1,9 +0,0 @@ -# -# Amontec JTAGkey-tiny -# -# http://www.amontec.com/jtagkey-tiny.shtml -# - -# The JTAGkey-tiny uses exactly the same config as the JTAGkey. -source [find interface/jtagkey.cfg] - diff --git a/tcl/interface/jtagkey.cfg b/tcl/interface/jtagkey.cfg deleted file mode 100644 index ca45dfcfc..000000000 --- a/tcl/interface/jtagkey.cfg +++ /dev/null @@ -1,11 +0,0 @@ -# -# Amontec JTAGkey -# -# http://www.amontec.com/jtagkey.shtml -# - -interface ft2232 -ft2232_device_desc "Amontec JTAGkey" -ft2232_layout jtagkey -ft2232_vid_pid 0x0403 0xcff8 - diff --git a/tcl/interface/jtagkey2.cfg b/tcl/interface/jtagkey2.cfg deleted file mode 100644 index 40a0b0db5..000000000 --- a/tcl/interface/jtagkey2.cfg +++ /dev/null @@ -1,11 +0,0 @@ -# -# Amontec JTAGkey2 -# -# http://www.amontec.com/jtagkey2.shtml -# - -interface ft2232 -ft2232_device_desc "Amontec JTAGkey-2" -ft2232_layout jtagkey -ft2232_vid_pid 0x0403 0xCFF8 - diff --git a/tcl/interface/jtagkey2p.cfg b/tcl/interface/jtagkey2p.cfg deleted file mode 100644 index 98a941716..000000000 --- a/tcl/interface/jtagkey2p.cfg +++ /dev/null @@ -1,11 +0,0 @@ -# -# Amontec JTAGkey2P -# -# http://www.amontec.com/jtagkey2p.shtml -# - -interface ft2232 -ft2232_device_desc "Amontec JTAGkey-2P" -ft2232_layout jtagkey -ft2232_vid_pid 0x0403 0xCFF8 - diff --git a/tcl/interface/kt-link.cfg b/tcl/interface/kt-link.cfg deleted file mode 100644 index 93af8e445..000000000 --- a/tcl/interface/kt-link.cfg +++ /dev/null @@ -1,10 +0,0 @@ -# -# Kristech KT-Link -# -# http://www.kristech.eu -# - -interface ft2232 -ft2232_device_desc "KT-LINK" -ft2232_layout ktlink -ft2232_vid_pid 0x0403 0xBBE2 diff --git a/tcl/interface/lisa-l.cfg b/tcl/interface/lisa-l.cfg deleted file mode 100644 index cc7d6ccd6..000000000 --- a/tcl/interface/lisa-l.cfg +++ /dev/null @@ -1,11 +0,0 @@ -# -# Lisa/L -# -# http://paparazzi.enac.fr/wiki/Lisa -# - -interface ft2232 -ft2232_vid_pid 0x0403 0x6010 -ft2232_device_desc "Lisa/L" -ft2232_layout "lisa-l" -ft2232_latency 2 diff --git a/tcl/interface/luminary-icdi.cfg b/tcl/interface/luminary-icdi.cfg deleted file mode 100644 index 94e00aee2..000000000 --- a/tcl/interface/luminary-icdi.cfg +++ /dev/null @@ -1,21 +0,0 @@ -# -# Luminary Micro Stellaris LM3S9B9x Evaluation Kits -# In-Circuit Debug Interface (ICDI) Board -# -# Essentially all Luminary debug hardware is the same, (with both -# JTAG and SWD support compatible with ICDI boards. This ICDI adapter -# configuration is JTAG-only, but the same hardware handles SWD too. -# -# This is a discrete FT2232 based debug board which supports ARM's -# JTAG/SWD connectors in both backwards-compatible 20-pin format and -# in the new-style compact 10-pin. There's also an 8-pin connector -# with serial port support. It's included with LM3S9B9x eval boards. -# -# http://www.luminarymicro.com/products/ek-lm3s9b90.html -# http://www.luminarymicro.com/products/ek-lm3s9b92.html -# - -interface ft2232 -ft2232_device_desc "Luminary Micro ICDI Board" -ft2232_layout luminary_icdi -ft2232_vid_pid 0x0403 0xbcda diff --git a/tcl/interface/luminary-lm3s811.cfg b/tcl/interface/luminary-lm3s811.cfg deleted file mode 100644 index fd747c090..000000000 --- a/tcl/interface/luminary-lm3s811.cfg +++ /dev/null @@ -1,18 +0,0 @@ -# -# Luminary Micro Stellaris LM3S811 Evaluation Kit -# -# http://www.luminarymicro.com/products/stellaris_811_evaluation_kits.html -# -# NOTE: this is only for boards *before* Rev C, which adds support -# for SWO tracing with ADBUS_6 DBG_ENn and BDBUS_4 SWO_EN signals. -# The "evb_lm3s811" layout doesn't set up those signals. -# -# Rev C boards work more like the other Stellaris eval boards. They -# need to use the "luminary_icdi" layout to work correctly. -# - -interface ft2232 -ft2232_device_desc "LM3S811 Evaluation Board" -ft2232_layout evb_lm3s811 -ft2232_vid_pid 0x0403 0xbcd9 - diff --git a/tcl/interface/luminary.cfg b/tcl/interface/luminary.cfg deleted file mode 100644 index e94e51494..000000000 --- a/tcl/interface/luminary.cfg +++ /dev/null @@ -1,31 +0,0 @@ -# -# Luminary Micro Stellaris Evaluation Kits -# -# http://www.luminarymicro.com/products/evaluation_kits.html -# -# There are a number of evaluation kits for Stellaris Cortex-M3 chips. -# Currently they all bundle FT2232 based debug support. When that is -# used (instead of an external adapter), use this config file in one -# of these two modes: -# -# - Eval board debug ... debug of the Stellaris chip via port A. -# -# - Other board debug ... same thing, but the board acts as a debug -# adapter for another board (using a standard ARM JTAG connector). -# The Stellaris chip stays in reset. -# -# Those support both JTAG and SWD. SWD is an ARM-only two-wire debug -# protocol; in 2009, OpenOCD does not support SWD. -# -# Port B of the FT2232 chip is normally used as a serial link to the -# Stellaris chip. On most boards (but not older LM3S811 eval boards), -# when SWD is used Port B may instead be used to read low-bandwidth -# "SWO trace" data, including so-called "printf style" output from -# firmware via the ITM module as well as profile data. -# - -interface ft2232 -ft2232_device_desc "Stellaris Evaluation Board" -ft2232_layout luminary_icdi -ft2232_vid_pid 0x0403 0xbcd9 - diff --git a/tcl/interface/minimodule.cfg b/tcl/interface/minimodule.cfg deleted file mode 100644 index c8f9ba106..000000000 --- a/tcl/interface/minimodule.cfg +++ /dev/null @@ -1,10 +0,0 @@ -# -# FTDI MiniModule -# -# http://www.ftdichip.com/Support/Documents/DataSheets/Modules/DS_FT2232H_Mini_Module.pdf -# - -interface ft2232 -ft2232_device_desc "FT2232H MiniModule" -ft2232_layout "minimodule" -ft2232_vid_pid 0x0403 0x6010 diff --git a/tcl/interface/nds32-aice.cfg b/tcl/interface/nds32-aice.cfg deleted file mode 100644 index 5363b4c1d..000000000 --- a/tcl/interface/nds32-aice.cfg +++ /dev/null @@ -1,15 +0,0 @@ -# -# Andes AICE -# -# http://www.andestech.com -# - -interface aice -aice desc "Andes AICE adapter" -aice serial "C001-42163" -aice vid_pid 0x1CFC 0x0000 -aice port aice_usb -reset_config trst_and_srst -adapter_khz 24000 -aice retry_times 50 -aice count_to_check_dbger 30 diff --git a/tcl/interface/neodb.cfg b/tcl/interface/neodb.cfg deleted file mode 100644 index 8e2f52672..000000000 --- a/tcl/interface/neodb.cfg +++ /dev/null @@ -1,10 +0,0 @@ -# -# Openmoko USB JTAG/RS232 adapter -# -# http://wiki.openmoko.org/wiki/Debug_Board_v3 -# - -interface ft2232 -ft2232_device_desc "Debug Board for Neo1973" -ft2232_layout jtagkey -ft2232_vid_pid 0x1457 0x5118 diff --git a/tcl/interface/ngxtech.cfg b/tcl/interface/ngxtech.cfg deleted file mode 100644 index 9dfe01c30..000000000 --- a/tcl/interface/ngxtech.cfg +++ /dev/null @@ -1,10 +0,0 @@ -# -# NGX ARM USB JTAG -# -# http://shop.ngxtechnologies.com/product_info.php?cPath=26&products_id=30 -# - -interface ft2232 -ft2232_device_desc "NGX JTAG A" -ft2232_vid_pid 0x0403 0x6010 -ft2232_layout "oocdlink" diff --git a/tcl/interface/olimex-arm-usb-ocd-h.cfg b/tcl/interface/olimex-arm-usb-ocd-h.cfg deleted file mode 100644 index 47daa928f..000000000 --- a/tcl/interface/olimex-arm-usb-ocd-h.cfg +++ /dev/null @@ -1,11 +0,0 @@ -# -# Olimex ARM-USB-OCD-H -# -# http://www.olimex.com/dev/arm-usb-ocd.html -# - -interface ft2232 -ft2232_device_desc "Olimex OpenOCD JTAG ARM-USB-OCD-H" -ft2232_layout olimex-jtag -ft2232_vid_pid 0x15ba 0x002b - diff --git a/tcl/interface/olimex-arm-usb-ocd.cfg b/tcl/interface/olimex-arm-usb-ocd.cfg deleted file mode 100644 index 569dcef59..000000000 --- a/tcl/interface/olimex-arm-usb-ocd.cfg +++ /dev/null @@ -1,11 +0,0 @@ -# -# Olimex ARM-USB-OCD -# -# http://www.olimex.com/dev/arm-usb-ocd.html -# - -interface ft2232 -ft2232_device_desc "Olimex OpenOCD JTAG" -ft2232_layout olimex-jtag -ft2232_vid_pid 0x15ba 0x0003 - diff --git a/tcl/interface/olimex-arm-usb-tiny-h.cfg b/tcl/interface/olimex-arm-usb-tiny-h.cfg deleted file mode 100644 index b6aa952f3..000000000 --- a/tcl/interface/olimex-arm-usb-tiny-h.cfg +++ /dev/null @@ -1,11 +0,0 @@ -# -# Olimex ARM-USB-TINY-H -# -# http://www.olimex.com/dev/arm-usb-tiny-h.html -# - -interface ft2232 -ft2232_device_desc "Olimex OpenOCD JTAG ARM-USB-TINY-H" -ft2232_layout olimex-jtag -ft2232_vid_pid 0x15ba 0x002a - diff --git a/tcl/interface/olimex-jtag-tiny.cfg b/tcl/interface/olimex-jtag-tiny.cfg deleted file mode 100644 index f28ed9daa..000000000 --- a/tcl/interface/olimex-jtag-tiny.cfg +++ /dev/null @@ -1,11 +0,0 @@ -# -# Olimex ARM-USB-TINY -# -# http://www.olimex.com/dev/arm-usb-tiny.html -# - -interface ft2232 -ft2232_device_desc "Olimex OpenOCD JTAG TINY" -ft2232_layout olimex-jtag -ft2232_vid_pid 0x15ba 0x0004 - diff --git a/tcl/interface/oocdlink.cfg b/tcl/interface/oocdlink.cfg deleted file mode 100644 index 4e962f522..000000000 --- a/tcl/interface/oocdlink.cfg +++ /dev/null @@ -1,12 +0,0 @@ -# -# Joern Kaipf's OOCDLink -# -# http://www.joernonline.de/contrexx2/cms/index.php?page=126 -# - -interface ft2232 -ft2232_device_desc "OOCDLink" -ft2232_layout oocdlink -ft2232_vid_pid 0x0403 0xbaf8 -adapter_khz 5 - diff --git a/tcl/interface/opendous.cfg b/tcl/interface/opendous.cfg deleted file mode 100644 index 21ced6fbe..000000000 --- a/tcl/interface/opendous.cfg +++ /dev/null @@ -1,7 +0,0 @@ -# -# opendous-jtag -# -# http://code.google.com/p/opendous-jtag/ -# - -interface opendous diff --git a/tcl/interface/opendous_ftdi.cfg b/tcl/interface/opendous_ftdi.cfg deleted file mode 100644 index e0e05c4a0..000000000 --- a/tcl/interface/opendous_ftdi.cfg +++ /dev/null @@ -1,15 +0,0 @@ -# -# Opendous -# -# http://code.google.com/p/opendous/wiki/JTAG -# -# According to the website, it is similar to jtagkey, but it uses channel B -# (and it has a different pid number). -# - -interface ft2232 -ft2232_device_desc "Dual RS232-HS" -ft2232_layout jtagkey -ft2232_vid_pid 0x0403 0x6010 -ft2232_channel 2 - diff --git a/tcl/interface/openjtag.cfg b/tcl/interface/openjtag.cfg deleted file mode 100644 index b20c22b6c..000000000 --- a/tcl/interface/openjtag.cfg +++ /dev/null @@ -1,8 +0,0 @@ -# -# OpenJTAG -# -# www.openjtag.org -# - -interface openjtag -openjtag_device_desc "Open JTAG Project" \ No newline at end of file diff --git a/tcl/interface/openocd-usb-hs.cfg b/tcl/interface/openocd-usb-hs.cfg deleted file mode 100644 index ddf3dce06..000000000 --- a/tcl/interface/openocd-usb-hs.cfg +++ /dev/null @@ -1,11 +0,0 @@ -# -# embedded projects openocd usb adapter v3 -# -# http://shop.embedded-projects.net/index.php?module=artikel&action=artikel&id=14 -# - -interface ft2232 -ft2232_vid_pid 0x0403 0x6010 -ft2232_device_desc "Dual RS232-HS" -ft2232_layout "oocdlink" -ft2232_latency 2 diff --git a/tcl/interface/openocd-usb.cfg b/tcl/interface/openocd-usb.cfg deleted file mode 100644 index 4000b23fb..000000000 --- a/tcl/interface/openocd-usb.cfg +++ /dev/null @@ -1,11 +0,0 @@ -# -# Hubert Hoegl's USB to JTAG -# -# http://www.hs-augsburg.de/~hhoegl/proj/usbjtag/usbjtag.html -# - -interface ft2232 -ft2232_vid_pid 0x0403 0x6010 -ft2232_device_desc "Dual RS232" -ft2232_layout "oocdlink" -ft2232_latency 2 diff --git a/tcl/interface/openrd.cfg b/tcl/interface/openrd.cfg deleted file mode 100644 index 322b508b9..000000000 --- a/tcl/interface/openrd.cfg +++ /dev/null @@ -1,12 +0,0 @@ -# -# Marvell OpenRD -# -# http://www.marvell.com/products/embedded_processors/developer/kirkwood/openrd.jsp -# - -interface ft2232 -ft2232_layout sheevaplug -ft2232_vid_pid 0x0403 0x9e90 -ft2232_device_desc "OpenRD JTAGKey FT2232D B" -adapter_khz 3000 - diff --git a/tcl/interface/osbdm.cfg b/tcl/interface/osbdm.cfg deleted file mode 100644 index e88ce50b5..000000000 --- a/tcl/interface/osbdm.cfg +++ /dev/null @@ -1,7 +0,0 @@ -# -# P&E Micro OSBDM (aka OSJTAG) interface -# -# http://pemicro.com/osbdm/ -# -interface osbdm -reset_config srst_only diff --git a/tcl/interface/parport.cfg b/tcl/interface/parport.cfg deleted file mode 100644 index ae3f8f158..000000000 --- a/tcl/interface/parport.cfg +++ /dev/null @@ -1,19 +0,0 @@ -# -# Parallel port wiggler (many clones available) on port 0x378 -# -# Addresses: 0x378/LPT1 or 0x278/LPT2 ... -# - -if { [info exists PARPORTADDR] } { - set _PARPORTADDR $PARPORTADDR -} else { - if {$tcl_platform(platform) eq "windows"} { - set _PARPORTADDR 0x378 - } { - set _PARPORTADDR 0 - } -} - -interface parport -parport_port $_PARPORTADDR -parport_cable wiggler diff --git a/tcl/interface/parport_dlc5.cfg b/tcl/interface/parport_dlc5.cfg deleted file mode 100644 index 98345808e..000000000 --- a/tcl/interface/parport_dlc5.cfg +++ /dev/null @@ -1,16 +0,0 @@ -# -# Xilinx Parallel Cable III 'DLC 5' (and various clones) -# -# http://www.xilinx.com/itp/xilinx4/data/docs/pac/appendixb.html -# - -if { [info exists PARPORTADDR] } { - set _PARPORTADDR $PARPORTADDR -} else { - set _PARPORTADDR 0 -} - -interface parport -parport_port $_PARPORTADDR -parport_cable dlc5 - diff --git a/tcl/interface/raspberrypi-native.cfg b/tcl/interface/raspberrypi-native.cfg deleted file mode 100644 index 6b73f3541..000000000 --- a/tcl/interface/raspberrypi-native.cfg +++ /dev/null @@ -1,35 +0,0 @@ -# -# Config for using Raspberry Pi's expansion header -# -# This is best used with a fast enough buffer but also -# is suitable for direct connection if the target voltage -# matches RPi's 3.3V and the cable is short enough. -# -# Do not forget the GND connection, pin 6 of the expansion header. -# - -interface bcm2835gpio - -bcm2835gpio_peripheral_base 0x20000000 - -# Transition delay calculation: SPEED_COEFF/khz - SPEED_OFFSET -# These depend on system clock, calibrated for stock 700MHz -# bcm2835gpio_speed SPEED_COEFF SPEED_OFFSET -bcm2835gpio_speed_coeffs 113714 28 - -# Each of the JTAG lines need a gpio number set: tck tms tdi tdo -# Header pin numbers: 23 22 19 21 -bcm2835gpio_jtag_nums 11 25 10 9 - -# If you define trst or srst, use appropriate reset_config -# Header pin numbers: TRST - 26, SRST - 18 - -# bcm2835gpio_trst_num 7 -# reset_config trst_only - -# bcm2835gpio_srst_num 24 -# reset_config srst_only srst_push_pull - -# or if you have both connected, -# reset_config trst_and_srst srst_push_pull - diff --git a/tcl/interface/raspberrypi2-native.cfg b/tcl/interface/raspberrypi2-native.cfg deleted file mode 100644 index f846fa25d..000000000 --- a/tcl/interface/raspberrypi2-native.cfg +++ /dev/null @@ -1,42 +0,0 @@ -# -# Config for using Raspberry Pi's expansion header -# -# This is best used with a fast enough buffer but also -# is suitable for direct connection if the target voltage -# matches RPi's 3.3V and the cable is short enough. -# -# Do not forget the GND connection, pin 6 of the expansion header. -# - -interface bcm2835gpio - -bcm2835gpio_peripheral_base 0x3F000000 - -# Transition delay calculation: SPEED_COEFF/khz - SPEED_OFFSET -# These depend on system clock, calibrated for stock 700MHz -# bcm2835gpio_speed SPEED_COEFF SPEED_OFFSET -bcm2835gpio_speed_coeffs 146203 36 - -# Each of the JTAG lines need a gpio number set: tck tms tdi tdo -# Header pin numbers: 23 22 19 21 -# bcm2835gpio_jtag_nums 11 25 10 9 - -# or if you have both connected, -# reset_config trst_and_srst srst_push_pull - -# Each of the SWD lines need a gpio number set: swclk swdio -# Header pin numbers: 22 18 -bcm2835gpio_swd_nums 25 24 - -# If you define trst or srst, use appropriate reset_config -# Header pin numbers: TRST - 26, SRST - 18 - -# bcm2835gpio_trst_num 7 -# reset_config trst_only - -bcm2835gpio_srst_num 18 -reset_config srst_only srst_push_pull - -# or if you have both connected, -# reset_config trst_and_srst srst_push_pull - diff --git a/tcl/interface/redbee-econotag.cfg b/tcl/interface/redbee-econotag.cfg deleted file mode 100644 index 7e17a05cc..000000000 --- a/tcl/interface/redbee-econotag.cfg +++ /dev/null @@ -1,13 +0,0 @@ -# -# Redwire Redbee-Econotag -# -# http://www.redwirellc.com/store/node/1 -# -# The Redbee-Econotag has an onboard FT2232H with: -# - FT2232H channel A wired to mc13224v JTAG -# - FT2232H channel B wired to mc13224v UART1 -# - -interface ft2232 -ft2232_layout redbee-econotag -ft2232_vid_pid 0x0403 0x6010 diff --git a/tcl/interface/redbee-usb.cfg b/tcl/interface/redbee-usb.cfg deleted file mode 100644 index 5e7e4f7de..000000000 --- a/tcl/interface/redbee-usb.cfg +++ /dev/null @@ -1,13 +0,0 @@ -# -# Redwire Redbee-USB -# -# http://www.redwirellc.com -# -# The Redbee-USB has an onboard FT2232H with: -# - FT2232H channel B wired to mc13224v JTAG -# - FT2232H channel A wired to mc13224v UART1 -# - -interface ft2232 -ft2232_layout redbee-usb -ft2232_vid_pid 0x0403 0x6010 diff --git a/tcl/interface/rlink.cfg b/tcl/interface/rlink.cfg deleted file mode 100644 index 2f13cc489..000000000 --- a/tcl/interface/rlink.cfg +++ /dev/null @@ -1,8 +0,0 @@ -# -# Raisonance RLink -# -# http://www.mcu-raisonance.com/~rlink-debugger-programmer__microcontrollers__tool~tool__T018:4cn9ziz4bnx6.html -# - -interface rlink - diff --git a/tcl/interface/sheevaplug.cfg b/tcl/interface/sheevaplug.cfg deleted file mode 100644 index d46d71e28..000000000 --- a/tcl/interface/sheevaplug.cfg +++ /dev/null @@ -1,12 +0,0 @@ -# -# Marvel SheevaPlug Development Kit -# -# http://www.marvell.com/products/embedded_processors/developer/kirkwood/sheevaplug.jsp -# - -interface ft2232 -ft2232_layout sheevaplug -ft2232_vid_pid 0x9e88 0x9e8f -ft2232_device_desc "SheevaPlug JTAGKey FT2232D B" -adapter_khz 2000 - diff --git a/tcl/interface/signalyzer-h2.cfg b/tcl/interface/signalyzer-h2.cfg deleted file mode 100644 index 24288acba..000000000 --- a/tcl/interface/signalyzer-h2.cfg +++ /dev/null @@ -1,11 +0,0 @@ -# -# Xverve Signalyzer H2 (DT-USB-SH2) -# -# http://www.signalyzer.com -# - -interface ft2232 -ft2232_device_desc "Signalyzer H2" -ft2232_layout signalyzer-h -ft2232_vid_pid 0x0403 0xbca2 - diff --git a/tcl/interface/signalyzer-h4.cfg b/tcl/interface/signalyzer-h4.cfg deleted file mode 100644 index d2b260b82..000000000 --- a/tcl/interface/signalyzer-h4.cfg +++ /dev/null @@ -1,11 +0,0 @@ -# -# Xverve Signalyzer H4 (DT-USB-SH4) -# -# http://www.signalyzer.com -# - -interface ft2232 -ft2232_device_desc "Signalyzer H4" -ft2232_layout signalyzer-h -ft2232_vid_pid 0x0403 0xbca4 - diff --git a/tcl/interface/signalyzer-lite.cfg b/tcl/interface/signalyzer-lite.cfg deleted file mode 100644 index 834bc0c59..000000000 --- a/tcl/interface/signalyzer-lite.cfg +++ /dev/null @@ -1,11 +0,0 @@ -# -# Xverve Signalyzer LITE (DT-USB-SLITE) -# -# http://www.signalyzer.com -# - -interface ft2232 -ft2232_device_desc "Signalyzer LITE" -ft2232_layout signalyzer -ft2232_vid_pid 0x0403 0xbca1 - diff --git a/tcl/interface/signalyzer.cfg b/tcl/interface/signalyzer.cfg deleted file mode 100644 index b0581c5c3..000000000 --- a/tcl/interface/signalyzer.cfg +++ /dev/null @@ -1,11 +0,0 @@ -# -# Xverve Signalyzer Tool (DT-USB-ST) -# -# http://www.signalyzer.com -# - -interface ft2232 -ft2232_device_desc "Signalyzer" -ft2232_layout signalyzer -ft2232_vid_pid 0x0403 0xbca0 - diff --git a/tcl/interface/stlink-v1.cfg b/tcl/interface/stlink-v1.cfg deleted file mode 100644 index 13f207dc6..000000000 --- a/tcl/interface/stlink-v1.cfg +++ /dev/null @@ -1,9 +0,0 @@ -# -# STMicroelectronics ST-LINK/V1 in-circuit debugger/programmer -# - -interface hla -hla_layout stlink -hla_device_desc "ST-LINK/V1" -hla_vid_pid 0x0483 0x3744 - diff --git a/tcl/interface/stlink-v2-1.cfg b/tcl/interface/stlink-v2-1.cfg deleted file mode 100644 index 093e80177..000000000 --- a/tcl/interface/stlink-v2-1.cfg +++ /dev/null @@ -1,16 +0,0 @@ -# -# STMicroelectronics ST-LINK/V2-1 in-circuit debugger/programmer -# - -interface hla -hla_layout stlink -hla_device_desc "ST-LINK/V2-1" -hla_vid_pid 0x0483 0x374b - -# Optionally specify the serial number of ST-LINK/V2 usb device. ST-LINK/V2 -# devices seem to have serial numbers with unreadable characters. ST-LINK/V2 -# firmware version >= V2.J21.S4 recommended to avoid issues with adapter serial -# number reset issues. -# eg. -#hla_serial "\xaa\xbc\x6e\x06\x50\x75\xff\x55\x17\x42\x19\x3f" - diff --git a/tcl/interface/stlink-v2.cfg b/tcl/interface/stlink-v2.cfg deleted file mode 100644 index ae545a118..000000000 --- a/tcl/interface/stlink-v2.cfg +++ /dev/null @@ -1,16 +0,0 @@ -# -# STMicroelectronics ST-LINK/V2 in-circuit debugger/programmer -# - -interface hla -hla_layout stlink -hla_device_desc "ST-LINK/V2" -hla_vid_pid 0x0483 0x3748 - -# Optionally specify the serial number of ST-LINK/V2 usb device. ST-LINK/V2 -# devices seem to have serial numbers with unreadable characters. ST-LINK/V2 -# firmware version >= V2.J21.S4 recommended to avoid issues with adapter serial -# number reset issues. -# eg. -#hla_serial "\xaa\xbc\x6e\x06\x50\x75\xff\x55\x17\x42\x19\x3f" - diff --git a/tcl/interface/stm32-stick.cfg b/tcl/interface/stm32-stick.cfg deleted file mode 100644 index 9dcf8162b..000000000 --- a/tcl/interface/stm32-stick.cfg +++ /dev/null @@ -1,11 +0,0 @@ -# -# Hitex STM32-PerformanceStick -# -# http://www.hitex.com/index.php?id=340 -# - -interface ft2232 -ft2232_device_desc "STM32-PerformanceStick" -ft2232_layout stm32stick -ft2232_vid_pid 0x0640 0x002d - diff --git a/tcl/interface/sysfsgpio-raspberrypi.cfg b/tcl/interface/sysfsgpio-raspberrypi.cfg deleted file mode 100644 index 363642284..000000000 --- a/tcl/interface/sysfsgpio-raspberrypi.cfg +++ /dev/null @@ -1,21 +0,0 @@ -# -# Config for using RaspberryPi's expansion header -# -# This is best used with a fast enough buffer but also -# is suitable for direct connection if the target voltage -# matches RPi's 3.3V -# -# Do not forget the GND connection, pin 6 of the expansion header. -# - -interface sysfsgpio - -# Each of the JTAG lines need a gpio number set: tck tms tdi tdo -# Header pin numbers: 23 22 19 21 -sysfsgpio_jtag_nums 11 25 10 9 - -# At least one of srst or trst needs to be specified -# Header pin numbers: TRST - 26, SRST - 18 -sysfsgpio_trst_num 7 -# sysfsgpio_srst_num 24 - diff --git a/tcl/interface/ti-icdi.cfg b/tcl/interface/ti-icdi.cfg deleted file mode 100644 index 0fc3a9b67..000000000 --- a/tcl/interface/ti-icdi.cfg +++ /dev/null @@ -1,13 +0,0 @@ -# -# TI Stellaris In-Circuit Debug Interface (ICDI) Board -# -# This is the propriety ICDI interface used on newer boards such as -# LM4F232 Evaluation Kit - http://www.ti.com/tool/ek-lm4f232 -# Stellaris Launchpad - http://www.ti.com/stellaris-launchpad -# http://www.ti.com/tool/ek-lm4f232 -# - -interface hla -hla_layout ti-icdi -hla_vid_pid 0x1cbe 0x00fd - diff --git a/tcl/interface/turtelizer2.cfg b/tcl/interface/turtelizer2.cfg deleted file mode 100644 index c5e10c08f..000000000 --- a/tcl/interface/turtelizer2.cfg +++ /dev/null @@ -1,15 +0,0 @@ -# -# egnite Turtelizer 2 -# -# http://www.ethernut.de/en/hardware/turtelizer/index.html -# -# Deprecated, if possible use tcl/interface/ftdi/turtelizer... -# To run, one of following configure option needed -# --enable-legacy-ft2232_libftdi -# --enable-legacy-ft2232_ftd2xx - -interface ft2232 -ft2232_device_desc "Turtelizer JTAG/RS232 Adapter" -ft2232_layout turtelizer2 -ft2232_vid_pid 0x0403 0xbdc8 - diff --git a/tcl/interface/ulink.cfg b/tcl/interface/ulink.cfg deleted file mode 100644 index 3b1fad071..000000000 --- a/tcl/interface/ulink.cfg +++ /dev/null @@ -1,8 +0,0 @@ -# -# Keil ULINK running OpenULINK firmware. -# -# http://www.keil.com/ulink1/ -# http://article.gmane.org/gmane.comp.debugging.openocd.devel/17362 -# - -interface ulink diff --git a/tcl/interface/usb-jtag.cfg b/tcl/interface/usb-jtag.cfg deleted file mode 100644 index 15274d529..000000000 --- a/tcl/interface/usb-jtag.cfg +++ /dev/null @@ -1,37 +0,0 @@ -# ixo-usb-jtag - Emulation of a Altera Bus Blaster I on a Cypress FX2 IC. -# -# The ixo-usb-jtag firmware can be loaded onto a bunch of different hardware -# including; -# * Xilinx USB Platform Cable -# * Many Digilent boards such as the Nexys, Nexys 2 and Atlys boards -# * Many fpga4fun.com boards from such as the Saxo and Xylo boards -# * The Numato Opsis -# -# Original version - http://www.ixo.de/info/usb_jtag/ -# Updated version - http://ixo-jtag.sourceforge.net/ -# Newest version - http://github.com/mithro/ixo-usb-jtag -# -# Procedure for using is; -# * Get the ixo-usb-jtag firmware for your hardware (or build it yourself). -# * Load the firmware using the fxload tool. -# * Use openocd. -# -# Unless you burn the firmware into the EEPROM on your device, power cycling -# will require you to reload the firmware using the fxload tool. This can be -# automated by using udev rules (which can be found in the firmware -# repository). -# -# Ubuntu packages built from mithro's version (with prebuilt firmware and udev -# rules) can be found at -# https://launchpad.net/~timvideos/+archive/ubuntu/fpga-support -# -# TODO: Refactor the usb_blaster driver to allow loading firmware using any low -# level driver. Loading firmware is currently only supported on the ublast2 -# driver but ixo-usb-jtag requires the ftdi or ftd2xx driver. - -interface usb_blaster -usb_blaster_vid_pid 0x16C0 0x06AD -usb_blaster_device_desc "Van Ooijen Technische Informatica" -# ixo-usb-jtag is only compatible with the ublast1 protocol implemented via the -# ftdi or ftd2xx modes, using ublast2 will cause openocd to hang. -usb_blaster_lowlevel_driver ftdi diff --git a/tcl/interface/usbprog.cfg b/tcl/interface/usbprog.cfg deleted file mode 100644 index b4f0da328..000000000 --- a/tcl/interface/usbprog.cfg +++ /dev/null @@ -1,10 +0,0 @@ -# -# Embedded Projects USBprog -# -# http://embedded-projects.net/index.php?page_id=135 -# - -interface usbprog -# USBprog is broken w/short TMS sequences, this is a workaround -# until the C code can be fixed. -tms_sequence long diff --git a/tcl/interface/vpaclink.cfg b/tcl/interface/vpaclink.cfg deleted file mode 100644 index a4795d30a..000000000 --- a/tcl/interface/vpaclink.cfg +++ /dev/null @@ -1,10 +0,0 @@ -# -# Voipac VPACLink -# -# http://voipac.com/27M-JTG-000 -# - -interface ft2232 -ft2232_device_desc "VPACLink A" -ft2232_layout oocdlink -ft2232_vid_pid 0x0403 0x6010 diff --git a/tcl/interface/vsllink.cfg b/tcl/interface/vsllink.cfg deleted file mode 100644 index fad793490..000000000 --- a/tcl/interface/vsllink.cfg +++ /dev/null @@ -1,8 +0,0 @@ -# -# Versaloon Link -- VSLLink -# -# http://www.versaloon.com/ -# - -interface vsllink - diff --git a/tcl/interface/xds100v2.cfg b/tcl/interface/xds100v2.cfg deleted file mode 100644 index f14f1d8d7..000000000 --- a/tcl/interface/xds100v2.cfg +++ /dev/null @@ -1,10 +0,0 @@ -# -# Texas Instruments XDS100v2 -# -# http://processors.wiki.ti.com/index.php/XDS100#XDS100v2_Features -# - -interface ft2232 -ft2232_device_desc "Texas Instruments Inc.XDS100 Ver 2.0" -ft2232_layout xds100v2 -ft2232_vid_pid 0x0403 0xa6d0 diff --git a/tcl/mem_helper.tcl b/tcl/mem_helper.tcl deleted file mode 100644 index 86ad00f7e..000000000 --- a/tcl/mem_helper.tcl +++ /dev/null @@ -1,31 +0,0 @@ -# Helper for common memory read/modify/write procedures - -# mrw: "memory read word", returns value of $reg -proc mrw {reg} { - set value "" - mem2array value 32 $reg 1 - return $value(0) -} - -add_usage_text mrw "address" -add_help_text mrw "Returns value of word in memory." - -proc mrb {reg} { - set value "" - mem2array value 8 $reg 1 - return $value(0) -} - -add_usage_text mrb "address" -add_help_text mrb "Returns value of byte in memory." - -# mmw: "memory modify word", updates value of $reg -# $reg <== ((value & ~$clearbits) | $setbits) -proc mmw {reg setbits clearbits} { - set old [mrw $reg] - set new [expr ($old & ~$clearbits) | $setbits] - mww $reg $new -} - -add_usage_text mmw "address setbits clearbits" -add_help_text mmw "Modify word in memory. new_val = (old_val & ~clearbits) | setbits;" diff --git a/tcl/memory.tcl b/tcl/memory.tcl deleted file mode 100644 index 83c96d6c9..000000000 --- a/tcl/memory.tcl +++ /dev/null @@ -1,187 +0,0 @@ -# MEMORY -# -# All Memory regions have two components. -# (1) A count of regions, in the form N_NAME -# (2) An array within info about each region. -# -# The ARRAY -# -# ( RegionNumber , ATTRIBUTE ) -# -# Where is one of: -# -# N_FLASH & FLASH (internal memory) -# N_RAM & RAM (internal memory) -# N_MMREGS & MMREGS (for memory mapped registers) -# N_XMEM & XMEM (off chip memory, ie: flash on cs0, sdram on cs2) -# or N_UNKNOWN & UNKNOWN for things that do not exist. -# -# We have 1 unknown region. -set N_UNKNOWN 1 -# All MEMORY regions must have these attributes -# CS - chip select (if internal, use -1) -set UNKNOWN(0,CHIPSELECT) -1 -# BASE - base address in memory -set UNKNOWN(0,BASE) 0 -# LEN - length in bytes -set UNKNOWN(0,LEN) $CPU_MAX_ADDRESS -# HUMAN - human name of the region -set UNKNOWN(0,HUMAN) "unknown" -# TYPE - one of: -# flash, ram, mmr, unknown -# For harvard arch: -# iflash, dflash, iram, dram -set UNKNOWN(0,TYPE) "unknown" -# RWX - access ablity -# unix style chmod bits -# 0 - no access -# 1 - execute -# 2 - write -# 4 - read -# hence: 7 - readwrite execute -set RWX_NO_ACCESS 0 -set RWX_X_ONLY $BIT0 -set RWX_W_ONLY $BIT1 -set RWX_R_ONLY $BIT2 -set RWX_RW [expr $RWX_R_ONLY + $RWX_W_ONLY] -set RWX_R_X [expr $RWX_R_ONLY + $RWX_X_ONLY] -set RWX_RWX [expr $RWX_R_ONLY + $RWX_W_ONLY + $RWX_X_ONLY] -set UNKNOWN(0,RWX) $RWX_NO_ACCESS - -# WIDTH - access width -# 8,16,32 [0 means ANY] -set ACCESS_WIDTH_NONE 0 -set ACCESS_WIDTH_8 $BIT0 -set ACCESS_WIDTH_16 $BIT1 -set ACCESS_WIDTH_32 $BIT2 -set ACCESS_WIDTH_ANY [expr $ACCESS_WIDTH_8 + $ACCESS_WIDTH_16 + $ACCESS_WIDTH_32] -set UNKNOWN(0,ACCESS_WIDTH) $ACCESS_WIDTH_NONE - -proc iswithin { ADDRESS BASE LEN } { - return [expr ((($ADDRESS - $BASE) > 0) && (($ADDRESS - $BASE + $LEN) > 0))] -} - -proc address_info { ADDRESS } { - - foreach WHERE { FLASH RAM MMREGS XMEM UNKNOWN } { - if { info exists $WHERE } { - set lmt [set N_[set WHERE]] - for { set region 0 } { $region < $lmt } { incr region } { - if { iswithin $ADDRESS $WHERE($region,BASE) $WHERE($region,LEN) } { - return "$WHERE $region"; - } - } - } - } - - # Return the 'unknown' - return "UNKNOWN 0" -} - -proc memread32 {ADDR} { - set foo(0) 0 - if ![ catch { mem2array foo 32 $ADDR 1 } msg ] { - return $foo(0) - } else { - error "memread32: $msg" - } -} - -proc memread16 {ADDR} { - set foo(0) 0 - if ![ catch { mem2array foo 16 $ADDR 1 } msg ] { - return $foo(0) - } else { - error "memread16: $msg" - } -} - -proc memread8 {ADDR} { - set foo(0) 0 - if ![ catch { mem2array foo 8 $ADDR 1 } msg ] { - return $foo(0) - } else { - error "memread8: $msg" - } -} - -proc memwrite32 {ADDR DATA} { - set foo(0) $DATA - if ![ catch { array2mem foo 32 $ADDR 1 } msg ] { - return $foo(0) - } else { - error "memwrite32: $msg" - } -} - -proc memwrite16 {ADDR DATA} { - set foo(0) $DATA - if ![ catch { array2mem foo 16 $ADDR 1 } msg ] { - return $foo(0) - } else { - error "memwrite16: $msg" - } -} - -proc memwrite8 {ADDR DATA} { - set foo(0) $DATA - if ![ catch { array2mem foo 8 $ADDR 1 } msg ] { - return $foo(0) - } else { - error "memwrite8: $msg" - } -} - -proc memread32_phys {ADDR} { - set foo(0) 0 - if ![ catch { mem2array foo 32 $ADDR 1 phys } msg ] { - return $foo(0) - } else { - error "memread32: $msg" - } -} - -proc memread16_phys {ADDR} { - set foo(0) 0 - if ![ catch { mem2array foo 16 $ADDR 1 phys } msg ] { - return $foo(0) - } else { - error "memread16: $msg" - } -} - -proc memread8_phys {ADDR} { - set foo(0) 0 - if ![ catch { mem2array foo 8 $ADDR 1 phys } msg ] { - return $foo(0) - } else { - error "memread8: $msg" - } -} - -proc memwrite32_phys {ADDR DATA} { - set foo(0) $DATA - if ![ catch { array2mem foo 32 $ADDR 1 phys } msg ] { - return $foo(0) - } else { - error "memwrite32: $msg" - } -} - -proc memwrite16_phys {ADDR DATA} { - set foo(0) $DATA - if ![ catch { array2mem foo 16 $ADDR 1 phys } msg ] { - return $foo(0) - } else { - error "memwrite16: $msg" - } -} - -proc memwrite8_phys {ADDR DATA} { - set foo(0) $DATA - if ![ catch { array2mem foo 8 $ADDR 1 phys } msg ] { - return $foo(0) - } else { - error "memwrite8: $msg" - } -} diff --git a/tcl/mmr_helpers.tcl b/tcl/mmr_helpers.tcl deleted file mode 100644 index ce116e459..000000000 --- a/tcl/mmr_helpers.tcl +++ /dev/null @@ -1,72 +0,0 @@ - -proc proc_exists { NAME } { - set n [info commands $NAME] - set l [string length $n] - return [expr $l != 0] -} - -# Give: REGISTER name - must be a global variable. -proc show_mmr32_reg { NAME } { - - global $NAME - # we want $($NAME) - set a [set [set NAME]] - - if ![catch { set v [memread32 $a] } msg ] { - echo [format "%15s: (0x%08x): 0x%08x" $NAME $a $v] - - # Was a helper defined? - set fn show_${NAME}_helper - if [ proc_exists $fn ] { - # Then call it - $fn $NAME $a $v - } - return $v; - } else { - error [format "%s (%s)" $msg $NAME ] - } -} - - -# Give: NAMES - an array of names accessable -# in the callers symbol-scope. -# VAL - the bits to display. - -proc show_mmr32_bits { NAMES VAL } { - - upvar $NAMES MYNAMES - - set w 5 - foreach {IDX N} $MYNAMES { - set l [string length $N] - if { $l > $w } { set w $l } - } - - for { set x 24 } { $x >= 0 } { incr x -8 } { - echo -n " " - for { set y 7 } { $y >= 0 } { incr y -1 } { - set s $MYNAMES([expr $x + $y]) - echo -n [format "%2d: %-*s | " [expr $x + $y] $w $s ] - } - echo "" - - echo -n " " - for { set y 7 } { $y >= 0 } { incr y -1 } { - echo -n [format " %d%*s | " [expr !!($VAL & (1 << ($x + $y)))] [expr $w -1] ""] - } - echo "" - } -} - - -proc show_mmr_bitfield { MSB LSB VAL FIELDNAME FIELDVALUES } { - set width [expr (($MSB - $LSB + 1) + 7) / 4] - set nval [show_normalize_bitfield $VAL $MSB $LSB ] - set name0 [lindex $FIELDVALUES 0 ] - if [ string compare $name0 _NUMBER_ ] { - set sval [lindex $FIELDVALUES $nval] - } else { - set sval "" - } - echo [format "%-15s: %d (0x%0*x) %s" $FIELDNAME $nval $width $nval $sval ] -} diff --git a/tcl/target/1986ве1т.cfg b/tcl/target/1986ве1т.cfg deleted file mode 100644 index 7b0c35f08..000000000 --- a/tcl/target/1986ве1т.cfg +++ /dev/null @@ -1,63 +0,0 @@ -# 1986ВЕ1Т -# http://milandr.ru/index.php?mact=Products,cntnt01,details,0&cntnt01productid=236&cntnt01returnid=68 - -source [find target/swj-dp.tcl] - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME 1986ве1т -} - -if { [info exists ENDIAN] } { - set _ENDIAN $ENDIAN -} else { - set _ENDIAN little -} - -# Work-area is a space in RAM used for flash programming -if { [info exists WORKAREASIZE] } { - set _WORKAREASIZE $WORKAREASIZE -} else { - set _WORKAREASIZE 0x4000 -} - -#jtag scan chain -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - if { [using_jtag] } { - set _CPUTAPID 0x4ba00477 - } { - # SWD IDCODE - set _CPUTAPID 0x2ba01477 - } -} -swj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID - -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME cortex_m -endian $_ENDIAN -chain-position $_TARGETNAME - -# use AHB-Lite SRAM for work area -$_TARGETNAME configure -work-area-phys 0x20100000 -work-area-size $_WORKAREASIZE -work-area-backup 0 - -# can't handle overlapping memory regions -if { [info exists IMEMORY] && [string equal $IMEMORY true] } { - flash bank ${_CHIPNAME}_info.flash mdr 0x00000000 0x01000 0 0 $_TARGETNAME 1 1 4 -} else { - flash bank $_CHIPNAME.flash mdr 0x00000000 0x20000 0 0 $_TARGETNAME 0 32 4 -} - -# JTAG speed should be <= F_CPU/6. F_CPU after reset is 8MHz, so use F_JTAG = 1MHz -adapter_khz 1000 - -adapter_nsrst_delay 100 -if {[using_jtag]} { - jtag_ntrst_delay 100 -} - -if {![using_hla]} { - # if srst is not fitted use SYSRESETREQ to - # perform a soft reset - cortex_m reset_config sysresetreq -} diff --git a/tcl/target/aduc702x.cfg b/tcl/target/aduc702x.cfg deleted file mode 100644 index fca0a7f96..000000000 --- a/tcl/target/aduc702x.cfg +++ /dev/null @@ -1,53 +0,0 @@ -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME aduc702x -} - -if { [info exists ENDIAN] } { - set _ENDIAN $ENDIAN -} else { - # This config file was defaulting to big endian.. - set _ENDIAN little -} - -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - set _CPUTAPID 0x3f0f0f0f -} - -adapter_nsrst_delay 200 -jtag_ntrst_delay 200 - -## JTAG scan chain -#format L IRC IRCM IDCODE (Length, IR Capture, IR Capture Mask, IDCODE) -jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID - -## -## Target configuration -## -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME arm7tdmi -endian $_ENDIAN -chain-position $_TARGETNAME - -# allocate the entire SRAM as working area -$_TARGETNAME configure -work-area-phys 0x10000 -work-area-size 0x2000 - -## flash configuration -# only target number is needed -set _FLASHNAME $_CHIPNAME.flash -flash bank $_FLASHNAME aduc702x 0 0 0 0 $_TARGETNAME - -## If you use the watchdog, the following code makes sure that the board -## doesn't reboot when halted via JTAG. Yes, on the older generation -## AdUC702x, timer3 continues running even when the CPU is halted. - -proc watchdog_service {} { - global watchdog_hdl - mww 0xffff036c 0 -# echo "watchdog!!" - set watchdog_hdl [after 500 watchdog_service] -} - -$_TARGETNAME configure -event reset-halt-post { watchdog_service } -$_TARGETNAME configure -event resume-start { global watchdog_hdl; after cancel $watchdog_hdl } diff --git a/tcl/target/aducm360.cfg b/tcl/target/aducm360.cfg deleted file mode 100755 index 785c18c59..000000000 --- a/tcl/target/aducm360.cfg +++ /dev/null @@ -1,55 +0,0 @@ -# -# This file was created using as references the stm32f1x.cfg and aduc702x.cfg -# -source [find target/swj-dp.tcl] - -# Chip name -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME aducm360 -} - -# Endianess -if { [info exists ENDIAN] } { - set _ENDIAN $ENDIAN -} else { - set _ENDIAN little -} - -# Work-area is a space in RAM used for flash programming -# Eventually, the whole SRAM of ADuCM360 will be used (8kB) -if { [info exists WORKAREASIZE] } { - set _WORKAREASIZE $WORKAREASIZE -} else { - set _WORKAREASIZE 0x2000 -} - -#jtag scan chain -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - set _CPUTAPID 0x2ba01477 -} - -swd newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID - -# SWD/JTAG speed -adapter_khz 1000 - -## -## Target configuration -## -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME cortex_m -endian $_ENDIAN -chain-position $_TARGETNAME - -# allocate the working area -$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0 - -# flash size will be probed -set _FLASHNAME $_CHIPNAME.flash -flash bank $_FLASHNAME aducm360 0x00 0 0 0 $_TARGETNAME - -adapter_nsrst_delay 100 - -cortex_m reset_config sysresetreq diff --git a/tcl/target/alphascale_asm9260t.cfg b/tcl/target/alphascale_asm9260t.cfg deleted file mode 100644 index 7892ea265..000000000 --- a/tcl/target/alphascale_asm9260t.cfg +++ /dev/null @@ -1,25 +0,0 @@ -if { [info exists CHIPNAME] } { - set _CHIPNAME $_CHIPNAME -} else { - set _CHIPNAME asm9260t -} - -if { [info exists ENDIAN] } { - set _ENDIAN $ENDIAN -} else { - set _ENDIAN little -} - -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - set _CPUTAPID 0x079264F3 -} - -# And srst_pulls_trst by chip design. -reset_config srst_pulls_trst - -jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID - -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME arm926ejs -endian $_ENDIAN -chain-position $_TARGETNAME diff --git a/tcl/target/altera_fpgasoc.cfg b/tcl/target/altera_fpgasoc.cfg deleted file mode 100644 index 25fe1f493..000000000 --- a/tcl/target/altera_fpgasoc.cfg +++ /dev/null @@ -1,64 +0,0 @@ -# -# Altera cyclone V SoC family, 5Cxxx -# -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME fpgasoc -} - -# CoreSight Debug Access Port -if { [info exists DAP_TAPID] } { - set _DAP_TAPID $DAP_TAPID -} else { - set _DAP_TAPID 0x4ba00477 -} - -jtag newtap $_CHIPNAME dap -irlen 4 -ircapture 0x01 -irmask 0x0f \ - -expected-id $_DAP_TAPID - -# Subsidiary TAP: fpga -if { [info exists FPGA_TAPID] } { - set _FPGA_TAPID $FPGA_TAPID -} else { - set _FPGA_TAPID 0x02d020dd -} -jtag newtap $_CHIPNAME.fpga tap -irlen 10 -ircapture 0x01 -irmask 0x3 -expected-id $_FPGA_TAPID - - -# -# Cortex-A9 target -# - -# GDB target: Cortex-A9, using DAP, configuring only one core -# Base addresses of cores: -# core 0 - 0x80110000 -# core 1 - 0x80112000 - -# Slow speed to be sure it will work -adapter_khz 1000 - -set _TARGETNAME1 $_CHIPNAME.cpu.0 -set _TARGETNAME2 $_CHIPNAME.cpu.1 - -# A9 core 0 -target create $_TARGETNAME1 cortex_a -chain-position $_CHIPNAME.dap \ - -coreid 0 -dbgbase 0x80110000 - -$_TARGETNAME1 configure -event reset-start { adapter_khz 1000 } -$_TARGETNAME1 configure -event reset-assert-post "cycv_dbginit $_TARGETNAME1" -$_TARGETNAME1 configure -event gdb-attach { halt } - - -# A9 core 1 -#target create $_TARGETNAME2 cortex_a -chain-position $_CHIPNAME.dap \ -# -coreid 1 -dbgbase 0x80112000 - -#$_TARGETNAME2 configure -event reset-start { adapter_khz 1000 } -#$_TARGETNAME2 configure -event reset-assert-post "cycv_dbginit $_TARGETNAME2" -#$_TARGETNAME2 configure -event gdb-attach { halt } - -proc cycv_dbginit {target} { - # General Cortex-A8/A9 debug initialisation - cortex_a dbginit -} diff --git a/tcl/target/am335x.cfg b/tcl/target/am335x.cfg deleted file mode 100644 index 74096151e..000000000 --- a/tcl/target/am335x.cfg +++ /dev/null @@ -1,78 +0,0 @@ -source [find target/icepick.cfg] - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME am335x -} - -# set the taps to be enabled by default. this can be overridden -# by setting DEFAULT_TAPS in a separate configuration file -# or directly on the command line. -if { [info exists DEFAULT_TAPS] } { - set _DEFAULT_TAPS "$DEFAULT_TAPS" -} else { - set _DEFAULT_TAPS "$_CHIPNAME.dap" -} - -# -# Main DAP -# -if { [info exists DAP_TAPID] } { - set _DAP_TAPID $DAP_TAPID -} else { - set _DAP_TAPID 0x4b6b902f -} -jtag newtap $_CHIPNAME dap -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_DAP_TAPID -disable -jtag configure $_CHIPNAME.dap -event tap-enable "icepick_d_tapenable $_CHIPNAME.jrc 12 0" - -# -# M3 DAP -# -if { [info exists M3_DAP_TAPID] } { - set _M3_DAP_TAPID $M3_DAP_TAPID -} else { - set _M3_DAP_TAPID 0x4b6b902f -} -jtag newtap $_CHIPNAME m3_dap -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_M3_DAP_TAPID -disable -jtag configure $_CHIPNAME.m3_dap -event tap-enable "icepick_d_tapenable $_CHIPNAME.jrc 11 0" - -# -# ICEpick-D (JTAG route controller) -# -if { [info exists JRC_TAPID] } { - set _JRC_TAPID $JRC_TAPID -} else { - set _JRC_TAPID 0x0b94402f -} -jtag newtap $_CHIPNAME jrc -irlen 6 -ircapture 0x1 -irmask 0x3f -expected-id $_JRC_TAPID -ignore-version -jtag configure $_CHIPNAME.jrc -event setup { - global _DEFAULT_TAPS - enable_default_taps $_DEFAULT_TAPS -} -# some TCK tycles are required to activate the DEBUG power domain -jtag configure $_CHIPNAME.jrc -event post-reset "runtest 100" - -# -# helper function that enables all taps passed as argument -# -proc enable_default_taps { taps } { - foreach tap $taps { - jtag tapenable $tap - } -} - -# -# Cortex-M3 target -# -set _TARGETNAME_2 $_CHIPNAME.m3 -target create $_TARGETNAME_2 cortex_m -chain-position $_CHIPNAME.m3_dap - -# -# Cortex-A8 target -# -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME cortex_a -chain-position $_CHIPNAME.dap -dbgbase 0x80001000 - -# SRAM: 64K at 0x4030.0000; use the first 16K -$_TARGETNAME configure -work-area-phys 0x40300000 -work-area-size 0x4000 diff --git a/tcl/target/am437x.cfg b/tcl/target/am437x.cfg deleted file mode 100644 index fe0ffff29..000000000 --- a/tcl/target/am437x.cfg +++ /dev/null @@ -1,999 +0,0 @@ -source [find target/icepick.cfg] -source [find mem_helper.tcl] - -############################################################################### -## AM437x Registers ## -############################################################################### -set PRCM_BASE_ADDR 0x44df0000 -set REVISION_PRM [expr $PRCM_BASE_ADDR + 0x0000] -set PRM_IRQSTATUS_MPU [expr $PRCM_BASE_ADDR + 0x0004] -set PRM_IRQENABLE_MPU [expr $PRCM_BASE_ADDR + 0x0008] -set PRM_IRQSTATUS_M3 [expr $PRCM_BASE_ADDR + 0x000c] -set PRM_IRQENABLE_M3 [expr $PRCM_BASE_ADDR + 0x0010] -set PM_MPU_PWRSTCTRL [expr $PRCM_BASE_ADDR + 0x0300] -set PM_MPU_PWRSTST [expr $PRCM_BASE_ADDR + 0x0304] -set RM_MPU_RSTST [expr $PRCM_BASE_ADDR + 0x0314] -set RM_MPU_CONTEXT [expr $PRCM_BASE_ADDR + 0x0324] -set PM_GFX_PWRSTCTRL [expr $PRCM_BASE_ADDR + 0x0400] -set PM_GFX_PWRSTST [expr $PRCM_BASE_ADDR + 0x0404] -set RM_GFX_RSTCTRL [expr $PRCM_BASE_ADDR + 0x0410] -set RM_GFX_RSTST [expr $PRCM_BASE_ADDR + 0x0414] -set RM_GFX_CONTEXT [expr $PRCM_BASE_ADDR + 0x0424] -set RM_RTC_CONTEXT [expr $PRCM_BASE_ADDR + 0x0524] -set RM_WKUP_RSTCTRL [expr $PRCM_BASE_ADDR + 0x2010] -set RM_WKUP_RSTST [expr $PRCM_BASE_ADDR + 0x2014] -set CM_L3_AON_CLKSTCTRL [expr $PRCM_BASE_ADDR + 0x2800] -set CM_WKUP_DEBUGSS_CLKCTRL [expr $PRCM_BASE_ADDR + 0x2820] -set CM_L3S_TSC_CLKSTCTRL [expr $PRCM_BASE_ADDR + 0x2900] -set CM_WKUP_ADC_TSC_CLKCTRL [expr $PRCM_BASE_ADDR + 0x2920] -set CM_L4_WKUP_AON_CLKSTCTRL [expr $PRCM_BASE_ADDR + 0x2a00] -set CM_WKUP_L4WKUP_CLKCTRL [expr $PRCM_BASE_ADDR + 0x2a20] -set CM_WKUP_WKUP_M3_CLKCTRL [expr $PRCM_BASE_ADDR + 0x2a28] -set CM_WKUP_SYNCTIMER_CLKCTRL [expr $PRCM_BASE_ADDR + 0x2a30] -set CM_WKUP_CLKDIV32K_CLKCTRL [expr $PRCM_BASE_ADDR + 0x2a38] -set CM_WKUP_USBPHY0_CLKCTRL [expr $PRCM_BASE_ADDR + 0x2a40] -set CM_WKUP_USBPHY1_CLKCTRL [expr $PRCM_BASE_ADDR + 0x2a48] -set CM_WKUP_CLKSTCTRL [expr $PRCM_BASE_ADDR + 0x2b00] -set CM_WKUP_TIMER0_CLKCTRL [expr $PRCM_BASE_ADDR + 0x2b20] -set CM_WKUP_TIMER1_CLKCTRL [expr $PRCM_BASE_ADDR + 0x2b28] -set CM_WKUP_WDT0_CLKCTRL [expr $PRCM_BASE_ADDR + 0x2b30] -set CM_WKUP_WDT1_CLKCTRL [expr $PRCM_BASE_ADDR + 0x2b38] -set CM_WKUP_I2C0_CLKCTRL [expr $PRCM_BASE_ADDR + 0x2b40] -set CM_WKUP_UART0_CLKCTRL [expr $PRCM_BASE_ADDR + 0x2b48] -set CM_WKUP_SMARTREFLEX0_CLKCTRL [expr $PRCM_BASE_ADDR + 0x2b50] -set CM_WKUP_SMARTREFLEX1_CLKCTRL [expr $PRCM_BASE_ADDR + 0x2b58] -set CM_WKUP_CONTROL_CLKCTRL [expr $PRCM_BASE_ADDR + 0x2b60] -set CM_WKUP_GPIO0_CLKCTRL [expr $PRCM_BASE_ADDR + 0x2b68] -set CM_CLKMODE_DPLL_CORE [expr $PRCM_BASE_ADDR + 0x2d20] -set CM_IDLEST_DPLL_CORE [expr $PRCM_BASE_ADDR + 0x2d24] -set CM_CLKSEL_DPLL_CORE [expr $PRCM_BASE_ADDR + 0x2d2c] -set CM_DIV_M4_DPLL_CORE [expr $PRCM_BASE_ADDR + 0x2d38] -set CM_DIV_M5_DPLL_CORE [expr $PRCM_BASE_ADDR + 0x2d3c] -set CM_DIV_M6_DPLL_CORE [expr $PRCM_BASE_ADDR + 0x2d40] -set CM_SSC_DELTAMSTEP_DPLL_CORE [expr $PRCM_BASE_ADDR + 0x2d48] -set CM_SSC_MODFREQDIV_DPLL_CORE [expr $PRCM_BASE_ADDR + 0x2d4c] -set CM_CLKMODE_DPLL_MPU [expr $PRCM_BASE_ADDR + 0x2d60] -set CM_IDLEST_DPLL_MPU [expr $PRCM_BASE_ADDR + 0x2d64] -set CM_CLKSEL_DPLL_MPU [expr $PRCM_BASE_ADDR + 0x2d6c] -set CM_DIV_M2_DPLL_MPU [expr $PRCM_BASE_ADDR + 0x2d70] -set CM_SSC_DELTAMSTEP_DPLL_MPU [expr $PRCM_BASE_ADDR + 0x2d88] -set CM_SSC_MODFREQDIV_DPLL_MPU [expr $PRCM_BASE_ADDR + 0x2d8c] -set CM_CLKMODE_DPLL_DDR [expr $PRCM_BASE_ADDR + 0x2da0] -set CM_IDLEST_DPLL_DDR [expr $PRCM_BASE_ADDR + 0x2da4] -set CM_CLKSEL_DPLL_DDR [expr $PRCM_BASE_ADDR + 0x2dac] -set CM_DIV_M2_DPLL_DDR [expr $PRCM_BASE_ADDR + 0x2db0] -set CM_DIV_M4_DPLL_DDR [expr $PRCM_BASE_ADDR + 0x2db8] -set CM_SSC_DELTAMSTEP_DPLL_DDR [expr $PRCM_BASE_ADDR + 0x2dc8] -set CM_SSC_MODFREQDIV_DPLL_DDR [expr $PRCM_BASE_ADDR + 0x2dcc] -set CM_CLKMODE_DPLL_PER [expr $PRCM_BASE_ADDR + 0x2de0] -set CM_IDLEST_DPLL_PER [expr $PRCM_BASE_ADDR + 0x2de4] -set CM_CLKSEL_DPLL_PER [expr $PRCM_BASE_ADDR + 0x2dec] -set CM_DIV_M2_DPLL_PER [expr $PRCM_BASE_ADDR + 0x2df0] -set CM_CLKSEL2_DPLL_PER [expr $PRCM_BASE_ADDR + 0x2e04] -set CM_SSC_DELTAMSTEP_DPLL_PER [expr $PRCM_BASE_ADDR + 0x2e08] -set CM_SSC_MODFREQDIV_DPLL_PER [expr $PRCM_BASE_ADDR + 0x2e0c] -set CM_CLKDCOLDO_DPLL_PER [expr $PRCM_BASE_ADDR + 0x2e14] -set CM_CLKMODE_DPLL_DISP [expr $PRCM_BASE_ADDR + 0x2e20] -set CM_IDLEST_DPLL_DISP [expr $PRCM_BASE_ADDR + 0x2e24] -set CM_CLKSEL_DPLL_DISP [expr $PRCM_BASE_ADDR + 0x2e2c] -set CM_DIV_M2_DPLL_DISP [expr $PRCM_BASE_ADDR + 0x2e30] -set CM_SSC_DELTAMSTEP_DPLL_DISP [expr $PRCM_BASE_ADDR + 0x2e48] -set CM_SSC_MODFREQDIV_DPLL_DISP [expr $PRCM_BASE_ADDR + 0x2e4c] -set CM_CLKMODE_DPLL_EXTDEV [expr $PRCM_BASE_ADDR + 0x2e60] -set CM_IDLEST_DPLL_EXTDEV [expr $PRCM_BASE_ADDR + 0x2e64] -set CM_CLKSEL_DPLL_EXTDEV [expr $PRCM_BASE_ADDR + 0x2e6c] -set CM_DIV_M2_DPLL_EXTDEV [expr $PRCM_BASE_ADDR + 0x2e70] -set CM_CLKSEL2_DPLL_EXTDEV [expr $PRCM_BASE_ADDR + 0x2e84] -set CM_SSC_DELTAMSTEP_DPLL_EXTDEV [expr $PRCM_BASE_ADDR + 0x2e88] -set CM_SSC_MODFREQDIV_DPLL_EXTDEV [expr $PRCM_BASE_ADDR + 0x2e8c] -set CM_SHADOW_FREQ_CONFIG1 [expr $PRCM_BASE_ADDR + 0x2fa0] -set CM_SHADOW_FREQ_CONFIG2 [expr $PRCM_BASE_ADDR + 0x2fa4] -set CM_CLKOUT1_CTRL [expr $PRCM_BASE_ADDR + 0x4100] -set CM_DLL_CTRL [expr $PRCM_BASE_ADDR + 0x4104] -set CM_CLKOUT2_CTRL [expr $PRCM_BASE_ADDR + 0x4108] -set CLKSEL_TIMER1MS_CLK [expr $PRCM_BASE_ADDR + 0x4200] -set CLKSEL_TIMER2_CLK [expr $PRCM_BASE_ADDR + 0x4204] -set CLKSEL_TIMER3_CLK [expr $PRCM_BASE_ADDR + 0x4208] -set CLKSEL_TIMER4_CLK [expr $PRCM_BASE_ADDR + 0x420c] -set CLKSEL_TIMER5_CLK [expr $PRCM_BASE_ADDR + 0x4210] -set CLKSEL_TIMER6_CLK [expr $PRCM_BASE_ADDR + 0x4214] -set CLKSEL_TIMER7_CLK [expr $PRCM_BASE_ADDR + 0x4218] -set CLKSEL_TIMER8_CLK [expr $PRCM_BASE_ADDR + 0x421c] -set CLKSEL_TIMER9_CLK [expr $PRCM_BASE_ADDR + 0x4220] -set CLKSEL_TIMER10_CLK [expr $PRCM_BASE_ADDR + 0x4224] -set CLKSEL_TIMER11_CLK [expr $PRCM_BASE_ADDR + 0x4228] -set CLKSEL_WDT1_CLK [expr $PRCM_BASE_ADDR + 0x422c] -set CLKSEL_SYNCTIMER_CLK [expr $PRCM_BASE_ADDR + 0x4230] -set CLKSEL_MAC_CLK [expr $PRCM_BASE_ADDR + 0x4234] -set CLKSEL_CPTS_RFT_CLK [expr $PRCM_BASE_ADDR + 0x4238] -set CLKSEL_GFX_FCLK [expr $PRCM_BASE_ADDR + 0x423c] -set CLKSEL_GPIO0_DBCLK [expr $PRCM_BASE_ADDR + 0x4240] -set CLKSEL_LCDC_PIXEL_CLK [expr $PRCM_BASE_ADDR + 0x4244] -set CLKSEL_ICSS_OCP_CLK [expr $PRCM_BASE_ADDR + 0x4248] -set CLKSEL_DLL_AGING_CLK [expr $PRCM_BASE_ADDR + 0x4250] -set CLKSEL_USBPHY32KHZ_GCLK [expr $PRCM_BASE_ADDR + 0x4260] -set CM_MPU_CLKSTCTRL [expr $PRCM_BASE_ADDR + 0x8300] -set CM_MPU_MPU_CLKCTRL [expr $PRCM_BASE_ADDR + 0x8320] -set CM_GFX_L3_CLKSTCTRL [expr $PRCM_BASE_ADDR + 0x8400] -set CM_GFX_GFX_CLKCTRL [expr $PRCM_BASE_ADDR + 0x8420] -set CM_RTC_CLKSTCTRL [expr $PRCM_BASE_ADDR + 0x8500] -set CM_RTC_RTC_CLKCTRL [expr $PRCM_BASE_ADDR + 0x8520] -set CM_PER_L3_CLKSTCTRL [expr $PRCM_BASE_ADDR + 0x8800] -set CM_PER_L3_CLKCTRL [expr $PRCM_BASE_ADDR + 0x8820] -set CM_PER_AES0_CLKCTRL [expr $PRCM_BASE_ADDR + 0x8828] -set CM_PER_DES_CLKCTRL [expr $PRCM_BASE_ADDR + 0x8830] -set CM_PER_CRYPTODMA_CLKCTRL [expr $PRCM_BASE_ADDR + 0x8838] -set CM_PER_L3_INSTR_CLKCTRL [expr $PRCM_BASE_ADDR + 0x8840] -set CM_PER_MSTR_EXPS_CLKCTRL [expr $PRCM_BASE_ADDR + 0x8848] -set CM_PER_OCMCRAM_CLKCTRL [expr $PRCM_BASE_ADDR + 0x8850] -set CM_PER_SHA0_CLKCTRL [expr $PRCM_BASE_ADDR + 0x8858] -set CM_PER_SLV_EXPS_CLKCTRL [expr $PRCM_BASE_ADDR + 0x8860] -set CM_PER_VPFE0_CLKCTRL [expr $PRCM_BASE_ADDR + 0x8868] -set CM_PER_VPFE1_CLKCTRL [expr $PRCM_BASE_ADDR + 0x8870] -set CM_PER_TPCC_CLKCTRL [expr $PRCM_BASE_ADDR + 0x8878] -set CM_PER_TPTC0_CLKCTRL [expr $PRCM_BASE_ADDR + 0x8880] -set CM_PER_TPTC1_CLKCTRL [expr $PRCM_BASE_ADDR + 0x8888] -set CM_PER_TPTC2_CLKCTRL [expr $PRCM_BASE_ADDR + 0x8890] -set CM_PER_DLL_AGING_CLKCTRL [expr $PRCM_BASE_ADDR + 0x8898] -set CM_PER_L4HS_CLKCTRL [expr $PRCM_BASE_ADDR + 0x88a0] -set CM_PER_L4FW_CLKCTRL [expr $PRCM_BASE_ADDR + 0x88a8] -set CM_PER_L3S_CLKSTCTRL [expr $PRCM_BASE_ADDR + 0x8a00] -set CM_PER_GPMC_CLKCTRL [expr $PRCM_BASE_ADDR + 0x8a20] -set CM_PER_IEEE5000_CLKCTRL [expr $PRCM_BASE_ADDR + 0x8a28] -set CM_PER_MCASP0_CLKCTRL [expr $PRCM_BASE_ADDR + 0x8a38] -set CM_PER_MCASP1_CLKCTRL [expr $PRCM_BASE_ADDR + 0x8a40] -set CM_PER_MMC2_CLKCTRL [expr $PRCM_BASE_ADDR + 0x8a48] -set CM_PER_QSPI_CLKCTRL [expr $PRCM_BASE_ADDR + 0x8a58] -set CM_PER_USB_OTG_SS0_CLKCTRL [expr $PRCM_BASE_ADDR + 0x8a60] -set CM_PER_USB_OTG_SS1_CLKCTRL [expr $PRCM_BASE_ADDR + 0x8a68] -set CM_PER_ICSS_CLKSTCTRL [expr $PRCM_BASE_ADDR + 0x8b00] -set CM_PER_ICSS_CLKCTRL [expr $PRCM_BASE_ADDR + 0x8b20] -set CM_PER_L4LS_CLKSTCTRL [expr $PRCM_BASE_ADDR + 0x8c00] -set CM_PER_L4LS_CLKCTRL [expr $PRCM_BASE_ADDR + 0x8c20] -set CM_PER_DCAN0_CLKCTRL [expr $PRCM_BASE_ADDR + 0x8c28] -set CM_PER_DCAN1_CLKCTRL [expr $PRCM_BASE_ADDR + 0x8c30] -set CM_PER_EPWMSS0_CLKCTRL [expr $PRCM_BASE_ADDR + 0x8c38] -set CM_PER_EPWMSS1_CLKCTRL [expr $PRCM_BASE_ADDR + 0x8c40] -set CM_PER_EPWMSS2_CLKCTRL [expr $PRCM_BASE_ADDR + 0x8c48] -set CM_PER_EPWMSS3_CLKCTRL [expr $PRCM_BASE_ADDR + 0x8c50] -set CM_PER_EPWMSS4_CLKCTRL [expr $PRCM_BASE_ADDR + 0x8c58] -set CM_PER_EPWMSS5_CLKCTRL [expr $PRCM_BASE_ADDR + 0x8c60] -set CM_PER_ELM_CLKCTRL [expr $PRCM_BASE_ADDR + 0x8c68] -set CM_PER_GPIO1_CLKCTRL [expr $PRCM_BASE_ADDR + 0x8c78] -set CM_PER_GPIO2_CLKCTRL [expr $PRCM_BASE_ADDR + 0x8c80] -set CM_PER_GPIO3_CLKCTRL [expr $PRCM_BASE_ADDR + 0x8c88] -set CM_PER_GPIO4_CLKCTRL [expr $PRCM_BASE_ADDR + 0x8c90] -set CM_PER_GPIO5_CLKCTRL [expr $PRCM_BASE_ADDR + 0x8c98] -set CM_PER_HDQ1W_CLKCTRL [expr $PRCM_BASE_ADDR + 0x8ca0] -set CM_PER_I2C1_CLKCTRL [expr $PRCM_BASE_ADDR + 0x8ca8] -set CM_PER_I2C2_CLKCTRL [expr $PRCM_BASE_ADDR + 0x8cb0] -set CM_PER_MAILBOX0_CLKCTRL [expr $PRCM_BASE_ADDR + 0x8cb8] -set CM_PER_MMC0_CLKCTRL [expr $PRCM_BASE_ADDR + 0x8cc0] -set CM_PER_MMC1_CLKCTRL [expr $PRCM_BASE_ADDR + 0x8cc8] -set CM_PER_PKA_CLKCTRL [expr $PRCM_BASE_ADDR + 0x8cd0] -set CM_PER_RNG_CLKCTRL [expr $PRCM_BASE_ADDR + 0x8ce0] -set CM_PER_SPARE0_CLKCTRL [expr $PRCM_BASE_ADDR + 0x8ce8] -set CM_PER_SPARE1_CLKCTRL [expr $PRCM_BASE_ADDR + 0x8cf0] -set CM_PER_SPI0_CLKCTRL [expr $PRCM_BASE_ADDR + 0x8d00] -set CM_PER_SPI1_CLKCTRL [expr $PRCM_BASE_ADDR + 0x8d08] -set CM_PER_SPI2_CLKCTRL [expr $PRCM_BASE_ADDR + 0x8d10] -set CM_PER_SPI3_CLKCTRL [expr $PRCM_BASE_ADDR + 0x8d18] -set CM_PER_SPI4_CLKCTRL [expr $PRCM_BASE_ADDR + 0x8d20] -set CM_PER_SPINLOCK_CLKCTRL [expr $PRCM_BASE_ADDR + 0x8d28] -set CM_PER_TIMER2_CLKCTRL [expr $PRCM_BASE_ADDR + 0x8d30] -set CM_PER_TIMER3_CLKCTRL [expr $PRCM_BASE_ADDR + 0x8d38] -set CM_PER_TIMER4_CLKCTRL [expr $PRCM_BASE_ADDR + 0x8d40] -set CM_PER_TIMER5_CLKCTRL [expr $PRCM_BASE_ADDR + 0x8d48] -set CM_PER_TIMER6_CLKCTRL [expr $PRCM_BASE_ADDR + 0x8d50] -set CM_PER_TIMER7_CLKCTRL [expr $PRCM_BASE_ADDR + 0x8d58] -set CM_PER_TIMER8_CLKCTRL [expr $PRCM_BASE_ADDR + 0x8d60] -set CM_PER_TIMER9_CLKCTRL [expr $PRCM_BASE_ADDR + 0x8d68] -set CM_PER_TIMER10_CLKCTRL [expr $PRCM_BASE_ADDR + 0x8d70] -set CM_PER_TIMER11_CLKCTRL [expr $PRCM_BASE_ADDR + 0x8d78] -set CM_PER_UART1_CLKCTRL [expr $PRCM_BASE_ADDR + 0x8d80] -set CM_PER_UART2_CLKCTRL [expr $PRCM_BASE_ADDR + 0x8d88] -set CM_PER_UART3_CLKCTRL [expr $PRCM_BASE_ADDR + 0x8d90] -set CM_PER_UART4_CLKCTRL [expr $PRCM_BASE_ADDR + 0x8d98] -set CM_PER_UART5_CLKCTRL [expr $PRCM_BASE_ADDR + 0x8da0] -set CM_PER_USBPHYOCP2SCP0_CLKCTRL [expr $PRCM_BASE_ADDR + 0x8db8] -set CM_PER_USBPHYOCP2SCP1_CLKCTRL [expr $PRCM_BASE_ADDR + 0x8dc0] -set CM_PER_EMIF_CLKSTCTRL [expr $PRCM_BASE_ADDR + 0x8f00] -set CM_PER_EMIF_CLKCTRL [expr $PRCM_BASE_ADDR + 0x8f20] -set CM_PER_DLL_CLKCTRL [expr $PRCM_BASE_ADDR + 0x8f28] -set CM_PER_EMIF_FW_CLKCTRL [expr $PRCM_BASE_ADDR + 0x8f30] -set CM_PER_OTFA_EMIF_CLKCTRL [expr $PRCM_BASE_ADDR + 0x8f38] -set CM_PER_DSS_CLKSTCTRL [expr $PRCM_BASE_ADDR + 0x9200] -set CM_PER_DSS_CLKCTRL [expr $PRCM_BASE_ADDR + 0x9220] -set CM_PER_CPSW_CLKSTCTRL [expr $PRCM_BASE_ADDR + 0x9300] -set CM_PER_CPGMAC0_CLKCTRL [expr $PRCM_BASE_ADDR + 0x9320] -set CM_PER_OCPWP_L3_CLKSTCTRL [expr $PRCM_BASE_ADDR + 0x9400] -set CM_PER_OCPWP_CLKCTRL [expr $PRCM_BASE_ADDR + 0x9420] - -set CONTROL_BASE_ADDR 0x44e10000 -set CONTROL_STATUS [expr $CONTROL_BASE_ADDR + 0x0040] -set DEVICE_ID [expr $CONTROL_BASE_ADDR + 0x0600] -set DEV_FEATURE [expr $CONTROL_BASE_ADDR + 0x0604] -set DEV_ATTRIBUTE [expr $CONTROL_BASE_ADDR + 0x0610] -set MAC_ID0_LO [expr $CONTROL_BASE_ADDR + 0x0630] -set MAC_ID0_HI [expr $CONTROL_BASE_ADDR + 0x0634] -set MAC_ID1_LO [expr $CONTROL_BASE_ADDR + 0x0638] -set MAC_ID1_HI [expr $CONTROL_BASE_ADDR + 0x063c] -set USB_VID_PID [expr $CONTROL_BASE_ADDR + 0x07f4] -set CONTROL_CONF_ECAP0_IN_PWM0_OUT [expr $CONTROL_BASE_ADDR + 0x0964] -set CONTROL_CONF_SPI4_CS0 [expr $CONTROL_BASE_ADDR + 0x0a5c] -set CONTROL_CONF_SPI2_SCLK [expr $CONTROL_BASE_ADDR + 0x0a60] -set CONTROL_CONF_SPI2_D0 [expr $CONTROL_BASE_ADDR + 0x0a64] -set CONTROL_CONF_XDMA_EVENT_INTR0 [expr $CONTROL_BASE_ADDR + 0x0a70] -set CONTROL_CONF_XDMA_EVENT_INTR1 [expr $CONTROL_BASE_ADDR + 0x0a74] -set CONTROL_CONF_GPMC_A0 [expr $CONTROL_BASE_ADDR + 0x0840] -set DDR_IO_CTRL [expr $CONTROL_BASE_ADDR + 0x0e04] -set VTP_CTRL_REG [expr $CONTROL_BASE_ADDR + 0x0e0c] -set VREF_CTRL [expr $CONTROL_BASE_ADDR + 0x0e14] -set DDR_CKE_CTRL [expr $CONTROL_BASE_ADDR + 0x131c] -set DDR_ADDRCTRL_IOCTRL [expr $CONTROL_BASE_ADDR + 0x1404] -set DDR_ADDRCTRL_WD0_IOCTRL [expr $CONTROL_BASE_ADDR + 0x1408] -set DDR_ADDRCTRL_WD1_IOCTRL [expr $CONTROL_BASE_ADDR + 0x140c] -set DDR_DATA0_IOCTRL [expr $CONTROL_BASE_ADDR + 0x1440] -set DDR_DATA1_IOCTRL [expr $CONTROL_BASE_ADDR + 0x1444] -set DDR_DATA2_IOCTRL [expr $CONTROL_BASE_ADDR + 0x1448] -set DDR_DATA3_IOCTRL [expr $CONTROL_BASE_ADDR + 0x144c] -set EMIF_SDRAM_CONFIG_EXT [expr $CONTROL_BASE_ADDR + 0x1460] -set EMIF_SDRAM_STATUS_EXT [expr $CONTROL_BASE_ADDR + 0x1464] - -set GPIO0_BASE_ADDR 0x44e07000 -set GPIO0_SYSCONFIG [expr $GPIO0_BASE_ADDR + 0x0010] -set GPIO0_SYSSTATUS [expr $GPIO0_BASE_ADDR + 0x0114] -set GPIO0_CTRL [expr $GPIO0_BASE_ADDR + 0x0130] -set GPIO0_OE [expr $GPIO0_BASE_ADDR + 0x0134] -set GPIO0_CLEARDATAOUT [expr $GPIO0_BASE_ADDR + 0x0190] -set GPIO0_SETDATAOUT [expr $GPIO0_BASE_ADDR + 0x0194] - -set GPIO5_BASE_ADDR 0x48322000 -set GPIO5_SYSCONFIG [expr $GPIO5_BASE_ADDR + 0x0010] -set GPIO5_SYSSTATUS [expr $GPIO5_BASE_ADDR + 0x0114] -set GPIO5_CTRL [expr $GPIO5_BASE_ADDR + 0x0130] -set GPIO5_OE [expr $GPIO5_BASE_ADDR + 0x0134] -set GPIO5_CLEARDATAOUT [expr $GPIO5_BASE_ADDR + 0x0190] -set GPIO5_SETDATAOUT [expr $GPIO5_BASE_ADDR + 0x0194] - -set GPIO1_BASE_ADDR 0x4804c000 -set GPIO1_SYSCONFIG [expr $GPIO1_BASE_ADDR + 0x0010] -set GPIO1_SYSSTATUS [expr $GPIO1_BASE_ADDR + 0x0114] -set GPIO1_CTRL [expr $GPIO1_BASE_ADDR + 0x0130] -set GPIO1_OE [expr $GPIO1_BASE_ADDR + 0x0134] -set GPIO1_CLEARDATAOUT [expr $GPIO1_BASE_ADDR + 0x0190] -set GPIO1_SETDATAOUT [expr $GPIO1_BASE_ADDR + 0x0194] - -set EMIF_BASE_ADDR 0x4c000000 -set EMIF_STATUS [expr $EMIF_BASE_ADDR + 0x0004] -set EMIF_SDRAM_CONFIG [expr $EMIF_BASE_ADDR + 0x0008] -set EMIF_SDRAM_CONFIG_2 [expr $EMIF_BASE_ADDR + 0x000c] -set EMIF_SDRAM_REF_CTRL [expr $EMIF_BASE_ADDR + 0x0010] -set EMIF_SDRAM_REF_CTRL_SHDW [expr $EMIF_BASE_ADDR + 0x0014] -set EMIF_SDRAM_TIM_1 [expr $EMIF_BASE_ADDR + 0x0018] -set EMIF_SDRAM_TIM_1_SHDW [expr $EMIF_BASE_ADDR + 0x001c] -set EMIF_SDRAM_TIM_2 [expr $EMIF_BASE_ADDR + 0x0020] -set EMIF_SDRAM_TIM_2_SHDW [expr $EMIF_BASE_ADDR + 0x0024] -set EMIF_SDRAM_TIM_3 [expr $EMIF_BASE_ADDR + 0x0028] -set EMIF_SDRAM_TIM_3_SHDW [expr $EMIF_BASE_ADDR + 0x002c] -set EMIF_LPDDR2_NVM_TIM [expr $EMIF_BASE_ADDR + 0x0030] -set EMIF_LPDDR2_NVM_TIM_SHDW [expr $EMIF_BASE_ADDR + 0x0034] -set EMIF_PWR_MGMT_CTRL [expr $EMIF_BASE_ADDR + 0x0038] -set EMIF_PWR_MGMT_CTRL_SHDW [expr $EMIF_BASE_ADDR + 0x003c] -set EMIF_LPDDR2_MODE_REG_DATA [expr $EMIF_BASE_ADDR + 0x0040] -set EMIF_LPDDR2_MODE_REG_CFG [expr $EMIF_BASE_ADDR + 0x0050] -set EMIF_OCP_CONFIG [expr $EMIF_BASE_ADDR + 0x0054] -set EMIF_OCP_CFG_VAL_1 [expr $EMIF_BASE_ADDR + 0x0058] -set EMIF_OCP_CFG_VAL_2 [expr $EMIF_BASE_ADDR + 0x005c] -set EMIF_IODFT_TLGC [expr $EMIF_BASE_ADDR + 0x0060] -set EMIF_IODFT_CTRL_MISR_RSLT [expr $EMIF_BASE_ADDR + 0x0064] -set EMIF_IODFT_ADDR_MISR_RSLT [expr $EMIF_BASE_ADDR + 0x0068] -set EMIF_IODFT_DATA_MISR_RSLT_1 [expr $EMIF_BASE_ADDR + 0x006c] -set EMIF_IODFT_DATA_MISR_RSLT_2 [expr $EMIF_BASE_ADDR + 0x0070] -set EMIF_IODFT_DATA_MISR_RSLT_3 [expr $EMIF_BASE_ADDR + 0x0074] -set EMIF_PERF_CNT_1 [expr $EMIF_BASE_ADDR + 0x0080] -set EMIF_PERF_CNT_2 [expr $EMIF_BASE_ADDR + 0x0084] -set EMIF_PERF_CNT_CFG [expr $EMIF_BASE_ADDR + 0x0088] -set EMIF_PERF_CNT_SEL [expr $EMIF_BASE_ADDR + 0x008c] -set EMIF_PERF_CNT_TIM [expr $EMIF_BASE_ADDR + 0x0090] -set EMIF_MISC_REG [expr $EMIF_BASE_ADDR + 0x0094] -set EMIF_DLL_CALIB_CTRL [expr $EMIF_BASE_ADDR + 0x0098] -set EMIF_DLL_CALIB_CTRL_SHDW [expr $EMIF_BASE_ADDR + 0x009c] -set EMIF_IRQ_EOI [expr $EMIF_BASE_ADDR + 0x00a0] -set EMIF_IRQSTATUS_RAW_SYS [expr $EMIF_BASE_ADDR + 0x00a4] -set EMIF_IRQSTATUS_SYS [expr $EMIF_BASE_ADDR + 0x00ac] -set EMIF_IRQENABLE_SET_SYS [expr $EMIF_BASE_ADDR + 0x00b4] -set EMIF_IRQENABLE_CLR_SYS [expr $EMIF_BASE_ADDR + 0x00bc] -set EMIF_ZQ_CONFIG [expr $EMIF_BASE_ADDR + 0x00c8] -set EMIF_TEMP_ALERT_CONFIG [expr $EMIF_BASE_ADDR + 0x00cc] -set EMIF_OCP_ERR_LOG [expr $EMIF_BASE_ADDR + 0x00d0] -set EMIF_RDWR_LVL_RMP_WIN [expr $EMIF_BASE_ADDR + 0x00d4] -set EMIF_RDWR_LVL_RMP_CTRL [expr $EMIF_BASE_ADDR + 0x00d8] -set EMIF_RDWR_LVL_CTRL [expr $EMIF_BASE_ADDR + 0x00dc] -set EMIF_DDR_PHY_CTRL_1 [expr $EMIF_BASE_ADDR + 0x00e4] -set EMIF_DDR_PHY_CTRL_1_SHDW [expr $EMIF_BASE_ADDR + 0x00e8] -set EMIF_DDR_PHY_CTRL_2 [expr $EMIF_BASE_ADDR + 0x00ec] -set EMIF_PRI_COS_MAP [expr $EMIF_BASE_ADDR + 0x0100] -set EMIF_CONNID_COS_1_MAP [expr $EMIF_BASE_ADDR + 0x0104] -set EMIF_CONNID_COS_2_MAP [expr $EMIF_BASE_ADDR + 0x0108] -set ECC_CTRL [expr $EMIF_BASE_ADDR + 0x0110] -set ECC_ADDR_RNG_1 [expr $EMIF_BASE_ADDR + 0x0114] -set ECC_ADDR_RNG_2 [expr $EMIF_BASE_ADDR + 0x0118] -set EMIF_RD_WR_EXEC_THRSH [expr $EMIF_BASE_ADDR + 0x0120] -set COS_CONFIG [expr $EMIF_BASE_ADDR + 0x0124] - -set PHY_STATUS_1 [expr $EMIF_BASE_ADDR + 0x0144] -set PHY_STATUS_2 [expr $EMIF_BASE_ADDR + 0x0148] -set PHY_STATUS_3 [expr $EMIF_BASE_ADDR + 0x014c] -set PHY_STATUS_4 [expr $EMIF_BASE_ADDR + 0x0150] -set PHY_STATUS_5 [expr $EMIF_BASE_ADDR + 0x0154] -set PHY_STATUS_6 [expr $EMIF_BASE_ADDR + 0x0158] -set PHY_STATUS_7 [expr $EMIF_BASE_ADDR + 0x015c] -set PHY_STATUS_8 [expr $EMIF_BASE_ADDR + 0x0160] -set PHY_STATUS_9 [expr $EMIF_BASE_ADDR + 0x0164] -set PHY_STATUS_10 [expr $EMIF_BASE_ADDR + 0x0168] -set PHY_STATUS_11 [expr $EMIF_BASE_ADDR + 0x016c] -set PHY_STATUS_12 [expr $EMIF_BASE_ADDR + 0x0170] -set PHY_STATUS_13 [expr $EMIF_BASE_ADDR + 0x0174] -set PHY_STATUS_14 [expr $EMIF_BASE_ADDR + 0x0178] -set PHY_STATUS_15 [expr $EMIF_BASE_ADDR + 0x017c] -set PHY_STATUS_16 [expr $EMIF_BASE_ADDR + 0x0180] -set PHY_STATUS_17 [expr $EMIF_BASE_ADDR + 0x0184] -set PHY_STATUS_18 [expr $EMIF_BASE_ADDR + 0x0188] -set PHY_STATUS_19 [expr $EMIF_BASE_ADDR + 0x018c] -set PHY_STATUS_20 [expr $EMIF_BASE_ADDR + 0x0190] -set PHY_STATUS_21 [expr $EMIF_BASE_ADDR + 0x0194] -set PHY_STATUS_22 [expr $EMIF_BASE_ADDR + 0x0198] -set PHY_STATUS_23 [expr $EMIF_BASE_ADDR + 0x019c] -set PHY_STATUS_24 [expr $EMIF_BASE_ADDR + 0x01a0] -set PHY_STATUS_25 [expr $EMIF_BASE_ADDR + 0x01a4] -set PHY_STATUS_26 [expr $EMIF_BASE_ADDR + 0x01a8] -set PHY_STATUS_27 [expr $EMIF_BASE_ADDR + 0x01ac] -set PHY_STATUS_28 [expr $EMIF_BASE_ADDR + 0x01b0] - -set EXT_PHY_CTRL_1 [expr $EMIF_BASE_ADDR + 0x0200] -set EXT_PHY_CTRL_1_SHDW [expr $EMIF_BASE_ADDR + 0x0204] -set EXT_PHY_CTRL_2 [expr $EMIF_BASE_ADDR + 0x0208] -set EXT_PHY_CTRL_2_SHDW [expr $EMIF_BASE_ADDR + 0x020c] -set EXT_PHY_CTRL_3 [expr $EMIF_BASE_ADDR + 0x0210] -set EXT_PHY_CTRL_3_SHDW [expr $EMIF_BASE_ADDR + 0x0214] -set EXT_PHY_CTRL_4 [expr $EMIF_BASE_ADDR + 0x0218] -set EXT_PHY_CTRL_4_SHDW [expr $EMIF_BASE_ADDR + 0x021c] -set EXT_PHY_CTRL_5 [expr $EMIF_BASE_ADDR + 0x0220] -set EXT_PHY_CTRL_5_SHDW [expr $EMIF_BASE_ADDR + 0x0224] -set EXT_PHY_CTRL_6 [expr $EMIF_BASE_ADDR + 0x0228] -set EXT_PHY_CTRL_6_SHDW [expr $EMIF_BASE_ADDR + 0x022c] -set EXT_PHY_CTRL_7 [expr $EMIF_BASE_ADDR + 0x0230] -set EXT_PHY_CTRL_7_SHDW [expr $EMIF_BASE_ADDR + 0x0234] -set EXT_PHY_CTRL_8 [expr $EMIF_BASE_ADDR + 0x0238] -set EXT_PHY_CTRL_8_SHDW [expr $EMIF_BASE_ADDR + 0x023c] -set EXT_PHY_CTRL_9 [expr $EMIF_BASE_ADDR + 0x0240] -set EXT_PHY_CTRL_9_SHDW [expr $EMIF_BASE_ADDR + 0x0244] -set EXT_PHY_CTRL_10 [expr $EMIF_BASE_ADDR + 0x0248] -set EXT_PHY_CTRL_10_SHDW [expr $EMIF_BASE_ADDR + 0x024c] -set EXT_PHY_CTRL_11 [expr $EMIF_BASE_ADDR + 0x0250] -set EXT_PHY_CTRL_11_SHDW [expr $EMIF_BASE_ADDR + 0x0254] -set EXT_PHY_CTRL_12 [expr $EMIF_BASE_ADDR + 0x0258] -set EXT_PHY_CTRL_12_SHDW [expr $EMIF_BASE_ADDR + 0x025c] -set EXT_PHY_CTRL_13 [expr $EMIF_BASE_ADDR + 0x0260] -set EXT_PHY_CTRL_13_SHDW [expr $EMIF_BASE_ADDR + 0x0264] -set EXT_PHY_CTRL_14 [expr $EMIF_BASE_ADDR + 0x0268] -set EXT_PHY_CTRL_14_SHDW [expr $EMIF_BASE_ADDR + 0x026c] -set EXT_PHY_CTRL_15 [expr $EMIF_BASE_ADDR + 0x0270] -set EXT_PHY_CTRL_15_SHDW [expr $EMIF_BASE_ADDR + 0x0274] -set EXT_PHY_CTRL_16 [expr $EMIF_BASE_ADDR + 0x0278] -set EXT_PHY_CTRL_16_SHDW [expr $EMIF_BASE_ADDR + 0x027c] -set EXT_PHY_CTRL_17 [expr $EMIF_BASE_ADDR + 0x0280] -set EXT_PHY_CTRL_17_SHDW [expr $EMIF_BASE_ADDR + 0x0284] -set EXT_PHY_CTRL_18 [expr $EMIF_BASE_ADDR + 0x0288] -set EXT_PHY_CTRL_18_SHDW [expr $EMIF_BASE_ADDR + 0x028c] -set EXT_PHY_CTRL_19 [expr $EMIF_BASE_ADDR + 0x0290] -set EXT_PHY_CTRL_19_SHDW [expr $EMIF_BASE_ADDR + 0x0294] -set EXT_PHY_CTRL_20 [expr $EMIF_BASE_ADDR + 0x0298] -set EXT_PHY_CTRL_20_SHDW [expr $EMIF_BASE_ADDR + 0x029c] -set EXT_PHY_CTRL_21 [expr $EMIF_BASE_ADDR + 0x02a0] -set EXT_PHY_CTRL_21_SHDW [expr $EMIF_BASE_ADDR + 0x02a4] -set EXT_PHY_CTRL_22 [expr $EMIF_BASE_ADDR + 0x02a8] -set EXT_PHY_CTRL_22_SHDW [expr $EMIF_BASE_ADDR + 0x02ac] -set EXT_PHY_CTRL_23 [expr $EMIF_BASE_ADDR + 0x02b0] -set EXT_PHY_CTRL_23_SHDW [expr $EMIF_BASE_ADDR + 0x02b4] -set EXT_PHY_CTRL_24 [expr $EMIF_BASE_ADDR + 0x02b8] -set EXT_PHY_CTRL_24_SHDW [expr $EMIF_BASE_ADDR + 0x02bc] -set EXT_PHY_CTRL_25 [expr $EMIF_BASE_ADDR + 0x02c0] -set EXT_PHY_CTRL_25_SHDW [expr $EMIF_BASE_ADDR + 0x02c4] -set EXT_PHY_CTRL_26 [expr $EMIF_BASE_ADDR + 0x02c8] -set EXT_PHY_CTRL_26_SHDW [expr $EMIF_BASE_ADDR + 0x02cc] -set EXT_PHY_CTRL_27 [expr $EMIF_BASE_ADDR + 0x02d0] -set EXT_PHY_CTRL_27_SHDW [expr $EMIF_BASE_ADDR + 0x02d4] -set EXT_PHY_CTRL_28 [expr $EMIF_BASE_ADDR + 0x02d8] -set EXT_PHY_CTRL_28_SHDW [expr $EMIF_BASE_ADDR + 0x02dc] -set EXT_PHY_CTRL_29 [expr $EMIF_BASE_ADDR + 0x02e0] -set EXT_PHY_CTRL_29_SHDW [expr $EMIF_BASE_ADDR + 0x02e4] -set EXT_PHY_CTRL_30 [expr $EMIF_BASE_ADDR + 0x02e8] -set EXT_PHY_CTRL_30_SHDW [expr $EMIF_BASE_ADDR + 0x02ec] -set EXT_PHY_CTRL_31 [expr $EMIF_BASE_ADDR + 0x02f0] -set EXT_PHY_CTRL_31_SHDW [expr $EMIF_BASE_ADDR + 0x02f4] -set EXT_PHY_CTRL_32 [expr $EMIF_BASE_ADDR + 0x02f8] -set EXT_PHY_CTRL_32_SHDW [expr $EMIF_BASE_ADDR + 0x02fc] -set EXT_PHY_CTRL_33 [expr $EMIF_BASE_ADDR + 0x0300] -set EXT_PHY_CTRL_33_SHDW [expr $EMIF_BASE_ADDR + 0x0304] -set EXT_PHY_CTRL_34 [expr $EMIF_BASE_ADDR + 0x0308] -set EXT_PHY_CTRL_34_SHDW [expr $EMIF_BASE_ADDR + 0x030c] -set EXT_PHY_CTRL_35 [expr $EMIF_BASE_ADDR + 0x0310] -set EXT_PHY_CTRL_35_SHDW [expr $EMIF_BASE_ADDR + 0x0314] -set EXT_PHY_CTRL_36 [expr $EMIF_BASE_ADDR + 0x0318] -set EXT_PHY_CTRL_36_SHDW [expr $EMIF_BASE_ADDR + 0x031c] - -set WDT1_BASE_ADDR 0x44e35000 -set WDT1_W_PEND_WSPR [expr $WDT1_BASE_ADDR + 0x0034] -set WDT1_WSPR [expr $WDT1_BASE_ADDR + 0x0048] - -set RTC_BASE_ADDR 0x44e3e000 -set RTC_KICK0R [expr $RTC_BASE_ADDR + 0x6c] -set RTC_KICK1R [expr $RTC_BASE_ADDR + 0x70] - - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME am437x -} - -set JRC_MODULE icepick_d -set DEBUGSS_MODULE debugss -set M3_MODULE m3_wakeupss - -set JRC_NAME $_CHIPNAME.$JRC_MODULE -set DEBUGSS_NAME $_CHIPNAME.$DEBUGSS_MODULE -set M3_NAME $_CHIPNAME.$M3_MODULE -set _TARGETNAME $_CHIPNAME.mpuss - -# -# M3 WakeupSS DAP -# -if { [info exists M3_DAP_TAPID] } { - set _M3_DAP_TAPID $M3_DAP_TAPID -} else { - set _M3_DAP_TAPID 0x4b6b902f -} -jtag newtap $_CHIPNAME $M3_MODULE -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_M3_DAP_TAPID -disable -jtag configure $M3_NAME -event tap-enable "icepick_d_tapenable $JRC_NAME 11 0" - -# -# DebugSS DAP -# -if { [info exists DAP_TAPID] } { - set _DAP_TAPID $DAP_TAPID -} else { - set _DAP_TAPID 0x46b6902f -} -jtag newtap $_CHIPNAME $DEBUGSS_MODULE -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_DAP_TAPID -disable -jtag configure $DEBUGSS_NAME -event tap-enable "icepick_d_tapenable $JRC_NAME 12 0" - -# -# ICEpick-D (JTAG route controller) -# -if { [info exists JRC_TAPID] } { - set _JRC_TAPID $JRC_TAPID -} else { - set _JRC_TAPID 0x0b98c02f -} -jtag newtap $_CHIPNAME $JRC_MODULE -irlen 6 -ircapture 0x1 -irmask 0x3f -expected-id $_JRC_TAPID -ignore-version -jtag configure $JRC_NAME -event setup "jtag tapenable $DEBUGSS_NAME" - # some TCK tycles are required to activate the DEBUG power domain -jtag configure $JRC_NAME -event post-reset "runtest 100" - -# -# Cortex-A9 target -# -target create $_TARGETNAME cortex_a -chain-position $DEBUGSS_NAME -coreid 0 -dbgbase 0x80000000 - - -# SRAM: 256K at 0x4030.0000 -$_TARGETNAME configure -work-area-phys 0x40300000 -work-area-size 0x40000 - -# Disables watchdog timer after reset otherwise board won't stay in -# halted state. -proc disable_watchdog { } { - global WDT1_WSPR - global WDT1_W_PEND_WSPR - global _TARGETNAME - - set curstate [$_TARGETNAME curstate] - - if { [string compare $curstate halted] == 0 } { - set WDT_DISABLE_SEQ1 0xaaaa - set WDT_DISABLE_SEQ2 0x5555 - - mww phys $WDT1_WSPR $WDT_DISABLE_SEQ1 - - # Empty body to make sure this executes as fast as possible. - # We don't want any delays here otherwise romcode might start - # executing and end up changing state of certain IPs. - while { [expr [mrw $WDT1_W_PEND_WSPR] & 0x10] } { } - - mww phys $WDT1_WSPR $WDT_DISABLE_SEQ2 - while { [expr [mrw $WDT1_W_PEND_WSPR] & 0x10] } { } - } -} - -proc ceil { x y } { - return [ expr ($x + $y - 1) / $y ] -} - -proc device_type { } { - global CONTROL_STATUS - - set tmp [ mrw $CONTROL_STATUS ] - set tmp [ expr $tmp & 0x700 ] - set tmp [ expr $tmp >> 8 ] - - return $tmp -} - -proc get_input_clock_frequency { } { - global CONTROL_STATUS - - if { [ device_type ] != 3 } { - error "Unknown device type\n" - return -1 - } - - set freq [ mrw $CONTROL_STATUS ] - set freq [ expr $freq & 0x00c00000 ] - set freq [ expr $freq >> 22 ] - - switch $freq { - 0 { - set CLKIN 19200000 - } - - 1 { - set CLKIN 24000000 - } - - 2 { - set CLKIN 25000000 - } - - 3 { - set CLKIN 26000000 - } - } - - return $CLKIN -} - -proc mpu_pll_config { CLKIN N M M2 } { - global CM_CLKMODE_DPLL_MPU - global CM_CLKSEL_DPLL_MPU - global CM_DIV_M2_DPLL_MPU - global CM_IDLEST_DPLL_MPU - - set clksel [ mrw $CM_CLKSEL_DPLL_MPU ] - set div_m2 [ mrw $CM_DIV_M2_DPLL_MPU ] - - mww $CM_CLKMODE_DPLL_MPU 0x4 - while { !([ mrw $CM_IDLEST_DPLL_MPU ] & 0x0100) } { } - - set clksel [ expr $clksel & (~0x7ffff) ] - set clksel [ expr $clksel | ($M << 0x8) | $N ] - mww $CM_CLKSEL_DPLL_MPU $clksel - - set div_m2 [ expr $div_m2 & (~0x1f) ] - set div_m2 [ expr $div_m2 | $M2 ] - mww $CM_DIV_M2_DPLL_MPU $div_m2 - - mww $CM_CLKMODE_DPLL_MPU 0x7 - while { [ mrw $CM_IDLEST_DPLL_MPU ] != 1 } { } - - echo "MPU DPLL locked" -} - -proc core_pll_config { CLKIN N M M4 M5 M6 } { - global CM_CLKMODE_DPLL_CORE - global CM_CLKSEL_DPLL_CORE - global CM_DIV_M4_DPLL_CORE - global CM_DIV_M5_DPLL_CORE - global CM_DIV_M6_DPLL_CORE - global CM_IDLEST_DPLL_CORE - - set clksel [ mrw $CM_CLKSEL_DPLL_CORE ] - - mww $CM_CLKMODE_DPLL_CORE 0x4 - while { !([ mrw $CM_IDLEST_DPLL_CORE ] & 0x0100) } { } - - set clksel [ expr $clksel & (~0x7ffff) ] - set clksel [ expr $clksel | ($M << 0x8) | $N ] - mww $CM_CLKSEL_DPLL_CORE $clksel - mww $CM_DIV_M4_DPLL_CORE $M4 - mww $CM_DIV_M5_DPLL_CORE $M5 - mww $CM_DIV_M6_DPLL_CORE $M6 - - mww $CM_CLKMODE_DPLL_CORE 0x7 - while { !([ mrw $CM_IDLEST_DPLL_CORE ] & 0x01) } { } - - echo "CORE DPLL locked" -} - -proc per_pll_config { CLKIN N M M2 } { - global CM_CLKMODE_DPLL_PER - global CM_CLKSEL_DPLL_PER - global CM_DIV_M2_DPLL_PER - global CM_IDLEST_DPLL_PER - - set x [ expr $M * $CLKIN / 1000000 ] - set y [ expr ($N + 1) * 250 ] - set sd [ ceil $x $y ] - - set clksel [ mrw $CM_CLKSEL_DPLL_PER ] - set div_m2 [ mrw $CM_DIV_M2_DPLL_PER ] - - mww $CM_CLKMODE_DPLL_PER 0x4 - while { !([ mrw $CM_IDLEST_DPLL_PER ] & 0x0100) } { } - - set clksel [ expr $clksel & (~0xff0fffff) ] - set clksel [ expr $clksel | ($M << 0x8) | $N ] - set clksel [ expr $clksel | ($sd << 24) ] - mww $CM_CLKSEL_DPLL_PER $clksel - - set div_m2 [ expr 0xffffff80 | $M2 ] - - mww $CM_CLKMODE_DPLL_PER 0x7 - while { !([ mrw $CM_IDLEST_DPLL_PER ] & 0x01) } { } - - echo "PER DPLL locked" -} - -proc ddr_pll_config { CLKIN N M M2 M4 } { - global CM_CLKMODE_DPLL_DDR - global CM_CLKSEL_DPLL_DDR - global CM_DIV_M2_DPLL_DDR - global CM_DIV_M4_DPLL_DDR - global CM_IDLEST_DPLL_DDR - - set clksel [ mrw $CM_CLKSEL_DPLL_DDR ] - set div_m2 [ mrw $CM_DIV_M2_DPLL_DDR ] - - mww $CM_CLKMODE_DPLL_DDR 0x4 - while { !([ mrw $CM_IDLEST_DPLL_DDR ] & 0x0100) } { } - - set clksel [ expr $clksel & (~0x7ffff) ] - set clksel [ expr $clksel | ($M << 8) | $N ] - mww $CM_CLKSEL_DPLL_DDR $clksel - - set div_m2 [ expr ($div_m2 & 0xffffffe0) | $M2 ] - mww $CM_DIV_M2_DPLL_DDR $div_m2 - mww $CM_DIV_M4_DPLL_DDR $M4 - - mww $CM_CLKMODE_DPLL_DDR 0x7 - while { !([ mrw $CM_IDLEST_DPLL_DDR ] & 0x01) } { } - - echo "DDR DPLL Locked" -} - -proc config_opp100 { } { - set CLKIN [ get_input_clock_frequency ] - - if { $CLKIN == -1 } { - return -1 - } - - switch $CLKIN { - 24000000 { - mpu_pll_config $CLKIN 0 25 1 - core_pll_config $CLKIN 2 125 10 8 4 - per_pll_config $CLKIN 9 400 5 - ddr_pll_config $CLKIN 2 50 1 2 - } - - 25000000 { - mpu_pll_config $CLKIN 0 24 1 - core_pll_config $CLKIN 0 40 10 8 4 - per_pll_config $CLKIN 9 384 5 - ddr_pll_config $CLKIN 0 16 1 2 - } - - 26000000 { - mpu_pll_config $CLKIN 12 300 1 - core_pll_config $CLKIN 12 500 10 8 4 - per_pll_config $CLKIN 12 480 5 - ddr_pll_config $CLKIN 12 200 1 2 - } - - 19200000 { - mpu_pll_config $CLKIN 3 125 1 - core_pll_config $CLKIN 11 625 10 8 4 - per_pll_config $CLKIN 7 400 5 - ddr_pll_config $CLKIN 2 125 1 2 - } - } -} - -proc emif_prcm_clk_enable { } { - global CM_PER_EMIF_FW_CLKCTRL - global CM_PER_EMIF_CLKCTRL - - mww $CM_PER_EMIF_FW_CLKCTRL 0x02 - mww $CM_PER_EMIF_CLKCTRL 0x02 - - while { [ mrw $CM_PER_EMIF_CLKCTRL ] != 0x02 } { } -} - -proc vtp_enable { } { - global VTP_CTRL_REG - - set vtp [ expr [ mrw $VTP_CTRL_REG ] | 0x40 ] - mww $VTP_CTRL_REG $vtp - - set vtp [ expr [ mrw $VTP_CTRL_REG ] & ~0x01 ] - mww $VTP_CTRL_REG $vtp - - set vtp [ expr [ mrw $VTP_CTRL_REG ] | 0x01 ] - mww $VTP_CTRL_REG $vtp - -} - -proc config_ddr_ioctrl { } { - global DDR_ADDRCTRL_IOCTRL - global DDR_ADDRCTRL_WD0_IOCTRL - global DDR_ADDRCTRL_WD1_IOCTRL - global DDR_CKE_CTRL - global DDR_DATA0_IOCTRL - global DDR_DATA1_IOCTRL - global DDR_DATA2_IOCTRL - global DDR_DATA3_IOCTRL - global DDR_IO_CTRL - - mww $DDR_ADDRCTRL_IOCTRL 0x84 - mww $DDR_ADDRCTRL_WD0_IOCTRL 0x00 - mww $DDR_ADDRCTRL_WD1_IOCTRL 0x00 - mww $DDR_DATA0_IOCTRL 0x84 - mww $DDR_DATA1_IOCTRL 0x84 - mww $DDR_DATA2_IOCTRL 0x84 - mww $DDR_DATA3_IOCTRL 0x84 - - mww $DDR_IO_CTRL 0x00 - mww $DDR_CKE_CTRL 0x03 -} - -proc config_ddr_phy { } { - global EMIF_DDR_PHY_CTRL_1 - global EMIF_DDR_PHY_CTRL_1_SHDW - - global EXT_PHY_CTRL_1 - global EXT_PHY_CTRL_1_SHDW - global EXT_PHY_CTRL_2 - global EXT_PHY_CTRL_2_SHDW - global EXT_PHY_CTRL_3 - global EXT_PHY_CTRL_3_SHDW - global EXT_PHY_CTRL_4 - global EXT_PHY_CTRL_4_SHDW - global EXT_PHY_CTRL_5 - global EXT_PHY_CTRL_5_SHDW - global EXT_PHY_CTRL_6 - global EXT_PHY_CTRL_6_SHDW - global EXT_PHY_CTRL_7 - global EXT_PHY_CTRL_7_SHDW - global EXT_PHY_CTRL_8 - global EXT_PHY_CTRL_8_SHDW - global EXT_PHY_CTRL_9 - global EXT_PHY_CTRL_9_SHDW - global EXT_PHY_CTRL_10 - global EXT_PHY_CTRL_10_SHDW - global EXT_PHY_CTRL_11 - global EXT_PHY_CTRL_11_SHDW - global EXT_PHY_CTRL_12 - global EXT_PHY_CTRL_12_SHDW - global EXT_PHY_CTRL_13 - global EXT_PHY_CTRL_13_SHDW - global EXT_PHY_CTRL_14 - global EXT_PHY_CTRL_14_SHDW - global EXT_PHY_CTRL_15 - global EXT_PHY_CTRL_15_SHDW - global EXT_PHY_CTRL_16 - global EXT_PHY_CTRL_16_SHDW - global EXT_PHY_CTRL_17 - global EXT_PHY_CTRL_17_SHDW - global EXT_PHY_CTRL_18 - global EXT_PHY_CTRL_18_SHDW - global EXT_PHY_CTRL_19 - global EXT_PHY_CTRL_19_SHDW - global EXT_PHY_CTRL_20 - global EXT_PHY_CTRL_20_SHDW - global EXT_PHY_CTRL_21 - global EXT_PHY_CTRL_21_SHDW - global EXT_PHY_CTRL_22 - global EXT_PHY_CTRL_22_SHDW - global EXT_PHY_CTRL_23 - global EXT_PHY_CTRL_23_SHDW - global EXT_PHY_CTRL_24 - global EXT_PHY_CTRL_24_SHDW - global EXT_PHY_CTRL_25 - global EXT_PHY_CTRL_25_SHDW - global EXT_PHY_CTRL_26 - global EXT_PHY_CTRL_26_SHDW - global EXT_PHY_CTRL_27 - global EXT_PHY_CTRL_27_SHDW - global EXT_PHY_CTRL_28 - global EXT_PHY_CTRL_28_SHDW - global EXT_PHY_CTRL_29 - global EXT_PHY_CTRL_29_SHDW - global EXT_PHY_CTRL_30 - global EXT_PHY_CTRL_30_SHDW - global EXT_PHY_CTRL_31 - global EXT_PHY_CTRL_31_SHDW - global EXT_PHY_CTRL_32 - global EXT_PHY_CTRL_32_SHDW - global EXT_PHY_CTRL_33 - global EXT_PHY_CTRL_33_SHDW - global EXT_PHY_CTRL_34 - global EXT_PHY_CTRL_34_SHDW - global EXT_PHY_CTRL_35 - global EXT_PHY_CTRL_35_SHDW - global EXT_PHY_CTRL_36 - global EXT_PHY_CTRL_36_SHDW - - mww $EMIF_DDR_PHY_CTRL_1 0x8009 - mww $EMIF_DDR_PHY_CTRL_1_SHDW 0x8009 - - set slave_ratio 0x80 - set gatelvl_init_ratio 0x20 - set wr_dqs_slave_delay 0x60 - set rd_dqs_slave_delay 0x60 - set dq_offset 0x40 - set gatelvl_init_mode 0x01 - set wr_data_slave_delay 0x80 - set gatelvl_num_dq0 0x0f - set wrlvl_num_dq0 0x0f - - mww $EXT_PHY_CTRL_1 [ expr ($slave_ratio << 20) | ($slave_ratio << 10) | $slave_ratio ] - mww $EXT_PHY_CTRL_1_SHDW [ expr ($slave_ratio << 20) | ($slave_ratio << 10) | $slave_ratio ] - mww $EXT_PHY_CTRL_26 [ expr ($gatelvl_init_ratio << 16) | $gatelvl_init_ratio ] - mww $EXT_PHY_CTRL_26_SHDW [ expr ($gatelvl_init_ratio << 16) | $gatelvl_init_ratio ] - mww $EXT_PHY_CTRL_27 [ expr ($gatelvl_init_ratio << 16) | $gatelvl_init_ratio ] - mww $EXT_PHY_CTRL_27_SHDW [ expr ($gatelvl_init_ratio << 16) | $gatelvl_init_ratio ] - mww $EXT_PHY_CTRL_28 [ expr ($gatelvl_init_ratio << 16) | $gatelvl_init_ratio ] - mww $EXT_PHY_CTRL_28_SHDW [ expr ($gatelvl_init_ratio << 16) | $gatelvl_init_ratio ] - mww $EXT_PHY_CTRL_29 [ expr ($gatelvl_init_ratio << 16) | $gatelvl_init_ratio ] - mww $EXT_PHY_CTRL_29_SHDW [ expr ($gatelvl_init_ratio << 16) | $gatelvl_init_ratio ] - mww $EXT_PHY_CTRL_30 [ expr ($gatelvl_init_ratio << 16) | $gatelvl_init_ratio ] - mww $EXT_PHY_CTRL_30_SHDW [ expr ($gatelvl_init_ratio << 16) | $gatelvl_init_ratio ] - mww $EXT_PHY_CTRL_31 0x00 - mww $EXT_PHY_CTRL_31_SHDW 0x00 - mww $EXT_PHY_CTRL_32 0x00 - mww $EXT_PHY_CTRL_32_SHDW 0x00 - mww $EXT_PHY_CTRL_33 0x00 - mww $EXT_PHY_CTRL_33_SHDW 0x00 - mww $EXT_PHY_CTRL_34 0x00 - mww $EXT_PHY_CTRL_34_SHDW 0x00 - mww $EXT_PHY_CTRL_35 0x00 - mww $EXT_PHY_CTRL_35_SHDW 0x00 - mww $EXT_PHY_CTRL_22 0x00 - mww $EXT_PHY_CTRL_22_SHDW 0x00 - mww $EXT_PHY_CTRL_23 [ expr ($wr_dqs_slave_delay << 16) | $rd_dqs_slave_delay ] - mww $EXT_PHY_CTRL_23_SHDW [ expr ($wr_dqs_slave_delay << 16) | $rd_dqs_slave_delay ] - mww $EXT_PHY_CTRL_24 [ expr ($dq_offset << 24) | ($gatelvl_init_mode << 16) | $wr_data_slave_delay ] - mww $EXT_PHY_CTRL_24_SHDW [ expr ($dq_offset << 24) | ($gatelvl_init_mode << 16) | $wr_data_slave_delay << 0 ] - mww $EXT_PHY_CTRL_25 [ expr ($dq_offset << 21) | ($dq_offset << 14) | ($dq_offset << 7) | $dq_offset ] - mww $EXT_PHY_CTRL_25_SHDW [ expr ($dq_offset << 21) | ($dq_offset << 14) | ($dq_offset << 7) | $dq_offset ] - mww $EXT_PHY_CTRL_36 [ expr ($wrlvl_num_dq0 << 4) | $gatelvl_num_dq0 ] - mww $EXT_PHY_CTRL_36_SHDW [ expr ($wrlvl_num_dq0 << 4) | $gatelvl_num_dq0 ] -} - -proc config_ddr_timing { } { - global EMIF_SDRAM_TIM_1 - global EMIF_SDRAM_TIM_2 - global EMIF_SDRAM_TIM_3 - global EMIF_SDRAM_TIM_1_SHDW - global EMIF_SDRAM_TIM_2_SHDW - global EMIF_SDRAM_TIM_3_SHDW - global EMIF_ZQ_CONFIG - - mww $EMIF_SDRAM_TIM_1 0xeaaad4db - mww $EMIF_SDRAM_TIM_1_SHDW 0xeaaad4db - - mww $EMIF_SDRAM_TIM_2 0x266b7fda - mww $EMIF_SDRAM_TIM_2_SHDW 0x266b7fda - - mww $EMIF_SDRAM_TIM_3 0x107f8678 - mww $EMIF_SDRAM_TIM_3_SHDW 0x107f8678 - - mww $EMIF_ZQ_CONFIG 0x50074be4 -} - -proc config_ddr_pm { } { - global EMIF_PWR_MGMT_CTRL - global EMIF_PWR_MGMT_CTRL_SHDW - global EMIF_DLL_CALIB_CTRL - global EMIF_DLL_CALIB_CTRL_SHDW - global EMIF_TEMP_ALERT_CONFIG - - mww $EMIF_PWR_MGMT_CTRL 0x00 - mww $EMIF_PWR_MGMT_CTRL_SHDW 0x00 - mww $EMIF_DLL_CALIB_CTRL 0x00050000 - mww $EMIF_DLL_CALIB_CTRL_SHDW 0x00050000 - mww $EMIF_TEMP_ALERT_CONFIG 0x00 -} - -proc config_ddr_priority { } { - global EMIF_PRI_COS_MAP - global EMIF_CONNID_COS_1_MAP - global EMIF_CONNID_COS_2_MAP - global EMIF_RD_WR_EXEC_THRSH - global COS_CONFIG - - mww $EMIF_PRI_COS_MAP 0x00 - mww $EMIF_CONNID_COS_1_MAP 0x00 - mww $EMIF_CONNID_COS_2_MAP 0x0 - mww $EMIF_RD_WR_EXEC_THRSH 0x0405 - mww $COS_CONFIG 0x00ffffff -} - -proc config_ddr3 { SDRAM_CONFIG } { - global CM_DLL_CTRL - global EMIF_IODFT_TLGC - global EMIF_RDWR_LVL_CTRL - global EMIF_RDWR_LVL_RMP_CTRL - global EMIF_SDRAM_CONFIG - global EMIF_SDRAM_CONFIG_EXT - global EMIF_SDRAM_REF_CTRL - global EMIF_SDRAM_REF_CTRL_SHDW - global EMIF_STATUS - global EXT_PHY_CTRL_36 - global EXT_PHY_CTRL_36_SHDW - - emif_prcm_clk_enable - vtp_enable - - set dll [ expr [ mrw $CM_DLL_CTRL ] & ~0x01 ] - mww $CM_DLL_CTRL $dll - while { !([ mrw $CM_DLL_CTRL ] & 0x04) } { } - - config_ddr_ioctrl - - mww $EMIF_SDRAM_CONFIG_EXT 0xc163 - mww $EMIF_IODFT_TLGC 0x2011 - mww $EMIF_IODFT_TLGC 0x2411 - mww $EMIF_IODFT_TLGC 0x2011 - mww $EMIF_SDRAM_REF_CTRL 0x80003000 - - config_ddr_phy - - mww $EMIF_IODFT_TLGC 0x2011 - mww $EMIF_IODFT_TLGC 0x2411 - mww $EMIF_IODFT_TLGC 0x2011 - - config_ddr_timing - config_ddr_pm - config_ddr_priority - - mww $EMIF_SDRAM_REF_CTRL 0x3000 - mww $EMIF_SDRAM_CONFIG $SDRAM_CONFIG - - mww $EMIF_SDRAM_REF_CTRL 0x0c30 - mww $EMIF_SDRAM_REF_CTRL_SHDW 0x0c30 - - sleep 10 - - set tmp [ expr [ mrw $EXT_PHY_CTRL_36 ] | 0x0100 ] - mww $EXT_PHY_CTRL_36 $tmp - mww $EXT_PHY_CTRL_36_SHDW $tmp - - mww $EMIF_RDWR_LVL_RMP_CTRL 0x80000000 - mww $EMIF_RDWR_LVL_CTRL 0x80000000 - - while { [ mrw $EMIF_RDWR_LVL_CTRL ] & 0x80000000 } { } - - if { [ mrw $EMIF_STATUS ] & 0x70 } { - error "DDR3 Hardware Leveling incomplete!!!" - } -} - -proc init_platform { SDRAM_CONFIG } { - config_opp100 - config_ddr3 $SDRAM_CONFIG -} - -$_TARGETNAME configure -event reset-init { init_platform 0x61a013b2 } -$_TARGETNAME configure -event reset-end { disable_watchdog } diff --git a/tcl/target/amdm37x.cfg b/tcl/target/amdm37x.cfg deleted file mode 100644 index c00dae921..000000000 --- a/tcl/target/amdm37x.cfg +++ /dev/null @@ -1,211 +0,0 @@ -# -# Copyright (C) 2010-2011 by Karl Kurbjun -# Copyright (C) 2009-2011 by Øyvind Harboe -# Copyright (C) 2009 by David Brownell -# Copyright (C) 2009 by Magnus Lundin -# -# TI AM/DM37x Technical Reference Manual (Version R) -# http://www.ti.com/lit/ug/sprugn4r/sprugn4r.pdf -# -# This script is based on the AM3517 initialization. It should be considered -# preliminary since it needs more complete testing and only the basic -# operations work. -# - -############################################################################### -# User modifiable parameters -############################################################################### - -# This script uses the variable CHIPTYPE to determine whether this is an AM35x -# or DM37x target. If CHIPTYPE is not set it will error out. -if { [info exists CHIPTYPE] } { - - if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME - } else { - set _CHIPNAME $CHIPTYPE - } - - switch $CHIPTYPE { - dm37x { - # Primary TAP: ICEPick-C (JTAG route controller) and boundary scan - set _JRC_TAPID "-expected-id 0x2b89102f -expected-id 0x1b89102f -expected-id 0x0b89102f" - } - am35x { - # Primary TAP: ICEPick-C (JTAG route controller) and boundary scan - set _JRC_TAPID "-expected-id 0x0b7ae02f -expected-id 0x0b86802f" - } - default { - error "ERROR: CHIPTYPE was set, but it was not set to a valid value. Acceptable values are \"dm37x\" or \"am35x\"." - } - } -} else { - error "ERROR: CHIPTYPE was not defined. Please set CHIPTYPE to \"am35x\" for the AM35x or \"dm37x\" for the DM37x series in the board configuration." -} - -# Run the adapter at the fastest acceptable speed with the slowest possible -# core clock. -adapter_khz 10 - -############################################################################### -# JTAG setup -# The OpenOCD commands are described in the TAP Declaration section -# http://openocd.org/doc/html/TAP-Declaration.html -############################################################################### - -# The AM/DM37x has an ICEPick module in it like many of TI's other devices. More -# can be read about this module in sprugn4r in chapter 27: "Debug and -# Emulation". The module is used to route the JTAG chain to the various -# subsystems in the chip. -source [find target/icepick.cfg] - -# The TAP order should be described from the TDO connection in OpenOCD to the -# TDI pin. The OpenOCD FAQ describes this in more detail: -# http://openocd.org/doc/html/FAQ.html - -# From SPRUGN4R CH27 the available secondary TAPs are in this order from TDO: -# -# Device | TAP number -# ---------|------------ -# DAP | 3 -# Sequencer| 2 Note: The sequencer is an ARM968 -# DSP | 1 -# D2D | 0 -# -# Right now the only secondary tap enabled is the DAP so the rest are left -# undescribed. - -###### -# Start of Chain Description -# The Secondary TAPs all have enable functions defined for use with the ICEPick -# Only the DAP is enabled. The AM37xx does not have the Sequencer or DSP but -# the TAP numbers for ICEPick do not change. -# -# TODO: A disable function should also be added. -###### - -# Secondary TAP: DAP is closest to the TDO output -# The TAP enable event also needs to be described -jtag newtap $_CHIPNAME dap -irlen 4 -ircapture 0x1 -irmask 0xf -disable -jtag configure $_CHIPNAME.dap -event tap-enable \ - "icepick_c_tapenable $_CHIPNAME.jrc 3" - -# These taps are only present in the DM37x series. -if { $CHIPTYPE == "dm37x" } { - # Secondary TAP: Sequencer (ARM968) it is not in the chain by default - # The ICEPick can be used to enable it in the chain. - jtag newtap $_CHIPNAME arm2 -irlen 4 -ircapture 0x1 -irmask 0x0f -disable - jtag configure $_CHIPNAME.arm2 -event tap-enable \ - "icepick_c_tapenable $_CHIPNAME.jrc 2" - - # Secondary TAP: C64x+ DSP - it is not in the chain by default (-disable) - # The ICEPick can be used to enable it in the chain. - jtag newtap $_CHIPNAME dsp -irlen 38 -ircapture 0x25 -irmask 0x3f -disable - jtag configure $_CHIPNAME.dsp -event tap-enable \ - "icepick_c_tapenable $_CHIPNAME.jrc 1" -} - -# Secondary TAP: D2D it is not in the chain by default (-disable) -# The ICEPick can be used to enable it in the chain. -# This IRLEN is probably incorrect - not sure where the documentation is. -jtag newtap $_CHIPNAME d2d -irlen 4 -ircapture 0x1 -irmask 0x0f -disable -jtag configure $_CHIPNAME.d2d -event tap-enable \ - "icepick_c_tapenable $_CHIPNAME.jrc 0" - -# Primary TAP: ICEPick - it is closest to TDI so last in the chain -eval "jtag newtap $_CHIPNAME jrc -irlen 6 -ircapture 0x1 -irmask 0x3f $_JRC_TAPID" - -###### -# End of Chain Description -###### - -###### -# Start JTAG TAP events -###### - -# some TCK tycles are required to activate the DEBUG power domain -jtag configure $_CHIPNAME.jrc -event post-reset "runtest 100" - -# Enable the DAP TAP -jtag configure $_CHIPNAME.jrc -event setup "jtag tapenable $_CHIPNAME.dap" - -###### -# End JTAG TAP events -###### - -############################################################################### -# Target Setup: -# This section is described in the OpenOCD documentation under CPU Configuration -# http://openocd.org/doc/html/CPU-Configuration.html -############################################################################### - -# Create the CPU target to be used with GDB: Cortex-A8, using DAP -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME cortex_a -chain-position $_CHIPNAME.dap - -# The DM37x has 64K of SRAM starting at address 0x4020_0000. Allow the first -# 16K to be used as a scratchpad for OpenOCD. - -$_TARGETNAME configure -work-area-phys 0x40200000 -work-area-size 0x4000 - -###### -# Start Target Reset Event Setup: -###### - -# Set the JTAG clock down to 10 kHz to be sure that it will work with the -# slowest possible core clock (16.8MHz/2 = 8.4MHz). It is OK to speed up -# *after* PLL and clock tree setup. - -$_TARGETNAME configure -event "reset-start" { adapter_khz 10 } - -# Describe the reset assert process for openocd - this is asserted with the -# ICEPick -$_TARGETNAME configure -event "reset-assert" { - - global _CHIPNAME - - # assert warm system reset through ICEPick - icepick_c_wreset $_CHIPNAME.jrc -} - -# After the reset is asserted we need to re-initialize debugging and speed up -# the JTAG clock. - -$_TARGETNAME configure -event reset-assert-post { - - global _TARGETNAME - amdm37x_dbginit $_TARGETNAME - adapter_khz 1000 -} - -$_TARGETNAME configure -event gdb-attach { - - global _TARGETNAME - amdm37x_dbginit $_TARGETNAME - - echo "Halting target" - halt -} - -###### -# End Target Reset Event Setup: -###### - -############################################################################### -# Target Functions -# Add any functions needed for the target here -############################################################################### - -# Run this to enable invasive debugging. This is run automatically in the -# reset sequence. -proc amdm37x_dbginit {target} { - # General Cortex-A8 debug initialisation - cortex_a dbginit - - # Enable DBGEN signal. This signal is described in the ARM v7 TRM, but - # access to the signal appears to be implementation specific. TI does not - # describe this register much except a quick line that states DBGEM (sic) is - # at this address and this bit. - $target mww phys 0x5401d030 0x00002000 -} - diff --git a/tcl/target/ar71xx.cfg b/tcl/target/ar71xx.cfg deleted file mode 100644 index 196b04868..000000000 --- a/tcl/target/ar71xx.cfg +++ /dev/null @@ -1,57 +0,0 @@ -# Atheros AR71xx MIPS 24Kc SoC. -# tested on PB44 refererence board - -adapter_nsrst_delay 100 -jtag_ntrst_delay 100 - -reset_config trst_and_srst - -set CHIPNAME ar71xx - -jtag newtap $CHIPNAME cpu -irlen 5 -ircapture 0x1 -irmask 0x1f -expected-id 1 - -set _TARGETNAME $CHIPNAME.cpu -target create $_TARGETNAME mips_m4k -endian big -chain-position $_TARGETNAME - -$_TARGETNAME configure -event reset-halt-post { - #setup PLL to lowest common denominator 300/300/150 setting - mww 0xb8050000 0x000f40a3 ;# reset val + CPU:3 DDR:3 AHB:0 - mww 0xb8050000 0x800f40a3 ;# send to PLL - - #next command will reset for PLL changes to take effect - mww 0xb8050008 3 ;# set reset_switch and clock_switch (resets SoC) -} - -$_TARGETNAME configure -event reset-init { - #complete pll initialization - mww 0xb8050000 0x800f0080 ;# set sw_update bit - mww 0xb8050008 0 ;# clear reset_switch bit - mww 0xb8050000 0x800f00e8 ;# clr pwrdwn & bypass - mww 0xb8050008 1 ;# set clock_switch bit - sleep 1 ;# wait for lock - - # Setup DDR config and flash mapping - mww 0xb8000000 0xefbc8cd0 ;# DDR cfg cdl val (rst: 0x5bfc8d0) - mww 0xb8000004 0x8e7156a2 ;# DDR cfg2 cdl val (rst: 0x80d106a8) - - mww 0xb8000010 8 ;# force precharge all banks - mww 0xb8000010 1 ;# force EMRS update cycle - mww 0xb800000c 0 ;# clr ext. mode register - mww 0xb8000010 2 ;# force auto refresh all banks - mww 0xb8000010 8 ;# force precharge all banks - mww 0xb8000008 0x31 ;# set DDR mode value CAS=3 - mww 0xb8000010 1 ;# force EMRS update cycle - mww 0xb8000014 0x461b ;# DDR refresh value - mww 0xb8000018 0xffff ;# DDR Read Data This Cycle value (16bit: 0xffff) - mww 0xb800001c 0x7 ;# delay added to the DQS line (normal = 7) - mww 0xb8000020 0 - mww 0xb8000024 0 - mww 0xb8000028 0 -} - -# setup working area somewhere in RAM -$_TARGETNAME configure -work-area-phys 0xa0600000 -work-area-size 0x20000 - -# serial SPI capable flash -# flash bank - diff --git a/tcl/target/armada370.cfg b/tcl/target/armada370.cfg deleted file mode 100644 index 40c779bdc..000000000 --- a/tcl/target/armada370.cfg +++ /dev/null @@ -1,33 +0,0 @@ -# -# armada370 -- support for the Marvell Armada/370 CPU family -# -# gerg@uclinux.org, OCT-2013 -# - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME armada370 -} - -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - set _CPUTAPID 0x4ba00477 -} - -jtag newtap $_CHIPNAME dap -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID - -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME cortex_a -chain-position $_CHIPNAME.dap - -proc armada370_dbginit {target} { - cortex_a dbginit -} - -$_TARGETNAME configure -event reset-assert-post "armada370_dbginit $_TARGETNAME" - -# We need to init now, so we can run the apsel command. -init -dap apsel 1 - diff --git a/tcl/target/at32ap7000.cfg b/tcl/target/at32ap7000.cfg deleted file mode 100644 index 8573aa1c4..000000000 --- a/tcl/target/at32ap7000.cfg +++ /dev/null @@ -1,16 +0,0 @@ -# Atmel AT32AP7000 -# -# This is the only core in the now-inactive high end AVR32 product line, -# with MMU, Java Acceleration, and "pixel coprocessor". The AP7 line -# is for "Application Processors" (AP) with 7-stage pipelines. -# -# Most current AVR32 parts are in the UC3 flash based microcontroller (UC) -# product line with 3-stage pipelines and without those extras. -# -# All AVR32 parts provide the Nexus Class 3 on-chip debug interfaces -# through their JTAG interfaces. - -jtag newtap ap7 nexus -irlen 5 -expected-id 0x21e8203f - -# REVISIT declare an avr32 target ... needs OpenOCD infrastructure -# for both Nexus (generic) and AVR32 (Atmel-specific). diff --git a/tcl/target/at91r40008.cfg b/tcl/target/at91r40008.cfg deleted file mode 100644 index 912bd0ea2..000000000 --- a/tcl/target/at91r40008.cfg +++ /dev/null @@ -1,29 +0,0 @@ -# AT91R40008 target configuration file - -# TRST is tied to SRST on the AT91X40 family. -reset_config srst_only srst_pulls_trst - - -if {[info exists CHIPNAME]} { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME at91r40008 -} - -if { [info exists ENDIAN] } { - set _ENDIAN $ENDIAN -} else { - set _ENDIAN little -} - -# Setup the JTAG scan chain. -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - set _CPUTAPID 0x1f0f0f0f -} -jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID - -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME arm7tdmi -endian $_ENDIAN -chain-position $_TARGETNAME -$_TARGETNAME configure -work-area-phys 0x20000 -work-area-size 0x20000 -work-area-backup 0 diff --git a/tcl/target/at91rm9200.cfg b/tcl/target/at91rm9200.cfg deleted file mode 100644 index 2e8c1e091..000000000 --- a/tcl/target/at91rm9200.cfg +++ /dev/null @@ -1,47 +0,0 @@ -# Atmel AT91rm9200 -# http://atmel.com/products/at91/ - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME at91rm9200 -} - -if { [info exists ENDIAN] } { - set _ENDIAN $ENDIAN -} else { - set _ENDIAN little -} - -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - set _CPUTAPID 0x05b0203f -} - -# Never allow the following! -if { $_CPUTAPID == 0x15b0203f } { - echo "-------------------------------------------------------" - echo "- ERROR: -" - echo "- ERROR: TapID 0x15b0203f is wrong for at91rm9200 -" - echo "- ERROR: The chip/board has a JTAG select pin/jumper -" - echo "- ERROR: -" - echo "- ERROR: In one position (0x05b0203f) it selects the -" - echo "- ERROR: ARM CPU, in the other position (0x1b0203f) -" - echo "- ERROR: it selects boundry-scan not the ARM -" - echo "- ERROR: -" - echo "-------------------------------------------------------" -} - -jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID - -# Create the GDB Target. -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME arm920t -endian $_ENDIAN -chain-position $_TARGETNAME - -# AT91RM9200 has a 16K block of sram @ 0x0020.0000 -$_TARGETNAME configure -work-area-phys 0x00200000 \ - -work-area-size 0x4000 -work-area-backup 1 - -# This chip has a DCC ... use it -arm7_9 dcc_downloads enable diff --git a/tcl/target/at91sam3XXX.cfg b/tcl/target/at91sam3XXX.cfg deleted file mode 100644 index fca655d2c..000000000 --- a/tcl/target/at91sam3XXX.cfg +++ /dev/null @@ -1,87 +0,0 @@ -# script for ATMEL sam3, a Cortex-M3 chip -# -# at91sam3u4e -# at91sam3u2e -# at91sam3u1e -# at91sam3u4c -# at91sam3u2c -# at91sam3u1c -# -# at91sam3s4c -# at91sam3s4b -# at91sam3s4a -# at91sam3s2c -# at91sam3s2b -# at91sam3s2a -# at91sam3s1c -# at91sam3s1b -# at91sam3s1a -# -# at91sam3A4C -# at91sam3A8C -# at91sam3X4C -# at91sam3X4E -# at91sam3X8C -# at91sam3X8E -# at91sam3X8H - -source [find target/swj-dp.tcl] - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME sam3 -} - -if { [info exists ENDIAN] } { - set _ENDIAN $ENDIAN -} else { - set _ENDIAN little -} - -# Work-area is a space in RAM used for flash programming -# By default use 64kB -if { [info exists WORKAREASIZE] } { - set _WORKAREASIZE $WORKAREASIZE -} else { - set _WORKAREASIZE 0x4000 -} - -#jtag scan chain -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - set _CPUTAPID 0x4ba00477 -} - -swj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID - -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME cortex_m -endian $_ENDIAN -chain-position $_TARGETNAME - -# 16K is plenty, the smallest chip has this much -$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0 - -$_TARGETNAME configure -event gdb-flash-erase-start { - halt -} - -# JTAG speed should be <= F_CPU/6. F_CPU after reset is 4 MHz, so use F_JTAG = 0.5MHz -# -# Since we may be running of an RC oscilator, we crank down the speed a -# bit more to be on the safe side. Perhaps superstition, but if are -# running off a crystal, we can run closer to the limit. Note -# that there can be a pretty wide band where things are more or less stable. - -adapter_khz 500 - -adapter_nsrst_delay 100 -if {[using_jtag]} { - jtag_ntrst_delay 100 -} - -if {![using_hla]} { - # if srst is not fitted use SYSRESETREQ to - # perform a soft reset - cortex_m reset_config sysresetreq -} diff --git a/tcl/target/at91sam3ax_4x.cfg b/tcl/target/at91sam3ax_4x.cfg deleted file mode 100644 index 78ca79f69..000000000 --- a/tcl/target/at91sam3ax_4x.cfg +++ /dev/null @@ -1,9 +0,0 @@ -# common stuff -source [find target/at91sam3ax_xx.cfg] - -# size is automatically "calculated" by probing -set _FLASHNAME $_CHIPNAME.flash0 -flash bank $_FLASHNAME at91sam3 0x000080000 0 1 1 $_TARGETNAME -# This is a 256K chip - it has the 2nd bank -set _FLASHNAME $_CHIPNAME.flash1 -flash bank $_FLASHNAME at91sam3 0x0000A0000 0 1 1 $_TARGETNAME diff --git a/tcl/target/at91sam3ax_8x.cfg b/tcl/target/at91sam3ax_8x.cfg deleted file mode 100644 index e2493837d..000000000 --- a/tcl/target/at91sam3ax_8x.cfg +++ /dev/null @@ -1,11 +0,0 @@ -# common stuff -source [find target/at91sam3ax_xx.cfg] - -# size is automatically "calculated" by probing -set _FLASHNAME $_CHIPNAME.flash0 -flash bank $_FLASHNAME at91sam3 0x000080000 0 1 1 $_TARGETNAME -# This is a 512K chip - it has the 2nd bank -set _FLASHNAME $_CHIPNAME.flash1 -flash bank $_FLASHNAME at91sam3 0x0000C0000 0 1 1 $_TARGETNAME - - diff --git a/tcl/target/at91sam3ax_xx.cfg b/tcl/target/at91sam3ax_xx.cfg deleted file mode 100644 index e56177122..000000000 --- a/tcl/target/at91sam3ax_xx.cfg +++ /dev/null @@ -1,11 +0,0 @@ -# script for ATMEL sam3, a Cortex-M3 chip -# -# at91sam3A4C -# at91sam3A8C -# at91sam3X4C -# at91sam3X4E -# at91sam3X8C -# at91sam3X8E -# at91sam3X8H -source [find target/at91sam3XXX.cfg] - diff --git a/tcl/target/at91sam3nXX.cfg b/tcl/target/at91sam3nXX.cfg deleted file mode 100644 index 19bd33a9e..000000000 --- a/tcl/target/at91sam3nXX.cfg +++ /dev/null @@ -1,32 +0,0 @@ - -# -# Configuration for Atmel's SAM3N series -# - -source [find target/swj-dp.tcl] - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME at91sam3n -} - -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - set _CPUTAPID 0x4ba00477 -} - -swj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID - -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME cortex_m -endian little -chain-position $_TARGETNAME - -set _FLASHNAME $_CHIPNAME.flash -flash bank flash0 at91sam3 0x00400000 0 0 0 $_TARGETNAME - -if {![using_hla]} { - # if srst is not fitted use SYSRESETREQ to - # perform a soft reset - cortex_m reset_config sysresetreq -} diff --git a/tcl/target/at91sam3sXX.cfg b/tcl/target/at91sam3sXX.cfg deleted file mode 100644 index 09146bd0f..000000000 --- a/tcl/target/at91sam3sXX.cfg +++ /dev/null @@ -1,16 +0,0 @@ -# script for ATMEL sam3, a Cortex-M3 chip -# -# at91sam3s4c -# at91sam3s4b -# at91sam3s4a -# at91sam3s2c -# at91sam3s2b -# at91sam3s2a -# at91sam3s1c -# at91sam3s1b -# at91sam3s1a - -source [find target/at91sam3XXX.cfg] - -set _FLASHNAME $_CHIPNAME.flash -flash bank $_FLASHNAME at91sam3 0x00400000 0 1 1 $_TARGETNAME diff --git a/tcl/target/at91sam3u1c.cfg b/tcl/target/at91sam3u1c.cfg deleted file mode 100644 index 47c227b26..000000000 --- a/tcl/target/at91sam3u1c.cfg +++ /dev/null @@ -1,8 +0,0 @@ -# common stuff -source [find target/at91sam3uxx.cfg] - -# size is automatically "calculated" by probing -set _FLASHNAME $_CHIPNAME.flash -flash bank $_FLASHNAME at91sam3 0x000080000 0 1 1 $_TARGETNAME - - diff --git a/tcl/target/at91sam3u1e.cfg b/tcl/target/at91sam3u1e.cfg deleted file mode 100644 index 47c227b26..000000000 --- a/tcl/target/at91sam3u1e.cfg +++ /dev/null @@ -1,8 +0,0 @@ -# common stuff -source [find target/at91sam3uxx.cfg] - -# size is automatically "calculated" by probing -set _FLASHNAME $_CHIPNAME.flash -flash bank $_FLASHNAME at91sam3 0x000080000 0 1 1 $_TARGETNAME - - diff --git a/tcl/target/at91sam3u2c.cfg b/tcl/target/at91sam3u2c.cfg deleted file mode 100644 index 47c227b26..000000000 --- a/tcl/target/at91sam3u2c.cfg +++ /dev/null @@ -1,8 +0,0 @@ -# common stuff -source [find target/at91sam3uxx.cfg] - -# size is automatically "calculated" by probing -set _FLASHNAME $_CHIPNAME.flash -flash bank $_FLASHNAME at91sam3 0x000080000 0 1 1 $_TARGETNAME - - diff --git a/tcl/target/at91sam3u2e.cfg b/tcl/target/at91sam3u2e.cfg deleted file mode 100644 index 47c227b26..000000000 --- a/tcl/target/at91sam3u2e.cfg +++ /dev/null @@ -1,8 +0,0 @@ -# common stuff -source [find target/at91sam3uxx.cfg] - -# size is automatically "calculated" by probing -set _FLASHNAME $_CHIPNAME.flash -flash bank $_FLASHNAME at91sam3 0x000080000 0 1 1 $_TARGETNAME - - diff --git a/tcl/target/at91sam3u4c.cfg b/tcl/target/at91sam3u4c.cfg deleted file mode 100644 index 5cacbcbef..000000000 --- a/tcl/target/at91sam3u4c.cfg +++ /dev/null @@ -1,11 +0,0 @@ -# common stuff -source [find target/at91sam3uxx.cfg] - -# size is automatically "calculated" by probing -set _FLASHNAME $_CHIPNAME.flash0 -flash bank $_FLASHNAME at91sam3 0x000080000 0 1 1 $_TARGETNAME -# This is a 256K chip, it has the 2nd bank -set _FLASHNAME $_CHIPNAME.flash1 -flash bank $_FLASHNAME at91sam3 0x000100000 0 1 1 $_TARGETNAME - - diff --git a/tcl/target/at91sam3u4e.cfg b/tcl/target/at91sam3u4e.cfg deleted file mode 100644 index a48f99265..000000000 --- a/tcl/target/at91sam3u4e.cfg +++ /dev/null @@ -1,11 +0,0 @@ -# common stuff -source [find target/at91sam3uxx.cfg] - -# size is automatically "calculated" by probing -set _FLASHNAME $_CHIPNAME.flash0 -flash bank $_FLASHNAME at91sam3 0x000080000 0 1 1 $_TARGETNAME -# This is a 256K chip - it has the 2nd bank -set _FLASHNAME $_CHIPNAME.flash1 -flash bank $_FLASHNAME at91sam3 0x000100000 0 1 1 $_TARGETNAME - - diff --git a/tcl/target/at91sam3uxx.cfg b/tcl/target/at91sam3uxx.cfg deleted file mode 100644 index b42ae19cf..000000000 --- a/tcl/target/at91sam3uxx.cfg +++ /dev/null @@ -1,11 +0,0 @@ -# script for ATMEL sam3, a Cortex-M3 chip -# -# at91sam3u4e -# at91sam3u2e -# at91sam3u1e -# at91sam3u4c -# at91sam3u2c -# at91sam3u1c - -source [find target/at91sam3XXX.cfg] - diff --git a/tcl/target/at91sam4XXX.cfg b/tcl/target/at91sam4XXX.cfg deleted file mode 100644 index ca801431a..000000000 --- a/tcl/target/at91sam4XXX.cfg +++ /dev/null @@ -1,63 +0,0 @@ -# -# script for ATMEL sam4, a Cortex-M4 chip -# - -# -# sam4 devices can support both JTAG and SWD transports. -# -source [find target/swj-dp.tcl] - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME sam4 -} - -if { [info exists ENDIAN] } { - set _ENDIAN $ENDIAN -} else { - set _ENDIAN little -} - -# Work-area is a space in RAM used for flash programming -# By default use 64kB -if { [info exists WORKAREASIZE] } { - set _WORKAREASIZE $WORKAREASIZE -} else { - set _WORKAREASIZE 0x4000 -} - -#jtag scan chain -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - set _CPUTAPID 0x4ba00477 -} - -swj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID - -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME cortex_m -endian $_ENDIAN -chain-position $_TARGETNAME - -# 16K is plenty, the smallest chip has this much -$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0 - -# JTAG speed should be <= F_CPU/6. F_CPU after reset is 4 MHz, so use F_JTAG = 0.5MHz -# -# Since we may be running of an RC oscilator, we crank down the speed a -# bit more to be on the safe side. Perhaps superstition, but if are -# running off a crystal, we can run closer to the limit. Note -# that there can be a pretty wide band where things are more or less stable. - -adapter_khz 500 - -adapter_nsrst_delay 100 -if {[using_jtag]} { - jtag_ntrst_delay 100 -} - -if {![using_hla]} { - # if srst is not fitted use SYSRESETREQ to - # perform a soft reset - cortex_m reset_config sysresetreq -} diff --git a/tcl/target/at91sam4lXX.cfg b/tcl/target/at91sam4lXX.cfg deleted file mode 100644 index 4aee7d081..000000000 --- a/tcl/target/at91sam4lXX.cfg +++ /dev/null @@ -1,27 +0,0 @@ -# script for ATMEL sam4l, a Cortex-M4 chip -# - -source [find target/at91sam4XXX.cfg] - -set _FLASHNAME $_CHIPNAME.flash -flash bank $_FLASHNAME at91sam4l 0x00000000 0 1 1 $_TARGETNAME - -# SAM4L SMAP will hold the CPU in reset if TCK is low when RESET_N -# deasserts (see datasheet 42023E-SAM-07/2013 sec 8.11.3). -# -# smap_reset_deassert configures whether we want to run or halt out of reset, -# then instruct the SMAP to let us out of reset. -$_TARGETNAME configure -event reset-deassert-post "at91sam4l smap_reset_deassert" - -# SRST (wired to RESET_N) resets debug circuitry -# srst_pulls_trst is not configured here to avoid an error raised in reset halt -reset_config srst_gates_jtag - -# SAM4L starts from POR with SYSCLK set to 115kHz RCSYS, needs slow JTAG speed. -# Datasheet does not specify SYSCLK to JTAG/SWD clock ratio. -# Usually used SYSCLK/6 is hell slow, testing shows that debugging can work @ SYSCLK/2 -# but your mileage may vary. -adapter_khz 50 - -# System RC oscillator RCSYS starts in 3 cycles -adapter_nsrst_delay 0 diff --git a/tcl/target/at91sam4sXX.cfg b/tcl/target/at91sam4sXX.cfg deleted file mode 100644 index 8883e23ca..000000000 --- a/tcl/target/at91sam4sXX.cfg +++ /dev/null @@ -1,7 +0,0 @@ -# script for ATMEL sam4, a Cortex-M4 chip -# - -source [find target/at91sam4XXX.cfg] - -set _FLASHNAME $_CHIPNAME.flash -flash bank $_FLASHNAME at91sam4 0x00400000 0 1 1 $_TARGETNAME diff --git a/tcl/target/at91sam4sd32x.cfg b/tcl/target/at91sam4sd32x.cfg deleted file mode 100644 index 077b1f51f..000000000 --- a/tcl/target/at91sam4sd32x.cfg +++ /dev/null @@ -1,9 +0,0 @@ -# script for ATMEL sam4sd32, a Cortex-M4 chip -# - -source [find target/at91sam4XXX.cfg] - -set _FLASHNAME $_CHIPNAME.flash0 -flash bank $_FLASHNAME at91sam4 0x00400000 0 1 1 $_TARGETNAME -set _FLASHNAME $_CHIPNAME.flash1 -flash bank $_FLASHNAME at91sam4 0x00500000 0 1 1 $_TARGETNAME diff --git a/tcl/target/at91sam7a2.cfg b/tcl/target/at91sam7a2.cfg deleted file mode 100644 index f7a0de2d6..000000000 --- a/tcl/target/at91sam7a2.cfg +++ /dev/null @@ -1,23 +0,0 @@ - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME at91sam7a2 -} - -if { [info exists ENDIAN] } { - set _ENDIAN $ENDIAN -} else { - set _ENDIAN little -} - -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - set _CPUTAPID 0x1f0f0f0f -} - -jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID -set _TARGETNAME $_CHIPNAME.cpu - -target create $_TARGETNAME arm7tdmi -endian $_ENDIAN -chain-position $_TARGETNAME diff --git a/tcl/target/at91sam7se512.cfg b/tcl/target/at91sam7se512.cfg deleted file mode 100644 index ab0970128..000000000 --- a/tcl/target/at91sam7se512.cfg +++ /dev/null @@ -1,39 +0,0 @@ -# ATMEL sam7se512 -# Example: the "Elektor Internet Radio" - EIR -# http://www.ethernut.de/en/hardware/eir/index.html - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME sam7se512 -} - -if { [info exists ENDIAN] } { - set _ENDIAN $ENDIAN -} else { - set _ENDIAN little -} - -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - # Force an error until we get a good number. - set _CPUTAPID 0xffffffff -} - -#use combined on interfaces or targets that can't set TRST/SRST separately -reset_config srst_only srst_pulls_trst - -#jtag scan chain -jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID - -# The target -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME arm7tdmi -endian $_ENDIAN -chain-position $_TARGETNAME - -$_TARGETNAME configure -work-area-phys 0x00200000 -work-area-size 0x4000 -work-area-backup 0 - -#flash bank [ ] -set _FLASHNAME $_CHIPNAME.flash -flash bank $_FLASHNAME at91sam7 0 0 0 0 $_TARGETNAME 0 0 0 0 0 0 0 18432 - diff --git a/tcl/target/at91sam7sx.cfg b/tcl/target/at91sam7sx.cfg deleted file mode 100644 index a563ac037..000000000 --- a/tcl/target/at91sam7sx.cfg +++ /dev/null @@ -1,53 +0,0 @@ -#use combined on interfaces or targets that can't set TRST/SRST separately -reset_config srst_only srst_pulls_trst - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME at91sam7s -} - -if { [info exists ENDIAN] } { - set _ENDIAN $ENDIAN -} else { - set _ENDIAN little -} - -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - set _CPUTAPID 0x3f0f0f0f -} - -jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID - -set _TARGETNAME $_CHIPNAME.cpu - -target create $_TARGETNAME arm7tdmi -endian $_ENDIAN -chain-position $_TARGETNAME -$_TARGETNAME configure -event reset-init { - soft_reset_halt - # RSTC_CR : Reset peripherals - mww 0xfffffd00 0xa5000004 - # disable watchdog - mww 0xfffffd44 0x00008000 - # enable user reset - mww 0xfffffd08 0xa5000001 - # CKGR_MOR : enable the main oscillator - mww 0xfffffc20 0x00000601 - sleep 10 - # CKGR_PLLR: 96.1097 MHz - mww 0xfffffc2c 0x00481c0e - sleep 10 - # PMC_MCKR : MCK = PLL / 2 ~= 48 MHz - mww 0xfffffc30 0x00000007 - sleep 10 - # MC_FMR: flash mode (FWS=1,FMCN=73) - mww 0xffffff60 0x00490100 - sleep 100 -} - -$_TARGETNAME configure -work-area-phys 0x00200000 -work-area-size 0x4000 -work-area-backup 0 - -#flash bank [ ] -set _FLASHNAME $_CHIPNAME.flash -flash bank $_FLASHNAME at91sam7 0 0 0 0 $_TARGETNAME 0 0 0 0 0 0 0 18432 diff --git a/tcl/target/at91sam7x256.cfg b/tcl/target/at91sam7x256.cfg deleted file mode 100644 index e1a243523..000000000 --- a/tcl/target/at91sam7x256.cfg +++ /dev/null @@ -1,50 +0,0 @@ -#use combined on interfaces or targets that can't set TRST/SRST separately -reset_config srst_only srst_pulls_trst - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME sam7x256 -} - -if { [info exists ENDIAN] } { - set _ENDIAN $ENDIAN -} else { - set _ENDIAN little -} - -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - set _CPUTAPID 0x3f0f0f0f -} - -jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID - -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME arm7tdmi -endian $_ENDIAN -chain-position $_TARGETNAME - -$_TARGETNAME configure -event reset-init { - # disable watchdog - mww 0xfffffd44 0x00008000 - # enable user reset - mww 0xfffffd08 0xa5000001 - # CKGR_MOR : enable the main oscillator - mww 0xfffffc20 0x00000601 - sleep 10 - # CKGR_PLLR: 96.1097 MHz - mww 0xfffffc2c 0x00481c0e - sleep 10 - # PMC_MCKR : MCK = PLL / 2 ~= 48 MHz - mww 0xfffffc30 0x00000007 - sleep 10 - # MC_FMR: flash mode (FWS=1,FMCN=60) - mww 0xffffff60 0x003c0100 - sleep 100 -} - -$_TARGETNAME configure -work-area-phys 0x00200000 -work-area-size 0x4000 -work-area-backup 0 - -#flash bank [ ] -set _FLASHNAME $_CHIPNAME.flash -flash bank $_FLASHNAME at91sam7 0 0 0 0 $_TARGETNAME 0 0 0 0 0 0 0 18432 diff --git a/tcl/target/at91sam7x512.cfg b/tcl/target/at91sam7x512.cfg deleted file mode 100644 index 6910e8559..000000000 --- a/tcl/target/at91sam7x512.cfg +++ /dev/null @@ -1,51 +0,0 @@ -#use combined on interfaces or targets that can't set TRST/SRST separately -reset_config srst_only srst_pulls_trst - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME sam7x512 -} - -if { [info exists ENDIAN] } { - set _ENDIAN $ENDIAN -} else { - set _ENDIAN little -} - -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - set _CPUTAPID 0x3f0f0f0f -} - -jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID - -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME arm7tdmi -endian $_ENDIAN -chain-position $_TARGETNAME - -$_TARGETNAME configure -event reset-init { - # disable watchdog - mww 0xfffffd44 0x00008000 - # enable user reset - mww 0xfffffd08 0xa5000001 - # CKGR_MOR : enable the main oscillator - mww 0xfffffc20 0x00000601 - sleep 10 - # CKGR_PLLR: 96.1097 MHz - mww 0xfffffc2c 0x00481c0e - sleep 10 - # PMC_MCKR : MCK = PLL / 2 ~= 48 MHz - mww 0xfffffc30 0x00000007 - sleep 10 - # MC_FMR: flash mode (FWS=1,FMCN=60) - mww 0xffffff60 0x003c0100 - sleep 100 -} - -$_TARGETNAME configure -work-area-phys 0x00200000 -work-area-size 0x4000 -work-area-backup 0 - -#flash bank [ ] -set _FLASHNAME $_CHIPNAME.flash -flash bank $_FLASHNAME.0 at91sam7 0 0 0 0 $_TARGETNAME 0 0 0 0 0 0 0 18432 -flash bank $_FLASHNAME.1 at91sam7 0 0 0 0 $_TARGETNAME 1 0 0 0 0 0 0 18432 diff --git a/tcl/target/at91sam9.cfg b/tcl/target/at91sam9.cfg deleted file mode 100644 index bf99fb2fa..000000000 --- a/tcl/target/at91sam9.cfg +++ /dev/null @@ -1,37 +0,0 @@ -###################################### -# Target: Atmel AT91SAM9 -###################################### - -if { [info exists AT91_CHIPNAME] } { - set _CHIPNAME $AT91_CHIPNAME -} else { - error "you must specify a chip name" -} - -if { [info exists ENDIAN] } { - set _ENDIAN $ENDIAN -} else { - set _ENDIAN little -} - -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - set _CPUTAPID 0x0792603f -} - -reset_config trst_and_srst separate trst_push_pull srst_open_drain - -jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID - -adapter_nsrst_delay 300 -jtag_ntrst_delay 200 - -adapter_khz 3 - -###################### -# Target configuration -###################### - -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME arm926ejs -endian $_ENDIAN -chain-position $_TARGETNAME diff --git a/tcl/target/at91sam9260.cfg b/tcl/target/at91sam9260.cfg deleted file mode 100644 index c5a07fdd9..000000000 --- a/tcl/target/at91sam9260.cfg +++ /dev/null @@ -1,19 +0,0 @@ -###################################### -# Target: Atmel AT91SAM9260 -###################################### - -if { [info exists CHIPNAME] } { - set AT91_CHIPNAME $CHIPNAME -} else { - set AT91_CHIPNAME at91sam9260 -} - -source [find target/at91sam9.cfg] - - -# Establish internal SRAM memory work areas that are important to pre-bootstrap loaders, etc. The -# AT91SAM9260 has two SRAM areas, one starting at 0x00200000 and the other starting at 0x00300000. -# Both areas are 4 kB long. - -#$_TARGETNAME configure -work-area-phys 0x00200000 -work-area-size 0x1000 -work-area-backup 1 -$_TARGETNAME configure -work-area-phys 0x00300000 -work-area-size 0x1000 -work-area-backup 1 diff --git a/tcl/target/at91sam9260_ext_RAM_ext_flash.cfg b/tcl/target/at91sam9260_ext_RAM_ext_flash.cfg deleted file mode 100644 index 9ab740904..000000000 --- a/tcl/target/at91sam9260_ext_RAM_ext_flash.cfg +++ /dev/null @@ -1,89 +0,0 @@ -###################################### -# Target: Atmel AT91SAM9260 -###################################### - -source [find target/at91sam9261.cfg] - -reset_config trst_and_srst - -adapter_khz 4 - -adapter_nsrst_delay 200 -jtag_ntrst_delay 200 - -scan_chain -$_TARGETNAME configure -event reset-start { - # at reset chip runs at 32khz - adapter_khz 8 -} - -$_TARGETNAME configure -event reset-init {at91sam_init} - -# Flash configuration -#flash bank cfi -set _FLASHNAME $_CHIPNAME.flash -flash bank $_FLASHNAME cfi 0x10000000 0x01000000 2 2 $_TARGETNAME - -# Faster memory downloads. This is disabled automatically during -# reset init since all reset init sequences are too short for -# fast memory access -arm7_9 dcc_downloads enable -arm7_9 fast_memory_access enable - -proc at91sam_init { } { - mww 0xfffffd08 0xa5000501 ;# RSTC_MR : enable user reset - mww 0xfffffd44 0x00008000 ;# WDT_MR : disable watchdog - - mww 0xfffffc20 0x00004001 ;# CKGR_MOR : enable the main oscillator - sleep 20 ;# wait 20 ms - mww 0xfffffc30 0x00000001 ;# PMC_MCKR : switch to main oscillator - sleep 10 ;# wait 10 ms - mww 0xfffffc28 0x2060bf09 ;# CKGR_PLLAR: Set PLLA Register for 198,656MHz - sleep 20 ;# wait 20 ms - mww 0xfffffc30 0x00000101 ;# PMC_MCKR : Select prescaler - sleep 10 ;# wait 10 ms - mww 0xfffffc30 0x00000102 ;# PMC_MCKR : Clock from PLLA is selected - sleep 10 ;# wait 10 ms - - # Now run at anything fast... ie: 10mhz! - adapter_khz 10000 ;# Increase JTAG Speed to 6 MHz - - mww 0xffffec00 0x0a0a0a0a ;# SMC_SETUP0 : Setup SMC for Intel NOR Flash JS28F128P30T85 128MBit - mww 0xffffec04 0x0b0b0b0b ;# SMC_PULSE0 - mww 0xffffec08 0x00160016 ;# SMC_CYCLE0 - mww 0xffffec0c 0x00161003 ;# SMC_MODE0 - - mww 0xfffff870 0xffff0000 ;# PIO_ASR : Select peripheral function for D15..D31 - mww 0xfffff804 0xffff0000 ;# PIO_PDR : Disable PIO function for D15..D31 - - mww 0xffffef1c 0x2 ;# EBI_CSA : Assign EBI Chip Select 1 to SDRAM - - mww 0xffffea08 0x85227259 ;# SDRAMC_CR : Configure SDRAM (2 x Samsung K4S561632H-UC75 : 4M x 16Bit x 4 Banks) - #mww 0xffffea08 0x85227254 ;# SDRAMC_CR : Configure SDRAM (2 x Samsung K4S641632H-UC75 : 1M x 16Bit x 4 Banks) - - mww 0xffffea00 0x1 ;# SDRAMC_MR : issue a NOP command - mww 0x20000000 0 - mww 0xffffea00 0x2 ;# SDRAMC_MR : issue an 'All Banks Precharge' command - mww 0x20000000 0 - mww 0xffffea00 0x4 ;# SDRAMC_MR : issue 8 x 'Auto-Refresh' Command - mww 0x20000000 0 - mww 0xffffea00 0x4 - mww 0x20000000 0 - mww 0xffffea00 0x4 - mww 0x20000000 0 - mww 0xffffea00 0x4 - mww 0x20000000 0 - mww 0xffffea00 0x4 - mww 0x20000000 0 - mww 0xffffea00 0x4 - mww 0x20000000 0 - mww 0xffffea00 0x4 - mww 0x20000000 0 - mww 0xffffea00 0x4 - mww 0x20000000 0 - mww 0xffffea00 0x3 ;# SDRAMC_MR : issue a 'Load Mode Register' command - mww 0x20000000 0 - mww 0xffffea00 0x0 ;# SDRAMC_MR : normal mode - mww 0x20000000 0 - mww 0xffffea04 0x5d2 ;# SDRAMC_TR : Set refresh timer count to 15us -} diff --git a/tcl/target/at91sam9261.cfg b/tcl/target/at91sam9261.cfg deleted file mode 100644 index 3ad141182..000000000 --- a/tcl/target/at91sam9261.cfg +++ /dev/null @@ -1,14 +0,0 @@ -###################################### -# Target: Atmel AT91SAM9261 -###################################### - -if { [info exists CHIPNAME] } { - set AT91_CHIPNAME $CHIPNAME -} else { - set AT91_CHIPNAME at91sam9261 -} - -source [find target/at91sam9.cfg] - -# Internal sram1 memory -$_TARGETNAME configure -work-area-phys 0x00300000 -work-area-size 0x28000 -work-area-backup 1 diff --git a/tcl/target/at91sam9263.cfg b/tcl/target/at91sam9263.cfg deleted file mode 100644 index d2ee113b2..000000000 --- a/tcl/target/at91sam9263.cfg +++ /dev/null @@ -1,20 +0,0 @@ -###################################### -# Target: Atmel AT91SAM9263 -###################################### - -if { [info exists CHIPNAME] } { - set AT91_CHIPNAME $CHIPNAME -} else { - set AT91_CHIPNAME at91sam9263 -} - -source [find target/at91sam9.cfg] - -# Establish internal SRAM memory work areas that are important to pre-bootstrap loaders, etc. The -# AT91SAM9263 has two SRAM areas, -# one starting at 0x00300000 of 80KiB -# and the other starting at 0x00500000 of 16KiB. - -# Internal sram1 memory -$_TARGETNAME configure -work-area-phys 0x00300000 -work-area-size 0x14000 -work-area-backup 1 -#$_TARGETNAME configure -work-area-phys 0x00500000 -work-area-size 0x4000 -work-area-backup 1 diff --git a/tcl/target/at91sam9g10.cfg b/tcl/target/at91sam9g10.cfg deleted file mode 100644 index b49f3d9d2..000000000 --- a/tcl/target/at91sam9g10.cfg +++ /dev/null @@ -1,16 +0,0 @@ -###################################### -# Target: Atmel AT91SAM9G10 -###################################### - -if { [info exists CHIPNAME] } { - set AT91_CHIPNAME $CHIPNAME -} else { - set AT91_CHIPNAME at91sam9g10 -} - -source [find target/at91sam9.cfg] - -# Establish internal SRAM memory work areas that are important to pre-bootstrap loaders, etc. The -# AT91SAM9G10 has one SRAM area at 0x00300000 of 16KiB - -$_TARGETNAME configure -work-area-phys 0x00300000 -work-area-size 0x4000 -work-area-backup 1 diff --git a/tcl/target/at91sam9g20.cfg b/tcl/target/at91sam9g20.cfg deleted file mode 100644 index 3f5e3c626..000000000 --- a/tcl/target/at91sam9g20.cfg +++ /dev/null @@ -1,22 +0,0 @@ -###################################### -# Target: Atmel AT91SAM9G20 -###################################### - -if { [info exists CHIPNAME] } { - set AT91_CHIPNAME $CHIPNAME -} else { - set AT91_CHIPNAME at91sam9g20 -} - -source [find target/at91sam9.cfg] - -# Set fallback clock to 1/6 of worst-case clock speed (which would be the 32.768 kHz slow clock). - -adapter_khz 5 - -# Establish internal SRAM memory work areas that are important to pre-bootstrap loaders, etc. The -# AT91SAM9G20 has two SRAM areas, one starting at 0x00200000 and the other starting at 0x00300000. -# Both areas are 16 kB long. - -#$_TARGETNAME configure -work-area-phys 0x00200000 -work-area-size 0x4000 -work-area-backup 1 -$_TARGETNAME configure -work-area-phys 0x00300000 -work-area-size 0x4000 -work-area-backup 1 diff --git a/tcl/target/at91sam9g45.cfg b/tcl/target/at91sam9g45.cfg deleted file mode 100644 index 7323679b9..000000000 --- a/tcl/target/at91sam9g45.cfg +++ /dev/null @@ -1,16 +0,0 @@ -###################################### -# Target: Atmel AT91SAM9G45 -###################################### - -if { [info exists CHIPNAME] } { - set AT91_CHIPNAME $CHIPNAME -} else { - set AT91_CHIPNAME at91sam9g45 -} - -source [find target/at91sam9.cfg] - -# Establish internal SRAM memory work areas that are important to pre-bootstrap loaders, etc. The -# AT91SAM9G45 has one SRAM area starting at 0x00300000 of 64 KiB. - -$_TARGETNAME configure -work-area-phys 0x00300000 -work-area-size 0x200000 -work-area-backup 1 diff --git a/tcl/target/at91sam9rl.cfg b/tcl/target/at91sam9rl.cfg deleted file mode 100644 index db0522928..000000000 --- a/tcl/target/at91sam9rl.cfg +++ /dev/null @@ -1,14 +0,0 @@ -###################################### -# Target: Atmel AT91SAM9RL -###################################### - -if { [info exists CHIPNAME] } { - set AT91_CHIPNAME $CHIPNAME -} else { - set AT91_CHIPNAME at91sam9rl -} - -source [find target/at91sam9.cfg] - -# Internal sram1 memory -$_TARGETNAME configure -work-area-phys 0x00300000 -work-area-size 0x10000 -work-area-backup 1 diff --git a/tcl/target/at91samdXX.cfg b/tcl/target/at91samdXX.cfg deleted file mode 100644 index 47b4f5f16..000000000 --- a/tcl/target/at91samdXX.cfg +++ /dev/null @@ -1,87 +0,0 @@ -# -# script for Atmel SAMD, SAMR, SAML or SAMC, a Cortex-M0 chip -# - -# -# samdXX devices only support SWD transports. -# -source [find target/swj-dp.tcl] - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME at91samd -} - -if { [info exists ENDIAN] } { - set _ENDIAN $ENDIAN -} else { - set _ENDIAN little -} - -# Work-area is a space in RAM used for flash programming -# By default use 2kB -if { [info exists WORKAREASIZE] } { - set _WORKAREASIZE $WORKAREASIZE -} else { - set _WORKAREASIZE 0x800 -} - -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - set _CPUTAPID 0x4ba00477 -} - -swj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID - -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME cortex_m -endian $_ENDIAN -chain-position $_TARGETNAME - -$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0 - -# SAMD DSU will hold the CPU in reset if TCK is low when RESET_N -# deasserts (see datasheet Atmel-42181E–SAM-D21_Datasheet–02/2015, section 12.6.2) -# -# dsu_reset_deassert configures whether we want to run or halt out of reset, -# then instruct the DSU to let us out of reset. -$_TARGETNAME configure -event reset-deassert-post { - at91samd dsu_reset_deassert -} - -# SRST (wired to RESET_N) resets debug circuitry -# srst_pulls_trst is not configured here to avoid an error raised in reset halt -reset_config srst_gates_jtag - -# Atmel's EDBG (on-board cmsis-dap adapter of Xplained kits) cannot -# stop the MCU before it starts executing code if hardware RESETN -# line is configured by command "reset_config srst_only" -# Use "reset_config none" (default) before flash programming. - -# Do not use a reset button with other SWD adapter than Atmel's EDBG. -# DSU usually locks MCU in reset state until you issue a reset command -# in OpenOCD. - -# SAMD runs at SYSCLK = 1 MHz divided from RC oscillator after reset. -# Other members of family usually use SYSCLK = 4 MHz after reset. -# Datasheet does not specify SYSCLK to SWD clock ratio. -# Usually used SYSCLK/6 is slow, testing shows that debugging can -# work @ SYSCLK/2 but your mileage may vary. -# This limit is most probably imposed by incorrectly handled SWD WAIT -# on some SWD adapters. - -adapter_khz 400 - -# Atmel's EDBG (on-board cmsis-dap adapter of Xplained kits) works -# without problem at maximal clock speed. Atmel recommends -# adapter speed less than 10 * CPU clock. -# adapter_khz 5000 - -if {![using_hla]} { - # if srst is not fitted use SYSRESETREQ to - # perform a soft reset - cortex_m reset_config sysresetreq -} - -set _FLASHNAME $_CHIPNAME.flash -flash bank $_FLASHNAME at91samd 0x00000000 0 1 1 $_TARGETNAME diff --git a/tcl/target/at91samg5x.cfg b/tcl/target/at91samg5x.cfg deleted file mode 100644 index 57274c0c5..000000000 --- a/tcl/target/at91samg5x.cfg +++ /dev/null @@ -1,7 +0,0 @@ -# script for the ATMEL samg5x Cortex-M4F chip family -# - -source [find target/at91sam4XXX.cfg] - -set _FLASHNAME $_CHIPNAME.flash -flash bank $_FLASHNAME at91sam4 0x00400000 0 1 1 $_TARGETNAME diff --git a/tcl/target/atheros_ar2313.cfg b/tcl/target/atheros_ar2313.cfg deleted file mode 100644 index 0966c6c7e..000000000 --- a/tcl/target/atheros_ar2313.cfg +++ /dev/null @@ -1,16 +0,0 @@ -if { [info exists CHIPNAME] } { - set _CHIPNAME $_CHIPNAME -} else { - set _CHIPNAME ar2313 -} - -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - set _CPUTAPID 0x00000001 -} - -jtag newtap $_CHIPNAME cpu -irlen 5 -expected-id $_CPUTAPID - -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME mips_m4k -endian big -chain-position $_TARGETNAME diff --git a/tcl/target/atheros_ar2315.cfg b/tcl/target/atheros_ar2315.cfg deleted file mode 100644 index 92ad37600..000000000 --- a/tcl/target/atheros_ar2315.cfg +++ /dev/null @@ -1,16 +0,0 @@ -if { [info exists CHIPNAME] } { - set _CHIPNAME $_CHIPNAME -} else { - set _CHIPNAME ar2315 -} - -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - set _CPUTAPID 0x00000001 -} - -jtag newtap $_CHIPNAME cpu -irlen 5 -expected-id $_CPUTAPID - -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME mips_m4k -endian big -chain-position $_TARGETNAME diff --git a/tcl/target/atheros_ar9331.cfg b/tcl/target/atheros_ar9331.cfg deleted file mode 100644 index c5609bb1d..000000000 --- a/tcl/target/atheros_ar9331.cfg +++ /dev/null @@ -1,16 +0,0 @@ -if { [info exists CHIPNAME] } { - set _CHIPNAME $_CHIPNAME -} else { - set _CHIPNAME ar9331 -} - -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - set _CPUTAPID 0x00000001 -} - -jtag newtap $_CHIPNAME cpu -irlen 5 -expected-id $_CPUTAPID - -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME mips_m4k -endian big -chain-position $_TARGETNAME diff --git a/tcl/target/atmega128.cfg b/tcl/target/atmega128.cfg deleted file mode 100644 index b8f7d0175..000000000 --- a/tcl/target/atmega128.cfg +++ /dev/null @@ -1,40 +0,0 @@ -# for avr - - set _CHIPNAME avr - set _ENDIAN little - -# jtag speed -adapter_khz 4500 - -reset_config srst_only -adapter_nsrst_delay 100 - -#jtag scan chain -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - set _CPUTAPID 0x8970203F -} -jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID - -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME avr -endian $_ENDIAN -chain-position $_TARGETNAME - -#$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size 16384 -work-area-backup 0 - -set _FLASHNAME $_CHIPNAME.flash -flash bank $_FLASHNAME avr 0 0 0 0 $_TARGETNAME - -#to use it, script will be like: -#init -#adapter_khz 4500 -#reset init -#verify_ircapture disable -# -#halt -#wait halt -#poll -#avr mass_erase 0 -#flash write_image E:/Versaloon/Software/CAMERAPROTOCOLAGENT.hex -#reset run -#shutdown diff --git a/tcl/target/atsamv.cfg b/tcl/target/atsamv.cfg deleted file mode 100644 index b6c484237..000000000 --- a/tcl/target/atsamv.cfg +++ /dev/null @@ -1,51 +0,0 @@ -# ATMEL SAMV, SAMS, and SAME chips are Cortex-M7 parts -# The chips are very similar; the SAMV series just has -# more peripherals and seems like the "flagship" of the -# family. This script will work for all of them. - -source [find target/swj-dp.tcl] - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME samv -} - -if { [info exists ENDIAN] } { - set _ENDIAN $ENDIAN -} else { - set _ENDIAN little -} - -# Work-area is a space in RAM used for flash programming -# By default use 16kB -if { [info exists WORKAREASIZE] } { - set _WORKAREASIZE $WORKAREASIZE -} else { - set _WORKAREASIZE 0x4000 -} - -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - set _CPUTAPID 0x0bd11477 -} - -swj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID - -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME cortex_m -endian $_ENDIAN -chain-position $_TARGETNAME - -$_TARGETNAME configure -work-area-phys 0x20400000 -work-area-size $_WORKAREASIZE -work-area-backup 0 - -adapter_khz 1800 - -if {![using_hla]} { - # if srst is not fitted use SYSRESETREQ to - # perform a soft reset - cortex_m reset_config sysresetreq -} - -set _FLASHNAME $_CHIPNAME.flash -flash bank $_FLASHNAME atsamv 0x00400000 0 0 0 $_TARGETNAME - diff --git a/tcl/target/avr32.cfg b/tcl/target/avr32.cfg deleted file mode 100644 index f5ee1a486..000000000 --- a/tcl/target/avr32.cfg +++ /dev/null @@ -1,17 +0,0 @@ -set _CHIPNAME avr32 -set _ENDIAN big - -set _CPUTAPID 0x21e8203f - -adapter_nsrst_delay 100 -jtag_ntrst_delay 100 - -reset_config trst_and_srst separate - -# jtag scan chain -# format L IRC IRCM IDCODE (Length, IR Capture, IR Capture Mask, IDCODE) -jtag newtap $_CHIPNAME cpu -irlen 5 -ircapture 0x1 -irmask 0x1 -expected-id $_CPUTAPID - -set _TARGETNAME [format "%s.cpu" $_CHIPNAME] -target create $_TARGETNAME avr32_ap7k -endian $_ENDIAN -chain-position $_TARGETNAME - diff --git a/tcl/target/bcm281xx.cfg b/tcl/target/bcm281xx.cfg deleted file mode 100644 index 224af7933..000000000 --- a/tcl/target/bcm281xx.cfg +++ /dev/null @@ -1,33 +0,0 @@ -# BCM281xx - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME bcm281xx -} - - -# Main CPU DAP -if { [info exists DAP_TAPID] } { - set _DAP_TAPID $DAP_TAPID -} else { - set _DAP_TAPID 0x4ba00477 -} - -jtag newtap $_CHIPNAME dap -expected-id $_DAP_TAPID -irlen 4 - - -# Dual Cortex-A9 -set _TARGETNAME0 $_CHIPNAME.cpu0 -set _TARGETNAME1 $_CHIPNAME.cpu1 - -target create $_TARGETNAME0 cortex_a -chain-position $_CHIPNAME.dap -coreid 0 -dbgbase 0x3fe10000 -target create $_TARGETNAME1 cortex_a -chain-position $_CHIPNAME.dap -coreid 1 -dbgbase 0x3fe12000 -target smp $_TARGETNAME0 $_TARGETNAME1 - -$_TARGETNAME0 configure -event gdb-attach { - cortex_a dbginit -} -$_TARGETNAME1 configure -event gdb-attach { - cortex_a dbginit -} diff --git a/tcl/target/bcm4706.cfg b/tcl/target/bcm4706.cfg deleted file mode 100644 index 10b32c77d..000000000 --- a/tcl/target/bcm4706.cfg +++ /dev/null @@ -1,7 +0,0 @@ -set _CHIPNAME bcm4706 -set _CPUID 0x1008c17f - -jtag newtap $_CHIPNAME cpu -irlen 5 -ircapture 0x1 -irmask 0x1f -expected-id $_CPUID - -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME mips_m4k -endian little -chain-position $_TARGETNAME diff --git a/tcl/target/bcm4718.cfg b/tcl/target/bcm4718.cfg deleted file mode 100644 index 8193914a3..000000000 --- a/tcl/target/bcm4718.cfg +++ /dev/null @@ -1,5 +0,0 @@ -set _CHIPNAME bcm4718 -set _LVTAPID 0x1471617f -set _CPUID 0x0008c17f - -source [find target/bcm47xx.cfg] diff --git a/tcl/target/bcm47xx.cfg b/tcl/target/bcm47xx.cfg deleted file mode 100644 index 0132bb802..000000000 --- a/tcl/target/bcm47xx.cfg +++ /dev/null @@ -1,21 +0,0 @@ -echo "Forcing reset_config to none to prevent OpenOCD from pulling SRST after the switch from LV is already performed" -reset_config none - -jtag newtap $_CHIPNAME-lv tap -irlen 32 -ircapture 0x1 -irmask 0x1f -expected-id $_LVTAPID -expected-id $_CPUID -jtag configure $_CHIPNAME-lv.tap -event setup "jtag tapenable $_CHIPNAME.cpu" -jtag configure $_CHIPNAME-lv.tap -event tap-disable {} - -jtag newtap $_CHIPNAME cpu -irlen 5 -ircapture 0x1 -irmask 0x1f -expected-id $_CPUID -disable -jtag configure $_CHIPNAME.cpu -event tap-enable "switch_lv_to_ejtag" - -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME mips_m4k -endian little -chain-position $_TARGETNAME - -proc switch_lv_to_ejtag {} { - global _CHIPNAME - poll 0 - irscan $_CHIPNAME-lv.tap 0x143ff3a - drscan $_CHIPNAME-lv.tap 32 1 - jtag tapdisable $_CHIPNAME-lv.tap - poll 1 -} diff --git a/tcl/target/bcm5352e.cfg b/tcl/target/bcm5352e.cfg deleted file mode 100644 index 3f0495a3e..000000000 --- a/tcl/target/bcm5352e.cfg +++ /dev/null @@ -1,7 +0,0 @@ -set _CHIPNAME bcm5352e -set _CPUID 0x0535217f - -jtag newtap $_CHIPNAME cpu -irlen 8 -ircapture 0x1 -irmask 0x1f -expected-id $_CPUID - -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME mips_m4k -endian little -chain-position $_TARGETNAME diff --git a/tcl/target/bcm6348.cfg b/tcl/target/bcm6348.cfg deleted file mode 100644 index 2540b51af..000000000 --- a/tcl/target/bcm6348.cfg +++ /dev/null @@ -1,9 +0,0 @@ -set _CHIPNAME bcm6348 -set _CPUID 0x0634817f - -adapter_khz 1000 - -jtag newtap $_CHIPNAME cpu -irlen 5 -ircapture 0x1 -irmask 0x1f -expected-id $_CPUID - -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME mips_m4k -endian big -chain-position $_TARGETNAME diff --git a/tcl/target/c100.cfg b/tcl/target/c100.cfg deleted file mode 100644 index 1eaa8fe8a..000000000 --- a/tcl/target/c100.cfg +++ /dev/null @@ -1,42 +0,0 @@ -# c100 config. -# This is ARM1136 dual core -# this script only configures one core (that is used to run Linux) - -# assume no PLL lock, start slowly -adapter_khz 100 - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME c100 -} - -if { [info exists ENDIAN] } { - set _ENDIAN $ENDIAN -} else { - set _ENDIAN little -} - -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - set _CPUTAPID 0x27b3645b -} - -if { [info exists DSPTAPID] } { - set _DSPTAPID $DSPTAPID -} else { - set _DSPTAPID 0x27b3645b -} - -jtag newtap $_CHIPNAME dsp -irlen 5 -ircapture 0x1 -irmask 0x1f -expected-id $_DSPTAPID - - -# Per ARM: DDI0211J_arm1136_r1p5_trm.pdf - the ARM 1136 as a 5 bit IR register -jtag newtap $_CHIPNAME cpu -irlen 5 -ircapture 0x1 -irmask 0x1f -expected-id $_CPUTAPID - -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME arm11 -endian $_ENDIAN -chain-position $_TARGETNAME - -# C100's ARAM 64k SRAM -$_TARGETNAME configure -work-area-phys 0x0a000000 -work-area-size 0x10000 -work-area-backup 0 diff --git a/tcl/target/c100config.tcl b/tcl/target/c100config.tcl deleted file mode 100644 index 52efa83c2..000000000 --- a/tcl/target/c100config.tcl +++ /dev/null @@ -1,412 +0,0 @@ - -# board(-config) specfic parameters file. - -# set CFG_REFCLKFREQ [configC100 CFG_REFCLKFREQ] -proc config {label} { - return [dict get [configC100] $label ] -} - -# show the value for the param. with label -proc showconfig {label} { - echo [format "0x%x" [dict get [configC100] $label ]] -} - -# Telo board config -# when there are more then one board config -# use soft links to c100board-config.tcl -# so that only the right board-config gets -# included (just like include/configs/board-configs.h -# in u-boot. -proc configC100 {} { - # xtal freq. 24MHz - dict set configC100 CFG_REFCLKFREQ 24000000 - - # Amba Clk 165MHz - dict set configC100 CONFIG_SYS_HZ_CLOCK 165000000 - dict set configC100 w_amba 1 - dict set configC100 x_amba 1 - # y = amba_clk * (w+1)*(x+1)*2/xtal_clk - dict set configC100 y_amba [expr ([dict get $configC100 CONFIG_SYS_HZ_CLOCK] * ( ([dict get $configC100 w_amba]+1 ) * ([dict get $configC100 x_amba]+1 ) *2 ) / [dict get $configC100 CFG_REFCLKFREQ]) ] - - # Arm Clk 450MHz, must be a multiple of 25 MHz - dict set configC100 CFG_ARM_CLOCK 450000000 - dict set configC100 w_arm 0 - dict set configC100 x_arm 1 - # y = arm_clk * (w+1)*(x+1)*2/xtal_clk - dict set configC100 y_arm [expr ([dict get $configC100 CFG_ARM_CLOCK] * ( ([dict get $configC100 w_arm]+1 ) * ([dict get $configC100 x_arm]+1 ) *2 ) / [dict get $configC100 CFG_REFCLKFREQ]) ] - - -} - -# This should be called for reset init event handler -proc setupTelo {} { - - # setup GPIO used as control signals for C100 - setupGPIO - # This will allow acces to lower 8MB or NOR - lowGPIO5 - # setup NOR size,timing,etc. - setupNOR - # setup internals + PLL + DDR2 - initC100 -} - - -proc setupNOR {} { - echo "Setting up NOR: 16MB, 16-bit wide bus, CS0" - # this is taken from u-boot/boards/mindspeed/ooma-darwin/board.c:nor_hw_init() - set EX_CSEN_REG [regs EX_CSEN_REG ] - set EX_CS0_SEG_REG [regs EX_CS0_SEG_REG ] - set EX_CS0_CFG_REG [regs EX_CS0_CFG_REG ] - set EX_CS0_TMG1_REG [regs EX_CS0_TMG1_REG ] - set EX_CS0_TMG2_REG [regs EX_CS0_TMG2_REG ] - set EX_CS0_TMG3_REG [regs EX_CS0_TMG3_REG ] - set EX_CLOCK_DIV_REG [regs EX_CLOCK_DIV_REG ] - set EX_MFSM_REG [regs EX_MFSM_REG ] - set EX_CSFSM_REG [regs EX_CSFSM_REG ] - set EX_WRFSM_REG [regs EX_WRFSM_REG ] - set EX_RDFSM_REG [regs EX_RDFSM_REG ] - - # enable Expansion Bus Clock + CS0 (NOR) - mww $EX_CSEN_REG 0x3 - # set the address space for CS0=16MB - mww $EX_CS0_SEG_REG 0x7ff - # set the CS0 bus width to 16-bit - mww $EX_CS0_CFG_REG 0x202 - # set timings to NOR - mww $EX_CS0_TMG1_REG 0x03034006 - mww $EX_CS0_TMG2_REG 0x04040002 - #mww $EX_CS0_TMG3_REG - # set EBUS clock 165/5=33MHz - mww $EX_CLOCK_DIV_REG 0x5 - # everthing else is OK with default -} - -proc bootNOR {} { - set EXP_CS0_BASEADDR [regs EXP_CS0_BASEADDR] - set BLOCK_RESET_REG [regs BLOCK_RESET_REG] - set DDR_RST [regs DDR_RST] - - # put DDR controller in reset (so that it comes reset in u-boot) - mmw $BLOCK_RESET_REG 0x0 $DDR_RST - # setup CS0 controller for NOR - setupNOR - # make sure we are accessing the lower part of NOR - lowGPIO5 - # set PC to start of NOR (at boot 0x20000000 = 0x0) - reg pc $EXP_CS0_BASEADDR - # run - resume -} -proc setupGPIO {} { - echo "Setting up GPIO block for Telo" - # This is current setup for Telo (see sch. for details): - #GPIO0 reset for FXS-FXO IC, leave as input, the IC has internal pullup - #GPIO1 irq line for FXS-FXO - #GPIO5 addr22 for NOR flash (access to upper 8MB) - #GPIO17 reset for DECT module. - #GPIO29 CS_n for NAND - - set GPIO_OUTPUT_REG [regs GPIO_OUTPUT_REG] - set GPIO_OE_REG [regs GPIO_OE_REG] - - # set GPIO29=GPIO17=1, GPIO5=0 - mww $GPIO_OUTPUT_REG [expr 1<<29 | 1<<17] - # enable [as output] GPIO29,GPIO17,GPIO5 - mww $GPIO_OE_REG [expr 1<<29 | 1<<17 | 1<<5] -} - -proc highGPIO5 {} { - echo "GPIO5 high" - set GPIO_OUTPUT_REG [regs GPIO_OUTPUT_REG] - # set GPIO5=1 - mmw $GPIO_OUTPUT_REG [expr 1 << 5] 0x0 -} - -proc lowGPIO5 {} { - echo "GPIO5 low" - set GPIO_OUTPUT_REG [regs GPIO_OUTPUT_REG] - # set GPIO5=0 - mmw $GPIO_OUTPUT_REG 0x0 [expr 1 << 5] -} - -proc boardID {id} { - # so far built: - # 4'b1111 - dict set boardID 15 name "EVT1" - dict set boardID 15 ddr2size 128M - # dict set boardID 15 nandsize 1G - # dict set boardID 15 norsize 16M - # 4'b0000 - dict set boardID 0 name "EVT2" - dict set boardID 0 ddr2size 128M - # 4'b0001 - dict set boardID 1 name "EVT3" - dict set boardID 1 ddr2size 256M - # 4'b1110 - dict set boardID 14 name "EVT3_old" - dict set boardID 14 ddr2size 128M - # 4'b0010 - dict set boardID 2 name "EVT4" - dict set boardID 2 ddr2size 256M - - return $boardID -} - - -# converted from u-boot/boards/mindspeed/ooma-darwin/board.c:ooma_board_detect() -# figure out what board revision this is, uses BOOTSTRAP register to read stuffed resistors -proc ooma_board_detect {} { - set GPIO_BOOTSTRAP_REG [regs GPIO_BOOTSTRAP_REG] - - # read the current value of the BOOTSRAP pins - set tmp [mrw $GPIO_BOOTSTRAP_REG] - echo [format "GPIO_BOOTSTRAP_REG (0x%x): 0x%x" $GPIO_BOOTSTRAP_REG $tmp] - # extract the GPBP bits - set gpbt [expr ($tmp &0x1C00) >> 10 | ($tmp & 0x40) >>3] - - # display board ID - echo [format "This is %s (0x%x)" [dict get [boardID $gpbt] $gpbt name] $gpbt] - # show it on serial console - putsUART0 [format "This is %s (0x%x)\n" [dict get [boardID $gpbt] $gpbt name] $gpbt] - # return the ddr2 size, used to configure DDR2 on a given board. - return [dict get [boardID $gpbt] $gpbt ddr2size] -} - -proc configureDDR2regs_256M {} { - - set DENALI_CTL_00_DATA [regs DENALI_CTL_00_DATA] - set DENALI_CTL_01_DATA [regs DENALI_CTL_01_DATA] - set DENALI_CTL_02_DATA [regs DENALI_CTL_02_DATA] - set DENALI_CTL_03_DATA [regs DENALI_CTL_03_DATA] - set DENALI_CTL_04_DATA [regs DENALI_CTL_04_DATA] - set DENALI_CTL_05_DATA [regs DENALI_CTL_05_DATA] - set DENALI_CTL_06_DATA [regs DENALI_CTL_06_DATA] - set DENALI_CTL_07_DATA [regs DENALI_CTL_07_DATA] - set DENALI_CTL_08_DATA [regs DENALI_CTL_08_DATA] - set DENALI_CTL_09_DATA [regs DENALI_CTL_09_DATA] - set DENALI_CTL_10_DATA [regs DENALI_CTL_10_DATA] - set DENALI_CTL_11_DATA [regs DENALI_CTL_11_DATA] - set DENALI_CTL_12_DATA [regs DENALI_CTL_12_DATA] - set DENALI_CTL_13_DATA [regs DENALI_CTL_13_DATA] - set DENALI_CTL_14_DATA [regs DENALI_CTL_14_DATA] - set DENALI_CTL_15_DATA [regs DENALI_CTL_15_DATA] - set DENALI_CTL_16_DATA [regs DENALI_CTL_16_DATA] - set DENALI_CTL_17_DATA [regs DENALI_CTL_17_DATA] - set DENALI_CTL_18_DATA [regs DENALI_CTL_18_DATA] - set DENALI_CTL_19_DATA [regs DENALI_CTL_19_DATA] - set DENALI_CTL_20_DATA [regs DENALI_CTL_20_DATA] - - set DENALI_CTL_02_VAL 0x0100000000010100 - set DENALI_CTL_11_VAL 0x433a32164a560a00 - - mw64bit $DENALI_CTL_00_DATA 0x0100000101010101 - # 01_DATA mod [40]=1, enable BA2 - mw64bit $DENALI_CTL_01_DATA 0x0100010100000001 - mw64bit $DENALI_CTL_02_DATA $DENALI_CTL_02_VAL - mw64bit $DENALI_CTL_03_DATA 0x0102020202020201 - mw64bit $DENALI_CTL_04_DATA 0x0000010100000001 - mw64bit $DENALI_CTL_05_DATA 0x0203010300010101 - mw64bit $DENALI_CTL_06_DATA 0x060a020200020202 - mw64bit $DENALI_CTL_07_DATA 0x0000000300000206 - mw64bit $DENALI_CTL_08_DATA 0x6400003f3f0a0209 - mw64bit $DENALI_CTL_09_DATA 0x1a000000001a1a1a - mw64bit $DENALI_CTL_10_DATA 0x0120202020191a18 - # 11_DATA mod [39-32]=16,more refresh - mw64bit $DENALI_CTL_11_DATA $DENALI_CTL_11_VAL - mw64bit $DENALI_CTL_12_DATA 0x0000000000000800 - mw64bit $DENALI_CTL_13_DATA 0x0010002000100040 - mw64bit $DENALI_CTL_14_DATA 0x0010004000100040 - mw64bit $DENALI_CTL_15_DATA 0x04f8000000000000 - mw64bit $DENALI_CTL_16_DATA 0x000000002cca0000 - mw64bit $DENALI_CTL_17_DATA 0x0000000000000000 - mw64bit $DENALI_CTL_18_DATA 0x0302000000000000 - mw64bit $DENALI_CTL_19_DATA 0x00001300c8030600 - mw64bit $DENALI_CTL_20_DATA 0x0000000081fe00c8 - - set wr_dqs_shift 0x40 - # start DDRC - mw64bit $DENALI_CTL_02_DATA [expr $DENALI_CTL_02_VAL | (1 << 32)] - # wait int_status[2] (DRAM init complete) - echo -n "Waiting for DDR2 controller to init..." - set tmp [mrw [expr $DENALI_CTL_08_DATA + 4]] - while { [expr $tmp & 0x040000] == 0 } { - sleep 1 - set tmp [mrw [expr $DENALI_CTL_08_DATA + 4]] - } - echo "done." - - # do ddr2 training sequence - # TBD (for now, if you need it, run trainDDR command) -} - -# converted from u-boot/cpu/arm1136/comcerto/bsp100.c:config_board99() -# The values are computed based on Mindspeed and Nanya datasheets -proc configureDDR2regs_128M {} { - - set DENALI_CTL_00_DATA [regs DENALI_CTL_00_DATA] - set DENALI_CTL_01_DATA [regs DENALI_CTL_01_DATA] - set DENALI_CTL_02_DATA [regs DENALI_CTL_02_DATA] - set DENALI_CTL_03_DATA [regs DENALI_CTL_03_DATA] - set DENALI_CTL_04_DATA [regs DENALI_CTL_04_DATA] - set DENALI_CTL_05_DATA [regs DENALI_CTL_05_DATA] - set DENALI_CTL_06_DATA [regs DENALI_CTL_06_DATA] - set DENALI_CTL_07_DATA [regs DENALI_CTL_07_DATA] - set DENALI_CTL_08_DATA [regs DENALI_CTL_08_DATA] - set DENALI_CTL_09_DATA [regs DENALI_CTL_09_DATA] - set DENALI_CTL_10_DATA [regs DENALI_CTL_10_DATA] - set DENALI_CTL_11_DATA [regs DENALI_CTL_11_DATA] - set DENALI_CTL_12_DATA [regs DENALI_CTL_12_DATA] - set DENALI_CTL_13_DATA [regs DENALI_CTL_13_DATA] - set DENALI_CTL_14_DATA [regs DENALI_CTL_14_DATA] - set DENALI_CTL_15_DATA [regs DENALI_CTL_15_DATA] - set DENALI_CTL_16_DATA [regs DENALI_CTL_16_DATA] - set DENALI_CTL_17_DATA [regs DENALI_CTL_17_DATA] - set DENALI_CTL_18_DATA [regs DENALI_CTL_18_DATA] - set DENALI_CTL_19_DATA [regs DENALI_CTL_19_DATA] - set DENALI_CTL_20_DATA [regs DENALI_CTL_20_DATA] - - - set DENALI_CTL_02_VAL 0x0100010000010100 - set DENALI_CTL_11_VAL 0x433A42124A650A37 - # set some default values - mw64bit $DENALI_CTL_00_DATA 0x0100000101010101 - mw64bit $DENALI_CTL_01_DATA 0x0100000100000101 - mw64bit $DENALI_CTL_02_DATA $DENALI_CTL_02_VAL - mw64bit $DENALI_CTL_03_DATA 0x0102020202020201 - mw64bit $DENALI_CTL_04_DATA 0x0201010100000201 - mw64bit $DENALI_CTL_05_DATA 0x0203010300010101 - mw64bit $DENALI_CTL_06_DATA 0x050A020200020202 - mw64bit $DENALI_CTL_07_DATA 0x000000030E0B0205 - mw64bit $DENALI_CTL_08_DATA 0x6427003F3F0A0209 - mw64bit $DENALI_CTL_09_DATA 0x1A00002F00001A00 - mw64bit $DENALI_CTL_10_DATA 0x01202020201A1A1A - mw64bit $DENALI_CTL_11_DATA $DENALI_CTL_11_VAL - mw64bit $DENALI_CTL_12_DATA 0x0000080000000800 - mw64bit $DENALI_CTL_13_DATA 0x0010002000100040 - mw64bit $DENALI_CTL_14_DATA 0x0010004000100040 - mw64bit $DENALI_CTL_15_DATA 0x0508000000000000 - mw64bit $DENALI_CTL_16_DATA 0x000020472D200000 - mw64bit $DENALI_CTL_17_DATA 0x0000000008000000 - mw64bit $DENALI_CTL_18_DATA 0x0302000000000000 - mw64bit $DENALI_CTL_19_DATA 0x00001400C8030604 - mw64bit $DENALI_CTL_20_DATA 0x00000000823600C8 - - set wr_dqs_shift 0x40 - # start DDRC - mw64bit $DENALI_CTL_02_DATA [expr $DENALI_CTL_02_VAL | (1 << 32)] - # wait int_status[2] (DRAM init complete) - echo -n "Waiting for DDR2 controller to init..." - set tmp [mrw [expr $DENALI_CTL_08_DATA + 4]] - while { [expr $tmp & 0x040000] == 0 } { - sleep 1 - set tmp [mrw [expr $DENALI_CTL_08_DATA + 4]] - } - # This is not necessary - #mw64bit $DENALI_CTL_11_DATA [expr ($DENALI_CTL_11_VAL & ~0x00007F0000000000) | ($wr_dqs_shift << 40) ] - echo "done." - - # do ddr2 training sequence - # TBD (for now, if you need it, run trainDDR command) -} - - - -proc setupUART0 {} { - # configure UART0 to 115200, 8N1 - set GPIO_LOCK_REG [regs GPIO_LOCK_REG] - set GPIO_IOCTRL_REG [regs GPIO_IOCTRL_REG] - set GPIO_IOCTRL_VAL [regs GPIO_IOCTRL_VAL] - set GPIO_IOCTRL_UART0 [regs GPIO_IOCTRL_UART0] - set UART0_LCR [regs UART0_LCR] - set LCR_DLAB [regs LCR_DLAB] - set UART0_DLL [regs UART0_DLL] - set UART0_DLH [regs UART0_DLH] - set UART0_IIR [regs UART0_IIR] - set UART0_IER [regs UART0_IER] - set LCR_ONE_STOP [regs LCR_ONE_STOP] - set LCR_CHAR_LEN_8 [regs LCR_CHAR_LEN_8] - set FCR_XMITRES [regs FCR_XMITRES] - set FCR_RCVRRES [regs FCR_RCVRRES] - set FCR_FIFOEN [regs FCR_FIFOEN] - set IER_UUE [regs IER_UUE] - - # unlock writing to IOCTRL register - mww $GPIO_LOCK_REG $GPIO_IOCTRL_VAL - # enable UART0 - mmw $GPIO_IOCTRL_REG $GPIO_IOCTRL_UART0 0x0 - # baudrate 115200 - # This should really be amba_clk/(16*115200) but amba_clk=165MHz - set tmp 89 - # Enable Divisor Latch access - mmw $UART0_LCR $LCR_DLAB 0x0 - # set the divisor to $tmp - mww $UART0_DLL [expr $tmp & 0xff] - mww $UART0_DLH [expr $tmp >> 8] - # Disable Divisor Latch access - mmw $UART0_LCR 0x0 $LCR_DLAB - # set the UART to 8N1 - mmw $UART0_LCR [expr $LCR_ONE_STOP | $LCR_CHAR_LEN_8 ] 0x0 - # reset FIFO - mmw $UART0_IIR [expr $FCR_XMITRES | $FCR_RCVRRES | $FCR_FIFOEN ] 0x0 - # enable FFUART - mww $UART0_IER $IER_UUE -} - -proc putcUART0 {char} { - - set UART0_LSR [regs UART0_LSR] - set UART0_THR [regs UART0_THR] - set LSR_TEMT [regs LSR_TEMT] - - # convert the 'char' to digit - set tmp [ scan $char %c ] - # /* wait for room in the tx FIFO on FFUART */ - while {[expr [mrw $UART0_LSR] & $LSR_TEMT] == 0} { sleep 1 } - mww $UART0_THR $tmp - if { $char == "\n" } { putcUART0 \r } -} - -proc putsUART0 {str} { - set index 0 - set len [string length $str] - while { $index < $len } { - putcUART0 [string index $str $index] - set index [expr $index + 1] - } -} - - -proc trainDDR2 {} { - set ARAM_BASEADDR [regs ARAM_BASEADDR] - - # you must have run 'reset init' or u-boot - # load the training code to ARAM - load_image ./images/ddr2train.bin $ARAM_BASEADDR bin - # set PC to start of NOR (at boot 0x20000000 = 0x0) - reg pc $ARAM_BASEADDR - # run - resume -} - -proc flashUBOOT {file} { - # this will update uboot on NOR partition - set EXP_CS0_BASEADDR [regs EXP_CS0_BASEADDR] - - # setup CS0 controller for NOR - setupNOR - # make sure we are accessing the lower part of NOR - lowGPIO5 - flash probe 0 - echo "Erasing sectors 0-3 for uboot" - putsUART0 "Erasing sectors 0-3 for uboot\n" - flash erase_sector 0 0 3 - echo "Programming u-boot" - putsUART0 "Programming u-boot..." - arm11 memwrite burst enable - flash write_image $file $EXP_CS0_BASEADDR - arm11 memwrite burst disable - putsUART0 "done.\n" - putsUART0 "Rebooting, please wait!\n" - reboot -} \ No newline at end of file diff --git a/tcl/target/c100helper.tcl b/tcl/target/c100helper.tcl deleted file mode 100644 index c9124cbc6..000000000 --- a/tcl/target/c100helper.tcl +++ /dev/null @@ -1,506 +0,0 @@ - -proc helpC100 {} { - echo "List of useful functions for C100 processor:" - echo "1) reset init: will set up your Telo board" - echo "2) setupNOR: will setup NOR access" - echo "3) showNOR: will show current NOR config registers for 16-bit, 16MB NOR" - echo "4) setupGPIO: will setup GPIOs for Telo board" - echo "5) showGPIO: will show current GPIO config registers" - echo "6) highGPIO5: will set GPIO5=NOR_addr22=1 to access upper 8MB" - echo "7) lowGPIO5: will set GPIO5=NOR_addr22=0 to access lower 8MB" - echo "8) showAmbaClk: will show current config registers for Amba Bus Clock" - echo "9) setupAmbaClk: will setup Amba Bus Clock=165MHz" - echo "10) showArmClk: will show current config registers for Arm Bus Clock" - echo "11) setupArmClk: will setup Amba Bus Clock=450MHz" - echo "12) ooma_board_detect: will show which version of Telo you have" - echo "13) setupDDR2: will configure DDR2 controller, you must have PLLs configureg" - echo "14) showDDR2: will show DDR2 config registers" - echo "15) showWatchdog: will show current regster config for watchdog" - echo "16) reboot: will trigger watchdog and reboot Telo (hw reset)" - echo "17) bootNOR: will boot Telo from NOR" - echo "18) setupUART0: will configure UART0 for 115200 8N1, PLLs have to be confiured" - echo "19) putcUART0: will print a character on UART0" - echo "20) putsUART0: will print a string on UART0" - echo "21) trainDDR2: will run DDR2 training program" - echo "22) flashUBOOT: will prgram NOR sectors 0-3 with u-boot.bin" -} - -source [find mem_helper.tcl] - -# read a 64-bit register (memory mapped) -proc mr64bit {reg} { - set value "" - mem2array value 32 $reg 2 - return $value -} - - -# write a 64-bit register (memory mapped) -proc mw64bit {reg value} { - set high [expr $value >> 32] - set low [expr $value & 0xffffffff] - #echo [format "mw64bit(0x%x): 0x%08x%08x" $reg $high $low] - mww $reg $low - mww [expr $reg+4] $high -} - - -proc showNOR {} { - echo "This is the current NOR setup" - set EX_CSEN_REG [regs EX_CSEN_REG ] - set EX_CS0_SEG_REG [regs EX_CS0_SEG_REG ] - set EX_CS0_CFG_REG [regs EX_CS0_CFG_REG ] - set EX_CS0_TMG1_REG [regs EX_CS0_TMG1_REG ] - set EX_CS0_TMG2_REG [regs EX_CS0_TMG2_REG ] - set EX_CS0_TMG3_REG [regs EX_CS0_TMG3_REG ] - set EX_CLOCK_DIV_REG [regs EX_CLOCK_DIV_REG ] - set EX_MFSM_REG [regs EX_MFSM_REG ] - set EX_CSFSM_REG [regs EX_CSFSM_REG ] - set EX_WRFSM_REG [regs EX_WRFSM_REG ] - set EX_RDFSM_REG [regs EX_RDFSM_REG ] - - echo [format "EX_CSEN_REG (0x%x): 0x%x" $EX_CSEN_REG [mrw $EX_CSEN_REG]] - echo [format "EX_CS0_SEG_REG (0x%x): 0x%x" $EX_CS0_SEG_REG [mrw $EX_CS0_SEG_REG]] - echo [format "EX_CS0_CFG_REG (0x%x): 0x%x" $EX_CS0_CFG_REG [mrw $EX_CS0_CFG_REG]] - echo [format "EX_CS0_TMG1_REG (0x%x): 0x%x" $EX_CS0_TMG1_REG [mrw $EX_CS0_TMG1_REG]] - echo [format "EX_CS0_TMG2_REG (0x%x): 0x%x" $EX_CS0_TMG2_REG [mrw $EX_CS0_TMG2_REG]] - echo [format "EX_CS0_TMG3_REG (0x%x): 0x%x" $EX_CS0_TMG3_REG [mrw $EX_CS0_TMG3_REG]] - echo [format "EX_CLOCK_DIV_REG (0x%x): 0x%x" $EX_CLOCK_DIV_REG [mrw $EX_CLOCK_DIV_REG]] - echo [format "EX_MFSM_REG (0x%x): 0x%x" $EX_MFSM_REG [mrw $EX_MFSM_REG]] - echo [format "EX_CSFSM_REG (0x%x): 0x%x" $EX_CSFSM_REG [mrw $EX_CSFSM_REG]] - echo [format "EX_WRFSM_REG (0x%x): 0x%x" $EX_WRFSM_REG [mrw $EX_WRFSM_REG]] - echo [format "EX_RDFSM_REG (0x%x): 0x%x" $EX_RDFSM_REG [mrw $EX_RDFSM_REG]] -} - - - -proc showGPIO {} { - echo "This is the current GPIO register setup" - # GPIO outputs register - set GPIO_OUTPUT_REG [regs GPIO_OUTPUT_REG] - # GPIO Output Enable register - set GPIO_OE_REG [regs GPIO_OE_REG] - set GPIO_HI_INT_ENABLE_REG [regs GPIO_HI_INT_ENABLE_REG] - set GPIO_LO_INT_ENABLE_REG [regs GPIO_LO_INT_ENABLE_REG] - # GPIO input register - set GPIO_INPUT_REG [regs GPIO_INPUT_REG] - set APB_ACCESS_WS_REG [regs APB_ACCESS_WS_REG] - set MUX_CONF_REG [regs MUX_CONF_REG] - set SYSCONF_REG [regs SYSCONF_REG] - set GPIO_ARM_ID_REG [regs GPIO_ARM_ID_REG] - set GPIO_BOOTSTRAP_REG [regs GPIO_BOOTSTRAP_REG] - set GPIO_LOCK_REG [regs GPIO_LOCK_REG] - set GPIO_IOCTRL_REG [regs GPIO_IOCTRL_REG] - set GPIO_DEVID_REG [regs GPIO_DEVID_REG] - - echo [format "GPIO_OUTPUT_REG (0x%x): 0x%x" $GPIO_OUTPUT_REG [mrw $GPIO_OUTPUT_REG]] - echo [format "GPIO_OE_REG (0x%x): 0x%x" $GPIO_OE_REG [mrw $GPIO_OE_REG]] - echo [format "GPIO_HI_INT_ENABLE_REG(0x%x): 0x%x" $GPIO_HI_INT_ENABLE_REG [mrw $GPIO_HI_INT_ENABLE_REG]] - echo [format "GPIO_LO_INT_ENABLE_REG(0x%x): 0x%x" $GPIO_LO_INT_ENABLE_REG [mrw $GPIO_LO_INT_ENABLE_REG]] - echo [format "GPIO_INPUT_REG (0x%x): 0x%x" $GPIO_INPUT_REG [mrw $GPIO_INPUT_REG]] - echo [format "APB_ACCESS_WS_REG (0x%x): 0x%x" $APB_ACCESS_WS_REG [mrw $APB_ACCESS_WS_REG]] - echo [format "MUX_CONF_REG (0x%x): 0x%x" $MUX_CONF_REG [mrw $MUX_CONF_REG]] - echo [format "SYSCONF_REG (0x%x): 0x%x" $SYSCONF_REG [mrw $SYSCONF_REG]] - echo [format "GPIO_ARM_ID_REG (0x%x): 0x%x" $GPIO_ARM_ID_REG [mrw $GPIO_ARM_ID_REG]] - echo [format "GPIO_BOOTSTRAP_REG (0x%x): 0x%x" $GPIO_BOOTSTRAP_REG [mrw $GPIO_BOOTSTRAP_REG]] - echo [format "GPIO_LOCK_REG (0x%x): 0x%x" $GPIO_LOCK_REG [mrw $GPIO_LOCK_REG]] - echo [format "GPIO_IOCTRL_REG (0x%x): 0x%x" $GPIO_IOCTRL_REG [mrw $GPIO_IOCTRL_REG]] - echo [format "GPIO_DEVID_REG (0x%x): 0x%x" $GPIO_DEVID_REG [mrw $GPIO_DEVID_REG]] -} - - - -# converted from u-boot/cpu/arm1136/comcerto/bsp100.c (HAL_get_amba_clk()) -proc showAmbaClk {} { - set CFG_REFCLKFREQ [config CFG_REFCLKFREQ] - set CLKCORE_AHB_CLK_CNTRL [regs CLKCORE_AHB_CLK_CNTRL] - set PLL_CLK_BYPASS [regs PLL_CLK_BYPASS] - - echo [format "CLKCORE_AHB_CLK_CNTRL (0x%x): 0x%x" $CLKCORE_AHB_CLK_CNTRL [mrw $CLKCORE_AHB_CLK_CNTRL]] - mem2array value 32 $CLKCORE_AHB_CLK_CNTRL 1 - # see if the PLL is in bypass mode - set bypass [expr ($value(0) & $PLL_CLK_BYPASS) >> 24 ] - echo [format "PLL bypass bit: %d" $bypass] - if {$bypass == 1} { - echo [format "Amba Clk is set to REFCLK: %d (MHz)" [expr $CFG_REFCLKFREQ/1000000]] - } else { - # nope, extract x,y,w and compute the PLL output freq. - set x [expr ($value(0) & 0x0001F0000) >> 16] - echo [format "x: %d" $x] - set y [expr ($value(0) & 0x00000007F)] - echo [format "y: %d" $y] - set w [expr ($value(0) & 0x000000300) >> 8] - echo [format "w: %d" $w] - echo [format "Amba PLL Clk: %d (MHz)" [expr ($CFG_REFCLKFREQ * $y / (($w + 1) * ($x + 1) * 2))/1000000]] - } -} - - -# converted from u-boot/cpu/arm1136/comcerto/bsp100.c (HAL_set_amba_clk()) -# this clock is useb by all peripherals (DDR2, ethernet, ebus, etc) -proc setupAmbaClk {} { - set CLKCORE_PLL_STATUS [regs CLKCORE_PLL_STATUS] - set CLKCORE_AHB_CLK_CNTRL [regs CLKCORE_AHB_CLK_CNTRL] - set ARM_PLL_BY_CTRL [regs ARM_PLL_BY_CTRL] - set ARM_AHB_BYP [regs ARM_AHB_BYP] - set PLL_DISABLE [regs PLL_DISABLE] - set PLL_CLK_BYPASS [regs PLL_CLK_BYPASS] - set AHB_PLL_BY_CTRL [regs AHB_PLL_BY_CTRL] - set DIV_BYPASS [regs DIV_BYPASS] - set AHBCLK_PLL_LOCK [regs AHBCLK_PLL_LOCK] - set CFG_REFCLKFREQ [config CFG_REFCLKFREQ] - set CONFIG_SYS_HZ_CLOCK [config CONFIG_SYS_HZ_CLOCK] - set w [config w_amba] - set x [config x_amba] - set y [config y_amba] - - echo [format "Setting Amba PLL to lock to %d MHz" [expr $CONFIG_SYS_HZ_CLOCK/1000000]] - #echo [format "setupAmbaClk: w= %d" $w] - #echo [format "setupAmbaClk: x= %d" $x] - #echo [format "setupAmbaClk: y= %d" $y] - # set PLL into BYPASS mode using MUX - mmw $CLKCORE_AHB_CLK_CNTRL $PLL_CLK_BYPASS 0x0 - # do an internal PLL bypass - mmw $CLKCORE_AHB_CLK_CNTRL $AHB_PLL_BY_CTRL 0x0 - # wait 500us (ARM running @24Mhz -> 12000 cycles => 500us) - # openocd smallest resolution is 1ms so, wait 1ms - sleep 1 - # disable the PLL - mmw $CLKCORE_AHB_CLK_CNTRL $PLL_DISABLE 0x0 - # wait 1ms - sleep 1 - # enable the PLL - mmw $CLKCORE_AHB_CLK_CNTRL 0x0 $PLL_DISABLE - sleep 1 - # set X, W and X - mmw $CLKCORE_AHB_CLK_CNTRL 0x0 0xFFFFFF - mmw $CLKCORE_AHB_CLK_CNTRL [expr (($x << 16) + ($w << 8) + $y)] 0x0 - # wait for PLL to lock - echo "Wating for Amba PLL to lock" - while {[expr [mrw $CLKCORE_PLL_STATUS] & $AHBCLK_PLL_LOCK] == 0} { sleep 1 } - # remove the internal PLL bypass - mmw $CLKCORE_AHB_CLK_CNTRL 0x0 $AHB_PLL_BY_CTRL - # remove PLL from BYPASS mode using MUX - mmw $CLKCORE_AHB_CLK_CNTRL 0x0 $PLL_CLK_BYPASS -} - - -# converted from u-boot/cpu/arm1136/comcerto/bsp100.c (HAL_get_arm_clk()) -proc showArmClk {} { - set CFG_REFCLKFREQ [config CFG_REFCLKFREQ] - set CLKCORE_ARM_CLK_CNTRL [regs CLKCORE_ARM_CLK_CNTRL] - set PLL_CLK_BYPASS [regs PLL_CLK_BYPASS] - - echo [format "CLKCORE_ARM_CLK_CNTRL (0x%x): 0x%x" $CLKCORE_ARM_CLK_CNTRL [mrw $CLKCORE_ARM_CLK_CNTRL]] - mem2array value 32 $CLKCORE_ARM_CLK_CNTRL 1 - # see if the PLL is in bypass mode - set bypass [expr ($value(0) & $PLL_CLK_BYPASS) >> 24 ] - echo [format "PLL bypass bit: %d" $bypass] - if {$bypass == 1} { - echo [format "Amba Clk is set to REFCLK: %d (MHz)" [expr $CFG_REFCLKFREQ/1000000]] - } else { - # nope, extract x,y,w and compute the PLL output freq. - set x [expr ($value(0) & 0x0001F0000) >> 16] - echo [format "x: %d" $x] - set y [expr ($value(0) & 0x00000007F)] - echo [format "y: %d" $y] - set w [expr ($value(0) & 0x000000300) >> 8] - echo [format "w: %d" $w] - echo [format "Arm PLL Clk: %d (MHz)" [expr ($CFG_REFCLKFREQ * $y / (($w + 1) * ($x + 1) * 2))/1000000]] - } -} - -# converted from u-boot/cpu/arm1136/comcerto/bsp100.c (HAL_set_arm_clk()) -# Arm Clock is used by two ARM1136 cores -proc setupArmClk {} { - set CLKCORE_PLL_STATUS [regs CLKCORE_PLL_STATUS] - set CLKCORE_ARM_CLK_CNTRL [regs CLKCORE_ARM_CLK_CNTRL] - set ARM_PLL_BY_CTRL [regs ARM_PLL_BY_CTRL] - set ARM_AHB_BYP [regs ARM_AHB_BYP] - set PLL_DISABLE [regs PLL_DISABLE] - set PLL_CLK_BYPASS [regs PLL_CLK_BYPASS] - set AHB_PLL_BY_CTRL [regs AHB_PLL_BY_CTRL] - set DIV_BYPASS [regs DIV_BYPASS] - set FCLK_PLL_LOCK [regs FCLK_PLL_LOCK] - set CFG_REFCLKFREQ [config CFG_REFCLKFREQ] - set CFG_ARM_CLOCK [config CFG_ARM_CLOCK] - set w [config w_arm] - set x [config x_arm] - set y [config y_arm] - - echo [format "Setting Arm PLL to lock to %d MHz" [expr $CFG_ARM_CLOCK/1000000]] - #echo [format "setupArmClk: w= %d" $w] - #echo [format "setupArmaClk: x= %d" $x] - #echo [format "setupArmaClk: y= %d" $y] - # set PLL into BYPASS mode using MUX - mmw $CLKCORE_ARM_CLK_CNTRL $PLL_CLK_BYPASS 0x0 - # do an internal PLL bypass - mmw $CLKCORE_ARM_CLK_CNTRL $ARM_PLL_BY_CTRL 0x0 - # wait 500us (ARM running @24Mhz -> 12000 cycles => 500us) - # openocd smallest resolution is 1ms so, wait 1ms - sleep 1 - # disable the PLL - mmw $CLKCORE_ARM_CLK_CNTRL $PLL_DISABLE 0x0 - # wait 1ms - sleep 1 - # enable the PLL - mmw $CLKCORE_ARM_CLK_CNTRL 0x0 $PLL_DISABLE - sleep 1 - # set X, W and X - mmw $CLKCORE_ARM_CLK_CNTRL 0x0 0xFFFFFF - mmw $CLKCORE_ARM_CLK_CNTRL [expr (($x << 16) + ($w << 8) + $y)] 0x0 - # wait for PLL to lock - echo "Wating for Amba PLL to lock" - while {[expr [mrw $CLKCORE_PLL_STATUS] & $FCLK_PLL_LOCK] == 0} { sleep 1 } - # remove the internal PLL bypass - mmw $CLKCORE_ARM_CLK_CNTRL 0x0 $ARM_PLL_BY_CTRL - # remove PLL from BYPASS mode using MUX - mmw $CLKCORE_ARM_CLK_CNTRL 0x0 $PLL_CLK_BYPASS -} - - - -proc setupPLL {} { - echo "PLLs setup" - setupAmbaClk - setupArmClk -} - -# converted from u-boot/cpu/arm1136/bsp100.c:SoC_mem_init() -proc setupDDR2 {} { - echo "Configuring DDR2" - - set MEMORY_BASE_ADDR [regs MEMORY_BASE_ADDR] - set MEMORY_MAX_ADDR [regs MEMORY_MAX_ADDR] - set MEMORY_CR [regs MEMORY_CR] - set BLOCK_RESET_REG [regs BLOCK_RESET_REG] - set DDR_RST [regs DDR_RST] - - # put DDR controller in reset (so that it is reset and correctly configured) - # this is only necessary if DDR was previously confiured - # and not reset. - mmw $BLOCK_RESET_REG 0x0 $DDR_RST - - set M [expr 1024 * 1024] - set DDR_SZ_1024M [expr 1024 * $M] - set DDR_SZ_256M [expr 256 * $M] - set DDR_SZ_128M [expr 128 * $M] - set DDR_SZ_64M [expr 64 * $M] - # ooma_board_detect returns DDR2 memory size - set tmp [ooma_board_detect] - if {$tmp == "128M"} { - echo "DDR2 size 128MB" - set ddr_size $DDR_SZ_128M - } elseif {$tmp == "256M"} { - echo "DDR2 size 256MB" - set ddr_size $DDR_SZ_256M - } else { - echo "Don't know how to handle this DDR2 size?" - } - - # Memory setup register - mww $MEMORY_MAX_ADDR [expr ($ddr_size - 1) + $MEMORY_BASE_ADDR] - # disbale ROM remap - mww $MEMORY_CR 0x0 - # Take DDR controller out of reset - mmw $BLOCK_RESET_REG $DDR_RST 0x0 - # min. 20 ops delay - sleep 1 - - # This will setup Denali DDR2 controller - if {$tmp == "128M"} { - configureDDR2regs_128M - } elseif {$tmp == "256M"} { - configureDDR2regs_256M - } else { - echo "Don't know how to configure DDR2 setup?" - } -} - - - -proc showDDR2 {} { - - set DENALI_CTL_00_DATA [regs DENALI_CTL_00_DATA] - set DENALI_CTL_01_DATA [regs DENALI_CTL_01_DATA] - set DENALI_CTL_02_DATA [regs DENALI_CTL_02_DATA] - set DENALI_CTL_03_DATA [regs DENALI_CTL_03_DATA] - set DENALI_CTL_04_DATA [regs DENALI_CTL_04_DATA] - set DENALI_CTL_05_DATA [regs DENALI_CTL_05_DATA] - set DENALI_CTL_06_DATA [regs DENALI_CTL_06_DATA] - set DENALI_CTL_07_DATA [regs DENALI_CTL_07_DATA] - set DENALI_CTL_08_DATA [regs DENALI_CTL_08_DATA] - set DENALI_CTL_09_DATA [regs DENALI_CTL_09_DATA] - set DENALI_CTL_10_DATA [regs DENALI_CTL_10_DATA] - set DENALI_CTL_11_DATA [regs DENALI_CTL_11_DATA] - set DENALI_CTL_12_DATA [regs DENALI_CTL_12_DATA] - set DENALI_CTL_13_DATA [regs DENALI_CTL_13_DATA] - set DENALI_CTL_14_DATA [regs DENALI_CTL_14_DATA] - set DENALI_CTL_15_DATA [regs DENALI_CTL_15_DATA] - set DENALI_CTL_16_DATA [regs DENALI_CTL_16_DATA] - set DENALI_CTL_17_DATA [regs DENALI_CTL_17_DATA] - set DENALI_CTL_18_DATA [regs DENALI_CTL_18_DATA] - set DENALI_CTL_19_DATA [regs DENALI_CTL_19_DATA] - set DENALI_CTL_20_DATA [regs DENALI_CTL_20_DATA] - - set tmp [mr64bit $DENALI_CTL_00_DATA] - echo [format "DENALI_CTL_00_DATA (0x%x): 0x%08x%08x" $DENALI_CTL_00_DATA $tmp(1) $tmp(0)] - set tmp [mr64bit $DENALI_CTL_01_DATA] - echo [format "DENALI_CTL_01_DATA (0x%x): 0x%08x%08x" $DENALI_CTL_01_DATA $tmp(1) $tmp(0)] - set tmp [mr64bit $DENALI_CTL_02_DATA] - echo [format "DENALI_CTL_02_DATA (0x%x): 0x%08x%08x" $DENALI_CTL_02_DATA $tmp(1) $tmp(0)] - set tmp [mr64bit $DENALI_CTL_03_DATA] - echo [format "DENALI_CTL_03_DATA (0x%x): 0x%08x%08x" $DENALI_CTL_03_DATA $tmp(1) $tmp(0)] - set tmp [mr64bit $DENALI_CTL_04_DATA] - echo [format "DENALI_CTL_04_DATA (0x%x): 0x%08x%08x" $DENALI_CTL_04_DATA $tmp(1) $tmp(0)] - set tmp [mr64bit $DENALI_CTL_05_DATA] - echo [format "DENALI_CTL_05_DATA (0x%x): 0x%08x%08x" $DENALI_CTL_05_DATA $tmp(1) $tmp(0)] - set tmp [mr64bit $DENALI_CTL_06_DATA] - echo [format "DENALI_CTL_06_DATA (0x%x): 0x%08x%08x" $DENALI_CTL_06_DATA $tmp(1) $tmp(0)] - set tmp [mr64bit $DENALI_CTL_07_DATA] - echo [format "DENALI_CTL_07_DATA (0x%x): 0x%08x%08x" $DENALI_CTL_07_DATA $tmp(1) $tmp(0)] - set tmp [mr64bit $DENALI_CTL_08_DATA] - echo [format "DENALI_CTL_08_DATA (0x%x): 0x%08x%08x" $DENALI_CTL_08_DATA $tmp(1) $tmp(0)] - set tmp [mr64bit $DENALI_CTL_09_DATA] - echo [format "DENALI_CTL_09_DATA (0x%x): 0x%08x%08x" $DENALI_CTL_09_DATA $tmp(1) $tmp(0)] - set tmp [mr64bit $DENALI_CTL_10_DATA] - echo [format "DENALI_CTL_10_DATA (0x%x): 0x%08x%08x" $DENALI_CTL_10_DATA $tmp(1) $tmp(0)] - set tmp [mr64bit $DENALI_CTL_11_DATA] - echo [format "DENALI_CTL_11_DATA (0x%x): 0x%08x%08x" $DENALI_CTL_11_DATA $tmp(1) $tmp(0)] - set tmp [mr64bit $DENALI_CTL_12_DATA] - echo [format "DENALI_CTL_12_DATA (0x%x): 0x%08x%08x" $DENALI_CTL_12_DATA $tmp(1) $tmp(0)] - set tmp [mr64bit $DENALI_CTL_13_DATA] - echo [format "DENALI_CTL_13_DATA (0x%x): 0x%08x%08x" $DENALI_CTL_13_DATA $tmp(1) $tmp(0)] - set tmp [mr64bit $DENALI_CTL_14_DATA] - echo [format "DENALI_CTL_14_DATA (0x%x): 0x%08x%08x" $DENALI_CTL_14_DATA $tmp(1) $tmp(0)] - set tmp [mr64bit $DENALI_CTL_15_DATA] - echo [format "DENALI_CTL_15_DATA (0x%x): 0x%08x%08x" $DENALI_CTL_15_DATA $tmp(1) $tmp(0)] - set tmp [mr64bit $DENALI_CTL_16_DATA] - echo [format "DENALI_CTL_16_DATA (0x%x): 0x%08x%08x" $DENALI_CTL_16_DATA $tmp(1) $tmp(0)] - set tmp [mr64bit $DENALI_CTL_17_DATA] - echo [format "DENALI_CTL_17_DATA (0x%x): 0x%08x%08x" $DENALI_CTL_17_DATA $tmp(1) $tmp(0)] - set tmp [mr64bit $DENALI_CTL_18_DATA] - echo [format "DENALI_CTL_18_DATA (0x%x): 0x%08x%08x" $DENALI_CTL_18_DATA $tmp(1) $tmp(0)] - set tmp [mr64bit $DENALI_CTL_19_DATA] - echo [format "DENALI_CTL_19_DATA (0x%x): 0x%08x%08x" $DENALI_CTL_19_DATA $tmp(1) $tmp(0)] - set tmp [mr64bit $DENALI_CTL_20_DATA] - echo [format "DENALI_CTL_20_DATA (0x%x): 0x%08x%08x" $DENALI_CTL_20_DATA $tmp(1) $tmp(0)] - -} - -proc initC100 {} { - # this follows u-boot/cpu/arm1136/start.S - set GPIO_LOCK_REG [regs GPIO_LOCK_REG] - set GPIO_IOCTRL_REG [regs GPIO_IOCTRL_REG] - set GPIO_IOCTRL_VAL [regs GPIO_IOCTRL_VAL] - set APB_ACCESS_WS_REG [regs APB_ACCESS_WS_REG] - set ASA_ARAM_BASEADDR [regs ASA_ARAM_BASEADDR] - set ASA_ARAM_TC_CR_REG [regs ASA_ARAM_TC_CR_REG] - set ASA_EBUS_BASEADDR [regs ASA_EBUS_BASEADDR] - set ASA_EBUS_TC_CR_REG [regs ASA_EBUS_TC_CR_REG] - set ASA_TC_REQIDMAEN [regs ASA_TC_REQIDMAEN] - set ASA_TC_REQTDMEN [regs ASA_TC_REQTDMEN] - set ASA_TC_REQIPSECUSBEN [regs ASA_TC_REQIPSECUSBEN] - set ASA_TC_REQARM0EN [regs ASA_TC_REQARM0EN] - set ASA_TC_REQARM1EN [regs ASA_TC_REQARM1EN] - set ASA_TC_REQMDMAEN [regs ASA_TC_REQMDMAEN] - set INTC_ARM1_CONTROL_REG [regs INTC_ARM1_CONTROL_REG] - - - # unlock writing to IOCTRL register - mww $GPIO_LOCK_REG $GPIO_IOCTRL_VAL - # enable address lines A15-A21 - mmw $GPIO_IOCTRL_REG 0xf 0x0 - # set ARM into supervisor mode (SVC32) - # disable IRQ, FIQ - # Do I need this in JTAG mode? - # it really should be done as 'and ~0x1f | 0xd3 but - # openocd does not support this yet - reg cpsr 0xd3 - # /* - # * flush v4 I/D caches - # */ - # mov r0, #0 - # mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */ - arm mcr 15 0 7 7 0 0x0 - # mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */ - arm mcr 15 0 8 7 0 0x0 - - # /* - # * disable MMU stuff and caches - # */ - # mrc p15, 0, r0, c1, c0, 0 - arm mrc 15 0 1 0 0 - # bic r0, r0, #0x00002300 @ clear bits 13, 9:8 (--V- --RS) - # bic r0, r0, #0x00000087 @ clear bits 7, 2:0 (B--- -CAM) - # orr r0, r0, #0x00000002 @ set bit 2 (A) Align - # orr r0, r0, #0x00001000 @ set bit 12 (I) I-Cache - # orr r0, r0, #0x00400000 @ set bit 22 (U) - # mcr p15, 0, r0, c1, c0, 0 - arm mcr 15 0 1 0 0 0x401002 - # This is from bsp_init() in u-boot/boards/mindspeed/ooma-darwin/board.c - # APB init - # // Setting APB Bus Wait states to 1, set post write - # (*(volatile u32*)(APB_ACCESS_WS_REG)) = 0x40; - mww [expr $APB_ACCESS_WS_REG] 0x40 - # AHB init - # // enable all 6 masters for ARAM - mmw $ASA_ARAM_TC_CR_REG [expr $ASA_TC_REQIDMAEN | $ASA_TC_REQTDMEN | $ASA_TC_REQIPSECUSBEN | $ASA_TC_REQARM0EN | $ASA_TC_REQARM1EN | $ASA_TC_REQMDMAEN] 0x0 - # // enable all 6 masters for EBUS - mmw $ASA_EBUS_TC_CR_REG [expr $ASA_TC_REQIDMAEN | $ASA_TC_REQTDMEN | $ASA_TC_REQIPSECUSBEN | $ASA_TC_REQARM0EN | $ASA_TC_REQARM1EN | $ASA_TC_REQMDMAEN] 0x0 - - # ARAM init - # // disable pipeline mode in ARAM - # I don't think this is documented anywhere? - mww $INTC_ARM1_CONTROL_REG 0x1 - # configure clocks - setupPLL - # setupUART0 must be run before setupDDR2 as setupDDR2 uses UART. - setupUART0 - # enable cache - # ? (u-boot does nothing here) - # DDR2 memory init - setupDDR2 - putsUART0 "C100 initialization complete.\n" - echo "C100 initialization complete." -} - -# show current state of watchdog timer -proc showWatchdog {} { - set TIMER_WDT_HIGH_BOUND [regs TIMER_WDT_HIGH_BOUND] - set TIMER_WDT_CONTROL [regs TIMER_WDT_CONTROL] - set TIMER_WDT_CURRENT_COUNT [regs TIMER_WDT_CURRENT_COUNT] - - echo [format "TIMER_WDT_HIGH_BOUND (0x%x): 0x%x" $TIMER_WDT_HIGH_BOUND [mrw $TIMER_WDT_HIGH_BOUND]] - echo [format "TIMER_WDT_CONTROL (0x%x): 0x%x" $TIMER_WDT_CONTROL [mrw $TIMER_WDT_CONTROL]] - echo [format "TIMER_WDT_CURRENT_COUNT (0x%x): 0x%x" $TIMER_WDT_CURRENT_COUNT [mrw $TIMER_WDT_CURRENT_COUNT]] -} - -# converted from u-boot/cpu/arm1136/comcerto/intrrupts.c:void reset_cpu (ulong ignored) -# this will trigger watchdog reset -# the sw. reset does not work on C100 -# watchdog reset effectively works as hw. reset -proc reboot {} { - set TIMER_WDT_HIGH_BOUND [regs TIMER_WDT_HIGH_BOUND] - set TIMER_WDT_CONTROL [regs TIMER_WDT_CONTROL] - set TIMER_WDT_CURRENT_COUNT [regs TIMER_WDT_CURRENT_COUNT] - - # allow the counter to count to high value before triggering - # this is because regsiter writes are slow over JTAG and - # I don't want to miss the high_bound==curr_count condition - mww $TIMER_WDT_HIGH_BOUND 0xffffff - mww $TIMER_WDT_CURRENT_COUNT 0x0 - echo "JTAG speed lowered to 100kHz" - adapter_khz 100 - mww $TIMER_WDT_CONTROL 0x1 - # wait until the reset - echo -n "Wating for watchdog to trigger..." - #while {[mrw $TIMER_WDT_CONTROL] == 1} { - # echo [format "TIMER_WDT_CURRENT_COUNT (0x%x): 0x%x" $TIMER_WDT_CURRENT_COUNT [mrw $TIMER_WDT_CURRENT_COUNT]] - # sleep 1 - # - #} - while {[c100.cpu curstate] != "running"} { sleep 1} - echo "done." - echo [format "Note that C100 is in %s state, type halt to stop" [c100.cpu curstate]] -} diff --git a/tcl/target/c100regs.tcl b/tcl/target/c100regs.tcl deleted file mode 100644 index a2c7a60d0..000000000 --- a/tcl/target/c100regs.tcl +++ /dev/null @@ -1,493 +0,0 @@ -# Note that I basically converted -# u-boot/include/asm-arm/arch/comcerto_100.h -# defines - -# this is a work-around for 'global' not working under Linux -# access registers by calling this routine. -# For example: -# set EX_CS_TMG1_REG [regs EX_CS0_TMG1_REG] -proc regs {reg} { - return [dict get [regsC100] $reg ] -} - -proc showreg {reg} { - echo [format "0x%x" [dict get [regsC100] $reg ]] -} - -proc regsC100 {} { -#/* memcore */ -#/* device memory base addresses */ -#// device memory sizes -#/* ARAM SIZE=64K */ -dict set regsC100 ARAM_SIZE 0x00010000 -dict set regsC100 ARAM_BASEADDR 0x0A000000 - -#/* Hardware Interface Units */ -dict set regsC100 APB_BASEADDR 0x10000000 -#/* APB_SIZE=16M address range */ -dict set regsC100 APB_SIZE 0x01000000 - -dict set regsC100 EXP_CS0_BASEADDR 0x20000000 -dict set regsC100 EXP_CS1_BASEADDR 0x24000000 -dict set regsC100 EXP_CS2_BASEADDR 0x28000000 -dict set regsC100 EXP_CS3_BASEADDR 0x2C000000 -dict set regsC100 EXP_CS4_BASEADDR 0x30000000 - -dict set regsC100 DDR_BASEADDR 0x80000000 - -dict set regsC100 TDM_BASEADDR [expr [dict get $regsC100 APB_BASEADDR ] + 0x000000] -dict set regsC100 PHI_BASEADDR [expr [dict get $regsC100 APB_BASEADDR ] + 0x010000] -dict set regsC100 TDMA_BASEADDR [expr [dict get $regsC100 APB_BASEADDR ] + 0x020000] -dict set regsC100 ASA_DDR_BASEADDR [expr [dict get $regsC100 APB_BASEADDR ] + 0x040000] -dict set regsC100 ASA_ARAM_BASEADDR [expr [dict get $regsC100 APB_BASEADDR ] + 0x048000] -dict set regsC100 TIMER_BASEADDR [expr [dict get $regsC100 APB_BASEADDR ] + 0x050000] -dict set regsC100 ASD_BASEADDR [expr [dict get $regsC100 APB_BASEADDR ] + 0x060000] -dict set regsC100 GPIO_BASEADDR [expr [dict get $regsC100 APB_BASEADDR ] + 0x070000] -dict set regsC100 UART0_BASEADDR [expr [dict get $regsC100 APB_BASEADDR ] + 0x090000] -dict set regsC100 UART1_BASEADDR [expr [dict get $regsC100 APB_BASEADDR ] + 0x094000] -dict set regsC100 SPI_BASEADDR [expr [dict get $regsC100 APB_BASEADDR ] + 0x098000] -dict set regsC100 I2C_BASEADDR [expr [dict get $regsC100 APB_BASEADDR ] + 0x09C000] -dict set regsC100 INTC_BASEADDR [expr [dict get $regsC100 APB_BASEADDR ] + 0x0A0000] -dict set regsC100 CLKCORE_BASEADDR [expr [dict get $regsC100 APB_BASEADDR ] + 0x0B0000] -dict set regsC100 PUI_BASEADDR [expr [dict get $regsC100 APB_BASEADDR ] + 0x0B0000] -dict set regsC100 GEMAC_BASEADDR [expr [dict get $regsC100 APB_BASEADDR ] + 0x0D0000] -dict set regsC100 IDMA_BASEADDR [expr [dict get $regsC100 APB_BASEADDR ] + 0x0E0000] -dict set regsC100 MEMCORE_BASEADDR [expr [dict get $regsC100 APB_BASEADDR ] + 0x0F0000] -dict set regsC100 ASA_EBUS_BASEADDR [expr [dict get $regsC100 APB_BASEADDR ] + 0x100000] -dict set regsC100 ASA_AAB_BASEADDR [expr [dict get $regsC100 APB_BASEADDR ] + 0x108000] -dict set regsC100 GEMAC1_BASEADDR [expr [dict get $regsC100 APB_BASEADDR ] + 0x190000] -dict set regsC100 EBUS_BASEADDR [expr [dict get $regsC100 APB_BASEADDR ] + 0x1A0000] -dict set regsC100 MDMA_BASEADDR [expr [dict get $regsC100 APB_BASEADDR ] + 0x1E0000] - - -#//////////////////////////////////////////////////////////// -#// AHB block // -#//////////////////////////////////////////////////////////// -dict set regsC100 ASA_ARAM_PRI_REG [expr [dict get $regsC100 ASA_ARAM_BASEADDR ] + 0x00] -dict set regsC100 ASA_ARAM_TC_REG [expr [dict get $regsC100 ASA_ARAM_BASEADDR ] + 0x04] -dict set regsC100 ASA_ARAM_TC_CR_REG [expr [dict get $regsC100 ASA_ARAM_BASEADDR ] + 0x08] -dict set regsC100 ASA_ARAM_STAT_REG [expr [dict get $regsC100 ASA_ARAM_BASEADDR ] + 0x0C] - -dict set regsC100 ASA_EBUS_PRI_REG [expr [dict get $regsC100 ASA_EBUS_BASEADDR ] + 0x00] -dict set regsC100 ASA_EBUS_TC_REG [expr [dict get $regsC100 ASA_EBUS_BASEADDR ] + 0x04] -dict set regsC100 ASA_EBUS_TC_CR_REG [expr [dict get $regsC100 ASA_EBUS_BASEADDR ] + 0x08] -dict set regsC100 ASA_EBUS_STAT_REG [expr [dict get $regsC100 ASA_EBUS_BASEADDR ] + 0x0C] - -dict set regsC100 IDMA_MASTER 0 -dict set regsC100 TDMA_MASTER 1 -dict set regsC100 USBIPSEC_MASTER 2 -dict set regsC100 ARM0_MASTER 3 -dict set regsC100 ARM1_MASTER 4 -dict set regsC100 MDMA_MASTER 5 - -#define IDMA_PRIORITY(level) (level) -#define TDM_PRIORITY(level) (level << 4) -#define USBIPSEC_PRIORITY(level) (level << 8) -#define ARM0_PRIORITY(level) (level << 12) -#define ARM1_PRIORITY(level) (level << 16) -#define MDMA_PRIORITY(level) (level << 20) - -dict set regsC100 ASA_TC_REQIDMAEN [expr 1<<18] -dict set regsC100 ASA_TC_REQTDMEN [expr 1<<19] -dict set regsC100 ASA_TC_REQIPSECUSBEN [expr 1<<20] -dict set regsC100 ASA_TC_REQARM0EN [expr 1<<21] -dict set regsC100 ASA_TC_REQARM1EN [expr 1<<22] -dict set regsC100 ASA_TC_REQMDMAEN [expr 1<<23] - -dict set regsC100 MEMORY_BASE_ADDR 0x80000000 -dict set regsC100 MEMORY_MAX_ADDR [expr [dict get $regsC100 ASD_BASEADDR ] + 0x10] -dict set regsC100 MEMORY_CR [expr [dict get $regsC100 ASD_BASEADDR ] + 0x14] -dict set regsC100 ROM_REMAP_EN 0x1 - -#define HAL_asb_priority(level) \ -#*(volatile unsigned *)ASA_PRI_REG = level - -#define HAL_aram_priority(level) \ -#*(volatile unsigned *)ASA_ARAM_PRI_REG = level - -#define HAL_aram_arbitration(arbitration_mask) \ -#*(volatile unsigned *)ASA_ARAM_TC_CR_REG |= arbitration_mask - -#define HAL_aram_defmaster(mask) \ -#*(volatile unsigned *)ASA_ARAM_TC_CR_REG = (*(volatile unsigned *)ASA_TC_CR_REG & 0xFFFF) | (mask << 24) - -#//////////////////////////////////////////////////////////// -#// INTC block // -#//////////////////////////////////////////////////////////// - -dict set regsC100 INTC_ARM1_CONTROL_REG [expr [dict get $regsC100 INTC_BASEADDR ] + 0x18] - -#//////////////////////////////////////////////////////////// -#// TIMER block // -#//////////////////////////////////////////////////////////// - -dict set regsC100 TIMER0_CNTR_REG [expr [dict get $regsC100 TIMER_BASEADDR ] + 0x00] -dict set regsC100 TIMER0_CURR_COUNT [expr [dict get $regsC100 TIMER_BASEADDR ] + 0x04] -dict set regsC100 TIMER1_CNTR_REG [expr [dict get $regsC100 TIMER_BASEADDR ] + 0x08] -dict set regsC100 TIMER1_CURR_COUNT [expr [dict get $regsC100 TIMER_BASEADDR ] + 0x0C] - -dict set regsC100 TIMER2_CNTR_REG [expr [dict get $regsC100 TIMER_BASEADDR ] + 0x18] -dict set regsC100 TIMER2_LBOUND_REG [expr [dict get $regsC100 TIMER_BASEADDR ] + 0x10] -dict set regsC100 TIMER2_HBOUND_REG [expr [dict get $regsC100 TIMER_BASEADDR ] + 0x14] -dict set regsC100 TIMER2_CURR_COUNT [expr [dict get $regsC100 TIMER_BASEADDR ] + 0x1C] - -dict set regsC100 TIMER3_LOBND [expr [dict get $regsC100 TIMER_BASEADDR ] + 0x20] -dict set regsC100 TIMER3_HIBND [expr [dict get $regsC100 TIMER_BASEADDR ] + 0x24] -dict set regsC100 TIMER3_CTRL [expr [dict get $regsC100 TIMER_BASEADDR ] + 0x28] -dict set regsC100 TIMER3_CURR_COUNT [expr [dict get $regsC100 TIMER_BASEADDR ] + 0x2C] - -dict set regsC100 TIMER_MASK [expr [dict get $regsC100 TIMER_BASEADDR ] + 0x40] -dict set regsC100 TIMER_STATUS [expr [dict get $regsC100 TIMER_BASEADDR ] + 0x50] -dict set regsC100 TIMER_ACK [expr [dict get $regsC100 TIMER_BASEADDR ] + 0x50] -dict set regsC100 TIMER_WDT_HIGH_BOUND [expr [dict get $regsC100 TIMER_BASEADDR ] + 0xD0] -dict set regsC100 TIMER_WDT_CONTROL [expr [dict get $regsC100 TIMER_BASEADDR ] + 0xD4] -dict set regsC100 TIMER_WDT_CURRENT_COUNT [expr [dict get $regsC100 TIMER_BASEADDR ] + 0xD8] - - - -#//////////////////////////////////////////////////////////// -#// EBUS block -#//////////////////////////////////////////////////////////// - -dict set regsC100 EX_SWRST_REG [expr [dict get $regsC100 EBUS_BASEADDR ] + 0x00] -dict set regsC100 EX_CSEN_REG [expr [dict get $regsC100 EBUS_BASEADDR ] + 0x04] -dict set regsC100 EX_CS0_SEG_REG [expr [dict get $regsC100 EBUS_BASEADDR ] + 0x08] -dict set regsC100 EX_CS1_SEG_REG [expr [dict get $regsC100 EBUS_BASEADDR ] + 0x0C] -dict set regsC100 EX_CS2_SEG_REG [expr [dict get $regsC100 EBUS_BASEADDR ] + 0x10] -dict set regsC100 EX_CS3_SEG_REG [expr [dict get $regsC100 EBUS_BASEADDR ] + 0x14] -dict set regsC100 EX_CS4_SEG_REG [expr [dict get $regsC100 EBUS_BASEADDR ] + 0x18] -dict set regsC100 EX_CS0_CFG_REG [expr [dict get $regsC100 EBUS_BASEADDR ] + 0x1C] -dict set regsC100 EX_CS1_CFG_REG [expr [dict get $regsC100 EBUS_BASEADDR ] + 0x20] -dict set regsC100 EX_CS2_CFG_REG [expr [dict get $regsC100 EBUS_BASEADDR ] + 0x24] -dict set regsC100 EX_CS3_CFG_REG [expr [dict get $regsC100 EBUS_BASEADDR ] + 0x28] -dict set regsC100 EX_CS4_CFG_REG [expr [dict get $regsC100 EBUS_BASEADDR ] + 0x2C] -dict set regsC100 EX_CS0_TMG1_REG [expr [dict get $regsC100 EBUS_BASEADDR ] + 0x30] -dict set regsC100 EX_CS1_TMG1_REG [expr [dict get $regsC100 EBUS_BASEADDR ] + 0x34] -dict set regsC100 EX_CS2_TMG1_REG [expr [dict get $regsC100 EBUS_BASEADDR ] + 0x38] -dict set regsC100 EX_CS3_TMG1_REG [expr [dict get $regsC100 EBUS_BASEADDR ] + 0x3C] -dict set regsC100 EX_CS4_TMG1_REG [expr [dict get $regsC100 EBUS_BASEADDR ] + 0x40] -dict set regsC100 EX_CS0_TMG2_REG [expr [dict get $regsC100 EBUS_BASEADDR ] + 0x44] -dict set regsC100 EX_CS1_TMG2_REG [expr [dict get $regsC100 EBUS_BASEADDR ] + 0x48] -dict set regsC100 EX_CS2_TMG2_REG [expr [dict get $regsC100 EBUS_BASEADDR ] + 0x4C] -dict set regsC100 EX_CS3_TMG2_REG [expr [dict get $regsC100 EBUS_BASEADDR ] + 0x50] -dict set regsC100 EX_CS4_TMG2_REG [expr [dict get $regsC100 EBUS_BASEADDR ] + 0x54] -dict set regsC100 EX_CS0_TMG3_REG [expr [dict get $regsC100 EBUS_BASEADDR ] + 0x58] -dict set regsC100 EX_CS1_TMG3_REG [expr [dict get $regsC100 EBUS_BASEADDR ] + 0x5C] -dict set regsC100 EX_CS2_TMG3_REG [expr [dict get $regsC100 EBUS_BASEADDR ] + 0x60] -dict set regsC100 EX_CS3_TMG3_REG [expr [dict get $regsC100 EBUS_BASEADDR ] + 0x64] -dict set regsC100 EX_CS4_TMG3_REG [expr [dict get $regsC100 EBUS_BASEADDR ] + 0x68] -dict set regsC100 EX_CLOCK_DIV_REG [expr [dict get $regsC100 EBUS_BASEADDR ] + 0x6C] - -dict set regsC100 EX_MFSM_REG [expr [dict get $regsC100 EBUS_BASEADDR] + 0x100] -dict set regsC100 EX_MFSM_REG [expr [dict get $regsC100 EBUS_BASEADDR] + 0x100] -dict set regsC100 EX_CSFSM_REG [expr [dict get $regsC100 EBUS_BASEADDR] + 0x104] -dict set regsC100 EX_WRFSM_REG [expr [dict get $regsC100 EBUS_BASEADDR] + 0x108] -dict set regsC100 EX_RDFSM_REG [expr [dict get $regsC100 EBUS_BASEADDR] + 0x10C] - - -dict set regsC100 EX_CLK_EN 0x00000001 -dict set regsC100 EX_CSBOOT_EN 0x00000002 -dict set regsC100 EX_CS0_EN 0x00000002 -dict set regsC100 EX_CS1_EN 0x00000004 -dict set regsC100 EX_CS2_EN 0x00000008 -dict set regsC100 EX_CS3_EN 0x00000010 -dict set regsC100 EX_CS4_EN 0x00000020 - -dict set regsC100 EX_MEM_BUS_8 0x00000000 -dict set regsC100 EX_MEM_BUS_16 0x00000002 -dict set regsC100 EX_MEM_BUS_32 0x00000004 -dict set regsC100 EX_CS_HIGH 0x00000008 -dict set regsC100 EX_WE_HIGH 0x00000010 -dict set regsC100 EX_RE_HIGH 0x00000020 -dict set regsC100 EX_ALE_MODE 0x00000040 -dict set regsC100 EX_STRB_MODE 0x00000080 -dict set regsC100 EX_DM_MODE 0x00000100 -dict set regsC100 EX_NAND_MODE 0x00000200 -dict set regsC100 EX_RDY_EN 0x00000400 -dict set regsC100 EX_RDY_EDGE 0x00000800 - -#//////////////////////////////////////////////////////////// -#// GPIO block -#//////////////////////////////////////////////////////////// - -# GPIO outputs register -dict set regsC100 GPIO_OUTPUT_REG [expr [dict get $regsC100 GPIO_BASEADDR ] + 0x00] -# GPIO Output Enable register -dict set regsC100 GPIO_OE_REG [expr [dict get $regsC100 GPIO_BASEADDR ] + 0x04] -dict set regsC100 GPIO_HI_INT_ENABLE_REG [expr [dict get $regsC100 GPIO_BASEADDR ] + 0x08] -dict set regsC100 GPIO_LO_INT_ENABLE_REG [expr [dict get $regsC100 GPIO_BASEADDR ] + 0x0C] -# GPIO input register -dict set regsC100 GPIO_INPUT_REG [expr [dict get $regsC100 GPIO_BASEADDR ] + 0x10] -dict set regsC100 APB_ACCESS_WS_REG [expr [dict get $regsC100 GPIO_BASEADDR ] + 0x14] -dict set regsC100 MUX_CONF_REG [expr [dict get $regsC100 GPIO_BASEADDR ] + 0x18] -dict set regsC100 SYSCONF_REG [expr [dict get $regsC100 GPIO_BASEADDR ] + 0x1C] -dict set regsC100 GPIO_ARM_ID_REG [expr [dict get $regsC100 GPIO_BASEADDR ] + 0x30] -dict set regsC100 GPIO_BOOTSTRAP_REG [expr [dict get $regsC100 GPIO_BASEADDR ] + 0x40] -dict set regsC100 GPIO_LOCK_REG [expr [dict get $regsC100 GPIO_BASEADDR ] + 0x38] -dict set regsC100 GPIO_IOCTRL_REG [expr [dict get $regsC100 GPIO_BASEADDR ] + 0x44] -dict set regsC100 GPIO_DEVID_REG [expr [dict get $regsC100 GPIO_BASEADDR ] + 0x50] - -dict set regsC100 GPIO_IOCTRL_A15A16 0x00000001 -dict set regsC100 GPIO_IOCTRL_A17A18 0x00000002 -dict set regsC100 GPIO_IOCTRL_A19A21 0x00000004 -dict set regsC100 GPIO_IOCTRL_TMREVT0 0x00000008 -dict set regsC100 GPIO_IOCTRL_TMREVT1 0x00000010 -dict set regsC100 GPIO_IOCTRL_GPBT3 0x00000020 -dict set regsC100 GPIO_IOCTRL_I2C 0x00000040 -dict set regsC100 GPIO_IOCTRL_UART0 0x00000080 -dict set regsC100 GPIO_IOCTRL_UART1 0x00000100 -dict set regsC100 GPIO_IOCTRL_SPI 0x00000200 -dict set regsC100 GPIO_IOCTRL_HBMODE 0x00000400 - -dict set regsC100 GPIO_IOCTRL_VAL 0x55555555 - -dict set regsC100 GPIO_0 0x01 -dict set regsC100 GPIO_1 0x02 -dict set regsC100 GPIO_2 0x04 -dict set regsC100 GPIO_3 0x08 -dict set regsC100 GPIO_4 0x10 -dict set regsC100 GPIO_5 0x20 -dict set regsC100 GPIO_6 0x40 -dict set regsC100 GPIO_7 0x80 - -dict set regsC100 GPIO_RISING_EDGE 1 -dict set regsC100 GPIO_FALLING_EDGE 2 -dict set regsC100 GPIO_BOTH_EDGES 3 - -#//////////////////////////////////////////////////////////// -#// UART -#//////////////////////////////////////////////////////////// - -dict set regsC100 UART0_RBR [expr [dict get $regsC100 UART0_BASEADDR ] + 0x00] -dict set regsC100 UART0_THR [expr [dict get $regsC100 UART0_BASEADDR ] + 0x00] -dict set regsC100 UART0_DLL [expr [dict get $regsC100 UART0_BASEADDR ] + 0x00] -dict set regsC100 UART0_IER [expr [dict get $regsC100 UART0_BASEADDR ] + 0x04] -dict set regsC100 UART0_DLH [expr [dict get $regsC100 UART0_BASEADDR ] + 0x04] -dict set regsC100 UART0_IIR [expr [dict get $regsC100 UART0_BASEADDR ] + 0x08] -dict set regsC100 UART0_FCR [expr [dict get $regsC100 UART0_BASEADDR ] + 0x08] -dict set regsC100 UART0_LCR [expr [dict get $regsC100 UART0_BASEADDR ] + 0x0C] -dict set regsC100 UART0_MCR [expr [dict get $regsC100 UART0_BASEADDR ] + 0x10] -dict set regsC100 UART0_LSR [expr [dict get $regsC100 UART0_BASEADDR ] + 0x14] -dict set regsC100 UART0_MSR [expr [dict get $regsC100 UART0_BASEADDR ] + 0x18] -dict set regsC100 UART0_SCR [expr [dict get $regsC100 UART0_BASEADDR ] + 0x1C] - -dict set regsC100 UART1_RBR [expr [dict get $regsC100 UART1_BASEADDR ] + 0x00] -dict set regsC100 UART1_THR [expr [dict get $regsC100 UART1_BASEADDR ] + 0x00] -dict set regsC100 UART1_DLL [expr [dict get $regsC100 UART1_BASEADDR ] + 0x00] -dict set regsC100 UART1_IER [expr [dict get $regsC100 UART1_BASEADDR ] + 0x04] -dict set regsC100 UART1_DLH [expr [dict get $regsC100 UART1_BASEADDR ] + 0x04] -dict set regsC100 UART1_IIR [expr [dict get $regsC100 UART1_BASEADDR ] + 0x08] -dict set regsC100 UART1_FCR [expr [dict get $regsC100 UART1_BASEADDR ] + 0x08] -dict set regsC100 UART1_LCR [expr [dict get $regsC100 UART1_BASEADDR ] + 0x0C] -dict set regsC100 UART1_MCR [expr [dict get $regsC100 UART1_BASEADDR ] + 0x10] -dict set regsC100 UART1_LSR [expr [dict get $regsC100 UART1_BASEADDR ] + 0x14] -dict set regsC100 UART1_MSR [expr [dict get $regsC100 UART1_BASEADDR ] + 0x18] -dict set regsC100 UART1_SCR [expr [dict get $regsC100 UART1_BASEADDR ] + 0x1C] - -# /* default */ -dict set regsC100 LCR_CHAR_LEN_5 0x00 -dict set regsC100 LCR_CHAR_LEN_6 0x01 -dict set regsC100 LCR_CHAR_LEN_7 0x02 -dict set regsC100 LCR_CHAR_LEN_8 0x03 -#/* One stop bit! - default */ -dict set regsC100 LCR_ONE_STOP 0x00 -#/* Two stop bit! */ -dict set regsC100 LCR_TWO_STOP 0x04 -#/* Parity Enable */ -dict set regsC100 LCR_PEN 0x08 -dict set regsC100 LCR_PARITY_NONE 0x00 -#/* Even Parity Select */ -dict set regsC100 LCR_EPS 0x10 -#/* Enable Parity Stuff */ -dict set regsC100 LCR_PS 0x20 -#/* Start Break */ -dict set regsC100 LCR_SBRK 0x40 -#/* Parity Stuff Bit */ -dict set regsC100 LCR_PSB 0x80 -#/* UART 16550 Divisor Latch Assess */ -dict set regsC100 LCR_DLAB 0x80 - -#/* FIFO Error Status */ -dict set regsC100 LSR_FIFOE [expr 1 << 7] -#/* Transmitter Empty */ -dict set regsC100 LSR_TEMT [expr 1 << 6] -#/* Transmit Data Request */ -dict set regsC100 LSR_TDRQ [expr 1 << 5] -#/* Break Interrupt */ -dict set regsC100 LSR_BI [expr 1 << 4] -#/* Framing Error */ -dict set regsC100 LSR_FE [expr 1 << 3] -#/* Parity Error */ -dict set regsC100 LSR_PE [expr 1 << 2] -#/* Overrun Error */ -dict set regsC100 LSR_OE [expr 1 << 1] -#/* Data Ready */ -dict set regsC100 LSR_DR [expr 1 << 0] - -#/* DMA Requests Enable */ -dict set regsC100 IER_DMAE [expr 1 << 7] -#/* UART Unit Enable */ -dict set regsC100 IER_UUE [expr 1 << 6] -#/* NRZ coding Enable */ -dict set regsC100 IER_NRZE [expr 1 << 5] -#/* Receiver Time Out Interrupt Enable */ -dict set regsC100 IER_RTIOE [expr 1 << 4] -#/* Modem Interrupt Enable */ -dict set regsC100 IER_MIE [expr 1 << 3] -#/* Receiver Line Status Interrupt Enable */ -dict set regsC100 IER_RLSE [expr 1 << 2] -#/* Transmit Data request Interrupt Enable */ -dict set regsC100 IER_TIE [expr 1 << 1] -#/* Receiver Data Available Interrupt Enable */ -dict set regsC100 IER_RAVIE [expr 1 << 0] - -#/* FIFO Mode Enable Status */ -dict set regsC100 IIR_FIFOES1 [expr 1 << 7] -#/* FIFO Mode Enable Status */ -dict set regsC100 IIR_FIFOES0 [expr 1 << 6] -#/* Time Out Detected */ -dict set regsC100 IIR_TOD [expr 1 << 3] -#/* Interrupt Source Encoded */ -dict set regsC100 IIR_IID2 [expr 1 << 2] -#/* Interrupt Source Encoded */ -dict set regsC100 IIR_IID1 [expr 1 << 1] -#/* Interrupt Pending (active low) */ -dict set regsC100 IIR_IP [expr 1 << 0] - -#/* UART 16550 FIFO Control Register */ -dict set regsC100 FCR_FIFOEN 0x01 -dict set regsC100 FCR_RCVRRES 0x02 -dict set regsC100 FCR_XMITRES 0x04 - -#/* Interrupt Enable Register */ -#// UART 16550 -#// Enable Received Data Available Interrupt -dict set regsC100 IER_RXTH 0x01 -#// Enable Transmitter Empty Interrupt -dict set regsC100 IER_TXTH 0x02 - - - -#//////////////////////////////////////////////////////////// -#// CLK + RESET block -#//////////////////////////////////////////////////////////// - -dict set regsC100 CLKCORE_ARM_CLK_CNTRL [expr [dict get $regsC100 CLKCORE_BASEADDR ] + 0x00] -dict set regsC100 CLKCORE_AHB_CLK_CNTRL [expr [dict get $regsC100 CLKCORE_BASEADDR ] + 0x04] -dict set regsC100 CLKCORE_PLL_STATUS [expr [dict get $regsC100 CLKCORE_BASEADDR ] + 0x08] -dict set regsC100 CLKCORE_CLKDIV_CNTRL [expr [dict get $regsC100 CLKCORE_BASEADDR ] + 0x0C] -dict set regsC100 CLKCORE_TDM_CLK_CNTRL [expr [dict get $regsC100 CLKCORE_BASEADDR ] + 0x10] -dict set regsC100 CLKCORE_FSYNC_CNTRL [expr [dict get $regsC100 CLKCORE_BASEADDR ] + 0x14] -dict set regsC100 CLKCORE_CLK_PWR_DWN [expr [dict get $regsC100 CLKCORE_BASEADDR ] + 0x18] -dict set regsC100 CLKCORE_RNG_CNTRL [expr [dict get $regsC100 CLKCORE_BASEADDR ] + 0x1C] -dict set regsC100 CLKCORE_RNG_STATUS [expr [dict get $regsC100 CLKCORE_BASEADDR ] + 0x20] -dict set regsC100 CLKCORE_ARM_CLK_CNTRL2 [expr [dict get $regsC100 CLKCORE_BASEADDR ] + 0x24] -dict set regsC100 CLKCORE_TDM_REF_DIV_RST [expr [dict get $regsC100 CLKCORE_BASEADDR ] + 0x40] - -dict set regsC100 ARM_PLL_BY_CTRL 0x80000000 -dict set regsC100 ARM_AHB_BYP 0x04000000 -dict set regsC100 PLL_DISABLE 0x02000000 -dict set regsC100 PLL_CLK_BYPASS 0x01000000 - -dict set regsC100 AHB_PLL_BY_CTRL 0x80000000 -dict set regsC100 DIV_BYPASS 0x40000000 -dict set regsC100 SYNC_MODE 0x20000000 - -dict set regsC100 EPHY_CLKDIV_BYPASS 0x00200000 -dict set regsC100 EPHY_CLKDIV_RATIO_SHIFT 16 -dict set regsC100 PUI_CLKDIV_BYPASS 0x00004000 -dict set regsC100 PUI_CLKDIV_SRCCLK 0x00002000 -dict set regsC100 PUI_CLKDIV_RATIO_SHIFT 8 -dict set regsC100 PCI_CLKDIV_BYPASS 0x00000020 -dict set regsC100 PCI_CLKDIV_RATIO_SHIFT 0 - -dict set regsC100 ARM0_CLK_PD 0x00200000 -dict set regsC100 ARM1_CLK_PD 0x00100000 -dict set regsC100 EPHY_CLK_PD 0x00080000 -dict set regsC100 TDM_CLK_PD 0x00040000 -dict set regsC100 PUI_CLK_PD 0x00020000 -dict set regsC100 PCI_CLK_PD 0x00010000 -dict set regsC100 MDMA_AHBCLK_PD 0x00000400 -dict set regsC100 I2CSPI_AHBCLK_PD 0x00000200 -dict set regsC100 UART_AHBCLK_PD 0x00000100 -dict set regsC100 IPSEC_AHBCLK_PD 0x00000080 -dict set regsC100 TDM_AHBCLK_PD 0x00000040 -dict set regsC100 USB1_AHBCLK_PD 0x00000020 -dict set regsC100 USB0_AHBCLK_PD 0x00000010 -dict set regsC100 GEMAC1_AHBCLK_PD 0x00000008 -dict set regsC100 GEMAC0_AHBCLK_PD 0x00000004 -dict set regsC100 PUI_AHBCLK_PD 0x00000002 -dict set regsC100 HIF_AHBCLK_PD 0x00000001 - -dict set regsC100 ARM1_DIV_BP 0x00001000 -dict set regsC100 ARM1_DIV_VAL_SHIFT 8 -dict set regsC100 ARM0_DIV_BP 0x00000010 -dict set regsC100 ARM0_DIV_VAL_SHIFT 0 - -dict set regsC100 AHBCLK_PLL_LOCK 0x00000002 -dict set regsC100 FCLK_PLL_LOCK 0x00000001 - - -#// reset block -dict set regsC100 BLOCK_RESET_REG [expr [dict get $regsC100 CLKCORE_BASEADDR ] + 0x100] -dict set regsC100 CSP_RESET_REG [expr [dict get $regsC100 CLKCORE_BASEADDR ] + 0x104] - -dict set regsC100 RNG_RST 0x1000 -dict set regsC100 IPSEC_RST 0x0800 -dict set regsC100 DDR_RST 0x0400 -dict set regsC100 USB1_PHY_RST 0x0200 -dict set regsC100 USB0_PHY_RST 0x0100 -dict set regsC100 USB1_RST 0x0080 -dict set regsC100 USB0_RST 0x0040 -dict set regsC100 GEMAC1_RST 0x0020 -dict set regsC100 GEMAC0_RST 0x0010 -dict set regsC100 TDM_RST 0x0008 -dict set regsC100 PUI_RST 0x0004 -dict set regsC100 HIF_RST 0x0002 -dict set regsC100 PCI_RST 0x0001 - -#//////////////////////////////////////////////////////////////// -#// DDR CONTROLLER block -#//////////////////////////////////////////////////////////////// - -dict set regsC100 DDR_CONFIG_BASEADDR 0x0D000000 -dict set regsC100 DENALI_CTL_00_DATA [expr [dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x00] -dict set regsC100 DENALI_CTL_01_DATA [expr [dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x08] -dict set regsC100 DENALI_CTL_02_DATA [expr [dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x10] -dict set regsC100 DENALI_CTL_03_DATA [expr [dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x18] -dict set regsC100 DENALI_CTL_04_DATA [expr [dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x20] -dict set regsC100 DENALI_CTL_05_DATA [expr [dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x28] -dict set regsC100 DENALI_CTL_06_DATA [expr [dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x30] -dict set regsC100 DENALI_CTL_07_DATA [expr [dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x38] -dict set regsC100 DENALI_CTL_08_DATA [expr [dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x40] -dict set regsC100 DENALI_CTL_09_DATA [expr [dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x48] -dict set regsC100 DENALI_CTL_10_DATA [expr [dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x50] -dict set regsC100 DENALI_CTL_11_DATA [expr [dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x58] -dict set regsC100 DENALI_CTL_12_DATA [expr [dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x60] -dict set regsC100 DENALI_CTL_13_DATA [expr [dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x68] -dict set regsC100 DENALI_CTL_14_DATA [expr [dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x70] -dict set regsC100 DENALI_CTL_15_DATA [expr [dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x78] -dict set regsC100 DENALI_CTL_16_DATA [expr [dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x80] -dict set regsC100 DENALI_CTL_17_DATA [expr [dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x88] -dict set regsC100 DENALI_CTL_18_DATA [expr [dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x90] -dict set regsC100 DENALI_CTL_19_DATA [expr [dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x98] -dict set regsC100 DENALI_CTL_20_DATA [expr [dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0xA0] - -# 32-bit value -dict set regsC100 DENALI_READY_CHECK [expr [dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x44] -# 8-bit -dict set regsC100 DENALI_WR_DQS [expr [dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x5D] -# 8-bit -dict set regsC100 DENALI_DQS_OUT [expr [dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x5A] -# 8-bit -dict set regsC100 DENALI_DQS_DELAY0 [expr [dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x4F] -# 8-bit -dict set regsC100 DENALI_DQS_DELAY1 [expr [dict get $regsC100 DDR_CONFIG_BASEADDR ] +0x50] -# 8-bit -dict set regsC100 DENALI_DQS_DELAY2 [expr [dict get $regsC100 DDR_CONFIG_BASEADDR ] +0x51] -# 8-bit -dict set regsC100 DENALI_DQS_DELAY3 [expr [dict get $regsC100 DDR_CONFIG_BASEADDR ] +0x52] - - -# end of proc regsC100 -} diff --git a/tcl/target/cc2538.cfg b/tcl/target/cc2538.cfg deleted file mode 100755 index 81593c105..000000000 --- a/tcl/target/cc2538.cfg +++ /dev/null @@ -1,16 +0,0 @@ -# Config for Texas Instruments low power RF SoC CC2538 -# http://www.ti.com/lit/pdf/swru319 - -if { [info exists CHIPNAME] } { - set CHIPNAME $CHIPNAME -} else { - set CHIPNAME cc2538 -} - -if { [info exists JRC_TAPID] } { - set JRC_TAPID $JRC_TAPID -} else { - set JRC_TAPID 0x8B96402F -} - -source [find target/cc26xx.cfg] diff --git a/tcl/target/cc26xx.cfg b/tcl/target/cc26xx.cfg deleted file mode 100755 index 1492e6a22..000000000 --- a/tcl/target/cc26xx.cfg +++ /dev/null @@ -1,43 +0,0 @@ -# Config for Texas Instruments low power SoC CC26xx family - -adapter_khz 100 - -source [find target/icepick.cfg] -source [find target/ti-cjtag.cfg] - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME cc26xx -} - -# -# Main DAP -# -if { [info exists DAP_TAPID] } { - set _DAP_TAPID $DAP_TAPID -} else { - set _DAP_TAPID 0x4BA00477 -} -jtag newtap $_CHIPNAME dap -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_DAP_TAPID -disable -jtag configure $_CHIPNAME.dap -event tap-enable "icepick_c_tapenable $_CHIPNAME.jrc 0" - -# -# ICEpick-C (JTAG route controller) -# -if { [info exists JRC_TAPID] } { - set _JRC_TAPID $JRC_TAPID -} else { - set _JRC_TAPID 0x1B99A02F -} -jtag newtap $_CHIPNAME jrc -irlen 6 -ircapture 0x1 -irmask 0x3f -expected-id $_JRC_TAPID -ignore-version -# A start sequence is needed to change from cJTAG (Compact JTAG) to -# 4-pin JTAG before talking via JTAG commands -jtag configure $_CHIPNAME.jrc -event setup "jtag tapenable $_CHIPNAME.dap" -jtag configure $_CHIPNAME.jrc -event post-reset "ti_cjtag_to_4pin_jtag $_CHIPNAME.jrc" - -# -# Cortex-M3 target -# -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME cortex_m -chain-position $_CHIPNAME.dap diff --git a/tcl/target/cc32xx.cfg b/tcl/target/cc32xx.cfg deleted file mode 100755 index 154bf9106..000000000 --- a/tcl/target/cc32xx.cfg +++ /dev/null @@ -1,53 +0,0 @@ -# Config for Texas Instruments SoC CC32xx family - -source [find target/swj-dp.tcl] - -adapter_khz 100 - -source [find target/icepick.cfg] - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME cc32xx -} - -# -# Main DAP -# -if { [info exists DAP_TAPID] } { - set _DAP_TAPID $DAP_TAPID -} else { - if {[using_jtag]} { - set _DAP_TAPID 0x4BA00477 - } else { - set _DAP_TAPID 0x2BA01477 - } -} - -if {[using_jtag]} { - jtag newtap $_CHIPNAME dap -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_DAP_TAPID -disable - jtag configure $_CHIPNAME.dap -event tap-enable "icepick_c_tapenable $_CHIPNAME.jrc 0" -} else { - swj_newdap $_CHIPNAME dap -expected-id $_DAP_TAPID -} - -# -# ICEpick-C (JTAG route controller) -# -if { [info exists JRC_TAPID] } { - set _JRC_TAPID $JRC_TAPID -} else { - set _JRC_TAPID 0x0B97C02F -} - -if {[using_jtag]} { - jtag newtap $_CHIPNAME jrc -irlen 6 -ircapture 0x1 -irmask 0x3f -expected-id $_JRC_TAPID -ignore-version - jtag configure $_CHIPNAME.jrc -event setup "jtag tapenable $_CHIPNAME.dap" -} - -# -# Cortex-M3 target -# -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME cortex_m -chain-position $_CHIPNAME.dap diff --git a/tcl/target/cs351x.cfg b/tcl/target/cs351x.cfg deleted file mode 100644 index cb05da2cf..000000000 --- a/tcl/target/cs351x.cfg +++ /dev/null @@ -1,31 +0,0 @@ -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME cs351x -} - -if { [info exists ENDIAN] } { - set _ENDIAN $ENDIAN -} else { - set _ENDIAN little -} - -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - set _CPUTAPID 0x00526fa1 -} - -jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID - -# Create the GDB Target. -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME fa526 -endian $_ENDIAN -chain-position $_TARGETNAME - -# There is 16K of SRAM on this chip -# FIXME: flash programming is not working by using this work area. So comment this out for now. -#$_TARGETNAME configure -work-area-phys 0x00000000 -work-area-size 0x4000 -work-area-backup 1 - -# This chip has a DCC ... use it -arm7_9 dcc_downloads enable - diff --git a/tcl/target/davinci.cfg b/tcl/target/davinci.cfg deleted file mode 100644 index 859a92539..000000000 --- a/tcl/target/davinci.cfg +++ /dev/null @@ -1,377 +0,0 @@ -# -# Utility code for DaVinci-family chips -# - -# davinci_pinmux: assigns PINMUX$reg <== $value -proc davinci_pinmux {soc reg value} { - mww [expr [dict get $soc sysbase] + 4 * $reg] $value -} - -source [find mem_helper.tcl] - -# -# pll_setup: initialize PLL -# - pll_addr ... physical addr of controller -# - mult ... pll multiplier -# - config ... dict mapping { prediv, postdiv, div[1-9] } to dividers -# -# For PLLs that don't have a given register (e.g. plldiv8), or where a -# given divider is non-programmable, caller provides *NO* config mapping. -# - -# PLL version 0x02: tested on dm355 -# REVISIT: On dm6446/dm357 the PLLRST polarity is different. -proc pll_v02_setup {pll_addr mult config} { - set pll_ctrl_addr [expr $pll_addr + 0x100] - set pll_ctrl [mrw $pll_ctrl_addr] - - # 1 - clear CLKMODE (bit 8) iff using on-chip oscillator - # NOTE: this assumes we should clear that bit - set pll_ctrl [expr $pll_ctrl & ~0x0100] - mww $pll_ctrl_addr $pll_ctrl - - # 2 - clear PLLENSRC (bit 5) - set pll_ctrl [expr $pll_ctrl & ~0x0020] - mww $pll_ctrl_addr $pll_ctrl - - # 3 - clear PLLEN (bit 0) ... enter bypass mode - set pll_ctrl [expr $pll_ctrl & ~0x0001] - mww $pll_ctrl_addr $pll_ctrl - - # 4 - wait at least 4 refclk cycles - sleep 1 - - # 5 - set PLLRST (bit 3) - set pll_ctrl [expr $pll_ctrl | 0x0008] - mww $pll_ctrl_addr $pll_ctrl - - # 6 - set PLLDIS (bit 4) - set pll_ctrl [expr $pll_ctrl | 0x0010] - mww $pll_ctrl_addr $pll_ctrl - - # 7 - clear PLLPWRDN (bit 1) - set pll_ctrl [expr $pll_ctrl & ~0x0002] - mww $pll_ctrl_addr $pll_ctrl - - # 8 - clear PLLDIS (bit 4) - set pll_ctrl [expr $pll_ctrl & ~0x0010] - mww $pll_ctrl_addr $pll_ctrl - - # 9 - optional: write prediv, postdiv, and pllm - # NOTE: for dm355 PLL1, postdiv is controlled via MISC register - mww [expr $pll_addr + 0x0110] [expr ($mult - 1) & 0xff] - if { [dict exists $config prediv] } { - set div [dict get $config prediv] - set div [expr 0x8000 | ($div - 1)] - mww [expr $pll_addr + 0x0114] $div - } - if { [dict exists $config postdiv] } { - set div [dict get $config postdiv] - set div [expr 0x8000 | ($div - 1)] - mww [expr $pll_addr + 0x0128] $div - } - - # 10 - optional: set plldiv1, plldiv2, ... - # NOTE: this assumes some registers have their just-reset values: - # - PLLSTAT.GOSTAT is clear when we enter - # - ALNCTL has everything set - set go 0 - if { [dict exists $config div1] } { - set div [dict get $config div1] - set div [expr 0x8000 | ($div - 1)] - mww [expr $pll_addr + 0x0118] $div - set go 1 - } - if { [dict exists $config div2] } { - set div [dict get $config div2] - set div [expr 0x8000 | ($div - 1)] - mww [expr $pll_addr + 0x011c] $div - set go 1 - } - if { [dict exists $config div3] } { - set div [dict get $config div3] - set div [expr 0x8000 | ($div - 1)] - mww [expr $pll_addr + 0x0120] $div - set go 1 - } - if { [dict exists $config div4] } { - set div [dict get $config div4] - set div [expr 0x8000 | ($div - 1)] - mww [expr $pll_addr + 0x0160] $div - set go 1 - } - if { [dict exists $config div5] } { - set div [dict get $config div5] - set div [expr 0x8000 | ($div - 1)] - mww [expr $pll_addr + 0x0164] $div - set go 1 - } - if {$go != 0} { - # write pllcmd.GO; poll pllstat.GO - mww [expr $pll_addr + 0x0138] 0x01 - set pllstat [expr $pll_addr + 0x013c] - while {[expr [mrw $pllstat] & 0x01] != 0} { sleep 1 } - } - mww [expr $pll_addr + 0x0138] 0x00 - - # 11 - wait at least 5 usec for reset to finish - # (assume covered by overheads including JTAG messaging) - - # 12 - clear PLLRST (bit 3) - set pll_ctrl [expr $pll_ctrl & ~0x0008] - mww $pll_ctrl_addr $pll_ctrl - - # 13 - wait at least 8000 refclk cycles for PLL to lock - # if we assume 24 MHz (slowest osc), that's 1/3 msec - sleep 3 - - # 14 - set PLLEN (bit 0) ... leave bypass mode - set pll_ctrl [expr $pll_ctrl | 0x0001] - mww $pll_ctrl_addr $pll_ctrl -} - -# PLL version 0x03: tested on dm365 -proc pll_v03_setup {pll_addr mult config} { - set pll_ctrl_addr [expr $pll_addr + 0x100] - set pll_secctrl_addr [expr $pll_addr + 0x108] - set pll_ctrl [mrw $pll_ctrl_addr] - - # 1 - power up the PLL - set pll_ctrl [expr $pll_ctrl & ~0x0002] - mww $pll_ctrl_addr $pll_ctrl - - # 2 - clear PLLENSRC (bit 5) - set pll_ctrl [expr $pll_ctrl & ~0x0020] - mww $pll_ctrl_addr $pll_ctrl - - # 2 - clear PLLEN (bit 0) ... enter bypass mode - set pll_ctrl [expr $pll_ctrl & ~0x0001] - mww $pll_ctrl_addr $pll_ctrl - - # 3 - wait at least 4 refclk cycles - sleep 1 - - # 4 - set PLLRST (bit 3) - set pll_ctrl [expr $pll_ctrl | 0x0008] - mww $pll_ctrl_addr $pll_ctrl - - # 5 - wait at least 5 usec - sleep 1 - - # 6 - clear PLLRST (bit 3) - set pll_ctrl [expr $pll_ctrl & ~0x0008] - mww $pll_ctrl_addr $pll_ctrl - - # 9 - optional: write prediv, postdiv, and pllm - mww [expr $pll_addr + 0x0110] [expr ($mult / 2) & 0x1ff] - if { [dict exists $config prediv] } { - set div [dict get $config prediv] - set div [expr 0x8000 | ($div - 1)] - mww [expr $pll_addr + 0x0114] $div - } - if { [dict exists $config postdiv] } { - set div [dict get $config postdiv] - set div [expr 0x8000 | ($div - 1)] - mww [expr $pll_addr + 0x0128] $div - } - - # 10 - write start sequence to PLLSECCTL - mww $pll_secctrl_addr 0x00470000 - mww $pll_secctrl_addr 0x00460000 - mww $pll_secctrl_addr 0x00400000 - mww $pll_secctrl_addr 0x00410000 - - # 11 - optional: set plldiv1, plldiv2, ... - # NOTE: this assumes some registers have their just-reset values: - # - PLLSTAT.GOSTAT is clear when we enter - set aln 0 - if { [dict exists $config div1] } { - set div [dict get $config div1] - set div [expr 0x8000 | ($div - 1)] - mww [expr $pll_addr + 0x0118] $div - set aln [expr $aln | 0x1] - } else { - mww [expr $pll_addr + 0x0118] 0 - } - if { [dict exists $config div2] } { - set div [dict get $config div2] - set div [expr 0x8000 | ($div - 1)] - mww [expr $pll_addr + 0x011c] $div - set aln [expr $aln | 0x2] - } else { - mww [expr $pll_addr + 0x011c] 0 - } - if { [dict exists $config div3] } { - set div [dict get $config div3] - set div [expr 0x8000 | ($div - 1)] - mww [expr $pll_addr + 0x0120] $div - set aln [expr $aln | 0x4] - } else { - mww [expr $pll_addr + 0x0120] 0 - } - if { [dict exists $config oscdiv] } { - set div [dict get $config oscdiv] - set div [expr 0x8000 | ($div - 1)] - mww [expr $pll_addr + 0x0124] $div - } else { - mww [expr $pll_addr + 0x0124] 0 - } - if { [dict exists $config div4] } { - set div [dict get $config div4] - set div [expr 0x8000 | ($div - 1)] - mww [expr $pll_addr + 0x0160] $div - set aln [expr $aln | 0x8] - } else { - mww [expr $pll_addr + 0x0160] 0 - } - if { [dict exists $config div5] } { - set div [dict get $config div5] - set div [expr 0x8000 | ($div - 1)] - mww [expr $pll_addr + 0x0164] $div - set aln [expr $aln | 0x10] - } else { - mww [expr $pll_addr + 0x0164] 0 - } - if { [dict exists $config div6] } { - set div [dict get $config div6] - set div [expr 0x8000 | ($div - 1)] - mww [expr $pll_addr + 0x0168] $div - set aln [expr $aln | 0x20] - } else { - mww [expr $pll_addr + 0x0168] 0 - } - if { [dict exists $config div7] } { - set div [dict get $config div7] - set div [expr 0x8000 | ($div - 1)] - mww [expr $pll_addr + 0x016c] $div - set aln [expr $aln | 0x40] - } else { - mww [expr $pll_addr + 0x016c] 0 - } - if { [dict exists $config div8] } { - set div [dict get $config div8] - set div [expr 0x8000 | ($div - 1)] - mww [expr $pll_addr + 0x0170] $div - set aln [expr $aln | 0x80] - } else { - mww [expr $pll_addr + 0x0170] 0 - } - if { [dict exists $config div9] } { - set div [dict get $config div9] - set div [expr 0x8000 | ($div - 1)] - mww [expr $pll_addr + 0x0174] $div - set aln [expr $aln | 0x100] - } else { - mww [expr $pll_addr + 0x0174] 0 - } - if {$aln != 0} { - # clear pllcmd.GO - mww [expr $pll_addr + 0x0138] 0x00 - # write alingment flags - mww [expr $pll_addr + 0x0140] $aln - # write pllcmd.GO; poll pllstat.GO - mww [expr $pll_addr + 0x0138] 0x01 - set pllstat [expr $pll_addr + 0x013c] - while {[expr [mrw $pllstat] & 0x01] != 0} { sleep 1 } - } - mww [expr $pll_addr + 0x0138] 0x00 - set addr [dict get $config ctladdr] - while {[expr [mrw $addr] & 0x0e000000] != 0x0e000000} { sleep 1 } - - # 12 - set PLLEN (bit 0) ... leave bypass mode - set pll_ctrl [expr $pll_ctrl | 0x0001] - mww $pll_ctrl_addr $pll_ctrl -} - -# NOTE: dm6446 requires EMURSTIE set in MDCTL before certain -# modules can be enabled. - -# prepare a non-DSP module to be enabled; finish with psc_go -proc psc_enable {module} { - set psc_addr 0x01c41000 - # write MDCTL - mmw [expr $psc_addr + 0x0a00 + (4 * $module)] 0x03 0x1f -} - -# prepare a non-DSP module to be reset; finish with psc_go -proc psc_reset {module} { - set psc_addr 0x01c41000 - # write MDCTL - mmw [expr $psc_addr + 0x0a00 + (4 * $module)] 0x01 0x1f -} - -# execute non-DSP PSC transition(s) set up by psc_enable, psc_reset, etc -proc psc_go {} { - set psc_addr 0x01c41000 - set ptstat_addr [expr $psc_addr + 0x0128] - - # just in case PTSTAT.go isn't clear - while { [expr [mrw $ptstat_addr] & 0x01] != 0 } { sleep 1 } - - # write PTCMD.go ... ignoring any DSP power domain - mww [expr $psc_addr + 0x0120] 1 - - # wait for PTSTAT.go to clear (again ignoring DSP power domain) - while { [expr [mrw $ptstat_addr] & 0x01] != 0 } { sleep 1 } -} - -# -# A reset using only SRST is a "Warm Reset", resetting everything in the -# chip except ARM emulation (and everything _outside_ the chip that hooks -# up to SRST). But many boards don't expose SRST via their JTAG connectors -# (it's not present on TI-14 headers). -# -# From the chip-only perspective, a "Max Reset" is a "Warm" reset ... except -# without any board-wide side effects, since it's triggered using JTAG using -# either (a) ARM watchdog timer, or (b) ICEpick. -# -proc davinci_wdog_reset {} { - set timer2_phys 0x01c21c00 - - # NOTE -- on entry - # - JTAG communication with the ARM *must* be working OK; this - # may imply using adaptive clocking or disabling WFI-in-idle - # - current target must be the DaVinci ARM - # - that ARM core must be halted - # - timer2 clock is still enabled (PSC 29 on most chips) - - # - # Part I -- run regardless of being halted via JTAG - # - # NOTE: for now, we assume there's no DSP that could control the - # watchdog; or, equivalently, SUSPSRC.TMR2SRC says the watchdog - # suspend signal is controlled via ARM emulation suspend. - # - - # EMUMGT_CLKSPEED: write FREE bit to run despite emulation halt - mww phys [expr $timer2_phys + 0x28] 0x00004000 - - # - # Part II -- in case watchdog hasn't been set up - # - - # TCR: disable, force internal clock source - mww phys [expr $timer2_phys + 0x20] 0 - - # TGCR: reset, force to 64-bit wdog mode, un-reset ("initial" state) - mww phys [expr $timer2_phys + 0x24] 0 - mww phys [expr $timer2_phys + 0x24] 0x110b - - # clear counter (TIM12, TIM34) and period (PRD12, PRD34) registers - # so watchdog triggers ASAP - mww phys [expr $timer2_phys + 0x10] 0 - mww phys [expr $timer2_phys + 0x14] 0 - mww phys [expr $timer2_phys + 0x18] 0 - mww phys [expr $timer2_phys + 0x1c] 0 - - # WDTCR: put into pre-active state, then active - mww phys [expr $timer2_phys + 0x28] 0xa5c64000 - mww phys [expr $timer2_phys + 0x28] 0xda7e4000 - - # - # Part III -- it's ready to rumble - # - - # WDTCR: write invalid WDKEY to trigger reset - mww phys [expr $timer2_phys + 0x28] 0x00004000 -} diff --git a/tcl/target/dragonite.cfg b/tcl/target/dragonite.cfg deleted file mode 100644 index 750fd6437..000000000 --- a/tcl/target/dragonite.cfg +++ /dev/null @@ -1,31 +0,0 @@ -###################################### -# Target: Marvell Dragonite CPU core -###################################### - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME dragonite -} - -if { [info exists ENDIAN] } { - set _ENDIAN $ENDIAN -} else { - set _ENDIAN little -} - -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - set _CPUTAPID 0x121003d3 -} - -jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID - -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME dragonite -endian $_ENDIAN -chain-position $_TARGETNAME - -reset_config trst_and_srst -adapter_nsrst_delay 200 -jtag_ntrst_delay 200 - diff --git a/tcl/target/dsp56321.cfg b/tcl/target/dsp56321.cfg deleted file mode 100644 index 6f3222373..000000000 --- a/tcl/target/dsp56321.cfg +++ /dev/null @@ -1,37 +0,0 @@ -# Script for freescale DSP56321 -# - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME dsp56321 -} - -if { [info exists ENDIAN] } { - set _ENDIAN $ENDIAN -} else { - # this defaults to a big endian - set _ENDIAN big -} - -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - set _CPUTAPID 0x1181501d -} - -#jtag speed -adapter_khz 4500 - -#has only srst -reset_config srst_only - -#jtag scan chain -jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 1 -irmask 0x1 -expected-id $_CPUTAPID - -#target configuration -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME dsp563xx -endian $_ENDIAN -chain-position $_TARGETNAME - -#working area at base of ram -$_TARGETNAME configure -work-area-virt 0 diff --git a/tcl/target/dsp568013.cfg b/tcl/target/dsp568013.cfg deleted file mode 100644 index 0c491fa95..000000000 --- a/tcl/target/dsp568013.cfg +++ /dev/null @@ -1,76 +0,0 @@ -# Script for freescale DSP568013 - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME dsp568013 -} - -if { [info exists ENDIAN] } { - set _ENDIAN $ENDIAN -} else { - # this defaults to a big endian - set _ENDIAN little -} - -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - set _CPUTAPID 0x01f2401d -} - -#jtag speed -adapter_khz 800 - -reset_config srst_only - -#MASTER tap -jtag newtap $_CHIPNAME chp -irlen 8 -ircapture 1 -irmask 0x03 -expected-id $_CPUTAPID - -#CORE tap -jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 1 -irmask 0x03 -disable -expected-id 0x02211004 - -#target configuration - There is only 1 tap at a time, hence only 1 target is defined. -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME dsp5680xx -endian $_ENDIAN -chain-position $_TARGETNAME - -# Setup the interesting tap -# Disable polling to be able to get idcode from core tap. If re enabled, can be re enabled, but it should be disabled to correctly unlock flash (operations requiere certain instruction to be in the IR register during reset, and polling would change this) -jtag configure $_CHIPNAME.chp -event setup " - jtag tapenable $_TARGETNAME - poll off -" - -#select CORE tap by modifying the TLM register. -#to be used when MASTER tap is selected. -jtag configure $_TARGETNAME -event tap-enable " - irscan $_CHIPNAME.chp 0x05; - drscan $_CHIPNAME.chp 4 0x02; - jtag tapdisable $_CHIPNAME.chp; -" - -#select MASTER tap by modifying the TLM register. -#to be used when CORE tap is selected. -jtag configure $_CHIPNAME.chp -event tap-enable " - irscan $_TARGETNAME 0x08; - drscan $_TARGETNAME 4 0x1; - jtag tapdisable $_TARGETNAME; -" - -#disables the master tap -jtag configure $_TARGETNAME -event tap-disable " -" -#TODO FIND SMARTER WAY. - -jtag configure $_CHIPNAME.chp -event tap-disable " -" -#TODO FIND SMARTER WAY. - - -#working area at base of ram -$_TARGETNAME configure -work-area-virt 0 - -#setup flash -set _FLASHNAME $_CHIPNAME.flash -flash bank $_FLASHNAME dsp5680xx_flash 0 0 2 1 $_TARGETNAME - diff --git a/tcl/target/dsp568037.cfg b/tcl/target/dsp568037.cfg deleted file mode 100644 index 01194d002..000000000 --- a/tcl/target/dsp568037.cfg +++ /dev/null @@ -1,72 +0,0 @@ -# Script for freescale DSP568037 - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME dsp568037 -} - -if { [info exists ENDIAN] } { - set _ENDIAN $ENDIAN -} else { - # this defaults to a big endian - set _ENDIAN little -} - -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - set _CPUTAPID 0x01f2801d -} - -#jtag speed -adapter_khz 800 - -reset_config srst_only - -#MASTER tap -jtag newtap $_CHIPNAME chp -irlen 8 -ircapture 1 -irmask 0x03 -expected-id $_CPUTAPID - -#CORE tap -jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 1 -irmask 0x03 -disable -expected-id 0x02211004 - -#target configuration - There is only 1 tap at a time, hence only 1 target is defined. -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME dsp5680xx -endian $_ENDIAN -chain-position $_TARGETNAME - -# Setup the interesting tap -jtag configure $_CHIPNAME.chp -event setup "jtag tapenable $_TARGETNAME" - -#select CORE tap by modifying the TLM register. -#to be used when MASTER tap is selected. -jtag configure $_TARGETNAME -event tap-enable " - irscan $_CHIPNAME.chp 0x05; - drscan $_CHIPNAME.chp 4 0x02; - jtag tapdisable $_CHIPNAME.chp; -" - -#select MASTER tap by modifying the TLM register. -#to be used when CORE tap is selected. -jtag configure $_CHIPNAME.chp -event tap-enable " - irscan $_TARGETNAME 0x08; - drscan $_TARGETNAME 4 0x1; - jtag tapdisable $_TARGETNAME; -" - -#disables the master tap -jtag configure $_TARGETNAME -event tap-disable " -" -#TODO FIND SMARTER WAY. - -jtag configure $_CHIPNAME.chp -event tap-disable " -" -#TODO FIND SMARTER WAY. - - -#working area at base of ram -$_TARGETNAME configure -work-area-virt 0 - -#setup flash -set _FLASHNAME $_CHIPNAME.flash -flash bank $_FLASHNAME dsp5680xx_flash 0 0 2 1 $_TARGETNAME - diff --git a/tcl/target/efm32.cfg b/tcl/target/efm32.cfg deleted file mode 100644 index 33610d5a8..000000000 --- a/tcl/target/efm32.cfg +++ /dev/null @@ -1,43 +0,0 @@ -# -# efm32 target -# - -source [find target/swj-dp.tcl] - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME efm32 -} - -# Work-area is a space in RAM used for flash programming -# By default use 2kB -if { [info exists WORKAREASIZE] } { - set _WORKAREASIZE $WORKAREASIZE -} else { - set _WORKAREASIZE 0x800 -} - -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - set _CPUTAPID 0x2ba01477 -} - -swj_newdap $_CHIPNAME cpu -expected-id $_CPUTAPID - -adapter_khz 1000 - -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME cortex_m -chain-position $_TARGETNAME - -$_TARGETNAME configure -work-area-phys 0x10000000 -work-area-size $_WORKAREASIZE -work-area-backup 0 - -set _FLASHNAME $_CHIPNAME.flash -flash bank $_FLASHNAME efm32 0 0 0 0 $_TARGETNAME - -if {![using_hla]} { - # if srst is not fitted use SYSRESETREQ to - # perform a soft reset - cortex_m reset_config sysresetreq -} diff --git a/tcl/target/efm32_stlink.cfg b/tcl/target/efm32_stlink.cfg deleted file mode 100644 index 230155ea0..000000000 --- a/tcl/target/efm32_stlink.cfg +++ /dev/null @@ -1,2 +0,0 @@ -echo "WARNING: target/efm32_stlink.cfg is deprecated, please switch to target/efm32.cfg" -source [find target/efm32.cfg] diff --git a/tcl/target/em357.cfg b/tcl/target/em357.cfg deleted file mode 100644 index 24ffb04f9..000000000 --- a/tcl/target/em357.cfg +++ /dev/null @@ -1,76 +0,0 @@ -# -# Target configuration for the Silicon Labs EM357 chips -# - -# -# em357 family supports JTAG and SWD transports -# -source [find target/swj-dp.tcl] - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME em357 -} - -# Work-area is a space in RAM used for flash programming -# By default use 4kB -if { [info exists WORKAREASIZE] } { - set _WORKAREASIZE $WORKAREASIZE -} else { - set _WORKAREASIZE 0x1000 -} - -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - if { [using_jtag] } { - set _CPUTAPID 0x3ba00477 - } else { - set _CPUTAPID 0x1ba00477 - } -} - -if { [info exists BSTAPID] } { - set _BSTAPID $BSTAPID -} else { - set _BSTAPID 0x069a962b -} - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME em358 -} - -if { [info exists FLASHSIZE] } { - set _FLASHSIZE $FLASHSIZE -} else { - set _FLASHSIZE 0x30000 -} - -swj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID -if { [using_jtag] } { - swj_newdap $_CHIPNAME bs -irlen 4 -expected-id $_BSTAPID -ircapture 0xe -irmask 0xf -} - -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME cortex_m -endian little -chain-position $_TARGETNAME - -$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0 - -set _FLASHNAME $_CHIPNAME.flash -flash bank $_FLASHNAME em357 0x08000000 $_FLASHSIZE 0 0 $_TARGETNAME - -if { ![using_hla]} { -# according to errata, we need to use vectreset rather than sysresetreq to avoid lockup -# There is a bug in the chip, which means that when using external debuggers the chip -# may lock up in certain CPU clock modes. Affected modes are operating the CPU at -# 24MHz derived from the 24MHz crystal, or 12MHz derived from the high frequency RC -# oscillator. If an external debugger tool asserts SYSRESETREQ, the chip will lock up and -# require a pin reset or power cycle. -# -# for details, refer to: -# http://www.silabs.com/Support%20Documents/TechnicalDocs/EM35x-Errata.pdf - cortex_m reset_config vectreset -} diff --git a/tcl/target/em358.cfg b/tcl/target/em358.cfg deleted file mode 100644 index 92e65a4c7..000000000 --- a/tcl/target/em358.cfg +++ /dev/null @@ -1,17 +0,0 @@ -# Target configuration for the Silicon Labs EM358 chips - -# -# em357 family supports JTAG and SWD transports -# - -if { ![info exists CHIPNAME] } { - set CHIPNAME em358 -} - -if { ![info exists BSTAPID] } { - set BSTAPID 0x069aa62b -} - -# 512K of flash in the em358 chips -set FLASHSIZE 0x80000 -source [find target/em357.cfg] diff --git a/tcl/target/epc9301.cfg b/tcl/target/epc9301.cfg deleted file mode 100644 index f186d37dc..000000000 --- a/tcl/target/epc9301.cfg +++ /dev/null @@ -1,32 +0,0 @@ -# Cirrus Logic EP9301 processor on an Olimex CS-E9301 board. - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME ep9301 -} - -if { [info exists ENDIAN] } { - set _ENDIAN $ENDIAN -} else { - set _ENDIAN little -} - -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - # Force an error until we get a good number. - set _CPUTAPID 0xffffffff -} - -jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID -adapter_nsrst_delay 100 -jtag_ntrst_delay 100 - -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME arm920t -endian $_ENDIAN -chain-position $_TARGETNAME -work-area-phys 0x80014000 -work-area-size 0x1000 -work-area-backup 1 - -#flash configuration -#flash bank [driver_options ...] -set _FLASHNAME $_CHIPNAME.flash -flash bank $_FLASHNAME cfi 0x60000000 0x1000000 2 2 $_TARGETNAME diff --git a/tcl/target/exynos5250.cfg b/tcl/target/exynos5250.cfg deleted file mode 100644 index 36783410b..000000000 --- a/tcl/target/exynos5250.cfg +++ /dev/null @@ -1,23 +0,0 @@ -# -# Samsung Exynos 5250 - dual-core ARM Cortex-A15 -# - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME exynos5250 -} - -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - set _CPUTAPID 0x4ba00477 -} - -jtag newtap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID - -set _TARGETNAME $_CHIPNAME.cpu -target create ${_TARGETNAME}0 cortex_a -chain-position $_TARGETNAME -target create ${_TARGETNAME}1 cortex_a -chain-position $_TARGETNAME - -target smp ${_TARGETNAME}0 ${_TARGETNAME}1 diff --git a/tcl/target/faux.cfg b/tcl/target/faux.cfg deleted file mode 100644 index d3891cded..000000000 --- a/tcl/target/faux.cfg +++ /dev/null @@ -1,30 +0,0 @@ -#Script for faux target - used for testing - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME at91eb40a -} - -if { [info exists ENDIAN] } { - set _ENDIAN $ENDIAN -} else { - set _ENDIAN little -} - -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - set _CPUTAPID 0x00000000 -} - - -jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID - -#target configuration -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME arm7tdmi -endian $_ENDIAN -chain-position $_TARGETNAME - -#dummy flash driver -set _FLASHNAME $_CHIPNAME.flash -flash bank $_FLASHNAME faux 0x01000000 0x200000 2 2 $_TARGETNAME diff --git a/tcl/target/feroceon.cfg b/tcl/target/feroceon.cfg deleted file mode 100644 index 389576e55..000000000 --- a/tcl/target/feroceon.cfg +++ /dev/null @@ -1,31 +0,0 @@ -###################################### -# Target: Marvell Feroceon CPU core -###################################### - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME feroceon -} - -if { [info exists ENDIAN] } { - set _ENDIAN $ENDIAN -} else { - set _ENDIAN little -} - -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - set _CPUTAPID 0x20a023d3 -} - -jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID - -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME feroceon -endian $_ENDIAN -chain-position $_TARGETNAME - -reset_config trst_and_srst -adapter_nsrst_delay 200 -jtag_ntrst_delay 200 - diff --git a/tcl/target/fm3.cfg b/tcl/target/fm3.cfg deleted file mode 100644 index 78bbc945c..000000000 --- a/tcl/target/fm3.cfg +++ /dev/null @@ -1,53 +0,0 @@ -# MB9BF506 -# Fujitsu Cortex-M3 with 512kB Flash and 64kB RAM - -source [find target/swj-dp.tcl] - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME mb9bfxx6 -} - -if { [info exists ENDIAN] } { - set _ENDIAN $ENDIAN -} else { - set _ENDIAN little -} - -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - set _CPUTAPID 0x4ba00477 -} - -# delays on reset lines -adapter_nsrst_delay 100 -if {[using_jtag]} { - jtag_ntrst_delay 100 -} - -# Fujitsu Cortex-M3 reset configuration -reset_config trst_only - -swj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID - -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME cortex_m -endian $_ENDIAN -chain-position $_TARGETNAME - -# MB9BF506 has 64kB of SRAM on its main system bus -$_TARGETNAME configure -work-area-phys 0x1FFF8000 -work-area-size 0x10000 -work-area-backup 0 - -# MB9BF506 has 512kB internal FLASH - -set _FLASHNAME $_CHIPNAME.flash -flash bank $_FLASHNAME fm3 0 0 0 0 $_TARGETNAME - -# 4MHz / 6 = 666kHz, so use 500 -adapter_khz 500 - -if {![using_hla]} { - # if srst is not fitted use SYSRESETREQ to - # perform a soft reset - cortex_m reset_config sysresetreq -} diff --git a/tcl/target/fm4.cfg b/tcl/target/fm4.cfg deleted file mode 100644 index e5d0f8d60..000000000 --- a/tcl/target/fm4.cfg +++ /dev/null @@ -1,30 +0,0 @@ -# -# Spansion FM4 (ARM Cortex-M4) -# - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME fm4 -} - -source [find target/swj-dp.tcl] - -if { [info exists CPUTAPID] } { - set _CPU_TAPID $CPUTAPID -} elseif { [using_jtag] } { - set _CPU_TAPID 0x4ba00477 -} else { - set _CPU_TAPID 0x2ba01477 -} - -swj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_CPU_TAPID - -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME cortex_m -endian little -chain-position $_TARGETNAME - -adapter_khz 500 - -if {![using_hla]} { - cortex_m reset_config sysresetreq -} diff --git a/tcl/target/fm4_mb9bf.cfg b/tcl/target/fm4_mb9bf.cfg deleted file mode 100644 index e53fdc878..000000000 --- a/tcl/target/fm4_mb9bf.cfg +++ /dev/null @@ -1,18 +0,0 @@ -# -# Spansion FM4 MB9BFxxx (ARM Cortex-M4) -# - -source [find target/fm4.cfg] - -# MB9BF566 M/N/R have 32 KB SRAM0 -if { [info exists WORKAREASIZE] } { - set _WORKAREASIZE $WORKAREASIZE -} else { - set _WORKAREASIZE 0x8000 -} - -$_TARGETNAME configure -work-area-phys [expr 0x20000000 - $_WORKAREASIZE] \ - -work-area-size $_WORKAREASIZE -work-area-backup 0 - -set _FLASHNAME $_CHIPNAME.flash -flash bank $_FLASHNAME fm4 0x00000000 0 0 0 $_TARGETNAME $CHIPSERIES diff --git a/tcl/target/fm4_s6e2cc.cfg b/tcl/target/fm4_s6e2cc.cfg deleted file mode 100644 index 60b73b974..000000000 --- a/tcl/target/fm4_s6e2cc.cfg +++ /dev/null @@ -1,19 +0,0 @@ -# -# Spansion FM4 S6E2CC (ARM Cortex-M4) -# - -source [find target/fm4.cfg] - -# S6E2CC8 H/J/L have 96 KB SRAM0 -if { [info exists WORKAREASIZE] } { - set _WORKAREASIZE $WORKAREASIZE -} else { - set _WORKAREASIZE 0x18000 -} - -$_TARGETNAME configure -work-area-phys [expr 0x20000000 - $_WORKAREASIZE] \ - -work-area-size $_WORKAREASIZE -work-area-backup 0 - -set _FLASHNAME $_CHIPNAME.flash -flash bank ${_FLASHNAME}0 fm4 0x00000000 0 0 0 $_TARGETNAME $CHIPSERIES -flash bank ${_FLASHNAME}1 fm4 0x00100000 0 0 0 $_TARGETNAME $CHIPSERIES diff --git a/tcl/target/gp326xxxa.cfg b/tcl/target/gp326xxxa.cfg deleted file mode 100644 index feb7554b7..000000000 --- a/tcl/target/gp326xxxa.cfg +++ /dev/null @@ -1,94 +0,0 @@ -# -# Support for General Plus GP326XXXA chips -# - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME gp326xxxa -} - -if { [info exists ENDIAN] } { - set _ENDIAN $ENDIAN -} else { - set _ENDIAN little -} - -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - set _CPUTAPID 0x4f1f0f0f -} - -jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID - -set _TARGETNAME $_CHIPNAME.cpu - -target create $_TARGETNAME arm7tdmi -endian $_ENDIAN -chain-position $_TARGETNAME - -# Use internal SRAM as a work area -$_TARGETNAME configure -work-area-phys 0xf8000000 -work-area-size 0x8000 -work-area-backup 0 - -# The chip has both lines connected together -reset_config trst_and_srst srst_pulls_trst -# This delay is needed otherwise communication with the target would -# be unreliable -adapter_nsrst_delay 100 - -# Set the adapter speed ridiculously low just in case we are -# running off of a 32kHz clock -adapter_khz 2 - -proc gp32xxxa_halt_and_reset_control_registers {} { - # System control registers - set P_SYSTEM_CTRL_NEW 0xD0000008 - set P_SYSTEM_CTRL 0xD000000C - set P_SYSTEM_CLK_EN0 0xD0000010 - set P_SYSTEM_CLK_EN1 0xD0000014 - set P_SYSTEM_RESET_FLAG 0xD0000018 - set P_SYSTEM_CLK_CTRL 0xD000001C - set P_SYSTEM_LVR_CTRL 0xD0000020 - set P_SYSTEM_WATCHDOG_CTRL 0xD0000024 - set P_SYSTEM_PLLEN 0xD000005C - - # Since we can't use SRST without pulling TRST - # we can't assume the state of the clock configuration - # or watchdog settings. So reset them before porceeding - - # Set the adapter speed ridiculously low just in case we are - # running off of a 32kHz clock - adapter_khz 2 - - # Disable any advanced features at this stage - arm7_9 dcc_downloads disable - arm7_9 fast_memory_access disable - - # Do a "soft reset" - soft_reset_halt - # Reset all system control registers to their default "after-reset" values - mwh $P_SYSTEM_WATCHDOG_CTRL 0x0000 - mwh $P_SYSTEM_LVR_CTRL 0x0000 - - mwh $P_SYSTEM_CTRL_NEW 0x0001 - mwh $P_SYSTEM_CTRL 0x0001 - # Clear all reset flags by writing 1's - mwh $P_SYSTEM_RESET_FLAG 0x001C - - mwh $P_SYSTEM_CLK_CTRL 0x8000 - mwh $P_SYSTEM_CLK_EN0 0xFFFF - mwh $P_SYSTEM_CLK_EN1 0xFFFF - mwh $P_SYSTEM_PLLEN 0x0010 - - # Unfortunately there's no register that would allow us to - # know if PLL is locked. So just wait for 100ms in hopes that - # it would be enough. - sleep 100 - - # Now that we know that we are running at 48Mhz - # Increase JTAG speed and enable speed optimization features - adapter_khz 5000 - arm7_9 dcc_downloads enable - arm7_9 fast_memory_access enable -} - -$_TARGETNAME configure -event reset-end { gp32xxxa_halt_and_reset_control_registers } diff --git a/tcl/target/hilscher_netx10.cfg b/tcl/target/hilscher_netx10.cfg deleted file mode 100644 index 3f96607c6..000000000 --- a/tcl/target/hilscher_netx10.cfg +++ /dev/null @@ -1,31 +0,0 @@ -################################################################################ -# Author: Michael Trensch (MTrensch@googlemail.com) -################################################################################ - -#Hilscher netX 10 CPU - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME netx10 -} - -if { [info exists ENDIAN] } { - set _ENDIAN $ENDIAN -} else { - set _ENDIAN little -} - -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - set _CPUTAPID 0x25966021 -} - -# jtag scan chain -jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID - -# that TAP is associated with a target -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME arm966e -endian $_ENDIAN -chain-position $_TARGETNAME - diff --git a/tcl/target/hilscher_netx50.cfg b/tcl/target/hilscher_netx50.cfg deleted file mode 100644 index c6510c613..000000000 --- a/tcl/target/hilscher_netx50.cfg +++ /dev/null @@ -1,50 +0,0 @@ -################################################################################ -# Author: Michael Trensch (MTrensch@googlemail.com) -################################################################################ - -#Hilscher netX 50 CPU - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME netx50 -} - -if { [info exists ENDIAN] } { - set _ENDIAN $ENDIAN -} else { - set _ENDIAN little -} - -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - set _CPUTAPID 0x25966021 -} - -# jtag scan chain -jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID - -# that TAP is associated with a target -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME arm966e -endian $_ENDIAN -chain-position $_TARGETNAME - -# On netX50 SDRAM is not accessible at offset 0xDEAD0-0xDEADF as it is busy from -# DMA controller at init. This function will setup a dummy DMA to free this ares -# and must be called before using SDRAM -proc sdram_fix { } { - - mww 0x1c005830 0x00000001 - - mww 0x1c005104 0xBFFFFFFC - mww 0x1c00510c 0x00480001 - mww 0x1c005110 0x00000001 - - sleep 100 - - mww 0x1c00510c 0 - mww 0x1c005110 0 - mww 0x1c005830 0x00000000 - - puts "SDRAM Fix executed!" -} diff --git a/tcl/target/hilscher_netx500.cfg b/tcl/target/hilscher_netx500.cfg deleted file mode 100644 index 93375fd81..000000000 --- a/tcl/target/hilscher_netx500.cfg +++ /dev/null @@ -1,47 +0,0 @@ -#Hilscher netX 500 CPU - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME netx500 -} - -if { [info exists ENDIAN] } { - set _ENDIAN $ENDIAN -} else { - set _ENDIAN little -} - -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - set _CPUTAPID 0x07926021 -} - -# jtag scan chain -jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID - -# that TAP is associated with a target -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME arm926ejs -endian $_ENDIAN -chain-position $_TARGETNAME - -proc mread32 {addr} { - set value(0) 0 - mem2array value 32 $addr 1 - return $value(0) -} - -# This function must be called on netX100/500 right after halt -# If it is called later the needed register cannot be written anymore -proc sdram_fix { } { - - set accesskey [mread32 0x00100070] - mww 0x00100070 [expr $accesskey] - mww 0x0010002c 0x00000001 - - if {[expr [mread32 0x0010002c] & 0x07] == 0x07} { - puts "SDRAM Fix was not executed. Probably your CPU halted too late and the register is already locked!" - } else { - puts "SDRAM Fix succeeded!" - } -} diff --git a/tcl/target/icepick.cfg b/tcl/target/icepick.cfg deleted file mode 100644 index abd7b6a08..000000000 --- a/tcl/target/icepick.cfg +++ /dev/null @@ -1,142 +0,0 @@ -# -# Copyright (C) 2011 by Karl Kurbjun -# Copyright (C) 2009 by David Brownell -# - -# Utilities for TI ICEpick-C/D used in most TI SoCs -# Details about the ICEPick are available in the the TRM for each SoC -# and http://processors.wiki.ti.com/index.php/ICEPICK - -# create "constants" -proc CONST { key } { - - array set constant { - # define ICEPick instructions - IR_BYPASS 0x00 - IR_ROUTER 0x02 - IR_CONNECT 0x07 - IF_BYPASS 0x3F - } - return $constant($key) -} - -# Instruction to connect to the icepick module -proc icepick_c_connect {jrc} { - - # Send CONNECT instruction in IR state - irscan $jrc [CONST IR_CONNECT] -endstate IRPAUSE - - # Send write and connect key - drscan $jrc 8 0x89 -endstate DRPAUSE -} - -# Instruction to disconnect to the icepick module -proc icepick_c_disconnect {jrc} { - - # Send CONNECT instruction in IR state - irscan $jrc [CONST IR_CONNECT] -endstate IRPAUSE - - # Send write and connect key - drscan $jrc 8 0x86 -endstate DRPAUSE -} - -# -# icepick_c_router: -# this function is for sending router commands -# arguments are: -# jrc: TAP name for the ICEpick -# rw: read/write (0 for read, 1 for write) -# block: icepick or DAP -# register: which register to read/write -# payload: value to read/write -# this function is for sending router commands -# -proc icepick_c_router {jrc rw block register payload} { - - set new_dr_value \ - [expr ( ($rw & 0x1) << 31) | ( ($block & 0x7) << 28) | \ - ( ($register & 0xF) << 24) | ( $payload & 0xFFFFFF ) ] - -# echo "\tNew router value:\t0x[format %x $new_dr_value]" - - # select router - irscan $jrc [CONST IR_ROUTER] -endstate IRPAUSE - - # ROUTER instructions are 32 bits wide - set old_dr_value [drscan $jrc 32 $new_dr_value -endstate DRPAUSE] -} - -# Configure the icepick control register -proc icepick_c_setup {jrc} { - - # send a router write, block is 0, register is 1, value is 0x2100 - icepick_c_router $jrc 1 0x0 0x1 0x001000 -} - -# jrc == TAP name for the ICEpick -# port == a port number, 0..15 -proc icepick_c_tapenable {jrc port} { - - # First CONNECT to the ICEPick -# echo "Connecting to ICEPick" - icepick_c_connect $jrc - -# echo "Configuring the ICEpick" - icepick_c_setup $jrc - - # NOTE: it's important not to enter RUN/IDLE state until - # done sending these instructions and data to the ICEpick. - # And never to enter RESET, which will disable the TAPs. - - # first enable power and clock for TAP - icepick_c_router $jrc 1 0x2 $port 0x100048 - - # TRM states that the register should be read back here, skipped for now - - # enable debug "default" mode - icepick_c_router $jrc 1 0x2 $port 0x102048 - - # TRM states that debug enable and debug mode should be read back and - # confirmed - skipped for now - - # Finally select the tap - icepick_c_router $jrc 1 0x2 $port 0x102148 - - # Enter the bypass state - irscan $jrc [CONST IR_BYPASS] -endstate RUN/IDLE - runtest 10 -} - -# jrc == TAP name for the ICEpick -# coreid== core id number 0..15 (not same as port number!) -proc icepick_d_set_coreid {jrc coreid } { - icepick_c_router $jrc 1 0x6 $coreid 0x2008 -} - -# jrc == TAP name for the ICEpick -# port == a port number, 0..15 -# Follow the sequence described in -# http://processors.wiki.ti.com/images/f/f6/Router_Scan_Sequence-ICEpick-D.pdf -proc icepick_d_tapenable {jrc port coreid} { - # First CONNECT to the ICEPick - icepick_c_connect $jrc - icepick_c_setup $jrc - - # Select the port - icepick_c_router $jrc 1 0x2 $port 0x2108 - - # Set 4 bit core ID to the Cortex-A - icepick_d_set_coreid $jrc $coreid - - # Enter the bypass state - irscan $jrc [CONST IF_BYPASS] -endstate RUN/IDLE - runtest 10 -} - -# This function uses the ICEPick to send a warm system reset -proc icepick_c_wreset {jrc} { - - # send a router write, block is 0, register is 1, value is 0x2100 - icepick_c_router $jrc 1 0x0 0x1 0x002101 -} - diff --git a/tcl/target/imx.cfg b/tcl/target/imx.cfg deleted file mode 100644 index 9eea53eef..000000000 --- a/tcl/target/imx.cfg +++ /dev/null @@ -1,30 +0,0 @@ -# utility fn's for Freescale i.MX series - -global TARGETNAME -set TARGETNAME $_TARGETNAME - -# rewrite commands of the form below to arm11 mcr... -# Data.Set c15:0x042f %long 0x40000015 -proc setc15 {regs value} { - global TARGETNAME - - echo [format "set p15 0x%04x, 0x%08x" $regs $value] - - arm mcr 15 [expr ($regs>>12)&0x7] [expr ($regs>>0)&0xf] [expr ($regs>>4)&0xf] [expr ($regs>>8)&0x7] $value -} - - -proc imx3x_reset {} { - # this reset script comes from the Freescale PDK - # - # http://www.freescale.com/webapp/sps/site/prod_summary.jsp?code=IMX35PDK - - echo "Target Setup: initialize DRAM controller and peripherals" - -# Data.Set c15:0x01 %long 0x00050078 - setc15 0x01 0x00050078 - - echo "configuring CP15 for enabling the peripheral bus" -# Data.Set c15:0x042f %long 0x40000015 - setc15 0x042f 0x40000015 -} diff --git a/tcl/target/imx21.cfg b/tcl/target/imx21.cfg deleted file mode 100644 index 2d9ce39c6..000000000 --- a/tcl/target/imx21.cfg +++ /dev/null @@ -1,34 +0,0 @@ -#use combined on interfaces or targets that can't set TRST/SRST separately -# -# Hmmm.... should srst_pulls_trst be used here like i.MX27??? -reset_config trst_and_srst - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME imx21 -} - -if { [info exists ENDIAN] } { - set _ENDIAN $ENDIAN -} else { - set _ENDIAN little -} - - -# Note above there is 1 tap - -# The CPU tap -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - set _CPUTAPID 0x0792611f -} -jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID - - -# Create the GDB Target. -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME arm926ejs -endian $_ENDIAN -chain-position $_TARGETNAME - -arm7_9 dcc_downloads enable diff --git a/tcl/target/imx25.cfg b/tcl/target/imx25.cfg deleted file mode 100644 index bc91278c4..000000000 --- a/tcl/target/imx25.cfg +++ /dev/null @@ -1,46 +0,0 @@ -# -# imx25 config -# - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME imx25 -} - -if { [info exists ENDIAN] } { - set _ENDIAN $ENDIAN -} else { - set _ENDIAN little -} - -if { [info exists ETBTAPID] } { - set _ETBTAPID $ETBTAPID -} else { - set _ETBTAPID 0x1b900f0f -} -jtag newtap $_CHIPNAME etb -irlen 4 -irmask 0x0f -expected-id $_ETBTAPID - -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - set _CPUTAPID 0x07926041 -} -jtag newtap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID - -jtag newtap $_CHIPNAME whatchacallit -irlen 4 -ircapture 0x0 -irmask 0x0 -expected-id 0x0 - -if { [info exists SDMATAPID] } { - set _SDMATAPID $SDMATAPID -} else { - set _SDMATAPID 0x0882301d -} -jtag newtap $_CHIPNAME sdma -irlen 5 -expected-id $_SDMATAPID - -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME arm926ejs -endian $_ENDIAN \ - -chain-position $_TARGETNAME - -# trace setup -etm config $_TARGETNAME 16 normal full etb -etb config $_TARGETNAME $_CHIPNAME.etb diff --git a/tcl/target/imx27.cfg b/tcl/target/imx27.cfg deleted file mode 100644 index e5a5035d4..000000000 --- a/tcl/target/imx27.cfg +++ /dev/null @@ -1,53 +0,0 @@ -# page 3-34 of "MCIMC27 Multimedia Applications Processor Reference Manual, Rev 0.3" -# SRST pulls TRST -# -# Without setting these options correctly you'll see all sorts -# of weird errors, e.g. MOE=0xe, invalid cpsr values, reset -# failing, etc. -reset_config trst_and_srst srst_pulls_trst - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME imx27 -} - -if { [info exists ENDIAN] } { - set _ENDIAN $ENDIAN -} else { - set _ENDIAN little -} - - -# Note above there are 2 taps - -# trace buffer -if { [info exists ETBTAPID] } { - set _ETBTAPID $ETBTAPID -} else { - set _ETBTAPID 0x1b900f0f -} -jtag newtap $_CHIPNAME etb -irlen 4 -irmask 0xf -expected-id $_ETBTAPID - -# The CPU tap -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - set _CPUTAPID 0x07926121 -} -jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID - -# Create the GDB Target. -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME arm926ejs -endian $_ENDIAN -chain-position $_TARGETNAME -# REVISIT what operating environment sets up this virtual address mapping? -$_TARGETNAME configure -work-area-virt 0xffff4c00 -work-area-phys 0xffff4c00 \ - -work-area-size 0x8000 -work-area-backup 1 -# Internal to the chip, there is 45K of SRAM -# - -arm7_9 dcc_downloads enable - -# trace setup -etm config $_TARGETNAME 16 normal full etb -etb config $_TARGETNAME $_CHIPNAME.etb diff --git a/tcl/target/imx28.cfg b/tcl/target/imx28.cfg deleted file mode 100644 index 4cc3950be..000000000 --- a/tcl/target/imx28.cfg +++ /dev/null @@ -1,38 +0,0 @@ -# i.MX28 config file. -# based off of the imx21.cfg file. - -reset_config trst_and_srst - -#jtag nTRST and nSRST delay -adapter_nsrst_delay 100 -jtag_ntrst_delay 100 - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME imx28 -} - -if { [info exists ENDIAN] } { - set _ENDIAN $ENDIAN -} else { - set _ENDIAN little -} - - -# Note above there is 1 tap - -# The CPU tap -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - set _CPUTAPID 0x079264f3 -} -jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID - - -# Create the GDB Target. -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME arm926ejs -endian $_ENDIAN -chain-position $_TARGETNAME - -arm7_9 dcc_downloads enable diff --git a/tcl/target/imx31.cfg b/tcl/target/imx31.cfg deleted file mode 100644 index ca639515f..000000000 --- a/tcl/target/imx31.cfg +++ /dev/null @@ -1,68 +0,0 @@ -# imx31 config -# - -reset_config trst_and_srst srst_gates_jtag - -adapter_nsrst_delay 5 - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME imx31 -} - -if { [info exists ENDIAN] } { - set _ENDIAN $ENDIAN -} else { - set _ENDIAN little -} - -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - set _CPUTAPID 0x07b3601d -} - -if { [info exists SDMATAPID] } { - set _SDMATAPID $SDMATAPID -} else { - set _SDMATAPID 0x2190101d -} - -if { [info exists ETBTAPID] } { - set _ETBTAPID $ETBTAPID -} else { - set _ETBTAPID 0x2b900f0f -} - -#======================================== - -jtag newtap $_CHIPNAME etb -irlen 4 -irmask 0xf -expected-id $_ETBTAPID - -# The "SDMA" - mart controller debug tap -# Based on some IO pins - this can be disabled & removed -# See diagram: 6-14 -# SIGNAL NAME: -# SJC_MOD - controls multiplexer - disables ARM1136 -# SDMA_BYPASS - disables SDMA - -# -# Per ARM: DDI0211J_arm1136_r1p5_trm.pdf - the ARM 1136 as a 5 bit IR register -jtag newtap $_CHIPNAME cpu -irlen 5 -ircapture 0x1 -irmask 0x1f -expected-id $_CPUTAPID - -# No IDCODE for this TAP -jtag newtap $_CHIPNAME whatchacallit -irlen 4 -ircapture 0 -irmask 0xf -expected-id 0x0 - -# Per section 40.17.1, table 40-85 the IR register is 4 bits -# But this conflicts with Diagram 6-13, "3bits ir and drs" -jtag newtap $_CHIPNAME smda -irlen 5 -ircapture 0x1 -irmask 0x1f -expected-id $_SDMATAPID - -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME arm11 -endian $_ENDIAN -chain-position $_TARGETNAME - - -proc power_restore {} { echo "Sensed power restore. No action." } -proc srst_deasserted {} { echo "Sensed nSRST deasserted. No action." } - -# trace setup ... NOTE, "normal full" mode fudges the real ETMv3.1 mode -etm config $_TARGETNAME 16 normal full etb -etb config $_TARGETNAME $_CHIPNAME.etb diff --git a/tcl/target/imx35.cfg b/tcl/target/imx35.cfg deleted file mode 100644 index 21495c23c..000000000 --- a/tcl/target/imx35.cfg +++ /dev/null @@ -1,55 +0,0 @@ -# imx35 config -# - -reset_config trst_and_srst srst_gates_jtag -jtag_ntrst_delay 100 - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME imx35 -} - -if { [info exists ENDIAN] } { - set _ENDIAN $ENDIAN -} else { - set _ENDIAN little -} - -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - set _CPUTAPID 0x07b3601d -} - -if { [info exists SDMATAPID] } { - set _SDMATAPID $SDMATAPID -} else { - set _SDMATAPID 0x0882601d -} - -if { [info exists ETBTAPID] } { - set _ETBTAPID $ETBTAPID -} else { - set _ETBTAPID 0x2b900f0f -} - -#======================================== - -jtag newtap $_CHIPNAME etb -irlen 4 -irmask 0xf -expected-id $_ETBTAPID -jtag newtap $_CHIPNAME cpu -irlen 5 -ircapture 0x1 -irmask 0x1f -expected-id $_CPUTAPID - -# No IDCODE for this TAP -jtag newtap $_CHIPNAME whatchacallit -irlen 4 -ircapture 0 -irmask 0x0 -expected-id 0x0 - -jtag newtap $_CHIPNAME smda -irlen 5 -ircapture 0x1 -irmask 0x1f -expected-id $_SDMATAPID - -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME arm11 -endian $_ENDIAN -chain-position $_TARGETNAME - -proc power_restore {} { echo "Sensed power restore. No action." } -proc srst_deasserted {} { echo "Sensed nSRST deasserted. No action." } - -# trace setup ... NOTE, "normal full" mode fudges the real ETMv3.1 mode -etm config $_TARGETNAME 16 normal full etb -etb config $_TARGETNAME $_CHIPNAME.etb diff --git a/tcl/target/imx51.cfg b/tcl/target/imx51.cfg deleted file mode 100644 index b143aad25..000000000 --- a/tcl/target/imx51.cfg +++ /dev/null @@ -1,47 +0,0 @@ -# Freescale i.MX51 - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME imx51 -} - -# CoreSight Debug Access Port -if { [info exists DAP_TAPID] } { - set _DAP_TAPID $DAP_TAPID -} else { - set _DAP_TAPID 0x1ba00477 -} - -jtag newtap $_CHIPNAME DAP -irlen 4 -ircapture 0x1 -irmask 0xf \ - -expected-id $_DAP_TAPID - -# SDMA / no IDCODE -jtag newtap $_CHIPNAME SDMA -irlen 4 -ircapture 0x0 -irmask 0xf - -# SJC -if { [info exists SJC_TAPID] } { - set _SJC_TAPID SJC_TAPID -} else { - set _SJC_TAPID 0x0190c01d -} - -jtag newtap $_CHIPNAME SJC -irlen 5 -ircapture 0x1 -irmask 0x1f \ - -expected-id $_SJC_TAPID -ignore-version - -# GDB target: Cortex-A8, using DAP -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME cortex_a -chain-position $_CHIPNAME.DAP - -# some TCK tycles are required to activate the DEBUG power domain -jtag configure $_CHIPNAME.SJC -event post-reset "runtest 100" - -# have the DAP "always" be active -jtag configure $_CHIPNAME.SJC -event setup "jtag tapenable $_CHIPNAME.DAP" - -proc imx51_dbginit {target} { - # General Cortex-A8 debug initialisation - cortex_a dbginit -} - -$_TARGETNAME configure -event reset-assert-post "imx51_dbginit $_TARGETNAME" diff --git a/tcl/target/imx53.cfg b/tcl/target/imx53.cfg deleted file mode 100644 index 87a3008e4..000000000 --- a/tcl/target/imx53.cfg +++ /dev/null @@ -1,47 +0,0 @@ -# Freescale i.MX53 - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME imx53 -} - -# CoreSight Debug Access Port -if { [info exists DAP_TAPID] } { - set _DAP_TAPID $DAP_TAPID -} else { - set _DAP_TAPID 0x1ba00477 -} - -jtag newtap $_CHIPNAME DAP -irlen 4 -ircapture 0x1 -irmask 0xf \ - -expected-id $_DAP_TAPID - -# SDMA / no IDCODE -jtag newtap $_CHIPNAME SDMA -irlen 4 -ircapture 0x0 -irmask 0xf - -# SJC -if { [info exists SJC_TAPID] } { - set _SJC_TAPID SJC_TAPID -} else { - set _SJC_TAPID 0x0190d01d -} - -jtag newtap $_CHIPNAME SJC -irlen 5 -ircapture 0x1 -irmask 0x1f \ - -expected-id $_SJC_TAPID -ignore-version - -# GDB target: Cortex-A8, using DAP -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME cortex_a -chain-position $_CHIPNAME.DAP - -# some TCK tycles are required to activate the DEBUG power domain -jtag configure $_CHIPNAME.SJC -event post-reset "runtest 100" - -# have the DAP "always" be active -jtag configure $_CHIPNAME.SJC -event setup "jtag tapenable $_CHIPNAME.DAP" - -proc imx53_dbginit {target} { - # General Cortex-A8 debug initialisation - cortex_a dbginit -} - -$_TARGETNAME configure -event reset-assert-post "imx53_dbginit $_TARGETNAME" diff --git a/tcl/target/imx6.cfg b/tcl/target/imx6.cfg deleted file mode 100644 index 4f7e98afd..000000000 --- a/tcl/target/imx6.cfg +++ /dev/null @@ -1,59 +0,0 @@ -# Freescale i.MX6 series single/dual/quad core processor - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME imx6 -} - -# CoreSight Debug Access Port -if { [info exists DAP_TAPID] } { - set _DAP_TAPID $DAP_TAPID -} else { - set _DAP_TAPID 0x4ba00477 -} - -jtag newtap $_CHIPNAME dap -irlen 4 -ircapture 0x01 -irmask 0x0f \ - -expected-id $_DAP_TAPID - -# SDMA / no IDCODE -jtag newtap $_CHIPNAME sdma -irlen 4 -ircapture 0x00 -irmask 0x0f - -# System JTAG Controller -if { [info exists SJC_TAPID] } { - set _SJC_TAPID $SJC_TAPID -} else { - set _SJC_TAPID 0x0191c01d -} -set _SJC_TAPID2 0x2191c01d -set _SJC_TAPID3 0x2191e01d -set _SJC_TAPID4 0x1191c01d - -jtag newtap $_CHIPNAME sjc -irlen 5 -ircapture 0x01 -irmask 0x1f \ - -expected-id $_SJC_TAPID -expected-id $_SJC_TAPID2 \ - -expected-id $_SJC_TAPID3 -expected-id $_SJC_TAPID4 - -# GDB target: Cortex-A9, using DAP, configuring only one core -# Base addresses of cores: -# core 0 - 0x82150000 -# core 1 - 0x82152000 -# core 2 - 0x82154000 -# core 3 - 0x82156000 -set _TARGETNAME $_CHIPNAME.cpu.0 -target create $_TARGETNAME cortex_a -chain-position $_CHIPNAME.dap \ - -coreid 0 -dbgbase 0x82150000 - -# some TCK cycles are required to activate the DEBUG power domain -jtag configure $_CHIPNAME.sjc -event post-reset "runtest 100" - -proc imx6_dbginit {target} { - # General Cortex-A8/A9 debug initialisation - cortex_a dbginit -} - -# Slow speed to be sure it will work -adapter_khz 1000 -$_TARGETNAME configure -event reset-start { adapter_khz 1000 } - -$_TARGETNAME configure -event reset-assert-post "imx6_dbginit $_TARGETNAME" -$_TARGETNAME configure -event gdb-attach { halt } diff --git a/tcl/target/is5114.cfg b/tcl/target/is5114.cfg deleted file mode 100644 index 31f1aa1aa..000000000 --- a/tcl/target/is5114.cfg +++ /dev/null @@ -1,46 +0,0 @@ -# script for Insilica IS-5114 -# AKA: Atmel AT76C114 - an ARM946 chip -# ATMEL sold his product line to Insilica... - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME is5114 -} - -if { [info exists ENDIAN] } { - set _ENDIAN $ENDIAN -} else { - # this defaults to a little endian - set _ENDIAN little -} - -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - # Force an error until we get a good number. - set _CPUTAPID 0xffffffff -} - -# jtag speed. We need to stick to 16kHz until we've finished reset. -adapter_khz 16 - -reset_config trst_and_srst - -# Do not specify a tap id here... -jtag newtap $_CHIPNAME unknown1 -irlen 8 -ircapture 0x01 -irmask 1 -# This is the "arm946" chip. -jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x0e -irmask 0xf -jtag newtap $_CHIPNAME unknown2 -irlen 5 -ircapture 1 -irmask 1 - - -#arm946e-s and -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME arm966e -endian $_ENDIAN -chain-position $_TARGETNAME - -$_TARGETNAME configure -event reset-start { adapter_khz 16 } -$_TARGETNAME configure -event reset-init { - # We can increase speed now that we know the target is halted. - adapter_khz 3000 -} -$_TARGETNAME configure -work-area-phys 0x50000000 -work-area-size 16384 -work-area-backup 1 diff --git a/tcl/target/ixp42x.cfg b/tcl/target/ixp42x.cfg deleted file mode 100644 index d7b5bf470..000000000 --- a/tcl/target/ixp42x.cfg +++ /dev/null @@ -1,107 +0,0 @@ -#xscale ixp42x CPU - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME ixp42x -} - -if { [info exists ENDIAN] } { - set _ENDIAN $ENDIAN -} else { - # this defaults to a bigendian - set _ENDIAN big -} - -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - set _CPUTAPID 0x19274013 -} -set _CPUTAPID2 0x19275013 -set _CPUTAPID3 0x19277013 -set _CPUTAPID4 0x29274013 -set _CPUTAPID5 0x29275013 -set _CPUTAPID6 0x29277013 - -jtag newtap $_CHIPNAME cpu -irlen 7 -ircapture 0x1 -irmask 0x7f -expected-id $_CPUTAPID -expected-id $_CPUTAPID2 -expected-id $_CPUTAPID3 -expected-id $_CPUTAPID4 -expected-id $_CPUTAPID5 -expected-id $_CPUTAPID6 - -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME xscale -endian $_ENDIAN -chain-position $_TARGETNAME - - -# register constants for IXP42x SDRAM controller -global IXP425_SDRAM_IR_MODE_SET_CAS2_CMD -global IXP425_SDRAM_IR_MODE_SET_CAS3_CMD -set IXP425_SDRAM_IR_MODE_SET_CAS2_CMD 0x0000 -set IXP425_SDRAM_IR_MODE_SET_CAS3_CMD 0x0001 - -global IXP42x_SDRAM_CL3 -global IXP42x_SDRAM_CL2 -set IXP42x_SDRAM_CL3 0x0008 -set IXP42x_SDRAM_CL2 0x0000 - -global IXP42x_SDRAM_8MB_2Mx32_1BANK -global IXP42x_SDRAM_16MB_2Mx32_2BANK -global IXP42x_SDRAM_16MB_4Mx16_1BANK -global IXP42x_SDRAM_32MB_4Mx16_2BANK -global IXP42x_SDRAM_32MB_8Mx16_1BANK -global IXP42x_SDRAM_64MB_8Mx16_2BANK -global IXP42x_SDRAM_64MB_16Mx16_1BANK -global IXP42x_SDRAM_128MB_16Mx16_2BANK -global IXP42x_SDRAM_128MB_32Mx16_1BANK -global IXP42x_SDRAM_256MB_32Mx16_2BANK - -set IXP42x_SDRAM_8MB_2Mx32_1BANK 0x0030 -set IXP42x_SDRAM_16MB_2Mx32_2BANK 0x0031 -set IXP42x_SDRAM_16MB_4Mx16_1BANK 0x0032 -set IXP42x_SDRAM_32MB_4Mx16_2BANK 0x0033 -set IXP42x_SDRAM_32MB_8Mx16_1BANK 0x0010 -set IXP42x_SDRAM_64MB_8Mx16_2BANK 0x0011 -set IXP42x_SDRAM_64MB_16Mx16_1BANK 0x0012 -set IXP42x_SDRAM_128MB_16Mx16_2BANK 0x0013 -set IXP42x_SDRAM_128MB_32Mx16_1BANK 0x0014 -set IXP42x_SDRAM_256MB_32Mx16_2BANK 0x0015 - - -# helper function to init SDRAM on IXP42x. -# SDRAM_CFG: one of IXP42X_SDRAM_xxx -# REFRESH: refresh counter reload value (integer) -# CASLAT: 2 or 3 -proc ixp42x_init_sdram { SDRAM_CFG REFRESH CASLAT } { - - switch $CASLAT { - 2 { - set SDRAM_CFG [expr $SDRAM_CFG | $::IXP42x_SDRAM_CL2 ] - set CASCMD $::IXP425_SDRAM_IR_MODE_SET_CAS2_CMD - } - 3 { - set SDRAM_CFG [expr $SDRAM_CFG | $::IXP42x_SDRAM_CL3 ] - set CASCMD $::IXP425_SDRAM_IR_MODE_SET_CAS3_CMD - } - default { error [format "unsupported cas latency \"%s\" " $CASLAT] } - } - echo [format "\tIXP42x SDRAM Config: 0x%x, Refresh %d " $SDRAM_CFG $REFRESH] - - mww 0xCC000000 $SDRAM_CFG ;# SDRAM_CFG: 0x2A: 64MBit, CL3 - mww 0xCC000004 0 ;# disable refresh - mww 0xCC000008 3 ;# NOP - sleep 100 - mww 0xCC000004 $REFRESH ;# set refresh counter - mww 0xCC000008 2 ;# Precharge All Banks - sleep 100 - mww 0xCC000008 4 ;# Auto Refresh - mww 0xCC000008 4 ;# Auto Refresh - mww 0xCC000008 4 ;# Auto Refresh - mww 0xCC000008 4 ;# Auto Refresh - mww 0xCC000008 4 ;# Auto Refresh - mww 0xCC000008 4 ;# Auto Refresh - mww 0xCC000008 4 ;# Auto Refresh - mww 0xCC000008 4 ;# Auto Refresh - mww 0xCC000008 $CASCMD ;# Mode Select CL2/CL3 -} - -proc ixp42x_set_bigendian { } { - reg XSCALE_CTRL 0xF8 -} - diff --git a/tcl/target/k1921vk01t.cfg b/tcl/target/k1921vk01t.cfg deleted file mode 100755 index 61b193e39..000000000 --- a/tcl/target/k1921vk01t.cfg +++ /dev/null @@ -1,55 +0,0 @@ -# K1921VK01T -# http://niiet.ru/chips/nis?id=354 - -source [find target/swj-dp.tcl] -source [find mem_helper.tcl] - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME k1921vk01t -} - -set _ENDIAN little - -# Work-area is a space in RAM used for flash programming -if { [info exists WORKAREASIZE] } { - set _WORKAREASIZE $WORKAREASIZE -} else { - set _WORKAREASIZE 0x10000 -} - -#jtag scan chain -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - if { [using_jtag] } { - set _CPUTAPID 0x4ba00477 - } { - # SWD IDCODE - set _CPUTAPID 0x2ba01477 - } -} -swj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID - -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME cortex_m -endian $_ENDIAN -chain-position $_TARGETNAME - -$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0 - -flash bank $_CHIPNAME.flash niietcm4 0 0 0 0 $_TARGETNAME - -adapter_khz 2000 - -adapter_nsrst_delay 100 -if {[using_jtag]} { - jtag_ntrst_delay 100 -} - -reset_config srst_nogate - -if {![using_hla]} { - # if srst is not fitted use SYSRESETREQ to - # perform a soft reset - cortex_m reset_config sysresetreq -} diff --git a/tcl/target/k40.cfg b/tcl/target/k40.cfg deleted file mode 100644 index 981161156..000000000 --- a/tcl/target/k40.cfg +++ /dev/null @@ -1,6 +0,0 @@ -# -# Freescale Kinetis K40 devices -# - -set CHIPNAME k40 -source [find target/kx.cfg] diff --git a/tcl/target/k60.cfg b/tcl/target/k60.cfg deleted file mode 100644 index b9c5e3a1e..000000000 --- a/tcl/target/k60.cfg +++ /dev/null @@ -1,6 +0,0 @@ -# -# Freescale Kinetis K60 devices -# - -set CHIPNAME k60 -source [find target/kx.cfg] diff --git a/tcl/target/ke02.cfg b/tcl/target/ke02.cfg deleted file mode 100644 index 8311920ad..000000000 --- a/tcl/target/ke02.cfg +++ /dev/null @@ -1,6 +0,0 @@ -# -# Freescale Kinetis KE02 devices -# - -set CHIPNAME ke02 -source [find target/kex.cfg] diff --git a/tcl/target/ke04.cfg b/tcl/target/ke04.cfg deleted file mode 100644 index f63d77c5e..000000000 --- a/tcl/target/ke04.cfg +++ /dev/null @@ -1,6 +0,0 @@ -# -# Freescale Kinetis KE04 devices -# - -set CHIPNAME ke04 -source [find target/kex.cfg] diff --git a/tcl/target/ke06.cfg b/tcl/target/ke06.cfg deleted file mode 100644 index 3465b8b33..000000000 --- a/tcl/target/ke06.cfg +++ /dev/null @@ -1,6 +0,0 @@ -# -# Freescale Kinetis KE06 devices -# - -set CHIPNAME ke06 -source [find target/kex.cfg] diff --git a/tcl/target/kex.cfg b/tcl/target/kex.cfg deleted file mode 100644 index dca8a35ab..000000000 --- a/tcl/target/kex.cfg +++ /dev/null @@ -1,58 +0,0 @@ -# -# Freescale Kinetis KE series devices -# - -source [find target/swj-dp.tcl] - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME ke -} - -# Work-area is a space in RAM used for flash programming -# By default use 1kB -if { [info exists WORKAREASIZE] } { - set _WORKAREASIZE $WORKAREASIZE -} else { - set _WORKAREASIZE 0x400 -} - -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - if { [using_jtag] } { - set _CPUTAPID 0x4ba00477 - } { - set _CPUTAPID 0x2ba01477 - } -} - -swj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID - -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME cortex_m -chain-position $_CHIPNAME.cpu - -$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0 - -set _FLASHNAME $_CHIPNAME.flash -flash bank $_FLASHNAME kinetis_ke 0 0 0 0 $_TARGETNAME - -adapter_khz 1000 - -reset_config srst_nogate - -if {![using_hla]} { - - # It is important that "kinetis_ke mdm check_security" is called for - # 'examine-end' event and not 'eximine-start'. Calling it in 'examine-start' - # causes "kinetis_ke mdm check_security" to fail the first time openocd - # calls it when it tries to connect after the CPU has been power-cycled. - $_CHIPNAME.cpu configure -event examine-end { - kinetis_ke mdm check_security - } - - # if srst is not fitted use SYSRESETREQ to - # perform a soft reset - cortex_m reset_config sysresetreq -} diff --git a/tcl/target/kl25.cfg b/tcl/target/kl25.cfg deleted file mode 100644 index 0e716e3ae..000000000 --- a/tcl/target/kl25.cfg +++ /dev/null @@ -1,6 +0,0 @@ -# -# Freescale Kinetis KL25 devices -# - -set CHIPNAME kl25 -source [find target/klx.cfg] diff --git a/tcl/target/kl25z_hla.cfg b/tcl/target/kl25z_hla.cfg deleted file mode 100644 index e4deac615..000000000 --- a/tcl/target/kl25z_hla.cfg +++ /dev/null @@ -1,2 +0,0 @@ -echo "WARNING: target/kl25z_hla.cfg is deprecated, please switch to target/kl25.cfg" -source [find target/kl25.cfg] diff --git a/tcl/target/kl46.cfg b/tcl/target/kl46.cfg deleted file mode 100644 index 70ea273ee..000000000 --- a/tcl/target/kl46.cfg +++ /dev/null @@ -1,6 +0,0 @@ -# -# Freescale Kinetis KL46 devices -# - -set CHIPNAME kl46 -source [find target/klx.cfg] diff --git a/tcl/target/klx.cfg b/tcl/target/klx.cfg deleted file mode 100644 index 0df6612f7..000000000 --- a/tcl/target/klx.cfg +++ /dev/null @@ -1,60 +0,0 @@ -# -# Freescale Kinetis KL series devices -# - -source [find target/swj-dp.tcl] - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME klx -} - -# Work-area is a space in RAM used for flash programming -# By default use 4kB -if { [info exists WORKAREASIZE] } { - set _WORKAREASIZE $WORKAREASIZE -} else { - set _WORKAREASIZE 0x1000 -} - -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - set _CPUTAPID 0x0bc11477 -} - -swj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID - -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME cortex_m -chain-position $_CHIPNAME.cpu - -$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0 - -set _FLASHNAME $_CHIPNAME.flash -flash bank $_FLASHNAME kinetis 0 0 0 0 $_TARGETNAME - -# Table 5-1. Clock Summary of KL25 Sub-Family Reference Manual -# specifies up to 1MHz for VLPR mode. -adapter_khz 1000 - -reset_config srst_nogate - -if {![using_hla]} { - # Detect secured MCU or boot lock-up in RESET/WDOG loop - $_CHIPNAME.cpu configure -event examine-start { - kinetis mdm check_security - } - - # if srst is not fitted use SYSRESETREQ to - # perform a soft reset - cortex_m reset_config sysresetreq -} - -# Table 5-1. Clock Summary of KL25 Sub-Family Reference Manual -# specifies up to 24MHz for run mode; Table 17 of Sub-Family Data -# Sheet rev4 lists 25MHz as the maximum frequency. -# Uncoment only if VLPR mode is not used -#$_TARGETNAME configure -event reset-init { -# adapter_khz 24000 -#} diff --git a/tcl/target/ks869x.cfg b/tcl/target/ks869x.cfg deleted file mode 100644 index 0f6829c91..000000000 --- a/tcl/target/ks869x.cfg +++ /dev/null @@ -1,34 +0,0 @@ -# ARM920T CPU - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME ks869x -} - -if { [info exists ENDIAN] } { - set _ENDIAN $ENDIAN -} else { - set _ENDIAN little -} - -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - set _CPUTAPID 0x00922f0f -} - -adapter_khz 6000 - -# jtag scan chain -jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID - -set _TARGETNAME $_CHIPNAME.cpu - -target create $_TARGETNAME arm920t -endian $_ENDIAN -chain-position $_TARGETNAME - -$_TARGETNAME configure -work-area-phys 0x20000 -work-area-size 0x20000 -work-area-backup 0 - -# speed up memory downloads -arm7_9 fast_memory_access enable -arm7_9 dcc_downloads enable diff --git a/tcl/target/kx.cfg b/tcl/target/kx.cfg deleted file mode 100644 index b39ee3dd1..000000000 --- a/tcl/target/kx.cfg +++ /dev/null @@ -1,54 +0,0 @@ -# -# Freescale Kinetis Kx series devices -# - -source [find target/swj-dp.tcl] - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME kx -} - -# Work-area is a space in RAM used for flash programming -# By default use 4kB -if { [info exists WORKAREASIZE] } { - set _WORKAREASIZE $WORKAREASIZE -} else { - set _WORKAREASIZE 0x1000 -} - -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - if { [using_jtag] } { - set _CPUTAPID 0x4ba00477 - } { - set _CPUTAPID 0x2ba01477 - } -} - -swj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID - -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME cortex_m -chain-position $_CHIPNAME.cpu - -$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0 - -set _FLASHNAME $_CHIPNAME.flash -flash bank $_FLASHNAME kinetis 0 0 0 0 $_TARGETNAME - -adapter_khz 1000 - -reset_config srst_nogate - -if {![using_hla]} { - # Detect secured MCU or boot lock-up in RESET/WDOG loop - $_CHIPNAME.cpu configure -event examine-start { - kinetis mdm check_security - } - - # if srst is not fitted use SYSRESETREQ to - # perform a soft reset - cortex_m reset_config sysresetreq -} diff --git a/tcl/target/lpc11xx.cfg b/tcl/target/lpc11xx.cfg deleted file mode 100644 index 7a65c1f47..000000000 --- a/tcl/target/lpc11xx.cfg +++ /dev/null @@ -1,8 +0,0 @@ -# NXP LPC11xx Cortex-M0 with at least 1kB SRAM -set CHIPNAME lpc11xx -set CHIPSERIES lpc1100 -if { ![info exists WORKAREASIZE] } { - set WORKAREASIZE 0x400 -} - -source [find target/lpc1xxx.cfg] diff --git a/tcl/target/lpc12xx.cfg b/tcl/target/lpc12xx.cfg deleted file mode 100644 index a37c6febc..000000000 --- a/tcl/target/lpc12xx.cfg +++ /dev/null @@ -1,8 +0,0 @@ -# NXP LPC12xx Cortex-M0 with at least 4kB SRAM -set CHIPNAME lpc12xx -set CHIPSERIES lpc1200 -if { ![info exists WORKAREASIZE] } { - set WORKAREASIZE 0x1000 -} - -source [find target/lpc1xxx.cfg] diff --git a/tcl/target/lpc13xx.cfg b/tcl/target/lpc13xx.cfg deleted file mode 100644 index 3d128c963..000000000 --- a/tcl/target/lpc13xx.cfg +++ /dev/null @@ -1,8 +0,0 @@ -# NXP LPC13xx Cortex-M3 with at least 4kB SRAM -set CHIPNAME lpc13xx -set CHIPSERIES lpc1300 -if { ![info exists WORKAREASIZE] } { - set WORKAREASIZE 0x1000 -} - -source [find target/lpc1xxx.cfg] diff --git a/tcl/target/lpc17xx.cfg b/tcl/target/lpc17xx.cfg deleted file mode 100644 index dccf880da..000000000 --- a/tcl/target/lpc17xx.cfg +++ /dev/null @@ -1,8 +0,0 @@ -# NXP LPC17xx Cortex-M3 with at least 8kB SRAM -set CHIPNAME lpc17xx -set CHIPSERIES lpc1700 -if { ![info exists WORKAREASIZE] } { - set WORKAREASIZE 0x2000 -} - -source [find target/lpc1xxx.cfg] diff --git a/tcl/target/lpc1850.cfg b/tcl/target/lpc1850.cfg deleted file mode 100644 index a78140374..000000000 --- a/tcl/target/lpc1850.cfg +++ /dev/null @@ -1,34 +0,0 @@ -source [find target/swj-dp.tcl] - -adapter_khz 500 - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME lpc1850 -} - -if { [info exists ENDIAN] } { - set _ENDIAN $ENDIAN -} else { - set _ENDIAN little -} -# -# M3 JTAG mode TAP -# -if { [info exists M3_JTAG_TAPID] } { - set _M3_JTAG_TAPID $M3_JTAG_TAPID -} else { - set _M3_JTAG_TAPID 0x4ba00477 -} - -swj_newdap $_CHIPNAME m3 -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_M3_JTAG_TAPID - -set _TARGETNAME $_CHIPNAME.m3 -target create $_TARGETNAME cortex_m -endian $_ENDIAN -chain-position $_TARGETNAME - -if {![using_hla]} { - # if srst is not fitted use SYSRESETREQ to - # perform a soft reset - cortex_m reset_config sysresetreq -} diff --git a/tcl/target/lpc1xxx.cfg b/tcl/target/lpc1xxx.cfg deleted file mode 100644 index 9c10e9f93..000000000 --- a/tcl/target/lpc1xxx.cfg +++ /dev/null @@ -1,159 +0,0 @@ -# Main file for NXP LPC1xxx/LPC40xx series Cortex-M0/0+/3/4F parts -# -# !!!!!! -# -# This file should not be included directly, rather by the lpc11xx.cfg, -# lpc13xx.cfg, lpc17xx.cfg, etc. which set the needed variables to the -# appropriate values. -# -# !!!!!! - -# LPC8xx chips support only SWD transport. -# LPC11xx chips support only SWD transport. -# LPC12xx chips support only SWD transport. -# LPC11Uxx chips support only SWD transports. -# LPC13xx chips support only SWD transports. -# LPC17xx chips support both JTAG and SWD transports. -# LPC40xx chips support both JTAG and SWD transports. -# Adapt based on what transport is active. -source [find target/swj-dp.tcl] - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - error "CHIPNAME not set. Please do not include lpc1xxx.cfg directly, but the specific chip configuration file (lpc11xx.cfg, lpc13xx.cfg, lpc17xx.cfg, etc)." -} - -if { [info exists CHIPSERIES] } { - # Validate chip series is supported - if { $CHIPSERIES != "lpc800" && $CHIPSERIES != "lpc1100" && $CHIPSERIES != "lpc1200" && $CHIPSERIES != "lpc1300" && $CHIPSERIES != "lpc1700" && $CHIPSERIES != "lpc4000" } { - error "Unsupported LPC1xxx chip series specified." - } - set _CHIPSERIES $CHIPSERIES -} else { - error "CHIPSERIES not set. Please do not include lpc1xxx.cfg directly, but the specific chip configuration file (lpc11xx.cfg, lpc13xx.cfg, lpc17xx.cfg, etc)." -} - -# After reset, the chip is clocked by an internal RC oscillator. -# When board-specific code (reset-init handler or device firmware) -# configures another oscillator and/or PLL0, set CCLK to match; if -# you don't, then flash erase and write operations may misbehave. -# (The ROM code doing those updates cares about core clock speed...) -# CCLK is the core clock frequency in KHz -if { [info exists CCLK] } { - # Allow user override - set _CCLK $CCLK -} else { - # LPC8xx/LPC11xx/LPC12xx/LPC13xx use a 12MHz one, LPC17xx uses a 4MHz one(except for LPC177x/8x,LPC407x/8x) - if { $_CHIPSERIES == "lpc800" || $_CHIPSERIES == "lpc1100" || $_CHIPSERIES == "lpc1200" || $_CHIPSERIES == "lpc1300" } { - set _CCLK 12000 - } elseif { $_CHIPSERIES == "lpc1700" || $_CHIPSERIES == "lpc4000" } { - set _CCLK 4000 - } -} - -if { [info exists CPUTAPID] } { - # Allow user override - set _CPUTAPID $CPUTAPID -} else { - # LPC8xx/LPC11xx/LPC12xx use a Cortex-M0/M0+ core, LPC13xx/LPC17xx use a Cortex-M3 core, LPC40xx use a Cortex-M4F core. - if { $_CHIPSERIES == "lpc800" || $_CHIPSERIES == "lpc1100" || $_CHIPSERIES == "lpc1200" } { - set _CPUTAPID 0x0bb11477 - } elseif { $_CHIPSERIES == "lpc1300" || $_CHIPSERIES == "lpc1700" || $_CHIPSERIES == "lpc4000" } { - if { [using_jtag] } { - set _CPUTAPID 0x4ba00477 - } { - set _CPUTAPID 0x2ba01477 - } - } -} - -if { [info exists WORKAREASIZE] } { - set _WORKAREASIZE $WORKAREASIZE -} else { - error "WORKAREASIZE is not set. The $CHIPNAME part is available in several Flash and RAM size configurations. Please set WORKAREASIZE." -} - -swj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID - -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME cortex_m -chain-position $_TARGETNAME - -# The LPC11xx devices have 2/4/8kB of SRAM in the ARMv7-M "Code" area (at 0x10000000) -# The LPC12xx devices have 4/8kB of SRAM in the ARMv7-M "Code" area (at 0x10000000) -# The LPC11Uxx devices have 4/6/8kB of SRAM in the ARMv7-M "Code" area (at 0x10000000) -# The LPC13xx devices have 4/8kB of SRAM in the ARMv7-M "Code" area (at 0x10000000) -# The LPC17xx devices have 8/16/32/64kB of SRAM in the ARMv7-M "Code" area (at 0x10000000) -# The LPC40xx devices have 16/32/64kB of SRAM in the ARMv7-ME "Code" area (at 0x10000000) -$_TARGETNAME configure -work-area-phys 0x10000000 -work-area-size $_WORKAREASIZE - -# The LPC11xx devies have 8/16/24/32/48/56/64kB of flash memory (at 0x00000000) -# The LPC12xx devies have 32/48/64/80/96/128kB of flash memory (at 0x00000000) -# The LPC11Uxx devies have 16/24/32/40/48/64/96/128kB of flash memory (at 0x00000000) -# The LPC13xx devies have 8/16/32kB of flash memory (at 0x00000000) -# The LPC17xx devies have 32/64/128/256/512kB of flash memory (at 0x00000000) -# The LPC40xx devies have 64/128/256/512kB of flash memory (at 0x00000000) -# -# All are compatible with the "lpc1700" variant of the LPC2000 flash driver -# (same cmd51 destination boundary alignment, and all three support 256 byte -# transfers). -# -# flash bank lpc2000 0 0 [calc checksum] -set _FLASHNAME $_CHIPNAME.flash -flash bank $_FLASHNAME lpc2000 0x0 0 0 0 $_TARGETNAME \ - auto $_CCLK calc_checksum - -if { $_CHIPSERIES == "lpc800" || $_CHIPSERIES == "lpc1100" || $_CHIPSERIES == "lpc1200" || $_CHIPSERIES == "lpc1300" } { - # Do not remap 0x0000-0x0200 to anything but the flash (i.e. select - # "User Flash Mode" where interrupt vectors are _not_ remapped, - # and reside in flash instead). - # - # Table 8. System memory remap register (SYSMEMREMAP, address 0x4004 8000) bit description - # Bit Symbol Value Description - # 1:0 MAP System memory remap - # 0x0 Boot Loader Mode. Interrupt vectors are re-mapped to Boot ROM. - # 0x1 User RAM Mode. Interrupt vectors are re-mapped to Static RAM. - # 0x2 User Flash Mode. Interrupt vectors are not re-mapped and reside in Flash. - # 31:2 - - Reserved. - $_TARGETNAME configure -event reset-init { - mww 0x40048000 0x02 - } -} elseif { $_CHIPSERIES == "lpc1700" || $_CHIPSERIES == "lpc4000" } { - # Do not remap 0x0000-0x0020 to anything but the flash (i.e. select - # "User Flash Mode" where interrupt vectors are _not_ remapped, - # and reside in flash instead). - # - # See Table 612. Memory Mapping Control register (MEMMAP - 0x400F C040) bit description - # Bit Symbol Value Description Reset - # value - # 0 MAP Memory map control. 0 - # 0 Boot mode. A portion of the Boot ROM is mapped to address 0. - # 1 User mode. The on-chip Flash memory is mapped to address 0. - # 31:1 - Reserved. The value read from a reserved bit is not defined. NA - # - # http://ics.nxp.com/support/documents/microcontrollers/?scope=LPC1768&type=user - $_TARGETNAME configure -event reset-init { - mww 0x400FC040 0x01 - } -} - -# Run with *real slow* clock by default since the -# boot rom could have been playing with the PLL, so -# we have no idea what clock the target is running at. -adapter_khz 10 - -# delays on reset lines -adapter_nsrst_delay 200 -if {[using_jtag]} { - jtag_ntrst_delay 200 -} - -# LPC8xx (Cortex-M0+ core) support SYSRESETREQ -# LPC11xx/LPC12xx (Cortex-M0 core) support SYSRESETREQ -# LPC13xx/LPC17xx (Cortex-M3 core) support SYSRESETREQ -# LPC40xx (Cortex-M4F core) support SYSRESETREQ -if {![using_hla]} { - # if srst is not fitted use SYSRESETREQ to - # perform a soft reset - cortex_m reset_config sysresetreq -} diff --git a/tcl/target/lpc2103.cfg b/tcl/target/lpc2103.cfg deleted file mode 100644 index f55777f56..000000000 --- a/tcl/target/lpc2103.cfg +++ /dev/null @@ -1,21 +0,0 @@ -# NXP LPC2103 ARM7TDMI-S with 32kB flash and 8kB SRAM, clocked with 12MHz crystal - -source [find target/lpc2xxx.cfg] - -# parameters: -# - core_freq_khz - frequency of core in kHz during flashing, usually equal to connected crystal or internal oscillator, e.g. 12000 -# - adapter_freq_khz - frequency of debug adapter in kHz, should be 8x slower than core_freq_khz, e.g. 1000 - -proc setup_lpc2103 {core_freq_khz adapter_freq_khz} { - # 32kB flash and 8kB SRAM - # setup_lpc2xxx - setup_lpc2xxx lpc2103 0x4f1f0f0f 0x8000 lpc2000_v2 0x2000 $core_freq_khz $adapter_freq_khz -} - -proc init_targets {} { - # default to core clocked with 12MHz crystal - echo "Warning - assuming default core clock 12MHz! Flashing may fail if actual core clock is different." - - # setup_lpc2103 - setup_lpc2103 12000 1500 -} diff --git a/tcl/target/lpc2124.cfg b/tcl/target/lpc2124.cfg deleted file mode 100644 index 02517381a..000000000 --- a/tcl/target/lpc2124.cfg +++ /dev/null @@ -1,21 +0,0 @@ -# NXP LPC2124 ARM7TDMI-S with 256kB flash and 16kB SRAM, clocked with 12MHz crystal - -source [find target/lpc2xxx.cfg] - -# parameters: -# - core_freq_khz - frequency of core in kHz during flashing, usually equal to connected crystal or internal oscillator, e.g. 12000 -# - adapter_freq_khz - frequency of debug adapter in kHz, should be 8x slower than core_freq_khz, e.g. 1000 - -proc setup_lpc2124 {core_freq_khz adapter_freq_khz} { - # 256kB flash and 16kB SRAM - # setup_lpc2xxx - setup_lpc2xxx lpc2124 0x4f1f0f0f 0x40000 lpc2000_v1 0x4000 $core_freq_khz $adapter_freq_khz -} - -proc init_targets {} { - # default to core clocked with 12MHz crystal - echo "Warning - assuming default core clock 12MHz! Flashing may fail if actual core clock is different." - - # setup_lpc2124 - setup_lpc2124 12000 1500 -} diff --git a/tcl/target/lpc2129.cfg b/tcl/target/lpc2129.cfg deleted file mode 100644 index 2c33cde31..000000000 --- a/tcl/target/lpc2129.cfg +++ /dev/null @@ -1,21 +0,0 @@ -# NXP LPC2129 ARM7TDMI-S with 256kB flash and 16kB SRAM, clocked with 12MHz crystal - -source [find target/lpc2xxx.cfg] - -# parameters: -# - core_freq_khz - frequency of core in kHz during flashing, usually equal to connected crystal or internal oscillator, e.g. 12000 -# - adapter_freq_khz - frequency of debug adapter in kHz, should be 8x slower than core_freq_khz, e.g. 1000 - -proc setup_lpc2129 {core_freq_khz adapter_freq_khz} { - # 256kB flash and 16kB SRAM - # setup_lpc2xxx - setup_lpc2xxx lpc2129 0xcf1f0f0f 0x40000 lpc2000_v1 0x4000 $core_freq_khz $adapter_freq_khz -} - -proc init_targets {} { - # default to core clocked with 12MHz crystal - echo "Warning - assuming default core clock 12MHz! Flashing may fail if actual core clock is different." - - # setup_lpc2129 - setup_lpc2129 12000 1500 -} diff --git a/tcl/target/lpc2148.cfg b/tcl/target/lpc2148.cfg deleted file mode 100644 index f3a2011a8..000000000 --- a/tcl/target/lpc2148.cfg +++ /dev/null @@ -1,21 +0,0 @@ -# NXP LPC2148 ARM7TDMI-S with 512kB flash (12kB used by bootloader) and 40kB SRAM (8kB for USB DMA), clocked with 12MHz crystal - -source [find target/lpc2xxx.cfg] - -# parameters: -# - core_freq_khz - frequency of core in kHz during flashing, usually equal to connected crystal or internal oscillator, e.g. 12000 -# - adapter_freq_khz - frequency of debug adapter in kHz, should be 8x slower than core_freq_khz, e.g. 1000 - -proc setup_lpc2148 {core_freq_khz adapter_freq_khz} { - # 500kB flash and 32kB SRAM - # setup_lpc2xxx - setup_lpc2xxx lpc2148 "0x3f0f0f0f 0x4f1f0f0f" 0x7d000 lpc2000_v2 0x8000 $core_freq_khz $adapter_freq_khz -} - -proc init_targets {} { - # default to core clocked with 12MHz crystal - echo "Warning - assuming default core clock 12MHz! Flashing may fail if actual core clock is different." - - # setup_lpc2148 - setup_lpc2148 12000 1500 -} diff --git a/tcl/target/lpc2294.cfg b/tcl/target/lpc2294.cfg deleted file mode 100644 index 83d595deb..000000000 --- a/tcl/target/lpc2294.cfg +++ /dev/null @@ -1,23 +0,0 @@ -# NXP LPC2294 ARM7TDMI-S with 256kB flash and 16kB SRAM, clocked with 12MHz crystal - -source [find target/lpc2xxx.cfg] - -# parameters: -# - core_freq_khz - frequency of core in kHz during flashing, usually equal to connected crystal or internal oscillator, e.g. 12000 -# - adapter_freq_khz - frequency of debug adapter in kHz, should be 8x slower than core_freq_khz, e.g. 1000 - -proc setup_lpc2294 {core_freq_khz adapter_freq_khz} { - # 256kB flash and 16kB SRAM - # setup_lpc2xxx - - # !! TAPID unknown !! - setup_lpc2xxx lpc2294 0xffffffff 0x40000 lpc2000_v1 0x4000 $core_freq_khz $adapter_freq_khz -} - -proc init_targets {} { - # default to core clocked with 12MHz crystal - echo "Warning - assuming default core clock 12MHz! Flashing may fail if actual core clock is different." - - # setup_lpc2294 - setup_lpc2294 12000 1500 -} diff --git a/tcl/target/lpc2378.cfg b/tcl/target/lpc2378.cfg deleted file mode 100644 index 0b66b8255..000000000 --- a/tcl/target/lpc2378.cfg +++ /dev/null @@ -1,21 +0,0 @@ -# NXP LPC2378 ARM7TDMI-S with 512kB flash (8kB used by bootloader) and 56kB SRAM (16kB for ETH, 8kB for DMA), clocked with 4MHz internal oscillator - -source [find target/lpc2xxx.cfg] - -# parameters: -# - core_freq_khz - frequency of core in kHz during flashing, usually equal to connected crystal or internal oscillator, e.g. 12000 -# - adapter_freq_khz - frequency of debug adapter in kHz, should be 8x slower than core_freq_khz, e.g. 1000 - -proc setup_lpc2378 {core_freq_khz adapter_freq_khz} { - # 504kB flash and 32kB SRAM - # setup_lpc2xxx - setup_lpc2xxx lpc2378 0x4f1f0f0f 0x7e000 lpc2000_v2 0x8000 $core_freq_khz $adapter_freq_khz -} - -proc init_targets {} { - # default to core clocked with 4MHz internal oscillator - echo "Warning - assuming default core clock 4MHz! Flashing may fail if actual core clock is different." - - # setup_lpc2378 - setup_lpc2378 4000 500 -} diff --git a/tcl/target/lpc2460.cfg b/tcl/target/lpc2460.cfg deleted file mode 100644 index 69fdc4aaf..000000000 --- a/tcl/target/lpc2460.cfg +++ /dev/null @@ -1,21 +0,0 @@ -# NXP LPC2460 ARM7TDMI-S with 98kB SRAM (16kB for ETH, 16kB for DMA, 2kB for RTC), clocked with 4MHz internal oscillator - -source [find target/lpc2xxx.cfg] - -# parameters: -# - core_freq_khz - frequency of core in kHz during flashing, usually equal to connected crystal or internal oscillator, e.g. 12000 -# - adapter_freq_khz - frequency of debug adapter in kHz, should be 8x slower than core_freq_khz, e.g. 1000 - -proc setup_lpc2460 {core_freq_khz adapter_freq_khz} { - # 64kB SRAM - # setup_lpc2xxx - setup_lpc2xxx lpc2460 0x4f1f0f0f 0 lpc2000_v2 0x10000 $core_freq_khz $adapter_freq_khz -} - -proc init_targets {} { - # default to core clocked with 4MHz internal oscillator - echo "Warning - assuming default core clock 4MHz! Flashing may fail if actual core clock is different." - - # setup_lpc2460 - setup_lpc2460 4000 500 -} diff --git a/tcl/target/lpc2478.cfg b/tcl/target/lpc2478.cfg deleted file mode 100644 index 48e5bdf3f..000000000 --- a/tcl/target/lpc2478.cfg +++ /dev/null @@ -1,21 +0,0 @@ -# NXP LPC2478 ARM7TDMI-S with 512kB flash (8kB used by bootloader) and 98kB SRAM (16kB for ETH, 16kB for DMA, 2kB for RTC), clocked with 4MHz internal oscillator - -source [find target/lpc2xxx.cfg] - -# parameters: -# - core_freq_khz - frequency of core in kHz during flashing, usually equal to connected crystal or internal oscillator, e.g. 12000 -# - adapter_freq_khz - frequency of debug adapter in kHz, should be 8x slower than core_freq_khz, e.g. 1000 - -proc setup_lpc2478 {core_freq_khz adapter_freq_khz} { - # 504kB flash and 64kB SRAM - # setup_lpc2xxx - setup_lpc2xxx lpc2478 0x4f1f0f0f 0x7e000 lpc2000_v2 0x10000 $core_freq_khz $adapter_freq_khz -} - -proc init_targets {} { - # default to core clocked with 4MHz internal oscillator - echo "Warning - assuming default core clock 4MHz! Flashing may fail if actual core clock is different." - - # setup_lpc2478 - setup_lpc2478 4000 500 -} diff --git a/tcl/target/lpc2900.cfg b/tcl/target/lpc2900.cfg deleted file mode 100644 index 53677873a..000000000 --- a/tcl/target/lpc2900.cfg +++ /dev/null @@ -1,66 +0,0 @@ - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME lpc2900 -} - -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - set _CPUTAPID 0x0596802B -} - -if { [info exists HAS_ETB] } { -} else { - # Set default (no ETB). - # Show a warning, because this should have been configured explicitely. - set HAS_ETB 0 - # TODO: warning? -} - -if { [info exists ETBTAPID] } { - set _ETBTAPID $ETBTAPID -} else { - set _ETBTAPID 0x1B900F0F -} - -# TRST and SRST both exist, and can be controlled independently -reset_config trst_and_srst separate - -# Define the _TARGETNAME -set _TARGETNAME $_CHIPNAME.cpu - -# Include the ETB tap controller if asked for. -# Has to be done manually for newer devices (not an "old" LPC2917/2919). -if { $HAS_ETB == 1 } { - # Clear the HAS_ETB flag. Must be set again for a new tap in the chain. - set HAS_ETB 0 - - # Add the ETB tap controller and the ARM9 core debug tap - jtag newtap $_CHIPNAME etb -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_ETBTAPID - jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID - - # Create the ".cpu" target - target create $_TARGETNAME arm966e -endian little -chain-position $_TARGETNAME - - # Configure ETM and ETB - etm config $_TARGETNAME 8 normal full etb - etb config $_TARGETNAME $_CHIPNAME.etb - -} else { - # Add the ARM9 core debug tap - jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID - - # Create the ".cpu" target - target create $_TARGETNAME arm966e -endian little -chain-position $_TARGETNAME -} - -arm7_9 dbgrq enable -arm7_9 dcc_downloads enable - -# Flash bank configuration: -# Flash: flash bank lpc2900 0 0 0 0 -# Flash base address, total flash size, and number of sectors are all configured automatically. -set _FLASHNAME $_CHIPNAME.flash -flash bank $_FLASHNAME lpc2900 0 0 0 0 $_TARGETNAME $FLASH_CLOCK diff --git a/tcl/target/lpc2xxx.cfg b/tcl/target/lpc2xxx.cfg deleted file mode 100644 index 11f1c48bc..000000000 --- a/tcl/target/lpc2xxx.cfg +++ /dev/null @@ -1,44 +0,0 @@ -# Common setup for the LPC2xxx parts - -# parameters: -# - chip_name - name of the chip, e.g. lpc2103 -# - cputapids - TAP IDs of the core, should be quoted if more than one, e.g. 0x4f1f0f0f or "0x3f0f0f0f 0x4f1f0f0f" -# - flash_size - size of on-chip flash (available for code, not including the bootloader) in bytes, e.g. 0x8000 -# - flash_variant - "type" of LPC2xxx device, lpc2000_v1 (LPC22xx and older LPC21xx) or lpc2000_v2 (LPC213x, LPC214x, LPC210[123], LPC23xx and LPC24xx) -# - workarea_size - size of work-area in RAM for flashing procedures, must not exceed the size of RAM available at 0x40000000, e.g. 0x2000 -# - core_freq_khz - frequency of core in kHz during flashing, usually equal to connected crystal or internal oscillator, e.g. 12000 -# - adapter_freq_khz - frequency of debug adapter in kHz, should be 8x slower than core_freq_khz, e.g. 1000 - -proc setup_lpc2xxx {chip_name cputapids flash_size flash_variant workarea_size core_freq_khz adapter_freq_khz} { - reset_config trst_and_srst - - # reset delays - adapter_nsrst_delay 100 - jtag_ntrst_delay 100 - - adapter_khz $adapter_freq_khz - - foreach i $cputapids { - append expected_ids "-expected-id " $i " " - } - - eval "jtag newtap $chip_name cpu -irlen 4 -ircapture 0x1 -irmask 0xf $expected_ids" - - global _TARGETNAME - set _TARGETNAME $chip_name.cpu - target create $_TARGETNAME arm7tdmi -chain-position $_TARGETNAME - - $_TARGETNAME configure -work-area-phys 0x40000000 -work-area-size $workarea_size -work-area-backup 0 - - if { $flash_size > 0 } { - # flash bank lpc2000 0 0 [calc checksum] - set _FLASHNAME $chip_name.flash - flash bank $_FLASHNAME lpc2000 0x0 $flash_size 0 0 $_TARGETNAME $flash_variant $core_freq_khz calc_checksum - } -} - -proc init_targets {} { - # FIX!!! read out CPUTAPID here and choose right setup. In addition to the - # CPUTAPID some querying of the target would be required. - return -error "This is a generic LPC2xxx configuration file, use a specific target file." -} diff --git a/tcl/target/lpc3131.cfg b/tcl/target/lpc3131.cfg deleted file mode 100644 index 27c1f6757..000000000 --- a/tcl/target/lpc3131.cfg +++ /dev/null @@ -1,76 +0,0 @@ -###################################### -# Target: NXP lpc3131 -###################################### - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME lpc3131 -} - -if { [info exists ENDIAN] } { - set _ENDIAN $ENDIAN -} else { - set _ENDIAN little -} - -# ARM926EJS core -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - set _CPUTAPID 0x07926f0f -} - -# Scan Tap -# Wired to seperate STDO pin on the lpc3131, externally muxed to TDO on ea3131 module -# JTAGSEL pin must be 0 to activate, which reassigns arm tdo to a pass through. -if { [info exists SJCTAPID] } { - set _SJCTAPID $SJCTAPID -} else { - set _SJCTAPID 0x1541E02B -} - -jtag newtap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID - -################################################################## -# various symbol definitions, to avoid hard-wiring addresses -################################################################## - -global lpc313x -set lpc313x [ dict create ] - -# Physical addresses for controllers and memory -dict set lpc313x sram0 0x11028000 -dict set lpc313x sram1 0x11040000 -dict set lpc313x uart 0x15001000 -dict set lpc313x cgu 0x13004000 -dict set lpc313x ioconfig 0x13003000 -dict set lpc313x sysconfig 0x13002800 -dict set lpc313x wdt 0x13002400 - -################################################################## -# Target configuration -################################################################## - -adapter_nsrst_delay 1000 -jtag_ntrst_delay 0 - -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME arm926ejs -endian $_ENDIAN -chain-position $_TARGETNAME - -$_TARGETNAME invoke-event halted - -$_TARGETNAME configure -work-area-phys [dict get $lpc313x sram0] -work-area-size 0x30000 -work-area-backup 0 - -$_TARGETNAME configure -event reset-init { - echo "\nRunning reset init script for LPC3131\n" - halt - wait_halt - reg cpsr 0xa00000d3 ;#Supervisor mode - reg pc 0x11029000 - poll - sleep 500 -} - -arm7_9 fast_memory_access enable -arm7_9 dcc_downloads enable diff --git a/tcl/target/lpc3250.cfg b/tcl/target/lpc3250.cfg deleted file mode 100644 index 14bb0f61b..000000000 --- a/tcl/target/lpc3250.cfg +++ /dev/null @@ -1,43 +0,0 @@ -# lpc3250 config -# - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME lpc3250 -} - -if { [info exists ENDIAN] } { - set _ENDIAN $ENDIAN -} else { - set _ENDIAN little -} - -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - set _CPUTAPID 0x17900f0f -} - -if { [info exists CPUTAPID_REV_A0] } { - set _CPUTAPID_REV_A0 $CPUTAPID_REV_A0 -} else { - set _CPUTAPID_REV_A0 0x17926f0f -} - -if { [info exists SJCTAPID] } { - set _SJCTAPID $SJCTAPID -} else { - set _SJCTAPID 0x1b900f0f -} - -jtag newtap $_CHIPNAME sjc -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_SJCTAPID - -jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID \ - -expected-id $_CPUTAPID_REV_A0 - -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME arm926ejs -endian little -chain-position $_TARGETNAME -work-area-phys 0x00000000 -work-area-size 0x7d0000 -work-area-backup 0 - -proc power_restore {} { echo "Sensed power restore. No action." } -proc srst_deasserted {} { echo "Sensed nSRST deasserted. No action." } diff --git a/tcl/target/lpc40xx.cfg b/tcl/target/lpc40xx.cfg deleted file mode 100644 index 606cda5c1..000000000 --- a/tcl/target/lpc40xx.cfg +++ /dev/null @@ -1,8 +0,0 @@ -# NXP LPC40xx Cortex-M4F with at least 16kB SRAM -set CHIPNAME lpc40xx -set CHIPSERIES lpc4000 -if { ![info exists WORKAREASIZE] } { - set WORKAREASIZE 0x4000 -} - -source [find target/lpc1xxx.cfg] diff --git a/tcl/target/lpc4350.cfg b/tcl/target/lpc4350.cfg deleted file mode 100644 index 4e23ffb0d..000000000 --- a/tcl/target/lpc4350.cfg +++ /dev/null @@ -1,70 +0,0 @@ -source [find target/swj-dp.tcl] - -adapter_khz 500 - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME lpc4350 -} - -# -# M4 JTAG mode TAP -# -if { [info exists M4_JTAG_TAPID] } { - set _M4_JTAG_TAPID $M4_JTAG_TAPID -} else { - set _M4_JTAG_TAPID 0x4ba00477 -} - -# -# M4 SWD mode TAP -# -if { [info exists M4_SWD_TAPID] } { - set _M4_SWD_TAPID $M4_SWD_TAPID -} else { - set _M4_SWD_TAPID 0x2ba01477 -} - -if { [using_jtag] } { - set _M4_TAPID $_M4_JTAG_TAPID -} { - set _M4_TAPID $_M4_SWD_TAPID -} - -# -# M0 TAP -# -if { [info exists M0_JTAG_TAPID] } { - set _M0_JTAG_TAPID $M0_JTAG_TAPID -} else { - set _M0_JTAG_TAPID 0x0ba01477 -} - -swj_newdap $_CHIPNAME m4 -irlen 4 -ircapture 0x1 -irmask 0xf \ - -expected-id $_M4_TAPID -target create $_CHIPNAME.m4 cortex_m -chain-position $_CHIPNAME.m4 - -if { [using_jtag] } { - swj_newdap $_CHIPNAME m0 -irlen 4 -ircapture 0x1 -irmask 0xf \ - -expected-id $_M0_JTAG_TAPID - target create $_CHIPNAME.m0 cortex_m -chain-position $_CHIPNAME.m0 -} - -# LPC4350 has 96+32 KB SRAM -if { [info exists WORKAREASIZE] } { - set _WORKAREASIZE $WORKAREASIZE -} else { - set _WORKAREASIZE 0x20000 -} -$_CHIPNAME.m4 configure -work-area-phys 0x10000000 \ - -work-area-size $_WORKAREASIZE -work-area-backup 0 - -if {![using_hla]} { - # on this CPU we should use VECTRESET to perform a soft reset and - # manually reset the periphery - # SRST or SYSRESETREQ disable the debug interface for the time of - # the reset and will not fit our requirements for a consistent debug - # session - cortex_m reset_config vectreset -} diff --git a/tcl/target/lpc4357.cfg b/tcl/target/lpc4357.cfg deleted file mode 100644 index 1a15ad623..000000000 --- a/tcl/target/lpc4357.cfg +++ /dev/null @@ -1,12 +0,0 @@ -# -# NXP LPC4357 -# - -if { ![info exists CHIPNAME] } { - set CHIPNAME lpc4357 -} -set WORKAREASIZE 0x8000 -source [find target/lpc4350.cfg] - -flash bank $_CHIPNAME.flasha lpc2000 0x1A000000 0x80000 0 0 $_CHIPNAME.m4 lpc4300 204000 calc_checksum -flash bank $_CHIPNAME.flashb lpc2000 0x1B000000 0x80000 0 0 $_CHIPNAME.m4 lpc4300 204000 calc_checksum diff --git a/tcl/target/lpc4370.cfg b/tcl/target/lpc4370.cfg deleted file mode 100644 index 67bff0adc..000000000 --- a/tcl/target/lpc4370.cfg +++ /dev/null @@ -1,85 +0,0 @@ -# -# NXP LPC4370 - 1x ARM Cortex-M4 + 2x ARM Cortex-M0 @ up to 204 MHz each -# - -adapter_khz 500 - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME lpc4370 -} - -# -# M4 JTAG mode TAP -# -if { [info exists M4_JTAG_TAPID] } { - set _M4_JTAG_TAPID $M4_JTAG_TAPID -} else { - set _M4_JTAG_TAPID 0x4ba00477 -} - -# -# M4 SWD mode TAP -# -if { [info exists M4_SWD_TAPID] } { - set _M4_SWD_TAPID $M4_SWD_TAPID -} else { - set _M4_SWD_TAPID 0x2ba01477 -} - -source [find target/swj-dp.tcl] - -if { [using_jtag] } { - set _M4_TAPID $_M4_JTAG_TAPID -} else { - set _M4_TAPID $_M4_SWD_TAPID -} - -# -# M0 TAP -# -if { [info exists M0_JTAG_TAPID] } { - set _M0_JTAG_TAPID $M0_JTAG_TAPID -} else { - set _M0_JTAG_TAPID 0x0ba01477 -} - -swj_newdap $_CHIPNAME m4 -irlen 4 -ircapture 0x1 -irmask 0xf \ - -expected-id $_M4_TAPID - -target create $_CHIPNAME.m4 cortex_m -chain-position $_CHIPNAME.m4 - -# LPC4370 has 96+32 KB contiguous SRAM -if { [info exists WORKAREASIZE] } { - set _WORKAREASIZE $WORKAREASIZE -} else { - set _WORKAREASIZE 0x20000 -} -$_CHIPNAME.m4 configure -work-area-phys 0x10000000 \ - -work-area-size $_WORKAREASIZE -work-area-backup 0 - -if { [using_jtag] } { - jtag newtap $_CHIPNAME m0app -irlen 4 -ircapture 0x1 -irmask 0xf \ - -expected-id $_M0_JTAG_TAPID - jtag newtap $_CHIPNAME m0sub -irlen 4 -ircapture 0x1 -irmask 0xf \ - -expected-id $_M0_JTAG_TAPID - - target create $_CHIPNAME.m0app cortex_m -chain-position $_CHIPNAME.m0app - target create $_CHIPNAME.m0sub cortex_m -chain-position $_CHIPNAME.m0sub - - # 32+8+32 KB SRAM - $_CHIPNAME.m0app configure -work-area-phys 0x10080000 \ - -work-area-size 0x92000 -work-area-backup 0 - - # 16+2 KB M0 subsystem SRAM - $_CHIPNAME.m0sub configure -work-area-phys 0x18000000 \ - -work-area-size 0x4800 -work-area-backup 0 - - # Default to the Cortex-M4 - targets $_CHIPNAME.m4 -} - -if { ![using_hla] } { - cortex_m reset_config vectreset -} diff --git a/tcl/target/lpc8xx.cfg b/tcl/target/lpc8xx.cfg deleted file mode 100644 index e0e210b96..000000000 --- a/tcl/target/lpc8xx.cfg +++ /dev/null @@ -1,10 +0,0 @@ -# NXP LPC8xx Cortex-M0+ with at least 1kB SRAM -if { ![info exists CHIPNAME] } { - set CHIPNAME lpc8xx -} -set CHIPSERIES lpc800 -if { ![info exists WORKAREASIZE] } { - set WORKAREASIZE 0x400 -} - -source [find target/lpc1xxx.cfg] diff --git a/tcl/target/mc13224v.cfg b/tcl/target/mc13224v.cfg deleted file mode 100644 index 27ac8c3b2..000000000 --- a/tcl/target/mc13224v.cfg +++ /dev/null @@ -1,54 +0,0 @@ -source [find bitsbytes.tcl] -source [find cpu/arm/arm7tdmi.tcl] -source [find memory.tcl] -source [find mmr_helpers.tcl] - -set CHIP_MAKER freescale -set CHIP_FAMILY mc1322x -set CHIP_NAME mc13224 -set N_RAM 1 -set RAM(0,BASE) 0x00400000 -set RAM(0,LEN) 0x18000 -set RAM(0,HUMAN) "internal SRAM" -set RAM(0,TYPE) "ram" -set RAM(0,RWX) $RWX_RWX -set RAM(0,ACCESS_WIDTH) $ACCESS_WIDTH_ANY - -# I AM LAZY... I create 1 region for all MMRs. -set N_MMREGS 1 -set MMREGS(0,CHIPSELECT) -1 -set MMREGS(0,BASE) 0x80000000 -set MMREGS(0,LEN) 0x00030000 -set MMREGS(0,HUMAN) "mm-regs" -set MMREGS(0,TYPE) "mmr" -set MMREGS(0,RWX) $RWX_RW -set MMREGS(0,ACCESS_WIDTH) $ACCESS_WIDTH_ANY - -set N_XMEM 0 - -set _CHIPNAME mc13224v -set _CPUTAPID 0x1f1f001d - -jtag newtap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID - -reset_config srst_only -jtag_ntrst_delay 200 - -# rclk hasn't been working well. This maybe the mc13224v or something else. -#adapter_khz 2000 -adapter_khz 2000 - -###################### -# Target configuration -###################### - -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME arm7tdmi -chain-position $_TARGETNAME - -# Internal sram memory -$_TARGETNAME configure -work-area-phys 0x00408000 \ - -work-area-size 0x1000 \ - -work-area-backup 1 - -# flash support is pending (should be straightforward to implement) -#flash bank mc1322x 0 0 0 0 $_TARGETNAME diff --git a/tcl/target/mdr32f9q2i.cfg b/tcl/target/mdr32f9q2i.cfg deleted file mode 100644 index 804ac1aef..000000000 --- a/tcl/target/mdr32f9q2i.cfg +++ /dev/null @@ -1,62 +0,0 @@ -# MDR32F9Q2I (1986ВЕ92У) -# http://milandr.ru/index.php?mact=Products,cntnt01,details,0&cntnt01productid=57&cntnt01returnid=68 - -source [find target/swj-dp.tcl] - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME mdr32f9q2i -} - -if { [info exists ENDIAN] } { - set _ENDIAN $ENDIAN -} else { - set _ENDIAN little -} - -# Work-area is a space in RAM used for flash programming -if { [info exists WORKAREASIZE] } { - set _WORKAREASIZE $WORKAREASIZE -} else { - set _WORKAREASIZE 0x8000 -} - -#jtag scan chain -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - if { [using_jtag] } { - set _CPUTAPID 0x4ba00477 - } { - # SWD IDCODE - set _CPUTAPID 0x2ba01477 - } -} -swj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID - -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME cortex_m -endian $_ENDIAN -chain-position $_TARGETNAME - -$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0 - -# can't handle overlapping memory regions -if { [info exists IMEMORY] && [string equal $IMEMORY true] } { - flash bank ${_CHIPNAME}_info.flash mdr 0x08000000 0x01000 0 0 $_TARGETNAME 1 1 4 -} else { - flash bank $_CHIPNAME.flash mdr 0x08000000 0x20000 0 0 $_TARGETNAME 0 32 4 -} - -# JTAG speed should be <= F_CPU/6. F_CPU after reset is 8MHz, so use F_JTAG = 1MHz -adapter_khz 1000 - -adapter_nsrst_delay 100 -if {[using_jtag]} { - jtag_ntrst_delay 100 -} - -if {![using_hla]} { - # if srst is not fitted use SYSRESETREQ to - # perform a soft reset - cortex_m reset_config sysresetreq -} diff --git a/tcl/target/nds32v2.cfg b/tcl/target/nds32v2.cfg deleted file mode 100644 index bbf6b3aee..000000000 --- a/tcl/target/nds32v2.cfg +++ /dev/null @@ -1,10 +0,0 @@ -# -# Andes Core -# -# http://www.andestech.com -# - -jtag newtap $_CHIPNAME cpu -expected-id $_CPUTAPID - -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME nds32_v2 -endian little -chain-position $_TARGETNAME diff --git a/tcl/target/nds32v3.cfg b/tcl/target/nds32v3.cfg deleted file mode 100644 index 0c267cd75..000000000 --- a/tcl/target/nds32v3.cfg +++ /dev/null @@ -1,10 +0,0 @@ -# -# Andes Core -# -# http://www.andestech.com -# - -jtag newtap $_CHIPNAME cpu -expected-id $_CPUTAPID - -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME nds32_v3 -endian little -chain-position $_TARGETNAME diff --git a/tcl/target/nds32v3m.cfg b/tcl/target/nds32v3m.cfg deleted file mode 100644 index 169e3d119..000000000 --- a/tcl/target/nds32v3m.cfg +++ /dev/null @@ -1,10 +0,0 @@ -# -# Andes Core -# -# http://www.andestech.com -# - -jtag newtap $_CHIPNAME cpu -expected-id $_CPUTAPID - -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME nds32_v3m -endian little -chain-position $_TARGETNAME diff --git a/tcl/target/nrf51.cfg b/tcl/target/nrf51.cfg deleted file mode 100644 index 280dd4ff3..000000000 --- a/tcl/target/nrf51.cfg +++ /dev/null @@ -1,60 +0,0 @@ -# -# script for Nordic nRF51 series, a Cortex-M0 chip -# - -source [find target/swj-dp.tcl] - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME nrf51 -} - -if { [info exists ENDIAN] } { - set _ENDIAN $ENDIAN -} else { - set _ENDIAN little -} - -# Work-area is a space in RAM used for flash programming -# By default use 16kB -if { [info exists WORKAREASIZE] } { - set _WORKAREASIZE $WORKAREASIZE -} else { - set _WORKAREASIZE 0x4000 -} - -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - set _CPUTAPID 0x0bb11477 -} - -swj_newdap $_CHIPNAME cpu -expected-id $_CPUTAPID - -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME cortex_m -chain-position $_TARGETNAME - -$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0 - -if {![using_hla]} { - # The chip supports standard ARM/Cortex-M0 SYSRESETREQ signal - cortex_m reset_config sysresetreq -} - -flash bank $_CHIPNAME.flash nrf51 0x00000000 0 1 1 $_TARGETNAME -flash bank $_CHIPNAME.uicr nrf51 0x10001000 0 1 1 $_TARGETNAME - -# -# The chip should start up from internal 16Mhz RC, so setting adapter -# clock to 1Mhz should be OK -# -adapter_khz 1000 - -proc enable_all_ram {} { - # nRF51822 Product Anomaly Notice (PAN) #16 explains that not all RAM banks - # are reliably enabled after reset on some revisions (contrary to spec.) So after - # resetting we enable all banks via the RAMON register - mww 0x40000524 0xF -} -$_TARGETNAME configure -event reset-end { enable_all_ram } diff --git a/tcl/target/nrf51_stlink.tcl b/tcl/target/nrf51_stlink.tcl deleted file mode 100644 index 7e23c5a74..000000000 --- a/tcl/target/nrf51_stlink.tcl +++ /dev/null @@ -1,2 +0,0 @@ -echo "WARNING: target/nrf51_stlink.cfg is deprecated, please switch to target/nrf51.cfg" -source [find target/nrf51.cfg] diff --git a/tcl/target/nrf52.cfg b/tcl/target/nrf52.cfg deleted file mode 100644 index c1cbf1a21..000000000 --- a/tcl/target/nrf52.cfg +++ /dev/null @@ -1,28 +0,0 @@ -# -# Nordic nRF52 series: ARM Cortex-M4 @ 64 MHz -# - -source [find target/swj-dp.tcl] - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME nrf52 -} - -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - set _CPUTAPID 0x2ba01477 -} - -swj_newdap $_CHIPNAME cpu -expected-id $_CPUTAPID - -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME cortex_m -chain-position $_TARGETNAME - -adapter_khz 10000 - -if { ![using_hla] } { - cortex_m reset_config sysresetreq -} diff --git a/tcl/target/nuc910.cfg b/tcl/target/nuc910.cfg deleted file mode 100644 index 29cd29f35..000000000 --- a/tcl/target/nuc910.cfg +++ /dev/null @@ -1,27 +0,0 @@ -# -# Nuvoton nuc910 (previously W90P910) based soc -# - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME nuc910 -} - -if { [info exists ENDIAN] } { - set _ENDIAN $ENDIAN -} else { - set _ENDIAN little -} - -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - # set useful default - set _CPUTAPID 0x07926f0f -} - -set _TARGETNAME $_CHIPNAME.cpu -jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID - -target create $_TARGETNAME arm926ejs -endian $_ENDIAN -chain-position $_TARGETNAME diff --git a/tcl/target/numicro.cfg b/tcl/target/numicro.cfg deleted file mode 100644 index 13d965432..000000000 --- a/tcl/target/numicro.cfg +++ /dev/null @@ -1,60 +0,0 @@ -# script for Nuvoton MuMicro Cortex-M0 Series - -# Adapt based on what transport is active. -source [find target/swj-dp.tcl] - -# Set Chipname -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME NuMicro -} - -# SWD DP-ID Nuvoton NuMicro Cortex-M0 has SWD Transport only. -if { [info exists CPUDAPID] } { - set _CPUDAPID $CPUDAPID -} else { - set _CPUDAPID 0x0BB11477 -} - -# Work-area is a space in RAM used for flash programming -# By default use 2kB -if { [info exists WORKAREASIZE] } { - set _WORKAREASIZE $WORKAREASIZE -} else { - set _WORKAREASIZE 0x800 -} - - -# Debug Adapter Target Settings -swj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUDAPID -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME cortex_m -chain-position $_TARGETNAME - -$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0 - -# flash bank numicro 0 0 -#set _FLASHNAME $_CHIPNAME.flash -#flash bank $_FLASHNAME numicro 0 $_FLASHSIZE 0 0 $_TARGETNAME -# flash size will be probed -set _FLASHNAME $_CHIPNAME.flash_aprom -flash bank $_FLASHNAME numicro 0x00000000 0 0 0 $_TARGETNAME -set _FLASHNAME $_CHIPNAME.flash_data -flash bank $_FLASHNAME numicro 0x0001F000 0 0 0 $_TARGETNAME -set _FLASHNAME $_CHIPNAME.flash_ldrom -flash bank $_FLASHNAME numicro 0x00100000 0 0 0 $_TARGETNAME -set _FLASHNAME $_CHIPNAME.flash_config -flash bank $_FLASHNAME numicro 0x00300000 0 0 0 $_TARGETNAME - -# set default SWCLK frequency -adapter_khz 1000 - -# set default srst setting "none" -reset_config none - -# HLA doesn't have cortex_m commands -if {![using_hla]} { - # if srst is not fitted use SYSRESETREQ to - # perform a soft reset - cortex_m reset_config sysresetreq -} diff --git a/tcl/target/omap2420.cfg b/tcl/target/omap2420.cfg deleted file mode 100644 index 7968ad1e8..000000000 --- a/tcl/target/omap2420.cfg +++ /dev/null @@ -1,61 +0,0 @@ -# Texas Instruments OMAP 2420 -# http://www.ti.com/omap -# as seen in Nokia N8x0 tablets - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME omap2420 -} - -# NOTE: likes slowish clock on reset (1.5 MBit/s or less) or use RCLK -reset_config srst_nogate - -# Subsidiary TAP: ARM7TDMIr4 plus imaging ... must add via ICEpick (addr 6). -jtag newtap $_CHIPNAME iva -irlen 4 -disable - -# Subsidiary TAP: C55x DSP ... must add via ICEpick (addr 2). -jtag newtap $_CHIPNAME dsp -irlen 38 -disable - -# Subsidiary TAP: ARM ETB11, with scan chain for 4K of ETM trace buffer -if { [info exists ETB_TAPID] } { - set _ETB_TAPID $ETB_TAPID -} else { - set _ETB_TAPID 0x2b900f0f -} -jtag newtap $_CHIPNAME etb -irlen 4 -expected-id $_ETB_TAPID - -# Subsidiary TAP: ARM1136jf-s with scan chains for ARM Debug, EmbeddedICE-RT, ETM. -if { [info exists CPU_TAPID] } { - set _CPU_TAPID $CPU_TAPID -} else { - set _CPU_TAPID 0x07b3602f -} -jtag newtap $_CHIPNAME arm -irlen 5 -expected-id $_CPU_TAPID - -# Primary TAP: ICEpick-B (JTAG route controller) and boundary scan -if { [info exists JRC_TAPID] } { - set _JRC_TAPID $JRC_TAPID -} else { - set _JRC_TAPID 0x01ce4801 -} -jtag newtap $_CHIPNAME jrc -irlen 2 -expected-id $_JRC_TAPID - -# GDB target: the ARM. -set _TARGETNAME $_CHIPNAME.arm -target create $_TARGETNAME arm11 -chain-position $_TARGETNAME - -# scratch: framebuffer, may be initially unavailable in some chips -$_TARGETNAME configure -work-area-phys 0x40210000 -$_TARGETNAME configure -work-area-size 0x00081000 -$_TARGETNAME configure -work-area-backup 0 - -# trace setup ... NOTE, "normal full" mode fudges the real ETMv3.1 mode -etm config $_TARGETNAME 16 normal full etb -etb config $_TARGETNAME $_CHIPNAME.etb - -# RM_RSTCTRL_WKUP.RST.GS - Trigger a global software reset, and -# give it a chance to finish before we talk to the chip again. -set RM_RSTCTRL_WKUP 0x48008450 -$_TARGETNAME configure -event reset-assert \ - "halt; $_TARGETNAME mww $RM_RSTCTRL_WKUP 2; sleep 200" diff --git a/tcl/target/omap3530.cfg b/tcl/target/omap3530.cfg deleted file mode 100644 index c2929d1c4..000000000 --- a/tcl/target/omap3530.cfg +++ /dev/null @@ -1,74 +0,0 @@ -# TI OMAP3530 -# http://focus.ti.com/docs/prod/folders/print/omap3530.html -# Other OMAP3 chips remove DSP and/or the OpenGL support - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME omap3530 -} - -# ICEpick-C ... used to route Cortex, DSP, and more not shown here -source [find target/icepick.cfg] - -# Subsidiary TAP: C64x+ DSP ... must enable via ICEpick -jtag newtap $_CHIPNAME dsp -irlen 38 -ircapture 0x25 -irmask 0x3f -disable - -# Subsidiary TAP: CoreSight Debug Access Port (DAP) -if { [info exists DAP_TAPID] } { - set _DAP_TAPID $DAP_TAPID -} else { - set _DAP_TAPID 0x0b6d602f -} -jtag newtap $_CHIPNAME dap -irlen 4 -ircapture 0x1 -irmask 0xf \ - -expected-id $_DAP_TAPID -disable -jtag configure $_CHIPNAME.dap -event tap-enable \ - "icepick_c_tapenable $_CHIPNAME.jrc 3" - -# Primary TAP: ICEpick-C (JTAG route controller) and boundary scan -if { [info exists JRC_TAPID] } { - set _JRC_TAPID $JRC_TAPID -} else { - set _JRC_TAPID 0x0b7ae02f -} -jtag newtap $_CHIPNAME jrc -irlen 6 -ircapture 0x1 -irmask 0x3f \ - -expected-id $_JRC_TAPID - -# GDB target: Cortex-A8, using DAP -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME cortex_a -chain-position $_CHIPNAME.dap - -# SRAM: 64K at 0x4020.0000; use the first 16K -$_TARGETNAME configure -work-area-phys 0x40200000 -work-area-size 0x4000 - -################### - -# the reset sequence is event-driven -# and kind of finicky... - -# some TCK tycles are required to activate the DEBUG power domain -jtag configure $_CHIPNAME.jrc -event post-reset "runtest 100" - -# have the DAP "always" be active -jtag configure $_CHIPNAME.jrc -event setup "jtag tapenable $_CHIPNAME.dap" - -proc omap3_dbginit {target} { - # General Cortex-A8 debug initialisation - cortex_a dbginit - # Enable DBGU signal for OMAP353x - $target mww phys 0x5401d030 0x00002000 -} - -# be absolutely certain the JTAG clock will work with the worst-case -# 16.8MHz/2 = 8.4MHz core clock, even before a bootloader kicks in. -# OK to speed up *after* PLL and clock tree setup. -adapter_khz 1000 -$_TARGETNAME configure -event "reset-start" { adapter_khz 1000 } - -# Assume SRST is unavailable (e.g. TI-14 JTAG), so we must assert reset -# ourselves using PRM_RSTCTRL. RST_GS (2) is a warm reset, like ICEpick -# would issue. RST_DPLL3 (4) is a cold reset. -set PRM_RSTCTRL 0x48307250 -$_TARGETNAME configure -event reset-assert "$_TARGETNAME mww $PRM_RSTCTRL 2" - -$_TARGETNAME configure -event reset-assert-post "omap3_dbginit $_TARGETNAME" diff --git a/tcl/target/omap4430.cfg b/tcl/target/omap4430.cfg deleted file mode 100644 index 6f3525aed..000000000 --- a/tcl/target/omap4430.cfg +++ /dev/null @@ -1,127 +0,0 @@ -# OMAP4430 - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME omap4430 -} - - -# Although the OMAP4430 supposedly has an ICEpick-D, only the -# ICEpick-C router commands seem to work. -# See http://processors.wiki.ti.com/index.php/ICEPICK -source [find target/icepick.cfg] - - -# -# A9 DAP -# -if { [info exists DAP_TAPID] } { - set _DAP_TAPID $DAP_TAPID -} else { - set _DAP_TAPID 0x3BA00477 -} - -jtag newtap $_CHIPNAME dap -irlen 4 -ircapture 0x1 -irmask 0xf \ - -expected-id $_DAP_TAPID -disable -jtag configure $_CHIPNAME.dap -event tap-enable \ - "icepick_c_tapenable $_CHIPNAME.jrc 9" - - -# -# M3 DAPs, one per core -# -if { [info exists M3_DAP_TAPID] } { - set _M3_DAP_TAPID $M3_DAP_TAPID -} else { - set _M3_DAP_TAPID 0x4BA00477 -} - -jtag newtap $_CHIPNAME m31_dap -irlen 4 -ircapture 0x1 -irmask 0xf \ - -expected-id $_M3_DAP_TAPID -disable -jtag configure $_CHIPNAME.m31_dap -event tap-enable \ - "icepick_c_tapenable $_CHIPNAME.jrc 5" - -jtag newtap $_CHIPNAME m30_dap -irlen 4 -ircapture 0x1 -irmask 0xf \ - -expected-id $_M3_DAP_TAPID -disable -jtag configure $_CHIPNAME.m30_dap -event tap-enable \ - "icepick_c_tapenable $_CHIPNAME.jrc 4" - - -# -# ICEpick-D JRC (JTAG route controller) -# -if { [info exists JRC_TAPID] } { - set _JRC_TAPID $JRC_TAPID -} else { - set _JRC_TAPID 0x3b95c02f - set _JRC_TAPID2 0x1b85202f -} - -# PandaBoard REV EA1 (PEAP platforms) -if { [info exists JRC_TAPID2] } { - set _JRC_TAPID2 $JRC_TAPID2 -} else { - set _JRC_TAPID2 0x1b85202f -} - - - -jtag newtap $_CHIPNAME jrc -irlen 6 -ircapture 0x1 -irmask 0x3f \ - -expected-id $_JRC_TAPID -expected-id $_JRC_TAPID2 - -# Required by ICEpick to power-up the debug domain -jtag configure $_CHIPNAME.jrc -event post-reset "runtest 200" - - -# -# GDB target: Cortex-A9, using DAP -# -# The debugger can connect to either core of the A9, but currently -# not both simultaneously. Change -coreid to 1 to connect to the -# second core. -# -set _TARGETNAME $_CHIPNAME.cpu - -# APB DBGBASE reads 0x80040000, but this points to an empty ROM table. -# 0x80000000 is cpu0 coresight region -# -# -# CORTEX_A8_PADDRDBG_CPU_SHIFT 13 -# 0x80000000 | (coreid << CORTEX_A8_PADDRDBG_CPU_SHIFT) - -set _coreid 0 -set _dbgbase [expr 0x80000000 | ($_coreid << 13)] -echo "Using dbgbase = [format 0x%x $_dbgbase]" - -target create $_TARGETNAME cortex_a -chain-position $_CHIPNAME.dap \ - -coreid 0 -dbgbase $_dbgbase - -# SRAM: 56KiB at 0x4030.0000 -$_TARGETNAME configure -work-area-phys 0x40300000 -work-area-size 0x1000 - - -# -# M3 targets, separate TAP/DAP for each core -# -target create $_CHIPNAME.m30 cortex_m -chain-position $_CHIPNAME.m30_dap -target create $_CHIPNAME.m31 cortex_m -chain-position $_CHIPNAME.m31_dap - - -# Once the JRC is up, enable our TAPs -jtag configure $_CHIPNAME.jrc -event setup " - jtag tapenable $_CHIPNAME.dap - jtag tapenable $_CHIPNAME.m30_dap - jtag tapenable $_CHIPNAME.m31_dap -" - -# Assume SRST is unavailable (e.g. TI-14 JTAG), so we must assert reset -# ourselves using PRM_RSTCTRL. 1 is a warm reset, 2 a cold reset. -set PRM_RSTCTRL 0x4A307B00 -$_TARGETNAME configure -event reset-assert "$_TARGETNAME mww phys $PRM_RSTCTRL 0x1" -$_CHIPNAME.m30 configure -event reset-assert { } -$_CHIPNAME.m31 configure -event reset-assert { } - -# Soft breakpoints don't currently work due to broken cache handling -gdb_breakpoint_override hard - diff --git a/tcl/target/omap4460.cfg b/tcl/target/omap4460.cfg deleted file mode 100644 index 9c40e62d0..000000000 --- a/tcl/target/omap4460.cfg +++ /dev/null @@ -1,126 +0,0 @@ -# OMAP4460 - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME omap4460 -} - - -# Although the OMAP4430 supposedly has an ICEpick-D, only the -# ICEpick-C router commands seem to work. -# See http://processors.wiki.ti.com/index.php/ICEPICK -source [find target/icepick.cfg] - - -# -# A9 DAP -# -if { [info exists DAP_TAPID] } { - set _DAP_TAPID $DAP_TAPID -} else { - set _DAP_TAPID 0x3BA00477 -} - -jtag newtap $_CHIPNAME dap -irlen 4 -ircapture 0x1 -irmask 0xf \ - -expected-id $_DAP_TAPID -disable -jtag configure $_CHIPNAME.dap -event tap-enable \ - "icepick_c_tapenable $_CHIPNAME.jrc 9" - - -# -# M3 DAPs, one per core -# -if { [info exists M3_DAP_TAPID] } { - set _M3_DAP_TAPID $M3_DAP_TAPID -} else { - set _M3_DAP_TAPID 0x4BA00477 -} - -jtag newtap $_CHIPNAME m31_dap -irlen 4 -ircapture 0x1 -irmask 0xf \ - -expected-id $_M3_DAP_TAPID -disable -jtag configure $_CHIPNAME.m31_dap -event tap-enable \ - "icepick_c_tapenable $_CHIPNAME.jrc 5" - -jtag newtap $_CHIPNAME m30_dap -irlen 4 -ircapture 0x1 -irmask 0xf \ - -expected-id $_M3_DAP_TAPID -disable -jtag configure $_CHIPNAME.m30_dap -event tap-enable \ - "icepick_c_tapenable $_CHIPNAME.jrc 4" - - -# -# ICEpick-D JRC (JTAG route controller) -# -if { [info exists JRC_TAPID] } { - set _JRC_TAPID $JRC_TAPID -} else { - set _JRC_TAPID 0x2b94e02f - set _JRC_TAPID2 0x1b85202f -} - -# PandaBoard REV EA1 (PEAP platforms) -if { [info exists JRC_TAPID2] } { - set _JRC_TAPID2 $JRC_TAPID2 -} else { - set _JRC_TAPID2 0x1b85202f -} - - - -jtag newtap $_CHIPNAME jrc -irlen 6 -ircapture 0x1 -irmask 0x3f \ - -expected-id $_JRC_TAPID -expected-id $_JRC_TAPID2 - -# Required by ICEpick to power-up the debug domain -jtag configure $_CHIPNAME.jrc -event post-reset "runtest 200" - - -# -# GDB target: Cortex-A9, using DAP -# -# The debugger can connect to either core of the A9, but currently -# not both simultaneously. Change -coreid to 1 to connect to the -# second core. -# -set _TARGETNAME $_CHIPNAME.cpu - -# APB DBGBASE reads 0x80040000, but this points to an empty ROM table. -# 0x80000000 is cpu0 coresight region -# -# -# CORTEX_A8_PADDRDBG_CPU_SHIFT 13 -# 0x80000000 | (coreid << CORTEX_A8_PADDRDBG_CPU_SHIFT) - -set _coreid 0 -set _dbgbase [expr 0x80000000 | ($_coreid << 13)] -echo "Using dbgbase = [format 0x%x $_dbgbase]" - -target create $_TARGETNAME cortex_a -chain-position $_CHIPNAME.dap \ - -coreid 0 -dbgbase $_dbgbase - -# SRAM: 56KiB at 0x4030.0000 -$_TARGETNAME configure -work-area-phys 0x40300000 -work-area-size 0x1000 - - -# -# M3 targets, separate TAP/DAP for each core -# -target create $_CHIPNAME.m30 cortex_m -chain-position $_CHIPNAME.m30_dap -target create $_CHIPNAME.m31 cortex_m -chain-position $_CHIPNAME.m31_dap - - -# Once the JRC is up, enable our TAPs -jtag configure $_CHIPNAME.jrc -event setup " - jtag tapenable $_CHIPNAME.dap - jtag tapenable $_CHIPNAME.m30_dap - jtag tapenable $_CHIPNAME.m31_dap -" - -# Assume SRST is unavailable (e.g. TI-14 JTAG), so we must assert reset -# ourselves using PRM_RSTCTRL. 1 is a warm reset, 2 a cold reset. -set PRM_RSTCTRL 0x4A307B00 -$_TARGETNAME configure -event reset-assert "$_TARGETNAME mww phys $PRM_RSTCTRL 0x1" -$_CHIPNAME.m30 configure -event reset-assert { } -$_CHIPNAME.m31 configure -event reset-assert { } - -# Soft breakpoints don't currently work due to broken cache handling -gdb_breakpoint_override hard diff --git a/tcl/target/omap5912.cfg b/tcl/target/omap5912.cfg deleted file mode 100644 index c4ff40e23..000000000 --- a/tcl/target/omap5912.cfg +++ /dev/null @@ -1,52 +0,0 @@ -# TI OMAP5912 dual core processor -# http://focus.ti.com/docs/prod/folders/print/omap5912.html - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME omap5912 -} - -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - # NOTE: validated with XOMAP5912 part - set _CPUTAPID 0x0692602f -} - -adapter_nsrst_delay 100 - -# NOTE: presumes irlen 38 is the C55x DSP, matching BSDL for -# its standalone siblings (like TMS320VC5502) of the same era - -#jtag scan chain -jtag newtap $_CHIPNAME dsp -irlen 38 -expected-id 0x03df1d81 -jtag newtap $_CHIPNAME arm -irlen 4 -expected-id $_CPUTAPID -jtag newtap $_CHIPNAME unknown -irlen 8 - -set _TARGETNAME $_CHIPNAME.arm -target create $_TARGETNAME arm926ejs -chain-position $_TARGETNAME - -proc omap5912_reset {} { - # - # halt target - # - poll - sleep 1 - halt - wait_halt - # - # disable wdt - # - mww 0xfffec808 0x000000f5 - mww 0xfffec808 0x000000a0 - - mww 0xfffeb048 0x0000aaaa - sleep 500 - mww 0xfffeb048 0x00005555 - sleep 500 -} - -# omap5912 lcd frame buffer as working area -$_TARGETNAME configure -work-area-phys 0x20000000 \ - -work-area-size 0x3e800 -work-area-backup 0 diff --git a/tcl/target/omapl138.cfg b/tcl/target/omapl138.cfg deleted file mode 100644 index fd9ff4c2e..000000000 --- a/tcl/target/omapl138.cfg +++ /dev/null @@ -1,66 +0,0 @@ -# -# Texas Instruments DaVinci family: OMAPL138 -# -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME omapl138 -} - -source [find target/icepick.cfg] - -# Subsidiary TAP: ARM ETB11, with scan chain for 4K of ETM trace buffer -if { [info exists ETB_TAPID] } { - set _ETB_TAPID $ETB_TAPID -} else { - set _ETB_TAPID 0x2b900f0f -} -jtag newtap $_CHIPNAME etb -irlen 4 -irmask 0xf -expected-id $_ETB_TAPID -disable -jtag configure $_CHIPNAME.etb -event tap-enable \ - "icepick_c_tapenable $_CHIPNAME.jrc 3" - -# Subsidiary TAP: ARM926ejs with scan chains for ARM Debug, EmbeddedICE-RT, ETM. -if { [info exists CPU_TAPID] } { - set _CPU_TAPID $CPU_TAPID -} else { - set _CPU_TAPID 0x07926001 -} -jtag newtap $_CHIPNAME arm -irlen 4 -irmask 0xf -expected-id $_CPU_TAPID -disable -jtag configure $_CHIPNAME.arm -event tap-enable \ - "icepick_c_tapenable $_CHIPNAME.jrc 2" - -# Primary TAP: ICEpick-C (JTAG route controller) and boundary scan -if { [info exists JRC_TAPID] } { - set _JRC_TAPID $JRC_TAPID -} else { - set _JRC_TAPID 0x0b7d102f -} -jtag newtap $_CHIPNAME jrc -irlen 6 -irmask 0x3f -expected-id $_JRC_TAPID -ignore-version - -jtag configure $_CHIPNAME.jrc -event setup \ - "jtag tapenable $_CHIPNAME.etb; jtag tapenable $_CHIPNAME.arm" - -################ -# GDB target: the ARM, using SRAM1 for scratch. SRAM0 (also 8K) -# and the ETB memory (4K) are other options, while trace is unused. -# Little-endian; use the OpenOCD default. -set _TARGETNAME $_CHIPNAME.arm - -target create $_TARGETNAME arm926ejs -chain-position $_TARGETNAME -$_TARGETNAME configure -work-area-phys 0x80000000 -work-area-size 0x2000 - -# be absolutely certain the JTAG clock will work with the worst-case -# CLKIN = 20 MHz (best case: 30 MHz) even when no bootloader turns -# on the PLL and starts using it. OK to speed up after clock setup. -adapter_khz 1500 -$_TARGETNAME configure -event "reset-start" { adapter_khz 1500 } - -arm7_9 fast_memory_access enable -arm7_9 dcc_downloads enable - -# trace setup -etm config $_TARGETNAME 16 normal full etb -etb config $_TARGETNAME $_CHIPNAME.etb - -gdb_breakpoint_override hard -arm7_9 dbgrq enable diff --git a/tcl/target/or1k.cfg b/tcl/target/or1k.cfg deleted file mode 100644 index 360a0ddf3..000000000 --- a/tcl/target/or1k.cfg +++ /dev/null @@ -1,72 +0,0 @@ -set _ENDIAN big - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME or1k -} - -if { [info exists TAP_TYPE] } { - set _TAP_TYPE $TAP_TYPE -} else { - puts "You need to select a tap type" - shutdown -} - -# Configure the target -if { [string compare $_TAP_TYPE "VJTAG"] == 0 } { - if { [info exists FPGATAPID] } { - set _FPGATAPID $FPGATAPID - } else { - puts "You need to set your FPGA JTAG ID" - shutdown - } - - jtag newtap $_CHIPNAME cpu -irlen 10 -expected-id $_FPGATAPID - - set _TARGETNAME $_CHIPNAME.cpu - target create $_TARGETNAME or1k -endian $_ENDIAN -chain-position $_TARGETNAME - - # Select the TAP core we are using - tap_select vjtag - -} elseif { [string compare $_TAP_TYPE "XILINX_BSCAN"] == 0 } { - - if { [info exists FPGATAPID] } { - set _FPGATAPID $FPGATAPID - } else { - puts "You need to set your FPGA JTAG ID" - shutdown - } - - jtag newtap $_CHIPNAME cpu -irlen 6 -expected-id $_FPGATAPID - - set _TARGETNAME $_CHIPNAME.cpu - target create $_TARGETNAME or1k -endian $_ENDIAN -chain-position $_TARGETNAME - - # Select the TAP core we are using - tap_select xilinx_bscan -} else { - # OpenCores Mohor JTAG TAP ID - set _CPUTAPID 0x14951185 - - jtag newtap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID - - set _TARGETNAME $_CHIPNAME.cpu - target create $_TARGETNAME or1k -endian $_ENDIAN -chain-position $_TARGETNAME - - # Select the TAP core we are using - tap_select mohor -} - -# Select the debug unit core we are using. This debug unit as an option. - -set ADBG_USE_HISPEED 1 -set ENABLE_JSP_SERVER 2 -set ENABLE_JSP_MULTI 4 - -# If ADBG_USE_HISPEED is set (options bit 1), status bits will be skipped -# on burst reads and writes to improve download speeds. -# This option must match the RTL configured option. - -du_select adv [expr $ADBG_USE_HISPEED | $ENABLE_JSP_SERVER | $ENABLE_JSP_MULTI] diff --git a/tcl/target/pic32mx.cfg b/tcl/target/pic32mx.cfg deleted file mode 100644 index d53b99a58..000000000 --- a/tcl/target/pic32mx.cfg +++ /dev/null @@ -1,90 +0,0 @@ -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME pic32mx -} - -if { [info exists ENDIAN] } { - set _ENDIAN $ENDIAN -} else { - set _ENDIAN little -} - -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - set _CPUTAPID 0x30938053 -} - -# default working area is 16384 -if { [info exists WORKAREASIZE] } { - set _WORKAREASIZE $WORKAREASIZE -} else { - set _WORKAREASIZE 0x4000 -} - -adapter_nsrst_delay 100 -jtag_ntrst_delay 100 - -#jtag scan chain -#format L IRC IRCM IDCODE (Length, IR Capture, IR Capture Mask, IDCODE) -jtag newtap $_CHIPNAME cpu -irlen 5 -ircapture 0x1 -irmask 0x1f -expected-id $_CPUTAPID - -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME mips_m4k -endian $_ENDIAN -chain-position $_TARGETNAME - -# -# At reset the pic32mx does not allow code execution from RAM -# we have to setup the BMX registers to allow this. -# One limitation is that we loose the first 2k of RAM. -# - -global _PIC32MX_DATASIZE -global _WORKAREASIZE -set _PIC32MX_DATASIZE 0x800 -set _PIC32MX_PROGSIZE [expr ($_WORKAREASIZE - $_PIC32MX_DATASIZE)] - -$_TARGETNAME configure -work-area-phys 0xa0000800 -work-area-size $_PIC32MX_PROGSIZE -work-area-backup 0 -$_TARGETNAME configure -event reset-init { - # - # from reset the pic32 cannot execute code in ram - enable ram execution - # minimum offset from start of ram is 2k - # - global _PIC32MX_DATASIZE - global _WORKAREASIZE - - # BMXCON set 0 wait state option by clearing BMXWSDRM bit, bit 6 - mww 0xbf882000 0x001f0000 - # BMXDKPBA: 2k kernel data @ 0xa0000000 - mww 0xbf882010 $_PIC32MX_DATASIZE - # BMXDUDBA: 14k kernel program @ 0xa0000800 - (BMXDUDBA - BMXDKPBA) - mww 0xbf882020 $_WORKAREASIZE - # BMXDUPBA: 0k user program - (BMXDUPBA - BMXDUDBA) - mww 0xbf882030 $_WORKAREASIZE - - # - # Set system clock to 8Mhz if the default clock configuration is set - # - - # SYSKEY register, make sure OSCCON is locked - mww 0xbf80f230 0x0 - # SYSKEY register, write unlock sequence - mww 0xbf80f230 0xaa996655 - mww 0xbf80f230 0x556699aa - # OSCCON register + 4, clear OSCCON FRCDIV bits: 24, 25 and 26, divided by 1 - mww 0xbf80f004 0x07000000 - # SYSKEY register, relock OSCCON - mww 0xbf80f230 0x0 -} - -set _FLASHNAME $_CHIPNAME.flash0 -flash bank $_FLASHNAME pic32mx 0x1fc00000 0 0 0 $_TARGETNAME -# add virtual banks for kseg0 and kseg1 -flash bank vbank0 virtual 0xbfc00000 0 0 0 $_TARGETNAME $_FLASHNAME -flash bank vbank1 virtual 0x9fc00000 0 0 0 $_TARGETNAME $_FLASHNAME - -set _FLASHNAME $_CHIPNAME.flash1 -flash bank $_FLASHNAME pic32mx 0x1d000000 0 0 0 $_TARGETNAME -# add virtual banks for kseg0 and kseg1 -flash bank vbank2 virtual 0xbd000000 0 0 0 $_TARGETNAME $_FLASHNAME -flash bank vbank3 virtual 0x9d000000 0 0 0 $_TARGETNAME $_FLASHNAME diff --git a/tcl/target/psoc4.cfg b/tcl/target/psoc4.cfg deleted file mode 100644 index d443b0144..000000000 --- a/tcl/target/psoc4.cfg +++ /dev/null @@ -1,152 +0,0 @@ -# script for Cypress PSoC 41xx/42xx family - -# -# PSoC 4 devices support SWD transports only. -# -source [find target/swj-dp.tcl] - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME psoc4 -} - -# Work-area is a space in RAM used for flash programming -# By default use 4kB -if { [info exists WORKAREASIZE] } { - set _WORKAREASIZE $WORKAREASIZE -} else { - set _WORKAREASIZE 0x1000 -} - -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - set _CPUTAPID 0x0bb11477 -} - -swj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID - -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME cortex_m -chain-position $_TARGETNAME - -$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0 - -set _FLASHNAME $_CHIPNAME.flash -flash bank $_FLASHNAME psoc4 0 0 0 0 $_TARGETNAME - -adapter_khz 1500 - -# Reset, bloody PSoC 4 reset -# -# 1) XRES (nSRST) resets also SWD DP so SWD line reset and DP reinit is needed. -# High level adapter stops working after SRST and needs OpenOCD restart. -# If your hw does not use SRST for other circuits, use sysresetreq instead -# -# 2) PSoC 4 executes initialization code from system ROM after reset. -# This code subsequently jumps to user flash reset vector address. -# Unfortunately the system ROM code is protected from reading and debugging. -# Protection breaks vector catch VC_CORERESET used for "reset halt" by cortex_m. -# -# Cypress uses TEST_MODE flag to loop CPU in system ROM before executing code -# from user flash. Programming specifications states that TEST_MODE flag must be -# set in time frame 400 usec delayed about 1 msec from reset. -# -# OpenOCD have no standard way how to set TEST_MODE in specified time frame. -# TEST_MODE flag is set before reset instead. It worked for tested chips -# despite it is not guaranteed by specification. -# -# 3) SWD cannot be connected during system initialization after reset. -# This might be a reason for unconnecting ST-Link v2 when deasserting reset. -# As a workaround arp_reset deassert is not called for hla - -if {![using_hla]} { - # if srst is not fitted use SYSRESETREQ to - # perform a soft reset - cortex_m reset_config sysresetreq -} - -proc ocd_process_reset_inner { MODE } { - if { 0 != [string compare psoc4.cpu [target names]] } { - return -code error "PSoC 4 reset can handle only one psoc4.cpu target"; - } - set t psoc4.cpu - - # If this target must be halted... - set halt -1 - if { 0 == [string compare $MODE halt] } { - set halt 1 - } - if { 0 == [string compare $MODE init] } { - set halt 1; - } - if { 0 == [string compare $MODE run ] } { - set halt 0; - } - if { $halt < 0 } { - return -code error "Invalid mode: $MODE, must be one of: halt, init, or run"; - } - - #$t invoke-event reset-start - $t invoke-event reset-assert-pre - - set TEST_MODE 0x40030014 - if { $halt == 1 } { - mww $TEST_MODE 0x80000000 - } else { - mww $TEST_MODE 0 - } - - $t arp_reset assert 0 - $t invoke-event reset-assert-post - $t invoke-event reset-deassert-pre - if {![using_hla]} { # workaround ST-Link v2 fails and forcing reconnect - $t arp_reset deassert 0 - } - $t invoke-event reset-deassert-post - - # Pass 1 - Now wait for any halt (requested as part of reset - # assert/deassert) to happen. Ideally it takes effect without - # first executing any instructions. - if { $halt } { - # Now PSoC CPU should loop in system ROM - $t arp_waitstate running 200 - $t arp_halt - - # Catch, but ignore any errors. - catch { $t arp_waitstate halted 1000 } - - # Did we succeed? - set s [$t curstate] - - if { 0 != [string compare $s "halted" ] } { - return -code error [format "TARGET: %s - Not halted" $t] - } - - # Check if PSoC CPU is stopped in system ROM - set pc [ocd_reg pc] - regsub {pc[^:]*: } $pc "" pc - if { $pc < 0x10000000 || $pc > 0x1000ffff } { - return -code error [format "TARGET: %s - Not halted in system ROM, use 'reset_config none'" $t] - } - - # Set registers to reset vector values - mem2array value 32 0 2 - reg pc [expr $value(1) & 0xfffffffe ] - reg msp $value(0) - - mww $TEST_MODE 0 - } - - #Pass 2 - if needed "init" - if { 0 == [string compare init $MODE] } { - set err [catch "$t arp_waitstate halted 5000"] - - # Did it halt? - if { $err == 0 } { - $t invoke-event reset-init - } - } - - $t invoke-event reset-end -} diff --git a/tcl/target/psoc5lp.cfg b/tcl/target/psoc5lp.cfg deleted file mode 100644 index 1cdde4712..000000000 --- a/tcl/target/psoc5lp.cfg +++ /dev/null @@ -1,32 +0,0 @@ -# -# Cypress PSoC 5LP -# - -source [find target/swj-dp.tcl] - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME psoc5lp -} - -if { [info exists CPUTAPID] } { - set _CPU_TAPID $CPUTAPID -} else { - set _CPU_TAPID 0x4BA00477 -} - -if { [using_jtag] } { - set _CPU_DAP_ID $_CPU_TAPID -} else { - set _CPU_DAP_ID 0x2ba01477 -} - -swj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_CPU_DAP_ID - -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME cortex_m -chain-position $_TARGETNAME - -if {![using_hla]} { - cortex_m reset_config sysresetreq -} diff --git a/tcl/target/pxa255.cfg b/tcl/target/pxa255.cfg deleted file mode 100644 index 386242597..000000000 --- a/tcl/target/pxa255.cfg +++ /dev/null @@ -1,59 +0,0 @@ -# PXA255 chip ... originally from Intel, PXA line was sold to Marvell. -# This chip is now at end-of-life. Final orders have been taken. - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME pxa255 -} - -if { [info exists ENDIAN] } { - set _ENDIAN $ENDIAN -} else { - set _ENDIAN little -} - -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - set _CPUTAPID 0x69264013 -} - -jtag newtap $_CHIPNAME cpu -irlen 5 -expected-id $_CPUTAPID - -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME xscale -endian $_ENDIAN \ - -chain-position $_CHIPNAME.cpu - -# PXA255 comes out of reset using 3.6864 MHz oscillator. -# Until the PLL kicks in, keep the JTAG clock slow enough -# that we get no errors. -adapter_khz 300 -$_TARGETNAME configure -event "reset-start" { adapter_khz 300 } - -# both TRST and SRST are *required* for debug -# DCSR is often accessed with SRST active -reset_config trst_and_srst separate srst_nogate - -# reset processing that works with PXA -proc init_reset {mode} { - # assert both resets; equivalent to power-on reset - jtag_reset 1 1 - - # drop TRST after at least 32 cycles - sleep 1 - jtag_reset 0 1 - - # minimum 32 TCK cycles to wake up the controller - runtest 50 - - # now the TAP will be responsive; validate scanchain - jtag arp_init - - # ... and take it out of reset - jtag_reset 0 0 -} - -proc jtag_init {} { - init_reset startup -} diff --git a/tcl/target/pxa270.cfg b/tcl/target/pxa270.cfg deleted file mode 100644 index 95f7f16f0..000000000 --- a/tcl/target/pxa270.cfg +++ /dev/null @@ -1,50 +0,0 @@ -#Marvell/Intel PXA270 Script - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME pxa270 -} - -if { [info exists ENDIAN] } { - set _ENDIAN $ENDIAN -} else { - set _ENDIAN little -} - -#IDs for pxa270. Are there more? -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - # set useful default - set _CPUTAPID 0x49265013 -} - -if { [info exists CPUTAPID2] } { - set _CPUTAPID2 $CPUTAPID2 -} else { - # set useful default - set _CPUTAPID2 0x79265013 -} - -if { [info exists CPUTAPID3] } { - set _CPUTAPID2 $CPUTAPID3 -} else { - # set useful default - set _CPUTAPID3 0x89265013 -} - -# set adapter_nsrst_delay to the delay introduced by your reset circuit -# the rest of the needed delays are built into the openocd program -adapter_nsrst_delay 260 -# set the jtag_ntrst_delay to the delay introduced by a reset circuit -# the rest of the needed delays are built into the openocd program -jtag_ntrst_delay 250 - -set _TARGETNAME $_CHIPNAME.cpu -jtag newtap $_CHIPNAME cpu -irlen 7 -ircapture 0x1 -irmask 0x7f -expected-id $_CPUTAPID -expected-id $_CPUTAPID2 -expected-id $_CPUTAPID3 - -target create $_TARGETNAME xscale -endian $_ENDIAN -chain-position $_TARGETNAME -# maps to PXA internal RAM. If you are using a PXA255 -# you must initialize SDRAM or leave this option off -$_TARGETNAME configure -work-area-phys 0x5c000000 -work-area-size 0x10000 -work-area-backup 0 diff --git a/tcl/target/pxa3xx.cfg b/tcl/target/pxa3xx.cfg deleted file mode 100644 index c459f6eaa..000000000 --- a/tcl/target/pxa3xx.cfg +++ /dev/null @@ -1,86 +0,0 @@ -# Marvell PXA3xx - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME pxa3xx -} - -if { [info exists ENDIAN] } { - set _ENDIAN $ENDIAN -} else { - set _ENDIAN little -} - -# IDs for all currently known PXA3xx chips -if { [info exists CPUTAPID_PXA30X_A0] } { - set _CPUTAPID_PXA30X_A0 $CPUTAPID_PXA30X_A0 -} else { - set _CPUTAPID_PXA30X_A0 0x0E648013 -} -if { [info exists CPUTAPID_PXA30X_A1] } { - set _CPUTAPID_PXA30X_A1 $CPUTAPID_PXA30X_A1 -} else { - set _CPUTAPID_PXA30X_A1 0x1E648013 -} -if { [info exists CPUTAPID_PXA31X_A0] } { - set _CPUTAPID_PXA31X_A0 $CPUTAPID_PXA31X_A0 -} else { - set _CPUTAPID_PXA31X_A0 0x0E649013 -} -if { [info exists CPUTAPID_PXA31X_A1] } { - set _CPUTAPID_PXA31X_A1 $CPUTAPID_PXA31X_A1 -} else { - set _CPUTAPID_PXA31X_A1 0x1E649013 -} -if { [info exists CPUTAPID_PXA31X_A2] } { - set _CPUTAPID_PXA31X_A2 $CPUTAPID_PXA31X_A2 -} else { - set _CPUTAPID_PXA31X_A2 0x2E649013 -} -if { [info exists CPUTAPID_PXA31X_B0] } { - set _CPUTAPID_PXA31X_B0 $CPUTAPID_PXA31X_B0 -} else { - set _CPUTAPID_PXA31X_B0 0x3E649013 -} -if { [info exists CPUTAPID_PXA32X_B1] } { - set _CPUTAPID_PXA32X_B1 $CPUTAPID_PXA32X_B1 -} else { - set _CPUTAPID_PXA32X_B1 0x5E642013 -} -if { [info exists CPUTAPID_PXA32X_B2] } { - set _CPUTAPID_PXA32X_B2 $CPUTAPID_PXA32X_B2 -} else { - set _CPUTAPID_PXA32X_B2 0x6E642013 -} -if { [info exists CPUTAPID_PXA32X_C0] } { - set _CPUTAPID_PXA32X_C0 $CPUTAPID_PXA32X_C0 -} else { - set _CPUTAPID_PXA32X_C0 0x7E642013 -} - -# set adapter_nsrst_delay to the delay introduced by your reset circuit -# the rest of the needed delays are built into the openocd program -adapter_nsrst_delay 260 - -# set the jtag_ntrst_delay to the delay introduced by a reset circuit -# the rest of the needed delays are built into the openocd program -jtag_ntrst_delay 250 - -set _TARGETNAME $_CHIPNAME.cpu -jtag newtap $_CHIPNAME cpu -irlen 11 -ircapture 0x1 -irmask 0x7f \ - -expected-id $_CPUTAPID_PXA30X_A0 \ - -expected-id $_CPUTAPID_PXA30X_A1 \ - -expected-id $_CPUTAPID_PXA31X_A0 \ - -expected-id $_CPUTAPID_PXA31X_A1 \ - -expected-id $_CPUTAPID_PXA31X_A2 \ - -expected-id $_CPUTAPID_PXA31X_B0 \ - -expected-id $_CPUTAPID_PXA32X_B1 \ - -expected-id $_CPUTAPID_PXA32X_B2 \ - -expected-id $_CPUTAPID_PXA32X_C0 - -target create $_TARGETNAME xscale -endian $_ENDIAN \ - -chain-position $_TARGETNAME - -# work area in internal RAM. -$_TARGETNAME configure -work-area-phys 0x5c030000 -work-area-size 0x10000 diff --git a/tcl/target/quark_d20xx.cfg b/tcl/target/quark_d20xx.cfg deleted file mode 100644 index 419f9dc4d..000000000 --- a/tcl/target/quark_d20xx.cfg +++ /dev/null @@ -1,50 +0,0 @@ -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - set _CPUTAPID 0x38289013 -} - -jtag newtap quark_d20xx quark -irlen 8 -irmask 0xff -expected-id $_CPUTAPID -disable -jtag newtap quark_d20xx cltap -irlen 8 -irmask 0xff -expected-id 0x0e786013 -enable - -proc quark_d20xx_tapenable {} { - echo "enabling quark core tap" - irscan quark_d20xx.cltap 0x11 - drscan quark_d20xx.cltap 12 1 - runtest 10 -} - -proc quark_d20xx_tapdisable {} { - echo "disabling quark core tap" - irscan quark_d20xx.cltap 0x11 - drscan quark_d20xx.cltap 12 0 - runtest 10 -} - -proc quark_d20xx_setup {} { - jtag tapenable quark_d20xx.quark -} - -jtag configure quark_d20xx.quark -event tap-enable \ - "quark_d20xx_tapenable" - -jtag configure quark_d20xx.quark -event tap-disable \ - "quark_d20xx_tapdisable" - -target create quark_d20xx.quark quark_d20xx -endian little -chain-position quark_d20xx.quark - -quark_d20xx.quark configure -event gdb-attach { halt } - -quark_d20xx.quark configure -event reset-start { - # need to halt the target to write to memory - if {[quark_d20xx.quark curstate] ne "halted"} { halt } - # set resetbreak via the core tap - irscan quark_d20xx.quark 0x35 ; drscan quark_d20xx.quark 1 0x1 - # trigger a warm reset - mww 0xb0800570 0x2 - # clear resetbreak - irscan quark_d20xx.quark 0x35 ; drscan quark_d20xx.quark 1 0x0 -} - -jtag configure quark_d20xx.quark -event setup \ - "quark_d20xx_setup" diff --git a/tcl/target/quark_x10xx.cfg b/tcl/target/quark_x10xx.cfg deleted file mode 100644 index a5bbfb497..000000000 --- a/tcl/target/quark_x10xx.cfg +++ /dev/null @@ -1,52 +0,0 @@ -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME quark_x10xx -} - -if { [info exists ENDIAN] } { - set _ENDIAN $ENDIAN -} else { - set _ENDIAN little -} - - -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - set _CPUTAPID 0x18289013 -} - -jtag newtap quark_x10xx cpu -irlen 8 -irmask 0xff -expected-id $_CPUTAPID -disable -jtag newtap quark_x10xx cltap -irlen 8 -irmask 0xff -expected-id 0x0e681013 -enable - -#openocd puts tap at front of chain not end of chain -proc quark_x10xx_tapenable {} { - echo "enabling core tap" - irscan quark_x10xx.cltap 0x11 - drscan quark_x10xx.cltap 64 1 - runtest 10 -} - -proc quark_x10xx_tapdisable {} { - echo "disabling core tap" - irscan quark_x10xx.cltap 0x11 - drscan quark_x10xx.cltap 64 0 - runtest 10 -} - -proc quark_x10xx_setup {} { - jtag tapenable quark_x10xx.cpu -} - -jtag configure $_CHIPNAME.cpu -event tap-enable \ - "quark_x10xx_tapenable" - -jtag configure $_CHIPNAME.cpu -event tap-disable \ - "quark_x10xx_tapdisable" - -set _TARGETNAME $_CHIPNAME.cpu -target create quark_x10xx.cpu quark_x10xx -endian $_ENDIAN -chain-position quark_x10xx.cpu - -jtag configure $_CHIPNAME.cpu -event setup \ - "quark_x10xx_setup" diff --git a/tcl/target/readme.txt b/tcl/target/readme.txt deleted file mode 100644 index f028b11c7..000000000 --- a/tcl/target/readme.txt +++ /dev/null @@ -1,41 +0,0 @@ -Prerequisites: -The users of OpenOCD as well as computer programs interacting with OpenOCD are expecting that certain commands -do the same thing across all the targets. - -Rules to follow when writing scripts: - -1. The configuration script should be defined such as , for example, the following sequences are working: - reset - flash info -and - reset - flash erase_address -and - reset init - load - -In most cases this can be accomplished by specifying the default startup mode as reset_init (target command -in the configuration file). - -2. If the target is correctly configured, flash must be writable without any other helper commands. It is -assumed that all write-protect mechanisms should be disabled. - -3. The configuration scripts should be defined such as the binary that was written to flash verifies -(turn off remapping, checksums, etc...) - -flash write_image [file] -verify_image [file] - -4. adapter_khz sets the maximum speed (or alternatively RCLK). If invoked -multiple times only the last setting is used. - -interface/xxx.cfg files are always executed *before* target/xxx.cfg -files, so any adapter_khz in interface/xxx.cfg will be overridden by -target/xxx.cfg. adapter_khz in interface/xxx.cfg would then, effectively, -set the default JTAG speed. - -Note that a target/xxx.cfg file can invoke another target/yyy.cfg file, -so one can create target subtype configurations where e.g. only -amount of DRAM, oscillator speeds differ and having a single -config file for the default/common settings. - diff --git a/tcl/target/renesas_s7g2.cfg b/tcl/target/renesas_s7g2.cfg deleted file mode 100644 index a09377b2d..000000000 --- a/tcl/target/renesas_s7g2.cfg +++ /dev/null @@ -1,50 +0,0 @@ -# -# Renesas Synergy S7 G2 w/ ARM Cortex-M4 @ 240 MHz -# - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME s7g2 -} - -if { [info exists CPU_JTAG_TAPID] } { - set _CPU_JTAG_TAPID $CPU_JTAG_TAPID -} else { - set _CPU_JTAG_TAPID 0x5ba00477 -} - -if { [info exists CPU_SWD_TAPID] } { - set _CPU_SWD_TAPID $CPU_SWD_TAPID -} else { - set _CPU_SWD_TAPID 0x5ba02477 -} - -source [find target/swj-dp.tcl] - -if { [using_jtag] } { - set _CPU_TAPID $_CPU_JTAG_TAPID -} else { - set _CPU_TAPID $_CPU_SWD_TAPID -} - -swj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_CPU_TAPID - -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME cortex_m -chain-position $_TARGETNAME - -if { [info exists WORKAREASIZE] } { - set _WORKAREASIZE $WORKAREASIZE -} else { - # 640 KB On-Chip SRAM - set _WORKAREASIZE 0xa0000 -} - -$_TARGETNAME configure -work-area-phys 0x1ffe0000 \ - -work-area-size $_WORKAREASIZE -work-area-backup 0 - -if { ![using_hla] } { - cortex_m reset_config sysresetreq -} - -adapter_khz 1000 diff --git a/tcl/target/samsung_s3c2410.cfg b/tcl/target/samsung_s3c2410.cfg deleted file mode 100644 index 017c10492..000000000 --- a/tcl/target/samsung_s3c2410.cfg +++ /dev/null @@ -1,36 +0,0 @@ -# Found on the 'TinCanTools' Hammer board. - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME s3c2410 -} - -if { [info exists ENDIAN] } { - set _ENDIAN $ENDIAN -} else { - # This config file was defaulting to big endian.. - set _ENDIAN little -} - -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - # Force an error until we get a good number. - set _CPUTAPID 0xffffffff -} - -#use combined on interfaces or targets that cannot set TRST/SRST separately -reset_config trst_and_srst - -#jtag scan chain -jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID - -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME arm920t -endian $_ENDIAN -chain-position $_TARGETNAME - -$_TARGETNAME configure -work-area-phys 0x30800000 -work-area-size 0x20000 -work-area-backup 0 - -# speed up memory downloads -arm7_9 fast_memory_access enable -arm7_9 dcc_downloads enable diff --git a/tcl/target/samsung_s3c2440.cfg b/tcl/target/samsung_s3c2440.cfg deleted file mode 100644 index 2a0a915d6..000000000 --- a/tcl/target/samsung_s3c2440.cfg +++ /dev/null @@ -1,35 +0,0 @@ -# Target configuration for the Samsung 2440 system on chip -# Tested on a S3C2440 Evaluation board by keesj -# Processor : ARM920Tid(wb) rev 0 (v4l) -# Info: JTAG tap: s3c2440.cpu tap/device found: 0x0032409d (Manufacturer: 0x04e, Part: 0x0324, Version: 0x0) - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME s3c2440 -} - -if { [info exists ENDIAN] } { - set _ENDIAN $ENDIAN -} else { - # this defaults to a bigendian - set _ENDIAN little -} - -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - set _CPUTAPID 0x0032409d -} - -#jtag scan chain -jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0x0f -expected-id $_CPUTAPID - -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME arm920t -endian $_ENDIAN -chain-position $_TARGETNAME - -$_TARGETNAME configure -work-area-phys 0x200000 -work-area-size 0x4000 -work-area-backup 1 - -#reset configuration -reset_config trst_and_srst - diff --git a/tcl/target/samsung_s3c2450.cfg b/tcl/target/samsung_s3c2450.cfg deleted file mode 100644 index 1bc4f2d87..000000000 --- a/tcl/target/samsung_s3c2450.cfg +++ /dev/null @@ -1,48 +0,0 @@ -# Target configuration for the Samsung 2450 system on chip -# Processor : ARM926ejs (wb) rev 0 (v4l) -# Info: JTAG tap: s3c2450.cpu tap/device found: 0x07926F0F - - -# FIX!!! what to use here? -# -# RCLK? -# -# adapter_khz 0 -# -# Really low clock during reset? -# -# adapter_khz 1 - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME s3c2450 -} - -if { [info exists ENDIAN] } { - set _ENDIAN $ENDIAN -} else { - # this defaults to a bigendian - set _ENDIAN little -} - -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - set _CPUTAPID 0x07926f0f -} - -#jtag scan chain -jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0xE -irmask 0x0f -expected-id $_CPUTAPID - -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME arm926ejs -endian $_ENDIAN -chain-position $_TARGETNAME - -# FIX!!!!! should this really use srst_pulls_trst? -# With srst_pulls_trst "reset halt" will not reset into the -# halted mode, but rather "reset run" and then halt the target. -# -# However, without "srst_pulls_trst", then "reset halt" produces weird -# errors: -# WARNING: unknown debug reason: 0x0 -reset_config trst_and_srst diff --git a/tcl/target/samsung_s3c4510.cfg b/tcl/target/samsung_s3c4510.cfg deleted file mode 100644 index 461d0478a..000000000 --- a/tcl/target/samsung_s3c4510.cfg +++ /dev/null @@ -1,24 +0,0 @@ -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME s3c4510 -} - -if { [info exists ENDIAN] } { - set _ENDIAN $ENDIAN -} else { - set _ENDIAN little -} - - -# This appears to be a "Version 1" arm7tdmi. -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - set _CPUTAPID 0x1f0f0f0f -} -jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID - -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME arm7tdmi -endian $_ENDIAN -chain-position $_TARGETNAME - diff --git a/tcl/target/samsung_s3c6410.cfg b/tcl/target/samsung_s3c6410.cfg deleted file mode 100644 index 88fe966dc..000000000 --- a/tcl/target/samsung_s3c6410.cfg +++ /dev/null @@ -1,51 +0,0 @@ -# -*- tcl -*- -# Target configuration for the Samsung s3c6410 system on chip -# Tested on a SMDK6410 -# Processor : ARM1176 -# Info: JTAG device found: 0x0032409d (Manufacturer: 0x04e, Part: 0x0324, Version: 0x0) -# [Duane Ellis 27/nov/2008: Above 0x0032409d appears to be copy/paste from other places] -# [and I do not believe it to be accurate, hence the 0xffffffff below] - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME s3c6410 -} - -if { [info exists ENDIAN] } { - set _ENDIAN $ENDIAN -} else { - # this defaults to a bigendian - set _ENDIAN little -} - -# trace buffer -if { [info exists ETBTAPID] } { - set _ETBTAPID $ETBTAPID -} else { - set _ETBTAPID 0x2b900f0f -} - -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - set _CPUTAPID 0x07b76f0f -} - -#jtag scan chain - -jtag newtap $_CHIPNAME etb -irlen 4 -expected-id $_ETBTAPID -jtag newtap $_CHIPNAME cpu -irlen 5 -ircapture 0x1 -irmask 0x1f -expected-id $_CPUTAPID - -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME arm11 -endian $_ENDIAN -chain-position $_TARGETNAME - -adapter_nsrst_delay 500 -jtag_ntrst_delay 500 - -#reset configuration -reset_config trst_and_srst - -# trace setup ... NOTE, "normal full" mode fudges the real ETMv3.1 mode -etm config $_TARGETNAME 16 normal full etb -etb config $_TARGETNAME $_CHIPNAME.etb diff --git a/tcl/target/sharp_lh79532.cfg b/tcl/target/sharp_lh79532.cfg deleted file mode 100644 index 6f2cf2234..000000000 --- a/tcl/target/sharp_lh79532.cfg +++ /dev/null @@ -1,26 +0,0 @@ -reset_config srst_only srst_pulls_trst - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME lh79532 -} - -if { [info exists ENDIAN] } { - set _ENDIAN $ENDIAN -} else { - set _ENDIAN little -} - -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - # sharp changed the number! - set _CPUTAPID 0x00002061 -} -jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID - -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME arm7tdmi -endian $_ENDIAN -chain-position $_TARGETNAME - - diff --git a/tcl/target/sim3x.cfg b/tcl/target/sim3x.cfg deleted file mode 100755 index f721f36c8..000000000 --- a/tcl/target/sim3x.cfg +++ /dev/null @@ -1,55 +0,0 @@ -# -# Silicon Laboratories SiM3x Cortex-M3 -# - -# SiM3x devices support both JTAG and SWD transports. -source [find target/swj-dp.tcl] - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME SiM3x -} - -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - set _CPUTAPID 0x4ba00477 -} - -if { [info exists CPURAMSIZE] } { - set _CPURAMSIZE $CPURAMSIZE -} else { -# Minimum size of RAM in the Silicon Labs product matrix (8KB) - set _CPURAMSIZE 0x2000 -} - -if { [info exists CPUROMSIZE] } { - set _CPUROMSIZE $CPUROMSIZE -} else { -# Minimum size of FLASH in the Silicon Labs product matrix (32KB) - set _CPUROMSIZE 0x8000 -} - -if { [info exists WORKAREASIZE] } { - set _WORKAREASIZE $WORKAREASIZE -} else { - set _WORKAREASIZE $_CPURAMSIZE -} - -swj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID - -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME cortex_m -chain-position $_TARGETNAME - -$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE - -set _FLASHNAME $_CHIPNAME.flash -flash bank $_FLASHNAME sim3x 0 $_CPUROMSIZE 0 0 $_TARGETNAME - -adapter_khz 1000 - -adapter_nsrst_delay 100 -if {[using_jtag]} { - jtag_ntrst_delay 100 -} diff --git a/tcl/target/smp8634.cfg b/tcl/target/smp8634.cfg deleted file mode 100644 index c13414c87..000000000 --- a/tcl/target/smp8634.cfg +++ /dev/null @@ -1,31 +0,0 @@ -# script for Sigma Designs SMP8634 (eventually even SMP8635) - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME smp8634 -} - -if { [info exists ENDIAN] } { - set _ENDIAN $ENDIAN -} else { - set _ENDIAN little -} - -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - set _CPUTAPID 0x08630001 -} - -adapter_nsrst_delay 100 -jtag_ntrst_delay 100 - -reset_config trst_and_srst separate - -# jtag scan chain -# format L IRC IRCM IDCODE (Length, IR Capture, IR Capture Mask, IDCODE) -jtag newtap $_CHIPNAME cpu -irlen 5 -ircapture 0x1 -irmask 0x1 - -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME mips_m4k -endian $_ENDIAN diff --git a/tcl/target/spear3xx.cfg b/tcl/target/spear3xx.cfg deleted file mode 100644 index a86a3c4eb..000000000 --- a/tcl/target/spear3xx.cfg +++ /dev/null @@ -1,41 +0,0 @@ -# Target configuration for the ST SPEAr3xx family of system on chip -# Supported SPEAr300, SPEAr310, SPEAr320 -# http://www.st.com/spear -# -# Processor: ARM926ejs -# Info: JTAG tap: spear3xx.cpu tap/device found: 0x07926041 -# Date: 2009-10-31 -# Author: Antonio Borneo - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME spear3xx -} - -if { [info exists ENDIAN] } { - set _ENDIAN $ENDIAN -} else { - set _ENDIAN little -} - -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - set _CPUTAPID 0x07926041 -} - -jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x01 -irmask 0x03 \ - -expected-id $_CPUTAPID - -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME arm926ejs -endian $_ENDIAN \ - -chain-position $_TARGETNAME - -# SPEAr3xx has a 8K block of sram @ 0xd280.0000 -# REVISIT: what OS puts virtual address equal to phys? -$_TARGETNAME configure \ - -work-area-virt 0xd2800000 \ - -work-area-phys 0xd2800000 \ - -work-area-size 0x2000 \ - -work-area-backup 0 diff --git a/tcl/target/stellaris.cfg b/tcl/target/stellaris.cfg deleted file mode 100644 index 4fe99394a..000000000 --- a/tcl/target/stellaris.cfg +++ /dev/null @@ -1,176 +0,0 @@ -# TI/Luminary Stellaris LM3S chip family - -# Some devices have errata in returning their device class. -# DEVICECLASS is provided as a manual override -# Manual setting of a device class of 0xff is not allowed - -global _DEVICECLASS - -if { [info exists DEVICECLASS] } { - set _DEVICECLASS $DEVICECLASS -} else { - set _DEVICECLASS 0xff -} - -# Luminary chips support both JTAG and SWD transports. -# Adapt based on what transport is active. -source [find target/swj-dp.tcl] - -# For now we ignore the SPI and UART options, which -# are usable only for ISP style initial flash programming. - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME lm3s -} - -# CPU TAP ID 0x1ba00477 for early Sandstorm parts -# CPU TAP ID 0x2ba00477 for later SandStorm parts, e.g. lm3s811 Rev C2 -# CPU TAP ID 0x3ba00477 for Cortex-M3 r1p2 (on Fury, DustDevil) -# CPU TAP ID 0x4ba00477 for Cortex-M3 r2p0 (on Tempest, Firestorm) -# CPU TAP ID 0x4ba00477 for Cortex-M4 r0p1 (on Blizzard) -# ... we'll ignore the JTAG version field, rather than list every -# chip revision that turns up. -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - set _CPUTAPID 0x0ba00477 -} - -# SWD DAP, and JTAG TAP, take same params for now; -# ... even though SWD ignores all except TAPID, and -# JTAG shouldn't need anything more then irlen. (and TAPID). -swj_newdap $_CHIPNAME cpu -irlen 4 -irmask 0xf \ - -expected-id $_CPUTAPID -ignore-version - -if { [info exists WORKAREASIZE] } { - set _WORKAREASIZE $WORKAREASIZE -} else { - # default to 2K working area - set _WORKAREASIZE 0x800 -} - -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME cortex_m -chain-position $_CHIPNAME.cpu - -# 8K working area at base of ram, not backed up -# -# NOTE: you may need or want to reconfigure the work area; -# some parts have just 6K, and you may want to use other -# addresses (at end of mem not beginning) or back it up. -$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE - -# JTAG speed ... slow enough to work with a 12 MHz RC oscillator; -# LM3S parts don't support RTCK -# -# NOTE: this may be increased by a reset-init handler, after it -# configures and enables the PLL. Or you might need to decrease -# this, if you're using a slower clock. -adapter_khz 500 - -source [find mem_helper.tcl] - -proc reset_peripherals {family} { - - source [find chip/ti/lm3s/lm3s.tcl] - - echo "Resetting Core Peripherals" - - # Disable the PLL and the system clock divider (nop if disabled) - mmw $SYSCTL_RCC 0 $SYSCTL_RCC_USESYSDIV - mmw $SYSCTL_RCC2 $SYSCTL_RCC2_BYPASS2 0 - - # RCC and RCC2 to their reset values - mww $SYSCTL_RCC [expr (0x078e3ad0 | ([mrw $SYSCTL_RCC] & $SYSCTL_RCC_MOSCDIS))] - mww $SYSCTL_RCC2 0x07806810 - mww $SYSCTL_RCC 0x078e3ad1 - - # Reset the deep sleep clock configuration register - mww $SYSCTL_DSLPCLKCFG 0x07800000 - - # Reset the clock gating registers - mww $SYSCTL_RCGC0 0x00000040 - mww $SYSCTL_RCGC1 0 - mww $SYSCTL_RCGC2 0 - mww $SYSCTL_SCGC0 0x00000040 - mww $SYSCTL_SCGC1 0 - mww $SYSCTL_SCGC2 0 - mww $SYSCTL_DCGC0 0x00000040 - mww $SYSCTL_DCGC1 0 - mww $SYSCTL_DCGC2 0 - - # Reset the remaining SysCtl registers - mww $SYSCTL_PBORCTL 0 - mww $SYSCTL_IMC 0 - mww $SYSCTL_GPIOHBCTL 0 - mww $SYSCTL_MOSCCTL 0 - mww $SYSCTL_PIOSCCAL 0 - mww $SYSCTL_I2SMCLKCFG 0 - - # Reset the peripherals - mww $SYSCTL_SRCR0 0xffffffff - mww $SYSCTL_SRCR1 0xffffffff - mww $SYSCTL_SRCR2 0xffffffff - mww $SYSCTL_SRCR0 0 - mww $SYSCTL_SRCR1 0 - mww $SYSCTL_SRCR2 0 - - # Clear any pending SysCtl interrupts - mww $SYSCTL_MISC 0xffffffff - - # Wait for any pending flash operations to complete - while {[expr [mrw $FLASH_FMC] & 0xffff] != 0} { sleep 1 } - while {[expr [mrw $FLASH_FMC2] & 0xffff] != 0} { sleep 1 } - - # Reset the flash controller registers - mww $FLASH_FMA 0 - mww $FLASH_FCIM 0 - mww $FLASH_FCMISC 0xffffffff - mww $FLASH_FWBVAL 0 -} - -$_TARGETNAME configure -event reset-start { - adapter_khz 500 - - # - # When nRST is asserted on most Stellaris devices, it clears some of - # the debug state. The ARMv7M and Cortex-M3 TRMs say that's wrong; - # and OpenOCD depends on those TRMs. So we won't use SRST on those - # chips. (Only power-on reset should affect debug state, beyond a - # few specified bits; not the chip's nRST input, wired to SRST.) - # - # REVISIT current errata specs don't seem to cover this issue. - # Do we have more details than this email? - # https://lists.berlios.de/pipermail - # /openocd-development/2008-August/003065.html - # - - global _DEVICECLASS - - if {$_DEVICECLASS != 0xff} { - set device_class $_DEVICECLASS - } else { - set device_class [expr (([mrw 0x400fe000] >> 16) & 0xff)] - } - - if {$device_class == 0 || $device_class == 1 || - $device_class == 3 || $device_class == 5 || $device_class == 0xa} { - if {![using_hla]} { - # Sandstorm, Fury, DustDevil, Blizzard and Snowflake are able to use NVIC SYSRESETREQ - cortex_m reset_config sysresetreq - } - } else { - if {![using_hla]} { - # Tempest and Firestorm default to using NVIC VECTRESET - # peripherals will need reseting manually, see proc reset_peripherals - cortex_m reset_config vectreset - } - # reset peripherals, based on code in - # http://www.ti.com/lit/er/spmz573a/spmz573a.pdf - reset_peripherals $device_class - } -} - -# flash configuration ... autodetects sizes, autoprobed -flash bank $_CHIPNAME.flash stellaris 0 0 0 0 $_TARGETNAME diff --git a/tcl/target/stellaris_icdi.cfg b/tcl/target/stellaris_icdi.cfg deleted file mode 100644 index f856a7a8d..000000000 --- a/tcl/target/stellaris_icdi.cfg +++ /dev/null @@ -1,2 +0,0 @@ -echo "WARNING: target/stellaris_icdi.cfg is deprecated, please switch to target/stellaris.cfg" -source [find target/stellaris.cfg] diff --git a/tcl/target/stm32_stlink.cfg b/tcl/target/stm32_stlink.cfg deleted file mode 100644 index 295292e3e..000000000 --- a/tcl/target/stm32_stlink.cfg +++ /dev/null @@ -1 +0,0 @@ -echo "WARNING: stm32_stlink.cfg is deprecated (and does nothing, you can safely remove it.)" diff --git a/tcl/target/stm32f0x.cfg b/tcl/target/stm32f0x.cfg deleted file mode 100644 index 2b48cfce3..000000000 --- a/tcl/target/stm32f0x.cfg +++ /dev/null @@ -1,86 +0,0 @@ -# script for stm32f0x family - -# -# stm32 devices support SWD transports only. -# -source [find target/swj-dp.tcl] -source [find mem_helper.tcl] - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME stm32f0x -} - -set _ENDIAN little - -# Work-area is a space in RAM used for flash programming -# By default use 4kB -if { [info exists WORKAREASIZE] } { - set _WORKAREASIZE $WORKAREASIZE -} else { - set _WORKAREASIZE 0x1000 -} - -#jtag scan chain -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - # See STM Document RM0091 - # Section 29.5.3 - set _CPUTAPID 0x0bb11477 -} - -swj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID - -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME cortex_m -endian $_ENDIAN -chain-position $_TARGETNAME - -$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0 - -# flash size will be probed -set _FLASHNAME $_CHIPNAME.flash -flash bank $_FLASHNAME stm32f1x 0x08000000 0 0 0 $_TARGETNAME - -# adapter speed should be <= F_CPU/6. F_CPU after reset is 8MHz, so use F_JTAG = 1MHz -adapter_khz 1000 - -adapter_nsrst_delay 100 - -reset_config srst_nogate - -if {![using_hla]} { - # if srst is not fitted use SYSRESETREQ to - # perform a soft reset - cortex_m reset_config sysresetreq -} - -proc stm32f0x_default_reset_start {} { - # Reset clock is HSI (8 MHz) - adapter_khz 1000 -} - -proc stm32f0x_default_examine_end {} { - # Enable debug during low power modes (uses more power) - mmw 0x40015804 0x00000006 0 ;# DBGMCU_CR |= DBG_STANDBY | DBG_STOP - - # Stop watchdog counters during halt - mmw 0x40015808 0x00001800 0 ;# DBGMCU_APB1_FZ |= DBG_IWDG_STOP | DBG_WWDG_STOP -} - -proc stm32f0x_default_reset_init {} { - # Configure PLL to boost clock to HSI x 6 (48 MHz) - mww 0x40021004 0x00100000 ;# RCC_CFGR = PLLMUL[2] - mmw 0x40021000 0x01000000 0 ;# RCC_CR[31:16] |= PLLON - mww 0x40022000 0x00000011 ;# FLASH_ACR = PRFTBE | LATENCY[0] - sleep 10 ;# Wait for PLL to lock - mmw 0x40021004 0x00000002 0 ;# RCC_CFGR |= SW[1] - - # Boost JTAG frequency - adapter_khz 8000 -} - -# Default hooks -$_TARGETNAME configure -event examine-end { stm32f0x_default_examine_end } -$_TARGETNAME configure -event reset-start { stm32f0x_default_reset_start } -$_TARGETNAME configure -event reset-init { stm32f0x_default_reset_init } diff --git a/tcl/target/stm32f0x_stlink.cfg b/tcl/target/stm32f0x_stlink.cfg deleted file mode 100644 index cecfb7a78..000000000 --- a/tcl/target/stm32f0x_stlink.cfg +++ /dev/null @@ -1,2 +0,0 @@ -echo "WARNING: target/stm32f0x_stlink.cfg is deprecated, please switch to target/stm32f0x.cfg" -source [find target/stm32f0x.cfg] diff --git a/tcl/target/stm32f1x.cfg b/tcl/target/stm32f1x.cfg deleted file mode 100644 index bd02e95b0..000000000 --- a/tcl/target/stm32f1x.cfg +++ /dev/null @@ -1,109 +0,0 @@ -# script for stm32f1x family - -# -# stm32 devices support both JTAG and SWD transports. -# -source [find target/swj-dp.tcl] -source [find mem_helper.tcl] - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME stm32f1x -} - -set _ENDIAN little - -# Work-area is a space in RAM used for flash programming -# By default use 4kB (as found on some STM32F100s) -if { [info exists WORKAREASIZE] } { - set _WORKAREASIZE $WORKAREASIZE -} else { - set _WORKAREASIZE 0x1000 -} - -#jtag scan chain -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - if { [using_jtag] } { - # See STM Document RM0008 Section 26.6.3 - set _CPUTAPID 0x3ba00477 - } { - # this is the SW-DP tap id not the jtag tap id - set _CPUTAPID 0x1ba01477 - } -} - -swj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID - -if { [info exists BSTAPID] } { - # FIXME this never gets used to override defaults... - set _BSTAPID $BSTAPID -} else { - # See STM Document RM0008 - # Section 29.6.2 - # Low density devices, Rev A - set _BSTAPID1 0x06412041 - # Medium density devices, Rev A - set _BSTAPID2 0x06410041 - # Medium density devices, Rev B and Rev Z - set _BSTAPID3 0x16410041 - set _BSTAPID4 0x06420041 - # High density devices, Rev A - set _BSTAPID5 0x06414041 - # Connectivity line devices, Rev A and Rev Z - set _BSTAPID6 0x06418041 - # XL line devices, Rev A - set _BSTAPID7 0x06430041 - # VL line devices, Rev A and Z In medium-density and high-density value line devices - set _BSTAPID8 0x06420041 - # VL line devices, Rev A - set _BSTAPID9 0x06428041 -} - -if {[using_jtag]} { - swj_newdap $_CHIPNAME bs -irlen 5 -expected-id $_BSTAPID1 \ - -expected-id $_BSTAPID2 -expected-id $_BSTAPID3 \ - -expected-id $_BSTAPID4 -expected-id $_BSTAPID5 \ - -expected-id $_BSTAPID6 -expected-id $_BSTAPID7 \ - -expected-id $_BSTAPID8 -expected-id $_BSTAPID9 -} - -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME cortex_m -endian $_ENDIAN -chain-position $_TARGETNAME - -$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0 - -# flash size will be probed -set _FLASHNAME $_CHIPNAME.flash -flash bank $_FLASHNAME stm32f1x 0x08000000 0 0 0 $_TARGETNAME - -# JTAG speed should be <= F_CPU/6. F_CPU after reset is 8MHz, so use F_JTAG = 1MHz -adapter_khz 1000 - -adapter_nsrst_delay 100 -if {[using_jtag]} { - jtag_ntrst_delay 100 -} - -reset_config srst_nogate - -if {![using_hla]} { - # if srst is not fitted use SYSRESETREQ to - # perform a soft reset - cortex_m reset_config sysresetreq -} - -$_TARGETNAME configure -event examine-end { - # DBGMCU_CR |= DBG_WWDG_STOP | DBG_IWDG_STOP | - # DBG_STANDBY | DBG_STOP | DBG_SLEEP - mmw 0xE0042004 0x00000307 0 -} - -$_TARGETNAME configure -event trace-config { - # Set TRACE_IOEN; TRACE_MODE is set to async; when using sync - # change this value accordingly to configure trace pins - # assignment - mmw 0xE0042004 0x00000020 0 -} diff --git a/tcl/target/stm32f1x_stlink.cfg b/tcl/target/stm32f1x_stlink.cfg deleted file mode 100644 index 0a3e6430e..000000000 --- a/tcl/target/stm32f1x_stlink.cfg +++ /dev/null @@ -1,2 +0,0 @@ -echo "WARNING: target/stm32f1x_stlink.cfg is deprecated, please switch to target/stm32f1x.cfg" -source [find target/stm32f1x.cfg] diff --git a/tcl/target/stm32f2x.cfg b/tcl/target/stm32f2x.cfg deleted file mode 100644 index 0e734debb..000000000 --- a/tcl/target/stm32f2x.cfg +++ /dev/null @@ -1,96 +0,0 @@ -# script for stm32f2x family - -# -# stm32 devices support both JTAG and SWD transports. -# -source [find target/swj-dp.tcl] -source [find mem_helper.tcl] - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME stm32f2x -} - -set _ENDIAN little - -# Work-area is a space in RAM used for flash programming -# By default use 64kB -if { [info exists WORKAREASIZE] } { - set _WORKAREASIZE $WORKAREASIZE -} else { - set _WORKAREASIZE 0x10000 -} - -# JTAG speed should be <= F_CPU/6. F_CPU after reset is 8MHz, so use F_JTAG = 1MHz -# -# Since we may be running of an RC oscilator, we crank down the speed a -# bit more to be on the safe side. Perhaps superstition, but if are -# running off a crystal, we can run closer to the limit. Note -# that there can be a pretty wide band where things are more or less stable. -adapter_khz 1000 - -adapter_nsrst_delay 100 -if {[using_jtag]} { - jtag_ntrst_delay 100 -} - -#jtag scan chain -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - if { [using_jtag] } { - # See STM Document RM0033 - # Section 32.6.3 - corresponds to Cortex-M3 r2p0 - set _CPUTAPID 0x4ba00477 - } { - set _CPUTAPID 0x2ba01477 - } -} - -swj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID - -if { [info exists BSTAPID] } { - set _BSTAPID $BSTAPID -} else { - # See STM Document RM0033 - # Section 32.6.2 - # - set _BSTAPID 0x06411041 -} - -if {[using_jtag]} { - swj_newdap $_CHIPNAME bs -irlen 5 -expected-id $_BSTAPID -} - -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME cortex_m -endian $_ENDIAN -chain-position $_TARGETNAME - -$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0 - -set _FLASHNAME $_CHIPNAME.flash -flash bank $_FLASHNAME stm32f2x 0 0 0 0 $_TARGETNAME - -reset_config srst_nogate - -if {![using_hla]} { - # if srst is not fitted use SYSRESETREQ to - # perform a soft reset - cortex_m reset_config sysresetreq -} - -$_TARGETNAME configure -event examine-end { - # DBGMCU_CR |= DBG_STANDBY | DBG_STOP | DBG_SLEEP - mmw 0xE0042004 0x00000007 0 - - # Stop watchdog counters during halt - # DBGMCU_APB1_FZ |= DBG_IWDG_STOP | DBG_WWDG_STOP - mmw 0xE0042008 0x00001800 0 -} - -$_TARGETNAME configure -event trace-config { - # Set TRACE_IOEN; TRACE_MODE is set to async; when using sync - # change this value accordingly to configure trace pins - # assignment - mmw 0xE0042004 0x00000020 0 -} diff --git a/tcl/target/stm32f2x_stlink.cfg b/tcl/target/stm32f2x_stlink.cfg deleted file mode 100644 index 451b2b5e2..000000000 --- a/tcl/target/stm32f2x_stlink.cfg +++ /dev/null @@ -1,2 +0,0 @@ -echo "WARNING: target/stm32f2x_stlink.cfg is deprecated, please switch to target/stm32f2x.cfg" -source [find target/stm32f2x.cfg] diff --git a/tcl/target/stm32f3x.cfg b/tcl/target/stm32f3x.cfg deleted file mode 100644 index f3ea40bad..000000000 --- a/tcl/target/stm32f3x.cfg +++ /dev/null @@ -1,127 +0,0 @@ -# script for stm32f3x family - -# -# stm32 devices support both JTAG and SWD transports. -# -source [find target/swj-dp.tcl] -source [find mem_helper.tcl] - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME stm32f3x -} - -set _ENDIAN little - -# Work-area is a space in RAM used for flash programming -# By default use 16kB -if { [info exists WORKAREASIZE] } { - set _WORKAREASIZE $WORKAREASIZE -} else { - set _WORKAREASIZE 0x4000 -} - -# JTAG speed should be <= F_CPU/6. F_CPU after reset is 8MHz, so use F_JTAG = 1MHz -# -# Since we may be running of an RC oscilator, we crank down the speed a -# bit more to be on the safe side. Perhaps superstition, but if are -# running off a crystal, we can run closer to the limit. Note -# that there can be a pretty wide band where things are more or less stable. -adapter_khz 1000 - -adapter_nsrst_delay 100 -if {[using_jtag]} { - jtag_ntrst_delay 100 -} - -#jtag scan chain -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - if { [using_jtag] } { - # See STM Document RM0316 - # Section 29.6.3 - corresponds to Cortex-M4 r0p1 - set _CPUTAPID 0x4ba00477 - } { - set _CPUTAPID 0x2ba01477 - } -} - -swj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID - -if { [info exists BSTAPID] } { - set _BSTAPID $BSTAPID -} else { - # STM Document RM0316 rev 5 for STM32F302/303 B/C size - set _BSTAPID1 0x06422041 - # STM Document RM0313 rev 3 for STM32F37x - set _BSTAPID2 0x06432041 - # STM Document RM364 rev 1 for STM32F334 - set _BSTAPID3 0x06438041 - # STM Document RM316 rev 5 for STM32F303 6/8 size - # STM Document RM365 rev 3 for STM32F302 6/8 size - # STM Document RM366 rev 2 for STM32F301 6/8 size - set _BSTAPID4 0x06439041 - # STM Document RM016 rev 5 for STM32F303 D/E size - set _BSTAPID5 0x06446041 -} - -if {[using_jtag]} { - swj_newdap $_CHIPNAME bs -irlen 5 -expected-id $_BSTAPID1 \ - -expected-id $_BSTAPID2 -expected-id $_BSTAPID3 \ - -expected-id $_BSTAPID4 -expected-id $_BSTAPID5 -} - -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME cortex_m -endian $_ENDIAN -chain-position $_TARGETNAME - -$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0 - -set _FLASHNAME $_CHIPNAME.flash -flash bank $_FLASHNAME stm32f1x 0 0 0 0 $_TARGETNAME - -reset_config srst_nogate - -if {![using_hla]} { - # if srst is not fitted use SYSRESETREQ to - # perform a soft reset - cortex_m reset_config sysresetreq -} - -proc stm32f3x_default_reset_start {} { - # Reset clock is HSI (8 MHz) - adapter_khz 1000 -} - -proc stm32f3x_default_examine_end {} { - # Enable debug during low power modes (uses more power) - mmw 0xe0042004 0x00000007 0 ;# DBGMCU_CR |= DBG_STANDBY | DBG_STOP | DBG_SLEEP - - # Stop watchdog counters during halt - mmw 0xe0042008 0x00001800 0 ;# DBGMCU_APB1_FZ |= DBG_IWDG_STOP | DBG_WWDG_STOP -} - -proc stm32f3x_default_reset_init {} { - # Configure PLL to boost clock to HSI x 8 (64 MHz) - mww 0x40021004 0x00380400 ;# RCC_CFGR = PLLMUL[3:1] | PPRE1[2] - mmw 0x40021000 0x01000000 0 ;# RCC_CR |= PLLON - mww 0x40022000 0x00000012 ;# FLASH_ACR = PRFTBE | LATENCY[1] - sleep 10 ;# Wait for PLL to lock - mmw 0x40021004 0x00000002 0 ;# RCC_CFGR |= SW[1] - - # Boost JTAG frequency - adapter_khz 8000 -} - -# Default hooks -$_TARGETNAME configure -event examine-end { stm32f3x_default_examine_end } -$_TARGETNAME configure -event reset-start { stm32f3x_default_reset_start } -$_TARGETNAME configure -event reset-init { stm32f3x_default_reset_init } - -$_TARGETNAME configure -event trace-config { - # Set TRACE_IOEN; TRACE_MODE is set to async; when using sync - # change this value accordingly to configure trace pins - # assignment - mmw 0xe0042004 0x00000020 0 -} diff --git a/tcl/target/stm32f3x_stlink.cfg b/tcl/target/stm32f3x_stlink.cfg deleted file mode 100644 index 87693586d..000000000 --- a/tcl/target/stm32f3x_stlink.cfg +++ /dev/null @@ -1,2 +0,0 @@ -echo "WARNING: target/stm32f3x_stlink.cfg is deprecated, please switch to target/stm32f3x.cfg" -source [find target/stm32f3x.cfg] diff --git a/tcl/target/stm32f4x.cfg b/tcl/target/stm32f4x.cfg deleted file mode 100644 index 2d5cf372f..000000000 --- a/tcl/target/stm32f4x.cfg +++ /dev/null @@ -1,137 +0,0 @@ -# script for stm32f4x family - -# -# stm32 devices support both JTAG and SWD transports. -# -source [find target/swj-dp.tcl] -source [find mem_helper.tcl] - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME stm32f4x -} - -set _ENDIAN little - -# Work-area is a space in RAM used for flash programming -# By default use 32kB (Available RAM in smallest device STM32F410) -if { [info exists WORKAREASIZE] } { - set _WORKAREASIZE $WORKAREASIZE -} else { - set _WORKAREASIZE 0x8000 -} - -#jtag scan chain -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - if { [using_jtag] } { - # See STM Document RM0090 - # Section 38.6.3 - corresponds to Cortex-M4 r0p1 - set _CPUTAPID 0x4ba00477 - } { - set _CPUTAPID 0x2ba01477 - } -} - -swj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID - -if { [info exists BSTAPID] } { - set _BSTAPID $BSTAPID -} else { - # See STM Document RM0090 - # Section 38.6.2 - # STM32F405xx/07xx and STM32F415xx/17xx - set _BSTAPID1 0x06413041 - # STM32F42xxx and STM32F43xxx - set _BSTAPID2 0x06419041 - # See STM Document RM0368 (Rev. 3) - # STM32F401B/C - set _BSTAPID3 0x06423041 - # STM32F401D/E - set _BSTAPID4 0x06433041 - # See STM Document RM0383 (Rev 2) - # STM32F411 - set _BSTAPID5 0x06431041 - # See STM Document RM0386 - # STM32F469 - set _BSTAPID6 0x06434041 - # See STM Document RM0401 - # STM32F410 - set _BSTAPID7 0x06458041 - # STM32F412 - set _BSTAPID8 0x06441041 -} - -if {[using_jtag]} { - swj_newdap $_CHIPNAME bs -irlen 5 -expected-id $_BSTAPID1 \ - -expected-id $_BSTAPID2 -expected-id $_BSTAPID3 \ - -expected-id $_BSTAPID4 -expected-id $_BSTAPID5 \ - -expected-id $_BSTAPID6 -expected-id $_BSTAPID7 \ - -expected-id $_BSTAPID8 -} - -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME cortex_m -endian $_ENDIAN -chain-position $_TARGETNAME - -$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0 - -set _FLASHNAME $_CHIPNAME.flash -flash bank $_FLASHNAME stm32f2x 0 0 0 0 $_TARGETNAME - -# JTAG speed should be <= F_CPU/6. F_CPU after reset is 16MHz, so use F_JTAG = 2MHz -# -# Since we may be running of an RC oscilator, we crank down the speed a -# bit more to be on the safe side. Perhaps superstition, but if are -# running off a crystal, we can run closer to the limit. Note -# that there can be a pretty wide band where things are more or less stable. -adapter_khz 2000 - -adapter_nsrst_delay 100 -if {[using_jtag]} { - jtag_ntrst_delay 100 -} - -reset_config srst_nogate - -if {![using_hla]} { - # if srst is not fitted use SYSRESETREQ to - # perform a soft reset - cortex_m reset_config sysresetreq -} - -$_TARGETNAME configure -event examine-end { - # Enable debug during low power modes (uses more power) - # DBGMCU_CR |= DBG_STANDBY | DBG_STOP | DBG_SLEEP - mmw 0xE0042004 0x00000007 0 - - # Stop watchdog counters during halt - # DBGMCU_APB1_FZ |= DBG_IWDG_STOP | DBG_WWDG_STOP - mmw 0xE0042008 0x00001800 0 -} - -$_TARGETNAME configure -event trace-config { - # Set TRACE_IOEN; TRACE_MODE is set to async; when using sync - # change this value accordingly to configure trace pins - # assignment - mmw 0xE0042004 0x00000020 0 -} - -$_TARGETNAME configure -event reset-init { - # Configure PLL to boost clock to HSI x 4 (64 MHz) - mww 0x40023804 0x08012008 ;# RCC_PLLCFGR 16 Mhz /8 (M) * 128 (N) /4(P) - mww 0x40023C00 0x00000102 ;# FLASH_ACR = PRFTBE | 2(Latency) - mmw 0x40023800 0x01000000 0 ;# RCC_CR |= PLLON - sleep 10 ;# Wait for PLL to lock - mmw 0x40023808 0x00001000 0 ;# RCC_CFGR |= RCC_CFGR_PPRE1_DIV2 - mmw 0x40023808 0x00000002 0 ;# RCC_CFGR |= RCC_CFGR_SW_PLL - - # Boost JTAG frequency - adapter_khz 8000 -} - -$_TARGETNAME configure -event reset-start { - # Reduce speed since CPU speed will slow down to 16MHz with the reset - adapter_khz 2000 -} diff --git a/tcl/target/stm32f4x_stlink.cfg b/tcl/target/stm32f4x_stlink.cfg deleted file mode 100644 index af3e8a098..000000000 --- a/tcl/target/stm32f4x_stlink.cfg +++ /dev/null @@ -1,2 +0,0 @@ -echo "WARNING: target/stm32f4x_stlink.cfg is deprecated, please switch to target/stm32f4x.cfg" -source [find target/stm32f4x.cfg] diff --git a/tcl/target/stm32f7x.cfg b/tcl/target/stm32f7x.cfg deleted file mode 100755 index 05470d498..000000000 --- a/tcl/target/stm32f7x.cfg +++ /dev/null @@ -1,92 +0,0 @@ -# script for stm32f7x family - -# -# stm32f7 devices support both JTAG and SWD transports. -# -source [find target/swj-dp.tcl] -source [find mem_helper.tcl] - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME stm32f7x -} - - set _ENDIAN little - -# Work-area is a space in RAM used for flash programming -# By default use 128kB -if { [info exists WORKAREASIZE] } { - set _WORKAREASIZE $WORKAREASIZE -} else { - set _WORKAREASIZE 0x20000 -} - -#jtag scan chain -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - if { [using_jtag] } { - # See STM Document RM0385 - # Section 40.6.3 - corresponds to Cortex-M7 with FPU r0p0 - set _CPUTAPID 0x5ba00477 - } { - set _CPUTAPID 0x5ba02477 - } -} - -swj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID - -if { [info exists BSTAPID] } { - set _BSTAPID $BSTAPID -} else { - # See STM Document RM0385 - # Section 40.6.1 - # STM32F75xxG - set _BSTAPID1 0x06449041 -} - -if {[using_jtag]} { - swj_newdap $_CHIPNAME bs -irlen 5 -expected-id $_BSTAPID1 -} - -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME cortex_m -endian $_ENDIAN -chain-position $_TARGETNAME - -$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0 - -set _FLASHNAME $_CHIPNAME.flash -flash bank $_FLASHNAME stm32f2x 0 0 0 0 $_TARGETNAME - -# adapter speed should be <= F_CPU/6. F_CPU after reset is 16MHz, so use F_JTAG = 2MHz -adapter_khz 2000 - -adapter_nsrst_delay 100 -if {[using_jtag]} { - jtag_ntrst_delay 100 -} - -# use hardware reset, connect under reset -reset_config srst_only srst_nogate - -if {![using_hla]} { - # if srst is not fitted use SYSRESETREQ to - # perform a soft reset - cortex_m reset_config sysresetreq -} - -$_TARGETNAME configure -event examine-end { - # DBGMCU_CR |= DBG_STANDBY | DBG_STOP | DBG_SLEEP - mmw 0xE0042004 0x00000007 0 - - # Stop watchdog counters during halt - # DBGMCU_APB1_FZ |= DBG_IWDG_STOP | DBG_WWDG_STOP - mmw 0xE0042008 0x00001800 0 -} - -$_TARGETNAME configure -event trace-config { - # Set TRACE_IOEN; TRACE_MODE is set to async; when using sync - # change this value accordingly to configure trace pins - # assignment - mmw 0xE0042004 0x00000020 0 -} diff --git a/tcl/target/stm32l0.cfg b/tcl/target/stm32l0.cfg deleted file mode 100644 index fd8f951bd..000000000 --- a/tcl/target/stm32l0.cfg +++ /dev/null @@ -1,77 +0,0 @@ -# -# M0+ devices only have SW-DP, but swj-dp code works, just don't -# set any jtag related features -# - -source [find target/swj-dp.tcl] - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME stm32l0 -} - -set _ENDIAN little - -# Work-area is a space in RAM used for flash programming -# By default use 8kB (max ram on smallest part) -if { [info exists WORKAREASIZE] } { - set _WORKAREASIZE $WORKAREASIZE -} else { - set _WORKAREASIZE 0x2000 -} - -# JTAG speed should be <= F_CPU/6. -# F_CPU after reset is ~2MHz, so use F_JTAG max = 333kHz -adapter_khz 300 - -adapter_nsrst_delay 100 - -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - # Arm, m0+, non-multidrop. - # http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/ka16088.html - set _CPUTAPID 0x0bc11477 -} - -swj_newdap $_CHIPNAME cpu -expected-id $_CPUTAPID - -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME cortex_m -endian $_ENDIAN -chain-position $_TARGETNAME - -$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0 - -# flash size will be probed -set _FLASHNAME $_CHIPNAME.flash -flash bank $_FLASHNAME stm32lx 0x08000000 0 0 0 $_TARGETNAME - -reset_config srst_nogate - -if {![using_hla]} { - # if srst is not fitted use SYSRESETREQ to - # perform a soft reset - cortex_m reset_config sysresetreq -} - -proc stm32l0_enable_HSI16 {} { - # Enable HSI16 as clock source - echo "STM32L0: Enabling HSI16" - - # Set HSI16ON in RCC_CR (leave MSI enabled) - mww 0x40021000 0x00000101 - - # Set HSI16 as SYSCLK (RCC_CFGR) - mww 0x4002100c 0x00000001 - - # Increase speed - adapter_khz 2500 -} - -$_TARGETNAME configure -event reset-init { - stm32l0_enable_HSI16 -} - -$_TARGETNAME configure -event reset-start { - adapter_khz 300 -} diff --git a/tcl/target/stm32l1.cfg b/tcl/target/stm32l1.cfg deleted file mode 100644 index 790c495b3..000000000 --- a/tcl/target/stm32l1.cfg +++ /dev/null @@ -1,126 +0,0 @@ -# -# stm32l1 devices support both JTAG and SWD transports. -# - -source [find target/swj-dp.tcl] -source [find mem_helper.tcl] - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME stm32l1 -} - -set _ENDIAN little - -# Work-area is a space in RAM used for flash programming -# By default use 10kB -if { [info exists WORKAREASIZE] } { - set _WORKAREASIZE $WORKAREASIZE -} else { - set _WORKAREASIZE 0x2800 -} - -# JTAG speed should be <= F_CPU/6. -# F_CPU after reset is 2MHz, so use F_JTAG max = 333kHz -adapter_khz 300 - -adapter_nsrst_delay 100 -if {[using_jtag]} { - jtag_ntrst_delay 100 -} - -#jtag scan chain -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - if { [using_jtag] } { - # See STM Document RM0038 - # Section 30.6.3 - corresponds to Cortex-M3 r2p0 - set _CPUTAPID 0x4ba00477 - } else { - # SWD IDCODE (single drop, arm) - set _CPUTAPID 0x2ba01477 - } -} - -swj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID - -if { [info exists BSTAPID] } { - # FIXME this never gets used to override defaults... - set _BSTAPID $BSTAPID -} else { - # See STM Document RM0038 Section 30.6.1 Rev. 12 - - # Low and medium density - set _BSTAPID1 0x06416041 - # Cat.2 device (medium+ density) - set _BSTAPID2 0x06429041 - # Cat.3 device (medium+ density) - set _BSTAPID3 0x06427041 - # Cat.4 device, STM32L15/6xxD or Cat.3 device, some STM32L15/6xxC-A models - set _BSTAPID4 0x06436041 - # Cat.5 device (high density), STM32L15/6xxE - set _BSTAPID5 0x06437041 -} - -if {[using_jtag]} { - swj_newdap $_CHIPNAME bs -irlen 5 \ - -expected-id $_BSTAPID1 -expected-id $_BSTAPID2 -expected-id $_BSTAPID3 \ - -expected-id $_BSTAPID4 -expected-id $_BSTAPID5 -} - -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME cortex_m -endian $_ENDIAN -chain-position $_TARGETNAME - -$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0 - -# flash size will be probed -set _FLASHNAME $_CHIPNAME.flash -flash bank $_FLASHNAME stm32lx 0x08000000 0 0 0 $_TARGETNAME - -reset_config srst_nogate - -if {![using_hla]} { - # if srst is not fitted use SYSRESETREQ to - # perform a soft reset - cortex_m reset_config sysresetreq -} - -proc stm32l_enable_HSI {} { - # Enable HSI as clock source - echo "STM32L: Enabling HSI" - - # Set HSION in RCC_CR - mww 0x40023800 0x00000101 - - # Set HSI as SYSCLK - mww 0x40023808 0x00000001 - - # Increase JTAG speed - adapter_khz 2000 -} - -$_TARGETNAME configure -event reset-init { - stm32l_enable_HSI -} - -$_TARGETNAME configure -event reset-start { - adapter_khz 300 -} - -$_TARGETNAME configure -event examine-end { - # DBGMCU_CR |= DBG_STANDBY | DBG_STOP | DBG_SLEEP - mmw 0xE0042004 0x00000007 0 - - # Stop watchdog counters during halt - # DBGMCU_APB1_FZ |= DBG_IWDG_STOP | DBG_WWDG_STOP - mmw 0xE0042008 0x00001800 0 -} - -$_TARGETNAME configure -event trace-config { - # Set TRACE_IOEN; TRACE_MODE is set to async; when using sync - # change this value accordingly to configure trace pins - # assignment - mmw 0xE0042004 0x00000020 0 -} diff --git a/tcl/target/stm32l1x_dual_bank.cfg b/tcl/target/stm32l1x_dual_bank.cfg deleted file mode 100644 index a3f7413a0..000000000 --- a/tcl/target/stm32l1x_dual_bank.cfg +++ /dev/null @@ -1,8 +0,0 @@ -source [find target/stm32l1.cfg] - -# The stm32l1x 384kb have a dual bank flash. -# Let's add a definition for the second bank here. - -# Add the second flash bank. -set _FLASHNAME $_CHIPNAME.flash1 -flash bank $_FLASHNAME stm32lx 0 0 0 0 $_TARGETNAME diff --git a/tcl/target/stm32l4x.cfg b/tcl/target/stm32l4x.cfg deleted file mode 100644 index dec006985..000000000 --- a/tcl/target/stm32l4x.cfg +++ /dev/null @@ -1,111 +0,0 @@ -# script for stm32l4x family - -# -# stm32l4 devices support both JTAG and SWD transports. -# -source [find target/swj-dp.tcl] -source [find mem_helper.tcl] - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME stm32l4x -} - -set _ENDIAN little - -# Work-area is a space in RAM used for flash programming -# Smallest current target has 64kB ram, use 32kB by default to avoid surprises -if { [info exists WORKAREASIZE] } { - set _WORKAREASIZE $WORKAREASIZE -} else { - set _WORKAREASIZE 0x8000 -} - -#jtag scan chain -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - if { [using_jtag] } { - # See STM Document RM0351 - # Section 44.6.3 - corresponds to Cortex-M4 r0p1 - set _CPUTAPID 0x4ba00477 - } { - set _CPUTAPID 0x2ba01477 - } -} - -swj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID - -if { [info exists BSTAPID] } { - set _BSTAPID $BSTAPID -} else { - # See STM Document RM0351 - # Section 44.6.3 - # STM32L4X6 - set _BSTAPID1 0x06415041 -} - -if {[using_jtag]} { - swj_newdap $_CHIPNAME bs -irlen 5 -expected-id $_BSTAPID1 -} - -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME cortex_m -endian $_ENDIAN -chain-position $_TARGETNAME - -$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0 - -set _FLASHNAME $_CHIPNAME.flash -flash bank $_FLASHNAME stm32l4x 0 0 0 0 $_TARGETNAME - -# Common knowledges tells JTAG speed should be <= F_CPU/6. -# F_CPU after reset is MSI 4MHz, so use F_JTAG = 500 kHz to stay on -# the safe side. -# -# Note that there is a pretty wide band where things are -# more or less stable, see http://openocd.zylin.com/#/c/3366/ -adapter_khz 500 - -adapter_nsrst_delay 100 -if {[using_jtag]} { - jtag_ntrst_delay 100 -} - -reset_config srst_nogate - -if {![using_hla]} { - # if srst is not fitted use SYSRESETREQ to - # perform a soft reset - cortex_m reset_config sysresetreq -} - -$_TARGETNAME configure -event reset-init { - # CPU comes out of reset with MSI_ON | MSI_RDY | MSI Range 6 (4 MHz). - # Use MSI 24 MHz clock, compliant even with VOS == 2. - # 3 WS compliant with VOS == 2 and 24 MHz. - mww 0x40022000 0x00000103 ;# FLASH_ACR = PRFTBE | 3(Latency) - mww 0x40021000 0x00000099 ;# RCC_CR = MSI_ON | MSIRGSEL| MSI Range 10 - # Boost JTAG frequency - adapter_khz 4000 -} - -$_TARGETNAME configure -event reset-start { - # Reset clock is MSI (4 MHz) - adapter_khz 500 -} - -$_TARGETNAME configure -event examine-end { - # DBGMCU_CR |= DBG_STANDBY | DBG_STOP | DBG_SLEEP - mmw 0xE0042004 0x00000007 0 - - # Stop watchdog counters during halt - # DBGMCU_APB1_FZ |= DBG_IWDG_STOP | DBG_WWDG_STOP - mmw 0xE0042008 0x00001800 0 -} - -$_TARGETNAME configure -event trace-config { - # Set TRACE_IOEN; TRACE_MODE is set to async; when using sync - # change this value accordingly to configure trace pins - # assignment - mmw 0xE0042004 0x00000020 0 -} diff --git a/tcl/target/stm32lx_stlink.cfg b/tcl/target/stm32lx_stlink.cfg deleted file mode 100644 index 5f694b546..000000000 --- a/tcl/target/stm32lx_stlink.cfg +++ /dev/null @@ -1,2 +0,0 @@ -echo "WARNING: target/stm32lx_stlink.cfg is deprecated, please switch to target/stm32l1.cfg" -source [find target/stm32l1.cfg] diff --git a/tcl/target/stm32w108_stlink.cfg b/tcl/target/stm32w108_stlink.cfg deleted file mode 100644 index 120feea94..000000000 --- a/tcl/target/stm32w108_stlink.cfg +++ /dev/null @@ -1,2 +0,0 @@ -echo "WARNING: target/stm32w108xx_stlink.cfg is deprecated, please switch to target/stm32w108xx.cfg" -source [find target/stm32w108xx.cfg] diff --git a/tcl/target/stm32w108xx.cfg b/tcl/target/stm32w108xx.cfg deleted file mode 100644 index d07afc414..000000000 --- a/tcl/target/stm32w108xx.cfg +++ /dev/null @@ -1,70 +0,0 @@ -# -# Target configuration for the ST STM32W108xx chips -# -# Processor: ARM Cortex-M3 -# Date: 2013-06-09 -# Author: Giuseppe Barba - -# -# stm32 devices support both JTAG and SWD transports. -# -source [find target/swj-dp.tcl] - -if { [info exists CHIPNAME] == 0 } { - set _CHIPNAME stm32w108 -} else { - set _CHIPNAME $CHIPNAME -} - -# Work-area is a space in RAM used for flash programming -# By default use 8kB -if { [info exists WORKAREASIZE] } { - set _WORKAREASIZE $WORKAREASIZE -} else { - set _WORKAREASIZE 0x2000 -} - -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - if { [using_jtag] } { - set _CPUTAPID 0x3ba00477 - } { - set _CPUTAPID 0x1ba01477 - } -} - -set _ENDIAN little - -swj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID - -if {[using_jtag]} { - if { [info exists BSTAPID] } { - set _BSTAPID $BSTAPID - swj_newdap $_CHIPNAME bs -irlen 4 -ircapture 0xe -irmask 0xf -expected-id _BSTAPID - } else { - set _BSTAPID_1 0x169a862b - set _BSTAPID_2 0x269a862b - swj_newdap $_CHIPNAME bs -irlen 4 -ircapture 0xe -irmask 0xf \ - -expected-id $_BSTAPID_1 -expected-id $_BSTAPID_2 - } -} -# -# Set Target -# -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME cortex_m -endian $_ENDIAN -chain-position $_TARGETNAME -$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0 - - -# Use the flash driver from the EM357 -set _FLASHNAME $_CHIPNAME.flash - -# 64k (0x10000) of flash -flash bank $_FLASHNAME em357 0x08000000 0x10000 0 0 $_TARGETNAME - -reset_config srst_nogate - -if {![using_hla]} { - cortex_m reset_config sysresetreq -} diff --git a/tcl/target/stm32xl.cfg b/tcl/target/stm32xl.cfg deleted file mode 100644 index f72896d32..000000000 --- a/tcl/target/stm32xl.cfg +++ /dev/null @@ -1,6 +0,0 @@ -# script for stm32xl family (dual flash bank) -source [find target/stm32f1x.cfg] - -# flash size will be probed -set _FLASHNAME $_CHIPNAME.flash1 -flash bank $_FLASHNAME stm32f1x 0x08080000 0 0 0 $_TARGETNAME diff --git a/tcl/target/str710.cfg b/tcl/target/str710.cfg deleted file mode 100644 index d26a8b1cf..000000000 --- a/tcl/target/str710.cfg +++ /dev/null @@ -1,53 +0,0 @@ -#start slow, speed up after reset -adapter_khz 10 - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME str710 -} - -if { [info exists ENDIAN] } { - set _ENDIAN $ENDIAN -} else { - set _ENDIAN little -} - -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - set _CPUTAPID 0x3f0f0f0f -} - -#use combined on interfaces or targets that can't set TRST/SRST separately -reset_config trst_and_srst srst_pulls_trst - -#jtag scan chain - -jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0x0f -expected-id $_CPUTAPID - -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME arm7tdmi -endian $_ENDIAN -chain-position $_TARGETNAME - -$_TARGETNAME configure -event reset-start { adapter_khz 10 } -$_TARGETNAME configure -event reset-init { - adapter_khz 6000 - -# Because the hardware cannot be interrogated for the protection state -# of sectors, initialize all the sectors to be unprotected. The initial -# state is reflected by the driver, too. - flash protect 0 0 last off - flash protect 1 0 last off -} -$_TARGETNAME configure -event gdb-flash-erase-start { - flash protect 0 0 7 off - flash protect 1 0 1 off -} - -$_TARGETNAME configure -work-area-phys 0x2000C000 -work-area-size 0x4000 -work-area-backup 0 - -#flash bank str7x 0 0 -set _FLASHNAME $_CHIPNAME.flash0 -flash bank $_FLASHNAME str7x 0x40000000 0x00040000 0 0 $_TARGETNAME STR71x -set _FLASHNAME $_CHIPNAME.flash1 -flash bank $_FLASHNAME str7x 0x400C0000 0x00004000 0 0 $_TARGETNAME STR71x diff --git a/tcl/target/str730.cfg b/tcl/target/str730.cfg deleted file mode 100644 index 48d3134aa..000000000 --- a/tcl/target/str730.cfg +++ /dev/null @@ -1,54 +0,0 @@ -#STR730 CPU - -adapter_khz 3000 - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME str730 -} - -if { [info exists ENDIAN] } { - set _ENDIAN $ENDIAN -} else { - set _ENDIAN little -} - -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - set _CPUTAPID 0x3f0f0f0f -} - -#use combined on interfaces or targets that can't set TRST/SRST separately -reset_config trst_and_srst srst_pulls_trst - -#jtag scan chain -jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0x0f -expected-id $_CPUTAPID - -#jtag nTRST and nSRST delay -adapter_nsrst_delay 500 -jtag_ntrst_delay 500 - -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME arm7tdmi -endian little -chain-position 0 - -$_TARGETNAME configure -event reset-start { adapter_khz 10 } -$_TARGETNAME configure -event reset-init { - adapter_khz 3000 - -# Because the hardware cannot be interrogated for the protection state -# of sectors, initialize all the sectors to be unprotected. The initial -# state is reflected by the driver, too. - flash protect 0 0 last off -} -$_TARGETNAME configure -event gdb-flash-erase-start { - flash protect 0 0 7 off -} - -$_TARGETNAME configure -work-area-phys 0xA0000000 -work-area-size 0x4000 -work-area-backup 0 - -#flash bank -set _FLASHNAME $_CHIPNAME.flash -flash bank $_FLASHNAME str7x 0x80000000 0x00040000 0 0 $_TARGETNAME STR73x - diff --git a/tcl/target/str750.cfg b/tcl/target/str750.cfg deleted file mode 100644 index ef6e7954e..000000000 --- a/tcl/target/str750.cfg +++ /dev/null @@ -1,72 +0,0 @@ -#STR750 CPU - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME str750 -} - -if { [info exists ENDIAN] } { - set _ENDIAN $ENDIAN -} else { - set _ENDIAN little -} - -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - set _CPUTAPID 0x4f1f0041 -} - -# jtag speed -adapter_khz 10 - -#use combined on interfaces or targets that can't set TRST/SRST separately -reset_config trst_and_srst srst_pulls_trst - -#jtag scan chain - -jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0x0f -expected-id $_CPUTAPID - -#jtag nTRST and nSRST delay -adapter_nsrst_delay 500 -jtag_ntrst_delay 500 - -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME arm7tdmi -endian little -chain-position 0 - -$_TARGETNAME configure -event reset-start { adapter_khz 10 } -$_TARGETNAME configure -event reset-init { - adapter_khz 3000 - - init_smi -# Because the hardware cannot be interrogated for the protection state -# of sectors, initialize all the sectors to be unprotected. The initial -# state is reflected by the driver, too. - flash protect 0 0 last off - flash protect 1 0 last off -} -$_TARGETNAME configure -event gdb-flash-erase-start { - flash protect 0 0 7 off - flash protect 1 0 1 off -} - -$_TARGETNAME configure -work-area-phys 0x40000000 -work-area-size 0x4000 -work-area-backup 0 - -#flash bank -set _FLASHNAME $_CHIPNAME.flash0 -flash bank $_FLASHNAME str7x 0x20000000 0x00040000 0 0 $_TARGETNAME STR75x -set _FLASHNAME $_CHIPNAME.flash1 -flash bank $_FLASHNAME str7x 0x200C0000 0x00004000 0 0 $_TARGETNAME STR75x - -# Serial NOR on SMI CS0. -set _FLASHNAME $_CHIPNAME.snor -flash bank $_FLASHNAME stmsmi 0x80000000 0 0 0 $_TARGETNAME - -source [find mem_helper.tcl] - -proc init_smi {} { - mmw 0x60000030 0x01000000 0x00000000; # enable clock for GPIO regs - mmw 0xffffe420 0x00000001 0x00000000; # set SMI_EN bit - mmw 0x90000000 0x00000001 0x00000000; # set BLOCK_EN_1 -} diff --git a/tcl/target/str912.cfg b/tcl/target/str912.cfg deleted file mode 100644 index 36c0b2a54..000000000 --- a/tcl/target/str912.cfg +++ /dev/null @@ -1,71 +0,0 @@ -# script for str9 - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME str912 -} - -if { [info exists ENDIAN] } { - set _ENDIAN $ENDIAN -} else { - set _ENDIAN little -} - -# jtag speed. We need to stick to 16kHz until we've finished reset. -adapter_khz 16 - -adapter_nsrst_delay 100 -jtag_ntrst_delay 100 - -#use combined on interfaces or targets that can't set TRST/SRST separately -reset_config trst_and_srst - -if { [info exists FLASHTAPID] } { - set _FLASHTAPID $FLASHTAPID -} else { - set _FLASHTAPID 0x04570041 -} -jtag newtap $_CHIPNAME flash -irlen 8 -ircapture 0x1 -irmask 0x1 -expected-id $_FLASHTAPID - -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - set _CPUTAPID 0x25966041 -} -jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID - - -if { [info exists BSTAPID] } { - set _BSTAPID $BSTAPID -} else { - # possible values: 0x1457f041, 0x2457f041 - # we ignore version in check below - set _BSTAPID 0x1457f041 -} -jtag newtap $_CHIPNAME bs -irlen 5 -ircapture 0x1 -irmask 0x1 -expected-id $_BSTAPID -ignore-version - -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME arm966e -endian $_ENDIAN -chain-position $_TARGETNAME - -$_TARGETNAME configure -event reset-start { adapter_khz 16 } - -$_TARGETNAME configure -event reset-init { - # We can increase speed now that we know the target is halted. - #adapter_khz 3000 - - # -- Enable 96K RAM - # PFQBC enabled / DTCM & AHB wait-states disabled - mww 0x5C002034 0x0191 - - str9x flash_config 0 4 2 0 0x80000 - flash protect 0 0 7 off -} - -$_TARGETNAME configure -work-area-phys 0x50000000 -work-area-size 16384 -work-area-backup 0 - -#flash bank str9x 0 0 -set _FLASHNAME $_CHIPNAME.flash0 -flash bank $_FLASHNAME str9x 0x00000000 0x00080000 0 0 $_TARGETNAME -set _FLASHNAME $_CHIPNAME.flash1 -flash bank $_FLASHNAME str9x 0x00080000 0x00008000 0 0 $_TARGETNAME diff --git a/tcl/target/swj-dp.tcl b/tcl/target/swj-dp.tcl deleted file mode 100644 index 1d274cb12..000000000 --- a/tcl/target/swj-dp.tcl +++ /dev/null @@ -1,34 +0,0 @@ -# ARM Debug Interface V5 (ADI_V5) utility -# ... Mostly for SWJ-DP (not SW-DP or JTAG-DP, since -# SW-DP and JTAG-DP targets don't need to switch based -# on which transport is active. -# -# declare a JTAG or SWD Debug Access Point (DAP) -# based on the transport in use with this session. -# You can't access JTAG ops when SWD is active, etc. - -# params are currently what "jtag newtap" uses -# because OpenOCD internals are still strongly biased -# to JTAG .... but for SWD, "irlen" etc are ignored, -# and the internals work differently - -# for now, ignore non-JTAG and non-SWD transports -# (e.g. initial flash programming via SPI or UART) - -# split out "chip" and "tag" so we can someday handle -# them more uniformly irlen too...) - -if [catch {transport select}] { - echo "Error: unable to select a session transport. Can't continue." - shutdown -} - -proc swj_newdap {chip tag args} { - if [using_hla] { - eval hla newtap $chip $tag $args - } elseif [using_jtag] { - eval jtag newtap $chip $tag $args - } elseif [using_swd] { - eval swd newdap $chip $tag $args - } -} diff --git a/tcl/target/test_reset_syntax_error.cfg b/tcl/target/test_reset_syntax_error.cfg deleted file mode 100644 index cb4e46fa4..000000000 --- a/tcl/target/test_reset_syntax_error.cfg +++ /dev/null @@ -1,17 +0,0 @@ -# Test script to check that syntax error in reset -# script is reported properly. - -# at91eb40a target - -#jtag scan chain -set _CHIPNAME syntaxtest -jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf - -#target configuration -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME arm7tdmi -endian $_ENDIAN -chain-position $_TARGETNAME - -$_TARGETNAME configure -event reset-init { - - syntax error -} diff --git a/tcl/target/test_syntax_error.cfg b/tcl/target/test_syntax_error.cfg deleted file mode 100644 index d4f92fab7..000000000 --- a/tcl/target/test_syntax_error.cfg +++ /dev/null @@ -1,4 +0,0 @@ -# This script tests a syntax error in the startup -# config script - -syntax error here diff --git a/tcl/target/ti-ar7.cfg b/tcl/target/ti-ar7.cfg deleted file mode 100644 index 19d8c6f34..000000000 --- a/tcl/target/ti-ar7.cfg +++ /dev/null @@ -1,30 +0,0 @@ -# -# Texas Instruments AR7 SOC - used in many adsl modems. -# http://www.linux-mips.org/wiki/AR7 -# - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME ti-ar7 -} - -if { [info exists ENDIAN] } { - set _ENDIAN $ENDIAN -} else { - set _ENDIAN little -} - -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - set _CPUTAPID 0x0000100f -} - -jtag newtap $_CHIPNAME cpu -irlen 5 -expected-id $_CPUTAPID - -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME mips_m4k -endian $_ENDIAN -chain-position $_CHIPNAME.cpu - -# use onboard 4k sram as working area -$_TARGETNAME configure -work-area-phys 0x80000000 -work-area-size 0x00001000 diff --git a/tcl/target/ti-cjtag.cfg b/tcl/target/ti-cjtag.cfg deleted file mode 100755 index 7114b2adf..000000000 --- a/tcl/target/ti-cjtag.cfg +++ /dev/null @@ -1,32 +0,0 @@ -# A start sequence to change from cJTAG to 4-pin JTAG -# This is needed for CC2538 and CC26xx to be able to communicate through JTAG -# Read section 6.3 in http://www.ti.com/lit/pdf/swru319 for more information. -proc ti_cjtag_to_4pin_jtag {jrc} { - # Bypass - irscan $jrc 0x3f -endstate RUN/IDLE - # Two zero bit scans and a one bit drshift - pathmove RUN/IDLE DRSELECT DRCAPTURE DREXIT1 DRPAUSE - pathmove DRPAUSE DREXIT2 DRUPDATE RUN/IDLE - pathmove RUN/IDLE DRSELECT DRCAPTURE DREXIT1 DRPAUSE - pathmove DRPAUSE DREXIT2 DRUPDATE RUN/IDLE - pathmove RUN/IDLE DRSELECT DRCAPTURE DREXIT1 DRPAUSE - pathmove DRPAUSE DREXIT2 DRSHIFT DREXIT1 DRUPDATE RUN/IDLE - pathmove RUN/IDLE DRSELECT DRCAPTURE DREXIT1 DRPAUSE - - # A two bit drhift and a 9 bit drshift - pathmove DRPAUSE DREXIT2 DRSHIFT DRSHIFT DREXIT1 DRUPDATE RUN/IDLE - pathmove RUN/IDLE DRSELECT DRCAPTURE DREXIT1 DRPAUSE - pathmove DRPAUSE DREXIT2 DRSHIFT DRSHIFT DREXIT1 DRPAUSE - pathmove DRPAUSE DREXIT2 DRSHIFT DRSHIFT DREXIT1 DRPAUSE - pathmove DRPAUSE DREXIT2 DRSHIFT DRSHIFT DREXIT1 DRPAUSE - pathmove DRPAUSE DREXIT2 DRSHIFT DRSHIFT DREXIT1 DRPAUSE - pathmove DRPAUSE DREXIT2 DRSHIFT DREXIT1 DRPAUSE - pathmove DRPAUSE DREXIT2 DRUPDATE RUN/IDLE - pathmove RUN/IDLE DRSELECT DRCAPTURE DREXIT1 DRPAUSE - - # Bypass - irscan $jrc 0x3f -endstate RUN/IDLE - - # Set ICEPick IDCODE in data register - irscan $jrc 0x04 -endstate RUN/IDLE -} diff --git a/tcl/target/ti_calypso.cfg b/tcl/target/ti_calypso.cfg deleted file mode 100644 index 9d3b293ee..000000000 --- a/tcl/target/ti_calypso.cfg +++ /dev/null @@ -1,57 +0,0 @@ -# -# TI Calypso (lite) G2 C035 Digital Base Band chip -# -# ARM7TDMIE + DSP subchip (S28C128) -# -# 512K SRAM Calypso -# 256K SRAM Calypso lite -# -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME calypso -} - -if { [info exists ENDIAN] } { - set _ENDIAN $ENDIAN -} else { - set _ENDIAN little -} - -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - set _CPUTAPID 0x3100e02f -} - -# Work-area is a space in RAM used for flash programming -# By default use 64kB -if { [info exists WORKAREASIZE] } { - set _WORKAREASIZE $WORKAREASIZE -} else { - set _WORKAREASIZE 0x10000 -} - -adapter_khz 1000 - -reset_config trst_and_srst - -jtag newtap $_CHIPNAME dsp -expected-id 0x00000000 -irlen 8 -jtag newtap $_CHIPNAME arm -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID - -# target - -set _TARGETNAME $_CHIPNAME.arm -target create $_TARGETNAME arm7tdmi -endian little -chain-position $_TARGETNAME - -# workarea - -$_TARGETNAME configure -work-area-phys 0x00800000 -work-area-size $_WORKAREASIZE -work-area-backup 1 - -arm7_9 dcc_downloads enable -arm7_9 fast_memory_access enable - -$_TARGETNAME configure -event examine-start { - irscan calypso.arm 0x0b -endstate DRPAUSE - drscan calypso.arm 2 2 -endstate RUN/IDLE -} diff --git a/tcl/target/ti_dm355.cfg b/tcl/target/ti_dm355.cfg deleted file mode 100644 index 4f8f523e8..000000000 --- a/tcl/target/ti_dm355.cfg +++ /dev/null @@ -1,109 +0,0 @@ -# -# Texas Instruments DaVinci family: TMS320DM355 -# -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME dm355 -} - -# TI boards default to EMU0/EMU1 *high* -- ARM and ETB are *disabled* -# after JTAG reset until ICEpick is used to route them in. -set EMU01 "-disable" - -# With EMU0/EMU1 jumpered *low* ARM and ETB are *enabled* without -# needing any ICEpick interaction. -#set EMU01 "-enable" - -source [find target/icepick.cfg] - -# -# Also note: when running without RTCK before the PLLs are set up, you -# may need to slow the JTAG clock down quite a lot (under 2 MHz). -# - -# Subsidiary TAP: ARM ETB11, with scan chain for 4K of ETM trace buffer -if { [info exists ETB_TAPID] } { - set _ETB_TAPID $ETB_TAPID -} else { - set _ETB_TAPID 0x2b900f0f -} -jtag newtap $_CHIPNAME etb -irlen 4 -irmask 0xf -expected-id $_ETB_TAPID $EMU01 -jtag configure $_CHIPNAME.etb -event tap-enable \ - "icepick_c_tapenable $_CHIPNAME.jrc 1" - -# Subsidiary TAP: ARM926ejs with scan chains for ARM Debug, EmbeddedICE-RT, ETM. -if { [info exists CPU_TAPID] } { - set _CPU_TAPID $CPU_TAPID -} else { - set _CPU_TAPID 0x07926001 -} -jtag newtap $_CHIPNAME arm -irlen 4 -irmask 0xf -expected-id $_CPU_TAPID $EMU01 -jtag configure $_CHIPNAME.arm -event tap-enable \ - "icepick_c_tapenable $_CHIPNAME.jrc 0" - -# Primary TAP: ICEpick (JTAG route controller) and boundary scan -if { [info exists JRC_TAPID] } { - set _JRC_TAPID $JRC_TAPID -} else { - set _JRC_TAPID 0x0b73b02f -} -jtag newtap $_CHIPNAME jrc -irlen 6 -irmask 0x3f -expected-id $_JRC_TAPID - -jtag configure $_CHIPNAME.jrc -event setup \ - "jtag tapenable $_CHIPNAME.etb; jtag tapenable $_CHIPNAME.arm" - -################ - -# various symbol definitions, to avoid hard-wiring addresses -# and enable some sharing of DaVinci-family utility code -global dm355 -set dm355 [ dict create ] - -# Physical addresses for controllers and memory -# (Some of these are valid for many DaVinci family chips) -dict set dm355 sram0 0x00010000 -dict set dm355 sram1 0x00014000 -dict set dm355 sysbase 0x01c40000 -dict set dm355 pllc1 0x01c40800 -dict set dm355 pllc2 0x01c40c00 -dict set dm355 psc 0x01c41000 -dict set dm355 gpio 0x01c67000 -dict set dm355 a_emif 0x01e10000 -dict set dm355 a_emif_cs0 0x02000000 -dict set dm355 a_emif_cs1 0x04000000 -dict set dm355 ddr_emif 0x20000000 -dict set dm355 ddr 0x80000000 -dict set dm355 uart0 0x01c20000 -dict set dm355 uart1 0x01c20400 -dict set dm355 uart2 0x01e06000 - -source [find target/davinci.cfg] - -################ -# GDB target: the ARM, using SRAM1 for scratch. SRAM0 (also 16K) -# and the ETB memory (4K) are other options, while trace is unused. -set _TARGETNAME $_CHIPNAME.arm - -target create $_TARGETNAME arm926ejs -chain-position $_TARGETNAME - -# NOTE that work-area-virt presumes a Linux 2.6.30-rc2+ kernel, -# and that the work area is used only with a kernel mmu context ... -$_TARGETNAME configure \ - -work-area-virt [expr 0xfffe0000 + 0x4000] \ - -work-area-phys [dict get $dm355 sram1] \ - -work-area-size 0x4000 \ - -work-area-backup 0 - -# be absolutely certain the JTAG clock will work with the worst-case -# CLKIN = 24 MHz (best case: 36 MHz) even when no bootloader turns -# on the PLL and starts using it. OK to speed up after clock setup. -adapter_khz 1500 -$_TARGETNAME configure -event "reset-start" { adapter_khz 1500 } - -arm7_9 fast_memory_access enable -arm7_9 dcc_downloads enable - -# trace setup -etm config $_TARGETNAME 16 normal full etb -etb config $_TARGETNAME $_CHIPNAME.etb diff --git a/tcl/target/ti_dm365.cfg b/tcl/target/ti_dm365.cfg deleted file mode 100644 index 0db83dbaa..000000000 --- a/tcl/target/ti_dm365.cfg +++ /dev/null @@ -1,101 +0,0 @@ -# -# Texas Instruments DaVinci family: TMS320DM365 -# -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME dm365 -} - -# TI boards default to EMU0/EMU1 *high* -- ARM and ETB are *disabled* -# after JTAG reset until ICEpick is used to route them in. -set EMU01 "-disable" - -# With EMU0/EMU1 jumpered *low* ARM and ETB are *enabled* without -# needing any ICEpick interaction. -#set EMU01 "-enable" - -source [find target/icepick.cfg] - -# Subsidiary TAP: ARM ETB11, with scan chain for 4K of ETM trace buffer -if { [info exists ETB_TAPID] } { - set _ETB_TAPID $ETB_TAPID -} else { - set _ETB_TAPID 0x2b900f0f -} -jtag newtap $_CHIPNAME etb -irlen 4 -irmask 0xf -expected-id $_ETB_TAPID $EMU01 -jtag configure $_CHIPNAME.etb -event tap-enable \ - "icepick_c_tapenable $_CHIPNAME.jrc 1" - -# Subsidiary TAP: ARM926ejs with scan chains for ARM Debug, EmbeddedICE-RT, ETM. -if { [info exists CPU_TAPID] } { - set _CPU_TAPID $CPU_TAPID -} else { - set _CPU_TAPID 0x0792602f -} -jtag newtap $_CHIPNAME arm -irlen 4 -irmask 0xf -expected-id $_CPU_TAPID $EMU01 -jtag configure $_CHIPNAME.arm -event tap-enable \ - "icepick_c_tapenable $_CHIPNAME.jrc 0" - -# Primary TAP: ICEpick (JTAG route controller) and boundary scan -if { [info exists JRC_TAPID] } { - set _JRC_TAPID $JRC_TAPID -} else { - set _JRC_TAPID 0x0b83e02f -} -jtag newtap $_CHIPNAME jrc -irlen 6 -irmask 0x3f -expected-id $_JRC_TAPID - -jtag configure $_CHIPNAME.jrc -event setup \ - "jtag tapenable $_CHIPNAME.etb; jtag tapenable $_CHIPNAME.arm" - -################ - -# various symbol definitions, to avoid hard-wiring addresses -# and enable some sharing of DaVinci-family utility code -global dm365 -set dm365 [ dict create ] - -# Physical addresses for controllers and memory -# (Some of these are valid for many DaVinci family chips) -dict set dm365 sram0 0x00010000 -dict set dm365 sram1 0x00014000 -dict set dm365 sysbase 0x01c40000 -dict set dm365 pllc1 0x01c40800 -dict set dm365 pllc2 0x01c40c00 -dict set dm365 psc 0x01c41000 -dict set dm365 gpio 0x01c67000 -dict set dm365 a_emif 0x01d10000 -dict set dm365 a_emif_cs0 0x02000000 -dict set dm365 a_emif_cs1 0x04000000 -dict set dm365 ddr_emif 0x20000000 -dict set dm365 ddr 0x80000000 - -source [find target/davinci.cfg] - -################ -# GDB target: the ARM, using SRAM1 for scratch. SRAM0 (also 16K) -# and the ETB memory (4K) are other options, while trace is unused. -set _TARGETNAME $_CHIPNAME.arm - -target create $_TARGETNAME arm926ejs -chain-position $_TARGETNAME - -# NOTE that work-area-virt presumes a Linux 2.6.30-rc2+ kernel, -# and that the work area is used only with a kernel mmu context ... -$_TARGETNAME configure \ - -work-area-virt [expr 0xfffe0000 + 0x4000] \ - -work-area-phys [dict get $dm365 sram1] \ - -work-area-size 0x4000 \ - -work-area-backup 0 - -# be absolutely certain the JTAG clock will work with the worst-case -# CLKIN = 19.2 MHz (best case: 36 MHz) even when no bootloader turns -# on the PLL and starts using it. OK to speed up after clock setup. -adapter_khz 1500 -$_TARGETNAME configure -event "reset-start" { adapter_khz 1500 } - -arm7_9 fast_memory_access enable -arm7_9 dcc_downloads enable - -# trace setup -etm config $_TARGETNAME 16 normal full etb -etb config $_TARGETNAME $_CHIPNAME.etb diff --git a/tcl/target/ti_dm6446.cfg b/tcl/target/ti_dm6446.cfg deleted file mode 100644 index fa1e6e957..000000000 --- a/tcl/target/ti_dm6446.cfg +++ /dev/null @@ -1,81 +0,0 @@ -# -# Texas Instruments DaVinci family: TMS320DM6446 -# -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME dm6446 -} - -# TI boards default to EMU0/EMU1 *high* -- ARM and ETB are *disabled* -# after JTAG reset until ICEpick is used to route them in. -set EMU01 "-disable" - -# With EMU0/EMU1 jumpered *low* ARM and ETB are *enabled* without -# needing any ICEpick interaction. -#set EMU01 "-enable" - -source [find target/icepick.cfg] - -# Subsidiary TAP: unknown ... must enable via ICEpick -jtag newtap $_CHIPNAME unknown -irlen 8 -disable -jtag configure $_CHIPNAME.unknown -event tap-enable \ - "icepick_c_tapenable $_CHIPNAME.jrc 3" - -# Subsidiary TAP: C64x+ DSP ... must enable via ICEpick -jtag newtap $_CHIPNAME dsp -irlen 38 -ircapture 0x25 -irmask 0x3f -disable -jtag configure $_CHIPNAME.dsp -event tap-enable \ - "icepick_c_tapenable $_CHIPNAME.jrc 2" - -# Subsidiary TAP: ARM ETB11, with scan chain for 4K of ETM trace buffer -if { [info exists ETB_TAPID] } { - set _ETB_TAPID $ETB_TAPID -} else { - set _ETB_TAPID 0x2b900f0f -} -jtag newtap $_CHIPNAME etb -irlen 4 -irmask 0xf -expected-id $_ETB_TAPID $EMU01 -jtag configure $_CHIPNAME.etb -event tap-enable \ - "icepick_c_tapenable $_CHIPNAME.jrc 1" - -# Subsidiary TAP: ARM926ejs with scan chains for ARM Debug, EmbeddedICE-RT, ETM. -if { [info exists CPU_TAPID] } { - set _CPU_TAPID $CPU_TAPID -} else { - set _CPU_TAPID 0x07926001 -} -jtag newtap $_CHIPNAME arm -irlen 4 -irmask 0xf -expected-id $_CPU_TAPID $EMU01 -jtag configure $_CHIPNAME.arm -event tap-enable \ - "icepick_c_tapenable $_CHIPNAME.jrc 0" - -# Primary TAP: ICEpick-C (JTAG route controller) and boundary scan -if { [info exists JRC_TAPID] } { - set _JRC_TAPID $JRC_TAPID -} else { - set _JRC_TAPID 0x0b70002f -} -jtag newtap $_CHIPNAME jrc -irlen 6 -irmask 0x3f -expected-id $_JRC_TAPID - -jtag configure $_CHIPNAME.jrc -event setup \ - "jtag tapenable $_CHIPNAME.etb; jtag tapenable $_CHIPNAME.arm" - -################ -# GDB target: the ARM, using SRAM1 for scratch. SRAM0 (also 8K) -# and the ETB memory (4K) are other options, while trace is unused. -# Little-endian; use the OpenOCD default. -set _TARGETNAME $_CHIPNAME.arm - -target create $_TARGETNAME arm926ejs -chain-position $_TARGETNAME -$_TARGETNAME configure -work-area-phys 0x0000a000 -work-area-size 0x2000 - -# be absolutely certain the JTAG clock will work with the worst-case -# CLKIN = 20 MHz (best case: 30 MHz) even when no bootloader turns -# on the PLL and starts using it. OK to speed up after clock setup. -adapter_khz 1500 -$_TARGETNAME configure -event "reset-start" { adapter_khz 1500 } - -arm7_9 fast_memory_access enable -arm7_9 dcc_downloads enable - -# trace setup -etm config $_TARGETNAME 16 normal full etb -etb config $_TARGETNAME $_CHIPNAME.etb diff --git a/tcl/target/ti_msp432p4xx.cfg b/tcl/target/ti_msp432p4xx.cfg deleted file mode 100644 index 860086707..000000000 --- a/tcl/target/ti_msp432p4xx.cfg +++ /dev/null @@ -1,52 +0,0 @@ -# -# Texas Instruments MSP432P4xx - ARM Cortex-M4F @ up to 48 MHz -# -# http://www.ti.com/MSP432 -# - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME msp432p4xx -} - -if { [info exists CPUTAPID] } { - set _DAP_TAPID $CPUTAPID -} else { - set _DAP_TAPID 0x4ba00477 -} - -if { [info exists DAP_SWD_ID] } { - set _DAP_SWD_ID $DAP_SWD_ID -} else { - set _DAP_SWD_ID 0x2ba01477 -} - -source [find target/swj-dp.tcl] - -if { [using_jtag] } { - set _DAP_ID $_DAP_TAPID -} else { - set _DAP_ID $_DAP_SWD_ID -} - -swj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_DAP_ID - -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME cortex_m -chain-position $_TARGETNAME - -if { [info exists WORKAREASIZE] } { - set _WORKAREASIZE $WORKAREASIZE -} else { - # On MSP432P401x Bank0 (8k) is always powered - set _WORKAREASIZE 0x2000 -} - -$_TARGETNAME configure -work-area-phys 0x20000000 \ - -work-area-size $_WORKAREASIZE -work-area-backup 0 - -if { ![using_hla] } { - cortex_m reset_config sysresetreq -} - -adapter_khz 500 diff --git a/tcl/target/ti_rm4x.cfg b/tcl/target/ti_rm4x.cfg deleted file mode 100644 index 85c3e814b..000000000 --- a/tcl/target/ti_rm4x.cfg +++ /dev/null @@ -1 +0,0 @@ -source [find target/ti_tms570.cfg] diff --git a/tcl/target/ti_tms570.cfg b/tcl/target/ti_tms570.cfg deleted file mode 100644 index 21da6c017..000000000 --- a/tcl/target/ti_tms570.cfg +++ /dev/null @@ -1,74 +0,0 @@ -adapter_khz 1500 - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME tms570 -} - -if { [info exists ENDIAN] } { - set _ENDIAN $ENDIAN -} else { - set _ENDIAN big -} - -# TMS570 has an ICEpick-C on which we need the router commands. -source [find target/icepick.cfg] - -# Main DAP -# DAP_TAPID should be set before source-ing this file -if { [info exists DAP_TAPID] } { - set _DAP_TAPID $DAP_TAPID -} -jtag newtap $_CHIPNAME dap -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_DAP_TAPID -disable -jtag configure $_CHIPNAME.dap -event tap-enable "icepick_c_tapenable $_CHIPNAME.jrc 0" - -# ICEpick-C (JTAG route controller) -# JRC_TAPID should be set before source-ing this file -if { [info exists JRC_TAPID] } { - set _JRC_TAPID $JRC_TAPID -} - -set _JRC_TAPID2 0x0B7B302F -set _JRC_TAPID3 0x0B95502F -set _JRC_TAPID4 0x0B97102F -set _JRC_TAPID5 0x0D8A002F -set _JRC_TAPID6 0x2B8A002F -set _JRC_TAPID7 0x2D8A002F -set _JRC_TAPID8 0x3B8A002F -set _JRC_TAPID9 0x3D8A002F - - -jtag newtap $_CHIPNAME jrc -irlen 6 -ircapture 0x1 -irmask 0x3f \ - -expected-id $_JRC_TAPID \ - -expected-id $_JRC_TAPID2 \ - -expected-id $_JRC_TAPID3 \ - -expected-id $_JRC_TAPID4 \ - -expected-id $_JRC_TAPID5 \ - -expected-id $_JRC_TAPID6 \ - -expected-id $_JRC_TAPID7 \ - -expected-id $_JRC_TAPID8 \ - -expected-id $_JRC_TAPID9 \ - -ignore-version -jtag configure $_CHIPNAME.jrc -event setup "jtag tapenable $_CHIPNAME.dap" -jtag configure $_CHIPNAME.jrc -event post-reset "runtest 100" - -# Cortex-R4 target -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME cortex_r4 -endian $_ENDIAN \ - -chain-position $_CHIPNAME.dap -coreid 0 -dbgbase 0x00001003 - -# TMS570 uses quirky BE-32 mode -$_TARGETNAME dap ti_be_32_quirks 1 - -$_TARGETNAME configure -event gdb-attach { - cortex_r4 dbginit - halt -} - -$_TARGETNAME configure -event "reset-assert" { - global _CHIPNAME - - # assert warm system reset through ICEPick - icepick_c_wreset $_CHIPNAME.jrc -} diff --git a/tcl/target/ti_tms570ls20xxx.cfg b/tcl/target/ti_tms570ls20xxx.cfg deleted file mode 100644 index ef45b7a5c..000000000 --- a/tcl/target/ti_tms570ls20xxx.cfg +++ /dev/null @@ -1,6 +0,0 @@ -# TMS570LS20216, TMS570LS20206, TMS570LS10216 -# TMS570LS10206, TMS570LS10116, TMS570LS10106 -set DAP_TAPID 0x0B7B302F -set JRC_TAPID 0x0B7B302F - -source [find target/ti_tms570.cfg] diff --git a/tcl/target/ti_tms570ls3137.cfg b/tcl/target/ti_tms570ls3137.cfg deleted file mode 100644 index f29180356..000000000 --- a/tcl/target/ti_tms570ls3137.cfg +++ /dev/null @@ -1,5 +0,0 @@ -# TMS570LS3137 -set DAP_TAPID 0x0B8A002F -set JRC_TAPID 0x0B8A002F - -source [find target/ti_tms570.cfg] diff --git a/tcl/target/tmpa900.cfg b/tcl/target/tmpa900.cfg deleted file mode 100644 index 3ba3591be..000000000 --- a/tcl/target/tmpa900.cfg +++ /dev/null @@ -1,46 +0,0 @@ -###################################### -# Target: Toshiba TMPA900 -###################################### - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME tmpa900 -} - -# Toshiba TMPA900 series MCUs are always little endian as per datasheet. -set _ENDIAN little - -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - set _CPUTAPID 0x07926031 -} - -#TMPA900 has following IDs: -# CP15.0 register 0x41069265 -# CP15.1 register 0x1d152152 -# ARM core 0x07926031 - - -# -jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID - -#use combined on interfaces or targets that can't set TRST/SRST separately -reset_config trst_and_srst -adapter_nsrst_delay 20 -jtag_ntrst_delay 20 - -###################### -# Target configuration -###################### - -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME arm926ejs -endian $_ENDIAN -chain-position $_TARGETNAME - -# Internal RAM-0 (16kB): 0xf8004000 -# Internal RAM-1 (8kB): 0xf8008000 - -# Use internal RAM-0 and RAM-1 as working area (24kB total). -$_TARGETNAME configure -work-area-phys 0xf8004000 -work-area-size 0x6000 \ --work-area-backup 0 diff --git a/tcl/target/tmpa910.cfg b/tcl/target/tmpa910.cfg deleted file mode 100644 index 5d41c8c2a..000000000 --- a/tcl/target/tmpa910.cfg +++ /dev/null @@ -1,47 +0,0 @@ -###################################### -# Target: Toshiba TMPA910 -###################################### - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME tmpa910 -} - -# Toshiba TMPA910 series MCUs are always little endian as per datasheet. -set _ENDIAN little - -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - set _CPUTAPID 0x07926031 -} - -#TMPA910 has following IDs: -# CP15.0 register 0x41069265 -# CP15.1 register 0x1d152152 -# ARM core 0x07926031 - - -# -jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID - -#use combined on interfaces or targets that can't set TRST/SRST separately -reset_config trst_and_srst -adapter_nsrst_delay 20 -jtag_ntrst_delay 20 - -###################### -# Target configuration -###################### - -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME arm926ejs -endian $_ENDIAN -chain-position $_TARGETNAME - -# Internal RAM-0 (16kB): 0xf8004000 -# Internal RAM-1 (16kB): 0xf8008000 -# Internal RAM-2 (16kB): 0xf800c000 - -# Use internal RAM-0, RAM-1, and RAM-2 as working area (48kB total). -$_TARGETNAME configure -work-area-phys 0xf8004000 -work-area-size 0xc000 \ --work-area-backup 0 diff --git a/tcl/target/u8500.cfg b/tcl/target/u8500.cfg deleted file mode 100644 index 66fc075c2..000000000 --- a/tcl/target/u8500.cfg +++ /dev/null @@ -1,332 +0,0 @@ -# Copyright (C) ST-Ericsson SA 2011 -# Author : michel.jaouen@stericsson.com -# U8500 target - -proc mmu_off {} { - set cp [arm mrc 15 0 1 0 0] - set cp [expr ($cp & ~1)] - arm mcr 15 0 1 0 0 $cp -} - -proc mmu_on {} { - set cp [arm mrc 15 0 1 0 0] - set cp [expr ($cp | 1)] - arm mcr 15 0 1 0 0 $cp -} - -proc ocd_gdb_restart {target_id} { - global _TARGETNAME_1 - global _SMP - targets $_TARGETNAME_1 - if { [expr ($_SMP == 1)] } { - cortex_a smp_off - } - rst_run - halt - if { [expr ($_SMP == 1)]} { - cortex_a smp_on - } -} - -proc smp_reg {} { - global _TARGETNAME_1 - global _TARGETNAME_2 - targets $_TARGETNAME_1 - echo "$_TARGETNAME_1" - set pc1 [reg pc] - set stck1 [reg sp_svc] - targets $_TARGETNAME_2 - echo "$_TARGETNAME_1" - set pc2 [reg pc] - set stck2 [reg sp_svc] -} - - -proc u8500_tapenable {chip val} { - echo "JTAG tap enable $chip" -} - - -proc pwrsts { } { - global _CHIPNAME - irscan $_CHIPNAME.jrc 0x3a - drscan $_CHIPNAME.jrc 4 0 - set pwrsts [drscan $_CHIPNAME.jrc 16 0] - echo "pwrsts ="$pwrsts - set a9 [expr (0x$pwrsts & 0xc)] - set ape [expr (0x$pwrsts & 0x3)] - if {[string equal "0" $ape]} { - echo "ape off" - } else { - echo "ape on" - } - echo "$a9" - switch $a9 { - 4 { - echo "A9 in retention" - } - 8 { - echo "A9 100% DVFS" - } - c { - echo "A9 50% DVFS" - } - } -} - -proc poll_pwrsts { } { - global _CHIPNAME - set result 1 - set i 0 - irscan $_CHIPNAME.jrc 0x3a - drscan $_CHIPNAME.jrc 4 0 - set pwrsts [drscan $_CHIPNAME.jrc 16 0] - set pwrsts [expr (0x$pwrsts & 0xc)] - while {[string equal "4" $pwrsts] && $i<20} { - irscan $_CHIPNAME.jrc 0x3a - drscan $_CHIPNAME.jrc 4 0; - set pwrsts [drscan $_CHIPNAME.jrc 16 0] - set pwrsts [expr (0x$pwrsts & 0xc)] - if {![string equal "4" $pwrsts]} { - set result 1 - } else { - set result 0 - sleep 200 - echo "loop $i" - } - incr i - } - return $result -} - -proc halt_ { } { - if {[poll_pwrsts]==1} { - halt - } else { - echo "halt failed : target in retention" - } -} - - -proc u8500_dapenable {chip} { -} - -proc u8500_tapdisable {chip val} { - echo "JTAG tap disable $chip" -} - - -proc enable_apetap {} { - global _CHIPNAME - global _TARGETNAME_2 - global _TARGETNAME_1 - poll off - irscan $_CHIPNAME.jrc 0x3e - drscan $_CHIPNAME.jrc 8 0xcf - jtag tapenable $_CHIPNAME.dap - irscan $_CHIPNAME.jrc 0x6 - drscan $_CHIPNAME.jrc 32 0 - irscan $_CHIPNAME.jrc 0x6 - drscan $_CHIPNAME.jrc 32 0 - set status [$_TARGETNAME_1 curstate] - if {[string equal "unknown" $status]} { - $_TARGETNAME_1 arp_examine - cache_config l2x 0xa0412000 8 - } - - set status [$_TARGETNAME_2 curstate] - if {[string equal "unknown" $status]} { - $_TARGETNAME_2 arp_examine - } - } - -tcl_port 5555 -telnet_port 4444 -gdb_port 3333 - -if { [info exists CHIPNAME] } { -global _CHIPNAME - set _CHIPNAME $CHIPNAME -} else { -global _CHIPNAME - set _CHIPNAME u8500 -} - -if { [info exists ENDIAN] } { - set _ENDIAN $ENDIAN -} else { - # this defaults to a bigendian - set _ENDIAN little -} - - - -# Subsidiary TAP: APE with scan chains for ARM Debug, EmbeddedICE-RT, -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - set _CPUTAPID 0x4ba00477 -} -jtag newtap $_CHIPNAME dap -irlen 4 -ircapture 0xe -irmask 0xf -expected-id $_CPUTAPID -disable -jtag configure $_CHIPNAME.dap -event tap-enable \ - "u8500_dapenable $_CHIPNAME.dap" -jtag configure $_CHIPNAME.dap -event tap-disable \ - "u8500_tapdisable $_CHIPNAME.dap 0xc0" - - -#CLTAPC TAP JRC equivalent -if { [info exists CLTAPC_ID] } { - set _CLTAPC_ID $CLTAPC_ID -} else { - set _CLTAPC_ID 0x22286041 -} -jtag newtap $_CHIPNAME jrc -irlen 6 -ircapture 0x6 -irmask 0xf -expected-id $_CLTAPC_ID -ignore-version - - -if { ![info exists TARGETNAME_1] } { -global _TARGETNAME_1 -set _TARGETNAME_1 $_CHIPNAME.cpu1 -} else { -global _TARGETNAME_1 -set _TARGETNAME_1 $TARGETNAME_1 -} - -if { [info exists DAP_DBG1] } { - set _DAP_DBG1 $DAP_DBG1 -} else { - set _DAP_DBG1 0x801A8000 -} -if { [info exists DAP_DBG2] } { - set _DAP_DBG2 $DAP_DBG2 -} else { - set _DAP_DBG2 0x801AA000 -} - -target create $_TARGETNAME_1 cortex_a -chain-position $_CHIPNAME.dap -dbgbase $_DAP_DBG1 -coreid 0 -rtos linux - -$_TARGETNAME_1 configure -event gdb-attach { - halt -} - - -if { ![info exists TARGETNAME_2] } { -global _TARGETNAME_2 -set _TARGETNAME_2 $_CHIPNAME.cpu2 -} else { -global _TARGETNAME_2 -set _TARGETNAME_2 $TARGETNAME_2 -} - -target create $_TARGETNAME_2 cortex_a -chain-position $_CHIPNAME.dap -dbgbase $_DAP_DBG2 -coreid 1 -rtos linux - -$_TARGETNAME_2 configure -event gdb-attach { - halt -} - - -if {![info exists SMP]} { -global _SMP -set _SMP 1 -} else { -global _SMP -set _SMP $SMP -} -global SMP -if { $_SMP == 1} { -target smp $_CHIPNAME.cpu2 $_CHIPNAME.cpu1 -} - - - - -proc secsts1 { } { - global _CHIPNAME - irscan $_CHIPNAME.jrc 0x3a - drscan $_CHIPNAME.jrc 4 4 - set secsts1 [drscan $_CHIPNAME.jrc 16 0] - echo "secsts1 ="$secsts1 - set secsts1 [expr (0x$secsts1 & 0x4)] - if {![string equal "4" $secsts1]} { - echo "APE target secured" - } else { - echo "APE target not secured" - } -} - -proc att { } { - global _CHIPNAME - jtag arp_init - irscan $_CHIPNAME.jrc 0x3a - drscan $_CHIPNAME.jrc 4 4 - set secsts1 [drscan $_CHIPNAME.jrc 16 0] - echo "secsts1 ="$secsts1 - set secsts1 [expr (0x$secsts1 & 0x4)] - if {[string equal "4" $secsts1]} { - if {[poll_pwrsts]==1} { - enable_apetap - } else { - echo "target in retention" - } - } else { - echo "target secured" - } - -} - - - -proc rst_run { } { - global _CHIPNAME - global _TARGETNAME_2 - global _TARGETNAME_1 - set status [$_TARGETNAME_1 curstate] - if {[string equal "halted" $status]} { - resume - targets $_TARGETNAME_1 - } - set status [$_TARGETNAME_2 curstate] - if {[string equal "halted" $status]} { - resume - targets $_TARGETNAME_2 - } - poll off - jtag arp_init - reset - sleep 20 - irscan $_CHIPNAME.jrc 0x3a - drscan $_CHIPNAME.jrc 4 4 - set secsts1 [drscan $_CHIPNAME.jrc 16 0] - echo "secsts1 ="$secsts1 - set secsts1 [expr (0x$secsts1 & 0x4)] - while {![string equal "4" $secsts1]} { - irscan u8500.jrc 0x3a - drscan u8500.jrc 4 4 - set secsts1 [drscan $_CHIPNAME.jrc 16 0] - echo "secsts1 ="$secsts1 - set secsts1 [expr (0x$secsts1 & 0x4)] - } - echo "ape debugable" - enable_apetap - poll on - targets $_TARGETNAME_1 - dap apsel 1 -} - -if {![info exists MAXSPEED]} { -global _MAXSPEED -set _MAXSPEED 15000 -} else { -global _MAXSPEED -set _MAXSPEED $MAXSPEED -} -global _MAXSPEED -adapter_khz $_MAXSPEED - - -gdb_breakpoint_override hard -set mem inaccessible-by-default-off - -jtag_ntrst_delay 100 -reset_config trst_and_srst combined - - diff --git a/tcl/target/vybrid_vf6xx.cfg b/tcl/target/vybrid_vf6xx.cfg deleted file mode 100644 index 6ec4b35cd..000000000 --- a/tcl/target/vybrid_vf6xx.cfg +++ /dev/null @@ -1,36 +0,0 @@ -# -# Freescale Vybrid VF610 -# - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME vf610 -} - -if { [info exists A5_JTAG_TAPID] } { - set _A5_JTAG_TAPID $A5_JTAG_TAPID -} else { - set _A5_JTAG_TAPID 0x4BA00477 -} - -if { [info exists A5_SWD_TAPID] } { - set _A5_SWD_TAPID $A5_SWD_TAPID -} else { - set _A5_SWD_TAPID 0x3BA02477 -} - -if { [using_jtag] } { - set _A5_TAPID $_A5_JTAG_TAPID -} else { - set _A5_TAPID $_A5_SWD_TAPID -} - -source [find target/swj-dp.tcl] - -swj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_A5_TAPID - -set _TARGETNAME $_CHIPNAME.cpu -target create ${_TARGETNAME}0 cortex_a -chain-position $_CHIPNAME.cpu -dbgbase 0xc0088000 - -adapter_khz 1000 diff --git a/tcl/target/xmc1xxx.cfg b/tcl/target/xmc1xxx.cfg deleted file mode 100644 index d3123c437..000000000 --- a/tcl/target/xmc1xxx.cfg +++ /dev/null @@ -1,40 +0,0 @@ -# -# Infineon XMC1100/XMC1200/XMC1300 family (ARM Cortex-M0 @ 32 MHz) -# - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME xmc1000 -} - -# -# Only SWD and SPD supported -# -source [find target/swj-dp.tcl] - -if { [info exists CPUTAPID] } { - set _CPU_SWD_TAPID $CPUTAPID -} else { - set _CPU_SWD_TAPID 0x0BB11477 -} - -swj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_CPU_SWD_TAPID - -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME cortex_m -endian little -chain-position $_TARGETNAME - -if { [info exists WORKAREASIZE] } { - set _WORKAREASIZE $WORKAREASIZE -} else { - set _WORKAREASIZE 0x4000 -} - -$_TARGETNAME configure -work-area-phys 0x20000000 \ - -work-area-size $_WORKAREASIZE \ - -work-area-backup 0 - -set _FLASHNAME $_CHIPNAME.flash -flash bank $_FLASHNAME xmc1xxx 0x10000000 0 0 0 $_TARGETNAME - -adapter_khz 1000 diff --git a/tcl/target/xmc4xxx.cfg b/tcl/target/xmc4xxx.cfg deleted file mode 100644 index bc0077799..000000000 --- a/tcl/target/xmc4xxx.cfg +++ /dev/null @@ -1,59 +0,0 @@ -# -# Infineon XMC4100/XMC4200/XMC4400/XMC4500 family (ARM Cortex-M4 @ 80-120 MHz) -# - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME xmc4000 -} - -source [find target/swj-dp.tcl] - -# -# SWJ-DP -# -if { [info exists CPU_JTAG_TAPID] } { - set _CPU_JTAG_TAPID $CPU_JTAG_TAPID -} else { - set _CPU_JTAG_TAPID 0x4BA00477 -} - -# -# SW_DP -# -if { [info exists CPU_SWD_TAPID] } { - set _CPU_SWD_TAPID $CPU_SWD_TAPID -} else { - set _CPU_SWD_TAPID 0x2BA01477 -} - -if { [using_jtag] } { - set _CPU_TAPID $_CPU_JTAG_TAPID -} else { - set _CPU_TAPID $_CPU_SWD_TAPID -} - -swj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_CPU_TAPID - -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME cortex_m -chain-position $_TARGETNAME - -# Work-area is a space in RAM used for flash programming -# By default use 16 kB -if { [info exists WORKAREASIZE] } { - set _WORKAREASIZE $WORKAREASIZE -} else { - set _WORKAREASIZE 0x1000 -} - -$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0 - -set _FLASHNAME $_CHIPNAME.flash -flash bank $_FLASHNAME xmc4xxx 0x0C000000 0 0 0 $_TARGETNAME - -if { ![using_hla] } { - cortex_m reset_config sysresetreq -} - -adapter_khz 1000 diff --git a/tcl/target/xmos_xs1-xau8a-10_arm.cfg b/tcl/target/xmos_xs1-xau8a-10_arm.cfg deleted file mode 100644 index 3fc197a3c..000000000 --- a/tcl/target/xmos_xs1-xau8a-10_arm.cfg +++ /dev/null @@ -1,16 +0,0 @@ -# -# XMOS xCORE-XA XS1-XAU8A-10: ARM Cortex-M3 @ 48 MHz -# -# http://www.xmos.com/products/silicon/xcore-xa/xa-series -# - -if { ![info exists CHIPNAME] } { - set CHIPNAME xcorexa -} - -if { ![info exists WORKAREASIZE] } { - # XS1-XAU8A-10-FB265: 128 KB SRAM - set WORKAREASIZE 0x20000 -} - -source [find target/efm32.cfg] diff --git a/tcl/target/zynq_7000.cfg b/tcl/target/zynq_7000.cfg deleted file mode 100644 index b11de3287..000000000 --- a/tcl/target/zynq_7000.cfg +++ /dev/null @@ -1,26 +0,0 @@ -# -# Xilinx Zynq-7000 All Programmable SoC -# -# http://www.xilinx.com/products/silicon-devices/soc/zynq-7000/index.htm -# - -set _CHIPNAME zynq -set _TARGETNAME $_CHIPNAME.cpu - -jtag newtap zynq_pl bs -irlen 6 -ircapture 0x1 -irmask 0x03 \ - -expected-id 0x23727093 \ - -expected-id 0x13722093 \ - -expected-id 0x03727093 - -jtag newtap $_CHIPNAME dap -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id 0x4ba00477 - -target create ${_TARGETNAME}0 cortex_a -chain-position $_CHIPNAME.dap \ - -coreid 0 -dbgbase 0x80090000 -target create ${_TARGETNAME}1 cortex_a -chain-position $_CHIPNAME.dap \ - -coreid 1 -dbgbase 0x80092000 -target smp ${_TARGETNAME}0 ${_TARGETNAME}1 - -adapter_khz 1000 - -${_TARGETNAME}0 configure -event reset-assert-post "cortex_a dbginit" -${_TARGETNAME}1 configure -event reset-assert-post "cortex_a dbginit" diff --git a/tcl/target/к1879xб1я.cfg b/tcl/target/к1879xб1я.cfg deleted file mode 100644 index 7d8c11358..000000000 --- a/tcl/target/к1879xб1я.cfg +++ /dev/null @@ -1,35 +0,0 @@ -# СБИС К1879ХБ1Я -# http://www.module.ru/catalog/micro/mikroshema_dekodera_cifrovogo_televizionnogo_signala_sbis_k1879hb1ya/ - -adapter_khz 1000 - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME к1879хб1я -} - -if { [info exists ENDIAN] } { - set _ENDIAN $ENDIAN -} else { - set _ENDIAN little -} - -if { [info exists DSP_TAPID] } { - set _DSP_TAPID $DSP_TAPID -} else { - set _DSP_TAPID 0x2b900f0f -} - -jtag newtap $_CHIPNAME dsp -irlen 4 -expected-id $_DSP_TAPID - -if { [info exists CPU_TAPID] } { - set _CPU_TAPID $CPU_TAPID -} else { - set _CPU_TAPID 0x07b76f0f -} - -jtag newtap $_CHIPNAME arm -irlen 5 -expected-id $_CPU_TAPID - -set _TARGETNAME $_CHIPNAME.arm -target create $_TARGETNAME arm11 -chain-position $_CHIPNAME.arm diff --git a/tcl/test/selftest.cfg b/tcl/test/selftest.cfg deleted file mode 100755 index be420ca0c..000000000 --- a/tcl/test/selftest.cfg +++ /dev/null @@ -1,17 +0,0 @@ - -add_help_text selftest "run selftest using working ram
" - -proc selftest {tmpfile address size} { - - for {set i 0} {$i < $size } {set i [expr $i+4]} { - mww [expr $address+$i] $i - } - - for {set i 0} {$i < 10 } {set i [expr $i+1]} { - echo "Test iteration $i" - dump_image $tmpfile $address $size - verify_image $tmpfile $address bin - load_image $tmpfile $address bin - } - -} diff --git a/tcl/test/syntax1.cfg b/tcl/test/syntax1.cfg deleted file mode 100644 index 79d538480..000000000 --- a/tcl/test/syntax1.cfg +++ /dev/null @@ -1,30 +0,0 @@ -adapter_nsrst_delay 200 -jtag_ntrst_delay 200 - -#use combined on interfaces or targets that can't set TRST/SRST separately -reset_config trst_and_srst srst_pulls_trst - -#LPCs need reset pulled while RTCK is low. 0 to activate JTAG, power-on reset is not enough -jtag_reset 1 1 -jtag_reset 0 0 - -#jtag scan chain -#format L IRC IRCM IDCODE (Length, IR Capture, IR Capture Mask, IDCODE) -jtag newtap lpc2148 one -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id 0x4f1f0f0f - -#target configuration -#daemon_startup reset - -set _TARGETNAME [format "%s.cpu" lpc2148] -target create lpc2148.cpu arm7tdmi -endian little -work-area-size 0x4000 -work-area-phys 0x40000000 -work-area-backup 0 - -$_TARGETNAME configure -event reset-init { -soft_reset_halt -mvb 0xE01FC040 0x01 -} - - - -set _FLASHNAME $_CHIPNAME.flash -flash bank $_FLASHNAME lpc2000 0x0 0x7d000 0 0 0 lpc2000_v2 14765 - diff --git a/tcl/tools/firmware-recovery.tcl b/tcl/tools/firmware-recovery.tcl deleted file mode 100644 index 6e23540f0..000000000 --- a/tcl/tools/firmware-recovery.tcl +++ /dev/null @@ -1,112 +0,0 @@ -echo "\n\nFirmware recovery helpers" -echo "Use -c firmware_help to get help\n" - -set known_boards { - "asus-rt-n16 ASUS RT-N16" - "asus-rt-n66u ASUS RT-N66U" - "linksys-wrt54gl Linksys WRT54GL v1.1" - "netgear-dg834v3 Netgear DG834G v3" - "tp-link_tl-mr3020 TP-LINK TL-MR3020" - "bt-homehubv1 BT HomeHub v1" -} - -proc firmware_help { } { - echo " -Your OpenOCD command should look like this: -openocd -f interface/.cfg -f tools/firmware-recovery.tcl -c \"*; shutdown\" - -Where: - is one of the supported devices, e.g. ftdi/jtagkey2 - are firmware-recovery commands separated by semicolon - -Supported commands: -firmware_help get this help -list_boards list known boards and exit -board select board you work with -list_partitions list partitions of the currently selected board -dump_part save partition's contents to a file -erase_part erase the given partition -flash_part erase, flash and verify the given partition -ram_boot load binary file to RAM and run it -adapter_khz set JTAG clock frequency in kHz - -For example, to clear nvram and reflash CFE on an RT-N16 using TUMPA, run: -openocd -f interface/ftdi/tumpa.cfg -f tools/firmware-recovery.tcl \\ - -c \"board asus-rt-n16; erase_part nvram; flash_part CFE cfe-n16.bin; shutdown\" -\n\n" - shutdown -} - -# set default, can be overriden later -adapter_khz 1000 - -proc get_partition { name } { - global partition_list - dict get $partition_list $name -} - -proc partition_desc { name } { lindex [get_partition $name] 0 } -proc partition_start { name } { lindex [get_partition $name] 1 } -proc partition_size { name } { lindex [get_partition $name] 2 } - -proc list_boards { } { - global known_boards - echo "List of the supported boards:\n" - echo "Board name\t\tDescription" - echo "-----------------------------------" - foreach i $known_boards { - echo $i - } - echo "\n\n" -} - -proc board { name } { - script [find board/$name.cfg] -} - -proc list_partitions { } { - global partition_list - set fstr "%-16s%-14s%-14s%s" - echo "\nThe currently selected board is known to have these partitions:\n" - echo [format $fstr Name Start Size Description] - echo "-------------------------------------------------------" - for {set i 0} {$i < [llength $partition_list]} {incr i 2} { - set key [lindex $partition_list $i] - echo [format $fstr $key [partition_start $key] [partition_size $key] [partition_desc $key]] - } - echo "\n\n" -} - -# Magic to work with any targets, including semi-functional -proc prepare_target { } { - init - catch {halt} - catch {reset init} - catch {halt} -} - -proc dump_part { name filename } { - prepare_target - dump_image $filename [partition_start $name] [partition_size $name] -} - -proc erase_part { name } { - prepare_target - flash erase_address [partition_start $name] [partition_size $name] -} - -proc flash_part { name filename } { - prepare_target - flash write_image erase $filename [partition_start $name] bin - echo "Verifying:" - verify_image $filename [partition_start $name] -} - -proc ram_boot { filename } { - global ram_boot_address - prepare_target - load_image $filename $ram_boot_address bin - resume $ram_boot_address -} - -echo "" diff --git a/tcl/tools/memtest.tcl b/tcl/tools/memtest.tcl deleted file mode 100644 index 02f94d307..000000000 --- a/tcl/tools/memtest.tcl +++ /dev/null @@ -1,189 +0,0 @@ -# Algorithms by Michael Barr, released into public domain -# Ported to OpenOCD by Shane Volpe, additional fixes by Paul Fertser - -set CPU_MAX_ADDRESS 0xFFFFFFFF -source [find bitsbytes.tcl] -source [find memory.tcl] - -proc runAllMemTests { baseAddress nBytes } { - memTestDataBus $baseAddress - memTestAddressBus $baseAddress $nBytes - memTestDevice $baseAddress $nBytes -} - -#*********************************************************************************** -# * -# * Function: memTestDataBus() -# * -# * Description: Test the data bus wiring in a memory region by -# * performing a walking 1's test at a fixed address -# * within that region. The address (and hence the -# * memory region) is selected by the caller. -# * Ported from: -# * http://www.netrino.com/Embedded-Systems/How-To/Memory-Test-Suite-C -# * Notes: -# * -# * Returns: Empty string if the test succeeds. -# * A non-zero result is the first pattern that failed. -# * -#*********************************************************************************** -proc memTestDataBus { address } { - echo "Running memTestDataBus" - - for {set i 0} {$i < 32} {incr i} { - # Shift bit - set pattern [expr {1 << $i}] - - # Write pattern to memory - memwrite32 $address $pattern - - # Read pattern from memory - set data [memread32 $address] - - if {$data != $pattern} { - echo "FAILED DATABUS: Address: $address, Pattern: $pattern, Returned: $data" - return $pattern - } - } -} - -#*********************************************************************************** -# * -# * Function: memTestAddressBus() -# * -# * Description: Perform a walking 1's test on the relevant bits -# * of the address and check for aliasing. This test -# * will find single-bit address failures such as stuck -# * -high, stuck-low, and shorted pins. The base address -# * and size of the region are selected by the caller. -# * Ported from: -# * http://www.netrino.com/Embedded-Systems/How-To/Memory-Test-Suite-C -# * -# * Notes: For best results, the selected base address should -# * have enough LSB 0's to guarantee single address bit -# * changes. For example, to test a 64-Kbyte region, -# * select a base address on a 64-Kbyte boundary. Also, -# * select the region size as a power-of-two--if at all -# * possible. -# * -# * Returns: Empty string if the test succeeds. -# * A non-zero result is the first address at which an -# * aliasing problem was uncovered. By examining the -# * contents of memory, it may be possible to gather -# * additional information about the problem. -# * -#*********************************************************************************** -proc memTestAddressBus { baseAddress nBytes } { - set addressMask [expr $nBytes - 1] - set pattern 0xAAAAAAAA - set antipattern 0x55555555 - - echo "Running memTestAddressBus" - - echo "addressMask: [convertToHex $addressMask]" - - echo "memTestAddressBus: Writing the default pattern at each of the power-of-two offsets..." - for {set offset 32} {[expr $offset & $addressMask] != 0} {set offset [expr $offset << 1] } { - set addr [expr $baseAddress + $offset] - memwrite32 $addr $pattern - } - - echo "memTestAddressBus: Checking for address bits stuck high..." - memwrite32 $baseAddress $antipattern - - for {set offset 32} {[expr $offset & $addressMask] != 0} {set offset [expr $offset << 1]} { - set addr [expr $baseAddress + $offset] - set data [memread32 $addr] - - if {$data != $pattern} { - echo "FAILED DATA_ADDR_BUS_SHIGH: Address: [convertToHex $addr], Pattern: [convertToHex $pattern], Returned: [convertToHex $data]" - return $pattern - } - } - - echo "memTestAddressBus: Checking for address bits stuck low or shorted..." - memwrite32 $baseAddress $pattern - for {set testOffset 32} {[expr $testOffset & $addressMask] != 0} {set testOffset [expr $testOffset << 1] } { - set addr [expr $baseAddress + $testOffset] - memwrite32 $addr $antipattern - - set data [memread32 $baseAddress] - if {$data != $pattern} { - echo "FAILED DATA_ADDR_BUS_SLOW: Address: [convertToHex $addr], Pattern: [convertToHex $pattern], Returned: [convertToHex $data]" - return $pattern - } - - for {set offset 32} {[expr $offset & $addressMask] != 0} {set offset [expr $offset << 1]} { - set addr [expr $baseAddress + $offset] - set data [memread32 $baseAddress] - - if {(($data != $pattern) && ($offset != $testOffset))} { - echo "FAILED DATA_ADDR_BUS_SLOW2: Address: [convertToHex $addr], Pattern: [convertToHex $pattern], Returned: [convertToHex $data], offset: [convertToHex $offset], testOffset [convertToHex $testOffset]" - return $pattern - } - } - set addr [expr $baseAddress + $testOffset] - memwrite32 $addr $pattern - } -} - -#*********************************************************************************** -# * -# * Function: memTestDevice() -# * -# * Description: Test the integrity of a physical memory device by -# * performing an increment/decrement test over the -# * entire region. In the process every storage bit -# * in the device is tested as zero and as one. The -# * base address and the size of the region are -# * selected by the caller. -# * Ported from: -# * http://www.netrino.com/Embedded-Systems/How-To/Memory-Test-Suite-C -# * Notes: -# * -# * Returns: Empty string if the test succeeds. -# * A non-zero result is the first address at which an -# * incorrect value was read back. By examining the -# * contents of memory, it may be possible to gather -# * additional information about the problem. -# * -#*********************************************************************************** -proc memTestDevice { baseAddress nBytes } { - echo "Running memTestDevice" - - echo "memTestDevice: Filling memory with a known pattern..." - for {set pattern 1; set offset 0} {$offset < $nBytes} {incr pattern; incr offset 32} { - memwrite32 [expr $baseAddress + $offset] $pattern - } - - echo "memTestDevice: Checking each location and inverting it for the second pass..." - for {set pattern 1; set offset 0} {$offset < $nBytes} {incr pattern; incr offset 32} { - set addr [expr $baseAddress + $offset] - set data [memread32 $addr] - - if {$data != $pattern} { - echo "FAILED memTestDevice_pattern: Address: [convertToHex $addr], Pattern: [convertToHex $pattern], Returned: [convertToHex $data], offset: [convertToHex $offset]" - return $pattern - } - - set antiPattern [expr ~$pattern] - memwrite32 [expr $baseAddress + $offset] $antiPattern - } - - echo "memTestDevice: Checking each location for the inverted pattern and zeroing it..." - for {set pattern 1; set offset 0} {$offset < $nBytes} {incr pattern; incr offset 32} { - set antiPattern [expr ~$pattern & ((1<<32) - 1)] - set addr [expr $baseAddress + $offset] - set data [memread32 $addr] - set dataHex [convertToHex $data] - set antiPatternHex [convertToHex $antiPattern] - if {[expr $dataHex != $antiPatternHex]} { - echo "FAILED memTestDevice_antipattern: Address: [convertToHex $addr], antiPattern: $antiPatternHex, Returned: $dataHex, offset: $offset" - return $pattern - } - } -} - -proc convertToHex { value } { - format 0x%08x $value -} diff --git a/testing/build.test1/Makefile b/testing/build.test1/Makefile deleted file mode 100644 index 7271bf2c6..000000000 --- a/testing/build.test1/Makefile +++ /dev/null @@ -1,98 +0,0 @@ -# -*- mode: makefile -*- -# -default: _complain_ -include ./local.uses - -%: _complain_ - - -_complain_: - @echo "" - @echo " Try the target: cygwin.buildtest or linux.buildtest " - @echo "" - -remove.install: - rm -rf ${INSTALL_DIR} - -.PHONY: remove.install - -cygwin.buildtest: - ${MAKE} -f Makefile.ftd2xx clean all - ${MAKE} -f Makefile.openocd cygwin.easy.permutations - ${MAKE} -f Makefile.openocd mingw32.easy.permutations - ${MAKE} -f Makefile.libftdi all - ${MAKE} -f Makefile.openocd cygwin.libftdi - -linux.buildtest: - ${MAKE} linux.easy.buildtest - ${MAKE} linux.ftd2xx_installed - ${MAKE} linux.ft2232_libftdi - @echo "" - @echo "" - @echo "========================================" - @echo " Linux Build Tests Complete " - @echo "========================================" - @echo "" - @echo "" - - -linux.easy.buildtest: - @test -d openocd || (echo "Where the source to openocd?" && exit 1) - ${MAKE} -f Makefile.openocd bootstrap - ${MAKE} -f Makefile.ftd2xx all - ${MAKE} -f Makefile.openocd linux.easy.permutations - -linux.ftd2xx_installed: - ${MAKE} remove.install - ${MAKE} linux.ftd2xx_installed.setup - ${MAKE} -f Makefile.openocd $@ - - linux.ft2232_libftdi: - ${MAKE} remove.install - ${MAKE} -f Makefile.libusb all - ${MAKE} -f Makefile.confuse all - ${MAKE} -f Makefile.libftdi all - ${MAKE} -f Makefile.openocd $@ - -# This target is used to "install" files from -# the FTDICHIP.COM tar.gz unpack directory -# into "a proper place" - where they should be found. -linux.ftd2xx_installed.setup: - mkdir -p ${INSTALL_DIR}/include - mkdir -p ${EXEC_PREFIX}/lib - @# - @# Sanity check - make sure the .H file is findable - @# - @f=$(FTD2XX_LINUX_DIR)/ftd2xx.h && \ - test -f $$f || (echo "Error: $$f not found" ; exit 1) - @# - @# Header files are simple... just copy them. - @# - cp $(FTD2XX_LINUX_DIR)/ftd2xx.h $(PREFIX)/include/. - cp $(FTD2XX_LINUX_DIR)/WinTypes.h $(PREFIX)/include/. - @# - @# .SO files are harder. - @# (1) copy them, (2) make links - @# - cp $(FTD2XX_LINUX_DIR)/libftd2xx.so.$(FTD2XX_LINUX_VERSION) $(EXEC_PREFIX)/lib/. - cd $(EXEC_PREFIX)/lib && rm -f libftd2xx.so.0 - cd $(EXEC_PREFIX)/lib && ln -s libftd2xx.so.$(FTD2XX_LINUX_VERSION) libftd2xx.so.0 - cd $(EXEC_PREFIX)/lib && rm -f libftd2xx.so - cd $(EXEC_PREFIX)/lib && ln -s libftd2xx.so.$(FTD2XX_LINUX_VERSION) libftd2xx.so - - -all.download: - mkdir -p ${VIRGINS} - ${MAKE} -f Makefile.confuse download - ${MAKE} -f Makefile.libftdi download - ${MAKE} -f Makefile.ftd2xx download - ${MAKE} -f Makefile.libusb download - -.PHONY: linux.buildtest \ - linux.easy.buildtest \ - linux.ftd2xx_installed \ - linux.ft22232_libftdi \ - linux.ftd2xx_installed.setup - - - diff --git a/testing/build.test1/Makefile.confuse b/testing/build.test1/Makefile.confuse deleted file mode 100644 index 9d5a0673f..000000000 --- a/testing/build.test1/Makefile.confuse +++ /dev/null @@ -1,46 +0,0 @@ -# -*- mode: makefile -*- -default: _complain_ -include ./local.uses - -TARFILE_LOCAL=${VIRGINS}/confuse-${LIBCONFUSE_VERSION}.tar.gz -TARFILE_URL =http://www.intra2net.com/de/produkte/opensource/ftdi/TGZ/confuse-${LIBCONFUSE_VERSION}.tar.gz - -CONFUSE_SRC_DIR =${HERE}/confuse-${LIBCONFUSE_VERSION} -CONFUSE_BUILD_DIR =${HERE}/confuse-build - -download: - wget -O ${TARFILE_LOCAL} ${TARFILE_URL} - -unpack: - rm -rf ${CONFUSE_SRC_DIR} - tar xfz ${TARFILE_LOCAL} - -clean:: - rm -rf ${CONFUSE_SRC_DIR} - -configure: - rm -rf ${CONFUSE_BUILD_DIR} - mkdir ${CONFUSE_BUILD_DIR} - cd ${CONFUSE_BUILD_DIR} && ${CONFUSE_SRC_DIR}/configure \ - --prefix=${PREFIX} \ - --exec-prefix=${EXEC_PREFIX} - -clean:: - rm -rf ${CONFUSE_BUILD_DIR} - -build: - cd ${CONFUSE_BUILD_DIR} && ${MAKE} - -install: - cd ${CONFUSE_BUILD_DIR} && ${MAKE} install - -all: unpack configure build install - -_complain_: - @echo "" - @echo "Please try one of these targets: bootstrap, clean, configure, build, install" - @echo " Or read the makefile and learn about the permutation test targets" - @echo "" - @echo "You also might find the download and unpack targets helpful." - @echo "" - @exit 1 diff --git a/testing/build.test1/Makefile.ftd2xx b/testing/build.test1/Makefile.ftd2xx deleted file mode 100644 index 3f19e7720..000000000 --- a/testing/build.test1/Makefile.ftd2xx +++ /dev/null @@ -1,88 +0,0 @@ -# -*- mode: makefile -*- -# -default: _complain_ - -include ./local.uses - -# WARNING... the file on the ftdi chip site has a SPACE in the filename GRRR!!! -# We fix that with the "-O" option to wget. -ZIPFILE_LOCAL=${VIRGINS}/cdm.${FTD2XX_WIN32_VERSION}.zip -ZIPFILE_URL ="http://www.ftdichip.com/Drivers/CDM/CDM ${FTD2XX_WIN32_VERSION}.zip" - -TARFILE_LOCAL=${VIRGINS}/libftd2xx${FTD2XX_LINUX_VERSION}.tar.gz -TARFILE_URL =http://www.ftdichip.com/Drivers/D2XX/Linux/libftd2xx${FTD2XX_LINUX_VERSION}.tar.gz - -TARFILE_64_LOCAL=${VIRGINS}/libftd2xx${FTD2XX_LINUX_VERSION}_x86_64.tar.gz -TARFILE_64_URL =http://www.ftdichip.com/Drivers/D2XX/Linux/libftd2xx${FTD2XX_LINUX_VERSION}_x86_64.tar.gz - - -download.win32: - mkdir -p ${VIRGINS} - wget -O ${ZIPFILE_LOCAL} ${ZIPFILE_URL} - -unpack.win32: - rm -rf ${FTD2XX_WIN32_DIR} - mkdir -p ${FTD2XX_WIN32_DIR} - cd ${FTD2XX_WIN32_DIR} && unzip ${ZIPFILE_LOCAL} - -clean:: - rm -rf ${FTD2XX_WIN32_DIR} - -download.linux: - mkdir -p ${VIRGINS} - wget -O ${TARFILE_LOCAL} ${TARFILE_URL} - -clean:: - rm -rf ${FTD2XX_LINUX_DIR} - -unpack.linux: - rm -rf ${FTD2XX_LINUX_DIR} - mkdir -p ${FTD2XX_LINUX_DIR} - tar xfz ${TARFILE_LOCAL} - -download.linux.x86_64: - mkdir -p ${VIRGINS} - wget -O ${TARFILE_LOCAL} ${TARFILE_URL} - -unpack.linux.x86_64: - rm -rf ${FTD2XX_LINUX_64_DIR} - mkdir -p ${FTD2XX_LINUX_64_DIR} - tar xfz ${TARFILE_64_LOCAL} - -clean:: - rm -rf ${FTD2XX_LINUX_64_DIR} - -download: download.win32 download.linux - -unpack.cygwin unpack.mingw32: unpack.win32 - -unpack: unpack.${BUILD_SYSNAME} - -# Nothing to do here -build: - @echo "Done" - -#Nothing to do here -configure: - @echo "Done" - -# Nothing to do here -install: - @echo "Done" - -all: unpack configure build install - -.PHONY: install - -# Nothing to do here -clean:: - @echo "Done" - -_complain_: - @echo "" - @echo "Please try one of these targets: bootstrap, clean, configure, build, install" - @echo " Or read the makefile and learn about the permutation test targets" - @echo "" - @echo "You also might find the download and unpack targets helpful." - @echo "" - @exit 1 diff --git a/testing/build.test1/Makefile.libftdi b/testing/build.test1/Makefile.libftdi deleted file mode 100644 index 1a9612c05..000000000 --- a/testing/build.test1/Makefile.libftdi +++ /dev/null @@ -1,51 +0,0 @@ -# -*- mode: makefile -*- -default: _complain_ -include ./local.uses - -TARFILE_LOCAL = ${VIRGINS}/libftdi-${LIBFTDI_VERSION}.tar.gz -TARFILE_URL = http://www.intra2net.com/de/produkte/opensource/ftdi/TGZ/libftdi-${LIBFTDI_VERSION}.tar.gz - -LIBFTDI_SRC_DIR = ${HERE}/libftdi-${LIBFTDI_VERSION} -LIBFTDI_BUILD_DIR= ${HERE}/libftdi-build - -download: - mkdir -p virgins - wget -O ${TARFILE_LOCAL} ${TARFILE_URL} - -clean:: - rm -rf ${LIBFTDI_SRC_DIR} - -unpack: - tar xf ${TARFILE_LOCAL} - -PATH := ${EXEC_PREFIX}/bin:${PATH} -export PATH - -clean:: - rm -rf ${LIBFTDI_BUILD_DIR} - -configure: - rm -rf ${LIBFTDI_BUILD_DIR} - mkdir -p ${LIBFTDI_BUILD_DIR} - cd ${LIBFTDI_BUILD_DIR} && ${LIBFTDI_SRC_DIR}/configure \ - --prefix=${PREFIX} \ - --exec-prefix=${EXEC_PREFIX} - -build: - cd ${LIBFTDI_BUILD_DIR} && ${MAKE} - -install: - cd ${LIBFTDI_BUILD_DIR} && ${MAKE} install - -all: unpack configure build install - -.PHONY: install - -_complain_: - @echo "" - @echo "Please try one of these targets: bootstrap, clean, configure, build, install" - @echo " Or read the makefile and learn about the permutation test targets" - @echo "" - @echo "You also might find the download and unpack targets helpful." - @echo "" - @exit 1 diff --git a/testing/build.test1/Makefile.libusb b/testing/build.test1/Makefile.libusb deleted file mode 100644 index 815592a18..000000000 --- a/testing/build.test1/Makefile.libusb +++ /dev/null @@ -1,55 +0,0 @@ -# -*- mode: makefile -*- -default: _complain_ - -include ./local.uses - -ifeq (x"$BUILD_SYSNAME",x"cygwin") -$(error Please use the Win32 specific port of LibUSB not the Unix version) -endif -ifeq (x"$BUILD_SYSNAME",x"mingw32") -$(error Please use the win32 specific port of LibUSB not the Unix version) -endif - -TARFILE_LOCAL = ${VIRGINS}/libusb-${LIBUSB_VERSION_linux}.tar.bz2 -TARFILE_URL = http://downloads.sourceforge.net/libusb/libusb-${LIBUSB_VERSION_linux}.tar.gz - -LIBUSB_SRC_DIR = ${HERE}/libusb-${LIBUSB_VERSION} -LIBUSB_BUILD_DIR = ${HERE}/libusb-build - -download: - wget -O ${TARFILE_LOCAL} ${TARFILE_URL} - -unpack: - rm -rf ${LIBUSB_SRC_DIR} - tar xfz ${TARFILE_LOCAL} - -clean:: - rm -rf ${LIBUSB_SRC_DIR} - -configure: - rm -rf ${LIBUSB_BUILD_DIR} - mkdir -p ${LIBUSB_BUILD_DIR} - cd ${LIBUSB_BUILD_DIR} && ${LIBUSB_SRC_DIR}/configure \ - --prefix=${PREFIX} --exec-prefix=${EXEC_PREFIX} - -clean:: - rm -rf ${LIBUSB_BUILD_DIR} - -build: - cd ${LIBUSB_BUILD_DIR} && ${MAKE} - -install: - cd ${LIBUSB_BUILD_DIR} && ${MAKE} install - -all: unpack configure build install - -.PHONY: install - -_complain_: - @echo "" - @echo "Please try one of these targets: bootstrap, clean, configure, build, install" - @echo " Or read the makefile and learn about the permutation test targets" - @echo "" - @echo "You also might find the download and unpack targets helpful." - @echo "" - @exit 1 diff --git a/testing/build.test1/Makefile.openocd b/testing/build.test1/Makefile.openocd deleted file mode 100644 index 6b0cb56ff..000000000 --- a/testing/build.test1/Makefile.openocd +++ /dev/null @@ -1,193 +0,0 @@ -# -*- mode: makefile -*- -# -default: _complain_ - -include ./local.uses - - -SRC_DIR ?= $(HERE)/openocd -BUILD_SUFFIX ?= $(BUILD_MACHINE) -BUILD_DIR =$(HERE)/openocd.$(BUILD_SUFFIX) - -checkout: - svn co https://svn.berlios.de/svnroot/repos/openocd/trunk openocd - -remove.install: - rm -rf ${INSTALL_DIR} - -#======================================== -# Win32 Build Permutations -# none -# parport -# ftd2xx - (ftdichip) -# libftd -CONFIG_OPTIONS_win32_none = -CONFIG_OPTIONS_win32_parport = --enable-parport -CONFIG_OPTIONS_win32_ftd2xx = --enable-parport --enable-ft2232_ftd2xx --with-ftd2xx-win32-zipdir=$(FTD2XX_WIN32_DIR) - -CYGWIN_EASY_PERMUTATIONS += none -CYGWIN_EASY_PERMUTATIONS += parport -CYGWIN_EASY_PERMUTATIONS += ftd2xx - -MINGW32_EASY_PERMUTATIONS += none -MINGW32_EASY_PERMUTATIONS += parport -MINGW32_EASY_PERMUTATIONS += ftd2xx - - -# This is not a possible permutation, it is manual :-( -# Why? Because "libftdi" installs things into install/include -# which would efect the 'ftd2xx' win32 build -CONFIG_OPTIONS_win32_libftdi = --enable-parport --enable-ft2232_libftdi - -# Default build for win32... is the ftd2xx type build. -PERMUTE_win32 ?= ftd2xx -CONFIG_OPTIONS_win32 ?= $(CONFIG_OPTIONS_win32_$(PERMUTE_win32)) -CONFIG_OPTIONS_cygwin = $(CONFIG_OPTIONS_win32) -CONFIG_OPTIONS_mingw32 = $(CONFIG_OPTIONS_win32) - -#======================================== -# Linux Build Permuatations -# none -# parport -# ft2232_ftd2xx -# ft2232_libftdi -CONFIG_OPTIONS_linux_none = -LINUX_EASY_PERMUTATIONS += none - -CONFIG_OPTIONS_linux_parport = --enable-parport -LINUX_EASY_PERMUTATIONS += parport - -CONFIG_OPTIONS_linux_ft2232_libftdi = --enable-parport --enable-ft2232-libftdi -#this cannot be done as part of the permutations. -#LINUX_EASY_PERMUTATIONS += ft2232_libftdi - -CONFIG_OPTIONS_linux_ft2232_ftd2xx_static = \ - --enable-parport \ - --enable-ft2232-ftd2xx --with-ftd2xx-lib=static --with-ftd2xx-linux-tardir=$(FTD2XX_LINUX_DIR) -LINUX_EASY_PERMUTATIONS += ft2232_ftd2xx_static - -# this is not a possible permutation it is manual :-( -# why? because it interfers with the other permutations -# by "installing files" in the $(INSTALL_DIR) -CONFIG_OPTIONS_linux_ftd2xx_installed = \ - --enable-parport \ - --enable-ft2232-ftd2xx \ - --with-ftd2xx-lib=shared - -# The default build permutation is -PERMUTE_linux ?= ft2232_ftd2xx_static -CONFIG_OPTIONS_linux = $(CONFIG_OPTIONS_linux_$(PERMUTE_linux)) - -CONFIG_OPTIONS_darwin=\ - --enable-ftd2232-libftdi - -# Which build are we doing? -CONFIG_OPTIONS := $(CONFIG_OPTIONS_$(BUILD_SYSNAME)) - -bootstrap: - cd $(SRC_DIR) && bash ./bootstrap - -clean:: - rm -rf $(BUILD_DIR) - -ifndef CFLAGS -_CFLAGS=true -else -_CFLAGS=export CFLAGS="${CFLAGS}" -endif - - -# if this was given... then pass it on -configure: - @echo " Build Sysname: $(BUILD_SYSNAME)" - @echo " Config Options: $(CONFIG_OPTIONS)" - rm -rf $(BUILD_DIR) - mkdir $(BUILD_DIR) - ${_CFLAGS} && \ - cd $(BUILD_DIR) && \ - $(SRC_DIR)/configure \ - --prefix=$(PREFIX) \ - --exec-prefix=$(EXEC_PREFIX) \ - $(CONFIG_OPTIONS) - -build: - cd $(BUILD_DIR) && $(MAKE) - -install: - cd $(BUILD_DIR) && $(MAKE) install - -all: configure build install - -.PHONY: install - -# The "cygwin.libftdi" requires that libftdi be built -# and installed *PRIOR* to running this target. -# it is not part of the permutations because ... -# it interfers with the ftd2xx based builds -cygwin.libftdi: - $(MAKE) -f Makefile.openocd bootstrap - $(MAKE) BUILD_SUFFIX=$@ PERMUTE_win32=libftdi -f Makefile.openocd all - -cygwin.easy.permutations: remove.install ${CYGWIN_EASY_PERMUTATIONS:%=_cygwin.%} - -_cygwin.%: - @echo "" - @echo "" - @echo "========================================" - @echo "Permutation Build... $@" - @echo "========================================" - @echo "" - @echo "" - $(MAKE) PERMUTE_win32=$* BUILD_SUFFIX=cygwin.$* -f Makefile.openocd all - $(EXEC_PREFIX)/bin/openocd -v - -mingw32.easy.permutations: remove.install ${MINGW32_EASY_PERMUTATIONS:%=_mingw32.%} - -# I (duane) build openocd-mingw32 via Cygwin. -# Sadly, the "mingw32" buid for cygwin does not include -# the required "elf.h" header files... so ... -# we have them in our own private helper place. -_mingw32.%: - @echo "" - @echo "" - @echo "========================================" - @echo "Permutation Build... $@" - @echo "========================================" - @echo "" - @echo "" - CFLAGS="-mno-cygwin -I$(HERE)/mingw32_help/include" \ - $(MAKE) -f Makefile.openocd all ;\ - $(EXEC_PREFIX)/bin/openocd -v - -win32.permutations: mingw32.permutations cygwin.permutations - - -# SMOKE TEST - Build every linux permuation... -# If "openocd -v" does exit(0) we are good enough. - -linux.easy.permutations: remove.install ${LINUX_EASY_PERMUTATIONS:%=_linux.%} - - -_linux.%: - @echo "" - @echo "" - @echo "========================================" - @echo "Permutation Build... $@" - @echo "========================================" - @echo "" - @echo "" - $(MAKE) PERMUTE_linux=$* BUILD_SUFFIX=linux.$* -f Makefile.openocd all - $(EXEC_PREFIX)/bin/openocd -v - -linux.ftd2xx_installed: - ${MAKE} -f Makefile.openocd _$@ - -linux.ft2232_libftdi: - ${MAKE} -f Makefile.openocd _$@ - -_complain_: - @echo "" - @echo "Please try one of these targets: bootstrap, clean, configure, build, install" - @echo " Or read the makefile and learn about the permutation test targets" - @echo "" - @exit 1 diff --git a/testing/build.test1/README.TXT b/testing/build.test1/README.TXT deleted file mode 100644 index c8244382a..000000000 --- a/testing/build.test1/README.TXT +++ /dev/null @@ -1,39 +0,0 @@ --- Duane Ellis'es test case for building numerous openocd configurations... -Dec 26,2008 ---------------------------------------------------------------------------- - -1) Make a directory some where.. - - mkdir ~/test - -2) Change to that directory - - cd ~/test - -3) Checkout OpenOCD in that directory. - - cd ~/test - svn co https://svn.berlios.de/svnroot/repos/openocd/trunk openocd - -4) Copy the "build.test1" directory to the "~/work" directory. - - - cd ~/test - cp ~/openocd/testing/build.test1/. ~/test/. - -5) If needed, download various components. - - cd ~/work - make all.download - - -6) For Linux - type: - - cd ~/work - make linux.buildtest - -7) For Cygwin - type: - - cd ~/work - make cygwin.buildtest - diff --git a/testing/build.test1/local.uses b/testing/build.test1/local.uses deleted file mode 100644 index 6c6795b54..000000000 --- a/testing/build.test1/local.uses +++ /dev/null @@ -1,39 +0,0 @@ -# -*- mode: makefile -*- -HERE := $(shell pwd) - -# Solve problems on systems with DASH.. Grrr... -SHELL=/bin/bash -export SHELL - -VIRGINS=${HERE}/virgins - -# Determine the build platform. -BUILD_SYSNAME_Linux =linux -BUILD_SYSNAME_linux =linux -BUILD_SYSNAME_CYGWIN_NT =cygwin -BUILD_SYSNAME_MINGW32_NT =mingw32 -BUILD_SYSNAME_Darwin =darwin -BUILD_SYSNAME_darwin =darwin -BUILD_SYSNAME :=$(BUILD_SYSNAME_$(shell uname --sysname | cut -d'-' -f1)) - -# And machine (ie: i686, x86_64, or what) -BUILD_MACHINE :=$(BUILD_SYSNAME).$(shell uname -m) - - -INSTALL_DIR := $(HERE)/install -PREFIX := ${INSTALL_DIR} -EXEC_PREFIX := ${INSTALL_DIR}/${BUILD_MACHINE} - -LIBFTDI_VERSION=0.14 -LIBCONFUSE_VERSION=2.5 - -LIBUSB_VERSION_linux=0.1.12 - -LIBUSB_VERSION=${LIBUSB_VERSION_${BUILD_SYSNAME}} - -FTD2XX_WIN32_VERSION=2.04.14 -FTD2XX_WIN32_DIR = ${HERE}/ftd2xx.win32 - -FTD2XX_LINUX_VERSION=0.4.16 -FTD2XX_LINUX_DIR = ${HERE}/libftd2xx${FTD2XX_LINUX_VERSION} -FTD2XX_LINUX_64_DIR = ${HERE}/libftd2xx${FTD2XX_LINUX_VERSION}_x86_64 diff --git a/testing/build.test1/mingw32_help/include/elf.h b/testing/build.test1/mingw32_help/include/elf.h deleted file mode 100644 index 23d4aa2d5..000000000 --- a/testing/build.test1/mingw32_help/include/elf.h +++ /dev/null @@ -1,38 +0,0 @@ -/* elf.h - - Copyright 2005 Red Hat, Inc. - -This file is part of Cygwin. - -This software is a copyrighted work licensed under the terms of the -Cygwin license. Please consult the file "CYGWIN_LICENSE" for -details. */ - -#ifndef _ELF_H_ -#define _ELF_H_ - -#include - -typedef signed char int8_t; -typedef unsigned char u_int8_t; -typedef short int16_t; -typedef unsigned short u_int16_t; -typedef int int32_t; -typedef unsigned int u_int32_t; -typedef long long int64_t; -typedef unsigned long long u_int64_t; -typedef int32_t register_t; - - -#ifdef __cplusplus -extern "C" { -#endif -#include -#include -#include -#include -#ifdef __cplusplus -} -#endif - -#endif /*_ELF_H_*/ diff --git a/testing/build.test1/mingw32_help/include/sys/cdefs.h b/testing/build.test1/mingw32_help/include/sys/cdefs.h deleted file mode 100644 index c401ce794..000000000 --- a/testing/build.test1/mingw32_help/include/sys/cdefs.h +++ /dev/null @@ -1,23 +0,0 @@ -/* sys/cdefs.h - - Copyright 1998, 2000, 2001 Red Hat, Inc. - -This file is part of Cygwin. - -This software is a copyrighted work licensed under the terms of the -Cygwin license. Please consult the file "CYGWIN_LICENSE" for -details. */ - -#ifndef _SYS_CDEFS_H -#define _SYS_CDEFS_H -#ifdef __cplusplus -#define __BEGIN_DECLS extern "C" { -#define __END_DECLS } -#else -#define __BEGIN_DECLS -#define __END_DECLS -#endif -#define __P(protos) protos /* full-blown ANSI C */ -#define __CONCAT(__x,__y) __x##__y -#endif - diff --git a/testing/build.test1/mingw32_help/include/sys/elf32.h b/testing/build.test1/mingw32_help/include/sys/elf32.h deleted file mode 100644 index 5dfe9c8b0..000000000 --- a/testing/build.test1/mingw32_help/include/sys/elf32.h +++ /dev/null @@ -1,156 +0,0 @@ -/*- - * Copyright (c) 1996-1998 John D. Polstra. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD: src/sys/sys/elf32.h,v 1.8 2002/05/30 08:32:18 dfr Exp $ - */ - -#ifndef _SYS_ELF32_H_ -#define _SYS_ELF32_H_ 1 - -#include - -/* - * ELF definitions common to all 32-bit architectures. - */ - -typedef u_int32_t Elf32_Addr; -typedef u_int16_t Elf32_Half; -typedef u_int32_t Elf32_Off; -typedef int32_t Elf32_Sword; -typedef u_int32_t Elf32_Word; -typedef u_int32_t Elf32_Size; -typedef Elf32_Off Elf32_Hashelt; - -/* - * ELF header. - */ - -typedef struct { - unsigned char e_ident[EI_NIDENT]; /* File identification. */ - Elf32_Half e_type; /* File type. */ - Elf32_Half e_machine; /* Machine architecture. */ - Elf32_Word e_version; /* ELF format version. */ - Elf32_Addr e_entry; /* Entry point. */ - Elf32_Off e_phoff; /* Program header file offset. */ - Elf32_Off e_shoff; /* Section header file offset. */ - Elf32_Word e_flags; /* Architecture-specific flags. */ - Elf32_Half e_ehsize; /* Size of ELF header in bytes. */ - Elf32_Half e_phentsize; /* Size of program header entry. */ - Elf32_Half e_phnum; /* Number of program header entries. */ - Elf32_Half e_shentsize; /* Size of section header entry. */ - Elf32_Half e_shnum; /* Number of section header entries. */ - Elf32_Half e_shstrndx; /* Section name strings section. */ -} Elf32_Ehdr; - -/* - * Section header. - */ - -typedef struct { - Elf32_Word sh_name; /* Section name (index into the - section header string table). */ - Elf32_Word sh_type; /* Section type. */ - Elf32_Word sh_flags; /* Section flags. */ - Elf32_Addr sh_addr; /* Address in memory image. */ - Elf32_Off sh_offset; /* Offset in file. */ - Elf32_Size sh_size; /* Size in bytes. */ - Elf32_Word sh_link; /* Index of a related section. */ - Elf32_Word sh_info; /* Depends on section type. */ - Elf32_Size sh_addralign; /* Alignment in bytes. */ - Elf32_Size sh_entsize; /* Size of each entry in section. */ -} Elf32_Shdr; - -/* - * Program header. - */ - -typedef struct { - Elf32_Word p_type; /* Entry type. */ - Elf32_Off p_offset; /* File offset of contents. */ - Elf32_Addr p_vaddr; /* Virtual address in memory image. */ - Elf32_Addr p_paddr; /* Physical address (not used). */ - Elf32_Size p_filesz; /* Size of contents in file. */ - Elf32_Size p_memsz; /* Size of contents in memory. */ - Elf32_Word p_flags; /* Access permission flags. */ - Elf32_Size p_align; /* Alignment in memory and file. */ -} Elf32_Phdr; - -/* - * Dynamic structure. The ".dynamic" section contains an array of them. - */ - -typedef struct { - Elf32_Sword d_tag; /* Entry type. */ - union { - Elf32_Size d_val; /* Integer value. */ - Elf32_Addr d_ptr; /* Address value. */ - } d_un; -} Elf32_Dyn; - -/* - * Relocation entries. - */ - -/* Relocations that don't need an addend field. */ -typedef struct { - Elf32_Addr r_offset; /* Location to be relocated. */ - Elf32_Word r_info; /* Relocation type and symbol index. */ -} Elf32_Rel; - -/* Relocations that need an addend field. */ -typedef struct { - Elf32_Addr r_offset; /* Location to be relocated. */ - Elf32_Word r_info; /* Relocation type and symbol index. */ - Elf32_Sword r_addend; /* Addend. */ -} Elf32_Rela; - -/* Macros for accessing the fields of r_info. */ -#define ELF32_R_SYM(info) ((info) >> 8) -#define ELF32_R_TYPE(info) ((unsigned char)(info)) - -/* Macro for constructing r_info from field values. */ -#define ELF32_R_INFO(sym, type) (((sym) << 8) + (unsigned char)(type)) - -/* - * Symbol table entries. - */ - -typedef struct { - Elf32_Word st_name; /* String table index of name. */ - Elf32_Addr st_value; /* Symbol value. */ - Elf32_Size st_size; /* Size of associated object. */ - unsigned char st_info; /* Type and binding information. */ - unsigned char st_other; /* Reserved (not used). */ - Elf32_Half st_shndx; /* Section index of symbol. */ -} Elf32_Sym; - -/* Macros for accessing the fields of st_info. */ -#define ELF32_ST_BIND(info) ((info) >> 4) -#define ELF32_ST_TYPE(info) ((info) & 0xf) - -/* Macro for constructing st_info from field values. */ -#define ELF32_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf)) - -#endif /* !_SYS_ELF32_H_ */ diff --git a/testing/build.test1/mingw32_help/include/sys/elf64.h b/testing/build.test1/mingw32_help/include/sys/elf64.h deleted file mode 100644 index 48556be5f..000000000 --- a/testing/build.test1/mingw32_help/include/sys/elf64.h +++ /dev/null @@ -1,172 +0,0 @@ -/*- - * Copyright (c) 1996-1998 John D. Polstra. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD: src/sys/sys/elf64.h,v 1.10 2002/05/30 08:32:18 dfr Exp $ - */ - -#ifndef _SYS_ELF64_H_ -#define _SYS_ELF64_H_ 1 - -#include - -/* - * ELF definitions common to all 64-bit architectures. - */ - -typedef uint64_t Elf64_Addr; -typedef uint16_t Elf64_Half; -typedef uint32_t Elf64_Word; -typedef int32_t Elf64_Sword; -typedef uint64_t Elf64_Xword; -typedef int64_t Elf64_Sxword; -typedef uint64_t Elf64_Off; -typedef uint16_t Elf64_Section; -typedef Elf64_Half Elf64_Versym; -typedef uint16_t Elf64_Quarter; - -/* - * Types of dynamic symbol hash table bucket and chain elements. - * - * This is inconsistent among 64 bit architectures, so a machine dependent - * typedef is required. - */ - -#ifdef __alpha__ -typedef Elf64_Off Elf64_Hashelt; -#else -typedef Elf64_Half Elf64_Hashelt; -#endif - -/* - * ELF header. - */ - -typedef struct { - unsigned char e_ident[EI_NIDENT]; /* File identification. */ - Elf64_Half e_type; /* File type. */ - Elf64_Half e_machine; /* Machine architecture. */ - Elf64_Word e_version; /* ELF format version. */ - Elf64_Addr e_entry; /* Entry point. */ - Elf64_Off e_phoff; /* Program header file offset. */ - Elf64_Off e_shoff; /* Section header file offset. */ - Elf64_Word e_flags; /* Architecture-specific flags. */ - Elf64_Half e_ehsize; /* Size of ELF header in bytes. */ - Elf64_Half e_phentsize; /* Size of program header entry. */ - Elf64_Half e_phnum; /* Number of program header entries. */ - Elf64_Half e_shentsize; /* Size of section header entry. */ - Elf64_Half e_shnum; /* Number of section header entries. */ - Elf64_Half e_shstrndx; /* Section name strings section. */ -} Elf64_Ehdr; - -/* - * Section header. - */ - -typedef struct { - Elf64_Word sh_name; /* Section name (index into the - section header string table). */ - Elf64_Word sh_type; /* Section type. */ - Elf64_Xword sh_flags; /* Section flags. */ - Elf64_Addr sh_addr; /* Address in memory image. */ - Elf64_Off sh_offset; /* Offset in file. */ - Elf64_Xword sh_size; /* Size in bytes. */ - Elf64_Word sh_link; /* Index of a related section. */ - Elf64_Word sh_info; /* Depends on section type. */ - Elf64_Xword sh_addralign; /* Alignment in bytes. */ - Elf64_Xword sh_entsize; /* Size of each entry in section. */ -} Elf64_Shdr; - -/* - * Program header. - */ - -typedef struct { - Elf64_Word p_type; /* Entry type. */ - Elf64_Word p_flags; /* Access permission flags. */ - Elf64_Off p_offset; /* File offset of contents. */ - Elf64_Addr p_vaddr; /* Virtual address in memory image. */ - Elf64_Addr p_paddr; /* Physical address (not used). */ - Elf64_Xword p_filesz; /* Size of contents in file. */ - Elf64_Xword p_memsz; /* Size of contents in memory. */ - Elf64_Xword p_align; /* Alignment in memory and file. */ -} Elf64_Phdr; - -/* - * Dynamic structure. The ".dynamic" section contains an array of them. - */ - -typedef struct { - Elf64_Sxword d_tag; /* Entry type. */ - union { - Elf64_Xword d_val; /* Integer value. */ - Elf64_Addr d_ptr; /* Address value. */ - } d_un; -} Elf64_Dyn; - -/* - * Relocation entries. - */ - -/* Relocations that don't need an addend field. */ -typedef struct { - Elf64_Addr r_offset; /* Location to be relocated. */ - Elf64_Xword r_info; /* Relocation type and symbol index. */ -} Elf64_Rel; - -/* Relocations that need an addend field. */ -typedef struct { - Elf64_Addr r_offset; /* Location to be relocated. */ - Elf64_Xword r_info; /* Relocation type and symbol index. */ - Elf64_Sxword r_addend; /* Addend. */ -} Elf64_Rela; - -/* Macros for accessing the fields of r_info. */ -#define ELF64_R_SYM(info) ((info) >> 32) -#define ELF64_R_TYPE(info) ((unsigned char)(info)) - -/* Macro for constructing r_info from field values. */ -#define ELF64_R_INFO(sym, type) (((sym) << 32) + (unsigned char)(type)) - -/* - * Symbol table entries. - */ - -typedef struct { - Elf64_Word st_name; /* String table index of name. */ - unsigned char st_info; /* Type and binding information. */ - unsigned char st_other; /* Reserved (not used). */ - Elf64_Section st_shndx; /* Section index of symbol. */ - Elf64_Addr st_value; /* Symbol value. */ - Elf64_Xword st_size; /* Size of associated object. */ -} Elf64_Sym; - -/* Macros for accessing the fields of st_info. */ -#define ELF64_ST_BIND(info) ((info) >> 4) -#define ELF64_ST_TYPE(info) ((info) & 0xf) - -/* Macro for constructing st_info from field values. */ -#define ELF64_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf)) - -#endif /* !_SYS_ELF64_H_ */ diff --git a/testing/build.test1/mingw32_help/include/sys/elf_common.h b/testing/build.test1/mingw32_help/include/sys/elf_common.h deleted file mode 100644 index b864f0464..000000000 --- a/testing/build.test1/mingw32_help/include/sys/elf_common.h +++ /dev/null @@ -1,299 +0,0 @@ -/*- - * Copyright (c) 1998 John D. Polstra. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD: src/sys/sys/elf_common.h,v 1.15 2004/05/05 02:38:54 marcel Exp $ - */ - -#ifndef _SYS_ELF_COMMON_H_ -#define _SYS_ELF_COMMON_H_ 1 - -/* - * ELF definitions that are independent of architecture or word size. - */ - -/* - * Note header. The ".note" section contains an array of notes. Each - * begins with this header, aligned to a word boundary. Immediately - * following the note header is n_namesz bytes of name, padded to the - * next word boundary. Then comes n_descsz bytes of descriptor, again - * padded to a word boundary. The values of n_namesz and n_descsz do - * not include the padding. - */ - -typedef struct { - u_int32_t n_namesz; /* Length of name. */ - u_int32_t n_descsz; /* Length of descriptor. */ - u_int32_t n_type; /* Type of this note. */ -} Elf_Note; - -/* Indexes into the e_ident array. Keep synced with - http://www.sco.com/developer/gabi/ch4.eheader.html */ -#define EI_MAG0 0 /* Magic number, byte 0. */ -#define EI_MAG1 1 /* Magic number, byte 1. */ -#define EI_MAG2 2 /* Magic number, byte 2. */ -#define EI_MAG3 3 /* Magic number, byte 3. */ -#define EI_CLASS 4 /* Class of machine. */ -#define EI_DATA 5 /* Data format. */ -#define EI_VERSION 6 /* ELF format version. */ -#define EI_OSABI 7 /* Operating system / ABI identification */ -#define EI_ABIVERSION 8 /* ABI version */ -#define OLD_EI_BRAND 8 /* Start of architecture identification. */ -#define EI_PAD 9 /* Start of padding (per SVR4 ABI). */ -#define EI_NIDENT 16 /* Size of e_ident array. */ - -/* Values for the magic number bytes. */ -#define ELFMAG0 0x7f -#define ELFMAG1 'E' -#define ELFMAG2 'L' -#define ELFMAG3 'F' -#define ELFMAG "\177ELF" /* magic string */ -#define SELFMAG 4 /* magic string size */ - -/* Values for e_ident[EI_VERSION] and e_version. */ -#define EV_NONE 0 -#define EV_CURRENT 1 - -/* Values for e_ident[EI_CLASS]. */ -#define ELFCLASSNONE 0 /* Unknown class. */ -#define ELFCLASS32 1 /* 32-bit architecture. */ -#define ELFCLASS64 2 /* 64-bit architecture. */ - -/* Values for e_ident[EI_DATA]. */ -#define ELFDATANONE 0 /* Unknown data format. */ -#define ELFDATA2LSB 1 /* 2's complement little-endian. */ -#define ELFDATA2MSB 2 /* 2's complement big-endian. */ - -/* Values for e_ident[EI_OSABI]. */ -#define ELFOSABI_SYSV 0 /* UNIX System V ABI */ -#define ELFOSABI_NONE ELFOSABI_SYSV /* symbol used in old spec */ -#define ELFOSABI_HPUX 1 /* HP-UX operating system */ -#define ELFOSABI_NETBSD 2 /* NetBSD */ -#define ELFOSABI_LINUX 3 /* GNU/Linux */ -#define ELFOSABI_HURD 4 /* GNU/Hurd */ -#define ELFOSABI_86OPEN 5 /* 86Open common IA32 ABI */ -#define ELFOSABI_SOLARIS 6 /* Solaris */ -#define ELFOSABI_MONTEREY 7 /* Monterey */ -#define ELFOSABI_IRIX 8 /* IRIX */ -#define ELFOSABI_FREEBSD 9 /* FreeBSD */ -#define ELFOSABI_TRU64 10 /* TRU64 UNIX */ -#define ELFOSABI_MODESTO 11 /* Novell Modesto */ -#define ELFOSABI_OPENBSD 12 /* OpenBSD */ -#define ELFOSABI_ARM 97 /* ARM */ -#define ELFOSABI_STANDALONE 255 /* Standalone (embedded) application */ - -/* e_ident */ -#define IS_ELF(ehdr) ((ehdr).e_ident[EI_MAG0] == ELFMAG0 && \ - (ehdr).e_ident[EI_MAG1] == ELFMAG1 && \ - (ehdr).e_ident[EI_MAG2] == ELFMAG2 && \ - (ehdr).e_ident[EI_MAG3] == ELFMAG3) - -/* Values for e_type. */ -#define ET_NONE 0 /* Unknown type. */ -#define ET_REL 1 /* Relocatable. */ -#define ET_EXEC 2 /* Executable. */ -#define ET_DYN 3 /* Shared object. */ -#define ET_CORE 4 /* Core file. */ - -/* Values for e_machine. */ -#define EM_NONE 0 /* Unknown machine. */ -#define EM_M32 1 /* AT&T WE32100. */ -#define EM_SPARC 2 /* Sun SPARC. */ -#define EM_386 3 /* Intel i386. */ -#define EM_68K 4 /* Motorola 68000. */ -#define EM_88K 5 /* Motorola 88000. */ -#define EM_486 6 /* Intel i486. */ -#define EM_860 7 /* Intel i860. */ -#define EM_MIPS 8 /* MIPS R3000 Big-Endian only */ - -/* Extensions. This list is not complete. */ -#define EM_S370 9 /* IBM System/370 */ -#define EM_MIPS_RS4_BE 10 /* MIPS R4000 Big-Endian */ /* Depreciated */ -#define EM_PARISC 15 /* HPPA */ -#define EM_SPARC32PLUS 18 /* SPARC v8plus */ -#define EM_PPC 20 /* PowerPC 32-bit */ -#define EM_PPC64 21 /* PowerPC 64-bit */ -#define EM_ARM 40 /* ARM */ -#define EM_SPARCV9 43 /* SPARC v9 64-bit */ -#define EM_IA_64 50 /* Intel IA-64 Processor */ -#define EM_X86_64 62 /* Advanced Micro Devices x86-64 */ -#define EM_ALPHA 0x9026 /* Alpha (written in the absence of an ABI */ - -/* Special section indexes. */ -#define SHN_UNDEF 0 /* Undefined, missing, irrelevant. */ -#define SHN_LORESERVE 0xff00 /* First of reserved range. */ -#define SHN_LOPROC 0xff00 /* First processor-specific. */ -#define SHN_HIPROC 0xff1f /* Last processor-specific. */ -#define SHN_ABS 0xfff1 /* Absolute values. */ -#define SHN_COMMON 0xfff2 /* Common data. */ -#define SHN_HIRESERVE 0xffff /* Last of reserved range. */ - -/* sh_type */ -#define SHT_NULL 0 /* inactive */ -#define SHT_PROGBITS 1 /* program defined information */ -#define SHT_SYMTAB 2 /* symbol table section */ -#define SHT_STRTAB 3 /* string table section */ -#define SHT_RELA 4 /* relocation section with addends */ -#define SHT_HASH 5 /* symbol hash table section */ -#define SHT_DYNAMIC 6 /* dynamic section */ -#define SHT_NOTE 7 /* note section */ -#define SHT_NOBITS 8 /* no space section */ -#define SHT_REL 9 /* relocation section - no addends */ -#define SHT_SHLIB 10 /* reserved - purpose unknown */ -#define SHT_DYNSYM 11 /* dynamic symbol table section */ -#define SHT_NUM 12 /* number of section types */ -#define SHT_LOOS 0x60000000 /* First of OS specific semantics */ -#define SHT_HIOS 0x6fffffff /* Last of OS specific semantics */ -#define SHT_LOPROC 0x70000000 /* reserved range for processor */ -#define SHT_HIPROC 0x7fffffff /* specific section header types */ -#define SHT_LOUSER 0x80000000 /* reserved range for application */ -#define SHT_HIUSER 0xffffffff /* specific indexes */ - -/* Flags for sh_flags. */ -#define SHF_WRITE 0x1 /* Section contains writable data. */ -#define SHF_ALLOC 0x2 /* Section occupies memory. */ -#define SHF_EXECINSTR 0x4 /* Section contains instructions. */ -#define SHF_TLS 0x400 /* Section contains TLS data. */ -#define SHF_MASKPROC 0xf0000000 /* Reserved for processor-specific. */ - -/* Values for p_type. */ -#define PT_NULL 0 /* Unused entry. */ -#define PT_LOAD 1 /* Loadable segment. */ -#define PT_DYNAMIC 2 /* Dynamic linking information segment. */ -#define PT_INTERP 3 /* Pathname of interpreter. */ -#define PT_NOTE 4 /* Auxiliary information. */ -#define PT_SHLIB 5 /* Reserved (not used). */ -#define PT_PHDR 6 /* Location of program header itself. */ -#define PT_TLS 7 /* Thread local storage segment */ - -#define PT_COUNT 8 /* Number of defined p_type values. */ - -#define PT_LOOS 0x60000000 /* OS-specific */ -#define PT_HIOS 0x6fffffff /* OS-specific */ -#define PT_LOPROC 0x70000000 /* First processor-specific type. */ -#define PT_HIPROC 0x7fffffff /* Last processor-specific type. */ - -/* Values for p_flags. */ -#define PF_X 0x1 /* Executable. */ -#define PF_W 0x2 /* Writable. */ -#define PF_R 0x4 /* Readable. */ - -/* Values for d_tag. */ -#define DT_NULL 0 /* Terminating entry. */ -#define DT_NEEDED 1 /* String table offset of a needed shared - library. */ -#define DT_PLTRELSZ 2 /* Total size in bytes of PLT relocations. */ -#define DT_PLTGOT 3 /* Processor-dependent address. */ -#define DT_HASH 4 /* Address of symbol hash table. */ -#define DT_STRTAB 5 /* Address of string table. */ -#define DT_SYMTAB 6 /* Address of symbol table. */ -#define DT_RELA 7 /* Address of ElfNN_Rela relocations. */ -#define DT_RELASZ 8 /* Total size of ElfNN_Rela relocations. */ -#define DT_RELAENT 9 /* Size of each ElfNN_Rela relocation entry. */ -#define DT_STRSZ 10 /* Size of string table. */ -#define DT_SYMENT 11 /* Size of each symbol table entry. */ -#define DT_INIT 12 /* Address of initialization function. */ -#define DT_FINI 13 /* Address of finalization function. */ -#define DT_SONAME 14 /* String table offset of shared object - name. */ -#define DT_RPATH 15 /* String table offset of library path. [sup] */ -#define DT_SYMBOLIC 16 /* Indicates "symbolic" linking. [sup] */ -#define DT_REL 17 /* Address of ElfNN_Rel relocations. */ -#define DT_RELSZ 18 /* Total size of ElfNN_Rel relocations. */ -#define DT_RELENT 19 /* Size of each ElfNN_Rel relocation. */ -#define DT_PLTREL 20 /* Type of relocation used for PLT. */ -#define DT_DEBUG 21 /* Reserved (not used). */ -#define DT_TEXTREL 22 /* Indicates there may be relocations in - non-writable segments. [sup] */ -#define DT_JMPREL 23 /* Address of PLT relocations. */ -#define DT_BIND_NOW 24 /* [sup] */ -#define DT_INIT_ARRAY 25 /* Address of the array of pointers to - initialization functions */ -#define DT_FINI_ARRAY 26 /* Address of the array of pointers to - termination functions */ -#define DT_INIT_ARRAYSZ 27 /* Size in bytes of the array of - initialization functions. */ -#define DT_FINI_ARRAYSZ 28 /* Size in bytes of the array of - terminationfunctions. */ -#define DT_RUNPATH 29 /* String table offset of a null-terminated - library search path string. */ -#define DT_FLAGS 30 /* Object specific flag values. */ -#define DT_ENCODING 32 /* Values greater than or equal to DT_ENCODING - and less than DT_LOOS follow the rules for - the interpretation of the d_un union - as follows: even == 'd_ptr', even == 'd_val' - or none */ -#define DT_PREINIT_ARRAY 32 /* Address of the array of pointers to - pre-initialization functions. */ -#define DT_PREINIT_ARRAYSZ 33 /* Size in bytes of the array of - pre-initialization functions. */ - -#define DT_COUNT 33 /* Number of defined d_tag values. */ - -#define DT_LOOS 0x6000000d /* First OS-specific */ -#define DT_HIOS 0x6fff0000 /* Last OS-specific */ -#define DT_LOPROC 0x70000000 /* First processor-specific type. */ -#define DT_HIPROC 0x7fffffff /* Last processor-specific type. */ - -/* Values for DT_FLAGS */ -#define DF_ORIGIN 0x0001 /* Indicates that the object being loaded may - make reference to the $ORIGIN substitution - string */ -#define DF_SYMBOLIC 0x0002 /* Indicates "symbolic" linking. */ -#define DF_TEXTREL 0x0004 /* Indicates there may be relocations in - non-writable segments. */ -#define DF_BIND_NOW 0x0008 /* Indicates that the dynamic linker should - process all relocations for the object - containing this entry before transferring - control to the program. */ -#define DF_STATIC_TLS 0x0010 /* Indicates that the shared object or - executable contains code using a static - thread-local storage scheme. */ - -/* Values for n_type. Used in core files. */ -#define NT_PRSTATUS 1 /* Process status. */ -#define NT_FPREGSET 2 /* Floating point registers. */ -#define NT_PRPSINFO 3 /* Process state info. */ - -/* Symbol Binding - ELFNN_ST_BIND - st_info */ -#define STB_LOCAL 0 /* Local symbol */ -#define STB_GLOBAL 1 /* Global symbol */ -#define STB_WEAK 2 /* like global - lower precedence */ -#define STB_LOPROC 13 /* reserved range for processor */ -#define STB_HIPROC 15 /* specific symbol bindings */ - -/* Symbol type - ELFNN_ST_TYPE - st_info */ -#define STT_NOTYPE 0 /* Unspecified type. */ -#define STT_OBJECT 1 /* Data object. */ -#define STT_FUNC 2 /* Function. */ -#define STT_SECTION 3 /* Section. */ -#define STT_FILE 4 /* Source file. */ -#define STT_TLS 6 /* TLS object. */ -#define STT_LOPROC 13 /* reserved range for processor */ -#define STT_HIPROC 15 /* specific symbol types */ - -/* Special symbol table indexes. */ -#define STN_UNDEF 0 /* Undefined symbol index. */ - -#endif /* !_SYS_ELF_COMMON_H_ */ diff --git a/testing/build.test1/mingw32_help/include/sys/elf_generic.h b/testing/build.test1/mingw32_help/include/sys/elf_generic.h deleted file mode 100644 index dbe9f1e83..000000000 --- a/testing/build.test1/mingw32_help/include/sys/elf_generic.h +++ /dev/null @@ -1,91 +0,0 @@ -/*- - * Copyright (c) 1998 John D. Polstra. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD: src/sys/sys/elf_generic.h,v 1.6 2002/07/20 02:56:11 peter Exp $ - */ - -#ifndef _SYS_ELF_GENERIC_H_ -#define _SYS_ELF_GENERIC_H_ 1 - -#include - -/* - * Definitions of generic ELF names which relieve applications from - * needing to know the word size. - */ - -#ifndef __ELF_WORD_SIZE -# define __ELF_WORD_SIZE 32 -#endif - -#if __ELF_WORD_SIZE != 32 && __ELF_WORD_SIZE != 64 -#error "__ELF_WORD_SIZE must be defined as 32 or 64" -#endif - -#define ELF_CLASS __CONCAT(ELFCLASS,__ELF_WORD_SIZE) - -#if BYTE_ORDER == LITTLE_ENDIAN -#define ELF_DATA ELFDATA2LSB -#elif BYTE_ORDER == BIG_ENDIAN -#define ELF_DATA ELFDATA2MSB -#else -#error "Unknown byte order" -#endif - -#if __ELF_WORD_SIZE == 32 -#define __elfN(x) elf32_##x -#define __ElfN(x) Elf32_##x -#define __ELFN(x) ELF32_##x -#else -#define __elfN(x) elf364_##x -#define __ElfN(x) Elf364_##x -#define __ELFN(x) ELF364_##x -#endif -#define __ElfType(x) typedef __ElfN(x) Elf_##x - -#define FOO -__ElfType(Addr); -__ElfType(Half); -__ElfType(Off); -__ElfType(Sword); -__ElfType(Word); -__ElfType(Size); -__ElfType(Hashelt); -__ElfType(Ehdr); -__ElfType(Shdr); -__ElfType(Phdr); -__ElfType(Dyn); -__ElfType(Rel); -__ElfType(Rela); -__ElfType(Sym); - -#define ELF_R_SYM __ELFN(R_SYM) -#define ELF_R_TYPE __ELFN(R_TYPE) -#define ELF_R_INFO __ELFN(R_INFO) -#define ELF_ST_BIND __ELFN(ST_BIND) -#define ELF_ST_TYPE __ELFN(ST_TYPE) -#define ELF_ST_INFO __ELFN(ST_INFO) - -#endif /* !_SYS_ELF_GENERIC_H_ */ diff --git a/testing/build.test2/Makefile b/testing/build.test2/Makefile deleted file mode 100644 index d4c428edd..000000000 --- a/testing/build.test2/Makefile +++ /dev/null @@ -1,193 +0,0 @@ -# -*- mode: makefile -*- -#======================================== -# DO NOT DELETE THE LINE BELOW -_default: default -# DO NOT DELETE THE LINE_ABOVE -#======================================== - -#======================================== -# -# There are no user configurable options here. -# -# All user configurable options are in local.uses -# -include ./local.uses -# -#======================================== - -#======================================== -# This is the USB driver for the FTDI2XX chips. -# It is a "closed" solution from FTDICHIP.COM -# Some claim it is faster then the open/free -# solution: win32-libusb+libftdi. -# -ftd2xx.download: - mkdir -p ${VIRGINS} - wget -O ${FTD2XX_ZIPFILE_LOCAL} \ - ${FTD2XX_ZIPFILE_URL} - -ftd2xx.unpack: - rm -rf ${FTD2XX_WIN32_DIR} - mkdir -p ${FTD2XX_WIN32_DIR} - cd ${FTD2XX_WIN32_DIR} && unzip \ - ${FTD2XX_ZIPFILE_LOCAL} - -ftd2xx.build: - @echo "Nothing to do for: $@" - -ftd2xx.configure: - @echo "Nothing to do for: $@" - -ftd2xx.install: - @echo "Nothing to do for: $@" - -clean:: - rm -rf ${FTD2XX_WIN32_DIR} - -ftd2xx.all: ftd2xx.unpack ftd2xx.configure \ - ftd2xx.build ftd2xx.install - - -#========================================- -# LIBFTDI - requires LIBCONFUSE.. -# So we handle it here :-( - -libconfuse.download: - mkdir -p virgins - wget -O ${LIBCONFUSE_TARFILE_LOCAL} \ - ${LIBCONFUSE_TARFILE_URL} - -libconfuse.unpack: - tar xfz ${LIBCONFUSE_TARFILE_LOCAL} - -clean:: - rm -rf ${LIBCONFUSE_SRC_DIR} - -libconfuse.configure: - rm -rf ${LIBCONFUSE_BUILD_DIR} - mkdir -p ${LIBCONFUSE_BUILD_DIR} - cd ${LIBCONFUSE_BUILD_DIR} && \ - ${LIBCONFUSE_SRC_DIR}/configure \ - --prefix=${PREFIX} - -clean:: - rm -rf ${LIBCONFUSE_BUILD_DIR} - -libconfuse.build: - cd ${LIBCONFUSE_BUILD_DIR} && ${MAKE} - -libconfuse.install: - cd ${LIBCONFUSE_BUILD_DIR} && ${MAKE} install - -libconfuse.all: libconfuse.unpack libconfuse.configure \ - libconfuse.build libconfuse.install - -#======================================== -# LIBFTDI - the open source (and free) -# alternative to (closed) FTD2XX drivers. - -libftdi.download: - mkdir -p virgins - wget -O ${LIBFTDI_TARFILE_LOCAL} \ - ${LIBFTDI_TARFILE_URL} - -libftdi.unpack: - tar xfz ${LIBFTDI_TARFILE_LOCAL} - -clean:: - rm -rf ${LIBFTDI_SRC_DIR} - -libftdi.configure: - rm -rf ${LIBFTDI_BUILD_DIR} - mkdir -p ${LIBFTDI_BUILD_DIR} - cd ${LIBFTDI_BUILD_DIR} && \ - ${LIBFTDI_SRC_DIR}/configure \ - --prefix=${PREFIX} - -clean:: - rm -rf ${LIBFTDI_BUILD_DIR} - -libftdi.build: - cd ${LIBFTDI_BUILD_DIR} && ${MAKE} - -libftdi.install: - cd ${LIBFTDI_BUILD_DIR} && ${MAKE} install - -libftdi.all: libftdi.unpack libftdi.configure \ - libftdi.build libftdi.install - -#======================================== -# Openocd... - -openocd.bootstrap: - cd ${OPENOCD_SRC_DIR} && bash ./bootstrap - -openocd.configure: - rm -rf ${OPENOCD_BUILD_DIR} - mkdir -p ${OPENOCD_BUILD_DIR} - cd ${OPENOCD_BUILD_DIR} && ${OPENOCD_SRC_DIR}/configure \ - --prefix=${INSTALL_DIR} \ - ${OPENOCD_CONFIG_OPTIONS} - -openocd.build: - cd ${OPENOCD_BUILD_DIR} && ${MAKE} - -openocd.docs: - cd ${OPENOCD_BUILD_DIR}/docs && ${MAKE} - -openocd.docs.pdf: - cd ${OPENOCD_BUILD_DIR}/docs && ${MAKE} pdf - -openocd.docs.html: - cd ${OPENOCD_BUILD_DIR}/docs && ${MAKE} html - -# fixme: -# need to add a "make one huge html file target" - -openocd.install: - cd ${OPENOCD_BUILD_DIR} && ${MAKE} install - -#======================================== -# The world... - -# Manual step. -download.all: \ - ftd2xx.download \ - libconfuse.download \ - libftdi.download - -ifeq (x"${FT2232_DRIVER}",x"ftd2xx") -prebuild: ftd2xx.all -endif - -ifeq (x"${FT2232_DRIVER}",x"libftdi") -prebuild: libconfuse.all libftdi.all -endif - -remake: \ - openocd.bootstrap \ - openocd.configure \ - openocd.build \ - openocd.install - -initial.build : download.all prebuild remake - -all: - @echo "" - @echo " This makefile does not support an 'all' target" - @echo "" - @echo " If this is your *FIRST* time building... " - @echo " Then use this command: \"make initial.build\"" - @echo "" - @echo " The \"default\" target is for openocd developers" - @echo " and rebuilds openocd completely.." - @echo "" - -default: - test -d ${OPENOCD_SRC_DIR} || (echo "Where is: The OPENOCD source?"; exit 1) - ${MAKE} remake - -whatis_%: - @echo "" - @echo "Makevariable: $* => ${${*}}" - @echo "" diff --git a/testing/build.test2/README.txt b/testing/build.test2/README.txt deleted file mode 100644 index d71c14b5a..000000000 --- a/testing/build.test2/README.txt +++ /dev/null @@ -1,59 +0,0 @@ - -This makefile is how I Duane Ellis (openocd@duaneellis.com) builds -openocd test purposes on Cygwin. I have included it here so others -might also make use of the same configuration that I use to develop -Openocd. - ---Duane Ellis - -To make use of it do the following: - -(1) Check out openocd in the standard way. - -For example - in cygwin, type this: - - bash$ mkdir -p /home/duane/test - bash$ cd /home/duane/test - bash$ svn co https://svn.berlios.de/svnroot/repos/openocd/trunk openocd - -(2) COPY this folder "right above" where you have OpenOCD. - - bash$ cd /home/duane/test - bash$ cp ./openocd/testing/build.test2/* /home/duane/test/. - -(3) OPTIONALLY - - You might want to review the file "local.uses" - Change options and so forth at the top of the file. - -(4) Initially, you need to download some additional files. - These include "libftdi", "libconfuse", and the ftd2xx drivers. - -(5) You also need to build the supporting libraries and install them - (They are installed "locally" only) - - Type this command: - - bash$ cd /home/duane/test - - bash$ make initial.build - - which: (1) downloads files - (2) builds the libs - (3) builds OpenOCD - -(6) As you hack upon OpenOCD... to rebuild OpenOCD... - - bash$ cd /home/duane/test - - bash$ make remake - - which: (1) re-bootstraps - (2) re-configures - (3) re-builds - (4) re-installs. - -======= -**END** -======= - diff --git a/testing/build.test2/local.uses b/testing/build.test2/local.uses deleted file mode 100644 index edde31b0c..000000000 --- a/testing/build.test2/local.uses +++ /dev/null @@ -1,161 +0,0 @@ -# -*- mode: makefile -*- -#======================================== -# DO NOT REMOVE THE LINE BELOW -HERE := $(shell pwd) -# DO NOT REMOVE THE LINE ABOVE -#======================================== - -# These are common CYGWIN build settings. -# Comment out things you do not want. -# Or unComment things you want. - -# PCs always have printer ports... -X86_PRINTER_PORT ?= y - -# Chose *ONE* of these three solutions. -#FTD2232_DRIVER = none -FT2232_DRIVER = ftd2xx -#FT2232_DRIVER = libftdi - -# Do you have "libusb" installed? -ifeq (x"${FT2232_DRIVER}",x"libftdi") -# With LIBFTDI... LIBUSB is manditory. -USE_LIBUSB = y -endif - -# By default... we assume libusb not present. -USE_LIBUSB ?= n - -#======================================== -# DO NOT EDIT SETTINGS BELOW THIS LINE -#======================================== - - - -#======================================== -# House keeping... - -# Solve problems on systems with DASH.. Grrr... -SHELL=/bin/bash -export SHELL - -VIRGINS ?= ${HERE}/virgins -INSTALL_DIR ?= $(HERE)/install -PREFIX ?= ${INSTALL_DIR} - -# Determine the build platform. -BUILD_SYSNAME_Linux =linux -BUILD_SYSNAME_linux =linux -BUILD_SYSNAME_CYGWIN_NT =cygwin -BUILD_SYSNAME_MINGW32_NT =mingw32 -BUILD_SYSNAME_Darwin =darwin -BUILD_SYSNAME_darwin =darwin -BUILD_SYSNAME :=$(BUILD_SYSNAME_$(shell uname --sysname | cut -d'-' -f1)) - -# And machine (ie: i686, x86_64, or what ever) -BUILD_MACHINE :=$(BUILD_SYSNAME).$(shell uname -m) - - -#======================================== -# - -FTD2XX_LINUX_VERSION=0.4.16 -FTD2XX_LINUX_DIR = ${HERE}/libftd2xx${FTD2XX_LINUX_VERSION} -FTD2XX_LINUX_64_DIR = ${HERE}/libftd2xx${FTD2XX_LINUX_VERSION}_x86_64 - - -# Wiggler type interfaces are here. -OPENOCD_CONFIG_OPTIONS_printer_y += --enable-parport -OPENOCD_CONFIG_OPTIONS_printer_y += --enable-parport-giveio -OPENOCD_CONFIG_OPTIONS_printer_y += --enable-gw16012 -OPENOCD_CONFIG_OPTIONS_printer_y += --enable-parport-giveio -OPENOCD_CONFIG_OPTIONS_printer_y += --enable-amtjtagaccel - - -# FTD2XX only supports these -OPENOCD_CONFIG_OPTIONS_ft2232_none = -OPENOCD_CONFIG_OPTIONS_ft2232_ftd2xx = --enable-ft2232_ftd2xx --enable-presto_ftd2xx --with-ftd2xx-win32-zipdir=${FTD2XX_WIN32_DIR} -OPENOCD_CONFIG_OPTIONS_ft2232_libftdi = --enable-ft2232_libftdi --enable-presto_libftdi - -# LIBUSB - adds support for these. -OPENOCD_CONFIG_OPTIONS_libusb_y += --enable-jlink -OPENOCD_CONFIG_OPTIONS_libusb_y += --enable-usbprog -OPENOCD_CONFIG_OPTIONS_libusb_y += --enable-rlink -OPENOCD_CONFIG_OPTIONS_libusb_y += --enable-vsllink -OPENOCD_CONFIG_OPTIONS_libusb_y += --enable-usbprog - -#======================================== -# EXPLICITY NOT SUPPORTED INTERFACES -# -# zy1000.c -# This is a standalone hardware box -# it is *NOT* a cygwin thing. -# -# at91rm9200.c -# This is a uC/Linux (or linux) that -# runs uC/Linux and uses the gpio pins -# to bit-bang JTAG stuff. -# -# ep93xx.c -# Just like at91rm9200 - different chip. - -#======================================== -# Build OPENOCD config options... -# Always enable "dummy" -OPENOCD_CONFIG_OPTIONS += --enable-dummy -# -# Today: Cannot enable 'oocd_trace' on cygwin. -# it assumes/uses termios functions like -# cfmakeraw() which do not exist on cygwin. -# -#OPENOCD_CONFIG_OPTIONS += --enable-oocd-trace -# -# Add printer options.. -OPENOCD_CONFIG_OPTIONS += ${OPENOCD_CONFIG_OPTIONS_printer_${X86_PRINTER_PORT}} - -# Add the FTD2232 based options. -OPENOCD_CONFIG_OPTIONS += ${OPENOCD_CONFIG_OPTIONS_ft2232_${FT2232_DRIVER}} - -# Add LIBUSB based options. -OPENOCD_CONFIG_OPTIONS += ${OPENOCD_CONFIG_OPTIONS_libusb_${USE_LIBUSB}} - - -#======================================== -# WARNING... the file on the ftdi chip site has a SPACE in the filename GRRR!!! -# We fix that with the "-O" option to wget. -FTD2XX_WIN32_VERSION=2.04.14 -FTD2XX_WIN32_DIR = ${HERE}/ftd2xx.win32 - -FTD2XX_ZIPFILE_LOCAL=${VIRGINS}/cdm.${FTD2XX_WIN32_VERSION}.zip -# Damn thing has a space in the F-ing filename! -FTD2XX_ZIPFILE_URL ="http://www.ftdichip.com/Drivers/CDM/CDM ${FTD2XX_WIN32_VERSION}.zip" - - -#======================================== -# LIBCONFUSE - used by LIBFTDI.. -LIBCONFUSE_VERSION=2.5 -LIBCONFUSE_TARFILE_LOCAL=${VIRGINS}/confuse-${LIBCONFUSE_VERSION}.tar.gz -LIBCONFUSE_TARFILE_URL =http://www.intra2net.com/de/produkte/opensource/ftdi/TGZ/confuse-${LIBCONFUSE_VERSION}.tar.gz - -LIBCONFUSE_SRC_DIR =${HERE}/confuse-${LIBCONFUSE_VERSION} -LIBCONFUSE_BUILD_DIR =${HERE}/confuse-build - - -#======================================== -# LIBFTDI... (which uses libusb, and libconfuse) -LIBFTDI_VERSION=0.14 -LIBFTDI_TARFILE_LOCAL = ${VIRGINS}/libftdi-${LIBFTDI_VERSION}.tar.gz -LIBFTDI_TARFILE_URL = http://www.intra2net.com/de/produkte/opensource/ftdi/TGZ/libftdi-${LIBFTDI_VERSION}.tar.gz - -LIBFTDI_SRC_DIR = ${HERE}/libftdi-${LIBFTDI_VERSION} -LIBFTDI_BUILD_DIR= ${HERE}/libftdi-build - -#======================================== -# Finally - OpenOCD... -# -OPENOCD_BUILD_DIR =${HERE}/openocd-build -OPENOCD_SRC_DIR =${HERE}/openocd - -#======================================== -# END .. -#======================================== diff --git a/testing/examples/AT91R40008Test/inc/typedefs.h b/testing/examples/AT91R40008Test/inc/typedefs.h deleted file mode 100644 index 42136426a..000000000 --- a/testing/examples/AT91R40008Test/inc/typedefs.h +++ /dev/null @@ -1,50 +0,0 @@ -/**************************************************************************** -* Copyright (c) 2006 by Michael Fischer. All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* 1. Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the author nor the names of its contributors may -* be used to endorse or promote products derived from this software -* without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -* THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS -* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED -* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF -* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -* SUCH DAMAGE. -* -**************************************************************************** -* History: -* -* 30.03.06 mifi First Version for Insight tutorial -****************************************************************************/ -#ifndef __TYPEDEFS_H__ -#define __TYPEDEFS_H__ - -/* - * Some types to use Windows like source - */ -typedef char CHAR; /* 8-bit signed data */ -typedef unsigned char BYTE; /* 8-bit unsigned data */ -typedef unsigned short WORD; /* 16-bit unsigned data */ -typedef long LONG; /* 32-bit signed data */ -typedef unsigned long ULONG; /* 32-bit unsigned data */ -typedef unsigned long DWORD; /* 32-bit unsigned data */ - - -#endif /* !__TYPEDEFS_H_ */ -/*** EOF ***/ diff --git a/testing/examples/AT91R40008Test/makefile b/testing/examples/AT91R40008Test/makefile deleted file mode 100644 index c57130a7b..000000000 --- a/testing/examples/AT91R40008Test/makefile +++ /dev/null @@ -1,137 +0,0 @@ -############################################################################################## -# -# !!!! Do NOT edit this makefile with an editor which replace tabs by spaces !!!! -# -############################################################################################## -# -# On command line: -# -# make all = Create project -# -# make clean = Clean project files. -# -# To rebuild project do "make clean" and "make all". -# - -############################################################################################## -# Start of default section -# - -TRGT = arm-elf- -CC = $(TRGT)gcc -CP = $(TRGT)objcopy -AS = $(TRGT)gcc -x assembler-with-cpp -BIN = $(CP) -O ihex - -MCU = arm7tdmi - -# List all default C defines here, like -D_DEBUG=1 -DDEFS = - -# List all default ASM defines here, like -D_DEBUG=1 -DADEFS = - -# List all default directories to look for include files here -DINCDIR = - -# List the default directory to look for the libraries here -DLIBDIR = - -# List all default libraries here -DLIBS = - -# -# End of default section -############################################################################################## - -############################################################################################## -# Start of user section -# - -# Define project name here -PROJECT = test - -# Define linker script file here -LDSCRIPT_RAM = ./prj/ethernut3_ram.ld - -# List all user C define here, like -D_DEBUG=1 -UDEFS = - -# Define ASM defines here -UADEFS = - -# List C source files here -SRC = ./src/main.c - -# List ASM source files here -ASRC = ./src/crt.s - -# List all user directories here -UINCDIR = ./inc - -# List the user directory to look for the libraries here -ULIBDIR = - -# List all user libraries here -ULIBS = - -# Define optimisation level here -OPT = -O0 - -# -# End of user defines -############################################################################################## - - -INCDIR = $(patsubst %,-I%,$(DINCDIR) $(UINCDIR)) -LIBDIR = $(patsubst %,-L%,$(DLIBDIR) $(ULIBDIR)) -DEFS = $(DDEFS) $(UDEFS) -ADEFS = $(DADEFS) $(UADEFS) -OBJS = $(ASRC:.s=.o) $(SRC:.c=.o) -LIBS = $(DLIBS) $(ULIBS) -MCFLAGS = -mcpu=$(MCU) - -ASFLAGS = $(MCFLAGS) -g -gdwarf-2 -Wa,-amhls=$(<:.s=.lst) $(ADEFS) -CPFLAGS = $(MCFLAGS) $(OPT) -gdwarf-2 -mthumb-interwork -fomit-frame-pointer -Wall -Wstrict-prototypes -fverbose-asm -Wa,-ahlms=$(<:.c=.lst) $(DEFS) -LDFLAGS_RAM = $(MCFLAGS) -nostartfiles -T$(LDSCRIPT_RAM) -Wl,-Map=$(PROJECT)_ram.map,--cref,--no-warn-mismatch $(LIBDIR) - -# Generate dependency information -CPFLAGS += -MD -MP -MF .dep/$(@F).d - -# -# makefile rules -# - -all: RAM - -RAM: $(OBJS) $(PROJECT)_ram.elf $(PROJECT)_ram.hex - -%o : %c - $(CC) -c $(CPFLAGS) -I . $(INCDIR) $< -o $@ - -%o : %s - $(AS) -c $(ASFLAGS) $< -o $@ - -%ram.elf: $(OBJS) - $(CC) $(OBJS) $(LDFLAGS_RAM) $(LIBS) -o $@ - -%hex: %elf - $(BIN) $< $@ - -clean: - -rm -f $(OBJS) - -rm -f $(PROJECT)_ram.elf - -rm -f $(PROJECT)_ram.map - -rm -f $(PROJECT)_ram.hex - -rm -f $(SRC:.c=.c.bak) - -rm -f $(SRC:.c=.lst) - -rm -f $(ASRC:.s=.s.bak) - -rm -f $(ASRC:.s=.lst) - -rm -fR .dep - -# -# Include the dependency files, should be the last of the makefile -# --include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*) - -# *** EOF *** \ No newline at end of file diff --git a/testing/examples/AT91R40008Test/prj/at91r40008_reset.script b/testing/examples/AT91R40008Test/prj/at91r40008_reset.script deleted file mode 100644 index 4cda1c589..000000000 --- a/testing/examples/AT91R40008Test/prj/at91r40008_reset.script +++ /dev/null @@ -1,7 +0,0 @@ -wait_halt -sleep 10 -poll -# Ethernut 3 remapping is required to access external flash memory. -mww 0xffe00000 0x1000213d -mww 0xffe00004 0x20003e3d -mww 0xffe00020 0x00000001 diff --git a/testing/examples/AT91R40008Test/prj/at91r40008_turtle.cfg b/testing/examples/AT91R40008Test/prj/at91r40008_turtle.cfg deleted file mode 100644 index 3928a27e6..000000000 --- a/testing/examples/AT91R40008Test/prj/at91r40008_turtle.cfg +++ /dev/null @@ -1,37 +0,0 @@ -#daemon configuration -telnet_port 4444 -gdb_port 3333 - -# tell gdb our flash memory map -gdb_memory_map enable -# enable flash programming -gdb_flash_program enable - -#interface -interface ft2232 -ft2232_device_desc "Turtelizer JTAG/RS232 Adapter A" -ft2232_layout turtelizer2 -ft2232_vid_pid 0x0403 0xbdc8 -jtag_speed 0 -jtag_nsrst_delay 200 -jtag_ntrst_delay 200 - -#use combined on interfaces or targets that can't set TRST/SRST separately -reset_config srst_only srst_pulls_trst - -#jtag scan chain -jtag newtap at91 cpu -irlen 4 -irmask 0xf - -#target configuration -target create target0 arm7tdmi -endian little -chain-position 0 -[new_target_name] configure -work-area-virt 0 -work-area-phys 0x3C000 -work-area-size 0x4000 -work-area-backup false - -target_script 0 reset .\prj\at91r40008_reset.script - -flash bank cfi 0x10000000 0x400000 2 2 0 - -# For more information about the configuration files, -# look at the OpenOCD User's Guide. - -init -reset halt diff --git a/testing/examples/AT91R40008Test/prj/eclipse_ram.gdb b/testing/examples/AT91R40008Test/prj/eclipse_ram.gdb deleted file mode 100644 index 620249714..000000000 --- a/testing/examples/AT91R40008Test/prj/eclipse_ram.gdb +++ /dev/null @@ -1,14 +0,0 @@ -target remote localhost:3333 -monitor reset -monitor sleep 500 -monitor poll -monitor soft_reset_halt -monitor arm7_9 sw_bkpts enable -monitor mww 0xFFE00000 0x1000213D -monitor mww 0xFFE00004 0x20003E3D -monitor mww 0xFFE00020 0x00000001 -monitor mdw 0xFFE00000 1 -monitor mdw 0xFFE00004 1 -load -break main -continue diff --git a/testing/examples/AT91R40008Test/prj/ethernut3_ram.ld b/testing/examples/AT91R40008Test/prj/ethernut3_ram.ld deleted file mode 100644 index 604e70412..000000000 --- a/testing/examples/AT91R40008Test/prj/ethernut3_ram.ld +++ /dev/null @@ -1,140 +0,0 @@ -/**************************************************************************** -* Copyright (c) 2006 by Michael Fischer. All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* 1. Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the author nor the names of its contributors may -* be used to endorse or promote products derived from this software -* without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -* THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS -* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED -* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF -* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -* SUCH DAMAGE. -* -**************************************************************************** -* -* History: -* -* 09.04.06 mifi First Version -****************************************************************************/ - - -ENTRY(ResetHandler) -SEARCH_DIR(.) - -/* - * Define stack size here - */ -FIQ_STACK_SIZE = 0x0100; -IRQ_STACK_SIZE = 0x0100; -ABT_STACK_SIZE = 0x0100; -UND_STACK_SIZE = 0x0100; -SVC_STACK_SIZE = 0x0400; - -/* - * This file, ethernut3_ram.ld, locate the program in the internal - * ram of the AT91R40008. For more information about the memory of the - * AT91R40008 take a look in the AT91 ARM data sheet. - * Reference is made to Rev. 1354D-ATARM-08/02 - * - * Take a look at page 15, Memory Map, Figure 3 - */ - -MEMORY -{ - ram : org = 0x00000000, len = 256k -} - -/* - * Do not change the next code - */ -SECTIONS -{ - .text : - { - *(.vectors); - . = ALIGN(4); - *(.init); - . = ALIGN(4); - *(.text); - . = ALIGN(4); - *(.rodata); - . = ALIGN(4); - *(.rodata*); - . = ALIGN(4); - *(.glue_7t); - . = ALIGN(4); - *(.glue_7); - . = ALIGN(4); - etext = .; - } > ram - - .data : - { - PROVIDE (__data_start = .); - *(.data) - . = ALIGN(4); - edata = .; - _edata = .; - PROVIDE (__data_end = .); - } > ram - - .bss : - { - PROVIDE (__bss_start = .); - *(.bss) - *(COMMON) - . = ALIGN(4); - PROVIDE (__bss_end = .); - - . = ALIGN(256); - - PROVIDE (__stack_start = .); - - PROVIDE (__stack_fiq_start = .); - . += FIQ_STACK_SIZE; - . = ALIGN(4); - PROVIDE (__stack_fiq_end = .); - - PROVIDE (__stack_irq_start = .); - . += IRQ_STACK_SIZE; - . = ALIGN(4); - PROVIDE (__stack_irq_end = .); - - PROVIDE (__stack_abt_start = .); - . += ABT_STACK_SIZE; - . = ALIGN(4); - PROVIDE (__stack_abt_end = .); - - PROVIDE (__stack_und_start = .); - . += UND_STACK_SIZE; - . = ALIGN(4); - PROVIDE (__stack_und_end = .); - - PROVIDE (__stack_svc_start = .); - . += SVC_STACK_SIZE; - . = ALIGN(4); - PROVIDE (__stack_svc_end = .); - PROVIDE (__stack_end = .); - PROVIDE (__heap_start = .); - } > ram - -} -/*** EOF ***/ - diff --git a/testing/examples/AT91R40008Test/src/crt.s b/testing/examples/AT91R40008Test/src/crt.s deleted file mode 100644 index 0b7026118..000000000 --- a/testing/examples/AT91R40008Test/src/crt.s +++ /dev/null @@ -1,172 +0,0 @@ -/**************************************************************************** -* Copyright (c) 2006 by Michael Fischer. All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* 1. Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the author nor the names of its contributors may -* be used to endorse or promote products derived from this software -* without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -* THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS -* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED -* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF -* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -* SUCH DAMAGE. -* -**************************************************************************** -* -* History: -* -* 09.04.06 mifi First Version -****************************************************************************/ - -/* - * Some defines for the program status registers - */ - ARM_MODE_USER = 0x10 /* Normal User Mode */ - ARM_MODE_FIQ = 0x11 /* FIQ Fast Interrupts Mode */ - ARM_MODE_IRQ = 0x12 /* IRQ Standard Interrupts Mode */ - ARM_MODE_SVC = 0x13 /* Supervisor Interrupts Mode */ - ARM_MODE_ABORT = 0x17 /* Abort Processing memory Faults Mode */ - ARM_MODE_UNDEF = 0x1B /* Undefined Instructions Mode */ - ARM_MODE_SYS = 0x1F /* System Running in Priviledged Operating Mode */ - ARM_MODE_MASK = 0x1F - - I_BIT = 0x80 /* disable IRQ when I bit is set */ - F_BIT = 0x40 /* disable IRQ when I bit is set */ - - - .section .vectors,"ax" - .code 32 - -/****************************************************************************/ -/* Vector table and reset entry */ -/****************************************************************************/ -_vectors: - ldr pc, ResetAddr /* Reset */ - ldr pc, UndefAddr /* Undefined instruction */ - ldr pc, SWIAddr /* Software interrupt */ - ldr pc, PAbortAddr /* Prefetch abort */ - ldr pc, DAbortAddr /* Data abort */ - ldr pc, ReservedAddr /* Reserved */ - ldr pc, IRQAddr /* IRQ interrupt */ - ldr pc, FIQAddr /* FIQ interrupt */ - - -ResetAddr: .word ResetHandler -UndefAddr: .word UndefHandler -SWIAddr: .word SWIHandler -PAbortAddr: .word PAbortHandler -DAbortAddr: .word DAbortHandler -ReservedAddr: .word 0 -IRQAddr: .word IRQHandler -FIQAddr: .word FIQHandler - - .ltorg - - - .section .init, "ax" - .code 32 - - .global ResetHandler - .global ExitFunction - .extern main -/****************************************************************************/ -/* Reset handler */ -/****************************************************************************/ -ResetHandler: - /* - * Setup a stack for each mode - */ - msr CPSR_c, #ARM_MODE_UNDEF | I_BIT | F_BIT /* Undefined Instruction Mode */ - ldr sp, =__stack_und_end - - msr CPSR_c, #ARM_MODE_ABORT | I_BIT | F_BIT /* Abort Mode */ - ldr sp, =__stack_abt_end - - msr CPSR_c, #ARM_MODE_FIQ | I_BIT | F_BIT /* FIQ Mode */ - ldr sp, =__stack_fiq_end - - msr CPSR_c, #ARM_MODE_IRQ | I_BIT | F_BIT /* IRQ Mode */ - ldr sp, =__stack_irq_end - - msr CPSR_c, #ARM_MODE_SVC | I_BIT | F_BIT /* Supervisor Mode */ - ldr sp, =__stack_svc_end - - - /* - * Clear .bss section - */ - ldr r1, =__bss_start - ldr r2, =__bss_end - ldr r3, =0 -bss_clear_loop: - cmp r1, r2 - strne r3, [r1], #+4 - bne bss_clear_loop - - - /* - * Jump to main - */ - mrs r0, cpsr - bic r0, r0, #I_BIT | F_BIT /* Enable FIQ and IRQ interrupt */ - msr cpsr, r0 - - mov r0, #0 /* No arguments */ - mov r1, #0 /* No arguments */ - ldr r2, =main - mov lr, pc - bx r2 /* And jump... */ - -ExitFunction: - nop - nop - nop - b ExitFunction - - -/****************************************************************************/ -/* Default interrupt handler */ -/****************************************************************************/ - -UndefHandler: - b UndefHandler - -SWIHandler: - b SWIHandler - -PAbortHandler: - b PAbortHandler - -DAbortHandler: - b DAbortHandler - -IRQHandler: - b IRQHandler - -FIQHandler: - b FIQHandler - - .weak ExitFunction - .weak UndefHandler, PAbortHandler, DAbortHandler - .weak IRQHandler, FIQHandler - - .ltorg -/*** EOF ***/ - - diff --git a/testing/examples/AT91R40008Test/src/main.c b/testing/examples/AT91R40008Test/src/main.c deleted file mode 100644 index 801c72747..000000000 --- a/testing/examples/AT91R40008Test/src/main.c +++ /dev/null @@ -1,93 +0,0 @@ -/**************************************************************************** -* Copyright (c) 2006 by Michael Fischer. All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* 1. Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the author nor the names of its contributors may -* be used to endorse or promote products derived from this software -* without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -* THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS -* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED -* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF -* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -* SUCH DAMAGE. -* -**************************************************************************** -* History: -* -* 30.03.06 mifi First Version for Insight tutorial -* 26.01.08 mifi Added variable "d" to test const variable. -****************************************************************************/ -#define __MAIN_C__ - -/* - * I use the include only, to show - * how to setup a include dir in the makefile - */ -#include -#include -#include "typedefs.h" - -/*=========================================================================*/ -/* DEFINE: All Structures and Common Constants */ -/*=========================================================================*/ - -/*=========================================================================*/ -/* DEFINE: Prototypes */ -/*=========================================================================*/ - -/*=========================================================================*/ -/* DEFINE: Definition of all local Data */ -/*=========================================================================*/ -static const DWORD d = 7; - -/*=========================================================================*/ -/* DEFINE: Definition of all local Procedures */ -/*=========================================================================*/ - -/*=========================================================================*/ -/* DEFINE: All code exported */ -/*=========================================================================*/ -/***************************************************************************/ -/* main */ -/***************************************************************************/ -int main (void) -{ - DWORD a = 1; - DWORD b = 2; - DWORD c = 0; - - a = a + d; - - while (1) - { - a++; - b++; - c = a + b; - } - - /* - * This return here make no sense. - * But to prevent the compiler warning: - * "return type of 'main' is not 'int' - * we use an int as return :-) - */ - return(0); -} - -/*** EOF ***/ diff --git a/testing/examples/AT91R40008Test/test_ram.elf b/testing/examples/AT91R40008Test/test_ram.elf deleted file mode 100644 index 06399016f9c1e28419c7d2de07e932f089ea2433..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 36586 zcmeH}Uu+y#6~@nFih-A^LMRVBfRu+I71RfW(pI8ENGPcZs(8u@o@mwOJ9p;p zjI9>&zzfnj)|q?0d(XZ1%x|t|=iAeBGfF9&LbK>FDZ~@-G5FCJiBdYwp#LzXX^$SK zO>~Af#}ghQ8f3l67cn6q1cZPP5CTF#2nYcoAOwVf5D)@FKnMr{As_^VfDjM@LO=)z z0U;m+gn$qb0zyCt2mv7=1cZPP5CTF#2nYcoAOwVf5D)@FKnMr{As_^VfDjM@LO=)z z0U;m+gn$qb0zyCt2mv7=1cZPP5CTF#2nYcoAOwVf5D)@FKnMr{As_^VfDjM@LO=)z z0U;m+gn$qb0zyCt2mv7=1cZPP5CTF#2nYcoAOwVf5D)@FKnMr{As_^VfDjM@LO=)z z0U;m+gn$qb0{>qGKK=0Kga70cxSd<@U&4O{zYS-*1AiU<=ZBAPU%Pwr!8>R-(7uV* zNBb7qRkUxTZK7?a;hCEcD8IFB(Z&18{PUmupx65h(Z2h4=*~7hJaV6CYn#$r+q1~q zcW>+dfnJXL`u={e_xBG!#wmqj2H**J68;F$oC^Fs$dS9}-c{I}@-IEG&?eDxEkkI> z^QbHHBj{H!cKsgbaIEsz-{m+N#(GZX6|EEb7w+-gf1;jQ>@$cx3j1)e9lP2f#ig|1 z7G?OV-ru{26bu5cI$n*a=K0wUOH^+0HSv_n1!f&UHhL$x_b;S!`S5QnhaeYRbGc*4 zK5>jqPbeYVq9^(KQ5$A+4Hw(C?1r1I@xK1mRj2MOb+Rj%1{<&#RpPhU@9f#RpDr(7 zx00x%!wd2_C3UeJ;RbR+{gbE4wX4g|Hr(<`yXBNyON~x##qrARRmW}D>SfJJAU z)<9>a?fF5nH5iC~j$R@;5Hy23yN3q!cKV_dhJyV+qKIUW%2|ozAd1j?C#No5n4cmm z`%P3opqLJ+8TB@lxi5rt4fmI_Nu4>$Y;X9fDyi8Z-bmp{6odF0rRt34OY` zpVWRzrxsI*p~r^4Fm#YlxZ1A}4Rgg@Y7?I5v+`V(8THQ^UoB zSTU=;Kx(X?W#PYf@DOo&XrpMuGibVK0ulSGaATiEV9~R<@=GAN z`^!2CEX9 zOw400^7!>@%#7_v2cAdYHj(#QUqx$hehe%9{QJ0H6wg1CPr&&;_&I(89$)YGKP38G zY@*p0X&-BeuyQ^}Y>6E^vySh;+E6t413?g86Vd6_Jqi5_AEhMvPc`UE=(~uI;}sUO z1P#X&??0j|j?Qtn$6T0gVBH?S%Od{W-Vx~Njo9t+dFPi+VBOv{g6O$+dkfIfdFb}+ zUAhgu2@kB>TSG7rDxz+We@h}$^sPuBQuIAsGyOhAe9lH=`p1Y5$Mnw-AC2i>AkN41 zuMv;M^zRUl$Mhc%e<`N_h&U6|e?rXPsevit`X@rg_5Kxc^d3{h^WTV#|DzxC+3fcI z1U7MZ2SWr3w0Xn4I_R%%+FxpQ63AANgC(%5Hx>dv+?*C z^p;kEE^vN$j5+@zv^nprFY!1#jQ3kYJfRh9MV(#w&v9<}lIHpR!4;qXGW6|mKG*Zw zj`@mi?a&t8hGrg@;rM=~-$0vxGp^_EuKag+oE^sFe?xpnDiPF=P(MaL+h53a@E}oy7o{41XYo$n> zE0oSsv2wb&Kr{L}YExz1srhZML-S6@@eB33M~g1Lu60zpRMhQP3srm}>ToIwd4{*{ z)O9}!)Geyk?P#4ad)9XAO~)gA4OD7P$M!1Cc6-%)%hw6nmC{0C@@%D4{Q5LYGow=J z_;&3|rL$hEIBuPS63poIM#G<3b8CL1?UG4dYCNM;ox1JYgo5Hr>)SKaD-|w?mo;CZjsf4?dCbIO20E!Txv<@m`c;meG8TFa+B EH}$NwBLDyZ diff --git a/testing/examples/AT91R40008Test/test_ram.hex b/testing/examples/AT91R40008Test/test_ram.hex deleted file mode 100644 index 28a1f40a4..000000000 --- a/testing/examples/AT91R40008Test/test_ram.hex +++ /dev/null @@ -1,23 +0,0 @@ -:1000000018F09FE518F09FE518F09FE518F09FE5C0 -:1000100018F09FE518F09FE518F09FE518F09FE5B0 -:1000200040000000B0000000B4000000B800000074 -:10003000BC00000000000000C0000000C400000080 -:10004000DBF021E37CD09FE5D7F021E378D09FE57A -:10005000D1F021E374D09FE5D2F021E370D09FE589 -:10006000D3F021E36CD09FE56C109FE56C209FE5F9 -:100070000030A0E3020051E104308114FCFFFF1ABC -:1000800000000FE1C000C0E300F029E10000A0E3A0 -:100090000010A0E348209FE50FE0A0E112FF2FE150 -:1000A0000000A0E10000A0E10000A0E1FBFFFFEAEA -:1000B000FEFFFFEAFEFFFFEAFEFFFFEAFEFFFFEAA8 -:1000C000FEFFFFEAFEFFFFEA000600000005000059 -:1000D0000003000000040000000A00004C010000C2 -:1000E0004C010000E80000000CD04DE20130A0E31C -:1000F00000308DE50230A0E304308DE50030A0E350 -:1001000008308DE538309FE5002093E500309DE50F -:10011000023083E000308DE500309DE5013083E260 -:1001200000308DE504309DE5013083E204308DE53B -:1001300000209DE504309DE5033082E008308DE528 -:0C014000F4FFFFEA480100000700000087 -:0400000300000040B9 -:00000001FF diff --git a/testing/examples/AT91R40008Test/test_ram.map b/testing/examples/AT91R40008Test/test_ram.map deleted file mode 100644 index 1df9053e4..000000000 --- a/testing/examples/AT91R40008Test/test_ram.map +++ /dev/null @@ -1,170 +0,0 @@ - -Memory Configuration - -Name Origin Length Attributes -ram 0x00000000 0x00040000 -*default* 0x00000000 0xffffffff - -Linker script and memory map - -LOAD ./src/crt.o -LOAD ./src/main.o -START GROUP -LOAD d:/compiler/yagarto/bin/../lib/gcc/arm-elf/4.2.2\libgcc.a -LOAD d:/compiler/yagarto/bin/../lib/gcc/arm-elf/4.2.2/../../../../arm-elf/lib\libc.a -END GROUP - 0x00000100 FIQ_STACK_SIZE = 0x100 - 0x00000100 IRQ_STACK_SIZE = 0x100 - 0x00000100 ABT_STACK_SIZE = 0x100 - 0x00000100 UND_STACK_SIZE = 0x100 - 0x00000400 SVC_STACK_SIZE = 0x400 - -.text 0x00000000 0x14c - *(.vectors) - .vectors 0x00000000 0x40 ./src/crt.o - 0x00000040 . = ALIGN (0x4) - *(.init) - .init 0x00000040 0xa8 ./src/crt.o - 0x000000c4 FIQHandler - 0x000000b8 PAbortHandler - 0x000000a0 ExitFunction - 0x00000040 ResetHandler - 0x000000bc DAbortHandler - 0x000000c0 IRQHandler - 0x000000b0 UndefHandler - 0x000000e8 . = ALIGN (0x4) - *(.text) - .text 0x000000e8 0x0 ./src/crt.o - .text 0x000000e8 0x60 ./src/main.o - 0x000000e8 main - 0x00000148 . = ALIGN (0x4) - *(.rodata) - .rodata 0x00000148 0x4 ./src/main.o - 0x0000014c . = ALIGN (0x4) - *(.rodata*) - 0x0000014c . = ALIGN (0x4) - *(.glue_7t) - .glue_7t 0x0000014c 0x0 ./src/crt.o - .glue_7t 0x0000014c 0x0 ./src/main.o - 0x0000014c . = ALIGN (0x4) - *(.glue_7) - .glue_7 0x0000014c 0x0 ./src/crt.o - .glue_7 0x0000014c 0x0 ./src/main.o - 0x0000014c . = ALIGN (0x4) - 0x0000014c etext = . - -.vfp11_veneer 0x00000000 0x0 - .vfp11_veneer 0x00000000 0x0 ./src/crt.o - .vfp11_veneer 0x00000000 0x0 ./src/main.o - -.data 0x0000014c 0x0 - 0x0000014c PROVIDE (__data_start, .) - *(.data) - .data 0x0000014c 0x0 ./src/crt.o - .data 0x0000014c 0x0 ./src/main.o - 0x0000014c . = ALIGN (0x4) - 0x0000014c edata = . - 0x0000014c _edata = . - 0x0000014c PROVIDE (__data_end, .) - -.bss 0x0000014c 0x8b4 - 0x0000014c PROVIDE (__bss_start, .) - *(.bss) - .bss 0x0000014c 0x0 ./src/crt.o - .bss 0x0000014c 0x0 ./src/main.o - *(COMMON) - 0x0000014c . = ALIGN (0x4) - 0x0000014c PROVIDE (__bss_end, .) - 0x00000200 . = ALIGN (0x100) - *fill* 0x0000014c 0xb4 00 - 0x00000200 PROVIDE (__stack_start, .) - 0x00000200 PROVIDE (__stack_fiq_start, .) - 0x00000300 . = (. + FIQ_STACK_SIZE) - *fill* 0x00000200 0x100 00 - 0x00000300 . = ALIGN (0x4) - 0x00000300 PROVIDE (__stack_fiq_end, .) - 0x00000300 PROVIDE (__stack_irq_start, .) - 0x00000400 . = (. + IRQ_STACK_SIZE) - *fill* 0x00000300 0x100 00 - 0x00000400 . = ALIGN (0x4) - 0x00000400 PROVIDE (__stack_irq_end, .) - 0x00000400 PROVIDE (__stack_abt_start, .) - 0x00000500 . = (. + ABT_STACK_SIZE) - *fill* 0x00000400 0x100 00 - 0x00000500 . = ALIGN (0x4) - 0x00000500 PROVIDE (__stack_abt_end, .) - 0x00000500 PROVIDE (__stack_und_start, .) - 0x00000600 . = (. + UND_STACK_SIZE) - *fill* 0x00000500 0x100 00 - 0x00000600 . = ALIGN (0x4) - 0x00000600 PROVIDE (__stack_und_end, .) - 0x00000600 PROVIDE (__stack_svc_start, .) - 0x00000a00 . = (. + SVC_STACK_SIZE) - *fill* 0x00000600 0x400 00 - 0x00000a00 . = ALIGN (0x4) - 0x00000a00 PROVIDE (__stack_svc_end, .) - 0x00000a00 PROVIDE (__stack_end, .) - 0x00000a00 PROVIDE (__heap_start, .) -OUTPUT(test_ram.elf elf32-littlearm) - -.ARM.attributes - 0x00000000 0x10 - .ARM.attributes - 0x00000000 0x10 ./src/crt.o - .ARM.attributes - 0x00000010 0x10 ./src/main.o - -.debug_line 0x00000000 0xc8 - .debug_line 0x00000000 0x71 ./src/crt.o - .debug_line 0x00000071 0x57 ./src/main.o - -.debug_info 0x00000000 0x208 - .debug_info 0x00000000 0x77 ./src/crt.o - .debug_info 0x00000077 0x191 ./src/main.o - -.debug_abbrev 0x00000000 0x76 - .debug_abbrev 0x00000000 0x12 ./src/crt.o - .debug_abbrev 0x00000012 0x64 ./src/main.o - -.debug_aranges 0x00000000 0x48 - .debug_aranges - 0x00000000 0x28 ./src/crt.o - .debug_aranges - 0x00000028 0x20 ./src/main.o - -.debug_ranges 0x00000000 0x20 - .debug_ranges 0x00000000 0x20 ./src/crt.o - -.debug_frame 0x00000000 0x24 - .debug_frame 0x00000000 0x24 ./src/main.o - -.debug_loc 0x00000000 0x1f - .debug_loc 0x00000000 0x1f ./src/main.o - -.debug_pubnames - 0x00000000 0x1b - .debug_pubnames - 0x00000000 0x1b ./src/main.o - -.comment 0x00000000 0x12 - .comment 0x00000000 0x12 ./src/main.o - -Cross Reference Table - -Symbol File -DAbortHandler ./src/crt.o -ExitFunction ./src/crt.o -FIQHandler ./src/crt.o -IRQHandler ./src/crt.o -PAbortHandler ./src/crt.o -ResetHandler ./src/crt.o -UndefHandler ./src/crt.o -__bss_end ./src/crt.o -__bss_start ./src/crt.o -__stack_abt_end ./src/crt.o -__stack_fiq_end ./src/crt.o -__stack_irq_end ./src/crt.o -__stack_svc_end ./src/crt.o -__stack_und_end ./src/crt.o -main ./src/main.o - ./src/crt.o diff --git a/testing/examples/LPC2148Test/inc/typedefs.h b/testing/examples/LPC2148Test/inc/typedefs.h deleted file mode 100644 index 42136426a..000000000 --- a/testing/examples/LPC2148Test/inc/typedefs.h +++ /dev/null @@ -1,50 +0,0 @@ -/**************************************************************************** -* Copyright (c) 2006 by Michael Fischer. All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* 1. Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the author nor the names of its contributors may -* be used to endorse or promote products derived from this software -* without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -* THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS -* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED -* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF -* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -* SUCH DAMAGE. -* -**************************************************************************** -* History: -* -* 30.03.06 mifi First Version for Insight tutorial -****************************************************************************/ -#ifndef __TYPEDEFS_H__ -#define __TYPEDEFS_H__ - -/* - * Some types to use Windows like source - */ -typedef char CHAR; /* 8-bit signed data */ -typedef unsigned char BYTE; /* 8-bit unsigned data */ -typedef unsigned short WORD; /* 16-bit unsigned data */ -typedef long LONG; /* 32-bit signed data */ -typedef unsigned long ULONG; /* 32-bit unsigned data */ -typedef unsigned long DWORD; /* 32-bit unsigned data */ - - -#endif /* !__TYPEDEFS_H_ */ -/*** EOF ***/ diff --git a/testing/examples/LPC2148Test/makefile b/testing/examples/LPC2148Test/makefile deleted file mode 100644 index 3a098c33b..000000000 --- a/testing/examples/LPC2148Test/makefile +++ /dev/null @@ -1,147 +0,0 @@ -############################################################################################## -# -# !!!! Do NOT edit this makefile with an editor which replace tabs by spaces !!!! -# -############################################################################################## -# -# On command line: -# -# make all = Create project -# -# make clean = Clean project files. -# -# To rebuild project do "make clean" and "make all". -# - -############################################################################################## -# Start of default section -# - -TRGT = arm-elf- -CC = $(TRGT)gcc -CP = $(TRGT)objcopy -AS = $(TRGT)gcc -x assembler-with-cpp -BIN = $(CP) -O ihex - -MCU = arm7tdmi - -# List all default C defines here, like -D_DEBUG=1 -DDEFS = - -# List all default ASM defines here, like -D_DEBUG=1 -DADEFS = - -# List all default directories to look for include files here -DINCDIR = - -# List the default directory to look for the libraries here -DLIBDIR = - -# List all default libraries here -DLIBS = - -# -# End of default section -############################################################################################## - -############################################################################################## -# Start of user section -# - -# Define project name here -PROJECT = test - -# Define linker script file here -LDSCRIPT_RAM = ./prj/lpc2148_ram.ld -LDSCRIPT_ROM = ./prj/lpc2148_rom.ld - -# List all user C define here, like -D_DEBUG=1 -UDEFS = - -# Define ASM defines here -UADEFS = - -# List C source files here -SRC = ./src/main.c - -# List ASM source files here -ASRC = ./src/crt.s - -# List all user directories here -UINCDIR = ./inc - -# List the user directory to look for the libraries here -ULIBDIR = - -# List all user libraries here -ULIBS = - -# Define optimisation level here -OPT = -O0 - -# -# End of user defines -############################################################################################## - - -INCDIR = $(patsubst %,-I%,$(DINCDIR) $(UINCDIR)) -LIBDIR = $(patsubst %,-L%,$(DLIBDIR) $(ULIBDIR)) -DEFS = $(DDEFS) $(UDEFS) -ADEFS = $(DADEFS) $(UADEFS) -OBJS = $(ASRC:.s=.o) $(SRC:.c=.o) -LIBS = $(DLIBS) $(ULIBS) -MCFLAGS = -mcpu=$(MCU) - -ASFLAGS = $(MCFLAGS) -g -gdwarf-2 -Wa,-amhls=$(<:.s=.lst) $(ADEFS) -CPFLAGS = $(MCFLAGS) $(OPT) -gdwarf-2 -mthumb-interwork -fomit-frame-pointer -Wall -Wstrict-prototypes -fverbose-asm -Wa,-ahlms=$(<:.c=.lst) $(DEFS) -LDFLAGS_RAM = $(MCFLAGS) -nostartfiles -T$(LDSCRIPT_RAM) -Wl,-Map=$(PROJECT)_ram.map,--cref,--no-warn-mismatch $(LIBDIR) -LDFLAGS_ROM = $(MCFLAGS) -nostartfiles -T$(LDSCRIPT_ROM) -Wl,-Map=$(PROJECT)_rom.map,--cref,--no-warn-mismatch $(LIBDIR) - -# Generate dependency information -CPFLAGS += -MD -MP -MF .dep/$(@F).d - -# -# makefile rules -# - -all: RAM ROM - -RAM: $(OBJS) $(PROJECT)_ram.elf $(PROJECT)_ram.hex - -ROM: $(OBJS) $(PROJECT)_rom.elf $(PROJECT)_rom.hex - -%o : %c - $(CC) -c $(CPFLAGS) -I . $(INCDIR) $< -o $@ - -%o : %s - $(AS) -c $(ASFLAGS) $< -o $@ - -%ram.elf: $(OBJS) - $(CC) $(OBJS) $(LDFLAGS_RAM) $(LIBS) -o $@ - -%rom.elf: $(OBJS) - $(CC) $(OBJS) $(LDFLAGS_ROM) $(LIBS) -o $@ - -%hex: %elf - $(BIN) $< $@ - -clean: - -rm -f $(OBJS) - -rm -f $(PROJECT)_ram.elf - -rm -f $(PROJECT)_ram.map - -rm -f $(PROJECT)_ram.hex - -rm -f $(PROJECT)_rom.elf - -rm -f $(PROJECT)_rom.map - -rm -f $(PROJECT)_rom.hex - -rm -f $(SRC:.c=.c.bak) - -rm -f $(SRC:.c=.lst) - -rm -f $(ASRC:.s=.s.bak) - -rm -f $(ASRC:.s=.lst) - -rm -fR .dep - -# -# Include the dependency files, should be the last of the makefile -# --include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*) - -# *** EOF *** \ No newline at end of file diff --git a/testing/examples/LPC2148Test/prj/eclipse_ram.gdb b/testing/examples/LPC2148Test/prj/eclipse_ram.gdb deleted file mode 100644 index 4f423124d..000000000 --- a/testing/examples/LPC2148Test/prj/eclipse_ram.gdb +++ /dev/null @@ -1,11 +0,0 @@ -target remote localhost:3333 -monitor reset -monitor sleep 500 -monitor poll -monitor soft_reset_halt -monitor arm7_9 sw_bkpts enable -monitor mww 0xE01FC040 0x0002 -monitor mdw 0xE01FC040 -load -break main -continue \ No newline at end of file diff --git a/testing/examples/LPC2148Test/prj/eclipse_rom.gdb b/testing/examples/LPC2148Test/prj/eclipse_rom.gdb deleted file mode 100644 index 86780056d..000000000 --- a/testing/examples/LPC2148Test/prj/eclipse_rom.gdb +++ /dev/null @@ -1,11 +0,0 @@ -target remote localhost:3333 -monitor reset -monitor sleep 500 -monitor poll -monitor soft_reset_halt -monitor arm7_9 force_hw_bkpts enable -monitor mww 0xE01FC040 0x0002 -monitor mdw 0xE01FC040 -load -break main -continue \ No newline at end of file diff --git a/testing/examples/LPC2148Test/prj/lpc2148_jtagkey.cfg b/testing/examples/LPC2148Test/prj/lpc2148_jtagkey.cfg deleted file mode 100644 index c73765d92..000000000 --- a/testing/examples/LPC2148Test/prj/lpc2148_jtagkey.cfg +++ /dev/null @@ -1,34 +0,0 @@ -#daemon configuration -telnet_port 4444 -gdb_port 3333 - -# tell gdb our flash memory map -# and enable flash programming -gdb_memory_map enable -gdb_flash_program enable - -#interface -interface ft2232 -ft2232_device_desc "Amontec JTAGkey A" -ft2232_layout jtagkey -ft2232_vid_pid 0x0403 0xcff8 -jtag_speed 3 - -#use combined on interfaces or targets that can't set TRST/SRST separately -reset_config trst_and_srst srst_pulls_trst - -#jtag scan chain -jtag newtap lpc cpu -irlen 4 -irmask 0xf - -#target configuration -target create target0 arm7tdmi -endian little -chain-position 0 -[new_target_name] configure -work-area-virt 0 -work-area-phys 0x40000000 -work-area-size 0x4000 -work-area-backup false - -#flash bank lpc2000 0 0 -flash bank lpc2000 0x0 0x7d000 0 0 0 lpc2000_v2 14765 calc_checksum - -# For more information about the configuration files, -# look at the OpenOCD User's Guide. - -init -reset halt diff --git a/testing/examples/LPC2148Test/prj/lpc2148_ram.ld b/testing/examples/LPC2148Test/prj/lpc2148_ram.ld deleted file mode 100644 index b7951342d..000000000 --- a/testing/examples/LPC2148Test/prj/lpc2148_ram.ld +++ /dev/null @@ -1,140 +0,0 @@ -/**************************************************************************** -* Copyright (c) 2006 by Michael Fischer. All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* 1. Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the author nor the names of its contributors may -* be used to endorse or promote products derived from this software -* without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -* THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS -* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED -* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF -* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -* SUCH DAMAGE. -* -**************************************************************************** -* -* History: -* -* 18.12.06 mifi First Version -****************************************************************************/ - - -ENTRY(ResetHandler) -SEARCH_DIR(.) - -/* - * Define stack size here - */ -FIQ_STACK_SIZE = 0x0100; -IRQ_STACK_SIZE = 0x0100; -ABT_STACK_SIZE = 0x0100; -UND_STACK_SIZE = 0x0100; -SVC_STACK_SIZE = 0x0400; - -/* - * This file, olimex_lpcp2148_ram.ld, locate the program in the internal - * ram of the LPC2148. For more information about the memory of the LPC2148 - * take a look in the LPC2141/2142/2144/2146/2148 USER MANUAL. - * Reference is made to the user manual from 25 July 2006 Rev. 02 - * - * Take a look at page 8, section 1.Memory maps - */ - -MEMORY -{ - ram : org = 0x40000000, len = 32k -} - -/* - * Do not change the next code - */ -SECTIONS -{ - .text : - { - *(.vectors); - . = ALIGN(4); - *(.init); - . = ALIGN(4); - *(.text); - . = ALIGN(4); - *(.rodata); - . = ALIGN(4); - *(.rodata*); - . = ALIGN(4); - *(.glue_7t); - . = ALIGN(4); - *(.glue_7); - . = ALIGN(4); - etext = .; - } > ram - - .data : - { - PROVIDE (__data_start = .); - *(.data) - . = ALIGN(4); - edata = .; - _edata = .; - PROVIDE (__data_end = .); - } > ram - - .bss : - { - PROVIDE (__bss_start = .); - *(.bss) - *(COMMON) - . = ALIGN(4); - PROVIDE (__bss_end = .); - - . = ALIGN(256); - - PROVIDE (__stack_start = .); - - PROVIDE (__stack_fiq_start = .); - . += FIQ_STACK_SIZE; - . = ALIGN(4); - PROVIDE (__stack_fiq_end = .); - - PROVIDE (__stack_irq_start = .); - . += IRQ_STACK_SIZE; - . = ALIGN(4); - PROVIDE (__stack_irq_end = .); - - PROVIDE (__stack_abt_start = .); - . += ABT_STACK_SIZE; - . = ALIGN(4); - PROVIDE (__stack_abt_end = .); - - PROVIDE (__stack_und_start = .); - . += UND_STACK_SIZE; - . = ALIGN(4); - PROVIDE (__stack_und_end = .); - - PROVIDE (__stack_svc_start = .); - . += SVC_STACK_SIZE; - . = ALIGN(4); - PROVIDE (__stack_svc_end = .); - PROVIDE (__stack_end = .); - PROVIDE (__heap_start = .); - } > ram - -} -/*** EOF ***/ - diff --git a/testing/examples/LPC2148Test/prj/lpc2148_rom.ld b/testing/examples/LPC2148Test/prj/lpc2148_rom.ld deleted file mode 100644 index 5844fffce..000000000 --- a/testing/examples/LPC2148Test/prj/lpc2148_rom.ld +++ /dev/null @@ -1,141 +0,0 @@ -/**************************************************************************** -* Copyright (c) 2006 by Michael Fischer. All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* 1. Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the author nor the names of its contributors may -* be used to endorse or promote products derived from this software -* without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -* THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS -* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED -* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF -* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -* SUCH DAMAGE. -* -**************************************************************************** -* -* History: -* -* 26.01.08 mifi First Version -****************************************************************************/ - - -ENTRY(ResetHandler) -SEARCH_DIR(.) - -/* - * Define stack size here - */ -FIQ_STACK_SIZE = 0x0100; -IRQ_STACK_SIZE = 0x0100; -ABT_STACK_SIZE = 0x0100; -UND_STACK_SIZE = 0x0100; -SVC_STACK_SIZE = 0x0400; - -/* - * This file, olimex_lpcp2148_ram.ld, locate the program in the internal - * ram of the LPC2148. For more information about the memory of the LPC2148 - * take a look in the LPC2141/2142/2144/2146/2148 USER MANUAL. - * Reference is made to the user manual from 25 July 2006 Rev. 02 - * - * Take a look at page 8, section 1.Memory maps - */ - -MEMORY -{ - rom : org = 0x00000000, len = 512k - ram : org = 0x40000000, len = 32k -} - -/* - * Do not change the next code - */ -SECTIONS -{ - .text : - { - *(.vectors); - . = ALIGN(4); - *(.init); - . = ALIGN(4); - *(.text); - . = ALIGN(4); - *(.rodata); - . = ALIGN(4); - *(.rodata*); - . = ALIGN(4); - *(.glue_7t); - . = ALIGN(4); - *(.glue_7); - . = ALIGN(4); - etext = .; - } > rom - - .data : - { - PROVIDE (__data_start = .); - *(.data) - . = ALIGN(4); - edata = .; - _edata = .; - PROVIDE (__data_end = .); - } > ram - - .bss : - { - PROVIDE (__bss_start = .); - *(.bss) - *(COMMON) - . = ALIGN(4); - PROVIDE (__bss_end = .); - - . = ALIGN(256); - - PROVIDE (__stack_start = .); - - PROVIDE (__stack_fiq_start = .); - . += FIQ_STACK_SIZE; - . = ALIGN(4); - PROVIDE (__stack_fiq_end = .); - - PROVIDE (__stack_irq_start = .); - . += IRQ_STACK_SIZE; - . = ALIGN(4); - PROVIDE (__stack_irq_end = .); - - PROVIDE (__stack_abt_start = .); - . += ABT_STACK_SIZE; - . = ALIGN(4); - PROVIDE (__stack_abt_end = .); - - PROVIDE (__stack_und_start = .); - . += UND_STACK_SIZE; - . = ALIGN(4); - PROVIDE (__stack_und_end = .); - - PROVIDE (__stack_svc_start = .); - . += SVC_STACK_SIZE; - . = ALIGN(4); - PROVIDE (__stack_svc_end = .); - PROVIDE (__stack_end = .); - PROVIDE (__heap_start = .); - } > ram - -} -/*** EOF ***/ - diff --git a/testing/examples/LPC2148Test/src/crt.s b/testing/examples/LPC2148Test/src/crt.s deleted file mode 100644 index 774f6b4ae..000000000 --- a/testing/examples/LPC2148Test/src/crt.s +++ /dev/null @@ -1,189 +0,0 @@ -/**************************************************************************** -* Copyright (c) 2006 by Michael Fischer. All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* 1. Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the author nor the names of its contributors may -* be used to endorse or promote products derived from this software -* without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -* THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS -* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED -* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF -* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -* SUCH DAMAGE. -* -**************************************************************************** -* -* History: -* -* 31.03.06 mifi First Version -* This version based on an example from Ethernut and -* "ARM Cross Development with Eclipse" from James P. Lynch -****************************************************************************/ - -/* - * Some defines for the program status registers - */ - ARM_MODE_USER = 0x10 /* Normal User Mode */ - ARM_MODE_FIQ = 0x11 /* FIQ Fast Interrupts Mode */ - ARM_MODE_IRQ = 0x12 /* IRQ Standard Interrupts Mode */ - ARM_MODE_SVC = 0x13 /* Supervisor Interrupts Mode */ - ARM_MODE_ABORT = 0x17 /* Abort Processing memory Faults Mode */ - ARM_MODE_UNDEF = 0x1B /* Undefined Instructions Mode */ - ARM_MODE_SYS = 0x1F /* System Running in Priviledged Operating Mode */ - ARM_MODE_MASK = 0x1F - - I_BIT = 0x80 /* disable IRQ when I bit is set */ - F_BIT = 0x40 /* disable IRQ when I bit is set */ - -/* - * Register Base Address - */ - - .section .vectors,"ax" - .code 32 - -/****************************************************************************/ -/* Vector table and reset entry */ -/****************************************************************************/ -_vectors: - ldr pc, ResetAddr /* Reset */ - ldr pc, UndefAddr /* Undefined instruction */ - ldr pc, SWIAddr /* Software interrupt */ - ldr pc, PAbortAddr /* Prefetch abort */ - ldr pc, DAbortAddr /* Data abort */ - .word 0xB8A06F60 - ldr pc, IRQAddr /* IRQ interrupt */ - ldr pc, FIQAddr /* FIQ interrupt */ - - -ResetAddr: .word ResetHandler -UndefAddr: .word UndefHandler -SWIAddr: .word SWIHandler -PAbortAddr: .word PAbortHandler -DAbortAddr: .word DAbortHandler -ReservedAddr: .word 0 -IRQAddr: .word IRQHandler -FIQAddr: .word FIQHandler - - .ltorg - - - .section .init, "ax" - .code 32 - - .global ResetHandler - .global ExitFunction - .extern main -/****************************************************************************/ -/* Reset handler */ -/****************************************************************************/ -ResetHandler: -/* - * Wait for the oscillator is stable - */ - nop - nop - nop - nop - nop - nop - nop - nop - - /* - * Setup a stack for each mode - */ - msr CPSR_c, #ARM_MODE_UNDEF | I_BIT | F_BIT /* Undefined Instruction Mode */ - ldr sp, =__stack_und_end - - msr CPSR_c, #ARM_MODE_ABORT | I_BIT | F_BIT /* Abort Mode */ - ldr sp, =__stack_abt_end - - msr CPSR_c, #ARM_MODE_FIQ | I_BIT | F_BIT /* FIQ Mode */ - ldr sp, =__stack_fiq_end - - msr CPSR_c, #ARM_MODE_IRQ | I_BIT | F_BIT /* IRQ Mode */ - ldr sp, =__stack_irq_end - - msr CPSR_c, #ARM_MODE_SVC | I_BIT | F_BIT /* Supervisor Mode */ - ldr sp, =__stack_svc_end - - - /* - * Clear .bss section - */ - ldr r1, =__bss_start - ldr r2, =__bss_end - ldr r3, =0 -bss_clear_loop: - cmp r1, r2 - strne r3, [r1], #+4 - bne bss_clear_loop - - - /* - * Jump to main - */ - mrs r0, cpsr - bic r0, r0, #I_BIT | F_BIT /* Enable FIQ and IRQ interrupt */ - msr cpsr, r0 - - mov r0, #0 /* No arguments */ - mov r1, #0 /* No arguments */ - ldr r2, =main - mov lr, pc - bx r2 /* And jump... */ - -ExitFunction: - nop - nop - nop - b ExitFunction - - -/****************************************************************************/ -/* Default interrupt handler */ -/****************************************************************************/ - -UndefHandler: - b UndefHandler - -SWIHandler: - b SWIHandler - -PAbortHandler: - b PAbortHandler - -DAbortHandler: - b DAbortHandler - -IRQHandler: - b IRQHandler - -FIQHandler: - b FIQHandler - - .weak ExitFunction - .weak UndefHandler, PAbortHandler, DAbortHandler - .weak IRQHandler, FIQHandler - - .ltorg -/*** EOF ***/ - - diff --git a/testing/examples/LPC2148Test/src/main.c b/testing/examples/LPC2148Test/src/main.c deleted file mode 100644 index 801c72747..000000000 --- a/testing/examples/LPC2148Test/src/main.c +++ /dev/null @@ -1,93 +0,0 @@ -/**************************************************************************** -* Copyright (c) 2006 by Michael Fischer. All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* 1. Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the author nor the names of its contributors may -* be used to endorse or promote products derived from this software -* without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -* THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS -* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED -* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF -* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -* SUCH DAMAGE. -* -**************************************************************************** -* History: -* -* 30.03.06 mifi First Version for Insight tutorial -* 26.01.08 mifi Added variable "d" to test const variable. -****************************************************************************/ -#define __MAIN_C__ - -/* - * I use the include only, to show - * how to setup a include dir in the makefile - */ -#include -#include -#include "typedefs.h" - -/*=========================================================================*/ -/* DEFINE: All Structures and Common Constants */ -/*=========================================================================*/ - -/*=========================================================================*/ -/* DEFINE: Prototypes */ -/*=========================================================================*/ - -/*=========================================================================*/ -/* DEFINE: Definition of all local Data */ -/*=========================================================================*/ -static const DWORD d = 7; - -/*=========================================================================*/ -/* DEFINE: Definition of all local Procedures */ -/*=========================================================================*/ - -/*=========================================================================*/ -/* DEFINE: All code exported */ -/*=========================================================================*/ -/***************************************************************************/ -/* main */ -/***************************************************************************/ -int main (void) -{ - DWORD a = 1; - DWORD b = 2; - DWORD c = 0; - - a = a + d; - - while (1) - { - a++; - b++; - c = a + b; - } - - /* - * This return here make no sense. - * But to prevent the compiler warning: - * "return type of 'main' is not 'int' - * we use an int as return :-) - */ - return(0); -} - -/*** EOF ***/ diff --git a/testing/examples/LPC2148Test/test_ram.elf b/testing/examples/LPC2148Test/test_ram.elf deleted file mode 100644 index a1453ff6c87cb197218db37ec9b1929ccbf5bbcf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 36650 zcmeH~U5p!7701tvKh|V7iIY^Nq6l1R35f)@6SmP35R9`QiIq*#taph(M$Xut-L>K! zFXP!|SER6Qpj1eyRMEFmWub3x!FTX)0`=SrL`l>WltKG3O4EMT zPuplzVdOM9VIR>5w`}u8Ob7@8As_^VfDjM@LO=)z0U;m+gn$qb0zyCt2mv7=1cZPP z5CTF#2nYcoAOwVf5D)@FKnMr{As_^VfDjM@LO=)z0U;m+gn$qb0zyCt2mv7=1cZPP z5CTF#2nYcoAOwVf5D)@FKnMr{As_^VfDjM@LO=)z0U;m+gn$qb0zyCt2mv7=1cZPP z5CTF#2nYcoAOwVf5D)@FKnMr{As_^VfDjM@LO=)z0U;m+gn$qb0zyCt2mv7=1cZPP z5CTF#2nYcoAOwWK{}+KL9^AS=T&}iuexutQBIgduyC{D_c@Kr}a2NFl%HO$1^vUI~ z51!h)e&^QxyQnu&{}FYF`cJ6WQ2!Zq6Lm9 zxA*A5ah_+7(mQ+S5O;8Q=icFN?xDFq>~{b0@h22YV%-Up7)l&vA304cDk;=scP_kd zVQ$Lbyl9T)y`=k%NjS%%-RL`lyMsxrUGFSKWr6t?~Tf)|yxM zmfG1Bq`?w4Ba8h3^PWFH_p9aQ8+IJ)SyRJuKwK@FJ={nxx{s;T<=WQr_ZxnBrM2pn zSC<;?+KLyHTWg-*s@2P3uW22W3(Du-S>Z1~G%Z_`~}YkKYS+%r=rPfScMpqz%%KRb@n)eeK|~4$vPML zn@MbjV&q?^WSy+9zKEbijG2sZJ6VS)om@=DQctG7kUGM9+&W~z8|9Wm)?q81#Hiym zI{FPX5yc`G8|HC}rB082ZM1j0t0*=-8@0p#w9>qUm%!{4ih3B(L}#a_PG^o`BOmYWW6HL-RztUnIt-$E zMSG#Q8B(^|Zd0}}e}j-K(xISDFpq(|*HWYH8oCRs(ONuL9R!9wa@i zmI8ORKSr}v(@AUVRUbW=s@7Uv^|06edwUY0yj!pr*c{p>!ne3@`UyUT7HkrHvQ@v+ ze2(Z9Zs?g#ISP#!{`@H8IQ?9>LC2jkd~UyvINtx-ble#6{w=!Zl4r_h;xibcH7#tr={^f5!f z4*exVzX_c;^lzabGc?ctgrVPpo;39Dp}%fu&d(V79q4xreHVJd&^*3l=ntS@F*J|& zcSHXZT3Z}^{tdB${T4@!-wWb+)~H|>@%Sl2bAR2?A4Oq&#e2}{j$)%@4G!xJ@*juh zb1dsL*>n_|&*-eVe**fpp$i<(=U*7dUxwE21M4f?&jrTwEx~ts`Dt{thvJ{*SUy+7 zIR7SVE-=pj1^oAV`MjPtpa=6=^y`PTO>aRnkE_VX`IdeMtzSbP@6J&CUGC=srF3E;{_XDUA5!1P^mRNH>fmQtu=kd zuM_errG>)O`AVtyof(!oy;5n1ZtYs7y-}-pex0Hv=-!#lMmW3f*TP22Cmp)f_?`;& z>Tc-r(#)aN?dkMNg%`xb>fCj|u5{tdf|(WFtxogQ(I-mA>VhyjLg8_kIhAOBJP5ND W%hAIqzFO!7G=gaHTD#RyE$BbPrqV_L diff --git a/testing/examples/LPC2148Test/test_ram.hex b/testing/examples/LPC2148Test/test_ram.hex deleted file mode 100644 index 6caf035ae..000000000 --- a/testing/examples/LPC2148Test/test_ram.hex +++ /dev/null @@ -1,26 +0,0 @@ -:020000044000BA -:1000000018F09FE518F09FE518F09FE518F09FE5C0 -:1000100018F09FE5606FA0B818F09FE518F09FE515 -:1000200040000040D0000040D4000040D800004014 -:10003000DC00004000000000E0000040E400004060 -:100040000000A0E10000A0E10000A0E10000A0E1AC -:100050000000A0E10000A0E10000A0E10000A0E19C -:10006000DBF021E37CD09FE5D7F021E378D09FE55A -:10007000D1F021E374D09FE5D2F021E370D09FE569 -:10008000D3F021E36CD09FE56C109FE56C209FE5D9 -:100090000030A0E3020051E104308114FCFFFF1A9C -:1000A00000000FE1C000C0E300F029E10000A0E380 -:1000B0000010A0E348209FE50FE0A0E112FF2FE130 -:1000C0000000A0E10000A0E10000A0E1FBFFFFEACA -:1000D000FEFFFFEAFEFFFFEAFEFFFFEAFEFFFFEA88 -:1000E000FEFFFFEAFEFFFFEA0006004000050040B9 -:1000F0000003004000040040000A00406C01004082 -:100100006C010040080100400CD04DE20130A0E33A -:1001100000308DE50230A0E304308DE50030A0E32F -:1001200008308DE538309FE5002093E500309DE5EF -:10013000023083E000308DE500309DE5013083E240 -:1001400000308DE504309DE5013083E204308DE51B -:1001500000209DE504309DE5033082E008308DE508 -:0C016000F4FFFFEA680100400700000007 -:040000054000004077 -:00000001FF diff --git a/testing/examples/LPC2148Test/test_ram.map b/testing/examples/LPC2148Test/test_ram.map deleted file mode 100644 index 73d4e7209..000000000 --- a/testing/examples/LPC2148Test/test_ram.map +++ /dev/null @@ -1,170 +0,0 @@ - -Memory Configuration - -Name Origin Length Attributes -ram 0x40000000 0x00008000 -*default* 0x00000000 0xffffffff - -Linker script and memory map - -LOAD ./src/crt.o -LOAD ./src/main.o -START GROUP -LOAD d:/compiler/yagarto/bin/../lib/gcc/arm-elf/4.2.2\libgcc.a -LOAD d:/compiler/yagarto/bin/../lib/gcc/arm-elf/4.2.2/../../../../arm-elf/lib\libc.a -END GROUP - 0x00000100 FIQ_STACK_SIZE = 0x100 - 0x00000100 IRQ_STACK_SIZE = 0x100 - 0x00000100 ABT_STACK_SIZE = 0x100 - 0x00000100 UND_STACK_SIZE = 0x100 - 0x00000400 SVC_STACK_SIZE = 0x400 - -.text 0x40000000 0x16c - *(.vectors) - .vectors 0x40000000 0x40 ./src/crt.o - 0x40000040 . = ALIGN (0x4) - *(.init) - .init 0x40000040 0xc8 ./src/crt.o - 0x400000e4 FIQHandler - 0x400000d8 PAbortHandler - 0x400000c0 ExitFunction - 0x40000040 ResetHandler - 0x400000dc DAbortHandler - 0x400000e0 IRQHandler - 0x400000d0 UndefHandler - 0x40000108 . = ALIGN (0x4) - *(.text) - .text 0x40000108 0x0 ./src/crt.o - .text 0x40000108 0x60 ./src/main.o - 0x40000108 main - 0x40000168 . = ALIGN (0x4) - *(.rodata) - .rodata 0x40000168 0x4 ./src/main.o - 0x4000016c . = ALIGN (0x4) - *(.rodata*) - 0x4000016c . = ALIGN (0x4) - *(.glue_7t) - .glue_7t 0x4000016c 0x0 ./src/crt.o - .glue_7t 0x4000016c 0x0 ./src/main.o - 0x4000016c . = ALIGN (0x4) - *(.glue_7) - .glue_7 0x4000016c 0x0 ./src/crt.o - .glue_7 0x4000016c 0x0 ./src/main.o - 0x4000016c . = ALIGN (0x4) - 0x4000016c etext = . - -.vfp11_veneer 0x00000000 0x0 - .vfp11_veneer 0x00000000 0x0 ./src/crt.o - .vfp11_veneer 0x00000000 0x0 ./src/main.o - -.data 0x4000016c 0x0 - 0x4000016c PROVIDE (__data_start, .) - *(.data) - .data 0x4000016c 0x0 ./src/crt.o - .data 0x4000016c 0x0 ./src/main.o - 0x4000016c . = ALIGN (0x4) - 0x4000016c edata = . - 0x4000016c _edata = . - 0x4000016c PROVIDE (__data_end, .) - -.bss 0x4000016c 0x894 - 0x4000016c PROVIDE (__bss_start, .) - *(.bss) - .bss 0x4000016c 0x0 ./src/crt.o - .bss 0x4000016c 0x0 ./src/main.o - *(COMMON) - 0x4000016c . = ALIGN (0x4) - 0x4000016c PROVIDE (__bss_end, .) - 0x40000200 . = ALIGN (0x100) - *fill* 0x4000016c 0x94 00 - 0x40000200 PROVIDE (__stack_start, .) - 0x40000200 PROVIDE (__stack_fiq_start, .) - 0x40000300 . = (. + FIQ_STACK_SIZE) - *fill* 0x40000200 0x100 00 - 0x40000300 . = ALIGN (0x4) - 0x40000300 PROVIDE (__stack_fiq_end, .) - 0x40000300 PROVIDE (__stack_irq_start, .) - 0x40000400 . = (. + IRQ_STACK_SIZE) - *fill* 0x40000300 0x100 00 - 0x40000400 . = ALIGN (0x4) - 0x40000400 PROVIDE (__stack_irq_end, .) - 0x40000400 PROVIDE (__stack_abt_start, .) - 0x40000500 . = (. + ABT_STACK_SIZE) - *fill* 0x40000400 0x100 00 - 0x40000500 . = ALIGN (0x4) - 0x40000500 PROVIDE (__stack_abt_end, .) - 0x40000500 PROVIDE (__stack_und_start, .) - 0x40000600 . = (. + UND_STACK_SIZE) - *fill* 0x40000500 0x100 00 - 0x40000600 . = ALIGN (0x4) - 0x40000600 PROVIDE (__stack_und_end, .) - 0x40000600 PROVIDE (__stack_svc_start, .) - 0x40000a00 . = (. + SVC_STACK_SIZE) - *fill* 0x40000600 0x400 00 - 0x40000a00 . = ALIGN (0x4) - 0x40000a00 PROVIDE (__stack_svc_end, .) - 0x40000a00 PROVIDE (__stack_end, .) - 0x40000a00 PROVIDE (__heap_start, .) -OUTPUT(test_ram.elf elf32-littlearm) - -.ARM.attributes - 0x00000000 0x10 - .ARM.attributes - 0x00000000 0x10 ./src/crt.o - .ARM.attributes - 0x00000010 0x10 ./src/main.o - -.debug_line 0x00000000 0xd0 - .debug_line 0x00000000 0x79 ./src/crt.o - .debug_line 0x00000079 0x57 ./src/main.o - -.debug_info 0x00000000 0x202 - .debug_info 0x00000000 0x74 ./src/crt.o - .debug_info 0x00000074 0x18e ./src/main.o - -.debug_abbrev 0x00000000 0x76 - .debug_abbrev 0x00000000 0x12 ./src/crt.o - .debug_abbrev 0x00000012 0x64 ./src/main.o - -.debug_aranges 0x00000000 0x48 - .debug_aranges - 0x00000000 0x28 ./src/crt.o - .debug_aranges - 0x00000028 0x20 ./src/main.o - -.debug_ranges 0x00000000 0x20 - .debug_ranges 0x00000000 0x20 ./src/crt.o - -.debug_frame 0x00000000 0x24 - .debug_frame 0x00000000 0x24 ./src/main.o - -.debug_loc 0x00000000 0x1f - .debug_loc 0x00000000 0x1f ./src/main.o - -.debug_pubnames - 0x00000000 0x1b - .debug_pubnames - 0x00000000 0x1b ./src/main.o - -.comment 0x00000000 0x12 - .comment 0x00000000 0x12 ./src/main.o - -Cross Reference Table - -Symbol File -DAbortHandler ./src/crt.o -ExitFunction ./src/crt.o -FIQHandler ./src/crt.o -IRQHandler ./src/crt.o -PAbortHandler ./src/crt.o -ResetHandler ./src/crt.o -UndefHandler ./src/crt.o -__bss_end ./src/crt.o -__bss_start ./src/crt.o -__stack_abt_end ./src/crt.o -__stack_fiq_end ./src/crt.o -__stack_irq_end ./src/crt.o -__stack_svc_end ./src/crt.o -__stack_und_end ./src/crt.o -main ./src/main.o - ./src/crt.o diff --git a/testing/examples/LPC2148Test/test_rom.elf b/testing/examples/LPC2148Test/test_rom.elf deleted file mode 100644 index 52be4c065de69745af9cb09b3f3ba1f7ccc789f1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 36650 zcmeH~O>A6O701te^WgzIiIY^Nq6nsvNfQZXCc%wNKrj=3B%?S<PC0K8h&g*L)5pF~&J&!$3#pNOdgn$qb0zyCt2mv7=1cZPP5CTF#2nYcoAOwVf z5D)@FKnMr{As_^VfDjM@LO=)z0U;m+gn$qb0zyCt2mv7=1cZPP5CTF#2nYcoAOwVf z5D)@FKnMr{As_^VfDjM@LO=)z0U;m+gn$qb0zyCt2mv7=1cZPP5CTF#2nYcoAOwVf z5D)@FKnMr{As_^VfDjM@LO=)z0U;m+gn$qb0zyCt2mv7=1cZPP5CTF#2nYcoAOwVf z5D)@FKnMr{As_^VfDjM@Lg4>^z+?As-WzOJnmfNWu{`#88|@vmchTNMW7|dhfF0Vo z`=8oh?mw}2?e@)kchGO5|0DVc{h!dUq5m`b2KvS*TKeWa%I)mAbm?w9_uL~NbvmCV zI&k+E-P)u3$9SDR8r|7Di@F25J9iItvJb5NVW;!=k3XSNobnVybI@G06dLK4a)?H5 zpMT%M+LXI-&qW_c&wELspU7cf>7PNrg5338u3_KFU4Nhbc-L2B(yu5T%RRr#WB-Z$ ztYH2jELJ#xi|2clIynir>u4^e`RaVQe;+w82sEb^R*9-%lxeXfO1OND-6AIoo6Wk1 zP>pDwqkB4v#8^&nH_^`osd zzveHsGAkGcOSp_I_6Mwc?%eFJmzS@*aqMSJP0IywwQ2TnBUybPlcyG|Tg%_82a7As zRey1Hsotut_~Bx6%@3N@+F}&02Uj!UQxhi_Bfk~ZgXKkk(_39@_^rj+rzcMwAD@^< zoX%WWNEb@!6Pe=^`VP#IQ-8j&0Ba06Q4v=4+EO$%;e;$^idq-W8HI1nby{7 z&|B@z(P&o9ptbc%fDD$ZHdj}DoVEYn9!Du7#aYm{P1LX$n>#Fh1vALLI+(jhWm*1iH^mrFKyFnkhnW>bSSC(%UcM_lC{$pUE$y@qO^`>r-g< zd?PoAK5q>)^P%h$E!JC=@>~>qU}e_!3akx9J!Om%+UZ_n{nM)=G4&U|UlLO%*VcR& zeTxxZV3x&b*iyXyh}yAvzYw)M%!S!%Yj^lv*5}{u9D_FRL$2rZ&MzBn?anlu{&Q`2 z=ArxNq22KYbQ5|TOxAwFkgmi`6&qn3UZ{+BHM zI{cia-+=#!rFs3wEd3_@2}}PT{?{$dU(ma3O(jUP8xuto&zghYp zJ)h5RyYnyT6&%hudi=d0u4k>yA)cTAZWzt^nx#MDL|2buzG3*h2evd4k8)0b$KrS5 z(h+F>MrY&vIP@*0v@UQxfB(X`{u1l%Ewa9>^D4;eEkWm%;(CW#1NG0c=I?44kH0Z6 z{+H12aT3P+c@5gU=Xt*0aJ{wuo6yYT3WE5)rQdO$;lX%6w+HI)u+}k^|111mE{5@X zZD{j;XZW@(0(%dN<(UM;sas%1Z@k=}yIPH)zunf0I=)tdpC(xv)$RjFU|B9FIb zPpxjx3@?{?Lp-e+yB^e(E}WjXN9nsY!+iDWqX%PmVWdBy@Hp%-WxYNggdN3p%ruIx R5oQDRP;cI7uM(*Z{Tne4zq|kd diff --git a/testing/examples/LPC2148Test/test_rom.hex b/testing/examples/LPC2148Test/test_rom.hex deleted file mode 100644 index 3ee04ee3c..000000000 --- a/testing/examples/LPC2148Test/test_rom.hex +++ /dev/null @@ -1,25 +0,0 @@ -:1000000018F09FE518F09FE518F09FE518F09FE5C0 -:1000100018F09FE5606FA0B818F09FE518F09FE515 -:1000200040000000D0000000D4000000D800000014 -:10003000DC00000000000000E0000000E400000020 -:100040000000A0E10000A0E10000A0E10000A0E1AC -:100050000000A0E10000A0E10000A0E10000A0E19C -:10006000DBF021E37CD09FE5D7F021E378D09FE55A -:10007000D1F021E374D09FE5D2F021E370D09FE569 -:10008000D3F021E36CD09FE56C109FE56C209FE5D9 -:100090000030A0E3020051E104308114FCFFFF1A9C -:1000A00000000FE1C000C0E300F029E10000A0E380 -:1000B0000010A0E348209FE50FE0A0E112FF2FE130 -:1000C0000000A0E10000A0E10000A0E1FBFFFFEACA -:1000D000FEFFFFEAFEFFFFEAFEFFFFEAFEFFFFEA88 -:1000E000FEFFFFEAFEFFFFEA0004004000030040BD -:1000F00000010040000200400008004000000040F5 -:1001000000000040080100000CD04DE20130A0E3E7 -:1001100000308DE50230A0E304308DE50030A0E32F -:1001200008308DE538309FE5002093E500309DE5EF -:10013000023083E000308DE500309DE5013083E240 -:1001400000308DE504309DE5013083E204308DE51B -:1001500000209DE504309DE5033082E008308DE508 -:0C016000F4FFFFEA680100000700000047 -:0400000300000040B9 -:00000001FF diff --git a/testing/examples/LPC2148Test/test_rom.map b/testing/examples/LPC2148Test/test_rom.map deleted file mode 100644 index b737e200d..000000000 --- a/testing/examples/LPC2148Test/test_rom.map +++ /dev/null @@ -1,170 +0,0 @@ - -Memory Configuration - -Name Origin Length Attributes -rom 0x00000000 0x00080000 -ram 0x40000000 0x00008000 -*default* 0x00000000 0xffffffff - -Linker script and memory map - -LOAD ./src/crt.o -LOAD ./src/main.o -START GROUP -LOAD d:/compiler/yagarto/bin/../lib/gcc/arm-elf/4.2.2\libgcc.a -LOAD d:/compiler/yagarto/bin/../lib/gcc/arm-elf/4.2.2/../../../../arm-elf/lib\libc.a -END GROUP - 0x00000100 FIQ_STACK_SIZE = 0x100 - 0x00000100 IRQ_STACK_SIZE = 0x100 - 0x00000100 ABT_STACK_SIZE = 0x100 - 0x00000100 UND_STACK_SIZE = 0x100 - 0x00000400 SVC_STACK_SIZE = 0x400 - -.text 0x00000000 0x16c - *(.vectors) - .vectors 0x00000000 0x40 ./src/crt.o - 0x00000040 . = ALIGN (0x4) - *(.init) - .init 0x00000040 0xc8 ./src/crt.o - 0x000000e4 FIQHandler - 0x000000d8 PAbortHandler - 0x000000c0 ExitFunction - 0x00000040 ResetHandler - 0x000000dc DAbortHandler - 0x000000e0 IRQHandler - 0x000000d0 UndefHandler - 0x00000108 . = ALIGN (0x4) - *(.text) - .text 0x00000108 0x0 ./src/crt.o - .text 0x00000108 0x60 ./src/main.o - 0x00000108 main - 0x00000168 . = ALIGN (0x4) - *(.rodata) - .rodata 0x00000168 0x4 ./src/main.o - 0x0000016c . = ALIGN (0x4) - *(.rodata*) - 0x0000016c . = ALIGN (0x4) - *(.glue_7t) - .glue_7t 0x0000016c 0x0 ./src/crt.o - .glue_7t 0x0000016c 0x0 ./src/main.o - 0x0000016c . = ALIGN (0x4) - *(.glue_7) - .glue_7 0x0000016c 0x0 ./src/crt.o - .glue_7 0x0000016c 0x0 ./src/main.o - 0x0000016c . = ALIGN (0x4) - 0x0000016c etext = . - -.vfp11_veneer 0x00000000 0x0 - .vfp11_veneer 0x00000000 0x0 ./src/crt.o - .vfp11_veneer 0x00000000 0x0 ./src/main.o - -.data 0x40000000 0x0 - 0x40000000 PROVIDE (__data_start, .) - *(.data) - .data 0x40000000 0x0 ./src/crt.o - .data 0x40000000 0x0 ./src/main.o - 0x40000000 . = ALIGN (0x4) - 0x40000000 edata = . - 0x40000000 _edata = . - 0x40000000 PROVIDE (__data_end, .) - -.bss 0x40000000 0x800 - 0x40000000 PROVIDE (__bss_start, .) - *(.bss) - .bss 0x40000000 0x0 ./src/crt.o - .bss 0x40000000 0x0 ./src/main.o - *(COMMON) - 0x40000000 . = ALIGN (0x4) - 0x40000000 PROVIDE (__bss_end, .) - 0x40000000 . = ALIGN (0x100) - 0x40000000 PROVIDE (__stack_start, .) - 0x40000000 PROVIDE (__stack_fiq_start, .) - 0x40000100 . = (. + FIQ_STACK_SIZE) - *fill* 0x40000000 0x100 00 - 0x40000100 . = ALIGN (0x4) - 0x40000100 PROVIDE (__stack_fiq_end, .) - 0x40000100 PROVIDE (__stack_irq_start, .) - 0x40000200 . = (. + IRQ_STACK_SIZE) - *fill* 0x40000100 0x100 00 - 0x40000200 . = ALIGN (0x4) - 0x40000200 PROVIDE (__stack_irq_end, .) - 0x40000200 PROVIDE (__stack_abt_start, .) - 0x40000300 . = (. + ABT_STACK_SIZE) - *fill* 0x40000200 0x100 00 - 0x40000300 . = ALIGN (0x4) - 0x40000300 PROVIDE (__stack_abt_end, .) - 0x40000300 PROVIDE (__stack_und_start, .) - 0x40000400 . = (. + UND_STACK_SIZE) - *fill* 0x40000300 0x100 00 - 0x40000400 . = ALIGN (0x4) - 0x40000400 PROVIDE (__stack_und_end, .) - 0x40000400 PROVIDE (__stack_svc_start, .) - 0x40000800 . = (. + SVC_STACK_SIZE) - *fill* 0x40000400 0x400 00 - 0x40000800 . = ALIGN (0x4) - 0x40000800 PROVIDE (__stack_svc_end, .) - 0x40000800 PROVIDE (__stack_end, .) - 0x40000800 PROVIDE (__heap_start, .) -OUTPUT(test_rom.elf elf32-littlearm) - -.ARM.attributes - 0x00000000 0x10 - .ARM.attributes - 0x00000000 0x10 ./src/crt.o - .ARM.attributes - 0x00000010 0x10 ./src/main.o - -.debug_line 0x00000000 0xd0 - .debug_line 0x00000000 0x79 ./src/crt.o - .debug_line 0x00000079 0x57 ./src/main.o - -.debug_info 0x00000000 0x202 - .debug_info 0x00000000 0x74 ./src/crt.o - .debug_info 0x00000074 0x18e ./src/main.o - -.debug_abbrev 0x00000000 0x76 - .debug_abbrev 0x00000000 0x12 ./src/crt.o - .debug_abbrev 0x00000012 0x64 ./src/main.o - -.debug_aranges 0x00000000 0x48 - .debug_aranges - 0x00000000 0x28 ./src/crt.o - .debug_aranges - 0x00000028 0x20 ./src/main.o - -.debug_ranges 0x00000000 0x20 - .debug_ranges 0x00000000 0x20 ./src/crt.o - -.debug_frame 0x00000000 0x24 - .debug_frame 0x00000000 0x24 ./src/main.o - -.debug_loc 0x00000000 0x1f - .debug_loc 0x00000000 0x1f ./src/main.o - -.debug_pubnames - 0x00000000 0x1b - .debug_pubnames - 0x00000000 0x1b ./src/main.o - -.comment 0x00000000 0x12 - .comment 0x00000000 0x12 ./src/main.o - -Cross Reference Table - -Symbol File -DAbortHandler ./src/crt.o -ExitFunction ./src/crt.o -FIQHandler ./src/crt.o -IRQHandler ./src/crt.o -PAbortHandler ./src/crt.o -ResetHandler ./src/crt.o -UndefHandler ./src/crt.o -__bss_end ./src/crt.o -__bss_start ./src/crt.o -__stack_abt_end ./src/crt.o -__stack_fiq_end ./src/crt.o -__stack_irq_end ./src/crt.o -__stack_svc_end ./src/crt.o -__stack_und_end ./src/crt.o -main ./src/main.o - ./src/crt.o diff --git a/testing/examples/LPC2294Test/inc/typedefs.h b/testing/examples/LPC2294Test/inc/typedefs.h deleted file mode 100644 index 42136426a..000000000 --- a/testing/examples/LPC2294Test/inc/typedefs.h +++ /dev/null @@ -1,50 +0,0 @@ -/**************************************************************************** -* Copyright (c) 2006 by Michael Fischer. All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* 1. Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the author nor the names of its contributors may -* be used to endorse or promote products derived from this software -* without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -* THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS -* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED -* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF -* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -* SUCH DAMAGE. -* -**************************************************************************** -* History: -* -* 30.03.06 mifi First Version for Insight tutorial -****************************************************************************/ -#ifndef __TYPEDEFS_H__ -#define __TYPEDEFS_H__ - -/* - * Some types to use Windows like source - */ -typedef char CHAR; /* 8-bit signed data */ -typedef unsigned char BYTE; /* 8-bit unsigned data */ -typedef unsigned short WORD; /* 16-bit unsigned data */ -typedef long LONG; /* 32-bit signed data */ -typedef unsigned long ULONG; /* 32-bit unsigned data */ -typedef unsigned long DWORD; /* 32-bit unsigned data */ - - -#endif /* !__TYPEDEFS_H_ */ -/*** EOF ***/ diff --git a/testing/examples/LPC2294Test/makefile b/testing/examples/LPC2294Test/makefile deleted file mode 100644 index 6af02fbe1..000000000 --- a/testing/examples/LPC2294Test/makefile +++ /dev/null @@ -1,147 +0,0 @@ -############################################################################################## -# -# !!!! Do NOT edit this makefile with an editor which replace tabs by spaces !!!! -# -############################################################################################## -# -# On command line: -# -# make all = Create project -# -# make clean = Clean project files. -# -# To rebuild project do "make clean" and "make all". -# - -############################################################################################## -# Start of default section -# - -TRGT = arm-elf- -CC = $(TRGT)gcc -CP = $(TRGT)objcopy -AS = $(TRGT)gcc -x assembler-with-cpp -BIN = $(CP) -O ihex - -MCU = arm7tdmi - -# List all default C defines here, like -D_DEBUG=1 -DDEFS = - -# List all default ASM defines here, like -D_DEBUG=1 -DADEFS = - -# List all default directories to look for include files here -DINCDIR = - -# List the default directory to look for the libraries here -DLIBDIR = - -# List all default libraries here -DLIBS = - -# -# End of default section -############################################################################################## - -############################################################################################## -# Start of user section -# - -# Define project name here -PROJECT = test - -# Define linker script file here -LDSCRIPT_RAM = ./prj/lpc2294_ram.ld -LDSCRIPT_ROM = ./prj/lpc2294_rom.ld - -# List all user C define here, like -D_DEBUG=1 -UDEFS = - -# Define ASM defines here -UADEFS = - -# List C source files here -SRC = ./src/main.c - -# List ASM source files here -ASRC = ./src/crt.s - -# List all user directories here -UINCDIR = ./inc - -# List the user directory to look for the libraries here -ULIBDIR = - -# List all user libraries here -ULIBS = - -# Define optimisation level here -OPT = -O0 - -# -# End of user defines -############################################################################################## - - -INCDIR = $(patsubst %,-I%,$(DINCDIR) $(UINCDIR)) -LIBDIR = $(patsubst %,-L%,$(DLIBDIR) $(ULIBDIR)) -DEFS = $(DDEFS) $(UDEFS) -ADEFS = $(DADEFS) $(UADEFS) -OBJS = $(ASRC:.s=.o) $(SRC:.c=.o) -LIBS = $(DLIBS) $(ULIBS) -MCFLAGS = -mcpu=$(MCU) - -ASFLAGS = $(MCFLAGS) -g -gdwarf-2 -Wa,-amhls=$(<:.s=.lst) $(ADEFS) -CPFLAGS = $(MCFLAGS) $(OPT) -gdwarf-2 -mthumb-interwork -fomit-frame-pointer -Wall -Wstrict-prototypes -fverbose-asm -Wa,-ahlms=$(<:.c=.lst) $(DEFS) -LDFLAGS_RAM = $(MCFLAGS) -nostartfiles -T$(LDSCRIPT_RAM) -Wl,-Map=$(PROJECT)_ram.map,--cref,--no-warn-mismatch $(LIBDIR) -LDFLAGS_ROM = $(MCFLAGS) -nostartfiles -T$(LDSCRIPT_ROM) -Wl,-Map=$(PROJECT)_rom.map,--cref,--no-warn-mismatch $(LIBDIR) - -# Generate dependency information -CPFLAGS += -MD -MP -MF .dep/$(@F).d - -# -# makefile rules -# - -all: RAM ROM - -RAM: $(OBJS) $(PROJECT)_ram.elf $(PROJECT)_ram.hex - -ROM: $(OBJS) $(PROJECT)_rom.elf $(PROJECT)_rom.hex - -%o : %c - $(CC) -c $(CPFLAGS) -I . $(INCDIR) $< -o $@ - -%o : %s - $(AS) -c $(ASFLAGS) $< -o $@ - -%ram.elf: $(OBJS) - $(CC) $(OBJS) $(LDFLAGS_RAM) $(LIBS) -o $@ - -%rom.elf: $(OBJS) - $(CC) $(OBJS) $(LDFLAGS_ROM) $(LIBS) -o $@ - -%hex: %elf - $(BIN) $< $@ - -clean: - -rm -f $(OBJS) - -rm -f $(PROJECT)_ram.elf - -rm -f $(PROJECT)_ram.map - -rm -f $(PROJECT)_ram.hex - -rm -f $(PROJECT)_rom.elf - -rm -f $(PROJECT)_rom.map - -rm -f $(PROJECT)_rom.hex - -rm -f $(SRC:.c=.c.bak) - -rm -f $(SRC:.c=.lst) - -rm -f $(ASRC:.s=.s.bak) - -rm -f $(ASRC:.s=.lst) - -rm -fR .dep - -# -# Include the dependency files, should be the last of the makefile -# --include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*) - -# *** EOF *** \ No newline at end of file diff --git a/testing/examples/LPC2294Test/prj/eclipse_ram.gdb b/testing/examples/LPC2294Test/prj/eclipse_ram.gdb deleted file mode 100644 index 4f423124d..000000000 --- a/testing/examples/LPC2294Test/prj/eclipse_ram.gdb +++ /dev/null @@ -1,11 +0,0 @@ -target remote localhost:3333 -monitor reset -monitor sleep 500 -monitor poll -monitor soft_reset_halt -monitor arm7_9 sw_bkpts enable -monitor mww 0xE01FC040 0x0002 -monitor mdw 0xE01FC040 -load -break main -continue \ No newline at end of file diff --git a/testing/examples/LPC2294Test/prj/eclipse_rom.gdb b/testing/examples/LPC2294Test/prj/eclipse_rom.gdb deleted file mode 100644 index 86780056d..000000000 --- a/testing/examples/LPC2294Test/prj/eclipse_rom.gdb +++ /dev/null @@ -1,11 +0,0 @@ -target remote localhost:3333 -monitor reset -monitor sleep 500 -monitor poll -monitor soft_reset_halt -monitor arm7_9 force_hw_bkpts enable -monitor mww 0xE01FC040 0x0002 -monitor mdw 0xE01FC040 -load -break main -continue \ No newline at end of file diff --git a/testing/examples/LPC2294Test/prj/lpc2294_jtagkey.cfg b/testing/examples/LPC2294Test/prj/lpc2294_jtagkey.cfg deleted file mode 100644 index 77537a22f..000000000 --- a/testing/examples/LPC2294Test/prj/lpc2294_jtagkey.cfg +++ /dev/null @@ -1,35 +0,0 @@ -#daemon configuration -telnet_port 4444 -gdb_port 3333 - -# tell gdb our flash memory map -# and enable flash programming -gdb_memory_map enable -gdb_flash_program enable - -#interface -interface ft2232 -ft2232_device_desc "Amontec JTAGkey A" -ft2232_layout jtagkey -ft2232_vid_pid 0x0403 0xcff8 -jtag_speed 3 - -#use combined on interfaces or targets that can't set TRST/SRST separately -reset_config trst_and_srst srst_pulls_trst - -#jtag scan chain -jtag newtap lpc cpu -irlen 4 -irmask 0xf - -#target configuration -target create target0 arm7tdmi -endian little -chain-position 0 -[new_target_name] configure -work-area-virt 0 -work-area-phys 0x40000000 -work-area-size 0x4000 -work-area-backup false - -#flash configuration -#flash bank lpc2000 0 0 -flash bank lpc2000 0x0 0x40000 0 0 0 lpc2000_v1 14765 calc_checksum - -# For more information about the configuration files, -# look at the OpenOCD User's Guide. - -init -reset halt diff --git a/testing/examples/LPC2294Test/prj/lpc2294_ram.ld b/testing/examples/LPC2294Test/prj/lpc2294_ram.ld deleted file mode 100644 index 17eaedd87..000000000 --- a/testing/examples/LPC2294Test/prj/lpc2294_ram.ld +++ /dev/null @@ -1,140 +0,0 @@ -/**************************************************************************** -* Copyright (c) 2006 by Michael Fischer. All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* 1. Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the author nor the names of its contributors may -* be used to endorse or promote products derived from this software -* without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -* THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS -* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED -* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF -* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -* SUCH DAMAGE. -* -**************************************************************************** -* -* History: -* -* 31.03.06 mifi First Version -****************************************************************************/ - - -ENTRY(ResetHandler) -SEARCH_DIR(.) - -/* - * Define stack size here - */ -FIQ_STACK_SIZE = 0x0100; -IRQ_STACK_SIZE = 0x0100; -ABT_STACK_SIZE = 0x0100; -UND_STACK_SIZE = 0x0100; -SVC_STACK_SIZE = 0x0400; - -/* - * This file, olimex_lpce2294_ram.ld, locate the program in the internal - * ram of the LPC2294. For more information about the memory of the LPC2294 - * take a look in the LPC2119/2129/2194/2292/2294 USER MANUAL. - * Reference is made to the user manual from 2004 May 03 - * - * Take a look at page 48, section 2.Memory Addressing - */ - -MEMORY -{ - ram : org = 0x40000000, len = 16k -} - -/* - * Do not change the next code - */ -SECTIONS -{ - .text : - { - *(.vectors); - . = ALIGN(4); - *(.init); - . = ALIGN(4); - *(.text); - . = ALIGN(4); - *(.rodata); - . = ALIGN(4); - *(.rodata*); - . = ALIGN(4); - *(.glue_7t); - . = ALIGN(4); - *(.glue_7); - . = ALIGN(4); - etext = .; - } > ram - - .data : - { - PROVIDE (__data_start = .); - *(.data) - . = ALIGN(4); - edata = .; - _edata = .; - PROVIDE (__data_end = .); - } > ram - - .bss : - { - PROVIDE (__bss_start = .); - *(.bss) - *(COMMON) - . = ALIGN(4); - PROVIDE (__bss_end = .); - - . = ALIGN(256); - - PROVIDE (__stack_start = .); - - PROVIDE (__stack_fiq_start = .); - . += FIQ_STACK_SIZE; - . = ALIGN(4); - PROVIDE (__stack_fiq_end = .); - - PROVIDE (__stack_irq_start = .); - . += IRQ_STACK_SIZE; - . = ALIGN(4); - PROVIDE (__stack_irq_end = .); - - PROVIDE (__stack_abt_start = .); - . += ABT_STACK_SIZE; - . = ALIGN(4); - PROVIDE (__stack_abt_end = .); - - PROVIDE (__stack_und_start = .); - . += UND_STACK_SIZE; - . = ALIGN(4); - PROVIDE (__stack_und_end = .); - - PROVIDE (__stack_svc_start = .); - . += SVC_STACK_SIZE; - . = ALIGN(4); - PROVIDE (__stack_svc_end = .); - PROVIDE (__stack_end = .); - PROVIDE (__heap_start = .); - } > ram - -} -/*** EOF ***/ - diff --git a/testing/examples/LPC2294Test/prj/lpc2294_rom.ld b/testing/examples/LPC2294Test/prj/lpc2294_rom.ld deleted file mode 100644 index 64a28f0c6..000000000 --- a/testing/examples/LPC2294Test/prj/lpc2294_rom.ld +++ /dev/null @@ -1,141 +0,0 @@ -/**************************************************************************** -* Copyright (c) 2006 by Michael Fischer. All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* 1. Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the author nor the names of its contributors may -* be used to endorse or promote products derived from this software -* without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -* THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS -* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED -* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF -* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -* SUCH DAMAGE. -* -**************************************************************************** -* -* History: -* -* 31.03.06 mifi First Version -****************************************************************************/ - - -ENTRY(ResetHandler) -SEARCH_DIR(.) - -/* - * Define stack size here - */ -FIQ_STACK_SIZE = 0x0100; -IRQ_STACK_SIZE = 0x0100; -ABT_STACK_SIZE = 0x0100; -UND_STACK_SIZE = 0x0100; -SVC_STACK_SIZE = 0x0400; - -/* - * This file, olimex_lpce2294_ram.ld, locate the program in the internal - * ram of the LPC2294. For more information about the memory of the LPC2294 - * take a look in the LPC2119/2129/2194/2292/2294 USER MANUAL. - * Reference is made to the user manual from 2004 May 03 - * - * Take a look at page 48, section 2.Memory Addressing - */ - -MEMORY -{ - rom : org = 0x00000000, len = 256k - ram : org = 0x40000000, len = 16k -} - -/* - * Do not change the next code - */ -SECTIONS -{ - .text : - { - *(.vectors); - . = ALIGN(4); - *(.init); - . = ALIGN(4); - *(.text); - . = ALIGN(4); - *(.rodata); - . = ALIGN(4); - *(.rodata*); - . = ALIGN(4); - *(.glue_7t); - . = ALIGN(4); - *(.glue_7); - . = ALIGN(4); - etext = .; - } > rom - - .data : - { - PROVIDE (__data_start = .); - *(.data) - . = ALIGN(4); - edata = .; - _edata = .; - PROVIDE (__data_end = .); - } > ram - - .bss : - { - PROVIDE (__bss_start = .); - *(.bss) - *(COMMON) - . = ALIGN(4); - PROVIDE (__bss_end = .); - - . = ALIGN(256); - - PROVIDE (__stack_start = .); - - PROVIDE (__stack_fiq_start = .); - . += FIQ_STACK_SIZE; - . = ALIGN(4); - PROVIDE (__stack_fiq_end = .); - - PROVIDE (__stack_irq_start = .); - . += IRQ_STACK_SIZE; - . = ALIGN(4); - PROVIDE (__stack_irq_end = .); - - PROVIDE (__stack_abt_start = .); - . += ABT_STACK_SIZE; - . = ALIGN(4); - PROVIDE (__stack_abt_end = .); - - PROVIDE (__stack_und_start = .); - . += UND_STACK_SIZE; - . = ALIGN(4); - PROVIDE (__stack_und_end = .); - - PROVIDE (__stack_svc_start = .); - . += SVC_STACK_SIZE; - . = ALIGN(4); - PROVIDE (__stack_svc_end = .); - PROVIDE (__stack_end = .); - PROVIDE (__heap_start = .); - } > ram - -} -/*** EOF ***/ - diff --git a/testing/examples/LPC2294Test/src/crt.s b/testing/examples/LPC2294Test/src/crt.s deleted file mode 100644 index ac17dcd5f..000000000 --- a/testing/examples/LPC2294Test/src/crt.s +++ /dev/null @@ -1,189 +0,0 @@ -/**************************************************************************** -* Copyright (c) 2006 by Michael Fischer. All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* 1. Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the author nor the names of its contributors may -* be used to endorse or promote products derived from this software -* without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -* THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS -* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED -* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF -* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -* SUCH DAMAGE. -* -**************************************************************************** -* -* History: -* -* 31.03.06 mifi First Version -* This version based on an example from Ethernut and -* "ARM Cross Development with Eclipse" from James P. Lynch -****************************************************************************/ - -/* - * Some defines for the program status registers - */ - ARM_MODE_USER = 0x10 /* Normal User Mode */ - ARM_MODE_FIQ = 0x11 /* FIQ Fast Interrupts Mode */ - ARM_MODE_IRQ = 0x12 /* IRQ Standard Interrupts Mode */ - ARM_MODE_SVC = 0x13 /* Supervisor Interrupts Mode */ - ARM_MODE_ABORT = 0x17 /* Abort Processing memory Faults Mode */ - ARM_MODE_UNDEF = 0x1B /* Undefined Instructions Mode */ - ARM_MODE_SYS = 0x1F /* System Running in Priviledged Operating Mode */ - ARM_MODE_MASK = 0x1F - - I_BIT = 0x80 /* disable IRQ when I bit is set */ - F_BIT = 0x40 /* disable IRQ when I bit is set */ - -/* - * Register Base Address - */ - - .section .vectors,"ax" - .code 32 - -/****************************************************************************/ -/* Vector table and reset entry */ -/****************************************************************************/ -_vectors: - ldr pc, ResetAddr /* Reset */ - ldr pc, UndefAddr /* Undefined instruction */ - ldr pc, SWIAddr /* Software interrupt */ - ldr pc, PAbortAddr /* Prefetch abort */ - ldr pc, DAbortAddr /* Data abort */ - ldr pc, ReservedAddr /* Reserved */ - ldr pc, IRQAddr /* IRQ interrupt */ - ldr pc, FIQAddr /* FIQ interrupt */ - - -ResetAddr: .word ResetHandler -UndefAddr: .word UndefHandler -SWIAddr: .word SWIHandler -PAbortAddr: .word PAbortHandler -DAbortAddr: .word DAbortHandler -ReservedAddr: .word 0 -IRQAddr: .word IRQHandler -FIQAddr: .word FIQHandler - - .ltorg - - - .section .init, "ax" - .code 32 - - .global ResetHandler - .global ExitFunction - .extern main -/****************************************************************************/ -/* Reset handler */ -/****************************************************************************/ -ResetHandler: -/* - * Wait for the oscillator is stable - */ - nop - nop - nop - nop - nop - nop - nop - nop - - /* - * Setup a stack for each mode - */ - msr CPSR_c, #ARM_MODE_UNDEF | I_BIT | F_BIT /* Undefined Instruction Mode */ - ldr sp, =__stack_und_end - - msr CPSR_c, #ARM_MODE_ABORT | I_BIT | F_BIT /* Abort Mode */ - ldr sp, =__stack_abt_end - - msr CPSR_c, #ARM_MODE_FIQ | I_BIT | F_BIT /* FIQ Mode */ - ldr sp, =__stack_fiq_end - - msr CPSR_c, #ARM_MODE_IRQ | I_BIT | F_BIT /* IRQ Mode */ - ldr sp, =__stack_irq_end - - msr CPSR_c, #ARM_MODE_SVC | I_BIT | F_BIT /* Supervisor Mode */ - ldr sp, =__stack_svc_end - - - /* - * Clear .bss section - */ - ldr r1, =__bss_start - ldr r2, =__bss_end - ldr r3, =0 -bss_clear_loop: - cmp r1, r2 - strne r3, [r1], #+4 - bne bss_clear_loop - - - /* - * Jump to main - */ - mrs r0, cpsr - bic r0, r0, #I_BIT | F_BIT /* Enable FIQ and IRQ interrupt */ - msr cpsr, r0 - - mov r0, #0 /* No arguments */ - mov r1, #0 /* No arguments */ - ldr r2, =main - mov lr, pc - bx r2 /* And jump... */ - -ExitFunction: - nop - nop - nop - b ExitFunction - - -/****************************************************************************/ -/* Default interrupt handler */ -/****************************************************************************/ - -UndefHandler: - b UndefHandler - -SWIHandler: - b SWIHandler - -PAbortHandler: - b PAbortHandler - -DAbortHandler: - b DAbortHandler - -IRQHandler: - b IRQHandler - -FIQHandler: - b FIQHandler - - .weak ExitFunction - .weak UndefHandler, PAbortHandler, DAbortHandler - .weak IRQHandler, FIQHandler - - .ltorg -/*** EOF ***/ - - diff --git a/testing/examples/LPC2294Test/src/main.c b/testing/examples/LPC2294Test/src/main.c deleted file mode 100644 index 801c72747..000000000 --- a/testing/examples/LPC2294Test/src/main.c +++ /dev/null @@ -1,93 +0,0 @@ -/**************************************************************************** -* Copyright (c) 2006 by Michael Fischer. All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* 1. Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the author nor the names of its contributors may -* be used to endorse or promote products derived from this software -* without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -* THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS -* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED -* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF -* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -* SUCH DAMAGE. -* -**************************************************************************** -* History: -* -* 30.03.06 mifi First Version for Insight tutorial -* 26.01.08 mifi Added variable "d" to test const variable. -****************************************************************************/ -#define __MAIN_C__ - -/* - * I use the include only, to show - * how to setup a include dir in the makefile - */ -#include -#include -#include "typedefs.h" - -/*=========================================================================*/ -/* DEFINE: All Structures and Common Constants */ -/*=========================================================================*/ - -/*=========================================================================*/ -/* DEFINE: Prototypes */ -/*=========================================================================*/ - -/*=========================================================================*/ -/* DEFINE: Definition of all local Data */ -/*=========================================================================*/ -static const DWORD d = 7; - -/*=========================================================================*/ -/* DEFINE: Definition of all local Procedures */ -/*=========================================================================*/ - -/*=========================================================================*/ -/* DEFINE: All code exported */ -/*=========================================================================*/ -/***************************************************************************/ -/* main */ -/***************************************************************************/ -int main (void) -{ - DWORD a = 1; - DWORD b = 2; - DWORD c = 0; - - a = a + d; - - while (1) - { - a++; - b++; - c = a + b; - } - - /* - * This return here make no sense. - * But to prevent the compiler warning: - * "return type of 'main' is not 'int' - * we use an int as return :-) - */ - return(0); -} - -/*** EOF ***/ diff --git a/testing/examples/LPC2294Test/test_ram.elf b/testing/examples/LPC2294Test/test_ram.elf deleted file mode 100644 index d53aa0cb5ecd64b167a78af22981b143a547bf70..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 36618 zcmeH}O>A6O701te^Wh#gqDyH3af!HFk2#Z!-Amlp#2!7X}{{H zO*E=7DzrFZAJGuEZ1O`)2nYcoAOwVf5D)@FKnMr{As_^VfDjM@LO=)z0U;m+gn$qb z0zyCt2mv7=1cZPP5CTF#2nYcoAOwVf5D)@FKnMr{As_^VfDjM@LO=)z0U;m+gn$qb z0zyCt2mv7=1cZPP5CTF#2nYcoAOwVf5D)@FKnMr{As_^VfDjM@LO=)z0U;m+gn$qb z0zyCt2mv7=1cZPP5CTF#2nYcoAOwVf5D)@FKnMr{As_^VfDjM@LO=)z0U;m+gn$qb z0zyCt2mv7=1cbo<7lBXSy?N(9l>$*=8|5vOKcc*Y!aLkS{hso-ZWDcU`Saa}cCT;W zyz@5db<}U74p9FN^$P0Wqi&&YrBO0B?@)eg*QU$2?m5IA+}XN)xR<+U?)Q7WzkT=-g_2lz0wsnLN7+Y(mKBy1>XGf4cP-3K`DgFg zsN<-4Eh*He@>o~q1?ZR1cVmZR*thaG-eo@?`6?&#lG3sKQ#+jdPpoGN;}3yZ@gN?K z>(rWLCE%{1*p%U?_5OkVWWgX%td3tNs{28^Ro5qK4&wxLP%P*hwzj$i(SNePi)kO|P=lUUn|$0o+c9vz=UJDt5apDC6zW7!j@ z$lCl7X0qw9nv;7bGUM5??3hBBi+1q8nwdAvFZ0`&&5jSX+TLPj)$24DJ-3l*dI4xA zBUN8=e8^P4J8ZBMou#%Pgu(VuDEcvKhL?8le+5lMvCzeV zd4OW6)5BjHE*-&$S?jAKq5S+v=?Lc)k`_9WN5#~oRr00*V; zM%2L7r%`MQ@C@U4>sO()^5%}aO=$WEfDcL7awc4Fdm<`~ZL@#q*+wzIJuI5pIPAJ$9S3*7a9vb9c! zvc=h%tP=!&v$l%A9m+P`+UjDp)%0BLH@$_n_MKYIch~yLcf7?x(!FZIcb5BOwAyu@ zw6a?B(1WS!?d4?`NA1722NBAL1xJCcK$}GP7WYlR!H3X-GlEaH>MyjOBzln>BGV~H zp%KGhA7vb;-wQYBxRZv@?bi|aCOeVoxHHh&=dPKj@B-~9$mqLh_}qKx`{6g8eKtKt z#qhcP4aA*eCo;XIYtTA}yV5@(%CHlej@y7X^qXg}Uo4(~CLc!Oeeiqy z7>YUG-+xT>86#1Thp_uufg5Adto)lFYGVM^Z_dE+nj%NDPJ~YMjOo+c*Zd1Vu$Vfz zrsiD?EQSk+X)zi$CFUDZD;}KVZjZSz+t9i_{+12+cYDX7qt79{ZjaA9e{4eQ_NL$r z-fOov2R%3s-JY{Yx1l#tLhJTc;S?gp<9{dgqb7^KyGQ>JI@3?Fh|k%mp??B>%+Rku zf5Ff{ht3=Nm(b&eejWOhp??egWkde~I%DWRLBC~aUVp*R??Jz4XwLtuq5lD`Esp*F z3t|c9iBAfC4~XMgqk>t)pWn3ykMmfM1C6)9C2ziGPA)`Q8lU{AXEnfpPv% z;lC5*^Lk!|9?WOaFYeJc{R*0STtz;vuk>qZ{b$DGZSRSHoBO%Ixc@KkcZ~VE(A$Ro zkYo97599S7u;K8XKhlI>$?D9d$*Jmmd1`i`rc0LxqBLuW^5YYOp5mEHvvUJEe{phZ zdLYYRD-Xm>v3#CN)ib3znpV$IhpKCCJ!tzKnsqyFP;4}On)h(2R$lo^N!5=PYq%aN zcXHrzhQH=ER67=^YOGq-qYXm#Imc_XT%T|osMcGq<5yel_KLp3Hwe+y@?3G^e6?Kq z`V>o@QLT0Yr+%&4S*urFuR-Awbnn!9GniiW>Or&Zkq%vGep7|I4JU923o?gR+tcaQ zDldqK)w!!)L+Rp~IWsHVtxj{*)h0~F>ii(QBH?wIIn{7}ya=-u%hAIqzFO!7H2rY# KT06BsE$H8eG}0IV diff --git a/testing/examples/LPC2294Test/test_ram.hex b/testing/examples/LPC2294Test/test_ram.hex deleted file mode 100644 index e54b9e350..000000000 --- a/testing/examples/LPC2294Test/test_ram.hex +++ /dev/null @@ -1,26 +0,0 @@ -:020000044000BA -:1000000018F09FE518F09FE518F09FE518F09FE5C0 -:1000100018F09FE518F09FE518F09FE518F09FE5B0 -:1000200040000040D0000040D4000040D800004014 -:10003000DC00004000000000E0000040E400004060 -:100040000000A0E10000A0E10000A0E10000A0E1AC -:100050000000A0E10000A0E10000A0E10000A0E19C -:10006000DBF021E37CD09FE5D7F021E378D09FE55A -:10007000D1F021E374D09FE5D2F021E370D09FE569 -:10008000D3F021E36CD09FE56C109FE56C209FE5D9 -:100090000030A0E3020051E104308114FCFFFF1A9C -:1000A00000000FE1C000C0E300F029E10000A0E380 -:1000B0000010A0E348209FE50FE0A0E112FF2FE130 -:1000C0000000A0E10000A0E10000A0E1FBFFFFEACA -:1000D000FEFFFFEAFEFFFFEAFEFFFFEAFEFFFFEA88 -:1000E000FEFFFFEAFEFFFFEA0006004000050040B9 -:1000F0000003004000040040000A00406C01004082 -:100100006C010040080100400CD04DE20130A0E33A -:1001100000308DE50230A0E304308DE50030A0E32F -:1001200008308DE538309FE5002093E500309DE5EF -:10013000023083E000308DE500309DE5013083E240 -:1001400000308DE504309DE5013083E204308DE51B -:1001500000209DE504309DE5033082E008308DE508 -:0C016000F4FFFFEA680100400700000007 -:040000054000004077 -:00000001FF diff --git a/testing/examples/LPC2294Test/test_ram.map b/testing/examples/LPC2294Test/test_ram.map deleted file mode 100644 index 20b9c68e1..000000000 --- a/testing/examples/LPC2294Test/test_ram.map +++ /dev/null @@ -1,170 +0,0 @@ - -Memory Configuration - -Name Origin Length Attributes -ram 0x40000000 0x00004000 -*default* 0x00000000 0xffffffff - -Linker script and memory map - -LOAD ./src/crt.o -LOAD ./src/main.o -START GROUP -LOAD d:/compiler/yagarto/bin/../lib/gcc/arm-elf/4.2.2\libgcc.a -LOAD d:/compiler/yagarto/bin/../lib/gcc/arm-elf/4.2.2/../../../../arm-elf/lib\libc.a -END GROUP - 0x00000100 FIQ_STACK_SIZE = 0x100 - 0x00000100 IRQ_STACK_SIZE = 0x100 - 0x00000100 ABT_STACK_SIZE = 0x100 - 0x00000100 UND_STACK_SIZE = 0x100 - 0x00000400 SVC_STACK_SIZE = 0x400 - -.text 0x40000000 0x16c - *(.vectors) - .vectors 0x40000000 0x40 ./src/crt.o - 0x40000040 . = ALIGN (0x4) - *(.init) - .init 0x40000040 0xc8 ./src/crt.o - 0x400000e4 FIQHandler - 0x400000d8 PAbortHandler - 0x400000c0 ExitFunction - 0x40000040 ResetHandler - 0x400000dc DAbortHandler - 0x400000e0 IRQHandler - 0x400000d0 UndefHandler - 0x40000108 . = ALIGN (0x4) - *(.text) - .text 0x40000108 0x0 ./src/crt.o - .text 0x40000108 0x60 ./src/main.o - 0x40000108 main - 0x40000168 . = ALIGN (0x4) - *(.rodata) - .rodata 0x40000168 0x4 ./src/main.o - 0x4000016c . = ALIGN (0x4) - *(.rodata*) - 0x4000016c . = ALIGN (0x4) - *(.glue_7t) - .glue_7t 0x4000016c 0x0 ./src/crt.o - .glue_7t 0x4000016c 0x0 ./src/main.o - 0x4000016c . = ALIGN (0x4) - *(.glue_7) - .glue_7 0x4000016c 0x0 ./src/crt.o - .glue_7 0x4000016c 0x0 ./src/main.o - 0x4000016c . = ALIGN (0x4) - 0x4000016c etext = . - -.vfp11_veneer 0x00000000 0x0 - .vfp11_veneer 0x00000000 0x0 ./src/crt.o - .vfp11_veneer 0x00000000 0x0 ./src/main.o - -.data 0x4000016c 0x0 - 0x4000016c PROVIDE (__data_start, .) - *(.data) - .data 0x4000016c 0x0 ./src/crt.o - .data 0x4000016c 0x0 ./src/main.o - 0x4000016c . = ALIGN (0x4) - 0x4000016c edata = . - 0x4000016c _edata = . - 0x4000016c PROVIDE (__data_end, .) - -.bss 0x4000016c 0x894 - 0x4000016c PROVIDE (__bss_start, .) - *(.bss) - .bss 0x4000016c 0x0 ./src/crt.o - .bss 0x4000016c 0x0 ./src/main.o - *(COMMON) - 0x4000016c . = ALIGN (0x4) - 0x4000016c PROVIDE (__bss_end, .) - 0x40000200 . = ALIGN (0x100) - *fill* 0x4000016c 0x94 00 - 0x40000200 PROVIDE (__stack_start, .) - 0x40000200 PROVIDE (__stack_fiq_start, .) - 0x40000300 . = (. + FIQ_STACK_SIZE) - *fill* 0x40000200 0x100 00 - 0x40000300 . = ALIGN (0x4) - 0x40000300 PROVIDE (__stack_fiq_end, .) - 0x40000300 PROVIDE (__stack_irq_start, .) - 0x40000400 . = (. + IRQ_STACK_SIZE) - *fill* 0x40000300 0x100 00 - 0x40000400 . = ALIGN (0x4) - 0x40000400 PROVIDE (__stack_irq_end, .) - 0x40000400 PROVIDE (__stack_abt_start, .) - 0x40000500 . = (. + ABT_STACK_SIZE) - *fill* 0x40000400 0x100 00 - 0x40000500 . = ALIGN (0x4) - 0x40000500 PROVIDE (__stack_abt_end, .) - 0x40000500 PROVIDE (__stack_und_start, .) - 0x40000600 . = (. + UND_STACK_SIZE) - *fill* 0x40000500 0x100 00 - 0x40000600 . = ALIGN (0x4) - 0x40000600 PROVIDE (__stack_und_end, .) - 0x40000600 PROVIDE (__stack_svc_start, .) - 0x40000a00 . = (. + SVC_STACK_SIZE) - *fill* 0x40000600 0x400 00 - 0x40000a00 . = ALIGN (0x4) - 0x40000a00 PROVIDE (__stack_svc_end, .) - 0x40000a00 PROVIDE (__stack_end, .) - 0x40000a00 PROVIDE (__heap_start, .) -OUTPUT(test_ram.elf elf32-littlearm) - -.ARM.attributes - 0x00000000 0x10 - .ARM.attributes - 0x00000000 0x10 ./src/crt.o - .ARM.attributes - 0x00000010 0x10 ./src/main.o - -.debug_line 0x00000000 0xd1 - .debug_line 0x00000000 0x7a ./src/crt.o - .debug_line 0x0000007a 0x57 ./src/main.o - -.debug_info 0x00000000 0x202 - .debug_info 0x00000000 0x74 ./src/crt.o - .debug_info 0x00000074 0x18e ./src/main.o - -.debug_abbrev 0x00000000 0x76 - .debug_abbrev 0x00000000 0x12 ./src/crt.o - .debug_abbrev 0x00000012 0x64 ./src/main.o - -.debug_aranges 0x00000000 0x48 - .debug_aranges - 0x00000000 0x28 ./src/crt.o - .debug_aranges - 0x00000028 0x20 ./src/main.o - -.debug_ranges 0x00000000 0x20 - .debug_ranges 0x00000000 0x20 ./src/crt.o - -.debug_frame 0x00000000 0x24 - .debug_frame 0x00000000 0x24 ./src/main.o - -.debug_loc 0x00000000 0x1f - .debug_loc 0x00000000 0x1f ./src/main.o - -.debug_pubnames - 0x00000000 0x1b - .debug_pubnames - 0x00000000 0x1b ./src/main.o - -.comment 0x00000000 0x12 - .comment 0x00000000 0x12 ./src/main.o - -Cross Reference Table - -Symbol File -DAbortHandler ./src/crt.o -ExitFunction ./src/crt.o -FIQHandler ./src/crt.o -IRQHandler ./src/crt.o -PAbortHandler ./src/crt.o -ResetHandler ./src/crt.o -UndefHandler ./src/crt.o -__bss_end ./src/crt.o -__bss_start ./src/crt.o -__stack_abt_end ./src/crt.o -__stack_fiq_end ./src/crt.o -__stack_irq_end ./src/crt.o -__stack_svc_end ./src/crt.o -__stack_und_end ./src/crt.o -main ./src/main.o - ./src/crt.o diff --git a/testing/examples/LPC2294Test/test_rom.elf b/testing/examples/LPC2294Test/test_rom.elf deleted file mode 100644 index 0b2f64caf8dd2043da104f181e8712df838a247b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 36618 zcmeH}U2Ggz701uaet5x7;v}dbieM|5kcet`W85eW2zKL-WR*B+yfzVN(PnmcY_GDO zH8W#lLkeyKr9!k)1#eKrz*`>>uSh(E2T&iX%7u!8+6Sj@5JEg;1y8i<@;~>^-JMu% z#RCsKoMYX&=YP++_n!I9-SK>9`r?dbSq?>J({Zxk7ttorE z5AEI9xpnt7^c(13K_8<31Nv3;e?;F#-yTKF-nvVL?LC{W+({Om_{clG-p7d!-MLM- z_vqdU-e-?SxA)E?@6hh{og=;ceS5#%>;3)R_i2=*A|=o)G#f30M!IDzqLH21H!bW< zg=g;C=#%KVmJIsS1=N-O5%lwj-Q49I_N~IrH`z}{zM7MLUg<>P$z7iNFVwS)^@p%o z=@2fC>(pChrQoik*_7q0_4dI7WWgZNtiW#&HT*Caup~;^d`;XYE3eHyf^-ZQd3dis z{JDG~`kTnZ$?I!Ae-g7!on%uJE0|@|BYb_Yopbq?hy7QamX~XA0paGV+jJL$+%l%Y zQZ_S7{0{qGxN!03OG`KHBeS6%L`xYd=#R?t{> z{c2~`^*W7aHT2iK>pB0C)2FJT8-y)ysp@VxE30ics9t<*a(w*JiFu6Exl0S#QYAZ{ zJ9(O{tsh_~n~tbGIWn1@$c^X56~cUU2mh;``KI|{eiOUd$)R?~Tgt9^L2Jo#o7t8Z zf@V5Wjb+D&%=E*0z)l6r9Y55`_K+6+9JNF;rMsc~hchX)ow}%mjNbn}ib(2I&PpVQ zP=wk$Id%2&+!Wcl4OE}97!6r77XP@-eZi$o++W%u>)Z(j`&^i=lXYJE8)+Pdvi5IK zx=GffPa`RnU?xL6PS#->O)sPqnFlkU&K%`KZXLGZ4fDuh>xea)#;Rj9Jp4rr;RtCL z2j&4vWX=qKez<%TE9R^(jcECqk@8WVS4>+7q$m1W_J^_OG2(Q#F*J2F@k2LOgv0Gc zG-IEDV^fH$&f{CZW`gK@Fe8g_xN(lL5jdPn;kQG%rdwZIsFl$aHL5Y6$6rL= zd3GW*w{#ua%;C`J_lUCWL}v0fq2qZ4w5Vc>(hH85uKq zKf{3WIrc2__{D3?#13O1dS)uLjl3635_*%zeGDtT^fc}l#q+<(&!X{t@bBwGXz}&_ z@k63d#wMEekoLZo=eYyj^g{H0BTZ2=K6tDlSzR!+D-`=Oc51s9gS;XgTET(?~|9DLQ0{+7> z{Y&_TnEo~ViJ1O9{L?Z0GW;*Z^q=5oWBM=fUyW(5zZlbR!T)hg^ZdWX^gsJPpUrOX z-_XlAe0);y|A083wKj`*eg3~-G{>7U{SF5rJ&N^);d2daSp**7nEp=1@4%*G(EJU~ z#_n8B*3m7pzN+JDkoQ}JE-J}h065YK+Tk|3`BV@CMsW^97IZIFVD>n6wA7e5EoFv!%)fD%Z}I=V?Y=#~iAyyN$5p2Q=pfZdhtIeOmDFQLVhn)w1dzE7kFN zsNAW6%QO6Sx2eWapz2Yz>c^Ud+2-)x*Fde&b{)Ug?sQhoCw!BTU8~HOCNI<~ z<*!b&G&5?oAaoknYr%S>=6X%iC79^+Mk}0I^BQ5R^SY<*p&x=kl^2nEHLR<~!S z*J@l4FKgzmc}=BDXXoRy^xc|iuKKjmlTn=?>Q5v*j`*CK-X9MlK8kY8GK#Merht~O Mi#OV-hpM3e0FR2m4gdfE diff --git a/testing/examples/LPC2294Test/test_rom.hex b/testing/examples/LPC2294Test/test_rom.hex deleted file mode 100644 index 7d6207520..000000000 --- a/testing/examples/LPC2294Test/test_rom.hex +++ /dev/null @@ -1,25 +0,0 @@ -:1000000018F09FE518F09FE518F09FE518F09FE5C0 -:1000100018F09FE518F09FE518F09FE518F09FE5B0 -:1000200040000000D0000000D4000000D800000014 -:10003000DC00000000000000E0000000E400000020 -:100040000000A0E10000A0E10000A0E10000A0E1AC -:100050000000A0E10000A0E10000A0E10000A0E19C -:10006000DBF021E37CD09FE5D7F021E378D09FE55A -:10007000D1F021E374D09FE5D2F021E370D09FE569 -:10008000D3F021E36CD09FE56C109FE56C209FE5D9 -:100090000030A0E3020051E104308114FCFFFF1A9C -:1000A00000000FE1C000C0E300F029E10000A0E380 -:1000B0000010A0E348209FE50FE0A0E112FF2FE130 -:1000C0000000A0E10000A0E10000A0E1FBFFFFEACA -:1000D000FEFFFFEAFEFFFFEAFEFFFFEAFEFFFFEA88 -:1000E000FEFFFFEAFEFFFFEA0004004000030040BD -:1000F00000010040000200400008004000000040F5 -:1001000000000040080100000CD04DE20130A0E3E7 -:1001100000308DE50230A0E304308DE50030A0E32F -:1001200008308DE538309FE5002093E500309DE5EF -:10013000023083E000308DE500309DE5013083E240 -:1001400000308DE504309DE5013083E204308DE51B -:1001500000209DE504309DE5033082E008308DE508 -:0C016000F4FFFFEA680100000700000047 -:0400000300000040B9 -:00000001FF diff --git a/testing/examples/LPC2294Test/test_rom.map b/testing/examples/LPC2294Test/test_rom.map deleted file mode 100644 index e19c99f26..000000000 --- a/testing/examples/LPC2294Test/test_rom.map +++ /dev/null @@ -1,170 +0,0 @@ - -Memory Configuration - -Name Origin Length Attributes -rom 0x00000000 0x00040000 -ram 0x40000000 0x00004000 -*default* 0x00000000 0xffffffff - -Linker script and memory map - -LOAD ./src/crt.o -LOAD ./src/main.o -START GROUP -LOAD d:/compiler/yagarto/bin/../lib/gcc/arm-elf/4.2.2\libgcc.a -LOAD d:/compiler/yagarto/bin/../lib/gcc/arm-elf/4.2.2/../../../../arm-elf/lib\libc.a -END GROUP - 0x00000100 FIQ_STACK_SIZE = 0x100 - 0x00000100 IRQ_STACK_SIZE = 0x100 - 0x00000100 ABT_STACK_SIZE = 0x100 - 0x00000100 UND_STACK_SIZE = 0x100 - 0x00000400 SVC_STACK_SIZE = 0x400 - -.text 0x00000000 0x16c - *(.vectors) - .vectors 0x00000000 0x40 ./src/crt.o - 0x00000040 . = ALIGN (0x4) - *(.init) - .init 0x00000040 0xc8 ./src/crt.o - 0x000000e4 FIQHandler - 0x000000d8 PAbortHandler - 0x000000c0 ExitFunction - 0x00000040 ResetHandler - 0x000000dc DAbortHandler - 0x000000e0 IRQHandler - 0x000000d0 UndefHandler - 0x00000108 . = ALIGN (0x4) - *(.text) - .text 0x00000108 0x0 ./src/crt.o - .text 0x00000108 0x60 ./src/main.o - 0x00000108 main - 0x00000168 . = ALIGN (0x4) - *(.rodata) - .rodata 0x00000168 0x4 ./src/main.o - 0x0000016c . = ALIGN (0x4) - *(.rodata*) - 0x0000016c . = ALIGN (0x4) - *(.glue_7t) - .glue_7t 0x0000016c 0x0 ./src/crt.o - .glue_7t 0x0000016c 0x0 ./src/main.o - 0x0000016c . = ALIGN (0x4) - *(.glue_7) - .glue_7 0x0000016c 0x0 ./src/crt.o - .glue_7 0x0000016c 0x0 ./src/main.o - 0x0000016c . = ALIGN (0x4) - 0x0000016c etext = . - -.vfp11_veneer 0x00000000 0x0 - .vfp11_veneer 0x00000000 0x0 ./src/crt.o - .vfp11_veneer 0x00000000 0x0 ./src/main.o - -.data 0x40000000 0x0 - 0x40000000 PROVIDE (__data_start, .) - *(.data) - .data 0x40000000 0x0 ./src/crt.o - .data 0x40000000 0x0 ./src/main.o - 0x40000000 . = ALIGN (0x4) - 0x40000000 edata = . - 0x40000000 _edata = . - 0x40000000 PROVIDE (__data_end, .) - -.bss 0x40000000 0x800 - 0x40000000 PROVIDE (__bss_start, .) - *(.bss) - .bss 0x40000000 0x0 ./src/crt.o - .bss 0x40000000 0x0 ./src/main.o - *(COMMON) - 0x40000000 . = ALIGN (0x4) - 0x40000000 PROVIDE (__bss_end, .) - 0x40000000 . = ALIGN (0x100) - 0x40000000 PROVIDE (__stack_start, .) - 0x40000000 PROVIDE (__stack_fiq_start, .) - 0x40000100 . = (. + FIQ_STACK_SIZE) - *fill* 0x40000000 0x100 00 - 0x40000100 . = ALIGN (0x4) - 0x40000100 PROVIDE (__stack_fiq_end, .) - 0x40000100 PROVIDE (__stack_irq_start, .) - 0x40000200 . = (. + IRQ_STACK_SIZE) - *fill* 0x40000100 0x100 00 - 0x40000200 . = ALIGN (0x4) - 0x40000200 PROVIDE (__stack_irq_end, .) - 0x40000200 PROVIDE (__stack_abt_start, .) - 0x40000300 . = (. + ABT_STACK_SIZE) - *fill* 0x40000200 0x100 00 - 0x40000300 . = ALIGN (0x4) - 0x40000300 PROVIDE (__stack_abt_end, .) - 0x40000300 PROVIDE (__stack_und_start, .) - 0x40000400 . = (. + UND_STACK_SIZE) - *fill* 0x40000300 0x100 00 - 0x40000400 . = ALIGN (0x4) - 0x40000400 PROVIDE (__stack_und_end, .) - 0x40000400 PROVIDE (__stack_svc_start, .) - 0x40000800 . = (. + SVC_STACK_SIZE) - *fill* 0x40000400 0x400 00 - 0x40000800 . = ALIGN (0x4) - 0x40000800 PROVIDE (__stack_svc_end, .) - 0x40000800 PROVIDE (__stack_end, .) - 0x40000800 PROVIDE (__heap_start, .) -OUTPUT(test_rom.elf elf32-littlearm) - -.ARM.attributes - 0x00000000 0x10 - .ARM.attributes - 0x00000000 0x10 ./src/crt.o - .ARM.attributes - 0x00000010 0x10 ./src/main.o - -.debug_line 0x00000000 0xd1 - .debug_line 0x00000000 0x7a ./src/crt.o - .debug_line 0x0000007a 0x57 ./src/main.o - -.debug_info 0x00000000 0x202 - .debug_info 0x00000000 0x74 ./src/crt.o - .debug_info 0x00000074 0x18e ./src/main.o - -.debug_abbrev 0x00000000 0x76 - .debug_abbrev 0x00000000 0x12 ./src/crt.o - .debug_abbrev 0x00000012 0x64 ./src/main.o - -.debug_aranges 0x00000000 0x48 - .debug_aranges - 0x00000000 0x28 ./src/crt.o - .debug_aranges - 0x00000028 0x20 ./src/main.o - -.debug_ranges 0x00000000 0x20 - .debug_ranges 0x00000000 0x20 ./src/crt.o - -.debug_frame 0x00000000 0x24 - .debug_frame 0x00000000 0x24 ./src/main.o - -.debug_loc 0x00000000 0x1f - .debug_loc 0x00000000 0x1f ./src/main.o - -.debug_pubnames - 0x00000000 0x1b - .debug_pubnames - 0x00000000 0x1b ./src/main.o - -.comment 0x00000000 0x12 - .comment 0x00000000 0x12 ./src/main.o - -Cross Reference Table - -Symbol File -DAbortHandler ./src/crt.o -ExitFunction ./src/crt.o -FIQHandler ./src/crt.o -IRQHandler ./src/crt.o -PAbortHandler ./src/crt.o -ResetHandler ./src/crt.o -UndefHandler ./src/crt.o -__bss_end ./src/crt.o -__bss_start ./src/crt.o -__stack_abt_end ./src/crt.o -__stack_fiq_end ./src/crt.o -__stack_irq_end ./src/crt.o -__stack_svc_end ./src/crt.o -__stack_und_end ./src/crt.o -main ./src/main.o - ./src/crt.o diff --git a/testing/examples/PIC32/BlinkingLeds.c b/testing/examples/PIC32/BlinkingLeds.c deleted file mode 100644 index 22758cc25..000000000 --- a/testing/examples/PIC32/BlinkingLeds.c +++ /dev/null @@ -1,23 +0,0 @@ -#include -int main(void) -{ - int i; - mPORTDClearBits(BIT_0); - mPORTDSetPinsDigitalOut(BIT_0); - mPORTDClearBits(BIT_1); - mPORTDSetPinsDigitalOut(BIT_1); - mPORTDClearBits(BIT_2); - mPORTDSetPinsDigitalOut(BIT_2); - - while (1) - { - for (i = 0; i < 500000; i++) - mPORTDToggleBits(BIT_0); - for (i = 0; i < 500000; i++) - mPORTDToggleBits(BIT_1); - for (i = 0; i < 500000; i++) - mPORTDToggleBits(BIT_2); - } - - return 0; -} diff --git a/testing/examples/PIC32/BlinkingLeds.elf b/testing/examples/PIC32/BlinkingLeds.elf deleted file mode 100644 index 593164ba0822f8aeeeed7799f36d8733454dc4f2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 770014 zcmeIb4SZi^efNLmp>5iRl0uvji~b5hB9=BuQz%k3ZPJoRAF?FHs?{WI(l*kju}QHw z)Tl740<9A#DjiW#xfLmTtAmLWCr-A%52$Q9$L_mRRGiFJMP-hy|Ihb2=lsq$X&bk_ z?&ALc`+Xoe=W|`(>*;+xU+0(p-mrS@nv#-|kX@yrA|z_!z9u>Dc>df_Qgv*&DHOuY zP#3m@p42~D9g@kReKThT`yH7 z4=)dg53dM!A8ro!9BvKw9X_Kugf`h%>E5Ax*iqgbdS^7hswAlcxgD4vLWyh+oT zmxum4UQl#9=f{e@!X|y-KV;G^G&5;OZ_~hxo~Vu zslEC7d7-yleqws<^<|;I>fE|Fhu12;icqey%($^K%v8B%+*ziyLYR5yv17Ap%fnml zurT7Lv_dhh?V;xi6>dA<(x?ib_~5xQ z-f*YlzVX9pU5Fi&}|RD54OuOz(vygA|)!f8t59q*qNYJaah%$0r3A6JCamzISi z^DR$V*o9SvQsrH3>Jw^Pcd5M{DXSAlYb(}HO2@u5oV62c9}D+S1Zyv9t7j~%v%>uF zriFzgD(|1ytGsI7Uu>!h-@h%4m#>%|%4%oH8>*!Syes|G@I_+gX9U!pjx!XMr?TYN2zC&G1iEL7vRd@ro( zP4AihKXX5JthCnRR|AUi|3~gY?bzC4x!QoW>r&-=_7md@`sO>5Hk-s{ZPwz>(#Y;v zJF~W(jmz16YF?Z2dip*Xq*xxz%S)tiv&tV@!Qw zJg9!oklTR}YX9hf>gCw6s^|Ph{k9}DJjdL#da<~yPO>~43)j|O?6GH`t;{lGQ< zcC1-FBLs6RZ0Wxv%i}RF2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_< z0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb z2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$## zAOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;| zfB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U< z00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa z0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV= z5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHaf zKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_ z009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz z00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_< z0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb z2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$## zAOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;| zfB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U< z00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa z0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV= z5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHaf zKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_ z009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz z00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_< z0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb z2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$## zAOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;| zfB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U< z00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa z0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV= z5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHaf zKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_ z009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz z00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_< z0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb z2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$## zAOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;| zfB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U< z00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa z0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV= z5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHaf zKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_ z009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz z00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_< z0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb z2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$## zAOHafKmY;|fB*y_009V0L*V+-aHzQ~9C}Fi1?Az;xPAf`1Rwwb2tWV=5P$##AOHaf zKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_ z009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz z00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_< z0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb z2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$## zAOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;| zfB*y_009U<00RH52^`aPvJ74u!uYs;?$ytjexB4%$;piWi|&)sFArgMRT5GE%vpz~ z`pv0IQa{d5K}z+XUFP?1)0C;8GMF6~1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U< z00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa z0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV= z5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHaf zKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_ z009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz z00bZa0SG_<0uX?}e?tPjXEjfhzw8Y&Li3q1cZbee@xY9ionH}}%S@MypS>cCeeV2{ z@dYc6j@@#8Y47aj!lpvW*t0Hp-L>uQuPg0+YjZgA@XFHOw>O7F6)WzZQE}evCqhY# zYrJB`6QSa~Fg|-lMd@?Tn;Ak?bPwU<<@%}6Po;jUWb?d=*(LvStWa(KvlP$1nMt@1 zo~!V46wiy#n^6ou_l6Ljr#LFkE0_QCDlRDbO&T_Y*()r}*`Y8$i)(mR8dpUUSEzXL zc_I9kIApv3zBwzZ3TE5>@e+%7EO9HGz^y)Y3vFY~$BxaZ4V&K9JaMbSR6X~+l6_*N z@FiB3FsHV){est(^uDcm%;MZ3zp;wuu^F>p*SvOi2)z}}n?lKo+UAmy^P1~QLht^_ zb;5I%&3(s8RvbIFu*vMAO}Mr`gb&qQ9RzU^+oTQ*0v7}z009U<00Izz00jPTC7}IH zp(Nkm{NIX!azg+D5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb z2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$## zAOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;| zfB*y_009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U< z00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa z0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z z1Rwwb2tWV=5P$##AOHafKmY>&{RvFmde(}A~)*VB;ckbRkI54uP&_1+v zabe}oorP#MQrI&vGO*{Wf&Rtezmo3Y?j=2gySMcBjrRTSQs1_BXzR#Rm;9B3qf171 z^z9iC_`O@6!i4`56@;nl8hiE(?SAT-$A1ES9LQGacWHbo&jz+bHF_GGKXGf7-ODEK zv-`pFiCd49m`S4T$*u+ZDGf*TI|;9_hbp3-oOC7rz4A=_3nk&ugNaxCU8~=vVdIR< z|ET=U!|u04i{w|UZl&S6qTThSiJjfsnnOH z4gXe*=OOulBAlHMOn?~kYVC)0cRjKsb&y;rCA1?jyuy)R1dP3e6_dT&kd zYtwsodf%-3BIRR$st>03o74Mvdbd2=mGJw>tc>67@;7(8TY0i8vHNz>?yl6%?#J8B zl2dsMdUtAP_v7s@F4|3`c6Rr6N&Rmx+C3nDYhT%w#&AS{t{&$ewl_m1qyoK{Asog>bwD>}Vq z&*11lW;GCFjy(f?{XM((jt=bW85~mf zV#+7*>>n5z-Lw1Z5VLUt|DC(HUKwJBPT)DZ=j!Mmb9Vy&y+hIaH7Ci~$iV1O->!k4 zq2ch>6Pxsnj_yhF|GsGqvNC*p8XK3^ebbwbUOgPM^o`@pMy?*&x_fAw<@fu?dk${z z9~|l1vNHz$<%#^Y>KWa=C;HD)eI<2OtgNj&2l|Hg4)+YJafD|~Ofx2d?hfs)jW>5Jryk6yTBJfvtnv2DgUm zj`Q8_eBWL4?a_R>wP$$G;8lvV$KdpBx3(0*h59KCHoj$@tY`bc(7>L)ojn8lwhj!B z4(=Z6+0i%Dzfh>f9%`Qzy`(AU;|gtpg5c)8MMKw=x31+?@c4O z2``<*g;Wf7?A|r7Wc!}oBU}1jwWPoA>e1apeHZQ-P{SG-7+EqrxOHjcg}Vl~?%BO{ z$KY`0abaBE@7cPvxWrE_RXHPZq2IS>bnozzt$Rl67k8baL^iB?anR*NSsY+;z2wP~FVaspZrj)GOIXHCX;L!H91N~YqhnDAWZr#0g z@2-KN(UF20PN8dHbX49Wo7eX3-6Pk*y_?rvT`1aY_TfY6-l37f?L!0og~6fGP(G`y zy!7Joo}SL`mX;0cw+xPs^o)kmi*1mSPkZ9Ca&70j%&Yy=@|saz`kC^XJv|-k)@^8A zoq2tx{K3R;_e}Y1=<+e{p7~hf_eh2OTGy>~sXbC*3obQy;h9w$vo#~n=2q<$LPp3%ajLX^&`c&j2Pi4$8%S&5A)M%O5p49y-4CFSN+`i>ChhGz znR}};P$?%XZYW*x*~Inja?+&b*FwD_dJTL+NMBlOS?vZC@WsznSXO za`2∾*F(3~x=M_?bnKIJK-*EU%uK#*(;ot?mw`dos7Kmv&vg`lX@t-I+uC`tGjo zl`?rUb6K@+lWHf8by~Z!J8>EIF74~DP(f0cV5KgNQ(bw{$byu=D?KO<5lXP8IHCF)TnE#_!jkdj@&=8DqrOyManF(>

a|!113RAXyF_*K=<&RC-M#fxDHh)gF1Exh*=Fj=)aAuyGi1s(Ll(-W`;x0n*|x}B-fN*=Z^|}E=JG*n$8RxZTP1V( zp1B+_RhzoRw*GEYwtX_2KeKplHDwzqbNLGk^$}CHr81Xu&E-y0t*Of!EYzn>txa9# znajPVx>J{LSf0OVYIExH0dx7Psr{+THVgH)rffTAX{|Mve=ubmGjn;|LjBm(c{K*w84w1Dl~yL0ryphJq-y3F`Yk=z+?7ggD65z|_l0w{ zXnA^=JNNl>FV$oD@5$93+t1XBC3RN}GgJ2&<~~b7=OsZa7MGNq`J&1s%=wk=XU;D< zqojFG2(z1t5tT~L$>dv_E7}!cMP&$cmj#QhGV{vZPfHzUINN!dTV|vpsfd=^c2Y11{Ho2|7u$3D*t)UwxqWQ?Sew+FGUqmVjE!wrD{BR5 z+t5}v|1t|>!Ihc2%VtaF8L+d~vN>7$c3M#yY%wtzUCZ;AbnMx^eNW%6!kWRI+TN|p zHg-#juWpuX85~-&c<~ZDmfpT~YqGD~wQos$!($%B|Kr|JK7&JBckb;USTd|VVhDZ< zq%D-L;iZkc_AR}re%rE!#+{3I*viGw+P-1_J$Kvn*@};TrsC4LrkdBse;E@r|`_MRF9S`>tkzWRz8cu&m0JD=JNWXqD{npSaJfX_BP*bwEKW6Vuznkps9@5E^&e+n{e0|KzAO6nrQlypU$Br|e%E2l& z?5tf)UhbxY)dN~JmYtRiR&n@wst16W#h&b3Gv#Ehr!-vi)Ye%5vaMKHhW^~qVe`Po5-9bLE1t5f8!S5itzx}cw4{VdSY!nL|9AFcB2u<$V}aL+`@JGI=VpU{sTd}xak?M>UUhu7JA-pt;PJiNahczA8c9bT8KPkLQBMORPJ3#RDW zDcX)We0+Am;k6xacx{IpUfa=z*LJXB+Um*5Z^s&obZ?ti(`@yWm3#k`a0jR8o2Te; zr+s^~_=dH@zI_`1gYvgyi!7g0!`~%;JEl09|AX?Mn8yF8{B1{mqVNlpzpAnjYzMwp z&uUwf+MeZqYJSvCgYCdi6rb7m%HMX}b$Z^pduaRQ29WiP&0o$TXY$DS-fy(*p@CKfV6 znOxB9&97c^xwqIS2-}ms(?5|{eAz$Q!@V+3JdP)7ue(oGGu3RFeO~UQAWqu2#KOI? zpIok-qk?Cj7&w7R`r(UH^kUYEmn|Kq+mcN4?!2eC{yo84@>5wYS-y+upK!PGROG;I zNP3DN0I;WG)=p{r%s?m`#RRpkE3UUsY2w9Hl;WvmJ!#>dix8L6r#9tuv3|-+m#)WS z;o?U$8cz?O($Zkkb#yF@+xgxk$0_2VjvJ>qO_F0epq%6|Mc9$%6sM{3&{PMnZOB1Lec(#5lyzLou8}soi&7!~U9dxWT zDZKaBx=j9Mlfv5?EQ{av57VV@dk2{xcV*#i?{J)_95R2~OHAi)dyDD(ZLcw%zwJGy z^S8aobpEzCnaI~Z+o<<{kxzHovj}mKWtB?+i_RsZ+o)iJmrx2hs7gT?;7pfqWkEcSwTtr9F3MB8NU4pCCa*{r>jUDWVey{b_QzCmwwo+Rwv3GEW^F(5 zaNdb;SS*vUc*j8BaEwi#5?`!$k#-&s7H{3X%RXnR2nM$7-QLr;r*CNcfUFZaymyQ3 z=8Jl8Xxr}0uW!qiJp)%|N}u3VXG=nDQ|v{d?yBSlwkJV{`=xe8v&DT|2CdQPL$8bb zuTDO&f1{liRII?JR$`z8jlA=Y;uN=i@tL;?|R;`x0kYn8vQp*)>mNccruI zoyKmjvm2Yn?hVdvd>XsAI=hK!?BaXE)b_|Ub~bTXUBvo0^W^+K;_M33*nPs;HBV!A zue0l&#_r3`ZfqL6Z#uj2Y3%;q*-cDi_o%ZwGL79YoL#6sIlq5*c7fU zuG-o4PGk3MXE!#D-388Wd>XrD&Te8FyJly1WE#86on3g^$@yL3>z&5#HO_8q8oM_+yYXr4Zg6%J)7ahY?2b%h_d#bDe(&V`?sRsAY3%NCcFoh+ z-S6yrr?LCGvm2Yn?z_%zd>XqSIJ=2y?6fB@wu2+n*!`=s3r{~eznOa1BGdR&n8t3t zvumElZh^DwoyP8bXE!#DU8A!bpT_P5&Te8FyEbQcWE#6JXBTQt&hM4Zt}u<=ptEb9 z#%|Qv^-g0KKN_9Z+t@UAZ*%dDPhZ8QzrO%kh>x|S+$(z4EU0f0DopN?%c4wt_7XLokoowBC&VSJE zxz0{ej-M>PrKz26c8%*}$Kmn#nEcA}cS&wnCI9iqWtaJxW%jJI#bEDyb*p;9($zXU z^YeCVa=Y+kYFC-Tb@5%ErfXgmr6(`P@4NV-oznFQXHjo*@hPJx<8=G@SuKZwk(%hb>fbQPta6n1PO*EiZf>Z~3Mum} zzAwv8eJFAno;B;xBlUBOpQ*7}t>|{<_n_>uF#Bcqr0mA@Y5DBR5dF2Yt2k}ep=&NW z@qY08va{kD3bU&?%@tN|7N2EzzJ6p{yez)QoI{o;yF0Am?)JH1;<6C>hN8Vc$FEhHZ=Gm|j_YnVx)4-ba+BB*xPB6J=@2W7_|keOZ=*_PL2p=w$CJ%0dcG z`?JJ9*^L*9IvJmui#n;e-l9%ejTLp$@WzWeVLnmR_9+g1W~8W3i#lk3V-ICPe?g$D zP}HYK-CWd0E`;8qwps~ctf=iz#xyt-^_fvm6m>F^9x3XlMgO4vfjyLk-;26X)K8DP zxu~rLD*d8)e)Z<0HH0p_> zZi@OyQ7?-+XnkZ4W#OWz3q^f#)Xhb0r$-_57WE}jj}`UvqaH8nOQW7B>J?ERDe4zQ z9kjl%hqCa(s0&5?qNtmTx;g6JqFx#GSW&Nvdc3GxqMj(~)~JsZ_3Egz_n&29P1O3O z^@-(21D7sahuFO=wAn4LH|$;(+U@4_i=)=BaeF8Wm)p&*ar;#k*4oY13*&Y#3wC-I zKQA|K_p-3wZgGCMds*0Ew>Xd6y)1Ot&FSBd+U8|@C<~p5PJfrhe@7#CDhu7Y&{J91 zI7MGEMcb)eewBqyxzJNtco@3+^4*GSjQNZMPF|C=nF)7MLPJAJcs ztJ5EpKH~Hzr1v|0pY+X6e@$9fEN`jW(|0At()p@X^VN?{r|-{8!;JXZNef_?mB;?w zj_fjh^%QOU_JZ0|uZ&96zJ4e@COw+!$E0n&xIgL*;g{0cW%0d2lePZxb9_vWC2DUw zq_fNXZJ&}|rq`BbD#_p1rsx-xPxilSiauw?WdFBK(Z86YUy@A8F_5Ky-xU3IY5NPr zB-YEq52P2&9J6W&^JV`}=0AUbQU6N1d`s>hG{v{}=6betZDX#_kgjv_Jwv*?FOTmW z>51N4*GV5~%yqqV*59kt-(O(i3%P&0w7p-pmBkrq9|O`=zsl3!DP2*>^;Ob~F3R;A zq&K4*? zUf}fKNEaNx?@HhA())pQ&3K;PKT9_`zQ2~vE?fPS2-IyZKeMH4n)2}TrFXjc&z83L z|GGuKm*}CkBe!pruCLF_w^q8>wUFT3-_|Hk#x%@vMUF+J< zH>7vC@;@wnmn+{7r0;e9Ka;-J`Tv`A!L_d$S`t^g`nK)FsH@MXNk8QHoGo4H>Z4A2 z(c^jkmrCF5%6F;sZ7%)GOgsM#7T)o^LVE0A9-r;y4m!O~Q4 zcH_s}rK`@#0amGApI4` z_XX0SDp?O1kG0avUHx5Q{^@1;?UAmk&-2%BdN|itO82_@88+?G+b3Nfa{D()SG)dj zgLI)W_kX9^J3fCR{jiJw!_uv8KKrEfqb|MANsl`Hm(u%P{X8UnljHgK(ziSRN2ROW z_;ysf&DF@=y-_}T17joSxz0;Nd71EoW-XY!V>|ZTig!vk)A`=U zgC9#*Ii5e2Zg%#+macTVL`O1ryYkMKR)dX~^^a#ruW;?5R(jOsXOVQ3TaPqIcQ{_p zmwwE}-y+@Q_-~ND!{z5?(vLd5O}gr6&Tp4=_P1G9-Zx3_bM4{n(nnl-J1G62%g@cy z%`QKGBE6_SkN+dm+25+!`t*y^{Vx31rQ2M4`mS`P%ikl?6|TO2DqZXH_bcfIu6_Kw z^ery_*>)u6%3md2?#73+q+1>TbEF?|;V+cF&4phs-QnzCVBwv8yL7p;?=tPm^9t!u zm-FeDUf{~NOS;OHZ;yo^&+V^~w$Hi0|17fV;V{<>27CTG7+y4t1xQt8KB`TL}^zbUl#`UleW zuD-{l?{ejRtMn!p-%Zk+U3#}lSGn?iM7pjyA74Kq{gCTF_ehVq{M={uj^6{)*Sh$= zC0*gx%MVNUy8Qh>dY{YB&n*1>JpJEDA93xeT#%bwc`KzWewEi>we%6!zRs3j;PQ8# z^deWD3#F@_zDT;mtxsMgU2yqnmEP~{*GWI&cx*K7^7jhq8rR+iq=Q>e@06}~x|(|1HvEE;W^K>2YU+;Jpq$}Ng_&n)@uKW$s zO)mZyNSEK7=l?S4eXf0VNf+Gs@Dk}yx$s-1Ynt=??vl>_rq;%3-?#GE{#hUEPuA_iv=vcINsYEW8_Ue>^4pKTF@?+Sjk8 zSGe${dPP#}^l8%B`GA$@T=P%!Yx!Rx{iNgDD*c4x(;;2q>gT1>_0Im4(%EI@+b&({ z`r~ftTF2um>9sEZua~YUR^E|Naz+WQNo%U%7xT)M*TuluEg%m0<8)64jb zNVmHBf4y{#n{WTn>|K4`Al>Bh_ipJz`u9x6?~~Gt-2C%-)5AIM2c$<`|N4e>aO2T; zq*plm?@8~g&)dsSr3-F8eO$WDmG4REQDBnE|R{@ zwVx*Go1Og%>E*7zFOz=K`EQV}b39%yUE{{P?b7!59yP*X?QK-L-qrUt(i5(Ju9Lpm z<>yA}iu$}fH%l*f>D?y1)|LM*>4NjWM|y{g?+el$j{ldXHyzC5|EBaKu6*B>Zg&3v zAYJR?|0n6-c>Yp)*oFU%bd#GeX6O}erE71er>}Gsi_SOnYSH}Neq^EaCRe^i()NBJ zv0oo9lD^B8?^5aPviMe7_>R1MYo+b)(`EPCve=5D8BlrKJboL6%%KI(p<&NLq zS@`s__IgCR%8i#ll3wKc!%^uKg*<;xN>@8RGxZUO>s@;~L%PQCJxhAr@i|BOCYPTJ zq`%_$FO`1W`ClrX?FX&@yj*&b^Y53o&$n5Tth`rA_d33RVA|#PP12Pvzc)%>U!Rxn zJ<`kF{Cb;ow`<>rrLT4Qy<2+0c+UUNr3)_nUzxv~KfftmFl!l_y_5IF8&`& zPq_8rucg~u`RqeaRW7~RHt;v*`KglL;p}UqYg~D1rL*%!k4z2DW>d(7YI4@p;zR#nSs-`?*MZ*tM5SrN>=+`F-gsSH71?SGxAv zFTK|Fk6qFeF8)2z^{#!rRyw<4eVM;2-&@V!#dkn@r{nQ%=}O1z1JX5aJpHJJPd~3w zrO#{pskFUMuxWpxK40<$^LO!mS$eIj&u>ZZcjf<~biuWc$D|jy`Rtb#KDD>;<>~r} zR)uTd3#EIVey((OS^1Ypf5-V>YTD&zjr5bQJ#|W#yZmgHUhC>_KsviD{wt*)cjX1J2I*Gad!^4%yM#*!GVKaX4Zj=Vj7OuE|He@eR6_1Diz*SPunOVYir{=O>R zih4cegFGM>7y<`zmRTo`FT>h-o;wjycn;oz9 z(hoa6S4b~+^|?j5#_3(s1()Bw(%EJG=?|nAxb*(Sv>V?(D&67AbCCr_$pt{a;E~yYTUk=3RTAdA9niEB}1yMNTh} zu6O!8>E$lIdb97y$Ae3yhn;_`^rx!w`dceq?#g?G^u)nDe2?^lPVbO@-0>KdzShNe zjr2n*ByynO#GU0Ijwf0176#@`wC5nac7o^-YA4`)eNx%{7N_O?0HW#jWQ z>FZtoS4#K0`ffM-i}Lh4qzi68@KW=y&;5I)tDW8API}I9Ga;)6bKx zckOYhbd^j066tKcVe9RU(qk_ES4fv@|8K8U7wYqduad5G`5BRJE6vOQ2I&g-e*CS{ zt*(6Ulx}wRw@BB!@%1)oEm`BgNoxH6hxxnu`J{Aq8P9v9>s);IOZU6{e_guDmH)4$ z7r6BPL3*ugPmf9Ocjfz~be)SY6vX4_d3onZS2yPR4C#uH>jl!;W%)g)p!{sf{p+N& z&)-^qdx7*#uDos13x;$1PU-C59yLC@%-^lw_DW}$rT5x`^6TQePP*RZ|9a^#fBZ-~`?prDJZfa& zac5sCUFX_swRDH8@3W=-=V#859(MJ2zI46gw^+K|jVBjNZ+7<0(sj=M#nSosygpnZ zU0KNMqgT58V6Lx}UeuhAKYOKXTzST%E2?t;w@Kgb%J)ao!HwVVlg>ULVSN5nI$NJu ze|<>0*Twg@(lsvs-?^}olYYutGBOX+Gi zpB$53;KI*7SN+SCcfRxkt~_T+mpfkPNH1{n`(o)89eMk_M7q}1SF3bgA#aZz=I`?R za_LZ*xKF?1df-*kM_hjPn16cN`1MBVM;))XPVx`ofOLlo|8D7uoAdm=UwZstu0JYW z=j=Z%UFFsnpO+3tbNeqzA9dlsCjEeGAK#X)a6G=8;{YvSA)BV!fW%+xRbfr7r7?FNdtX38S3f_Je!!Lg7iRD34MuIY&3rtf3I|f ztM4nNH@ot@M*4mi|Csd6t~_s-e%$eRw{-UR2v&a|m#%l?+h?R}9iRK87r6TQE9nWR zzbU=Q)z^2Wv-htS|Ieg%xb&Zte!_*Xc#g{7oVTCTrLS@Mf2MT38=uaVzQcuIEM4K+ z({j^pf3r%u+U4(Z^LP1qiFB{y+atYVQ(phClFs`38KES+TDsY#|61uyF8p=T-on`U z7sA`6+uZnllk`DX-uFrGbnWd!(iP9i(?2YIx8w0yvv=+1e(BB5|Lf8_T>kz}`u24F zW%cnZ>APL|OV3w(bN2J3{rkH!r8m3wzrg(6e&adP6R!O&lCE~;T_#=Q+H14)Ev`P= zrLRx_&3_v&Hc4mi8!f*>()(R`Un8BJf0+MGrd|KLMY_ByZ%-eV4sN~hap}#jzV4Q; zYs`6nLAt(>hyN?-4yV5*z2EWr-_mWazy7224wv6wNN4L+%kRuOotL@tpDtZ+?fdD{ ztuBA(NSC|zut>Vv`7bwr$9I+V0@ohaNiTBw*(hB&n3wkz(vLa&LFpaNe^k2M^{3ZM zU*qcg52b@k{|4z=w_d(UI&V)M;l0w?_d-~G-zr__#+%!vkGS~nl9ey2Ita zTDr-NuLbG5UHe%iy~)+jGU-ZJo@QxnrVlkK+s13XbX6g5pD&TFXwG$?biw(*N_tUa zUf(0q)oy%ygY-jW{C^^yeO}nw^QWY1UH|)>*}M22kiN!+e@J@R z$u5{z;yQQywQ~ygpKVtcPn)HK?$63-}as1DbzSsF*AYJM5*JQdr zZyzs|u660POINt|(Chx7EVG5hqg`nXPd zr)!S~rN83%zE8T^@%f;IclrI8>GZPrJ|*q{p5o7>H@o=$Lb|mh&(AlcYhC&NRyw%y zAF=SR{(oZjj`!oz<@I@d|1MqO+T$#JaQ0Eh<88M!pQX~Z zF8rm^HBPrmKdu@nSGMQt?`JniSGn=v3hC@JKCh6j_<5e+?b0jMA2ck-{_tw)I>+Z4 z>4NJ|Z<4NY?~C3hz1-QqOZuSW^Ip@gJmb<8ZhZTwbX#YhpHE9)>&o|e=|u-~|G$(j zxbgL?(&f#0d;7L@aQXXt>4#kXKPuho=8K<6Z+7uNDP86IOUZ>=Pr3T3l&*5~`I*w$ zWqh9@y~34up>%~yf06X4D_@gzxtmX3B>kl850^_{<9K#S*Sq<1vvkEdIiGFP-*M>= zN&C-tTqAvpi|<4NJopORkT;=fnA+wuLf^!3jF z>(aF@z3)m_yZZf}^di@vek`3`#`~!GyY}?2(g)po{q)63zdmmtXGuTe^mC-E-1>2e zba3mbi=?l2?d3(%wQf9GBR%HY#|G(fSH5oPN>{%<(sizUr|hd1;y)+6B>lqGp6s6& z?it$Mqwll}J^IIjd$#Tv*m`C1I5;#os;`vP@60tm$A4wGC;exHd-`|lU;j;vvVU2) z=$FQ|t8Z|qNB`3Bo~spa@^5wz437@(9t!rAC;2y;O#LR)Q}tyK35Danish7jb@j+- z@#~;^;&%xd!Fv0$&a3phPye{{;As6RtMmRTUjn7v?A|-tvt{qLQE@|S@ptlVJEycjPw|)QO#b@mt}wi3@G6aR zJ^ce$4Q?H=%1PotJZDm*x0dZrI}6lZDyTa zFX`;+4(%-sEgRNb0T-?bLs4EX1?rVM7&AHyCM_C)zFnZZfscHu{>CQl4AC> zuDYye^`@4N?jFU`DKJtRiw;PHPB*r<=;$Jwzf2^+PJ16duX&IVw9GZVxH{5V%lhh6@o^EG0R4a zqtkfEyiv^|Nv_jc#!7n@pRC==d|Bp{mOE>f=G@+54J#I=qb0^00c26Osb6%bScE9n zTK3g{{tFB{)~#G!M84W`*3!0mUDxFnRApaf30S4YJg>f@J$4vVX0V}US(*o-TOG3a zlkZn_-?nGit!t#lagCUCwAf#)I7!{xlPV;QzQ?|@LW{nB(YESZYTm}VD{aOt>#|;B ztx(^IV*N(7X?AH%t+B8jEo&~b{92E1v4^DJ#2Q&D5!;~QQ>#t-$H11pk%6AR{(gN; z%t(sFVzr)7Zx0(<8q_G(*=S>&)}+mEWq3)e^#sFaRh*KKV^G$s&97zs>PS#FOD)mN zUP04Bs(&SI*$S+>G-vB3u{D~T#tw6n%gVK#>ms7IE_3O&>ahq_DXmEpOlvciJ!v>; z^(BMVz@9xryJLRSMq|Z{1FKqG>*eV{s6^Gl;xJ^7Dw?HcZF0@Ju9sQ;#&O1ISnRS{ zDjR$3**=_BYwRxS_39Sp(UDd4MjLX9EzL5oaWH~T#~^dc+SlZ-Yg8jN)=3`G0NXZ}}-^R!y8%q^n%4jvVLVooqtUi|Wo)N5B*Ze?AeA(bw7}N=qffTV zu##KDutefGVTRV+mYG>`?HMd1=F*wMOUJ~EW9(K2l_j=x10I(Tsm1EppkiB%d9#ru zP2-}3v({9WX0l94#~@288UA9(I6TB$C8bI7c(H|>%r1UKZ)b6bMbL7E zA+sk#oz3Q214Jv+(W-6r%4Efme}QOz64A4xZ>WE#7O93HcFL*Wj+}Lqtvd($hV~Bk z47;x!?&#E)Zf!Icaj{};#geoME*(2JHgs?5T&)j!ip8>+h?T_*(&;;$3@uoe(&Uxi zi7$&Otuc>{jh(TClk=I3k;%DI@k?ASc1yoU{PoRLJ-hbVq@B`h z?CxA2JGtp(%rsk@!n@4uC2`@gCKia9biid0Kr zRfs0^Y=SrU1iwYEuC#v5WeuwIY(Hj+Z`u&Yjvo6Kw7Aezo?#aWJ>~S#E~umedx& zaU)?7S#wP$mu!BvEL&vBUev-RqgS%?v@ojPxUaFP-7Mp(%RCfxRm@RmTo4q`Tz3u( zZ6Do{EF@zlFH6G2z_wMhK;79uZ8e&;wsg!f|8y#;kEx_t*Kip*W&I~kAI|ua;$UZv zJ?S?tjtuv09UR&or!$LaV?(C|T%3VT)q zwLrGoNZX0!M5B$RX-y$kW3n|V8YcV3WifkN{@KPp4wFrWHI9;#zrQ**DJ!KV6U~#= zku`#N9${%_b7nRz#0j|PveoPT#@(`PZA`pkM@gr4%ZbGyW-;HkFf%txIIgCW0e@*U zvSyJ6h}DqdkDGUMx7xE<(g;)U`jm-WZ3C6nndQ0|Swc3-c$*>-Wiw)}=t+X** zy1SRRkjKd}GEpyD+qp4ay<41i>SECt)Q}voXD3c0`qEETaLl7+AzkNMD2>JKS<6|P zRjkrl)46V~ZFp3Ul}XQu_$^4f0JcZ#^p<9^+gV4~fqsvDwc2%)VJ^ zfn~R3B(vm2%l7UDT9cmnDeAZ?H=wFerQaAw{WP=j+$JkSx>+?NbBYTNi$f0CK+ur2 zP({~bHKH9+hVcZrt%TXiD0Yq{*RgwwLbBpbR$%56&C?X)PS9#ITRkSDge8}(qEov| zEUPwetg^9Q17?g!XF(zEflL(}Ofu#e?Ks27<`_#Fk8t8hn=TgP=-8T!j`4ip_+sXZ z9Dj0?tTzo=T*4ZDLzW`8o|-<|S!QfY4JREx74PWP!vj4-!^P3bvSCwNgVp^q>oZ-Q zE%7KI8_%=ot%UJ;-AePffLbG~WkhSmv94Wff@D_}ky&Gm%|+QY2g|x1Enrp(J;Vb} zi`UwtqDsBv@+meH3#z=Nk))H_vTSyX>!?WI>}(WClZu@wx^=W%oJ_?riOv>Vi`ce3 zO{vkQh$+bY0bTrB*0?sw>M)HpX>_*ki`kDm@-)tPq?DB;#-A8atf@F@{<)*<)NIM+X~tH#X>0x;xz>0}$S^w=Ox+8SVNbxV_NgrP7CEg54-i(DPE zcxaZbcx?!<^+X&8HZ~;t4C{5PPjHswM$cp#*EVBtWORpy;QoRBWT3W$Yzu0~&PjdP z44Gx8EuLU!{)WXiXB;IfR;UwY zDrPCN6IL@)Q;wCAoe{*PptTEItJ%zwG*>f?Bd--D8CYUI++VUqT2 zj_LRl3mf-__GB}a-Ib$wCN(9`lTS0VN$13)vCc%5vFy-K5!#ucMQlg>v7yJTrAHw# z8w!#XM?;%!jnW}-QaV{RCNN?!Rh9PaElcgig-xJw2DJ_oi)rmLtpIC#aT9T(ns76T z*=1v1#E?W3$KPTGjiyptrUsSmv6GcUzgs!je9;)YO@17tPGQ+jRt{;MXzoli8waeo z%uma9v6*CJq8V9dN{>y%$oijIWFxMH5@eg=%sIZ|YS9p$yx}q*QB4k-?Q61=b7m`t z1+;D*rwKbTPxof#o=zokp==p+ZmP<-u+40iCo2iFu#Be0J)PF5lRU)Da*QDzgDjuc zKGN|~-BS5kZWh)V5-*#0Y$(#Sr%`v?P8;XaQP+ZI>uphpFGC|IH7AQYZh>OaG`U%Z z%rhQ5zGly$)}`tQHZMn7Cq0bo*)w2^YmM<5p>6KBu|g@w`P3p*R+FQq*y^muwZ%j8 zw6?M`T2u68x1h;l)m*bf2D46%sLeH5ec6*mW(499iuok3l$EDsAXnpWw6Gm|U1_$O z;7l60tk%;0X6eROmS)U4Ws-yB7|ondxHgZ4wsm0~NVB({w)e3pjfiz~qhWed*Nq#~ zcq$cZyO>~PXo)9-lSLBOG!}t1e4CXm;y>^I*jez!e)%E*tUkT?PWUq zSTzoeT5NHr63L_oCz`c3tWh(OWtx|^c4aBOC-!^6hZ2mPG&K~dc9=# zWYUX6Ry>qX-E5C$8A#fW#iHI5H;BoEqrQ{8nXu6@*e6MnhHhcvuFN8~NGxb_dKFVu zwzA%)lg(HqaieM7P?@wYX;CP#SbJ93mD!ltYDF!+)-kX6jy9e>S~Ax7vz?3)OjamL zQ4w3>J=;dE9@?6XhgKQ(9@M&%3@p`HKiX2MD5^0FVtvA4)X*D8khl~!f9pqbw8zO+ zmA&wbLr_`?wpK|4#Zy6hR+6hWZ0OcuW72WVE&0Ste9}bIlq8~|#9WfhrXgegE#uZv zZNX{oSw7t1e;nE)*5oChp^Fo@tz%-W@k1w;&5Vk}U?w zcjM``1<|(8f>?7g8(aNEiY?2s%*WHJY#pj*lDtvZPQc=_4xB=XHJ5f0d#hm4q;0K5 zFtVxN8kA+cIIYK{R4b+hNM==wSx>eeGE^Uc!+CJTG6tP71*?3xe&7K aOuQi;ET}uBw(;OLV$S$j8XD29F#j)2VM=uX diff --git a/testing/examples/PIC32/readme.txt b/testing/examples/PIC32/readme.txt deleted file mode 100644 index 8a5ac3b43..000000000 --- a/testing/examples/PIC32/readme.txt +++ /dev/null @@ -1,3 +0,0 @@ -Here you'll find a simple example tested with PIC32 Starter kit (source code and .elf file). It will blink repeatedly the LEDs on the board. -The program was compiled and written on the target using MPLAB IDE v 8.0 that comes with the kit because openocd is missing currently the ability -to program the flash for this specific target. It is possible in the future this limitation to be removed. diff --git a/testing/examples/SAM7S256Test/inc/typedefs.h b/testing/examples/SAM7S256Test/inc/typedefs.h deleted file mode 100644 index 42136426a..000000000 --- a/testing/examples/SAM7S256Test/inc/typedefs.h +++ /dev/null @@ -1,50 +0,0 @@ -/**************************************************************************** -* Copyright (c) 2006 by Michael Fischer. All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* 1. Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the author nor the names of its contributors may -* be used to endorse or promote products derived from this software -* without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -* THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS -* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED -* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF -* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -* SUCH DAMAGE. -* -**************************************************************************** -* History: -* -* 30.03.06 mifi First Version for Insight tutorial -****************************************************************************/ -#ifndef __TYPEDEFS_H__ -#define __TYPEDEFS_H__ - -/* - * Some types to use Windows like source - */ -typedef char CHAR; /* 8-bit signed data */ -typedef unsigned char BYTE; /* 8-bit unsigned data */ -typedef unsigned short WORD; /* 16-bit unsigned data */ -typedef long LONG; /* 32-bit signed data */ -typedef unsigned long ULONG; /* 32-bit unsigned data */ -typedef unsigned long DWORD; /* 32-bit unsigned data */ - - -#endif /* !__TYPEDEFS_H_ */ -/*** EOF ***/ diff --git a/testing/examples/SAM7S256Test/makefile b/testing/examples/SAM7S256Test/makefile deleted file mode 100644 index 9e1e83f8e..000000000 --- a/testing/examples/SAM7S256Test/makefile +++ /dev/null @@ -1,146 +0,0 @@ -# -# !!!! Do NOT edit this makefile with an editor which replace tabs by spaces !!!! -# -############################################################################################## -# -# On command line: -# -# make all = Create project -# -# make clean = Clean project files. -# -# To rebuild project do "make clean" and "make all". -# - -############################################################################################## -# Start of default section -# - -TRGT = arm-elf- -CC = $(TRGT)gcc -CP = $(TRGT)objcopy -AS = $(TRGT)gcc -x assembler-with-cpp -BIN = $(CP) -O ihex - -MCU = arm7tdmi - -# List all default C defines here, like -D_DEBUG=1 -DDEFS = - -# List all default ASM defines here, like -D_DEBUG=1 -DADEFS = - -# List all default directories to look for include files here -DINCDIR = - -# List the default directory to look for the libraries here -DLIBDIR = - -# List all default libraries here -DLIBS = - -# -# End of default section -############################################################################################## - -############################################################################################## -# Start of user section -# - -# Define project name here -PROJECT = test - -# Define linker script file here -LDSCRIPT_RAM = ./prj/sam7s256_ram.ld -LDSCRIPT_ROM = ./prj/sam7s256_rom.ld - -# List all user C define here, like -D_DEBUG=1 -UDEFS = - -# Define ASM defines here -UADEFS = - -# List C source files here -SRC = ./src/main.c - -# List ASM source files here -ASRC = ./src/crt.s - -# List all user directories here -UINCDIR = ./inc - -# List the user directory to look for the libraries here -ULIBDIR = - -# List all user libraries here -ULIBS = - -# Define optimisation level here -OPT = -O0 - -# -# End of user defines -############################################################################################## - - -INCDIR = $(patsubst %,-I%,$(DINCDIR) $(UINCDIR)) -LIBDIR = $(patsubst %,-L%,$(DLIBDIR) $(ULIBDIR)) -DEFS = $(DDEFS) $(UDEFS) -ADEFS = $(DADEFS) $(UADEFS) -OBJS = $(ASRC:.s=.o) $(SRC:.c=.o) -LIBS = $(DLIBS) $(ULIBS) -MCFLAGS = -mcpu=$(MCU) - -ASFLAGS = $(MCFLAGS) -g -gdwarf-2 -Wa,-amhls=$(<:.s=.lst) $(ADEFS) -CPFLAGS = $(MCFLAGS) $(OPT) -gdwarf-2 -mthumb-interwork -fomit-frame-pointer -Wall -Wstrict-prototypes -fverbose-asm -Wa,-ahlms=$(<:.c=.lst) $(DEFS) -LDFLAGS_RAM = $(MCFLAGS) -nostartfiles -T$(LDSCRIPT_RAM) -Wl,-Map=$(PROJECT)_ram.map,--cref,--no-warn-mismatch $(LIBDIR) -LDFLAGS_ROM = $(MCFLAGS) -nostartfiles -T$(LDSCRIPT_ROM) -Wl,-Map=$(PROJECT)_rom.map,--cref,--no-warn-mismatch $(LIBDIR) - -# Generate dependency information -CPFLAGS += -MD -MP -MF .dep/$(@F).d - -# -# makefile rules -# - -all: RAM ROM - -RAM: $(OBJS) $(PROJECT)_ram.elf $(PROJECT)_ram.hex - -ROM: $(OBJS) $(PROJECT)_rom.elf $(PROJECT)_rom.hex - -%o : %c - $(CC) -c $(CPFLAGS) -I . $(INCDIR) $< -o $@ - -%o : %s - $(AS) -c $(ASFLAGS) $< -o $@ - -%ram.elf: $(OBJS) - $(CC) $(OBJS) $(LDFLAGS_RAM) $(LIBS) -o $@ - -%rom.elf: $(OBJS) - $(CC) $(OBJS) $(LDFLAGS_ROM) $(LIBS) -o $@ - -%hex: %elf - $(BIN) $< $@ - -clean: - -rm -f $(OBJS) - -rm -f $(PROJECT)_ram.elf - -rm -f $(PROJECT)_ram.map - -rm -f $(PROJECT)_ram.hex - -rm -f $(PROJECT)_rom.elf - -rm -f $(PROJECT)_rom.map - -rm -f $(PROJECT)_rom.hex - -rm -f $(SRC:.c=.c.bak) - -rm -f $(SRC:.c=.lst) - -rm -f $(ASRC:.s=.s.bak) - -rm -f $(ASRC:.s=.lst) - -rm -fR .dep - -# -# Include the dependency files, should be the last of the makefile -# --include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*) - -# *** EOF *** \ No newline at end of file diff --git a/testing/examples/SAM7S256Test/prj/eclipse_ram.gdb b/testing/examples/SAM7S256Test/prj/eclipse_ram.gdb deleted file mode 100644 index 9d9f24d16..000000000 --- a/testing/examples/SAM7S256Test/prj/eclipse_ram.gdb +++ /dev/null @@ -1,32 +0,0 @@ -target remote localhost:3333 -monitor reset -monitor sleep 500 -monitor poll -monitor soft_reset_halt -monitor arm7_9 sw_bkpts enable - -# WDT_MR, disable watchdog -monitor mww 0xFFFFFD44 0x00008000 - -# RSTC_MR, enable user reset -monitor mww 0xfffffd08 0xa5000001 - -# CKGR_MOR -monitor mww 0xFFFFFC20 0x00000601 -monitor sleep 10 - -# CKGR_PLLR -monitor mww 0xFFFFFC2C 0x00481c0e -monitor sleep 10 - -# PMC_MCKR -monitor mww 0xFFFFFC30 0x00000007 -monitor sleep 10 - -# PMC_IER -monitor mww 0xFFFFFF60 0x00480100 -monitor sleep 100 - -load -break main -continue diff --git a/testing/examples/SAM7S256Test/prj/eclipse_rom.gdb b/testing/examples/SAM7S256Test/prj/eclipse_rom.gdb deleted file mode 100644 index db2a4643d..000000000 --- a/testing/examples/SAM7S256Test/prj/eclipse_rom.gdb +++ /dev/null @@ -1,32 +0,0 @@ -target remote localhost:3333 -monitor reset -monitor sleep 500 -monitor poll -monitor soft_reset_halt -monitor arm7_9 force_hw_bkpts enable - -# WDT_MR, disable watchdog -monitor mww 0xFFFFFD44 0x00008000 - -# RSTC_MR, enable user reset -monitor mww 0xfffffd08 0xa5000001 - -# CKGR_MOR -monitor mww 0xFFFFFC20 0x00000601 -monitor sleep 10 - -# CKGR_PLLR -monitor mww 0xFFFFFC2C 0x00481c0e -monitor sleep 10 - -# PMC_MCKR -monitor mww 0xFFFFFC30 0x00000007 -monitor sleep 10 - -# PMC_IER -monitor mww 0xFFFFFF60 0x00480100 -monitor sleep 100 - -load -break main -continue diff --git a/testing/examples/SAM7S256Test/prj/sam7s256_jtagkey.cfg b/testing/examples/SAM7S256Test/prj/sam7s256_jtagkey.cfg deleted file mode 100644 index 0447ed66a..000000000 --- a/testing/examples/SAM7S256Test/prj/sam7s256_jtagkey.cfg +++ /dev/null @@ -1,39 +0,0 @@ -#daemon configuration -telnet_port 4444 -gdb_port 3333 - -# tell gdb our flash memory map -# and enable flash programming -gdb_memory_map enable -gdb_flash_program enable - -#interface -interface ft2232 -ft2232_device_desc "Amontec JTAGkey A" -ft2232_layout jtagkey -ft2232_vid_pid 0x0403 0xcff8 -jtag_speed 0 -jtag_nsrst_delay 200 -jtag_ntrst_delay 200 - - -#use combined on interfaces or targets that can't set TRST/SRST separately -reset_config srst_only srst_pulls_trst - -#jtag scan chain -jtag newtap sam7 cpu -irlen 4 -irmask 0xf - -#target configuration -target create target0 arm7tdmi -endian little -chain-position 0 -[new_target_name] configure -work-area-virt 0 -work-area-phys 0x00200000 -work-area-size 0x4000 -work-area-backup false - -target_script 0 reset .\prj\sam7s256_reset.script - -#flash bank -flash bank at91sam7 0 0 0 0 0 - -# For more information about the configuration files, -# look at the OpenOCD User's Guide. - -init -reset halt diff --git a/testing/examples/SAM7S256Test/prj/sam7s256_ram.ld b/testing/examples/SAM7S256Test/prj/sam7s256_ram.ld deleted file mode 100644 index 1b857c99f..000000000 --- a/testing/examples/SAM7S256Test/prj/sam7s256_ram.ld +++ /dev/null @@ -1,132 +0,0 @@ -/**************************************************************************** -* Copyright (c) 2006 by Michael Fischer. All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* 1. Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the author nor the names of its contributors may -* be used to endorse or promote products derived from this software -* without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -* THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS -* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED -* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF -* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -* SUCH DAMAGE. -* -**************************************************************************** -* -* History: -* -* 30.03.06 mifi First Version -****************************************************************************/ - - -ENTRY(ResetHandler) -SEARCH_DIR(.) - -/* - * Define stack size here - */ -FIQ_STACK_SIZE = 0x0100; -IRQ_STACK_SIZE = 0x0100; -ABT_STACK_SIZE = 0x0100; -UND_STACK_SIZE = 0x0100; -SVC_STACK_SIZE = 0x0400; - - -MEMORY -{ - ram : org = 0x00200000, len = 64k -} - -/* - * Do not change the next code - */ -SECTIONS -{ - .text : - { - *(.vectors); - . = ALIGN(4); - *(.init); - . = ALIGN(4); - *(.text); - . = ALIGN(4); - *(.rodata); - . = ALIGN(4); - *(.rodata*); - . = ALIGN(4); - *(.glue_7t); - . = ALIGN(4); - *(.glue_7); - . = ALIGN(4); - etext = .; - } > ram - - .data : - { - PROVIDE (__data_start = .); - *(.data) - . = ALIGN(4); - edata = .; - _edata = .; - PROVIDE (__data_end = .); - } > ram - - .bss : - { - PROVIDE (__bss_start = .); - *(.bss) - *(COMMON) - . = ALIGN(4); - PROVIDE (__bss_end = .); - - . = ALIGN(256); - - PROVIDE (__stack_start = .); - - PROVIDE (__stack_fiq_start = .); - . += FIQ_STACK_SIZE; - . = ALIGN(4); - PROVIDE (__stack_fiq_end = .); - - PROVIDE (__stack_irq_start = .); - . += IRQ_STACK_SIZE; - . = ALIGN(4); - PROVIDE (__stack_irq_end = .); - - PROVIDE (__stack_abt_start = .); - . += ABT_STACK_SIZE; - . = ALIGN(4); - PROVIDE (__stack_abt_end = .); - - PROVIDE (__stack_und_start = .); - . += UND_STACK_SIZE; - . = ALIGN(4); - PROVIDE (__stack_und_end = .); - - PROVIDE (__stack_svc_start = .); - . += SVC_STACK_SIZE; - . = ALIGN(4); - PROVIDE (__stack_svc_end = .); - PROVIDE (__stack_end = .); - PROVIDE (__heap_start = .); - } > ram - -} -/*** EOF ***/ - diff --git a/testing/examples/SAM7S256Test/prj/sam7s256_reset.script b/testing/examples/SAM7S256Test/prj/sam7s256_reset.script deleted file mode 100644 index 456341d60..000000000 --- a/testing/examples/SAM7S256Test/prj/sam7s256_reset.script +++ /dev/null @@ -1,17 +0,0 @@ -# -# Init - taken form the script openocd_at91sam7_ecr.script -# -# I take this script from the following page: -# -# http://www.siwawi.arubi.uni-kl.de/avr_projects/arm_projects/openocd_intro/index.html -# -mww 0xfffffd44 0x00008000 # disable watchdog -mww 0xfffffd08 0xa5000001 # enable user reset -mww 0xfffffc20 0x00000601 # CKGR_MOR : enable the main oscillator -sleep 10 -mww 0xfffffc2c 0x00481c0e # CKGR_PLLR: 96.1097 MHz -sleep 10 -mww 0xfffffc30 0x00000007 # PMC_MCKR : MCK = PLL / 2 ~= 48 MHz -sleep 10 -mww 0xffffff60 0x003c0100 # MC_FMR: flash mode (FWS=1,FMCN=60) -sleep 100 diff --git a/testing/examples/SAM7S256Test/prj/sam7s256_rom.ld b/testing/examples/SAM7S256Test/prj/sam7s256_rom.ld deleted file mode 100644 index b64854acd..000000000 --- a/testing/examples/SAM7S256Test/prj/sam7s256_rom.ld +++ /dev/null @@ -1,133 +0,0 @@ -/**************************************************************************** -* Copyright (c) 2006 by Michael Fischer. All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* 1. Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the author nor the names of its contributors may -* be used to endorse or promote products derived from this software -* without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -* THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS -* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED -* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF -* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -* SUCH DAMAGE. -* -**************************************************************************** -* -* History: -* -* 26.01.08 mifi First Version -****************************************************************************/ - - -ENTRY(ResetHandler) -SEARCH_DIR(.) - -/* - * Define stack size here - */ -FIQ_STACK_SIZE = 0x0100; -IRQ_STACK_SIZE = 0x0100; -ABT_STACK_SIZE = 0x0100; -UND_STACK_SIZE = 0x0100; -SVC_STACK_SIZE = 0x0400; - - -MEMORY -{ - rom : org = 0x00100000, len = 256k - ram : org = 0x00200000, len = 64k -} - -/* - * Do not change the next code - */ -SECTIONS -{ - .text : - { - *(.vectors); - . = ALIGN(4); - *(.init); - . = ALIGN(4); - *(.text); - . = ALIGN(4); - *(.rodata); - . = ALIGN(4); - *(.rodata*); - . = ALIGN(4); - *(.glue_7t); - . = ALIGN(4); - *(.glue_7); - . = ALIGN(4); - etext = .; - } > rom - - .data : - { - PROVIDE (__data_start = .); - *(.data) - . = ALIGN(4); - edata = .; - _edata = .; - PROVIDE (__data_end = .); - } > ram - - .bss : - { - PROVIDE (__bss_start = .); - *(.bss) - *(COMMON) - . = ALIGN(4); - PROVIDE (__bss_end = .); - - . = ALIGN(256); - - PROVIDE (__stack_start = .); - - PROVIDE (__stack_fiq_start = .); - . += FIQ_STACK_SIZE; - . = ALIGN(4); - PROVIDE (__stack_fiq_end = .); - - PROVIDE (__stack_irq_start = .); - . += IRQ_STACK_SIZE; - . = ALIGN(4); - PROVIDE (__stack_irq_end = .); - - PROVIDE (__stack_abt_start = .); - . += ABT_STACK_SIZE; - . = ALIGN(4); - PROVIDE (__stack_abt_end = .); - - PROVIDE (__stack_und_start = .); - . += UND_STACK_SIZE; - . = ALIGN(4); - PROVIDE (__stack_und_end = .); - - PROVIDE (__stack_svc_start = .); - . += SVC_STACK_SIZE; - . = ALIGN(4); - PROVIDE (__stack_svc_end = .); - PROVIDE (__stack_end = .); - PROVIDE (__heap_start = .); - } > ram - -} -/*** EOF ***/ - diff --git a/testing/examples/SAM7S256Test/results/607.html b/testing/examples/SAM7S256Test/results/607.html deleted file mode 100644 index 852c0ad67..000000000 --- a/testing/examples/SAM7S256Test/results/607.html +++ /dev/null @@ -1,698 +0,0 @@ - - -Test results for revision 607 - - - -

Test cases

-

Test case results

-The test results are stored in seperate documents. One document for -each subversion number. - - - - -
Test resultscomment
607
templateTest results template
- -

SAM7S64

- -

Connectivity

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
IDTargetInterfaceDescriptionInitial stateInputExpected outputActual outputPass/Fail
CON001SAM7S64ZY1000Telnet connectionPower on, jtag target attachedOn console, type
telnet ip port
Open On-Chip Debugger
>
Open On-Chip Debugger
>
PASS
CON002SAM7S64ZY1000GDB server connectionPower on, jtag target attachedOn GDB console, type
target remote ip:port
Remote debugging using 10.0.0.73:3333Remote debugging using 10.0.0.73:3333PASS
- -

Reset

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
IDTargetInterfaceDescriptionInitial stateInputExpected outputActual outputPass/Fail
RES001SAM7S64ZY1000Reset halt on a blank targetErase all the content of the flashConnect via the telnet interface and type
reset halt
Reset should return without error and the output should contain
target state: halted
pc = 0
- - JTAG device found: 0x3f0f0f0f (Manufacturer: 0x787, Part: 0xf0f0, Version: 0x3)
- nSRST pulls nTRST, falling back to "reset run_and_halt"
- target state: halted
- target halted in ARM state due to debug request, current mode: Supervisor
- cpsr: 0x60000013 pc: 0x00100178 -
-
PASS
RES002SAM7S64ZY1000Reset init on a blank targetErase all the content of the flashConnect via the telnet interface and type
reset init
Reset should return without error and the output should contain
executing reset script 'name_of_the_script'
- - JTAG device found: 0x3f0f0f0f (Manufacturer: 0x787, Part: 0xf0f0, Version: 0x3)
- nSRST pulls nTRST, falling back to "reset run_and_init"
- target state: halted
- target halted in ARM state due to debug request, current mode: Supervisor
- cpsr: 0x600000d3 pc: 0x00003e24
- executing reset script 'event/sam7s256_reset.script' -
-
PASS
RES003SAM7S64ZY1000Reset after a power cycle of the targetReset the target then power cycle the targetConnect via the telnet interface and type
reset halt after the power was detected
Reset should return without error and the output should contain
target state: halted
- - JTAG device found: 0x3f0f0f0f (Manufacturer: 0x787, Part: 0xf0f0, Version: 0x3)
- nSRST pulls nTRST, falling back to "reset run_and_halt"
- target state: halted
- target halted in ARM state due to debug request, current mode: Supervisor
- cpsr: 0x300000d3 pc: 0x00003a38 -
-
PASS
- -

JTAG Speed

- - - - - - - - - - - - - - - - - - - - - - - -
IDTargetZY1000DescriptionInitial stateInputExpected outputActual outputPass/Fail
RES001SAM7S64ZY100016MHz on normal operationReset init the target according to RES002 Exercise a memory access over the JTAG, for example
mdw 0x0 32
The command should run without any errors. If any JTAG checking errors happen, the test failed - - > jtag_khz 16000
- > mdw 0 32
- 0x00000000: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- 0x00000020: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- 0x00000040: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- 0x00000060: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff -
-
PASS
- -

Debugging

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
IDTargetInterfaceDescriptionInitial stateInputExpected outputActual outputPass/Fail
DBG001SAM7S64ZY1000Load is workingReset init is working, RAM is accesible, GDB server is startedOn the console of the OS:
- arm-elf-gdb test_ram.elf
- (gdb) target remote ip:port
- (gdb) load -
Load should return without error, typical output looks like:
- - Loading section .text, size 0x14c lma 0x0
- Start address 0x40, load size 332
- Transfer rate: 180 bytes/sec, 332 bytes/write.
-
-
- (gdb) load
- Loading section .text, size 0x194 lma 0x200000
- Start address 0x200040, load size 404
- Transfer rate: 17470 bits/sec, 404 bytes/write. -
PASS
DBG002SAM7S64ZY1000Software breakpointLoad the test_ram.elf application, use instructions from GDB001In the GDB console:
- - (gdb) monitor arm7_9 sw_bkpts enable
- software breakpoints enabled
- (gdb) break main
- Breakpoint 1 at 0xec: file src/main.c, line 71.
- (gdb) continue
- Continuing. -
-
The software breakpoint should be reached, a typical output looks like:
- - target state: halted
- target halted in ARM state due to breakpoint, current mode: Supervisor
- cpsr: 0x000000d3 pc: 0x000000ec
-
- Breakpoint 1, main () at src/main.c:71
- 71 DWORD a = 1; -
-
- - (gdb) break main
- Breakpoint 2 at 0x200134: file src/main.c, line 69.
- (gdb) c
- Continuing.
- target state: halted
- target halted in ARM state due to breakpoint, current mode: Supervisor
- cpsr: 0x60000013 pc: 0x00200134
-
- Breakpoint 2, main () at src/main.c:69
- 69 DWORD a = 1; -
-
PASS
DBG003SAM7S64ZY1000Single step in a RAM applicationLoad the test_ram.elf application, use instructions from GDB001, break in main using the instructions from GDB002In GDB, type
(gdb) step
The next instruction should be reached, typical output:
- - (gdb) step
- target state: halted
- target halted in ARM state due to single step, current mode: Abort
- cpsr: 0x20000097 pc: 0x000000f0
- target state: halted
- target halted in ARM state due to single step, current mode: Abort
- cpsr: 0x20000097 pc: 0x000000f4
- 72 DWORD b = 2; -
-
- - (gdb) step
- target state: halted
- target halted in ARM state due to single step, current mode: Abort
- cpsr: 0x20000097 pc: 0x000000f0
- target state: halted
- target halted in ARM state due to single step, current mode: Abort
- cpsr: 0x20000097 pc: 0x000000f4
- 72 DWORD b = 2; -
-
PASS
DBG004SAM7S64ZY1000Software break points are working after a resetLoad the test_ram.elf application, use instructions from GDB001, break in main using the instructions from GDB002In GDB, type
- (gdb) monitor reset
- (gdb) load
- (gdb) continue
-
The breakpoint should be reached, typical output:
- - target state: halted
- target halted in ARM state due to breakpoint, current mode: Supervisor
- cpsr: 0x000000d3 pc: 0x000000ec
-
- Breakpoint 1, main () at src/main.c:71
- 71 DWORD a = 1; -
-
- (gdb) moni reset
- JTAG device found: 0x3f0f0f0f (Manufacturer: 0x787, Part: 0xf0f0, Version: 0x3)
- target state: halted
- target halted in ARM state due to debug request, current mode: Supervisor
- cpsr: 0x600000d3 pc: 0x00003e28
- executing reset script 'event/sam7s256_reset.script'
- (gdb) load
- Loading section .text, size 0x194 lma 0x200000
- Start address 0x200040, load size 404
- Transfer rate: 20455 bits/sec, 404 bytes/write.
- (gdb) continue
- Continuing.
- target state: halted
- target halted in ARM state due to breakpoint, current mode: Supervisor
- cpsr: 0x60000013 pc: 0x00200134
-
- Breakpoint 2, main () at src/main.c:69
- 69 DWORD a = 1; -
PASS
DBG005SAM7S64ZY1000Hardware breakpointFlash the test_rom.elf application. Make this test after FLA004 has passedBe sure that gdb_memory_map and gdb_flash_program are enabled. In GDB, type
- - (gdb) monitor reset
- (gdb) load
- Loading section .text, size 0x194 lma 0x100000
- Start address 0x100040, load size 404
- Transfer rate: 179 bytes/sec, 404 bytes/write.
- (gdb) monitor arm7_9 force_hw_bkpts enable
- force hardware breakpoints enabled
- (gdb) break main
- Breakpoint 1 at 0x100134: file src/main.c, line 69.
- (gdb) continue
-
-
The breakpoint should be reached, typical output:
- - Continuing.
-
- Breakpoint 1, main () at src/main.c:69
- 69 DWORD a = 1;
-
-
- - (gdb) break main
- Breakpoint 1 at 0x100134: file src/main.c, line 69.
- (gdb) c
- Continuing.
- target state: halted
- target halted in ARM state due to breakpoint, current mode: Supervisor
- cpsr: 0x60000013 pc: 0x00100134
-
- Breakpoint 1, main () at src/main.c:69
- 69 DWORD a = 1; -
-
PASS
DBG006SAM7S64ZY1000Hardware breakpoint is set after a resetFollow the instructions to flash and insert a hardware breakpoint from DBG005In GDB, type
- - (gdb) monitor reset
- (gdb) monitor reg pc 0x100000
- pc (/32): 0x00100000
- (gdb) continue -

- where the value inserted in PC is the start address of the application -
The breakpoint should be reached, typical output:
- - Continuing.
-
- Breakpoint 1, main () at src/main.c:69
- 69 DWORD a = 1;
-
-
- - Continuing.
- target state: halted
- target halted in ARM state due to single step, current mode: Supervisor
- cpsr: 0x60000013 pc: 0x00100040
- target state: halted
- target halted in ARM state due to breakpoint, current mode: Supervisor
- cpsr: 0x60000013 pc: 0x00100134
-
- Breakpoint 1, main () at src/main.c:69
- 69 DWORD a = 1; -

- Aren't there too many "halted" signs? -
PASS
DBG007SAM7S64ZY1000Single step in ROMFlash the test_rom.elf application and set a breakpoint in main, use DBG005. Make this test after FLA004 has passedBe sure that gdb_memory_map and gdb_flash_program are enabled. In GDB, type
- - (gdb) monitor reset
- (gdb) load
- Loading section .text, size 0x194 lma 0x100000
- Start address 0x100040, load size 404
- Transfer rate: 179 bytes/sec, 404 bytes/write.
- (gdb) monitor arm7_9 force_hw_bkpts enable
- force hardware breakpoints enabled
- (gdb) break main
- Breakpoint 1 at 0x100134: file src/main.c, line 69.
- (gdb) continue
- Continuing.
-
- Breakpoint 1, main () at src/main.c:69
- 69 DWORD a = 1;
- (gdb) step -
-
The breakpoint should be reached, typical output:
- - target state: halted
- target halted in ARM state due to single step, current mode: Supervisor
- cpsr: 0x60000013 pc: 0x0010013c
- 70 DWORD b = 2;
-
-
- (gdb) step
- target state: halted
- target halted in ARM state due to single step, current mode: Supervisor
- cpsr: 0x60000013 pc: 0x00100138
- target state: halted
- target halted in ARM state due to single step, current mode: Supervisor
- cpsr: 0x60000013 pc: 0x0010013c
- 70 DWORD b = 2; -
PASS
- -

RAM access

-Note: these tests are not designed to test/debug the target, but to test functionalities! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
IDTargetInterfaceDescriptionInitial stateInputExpected outputActual outputPass/Fail
RAM001SAM7S64ZY100032 bit Write/read RAMReset init is workingOn the telnet interface
- > mww ram_address 0xdeadbeef 16
- > mdw ram_address 32 -
-
The commands should execute without error. A clear failure is a memory access exception. The result of running the commands should be a list of 16 locations 32bit long containing 0xdeadbeef.
- - > mww 0x0 0xdeadbeef 16
- > mdw 0x0 32
- 0x00000000: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef
- 0x00000020: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef
- 0x00000040: e1a00000 e59fa51c e59f051c e04aa000 00080017 00009388 00009388 00009388
- 0x00000060: 00009388 0002c2c0 0002c2c0 000094f8 000094f4 00009388 00009388 00009388
-
-
- - > mww 0x00200000 0xdeadbeef 16
- > mdw 0x00200000 32
- 0x00200000: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef
- 0x00200020: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef
- 0x00200040: e59f10b4 e3a00902 e5810004 e59f00ac e59f10ac e5810000 e3e010ff e59f00a4
- 0x00200060: e5810060 e59f10a0 e3e00000 e5810130 e5810124 e321f0db e59fd090 e321f0d7 -
-
PASS
RAM002SAM7S64ZY100016 bit Write/read RAMReset init is workingOn the telnet interface
- > mwh ram_address 0xbeef 16
- > mdh ram_address 32 -
-
The commands should execute without error. A clear failure is a memory access exception. The result of running the commands should be a list of 16 locations 16bit long containing 0xbeef.
- - > mwh 0x0 0xbeef 16
- > mdh 0x0 32
- 0x00000000: beef beef beef beef beef beef beef beef beef beef beef beef beef beef beef beef
- 0x00000020: 00e0 0000 021c 0000 0240 0000 026c 0000 0288 0000 0000 0000 0388 0000 0350 0000
- > -
-
- > mwh 0x00200000 0xbeef 16
- > mdh 0x00200000 32
- 0x00200000: beef beef beef beef beef beef beef beef beef beef beef beef beef beef beef beef
- 0x00200020: 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 -
PASS
RAM003SAM7S64ZY10008 bit Write/read RAMReset init is workingOn the telnet interface
- > mwb ram_address 0xab 16
- > mdb ram_address 32 -
-
The commands should execute without error. A clear failure is a memory access exception. The result of running the commands should be a list of 16 locations 8bit long containing 0xab.
- - > mwb ram_address 0xab 16
- > mdb ram_address 32
- 0x00000000: ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- > -
-
- > mwb 0x00200000 0xab 16
- > mdb 0x00200000 32
- 0x00200000: ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -
PASS
- - - -

Flash access

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
IDTargetInterfaceDescriptionInitial stateInputExpected outputActual outputPass/Fail
FLA001SAM7S64ZY1000Flash probeReset init is workingOn the telnet interface:
- > flash probe 0 -
The command should execute without error. The output should state the name of the flash and the starting address. An example of output:
- flash 'ecosflash' found at 0x01000000 -
- - > flash probe 0
- flash 'at91sam7' found at 0x00100000 -
-
PASS
FLA002SAM7S64ZY1000flash fillwReset init is working, flash is probedOn the telnet interface
- > flash fillw 0x1000000 0xdeadbeef 16 - -
The commands should execute without error. The output looks like:
- - wrote 64 bytes to 0x01000000 in 11.610000s (0.091516 kb/s) -
- To verify the contents of the flash:
- - > mdw 0x1000000 32
- 0x01000000: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef
- 0x01000020: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef
- 0x01000040: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- 0x01000060: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff -
-
- > flash fillw 0x100000 0xdeadbeef 16
- wrote 64 bytes to 0x00100000 in 1.110000s (0.957207 kb/s)
- > mdw 0x100000 32
- 0x00100000: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef
- 0x00100020: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef
- 0x00100040: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- 0x00100060: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff -
PASS
FLA003SAM7S64ZY1000Flash eraseReset init is working, flash is probedOn the telnet interface
- > flash erase_address 0x1000000 0x2000 - -
The commands should execute without error.
- - erased address 0x01000000 length 8192 in 4.970000s - - To check that the flash has been erased, read at different addresses. The result should always be 0xff. - - > mdw 0x1000000 32
- 0x01000000: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- 0x01000020: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- 0x01000040: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- 0x01000060: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff -
-
- > flash erase_address 0x100000 0x2000
- erased address 0x00100000 length 8192 in 0.510000s
- > mdw 0x100000 32
- 0x00100000: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- 0x00100020: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- 0x00100040: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- 0x00100060: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- > -
PASS
FLA004SAM7S64ZY1000Loading to flash from GDBReset init is working, flash is probed, connectivity to GDB server is workingStart GDB using a ROM elf image, eg: arm-elf-gdb test_rom.elf.
- - (gdb) target remote ip:port
- (gdb) monitor reset
- (gdb) load
- Loading section .text, size 0x194 lma 0x100000
- Start address 0x100040, load size 404
- Transfer rate: 179 bytes/sec, 404 bytes/write. - (gdb) monitor verify_image path_to_elf_file -
-
The output should look like:
- - verified 404 bytes in 5.060000s -
- The failure message is something like:
- Verify operation failed address 0x00200000. Was 0x00 instead of 0x18 -
- - (gdb) load
- Loading section .text, size 0x194 lma 0x100000
- Start address 0x100040, load size 404
- Transfer rate: 1540 bits/sec, 404 bytes/write.
- (gdb) monitor verify_image /tftp/10.0.0.9/c:\workspace/ecosboard/ecosboard/phi/openocd/rep/testing/examples/SAM7S256Test/test_rom.elf
- verified 404 bytes in 4.860000s -
-
PASS
- - - \ No newline at end of file diff --git a/testing/examples/SAM7S256Test/src/crt.s b/testing/examples/SAM7S256Test/src/crt.s deleted file mode 100644 index 16e5865ea..000000000 --- a/testing/examples/SAM7S256Test/src/crt.s +++ /dev/null @@ -1,225 +0,0 @@ -/**************************************************************************** -* Copyright (c) 2006 by Michael Fischer. All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* 1. Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the author nor the names of its contributors may -* be used to endorse or promote products derived from this software -* without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -* THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS -* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED -* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF -* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -* SUCH DAMAGE. -* -**************************************************************************** -* -* History: -* -* 18.12.06 mifi First Version -* The hardware initialization is based on the startup file -* crtat91sam7x256_rom.S from NutOS 4.2.1. -* Therefore partial copyright by egnite Software GmbH. -****************************************************************************/ - -/* - * Some defines for the program status registers - */ - ARM_MODE_USER = 0x10 /* Normal User Mode */ - ARM_MODE_FIQ = 0x11 /* FIQ Fast Interrupts Mode */ - ARM_MODE_IRQ = 0x12 /* IRQ Standard Interrupts Mode */ - ARM_MODE_SVC = 0x13 /* Supervisor Interrupts Mode */ - ARM_MODE_ABORT = 0x17 /* Abort Processing memory Faults Mode */ - ARM_MODE_UNDEF = 0x1B /* Undefined Instructions Mode */ - ARM_MODE_SYS = 0x1F /* System Running in Priviledged Operating Mode */ - ARM_MODE_MASK = 0x1F - - I_BIT = 0x80 /* disable IRQ when I bit is set */ - F_BIT = 0x40 /* disable IRQ when I bit is set */ - -/* - * Register Base Address - */ - AIC_BASE = 0xFFFFF000 - AIC_EOICR_OFF = 0x130 - AIC_IDCR_OFF = 0x124 - - RSTC_MR = 0xFFFFFD08 - RSTC_KEY = 0xA5000000 - RSTC_URSTEN = 0x00000001 - - WDT_BASE = 0xFFFFFD40 - WDT_MR_OFF = 0x00000004 - WDT_WDDIS = 0x00008000 - - MC_BASE = 0xFFFFFF00 - MC_FMR_OFF = 0x00000060 - MC_FWS_1FWS = 0x00480100 - - .section .vectors,"ax" - .code 32 - -/****************************************************************************/ -/* Vector table and reset entry */ -/****************************************************************************/ -_vectors: - ldr pc, ResetAddr /* Reset */ - ldr pc, UndefAddr /* Undefined instruction */ - ldr pc, SWIAddr /* Software interrupt */ - ldr pc, PAbortAddr /* Prefetch abort */ - ldr pc, DAbortAddr /* Data abort */ - ldr pc, ReservedAddr /* Reserved */ - ldr pc, IRQAddr /* IRQ interrupt */ - ldr pc, FIQAddr /* FIQ interrupt */ - - -ResetAddr: .word ResetHandler -UndefAddr: .word UndefHandler -SWIAddr: .word SWIHandler -PAbortAddr: .word PAbortHandler -DAbortAddr: .word DAbortHandler -ReservedAddr: .word 0 -IRQAddr: .word IRQHandler -FIQAddr: .word FIQHandler - - .ltorg - - .section .init, "ax" - .code 32 - - .global ResetHandler - .global ExitFunction - .extern main -/****************************************************************************/ -/* Reset handler */ -/****************************************************************************/ -ResetHandler: - /* - * The watchdog is enabled after processor reset. Disable it. - */ - ldr r1, =WDT_BASE - ldr r0, =WDT_WDDIS - str r0, [r1, #WDT_MR_OFF] - - - /* - * Enable user reset: assertion length programmed to 1ms - */ - ldr r0, =(RSTC_KEY | RSTC_URSTEN | (4 << 8)) - ldr r1, =RSTC_MR - str r0, [r1, #0] - - - /* - * Use 2 cycles for flash access. - */ - ldr r1, =MC_BASE - ldr r0, =MC_FWS_1FWS - str r0, [r1, #MC_FMR_OFF] - - - /* - * Disable all interrupts. Useful for debugging w/o target reset. - */ - ldr r1, =AIC_BASE - mvn r0, #0 - str r0, [r1, #AIC_EOICR_OFF] - str r0, [r1, #AIC_IDCR_OFF] - - - /* - * Setup a stack for each mode - */ - msr CPSR_c, #ARM_MODE_UNDEF | I_BIT | F_BIT /* Undefined Instruction Mode */ - ldr sp, =__stack_und_end - - msr CPSR_c, #ARM_MODE_ABORT | I_BIT | F_BIT /* Abort Mode */ - ldr sp, =__stack_abt_end - - msr CPSR_c, #ARM_MODE_FIQ | I_BIT | F_BIT /* FIQ Mode */ - ldr sp, =__stack_fiq_end - - msr CPSR_c, #ARM_MODE_IRQ | I_BIT | F_BIT /* IRQ Mode */ - ldr sp, =__stack_irq_end - - msr CPSR_c, #ARM_MODE_SVC | I_BIT | F_BIT /* Supervisor Mode */ - ldr sp, =__stack_svc_end - - - /* - * Clear .bss section - */ - ldr r1, =__bss_start - ldr r2, =__bss_end - ldr r3, =0 -bss_clear_loop: - cmp r1, r2 - strne r3, [r1], #+4 - bne bss_clear_loop - - - /* - * Jump to main - */ - mrs r0, cpsr - bic r0, r0, #I_BIT | F_BIT /* Enable FIQ and IRQ interrupt */ - msr cpsr, r0 - - mov r0, #0 /* No arguments */ - mov r1, #0 /* No arguments */ - ldr r2, =main - mov lr, pc - bx r2 /* And jump... */ - -ExitFunction: - nop - nop - nop - b ExitFunction - - -/****************************************************************************/ -/* Default interrupt handler */ -/****************************************************************************/ - -UndefHandler: - b UndefHandler - -SWIHandler: - b SWIHandler - -PAbortHandler: - b PAbortHandler - -DAbortHandler: - b DAbortHandler - -IRQHandler: - b IRQHandler - -FIQHandler: - b FIQHandler - - .weak ExitFunction - .weak UndefHandler, PAbortHandler, DAbortHandler - .weak IRQHandler, FIQHandler - - .ltorg -/*** EOF ***/ - - diff --git a/testing/examples/SAM7S256Test/src/main.c b/testing/examples/SAM7S256Test/src/main.c deleted file mode 100644 index 99f2d2628..000000000 --- a/testing/examples/SAM7S256Test/src/main.c +++ /dev/null @@ -1,91 +0,0 @@ -/**************************************************************************** -* Copyright (c) 2006 by Michael Fischer. All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* 1. Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the author nor the names of its contributors may -* be used to endorse or promote products derived from this software -* without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -* THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS -* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED -* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF -* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -* SUCH DAMAGE. -* -**************************************************************************** -* History: -* -* 30.03.06 mifi First Version for Insight tutorial -* 26.01.08 mifi Added variable "d" to test const variable. -****************************************************************************/ -#define __MAIN_C__ - -/* - * I use the include only, to show - * how to setup a include dir in the makefile - */ -#include "typedefs.h" - -/*=========================================================================*/ -/* DEFINE: All Structures and Common Constants */ -/*=========================================================================*/ - -/*=========================================================================*/ -/* DEFINE: Prototypes */ -/*=========================================================================*/ - -/*=========================================================================*/ -/* DEFINE: Definition of all local Data */ -/*=========================================================================*/ -static const DWORD d = 7; - -/*=========================================================================*/ -/* DEFINE: Definition of all local Procedures */ -/*=========================================================================*/ - -/*=========================================================================*/ -/* DEFINE: All code exported */ -/*=========================================================================*/ -/***************************************************************************/ -/* main */ -/***************************************************************************/ -int main (void) -{ - DWORD a = 1; - DWORD b = 2; - DWORD c = 0; - - a = a + d; - - while (1) - { - a++; - b++; - c = a + b; - } - - /* - * This return here make no sense. - * But to prevent the compiler warning: - * "return type of 'main' is not 'int' - * we use an int as return :-) - */ - return(0); -} - -/*** EOF ***/ diff --git a/testing/examples/SAM7S256Test/test_ram.elf b/testing/examples/SAM7S256Test/test_ram.elf deleted file mode 100644 index 5143e85ddb0c004855d0852567d1584194577cf4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 36888 zcmeH~U2Ggz701t=-F4j9Nt^`n(MDn-nUYA=dL20*3W$2WyG~b*?bd5!6)mjyV{ETt z?>f8V;FO>`O{j{LN-5-_53OuaDypgv2=x((N{9!Z2;UOCIB_f?1d;05WNeh+^G{+IBt!T$>WI{dHUSK(KC z&}__?Sl_hhg}c$j)lWR~yeEkc-2IR~+@$T}cZt?Fsb_sNkGcaJ>vs=%eVp5A4?XYC z|NJ*?@E@M1qV!HDJgMi1w&6Q)e=)QOS`=-sO}CWa67b!3M(-)?hZ3)ES@2PK-d`vD znFRJ~e;4{~^j+KF8je-s+C7e=L9EBvZ)+V%yt2V#A7GC+G5;PSN*=(a=oCv;QZaM9a4S1S%*-LG(X44-#9&B{v%2R|By@Q zG_HMp{b;B9*{mZNox{8qo#gAsEg$cz*071iVzm}8^Df-WOHRd^ZN}#@3>LE(T;!)% zd}QSO_vhxWSy4=TktgJSit4R%gxl%!?q}0p zUasWb#&YdKym9i(sl4kn-D+(v@2nITmlm96K9?LlojY;z)Fe9S+}M=4?OSqvOX4BI)Vzi8NX95A?n8)=8z+XK;UJS#%KVSdmob=e&nE z+*pa!uph6)@U+hP@fBW>*NRn0o$lj75#D(Rcau6uJsndWk_Ixu-Jb#;9SDg5btk|LdFyS~tsJ&cDNSI>6)^7GxPlud((_#AHs8Foj|ELz4j%2MC_jE?+^2lFEy?>7cytQ!H>C{kDUckiQ~ zpo42>5U2NZg+IHZuks=@Xcm3b&m;bn*1Uz20QWn1{WRc-&ZSak?PEA;$Ag1L@#f`4 zw^)LA8@``6k?X9u6fZTK6i-f!#*41osFs#-yeVFBO3QPFg=)<)akVyEH*v94YB-m6 zRHIm%YY%!{%{GdQJ98}5%VyBha;b(MELE;AE;=|0|GhnhQrtP=6u@kvRl;W`$G-Vb zhUh3Hjt521^k?c-q6JO_W`;ZsjhZEszlA#UTsUXyPK9F5-$otdH)iUFkT5a#z4Qvv zd!d90$9C2AUdN;40fCviJhX|q>rK?*+hfPfEnPq+T(^Nbd#B20!SXU%xQ@O>)Elac z2Jx%A>UvT4*-)LCZGG^+&hlGi_?`x>zk49sr?;sNV%#1Ce?mZ*mO&xnH zlz;0rq77`Gzs^ph@qO@fd;%>z-<8*i-Us!m?&$2fE zmUkSw{gK%6_`LInjc+Y4gP{FfTizse`#iL~;x1i>UPbe*V4#Rv9=~VkcOac> zdDr0+I}fAfeFwTXq}QPJyHimA1MTS@-?h9SBG@U%{6B`~cP`WaGX(9Y((>+b$0}dg zTHYVn?RynB!{oYU6w{>q-;+qAX3ziV&%5-UI2rDNEPjeou=Isn}p()?w4EToS@ zKNHf=Kqo@_H1t47r=ib;^m*tnhV&$Kc>QT;ey=wB;r$PWbP4_MhBS|V6w()=jYYw0 z1^TA4HB)?_5!bW!O%czZP_{3F{u?3v63-XR*@OAMjrb$->uq%0;y%0&v-RNb?KU+3 zCSc?KA3^^nq<;cU5u3Yp{V$-+-z$&*E%$SS@p|_W50V{dMJ?!X{X?$h_j4GJ@3IhZ z4#wl3gf_oVct6LW+v63*AJZ0{g=QWz7?0OvdKTIoNS<$OSN#~w2&11X)+!55gYYg@C@(n0 zMq!~|UoyW@Dun7nZZeq~Dde(W$*?pd3WcUyEMF)zFO>^UtwR15OmAkT>JBg0%5Jq@ zBU3tCy{Jo_O3^J6HWZ#(-<}y>DDZ}OS~GUJR?#{+G#MV{->n(u=odqOFm~5){TECe hhVYnzzdnvZIE(F=X*6FW%m%6rfAdBcORnC~zW{ny89@L5 diff --git a/testing/examples/SAM7S256Test/test_ram.hex b/testing/examples/SAM7S256Test/test_ram.hex deleted file mode 100644 index 7194eec30..000000000 --- a/testing/examples/SAM7S256Test/test_ram.hex +++ /dev/null @@ -1,29 +0,0 @@ -:020000040020DA -:1000000018F09FE518F09FE518F09FE518F09FE5C0 -:1000100018F09FE518F09FE518F09FE518F09FE5B0 -:1000200040002000E4002000E8002000EC00200058 -:10003000F000200000000000F4002000F800200084 -:10004000B4109FE50209A0E3040081E5AC009FE540 -:10005000AC109FE5000081E5FF10E0E3A4009FE500 -:10006000600081E5A0109FE50000E0E3300181E53C -:10007000240181E5DBF021E390D09FE5D7F021E377 -:100080008CD09FE5D1F021E388D09FE5D2F021E329 -:1000900084D09FE5D3F021E380D09FE580109FE5D9 -:1000A00080209FE50030A0E3020051E1043081147C -:1000B000FCFFFF1A00000FE1C000C0E300F029E1DF -:1000C0000000A0E30010A0E35C209FE50FE0A0E1AA -:1000D00012FF2FE10000A0E10000A0E10000A0E17C -:1000E000FBFFFFEAFEFFFFEAFEFFFFEAFEFFFFEA7B -:1000F000FEFFFFEAFEFFFFEAFEFFFFEA40FDFFFF13 -:10010000010400A508FDFFFF0001480000F0FFFF0B -:10011000000620000005200000032000000420004D -:10012000000A2000940120009401200030012000EA -:100130000CD04DE20130A0E300308DE50230A0E3A9 -:1001400004308DE50030A0E308308DE538309FE5C0 -:10015000002093E500309DE5023083E000308DE51E -:1001600000309DE5013083E200308DE504309DE5EF -:10017000013083E204308DE500209DE504309DE5EB -:10018000033082E008308DE5F4FFFFEA90012000A3 -:040190000700000064 -:040000050020004097 -:00000001FF diff --git a/testing/examples/SAM7S256Test/test_ram.map b/testing/examples/SAM7S256Test/test_ram.map deleted file mode 100644 index a773a1fa3..000000000 --- a/testing/examples/SAM7S256Test/test_ram.map +++ /dev/null @@ -1,170 +0,0 @@ - -Memory Configuration - -Name Origin Length Attributes -ram 0x00200000 0x00010000 -*default* 0x00000000 0xffffffff - -Linker script and memory map - -LOAD ./src/crt.o -LOAD ./src/main.o -START GROUP -LOAD d:/compiler/yagarto/bin/../lib/gcc/arm-elf/4.2.2\libgcc.a -LOAD d:/compiler/yagarto/bin/../lib/gcc/arm-elf/4.2.2/../../../../arm-elf/lib\libc.a -END GROUP - 0x00000100 FIQ_STACK_SIZE = 0x100 - 0x00000100 IRQ_STACK_SIZE = 0x100 - 0x00000100 ABT_STACK_SIZE = 0x100 - 0x00000100 UND_STACK_SIZE = 0x100 - 0x00000400 SVC_STACK_SIZE = 0x400 - -.text 0x00200000 0x194 - *(.vectors) - .vectors 0x00200000 0x40 ./src/crt.o - 0x00200040 . = ALIGN (0x4) - *(.init) - .init 0x00200040 0xf0 ./src/crt.o - 0x002000f8 FIQHandler - 0x002000ec PAbortHandler - 0x002000d4 ExitFunction - 0x00200040 ResetHandler - 0x002000f0 DAbortHandler - 0x002000f4 IRQHandler - 0x002000e4 UndefHandler - 0x00200130 . = ALIGN (0x4) - *(.text) - .text 0x00200130 0x0 ./src/crt.o - .text 0x00200130 0x60 ./src/main.o - 0x00200130 main - 0x00200190 . = ALIGN (0x4) - *(.rodata) - .rodata 0x00200190 0x4 ./src/main.o - 0x00200194 . = ALIGN (0x4) - *(.rodata*) - 0x00200194 . = ALIGN (0x4) - *(.glue_7t) - .glue_7t 0x00200194 0x0 ./src/crt.o - .glue_7t 0x00200194 0x0 ./src/main.o - 0x00200194 . = ALIGN (0x4) - *(.glue_7) - .glue_7 0x00200194 0x0 ./src/crt.o - .glue_7 0x00200194 0x0 ./src/main.o - 0x00200194 . = ALIGN (0x4) - 0x00200194 etext = . - -.vfp11_veneer 0x00000000 0x0 - .vfp11_veneer 0x00000000 0x0 ./src/crt.o - .vfp11_veneer 0x00000000 0x0 ./src/main.o - -.data 0x00200194 0x0 - 0x00200194 PROVIDE (__data_start, .) - *(.data) - .data 0x00200194 0x0 ./src/crt.o - .data 0x00200194 0x0 ./src/main.o - 0x00200194 . = ALIGN (0x4) - 0x00200194 edata = . - 0x00200194 _edata = . - 0x00200194 PROVIDE (__data_end, .) - -.bss 0x00200194 0x86c - 0x00200194 PROVIDE (__bss_start, .) - *(.bss) - .bss 0x00200194 0x0 ./src/crt.o - .bss 0x00200194 0x0 ./src/main.o - *(COMMON) - 0x00200194 . = ALIGN (0x4) - 0x00200194 PROVIDE (__bss_end, .) - 0x00200200 . = ALIGN (0x100) - *fill* 0x00200194 0x6c 00 - 0x00200200 PROVIDE (__stack_start, .) - 0x00200200 PROVIDE (__stack_fiq_start, .) - 0x00200300 . = (. + FIQ_STACK_SIZE) - *fill* 0x00200200 0x100 00 - 0x00200300 . = ALIGN (0x4) - 0x00200300 PROVIDE (__stack_fiq_end, .) - 0x00200300 PROVIDE (__stack_irq_start, .) - 0x00200400 . = (. + IRQ_STACK_SIZE) - *fill* 0x00200300 0x100 00 - 0x00200400 . = ALIGN (0x4) - 0x00200400 PROVIDE (__stack_irq_end, .) - 0x00200400 PROVIDE (__stack_abt_start, .) - 0x00200500 . = (. + ABT_STACK_SIZE) - *fill* 0x00200400 0x100 00 - 0x00200500 . = ALIGN (0x4) - 0x00200500 PROVIDE (__stack_abt_end, .) - 0x00200500 PROVIDE (__stack_und_start, .) - 0x00200600 . = (. + UND_STACK_SIZE) - *fill* 0x00200500 0x100 00 - 0x00200600 . = ALIGN (0x4) - 0x00200600 PROVIDE (__stack_und_end, .) - 0x00200600 PROVIDE (__stack_svc_start, .) - 0x00200a00 . = (. + SVC_STACK_SIZE) - *fill* 0x00200600 0x400 00 - 0x00200a00 . = ALIGN (0x4) - 0x00200a00 PROVIDE (__stack_svc_end, .) - 0x00200a00 PROVIDE (__stack_end, .) - 0x00200a00 PROVIDE (__heap_start, .) -OUTPUT(test_ram.elf elf32-littlearm) - -.ARM.attributes - 0x00000000 0x10 - .ARM.attributes - 0x00000000 0x10 ./src/crt.o - .ARM.attributes - 0x00000010 0x10 ./src/main.o - -.debug_line 0x00000000 0xd6 - .debug_line 0x00000000 0x7f ./src/crt.o - .debug_line 0x0000007f 0x57 ./src/main.o - -.debug_info 0x00000000 0x1aa - .debug_info 0x00000000 0x75 ./src/crt.o - .debug_info 0x00000075 0x135 ./src/main.o - -.debug_abbrev 0x00000000 0x6d - .debug_abbrev 0x00000000 0x12 ./src/crt.o - .debug_abbrev 0x00000012 0x5b ./src/main.o - -.debug_aranges 0x00000000 0x48 - .debug_aranges - 0x00000000 0x28 ./src/crt.o - .debug_aranges - 0x00000028 0x20 ./src/main.o - -.debug_ranges 0x00000000 0x20 - .debug_ranges 0x00000000 0x20 ./src/crt.o - -.debug_frame 0x00000000 0x24 - .debug_frame 0x00000000 0x24 ./src/main.o - -.debug_loc 0x00000000 0x1f - .debug_loc 0x00000000 0x1f ./src/main.o - -.debug_pubnames - 0x00000000 0x1b - .debug_pubnames - 0x00000000 0x1b ./src/main.o - -.comment 0x00000000 0x12 - .comment 0x00000000 0x12 ./src/main.o - -Cross Reference Table - -Symbol File -DAbortHandler ./src/crt.o -ExitFunction ./src/crt.o -FIQHandler ./src/crt.o -IRQHandler ./src/crt.o -PAbortHandler ./src/crt.o -ResetHandler ./src/crt.o -UndefHandler ./src/crt.o -__bss_end ./src/crt.o -__bss_start ./src/crt.o -__stack_abt_end ./src/crt.o -__stack_fiq_end ./src/crt.o -__stack_irq_end ./src/crt.o -__stack_svc_end ./src/crt.o -__stack_und_end ./src/crt.o -main ./src/main.o - ./src/crt.o diff --git a/testing/examples/SAM7S256Test/test_rom.elf b/testing/examples/SAM7S256Test/test_rom.elf deleted file mode 100644 index e1ba239cc223fdaec0fcf13ca6c6c0cff6485e5d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 36888 zcmeH~U2Ggz701ua?mAoSB%1{B(MDn-EhUkv^*VAs6cF`#cb%>r+th1g6)kM`V{ETt z?>f8V;FO>`O{j{LN-gA}53OuaDp1u2g!+g?CBy?ygl`F6oVb<{0?CW|07_u^pL_T2 zPOO4>;DLv8k~`=8&pr2Jelwn#eIa{c%(AQ!b!k@V|h6 z8UB~>H{pK;zYf11Lvt`+a&z0JXYYlR*FXBu_a7%Zc<()WZ<}^c+#}lDrr73o0d)tr zHt!ww2RYYm4}AYm|NJ*?qA(|ro(Dc?nyhtiIa(w3glqt6#i#R^J()neF4kaRQy=S%~^MbI3Yu#riOLocjAej}-oVK1QMFx&F`g=Z@gwCak9iwEWCK?g*EU z^jYYL40o&Sj}Y}eNnCC$jzHZ#6z-&AG=hll^5r151-ohz>`z^e>8t_Et)9G{0 zaolMqIyV|6T3467QW@TBYQJbA&t3B0aroW~si=8}z7}Zv9z z^o=56V(xqXMWVL@2@_84sf*vlrQ`t}Gj#=M6LZ(=sKeW%YvzpC>Ye)4 zJ$3XAqIjS#+=*Y>Qx`|wrvi0mt=IO{rBTP%$e5}74iYBjzOSH;AC1OL-ytOQHPbyS zsC(NK!J9hvb|C-8%S2n)JipG)pz(R|-`8Vk!TGMeLi9#ppqUS4A7c71G}K+yQ8l4Q zR_6JGE3h^c^^_rsJTiBvbN8BLNWF=T;_>FHn(=%VJqr<@VF3$Ke?am00kvbjd+uuc z%!S!%Yy12x>+x^;QDjW{9UchBHsTF2Cb$;SFOs$WUyw*Nk~IsX{uYwxLlz&h-x z0X)9nMyP6dzPA53wE2C)`#BDMyK{a#UxMq&;e%TL9JG1Q<1?9_=KjtN$@5L_sh?#X zSg#7rzk}F#y#_S@Rx zJ*m;D>6xCKoy=s%dNTi9z9%M9`Ekk>M{_eYrjDsxx;UE3XNiOCR4zSToEpPus9dHa zrt>rD;>0v5Kc0O~2eXjbNt(;d=m|KO(4#q=%VctSn&`|9Ki28wa4ugQ!hzx?Dqe9b zUZdHfX}9HiscN-JvvvGxP*Hv^r~DUEWqcW{Fw+ZpMDvPURe9i19?X=FR|%t^Db=e> zZjlLrosFNw3uU%H9Znfl<2pbActxnGjFBW-2JgphKTCXad8l4G_(r0Uix$47E p5614Ap8mkZ%@7<@)a&Cm2xhSzGmYYFgxNr?sW)$QsqCo@{R=mp5WfHb diff --git a/testing/examples/SAM7S256Test/test_rom.hex b/testing/examples/SAM7S256Test/test_rom.hex deleted file mode 100644 index 27c4cba21..000000000 --- a/testing/examples/SAM7S256Test/test_rom.hex +++ /dev/null @@ -1,29 +0,0 @@ -:020000040010EA -:1000000018F09FE518F09FE518F09FE518F09FE5C0 -:1000100018F09FE518F09FE518F09FE518F09FE5B0 -:1000200040001000E4001000E8001000EC00100098 -:10003000F000100000000000F4001000F8001000B4 -:10004000B4109FE50209A0E3040081E5AC009FE540 -:10005000AC109FE5000081E5FF10E0E3A4009FE500 -:10006000600081E5A0109FE50000E0E3300181E53C -:10007000240181E5DBF021E390D09FE5D7F021E377 -:100080008CD09FE5D1F021E388D09FE5D2F021E329 -:1000900084D09FE5D3F021E380D09FE580109FE5D9 -:1000A00080209FE50030A0E3020051E1043081147C -:1000B000FCFFFF1A00000FE1C000C0E300F029E1DF -:1000C0000000A0E30010A0E35C209FE50FE0A0E1AA -:1000D00012FF2FE10000A0E10000A0E10000A0E17C -:1000E000FBFFFFEAFEFFFFEAFEFFFFEAFEFFFFEA7B -:1000F000FEFFFFEAFEFFFFEAFEFFFFEA40FDFFFF13 -:10010000010400A508FDFFFF0001480000F0FFFF0B -:100110000004200000032000000120000002200055 -:100120000008200000002000000020003001100026 -:100130000CD04DE20130A0E300308DE50230A0E3A9 -:1001400004308DE50030A0E308308DE538309FE5C0 -:10015000002093E500309DE5023083E000308DE51E -:1001600000309DE5013083E200308DE504309DE5EF -:10017000013083E204308DE500209DE504309DE5EB -:10018000033082E008308DE5F4FFFFEA90011000B3 -:040190000700000064 -:0400000500100040A7 -:00000001FF diff --git a/testing/examples/SAM7S256Test/test_rom.map b/testing/examples/SAM7S256Test/test_rom.map deleted file mode 100644 index c8047f282..000000000 --- a/testing/examples/SAM7S256Test/test_rom.map +++ /dev/null @@ -1,170 +0,0 @@ - -Memory Configuration - -Name Origin Length Attributes -rom 0x00100000 0x00040000 -ram 0x00200000 0x00010000 -*default* 0x00000000 0xffffffff - -Linker script and memory map - -LOAD ./src/crt.o -LOAD ./src/main.o -START GROUP -LOAD d:/compiler/yagarto/bin/../lib/gcc/arm-elf/4.2.2\libgcc.a -LOAD d:/compiler/yagarto/bin/../lib/gcc/arm-elf/4.2.2/../../../../arm-elf/lib\libc.a -END GROUP - 0x00000100 FIQ_STACK_SIZE = 0x100 - 0x00000100 IRQ_STACK_SIZE = 0x100 - 0x00000100 ABT_STACK_SIZE = 0x100 - 0x00000100 UND_STACK_SIZE = 0x100 - 0x00000400 SVC_STACK_SIZE = 0x400 - -.text 0x00100000 0x194 - *(.vectors) - .vectors 0x00100000 0x40 ./src/crt.o - 0x00100040 . = ALIGN (0x4) - *(.init) - .init 0x00100040 0xf0 ./src/crt.o - 0x001000f8 FIQHandler - 0x001000ec PAbortHandler - 0x001000d4 ExitFunction - 0x00100040 ResetHandler - 0x001000f0 DAbortHandler - 0x001000f4 IRQHandler - 0x001000e4 UndefHandler - 0x00100130 . = ALIGN (0x4) - *(.text) - .text 0x00100130 0x0 ./src/crt.o - .text 0x00100130 0x60 ./src/main.o - 0x00100130 main - 0x00100190 . = ALIGN (0x4) - *(.rodata) - .rodata 0x00100190 0x4 ./src/main.o - 0x00100194 . = ALIGN (0x4) - *(.rodata*) - 0x00100194 . = ALIGN (0x4) - *(.glue_7t) - .glue_7t 0x00100194 0x0 ./src/crt.o - .glue_7t 0x00100194 0x0 ./src/main.o - 0x00100194 . = ALIGN (0x4) - *(.glue_7) - .glue_7 0x00100194 0x0 ./src/crt.o - .glue_7 0x00100194 0x0 ./src/main.o - 0x00100194 . = ALIGN (0x4) - 0x00100194 etext = . - -.vfp11_veneer 0x00000000 0x0 - .vfp11_veneer 0x00000000 0x0 ./src/crt.o - .vfp11_veneer 0x00000000 0x0 ./src/main.o - -.data 0x00200000 0x0 - 0x00200000 PROVIDE (__data_start, .) - *(.data) - .data 0x00200000 0x0 ./src/crt.o - .data 0x00200000 0x0 ./src/main.o - 0x00200000 . = ALIGN (0x4) - 0x00200000 edata = . - 0x00200000 _edata = . - 0x00200000 PROVIDE (__data_end, .) - -.bss 0x00200000 0x800 - 0x00200000 PROVIDE (__bss_start, .) - *(.bss) - .bss 0x00200000 0x0 ./src/crt.o - .bss 0x00200000 0x0 ./src/main.o - *(COMMON) - 0x00200000 . = ALIGN (0x4) - 0x00200000 PROVIDE (__bss_end, .) - 0x00200000 . = ALIGN (0x100) - 0x00200000 PROVIDE (__stack_start, .) - 0x00200000 PROVIDE (__stack_fiq_start, .) - 0x00200100 . = (. + FIQ_STACK_SIZE) - *fill* 0x00200000 0x100 00 - 0x00200100 . = ALIGN (0x4) - 0x00200100 PROVIDE (__stack_fiq_end, .) - 0x00200100 PROVIDE (__stack_irq_start, .) - 0x00200200 . = (. + IRQ_STACK_SIZE) - *fill* 0x00200100 0x100 00 - 0x00200200 . = ALIGN (0x4) - 0x00200200 PROVIDE (__stack_irq_end, .) - 0x00200200 PROVIDE (__stack_abt_start, .) - 0x00200300 . = (. + ABT_STACK_SIZE) - *fill* 0x00200200 0x100 00 - 0x00200300 . = ALIGN (0x4) - 0x00200300 PROVIDE (__stack_abt_end, .) - 0x00200300 PROVIDE (__stack_und_start, .) - 0x00200400 . = (. + UND_STACK_SIZE) - *fill* 0x00200300 0x100 00 - 0x00200400 . = ALIGN (0x4) - 0x00200400 PROVIDE (__stack_und_end, .) - 0x00200400 PROVIDE (__stack_svc_start, .) - 0x00200800 . = (. + SVC_STACK_SIZE) - *fill* 0x00200400 0x400 00 - 0x00200800 . = ALIGN (0x4) - 0x00200800 PROVIDE (__stack_svc_end, .) - 0x00200800 PROVIDE (__stack_end, .) - 0x00200800 PROVIDE (__heap_start, .) -OUTPUT(test_rom.elf elf32-littlearm) - -.ARM.attributes - 0x00000000 0x10 - .ARM.attributes - 0x00000000 0x10 ./src/crt.o - .ARM.attributes - 0x00000010 0x10 ./src/main.o - -.debug_line 0x00000000 0xd6 - .debug_line 0x00000000 0x7f ./src/crt.o - .debug_line 0x0000007f 0x57 ./src/main.o - -.debug_info 0x00000000 0x1aa - .debug_info 0x00000000 0x75 ./src/crt.o - .debug_info 0x00000075 0x135 ./src/main.o - -.debug_abbrev 0x00000000 0x6d - .debug_abbrev 0x00000000 0x12 ./src/crt.o - .debug_abbrev 0x00000012 0x5b ./src/main.o - -.debug_aranges 0x00000000 0x48 - .debug_aranges - 0x00000000 0x28 ./src/crt.o - .debug_aranges - 0x00000028 0x20 ./src/main.o - -.debug_ranges 0x00000000 0x20 - .debug_ranges 0x00000000 0x20 ./src/crt.o - -.debug_frame 0x00000000 0x24 - .debug_frame 0x00000000 0x24 ./src/main.o - -.debug_loc 0x00000000 0x1f - .debug_loc 0x00000000 0x1f ./src/main.o - -.debug_pubnames - 0x00000000 0x1b - .debug_pubnames - 0x00000000 0x1b ./src/main.o - -.comment 0x00000000 0x12 - .comment 0x00000000 0x12 ./src/main.o - -Cross Reference Table - -Symbol File -DAbortHandler ./src/crt.o -ExitFunction ./src/crt.o -FIQHandler ./src/crt.o -IRQHandler ./src/crt.o -PAbortHandler ./src/crt.o -ResetHandler ./src/crt.o -UndefHandler ./src/crt.o -__bss_end ./src/crt.o -__bss_start ./src/crt.o -__stack_abt_end ./src/crt.o -__stack_fiq_end ./src/crt.o -__stack_irq_end ./src/crt.o -__stack_svc_end ./src/crt.o -__stack_und_end ./src/crt.o -main ./src/main.o - ./src/crt.o diff --git a/testing/examples/SAM7X256Test/inc/typedefs.h b/testing/examples/SAM7X256Test/inc/typedefs.h deleted file mode 100644 index 42136426a..000000000 --- a/testing/examples/SAM7X256Test/inc/typedefs.h +++ /dev/null @@ -1,50 +0,0 @@ -/**************************************************************************** -* Copyright (c) 2006 by Michael Fischer. All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* 1. Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the author nor the names of its contributors may -* be used to endorse or promote products derived from this software -* without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -* THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS -* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED -* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF -* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -* SUCH DAMAGE. -* -**************************************************************************** -* History: -* -* 30.03.06 mifi First Version for Insight tutorial -****************************************************************************/ -#ifndef __TYPEDEFS_H__ -#define __TYPEDEFS_H__ - -/* - * Some types to use Windows like source - */ -typedef char CHAR; /* 8-bit signed data */ -typedef unsigned char BYTE; /* 8-bit unsigned data */ -typedef unsigned short WORD; /* 16-bit unsigned data */ -typedef long LONG; /* 32-bit signed data */ -typedef unsigned long ULONG; /* 32-bit unsigned data */ -typedef unsigned long DWORD; /* 32-bit unsigned data */ - - -#endif /* !__TYPEDEFS_H_ */ -/*** EOF ***/ diff --git a/testing/examples/SAM7X256Test/makefile b/testing/examples/SAM7X256Test/makefile deleted file mode 100644 index 4ad44cf0b..000000000 --- a/testing/examples/SAM7X256Test/makefile +++ /dev/null @@ -1,146 +0,0 @@ -# -# !!!! Do NOT edit this makefile with an editor which replace tabs by spaces !!!! -# -############################################################################################## -# -# On command line: -# -# make all = Create project -# -# make clean = Clean project files. -# -# To rebuild project do "make clean" and "make all". -# - -############################################################################################## -# Start of default section -# - -TRGT = arm-elf- -CC = $(TRGT)gcc -CP = $(TRGT)objcopy -AS = $(TRGT)gcc -x assembler-with-cpp -BIN = $(CP) -O ihex - -MCU = arm7tdmi - -# List all default C defines here, like -D_DEBUG=1 -DDEFS = - -# List all default ASM defines here, like -D_DEBUG=1 -DADEFS = - -# List all default directories to look for include files here -DINCDIR = - -# List the default directory to look for the libraries here -DLIBDIR = - -# List all default libraries here -DLIBS = - -# -# End of default section -############################################################################################## - -############################################################################################## -# Start of user section -# - -# Define project name here -PROJECT = test - -# Define linker script file here -LDSCRIPT_RAM = ./prj/sam7x256_ram.ld -LDSCRIPT_ROM = ./prj/sam7x256_rom.ld - -# List all user C define here, like -D_DEBUG=1 -UDEFS = - -# Define ASM defines here -UADEFS = - -# List C source files here -SRC = ./src/main.c - -# List ASM source files here -ASRC = ./src/crt.s - -# List all user directories here -UINCDIR = ./inc - -# List the user directory to look for the libraries here -ULIBDIR = - -# List all user libraries here -ULIBS = - -# Define optimisation level here -OPT = -O0 - -# -# End of user defines -############################################################################################## - - -INCDIR = $(patsubst %,-I%,$(DINCDIR) $(UINCDIR)) -LIBDIR = $(patsubst %,-L%,$(DLIBDIR) $(ULIBDIR)) -DEFS = $(DDEFS) $(UDEFS) -ADEFS = $(DADEFS) $(UADEFS) -OBJS = $(ASRC:.s=.o) $(SRC:.c=.o) -LIBS = $(DLIBS) $(ULIBS) -MCFLAGS = -mcpu=$(MCU) - -ASFLAGS = $(MCFLAGS) -g -gdwarf-2 -Wa,-amhls=$(<:.s=.lst) $(ADEFS) -CPFLAGS = $(MCFLAGS) $(OPT) -gdwarf-2 -mthumb-interwork -fomit-frame-pointer -Wall -Wstrict-prototypes -fverbose-asm -Wa,-ahlms=$(<:.c=.lst) $(DEFS) -LDFLAGS_RAM = $(MCFLAGS) -nostartfiles -T$(LDSCRIPT_RAM) -Wl,-Map=$(PROJECT)_ram.map,--cref,--no-warn-mismatch $(LIBDIR) -LDFLAGS_ROM = $(MCFLAGS) -nostartfiles -T$(LDSCRIPT_ROM) -Wl,-Map=$(PROJECT)_rom.map,--cref,--no-warn-mismatch $(LIBDIR) - -# Generate dependency information -CPFLAGS += -MD -MP -MF .dep/$(@F).d - -# -# makefile rules -# - -all: RAM ROM - -RAM: $(OBJS) $(PROJECT)_ram.elf $(PROJECT)_ram.hex - -ROM: $(OBJS) $(PROJECT)_rom.elf $(PROJECT)_rom.hex - -%o : %c - $(CC) -c $(CPFLAGS) -I . $(INCDIR) $< -o $@ - -%o : %s - $(AS) -c $(ASFLAGS) $< -o $@ - -%ram.elf: $(OBJS) - $(CC) $(OBJS) $(LDFLAGS_RAM) $(LIBS) -o $@ - -%rom.elf: $(OBJS) - $(CC) $(OBJS) $(LDFLAGS_ROM) $(LIBS) -o $@ - -%hex: %elf - $(BIN) $< $@ - -clean: - -rm -f $(OBJS) - -rm -f $(PROJECT)_ram.elf - -rm -f $(PROJECT)_ram.map - -rm -f $(PROJECT)_ram.hex - -rm -f $(PROJECT)_rom.elf - -rm -f $(PROJECT)_rom.map - -rm -f $(PROJECT)_rom.hex - -rm -f $(SRC:.c=.c.bak) - -rm -f $(SRC:.c=.lst) - -rm -f $(ASRC:.s=.s.bak) - -rm -f $(ASRC:.s=.lst) - -rm -fR .dep - -# -# Include the dependency files, should be the last of the makefile -# --include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*) - -# *** EOF *** \ No newline at end of file diff --git a/testing/examples/SAM7X256Test/prj/eclipse_ram.gdb b/testing/examples/SAM7X256Test/prj/eclipse_ram.gdb deleted file mode 100644 index 9d9f24d16..000000000 --- a/testing/examples/SAM7X256Test/prj/eclipse_ram.gdb +++ /dev/null @@ -1,32 +0,0 @@ -target remote localhost:3333 -monitor reset -monitor sleep 500 -monitor poll -monitor soft_reset_halt -monitor arm7_9 sw_bkpts enable - -# WDT_MR, disable watchdog -monitor mww 0xFFFFFD44 0x00008000 - -# RSTC_MR, enable user reset -monitor mww 0xfffffd08 0xa5000001 - -# CKGR_MOR -monitor mww 0xFFFFFC20 0x00000601 -monitor sleep 10 - -# CKGR_PLLR -monitor mww 0xFFFFFC2C 0x00481c0e -monitor sleep 10 - -# PMC_MCKR -monitor mww 0xFFFFFC30 0x00000007 -monitor sleep 10 - -# PMC_IER -monitor mww 0xFFFFFF60 0x00480100 -monitor sleep 100 - -load -break main -continue diff --git a/testing/examples/SAM7X256Test/prj/eclipse_rom.gdb b/testing/examples/SAM7X256Test/prj/eclipse_rom.gdb deleted file mode 100644 index db2a4643d..000000000 --- a/testing/examples/SAM7X256Test/prj/eclipse_rom.gdb +++ /dev/null @@ -1,32 +0,0 @@ -target remote localhost:3333 -monitor reset -monitor sleep 500 -monitor poll -monitor soft_reset_halt -monitor arm7_9 force_hw_bkpts enable - -# WDT_MR, disable watchdog -monitor mww 0xFFFFFD44 0x00008000 - -# RSTC_MR, enable user reset -monitor mww 0xfffffd08 0xa5000001 - -# CKGR_MOR -monitor mww 0xFFFFFC20 0x00000601 -monitor sleep 10 - -# CKGR_PLLR -monitor mww 0xFFFFFC2C 0x00481c0e -monitor sleep 10 - -# PMC_MCKR -monitor mww 0xFFFFFC30 0x00000007 -monitor sleep 10 - -# PMC_IER -monitor mww 0xFFFFFF60 0x00480100 -monitor sleep 100 - -load -break main -continue diff --git a/testing/examples/SAM7X256Test/prj/sam7x256_jtagkey.cfg b/testing/examples/SAM7X256Test/prj/sam7x256_jtagkey.cfg deleted file mode 100644 index a2894df7f..000000000 --- a/testing/examples/SAM7X256Test/prj/sam7x256_jtagkey.cfg +++ /dev/null @@ -1,39 +0,0 @@ -#daemon configuration -telnet_port 4444 -gdb_port 3333 - -# tell gdb our flash memory map -# and enable flash programming -gdb_memory_map enable -gdb_flash_program enable - -#interface -interface ft2232 -ft2232_device_desc "Amontec JTAGkey A" -ft2232_layout jtagkey -ft2232_vid_pid 0x0403 0xcff8 -jtag_speed 0 -jtag_nsrst_delay 200 -jtag_ntrst_delay 200 - - -#use combined on interfaces or targets that can't set TRST/SRST separately -reset_config srst_only srst_pulls_trst - -#jtag scan chain -jtag newtap sam7 cpu -irlen 4 -irmask 0xf - -#target configuration -target create target0 arm7tdmi -endian little -chain-position 0 -[new_target_name] configure -work-area-virt 0 -work-area-phys 0x00200000 -work-area-size 0x4000 -work-area-backup false - -target_script 0 reset .\prj\sam7x256_reset.script - -#flash bank -flash bank at91sam7 0 0 0 0 0 - -# For more information about the configuration files, -# look at the OpenOCD User's Guide. - -init -reset halt diff --git a/testing/examples/SAM7X256Test/prj/sam7x256_ram.ld b/testing/examples/SAM7X256Test/prj/sam7x256_ram.ld deleted file mode 100644 index 1b857c99f..000000000 --- a/testing/examples/SAM7X256Test/prj/sam7x256_ram.ld +++ /dev/null @@ -1,132 +0,0 @@ -/**************************************************************************** -* Copyright (c) 2006 by Michael Fischer. All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* 1. Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the author nor the names of its contributors may -* be used to endorse or promote products derived from this software -* without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -* THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS -* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED -* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF -* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -* SUCH DAMAGE. -* -**************************************************************************** -* -* History: -* -* 30.03.06 mifi First Version -****************************************************************************/ - - -ENTRY(ResetHandler) -SEARCH_DIR(.) - -/* - * Define stack size here - */ -FIQ_STACK_SIZE = 0x0100; -IRQ_STACK_SIZE = 0x0100; -ABT_STACK_SIZE = 0x0100; -UND_STACK_SIZE = 0x0100; -SVC_STACK_SIZE = 0x0400; - - -MEMORY -{ - ram : org = 0x00200000, len = 64k -} - -/* - * Do not change the next code - */ -SECTIONS -{ - .text : - { - *(.vectors); - . = ALIGN(4); - *(.init); - . = ALIGN(4); - *(.text); - . = ALIGN(4); - *(.rodata); - . = ALIGN(4); - *(.rodata*); - . = ALIGN(4); - *(.glue_7t); - . = ALIGN(4); - *(.glue_7); - . = ALIGN(4); - etext = .; - } > ram - - .data : - { - PROVIDE (__data_start = .); - *(.data) - . = ALIGN(4); - edata = .; - _edata = .; - PROVIDE (__data_end = .); - } > ram - - .bss : - { - PROVIDE (__bss_start = .); - *(.bss) - *(COMMON) - . = ALIGN(4); - PROVIDE (__bss_end = .); - - . = ALIGN(256); - - PROVIDE (__stack_start = .); - - PROVIDE (__stack_fiq_start = .); - . += FIQ_STACK_SIZE; - . = ALIGN(4); - PROVIDE (__stack_fiq_end = .); - - PROVIDE (__stack_irq_start = .); - . += IRQ_STACK_SIZE; - . = ALIGN(4); - PROVIDE (__stack_irq_end = .); - - PROVIDE (__stack_abt_start = .); - . += ABT_STACK_SIZE; - . = ALIGN(4); - PROVIDE (__stack_abt_end = .); - - PROVIDE (__stack_und_start = .); - . += UND_STACK_SIZE; - . = ALIGN(4); - PROVIDE (__stack_und_end = .); - - PROVIDE (__stack_svc_start = .); - . += SVC_STACK_SIZE; - . = ALIGN(4); - PROVIDE (__stack_svc_end = .); - PROVIDE (__stack_end = .); - PROVIDE (__heap_start = .); - } > ram - -} -/*** EOF ***/ - diff --git a/testing/examples/SAM7X256Test/prj/sam7x256_reset.script b/testing/examples/SAM7X256Test/prj/sam7x256_reset.script deleted file mode 100644 index 456341d60..000000000 --- a/testing/examples/SAM7X256Test/prj/sam7x256_reset.script +++ /dev/null @@ -1,17 +0,0 @@ -# -# Init - taken form the script openocd_at91sam7_ecr.script -# -# I take this script from the following page: -# -# http://www.siwawi.arubi.uni-kl.de/avr_projects/arm_projects/openocd_intro/index.html -# -mww 0xfffffd44 0x00008000 # disable watchdog -mww 0xfffffd08 0xa5000001 # enable user reset -mww 0xfffffc20 0x00000601 # CKGR_MOR : enable the main oscillator -sleep 10 -mww 0xfffffc2c 0x00481c0e # CKGR_PLLR: 96.1097 MHz -sleep 10 -mww 0xfffffc30 0x00000007 # PMC_MCKR : MCK = PLL / 2 ~= 48 MHz -sleep 10 -mww 0xffffff60 0x003c0100 # MC_FMR: flash mode (FWS=1,FMCN=60) -sleep 100 diff --git a/testing/examples/SAM7X256Test/prj/sam7x256_rom.ld b/testing/examples/SAM7X256Test/prj/sam7x256_rom.ld deleted file mode 100644 index b64854acd..000000000 --- a/testing/examples/SAM7X256Test/prj/sam7x256_rom.ld +++ /dev/null @@ -1,133 +0,0 @@ -/**************************************************************************** -* Copyright (c) 2006 by Michael Fischer. All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* 1. Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the author nor the names of its contributors may -* be used to endorse or promote products derived from this software -* without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -* THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS -* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED -* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF -* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -* SUCH DAMAGE. -* -**************************************************************************** -* -* History: -* -* 26.01.08 mifi First Version -****************************************************************************/ - - -ENTRY(ResetHandler) -SEARCH_DIR(.) - -/* - * Define stack size here - */ -FIQ_STACK_SIZE = 0x0100; -IRQ_STACK_SIZE = 0x0100; -ABT_STACK_SIZE = 0x0100; -UND_STACK_SIZE = 0x0100; -SVC_STACK_SIZE = 0x0400; - - -MEMORY -{ - rom : org = 0x00100000, len = 256k - ram : org = 0x00200000, len = 64k -} - -/* - * Do not change the next code - */ -SECTIONS -{ - .text : - { - *(.vectors); - . = ALIGN(4); - *(.init); - . = ALIGN(4); - *(.text); - . = ALIGN(4); - *(.rodata); - . = ALIGN(4); - *(.rodata*); - . = ALIGN(4); - *(.glue_7t); - . = ALIGN(4); - *(.glue_7); - . = ALIGN(4); - etext = .; - } > rom - - .data : - { - PROVIDE (__data_start = .); - *(.data) - . = ALIGN(4); - edata = .; - _edata = .; - PROVIDE (__data_end = .); - } > ram - - .bss : - { - PROVIDE (__bss_start = .); - *(.bss) - *(COMMON) - . = ALIGN(4); - PROVIDE (__bss_end = .); - - . = ALIGN(256); - - PROVIDE (__stack_start = .); - - PROVIDE (__stack_fiq_start = .); - . += FIQ_STACK_SIZE; - . = ALIGN(4); - PROVIDE (__stack_fiq_end = .); - - PROVIDE (__stack_irq_start = .); - . += IRQ_STACK_SIZE; - . = ALIGN(4); - PROVIDE (__stack_irq_end = .); - - PROVIDE (__stack_abt_start = .); - . += ABT_STACK_SIZE; - . = ALIGN(4); - PROVIDE (__stack_abt_end = .); - - PROVIDE (__stack_und_start = .); - . += UND_STACK_SIZE; - . = ALIGN(4); - PROVIDE (__stack_und_end = .); - - PROVIDE (__stack_svc_start = .); - . += SVC_STACK_SIZE; - . = ALIGN(4); - PROVIDE (__stack_svc_end = .); - PROVIDE (__stack_end = .); - PROVIDE (__heap_start = .); - } > ram - -} -/*** EOF ***/ - diff --git a/testing/examples/SAM7X256Test/src/crt.s b/testing/examples/SAM7X256Test/src/crt.s deleted file mode 100644 index 16e5865ea..000000000 --- a/testing/examples/SAM7X256Test/src/crt.s +++ /dev/null @@ -1,225 +0,0 @@ -/**************************************************************************** -* Copyright (c) 2006 by Michael Fischer. All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* 1. Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the author nor the names of its contributors may -* be used to endorse or promote products derived from this software -* without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -* THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS -* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED -* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF -* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -* SUCH DAMAGE. -* -**************************************************************************** -* -* History: -* -* 18.12.06 mifi First Version -* The hardware initialization is based on the startup file -* crtat91sam7x256_rom.S from NutOS 4.2.1. -* Therefore partial copyright by egnite Software GmbH. -****************************************************************************/ - -/* - * Some defines for the program status registers - */ - ARM_MODE_USER = 0x10 /* Normal User Mode */ - ARM_MODE_FIQ = 0x11 /* FIQ Fast Interrupts Mode */ - ARM_MODE_IRQ = 0x12 /* IRQ Standard Interrupts Mode */ - ARM_MODE_SVC = 0x13 /* Supervisor Interrupts Mode */ - ARM_MODE_ABORT = 0x17 /* Abort Processing memory Faults Mode */ - ARM_MODE_UNDEF = 0x1B /* Undefined Instructions Mode */ - ARM_MODE_SYS = 0x1F /* System Running in Priviledged Operating Mode */ - ARM_MODE_MASK = 0x1F - - I_BIT = 0x80 /* disable IRQ when I bit is set */ - F_BIT = 0x40 /* disable IRQ when I bit is set */ - -/* - * Register Base Address - */ - AIC_BASE = 0xFFFFF000 - AIC_EOICR_OFF = 0x130 - AIC_IDCR_OFF = 0x124 - - RSTC_MR = 0xFFFFFD08 - RSTC_KEY = 0xA5000000 - RSTC_URSTEN = 0x00000001 - - WDT_BASE = 0xFFFFFD40 - WDT_MR_OFF = 0x00000004 - WDT_WDDIS = 0x00008000 - - MC_BASE = 0xFFFFFF00 - MC_FMR_OFF = 0x00000060 - MC_FWS_1FWS = 0x00480100 - - .section .vectors,"ax" - .code 32 - -/****************************************************************************/ -/* Vector table and reset entry */ -/****************************************************************************/ -_vectors: - ldr pc, ResetAddr /* Reset */ - ldr pc, UndefAddr /* Undefined instruction */ - ldr pc, SWIAddr /* Software interrupt */ - ldr pc, PAbortAddr /* Prefetch abort */ - ldr pc, DAbortAddr /* Data abort */ - ldr pc, ReservedAddr /* Reserved */ - ldr pc, IRQAddr /* IRQ interrupt */ - ldr pc, FIQAddr /* FIQ interrupt */ - - -ResetAddr: .word ResetHandler -UndefAddr: .word UndefHandler -SWIAddr: .word SWIHandler -PAbortAddr: .word PAbortHandler -DAbortAddr: .word DAbortHandler -ReservedAddr: .word 0 -IRQAddr: .word IRQHandler -FIQAddr: .word FIQHandler - - .ltorg - - .section .init, "ax" - .code 32 - - .global ResetHandler - .global ExitFunction - .extern main -/****************************************************************************/ -/* Reset handler */ -/****************************************************************************/ -ResetHandler: - /* - * The watchdog is enabled after processor reset. Disable it. - */ - ldr r1, =WDT_BASE - ldr r0, =WDT_WDDIS - str r0, [r1, #WDT_MR_OFF] - - - /* - * Enable user reset: assertion length programmed to 1ms - */ - ldr r0, =(RSTC_KEY | RSTC_URSTEN | (4 << 8)) - ldr r1, =RSTC_MR - str r0, [r1, #0] - - - /* - * Use 2 cycles for flash access. - */ - ldr r1, =MC_BASE - ldr r0, =MC_FWS_1FWS - str r0, [r1, #MC_FMR_OFF] - - - /* - * Disable all interrupts. Useful for debugging w/o target reset. - */ - ldr r1, =AIC_BASE - mvn r0, #0 - str r0, [r1, #AIC_EOICR_OFF] - str r0, [r1, #AIC_IDCR_OFF] - - - /* - * Setup a stack for each mode - */ - msr CPSR_c, #ARM_MODE_UNDEF | I_BIT | F_BIT /* Undefined Instruction Mode */ - ldr sp, =__stack_und_end - - msr CPSR_c, #ARM_MODE_ABORT | I_BIT | F_BIT /* Abort Mode */ - ldr sp, =__stack_abt_end - - msr CPSR_c, #ARM_MODE_FIQ | I_BIT | F_BIT /* FIQ Mode */ - ldr sp, =__stack_fiq_end - - msr CPSR_c, #ARM_MODE_IRQ | I_BIT | F_BIT /* IRQ Mode */ - ldr sp, =__stack_irq_end - - msr CPSR_c, #ARM_MODE_SVC | I_BIT | F_BIT /* Supervisor Mode */ - ldr sp, =__stack_svc_end - - - /* - * Clear .bss section - */ - ldr r1, =__bss_start - ldr r2, =__bss_end - ldr r3, =0 -bss_clear_loop: - cmp r1, r2 - strne r3, [r1], #+4 - bne bss_clear_loop - - - /* - * Jump to main - */ - mrs r0, cpsr - bic r0, r0, #I_BIT | F_BIT /* Enable FIQ and IRQ interrupt */ - msr cpsr, r0 - - mov r0, #0 /* No arguments */ - mov r1, #0 /* No arguments */ - ldr r2, =main - mov lr, pc - bx r2 /* And jump... */ - -ExitFunction: - nop - nop - nop - b ExitFunction - - -/****************************************************************************/ -/* Default interrupt handler */ -/****************************************************************************/ - -UndefHandler: - b UndefHandler - -SWIHandler: - b SWIHandler - -PAbortHandler: - b PAbortHandler - -DAbortHandler: - b DAbortHandler - -IRQHandler: - b IRQHandler - -FIQHandler: - b FIQHandler - - .weak ExitFunction - .weak UndefHandler, PAbortHandler, DAbortHandler - .weak IRQHandler, FIQHandler - - .ltorg -/*** EOF ***/ - - diff --git a/testing/examples/SAM7X256Test/src/main.c b/testing/examples/SAM7X256Test/src/main.c deleted file mode 100644 index 99f2d2628..000000000 --- a/testing/examples/SAM7X256Test/src/main.c +++ /dev/null @@ -1,91 +0,0 @@ -/**************************************************************************** -* Copyright (c) 2006 by Michael Fischer. All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* 1. Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the author nor the names of its contributors may -* be used to endorse or promote products derived from this software -* without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -* THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS -* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED -* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF -* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -* SUCH DAMAGE. -* -**************************************************************************** -* History: -* -* 30.03.06 mifi First Version for Insight tutorial -* 26.01.08 mifi Added variable "d" to test const variable. -****************************************************************************/ -#define __MAIN_C__ - -/* - * I use the include only, to show - * how to setup a include dir in the makefile - */ -#include "typedefs.h" - -/*=========================================================================*/ -/* DEFINE: All Structures and Common Constants */ -/*=========================================================================*/ - -/*=========================================================================*/ -/* DEFINE: Prototypes */ -/*=========================================================================*/ - -/*=========================================================================*/ -/* DEFINE: Definition of all local Data */ -/*=========================================================================*/ -static const DWORD d = 7; - -/*=========================================================================*/ -/* DEFINE: Definition of all local Procedures */ -/*=========================================================================*/ - -/*=========================================================================*/ -/* DEFINE: All code exported */ -/*=========================================================================*/ -/***************************************************************************/ -/* main */ -/***************************************************************************/ -int main (void) -{ - DWORD a = 1; - DWORD b = 2; - DWORD c = 0; - - a = a + d; - - while (1) - { - a++; - b++; - c = a + b; - } - - /* - * This return here make no sense. - * But to prevent the compiler warning: - * "return type of 'main' is not 'int' - * we use an int as return :-) - */ - return(0); -} - -/*** EOF ***/ diff --git a/testing/examples/SAM7X256Test/test_ram.elf b/testing/examples/SAM7X256Test/test_ram.elf deleted file mode 100644 index 050209526ceac48011c2f78068e74927ae2fc2cd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 36888 zcmeH~U2Ggz701t=-F4j9Nt^`n(MDn-EhUkv^*VAs6cF{=yG~b*?bd5!iVW-h7~8AZ zyUy-7I3=h~6RIMmQVMzCp_L6vMOF0yp*|u}3Gu)a;ah?iCyphAK=PtI6eTeH&z-ru z6RRK|ctJWRxpU6{+;czXH`lwfFK5mVE2Rn)m_^4(As!%``r(hfO4I@053SJGL;G|; zts#jVw_6HsFVP-2KhJ@f5D)@FKnMr{As_^VfDjM@LO=)z0U;m+gn$qb0zyCt2mv7= z1cZPP5CTF#2nYcoAOwVf5D)@FKnMr{As_^VfDjM@LO=)z0U;m+gn$qb0zyCt2mv7= z1cZPP5CTF#2nYcoAOwVf5D)@FKnMr{As_^VfDjM@LO=)z0U;m+gn$qb0zyCt2mv7= z1cZPP5CTF#2nYcoAOwVf5D)@FKnMr{As_^VfDjM@LO=)z0U;m+gn$qb0zyCt2mv7= z1cZPP5CTF#2nd1y9|E7;S>OIoZGddLkM<|Dzo6})u|0tQ5bgb*^=<2kjjbqM-F}bO zx8H*%#9q(l)@|rn#2Y%dxs_B`x8rDk+&Q{+^UnJA@8NI2{}TQ+_+P6Y?a62AM+=skt~Q1bO{3qA_Z`|E^1 zlf+)_??AtWzH6IY!?8+UyT@@fi1irzEv+NTS2lU<1MKl8=HEj^sROtaoIk!J3=I0ps8>jote?-aPA96{Z z#o<*67`d3PR+PZ!>v^3XPni-(()LWArLZsC8nG~YHq)0eTFr8-Lsg*y9{YNIk=b;`D%u=X?- zYIWCcr7KmJtY~bpR-L!~c#n=BD~P10$0yQcCEnNf!doYmR-eNCnPt&ItYZaInV<6> z-f&|@Qp0|{8pG2%=f_ugL0&6XCUv@(2Ss@29o$XoAoX-ibwoO!>ikUSVLp-SphDEe znS<((>gmAbaq8;&0#f+X`8Y*7&vt#TD|;9ZH=&;G_T^{0vxm8SphKY}*59hK_7ZhG zO=ak#^NW?LW8zA6u4dvwu~>I5 zwN$-Ooo^3%T+P)BORYH;Yb7&id8JrI50)y`mX;hGh5z23LMiT?a0*~H(Hh}1lVjif zCqr};632rgX!g(&kVU8~qyHz5J9UP^Zyu{-?>cx&k(eqO4GZ;9cz4H zYkGfR*ZTZ!diNk_Ij61Z{gpkxw`ps7f7jmjC02g4OUJMo8~=P$bO1UY()?w4EToS@ zKNHf=Kqo``G<1JRr=ib;^m*vdhx8QT;ey=wB;r$PUbP@gUgfx$T6w()=jYYw0 z75b*KHB)?_5!bW!O%czZRJJdJ{u?3v63-XR*@OAMh4@4A>uq%0;y%0&v-RNb?KU+3 zCSc?KA3^^nq<;cU5u3Yp{V$-+-z$&*E%$SS@p|_W50D*bMNQ~%{X?$h_j4GJ@3IhZ z4#wl3gf_oVct6LW+v61_9@7?`g=QYJ7?0OvdKTIoNS<$OSN#Eslvgtrf8{F>2x+nqrvR(!$Bv9)46;fE)*|N{*qI2YxM?AI1R^5 zmCJRSs^V9Jj&jpk?VnE-@n)>UbUWk`^-E4!=YdCiFw;I>CX9ZrP%SSyb;7$;zO?8R z>iNZ5ZQ1-rDHE#mxyjVfNIsYSa)zZDkD3 zDw)!`%0*r3lnZWwu%YnO`u5E5e4aPN)0(j>)w0&9!O8F_|8C7NN52^QgR#51>%U;) hFoehC{q=DS!dYy`Or!Z4VKz{y`r+th1giWWBeF}7E+ zcb(mFa7s{}CR9aAr55tQLn|AU3RLw0p*|u}3Gu)a;ah?iC$1%gK=PtKfD#z~=ia@$ z6RRK|c;MljYN{+}yV5*?ZyS^$$Pv{l|$8-g}qc-KO0W_lP#PDYm&?K;6Nu z&3lLaLC$sC1KIA*=SKT(k*GlXyER|eGB`c zEeh7ll8Y#9p0mLBD~%8(Un%v6Z}WpW|>RR%4tulny0d+~TqCV~?+5{(V?2 zbr6S=TPoMciXi+dnyvO=TMrKGCkuuYn$>Dnh$>Al(PBvyu?ZI?beF6_ZT4Z5BhA+_ z^jA&~oBxQCoqxzBRT{^^!6CHMLu~d@jLu_Tn@;iZgO*PW*6P^Aa;a8NRCpKO)fKnu z&bJba7zT^j3@-E&EIvMd;kye9H|#K`y{x9?g0R{;M>w59eKzTHh04{1uhi;=#m2H* zSe~!7DvNHj&{%QnjY_rPHCOAG63tU*PZvD5<<;s71$V8qyt3rB3i;H;nJ=6?b$SLJ zbbfNyN#&iBiJ`M(tq)--n+~f*xhL%mCr&0#Dv*PnQ}~}P&8N-R^aU(uThYp5smXq| z-l{Fs-KwJ#_P*9)qv<)_bgk}@9gZwD>I;sJ_o?`if>35|YC1!9;vID^ymhiN*2i&v zW?6I)>qv>L?9X@)uX&L&Sz|h0i{NUV*YP!8kk^V-$vQL0gF?LXKJFXJgt`$Ewt zqMwW&;XBegWFhM3%pvQr73;&~aq92?EK>OM`3Qxg=lVb0pF4t!o3Nf9(DG9Qxg%UY z(r2L~GTg1QKSb2`ByqX1I0AL|P`Hzd(Fh{Gk9Rv6c1O`{TE$V<@yTC=GUmf{%;RQS!WIt-Olcn-W#Gyt+_as?}W+ z*Xr{P6PL>6rhBEUnx*}m_aM6RHd=J?BZ7V@9hbc;>-zm z0SpA!iEeYEW9AATgU0PaA(eMKMN< z(>IEQiMj9j7m3~qBuqHDr!IaImy!o`%+wX2P0U^2MjhTBT{EY237KHs7V4aCRqxcV z?x~}%6U75{;ZFS0p1L^dJ`t!hYrVFoE{!_AM#fCtcaShK_k9_4{Ae_0`VJwXubJ*y zLET%X2;S7Ow*&dtUnbhZ=J|DY293{y|GpkW3(j}#6{6Pz1I>IW`vB8_p`q@oj;aYg zvNF#fT!FQrsHY53n9?(X_RFeq@bw z6z_+>Gt@Vb%C-HQ@X7AQX#3xUjtBGxwEA}H)PGNTdQ-c${{sZwa?JlDX#VCh{Xa#} zyDDw}E_bZ+fvxTTo?Z9(-S+Q8UgVszw*MFQ{N1Lk?f+eQL)fB+dvpYwak@`Ep^iu)-6m&A6&p;0cbO!otKwp6VOhC^-2iKp2=I?547V-W^0=kU;?*}xG ze;Cl0p^b&XYYm#;+RPO1Gva#I+VuRrcc1RR73hDS=j+TF!+hUB%-{HI4m#8`J?bbO z!{6H-^z&~5Htzo+^sfW@$IxUsIPl-SO+ROiN;cNNQT<9nxBd5^&H2YLUwcpe1J+?j z4dC(pHbPay^R@lQq0R3T-p_I9+nw{{`4U`D4jouVHx02Dq(7HP0#e?>|`c8)|2_?@;xz;%8yg7IGUTGF?CGk(#6qKK1&>Ar*i4(;?x*ML*+6Z zF`b`D7bm7k`SI*?I+%sbPSRXvMo+-OgdWY|Tqcvt(?n->__0nWhjaPj5DpYCQSpjf z@fyt*O}j1EOI52)nyuqkgNpKVIpsf>D&xyog_&N+Bbry-s>%b8@?fTXyh<4TOsQU7 za+`#2sbXcxEj5cvjmC=kjZ!647xOcz^ms9!`(l=*8Br{@yi(;-v2~?Vbn8{pTQI%Z zwVF4!TCaGuMx9LQeC@I-b*m+>MA%SpYIS;Mc(KSE;%Uv;)p}Lw)aXobls;QC%vB$T pdN6j^^z;WNZie8PqFx`jK`@K$m}wMWBg_VBO}%-eOJz@O=wG?E5Xk@l diff --git a/testing/examples/SAM7X256Test/test_rom.hex b/testing/examples/SAM7X256Test/test_rom.hex deleted file mode 100644 index 27c4cba21..000000000 --- a/testing/examples/SAM7X256Test/test_rom.hex +++ /dev/null @@ -1,29 +0,0 @@ -:020000040010EA -:1000000018F09FE518F09FE518F09FE518F09FE5C0 -:1000100018F09FE518F09FE518F09FE518F09FE5B0 -:1000200040001000E4001000E8001000EC00100098 -:10003000F000100000000000F4001000F8001000B4 -:10004000B4109FE50209A0E3040081E5AC009FE540 -:10005000AC109FE5000081E5FF10E0E3A4009FE500 -:10006000600081E5A0109FE50000E0E3300181E53C -:10007000240181E5DBF021E390D09FE5D7F021E377 -:100080008CD09FE5D1F021E388D09FE5D2F021E329 -:1000900084D09FE5D3F021E380D09FE580109FE5D9 -:1000A00080209FE50030A0E3020051E1043081147C -:1000B000FCFFFF1A00000FE1C000C0E300F029E1DF -:1000C0000000A0E30010A0E35C209FE50FE0A0E1AA -:1000D00012FF2FE10000A0E10000A0E10000A0E17C -:1000E000FBFFFFEAFEFFFFEAFEFFFFEAFEFFFFEA7B -:1000F000FEFFFFEAFEFFFFEAFEFFFFEA40FDFFFF13 -:10010000010400A508FDFFFF0001480000F0FFFF0B -:100110000004200000032000000120000002200055 -:100120000008200000002000000020003001100026 -:100130000CD04DE20130A0E300308DE50230A0E3A9 -:1001400004308DE50030A0E308308DE538309FE5C0 -:10015000002093E500309DE5023083E000308DE51E -:1001600000309DE5013083E200308DE504309DE5EF -:10017000013083E204308DE500209DE504309DE5EB -:10018000033082E008308DE5F4FFFFEA90011000B3 -:040190000700000064 -:0400000500100040A7 -:00000001FF diff --git a/testing/examples/SAM7X256Test/test_rom.map b/testing/examples/SAM7X256Test/test_rom.map deleted file mode 100644 index c8047f282..000000000 --- a/testing/examples/SAM7X256Test/test_rom.map +++ /dev/null @@ -1,170 +0,0 @@ - -Memory Configuration - -Name Origin Length Attributes -rom 0x00100000 0x00040000 -ram 0x00200000 0x00010000 -*default* 0x00000000 0xffffffff - -Linker script and memory map - -LOAD ./src/crt.o -LOAD ./src/main.o -START GROUP -LOAD d:/compiler/yagarto/bin/../lib/gcc/arm-elf/4.2.2\libgcc.a -LOAD d:/compiler/yagarto/bin/../lib/gcc/arm-elf/4.2.2/../../../../arm-elf/lib\libc.a -END GROUP - 0x00000100 FIQ_STACK_SIZE = 0x100 - 0x00000100 IRQ_STACK_SIZE = 0x100 - 0x00000100 ABT_STACK_SIZE = 0x100 - 0x00000100 UND_STACK_SIZE = 0x100 - 0x00000400 SVC_STACK_SIZE = 0x400 - -.text 0x00100000 0x194 - *(.vectors) - .vectors 0x00100000 0x40 ./src/crt.o - 0x00100040 . = ALIGN (0x4) - *(.init) - .init 0x00100040 0xf0 ./src/crt.o - 0x001000f8 FIQHandler - 0x001000ec PAbortHandler - 0x001000d4 ExitFunction - 0x00100040 ResetHandler - 0x001000f0 DAbortHandler - 0x001000f4 IRQHandler - 0x001000e4 UndefHandler - 0x00100130 . = ALIGN (0x4) - *(.text) - .text 0x00100130 0x0 ./src/crt.o - .text 0x00100130 0x60 ./src/main.o - 0x00100130 main - 0x00100190 . = ALIGN (0x4) - *(.rodata) - .rodata 0x00100190 0x4 ./src/main.o - 0x00100194 . = ALIGN (0x4) - *(.rodata*) - 0x00100194 . = ALIGN (0x4) - *(.glue_7t) - .glue_7t 0x00100194 0x0 ./src/crt.o - .glue_7t 0x00100194 0x0 ./src/main.o - 0x00100194 . = ALIGN (0x4) - *(.glue_7) - .glue_7 0x00100194 0x0 ./src/crt.o - .glue_7 0x00100194 0x0 ./src/main.o - 0x00100194 . = ALIGN (0x4) - 0x00100194 etext = . - -.vfp11_veneer 0x00000000 0x0 - .vfp11_veneer 0x00000000 0x0 ./src/crt.o - .vfp11_veneer 0x00000000 0x0 ./src/main.o - -.data 0x00200000 0x0 - 0x00200000 PROVIDE (__data_start, .) - *(.data) - .data 0x00200000 0x0 ./src/crt.o - .data 0x00200000 0x0 ./src/main.o - 0x00200000 . = ALIGN (0x4) - 0x00200000 edata = . - 0x00200000 _edata = . - 0x00200000 PROVIDE (__data_end, .) - -.bss 0x00200000 0x800 - 0x00200000 PROVIDE (__bss_start, .) - *(.bss) - .bss 0x00200000 0x0 ./src/crt.o - .bss 0x00200000 0x0 ./src/main.o - *(COMMON) - 0x00200000 . = ALIGN (0x4) - 0x00200000 PROVIDE (__bss_end, .) - 0x00200000 . = ALIGN (0x100) - 0x00200000 PROVIDE (__stack_start, .) - 0x00200000 PROVIDE (__stack_fiq_start, .) - 0x00200100 . = (. + FIQ_STACK_SIZE) - *fill* 0x00200000 0x100 00 - 0x00200100 . = ALIGN (0x4) - 0x00200100 PROVIDE (__stack_fiq_end, .) - 0x00200100 PROVIDE (__stack_irq_start, .) - 0x00200200 . = (. + IRQ_STACK_SIZE) - *fill* 0x00200100 0x100 00 - 0x00200200 . = ALIGN (0x4) - 0x00200200 PROVIDE (__stack_irq_end, .) - 0x00200200 PROVIDE (__stack_abt_start, .) - 0x00200300 . = (. + ABT_STACK_SIZE) - *fill* 0x00200200 0x100 00 - 0x00200300 . = ALIGN (0x4) - 0x00200300 PROVIDE (__stack_abt_end, .) - 0x00200300 PROVIDE (__stack_und_start, .) - 0x00200400 . = (. + UND_STACK_SIZE) - *fill* 0x00200300 0x100 00 - 0x00200400 . = ALIGN (0x4) - 0x00200400 PROVIDE (__stack_und_end, .) - 0x00200400 PROVIDE (__stack_svc_start, .) - 0x00200800 . = (. + SVC_STACK_SIZE) - *fill* 0x00200400 0x400 00 - 0x00200800 . = ALIGN (0x4) - 0x00200800 PROVIDE (__stack_svc_end, .) - 0x00200800 PROVIDE (__stack_end, .) - 0x00200800 PROVIDE (__heap_start, .) -OUTPUT(test_rom.elf elf32-littlearm) - -.ARM.attributes - 0x00000000 0x10 - .ARM.attributes - 0x00000000 0x10 ./src/crt.o - .ARM.attributes - 0x00000010 0x10 ./src/main.o - -.debug_line 0x00000000 0xd6 - .debug_line 0x00000000 0x7f ./src/crt.o - .debug_line 0x0000007f 0x57 ./src/main.o - -.debug_info 0x00000000 0x1aa - .debug_info 0x00000000 0x75 ./src/crt.o - .debug_info 0x00000075 0x135 ./src/main.o - -.debug_abbrev 0x00000000 0x6d - .debug_abbrev 0x00000000 0x12 ./src/crt.o - .debug_abbrev 0x00000012 0x5b ./src/main.o - -.debug_aranges 0x00000000 0x48 - .debug_aranges - 0x00000000 0x28 ./src/crt.o - .debug_aranges - 0x00000028 0x20 ./src/main.o - -.debug_ranges 0x00000000 0x20 - .debug_ranges 0x00000000 0x20 ./src/crt.o - -.debug_frame 0x00000000 0x24 - .debug_frame 0x00000000 0x24 ./src/main.o - -.debug_loc 0x00000000 0x1f - .debug_loc 0x00000000 0x1f ./src/main.o - -.debug_pubnames - 0x00000000 0x1b - .debug_pubnames - 0x00000000 0x1b ./src/main.o - -.comment 0x00000000 0x12 - .comment 0x00000000 0x12 ./src/main.o - -Cross Reference Table - -Symbol File -DAbortHandler ./src/crt.o -ExitFunction ./src/crt.o -FIQHandler ./src/crt.o -IRQHandler ./src/crt.o -PAbortHandler ./src/crt.o -ResetHandler ./src/crt.o -UndefHandler ./src/crt.o -__bss_end ./src/crt.o -__bss_start ./src/crt.o -__stack_abt_end ./src/crt.o -__stack_fiq_end ./src/crt.o -__stack_irq_end ./src/crt.o -__stack_svc_end ./src/crt.o -__stack_und_end ./src/crt.o -main ./src/main.o - ./src/crt.o diff --git a/testing/examples/STM32-103/main.elf b/testing/examples/STM32-103/main.elf deleted file mode 100644 index a7f30197b5822a350b1177e3fa3c78afa6adc324..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 144604 zcmeHud3cr8x$pYEZztI#A=yb7B5>MB&{Am`oe|6ckw74rpfYI5CfQ_f3?U{vKuFV@ z7Olgvy;XWWEe_XO>r~r%Jho43q=#cYt@>Dt!|7G*>BDVpODXk6N|6!|-rsMnZ`v8G z_UZH7KkmC>?RUNF9oAaEHLtz$-yPj1 zum+Fla#({i|HATEgU3$7gN^)cPzTi6kg7i3-`E(R`>(?#Q?;Zd{+r+RKcT*}ucrU0 zj?4Df43B%cPfa>+TeindX$tgrKc>F3v&lKs3yt>{^fvV-)vS{*<-DDr9g zLUz2rd}R6tq@Omv(CVfpdq=d<@RDe6?~_Y!a$(cLn*`OgNtnCZFSx&j=NM=l zYW`qld_NyejYAmwqqp4fx*9xl(Rw8{1J@1os9A*vDvyn`(046R(<62se0->fsJ-!c zUPlpn*En|^dGgmG-=^gpNpCz}(h+WdGcQ#fdri04F5P>)-oZ9~zq(XZe=s~u9+k(+ zbcxYE_7u$FVa|*pYnFo%6qyx0P=I=PatqqoAwCOyP=m~V*IzwaANTUloMFz`(wnRV zA|;ywZ{a?C$*8_=^!vwv+e_Hr7RLGA>(6x?lI)oSO#^yvh|J1Iy`r;X_*S!4zO*Ze z@m#+D*e=X_b%(;-Qq)svl;Gib2S(oz`pTYa=k4$qr>uX$!uZ0JnlfShVO!lUxpK_4*`lgW0@k7l-05;_#ZPxoXdoygB8jZ~>?`spRKg6P<+Su$_VDdQ} zD%(NKDO2J(Z%+%>Sv^nfY|5({>KNLoW{t;~%Iq2IQl@7##@P=?$~c}%cmw6#tRP(CGBw9mWA=GU<862>Tw1?s@I=|sq$0ypB(IX-gsPL zw!?nU8S1tVF)!rOS6UPFRCmvnu`AlJrFyWxt8tURXUyCubb004n;hz~(QI0SoKBcb+(H;tKI^pPmm%)RjC43FDM}?etlY#9YZ~sbTodN6*8H=Gkvatr-xpPX*fZn%JGW8~B@I6Qx5A-Id zCXMaFc=e%+Q^?(M&|iAtY3fZ=YI;*_Q@!S<_Eyb)X<@4V$Zo7UyP#R9HHYFuDU2R_ zAmw0JH~`5&5+05Xq_|5Q&?TCQzUuqtoUK!r4NIMZ)dgo6tZWNYIkUe1dT;W{6wg(x z9ZU1xtaV7+;Fq`V5cQ+Zl$!T1^|^m@smH-GBZpAgN0VjN;5)DHN)DtNF;mUR*caLj80zXx?oIaI^ufp2PVD;bOy2o8M_+i& zF#D^pU#wUk((fCi`1RJJ-u{xB-i}_ZbIyTXH*qbr50S1PWp3r1-P=#;!O)EE?E!Te zvG2f%;3n_Xu`4;0+!Lq8-nfaQmMQLV`5m5TSWlZb z)5kgEI>lZ-Pxg2*&t~j%&NR$IWh2fxX5YrOS@&VxlZW)Tw|DbAZ@`@1%iUKwb}rT2 z-=HMbj1Qn*&T&oE=&=}g3**^`1~Pc= zJBl#gjklZw+$A|x3-u^n7>{5qJ*nr1g>kP`7pHhS@OCj@dgA&~@EpK8<2aZTY=1r= z#yBrn)&TI_gH@-r1}RumEZa-r-m>9jd6_OT(YF;+Dv>hWcG_6B>Qs-Pw_~4j{!{@k z5!Xx3+cAu|FS++7reF4Am!JRAs$(%*-y9u_IquC7Mjp?|BPHcpk~wyaFX(FPUD$n& zChx_HJ$hcecbJU!D|y>498IGf^KVI0HcO*(K+m!Fj*J@3CSc?GS?S(VH%P;pE9A6kgAAIleLGJ)XPY@6U1OY)n z5D)|e0YN|z5CjAPK|l}?1Ox#=KoAfF1OY)n5D)|e0YN|z5CjAPK|l}?1Ox#=KoAfF z1OY)n5D)|e0YN|z5CjAPK|l}?1Ox#=KoAfF1OY)n5D)|e0YN|z5CjAPK|l}?1Ox#= zKoAfF1OY)n5D)|e0YN|z5CjAPK|l}?1Ox#=KoAfF1OY)n5D)|e0YN|z5CjAPK|l}? z1Ox#=KoAfF1OY)n5D)|e0YN|z5CjAPK|l}?1Ox#=KoAfF1OY)n5D)|e0YN|z5CjAP zK|l}?1Ox#=KoAfF1OY)n5D)|e0YN|z5CjAPK|l}?1Ox#=KoAfF1OY)n5D)|e0YN|z z5CjAPK|l}?1Ox#=KoAfF1OY)n5D)|e0YN|z5CjAPK|l}?1Ox#=KoAfF1OY)n5D)|e z0YN|z5CjAPK|l}?1Ox#=KoAfF1OY)n5D)|e0YN|z5CjAPK|l}?1Ox#=KoAfF1OY)n z5D)|e0YN|z5CjAPK|l}?1Ox#=KoAfF1OY)n5D)|e0YN|z5CjAPK|l}?1Ox#=KoAfF z1OY)n5D)|e0YN|z5CjAPK|l}?1Ox#=KoAfF1OY)n5D)|e0YN|z5CjAPK|l}?1Ox#= zKoAfF1OY)n5D)|e0YN|z5CjAPK|l}?1Ox#=KoAfF1OY)n5D)|e0YN|z5CjAPK|l}? z1Ox#=KoAfF1OY)n5D)|e0YN|z5CjAPK|l}?1Ox#=KoAfF1OY)n5D)|e0YN|z5CjAP zK|l}?1Ox#=KoAfF1OY)n5D)|e0YN|z5CjAPK|l}?1Ox#=KoAfF1OY)n5D)|e0YN|z z5CjAPK|l}?1Ox#=KoAfF1OY)n5D)|e0YN|z5CjAPK|l}?1Ox#=KoAfF1OY)n5D)|e z0YN|z5CjAPK|l}?1Ox#=KoAfF1OY)n5D)|e0YN|z5CjAPK|l}?1Ox#=KoAfF1OY)n z5D)|e0YN|z5CjAPK|l}?1Ox#=KoAfF1OY)n5D)|e0YN|z5CjAPK|l}?1Ox#=KoAfF z1OY)n5D)|e0YN|z5CjAPK|l}?1O$QqpAoQZC&G}O6CGzqvZGd!byh)1o>MTjpvWq= zV%bXBGgMyQVk9Z$Oj1tt;=F}kTVULg%`+J(m5*%Pbfw16R+r`*_G9_AB`j41N>$*NDymdrSi_UYW?O-o zNn`le7x5o_w~hxcd8J6|VO< z4~^U~f_a$;=4T?9ft80u!RSa7W+D*_s>{k2`9@hE%Maiyc8#)XOQ==i8oBHQzad~0 zG!>C#uW_{|c?eGq=i#ZdF-pUJylR}`HPsZasiywD+aV19hv~Oo$@0CDjrZE_17hzX zQsh@W&qE!3G_z%hxjP2g1QUD^VG;&$qAv(F2GO0A*@lxd+psij7Bu`BnQb^_q!wn; zzhOX_Cd>}cA)Gq&91`{Bka6LL$@Q?!3y+K810i#me86T1qwhf(9tt6Z|5~%Cmu<|P zdS!`NmIZ8X$Jah2RA5e=X)DZIP>5t5MzU>Z{fNZME+mQMd=oOKd*1n&d+VrX=e$K? zMaM%Pxft;*%RVm+n!OcYDyMPj8f7u@f}5F`#hkPE;LB3cX-@rd#Ku)O)G256dPMDV za?6x+x#1$?YL_%9r@?U1arNXH4VRz01{Tg5!^Or`H9&TS;U?r_!c@+chAUNhk(?|m z^3h@xGJ7v1R`xpPmYqa`qw+rsCQ|+mzM*x_Rn&SLUn)CBLH7Cho|)Z+?`Ku^c+_A* zHg#gzXCrA^b`RpED*q!8MCShkm}n%j@PB~j-i)uvC6&-Z#V{nmEn*q$ay$2@lr5$o zyBtOMUt}-cgl`m~`n#anDH>#7hNz{+Tc0Goz%+@>pJ~n zu=Z`tW-<9L>sIKnulyQ<;y4r;O4yo(YC@zH3_8nWU?+Z+1`{twik0OcAzHi#afV4$ z|JPR`NB@}wGVwj?e(X`BTRK5SC-);h@i8XPBBI7c*~Et#|0J_PN<^tLH4SLk3bj{m zukJ!Jdo@d0man4sB0g%bcDfhLM;k2Fa^1n*UhQ;WsO+<@VY=JDsl)#L8PJUW9lbLP zTIaFFqPzVld;P;y&FJ-&D42c0mytd$l9M~r`T7bJIcX87`K;4*)w48*W1WHz<3=aHaXTqFBy14L2?SC*&SA zTv=XqBXanb;by4Z36YQNMVa!y908gi)oqVLHN$zN%y5x>1qYEc4HwP-4-_gg-EjH& zXH&D>a4{8qld3aV%kkC*#H}8SjgsrAXaN!ntOWA09=7t4a0kLgNcf!%Be4KHJL|1s0> z3n9bjSk`Y@)*2Y?MVJPo$7pyt4Ij-k{C3Fj1h^xT{*Oj zf$e85Y}--C2^byL|3O2+=pzWXz^DYJDE=0U@>VE|-AstsRvEN5A^aOO>!|rU^LA{v zNe#eRF3UE228vd>ZMDGYX@ryDx6|-KmTh`Sb3LrI3?;P0iTZtYq-Xl)kL z+GJbQisfMLh1T=be3XKC$mgG!&~01Pnu~BZw2u2e(;=VVWj$`NEovQ$s_3iGT9341 zb~x*Ln{oTLmWk=D9m@K=n?rJoxrs8k9h3tYMN1GLKtU4IohfoEhmudI_zAVRahpI7j9D^7Q z&!OWPj&(nbP9gL_KM!Rs?qmteGY!i_hQFY^%CX*sQA4hZJ_f@jG}Jj(W*Sz83==GB z+_Bcc=n;h9!LZNIu_@EADP&l}9D5w=Q5d~|fPSeSq@nHxJ6%mqGZrg#vtv=~D8d!c zddb(kDWrK73v-WSQ7b=BMQ?@H5H&GIm36mcCcGVLvh`&qJn2|mm#BFc!jGVNWe&9W z(ajHB?N-wj2HcvomAuS?KjpF=CF{uUbLfb(VyTr4H`X5=i!OhNa0>in>(k88idZ*8 zZ$DBM7TB|p*~83Gk6#sW=VRm2j!@N1w4Y{yW<)F+ab><5Mz8pW<*wllbq1H-UqdkE z2}BB2tdzNKK8}KwDD z?u8TXss9A(?y2?R!{1Z048fk7d2vsjWA@bh!E#Ssf(FjmQ|J5(0EjF-4S9j}6e^5; zGJ8X8yo&AtTLXi_6w@zYl>6UUgzZ&i^~2I?wx~H5;dv+(SaX<|wwUm4fr|baiCoQ% zi!S5h>cV~0>Y~8DZEf*mbl+`ez^3A7LtIPo?huzO>DbogYqk~ZUB`A~*HQcceYzYA zNuUa><4iqhu`Fj7;>3UvaR!FBDZ%Te1Zg$F`V#g2V0{WTn+d%Zgl6c*sjI7h#FV|Q zkmnieh{pc5Eya4SI7%~)>xtIgEH6eE<#h5HguQU|-{EMIcH~$dkQ1$W)W$6r?faqm z6v9i;e#6%;a<$tg>3oZ{WBax(lXb==+S26w8hy<&In&S25u)R`!S-@K$IrRcT21Xm zmh~F6aKejT3Qg{#O&KroG)=CTxVd&tT1A*HvDl65+pfdZ_$m6i(z2rPF#};c{M_RE zxx)9ejCxmieqeYD6Iv{bMoENk!SH3@usO5Z&0e+7(2ID&-`YSwFHY zYJI;*FRtnb)cidKPrE)_jN#L+VY4auGp;l_xt7Wv+h)q+u^p2mERDye)f6kA2`4Oz z8FHq+8O1YI{Bvd%J+|Fs_>NyibqXEVR*QhKJNw^(p2pd~1O9l>tVXZ$o<4{k?~hn;@;$0!$tEiqU^bp*38H7=NQIy0BiUp!hWDO1uzs&V)`t1 z(*?at$yZxXLFXXCJJ7>jfht_i^r}GbPi%%OtzSTAafyn~#tq9B>Sa^!ia>8B`Rl9- z=-i5sfF5s{%z3MW^=4m+S&vZfM%_l#yAJ`I3{0-Q6#SD#1n);8o98DG6kf^nJIuDC zwODUlzGAX%E74=a-F- z&GY8&+?ej^NX$-VrfrRP3{Pt9NNqD|SYYf5tWnPS*4(G&wx<4PcX#*Kx>u}Nv1(xY z3v=t{uADQla((S$CvWrIy6ts!JCb!fAY4(meT8kKG&@idTQwoWk>v|Y)!E$qHx`tZ zx;iW;kKWEnWzF5e&%QsuzHeW*Q@DKfzI~7Vbib3od0k~{<&IWo{MxHqoe68#Ri#$m z(28Vm1#4G8wgHjNb9Orum%Cii=8OnzOE%wl={wQsPHgR}Rww3(3pcOcvE$1(?lR6w z*495~GRa%JV&C=O+1ax@dHv$A@44^(w%sds>5ShzcfcuHzOL$Caz&dz)oNz}`WYJfO@9S? z-O_)LPQvYlbAh$Oo;$I1r~9wX$zMLF6{yZ$H?Vd6wLQtjbxCxR)*Uz0?Wl8-X=hq` zQDxnty4$-=;@9e&)IHABG`iE;I`kso*;=`M)#5Xq+|4T%Ir-@@7fau`c-3O6K(e;A za{Xd_7CD7$cUL8McdvIbJ9BO8{$y)%{rdH-pWm@~{pZofuCj1hF2g3YTIKVSF4c5qiSF?a2pb?ATVTG6IE zQ@5kCb~aisALV%uA4^%EF2F^5DR_P=Fcy!3Rux3QXx(U6jmOkAfdYJZL5e93vdE1V zBwjl2NJmTOHR<$_zLy7YO5OCTf|z#Y=g-?wPCDWIhnJQ4K8nEc_^V<5na+&k+l|0P-v*5#mL+J~4(Y zhU=KI?08l4G-e&0Us-0`@oI&4^rMx9wki~r;I10DV{7e zPATJgXe>LPZ^p9YiDvc~KBL&OyW=!t>@YtbM3#7V!^)Y2tZ59{vyhc}vSD@L5#fL* zbKBZ$3-08GySf2YZnIkbe>ZW+YE(abJY=hbA5) zeND%Ms*^v605g(bXmMYJl)n!Fy;9QYs54;jbDIJFYy_B*V2!70g!CK}kC86X@gO(y zydi-Z$uceOi;yli@lw*y>v)jcP2g`qfEmfHTHF^QyjM}&d&948ZoPk^6|05g)gTHF^Qop0i$q@6k*p@TU-9M)Ix}W2k|i zHt|x@i_wR}O?(OX#RxDXsnFuS2x*mx$4K|;c#zv&;O{|z8Ogm`+!rCe&%|S-Pw9AI zM*fEgFeBNo#eEUdr%gOYdRWH;GxA3eU`BFOi_vbNZ<%W+mb@Rs<`CJ5;k>qP} zUxXAtDiYN)(&urH1G6%Bh^ZIAzlZ=ck^@@Y7a@Jw#ABq>u^SKPHUs?Gyj;Lw0hy`A z7%ZUYn0SnImyQR8{51H_Ai#{IUyJ)9q@OeK80pJ89+G1AZJc#zxm;6IN5Gm@LMxGzF_i;2fb@7M9bjQj%# zFe7GLKYBYjiH12gi!MSvN}VJ*f?40^=G z%ShAXGMk$`?>u2fvQvvOOhNC^@nG8d3i!PUP$jubi~Ay^_n3Go>1#S3Oa$Z)BEXE~ z7g~%F4f;zHkCC3#@t{8JkC=^UMuHB`Ce}+bx*y|wJ?gH%ff?6f-nqeysE-q}h7f2?`bk zkJl13Bf-g#IYdYcOuUqIiH-;8k*`638Obs&#%cn(+{9y~pVILlwzr#p!>%0m9W+bb% zxGzH5VB#^-Ejk|5tqpuT0?bG{w74%q+G*l3(ie3+FgpPLWdxX!ysE{05z?QVc#L$K z9(#cq`HvvLjHFD9`y!BS~qM*5JB2cX}tbH|tZInd)T zkGxP;|A9#R*3`yiyuGC@(W#DrPsTf2Hpjc$(tawRySZ0pe%b`M+1j%t(H8H~5Adqn zuH9JMo=U5BE!duDPH*e%QhUL5b;O$!>Yow2Y;|qD)@n?5b~mTHI}_?hNN(oS&MCjSO9Zm6!_xFn%nKk2f|8kbgYYu}t|)z7b}P}#DjyDPn{v9>zimfF-A zPp7uEUm0)fPUweM)Szr@i+)i>c6D8y>w=q7F9iyGkV3X`U1N3K3Rj1}K{D~OMB1b` zZtLzuo%m3Y>B|Du#ctASB+YZp`94W!fwcK<8lN69t#*x@z$ZmaxT3Kt@W$stOsrf| z9VFJdiFG~>mF{W8ZEj*K9rAq&#Vf1pT~zrFg(;|GOTb;2G_2XxsrEW_3l~ZL@T-%TZcntQOS?UF!060t>MAc&9c^t} zyW83neh=?Vv?{Ka^EYz+=}xpa_b3*yp>a)vHV7}J^i{jYB>PJ^6NfDnX2A@3qz)E+ zci|>Cd@$;t%B9t=NcjXpBp)FSv&NcB(Z3*2~=7qAN7CJ7w4A2cJ zQZV+ukW$^Tf^z7XyH;ys4@rLq#8h+}e}_QmylQ6dFtoit%Cu*$Fu^vfY6JWlf1 zC%dxDRa#q)Tx%ip{y>`^dH(qycUSiRx0;o6vE7O%;+s;+Ivdff>iUK?OV@sK z`z>G&qlbf=+7FNR%CTFu_n)um>)BsO)o zZj5i*)S1}sajEvr+q^h-J_#?rxih}iXE1Si=^fph+93(Nb;jFU0~Wce+0EOwZbhe4 zvnv}`&W@+kovBUTY4?cjZ6yB+oeDX(o$l6D|DJd>w9z%YQ>D&?4vy*y#|?hUntqQ* zB_^)FJw3u0+QusC)#4!FeLUH@!}K10%TmXRJ*~h;#W1})EnB_r7J}NIKVATNai*v7 znDP41e%mV_|Ijk5cQVgbr}3Q6`*^aJVR|Pf+iLkJ_24Pdv!RcQf3Q_QBksqO?FP>{ zdmKOep|>vtAY}|+bSa4b^qp<1hdc(<^Y>4P1BMPybk@ggHP2&0dPPRhms|}E01#XPQ^T#u!NwyT<5b%#mh&kSqX?yaXd=4V~a}pxs$saXB zd}nL@0>98XYLPDs^5dD*Bpd&HdtpAto_}>*!j_;0xHD=6p9>+jt+B;@%B z;in<}R`7SbZ-yxE2EWvOlSlpr@Z(YcTaYjLJ>XZmZ=uLP0)C$Ru7~^+;PJOv`ke`R zzR^0>IT9W@7?a`mEbmjaZsuK0(x<>hP;Qz~g z+eMyhApSC0zY!(>2k`ite4l>@{8?!KC9ZugD*o>%f0@fq1pi;5_WcC-FTnmTSAHJ& zkB7$B3h?{Tzc?>3ziYt%G&G*P>ya60HKQf8Pc+ZON1WO+4|~D3(%sAl3Bf*-ryuv& z?QJ6II}h*W&5sDw&}XTPJ6?Y)AMD3*j?qW6%zF}lgH1mf7at??b5Fg) z?kc=OXKt&tF-{lZi&Ill+@y@W`t~cKud`in{9kJ*4SqEt#}oRnn|ht2zK5nl@C%7n z4fQ}upd(ivx7JL;s+{YEGnKA$Q!bkp27`|xL+L?!A7BO_c6!btp YPycpSTW7Q!8^SA6aCW83(ADGr1-NT2H~;_u diff --git a/testing/examples/STM32-103/readme.txt b/testing/examples/STM32-103/readme.txt deleted file mode 100644 index 39b080dd6..000000000 --- a/testing/examples/STM32-103/readme.txt +++ /dev/null @@ -1,6 +0,0 @@ -Olimex STM32-p103 board. - -main.elf is a file that can be programmed to flash for -testing purposes(e.g. test GDB load performance). - -http://www.olimex.com/dev/stm32-p103.html \ No newline at end of file diff --git a/testing/examples/STR710JtagSpeed/inc/typedefs.h b/testing/examples/STR710JtagSpeed/inc/typedefs.h deleted file mode 100644 index 42136426a..000000000 --- a/testing/examples/STR710JtagSpeed/inc/typedefs.h +++ /dev/null @@ -1,50 +0,0 @@ -/**************************************************************************** -* Copyright (c) 2006 by Michael Fischer. All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* 1. Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the author nor the names of its contributors may -* be used to endorse or promote products derived from this software -* without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -* THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS -* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED -* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF -* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -* SUCH DAMAGE. -* -**************************************************************************** -* History: -* -* 30.03.06 mifi First Version for Insight tutorial -****************************************************************************/ -#ifndef __TYPEDEFS_H__ -#define __TYPEDEFS_H__ - -/* - * Some types to use Windows like source - */ -typedef char CHAR; /* 8-bit signed data */ -typedef unsigned char BYTE; /* 8-bit unsigned data */ -typedef unsigned short WORD; /* 16-bit unsigned data */ -typedef long LONG; /* 32-bit signed data */ -typedef unsigned long ULONG; /* 32-bit unsigned data */ -typedef unsigned long DWORD; /* 32-bit unsigned data */ - - -#endif /* !__TYPEDEFS_H_ */ -/*** EOF ***/ diff --git a/testing/examples/STR710JtagSpeed/makefile b/testing/examples/STR710JtagSpeed/makefile deleted file mode 100644 index 816ab233e..000000000 --- a/testing/examples/STR710JtagSpeed/makefile +++ /dev/null @@ -1,134 +0,0 @@ -# -# !!!! Do NOT edit this makefile with an editor which replace tabs by spaces !!!! -# -############################################################################################## -# -# On command line: -# -# make all = Create project -# -# make clean = Clean project files. -# -# To rebuild project do "make clean" and "make all". -# - -############################################################################################## -# Start of default section -# - -TRGT = arm-elf- -CC = $(TRGT)gcc -CP = $(TRGT)objcopy -AS = $(TRGT)gcc -x assembler-with-cpp -BIN = $(CP) -O ihex - -MCU = arm7tdmi - -# List all default C defines here, like -D_DEBUG=1 -DDEFS = - -# List all default ASM defines here, like -D_DEBUG=1 -DADEFS = - -# List all default directories to look for include files here -DINCDIR = - -# List the default directory to look for the libraries here -DLIBDIR = - -# List all default libraries here -DLIBS = - -# -# End of default section -############################################################################################## - -############################################################################################## -# Start of user section -# - -# Define project name here -PROJECT = test - -# Define linker script file here -LDSCRIPT= ./prj/str7_ram.ld - -# List all user C define here, like -D_DEBUG=1 -UDEFS = - -# Define ASM defines here -UADEFS = - -# List C source files here -SRC = ./src/main.c - -# List ASM source files here -ASRC = ./src/crt.s - -# List all user directories here -UINCDIR = ./inc - -# List the user directory to look for the libraries here -ULIBDIR = - -# List all user libraries here -ULIBS = - -# Define optimisation level here -OPT = -O0 - -# -# End of user defines -############################################################################################## - - -INCDIR = $(patsubst %,-I%,$(DINCDIR) $(UINCDIR)) -LIBDIR = $(patsubst %,-L%,$(DLIBDIR) $(ULIBDIR)) -DEFS = $(DDEFS) $(UDEFS) -ADEFS = $(DADEFS) $(UADEFS) -OBJS = $(ASRC:.s=.o) $(SRC:.c=.o) -LIBS = $(DLIBS) $(ULIBS) -MCFLAGS = -mcpu=$(MCU) - -ASFLAGS = $(MCFLAGS) -g -gdwarf-2 -Wa,-amhls=$(<:.s=.lst) $(ADEFS) -CPFLAGS = $(MCFLAGS) $(OPT) -gdwarf-2 -mthumb-interwork -fomit-frame-pointer -Wall -Wstrict-prototypes -fverbose-asm -Wa,-ahlms=$(<:.c=.lst) $(DEFS) -LDFLAGS = $(MCFLAGS) -nostartfiles -T$(LDSCRIPT) -Wl,-Map=$(PROJECT).map,--cref,--no-warn-mismatch $(LIBDIR) - -# Generate dependency information -CPFLAGS += -MD -MP -MF .dep/$(@F).d - -# -# makefile rules -# - -all: $(OBJS) $(PROJECT).elf $(PROJECT).hex - -%o : %c - $(CC) -c $(CPFLAGS) -I . $(INCDIR) $< -o $@ - -%o : %s - $(AS) -c $(ASFLAGS) $< -o $@ - -%elf: $(OBJS) - $(CC) $(OBJS) $(LDFLAGS) $(LIBS) -o $@ - -%hex: %elf - $(BIN) $< $@ - -clean: - -rm -f $(OBJS) - -rm -f $(PROJECT).elf - -rm -f $(PROJECT).map - -rm -f $(PROJECT).hex - -rm -f $(SRC:.c=.c.bak) - -rm -f $(SRC:.c=.lst) - -rm -f $(ASRC:.s=.s.bak) - -rm -f $(ASRC:.s=.lst) - -rm -fR .dep - -# -# Include the dependency files, should be the last of the makefile -# --include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*) - -# *** EOF *** \ No newline at end of file diff --git a/testing/examples/STR710JtagSpeed/prj/eclipse_ft2232_ram.gdb b/testing/examples/STR710JtagSpeed/prj/eclipse_ft2232_ram.gdb deleted file mode 100644 index 92f8e18e5..000000000 --- a/testing/examples/STR710JtagSpeed/prj/eclipse_ft2232_ram.gdb +++ /dev/null @@ -1,33 +0,0 @@ -target remote localhost:3333 - -monitor reset -monitor sleep 500 -monitor poll -monitor soft_reset_halt -monitor arm7_9 sw_bkpts enable -monitor mww 0xA0000050 0x01c2 -monitor mdw 0xA0000050 -monitor mww 0x6C000004 0x8005 -monitor mdw 0x6C000004 -monitor mww 0xE0005000 0xFFFF -monitor mww 0xE0005004 0x00FF -monitor mww 0xE0005008 0xFFFF -monitor mdw 0xE0005000 -monitor mdw 0xE0005004 -monitor mdw 0xE0005008 -monitor mww 0xE000500C 0x0000 - -monitor arm7_9 fast_memory_access enable -monitor arm7_9 dcc_downloads enable -monitor verify_ircapture disable - -load -break main -continue - - - - - - - diff --git a/testing/examples/STR710JtagSpeed/prj/str710_jtagkey.cfg b/testing/examples/STR710JtagSpeed/prj/str710_jtagkey.cfg deleted file mode 100644 index b8aa96f5e..000000000 --- a/testing/examples/STR710JtagSpeed/prj/str710_jtagkey.cfg +++ /dev/null @@ -1,34 +0,0 @@ -#daemon configuration -telnet_port 4444 -gdb_port 3333 - -# tell gdb our flash memory map -# and enable flash programming -gdb_memory_map enable -gdb_flash_program enable - -#interface -interface ft2232 -ft2232_device_desc "Amontec JTAGkey A" -ft2232_layout jtagkey -ft2232_vid_pid 0x0403 0xcff8 -jtag_speed 0 - -#use combined on interfaces or targets that can't set TRST/SRST separately -reset_config trst_and_srst srst_pulls_trst - -#jtag scan chain -jtag newtap str7 cpu -irlen 4 -irmask 0xf - -#target configuration -target create target0 arm7tdmi -endian little -chain-position 0 -[new_target_name] configure -work-area-virt 0 -work-area-phys 0x2000C000 -work-area-size 0x4000 -work-area-backup false - -#flash bank str7x 0 0 -flash bank str7x 0x40000000 0x00040000 0 0 0 STR71x - -# For more information about the configuration files, -# look at the OpenOCD User's Guide. - -init -reset halt diff --git a/testing/examples/STR710JtagSpeed/prj/str7_ram.ld b/testing/examples/STR710JtagSpeed/prj/str7_ram.ld deleted file mode 100644 index d760f2620..000000000 --- a/testing/examples/STR710JtagSpeed/prj/str7_ram.ld +++ /dev/null @@ -1,140 +0,0 @@ -/**************************************************************************** -* Copyright (c) 2006 by Michael Fischer. All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* 1. Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the author nor the names of its contributors may -* be used to endorse or promote products derived from this software -* without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -* THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS -* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED -* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF -* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -* SUCH DAMAGE. -* -**************************************************************************** -* -* History: -* -* 30.03.06 mifi First Version -****************************************************************************/ - - -ENTRY(ResetHandler) -SEARCH_DIR(.) - -/* - * Define stack size here - */ -FIQ_STACK_SIZE = 0x0100; -IRQ_STACK_SIZE = 0x0100; -ABT_STACK_SIZE = 0x0100; -UND_STACK_SIZE = 0x0100; -SVC_STACK_SIZE = 0x0400; - -/* - * This file, hitex_str7_ram.ld, locate the program in the internal - * ram of the STR7. For more information about the memory of the STR7 - * take a look in the STR71X Microcontroller Reference Manual. - * Reference is made to Rev. 6 March 2005 - * - * Take a look at page 16, section 2.1.1 Memory Map - */ - -MEMORY -{ - ram : org = 0x62000000, len = 512k -} - -/* - * Do not change the next code - */ -SECTIONS -{ - .text : - { - *(.vectors); - . = ALIGN(4); - *(.init); - . = ALIGN(4); - *(.text); - . = ALIGN(4); - *(.rodata); - . = ALIGN(4); - *(.rodata*); - . = ALIGN(4); - *(.glue_7t); - . = ALIGN(4); - *(.glue_7); - . = ALIGN(4); - etext = .; - } > ram - - .data : - { - PROVIDE (__data_start = .); - *(.data) - . = ALIGN(4); - edata = .; - _edata = .; - PROVIDE (__data_end = .); - } > ram - - .bss : - { - PROVIDE (__bss_start = .); - *(.bss) - *(COMMON) - . = ALIGN(4); - PROVIDE (__bss_end = .); - - . = ALIGN(256); - - PROVIDE (__stack_start = .); - - PROVIDE (__stack_fiq_start = .); - . += FIQ_STACK_SIZE; - . = ALIGN(4); - PROVIDE (__stack_fiq_end = .); - - PROVIDE (__stack_irq_start = .); - . += IRQ_STACK_SIZE; - . = ALIGN(4); - PROVIDE (__stack_irq_end = .); - - PROVIDE (__stack_abt_start = .); - . += ABT_STACK_SIZE; - . = ALIGN(4); - PROVIDE (__stack_abt_end = .); - - PROVIDE (__stack_und_start = .); - . += UND_STACK_SIZE; - . = ALIGN(4); - PROVIDE (__stack_und_end = .); - - PROVIDE (__stack_svc_start = .); - . += SVC_STACK_SIZE; - . = ALIGN(4); - PROVIDE (__stack_svc_end = .); - PROVIDE (__stack_end = .); - PROVIDE (__heap_start = .); - } > ram - -} -/*** EOF ***/ - diff --git a/testing/examples/STR710JtagSpeed/src/crt.s b/testing/examples/STR710JtagSpeed/src/crt.s deleted file mode 100644 index d1c238c7b..000000000 --- a/testing/examples/STR710JtagSpeed/src/crt.s +++ /dev/null @@ -1,263 +0,0 @@ -/**************************************************************************** -* Copyright (c) 2006 by Michael Fischer. All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* 1. Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the author nor the names of its contributors may -* be used to endorse or promote products derived from this software -* without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -* THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS -* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED -* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF -* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -* SUCH DAMAGE. -* -**************************************************************************** -* -* History: -* -* 04.03.06 mifi First Version -* This version based on an example from Ethernut and -* "ARM Cross Development with Eclipse" from James P. Lynch -****************************************************************************/ - -/* - * Some defines for the program status registers - */ - ARM_MODE_USER = 0x10 /* Normal User Mode */ - ARM_MODE_FIQ = 0x11 /* FIQ Fast Interrupts Mode */ - ARM_MODE_IRQ = 0x12 /* IRQ Standard Interrupts Mode */ - ARM_MODE_SVC = 0x13 /* Supervisor Interrupts Mode */ - ARM_MODE_ABORT = 0x17 /* Abort Processing memory Faults Mode */ - ARM_MODE_UNDEF = 0x1B /* Undefined Instructions Mode */ - ARM_MODE_SYS = 0x1F /* System Running in Priviledged Operating Mode */ - ARM_MODE_MASK = 0x1F - - I_BIT = 0x80 /* disable IRQ when I bit is set */ - F_BIT = 0x40 /* disable IRQ when I bit is set */ - -/* - * Register Base Address - */ - PRCCU_BASE = 0xA0000000 - RCCU_CFR = 0x08 - RCCU_PLL1CR = 0x18 - PCU_MDIVR = 0x40 - PCU_PDIVR = 0x44 - PCU_BOOTCR = 0x50 - - - - - .section .vectors,"ax" - .code 32 - -/****************************************************************************/ -/* Vector table and reset entry */ -/****************************************************************************/ -_vectors: - ldr pc, ResetAddr /* Reset */ - ldr pc, UndefAddr /* Undefined instruction */ - ldr pc, SWIAddr /* Software interrupt */ - ldr pc, PAbortAddr /* Prefetch abort */ - ldr pc, DAbortAddr /* Data abort */ - ldr pc, ReservedAddr /* Reserved */ - ldr pc, IRQAddr /* IRQ interrupt */ - ldr pc, FIQAddr /* FIQ interrupt */ - - -ResetAddr: .word ResetHandler -UndefAddr: .word UndefHandler -SWIAddr: .word SWIHandler -PAbortAddr: .word PAbortHandler -DAbortAddr: .word DAbortHandler -ReservedAddr: .word 0 -IRQAddr: .word IRQHandler -FIQAddr: .word FIQHandler - - .ltorg - - - .section .init, "ax" - .code 32 - - .global ResetHandler - .global ExitFunction - .extern main -/****************************************************************************/ -/* Reset handler */ -/****************************************************************************/ -ResetHandler: -/* - * Wait for the oscillator is stable - */ - nop - nop - nop - nop - nop - nop - nop - nop - -/* - * Setup STR71X, for more information about the register - * take a look in the STR71x Microcontroller Reference Manual. - * - * Reference is made to: Rev. 6 March 2005 - * - * 1. Map internal RAM to address 0 - * In this case, we are running always in the RAM - * this make no sence. But if we are in flash, we - * can copy the interrupt vectors into the ram and - * switch to RAM mode. - * - * 2. Setup the PLL, the eval board HITEX STR7 is equipped - * with an external 16MHz oscillator. We want: - * - * RCLK: 32MHz = (CLK2 * 16) / 4 - * MCLK: 32Mhz - * PCLK1: 32MHz - * PCLK2: 32MHz - * - */ - - /* - * 1. Map RAM to the boot memory 0x00000000 - */ - ldr r0, =PRCCU_BASE - ldr r1, =0x01C2 - str r1, [r0, #PCU_BOOTCR] - - - /* - * 2. Setup PLL start - */ - - /* Set the prescaling factor for APB and APB1 group */ - ldr r0, =PRCCU_BASE - ldr r1, =0x0000 /* no prescaling PCLKx = RCLK */ - str r1, [r0, #PCU_PDIVR] - - /* Set the prescaling factor for the Main System Clock MCLK */ - ldr r0, =PRCCU_BASE - ldr r1, =0x0000 /* no prescaling MCLK = RCLK - str r1, [r0, #PCU_MDIVR] - - /* Configure the PLL1 ( * 16 , / 4 ) */ - ldr r0, =PRCCU_BASE - ldr r1, =0x0073 - str r1, [r0, #RCCU_PLL1CR] - - /* Check if the PLL is locked */ -pll_lock_loop: - ldr r1, [r0, #RCCU_CFR] - tst r1, #0x0002 - beq pll_lock_loop - - /* Select PLL1_Output as RCLK clock */ - ldr r0, =PRCCU_BASE - ldr r1, =0x8009 - str r1, [r0, #RCCU_CFR] - - /* - * Setup PLL end - */ - - - /* - * Setup a stack for each mode - */ - msr CPSR_c, #ARM_MODE_UNDEF | I_BIT | F_BIT /* Undefined Instruction Mode */ - ldr sp, =__stack_und_end - - msr CPSR_c, #ARM_MODE_ABORT | I_BIT | F_BIT /* Abort Mode */ - ldr sp, =__stack_abt_end - - msr CPSR_c, #ARM_MODE_FIQ | I_BIT | F_BIT /* FIQ Mode */ - ldr sp, =__stack_fiq_end - - msr CPSR_c, #ARM_MODE_IRQ | I_BIT | F_BIT /* IRQ Mode */ - ldr sp, =__stack_irq_end - - msr CPSR_c, #ARM_MODE_SVC | I_BIT | F_BIT /* Supervisor Mode */ - ldr sp, =__stack_svc_end - - - /* - * Clear .bss section - */ - ldr r1, =__bss_start - ldr r2, =__bss_end - ldr r3, =0 -bss_clear_loop: - cmp r1, r2 - strne r3, [r1], #+4 - bne bss_clear_loop - - - /* - * Jump to main - */ - mrs r0, cpsr - bic r0, r0, #I_BIT | F_BIT /* Enable FIQ and IRQ interrupt */ - msr cpsr, r0 - - mov r0, #0 /* No arguments */ - mov r1, #0 /* No arguments */ - ldr r2, =main - mov lr, pc - bx r2 /* And jump... */ - -ExitFunction: - nop - nop - nop - b ExitFunction - - -/****************************************************************************/ -/* Default interrupt handler */ -/****************************************************************************/ - -UndefHandler: - b UndefHandler - -SWIHandler: - b SWIHandler - -PAbortHandler: - b PAbortHandler - -DAbortHandler: - b DAbortHandler - -IRQHandler: - b IRQHandler - -FIQHandler: - b FIQHandler - - .weak ExitFunction - .weak UndefHandler, PAbortHandler, DAbortHandler - .weak IRQHandler, FIQHandler - - .ltorg -/*** EOF ***/ - - diff --git a/testing/examples/STR710JtagSpeed/src/main.c b/testing/examples/STR710JtagSpeed/src/main.c deleted file mode 100644 index 93a6a544b..000000000 --- a/testing/examples/STR710JtagSpeed/src/main.c +++ /dev/null @@ -1,90 +0,0 @@ -/**************************************************************************** -* Copyright (c) 2006 by Michael Fischer. All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* 1. Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the author nor the names of its contributors may -* be used to endorse or promote products derived from this software -* without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -* THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS -* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED -* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF -* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -* SUCH DAMAGE. -* -**************************************************************************** -* History: -* -* 30.03.06 mifi First Version for Insight tutorial -****************************************************************************/ -#define __MAIN_C__ - -/* - * I use the include only, to show - * how to setup a include dir in the makefile - */ -#include "typedefs.h" - -/*=========================================================================*/ -/* DEFINE: All Structures and Common Constants */ -/*=========================================================================*/ - -/*=========================================================================*/ -/* DEFINE: Prototypes */ -/*=========================================================================*/ - -/*=========================================================================*/ -/* DEFINE: Definition of all local Data */ -/*=========================================================================*/ -static const BYTE ConstArray1[128*1024] = {1}; -static const BYTE ConstArray2[128*1024] = {2}; -static const BYTE ConstArray3[128*1024] = {3}; - -/*=========================================================================*/ -/* DEFINE: Definition of all local Procedures */ -/*=========================================================================*/ - -/*=========================================================================*/ -/* DEFINE: All code exported */ -/*=========================================================================*/ -/***************************************************************************/ -/* main */ -/***************************************************************************/ -int main (void) -{ - DWORD a = 1; - DWORD b = 2; - DWORD c = 0; - - while (1) - { - a++; - b++; - c = a + b; - } - - /* - * This return here make no sense. - * But to prevent the compiler warning: - * "return type of 'main' is not 'int' - * we use an int as return :-) - */ - return(0); -} - -/*** EOF ***/ diff --git a/testing/examples/STR710JtagSpeed/test.elf b/testing/examples/STR710JtagSpeed/test.elf deleted file mode 100644 index cb6da2605c9fe6b6354d096dc49c5a05589d910e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 430217 zcmeI#QH)&ISpeX3XLiRM+ey}OD27DpMwsG2wYyGT*9sNg^?IEwiDP$n-Kxm2%W6)7w6fYhkVf9~wv znJg{hffuCjB=?^4pYz{y&i(G)nelJUzj(GNie}m=wR9{M(Vj`Ebt3A&dZUpVQJ+W? z(SIzBr-#e&bUQjDCm(l;$k^XV`*P3id{PJyAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!CviFM%WPzy08UI%ZO8Jzk{NkvN`=VE&gA3!gALMo#zkC18P&@Z+M&FU>8yo+|gIYRt|AX!A{ki|^aot$-|Lglt-GBX^ zw;%j-)VHJl`>0=w`X8dc74<(x-HW<69>>Jn57PAA`?d7hcSokb^mxqmlPNv=?!9#H zetQ4uyw`FM7b5S`@7{g)vF)i3?f?7R+yC~1A94Imk+)=`x~u0 zMgLe1lY{S^d#{K+r0F*w)S@1VI`3($tiSo7nEuLpd2D35-!8`|zFEfg=`Vjb=lw_Q zA(m4J5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAW#a_I1nH}fB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkKcN1#rE009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RlS$vyVoj*>1MhQ!yINuf2fiJu{X6KRz{8-#X`yJ`%Gn#uByk$$b7{+nJnN@5H9AH`hCpt9e(wS8ue}+Lt#cuf}CjMr+GOZ01|B znHOGo>B^O_)M_znubefHkCb#8>?%Vdfl6ymnXZQJazI?uf5q@?_9amzSX>b<63+3($ezcr;bnmVy}5+=|;P~ zmY#d*;>7II#50q}Po?7aomj1w9xK<)BXbicCZCynrlg(PxrzVF)$_f_nyufB6>G)V z>eXg9)lYw6c|O&C_8a}ao1M+|E1mY*L^)Wi?c2P%(d|v_cCUAOsWvitZKHE#qTk+E zwm+0mKlAzXi)T`8@^8yq%XgBB`QljIZncFNNI4#DrsC{(^4f3pMq87kEBPprCAjz(R+#c8DKYRyC|j@IL`^{PA>jas@D=YC!`f4&-wdOONa z*qVuJ^O1AXPB|EL&M8vy+9L-aPUAcM)jVe&$r=6Gi}cHRkvx4ZeX-vk?H@1WyoI~5 zu?JC?FG18PJvTS^?8LEn-=E%j-P7detJizYR@A+2zrI?vdhJ`iG}+qROp~*V=O&xI zUU$89GycxfXBnjc9#&RkmQc1m}OohUl0C-_vf@&1n6q=7KjH?ZUcJ3LUG=nYFc_`+?$hdb*UP&Yq|{SkpPY9=yj} z+u0@C_RH3G{wy2#Z*4yv@!%tIYdgR1`NO7PwzlV^F?g<9+shFT-iNL2=AL*X;@ffb z%hvYIXw2+HDQ#{4X1{&6Uu|vY_pN$I^LYL$J<=bH^Vaqs#Cc{Y{^Mw$8H)cr+82i6 zzwEcm=at`@zupsnJK~A_`B9c4y%Y7(q4-}SJ~kA;7xBl3;(w2LdMN(Sh))c~qw!*$ z8j2r|_|rr2k3~E&6d#E=j@|v_{m%@I|5S{BeJDO2@pp#eJm1HMuAhmxDkI_dT*Udy zJO9rjjcCX3 zl9(^0i5U259^2pldm4{D{a(aR4vqg&#POqXH~%kketnRCFXHO&F<<}fJf4pzdA)y% z_RNmYcnrL^C;xjnw=tOSgB<50O1}O;Ev1Q}^?xGb!Fomd=!fE3`nia!@A3F~o~9$N zJ_ho9pV^atHjfXjcQN9lL+kx&#E%cf*K_{JV836?@#r8<@h!e`?);hgm5WRBi-YLw z!el>X^rCwhDwKBE6*6cM?+`#bEB}aAn z%1YjHp0>L7W@oL8XHPE=U)9&CE^C*+^!gXa?z+AHFUENK!`H0z*N^8u+#B1erYWCC T6;vBo@Afxe#m!c)+|YjkX8tD2 diff --git a/testing/examples/STR710JtagSpeed/test.hex b/testing/examples/STR710JtagSpeed/test.hex deleted file mode 100644 index b8ace5bc3..000000000 --- a/testing/examples/STR710JtagSpeed/test.hex +++ /dev/null @@ -1,24611 +0,0 @@ -:02000004620098 -:1000000018F09FE518F09FE518F09FE518F09FE5C0 -:1000100018F09FE518F09FE518F09FE518F09FE5B0 -:100020004000006214010062180100621C010062BD -:10003000200100620000000024010062280100622B -:100040000000A0E10000A0E10000A0E10000A0E1AC -:100050000000A0E10000A0E10000A0E10000A0E19C -:100060000A02A0E3C0109FE5501080E50A02A0E359 -:100070000010A0E3441080E50A02A0E30010A0E312 -:100080000A02A0E37310A0E3181080E5081090E5C1 -:10009000020011E3FCFFFF0A0A02A0E38C109FE5B7 -:1000A000081080E5DBF021E384D09FE5D7F021E361 -:1000B00080D09FE5D1F021E37CD09FE5D2F021E311 -:1000C00078D09FE5D3F021E374D09FE574109FE5CD -:1000D00074209FE50030A0E3020051E10430811458 -:1000E000FCFFFF1A00000FE1C000C0E300F029E1AF -:1000F0000000A0E30010A0E350209FE50FE0A0E186 -:1001000012FF2FE10000A0E10000A0E10000A0E14B -:10011000FBFFFFEAFEFFFFEAFEFFFFEAFEFFFFEA4A -:10012000FEFFFFEAFEFFFFEAFEFFFFEAC20100005A -:1001300009800000000606620005066200030662F0 -:1001400000040662000A06629C0106629C010662C7 -:10015000540100620CD04DE20130A0E300308DE587 -:100160000230A0E304308DE50030A0E308308DE5D7 -:1001700000309DE5013083E200308DE504309DE5DF -:10018000013083E204308DE500209DE504309DE5DB -:10019000033082E008308DE5F4FFFFEA0100000043 -:1001A000000000000000000000000000000000004F -:1001B000000000000000000000000000000000003F -:1001C000000000000000000000000000000000002F -:1001D000000000000000000000000000000000001F -:1001E000000000000000000000000000000000000F -:1001F00000000000000000000000000000000000FF -:1002000000000000000000000000000000000000EE -:1002100000000000000000000000000000000000DE -:1002200000000000000000000000000000000000CE -:1002300000000000000000000000000000000000BE -:1002400000000000000000000000000000000000AE -:10025000000000000000000000000000000000009E -:10026000000000000000000000000000000000008E -:10027000000000000000000000000000000000007E -:10028000000000000000000000000000000000006E -:10029000000000000000000000000000000000005E -:1002A000000000000000000000000000000000004E -:1002B000000000000000000000000000000000003E -:1002C000000000000000000000000000000000002E -:1002D000000000000000000000000000000000001E -:1002E000000000000000000000000000000000000E -:1002F00000000000000000000000000000000000FE -:1003000000000000000000000000000000000000ED -:1003100000000000000000000000000000000000DD -:1003200000000000000000000000000000000000CD -:1003300000000000000000000000000000000000BD -:1003400000000000000000000000000000000000AD -:10035000000000000000000000000000000000009D -:10036000000000000000000000000000000000008D -:10037000000000000000000000000000000000007D -:10038000000000000000000000000000000000006D -:10039000000000000000000000000000000000005D -:1003A000000000000000000000000000000000004D -:1003B000000000000000000000000000000000003D -:1003C000000000000000000000000000000000002D -:1003D000000000000000000000000000000000001D -:1003E000000000000000000000000000000000000D -:1003F00000000000000000000000000000000000FD -:1004000000000000000000000000000000000000EC -:1004100000000000000000000000000000000000DC -:1004200000000000000000000000000000000000CC -:1004300000000000000000000000000000000000BC -:1004400000000000000000000000000000000000AC -:10045000000000000000000000000000000000009C -:10046000000000000000000000000000000000008C -:10047000000000000000000000000000000000007C -:10048000000000000000000000000000000000006C -:10049000000000000000000000000000000000005C -:1004A000000000000000000000000000000000004C -:1004B000000000000000000000000000000000003C -:1004C000000000000000000000000000000000002C -:1004D000000000000000000000000000000000001C -:1004E000000000000000000000000000000000000C -:1004F00000000000000000000000000000000000FC -:1005000000000000000000000000000000000000EB -:1005100000000000000000000000000000000000DB -:1005200000000000000000000000000000000000CB -:1005300000000000000000000000000000000000BB -:1005400000000000000000000000000000000000AB -:10055000000000000000000000000000000000009B -:10056000000000000000000000000000000000008B -:10057000000000000000000000000000000000007B -:10058000000000000000000000000000000000006B -:10059000000000000000000000000000000000005B -:1005A000000000000000000000000000000000004B -:1005B000000000000000000000000000000000003B -:1005C000000000000000000000000000000000002B -:1005D000000000000000000000000000000000001B -:1005E000000000000000000000000000000000000B -:1005F00000000000000000000000000000000000FB -:1006000000000000000000000000000000000000EA -:1006100000000000000000000000000000000000DA -:1006200000000000000000000000000000000000CA -:1006300000000000000000000000000000000000BA -:1006400000000000000000000000000000000000AA -:10065000000000000000000000000000000000009A -:10066000000000000000000000000000000000008A -:10067000000000000000000000000000000000007A -:10068000000000000000000000000000000000006A -:10069000000000000000000000000000000000005A -:1006A000000000000000000000000000000000004A -:1006B000000000000000000000000000000000003A -:1006C000000000000000000000000000000000002A -:1006D000000000000000000000000000000000001A -:1006E000000000000000000000000000000000000A -:1006F00000000000000000000000000000000000FA -:1007000000000000000000000000000000000000E9 -:1007100000000000000000000000000000000000D9 -:1007200000000000000000000000000000000000C9 -:1007300000000000000000000000000000000000B9 -:1007400000000000000000000000000000000000A9 -:100750000000000000000000000000000000000099 -:100760000000000000000000000000000000000089 -:100770000000000000000000000000000000000079 -:100780000000000000000000000000000000000069 -:100790000000000000000000000000000000000059 -:1007A0000000000000000000000000000000000049 -:1007B0000000000000000000000000000000000039 -:1007C0000000000000000000000000000000000029 -:1007D0000000000000000000000000000000000019 -:1007E0000000000000000000000000000000000009 -:1007F00000000000000000000000000000000000F9 -:1008000000000000000000000000000000000000E8 -:1008100000000000000000000000000000000000D8 -:1008200000000000000000000000000000000000C8 -:1008300000000000000000000000000000000000B8 -:1008400000000000000000000000000000000000A8 -:100850000000000000000000000000000000000098 -:100860000000000000000000000000000000000088 -:100870000000000000000000000000000000000078 -:100880000000000000000000000000000000000068 -:100890000000000000000000000000000000000058 -:1008A0000000000000000000000000000000000048 -:1008B0000000000000000000000000000000000038 -:1008C0000000000000000000000000000000000028 -:1008D0000000000000000000000000000000000018 -:1008E0000000000000000000000000000000000008 -:1008F00000000000000000000000000000000000F8 -:1009000000000000000000000000000000000000E7 -:1009100000000000000000000000000000000000D7 -:1009200000000000000000000000000000000000C7 -:1009300000000000000000000000000000000000B7 -:1009400000000000000000000000000000000000A7 -:100950000000000000000000000000000000000097 -:100960000000000000000000000000000000000087 -:100970000000000000000000000000000000000077 -:100980000000000000000000000000000000000067 -:100990000000000000000000000000000000000057 -:1009A0000000000000000000000000000000000047 -:1009B0000000000000000000000000000000000037 -:1009C0000000000000000000000000000000000027 -:1009D0000000000000000000000000000000000017 -:1009E0000000000000000000000000000000000007 -:1009F00000000000000000000000000000000000F7 -:100A000000000000000000000000000000000000E6 -:100A100000000000000000000000000000000000D6 -:100A200000000000000000000000000000000000C6 -:100A300000000000000000000000000000000000B6 -:100A400000000000000000000000000000000000A6 -:100A50000000000000000000000000000000000096 -:100A60000000000000000000000000000000000086 -:100A70000000000000000000000000000000000076 -:100A80000000000000000000000000000000000066 -:100A90000000000000000000000000000000000056 -:100AA0000000000000000000000000000000000046 -:100AB0000000000000000000000000000000000036 -:100AC0000000000000000000000000000000000026 -:100AD0000000000000000000000000000000000016 -:100AE0000000000000000000000000000000000006 -:100AF00000000000000000000000000000000000F6 -:100B000000000000000000000000000000000000E5 -:100B100000000000000000000000000000000000D5 -:100B200000000000000000000000000000000000C5 -:100B300000000000000000000000000000000000B5 -:100B400000000000000000000000000000000000A5 -:100B50000000000000000000000000000000000095 -:100B60000000000000000000000000000000000085 -:100B70000000000000000000000000000000000075 -:100B80000000000000000000000000000000000065 -:100B90000000000000000000000000000000000055 -:100BA0000000000000000000000000000000000045 -:100BB0000000000000000000000000000000000035 -:100BC0000000000000000000000000000000000025 -:100BD0000000000000000000000000000000000015 -:100BE0000000000000000000000000000000000005 -:100BF00000000000000000000000000000000000F5 -:100C000000000000000000000000000000000000E4 -:100C100000000000000000000000000000000000D4 -:100C200000000000000000000000000000000000C4 -:100C300000000000000000000000000000000000B4 -:100C400000000000000000000000000000000000A4 -:100C50000000000000000000000000000000000094 -:100C60000000000000000000000000000000000084 -:100C70000000000000000000000000000000000074 -:100C80000000000000000000000000000000000064 -:100C90000000000000000000000000000000000054 -:100CA0000000000000000000000000000000000044 -:100CB0000000000000000000000000000000000034 -:100CC0000000000000000000000000000000000024 -:100CD0000000000000000000000000000000000014 -:100CE0000000000000000000000000000000000004 -:100CF00000000000000000000000000000000000F4 -:100D000000000000000000000000000000000000E3 -:100D100000000000000000000000000000000000D3 -:100D200000000000000000000000000000000000C3 -:100D300000000000000000000000000000000000B3 -:100D400000000000000000000000000000000000A3 -:100D50000000000000000000000000000000000093 -:100D60000000000000000000000000000000000083 -:100D70000000000000000000000000000000000073 -:100D80000000000000000000000000000000000063 -:100D90000000000000000000000000000000000053 -:100DA0000000000000000000000000000000000043 -:100DB0000000000000000000000000000000000033 -:100DC0000000000000000000000000000000000023 -:100DD0000000000000000000000000000000000013 -:100DE0000000000000000000000000000000000003 -:100DF00000000000000000000000000000000000F3 -:100E000000000000000000000000000000000000E2 -:100E100000000000000000000000000000000000D2 -:100E200000000000000000000000000000000000C2 -:100E300000000000000000000000000000000000B2 -:100E400000000000000000000000000000000000A2 -:100E50000000000000000000000000000000000092 -:100E60000000000000000000000000000000000082 -:100E70000000000000000000000000000000000072 -:100E80000000000000000000000000000000000062 -:100E90000000000000000000000000000000000052 -:100EA0000000000000000000000000000000000042 -:100EB0000000000000000000000000000000000032 -:100EC0000000000000000000000000000000000022 -:100ED0000000000000000000000000000000000012 -:100EE0000000000000000000000000000000000002 -:100EF00000000000000000000000000000000000F2 -:100F000000000000000000000000000000000000E1 -:100F100000000000000000000000000000000000D1 -:100F200000000000000000000000000000000000C1 -:100F300000000000000000000000000000000000B1 -:100F400000000000000000000000000000000000A1 -:100F50000000000000000000000000000000000091 -:100F60000000000000000000000000000000000081 -:100F70000000000000000000000000000000000071 -:100F80000000000000000000000000000000000061 -:100F90000000000000000000000000000000000051 -:100FA0000000000000000000000000000000000041 -:100FB0000000000000000000000000000000000031 -:100FC0000000000000000000000000000000000021 -:100FD0000000000000000000000000000000000011 -:100FE0000000000000000000000000000000000001 -:100FF00000000000000000000000000000000000F1 -:1010000000000000000000000000000000000000E0 -:1010100000000000000000000000000000000000D0 -:1010200000000000000000000000000000000000C0 -:1010300000000000000000000000000000000000B0 -:1010400000000000000000000000000000000000A0 -:101050000000000000000000000000000000000090 -:101060000000000000000000000000000000000080 -:101070000000000000000000000000000000000070 -:101080000000000000000000000000000000000060 -:101090000000000000000000000000000000000050 -:1010A0000000000000000000000000000000000040 -:1010B0000000000000000000000000000000000030 -:1010C0000000000000000000000000000000000020 -:1010D0000000000000000000000000000000000010 -:1010E0000000000000000000000000000000000000 -:1010F00000000000000000000000000000000000F0 -:1011000000000000000000000000000000000000DF -:1011100000000000000000000000000000000000CF -:1011200000000000000000000000000000000000BF -:1011300000000000000000000000000000000000AF -:10114000000000000000000000000000000000009F -:10115000000000000000000000000000000000008F -:10116000000000000000000000000000000000007F -:10117000000000000000000000000000000000006F -:10118000000000000000000000000000000000005F -:10119000000000000000000000000000000000004F -:1011A000000000000000000000000000000000003F -:1011B000000000000000000000000000000000002F -:1011C000000000000000000000000000000000001F -:1011D000000000000000000000000000000000000F -:1011E00000000000000000000000000000000000FF -:1011F00000000000000000000000000000000000EF -:1012000000000000000000000000000000000000DE -:1012100000000000000000000000000000000000CE -:1012200000000000000000000000000000000000BE -:1012300000000000000000000000000000000000AE -:10124000000000000000000000000000000000009E -:10125000000000000000000000000000000000008E -:10126000000000000000000000000000000000007E -:10127000000000000000000000000000000000006E -:10128000000000000000000000000000000000005E -:10129000000000000000000000000000000000004E -:1012A000000000000000000000000000000000003E -:1012B000000000000000000000000000000000002E -:1012C000000000000000000000000000000000001E -:1012D000000000000000000000000000000000000E -:1012E00000000000000000000000000000000000FE -:1012F00000000000000000000000000000000000EE -:1013000000000000000000000000000000000000DD -:1013100000000000000000000000000000000000CD -:1013200000000000000000000000000000000000BD -:1013300000000000000000000000000000000000AD -:10134000000000000000000000000000000000009D -:10135000000000000000000000000000000000008D -:10136000000000000000000000000000000000007D -:10137000000000000000000000000000000000006D -:10138000000000000000000000000000000000005D -:10139000000000000000000000000000000000004D -:1013A000000000000000000000000000000000003D -:1013B000000000000000000000000000000000002D -:1013C000000000000000000000000000000000001D -:1013D000000000000000000000000000000000000D -:1013E00000000000000000000000000000000000FD -:1013F00000000000000000000000000000000000ED -:1014000000000000000000000000000000000000DC -:1014100000000000000000000000000000000000CC -:1014200000000000000000000000000000000000BC -:1014300000000000000000000000000000000000AC -:10144000000000000000000000000000000000009C -:10145000000000000000000000000000000000008C -:10146000000000000000000000000000000000007C -:10147000000000000000000000000000000000006C -:10148000000000000000000000000000000000005C -:10149000000000000000000000000000000000004C -:1014A000000000000000000000000000000000003C -:1014B000000000000000000000000000000000002C -:1014C000000000000000000000000000000000001C -:1014D000000000000000000000000000000000000C -:1014E00000000000000000000000000000000000FC -:1014F00000000000000000000000000000000000EC -:1015000000000000000000000000000000000000DB -:1015100000000000000000000000000000000000CB -:1015200000000000000000000000000000000000BB -:1015300000000000000000000000000000000000AB -:10154000000000000000000000000000000000009B -:10155000000000000000000000000000000000008B -:10156000000000000000000000000000000000007B -:10157000000000000000000000000000000000006B -:10158000000000000000000000000000000000005B -:10159000000000000000000000000000000000004B -:1015A000000000000000000000000000000000003B -:1015B000000000000000000000000000000000002B -:1015C000000000000000000000000000000000001B -:1015D000000000000000000000000000000000000B -:1015E00000000000000000000000000000000000FB -:1015F00000000000000000000000000000000000EB -:1016000000000000000000000000000000000000DA -:1016100000000000000000000000000000000000CA -:1016200000000000000000000000000000000000BA -:1016300000000000000000000000000000000000AA -:10164000000000000000000000000000000000009A -:10165000000000000000000000000000000000008A -:10166000000000000000000000000000000000007A -:10167000000000000000000000000000000000006A -:10168000000000000000000000000000000000005A -:10169000000000000000000000000000000000004A -:1016A000000000000000000000000000000000003A -:1016B000000000000000000000000000000000002A -:1016C000000000000000000000000000000000001A -:1016D000000000000000000000000000000000000A -:1016E00000000000000000000000000000000000FA -:1016F00000000000000000000000000000000000EA -:1017000000000000000000000000000000000000D9 -:1017100000000000000000000000000000000000C9 -:1017200000000000000000000000000000000000B9 -:1017300000000000000000000000000000000000A9 -:101740000000000000000000000000000000000099 -:101750000000000000000000000000000000000089 -:101760000000000000000000000000000000000079 -:101770000000000000000000000000000000000069 -:101780000000000000000000000000000000000059 -:101790000000000000000000000000000000000049 -:1017A0000000000000000000000000000000000039 -:1017B0000000000000000000000000000000000029 -:1017C0000000000000000000000000000000000019 -:1017D0000000000000000000000000000000000009 -:1017E00000000000000000000000000000000000F9 -:1017F00000000000000000000000000000000000E9 -:1018000000000000000000000000000000000000D8 -:1018100000000000000000000000000000000000C8 -:1018200000000000000000000000000000000000B8 -:1018300000000000000000000000000000000000A8 -:101840000000000000000000000000000000000098 -:101850000000000000000000000000000000000088 -:101860000000000000000000000000000000000078 -:101870000000000000000000000000000000000068 -:101880000000000000000000000000000000000058 -:101890000000000000000000000000000000000048 -:1018A0000000000000000000000000000000000038 -:1018B0000000000000000000000000000000000028 -:1018C0000000000000000000000000000000000018 -:1018D0000000000000000000000000000000000008 -:1018E00000000000000000000000000000000000F8 -:1018F00000000000000000000000000000000000E8 -:1019000000000000000000000000000000000000D7 -:1019100000000000000000000000000000000000C7 -:1019200000000000000000000000000000000000B7 -:1019300000000000000000000000000000000000A7 -:101940000000000000000000000000000000000097 -:101950000000000000000000000000000000000087 -:101960000000000000000000000000000000000077 -:101970000000000000000000000000000000000067 -:101980000000000000000000000000000000000057 -:101990000000000000000000000000000000000047 -:1019A0000000000000000000000000000000000037 -:1019B0000000000000000000000000000000000027 -:1019C0000000000000000000000000000000000017 -:1019D0000000000000000000000000000000000007 -:1019E00000000000000000000000000000000000F7 -:1019F00000000000000000000000000000000000E7 -:101A000000000000000000000000000000000000D6 -:101A100000000000000000000000000000000000C6 -:101A200000000000000000000000000000000000B6 -:101A300000000000000000000000000000000000A6 -:101A40000000000000000000000000000000000096 -:101A50000000000000000000000000000000000086 -:101A60000000000000000000000000000000000076 -:101A70000000000000000000000000000000000066 -:101A80000000000000000000000000000000000056 -:101A90000000000000000000000000000000000046 -:101AA0000000000000000000000000000000000036 -:101AB0000000000000000000000000000000000026 -:101AC0000000000000000000000000000000000016 -:101AD0000000000000000000000000000000000006 -:101AE00000000000000000000000000000000000F6 -:101AF00000000000000000000000000000000000E6 -:101B000000000000000000000000000000000000D5 -:101B100000000000000000000000000000000000C5 -:101B200000000000000000000000000000000000B5 -:101B300000000000000000000000000000000000A5 -:101B40000000000000000000000000000000000095 -:101B50000000000000000000000000000000000085 -:101B60000000000000000000000000000000000075 -:101B70000000000000000000000000000000000065 -:101B80000000000000000000000000000000000055 -:101B90000000000000000000000000000000000045 -:101BA0000000000000000000000000000000000035 -:101BB0000000000000000000000000000000000025 -:101BC0000000000000000000000000000000000015 -:101BD0000000000000000000000000000000000005 -:101BE00000000000000000000000000000000000F5 -:101BF00000000000000000000000000000000000E5 -:101C000000000000000000000000000000000000D4 -:101C100000000000000000000000000000000000C4 -:101C200000000000000000000000000000000000B4 -:101C300000000000000000000000000000000000A4 -:101C40000000000000000000000000000000000094 -:101C50000000000000000000000000000000000084 -:101C60000000000000000000000000000000000074 -:101C70000000000000000000000000000000000064 -:101C80000000000000000000000000000000000054 -:101C90000000000000000000000000000000000044 -:101CA0000000000000000000000000000000000034 -:101CB0000000000000000000000000000000000024 -:101CC0000000000000000000000000000000000014 -:101CD0000000000000000000000000000000000004 -:101CE00000000000000000000000000000000000F4 -:101CF00000000000000000000000000000000000E4 -:101D000000000000000000000000000000000000D3 -:101D100000000000000000000000000000000000C3 -:101D200000000000000000000000000000000000B3 -:101D300000000000000000000000000000000000A3 -:101D40000000000000000000000000000000000093 -:101D50000000000000000000000000000000000083 -:101D60000000000000000000000000000000000073 -:101D70000000000000000000000000000000000063 -:101D80000000000000000000000000000000000053 -:101D90000000000000000000000000000000000043 -:101DA0000000000000000000000000000000000033 -:101DB0000000000000000000000000000000000023 -:101DC0000000000000000000000000000000000013 -:101DD0000000000000000000000000000000000003 -:101DE00000000000000000000000000000000000F3 -:101DF00000000000000000000000000000000000E3 -:101E000000000000000000000000000000000000D2 -:101E100000000000000000000000000000000000C2 -:101E200000000000000000000000000000000000B2 -:101E300000000000000000000000000000000000A2 -:101E40000000000000000000000000000000000092 -:101E50000000000000000000000000000000000082 -:101E60000000000000000000000000000000000072 -:101E70000000000000000000000000000000000062 -:101E80000000000000000000000000000000000052 -:101E90000000000000000000000000000000000042 -:101EA0000000000000000000000000000000000032 -:101EB0000000000000000000000000000000000022 -:101EC0000000000000000000000000000000000012 -:101ED0000000000000000000000000000000000002 -:101EE00000000000000000000000000000000000F2 -:101EF00000000000000000000000000000000000E2 -:101F000000000000000000000000000000000000D1 -:101F100000000000000000000000000000000000C1 -:101F200000000000000000000000000000000000B1 -:101F300000000000000000000000000000000000A1 -:101F40000000000000000000000000000000000091 -:101F50000000000000000000000000000000000081 -:101F60000000000000000000000000000000000071 -:101F70000000000000000000000000000000000061 -:101F80000000000000000000000000000000000051 -:101F90000000000000000000000000000000000041 -:101FA0000000000000000000000000000000000031 -:101FB0000000000000000000000000000000000021 -:101FC0000000000000000000000000000000000011 -:101FD0000000000000000000000000000000000001 -:101FE00000000000000000000000000000000000F1 -:101FF00000000000000000000000000000000000E1 -:1020000000000000000000000000000000000000D0 -:1020100000000000000000000000000000000000C0 -:1020200000000000000000000000000000000000B0 -:1020300000000000000000000000000000000000A0 -:102040000000000000000000000000000000000090 -:102050000000000000000000000000000000000080 -:102060000000000000000000000000000000000070 -:102070000000000000000000000000000000000060 -:102080000000000000000000000000000000000050 -:102090000000000000000000000000000000000040 -:1020A0000000000000000000000000000000000030 -:1020B0000000000000000000000000000000000020 -:1020C0000000000000000000000000000000000010 -:1020D0000000000000000000000000000000000000 -:1020E00000000000000000000000000000000000F0 -:1020F00000000000000000000000000000000000E0 -:1021000000000000000000000000000000000000CF -:1021100000000000000000000000000000000000BF -:1021200000000000000000000000000000000000AF -:10213000000000000000000000000000000000009F -:10214000000000000000000000000000000000008F -:10215000000000000000000000000000000000007F -:10216000000000000000000000000000000000006F -:10217000000000000000000000000000000000005F -:10218000000000000000000000000000000000004F -:10219000000000000000000000000000000000003F -:1021A000000000000000000000000000000000002F -:1021B000000000000000000000000000000000001F -:1021C000000000000000000000000000000000000F -:1021D00000000000000000000000000000000000FF -:1021E00000000000000000000000000000000000EF -:1021F00000000000000000000000000000000000DF -:1022000000000000000000000000000000000000CE -:1022100000000000000000000000000000000000BE -:1022200000000000000000000000000000000000AE -:10223000000000000000000000000000000000009E -:10224000000000000000000000000000000000008E -:10225000000000000000000000000000000000007E -:10226000000000000000000000000000000000006E -:10227000000000000000000000000000000000005E -:10228000000000000000000000000000000000004E -:10229000000000000000000000000000000000003E -:1022A000000000000000000000000000000000002E -:1022B000000000000000000000000000000000001E -:1022C000000000000000000000000000000000000E -:1022D00000000000000000000000000000000000FE -:1022E00000000000000000000000000000000000EE -:1022F00000000000000000000000000000000000DE -:1023000000000000000000000000000000000000CD -:1023100000000000000000000000000000000000BD -:1023200000000000000000000000000000000000AD -:10233000000000000000000000000000000000009D -:10234000000000000000000000000000000000008D -:10235000000000000000000000000000000000007D -:10236000000000000000000000000000000000006D -:10237000000000000000000000000000000000005D -:10238000000000000000000000000000000000004D -:10239000000000000000000000000000000000003D -:1023A000000000000000000000000000000000002D -:1023B000000000000000000000000000000000001D -:1023C000000000000000000000000000000000000D -:1023D00000000000000000000000000000000000FD -:1023E00000000000000000000000000000000000ED -:1023F00000000000000000000000000000000000DD -:1024000000000000000000000000000000000000CC -:1024100000000000000000000000000000000000BC -:1024200000000000000000000000000000000000AC -:10243000000000000000000000000000000000009C -:10244000000000000000000000000000000000008C -:10245000000000000000000000000000000000007C -:10246000000000000000000000000000000000006C -:10247000000000000000000000000000000000005C -:10248000000000000000000000000000000000004C -:10249000000000000000000000000000000000003C -:1024A000000000000000000000000000000000002C -:1024B000000000000000000000000000000000001C -:1024C000000000000000000000000000000000000C -:1024D00000000000000000000000000000000000FC -:1024E00000000000000000000000000000000000EC -:1024F00000000000000000000000000000000000DC -:1025000000000000000000000000000000000000CB -:1025100000000000000000000000000000000000BB -:1025200000000000000000000000000000000000AB -:10253000000000000000000000000000000000009B -:10254000000000000000000000000000000000008B -:10255000000000000000000000000000000000007B -:10256000000000000000000000000000000000006B -:10257000000000000000000000000000000000005B -:10258000000000000000000000000000000000004B -:10259000000000000000000000000000000000003B -:1025A000000000000000000000000000000000002B -:1025B000000000000000000000000000000000001B -:1025C000000000000000000000000000000000000B -:1025D00000000000000000000000000000000000FB -:1025E00000000000000000000000000000000000EB -:1025F00000000000000000000000000000000000DB -:1026000000000000000000000000000000000000CA -:1026100000000000000000000000000000000000BA -:1026200000000000000000000000000000000000AA -:10263000000000000000000000000000000000009A -:10264000000000000000000000000000000000008A -:10265000000000000000000000000000000000007A -:10266000000000000000000000000000000000006A -:10267000000000000000000000000000000000005A -:10268000000000000000000000000000000000004A -:10269000000000000000000000000000000000003A -:1026A000000000000000000000000000000000002A -:1026B000000000000000000000000000000000001A -:1026C000000000000000000000000000000000000A -:1026D00000000000000000000000000000000000FA -:1026E00000000000000000000000000000000000EA -:1026F00000000000000000000000000000000000DA -:1027000000000000000000000000000000000000C9 -:1027100000000000000000000000000000000000B9 -:1027200000000000000000000000000000000000A9 -:102730000000000000000000000000000000000099 -:102740000000000000000000000000000000000089 -:102750000000000000000000000000000000000079 -:102760000000000000000000000000000000000069 -:102770000000000000000000000000000000000059 -:102780000000000000000000000000000000000049 -:102790000000000000000000000000000000000039 -:1027A0000000000000000000000000000000000029 -:1027B0000000000000000000000000000000000019 -:1027C0000000000000000000000000000000000009 -:1027D00000000000000000000000000000000000F9 -:1027E00000000000000000000000000000000000E9 -:1027F00000000000000000000000000000000000D9 -:1028000000000000000000000000000000000000C8 -:1028100000000000000000000000000000000000B8 -:1028200000000000000000000000000000000000A8 -:102830000000000000000000000000000000000098 -:102840000000000000000000000000000000000088 -:102850000000000000000000000000000000000078 -:102860000000000000000000000000000000000068 -:102870000000000000000000000000000000000058 -:102880000000000000000000000000000000000048 -:102890000000000000000000000000000000000038 -:1028A0000000000000000000000000000000000028 -:1028B0000000000000000000000000000000000018 -:1028C0000000000000000000000000000000000008 -:1028D00000000000000000000000000000000000F8 -:1028E00000000000000000000000000000000000E8 -:1028F00000000000000000000000000000000000D8 -:1029000000000000000000000000000000000000C7 -:1029100000000000000000000000000000000000B7 -:1029200000000000000000000000000000000000A7 -:102930000000000000000000000000000000000097 -:102940000000000000000000000000000000000087 -:102950000000000000000000000000000000000077 -:102960000000000000000000000000000000000067 -:102970000000000000000000000000000000000057 -:102980000000000000000000000000000000000047 -:102990000000000000000000000000000000000037 -:1029A0000000000000000000000000000000000027 -:1029B0000000000000000000000000000000000017 -:1029C0000000000000000000000000000000000007 -:1029D00000000000000000000000000000000000F7 -:1029E00000000000000000000000000000000000E7 -:1029F00000000000000000000000000000000000D7 -:102A000000000000000000000000000000000000C6 -:102A100000000000000000000000000000000000B6 -:102A200000000000000000000000000000000000A6 -:102A30000000000000000000000000000000000096 -:102A40000000000000000000000000000000000086 -:102A50000000000000000000000000000000000076 -:102A60000000000000000000000000000000000066 -:102A70000000000000000000000000000000000056 -:102A80000000000000000000000000000000000046 -:102A90000000000000000000000000000000000036 -:102AA0000000000000000000000000000000000026 -:102AB0000000000000000000000000000000000016 -:102AC0000000000000000000000000000000000006 -:102AD00000000000000000000000000000000000F6 -:102AE00000000000000000000000000000000000E6 -:102AF00000000000000000000000000000000000D6 -:102B000000000000000000000000000000000000C5 -:102B100000000000000000000000000000000000B5 -:102B200000000000000000000000000000000000A5 -:102B30000000000000000000000000000000000095 -:102B40000000000000000000000000000000000085 -:102B50000000000000000000000000000000000075 -:102B60000000000000000000000000000000000065 -:102B70000000000000000000000000000000000055 -:102B80000000000000000000000000000000000045 -:102B90000000000000000000000000000000000035 -:102BA0000000000000000000000000000000000025 -:102BB0000000000000000000000000000000000015 -:102BC0000000000000000000000000000000000005 -:102BD00000000000000000000000000000000000F5 -:102BE00000000000000000000000000000000000E5 -:102BF00000000000000000000000000000000000D5 -:102C000000000000000000000000000000000000C4 -:102C100000000000000000000000000000000000B4 -:102C200000000000000000000000000000000000A4 -:102C30000000000000000000000000000000000094 -:102C40000000000000000000000000000000000084 -:102C50000000000000000000000000000000000074 -:102C60000000000000000000000000000000000064 -:102C70000000000000000000000000000000000054 -:102C80000000000000000000000000000000000044 -:102C90000000000000000000000000000000000034 -:102CA0000000000000000000000000000000000024 -:102CB0000000000000000000000000000000000014 -:102CC0000000000000000000000000000000000004 -:102CD00000000000000000000000000000000000F4 -:102CE00000000000000000000000000000000000E4 -:102CF00000000000000000000000000000000000D4 -:102D000000000000000000000000000000000000C3 -:102D100000000000000000000000000000000000B3 -:102D200000000000000000000000000000000000A3 -:102D30000000000000000000000000000000000093 -:102D40000000000000000000000000000000000083 -:102D50000000000000000000000000000000000073 -:102D60000000000000000000000000000000000063 -:102D70000000000000000000000000000000000053 -:102D80000000000000000000000000000000000043 -:102D90000000000000000000000000000000000033 -:102DA0000000000000000000000000000000000023 -:102DB0000000000000000000000000000000000013 -:102DC0000000000000000000000000000000000003 -:102DD00000000000000000000000000000000000F3 -:102DE00000000000000000000000000000000000E3 -:102DF00000000000000000000000000000000000D3 -:102E000000000000000000000000000000000000C2 -:102E100000000000000000000000000000000000B2 -:102E200000000000000000000000000000000000A2 -:102E30000000000000000000000000000000000092 -:102E40000000000000000000000000000000000082 -:102E50000000000000000000000000000000000072 -:102E60000000000000000000000000000000000062 -:102E70000000000000000000000000000000000052 -:102E80000000000000000000000000000000000042 -:102E90000000000000000000000000000000000032 -:102EA0000000000000000000000000000000000022 -:102EB0000000000000000000000000000000000012 -:102EC0000000000000000000000000000000000002 -:102ED00000000000000000000000000000000000F2 -:102EE00000000000000000000000000000000000E2 -:102EF00000000000000000000000000000000000D2 -:102F000000000000000000000000000000000000C1 -:102F100000000000000000000000000000000000B1 -:102F200000000000000000000000000000000000A1 -:102F30000000000000000000000000000000000091 -:102F40000000000000000000000000000000000081 -:102F50000000000000000000000000000000000071 -:102F60000000000000000000000000000000000061 -:102F70000000000000000000000000000000000051 -:102F80000000000000000000000000000000000041 -:102F90000000000000000000000000000000000031 -:102FA0000000000000000000000000000000000021 -:102FB0000000000000000000000000000000000011 -:102FC0000000000000000000000000000000000001 -:102FD00000000000000000000000000000000000F1 -:102FE00000000000000000000000000000000000E1 -:102FF00000000000000000000000000000000000D1 -:1030000000000000000000000000000000000000C0 -:1030100000000000000000000000000000000000B0 -:1030200000000000000000000000000000000000A0 -:103030000000000000000000000000000000000090 -:103040000000000000000000000000000000000080 -:103050000000000000000000000000000000000070 -:103060000000000000000000000000000000000060 -:103070000000000000000000000000000000000050 -:103080000000000000000000000000000000000040 -:103090000000000000000000000000000000000030 -:1030A0000000000000000000000000000000000020 -:1030B0000000000000000000000000000000000010 -:1030C0000000000000000000000000000000000000 -:1030D00000000000000000000000000000000000F0 -:1030E00000000000000000000000000000000000E0 -:1030F00000000000000000000000000000000000D0 -:1031000000000000000000000000000000000000BF -:1031100000000000000000000000000000000000AF -:10312000000000000000000000000000000000009F -:10313000000000000000000000000000000000008F -:10314000000000000000000000000000000000007F -:10315000000000000000000000000000000000006F -:10316000000000000000000000000000000000005F -:10317000000000000000000000000000000000004F -:10318000000000000000000000000000000000003F -:10319000000000000000000000000000000000002F -:1031A000000000000000000000000000000000001F -:1031B000000000000000000000000000000000000F -:1031C00000000000000000000000000000000000FF -:1031D00000000000000000000000000000000000EF -:1031E00000000000000000000000000000000000DF -:1031F00000000000000000000000000000000000CF -:1032000000000000000000000000000000000000BE -:1032100000000000000000000000000000000000AE -:10322000000000000000000000000000000000009E -:10323000000000000000000000000000000000008E -:10324000000000000000000000000000000000007E -:10325000000000000000000000000000000000006E -:10326000000000000000000000000000000000005E -:10327000000000000000000000000000000000004E -:10328000000000000000000000000000000000003E -:10329000000000000000000000000000000000002E -:1032A000000000000000000000000000000000001E -:1032B000000000000000000000000000000000000E -:1032C00000000000000000000000000000000000FE -:1032D00000000000000000000000000000000000EE -:1032E00000000000000000000000000000000000DE -:1032F00000000000000000000000000000000000CE -:1033000000000000000000000000000000000000BD -:1033100000000000000000000000000000000000AD -:10332000000000000000000000000000000000009D -:10333000000000000000000000000000000000008D -:10334000000000000000000000000000000000007D -:10335000000000000000000000000000000000006D -:10336000000000000000000000000000000000005D -:10337000000000000000000000000000000000004D -:10338000000000000000000000000000000000003D -:10339000000000000000000000000000000000002D -:1033A000000000000000000000000000000000001D -:1033B000000000000000000000000000000000000D -:1033C00000000000000000000000000000000000FD -:1033D00000000000000000000000000000000000ED -:1033E00000000000000000000000000000000000DD -:1033F00000000000000000000000000000000000CD -:1034000000000000000000000000000000000000BC -:1034100000000000000000000000000000000000AC -:10342000000000000000000000000000000000009C -:10343000000000000000000000000000000000008C -:10344000000000000000000000000000000000007C -:10345000000000000000000000000000000000006C -:10346000000000000000000000000000000000005C -:10347000000000000000000000000000000000004C -:10348000000000000000000000000000000000003C -:10349000000000000000000000000000000000002C -:1034A000000000000000000000000000000000001C -:1034B000000000000000000000000000000000000C -:1034C00000000000000000000000000000000000FC -:1034D00000000000000000000000000000000000EC -:1034E00000000000000000000000000000000000DC -:1034F00000000000000000000000000000000000CC -:1035000000000000000000000000000000000000BB -:1035100000000000000000000000000000000000AB -:10352000000000000000000000000000000000009B -:10353000000000000000000000000000000000008B -:10354000000000000000000000000000000000007B -:10355000000000000000000000000000000000006B -:10356000000000000000000000000000000000005B -:10357000000000000000000000000000000000004B -:10358000000000000000000000000000000000003B -:10359000000000000000000000000000000000002B -:1035A000000000000000000000000000000000001B -:1035B000000000000000000000000000000000000B -:1035C00000000000000000000000000000000000FB -:1035D00000000000000000000000000000000000EB -:1035E00000000000000000000000000000000000DB -:1035F00000000000000000000000000000000000CB -:1036000000000000000000000000000000000000BA -:1036100000000000000000000000000000000000AA -:10362000000000000000000000000000000000009A -:10363000000000000000000000000000000000008A -:10364000000000000000000000000000000000007A -:10365000000000000000000000000000000000006A -:10366000000000000000000000000000000000005A -:10367000000000000000000000000000000000004A -:10368000000000000000000000000000000000003A -:10369000000000000000000000000000000000002A -:1036A000000000000000000000000000000000001A -:1036B000000000000000000000000000000000000A -:1036C00000000000000000000000000000000000FA -:1036D00000000000000000000000000000000000EA -:1036E00000000000000000000000000000000000DA -:1036F00000000000000000000000000000000000CA -:1037000000000000000000000000000000000000B9 -:1037100000000000000000000000000000000000A9 -:103720000000000000000000000000000000000099 -:103730000000000000000000000000000000000089 -:103740000000000000000000000000000000000079 -:103750000000000000000000000000000000000069 -:103760000000000000000000000000000000000059 -:103770000000000000000000000000000000000049 -:103780000000000000000000000000000000000039 -:103790000000000000000000000000000000000029 -:1037A0000000000000000000000000000000000019 -:1037B0000000000000000000000000000000000009 -:1037C00000000000000000000000000000000000F9 -:1037D00000000000000000000000000000000000E9 -:1037E00000000000000000000000000000000000D9 -:1037F00000000000000000000000000000000000C9 -:1038000000000000000000000000000000000000B8 -:1038100000000000000000000000000000000000A8 -:103820000000000000000000000000000000000098 -:103830000000000000000000000000000000000088 -:103840000000000000000000000000000000000078 -:103850000000000000000000000000000000000068 -:103860000000000000000000000000000000000058 -:103870000000000000000000000000000000000048 -:103880000000000000000000000000000000000038 -:103890000000000000000000000000000000000028 -:1038A0000000000000000000000000000000000018 -:1038B0000000000000000000000000000000000008 -:1038C00000000000000000000000000000000000F8 -:1038D00000000000000000000000000000000000E8 -:1038E00000000000000000000000000000000000D8 -:1038F00000000000000000000000000000000000C8 -:1039000000000000000000000000000000000000B7 -:1039100000000000000000000000000000000000A7 -:103920000000000000000000000000000000000097 -:103930000000000000000000000000000000000087 -:103940000000000000000000000000000000000077 -:103950000000000000000000000000000000000067 -:103960000000000000000000000000000000000057 -:103970000000000000000000000000000000000047 -:103980000000000000000000000000000000000037 -:103990000000000000000000000000000000000027 -:1039A0000000000000000000000000000000000017 -:1039B0000000000000000000000000000000000007 -:1039C00000000000000000000000000000000000F7 -:1039D00000000000000000000000000000000000E7 -:1039E00000000000000000000000000000000000D7 -:1039F00000000000000000000000000000000000C7 -:103A000000000000000000000000000000000000B6 -:103A100000000000000000000000000000000000A6 -:103A20000000000000000000000000000000000096 -:103A30000000000000000000000000000000000086 -:103A40000000000000000000000000000000000076 -:103A50000000000000000000000000000000000066 -:103A60000000000000000000000000000000000056 -:103A70000000000000000000000000000000000046 -:103A80000000000000000000000000000000000036 -:103A90000000000000000000000000000000000026 -:103AA0000000000000000000000000000000000016 -:103AB0000000000000000000000000000000000006 -:103AC00000000000000000000000000000000000F6 -:103AD00000000000000000000000000000000000E6 -:103AE00000000000000000000000000000000000D6 -:103AF00000000000000000000000000000000000C6 -:103B000000000000000000000000000000000000B5 -:103B100000000000000000000000000000000000A5 -:103B20000000000000000000000000000000000095 -:103B30000000000000000000000000000000000085 -:103B40000000000000000000000000000000000075 -:103B50000000000000000000000000000000000065 -:103B60000000000000000000000000000000000055 -:103B70000000000000000000000000000000000045 -:103B80000000000000000000000000000000000035 -:103B90000000000000000000000000000000000025 -:103BA0000000000000000000000000000000000015 -:103BB0000000000000000000000000000000000005 -:103BC00000000000000000000000000000000000F5 -:103BD00000000000000000000000000000000000E5 -:103BE00000000000000000000000000000000000D5 -:103BF00000000000000000000000000000000000C5 -:103C000000000000000000000000000000000000B4 -:103C100000000000000000000000000000000000A4 -:103C20000000000000000000000000000000000094 -:103C30000000000000000000000000000000000084 -:103C40000000000000000000000000000000000074 -:103C50000000000000000000000000000000000064 -:103C60000000000000000000000000000000000054 -:103C70000000000000000000000000000000000044 -:103C80000000000000000000000000000000000034 -:103C90000000000000000000000000000000000024 -:103CA0000000000000000000000000000000000014 -:103CB0000000000000000000000000000000000004 -:103CC00000000000000000000000000000000000F4 -:103CD00000000000000000000000000000000000E4 -:103CE00000000000000000000000000000000000D4 -:103CF00000000000000000000000000000000000C4 -:103D000000000000000000000000000000000000B3 -:103D100000000000000000000000000000000000A3 -:103D20000000000000000000000000000000000093 -:103D30000000000000000000000000000000000083 -:103D40000000000000000000000000000000000073 -:103D50000000000000000000000000000000000063 -:103D60000000000000000000000000000000000053 -:103D70000000000000000000000000000000000043 -:103D80000000000000000000000000000000000033 -:103D90000000000000000000000000000000000023 -:103DA0000000000000000000000000000000000013 -:103DB0000000000000000000000000000000000003 -:103DC00000000000000000000000000000000000F3 -:103DD00000000000000000000000000000000000E3 -:103DE00000000000000000000000000000000000D3 -:103DF00000000000000000000000000000000000C3 -:103E000000000000000000000000000000000000B2 -:103E100000000000000000000000000000000000A2 -:103E20000000000000000000000000000000000092 -:103E30000000000000000000000000000000000082 -:103E40000000000000000000000000000000000072 -:103E50000000000000000000000000000000000062 -:103E60000000000000000000000000000000000052 -:103E70000000000000000000000000000000000042 -:103E80000000000000000000000000000000000032 -:103E90000000000000000000000000000000000022 -:103EA0000000000000000000000000000000000012 -:103EB0000000000000000000000000000000000002 -:103EC00000000000000000000000000000000000F2 -:103ED00000000000000000000000000000000000E2 -:103EE00000000000000000000000000000000000D2 -:103EF00000000000000000000000000000000000C2 -:103F000000000000000000000000000000000000B1 -:103F100000000000000000000000000000000000A1 -:103F20000000000000000000000000000000000091 -:103F30000000000000000000000000000000000081 -:103F40000000000000000000000000000000000071 -:103F50000000000000000000000000000000000061 -:103F60000000000000000000000000000000000051 -:103F70000000000000000000000000000000000041 -:103F80000000000000000000000000000000000031 -:103F90000000000000000000000000000000000021 -:103FA0000000000000000000000000000000000011 -:103FB0000000000000000000000000000000000001 -:103FC00000000000000000000000000000000000F1 -:103FD00000000000000000000000000000000000E1 -:103FE00000000000000000000000000000000000D1 -:103FF00000000000000000000000000000000000C1 -:1040000000000000000000000000000000000000B0 -:1040100000000000000000000000000000000000A0 -:104020000000000000000000000000000000000090 -:104030000000000000000000000000000000000080 -:104040000000000000000000000000000000000070 -:104050000000000000000000000000000000000060 -:104060000000000000000000000000000000000050 -:104070000000000000000000000000000000000040 -:104080000000000000000000000000000000000030 -:104090000000000000000000000000000000000020 -:1040A0000000000000000000000000000000000010 -:1040B0000000000000000000000000000000000000 -:1040C00000000000000000000000000000000000F0 -:1040D00000000000000000000000000000000000E0 -:1040E00000000000000000000000000000000000D0 -:1040F00000000000000000000000000000000000C0 -:1041000000000000000000000000000000000000AF -:10411000000000000000000000000000000000009F -:10412000000000000000000000000000000000008F -:10413000000000000000000000000000000000007F -:10414000000000000000000000000000000000006F -:10415000000000000000000000000000000000005F -:10416000000000000000000000000000000000004F -:10417000000000000000000000000000000000003F -:10418000000000000000000000000000000000002F -:10419000000000000000000000000000000000001F -:1041A000000000000000000000000000000000000F -:1041B00000000000000000000000000000000000FF -:1041C00000000000000000000000000000000000EF -:1041D00000000000000000000000000000000000DF -:1041E00000000000000000000000000000000000CF -:1041F00000000000000000000000000000000000BF -:1042000000000000000000000000000000000000AE -:10421000000000000000000000000000000000009E -:10422000000000000000000000000000000000008E -:10423000000000000000000000000000000000007E -:10424000000000000000000000000000000000006E -:10425000000000000000000000000000000000005E -:10426000000000000000000000000000000000004E -:10427000000000000000000000000000000000003E -:10428000000000000000000000000000000000002E -:10429000000000000000000000000000000000001E -:1042A000000000000000000000000000000000000E -:1042B00000000000000000000000000000000000FE -:1042C00000000000000000000000000000000000EE -:1042D00000000000000000000000000000000000DE -:1042E00000000000000000000000000000000000CE -:1042F00000000000000000000000000000000000BE -:1043000000000000000000000000000000000000AD -:10431000000000000000000000000000000000009D -:10432000000000000000000000000000000000008D -:10433000000000000000000000000000000000007D -:10434000000000000000000000000000000000006D -:10435000000000000000000000000000000000005D -:10436000000000000000000000000000000000004D -:10437000000000000000000000000000000000003D -:10438000000000000000000000000000000000002D -:10439000000000000000000000000000000000001D -:1043A000000000000000000000000000000000000D -:1043B00000000000000000000000000000000000FD -:1043C00000000000000000000000000000000000ED -:1043D00000000000000000000000000000000000DD -:1043E00000000000000000000000000000000000CD -:1043F00000000000000000000000000000000000BD -:1044000000000000000000000000000000000000AC -:10441000000000000000000000000000000000009C -:10442000000000000000000000000000000000008C -:10443000000000000000000000000000000000007C -:10444000000000000000000000000000000000006C -:10445000000000000000000000000000000000005C -:10446000000000000000000000000000000000004C -:10447000000000000000000000000000000000003C -:10448000000000000000000000000000000000002C -:10449000000000000000000000000000000000001C -:1044A000000000000000000000000000000000000C -:1044B00000000000000000000000000000000000FC -:1044C00000000000000000000000000000000000EC -:1044D00000000000000000000000000000000000DC -:1044E00000000000000000000000000000000000CC -:1044F00000000000000000000000000000000000BC -:1045000000000000000000000000000000000000AB -:10451000000000000000000000000000000000009B -:10452000000000000000000000000000000000008B -:10453000000000000000000000000000000000007B -:10454000000000000000000000000000000000006B -:10455000000000000000000000000000000000005B -:10456000000000000000000000000000000000004B -:10457000000000000000000000000000000000003B -:10458000000000000000000000000000000000002B -:10459000000000000000000000000000000000001B -:1045A000000000000000000000000000000000000B -:1045B00000000000000000000000000000000000FB -:1045C00000000000000000000000000000000000EB -:1045D00000000000000000000000000000000000DB -:1045E00000000000000000000000000000000000CB -:1045F00000000000000000000000000000000000BB -:1046000000000000000000000000000000000000AA -:10461000000000000000000000000000000000009A -:10462000000000000000000000000000000000008A -:10463000000000000000000000000000000000007A -:10464000000000000000000000000000000000006A -:10465000000000000000000000000000000000005A -:10466000000000000000000000000000000000004A -:10467000000000000000000000000000000000003A -:10468000000000000000000000000000000000002A -:10469000000000000000000000000000000000001A -:1046A000000000000000000000000000000000000A -:1046B00000000000000000000000000000000000FA -:1046C00000000000000000000000000000000000EA -:1046D00000000000000000000000000000000000DA -:1046E00000000000000000000000000000000000CA -:1046F00000000000000000000000000000000000BA -:1047000000000000000000000000000000000000A9 -:104710000000000000000000000000000000000099 -:104720000000000000000000000000000000000089 -:104730000000000000000000000000000000000079 -:104740000000000000000000000000000000000069 -:104750000000000000000000000000000000000059 -:104760000000000000000000000000000000000049 -:104770000000000000000000000000000000000039 -:104780000000000000000000000000000000000029 -:104790000000000000000000000000000000000019 -:1047A0000000000000000000000000000000000009 -:1047B00000000000000000000000000000000000F9 -:1047C00000000000000000000000000000000000E9 -:1047D00000000000000000000000000000000000D9 -:1047E00000000000000000000000000000000000C9 -:1047F00000000000000000000000000000000000B9 -:1048000000000000000000000000000000000000A8 -:104810000000000000000000000000000000000098 -:104820000000000000000000000000000000000088 -:104830000000000000000000000000000000000078 -:104840000000000000000000000000000000000068 -:104850000000000000000000000000000000000058 -:104860000000000000000000000000000000000048 -:104870000000000000000000000000000000000038 -:104880000000000000000000000000000000000028 -:104890000000000000000000000000000000000018 -:1048A0000000000000000000000000000000000008 -:1048B00000000000000000000000000000000000F8 -:1048C00000000000000000000000000000000000E8 -:1048D00000000000000000000000000000000000D8 -:1048E00000000000000000000000000000000000C8 -:1048F00000000000000000000000000000000000B8 -:1049000000000000000000000000000000000000A7 -:104910000000000000000000000000000000000097 -:104920000000000000000000000000000000000087 -:104930000000000000000000000000000000000077 -:104940000000000000000000000000000000000067 -:104950000000000000000000000000000000000057 -:104960000000000000000000000000000000000047 -:104970000000000000000000000000000000000037 -:104980000000000000000000000000000000000027 -:104990000000000000000000000000000000000017 -:1049A0000000000000000000000000000000000007 -:1049B00000000000000000000000000000000000F7 -:1049C00000000000000000000000000000000000E7 -:1049D00000000000000000000000000000000000D7 -:1049E00000000000000000000000000000000000C7 -:1049F00000000000000000000000000000000000B7 -:104A000000000000000000000000000000000000A6 -:104A10000000000000000000000000000000000096 -:104A20000000000000000000000000000000000086 -:104A30000000000000000000000000000000000076 -:104A40000000000000000000000000000000000066 -:104A50000000000000000000000000000000000056 -:104A60000000000000000000000000000000000046 -:104A70000000000000000000000000000000000036 -:104A80000000000000000000000000000000000026 -:104A90000000000000000000000000000000000016 -:104AA0000000000000000000000000000000000006 -:104AB00000000000000000000000000000000000F6 -:104AC00000000000000000000000000000000000E6 -:104AD00000000000000000000000000000000000D6 -:104AE00000000000000000000000000000000000C6 -:104AF00000000000000000000000000000000000B6 -:104B000000000000000000000000000000000000A5 -:104B10000000000000000000000000000000000095 -:104B20000000000000000000000000000000000085 -:104B30000000000000000000000000000000000075 -:104B40000000000000000000000000000000000065 -:104B50000000000000000000000000000000000055 -:104B60000000000000000000000000000000000045 -:104B70000000000000000000000000000000000035 -:104B80000000000000000000000000000000000025 -:104B90000000000000000000000000000000000015 -:104BA0000000000000000000000000000000000005 -:104BB00000000000000000000000000000000000F5 -:104BC00000000000000000000000000000000000E5 -:104BD00000000000000000000000000000000000D5 -:104BE00000000000000000000000000000000000C5 -:104BF00000000000000000000000000000000000B5 -:104C000000000000000000000000000000000000A4 -:104C10000000000000000000000000000000000094 -:104C20000000000000000000000000000000000084 -:104C30000000000000000000000000000000000074 -:104C40000000000000000000000000000000000064 -:104C50000000000000000000000000000000000054 -:104C60000000000000000000000000000000000044 -:104C70000000000000000000000000000000000034 -:104C80000000000000000000000000000000000024 -:104C90000000000000000000000000000000000014 -:104CA0000000000000000000000000000000000004 -:104CB00000000000000000000000000000000000F4 -:104CC00000000000000000000000000000000000E4 -:104CD00000000000000000000000000000000000D4 -:104CE00000000000000000000000000000000000C4 -:104CF00000000000000000000000000000000000B4 -:104D000000000000000000000000000000000000A3 -:104D10000000000000000000000000000000000093 -:104D20000000000000000000000000000000000083 -:104D30000000000000000000000000000000000073 -:104D40000000000000000000000000000000000063 -:104D50000000000000000000000000000000000053 -:104D60000000000000000000000000000000000043 -:104D70000000000000000000000000000000000033 -:104D80000000000000000000000000000000000023 -:104D90000000000000000000000000000000000013 -:104DA0000000000000000000000000000000000003 -:104DB00000000000000000000000000000000000F3 -:104DC00000000000000000000000000000000000E3 -:104DD00000000000000000000000000000000000D3 -:104DE00000000000000000000000000000000000C3 -:104DF00000000000000000000000000000000000B3 -:104E000000000000000000000000000000000000A2 -:104E10000000000000000000000000000000000092 -:104E20000000000000000000000000000000000082 -:104E30000000000000000000000000000000000072 -:104E40000000000000000000000000000000000062 -:104E50000000000000000000000000000000000052 -:104E60000000000000000000000000000000000042 -:104E70000000000000000000000000000000000032 -:104E80000000000000000000000000000000000022 -:104E90000000000000000000000000000000000012 -:104EA0000000000000000000000000000000000002 -:104EB00000000000000000000000000000000000F2 -:104EC00000000000000000000000000000000000E2 -:104ED00000000000000000000000000000000000D2 -:104EE00000000000000000000000000000000000C2 -:104EF00000000000000000000000000000000000B2 -:104F000000000000000000000000000000000000A1 -:104F10000000000000000000000000000000000091 -:104F20000000000000000000000000000000000081 -:104F30000000000000000000000000000000000071 -:104F40000000000000000000000000000000000061 -:104F50000000000000000000000000000000000051 -:104F60000000000000000000000000000000000041 -:104F70000000000000000000000000000000000031 -:104F80000000000000000000000000000000000021 -:104F90000000000000000000000000000000000011 -:104FA0000000000000000000000000000000000001 -:104FB00000000000000000000000000000000000F1 -:104FC00000000000000000000000000000000000E1 -:104FD00000000000000000000000000000000000D1 -:104FE00000000000000000000000000000000000C1 -:104FF00000000000000000000000000000000000B1 -:1050000000000000000000000000000000000000A0 -:105010000000000000000000000000000000000090 -:105020000000000000000000000000000000000080 -:105030000000000000000000000000000000000070 -:105040000000000000000000000000000000000060 -:105050000000000000000000000000000000000050 -:105060000000000000000000000000000000000040 -:105070000000000000000000000000000000000030 -:105080000000000000000000000000000000000020 -:105090000000000000000000000000000000000010 -:1050A0000000000000000000000000000000000000 -:1050B00000000000000000000000000000000000F0 -:1050C00000000000000000000000000000000000E0 -:1050D00000000000000000000000000000000000D0 -:1050E00000000000000000000000000000000000C0 -:1050F00000000000000000000000000000000000B0 -:10510000000000000000000000000000000000009F -:10511000000000000000000000000000000000008F -:10512000000000000000000000000000000000007F -:10513000000000000000000000000000000000006F -:10514000000000000000000000000000000000005F -:10515000000000000000000000000000000000004F -:10516000000000000000000000000000000000003F -:10517000000000000000000000000000000000002F -:10518000000000000000000000000000000000001F -:10519000000000000000000000000000000000000F -:1051A00000000000000000000000000000000000FF -:1051B00000000000000000000000000000000000EF -:1051C00000000000000000000000000000000000DF -:1051D00000000000000000000000000000000000CF -:1051E00000000000000000000000000000000000BF -:1051F00000000000000000000000000000000000AF -:10520000000000000000000000000000000000009E -:10521000000000000000000000000000000000008E -:10522000000000000000000000000000000000007E -:10523000000000000000000000000000000000006E -:10524000000000000000000000000000000000005E -:10525000000000000000000000000000000000004E -:10526000000000000000000000000000000000003E -:10527000000000000000000000000000000000002E -:10528000000000000000000000000000000000001E -:10529000000000000000000000000000000000000E -:1052A00000000000000000000000000000000000FE -:1052B00000000000000000000000000000000000EE -:1052C00000000000000000000000000000000000DE -:1052D00000000000000000000000000000000000CE -:1052E00000000000000000000000000000000000BE -:1052F00000000000000000000000000000000000AE -:10530000000000000000000000000000000000009D -:10531000000000000000000000000000000000008D -:10532000000000000000000000000000000000007D -:10533000000000000000000000000000000000006D -:10534000000000000000000000000000000000005D -:10535000000000000000000000000000000000004D -:10536000000000000000000000000000000000003D -:10537000000000000000000000000000000000002D -:10538000000000000000000000000000000000001D -:10539000000000000000000000000000000000000D -:1053A00000000000000000000000000000000000FD -:1053B00000000000000000000000000000000000ED -:1053C00000000000000000000000000000000000DD -:1053D00000000000000000000000000000000000CD -:1053E00000000000000000000000000000000000BD -:1053F00000000000000000000000000000000000AD -:10540000000000000000000000000000000000009C -:10541000000000000000000000000000000000008C -:10542000000000000000000000000000000000007C -:10543000000000000000000000000000000000006C -:10544000000000000000000000000000000000005C -:10545000000000000000000000000000000000004C -:10546000000000000000000000000000000000003C -:10547000000000000000000000000000000000002C -:10548000000000000000000000000000000000001C -:10549000000000000000000000000000000000000C -:1054A00000000000000000000000000000000000FC -:1054B00000000000000000000000000000000000EC -:1054C00000000000000000000000000000000000DC -:1054D00000000000000000000000000000000000CC -:1054E00000000000000000000000000000000000BC -:1054F00000000000000000000000000000000000AC -:10550000000000000000000000000000000000009B -:10551000000000000000000000000000000000008B -:10552000000000000000000000000000000000007B -:10553000000000000000000000000000000000006B -:10554000000000000000000000000000000000005B -:10555000000000000000000000000000000000004B -:10556000000000000000000000000000000000003B -:10557000000000000000000000000000000000002B -:10558000000000000000000000000000000000001B -:10559000000000000000000000000000000000000B -:1055A00000000000000000000000000000000000FB -:1055B00000000000000000000000000000000000EB -:1055C00000000000000000000000000000000000DB -:1055D00000000000000000000000000000000000CB -:1055E00000000000000000000000000000000000BB -:1055F00000000000000000000000000000000000AB -:10560000000000000000000000000000000000009A -:10561000000000000000000000000000000000008A -:10562000000000000000000000000000000000007A -:10563000000000000000000000000000000000006A -:10564000000000000000000000000000000000005A -:10565000000000000000000000000000000000004A -:10566000000000000000000000000000000000003A -:10567000000000000000000000000000000000002A -:10568000000000000000000000000000000000001A -:10569000000000000000000000000000000000000A -:1056A00000000000000000000000000000000000FA -:1056B00000000000000000000000000000000000EA -:1056C00000000000000000000000000000000000DA -:1056D00000000000000000000000000000000000CA -:1056E00000000000000000000000000000000000BA -:1056F00000000000000000000000000000000000AA -:105700000000000000000000000000000000000099 -:105710000000000000000000000000000000000089 -:105720000000000000000000000000000000000079 -:105730000000000000000000000000000000000069 -:105740000000000000000000000000000000000059 -:105750000000000000000000000000000000000049 -:105760000000000000000000000000000000000039 -:105770000000000000000000000000000000000029 -:105780000000000000000000000000000000000019 -:105790000000000000000000000000000000000009 -:1057A00000000000000000000000000000000000F9 -:1057B00000000000000000000000000000000000E9 -:1057C00000000000000000000000000000000000D9 -:1057D00000000000000000000000000000000000C9 -:1057E00000000000000000000000000000000000B9 -:1057F00000000000000000000000000000000000A9 -:105800000000000000000000000000000000000098 -:105810000000000000000000000000000000000088 -:105820000000000000000000000000000000000078 -:105830000000000000000000000000000000000068 -:105840000000000000000000000000000000000058 -:105850000000000000000000000000000000000048 -:105860000000000000000000000000000000000038 -:105870000000000000000000000000000000000028 -:105880000000000000000000000000000000000018 -:105890000000000000000000000000000000000008 -:1058A00000000000000000000000000000000000F8 -:1058B00000000000000000000000000000000000E8 -:1058C00000000000000000000000000000000000D8 -:1058D00000000000000000000000000000000000C8 -:1058E00000000000000000000000000000000000B8 -:1058F00000000000000000000000000000000000A8 -:105900000000000000000000000000000000000097 -:105910000000000000000000000000000000000087 -:105920000000000000000000000000000000000077 -:105930000000000000000000000000000000000067 -:105940000000000000000000000000000000000057 -:105950000000000000000000000000000000000047 -:105960000000000000000000000000000000000037 -:105970000000000000000000000000000000000027 -:105980000000000000000000000000000000000017 -:105990000000000000000000000000000000000007 -:1059A00000000000000000000000000000000000F7 -:1059B00000000000000000000000000000000000E7 -:1059C00000000000000000000000000000000000D7 -:1059D00000000000000000000000000000000000C7 -:1059E00000000000000000000000000000000000B7 -:1059F00000000000000000000000000000000000A7 -:105A00000000000000000000000000000000000096 -:105A10000000000000000000000000000000000086 -:105A20000000000000000000000000000000000076 -:105A30000000000000000000000000000000000066 -:105A40000000000000000000000000000000000056 -:105A50000000000000000000000000000000000046 -:105A60000000000000000000000000000000000036 -:105A70000000000000000000000000000000000026 -:105A80000000000000000000000000000000000016 -:105A90000000000000000000000000000000000006 -:105AA00000000000000000000000000000000000F6 -:105AB00000000000000000000000000000000000E6 -:105AC00000000000000000000000000000000000D6 -:105AD00000000000000000000000000000000000C6 -:105AE00000000000000000000000000000000000B6 -:105AF00000000000000000000000000000000000A6 -:105B00000000000000000000000000000000000095 -:105B10000000000000000000000000000000000085 -:105B20000000000000000000000000000000000075 -:105B30000000000000000000000000000000000065 -:105B40000000000000000000000000000000000055 -:105B50000000000000000000000000000000000045 -:105B60000000000000000000000000000000000035 -:105B70000000000000000000000000000000000025 -:105B80000000000000000000000000000000000015 -:105B90000000000000000000000000000000000005 -:105BA00000000000000000000000000000000000F5 -:105BB00000000000000000000000000000000000E5 -:105BC00000000000000000000000000000000000D5 -:105BD00000000000000000000000000000000000C5 -:105BE00000000000000000000000000000000000B5 -:105BF00000000000000000000000000000000000A5 -:105C00000000000000000000000000000000000094 -:105C10000000000000000000000000000000000084 -:105C20000000000000000000000000000000000074 -:105C30000000000000000000000000000000000064 -:105C40000000000000000000000000000000000054 -:105C50000000000000000000000000000000000044 -:105C60000000000000000000000000000000000034 -:105C70000000000000000000000000000000000024 -:105C80000000000000000000000000000000000014 -:105C90000000000000000000000000000000000004 -:105CA00000000000000000000000000000000000F4 -:105CB00000000000000000000000000000000000E4 -:105CC00000000000000000000000000000000000D4 -:105CD00000000000000000000000000000000000C4 -:105CE00000000000000000000000000000000000B4 -:105CF00000000000000000000000000000000000A4 -:105D00000000000000000000000000000000000093 -:105D10000000000000000000000000000000000083 -:105D20000000000000000000000000000000000073 -:105D30000000000000000000000000000000000063 -:105D40000000000000000000000000000000000053 -:105D50000000000000000000000000000000000043 -:105D60000000000000000000000000000000000033 -:105D70000000000000000000000000000000000023 -:105D80000000000000000000000000000000000013 -:105D90000000000000000000000000000000000003 -:105DA00000000000000000000000000000000000F3 -:105DB00000000000000000000000000000000000E3 -:105DC00000000000000000000000000000000000D3 -:105DD00000000000000000000000000000000000C3 -:105DE00000000000000000000000000000000000B3 -:105DF00000000000000000000000000000000000A3 -:105E00000000000000000000000000000000000092 -:105E10000000000000000000000000000000000082 -:105E20000000000000000000000000000000000072 -:105E30000000000000000000000000000000000062 -:105E40000000000000000000000000000000000052 -:105E50000000000000000000000000000000000042 -:105E60000000000000000000000000000000000032 -:105E70000000000000000000000000000000000022 -:105E80000000000000000000000000000000000012 -:105E90000000000000000000000000000000000002 -:105EA00000000000000000000000000000000000F2 -:105EB00000000000000000000000000000000000E2 -:105EC00000000000000000000000000000000000D2 -:105ED00000000000000000000000000000000000C2 -:105EE00000000000000000000000000000000000B2 -:105EF00000000000000000000000000000000000A2 -:105F00000000000000000000000000000000000091 -:105F10000000000000000000000000000000000081 -:105F20000000000000000000000000000000000071 -:105F30000000000000000000000000000000000061 -:105F40000000000000000000000000000000000051 -:105F50000000000000000000000000000000000041 -:105F60000000000000000000000000000000000031 -:105F70000000000000000000000000000000000021 -:105F80000000000000000000000000000000000011 -:105F90000000000000000000000000000000000001 -:105FA00000000000000000000000000000000000F1 -:105FB00000000000000000000000000000000000E1 -:105FC00000000000000000000000000000000000D1 -:105FD00000000000000000000000000000000000C1 -:105FE00000000000000000000000000000000000B1 -:105FF00000000000000000000000000000000000A1 -:106000000000000000000000000000000000000090 -:106010000000000000000000000000000000000080 -:106020000000000000000000000000000000000070 -:106030000000000000000000000000000000000060 -:106040000000000000000000000000000000000050 -:106050000000000000000000000000000000000040 -:106060000000000000000000000000000000000030 -:106070000000000000000000000000000000000020 -:106080000000000000000000000000000000000010 -:106090000000000000000000000000000000000000 -:1060A00000000000000000000000000000000000F0 -:1060B00000000000000000000000000000000000E0 -:1060C00000000000000000000000000000000000D0 -:1060D00000000000000000000000000000000000C0 -:1060E00000000000000000000000000000000000B0 -:1060F00000000000000000000000000000000000A0 -:10610000000000000000000000000000000000008F -:10611000000000000000000000000000000000007F -:10612000000000000000000000000000000000006F -:10613000000000000000000000000000000000005F -:10614000000000000000000000000000000000004F -:10615000000000000000000000000000000000003F -:10616000000000000000000000000000000000002F -:10617000000000000000000000000000000000001F -:10618000000000000000000000000000000000000F -:1061900000000000000000000000000000000000FF -:1061A00000000000000000000000000000000000EF -:1061B00000000000000000000000000000000000DF -:1061C00000000000000000000000000000000000CF -:1061D00000000000000000000000000000000000BF -:1061E00000000000000000000000000000000000AF -:1061F000000000000000000000000000000000009F -:10620000000000000000000000000000000000008E -:10621000000000000000000000000000000000007E -:10622000000000000000000000000000000000006E -:10623000000000000000000000000000000000005E -:10624000000000000000000000000000000000004E -:10625000000000000000000000000000000000003E -:10626000000000000000000000000000000000002E -:10627000000000000000000000000000000000001E -:10628000000000000000000000000000000000000E -:1062900000000000000000000000000000000000FE -:1062A00000000000000000000000000000000000EE -:1062B00000000000000000000000000000000000DE -:1062C00000000000000000000000000000000000CE -:1062D00000000000000000000000000000000000BE -:1062E00000000000000000000000000000000000AE -:1062F000000000000000000000000000000000009E -:10630000000000000000000000000000000000008D -:10631000000000000000000000000000000000007D -:10632000000000000000000000000000000000006D -:10633000000000000000000000000000000000005D -:10634000000000000000000000000000000000004D -:10635000000000000000000000000000000000003D -:10636000000000000000000000000000000000002D -:10637000000000000000000000000000000000001D -:10638000000000000000000000000000000000000D -:1063900000000000000000000000000000000000FD -:1063A00000000000000000000000000000000000ED -:1063B00000000000000000000000000000000000DD -:1063C00000000000000000000000000000000000CD -:1063D00000000000000000000000000000000000BD -:1063E00000000000000000000000000000000000AD -:1063F000000000000000000000000000000000009D -:10640000000000000000000000000000000000008C -:10641000000000000000000000000000000000007C -:10642000000000000000000000000000000000006C -:10643000000000000000000000000000000000005C -:10644000000000000000000000000000000000004C -:10645000000000000000000000000000000000003C -:10646000000000000000000000000000000000002C -:10647000000000000000000000000000000000001C -:10648000000000000000000000000000000000000C -:1064900000000000000000000000000000000000FC -:1064A00000000000000000000000000000000000EC -:1064B00000000000000000000000000000000000DC -:1064C00000000000000000000000000000000000CC -:1064D00000000000000000000000000000000000BC -:1064E00000000000000000000000000000000000AC -:1064F000000000000000000000000000000000009C -:10650000000000000000000000000000000000008B -:10651000000000000000000000000000000000007B -:10652000000000000000000000000000000000006B -:10653000000000000000000000000000000000005B -:10654000000000000000000000000000000000004B -:10655000000000000000000000000000000000003B -:10656000000000000000000000000000000000002B -:10657000000000000000000000000000000000001B -:10658000000000000000000000000000000000000B -:1065900000000000000000000000000000000000FB -:1065A00000000000000000000000000000000000EB -:1065B00000000000000000000000000000000000DB -:1065C00000000000000000000000000000000000CB -:1065D00000000000000000000000000000000000BB -:1065E00000000000000000000000000000000000AB -:1065F000000000000000000000000000000000009B -:10660000000000000000000000000000000000008A -:10661000000000000000000000000000000000007A -:10662000000000000000000000000000000000006A -:10663000000000000000000000000000000000005A -:10664000000000000000000000000000000000004A -:10665000000000000000000000000000000000003A -:10666000000000000000000000000000000000002A -:10667000000000000000000000000000000000001A -:10668000000000000000000000000000000000000A -:1066900000000000000000000000000000000000FA -:1066A00000000000000000000000000000000000EA -:1066B00000000000000000000000000000000000DA -:1066C00000000000000000000000000000000000CA -:1066D00000000000000000000000000000000000BA -:1066E00000000000000000000000000000000000AA -:1066F000000000000000000000000000000000009A -:106700000000000000000000000000000000000089 -:106710000000000000000000000000000000000079 -:106720000000000000000000000000000000000069 -:106730000000000000000000000000000000000059 -:106740000000000000000000000000000000000049 -:106750000000000000000000000000000000000039 -:106760000000000000000000000000000000000029 -:106770000000000000000000000000000000000019 -:106780000000000000000000000000000000000009 -:1067900000000000000000000000000000000000F9 -:1067A00000000000000000000000000000000000E9 -:1067B00000000000000000000000000000000000D9 -:1067C00000000000000000000000000000000000C9 -:1067D00000000000000000000000000000000000B9 -:1067E00000000000000000000000000000000000A9 -:1067F0000000000000000000000000000000000099 -:106800000000000000000000000000000000000088 -:106810000000000000000000000000000000000078 -:106820000000000000000000000000000000000068 -:106830000000000000000000000000000000000058 -:106840000000000000000000000000000000000048 -:106850000000000000000000000000000000000038 -:106860000000000000000000000000000000000028 -:106870000000000000000000000000000000000018 -:106880000000000000000000000000000000000008 -:1068900000000000000000000000000000000000F8 -:1068A00000000000000000000000000000000000E8 -:1068B00000000000000000000000000000000000D8 -:1068C00000000000000000000000000000000000C8 -:1068D00000000000000000000000000000000000B8 -:1068E00000000000000000000000000000000000A8 -:1068F0000000000000000000000000000000000098 -:106900000000000000000000000000000000000087 -:106910000000000000000000000000000000000077 -:106920000000000000000000000000000000000067 -:106930000000000000000000000000000000000057 -:106940000000000000000000000000000000000047 -:106950000000000000000000000000000000000037 -:106960000000000000000000000000000000000027 -:106970000000000000000000000000000000000017 -:106980000000000000000000000000000000000007 -:1069900000000000000000000000000000000000F7 -:1069A00000000000000000000000000000000000E7 -:1069B00000000000000000000000000000000000D7 -:1069C00000000000000000000000000000000000C7 -:1069D00000000000000000000000000000000000B7 -:1069E00000000000000000000000000000000000A7 -:1069F0000000000000000000000000000000000097 -:106A00000000000000000000000000000000000086 -:106A10000000000000000000000000000000000076 -:106A20000000000000000000000000000000000066 -:106A30000000000000000000000000000000000056 -:106A40000000000000000000000000000000000046 -:106A50000000000000000000000000000000000036 -:106A60000000000000000000000000000000000026 -:106A70000000000000000000000000000000000016 -:106A80000000000000000000000000000000000006 -:106A900000000000000000000000000000000000F6 -:106AA00000000000000000000000000000000000E6 -:106AB00000000000000000000000000000000000D6 -:106AC00000000000000000000000000000000000C6 -:106AD00000000000000000000000000000000000B6 -:106AE00000000000000000000000000000000000A6 -:106AF0000000000000000000000000000000000096 -:106B00000000000000000000000000000000000085 -:106B10000000000000000000000000000000000075 -:106B20000000000000000000000000000000000065 -:106B30000000000000000000000000000000000055 -:106B40000000000000000000000000000000000045 -:106B50000000000000000000000000000000000035 -:106B60000000000000000000000000000000000025 -:106B70000000000000000000000000000000000015 -:106B80000000000000000000000000000000000005 -:106B900000000000000000000000000000000000F5 -:106BA00000000000000000000000000000000000E5 -:106BB00000000000000000000000000000000000D5 -:106BC00000000000000000000000000000000000C5 -:106BD00000000000000000000000000000000000B5 -:106BE00000000000000000000000000000000000A5 -:106BF0000000000000000000000000000000000095 -:106C00000000000000000000000000000000000084 -:106C10000000000000000000000000000000000074 -:106C20000000000000000000000000000000000064 -:106C30000000000000000000000000000000000054 -:106C40000000000000000000000000000000000044 -:106C50000000000000000000000000000000000034 -:106C60000000000000000000000000000000000024 -:106C70000000000000000000000000000000000014 -:106C80000000000000000000000000000000000004 -:106C900000000000000000000000000000000000F4 -:106CA00000000000000000000000000000000000E4 -:106CB00000000000000000000000000000000000D4 -:106CC00000000000000000000000000000000000C4 -:106CD00000000000000000000000000000000000B4 -:106CE00000000000000000000000000000000000A4 -:106CF0000000000000000000000000000000000094 -:106D00000000000000000000000000000000000083 -:106D10000000000000000000000000000000000073 -:106D20000000000000000000000000000000000063 -:106D30000000000000000000000000000000000053 -:106D40000000000000000000000000000000000043 -:106D50000000000000000000000000000000000033 -:106D60000000000000000000000000000000000023 -:106D70000000000000000000000000000000000013 -:106D80000000000000000000000000000000000003 -:106D900000000000000000000000000000000000F3 -:106DA00000000000000000000000000000000000E3 -:106DB00000000000000000000000000000000000D3 -:106DC00000000000000000000000000000000000C3 -:106DD00000000000000000000000000000000000B3 -:106DE00000000000000000000000000000000000A3 -:106DF0000000000000000000000000000000000093 -:106E00000000000000000000000000000000000082 -:106E10000000000000000000000000000000000072 -:106E20000000000000000000000000000000000062 -:106E30000000000000000000000000000000000052 -:106E40000000000000000000000000000000000042 -:106E50000000000000000000000000000000000032 -:106E60000000000000000000000000000000000022 -:106E70000000000000000000000000000000000012 -:106E80000000000000000000000000000000000002 -:106E900000000000000000000000000000000000F2 -:106EA00000000000000000000000000000000000E2 -:106EB00000000000000000000000000000000000D2 -:106EC00000000000000000000000000000000000C2 -:106ED00000000000000000000000000000000000B2 -:106EE00000000000000000000000000000000000A2 -:106EF0000000000000000000000000000000000092 -:106F00000000000000000000000000000000000081 -:106F10000000000000000000000000000000000071 -:106F20000000000000000000000000000000000061 -:106F30000000000000000000000000000000000051 -:106F40000000000000000000000000000000000041 -:106F50000000000000000000000000000000000031 -:106F60000000000000000000000000000000000021 -:106F70000000000000000000000000000000000011 -:106F80000000000000000000000000000000000001 -:106F900000000000000000000000000000000000F1 -:106FA00000000000000000000000000000000000E1 -:106FB00000000000000000000000000000000000D1 -:106FC00000000000000000000000000000000000C1 -:106FD00000000000000000000000000000000000B1 -:106FE00000000000000000000000000000000000A1 -:106FF0000000000000000000000000000000000091 -:107000000000000000000000000000000000000080 -:107010000000000000000000000000000000000070 -:107020000000000000000000000000000000000060 -:107030000000000000000000000000000000000050 -:107040000000000000000000000000000000000040 -:107050000000000000000000000000000000000030 -:107060000000000000000000000000000000000020 -:107070000000000000000000000000000000000010 -:107080000000000000000000000000000000000000 -:1070900000000000000000000000000000000000F0 -:1070A00000000000000000000000000000000000E0 -:1070B00000000000000000000000000000000000D0 -:1070C00000000000000000000000000000000000C0 -:1070D00000000000000000000000000000000000B0 -:1070E00000000000000000000000000000000000A0 -:1070F0000000000000000000000000000000000090 -:10710000000000000000000000000000000000007F -:10711000000000000000000000000000000000006F -:10712000000000000000000000000000000000005F -:10713000000000000000000000000000000000004F -:10714000000000000000000000000000000000003F -:10715000000000000000000000000000000000002F -:10716000000000000000000000000000000000001F -:10717000000000000000000000000000000000000F -:1071800000000000000000000000000000000000FF -:1071900000000000000000000000000000000000EF -:1071A00000000000000000000000000000000000DF -:1071B00000000000000000000000000000000000CF -:1071C00000000000000000000000000000000000BF -:1071D00000000000000000000000000000000000AF -:1071E000000000000000000000000000000000009F -:1071F000000000000000000000000000000000008F -:10720000000000000000000000000000000000007E -:10721000000000000000000000000000000000006E -:10722000000000000000000000000000000000005E -:10723000000000000000000000000000000000004E -:10724000000000000000000000000000000000003E -:10725000000000000000000000000000000000002E -:10726000000000000000000000000000000000001E -:10727000000000000000000000000000000000000E -:1072800000000000000000000000000000000000FE -:1072900000000000000000000000000000000000EE -:1072A00000000000000000000000000000000000DE -:1072B00000000000000000000000000000000000CE -:1072C00000000000000000000000000000000000BE -:1072D00000000000000000000000000000000000AE -:1072E000000000000000000000000000000000009E -:1072F000000000000000000000000000000000008E -:10730000000000000000000000000000000000007D -:10731000000000000000000000000000000000006D -:10732000000000000000000000000000000000005D -:10733000000000000000000000000000000000004D -:10734000000000000000000000000000000000003D -:10735000000000000000000000000000000000002D -:10736000000000000000000000000000000000001D -:10737000000000000000000000000000000000000D -:1073800000000000000000000000000000000000FD -:1073900000000000000000000000000000000000ED -:1073A00000000000000000000000000000000000DD -:1073B00000000000000000000000000000000000CD -:1073C00000000000000000000000000000000000BD -:1073D00000000000000000000000000000000000AD -:1073E000000000000000000000000000000000009D -:1073F000000000000000000000000000000000008D -:10740000000000000000000000000000000000007C -:10741000000000000000000000000000000000006C -:10742000000000000000000000000000000000005C -:10743000000000000000000000000000000000004C -:10744000000000000000000000000000000000003C -:10745000000000000000000000000000000000002C -:10746000000000000000000000000000000000001C -:10747000000000000000000000000000000000000C -:1074800000000000000000000000000000000000FC -:1074900000000000000000000000000000000000EC -:1074A00000000000000000000000000000000000DC -:1074B00000000000000000000000000000000000CC -:1074C00000000000000000000000000000000000BC -:1074D00000000000000000000000000000000000AC -:1074E000000000000000000000000000000000009C -:1074F000000000000000000000000000000000008C -:10750000000000000000000000000000000000007B -:10751000000000000000000000000000000000006B -:10752000000000000000000000000000000000005B -:10753000000000000000000000000000000000004B -:10754000000000000000000000000000000000003B -:10755000000000000000000000000000000000002B -:10756000000000000000000000000000000000001B -:10757000000000000000000000000000000000000B -:1075800000000000000000000000000000000000FB -:1075900000000000000000000000000000000000EB -:1075A00000000000000000000000000000000000DB -:1075B00000000000000000000000000000000000CB -:1075C00000000000000000000000000000000000BB -:1075D00000000000000000000000000000000000AB -:1075E000000000000000000000000000000000009B -:1075F000000000000000000000000000000000008B -:10760000000000000000000000000000000000007A -:10761000000000000000000000000000000000006A -:10762000000000000000000000000000000000005A -:10763000000000000000000000000000000000004A -:10764000000000000000000000000000000000003A -:10765000000000000000000000000000000000002A -:10766000000000000000000000000000000000001A -:10767000000000000000000000000000000000000A -:1076800000000000000000000000000000000000FA -:1076900000000000000000000000000000000000EA -:1076A00000000000000000000000000000000000DA -:1076B00000000000000000000000000000000000CA -:1076C00000000000000000000000000000000000BA -:1076D00000000000000000000000000000000000AA -:1076E000000000000000000000000000000000009A -:1076F000000000000000000000000000000000008A -:107700000000000000000000000000000000000079 -:107710000000000000000000000000000000000069 -:107720000000000000000000000000000000000059 -:107730000000000000000000000000000000000049 -:107740000000000000000000000000000000000039 -:107750000000000000000000000000000000000029 -:107760000000000000000000000000000000000019 -:107770000000000000000000000000000000000009 -:1077800000000000000000000000000000000000F9 -:1077900000000000000000000000000000000000E9 -:1077A00000000000000000000000000000000000D9 -:1077B00000000000000000000000000000000000C9 -:1077C00000000000000000000000000000000000B9 -:1077D00000000000000000000000000000000000A9 -:1077E0000000000000000000000000000000000099 -:1077F0000000000000000000000000000000000089 -:107800000000000000000000000000000000000078 -:107810000000000000000000000000000000000068 -:107820000000000000000000000000000000000058 -:107830000000000000000000000000000000000048 -:107840000000000000000000000000000000000038 -:107850000000000000000000000000000000000028 -:107860000000000000000000000000000000000018 -:107870000000000000000000000000000000000008 -:1078800000000000000000000000000000000000F8 -:1078900000000000000000000000000000000000E8 -:1078A00000000000000000000000000000000000D8 -:1078B00000000000000000000000000000000000C8 -:1078C00000000000000000000000000000000000B8 -:1078D00000000000000000000000000000000000A8 -:1078E0000000000000000000000000000000000098 -:1078F0000000000000000000000000000000000088 -:107900000000000000000000000000000000000077 -:107910000000000000000000000000000000000067 -:107920000000000000000000000000000000000057 -:107930000000000000000000000000000000000047 -:107940000000000000000000000000000000000037 -:107950000000000000000000000000000000000027 -:107960000000000000000000000000000000000017 -:107970000000000000000000000000000000000007 -:1079800000000000000000000000000000000000F7 -:1079900000000000000000000000000000000000E7 -:1079A00000000000000000000000000000000000D7 -:1079B00000000000000000000000000000000000C7 -:1079C00000000000000000000000000000000000B7 -:1079D00000000000000000000000000000000000A7 -:1079E0000000000000000000000000000000000097 -:1079F0000000000000000000000000000000000087 -:107A00000000000000000000000000000000000076 -:107A10000000000000000000000000000000000066 -:107A20000000000000000000000000000000000056 -:107A30000000000000000000000000000000000046 -:107A40000000000000000000000000000000000036 -:107A50000000000000000000000000000000000026 -:107A60000000000000000000000000000000000016 -:107A70000000000000000000000000000000000006 -:107A800000000000000000000000000000000000F6 -:107A900000000000000000000000000000000000E6 -:107AA00000000000000000000000000000000000D6 -:107AB00000000000000000000000000000000000C6 -:107AC00000000000000000000000000000000000B6 -:107AD00000000000000000000000000000000000A6 -:107AE0000000000000000000000000000000000096 -:107AF0000000000000000000000000000000000086 -:107B00000000000000000000000000000000000075 -:107B10000000000000000000000000000000000065 -:107B20000000000000000000000000000000000055 -:107B30000000000000000000000000000000000045 -:107B40000000000000000000000000000000000035 -:107B50000000000000000000000000000000000025 -:107B60000000000000000000000000000000000015 -:107B70000000000000000000000000000000000005 -:107B800000000000000000000000000000000000F5 -:107B900000000000000000000000000000000000E5 -:107BA00000000000000000000000000000000000D5 -:107BB00000000000000000000000000000000000C5 -:107BC00000000000000000000000000000000000B5 -:107BD00000000000000000000000000000000000A5 -:107BE0000000000000000000000000000000000095 -:107BF0000000000000000000000000000000000085 -:107C00000000000000000000000000000000000074 -:107C10000000000000000000000000000000000064 -:107C20000000000000000000000000000000000054 -:107C30000000000000000000000000000000000044 -:107C40000000000000000000000000000000000034 -:107C50000000000000000000000000000000000024 -:107C60000000000000000000000000000000000014 -:107C70000000000000000000000000000000000004 -:107C800000000000000000000000000000000000F4 -:107C900000000000000000000000000000000000E4 -:107CA00000000000000000000000000000000000D4 -:107CB00000000000000000000000000000000000C4 -:107CC00000000000000000000000000000000000B4 -:107CD00000000000000000000000000000000000A4 -:107CE0000000000000000000000000000000000094 -:107CF0000000000000000000000000000000000084 -:107D00000000000000000000000000000000000073 -:107D10000000000000000000000000000000000063 -:107D20000000000000000000000000000000000053 -:107D30000000000000000000000000000000000043 -:107D40000000000000000000000000000000000033 -:107D50000000000000000000000000000000000023 -:107D60000000000000000000000000000000000013 -:107D70000000000000000000000000000000000003 -:107D800000000000000000000000000000000000F3 -:107D900000000000000000000000000000000000E3 -:107DA00000000000000000000000000000000000D3 -:107DB00000000000000000000000000000000000C3 -:107DC00000000000000000000000000000000000B3 -:107DD00000000000000000000000000000000000A3 -:107DE0000000000000000000000000000000000093 -:107DF0000000000000000000000000000000000083 -:107E00000000000000000000000000000000000072 -:107E10000000000000000000000000000000000062 -:107E20000000000000000000000000000000000052 -:107E30000000000000000000000000000000000042 -:107E40000000000000000000000000000000000032 -:107E50000000000000000000000000000000000022 -:107E60000000000000000000000000000000000012 -:107E70000000000000000000000000000000000002 -:107E800000000000000000000000000000000000F2 -:107E900000000000000000000000000000000000E2 -:107EA00000000000000000000000000000000000D2 -:107EB00000000000000000000000000000000000C2 -:107EC00000000000000000000000000000000000B2 -:107ED00000000000000000000000000000000000A2 -:107EE0000000000000000000000000000000000092 -:107EF0000000000000000000000000000000000082 -:107F00000000000000000000000000000000000071 -:107F10000000000000000000000000000000000061 -:107F20000000000000000000000000000000000051 -:107F30000000000000000000000000000000000041 -:107F40000000000000000000000000000000000031 -:107F50000000000000000000000000000000000021 -:107F60000000000000000000000000000000000011 -:107F70000000000000000000000000000000000001 -:107F800000000000000000000000000000000000F1 -:107F900000000000000000000000000000000000E1 -:107FA00000000000000000000000000000000000D1 -:107FB00000000000000000000000000000000000C1 -:107FC00000000000000000000000000000000000B1 -:107FD00000000000000000000000000000000000A1 -:107FE0000000000000000000000000000000000091 -:107FF0000000000000000000000000000000000081 -:108000000000000000000000000000000000000070 -:108010000000000000000000000000000000000060 -:108020000000000000000000000000000000000050 -:108030000000000000000000000000000000000040 -:108040000000000000000000000000000000000030 -:108050000000000000000000000000000000000020 -:108060000000000000000000000000000000000010 -:108070000000000000000000000000000000000000 -:1080800000000000000000000000000000000000F0 -:1080900000000000000000000000000000000000E0 -:1080A00000000000000000000000000000000000D0 -:1080B00000000000000000000000000000000000C0 -:1080C00000000000000000000000000000000000B0 -:1080D00000000000000000000000000000000000A0 -:1080E0000000000000000000000000000000000090 -:1080F0000000000000000000000000000000000080 -:10810000000000000000000000000000000000006F -:10811000000000000000000000000000000000005F -:10812000000000000000000000000000000000004F -:10813000000000000000000000000000000000003F -:10814000000000000000000000000000000000002F -:10815000000000000000000000000000000000001F -:10816000000000000000000000000000000000000F -:1081700000000000000000000000000000000000FF -:1081800000000000000000000000000000000000EF -:1081900000000000000000000000000000000000DF -:1081A00000000000000000000000000000000000CF -:1081B00000000000000000000000000000000000BF -:1081C00000000000000000000000000000000000AF -:1081D000000000000000000000000000000000009F -:1081E000000000000000000000000000000000008F -:1081F000000000000000000000000000000000007F -:10820000000000000000000000000000000000006E -:10821000000000000000000000000000000000005E -:10822000000000000000000000000000000000004E -:10823000000000000000000000000000000000003E -:10824000000000000000000000000000000000002E -:10825000000000000000000000000000000000001E -:10826000000000000000000000000000000000000E -:1082700000000000000000000000000000000000FE -:1082800000000000000000000000000000000000EE -:1082900000000000000000000000000000000000DE -:1082A00000000000000000000000000000000000CE -:1082B00000000000000000000000000000000000BE -:1082C00000000000000000000000000000000000AE -:1082D000000000000000000000000000000000009E -:1082E000000000000000000000000000000000008E -:1082F000000000000000000000000000000000007E -:10830000000000000000000000000000000000006D -:10831000000000000000000000000000000000005D -:10832000000000000000000000000000000000004D -:10833000000000000000000000000000000000003D -:10834000000000000000000000000000000000002D -:10835000000000000000000000000000000000001D -:10836000000000000000000000000000000000000D -:1083700000000000000000000000000000000000FD -:1083800000000000000000000000000000000000ED -:1083900000000000000000000000000000000000DD -:1083A00000000000000000000000000000000000CD -:1083B00000000000000000000000000000000000BD -:1083C00000000000000000000000000000000000AD -:1083D000000000000000000000000000000000009D -:1083E000000000000000000000000000000000008D -:1083F000000000000000000000000000000000007D -:10840000000000000000000000000000000000006C -:10841000000000000000000000000000000000005C -:10842000000000000000000000000000000000004C -:10843000000000000000000000000000000000003C -:10844000000000000000000000000000000000002C -:10845000000000000000000000000000000000001C -:10846000000000000000000000000000000000000C -:1084700000000000000000000000000000000000FC -:1084800000000000000000000000000000000000EC -:1084900000000000000000000000000000000000DC -:1084A00000000000000000000000000000000000CC -:1084B00000000000000000000000000000000000BC -:1084C00000000000000000000000000000000000AC -:1084D000000000000000000000000000000000009C -:1084E000000000000000000000000000000000008C -:1084F000000000000000000000000000000000007C -:10850000000000000000000000000000000000006B -:10851000000000000000000000000000000000005B -:10852000000000000000000000000000000000004B -:10853000000000000000000000000000000000003B -:10854000000000000000000000000000000000002B -:10855000000000000000000000000000000000001B -:10856000000000000000000000000000000000000B -:1085700000000000000000000000000000000000FB -:1085800000000000000000000000000000000000EB -:1085900000000000000000000000000000000000DB -:1085A00000000000000000000000000000000000CB -:1085B00000000000000000000000000000000000BB -:1085C00000000000000000000000000000000000AB -:1085D000000000000000000000000000000000009B -:1085E000000000000000000000000000000000008B -:1085F000000000000000000000000000000000007B -:10860000000000000000000000000000000000006A -:10861000000000000000000000000000000000005A -:10862000000000000000000000000000000000004A -:10863000000000000000000000000000000000003A -:10864000000000000000000000000000000000002A -:10865000000000000000000000000000000000001A -:10866000000000000000000000000000000000000A -:1086700000000000000000000000000000000000FA -:1086800000000000000000000000000000000000EA -:1086900000000000000000000000000000000000DA -:1086A00000000000000000000000000000000000CA -:1086B00000000000000000000000000000000000BA -:1086C00000000000000000000000000000000000AA -:1086D000000000000000000000000000000000009A -:1086E000000000000000000000000000000000008A -:1086F000000000000000000000000000000000007A -:108700000000000000000000000000000000000069 -:108710000000000000000000000000000000000059 -:108720000000000000000000000000000000000049 -:108730000000000000000000000000000000000039 -:108740000000000000000000000000000000000029 -:108750000000000000000000000000000000000019 -:108760000000000000000000000000000000000009 -:1087700000000000000000000000000000000000F9 -:1087800000000000000000000000000000000000E9 -:1087900000000000000000000000000000000000D9 -:1087A00000000000000000000000000000000000C9 -:1087B00000000000000000000000000000000000B9 -:1087C00000000000000000000000000000000000A9 -:1087D0000000000000000000000000000000000099 -:1087E0000000000000000000000000000000000089 -:1087F0000000000000000000000000000000000079 -:108800000000000000000000000000000000000068 -:108810000000000000000000000000000000000058 -:108820000000000000000000000000000000000048 -:108830000000000000000000000000000000000038 -:108840000000000000000000000000000000000028 -:108850000000000000000000000000000000000018 -:108860000000000000000000000000000000000008 -:1088700000000000000000000000000000000000F8 -:1088800000000000000000000000000000000000E8 -:1088900000000000000000000000000000000000D8 -:1088A00000000000000000000000000000000000C8 -:1088B00000000000000000000000000000000000B8 -:1088C00000000000000000000000000000000000A8 -:1088D0000000000000000000000000000000000098 -:1088E0000000000000000000000000000000000088 -:1088F0000000000000000000000000000000000078 -:108900000000000000000000000000000000000067 -:108910000000000000000000000000000000000057 -:108920000000000000000000000000000000000047 -:108930000000000000000000000000000000000037 -:108940000000000000000000000000000000000027 -:108950000000000000000000000000000000000017 -:108960000000000000000000000000000000000007 -:1089700000000000000000000000000000000000F7 -:1089800000000000000000000000000000000000E7 -:1089900000000000000000000000000000000000D7 -:1089A00000000000000000000000000000000000C7 -:1089B00000000000000000000000000000000000B7 -:1089C00000000000000000000000000000000000A7 -:1089D0000000000000000000000000000000000097 -:1089E0000000000000000000000000000000000087 -:1089F0000000000000000000000000000000000077 -:108A00000000000000000000000000000000000066 -:108A10000000000000000000000000000000000056 -:108A20000000000000000000000000000000000046 -:108A30000000000000000000000000000000000036 -:108A40000000000000000000000000000000000026 -:108A50000000000000000000000000000000000016 -:108A60000000000000000000000000000000000006 -:108A700000000000000000000000000000000000F6 -:108A800000000000000000000000000000000000E6 -:108A900000000000000000000000000000000000D6 -:108AA00000000000000000000000000000000000C6 -:108AB00000000000000000000000000000000000B6 -:108AC00000000000000000000000000000000000A6 -:108AD0000000000000000000000000000000000096 -:108AE0000000000000000000000000000000000086 -:108AF0000000000000000000000000000000000076 -:108B00000000000000000000000000000000000065 -:108B10000000000000000000000000000000000055 -:108B20000000000000000000000000000000000045 -:108B30000000000000000000000000000000000035 -:108B40000000000000000000000000000000000025 -:108B50000000000000000000000000000000000015 -:108B60000000000000000000000000000000000005 -:108B700000000000000000000000000000000000F5 -:108B800000000000000000000000000000000000E5 -:108B900000000000000000000000000000000000D5 -:108BA00000000000000000000000000000000000C5 -:108BB00000000000000000000000000000000000B5 -:108BC00000000000000000000000000000000000A5 -:108BD0000000000000000000000000000000000095 -:108BE0000000000000000000000000000000000085 -:108BF0000000000000000000000000000000000075 -:108C00000000000000000000000000000000000064 -:108C10000000000000000000000000000000000054 -:108C20000000000000000000000000000000000044 -:108C30000000000000000000000000000000000034 -:108C40000000000000000000000000000000000024 -:108C50000000000000000000000000000000000014 -:108C60000000000000000000000000000000000004 -:108C700000000000000000000000000000000000F4 -:108C800000000000000000000000000000000000E4 -:108C900000000000000000000000000000000000D4 -:108CA00000000000000000000000000000000000C4 -:108CB00000000000000000000000000000000000B4 -:108CC00000000000000000000000000000000000A4 -:108CD0000000000000000000000000000000000094 -:108CE0000000000000000000000000000000000084 -:108CF0000000000000000000000000000000000074 -:108D00000000000000000000000000000000000063 -:108D10000000000000000000000000000000000053 -:108D20000000000000000000000000000000000043 -:108D30000000000000000000000000000000000033 -:108D40000000000000000000000000000000000023 -:108D50000000000000000000000000000000000013 -:108D60000000000000000000000000000000000003 -:108D700000000000000000000000000000000000F3 -:108D800000000000000000000000000000000000E3 -:108D900000000000000000000000000000000000D3 -:108DA00000000000000000000000000000000000C3 -:108DB00000000000000000000000000000000000B3 -:108DC00000000000000000000000000000000000A3 -:108DD0000000000000000000000000000000000093 -:108DE0000000000000000000000000000000000083 -:108DF0000000000000000000000000000000000073 -:108E00000000000000000000000000000000000062 -:108E10000000000000000000000000000000000052 -:108E20000000000000000000000000000000000042 -:108E30000000000000000000000000000000000032 -:108E40000000000000000000000000000000000022 -:108E50000000000000000000000000000000000012 -:108E60000000000000000000000000000000000002 -:108E700000000000000000000000000000000000F2 -:108E800000000000000000000000000000000000E2 -:108E900000000000000000000000000000000000D2 -:108EA00000000000000000000000000000000000C2 -:108EB00000000000000000000000000000000000B2 -:108EC00000000000000000000000000000000000A2 -:108ED0000000000000000000000000000000000092 -:108EE0000000000000000000000000000000000082 -:108EF0000000000000000000000000000000000072 -:108F00000000000000000000000000000000000061 -:108F10000000000000000000000000000000000051 -:108F20000000000000000000000000000000000041 -:108F30000000000000000000000000000000000031 -:108F40000000000000000000000000000000000021 -:108F50000000000000000000000000000000000011 -:108F60000000000000000000000000000000000001 -:108F700000000000000000000000000000000000F1 -:108F800000000000000000000000000000000000E1 -:108F900000000000000000000000000000000000D1 -:108FA00000000000000000000000000000000000C1 -:108FB00000000000000000000000000000000000B1 -:108FC00000000000000000000000000000000000A1 -:108FD0000000000000000000000000000000000091 -:108FE0000000000000000000000000000000000081 -:108FF0000000000000000000000000000000000071 -:109000000000000000000000000000000000000060 -:109010000000000000000000000000000000000050 -:109020000000000000000000000000000000000040 -:109030000000000000000000000000000000000030 -:109040000000000000000000000000000000000020 -:109050000000000000000000000000000000000010 -:109060000000000000000000000000000000000000 -:1090700000000000000000000000000000000000F0 -:1090800000000000000000000000000000000000E0 -:1090900000000000000000000000000000000000D0 -:1090A00000000000000000000000000000000000C0 -:1090B00000000000000000000000000000000000B0 -:1090C00000000000000000000000000000000000A0 -:1090D0000000000000000000000000000000000090 -:1090E0000000000000000000000000000000000080 -:1090F0000000000000000000000000000000000070 -:10910000000000000000000000000000000000005F -:10911000000000000000000000000000000000004F -:10912000000000000000000000000000000000003F -:10913000000000000000000000000000000000002F -:10914000000000000000000000000000000000001F -:10915000000000000000000000000000000000000F -:1091600000000000000000000000000000000000FF -:1091700000000000000000000000000000000000EF -:1091800000000000000000000000000000000000DF -:1091900000000000000000000000000000000000CF -:1091A00000000000000000000000000000000000BF -:1091B00000000000000000000000000000000000AF -:1091C000000000000000000000000000000000009F -:1091D000000000000000000000000000000000008F -:1091E000000000000000000000000000000000007F -:1091F000000000000000000000000000000000006F -:10920000000000000000000000000000000000005E -:10921000000000000000000000000000000000004E -:10922000000000000000000000000000000000003E -:10923000000000000000000000000000000000002E -:10924000000000000000000000000000000000001E -:10925000000000000000000000000000000000000E -:1092600000000000000000000000000000000000FE -:1092700000000000000000000000000000000000EE -:1092800000000000000000000000000000000000DE -:1092900000000000000000000000000000000000CE -:1092A00000000000000000000000000000000000BE -:1092B00000000000000000000000000000000000AE -:1092C000000000000000000000000000000000009E -:1092D000000000000000000000000000000000008E -:1092E000000000000000000000000000000000007E -:1092F000000000000000000000000000000000006E -:10930000000000000000000000000000000000005D -:10931000000000000000000000000000000000004D -:10932000000000000000000000000000000000003D -:10933000000000000000000000000000000000002D -:10934000000000000000000000000000000000001D -:10935000000000000000000000000000000000000D -:1093600000000000000000000000000000000000FD -:1093700000000000000000000000000000000000ED -:1093800000000000000000000000000000000000DD -:1093900000000000000000000000000000000000CD -:1093A00000000000000000000000000000000000BD -:1093B00000000000000000000000000000000000AD -:1093C000000000000000000000000000000000009D -:1093D000000000000000000000000000000000008D -:1093E000000000000000000000000000000000007D -:1093F000000000000000000000000000000000006D -:10940000000000000000000000000000000000005C -:10941000000000000000000000000000000000004C -:10942000000000000000000000000000000000003C -:10943000000000000000000000000000000000002C -:10944000000000000000000000000000000000001C -:10945000000000000000000000000000000000000C -:1094600000000000000000000000000000000000FC -:1094700000000000000000000000000000000000EC -:1094800000000000000000000000000000000000DC -:1094900000000000000000000000000000000000CC -:1094A00000000000000000000000000000000000BC -:1094B00000000000000000000000000000000000AC -:1094C000000000000000000000000000000000009C -:1094D000000000000000000000000000000000008C -:1094E000000000000000000000000000000000007C -:1094F000000000000000000000000000000000006C -:10950000000000000000000000000000000000005B -:10951000000000000000000000000000000000004B -:10952000000000000000000000000000000000003B -:10953000000000000000000000000000000000002B -:10954000000000000000000000000000000000001B -:10955000000000000000000000000000000000000B -:1095600000000000000000000000000000000000FB -:1095700000000000000000000000000000000000EB -:1095800000000000000000000000000000000000DB -:1095900000000000000000000000000000000000CB -:1095A00000000000000000000000000000000000BB -:1095B00000000000000000000000000000000000AB -:1095C000000000000000000000000000000000009B -:1095D000000000000000000000000000000000008B -:1095E000000000000000000000000000000000007B -:1095F000000000000000000000000000000000006B -:10960000000000000000000000000000000000005A -:10961000000000000000000000000000000000004A -:10962000000000000000000000000000000000003A -:10963000000000000000000000000000000000002A -:10964000000000000000000000000000000000001A -:10965000000000000000000000000000000000000A -:1096600000000000000000000000000000000000FA -:1096700000000000000000000000000000000000EA -:1096800000000000000000000000000000000000DA -:1096900000000000000000000000000000000000CA -:1096A00000000000000000000000000000000000BA -:1096B00000000000000000000000000000000000AA -:1096C000000000000000000000000000000000009A -:1096D000000000000000000000000000000000008A -:1096E000000000000000000000000000000000007A -:1096F000000000000000000000000000000000006A -:109700000000000000000000000000000000000059 -:109710000000000000000000000000000000000049 -:109720000000000000000000000000000000000039 -:109730000000000000000000000000000000000029 -:109740000000000000000000000000000000000019 -:109750000000000000000000000000000000000009 -:1097600000000000000000000000000000000000F9 -:1097700000000000000000000000000000000000E9 -:1097800000000000000000000000000000000000D9 -:1097900000000000000000000000000000000000C9 -:1097A00000000000000000000000000000000000B9 -:1097B00000000000000000000000000000000000A9 -:1097C0000000000000000000000000000000000099 -:1097D0000000000000000000000000000000000089 -:1097E0000000000000000000000000000000000079 -:1097F0000000000000000000000000000000000069 -:109800000000000000000000000000000000000058 -:109810000000000000000000000000000000000048 -:109820000000000000000000000000000000000038 -:109830000000000000000000000000000000000028 -:109840000000000000000000000000000000000018 -:109850000000000000000000000000000000000008 -:1098600000000000000000000000000000000000F8 -:1098700000000000000000000000000000000000E8 -:1098800000000000000000000000000000000000D8 -:1098900000000000000000000000000000000000C8 -:1098A00000000000000000000000000000000000B8 -:1098B00000000000000000000000000000000000A8 -:1098C0000000000000000000000000000000000098 -:1098D0000000000000000000000000000000000088 -:1098E0000000000000000000000000000000000078 -:1098F0000000000000000000000000000000000068 -:109900000000000000000000000000000000000057 -:109910000000000000000000000000000000000047 -:109920000000000000000000000000000000000037 -:109930000000000000000000000000000000000027 -:109940000000000000000000000000000000000017 -:109950000000000000000000000000000000000007 -:1099600000000000000000000000000000000000F7 -:1099700000000000000000000000000000000000E7 -:1099800000000000000000000000000000000000D7 -:1099900000000000000000000000000000000000C7 -:1099A00000000000000000000000000000000000B7 -:1099B00000000000000000000000000000000000A7 -:1099C0000000000000000000000000000000000097 -:1099D0000000000000000000000000000000000087 -:1099E0000000000000000000000000000000000077 -:1099F0000000000000000000000000000000000067 -:109A00000000000000000000000000000000000056 -:109A10000000000000000000000000000000000046 -:109A20000000000000000000000000000000000036 -:109A30000000000000000000000000000000000026 -:109A40000000000000000000000000000000000016 -:109A50000000000000000000000000000000000006 -:109A600000000000000000000000000000000000F6 -:109A700000000000000000000000000000000000E6 -:109A800000000000000000000000000000000000D6 -:109A900000000000000000000000000000000000C6 -:109AA00000000000000000000000000000000000B6 -:109AB00000000000000000000000000000000000A6 -:109AC0000000000000000000000000000000000096 -:109AD0000000000000000000000000000000000086 -:109AE0000000000000000000000000000000000076 -:109AF0000000000000000000000000000000000066 -:109B00000000000000000000000000000000000055 -:109B10000000000000000000000000000000000045 -:109B20000000000000000000000000000000000035 -:109B30000000000000000000000000000000000025 -:109B40000000000000000000000000000000000015 -:109B50000000000000000000000000000000000005 -:109B600000000000000000000000000000000000F5 -:109B700000000000000000000000000000000000E5 -:109B800000000000000000000000000000000000D5 -:109B900000000000000000000000000000000000C5 -:109BA00000000000000000000000000000000000B5 -:109BB00000000000000000000000000000000000A5 -:109BC0000000000000000000000000000000000095 -:109BD0000000000000000000000000000000000085 -:109BE0000000000000000000000000000000000075 -:109BF0000000000000000000000000000000000065 -:109C00000000000000000000000000000000000054 -:109C10000000000000000000000000000000000044 -:109C20000000000000000000000000000000000034 -:109C30000000000000000000000000000000000024 -:109C40000000000000000000000000000000000014 -:109C50000000000000000000000000000000000004 -:109C600000000000000000000000000000000000F4 -:109C700000000000000000000000000000000000E4 -:109C800000000000000000000000000000000000D4 -:109C900000000000000000000000000000000000C4 -:109CA00000000000000000000000000000000000B4 -:109CB00000000000000000000000000000000000A4 -:109CC0000000000000000000000000000000000094 -:109CD0000000000000000000000000000000000084 -:109CE0000000000000000000000000000000000074 -:109CF0000000000000000000000000000000000064 -:109D00000000000000000000000000000000000053 -:109D10000000000000000000000000000000000043 -:109D20000000000000000000000000000000000033 -:109D30000000000000000000000000000000000023 -:109D40000000000000000000000000000000000013 -:109D50000000000000000000000000000000000003 -:109D600000000000000000000000000000000000F3 -:109D700000000000000000000000000000000000E3 -:109D800000000000000000000000000000000000D3 -:109D900000000000000000000000000000000000C3 -:109DA00000000000000000000000000000000000B3 -:109DB00000000000000000000000000000000000A3 -:109DC0000000000000000000000000000000000093 -:109DD0000000000000000000000000000000000083 -:109DE0000000000000000000000000000000000073 -:109DF0000000000000000000000000000000000063 -:109E00000000000000000000000000000000000052 -:109E10000000000000000000000000000000000042 -:109E20000000000000000000000000000000000032 -:109E30000000000000000000000000000000000022 -:109E40000000000000000000000000000000000012 -:109E50000000000000000000000000000000000002 -:109E600000000000000000000000000000000000F2 -:109E700000000000000000000000000000000000E2 -:109E800000000000000000000000000000000000D2 -:109E900000000000000000000000000000000000C2 -:109EA00000000000000000000000000000000000B2 -:109EB00000000000000000000000000000000000A2 -:109EC0000000000000000000000000000000000092 -:109ED0000000000000000000000000000000000082 -:109EE0000000000000000000000000000000000072 -:109EF0000000000000000000000000000000000062 -:109F00000000000000000000000000000000000051 -:109F10000000000000000000000000000000000041 -:109F20000000000000000000000000000000000031 -:109F30000000000000000000000000000000000021 -:109F40000000000000000000000000000000000011 -:109F50000000000000000000000000000000000001 -:109F600000000000000000000000000000000000F1 -:109F700000000000000000000000000000000000E1 -:109F800000000000000000000000000000000000D1 -:109F900000000000000000000000000000000000C1 -:109FA00000000000000000000000000000000000B1 -:109FB00000000000000000000000000000000000A1 -:109FC0000000000000000000000000000000000091 -:109FD0000000000000000000000000000000000081 -:109FE0000000000000000000000000000000000071 -:109FF0000000000000000000000000000000000061 -:10A000000000000000000000000000000000000050 -:10A010000000000000000000000000000000000040 -:10A020000000000000000000000000000000000030 -:10A030000000000000000000000000000000000020 -:10A040000000000000000000000000000000000010 -:10A050000000000000000000000000000000000000 -:10A0600000000000000000000000000000000000F0 -:10A0700000000000000000000000000000000000E0 -:10A0800000000000000000000000000000000000D0 -:10A0900000000000000000000000000000000000C0 -:10A0A00000000000000000000000000000000000B0 -:10A0B00000000000000000000000000000000000A0 -:10A0C0000000000000000000000000000000000090 -:10A0D0000000000000000000000000000000000080 -:10A0E0000000000000000000000000000000000070 -:10A0F0000000000000000000000000000000000060 -:10A10000000000000000000000000000000000004F -:10A11000000000000000000000000000000000003F -:10A12000000000000000000000000000000000002F -:10A13000000000000000000000000000000000001F -:10A14000000000000000000000000000000000000F -:10A1500000000000000000000000000000000000FF -:10A1600000000000000000000000000000000000EF -:10A1700000000000000000000000000000000000DF -:10A1800000000000000000000000000000000000CF -:10A1900000000000000000000000000000000000BF -:10A1A00000000000000000000000000000000000AF -:10A1B000000000000000000000000000000000009F -:10A1C000000000000000000000000000000000008F -:10A1D000000000000000000000000000000000007F -:10A1E000000000000000000000000000000000006F -:10A1F000000000000000000000000000000000005F -:10A20000000000000000000000000000000000004E -:10A21000000000000000000000000000000000003E -:10A22000000000000000000000000000000000002E -:10A23000000000000000000000000000000000001E -:10A24000000000000000000000000000000000000E -:10A2500000000000000000000000000000000000FE -:10A2600000000000000000000000000000000000EE -:10A2700000000000000000000000000000000000DE -:10A2800000000000000000000000000000000000CE -:10A2900000000000000000000000000000000000BE -:10A2A00000000000000000000000000000000000AE -:10A2B000000000000000000000000000000000009E -:10A2C000000000000000000000000000000000008E -:10A2D000000000000000000000000000000000007E -:10A2E000000000000000000000000000000000006E -:10A2F000000000000000000000000000000000005E -:10A30000000000000000000000000000000000004D -:10A31000000000000000000000000000000000003D -:10A32000000000000000000000000000000000002D -:10A33000000000000000000000000000000000001D -:10A34000000000000000000000000000000000000D -:10A3500000000000000000000000000000000000FD -:10A3600000000000000000000000000000000000ED -:10A3700000000000000000000000000000000000DD -:10A3800000000000000000000000000000000000CD -:10A3900000000000000000000000000000000000BD -:10A3A00000000000000000000000000000000000AD -:10A3B000000000000000000000000000000000009D -:10A3C000000000000000000000000000000000008D -:10A3D000000000000000000000000000000000007D -:10A3E000000000000000000000000000000000006D -:10A3F000000000000000000000000000000000005D -:10A40000000000000000000000000000000000004C -:10A41000000000000000000000000000000000003C -:10A42000000000000000000000000000000000002C -:10A43000000000000000000000000000000000001C -:10A44000000000000000000000000000000000000C -:10A4500000000000000000000000000000000000FC -:10A4600000000000000000000000000000000000EC -:10A4700000000000000000000000000000000000DC -:10A4800000000000000000000000000000000000CC -:10A4900000000000000000000000000000000000BC -:10A4A00000000000000000000000000000000000AC -:10A4B000000000000000000000000000000000009C -:10A4C000000000000000000000000000000000008C -:10A4D000000000000000000000000000000000007C -:10A4E000000000000000000000000000000000006C -:10A4F000000000000000000000000000000000005C -:10A50000000000000000000000000000000000004B -:10A51000000000000000000000000000000000003B -:10A52000000000000000000000000000000000002B -:10A53000000000000000000000000000000000001B -:10A54000000000000000000000000000000000000B -:10A5500000000000000000000000000000000000FB -:10A5600000000000000000000000000000000000EB -:10A5700000000000000000000000000000000000DB -:10A5800000000000000000000000000000000000CB -:10A5900000000000000000000000000000000000BB -:10A5A00000000000000000000000000000000000AB -:10A5B000000000000000000000000000000000009B -:10A5C000000000000000000000000000000000008B -:10A5D000000000000000000000000000000000007B -:10A5E000000000000000000000000000000000006B -:10A5F000000000000000000000000000000000005B -:10A60000000000000000000000000000000000004A -:10A61000000000000000000000000000000000003A -:10A62000000000000000000000000000000000002A -:10A63000000000000000000000000000000000001A -:10A64000000000000000000000000000000000000A -:10A6500000000000000000000000000000000000FA -:10A6600000000000000000000000000000000000EA -:10A6700000000000000000000000000000000000DA -:10A6800000000000000000000000000000000000CA -:10A6900000000000000000000000000000000000BA -:10A6A00000000000000000000000000000000000AA -:10A6B000000000000000000000000000000000009A -:10A6C000000000000000000000000000000000008A -:10A6D000000000000000000000000000000000007A -:10A6E000000000000000000000000000000000006A -:10A6F000000000000000000000000000000000005A -:10A700000000000000000000000000000000000049 -:10A710000000000000000000000000000000000039 -:10A720000000000000000000000000000000000029 -:10A730000000000000000000000000000000000019 -:10A740000000000000000000000000000000000009 -:10A7500000000000000000000000000000000000F9 -:10A7600000000000000000000000000000000000E9 -:10A7700000000000000000000000000000000000D9 -:10A7800000000000000000000000000000000000C9 -:10A7900000000000000000000000000000000000B9 -:10A7A00000000000000000000000000000000000A9 -:10A7B0000000000000000000000000000000000099 -:10A7C0000000000000000000000000000000000089 -:10A7D0000000000000000000000000000000000079 -:10A7E0000000000000000000000000000000000069 -:10A7F0000000000000000000000000000000000059 -:10A800000000000000000000000000000000000048 -:10A810000000000000000000000000000000000038 -:10A820000000000000000000000000000000000028 -:10A830000000000000000000000000000000000018 -:10A840000000000000000000000000000000000008 -:10A8500000000000000000000000000000000000F8 -:10A8600000000000000000000000000000000000E8 -:10A8700000000000000000000000000000000000D8 -:10A8800000000000000000000000000000000000C8 -:10A8900000000000000000000000000000000000B8 -:10A8A00000000000000000000000000000000000A8 -:10A8B0000000000000000000000000000000000098 -:10A8C0000000000000000000000000000000000088 -:10A8D0000000000000000000000000000000000078 -:10A8E0000000000000000000000000000000000068 -:10A8F0000000000000000000000000000000000058 -:10A900000000000000000000000000000000000047 -:10A910000000000000000000000000000000000037 -:10A920000000000000000000000000000000000027 -:10A930000000000000000000000000000000000017 -:10A940000000000000000000000000000000000007 -:10A9500000000000000000000000000000000000F7 -:10A9600000000000000000000000000000000000E7 -:10A9700000000000000000000000000000000000D7 -:10A9800000000000000000000000000000000000C7 -:10A9900000000000000000000000000000000000B7 -:10A9A00000000000000000000000000000000000A7 -:10A9B0000000000000000000000000000000000097 -:10A9C0000000000000000000000000000000000087 -:10A9D0000000000000000000000000000000000077 -:10A9E0000000000000000000000000000000000067 -:10A9F0000000000000000000000000000000000057 -:10AA00000000000000000000000000000000000046 -:10AA10000000000000000000000000000000000036 -:10AA20000000000000000000000000000000000026 -:10AA30000000000000000000000000000000000016 -:10AA40000000000000000000000000000000000006 -:10AA500000000000000000000000000000000000F6 -:10AA600000000000000000000000000000000000E6 -:10AA700000000000000000000000000000000000D6 -:10AA800000000000000000000000000000000000C6 -:10AA900000000000000000000000000000000000B6 -:10AAA00000000000000000000000000000000000A6 -:10AAB0000000000000000000000000000000000096 -:10AAC0000000000000000000000000000000000086 -:10AAD0000000000000000000000000000000000076 -:10AAE0000000000000000000000000000000000066 -:10AAF0000000000000000000000000000000000056 -:10AB00000000000000000000000000000000000045 -:10AB10000000000000000000000000000000000035 -:10AB20000000000000000000000000000000000025 -:10AB30000000000000000000000000000000000015 -:10AB40000000000000000000000000000000000005 -:10AB500000000000000000000000000000000000F5 -:10AB600000000000000000000000000000000000E5 -:10AB700000000000000000000000000000000000D5 -:10AB800000000000000000000000000000000000C5 -:10AB900000000000000000000000000000000000B5 -:10ABA00000000000000000000000000000000000A5 -:10ABB0000000000000000000000000000000000095 -:10ABC0000000000000000000000000000000000085 -:10ABD0000000000000000000000000000000000075 -:10ABE0000000000000000000000000000000000065 -:10ABF0000000000000000000000000000000000055 -:10AC00000000000000000000000000000000000044 -:10AC10000000000000000000000000000000000034 -:10AC20000000000000000000000000000000000024 -:10AC30000000000000000000000000000000000014 -:10AC40000000000000000000000000000000000004 -:10AC500000000000000000000000000000000000F4 -:10AC600000000000000000000000000000000000E4 -:10AC700000000000000000000000000000000000D4 -:10AC800000000000000000000000000000000000C4 -:10AC900000000000000000000000000000000000B4 -:10ACA00000000000000000000000000000000000A4 -:10ACB0000000000000000000000000000000000094 -:10ACC0000000000000000000000000000000000084 -:10ACD0000000000000000000000000000000000074 -:10ACE0000000000000000000000000000000000064 -:10ACF0000000000000000000000000000000000054 -:10AD00000000000000000000000000000000000043 -:10AD10000000000000000000000000000000000033 -:10AD20000000000000000000000000000000000023 -:10AD30000000000000000000000000000000000013 -:10AD40000000000000000000000000000000000003 -:10AD500000000000000000000000000000000000F3 -:10AD600000000000000000000000000000000000E3 -:10AD700000000000000000000000000000000000D3 -:10AD800000000000000000000000000000000000C3 -:10AD900000000000000000000000000000000000B3 -:10ADA00000000000000000000000000000000000A3 -:10ADB0000000000000000000000000000000000093 -:10ADC0000000000000000000000000000000000083 -:10ADD0000000000000000000000000000000000073 -:10ADE0000000000000000000000000000000000063 -:10ADF0000000000000000000000000000000000053 -:10AE00000000000000000000000000000000000042 -:10AE10000000000000000000000000000000000032 -:10AE20000000000000000000000000000000000022 -:10AE30000000000000000000000000000000000012 -:10AE40000000000000000000000000000000000002 -:10AE500000000000000000000000000000000000F2 -:10AE600000000000000000000000000000000000E2 -:10AE700000000000000000000000000000000000D2 -:10AE800000000000000000000000000000000000C2 -:10AE900000000000000000000000000000000000B2 -:10AEA00000000000000000000000000000000000A2 -:10AEB0000000000000000000000000000000000092 -:10AEC0000000000000000000000000000000000082 -:10AED0000000000000000000000000000000000072 -:10AEE0000000000000000000000000000000000062 -:10AEF0000000000000000000000000000000000052 -:10AF00000000000000000000000000000000000041 -:10AF10000000000000000000000000000000000031 -:10AF20000000000000000000000000000000000021 -:10AF30000000000000000000000000000000000011 -:10AF40000000000000000000000000000000000001 -:10AF500000000000000000000000000000000000F1 -:10AF600000000000000000000000000000000000E1 -:10AF700000000000000000000000000000000000D1 -:10AF800000000000000000000000000000000000C1 -:10AF900000000000000000000000000000000000B1 -:10AFA00000000000000000000000000000000000A1 -:10AFB0000000000000000000000000000000000091 -:10AFC0000000000000000000000000000000000081 -:10AFD0000000000000000000000000000000000071 -:10AFE0000000000000000000000000000000000061 -:10AFF0000000000000000000000000000000000051 -:10B000000000000000000000000000000000000040 -:10B010000000000000000000000000000000000030 -:10B020000000000000000000000000000000000020 -:10B030000000000000000000000000000000000010 -:10B040000000000000000000000000000000000000 -:10B0500000000000000000000000000000000000F0 -:10B0600000000000000000000000000000000000E0 -:10B0700000000000000000000000000000000000D0 -:10B0800000000000000000000000000000000000C0 -:10B0900000000000000000000000000000000000B0 -:10B0A00000000000000000000000000000000000A0 -:10B0B0000000000000000000000000000000000090 -:10B0C0000000000000000000000000000000000080 -:10B0D0000000000000000000000000000000000070 -:10B0E0000000000000000000000000000000000060 -:10B0F0000000000000000000000000000000000050 -:10B10000000000000000000000000000000000003F -:10B11000000000000000000000000000000000002F -:10B12000000000000000000000000000000000001F -:10B13000000000000000000000000000000000000F -:10B1400000000000000000000000000000000000FF -:10B1500000000000000000000000000000000000EF -:10B1600000000000000000000000000000000000DF -:10B1700000000000000000000000000000000000CF -:10B1800000000000000000000000000000000000BF -:10B1900000000000000000000000000000000000AF -:10B1A000000000000000000000000000000000009F -:10B1B000000000000000000000000000000000008F -:10B1C000000000000000000000000000000000007F -:10B1D000000000000000000000000000000000006F -:10B1E000000000000000000000000000000000005F -:10B1F000000000000000000000000000000000004F -:10B20000000000000000000000000000000000003E -:10B21000000000000000000000000000000000002E -:10B22000000000000000000000000000000000001E -:10B23000000000000000000000000000000000000E -:10B2400000000000000000000000000000000000FE -:10B2500000000000000000000000000000000000EE -:10B2600000000000000000000000000000000000DE -:10B2700000000000000000000000000000000000CE -:10B2800000000000000000000000000000000000BE -:10B2900000000000000000000000000000000000AE -:10B2A000000000000000000000000000000000009E -:10B2B000000000000000000000000000000000008E -:10B2C000000000000000000000000000000000007E -:10B2D000000000000000000000000000000000006E -:10B2E000000000000000000000000000000000005E -:10B2F000000000000000000000000000000000004E -:10B30000000000000000000000000000000000003D -:10B31000000000000000000000000000000000002D -:10B32000000000000000000000000000000000001D -:10B33000000000000000000000000000000000000D -:10B3400000000000000000000000000000000000FD -:10B3500000000000000000000000000000000000ED -:10B3600000000000000000000000000000000000DD -:10B3700000000000000000000000000000000000CD -:10B3800000000000000000000000000000000000BD -:10B3900000000000000000000000000000000000AD -:10B3A000000000000000000000000000000000009D -:10B3B000000000000000000000000000000000008D -:10B3C000000000000000000000000000000000007D -:10B3D000000000000000000000000000000000006D -:10B3E000000000000000000000000000000000005D -:10B3F000000000000000000000000000000000004D -:10B40000000000000000000000000000000000003C -:10B41000000000000000000000000000000000002C -:10B42000000000000000000000000000000000001C -:10B43000000000000000000000000000000000000C -:10B4400000000000000000000000000000000000FC -:10B4500000000000000000000000000000000000EC -:10B4600000000000000000000000000000000000DC -:10B4700000000000000000000000000000000000CC -:10B4800000000000000000000000000000000000BC -:10B4900000000000000000000000000000000000AC -:10B4A000000000000000000000000000000000009C -:10B4B000000000000000000000000000000000008C -:10B4C000000000000000000000000000000000007C -:10B4D000000000000000000000000000000000006C -:10B4E000000000000000000000000000000000005C -:10B4F000000000000000000000000000000000004C -:10B50000000000000000000000000000000000003B -:10B51000000000000000000000000000000000002B -:10B52000000000000000000000000000000000001B -:10B53000000000000000000000000000000000000B -:10B5400000000000000000000000000000000000FB -:10B5500000000000000000000000000000000000EB -:10B5600000000000000000000000000000000000DB -:10B5700000000000000000000000000000000000CB -:10B5800000000000000000000000000000000000BB -:10B5900000000000000000000000000000000000AB -:10B5A000000000000000000000000000000000009B -:10B5B000000000000000000000000000000000008B -:10B5C000000000000000000000000000000000007B -:10B5D000000000000000000000000000000000006B -:10B5E000000000000000000000000000000000005B -:10B5F000000000000000000000000000000000004B -:10B60000000000000000000000000000000000003A -:10B61000000000000000000000000000000000002A -:10B62000000000000000000000000000000000001A -:10B63000000000000000000000000000000000000A -:10B6400000000000000000000000000000000000FA -:10B6500000000000000000000000000000000000EA -:10B6600000000000000000000000000000000000DA -:10B6700000000000000000000000000000000000CA -:10B6800000000000000000000000000000000000BA -:10B6900000000000000000000000000000000000AA -:10B6A000000000000000000000000000000000009A -:10B6B000000000000000000000000000000000008A -:10B6C000000000000000000000000000000000007A -:10B6D000000000000000000000000000000000006A -:10B6E000000000000000000000000000000000005A -:10B6F000000000000000000000000000000000004A -:10B700000000000000000000000000000000000039 -:10B710000000000000000000000000000000000029 -:10B720000000000000000000000000000000000019 -:10B730000000000000000000000000000000000009 -:10B7400000000000000000000000000000000000F9 -:10B7500000000000000000000000000000000000E9 -:10B7600000000000000000000000000000000000D9 -:10B7700000000000000000000000000000000000C9 -:10B7800000000000000000000000000000000000B9 -:10B7900000000000000000000000000000000000A9 -:10B7A0000000000000000000000000000000000099 -:10B7B0000000000000000000000000000000000089 -:10B7C0000000000000000000000000000000000079 -:10B7D0000000000000000000000000000000000069 -:10B7E0000000000000000000000000000000000059 -:10B7F0000000000000000000000000000000000049 -:10B800000000000000000000000000000000000038 -:10B810000000000000000000000000000000000028 -:10B820000000000000000000000000000000000018 -:10B830000000000000000000000000000000000008 -:10B8400000000000000000000000000000000000F8 -:10B8500000000000000000000000000000000000E8 -:10B8600000000000000000000000000000000000D8 -:10B8700000000000000000000000000000000000C8 -:10B8800000000000000000000000000000000000B8 -:10B8900000000000000000000000000000000000A8 -:10B8A0000000000000000000000000000000000098 -:10B8B0000000000000000000000000000000000088 -:10B8C0000000000000000000000000000000000078 -:10B8D0000000000000000000000000000000000068 -:10B8E0000000000000000000000000000000000058 -:10B8F0000000000000000000000000000000000048 -:10B900000000000000000000000000000000000037 -:10B910000000000000000000000000000000000027 -:10B920000000000000000000000000000000000017 -:10B930000000000000000000000000000000000007 -:10B9400000000000000000000000000000000000F7 -:10B9500000000000000000000000000000000000E7 -:10B9600000000000000000000000000000000000D7 -:10B9700000000000000000000000000000000000C7 -:10B9800000000000000000000000000000000000B7 -:10B9900000000000000000000000000000000000A7 -:10B9A0000000000000000000000000000000000097 -:10B9B0000000000000000000000000000000000087 -:10B9C0000000000000000000000000000000000077 -:10B9D0000000000000000000000000000000000067 -:10B9E0000000000000000000000000000000000057 -:10B9F0000000000000000000000000000000000047 -:10BA00000000000000000000000000000000000036 -:10BA10000000000000000000000000000000000026 -:10BA20000000000000000000000000000000000016 -:10BA30000000000000000000000000000000000006 -:10BA400000000000000000000000000000000000F6 -:10BA500000000000000000000000000000000000E6 -:10BA600000000000000000000000000000000000D6 -:10BA700000000000000000000000000000000000C6 -:10BA800000000000000000000000000000000000B6 -:10BA900000000000000000000000000000000000A6 -:10BAA0000000000000000000000000000000000096 -:10BAB0000000000000000000000000000000000086 -:10BAC0000000000000000000000000000000000076 -:10BAD0000000000000000000000000000000000066 -:10BAE0000000000000000000000000000000000056 -:10BAF0000000000000000000000000000000000046 -:10BB00000000000000000000000000000000000035 -:10BB10000000000000000000000000000000000025 -:10BB20000000000000000000000000000000000015 -:10BB30000000000000000000000000000000000005 -:10BB400000000000000000000000000000000000F5 -:10BB500000000000000000000000000000000000E5 -:10BB600000000000000000000000000000000000D5 -:10BB700000000000000000000000000000000000C5 -:10BB800000000000000000000000000000000000B5 -:10BB900000000000000000000000000000000000A5 -:10BBA0000000000000000000000000000000000095 -:10BBB0000000000000000000000000000000000085 -:10BBC0000000000000000000000000000000000075 -:10BBD0000000000000000000000000000000000065 -:10BBE0000000000000000000000000000000000055 -:10BBF0000000000000000000000000000000000045 -:10BC00000000000000000000000000000000000034 -:10BC10000000000000000000000000000000000024 -:10BC20000000000000000000000000000000000014 -:10BC30000000000000000000000000000000000004 -:10BC400000000000000000000000000000000000F4 -:10BC500000000000000000000000000000000000E4 -:10BC600000000000000000000000000000000000D4 -:10BC700000000000000000000000000000000000C4 -:10BC800000000000000000000000000000000000B4 -:10BC900000000000000000000000000000000000A4 -:10BCA0000000000000000000000000000000000094 -:10BCB0000000000000000000000000000000000084 -:10BCC0000000000000000000000000000000000074 -:10BCD0000000000000000000000000000000000064 -:10BCE0000000000000000000000000000000000054 -:10BCF0000000000000000000000000000000000044 -:10BD00000000000000000000000000000000000033 -:10BD10000000000000000000000000000000000023 -:10BD20000000000000000000000000000000000013 -:10BD30000000000000000000000000000000000003 -:10BD400000000000000000000000000000000000F3 -:10BD500000000000000000000000000000000000E3 -:10BD600000000000000000000000000000000000D3 -:10BD700000000000000000000000000000000000C3 -:10BD800000000000000000000000000000000000B3 -:10BD900000000000000000000000000000000000A3 -:10BDA0000000000000000000000000000000000093 -:10BDB0000000000000000000000000000000000083 -:10BDC0000000000000000000000000000000000073 -:10BDD0000000000000000000000000000000000063 -:10BDE0000000000000000000000000000000000053 -:10BDF0000000000000000000000000000000000043 -:10BE00000000000000000000000000000000000032 -:10BE10000000000000000000000000000000000022 -:10BE20000000000000000000000000000000000012 -:10BE30000000000000000000000000000000000002 -:10BE400000000000000000000000000000000000F2 -:10BE500000000000000000000000000000000000E2 -:10BE600000000000000000000000000000000000D2 -:10BE700000000000000000000000000000000000C2 -:10BE800000000000000000000000000000000000B2 -:10BE900000000000000000000000000000000000A2 -:10BEA0000000000000000000000000000000000092 -:10BEB0000000000000000000000000000000000082 -:10BEC0000000000000000000000000000000000072 -:10BED0000000000000000000000000000000000062 -:10BEE0000000000000000000000000000000000052 -:10BEF0000000000000000000000000000000000042 -:10BF00000000000000000000000000000000000031 -:10BF10000000000000000000000000000000000021 -:10BF20000000000000000000000000000000000011 -:10BF30000000000000000000000000000000000001 -:10BF400000000000000000000000000000000000F1 -:10BF500000000000000000000000000000000000E1 -:10BF600000000000000000000000000000000000D1 -:10BF700000000000000000000000000000000000C1 -:10BF800000000000000000000000000000000000B1 -:10BF900000000000000000000000000000000000A1 -:10BFA0000000000000000000000000000000000091 -:10BFB0000000000000000000000000000000000081 -:10BFC0000000000000000000000000000000000071 -:10BFD0000000000000000000000000000000000061 -:10BFE0000000000000000000000000000000000051 -:10BFF0000000000000000000000000000000000041 -:10C000000000000000000000000000000000000030 -:10C010000000000000000000000000000000000020 -:10C020000000000000000000000000000000000010 -:10C030000000000000000000000000000000000000 -:10C0400000000000000000000000000000000000F0 -:10C0500000000000000000000000000000000000E0 -:10C0600000000000000000000000000000000000D0 -:10C0700000000000000000000000000000000000C0 -:10C0800000000000000000000000000000000000B0 -:10C0900000000000000000000000000000000000A0 -:10C0A0000000000000000000000000000000000090 -:10C0B0000000000000000000000000000000000080 -:10C0C0000000000000000000000000000000000070 -:10C0D0000000000000000000000000000000000060 -:10C0E0000000000000000000000000000000000050 -:10C0F0000000000000000000000000000000000040 -:10C10000000000000000000000000000000000002F -:10C11000000000000000000000000000000000001F -:10C12000000000000000000000000000000000000F -:10C1300000000000000000000000000000000000FF -:10C1400000000000000000000000000000000000EF -:10C1500000000000000000000000000000000000DF -:10C1600000000000000000000000000000000000CF -:10C1700000000000000000000000000000000000BF -:10C1800000000000000000000000000000000000AF -:10C19000000000000000000000000000000000009F -:10C1A000000000000000000000000000000000008F -:10C1B000000000000000000000000000000000007F -:10C1C000000000000000000000000000000000006F -:10C1D000000000000000000000000000000000005F -:10C1E000000000000000000000000000000000004F -:10C1F000000000000000000000000000000000003F -:10C20000000000000000000000000000000000002E -:10C21000000000000000000000000000000000001E -:10C22000000000000000000000000000000000000E -:10C2300000000000000000000000000000000000FE -:10C2400000000000000000000000000000000000EE -:10C2500000000000000000000000000000000000DE -:10C2600000000000000000000000000000000000CE -:10C2700000000000000000000000000000000000BE -:10C2800000000000000000000000000000000000AE -:10C29000000000000000000000000000000000009E -:10C2A000000000000000000000000000000000008E -:10C2B000000000000000000000000000000000007E -:10C2C000000000000000000000000000000000006E -:10C2D000000000000000000000000000000000005E -:10C2E000000000000000000000000000000000004E -:10C2F000000000000000000000000000000000003E -:10C30000000000000000000000000000000000002D -:10C31000000000000000000000000000000000001D -:10C32000000000000000000000000000000000000D -:10C3300000000000000000000000000000000000FD -:10C3400000000000000000000000000000000000ED -:10C3500000000000000000000000000000000000DD -:10C3600000000000000000000000000000000000CD -:10C3700000000000000000000000000000000000BD -:10C3800000000000000000000000000000000000AD -:10C39000000000000000000000000000000000009D -:10C3A000000000000000000000000000000000008D -:10C3B000000000000000000000000000000000007D -:10C3C000000000000000000000000000000000006D -:10C3D000000000000000000000000000000000005D -:10C3E000000000000000000000000000000000004D -:10C3F000000000000000000000000000000000003D -:10C40000000000000000000000000000000000002C -:10C41000000000000000000000000000000000001C -:10C42000000000000000000000000000000000000C -:10C4300000000000000000000000000000000000FC -:10C4400000000000000000000000000000000000EC -:10C4500000000000000000000000000000000000DC -:10C4600000000000000000000000000000000000CC -:10C4700000000000000000000000000000000000BC -:10C4800000000000000000000000000000000000AC -:10C49000000000000000000000000000000000009C -:10C4A000000000000000000000000000000000008C -:10C4B000000000000000000000000000000000007C -:10C4C000000000000000000000000000000000006C -:10C4D000000000000000000000000000000000005C -:10C4E000000000000000000000000000000000004C -:10C4F000000000000000000000000000000000003C -:10C50000000000000000000000000000000000002B -:10C51000000000000000000000000000000000001B -:10C52000000000000000000000000000000000000B -:10C5300000000000000000000000000000000000FB -:10C5400000000000000000000000000000000000EB -:10C5500000000000000000000000000000000000DB -:10C5600000000000000000000000000000000000CB -:10C5700000000000000000000000000000000000BB -:10C5800000000000000000000000000000000000AB -:10C59000000000000000000000000000000000009B -:10C5A000000000000000000000000000000000008B -:10C5B000000000000000000000000000000000007B -:10C5C000000000000000000000000000000000006B -:10C5D000000000000000000000000000000000005B -:10C5E000000000000000000000000000000000004B -:10C5F000000000000000000000000000000000003B -:10C60000000000000000000000000000000000002A -:10C61000000000000000000000000000000000001A -:10C62000000000000000000000000000000000000A -:10C6300000000000000000000000000000000000FA -:10C6400000000000000000000000000000000000EA -:10C6500000000000000000000000000000000000DA -:10C6600000000000000000000000000000000000CA -:10C6700000000000000000000000000000000000BA -:10C6800000000000000000000000000000000000AA -:10C69000000000000000000000000000000000009A -:10C6A000000000000000000000000000000000008A -:10C6B000000000000000000000000000000000007A -:10C6C000000000000000000000000000000000006A -:10C6D000000000000000000000000000000000005A -:10C6E000000000000000000000000000000000004A -:10C6F000000000000000000000000000000000003A -:10C700000000000000000000000000000000000029 -:10C710000000000000000000000000000000000019 -:10C720000000000000000000000000000000000009 -:10C7300000000000000000000000000000000000F9 -:10C7400000000000000000000000000000000000E9 -:10C7500000000000000000000000000000000000D9 -:10C7600000000000000000000000000000000000C9 -:10C7700000000000000000000000000000000000B9 -:10C7800000000000000000000000000000000000A9 -:10C790000000000000000000000000000000000099 -:10C7A0000000000000000000000000000000000089 -:10C7B0000000000000000000000000000000000079 -:10C7C0000000000000000000000000000000000069 -:10C7D0000000000000000000000000000000000059 -:10C7E0000000000000000000000000000000000049 -:10C7F0000000000000000000000000000000000039 -:10C800000000000000000000000000000000000028 -:10C810000000000000000000000000000000000018 -:10C820000000000000000000000000000000000008 -:10C8300000000000000000000000000000000000F8 -:10C8400000000000000000000000000000000000E8 -:10C8500000000000000000000000000000000000D8 -:10C8600000000000000000000000000000000000C8 -:10C8700000000000000000000000000000000000B8 -:10C8800000000000000000000000000000000000A8 -:10C890000000000000000000000000000000000098 -:10C8A0000000000000000000000000000000000088 -:10C8B0000000000000000000000000000000000078 -:10C8C0000000000000000000000000000000000068 -:10C8D0000000000000000000000000000000000058 -:10C8E0000000000000000000000000000000000048 -:10C8F0000000000000000000000000000000000038 -:10C900000000000000000000000000000000000027 -:10C910000000000000000000000000000000000017 -:10C920000000000000000000000000000000000007 -:10C9300000000000000000000000000000000000F7 -:10C9400000000000000000000000000000000000E7 -:10C9500000000000000000000000000000000000D7 -:10C9600000000000000000000000000000000000C7 -:10C9700000000000000000000000000000000000B7 -:10C9800000000000000000000000000000000000A7 -:10C990000000000000000000000000000000000097 -:10C9A0000000000000000000000000000000000087 -:10C9B0000000000000000000000000000000000077 -:10C9C0000000000000000000000000000000000067 -:10C9D0000000000000000000000000000000000057 -:10C9E0000000000000000000000000000000000047 -:10C9F0000000000000000000000000000000000037 -:10CA00000000000000000000000000000000000026 -:10CA10000000000000000000000000000000000016 -:10CA20000000000000000000000000000000000006 -:10CA300000000000000000000000000000000000F6 -:10CA400000000000000000000000000000000000E6 -:10CA500000000000000000000000000000000000D6 -:10CA600000000000000000000000000000000000C6 -:10CA700000000000000000000000000000000000B6 -:10CA800000000000000000000000000000000000A6 -:10CA90000000000000000000000000000000000096 -:10CAA0000000000000000000000000000000000086 -:10CAB0000000000000000000000000000000000076 -:10CAC0000000000000000000000000000000000066 -:10CAD0000000000000000000000000000000000056 -:10CAE0000000000000000000000000000000000046 -:10CAF0000000000000000000000000000000000036 -:10CB00000000000000000000000000000000000025 -:10CB10000000000000000000000000000000000015 -:10CB20000000000000000000000000000000000005 -:10CB300000000000000000000000000000000000F5 -:10CB400000000000000000000000000000000000E5 -:10CB500000000000000000000000000000000000D5 -:10CB600000000000000000000000000000000000C5 -:10CB700000000000000000000000000000000000B5 -:10CB800000000000000000000000000000000000A5 -:10CB90000000000000000000000000000000000095 -:10CBA0000000000000000000000000000000000085 -:10CBB0000000000000000000000000000000000075 -:10CBC0000000000000000000000000000000000065 -:10CBD0000000000000000000000000000000000055 -:10CBE0000000000000000000000000000000000045 -:10CBF0000000000000000000000000000000000035 -:10CC00000000000000000000000000000000000024 -:10CC10000000000000000000000000000000000014 -:10CC20000000000000000000000000000000000004 -:10CC300000000000000000000000000000000000F4 -:10CC400000000000000000000000000000000000E4 -:10CC500000000000000000000000000000000000D4 -:10CC600000000000000000000000000000000000C4 -:10CC700000000000000000000000000000000000B4 -:10CC800000000000000000000000000000000000A4 -:10CC90000000000000000000000000000000000094 -:10CCA0000000000000000000000000000000000084 -:10CCB0000000000000000000000000000000000074 -:10CCC0000000000000000000000000000000000064 -:10CCD0000000000000000000000000000000000054 -:10CCE0000000000000000000000000000000000044 -:10CCF0000000000000000000000000000000000034 -:10CD00000000000000000000000000000000000023 -:10CD10000000000000000000000000000000000013 -:10CD20000000000000000000000000000000000003 -:10CD300000000000000000000000000000000000F3 -:10CD400000000000000000000000000000000000E3 -:10CD500000000000000000000000000000000000D3 -:10CD600000000000000000000000000000000000C3 -:10CD700000000000000000000000000000000000B3 -:10CD800000000000000000000000000000000000A3 -:10CD90000000000000000000000000000000000093 -:10CDA0000000000000000000000000000000000083 -:10CDB0000000000000000000000000000000000073 -:10CDC0000000000000000000000000000000000063 -:10CDD0000000000000000000000000000000000053 -:10CDE0000000000000000000000000000000000043 -:10CDF0000000000000000000000000000000000033 -:10CE00000000000000000000000000000000000022 -:10CE10000000000000000000000000000000000012 -:10CE20000000000000000000000000000000000002 -:10CE300000000000000000000000000000000000F2 -:10CE400000000000000000000000000000000000E2 -:10CE500000000000000000000000000000000000D2 -:10CE600000000000000000000000000000000000C2 -:10CE700000000000000000000000000000000000B2 -:10CE800000000000000000000000000000000000A2 -:10CE90000000000000000000000000000000000092 -:10CEA0000000000000000000000000000000000082 -:10CEB0000000000000000000000000000000000072 -:10CEC0000000000000000000000000000000000062 -:10CED0000000000000000000000000000000000052 -:10CEE0000000000000000000000000000000000042 -:10CEF0000000000000000000000000000000000032 -:10CF00000000000000000000000000000000000021 -:10CF10000000000000000000000000000000000011 -:10CF20000000000000000000000000000000000001 -:10CF300000000000000000000000000000000000F1 -:10CF400000000000000000000000000000000000E1 -:10CF500000000000000000000000000000000000D1 -:10CF600000000000000000000000000000000000C1 -:10CF700000000000000000000000000000000000B1 -:10CF800000000000000000000000000000000000A1 -:10CF90000000000000000000000000000000000091 -:10CFA0000000000000000000000000000000000081 -:10CFB0000000000000000000000000000000000071 -:10CFC0000000000000000000000000000000000061 -:10CFD0000000000000000000000000000000000051 -:10CFE0000000000000000000000000000000000041 -:10CFF0000000000000000000000000000000000031 -:10D000000000000000000000000000000000000020 -:10D010000000000000000000000000000000000010 -:10D020000000000000000000000000000000000000 -:10D0300000000000000000000000000000000000F0 -:10D0400000000000000000000000000000000000E0 -:10D0500000000000000000000000000000000000D0 -:10D0600000000000000000000000000000000000C0 -:10D0700000000000000000000000000000000000B0 -:10D0800000000000000000000000000000000000A0 -:10D090000000000000000000000000000000000090 -:10D0A0000000000000000000000000000000000080 -:10D0B0000000000000000000000000000000000070 -:10D0C0000000000000000000000000000000000060 -:10D0D0000000000000000000000000000000000050 -:10D0E0000000000000000000000000000000000040 -:10D0F0000000000000000000000000000000000030 -:10D10000000000000000000000000000000000001F -:10D11000000000000000000000000000000000000F -:10D1200000000000000000000000000000000000FF -:10D1300000000000000000000000000000000000EF -:10D1400000000000000000000000000000000000DF -:10D1500000000000000000000000000000000000CF -:10D1600000000000000000000000000000000000BF -:10D1700000000000000000000000000000000000AF -:10D18000000000000000000000000000000000009F -:10D19000000000000000000000000000000000008F -:10D1A000000000000000000000000000000000007F -:10D1B000000000000000000000000000000000006F -:10D1C000000000000000000000000000000000005F -:10D1D000000000000000000000000000000000004F -:10D1E000000000000000000000000000000000003F -:10D1F000000000000000000000000000000000002F -:10D20000000000000000000000000000000000001E -:10D21000000000000000000000000000000000000E -:10D2200000000000000000000000000000000000FE -:10D2300000000000000000000000000000000000EE -:10D2400000000000000000000000000000000000DE -:10D2500000000000000000000000000000000000CE -:10D2600000000000000000000000000000000000BE -:10D2700000000000000000000000000000000000AE -:10D28000000000000000000000000000000000009E -:10D29000000000000000000000000000000000008E -:10D2A000000000000000000000000000000000007E -:10D2B000000000000000000000000000000000006E -:10D2C000000000000000000000000000000000005E -:10D2D000000000000000000000000000000000004E -:10D2E000000000000000000000000000000000003E -:10D2F000000000000000000000000000000000002E -:10D30000000000000000000000000000000000001D -:10D31000000000000000000000000000000000000D -:10D3200000000000000000000000000000000000FD -:10D3300000000000000000000000000000000000ED -:10D3400000000000000000000000000000000000DD -:10D3500000000000000000000000000000000000CD -:10D3600000000000000000000000000000000000BD -:10D3700000000000000000000000000000000000AD -:10D38000000000000000000000000000000000009D -:10D39000000000000000000000000000000000008D -:10D3A000000000000000000000000000000000007D -:10D3B000000000000000000000000000000000006D -:10D3C000000000000000000000000000000000005D -:10D3D000000000000000000000000000000000004D -:10D3E000000000000000000000000000000000003D -:10D3F000000000000000000000000000000000002D -:10D40000000000000000000000000000000000001C -:10D41000000000000000000000000000000000000C -:10D4200000000000000000000000000000000000FC -:10D4300000000000000000000000000000000000EC -:10D4400000000000000000000000000000000000DC -:10D4500000000000000000000000000000000000CC -:10D4600000000000000000000000000000000000BC -:10D4700000000000000000000000000000000000AC -:10D48000000000000000000000000000000000009C -:10D49000000000000000000000000000000000008C -:10D4A000000000000000000000000000000000007C -:10D4B000000000000000000000000000000000006C -:10D4C000000000000000000000000000000000005C -:10D4D000000000000000000000000000000000004C -:10D4E000000000000000000000000000000000003C -:10D4F000000000000000000000000000000000002C -:10D50000000000000000000000000000000000001B -:10D51000000000000000000000000000000000000B -:10D5200000000000000000000000000000000000FB -:10D5300000000000000000000000000000000000EB -:10D5400000000000000000000000000000000000DB -:10D5500000000000000000000000000000000000CB -:10D5600000000000000000000000000000000000BB -:10D5700000000000000000000000000000000000AB -:10D58000000000000000000000000000000000009B -:10D59000000000000000000000000000000000008B -:10D5A000000000000000000000000000000000007B -:10D5B000000000000000000000000000000000006B -:10D5C000000000000000000000000000000000005B -:10D5D000000000000000000000000000000000004B -:10D5E000000000000000000000000000000000003B -:10D5F000000000000000000000000000000000002B -:10D60000000000000000000000000000000000001A -:10D61000000000000000000000000000000000000A -:10D6200000000000000000000000000000000000FA -:10D6300000000000000000000000000000000000EA -:10D6400000000000000000000000000000000000DA -:10D6500000000000000000000000000000000000CA -:10D6600000000000000000000000000000000000BA -:10D6700000000000000000000000000000000000AA -:10D68000000000000000000000000000000000009A -:10D69000000000000000000000000000000000008A -:10D6A000000000000000000000000000000000007A -:10D6B000000000000000000000000000000000006A -:10D6C000000000000000000000000000000000005A -:10D6D000000000000000000000000000000000004A -:10D6E000000000000000000000000000000000003A -:10D6F000000000000000000000000000000000002A -:10D700000000000000000000000000000000000019 -:10D710000000000000000000000000000000000009 -:10D7200000000000000000000000000000000000F9 -:10D7300000000000000000000000000000000000E9 -:10D7400000000000000000000000000000000000D9 -:10D7500000000000000000000000000000000000C9 -:10D7600000000000000000000000000000000000B9 -:10D7700000000000000000000000000000000000A9 -:10D780000000000000000000000000000000000099 -:10D790000000000000000000000000000000000089 -:10D7A0000000000000000000000000000000000079 -:10D7B0000000000000000000000000000000000069 -:10D7C0000000000000000000000000000000000059 -:10D7D0000000000000000000000000000000000049 -:10D7E0000000000000000000000000000000000039 -:10D7F0000000000000000000000000000000000029 -:10D800000000000000000000000000000000000018 -:10D810000000000000000000000000000000000008 -:10D8200000000000000000000000000000000000F8 -:10D8300000000000000000000000000000000000E8 -:10D8400000000000000000000000000000000000D8 -:10D8500000000000000000000000000000000000C8 -:10D8600000000000000000000000000000000000B8 -:10D8700000000000000000000000000000000000A8 -:10D880000000000000000000000000000000000098 -:10D890000000000000000000000000000000000088 -:10D8A0000000000000000000000000000000000078 -:10D8B0000000000000000000000000000000000068 -:10D8C0000000000000000000000000000000000058 -:10D8D0000000000000000000000000000000000048 -:10D8E0000000000000000000000000000000000038 -:10D8F0000000000000000000000000000000000028 -:10D900000000000000000000000000000000000017 -:10D910000000000000000000000000000000000007 -:10D9200000000000000000000000000000000000F7 -:10D9300000000000000000000000000000000000E7 -:10D9400000000000000000000000000000000000D7 -:10D9500000000000000000000000000000000000C7 -:10D9600000000000000000000000000000000000B7 -:10D9700000000000000000000000000000000000A7 -:10D980000000000000000000000000000000000097 -:10D990000000000000000000000000000000000087 -:10D9A0000000000000000000000000000000000077 -:10D9B0000000000000000000000000000000000067 -:10D9C0000000000000000000000000000000000057 -:10D9D0000000000000000000000000000000000047 -:10D9E0000000000000000000000000000000000037 -:10D9F0000000000000000000000000000000000027 -:10DA00000000000000000000000000000000000016 -:10DA10000000000000000000000000000000000006 -:10DA200000000000000000000000000000000000F6 -:10DA300000000000000000000000000000000000E6 -:10DA400000000000000000000000000000000000D6 -:10DA500000000000000000000000000000000000C6 -:10DA600000000000000000000000000000000000B6 -:10DA700000000000000000000000000000000000A6 -:10DA80000000000000000000000000000000000096 -:10DA90000000000000000000000000000000000086 -:10DAA0000000000000000000000000000000000076 -:10DAB0000000000000000000000000000000000066 -:10DAC0000000000000000000000000000000000056 -:10DAD0000000000000000000000000000000000046 -:10DAE0000000000000000000000000000000000036 -:10DAF0000000000000000000000000000000000026 -:10DB00000000000000000000000000000000000015 -:10DB10000000000000000000000000000000000005 -:10DB200000000000000000000000000000000000F5 -:10DB300000000000000000000000000000000000E5 -:10DB400000000000000000000000000000000000D5 -:10DB500000000000000000000000000000000000C5 -:10DB600000000000000000000000000000000000B5 -:10DB700000000000000000000000000000000000A5 -:10DB80000000000000000000000000000000000095 -:10DB90000000000000000000000000000000000085 -:10DBA0000000000000000000000000000000000075 -:10DBB0000000000000000000000000000000000065 -:10DBC0000000000000000000000000000000000055 -:10DBD0000000000000000000000000000000000045 -:10DBE0000000000000000000000000000000000035 -:10DBF0000000000000000000000000000000000025 -:10DC00000000000000000000000000000000000014 -:10DC10000000000000000000000000000000000004 -:10DC200000000000000000000000000000000000F4 -:10DC300000000000000000000000000000000000E4 -:10DC400000000000000000000000000000000000D4 -:10DC500000000000000000000000000000000000C4 -:10DC600000000000000000000000000000000000B4 -:10DC700000000000000000000000000000000000A4 -:10DC80000000000000000000000000000000000094 -:10DC90000000000000000000000000000000000084 -:10DCA0000000000000000000000000000000000074 -:10DCB0000000000000000000000000000000000064 -:10DCC0000000000000000000000000000000000054 -:10DCD0000000000000000000000000000000000044 -:10DCE0000000000000000000000000000000000034 -:10DCF0000000000000000000000000000000000024 -:10DD00000000000000000000000000000000000013 -:10DD10000000000000000000000000000000000003 -:10DD200000000000000000000000000000000000F3 -:10DD300000000000000000000000000000000000E3 -:10DD400000000000000000000000000000000000D3 -:10DD500000000000000000000000000000000000C3 -:10DD600000000000000000000000000000000000B3 -:10DD700000000000000000000000000000000000A3 -:10DD80000000000000000000000000000000000093 -:10DD90000000000000000000000000000000000083 -:10DDA0000000000000000000000000000000000073 -:10DDB0000000000000000000000000000000000063 -:10DDC0000000000000000000000000000000000053 -:10DDD0000000000000000000000000000000000043 -:10DDE0000000000000000000000000000000000033 -:10DDF0000000000000000000000000000000000023 -:10DE00000000000000000000000000000000000012 -:10DE10000000000000000000000000000000000002 -:10DE200000000000000000000000000000000000F2 -:10DE300000000000000000000000000000000000E2 -:10DE400000000000000000000000000000000000D2 -:10DE500000000000000000000000000000000000C2 -:10DE600000000000000000000000000000000000B2 -:10DE700000000000000000000000000000000000A2 -:10DE80000000000000000000000000000000000092 -:10DE90000000000000000000000000000000000082 -:10DEA0000000000000000000000000000000000072 -:10DEB0000000000000000000000000000000000062 -:10DEC0000000000000000000000000000000000052 -:10DED0000000000000000000000000000000000042 -:10DEE0000000000000000000000000000000000032 -:10DEF0000000000000000000000000000000000022 -:10DF00000000000000000000000000000000000011 -:10DF10000000000000000000000000000000000001 -:10DF200000000000000000000000000000000000F1 -:10DF300000000000000000000000000000000000E1 -:10DF400000000000000000000000000000000000D1 -:10DF500000000000000000000000000000000000C1 -:10DF600000000000000000000000000000000000B1 -:10DF700000000000000000000000000000000000A1 -:10DF80000000000000000000000000000000000091 -:10DF90000000000000000000000000000000000081 -:10DFA0000000000000000000000000000000000071 -:10DFB0000000000000000000000000000000000061 -:10DFC0000000000000000000000000000000000051 -:10DFD0000000000000000000000000000000000041 -:10DFE0000000000000000000000000000000000031 -:10DFF0000000000000000000000000000000000021 -:10E000000000000000000000000000000000000010 -:10E010000000000000000000000000000000000000 -:10E0200000000000000000000000000000000000F0 -:10E0300000000000000000000000000000000000E0 -:10E0400000000000000000000000000000000000D0 -:10E0500000000000000000000000000000000000C0 -:10E0600000000000000000000000000000000000B0 -:10E0700000000000000000000000000000000000A0 -:10E080000000000000000000000000000000000090 -:10E090000000000000000000000000000000000080 -:10E0A0000000000000000000000000000000000070 -:10E0B0000000000000000000000000000000000060 -:10E0C0000000000000000000000000000000000050 -:10E0D0000000000000000000000000000000000040 -:10E0E0000000000000000000000000000000000030 -:10E0F0000000000000000000000000000000000020 -:10E10000000000000000000000000000000000000F -:10E1100000000000000000000000000000000000FF -:10E1200000000000000000000000000000000000EF -:10E1300000000000000000000000000000000000DF -:10E1400000000000000000000000000000000000CF -:10E1500000000000000000000000000000000000BF -:10E1600000000000000000000000000000000000AF -:10E17000000000000000000000000000000000009F -:10E18000000000000000000000000000000000008F -:10E19000000000000000000000000000000000007F -:10E1A000000000000000000000000000000000006F -:10E1B000000000000000000000000000000000005F -:10E1C000000000000000000000000000000000004F -:10E1D000000000000000000000000000000000003F -:10E1E000000000000000000000000000000000002F -:10E1F000000000000000000000000000000000001F -:10E20000000000000000000000000000000000000E -:10E2100000000000000000000000000000000000FE -:10E2200000000000000000000000000000000000EE -:10E2300000000000000000000000000000000000DE -:10E2400000000000000000000000000000000000CE -:10E2500000000000000000000000000000000000BE -:10E2600000000000000000000000000000000000AE -:10E27000000000000000000000000000000000009E -:10E28000000000000000000000000000000000008E -:10E29000000000000000000000000000000000007E -:10E2A000000000000000000000000000000000006E -:10E2B000000000000000000000000000000000005E -:10E2C000000000000000000000000000000000004E -:10E2D000000000000000000000000000000000003E -:10E2E000000000000000000000000000000000002E -:10E2F000000000000000000000000000000000001E -:10E30000000000000000000000000000000000000D -:10E3100000000000000000000000000000000000FD -:10E3200000000000000000000000000000000000ED -:10E3300000000000000000000000000000000000DD -:10E3400000000000000000000000000000000000CD -:10E3500000000000000000000000000000000000BD -:10E3600000000000000000000000000000000000AD -:10E37000000000000000000000000000000000009D -:10E38000000000000000000000000000000000008D -:10E39000000000000000000000000000000000007D -:10E3A000000000000000000000000000000000006D -:10E3B000000000000000000000000000000000005D -:10E3C000000000000000000000000000000000004D -:10E3D000000000000000000000000000000000003D -:10E3E000000000000000000000000000000000002D -:10E3F000000000000000000000000000000000001D -:10E40000000000000000000000000000000000000C -:10E4100000000000000000000000000000000000FC -:10E4200000000000000000000000000000000000EC -:10E4300000000000000000000000000000000000DC -:10E4400000000000000000000000000000000000CC -:10E4500000000000000000000000000000000000BC -:10E4600000000000000000000000000000000000AC -:10E47000000000000000000000000000000000009C -:10E48000000000000000000000000000000000008C -:10E49000000000000000000000000000000000007C -:10E4A000000000000000000000000000000000006C -:10E4B000000000000000000000000000000000005C -:10E4C000000000000000000000000000000000004C -:10E4D000000000000000000000000000000000003C -:10E4E000000000000000000000000000000000002C -:10E4F000000000000000000000000000000000001C -:10E50000000000000000000000000000000000000B -:10E5100000000000000000000000000000000000FB -:10E5200000000000000000000000000000000000EB -:10E5300000000000000000000000000000000000DB -:10E5400000000000000000000000000000000000CB -:10E5500000000000000000000000000000000000BB -:10E5600000000000000000000000000000000000AB -:10E57000000000000000000000000000000000009B -:10E58000000000000000000000000000000000008B -:10E59000000000000000000000000000000000007B -:10E5A000000000000000000000000000000000006B -:10E5B000000000000000000000000000000000005B -:10E5C000000000000000000000000000000000004B -:10E5D000000000000000000000000000000000003B -:10E5E000000000000000000000000000000000002B -:10E5F000000000000000000000000000000000001B -:10E60000000000000000000000000000000000000A -:10E6100000000000000000000000000000000000FA -:10E6200000000000000000000000000000000000EA -:10E6300000000000000000000000000000000000DA -:10E6400000000000000000000000000000000000CA -:10E6500000000000000000000000000000000000BA -:10E6600000000000000000000000000000000000AA -:10E67000000000000000000000000000000000009A -:10E68000000000000000000000000000000000008A -:10E69000000000000000000000000000000000007A -:10E6A000000000000000000000000000000000006A -:10E6B000000000000000000000000000000000005A -:10E6C000000000000000000000000000000000004A -:10E6D000000000000000000000000000000000003A -:10E6E000000000000000000000000000000000002A -:10E6F000000000000000000000000000000000001A -:10E700000000000000000000000000000000000009 -:10E7100000000000000000000000000000000000F9 -:10E7200000000000000000000000000000000000E9 -:10E7300000000000000000000000000000000000D9 -:10E7400000000000000000000000000000000000C9 -:10E7500000000000000000000000000000000000B9 -:10E7600000000000000000000000000000000000A9 -:10E770000000000000000000000000000000000099 -:10E780000000000000000000000000000000000089 -:10E790000000000000000000000000000000000079 -:10E7A0000000000000000000000000000000000069 -:10E7B0000000000000000000000000000000000059 -:10E7C0000000000000000000000000000000000049 -:10E7D0000000000000000000000000000000000039 -:10E7E0000000000000000000000000000000000029 -:10E7F0000000000000000000000000000000000019 -:10E800000000000000000000000000000000000008 -:10E8100000000000000000000000000000000000F8 -:10E8200000000000000000000000000000000000E8 -:10E8300000000000000000000000000000000000D8 -:10E8400000000000000000000000000000000000C8 -:10E8500000000000000000000000000000000000B8 -:10E8600000000000000000000000000000000000A8 -:10E870000000000000000000000000000000000098 -:10E880000000000000000000000000000000000088 -:10E890000000000000000000000000000000000078 -:10E8A0000000000000000000000000000000000068 -:10E8B0000000000000000000000000000000000058 -:10E8C0000000000000000000000000000000000048 -:10E8D0000000000000000000000000000000000038 -:10E8E0000000000000000000000000000000000028 -:10E8F0000000000000000000000000000000000018 -:10E900000000000000000000000000000000000007 -:10E9100000000000000000000000000000000000F7 -:10E9200000000000000000000000000000000000E7 -:10E9300000000000000000000000000000000000D7 -:10E9400000000000000000000000000000000000C7 -:10E9500000000000000000000000000000000000B7 -:10E9600000000000000000000000000000000000A7 -:10E970000000000000000000000000000000000097 -:10E980000000000000000000000000000000000087 -:10E990000000000000000000000000000000000077 -:10E9A0000000000000000000000000000000000067 -:10E9B0000000000000000000000000000000000057 -:10E9C0000000000000000000000000000000000047 -:10E9D0000000000000000000000000000000000037 -:10E9E0000000000000000000000000000000000027 -:10E9F0000000000000000000000000000000000017 -:10EA00000000000000000000000000000000000006 -:10EA100000000000000000000000000000000000F6 -:10EA200000000000000000000000000000000000E6 -:10EA300000000000000000000000000000000000D6 -:10EA400000000000000000000000000000000000C6 -:10EA500000000000000000000000000000000000B6 -:10EA600000000000000000000000000000000000A6 -:10EA70000000000000000000000000000000000096 -:10EA80000000000000000000000000000000000086 -:10EA90000000000000000000000000000000000076 -:10EAA0000000000000000000000000000000000066 -:10EAB0000000000000000000000000000000000056 -:10EAC0000000000000000000000000000000000046 -:10EAD0000000000000000000000000000000000036 -:10EAE0000000000000000000000000000000000026 -:10EAF0000000000000000000000000000000000016 -:10EB00000000000000000000000000000000000005 -:10EB100000000000000000000000000000000000F5 -:10EB200000000000000000000000000000000000E5 -:10EB300000000000000000000000000000000000D5 -:10EB400000000000000000000000000000000000C5 -:10EB500000000000000000000000000000000000B5 -:10EB600000000000000000000000000000000000A5 -:10EB70000000000000000000000000000000000095 -:10EB80000000000000000000000000000000000085 -:10EB90000000000000000000000000000000000075 -:10EBA0000000000000000000000000000000000065 -:10EBB0000000000000000000000000000000000055 -:10EBC0000000000000000000000000000000000045 -:10EBD0000000000000000000000000000000000035 -:10EBE0000000000000000000000000000000000025 -:10EBF0000000000000000000000000000000000015 -:10EC00000000000000000000000000000000000004 -:10EC100000000000000000000000000000000000F4 -:10EC200000000000000000000000000000000000E4 -:10EC300000000000000000000000000000000000D4 -:10EC400000000000000000000000000000000000C4 -:10EC500000000000000000000000000000000000B4 -:10EC600000000000000000000000000000000000A4 -:10EC70000000000000000000000000000000000094 -:10EC80000000000000000000000000000000000084 -:10EC90000000000000000000000000000000000074 -:10ECA0000000000000000000000000000000000064 -:10ECB0000000000000000000000000000000000054 -:10ECC0000000000000000000000000000000000044 -:10ECD0000000000000000000000000000000000034 -:10ECE0000000000000000000000000000000000024 -:10ECF0000000000000000000000000000000000014 -:10ED00000000000000000000000000000000000003 -:10ED100000000000000000000000000000000000F3 -:10ED200000000000000000000000000000000000E3 -:10ED300000000000000000000000000000000000D3 -:10ED400000000000000000000000000000000000C3 -:10ED500000000000000000000000000000000000B3 -:10ED600000000000000000000000000000000000A3 -:10ED70000000000000000000000000000000000093 -:10ED80000000000000000000000000000000000083 -:10ED90000000000000000000000000000000000073 -:10EDA0000000000000000000000000000000000063 -:10EDB0000000000000000000000000000000000053 -:10EDC0000000000000000000000000000000000043 -:10EDD0000000000000000000000000000000000033 -:10EDE0000000000000000000000000000000000023 -:10EDF0000000000000000000000000000000000013 -:10EE00000000000000000000000000000000000002 -:10EE100000000000000000000000000000000000F2 -:10EE200000000000000000000000000000000000E2 -:10EE300000000000000000000000000000000000D2 -:10EE400000000000000000000000000000000000C2 -:10EE500000000000000000000000000000000000B2 -:10EE600000000000000000000000000000000000A2 -:10EE70000000000000000000000000000000000092 -:10EE80000000000000000000000000000000000082 -:10EE90000000000000000000000000000000000072 -:10EEA0000000000000000000000000000000000062 -:10EEB0000000000000000000000000000000000052 -:10EEC0000000000000000000000000000000000042 -:10EED0000000000000000000000000000000000032 -:10EEE0000000000000000000000000000000000022 -:10EEF0000000000000000000000000000000000012 -:10EF00000000000000000000000000000000000001 -:10EF100000000000000000000000000000000000F1 -:10EF200000000000000000000000000000000000E1 -:10EF300000000000000000000000000000000000D1 -:10EF400000000000000000000000000000000000C1 -:10EF500000000000000000000000000000000000B1 -:10EF600000000000000000000000000000000000A1 -:10EF70000000000000000000000000000000000091 -:10EF80000000000000000000000000000000000081 -:10EF90000000000000000000000000000000000071 -:10EFA0000000000000000000000000000000000061 -:10EFB0000000000000000000000000000000000051 -:10EFC0000000000000000000000000000000000041 -:10EFD0000000000000000000000000000000000031 -:10EFE0000000000000000000000000000000000021 -:10EFF0000000000000000000000000000000000011 -:10F000000000000000000000000000000000000000 -:10F0100000000000000000000000000000000000F0 -:10F0200000000000000000000000000000000000E0 -:10F0300000000000000000000000000000000000D0 -:10F0400000000000000000000000000000000000C0 -:10F0500000000000000000000000000000000000B0 -:10F0600000000000000000000000000000000000A0 -:10F070000000000000000000000000000000000090 -:10F080000000000000000000000000000000000080 -:10F090000000000000000000000000000000000070 -:10F0A0000000000000000000000000000000000060 -:10F0B0000000000000000000000000000000000050 -:10F0C0000000000000000000000000000000000040 -:10F0D0000000000000000000000000000000000030 -:10F0E0000000000000000000000000000000000020 -:10F0F0000000000000000000000000000000000010 -:10F1000000000000000000000000000000000000FF -:10F1100000000000000000000000000000000000EF -:10F1200000000000000000000000000000000000DF -:10F1300000000000000000000000000000000000CF -:10F1400000000000000000000000000000000000BF -:10F1500000000000000000000000000000000000AF -:10F16000000000000000000000000000000000009F -:10F17000000000000000000000000000000000008F -:10F18000000000000000000000000000000000007F -:10F19000000000000000000000000000000000006F -:10F1A000000000000000000000000000000000005F -:10F1B000000000000000000000000000000000004F -:10F1C000000000000000000000000000000000003F -:10F1D000000000000000000000000000000000002F -:10F1E000000000000000000000000000000000001F -:10F1F000000000000000000000000000000000000F -:10F2000000000000000000000000000000000000FE -:10F2100000000000000000000000000000000000EE -:10F2200000000000000000000000000000000000DE -:10F2300000000000000000000000000000000000CE -:10F2400000000000000000000000000000000000BE -:10F2500000000000000000000000000000000000AE -:10F26000000000000000000000000000000000009E -:10F27000000000000000000000000000000000008E -:10F28000000000000000000000000000000000007E -:10F29000000000000000000000000000000000006E -:10F2A000000000000000000000000000000000005E -:10F2B000000000000000000000000000000000004E -:10F2C000000000000000000000000000000000003E -:10F2D000000000000000000000000000000000002E -:10F2E000000000000000000000000000000000001E -:10F2F000000000000000000000000000000000000E -:10F3000000000000000000000000000000000000FD -:10F3100000000000000000000000000000000000ED -:10F3200000000000000000000000000000000000DD -:10F3300000000000000000000000000000000000CD -:10F3400000000000000000000000000000000000BD -:10F3500000000000000000000000000000000000AD -:10F36000000000000000000000000000000000009D -:10F37000000000000000000000000000000000008D -:10F38000000000000000000000000000000000007D -:10F39000000000000000000000000000000000006D -:10F3A000000000000000000000000000000000005D -:10F3B000000000000000000000000000000000004D -:10F3C000000000000000000000000000000000003D -:10F3D000000000000000000000000000000000002D -:10F3E000000000000000000000000000000000001D -:10F3F000000000000000000000000000000000000D -:10F4000000000000000000000000000000000000FC -:10F4100000000000000000000000000000000000EC -:10F4200000000000000000000000000000000000DC -:10F4300000000000000000000000000000000000CC -:10F4400000000000000000000000000000000000BC -:10F4500000000000000000000000000000000000AC -:10F46000000000000000000000000000000000009C -:10F47000000000000000000000000000000000008C -:10F48000000000000000000000000000000000007C -:10F49000000000000000000000000000000000006C -:10F4A000000000000000000000000000000000005C -:10F4B000000000000000000000000000000000004C -:10F4C000000000000000000000000000000000003C -:10F4D000000000000000000000000000000000002C -:10F4E000000000000000000000000000000000001C -:10F4F000000000000000000000000000000000000C -:10F5000000000000000000000000000000000000FB -:10F5100000000000000000000000000000000000EB -:10F5200000000000000000000000000000000000DB -:10F5300000000000000000000000000000000000CB -:10F5400000000000000000000000000000000000BB -:10F5500000000000000000000000000000000000AB -:10F56000000000000000000000000000000000009B -:10F57000000000000000000000000000000000008B -:10F58000000000000000000000000000000000007B -:10F59000000000000000000000000000000000006B -:10F5A000000000000000000000000000000000005B -:10F5B000000000000000000000000000000000004B -:10F5C000000000000000000000000000000000003B -:10F5D000000000000000000000000000000000002B -:10F5E000000000000000000000000000000000001B -:10F5F000000000000000000000000000000000000B -:10F6000000000000000000000000000000000000FA -:10F6100000000000000000000000000000000000EA -:10F6200000000000000000000000000000000000DA -:10F6300000000000000000000000000000000000CA -:10F6400000000000000000000000000000000000BA -:10F6500000000000000000000000000000000000AA -:10F66000000000000000000000000000000000009A -:10F67000000000000000000000000000000000008A -:10F68000000000000000000000000000000000007A -:10F69000000000000000000000000000000000006A -:10F6A000000000000000000000000000000000005A -:10F6B000000000000000000000000000000000004A -:10F6C000000000000000000000000000000000003A -:10F6D000000000000000000000000000000000002A -:10F6E000000000000000000000000000000000001A -:10F6F000000000000000000000000000000000000A -:10F7000000000000000000000000000000000000F9 -:10F7100000000000000000000000000000000000E9 -:10F7200000000000000000000000000000000000D9 -:10F7300000000000000000000000000000000000C9 -:10F7400000000000000000000000000000000000B9 -:10F7500000000000000000000000000000000000A9 -:10F760000000000000000000000000000000000099 -:10F770000000000000000000000000000000000089 -:10F780000000000000000000000000000000000079 -:10F790000000000000000000000000000000000069 -:10F7A0000000000000000000000000000000000059 -:10F7B0000000000000000000000000000000000049 -:10F7C0000000000000000000000000000000000039 -:10F7D0000000000000000000000000000000000029 -:10F7E0000000000000000000000000000000000019 -:10F7F0000000000000000000000000000000000009 -:10F8000000000000000000000000000000000000F8 -:10F8100000000000000000000000000000000000E8 -:10F8200000000000000000000000000000000000D8 -:10F8300000000000000000000000000000000000C8 -:10F8400000000000000000000000000000000000B8 -:10F8500000000000000000000000000000000000A8 -:10F860000000000000000000000000000000000098 -:10F870000000000000000000000000000000000088 -:10F880000000000000000000000000000000000078 -:10F890000000000000000000000000000000000068 -:10F8A0000000000000000000000000000000000058 -:10F8B0000000000000000000000000000000000048 -:10F8C0000000000000000000000000000000000038 -:10F8D0000000000000000000000000000000000028 -:10F8E0000000000000000000000000000000000018 -:10F8F0000000000000000000000000000000000008 -:10F9000000000000000000000000000000000000F7 -:10F9100000000000000000000000000000000000E7 -:10F9200000000000000000000000000000000000D7 -:10F9300000000000000000000000000000000000C7 -:10F9400000000000000000000000000000000000B7 -:10F9500000000000000000000000000000000000A7 -:10F960000000000000000000000000000000000097 -:10F970000000000000000000000000000000000087 -:10F980000000000000000000000000000000000077 -:10F990000000000000000000000000000000000067 -:10F9A0000000000000000000000000000000000057 -:10F9B0000000000000000000000000000000000047 -:10F9C0000000000000000000000000000000000037 -:10F9D0000000000000000000000000000000000027 -:10F9E0000000000000000000000000000000000017 -:10F9F0000000000000000000000000000000000007 -:10FA000000000000000000000000000000000000F6 -:10FA100000000000000000000000000000000000E6 -:10FA200000000000000000000000000000000000D6 -:10FA300000000000000000000000000000000000C6 -:10FA400000000000000000000000000000000000B6 -:10FA500000000000000000000000000000000000A6 -:10FA60000000000000000000000000000000000096 -:10FA70000000000000000000000000000000000086 -:10FA80000000000000000000000000000000000076 -:10FA90000000000000000000000000000000000066 -:10FAA0000000000000000000000000000000000056 -:10FAB0000000000000000000000000000000000046 -:10FAC0000000000000000000000000000000000036 -:10FAD0000000000000000000000000000000000026 -:10FAE0000000000000000000000000000000000016 -:10FAF0000000000000000000000000000000000006 -:10FB000000000000000000000000000000000000F5 -:10FB100000000000000000000000000000000000E5 -:10FB200000000000000000000000000000000000D5 -:10FB300000000000000000000000000000000000C5 -:10FB400000000000000000000000000000000000B5 -:10FB500000000000000000000000000000000000A5 -:10FB60000000000000000000000000000000000095 -:10FB70000000000000000000000000000000000085 -:10FB80000000000000000000000000000000000075 -:10FB90000000000000000000000000000000000065 -:10FBA0000000000000000000000000000000000055 -:10FBB0000000000000000000000000000000000045 -:10FBC0000000000000000000000000000000000035 -:10FBD0000000000000000000000000000000000025 -:10FBE0000000000000000000000000000000000015 -:10FBF0000000000000000000000000000000000005 -:10FC000000000000000000000000000000000000F4 -:10FC100000000000000000000000000000000000E4 -:10FC200000000000000000000000000000000000D4 -:10FC300000000000000000000000000000000000C4 -:10FC400000000000000000000000000000000000B4 -:10FC500000000000000000000000000000000000A4 -:10FC60000000000000000000000000000000000094 -:10FC70000000000000000000000000000000000084 -:10FC80000000000000000000000000000000000074 -:10FC90000000000000000000000000000000000064 -:10FCA0000000000000000000000000000000000054 -:10FCB0000000000000000000000000000000000044 -:10FCC0000000000000000000000000000000000034 -:10FCD0000000000000000000000000000000000024 -:10FCE0000000000000000000000000000000000014 -:10FCF0000000000000000000000000000000000004 -:10FD000000000000000000000000000000000000F3 -:10FD100000000000000000000000000000000000E3 -:10FD200000000000000000000000000000000000D3 -:10FD300000000000000000000000000000000000C3 -:10FD400000000000000000000000000000000000B3 -:10FD500000000000000000000000000000000000A3 -:10FD60000000000000000000000000000000000093 -:10FD70000000000000000000000000000000000083 -:10FD80000000000000000000000000000000000073 -:10FD90000000000000000000000000000000000063 -:10FDA0000000000000000000000000000000000053 -:10FDB0000000000000000000000000000000000043 -:10FDC0000000000000000000000000000000000033 -:10FDD0000000000000000000000000000000000023 -:10FDE0000000000000000000000000000000000013 -:10FDF0000000000000000000000000000000000003 -:10FE000000000000000000000000000000000000F2 -:10FE100000000000000000000000000000000000E2 -:10FE200000000000000000000000000000000000D2 -:10FE300000000000000000000000000000000000C2 -:10FE400000000000000000000000000000000000B2 -:10FE500000000000000000000000000000000000A2 -:10FE60000000000000000000000000000000000092 -:10FE70000000000000000000000000000000000082 -:10FE80000000000000000000000000000000000072 -:10FE90000000000000000000000000000000000062 -:10FEA0000000000000000000000000000000000052 -:10FEB0000000000000000000000000000000000042 -:10FEC0000000000000000000000000000000000032 -:10FED0000000000000000000000000000000000022 -:10FEE0000000000000000000000000000000000012 -:10FEF0000000000000000000000000000000000002 -:10FF000000000000000000000000000000000000F1 -:10FF100000000000000000000000000000000000E1 -:10FF200000000000000000000000000000000000D1 -:10FF300000000000000000000000000000000000C1 -:10FF400000000000000000000000000000000000B1 -:10FF500000000000000000000000000000000000A1 -:10FF60000000000000000000000000000000000091 -:10FF70000000000000000000000000000000000081 -:10FF80000000000000000000000000000000000071 -:10FF90000000000000000000000000000000000061 -:10FFA0000000000000000000000000000000000051 -:10FFB0000000000000000000000000000000000041 -:10FFC0000000000000000000000000000000000031 -:10FFD0000000000000000000000000000000000021 -:10FFE0000000000000000000000000000000000011 -:10FFF0000000000000000000000000000000000001 -:02000004620197 -:1000000000000000000000000000000000000000F0 -:1000100000000000000000000000000000000000E0 -:1000200000000000000000000000000000000000D0 -:1000300000000000000000000000000000000000C0 -:1000400000000000000000000000000000000000B0 -:1000500000000000000000000000000000000000A0 -:100060000000000000000000000000000000000090 -:100070000000000000000000000000000000000080 -:100080000000000000000000000000000000000070 -:100090000000000000000000000000000000000060 -:1000A0000000000000000000000000000000000050 -:1000B0000000000000000000000000000000000040 -:1000C0000000000000000000000000000000000030 -:1000D0000000000000000000000000000000000020 -:1000E0000000000000000000000000000000000010 -:1000F0000000000000000000000000000000000000 -:1001000000000000000000000000000000000000EF -:1001100000000000000000000000000000000000DF -:1001200000000000000000000000000000000000CF -:1001300000000000000000000000000000000000BF -:1001400000000000000000000000000000000000AF -:10015000000000000000000000000000000000009F -:10016000000000000000000000000000000000008F -:10017000000000000000000000000000000000007F -:10018000000000000000000000000000000000006F -:10019000000000000000000000000000000000005F -:1001A000000000000000000000000000000000004F -:1001B000000000000000000000000000000000003F -:1001C000000000000000000000000000000000002F -:1001D000000000000000000000000000000000001F -:1001E000000000000000000000000000000000000F -:1001F00000000000000000000000000000000000FF -:1002000000000000000000000000000000000000EE -:1002100000000000000000000000000000000000DE -:1002200000000000000000000000000000000000CE -:1002300000000000000000000000000000000000BE -:1002400000000000000000000000000000000000AE -:10025000000000000000000000000000000000009E -:10026000000000000000000000000000000000008E -:10027000000000000000000000000000000000007E -:10028000000000000000000000000000000000006E -:10029000000000000000000000000000000000005E -:1002A000000000000000000000000000000000004E -:1002B000000000000000000000000000000000003E -:1002C000000000000000000000000000000000002E -:1002D000000000000000000000000000000000001E -:1002E000000000000000000000000000000000000E -:1002F00000000000000000000000000000000000FE -:1003000000000000000000000000000000000000ED -:1003100000000000000000000000000000000000DD -:1003200000000000000000000000000000000000CD -:1003300000000000000000000000000000000000BD -:1003400000000000000000000000000000000000AD -:10035000000000000000000000000000000000009D -:10036000000000000000000000000000000000008D -:10037000000000000000000000000000000000007D -:10038000000000000000000000000000000000006D -:10039000000000000000000000000000000000005D -:1003A000000000000000000000000000000000004D -:1003B000000000000000000000000000000000003D -:1003C000000000000000000000000000000000002D -:1003D000000000000000000000000000000000001D -:1003E000000000000000000000000000000000000D -:1003F00000000000000000000000000000000000FD -:1004000000000000000000000000000000000000EC -:1004100000000000000000000000000000000000DC -:1004200000000000000000000000000000000000CC -:1004300000000000000000000000000000000000BC -:1004400000000000000000000000000000000000AC -:10045000000000000000000000000000000000009C -:10046000000000000000000000000000000000008C -:10047000000000000000000000000000000000007C -:10048000000000000000000000000000000000006C -:10049000000000000000000000000000000000005C -:1004A000000000000000000000000000000000004C -:1004B000000000000000000000000000000000003C -:1004C000000000000000000000000000000000002C -:1004D000000000000000000000000000000000001C -:1004E000000000000000000000000000000000000C -:1004F00000000000000000000000000000000000FC -:1005000000000000000000000000000000000000EB -:1005100000000000000000000000000000000000DB -:1005200000000000000000000000000000000000CB -:1005300000000000000000000000000000000000BB -:1005400000000000000000000000000000000000AB -:10055000000000000000000000000000000000009B -:10056000000000000000000000000000000000008B -:10057000000000000000000000000000000000007B -:10058000000000000000000000000000000000006B -:10059000000000000000000000000000000000005B -:1005A000000000000000000000000000000000004B -:1005B000000000000000000000000000000000003B -:1005C000000000000000000000000000000000002B -:1005D000000000000000000000000000000000001B -:1005E000000000000000000000000000000000000B -:1005F00000000000000000000000000000000000FB -:1006000000000000000000000000000000000000EA -:1006100000000000000000000000000000000000DA -:1006200000000000000000000000000000000000CA -:1006300000000000000000000000000000000000BA -:1006400000000000000000000000000000000000AA -:10065000000000000000000000000000000000009A -:10066000000000000000000000000000000000008A -:10067000000000000000000000000000000000007A -:10068000000000000000000000000000000000006A -:10069000000000000000000000000000000000005A -:1006A000000000000000000000000000000000004A -:1006B000000000000000000000000000000000003A -:1006C000000000000000000000000000000000002A -:1006D000000000000000000000000000000000001A -:1006E000000000000000000000000000000000000A -:1006F00000000000000000000000000000000000FA -:1007000000000000000000000000000000000000E9 -:1007100000000000000000000000000000000000D9 -:1007200000000000000000000000000000000000C9 -:1007300000000000000000000000000000000000B9 -:1007400000000000000000000000000000000000A9 -:100750000000000000000000000000000000000099 -:100760000000000000000000000000000000000089 -:100770000000000000000000000000000000000079 -:100780000000000000000000000000000000000069 -:100790000000000000000000000000000000000059 -:1007A0000000000000000000000000000000000049 -:1007B0000000000000000000000000000000000039 -:1007C0000000000000000000000000000000000029 -:1007D0000000000000000000000000000000000019 -:1007E0000000000000000000000000000000000009 -:1007F00000000000000000000000000000000000F9 -:1008000000000000000000000000000000000000E8 -:1008100000000000000000000000000000000000D8 -:1008200000000000000000000000000000000000C8 -:1008300000000000000000000000000000000000B8 -:1008400000000000000000000000000000000000A8 -:100850000000000000000000000000000000000098 -:100860000000000000000000000000000000000088 -:100870000000000000000000000000000000000078 -:100880000000000000000000000000000000000068 -:100890000000000000000000000000000000000058 -:1008A0000000000000000000000000000000000048 -:1008B0000000000000000000000000000000000038 -:1008C0000000000000000000000000000000000028 -:1008D0000000000000000000000000000000000018 -:1008E0000000000000000000000000000000000008 -:1008F00000000000000000000000000000000000F8 -:1009000000000000000000000000000000000000E7 -:1009100000000000000000000000000000000000D7 -:1009200000000000000000000000000000000000C7 -:1009300000000000000000000000000000000000B7 -:1009400000000000000000000000000000000000A7 -:100950000000000000000000000000000000000097 -:100960000000000000000000000000000000000087 -:100970000000000000000000000000000000000077 -:100980000000000000000000000000000000000067 -:100990000000000000000000000000000000000057 -:1009A0000000000000000000000000000000000047 -:1009B0000000000000000000000000000000000037 -:1009C0000000000000000000000000000000000027 -:1009D0000000000000000000000000000000000017 -:1009E0000000000000000000000000000000000007 -:1009F00000000000000000000000000000000000F7 -:100A000000000000000000000000000000000000E6 -:100A100000000000000000000000000000000000D6 -:100A200000000000000000000000000000000000C6 -:100A300000000000000000000000000000000000B6 -:100A400000000000000000000000000000000000A6 -:100A50000000000000000000000000000000000096 -:100A60000000000000000000000000000000000086 -:100A70000000000000000000000000000000000076 -:100A80000000000000000000000000000000000066 -:100A90000000000000000000000000000000000056 -:100AA0000000000000000000000000000000000046 -:100AB0000000000000000000000000000000000036 -:100AC0000000000000000000000000000000000026 -:100AD0000000000000000000000000000000000016 -:100AE0000000000000000000000000000000000006 -:100AF00000000000000000000000000000000000F6 -:100B000000000000000000000000000000000000E5 -:100B100000000000000000000000000000000000D5 -:100B200000000000000000000000000000000000C5 -:100B300000000000000000000000000000000000B5 -:100B400000000000000000000000000000000000A5 -:100B50000000000000000000000000000000000095 -:100B60000000000000000000000000000000000085 -:100B70000000000000000000000000000000000075 -:100B80000000000000000000000000000000000065 -:100B90000000000000000000000000000000000055 -:100BA0000000000000000000000000000000000045 -:100BB0000000000000000000000000000000000035 -:100BC0000000000000000000000000000000000025 -:100BD0000000000000000000000000000000000015 -:100BE0000000000000000000000000000000000005 -:100BF00000000000000000000000000000000000F5 -:100C000000000000000000000000000000000000E4 -:100C100000000000000000000000000000000000D4 -:100C200000000000000000000000000000000000C4 -:100C300000000000000000000000000000000000B4 -:100C400000000000000000000000000000000000A4 -:100C50000000000000000000000000000000000094 -:100C60000000000000000000000000000000000084 -:100C70000000000000000000000000000000000074 -:100C80000000000000000000000000000000000064 -:100C90000000000000000000000000000000000054 -:100CA0000000000000000000000000000000000044 -:100CB0000000000000000000000000000000000034 -:100CC0000000000000000000000000000000000024 -:100CD0000000000000000000000000000000000014 -:100CE0000000000000000000000000000000000004 -:100CF00000000000000000000000000000000000F4 -:100D000000000000000000000000000000000000E3 -:100D100000000000000000000000000000000000D3 -:100D200000000000000000000000000000000000C3 -:100D300000000000000000000000000000000000B3 -:100D400000000000000000000000000000000000A3 -:100D50000000000000000000000000000000000093 -:100D60000000000000000000000000000000000083 -:100D70000000000000000000000000000000000073 -:100D80000000000000000000000000000000000063 -:100D90000000000000000000000000000000000053 -:100DA0000000000000000000000000000000000043 -:100DB0000000000000000000000000000000000033 -:100DC0000000000000000000000000000000000023 -:100DD0000000000000000000000000000000000013 -:100DE0000000000000000000000000000000000003 -:100DF00000000000000000000000000000000000F3 -:100E000000000000000000000000000000000000E2 -:100E100000000000000000000000000000000000D2 -:100E200000000000000000000000000000000000C2 -:100E300000000000000000000000000000000000B2 -:100E400000000000000000000000000000000000A2 -:100E50000000000000000000000000000000000092 -:100E60000000000000000000000000000000000082 -:100E70000000000000000000000000000000000072 -:100E80000000000000000000000000000000000062 -:100E90000000000000000000000000000000000052 -:100EA0000000000000000000000000000000000042 -:100EB0000000000000000000000000000000000032 -:100EC0000000000000000000000000000000000022 -:100ED0000000000000000000000000000000000012 -:100EE0000000000000000000000000000000000002 -:100EF00000000000000000000000000000000000F2 -:100F000000000000000000000000000000000000E1 -:100F100000000000000000000000000000000000D1 -:100F200000000000000000000000000000000000C1 -:100F300000000000000000000000000000000000B1 -:100F400000000000000000000000000000000000A1 -:100F50000000000000000000000000000000000091 -:100F60000000000000000000000000000000000081 -:100F70000000000000000000000000000000000071 -:100F80000000000000000000000000000000000061 -:100F90000000000000000000000000000000000051 -:100FA0000000000000000000000000000000000041 -:100FB0000000000000000000000000000000000031 -:100FC0000000000000000000000000000000000021 -:100FD0000000000000000000000000000000000011 -:100FE0000000000000000000000000000000000001 -:100FF00000000000000000000000000000000000F1 -:1010000000000000000000000000000000000000E0 -:1010100000000000000000000000000000000000D0 -:1010200000000000000000000000000000000000C0 -:1010300000000000000000000000000000000000B0 -:1010400000000000000000000000000000000000A0 -:101050000000000000000000000000000000000090 -:101060000000000000000000000000000000000080 -:101070000000000000000000000000000000000070 -:101080000000000000000000000000000000000060 -:101090000000000000000000000000000000000050 -:1010A0000000000000000000000000000000000040 -:1010B0000000000000000000000000000000000030 -:1010C0000000000000000000000000000000000020 -:1010D0000000000000000000000000000000000010 -:1010E0000000000000000000000000000000000000 -:1010F00000000000000000000000000000000000F0 -:1011000000000000000000000000000000000000DF -:1011100000000000000000000000000000000000CF -:1011200000000000000000000000000000000000BF -:1011300000000000000000000000000000000000AF -:10114000000000000000000000000000000000009F -:10115000000000000000000000000000000000008F -:10116000000000000000000000000000000000007F -:10117000000000000000000000000000000000006F -:10118000000000000000000000000000000000005F -:10119000000000000000000000000000000000004F -:1011A000000000000000000000000000000000003F -:1011B000000000000000000000000000000000002F -:1011C000000000000000000000000000000000001F -:1011D000000000000000000000000000000000000F -:1011E00000000000000000000000000000000000FF -:1011F00000000000000000000000000000000000EF -:1012000000000000000000000000000000000000DE -:1012100000000000000000000000000000000000CE -:1012200000000000000000000000000000000000BE -:1012300000000000000000000000000000000000AE -:10124000000000000000000000000000000000009E -:10125000000000000000000000000000000000008E -:10126000000000000000000000000000000000007E -:10127000000000000000000000000000000000006E -:10128000000000000000000000000000000000005E -:10129000000000000000000000000000000000004E -:1012A000000000000000000000000000000000003E -:1012B000000000000000000000000000000000002E -:1012C000000000000000000000000000000000001E -:1012D000000000000000000000000000000000000E -:1012E00000000000000000000000000000000000FE -:1012F00000000000000000000000000000000000EE -:1013000000000000000000000000000000000000DD -:1013100000000000000000000000000000000000CD -:1013200000000000000000000000000000000000BD -:1013300000000000000000000000000000000000AD -:10134000000000000000000000000000000000009D -:10135000000000000000000000000000000000008D -:10136000000000000000000000000000000000007D -:10137000000000000000000000000000000000006D -:10138000000000000000000000000000000000005D -:10139000000000000000000000000000000000004D -:1013A000000000000000000000000000000000003D -:1013B000000000000000000000000000000000002D -:1013C000000000000000000000000000000000001D -:1013D000000000000000000000000000000000000D -:1013E00000000000000000000000000000000000FD -:1013F00000000000000000000000000000000000ED -:1014000000000000000000000000000000000000DC -:1014100000000000000000000000000000000000CC -:1014200000000000000000000000000000000000BC -:1014300000000000000000000000000000000000AC -:10144000000000000000000000000000000000009C -:10145000000000000000000000000000000000008C -:10146000000000000000000000000000000000007C -:10147000000000000000000000000000000000006C -:10148000000000000000000000000000000000005C -:10149000000000000000000000000000000000004C -:1014A000000000000000000000000000000000003C -:1014B000000000000000000000000000000000002C -:1014C000000000000000000000000000000000001C -:1014D000000000000000000000000000000000000C -:1014E00000000000000000000000000000000000FC -:1014F00000000000000000000000000000000000EC -:1015000000000000000000000000000000000000DB -:1015100000000000000000000000000000000000CB -:1015200000000000000000000000000000000000BB -:1015300000000000000000000000000000000000AB -:10154000000000000000000000000000000000009B -:10155000000000000000000000000000000000008B -:10156000000000000000000000000000000000007B -:10157000000000000000000000000000000000006B -:10158000000000000000000000000000000000005B -:10159000000000000000000000000000000000004B -:1015A000000000000000000000000000000000003B -:1015B000000000000000000000000000000000002B -:1015C000000000000000000000000000000000001B -:1015D000000000000000000000000000000000000B -:1015E00000000000000000000000000000000000FB -:1015F00000000000000000000000000000000000EB -:1016000000000000000000000000000000000000DA -:1016100000000000000000000000000000000000CA -:1016200000000000000000000000000000000000BA -:1016300000000000000000000000000000000000AA -:10164000000000000000000000000000000000009A -:10165000000000000000000000000000000000008A -:10166000000000000000000000000000000000007A -:10167000000000000000000000000000000000006A -:10168000000000000000000000000000000000005A -:10169000000000000000000000000000000000004A -:1016A000000000000000000000000000000000003A -:1016B000000000000000000000000000000000002A -:1016C000000000000000000000000000000000001A -:1016D000000000000000000000000000000000000A -:1016E00000000000000000000000000000000000FA -:1016F00000000000000000000000000000000000EA -:1017000000000000000000000000000000000000D9 -:1017100000000000000000000000000000000000C9 -:1017200000000000000000000000000000000000B9 -:1017300000000000000000000000000000000000A9 -:101740000000000000000000000000000000000099 -:101750000000000000000000000000000000000089 -:101760000000000000000000000000000000000079 -:101770000000000000000000000000000000000069 -:101780000000000000000000000000000000000059 -:101790000000000000000000000000000000000049 -:1017A0000000000000000000000000000000000039 -:1017B0000000000000000000000000000000000029 -:1017C0000000000000000000000000000000000019 -:1017D0000000000000000000000000000000000009 -:1017E00000000000000000000000000000000000F9 -:1017F00000000000000000000000000000000000E9 -:1018000000000000000000000000000000000000D8 -:1018100000000000000000000000000000000000C8 -:1018200000000000000000000000000000000000B8 -:1018300000000000000000000000000000000000A8 -:101840000000000000000000000000000000000098 -:101850000000000000000000000000000000000088 -:101860000000000000000000000000000000000078 -:101870000000000000000000000000000000000068 -:101880000000000000000000000000000000000058 -:101890000000000000000000000000000000000048 -:1018A0000000000000000000000000000000000038 -:1018B0000000000000000000000000000000000028 -:1018C0000000000000000000000000000000000018 -:1018D0000000000000000000000000000000000008 -:1018E00000000000000000000000000000000000F8 -:1018F00000000000000000000000000000000000E8 -:1019000000000000000000000000000000000000D7 -:1019100000000000000000000000000000000000C7 -:1019200000000000000000000000000000000000B7 -:1019300000000000000000000000000000000000A7 -:101940000000000000000000000000000000000097 -:101950000000000000000000000000000000000087 -:101960000000000000000000000000000000000077 -:101970000000000000000000000000000000000067 -:101980000000000000000000000000000000000057 -:101990000000000000000000000000000000000047 -:1019A0000000000000000000000000000000000037 -:1019B0000000000000000000000000000000000027 -:1019C0000000000000000000000000000000000017 -:1019D0000000000000000000000000000000000007 -:1019E00000000000000000000000000000000000F7 -:1019F00000000000000000000000000000000000E7 -:101A000000000000000000000000000000000000D6 -:101A100000000000000000000000000000000000C6 -:101A200000000000000000000000000000000000B6 -:101A300000000000000000000000000000000000A6 -:101A40000000000000000000000000000000000096 -:101A50000000000000000000000000000000000086 -:101A60000000000000000000000000000000000076 -:101A70000000000000000000000000000000000066 -:101A80000000000000000000000000000000000056 -:101A90000000000000000000000000000000000046 -:101AA0000000000000000000000000000000000036 -:101AB0000000000000000000000000000000000026 -:101AC0000000000000000000000000000000000016 -:101AD0000000000000000000000000000000000006 -:101AE00000000000000000000000000000000000F6 -:101AF00000000000000000000000000000000000E6 -:101B000000000000000000000000000000000000D5 -:101B100000000000000000000000000000000000C5 -:101B200000000000000000000000000000000000B5 -:101B300000000000000000000000000000000000A5 -:101B40000000000000000000000000000000000095 -:101B50000000000000000000000000000000000085 -:101B60000000000000000000000000000000000075 -:101B70000000000000000000000000000000000065 -:101B80000000000000000000000000000000000055 -:101B90000000000000000000000000000000000045 -:101BA0000000000000000000000000000000000035 -:101BB0000000000000000000000000000000000025 -:101BC0000000000000000000000000000000000015 -:101BD0000000000000000000000000000000000005 -:101BE00000000000000000000000000000000000F5 -:101BF00000000000000000000000000000000000E5 -:101C000000000000000000000000000000000000D4 -:101C100000000000000000000000000000000000C4 -:101C200000000000000000000000000000000000B4 -:101C300000000000000000000000000000000000A4 -:101C40000000000000000000000000000000000094 -:101C50000000000000000000000000000000000084 -:101C60000000000000000000000000000000000074 -:101C70000000000000000000000000000000000064 -:101C80000000000000000000000000000000000054 -:101C90000000000000000000000000000000000044 -:101CA0000000000000000000000000000000000034 -:101CB0000000000000000000000000000000000024 -:101CC0000000000000000000000000000000000014 -:101CD0000000000000000000000000000000000004 -:101CE00000000000000000000000000000000000F4 -:101CF00000000000000000000000000000000000E4 -:101D000000000000000000000000000000000000D3 -:101D100000000000000000000000000000000000C3 -:101D200000000000000000000000000000000000B3 -:101D300000000000000000000000000000000000A3 -:101D40000000000000000000000000000000000093 -:101D50000000000000000000000000000000000083 -:101D60000000000000000000000000000000000073 -:101D70000000000000000000000000000000000063 -:101D80000000000000000000000000000000000053 -:101D90000000000000000000000000000000000043 -:101DA0000000000000000000000000000000000033 -:101DB0000000000000000000000000000000000023 -:101DC0000000000000000000000000000000000013 -:101DD0000000000000000000000000000000000003 -:101DE00000000000000000000000000000000000F3 -:101DF00000000000000000000000000000000000E3 -:101E000000000000000000000000000000000000D2 -:101E100000000000000000000000000000000000C2 -:101E200000000000000000000000000000000000B2 -:101E300000000000000000000000000000000000A2 -:101E40000000000000000000000000000000000092 -:101E50000000000000000000000000000000000082 -:101E60000000000000000000000000000000000072 -:101E70000000000000000000000000000000000062 -:101E80000000000000000000000000000000000052 -:101E90000000000000000000000000000000000042 -:101EA0000000000000000000000000000000000032 -:101EB0000000000000000000000000000000000022 -:101EC0000000000000000000000000000000000012 -:101ED0000000000000000000000000000000000002 -:101EE00000000000000000000000000000000000F2 -:101EF00000000000000000000000000000000000E2 -:101F000000000000000000000000000000000000D1 -:101F100000000000000000000000000000000000C1 -:101F200000000000000000000000000000000000B1 -:101F300000000000000000000000000000000000A1 -:101F40000000000000000000000000000000000091 -:101F50000000000000000000000000000000000081 -:101F60000000000000000000000000000000000071 -:101F70000000000000000000000000000000000061 -:101F80000000000000000000000000000000000051 -:101F90000000000000000000000000000000000041 -:101FA0000000000000000000000000000000000031 -:101FB0000000000000000000000000000000000021 -:101FC0000000000000000000000000000000000011 -:101FD0000000000000000000000000000000000001 -:101FE00000000000000000000000000000000000F1 -:101FF00000000000000000000000000000000000E1 -:1020000000000000000000000000000000000000D0 -:1020100000000000000000000000000000000000C0 -:1020200000000000000000000000000000000000B0 -:1020300000000000000000000000000000000000A0 -:102040000000000000000000000000000000000090 -:102050000000000000000000000000000000000080 -:102060000000000000000000000000000000000070 -:102070000000000000000000000000000000000060 -:102080000000000000000000000000000000000050 -:102090000000000000000000000000000000000040 -:1020A0000000000000000000000000000000000030 -:1020B0000000000000000000000000000000000020 -:1020C0000000000000000000000000000000000010 -:1020D0000000000000000000000000000000000000 -:1020E00000000000000000000000000000000000F0 -:1020F00000000000000000000000000000000000E0 -:1021000000000000000000000000000000000000CF -:1021100000000000000000000000000000000000BF -:1021200000000000000000000000000000000000AF -:10213000000000000000000000000000000000009F -:10214000000000000000000000000000000000008F -:10215000000000000000000000000000000000007F -:10216000000000000000000000000000000000006F -:10217000000000000000000000000000000000005F -:10218000000000000000000000000000000000004F -:10219000000000000000000000000000000000003F -:1021A000000000000000000000000000000000002F -:1021B000000000000000000000000000000000001F -:1021C000000000000000000000000000000000000F -:1021D00000000000000000000000000000000000FF -:1021E00000000000000000000000000000000000EF -:1021F00000000000000000000000000000000000DF -:1022000000000000000000000000000000000000CE -:1022100000000000000000000000000000000000BE -:1022200000000000000000000000000000000000AE -:10223000000000000000000000000000000000009E -:10224000000000000000000000000000000000008E -:10225000000000000000000000000000000000007E -:10226000000000000000000000000000000000006E -:10227000000000000000000000000000000000005E -:10228000000000000000000000000000000000004E -:10229000000000000000000000000000000000003E -:1022A000000000000000000000000000000000002E -:1022B000000000000000000000000000000000001E -:1022C000000000000000000000000000000000000E -:1022D00000000000000000000000000000000000FE -:1022E00000000000000000000000000000000000EE -:1022F00000000000000000000000000000000000DE -:1023000000000000000000000000000000000000CD -:1023100000000000000000000000000000000000BD -:1023200000000000000000000000000000000000AD -:10233000000000000000000000000000000000009D -:10234000000000000000000000000000000000008D -:10235000000000000000000000000000000000007D -:10236000000000000000000000000000000000006D -:10237000000000000000000000000000000000005D -:10238000000000000000000000000000000000004D -:10239000000000000000000000000000000000003D -:1023A000000000000000000000000000000000002D -:1023B000000000000000000000000000000000001D -:1023C000000000000000000000000000000000000D -:1023D00000000000000000000000000000000000FD -:1023E00000000000000000000000000000000000ED -:1023F00000000000000000000000000000000000DD -:1024000000000000000000000000000000000000CC -:1024100000000000000000000000000000000000BC -:1024200000000000000000000000000000000000AC -:10243000000000000000000000000000000000009C -:10244000000000000000000000000000000000008C -:10245000000000000000000000000000000000007C -:10246000000000000000000000000000000000006C -:10247000000000000000000000000000000000005C -:10248000000000000000000000000000000000004C -:10249000000000000000000000000000000000003C -:1024A000000000000000000000000000000000002C -:1024B000000000000000000000000000000000001C -:1024C000000000000000000000000000000000000C -:1024D00000000000000000000000000000000000FC -:1024E00000000000000000000000000000000000EC -:1024F00000000000000000000000000000000000DC -:1025000000000000000000000000000000000000CB -:1025100000000000000000000000000000000000BB -:1025200000000000000000000000000000000000AB -:10253000000000000000000000000000000000009B -:10254000000000000000000000000000000000008B -:10255000000000000000000000000000000000007B -:10256000000000000000000000000000000000006B -:10257000000000000000000000000000000000005B -:10258000000000000000000000000000000000004B -:10259000000000000000000000000000000000003B -:1025A000000000000000000000000000000000002B -:1025B000000000000000000000000000000000001B -:1025C000000000000000000000000000000000000B -:1025D00000000000000000000000000000000000FB -:1025E00000000000000000000000000000000000EB -:1025F00000000000000000000000000000000000DB -:1026000000000000000000000000000000000000CA -:1026100000000000000000000000000000000000BA -:1026200000000000000000000000000000000000AA -:10263000000000000000000000000000000000009A -:10264000000000000000000000000000000000008A -:10265000000000000000000000000000000000007A -:10266000000000000000000000000000000000006A -:10267000000000000000000000000000000000005A -:10268000000000000000000000000000000000004A -:10269000000000000000000000000000000000003A -:1026A000000000000000000000000000000000002A -:1026B000000000000000000000000000000000001A -:1026C000000000000000000000000000000000000A -:1026D00000000000000000000000000000000000FA -:1026E00000000000000000000000000000000000EA -:1026F00000000000000000000000000000000000DA -:1027000000000000000000000000000000000000C9 -:1027100000000000000000000000000000000000B9 -:1027200000000000000000000000000000000000A9 -:102730000000000000000000000000000000000099 -:102740000000000000000000000000000000000089 -:102750000000000000000000000000000000000079 -:102760000000000000000000000000000000000069 -:102770000000000000000000000000000000000059 -:102780000000000000000000000000000000000049 -:102790000000000000000000000000000000000039 -:1027A0000000000000000000000000000000000029 -:1027B0000000000000000000000000000000000019 -:1027C0000000000000000000000000000000000009 -:1027D00000000000000000000000000000000000F9 -:1027E00000000000000000000000000000000000E9 -:1027F00000000000000000000000000000000000D9 -:1028000000000000000000000000000000000000C8 -:1028100000000000000000000000000000000000B8 -:1028200000000000000000000000000000000000A8 -:102830000000000000000000000000000000000098 -:102840000000000000000000000000000000000088 -:102850000000000000000000000000000000000078 -:102860000000000000000000000000000000000068 -:102870000000000000000000000000000000000058 -:102880000000000000000000000000000000000048 -:102890000000000000000000000000000000000038 -:1028A0000000000000000000000000000000000028 -:1028B0000000000000000000000000000000000018 -:1028C0000000000000000000000000000000000008 -:1028D00000000000000000000000000000000000F8 -:1028E00000000000000000000000000000000000E8 -:1028F00000000000000000000000000000000000D8 -:1029000000000000000000000000000000000000C7 -:1029100000000000000000000000000000000000B7 -:1029200000000000000000000000000000000000A7 -:102930000000000000000000000000000000000097 -:102940000000000000000000000000000000000087 -:102950000000000000000000000000000000000077 -:102960000000000000000000000000000000000067 -:102970000000000000000000000000000000000057 -:102980000000000000000000000000000000000047 -:102990000000000000000000000000000000000037 -:1029A0000000000000000000000000000000000027 -:1029B0000000000000000000000000000000000017 -:1029C0000000000000000000000000000000000007 -:1029D00000000000000000000000000000000000F7 -:1029E00000000000000000000000000000000000E7 -:1029F00000000000000000000000000000000000D7 -:102A000000000000000000000000000000000000C6 -:102A100000000000000000000000000000000000B6 -:102A200000000000000000000000000000000000A6 -:102A30000000000000000000000000000000000096 -:102A40000000000000000000000000000000000086 -:102A50000000000000000000000000000000000076 -:102A60000000000000000000000000000000000066 -:102A70000000000000000000000000000000000056 -:102A80000000000000000000000000000000000046 -:102A90000000000000000000000000000000000036 -:102AA0000000000000000000000000000000000026 -:102AB0000000000000000000000000000000000016 -:102AC0000000000000000000000000000000000006 -:102AD00000000000000000000000000000000000F6 -:102AE00000000000000000000000000000000000E6 -:102AF00000000000000000000000000000000000D6 -:102B000000000000000000000000000000000000C5 -:102B100000000000000000000000000000000000B5 -:102B200000000000000000000000000000000000A5 -:102B30000000000000000000000000000000000095 -:102B40000000000000000000000000000000000085 -:102B50000000000000000000000000000000000075 -:102B60000000000000000000000000000000000065 -:102B70000000000000000000000000000000000055 -:102B80000000000000000000000000000000000045 -:102B90000000000000000000000000000000000035 -:102BA0000000000000000000000000000000000025 -:102BB0000000000000000000000000000000000015 -:102BC0000000000000000000000000000000000005 -:102BD00000000000000000000000000000000000F5 -:102BE00000000000000000000000000000000000E5 -:102BF00000000000000000000000000000000000D5 -:102C000000000000000000000000000000000000C4 -:102C100000000000000000000000000000000000B4 -:102C200000000000000000000000000000000000A4 -:102C30000000000000000000000000000000000094 -:102C40000000000000000000000000000000000084 -:102C50000000000000000000000000000000000074 -:102C60000000000000000000000000000000000064 -:102C70000000000000000000000000000000000054 -:102C80000000000000000000000000000000000044 -:102C90000000000000000000000000000000000034 -:102CA0000000000000000000000000000000000024 -:102CB0000000000000000000000000000000000014 -:102CC0000000000000000000000000000000000004 -:102CD00000000000000000000000000000000000F4 -:102CE00000000000000000000000000000000000E4 -:102CF00000000000000000000000000000000000D4 -:102D000000000000000000000000000000000000C3 -:102D100000000000000000000000000000000000B3 -:102D200000000000000000000000000000000000A3 -:102D30000000000000000000000000000000000093 -:102D40000000000000000000000000000000000083 -:102D50000000000000000000000000000000000073 -:102D60000000000000000000000000000000000063 -:102D70000000000000000000000000000000000053 -:102D80000000000000000000000000000000000043 -:102D90000000000000000000000000000000000033 -:102DA0000000000000000000000000000000000023 -:102DB0000000000000000000000000000000000013 -:102DC0000000000000000000000000000000000003 -:102DD00000000000000000000000000000000000F3 -:102DE00000000000000000000000000000000000E3 -:102DF00000000000000000000000000000000000D3 -:102E000000000000000000000000000000000000C2 -:102E100000000000000000000000000000000000B2 -:102E200000000000000000000000000000000000A2 -:102E30000000000000000000000000000000000092 -:102E40000000000000000000000000000000000082 -:102E50000000000000000000000000000000000072 -:102E60000000000000000000000000000000000062 -:102E70000000000000000000000000000000000052 -:102E80000000000000000000000000000000000042 -:102E90000000000000000000000000000000000032 -:102EA0000000000000000000000000000000000022 -:102EB0000000000000000000000000000000000012 -:102EC0000000000000000000000000000000000002 -:102ED00000000000000000000000000000000000F2 -:102EE00000000000000000000000000000000000E2 -:102EF00000000000000000000000000000000000D2 -:102F000000000000000000000000000000000000C1 -:102F100000000000000000000000000000000000B1 -:102F200000000000000000000000000000000000A1 -:102F30000000000000000000000000000000000091 -:102F40000000000000000000000000000000000081 -:102F50000000000000000000000000000000000071 -:102F60000000000000000000000000000000000061 -:102F70000000000000000000000000000000000051 -:102F80000000000000000000000000000000000041 -:102F90000000000000000000000000000000000031 -:102FA0000000000000000000000000000000000021 -:102FB0000000000000000000000000000000000011 -:102FC0000000000000000000000000000000000001 -:102FD00000000000000000000000000000000000F1 -:102FE00000000000000000000000000000000000E1 -:102FF00000000000000000000000000000000000D1 -:1030000000000000000000000000000000000000C0 -:1030100000000000000000000000000000000000B0 -:1030200000000000000000000000000000000000A0 -:103030000000000000000000000000000000000090 -:103040000000000000000000000000000000000080 -:103050000000000000000000000000000000000070 -:103060000000000000000000000000000000000060 -:103070000000000000000000000000000000000050 -:103080000000000000000000000000000000000040 -:103090000000000000000000000000000000000030 -:1030A0000000000000000000000000000000000020 -:1030B0000000000000000000000000000000000010 -:1030C0000000000000000000000000000000000000 -:1030D00000000000000000000000000000000000F0 -:1030E00000000000000000000000000000000000E0 -:1030F00000000000000000000000000000000000D0 -:1031000000000000000000000000000000000000BF -:1031100000000000000000000000000000000000AF -:10312000000000000000000000000000000000009F -:10313000000000000000000000000000000000008F -:10314000000000000000000000000000000000007F -:10315000000000000000000000000000000000006F -:10316000000000000000000000000000000000005F -:10317000000000000000000000000000000000004F -:10318000000000000000000000000000000000003F -:10319000000000000000000000000000000000002F -:1031A000000000000000000000000000000000001F -:1031B000000000000000000000000000000000000F -:1031C00000000000000000000000000000000000FF -:1031D00000000000000000000000000000000000EF -:1031E00000000000000000000000000000000000DF -:1031F00000000000000000000000000000000000CF -:1032000000000000000000000000000000000000BE -:1032100000000000000000000000000000000000AE -:10322000000000000000000000000000000000009E -:10323000000000000000000000000000000000008E -:10324000000000000000000000000000000000007E -:10325000000000000000000000000000000000006E -:10326000000000000000000000000000000000005E -:10327000000000000000000000000000000000004E -:10328000000000000000000000000000000000003E -:10329000000000000000000000000000000000002E -:1032A000000000000000000000000000000000001E -:1032B000000000000000000000000000000000000E -:1032C00000000000000000000000000000000000FE -:1032D00000000000000000000000000000000000EE -:1032E00000000000000000000000000000000000DE -:1032F00000000000000000000000000000000000CE -:1033000000000000000000000000000000000000BD -:1033100000000000000000000000000000000000AD -:10332000000000000000000000000000000000009D -:10333000000000000000000000000000000000008D -:10334000000000000000000000000000000000007D -:10335000000000000000000000000000000000006D -:10336000000000000000000000000000000000005D -:10337000000000000000000000000000000000004D -:10338000000000000000000000000000000000003D -:10339000000000000000000000000000000000002D -:1033A000000000000000000000000000000000001D -:1033B000000000000000000000000000000000000D -:1033C00000000000000000000000000000000000FD -:1033D00000000000000000000000000000000000ED -:1033E00000000000000000000000000000000000DD -:1033F00000000000000000000000000000000000CD -:1034000000000000000000000000000000000000BC -:1034100000000000000000000000000000000000AC -:10342000000000000000000000000000000000009C -:10343000000000000000000000000000000000008C -:10344000000000000000000000000000000000007C -:10345000000000000000000000000000000000006C -:10346000000000000000000000000000000000005C -:10347000000000000000000000000000000000004C -:10348000000000000000000000000000000000003C -:10349000000000000000000000000000000000002C -:1034A000000000000000000000000000000000001C -:1034B000000000000000000000000000000000000C -:1034C00000000000000000000000000000000000FC -:1034D00000000000000000000000000000000000EC -:1034E00000000000000000000000000000000000DC -:1034F00000000000000000000000000000000000CC -:1035000000000000000000000000000000000000BB -:1035100000000000000000000000000000000000AB -:10352000000000000000000000000000000000009B -:10353000000000000000000000000000000000008B -:10354000000000000000000000000000000000007B -:10355000000000000000000000000000000000006B -:10356000000000000000000000000000000000005B -:10357000000000000000000000000000000000004B -:10358000000000000000000000000000000000003B -:10359000000000000000000000000000000000002B -:1035A000000000000000000000000000000000001B -:1035B000000000000000000000000000000000000B -:1035C00000000000000000000000000000000000FB -:1035D00000000000000000000000000000000000EB -:1035E00000000000000000000000000000000000DB -:1035F00000000000000000000000000000000000CB -:1036000000000000000000000000000000000000BA -:1036100000000000000000000000000000000000AA -:10362000000000000000000000000000000000009A -:10363000000000000000000000000000000000008A -:10364000000000000000000000000000000000007A -:10365000000000000000000000000000000000006A -:10366000000000000000000000000000000000005A -:10367000000000000000000000000000000000004A -:10368000000000000000000000000000000000003A -:10369000000000000000000000000000000000002A -:1036A000000000000000000000000000000000001A -:1036B000000000000000000000000000000000000A -:1036C00000000000000000000000000000000000FA -:1036D00000000000000000000000000000000000EA -:1036E00000000000000000000000000000000000DA -:1036F00000000000000000000000000000000000CA -:1037000000000000000000000000000000000000B9 -:1037100000000000000000000000000000000000A9 -:103720000000000000000000000000000000000099 -:103730000000000000000000000000000000000089 -:103740000000000000000000000000000000000079 -:103750000000000000000000000000000000000069 -:103760000000000000000000000000000000000059 -:103770000000000000000000000000000000000049 -:103780000000000000000000000000000000000039 -:103790000000000000000000000000000000000029 -:1037A0000000000000000000000000000000000019 -:1037B0000000000000000000000000000000000009 -:1037C00000000000000000000000000000000000F9 -:1037D00000000000000000000000000000000000E9 -:1037E00000000000000000000000000000000000D9 -:1037F00000000000000000000000000000000000C9 -:1038000000000000000000000000000000000000B8 -:1038100000000000000000000000000000000000A8 -:103820000000000000000000000000000000000098 -:103830000000000000000000000000000000000088 -:103840000000000000000000000000000000000078 -:103850000000000000000000000000000000000068 -:103860000000000000000000000000000000000058 -:103870000000000000000000000000000000000048 -:103880000000000000000000000000000000000038 -:103890000000000000000000000000000000000028 -:1038A0000000000000000000000000000000000018 -:1038B0000000000000000000000000000000000008 -:1038C00000000000000000000000000000000000F8 -:1038D00000000000000000000000000000000000E8 -:1038E00000000000000000000000000000000000D8 -:1038F00000000000000000000000000000000000C8 -:1039000000000000000000000000000000000000B7 -:1039100000000000000000000000000000000000A7 -:103920000000000000000000000000000000000097 -:103930000000000000000000000000000000000087 -:103940000000000000000000000000000000000077 -:103950000000000000000000000000000000000067 -:103960000000000000000000000000000000000057 -:103970000000000000000000000000000000000047 -:103980000000000000000000000000000000000037 -:103990000000000000000000000000000000000027 -:1039A0000000000000000000000000000000000017 -:1039B0000000000000000000000000000000000007 -:1039C00000000000000000000000000000000000F7 -:1039D00000000000000000000000000000000000E7 -:1039E00000000000000000000000000000000000D7 -:1039F00000000000000000000000000000000000C7 -:103A000000000000000000000000000000000000B6 -:103A100000000000000000000000000000000000A6 -:103A20000000000000000000000000000000000096 -:103A30000000000000000000000000000000000086 -:103A40000000000000000000000000000000000076 -:103A50000000000000000000000000000000000066 -:103A60000000000000000000000000000000000056 -:103A70000000000000000000000000000000000046 -:103A80000000000000000000000000000000000036 -:103A90000000000000000000000000000000000026 -:103AA0000000000000000000000000000000000016 -:103AB0000000000000000000000000000000000006 -:103AC00000000000000000000000000000000000F6 -:103AD00000000000000000000000000000000000E6 -:103AE00000000000000000000000000000000000D6 -:103AF00000000000000000000000000000000000C6 -:103B000000000000000000000000000000000000B5 -:103B100000000000000000000000000000000000A5 -:103B20000000000000000000000000000000000095 -:103B30000000000000000000000000000000000085 -:103B40000000000000000000000000000000000075 -:103B50000000000000000000000000000000000065 -:103B60000000000000000000000000000000000055 -:103B70000000000000000000000000000000000045 -:103B80000000000000000000000000000000000035 -:103B90000000000000000000000000000000000025 -:103BA0000000000000000000000000000000000015 -:103BB0000000000000000000000000000000000005 -:103BC00000000000000000000000000000000000F5 -:103BD00000000000000000000000000000000000E5 -:103BE00000000000000000000000000000000000D5 -:103BF00000000000000000000000000000000000C5 -:103C000000000000000000000000000000000000B4 -:103C100000000000000000000000000000000000A4 -:103C20000000000000000000000000000000000094 -:103C30000000000000000000000000000000000084 -:103C40000000000000000000000000000000000074 -:103C50000000000000000000000000000000000064 -:103C60000000000000000000000000000000000054 -:103C70000000000000000000000000000000000044 -:103C80000000000000000000000000000000000034 -:103C90000000000000000000000000000000000024 -:103CA0000000000000000000000000000000000014 -:103CB0000000000000000000000000000000000004 -:103CC00000000000000000000000000000000000F4 -:103CD00000000000000000000000000000000000E4 -:103CE00000000000000000000000000000000000D4 -:103CF00000000000000000000000000000000000C4 -:103D000000000000000000000000000000000000B3 -:103D100000000000000000000000000000000000A3 -:103D20000000000000000000000000000000000093 -:103D30000000000000000000000000000000000083 -:103D40000000000000000000000000000000000073 -:103D50000000000000000000000000000000000063 -:103D60000000000000000000000000000000000053 -:103D70000000000000000000000000000000000043 -:103D80000000000000000000000000000000000033 -:103D90000000000000000000000000000000000023 -:103DA0000000000000000000000000000000000013 -:103DB0000000000000000000000000000000000003 -:103DC00000000000000000000000000000000000F3 -:103DD00000000000000000000000000000000000E3 -:103DE00000000000000000000000000000000000D3 -:103DF00000000000000000000000000000000000C3 -:103E000000000000000000000000000000000000B2 -:103E100000000000000000000000000000000000A2 -:103E20000000000000000000000000000000000092 -:103E30000000000000000000000000000000000082 -:103E40000000000000000000000000000000000072 -:103E50000000000000000000000000000000000062 -:103E60000000000000000000000000000000000052 -:103E70000000000000000000000000000000000042 -:103E80000000000000000000000000000000000032 -:103E90000000000000000000000000000000000022 -:103EA0000000000000000000000000000000000012 -:103EB0000000000000000000000000000000000002 -:103EC00000000000000000000000000000000000F2 -:103ED00000000000000000000000000000000000E2 -:103EE00000000000000000000000000000000000D2 -:103EF00000000000000000000000000000000000C2 -:103F000000000000000000000000000000000000B1 -:103F100000000000000000000000000000000000A1 -:103F20000000000000000000000000000000000091 -:103F30000000000000000000000000000000000081 -:103F40000000000000000000000000000000000071 -:103F50000000000000000000000000000000000061 -:103F60000000000000000000000000000000000051 -:103F70000000000000000000000000000000000041 -:103F80000000000000000000000000000000000031 -:103F90000000000000000000000000000000000021 -:103FA0000000000000000000000000000000000011 -:103FB0000000000000000000000000000000000001 -:103FC00000000000000000000000000000000000F1 -:103FD00000000000000000000000000000000000E1 -:103FE00000000000000000000000000000000000D1 -:103FF00000000000000000000000000000000000C1 -:1040000000000000000000000000000000000000B0 -:1040100000000000000000000000000000000000A0 -:104020000000000000000000000000000000000090 -:104030000000000000000000000000000000000080 -:104040000000000000000000000000000000000070 -:104050000000000000000000000000000000000060 -:104060000000000000000000000000000000000050 -:104070000000000000000000000000000000000040 -:104080000000000000000000000000000000000030 -:104090000000000000000000000000000000000020 -:1040A0000000000000000000000000000000000010 -:1040B0000000000000000000000000000000000000 -:1040C00000000000000000000000000000000000F0 -:1040D00000000000000000000000000000000000E0 -:1040E00000000000000000000000000000000000D0 -:1040F00000000000000000000000000000000000C0 -:1041000000000000000000000000000000000000AF -:10411000000000000000000000000000000000009F -:10412000000000000000000000000000000000008F -:10413000000000000000000000000000000000007F -:10414000000000000000000000000000000000006F -:10415000000000000000000000000000000000005F -:10416000000000000000000000000000000000004F -:10417000000000000000000000000000000000003F -:10418000000000000000000000000000000000002F -:10419000000000000000000000000000000000001F -:1041A000000000000000000000000000000000000F -:1041B00000000000000000000000000000000000FF -:1041C00000000000000000000000000000000000EF -:1041D00000000000000000000000000000000000DF -:1041E00000000000000000000000000000000000CF -:1041F00000000000000000000000000000000000BF -:1042000000000000000000000000000000000000AE -:10421000000000000000000000000000000000009E -:10422000000000000000000000000000000000008E -:10423000000000000000000000000000000000007E -:10424000000000000000000000000000000000006E -:10425000000000000000000000000000000000005E -:10426000000000000000000000000000000000004E -:10427000000000000000000000000000000000003E -:10428000000000000000000000000000000000002E -:10429000000000000000000000000000000000001E -:1042A000000000000000000000000000000000000E -:1042B00000000000000000000000000000000000FE -:1042C00000000000000000000000000000000000EE -:1042D00000000000000000000000000000000000DE -:1042E00000000000000000000000000000000000CE -:1042F00000000000000000000000000000000000BE -:1043000000000000000000000000000000000000AD -:10431000000000000000000000000000000000009D -:10432000000000000000000000000000000000008D -:10433000000000000000000000000000000000007D -:10434000000000000000000000000000000000006D -:10435000000000000000000000000000000000005D -:10436000000000000000000000000000000000004D -:10437000000000000000000000000000000000003D -:10438000000000000000000000000000000000002D -:10439000000000000000000000000000000000001D -:1043A000000000000000000000000000000000000D -:1043B00000000000000000000000000000000000FD -:1043C00000000000000000000000000000000000ED -:1043D00000000000000000000000000000000000DD -:1043E00000000000000000000000000000000000CD -:1043F00000000000000000000000000000000000BD -:1044000000000000000000000000000000000000AC -:10441000000000000000000000000000000000009C -:10442000000000000000000000000000000000008C -:10443000000000000000000000000000000000007C -:10444000000000000000000000000000000000006C -:10445000000000000000000000000000000000005C -:10446000000000000000000000000000000000004C -:10447000000000000000000000000000000000003C -:10448000000000000000000000000000000000002C -:10449000000000000000000000000000000000001C -:1044A000000000000000000000000000000000000C -:1044B00000000000000000000000000000000000FC -:1044C00000000000000000000000000000000000EC -:1044D00000000000000000000000000000000000DC -:1044E00000000000000000000000000000000000CC -:1044F00000000000000000000000000000000000BC -:1045000000000000000000000000000000000000AB -:10451000000000000000000000000000000000009B -:10452000000000000000000000000000000000008B -:10453000000000000000000000000000000000007B -:10454000000000000000000000000000000000006B -:10455000000000000000000000000000000000005B -:10456000000000000000000000000000000000004B -:10457000000000000000000000000000000000003B -:10458000000000000000000000000000000000002B -:10459000000000000000000000000000000000001B -:1045A000000000000000000000000000000000000B -:1045B00000000000000000000000000000000000FB -:1045C00000000000000000000000000000000000EB -:1045D00000000000000000000000000000000000DB -:1045E00000000000000000000000000000000000CB -:1045F00000000000000000000000000000000000BB -:1046000000000000000000000000000000000000AA -:10461000000000000000000000000000000000009A -:10462000000000000000000000000000000000008A -:10463000000000000000000000000000000000007A -:10464000000000000000000000000000000000006A -:10465000000000000000000000000000000000005A -:10466000000000000000000000000000000000004A -:10467000000000000000000000000000000000003A -:10468000000000000000000000000000000000002A -:10469000000000000000000000000000000000001A -:1046A000000000000000000000000000000000000A -:1046B00000000000000000000000000000000000FA -:1046C00000000000000000000000000000000000EA -:1046D00000000000000000000000000000000000DA -:1046E00000000000000000000000000000000000CA -:1046F00000000000000000000000000000000000BA -:1047000000000000000000000000000000000000A9 -:104710000000000000000000000000000000000099 -:104720000000000000000000000000000000000089 -:104730000000000000000000000000000000000079 -:104740000000000000000000000000000000000069 -:104750000000000000000000000000000000000059 -:104760000000000000000000000000000000000049 -:104770000000000000000000000000000000000039 -:104780000000000000000000000000000000000029 -:104790000000000000000000000000000000000019 -:1047A0000000000000000000000000000000000009 -:1047B00000000000000000000000000000000000F9 -:1047C00000000000000000000000000000000000E9 -:1047D00000000000000000000000000000000000D9 -:1047E00000000000000000000000000000000000C9 -:1047F00000000000000000000000000000000000B9 -:1048000000000000000000000000000000000000A8 -:104810000000000000000000000000000000000098 -:104820000000000000000000000000000000000088 -:104830000000000000000000000000000000000078 -:104840000000000000000000000000000000000068 -:104850000000000000000000000000000000000058 -:104860000000000000000000000000000000000048 -:104870000000000000000000000000000000000038 -:104880000000000000000000000000000000000028 -:104890000000000000000000000000000000000018 -:1048A0000000000000000000000000000000000008 -:1048B00000000000000000000000000000000000F8 -:1048C00000000000000000000000000000000000E8 -:1048D00000000000000000000000000000000000D8 -:1048E00000000000000000000000000000000000C8 -:1048F00000000000000000000000000000000000B8 -:1049000000000000000000000000000000000000A7 -:104910000000000000000000000000000000000097 -:104920000000000000000000000000000000000087 -:104930000000000000000000000000000000000077 -:104940000000000000000000000000000000000067 -:104950000000000000000000000000000000000057 -:104960000000000000000000000000000000000047 -:104970000000000000000000000000000000000037 -:104980000000000000000000000000000000000027 -:104990000000000000000000000000000000000017 -:1049A0000000000000000000000000000000000007 -:1049B00000000000000000000000000000000000F7 -:1049C00000000000000000000000000000000000E7 -:1049D00000000000000000000000000000000000D7 -:1049E00000000000000000000000000000000000C7 -:1049F00000000000000000000000000000000000B7 -:104A000000000000000000000000000000000000A6 -:104A10000000000000000000000000000000000096 -:104A20000000000000000000000000000000000086 -:104A30000000000000000000000000000000000076 -:104A40000000000000000000000000000000000066 -:104A50000000000000000000000000000000000056 -:104A60000000000000000000000000000000000046 -:104A70000000000000000000000000000000000036 -:104A80000000000000000000000000000000000026 -:104A90000000000000000000000000000000000016 -:104AA0000000000000000000000000000000000006 -:104AB00000000000000000000000000000000000F6 -:104AC00000000000000000000000000000000000E6 -:104AD00000000000000000000000000000000000D6 -:104AE00000000000000000000000000000000000C6 -:104AF00000000000000000000000000000000000B6 -:104B000000000000000000000000000000000000A5 -:104B10000000000000000000000000000000000095 -:104B20000000000000000000000000000000000085 -:104B30000000000000000000000000000000000075 -:104B40000000000000000000000000000000000065 -:104B50000000000000000000000000000000000055 -:104B60000000000000000000000000000000000045 -:104B70000000000000000000000000000000000035 -:104B80000000000000000000000000000000000025 -:104B90000000000000000000000000000000000015 -:104BA0000000000000000000000000000000000005 -:104BB00000000000000000000000000000000000F5 -:104BC00000000000000000000000000000000000E5 -:104BD00000000000000000000000000000000000D5 -:104BE00000000000000000000000000000000000C5 -:104BF00000000000000000000000000000000000B5 -:104C000000000000000000000000000000000000A4 -:104C10000000000000000000000000000000000094 -:104C20000000000000000000000000000000000084 -:104C30000000000000000000000000000000000074 -:104C40000000000000000000000000000000000064 -:104C50000000000000000000000000000000000054 -:104C60000000000000000000000000000000000044 -:104C70000000000000000000000000000000000034 -:104C80000000000000000000000000000000000024 -:104C90000000000000000000000000000000000014 -:104CA0000000000000000000000000000000000004 -:104CB00000000000000000000000000000000000F4 -:104CC00000000000000000000000000000000000E4 -:104CD00000000000000000000000000000000000D4 -:104CE00000000000000000000000000000000000C4 -:104CF00000000000000000000000000000000000B4 -:104D000000000000000000000000000000000000A3 -:104D10000000000000000000000000000000000093 -:104D20000000000000000000000000000000000083 -:104D30000000000000000000000000000000000073 -:104D40000000000000000000000000000000000063 -:104D50000000000000000000000000000000000053 -:104D60000000000000000000000000000000000043 -:104D70000000000000000000000000000000000033 -:104D80000000000000000000000000000000000023 -:104D90000000000000000000000000000000000013 -:104DA0000000000000000000000000000000000003 -:104DB00000000000000000000000000000000000F3 -:104DC00000000000000000000000000000000000E3 -:104DD00000000000000000000000000000000000D3 -:104DE00000000000000000000000000000000000C3 -:104DF00000000000000000000000000000000000B3 -:104E000000000000000000000000000000000000A2 -:104E10000000000000000000000000000000000092 -:104E20000000000000000000000000000000000082 -:104E30000000000000000000000000000000000072 -:104E40000000000000000000000000000000000062 -:104E50000000000000000000000000000000000052 -:104E60000000000000000000000000000000000042 -:104E70000000000000000000000000000000000032 -:104E80000000000000000000000000000000000022 -:104E90000000000000000000000000000000000012 -:104EA0000000000000000000000000000000000002 -:104EB00000000000000000000000000000000000F2 -:104EC00000000000000000000000000000000000E2 -:104ED00000000000000000000000000000000000D2 -:104EE00000000000000000000000000000000000C2 -:104EF00000000000000000000000000000000000B2 -:104F000000000000000000000000000000000000A1 -:104F10000000000000000000000000000000000091 -:104F20000000000000000000000000000000000081 -:104F30000000000000000000000000000000000071 -:104F40000000000000000000000000000000000061 -:104F50000000000000000000000000000000000051 -:104F60000000000000000000000000000000000041 -:104F70000000000000000000000000000000000031 -:104F80000000000000000000000000000000000021 -:104F90000000000000000000000000000000000011 -:104FA0000000000000000000000000000000000001 -:104FB00000000000000000000000000000000000F1 -:104FC00000000000000000000000000000000000E1 -:104FD00000000000000000000000000000000000D1 -:104FE00000000000000000000000000000000000C1 -:104FF00000000000000000000000000000000000B1 -:1050000000000000000000000000000000000000A0 -:105010000000000000000000000000000000000090 -:105020000000000000000000000000000000000080 -:105030000000000000000000000000000000000070 -:105040000000000000000000000000000000000060 -:105050000000000000000000000000000000000050 -:105060000000000000000000000000000000000040 -:105070000000000000000000000000000000000030 -:105080000000000000000000000000000000000020 -:105090000000000000000000000000000000000010 -:1050A0000000000000000000000000000000000000 -:1050B00000000000000000000000000000000000F0 -:1050C00000000000000000000000000000000000E0 -:1050D00000000000000000000000000000000000D0 -:1050E00000000000000000000000000000000000C0 -:1050F00000000000000000000000000000000000B0 -:10510000000000000000000000000000000000009F -:10511000000000000000000000000000000000008F -:10512000000000000000000000000000000000007F -:10513000000000000000000000000000000000006F -:10514000000000000000000000000000000000005F -:10515000000000000000000000000000000000004F -:10516000000000000000000000000000000000003F -:10517000000000000000000000000000000000002F -:10518000000000000000000000000000000000001F -:10519000000000000000000000000000000000000F -:1051A00000000000000000000000000000000000FF -:1051B00000000000000000000000000000000000EF -:1051C00000000000000000000000000000000000DF -:1051D00000000000000000000000000000000000CF -:1051E00000000000000000000000000000000000BF -:1051F00000000000000000000000000000000000AF -:10520000000000000000000000000000000000009E -:10521000000000000000000000000000000000008E -:10522000000000000000000000000000000000007E -:10523000000000000000000000000000000000006E -:10524000000000000000000000000000000000005E -:10525000000000000000000000000000000000004E -:10526000000000000000000000000000000000003E -:10527000000000000000000000000000000000002E -:10528000000000000000000000000000000000001E -:10529000000000000000000000000000000000000E -:1052A00000000000000000000000000000000000FE -:1052B00000000000000000000000000000000000EE -:1052C00000000000000000000000000000000000DE -:1052D00000000000000000000000000000000000CE -:1052E00000000000000000000000000000000000BE -:1052F00000000000000000000000000000000000AE -:10530000000000000000000000000000000000009D -:10531000000000000000000000000000000000008D -:10532000000000000000000000000000000000007D -:10533000000000000000000000000000000000006D -:10534000000000000000000000000000000000005D -:10535000000000000000000000000000000000004D -:10536000000000000000000000000000000000003D -:10537000000000000000000000000000000000002D -:10538000000000000000000000000000000000001D -:10539000000000000000000000000000000000000D -:1053A00000000000000000000000000000000000FD -:1053B00000000000000000000000000000000000ED -:1053C00000000000000000000000000000000000DD -:1053D00000000000000000000000000000000000CD -:1053E00000000000000000000000000000000000BD -:1053F00000000000000000000000000000000000AD -:10540000000000000000000000000000000000009C -:10541000000000000000000000000000000000008C -:10542000000000000000000000000000000000007C -:10543000000000000000000000000000000000006C -:10544000000000000000000000000000000000005C -:10545000000000000000000000000000000000004C -:10546000000000000000000000000000000000003C -:10547000000000000000000000000000000000002C -:10548000000000000000000000000000000000001C -:10549000000000000000000000000000000000000C -:1054A00000000000000000000000000000000000FC -:1054B00000000000000000000000000000000000EC -:1054C00000000000000000000000000000000000DC -:1054D00000000000000000000000000000000000CC -:1054E00000000000000000000000000000000000BC -:1054F00000000000000000000000000000000000AC -:10550000000000000000000000000000000000009B -:10551000000000000000000000000000000000008B -:10552000000000000000000000000000000000007B -:10553000000000000000000000000000000000006B -:10554000000000000000000000000000000000005B -:10555000000000000000000000000000000000004B -:10556000000000000000000000000000000000003B -:10557000000000000000000000000000000000002B -:10558000000000000000000000000000000000001B -:10559000000000000000000000000000000000000B -:1055A00000000000000000000000000000000000FB -:1055B00000000000000000000000000000000000EB -:1055C00000000000000000000000000000000000DB -:1055D00000000000000000000000000000000000CB -:1055E00000000000000000000000000000000000BB -:1055F00000000000000000000000000000000000AB -:10560000000000000000000000000000000000009A -:10561000000000000000000000000000000000008A -:10562000000000000000000000000000000000007A -:10563000000000000000000000000000000000006A -:10564000000000000000000000000000000000005A -:10565000000000000000000000000000000000004A -:10566000000000000000000000000000000000003A -:10567000000000000000000000000000000000002A -:10568000000000000000000000000000000000001A -:10569000000000000000000000000000000000000A -:1056A00000000000000000000000000000000000FA -:1056B00000000000000000000000000000000000EA -:1056C00000000000000000000000000000000000DA -:1056D00000000000000000000000000000000000CA -:1056E00000000000000000000000000000000000BA -:1056F00000000000000000000000000000000000AA -:105700000000000000000000000000000000000099 -:105710000000000000000000000000000000000089 -:105720000000000000000000000000000000000079 -:105730000000000000000000000000000000000069 -:105740000000000000000000000000000000000059 -:105750000000000000000000000000000000000049 -:105760000000000000000000000000000000000039 -:105770000000000000000000000000000000000029 -:105780000000000000000000000000000000000019 -:105790000000000000000000000000000000000009 -:1057A00000000000000000000000000000000000F9 -:1057B00000000000000000000000000000000000E9 -:1057C00000000000000000000000000000000000D9 -:1057D00000000000000000000000000000000000C9 -:1057E00000000000000000000000000000000000B9 -:1057F00000000000000000000000000000000000A9 -:105800000000000000000000000000000000000098 -:105810000000000000000000000000000000000088 -:105820000000000000000000000000000000000078 -:105830000000000000000000000000000000000068 -:105840000000000000000000000000000000000058 -:105850000000000000000000000000000000000048 -:105860000000000000000000000000000000000038 -:105870000000000000000000000000000000000028 -:105880000000000000000000000000000000000018 -:105890000000000000000000000000000000000008 -:1058A00000000000000000000000000000000000F8 -:1058B00000000000000000000000000000000000E8 -:1058C00000000000000000000000000000000000D8 -:1058D00000000000000000000000000000000000C8 -:1058E00000000000000000000000000000000000B8 -:1058F00000000000000000000000000000000000A8 -:105900000000000000000000000000000000000097 -:105910000000000000000000000000000000000087 -:105920000000000000000000000000000000000077 -:105930000000000000000000000000000000000067 -:105940000000000000000000000000000000000057 -:105950000000000000000000000000000000000047 -:105960000000000000000000000000000000000037 -:105970000000000000000000000000000000000027 -:105980000000000000000000000000000000000017 -:105990000000000000000000000000000000000007 -:1059A00000000000000000000000000000000000F7 -:1059B00000000000000000000000000000000000E7 -:1059C00000000000000000000000000000000000D7 -:1059D00000000000000000000000000000000000C7 -:1059E00000000000000000000000000000000000B7 -:1059F00000000000000000000000000000000000A7 -:105A00000000000000000000000000000000000096 -:105A10000000000000000000000000000000000086 -:105A20000000000000000000000000000000000076 -:105A30000000000000000000000000000000000066 -:105A40000000000000000000000000000000000056 -:105A50000000000000000000000000000000000046 -:105A60000000000000000000000000000000000036 -:105A70000000000000000000000000000000000026 -:105A80000000000000000000000000000000000016 -:105A90000000000000000000000000000000000006 -:105AA00000000000000000000000000000000000F6 -:105AB00000000000000000000000000000000000E6 -:105AC00000000000000000000000000000000000D6 -:105AD00000000000000000000000000000000000C6 -:105AE00000000000000000000000000000000000B6 -:105AF00000000000000000000000000000000000A6 -:105B00000000000000000000000000000000000095 -:105B10000000000000000000000000000000000085 -:105B20000000000000000000000000000000000075 -:105B30000000000000000000000000000000000065 -:105B40000000000000000000000000000000000055 -:105B50000000000000000000000000000000000045 -:105B60000000000000000000000000000000000035 -:105B70000000000000000000000000000000000025 -:105B80000000000000000000000000000000000015 -:105B90000000000000000000000000000000000005 -:105BA00000000000000000000000000000000000F5 -:105BB00000000000000000000000000000000000E5 -:105BC00000000000000000000000000000000000D5 -:105BD00000000000000000000000000000000000C5 -:105BE00000000000000000000000000000000000B5 -:105BF00000000000000000000000000000000000A5 -:105C00000000000000000000000000000000000094 -:105C10000000000000000000000000000000000084 -:105C20000000000000000000000000000000000074 -:105C30000000000000000000000000000000000064 -:105C40000000000000000000000000000000000054 -:105C50000000000000000000000000000000000044 -:105C60000000000000000000000000000000000034 -:105C70000000000000000000000000000000000024 -:105C80000000000000000000000000000000000014 -:105C90000000000000000000000000000000000004 -:105CA00000000000000000000000000000000000F4 -:105CB00000000000000000000000000000000000E4 -:105CC00000000000000000000000000000000000D4 -:105CD00000000000000000000000000000000000C4 -:105CE00000000000000000000000000000000000B4 -:105CF00000000000000000000000000000000000A4 -:105D00000000000000000000000000000000000093 -:105D10000000000000000000000000000000000083 -:105D20000000000000000000000000000000000073 -:105D30000000000000000000000000000000000063 -:105D40000000000000000000000000000000000053 -:105D50000000000000000000000000000000000043 -:105D60000000000000000000000000000000000033 -:105D70000000000000000000000000000000000023 -:105D80000000000000000000000000000000000013 -:105D90000000000000000000000000000000000003 -:105DA00000000000000000000000000000000000F3 -:105DB00000000000000000000000000000000000E3 -:105DC00000000000000000000000000000000000D3 -:105DD00000000000000000000000000000000000C3 -:105DE00000000000000000000000000000000000B3 -:105DF00000000000000000000000000000000000A3 -:105E00000000000000000000000000000000000092 -:105E10000000000000000000000000000000000082 -:105E20000000000000000000000000000000000072 -:105E30000000000000000000000000000000000062 -:105E40000000000000000000000000000000000052 -:105E50000000000000000000000000000000000042 -:105E60000000000000000000000000000000000032 -:105E70000000000000000000000000000000000022 -:105E80000000000000000000000000000000000012 -:105E90000000000000000000000000000000000002 -:105EA00000000000000000000000000000000000F2 -:105EB00000000000000000000000000000000000E2 -:105EC00000000000000000000000000000000000D2 -:105ED00000000000000000000000000000000000C2 -:105EE00000000000000000000000000000000000B2 -:105EF00000000000000000000000000000000000A2 -:105F00000000000000000000000000000000000091 -:105F10000000000000000000000000000000000081 -:105F20000000000000000000000000000000000071 -:105F30000000000000000000000000000000000061 -:105F40000000000000000000000000000000000051 -:105F50000000000000000000000000000000000041 -:105F60000000000000000000000000000000000031 -:105F70000000000000000000000000000000000021 -:105F80000000000000000000000000000000000011 -:105F90000000000000000000000000000000000001 -:105FA00000000000000000000000000000000000F1 -:105FB00000000000000000000000000000000000E1 -:105FC00000000000000000000000000000000000D1 -:105FD00000000000000000000000000000000000C1 -:105FE00000000000000000000000000000000000B1 -:105FF00000000000000000000000000000000000A1 -:106000000000000000000000000000000000000090 -:106010000000000000000000000000000000000080 -:106020000000000000000000000000000000000070 -:106030000000000000000000000000000000000060 -:106040000000000000000000000000000000000050 -:106050000000000000000000000000000000000040 -:106060000000000000000000000000000000000030 -:106070000000000000000000000000000000000020 -:106080000000000000000000000000000000000010 -:106090000000000000000000000000000000000000 -:1060A00000000000000000000000000000000000F0 -:1060B00000000000000000000000000000000000E0 -:1060C00000000000000000000000000000000000D0 -:1060D00000000000000000000000000000000000C0 -:1060E00000000000000000000000000000000000B0 -:1060F00000000000000000000000000000000000A0 -:10610000000000000000000000000000000000008F -:10611000000000000000000000000000000000007F -:10612000000000000000000000000000000000006F -:10613000000000000000000000000000000000005F -:10614000000000000000000000000000000000004F -:10615000000000000000000000000000000000003F -:10616000000000000000000000000000000000002F -:10617000000000000000000000000000000000001F -:10618000000000000000000000000000000000000F -:1061900000000000000000000000000000000000FF -:1061A00000000000000000000000000000000000EF -:1061B00000000000000000000000000000000000DF -:1061C00000000000000000000000000000000000CF -:1061D00000000000000000000000000000000000BF -:1061E00000000000000000000000000000000000AF -:1061F000000000000000000000000000000000009F -:10620000000000000000000000000000000000008E -:10621000000000000000000000000000000000007E -:10622000000000000000000000000000000000006E -:10623000000000000000000000000000000000005E -:10624000000000000000000000000000000000004E -:10625000000000000000000000000000000000003E -:10626000000000000000000000000000000000002E -:10627000000000000000000000000000000000001E -:10628000000000000000000000000000000000000E -:1062900000000000000000000000000000000000FE -:1062A00000000000000000000000000000000000EE -:1062B00000000000000000000000000000000000DE -:1062C00000000000000000000000000000000000CE -:1062D00000000000000000000000000000000000BE -:1062E00000000000000000000000000000000000AE -:1062F000000000000000000000000000000000009E -:10630000000000000000000000000000000000008D -:10631000000000000000000000000000000000007D -:10632000000000000000000000000000000000006D -:10633000000000000000000000000000000000005D -:10634000000000000000000000000000000000004D -:10635000000000000000000000000000000000003D -:10636000000000000000000000000000000000002D -:10637000000000000000000000000000000000001D -:10638000000000000000000000000000000000000D -:1063900000000000000000000000000000000000FD -:1063A00000000000000000000000000000000000ED -:1063B00000000000000000000000000000000000DD -:1063C00000000000000000000000000000000000CD -:1063D00000000000000000000000000000000000BD -:1063E00000000000000000000000000000000000AD -:1063F000000000000000000000000000000000009D -:10640000000000000000000000000000000000008C -:10641000000000000000000000000000000000007C -:10642000000000000000000000000000000000006C -:10643000000000000000000000000000000000005C -:10644000000000000000000000000000000000004C -:10645000000000000000000000000000000000003C -:10646000000000000000000000000000000000002C -:10647000000000000000000000000000000000001C -:10648000000000000000000000000000000000000C -:1064900000000000000000000000000000000000FC -:1064A00000000000000000000000000000000000EC -:1064B00000000000000000000000000000000000DC -:1064C00000000000000000000000000000000000CC -:1064D00000000000000000000000000000000000BC -:1064E00000000000000000000000000000000000AC -:1064F000000000000000000000000000000000009C -:10650000000000000000000000000000000000008B -:10651000000000000000000000000000000000007B -:10652000000000000000000000000000000000006B -:10653000000000000000000000000000000000005B -:10654000000000000000000000000000000000004B -:10655000000000000000000000000000000000003B -:10656000000000000000000000000000000000002B -:10657000000000000000000000000000000000001B -:10658000000000000000000000000000000000000B -:1065900000000000000000000000000000000000FB -:1065A00000000000000000000000000000000000EB -:1065B00000000000000000000000000000000000DB -:1065C00000000000000000000000000000000000CB -:1065D00000000000000000000000000000000000BB -:1065E00000000000000000000000000000000000AB -:1065F000000000000000000000000000000000009B -:10660000000000000000000000000000000000008A -:10661000000000000000000000000000000000007A -:10662000000000000000000000000000000000006A -:10663000000000000000000000000000000000005A -:10664000000000000000000000000000000000004A -:10665000000000000000000000000000000000003A -:10666000000000000000000000000000000000002A -:10667000000000000000000000000000000000001A -:10668000000000000000000000000000000000000A -:1066900000000000000000000000000000000000FA -:1066A00000000000000000000000000000000000EA -:1066B00000000000000000000000000000000000DA -:1066C00000000000000000000000000000000000CA -:1066D00000000000000000000000000000000000BA -:1066E00000000000000000000000000000000000AA -:1066F000000000000000000000000000000000009A -:106700000000000000000000000000000000000089 -:106710000000000000000000000000000000000079 -:106720000000000000000000000000000000000069 -:106730000000000000000000000000000000000059 -:106740000000000000000000000000000000000049 -:106750000000000000000000000000000000000039 -:106760000000000000000000000000000000000029 -:106770000000000000000000000000000000000019 -:106780000000000000000000000000000000000009 -:1067900000000000000000000000000000000000F9 -:1067A00000000000000000000000000000000000E9 -:1067B00000000000000000000000000000000000D9 -:1067C00000000000000000000000000000000000C9 -:1067D00000000000000000000000000000000000B9 -:1067E00000000000000000000000000000000000A9 -:1067F0000000000000000000000000000000000099 -:106800000000000000000000000000000000000088 -:106810000000000000000000000000000000000078 -:106820000000000000000000000000000000000068 -:106830000000000000000000000000000000000058 -:106840000000000000000000000000000000000048 -:106850000000000000000000000000000000000038 -:106860000000000000000000000000000000000028 -:106870000000000000000000000000000000000018 -:106880000000000000000000000000000000000008 -:1068900000000000000000000000000000000000F8 -:1068A00000000000000000000000000000000000E8 -:1068B00000000000000000000000000000000000D8 -:1068C00000000000000000000000000000000000C8 -:1068D00000000000000000000000000000000000B8 -:1068E00000000000000000000000000000000000A8 -:1068F0000000000000000000000000000000000098 -:106900000000000000000000000000000000000087 -:106910000000000000000000000000000000000077 -:106920000000000000000000000000000000000067 -:106930000000000000000000000000000000000057 -:106940000000000000000000000000000000000047 -:106950000000000000000000000000000000000037 -:106960000000000000000000000000000000000027 -:106970000000000000000000000000000000000017 -:106980000000000000000000000000000000000007 -:1069900000000000000000000000000000000000F7 -:1069A00000000000000000000000000000000000E7 -:1069B00000000000000000000000000000000000D7 -:1069C00000000000000000000000000000000000C7 -:1069D00000000000000000000000000000000000B7 -:1069E00000000000000000000000000000000000A7 -:1069F0000000000000000000000000000000000097 -:106A00000000000000000000000000000000000086 -:106A10000000000000000000000000000000000076 -:106A20000000000000000000000000000000000066 -:106A30000000000000000000000000000000000056 -:106A40000000000000000000000000000000000046 -:106A50000000000000000000000000000000000036 -:106A60000000000000000000000000000000000026 -:106A70000000000000000000000000000000000016 -:106A80000000000000000000000000000000000006 -:106A900000000000000000000000000000000000F6 -:106AA00000000000000000000000000000000000E6 -:106AB00000000000000000000000000000000000D6 -:106AC00000000000000000000000000000000000C6 -:106AD00000000000000000000000000000000000B6 -:106AE00000000000000000000000000000000000A6 -:106AF0000000000000000000000000000000000096 -:106B00000000000000000000000000000000000085 -:106B10000000000000000000000000000000000075 -:106B20000000000000000000000000000000000065 -:106B30000000000000000000000000000000000055 -:106B40000000000000000000000000000000000045 -:106B50000000000000000000000000000000000035 -:106B60000000000000000000000000000000000025 -:106B70000000000000000000000000000000000015 -:106B80000000000000000000000000000000000005 -:106B900000000000000000000000000000000000F5 -:106BA00000000000000000000000000000000000E5 -:106BB00000000000000000000000000000000000D5 -:106BC00000000000000000000000000000000000C5 -:106BD00000000000000000000000000000000000B5 -:106BE00000000000000000000000000000000000A5 -:106BF0000000000000000000000000000000000095 -:106C00000000000000000000000000000000000084 -:106C10000000000000000000000000000000000074 -:106C20000000000000000000000000000000000064 -:106C30000000000000000000000000000000000054 -:106C40000000000000000000000000000000000044 -:106C50000000000000000000000000000000000034 -:106C60000000000000000000000000000000000024 -:106C70000000000000000000000000000000000014 -:106C80000000000000000000000000000000000004 -:106C900000000000000000000000000000000000F4 -:106CA00000000000000000000000000000000000E4 -:106CB00000000000000000000000000000000000D4 -:106CC00000000000000000000000000000000000C4 -:106CD00000000000000000000000000000000000B4 -:106CE00000000000000000000000000000000000A4 -:106CF0000000000000000000000000000000000094 -:106D00000000000000000000000000000000000083 -:106D10000000000000000000000000000000000073 -:106D20000000000000000000000000000000000063 -:106D30000000000000000000000000000000000053 -:106D40000000000000000000000000000000000043 -:106D50000000000000000000000000000000000033 -:106D60000000000000000000000000000000000023 -:106D70000000000000000000000000000000000013 -:106D80000000000000000000000000000000000003 -:106D900000000000000000000000000000000000F3 -:106DA00000000000000000000000000000000000E3 -:106DB00000000000000000000000000000000000D3 -:106DC00000000000000000000000000000000000C3 -:106DD00000000000000000000000000000000000B3 -:106DE00000000000000000000000000000000000A3 -:106DF0000000000000000000000000000000000093 -:106E00000000000000000000000000000000000082 -:106E10000000000000000000000000000000000072 -:106E20000000000000000000000000000000000062 -:106E30000000000000000000000000000000000052 -:106E40000000000000000000000000000000000042 -:106E50000000000000000000000000000000000032 -:106E60000000000000000000000000000000000022 -:106E70000000000000000000000000000000000012 -:106E80000000000000000000000000000000000002 -:106E900000000000000000000000000000000000F2 -:106EA00000000000000000000000000000000000E2 -:106EB00000000000000000000000000000000000D2 -:106EC00000000000000000000000000000000000C2 -:106ED00000000000000000000000000000000000B2 -:106EE00000000000000000000000000000000000A2 -:106EF0000000000000000000000000000000000092 -:106F00000000000000000000000000000000000081 -:106F10000000000000000000000000000000000071 -:106F20000000000000000000000000000000000061 -:106F30000000000000000000000000000000000051 -:106F40000000000000000000000000000000000041 -:106F50000000000000000000000000000000000031 -:106F60000000000000000000000000000000000021 -:106F70000000000000000000000000000000000011 -:106F80000000000000000000000000000000000001 -:106F900000000000000000000000000000000000F1 -:106FA00000000000000000000000000000000000E1 -:106FB00000000000000000000000000000000000D1 -:106FC00000000000000000000000000000000000C1 -:106FD00000000000000000000000000000000000B1 -:106FE00000000000000000000000000000000000A1 -:106FF0000000000000000000000000000000000091 -:107000000000000000000000000000000000000080 -:107010000000000000000000000000000000000070 -:107020000000000000000000000000000000000060 -:107030000000000000000000000000000000000050 -:107040000000000000000000000000000000000040 -:107050000000000000000000000000000000000030 -:107060000000000000000000000000000000000020 -:107070000000000000000000000000000000000010 -:107080000000000000000000000000000000000000 -:1070900000000000000000000000000000000000F0 -:1070A00000000000000000000000000000000000E0 -:1070B00000000000000000000000000000000000D0 -:1070C00000000000000000000000000000000000C0 -:1070D00000000000000000000000000000000000B0 -:1070E00000000000000000000000000000000000A0 -:1070F0000000000000000000000000000000000090 -:10710000000000000000000000000000000000007F -:10711000000000000000000000000000000000006F -:10712000000000000000000000000000000000005F -:10713000000000000000000000000000000000004F -:10714000000000000000000000000000000000003F -:10715000000000000000000000000000000000002F -:10716000000000000000000000000000000000001F -:10717000000000000000000000000000000000000F -:1071800000000000000000000000000000000000FF -:1071900000000000000000000000000000000000EF -:1071A00000000000000000000000000000000000DF -:1071B00000000000000000000000000000000000CF -:1071C00000000000000000000000000000000000BF -:1071D00000000000000000000000000000000000AF -:1071E000000000000000000000000000000000009F -:1071F000000000000000000000000000000000008F -:10720000000000000000000000000000000000007E -:10721000000000000000000000000000000000006E -:10722000000000000000000000000000000000005E -:10723000000000000000000000000000000000004E -:10724000000000000000000000000000000000003E -:10725000000000000000000000000000000000002E -:10726000000000000000000000000000000000001E -:10727000000000000000000000000000000000000E -:1072800000000000000000000000000000000000FE -:1072900000000000000000000000000000000000EE -:1072A00000000000000000000000000000000000DE -:1072B00000000000000000000000000000000000CE -:1072C00000000000000000000000000000000000BE -:1072D00000000000000000000000000000000000AE -:1072E000000000000000000000000000000000009E -:1072F000000000000000000000000000000000008E -:10730000000000000000000000000000000000007D -:10731000000000000000000000000000000000006D -:10732000000000000000000000000000000000005D -:10733000000000000000000000000000000000004D -:10734000000000000000000000000000000000003D -:10735000000000000000000000000000000000002D -:10736000000000000000000000000000000000001D -:10737000000000000000000000000000000000000D -:1073800000000000000000000000000000000000FD -:1073900000000000000000000000000000000000ED -:1073A00000000000000000000000000000000000DD -:1073B00000000000000000000000000000000000CD -:1073C00000000000000000000000000000000000BD -:1073D00000000000000000000000000000000000AD -:1073E000000000000000000000000000000000009D -:1073F000000000000000000000000000000000008D -:10740000000000000000000000000000000000007C -:10741000000000000000000000000000000000006C -:10742000000000000000000000000000000000005C -:10743000000000000000000000000000000000004C -:10744000000000000000000000000000000000003C -:10745000000000000000000000000000000000002C -:10746000000000000000000000000000000000001C -:10747000000000000000000000000000000000000C -:1074800000000000000000000000000000000000FC -:1074900000000000000000000000000000000000EC -:1074A00000000000000000000000000000000000DC -:1074B00000000000000000000000000000000000CC -:1074C00000000000000000000000000000000000BC -:1074D00000000000000000000000000000000000AC -:1074E000000000000000000000000000000000009C -:1074F000000000000000000000000000000000008C -:10750000000000000000000000000000000000007B -:10751000000000000000000000000000000000006B -:10752000000000000000000000000000000000005B -:10753000000000000000000000000000000000004B -:10754000000000000000000000000000000000003B -:10755000000000000000000000000000000000002B -:10756000000000000000000000000000000000001B -:10757000000000000000000000000000000000000B -:1075800000000000000000000000000000000000FB -:1075900000000000000000000000000000000000EB -:1075A00000000000000000000000000000000000DB -:1075B00000000000000000000000000000000000CB -:1075C00000000000000000000000000000000000BB -:1075D00000000000000000000000000000000000AB -:1075E000000000000000000000000000000000009B -:1075F000000000000000000000000000000000008B -:10760000000000000000000000000000000000007A -:10761000000000000000000000000000000000006A -:10762000000000000000000000000000000000005A -:10763000000000000000000000000000000000004A -:10764000000000000000000000000000000000003A -:10765000000000000000000000000000000000002A -:10766000000000000000000000000000000000001A -:10767000000000000000000000000000000000000A -:1076800000000000000000000000000000000000FA -:1076900000000000000000000000000000000000EA -:1076A00000000000000000000000000000000000DA -:1076B00000000000000000000000000000000000CA -:1076C00000000000000000000000000000000000BA -:1076D00000000000000000000000000000000000AA -:1076E000000000000000000000000000000000009A -:1076F000000000000000000000000000000000008A -:107700000000000000000000000000000000000079 -:107710000000000000000000000000000000000069 -:107720000000000000000000000000000000000059 -:107730000000000000000000000000000000000049 -:107740000000000000000000000000000000000039 -:107750000000000000000000000000000000000029 -:107760000000000000000000000000000000000019 -:107770000000000000000000000000000000000009 -:1077800000000000000000000000000000000000F9 -:1077900000000000000000000000000000000000E9 -:1077A00000000000000000000000000000000000D9 -:1077B00000000000000000000000000000000000C9 -:1077C00000000000000000000000000000000000B9 -:1077D00000000000000000000000000000000000A9 -:1077E0000000000000000000000000000000000099 -:1077F0000000000000000000000000000000000089 -:107800000000000000000000000000000000000078 -:107810000000000000000000000000000000000068 -:107820000000000000000000000000000000000058 -:107830000000000000000000000000000000000048 -:107840000000000000000000000000000000000038 -:107850000000000000000000000000000000000028 -:107860000000000000000000000000000000000018 -:107870000000000000000000000000000000000008 -:1078800000000000000000000000000000000000F8 -:1078900000000000000000000000000000000000E8 -:1078A00000000000000000000000000000000000D8 -:1078B00000000000000000000000000000000000C8 -:1078C00000000000000000000000000000000000B8 -:1078D00000000000000000000000000000000000A8 -:1078E0000000000000000000000000000000000098 -:1078F0000000000000000000000000000000000088 -:107900000000000000000000000000000000000077 -:107910000000000000000000000000000000000067 -:107920000000000000000000000000000000000057 -:107930000000000000000000000000000000000047 -:107940000000000000000000000000000000000037 -:107950000000000000000000000000000000000027 -:107960000000000000000000000000000000000017 -:107970000000000000000000000000000000000007 -:1079800000000000000000000000000000000000F7 -:1079900000000000000000000000000000000000E7 -:1079A00000000000000000000000000000000000D7 -:1079B00000000000000000000000000000000000C7 -:1079C00000000000000000000000000000000000B7 -:1079D00000000000000000000000000000000000A7 -:1079E0000000000000000000000000000000000097 -:1079F0000000000000000000000000000000000087 -:107A00000000000000000000000000000000000076 -:107A10000000000000000000000000000000000066 -:107A20000000000000000000000000000000000056 -:107A30000000000000000000000000000000000046 -:107A40000000000000000000000000000000000036 -:107A50000000000000000000000000000000000026 -:107A60000000000000000000000000000000000016 -:107A70000000000000000000000000000000000006 -:107A800000000000000000000000000000000000F6 -:107A900000000000000000000000000000000000E6 -:107AA00000000000000000000000000000000000D6 -:107AB00000000000000000000000000000000000C6 -:107AC00000000000000000000000000000000000B6 -:107AD00000000000000000000000000000000000A6 -:107AE0000000000000000000000000000000000096 -:107AF0000000000000000000000000000000000086 -:107B00000000000000000000000000000000000075 -:107B10000000000000000000000000000000000065 -:107B20000000000000000000000000000000000055 -:107B30000000000000000000000000000000000045 -:107B40000000000000000000000000000000000035 -:107B50000000000000000000000000000000000025 -:107B60000000000000000000000000000000000015 -:107B70000000000000000000000000000000000005 -:107B800000000000000000000000000000000000F5 -:107B900000000000000000000000000000000000E5 -:107BA00000000000000000000000000000000000D5 -:107BB00000000000000000000000000000000000C5 -:107BC00000000000000000000000000000000000B5 -:107BD00000000000000000000000000000000000A5 -:107BE0000000000000000000000000000000000095 -:107BF0000000000000000000000000000000000085 -:107C00000000000000000000000000000000000074 -:107C10000000000000000000000000000000000064 -:107C20000000000000000000000000000000000054 -:107C30000000000000000000000000000000000044 -:107C40000000000000000000000000000000000034 -:107C50000000000000000000000000000000000024 -:107C60000000000000000000000000000000000014 -:107C70000000000000000000000000000000000004 -:107C800000000000000000000000000000000000F4 -:107C900000000000000000000000000000000000E4 -:107CA00000000000000000000000000000000000D4 -:107CB00000000000000000000000000000000000C4 -:107CC00000000000000000000000000000000000B4 -:107CD00000000000000000000000000000000000A4 -:107CE0000000000000000000000000000000000094 -:107CF0000000000000000000000000000000000084 -:107D00000000000000000000000000000000000073 -:107D10000000000000000000000000000000000063 -:107D20000000000000000000000000000000000053 -:107D30000000000000000000000000000000000043 -:107D40000000000000000000000000000000000033 -:107D50000000000000000000000000000000000023 -:107D60000000000000000000000000000000000013 -:107D70000000000000000000000000000000000003 -:107D800000000000000000000000000000000000F3 -:107D900000000000000000000000000000000000E3 -:107DA00000000000000000000000000000000000D3 -:107DB00000000000000000000000000000000000C3 -:107DC00000000000000000000000000000000000B3 -:107DD00000000000000000000000000000000000A3 -:107DE0000000000000000000000000000000000093 -:107DF0000000000000000000000000000000000083 -:107E00000000000000000000000000000000000072 -:107E10000000000000000000000000000000000062 -:107E20000000000000000000000000000000000052 -:107E30000000000000000000000000000000000042 -:107E40000000000000000000000000000000000032 -:107E50000000000000000000000000000000000022 -:107E60000000000000000000000000000000000012 -:107E70000000000000000000000000000000000002 -:107E800000000000000000000000000000000000F2 -:107E900000000000000000000000000000000000E2 -:107EA00000000000000000000000000000000000D2 -:107EB00000000000000000000000000000000000C2 -:107EC00000000000000000000000000000000000B2 -:107ED00000000000000000000000000000000000A2 -:107EE0000000000000000000000000000000000092 -:107EF0000000000000000000000000000000000082 -:107F00000000000000000000000000000000000071 -:107F10000000000000000000000000000000000061 -:107F20000000000000000000000000000000000051 -:107F30000000000000000000000000000000000041 -:107F40000000000000000000000000000000000031 -:107F50000000000000000000000000000000000021 -:107F60000000000000000000000000000000000011 -:107F70000000000000000000000000000000000001 -:107F800000000000000000000000000000000000F1 -:107F900000000000000000000000000000000000E1 -:107FA00000000000000000000000000000000000D1 -:107FB00000000000000000000000000000000000C1 -:107FC00000000000000000000000000000000000B1 -:107FD00000000000000000000000000000000000A1 -:107FE0000000000000000000000000000000000091 -:107FF0000000000000000000000000000000000081 -:108000000000000000000000000000000000000070 -:108010000000000000000000000000000000000060 -:108020000000000000000000000000000000000050 -:108030000000000000000000000000000000000040 -:108040000000000000000000000000000000000030 -:108050000000000000000000000000000000000020 -:108060000000000000000000000000000000000010 -:108070000000000000000000000000000000000000 -:1080800000000000000000000000000000000000F0 -:1080900000000000000000000000000000000000E0 -:1080A00000000000000000000000000000000000D0 -:1080B00000000000000000000000000000000000C0 -:1080C00000000000000000000000000000000000B0 -:1080D00000000000000000000000000000000000A0 -:1080E0000000000000000000000000000000000090 -:1080F0000000000000000000000000000000000080 -:10810000000000000000000000000000000000006F -:10811000000000000000000000000000000000005F -:10812000000000000000000000000000000000004F -:10813000000000000000000000000000000000003F -:10814000000000000000000000000000000000002F -:10815000000000000000000000000000000000001F -:10816000000000000000000000000000000000000F -:1081700000000000000000000000000000000000FF -:1081800000000000000000000000000000000000EF -:1081900000000000000000000000000000000000DF -:1081A00000000000000000000000000000000000CF -:1081B00000000000000000000000000000000000BF -:1081C00000000000000000000000000000000000AF -:1081D000000000000000000000000000000000009F -:1081E000000000000000000000000000000000008F -:1081F000000000000000000000000000000000007F -:10820000000000000000000000000000000000006E -:10821000000000000000000000000000000000005E -:10822000000000000000000000000000000000004E -:10823000000000000000000000000000000000003E -:10824000000000000000000000000000000000002E -:10825000000000000000000000000000000000001E -:10826000000000000000000000000000000000000E -:1082700000000000000000000000000000000000FE -:1082800000000000000000000000000000000000EE -:1082900000000000000000000000000000000000DE -:1082A00000000000000000000000000000000000CE -:1082B00000000000000000000000000000000000BE -:1082C00000000000000000000000000000000000AE -:1082D000000000000000000000000000000000009E -:1082E000000000000000000000000000000000008E -:1082F000000000000000000000000000000000007E -:10830000000000000000000000000000000000006D -:10831000000000000000000000000000000000005D -:10832000000000000000000000000000000000004D -:10833000000000000000000000000000000000003D -:10834000000000000000000000000000000000002D -:10835000000000000000000000000000000000001D -:10836000000000000000000000000000000000000D -:1083700000000000000000000000000000000000FD -:1083800000000000000000000000000000000000ED -:1083900000000000000000000000000000000000DD -:1083A00000000000000000000000000000000000CD -:1083B00000000000000000000000000000000000BD -:1083C00000000000000000000000000000000000AD -:1083D000000000000000000000000000000000009D -:1083E000000000000000000000000000000000008D -:1083F000000000000000000000000000000000007D -:10840000000000000000000000000000000000006C -:10841000000000000000000000000000000000005C -:10842000000000000000000000000000000000004C -:10843000000000000000000000000000000000003C -:10844000000000000000000000000000000000002C -:10845000000000000000000000000000000000001C -:10846000000000000000000000000000000000000C -:1084700000000000000000000000000000000000FC -:1084800000000000000000000000000000000000EC -:1084900000000000000000000000000000000000DC -:1084A00000000000000000000000000000000000CC -:1084B00000000000000000000000000000000000BC -:1084C00000000000000000000000000000000000AC -:1084D000000000000000000000000000000000009C -:1084E000000000000000000000000000000000008C -:1084F000000000000000000000000000000000007C -:10850000000000000000000000000000000000006B -:10851000000000000000000000000000000000005B -:10852000000000000000000000000000000000004B -:10853000000000000000000000000000000000003B -:10854000000000000000000000000000000000002B -:10855000000000000000000000000000000000001B -:10856000000000000000000000000000000000000B -:1085700000000000000000000000000000000000FB -:1085800000000000000000000000000000000000EB -:1085900000000000000000000000000000000000DB -:1085A00000000000000000000000000000000000CB -:1085B00000000000000000000000000000000000BB -:1085C00000000000000000000000000000000000AB -:1085D000000000000000000000000000000000009B -:1085E000000000000000000000000000000000008B -:1085F000000000000000000000000000000000007B -:10860000000000000000000000000000000000006A -:10861000000000000000000000000000000000005A -:10862000000000000000000000000000000000004A -:10863000000000000000000000000000000000003A -:10864000000000000000000000000000000000002A -:10865000000000000000000000000000000000001A -:10866000000000000000000000000000000000000A -:1086700000000000000000000000000000000000FA -:1086800000000000000000000000000000000000EA -:1086900000000000000000000000000000000000DA -:1086A00000000000000000000000000000000000CA -:1086B00000000000000000000000000000000000BA -:1086C00000000000000000000000000000000000AA -:1086D000000000000000000000000000000000009A -:1086E000000000000000000000000000000000008A -:1086F000000000000000000000000000000000007A -:108700000000000000000000000000000000000069 -:108710000000000000000000000000000000000059 -:108720000000000000000000000000000000000049 -:108730000000000000000000000000000000000039 -:108740000000000000000000000000000000000029 -:108750000000000000000000000000000000000019 -:108760000000000000000000000000000000000009 -:1087700000000000000000000000000000000000F9 -:1087800000000000000000000000000000000000E9 -:1087900000000000000000000000000000000000D9 -:1087A00000000000000000000000000000000000C9 -:1087B00000000000000000000000000000000000B9 -:1087C00000000000000000000000000000000000A9 -:1087D0000000000000000000000000000000000099 -:1087E0000000000000000000000000000000000089 -:1087F0000000000000000000000000000000000079 -:108800000000000000000000000000000000000068 -:108810000000000000000000000000000000000058 -:108820000000000000000000000000000000000048 -:108830000000000000000000000000000000000038 -:108840000000000000000000000000000000000028 -:108850000000000000000000000000000000000018 -:108860000000000000000000000000000000000008 -:1088700000000000000000000000000000000000F8 -:1088800000000000000000000000000000000000E8 -:1088900000000000000000000000000000000000D8 -:1088A00000000000000000000000000000000000C8 -:1088B00000000000000000000000000000000000B8 -:1088C00000000000000000000000000000000000A8 -:1088D0000000000000000000000000000000000098 -:1088E0000000000000000000000000000000000088 -:1088F0000000000000000000000000000000000078 -:108900000000000000000000000000000000000067 -:108910000000000000000000000000000000000057 -:108920000000000000000000000000000000000047 -:108930000000000000000000000000000000000037 -:108940000000000000000000000000000000000027 -:108950000000000000000000000000000000000017 -:108960000000000000000000000000000000000007 -:1089700000000000000000000000000000000000F7 -:1089800000000000000000000000000000000000E7 -:1089900000000000000000000000000000000000D7 -:1089A00000000000000000000000000000000000C7 -:1089B00000000000000000000000000000000000B7 -:1089C00000000000000000000000000000000000A7 -:1089D0000000000000000000000000000000000097 -:1089E0000000000000000000000000000000000087 -:1089F0000000000000000000000000000000000077 -:108A00000000000000000000000000000000000066 -:108A10000000000000000000000000000000000056 -:108A20000000000000000000000000000000000046 -:108A30000000000000000000000000000000000036 -:108A40000000000000000000000000000000000026 -:108A50000000000000000000000000000000000016 -:108A60000000000000000000000000000000000006 -:108A700000000000000000000000000000000000F6 -:108A800000000000000000000000000000000000E6 -:108A900000000000000000000000000000000000D6 -:108AA00000000000000000000000000000000000C6 -:108AB00000000000000000000000000000000000B6 -:108AC00000000000000000000000000000000000A6 -:108AD0000000000000000000000000000000000096 -:108AE0000000000000000000000000000000000086 -:108AF0000000000000000000000000000000000076 -:108B00000000000000000000000000000000000065 -:108B10000000000000000000000000000000000055 -:108B20000000000000000000000000000000000045 -:108B30000000000000000000000000000000000035 -:108B40000000000000000000000000000000000025 -:108B50000000000000000000000000000000000015 -:108B60000000000000000000000000000000000005 -:108B700000000000000000000000000000000000F5 -:108B800000000000000000000000000000000000E5 -:108B900000000000000000000000000000000000D5 -:108BA00000000000000000000000000000000000C5 -:108BB00000000000000000000000000000000000B5 -:108BC00000000000000000000000000000000000A5 -:108BD0000000000000000000000000000000000095 -:108BE0000000000000000000000000000000000085 -:108BF0000000000000000000000000000000000075 -:108C00000000000000000000000000000000000064 -:108C10000000000000000000000000000000000054 -:108C20000000000000000000000000000000000044 -:108C30000000000000000000000000000000000034 -:108C40000000000000000000000000000000000024 -:108C50000000000000000000000000000000000014 -:108C60000000000000000000000000000000000004 -:108C700000000000000000000000000000000000F4 -:108C800000000000000000000000000000000000E4 -:108C900000000000000000000000000000000000D4 -:108CA00000000000000000000000000000000000C4 -:108CB00000000000000000000000000000000000B4 -:108CC00000000000000000000000000000000000A4 -:108CD0000000000000000000000000000000000094 -:108CE0000000000000000000000000000000000084 -:108CF0000000000000000000000000000000000074 -:108D00000000000000000000000000000000000063 -:108D10000000000000000000000000000000000053 -:108D20000000000000000000000000000000000043 -:108D30000000000000000000000000000000000033 -:108D40000000000000000000000000000000000023 -:108D50000000000000000000000000000000000013 -:108D60000000000000000000000000000000000003 -:108D700000000000000000000000000000000000F3 -:108D800000000000000000000000000000000000E3 -:108D900000000000000000000000000000000000D3 -:108DA00000000000000000000000000000000000C3 -:108DB00000000000000000000000000000000000B3 -:108DC00000000000000000000000000000000000A3 -:108DD0000000000000000000000000000000000093 -:108DE0000000000000000000000000000000000083 -:108DF0000000000000000000000000000000000073 -:108E00000000000000000000000000000000000062 -:108E10000000000000000000000000000000000052 -:108E20000000000000000000000000000000000042 -:108E30000000000000000000000000000000000032 -:108E40000000000000000000000000000000000022 -:108E50000000000000000000000000000000000012 -:108E60000000000000000000000000000000000002 -:108E700000000000000000000000000000000000F2 -:108E800000000000000000000000000000000000E2 -:108E900000000000000000000000000000000000D2 -:108EA00000000000000000000000000000000000C2 -:108EB00000000000000000000000000000000000B2 -:108EC00000000000000000000000000000000000A2 -:108ED0000000000000000000000000000000000092 -:108EE0000000000000000000000000000000000082 -:108EF0000000000000000000000000000000000072 -:108F00000000000000000000000000000000000061 -:108F10000000000000000000000000000000000051 -:108F20000000000000000000000000000000000041 -:108F30000000000000000000000000000000000031 -:108F40000000000000000000000000000000000021 -:108F50000000000000000000000000000000000011 -:108F60000000000000000000000000000000000001 -:108F700000000000000000000000000000000000F1 -:108F800000000000000000000000000000000000E1 -:108F900000000000000000000000000000000000D1 -:108FA00000000000000000000000000000000000C1 -:108FB00000000000000000000000000000000000B1 -:108FC00000000000000000000000000000000000A1 -:108FD0000000000000000000000000000000000091 -:108FE0000000000000000000000000000000000081 -:108FF0000000000000000000000000000000000071 -:109000000000000000000000000000000000000060 -:109010000000000000000000000000000000000050 -:109020000000000000000000000000000000000040 -:109030000000000000000000000000000000000030 -:109040000000000000000000000000000000000020 -:109050000000000000000000000000000000000010 -:109060000000000000000000000000000000000000 -:1090700000000000000000000000000000000000F0 -:1090800000000000000000000000000000000000E0 -:1090900000000000000000000000000000000000D0 -:1090A00000000000000000000000000000000000C0 -:1090B00000000000000000000000000000000000B0 -:1090C00000000000000000000000000000000000A0 -:1090D0000000000000000000000000000000000090 -:1090E0000000000000000000000000000000000080 -:1090F0000000000000000000000000000000000070 -:10910000000000000000000000000000000000005F -:10911000000000000000000000000000000000004F -:10912000000000000000000000000000000000003F -:10913000000000000000000000000000000000002F -:10914000000000000000000000000000000000001F -:10915000000000000000000000000000000000000F -:1091600000000000000000000000000000000000FF -:1091700000000000000000000000000000000000EF -:1091800000000000000000000000000000000000DF -:1091900000000000000000000000000000000000CF -:1091A00000000000000000000000000000000000BF -:1091B00000000000000000000000000000000000AF -:1091C000000000000000000000000000000000009F -:1091D000000000000000000000000000000000008F -:1091E000000000000000000000000000000000007F -:1091F000000000000000000000000000000000006F -:10920000000000000000000000000000000000005E -:10921000000000000000000000000000000000004E -:10922000000000000000000000000000000000003E -:10923000000000000000000000000000000000002E -:10924000000000000000000000000000000000001E -:10925000000000000000000000000000000000000E -:1092600000000000000000000000000000000000FE -:1092700000000000000000000000000000000000EE -:1092800000000000000000000000000000000000DE -:1092900000000000000000000000000000000000CE -:1092A00000000000000000000000000000000000BE -:1092B00000000000000000000000000000000000AE -:1092C000000000000000000000000000000000009E -:1092D000000000000000000000000000000000008E -:1092E000000000000000000000000000000000007E -:1092F000000000000000000000000000000000006E -:10930000000000000000000000000000000000005D -:10931000000000000000000000000000000000004D -:10932000000000000000000000000000000000003D -:10933000000000000000000000000000000000002D -:10934000000000000000000000000000000000001D -:10935000000000000000000000000000000000000D -:1093600000000000000000000000000000000000FD -:1093700000000000000000000000000000000000ED -:1093800000000000000000000000000000000000DD -:1093900000000000000000000000000000000000CD -:1093A00000000000000000000000000000000000BD -:1093B00000000000000000000000000000000000AD -:1093C000000000000000000000000000000000009D -:1093D000000000000000000000000000000000008D -:1093E000000000000000000000000000000000007D -:1093F000000000000000000000000000000000006D -:10940000000000000000000000000000000000005C -:10941000000000000000000000000000000000004C -:10942000000000000000000000000000000000003C -:10943000000000000000000000000000000000002C -:10944000000000000000000000000000000000001C -:10945000000000000000000000000000000000000C -:1094600000000000000000000000000000000000FC -:1094700000000000000000000000000000000000EC -:1094800000000000000000000000000000000000DC -:1094900000000000000000000000000000000000CC -:1094A00000000000000000000000000000000000BC -:1094B00000000000000000000000000000000000AC -:1094C000000000000000000000000000000000009C -:1094D000000000000000000000000000000000008C -:1094E000000000000000000000000000000000007C -:1094F000000000000000000000000000000000006C -:10950000000000000000000000000000000000005B -:10951000000000000000000000000000000000004B -:10952000000000000000000000000000000000003B -:10953000000000000000000000000000000000002B -:10954000000000000000000000000000000000001B -:10955000000000000000000000000000000000000B -:1095600000000000000000000000000000000000FB -:1095700000000000000000000000000000000000EB -:1095800000000000000000000000000000000000DB -:1095900000000000000000000000000000000000CB -:1095A00000000000000000000000000000000000BB -:1095B00000000000000000000000000000000000AB -:1095C000000000000000000000000000000000009B -:1095D000000000000000000000000000000000008B -:1095E000000000000000000000000000000000007B -:1095F000000000000000000000000000000000006B -:10960000000000000000000000000000000000005A -:10961000000000000000000000000000000000004A -:10962000000000000000000000000000000000003A -:10963000000000000000000000000000000000002A -:10964000000000000000000000000000000000001A -:10965000000000000000000000000000000000000A -:1096600000000000000000000000000000000000FA -:1096700000000000000000000000000000000000EA -:1096800000000000000000000000000000000000DA -:1096900000000000000000000000000000000000CA -:1096A00000000000000000000000000000000000BA -:1096B00000000000000000000000000000000000AA -:1096C000000000000000000000000000000000009A -:1096D000000000000000000000000000000000008A -:1096E000000000000000000000000000000000007A -:1096F000000000000000000000000000000000006A -:109700000000000000000000000000000000000059 -:109710000000000000000000000000000000000049 -:109720000000000000000000000000000000000039 -:109730000000000000000000000000000000000029 -:109740000000000000000000000000000000000019 -:109750000000000000000000000000000000000009 -:1097600000000000000000000000000000000000F9 -:1097700000000000000000000000000000000000E9 -:1097800000000000000000000000000000000000D9 -:1097900000000000000000000000000000000000C9 -:1097A00000000000000000000000000000000000B9 -:1097B00000000000000000000000000000000000A9 -:1097C0000000000000000000000000000000000099 -:1097D0000000000000000000000000000000000089 -:1097E0000000000000000000000000000000000079 -:1097F0000000000000000000000000000000000069 -:109800000000000000000000000000000000000058 -:109810000000000000000000000000000000000048 -:109820000000000000000000000000000000000038 -:109830000000000000000000000000000000000028 -:109840000000000000000000000000000000000018 -:109850000000000000000000000000000000000008 -:1098600000000000000000000000000000000000F8 -:1098700000000000000000000000000000000000E8 -:1098800000000000000000000000000000000000D8 -:1098900000000000000000000000000000000000C8 -:1098A00000000000000000000000000000000000B8 -:1098B00000000000000000000000000000000000A8 -:1098C0000000000000000000000000000000000098 -:1098D0000000000000000000000000000000000088 -:1098E0000000000000000000000000000000000078 -:1098F0000000000000000000000000000000000068 -:109900000000000000000000000000000000000057 -:109910000000000000000000000000000000000047 -:109920000000000000000000000000000000000037 -:109930000000000000000000000000000000000027 -:109940000000000000000000000000000000000017 -:109950000000000000000000000000000000000007 -:1099600000000000000000000000000000000000F7 -:1099700000000000000000000000000000000000E7 -:1099800000000000000000000000000000000000D7 -:1099900000000000000000000000000000000000C7 -:1099A00000000000000000000000000000000000B7 -:1099B00000000000000000000000000000000000A7 -:1099C0000000000000000000000000000000000097 -:1099D0000000000000000000000000000000000087 -:1099E0000000000000000000000000000000000077 -:1099F0000000000000000000000000000000000067 -:109A00000000000000000000000000000000000056 -:109A10000000000000000000000000000000000046 -:109A20000000000000000000000000000000000036 -:109A30000000000000000000000000000000000026 -:109A40000000000000000000000000000000000016 -:109A50000000000000000000000000000000000006 -:109A600000000000000000000000000000000000F6 -:109A700000000000000000000000000000000000E6 -:109A800000000000000000000000000000000000D6 -:109A900000000000000000000000000000000000C6 -:109AA00000000000000000000000000000000000B6 -:109AB00000000000000000000000000000000000A6 -:109AC0000000000000000000000000000000000096 -:109AD0000000000000000000000000000000000086 -:109AE0000000000000000000000000000000000076 -:109AF0000000000000000000000000000000000066 -:109B00000000000000000000000000000000000055 -:109B10000000000000000000000000000000000045 -:109B20000000000000000000000000000000000035 -:109B30000000000000000000000000000000000025 -:109B40000000000000000000000000000000000015 -:109B50000000000000000000000000000000000005 -:109B600000000000000000000000000000000000F5 -:109B700000000000000000000000000000000000E5 -:109B800000000000000000000000000000000000D5 -:109B900000000000000000000000000000000000C5 -:109BA00000000000000000000000000000000000B5 -:109BB00000000000000000000000000000000000A5 -:109BC0000000000000000000000000000000000095 -:109BD0000000000000000000000000000000000085 -:109BE0000000000000000000000000000000000075 -:109BF0000000000000000000000000000000000065 -:109C00000000000000000000000000000000000054 -:109C10000000000000000000000000000000000044 -:109C20000000000000000000000000000000000034 -:109C30000000000000000000000000000000000024 -:109C40000000000000000000000000000000000014 -:109C50000000000000000000000000000000000004 -:109C600000000000000000000000000000000000F4 -:109C700000000000000000000000000000000000E4 -:109C800000000000000000000000000000000000D4 -:109C900000000000000000000000000000000000C4 -:109CA00000000000000000000000000000000000B4 -:109CB00000000000000000000000000000000000A4 -:109CC0000000000000000000000000000000000094 -:109CD0000000000000000000000000000000000084 -:109CE0000000000000000000000000000000000074 -:109CF0000000000000000000000000000000000064 -:109D00000000000000000000000000000000000053 -:109D10000000000000000000000000000000000043 -:109D20000000000000000000000000000000000033 -:109D30000000000000000000000000000000000023 -:109D40000000000000000000000000000000000013 -:109D50000000000000000000000000000000000003 -:109D600000000000000000000000000000000000F3 -:109D700000000000000000000000000000000000E3 -:109D800000000000000000000000000000000000D3 -:109D900000000000000000000000000000000000C3 -:109DA00000000000000000000000000000000000B3 -:109DB00000000000000000000000000000000000A3 -:109DC0000000000000000000000000000000000093 -:109DD0000000000000000000000000000000000083 -:109DE0000000000000000000000000000000000073 -:109DF0000000000000000000000000000000000063 -:109E00000000000000000000000000000000000052 -:109E10000000000000000000000000000000000042 -:109E20000000000000000000000000000000000032 -:109E30000000000000000000000000000000000022 -:109E40000000000000000000000000000000000012 -:109E50000000000000000000000000000000000002 -:109E600000000000000000000000000000000000F2 -:109E700000000000000000000000000000000000E2 -:109E800000000000000000000000000000000000D2 -:109E900000000000000000000000000000000000C2 -:109EA00000000000000000000000000000000000B2 -:109EB00000000000000000000000000000000000A2 -:109EC0000000000000000000000000000000000092 -:109ED0000000000000000000000000000000000082 -:109EE0000000000000000000000000000000000072 -:109EF0000000000000000000000000000000000062 -:109F00000000000000000000000000000000000051 -:109F10000000000000000000000000000000000041 -:109F20000000000000000000000000000000000031 -:109F30000000000000000000000000000000000021 -:109F40000000000000000000000000000000000011 -:109F50000000000000000000000000000000000001 -:109F600000000000000000000000000000000000F1 -:109F700000000000000000000000000000000000E1 -:109F800000000000000000000000000000000000D1 -:109F900000000000000000000000000000000000C1 -:109FA00000000000000000000000000000000000B1 -:109FB00000000000000000000000000000000000A1 -:109FC0000000000000000000000000000000000091 -:109FD0000000000000000000000000000000000081 -:109FE0000000000000000000000000000000000071 -:109FF0000000000000000000000000000000000061 -:10A000000000000000000000000000000000000050 -:10A010000000000000000000000000000000000040 -:10A020000000000000000000000000000000000030 -:10A030000000000000000000000000000000000020 -:10A040000000000000000000000000000000000010 -:10A050000000000000000000000000000000000000 -:10A0600000000000000000000000000000000000F0 -:10A0700000000000000000000000000000000000E0 -:10A0800000000000000000000000000000000000D0 -:10A0900000000000000000000000000000000000C0 -:10A0A00000000000000000000000000000000000B0 -:10A0B00000000000000000000000000000000000A0 -:10A0C0000000000000000000000000000000000090 -:10A0D0000000000000000000000000000000000080 -:10A0E0000000000000000000000000000000000070 -:10A0F0000000000000000000000000000000000060 -:10A10000000000000000000000000000000000004F -:10A11000000000000000000000000000000000003F -:10A12000000000000000000000000000000000002F -:10A13000000000000000000000000000000000001F -:10A14000000000000000000000000000000000000F -:10A1500000000000000000000000000000000000FF -:10A1600000000000000000000000000000000000EF -:10A1700000000000000000000000000000000000DF -:10A1800000000000000000000000000000000000CF -:10A1900000000000000000000000000000000000BF -:10A1A00000000000000000000000000000000000AF -:10A1B000000000000000000000000000000000009F -:10A1C000000000000000000000000000000000008F -:10A1D000000000000000000000000000000000007F -:10A1E000000000000000000000000000000000006F -:10A1F000000000000000000000000000000000005F -:10A20000000000000000000000000000000000004E -:10A21000000000000000000000000000000000003E -:10A22000000000000000000000000000000000002E -:10A23000000000000000000000000000000000001E -:10A24000000000000000000000000000000000000E -:10A2500000000000000000000000000000000000FE -:10A2600000000000000000000000000000000000EE -:10A2700000000000000000000000000000000000DE -:10A2800000000000000000000000000000000000CE -:10A2900000000000000000000000000000000000BE -:10A2A00000000000000000000000000000000000AE -:10A2B000000000000000000000000000000000009E -:10A2C000000000000000000000000000000000008E -:10A2D000000000000000000000000000000000007E -:10A2E000000000000000000000000000000000006E -:10A2F000000000000000000000000000000000005E -:10A30000000000000000000000000000000000004D -:10A31000000000000000000000000000000000003D -:10A32000000000000000000000000000000000002D -:10A33000000000000000000000000000000000001D -:10A34000000000000000000000000000000000000D -:10A3500000000000000000000000000000000000FD -:10A3600000000000000000000000000000000000ED -:10A3700000000000000000000000000000000000DD -:10A3800000000000000000000000000000000000CD -:10A3900000000000000000000000000000000000BD -:10A3A00000000000000000000000000000000000AD -:10A3B000000000000000000000000000000000009D -:10A3C000000000000000000000000000000000008D -:10A3D000000000000000000000000000000000007D -:10A3E000000000000000000000000000000000006D -:10A3F000000000000000000000000000000000005D -:10A40000000000000000000000000000000000004C -:10A41000000000000000000000000000000000003C -:10A42000000000000000000000000000000000002C -:10A43000000000000000000000000000000000001C -:10A44000000000000000000000000000000000000C -:10A4500000000000000000000000000000000000FC -:10A4600000000000000000000000000000000000EC -:10A4700000000000000000000000000000000000DC -:10A4800000000000000000000000000000000000CC -:10A4900000000000000000000000000000000000BC -:10A4A00000000000000000000000000000000000AC -:10A4B000000000000000000000000000000000009C -:10A4C000000000000000000000000000000000008C -:10A4D000000000000000000000000000000000007C -:10A4E000000000000000000000000000000000006C -:10A4F000000000000000000000000000000000005C -:10A50000000000000000000000000000000000004B -:10A51000000000000000000000000000000000003B -:10A52000000000000000000000000000000000002B -:10A53000000000000000000000000000000000001B -:10A54000000000000000000000000000000000000B -:10A5500000000000000000000000000000000000FB -:10A5600000000000000000000000000000000000EB -:10A5700000000000000000000000000000000000DB -:10A5800000000000000000000000000000000000CB -:10A5900000000000000000000000000000000000BB -:10A5A00000000000000000000000000000000000AB -:10A5B000000000000000000000000000000000009B -:10A5C000000000000000000000000000000000008B -:10A5D000000000000000000000000000000000007B -:10A5E000000000000000000000000000000000006B -:10A5F000000000000000000000000000000000005B -:10A60000000000000000000000000000000000004A -:10A61000000000000000000000000000000000003A -:10A62000000000000000000000000000000000002A -:10A63000000000000000000000000000000000001A -:10A64000000000000000000000000000000000000A -:10A6500000000000000000000000000000000000FA -:10A6600000000000000000000000000000000000EA -:10A6700000000000000000000000000000000000DA -:10A6800000000000000000000000000000000000CA -:10A6900000000000000000000000000000000000BA -:10A6A00000000000000000000000000000000000AA -:10A6B000000000000000000000000000000000009A -:10A6C000000000000000000000000000000000008A -:10A6D000000000000000000000000000000000007A -:10A6E000000000000000000000000000000000006A -:10A6F000000000000000000000000000000000005A -:10A700000000000000000000000000000000000049 -:10A710000000000000000000000000000000000039 -:10A720000000000000000000000000000000000029 -:10A730000000000000000000000000000000000019 -:10A740000000000000000000000000000000000009 -:10A7500000000000000000000000000000000000F9 -:10A7600000000000000000000000000000000000E9 -:10A7700000000000000000000000000000000000D9 -:10A7800000000000000000000000000000000000C9 -:10A7900000000000000000000000000000000000B9 -:10A7A00000000000000000000000000000000000A9 -:10A7B0000000000000000000000000000000000099 -:10A7C0000000000000000000000000000000000089 -:10A7D0000000000000000000000000000000000079 -:10A7E0000000000000000000000000000000000069 -:10A7F0000000000000000000000000000000000059 -:10A800000000000000000000000000000000000048 -:10A810000000000000000000000000000000000038 -:10A820000000000000000000000000000000000028 -:10A830000000000000000000000000000000000018 -:10A840000000000000000000000000000000000008 -:10A8500000000000000000000000000000000000F8 -:10A8600000000000000000000000000000000000E8 -:10A8700000000000000000000000000000000000D8 -:10A8800000000000000000000000000000000000C8 -:10A8900000000000000000000000000000000000B8 -:10A8A00000000000000000000000000000000000A8 -:10A8B0000000000000000000000000000000000098 -:10A8C0000000000000000000000000000000000088 -:10A8D0000000000000000000000000000000000078 -:10A8E0000000000000000000000000000000000068 -:10A8F0000000000000000000000000000000000058 -:10A900000000000000000000000000000000000047 -:10A910000000000000000000000000000000000037 -:10A920000000000000000000000000000000000027 -:10A930000000000000000000000000000000000017 -:10A940000000000000000000000000000000000007 -:10A9500000000000000000000000000000000000F7 -:10A9600000000000000000000000000000000000E7 -:10A9700000000000000000000000000000000000D7 -:10A9800000000000000000000000000000000000C7 -:10A9900000000000000000000000000000000000B7 -:10A9A00000000000000000000000000000000000A7 -:10A9B0000000000000000000000000000000000097 -:10A9C0000000000000000000000000000000000087 -:10A9D0000000000000000000000000000000000077 -:10A9E0000000000000000000000000000000000067 -:10A9F0000000000000000000000000000000000057 -:10AA00000000000000000000000000000000000046 -:10AA10000000000000000000000000000000000036 -:10AA20000000000000000000000000000000000026 -:10AA30000000000000000000000000000000000016 -:10AA40000000000000000000000000000000000006 -:10AA500000000000000000000000000000000000F6 -:10AA600000000000000000000000000000000000E6 -:10AA700000000000000000000000000000000000D6 -:10AA800000000000000000000000000000000000C6 -:10AA900000000000000000000000000000000000B6 -:10AAA00000000000000000000000000000000000A6 -:10AAB0000000000000000000000000000000000096 -:10AAC0000000000000000000000000000000000086 -:10AAD0000000000000000000000000000000000076 -:10AAE0000000000000000000000000000000000066 -:10AAF0000000000000000000000000000000000056 -:10AB00000000000000000000000000000000000045 -:10AB10000000000000000000000000000000000035 -:10AB20000000000000000000000000000000000025 -:10AB30000000000000000000000000000000000015 -:10AB40000000000000000000000000000000000005 -:10AB500000000000000000000000000000000000F5 -:10AB600000000000000000000000000000000000E5 -:10AB700000000000000000000000000000000000D5 -:10AB800000000000000000000000000000000000C5 -:10AB900000000000000000000000000000000000B5 -:10ABA00000000000000000000000000000000000A5 -:10ABB0000000000000000000000000000000000095 -:10ABC0000000000000000000000000000000000085 -:10ABD0000000000000000000000000000000000075 -:10ABE0000000000000000000000000000000000065 -:10ABF0000000000000000000000000000000000055 -:10AC00000000000000000000000000000000000044 -:10AC10000000000000000000000000000000000034 -:10AC20000000000000000000000000000000000024 -:10AC30000000000000000000000000000000000014 -:10AC40000000000000000000000000000000000004 -:10AC500000000000000000000000000000000000F4 -:10AC600000000000000000000000000000000000E4 -:10AC700000000000000000000000000000000000D4 -:10AC800000000000000000000000000000000000C4 -:10AC900000000000000000000000000000000000B4 -:10ACA00000000000000000000000000000000000A4 -:10ACB0000000000000000000000000000000000094 -:10ACC0000000000000000000000000000000000084 -:10ACD0000000000000000000000000000000000074 -:10ACE0000000000000000000000000000000000064 -:10ACF0000000000000000000000000000000000054 -:10AD00000000000000000000000000000000000043 -:10AD10000000000000000000000000000000000033 -:10AD20000000000000000000000000000000000023 -:10AD30000000000000000000000000000000000013 -:10AD40000000000000000000000000000000000003 -:10AD500000000000000000000000000000000000F3 -:10AD600000000000000000000000000000000000E3 -:10AD700000000000000000000000000000000000D3 -:10AD800000000000000000000000000000000000C3 -:10AD900000000000000000000000000000000000B3 -:10ADA00000000000000000000000000000000000A3 -:10ADB0000000000000000000000000000000000093 -:10ADC0000000000000000000000000000000000083 -:10ADD0000000000000000000000000000000000073 -:10ADE0000000000000000000000000000000000063 -:10ADF0000000000000000000000000000000000053 -:10AE00000000000000000000000000000000000042 -:10AE10000000000000000000000000000000000032 -:10AE20000000000000000000000000000000000022 -:10AE30000000000000000000000000000000000012 -:10AE40000000000000000000000000000000000002 -:10AE500000000000000000000000000000000000F2 -:10AE600000000000000000000000000000000000E2 -:10AE700000000000000000000000000000000000D2 -:10AE800000000000000000000000000000000000C2 -:10AE900000000000000000000000000000000000B2 -:10AEA00000000000000000000000000000000000A2 -:10AEB0000000000000000000000000000000000092 -:10AEC0000000000000000000000000000000000082 -:10AED0000000000000000000000000000000000072 -:10AEE0000000000000000000000000000000000062 -:10AEF0000000000000000000000000000000000052 -:10AF00000000000000000000000000000000000041 -:10AF10000000000000000000000000000000000031 -:10AF20000000000000000000000000000000000021 -:10AF30000000000000000000000000000000000011 -:10AF40000000000000000000000000000000000001 -:10AF500000000000000000000000000000000000F1 -:10AF600000000000000000000000000000000000E1 -:10AF700000000000000000000000000000000000D1 -:10AF800000000000000000000000000000000000C1 -:10AF900000000000000000000000000000000000B1 -:10AFA00000000000000000000000000000000000A1 -:10AFB0000000000000000000000000000000000091 -:10AFC0000000000000000000000000000000000081 -:10AFD0000000000000000000000000000000000071 -:10AFE0000000000000000000000000000000000061 -:10AFF0000000000000000000000000000000000051 -:10B000000000000000000000000000000000000040 -:10B010000000000000000000000000000000000030 -:10B020000000000000000000000000000000000020 -:10B030000000000000000000000000000000000010 -:10B040000000000000000000000000000000000000 -:10B0500000000000000000000000000000000000F0 -:10B0600000000000000000000000000000000000E0 -:10B0700000000000000000000000000000000000D0 -:10B0800000000000000000000000000000000000C0 -:10B0900000000000000000000000000000000000B0 -:10B0A00000000000000000000000000000000000A0 -:10B0B0000000000000000000000000000000000090 -:10B0C0000000000000000000000000000000000080 -:10B0D0000000000000000000000000000000000070 -:10B0E0000000000000000000000000000000000060 -:10B0F0000000000000000000000000000000000050 -:10B10000000000000000000000000000000000003F -:10B11000000000000000000000000000000000002F -:10B12000000000000000000000000000000000001F -:10B13000000000000000000000000000000000000F -:10B1400000000000000000000000000000000000FF -:10B1500000000000000000000000000000000000EF -:10B1600000000000000000000000000000000000DF -:10B1700000000000000000000000000000000000CF -:10B1800000000000000000000000000000000000BF -:10B1900000000000000000000000000000000000AF -:10B1A000000000000000000000000000000000009F -:10B1B000000000000000000000000000000000008F -:10B1C000000000000000000000000000000000007F -:10B1D000000000000000000000000000000000006F -:10B1E000000000000000000000000000000000005F -:10B1F000000000000000000000000000000000004F -:10B20000000000000000000000000000000000003E -:10B21000000000000000000000000000000000002E -:10B22000000000000000000000000000000000001E -:10B23000000000000000000000000000000000000E -:10B2400000000000000000000000000000000000FE -:10B2500000000000000000000000000000000000EE -:10B2600000000000000000000000000000000000DE -:10B2700000000000000000000000000000000000CE -:10B2800000000000000000000000000000000000BE -:10B2900000000000000000000000000000000000AE -:10B2A000000000000000000000000000000000009E -:10B2B000000000000000000000000000000000008E -:10B2C000000000000000000000000000000000007E -:10B2D000000000000000000000000000000000006E -:10B2E000000000000000000000000000000000005E -:10B2F000000000000000000000000000000000004E -:10B30000000000000000000000000000000000003D -:10B31000000000000000000000000000000000002D -:10B32000000000000000000000000000000000001D -:10B33000000000000000000000000000000000000D -:10B3400000000000000000000000000000000000FD -:10B3500000000000000000000000000000000000ED -:10B3600000000000000000000000000000000000DD -:10B3700000000000000000000000000000000000CD -:10B3800000000000000000000000000000000000BD -:10B3900000000000000000000000000000000000AD -:10B3A000000000000000000000000000000000009D -:10B3B000000000000000000000000000000000008D -:10B3C000000000000000000000000000000000007D -:10B3D000000000000000000000000000000000006D -:10B3E000000000000000000000000000000000005D -:10B3F000000000000000000000000000000000004D -:10B40000000000000000000000000000000000003C -:10B41000000000000000000000000000000000002C -:10B42000000000000000000000000000000000001C -:10B43000000000000000000000000000000000000C -:10B4400000000000000000000000000000000000FC -:10B4500000000000000000000000000000000000EC -:10B4600000000000000000000000000000000000DC -:10B4700000000000000000000000000000000000CC -:10B4800000000000000000000000000000000000BC -:10B4900000000000000000000000000000000000AC -:10B4A000000000000000000000000000000000009C -:10B4B000000000000000000000000000000000008C -:10B4C000000000000000000000000000000000007C -:10B4D000000000000000000000000000000000006C -:10B4E000000000000000000000000000000000005C -:10B4F000000000000000000000000000000000004C -:10B50000000000000000000000000000000000003B -:10B51000000000000000000000000000000000002B -:10B52000000000000000000000000000000000001B -:10B53000000000000000000000000000000000000B -:10B5400000000000000000000000000000000000FB -:10B5500000000000000000000000000000000000EB -:10B5600000000000000000000000000000000000DB -:10B5700000000000000000000000000000000000CB -:10B5800000000000000000000000000000000000BB -:10B5900000000000000000000000000000000000AB -:10B5A000000000000000000000000000000000009B -:10B5B000000000000000000000000000000000008B -:10B5C000000000000000000000000000000000007B -:10B5D000000000000000000000000000000000006B -:10B5E000000000000000000000000000000000005B -:10B5F000000000000000000000000000000000004B -:10B60000000000000000000000000000000000003A -:10B61000000000000000000000000000000000002A -:10B62000000000000000000000000000000000001A -:10B63000000000000000000000000000000000000A -:10B6400000000000000000000000000000000000FA -:10B6500000000000000000000000000000000000EA -:10B6600000000000000000000000000000000000DA -:10B6700000000000000000000000000000000000CA -:10B6800000000000000000000000000000000000BA -:10B6900000000000000000000000000000000000AA -:10B6A000000000000000000000000000000000009A -:10B6B000000000000000000000000000000000008A -:10B6C000000000000000000000000000000000007A -:10B6D000000000000000000000000000000000006A -:10B6E000000000000000000000000000000000005A -:10B6F000000000000000000000000000000000004A -:10B700000000000000000000000000000000000039 -:10B710000000000000000000000000000000000029 -:10B720000000000000000000000000000000000019 -:10B730000000000000000000000000000000000009 -:10B7400000000000000000000000000000000000F9 -:10B7500000000000000000000000000000000000E9 -:10B7600000000000000000000000000000000000D9 -:10B7700000000000000000000000000000000000C9 -:10B7800000000000000000000000000000000000B9 -:10B7900000000000000000000000000000000000A9 -:10B7A0000000000000000000000000000000000099 -:10B7B0000000000000000000000000000000000089 -:10B7C0000000000000000000000000000000000079 -:10B7D0000000000000000000000000000000000069 -:10B7E0000000000000000000000000000000000059 -:10B7F0000000000000000000000000000000000049 -:10B800000000000000000000000000000000000038 -:10B810000000000000000000000000000000000028 -:10B820000000000000000000000000000000000018 -:10B830000000000000000000000000000000000008 -:10B8400000000000000000000000000000000000F8 -:10B8500000000000000000000000000000000000E8 -:10B8600000000000000000000000000000000000D8 -:10B8700000000000000000000000000000000000C8 -:10B8800000000000000000000000000000000000B8 -:10B8900000000000000000000000000000000000A8 -:10B8A0000000000000000000000000000000000098 -:10B8B0000000000000000000000000000000000088 -:10B8C0000000000000000000000000000000000078 -:10B8D0000000000000000000000000000000000068 -:10B8E0000000000000000000000000000000000058 -:10B8F0000000000000000000000000000000000048 -:10B900000000000000000000000000000000000037 -:10B910000000000000000000000000000000000027 -:10B920000000000000000000000000000000000017 -:10B930000000000000000000000000000000000007 -:10B9400000000000000000000000000000000000F7 -:10B9500000000000000000000000000000000000E7 -:10B9600000000000000000000000000000000000D7 -:10B9700000000000000000000000000000000000C7 -:10B9800000000000000000000000000000000000B7 -:10B9900000000000000000000000000000000000A7 -:10B9A0000000000000000000000000000000000097 -:10B9B0000000000000000000000000000000000087 -:10B9C0000000000000000000000000000000000077 -:10B9D0000000000000000000000000000000000067 -:10B9E0000000000000000000000000000000000057 -:10B9F0000000000000000000000000000000000047 -:10BA00000000000000000000000000000000000036 -:10BA10000000000000000000000000000000000026 -:10BA20000000000000000000000000000000000016 -:10BA30000000000000000000000000000000000006 -:10BA400000000000000000000000000000000000F6 -:10BA500000000000000000000000000000000000E6 -:10BA600000000000000000000000000000000000D6 -:10BA700000000000000000000000000000000000C6 -:10BA800000000000000000000000000000000000B6 -:10BA900000000000000000000000000000000000A6 -:10BAA0000000000000000000000000000000000096 -:10BAB0000000000000000000000000000000000086 -:10BAC0000000000000000000000000000000000076 -:10BAD0000000000000000000000000000000000066 -:10BAE0000000000000000000000000000000000056 -:10BAF0000000000000000000000000000000000046 -:10BB00000000000000000000000000000000000035 -:10BB10000000000000000000000000000000000025 -:10BB20000000000000000000000000000000000015 -:10BB30000000000000000000000000000000000005 -:10BB400000000000000000000000000000000000F5 -:10BB500000000000000000000000000000000000E5 -:10BB600000000000000000000000000000000000D5 -:10BB700000000000000000000000000000000000C5 -:10BB800000000000000000000000000000000000B5 -:10BB900000000000000000000000000000000000A5 -:10BBA0000000000000000000000000000000000095 -:10BBB0000000000000000000000000000000000085 -:10BBC0000000000000000000000000000000000075 -:10BBD0000000000000000000000000000000000065 -:10BBE0000000000000000000000000000000000055 -:10BBF0000000000000000000000000000000000045 -:10BC00000000000000000000000000000000000034 -:10BC10000000000000000000000000000000000024 -:10BC20000000000000000000000000000000000014 -:10BC30000000000000000000000000000000000004 -:10BC400000000000000000000000000000000000F4 -:10BC500000000000000000000000000000000000E4 -:10BC600000000000000000000000000000000000D4 -:10BC700000000000000000000000000000000000C4 -:10BC800000000000000000000000000000000000B4 -:10BC900000000000000000000000000000000000A4 -:10BCA0000000000000000000000000000000000094 -:10BCB0000000000000000000000000000000000084 -:10BCC0000000000000000000000000000000000074 -:10BCD0000000000000000000000000000000000064 -:10BCE0000000000000000000000000000000000054 -:10BCF0000000000000000000000000000000000044 -:10BD00000000000000000000000000000000000033 -:10BD10000000000000000000000000000000000023 -:10BD20000000000000000000000000000000000013 -:10BD30000000000000000000000000000000000003 -:10BD400000000000000000000000000000000000F3 -:10BD500000000000000000000000000000000000E3 -:10BD600000000000000000000000000000000000D3 -:10BD700000000000000000000000000000000000C3 -:10BD800000000000000000000000000000000000B3 -:10BD900000000000000000000000000000000000A3 -:10BDA0000000000000000000000000000000000093 -:10BDB0000000000000000000000000000000000083 -:10BDC0000000000000000000000000000000000073 -:10BDD0000000000000000000000000000000000063 -:10BDE0000000000000000000000000000000000053 -:10BDF0000000000000000000000000000000000043 -:10BE00000000000000000000000000000000000032 -:10BE10000000000000000000000000000000000022 -:10BE20000000000000000000000000000000000012 -:10BE30000000000000000000000000000000000002 -:10BE400000000000000000000000000000000000F2 -:10BE500000000000000000000000000000000000E2 -:10BE600000000000000000000000000000000000D2 -:10BE700000000000000000000000000000000000C2 -:10BE800000000000000000000000000000000000B2 -:10BE900000000000000000000000000000000000A2 -:10BEA0000000000000000000000000000000000092 -:10BEB0000000000000000000000000000000000082 -:10BEC0000000000000000000000000000000000072 -:10BED0000000000000000000000000000000000062 -:10BEE0000000000000000000000000000000000052 -:10BEF0000000000000000000000000000000000042 -:10BF00000000000000000000000000000000000031 -:10BF10000000000000000000000000000000000021 -:10BF20000000000000000000000000000000000011 -:10BF30000000000000000000000000000000000001 -:10BF400000000000000000000000000000000000F1 -:10BF500000000000000000000000000000000000E1 -:10BF600000000000000000000000000000000000D1 -:10BF700000000000000000000000000000000000C1 -:10BF800000000000000000000000000000000000B1 -:10BF900000000000000000000000000000000000A1 -:10BFA0000000000000000000000000000000000091 -:10BFB0000000000000000000000000000000000081 -:10BFC0000000000000000000000000000000000071 -:10BFD0000000000000000000000000000000000061 -:10BFE0000000000000000000000000000000000051 -:10BFF0000000000000000000000000000000000041 -:10C000000000000000000000000000000000000030 -:10C010000000000000000000000000000000000020 -:10C020000000000000000000000000000000000010 -:10C030000000000000000000000000000000000000 -:10C0400000000000000000000000000000000000F0 -:10C0500000000000000000000000000000000000E0 -:10C0600000000000000000000000000000000000D0 -:10C0700000000000000000000000000000000000C0 -:10C0800000000000000000000000000000000000B0 -:10C0900000000000000000000000000000000000A0 -:10C0A0000000000000000000000000000000000090 -:10C0B0000000000000000000000000000000000080 -:10C0C0000000000000000000000000000000000070 -:10C0D0000000000000000000000000000000000060 -:10C0E0000000000000000000000000000000000050 -:10C0F0000000000000000000000000000000000040 -:10C10000000000000000000000000000000000002F -:10C11000000000000000000000000000000000001F -:10C12000000000000000000000000000000000000F -:10C1300000000000000000000000000000000000FF -:10C1400000000000000000000000000000000000EF -:10C1500000000000000000000000000000000000DF -:10C1600000000000000000000000000000000000CF -:10C1700000000000000000000000000000000000BF -:10C1800000000000000000000000000000000000AF -:10C19000000000000000000000000000000000009F -:10C1A000000000000000000000000000000000008F -:10C1B000000000000000000000000000000000007F -:10C1C000000000000000000000000000000000006F -:10C1D000000000000000000000000000000000005F -:10C1E000000000000000000000000000000000004F -:10C1F000000000000000000000000000000000003F -:10C20000000000000000000000000000000000002E -:10C21000000000000000000000000000000000001E -:10C22000000000000000000000000000000000000E -:10C2300000000000000000000000000000000000FE -:10C2400000000000000000000000000000000000EE -:10C2500000000000000000000000000000000000DE -:10C2600000000000000000000000000000000000CE -:10C2700000000000000000000000000000000000BE -:10C2800000000000000000000000000000000000AE -:10C29000000000000000000000000000000000009E -:10C2A000000000000000000000000000000000008E -:10C2B000000000000000000000000000000000007E -:10C2C000000000000000000000000000000000006E -:10C2D000000000000000000000000000000000005E -:10C2E000000000000000000000000000000000004E -:10C2F000000000000000000000000000000000003E -:10C30000000000000000000000000000000000002D -:10C31000000000000000000000000000000000001D -:10C32000000000000000000000000000000000000D -:10C3300000000000000000000000000000000000FD -:10C3400000000000000000000000000000000000ED -:10C3500000000000000000000000000000000000DD -:10C3600000000000000000000000000000000000CD -:10C3700000000000000000000000000000000000BD -:10C3800000000000000000000000000000000000AD -:10C39000000000000000000000000000000000009D -:10C3A000000000000000000000000000000000008D -:10C3B000000000000000000000000000000000007D -:10C3C000000000000000000000000000000000006D -:10C3D000000000000000000000000000000000005D -:10C3E000000000000000000000000000000000004D -:10C3F000000000000000000000000000000000003D -:10C40000000000000000000000000000000000002C -:10C41000000000000000000000000000000000001C -:10C42000000000000000000000000000000000000C -:10C4300000000000000000000000000000000000FC -:10C4400000000000000000000000000000000000EC -:10C4500000000000000000000000000000000000DC -:10C4600000000000000000000000000000000000CC -:10C4700000000000000000000000000000000000BC -:10C4800000000000000000000000000000000000AC -:10C49000000000000000000000000000000000009C -:10C4A000000000000000000000000000000000008C -:10C4B000000000000000000000000000000000007C -:10C4C000000000000000000000000000000000006C -:10C4D000000000000000000000000000000000005C -:10C4E000000000000000000000000000000000004C -:10C4F000000000000000000000000000000000003C -:10C50000000000000000000000000000000000002B -:10C51000000000000000000000000000000000001B -:10C52000000000000000000000000000000000000B -:10C5300000000000000000000000000000000000FB -:10C5400000000000000000000000000000000000EB -:10C5500000000000000000000000000000000000DB -:10C5600000000000000000000000000000000000CB -:10C5700000000000000000000000000000000000BB -:10C5800000000000000000000000000000000000AB -:10C59000000000000000000000000000000000009B -:10C5A000000000000000000000000000000000008B -:10C5B000000000000000000000000000000000007B -:10C5C000000000000000000000000000000000006B -:10C5D000000000000000000000000000000000005B -:10C5E000000000000000000000000000000000004B -:10C5F000000000000000000000000000000000003B -:10C60000000000000000000000000000000000002A -:10C61000000000000000000000000000000000001A -:10C62000000000000000000000000000000000000A -:10C6300000000000000000000000000000000000FA -:10C6400000000000000000000000000000000000EA -:10C6500000000000000000000000000000000000DA -:10C6600000000000000000000000000000000000CA -:10C6700000000000000000000000000000000000BA -:10C6800000000000000000000000000000000000AA -:10C69000000000000000000000000000000000009A -:10C6A000000000000000000000000000000000008A -:10C6B000000000000000000000000000000000007A -:10C6C000000000000000000000000000000000006A -:10C6D000000000000000000000000000000000005A -:10C6E000000000000000000000000000000000004A -:10C6F000000000000000000000000000000000003A -:10C700000000000000000000000000000000000029 -:10C710000000000000000000000000000000000019 -:10C720000000000000000000000000000000000009 -:10C7300000000000000000000000000000000000F9 -:10C7400000000000000000000000000000000000E9 -:10C7500000000000000000000000000000000000D9 -:10C7600000000000000000000000000000000000C9 -:10C7700000000000000000000000000000000000B9 -:10C7800000000000000000000000000000000000A9 -:10C790000000000000000000000000000000000099 -:10C7A0000000000000000000000000000000000089 -:10C7B0000000000000000000000000000000000079 -:10C7C0000000000000000000000000000000000069 -:10C7D0000000000000000000000000000000000059 -:10C7E0000000000000000000000000000000000049 -:10C7F0000000000000000000000000000000000039 -:10C800000000000000000000000000000000000028 -:10C810000000000000000000000000000000000018 -:10C820000000000000000000000000000000000008 -:10C8300000000000000000000000000000000000F8 -:10C8400000000000000000000000000000000000E8 -:10C8500000000000000000000000000000000000D8 -:10C8600000000000000000000000000000000000C8 -:10C8700000000000000000000000000000000000B8 -:10C8800000000000000000000000000000000000A8 -:10C890000000000000000000000000000000000098 -:10C8A0000000000000000000000000000000000088 -:10C8B0000000000000000000000000000000000078 -:10C8C0000000000000000000000000000000000068 -:10C8D0000000000000000000000000000000000058 -:10C8E0000000000000000000000000000000000048 -:10C8F0000000000000000000000000000000000038 -:10C900000000000000000000000000000000000027 -:10C910000000000000000000000000000000000017 -:10C920000000000000000000000000000000000007 -:10C9300000000000000000000000000000000000F7 -:10C9400000000000000000000000000000000000E7 -:10C9500000000000000000000000000000000000D7 -:10C9600000000000000000000000000000000000C7 -:10C9700000000000000000000000000000000000B7 -:10C9800000000000000000000000000000000000A7 -:10C990000000000000000000000000000000000097 -:10C9A0000000000000000000000000000000000087 -:10C9B0000000000000000000000000000000000077 -:10C9C0000000000000000000000000000000000067 -:10C9D0000000000000000000000000000000000057 -:10C9E0000000000000000000000000000000000047 -:10C9F0000000000000000000000000000000000037 -:10CA00000000000000000000000000000000000026 -:10CA10000000000000000000000000000000000016 -:10CA20000000000000000000000000000000000006 -:10CA300000000000000000000000000000000000F6 -:10CA400000000000000000000000000000000000E6 -:10CA500000000000000000000000000000000000D6 -:10CA600000000000000000000000000000000000C6 -:10CA700000000000000000000000000000000000B6 -:10CA800000000000000000000000000000000000A6 -:10CA90000000000000000000000000000000000096 -:10CAA0000000000000000000000000000000000086 -:10CAB0000000000000000000000000000000000076 -:10CAC0000000000000000000000000000000000066 -:10CAD0000000000000000000000000000000000056 -:10CAE0000000000000000000000000000000000046 -:10CAF0000000000000000000000000000000000036 -:10CB00000000000000000000000000000000000025 -:10CB10000000000000000000000000000000000015 -:10CB20000000000000000000000000000000000005 -:10CB300000000000000000000000000000000000F5 -:10CB400000000000000000000000000000000000E5 -:10CB500000000000000000000000000000000000D5 -:10CB600000000000000000000000000000000000C5 -:10CB700000000000000000000000000000000000B5 -:10CB800000000000000000000000000000000000A5 -:10CB90000000000000000000000000000000000095 -:10CBA0000000000000000000000000000000000085 -:10CBB0000000000000000000000000000000000075 -:10CBC0000000000000000000000000000000000065 -:10CBD0000000000000000000000000000000000055 -:10CBE0000000000000000000000000000000000045 -:10CBF0000000000000000000000000000000000035 -:10CC00000000000000000000000000000000000024 -:10CC10000000000000000000000000000000000014 -:10CC20000000000000000000000000000000000004 -:10CC300000000000000000000000000000000000F4 -:10CC400000000000000000000000000000000000E4 -:10CC500000000000000000000000000000000000D4 -:10CC600000000000000000000000000000000000C4 -:10CC700000000000000000000000000000000000B4 -:10CC800000000000000000000000000000000000A4 -:10CC90000000000000000000000000000000000094 -:10CCA0000000000000000000000000000000000084 -:10CCB0000000000000000000000000000000000074 -:10CCC0000000000000000000000000000000000064 -:10CCD0000000000000000000000000000000000054 -:10CCE0000000000000000000000000000000000044 -:10CCF0000000000000000000000000000000000034 -:10CD00000000000000000000000000000000000023 -:10CD10000000000000000000000000000000000013 -:10CD20000000000000000000000000000000000003 -:10CD300000000000000000000000000000000000F3 -:10CD400000000000000000000000000000000000E3 -:10CD500000000000000000000000000000000000D3 -:10CD600000000000000000000000000000000000C3 -:10CD700000000000000000000000000000000000B3 -:10CD800000000000000000000000000000000000A3 -:10CD90000000000000000000000000000000000093 -:10CDA0000000000000000000000000000000000083 -:10CDB0000000000000000000000000000000000073 -:10CDC0000000000000000000000000000000000063 -:10CDD0000000000000000000000000000000000053 -:10CDE0000000000000000000000000000000000043 -:10CDF0000000000000000000000000000000000033 -:10CE00000000000000000000000000000000000022 -:10CE10000000000000000000000000000000000012 -:10CE20000000000000000000000000000000000002 -:10CE300000000000000000000000000000000000F2 -:10CE400000000000000000000000000000000000E2 -:10CE500000000000000000000000000000000000D2 -:10CE600000000000000000000000000000000000C2 -:10CE700000000000000000000000000000000000B2 -:10CE800000000000000000000000000000000000A2 -:10CE90000000000000000000000000000000000092 -:10CEA0000000000000000000000000000000000082 -:10CEB0000000000000000000000000000000000072 -:10CEC0000000000000000000000000000000000062 -:10CED0000000000000000000000000000000000052 -:10CEE0000000000000000000000000000000000042 -:10CEF0000000000000000000000000000000000032 -:10CF00000000000000000000000000000000000021 -:10CF10000000000000000000000000000000000011 -:10CF20000000000000000000000000000000000001 -:10CF300000000000000000000000000000000000F1 -:10CF400000000000000000000000000000000000E1 -:10CF500000000000000000000000000000000000D1 -:10CF600000000000000000000000000000000000C1 -:10CF700000000000000000000000000000000000B1 -:10CF800000000000000000000000000000000000A1 -:10CF90000000000000000000000000000000000091 -:10CFA0000000000000000000000000000000000081 -:10CFB0000000000000000000000000000000000071 -:10CFC0000000000000000000000000000000000061 -:10CFD0000000000000000000000000000000000051 -:10CFE0000000000000000000000000000000000041 -:10CFF0000000000000000000000000000000000031 -:10D000000000000000000000000000000000000020 -:10D010000000000000000000000000000000000010 -:10D020000000000000000000000000000000000000 -:10D0300000000000000000000000000000000000F0 -:10D0400000000000000000000000000000000000E0 -:10D0500000000000000000000000000000000000D0 -:10D0600000000000000000000000000000000000C0 -:10D0700000000000000000000000000000000000B0 -:10D0800000000000000000000000000000000000A0 -:10D090000000000000000000000000000000000090 -:10D0A0000000000000000000000000000000000080 -:10D0B0000000000000000000000000000000000070 -:10D0C0000000000000000000000000000000000060 -:10D0D0000000000000000000000000000000000050 -:10D0E0000000000000000000000000000000000040 -:10D0F0000000000000000000000000000000000030 -:10D10000000000000000000000000000000000001F -:10D11000000000000000000000000000000000000F -:10D1200000000000000000000000000000000000FF -:10D1300000000000000000000000000000000000EF -:10D1400000000000000000000000000000000000DF -:10D1500000000000000000000000000000000000CF -:10D1600000000000000000000000000000000000BF -:10D1700000000000000000000000000000000000AF -:10D18000000000000000000000000000000000009F -:10D19000000000000000000000000000000000008F -:10D1A000000000000000000000000000000000007F -:10D1B000000000000000000000000000000000006F -:10D1C000000000000000000000000000000000005F -:10D1D000000000000000000000000000000000004F -:10D1E000000000000000000000000000000000003F -:10D1F000000000000000000000000000000000002F -:10D20000000000000000000000000000000000001E -:10D21000000000000000000000000000000000000E -:10D2200000000000000000000000000000000000FE -:10D2300000000000000000000000000000000000EE -:10D2400000000000000000000000000000000000DE -:10D2500000000000000000000000000000000000CE -:10D2600000000000000000000000000000000000BE -:10D2700000000000000000000000000000000000AE -:10D28000000000000000000000000000000000009E -:10D29000000000000000000000000000000000008E -:10D2A000000000000000000000000000000000007E -:10D2B000000000000000000000000000000000006E -:10D2C000000000000000000000000000000000005E -:10D2D000000000000000000000000000000000004E -:10D2E000000000000000000000000000000000003E -:10D2F000000000000000000000000000000000002E -:10D30000000000000000000000000000000000001D -:10D31000000000000000000000000000000000000D -:10D3200000000000000000000000000000000000FD -:10D3300000000000000000000000000000000000ED -:10D3400000000000000000000000000000000000DD -:10D3500000000000000000000000000000000000CD -:10D3600000000000000000000000000000000000BD -:10D3700000000000000000000000000000000000AD -:10D38000000000000000000000000000000000009D -:10D39000000000000000000000000000000000008D -:10D3A000000000000000000000000000000000007D -:10D3B000000000000000000000000000000000006D -:10D3C000000000000000000000000000000000005D -:10D3D000000000000000000000000000000000004D -:10D3E000000000000000000000000000000000003D -:10D3F000000000000000000000000000000000002D -:10D40000000000000000000000000000000000001C -:10D41000000000000000000000000000000000000C -:10D4200000000000000000000000000000000000FC -:10D4300000000000000000000000000000000000EC -:10D4400000000000000000000000000000000000DC -:10D4500000000000000000000000000000000000CC -:10D4600000000000000000000000000000000000BC -:10D4700000000000000000000000000000000000AC -:10D48000000000000000000000000000000000009C -:10D49000000000000000000000000000000000008C -:10D4A000000000000000000000000000000000007C -:10D4B000000000000000000000000000000000006C -:10D4C000000000000000000000000000000000005C -:10D4D000000000000000000000000000000000004C -:10D4E000000000000000000000000000000000003C -:10D4F000000000000000000000000000000000002C -:10D50000000000000000000000000000000000001B -:10D51000000000000000000000000000000000000B -:10D5200000000000000000000000000000000000FB -:10D5300000000000000000000000000000000000EB -:10D5400000000000000000000000000000000000DB -:10D5500000000000000000000000000000000000CB -:10D5600000000000000000000000000000000000BB -:10D5700000000000000000000000000000000000AB -:10D58000000000000000000000000000000000009B -:10D59000000000000000000000000000000000008B -:10D5A000000000000000000000000000000000007B -:10D5B000000000000000000000000000000000006B -:10D5C000000000000000000000000000000000005B -:10D5D000000000000000000000000000000000004B -:10D5E000000000000000000000000000000000003B -:10D5F000000000000000000000000000000000002B -:10D60000000000000000000000000000000000001A -:10D61000000000000000000000000000000000000A -:10D6200000000000000000000000000000000000FA -:10D6300000000000000000000000000000000000EA -:10D6400000000000000000000000000000000000DA -:10D6500000000000000000000000000000000000CA -:10D6600000000000000000000000000000000000BA -:10D6700000000000000000000000000000000000AA -:10D68000000000000000000000000000000000009A -:10D69000000000000000000000000000000000008A -:10D6A000000000000000000000000000000000007A -:10D6B000000000000000000000000000000000006A -:10D6C000000000000000000000000000000000005A -:10D6D000000000000000000000000000000000004A -:10D6E000000000000000000000000000000000003A -:10D6F000000000000000000000000000000000002A -:10D700000000000000000000000000000000000019 -:10D710000000000000000000000000000000000009 -:10D7200000000000000000000000000000000000F9 -:10D7300000000000000000000000000000000000E9 -:10D7400000000000000000000000000000000000D9 -:10D7500000000000000000000000000000000000C9 -:10D7600000000000000000000000000000000000B9 -:10D7700000000000000000000000000000000000A9 -:10D780000000000000000000000000000000000099 -:10D790000000000000000000000000000000000089 -:10D7A0000000000000000000000000000000000079 -:10D7B0000000000000000000000000000000000069 -:10D7C0000000000000000000000000000000000059 -:10D7D0000000000000000000000000000000000049 -:10D7E0000000000000000000000000000000000039 -:10D7F0000000000000000000000000000000000029 -:10D800000000000000000000000000000000000018 -:10D810000000000000000000000000000000000008 -:10D8200000000000000000000000000000000000F8 -:10D8300000000000000000000000000000000000E8 -:10D8400000000000000000000000000000000000D8 -:10D8500000000000000000000000000000000000C8 -:10D8600000000000000000000000000000000000B8 -:10D8700000000000000000000000000000000000A8 -:10D880000000000000000000000000000000000098 -:10D890000000000000000000000000000000000088 -:10D8A0000000000000000000000000000000000078 -:10D8B0000000000000000000000000000000000068 -:10D8C0000000000000000000000000000000000058 -:10D8D0000000000000000000000000000000000048 -:10D8E0000000000000000000000000000000000038 -:10D8F0000000000000000000000000000000000028 -:10D900000000000000000000000000000000000017 -:10D910000000000000000000000000000000000007 -:10D9200000000000000000000000000000000000F7 -:10D9300000000000000000000000000000000000E7 -:10D9400000000000000000000000000000000000D7 -:10D9500000000000000000000000000000000000C7 -:10D9600000000000000000000000000000000000B7 -:10D9700000000000000000000000000000000000A7 -:10D980000000000000000000000000000000000097 -:10D990000000000000000000000000000000000087 -:10D9A0000000000000000000000000000000000077 -:10D9B0000000000000000000000000000000000067 -:10D9C0000000000000000000000000000000000057 -:10D9D0000000000000000000000000000000000047 -:10D9E0000000000000000000000000000000000037 -:10D9F0000000000000000000000000000000000027 -:10DA00000000000000000000000000000000000016 -:10DA10000000000000000000000000000000000006 -:10DA200000000000000000000000000000000000F6 -:10DA300000000000000000000000000000000000E6 -:10DA400000000000000000000000000000000000D6 -:10DA500000000000000000000000000000000000C6 -:10DA600000000000000000000000000000000000B6 -:10DA700000000000000000000000000000000000A6 -:10DA80000000000000000000000000000000000096 -:10DA90000000000000000000000000000000000086 -:10DAA0000000000000000000000000000000000076 -:10DAB0000000000000000000000000000000000066 -:10DAC0000000000000000000000000000000000056 -:10DAD0000000000000000000000000000000000046 -:10DAE0000000000000000000000000000000000036 -:10DAF0000000000000000000000000000000000026 -:10DB00000000000000000000000000000000000015 -:10DB10000000000000000000000000000000000005 -:10DB200000000000000000000000000000000000F5 -:10DB300000000000000000000000000000000000E5 -:10DB400000000000000000000000000000000000D5 -:10DB500000000000000000000000000000000000C5 -:10DB600000000000000000000000000000000000B5 -:10DB700000000000000000000000000000000000A5 -:10DB80000000000000000000000000000000000095 -:10DB90000000000000000000000000000000000085 -:10DBA0000000000000000000000000000000000075 -:10DBB0000000000000000000000000000000000065 -:10DBC0000000000000000000000000000000000055 -:10DBD0000000000000000000000000000000000045 -:10DBE0000000000000000000000000000000000035 -:10DBF0000000000000000000000000000000000025 -:10DC00000000000000000000000000000000000014 -:10DC10000000000000000000000000000000000004 -:10DC200000000000000000000000000000000000F4 -:10DC300000000000000000000000000000000000E4 -:10DC400000000000000000000000000000000000D4 -:10DC500000000000000000000000000000000000C4 -:10DC600000000000000000000000000000000000B4 -:10DC700000000000000000000000000000000000A4 -:10DC80000000000000000000000000000000000094 -:10DC90000000000000000000000000000000000084 -:10DCA0000000000000000000000000000000000074 -:10DCB0000000000000000000000000000000000064 -:10DCC0000000000000000000000000000000000054 -:10DCD0000000000000000000000000000000000044 -:10DCE0000000000000000000000000000000000034 -:10DCF0000000000000000000000000000000000024 -:10DD00000000000000000000000000000000000013 -:10DD10000000000000000000000000000000000003 -:10DD200000000000000000000000000000000000F3 -:10DD300000000000000000000000000000000000E3 -:10DD400000000000000000000000000000000000D3 -:10DD500000000000000000000000000000000000C3 -:10DD600000000000000000000000000000000000B3 -:10DD700000000000000000000000000000000000A3 -:10DD80000000000000000000000000000000000093 -:10DD90000000000000000000000000000000000083 -:10DDA0000000000000000000000000000000000073 -:10DDB0000000000000000000000000000000000063 -:10DDC0000000000000000000000000000000000053 -:10DDD0000000000000000000000000000000000043 -:10DDE0000000000000000000000000000000000033 -:10DDF0000000000000000000000000000000000023 -:10DE00000000000000000000000000000000000012 -:10DE10000000000000000000000000000000000002 -:10DE200000000000000000000000000000000000F2 -:10DE300000000000000000000000000000000000E2 -:10DE400000000000000000000000000000000000D2 -:10DE500000000000000000000000000000000000C2 -:10DE600000000000000000000000000000000000B2 -:10DE700000000000000000000000000000000000A2 -:10DE80000000000000000000000000000000000092 -:10DE90000000000000000000000000000000000082 -:10DEA0000000000000000000000000000000000072 -:10DEB0000000000000000000000000000000000062 -:10DEC0000000000000000000000000000000000052 -:10DED0000000000000000000000000000000000042 -:10DEE0000000000000000000000000000000000032 -:10DEF0000000000000000000000000000000000022 -:10DF00000000000000000000000000000000000011 -:10DF10000000000000000000000000000000000001 -:10DF200000000000000000000000000000000000F1 -:10DF300000000000000000000000000000000000E1 -:10DF400000000000000000000000000000000000D1 -:10DF500000000000000000000000000000000000C1 -:10DF600000000000000000000000000000000000B1 -:10DF700000000000000000000000000000000000A1 -:10DF80000000000000000000000000000000000091 -:10DF90000000000000000000000000000000000081 -:10DFA0000000000000000000000000000000000071 -:10DFB0000000000000000000000000000000000061 -:10DFC0000000000000000000000000000000000051 -:10DFD0000000000000000000000000000000000041 -:10DFE0000000000000000000000000000000000031 -:10DFF0000000000000000000000000000000000021 -:10E000000000000000000000000000000000000010 -:10E010000000000000000000000000000000000000 -:10E0200000000000000000000000000000000000F0 -:10E0300000000000000000000000000000000000E0 -:10E0400000000000000000000000000000000000D0 -:10E0500000000000000000000000000000000000C0 -:10E0600000000000000000000000000000000000B0 -:10E0700000000000000000000000000000000000A0 -:10E080000000000000000000000000000000000090 -:10E090000000000000000000000000000000000080 -:10E0A0000000000000000000000000000000000070 -:10E0B0000000000000000000000000000000000060 -:10E0C0000000000000000000000000000000000050 -:10E0D0000000000000000000000000000000000040 -:10E0E0000000000000000000000000000000000030 -:10E0F0000000000000000000000000000000000020 -:10E10000000000000000000000000000000000000F -:10E1100000000000000000000000000000000000FF -:10E1200000000000000000000000000000000000EF -:10E1300000000000000000000000000000000000DF -:10E1400000000000000000000000000000000000CF -:10E1500000000000000000000000000000000000BF -:10E1600000000000000000000000000000000000AF -:10E17000000000000000000000000000000000009F -:10E18000000000000000000000000000000000008F -:10E19000000000000000000000000000000000007F -:10E1A000000000000000000000000000000000006F -:10E1B000000000000000000000000000000000005F -:10E1C000000000000000000000000000000000004F -:10E1D000000000000000000000000000000000003F -:10E1E000000000000000000000000000000000002F -:10E1F000000000000000000000000000000000001F -:10E20000000000000000000000000000000000000E -:10E2100000000000000000000000000000000000FE -:10E2200000000000000000000000000000000000EE -:10E2300000000000000000000000000000000000DE -:10E2400000000000000000000000000000000000CE -:10E2500000000000000000000000000000000000BE -:10E2600000000000000000000000000000000000AE -:10E27000000000000000000000000000000000009E -:10E28000000000000000000000000000000000008E -:10E29000000000000000000000000000000000007E -:10E2A000000000000000000000000000000000006E -:10E2B000000000000000000000000000000000005E -:10E2C000000000000000000000000000000000004E -:10E2D000000000000000000000000000000000003E -:10E2E000000000000000000000000000000000002E -:10E2F000000000000000000000000000000000001E -:10E30000000000000000000000000000000000000D -:10E3100000000000000000000000000000000000FD -:10E3200000000000000000000000000000000000ED -:10E3300000000000000000000000000000000000DD -:10E3400000000000000000000000000000000000CD -:10E3500000000000000000000000000000000000BD -:10E3600000000000000000000000000000000000AD -:10E37000000000000000000000000000000000009D -:10E38000000000000000000000000000000000008D -:10E39000000000000000000000000000000000007D -:10E3A000000000000000000000000000000000006D -:10E3B000000000000000000000000000000000005D -:10E3C000000000000000000000000000000000004D -:10E3D000000000000000000000000000000000003D -:10E3E000000000000000000000000000000000002D -:10E3F000000000000000000000000000000000001D -:10E40000000000000000000000000000000000000C -:10E4100000000000000000000000000000000000FC -:10E4200000000000000000000000000000000000EC -:10E4300000000000000000000000000000000000DC -:10E4400000000000000000000000000000000000CC -:10E4500000000000000000000000000000000000BC -:10E4600000000000000000000000000000000000AC -:10E47000000000000000000000000000000000009C -:10E48000000000000000000000000000000000008C -:10E49000000000000000000000000000000000007C -:10E4A000000000000000000000000000000000006C -:10E4B000000000000000000000000000000000005C -:10E4C000000000000000000000000000000000004C -:10E4D000000000000000000000000000000000003C -:10E4E000000000000000000000000000000000002C -:10E4F000000000000000000000000000000000001C -:10E50000000000000000000000000000000000000B -:10E5100000000000000000000000000000000000FB -:10E5200000000000000000000000000000000000EB -:10E5300000000000000000000000000000000000DB -:10E5400000000000000000000000000000000000CB -:10E5500000000000000000000000000000000000BB -:10E5600000000000000000000000000000000000AB -:10E57000000000000000000000000000000000009B -:10E58000000000000000000000000000000000008B -:10E59000000000000000000000000000000000007B -:10E5A000000000000000000000000000000000006B -:10E5B000000000000000000000000000000000005B -:10E5C000000000000000000000000000000000004B -:10E5D000000000000000000000000000000000003B -:10E5E000000000000000000000000000000000002B -:10E5F000000000000000000000000000000000001B -:10E60000000000000000000000000000000000000A -:10E6100000000000000000000000000000000000FA -:10E6200000000000000000000000000000000000EA -:10E6300000000000000000000000000000000000DA -:10E6400000000000000000000000000000000000CA -:10E6500000000000000000000000000000000000BA -:10E6600000000000000000000000000000000000AA -:10E67000000000000000000000000000000000009A -:10E68000000000000000000000000000000000008A -:10E69000000000000000000000000000000000007A -:10E6A000000000000000000000000000000000006A -:10E6B000000000000000000000000000000000005A -:10E6C000000000000000000000000000000000004A -:10E6D000000000000000000000000000000000003A -:10E6E000000000000000000000000000000000002A -:10E6F000000000000000000000000000000000001A -:10E700000000000000000000000000000000000009 -:10E7100000000000000000000000000000000000F9 -:10E7200000000000000000000000000000000000E9 -:10E7300000000000000000000000000000000000D9 -:10E7400000000000000000000000000000000000C9 -:10E7500000000000000000000000000000000000B9 -:10E7600000000000000000000000000000000000A9 -:10E770000000000000000000000000000000000099 -:10E780000000000000000000000000000000000089 -:10E790000000000000000000000000000000000079 -:10E7A0000000000000000000000000000000000069 -:10E7B0000000000000000000000000000000000059 -:10E7C0000000000000000000000000000000000049 -:10E7D0000000000000000000000000000000000039 -:10E7E0000000000000000000000000000000000029 -:10E7F0000000000000000000000000000000000019 -:10E800000000000000000000000000000000000008 -:10E8100000000000000000000000000000000000F8 -:10E8200000000000000000000000000000000000E8 -:10E8300000000000000000000000000000000000D8 -:10E8400000000000000000000000000000000000C8 -:10E8500000000000000000000000000000000000B8 -:10E8600000000000000000000000000000000000A8 -:10E870000000000000000000000000000000000098 -:10E880000000000000000000000000000000000088 -:10E890000000000000000000000000000000000078 -:10E8A0000000000000000000000000000000000068 -:10E8B0000000000000000000000000000000000058 -:10E8C0000000000000000000000000000000000048 -:10E8D0000000000000000000000000000000000038 -:10E8E0000000000000000000000000000000000028 -:10E8F0000000000000000000000000000000000018 -:10E900000000000000000000000000000000000007 -:10E9100000000000000000000000000000000000F7 -:10E9200000000000000000000000000000000000E7 -:10E9300000000000000000000000000000000000D7 -:10E9400000000000000000000000000000000000C7 -:10E9500000000000000000000000000000000000B7 -:10E9600000000000000000000000000000000000A7 -:10E970000000000000000000000000000000000097 -:10E980000000000000000000000000000000000087 -:10E990000000000000000000000000000000000077 -:10E9A0000000000000000000000000000000000067 -:10E9B0000000000000000000000000000000000057 -:10E9C0000000000000000000000000000000000047 -:10E9D0000000000000000000000000000000000037 -:10E9E0000000000000000000000000000000000027 -:10E9F0000000000000000000000000000000000017 -:10EA00000000000000000000000000000000000006 -:10EA100000000000000000000000000000000000F6 -:10EA200000000000000000000000000000000000E6 -:10EA300000000000000000000000000000000000D6 -:10EA400000000000000000000000000000000000C6 -:10EA500000000000000000000000000000000000B6 -:10EA600000000000000000000000000000000000A6 -:10EA70000000000000000000000000000000000096 -:10EA80000000000000000000000000000000000086 -:10EA90000000000000000000000000000000000076 -:10EAA0000000000000000000000000000000000066 -:10EAB0000000000000000000000000000000000056 -:10EAC0000000000000000000000000000000000046 -:10EAD0000000000000000000000000000000000036 -:10EAE0000000000000000000000000000000000026 -:10EAF0000000000000000000000000000000000016 -:10EB00000000000000000000000000000000000005 -:10EB100000000000000000000000000000000000F5 -:10EB200000000000000000000000000000000000E5 -:10EB300000000000000000000000000000000000D5 -:10EB400000000000000000000000000000000000C5 -:10EB500000000000000000000000000000000000B5 -:10EB600000000000000000000000000000000000A5 -:10EB70000000000000000000000000000000000095 -:10EB80000000000000000000000000000000000085 -:10EB90000000000000000000000000000000000075 -:10EBA0000000000000000000000000000000000065 -:10EBB0000000000000000000000000000000000055 -:10EBC0000000000000000000000000000000000045 -:10EBD0000000000000000000000000000000000035 -:10EBE0000000000000000000000000000000000025 -:10EBF0000000000000000000000000000000000015 -:10EC00000000000000000000000000000000000004 -:10EC100000000000000000000000000000000000F4 -:10EC200000000000000000000000000000000000E4 -:10EC300000000000000000000000000000000000D4 -:10EC400000000000000000000000000000000000C4 -:10EC500000000000000000000000000000000000B4 -:10EC600000000000000000000000000000000000A4 -:10EC70000000000000000000000000000000000094 -:10EC80000000000000000000000000000000000084 -:10EC90000000000000000000000000000000000074 -:10ECA0000000000000000000000000000000000064 -:10ECB0000000000000000000000000000000000054 -:10ECC0000000000000000000000000000000000044 -:10ECD0000000000000000000000000000000000034 -:10ECE0000000000000000000000000000000000024 -:10ECF0000000000000000000000000000000000014 -:10ED00000000000000000000000000000000000003 -:10ED100000000000000000000000000000000000F3 -:10ED200000000000000000000000000000000000E3 -:10ED300000000000000000000000000000000000D3 -:10ED400000000000000000000000000000000000C3 -:10ED500000000000000000000000000000000000B3 -:10ED600000000000000000000000000000000000A3 -:10ED70000000000000000000000000000000000093 -:10ED80000000000000000000000000000000000083 -:10ED90000000000000000000000000000000000073 -:10EDA0000000000000000000000000000000000063 -:10EDB0000000000000000000000000000000000053 -:10EDC0000000000000000000000000000000000043 -:10EDD0000000000000000000000000000000000033 -:10EDE0000000000000000000000000000000000023 -:10EDF0000000000000000000000000000000000013 -:10EE00000000000000000000000000000000000002 -:10EE100000000000000000000000000000000000F2 -:10EE200000000000000000000000000000000000E2 -:10EE300000000000000000000000000000000000D2 -:10EE400000000000000000000000000000000000C2 -:10EE500000000000000000000000000000000000B2 -:10EE600000000000000000000000000000000000A2 -:10EE70000000000000000000000000000000000092 -:10EE80000000000000000000000000000000000082 -:10EE90000000000000000000000000000000000072 -:10EEA0000000000000000000000000000000000062 -:10EEB0000000000000000000000000000000000052 -:10EEC0000000000000000000000000000000000042 -:10EED0000000000000000000000000000000000032 -:10EEE0000000000000000000000000000000000022 -:10EEF0000000000000000000000000000000000012 -:10EF00000000000000000000000000000000000001 -:10EF100000000000000000000000000000000000F1 -:10EF200000000000000000000000000000000000E1 -:10EF300000000000000000000000000000000000D1 -:10EF400000000000000000000000000000000000C1 -:10EF500000000000000000000000000000000000B1 -:10EF600000000000000000000000000000000000A1 -:10EF70000000000000000000000000000000000091 -:10EF80000000000000000000000000000000000081 -:10EF90000000000000000000000000000000000071 -:10EFA0000000000000000000000000000000000061 -:10EFB0000000000000000000000000000000000051 -:10EFC0000000000000000000000000000000000041 -:10EFD0000000000000000000000000000000000031 -:10EFE0000000000000000000000000000000000021 -:10EFF0000000000000000000000000000000000011 -:10F000000000000000000000000000000000000000 -:10F0100000000000000000000000000000000000F0 -:10F0200000000000000000000000000000000000E0 -:10F0300000000000000000000000000000000000D0 -:10F0400000000000000000000000000000000000C0 -:10F0500000000000000000000000000000000000B0 -:10F0600000000000000000000000000000000000A0 -:10F070000000000000000000000000000000000090 -:10F080000000000000000000000000000000000080 -:10F090000000000000000000000000000000000070 -:10F0A0000000000000000000000000000000000060 -:10F0B0000000000000000000000000000000000050 -:10F0C0000000000000000000000000000000000040 -:10F0D0000000000000000000000000000000000030 -:10F0E0000000000000000000000000000000000020 -:10F0F0000000000000000000000000000000000010 -:10F1000000000000000000000000000000000000FF -:10F1100000000000000000000000000000000000EF -:10F1200000000000000000000000000000000000DF -:10F1300000000000000000000000000000000000CF -:10F1400000000000000000000000000000000000BF -:10F1500000000000000000000000000000000000AF -:10F16000000000000000000000000000000000009F -:10F17000000000000000000000000000000000008F -:10F18000000000000000000000000000000000007F -:10F19000000000000000000000000000000000006F -:10F1A000000000000000000000000000000000005F -:10F1B000000000000000000000000000000000004F -:10F1C000000000000000000000000000000000003F -:10F1D000000000000000000000000000000000002F -:10F1E000000000000000000000000000000000001F -:10F1F000000000000000000000000000000000000F -:10F2000000000000000000000000000000000000FE -:10F2100000000000000000000000000000000000EE -:10F2200000000000000000000000000000000000DE -:10F2300000000000000000000000000000000000CE -:10F2400000000000000000000000000000000000BE -:10F2500000000000000000000000000000000000AE -:10F26000000000000000000000000000000000009E -:10F27000000000000000000000000000000000008E -:10F28000000000000000000000000000000000007E -:10F29000000000000000000000000000000000006E -:10F2A000000000000000000000000000000000005E -:10F2B000000000000000000000000000000000004E -:10F2C000000000000000000000000000000000003E -:10F2D000000000000000000000000000000000002E -:10F2E000000000000000000000000000000000001E -:10F2F000000000000000000000000000000000000E -:10F3000000000000000000000000000000000000FD -:10F3100000000000000000000000000000000000ED -:10F3200000000000000000000000000000000000DD -:10F3300000000000000000000000000000000000CD -:10F3400000000000000000000000000000000000BD -:10F3500000000000000000000000000000000000AD -:10F36000000000000000000000000000000000009D -:10F37000000000000000000000000000000000008D -:10F38000000000000000000000000000000000007D -:10F39000000000000000000000000000000000006D -:10F3A000000000000000000000000000000000005D -:10F3B000000000000000000000000000000000004D -:10F3C000000000000000000000000000000000003D -:10F3D000000000000000000000000000000000002D -:10F3E000000000000000000000000000000000001D -:10F3F000000000000000000000000000000000000D -:10F4000000000000000000000000000000000000FC -:10F4100000000000000000000000000000000000EC -:10F4200000000000000000000000000000000000DC -:10F4300000000000000000000000000000000000CC -:10F4400000000000000000000000000000000000BC -:10F4500000000000000000000000000000000000AC -:10F46000000000000000000000000000000000009C -:10F47000000000000000000000000000000000008C -:10F48000000000000000000000000000000000007C -:10F49000000000000000000000000000000000006C -:10F4A000000000000000000000000000000000005C -:10F4B000000000000000000000000000000000004C -:10F4C000000000000000000000000000000000003C -:10F4D000000000000000000000000000000000002C -:10F4E000000000000000000000000000000000001C -:10F4F000000000000000000000000000000000000C -:10F5000000000000000000000000000000000000FB -:10F5100000000000000000000000000000000000EB -:10F5200000000000000000000000000000000000DB -:10F5300000000000000000000000000000000000CB -:10F5400000000000000000000000000000000000BB -:10F5500000000000000000000000000000000000AB -:10F56000000000000000000000000000000000009B -:10F57000000000000000000000000000000000008B -:10F58000000000000000000000000000000000007B -:10F59000000000000000000000000000000000006B -:10F5A000000000000000000000000000000000005B -:10F5B000000000000000000000000000000000004B -:10F5C000000000000000000000000000000000003B -:10F5D000000000000000000000000000000000002B -:10F5E000000000000000000000000000000000001B -:10F5F000000000000000000000000000000000000B -:10F6000000000000000000000000000000000000FA -:10F6100000000000000000000000000000000000EA -:10F6200000000000000000000000000000000000DA -:10F6300000000000000000000000000000000000CA -:10F6400000000000000000000000000000000000BA -:10F6500000000000000000000000000000000000AA -:10F66000000000000000000000000000000000009A -:10F67000000000000000000000000000000000008A -:10F68000000000000000000000000000000000007A -:10F69000000000000000000000000000000000006A -:10F6A000000000000000000000000000000000005A -:10F6B000000000000000000000000000000000004A -:10F6C000000000000000000000000000000000003A -:10F6D000000000000000000000000000000000002A -:10F6E000000000000000000000000000000000001A -:10F6F000000000000000000000000000000000000A -:10F7000000000000000000000000000000000000F9 -:10F7100000000000000000000000000000000000E9 -:10F7200000000000000000000000000000000000D9 -:10F7300000000000000000000000000000000000C9 -:10F7400000000000000000000000000000000000B9 -:10F7500000000000000000000000000000000000A9 -:10F760000000000000000000000000000000000099 -:10F770000000000000000000000000000000000089 -:10F780000000000000000000000000000000000079 -:10F790000000000000000000000000000000000069 -:10F7A0000000000000000000000000000000000059 -:10F7B0000000000000000000000000000000000049 -:10F7C0000000000000000000000000000000000039 -:10F7D0000000000000000000000000000000000029 -:10F7E0000000000000000000000000000000000019 -:10F7F0000000000000000000000000000000000009 -:10F8000000000000000000000000000000000000F8 -:10F8100000000000000000000000000000000000E8 -:10F8200000000000000000000000000000000000D8 -:10F8300000000000000000000000000000000000C8 -:10F8400000000000000000000000000000000000B8 -:10F8500000000000000000000000000000000000A8 -:10F860000000000000000000000000000000000098 -:10F870000000000000000000000000000000000088 -:10F880000000000000000000000000000000000078 -:10F890000000000000000000000000000000000068 -:10F8A0000000000000000000000000000000000058 -:10F8B0000000000000000000000000000000000048 -:10F8C0000000000000000000000000000000000038 -:10F8D0000000000000000000000000000000000028 -:10F8E0000000000000000000000000000000000018 -:10F8F0000000000000000000000000000000000008 -:10F9000000000000000000000000000000000000F7 -:10F9100000000000000000000000000000000000E7 -:10F9200000000000000000000000000000000000D7 -:10F9300000000000000000000000000000000000C7 -:10F9400000000000000000000000000000000000B7 -:10F9500000000000000000000000000000000000A7 -:10F960000000000000000000000000000000000097 -:10F970000000000000000000000000000000000087 -:10F980000000000000000000000000000000000077 -:10F990000000000000000000000000000000000067 -:10F9A0000000000000000000000000000000000057 -:10F9B0000000000000000000000000000000000047 -:10F9C0000000000000000000000000000000000037 -:10F9D0000000000000000000000000000000000027 -:10F9E0000000000000000000000000000000000017 -:10F9F0000000000000000000000000000000000007 -:10FA000000000000000000000000000000000000F6 -:10FA100000000000000000000000000000000000E6 -:10FA200000000000000000000000000000000000D6 -:10FA300000000000000000000000000000000000C6 -:10FA400000000000000000000000000000000000B6 -:10FA500000000000000000000000000000000000A6 -:10FA60000000000000000000000000000000000096 -:10FA70000000000000000000000000000000000086 -:10FA80000000000000000000000000000000000076 -:10FA90000000000000000000000000000000000066 -:10FAA0000000000000000000000000000000000056 -:10FAB0000000000000000000000000000000000046 -:10FAC0000000000000000000000000000000000036 -:10FAD0000000000000000000000000000000000026 -:10FAE0000000000000000000000000000000000016 -:10FAF0000000000000000000000000000000000006 -:10FB000000000000000000000000000000000000F5 -:10FB100000000000000000000000000000000000E5 -:10FB200000000000000000000000000000000000D5 -:10FB300000000000000000000000000000000000C5 -:10FB400000000000000000000000000000000000B5 -:10FB500000000000000000000000000000000000A5 -:10FB60000000000000000000000000000000000095 -:10FB70000000000000000000000000000000000085 -:10FB80000000000000000000000000000000000075 -:10FB90000000000000000000000000000000000065 -:10FBA0000000000000000000000000000000000055 -:10FBB0000000000000000000000000000000000045 -:10FBC0000000000000000000000000000000000035 -:10FBD0000000000000000000000000000000000025 -:10FBE0000000000000000000000000000000000015 -:10FBF0000000000000000000000000000000000005 -:10FC000000000000000000000000000000000000F4 -:10FC100000000000000000000000000000000000E4 -:10FC200000000000000000000000000000000000D4 -:10FC300000000000000000000000000000000000C4 -:10FC400000000000000000000000000000000000B4 -:10FC500000000000000000000000000000000000A4 -:10FC60000000000000000000000000000000000094 -:10FC70000000000000000000000000000000000084 -:10FC80000000000000000000000000000000000074 -:10FC90000000000000000000000000000000000064 -:10FCA0000000000000000000000000000000000054 -:10FCB0000000000000000000000000000000000044 -:10FCC0000000000000000000000000000000000034 -:10FCD0000000000000000000000000000000000024 -:10FCE0000000000000000000000000000000000014 -:10FCF0000000000000000000000000000000000004 -:10FD000000000000000000000000000000000000F3 -:10FD100000000000000000000000000000000000E3 -:10FD200000000000000000000000000000000000D3 -:10FD300000000000000000000000000000000000C3 -:10FD400000000000000000000000000000000000B3 -:10FD500000000000000000000000000000000000A3 -:10FD60000000000000000000000000000000000093 -:10FD70000000000000000000000000000000000083 -:10FD80000000000000000000000000000000000073 -:10FD90000000000000000000000000000000000063 -:10FDA0000000000000000000000000000000000053 -:10FDB0000000000000000000000000000000000043 -:10FDC0000000000000000000000000000000000033 -:10FDD0000000000000000000000000000000000023 -:10FDE0000000000000000000000000000000000013 -:10FDF0000000000000000000000000000000000003 -:10FE000000000000000000000000000000000000F2 -:10FE100000000000000000000000000000000000E2 -:10FE200000000000000000000000000000000000D2 -:10FE300000000000000000000000000000000000C2 -:10FE400000000000000000000000000000000000B2 -:10FE500000000000000000000000000000000000A2 -:10FE60000000000000000000000000000000000092 -:10FE70000000000000000000000000000000000082 -:10FE80000000000000000000000000000000000072 -:10FE90000000000000000000000000000000000062 -:10FEA0000000000000000000000000000000000052 -:10FEB0000000000000000000000000000000000042 -:10FEC0000000000000000000000000000000000032 -:10FED0000000000000000000000000000000000022 -:10FEE0000000000000000000000000000000000012 -:10FEF0000000000000000000000000000000000002 -:10FF000000000000000000000000000000000000F1 -:10FF100000000000000000000000000000000000E1 -:10FF200000000000000000000000000000000000D1 -:10FF300000000000000000000000000000000000C1 -:10FF400000000000000000000000000000000000B1 -:10FF500000000000000000000000000000000000A1 -:10FF60000000000000000000000000000000000091 -:10FF70000000000000000000000000000000000081 -:10FF80000000000000000000000000000000000071 -:10FF90000000000000000000000000000000000061 -:10FFA0000000000000000000000000000000000051 -:10FFB0000000000000000000000000000000000041 -:10FFC0000000000000000000000000000000000031 -:10FFD0000000000000000000000000000000000021 -:10FFE0000000000000000000000000000000000011 -:10FFF0000000000000000000000000000000000001 -:02000004620296 -:1000000000000000000000000000000000000000F0 -:1000100000000000000000000000000000000000E0 -:1000200000000000000000000000000000000000D0 -:1000300000000000000000000000000000000000C0 -:1000400000000000000000000000000000000000B0 -:1000500000000000000000000000000000000000A0 -:100060000000000000000000000000000000000090 -:100070000000000000000000000000000000000080 -:100080000000000000000000000000000000000070 -:100090000000000000000000000000000000000060 -:1000A0000000000000000000000000000000000050 -:1000B0000000000000000000000000000000000040 -:1000C0000000000000000000000000000000000030 -:1000D0000000000000000000000000000000000020 -:1000E0000000000000000000000000000000000010 -:1000F0000000000000000000000000000000000000 -:1001000000000000000000000000000000000000EF -:1001100000000000000000000000000000000000DF -:1001200000000000000000000000000000000000CF -:1001300000000000000000000000000000000000BF -:1001400000000000000000000000000000000000AF -:10015000000000000000000000000000000000009F -:10016000000000000000000000000000000000008F -:10017000000000000000000000000000000000007F -:10018000000000000000000000000000000000006F -:10019000000000000000000000000000020000005D -:1001A000000000000000000000000000000000004F -:1001B000000000000000000000000000000000003F -:1001C000000000000000000000000000000000002F -:1001D000000000000000000000000000000000001F -:1001E000000000000000000000000000000000000F -:1001F00000000000000000000000000000000000FF -:1002000000000000000000000000000000000000EE -:1002100000000000000000000000000000000000DE -:1002200000000000000000000000000000000000CE -:1002300000000000000000000000000000000000BE -:1002400000000000000000000000000000000000AE -:10025000000000000000000000000000000000009E -:10026000000000000000000000000000000000008E -:10027000000000000000000000000000000000007E -:10028000000000000000000000000000000000006E -:10029000000000000000000000000000000000005E -:1002A000000000000000000000000000000000004E -:1002B000000000000000000000000000000000003E -:1002C000000000000000000000000000000000002E -:1002D000000000000000000000000000000000001E -:1002E000000000000000000000000000000000000E -:1002F00000000000000000000000000000000000FE -:1003000000000000000000000000000000000000ED -:1003100000000000000000000000000000000000DD -:1003200000000000000000000000000000000000CD -:1003300000000000000000000000000000000000BD -:1003400000000000000000000000000000000000AD -:10035000000000000000000000000000000000009D -:10036000000000000000000000000000000000008D -:10037000000000000000000000000000000000007D -:10038000000000000000000000000000000000006D -:10039000000000000000000000000000000000005D -:1003A000000000000000000000000000000000004D -:1003B000000000000000000000000000000000003D -:1003C000000000000000000000000000000000002D -:1003D000000000000000000000000000000000001D -:1003E000000000000000000000000000000000000D -:1003F00000000000000000000000000000000000FD -:1004000000000000000000000000000000000000EC -:1004100000000000000000000000000000000000DC -:1004200000000000000000000000000000000000CC -:1004300000000000000000000000000000000000BC -:1004400000000000000000000000000000000000AC -:10045000000000000000000000000000000000009C -:10046000000000000000000000000000000000008C -:10047000000000000000000000000000000000007C -:10048000000000000000000000000000000000006C -:10049000000000000000000000000000000000005C -:1004A000000000000000000000000000000000004C -:1004B000000000000000000000000000000000003C -:1004C000000000000000000000000000000000002C -:1004D000000000000000000000000000000000001C -:1004E000000000000000000000000000000000000C -:1004F00000000000000000000000000000000000FC -:1005000000000000000000000000000000000000EB -:1005100000000000000000000000000000000000DB -:1005200000000000000000000000000000000000CB -:1005300000000000000000000000000000000000BB -:1005400000000000000000000000000000000000AB -:10055000000000000000000000000000000000009B -:10056000000000000000000000000000000000008B -:10057000000000000000000000000000000000007B -:10058000000000000000000000000000000000006B -:10059000000000000000000000000000000000005B -:1005A000000000000000000000000000000000004B -:1005B000000000000000000000000000000000003B -:1005C000000000000000000000000000000000002B -:1005D000000000000000000000000000000000001B -:1005E000000000000000000000000000000000000B -:1005F00000000000000000000000000000000000FB -:1006000000000000000000000000000000000000EA -:1006100000000000000000000000000000000000DA -:1006200000000000000000000000000000000000CA -:1006300000000000000000000000000000000000BA -:1006400000000000000000000000000000000000AA -:10065000000000000000000000000000000000009A -:10066000000000000000000000000000000000008A -:10067000000000000000000000000000000000007A -:10068000000000000000000000000000000000006A -:10069000000000000000000000000000000000005A -:1006A000000000000000000000000000000000004A -:1006B000000000000000000000000000000000003A -:1006C000000000000000000000000000000000002A -:1006D000000000000000000000000000000000001A -:1006E000000000000000000000000000000000000A -:1006F00000000000000000000000000000000000FA -:1007000000000000000000000000000000000000E9 -:1007100000000000000000000000000000000000D9 -:1007200000000000000000000000000000000000C9 -:1007300000000000000000000000000000000000B9 -:1007400000000000000000000000000000000000A9 -:100750000000000000000000000000000000000099 -:100760000000000000000000000000000000000089 -:100770000000000000000000000000000000000079 -:100780000000000000000000000000000000000069 -:100790000000000000000000000000000000000059 -:1007A0000000000000000000000000000000000049 -:1007B0000000000000000000000000000000000039 -:1007C0000000000000000000000000000000000029 -:1007D0000000000000000000000000000000000019 -:1007E0000000000000000000000000000000000009 -:1007F00000000000000000000000000000000000F9 -:1008000000000000000000000000000000000000E8 -:1008100000000000000000000000000000000000D8 -:1008200000000000000000000000000000000000C8 -:1008300000000000000000000000000000000000B8 -:1008400000000000000000000000000000000000A8 -:100850000000000000000000000000000000000098 -:100860000000000000000000000000000000000088 -:100870000000000000000000000000000000000078 -:100880000000000000000000000000000000000068 -:100890000000000000000000000000000000000058 -:1008A0000000000000000000000000000000000048 -:1008B0000000000000000000000000000000000038 -:1008C0000000000000000000000000000000000028 -:1008D0000000000000000000000000000000000018 -:1008E0000000000000000000000000000000000008 -:1008F00000000000000000000000000000000000F8 -:1009000000000000000000000000000000000000E7 -:1009100000000000000000000000000000000000D7 -:1009200000000000000000000000000000000000C7 -:1009300000000000000000000000000000000000B7 -:1009400000000000000000000000000000000000A7 -:100950000000000000000000000000000000000097 -:100960000000000000000000000000000000000087 -:100970000000000000000000000000000000000077 -:100980000000000000000000000000000000000067 -:100990000000000000000000000000000000000057 -:1009A0000000000000000000000000000000000047 -:1009B0000000000000000000000000000000000037 -:1009C0000000000000000000000000000000000027 -:1009D0000000000000000000000000000000000017 -:1009E0000000000000000000000000000000000007 -:1009F00000000000000000000000000000000000F7 -:100A000000000000000000000000000000000000E6 -:100A100000000000000000000000000000000000D6 -:100A200000000000000000000000000000000000C6 -:100A300000000000000000000000000000000000B6 -:100A400000000000000000000000000000000000A6 -:100A50000000000000000000000000000000000096 -:100A60000000000000000000000000000000000086 -:100A70000000000000000000000000000000000076 -:100A80000000000000000000000000000000000066 -:100A90000000000000000000000000000000000056 -:100AA0000000000000000000000000000000000046 -:100AB0000000000000000000000000000000000036 -:100AC0000000000000000000000000000000000026 -:100AD0000000000000000000000000000000000016 -:100AE0000000000000000000000000000000000006 -:100AF00000000000000000000000000000000000F6 -:100B000000000000000000000000000000000000E5 -:100B100000000000000000000000000000000000D5 -:100B200000000000000000000000000000000000C5 -:100B300000000000000000000000000000000000B5 -:100B400000000000000000000000000000000000A5 -:100B50000000000000000000000000000000000095 -:100B60000000000000000000000000000000000085 -:100B70000000000000000000000000000000000075 -:100B80000000000000000000000000000000000065 -:100B90000000000000000000000000000000000055 -:100BA0000000000000000000000000000000000045 -:100BB0000000000000000000000000000000000035 -:100BC0000000000000000000000000000000000025 -:100BD0000000000000000000000000000000000015 -:100BE0000000000000000000000000000000000005 -:100BF00000000000000000000000000000000000F5 -:100C000000000000000000000000000000000000E4 -:100C100000000000000000000000000000000000D4 -:100C200000000000000000000000000000000000C4 -:100C300000000000000000000000000000000000B4 -:100C400000000000000000000000000000000000A4 -:100C50000000000000000000000000000000000094 -:100C60000000000000000000000000000000000084 -:100C70000000000000000000000000000000000074 -:100C80000000000000000000000000000000000064 -:100C90000000000000000000000000000000000054 -:100CA0000000000000000000000000000000000044 -:100CB0000000000000000000000000000000000034 -:100CC0000000000000000000000000000000000024 -:100CD0000000000000000000000000000000000014 -:100CE0000000000000000000000000000000000004 -:100CF00000000000000000000000000000000000F4 -:100D000000000000000000000000000000000000E3 -:100D100000000000000000000000000000000000D3 -:100D200000000000000000000000000000000000C3 -:100D300000000000000000000000000000000000B3 -:100D400000000000000000000000000000000000A3 -:100D50000000000000000000000000000000000093 -:100D60000000000000000000000000000000000083 -:100D70000000000000000000000000000000000073 -:100D80000000000000000000000000000000000063 -:100D90000000000000000000000000000000000053 -:100DA0000000000000000000000000000000000043 -:100DB0000000000000000000000000000000000033 -:100DC0000000000000000000000000000000000023 -:100DD0000000000000000000000000000000000013 -:100DE0000000000000000000000000000000000003 -:100DF00000000000000000000000000000000000F3 -:100E000000000000000000000000000000000000E2 -:100E100000000000000000000000000000000000D2 -:100E200000000000000000000000000000000000C2 -:100E300000000000000000000000000000000000B2 -:100E400000000000000000000000000000000000A2 -:100E50000000000000000000000000000000000092 -:100E60000000000000000000000000000000000082 -:100E70000000000000000000000000000000000072 -:100E80000000000000000000000000000000000062 -:100E90000000000000000000000000000000000052 -:100EA0000000000000000000000000000000000042 -:100EB0000000000000000000000000000000000032 -:100EC0000000000000000000000000000000000022 -:100ED0000000000000000000000000000000000012 -:100EE0000000000000000000000000000000000002 -:100EF00000000000000000000000000000000000F2 -:100F000000000000000000000000000000000000E1 -:100F100000000000000000000000000000000000D1 -:100F200000000000000000000000000000000000C1 -:100F300000000000000000000000000000000000B1 -:100F400000000000000000000000000000000000A1 -:100F50000000000000000000000000000000000091 -:100F60000000000000000000000000000000000081 -:100F70000000000000000000000000000000000071 -:100F80000000000000000000000000000000000061 -:100F90000000000000000000000000000000000051 -:100FA0000000000000000000000000000000000041 -:100FB0000000000000000000000000000000000031 -:100FC0000000000000000000000000000000000021 -:100FD0000000000000000000000000000000000011 -:100FE0000000000000000000000000000000000001 -:100FF00000000000000000000000000000000000F1 -:1010000000000000000000000000000000000000E0 -:1010100000000000000000000000000000000000D0 -:1010200000000000000000000000000000000000C0 -:1010300000000000000000000000000000000000B0 -:1010400000000000000000000000000000000000A0 -:101050000000000000000000000000000000000090 -:101060000000000000000000000000000000000080 -:101070000000000000000000000000000000000070 -:101080000000000000000000000000000000000060 -:101090000000000000000000000000000000000050 -:1010A0000000000000000000000000000000000040 -:1010B0000000000000000000000000000000000030 -:1010C0000000000000000000000000000000000020 -:1010D0000000000000000000000000000000000010 -:1010E0000000000000000000000000000000000000 -:1010F00000000000000000000000000000000000F0 -:1011000000000000000000000000000000000000DF -:1011100000000000000000000000000000000000CF -:1011200000000000000000000000000000000000BF -:1011300000000000000000000000000000000000AF -:10114000000000000000000000000000000000009F -:10115000000000000000000000000000000000008F -:10116000000000000000000000000000000000007F -:10117000000000000000000000000000000000006F -:10118000000000000000000000000000000000005F -:10119000000000000000000000000000000000004F -:1011A000000000000000000000000000000000003F -:1011B000000000000000000000000000000000002F -:1011C000000000000000000000000000000000001F -:1011D000000000000000000000000000000000000F -:1011E00000000000000000000000000000000000FF -:1011F00000000000000000000000000000000000EF -:1012000000000000000000000000000000000000DE -:1012100000000000000000000000000000000000CE -:1012200000000000000000000000000000000000BE -:1012300000000000000000000000000000000000AE -:10124000000000000000000000000000000000009E -:10125000000000000000000000000000000000008E -:10126000000000000000000000000000000000007E -:10127000000000000000000000000000000000006E -:10128000000000000000000000000000000000005E -:10129000000000000000000000000000000000004E -:1012A000000000000000000000000000000000003E -:1012B000000000000000000000000000000000002E -:1012C000000000000000000000000000000000001E -:1012D000000000000000000000000000000000000E -:1012E00000000000000000000000000000000000FE -:1012F00000000000000000000000000000000000EE -:1013000000000000000000000000000000000000DD -:1013100000000000000000000000000000000000CD -:1013200000000000000000000000000000000000BD -:1013300000000000000000000000000000000000AD -:10134000000000000000000000000000000000009D -:10135000000000000000000000000000000000008D -:10136000000000000000000000000000000000007D -:10137000000000000000000000000000000000006D -:10138000000000000000000000000000000000005D -:10139000000000000000000000000000000000004D -:1013A000000000000000000000000000000000003D -:1013B000000000000000000000000000000000002D -:1013C000000000000000000000000000000000001D -:1013D000000000000000000000000000000000000D -:1013E00000000000000000000000000000000000FD -:1013F00000000000000000000000000000000000ED -:1014000000000000000000000000000000000000DC -:1014100000000000000000000000000000000000CC -:1014200000000000000000000000000000000000BC -:1014300000000000000000000000000000000000AC -:10144000000000000000000000000000000000009C -:10145000000000000000000000000000000000008C -:10146000000000000000000000000000000000007C -:10147000000000000000000000000000000000006C -:10148000000000000000000000000000000000005C -:10149000000000000000000000000000000000004C -:1014A000000000000000000000000000000000003C -:1014B000000000000000000000000000000000002C -:1014C000000000000000000000000000000000001C -:1014D000000000000000000000000000000000000C -:1014E00000000000000000000000000000000000FC -:1014F00000000000000000000000000000000000EC -:1015000000000000000000000000000000000000DB -:1015100000000000000000000000000000000000CB -:1015200000000000000000000000000000000000BB -:1015300000000000000000000000000000000000AB -:10154000000000000000000000000000000000009B -:10155000000000000000000000000000000000008B -:10156000000000000000000000000000000000007B -:10157000000000000000000000000000000000006B -:10158000000000000000000000000000000000005B -:10159000000000000000000000000000000000004B -:1015A000000000000000000000000000000000003B -:1015B000000000000000000000000000000000002B -:1015C000000000000000000000000000000000001B -:1015D000000000000000000000000000000000000B -:1015E00000000000000000000000000000000000FB -:1015F00000000000000000000000000000000000EB -:1016000000000000000000000000000000000000DA -:1016100000000000000000000000000000000000CA -:1016200000000000000000000000000000000000BA -:1016300000000000000000000000000000000000AA -:10164000000000000000000000000000000000009A -:10165000000000000000000000000000000000008A -:10166000000000000000000000000000000000007A -:10167000000000000000000000000000000000006A -:10168000000000000000000000000000000000005A -:10169000000000000000000000000000000000004A -:1016A000000000000000000000000000000000003A -:1016B000000000000000000000000000000000002A -:1016C000000000000000000000000000000000001A -:1016D000000000000000000000000000000000000A -:1016E00000000000000000000000000000000000FA -:1016F00000000000000000000000000000000000EA -:1017000000000000000000000000000000000000D9 -:1017100000000000000000000000000000000000C9 -:1017200000000000000000000000000000000000B9 -:1017300000000000000000000000000000000000A9 -:101740000000000000000000000000000000000099 -:101750000000000000000000000000000000000089 -:101760000000000000000000000000000000000079 -:101770000000000000000000000000000000000069 -:101780000000000000000000000000000000000059 -:101790000000000000000000000000000000000049 -:1017A0000000000000000000000000000000000039 -:1017B0000000000000000000000000000000000029 -:1017C0000000000000000000000000000000000019 -:1017D0000000000000000000000000000000000009 -:1017E00000000000000000000000000000000000F9 -:1017F00000000000000000000000000000000000E9 -:1018000000000000000000000000000000000000D8 -:1018100000000000000000000000000000000000C8 -:1018200000000000000000000000000000000000B8 -:1018300000000000000000000000000000000000A8 -:101840000000000000000000000000000000000098 -:101850000000000000000000000000000000000088 -:101860000000000000000000000000000000000078 -:101870000000000000000000000000000000000068 -:101880000000000000000000000000000000000058 -:101890000000000000000000000000000000000048 -:1018A0000000000000000000000000000000000038 -:1018B0000000000000000000000000000000000028 -:1018C0000000000000000000000000000000000018 -:1018D0000000000000000000000000000000000008 -:1018E00000000000000000000000000000000000F8 -:1018F00000000000000000000000000000000000E8 -:1019000000000000000000000000000000000000D7 -:1019100000000000000000000000000000000000C7 -:1019200000000000000000000000000000000000B7 -:1019300000000000000000000000000000000000A7 -:101940000000000000000000000000000000000097 -:101950000000000000000000000000000000000087 -:101960000000000000000000000000000000000077 -:101970000000000000000000000000000000000067 -:101980000000000000000000000000000000000057 -:101990000000000000000000000000000000000047 -:1019A0000000000000000000000000000000000037 -:1019B0000000000000000000000000000000000027 -:1019C0000000000000000000000000000000000017 -:1019D0000000000000000000000000000000000007 -:1019E00000000000000000000000000000000000F7 -:1019F00000000000000000000000000000000000E7 -:101A000000000000000000000000000000000000D6 -:101A100000000000000000000000000000000000C6 -:101A200000000000000000000000000000000000B6 -:101A300000000000000000000000000000000000A6 -:101A40000000000000000000000000000000000096 -:101A50000000000000000000000000000000000086 -:101A60000000000000000000000000000000000076 -:101A70000000000000000000000000000000000066 -:101A80000000000000000000000000000000000056 -:101A90000000000000000000000000000000000046 -:101AA0000000000000000000000000000000000036 -:101AB0000000000000000000000000000000000026 -:101AC0000000000000000000000000000000000016 -:101AD0000000000000000000000000000000000006 -:101AE00000000000000000000000000000000000F6 -:101AF00000000000000000000000000000000000E6 -:101B000000000000000000000000000000000000D5 -:101B100000000000000000000000000000000000C5 -:101B200000000000000000000000000000000000B5 -:101B300000000000000000000000000000000000A5 -:101B40000000000000000000000000000000000095 -:101B50000000000000000000000000000000000085 -:101B60000000000000000000000000000000000075 -:101B70000000000000000000000000000000000065 -:101B80000000000000000000000000000000000055 -:101B90000000000000000000000000000000000045 -:101BA0000000000000000000000000000000000035 -:101BB0000000000000000000000000000000000025 -:101BC0000000000000000000000000000000000015 -:101BD0000000000000000000000000000000000005 -:101BE00000000000000000000000000000000000F5 -:101BF00000000000000000000000000000000000E5 -:101C000000000000000000000000000000000000D4 -:101C100000000000000000000000000000000000C4 -:101C200000000000000000000000000000000000B4 -:101C300000000000000000000000000000000000A4 -:101C40000000000000000000000000000000000094 -:101C50000000000000000000000000000000000084 -:101C60000000000000000000000000000000000074 -:101C70000000000000000000000000000000000064 -:101C80000000000000000000000000000000000054 -:101C90000000000000000000000000000000000044 -:101CA0000000000000000000000000000000000034 -:101CB0000000000000000000000000000000000024 -:101CC0000000000000000000000000000000000014 -:101CD0000000000000000000000000000000000004 -:101CE00000000000000000000000000000000000F4 -:101CF00000000000000000000000000000000000E4 -:101D000000000000000000000000000000000000D3 -:101D100000000000000000000000000000000000C3 -:101D200000000000000000000000000000000000B3 -:101D300000000000000000000000000000000000A3 -:101D40000000000000000000000000000000000093 -:101D50000000000000000000000000000000000083 -:101D60000000000000000000000000000000000073 -:101D70000000000000000000000000000000000063 -:101D80000000000000000000000000000000000053 -:101D90000000000000000000000000000000000043 -:101DA0000000000000000000000000000000000033 -:101DB0000000000000000000000000000000000023 -:101DC0000000000000000000000000000000000013 -:101DD0000000000000000000000000000000000003 -:101DE00000000000000000000000000000000000F3 -:101DF00000000000000000000000000000000000E3 -:101E000000000000000000000000000000000000D2 -:101E100000000000000000000000000000000000C2 -:101E200000000000000000000000000000000000B2 -:101E300000000000000000000000000000000000A2 -:101E40000000000000000000000000000000000092 -:101E50000000000000000000000000000000000082 -:101E60000000000000000000000000000000000072 -:101E70000000000000000000000000000000000062 -:101E80000000000000000000000000000000000052 -:101E90000000000000000000000000000000000042 -:101EA0000000000000000000000000000000000032 -:101EB0000000000000000000000000000000000022 -:101EC0000000000000000000000000000000000012 -:101ED0000000000000000000000000000000000002 -:101EE00000000000000000000000000000000000F2 -:101EF00000000000000000000000000000000000E2 -:101F000000000000000000000000000000000000D1 -:101F100000000000000000000000000000000000C1 -:101F200000000000000000000000000000000000B1 -:101F300000000000000000000000000000000000A1 -:101F40000000000000000000000000000000000091 -:101F50000000000000000000000000000000000081 -:101F60000000000000000000000000000000000071 -:101F70000000000000000000000000000000000061 -:101F80000000000000000000000000000000000051 -:101F90000000000000000000000000000000000041 -:101FA0000000000000000000000000000000000031 -:101FB0000000000000000000000000000000000021 -:101FC0000000000000000000000000000000000011 -:101FD0000000000000000000000000000000000001 -:101FE00000000000000000000000000000000000F1 -:101FF00000000000000000000000000000000000E1 -:1020000000000000000000000000000000000000D0 -:1020100000000000000000000000000000000000C0 -:1020200000000000000000000000000000000000B0 -:1020300000000000000000000000000000000000A0 -:102040000000000000000000000000000000000090 -:102050000000000000000000000000000000000080 -:102060000000000000000000000000000000000070 -:102070000000000000000000000000000000000060 -:102080000000000000000000000000000000000050 -:102090000000000000000000000000000000000040 -:1020A0000000000000000000000000000000000030 -:1020B0000000000000000000000000000000000020 -:1020C0000000000000000000000000000000000010 -:1020D0000000000000000000000000000000000000 -:1020E00000000000000000000000000000000000F0 -:1020F00000000000000000000000000000000000E0 -:1021000000000000000000000000000000000000CF -:1021100000000000000000000000000000000000BF -:1021200000000000000000000000000000000000AF -:10213000000000000000000000000000000000009F -:10214000000000000000000000000000000000008F -:10215000000000000000000000000000000000007F -:10216000000000000000000000000000000000006F -:10217000000000000000000000000000000000005F -:10218000000000000000000000000000000000004F -:10219000000000000000000000000000000000003F -:1021A000000000000000000000000000000000002F -:1021B000000000000000000000000000000000001F -:1021C000000000000000000000000000000000000F -:1021D00000000000000000000000000000000000FF -:1021E00000000000000000000000000000000000EF -:1021F00000000000000000000000000000000000DF -:1022000000000000000000000000000000000000CE -:1022100000000000000000000000000000000000BE -:1022200000000000000000000000000000000000AE -:10223000000000000000000000000000000000009E -:10224000000000000000000000000000000000008E -:10225000000000000000000000000000000000007E -:10226000000000000000000000000000000000006E -:10227000000000000000000000000000000000005E -:10228000000000000000000000000000000000004E -:10229000000000000000000000000000000000003E -:1022A000000000000000000000000000000000002E -:1022B000000000000000000000000000000000001E -:1022C000000000000000000000000000000000000E -:1022D00000000000000000000000000000000000FE -:1022E00000000000000000000000000000000000EE -:1022F00000000000000000000000000000000000DE -:1023000000000000000000000000000000000000CD -:1023100000000000000000000000000000000000BD -:1023200000000000000000000000000000000000AD -:10233000000000000000000000000000000000009D -:10234000000000000000000000000000000000008D -:10235000000000000000000000000000000000007D -:10236000000000000000000000000000000000006D -:10237000000000000000000000000000000000005D -:10238000000000000000000000000000000000004D -:10239000000000000000000000000000000000003D -:1023A000000000000000000000000000000000002D -:1023B000000000000000000000000000000000001D -:1023C000000000000000000000000000000000000D -:1023D00000000000000000000000000000000000FD -:1023E00000000000000000000000000000000000ED -:1023F00000000000000000000000000000000000DD -:1024000000000000000000000000000000000000CC -:1024100000000000000000000000000000000000BC -:1024200000000000000000000000000000000000AC -:10243000000000000000000000000000000000009C -:10244000000000000000000000000000000000008C -:10245000000000000000000000000000000000007C -:10246000000000000000000000000000000000006C -:10247000000000000000000000000000000000005C -:10248000000000000000000000000000000000004C -:10249000000000000000000000000000000000003C -:1024A000000000000000000000000000000000002C -:1024B000000000000000000000000000000000001C -:1024C000000000000000000000000000000000000C -:1024D00000000000000000000000000000000000FC -:1024E00000000000000000000000000000000000EC -:1024F00000000000000000000000000000000000DC -:1025000000000000000000000000000000000000CB -:1025100000000000000000000000000000000000BB -:1025200000000000000000000000000000000000AB -:10253000000000000000000000000000000000009B -:10254000000000000000000000000000000000008B -:10255000000000000000000000000000000000007B -:10256000000000000000000000000000000000006B -:10257000000000000000000000000000000000005B -:10258000000000000000000000000000000000004B -:10259000000000000000000000000000000000003B -:1025A000000000000000000000000000000000002B -:1025B000000000000000000000000000000000001B -:1025C000000000000000000000000000000000000B -:1025D00000000000000000000000000000000000FB -:1025E00000000000000000000000000000000000EB -:1025F00000000000000000000000000000000000DB -:1026000000000000000000000000000000000000CA -:1026100000000000000000000000000000000000BA -:1026200000000000000000000000000000000000AA -:10263000000000000000000000000000000000009A -:10264000000000000000000000000000000000008A -:10265000000000000000000000000000000000007A -:10266000000000000000000000000000000000006A -:10267000000000000000000000000000000000005A -:10268000000000000000000000000000000000004A -:10269000000000000000000000000000000000003A -:1026A000000000000000000000000000000000002A -:1026B000000000000000000000000000000000001A -:1026C000000000000000000000000000000000000A -:1026D00000000000000000000000000000000000FA -:1026E00000000000000000000000000000000000EA -:1026F00000000000000000000000000000000000DA -:1027000000000000000000000000000000000000C9 -:1027100000000000000000000000000000000000B9 -:1027200000000000000000000000000000000000A9 -:102730000000000000000000000000000000000099 -:102740000000000000000000000000000000000089 -:102750000000000000000000000000000000000079 -:102760000000000000000000000000000000000069 -:102770000000000000000000000000000000000059 -:102780000000000000000000000000000000000049 -:102790000000000000000000000000000000000039 -:1027A0000000000000000000000000000000000029 -:1027B0000000000000000000000000000000000019 -:1027C0000000000000000000000000000000000009 -:1027D00000000000000000000000000000000000F9 -:1027E00000000000000000000000000000000000E9 -:1027F00000000000000000000000000000000000D9 -:1028000000000000000000000000000000000000C8 -:1028100000000000000000000000000000000000B8 -:1028200000000000000000000000000000000000A8 -:102830000000000000000000000000000000000098 -:102840000000000000000000000000000000000088 -:102850000000000000000000000000000000000078 -:102860000000000000000000000000000000000068 -:102870000000000000000000000000000000000058 -:102880000000000000000000000000000000000048 -:102890000000000000000000000000000000000038 -:1028A0000000000000000000000000000000000028 -:1028B0000000000000000000000000000000000018 -:1028C0000000000000000000000000000000000008 -:1028D00000000000000000000000000000000000F8 -:1028E00000000000000000000000000000000000E8 -:1028F00000000000000000000000000000000000D8 -:1029000000000000000000000000000000000000C7 -:1029100000000000000000000000000000000000B7 -:1029200000000000000000000000000000000000A7 -:102930000000000000000000000000000000000097 -:102940000000000000000000000000000000000087 -:102950000000000000000000000000000000000077 -:102960000000000000000000000000000000000067 -:102970000000000000000000000000000000000057 -:102980000000000000000000000000000000000047 -:102990000000000000000000000000000000000037 -:1029A0000000000000000000000000000000000027 -:1029B0000000000000000000000000000000000017 -:1029C0000000000000000000000000000000000007 -:1029D00000000000000000000000000000000000F7 -:1029E00000000000000000000000000000000000E7 -:1029F00000000000000000000000000000000000D7 -:102A000000000000000000000000000000000000C6 -:102A100000000000000000000000000000000000B6 -:102A200000000000000000000000000000000000A6 -:102A30000000000000000000000000000000000096 -:102A40000000000000000000000000000000000086 -:102A50000000000000000000000000000000000076 -:102A60000000000000000000000000000000000066 -:102A70000000000000000000000000000000000056 -:102A80000000000000000000000000000000000046 -:102A90000000000000000000000000000000000036 -:102AA0000000000000000000000000000000000026 -:102AB0000000000000000000000000000000000016 -:102AC0000000000000000000000000000000000006 -:102AD00000000000000000000000000000000000F6 -:102AE00000000000000000000000000000000000E6 -:102AF00000000000000000000000000000000000D6 -:102B000000000000000000000000000000000000C5 -:102B100000000000000000000000000000000000B5 -:102B200000000000000000000000000000000000A5 -:102B30000000000000000000000000000000000095 -:102B40000000000000000000000000000000000085 -:102B50000000000000000000000000000000000075 -:102B60000000000000000000000000000000000065 -:102B70000000000000000000000000000000000055 -:102B80000000000000000000000000000000000045 -:102B90000000000000000000000000000000000035 -:102BA0000000000000000000000000000000000025 -:102BB0000000000000000000000000000000000015 -:102BC0000000000000000000000000000000000005 -:102BD00000000000000000000000000000000000F5 -:102BE00000000000000000000000000000000000E5 -:102BF00000000000000000000000000000000000D5 -:102C000000000000000000000000000000000000C4 -:102C100000000000000000000000000000000000B4 -:102C200000000000000000000000000000000000A4 -:102C30000000000000000000000000000000000094 -:102C40000000000000000000000000000000000084 -:102C50000000000000000000000000000000000074 -:102C60000000000000000000000000000000000064 -:102C70000000000000000000000000000000000054 -:102C80000000000000000000000000000000000044 -:102C90000000000000000000000000000000000034 -:102CA0000000000000000000000000000000000024 -:102CB0000000000000000000000000000000000014 -:102CC0000000000000000000000000000000000004 -:102CD00000000000000000000000000000000000F4 -:102CE00000000000000000000000000000000000E4 -:102CF00000000000000000000000000000000000D4 -:102D000000000000000000000000000000000000C3 -:102D100000000000000000000000000000000000B3 -:102D200000000000000000000000000000000000A3 -:102D30000000000000000000000000000000000093 -:102D40000000000000000000000000000000000083 -:102D50000000000000000000000000000000000073 -:102D60000000000000000000000000000000000063 -:102D70000000000000000000000000000000000053 -:102D80000000000000000000000000000000000043 -:102D90000000000000000000000000000000000033 -:102DA0000000000000000000000000000000000023 -:102DB0000000000000000000000000000000000013 -:102DC0000000000000000000000000000000000003 -:102DD00000000000000000000000000000000000F3 -:102DE00000000000000000000000000000000000E3 -:102DF00000000000000000000000000000000000D3 -:102E000000000000000000000000000000000000C2 -:102E100000000000000000000000000000000000B2 -:102E200000000000000000000000000000000000A2 -:102E30000000000000000000000000000000000092 -:102E40000000000000000000000000000000000082 -:102E50000000000000000000000000000000000072 -:102E60000000000000000000000000000000000062 -:102E70000000000000000000000000000000000052 -:102E80000000000000000000000000000000000042 -:102E90000000000000000000000000000000000032 -:102EA0000000000000000000000000000000000022 -:102EB0000000000000000000000000000000000012 -:102EC0000000000000000000000000000000000002 -:102ED00000000000000000000000000000000000F2 -:102EE00000000000000000000000000000000000E2 -:102EF00000000000000000000000000000000000D2 -:102F000000000000000000000000000000000000C1 -:102F100000000000000000000000000000000000B1 -:102F200000000000000000000000000000000000A1 -:102F30000000000000000000000000000000000091 -:102F40000000000000000000000000000000000081 -:102F50000000000000000000000000000000000071 -:102F60000000000000000000000000000000000061 -:102F70000000000000000000000000000000000051 -:102F80000000000000000000000000000000000041 -:102F90000000000000000000000000000000000031 -:102FA0000000000000000000000000000000000021 -:102FB0000000000000000000000000000000000011 -:102FC0000000000000000000000000000000000001 -:102FD00000000000000000000000000000000000F1 -:102FE00000000000000000000000000000000000E1 -:102FF00000000000000000000000000000000000D1 -:1030000000000000000000000000000000000000C0 -:1030100000000000000000000000000000000000B0 -:1030200000000000000000000000000000000000A0 -:103030000000000000000000000000000000000090 -:103040000000000000000000000000000000000080 -:103050000000000000000000000000000000000070 -:103060000000000000000000000000000000000060 -:103070000000000000000000000000000000000050 -:103080000000000000000000000000000000000040 -:103090000000000000000000000000000000000030 -:1030A0000000000000000000000000000000000020 -:1030B0000000000000000000000000000000000010 -:1030C0000000000000000000000000000000000000 -:1030D00000000000000000000000000000000000F0 -:1030E00000000000000000000000000000000000E0 -:1030F00000000000000000000000000000000000D0 -:1031000000000000000000000000000000000000BF -:1031100000000000000000000000000000000000AF -:10312000000000000000000000000000000000009F -:10313000000000000000000000000000000000008F -:10314000000000000000000000000000000000007F -:10315000000000000000000000000000000000006F -:10316000000000000000000000000000000000005F -:10317000000000000000000000000000000000004F -:10318000000000000000000000000000000000003F -:10319000000000000000000000000000000000002F -:1031A000000000000000000000000000000000001F -:1031B000000000000000000000000000000000000F -:1031C00000000000000000000000000000000000FF -:1031D00000000000000000000000000000000000EF -:1031E00000000000000000000000000000000000DF -:1031F00000000000000000000000000000000000CF -:1032000000000000000000000000000000000000BE -:1032100000000000000000000000000000000000AE -:10322000000000000000000000000000000000009E -:10323000000000000000000000000000000000008E -:10324000000000000000000000000000000000007E -:10325000000000000000000000000000000000006E -:10326000000000000000000000000000000000005E -:10327000000000000000000000000000000000004E -:10328000000000000000000000000000000000003E -:10329000000000000000000000000000000000002E -:1032A000000000000000000000000000000000001E -:1032B000000000000000000000000000000000000E -:1032C00000000000000000000000000000000000FE -:1032D00000000000000000000000000000000000EE -:1032E00000000000000000000000000000000000DE -:1032F00000000000000000000000000000000000CE -:1033000000000000000000000000000000000000BD -:1033100000000000000000000000000000000000AD -:10332000000000000000000000000000000000009D -:10333000000000000000000000000000000000008D -:10334000000000000000000000000000000000007D -:10335000000000000000000000000000000000006D -:10336000000000000000000000000000000000005D -:10337000000000000000000000000000000000004D -:10338000000000000000000000000000000000003D -:10339000000000000000000000000000000000002D -:1033A000000000000000000000000000000000001D -:1033B000000000000000000000000000000000000D -:1033C00000000000000000000000000000000000FD -:1033D00000000000000000000000000000000000ED -:1033E00000000000000000000000000000000000DD -:1033F00000000000000000000000000000000000CD -:1034000000000000000000000000000000000000BC -:1034100000000000000000000000000000000000AC -:10342000000000000000000000000000000000009C -:10343000000000000000000000000000000000008C -:10344000000000000000000000000000000000007C -:10345000000000000000000000000000000000006C -:10346000000000000000000000000000000000005C -:10347000000000000000000000000000000000004C -:10348000000000000000000000000000000000003C -:10349000000000000000000000000000000000002C -:1034A000000000000000000000000000000000001C -:1034B000000000000000000000000000000000000C -:1034C00000000000000000000000000000000000FC -:1034D00000000000000000000000000000000000EC -:1034E00000000000000000000000000000000000DC -:1034F00000000000000000000000000000000000CC -:1035000000000000000000000000000000000000BB -:1035100000000000000000000000000000000000AB -:10352000000000000000000000000000000000009B -:10353000000000000000000000000000000000008B -:10354000000000000000000000000000000000007B -:10355000000000000000000000000000000000006B -:10356000000000000000000000000000000000005B -:10357000000000000000000000000000000000004B -:10358000000000000000000000000000000000003B -:10359000000000000000000000000000000000002B -:1035A000000000000000000000000000000000001B -:1035B000000000000000000000000000000000000B -:1035C00000000000000000000000000000000000FB -:1035D00000000000000000000000000000000000EB -:1035E00000000000000000000000000000000000DB -:1035F00000000000000000000000000000000000CB -:1036000000000000000000000000000000000000BA -:1036100000000000000000000000000000000000AA -:10362000000000000000000000000000000000009A -:10363000000000000000000000000000000000008A -:10364000000000000000000000000000000000007A -:10365000000000000000000000000000000000006A -:10366000000000000000000000000000000000005A -:10367000000000000000000000000000000000004A -:10368000000000000000000000000000000000003A -:10369000000000000000000000000000000000002A -:1036A000000000000000000000000000000000001A -:1036B000000000000000000000000000000000000A -:1036C00000000000000000000000000000000000FA -:1036D00000000000000000000000000000000000EA -:1036E00000000000000000000000000000000000DA -:1036F00000000000000000000000000000000000CA -:1037000000000000000000000000000000000000B9 -:1037100000000000000000000000000000000000A9 -:103720000000000000000000000000000000000099 -:103730000000000000000000000000000000000089 -:103740000000000000000000000000000000000079 -:103750000000000000000000000000000000000069 -:103760000000000000000000000000000000000059 -:103770000000000000000000000000000000000049 -:103780000000000000000000000000000000000039 -:103790000000000000000000000000000000000029 -:1037A0000000000000000000000000000000000019 -:1037B0000000000000000000000000000000000009 -:1037C00000000000000000000000000000000000F9 -:1037D00000000000000000000000000000000000E9 -:1037E00000000000000000000000000000000000D9 -:1037F00000000000000000000000000000000000C9 -:1038000000000000000000000000000000000000B8 -:1038100000000000000000000000000000000000A8 -:103820000000000000000000000000000000000098 -:103830000000000000000000000000000000000088 -:103840000000000000000000000000000000000078 -:103850000000000000000000000000000000000068 -:103860000000000000000000000000000000000058 -:103870000000000000000000000000000000000048 -:103880000000000000000000000000000000000038 -:103890000000000000000000000000000000000028 -:1038A0000000000000000000000000000000000018 -:1038B0000000000000000000000000000000000008 -:1038C00000000000000000000000000000000000F8 -:1038D00000000000000000000000000000000000E8 -:1038E00000000000000000000000000000000000D8 -:1038F00000000000000000000000000000000000C8 -:1039000000000000000000000000000000000000B7 -:1039100000000000000000000000000000000000A7 -:103920000000000000000000000000000000000097 -:103930000000000000000000000000000000000087 -:103940000000000000000000000000000000000077 -:103950000000000000000000000000000000000067 -:103960000000000000000000000000000000000057 -:103970000000000000000000000000000000000047 -:103980000000000000000000000000000000000037 -:103990000000000000000000000000000000000027 -:1039A0000000000000000000000000000000000017 -:1039B0000000000000000000000000000000000007 -:1039C00000000000000000000000000000000000F7 -:1039D00000000000000000000000000000000000E7 -:1039E00000000000000000000000000000000000D7 -:1039F00000000000000000000000000000000000C7 -:103A000000000000000000000000000000000000B6 -:103A100000000000000000000000000000000000A6 -:103A20000000000000000000000000000000000096 -:103A30000000000000000000000000000000000086 -:103A40000000000000000000000000000000000076 -:103A50000000000000000000000000000000000066 -:103A60000000000000000000000000000000000056 -:103A70000000000000000000000000000000000046 -:103A80000000000000000000000000000000000036 -:103A90000000000000000000000000000000000026 -:103AA0000000000000000000000000000000000016 -:103AB0000000000000000000000000000000000006 -:103AC00000000000000000000000000000000000F6 -:103AD00000000000000000000000000000000000E6 -:103AE00000000000000000000000000000000000D6 -:103AF00000000000000000000000000000000000C6 -:103B000000000000000000000000000000000000B5 -:103B100000000000000000000000000000000000A5 -:103B20000000000000000000000000000000000095 -:103B30000000000000000000000000000000000085 -:103B40000000000000000000000000000000000075 -:103B50000000000000000000000000000000000065 -:103B60000000000000000000000000000000000055 -:103B70000000000000000000000000000000000045 -:103B80000000000000000000000000000000000035 -:103B90000000000000000000000000000000000025 -:103BA0000000000000000000000000000000000015 -:103BB0000000000000000000000000000000000005 -:103BC00000000000000000000000000000000000F5 -:103BD00000000000000000000000000000000000E5 -:103BE00000000000000000000000000000000000D5 -:103BF00000000000000000000000000000000000C5 -:103C000000000000000000000000000000000000B4 -:103C100000000000000000000000000000000000A4 -:103C20000000000000000000000000000000000094 -:103C30000000000000000000000000000000000084 -:103C40000000000000000000000000000000000074 -:103C50000000000000000000000000000000000064 -:103C60000000000000000000000000000000000054 -:103C70000000000000000000000000000000000044 -:103C80000000000000000000000000000000000034 -:103C90000000000000000000000000000000000024 -:103CA0000000000000000000000000000000000014 -:103CB0000000000000000000000000000000000004 -:103CC00000000000000000000000000000000000F4 -:103CD00000000000000000000000000000000000E4 -:103CE00000000000000000000000000000000000D4 -:103CF00000000000000000000000000000000000C4 -:103D000000000000000000000000000000000000B3 -:103D100000000000000000000000000000000000A3 -:103D20000000000000000000000000000000000093 -:103D30000000000000000000000000000000000083 -:103D40000000000000000000000000000000000073 -:103D50000000000000000000000000000000000063 -:103D60000000000000000000000000000000000053 -:103D70000000000000000000000000000000000043 -:103D80000000000000000000000000000000000033 -:103D90000000000000000000000000000000000023 -:103DA0000000000000000000000000000000000013 -:103DB0000000000000000000000000000000000003 -:103DC00000000000000000000000000000000000F3 -:103DD00000000000000000000000000000000000E3 -:103DE00000000000000000000000000000000000D3 -:103DF00000000000000000000000000000000000C3 -:103E000000000000000000000000000000000000B2 -:103E100000000000000000000000000000000000A2 -:103E20000000000000000000000000000000000092 -:103E30000000000000000000000000000000000082 -:103E40000000000000000000000000000000000072 -:103E50000000000000000000000000000000000062 -:103E60000000000000000000000000000000000052 -:103E70000000000000000000000000000000000042 -:103E80000000000000000000000000000000000032 -:103E90000000000000000000000000000000000022 -:103EA0000000000000000000000000000000000012 -:103EB0000000000000000000000000000000000002 -:103EC00000000000000000000000000000000000F2 -:103ED00000000000000000000000000000000000E2 -:103EE00000000000000000000000000000000000D2 -:103EF00000000000000000000000000000000000C2 -:103F000000000000000000000000000000000000B1 -:103F100000000000000000000000000000000000A1 -:103F20000000000000000000000000000000000091 -:103F30000000000000000000000000000000000081 -:103F40000000000000000000000000000000000071 -:103F50000000000000000000000000000000000061 -:103F60000000000000000000000000000000000051 -:103F70000000000000000000000000000000000041 -:103F80000000000000000000000000000000000031 -:103F90000000000000000000000000000000000021 -:103FA0000000000000000000000000000000000011 -:103FB0000000000000000000000000000000000001 -:103FC00000000000000000000000000000000000F1 -:103FD00000000000000000000000000000000000E1 -:103FE00000000000000000000000000000000000D1 -:103FF00000000000000000000000000000000000C1 -:1040000000000000000000000000000000000000B0 -:1040100000000000000000000000000000000000A0 -:104020000000000000000000000000000000000090 -:104030000000000000000000000000000000000080 -:104040000000000000000000000000000000000070 -:104050000000000000000000000000000000000060 -:104060000000000000000000000000000000000050 -:104070000000000000000000000000000000000040 -:104080000000000000000000000000000000000030 -:104090000000000000000000000000000000000020 -:1040A0000000000000000000000000000000000010 -:1040B0000000000000000000000000000000000000 -:1040C00000000000000000000000000000000000F0 -:1040D00000000000000000000000000000000000E0 -:1040E00000000000000000000000000000000000D0 -:1040F00000000000000000000000000000000000C0 -:1041000000000000000000000000000000000000AF -:10411000000000000000000000000000000000009F -:10412000000000000000000000000000000000008F -:10413000000000000000000000000000000000007F -:10414000000000000000000000000000000000006F -:10415000000000000000000000000000000000005F -:10416000000000000000000000000000000000004F -:10417000000000000000000000000000000000003F -:10418000000000000000000000000000000000002F -:10419000000000000000000000000000000000001F -:1041A000000000000000000000000000000000000F -:1041B00000000000000000000000000000000000FF -:1041C00000000000000000000000000000000000EF -:1041D00000000000000000000000000000000000DF -:1041E00000000000000000000000000000000000CF -:1041F00000000000000000000000000000000000BF -:1042000000000000000000000000000000000000AE -:10421000000000000000000000000000000000009E -:10422000000000000000000000000000000000008E -:10423000000000000000000000000000000000007E -:10424000000000000000000000000000000000006E -:10425000000000000000000000000000000000005E -:10426000000000000000000000000000000000004E -:10427000000000000000000000000000000000003E -:10428000000000000000000000000000000000002E -:10429000000000000000000000000000000000001E -:1042A000000000000000000000000000000000000E -:1042B00000000000000000000000000000000000FE -:1042C00000000000000000000000000000000000EE -:1042D00000000000000000000000000000000000DE -:1042E00000000000000000000000000000000000CE -:1042F00000000000000000000000000000000000BE -:1043000000000000000000000000000000000000AD -:10431000000000000000000000000000000000009D -:10432000000000000000000000000000000000008D -:10433000000000000000000000000000000000007D -:10434000000000000000000000000000000000006D -:10435000000000000000000000000000000000005D -:10436000000000000000000000000000000000004D -:10437000000000000000000000000000000000003D -:10438000000000000000000000000000000000002D -:10439000000000000000000000000000000000001D -:1043A000000000000000000000000000000000000D -:1043B00000000000000000000000000000000000FD -:1043C00000000000000000000000000000000000ED -:1043D00000000000000000000000000000000000DD -:1043E00000000000000000000000000000000000CD -:1043F00000000000000000000000000000000000BD -:1044000000000000000000000000000000000000AC -:10441000000000000000000000000000000000009C -:10442000000000000000000000000000000000008C -:10443000000000000000000000000000000000007C -:10444000000000000000000000000000000000006C -:10445000000000000000000000000000000000005C -:10446000000000000000000000000000000000004C -:10447000000000000000000000000000000000003C -:10448000000000000000000000000000000000002C -:10449000000000000000000000000000000000001C -:1044A000000000000000000000000000000000000C -:1044B00000000000000000000000000000000000FC -:1044C00000000000000000000000000000000000EC -:1044D00000000000000000000000000000000000DC -:1044E00000000000000000000000000000000000CC -:1044F00000000000000000000000000000000000BC -:1045000000000000000000000000000000000000AB -:10451000000000000000000000000000000000009B -:10452000000000000000000000000000000000008B -:10453000000000000000000000000000000000007B -:10454000000000000000000000000000000000006B -:10455000000000000000000000000000000000005B -:10456000000000000000000000000000000000004B -:10457000000000000000000000000000000000003B -:10458000000000000000000000000000000000002B -:10459000000000000000000000000000000000001B -:1045A000000000000000000000000000000000000B -:1045B00000000000000000000000000000000000FB -:1045C00000000000000000000000000000000000EB -:1045D00000000000000000000000000000000000DB -:1045E00000000000000000000000000000000000CB -:1045F00000000000000000000000000000000000BB -:1046000000000000000000000000000000000000AA -:10461000000000000000000000000000000000009A -:10462000000000000000000000000000000000008A -:10463000000000000000000000000000000000007A -:10464000000000000000000000000000000000006A -:10465000000000000000000000000000000000005A -:10466000000000000000000000000000000000004A -:10467000000000000000000000000000000000003A -:10468000000000000000000000000000000000002A -:10469000000000000000000000000000000000001A -:1046A000000000000000000000000000000000000A -:1046B00000000000000000000000000000000000FA -:1046C00000000000000000000000000000000000EA -:1046D00000000000000000000000000000000000DA -:1046E00000000000000000000000000000000000CA -:1046F00000000000000000000000000000000000BA -:1047000000000000000000000000000000000000A9 -:104710000000000000000000000000000000000099 -:104720000000000000000000000000000000000089 -:104730000000000000000000000000000000000079 -:104740000000000000000000000000000000000069 -:104750000000000000000000000000000000000059 -:104760000000000000000000000000000000000049 -:104770000000000000000000000000000000000039 -:104780000000000000000000000000000000000029 -:104790000000000000000000000000000000000019 -:1047A0000000000000000000000000000000000009 -:1047B00000000000000000000000000000000000F9 -:1047C00000000000000000000000000000000000E9 -:1047D00000000000000000000000000000000000D9 -:1047E00000000000000000000000000000000000C9 -:1047F00000000000000000000000000000000000B9 -:1048000000000000000000000000000000000000A8 -:104810000000000000000000000000000000000098 -:104820000000000000000000000000000000000088 -:104830000000000000000000000000000000000078 -:104840000000000000000000000000000000000068 -:104850000000000000000000000000000000000058 -:104860000000000000000000000000000000000048 -:104870000000000000000000000000000000000038 -:104880000000000000000000000000000000000028 -:104890000000000000000000000000000000000018 -:1048A0000000000000000000000000000000000008 -:1048B00000000000000000000000000000000000F8 -:1048C00000000000000000000000000000000000E8 -:1048D00000000000000000000000000000000000D8 -:1048E00000000000000000000000000000000000C8 -:1048F00000000000000000000000000000000000B8 -:1049000000000000000000000000000000000000A7 -:104910000000000000000000000000000000000097 -:104920000000000000000000000000000000000087 -:104930000000000000000000000000000000000077 -:104940000000000000000000000000000000000067 -:104950000000000000000000000000000000000057 -:104960000000000000000000000000000000000047 -:104970000000000000000000000000000000000037 -:104980000000000000000000000000000000000027 -:104990000000000000000000000000000000000017 -:1049A0000000000000000000000000000000000007 -:1049B00000000000000000000000000000000000F7 -:1049C00000000000000000000000000000000000E7 -:1049D00000000000000000000000000000000000D7 -:1049E00000000000000000000000000000000000C7 -:1049F00000000000000000000000000000000000B7 -:104A000000000000000000000000000000000000A6 -:104A10000000000000000000000000000000000096 -:104A20000000000000000000000000000000000086 -:104A30000000000000000000000000000000000076 -:104A40000000000000000000000000000000000066 -:104A50000000000000000000000000000000000056 -:104A60000000000000000000000000000000000046 -:104A70000000000000000000000000000000000036 -:104A80000000000000000000000000000000000026 -:104A90000000000000000000000000000000000016 -:104AA0000000000000000000000000000000000006 -:104AB00000000000000000000000000000000000F6 -:104AC00000000000000000000000000000000000E6 -:104AD00000000000000000000000000000000000D6 -:104AE00000000000000000000000000000000000C6 -:104AF00000000000000000000000000000000000B6 -:104B000000000000000000000000000000000000A5 -:104B10000000000000000000000000000000000095 -:104B20000000000000000000000000000000000085 -:104B30000000000000000000000000000000000075 -:104B40000000000000000000000000000000000065 -:104B50000000000000000000000000000000000055 -:104B60000000000000000000000000000000000045 -:104B70000000000000000000000000000000000035 -:104B80000000000000000000000000000000000025 -:104B90000000000000000000000000000000000015 -:104BA0000000000000000000000000000000000005 -:104BB00000000000000000000000000000000000F5 -:104BC00000000000000000000000000000000000E5 -:104BD00000000000000000000000000000000000D5 -:104BE00000000000000000000000000000000000C5 -:104BF00000000000000000000000000000000000B5 -:104C000000000000000000000000000000000000A4 -:104C10000000000000000000000000000000000094 -:104C20000000000000000000000000000000000084 -:104C30000000000000000000000000000000000074 -:104C40000000000000000000000000000000000064 -:104C50000000000000000000000000000000000054 -:104C60000000000000000000000000000000000044 -:104C70000000000000000000000000000000000034 -:104C80000000000000000000000000000000000024 -:104C90000000000000000000000000000000000014 -:104CA0000000000000000000000000000000000004 -:104CB00000000000000000000000000000000000F4 -:104CC00000000000000000000000000000000000E4 -:104CD00000000000000000000000000000000000D4 -:104CE00000000000000000000000000000000000C4 -:104CF00000000000000000000000000000000000B4 -:104D000000000000000000000000000000000000A3 -:104D10000000000000000000000000000000000093 -:104D20000000000000000000000000000000000083 -:104D30000000000000000000000000000000000073 -:104D40000000000000000000000000000000000063 -:104D50000000000000000000000000000000000053 -:104D60000000000000000000000000000000000043 -:104D70000000000000000000000000000000000033 -:104D80000000000000000000000000000000000023 -:104D90000000000000000000000000000000000013 -:104DA0000000000000000000000000000000000003 -:104DB00000000000000000000000000000000000F3 -:104DC00000000000000000000000000000000000E3 -:104DD00000000000000000000000000000000000D3 -:104DE00000000000000000000000000000000000C3 -:104DF00000000000000000000000000000000000B3 -:104E000000000000000000000000000000000000A2 -:104E10000000000000000000000000000000000092 -:104E20000000000000000000000000000000000082 -:104E30000000000000000000000000000000000072 -:104E40000000000000000000000000000000000062 -:104E50000000000000000000000000000000000052 -:104E60000000000000000000000000000000000042 -:104E70000000000000000000000000000000000032 -:104E80000000000000000000000000000000000022 -:104E90000000000000000000000000000000000012 -:104EA0000000000000000000000000000000000002 -:104EB00000000000000000000000000000000000F2 -:104EC00000000000000000000000000000000000E2 -:104ED00000000000000000000000000000000000D2 -:104EE00000000000000000000000000000000000C2 -:104EF00000000000000000000000000000000000B2 -:104F000000000000000000000000000000000000A1 -:104F10000000000000000000000000000000000091 -:104F20000000000000000000000000000000000081 -:104F30000000000000000000000000000000000071 -:104F40000000000000000000000000000000000061 -:104F50000000000000000000000000000000000051 -:104F60000000000000000000000000000000000041 -:104F70000000000000000000000000000000000031 -:104F80000000000000000000000000000000000021 -:104F90000000000000000000000000000000000011 -:104FA0000000000000000000000000000000000001 -:104FB00000000000000000000000000000000000F1 -:104FC00000000000000000000000000000000000E1 -:104FD00000000000000000000000000000000000D1 -:104FE00000000000000000000000000000000000C1 -:104FF00000000000000000000000000000000000B1 -:1050000000000000000000000000000000000000A0 -:105010000000000000000000000000000000000090 -:105020000000000000000000000000000000000080 -:105030000000000000000000000000000000000070 -:105040000000000000000000000000000000000060 -:105050000000000000000000000000000000000050 -:105060000000000000000000000000000000000040 -:105070000000000000000000000000000000000030 -:105080000000000000000000000000000000000020 -:105090000000000000000000000000000000000010 -:1050A0000000000000000000000000000000000000 -:1050B00000000000000000000000000000000000F0 -:1050C00000000000000000000000000000000000E0 -:1050D00000000000000000000000000000000000D0 -:1050E00000000000000000000000000000000000C0 -:1050F00000000000000000000000000000000000B0 -:10510000000000000000000000000000000000009F -:10511000000000000000000000000000000000008F -:10512000000000000000000000000000000000007F -:10513000000000000000000000000000000000006F -:10514000000000000000000000000000000000005F -:10515000000000000000000000000000000000004F -:10516000000000000000000000000000000000003F -:10517000000000000000000000000000000000002F -:10518000000000000000000000000000000000001F -:10519000000000000000000000000000000000000F -:1051A00000000000000000000000000000000000FF -:1051B00000000000000000000000000000000000EF -:1051C00000000000000000000000000000000000DF -:1051D00000000000000000000000000000000000CF -:1051E00000000000000000000000000000000000BF -:1051F00000000000000000000000000000000000AF -:10520000000000000000000000000000000000009E -:10521000000000000000000000000000000000008E -:10522000000000000000000000000000000000007E -:10523000000000000000000000000000000000006E -:10524000000000000000000000000000000000005E -:10525000000000000000000000000000000000004E -:10526000000000000000000000000000000000003E -:10527000000000000000000000000000000000002E -:10528000000000000000000000000000000000001E -:10529000000000000000000000000000000000000E -:1052A00000000000000000000000000000000000FE -:1052B00000000000000000000000000000000000EE -:1052C00000000000000000000000000000000000DE -:1052D00000000000000000000000000000000000CE -:1052E00000000000000000000000000000000000BE -:1052F00000000000000000000000000000000000AE -:10530000000000000000000000000000000000009D -:10531000000000000000000000000000000000008D -:10532000000000000000000000000000000000007D -:10533000000000000000000000000000000000006D -:10534000000000000000000000000000000000005D -:10535000000000000000000000000000000000004D -:10536000000000000000000000000000000000003D -:10537000000000000000000000000000000000002D -:10538000000000000000000000000000000000001D -:10539000000000000000000000000000000000000D -:1053A00000000000000000000000000000000000FD -:1053B00000000000000000000000000000000000ED -:1053C00000000000000000000000000000000000DD -:1053D00000000000000000000000000000000000CD -:1053E00000000000000000000000000000000000BD -:1053F00000000000000000000000000000000000AD -:10540000000000000000000000000000000000009C -:10541000000000000000000000000000000000008C -:10542000000000000000000000000000000000007C -:10543000000000000000000000000000000000006C -:10544000000000000000000000000000000000005C -:10545000000000000000000000000000000000004C -:10546000000000000000000000000000000000003C -:10547000000000000000000000000000000000002C -:10548000000000000000000000000000000000001C -:10549000000000000000000000000000000000000C -:1054A00000000000000000000000000000000000FC -:1054B00000000000000000000000000000000000EC -:1054C00000000000000000000000000000000000DC -:1054D00000000000000000000000000000000000CC -:1054E00000000000000000000000000000000000BC -:1054F00000000000000000000000000000000000AC -:10550000000000000000000000000000000000009B -:10551000000000000000000000000000000000008B -:10552000000000000000000000000000000000007B -:10553000000000000000000000000000000000006B -:10554000000000000000000000000000000000005B -:10555000000000000000000000000000000000004B -:10556000000000000000000000000000000000003B -:10557000000000000000000000000000000000002B -:10558000000000000000000000000000000000001B -:10559000000000000000000000000000000000000B -:1055A00000000000000000000000000000000000FB -:1055B00000000000000000000000000000000000EB -:1055C00000000000000000000000000000000000DB -:1055D00000000000000000000000000000000000CB -:1055E00000000000000000000000000000000000BB -:1055F00000000000000000000000000000000000AB -:10560000000000000000000000000000000000009A -:10561000000000000000000000000000000000008A -:10562000000000000000000000000000000000007A -:10563000000000000000000000000000000000006A -:10564000000000000000000000000000000000005A -:10565000000000000000000000000000000000004A -:10566000000000000000000000000000000000003A -:10567000000000000000000000000000000000002A -:10568000000000000000000000000000000000001A -:10569000000000000000000000000000000000000A -:1056A00000000000000000000000000000000000FA -:1056B00000000000000000000000000000000000EA -:1056C00000000000000000000000000000000000DA -:1056D00000000000000000000000000000000000CA -:1056E00000000000000000000000000000000000BA -:1056F00000000000000000000000000000000000AA -:105700000000000000000000000000000000000099 -:105710000000000000000000000000000000000089 -:105720000000000000000000000000000000000079 -:105730000000000000000000000000000000000069 -:105740000000000000000000000000000000000059 -:105750000000000000000000000000000000000049 -:105760000000000000000000000000000000000039 -:105770000000000000000000000000000000000029 -:105780000000000000000000000000000000000019 -:105790000000000000000000000000000000000009 -:1057A00000000000000000000000000000000000F9 -:1057B00000000000000000000000000000000000E9 -:1057C00000000000000000000000000000000000D9 -:1057D00000000000000000000000000000000000C9 -:1057E00000000000000000000000000000000000B9 -:1057F00000000000000000000000000000000000A9 -:105800000000000000000000000000000000000098 -:105810000000000000000000000000000000000088 -:105820000000000000000000000000000000000078 -:105830000000000000000000000000000000000068 -:105840000000000000000000000000000000000058 -:105850000000000000000000000000000000000048 -:105860000000000000000000000000000000000038 -:105870000000000000000000000000000000000028 -:105880000000000000000000000000000000000018 -:105890000000000000000000000000000000000008 -:1058A00000000000000000000000000000000000F8 -:1058B00000000000000000000000000000000000E8 -:1058C00000000000000000000000000000000000D8 -:1058D00000000000000000000000000000000000C8 -:1058E00000000000000000000000000000000000B8 -:1058F00000000000000000000000000000000000A8 -:105900000000000000000000000000000000000097 -:105910000000000000000000000000000000000087 -:105920000000000000000000000000000000000077 -:105930000000000000000000000000000000000067 -:105940000000000000000000000000000000000057 -:105950000000000000000000000000000000000047 -:105960000000000000000000000000000000000037 -:105970000000000000000000000000000000000027 -:105980000000000000000000000000000000000017 -:105990000000000000000000000000000000000007 -:1059A00000000000000000000000000000000000F7 -:1059B00000000000000000000000000000000000E7 -:1059C00000000000000000000000000000000000D7 -:1059D00000000000000000000000000000000000C7 -:1059E00000000000000000000000000000000000B7 -:1059F00000000000000000000000000000000000A7 -:105A00000000000000000000000000000000000096 -:105A10000000000000000000000000000000000086 -:105A20000000000000000000000000000000000076 -:105A30000000000000000000000000000000000066 -:105A40000000000000000000000000000000000056 -:105A50000000000000000000000000000000000046 -:105A60000000000000000000000000000000000036 -:105A70000000000000000000000000000000000026 -:105A80000000000000000000000000000000000016 -:105A90000000000000000000000000000000000006 -:105AA00000000000000000000000000000000000F6 -:105AB00000000000000000000000000000000000E6 -:105AC00000000000000000000000000000000000D6 -:105AD00000000000000000000000000000000000C6 -:105AE00000000000000000000000000000000000B6 -:105AF00000000000000000000000000000000000A6 -:105B00000000000000000000000000000000000095 -:105B10000000000000000000000000000000000085 -:105B20000000000000000000000000000000000075 -:105B30000000000000000000000000000000000065 -:105B40000000000000000000000000000000000055 -:105B50000000000000000000000000000000000045 -:105B60000000000000000000000000000000000035 -:105B70000000000000000000000000000000000025 -:105B80000000000000000000000000000000000015 -:105B90000000000000000000000000000000000005 -:105BA00000000000000000000000000000000000F5 -:105BB00000000000000000000000000000000000E5 -:105BC00000000000000000000000000000000000D5 -:105BD00000000000000000000000000000000000C5 -:105BE00000000000000000000000000000000000B5 -:105BF00000000000000000000000000000000000A5 -:105C00000000000000000000000000000000000094 -:105C10000000000000000000000000000000000084 -:105C20000000000000000000000000000000000074 -:105C30000000000000000000000000000000000064 -:105C40000000000000000000000000000000000054 -:105C50000000000000000000000000000000000044 -:105C60000000000000000000000000000000000034 -:105C70000000000000000000000000000000000024 -:105C80000000000000000000000000000000000014 -:105C90000000000000000000000000000000000004 -:105CA00000000000000000000000000000000000F4 -:105CB00000000000000000000000000000000000E4 -:105CC00000000000000000000000000000000000D4 -:105CD00000000000000000000000000000000000C4 -:105CE00000000000000000000000000000000000B4 -:105CF00000000000000000000000000000000000A4 -:105D00000000000000000000000000000000000093 -:105D10000000000000000000000000000000000083 -:105D20000000000000000000000000000000000073 -:105D30000000000000000000000000000000000063 -:105D40000000000000000000000000000000000053 -:105D50000000000000000000000000000000000043 -:105D60000000000000000000000000000000000033 -:105D70000000000000000000000000000000000023 -:105D80000000000000000000000000000000000013 -:105D90000000000000000000000000000000000003 -:105DA00000000000000000000000000000000000F3 -:105DB00000000000000000000000000000000000E3 -:105DC00000000000000000000000000000000000D3 -:105DD00000000000000000000000000000000000C3 -:105DE00000000000000000000000000000000000B3 -:105DF00000000000000000000000000000000000A3 -:105E00000000000000000000000000000000000092 -:105E10000000000000000000000000000000000082 -:105E20000000000000000000000000000000000072 -:105E30000000000000000000000000000000000062 -:105E40000000000000000000000000000000000052 -:105E50000000000000000000000000000000000042 -:105E60000000000000000000000000000000000032 -:105E70000000000000000000000000000000000022 -:105E80000000000000000000000000000000000012 -:105E90000000000000000000000000000000000002 -:105EA00000000000000000000000000000000000F2 -:105EB00000000000000000000000000000000000E2 -:105EC00000000000000000000000000000000000D2 -:105ED00000000000000000000000000000000000C2 -:105EE00000000000000000000000000000000000B2 -:105EF00000000000000000000000000000000000A2 -:105F00000000000000000000000000000000000091 -:105F10000000000000000000000000000000000081 -:105F20000000000000000000000000000000000071 -:105F30000000000000000000000000000000000061 -:105F40000000000000000000000000000000000051 -:105F50000000000000000000000000000000000041 -:105F60000000000000000000000000000000000031 -:105F70000000000000000000000000000000000021 -:105F80000000000000000000000000000000000011 -:105F90000000000000000000000000000000000001 -:105FA00000000000000000000000000000000000F1 -:105FB00000000000000000000000000000000000E1 -:105FC00000000000000000000000000000000000D1 -:105FD00000000000000000000000000000000000C1 -:105FE00000000000000000000000000000000000B1 -:105FF00000000000000000000000000000000000A1 -:106000000000000000000000000000000000000090 -:106010000000000000000000000000000000000080 -:106020000000000000000000000000000000000070 -:106030000000000000000000000000000000000060 -:106040000000000000000000000000000000000050 -:106050000000000000000000000000000000000040 -:106060000000000000000000000000000000000030 -:106070000000000000000000000000000000000020 -:106080000000000000000000000000000000000010 -:106090000000000000000000000000000000000000 -:1060A00000000000000000000000000000000000F0 -:1060B00000000000000000000000000000000000E0 -:1060C00000000000000000000000000000000000D0 -:1060D00000000000000000000000000000000000C0 -:1060E00000000000000000000000000000000000B0 -:1060F00000000000000000000000000000000000A0 -:10610000000000000000000000000000000000008F -:10611000000000000000000000000000000000007F -:10612000000000000000000000000000000000006F -:10613000000000000000000000000000000000005F -:10614000000000000000000000000000000000004F -:10615000000000000000000000000000000000003F -:10616000000000000000000000000000000000002F -:10617000000000000000000000000000000000001F -:10618000000000000000000000000000000000000F -:1061900000000000000000000000000000000000FF -:1061A00000000000000000000000000000000000EF -:1061B00000000000000000000000000000000000DF -:1061C00000000000000000000000000000000000CF -:1061D00000000000000000000000000000000000BF -:1061E00000000000000000000000000000000000AF -:1061F000000000000000000000000000000000009F -:10620000000000000000000000000000000000008E -:10621000000000000000000000000000000000007E -:10622000000000000000000000000000000000006E -:10623000000000000000000000000000000000005E -:10624000000000000000000000000000000000004E -:10625000000000000000000000000000000000003E -:10626000000000000000000000000000000000002E -:10627000000000000000000000000000000000001E -:10628000000000000000000000000000000000000E -:1062900000000000000000000000000000000000FE -:1062A00000000000000000000000000000000000EE -:1062B00000000000000000000000000000000000DE -:1062C00000000000000000000000000000000000CE -:1062D00000000000000000000000000000000000BE -:1062E00000000000000000000000000000000000AE -:1062F000000000000000000000000000000000009E -:10630000000000000000000000000000000000008D -:10631000000000000000000000000000000000007D -:10632000000000000000000000000000000000006D -:10633000000000000000000000000000000000005D -:10634000000000000000000000000000000000004D -:10635000000000000000000000000000000000003D -:10636000000000000000000000000000000000002D -:10637000000000000000000000000000000000001D -:10638000000000000000000000000000000000000D -:1063900000000000000000000000000000000000FD -:1063A00000000000000000000000000000000000ED -:1063B00000000000000000000000000000000000DD -:1063C00000000000000000000000000000000000CD -:1063D00000000000000000000000000000000000BD -:1063E00000000000000000000000000000000000AD -:1063F000000000000000000000000000000000009D -:10640000000000000000000000000000000000008C -:10641000000000000000000000000000000000007C -:10642000000000000000000000000000000000006C -:10643000000000000000000000000000000000005C -:10644000000000000000000000000000000000004C -:10645000000000000000000000000000000000003C -:10646000000000000000000000000000000000002C -:10647000000000000000000000000000000000001C -:10648000000000000000000000000000000000000C -:1064900000000000000000000000000000000000FC -:1064A00000000000000000000000000000000000EC -:1064B00000000000000000000000000000000000DC -:1064C00000000000000000000000000000000000CC -:1064D00000000000000000000000000000000000BC -:1064E00000000000000000000000000000000000AC -:1064F000000000000000000000000000000000009C -:10650000000000000000000000000000000000008B -:10651000000000000000000000000000000000007B -:10652000000000000000000000000000000000006B -:10653000000000000000000000000000000000005B -:10654000000000000000000000000000000000004B -:10655000000000000000000000000000000000003B -:10656000000000000000000000000000000000002B -:10657000000000000000000000000000000000001B -:10658000000000000000000000000000000000000B -:1065900000000000000000000000000000000000FB -:1065A00000000000000000000000000000000000EB -:1065B00000000000000000000000000000000000DB -:1065C00000000000000000000000000000000000CB -:1065D00000000000000000000000000000000000BB -:1065E00000000000000000000000000000000000AB -:1065F000000000000000000000000000000000009B -:10660000000000000000000000000000000000008A -:10661000000000000000000000000000000000007A -:10662000000000000000000000000000000000006A -:10663000000000000000000000000000000000005A -:10664000000000000000000000000000000000004A -:10665000000000000000000000000000000000003A -:10666000000000000000000000000000000000002A -:10667000000000000000000000000000000000001A -:10668000000000000000000000000000000000000A -:1066900000000000000000000000000000000000FA -:1066A00000000000000000000000000000000000EA -:1066B00000000000000000000000000000000000DA -:1066C00000000000000000000000000000000000CA -:1066D00000000000000000000000000000000000BA -:1066E00000000000000000000000000000000000AA -:1066F000000000000000000000000000000000009A -:106700000000000000000000000000000000000089 -:106710000000000000000000000000000000000079 -:106720000000000000000000000000000000000069 -:106730000000000000000000000000000000000059 -:106740000000000000000000000000000000000049 -:106750000000000000000000000000000000000039 -:106760000000000000000000000000000000000029 -:106770000000000000000000000000000000000019 -:106780000000000000000000000000000000000009 -:1067900000000000000000000000000000000000F9 -:1067A00000000000000000000000000000000000E9 -:1067B00000000000000000000000000000000000D9 -:1067C00000000000000000000000000000000000C9 -:1067D00000000000000000000000000000000000B9 -:1067E00000000000000000000000000000000000A9 -:1067F0000000000000000000000000000000000099 -:106800000000000000000000000000000000000088 -:106810000000000000000000000000000000000078 -:106820000000000000000000000000000000000068 -:106830000000000000000000000000000000000058 -:106840000000000000000000000000000000000048 -:106850000000000000000000000000000000000038 -:106860000000000000000000000000000000000028 -:106870000000000000000000000000000000000018 -:106880000000000000000000000000000000000008 -:1068900000000000000000000000000000000000F8 -:1068A00000000000000000000000000000000000E8 -:1068B00000000000000000000000000000000000D8 -:1068C00000000000000000000000000000000000C8 -:1068D00000000000000000000000000000000000B8 -:1068E00000000000000000000000000000000000A8 -:1068F0000000000000000000000000000000000098 -:106900000000000000000000000000000000000087 -:106910000000000000000000000000000000000077 -:106920000000000000000000000000000000000067 -:106930000000000000000000000000000000000057 -:106940000000000000000000000000000000000047 -:106950000000000000000000000000000000000037 -:106960000000000000000000000000000000000027 -:106970000000000000000000000000000000000017 -:106980000000000000000000000000000000000007 -:1069900000000000000000000000000000000000F7 -:1069A00000000000000000000000000000000000E7 -:1069B00000000000000000000000000000000000D7 -:1069C00000000000000000000000000000000000C7 -:1069D00000000000000000000000000000000000B7 -:1069E00000000000000000000000000000000000A7 -:1069F0000000000000000000000000000000000097 -:106A00000000000000000000000000000000000086 -:106A10000000000000000000000000000000000076 -:106A20000000000000000000000000000000000066 -:106A30000000000000000000000000000000000056 -:106A40000000000000000000000000000000000046 -:106A50000000000000000000000000000000000036 -:106A60000000000000000000000000000000000026 -:106A70000000000000000000000000000000000016 -:106A80000000000000000000000000000000000006 -:106A900000000000000000000000000000000000F6 -:106AA00000000000000000000000000000000000E6 -:106AB00000000000000000000000000000000000D6 -:106AC00000000000000000000000000000000000C6 -:106AD00000000000000000000000000000000000B6 -:106AE00000000000000000000000000000000000A6 -:106AF0000000000000000000000000000000000096 -:106B00000000000000000000000000000000000085 -:106B10000000000000000000000000000000000075 -:106B20000000000000000000000000000000000065 -:106B30000000000000000000000000000000000055 -:106B40000000000000000000000000000000000045 -:106B50000000000000000000000000000000000035 -:106B60000000000000000000000000000000000025 -:106B70000000000000000000000000000000000015 -:106B80000000000000000000000000000000000005 -:106B900000000000000000000000000000000000F5 -:106BA00000000000000000000000000000000000E5 -:106BB00000000000000000000000000000000000D5 -:106BC00000000000000000000000000000000000C5 -:106BD00000000000000000000000000000000000B5 -:106BE00000000000000000000000000000000000A5 -:106BF0000000000000000000000000000000000095 -:106C00000000000000000000000000000000000084 -:106C10000000000000000000000000000000000074 -:106C20000000000000000000000000000000000064 -:106C30000000000000000000000000000000000054 -:106C40000000000000000000000000000000000044 -:106C50000000000000000000000000000000000034 -:106C60000000000000000000000000000000000024 -:106C70000000000000000000000000000000000014 -:106C80000000000000000000000000000000000004 -:106C900000000000000000000000000000000000F4 -:106CA00000000000000000000000000000000000E4 -:106CB00000000000000000000000000000000000D4 -:106CC00000000000000000000000000000000000C4 -:106CD00000000000000000000000000000000000B4 -:106CE00000000000000000000000000000000000A4 -:106CF0000000000000000000000000000000000094 -:106D00000000000000000000000000000000000083 -:106D10000000000000000000000000000000000073 -:106D20000000000000000000000000000000000063 -:106D30000000000000000000000000000000000053 -:106D40000000000000000000000000000000000043 -:106D50000000000000000000000000000000000033 -:106D60000000000000000000000000000000000023 -:106D70000000000000000000000000000000000013 -:106D80000000000000000000000000000000000003 -:106D900000000000000000000000000000000000F3 -:106DA00000000000000000000000000000000000E3 -:106DB00000000000000000000000000000000000D3 -:106DC00000000000000000000000000000000000C3 -:106DD00000000000000000000000000000000000B3 -:106DE00000000000000000000000000000000000A3 -:106DF0000000000000000000000000000000000093 -:106E00000000000000000000000000000000000082 -:106E10000000000000000000000000000000000072 -:106E20000000000000000000000000000000000062 -:106E30000000000000000000000000000000000052 -:106E40000000000000000000000000000000000042 -:106E50000000000000000000000000000000000032 -:106E60000000000000000000000000000000000022 -:106E70000000000000000000000000000000000012 -:106E80000000000000000000000000000000000002 -:106E900000000000000000000000000000000000F2 -:106EA00000000000000000000000000000000000E2 -:106EB00000000000000000000000000000000000D2 -:106EC00000000000000000000000000000000000C2 -:106ED00000000000000000000000000000000000B2 -:106EE00000000000000000000000000000000000A2 -:106EF0000000000000000000000000000000000092 -:106F00000000000000000000000000000000000081 -:106F10000000000000000000000000000000000071 -:106F20000000000000000000000000000000000061 -:106F30000000000000000000000000000000000051 -:106F40000000000000000000000000000000000041 -:106F50000000000000000000000000000000000031 -:106F60000000000000000000000000000000000021 -:106F70000000000000000000000000000000000011 -:106F80000000000000000000000000000000000001 -:106F900000000000000000000000000000000000F1 -:106FA00000000000000000000000000000000000E1 -:106FB00000000000000000000000000000000000D1 -:106FC00000000000000000000000000000000000C1 -:106FD00000000000000000000000000000000000B1 -:106FE00000000000000000000000000000000000A1 -:106FF0000000000000000000000000000000000091 -:107000000000000000000000000000000000000080 -:107010000000000000000000000000000000000070 -:107020000000000000000000000000000000000060 -:107030000000000000000000000000000000000050 -:107040000000000000000000000000000000000040 -:107050000000000000000000000000000000000030 -:107060000000000000000000000000000000000020 -:107070000000000000000000000000000000000010 -:107080000000000000000000000000000000000000 -:1070900000000000000000000000000000000000F0 -:1070A00000000000000000000000000000000000E0 -:1070B00000000000000000000000000000000000D0 -:1070C00000000000000000000000000000000000C0 -:1070D00000000000000000000000000000000000B0 -:1070E00000000000000000000000000000000000A0 -:1070F0000000000000000000000000000000000090 -:10710000000000000000000000000000000000007F -:10711000000000000000000000000000000000006F -:10712000000000000000000000000000000000005F -:10713000000000000000000000000000000000004F -:10714000000000000000000000000000000000003F -:10715000000000000000000000000000000000002F -:10716000000000000000000000000000000000001F -:10717000000000000000000000000000000000000F -:1071800000000000000000000000000000000000FF -:1071900000000000000000000000000000000000EF -:1071A00000000000000000000000000000000000DF -:1071B00000000000000000000000000000000000CF -:1071C00000000000000000000000000000000000BF -:1071D00000000000000000000000000000000000AF -:1071E000000000000000000000000000000000009F -:1071F000000000000000000000000000000000008F -:10720000000000000000000000000000000000007E -:10721000000000000000000000000000000000006E -:10722000000000000000000000000000000000005E -:10723000000000000000000000000000000000004E -:10724000000000000000000000000000000000003E -:10725000000000000000000000000000000000002E -:10726000000000000000000000000000000000001E -:10727000000000000000000000000000000000000E -:1072800000000000000000000000000000000000FE -:1072900000000000000000000000000000000000EE -:1072A00000000000000000000000000000000000DE -:1072B00000000000000000000000000000000000CE -:1072C00000000000000000000000000000000000BE -:1072D00000000000000000000000000000000000AE -:1072E000000000000000000000000000000000009E -:1072F000000000000000000000000000000000008E -:10730000000000000000000000000000000000007D -:10731000000000000000000000000000000000006D -:10732000000000000000000000000000000000005D -:10733000000000000000000000000000000000004D -:10734000000000000000000000000000000000003D -:10735000000000000000000000000000000000002D -:10736000000000000000000000000000000000001D -:10737000000000000000000000000000000000000D -:1073800000000000000000000000000000000000FD -:1073900000000000000000000000000000000000ED -:1073A00000000000000000000000000000000000DD -:1073B00000000000000000000000000000000000CD -:1073C00000000000000000000000000000000000BD -:1073D00000000000000000000000000000000000AD -:1073E000000000000000000000000000000000009D -:1073F000000000000000000000000000000000008D -:10740000000000000000000000000000000000007C -:10741000000000000000000000000000000000006C -:10742000000000000000000000000000000000005C -:10743000000000000000000000000000000000004C -:10744000000000000000000000000000000000003C -:10745000000000000000000000000000000000002C -:10746000000000000000000000000000000000001C -:10747000000000000000000000000000000000000C -:1074800000000000000000000000000000000000FC -:1074900000000000000000000000000000000000EC -:1074A00000000000000000000000000000000000DC -:1074B00000000000000000000000000000000000CC -:1074C00000000000000000000000000000000000BC -:1074D00000000000000000000000000000000000AC -:1074E000000000000000000000000000000000009C -:1074F000000000000000000000000000000000008C -:10750000000000000000000000000000000000007B -:10751000000000000000000000000000000000006B -:10752000000000000000000000000000000000005B -:10753000000000000000000000000000000000004B -:10754000000000000000000000000000000000003B -:10755000000000000000000000000000000000002B -:10756000000000000000000000000000000000001B -:10757000000000000000000000000000000000000B -:1075800000000000000000000000000000000000FB -:1075900000000000000000000000000000000000EB -:1075A00000000000000000000000000000000000DB -:1075B00000000000000000000000000000000000CB -:1075C00000000000000000000000000000000000BB -:1075D00000000000000000000000000000000000AB -:1075E000000000000000000000000000000000009B -:1075F000000000000000000000000000000000008B -:10760000000000000000000000000000000000007A -:10761000000000000000000000000000000000006A -:10762000000000000000000000000000000000005A -:10763000000000000000000000000000000000004A -:10764000000000000000000000000000000000003A -:10765000000000000000000000000000000000002A -:10766000000000000000000000000000000000001A -:10767000000000000000000000000000000000000A -:1076800000000000000000000000000000000000FA -:1076900000000000000000000000000000000000EA -:1076A00000000000000000000000000000000000DA -:1076B00000000000000000000000000000000000CA -:1076C00000000000000000000000000000000000BA -:1076D00000000000000000000000000000000000AA -:1076E000000000000000000000000000000000009A -:1076F000000000000000000000000000000000008A -:107700000000000000000000000000000000000079 -:107710000000000000000000000000000000000069 -:107720000000000000000000000000000000000059 -:107730000000000000000000000000000000000049 -:107740000000000000000000000000000000000039 -:107750000000000000000000000000000000000029 -:107760000000000000000000000000000000000019 -:107770000000000000000000000000000000000009 -:1077800000000000000000000000000000000000F9 -:1077900000000000000000000000000000000000E9 -:1077A00000000000000000000000000000000000D9 -:1077B00000000000000000000000000000000000C9 -:1077C00000000000000000000000000000000000B9 -:1077D00000000000000000000000000000000000A9 -:1077E0000000000000000000000000000000000099 -:1077F0000000000000000000000000000000000089 -:107800000000000000000000000000000000000078 -:107810000000000000000000000000000000000068 -:107820000000000000000000000000000000000058 -:107830000000000000000000000000000000000048 -:107840000000000000000000000000000000000038 -:107850000000000000000000000000000000000028 -:107860000000000000000000000000000000000018 -:107870000000000000000000000000000000000008 -:1078800000000000000000000000000000000000F8 -:1078900000000000000000000000000000000000E8 -:1078A00000000000000000000000000000000000D8 -:1078B00000000000000000000000000000000000C8 -:1078C00000000000000000000000000000000000B8 -:1078D00000000000000000000000000000000000A8 -:1078E0000000000000000000000000000000000098 -:1078F0000000000000000000000000000000000088 -:107900000000000000000000000000000000000077 -:107910000000000000000000000000000000000067 -:107920000000000000000000000000000000000057 -:107930000000000000000000000000000000000047 -:107940000000000000000000000000000000000037 -:107950000000000000000000000000000000000027 -:107960000000000000000000000000000000000017 -:107970000000000000000000000000000000000007 -:1079800000000000000000000000000000000000F7 -:1079900000000000000000000000000000000000E7 -:1079A00000000000000000000000000000000000D7 -:1079B00000000000000000000000000000000000C7 -:1079C00000000000000000000000000000000000B7 -:1079D00000000000000000000000000000000000A7 -:1079E0000000000000000000000000000000000097 -:1079F0000000000000000000000000000000000087 -:107A00000000000000000000000000000000000076 -:107A10000000000000000000000000000000000066 -:107A20000000000000000000000000000000000056 -:107A30000000000000000000000000000000000046 -:107A40000000000000000000000000000000000036 -:107A50000000000000000000000000000000000026 -:107A60000000000000000000000000000000000016 -:107A70000000000000000000000000000000000006 -:107A800000000000000000000000000000000000F6 -:107A900000000000000000000000000000000000E6 -:107AA00000000000000000000000000000000000D6 -:107AB00000000000000000000000000000000000C6 -:107AC00000000000000000000000000000000000B6 -:107AD00000000000000000000000000000000000A6 -:107AE0000000000000000000000000000000000096 -:107AF0000000000000000000000000000000000086 -:107B00000000000000000000000000000000000075 -:107B10000000000000000000000000000000000065 -:107B20000000000000000000000000000000000055 -:107B30000000000000000000000000000000000045 -:107B40000000000000000000000000000000000035 -:107B50000000000000000000000000000000000025 -:107B60000000000000000000000000000000000015 -:107B70000000000000000000000000000000000005 -:107B800000000000000000000000000000000000F5 -:107B900000000000000000000000000000000000E5 -:107BA00000000000000000000000000000000000D5 -:107BB00000000000000000000000000000000000C5 -:107BC00000000000000000000000000000000000B5 -:107BD00000000000000000000000000000000000A5 -:107BE0000000000000000000000000000000000095 -:107BF0000000000000000000000000000000000085 -:107C00000000000000000000000000000000000074 -:107C10000000000000000000000000000000000064 -:107C20000000000000000000000000000000000054 -:107C30000000000000000000000000000000000044 -:107C40000000000000000000000000000000000034 -:107C50000000000000000000000000000000000024 -:107C60000000000000000000000000000000000014 -:107C70000000000000000000000000000000000004 -:107C800000000000000000000000000000000000F4 -:107C900000000000000000000000000000000000E4 -:107CA00000000000000000000000000000000000D4 -:107CB00000000000000000000000000000000000C4 -:107CC00000000000000000000000000000000000B4 -:107CD00000000000000000000000000000000000A4 -:107CE0000000000000000000000000000000000094 -:107CF0000000000000000000000000000000000084 -:107D00000000000000000000000000000000000073 -:107D10000000000000000000000000000000000063 -:107D20000000000000000000000000000000000053 -:107D30000000000000000000000000000000000043 -:107D40000000000000000000000000000000000033 -:107D50000000000000000000000000000000000023 -:107D60000000000000000000000000000000000013 -:107D70000000000000000000000000000000000003 -:107D800000000000000000000000000000000000F3 -:107D900000000000000000000000000000000000E3 -:107DA00000000000000000000000000000000000D3 -:107DB00000000000000000000000000000000000C3 -:107DC00000000000000000000000000000000000B3 -:107DD00000000000000000000000000000000000A3 -:107DE0000000000000000000000000000000000093 -:107DF0000000000000000000000000000000000083 -:107E00000000000000000000000000000000000072 -:107E10000000000000000000000000000000000062 -:107E20000000000000000000000000000000000052 -:107E30000000000000000000000000000000000042 -:107E40000000000000000000000000000000000032 -:107E50000000000000000000000000000000000022 -:107E60000000000000000000000000000000000012 -:107E70000000000000000000000000000000000002 -:107E800000000000000000000000000000000000F2 -:107E900000000000000000000000000000000000E2 -:107EA00000000000000000000000000000000000D2 -:107EB00000000000000000000000000000000000C2 -:107EC00000000000000000000000000000000000B2 -:107ED00000000000000000000000000000000000A2 -:107EE0000000000000000000000000000000000092 -:107EF0000000000000000000000000000000000082 -:107F00000000000000000000000000000000000071 -:107F10000000000000000000000000000000000061 -:107F20000000000000000000000000000000000051 -:107F30000000000000000000000000000000000041 -:107F40000000000000000000000000000000000031 -:107F50000000000000000000000000000000000021 -:107F60000000000000000000000000000000000011 -:107F70000000000000000000000000000000000001 -:107F800000000000000000000000000000000000F1 -:107F900000000000000000000000000000000000E1 -:107FA00000000000000000000000000000000000D1 -:107FB00000000000000000000000000000000000C1 -:107FC00000000000000000000000000000000000B1 -:107FD00000000000000000000000000000000000A1 -:107FE0000000000000000000000000000000000091 -:107FF0000000000000000000000000000000000081 -:108000000000000000000000000000000000000070 -:108010000000000000000000000000000000000060 -:108020000000000000000000000000000000000050 -:108030000000000000000000000000000000000040 -:108040000000000000000000000000000000000030 -:108050000000000000000000000000000000000020 -:108060000000000000000000000000000000000010 -:108070000000000000000000000000000000000000 -:1080800000000000000000000000000000000000F0 -:1080900000000000000000000000000000000000E0 -:1080A00000000000000000000000000000000000D0 -:1080B00000000000000000000000000000000000C0 -:1080C00000000000000000000000000000000000B0 -:1080D00000000000000000000000000000000000A0 -:1080E0000000000000000000000000000000000090 -:1080F0000000000000000000000000000000000080 -:10810000000000000000000000000000000000006F -:10811000000000000000000000000000000000005F -:10812000000000000000000000000000000000004F -:10813000000000000000000000000000000000003F -:10814000000000000000000000000000000000002F -:10815000000000000000000000000000000000001F -:10816000000000000000000000000000000000000F -:1081700000000000000000000000000000000000FF -:1081800000000000000000000000000000000000EF -:1081900000000000000000000000000000000000DF -:1081A00000000000000000000000000000000000CF -:1081B00000000000000000000000000000000000BF -:1081C00000000000000000000000000000000000AF -:1081D000000000000000000000000000000000009F -:1081E000000000000000000000000000000000008F -:1081F000000000000000000000000000000000007F -:10820000000000000000000000000000000000006E -:10821000000000000000000000000000000000005E -:10822000000000000000000000000000000000004E -:10823000000000000000000000000000000000003E -:10824000000000000000000000000000000000002E -:10825000000000000000000000000000000000001E -:10826000000000000000000000000000000000000E -:1082700000000000000000000000000000000000FE -:1082800000000000000000000000000000000000EE -:1082900000000000000000000000000000000000DE -:1082A00000000000000000000000000000000000CE -:1082B00000000000000000000000000000000000BE -:1082C00000000000000000000000000000000000AE -:1082D000000000000000000000000000000000009E -:1082E000000000000000000000000000000000008E -:1082F000000000000000000000000000000000007E -:10830000000000000000000000000000000000006D -:10831000000000000000000000000000000000005D -:10832000000000000000000000000000000000004D -:10833000000000000000000000000000000000003D -:10834000000000000000000000000000000000002D -:10835000000000000000000000000000000000001D -:10836000000000000000000000000000000000000D -:1083700000000000000000000000000000000000FD -:1083800000000000000000000000000000000000ED -:1083900000000000000000000000000000000000DD -:1083A00000000000000000000000000000000000CD -:1083B00000000000000000000000000000000000BD -:1083C00000000000000000000000000000000000AD -:1083D000000000000000000000000000000000009D -:1083E000000000000000000000000000000000008D -:1083F000000000000000000000000000000000007D -:10840000000000000000000000000000000000006C -:10841000000000000000000000000000000000005C -:10842000000000000000000000000000000000004C -:10843000000000000000000000000000000000003C -:10844000000000000000000000000000000000002C -:10845000000000000000000000000000000000001C -:10846000000000000000000000000000000000000C -:1084700000000000000000000000000000000000FC -:1084800000000000000000000000000000000000EC -:1084900000000000000000000000000000000000DC -:1084A00000000000000000000000000000000000CC -:1084B00000000000000000000000000000000000BC -:1084C00000000000000000000000000000000000AC -:1084D000000000000000000000000000000000009C -:1084E000000000000000000000000000000000008C -:1084F000000000000000000000000000000000007C -:10850000000000000000000000000000000000006B -:10851000000000000000000000000000000000005B -:10852000000000000000000000000000000000004B -:10853000000000000000000000000000000000003B -:10854000000000000000000000000000000000002B -:10855000000000000000000000000000000000001B -:10856000000000000000000000000000000000000B -:1085700000000000000000000000000000000000FB -:1085800000000000000000000000000000000000EB -:1085900000000000000000000000000000000000DB -:1085A00000000000000000000000000000000000CB -:1085B00000000000000000000000000000000000BB -:1085C00000000000000000000000000000000000AB -:1085D000000000000000000000000000000000009B -:1085E000000000000000000000000000000000008B -:1085F000000000000000000000000000000000007B -:10860000000000000000000000000000000000006A -:10861000000000000000000000000000000000005A -:10862000000000000000000000000000000000004A -:10863000000000000000000000000000000000003A -:10864000000000000000000000000000000000002A -:10865000000000000000000000000000000000001A -:10866000000000000000000000000000000000000A -:1086700000000000000000000000000000000000FA -:1086800000000000000000000000000000000000EA -:1086900000000000000000000000000000000000DA -:1086A00000000000000000000000000000000000CA -:1086B00000000000000000000000000000000000BA -:1086C00000000000000000000000000000000000AA -:1086D000000000000000000000000000000000009A -:1086E000000000000000000000000000000000008A -:1086F000000000000000000000000000000000007A -:108700000000000000000000000000000000000069 -:108710000000000000000000000000000000000059 -:108720000000000000000000000000000000000049 -:108730000000000000000000000000000000000039 -:108740000000000000000000000000000000000029 -:108750000000000000000000000000000000000019 -:108760000000000000000000000000000000000009 -:1087700000000000000000000000000000000000F9 -:1087800000000000000000000000000000000000E9 -:1087900000000000000000000000000000000000D9 -:1087A00000000000000000000000000000000000C9 -:1087B00000000000000000000000000000000000B9 -:1087C00000000000000000000000000000000000A9 -:1087D0000000000000000000000000000000000099 -:1087E0000000000000000000000000000000000089 -:1087F0000000000000000000000000000000000079 -:108800000000000000000000000000000000000068 -:108810000000000000000000000000000000000058 -:108820000000000000000000000000000000000048 -:108830000000000000000000000000000000000038 -:108840000000000000000000000000000000000028 -:108850000000000000000000000000000000000018 -:108860000000000000000000000000000000000008 -:1088700000000000000000000000000000000000F8 -:1088800000000000000000000000000000000000E8 -:1088900000000000000000000000000000000000D8 -:1088A00000000000000000000000000000000000C8 -:1088B00000000000000000000000000000000000B8 -:1088C00000000000000000000000000000000000A8 -:1088D0000000000000000000000000000000000098 -:1088E0000000000000000000000000000000000088 -:1088F0000000000000000000000000000000000078 -:108900000000000000000000000000000000000067 -:108910000000000000000000000000000000000057 -:108920000000000000000000000000000000000047 -:108930000000000000000000000000000000000037 -:108940000000000000000000000000000000000027 -:108950000000000000000000000000000000000017 -:108960000000000000000000000000000000000007 -:1089700000000000000000000000000000000000F7 -:1089800000000000000000000000000000000000E7 -:1089900000000000000000000000000000000000D7 -:1089A00000000000000000000000000000000000C7 -:1089B00000000000000000000000000000000000B7 -:1089C00000000000000000000000000000000000A7 -:1089D0000000000000000000000000000000000097 -:1089E0000000000000000000000000000000000087 -:1089F0000000000000000000000000000000000077 -:108A00000000000000000000000000000000000066 -:108A10000000000000000000000000000000000056 -:108A20000000000000000000000000000000000046 -:108A30000000000000000000000000000000000036 -:108A40000000000000000000000000000000000026 -:108A50000000000000000000000000000000000016 -:108A60000000000000000000000000000000000006 -:108A700000000000000000000000000000000000F6 -:108A800000000000000000000000000000000000E6 -:108A900000000000000000000000000000000000D6 -:108AA00000000000000000000000000000000000C6 -:108AB00000000000000000000000000000000000B6 -:108AC00000000000000000000000000000000000A6 -:108AD0000000000000000000000000000000000096 -:108AE0000000000000000000000000000000000086 -:108AF0000000000000000000000000000000000076 -:108B00000000000000000000000000000000000065 -:108B10000000000000000000000000000000000055 -:108B20000000000000000000000000000000000045 -:108B30000000000000000000000000000000000035 -:108B40000000000000000000000000000000000025 -:108B50000000000000000000000000000000000015 -:108B60000000000000000000000000000000000005 -:108B700000000000000000000000000000000000F5 -:108B800000000000000000000000000000000000E5 -:108B900000000000000000000000000000000000D5 -:108BA00000000000000000000000000000000000C5 -:108BB00000000000000000000000000000000000B5 -:108BC00000000000000000000000000000000000A5 -:108BD0000000000000000000000000000000000095 -:108BE0000000000000000000000000000000000085 -:108BF0000000000000000000000000000000000075 -:108C00000000000000000000000000000000000064 -:108C10000000000000000000000000000000000054 -:108C20000000000000000000000000000000000044 -:108C30000000000000000000000000000000000034 -:108C40000000000000000000000000000000000024 -:108C50000000000000000000000000000000000014 -:108C60000000000000000000000000000000000004 -:108C700000000000000000000000000000000000F4 -:108C800000000000000000000000000000000000E4 -:108C900000000000000000000000000000000000D4 -:108CA00000000000000000000000000000000000C4 -:108CB00000000000000000000000000000000000B4 -:108CC00000000000000000000000000000000000A4 -:108CD0000000000000000000000000000000000094 -:108CE0000000000000000000000000000000000084 -:108CF0000000000000000000000000000000000074 -:108D00000000000000000000000000000000000063 -:108D10000000000000000000000000000000000053 -:108D20000000000000000000000000000000000043 -:108D30000000000000000000000000000000000033 -:108D40000000000000000000000000000000000023 -:108D50000000000000000000000000000000000013 -:108D60000000000000000000000000000000000003 -:108D700000000000000000000000000000000000F3 -:108D800000000000000000000000000000000000E3 -:108D900000000000000000000000000000000000D3 -:108DA00000000000000000000000000000000000C3 -:108DB00000000000000000000000000000000000B3 -:108DC00000000000000000000000000000000000A3 -:108DD0000000000000000000000000000000000093 -:108DE0000000000000000000000000000000000083 -:108DF0000000000000000000000000000000000073 -:108E00000000000000000000000000000000000062 -:108E10000000000000000000000000000000000052 -:108E20000000000000000000000000000000000042 -:108E30000000000000000000000000000000000032 -:108E40000000000000000000000000000000000022 -:108E50000000000000000000000000000000000012 -:108E60000000000000000000000000000000000002 -:108E700000000000000000000000000000000000F2 -:108E800000000000000000000000000000000000E2 -:108E900000000000000000000000000000000000D2 -:108EA00000000000000000000000000000000000C2 -:108EB00000000000000000000000000000000000B2 -:108EC00000000000000000000000000000000000A2 -:108ED0000000000000000000000000000000000092 -:108EE0000000000000000000000000000000000082 -:108EF0000000000000000000000000000000000072 -:108F00000000000000000000000000000000000061 -:108F10000000000000000000000000000000000051 -:108F20000000000000000000000000000000000041 -:108F30000000000000000000000000000000000031 -:108F40000000000000000000000000000000000021 -:108F50000000000000000000000000000000000011 -:108F60000000000000000000000000000000000001 -:108F700000000000000000000000000000000000F1 -:108F800000000000000000000000000000000000E1 -:108F900000000000000000000000000000000000D1 -:108FA00000000000000000000000000000000000C1 -:108FB00000000000000000000000000000000000B1 -:108FC00000000000000000000000000000000000A1 -:108FD0000000000000000000000000000000000091 -:108FE0000000000000000000000000000000000081 -:108FF0000000000000000000000000000000000071 -:109000000000000000000000000000000000000060 -:109010000000000000000000000000000000000050 -:109020000000000000000000000000000000000040 -:109030000000000000000000000000000000000030 -:109040000000000000000000000000000000000020 -:109050000000000000000000000000000000000010 -:109060000000000000000000000000000000000000 -:1090700000000000000000000000000000000000F0 -:1090800000000000000000000000000000000000E0 -:1090900000000000000000000000000000000000D0 -:1090A00000000000000000000000000000000000C0 -:1090B00000000000000000000000000000000000B0 -:1090C00000000000000000000000000000000000A0 -:1090D0000000000000000000000000000000000090 -:1090E0000000000000000000000000000000000080 -:1090F0000000000000000000000000000000000070 -:10910000000000000000000000000000000000005F -:10911000000000000000000000000000000000004F -:10912000000000000000000000000000000000003F -:10913000000000000000000000000000000000002F -:10914000000000000000000000000000000000001F -:10915000000000000000000000000000000000000F -:1091600000000000000000000000000000000000FF -:1091700000000000000000000000000000000000EF -:1091800000000000000000000000000000000000DF -:1091900000000000000000000000000000000000CF -:1091A00000000000000000000000000000000000BF -:1091B00000000000000000000000000000000000AF -:1091C000000000000000000000000000000000009F -:1091D000000000000000000000000000000000008F -:1091E000000000000000000000000000000000007F -:1091F000000000000000000000000000000000006F -:10920000000000000000000000000000000000005E -:10921000000000000000000000000000000000004E -:10922000000000000000000000000000000000003E -:10923000000000000000000000000000000000002E -:10924000000000000000000000000000000000001E -:10925000000000000000000000000000000000000E -:1092600000000000000000000000000000000000FE -:1092700000000000000000000000000000000000EE -:1092800000000000000000000000000000000000DE -:1092900000000000000000000000000000000000CE -:1092A00000000000000000000000000000000000BE -:1092B00000000000000000000000000000000000AE -:1092C000000000000000000000000000000000009E -:1092D000000000000000000000000000000000008E -:1092E000000000000000000000000000000000007E -:1092F000000000000000000000000000000000006E -:10930000000000000000000000000000000000005D -:10931000000000000000000000000000000000004D -:10932000000000000000000000000000000000003D -:10933000000000000000000000000000000000002D -:10934000000000000000000000000000000000001D -:10935000000000000000000000000000000000000D -:1093600000000000000000000000000000000000FD -:1093700000000000000000000000000000000000ED -:1093800000000000000000000000000000000000DD -:1093900000000000000000000000000000000000CD -:1093A00000000000000000000000000000000000BD -:1093B00000000000000000000000000000000000AD -:1093C000000000000000000000000000000000009D -:1093D000000000000000000000000000000000008D -:1093E000000000000000000000000000000000007D -:1093F000000000000000000000000000000000006D -:10940000000000000000000000000000000000005C -:10941000000000000000000000000000000000004C -:10942000000000000000000000000000000000003C -:10943000000000000000000000000000000000002C -:10944000000000000000000000000000000000001C -:10945000000000000000000000000000000000000C -:1094600000000000000000000000000000000000FC -:1094700000000000000000000000000000000000EC -:1094800000000000000000000000000000000000DC -:1094900000000000000000000000000000000000CC -:1094A00000000000000000000000000000000000BC -:1094B00000000000000000000000000000000000AC -:1094C000000000000000000000000000000000009C -:1094D000000000000000000000000000000000008C -:1094E000000000000000000000000000000000007C -:1094F000000000000000000000000000000000006C -:10950000000000000000000000000000000000005B -:10951000000000000000000000000000000000004B -:10952000000000000000000000000000000000003B -:10953000000000000000000000000000000000002B -:10954000000000000000000000000000000000001B -:10955000000000000000000000000000000000000B -:1095600000000000000000000000000000000000FB -:1095700000000000000000000000000000000000EB -:1095800000000000000000000000000000000000DB -:1095900000000000000000000000000000000000CB -:1095A00000000000000000000000000000000000BB -:1095B00000000000000000000000000000000000AB -:1095C000000000000000000000000000000000009B -:1095D000000000000000000000000000000000008B -:1095E000000000000000000000000000000000007B -:1095F000000000000000000000000000000000006B -:10960000000000000000000000000000000000005A -:10961000000000000000000000000000000000004A -:10962000000000000000000000000000000000003A -:10963000000000000000000000000000000000002A -:10964000000000000000000000000000000000001A -:10965000000000000000000000000000000000000A -:1096600000000000000000000000000000000000FA -:1096700000000000000000000000000000000000EA -:1096800000000000000000000000000000000000DA -:1096900000000000000000000000000000000000CA -:1096A00000000000000000000000000000000000BA -:1096B00000000000000000000000000000000000AA -:1096C000000000000000000000000000000000009A -:1096D000000000000000000000000000000000008A -:1096E000000000000000000000000000000000007A -:1096F000000000000000000000000000000000006A -:109700000000000000000000000000000000000059 -:109710000000000000000000000000000000000049 -:109720000000000000000000000000000000000039 -:109730000000000000000000000000000000000029 -:109740000000000000000000000000000000000019 -:109750000000000000000000000000000000000009 -:1097600000000000000000000000000000000000F9 -:1097700000000000000000000000000000000000E9 -:1097800000000000000000000000000000000000D9 -:1097900000000000000000000000000000000000C9 -:1097A00000000000000000000000000000000000B9 -:1097B00000000000000000000000000000000000A9 -:1097C0000000000000000000000000000000000099 -:1097D0000000000000000000000000000000000089 -:1097E0000000000000000000000000000000000079 -:1097F0000000000000000000000000000000000069 -:109800000000000000000000000000000000000058 -:109810000000000000000000000000000000000048 -:109820000000000000000000000000000000000038 -:109830000000000000000000000000000000000028 -:109840000000000000000000000000000000000018 -:109850000000000000000000000000000000000008 -:1098600000000000000000000000000000000000F8 -:1098700000000000000000000000000000000000E8 -:1098800000000000000000000000000000000000D8 -:1098900000000000000000000000000000000000C8 -:1098A00000000000000000000000000000000000B8 -:1098B00000000000000000000000000000000000A8 -:1098C0000000000000000000000000000000000098 -:1098D0000000000000000000000000000000000088 -:1098E0000000000000000000000000000000000078 -:1098F0000000000000000000000000000000000068 -:109900000000000000000000000000000000000057 -:109910000000000000000000000000000000000047 -:109920000000000000000000000000000000000037 -:109930000000000000000000000000000000000027 -:109940000000000000000000000000000000000017 -:109950000000000000000000000000000000000007 -:1099600000000000000000000000000000000000F7 -:1099700000000000000000000000000000000000E7 -:1099800000000000000000000000000000000000D7 -:1099900000000000000000000000000000000000C7 -:1099A00000000000000000000000000000000000B7 -:1099B00000000000000000000000000000000000A7 -:1099C0000000000000000000000000000000000097 -:1099D0000000000000000000000000000000000087 -:1099E0000000000000000000000000000000000077 -:1099F0000000000000000000000000000000000067 -:109A00000000000000000000000000000000000056 -:109A10000000000000000000000000000000000046 -:109A20000000000000000000000000000000000036 -:109A30000000000000000000000000000000000026 -:109A40000000000000000000000000000000000016 -:109A50000000000000000000000000000000000006 -:109A600000000000000000000000000000000000F6 -:109A700000000000000000000000000000000000E6 -:109A800000000000000000000000000000000000D6 -:109A900000000000000000000000000000000000C6 -:109AA00000000000000000000000000000000000B6 -:109AB00000000000000000000000000000000000A6 -:109AC0000000000000000000000000000000000096 -:109AD0000000000000000000000000000000000086 -:109AE0000000000000000000000000000000000076 -:109AF0000000000000000000000000000000000066 -:109B00000000000000000000000000000000000055 -:109B10000000000000000000000000000000000045 -:109B20000000000000000000000000000000000035 -:109B30000000000000000000000000000000000025 -:109B40000000000000000000000000000000000015 -:109B50000000000000000000000000000000000005 -:109B600000000000000000000000000000000000F5 -:109B700000000000000000000000000000000000E5 -:109B800000000000000000000000000000000000D5 -:109B900000000000000000000000000000000000C5 -:109BA00000000000000000000000000000000000B5 -:109BB00000000000000000000000000000000000A5 -:109BC0000000000000000000000000000000000095 -:109BD0000000000000000000000000000000000085 -:109BE0000000000000000000000000000000000075 -:109BF0000000000000000000000000000000000065 -:109C00000000000000000000000000000000000054 -:109C10000000000000000000000000000000000044 -:109C20000000000000000000000000000000000034 -:109C30000000000000000000000000000000000024 -:109C40000000000000000000000000000000000014 -:109C50000000000000000000000000000000000004 -:109C600000000000000000000000000000000000F4 -:109C700000000000000000000000000000000000E4 -:109C800000000000000000000000000000000000D4 -:109C900000000000000000000000000000000000C4 -:109CA00000000000000000000000000000000000B4 -:109CB00000000000000000000000000000000000A4 -:109CC0000000000000000000000000000000000094 -:109CD0000000000000000000000000000000000084 -:109CE0000000000000000000000000000000000074 -:109CF0000000000000000000000000000000000064 -:109D00000000000000000000000000000000000053 -:109D10000000000000000000000000000000000043 -:109D20000000000000000000000000000000000033 -:109D30000000000000000000000000000000000023 -:109D40000000000000000000000000000000000013 -:109D50000000000000000000000000000000000003 -:109D600000000000000000000000000000000000F3 -:109D700000000000000000000000000000000000E3 -:109D800000000000000000000000000000000000D3 -:109D900000000000000000000000000000000000C3 -:109DA00000000000000000000000000000000000B3 -:109DB00000000000000000000000000000000000A3 -:109DC0000000000000000000000000000000000093 -:109DD0000000000000000000000000000000000083 -:109DE0000000000000000000000000000000000073 -:109DF0000000000000000000000000000000000063 -:109E00000000000000000000000000000000000052 -:109E10000000000000000000000000000000000042 -:109E20000000000000000000000000000000000032 -:109E30000000000000000000000000000000000022 -:109E40000000000000000000000000000000000012 -:109E50000000000000000000000000000000000002 -:109E600000000000000000000000000000000000F2 -:109E700000000000000000000000000000000000E2 -:109E800000000000000000000000000000000000D2 -:109E900000000000000000000000000000000000C2 -:109EA00000000000000000000000000000000000B2 -:109EB00000000000000000000000000000000000A2 -:109EC0000000000000000000000000000000000092 -:109ED0000000000000000000000000000000000082 -:109EE0000000000000000000000000000000000072 -:109EF0000000000000000000000000000000000062 -:109F00000000000000000000000000000000000051 -:109F10000000000000000000000000000000000041 -:109F20000000000000000000000000000000000031 -:109F30000000000000000000000000000000000021 -:109F40000000000000000000000000000000000011 -:109F50000000000000000000000000000000000001 -:109F600000000000000000000000000000000000F1 -:109F700000000000000000000000000000000000E1 -:109F800000000000000000000000000000000000D1 -:109F900000000000000000000000000000000000C1 -:109FA00000000000000000000000000000000000B1 -:109FB00000000000000000000000000000000000A1 -:109FC0000000000000000000000000000000000091 -:109FD0000000000000000000000000000000000081 -:109FE0000000000000000000000000000000000071 -:109FF0000000000000000000000000000000000061 -:10A000000000000000000000000000000000000050 -:10A010000000000000000000000000000000000040 -:10A020000000000000000000000000000000000030 -:10A030000000000000000000000000000000000020 -:10A040000000000000000000000000000000000010 -:10A050000000000000000000000000000000000000 -:10A0600000000000000000000000000000000000F0 -:10A0700000000000000000000000000000000000E0 -:10A0800000000000000000000000000000000000D0 -:10A0900000000000000000000000000000000000C0 -:10A0A00000000000000000000000000000000000B0 -:10A0B00000000000000000000000000000000000A0 -:10A0C0000000000000000000000000000000000090 -:10A0D0000000000000000000000000000000000080 -:10A0E0000000000000000000000000000000000070 -:10A0F0000000000000000000000000000000000060 -:10A10000000000000000000000000000000000004F -:10A11000000000000000000000000000000000003F -:10A12000000000000000000000000000000000002F -:10A13000000000000000000000000000000000001F -:10A14000000000000000000000000000000000000F -:10A1500000000000000000000000000000000000FF -:10A1600000000000000000000000000000000000EF -:10A1700000000000000000000000000000000000DF -:10A1800000000000000000000000000000000000CF -:10A1900000000000000000000000000000000000BF -:10A1A00000000000000000000000000000000000AF -:10A1B000000000000000000000000000000000009F -:10A1C000000000000000000000000000000000008F -:10A1D000000000000000000000000000000000007F -:10A1E000000000000000000000000000000000006F -:10A1F000000000000000000000000000000000005F -:10A20000000000000000000000000000000000004E -:10A21000000000000000000000000000000000003E -:10A22000000000000000000000000000000000002E -:10A23000000000000000000000000000000000001E -:10A24000000000000000000000000000000000000E -:10A2500000000000000000000000000000000000FE -:10A2600000000000000000000000000000000000EE -:10A2700000000000000000000000000000000000DE -:10A2800000000000000000000000000000000000CE -:10A2900000000000000000000000000000000000BE -:10A2A00000000000000000000000000000000000AE -:10A2B000000000000000000000000000000000009E -:10A2C000000000000000000000000000000000008E -:10A2D000000000000000000000000000000000007E -:10A2E000000000000000000000000000000000006E -:10A2F000000000000000000000000000000000005E -:10A30000000000000000000000000000000000004D -:10A31000000000000000000000000000000000003D -:10A32000000000000000000000000000000000002D -:10A33000000000000000000000000000000000001D -:10A34000000000000000000000000000000000000D -:10A3500000000000000000000000000000000000FD -:10A3600000000000000000000000000000000000ED -:10A3700000000000000000000000000000000000DD -:10A3800000000000000000000000000000000000CD -:10A3900000000000000000000000000000000000BD -:10A3A00000000000000000000000000000000000AD -:10A3B000000000000000000000000000000000009D -:10A3C000000000000000000000000000000000008D -:10A3D000000000000000000000000000000000007D -:10A3E000000000000000000000000000000000006D -:10A3F000000000000000000000000000000000005D -:10A40000000000000000000000000000000000004C -:10A41000000000000000000000000000000000003C -:10A42000000000000000000000000000000000002C -:10A43000000000000000000000000000000000001C -:10A44000000000000000000000000000000000000C -:10A4500000000000000000000000000000000000FC -:10A4600000000000000000000000000000000000EC -:10A4700000000000000000000000000000000000DC -:10A4800000000000000000000000000000000000CC -:10A4900000000000000000000000000000000000BC -:10A4A00000000000000000000000000000000000AC -:10A4B000000000000000000000000000000000009C -:10A4C000000000000000000000000000000000008C -:10A4D000000000000000000000000000000000007C -:10A4E000000000000000000000000000000000006C -:10A4F000000000000000000000000000000000005C -:10A50000000000000000000000000000000000004B -:10A51000000000000000000000000000000000003B -:10A52000000000000000000000000000000000002B -:10A53000000000000000000000000000000000001B -:10A54000000000000000000000000000000000000B -:10A5500000000000000000000000000000000000FB -:10A5600000000000000000000000000000000000EB -:10A5700000000000000000000000000000000000DB -:10A5800000000000000000000000000000000000CB -:10A5900000000000000000000000000000000000BB -:10A5A00000000000000000000000000000000000AB -:10A5B000000000000000000000000000000000009B -:10A5C000000000000000000000000000000000008B -:10A5D000000000000000000000000000000000007B -:10A5E000000000000000000000000000000000006B -:10A5F000000000000000000000000000000000005B -:10A60000000000000000000000000000000000004A -:10A61000000000000000000000000000000000003A -:10A62000000000000000000000000000000000002A -:10A63000000000000000000000000000000000001A -:10A64000000000000000000000000000000000000A -:10A6500000000000000000000000000000000000FA -:10A6600000000000000000000000000000000000EA -:10A6700000000000000000000000000000000000DA -:10A6800000000000000000000000000000000000CA -:10A6900000000000000000000000000000000000BA -:10A6A00000000000000000000000000000000000AA -:10A6B000000000000000000000000000000000009A -:10A6C000000000000000000000000000000000008A -:10A6D000000000000000000000000000000000007A -:10A6E000000000000000000000000000000000006A -:10A6F000000000000000000000000000000000005A -:10A700000000000000000000000000000000000049 -:10A710000000000000000000000000000000000039 -:10A720000000000000000000000000000000000029 -:10A730000000000000000000000000000000000019 -:10A740000000000000000000000000000000000009 -:10A7500000000000000000000000000000000000F9 -:10A7600000000000000000000000000000000000E9 -:10A7700000000000000000000000000000000000D9 -:10A7800000000000000000000000000000000000C9 -:10A7900000000000000000000000000000000000B9 -:10A7A00000000000000000000000000000000000A9 -:10A7B0000000000000000000000000000000000099 -:10A7C0000000000000000000000000000000000089 -:10A7D0000000000000000000000000000000000079 -:10A7E0000000000000000000000000000000000069 -:10A7F0000000000000000000000000000000000059 -:10A800000000000000000000000000000000000048 -:10A810000000000000000000000000000000000038 -:10A820000000000000000000000000000000000028 -:10A830000000000000000000000000000000000018 -:10A840000000000000000000000000000000000008 -:10A8500000000000000000000000000000000000F8 -:10A8600000000000000000000000000000000000E8 -:10A8700000000000000000000000000000000000D8 -:10A8800000000000000000000000000000000000C8 -:10A8900000000000000000000000000000000000B8 -:10A8A00000000000000000000000000000000000A8 -:10A8B0000000000000000000000000000000000098 -:10A8C0000000000000000000000000000000000088 -:10A8D0000000000000000000000000000000000078 -:10A8E0000000000000000000000000000000000068 -:10A8F0000000000000000000000000000000000058 -:10A900000000000000000000000000000000000047 -:10A910000000000000000000000000000000000037 -:10A920000000000000000000000000000000000027 -:10A930000000000000000000000000000000000017 -:10A940000000000000000000000000000000000007 -:10A9500000000000000000000000000000000000F7 -:10A9600000000000000000000000000000000000E7 -:10A9700000000000000000000000000000000000D7 -:10A9800000000000000000000000000000000000C7 -:10A9900000000000000000000000000000000000B7 -:10A9A00000000000000000000000000000000000A7 -:10A9B0000000000000000000000000000000000097 -:10A9C0000000000000000000000000000000000087 -:10A9D0000000000000000000000000000000000077 -:10A9E0000000000000000000000000000000000067 -:10A9F0000000000000000000000000000000000057 -:10AA00000000000000000000000000000000000046 -:10AA10000000000000000000000000000000000036 -:10AA20000000000000000000000000000000000026 -:10AA30000000000000000000000000000000000016 -:10AA40000000000000000000000000000000000006 -:10AA500000000000000000000000000000000000F6 -:10AA600000000000000000000000000000000000E6 -:10AA700000000000000000000000000000000000D6 -:10AA800000000000000000000000000000000000C6 -:10AA900000000000000000000000000000000000B6 -:10AAA00000000000000000000000000000000000A6 -:10AAB0000000000000000000000000000000000096 -:10AAC0000000000000000000000000000000000086 -:10AAD0000000000000000000000000000000000076 -:10AAE0000000000000000000000000000000000066 -:10AAF0000000000000000000000000000000000056 -:10AB00000000000000000000000000000000000045 -:10AB10000000000000000000000000000000000035 -:10AB20000000000000000000000000000000000025 -:10AB30000000000000000000000000000000000015 -:10AB40000000000000000000000000000000000005 -:10AB500000000000000000000000000000000000F5 -:10AB600000000000000000000000000000000000E5 -:10AB700000000000000000000000000000000000D5 -:10AB800000000000000000000000000000000000C5 -:10AB900000000000000000000000000000000000B5 -:10ABA00000000000000000000000000000000000A5 -:10ABB0000000000000000000000000000000000095 -:10ABC0000000000000000000000000000000000085 -:10ABD0000000000000000000000000000000000075 -:10ABE0000000000000000000000000000000000065 -:10ABF0000000000000000000000000000000000055 -:10AC00000000000000000000000000000000000044 -:10AC10000000000000000000000000000000000034 -:10AC20000000000000000000000000000000000024 -:10AC30000000000000000000000000000000000014 -:10AC40000000000000000000000000000000000004 -:10AC500000000000000000000000000000000000F4 -:10AC600000000000000000000000000000000000E4 -:10AC700000000000000000000000000000000000D4 -:10AC800000000000000000000000000000000000C4 -:10AC900000000000000000000000000000000000B4 -:10ACA00000000000000000000000000000000000A4 -:10ACB0000000000000000000000000000000000094 -:10ACC0000000000000000000000000000000000084 -:10ACD0000000000000000000000000000000000074 -:10ACE0000000000000000000000000000000000064 -:10ACF0000000000000000000000000000000000054 -:10AD00000000000000000000000000000000000043 -:10AD10000000000000000000000000000000000033 -:10AD20000000000000000000000000000000000023 -:10AD30000000000000000000000000000000000013 -:10AD40000000000000000000000000000000000003 -:10AD500000000000000000000000000000000000F3 -:10AD600000000000000000000000000000000000E3 -:10AD700000000000000000000000000000000000D3 -:10AD800000000000000000000000000000000000C3 -:10AD900000000000000000000000000000000000B3 -:10ADA00000000000000000000000000000000000A3 -:10ADB0000000000000000000000000000000000093 -:10ADC0000000000000000000000000000000000083 -:10ADD0000000000000000000000000000000000073 -:10ADE0000000000000000000000000000000000063 -:10ADF0000000000000000000000000000000000053 -:10AE00000000000000000000000000000000000042 -:10AE10000000000000000000000000000000000032 -:10AE20000000000000000000000000000000000022 -:10AE30000000000000000000000000000000000012 -:10AE40000000000000000000000000000000000002 -:10AE500000000000000000000000000000000000F2 -:10AE600000000000000000000000000000000000E2 -:10AE700000000000000000000000000000000000D2 -:10AE800000000000000000000000000000000000C2 -:10AE900000000000000000000000000000000000B2 -:10AEA00000000000000000000000000000000000A2 -:10AEB0000000000000000000000000000000000092 -:10AEC0000000000000000000000000000000000082 -:10AED0000000000000000000000000000000000072 -:10AEE0000000000000000000000000000000000062 -:10AEF0000000000000000000000000000000000052 -:10AF00000000000000000000000000000000000041 -:10AF10000000000000000000000000000000000031 -:10AF20000000000000000000000000000000000021 -:10AF30000000000000000000000000000000000011 -:10AF40000000000000000000000000000000000001 -:10AF500000000000000000000000000000000000F1 -:10AF600000000000000000000000000000000000E1 -:10AF700000000000000000000000000000000000D1 -:10AF800000000000000000000000000000000000C1 -:10AF900000000000000000000000000000000000B1 -:10AFA00000000000000000000000000000000000A1 -:10AFB0000000000000000000000000000000000091 -:10AFC0000000000000000000000000000000000081 -:10AFD0000000000000000000000000000000000071 -:10AFE0000000000000000000000000000000000061 -:10AFF0000000000000000000000000000000000051 -:10B000000000000000000000000000000000000040 -:10B010000000000000000000000000000000000030 -:10B020000000000000000000000000000000000020 -:10B030000000000000000000000000000000000010 -:10B040000000000000000000000000000000000000 -:10B0500000000000000000000000000000000000F0 -:10B0600000000000000000000000000000000000E0 -:10B0700000000000000000000000000000000000D0 -:10B0800000000000000000000000000000000000C0 -:10B0900000000000000000000000000000000000B0 -:10B0A00000000000000000000000000000000000A0 -:10B0B0000000000000000000000000000000000090 -:10B0C0000000000000000000000000000000000080 -:10B0D0000000000000000000000000000000000070 -:10B0E0000000000000000000000000000000000060 -:10B0F0000000000000000000000000000000000050 -:10B10000000000000000000000000000000000003F -:10B11000000000000000000000000000000000002F -:10B12000000000000000000000000000000000001F -:10B13000000000000000000000000000000000000F -:10B1400000000000000000000000000000000000FF -:10B1500000000000000000000000000000000000EF -:10B1600000000000000000000000000000000000DF -:10B1700000000000000000000000000000000000CF -:10B1800000000000000000000000000000000000BF -:10B1900000000000000000000000000000000000AF -:10B1A000000000000000000000000000000000009F -:10B1B000000000000000000000000000000000008F -:10B1C000000000000000000000000000000000007F -:10B1D000000000000000000000000000000000006F -:10B1E000000000000000000000000000000000005F -:10B1F000000000000000000000000000000000004F -:10B20000000000000000000000000000000000003E -:10B21000000000000000000000000000000000002E -:10B22000000000000000000000000000000000001E -:10B23000000000000000000000000000000000000E -:10B2400000000000000000000000000000000000FE -:10B2500000000000000000000000000000000000EE -:10B2600000000000000000000000000000000000DE -:10B2700000000000000000000000000000000000CE -:10B2800000000000000000000000000000000000BE -:10B2900000000000000000000000000000000000AE -:10B2A000000000000000000000000000000000009E -:10B2B000000000000000000000000000000000008E -:10B2C000000000000000000000000000000000007E -:10B2D000000000000000000000000000000000006E -:10B2E000000000000000000000000000000000005E -:10B2F000000000000000000000000000000000004E -:10B30000000000000000000000000000000000003D -:10B31000000000000000000000000000000000002D -:10B32000000000000000000000000000000000001D -:10B33000000000000000000000000000000000000D -:10B3400000000000000000000000000000000000FD -:10B3500000000000000000000000000000000000ED -:10B3600000000000000000000000000000000000DD -:10B3700000000000000000000000000000000000CD -:10B3800000000000000000000000000000000000BD -:10B3900000000000000000000000000000000000AD -:10B3A000000000000000000000000000000000009D -:10B3B000000000000000000000000000000000008D -:10B3C000000000000000000000000000000000007D -:10B3D000000000000000000000000000000000006D -:10B3E000000000000000000000000000000000005D -:10B3F000000000000000000000000000000000004D -:10B40000000000000000000000000000000000003C -:10B41000000000000000000000000000000000002C -:10B42000000000000000000000000000000000001C -:10B43000000000000000000000000000000000000C -:10B4400000000000000000000000000000000000FC -:10B4500000000000000000000000000000000000EC -:10B4600000000000000000000000000000000000DC -:10B4700000000000000000000000000000000000CC -:10B4800000000000000000000000000000000000BC -:10B4900000000000000000000000000000000000AC -:10B4A000000000000000000000000000000000009C -:10B4B000000000000000000000000000000000008C -:10B4C000000000000000000000000000000000007C -:10B4D000000000000000000000000000000000006C -:10B4E000000000000000000000000000000000005C -:10B4F000000000000000000000000000000000004C -:10B50000000000000000000000000000000000003B -:10B51000000000000000000000000000000000002B -:10B52000000000000000000000000000000000001B -:10B53000000000000000000000000000000000000B -:10B5400000000000000000000000000000000000FB -:10B5500000000000000000000000000000000000EB -:10B5600000000000000000000000000000000000DB -:10B5700000000000000000000000000000000000CB -:10B5800000000000000000000000000000000000BB -:10B5900000000000000000000000000000000000AB -:10B5A000000000000000000000000000000000009B -:10B5B000000000000000000000000000000000008B -:10B5C000000000000000000000000000000000007B -:10B5D000000000000000000000000000000000006B -:10B5E000000000000000000000000000000000005B -:10B5F000000000000000000000000000000000004B -:10B60000000000000000000000000000000000003A -:10B61000000000000000000000000000000000002A -:10B62000000000000000000000000000000000001A -:10B63000000000000000000000000000000000000A -:10B6400000000000000000000000000000000000FA -:10B6500000000000000000000000000000000000EA -:10B6600000000000000000000000000000000000DA -:10B6700000000000000000000000000000000000CA -:10B6800000000000000000000000000000000000BA -:10B6900000000000000000000000000000000000AA -:10B6A000000000000000000000000000000000009A -:10B6B000000000000000000000000000000000008A -:10B6C000000000000000000000000000000000007A -:10B6D000000000000000000000000000000000006A -:10B6E000000000000000000000000000000000005A -:10B6F000000000000000000000000000000000004A -:10B700000000000000000000000000000000000039 -:10B710000000000000000000000000000000000029 -:10B720000000000000000000000000000000000019 -:10B730000000000000000000000000000000000009 -:10B7400000000000000000000000000000000000F9 -:10B7500000000000000000000000000000000000E9 -:10B7600000000000000000000000000000000000D9 -:10B7700000000000000000000000000000000000C9 -:10B7800000000000000000000000000000000000B9 -:10B7900000000000000000000000000000000000A9 -:10B7A0000000000000000000000000000000000099 -:10B7B0000000000000000000000000000000000089 -:10B7C0000000000000000000000000000000000079 -:10B7D0000000000000000000000000000000000069 -:10B7E0000000000000000000000000000000000059 -:10B7F0000000000000000000000000000000000049 -:10B800000000000000000000000000000000000038 -:10B810000000000000000000000000000000000028 -:10B820000000000000000000000000000000000018 -:10B830000000000000000000000000000000000008 -:10B8400000000000000000000000000000000000F8 -:10B8500000000000000000000000000000000000E8 -:10B8600000000000000000000000000000000000D8 -:10B8700000000000000000000000000000000000C8 -:10B8800000000000000000000000000000000000B8 -:10B8900000000000000000000000000000000000A8 -:10B8A0000000000000000000000000000000000098 -:10B8B0000000000000000000000000000000000088 -:10B8C0000000000000000000000000000000000078 -:10B8D0000000000000000000000000000000000068 -:10B8E0000000000000000000000000000000000058 -:10B8F0000000000000000000000000000000000048 -:10B900000000000000000000000000000000000037 -:10B910000000000000000000000000000000000027 -:10B920000000000000000000000000000000000017 -:10B930000000000000000000000000000000000007 -:10B9400000000000000000000000000000000000F7 -:10B9500000000000000000000000000000000000E7 -:10B9600000000000000000000000000000000000D7 -:10B9700000000000000000000000000000000000C7 -:10B9800000000000000000000000000000000000B7 -:10B9900000000000000000000000000000000000A7 -:10B9A0000000000000000000000000000000000097 -:10B9B0000000000000000000000000000000000087 -:10B9C0000000000000000000000000000000000077 -:10B9D0000000000000000000000000000000000067 -:10B9E0000000000000000000000000000000000057 -:10B9F0000000000000000000000000000000000047 -:10BA00000000000000000000000000000000000036 -:10BA10000000000000000000000000000000000026 -:10BA20000000000000000000000000000000000016 -:10BA30000000000000000000000000000000000006 -:10BA400000000000000000000000000000000000F6 -:10BA500000000000000000000000000000000000E6 -:10BA600000000000000000000000000000000000D6 -:10BA700000000000000000000000000000000000C6 -:10BA800000000000000000000000000000000000B6 -:10BA900000000000000000000000000000000000A6 -:10BAA0000000000000000000000000000000000096 -:10BAB0000000000000000000000000000000000086 -:10BAC0000000000000000000000000000000000076 -:10BAD0000000000000000000000000000000000066 -:10BAE0000000000000000000000000000000000056 -:10BAF0000000000000000000000000000000000046 -:10BB00000000000000000000000000000000000035 -:10BB10000000000000000000000000000000000025 -:10BB20000000000000000000000000000000000015 -:10BB30000000000000000000000000000000000005 -:10BB400000000000000000000000000000000000F5 -:10BB500000000000000000000000000000000000E5 -:10BB600000000000000000000000000000000000D5 -:10BB700000000000000000000000000000000000C5 -:10BB800000000000000000000000000000000000B5 -:10BB900000000000000000000000000000000000A5 -:10BBA0000000000000000000000000000000000095 -:10BBB0000000000000000000000000000000000085 -:10BBC0000000000000000000000000000000000075 -:10BBD0000000000000000000000000000000000065 -:10BBE0000000000000000000000000000000000055 -:10BBF0000000000000000000000000000000000045 -:10BC00000000000000000000000000000000000034 -:10BC10000000000000000000000000000000000024 -:10BC20000000000000000000000000000000000014 -:10BC30000000000000000000000000000000000004 -:10BC400000000000000000000000000000000000F4 -:10BC500000000000000000000000000000000000E4 -:10BC600000000000000000000000000000000000D4 -:10BC700000000000000000000000000000000000C4 -:10BC800000000000000000000000000000000000B4 -:10BC900000000000000000000000000000000000A4 -:10BCA0000000000000000000000000000000000094 -:10BCB0000000000000000000000000000000000084 -:10BCC0000000000000000000000000000000000074 -:10BCD0000000000000000000000000000000000064 -:10BCE0000000000000000000000000000000000054 -:10BCF0000000000000000000000000000000000044 -:10BD00000000000000000000000000000000000033 -:10BD10000000000000000000000000000000000023 -:10BD20000000000000000000000000000000000013 -:10BD30000000000000000000000000000000000003 -:10BD400000000000000000000000000000000000F3 -:10BD500000000000000000000000000000000000E3 -:10BD600000000000000000000000000000000000D3 -:10BD700000000000000000000000000000000000C3 -:10BD800000000000000000000000000000000000B3 -:10BD900000000000000000000000000000000000A3 -:10BDA0000000000000000000000000000000000093 -:10BDB0000000000000000000000000000000000083 -:10BDC0000000000000000000000000000000000073 -:10BDD0000000000000000000000000000000000063 -:10BDE0000000000000000000000000000000000053 -:10BDF0000000000000000000000000000000000043 -:10BE00000000000000000000000000000000000032 -:10BE10000000000000000000000000000000000022 -:10BE20000000000000000000000000000000000012 -:10BE30000000000000000000000000000000000002 -:10BE400000000000000000000000000000000000F2 -:10BE500000000000000000000000000000000000E2 -:10BE600000000000000000000000000000000000D2 -:10BE700000000000000000000000000000000000C2 -:10BE800000000000000000000000000000000000B2 -:10BE900000000000000000000000000000000000A2 -:10BEA0000000000000000000000000000000000092 -:10BEB0000000000000000000000000000000000082 -:10BEC0000000000000000000000000000000000072 -:10BED0000000000000000000000000000000000062 -:10BEE0000000000000000000000000000000000052 -:10BEF0000000000000000000000000000000000042 -:10BF00000000000000000000000000000000000031 -:10BF10000000000000000000000000000000000021 -:10BF20000000000000000000000000000000000011 -:10BF30000000000000000000000000000000000001 -:10BF400000000000000000000000000000000000F1 -:10BF500000000000000000000000000000000000E1 -:10BF600000000000000000000000000000000000D1 -:10BF700000000000000000000000000000000000C1 -:10BF800000000000000000000000000000000000B1 -:10BF900000000000000000000000000000000000A1 -:10BFA0000000000000000000000000000000000091 -:10BFB0000000000000000000000000000000000081 -:10BFC0000000000000000000000000000000000071 -:10BFD0000000000000000000000000000000000061 -:10BFE0000000000000000000000000000000000051 -:10BFF0000000000000000000000000000000000041 -:10C000000000000000000000000000000000000030 -:10C010000000000000000000000000000000000020 -:10C020000000000000000000000000000000000010 -:10C030000000000000000000000000000000000000 -:10C0400000000000000000000000000000000000F0 -:10C0500000000000000000000000000000000000E0 -:10C0600000000000000000000000000000000000D0 -:10C0700000000000000000000000000000000000C0 -:10C0800000000000000000000000000000000000B0 -:10C0900000000000000000000000000000000000A0 -:10C0A0000000000000000000000000000000000090 -:10C0B0000000000000000000000000000000000080 -:10C0C0000000000000000000000000000000000070 -:10C0D0000000000000000000000000000000000060 -:10C0E0000000000000000000000000000000000050 -:10C0F0000000000000000000000000000000000040 -:10C10000000000000000000000000000000000002F -:10C11000000000000000000000000000000000001F -:10C12000000000000000000000000000000000000F -:10C1300000000000000000000000000000000000FF -:10C1400000000000000000000000000000000000EF -:10C1500000000000000000000000000000000000DF -:10C1600000000000000000000000000000000000CF -:10C1700000000000000000000000000000000000BF -:10C1800000000000000000000000000000000000AF -:10C19000000000000000000000000000000000009F -:10C1A000000000000000000000000000000000008F -:10C1B000000000000000000000000000000000007F -:10C1C000000000000000000000000000000000006F -:10C1D000000000000000000000000000000000005F -:10C1E000000000000000000000000000000000004F -:10C1F000000000000000000000000000000000003F -:10C20000000000000000000000000000000000002E -:10C21000000000000000000000000000000000001E -:10C22000000000000000000000000000000000000E -:10C2300000000000000000000000000000000000FE -:10C2400000000000000000000000000000000000EE -:10C2500000000000000000000000000000000000DE -:10C2600000000000000000000000000000000000CE -:10C2700000000000000000000000000000000000BE -:10C2800000000000000000000000000000000000AE -:10C29000000000000000000000000000000000009E -:10C2A000000000000000000000000000000000008E -:10C2B000000000000000000000000000000000007E -:10C2C000000000000000000000000000000000006E -:10C2D000000000000000000000000000000000005E -:10C2E000000000000000000000000000000000004E -:10C2F000000000000000000000000000000000003E -:10C30000000000000000000000000000000000002D -:10C31000000000000000000000000000000000001D -:10C32000000000000000000000000000000000000D -:10C3300000000000000000000000000000000000FD -:10C3400000000000000000000000000000000000ED -:10C3500000000000000000000000000000000000DD -:10C3600000000000000000000000000000000000CD -:10C3700000000000000000000000000000000000BD -:10C3800000000000000000000000000000000000AD -:10C39000000000000000000000000000000000009D -:10C3A000000000000000000000000000000000008D -:10C3B000000000000000000000000000000000007D -:10C3C000000000000000000000000000000000006D -:10C3D000000000000000000000000000000000005D -:10C3E000000000000000000000000000000000004D -:10C3F000000000000000000000000000000000003D -:10C40000000000000000000000000000000000002C -:10C41000000000000000000000000000000000001C -:10C42000000000000000000000000000000000000C -:10C4300000000000000000000000000000000000FC -:10C4400000000000000000000000000000000000EC -:10C4500000000000000000000000000000000000DC -:10C4600000000000000000000000000000000000CC -:10C4700000000000000000000000000000000000BC -:10C4800000000000000000000000000000000000AC -:10C49000000000000000000000000000000000009C -:10C4A000000000000000000000000000000000008C -:10C4B000000000000000000000000000000000007C -:10C4C000000000000000000000000000000000006C -:10C4D000000000000000000000000000000000005C -:10C4E000000000000000000000000000000000004C -:10C4F000000000000000000000000000000000003C -:10C50000000000000000000000000000000000002B -:10C51000000000000000000000000000000000001B -:10C52000000000000000000000000000000000000B -:10C5300000000000000000000000000000000000FB -:10C5400000000000000000000000000000000000EB -:10C5500000000000000000000000000000000000DB -:10C5600000000000000000000000000000000000CB -:10C5700000000000000000000000000000000000BB -:10C5800000000000000000000000000000000000AB -:10C59000000000000000000000000000000000009B -:10C5A000000000000000000000000000000000008B -:10C5B000000000000000000000000000000000007B -:10C5C000000000000000000000000000000000006B -:10C5D000000000000000000000000000000000005B -:10C5E000000000000000000000000000000000004B -:10C5F000000000000000000000000000000000003B -:10C60000000000000000000000000000000000002A -:10C61000000000000000000000000000000000001A -:10C62000000000000000000000000000000000000A -:10C6300000000000000000000000000000000000FA -:10C6400000000000000000000000000000000000EA -:10C6500000000000000000000000000000000000DA -:10C6600000000000000000000000000000000000CA -:10C6700000000000000000000000000000000000BA -:10C6800000000000000000000000000000000000AA -:10C69000000000000000000000000000000000009A -:10C6A000000000000000000000000000000000008A -:10C6B000000000000000000000000000000000007A -:10C6C000000000000000000000000000000000006A -:10C6D000000000000000000000000000000000005A -:10C6E000000000000000000000000000000000004A -:10C6F000000000000000000000000000000000003A -:10C700000000000000000000000000000000000029 -:10C710000000000000000000000000000000000019 -:10C720000000000000000000000000000000000009 -:10C7300000000000000000000000000000000000F9 -:10C7400000000000000000000000000000000000E9 -:10C7500000000000000000000000000000000000D9 -:10C7600000000000000000000000000000000000C9 -:10C7700000000000000000000000000000000000B9 -:10C7800000000000000000000000000000000000A9 -:10C790000000000000000000000000000000000099 -:10C7A0000000000000000000000000000000000089 -:10C7B0000000000000000000000000000000000079 -:10C7C0000000000000000000000000000000000069 -:10C7D0000000000000000000000000000000000059 -:10C7E0000000000000000000000000000000000049 -:10C7F0000000000000000000000000000000000039 -:10C800000000000000000000000000000000000028 -:10C810000000000000000000000000000000000018 -:10C820000000000000000000000000000000000008 -:10C8300000000000000000000000000000000000F8 -:10C8400000000000000000000000000000000000E8 -:10C8500000000000000000000000000000000000D8 -:10C8600000000000000000000000000000000000C8 -:10C8700000000000000000000000000000000000B8 -:10C8800000000000000000000000000000000000A8 -:10C890000000000000000000000000000000000098 -:10C8A0000000000000000000000000000000000088 -:10C8B0000000000000000000000000000000000078 -:10C8C0000000000000000000000000000000000068 -:10C8D0000000000000000000000000000000000058 -:10C8E0000000000000000000000000000000000048 -:10C8F0000000000000000000000000000000000038 -:10C900000000000000000000000000000000000027 -:10C910000000000000000000000000000000000017 -:10C920000000000000000000000000000000000007 -:10C9300000000000000000000000000000000000F7 -:10C9400000000000000000000000000000000000E7 -:10C9500000000000000000000000000000000000D7 -:10C9600000000000000000000000000000000000C7 -:10C9700000000000000000000000000000000000B7 -:10C9800000000000000000000000000000000000A7 -:10C990000000000000000000000000000000000097 -:10C9A0000000000000000000000000000000000087 -:10C9B0000000000000000000000000000000000077 -:10C9C0000000000000000000000000000000000067 -:10C9D0000000000000000000000000000000000057 -:10C9E0000000000000000000000000000000000047 -:10C9F0000000000000000000000000000000000037 -:10CA00000000000000000000000000000000000026 -:10CA10000000000000000000000000000000000016 -:10CA20000000000000000000000000000000000006 -:10CA300000000000000000000000000000000000F6 -:10CA400000000000000000000000000000000000E6 -:10CA500000000000000000000000000000000000D6 -:10CA600000000000000000000000000000000000C6 -:10CA700000000000000000000000000000000000B6 -:10CA800000000000000000000000000000000000A6 -:10CA90000000000000000000000000000000000096 -:10CAA0000000000000000000000000000000000086 -:10CAB0000000000000000000000000000000000076 -:10CAC0000000000000000000000000000000000066 -:10CAD0000000000000000000000000000000000056 -:10CAE0000000000000000000000000000000000046 -:10CAF0000000000000000000000000000000000036 -:10CB00000000000000000000000000000000000025 -:10CB10000000000000000000000000000000000015 -:10CB20000000000000000000000000000000000005 -:10CB300000000000000000000000000000000000F5 -:10CB400000000000000000000000000000000000E5 -:10CB500000000000000000000000000000000000D5 -:10CB600000000000000000000000000000000000C5 -:10CB700000000000000000000000000000000000B5 -:10CB800000000000000000000000000000000000A5 -:10CB90000000000000000000000000000000000095 -:10CBA0000000000000000000000000000000000085 -:10CBB0000000000000000000000000000000000075 -:10CBC0000000000000000000000000000000000065 -:10CBD0000000000000000000000000000000000055 -:10CBE0000000000000000000000000000000000045 -:10CBF0000000000000000000000000000000000035 -:10CC00000000000000000000000000000000000024 -:10CC10000000000000000000000000000000000014 -:10CC20000000000000000000000000000000000004 -:10CC300000000000000000000000000000000000F4 -:10CC400000000000000000000000000000000000E4 -:10CC500000000000000000000000000000000000D4 -:10CC600000000000000000000000000000000000C4 -:10CC700000000000000000000000000000000000B4 -:10CC800000000000000000000000000000000000A4 -:10CC90000000000000000000000000000000000094 -:10CCA0000000000000000000000000000000000084 -:10CCB0000000000000000000000000000000000074 -:10CCC0000000000000000000000000000000000064 -:10CCD0000000000000000000000000000000000054 -:10CCE0000000000000000000000000000000000044 -:10CCF0000000000000000000000000000000000034 -:10CD00000000000000000000000000000000000023 -:10CD10000000000000000000000000000000000013 -:10CD20000000000000000000000000000000000003 -:10CD300000000000000000000000000000000000F3 -:10CD400000000000000000000000000000000000E3 -:10CD500000000000000000000000000000000000D3 -:10CD600000000000000000000000000000000000C3 -:10CD700000000000000000000000000000000000B3 -:10CD800000000000000000000000000000000000A3 -:10CD90000000000000000000000000000000000093 -:10CDA0000000000000000000000000000000000083 -:10CDB0000000000000000000000000000000000073 -:10CDC0000000000000000000000000000000000063 -:10CDD0000000000000000000000000000000000053 -:10CDE0000000000000000000000000000000000043 -:10CDF0000000000000000000000000000000000033 -:10CE00000000000000000000000000000000000022 -:10CE10000000000000000000000000000000000012 -:10CE20000000000000000000000000000000000002 -:10CE300000000000000000000000000000000000F2 -:10CE400000000000000000000000000000000000E2 -:10CE500000000000000000000000000000000000D2 -:10CE600000000000000000000000000000000000C2 -:10CE700000000000000000000000000000000000B2 -:10CE800000000000000000000000000000000000A2 -:10CE90000000000000000000000000000000000092 -:10CEA0000000000000000000000000000000000082 -:10CEB0000000000000000000000000000000000072 -:10CEC0000000000000000000000000000000000062 -:10CED0000000000000000000000000000000000052 -:10CEE0000000000000000000000000000000000042 -:10CEF0000000000000000000000000000000000032 -:10CF00000000000000000000000000000000000021 -:10CF10000000000000000000000000000000000011 -:10CF20000000000000000000000000000000000001 -:10CF300000000000000000000000000000000000F1 -:10CF400000000000000000000000000000000000E1 -:10CF500000000000000000000000000000000000D1 -:10CF600000000000000000000000000000000000C1 -:10CF700000000000000000000000000000000000B1 -:10CF800000000000000000000000000000000000A1 -:10CF90000000000000000000000000000000000091 -:10CFA0000000000000000000000000000000000081 -:10CFB0000000000000000000000000000000000071 -:10CFC0000000000000000000000000000000000061 -:10CFD0000000000000000000000000000000000051 -:10CFE0000000000000000000000000000000000041 -:10CFF0000000000000000000000000000000000031 -:10D000000000000000000000000000000000000020 -:10D010000000000000000000000000000000000010 -:10D020000000000000000000000000000000000000 -:10D0300000000000000000000000000000000000F0 -:10D0400000000000000000000000000000000000E0 -:10D0500000000000000000000000000000000000D0 -:10D0600000000000000000000000000000000000C0 -:10D0700000000000000000000000000000000000B0 -:10D0800000000000000000000000000000000000A0 -:10D090000000000000000000000000000000000090 -:10D0A0000000000000000000000000000000000080 -:10D0B0000000000000000000000000000000000070 -:10D0C0000000000000000000000000000000000060 -:10D0D0000000000000000000000000000000000050 -:10D0E0000000000000000000000000000000000040 -:10D0F0000000000000000000000000000000000030 -:10D10000000000000000000000000000000000001F -:10D11000000000000000000000000000000000000F -:10D1200000000000000000000000000000000000FF -:10D1300000000000000000000000000000000000EF -:10D1400000000000000000000000000000000000DF -:10D1500000000000000000000000000000000000CF -:10D1600000000000000000000000000000000000BF -:10D1700000000000000000000000000000000000AF -:10D18000000000000000000000000000000000009F -:10D19000000000000000000000000000000000008F -:10D1A000000000000000000000000000000000007F -:10D1B000000000000000000000000000000000006F -:10D1C000000000000000000000000000000000005F -:10D1D000000000000000000000000000000000004F -:10D1E000000000000000000000000000000000003F -:10D1F000000000000000000000000000000000002F -:10D20000000000000000000000000000000000001E -:10D21000000000000000000000000000000000000E -:10D2200000000000000000000000000000000000FE -:10D2300000000000000000000000000000000000EE -:10D2400000000000000000000000000000000000DE -:10D2500000000000000000000000000000000000CE -:10D2600000000000000000000000000000000000BE -:10D2700000000000000000000000000000000000AE -:10D28000000000000000000000000000000000009E -:10D29000000000000000000000000000000000008E -:10D2A000000000000000000000000000000000007E -:10D2B000000000000000000000000000000000006E -:10D2C000000000000000000000000000000000005E -:10D2D000000000000000000000000000000000004E -:10D2E000000000000000000000000000000000003E -:10D2F000000000000000000000000000000000002E -:10D30000000000000000000000000000000000001D -:10D31000000000000000000000000000000000000D -:10D3200000000000000000000000000000000000FD -:10D3300000000000000000000000000000000000ED -:10D3400000000000000000000000000000000000DD -:10D3500000000000000000000000000000000000CD -:10D3600000000000000000000000000000000000BD -:10D3700000000000000000000000000000000000AD -:10D38000000000000000000000000000000000009D -:10D39000000000000000000000000000000000008D -:10D3A000000000000000000000000000000000007D -:10D3B000000000000000000000000000000000006D -:10D3C000000000000000000000000000000000005D -:10D3D000000000000000000000000000000000004D -:10D3E000000000000000000000000000000000003D -:10D3F000000000000000000000000000000000002D -:10D40000000000000000000000000000000000001C -:10D41000000000000000000000000000000000000C -:10D4200000000000000000000000000000000000FC -:10D4300000000000000000000000000000000000EC -:10D4400000000000000000000000000000000000DC -:10D4500000000000000000000000000000000000CC -:10D4600000000000000000000000000000000000BC -:10D4700000000000000000000000000000000000AC -:10D48000000000000000000000000000000000009C -:10D49000000000000000000000000000000000008C -:10D4A000000000000000000000000000000000007C -:10D4B000000000000000000000000000000000006C -:10D4C000000000000000000000000000000000005C -:10D4D000000000000000000000000000000000004C -:10D4E000000000000000000000000000000000003C -:10D4F000000000000000000000000000000000002C -:10D50000000000000000000000000000000000001B -:10D51000000000000000000000000000000000000B -:10D5200000000000000000000000000000000000FB -:10D5300000000000000000000000000000000000EB -:10D5400000000000000000000000000000000000DB -:10D5500000000000000000000000000000000000CB -:10D5600000000000000000000000000000000000BB -:10D5700000000000000000000000000000000000AB -:10D58000000000000000000000000000000000009B -:10D59000000000000000000000000000000000008B -:10D5A000000000000000000000000000000000007B -:10D5B000000000000000000000000000000000006B -:10D5C000000000000000000000000000000000005B -:10D5D000000000000000000000000000000000004B -:10D5E000000000000000000000000000000000003B -:10D5F000000000000000000000000000000000002B -:10D60000000000000000000000000000000000001A -:10D61000000000000000000000000000000000000A -:10D6200000000000000000000000000000000000FA -:10D6300000000000000000000000000000000000EA -:10D6400000000000000000000000000000000000DA -:10D6500000000000000000000000000000000000CA -:10D6600000000000000000000000000000000000BA -:10D6700000000000000000000000000000000000AA -:10D68000000000000000000000000000000000009A -:10D69000000000000000000000000000000000008A -:10D6A000000000000000000000000000000000007A -:10D6B000000000000000000000000000000000006A -:10D6C000000000000000000000000000000000005A -:10D6D000000000000000000000000000000000004A -:10D6E000000000000000000000000000000000003A -:10D6F000000000000000000000000000000000002A -:10D700000000000000000000000000000000000019 -:10D710000000000000000000000000000000000009 -:10D7200000000000000000000000000000000000F9 -:10D7300000000000000000000000000000000000E9 -:10D7400000000000000000000000000000000000D9 -:10D7500000000000000000000000000000000000C9 -:10D7600000000000000000000000000000000000B9 -:10D7700000000000000000000000000000000000A9 -:10D780000000000000000000000000000000000099 -:10D790000000000000000000000000000000000089 -:10D7A0000000000000000000000000000000000079 -:10D7B0000000000000000000000000000000000069 -:10D7C0000000000000000000000000000000000059 -:10D7D0000000000000000000000000000000000049 -:10D7E0000000000000000000000000000000000039 -:10D7F0000000000000000000000000000000000029 -:10D800000000000000000000000000000000000018 -:10D810000000000000000000000000000000000008 -:10D8200000000000000000000000000000000000F8 -:10D8300000000000000000000000000000000000E8 -:10D8400000000000000000000000000000000000D8 -:10D8500000000000000000000000000000000000C8 -:10D8600000000000000000000000000000000000B8 -:10D8700000000000000000000000000000000000A8 -:10D880000000000000000000000000000000000098 -:10D890000000000000000000000000000000000088 -:10D8A0000000000000000000000000000000000078 -:10D8B0000000000000000000000000000000000068 -:10D8C0000000000000000000000000000000000058 -:10D8D0000000000000000000000000000000000048 -:10D8E0000000000000000000000000000000000038 -:10D8F0000000000000000000000000000000000028 -:10D900000000000000000000000000000000000017 -:10D910000000000000000000000000000000000007 -:10D9200000000000000000000000000000000000F7 -:10D9300000000000000000000000000000000000E7 -:10D9400000000000000000000000000000000000D7 -:10D9500000000000000000000000000000000000C7 -:10D9600000000000000000000000000000000000B7 -:10D9700000000000000000000000000000000000A7 -:10D980000000000000000000000000000000000097 -:10D990000000000000000000000000000000000087 -:10D9A0000000000000000000000000000000000077 -:10D9B0000000000000000000000000000000000067 -:10D9C0000000000000000000000000000000000057 -:10D9D0000000000000000000000000000000000047 -:10D9E0000000000000000000000000000000000037 -:10D9F0000000000000000000000000000000000027 -:10DA00000000000000000000000000000000000016 -:10DA10000000000000000000000000000000000006 -:10DA200000000000000000000000000000000000F6 -:10DA300000000000000000000000000000000000E6 -:10DA400000000000000000000000000000000000D6 -:10DA500000000000000000000000000000000000C6 -:10DA600000000000000000000000000000000000B6 -:10DA700000000000000000000000000000000000A6 -:10DA80000000000000000000000000000000000096 -:10DA90000000000000000000000000000000000086 -:10DAA0000000000000000000000000000000000076 -:10DAB0000000000000000000000000000000000066 -:10DAC0000000000000000000000000000000000056 -:10DAD0000000000000000000000000000000000046 -:10DAE0000000000000000000000000000000000036 -:10DAF0000000000000000000000000000000000026 -:10DB00000000000000000000000000000000000015 -:10DB10000000000000000000000000000000000005 -:10DB200000000000000000000000000000000000F5 -:10DB300000000000000000000000000000000000E5 -:10DB400000000000000000000000000000000000D5 -:10DB500000000000000000000000000000000000C5 -:10DB600000000000000000000000000000000000B5 -:10DB700000000000000000000000000000000000A5 -:10DB80000000000000000000000000000000000095 -:10DB90000000000000000000000000000000000085 -:10DBA0000000000000000000000000000000000075 -:10DBB0000000000000000000000000000000000065 -:10DBC0000000000000000000000000000000000055 -:10DBD0000000000000000000000000000000000045 -:10DBE0000000000000000000000000000000000035 -:10DBF0000000000000000000000000000000000025 -:10DC00000000000000000000000000000000000014 -:10DC10000000000000000000000000000000000004 -:10DC200000000000000000000000000000000000F4 -:10DC300000000000000000000000000000000000E4 -:10DC400000000000000000000000000000000000D4 -:10DC500000000000000000000000000000000000C4 -:10DC600000000000000000000000000000000000B4 -:10DC700000000000000000000000000000000000A4 -:10DC80000000000000000000000000000000000094 -:10DC90000000000000000000000000000000000084 -:10DCA0000000000000000000000000000000000074 -:10DCB0000000000000000000000000000000000064 -:10DCC0000000000000000000000000000000000054 -:10DCD0000000000000000000000000000000000044 -:10DCE0000000000000000000000000000000000034 -:10DCF0000000000000000000000000000000000024 -:10DD00000000000000000000000000000000000013 -:10DD10000000000000000000000000000000000003 -:10DD200000000000000000000000000000000000F3 -:10DD300000000000000000000000000000000000E3 -:10DD400000000000000000000000000000000000D3 -:10DD500000000000000000000000000000000000C3 -:10DD600000000000000000000000000000000000B3 -:10DD700000000000000000000000000000000000A3 -:10DD80000000000000000000000000000000000093 -:10DD90000000000000000000000000000000000083 -:10DDA0000000000000000000000000000000000073 -:10DDB0000000000000000000000000000000000063 -:10DDC0000000000000000000000000000000000053 -:10DDD0000000000000000000000000000000000043 -:10DDE0000000000000000000000000000000000033 -:10DDF0000000000000000000000000000000000023 -:10DE00000000000000000000000000000000000012 -:10DE10000000000000000000000000000000000002 -:10DE200000000000000000000000000000000000F2 -:10DE300000000000000000000000000000000000E2 -:10DE400000000000000000000000000000000000D2 -:10DE500000000000000000000000000000000000C2 -:10DE600000000000000000000000000000000000B2 -:10DE700000000000000000000000000000000000A2 -:10DE80000000000000000000000000000000000092 -:10DE90000000000000000000000000000000000082 -:10DEA0000000000000000000000000000000000072 -:10DEB0000000000000000000000000000000000062 -:10DEC0000000000000000000000000000000000052 -:10DED0000000000000000000000000000000000042 -:10DEE0000000000000000000000000000000000032 -:10DEF0000000000000000000000000000000000022 -:10DF00000000000000000000000000000000000011 -:10DF10000000000000000000000000000000000001 -:10DF200000000000000000000000000000000000F1 -:10DF300000000000000000000000000000000000E1 -:10DF400000000000000000000000000000000000D1 -:10DF500000000000000000000000000000000000C1 -:10DF600000000000000000000000000000000000B1 -:10DF700000000000000000000000000000000000A1 -:10DF80000000000000000000000000000000000091 -:10DF90000000000000000000000000000000000081 -:10DFA0000000000000000000000000000000000071 -:10DFB0000000000000000000000000000000000061 -:10DFC0000000000000000000000000000000000051 -:10DFD0000000000000000000000000000000000041 -:10DFE0000000000000000000000000000000000031 -:10DFF0000000000000000000000000000000000021 -:10E000000000000000000000000000000000000010 -:10E010000000000000000000000000000000000000 -:10E0200000000000000000000000000000000000F0 -:10E0300000000000000000000000000000000000E0 -:10E0400000000000000000000000000000000000D0 -:10E0500000000000000000000000000000000000C0 -:10E0600000000000000000000000000000000000B0 -:10E0700000000000000000000000000000000000A0 -:10E080000000000000000000000000000000000090 -:10E090000000000000000000000000000000000080 -:10E0A0000000000000000000000000000000000070 -:10E0B0000000000000000000000000000000000060 -:10E0C0000000000000000000000000000000000050 -:10E0D0000000000000000000000000000000000040 -:10E0E0000000000000000000000000000000000030 -:10E0F0000000000000000000000000000000000020 -:10E10000000000000000000000000000000000000F -:10E1100000000000000000000000000000000000FF -:10E1200000000000000000000000000000000000EF -:10E1300000000000000000000000000000000000DF -:10E1400000000000000000000000000000000000CF -:10E1500000000000000000000000000000000000BF -:10E1600000000000000000000000000000000000AF -:10E17000000000000000000000000000000000009F -:10E18000000000000000000000000000000000008F -:10E19000000000000000000000000000000000007F -:10E1A000000000000000000000000000000000006F -:10E1B000000000000000000000000000000000005F -:10E1C000000000000000000000000000000000004F -:10E1D000000000000000000000000000000000003F -:10E1E000000000000000000000000000000000002F -:10E1F000000000000000000000000000000000001F -:10E20000000000000000000000000000000000000E -:10E2100000000000000000000000000000000000FE -:10E2200000000000000000000000000000000000EE -:10E2300000000000000000000000000000000000DE -:10E2400000000000000000000000000000000000CE -:10E2500000000000000000000000000000000000BE -:10E2600000000000000000000000000000000000AE -:10E27000000000000000000000000000000000009E -:10E28000000000000000000000000000000000008E -:10E29000000000000000000000000000000000007E -:10E2A000000000000000000000000000000000006E -:10E2B000000000000000000000000000000000005E -:10E2C000000000000000000000000000000000004E -:10E2D000000000000000000000000000000000003E -:10E2E000000000000000000000000000000000002E -:10E2F000000000000000000000000000000000001E -:10E30000000000000000000000000000000000000D -:10E3100000000000000000000000000000000000FD -:10E3200000000000000000000000000000000000ED -:10E3300000000000000000000000000000000000DD -:10E3400000000000000000000000000000000000CD -:10E3500000000000000000000000000000000000BD -:10E3600000000000000000000000000000000000AD -:10E37000000000000000000000000000000000009D -:10E38000000000000000000000000000000000008D -:10E39000000000000000000000000000000000007D -:10E3A000000000000000000000000000000000006D -:10E3B000000000000000000000000000000000005D -:10E3C000000000000000000000000000000000004D -:10E3D000000000000000000000000000000000003D -:10E3E000000000000000000000000000000000002D -:10E3F000000000000000000000000000000000001D -:10E40000000000000000000000000000000000000C -:10E4100000000000000000000000000000000000FC -:10E4200000000000000000000000000000000000EC -:10E4300000000000000000000000000000000000DC -:10E4400000000000000000000000000000000000CC -:10E4500000000000000000000000000000000000BC -:10E4600000000000000000000000000000000000AC -:10E47000000000000000000000000000000000009C -:10E48000000000000000000000000000000000008C -:10E49000000000000000000000000000000000007C -:10E4A000000000000000000000000000000000006C -:10E4B000000000000000000000000000000000005C -:10E4C000000000000000000000000000000000004C -:10E4D000000000000000000000000000000000003C -:10E4E000000000000000000000000000000000002C -:10E4F000000000000000000000000000000000001C -:10E50000000000000000000000000000000000000B -:10E5100000000000000000000000000000000000FB -:10E5200000000000000000000000000000000000EB -:10E5300000000000000000000000000000000000DB -:10E5400000000000000000000000000000000000CB -:10E5500000000000000000000000000000000000BB -:10E5600000000000000000000000000000000000AB -:10E57000000000000000000000000000000000009B -:10E58000000000000000000000000000000000008B -:10E59000000000000000000000000000000000007B -:10E5A000000000000000000000000000000000006B -:10E5B000000000000000000000000000000000005B -:10E5C000000000000000000000000000000000004B -:10E5D000000000000000000000000000000000003B -:10E5E000000000000000000000000000000000002B -:10E5F000000000000000000000000000000000001B -:10E60000000000000000000000000000000000000A -:10E6100000000000000000000000000000000000FA -:10E6200000000000000000000000000000000000EA -:10E6300000000000000000000000000000000000DA -:10E6400000000000000000000000000000000000CA -:10E6500000000000000000000000000000000000BA -:10E6600000000000000000000000000000000000AA -:10E67000000000000000000000000000000000009A -:10E68000000000000000000000000000000000008A -:10E69000000000000000000000000000000000007A -:10E6A000000000000000000000000000000000006A -:10E6B000000000000000000000000000000000005A -:10E6C000000000000000000000000000000000004A -:10E6D000000000000000000000000000000000003A -:10E6E000000000000000000000000000000000002A -:10E6F000000000000000000000000000000000001A -:10E700000000000000000000000000000000000009 -:10E7100000000000000000000000000000000000F9 -:10E7200000000000000000000000000000000000E9 -:10E7300000000000000000000000000000000000D9 -:10E7400000000000000000000000000000000000C9 -:10E7500000000000000000000000000000000000B9 -:10E7600000000000000000000000000000000000A9 -:10E770000000000000000000000000000000000099 -:10E780000000000000000000000000000000000089 -:10E790000000000000000000000000000000000079 -:10E7A0000000000000000000000000000000000069 -:10E7B0000000000000000000000000000000000059 -:10E7C0000000000000000000000000000000000049 -:10E7D0000000000000000000000000000000000039 -:10E7E0000000000000000000000000000000000029 -:10E7F0000000000000000000000000000000000019 -:10E800000000000000000000000000000000000008 -:10E8100000000000000000000000000000000000F8 -:10E8200000000000000000000000000000000000E8 -:10E8300000000000000000000000000000000000D8 -:10E8400000000000000000000000000000000000C8 -:10E8500000000000000000000000000000000000B8 -:10E8600000000000000000000000000000000000A8 -:10E870000000000000000000000000000000000098 -:10E880000000000000000000000000000000000088 -:10E890000000000000000000000000000000000078 -:10E8A0000000000000000000000000000000000068 -:10E8B0000000000000000000000000000000000058 -:10E8C0000000000000000000000000000000000048 -:10E8D0000000000000000000000000000000000038 -:10E8E0000000000000000000000000000000000028 -:10E8F0000000000000000000000000000000000018 -:10E900000000000000000000000000000000000007 -:10E9100000000000000000000000000000000000F7 -:10E9200000000000000000000000000000000000E7 -:10E9300000000000000000000000000000000000D7 -:10E9400000000000000000000000000000000000C7 -:10E9500000000000000000000000000000000000B7 -:10E9600000000000000000000000000000000000A7 -:10E970000000000000000000000000000000000097 -:10E980000000000000000000000000000000000087 -:10E990000000000000000000000000000000000077 -:10E9A0000000000000000000000000000000000067 -:10E9B0000000000000000000000000000000000057 -:10E9C0000000000000000000000000000000000047 -:10E9D0000000000000000000000000000000000037 -:10E9E0000000000000000000000000000000000027 -:10E9F0000000000000000000000000000000000017 -:10EA00000000000000000000000000000000000006 -:10EA100000000000000000000000000000000000F6 -:10EA200000000000000000000000000000000000E6 -:10EA300000000000000000000000000000000000D6 -:10EA400000000000000000000000000000000000C6 -:10EA500000000000000000000000000000000000B6 -:10EA600000000000000000000000000000000000A6 -:10EA70000000000000000000000000000000000096 -:10EA80000000000000000000000000000000000086 -:10EA90000000000000000000000000000000000076 -:10EAA0000000000000000000000000000000000066 -:10EAB0000000000000000000000000000000000056 -:10EAC0000000000000000000000000000000000046 -:10EAD0000000000000000000000000000000000036 -:10EAE0000000000000000000000000000000000026 -:10EAF0000000000000000000000000000000000016 -:10EB00000000000000000000000000000000000005 -:10EB100000000000000000000000000000000000F5 -:10EB200000000000000000000000000000000000E5 -:10EB300000000000000000000000000000000000D5 -:10EB400000000000000000000000000000000000C5 -:10EB500000000000000000000000000000000000B5 -:10EB600000000000000000000000000000000000A5 -:10EB70000000000000000000000000000000000095 -:10EB80000000000000000000000000000000000085 -:10EB90000000000000000000000000000000000075 -:10EBA0000000000000000000000000000000000065 -:10EBB0000000000000000000000000000000000055 -:10EBC0000000000000000000000000000000000045 -:10EBD0000000000000000000000000000000000035 -:10EBE0000000000000000000000000000000000025 -:10EBF0000000000000000000000000000000000015 -:10EC00000000000000000000000000000000000004 -:10EC100000000000000000000000000000000000F4 -:10EC200000000000000000000000000000000000E4 -:10EC300000000000000000000000000000000000D4 -:10EC400000000000000000000000000000000000C4 -:10EC500000000000000000000000000000000000B4 -:10EC600000000000000000000000000000000000A4 -:10EC70000000000000000000000000000000000094 -:10EC80000000000000000000000000000000000084 -:10EC90000000000000000000000000000000000074 -:10ECA0000000000000000000000000000000000064 -:10ECB0000000000000000000000000000000000054 -:10ECC0000000000000000000000000000000000044 -:10ECD0000000000000000000000000000000000034 -:10ECE0000000000000000000000000000000000024 -:10ECF0000000000000000000000000000000000014 -:10ED00000000000000000000000000000000000003 -:10ED100000000000000000000000000000000000F3 -:10ED200000000000000000000000000000000000E3 -:10ED300000000000000000000000000000000000D3 -:10ED400000000000000000000000000000000000C3 -:10ED500000000000000000000000000000000000B3 -:10ED600000000000000000000000000000000000A3 -:10ED70000000000000000000000000000000000093 -:10ED80000000000000000000000000000000000083 -:10ED90000000000000000000000000000000000073 -:10EDA0000000000000000000000000000000000063 -:10EDB0000000000000000000000000000000000053 -:10EDC0000000000000000000000000000000000043 -:10EDD0000000000000000000000000000000000033 -:10EDE0000000000000000000000000000000000023 -:10EDF0000000000000000000000000000000000013 -:10EE00000000000000000000000000000000000002 -:10EE100000000000000000000000000000000000F2 -:10EE200000000000000000000000000000000000E2 -:10EE300000000000000000000000000000000000D2 -:10EE400000000000000000000000000000000000C2 -:10EE500000000000000000000000000000000000B2 -:10EE600000000000000000000000000000000000A2 -:10EE70000000000000000000000000000000000092 -:10EE80000000000000000000000000000000000082 -:10EE90000000000000000000000000000000000072 -:10EEA0000000000000000000000000000000000062 -:10EEB0000000000000000000000000000000000052 -:10EEC0000000000000000000000000000000000042 -:10EED0000000000000000000000000000000000032 -:10EEE0000000000000000000000000000000000022 -:10EEF0000000000000000000000000000000000012 -:10EF00000000000000000000000000000000000001 -:10EF100000000000000000000000000000000000F1 -:10EF200000000000000000000000000000000000E1 -:10EF300000000000000000000000000000000000D1 -:10EF400000000000000000000000000000000000C1 -:10EF500000000000000000000000000000000000B1 -:10EF600000000000000000000000000000000000A1 -:10EF70000000000000000000000000000000000091 -:10EF80000000000000000000000000000000000081 -:10EF90000000000000000000000000000000000071 -:10EFA0000000000000000000000000000000000061 -:10EFB0000000000000000000000000000000000051 -:10EFC0000000000000000000000000000000000041 -:10EFD0000000000000000000000000000000000031 -:10EFE0000000000000000000000000000000000021 -:10EFF0000000000000000000000000000000000011 -:10F000000000000000000000000000000000000000 -:10F0100000000000000000000000000000000000F0 -:10F0200000000000000000000000000000000000E0 -:10F0300000000000000000000000000000000000D0 -:10F0400000000000000000000000000000000000C0 -:10F0500000000000000000000000000000000000B0 -:10F0600000000000000000000000000000000000A0 -:10F070000000000000000000000000000000000090 -:10F080000000000000000000000000000000000080 -:10F090000000000000000000000000000000000070 -:10F0A0000000000000000000000000000000000060 -:10F0B0000000000000000000000000000000000050 -:10F0C0000000000000000000000000000000000040 -:10F0D0000000000000000000000000000000000030 -:10F0E0000000000000000000000000000000000020 -:10F0F0000000000000000000000000000000000010 -:10F1000000000000000000000000000000000000FF -:10F1100000000000000000000000000000000000EF -:10F1200000000000000000000000000000000000DF -:10F1300000000000000000000000000000000000CF -:10F1400000000000000000000000000000000000BF -:10F1500000000000000000000000000000000000AF -:10F16000000000000000000000000000000000009F -:10F17000000000000000000000000000000000008F -:10F18000000000000000000000000000000000007F -:10F19000000000000000000000000000000000006F -:10F1A000000000000000000000000000000000005F -:10F1B000000000000000000000000000000000004F -:10F1C000000000000000000000000000000000003F -:10F1D000000000000000000000000000000000002F -:10F1E000000000000000000000000000000000001F -:10F1F000000000000000000000000000000000000F -:10F2000000000000000000000000000000000000FE -:10F2100000000000000000000000000000000000EE -:10F2200000000000000000000000000000000000DE -:10F2300000000000000000000000000000000000CE -:10F2400000000000000000000000000000000000BE -:10F2500000000000000000000000000000000000AE -:10F26000000000000000000000000000000000009E -:10F27000000000000000000000000000000000008E -:10F28000000000000000000000000000000000007E -:10F29000000000000000000000000000000000006E -:10F2A000000000000000000000000000000000005E -:10F2B000000000000000000000000000000000004E -:10F2C000000000000000000000000000000000003E -:10F2D000000000000000000000000000000000002E -:10F2E000000000000000000000000000000000001E -:10F2F000000000000000000000000000000000000E -:10F3000000000000000000000000000000000000FD -:10F3100000000000000000000000000000000000ED -:10F3200000000000000000000000000000000000DD -:10F3300000000000000000000000000000000000CD -:10F3400000000000000000000000000000000000BD -:10F3500000000000000000000000000000000000AD -:10F36000000000000000000000000000000000009D -:10F37000000000000000000000000000000000008D -:10F38000000000000000000000000000000000007D -:10F39000000000000000000000000000000000006D -:10F3A000000000000000000000000000000000005D -:10F3B000000000000000000000000000000000004D -:10F3C000000000000000000000000000000000003D -:10F3D000000000000000000000000000000000002D -:10F3E000000000000000000000000000000000001D -:10F3F000000000000000000000000000000000000D -:10F4000000000000000000000000000000000000FC -:10F4100000000000000000000000000000000000EC -:10F4200000000000000000000000000000000000DC -:10F4300000000000000000000000000000000000CC -:10F4400000000000000000000000000000000000BC -:10F4500000000000000000000000000000000000AC -:10F46000000000000000000000000000000000009C -:10F47000000000000000000000000000000000008C -:10F48000000000000000000000000000000000007C -:10F49000000000000000000000000000000000006C -:10F4A000000000000000000000000000000000005C -:10F4B000000000000000000000000000000000004C -:10F4C000000000000000000000000000000000003C -:10F4D000000000000000000000000000000000002C -:10F4E000000000000000000000000000000000001C -:10F4F000000000000000000000000000000000000C -:10F5000000000000000000000000000000000000FB -:10F5100000000000000000000000000000000000EB -:10F5200000000000000000000000000000000000DB -:10F5300000000000000000000000000000000000CB -:10F5400000000000000000000000000000000000BB -:10F5500000000000000000000000000000000000AB -:10F56000000000000000000000000000000000009B -:10F57000000000000000000000000000000000008B -:10F58000000000000000000000000000000000007B -:10F59000000000000000000000000000000000006B -:10F5A000000000000000000000000000000000005B -:10F5B000000000000000000000000000000000004B -:10F5C000000000000000000000000000000000003B -:10F5D000000000000000000000000000000000002B -:10F5E000000000000000000000000000000000001B -:10F5F000000000000000000000000000000000000B -:10F6000000000000000000000000000000000000FA -:10F6100000000000000000000000000000000000EA -:10F6200000000000000000000000000000000000DA -:10F6300000000000000000000000000000000000CA -:10F6400000000000000000000000000000000000BA -:10F6500000000000000000000000000000000000AA -:10F66000000000000000000000000000000000009A -:10F67000000000000000000000000000000000008A -:10F68000000000000000000000000000000000007A -:10F69000000000000000000000000000000000006A -:10F6A000000000000000000000000000000000005A -:10F6B000000000000000000000000000000000004A -:10F6C000000000000000000000000000000000003A -:10F6D000000000000000000000000000000000002A -:10F6E000000000000000000000000000000000001A -:10F6F000000000000000000000000000000000000A -:10F7000000000000000000000000000000000000F9 -:10F7100000000000000000000000000000000000E9 -:10F7200000000000000000000000000000000000D9 -:10F7300000000000000000000000000000000000C9 -:10F7400000000000000000000000000000000000B9 -:10F7500000000000000000000000000000000000A9 -:10F760000000000000000000000000000000000099 -:10F770000000000000000000000000000000000089 -:10F780000000000000000000000000000000000079 -:10F790000000000000000000000000000000000069 -:10F7A0000000000000000000000000000000000059 -:10F7B0000000000000000000000000000000000049 -:10F7C0000000000000000000000000000000000039 -:10F7D0000000000000000000000000000000000029 -:10F7E0000000000000000000000000000000000019 -:10F7F0000000000000000000000000000000000009 -:10F8000000000000000000000000000000000000F8 -:10F8100000000000000000000000000000000000E8 -:10F8200000000000000000000000000000000000D8 -:10F8300000000000000000000000000000000000C8 -:10F8400000000000000000000000000000000000B8 -:10F8500000000000000000000000000000000000A8 -:10F860000000000000000000000000000000000098 -:10F870000000000000000000000000000000000088 -:10F880000000000000000000000000000000000078 -:10F890000000000000000000000000000000000068 -:10F8A0000000000000000000000000000000000058 -:10F8B0000000000000000000000000000000000048 -:10F8C0000000000000000000000000000000000038 -:10F8D0000000000000000000000000000000000028 -:10F8E0000000000000000000000000000000000018 -:10F8F0000000000000000000000000000000000008 -:10F9000000000000000000000000000000000000F7 -:10F9100000000000000000000000000000000000E7 -:10F9200000000000000000000000000000000000D7 -:10F9300000000000000000000000000000000000C7 -:10F9400000000000000000000000000000000000B7 -:10F9500000000000000000000000000000000000A7 -:10F960000000000000000000000000000000000097 -:10F970000000000000000000000000000000000087 -:10F980000000000000000000000000000000000077 -:10F990000000000000000000000000000000000067 -:10F9A0000000000000000000000000000000000057 -:10F9B0000000000000000000000000000000000047 -:10F9C0000000000000000000000000000000000037 -:10F9D0000000000000000000000000000000000027 -:10F9E0000000000000000000000000000000000017 -:10F9F0000000000000000000000000000000000007 -:10FA000000000000000000000000000000000000F6 -:10FA100000000000000000000000000000000000E6 -:10FA200000000000000000000000000000000000D6 -:10FA300000000000000000000000000000000000C6 -:10FA400000000000000000000000000000000000B6 -:10FA500000000000000000000000000000000000A6 -:10FA60000000000000000000000000000000000096 -:10FA70000000000000000000000000000000000086 -:10FA80000000000000000000000000000000000076 -:10FA90000000000000000000000000000000000066 -:10FAA0000000000000000000000000000000000056 -:10FAB0000000000000000000000000000000000046 -:10FAC0000000000000000000000000000000000036 -:10FAD0000000000000000000000000000000000026 -:10FAE0000000000000000000000000000000000016 -:10FAF0000000000000000000000000000000000006 -:10FB000000000000000000000000000000000000F5 -:10FB100000000000000000000000000000000000E5 -:10FB200000000000000000000000000000000000D5 -:10FB300000000000000000000000000000000000C5 -:10FB400000000000000000000000000000000000B5 -:10FB500000000000000000000000000000000000A5 -:10FB60000000000000000000000000000000000095 -:10FB70000000000000000000000000000000000085 -:10FB80000000000000000000000000000000000075 -:10FB90000000000000000000000000000000000065 -:10FBA0000000000000000000000000000000000055 -:10FBB0000000000000000000000000000000000045 -:10FBC0000000000000000000000000000000000035 -:10FBD0000000000000000000000000000000000025 -:10FBE0000000000000000000000000000000000015 -:10FBF0000000000000000000000000000000000005 -:10FC000000000000000000000000000000000000F4 -:10FC100000000000000000000000000000000000E4 -:10FC200000000000000000000000000000000000D4 -:10FC300000000000000000000000000000000000C4 -:10FC400000000000000000000000000000000000B4 -:10FC500000000000000000000000000000000000A4 -:10FC60000000000000000000000000000000000094 -:10FC70000000000000000000000000000000000084 -:10FC80000000000000000000000000000000000074 -:10FC90000000000000000000000000000000000064 -:10FCA0000000000000000000000000000000000054 -:10FCB0000000000000000000000000000000000044 -:10FCC0000000000000000000000000000000000034 -:10FCD0000000000000000000000000000000000024 -:10FCE0000000000000000000000000000000000014 -:10FCF0000000000000000000000000000000000004 -:10FD000000000000000000000000000000000000F3 -:10FD100000000000000000000000000000000000E3 -:10FD200000000000000000000000000000000000D3 -:10FD300000000000000000000000000000000000C3 -:10FD400000000000000000000000000000000000B3 -:10FD500000000000000000000000000000000000A3 -:10FD60000000000000000000000000000000000093 -:10FD70000000000000000000000000000000000083 -:10FD80000000000000000000000000000000000073 -:10FD90000000000000000000000000000000000063 -:10FDA0000000000000000000000000000000000053 -:10FDB0000000000000000000000000000000000043 -:10FDC0000000000000000000000000000000000033 -:10FDD0000000000000000000000000000000000023 -:10FDE0000000000000000000000000000000000013 -:10FDF0000000000000000000000000000000000003 -:10FE000000000000000000000000000000000000F2 -:10FE100000000000000000000000000000000000E2 -:10FE200000000000000000000000000000000000D2 -:10FE300000000000000000000000000000000000C2 -:10FE400000000000000000000000000000000000B2 -:10FE500000000000000000000000000000000000A2 -:10FE60000000000000000000000000000000000092 -:10FE70000000000000000000000000000000000082 -:10FE80000000000000000000000000000000000072 -:10FE90000000000000000000000000000000000062 -:10FEA0000000000000000000000000000000000052 -:10FEB0000000000000000000000000000000000042 -:10FEC0000000000000000000000000000000000032 -:10FED0000000000000000000000000000000000022 -:10FEE0000000000000000000000000000000000012 -:10FEF0000000000000000000000000000000000002 -:10FF000000000000000000000000000000000000F1 -:10FF100000000000000000000000000000000000E1 -:10FF200000000000000000000000000000000000D1 -:10FF300000000000000000000000000000000000C1 -:10FF400000000000000000000000000000000000B1 -:10FF500000000000000000000000000000000000A1 -:10FF60000000000000000000000000000000000091 -:10FF70000000000000000000000000000000000081 -:10FF80000000000000000000000000000000000071 -:10FF90000000000000000000000000000000000061 -:10FFA0000000000000000000000000000000000051 -:10FFB0000000000000000000000000000000000041 -:10FFC0000000000000000000000000000000000031 -:10FFD0000000000000000000000000000000000021 -:10FFE0000000000000000000000000000000000011 -:10FFF0000000000000000000000000000000000001 -:02000004620395 -:1000000000000000000000000000000000000000F0 -:1000100000000000000000000000000000000000E0 -:1000200000000000000000000000000000000000D0 -:1000300000000000000000000000000000000000C0 -:1000400000000000000000000000000000000000B0 -:1000500000000000000000000000000000000000A0 -:100060000000000000000000000000000000000090 -:100070000000000000000000000000000000000080 -:100080000000000000000000000000000000000070 -:100090000000000000000000000000000000000060 -:1000A0000000000000000000000000000000000050 -:1000B0000000000000000000000000000000000040 -:1000C0000000000000000000000000000000000030 -:1000D0000000000000000000000000000000000020 -:1000E0000000000000000000000000000000000010 -:1000F0000000000000000000000000000000000000 -:1001000000000000000000000000000000000000EF -:1001100000000000000000000000000000000000DF -:1001200000000000000000000000000000000000CF -:1001300000000000000000000000000000000000BF -:1001400000000000000000000000000000000000AF -:10015000000000000000000000000000000000009F -:10016000000000000000000000000000000000008F -:10017000000000000000000000000000000000007F -:10018000000000000000000000000000000000006F -:10019000000000000000000000000000000000005F -:1001A000000000000000000000000000000000004F -:1001B000000000000000000000000000000000003F -:1001C000000000000000000000000000000000002F -:1001D000000000000000000000000000000000001F -:1001E000000000000000000000000000000000000F -:1001F00000000000000000000000000000000000FF -:1002000000000000000000000000000000000000EE -:1002100000000000000000000000000000000000DE -:1002200000000000000000000000000000000000CE -:1002300000000000000000000000000000000000BE -:1002400000000000000000000000000000000000AE -:10025000000000000000000000000000000000009E -:10026000000000000000000000000000000000008E -:10027000000000000000000000000000000000007E -:10028000000000000000000000000000000000006E -:10029000000000000000000000000000000000005E -:1002A000000000000000000000000000000000004E -:1002B000000000000000000000000000000000003E -:1002C000000000000000000000000000000000002E -:1002D000000000000000000000000000000000001E -:1002E000000000000000000000000000000000000E -:1002F00000000000000000000000000000000000FE -:1003000000000000000000000000000000000000ED -:1003100000000000000000000000000000000000DD -:1003200000000000000000000000000000000000CD -:1003300000000000000000000000000000000000BD -:1003400000000000000000000000000000000000AD -:10035000000000000000000000000000000000009D -:10036000000000000000000000000000000000008D -:10037000000000000000000000000000000000007D -:10038000000000000000000000000000000000006D -:10039000000000000000000000000000000000005D -:1003A000000000000000000000000000000000004D -:1003B000000000000000000000000000000000003D -:1003C000000000000000000000000000000000002D -:1003D000000000000000000000000000000000001D -:1003E000000000000000000000000000000000000D -:1003F00000000000000000000000000000000000FD -:1004000000000000000000000000000000000000EC -:1004100000000000000000000000000000000000DC -:1004200000000000000000000000000000000000CC -:1004300000000000000000000000000000000000BC -:1004400000000000000000000000000000000000AC -:10045000000000000000000000000000000000009C -:10046000000000000000000000000000000000008C -:10047000000000000000000000000000000000007C -:10048000000000000000000000000000000000006C -:10049000000000000000000000000000000000005C -:1004A000000000000000000000000000000000004C -:1004B000000000000000000000000000000000003C -:1004C000000000000000000000000000000000002C -:1004D000000000000000000000000000000000001C -:1004E000000000000000000000000000000000000C -:1004F00000000000000000000000000000000000FC -:1005000000000000000000000000000000000000EB -:1005100000000000000000000000000000000000DB -:1005200000000000000000000000000000000000CB -:1005300000000000000000000000000000000000BB -:1005400000000000000000000000000000000000AB -:10055000000000000000000000000000000000009B -:10056000000000000000000000000000000000008B -:10057000000000000000000000000000000000007B -:10058000000000000000000000000000000000006B -:10059000000000000000000000000000000000005B -:1005A000000000000000000000000000000000004B -:1005B000000000000000000000000000000000003B -:1005C000000000000000000000000000000000002B -:1005D000000000000000000000000000000000001B -:1005E000000000000000000000000000000000000B -:1005F00000000000000000000000000000000000FB -:1006000000000000000000000000000000000000EA -:1006100000000000000000000000000000000000DA -:1006200000000000000000000000000000000000CA -:1006300000000000000000000000000000000000BA -:1006400000000000000000000000000000000000AA -:10065000000000000000000000000000000000009A -:10066000000000000000000000000000000000008A -:10067000000000000000000000000000000000007A -:10068000000000000000000000000000000000006A -:10069000000000000000000000000000000000005A -:1006A000000000000000000000000000000000004A -:1006B000000000000000000000000000000000003A -:1006C000000000000000000000000000000000002A -:1006D000000000000000000000000000000000001A -:1006E000000000000000000000000000000000000A -:1006F00000000000000000000000000000000000FA -:1007000000000000000000000000000000000000E9 -:1007100000000000000000000000000000000000D9 -:1007200000000000000000000000000000000000C9 -:1007300000000000000000000000000000000000B9 -:1007400000000000000000000000000000000000A9 -:100750000000000000000000000000000000000099 -:100760000000000000000000000000000000000089 -:100770000000000000000000000000000000000079 -:100780000000000000000000000000000000000069 -:100790000000000000000000000000000000000059 -:1007A0000000000000000000000000000000000049 -:1007B0000000000000000000000000000000000039 -:1007C0000000000000000000000000000000000029 -:1007D0000000000000000000000000000000000019 -:1007E0000000000000000000000000000000000009 -:1007F00000000000000000000000000000000000F9 -:1008000000000000000000000000000000000000E8 -:1008100000000000000000000000000000000000D8 -:1008200000000000000000000000000000000000C8 -:1008300000000000000000000000000000000000B8 -:1008400000000000000000000000000000000000A8 -:100850000000000000000000000000000000000098 -:100860000000000000000000000000000000000088 -:100870000000000000000000000000000000000078 -:100880000000000000000000000000000000000068 -:100890000000000000000000000000000000000058 -:1008A0000000000000000000000000000000000048 -:1008B0000000000000000000000000000000000038 -:1008C0000000000000000000000000000000000028 -:1008D0000000000000000000000000000000000018 -:1008E0000000000000000000000000000000000008 -:1008F00000000000000000000000000000000000F8 -:1009000000000000000000000000000000000000E7 -:1009100000000000000000000000000000000000D7 -:1009200000000000000000000000000000000000C7 -:1009300000000000000000000000000000000000B7 -:1009400000000000000000000000000000000000A7 -:100950000000000000000000000000000000000097 -:100960000000000000000000000000000000000087 -:100970000000000000000000000000000000000077 -:100980000000000000000000000000000000000067 -:100990000000000000000000000000000000000057 -:1009A0000000000000000000000000000000000047 -:1009B0000000000000000000000000000000000037 -:1009C0000000000000000000000000000000000027 -:1009D0000000000000000000000000000000000017 -:1009E0000000000000000000000000000000000007 -:1009F00000000000000000000000000000000000F7 -:100A000000000000000000000000000000000000E6 -:100A100000000000000000000000000000000000D6 -:100A200000000000000000000000000000000000C6 -:100A300000000000000000000000000000000000B6 -:100A400000000000000000000000000000000000A6 -:100A50000000000000000000000000000000000096 -:100A60000000000000000000000000000000000086 -:100A70000000000000000000000000000000000076 -:100A80000000000000000000000000000000000066 -:100A90000000000000000000000000000000000056 -:100AA0000000000000000000000000000000000046 -:100AB0000000000000000000000000000000000036 -:100AC0000000000000000000000000000000000026 -:100AD0000000000000000000000000000000000016 -:100AE0000000000000000000000000000000000006 -:100AF00000000000000000000000000000000000F6 -:100B000000000000000000000000000000000000E5 -:100B100000000000000000000000000000000000D5 -:100B200000000000000000000000000000000000C5 -:100B300000000000000000000000000000000000B5 -:100B400000000000000000000000000000000000A5 -:100B50000000000000000000000000000000000095 -:100B60000000000000000000000000000000000085 -:100B70000000000000000000000000000000000075 -:100B80000000000000000000000000000000000065 -:100B90000000000000000000000000000000000055 -:100BA0000000000000000000000000000000000045 -:100BB0000000000000000000000000000000000035 -:100BC0000000000000000000000000000000000025 -:100BD0000000000000000000000000000000000015 -:100BE0000000000000000000000000000000000005 -:100BF00000000000000000000000000000000000F5 -:100C000000000000000000000000000000000000E4 -:100C100000000000000000000000000000000000D4 -:100C200000000000000000000000000000000000C4 -:100C300000000000000000000000000000000000B4 -:100C400000000000000000000000000000000000A4 -:100C50000000000000000000000000000000000094 -:100C60000000000000000000000000000000000084 -:100C70000000000000000000000000000000000074 -:100C80000000000000000000000000000000000064 -:100C90000000000000000000000000000000000054 -:100CA0000000000000000000000000000000000044 -:100CB0000000000000000000000000000000000034 -:100CC0000000000000000000000000000000000024 -:100CD0000000000000000000000000000000000014 -:100CE0000000000000000000000000000000000004 -:100CF00000000000000000000000000000000000F4 -:100D000000000000000000000000000000000000E3 -:100D100000000000000000000000000000000000D3 -:100D200000000000000000000000000000000000C3 -:100D300000000000000000000000000000000000B3 -:100D400000000000000000000000000000000000A3 -:100D50000000000000000000000000000000000093 -:100D60000000000000000000000000000000000083 -:100D70000000000000000000000000000000000073 -:100D80000000000000000000000000000000000063 -:100D90000000000000000000000000000000000053 -:100DA0000000000000000000000000000000000043 -:100DB0000000000000000000000000000000000033 -:100DC0000000000000000000000000000000000023 -:100DD0000000000000000000000000000000000013 -:100DE0000000000000000000000000000000000003 -:100DF00000000000000000000000000000000000F3 -:100E000000000000000000000000000000000000E2 -:100E100000000000000000000000000000000000D2 -:100E200000000000000000000000000000000000C2 -:100E300000000000000000000000000000000000B2 -:100E400000000000000000000000000000000000A2 -:100E50000000000000000000000000000000000092 -:100E60000000000000000000000000000000000082 -:100E70000000000000000000000000000000000072 -:100E80000000000000000000000000000000000062 -:100E90000000000000000000000000000000000052 -:100EA0000000000000000000000000000000000042 -:100EB0000000000000000000000000000000000032 -:100EC0000000000000000000000000000000000022 -:100ED0000000000000000000000000000000000012 -:100EE0000000000000000000000000000000000002 -:100EF00000000000000000000000000000000000F2 -:100F000000000000000000000000000000000000E1 -:100F100000000000000000000000000000000000D1 -:100F200000000000000000000000000000000000C1 -:100F300000000000000000000000000000000000B1 -:100F400000000000000000000000000000000000A1 -:100F50000000000000000000000000000000000091 -:100F60000000000000000000000000000000000081 -:100F70000000000000000000000000000000000071 -:100F80000000000000000000000000000000000061 -:100F90000000000000000000000000000000000051 -:100FA0000000000000000000000000000000000041 -:100FB0000000000000000000000000000000000031 -:100FC0000000000000000000000000000000000021 -:100FD0000000000000000000000000000000000011 -:100FE0000000000000000000000000000000000001 -:100FF00000000000000000000000000000000000F1 -:1010000000000000000000000000000000000000E0 -:1010100000000000000000000000000000000000D0 -:1010200000000000000000000000000000000000C0 -:1010300000000000000000000000000000000000B0 -:1010400000000000000000000000000000000000A0 -:101050000000000000000000000000000000000090 -:101060000000000000000000000000000000000080 -:101070000000000000000000000000000000000070 -:101080000000000000000000000000000000000060 -:101090000000000000000000000000000000000050 -:1010A0000000000000000000000000000000000040 -:1010B0000000000000000000000000000000000030 -:1010C0000000000000000000000000000000000020 -:1010D0000000000000000000000000000000000010 -:1010E0000000000000000000000000000000000000 -:1010F00000000000000000000000000000000000F0 -:1011000000000000000000000000000000000000DF -:1011100000000000000000000000000000000000CF -:1011200000000000000000000000000000000000BF -:1011300000000000000000000000000000000000AF -:10114000000000000000000000000000000000009F -:10115000000000000000000000000000000000008F -:10116000000000000000000000000000000000007F -:10117000000000000000000000000000000000006F -:10118000000000000000000000000000000000005F -:10119000000000000000000000000000000000004F -:1011A000000000000000000000000000000000003F -:1011B000000000000000000000000000000000002F -:1011C000000000000000000000000000000000001F -:1011D000000000000000000000000000000000000F -:1011E00000000000000000000000000000000000FF -:1011F00000000000000000000000000000000000EF -:1012000000000000000000000000000000000000DE -:1012100000000000000000000000000000000000CE -:1012200000000000000000000000000000000000BE -:1012300000000000000000000000000000000000AE -:10124000000000000000000000000000000000009E -:10125000000000000000000000000000000000008E -:10126000000000000000000000000000000000007E -:10127000000000000000000000000000000000006E -:10128000000000000000000000000000000000005E -:10129000000000000000000000000000000000004E -:1012A000000000000000000000000000000000003E -:1012B000000000000000000000000000000000002E -:1012C000000000000000000000000000000000001E -:1012D000000000000000000000000000000000000E -:1012E00000000000000000000000000000000000FE -:1012F00000000000000000000000000000000000EE -:1013000000000000000000000000000000000000DD -:1013100000000000000000000000000000000000CD -:1013200000000000000000000000000000000000BD -:1013300000000000000000000000000000000000AD -:10134000000000000000000000000000000000009D -:10135000000000000000000000000000000000008D -:10136000000000000000000000000000000000007D -:10137000000000000000000000000000000000006D -:10138000000000000000000000000000000000005D -:10139000000000000000000000000000000000004D -:1013A000000000000000000000000000000000003D -:1013B000000000000000000000000000000000002D -:1013C000000000000000000000000000000000001D -:1013D000000000000000000000000000000000000D -:1013E00000000000000000000000000000000000FD -:1013F00000000000000000000000000000000000ED -:1014000000000000000000000000000000000000DC -:1014100000000000000000000000000000000000CC -:1014200000000000000000000000000000000000BC -:1014300000000000000000000000000000000000AC -:10144000000000000000000000000000000000009C -:10145000000000000000000000000000000000008C -:10146000000000000000000000000000000000007C -:10147000000000000000000000000000000000006C -:10148000000000000000000000000000000000005C -:10149000000000000000000000000000000000004C -:1014A000000000000000000000000000000000003C -:1014B000000000000000000000000000000000002C -:1014C000000000000000000000000000000000001C -:1014D000000000000000000000000000000000000C -:1014E00000000000000000000000000000000000FC -:1014F00000000000000000000000000000000000EC -:1015000000000000000000000000000000000000DB -:1015100000000000000000000000000000000000CB -:1015200000000000000000000000000000000000BB -:1015300000000000000000000000000000000000AB -:10154000000000000000000000000000000000009B -:10155000000000000000000000000000000000008B -:10156000000000000000000000000000000000007B -:10157000000000000000000000000000000000006B -:10158000000000000000000000000000000000005B -:10159000000000000000000000000000000000004B -:1015A000000000000000000000000000000000003B -:1015B000000000000000000000000000000000002B -:1015C000000000000000000000000000000000001B -:1015D000000000000000000000000000000000000B -:1015E00000000000000000000000000000000000FB -:1015F00000000000000000000000000000000000EB -:1016000000000000000000000000000000000000DA -:1016100000000000000000000000000000000000CA -:1016200000000000000000000000000000000000BA -:1016300000000000000000000000000000000000AA -:10164000000000000000000000000000000000009A -:10165000000000000000000000000000000000008A -:10166000000000000000000000000000000000007A -:10167000000000000000000000000000000000006A -:10168000000000000000000000000000000000005A -:10169000000000000000000000000000000000004A -:1016A000000000000000000000000000000000003A -:1016B000000000000000000000000000000000002A -:1016C000000000000000000000000000000000001A -:1016D000000000000000000000000000000000000A -:1016E00000000000000000000000000000000000FA -:1016F00000000000000000000000000000000000EA -:1017000000000000000000000000000000000000D9 -:1017100000000000000000000000000000000000C9 -:1017200000000000000000000000000000000000B9 -:1017300000000000000000000000000000000000A9 -:101740000000000000000000000000000000000099 -:101750000000000000000000000000000000000089 -:101760000000000000000000000000000000000079 -:101770000000000000000000000000000000000069 -:101780000000000000000000000000000000000059 -:101790000000000000000000000000000000000049 -:1017A0000000000000000000000000000000000039 -:1017B0000000000000000000000000000000000029 -:1017C0000000000000000000000000000000000019 -:1017D0000000000000000000000000000000000009 -:1017E00000000000000000000000000000000000F9 -:1017F00000000000000000000000000000000000E9 -:1018000000000000000000000000000000000000D8 -:1018100000000000000000000000000000000000C8 -:1018200000000000000000000000000000000000B8 -:1018300000000000000000000000000000000000A8 -:101840000000000000000000000000000000000098 -:101850000000000000000000000000000000000088 -:101860000000000000000000000000000000000078 -:101870000000000000000000000000000000000068 -:101880000000000000000000000000000000000058 -:101890000000000000000000000000000000000048 -:1018A0000000000000000000000000000000000038 -:1018B0000000000000000000000000000000000028 -:1018C0000000000000000000000000000000000018 -:1018D0000000000000000000000000000000000008 -:1018E00000000000000000000000000000000000F8 -:1018F00000000000000000000000000000000000E8 -:1019000000000000000000000000000000000000D7 -:1019100000000000000000000000000000000000C7 -:1019200000000000000000000000000000000000B7 -:1019300000000000000000000000000000000000A7 -:101940000000000000000000000000000000000097 -:101950000000000000000000000000000000000087 -:101960000000000000000000000000000000000077 -:101970000000000000000000000000000000000067 -:101980000000000000000000000000000000000057 -:101990000000000000000000000000000000000047 -:1019A0000000000000000000000000000000000037 -:1019B0000000000000000000000000000000000027 -:1019C0000000000000000000000000000000000017 -:1019D0000000000000000000000000000000000007 -:1019E00000000000000000000000000000000000F7 -:1019F00000000000000000000000000000000000E7 -:101A000000000000000000000000000000000000D6 -:101A100000000000000000000000000000000000C6 -:101A200000000000000000000000000000000000B6 -:101A300000000000000000000000000000000000A6 -:101A40000000000000000000000000000000000096 -:101A50000000000000000000000000000000000086 -:101A60000000000000000000000000000000000076 -:101A70000000000000000000000000000000000066 -:101A80000000000000000000000000000000000056 -:101A90000000000000000000000000000000000046 -:101AA0000000000000000000000000000000000036 -:101AB0000000000000000000000000000000000026 -:101AC0000000000000000000000000000000000016 -:101AD0000000000000000000000000000000000006 -:101AE00000000000000000000000000000000000F6 -:101AF00000000000000000000000000000000000E6 -:101B000000000000000000000000000000000000D5 -:101B100000000000000000000000000000000000C5 -:101B200000000000000000000000000000000000B5 -:101B300000000000000000000000000000000000A5 -:101B40000000000000000000000000000000000095 -:101B50000000000000000000000000000000000085 -:101B60000000000000000000000000000000000075 -:101B70000000000000000000000000000000000065 -:101B80000000000000000000000000000000000055 -:101B90000000000000000000000000000000000045 -:101BA0000000000000000000000000000000000035 -:101BB0000000000000000000000000000000000025 -:101BC0000000000000000000000000000000000015 -:101BD0000000000000000000000000000000000005 -:101BE00000000000000000000000000000000000F5 -:101BF00000000000000000000000000000000000E5 -:101C000000000000000000000000000000000000D4 -:101C100000000000000000000000000000000000C4 -:101C200000000000000000000000000000000000B4 -:101C300000000000000000000000000000000000A4 -:101C40000000000000000000000000000000000094 -:101C50000000000000000000000000000000000084 -:101C60000000000000000000000000000000000074 -:101C70000000000000000000000000000000000064 -:101C80000000000000000000000000000000000054 -:101C90000000000000000000000000000000000044 -:101CA0000000000000000000000000000000000034 -:101CB0000000000000000000000000000000000024 -:101CC0000000000000000000000000000000000014 -:101CD0000000000000000000000000000000000004 -:101CE00000000000000000000000000000000000F4 -:101CF00000000000000000000000000000000000E4 -:101D000000000000000000000000000000000000D3 -:101D100000000000000000000000000000000000C3 -:101D200000000000000000000000000000000000B3 -:101D300000000000000000000000000000000000A3 -:101D40000000000000000000000000000000000093 -:101D50000000000000000000000000000000000083 -:101D60000000000000000000000000000000000073 -:101D70000000000000000000000000000000000063 -:101D80000000000000000000000000000000000053 -:101D90000000000000000000000000000000000043 -:101DA0000000000000000000000000000000000033 -:101DB0000000000000000000000000000000000023 -:101DC0000000000000000000000000000000000013 -:101DD0000000000000000000000000000000000003 -:101DE00000000000000000000000000000000000F3 -:101DF00000000000000000000000000000000000E3 -:101E000000000000000000000000000000000000D2 -:101E100000000000000000000000000000000000C2 -:101E200000000000000000000000000000000000B2 -:101E300000000000000000000000000000000000A2 -:101E40000000000000000000000000000000000092 -:101E50000000000000000000000000000000000082 -:101E60000000000000000000000000000000000072 -:101E70000000000000000000000000000000000062 -:101E80000000000000000000000000000000000052 -:101E90000000000000000000000000000000000042 -:101EA0000000000000000000000000000000000032 -:101EB0000000000000000000000000000000000022 -:101EC0000000000000000000000000000000000012 -:101ED0000000000000000000000000000000000002 -:101EE00000000000000000000000000000000000F2 -:101EF00000000000000000000000000000000000E2 -:101F000000000000000000000000000000000000D1 -:101F100000000000000000000000000000000000C1 -:101F200000000000000000000000000000000000B1 -:101F300000000000000000000000000000000000A1 -:101F40000000000000000000000000000000000091 -:101F50000000000000000000000000000000000081 -:101F60000000000000000000000000000000000071 -:101F70000000000000000000000000000000000061 -:101F80000000000000000000000000000000000051 -:101F90000000000000000000000000000000000041 -:101FA0000000000000000000000000000000000031 -:101FB0000000000000000000000000000000000021 -:101FC0000000000000000000000000000000000011 -:101FD0000000000000000000000000000000000001 -:101FE00000000000000000000000000000000000F1 -:101FF00000000000000000000000000000000000E1 -:1020000000000000000000000000000000000000D0 -:1020100000000000000000000000000000000000C0 -:1020200000000000000000000000000000000000B0 -:1020300000000000000000000000000000000000A0 -:102040000000000000000000000000000000000090 -:102050000000000000000000000000000000000080 -:102060000000000000000000000000000000000070 -:102070000000000000000000000000000000000060 -:102080000000000000000000000000000000000050 -:102090000000000000000000000000000000000040 -:1020A0000000000000000000000000000000000030 -:1020B0000000000000000000000000000000000020 -:1020C0000000000000000000000000000000000010 -:1020D0000000000000000000000000000000000000 -:1020E00000000000000000000000000000000000F0 -:1020F00000000000000000000000000000000000E0 -:1021000000000000000000000000000000000000CF -:1021100000000000000000000000000000000000BF -:1021200000000000000000000000000000000000AF -:10213000000000000000000000000000000000009F -:10214000000000000000000000000000000000008F -:10215000000000000000000000000000000000007F -:10216000000000000000000000000000000000006F -:10217000000000000000000000000000000000005F -:10218000000000000000000000000000000000004F -:10219000000000000000000000000000000000003F -:1021A000000000000000000000000000000000002F -:1021B000000000000000000000000000000000001F -:1021C000000000000000000000000000000000000F -:1021D00000000000000000000000000000000000FF -:1021E00000000000000000000000000000000000EF -:1021F00000000000000000000000000000000000DF -:1022000000000000000000000000000000000000CE -:1022100000000000000000000000000000000000BE -:1022200000000000000000000000000000000000AE -:10223000000000000000000000000000000000009E -:10224000000000000000000000000000000000008E -:10225000000000000000000000000000000000007E -:10226000000000000000000000000000000000006E -:10227000000000000000000000000000000000005E -:10228000000000000000000000000000000000004E -:10229000000000000000000000000000000000003E -:1022A000000000000000000000000000000000002E -:1022B000000000000000000000000000000000001E -:1022C000000000000000000000000000000000000E -:1022D00000000000000000000000000000000000FE -:1022E00000000000000000000000000000000000EE -:1022F00000000000000000000000000000000000DE -:1023000000000000000000000000000000000000CD -:1023100000000000000000000000000000000000BD -:1023200000000000000000000000000000000000AD -:10233000000000000000000000000000000000009D -:10234000000000000000000000000000000000008D -:10235000000000000000000000000000000000007D -:10236000000000000000000000000000000000006D -:10237000000000000000000000000000000000005D -:10238000000000000000000000000000000000004D -:10239000000000000000000000000000000000003D -:1023A000000000000000000000000000000000002D -:1023B000000000000000000000000000000000001D -:1023C000000000000000000000000000000000000D -:1023D00000000000000000000000000000000000FD -:1023E00000000000000000000000000000000000ED -:1023F00000000000000000000000000000000000DD -:1024000000000000000000000000000000000000CC -:1024100000000000000000000000000000000000BC -:1024200000000000000000000000000000000000AC -:10243000000000000000000000000000000000009C -:10244000000000000000000000000000000000008C -:10245000000000000000000000000000000000007C -:10246000000000000000000000000000000000006C -:10247000000000000000000000000000000000005C -:10248000000000000000000000000000000000004C -:10249000000000000000000000000000000000003C -:1024A000000000000000000000000000000000002C -:1024B000000000000000000000000000000000001C -:1024C000000000000000000000000000000000000C -:1024D00000000000000000000000000000000000FC -:1024E00000000000000000000000000000000000EC -:1024F00000000000000000000000000000000000DC -:1025000000000000000000000000000000000000CB -:1025100000000000000000000000000000000000BB -:1025200000000000000000000000000000000000AB -:10253000000000000000000000000000000000009B -:10254000000000000000000000000000000000008B -:10255000000000000000000000000000000000007B -:10256000000000000000000000000000000000006B -:10257000000000000000000000000000000000005B -:10258000000000000000000000000000000000004B -:10259000000000000000000000000000000000003B -:1025A000000000000000000000000000000000002B -:1025B000000000000000000000000000000000001B -:1025C000000000000000000000000000000000000B -:1025D00000000000000000000000000000000000FB -:1025E00000000000000000000000000000000000EB -:1025F00000000000000000000000000000000000DB -:1026000000000000000000000000000000000000CA -:1026100000000000000000000000000000000000BA -:1026200000000000000000000000000000000000AA -:10263000000000000000000000000000000000009A -:10264000000000000000000000000000000000008A -:10265000000000000000000000000000000000007A -:10266000000000000000000000000000000000006A -:10267000000000000000000000000000000000005A -:10268000000000000000000000000000000000004A -:10269000000000000000000000000000000000003A -:1026A000000000000000000000000000000000002A -:1026B000000000000000000000000000000000001A -:1026C000000000000000000000000000000000000A -:1026D00000000000000000000000000000000000FA -:1026E00000000000000000000000000000000000EA -:1026F00000000000000000000000000000000000DA -:1027000000000000000000000000000000000000C9 -:1027100000000000000000000000000000000000B9 -:1027200000000000000000000000000000000000A9 -:102730000000000000000000000000000000000099 -:102740000000000000000000000000000000000089 -:102750000000000000000000000000000000000079 -:102760000000000000000000000000000000000069 -:102770000000000000000000000000000000000059 -:102780000000000000000000000000000000000049 -:102790000000000000000000000000000000000039 -:1027A0000000000000000000000000000000000029 -:1027B0000000000000000000000000000000000019 -:1027C0000000000000000000000000000000000009 -:1027D00000000000000000000000000000000000F9 -:1027E00000000000000000000000000000000000E9 -:1027F00000000000000000000000000000000000D9 -:1028000000000000000000000000000000000000C8 -:1028100000000000000000000000000000000000B8 -:1028200000000000000000000000000000000000A8 -:102830000000000000000000000000000000000098 -:102840000000000000000000000000000000000088 -:102850000000000000000000000000000000000078 -:102860000000000000000000000000000000000068 -:102870000000000000000000000000000000000058 -:102880000000000000000000000000000000000048 -:102890000000000000000000000000000000000038 -:1028A0000000000000000000000000000000000028 -:1028B0000000000000000000000000000000000018 -:1028C0000000000000000000000000000000000008 -:1028D00000000000000000000000000000000000F8 -:1028E00000000000000000000000000000000000E8 -:1028F00000000000000000000000000000000000D8 -:1029000000000000000000000000000000000000C7 -:1029100000000000000000000000000000000000B7 -:1029200000000000000000000000000000000000A7 -:102930000000000000000000000000000000000097 -:102940000000000000000000000000000000000087 -:102950000000000000000000000000000000000077 -:102960000000000000000000000000000000000067 -:102970000000000000000000000000000000000057 -:102980000000000000000000000000000000000047 -:102990000000000000000000000000000000000037 -:1029A0000000000000000000000000000000000027 -:1029B0000000000000000000000000000000000017 -:1029C0000000000000000000000000000000000007 -:1029D00000000000000000000000000000000000F7 -:1029E00000000000000000000000000000000000E7 -:1029F00000000000000000000000000000000000D7 -:102A000000000000000000000000000000000000C6 -:102A100000000000000000000000000000000000B6 -:102A200000000000000000000000000000000000A6 -:102A30000000000000000000000000000000000096 -:102A40000000000000000000000000000000000086 -:102A50000000000000000000000000000000000076 -:102A60000000000000000000000000000000000066 -:102A70000000000000000000000000000000000056 -:102A80000000000000000000000000000000000046 -:102A90000000000000000000000000000000000036 -:102AA0000000000000000000000000000000000026 -:102AB0000000000000000000000000000000000016 -:102AC0000000000000000000000000000000000006 -:102AD00000000000000000000000000000000000F6 -:102AE00000000000000000000000000000000000E6 -:102AF00000000000000000000000000000000000D6 -:102B000000000000000000000000000000000000C5 -:102B100000000000000000000000000000000000B5 -:102B200000000000000000000000000000000000A5 -:102B30000000000000000000000000000000000095 -:102B40000000000000000000000000000000000085 -:102B50000000000000000000000000000000000075 -:102B60000000000000000000000000000000000065 -:102B70000000000000000000000000000000000055 -:102B80000000000000000000000000000000000045 -:102B90000000000000000000000000000000000035 -:102BA0000000000000000000000000000000000025 -:102BB0000000000000000000000000000000000015 -:102BC0000000000000000000000000000000000005 -:102BD00000000000000000000000000000000000F5 -:102BE00000000000000000000000000000000000E5 -:102BF00000000000000000000000000000000000D5 -:102C000000000000000000000000000000000000C4 -:102C100000000000000000000000000000000000B4 -:102C200000000000000000000000000000000000A4 -:102C30000000000000000000000000000000000094 -:102C40000000000000000000000000000000000084 -:102C50000000000000000000000000000000000074 -:102C60000000000000000000000000000000000064 -:102C70000000000000000000000000000000000054 -:102C80000000000000000000000000000000000044 -:102C90000000000000000000000000000000000034 -:102CA0000000000000000000000000000000000024 -:102CB0000000000000000000000000000000000014 -:102CC0000000000000000000000000000000000004 -:102CD00000000000000000000000000000000000F4 -:102CE00000000000000000000000000000000000E4 -:102CF00000000000000000000000000000000000D4 -:102D000000000000000000000000000000000000C3 -:102D100000000000000000000000000000000000B3 -:102D200000000000000000000000000000000000A3 -:102D30000000000000000000000000000000000093 -:102D40000000000000000000000000000000000083 -:102D50000000000000000000000000000000000073 -:102D60000000000000000000000000000000000063 -:102D70000000000000000000000000000000000053 -:102D80000000000000000000000000000000000043 -:102D90000000000000000000000000000000000033 -:102DA0000000000000000000000000000000000023 -:102DB0000000000000000000000000000000000013 -:102DC0000000000000000000000000000000000003 -:102DD00000000000000000000000000000000000F3 -:102DE00000000000000000000000000000000000E3 -:102DF00000000000000000000000000000000000D3 -:102E000000000000000000000000000000000000C2 -:102E100000000000000000000000000000000000B2 -:102E200000000000000000000000000000000000A2 -:102E30000000000000000000000000000000000092 -:102E40000000000000000000000000000000000082 -:102E50000000000000000000000000000000000072 -:102E60000000000000000000000000000000000062 -:102E70000000000000000000000000000000000052 -:102E80000000000000000000000000000000000042 -:102E90000000000000000000000000000000000032 -:102EA0000000000000000000000000000000000022 -:102EB0000000000000000000000000000000000012 -:102EC0000000000000000000000000000000000002 -:102ED00000000000000000000000000000000000F2 -:102EE00000000000000000000000000000000000E2 -:102EF00000000000000000000000000000000000D2 -:102F000000000000000000000000000000000000C1 -:102F100000000000000000000000000000000000B1 -:102F200000000000000000000000000000000000A1 -:102F30000000000000000000000000000000000091 -:102F40000000000000000000000000000000000081 -:102F50000000000000000000000000000000000071 -:102F60000000000000000000000000000000000061 -:102F70000000000000000000000000000000000051 -:102F80000000000000000000000000000000000041 -:102F90000000000000000000000000000000000031 -:102FA0000000000000000000000000000000000021 -:102FB0000000000000000000000000000000000011 -:102FC0000000000000000000000000000000000001 -:102FD00000000000000000000000000000000000F1 -:102FE00000000000000000000000000000000000E1 -:102FF00000000000000000000000000000000000D1 -:1030000000000000000000000000000000000000C0 -:1030100000000000000000000000000000000000B0 -:1030200000000000000000000000000000000000A0 -:103030000000000000000000000000000000000090 -:103040000000000000000000000000000000000080 -:103050000000000000000000000000000000000070 -:103060000000000000000000000000000000000060 -:103070000000000000000000000000000000000050 -:103080000000000000000000000000000000000040 -:103090000000000000000000000000000000000030 -:1030A0000000000000000000000000000000000020 -:1030B0000000000000000000000000000000000010 -:1030C0000000000000000000000000000000000000 -:1030D00000000000000000000000000000000000F0 -:1030E00000000000000000000000000000000000E0 -:1030F00000000000000000000000000000000000D0 -:1031000000000000000000000000000000000000BF -:1031100000000000000000000000000000000000AF -:10312000000000000000000000000000000000009F -:10313000000000000000000000000000000000008F -:10314000000000000000000000000000000000007F -:10315000000000000000000000000000000000006F -:10316000000000000000000000000000000000005F -:10317000000000000000000000000000000000004F -:10318000000000000000000000000000000000003F -:10319000000000000000000000000000000000002F -:1031A000000000000000000000000000000000001F -:1031B000000000000000000000000000000000000F -:1031C00000000000000000000000000000000000FF -:1031D00000000000000000000000000000000000EF -:1031E00000000000000000000000000000000000DF -:1031F00000000000000000000000000000000000CF -:1032000000000000000000000000000000000000BE -:1032100000000000000000000000000000000000AE -:10322000000000000000000000000000000000009E -:10323000000000000000000000000000000000008E -:10324000000000000000000000000000000000007E -:10325000000000000000000000000000000000006E -:10326000000000000000000000000000000000005E -:10327000000000000000000000000000000000004E -:10328000000000000000000000000000000000003E -:10329000000000000000000000000000000000002E -:1032A000000000000000000000000000000000001E -:1032B000000000000000000000000000000000000E -:1032C00000000000000000000000000000000000FE -:1032D00000000000000000000000000000000000EE -:1032E00000000000000000000000000000000000DE -:1032F00000000000000000000000000000000000CE -:1033000000000000000000000000000000000000BD -:1033100000000000000000000000000000000000AD -:10332000000000000000000000000000000000009D -:10333000000000000000000000000000000000008D -:10334000000000000000000000000000000000007D -:10335000000000000000000000000000000000006D -:10336000000000000000000000000000000000005D -:10337000000000000000000000000000000000004D -:10338000000000000000000000000000000000003D -:10339000000000000000000000000000000000002D -:1033A000000000000000000000000000000000001D -:1033B000000000000000000000000000000000000D -:1033C00000000000000000000000000000000000FD -:1033D00000000000000000000000000000000000ED -:1033E00000000000000000000000000000000000DD -:1033F00000000000000000000000000000000000CD -:1034000000000000000000000000000000000000BC -:1034100000000000000000000000000000000000AC -:10342000000000000000000000000000000000009C -:10343000000000000000000000000000000000008C -:10344000000000000000000000000000000000007C -:10345000000000000000000000000000000000006C -:10346000000000000000000000000000000000005C -:10347000000000000000000000000000000000004C -:10348000000000000000000000000000000000003C -:10349000000000000000000000000000000000002C -:1034A000000000000000000000000000000000001C -:1034B000000000000000000000000000000000000C -:1034C00000000000000000000000000000000000FC -:1034D00000000000000000000000000000000000EC -:1034E00000000000000000000000000000000000DC -:1034F00000000000000000000000000000000000CC -:1035000000000000000000000000000000000000BB -:1035100000000000000000000000000000000000AB -:10352000000000000000000000000000000000009B -:10353000000000000000000000000000000000008B -:10354000000000000000000000000000000000007B -:10355000000000000000000000000000000000006B -:10356000000000000000000000000000000000005B -:10357000000000000000000000000000000000004B -:10358000000000000000000000000000000000003B -:10359000000000000000000000000000000000002B -:1035A000000000000000000000000000000000001B -:1035B000000000000000000000000000000000000B -:1035C00000000000000000000000000000000000FB -:1035D00000000000000000000000000000000000EB -:1035E00000000000000000000000000000000000DB -:1035F00000000000000000000000000000000000CB -:1036000000000000000000000000000000000000BA -:1036100000000000000000000000000000000000AA -:10362000000000000000000000000000000000009A -:10363000000000000000000000000000000000008A -:10364000000000000000000000000000000000007A -:10365000000000000000000000000000000000006A -:10366000000000000000000000000000000000005A -:10367000000000000000000000000000000000004A -:10368000000000000000000000000000000000003A -:10369000000000000000000000000000000000002A -:1036A000000000000000000000000000000000001A -:1036B000000000000000000000000000000000000A -:1036C00000000000000000000000000000000000FA -:1036D00000000000000000000000000000000000EA -:1036E00000000000000000000000000000000000DA -:1036F00000000000000000000000000000000000CA -:1037000000000000000000000000000000000000B9 -:1037100000000000000000000000000000000000A9 -:103720000000000000000000000000000000000099 -:103730000000000000000000000000000000000089 -:103740000000000000000000000000000000000079 -:103750000000000000000000000000000000000069 -:103760000000000000000000000000000000000059 -:103770000000000000000000000000000000000049 -:103780000000000000000000000000000000000039 -:103790000000000000000000000000000000000029 -:1037A0000000000000000000000000000000000019 -:1037B0000000000000000000000000000000000009 -:1037C00000000000000000000000000000000000F9 -:1037D00000000000000000000000000000000000E9 -:1037E00000000000000000000000000000000000D9 -:1037F00000000000000000000000000000000000C9 -:1038000000000000000000000000000000000000B8 -:1038100000000000000000000000000000000000A8 -:103820000000000000000000000000000000000098 -:103830000000000000000000000000000000000088 -:103840000000000000000000000000000000000078 -:103850000000000000000000000000000000000068 -:103860000000000000000000000000000000000058 -:103870000000000000000000000000000000000048 -:103880000000000000000000000000000000000038 -:103890000000000000000000000000000000000028 -:1038A0000000000000000000000000000000000018 -:1038B0000000000000000000000000000000000008 -:1038C00000000000000000000000000000000000F8 -:1038D00000000000000000000000000000000000E8 -:1038E00000000000000000000000000000000000D8 -:1038F00000000000000000000000000000000000C8 -:1039000000000000000000000000000000000000B7 -:1039100000000000000000000000000000000000A7 -:103920000000000000000000000000000000000097 -:103930000000000000000000000000000000000087 -:103940000000000000000000000000000000000077 -:103950000000000000000000000000000000000067 -:103960000000000000000000000000000000000057 -:103970000000000000000000000000000000000047 -:103980000000000000000000000000000000000037 -:103990000000000000000000000000000000000027 -:1039A0000000000000000000000000000000000017 -:1039B0000000000000000000000000000000000007 -:1039C00000000000000000000000000000000000F7 -:1039D00000000000000000000000000000000000E7 -:1039E00000000000000000000000000000000000D7 -:1039F00000000000000000000000000000000000C7 -:103A000000000000000000000000000000000000B6 -:103A100000000000000000000000000000000000A6 -:103A20000000000000000000000000000000000096 -:103A30000000000000000000000000000000000086 -:103A40000000000000000000000000000000000076 -:103A50000000000000000000000000000000000066 -:103A60000000000000000000000000000000000056 -:103A70000000000000000000000000000000000046 -:103A80000000000000000000000000000000000036 -:103A90000000000000000000000000000000000026 -:103AA0000000000000000000000000000000000016 -:103AB0000000000000000000000000000000000006 -:103AC00000000000000000000000000000000000F6 -:103AD00000000000000000000000000000000000E6 -:103AE00000000000000000000000000000000000D6 -:103AF00000000000000000000000000000000000C6 -:103B000000000000000000000000000000000000B5 -:103B100000000000000000000000000000000000A5 -:103B20000000000000000000000000000000000095 -:103B30000000000000000000000000000000000085 -:103B40000000000000000000000000000000000075 -:103B50000000000000000000000000000000000065 -:103B60000000000000000000000000000000000055 -:103B70000000000000000000000000000000000045 -:103B80000000000000000000000000000000000035 -:103B90000000000000000000000000000000000025 -:103BA0000000000000000000000000000000000015 -:103BB0000000000000000000000000000000000005 -:103BC00000000000000000000000000000000000F5 -:103BD00000000000000000000000000000000000E5 -:103BE00000000000000000000000000000000000D5 -:103BF00000000000000000000000000000000000C5 -:103C000000000000000000000000000000000000B4 -:103C100000000000000000000000000000000000A4 -:103C20000000000000000000000000000000000094 -:103C30000000000000000000000000000000000084 -:103C40000000000000000000000000000000000074 -:103C50000000000000000000000000000000000064 -:103C60000000000000000000000000000000000054 -:103C70000000000000000000000000000000000044 -:103C80000000000000000000000000000000000034 -:103C90000000000000000000000000000000000024 -:103CA0000000000000000000000000000000000014 -:103CB0000000000000000000000000000000000004 -:103CC00000000000000000000000000000000000F4 -:103CD00000000000000000000000000000000000E4 -:103CE00000000000000000000000000000000000D4 -:103CF00000000000000000000000000000000000C4 -:103D000000000000000000000000000000000000B3 -:103D100000000000000000000000000000000000A3 -:103D20000000000000000000000000000000000093 -:103D30000000000000000000000000000000000083 -:103D40000000000000000000000000000000000073 -:103D50000000000000000000000000000000000063 -:103D60000000000000000000000000000000000053 -:103D70000000000000000000000000000000000043 -:103D80000000000000000000000000000000000033 -:103D90000000000000000000000000000000000023 -:103DA0000000000000000000000000000000000013 -:103DB0000000000000000000000000000000000003 -:103DC00000000000000000000000000000000000F3 -:103DD00000000000000000000000000000000000E3 -:103DE00000000000000000000000000000000000D3 -:103DF00000000000000000000000000000000000C3 -:103E000000000000000000000000000000000000B2 -:103E100000000000000000000000000000000000A2 -:103E20000000000000000000000000000000000092 -:103E30000000000000000000000000000000000082 -:103E40000000000000000000000000000000000072 -:103E50000000000000000000000000000000000062 -:103E60000000000000000000000000000000000052 -:103E70000000000000000000000000000000000042 -:103E80000000000000000000000000000000000032 -:103E90000000000000000000000000000000000022 -:103EA0000000000000000000000000000000000012 -:103EB0000000000000000000000000000000000002 -:103EC00000000000000000000000000000000000F2 -:103ED00000000000000000000000000000000000E2 -:103EE00000000000000000000000000000000000D2 -:103EF00000000000000000000000000000000000C2 -:103F000000000000000000000000000000000000B1 -:103F100000000000000000000000000000000000A1 -:103F20000000000000000000000000000000000091 -:103F30000000000000000000000000000000000081 -:103F40000000000000000000000000000000000071 -:103F50000000000000000000000000000000000061 -:103F60000000000000000000000000000000000051 -:103F70000000000000000000000000000000000041 -:103F80000000000000000000000000000000000031 -:103F90000000000000000000000000000000000021 -:103FA0000000000000000000000000000000000011 -:103FB0000000000000000000000000000000000001 -:103FC00000000000000000000000000000000000F1 -:103FD00000000000000000000000000000000000E1 -:103FE00000000000000000000000000000000000D1 -:103FF00000000000000000000000000000000000C1 -:1040000000000000000000000000000000000000B0 -:1040100000000000000000000000000000000000A0 -:104020000000000000000000000000000000000090 -:104030000000000000000000000000000000000080 -:104040000000000000000000000000000000000070 -:104050000000000000000000000000000000000060 -:104060000000000000000000000000000000000050 -:104070000000000000000000000000000000000040 -:104080000000000000000000000000000000000030 -:104090000000000000000000000000000000000020 -:1040A0000000000000000000000000000000000010 -:1040B0000000000000000000000000000000000000 -:1040C00000000000000000000000000000000000F0 -:1040D00000000000000000000000000000000000E0 -:1040E00000000000000000000000000000000000D0 -:1040F00000000000000000000000000000000000C0 -:1041000000000000000000000000000000000000AF -:10411000000000000000000000000000000000009F -:10412000000000000000000000000000000000008F -:10413000000000000000000000000000000000007F -:10414000000000000000000000000000000000006F -:10415000000000000000000000000000000000005F -:10416000000000000000000000000000000000004F -:10417000000000000000000000000000000000003F -:10418000000000000000000000000000000000002F -:10419000000000000000000000000000000000001F -:1041A000000000000000000000000000000000000F -:1041B00000000000000000000000000000000000FF -:1041C00000000000000000000000000000000000EF -:1041D00000000000000000000000000000000000DF -:1041E00000000000000000000000000000000000CF -:1041F00000000000000000000000000000000000BF -:1042000000000000000000000000000000000000AE -:10421000000000000000000000000000000000009E -:10422000000000000000000000000000000000008E -:10423000000000000000000000000000000000007E -:10424000000000000000000000000000000000006E -:10425000000000000000000000000000000000005E -:10426000000000000000000000000000000000004E -:10427000000000000000000000000000000000003E -:10428000000000000000000000000000000000002E -:10429000000000000000000000000000000000001E -:1042A000000000000000000000000000000000000E -:1042B00000000000000000000000000000000000FE -:1042C00000000000000000000000000000000000EE -:1042D00000000000000000000000000000000000DE -:1042E00000000000000000000000000000000000CE -:1042F00000000000000000000000000000000000BE -:1043000000000000000000000000000000000000AD -:10431000000000000000000000000000000000009D -:10432000000000000000000000000000000000008D -:10433000000000000000000000000000000000007D -:10434000000000000000000000000000000000006D -:10435000000000000000000000000000000000005D -:10436000000000000000000000000000000000004D -:10437000000000000000000000000000000000003D -:10438000000000000000000000000000000000002D -:10439000000000000000000000000000000000001D -:1043A000000000000000000000000000000000000D -:1043B00000000000000000000000000000000000FD -:1043C00000000000000000000000000000000000ED -:1043D00000000000000000000000000000000000DD -:1043E00000000000000000000000000000000000CD -:1043F00000000000000000000000000000000000BD -:1044000000000000000000000000000000000000AC -:10441000000000000000000000000000000000009C -:10442000000000000000000000000000000000008C -:10443000000000000000000000000000000000007C -:10444000000000000000000000000000000000006C -:10445000000000000000000000000000000000005C -:10446000000000000000000000000000000000004C -:10447000000000000000000000000000000000003C -:10448000000000000000000000000000000000002C -:10449000000000000000000000000000000000001C -:1044A000000000000000000000000000000000000C -:1044B00000000000000000000000000000000000FC -:1044C00000000000000000000000000000000000EC -:1044D00000000000000000000000000000000000DC -:1044E00000000000000000000000000000000000CC -:1044F00000000000000000000000000000000000BC -:1045000000000000000000000000000000000000AB -:10451000000000000000000000000000000000009B -:10452000000000000000000000000000000000008B -:10453000000000000000000000000000000000007B -:10454000000000000000000000000000000000006B -:10455000000000000000000000000000000000005B -:10456000000000000000000000000000000000004B -:10457000000000000000000000000000000000003B -:10458000000000000000000000000000000000002B -:10459000000000000000000000000000000000001B -:1045A000000000000000000000000000000000000B -:1045B00000000000000000000000000000000000FB -:1045C00000000000000000000000000000000000EB -:1045D00000000000000000000000000000000000DB -:1045E00000000000000000000000000000000000CB -:1045F00000000000000000000000000000000000BB -:1046000000000000000000000000000000000000AA -:10461000000000000000000000000000000000009A -:10462000000000000000000000000000000000008A -:10463000000000000000000000000000000000007A -:10464000000000000000000000000000000000006A -:10465000000000000000000000000000000000005A -:10466000000000000000000000000000000000004A -:10467000000000000000000000000000000000003A -:10468000000000000000000000000000000000002A -:10469000000000000000000000000000000000001A -:1046A000000000000000000000000000000000000A -:1046B00000000000000000000000000000000000FA -:1046C00000000000000000000000000000000000EA -:1046D00000000000000000000000000000000000DA -:1046E00000000000000000000000000000000000CA -:1046F00000000000000000000000000000000000BA -:1047000000000000000000000000000000000000A9 -:104710000000000000000000000000000000000099 -:104720000000000000000000000000000000000089 -:104730000000000000000000000000000000000079 -:104740000000000000000000000000000000000069 -:104750000000000000000000000000000000000059 -:104760000000000000000000000000000000000049 -:104770000000000000000000000000000000000039 -:104780000000000000000000000000000000000029 -:104790000000000000000000000000000000000019 -:1047A0000000000000000000000000000000000009 -:1047B00000000000000000000000000000000000F9 -:1047C00000000000000000000000000000000000E9 -:1047D00000000000000000000000000000000000D9 -:1047E00000000000000000000000000000000000C9 -:1047F00000000000000000000000000000000000B9 -:1048000000000000000000000000000000000000A8 -:104810000000000000000000000000000000000098 -:104820000000000000000000000000000000000088 -:104830000000000000000000000000000000000078 -:104840000000000000000000000000000000000068 -:104850000000000000000000000000000000000058 -:104860000000000000000000000000000000000048 -:104870000000000000000000000000000000000038 -:104880000000000000000000000000000000000028 -:104890000000000000000000000000000000000018 -:1048A0000000000000000000000000000000000008 -:1048B00000000000000000000000000000000000F8 -:1048C00000000000000000000000000000000000E8 -:1048D00000000000000000000000000000000000D8 -:1048E00000000000000000000000000000000000C8 -:1048F00000000000000000000000000000000000B8 -:1049000000000000000000000000000000000000A7 -:104910000000000000000000000000000000000097 -:104920000000000000000000000000000000000087 -:104930000000000000000000000000000000000077 -:104940000000000000000000000000000000000067 -:104950000000000000000000000000000000000057 -:104960000000000000000000000000000000000047 -:104970000000000000000000000000000000000037 -:104980000000000000000000000000000000000027 -:104990000000000000000000000000000000000017 -:1049A0000000000000000000000000000000000007 -:1049B00000000000000000000000000000000000F7 -:1049C00000000000000000000000000000000000E7 -:1049D00000000000000000000000000000000000D7 -:1049E00000000000000000000000000000000000C7 -:1049F00000000000000000000000000000000000B7 -:104A000000000000000000000000000000000000A6 -:104A10000000000000000000000000000000000096 -:104A20000000000000000000000000000000000086 -:104A30000000000000000000000000000000000076 -:104A40000000000000000000000000000000000066 -:104A50000000000000000000000000000000000056 -:104A60000000000000000000000000000000000046 -:104A70000000000000000000000000000000000036 -:104A80000000000000000000000000000000000026 -:104A90000000000000000000000000000000000016 -:104AA0000000000000000000000000000000000006 -:104AB00000000000000000000000000000000000F6 -:104AC00000000000000000000000000000000000E6 -:104AD00000000000000000000000000000000000D6 -:104AE00000000000000000000000000000000000C6 -:104AF00000000000000000000000000000000000B6 -:104B000000000000000000000000000000000000A5 -:104B10000000000000000000000000000000000095 -:104B20000000000000000000000000000000000085 -:104B30000000000000000000000000000000000075 -:104B40000000000000000000000000000000000065 -:104B50000000000000000000000000000000000055 -:104B60000000000000000000000000000000000045 -:104B70000000000000000000000000000000000035 -:104B80000000000000000000000000000000000025 -:104B90000000000000000000000000000000000015 -:104BA0000000000000000000000000000000000005 -:104BB00000000000000000000000000000000000F5 -:104BC00000000000000000000000000000000000E5 -:104BD00000000000000000000000000000000000D5 -:104BE00000000000000000000000000000000000C5 -:104BF00000000000000000000000000000000000B5 -:104C000000000000000000000000000000000000A4 -:104C10000000000000000000000000000000000094 -:104C20000000000000000000000000000000000084 -:104C30000000000000000000000000000000000074 -:104C40000000000000000000000000000000000064 -:104C50000000000000000000000000000000000054 -:104C60000000000000000000000000000000000044 -:104C70000000000000000000000000000000000034 -:104C80000000000000000000000000000000000024 -:104C90000000000000000000000000000000000014 -:104CA0000000000000000000000000000000000004 -:104CB00000000000000000000000000000000000F4 -:104CC00000000000000000000000000000000000E4 -:104CD00000000000000000000000000000000000D4 -:104CE00000000000000000000000000000000000C4 -:104CF00000000000000000000000000000000000B4 -:104D000000000000000000000000000000000000A3 -:104D10000000000000000000000000000000000093 -:104D20000000000000000000000000000000000083 -:104D30000000000000000000000000000000000073 -:104D40000000000000000000000000000000000063 -:104D50000000000000000000000000000000000053 -:104D60000000000000000000000000000000000043 -:104D70000000000000000000000000000000000033 -:104D80000000000000000000000000000000000023 -:104D90000000000000000000000000000000000013 -:104DA0000000000000000000000000000000000003 -:104DB00000000000000000000000000000000000F3 -:104DC00000000000000000000000000000000000E3 -:104DD00000000000000000000000000000000000D3 -:104DE00000000000000000000000000000000000C3 -:104DF00000000000000000000000000000000000B3 -:104E000000000000000000000000000000000000A2 -:104E10000000000000000000000000000000000092 -:104E20000000000000000000000000000000000082 -:104E30000000000000000000000000000000000072 -:104E40000000000000000000000000000000000062 -:104E50000000000000000000000000000000000052 -:104E60000000000000000000000000000000000042 -:104E70000000000000000000000000000000000032 -:104E80000000000000000000000000000000000022 -:104E90000000000000000000000000000000000012 -:104EA0000000000000000000000000000000000002 -:104EB00000000000000000000000000000000000F2 -:104EC00000000000000000000000000000000000E2 -:104ED00000000000000000000000000000000000D2 -:104EE00000000000000000000000000000000000C2 -:104EF00000000000000000000000000000000000B2 -:104F000000000000000000000000000000000000A1 -:104F10000000000000000000000000000000000091 -:104F20000000000000000000000000000000000081 -:104F30000000000000000000000000000000000071 -:104F40000000000000000000000000000000000061 -:104F50000000000000000000000000000000000051 -:104F60000000000000000000000000000000000041 -:104F70000000000000000000000000000000000031 -:104F80000000000000000000000000000000000021 -:104F90000000000000000000000000000000000011 -:104FA0000000000000000000000000000000000001 -:104FB00000000000000000000000000000000000F1 -:104FC00000000000000000000000000000000000E1 -:104FD00000000000000000000000000000000000D1 -:104FE00000000000000000000000000000000000C1 -:104FF00000000000000000000000000000000000B1 -:1050000000000000000000000000000000000000A0 -:105010000000000000000000000000000000000090 -:105020000000000000000000000000000000000080 -:105030000000000000000000000000000000000070 -:105040000000000000000000000000000000000060 -:105050000000000000000000000000000000000050 -:105060000000000000000000000000000000000040 -:105070000000000000000000000000000000000030 -:105080000000000000000000000000000000000020 -:105090000000000000000000000000000000000010 -:1050A0000000000000000000000000000000000000 -:1050B00000000000000000000000000000000000F0 -:1050C00000000000000000000000000000000000E0 -:1050D00000000000000000000000000000000000D0 -:1050E00000000000000000000000000000000000C0 -:1050F00000000000000000000000000000000000B0 -:10510000000000000000000000000000000000009F -:10511000000000000000000000000000000000008F -:10512000000000000000000000000000000000007F -:10513000000000000000000000000000000000006F -:10514000000000000000000000000000000000005F -:10515000000000000000000000000000000000004F -:10516000000000000000000000000000000000003F -:10517000000000000000000000000000000000002F -:10518000000000000000000000000000000000001F -:10519000000000000000000000000000000000000F -:1051A00000000000000000000000000000000000FF -:1051B00000000000000000000000000000000000EF -:1051C00000000000000000000000000000000000DF -:1051D00000000000000000000000000000000000CF -:1051E00000000000000000000000000000000000BF -:1051F00000000000000000000000000000000000AF -:10520000000000000000000000000000000000009E -:10521000000000000000000000000000000000008E -:10522000000000000000000000000000000000007E -:10523000000000000000000000000000000000006E -:10524000000000000000000000000000000000005E -:10525000000000000000000000000000000000004E -:10526000000000000000000000000000000000003E -:10527000000000000000000000000000000000002E -:10528000000000000000000000000000000000001E -:10529000000000000000000000000000000000000E -:1052A00000000000000000000000000000000000FE -:1052B00000000000000000000000000000000000EE -:1052C00000000000000000000000000000000000DE -:1052D00000000000000000000000000000000000CE -:1052E00000000000000000000000000000000000BE -:1052F00000000000000000000000000000000000AE -:10530000000000000000000000000000000000009D -:10531000000000000000000000000000000000008D -:10532000000000000000000000000000000000007D -:10533000000000000000000000000000000000006D -:10534000000000000000000000000000000000005D -:10535000000000000000000000000000000000004D -:10536000000000000000000000000000000000003D -:10537000000000000000000000000000000000002D -:10538000000000000000000000000000000000001D -:10539000000000000000000000000000000000000D -:1053A00000000000000000000000000000000000FD -:1053B00000000000000000000000000000000000ED -:1053C00000000000000000000000000000000000DD -:1053D00000000000000000000000000000000000CD -:1053E00000000000000000000000000000000000BD -:1053F00000000000000000000000000000000000AD -:10540000000000000000000000000000000000009C -:10541000000000000000000000000000000000008C -:10542000000000000000000000000000000000007C -:10543000000000000000000000000000000000006C -:10544000000000000000000000000000000000005C -:10545000000000000000000000000000000000004C -:10546000000000000000000000000000000000003C -:10547000000000000000000000000000000000002C -:10548000000000000000000000000000000000001C -:10549000000000000000000000000000000000000C -:1054A00000000000000000000000000000000000FC -:1054B00000000000000000000000000000000000EC -:1054C00000000000000000000000000000000000DC -:1054D00000000000000000000000000000000000CC -:1054E00000000000000000000000000000000000BC -:1054F00000000000000000000000000000000000AC -:10550000000000000000000000000000000000009B -:10551000000000000000000000000000000000008B -:10552000000000000000000000000000000000007B -:10553000000000000000000000000000000000006B -:10554000000000000000000000000000000000005B -:10555000000000000000000000000000000000004B -:10556000000000000000000000000000000000003B -:10557000000000000000000000000000000000002B -:10558000000000000000000000000000000000001B -:10559000000000000000000000000000000000000B -:1055A00000000000000000000000000000000000FB -:1055B00000000000000000000000000000000000EB -:1055C00000000000000000000000000000000000DB -:1055D00000000000000000000000000000000000CB -:1055E00000000000000000000000000000000000BB -:1055F00000000000000000000000000000000000AB -:10560000000000000000000000000000000000009A -:10561000000000000000000000000000000000008A -:10562000000000000000000000000000000000007A -:10563000000000000000000000000000000000006A -:10564000000000000000000000000000000000005A -:10565000000000000000000000000000000000004A -:10566000000000000000000000000000000000003A -:10567000000000000000000000000000000000002A -:10568000000000000000000000000000000000001A -:10569000000000000000000000000000000000000A -:1056A00000000000000000000000000000000000FA -:1056B00000000000000000000000000000000000EA -:1056C00000000000000000000000000000000000DA -:1056D00000000000000000000000000000000000CA -:1056E00000000000000000000000000000000000BA -:1056F00000000000000000000000000000000000AA -:105700000000000000000000000000000000000099 -:105710000000000000000000000000000000000089 -:105720000000000000000000000000000000000079 -:105730000000000000000000000000000000000069 -:105740000000000000000000000000000000000059 -:105750000000000000000000000000000000000049 -:105760000000000000000000000000000000000039 -:105770000000000000000000000000000000000029 -:105780000000000000000000000000000000000019 -:105790000000000000000000000000000000000009 -:1057A00000000000000000000000000000000000F9 -:1057B00000000000000000000000000000000000E9 -:1057C00000000000000000000000000000000000D9 -:1057D00000000000000000000000000000000000C9 -:1057E00000000000000000000000000000000000B9 -:1057F00000000000000000000000000000000000A9 -:105800000000000000000000000000000000000098 -:105810000000000000000000000000000000000088 -:105820000000000000000000000000000000000078 -:105830000000000000000000000000000000000068 -:105840000000000000000000000000000000000058 -:105850000000000000000000000000000000000048 -:105860000000000000000000000000000000000038 -:105870000000000000000000000000000000000028 -:105880000000000000000000000000000000000018 -:105890000000000000000000000000000000000008 -:1058A00000000000000000000000000000000000F8 -:1058B00000000000000000000000000000000000E8 -:1058C00000000000000000000000000000000000D8 -:1058D00000000000000000000000000000000000C8 -:1058E00000000000000000000000000000000000B8 -:1058F00000000000000000000000000000000000A8 -:105900000000000000000000000000000000000097 -:105910000000000000000000000000000000000087 -:105920000000000000000000000000000000000077 -:105930000000000000000000000000000000000067 -:105940000000000000000000000000000000000057 -:105950000000000000000000000000000000000047 -:105960000000000000000000000000000000000037 -:105970000000000000000000000000000000000027 -:105980000000000000000000000000000000000017 -:105990000000000000000000000000000000000007 -:1059A00000000000000000000000000000000000F7 -:1059B00000000000000000000000000000000000E7 -:1059C00000000000000000000000000000000000D7 -:1059D00000000000000000000000000000000000C7 -:1059E00000000000000000000000000000000000B7 -:1059F00000000000000000000000000000000000A7 -:105A00000000000000000000000000000000000096 -:105A10000000000000000000000000000000000086 -:105A20000000000000000000000000000000000076 -:105A30000000000000000000000000000000000066 -:105A40000000000000000000000000000000000056 -:105A50000000000000000000000000000000000046 -:105A60000000000000000000000000000000000036 -:105A70000000000000000000000000000000000026 -:105A80000000000000000000000000000000000016 -:105A90000000000000000000000000000000000006 -:105AA00000000000000000000000000000000000F6 -:105AB00000000000000000000000000000000000E6 -:105AC00000000000000000000000000000000000D6 -:105AD00000000000000000000000000000000000C6 -:105AE00000000000000000000000000000000000B6 -:105AF00000000000000000000000000000000000A6 -:105B00000000000000000000000000000000000095 -:105B10000000000000000000000000000000000085 -:105B20000000000000000000000000000000000075 -:105B30000000000000000000000000000000000065 -:105B40000000000000000000000000000000000055 -:105B50000000000000000000000000000000000045 -:105B60000000000000000000000000000000000035 -:105B70000000000000000000000000000000000025 -:105B80000000000000000000000000000000000015 -:105B90000000000000000000000000000000000005 -:105BA00000000000000000000000000000000000F5 -:105BB00000000000000000000000000000000000E5 -:105BC00000000000000000000000000000000000D5 -:105BD00000000000000000000000000000000000C5 -:105BE00000000000000000000000000000000000B5 -:105BF00000000000000000000000000000000000A5 -:105C00000000000000000000000000000000000094 -:105C10000000000000000000000000000000000084 -:105C20000000000000000000000000000000000074 -:105C30000000000000000000000000000000000064 -:105C40000000000000000000000000000000000054 -:105C50000000000000000000000000000000000044 -:105C60000000000000000000000000000000000034 -:105C70000000000000000000000000000000000024 -:105C80000000000000000000000000000000000014 -:105C90000000000000000000000000000000000004 -:105CA00000000000000000000000000000000000F4 -:105CB00000000000000000000000000000000000E4 -:105CC00000000000000000000000000000000000D4 -:105CD00000000000000000000000000000000000C4 -:105CE00000000000000000000000000000000000B4 -:105CF00000000000000000000000000000000000A4 -:105D00000000000000000000000000000000000093 -:105D10000000000000000000000000000000000083 -:105D20000000000000000000000000000000000073 -:105D30000000000000000000000000000000000063 -:105D40000000000000000000000000000000000053 -:105D50000000000000000000000000000000000043 -:105D60000000000000000000000000000000000033 -:105D70000000000000000000000000000000000023 -:105D80000000000000000000000000000000000013 -:105D90000000000000000000000000000000000003 -:105DA00000000000000000000000000000000000F3 -:105DB00000000000000000000000000000000000E3 -:105DC00000000000000000000000000000000000D3 -:105DD00000000000000000000000000000000000C3 -:105DE00000000000000000000000000000000000B3 -:105DF00000000000000000000000000000000000A3 -:105E00000000000000000000000000000000000092 -:105E10000000000000000000000000000000000082 -:105E20000000000000000000000000000000000072 -:105E30000000000000000000000000000000000062 -:105E40000000000000000000000000000000000052 -:105E50000000000000000000000000000000000042 -:105E60000000000000000000000000000000000032 -:105E70000000000000000000000000000000000022 -:105E80000000000000000000000000000000000012 -:105E90000000000000000000000000000000000002 -:105EA00000000000000000000000000000000000F2 -:105EB00000000000000000000000000000000000E2 -:105EC00000000000000000000000000000000000D2 -:105ED00000000000000000000000000000000000C2 -:105EE00000000000000000000000000000000000B2 -:105EF00000000000000000000000000000000000A2 -:105F00000000000000000000000000000000000091 -:105F10000000000000000000000000000000000081 -:105F20000000000000000000000000000000000071 -:105F30000000000000000000000000000000000061 -:105F40000000000000000000000000000000000051 -:105F50000000000000000000000000000000000041 -:105F60000000000000000000000000000000000031 -:105F70000000000000000000000000000000000021 -:105F80000000000000000000000000000000000011 -:105F90000000000000000000000000000000000001 -:105FA00000000000000000000000000000000000F1 -:105FB00000000000000000000000000000000000E1 -:105FC00000000000000000000000000000000000D1 -:105FD00000000000000000000000000000000000C1 -:105FE00000000000000000000000000000000000B1 -:105FF00000000000000000000000000000000000A1 -:106000000000000000000000000000000000000090 -:106010000000000000000000000000000000000080 -:106020000000000000000000000000000000000070 -:106030000000000000000000000000000000000060 -:106040000000000000000000000000000000000050 -:106050000000000000000000000000000000000040 -:106060000000000000000000000000000000000030 -:106070000000000000000000000000000000000020 -:106080000000000000000000000000000000000010 -:106090000000000000000000000000000000000000 -:1060A00000000000000000000000000000000000F0 -:1060B00000000000000000000000000000000000E0 -:1060C00000000000000000000000000000000000D0 -:1060D00000000000000000000000000000000000C0 -:1060E00000000000000000000000000000000000B0 -:1060F00000000000000000000000000000000000A0 -:10610000000000000000000000000000000000008F -:10611000000000000000000000000000000000007F -:10612000000000000000000000000000000000006F -:10613000000000000000000000000000000000005F -:10614000000000000000000000000000000000004F -:10615000000000000000000000000000000000003F -:10616000000000000000000000000000000000002F -:10617000000000000000000000000000000000001F -:10618000000000000000000000000000000000000F -:1061900000000000000000000000000000000000FF -:1061A00000000000000000000000000000000000EF -:1061B00000000000000000000000000000000000DF -:1061C00000000000000000000000000000000000CF -:1061D00000000000000000000000000000000000BF -:1061E00000000000000000000000000000000000AF -:1061F000000000000000000000000000000000009F -:10620000000000000000000000000000000000008E -:10621000000000000000000000000000000000007E -:10622000000000000000000000000000000000006E -:10623000000000000000000000000000000000005E -:10624000000000000000000000000000000000004E -:10625000000000000000000000000000000000003E -:10626000000000000000000000000000000000002E -:10627000000000000000000000000000000000001E -:10628000000000000000000000000000000000000E -:1062900000000000000000000000000000000000FE -:1062A00000000000000000000000000000000000EE -:1062B00000000000000000000000000000000000DE -:1062C00000000000000000000000000000000000CE -:1062D00000000000000000000000000000000000BE -:1062E00000000000000000000000000000000000AE -:1062F000000000000000000000000000000000009E -:10630000000000000000000000000000000000008D -:10631000000000000000000000000000000000007D -:10632000000000000000000000000000000000006D -:10633000000000000000000000000000000000005D -:10634000000000000000000000000000000000004D -:10635000000000000000000000000000000000003D -:10636000000000000000000000000000000000002D -:10637000000000000000000000000000000000001D -:10638000000000000000000000000000000000000D -:1063900000000000000000000000000000000000FD -:1063A00000000000000000000000000000000000ED -:1063B00000000000000000000000000000000000DD -:1063C00000000000000000000000000000000000CD -:1063D00000000000000000000000000000000000BD -:1063E00000000000000000000000000000000000AD -:1063F000000000000000000000000000000000009D -:10640000000000000000000000000000000000008C -:10641000000000000000000000000000000000007C -:10642000000000000000000000000000000000006C -:10643000000000000000000000000000000000005C -:10644000000000000000000000000000000000004C -:10645000000000000000000000000000000000003C -:10646000000000000000000000000000000000002C -:10647000000000000000000000000000000000001C -:10648000000000000000000000000000000000000C -:1064900000000000000000000000000000000000FC -:1064A00000000000000000000000000000000000EC -:1064B00000000000000000000000000000000000DC -:1064C00000000000000000000000000000000000CC -:1064D00000000000000000000000000000000000BC -:1064E00000000000000000000000000000000000AC -:1064F000000000000000000000000000000000009C -:10650000000000000000000000000000000000008B -:10651000000000000000000000000000000000007B -:10652000000000000000000000000000000000006B -:10653000000000000000000000000000000000005B -:10654000000000000000000000000000000000004B -:10655000000000000000000000000000000000003B -:10656000000000000000000000000000000000002B -:10657000000000000000000000000000000000001B -:10658000000000000000000000000000000000000B -:1065900000000000000000000000000000000000FB -:1065A00000000000000000000000000000000000EB -:1065B00000000000000000000000000000000000DB -:1065C00000000000000000000000000000000000CB -:1065D00000000000000000000000000000000000BB -:1065E00000000000000000000000000000000000AB -:1065F000000000000000000000000000000000009B -:10660000000000000000000000000000000000008A -:10661000000000000000000000000000000000007A -:10662000000000000000000000000000000000006A -:10663000000000000000000000000000000000005A -:10664000000000000000000000000000000000004A -:10665000000000000000000000000000000000003A -:10666000000000000000000000000000000000002A -:10667000000000000000000000000000000000001A -:10668000000000000000000000000000000000000A -:1066900000000000000000000000000000000000FA -:1066A00000000000000000000000000000000000EA -:1066B00000000000000000000000000000000000DA -:1066C00000000000000000000000000000000000CA -:1066D00000000000000000000000000000000000BA -:1066E00000000000000000000000000000000000AA -:1066F000000000000000000000000000000000009A -:106700000000000000000000000000000000000089 -:106710000000000000000000000000000000000079 -:106720000000000000000000000000000000000069 -:106730000000000000000000000000000000000059 -:106740000000000000000000000000000000000049 -:106750000000000000000000000000000000000039 -:106760000000000000000000000000000000000029 -:106770000000000000000000000000000000000019 -:106780000000000000000000000000000000000009 -:1067900000000000000000000000000000000000F9 -:1067A00000000000000000000000000000000000E9 -:1067B00000000000000000000000000000000000D9 -:1067C00000000000000000000000000000000000C9 -:1067D00000000000000000000000000000000000B9 -:1067E00000000000000000000000000000000000A9 -:1067F0000000000000000000000000000000000099 -:106800000000000000000000000000000000000088 -:106810000000000000000000000000000000000078 -:106820000000000000000000000000000000000068 -:106830000000000000000000000000000000000058 -:106840000000000000000000000000000000000048 -:106850000000000000000000000000000000000038 -:106860000000000000000000000000000000000028 -:106870000000000000000000000000000000000018 -:106880000000000000000000000000000000000008 -:1068900000000000000000000000000000000000F8 -:1068A00000000000000000000000000000000000E8 -:1068B00000000000000000000000000000000000D8 -:1068C00000000000000000000000000000000000C8 -:1068D00000000000000000000000000000000000B8 -:1068E00000000000000000000000000000000000A8 -:1068F0000000000000000000000000000000000098 -:106900000000000000000000000000000000000087 -:106910000000000000000000000000000000000077 -:106920000000000000000000000000000000000067 -:106930000000000000000000000000000000000057 -:106940000000000000000000000000000000000047 -:106950000000000000000000000000000000000037 -:106960000000000000000000000000000000000027 -:106970000000000000000000000000000000000017 -:106980000000000000000000000000000000000007 -:1069900000000000000000000000000000000000F7 -:1069A00000000000000000000000000000000000E7 -:1069B00000000000000000000000000000000000D7 -:1069C00000000000000000000000000000000000C7 -:1069D00000000000000000000000000000000000B7 -:1069E00000000000000000000000000000000000A7 -:1069F0000000000000000000000000000000000097 -:106A00000000000000000000000000000000000086 -:106A10000000000000000000000000000000000076 -:106A20000000000000000000000000000000000066 -:106A30000000000000000000000000000000000056 -:106A40000000000000000000000000000000000046 -:106A50000000000000000000000000000000000036 -:106A60000000000000000000000000000000000026 -:106A70000000000000000000000000000000000016 -:106A80000000000000000000000000000000000006 -:106A900000000000000000000000000000000000F6 -:106AA00000000000000000000000000000000000E6 -:106AB00000000000000000000000000000000000D6 -:106AC00000000000000000000000000000000000C6 -:106AD00000000000000000000000000000000000B6 -:106AE00000000000000000000000000000000000A6 -:106AF0000000000000000000000000000000000096 -:106B00000000000000000000000000000000000085 -:106B10000000000000000000000000000000000075 -:106B20000000000000000000000000000000000065 -:106B30000000000000000000000000000000000055 -:106B40000000000000000000000000000000000045 -:106B50000000000000000000000000000000000035 -:106B60000000000000000000000000000000000025 -:106B70000000000000000000000000000000000015 -:106B80000000000000000000000000000000000005 -:106B900000000000000000000000000000000000F5 -:106BA00000000000000000000000000000000000E5 -:106BB00000000000000000000000000000000000D5 -:106BC00000000000000000000000000000000000C5 -:106BD00000000000000000000000000000000000B5 -:106BE00000000000000000000000000000000000A5 -:106BF0000000000000000000000000000000000095 -:106C00000000000000000000000000000000000084 -:106C10000000000000000000000000000000000074 -:106C20000000000000000000000000000000000064 -:106C30000000000000000000000000000000000054 -:106C40000000000000000000000000000000000044 -:106C50000000000000000000000000000000000034 -:106C60000000000000000000000000000000000024 -:106C70000000000000000000000000000000000014 -:106C80000000000000000000000000000000000004 -:106C900000000000000000000000000000000000F4 -:106CA00000000000000000000000000000000000E4 -:106CB00000000000000000000000000000000000D4 -:106CC00000000000000000000000000000000000C4 -:106CD00000000000000000000000000000000000B4 -:106CE00000000000000000000000000000000000A4 -:106CF0000000000000000000000000000000000094 -:106D00000000000000000000000000000000000083 -:106D10000000000000000000000000000000000073 -:106D20000000000000000000000000000000000063 -:106D30000000000000000000000000000000000053 -:106D40000000000000000000000000000000000043 -:106D50000000000000000000000000000000000033 -:106D60000000000000000000000000000000000023 -:106D70000000000000000000000000000000000013 -:106D80000000000000000000000000000000000003 -:106D900000000000000000000000000000000000F3 -:106DA00000000000000000000000000000000000E3 -:106DB00000000000000000000000000000000000D3 -:106DC00000000000000000000000000000000000C3 -:106DD00000000000000000000000000000000000B3 -:106DE00000000000000000000000000000000000A3 -:106DF0000000000000000000000000000000000093 -:106E00000000000000000000000000000000000082 -:106E10000000000000000000000000000000000072 -:106E20000000000000000000000000000000000062 -:106E30000000000000000000000000000000000052 -:106E40000000000000000000000000000000000042 -:106E50000000000000000000000000000000000032 -:106E60000000000000000000000000000000000022 -:106E70000000000000000000000000000000000012 -:106E80000000000000000000000000000000000002 -:106E900000000000000000000000000000000000F2 -:106EA00000000000000000000000000000000000E2 -:106EB00000000000000000000000000000000000D2 -:106EC00000000000000000000000000000000000C2 -:106ED00000000000000000000000000000000000B2 -:106EE00000000000000000000000000000000000A2 -:106EF0000000000000000000000000000000000092 -:106F00000000000000000000000000000000000081 -:106F10000000000000000000000000000000000071 -:106F20000000000000000000000000000000000061 -:106F30000000000000000000000000000000000051 -:106F40000000000000000000000000000000000041 -:106F50000000000000000000000000000000000031 -:106F60000000000000000000000000000000000021 -:106F70000000000000000000000000000000000011 -:106F80000000000000000000000000000000000001 -:106F900000000000000000000000000000000000F1 -:106FA00000000000000000000000000000000000E1 -:106FB00000000000000000000000000000000000D1 -:106FC00000000000000000000000000000000000C1 -:106FD00000000000000000000000000000000000B1 -:106FE00000000000000000000000000000000000A1 -:106FF0000000000000000000000000000000000091 -:107000000000000000000000000000000000000080 -:107010000000000000000000000000000000000070 -:107020000000000000000000000000000000000060 -:107030000000000000000000000000000000000050 -:107040000000000000000000000000000000000040 -:107050000000000000000000000000000000000030 -:107060000000000000000000000000000000000020 -:107070000000000000000000000000000000000010 -:107080000000000000000000000000000000000000 -:1070900000000000000000000000000000000000F0 -:1070A00000000000000000000000000000000000E0 -:1070B00000000000000000000000000000000000D0 -:1070C00000000000000000000000000000000000C0 -:1070D00000000000000000000000000000000000B0 -:1070E00000000000000000000000000000000000A0 -:1070F0000000000000000000000000000000000090 -:10710000000000000000000000000000000000007F -:10711000000000000000000000000000000000006F -:10712000000000000000000000000000000000005F -:10713000000000000000000000000000000000004F -:10714000000000000000000000000000000000003F -:10715000000000000000000000000000000000002F -:10716000000000000000000000000000000000001F -:10717000000000000000000000000000000000000F -:1071800000000000000000000000000000000000FF -:1071900000000000000000000000000000000000EF -:1071A00000000000000000000000000000000000DF -:1071B00000000000000000000000000000000000CF -:1071C00000000000000000000000000000000000BF -:1071D00000000000000000000000000000000000AF -:1071E000000000000000000000000000000000009F -:1071F000000000000000000000000000000000008F -:10720000000000000000000000000000000000007E -:10721000000000000000000000000000000000006E -:10722000000000000000000000000000000000005E -:10723000000000000000000000000000000000004E -:10724000000000000000000000000000000000003E -:10725000000000000000000000000000000000002E -:10726000000000000000000000000000000000001E -:10727000000000000000000000000000000000000E -:1072800000000000000000000000000000000000FE -:1072900000000000000000000000000000000000EE -:1072A00000000000000000000000000000000000DE -:1072B00000000000000000000000000000000000CE -:1072C00000000000000000000000000000000000BE -:1072D00000000000000000000000000000000000AE -:1072E000000000000000000000000000000000009E -:1072F000000000000000000000000000000000008E -:10730000000000000000000000000000000000007D -:10731000000000000000000000000000000000006D -:10732000000000000000000000000000000000005D -:10733000000000000000000000000000000000004D -:10734000000000000000000000000000000000003D -:10735000000000000000000000000000000000002D -:10736000000000000000000000000000000000001D -:10737000000000000000000000000000000000000D -:1073800000000000000000000000000000000000FD -:1073900000000000000000000000000000000000ED -:1073A00000000000000000000000000000000000DD -:1073B00000000000000000000000000000000000CD -:1073C00000000000000000000000000000000000BD -:1073D00000000000000000000000000000000000AD -:1073E000000000000000000000000000000000009D -:1073F000000000000000000000000000000000008D -:10740000000000000000000000000000000000007C -:10741000000000000000000000000000000000006C -:10742000000000000000000000000000000000005C -:10743000000000000000000000000000000000004C -:10744000000000000000000000000000000000003C -:10745000000000000000000000000000000000002C -:10746000000000000000000000000000000000001C -:10747000000000000000000000000000000000000C -:1074800000000000000000000000000000000000FC -:1074900000000000000000000000000000000000EC -:1074A00000000000000000000000000000000000DC -:1074B00000000000000000000000000000000000CC -:1074C00000000000000000000000000000000000BC -:1074D00000000000000000000000000000000000AC -:1074E000000000000000000000000000000000009C -:1074F000000000000000000000000000000000008C -:10750000000000000000000000000000000000007B -:10751000000000000000000000000000000000006B -:10752000000000000000000000000000000000005B -:10753000000000000000000000000000000000004B -:10754000000000000000000000000000000000003B -:10755000000000000000000000000000000000002B -:10756000000000000000000000000000000000001B -:10757000000000000000000000000000000000000B -:1075800000000000000000000000000000000000FB -:1075900000000000000000000000000000000000EB -:1075A00000000000000000000000000000000000DB -:1075B00000000000000000000000000000000000CB -:1075C00000000000000000000000000000000000BB -:1075D00000000000000000000000000000000000AB -:1075E000000000000000000000000000000000009B -:1075F000000000000000000000000000000000008B -:10760000000000000000000000000000000000007A -:10761000000000000000000000000000000000006A -:10762000000000000000000000000000000000005A -:10763000000000000000000000000000000000004A -:10764000000000000000000000000000000000003A -:10765000000000000000000000000000000000002A -:10766000000000000000000000000000000000001A -:10767000000000000000000000000000000000000A -:1076800000000000000000000000000000000000FA -:1076900000000000000000000000000000000000EA -:1076A00000000000000000000000000000000000DA -:1076B00000000000000000000000000000000000CA -:1076C00000000000000000000000000000000000BA -:1076D00000000000000000000000000000000000AA -:1076E000000000000000000000000000000000009A -:1076F000000000000000000000000000000000008A -:107700000000000000000000000000000000000079 -:107710000000000000000000000000000000000069 -:107720000000000000000000000000000000000059 -:107730000000000000000000000000000000000049 -:107740000000000000000000000000000000000039 -:107750000000000000000000000000000000000029 -:107760000000000000000000000000000000000019 -:107770000000000000000000000000000000000009 -:1077800000000000000000000000000000000000F9 -:1077900000000000000000000000000000000000E9 -:1077A00000000000000000000000000000000000D9 -:1077B00000000000000000000000000000000000C9 -:1077C00000000000000000000000000000000000B9 -:1077D00000000000000000000000000000000000A9 -:1077E0000000000000000000000000000000000099 -:1077F0000000000000000000000000000000000089 -:107800000000000000000000000000000000000078 -:107810000000000000000000000000000000000068 -:107820000000000000000000000000000000000058 -:107830000000000000000000000000000000000048 -:107840000000000000000000000000000000000038 -:107850000000000000000000000000000000000028 -:107860000000000000000000000000000000000018 -:107870000000000000000000000000000000000008 -:1078800000000000000000000000000000000000F8 -:1078900000000000000000000000000000000000E8 -:1078A00000000000000000000000000000000000D8 -:1078B00000000000000000000000000000000000C8 -:1078C00000000000000000000000000000000000B8 -:1078D00000000000000000000000000000000000A8 -:1078E0000000000000000000000000000000000098 -:1078F0000000000000000000000000000000000088 -:107900000000000000000000000000000000000077 -:107910000000000000000000000000000000000067 -:107920000000000000000000000000000000000057 -:107930000000000000000000000000000000000047 -:107940000000000000000000000000000000000037 -:107950000000000000000000000000000000000027 -:107960000000000000000000000000000000000017 -:107970000000000000000000000000000000000007 -:1079800000000000000000000000000000000000F7 -:1079900000000000000000000000000000000000E7 -:1079A00000000000000000000000000000000000D7 -:1079B00000000000000000000000000000000000C7 -:1079C00000000000000000000000000000000000B7 -:1079D00000000000000000000000000000000000A7 -:1079E0000000000000000000000000000000000097 -:1079F0000000000000000000000000000000000087 -:107A00000000000000000000000000000000000076 -:107A10000000000000000000000000000000000066 -:107A20000000000000000000000000000000000056 -:107A30000000000000000000000000000000000046 -:107A40000000000000000000000000000000000036 -:107A50000000000000000000000000000000000026 -:107A60000000000000000000000000000000000016 -:107A70000000000000000000000000000000000006 -:107A800000000000000000000000000000000000F6 -:107A900000000000000000000000000000000000E6 -:107AA00000000000000000000000000000000000D6 -:107AB00000000000000000000000000000000000C6 -:107AC00000000000000000000000000000000000B6 -:107AD00000000000000000000000000000000000A6 -:107AE0000000000000000000000000000000000096 -:107AF0000000000000000000000000000000000086 -:107B00000000000000000000000000000000000075 -:107B10000000000000000000000000000000000065 -:107B20000000000000000000000000000000000055 -:107B30000000000000000000000000000000000045 -:107B40000000000000000000000000000000000035 -:107B50000000000000000000000000000000000025 -:107B60000000000000000000000000000000000015 -:107B70000000000000000000000000000000000005 -:107B800000000000000000000000000000000000F5 -:107B900000000000000000000000000000000000E5 -:107BA00000000000000000000000000000000000D5 -:107BB00000000000000000000000000000000000C5 -:107BC00000000000000000000000000000000000B5 -:107BD00000000000000000000000000000000000A5 -:107BE0000000000000000000000000000000000095 -:107BF0000000000000000000000000000000000085 -:107C00000000000000000000000000000000000074 -:107C10000000000000000000000000000000000064 -:107C20000000000000000000000000000000000054 -:107C30000000000000000000000000000000000044 -:107C40000000000000000000000000000000000034 -:107C50000000000000000000000000000000000024 -:107C60000000000000000000000000000000000014 -:107C70000000000000000000000000000000000004 -:107C800000000000000000000000000000000000F4 -:107C900000000000000000000000000000000000E4 -:107CA00000000000000000000000000000000000D4 -:107CB00000000000000000000000000000000000C4 -:107CC00000000000000000000000000000000000B4 -:107CD00000000000000000000000000000000000A4 -:107CE0000000000000000000000000000000000094 -:107CF0000000000000000000000000000000000084 -:107D00000000000000000000000000000000000073 -:107D10000000000000000000000000000000000063 -:107D20000000000000000000000000000000000053 -:107D30000000000000000000000000000000000043 -:107D40000000000000000000000000000000000033 -:107D50000000000000000000000000000000000023 -:107D60000000000000000000000000000000000013 -:107D70000000000000000000000000000000000003 -:107D800000000000000000000000000000000000F3 -:107D900000000000000000000000000000000000E3 -:107DA00000000000000000000000000000000000D3 -:107DB00000000000000000000000000000000000C3 -:107DC00000000000000000000000000000000000B3 -:107DD00000000000000000000000000000000000A3 -:107DE0000000000000000000000000000000000093 -:107DF0000000000000000000000000000000000083 -:107E00000000000000000000000000000000000072 -:107E10000000000000000000000000000000000062 -:107E20000000000000000000000000000000000052 -:107E30000000000000000000000000000000000042 -:107E40000000000000000000000000000000000032 -:107E50000000000000000000000000000000000022 -:107E60000000000000000000000000000000000012 -:107E70000000000000000000000000000000000002 -:107E800000000000000000000000000000000000F2 -:107E900000000000000000000000000000000000E2 -:107EA00000000000000000000000000000000000D2 -:107EB00000000000000000000000000000000000C2 -:107EC00000000000000000000000000000000000B2 -:107ED00000000000000000000000000000000000A2 -:107EE0000000000000000000000000000000000092 -:107EF0000000000000000000000000000000000082 -:107F00000000000000000000000000000000000071 -:107F10000000000000000000000000000000000061 -:107F20000000000000000000000000000000000051 -:107F30000000000000000000000000000000000041 -:107F40000000000000000000000000000000000031 -:107F50000000000000000000000000000000000021 -:107F60000000000000000000000000000000000011 -:107F70000000000000000000000000000000000001 -:107F800000000000000000000000000000000000F1 -:107F900000000000000000000000000000000000E1 -:107FA00000000000000000000000000000000000D1 -:107FB00000000000000000000000000000000000C1 -:107FC00000000000000000000000000000000000B1 -:107FD00000000000000000000000000000000000A1 -:107FE0000000000000000000000000000000000091 -:107FF0000000000000000000000000000000000081 -:108000000000000000000000000000000000000070 -:108010000000000000000000000000000000000060 -:108020000000000000000000000000000000000050 -:108030000000000000000000000000000000000040 -:108040000000000000000000000000000000000030 -:108050000000000000000000000000000000000020 -:108060000000000000000000000000000000000010 -:108070000000000000000000000000000000000000 -:1080800000000000000000000000000000000000F0 -:1080900000000000000000000000000000000000E0 -:1080A00000000000000000000000000000000000D0 -:1080B00000000000000000000000000000000000C0 -:1080C00000000000000000000000000000000000B0 -:1080D00000000000000000000000000000000000A0 -:1080E0000000000000000000000000000000000090 -:1080F0000000000000000000000000000000000080 -:10810000000000000000000000000000000000006F -:10811000000000000000000000000000000000005F -:10812000000000000000000000000000000000004F -:10813000000000000000000000000000000000003F -:10814000000000000000000000000000000000002F -:10815000000000000000000000000000000000001F -:10816000000000000000000000000000000000000F -:1081700000000000000000000000000000000000FF -:1081800000000000000000000000000000000000EF -:1081900000000000000000000000000000000000DF -:1081A00000000000000000000000000000000000CF -:1081B00000000000000000000000000000000000BF -:1081C00000000000000000000000000000000000AF -:1081D000000000000000000000000000000000009F -:1081E000000000000000000000000000000000008F -:1081F000000000000000000000000000000000007F -:10820000000000000000000000000000000000006E -:10821000000000000000000000000000000000005E -:10822000000000000000000000000000000000004E -:10823000000000000000000000000000000000003E -:10824000000000000000000000000000000000002E -:10825000000000000000000000000000000000001E -:10826000000000000000000000000000000000000E -:1082700000000000000000000000000000000000FE -:1082800000000000000000000000000000000000EE -:1082900000000000000000000000000000000000DE -:1082A00000000000000000000000000000000000CE -:1082B00000000000000000000000000000000000BE -:1082C00000000000000000000000000000000000AE -:1082D000000000000000000000000000000000009E -:1082E000000000000000000000000000000000008E -:1082F000000000000000000000000000000000007E -:10830000000000000000000000000000000000006D -:10831000000000000000000000000000000000005D -:10832000000000000000000000000000000000004D -:10833000000000000000000000000000000000003D -:10834000000000000000000000000000000000002D -:10835000000000000000000000000000000000001D -:10836000000000000000000000000000000000000D -:1083700000000000000000000000000000000000FD -:1083800000000000000000000000000000000000ED -:1083900000000000000000000000000000000000DD -:1083A00000000000000000000000000000000000CD -:1083B00000000000000000000000000000000000BD -:1083C00000000000000000000000000000000000AD -:1083D000000000000000000000000000000000009D -:1083E000000000000000000000000000000000008D -:1083F000000000000000000000000000000000007D -:10840000000000000000000000000000000000006C -:10841000000000000000000000000000000000005C -:10842000000000000000000000000000000000004C -:10843000000000000000000000000000000000003C -:10844000000000000000000000000000000000002C -:10845000000000000000000000000000000000001C -:10846000000000000000000000000000000000000C -:1084700000000000000000000000000000000000FC -:1084800000000000000000000000000000000000EC -:1084900000000000000000000000000000000000DC -:1084A00000000000000000000000000000000000CC -:1084B00000000000000000000000000000000000BC -:1084C00000000000000000000000000000000000AC -:1084D000000000000000000000000000000000009C -:1084E000000000000000000000000000000000008C -:1084F000000000000000000000000000000000007C -:10850000000000000000000000000000000000006B -:10851000000000000000000000000000000000005B -:10852000000000000000000000000000000000004B -:10853000000000000000000000000000000000003B -:10854000000000000000000000000000000000002B -:10855000000000000000000000000000000000001B -:10856000000000000000000000000000000000000B -:1085700000000000000000000000000000000000FB -:1085800000000000000000000000000000000000EB -:1085900000000000000000000000000000000000DB -:1085A00000000000000000000000000000000000CB -:1085B00000000000000000000000000000000000BB -:1085C00000000000000000000000000000000000AB -:1085D000000000000000000000000000000000009B -:1085E000000000000000000000000000000000008B -:1085F000000000000000000000000000000000007B -:10860000000000000000000000000000000000006A -:10861000000000000000000000000000000000005A -:10862000000000000000000000000000000000004A -:10863000000000000000000000000000000000003A -:10864000000000000000000000000000000000002A -:10865000000000000000000000000000000000001A -:10866000000000000000000000000000000000000A -:1086700000000000000000000000000000000000FA -:1086800000000000000000000000000000000000EA -:1086900000000000000000000000000000000000DA -:1086A00000000000000000000000000000000000CA -:1086B00000000000000000000000000000000000BA -:1086C00000000000000000000000000000000000AA -:1086D000000000000000000000000000000000009A -:1086E000000000000000000000000000000000008A -:1086F000000000000000000000000000000000007A -:108700000000000000000000000000000000000069 -:108710000000000000000000000000000000000059 -:108720000000000000000000000000000000000049 -:108730000000000000000000000000000000000039 -:108740000000000000000000000000000000000029 -:108750000000000000000000000000000000000019 -:108760000000000000000000000000000000000009 -:1087700000000000000000000000000000000000F9 -:1087800000000000000000000000000000000000E9 -:1087900000000000000000000000000000000000D9 -:1087A00000000000000000000000000000000000C9 -:1087B00000000000000000000000000000000000B9 -:1087C00000000000000000000000000000000000A9 -:1087D0000000000000000000000000000000000099 -:1087E0000000000000000000000000000000000089 -:1087F0000000000000000000000000000000000079 -:108800000000000000000000000000000000000068 -:108810000000000000000000000000000000000058 -:108820000000000000000000000000000000000048 -:108830000000000000000000000000000000000038 -:108840000000000000000000000000000000000028 -:108850000000000000000000000000000000000018 -:108860000000000000000000000000000000000008 -:1088700000000000000000000000000000000000F8 -:1088800000000000000000000000000000000000E8 -:1088900000000000000000000000000000000000D8 -:1088A00000000000000000000000000000000000C8 -:1088B00000000000000000000000000000000000B8 -:1088C00000000000000000000000000000000000A8 -:1088D0000000000000000000000000000000000098 -:1088E0000000000000000000000000000000000088 -:1088F0000000000000000000000000000000000078 -:108900000000000000000000000000000000000067 -:108910000000000000000000000000000000000057 -:108920000000000000000000000000000000000047 -:108930000000000000000000000000000000000037 -:108940000000000000000000000000000000000027 -:108950000000000000000000000000000000000017 -:108960000000000000000000000000000000000007 -:1089700000000000000000000000000000000000F7 -:1089800000000000000000000000000000000000E7 -:1089900000000000000000000000000000000000D7 -:1089A00000000000000000000000000000000000C7 -:1089B00000000000000000000000000000000000B7 -:1089C00000000000000000000000000000000000A7 -:1089D0000000000000000000000000000000000097 -:1089E0000000000000000000000000000000000087 -:1089F0000000000000000000000000000000000077 -:108A00000000000000000000000000000000000066 -:108A10000000000000000000000000000000000056 -:108A20000000000000000000000000000000000046 -:108A30000000000000000000000000000000000036 -:108A40000000000000000000000000000000000026 -:108A50000000000000000000000000000000000016 -:108A60000000000000000000000000000000000006 -:108A700000000000000000000000000000000000F6 -:108A800000000000000000000000000000000000E6 -:108A900000000000000000000000000000000000D6 -:108AA00000000000000000000000000000000000C6 -:108AB00000000000000000000000000000000000B6 -:108AC00000000000000000000000000000000000A6 -:108AD0000000000000000000000000000000000096 -:108AE0000000000000000000000000000000000086 -:108AF0000000000000000000000000000000000076 -:108B00000000000000000000000000000000000065 -:108B10000000000000000000000000000000000055 -:108B20000000000000000000000000000000000045 -:108B30000000000000000000000000000000000035 -:108B40000000000000000000000000000000000025 -:108B50000000000000000000000000000000000015 -:108B60000000000000000000000000000000000005 -:108B700000000000000000000000000000000000F5 -:108B800000000000000000000000000000000000E5 -:108B900000000000000000000000000000000000D5 -:108BA00000000000000000000000000000000000C5 -:108BB00000000000000000000000000000000000B5 -:108BC00000000000000000000000000000000000A5 -:108BD0000000000000000000000000000000000095 -:108BE0000000000000000000000000000000000085 -:108BF0000000000000000000000000000000000075 -:108C00000000000000000000000000000000000064 -:108C10000000000000000000000000000000000054 -:108C20000000000000000000000000000000000044 -:108C30000000000000000000000000000000000034 -:108C40000000000000000000000000000000000024 -:108C50000000000000000000000000000000000014 -:108C60000000000000000000000000000000000004 -:108C700000000000000000000000000000000000F4 -:108C800000000000000000000000000000000000E4 -:108C900000000000000000000000000000000000D4 -:108CA00000000000000000000000000000000000C4 -:108CB00000000000000000000000000000000000B4 -:108CC00000000000000000000000000000000000A4 -:108CD0000000000000000000000000000000000094 -:108CE0000000000000000000000000000000000084 -:108CF0000000000000000000000000000000000074 -:108D00000000000000000000000000000000000063 -:108D10000000000000000000000000000000000053 -:108D20000000000000000000000000000000000043 -:108D30000000000000000000000000000000000033 -:108D40000000000000000000000000000000000023 -:108D50000000000000000000000000000000000013 -:108D60000000000000000000000000000000000003 -:108D700000000000000000000000000000000000F3 -:108D800000000000000000000000000000000000E3 -:108D900000000000000000000000000000000000D3 -:108DA00000000000000000000000000000000000C3 -:108DB00000000000000000000000000000000000B3 -:108DC00000000000000000000000000000000000A3 -:108DD0000000000000000000000000000000000093 -:108DE0000000000000000000000000000000000083 -:108DF0000000000000000000000000000000000073 -:108E00000000000000000000000000000000000062 -:108E10000000000000000000000000000000000052 -:108E20000000000000000000000000000000000042 -:108E30000000000000000000000000000000000032 -:108E40000000000000000000000000000000000022 -:108E50000000000000000000000000000000000012 -:108E60000000000000000000000000000000000002 -:108E700000000000000000000000000000000000F2 -:108E800000000000000000000000000000000000E2 -:108E900000000000000000000000000000000000D2 -:108EA00000000000000000000000000000000000C2 -:108EB00000000000000000000000000000000000B2 -:108EC00000000000000000000000000000000000A2 -:108ED0000000000000000000000000000000000092 -:108EE0000000000000000000000000000000000082 -:108EF0000000000000000000000000000000000072 -:108F00000000000000000000000000000000000061 -:108F10000000000000000000000000000000000051 -:108F20000000000000000000000000000000000041 -:108F30000000000000000000000000000000000031 -:108F40000000000000000000000000000000000021 -:108F50000000000000000000000000000000000011 -:108F60000000000000000000000000000000000001 -:108F700000000000000000000000000000000000F1 -:108F800000000000000000000000000000000000E1 -:108F900000000000000000000000000000000000D1 -:108FA00000000000000000000000000000000000C1 -:108FB00000000000000000000000000000000000B1 -:108FC00000000000000000000000000000000000A1 -:108FD0000000000000000000000000000000000091 -:108FE0000000000000000000000000000000000081 -:108FF0000000000000000000000000000000000071 -:109000000000000000000000000000000000000060 -:109010000000000000000000000000000000000050 -:109020000000000000000000000000000000000040 -:109030000000000000000000000000000000000030 -:109040000000000000000000000000000000000020 -:109050000000000000000000000000000000000010 -:109060000000000000000000000000000000000000 -:1090700000000000000000000000000000000000F0 -:1090800000000000000000000000000000000000E0 -:1090900000000000000000000000000000000000D0 -:1090A00000000000000000000000000000000000C0 -:1090B00000000000000000000000000000000000B0 -:1090C00000000000000000000000000000000000A0 -:1090D0000000000000000000000000000000000090 -:1090E0000000000000000000000000000000000080 -:1090F0000000000000000000000000000000000070 -:10910000000000000000000000000000000000005F -:10911000000000000000000000000000000000004F -:10912000000000000000000000000000000000003F -:10913000000000000000000000000000000000002F -:10914000000000000000000000000000000000001F -:10915000000000000000000000000000000000000F -:1091600000000000000000000000000000000000FF -:1091700000000000000000000000000000000000EF -:1091800000000000000000000000000000000000DF -:1091900000000000000000000000000000000000CF -:1091A00000000000000000000000000000000000BF -:1091B00000000000000000000000000000000000AF -:1091C000000000000000000000000000000000009F -:1091D000000000000000000000000000000000008F -:1091E000000000000000000000000000000000007F -:1091F000000000000000000000000000000000006F -:10920000000000000000000000000000000000005E -:10921000000000000000000000000000000000004E -:10922000000000000000000000000000000000003E -:10923000000000000000000000000000000000002E -:10924000000000000000000000000000000000001E -:10925000000000000000000000000000000000000E -:1092600000000000000000000000000000000000FE -:1092700000000000000000000000000000000000EE -:1092800000000000000000000000000000000000DE -:1092900000000000000000000000000000000000CE -:1092A00000000000000000000000000000000000BE -:1092B00000000000000000000000000000000000AE -:1092C000000000000000000000000000000000009E -:1092D000000000000000000000000000000000008E -:1092E000000000000000000000000000000000007E -:1092F000000000000000000000000000000000006E -:10930000000000000000000000000000000000005D -:10931000000000000000000000000000000000004D -:10932000000000000000000000000000000000003D -:10933000000000000000000000000000000000002D -:10934000000000000000000000000000000000001D -:10935000000000000000000000000000000000000D -:1093600000000000000000000000000000000000FD -:1093700000000000000000000000000000000000ED -:1093800000000000000000000000000000000000DD -:1093900000000000000000000000000000000000CD -:1093A00000000000000000000000000000000000BD -:1093B00000000000000000000000000000000000AD -:1093C000000000000000000000000000000000009D -:1093D000000000000000000000000000000000008D -:1093E000000000000000000000000000000000007D -:1093F000000000000000000000000000000000006D -:10940000000000000000000000000000000000005C -:10941000000000000000000000000000000000004C -:10942000000000000000000000000000000000003C -:10943000000000000000000000000000000000002C -:10944000000000000000000000000000000000001C -:10945000000000000000000000000000000000000C -:1094600000000000000000000000000000000000FC -:1094700000000000000000000000000000000000EC -:1094800000000000000000000000000000000000DC -:1094900000000000000000000000000000000000CC -:1094A00000000000000000000000000000000000BC -:1094B00000000000000000000000000000000000AC -:1094C000000000000000000000000000000000009C -:1094D000000000000000000000000000000000008C -:1094E000000000000000000000000000000000007C -:1094F000000000000000000000000000000000006C -:10950000000000000000000000000000000000005B -:10951000000000000000000000000000000000004B -:10952000000000000000000000000000000000003B -:10953000000000000000000000000000000000002B -:10954000000000000000000000000000000000001B -:10955000000000000000000000000000000000000B -:1095600000000000000000000000000000000000FB -:1095700000000000000000000000000000000000EB -:1095800000000000000000000000000000000000DB -:1095900000000000000000000000000000000000CB -:1095A00000000000000000000000000000000000BB -:1095B00000000000000000000000000000000000AB -:1095C000000000000000000000000000000000009B -:1095D000000000000000000000000000000000008B -:1095E000000000000000000000000000000000007B -:1095F000000000000000000000000000000000006B -:10960000000000000000000000000000000000005A -:10961000000000000000000000000000000000004A -:10962000000000000000000000000000000000003A -:10963000000000000000000000000000000000002A -:10964000000000000000000000000000000000001A -:10965000000000000000000000000000000000000A -:1096600000000000000000000000000000000000FA -:1096700000000000000000000000000000000000EA -:1096800000000000000000000000000000000000DA -:1096900000000000000000000000000000000000CA -:1096A00000000000000000000000000000000000BA -:1096B00000000000000000000000000000000000AA -:1096C000000000000000000000000000000000009A -:1096D000000000000000000000000000000000008A -:1096E000000000000000000000000000000000007A -:1096F000000000000000000000000000000000006A -:109700000000000000000000000000000000000059 -:109710000000000000000000000000000000000049 -:109720000000000000000000000000000000000039 -:109730000000000000000000000000000000000029 -:109740000000000000000000000000000000000019 -:109750000000000000000000000000000000000009 -:1097600000000000000000000000000000000000F9 -:1097700000000000000000000000000000000000E9 -:1097800000000000000000000000000000000000D9 -:1097900000000000000000000000000000000000C9 -:1097A00000000000000000000000000000000000B9 -:1097B00000000000000000000000000000000000A9 -:1097C0000000000000000000000000000000000099 -:1097D0000000000000000000000000000000000089 -:1097E0000000000000000000000000000000000079 -:1097F0000000000000000000000000000000000069 -:109800000000000000000000000000000000000058 -:109810000000000000000000000000000000000048 -:109820000000000000000000000000000000000038 -:109830000000000000000000000000000000000028 -:109840000000000000000000000000000000000018 -:109850000000000000000000000000000000000008 -:1098600000000000000000000000000000000000F8 -:1098700000000000000000000000000000000000E8 -:1098800000000000000000000000000000000000D8 -:1098900000000000000000000000000000000000C8 -:1098A00000000000000000000000000000000000B8 -:1098B00000000000000000000000000000000000A8 -:1098C0000000000000000000000000000000000098 -:1098D0000000000000000000000000000000000088 -:1098E0000000000000000000000000000000000078 -:1098F0000000000000000000000000000000000068 -:109900000000000000000000000000000000000057 -:109910000000000000000000000000000000000047 -:109920000000000000000000000000000000000037 -:109930000000000000000000000000000000000027 -:109940000000000000000000000000000000000017 -:109950000000000000000000000000000000000007 -:1099600000000000000000000000000000000000F7 -:1099700000000000000000000000000000000000E7 -:1099800000000000000000000000000000000000D7 -:1099900000000000000000000000000000000000C7 -:1099A00000000000000000000000000000000000B7 -:1099B00000000000000000000000000000000000A7 -:1099C0000000000000000000000000000000000097 -:1099D0000000000000000000000000000000000087 -:1099E0000000000000000000000000000000000077 -:1099F0000000000000000000000000000000000067 -:109A00000000000000000000000000000000000056 -:109A10000000000000000000000000000000000046 -:109A20000000000000000000000000000000000036 -:109A30000000000000000000000000000000000026 -:109A40000000000000000000000000000000000016 -:109A50000000000000000000000000000000000006 -:109A600000000000000000000000000000000000F6 -:109A700000000000000000000000000000000000E6 -:109A800000000000000000000000000000000000D6 -:109A900000000000000000000000000000000000C6 -:109AA00000000000000000000000000000000000B6 -:109AB00000000000000000000000000000000000A6 -:109AC0000000000000000000000000000000000096 -:109AD0000000000000000000000000000000000086 -:109AE0000000000000000000000000000000000076 -:109AF0000000000000000000000000000000000066 -:109B00000000000000000000000000000000000055 -:109B10000000000000000000000000000000000045 -:109B20000000000000000000000000000000000035 -:109B30000000000000000000000000000000000025 -:109B40000000000000000000000000000000000015 -:109B50000000000000000000000000000000000005 -:109B600000000000000000000000000000000000F5 -:109B700000000000000000000000000000000000E5 -:109B800000000000000000000000000000000000D5 -:109B900000000000000000000000000000000000C5 -:109BA00000000000000000000000000000000000B5 -:109BB00000000000000000000000000000000000A5 -:109BC0000000000000000000000000000000000095 -:109BD0000000000000000000000000000000000085 -:109BE0000000000000000000000000000000000075 -:109BF0000000000000000000000000000000000065 -:109C00000000000000000000000000000000000054 -:109C10000000000000000000000000000000000044 -:109C20000000000000000000000000000000000034 -:109C30000000000000000000000000000000000024 -:109C40000000000000000000000000000000000014 -:109C50000000000000000000000000000000000004 -:109C600000000000000000000000000000000000F4 -:109C700000000000000000000000000000000000E4 -:109C800000000000000000000000000000000000D4 -:109C900000000000000000000000000000000000C4 -:109CA00000000000000000000000000000000000B4 -:109CB00000000000000000000000000000000000A4 -:109CC0000000000000000000000000000000000094 -:109CD0000000000000000000000000000000000084 -:109CE0000000000000000000000000000000000074 -:109CF0000000000000000000000000000000000064 -:109D00000000000000000000000000000000000053 -:109D10000000000000000000000000000000000043 -:109D20000000000000000000000000000000000033 -:109D30000000000000000000000000000000000023 -:109D40000000000000000000000000000000000013 -:109D50000000000000000000000000000000000003 -:109D600000000000000000000000000000000000F3 -:109D700000000000000000000000000000000000E3 -:109D800000000000000000000000000000000000D3 -:109D900000000000000000000000000000000000C3 -:109DA00000000000000000000000000000000000B3 -:109DB00000000000000000000000000000000000A3 -:109DC0000000000000000000000000000000000093 -:109DD0000000000000000000000000000000000083 -:109DE0000000000000000000000000000000000073 -:109DF0000000000000000000000000000000000063 -:109E00000000000000000000000000000000000052 -:109E10000000000000000000000000000000000042 -:109E20000000000000000000000000000000000032 -:109E30000000000000000000000000000000000022 -:109E40000000000000000000000000000000000012 -:109E50000000000000000000000000000000000002 -:109E600000000000000000000000000000000000F2 -:109E700000000000000000000000000000000000E2 -:109E800000000000000000000000000000000000D2 -:109E900000000000000000000000000000000000C2 -:109EA00000000000000000000000000000000000B2 -:109EB00000000000000000000000000000000000A2 -:109EC0000000000000000000000000000000000092 -:109ED0000000000000000000000000000000000082 -:109EE0000000000000000000000000000000000072 -:109EF0000000000000000000000000000000000062 -:109F00000000000000000000000000000000000051 -:109F10000000000000000000000000000000000041 -:109F20000000000000000000000000000000000031 -:109F30000000000000000000000000000000000021 -:109F40000000000000000000000000000000000011 -:109F50000000000000000000000000000000000001 -:109F600000000000000000000000000000000000F1 -:109F700000000000000000000000000000000000E1 -:109F800000000000000000000000000000000000D1 -:109F900000000000000000000000000000000000C1 -:109FA00000000000000000000000000000000000B1 -:109FB00000000000000000000000000000000000A1 -:109FC0000000000000000000000000000000000091 -:109FD0000000000000000000000000000000000081 -:109FE0000000000000000000000000000000000071 -:109FF0000000000000000000000000000000000061 -:10A000000000000000000000000000000000000050 -:10A010000000000000000000000000000000000040 -:10A020000000000000000000000000000000000030 -:10A030000000000000000000000000000000000020 -:10A040000000000000000000000000000000000010 -:10A050000000000000000000000000000000000000 -:10A0600000000000000000000000000000000000F0 -:10A0700000000000000000000000000000000000E0 -:10A0800000000000000000000000000000000000D0 -:10A0900000000000000000000000000000000000C0 -:10A0A00000000000000000000000000000000000B0 -:10A0B00000000000000000000000000000000000A0 -:10A0C0000000000000000000000000000000000090 -:10A0D0000000000000000000000000000000000080 -:10A0E0000000000000000000000000000000000070 -:10A0F0000000000000000000000000000000000060 -:10A10000000000000000000000000000000000004F -:10A11000000000000000000000000000000000003F -:10A12000000000000000000000000000000000002F -:10A13000000000000000000000000000000000001F -:10A14000000000000000000000000000000000000F -:10A1500000000000000000000000000000000000FF -:10A1600000000000000000000000000000000000EF -:10A1700000000000000000000000000000000000DF -:10A1800000000000000000000000000000000000CF -:10A1900000000000000000000000000000000000BF -:10A1A00000000000000000000000000000000000AF -:10A1B000000000000000000000000000000000009F -:10A1C000000000000000000000000000000000008F -:10A1D000000000000000000000000000000000007F -:10A1E000000000000000000000000000000000006F -:10A1F000000000000000000000000000000000005F -:10A20000000000000000000000000000000000004E -:10A21000000000000000000000000000000000003E -:10A22000000000000000000000000000000000002E -:10A23000000000000000000000000000000000001E -:10A24000000000000000000000000000000000000E -:10A2500000000000000000000000000000000000FE -:10A2600000000000000000000000000000000000EE -:10A2700000000000000000000000000000000000DE -:10A2800000000000000000000000000000000000CE -:10A2900000000000000000000000000000000000BE -:10A2A00000000000000000000000000000000000AE -:10A2B000000000000000000000000000000000009E -:10A2C000000000000000000000000000000000008E -:10A2D000000000000000000000000000000000007E -:10A2E000000000000000000000000000000000006E -:10A2F000000000000000000000000000000000005E -:10A30000000000000000000000000000000000004D -:10A31000000000000000000000000000000000003D -:10A32000000000000000000000000000000000002D -:10A33000000000000000000000000000000000001D -:10A34000000000000000000000000000000000000D -:10A3500000000000000000000000000000000000FD -:10A3600000000000000000000000000000000000ED -:10A3700000000000000000000000000000000000DD -:10A3800000000000000000000000000000000000CD -:10A3900000000000000000000000000000000000BD -:10A3A00000000000000000000000000000000000AD -:10A3B000000000000000000000000000000000009D -:10A3C000000000000000000000000000000000008D -:10A3D000000000000000000000000000000000007D -:10A3E000000000000000000000000000000000006D -:10A3F000000000000000000000000000000000005D -:10A40000000000000000000000000000000000004C -:10A41000000000000000000000000000000000003C -:10A42000000000000000000000000000000000002C -:10A43000000000000000000000000000000000001C -:10A44000000000000000000000000000000000000C -:10A4500000000000000000000000000000000000FC -:10A4600000000000000000000000000000000000EC -:10A4700000000000000000000000000000000000DC -:10A4800000000000000000000000000000000000CC -:10A4900000000000000000000000000000000000BC -:10A4A00000000000000000000000000000000000AC -:10A4B000000000000000000000000000000000009C -:10A4C000000000000000000000000000000000008C -:10A4D000000000000000000000000000000000007C -:10A4E000000000000000000000000000000000006C -:10A4F000000000000000000000000000000000005C -:10A50000000000000000000000000000000000004B -:10A51000000000000000000000000000000000003B -:10A52000000000000000000000000000000000002B -:10A53000000000000000000000000000000000001B -:10A54000000000000000000000000000000000000B -:10A5500000000000000000000000000000000000FB -:10A5600000000000000000000000000000000000EB -:10A5700000000000000000000000000000000000DB -:10A5800000000000000000000000000000000000CB -:10A5900000000000000000000000000000000000BB -:10A5A00000000000000000000000000000000000AB -:10A5B000000000000000000000000000000000009B -:10A5C000000000000000000000000000000000008B -:10A5D000000000000000000000000000000000007B -:10A5E000000000000000000000000000000000006B -:10A5F000000000000000000000000000000000005B -:10A60000000000000000000000000000000000004A -:10A61000000000000000000000000000000000003A -:10A62000000000000000000000000000000000002A -:10A63000000000000000000000000000000000001A -:10A64000000000000000000000000000000000000A -:10A6500000000000000000000000000000000000FA -:10A6600000000000000000000000000000000000EA -:10A6700000000000000000000000000000000000DA -:10A6800000000000000000000000000000000000CA -:10A6900000000000000000000000000000000000BA -:10A6A00000000000000000000000000000000000AA -:10A6B000000000000000000000000000000000009A -:10A6C000000000000000000000000000000000008A -:10A6D000000000000000000000000000000000007A -:10A6E000000000000000000000000000000000006A -:10A6F000000000000000000000000000000000005A -:10A700000000000000000000000000000000000049 -:10A710000000000000000000000000000000000039 -:10A720000000000000000000000000000000000029 -:10A730000000000000000000000000000000000019 -:10A740000000000000000000000000000000000009 -:10A7500000000000000000000000000000000000F9 -:10A7600000000000000000000000000000000000E9 -:10A7700000000000000000000000000000000000D9 -:10A7800000000000000000000000000000000000C9 -:10A7900000000000000000000000000000000000B9 -:10A7A00000000000000000000000000000000000A9 -:10A7B0000000000000000000000000000000000099 -:10A7C0000000000000000000000000000000000089 -:10A7D0000000000000000000000000000000000079 -:10A7E0000000000000000000000000000000000069 -:10A7F0000000000000000000000000000000000059 -:10A800000000000000000000000000000000000048 -:10A810000000000000000000000000000000000038 -:10A820000000000000000000000000000000000028 -:10A830000000000000000000000000000000000018 -:10A840000000000000000000000000000000000008 -:10A8500000000000000000000000000000000000F8 -:10A8600000000000000000000000000000000000E8 -:10A8700000000000000000000000000000000000D8 -:10A8800000000000000000000000000000000000C8 -:10A8900000000000000000000000000000000000B8 -:10A8A00000000000000000000000000000000000A8 -:10A8B0000000000000000000000000000000000098 -:10A8C0000000000000000000000000000000000088 -:10A8D0000000000000000000000000000000000078 -:10A8E0000000000000000000000000000000000068 -:10A8F0000000000000000000000000000000000058 -:10A900000000000000000000000000000000000047 -:10A910000000000000000000000000000000000037 -:10A920000000000000000000000000000000000027 -:10A930000000000000000000000000000000000017 -:10A940000000000000000000000000000000000007 -:10A9500000000000000000000000000000000000F7 -:10A9600000000000000000000000000000000000E7 -:10A9700000000000000000000000000000000000D7 -:10A9800000000000000000000000000000000000C7 -:10A9900000000000000000000000000000000000B7 -:10A9A00000000000000000000000000000000000A7 -:10A9B0000000000000000000000000000000000097 -:10A9C0000000000000000000000000000000000087 -:10A9D0000000000000000000000000000000000077 -:10A9E0000000000000000000000000000000000067 -:10A9F0000000000000000000000000000000000057 -:10AA00000000000000000000000000000000000046 -:10AA10000000000000000000000000000000000036 -:10AA20000000000000000000000000000000000026 -:10AA30000000000000000000000000000000000016 -:10AA40000000000000000000000000000000000006 -:10AA500000000000000000000000000000000000F6 -:10AA600000000000000000000000000000000000E6 -:10AA700000000000000000000000000000000000D6 -:10AA800000000000000000000000000000000000C6 -:10AA900000000000000000000000000000000000B6 -:10AAA00000000000000000000000000000000000A6 -:10AAB0000000000000000000000000000000000096 -:10AAC0000000000000000000000000000000000086 -:10AAD0000000000000000000000000000000000076 -:10AAE0000000000000000000000000000000000066 -:10AAF0000000000000000000000000000000000056 -:10AB00000000000000000000000000000000000045 -:10AB10000000000000000000000000000000000035 -:10AB20000000000000000000000000000000000025 -:10AB30000000000000000000000000000000000015 -:10AB40000000000000000000000000000000000005 -:10AB500000000000000000000000000000000000F5 -:10AB600000000000000000000000000000000000E5 -:10AB700000000000000000000000000000000000D5 -:10AB800000000000000000000000000000000000C5 -:10AB900000000000000000000000000000000000B5 -:10ABA00000000000000000000000000000000000A5 -:10ABB0000000000000000000000000000000000095 -:10ABC0000000000000000000000000000000000085 -:10ABD0000000000000000000000000000000000075 -:10ABE0000000000000000000000000000000000065 -:10ABF0000000000000000000000000000000000055 -:10AC00000000000000000000000000000000000044 -:10AC10000000000000000000000000000000000034 -:10AC20000000000000000000000000000000000024 -:10AC30000000000000000000000000000000000014 -:10AC40000000000000000000000000000000000004 -:10AC500000000000000000000000000000000000F4 -:10AC600000000000000000000000000000000000E4 -:10AC700000000000000000000000000000000000D4 -:10AC800000000000000000000000000000000000C4 -:10AC900000000000000000000000000000000000B4 -:10ACA00000000000000000000000000000000000A4 -:10ACB0000000000000000000000000000000000094 -:10ACC0000000000000000000000000000000000084 -:10ACD0000000000000000000000000000000000074 -:10ACE0000000000000000000000000000000000064 -:10ACF0000000000000000000000000000000000054 -:10AD00000000000000000000000000000000000043 -:10AD10000000000000000000000000000000000033 -:10AD20000000000000000000000000000000000023 -:10AD30000000000000000000000000000000000013 -:10AD40000000000000000000000000000000000003 -:10AD500000000000000000000000000000000000F3 -:10AD600000000000000000000000000000000000E3 -:10AD700000000000000000000000000000000000D3 -:10AD800000000000000000000000000000000000C3 -:10AD900000000000000000000000000000000000B3 -:10ADA00000000000000000000000000000000000A3 -:10ADB0000000000000000000000000000000000093 -:10ADC0000000000000000000000000000000000083 -:10ADD0000000000000000000000000000000000073 -:10ADE0000000000000000000000000000000000063 -:10ADF0000000000000000000000000000000000053 -:10AE00000000000000000000000000000000000042 -:10AE10000000000000000000000000000000000032 -:10AE20000000000000000000000000000000000022 -:10AE30000000000000000000000000000000000012 -:10AE40000000000000000000000000000000000002 -:10AE500000000000000000000000000000000000F2 -:10AE600000000000000000000000000000000000E2 -:10AE700000000000000000000000000000000000D2 -:10AE800000000000000000000000000000000000C2 -:10AE900000000000000000000000000000000000B2 -:10AEA00000000000000000000000000000000000A2 -:10AEB0000000000000000000000000000000000092 -:10AEC0000000000000000000000000000000000082 -:10AED0000000000000000000000000000000000072 -:10AEE0000000000000000000000000000000000062 -:10AEF0000000000000000000000000000000000052 -:10AF00000000000000000000000000000000000041 -:10AF10000000000000000000000000000000000031 -:10AF20000000000000000000000000000000000021 -:10AF30000000000000000000000000000000000011 -:10AF40000000000000000000000000000000000001 -:10AF500000000000000000000000000000000000F1 -:10AF600000000000000000000000000000000000E1 -:10AF700000000000000000000000000000000000D1 -:10AF800000000000000000000000000000000000C1 -:10AF900000000000000000000000000000000000B1 -:10AFA00000000000000000000000000000000000A1 -:10AFB0000000000000000000000000000000000091 -:10AFC0000000000000000000000000000000000081 -:10AFD0000000000000000000000000000000000071 -:10AFE0000000000000000000000000000000000061 -:10AFF0000000000000000000000000000000000051 -:10B000000000000000000000000000000000000040 -:10B010000000000000000000000000000000000030 -:10B020000000000000000000000000000000000020 -:10B030000000000000000000000000000000000010 -:10B040000000000000000000000000000000000000 -:10B0500000000000000000000000000000000000F0 -:10B0600000000000000000000000000000000000E0 -:10B0700000000000000000000000000000000000D0 -:10B0800000000000000000000000000000000000C0 -:10B0900000000000000000000000000000000000B0 -:10B0A00000000000000000000000000000000000A0 -:10B0B0000000000000000000000000000000000090 -:10B0C0000000000000000000000000000000000080 -:10B0D0000000000000000000000000000000000070 -:10B0E0000000000000000000000000000000000060 -:10B0F0000000000000000000000000000000000050 -:10B10000000000000000000000000000000000003F -:10B11000000000000000000000000000000000002F -:10B12000000000000000000000000000000000001F -:10B13000000000000000000000000000000000000F -:10B1400000000000000000000000000000000000FF -:10B1500000000000000000000000000000000000EF -:10B1600000000000000000000000000000000000DF -:10B1700000000000000000000000000000000000CF -:10B1800000000000000000000000000000000000BF -:10B1900000000000000000000000000000000000AF -:10B1A000000000000000000000000000000000009F -:10B1B000000000000000000000000000000000008F -:10B1C000000000000000000000000000000000007F -:10B1D000000000000000000000000000000000006F -:10B1E000000000000000000000000000000000005F -:10B1F000000000000000000000000000000000004F -:10B20000000000000000000000000000000000003E -:10B21000000000000000000000000000000000002E -:10B22000000000000000000000000000000000001E -:10B23000000000000000000000000000000000000E -:10B2400000000000000000000000000000000000FE -:10B2500000000000000000000000000000000000EE -:10B2600000000000000000000000000000000000DE -:10B2700000000000000000000000000000000000CE -:10B2800000000000000000000000000000000000BE -:10B2900000000000000000000000000000000000AE -:10B2A000000000000000000000000000000000009E -:10B2B000000000000000000000000000000000008E -:10B2C000000000000000000000000000000000007E -:10B2D000000000000000000000000000000000006E -:10B2E000000000000000000000000000000000005E -:10B2F000000000000000000000000000000000004E -:10B30000000000000000000000000000000000003D -:10B31000000000000000000000000000000000002D -:10B32000000000000000000000000000000000001D -:10B33000000000000000000000000000000000000D -:10B3400000000000000000000000000000000000FD -:10B3500000000000000000000000000000000000ED -:10B3600000000000000000000000000000000000DD -:10B3700000000000000000000000000000000000CD -:10B3800000000000000000000000000000000000BD -:10B3900000000000000000000000000000000000AD -:10B3A000000000000000000000000000000000009D -:10B3B000000000000000000000000000000000008D -:10B3C000000000000000000000000000000000007D -:10B3D000000000000000000000000000000000006D -:10B3E000000000000000000000000000000000005D -:10B3F000000000000000000000000000000000004D -:10B40000000000000000000000000000000000003C -:10B41000000000000000000000000000000000002C -:10B42000000000000000000000000000000000001C -:10B43000000000000000000000000000000000000C -:10B4400000000000000000000000000000000000FC -:10B4500000000000000000000000000000000000EC -:10B4600000000000000000000000000000000000DC -:10B4700000000000000000000000000000000000CC -:10B4800000000000000000000000000000000000BC -:10B4900000000000000000000000000000000000AC -:10B4A000000000000000000000000000000000009C -:10B4B000000000000000000000000000000000008C -:10B4C000000000000000000000000000000000007C -:10B4D000000000000000000000000000000000006C -:10B4E000000000000000000000000000000000005C -:10B4F000000000000000000000000000000000004C -:10B50000000000000000000000000000000000003B -:10B51000000000000000000000000000000000002B -:10B52000000000000000000000000000000000001B -:10B53000000000000000000000000000000000000B -:10B5400000000000000000000000000000000000FB -:10B5500000000000000000000000000000000000EB -:10B5600000000000000000000000000000000000DB -:10B5700000000000000000000000000000000000CB -:10B5800000000000000000000000000000000000BB -:10B5900000000000000000000000000000000000AB -:10B5A000000000000000000000000000000000009B -:10B5B000000000000000000000000000000000008B -:10B5C000000000000000000000000000000000007B -:10B5D000000000000000000000000000000000006B -:10B5E000000000000000000000000000000000005B -:10B5F000000000000000000000000000000000004B -:10B60000000000000000000000000000000000003A -:10B61000000000000000000000000000000000002A -:10B62000000000000000000000000000000000001A -:10B63000000000000000000000000000000000000A -:10B6400000000000000000000000000000000000FA -:10B6500000000000000000000000000000000000EA -:10B6600000000000000000000000000000000000DA -:10B6700000000000000000000000000000000000CA -:10B6800000000000000000000000000000000000BA -:10B6900000000000000000000000000000000000AA -:10B6A000000000000000000000000000000000009A -:10B6B000000000000000000000000000000000008A -:10B6C000000000000000000000000000000000007A -:10B6D000000000000000000000000000000000006A -:10B6E000000000000000000000000000000000005A -:10B6F000000000000000000000000000000000004A -:10B700000000000000000000000000000000000039 -:10B710000000000000000000000000000000000029 -:10B720000000000000000000000000000000000019 -:10B730000000000000000000000000000000000009 -:10B7400000000000000000000000000000000000F9 -:10B7500000000000000000000000000000000000E9 -:10B7600000000000000000000000000000000000D9 -:10B7700000000000000000000000000000000000C9 -:10B7800000000000000000000000000000000000B9 -:10B7900000000000000000000000000000000000A9 -:10B7A0000000000000000000000000000000000099 -:10B7B0000000000000000000000000000000000089 -:10B7C0000000000000000000000000000000000079 -:10B7D0000000000000000000000000000000000069 -:10B7E0000000000000000000000000000000000059 -:10B7F0000000000000000000000000000000000049 -:10B800000000000000000000000000000000000038 -:10B810000000000000000000000000000000000028 -:10B820000000000000000000000000000000000018 -:10B830000000000000000000000000000000000008 -:10B8400000000000000000000000000000000000F8 -:10B8500000000000000000000000000000000000E8 -:10B8600000000000000000000000000000000000D8 -:10B8700000000000000000000000000000000000C8 -:10B8800000000000000000000000000000000000B8 -:10B8900000000000000000000000000000000000A8 -:10B8A0000000000000000000000000000000000098 -:10B8B0000000000000000000000000000000000088 -:10B8C0000000000000000000000000000000000078 -:10B8D0000000000000000000000000000000000068 -:10B8E0000000000000000000000000000000000058 -:10B8F0000000000000000000000000000000000048 -:10B900000000000000000000000000000000000037 -:10B910000000000000000000000000000000000027 -:10B920000000000000000000000000000000000017 -:10B930000000000000000000000000000000000007 -:10B9400000000000000000000000000000000000F7 -:10B9500000000000000000000000000000000000E7 -:10B9600000000000000000000000000000000000D7 -:10B9700000000000000000000000000000000000C7 -:10B9800000000000000000000000000000000000B7 -:10B9900000000000000000000000000000000000A7 -:10B9A0000000000000000000000000000000000097 -:10B9B0000000000000000000000000000000000087 -:10B9C0000000000000000000000000000000000077 -:10B9D0000000000000000000000000000000000067 -:10B9E0000000000000000000000000000000000057 -:10B9F0000000000000000000000000000000000047 -:10BA00000000000000000000000000000000000036 -:10BA10000000000000000000000000000000000026 -:10BA20000000000000000000000000000000000016 -:10BA30000000000000000000000000000000000006 -:10BA400000000000000000000000000000000000F6 -:10BA500000000000000000000000000000000000E6 -:10BA600000000000000000000000000000000000D6 -:10BA700000000000000000000000000000000000C6 -:10BA800000000000000000000000000000000000B6 -:10BA900000000000000000000000000000000000A6 -:10BAA0000000000000000000000000000000000096 -:10BAB0000000000000000000000000000000000086 -:10BAC0000000000000000000000000000000000076 -:10BAD0000000000000000000000000000000000066 -:10BAE0000000000000000000000000000000000056 -:10BAF0000000000000000000000000000000000046 -:10BB00000000000000000000000000000000000035 -:10BB10000000000000000000000000000000000025 -:10BB20000000000000000000000000000000000015 -:10BB30000000000000000000000000000000000005 -:10BB400000000000000000000000000000000000F5 -:10BB500000000000000000000000000000000000E5 -:10BB600000000000000000000000000000000000D5 -:10BB700000000000000000000000000000000000C5 -:10BB800000000000000000000000000000000000B5 -:10BB900000000000000000000000000000000000A5 -:10BBA0000000000000000000000000000000000095 -:10BBB0000000000000000000000000000000000085 -:10BBC0000000000000000000000000000000000075 -:10BBD0000000000000000000000000000000000065 -:10BBE0000000000000000000000000000000000055 -:10BBF0000000000000000000000000000000000045 -:10BC00000000000000000000000000000000000034 -:10BC10000000000000000000000000000000000024 -:10BC20000000000000000000000000000000000014 -:10BC30000000000000000000000000000000000004 -:10BC400000000000000000000000000000000000F4 -:10BC500000000000000000000000000000000000E4 -:10BC600000000000000000000000000000000000D4 -:10BC700000000000000000000000000000000000C4 -:10BC800000000000000000000000000000000000B4 -:10BC900000000000000000000000000000000000A4 -:10BCA0000000000000000000000000000000000094 -:10BCB0000000000000000000000000000000000084 -:10BCC0000000000000000000000000000000000074 -:10BCD0000000000000000000000000000000000064 -:10BCE0000000000000000000000000000000000054 -:10BCF0000000000000000000000000000000000044 -:10BD00000000000000000000000000000000000033 -:10BD10000000000000000000000000000000000023 -:10BD20000000000000000000000000000000000013 -:10BD30000000000000000000000000000000000003 -:10BD400000000000000000000000000000000000F3 -:10BD500000000000000000000000000000000000E3 -:10BD600000000000000000000000000000000000D3 -:10BD700000000000000000000000000000000000C3 -:10BD800000000000000000000000000000000000B3 -:10BD900000000000000000000000000000000000A3 -:10BDA0000000000000000000000000000000000093 -:10BDB0000000000000000000000000000000000083 -:10BDC0000000000000000000000000000000000073 -:10BDD0000000000000000000000000000000000063 -:10BDE0000000000000000000000000000000000053 -:10BDF0000000000000000000000000000000000043 -:10BE00000000000000000000000000000000000032 -:10BE10000000000000000000000000000000000022 -:10BE20000000000000000000000000000000000012 -:10BE30000000000000000000000000000000000002 -:10BE400000000000000000000000000000000000F2 -:10BE500000000000000000000000000000000000E2 -:10BE600000000000000000000000000000000000D2 -:10BE700000000000000000000000000000000000C2 -:10BE800000000000000000000000000000000000B2 -:10BE900000000000000000000000000000000000A2 -:10BEA0000000000000000000000000000000000092 -:10BEB0000000000000000000000000000000000082 -:10BEC0000000000000000000000000000000000072 -:10BED0000000000000000000000000000000000062 -:10BEE0000000000000000000000000000000000052 -:10BEF0000000000000000000000000000000000042 -:10BF00000000000000000000000000000000000031 -:10BF10000000000000000000000000000000000021 -:10BF20000000000000000000000000000000000011 -:10BF30000000000000000000000000000000000001 -:10BF400000000000000000000000000000000000F1 -:10BF500000000000000000000000000000000000E1 -:10BF600000000000000000000000000000000000D1 -:10BF700000000000000000000000000000000000C1 -:10BF800000000000000000000000000000000000B1 -:10BF900000000000000000000000000000000000A1 -:10BFA0000000000000000000000000000000000091 -:10BFB0000000000000000000000000000000000081 -:10BFC0000000000000000000000000000000000071 -:10BFD0000000000000000000000000000000000061 -:10BFE0000000000000000000000000000000000051 -:10BFF0000000000000000000000000000000000041 -:10C000000000000000000000000000000000000030 -:10C010000000000000000000000000000000000020 -:10C020000000000000000000000000000000000010 -:10C030000000000000000000000000000000000000 -:10C0400000000000000000000000000000000000F0 -:10C0500000000000000000000000000000000000E0 -:10C0600000000000000000000000000000000000D0 -:10C0700000000000000000000000000000000000C0 -:10C0800000000000000000000000000000000000B0 -:10C0900000000000000000000000000000000000A0 -:10C0A0000000000000000000000000000000000090 -:10C0B0000000000000000000000000000000000080 -:10C0C0000000000000000000000000000000000070 -:10C0D0000000000000000000000000000000000060 -:10C0E0000000000000000000000000000000000050 -:10C0F0000000000000000000000000000000000040 -:10C10000000000000000000000000000000000002F -:10C11000000000000000000000000000000000001F -:10C12000000000000000000000000000000000000F -:10C1300000000000000000000000000000000000FF -:10C1400000000000000000000000000000000000EF -:10C1500000000000000000000000000000000000DF -:10C1600000000000000000000000000000000000CF -:10C1700000000000000000000000000000000000BF -:10C1800000000000000000000000000000000000AF -:10C19000000000000000000000000000000000009F -:10C1A000000000000000000000000000000000008F -:10C1B000000000000000000000000000000000007F -:10C1C000000000000000000000000000000000006F -:10C1D000000000000000000000000000000000005F -:10C1E000000000000000000000000000000000004F -:10C1F000000000000000000000000000000000003F -:10C20000000000000000000000000000000000002E -:10C21000000000000000000000000000000000001E -:10C22000000000000000000000000000000000000E -:10C2300000000000000000000000000000000000FE -:10C2400000000000000000000000000000000000EE -:10C2500000000000000000000000000000000000DE -:10C2600000000000000000000000000000000000CE -:10C2700000000000000000000000000000000000BE -:10C2800000000000000000000000000000000000AE -:10C29000000000000000000000000000000000009E -:10C2A000000000000000000000000000000000008E -:10C2B000000000000000000000000000000000007E -:10C2C000000000000000000000000000000000006E -:10C2D000000000000000000000000000000000005E -:10C2E000000000000000000000000000000000004E -:10C2F000000000000000000000000000000000003E -:10C30000000000000000000000000000000000002D -:10C31000000000000000000000000000000000001D -:10C32000000000000000000000000000000000000D -:10C3300000000000000000000000000000000000FD -:10C3400000000000000000000000000000000000ED -:10C3500000000000000000000000000000000000DD -:10C3600000000000000000000000000000000000CD -:10C3700000000000000000000000000000000000BD -:10C3800000000000000000000000000000000000AD -:10C39000000000000000000000000000000000009D -:10C3A000000000000000000000000000000000008D -:10C3B000000000000000000000000000000000007D -:10C3C000000000000000000000000000000000006D -:10C3D000000000000000000000000000000000005D -:10C3E000000000000000000000000000000000004D -:10C3F000000000000000000000000000000000003D -:10C40000000000000000000000000000000000002C -:10C41000000000000000000000000000000000001C -:10C42000000000000000000000000000000000000C -:10C4300000000000000000000000000000000000FC -:10C4400000000000000000000000000000000000EC -:10C4500000000000000000000000000000000000DC -:10C4600000000000000000000000000000000000CC -:10C4700000000000000000000000000000000000BC -:10C4800000000000000000000000000000000000AC -:10C49000000000000000000000000000000000009C -:10C4A000000000000000000000000000000000008C -:10C4B000000000000000000000000000000000007C -:10C4C000000000000000000000000000000000006C -:10C4D000000000000000000000000000000000005C -:10C4E000000000000000000000000000000000004C -:10C4F000000000000000000000000000000000003C -:10C50000000000000000000000000000000000002B -:10C51000000000000000000000000000000000001B -:10C52000000000000000000000000000000000000B -:10C5300000000000000000000000000000000000FB -:10C5400000000000000000000000000000000000EB -:10C5500000000000000000000000000000000000DB -:10C5600000000000000000000000000000000000CB -:10C5700000000000000000000000000000000000BB -:10C5800000000000000000000000000000000000AB -:10C59000000000000000000000000000000000009B -:10C5A000000000000000000000000000000000008B -:10C5B000000000000000000000000000000000007B -:10C5C000000000000000000000000000000000006B -:10C5D000000000000000000000000000000000005B -:10C5E000000000000000000000000000000000004B -:10C5F000000000000000000000000000000000003B -:10C60000000000000000000000000000000000002A -:10C61000000000000000000000000000000000001A -:10C62000000000000000000000000000000000000A -:10C6300000000000000000000000000000000000FA -:10C6400000000000000000000000000000000000EA -:10C6500000000000000000000000000000000000DA -:10C6600000000000000000000000000000000000CA -:10C6700000000000000000000000000000000000BA -:10C6800000000000000000000000000000000000AA -:10C69000000000000000000000000000000000009A -:10C6A000000000000000000000000000000000008A -:10C6B000000000000000000000000000000000007A -:10C6C000000000000000000000000000000000006A -:10C6D000000000000000000000000000000000005A -:10C6E000000000000000000000000000000000004A -:10C6F000000000000000000000000000000000003A -:10C700000000000000000000000000000000000029 -:10C710000000000000000000000000000000000019 -:10C720000000000000000000000000000000000009 -:10C7300000000000000000000000000000000000F9 -:10C7400000000000000000000000000000000000E9 -:10C7500000000000000000000000000000000000D9 -:10C7600000000000000000000000000000000000C9 -:10C7700000000000000000000000000000000000B9 -:10C7800000000000000000000000000000000000A9 -:10C790000000000000000000000000000000000099 -:10C7A0000000000000000000000000000000000089 -:10C7B0000000000000000000000000000000000079 -:10C7C0000000000000000000000000000000000069 -:10C7D0000000000000000000000000000000000059 -:10C7E0000000000000000000000000000000000049 -:10C7F0000000000000000000000000000000000039 -:10C800000000000000000000000000000000000028 -:10C810000000000000000000000000000000000018 -:10C820000000000000000000000000000000000008 -:10C8300000000000000000000000000000000000F8 -:10C8400000000000000000000000000000000000E8 -:10C8500000000000000000000000000000000000D8 -:10C8600000000000000000000000000000000000C8 -:10C8700000000000000000000000000000000000B8 -:10C8800000000000000000000000000000000000A8 -:10C890000000000000000000000000000000000098 -:10C8A0000000000000000000000000000000000088 -:10C8B0000000000000000000000000000000000078 -:10C8C0000000000000000000000000000000000068 -:10C8D0000000000000000000000000000000000058 -:10C8E0000000000000000000000000000000000048 -:10C8F0000000000000000000000000000000000038 -:10C900000000000000000000000000000000000027 -:10C910000000000000000000000000000000000017 -:10C920000000000000000000000000000000000007 -:10C9300000000000000000000000000000000000F7 -:10C9400000000000000000000000000000000000E7 -:10C9500000000000000000000000000000000000D7 -:10C9600000000000000000000000000000000000C7 -:10C9700000000000000000000000000000000000B7 -:10C9800000000000000000000000000000000000A7 -:10C990000000000000000000000000000000000097 -:10C9A0000000000000000000000000000000000087 -:10C9B0000000000000000000000000000000000077 -:10C9C0000000000000000000000000000000000067 -:10C9D0000000000000000000000000000000000057 -:10C9E0000000000000000000000000000000000047 -:10C9F0000000000000000000000000000000000037 -:10CA00000000000000000000000000000000000026 -:10CA10000000000000000000000000000000000016 -:10CA20000000000000000000000000000000000006 -:10CA300000000000000000000000000000000000F6 -:10CA400000000000000000000000000000000000E6 -:10CA500000000000000000000000000000000000D6 -:10CA600000000000000000000000000000000000C6 -:10CA700000000000000000000000000000000000B6 -:10CA800000000000000000000000000000000000A6 -:10CA90000000000000000000000000000000000096 -:10CAA0000000000000000000000000000000000086 -:10CAB0000000000000000000000000000000000076 -:10CAC0000000000000000000000000000000000066 -:10CAD0000000000000000000000000000000000056 -:10CAE0000000000000000000000000000000000046 -:10CAF0000000000000000000000000000000000036 -:10CB00000000000000000000000000000000000025 -:10CB10000000000000000000000000000000000015 -:10CB20000000000000000000000000000000000005 -:10CB300000000000000000000000000000000000F5 -:10CB400000000000000000000000000000000000E5 -:10CB500000000000000000000000000000000000D5 -:10CB600000000000000000000000000000000000C5 -:10CB700000000000000000000000000000000000B5 -:10CB800000000000000000000000000000000000A5 -:10CB90000000000000000000000000000000000095 -:10CBA0000000000000000000000000000000000085 -:10CBB0000000000000000000000000000000000075 -:10CBC0000000000000000000000000000000000065 -:10CBD0000000000000000000000000000000000055 -:10CBE0000000000000000000000000000000000045 -:10CBF0000000000000000000000000000000000035 -:10CC00000000000000000000000000000000000024 -:10CC10000000000000000000000000000000000014 -:10CC20000000000000000000000000000000000004 -:10CC300000000000000000000000000000000000F4 -:10CC400000000000000000000000000000000000E4 -:10CC500000000000000000000000000000000000D4 -:10CC600000000000000000000000000000000000C4 -:10CC700000000000000000000000000000000000B4 -:10CC800000000000000000000000000000000000A4 -:10CC90000000000000000000000000000000000094 -:10CCA0000000000000000000000000000000000084 -:10CCB0000000000000000000000000000000000074 -:10CCC0000000000000000000000000000000000064 -:10CCD0000000000000000000000000000000000054 -:10CCE0000000000000000000000000000000000044 -:10CCF0000000000000000000000000000000000034 -:10CD00000000000000000000000000000000000023 -:10CD10000000000000000000000000000000000013 -:10CD20000000000000000000000000000000000003 -:10CD300000000000000000000000000000000000F3 -:10CD400000000000000000000000000000000000E3 -:10CD500000000000000000000000000000000000D3 -:10CD600000000000000000000000000000000000C3 -:10CD700000000000000000000000000000000000B3 -:10CD800000000000000000000000000000000000A3 -:10CD90000000000000000000000000000000000093 -:10CDA0000000000000000000000000000000000083 -:10CDB0000000000000000000000000000000000073 -:10CDC0000000000000000000000000000000000063 -:10CDD0000000000000000000000000000000000053 -:10CDE0000000000000000000000000000000000043 -:10CDF0000000000000000000000000000000000033 -:10CE00000000000000000000000000000000000022 -:10CE10000000000000000000000000000000000012 -:10CE20000000000000000000000000000000000002 -:10CE300000000000000000000000000000000000F2 -:10CE400000000000000000000000000000000000E2 -:10CE500000000000000000000000000000000000D2 -:10CE600000000000000000000000000000000000C2 -:10CE700000000000000000000000000000000000B2 -:10CE800000000000000000000000000000000000A2 -:10CE90000000000000000000000000000000000092 -:10CEA0000000000000000000000000000000000082 -:10CEB0000000000000000000000000000000000072 -:10CEC0000000000000000000000000000000000062 -:10CED0000000000000000000000000000000000052 -:10CEE0000000000000000000000000000000000042 -:10CEF0000000000000000000000000000000000032 -:10CF00000000000000000000000000000000000021 -:10CF10000000000000000000000000000000000011 -:10CF20000000000000000000000000000000000001 -:10CF300000000000000000000000000000000000F1 -:10CF400000000000000000000000000000000000E1 -:10CF500000000000000000000000000000000000D1 -:10CF600000000000000000000000000000000000C1 -:10CF700000000000000000000000000000000000B1 -:10CF800000000000000000000000000000000000A1 -:10CF90000000000000000000000000000000000091 -:10CFA0000000000000000000000000000000000081 -:10CFB0000000000000000000000000000000000071 -:10CFC0000000000000000000000000000000000061 -:10CFD0000000000000000000000000000000000051 -:10CFE0000000000000000000000000000000000041 -:10CFF0000000000000000000000000000000000031 -:10D000000000000000000000000000000000000020 -:10D010000000000000000000000000000000000010 -:10D020000000000000000000000000000000000000 -:10D0300000000000000000000000000000000000F0 -:10D0400000000000000000000000000000000000E0 -:10D0500000000000000000000000000000000000D0 -:10D0600000000000000000000000000000000000C0 -:10D0700000000000000000000000000000000000B0 -:10D0800000000000000000000000000000000000A0 -:10D090000000000000000000000000000000000090 -:10D0A0000000000000000000000000000000000080 -:10D0B0000000000000000000000000000000000070 -:10D0C0000000000000000000000000000000000060 -:10D0D0000000000000000000000000000000000050 -:10D0E0000000000000000000000000000000000040 -:10D0F0000000000000000000000000000000000030 -:10D10000000000000000000000000000000000001F -:10D11000000000000000000000000000000000000F -:10D1200000000000000000000000000000000000FF -:10D1300000000000000000000000000000000000EF -:10D1400000000000000000000000000000000000DF -:10D1500000000000000000000000000000000000CF -:10D1600000000000000000000000000000000000BF -:10D1700000000000000000000000000000000000AF -:10D18000000000000000000000000000000000009F -:10D19000000000000000000000000000000000008F -:10D1A000000000000000000000000000000000007F -:10D1B000000000000000000000000000000000006F -:10D1C000000000000000000000000000000000005F -:10D1D000000000000000000000000000000000004F -:10D1E000000000000000000000000000000000003F -:10D1F000000000000000000000000000000000002F -:10D20000000000000000000000000000000000001E -:10D21000000000000000000000000000000000000E -:10D2200000000000000000000000000000000000FE -:10D2300000000000000000000000000000000000EE -:10D2400000000000000000000000000000000000DE -:10D2500000000000000000000000000000000000CE -:10D2600000000000000000000000000000000000BE -:10D2700000000000000000000000000000000000AE -:10D28000000000000000000000000000000000009E -:10D29000000000000000000000000000000000008E -:10D2A000000000000000000000000000000000007E -:10D2B000000000000000000000000000000000006E -:10D2C000000000000000000000000000000000005E -:10D2D000000000000000000000000000000000004E -:10D2E000000000000000000000000000000000003E -:10D2F000000000000000000000000000000000002E -:10D30000000000000000000000000000000000001D -:10D31000000000000000000000000000000000000D -:10D3200000000000000000000000000000000000FD -:10D3300000000000000000000000000000000000ED -:10D3400000000000000000000000000000000000DD -:10D3500000000000000000000000000000000000CD -:10D3600000000000000000000000000000000000BD -:10D3700000000000000000000000000000000000AD -:10D38000000000000000000000000000000000009D -:10D39000000000000000000000000000000000008D -:10D3A000000000000000000000000000000000007D -:10D3B000000000000000000000000000000000006D -:10D3C000000000000000000000000000000000005D -:10D3D000000000000000000000000000000000004D -:10D3E000000000000000000000000000000000003D -:10D3F000000000000000000000000000000000002D -:10D40000000000000000000000000000000000001C -:10D41000000000000000000000000000000000000C -:10D4200000000000000000000000000000000000FC -:10D4300000000000000000000000000000000000EC -:10D4400000000000000000000000000000000000DC -:10D4500000000000000000000000000000000000CC -:10D4600000000000000000000000000000000000BC -:10D4700000000000000000000000000000000000AC -:10D48000000000000000000000000000000000009C -:10D49000000000000000000000000000000000008C -:10D4A000000000000000000000000000000000007C -:10D4B000000000000000000000000000000000006C -:10D4C000000000000000000000000000000000005C -:10D4D000000000000000000000000000000000004C -:10D4E000000000000000000000000000000000003C -:10D4F000000000000000000000000000000000002C -:10D50000000000000000000000000000000000001B -:10D51000000000000000000000000000000000000B -:10D5200000000000000000000000000000000000FB -:10D5300000000000000000000000000000000000EB -:10D5400000000000000000000000000000000000DB -:10D5500000000000000000000000000000000000CB -:10D5600000000000000000000000000000000000BB -:10D5700000000000000000000000000000000000AB -:10D58000000000000000000000000000000000009B -:10D59000000000000000000000000000000000008B -:10D5A000000000000000000000000000000000007B -:10D5B000000000000000000000000000000000006B -:10D5C000000000000000000000000000000000005B -:10D5D000000000000000000000000000000000004B -:10D5E000000000000000000000000000000000003B -:10D5F000000000000000000000000000000000002B -:10D60000000000000000000000000000000000001A -:10D61000000000000000000000000000000000000A -:10D6200000000000000000000000000000000000FA -:10D6300000000000000000000000000000000000EA -:10D6400000000000000000000000000000000000DA -:10D6500000000000000000000000000000000000CA -:10D6600000000000000000000000000000000000BA -:10D6700000000000000000000000000000000000AA -:10D68000000000000000000000000000000000009A -:10D69000000000000000000000000000000000008A -:10D6A000000000000000000000000000000000007A -:10D6B000000000000000000000000000000000006A -:10D6C000000000000000000000000000000000005A -:10D6D000000000000000000000000000000000004A -:10D6E000000000000000000000000000000000003A -:10D6F000000000000000000000000000000000002A -:10D700000000000000000000000000000000000019 -:10D710000000000000000000000000000000000009 -:10D7200000000000000000000000000000000000F9 -:10D7300000000000000000000000000000000000E9 -:10D7400000000000000000000000000000000000D9 -:10D7500000000000000000000000000000000000C9 -:10D7600000000000000000000000000000000000B9 -:10D7700000000000000000000000000000000000A9 -:10D780000000000000000000000000000000000099 -:10D790000000000000000000000000000000000089 -:10D7A0000000000000000000000000000000000079 -:10D7B0000000000000000000000000000000000069 -:10D7C0000000000000000000000000000000000059 -:10D7D0000000000000000000000000000000000049 -:10D7E0000000000000000000000000000000000039 -:10D7F0000000000000000000000000000000000029 -:10D800000000000000000000000000000000000018 -:10D810000000000000000000000000000000000008 -:10D8200000000000000000000000000000000000F8 -:10D8300000000000000000000000000000000000E8 -:10D8400000000000000000000000000000000000D8 -:10D8500000000000000000000000000000000000C8 -:10D8600000000000000000000000000000000000B8 -:10D8700000000000000000000000000000000000A8 -:10D880000000000000000000000000000000000098 -:10D890000000000000000000000000000000000088 -:10D8A0000000000000000000000000000000000078 -:10D8B0000000000000000000000000000000000068 -:10D8C0000000000000000000000000000000000058 -:10D8D0000000000000000000000000000000000048 -:10D8E0000000000000000000000000000000000038 -:10D8F0000000000000000000000000000000000028 -:10D900000000000000000000000000000000000017 -:10D910000000000000000000000000000000000007 -:10D9200000000000000000000000000000000000F7 -:10D9300000000000000000000000000000000000E7 -:10D9400000000000000000000000000000000000D7 -:10D9500000000000000000000000000000000000C7 -:10D9600000000000000000000000000000000000B7 -:10D9700000000000000000000000000000000000A7 -:10D980000000000000000000000000000000000097 -:10D990000000000000000000000000000000000087 -:10D9A0000000000000000000000000000000000077 -:10D9B0000000000000000000000000000000000067 -:10D9C0000000000000000000000000000000000057 -:10D9D0000000000000000000000000000000000047 -:10D9E0000000000000000000000000000000000037 -:10D9F0000000000000000000000000000000000027 -:10DA00000000000000000000000000000000000016 -:10DA10000000000000000000000000000000000006 -:10DA200000000000000000000000000000000000F6 -:10DA300000000000000000000000000000000000E6 -:10DA400000000000000000000000000000000000D6 -:10DA500000000000000000000000000000000000C6 -:10DA600000000000000000000000000000000000B6 -:10DA700000000000000000000000000000000000A6 -:10DA80000000000000000000000000000000000096 -:10DA90000000000000000000000000000000000086 -:10DAA0000000000000000000000000000000000076 -:10DAB0000000000000000000000000000000000066 -:10DAC0000000000000000000000000000000000056 -:10DAD0000000000000000000000000000000000046 -:10DAE0000000000000000000000000000000000036 -:10DAF0000000000000000000000000000000000026 -:10DB00000000000000000000000000000000000015 -:10DB10000000000000000000000000000000000005 -:10DB200000000000000000000000000000000000F5 -:10DB300000000000000000000000000000000000E5 -:10DB400000000000000000000000000000000000D5 -:10DB500000000000000000000000000000000000C5 -:10DB600000000000000000000000000000000000B5 -:10DB700000000000000000000000000000000000A5 -:10DB80000000000000000000000000000000000095 -:10DB90000000000000000000000000000000000085 -:10DBA0000000000000000000000000000000000075 -:10DBB0000000000000000000000000000000000065 -:10DBC0000000000000000000000000000000000055 -:10DBD0000000000000000000000000000000000045 -:10DBE0000000000000000000000000000000000035 -:10DBF0000000000000000000000000000000000025 -:10DC00000000000000000000000000000000000014 -:10DC10000000000000000000000000000000000004 -:10DC200000000000000000000000000000000000F4 -:10DC300000000000000000000000000000000000E4 -:10DC400000000000000000000000000000000000D4 -:10DC500000000000000000000000000000000000C4 -:10DC600000000000000000000000000000000000B4 -:10DC700000000000000000000000000000000000A4 -:10DC80000000000000000000000000000000000094 -:10DC90000000000000000000000000000000000084 -:10DCA0000000000000000000000000000000000074 -:10DCB0000000000000000000000000000000000064 -:10DCC0000000000000000000000000000000000054 -:10DCD0000000000000000000000000000000000044 -:10DCE0000000000000000000000000000000000034 -:10DCF0000000000000000000000000000000000024 -:10DD00000000000000000000000000000000000013 -:10DD10000000000000000000000000000000000003 -:10DD200000000000000000000000000000000000F3 -:10DD300000000000000000000000000000000000E3 -:10DD400000000000000000000000000000000000D3 -:10DD500000000000000000000000000000000000C3 -:10DD600000000000000000000000000000000000B3 -:10DD700000000000000000000000000000000000A3 -:10DD80000000000000000000000000000000000093 -:10DD90000000000000000000000000000000000083 -:10DDA0000000000000000000000000000000000073 -:10DDB0000000000000000000000000000000000063 -:10DDC0000000000000000000000000000000000053 -:10DDD0000000000000000000000000000000000043 -:10DDE0000000000000000000000000000000000033 -:10DDF0000000000000000000000000000000000023 -:10DE00000000000000000000000000000000000012 -:10DE10000000000000000000000000000000000002 -:10DE200000000000000000000000000000000000F2 -:10DE300000000000000000000000000000000000E2 -:10DE400000000000000000000000000000000000D2 -:10DE500000000000000000000000000000000000C2 -:10DE600000000000000000000000000000000000B2 -:10DE700000000000000000000000000000000000A2 -:10DE80000000000000000000000000000000000092 -:10DE90000000000000000000000000000000000082 -:10DEA0000000000000000000000000000000000072 -:10DEB0000000000000000000000000000000000062 -:10DEC0000000000000000000000000000000000052 -:10DED0000000000000000000000000000000000042 -:10DEE0000000000000000000000000000000000032 -:10DEF0000000000000000000000000000000000022 -:10DF00000000000000000000000000000000000011 -:10DF10000000000000000000000000000000000001 -:10DF200000000000000000000000000000000000F1 -:10DF300000000000000000000000000000000000E1 -:10DF400000000000000000000000000000000000D1 -:10DF500000000000000000000000000000000000C1 -:10DF600000000000000000000000000000000000B1 -:10DF700000000000000000000000000000000000A1 -:10DF80000000000000000000000000000000000091 -:10DF90000000000000000000000000000000000081 -:10DFA0000000000000000000000000000000000071 -:10DFB0000000000000000000000000000000000061 -:10DFC0000000000000000000000000000000000051 -:10DFD0000000000000000000000000000000000041 -:10DFE0000000000000000000000000000000000031 -:10DFF0000000000000000000000000000000000021 -:10E000000000000000000000000000000000000010 -:10E010000000000000000000000000000000000000 -:10E0200000000000000000000000000000000000F0 -:10E0300000000000000000000000000000000000E0 -:10E0400000000000000000000000000000000000D0 -:10E0500000000000000000000000000000000000C0 -:10E0600000000000000000000000000000000000B0 -:10E0700000000000000000000000000000000000A0 -:10E080000000000000000000000000000000000090 -:10E090000000000000000000000000000000000080 -:10E0A0000000000000000000000000000000000070 -:10E0B0000000000000000000000000000000000060 -:10E0C0000000000000000000000000000000000050 -:10E0D0000000000000000000000000000000000040 -:10E0E0000000000000000000000000000000000030 -:10E0F0000000000000000000000000000000000020 -:10E10000000000000000000000000000000000000F -:10E1100000000000000000000000000000000000FF -:10E1200000000000000000000000000000000000EF -:10E1300000000000000000000000000000000000DF -:10E1400000000000000000000000000000000000CF -:10E1500000000000000000000000000000000000BF -:10E1600000000000000000000000000000000000AF -:10E17000000000000000000000000000000000009F -:10E18000000000000000000000000000000000008F -:10E19000000000000000000000000000000000007F -:10E1A000000000000000000000000000000000006F -:10E1B000000000000000000000000000000000005F -:10E1C000000000000000000000000000000000004F -:10E1D000000000000000000000000000000000003F -:10E1E000000000000000000000000000000000002F -:10E1F000000000000000000000000000000000001F -:10E20000000000000000000000000000000000000E -:10E2100000000000000000000000000000000000FE -:10E2200000000000000000000000000000000000EE -:10E2300000000000000000000000000000000000DE -:10E2400000000000000000000000000000000000CE -:10E2500000000000000000000000000000000000BE -:10E2600000000000000000000000000000000000AE -:10E27000000000000000000000000000000000009E -:10E28000000000000000000000000000000000008E -:10E29000000000000000000000000000000000007E -:10E2A000000000000000000000000000000000006E -:10E2B000000000000000000000000000000000005E -:10E2C000000000000000000000000000000000004E -:10E2D000000000000000000000000000000000003E -:10E2E000000000000000000000000000000000002E -:10E2F000000000000000000000000000000000001E -:10E30000000000000000000000000000000000000D -:10E3100000000000000000000000000000000000FD -:10E3200000000000000000000000000000000000ED -:10E3300000000000000000000000000000000000DD -:10E3400000000000000000000000000000000000CD -:10E3500000000000000000000000000000000000BD -:10E3600000000000000000000000000000000000AD -:10E37000000000000000000000000000000000009D -:10E38000000000000000000000000000000000008D -:10E39000000000000000000000000000000000007D -:10E3A000000000000000000000000000000000006D -:10E3B000000000000000000000000000000000005D -:10E3C000000000000000000000000000000000004D -:10E3D000000000000000000000000000000000003D -:10E3E000000000000000000000000000000000002D -:10E3F000000000000000000000000000000000001D -:10E40000000000000000000000000000000000000C -:10E4100000000000000000000000000000000000FC -:10E4200000000000000000000000000000000000EC -:10E4300000000000000000000000000000000000DC -:10E4400000000000000000000000000000000000CC -:10E4500000000000000000000000000000000000BC -:10E4600000000000000000000000000000000000AC -:10E47000000000000000000000000000000000009C -:10E48000000000000000000000000000000000008C -:10E49000000000000000000000000000000000007C -:10E4A000000000000000000000000000000000006C -:10E4B000000000000000000000000000000000005C -:10E4C000000000000000000000000000000000004C -:10E4D000000000000000000000000000000000003C -:10E4E000000000000000000000000000000000002C -:10E4F000000000000000000000000000000000001C -:10E50000000000000000000000000000000000000B -:10E5100000000000000000000000000000000000FB -:10E5200000000000000000000000000000000000EB -:10E5300000000000000000000000000000000000DB -:10E5400000000000000000000000000000000000CB -:10E5500000000000000000000000000000000000BB -:10E5600000000000000000000000000000000000AB -:10E57000000000000000000000000000000000009B -:10E58000000000000000000000000000000000008B -:10E59000000000000000000000000000000000007B -:10E5A000000000000000000000000000000000006B -:10E5B000000000000000000000000000000000005B -:10E5C000000000000000000000000000000000004B -:10E5D000000000000000000000000000000000003B -:10E5E000000000000000000000000000000000002B -:10E5F000000000000000000000000000000000001B -:10E60000000000000000000000000000000000000A -:10E6100000000000000000000000000000000000FA -:10E6200000000000000000000000000000000000EA -:10E6300000000000000000000000000000000000DA -:10E6400000000000000000000000000000000000CA -:10E6500000000000000000000000000000000000BA -:10E6600000000000000000000000000000000000AA -:10E67000000000000000000000000000000000009A -:10E68000000000000000000000000000000000008A -:10E69000000000000000000000000000000000007A -:10E6A000000000000000000000000000000000006A -:10E6B000000000000000000000000000000000005A -:10E6C000000000000000000000000000000000004A -:10E6D000000000000000000000000000000000003A -:10E6E000000000000000000000000000000000002A -:10E6F000000000000000000000000000000000001A -:10E700000000000000000000000000000000000009 -:10E7100000000000000000000000000000000000F9 -:10E7200000000000000000000000000000000000E9 -:10E7300000000000000000000000000000000000D9 -:10E7400000000000000000000000000000000000C9 -:10E7500000000000000000000000000000000000B9 -:10E7600000000000000000000000000000000000A9 -:10E770000000000000000000000000000000000099 -:10E780000000000000000000000000000000000089 -:10E790000000000000000000000000000000000079 -:10E7A0000000000000000000000000000000000069 -:10E7B0000000000000000000000000000000000059 -:10E7C0000000000000000000000000000000000049 -:10E7D0000000000000000000000000000000000039 -:10E7E0000000000000000000000000000000000029 -:10E7F0000000000000000000000000000000000019 -:10E800000000000000000000000000000000000008 -:10E8100000000000000000000000000000000000F8 -:10E8200000000000000000000000000000000000E8 -:10E8300000000000000000000000000000000000D8 -:10E8400000000000000000000000000000000000C8 -:10E8500000000000000000000000000000000000B8 -:10E8600000000000000000000000000000000000A8 -:10E870000000000000000000000000000000000098 -:10E880000000000000000000000000000000000088 -:10E890000000000000000000000000000000000078 -:10E8A0000000000000000000000000000000000068 -:10E8B0000000000000000000000000000000000058 -:10E8C0000000000000000000000000000000000048 -:10E8D0000000000000000000000000000000000038 -:10E8E0000000000000000000000000000000000028 -:10E8F0000000000000000000000000000000000018 -:10E900000000000000000000000000000000000007 -:10E9100000000000000000000000000000000000F7 -:10E9200000000000000000000000000000000000E7 -:10E9300000000000000000000000000000000000D7 -:10E9400000000000000000000000000000000000C7 -:10E9500000000000000000000000000000000000B7 -:10E9600000000000000000000000000000000000A7 -:10E970000000000000000000000000000000000097 -:10E980000000000000000000000000000000000087 -:10E990000000000000000000000000000000000077 -:10E9A0000000000000000000000000000000000067 -:10E9B0000000000000000000000000000000000057 -:10E9C0000000000000000000000000000000000047 -:10E9D0000000000000000000000000000000000037 -:10E9E0000000000000000000000000000000000027 -:10E9F0000000000000000000000000000000000017 -:10EA00000000000000000000000000000000000006 -:10EA100000000000000000000000000000000000F6 -:10EA200000000000000000000000000000000000E6 -:10EA300000000000000000000000000000000000D6 -:10EA400000000000000000000000000000000000C6 -:10EA500000000000000000000000000000000000B6 -:10EA600000000000000000000000000000000000A6 -:10EA70000000000000000000000000000000000096 -:10EA80000000000000000000000000000000000086 -:10EA90000000000000000000000000000000000076 -:10EAA0000000000000000000000000000000000066 -:10EAB0000000000000000000000000000000000056 -:10EAC0000000000000000000000000000000000046 -:10EAD0000000000000000000000000000000000036 -:10EAE0000000000000000000000000000000000026 -:10EAF0000000000000000000000000000000000016 -:10EB00000000000000000000000000000000000005 -:10EB100000000000000000000000000000000000F5 -:10EB200000000000000000000000000000000000E5 -:10EB300000000000000000000000000000000000D5 -:10EB400000000000000000000000000000000000C5 -:10EB500000000000000000000000000000000000B5 -:10EB600000000000000000000000000000000000A5 -:10EB70000000000000000000000000000000000095 -:10EB80000000000000000000000000000000000085 -:10EB90000000000000000000000000000000000075 -:10EBA0000000000000000000000000000000000065 -:10EBB0000000000000000000000000000000000055 -:10EBC0000000000000000000000000000000000045 -:10EBD0000000000000000000000000000000000035 -:10EBE0000000000000000000000000000000000025 -:10EBF0000000000000000000000000000000000015 -:10EC00000000000000000000000000000000000004 -:10EC100000000000000000000000000000000000F4 -:10EC200000000000000000000000000000000000E4 -:10EC300000000000000000000000000000000000D4 -:10EC400000000000000000000000000000000000C4 -:10EC500000000000000000000000000000000000B4 -:10EC600000000000000000000000000000000000A4 -:10EC70000000000000000000000000000000000094 -:10EC80000000000000000000000000000000000084 -:10EC90000000000000000000000000000000000074 -:10ECA0000000000000000000000000000000000064 -:10ECB0000000000000000000000000000000000054 -:10ECC0000000000000000000000000000000000044 -:10ECD0000000000000000000000000000000000034 -:10ECE0000000000000000000000000000000000024 -:10ECF0000000000000000000000000000000000014 -:10ED00000000000000000000000000000000000003 -:10ED100000000000000000000000000000000000F3 -:10ED200000000000000000000000000000000000E3 -:10ED300000000000000000000000000000000000D3 -:10ED400000000000000000000000000000000000C3 -:10ED500000000000000000000000000000000000B3 -:10ED600000000000000000000000000000000000A3 -:10ED70000000000000000000000000000000000093 -:10ED80000000000000000000000000000000000083 -:10ED90000000000000000000000000000000000073 -:10EDA0000000000000000000000000000000000063 -:10EDB0000000000000000000000000000000000053 -:10EDC0000000000000000000000000000000000043 -:10EDD0000000000000000000000000000000000033 -:10EDE0000000000000000000000000000000000023 -:10EDF0000000000000000000000000000000000013 -:10EE00000000000000000000000000000000000002 -:10EE100000000000000000000000000000000000F2 -:10EE200000000000000000000000000000000000E2 -:10EE300000000000000000000000000000000000D2 -:10EE400000000000000000000000000000000000C2 -:10EE500000000000000000000000000000000000B2 -:10EE600000000000000000000000000000000000A2 -:10EE70000000000000000000000000000000000092 -:10EE80000000000000000000000000000000000082 -:10EE90000000000000000000000000000000000072 -:10EEA0000000000000000000000000000000000062 -:10EEB0000000000000000000000000000000000052 -:10EEC0000000000000000000000000000000000042 -:10EED0000000000000000000000000000000000032 -:10EEE0000000000000000000000000000000000022 -:10EEF0000000000000000000000000000000000012 -:10EF00000000000000000000000000000000000001 -:10EF100000000000000000000000000000000000F1 -:10EF200000000000000000000000000000000000E1 -:10EF300000000000000000000000000000000000D1 -:10EF400000000000000000000000000000000000C1 -:10EF500000000000000000000000000000000000B1 -:10EF600000000000000000000000000000000000A1 -:10EF70000000000000000000000000000000000091 -:10EF80000000000000000000000000000000000081 -:10EF90000000000000000000000000000000000071 -:10EFA0000000000000000000000000000000000061 -:10EFB0000000000000000000000000000000000051 -:10EFC0000000000000000000000000000000000041 -:10EFD0000000000000000000000000000000000031 -:10EFE0000000000000000000000000000000000021 -:10EFF0000000000000000000000000000000000011 -:10F000000000000000000000000000000000000000 -:10F0100000000000000000000000000000000000F0 -:10F0200000000000000000000000000000000000E0 -:10F0300000000000000000000000000000000000D0 -:10F0400000000000000000000000000000000000C0 -:10F0500000000000000000000000000000000000B0 -:10F0600000000000000000000000000000000000A0 -:10F070000000000000000000000000000000000090 -:10F080000000000000000000000000000000000080 -:10F090000000000000000000000000000000000070 -:10F0A0000000000000000000000000000000000060 -:10F0B0000000000000000000000000000000000050 -:10F0C0000000000000000000000000000000000040 -:10F0D0000000000000000000000000000000000030 -:10F0E0000000000000000000000000000000000020 -:10F0F0000000000000000000000000000000000010 -:10F1000000000000000000000000000000000000FF -:10F1100000000000000000000000000000000000EF -:10F1200000000000000000000000000000000000DF -:10F1300000000000000000000000000000000000CF -:10F1400000000000000000000000000000000000BF -:10F1500000000000000000000000000000000000AF -:10F16000000000000000000000000000000000009F -:10F17000000000000000000000000000000000008F -:10F18000000000000000000000000000000000007F -:10F19000000000000000000000000000000000006F -:10F1A000000000000000000000000000000000005F -:10F1B000000000000000000000000000000000004F -:10F1C000000000000000000000000000000000003F -:10F1D000000000000000000000000000000000002F -:10F1E000000000000000000000000000000000001F -:10F1F000000000000000000000000000000000000F -:10F2000000000000000000000000000000000000FE -:10F2100000000000000000000000000000000000EE -:10F2200000000000000000000000000000000000DE -:10F2300000000000000000000000000000000000CE -:10F2400000000000000000000000000000000000BE -:10F2500000000000000000000000000000000000AE -:10F26000000000000000000000000000000000009E -:10F27000000000000000000000000000000000008E -:10F28000000000000000000000000000000000007E -:10F29000000000000000000000000000000000006E -:10F2A000000000000000000000000000000000005E -:10F2B000000000000000000000000000000000004E -:10F2C000000000000000000000000000000000003E -:10F2D000000000000000000000000000000000002E -:10F2E000000000000000000000000000000000001E -:10F2F000000000000000000000000000000000000E -:10F3000000000000000000000000000000000000FD -:10F3100000000000000000000000000000000000ED -:10F3200000000000000000000000000000000000DD -:10F3300000000000000000000000000000000000CD -:10F3400000000000000000000000000000000000BD -:10F3500000000000000000000000000000000000AD -:10F36000000000000000000000000000000000009D -:10F37000000000000000000000000000000000008D -:10F38000000000000000000000000000000000007D -:10F39000000000000000000000000000000000006D -:10F3A000000000000000000000000000000000005D -:10F3B000000000000000000000000000000000004D -:10F3C000000000000000000000000000000000003D -:10F3D000000000000000000000000000000000002D -:10F3E000000000000000000000000000000000001D -:10F3F000000000000000000000000000000000000D -:10F4000000000000000000000000000000000000FC -:10F4100000000000000000000000000000000000EC -:10F4200000000000000000000000000000000000DC -:10F4300000000000000000000000000000000000CC -:10F4400000000000000000000000000000000000BC -:10F4500000000000000000000000000000000000AC -:10F46000000000000000000000000000000000009C -:10F47000000000000000000000000000000000008C -:10F48000000000000000000000000000000000007C -:10F49000000000000000000000000000000000006C -:10F4A000000000000000000000000000000000005C -:10F4B000000000000000000000000000000000004C -:10F4C000000000000000000000000000000000003C -:10F4D000000000000000000000000000000000002C -:10F4E000000000000000000000000000000000001C -:10F4F000000000000000000000000000000000000C -:10F5000000000000000000000000000000000000FB -:10F5100000000000000000000000000000000000EB -:10F5200000000000000000000000000000000000DB -:10F5300000000000000000000000000000000000CB -:10F5400000000000000000000000000000000000BB -:10F5500000000000000000000000000000000000AB -:10F56000000000000000000000000000000000009B -:10F57000000000000000000000000000000000008B -:10F58000000000000000000000000000000000007B -:10F59000000000000000000000000000000000006B -:10F5A000000000000000000000000000000000005B -:10F5B000000000000000000000000000000000004B -:10F5C000000000000000000000000000000000003B -:10F5D000000000000000000000000000000000002B -:10F5E000000000000000000000000000000000001B -:10F5F000000000000000000000000000000000000B -:10F6000000000000000000000000000000000000FA -:10F6100000000000000000000000000000000000EA -:10F6200000000000000000000000000000000000DA -:10F6300000000000000000000000000000000000CA -:10F6400000000000000000000000000000000000BA -:10F6500000000000000000000000000000000000AA -:10F66000000000000000000000000000000000009A -:10F67000000000000000000000000000000000008A -:10F68000000000000000000000000000000000007A -:10F69000000000000000000000000000000000006A -:10F6A000000000000000000000000000000000005A -:10F6B000000000000000000000000000000000004A -:10F6C000000000000000000000000000000000003A -:10F6D000000000000000000000000000000000002A -:10F6E000000000000000000000000000000000001A -:10F6F000000000000000000000000000000000000A -:10F7000000000000000000000000000000000000F9 -:10F7100000000000000000000000000000000000E9 -:10F7200000000000000000000000000000000000D9 -:10F7300000000000000000000000000000000000C9 -:10F7400000000000000000000000000000000000B9 -:10F7500000000000000000000000000000000000A9 -:10F760000000000000000000000000000000000099 -:10F770000000000000000000000000000000000089 -:10F780000000000000000000000000000000000079 -:10F790000000000000000000000000000000000069 -:10F7A0000000000000000000000000000000000059 -:10F7B0000000000000000000000000000000000049 -:10F7C0000000000000000000000000000000000039 -:10F7D0000000000000000000000000000000000029 -:10F7E0000000000000000000000000000000000019 -:10F7F0000000000000000000000000000000000009 -:10F8000000000000000000000000000000000000F8 -:10F8100000000000000000000000000000000000E8 -:10F8200000000000000000000000000000000000D8 -:10F8300000000000000000000000000000000000C8 -:10F8400000000000000000000000000000000000B8 -:10F8500000000000000000000000000000000000A8 -:10F860000000000000000000000000000000000098 -:10F870000000000000000000000000000000000088 -:10F880000000000000000000000000000000000078 -:10F890000000000000000000000000000000000068 -:10F8A0000000000000000000000000000000000058 -:10F8B0000000000000000000000000000000000048 -:10F8C0000000000000000000000000000000000038 -:10F8D0000000000000000000000000000000000028 -:10F8E0000000000000000000000000000000000018 -:10F8F0000000000000000000000000000000000008 -:10F9000000000000000000000000000000000000F7 -:10F9100000000000000000000000000000000000E7 -:10F9200000000000000000000000000000000000D7 -:10F9300000000000000000000000000000000000C7 -:10F9400000000000000000000000000000000000B7 -:10F9500000000000000000000000000000000000A7 -:10F960000000000000000000000000000000000097 -:10F970000000000000000000000000000000000087 -:10F980000000000000000000000000000000000077 -:10F990000000000000000000000000000000000067 -:10F9A0000000000000000000000000000000000057 -:10F9B0000000000000000000000000000000000047 -:10F9C0000000000000000000000000000000000037 -:10F9D0000000000000000000000000000000000027 -:10F9E0000000000000000000000000000000000017 -:10F9F0000000000000000000000000000000000007 -:10FA000000000000000000000000000000000000F6 -:10FA100000000000000000000000000000000000E6 -:10FA200000000000000000000000000000000000D6 -:10FA300000000000000000000000000000000000C6 -:10FA400000000000000000000000000000000000B6 -:10FA500000000000000000000000000000000000A6 -:10FA60000000000000000000000000000000000096 -:10FA70000000000000000000000000000000000086 -:10FA80000000000000000000000000000000000076 -:10FA90000000000000000000000000000000000066 -:10FAA0000000000000000000000000000000000056 -:10FAB0000000000000000000000000000000000046 -:10FAC0000000000000000000000000000000000036 -:10FAD0000000000000000000000000000000000026 -:10FAE0000000000000000000000000000000000016 -:10FAF0000000000000000000000000000000000006 -:10FB000000000000000000000000000000000000F5 -:10FB100000000000000000000000000000000000E5 -:10FB200000000000000000000000000000000000D5 -:10FB300000000000000000000000000000000000C5 -:10FB400000000000000000000000000000000000B5 -:10FB500000000000000000000000000000000000A5 -:10FB60000000000000000000000000000000000095 -:10FB70000000000000000000000000000000000085 -:10FB80000000000000000000000000000000000075 -:10FB90000000000000000000000000000000000065 -:10FBA0000000000000000000000000000000000055 -:10FBB0000000000000000000000000000000000045 -:10FBC0000000000000000000000000000000000035 -:10FBD0000000000000000000000000000000000025 -:10FBE0000000000000000000000000000000000015 -:10FBF0000000000000000000000000000000000005 -:10FC000000000000000000000000000000000000F4 -:10FC100000000000000000000000000000000000E4 -:10FC200000000000000000000000000000000000D4 -:10FC300000000000000000000000000000000000C4 -:10FC400000000000000000000000000000000000B4 -:10FC500000000000000000000000000000000000A4 -:10FC60000000000000000000000000000000000094 -:10FC70000000000000000000000000000000000084 -:10FC80000000000000000000000000000000000074 -:10FC90000000000000000000000000000000000064 -:10FCA0000000000000000000000000000000000054 -:10FCB0000000000000000000000000000000000044 -:10FCC0000000000000000000000000000000000034 -:10FCD0000000000000000000000000000000000024 -:10FCE0000000000000000000000000000000000014 -:10FCF0000000000000000000000000000000000004 -:10FD000000000000000000000000000000000000F3 -:10FD100000000000000000000000000000000000E3 -:10FD200000000000000000000000000000000000D3 -:10FD300000000000000000000000000000000000C3 -:10FD400000000000000000000000000000000000B3 -:10FD500000000000000000000000000000000000A3 -:10FD60000000000000000000000000000000000093 -:10FD70000000000000000000000000000000000083 -:10FD80000000000000000000000000000000000073 -:10FD90000000000000000000000000000000000063 -:10FDA0000000000000000000000000000000000053 -:10FDB0000000000000000000000000000000000043 -:10FDC0000000000000000000000000000000000033 -:10FDD0000000000000000000000000000000000023 -:10FDE0000000000000000000000000000000000013 -:10FDF0000000000000000000000000000000000003 -:10FE000000000000000000000000000000000000F2 -:10FE100000000000000000000000000000000000E2 -:10FE200000000000000000000000000000000000D2 -:10FE300000000000000000000000000000000000C2 -:10FE400000000000000000000000000000000000B2 -:10FE500000000000000000000000000000000000A2 -:10FE60000000000000000000000000000000000092 -:10FE70000000000000000000000000000000000082 -:10FE80000000000000000000000000000000000072 -:10FE90000000000000000000000000000000000062 -:10FEA0000000000000000000000000000000000052 -:10FEB0000000000000000000000000000000000042 -:10FEC0000000000000000000000000000000000032 -:10FED0000000000000000000000000000000000022 -:10FEE0000000000000000000000000000000000012 -:10FEF0000000000000000000000000000000000002 -:10FF000000000000000000000000000000000000F1 -:10FF100000000000000000000000000000000000E1 -:10FF200000000000000000000000000000000000D1 -:10FF300000000000000000000000000000000000C1 -:10FF400000000000000000000000000000000000B1 -:10FF500000000000000000000000000000000000A1 -:10FF60000000000000000000000000000000000091 -:10FF70000000000000000000000000000000000081 -:10FF80000000000000000000000000000000000071 -:10FF90000000000000000000000000000000000061 -:10FFA0000000000000000000000000000000000051 -:10FFB0000000000000000000000000000000000041 -:10FFC0000000000000000000000000000000000031 -:10FFD0000000000000000000000000000000000021 -:10FFE0000000000000000000000000000000000011 -:10FFF0000000000000000000000000000000000001 -:02000004620494 -:1000000000000000000000000000000000000000F0 -:1000100000000000000000000000000000000000E0 -:1000200000000000000000000000000000000000D0 -:1000300000000000000000000000000000000000C0 -:1000400000000000000000000000000000000000B0 -:1000500000000000000000000000000000000000A0 -:100060000000000000000000000000000000000090 -:100070000000000000000000000000000000000080 -:100080000000000000000000000000000000000070 -:100090000000000000000000000000000000000060 -:1000A0000000000000000000000000000000000050 -:1000B0000000000000000000000000000000000040 -:1000C0000000000000000000000000000000000030 -:1000D0000000000000000000000000000000000020 -:1000E0000000000000000000000000000000000010 -:1000F0000000000000000000000000000000000000 -:1001000000000000000000000000000000000000EF -:1001100000000000000000000000000000000000DF -:1001200000000000000000000000000000000000CF -:1001300000000000000000000000000000000000BF -:1001400000000000000000000000000000000000AF -:10015000000000000000000000000000000000009F -:10016000000000000000000000000000000000008F -:10017000000000000000000000000000000000007F -:10018000000000000000000000000000000000006F -:10019000000000000000000000000000030000005C -:1001A000000000000000000000000000000000004F -:1001B000000000000000000000000000000000003F -:1001C000000000000000000000000000000000002F -:1001D000000000000000000000000000000000001F -:1001E000000000000000000000000000000000000F -:1001F00000000000000000000000000000000000FF -:1002000000000000000000000000000000000000EE -:1002100000000000000000000000000000000000DE -:1002200000000000000000000000000000000000CE -:1002300000000000000000000000000000000000BE -:1002400000000000000000000000000000000000AE -:10025000000000000000000000000000000000009E -:10026000000000000000000000000000000000008E -:10027000000000000000000000000000000000007E -:10028000000000000000000000000000000000006E -:10029000000000000000000000000000000000005E -:1002A000000000000000000000000000000000004E -:1002B000000000000000000000000000000000003E -:1002C000000000000000000000000000000000002E -:1002D000000000000000000000000000000000001E -:1002E000000000000000000000000000000000000E -:1002F00000000000000000000000000000000000FE -:1003000000000000000000000000000000000000ED -:1003100000000000000000000000000000000000DD -:1003200000000000000000000000000000000000CD -:1003300000000000000000000000000000000000BD -:1003400000000000000000000000000000000000AD -:10035000000000000000000000000000000000009D -:10036000000000000000000000000000000000008D -:10037000000000000000000000000000000000007D -:10038000000000000000000000000000000000006D -:10039000000000000000000000000000000000005D -:1003A000000000000000000000000000000000004D -:1003B000000000000000000000000000000000003D -:1003C000000000000000000000000000000000002D -:1003D000000000000000000000000000000000001D -:1003E000000000000000000000000000000000000D -:1003F00000000000000000000000000000000000FD -:1004000000000000000000000000000000000000EC -:1004100000000000000000000000000000000000DC -:1004200000000000000000000000000000000000CC -:1004300000000000000000000000000000000000BC -:1004400000000000000000000000000000000000AC -:10045000000000000000000000000000000000009C -:10046000000000000000000000000000000000008C -:10047000000000000000000000000000000000007C -:10048000000000000000000000000000000000006C -:10049000000000000000000000000000000000005C -:1004A000000000000000000000000000000000004C -:1004B000000000000000000000000000000000003C -:1004C000000000000000000000000000000000002C -:1004D000000000000000000000000000000000001C -:1004E000000000000000000000000000000000000C -:1004F00000000000000000000000000000000000FC -:1005000000000000000000000000000000000000EB -:1005100000000000000000000000000000000000DB -:1005200000000000000000000000000000000000CB -:1005300000000000000000000000000000000000BB -:1005400000000000000000000000000000000000AB -:10055000000000000000000000000000000000009B -:10056000000000000000000000000000000000008B -:10057000000000000000000000000000000000007B -:10058000000000000000000000000000000000006B -:10059000000000000000000000000000000000005B -:1005A000000000000000000000000000000000004B -:1005B000000000000000000000000000000000003B -:1005C000000000000000000000000000000000002B -:1005D000000000000000000000000000000000001B -:1005E000000000000000000000000000000000000B -:1005F00000000000000000000000000000000000FB -:1006000000000000000000000000000000000000EA -:1006100000000000000000000000000000000000DA -:1006200000000000000000000000000000000000CA -:1006300000000000000000000000000000000000BA -:1006400000000000000000000000000000000000AA -:10065000000000000000000000000000000000009A -:10066000000000000000000000000000000000008A -:10067000000000000000000000000000000000007A -:10068000000000000000000000000000000000006A -:10069000000000000000000000000000000000005A -:1006A000000000000000000000000000000000004A -:1006B000000000000000000000000000000000003A -:1006C000000000000000000000000000000000002A -:1006D000000000000000000000000000000000001A -:1006E000000000000000000000000000000000000A -:1006F00000000000000000000000000000000000FA -:1007000000000000000000000000000000000000E9 -:1007100000000000000000000000000000000000D9 -:1007200000000000000000000000000000000000C9 -:1007300000000000000000000000000000000000B9 -:1007400000000000000000000000000000000000A9 -:100750000000000000000000000000000000000099 -:100760000000000000000000000000000000000089 -:100770000000000000000000000000000000000079 -:100780000000000000000000000000000000000069 -:100790000000000000000000000000000000000059 -:1007A0000000000000000000000000000000000049 -:1007B0000000000000000000000000000000000039 -:1007C0000000000000000000000000000000000029 -:1007D0000000000000000000000000000000000019 -:1007E0000000000000000000000000000000000009 -:1007F00000000000000000000000000000000000F9 -:1008000000000000000000000000000000000000E8 -:1008100000000000000000000000000000000000D8 -:1008200000000000000000000000000000000000C8 -:1008300000000000000000000000000000000000B8 -:1008400000000000000000000000000000000000A8 -:100850000000000000000000000000000000000098 -:100860000000000000000000000000000000000088 -:100870000000000000000000000000000000000078 -:100880000000000000000000000000000000000068 -:100890000000000000000000000000000000000058 -:1008A0000000000000000000000000000000000048 -:1008B0000000000000000000000000000000000038 -:1008C0000000000000000000000000000000000028 -:1008D0000000000000000000000000000000000018 -:1008E0000000000000000000000000000000000008 -:1008F00000000000000000000000000000000000F8 -:1009000000000000000000000000000000000000E7 -:1009100000000000000000000000000000000000D7 -:1009200000000000000000000000000000000000C7 -:1009300000000000000000000000000000000000B7 -:1009400000000000000000000000000000000000A7 -:100950000000000000000000000000000000000097 -:100960000000000000000000000000000000000087 -:100970000000000000000000000000000000000077 -:100980000000000000000000000000000000000067 -:100990000000000000000000000000000000000057 -:1009A0000000000000000000000000000000000047 -:1009B0000000000000000000000000000000000037 -:1009C0000000000000000000000000000000000027 -:1009D0000000000000000000000000000000000017 -:1009E0000000000000000000000000000000000007 -:1009F00000000000000000000000000000000000F7 -:100A000000000000000000000000000000000000E6 -:100A100000000000000000000000000000000000D6 -:100A200000000000000000000000000000000000C6 -:100A300000000000000000000000000000000000B6 -:100A400000000000000000000000000000000000A6 -:100A50000000000000000000000000000000000096 -:100A60000000000000000000000000000000000086 -:100A70000000000000000000000000000000000076 -:100A80000000000000000000000000000000000066 -:100A90000000000000000000000000000000000056 -:100AA0000000000000000000000000000000000046 -:100AB0000000000000000000000000000000000036 -:100AC0000000000000000000000000000000000026 -:100AD0000000000000000000000000000000000016 -:100AE0000000000000000000000000000000000006 -:100AF00000000000000000000000000000000000F6 -:100B000000000000000000000000000000000000E5 -:100B100000000000000000000000000000000000D5 -:100B200000000000000000000000000000000000C5 -:100B300000000000000000000000000000000000B5 -:100B400000000000000000000000000000000000A5 -:100B50000000000000000000000000000000000095 -:100B60000000000000000000000000000000000085 -:100B70000000000000000000000000000000000075 -:100B80000000000000000000000000000000000065 -:100B90000000000000000000000000000000000055 -:100BA0000000000000000000000000000000000045 -:100BB0000000000000000000000000000000000035 -:100BC0000000000000000000000000000000000025 -:100BD0000000000000000000000000000000000015 -:100BE0000000000000000000000000000000000005 -:100BF00000000000000000000000000000000000F5 -:100C000000000000000000000000000000000000E4 -:100C100000000000000000000000000000000000D4 -:100C200000000000000000000000000000000000C4 -:100C300000000000000000000000000000000000B4 -:100C400000000000000000000000000000000000A4 -:100C50000000000000000000000000000000000094 -:100C60000000000000000000000000000000000084 -:100C70000000000000000000000000000000000074 -:100C80000000000000000000000000000000000064 -:100C90000000000000000000000000000000000054 -:100CA0000000000000000000000000000000000044 -:100CB0000000000000000000000000000000000034 -:100CC0000000000000000000000000000000000024 -:100CD0000000000000000000000000000000000014 -:100CE0000000000000000000000000000000000004 -:100CF00000000000000000000000000000000000F4 -:100D000000000000000000000000000000000000E3 -:100D100000000000000000000000000000000000D3 -:100D200000000000000000000000000000000000C3 -:100D300000000000000000000000000000000000B3 -:100D400000000000000000000000000000000000A3 -:100D50000000000000000000000000000000000093 -:100D60000000000000000000000000000000000083 -:100D70000000000000000000000000000000000073 -:100D80000000000000000000000000000000000063 -:100D90000000000000000000000000000000000053 -:100DA0000000000000000000000000000000000043 -:100DB0000000000000000000000000000000000033 -:100DC0000000000000000000000000000000000023 -:100DD0000000000000000000000000000000000013 -:100DE0000000000000000000000000000000000003 -:100DF00000000000000000000000000000000000F3 -:100E000000000000000000000000000000000000E2 -:100E100000000000000000000000000000000000D2 -:100E200000000000000000000000000000000000C2 -:100E300000000000000000000000000000000000B2 -:100E400000000000000000000000000000000000A2 -:100E50000000000000000000000000000000000092 -:100E60000000000000000000000000000000000082 -:100E70000000000000000000000000000000000072 -:100E80000000000000000000000000000000000062 -:100E90000000000000000000000000000000000052 -:100EA0000000000000000000000000000000000042 -:100EB0000000000000000000000000000000000032 -:100EC0000000000000000000000000000000000022 -:100ED0000000000000000000000000000000000012 -:100EE0000000000000000000000000000000000002 -:100EF00000000000000000000000000000000000F2 -:100F000000000000000000000000000000000000E1 -:100F100000000000000000000000000000000000D1 -:100F200000000000000000000000000000000000C1 -:100F300000000000000000000000000000000000B1 -:100F400000000000000000000000000000000000A1 -:100F50000000000000000000000000000000000091 -:100F60000000000000000000000000000000000081 -:100F70000000000000000000000000000000000071 -:100F80000000000000000000000000000000000061 -:100F90000000000000000000000000000000000051 -:100FA0000000000000000000000000000000000041 -:100FB0000000000000000000000000000000000031 -:100FC0000000000000000000000000000000000021 -:100FD0000000000000000000000000000000000011 -:100FE0000000000000000000000000000000000001 -:100FF00000000000000000000000000000000000F1 -:1010000000000000000000000000000000000000E0 -:1010100000000000000000000000000000000000D0 -:1010200000000000000000000000000000000000C0 -:1010300000000000000000000000000000000000B0 -:1010400000000000000000000000000000000000A0 -:101050000000000000000000000000000000000090 -:101060000000000000000000000000000000000080 -:101070000000000000000000000000000000000070 -:101080000000000000000000000000000000000060 -:101090000000000000000000000000000000000050 -:1010A0000000000000000000000000000000000040 -:1010B0000000000000000000000000000000000030 -:1010C0000000000000000000000000000000000020 -:1010D0000000000000000000000000000000000010 -:1010E0000000000000000000000000000000000000 -:1010F00000000000000000000000000000000000F0 -:1011000000000000000000000000000000000000DF -:1011100000000000000000000000000000000000CF -:1011200000000000000000000000000000000000BF -:1011300000000000000000000000000000000000AF -:10114000000000000000000000000000000000009F -:10115000000000000000000000000000000000008F -:10116000000000000000000000000000000000007F -:10117000000000000000000000000000000000006F -:10118000000000000000000000000000000000005F -:10119000000000000000000000000000000000004F -:1011A000000000000000000000000000000000003F -:1011B000000000000000000000000000000000002F -:1011C000000000000000000000000000000000001F -:1011D000000000000000000000000000000000000F -:1011E00000000000000000000000000000000000FF -:1011F00000000000000000000000000000000000EF -:1012000000000000000000000000000000000000DE -:1012100000000000000000000000000000000000CE -:1012200000000000000000000000000000000000BE -:1012300000000000000000000000000000000000AE -:10124000000000000000000000000000000000009E -:10125000000000000000000000000000000000008E -:10126000000000000000000000000000000000007E -:10127000000000000000000000000000000000006E -:10128000000000000000000000000000000000005E -:10129000000000000000000000000000000000004E -:1012A000000000000000000000000000000000003E -:1012B000000000000000000000000000000000002E -:1012C000000000000000000000000000000000001E -:1012D000000000000000000000000000000000000E -:1012E00000000000000000000000000000000000FE -:1012F00000000000000000000000000000000000EE -:1013000000000000000000000000000000000000DD -:1013100000000000000000000000000000000000CD -:1013200000000000000000000000000000000000BD -:1013300000000000000000000000000000000000AD -:10134000000000000000000000000000000000009D -:10135000000000000000000000000000000000008D -:10136000000000000000000000000000000000007D -:10137000000000000000000000000000000000006D -:10138000000000000000000000000000000000005D -:10139000000000000000000000000000000000004D -:1013A000000000000000000000000000000000003D -:1013B000000000000000000000000000000000002D -:1013C000000000000000000000000000000000001D -:1013D000000000000000000000000000000000000D -:1013E00000000000000000000000000000000000FD -:1013F00000000000000000000000000000000000ED -:1014000000000000000000000000000000000000DC -:1014100000000000000000000000000000000000CC -:1014200000000000000000000000000000000000BC -:1014300000000000000000000000000000000000AC -:10144000000000000000000000000000000000009C -:10145000000000000000000000000000000000008C -:10146000000000000000000000000000000000007C -:10147000000000000000000000000000000000006C -:10148000000000000000000000000000000000005C -:10149000000000000000000000000000000000004C -:1014A000000000000000000000000000000000003C -:1014B000000000000000000000000000000000002C -:1014C000000000000000000000000000000000001C -:1014D000000000000000000000000000000000000C -:1014E00000000000000000000000000000000000FC -:1014F00000000000000000000000000000000000EC -:1015000000000000000000000000000000000000DB -:1015100000000000000000000000000000000000CB -:1015200000000000000000000000000000000000BB -:1015300000000000000000000000000000000000AB -:10154000000000000000000000000000000000009B -:10155000000000000000000000000000000000008B -:10156000000000000000000000000000000000007B -:10157000000000000000000000000000000000006B -:10158000000000000000000000000000000000005B -:10159000000000000000000000000000000000004B -:1015A000000000000000000000000000000000003B -:1015B000000000000000000000000000000000002B -:1015C000000000000000000000000000000000001B -:1015D000000000000000000000000000000000000B -:1015E00000000000000000000000000000000000FB -:1015F00000000000000000000000000000000000EB -:1016000000000000000000000000000000000000DA -:1016100000000000000000000000000000000000CA -:1016200000000000000000000000000000000000BA -:1016300000000000000000000000000000000000AA -:10164000000000000000000000000000000000009A -:10165000000000000000000000000000000000008A -:10166000000000000000000000000000000000007A -:10167000000000000000000000000000000000006A -:10168000000000000000000000000000000000005A -:10169000000000000000000000000000000000004A -:1016A000000000000000000000000000000000003A -:1016B000000000000000000000000000000000002A -:1016C000000000000000000000000000000000001A -:1016D000000000000000000000000000000000000A -:1016E00000000000000000000000000000000000FA -:1016F00000000000000000000000000000000000EA -:1017000000000000000000000000000000000000D9 -:1017100000000000000000000000000000000000C9 -:1017200000000000000000000000000000000000B9 -:1017300000000000000000000000000000000000A9 -:101740000000000000000000000000000000000099 -:101750000000000000000000000000000000000089 -:101760000000000000000000000000000000000079 -:101770000000000000000000000000000000000069 -:101780000000000000000000000000000000000059 -:101790000000000000000000000000000000000049 -:1017A0000000000000000000000000000000000039 -:1017B0000000000000000000000000000000000029 -:1017C0000000000000000000000000000000000019 -:1017D0000000000000000000000000000000000009 -:1017E00000000000000000000000000000000000F9 -:1017F00000000000000000000000000000000000E9 -:1018000000000000000000000000000000000000D8 -:1018100000000000000000000000000000000000C8 -:1018200000000000000000000000000000000000B8 -:1018300000000000000000000000000000000000A8 -:101840000000000000000000000000000000000098 -:101850000000000000000000000000000000000088 -:101860000000000000000000000000000000000078 -:101870000000000000000000000000000000000068 -:101880000000000000000000000000000000000058 -:101890000000000000000000000000000000000048 -:1018A0000000000000000000000000000000000038 -:1018B0000000000000000000000000000000000028 -:1018C0000000000000000000000000000000000018 -:1018D0000000000000000000000000000000000008 -:1018E00000000000000000000000000000000000F8 -:1018F00000000000000000000000000000000000E8 -:1019000000000000000000000000000000000000D7 -:1019100000000000000000000000000000000000C7 -:1019200000000000000000000000000000000000B7 -:1019300000000000000000000000000000000000A7 -:101940000000000000000000000000000000000097 -:101950000000000000000000000000000000000087 -:101960000000000000000000000000000000000077 -:101970000000000000000000000000000000000067 -:101980000000000000000000000000000000000057 -:101990000000000000000000000000000000000047 -:1019A0000000000000000000000000000000000037 -:1019B0000000000000000000000000000000000027 -:1019C0000000000000000000000000000000000017 -:1019D0000000000000000000000000000000000007 -:1019E00000000000000000000000000000000000F7 -:1019F00000000000000000000000000000000000E7 -:101A000000000000000000000000000000000000D6 -:101A100000000000000000000000000000000000C6 -:101A200000000000000000000000000000000000B6 -:101A300000000000000000000000000000000000A6 -:101A40000000000000000000000000000000000096 -:101A50000000000000000000000000000000000086 -:101A60000000000000000000000000000000000076 -:101A70000000000000000000000000000000000066 -:101A80000000000000000000000000000000000056 -:101A90000000000000000000000000000000000046 -:101AA0000000000000000000000000000000000036 -:101AB0000000000000000000000000000000000026 -:101AC0000000000000000000000000000000000016 -:101AD0000000000000000000000000000000000006 -:101AE00000000000000000000000000000000000F6 -:101AF00000000000000000000000000000000000E6 -:101B000000000000000000000000000000000000D5 -:101B100000000000000000000000000000000000C5 -:101B200000000000000000000000000000000000B5 -:101B300000000000000000000000000000000000A5 -:101B40000000000000000000000000000000000095 -:101B50000000000000000000000000000000000085 -:101B60000000000000000000000000000000000075 -:101B70000000000000000000000000000000000065 -:101B80000000000000000000000000000000000055 -:101B90000000000000000000000000000000000045 -:101BA0000000000000000000000000000000000035 -:101BB0000000000000000000000000000000000025 -:101BC0000000000000000000000000000000000015 -:101BD0000000000000000000000000000000000005 -:101BE00000000000000000000000000000000000F5 -:101BF00000000000000000000000000000000000E5 -:101C000000000000000000000000000000000000D4 -:101C100000000000000000000000000000000000C4 -:101C200000000000000000000000000000000000B4 -:101C300000000000000000000000000000000000A4 -:101C40000000000000000000000000000000000094 -:101C50000000000000000000000000000000000084 -:101C60000000000000000000000000000000000074 -:101C70000000000000000000000000000000000064 -:101C80000000000000000000000000000000000054 -:101C90000000000000000000000000000000000044 -:101CA0000000000000000000000000000000000034 -:101CB0000000000000000000000000000000000024 -:101CC0000000000000000000000000000000000014 -:101CD0000000000000000000000000000000000004 -:101CE00000000000000000000000000000000000F4 -:101CF00000000000000000000000000000000000E4 -:101D000000000000000000000000000000000000D3 -:101D100000000000000000000000000000000000C3 -:101D200000000000000000000000000000000000B3 -:101D300000000000000000000000000000000000A3 -:101D40000000000000000000000000000000000093 -:101D50000000000000000000000000000000000083 -:101D60000000000000000000000000000000000073 -:101D70000000000000000000000000000000000063 -:101D80000000000000000000000000000000000053 -:101D90000000000000000000000000000000000043 -:101DA0000000000000000000000000000000000033 -:101DB0000000000000000000000000000000000023 -:101DC0000000000000000000000000000000000013 -:101DD0000000000000000000000000000000000003 -:101DE00000000000000000000000000000000000F3 -:101DF00000000000000000000000000000000000E3 -:101E000000000000000000000000000000000000D2 -:101E100000000000000000000000000000000000C2 -:101E200000000000000000000000000000000000B2 -:101E300000000000000000000000000000000000A2 -:101E40000000000000000000000000000000000092 -:101E50000000000000000000000000000000000082 -:101E60000000000000000000000000000000000072 -:101E70000000000000000000000000000000000062 -:101E80000000000000000000000000000000000052 -:101E90000000000000000000000000000000000042 -:101EA0000000000000000000000000000000000032 -:101EB0000000000000000000000000000000000022 -:101EC0000000000000000000000000000000000012 -:101ED0000000000000000000000000000000000002 -:101EE00000000000000000000000000000000000F2 -:101EF00000000000000000000000000000000000E2 -:101F000000000000000000000000000000000000D1 -:101F100000000000000000000000000000000000C1 -:101F200000000000000000000000000000000000B1 -:101F300000000000000000000000000000000000A1 -:101F40000000000000000000000000000000000091 -:101F50000000000000000000000000000000000081 -:101F60000000000000000000000000000000000071 -:101F70000000000000000000000000000000000061 -:101F80000000000000000000000000000000000051 -:101F90000000000000000000000000000000000041 -:101FA0000000000000000000000000000000000031 -:101FB0000000000000000000000000000000000021 -:101FC0000000000000000000000000000000000011 -:101FD0000000000000000000000000000000000001 -:101FE00000000000000000000000000000000000F1 -:101FF00000000000000000000000000000000000E1 -:1020000000000000000000000000000000000000D0 -:1020100000000000000000000000000000000000C0 -:1020200000000000000000000000000000000000B0 -:1020300000000000000000000000000000000000A0 -:102040000000000000000000000000000000000090 -:102050000000000000000000000000000000000080 -:102060000000000000000000000000000000000070 -:102070000000000000000000000000000000000060 -:102080000000000000000000000000000000000050 -:102090000000000000000000000000000000000040 -:1020A0000000000000000000000000000000000030 -:1020B0000000000000000000000000000000000020 -:1020C0000000000000000000000000000000000010 -:1020D0000000000000000000000000000000000000 -:1020E00000000000000000000000000000000000F0 -:1020F00000000000000000000000000000000000E0 -:1021000000000000000000000000000000000000CF -:1021100000000000000000000000000000000000BF -:1021200000000000000000000000000000000000AF -:10213000000000000000000000000000000000009F -:10214000000000000000000000000000000000008F -:10215000000000000000000000000000000000007F -:10216000000000000000000000000000000000006F -:10217000000000000000000000000000000000005F -:10218000000000000000000000000000000000004F -:10219000000000000000000000000000000000003F -:1021A000000000000000000000000000000000002F -:1021B000000000000000000000000000000000001F -:1021C000000000000000000000000000000000000F -:1021D00000000000000000000000000000000000FF -:1021E00000000000000000000000000000000000EF -:1021F00000000000000000000000000000000000DF -:1022000000000000000000000000000000000000CE -:1022100000000000000000000000000000000000BE -:1022200000000000000000000000000000000000AE -:10223000000000000000000000000000000000009E -:10224000000000000000000000000000000000008E -:10225000000000000000000000000000000000007E -:10226000000000000000000000000000000000006E -:10227000000000000000000000000000000000005E -:10228000000000000000000000000000000000004E -:10229000000000000000000000000000000000003E -:1022A000000000000000000000000000000000002E -:1022B000000000000000000000000000000000001E -:1022C000000000000000000000000000000000000E -:1022D00000000000000000000000000000000000FE -:1022E00000000000000000000000000000000000EE -:1022F00000000000000000000000000000000000DE -:1023000000000000000000000000000000000000CD -:1023100000000000000000000000000000000000BD -:1023200000000000000000000000000000000000AD -:10233000000000000000000000000000000000009D -:10234000000000000000000000000000000000008D -:10235000000000000000000000000000000000007D -:10236000000000000000000000000000000000006D -:10237000000000000000000000000000000000005D -:10238000000000000000000000000000000000004D -:10239000000000000000000000000000000000003D -:1023A000000000000000000000000000000000002D -:1023B000000000000000000000000000000000001D -:1023C000000000000000000000000000000000000D -:1023D00000000000000000000000000000000000FD -:1023E00000000000000000000000000000000000ED -:1023F00000000000000000000000000000000000DD -:1024000000000000000000000000000000000000CC -:1024100000000000000000000000000000000000BC -:1024200000000000000000000000000000000000AC -:10243000000000000000000000000000000000009C -:10244000000000000000000000000000000000008C -:10245000000000000000000000000000000000007C -:10246000000000000000000000000000000000006C -:10247000000000000000000000000000000000005C -:10248000000000000000000000000000000000004C -:10249000000000000000000000000000000000003C -:1024A000000000000000000000000000000000002C -:1024B000000000000000000000000000000000001C -:1024C000000000000000000000000000000000000C -:1024D00000000000000000000000000000000000FC -:1024E00000000000000000000000000000000000EC -:1024F00000000000000000000000000000000000DC -:1025000000000000000000000000000000000000CB -:1025100000000000000000000000000000000000BB -:1025200000000000000000000000000000000000AB -:10253000000000000000000000000000000000009B -:10254000000000000000000000000000000000008B -:10255000000000000000000000000000000000007B -:10256000000000000000000000000000000000006B -:10257000000000000000000000000000000000005B -:10258000000000000000000000000000000000004B -:10259000000000000000000000000000000000003B -:1025A000000000000000000000000000000000002B -:1025B000000000000000000000000000000000001B -:1025C000000000000000000000000000000000000B -:1025D00000000000000000000000000000000000FB -:1025E00000000000000000000000000000000000EB -:1025F00000000000000000000000000000000000DB -:1026000000000000000000000000000000000000CA -:1026100000000000000000000000000000000000BA -:1026200000000000000000000000000000000000AA -:10263000000000000000000000000000000000009A -:10264000000000000000000000000000000000008A -:10265000000000000000000000000000000000007A -:10266000000000000000000000000000000000006A -:10267000000000000000000000000000000000005A -:10268000000000000000000000000000000000004A -:10269000000000000000000000000000000000003A -:1026A000000000000000000000000000000000002A -:1026B000000000000000000000000000000000001A -:1026C000000000000000000000000000000000000A -:1026D00000000000000000000000000000000000FA -:1026E00000000000000000000000000000000000EA -:1026F00000000000000000000000000000000000DA -:1027000000000000000000000000000000000000C9 -:1027100000000000000000000000000000000000B9 -:1027200000000000000000000000000000000000A9 -:102730000000000000000000000000000000000099 -:102740000000000000000000000000000000000089 -:102750000000000000000000000000000000000079 -:102760000000000000000000000000000000000069 -:102770000000000000000000000000000000000059 -:102780000000000000000000000000000000000049 -:102790000000000000000000000000000000000039 -:1027A0000000000000000000000000000000000029 -:1027B0000000000000000000000000000000000019 -:1027C0000000000000000000000000000000000009 -:1027D00000000000000000000000000000000000F9 -:1027E00000000000000000000000000000000000E9 -:1027F00000000000000000000000000000000000D9 -:1028000000000000000000000000000000000000C8 -:1028100000000000000000000000000000000000B8 -:1028200000000000000000000000000000000000A8 -:102830000000000000000000000000000000000098 -:102840000000000000000000000000000000000088 -:102850000000000000000000000000000000000078 -:102860000000000000000000000000000000000068 -:102870000000000000000000000000000000000058 -:102880000000000000000000000000000000000048 -:102890000000000000000000000000000000000038 -:1028A0000000000000000000000000000000000028 -:1028B0000000000000000000000000000000000018 -:1028C0000000000000000000000000000000000008 -:1028D00000000000000000000000000000000000F8 -:1028E00000000000000000000000000000000000E8 -:1028F00000000000000000000000000000000000D8 -:1029000000000000000000000000000000000000C7 -:1029100000000000000000000000000000000000B7 -:1029200000000000000000000000000000000000A7 -:102930000000000000000000000000000000000097 -:102940000000000000000000000000000000000087 -:102950000000000000000000000000000000000077 -:102960000000000000000000000000000000000067 -:102970000000000000000000000000000000000057 -:102980000000000000000000000000000000000047 -:102990000000000000000000000000000000000037 -:1029A0000000000000000000000000000000000027 -:1029B0000000000000000000000000000000000017 -:1029C0000000000000000000000000000000000007 -:1029D00000000000000000000000000000000000F7 -:1029E00000000000000000000000000000000000E7 -:1029F00000000000000000000000000000000000D7 -:102A000000000000000000000000000000000000C6 -:102A100000000000000000000000000000000000B6 -:102A200000000000000000000000000000000000A6 -:102A30000000000000000000000000000000000096 -:102A40000000000000000000000000000000000086 -:102A50000000000000000000000000000000000076 -:102A60000000000000000000000000000000000066 -:102A70000000000000000000000000000000000056 -:102A80000000000000000000000000000000000046 -:102A90000000000000000000000000000000000036 -:102AA0000000000000000000000000000000000026 -:102AB0000000000000000000000000000000000016 -:102AC0000000000000000000000000000000000006 -:102AD00000000000000000000000000000000000F6 -:102AE00000000000000000000000000000000000E6 -:102AF00000000000000000000000000000000000D6 -:102B000000000000000000000000000000000000C5 -:102B100000000000000000000000000000000000B5 -:102B200000000000000000000000000000000000A5 -:102B30000000000000000000000000000000000095 -:102B40000000000000000000000000000000000085 -:102B50000000000000000000000000000000000075 -:102B60000000000000000000000000000000000065 -:102B70000000000000000000000000000000000055 -:102B80000000000000000000000000000000000045 -:102B90000000000000000000000000000000000035 -:102BA0000000000000000000000000000000000025 -:102BB0000000000000000000000000000000000015 -:102BC0000000000000000000000000000000000005 -:102BD00000000000000000000000000000000000F5 -:102BE00000000000000000000000000000000000E5 -:102BF00000000000000000000000000000000000D5 -:102C000000000000000000000000000000000000C4 -:102C100000000000000000000000000000000000B4 -:102C200000000000000000000000000000000000A4 -:102C30000000000000000000000000000000000094 -:102C40000000000000000000000000000000000084 -:102C50000000000000000000000000000000000074 -:102C60000000000000000000000000000000000064 -:102C70000000000000000000000000000000000054 -:102C80000000000000000000000000000000000044 -:102C90000000000000000000000000000000000034 -:102CA0000000000000000000000000000000000024 -:102CB0000000000000000000000000000000000014 -:102CC0000000000000000000000000000000000004 -:102CD00000000000000000000000000000000000F4 -:102CE00000000000000000000000000000000000E4 -:102CF00000000000000000000000000000000000D4 -:102D000000000000000000000000000000000000C3 -:102D100000000000000000000000000000000000B3 -:102D200000000000000000000000000000000000A3 -:102D30000000000000000000000000000000000093 -:102D40000000000000000000000000000000000083 -:102D50000000000000000000000000000000000073 -:102D60000000000000000000000000000000000063 -:102D70000000000000000000000000000000000053 -:102D80000000000000000000000000000000000043 -:102D90000000000000000000000000000000000033 -:102DA0000000000000000000000000000000000023 -:102DB0000000000000000000000000000000000013 -:102DC0000000000000000000000000000000000003 -:102DD00000000000000000000000000000000000F3 -:102DE00000000000000000000000000000000000E3 -:102DF00000000000000000000000000000000000D3 -:102E000000000000000000000000000000000000C2 -:102E100000000000000000000000000000000000B2 -:102E200000000000000000000000000000000000A2 -:102E30000000000000000000000000000000000092 -:102E40000000000000000000000000000000000082 -:102E50000000000000000000000000000000000072 -:102E60000000000000000000000000000000000062 -:102E70000000000000000000000000000000000052 -:102E80000000000000000000000000000000000042 -:102E90000000000000000000000000000000000032 -:102EA0000000000000000000000000000000000022 -:102EB0000000000000000000000000000000000012 -:102EC0000000000000000000000000000000000002 -:102ED00000000000000000000000000000000000F2 -:102EE00000000000000000000000000000000000E2 -:102EF00000000000000000000000000000000000D2 -:102F000000000000000000000000000000000000C1 -:102F100000000000000000000000000000000000B1 -:102F200000000000000000000000000000000000A1 -:102F30000000000000000000000000000000000091 -:102F40000000000000000000000000000000000081 -:102F50000000000000000000000000000000000071 -:102F60000000000000000000000000000000000061 -:102F70000000000000000000000000000000000051 -:102F80000000000000000000000000000000000041 -:102F90000000000000000000000000000000000031 -:102FA0000000000000000000000000000000000021 -:102FB0000000000000000000000000000000000011 -:102FC0000000000000000000000000000000000001 -:102FD00000000000000000000000000000000000F1 -:102FE00000000000000000000000000000000000E1 -:102FF00000000000000000000000000000000000D1 -:1030000000000000000000000000000000000000C0 -:1030100000000000000000000000000000000000B0 -:1030200000000000000000000000000000000000A0 -:103030000000000000000000000000000000000090 -:103040000000000000000000000000000000000080 -:103050000000000000000000000000000000000070 -:103060000000000000000000000000000000000060 -:103070000000000000000000000000000000000050 -:103080000000000000000000000000000000000040 -:103090000000000000000000000000000000000030 -:1030A0000000000000000000000000000000000020 -:1030B0000000000000000000000000000000000010 -:1030C0000000000000000000000000000000000000 -:1030D00000000000000000000000000000000000F0 -:1030E00000000000000000000000000000000000E0 -:1030F00000000000000000000000000000000000D0 -:1031000000000000000000000000000000000000BF -:1031100000000000000000000000000000000000AF -:10312000000000000000000000000000000000009F -:10313000000000000000000000000000000000008F -:10314000000000000000000000000000000000007F -:10315000000000000000000000000000000000006F -:10316000000000000000000000000000000000005F -:10317000000000000000000000000000000000004F -:10318000000000000000000000000000000000003F -:10319000000000000000000000000000000000002F -:1031A000000000000000000000000000000000001F -:1031B000000000000000000000000000000000000F -:1031C00000000000000000000000000000000000FF -:1031D00000000000000000000000000000000000EF -:1031E00000000000000000000000000000000000DF -:1031F00000000000000000000000000000000000CF -:1032000000000000000000000000000000000000BE -:1032100000000000000000000000000000000000AE -:10322000000000000000000000000000000000009E -:10323000000000000000000000000000000000008E -:10324000000000000000000000000000000000007E -:10325000000000000000000000000000000000006E -:10326000000000000000000000000000000000005E -:10327000000000000000000000000000000000004E -:10328000000000000000000000000000000000003E -:10329000000000000000000000000000000000002E -:1032A000000000000000000000000000000000001E -:1032B000000000000000000000000000000000000E -:1032C00000000000000000000000000000000000FE -:1032D00000000000000000000000000000000000EE -:1032E00000000000000000000000000000000000DE -:1032F00000000000000000000000000000000000CE -:1033000000000000000000000000000000000000BD -:1033100000000000000000000000000000000000AD -:10332000000000000000000000000000000000009D -:10333000000000000000000000000000000000008D -:10334000000000000000000000000000000000007D -:10335000000000000000000000000000000000006D -:10336000000000000000000000000000000000005D -:10337000000000000000000000000000000000004D -:10338000000000000000000000000000000000003D -:10339000000000000000000000000000000000002D -:1033A000000000000000000000000000000000001D -:1033B000000000000000000000000000000000000D -:1033C00000000000000000000000000000000000FD -:1033D00000000000000000000000000000000000ED -:1033E00000000000000000000000000000000000DD -:1033F00000000000000000000000000000000000CD -:1034000000000000000000000000000000000000BC -:1034100000000000000000000000000000000000AC -:10342000000000000000000000000000000000009C -:10343000000000000000000000000000000000008C -:10344000000000000000000000000000000000007C -:10345000000000000000000000000000000000006C -:10346000000000000000000000000000000000005C -:10347000000000000000000000000000000000004C -:10348000000000000000000000000000000000003C -:10349000000000000000000000000000000000002C -:1034A000000000000000000000000000000000001C -:1034B000000000000000000000000000000000000C -:1034C00000000000000000000000000000000000FC -:1034D00000000000000000000000000000000000EC -:1034E00000000000000000000000000000000000DC -:1034F00000000000000000000000000000000000CC -:1035000000000000000000000000000000000000BB -:1035100000000000000000000000000000000000AB -:10352000000000000000000000000000000000009B -:10353000000000000000000000000000000000008B -:10354000000000000000000000000000000000007B -:10355000000000000000000000000000000000006B -:10356000000000000000000000000000000000005B -:10357000000000000000000000000000000000004B -:10358000000000000000000000000000000000003B -:10359000000000000000000000000000000000002B -:1035A000000000000000000000000000000000001B -:1035B000000000000000000000000000000000000B -:1035C00000000000000000000000000000000000FB -:1035D00000000000000000000000000000000000EB -:1035E00000000000000000000000000000000000DB -:1035F00000000000000000000000000000000000CB -:1036000000000000000000000000000000000000BA -:1036100000000000000000000000000000000000AA -:10362000000000000000000000000000000000009A -:10363000000000000000000000000000000000008A -:10364000000000000000000000000000000000007A -:10365000000000000000000000000000000000006A -:10366000000000000000000000000000000000005A -:10367000000000000000000000000000000000004A -:10368000000000000000000000000000000000003A -:10369000000000000000000000000000000000002A -:1036A000000000000000000000000000000000001A -:1036B000000000000000000000000000000000000A -:1036C00000000000000000000000000000000000FA -:1036D00000000000000000000000000000000000EA -:1036E00000000000000000000000000000000000DA -:1036F00000000000000000000000000000000000CA -:1037000000000000000000000000000000000000B9 -:1037100000000000000000000000000000000000A9 -:103720000000000000000000000000000000000099 -:103730000000000000000000000000000000000089 -:103740000000000000000000000000000000000079 -:103750000000000000000000000000000000000069 -:103760000000000000000000000000000000000059 -:103770000000000000000000000000000000000049 -:103780000000000000000000000000000000000039 -:103790000000000000000000000000000000000029 -:1037A0000000000000000000000000000000000019 -:1037B0000000000000000000000000000000000009 -:1037C00000000000000000000000000000000000F9 -:1037D00000000000000000000000000000000000E9 -:1037E00000000000000000000000000000000000D9 -:1037F00000000000000000000000000000000000C9 -:1038000000000000000000000000000000000000B8 -:1038100000000000000000000000000000000000A8 -:103820000000000000000000000000000000000098 -:103830000000000000000000000000000000000088 -:103840000000000000000000000000000000000078 -:103850000000000000000000000000000000000068 -:103860000000000000000000000000000000000058 -:103870000000000000000000000000000000000048 -:103880000000000000000000000000000000000038 -:103890000000000000000000000000000000000028 -:1038A0000000000000000000000000000000000018 -:1038B0000000000000000000000000000000000008 -:1038C00000000000000000000000000000000000F8 -:1038D00000000000000000000000000000000000E8 -:1038E00000000000000000000000000000000000D8 -:1038F00000000000000000000000000000000000C8 -:1039000000000000000000000000000000000000B7 -:1039100000000000000000000000000000000000A7 -:103920000000000000000000000000000000000097 -:103930000000000000000000000000000000000087 -:103940000000000000000000000000000000000077 -:103950000000000000000000000000000000000067 -:103960000000000000000000000000000000000057 -:103970000000000000000000000000000000000047 -:103980000000000000000000000000000000000037 -:103990000000000000000000000000000000000027 -:1039A0000000000000000000000000000000000017 -:1039B0000000000000000000000000000000000007 -:1039C00000000000000000000000000000000000F7 -:1039D00000000000000000000000000000000000E7 -:1039E00000000000000000000000000000000000D7 -:1039F00000000000000000000000000000000000C7 -:103A000000000000000000000000000000000000B6 -:103A100000000000000000000000000000000000A6 -:103A20000000000000000000000000000000000096 -:103A30000000000000000000000000000000000086 -:103A40000000000000000000000000000000000076 -:103A50000000000000000000000000000000000066 -:103A60000000000000000000000000000000000056 -:103A70000000000000000000000000000000000046 -:103A80000000000000000000000000000000000036 -:103A90000000000000000000000000000000000026 -:103AA0000000000000000000000000000000000016 -:103AB0000000000000000000000000000000000006 -:103AC00000000000000000000000000000000000F6 -:103AD00000000000000000000000000000000000E6 -:103AE00000000000000000000000000000000000D6 -:103AF00000000000000000000000000000000000C6 -:103B000000000000000000000000000000000000B5 -:103B100000000000000000000000000000000000A5 -:103B20000000000000000000000000000000000095 -:103B30000000000000000000000000000000000085 -:103B40000000000000000000000000000000000075 -:103B50000000000000000000000000000000000065 -:103B60000000000000000000000000000000000055 -:103B70000000000000000000000000000000000045 -:103B80000000000000000000000000000000000035 -:103B90000000000000000000000000000000000025 -:103BA0000000000000000000000000000000000015 -:103BB0000000000000000000000000000000000005 -:103BC00000000000000000000000000000000000F5 -:103BD00000000000000000000000000000000000E5 -:103BE00000000000000000000000000000000000D5 -:103BF00000000000000000000000000000000000C5 -:103C000000000000000000000000000000000000B4 -:103C100000000000000000000000000000000000A4 -:103C20000000000000000000000000000000000094 -:103C30000000000000000000000000000000000084 -:103C40000000000000000000000000000000000074 -:103C50000000000000000000000000000000000064 -:103C60000000000000000000000000000000000054 -:103C70000000000000000000000000000000000044 -:103C80000000000000000000000000000000000034 -:103C90000000000000000000000000000000000024 -:103CA0000000000000000000000000000000000014 -:103CB0000000000000000000000000000000000004 -:103CC00000000000000000000000000000000000F4 -:103CD00000000000000000000000000000000000E4 -:103CE00000000000000000000000000000000000D4 -:103CF00000000000000000000000000000000000C4 -:103D000000000000000000000000000000000000B3 -:103D100000000000000000000000000000000000A3 -:103D20000000000000000000000000000000000093 -:103D30000000000000000000000000000000000083 -:103D40000000000000000000000000000000000073 -:103D50000000000000000000000000000000000063 -:103D60000000000000000000000000000000000053 -:103D70000000000000000000000000000000000043 -:103D80000000000000000000000000000000000033 -:103D90000000000000000000000000000000000023 -:103DA0000000000000000000000000000000000013 -:103DB0000000000000000000000000000000000003 -:103DC00000000000000000000000000000000000F3 -:103DD00000000000000000000000000000000000E3 -:103DE00000000000000000000000000000000000D3 -:103DF00000000000000000000000000000000000C3 -:103E000000000000000000000000000000000000B2 -:103E100000000000000000000000000000000000A2 -:103E20000000000000000000000000000000000092 -:103E30000000000000000000000000000000000082 -:103E40000000000000000000000000000000000072 -:103E50000000000000000000000000000000000062 -:103E60000000000000000000000000000000000052 -:103E70000000000000000000000000000000000042 -:103E80000000000000000000000000000000000032 -:103E90000000000000000000000000000000000022 -:103EA0000000000000000000000000000000000012 -:103EB0000000000000000000000000000000000002 -:103EC00000000000000000000000000000000000F2 -:103ED00000000000000000000000000000000000E2 -:103EE00000000000000000000000000000000000D2 -:103EF00000000000000000000000000000000000C2 -:103F000000000000000000000000000000000000B1 -:103F100000000000000000000000000000000000A1 -:103F20000000000000000000000000000000000091 -:103F30000000000000000000000000000000000081 -:103F40000000000000000000000000000000000071 -:103F50000000000000000000000000000000000061 -:103F60000000000000000000000000000000000051 -:103F70000000000000000000000000000000000041 -:103F80000000000000000000000000000000000031 -:103F90000000000000000000000000000000000021 -:103FA0000000000000000000000000000000000011 -:103FB0000000000000000000000000000000000001 -:103FC00000000000000000000000000000000000F1 -:103FD00000000000000000000000000000000000E1 -:103FE00000000000000000000000000000000000D1 -:103FF00000000000000000000000000000000000C1 -:1040000000000000000000000000000000000000B0 -:1040100000000000000000000000000000000000A0 -:104020000000000000000000000000000000000090 -:104030000000000000000000000000000000000080 -:104040000000000000000000000000000000000070 -:104050000000000000000000000000000000000060 -:104060000000000000000000000000000000000050 -:104070000000000000000000000000000000000040 -:104080000000000000000000000000000000000030 -:104090000000000000000000000000000000000020 -:1040A0000000000000000000000000000000000010 -:1040B0000000000000000000000000000000000000 -:1040C00000000000000000000000000000000000F0 -:1040D00000000000000000000000000000000000E0 -:1040E00000000000000000000000000000000000D0 -:1040F00000000000000000000000000000000000C0 -:1041000000000000000000000000000000000000AF -:10411000000000000000000000000000000000009F -:10412000000000000000000000000000000000008F -:10413000000000000000000000000000000000007F -:10414000000000000000000000000000000000006F -:10415000000000000000000000000000000000005F -:10416000000000000000000000000000000000004F -:10417000000000000000000000000000000000003F -:10418000000000000000000000000000000000002F -:10419000000000000000000000000000000000001F -:1041A000000000000000000000000000000000000F -:1041B00000000000000000000000000000000000FF -:1041C00000000000000000000000000000000000EF -:1041D00000000000000000000000000000000000DF -:1041E00000000000000000000000000000000000CF -:1041F00000000000000000000000000000000000BF -:1042000000000000000000000000000000000000AE -:10421000000000000000000000000000000000009E -:10422000000000000000000000000000000000008E -:10423000000000000000000000000000000000007E -:10424000000000000000000000000000000000006E -:10425000000000000000000000000000000000005E -:10426000000000000000000000000000000000004E -:10427000000000000000000000000000000000003E -:10428000000000000000000000000000000000002E -:10429000000000000000000000000000000000001E -:1042A000000000000000000000000000000000000E -:1042B00000000000000000000000000000000000FE -:1042C00000000000000000000000000000000000EE -:1042D00000000000000000000000000000000000DE -:1042E00000000000000000000000000000000000CE -:1042F00000000000000000000000000000000000BE -:1043000000000000000000000000000000000000AD -:10431000000000000000000000000000000000009D -:10432000000000000000000000000000000000008D -:10433000000000000000000000000000000000007D -:10434000000000000000000000000000000000006D -:10435000000000000000000000000000000000005D -:10436000000000000000000000000000000000004D -:10437000000000000000000000000000000000003D -:10438000000000000000000000000000000000002D -:10439000000000000000000000000000000000001D -:1043A000000000000000000000000000000000000D -:1043B00000000000000000000000000000000000FD -:1043C00000000000000000000000000000000000ED -:1043D00000000000000000000000000000000000DD -:1043E00000000000000000000000000000000000CD -:1043F00000000000000000000000000000000000BD -:1044000000000000000000000000000000000000AC -:10441000000000000000000000000000000000009C -:10442000000000000000000000000000000000008C -:10443000000000000000000000000000000000007C -:10444000000000000000000000000000000000006C -:10445000000000000000000000000000000000005C -:10446000000000000000000000000000000000004C -:10447000000000000000000000000000000000003C -:10448000000000000000000000000000000000002C -:10449000000000000000000000000000000000001C -:1044A000000000000000000000000000000000000C -:1044B00000000000000000000000000000000000FC -:1044C00000000000000000000000000000000000EC -:1044D00000000000000000000000000000000000DC -:1044E00000000000000000000000000000000000CC -:1044F00000000000000000000000000000000000BC -:1045000000000000000000000000000000000000AB -:10451000000000000000000000000000000000009B -:10452000000000000000000000000000000000008B -:10453000000000000000000000000000000000007B -:10454000000000000000000000000000000000006B -:10455000000000000000000000000000000000005B -:10456000000000000000000000000000000000004B -:10457000000000000000000000000000000000003B -:10458000000000000000000000000000000000002B -:10459000000000000000000000000000000000001B -:1045A000000000000000000000000000000000000B -:1045B00000000000000000000000000000000000FB -:1045C00000000000000000000000000000000000EB -:1045D00000000000000000000000000000000000DB -:1045E00000000000000000000000000000000000CB -:1045F00000000000000000000000000000000000BB -:1046000000000000000000000000000000000000AA -:10461000000000000000000000000000000000009A -:10462000000000000000000000000000000000008A -:10463000000000000000000000000000000000007A -:10464000000000000000000000000000000000006A -:10465000000000000000000000000000000000005A -:10466000000000000000000000000000000000004A -:10467000000000000000000000000000000000003A -:10468000000000000000000000000000000000002A -:10469000000000000000000000000000000000001A -:1046A000000000000000000000000000000000000A -:1046B00000000000000000000000000000000000FA -:1046C00000000000000000000000000000000000EA -:1046D00000000000000000000000000000000000DA -:1046E00000000000000000000000000000000000CA -:1046F00000000000000000000000000000000000BA -:1047000000000000000000000000000000000000A9 -:104710000000000000000000000000000000000099 -:104720000000000000000000000000000000000089 -:104730000000000000000000000000000000000079 -:104740000000000000000000000000000000000069 -:104750000000000000000000000000000000000059 -:104760000000000000000000000000000000000049 -:104770000000000000000000000000000000000039 -:104780000000000000000000000000000000000029 -:104790000000000000000000000000000000000019 -:1047A0000000000000000000000000000000000009 -:1047B00000000000000000000000000000000000F9 -:1047C00000000000000000000000000000000000E9 -:1047D00000000000000000000000000000000000D9 -:1047E00000000000000000000000000000000000C9 -:1047F00000000000000000000000000000000000B9 -:1048000000000000000000000000000000000000A8 -:104810000000000000000000000000000000000098 -:104820000000000000000000000000000000000088 -:104830000000000000000000000000000000000078 -:104840000000000000000000000000000000000068 -:104850000000000000000000000000000000000058 -:104860000000000000000000000000000000000048 -:104870000000000000000000000000000000000038 -:104880000000000000000000000000000000000028 -:104890000000000000000000000000000000000018 -:1048A0000000000000000000000000000000000008 -:1048B00000000000000000000000000000000000F8 -:1048C00000000000000000000000000000000000E8 -:1048D00000000000000000000000000000000000D8 -:1048E00000000000000000000000000000000000C8 -:1048F00000000000000000000000000000000000B8 -:1049000000000000000000000000000000000000A7 -:104910000000000000000000000000000000000097 -:104920000000000000000000000000000000000087 -:104930000000000000000000000000000000000077 -:104940000000000000000000000000000000000067 -:104950000000000000000000000000000000000057 -:104960000000000000000000000000000000000047 -:104970000000000000000000000000000000000037 -:104980000000000000000000000000000000000027 -:104990000000000000000000000000000000000017 -:1049A0000000000000000000000000000000000007 -:1049B00000000000000000000000000000000000F7 -:1049C00000000000000000000000000000000000E7 -:1049D00000000000000000000000000000000000D7 -:1049E00000000000000000000000000000000000C7 -:1049F00000000000000000000000000000000000B7 -:104A000000000000000000000000000000000000A6 -:104A10000000000000000000000000000000000096 -:104A20000000000000000000000000000000000086 -:104A30000000000000000000000000000000000076 -:104A40000000000000000000000000000000000066 -:104A50000000000000000000000000000000000056 -:104A60000000000000000000000000000000000046 -:104A70000000000000000000000000000000000036 -:104A80000000000000000000000000000000000026 -:104A90000000000000000000000000000000000016 -:104AA0000000000000000000000000000000000006 -:104AB00000000000000000000000000000000000F6 -:104AC00000000000000000000000000000000000E6 -:104AD00000000000000000000000000000000000D6 -:104AE00000000000000000000000000000000000C6 -:104AF00000000000000000000000000000000000B6 -:104B000000000000000000000000000000000000A5 -:104B10000000000000000000000000000000000095 -:104B20000000000000000000000000000000000085 -:104B30000000000000000000000000000000000075 -:104B40000000000000000000000000000000000065 -:104B50000000000000000000000000000000000055 -:104B60000000000000000000000000000000000045 -:104B70000000000000000000000000000000000035 -:104B80000000000000000000000000000000000025 -:104B90000000000000000000000000000000000015 -:104BA0000000000000000000000000000000000005 -:104BB00000000000000000000000000000000000F5 -:104BC00000000000000000000000000000000000E5 -:104BD00000000000000000000000000000000000D5 -:104BE00000000000000000000000000000000000C5 -:104BF00000000000000000000000000000000000B5 -:104C000000000000000000000000000000000000A4 -:104C10000000000000000000000000000000000094 -:104C20000000000000000000000000000000000084 -:104C30000000000000000000000000000000000074 -:104C40000000000000000000000000000000000064 -:104C50000000000000000000000000000000000054 -:104C60000000000000000000000000000000000044 -:104C70000000000000000000000000000000000034 -:104C80000000000000000000000000000000000024 -:104C90000000000000000000000000000000000014 -:104CA0000000000000000000000000000000000004 -:104CB00000000000000000000000000000000000F4 -:104CC00000000000000000000000000000000000E4 -:104CD00000000000000000000000000000000000D4 -:104CE00000000000000000000000000000000000C4 -:104CF00000000000000000000000000000000000B4 -:104D000000000000000000000000000000000000A3 -:104D10000000000000000000000000000000000093 -:104D20000000000000000000000000000000000083 -:104D30000000000000000000000000000000000073 -:104D40000000000000000000000000000000000063 -:104D50000000000000000000000000000000000053 -:104D60000000000000000000000000000000000043 -:104D70000000000000000000000000000000000033 -:104D80000000000000000000000000000000000023 -:104D90000000000000000000000000000000000013 -:104DA0000000000000000000000000000000000003 -:104DB00000000000000000000000000000000000F3 -:104DC00000000000000000000000000000000000E3 -:104DD00000000000000000000000000000000000D3 -:104DE00000000000000000000000000000000000C3 -:104DF00000000000000000000000000000000000B3 -:104E000000000000000000000000000000000000A2 -:104E10000000000000000000000000000000000092 -:104E20000000000000000000000000000000000082 -:104E30000000000000000000000000000000000072 -:104E40000000000000000000000000000000000062 -:104E50000000000000000000000000000000000052 -:104E60000000000000000000000000000000000042 -:104E70000000000000000000000000000000000032 -:104E80000000000000000000000000000000000022 -:104E90000000000000000000000000000000000012 -:104EA0000000000000000000000000000000000002 -:104EB00000000000000000000000000000000000F2 -:104EC00000000000000000000000000000000000E2 -:104ED00000000000000000000000000000000000D2 -:104EE00000000000000000000000000000000000C2 -:104EF00000000000000000000000000000000000B2 -:104F000000000000000000000000000000000000A1 -:104F10000000000000000000000000000000000091 -:104F20000000000000000000000000000000000081 -:104F30000000000000000000000000000000000071 -:104F40000000000000000000000000000000000061 -:104F50000000000000000000000000000000000051 -:104F60000000000000000000000000000000000041 -:104F70000000000000000000000000000000000031 -:104F80000000000000000000000000000000000021 -:104F90000000000000000000000000000000000011 -:104FA0000000000000000000000000000000000001 -:104FB00000000000000000000000000000000000F1 -:104FC00000000000000000000000000000000000E1 -:104FD00000000000000000000000000000000000D1 -:104FE00000000000000000000000000000000000C1 -:104FF00000000000000000000000000000000000B1 -:1050000000000000000000000000000000000000A0 -:105010000000000000000000000000000000000090 -:105020000000000000000000000000000000000080 -:105030000000000000000000000000000000000070 -:105040000000000000000000000000000000000060 -:105050000000000000000000000000000000000050 -:105060000000000000000000000000000000000040 -:105070000000000000000000000000000000000030 -:105080000000000000000000000000000000000020 -:105090000000000000000000000000000000000010 -:1050A0000000000000000000000000000000000000 -:1050B00000000000000000000000000000000000F0 -:1050C00000000000000000000000000000000000E0 -:1050D00000000000000000000000000000000000D0 -:1050E00000000000000000000000000000000000C0 -:1050F00000000000000000000000000000000000B0 -:10510000000000000000000000000000000000009F -:10511000000000000000000000000000000000008F -:10512000000000000000000000000000000000007F -:10513000000000000000000000000000000000006F -:10514000000000000000000000000000000000005F -:10515000000000000000000000000000000000004F -:10516000000000000000000000000000000000003F -:10517000000000000000000000000000000000002F -:10518000000000000000000000000000000000001F -:10519000000000000000000000000000000000000F -:1051A00000000000000000000000000000000000FF -:1051B00000000000000000000000000000000000EF -:1051C00000000000000000000000000000000000DF -:1051D00000000000000000000000000000000000CF -:1051E00000000000000000000000000000000000BF -:1051F00000000000000000000000000000000000AF -:10520000000000000000000000000000000000009E -:10521000000000000000000000000000000000008E -:10522000000000000000000000000000000000007E -:10523000000000000000000000000000000000006E -:10524000000000000000000000000000000000005E -:10525000000000000000000000000000000000004E -:10526000000000000000000000000000000000003E -:10527000000000000000000000000000000000002E -:10528000000000000000000000000000000000001E -:10529000000000000000000000000000000000000E -:1052A00000000000000000000000000000000000FE -:1052B00000000000000000000000000000000000EE -:1052C00000000000000000000000000000000000DE -:1052D00000000000000000000000000000000000CE -:1052E00000000000000000000000000000000000BE -:1052F00000000000000000000000000000000000AE -:10530000000000000000000000000000000000009D -:10531000000000000000000000000000000000008D -:10532000000000000000000000000000000000007D -:10533000000000000000000000000000000000006D -:10534000000000000000000000000000000000005D -:10535000000000000000000000000000000000004D -:10536000000000000000000000000000000000003D -:10537000000000000000000000000000000000002D -:10538000000000000000000000000000000000001D -:10539000000000000000000000000000000000000D -:1053A00000000000000000000000000000000000FD -:1053B00000000000000000000000000000000000ED -:1053C00000000000000000000000000000000000DD -:1053D00000000000000000000000000000000000CD -:1053E00000000000000000000000000000000000BD -:1053F00000000000000000000000000000000000AD -:10540000000000000000000000000000000000009C -:10541000000000000000000000000000000000008C -:10542000000000000000000000000000000000007C -:10543000000000000000000000000000000000006C -:10544000000000000000000000000000000000005C -:10545000000000000000000000000000000000004C -:10546000000000000000000000000000000000003C -:10547000000000000000000000000000000000002C -:10548000000000000000000000000000000000001C -:10549000000000000000000000000000000000000C -:1054A00000000000000000000000000000000000FC -:1054B00000000000000000000000000000000000EC -:1054C00000000000000000000000000000000000DC -:1054D00000000000000000000000000000000000CC -:1054E00000000000000000000000000000000000BC -:1054F00000000000000000000000000000000000AC -:10550000000000000000000000000000000000009B -:10551000000000000000000000000000000000008B -:10552000000000000000000000000000000000007B -:10553000000000000000000000000000000000006B -:10554000000000000000000000000000000000005B -:10555000000000000000000000000000000000004B -:10556000000000000000000000000000000000003B -:10557000000000000000000000000000000000002B -:10558000000000000000000000000000000000001B -:10559000000000000000000000000000000000000B -:1055A00000000000000000000000000000000000FB -:1055B00000000000000000000000000000000000EB -:1055C00000000000000000000000000000000000DB -:1055D00000000000000000000000000000000000CB -:1055E00000000000000000000000000000000000BB -:1055F00000000000000000000000000000000000AB -:10560000000000000000000000000000000000009A -:10561000000000000000000000000000000000008A -:10562000000000000000000000000000000000007A -:10563000000000000000000000000000000000006A -:10564000000000000000000000000000000000005A -:10565000000000000000000000000000000000004A -:10566000000000000000000000000000000000003A -:10567000000000000000000000000000000000002A -:10568000000000000000000000000000000000001A -:10569000000000000000000000000000000000000A -:1056A00000000000000000000000000000000000FA -:1056B00000000000000000000000000000000000EA -:1056C00000000000000000000000000000000000DA -:1056D00000000000000000000000000000000000CA -:1056E00000000000000000000000000000000000BA -:1056F00000000000000000000000000000000000AA -:105700000000000000000000000000000000000099 -:105710000000000000000000000000000000000089 -:105720000000000000000000000000000000000079 -:105730000000000000000000000000000000000069 -:105740000000000000000000000000000000000059 -:105750000000000000000000000000000000000049 -:105760000000000000000000000000000000000039 -:105770000000000000000000000000000000000029 -:105780000000000000000000000000000000000019 -:105790000000000000000000000000000000000009 -:1057A00000000000000000000000000000000000F9 -:1057B00000000000000000000000000000000000E9 -:1057C00000000000000000000000000000000000D9 -:1057D00000000000000000000000000000000000C9 -:1057E00000000000000000000000000000000000B9 -:1057F00000000000000000000000000000000000A9 -:105800000000000000000000000000000000000098 -:105810000000000000000000000000000000000088 -:105820000000000000000000000000000000000078 -:105830000000000000000000000000000000000068 -:105840000000000000000000000000000000000058 -:105850000000000000000000000000000000000048 -:105860000000000000000000000000000000000038 -:105870000000000000000000000000000000000028 -:105880000000000000000000000000000000000018 -:105890000000000000000000000000000000000008 -:1058A00000000000000000000000000000000000F8 -:1058B00000000000000000000000000000000000E8 -:1058C00000000000000000000000000000000000D8 -:1058D00000000000000000000000000000000000C8 -:1058E00000000000000000000000000000000000B8 -:1058F00000000000000000000000000000000000A8 -:105900000000000000000000000000000000000097 -:105910000000000000000000000000000000000087 -:105920000000000000000000000000000000000077 -:105930000000000000000000000000000000000067 -:105940000000000000000000000000000000000057 -:105950000000000000000000000000000000000047 -:105960000000000000000000000000000000000037 -:105970000000000000000000000000000000000027 -:105980000000000000000000000000000000000017 -:105990000000000000000000000000000000000007 -:1059A00000000000000000000000000000000000F7 -:1059B00000000000000000000000000000000000E7 -:1059C00000000000000000000000000000000000D7 -:1059D00000000000000000000000000000000000C7 -:1059E00000000000000000000000000000000000B7 -:1059F00000000000000000000000000000000000A7 -:105A00000000000000000000000000000000000096 -:105A10000000000000000000000000000000000086 -:105A20000000000000000000000000000000000076 -:105A30000000000000000000000000000000000066 -:105A40000000000000000000000000000000000056 -:105A50000000000000000000000000000000000046 -:105A60000000000000000000000000000000000036 -:105A70000000000000000000000000000000000026 -:105A80000000000000000000000000000000000016 -:105A90000000000000000000000000000000000006 -:105AA00000000000000000000000000000000000F6 -:105AB00000000000000000000000000000000000E6 -:105AC00000000000000000000000000000000000D6 -:105AD00000000000000000000000000000000000C6 -:105AE00000000000000000000000000000000000B6 -:105AF00000000000000000000000000000000000A6 -:105B00000000000000000000000000000000000095 -:105B10000000000000000000000000000000000085 -:105B20000000000000000000000000000000000075 -:105B30000000000000000000000000000000000065 -:105B40000000000000000000000000000000000055 -:105B50000000000000000000000000000000000045 -:105B60000000000000000000000000000000000035 -:105B70000000000000000000000000000000000025 -:105B80000000000000000000000000000000000015 -:105B90000000000000000000000000000000000005 -:105BA00000000000000000000000000000000000F5 -:105BB00000000000000000000000000000000000E5 -:105BC00000000000000000000000000000000000D5 -:105BD00000000000000000000000000000000000C5 -:105BE00000000000000000000000000000000000B5 -:105BF00000000000000000000000000000000000A5 -:105C00000000000000000000000000000000000094 -:105C10000000000000000000000000000000000084 -:105C20000000000000000000000000000000000074 -:105C30000000000000000000000000000000000064 -:105C40000000000000000000000000000000000054 -:105C50000000000000000000000000000000000044 -:105C60000000000000000000000000000000000034 -:105C70000000000000000000000000000000000024 -:105C80000000000000000000000000000000000014 -:105C90000000000000000000000000000000000004 -:105CA00000000000000000000000000000000000F4 -:105CB00000000000000000000000000000000000E4 -:105CC00000000000000000000000000000000000D4 -:105CD00000000000000000000000000000000000C4 -:105CE00000000000000000000000000000000000B4 -:105CF00000000000000000000000000000000000A4 -:105D00000000000000000000000000000000000093 -:105D10000000000000000000000000000000000083 -:105D20000000000000000000000000000000000073 -:105D30000000000000000000000000000000000063 -:105D40000000000000000000000000000000000053 -:105D50000000000000000000000000000000000043 -:105D60000000000000000000000000000000000033 -:105D70000000000000000000000000000000000023 -:105D80000000000000000000000000000000000013 -:105D90000000000000000000000000000000000003 -:105DA00000000000000000000000000000000000F3 -:105DB00000000000000000000000000000000000E3 -:105DC00000000000000000000000000000000000D3 -:105DD00000000000000000000000000000000000C3 -:105DE00000000000000000000000000000000000B3 -:105DF00000000000000000000000000000000000A3 -:105E00000000000000000000000000000000000092 -:105E10000000000000000000000000000000000082 -:105E20000000000000000000000000000000000072 -:105E30000000000000000000000000000000000062 -:105E40000000000000000000000000000000000052 -:105E50000000000000000000000000000000000042 -:105E60000000000000000000000000000000000032 -:105E70000000000000000000000000000000000022 -:105E80000000000000000000000000000000000012 -:105E90000000000000000000000000000000000002 -:105EA00000000000000000000000000000000000F2 -:105EB00000000000000000000000000000000000E2 -:105EC00000000000000000000000000000000000D2 -:105ED00000000000000000000000000000000000C2 -:105EE00000000000000000000000000000000000B2 -:105EF00000000000000000000000000000000000A2 -:105F00000000000000000000000000000000000091 -:105F10000000000000000000000000000000000081 -:105F20000000000000000000000000000000000071 -:105F30000000000000000000000000000000000061 -:105F40000000000000000000000000000000000051 -:105F50000000000000000000000000000000000041 -:105F60000000000000000000000000000000000031 -:105F70000000000000000000000000000000000021 -:105F80000000000000000000000000000000000011 -:105F90000000000000000000000000000000000001 -:105FA00000000000000000000000000000000000F1 -:105FB00000000000000000000000000000000000E1 -:105FC00000000000000000000000000000000000D1 -:105FD00000000000000000000000000000000000C1 -:105FE00000000000000000000000000000000000B1 -:105FF00000000000000000000000000000000000A1 -:106000000000000000000000000000000000000090 -:106010000000000000000000000000000000000080 -:106020000000000000000000000000000000000070 -:106030000000000000000000000000000000000060 -:106040000000000000000000000000000000000050 -:106050000000000000000000000000000000000040 -:106060000000000000000000000000000000000030 -:106070000000000000000000000000000000000020 -:106080000000000000000000000000000000000010 -:106090000000000000000000000000000000000000 -:1060A00000000000000000000000000000000000F0 -:1060B00000000000000000000000000000000000E0 -:1060C00000000000000000000000000000000000D0 -:1060D00000000000000000000000000000000000C0 -:1060E00000000000000000000000000000000000B0 -:1060F00000000000000000000000000000000000A0 -:10610000000000000000000000000000000000008F -:10611000000000000000000000000000000000007F -:10612000000000000000000000000000000000006F -:10613000000000000000000000000000000000005F -:10614000000000000000000000000000000000004F -:10615000000000000000000000000000000000003F -:10616000000000000000000000000000000000002F -:10617000000000000000000000000000000000001F -:10618000000000000000000000000000000000000F -:1061900000000000000000000000000000000000FF -:1061A00000000000000000000000000000000000EF -:1061B00000000000000000000000000000000000DF -:1061C00000000000000000000000000000000000CF -:1061D00000000000000000000000000000000000BF -:1061E00000000000000000000000000000000000AF -:1061F000000000000000000000000000000000009F -:10620000000000000000000000000000000000008E -:10621000000000000000000000000000000000007E -:10622000000000000000000000000000000000006E -:10623000000000000000000000000000000000005E -:10624000000000000000000000000000000000004E -:10625000000000000000000000000000000000003E -:10626000000000000000000000000000000000002E -:10627000000000000000000000000000000000001E -:10628000000000000000000000000000000000000E -:1062900000000000000000000000000000000000FE -:1062A00000000000000000000000000000000000EE -:1062B00000000000000000000000000000000000DE -:1062C00000000000000000000000000000000000CE -:1062D00000000000000000000000000000000000BE -:1062E00000000000000000000000000000000000AE -:1062F000000000000000000000000000000000009E -:10630000000000000000000000000000000000008D -:10631000000000000000000000000000000000007D -:10632000000000000000000000000000000000006D -:10633000000000000000000000000000000000005D -:10634000000000000000000000000000000000004D -:10635000000000000000000000000000000000003D -:10636000000000000000000000000000000000002D -:10637000000000000000000000000000000000001D -:10638000000000000000000000000000000000000D -:1063900000000000000000000000000000000000FD -:1063A00000000000000000000000000000000000ED -:1063B00000000000000000000000000000000000DD -:1063C00000000000000000000000000000000000CD -:1063D00000000000000000000000000000000000BD -:1063E00000000000000000000000000000000000AD -:1063F000000000000000000000000000000000009D -:10640000000000000000000000000000000000008C -:10641000000000000000000000000000000000007C -:10642000000000000000000000000000000000006C -:10643000000000000000000000000000000000005C -:10644000000000000000000000000000000000004C -:10645000000000000000000000000000000000003C -:10646000000000000000000000000000000000002C -:10647000000000000000000000000000000000001C -:10648000000000000000000000000000000000000C -:1064900000000000000000000000000000000000FC -:1064A00000000000000000000000000000000000EC -:1064B00000000000000000000000000000000000DC -:1064C00000000000000000000000000000000000CC -:1064D00000000000000000000000000000000000BC -:1064E00000000000000000000000000000000000AC -:1064F000000000000000000000000000000000009C -:10650000000000000000000000000000000000008B -:10651000000000000000000000000000000000007B -:10652000000000000000000000000000000000006B -:10653000000000000000000000000000000000005B -:10654000000000000000000000000000000000004B -:10655000000000000000000000000000000000003B -:10656000000000000000000000000000000000002B -:10657000000000000000000000000000000000001B -:10658000000000000000000000000000000000000B -:1065900000000000000000000000000000000000FB -:1065A00000000000000000000000000000000000EB -:1065B00000000000000000000000000000000000DB -:1065C00000000000000000000000000000000000CB -:1065D00000000000000000000000000000000000BB -:1065E00000000000000000000000000000000000AB -:1065F000000000000000000000000000000000009B -:10660000000000000000000000000000000000008A -:10661000000000000000000000000000000000007A -:10662000000000000000000000000000000000006A -:10663000000000000000000000000000000000005A -:10664000000000000000000000000000000000004A -:10665000000000000000000000000000000000003A -:10666000000000000000000000000000000000002A -:10667000000000000000000000000000000000001A -:10668000000000000000000000000000000000000A -:1066900000000000000000000000000000000000FA -:1066A00000000000000000000000000000000000EA -:1066B00000000000000000000000000000000000DA -:1066C00000000000000000000000000000000000CA -:1066D00000000000000000000000000000000000BA -:1066E00000000000000000000000000000000000AA -:1066F000000000000000000000000000000000009A -:106700000000000000000000000000000000000089 -:106710000000000000000000000000000000000079 -:106720000000000000000000000000000000000069 -:106730000000000000000000000000000000000059 -:106740000000000000000000000000000000000049 -:106750000000000000000000000000000000000039 -:106760000000000000000000000000000000000029 -:106770000000000000000000000000000000000019 -:106780000000000000000000000000000000000009 -:1067900000000000000000000000000000000000F9 -:1067A00000000000000000000000000000000000E9 -:1067B00000000000000000000000000000000000D9 -:1067C00000000000000000000000000000000000C9 -:1067D00000000000000000000000000000000000B9 -:1067E00000000000000000000000000000000000A9 -:1067F0000000000000000000000000000000000099 -:106800000000000000000000000000000000000088 -:106810000000000000000000000000000000000078 -:106820000000000000000000000000000000000068 -:106830000000000000000000000000000000000058 -:106840000000000000000000000000000000000048 -:106850000000000000000000000000000000000038 -:106860000000000000000000000000000000000028 -:106870000000000000000000000000000000000018 -:106880000000000000000000000000000000000008 -:1068900000000000000000000000000000000000F8 -:1068A00000000000000000000000000000000000E8 -:1068B00000000000000000000000000000000000D8 -:1068C00000000000000000000000000000000000C8 -:1068D00000000000000000000000000000000000B8 -:1068E00000000000000000000000000000000000A8 -:1068F0000000000000000000000000000000000098 -:106900000000000000000000000000000000000087 -:106910000000000000000000000000000000000077 -:106920000000000000000000000000000000000067 -:106930000000000000000000000000000000000057 -:106940000000000000000000000000000000000047 -:106950000000000000000000000000000000000037 -:106960000000000000000000000000000000000027 -:106970000000000000000000000000000000000017 -:106980000000000000000000000000000000000007 -:1069900000000000000000000000000000000000F7 -:1069A00000000000000000000000000000000000E7 -:1069B00000000000000000000000000000000000D7 -:1069C00000000000000000000000000000000000C7 -:1069D00000000000000000000000000000000000B7 -:1069E00000000000000000000000000000000000A7 -:1069F0000000000000000000000000000000000097 -:106A00000000000000000000000000000000000086 -:106A10000000000000000000000000000000000076 -:106A20000000000000000000000000000000000066 -:106A30000000000000000000000000000000000056 -:106A40000000000000000000000000000000000046 -:106A50000000000000000000000000000000000036 -:106A60000000000000000000000000000000000026 -:106A70000000000000000000000000000000000016 -:106A80000000000000000000000000000000000006 -:106A900000000000000000000000000000000000F6 -:106AA00000000000000000000000000000000000E6 -:106AB00000000000000000000000000000000000D6 -:106AC00000000000000000000000000000000000C6 -:106AD00000000000000000000000000000000000B6 -:106AE00000000000000000000000000000000000A6 -:106AF0000000000000000000000000000000000096 -:106B00000000000000000000000000000000000085 -:106B10000000000000000000000000000000000075 -:106B20000000000000000000000000000000000065 -:106B30000000000000000000000000000000000055 -:106B40000000000000000000000000000000000045 -:106B50000000000000000000000000000000000035 -:106B60000000000000000000000000000000000025 -:106B70000000000000000000000000000000000015 -:106B80000000000000000000000000000000000005 -:106B900000000000000000000000000000000000F5 -:106BA00000000000000000000000000000000000E5 -:106BB00000000000000000000000000000000000D5 -:106BC00000000000000000000000000000000000C5 -:106BD00000000000000000000000000000000000B5 -:106BE00000000000000000000000000000000000A5 -:106BF0000000000000000000000000000000000095 -:106C00000000000000000000000000000000000084 -:106C10000000000000000000000000000000000074 -:106C20000000000000000000000000000000000064 -:106C30000000000000000000000000000000000054 -:106C40000000000000000000000000000000000044 -:106C50000000000000000000000000000000000034 -:106C60000000000000000000000000000000000024 -:106C70000000000000000000000000000000000014 -:106C80000000000000000000000000000000000004 -:106C900000000000000000000000000000000000F4 -:106CA00000000000000000000000000000000000E4 -:106CB00000000000000000000000000000000000D4 -:106CC00000000000000000000000000000000000C4 -:106CD00000000000000000000000000000000000B4 -:106CE00000000000000000000000000000000000A4 -:106CF0000000000000000000000000000000000094 -:106D00000000000000000000000000000000000083 -:106D10000000000000000000000000000000000073 -:106D20000000000000000000000000000000000063 -:106D30000000000000000000000000000000000053 -:106D40000000000000000000000000000000000043 -:106D50000000000000000000000000000000000033 -:106D60000000000000000000000000000000000023 -:106D70000000000000000000000000000000000013 -:106D80000000000000000000000000000000000003 -:106D900000000000000000000000000000000000F3 -:106DA00000000000000000000000000000000000E3 -:106DB00000000000000000000000000000000000D3 -:106DC00000000000000000000000000000000000C3 -:106DD00000000000000000000000000000000000B3 -:106DE00000000000000000000000000000000000A3 -:106DF0000000000000000000000000000000000093 -:106E00000000000000000000000000000000000082 -:106E10000000000000000000000000000000000072 -:106E20000000000000000000000000000000000062 -:106E30000000000000000000000000000000000052 -:106E40000000000000000000000000000000000042 -:106E50000000000000000000000000000000000032 -:106E60000000000000000000000000000000000022 -:106E70000000000000000000000000000000000012 -:106E80000000000000000000000000000000000002 -:106E900000000000000000000000000000000000F2 -:106EA00000000000000000000000000000000000E2 -:106EB00000000000000000000000000000000000D2 -:106EC00000000000000000000000000000000000C2 -:106ED00000000000000000000000000000000000B2 -:106EE00000000000000000000000000000000000A2 -:106EF0000000000000000000000000000000000092 -:106F00000000000000000000000000000000000081 -:106F10000000000000000000000000000000000071 -:106F20000000000000000000000000000000000061 -:106F30000000000000000000000000000000000051 -:106F40000000000000000000000000000000000041 -:106F50000000000000000000000000000000000031 -:106F60000000000000000000000000000000000021 -:106F70000000000000000000000000000000000011 -:106F80000000000000000000000000000000000001 -:106F900000000000000000000000000000000000F1 -:106FA00000000000000000000000000000000000E1 -:106FB00000000000000000000000000000000000D1 -:106FC00000000000000000000000000000000000C1 -:106FD00000000000000000000000000000000000B1 -:106FE00000000000000000000000000000000000A1 -:106FF0000000000000000000000000000000000091 -:107000000000000000000000000000000000000080 -:107010000000000000000000000000000000000070 -:107020000000000000000000000000000000000060 -:107030000000000000000000000000000000000050 -:107040000000000000000000000000000000000040 -:107050000000000000000000000000000000000030 -:107060000000000000000000000000000000000020 -:107070000000000000000000000000000000000010 -:107080000000000000000000000000000000000000 -:1070900000000000000000000000000000000000F0 -:1070A00000000000000000000000000000000000E0 -:1070B00000000000000000000000000000000000D0 -:1070C00000000000000000000000000000000000C0 -:1070D00000000000000000000000000000000000B0 -:1070E00000000000000000000000000000000000A0 -:1070F0000000000000000000000000000000000090 -:10710000000000000000000000000000000000007F -:10711000000000000000000000000000000000006F -:10712000000000000000000000000000000000005F -:10713000000000000000000000000000000000004F -:10714000000000000000000000000000000000003F -:10715000000000000000000000000000000000002F -:10716000000000000000000000000000000000001F -:10717000000000000000000000000000000000000F -:1071800000000000000000000000000000000000FF -:1071900000000000000000000000000000000000EF -:1071A00000000000000000000000000000000000DF -:1071B00000000000000000000000000000000000CF -:1071C00000000000000000000000000000000000BF -:1071D00000000000000000000000000000000000AF -:1071E000000000000000000000000000000000009F -:1071F000000000000000000000000000000000008F -:10720000000000000000000000000000000000007E -:10721000000000000000000000000000000000006E -:10722000000000000000000000000000000000005E -:10723000000000000000000000000000000000004E -:10724000000000000000000000000000000000003E -:10725000000000000000000000000000000000002E -:10726000000000000000000000000000000000001E -:10727000000000000000000000000000000000000E -:1072800000000000000000000000000000000000FE -:1072900000000000000000000000000000000000EE -:1072A00000000000000000000000000000000000DE -:1072B00000000000000000000000000000000000CE -:1072C00000000000000000000000000000000000BE -:1072D00000000000000000000000000000000000AE -:1072E000000000000000000000000000000000009E -:1072F000000000000000000000000000000000008E -:10730000000000000000000000000000000000007D -:10731000000000000000000000000000000000006D -:10732000000000000000000000000000000000005D -:10733000000000000000000000000000000000004D -:10734000000000000000000000000000000000003D -:10735000000000000000000000000000000000002D -:10736000000000000000000000000000000000001D -:10737000000000000000000000000000000000000D -:1073800000000000000000000000000000000000FD -:1073900000000000000000000000000000000000ED -:1073A00000000000000000000000000000000000DD -:1073B00000000000000000000000000000000000CD -:1073C00000000000000000000000000000000000BD -:1073D00000000000000000000000000000000000AD -:1073E000000000000000000000000000000000009D -:1073F000000000000000000000000000000000008D -:10740000000000000000000000000000000000007C -:10741000000000000000000000000000000000006C -:10742000000000000000000000000000000000005C -:10743000000000000000000000000000000000004C -:10744000000000000000000000000000000000003C -:10745000000000000000000000000000000000002C -:10746000000000000000000000000000000000001C -:10747000000000000000000000000000000000000C -:1074800000000000000000000000000000000000FC -:1074900000000000000000000000000000000000EC -:1074A00000000000000000000000000000000000DC -:1074B00000000000000000000000000000000000CC -:1074C00000000000000000000000000000000000BC -:1074D00000000000000000000000000000000000AC -:1074E000000000000000000000000000000000009C -:1074F000000000000000000000000000000000008C -:10750000000000000000000000000000000000007B -:10751000000000000000000000000000000000006B -:10752000000000000000000000000000000000005B -:10753000000000000000000000000000000000004B -:10754000000000000000000000000000000000003B -:10755000000000000000000000000000000000002B -:10756000000000000000000000000000000000001B -:10757000000000000000000000000000000000000B -:1075800000000000000000000000000000000000FB -:1075900000000000000000000000000000000000EB -:1075A00000000000000000000000000000000000DB -:1075B00000000000000000000000000000000000CB -:1075C00000000000000000000000000000000000BB -:1075D00000000000000000000000000000000000AB -:1075E000000000000000000000000000000000009B -:1075F000000000000000000000000000000000008B -:10760000000000000000000000000000000000007A -:10761000000000000000000000000000000000006A -:10762000000000000000000000000000000000005A -:10763000000000000000000000000000000000004A -:10764000000000000000000000000000000000003A -:10765000000000000000000000000000000000002A -:10766000000000000000000000000000000000001A -:10767000000000000000000000000000000000000A -:1076800000000000000000000000000000000000FA -:1076900000000000000000000000000000000000EA -:1076A00000000000000000000000000000000000DA -:1076B00000000000000000000000000000000000CA -:1076C00000000000000000000000000000000000BA -:1076D00000000000000000000000000000000000AA -:1076E000000000000000000000000000000000009A -:1076F000000000000000000000000000000000008A -:107700000000000000000000000000000000000079 -:107710000000000000000000000000000000000069 -:107720000000000000000000000000000000000059 -:107730000000000000000000000000000000000049 -:107740000000000000000000000000000000000039 -:107750000000000000000000000000000000000029 -:107760000000000000000000000000000000000019 -:107770000000000000000000000000000000000009 -:1077800000000000000000000000000000000000F9 -:1077900000000000000000000000000000000000E9 -:1077A00000000000000000000000000000000000D9 -:1077B00000000000000000000000000000000000C9 -:1077C00000000000000000000000000000000000B9 -:1077D00000000000000000000000000000000000A9 -:1077E0000000000000000000000000000000000099 -:1077F0000000000000000000000000000000000089 -:107800000000000000000000000000000000000078 -:107810000000000000000000000000000000000068 -:107820000000000000000000000000000000000058 -:107830000000000000000000000000000000000048 -:107840000000000000000000000000000000000038 -:107850000000000000000000000000000000000028 -:107860000000000000000000000000000000000018 -:107870000000000000000000000000000000000008 -:1078800000000000000000000000000000000000F8 -:1078900000000000000000000000000000000000E8 -:1078A00000000000000000000000000000000000D8 -:1078B00000000000000000000000000000000000C8 -:1078C00000000000000000000000000000000000B8 -:1078D00000000000000000000000000000000000A8 -:1078E0000000000000000000000000000000000098 -:1078F0000000000000000000000000000000000088 -:107900000000000000000000000000000000000077 -:107910000000000000000000000000000000000067 -:107920000000000000000000000000000000000057 -:107930000000000000000000000000000000000047 -:107940000000000000000000000000000000000037 -:107950000000000000000000000000000000000027 -:107960000000000000000000000000000000000017 -:107970000000000000000000000000000000000007 -:1079800000000000000000000000000000000000F7 -:1079900000000000000000000000000000000000E7 -:1079A00000000000000000000000000000000000D7 -:1079B00000000000000000000000000000000000C7 -:1079C00000000000000000000000000000000000B7 -:1079D00000000000000000000000000000000000A7 -:1079E0000000000000000000000000000000000097 -:1079F0000000000000000000000000000000000087 -:107A00000000000000000000000000000000000076 -:107A10000000000000000000000000000000000066 -:107A20000000000000000000000000000000000056 -:107A30000000000000000000000000000000000046 -:107A40000000000000000000000000000000000036 -:107A50000000000000000000000000000000000026 -:107A60000000000000000000000000000000000016 -:107A70000000000000000000000000000000000006 -:107A800000000000000000000000000000000000F6 -:107A900000000000000000000000000000000000E6 -:107AA00000000000000000000000000000000000D6 -:107AB00000000000000000000000000000000000C6 -:107AC00000000000000000000000000000000000B6 -:107AD00000000000000000000000000000000000A6 -:107AE0000000000000000000000000000000000096 -:107AF0000000000000000000000000000000000086 -:107B00000000000000000000000000000000000075 -:107B10000000000000000000000000000000000065 -:107B20000000000000000000000000000000000055 -:107B30000000000000000000000000000000000045 -:107B40000000000000000000000000000000000035 -:107B50000000000000000000000000000000000025 -:107B60000000000000000000000000000000000015 -:107B70000000000000000000000000000000000005 -:107B800000000000000000000000000000000000F5 -:107B900000000000000000000000000000000000E5 -:107BA00000000000000000000000000000000000D5 -:107BB00000000000000000000000000000000000C5 -:107BC00000000000000000000000000000000000B5 -:107BD00000000000000000000000000000000000A5 -:107BE0000000000000000000000000000000000095 -:107BF0000000000000000000000000000000000085 -:107C00000000000000000000000000000000000074 -:107C10000000000000000000000000000000000064 -:107C20000000000000000000000000000000000054 -:107C30000000000000000000000000000000000044 -:107C40000000000000000000000000000000000034 -:107C50000000000000000000000000000000000024 -:107C60000000000000000000000000000000000014 -:107C70000000000000000000000000000000000004 -:107C800000000000000000000000000000000000F4 -:107C900000000000000000000000000000000000E4 -:107CA00000000000000000000000000000000000D4 -:107CB00000000000000000000000000000000000C4 -:107CC00000000000000000000000000000000000B4 -:107CD00000000000000000000000000000000000A4 -:107CE0000000000000000000000000000000000094 -:107CF0000000000000000000000000000000000084 -:107D00000000000000000000000000000000000073 -:107D10000000000000000000000000000000000063 -:107D20000000000000000000000000000000000053 -:107D30000000000000000000000000000000000043 -:107D40000000000000000000000000000000000033 -:107D50000000000000000000000000000000000023 -:107D60000000000000000000000000000000000013 -:107D70000000000000000000000000000000000003 -:107D800000000000000000000000000000000000F3 -:107D900000000000000000000000000000000000E3 -:107DA00000000000000000000000000000000000D3 -:107DB00000000000000000000000000000000000C3 -:107DC00000000000000000000000000000000000B3 -:107DD00000000000000000000000000000000000A3 -:107DE0000000000000000000000000000000000093 -:107DF0000000000000000000000000000000000083 -:107E00000000000000000000000000000000000072 -:107E10000000000000000000000000000000000062 -:107E20000000000000000000000000000000000052 -:107E30000000000000000000000000000000000042 -:107E40000000000000000000000000000000000032 -:107E50000000000000000000000000000000000022 -:107E60000000000000000000000000000000000012 -:107E70000000000000000000000000000000000002 -:107E800000000000000000000000000000000000F2 -:107E900000000000000000000000000000000000E2 -:107EA00000000000000000000000000000000000D2 -:107EB00000000000000000000000000000000000C2 -:107EC00000000000000000000000000000000000B2 -:107ED00000000000000000000000000000000000A2 -:107EE0000000000000000000000000000000000092 -:107EF0000000000000000000000000000000000082 -:107F00000000000000000000000000000000000071 -:107F10000000000000000000000000000000000061 -:107F20000000000000000000000000000000000051 -:107F30000000000000000000000000000000000041 -:107F40000000000000000000000000000000000031 -:107F50000000000000000000000000000000000021 -:107F60000000000000000000000000000000000011 -:107F70000000000000000000000000000000000001 -:107F800000000000000000000000000000000000F1 -:107F900000000000000000000000000000000000E1 -:107FA00000000000000000000000000000000000D1 -:107FB00000000000000000000000000000000000C1 -:107FC00000000000000000000000000000000000B1 -:107FD00000000000000000000000000000000000A1 -:107FE0000000000000000000000000000000000091 -:107FF0000000000000000000000000000000000081 -:108000000000000000000000000000000000000070 -:108010000000000000000000000000000000000060 -:108020000000000000000000000000000000000050 -:108030000000000000000000000000000000000040 -:108040000000000000000000000000000000000030 -:108050000000000000000000000000000000000020 -:108060000000000000000000000000000000000010 -:108070000000000000000000000000000000000000 -:1080800000000000000000000000000000000000F0 -:1080900000000000000000000000000000000000E0 -:1080A00000000000000000000000000000000000D0 -:1080B00000000000000000000000000000000000C0 -:1080C00000000000000000000000000000000000B0 -:1080D00000000000000000000000000000000000A0 -:1080E0000000000000000000000000000000000090 -:1080F0000000000000000000000000000000000080 -:10810000000000000000000000000000000000006F -:10811000000000000000000000000000000000005F -:10812000000000000000000000000000000000004F -:10813000000000000000000000000000000000003F -:10814000000000000000000000000000000000002F -:10815000000000000000000000000000000000001F -:10816000000000000000000000000000000000000F -:1081700000000000000000000000000000000000FF -:1081800000000000000000000000000000000000EF -:1081900000000000000000000000000000000000DF -:1081A00000000000000000000000000000000000CF -:1081B00000000000000000000000000000000000BF -:1081C00000000000000000000000000000000000AF -:1081D000000000000000000000000000000000009F -:1081E000000000000000000000000000000000008F -:1081F000000000000000000000000000000000007F -:10820000000000000000000000000000000000006E -:10821000000000000000000000000000000000005E -:10822000000000000000000000000000000000004E -:10823000000000000000000000000000000000003E -:10824000000000000000000000000000000000002E -:10825000000000000000000000000000000000001E -:10826000000000000000000000000000000000000E -:1082700000000000000000000000000000000000FE -:1082800000000000000000000000000000000000EE -:1082900000000000000000000000000000000000DE -:1082A00000000000000000000000000000000000CE -:1082B00000000000000000000000000000000000BE -:1082C00000000000000000000000000000000000AE -:1082D000000000000000000000000000000000009E -:1082E000000000000000000000000000000000008E -:1082F000000000000000000000000000000000007E -:10830000000000000000000000000000000000006D -:10831000000000000000000000000000000000005D -:10832000000000000000000000000000000000004D -:10833000000000000000000000000000000000003D -:10834000000000000000000000000000000000002D -:10835000000000000000000000000000000000001D -:10836000000000000000000000000000000000000D -:1083700000000000000000000000000000000000FD -:1083800000000000000000000000000000000000ED -:1083900000000000000000000000000000000000DD -:1083A00000000000000000000000000000000000CD -:1083B00000000000000000000000000000000000BD -:1083C00000000000000000000000000000000000AD -:1083D000000000000000000000000000000000009D -:1083E000000000000000000000000000000000008D -:1083F000000000000000000000000000000000007D -:10840000000000000000000000000000000000006C -:10841000000000000000000000000000000000005C -:10842000000000000000000000000000000000004C -:10843000000000000000000000000000000000003C -:10844000000000000000000000000000000000002C -:10845000000000000000000000000000000000001C -:10846000000000000000000000000000000000000C -:1084700000000000000000000000000000000000FC -:1084800000000000000000000000000000000000EC -:1084900000000000000000000000000000000000DC -:1084A00000000000000000000000000000000000CC -:1084B00000000000000000000000000000000000BC -:1084C00000000000000000000000000000000000AC -:1084D000000000000000000000000000000000009C -:1084E000000000000000000000000000000000008C -:1084F000000000000000000000000000000000007C -:10850000000000000000000000000000000000006B -:10851000000000000000000000000000000000005B -:10852000000000000000000000000000000000004B -:10853000000000000000000000000000000000003B -:10854000000000000000000000000000000000002B -:10855000000000000000000000000000000000001B -:10856000000000000000000000000000000000000B -:1085700000000000000000000000000000000000FB -:1085800000000000000000000000000000000000EB -:1085900000000000000000000000000000000000DB -:1085A00000000000000000000000000000000000CB -:1085B00000000000000000000000000000000000BB -:1085C00000000000000000000000000000000000AB -:1085D000000000000000000000000000000000009B -:1085E000000000000000000000000000000000008B -:1085F000000000000000000000000000000000007B -:10860000000000000000000000000000000000006A -:10861000000000000000000000000000000000005A -:10862000000000000000000000000000000000004A -:10863000000000000000000000000000000000003A -:10864000000000000000000000000000000000002A -:10865000000000000000000000000000000000001A -:10866000000000000000000000000000000000000A -:1086700000000000000000000000000000000000FA -:1086800000000000000000000000000000000000EA -:1086900000000000000000000000000000000000DA -:1086A00000000000000000000000000000000000CA -:1086B00000000000000000000000000000000000BA -:1086C00000000000000000000000000000000000AA -:1086D000000000000000000000000000000000009A -:1086E000000000000000000000000000000000008A -:1086F000000000000000000000000000000000007A -:108700000000000000000000000000000000000069 -:108710000000000000000000000000000000000059 -:108720000000000000000000000000000000000049 -:108730000000000000000000000000000000000039 -:108740000000000000000000000000000000000029 -:108750000000000000000000000000000000000019 -:108760000000000000000000000000000000000009 -:1087700000000000000000000000000000000000F9 -:1087800000000000000000000000000000000000E9 -:1087900000000000000000000000000000000000D9 -:1087A00000000000000000000000000000000000C9 -:1087B00000000000000000000000000000000000B9 -:1087C00000000000000000000000000000000000A9 -:1087D0000000000000000000000000000000000099 -:1087E0000000000000000000000000000000000089 -:1087F0000000000000000000000000000000000079 -:108800000000000000000000000000000000000068 -:108810000000000000000000000000000000000058 -:108820000000000000000000000000000000000048 -:108830000000000000000000000000000000000038 -:108840000000000000000000000000000000000028 -:108850000000000000000000000000000000000018 -:108860000000000000000000000000000000000008 -:1088700000000000000000000000000000000000F8 -:1088800000000000000000000000000000000000E8 -:1088900000000000000000000000000000000000D8 -:1088A00000000000000000000000000000000000C8 -:1088B00000000000000000000000000000000000B8 -:1088C00000000000000000000000000000000000A8 -:1088D0000000000000000000000000000000000098 -:1088E0000000000000000000000000000000000088 -:1088F0000000000000000000000000000000000078 -:108900000000000000000000000000000000000067 -:108910000000000000000000000000000000000057 -:108920000000000000000000000000000000000047 -:108930000000000000000000000000000000000037 -:108940000000000000000000000000000000000027 -:108950000000000000000000000000000000000017 -:108960000000000000000000000000000000000007 -:1089700000000000000000000000000000000000F7 -:1089800000000000000000000000000000000000E7 -:1089900000000000000000000000000000000000D7 -:1089A00000000000000000000000000000000000C7 -:1089B00000000000000000000000000000000000B7 -:1089C00000000000000000000000000000000000A7 -:1089D0000000000000000000000000000000000097 -:1089E0000000000000000000000000000000000087 -:1089F0000000000000000000000000000000000077 -:108A00000000000000000000000000000000000066 -:108A10000000000000000000000000000000000056 -:108A20000000000000000000000000000000000046 -:108A30000000000000000000000000000000000036 -:108A40000000000000000000000000000000000026 -:108A50000000000000000000000000000000000016 -:108A60000000000000000000000000000000000006 -:108A700000000000000000000000000000000000F6 -:108A800000000000000000000000000000000000E6 -:108A900000000000000000000000000000000000D6 -:108AA00000000000000000000000000000000000C6 -:108AB00000000000000000000000000000000000B6 -:108AC00000000000000000000000000000000000A6 -:108AD0000000000000000000000000000000000096 -:108AE0000000000000000000000000000000000086 -:108AF0000000000000000000000000000000000076 -:108B00000000000000000000000000000000000065 -:108B10000000000000000000000000000000000055 -:108B20000000000000000000000000000000000045 -:108B30000000000000000000000000000000000035 -:108B40000000000000000000000000000000000025 -:108B50000000000000000000000000000000000015 -:108B60000000000000000000000000000000000005 -:108B700000000000000000000000000000000000F5 -:108B800000000000000000000000000000000000E5 -:108B900000000000000000000000000000000000D5 -:108BA00000000000000000000000000000000000C5 -:108BB00000000000000000000000000000000000B5 -:108BC00000000000000000000000000000000000A5 -:108BD0000000000000000000000000000000000095 -:108BE0000000000000000000000000000000000085 -:108BF0000000000000000000000000000000000075 -:108C00000000000000000000000000000000000064 -:108C10000000000000000000000000000000000054 -:108C20000000000000000000000000000000000044 -:108C30000000000000000000000000000000000034 -:108C40000000000000000000000000000000000024 -:108C50000000000000000000000000000000000014 -:108C60000000000000000000000000000000000004 -:108C700000000000000000000000000000000000F4 -:108C800000000000000000000000000000000000E4 -:108C900000000000000000000000000000000000D4 -:108CA00000000000000000000000000000000000C4 -:108CB00000000000000000000000000000000000B4 -:108CC00000000000000000000000000000000000A4 -:108CD0000000000000000000000000000000000094 -:108CE0000000000000000000000000000000000084 -:108CF0000000000000000000000000000000000074 -:108D00000000000000000000000000000000000063 -:108D10000000000000000000000000000000000053 -:108D20000000000000000000000000000000000043 -:108D30000000000000000000000000000000000033 -:108D40000000000000000000000000000000000023 -:108D50000000000000000000000000000000000013 -:108D60000000000000000000000000000000000003 -:108D700000000000000000000000000000000000F3 -:108D800000000000000000000000000000000000E3 -:108D900000000000000000000000000000000000D3 -:108DA00000000000000000000000000000000000C3 -:108DB00000000000000000000000000000000000B3 -:108DC00000000000000000000000000000000000A3 -:108DD0000000000000000000000000000000000093 -:108DE0000000000000000000000000000000000083 -:108DF0000000000000000000000000000000000073 -:108E00000000000000000000000000000000000062 -:108E10000000000000000000000000000000000052 -:108E20000000000000000000000000000000000042 -:108E30000000000000000000000000000000000032 -:108E40000000000000000000000000000000000022 -:108E50000000000000000000000000000000000012 -:108E60000000000000000000000000000000000002 -:108E700000000000000000000000000000000000F2 -:108E800000000000000000000000000000000000E2 -:108E900000000000000000000000000000000000D2 -:108EA00000000000000000000000000000000000C2 -:108EB00000000000000000000000000000000000B2 -:108EC00000000000000000000000000000000000A2 -:108ED0000000000000000000000000000000000092 -:108EE0000000000000000000000000000000000082 -:108EF0000000000000000000000000000000000072 -:108F00000000000000000000000000000000000061 -:108F10000000000000000000000000000000000051 -:108F20000000000000000000000000000000000041 -:108F30000000000000000000000000000000000031 -:108F40000000000000000000000000000000000021 -:108F50000000000000000000000000000000000011 -:108F60000000000000000000000000000000000001 -:108F700000000000000000000000000000000000F1 -:108F800000000000000000000000000000000000E1 -:108F900000000000000000000000000000000000D1 -:108FA00000000000000000000000000000000000C1 -:108FB00000000000000000000000000000000000B1 -:108FC00000000000000000000000000000000000A1 -:108FD0000000000000000000000000000000000091 -:108FE0000000000000000000000000000000000081 -:108FF0000000000000000000000000000000000071 -:109000000000000000000000000000000000000060 -:109010000000000000000000000000000000000050 -:109020000000000000000000000000000000000040 -:109030000000000000000000000000000000000030 -:109040000000000000000000000000000000000020 -:109050000000000000000000000000000000000010 -:109060000000000000000000000000000000000000 -:1090700000000000000000000000000000000000F0 -:1090800000000000000000000000000000000000E0 -:1090900000000000000000000000000000000000D0 -:1090A00000000000000000000000000000000000C0 -:1090B00000000000000000000000000000000000B0 -:1090C00000000000000000000000000000000000A0 -:1090D0000000000000000000000000000000000090 -:1090E0000000000000000000000000000000000080 -:1090F0000000000000000000000000000000000070 -:10910000000000000000000000000000000000005F -:10911000000000000000000000000000000000004F -:10912000000000000000000000000000000000003F -:10913000000000000000000000000000000000002F -:10914000000000000000000000000000000000001F -:10915000000000000000000000000000000000000F -:1091600000000000000000000000000000000000FF -:1091700000000000000000000000000000000000EF -:1091800000000000000000000000000000000000DF -:1091900000000000000000000000000000000000CF -:1091A00000000000000000000000000000000000BF -:1091B00000000000000000000000000000000000AF -:1091C000000000000000000000000000000000009F -:1091D000000000000000000000000000000000008F -:1091E000000000000000000000000000000000007F -:1091F000000000000000000000000000000000006F -:10920000000000000000000000000000000000005E -:10921000000000000000000000000000000000004E -:10922000000000000000000000000000000000003E -:10923000000000000000000000000000000000002E -:10924000000000000000000000000000000000001E -:10925000000000000000000000000000000000000E -:1092600000000000000000000000000000000000FE -:1092700000000000000000000000000000000000EE -:1092800000000000000000000000000000000000DE -:1092900000000000000000000000000000000000CE -:1092A00000000000000000000000000000000000BE -:1092B00000000000000000000000000000000000AE -:1092C000000000000000000000000000000000009E -:1092D000000000000000000000000000000000008E -:1092E000000000000000000000000000000000007E -:1092F000000000000000000000000000000000006E -:10930000000000000000000000000000000000005D -:10931000000000000000000000000000000000004D -:10932000000000000000000000000000000000003D -:10933000000000000000000000000000000000002D -:10934000000000000000000000000000000000001D -:10935000000000000000000000000000000000000D -:1093600000000000000000000000000000000000FD -:1093700000000000000000000000000000000000ED -:1093800000000000000000000000000000000000DD -:1093900000000000000000000000000000000000CD -:1093A00000000000000000000000000000000000BD -:1093B00000000000000000000000000000000000AD -:1093C000000000000000000000000000000000009D -:1093D000000000000000000000000000000000008D -:1093E000000000000000000000000000000000007D -:1093F000000000000000000000000000000000006D -:10940000000000000000000000000000000000005C -:10941000000000000000000000000000000000004C -:10942000000000000000000000000000000000003C -:10943000000000000000000000000000000000002C -:10944000000000000000000000000000000000001C -:10945000000000000000000000000000000000000C -:1094600000000000000000000000000000000000FC -:1094700000000000000000000000000000000000EC -:1094800000000000000000000000000000000000DC -:1094900000000000000000000000000000000000CC -:1094A00000000000000000000000000000000000BC -:1094B00000000000000000000000000000000000AC -:1094C000000000000000000000000000000000009C -:1094D000000000000000000000000000000000008C -:1094E000000000000000000000000000000000007C -:1094F000000000000000000000000000000000006C -:10950000000000000000000000000000000000005B -:10951000000000000000000000000000000000004B -:10952000000000000000000000000000000000003B -:10953000000000000000000000000000000000002B -:10954000000000000000000000000000000000001B -:10955000000000000000000000000000000000000B -:1095600000000000000000000000000000000000FB -:1095700000000000000000000000000000000000EB -:1095800000000000000000000000000000000000DB -:1095900000000000000000000000000000000000CB -:1095A00000000000000000000000000000000000BB -:1095B00000000000000000000000000000000000AB -:1095C000000000000000000000000000000000009B -:1095D000000000000000000000000000000000008B -:1095E000000000000000000000000000000000007B -:1095F000000000000000000000000000000000006B -:10960000000000000000000000000000000000005A -:10961000000000000000000000000000000000004A -:10962000000000000000000000000000000000003A -:10963000000000000000000000000000000000002A -:10964000000000000000000000000000000000001A -:10965000000000000000000000000000000000000A -:1096600000000000000000000000000000000000FA -:1096700000000000000000000000000000000000EA -:1096800000000000000000000000000000000000DA -:1096900000000000000000000000000000000000CA -:1096A00000000000000000000000000000000000BA -:1096B00000000000000000000000000000000000AA -:1096C000000000000000000000000000000000009A -:1096D000000000000000000000000000000000008A -:1096E000000000000000000000000000000000007A -:1096F000000000000000000000000000000000006A -:109700000000000000000000000000000000000059 -:109710000000000000000000000000000000000049 -:109720000000000000000000000000000000000039 -:109730000000000000000000000000000000000029 -:109740000000000000000000000000000000000019 -:109750000000000000000000000000000000000009 -:1097600000000000000000000000000000000000F9 -:1097700000000000000000000000000000000000E9 -:1097800000000000000000000000000000000000D9 -:1097900000000000000000000000000000000000C9 -:1097A00000000000000000000000000000000000B9 -:1097B00000000000000000000000000000000000A9 -:1097C0000000000000000000000000000000000099 -:1097D0000000000000000000000000000000000089 -:1097E0000000000000000000000000000000000079 -:1097F0000000000000000000000000000000000069 -:109800000000000000000000000000000000000058 -:109810000000000000000000000000000000000048 -:109820000000000000000000000000000000000038 -:109830000000000000000000000000000000000028 -:109840000000000000000000000000000000000018 -:109850000000000000000000000000000000000008 -:1098600000000000000000000000000000000000F8 -:1098700000000000000000000000000000000000E8 -:1098800000000000000000000000000000000000D8 -:1098900000000000000000000000000000000000C8 -:1098A00000000000000000000000000000000000B8 -:1098B00000000000000000000000000000000000A8 -:1098C0000000000000000000000000000000000098 -:1098D0000000000000000000000000000000000088 -:1098E0000000000000000000000000000000000078 -:1098F0000000000000000000000000000000000068 -:109900000000000000000000000000000000000057 -:109910000000000000000000000000000000000047 -:109920000000000000000000000000000000000037 -:109930000000000000000000000000000000000027 -:109940000000000000000000000000000000000017 -:109950000000000000000000000000000000000007 -:1099600000000000000000000000000000000000F7 -:1099700000000000000000000000000000000000E7 -:1099800000000000000000000000000000000000D7 -:1099900000000000000000000000000000000000C7 -:1099A00000000000000000000000000000000000B7 -:1099B00000000000000000000000000000000000A7 -:1099C0000000000000000000000000000000000097 -:1099D0000000000000000000000000000000000087 -:1099E0000000000000000000000000000000000077 -:1099F0000000000000000000000000000000000067 -:109A00000000000000000000000000000000000056 -:109A10000000000000000000000000000000000046 -:109A20000000000000000000000000000000000036 -:109A30000000000000000000000000000000000026 -:109A40000000000000000000000000000000000016 -:109A50000000000000000000000000000000000006 -:109A600000000000000000000000000000000000F6 -:109A700000000000000000000000000000000000E6 -:109A800000000000000000000000000000000000D6 -:109A900000000000000000000000000000000000C6 -:109AA00000000000000000000000000000000000B6 -:109AB00000000000000000000000000000000000A6 -:109AC0000000000000000000000000000000000096 -:109AD0000000000000000000000000000000000086 -:109AE0000000000000000000000000000000000076 -:109AF0000000000000000000000000000000000066 -:109B00000000000000000000000000000000000055 -:109B10000000000000000000000000000000000045 -:109B20000000000000000000000000000000000035 -:109B30000000000000000000000000000000000025 -:109B40000000000000000000000000000000000015 -:109B50000000000000000000000000000000000005 -:109B600000000000000000000000000000000000F5 -:109B700000000000000000000000000000000000E5 -:109B800000000000000000000000000000000000D5 -:109B900000000000000000000000000000000000C5 -:109BA00000000000000000000000000000000000B5 -:109BB00000000000000000000000000000000000A5 -:109BC0000000000000000000000000000000000095 -:109BD0000000000000000000000000000000000085 -:109BE0000000000000000000000000000000000075 -:109BF0000000000000000000000000000000000065 -:109C00000000000000000000000000000000000054 -:109C10000000000000000000000000000000000044 -:109C20000000000000000000000000000000000034 -:109C30000000000000000000000000000000000024 -:109C40000000000000000000000000000000000014 -:109C50000000000000000000000000000000000004 -:109C600000000000000000000000000000000000F4 -:109C700000000000000000000000000000000000E4 -:109C800000000000000000000000000000000000D4 -:109C900000000000000000000000000000000000C4 -:109CA00000000000000000000000000000000000B4 -:109CB00000000000000000000000000000000000A4 -:109CC0000000000000000000000000000000000094 -:109CD0000000000000000000000000000000000084 -:109CE0000000000000000000000000000000000074 -:109CF0000000000000000000000000000000000064 -:109D00000000000000000000000000000000000053 -:109D10000000000000000000000000000000000043 -:109D20000000000000000000000000000000000033 -:109D30000000000000000000000000000000000023 -:109D40000000000000000000000000000000000013 -:109D50000000000000000000000000000000000003 -:109D600000000000000000000000000000000000F3 -:109D700000000000000000000000000000000000E3 -:109D800000000000000000000000000000000000D3 -:109D900000000000000000000000000000000000C3 -:109DA00000000000000000000000000000000000B3 -:109DB00000000000000000000000000000000000A3 -:109DC0000000000000000000000000000000000093 -:109DD0000000000000000000000000000000000083 -:109DE0000000000000000000000000000000000073 -:109DF0000000000000000000000000000000000063 -:109E00000000000000000000000000000000000052 -:109E10000000000000000000000000000000000042 -:109E20000000000000000000000000000000000032 -:109E30000000000000000000000000000000000022 -:109E40000000000000000000000000000000000012 -:109E50000000000000000000000000000000000002 -:109E600000000000000000000000000000000000F2 -:109E700000000000000000000000000000000000E2 -:109E800000000000000000000000000000000000D2 -:109E900000000000000000000000000000000000C2 -:109EA00000000000000000000000000000000000B2 -:109EB00000000000000000000000000000000000A2 -:109EC0000000000000000000000000000000000092 -:109ED0000000000000000000000000000000000082 -:109EE0000000000000000000000000000000000072 -:109EF0000000000000000000000000000000000062 -:109F00000000000000000000000000000000000051 -:109F10000000000000000000000000000000000041 -:109F20000000000000000000000000000000000031 -:109F30000000000000000000000000000000000021 -:109F40000000000000000000000000000000000011 -:109F50000000000000000000000000000000000001 -:109F600000000000000000000000000000000000F1 -:109F700000000000000000000000000000000000E1 -:109F800000000000000000000000000000000000D1 -:109F900000000000000000000000000000000000C1 -:109FA00000000000000000000000000000000000B1 -:109FB00000000000000000000000000000000000A1 -:109FC0000000000000000000000000000000000091 -:109FD0000000000000000000000000000000000081 -:109FE0000000000000000000000000000000000071 -:109FF0000000000000000000000000000000000061 -:10A000000000000000000000000000000000000050 -:10A010000000000000000000000000000000000040 -:10A020000000000000000000000000000000000030 -:10A030000000000000000000000000000000000020 -:10A040000000000000000000000000000000000010 -:10A050000000000000000000000000000000000000 -:10A0600000000000000000000000000000000000F0 -:10A0700000000000000000000000000000000000E0 -:10A0800000000000000000000000000000000000D0 -:10A0900000000000000000000000000000000000C0 -:10A0A00000000000000000000000000000000000B0 -:10A0B00000000000000000000000000000000000A0 -:10A0C0000000000000000000000000000000000090 -:10A0D0000000000000000000000000000000000080 -:10A0E0000000000000000000000000000000000070 -:10A0F0000000000000000000000000000000000060 -:10A10000000000000000000000000000000000004F -:10A11000000000000000000000000000000000003F -:10A12000000000000000000000000000000000002F -:10A13000000000000000000000000000000000001F -:10A14000000000000000000000000000000000000F -:10A1500000000000000000000000000000000000FF -:10A1600000000000000000000000000000000000EF -:10A1700000000000000000000000000000000000DF -:10A1800000000000000000000000000000000000CF -:10A1900000000000000000000000000000000000BF -:10A1A00000000000000000000000000000000000AF -:10A1B000000000000000000000000000000000009F -:10A1C000000000000000000000000000000000008F -:10A1D000000000000000000000000000000000007F -:10A1E000000000000000000000000000000000006F -:10A1F000000000000000000000000000000000005F -:10A20000000000000000000000000000000000004E -:10A21000000000000000000000000000000000003E -:10A22000000000000000000000000000000000002E -:10A23000000000000000000000000000000000001E -:10A24000000000000000000000000000000000000E -:10A2500000000000000000000000000000000000FE -:10A2600000000000000000000000000000000000EE -:10A2700000000000000000000000000000000000DE -:10A2800000000000000000000000000000000000CE -:10A2900000000000000000000000000000000000BE -:10A2A00000000000000000000000000000000000AE -:10A2B000000000000000000000000000000000009E -:10A2C000000000000000000000000000000000008E -:10A2D000000000000000000000000000000000007E -:10A2E000000000000000000000000000000000006E -:10A2F000000000000000000000000000000000005E -:10A30000000000000000000000000000000000004D -:10A31000000000000000000000000000000000003D -:10A32000000000000000000000000000000000002D -:10A33000000000000000000000000000000000001D -:10A34000000000000000000000000000000000000D -:10A3500000000000000000000000000000000000FD -:10A3600000000000000000000000000000000000ED -:10A3700000000000000000000000000000000000DD -:10A3800000000000000000000000000000000000CD -:10A3900000000000000000000000000000000000BD -:10A3A00000000000000000000000000000000000AD -:10A3B000000000000000000000000000000000009D -:10A3C000000000000000000000000000000000008D -:10A3D000000000000000000000000000000000007D -:10A3E000000000000000000000000000000000006D -:10A3F000000000000000000000000000000000005D -:10A40000000000000000000000000000000000004C -:10A41000000000000000000000000000000000003C -:10A42000000000000000000000000000000000002C -:10A43000000000000000000000000000000000001C -:10A44000000000000000000000000000000000000C -:10A4500000000000000000000000000000000000FC -:10A4600000000000000000000000000000000000EC -:10A4700000000000000000000000000000000000DC -:10A4800000000000000000000000000000000000CC -:10A4900000000000000000000000000000000000BC -:10A4A00000000000000000000000000000000000AC -:10A4B000000000000000000000000000000000009C -:10A4C000000000000000000000000000000000008C -:10A4D000000000000000000000000000000000007C -:10A4E000000000000000000000000000000000006C -:10A4F000000000000000000000000000000000005C -:10A50000000000000000000000000000000000004B -:10A51000000000000000000000000000000000003B -:10A52000000000000000000000000000000000002B -:10A53000000000000000000000000000000000001B -:10A54000000000000000000000000000000000000B -:10A5500000000000000000000000000000000000FB -:10A5600000000000000000000000000000000000EB -:10A5700000000000000000000000000000000000DB -:10A5800000000000000000000000000000000000CB -:10A5900000000000000000000000000000000000BB -:10A5A00000000000000000000000000000000000AB -:10A5B000000000000000000000000000000000009B -:10A5C000000000000000000000000000000000008B -:10A5D000000000000000000000000000000000007B -:10A5E000000000000000000000000000000000006B -:10A5F000000000000000000000000000000000005B -:10A60000000000000000000000000000000000004A -:10A61000000000000000000000000000000000003A -:10A62000000000000000000000000000000000002A -:10A63000000000000000000000000000000000001A -:10A64000000000000000000000000000000000000A -:10A6500000000000000000000000000000000000FA -:10A6600000000000000000000000000000000000EA -:10A6700000000000000000000000000000000000DA -:10A6800000000000000000000000000000000000CA -:10A6900000000000000000000000000000000000BA -:10A6A00000000000000000000000000000000000AA -:10A6B000000000000000000000000000000000009A -:10A6C000000000000000000000000000000000008A -:10A6D000000000000000000000000000000000007A -:10A6E000000000000000000000000000000000006A -:10A6F000000000000000000000000000000000005A -:10A700000000000000000000000000000000000049 -:10A710000000000000000000000000000000000039 -:10A720000000000000000000000000000000000029 -:10A730000000000000000000000000000000000019 -:10A740000000000000000000000000000000000009 -:10A7500000000000000000000000000000000000F9 -:10A7600000000000000000000000000000000000E9 -:10A7700000000000000000000000000000000000D9 -:10A7800000000000000000000000000000000000C9 -:10A7900000000000000000000000000000000000B9 -:10A7A00000000000000000000000000000000000A9 -:10A7B0000000000000000000000000000000000099 -:10A7C0000000000000000000000000000000000089 -:10A7D0000000000000000000000000000000000079 -:10A7E0000000000000000000000000000000000069 -:10A7F0000000000000000000000000000000000059 -:10A800000000000000000000000000000000000048 -:10A810000000000000000000000000000000000038 -:10A820000000000000000000000000000000000028 -:10A830000000000000000000000000000000000018 -:10A840000000000000000000000000000000000008 -:10A8500000000000000000000000000000000000F8 -:10A8600000000000000000000000000000000000E8 -:10A8700000000000000000000000000000000000D8 -:10A8800000000000000000000000000000000000C8 -:10A8900000000000000000000000000000000000B8 -:10A8A00000000000000000000000000000000000A8 -:10A8B0000000000000000000000000000000000098 -:10A8C0000000000000000000000000000000000088 -:10A8D0000000000000000000000000000000000078 -:10A8E0000000000000000000000000000000000068 -:10A8F0000000000000000000000000000000000058 -:10A900000000000000000000000000000000000047 -:10A910000000000000000000000000000000000037 -:10A920000000000000000000000000000000000027 -:10A930000000000000000000000000000000000017 -:10A940000000000000000000000000000000000007 -:10A9500000000000000000000000000000000000F7 -:10A9600000000000000000000000000000000000E7 -:10A9700000000000000000000000000000000000D7 -:10A9800000000000000000000000000000000000C7 -:10A9900000000000000000000000000000000000B7 -:10A9A00000000000000000000000000000000000A7 -:10A9B0000000000000000000000000000000000097 -:10A9C0000000000000000000000000000000000087 -:10A9D0000000000000000000000000000000000077 -:10A9E0000000000000000000000000000000000067 -:10A9F0000000000000000000000000000000000057 -:10AA00000000000000000000000000000000000046 -:10AA10000000000000000000000000000000000036 -:10AA20000000000000000000000000000000000026 -:10AA30000000000000000000000000000000000016 -:10AA40000000000000000000000000000000000006 -:10AA500000000000000000000000000000000000F6 -:10AA600000000000000000000000000000000000E6 -:10AA700000000000000000000000000000000000D6 -:10AA800000000000000000000000000000000000C6 -:10AA900000000000000000000000000000000000B6 -:10AAA00000000000000000000000000000000000A6 -:10AAB0000000000000000000000000000000000096 -:10AAC0000000000000000000000000000000000086 -:10AAD0000000000000000000000000000000000076 -:10AAE0000000000000000000000000000000000066 -:10AAF0000000000000000000000000000000000056 -:10AB00000000000000000000000000000000000045 -:10AB10000000000000000000000000000000000035 -:10AB20000000000000000000000000000000000025 -:10AB30000000000000000000000000000000000015 -:10AB40000000000000000000000000000000000005 -:10AB500000000000000000000000000000000000F5 -:10AB600000000000000000000000000000000000E5 -:10AB700000000000000000000000000000000000D5 -:10AB800000000000000000000000000000000000C5 -:10AB900000000000000000000000000000000000B5 -:10ABA00000000000000000000000000000000000A5 -:10ABB0000000000000000000000000000000000095 -:10ABC0000000000000000000000000000000000085 -:10ABD0000000000000000000000000000000000075 -:10ABE0000000000000000000000000000000000065 -:10ABF0000000000000000000000000000000000055 -:10AC00000000000000000000000000000000000044 -:10AC10000000000000000000000000000000000034 -:10AC20000000000000000000000000000000000024 -:10AC30000000000000000000000000000000000014 -:10AC40000000000000000000000000000000000004 -:10AC500000000000000000000000000000000000F4 -:10AC600000000000000000000000000000000000E4 -:10AC700000000000000000000000000000000000D4 -:10AC800000000000000000000000000000000000C4 -:10AC900000000000000000000000000000000000B4 -:10ACA00000000000000000000000000000000000A4 -:10ACB0000000000000000000000000000000000094 -:10ACC0000000000000000000000000000000000084 -:10ACD0000000000000000000000000000000000074 -:10ACE0000000000000000000000000000000000064 -:10ACF0000000000000000000000000000000000054 -:10AD00000000000000000000000000000000000043 -:10AD10000000000000000000000000000000000033 -:10AD20000000000000000000000000000000000023 -:10AD30000000000000000000000000000000000013 -:10AD40000000000000000000000000000000000003 -:10AD500000000000000000000000000000000000F3 -:10AD600000000000000000000000000000000000E3 -:10AD700000000000000000000000000000000000D3 -:10AD800000000000000000000000000000000000C3 -:10AD900000000000000000000000000000000000B3 -:10ADA00000000000000000000000000000000000A3 -:10ADB0000000000000000000000000000000000093 -:10ADC0000000000000000000000000000000000083 -:10ADD0000000000000000000000000000000000073 -:10ADE0000000000000000000000000000000000063 -:10ADF0000000000000000000000000000000000053 -:10AE00000000000000000000000000000000000042 -:10AE10000000000000000000000000000000000032 -:10AE20000000000000000000000000000000000022 -:10AE30000000000000000000000000000000000012 -:10AE40000000000000000000000000000000000002 -:10AE500000000000000000000000000000000000F2 -:10AE600000000000000000000000000000000000E2 -:10AE700000000000000000000000000000000000D2 -:10AE800000000000000000000000000000000000C2 -:10AE900000000000000000000000000000000000B2 -:10AEA00000000000000000000000000000000000A2 -:10AEB0000000000000000000000000000000000092 -:10AEC0000000000000000000000000000000000082 -:10AED0000000000000000000000000000000000072 -:10AEE0000000000000000000000000000000000062 -:10AEF0000000000000000000000000000000000052 -:10AF00000000000000000000000000000000000041 -:10AF10000000000000000000000000000000000031 -:10AF20000000000000000000000000000000000021 -:10AF30000000000000000000000000000000000011 -:10AF40000000000000000000000000000000000001 -:10AF500000000000000000000000000000000000F1 -:10AF600000000000000000000000000000000000E1 -:10AF700000000000000000000000000000000000D1 -:10AF800000000000000000000000000000000000C1 -:10AF900000000000000000000000000000000000B1 -:10AFA00000000000000000000000000000000000A1 -:10AFB0000000000000000000000000000000000091 -:10AFC0000000000000000000000000000000000081 -:10AFD0000000000000000000000000000000000071 -:10AFE0000000000000000000000000000000000061 -:10AFF0000000000000000000000000000000000051 -:10B000000000000000000000000000000000000040 -:10B010000000000000000000000000000000000030 -:10B020000000000000000000000000000000000020 -:10B030000000000000000000000000000000000010 -:10B040000000000000000000000000000000000000 -:10B0500000000000000000000000000000000000F0 -:10B0600000000000000000000000000000000000E0 -:10B0700000000000000000000000000000000000D0 -:10B0800000000000000000000000000000000000C0 -:10B0900000000000000000000000000000000000B0 -:10B0A00000000000000000000000000000000000A0 -:10B0B0000000000000000000000000000000000090 -:10B0C0000000000000000000000000000000000080 -:10B0D0000000000000000000000000000000000070 -:10B0E0000000000000000000000000000000000060 -:10B0F0000000000000000000000000000000000050 -:10B10000000000000000000000000000000000003F -:10B11000000000000000000000000000000000002F -:10B12000000000000000000000000000000000001F -:10B13000000000000000000000000000000000000F -:10B1400000000000000000000000000000000000FF -:10B1500000000000000000000000000000000000EF -:10B1600000000000000000000000000000000000DF -:10B1700000000000000000000000000000000000CF -:10B1800000000000000000000000000000000000BF -:10B1900000000000000000000000000000000000AF -:10B1A000000000000000000000000000000000009F -:10B1B000000000000000000000000000000000008F -:10B1C000000000000000000000000000000000007F -:10B1D000000000000000000000000000000000006F -:10B1E000000000000000000000000000000000005F -:10B1F000000000000000000000000000000000004F -:10B20000000000000000000000000000000000003E -:10B21000000000000000000000000000000000002E -:10B22000000000000000000000000000000000001E -:10B23000000000000000000000000000000000000E -:10B2400000000000000000000000000000000000FE -:10B2500000000000000000000000000000000000EE -:10B2600000000000000000000000000000000000DE -:10B2700000000000000000000000000000000000CE -:10B2800000000000000000000000000000000000BE -:10B2900000000000000000000000000000000000AE -:10B2A000000000000000000000000000000000009E -:10B2B000000000000000000000000000000000008E -:10B2C000000000000000000000000000000000007E -:10B2D000000000000000000000000000000000006E -:10B2E000000000000000000000000000000000005E -:10B2F000000000000000000000000000000000004E -:10B30000000000000000000000000000000000003D -:10B31000000000000000000000000000000000002D -:10B32000000000000000000000000000000000001D -:10B33000000000000000000000000000000000000D -:10B3400000000000000000000000000000000000FD -:10B3500000000000000000000000000000000000ED -:10B3600000000000000000000000000000000000DD -:10B3700000000000000000000000000000000000CD -:10B3800000000000000000000000000000000000BD -:10B3900000000000000000000000000000000000AD -:10B3A000000000000000000000000000000000009D -:10B3B000000000000000000000000000000000008D -:10B3C000000000000000000000000000000000007D -:10B3D000000000000000000000000000000000006D -:10B3E000000000000000000000000000000000005D -:10B3F000000000000000000000000000000000004D -:10B40000000000000000000000000000000000003C -:10B41000000000000000000000000000000000002C -:10B42000000000000000000000000000000000001C -:10B43000000000000000000000000000000000000C -:10B4400000000000000000000000000000000000FC -:10B4500000000000000000000000000000000000EC -:10B4600000000000000000000000000000000000DC -:10B4700000000000000000000000000000000000CC -:10B4800000000000000000000000000000000000BC -:10B4900000000000000000000000000000000000AC -:10B4A000000000000000000000000000000000009C -:10B4B000000000000000000000000000000000008C -:10B4C000000000000000000000000000000000007C -:10B4D000000000000000000000000000000000006C -:10B4E000000000000000000000000000000000005C -:10B4F000000000000000000000000000000000004C -:10B50000000000000000000000000000000000003B -:10B51000000000000000000000000000000000002B -:10B52000000000000000000000000000000000001B -:10B53000000000000000000000000000000000000B -:10B5400000000000000000000000000000000000FB -:10B5500000000000000000000000000000000000EB -:10B5600000000000000000000000000000000000DB -:10B5700000000000000000000000000000000000CB -:10B5800000000000000000000000000000000000BB -:10B5900000000000000000000000000000000000AB -:10B5A000000000000000000000000000000000009B -:10B5B000000000000000000000000000000000008B -:10B5C000000000000000000000000000000000007B -:10B5D000000000000000000000000000000000006B -:10B5E000000000000000000000000000000000005B -:10B5F000000000000000000000000000000000004B -:10B60000000000000000000000000000000000003A -:10B61000000000000000000000000000000000002A -:10B62000000000000000000000000000000000001A -:10B63000000000000000000000000000000000000A -:10B6400000000000000000000000000000000000FA -:10B6500000000000000000000000000000000000EA -:10B6600000000000000000000000000000000000DA -:10B6700000000000000000000000000000000000CA -:10B6800000000000000000000000000000000000BA -:10B6900000000000000000000000000000000000AA -:10B6A000000000000000000000000000000000009A -:10B6B000000000000000000000000000000000008A -:10B6C000000000000000000000000000000000007A -:10B6D000000000000000000000000000000000006A -:10B6E000000000000000000000000000000000005A -:10B6F000000000000000000000000000000000004A -:10B700000000000000000000000000000000000039 -:10B710000000000000000000000000000000000029 -:10B720000000000000000000000000000000000019 -:10B730000000000000000000000000000000000009 -:10B7400000000000000000000000000000000000F9 -:10B7500000000000000000000000000000000000E9 -:10B7600000000000000000000000000000000000D9 -:10B7700000000000000000000000000000000000C9 -:10B7800000000000000000000000000000000000B9 -:10B7900000000000000000000000000000000000A9 -:10B7A0000000000000000000000000000000000099 -:10B7B0000000000000000000000000000000000089 -:10B7C0000000000000000000000000000000000079 -:10B7D0000000000000000000000000000000000069 -:10B7E0000000000000000000000000000000000059 -:10B7F0000000000000000000000000000000000049 -:10B800000000000000000000000000000000000038 -:10B810000000000000000000000000000000000028 -:10B820000000000000000000000000000000000018 -:10B830000000000000000000000000000000000008 -:10B8400000000000000000000000000000000000F8 -:10B8500000000000000000000000000000000000E8 -:10B8600000000000000000000000000000000000D8 -:10B8700000000000000000000000000000000000C8 -:10B8800000000000000000000000000000000000B8 -:10B8900000000000000000000000000000000000A8 -:10B8A0000000000000000000000000000000000098 -:10B8B0000000000000000000000000000000000088 -:10B8C0000000000000000000000000000000000078 -:10B8D0000000000000000000000000000000000068 -:10B8E0000000000000000000000000000000000058 -:10B8F0000000000000000000000000000000000048 -:10B900000000000000000000000000000000000037 -:10B910000000000000000000000000000000000027 -:10B920000000000000000000000000000000000017 -:10B930000000000000000000000000000000000007 -:10B9400000000000000000000000000000000000F7 -:10B9500000000000000000000000000000000000E7 -:10B9600000000000000000000000000000000000D7 -:10B9700000000000000000000000000000000000C7 -:10B9800000000000000000000000000000000000B7 -:10B9900000000000000000000000000000000000A7 -:10B9A0000000000000000000000000000000000097 -:10B9B0000000000000000000000000000000000087 -:10B9C0000000000000000000000000000000000077 -:10B9D0000000000000000000000000000000000067 -:10B9E0000000000000000000000000000000000057 -:10B9F0000000000000000000000000000000000047 -:10BA00000000000000000000000000000000000036 -:10BA10000000000000000000000000000000000026 -:10BA20000000000000000000000000000000000016 -:10BA30000000000000000000000000000000000006 -:10BA400000000000000000000000000000000000F6 -:10BA500000000000000000000000000000000000E6 -:10BA600000000000000000000000000000000000D6 -:10BA700000000000000000000000000000000000C6 -:10BA800000000000000000000000000000000000B6 -:10BA900000000000000000000000000000000000A6 -:10BAA0000000000000000000000000000000000096 -:10BAB0000000000000000000000000000000000086 -:10BAC0000000000000000000000000000000000076 -:10BAD0000000000000000000000000000000000066 -:10BAE0000000000000000000000000000000000056 -:10BAF0000000000000000000000000000000000046 -:10BB00000000000000000000000000000000000035 -:10BB10000000000000000000000000000000000025 -:10BB20000000000000000000000000000000000015 -:10BB30000000000000000000000000000000000005 -:10BB400000000000000000000000000000000000F5 -:10BB500000000000000000000000000000000000E5 -:10BB600000000000000000000000000000000000D5 -:10BB700000000000000000000000000000000000C5 -:10BB800000000000000000000000000000000000B5 -:10BB900000000000000000000000000000000000A5 -:10BBA0000000000000000000000000000000000095 -:10BBB0000000000000000000000000000000000085 -:10BBC0000000000000000000000000000000000075 -:10BBD0000000000000000000000000000000000065 -:10BBE0000000000000000000000000000000000055 -:10BBF0000000000000000000000000000000000045 -:10BC00000000000000000000000000000000000034 -:10BC10000000000000000000000000000000000024 -:10BC20000000000000000000000000000000000014 -:10BC30000000000000000000000000000000000004 -:10BC400000000000000000000000000000000000F4 -:10BC500000000000000000000000000000000000E4 -:10BC600000000000000000000000000000000000D4 -:10BC700000000000000000000000000000000000C4 -:10BC800000000000000000000000000000000000B4 -:10BC900000000000000000000000000000000000A4 -:10BCA0000000000000000000000000000000000094 -:10BCB0000000000000000000000000000000000084 -:10BCC0000000000000000000000000000000000074 -:10BCD0000000000000000000000000000000000064 -:10BCE0000000000000000000000000000000000054 -:10BCF0000000000000000000000000000000000044 -:10BD00000000000000000000000000000000000033 -:10BD10000000000000000000000000000000000023 -:10BD20000000000000000000000000000000000013 -:10BD30000000000000000000000000000000000003 -:10BD400000000000000000000000000000000000F3 -:10BD500000000000000000000000000000000000E3 -:10BD600000000000000000000000000000000000D3 -:10BD700000000000000000000000000000000000C3 -:10BD800000000000000000000000000000000000B3 -:10BD900000000000000000000000000000000000A3 -:10BDA0000000000000000000000000000000000093 -:10BDB0000000000000000000000000000000000083 -:10BDC0000000000000000000000000000000000073 -:10BDD0000000000000000000000000000000000063 -:10BDE0000000000000000000000000000000000053 -:10BDF0000000000000000000000000000000000043 -:10BE00000000000000000000000000000000000032 -:10BE10000000000000000000000000000000000022 -:10BE20000000000000000000000000000000000012 -:10BE30000000000000000000000000000000000002 -:10BE400000000000000000000000000000000000F2 -:10BE500000000000000000000000000000000000E2 -:10BE600000000000000000000000000000000000D2 -:10BE700000000000000000000000000000000000C2 -:10BE800000000000000000000000000000000000B2 -:10BE900000000000000000000000000000000000A2 -:10BEA0000000000000000000000000000000000092 -:10BEB0000000000000000000000000000000000082 -:10BEC0000000000000000000000000000000000072 -:10BED0000000000000000000000000000000000062 -:10BEE0000000000000000000000000000000000052 -:10BEF0000000000000000000000000000000000042 -:10BF00000000000000000000000000000000000031 -:10BF10000000000000000000000000000000000021 -:10BF20000000000000000000000000000000000011 -:10BF30000000000000000000000000000000000001 -:10BF400000000000000000000000000000000000F1 -:10BF500000000000000000000000000000000000E1 -:10BF600000000000000000000000000000000000D1 -:10BF700000000000000000000000000000000000C1 -:10BF800000000000000000000000000000000000B1 -:10BF900000000000000000000000000000000000A1 -:10BFA0000000000000000000000000000000000091 -:10BFB0000000000000000000000000000000000081 -:10BFC0000000000000000000000000000000000071 -:10BFD0000000000000000000000000000000000061 -:10BFE0000000000000000000000000000000000051 -:10BFF0000000000000000000000000000000000041 -:10C000000000000000000000000000000000000030 -:10C010000000000000000000000000000000000020 -:10C020000000000000000000000000000000000010 -:10C030000000000000000000000000000000000000 -:10C0400000000000000000000000000000000000F0 -:10C0500000000000000000000000000000000000E0 -:10C0600000000000000000000000000000000000D0 -:10C0700000000000000000000000000000000000C0 -:10C0800000000000000000000000000000000000B0 -:10C0900000000000000000000000000000000000A0 -:10C0A0000000000000000000000000000000000090 -:10C0B0000000000000000000000000000000000080 -:10C0C0000000000000000000000000000000000070 -:10C0D0000000000000000000000000000000000060 -:10C0E0000000000000000000000000000000000050 -:10C0F0000000000000000000000000000000000040 -:10C10000000000000000000000000000000000002F -:10C11000000000000000000000000000000000001F -:10C12000000000000000000000000000000000000F -:10C1300000000000000000000000000000000000FF -:10C1400000000000000000000000000000000000EF -:10C1500000000000000000000000000000000000DF -:10C1600000000000000000000000000000000000CF -:10C1700000000000000000000000000000000000BF -:10C1800000000000000000000000000000000000AF -:10C19000000000000000000000000000000000009F -:10C1A000000000000000000000000000000000008F -:10C1B000000000000000000000000000000000007F -:10C1C000000000000000000000000000000000006F -:10C1D000000000000000000000000000000000005F -:10C1E000000000000000000000000000000000004F -:10C1F000000000000000000000000000000000003F -:10C20000000000000000000000000000000000002E -:10C21000000000000000000000000000000000001E -:10C22000000000000000000000000000000000000E -:10C2300000000000000000000000000000000000FE -:10C2400000000000000000000000000000000000EE -:10C2500000000000000000000000000000000000DE -:10C2600000000000000000000000000000000000CE -:10C2700000000000000000000000000000000000BE -:10C2800000000000000000000000000000000000AE -:10C29000000000000000000000000000000000009E -:10C2A000000000000000000000000000000000008E -:10C2B000000000000000000000000000000000007E -:10C2C000000000000000000000000000000000006E -:10C2D000000000000000000000000000000000005E -:10C2E000000000000000000000000000000000004E -:10C2F000000000000000000000000000000000003E -:10C30000000000000000000000000000000000002D -:10C31000000000000000000000000000000000001D -:10C32000000000000000000000000000000000000D -:10C3300000000000000000000000000000000000FD -:10C3400000000000000000000000000000000000ED -:10C3500000000000000000000000000000000000DD -:10C3600000000000000000000000000000000000CD -:10C3700000000000000000000000000000000000BD -:10C3800000000000000000000000000000000000AD -:10C39000000000000000000000000000000000009D -:10C3A000000000000000000000000000000000008D -:10C3B000000000000000000000000000000000007D -:10C3C000000000000000000000000000000000006D -:10C3D000000000000000000000000000000000005D -:10C3E000000000000000000000000000000000004D -:10C3F000000000000000000000000000000000003D -:10C40000000000000000000000000000000000002C -:10C41000000000000000000000000000000000001C -:10C42000000000000000000000000000000000000C -:10C4300000000000000000000000000000000000FC -:10C4400000000000000000000000000000000000EC -:10C4500000000000000000000000000000000000DC -:10C4600000000000000000000000000000000000CC -:10C4700000000000000000000000000000000000BC -:10C4800000000000000000000000000000000000AC -:10C49000000000000000000000000000000000009C -:10C4A000000000000000000000000000000000008C -:10C4B000000000000000000000000000000000007C -:10C4C000000000000000000000000000000000006C -:10C4D000000000000000000000000000000000005C -:10C4E000000000000000000000000000000000004C -:10C4F000000000000000000000000000000000003C -:10C50000000000000000000000000000000000002B -:10C51000000000000000000000000000000000001B -:10C52000000000000000000000000000000000000B -:10C5300000000000000000000000000000000000FB -:10C5400000000000000000000000000000000000EB -:10C5500000000000000000000000000000000000DB -:10C5600000000000000000000000000000000000CB -:10C5700000000000000000000000000000000000BB -:10C5800000000000000000000000000000000000AB -:10C59000000000000000000000000000000000009B -:10C5A000000000000000000000000000000000008B -:10C5B000000000000000000000000000000000007B -:10C5C000000000000000000000000000000000006B -:10C5D000000000000000000000000000000000005B -:10C5E000000000000000000000000000000000004B -:10C5F000000000000000000000000000000000003B -:10C60000000000000000000000000000000000002A -:10C61000000000000000000000000000000000001A -:10C62000000000000000000000000000000000000A -:10C6300000000000000000000000000000000000FA -:10C6400000000000000000000000000000000000EA -:10C6500000000000000000000000000000000000DA -:10C6600000000000000000000000000000000000CA -:10C6700000000000000000000000000000000000BA -:10C6800000000000000000000000000000000000AA -:10C69000000000000000000000000000000000009A -:10C6A000000000000000000000000000000000008A -:10C6B000000000000000000000000000000000007A -:10C6C000000000000000000000000000000000006A -:10C6D000000000000000000000000000000000005A -:10C6E000000000000000000000000000000000004A -:10C6F000000000000000000000000000000000003A -:10C700000000000000000000000000000000000029 -:10C710000000000000000000000000000000000019 -:10C720000000000000000000000000000000000009 -:10C7300000000000000000000000000000000000F9 -:10C7400000000000000000000000000000000000E9 -:10C7500000000000000000000000000000000000D9 -:10C7600000000000000000000000000000000000C9 -:10C7700000000000000000000000000000000000B9 -:10C7800000000000000000000000000000000000A9 -:10C790000000000000000000000000000000000099 -:10C7A0000000000000000000000000000000000089 -:10C7B0000000000000000000000000000000000079 -:10C7C0000000000000000000000000000000000069 -:10C7D0000000000000000000000000000000000059 -:10C7E0000000000000000000000000000000000049 -:10C7F0000000000000000000000000000000000039 -:10C800000000000000000000000000000000000028 -:10C810000000000000000000000000000000000018 -:10C820000000000000000000000000000000000008 -:10C8300000000000000000000000000000000000F8 -:10C8400000000000000000000000000000000000E8 -:10C8500000000000000000000000000000000000D8 -:10C8600000000000000000000000000000000000C8 -:10C8700000000000000000000000000000000000B8 -:10C8800000000000000000000000000000000000A8 -:10C890000000000000000000000000000000000098 -:10C8A0000000000000000000000000000000000088 -:10C8B0000000000000000000000000000000000078 -:10C8C0000000000000000000000000000000000068 -:10C8D0000000000000000000000000000000000058 -:10C8E0000000000000000000000000000000000048 -:10C8F0000000000000000000000000000000000038 -:10C900000000000000000000000000000000000027 -:10C910000000000000000000000000000000000017 -:10C920000000000000000000000000000000000007 -:10C9300000000000000000000000000000000000F7 -:10C9400000000000000000000000000000000000E7 -:10C9500000000000000000000000000000000000D7 -:10C9600000000000000000000000000000000000C7 -:10C9700000000000000000000000000000000000B7 -:10C9800000000000000000000000000000000000A7 -:10C990000000000000000000000000000000000097 -:10C9A0000000000000000000000000000000000087 -:10C9B0000000000000000000000000000000000077 -:10C9C0000000000000000000000000000000000067 -:10C9D0000000000000000000000000000000000057 -:10C9E0000000000000000000000000000000000047 -:10C9F0000000000000000000000000000000000037 -:10CA00000000000000000000000000000000000026 -:10CA10000000000000000000000000000000000016 -:10CA20000000000000000000000000000000000006 -:10CA300000000000000000000000000000000000F6 -:10CA400000000000000000000000000000000000E6 -:10CA500000000000000000000000000000000000D6 -:10CA600000000000000000000000000000000000C6 -:10CA700000000000000000000000000000000000B6 -:10CA800000000000000000000000000000000000A6 -:10CA90000000000000000000000000000000000096 -:10CAA0000000000000000000000000000000000086 -:10CAB0000000000000000000000000000000000076 -:10CAC0000000000000000000000000000000000066 -:10CAD0000000000000000000000000000000000056 -:10CAE0000000000000000000000000000000000046 -:10CAF0000000000000000000000000000000000036 -:10CB00000000000000000000000000000000000025 -:10CB10000000000000000000000000000000000015 -:10CB20000000000000000000000000000000000005 -:10CB300000000000000000000000000000000000F5 -:10CB400000000000000000000000000000000000E5 -:10CB500000000000000000000000000000000000D5 -:10CB600000000000000000000000000000000000C5 -:10CB700000000000000000000000000000000000B5 -:10CB800000000000000000000000000000000000A5 -:10CB90000000000000000000000000000000000095 -:10CBA0000000000000000000000000000000000085 -:10CBB0000000000000000000000000000000000075 -:10CBC0000000000000000000000000000000000065 -:10CBD0000000000000000000000000000000000055 -:10CBE0000000000000000000000000000000000045 -:10CBF0000000000000000000000000000000000035 -:10CC00000000000000000000000000000000000024 -:10CC10000000000000000000000000000000000014 -:10CC20000000000000000000000000000000000004 -:10CC300000000000000000000000000000000000F4 -:10CC400000000000000000000000000000000000E4 -:10CC500000000000000000000000000000000000D4 -:10CC600000000000000000000000000000000000C4 -:10CC700000000000000000000000000000000000B4 -:10CC800000000000000000000000000000000000A4 -:10CC90000000000000000000000000000000000094 -:10CCA0000000000000000000000000000000000084 -:10CCB0000000000000000000000000000000000074 -:10CCC0000000000000000000000000000000000064 -:10CCD0000000000000000000000000000000000054 -:10CCE0000000000000000000000000000000000044 -:10CCF0000000000000000000000000000000000034 -:10CD00000000000000000000000000000000000023 -:10CD10000000000000000000000000000000000013 -:10CD20000000000000000000000000000000000003 -:10CD300000000000000000000000000000000000F3 -:10CD400000000000000000000000000000000000E3 -:10CD500000000000000000000000000000000000D3 -:10CD600000000000000000000000000000000000C3 -:10CD700000000000000000000000000000000000B3 -:10CD800000000000000000000000000000000000A3 -:10CD90000000000000000000000000000000000093 -:10CDA0000000000000000000000000000000000083 -:10CDB0000000000000000000000000000000000073 -:10CDC0000000000000000000000000000000000063 -:10CDD0000000000000000000000000000000000053 -:10CDE0000000000000000000000000000000000043 -:10CDF0000000000000000000000000000000000033 -:10CE00000000000000000000000000000000000022 -:10CE10000000000000000000000000000000000012 -:10CE20000000000000000000000000000000000002 -:10CE300000000000000000000000000000000000F2 -:10CE400000000000000000000000000000000000E2 -:10CE500000000000000000000000000000000000D2 -:10CE600000000000000000000000000000000000C2 -:10CE700000000000000000000000000000000000B2 -:10CE800000000000000000000000000000000000A2 -:10CE90000000000000000000000000000000000092 -:10CEA0000000000000000000000000000000000082 -:10CEB0000000000000000000000000000000000072 -:10CEC0000000000000000000000000000000000062 -:10CED0000000000000000000000000000000000052 -:10CEE0000000000000000000000000000000000042 -:10CEF0000000000000000000000000000000000032 -:10CF00000000000000000000000000000000000021 -:10CF10000000000000000000000000000000000011 -:10CF20000000000000000000000000000000000001 -:10CF300000000000000000000000000000000000F1 -:10CF400000000000000000000000000000000000E1 -:10CF500000000000000000000000000000000000D1 -:10CF600000000000000000000000000000000000C1 -:10CF700000000000000000000000000000000000B1 -:10CF800000000000000000000000000000000000A1 -:10CF90000000000000000000000000000000000091 -:10CFA0000000000000000000000000000000000081 -:10CFB0000000000000000000000000000000000071 -:10CFC0000000000000000000000000000000000061 -:10CFD0000000000000000000000000000000000051 -:10CFE0000000000000000000000000000000000041 -:10CFF0000000000000000000000000000000000031 -:10D000000000000000000000000000000000000020 -:10D010000000000000000000000000000000000010 -:10D020000000000000000000000000000000000000 -:10D0300000000000000000000000000000000000F0 -:10D0400000000000000000000000000000000000E0 -:10D0500000000000000000000000000000000000D0 -:10D0600000000000000000000000000000000000C0 -:10D0700000000000000000000000000000000000B0 -:10D0800000000000000000000000000000000000A0 -:10D090000000000000000000000000000000000090 -:10D0A0000000000000000000000000000000000080 -:10D0B0000000000000000000000000000000000070 -:10D0C0000000000000000000000000000000000060 -:10D0D0000000000000000000000000000000000050 -:10D0E0000000000000000000000000000000000040 -:10D0F0000000000000000000000000000000000030 -:10D10000000000000000000000000000000000001F -:10D11000000000000000000000000000000000000F -:10D1200000000000000000000000000000000000FF -:10D1300000000000000000000000000000000000EF -:10D1400000000000000000000000000000000000DF -:10D1500000000000000000000000000000000000CF -:10D1600000000000000000000000000000000000BF -:10D1700000000000000000000000000000000000AF -:10D18000000000000000000000000000000000009F -:10D19000000000000000000000000000000000008F -:10D1A000000000000000000000000000000000007F -:10D1B000000000000000000000000000000000006F -:10D1C000000000000000000000000000000000005F -:10D1D000000000000000000000000000000000004F -:10D1E000000000000000000000000000000000003F -:10D1F000000000000000000000000000000000002F -:10D20000000000000000000000000000000000001E -:10D21000000000000000000000000000000000000E -:10D2200000000000000000000000000000000000FE -:10D2300000000000000000000000000000000000EE -:10D2400000000000000000000000000000000000DE -:10D2500000000000000000000000000000000000CE -:10D2600000000000000000000000000000000000BE -:10D2700000000000000000000000000000000000AE -:10D28000000000000000000000000000000000009E -:10D29000000000000000000000000000000000008E -:10D2A000000000000000000000000000000000007E -:10D2B000000000000000000000000000000000006E -:10D2C000000000000000000000000000000000005E -:10D2D000000000000000000000000000000000004E -:10D2E000000000000000000000000000000000003E -:10D2F000000000000000000000000000000000002E -:10D30000000000000000000000000000000000001D -:10D31000000000000000000000000000000000000D -:10D3200000000000000000000000000000000000FD -:10D3300000000000000000000000000000000000ED -:10D3400000000000000000000000000000000000DD -:10D3500000000000000000000000000000000000CD -:10D3600000000000000000000000000000000000BD -:10D3700000000000000000000000000000000000AD -:10D38000000000000000000000000000000000009D -:10D39000000000000000000000000000000000008D -:10D3A000000000000000000000000000000000007D -:10D3B000000000000000000000000000000000006D -:10D3C000000000000000000000000000000000005D -:10D3D000000000000000000000000000000000004D -:10D3E000000000000000000000000000000000003D -:10D3F000000000000000000000000000000000002D -:10D40000000000000000000000000000000000001C -:10D41000000000000000000000000000000000000C -:10D4200000000000000000000000000000000000FC -:10D4300000000000000000000000000000000000EC -:10D4400000000000000000000000000000000000DC -:10D4500000000000000000000000000000000000CC -:10D4600000000000000000000000000000000000BC -:10D4700000000000000000000000000000000000AC -:10D48000000000000000000000000000000000009C -:10D49000000000000000000000000000000000008C -:10D4A000000000000000000000000000000000007C -:10D4B000000000000000000000000000000000006C -:10D4C000000000000000000000000000000000005C -:10D4D000000000000000000000000000000000004C -:10D4E000000000000000000000000000000000003C -:10D4F000000000000000000000000000000000002C -:10D50000000000000000000000000000000000001B -:10D51000000000000000000000000000000000000B -:10D5200000000000000000000000000000000000FB -:10D5300000000000000000000000000000000000EB -:10D5400000000000000000000000000000000000DB -:10D5500000000000000000000000000000000000CB -:10D5600000000000000000000000000000000000BB -:10D5700000000000000000000000000000000000AB -:10D58000000000000000000000000000000000009B -:10D59000000000000000000000000000000000008B -:10D5A000000000000000000000000000000000007B -:10D5B000000000000000000000000000000000006B -:10D5C000000000000000000000000000000000005B -:10D5D000000000000000000000000000000000004B -:10D5E000000000000000000000000000000000003B -:10D5F000000000000000000000000000000000002B -:10D60000000000000000000000000000000000001A -:10D61000000000000000000000000000000000000A -:10D6200000000000000000000000000000000000FA -:10D6300000000000000000000000000000000000EA -:10D6400000000000000000000000000000000000DA -:10D6500000000000000000000000000000000000CA -:10D6600000000000000000000000000000000000BA -:10D6700000000000000000000000000000000000AA -:10D68000000000000000000000000000000000009A -:10D69000000000000000000000000000000000008A -:10D6A000000000000000000000000000000000007A -:10D6B000000000000000000000000000000000006A -:10D6C000000000000000000000000000000000005A -:10D6D000000000000000000000000000000000004A -:10D6E000000000000000000000000000000000003A -:10D6F000000000000000000000000000000000002A -:10D700000000000000000000000000000000000019 -:10D710000000000000000000000000000000000009 -:10D7200000000000000000000000000000000000F9 -:10D7300000000000000000000000000000000000E9 -:10D7400000000000000000000000000000000000D9 -:10D7500000000000000000000000000000000000C9 -:10D7600000000000000000000000000000000000B9 -:10D7700000000000000000000000000000000000A9 -:10D780000000000000000000000000000000000099 -:10D790000000000000000000000000000000000089 -:10D7A0000000000000000000000000000000000079 -:10D7B0000000000000000000000000000000000069 -:10D7C0000000000000000000000000000000000059 -:10D7D0000000000000000000000000000000000049 -:10D7E0000000000000000000000000000000000039 -:10D7F0000000000000000000000000000000000029 -:10D800000000000000000000000000000000000018 -:10D810000000000000000000000000000000000008 -:10D8200000000000000000000000000000000000F8 -:10D8300000000000000000000000000000000000E8 -:10D8400000000000000000000000000000000000D8 -:10D8500000000000000000000000000000000000C8 -:10D8600000000000000000000000000000000000B8 -:10D8700000000000000000000000000000000000A8 -:10D880000000000000000000000000000000000098 -:10D890000000000000000000000000000000000088 -:10D8A0000000000000000000000000000000000078 -:10D8B0000000000000000000000000000000000068 -:10D8C0000000000000000000000000000000000058 -:10D8D0000000000000000000000000000000000048 -:10D8E0000000000000000000000000000000000038 -:10D8F0000000000000000000000000000000000028 -:10D900000000000000000000000000000000000017 -:10D910000000000000000000000000000000000007 -:10D9200000000000000000000000000000000000F7 -:10D9300000000000000000000000000000000000E7 -:10D9400000000000000000000000000000000000D7 -:10D9500000000000000000000000000000000000C7 -:10D9600000000000000000000000000000000000B7 -:10D9700000000000000000000000000000000000A7 -:10D980000000000000000000000000000000000097 -:10D990000000000000000000000000000000000087 -:10D9A0000000000000000000000000000000000077 -:10D9B0000000000000000000000000000000000067 -:10D9C0000000000000000000000000000000000057 -:10D9D0000000000000000000000000000000000047 -:10D9E0000000000000000000000000000000000037 -:10D9F0000000000000000000000000000000000027 -:10DA00000000000000000000000000000000000016 -:10DA10000000000000000000000000000000000006 -:10DA200000000000000000000000000000000000F6 -:10DA300000000000000000000000000000000000E6 -:10DA400000000000000000000000000000000000D6 -:10DA500000000000000000000000000000000000C6 -:10DA600000000000000000000000000000000000B6 -:10DA700000000000000000000000000000000000A6 -:10DA80000000000000000000000000000000000096 -:10DA90000000000000000000000000000000000086 -:10DAA0000000000000000000000000000000000076 -:10DAB0000000000000000000000000000000000066 -:10DAC0000000000000000000000000000000000056 -:10DAD0000000000000000000000000000000000046 -:10DAE0000000000000000000000000000000000036 -:10DAF0000000000000000000000000000000000026 -:10DB00000000000000000000000000000000000015 -:10DB10000000000000000000000000000000000005 -:10DB200000000000000000000000000000000000F5 -:10DB300000000000000000000000000000000000E5 -:10DB400000000000000000000000000000000000D5 -:10DB500000000000000000000000000000000000C5 -:10DB600000000000000000000000000000000000B5 -:10DB700000000000000000000000000000000000A5 -:10DB80000000000000000000000000000000000095 -:10DB90000000000000000000000000000000000085 -:10DBA0000000000000000000000000000000000075 -:10DBB0000000000000000000000000000000000065 -:10DBC0000000000000000000000000000000000055 -:10DBD0000000000000000000000000000000000045 -:10DBE0000000000000000000000000000000000035 -:10DBF0000000000000000000000000000000000025 -:10DC00000000000000000000000000000000000014 -:10DC10000000000000000000000000000000000004 -:10DC200000000000000000000000000000000000F4 -:10DC300000000000000000000000000000000000E4 -:10DC400000000000000000000000000000000000D4 -:10DC500000000000000000000000000000000000C4 -:10DC600000000000000000000000000000000000B4 -:10DC700000000000000000000000000000000000A4 -:10DC80000000000000000000000000000000000094 -:10DC90000000000000000000000000000000000084 -:10DCA0000000000000000000000000000000000074 -:10DCB0000000000000000000000000000000000064 -:10DCC0000000000000000000000000000000000054 -:10DCD0000000000000000000000000000000000044 -:10DCE0000000000000000000000000000000000034 -:10DCF0000000000000000000000000000000000024 -:10DD00000000000000000000000000000000000013 -:10DD10000000000000000000000000000000000003 -:10DD200000000000000000000000000000000000F3 -:10DD300000000000000000000000000000000000E3 -:10DD400000000000000000000000000000000000D3 -:10DD500000000000000000000000000000000000C3 -:10DD600000000000000000000000000000000000B3 -:10DD700000000000000000000000000000000000A3 -:10DD80000000000000000000000000000000000093 -:10DD90000000000000000000000000000000000083 -:10DDA0000000000000000000000000000000000073 -:10DDB0000000000000000000000000000000000063 -:10DDC0000000000000000000000000000000000053 -:10DDD0000000000000000000000000000000000043 -:10DDE0000000000000000000000000000000000033 -:10DDF0000000000000000000000000000000000023 -:10DE00000000000000000000000000000000000012 -:10DE10000000000000000000000000000000000002 -:10DE200000000000000000000000000000000000F2 -:10DE300000000000000000000000000000000000E2 -:10DE400000000000000000000000000000000000D2 -:10DE500000000000000000000000000000000000C2 -:10DE600000000000000000000000000000000000B2 -:10DE700000000000000000000000000000000000A2 -:10DE80000000000000000000000000000000000092 -:10DE90000000000000000000000000000000000082 -:10DEA0000000000000000000000000000000000072 -:10DEB0000000000000000000000000000000000062 -:10DEC0000000000000000000000000000000000052 -:10DED0000000000000000000000000000000000042 -:10DEE0000000000000000000000000000000000032 -:10DEF0000000000000000000000000000000000022 -:10DF00000000000000000000000000000000000011 -:10DF10000000000000000000000000000000000001 -:10DF200000000000000000000000000000000000F1 -:10DF300000000000000000000000000000000000E1 -:10DF400000000000000000000000000000000000D1 -:10DF500000000000000000000000000000000000C1 -:10DF600000000000000000000000000000000000B1 -:10DF700000000000000000000000000000000000A1 -:10DF80000000000000000000000000000000000091 -:10DF90000000000000000000000000000000000081 -:10DFA0000000000000000000000000000000000071 -:10DFB0000000000000000000000000000000000061 -:10DFC0000000000000000000000000000000000051 -:10DFD0000000000000000000000000000000000041 -:10DFE0000000000000000000000000000000000031 -:10DFF0000000000000000000000000000000000021 -:10E000000000000000000000000000000000000010 -:10E010000000000000000000000000000000000000 -:10E0200000000000000000000000000000000000F0 -:10E0300000000000000000000000000000000000E0 -:10E0400000000000000000000000000000000000D0 -:10E0500000000000000000000000000000000000C0 -:10E0600000000000000000000000000000000000B0 -:10E0700000000000000000000000000000000000A0 -:10E080000000000000000000000000000000000090 -:10E090000000000000000000000000000000000080 -:10E0A0000000000000000000000000000000000070 -:10E0B0000000000000000000000000000000000060 -:10E0C0000000000000000000000000000000000050 -:10E0D0000000000000000000000000000000000040 -:10E0E0000000000000000000000000000000000030 -:10E0F0000000000000000000000000000000000020 -:10E10000000000000000000000000000000000000F -:10E1100000000000000000000000000000000000FF -:10E1200000000000000000000000000000000000EF -:10E1300000000000000000000000000000000000DF -:10E1400000000000000000000000000000000000CF -:10E1500000000000000000000000000000000000BF -:10E1600000000000000000000000000000000000AF -:10E17000000000000000000000000000000000009F -:10E18000000000000000000000000000000000008F -:10E19000000000000000000000000000000000007F -:10E1A000000000000000000000000000000000006F -:10E1B000000000000000000000000000000000005F -:10E1C000000000000000000000000000000000004F -:10E1D000000000000000000000000000000000003F -:10E1E000000000000000000000000000000000002F -:10E1F000000000000000000000000000000000001F -:10E20000000000000000000000000000000000000E -:10E2100000000000000000000000000000000000FE -:10E2200000000000000000000000000000000000EE -:10E2300000000000000000000000000000000000DE -:10E2400000000000000000000000000000000000CE -:10E2500000000000000000000000000000000000BE -:10E2600000000000000000000000000000000000AE -:10E27000000000000000000000000000000000009E -:10E28000000000000000000000000000000000008E -:10E29000000000000000000000000000000000007E -:10E2A000000000000000000000000000000000006E -:10E2B000000000000000000000000000000000005E -:10E2C000000000000000000000000000000000004E -:10E2D000000000000000000000000000000000003E -:10E2E000000000000000000000000000000000002E -:10E2F000000000000000000000000000000000001E -:10E30000000000000000000000000000000000000D -:10E3100000000000000000000000000000000000FD -:10E3200000000000000000000000000000000000ED -:10E3300000000000000000000000000000000000DD -:10E3400000000000000000000000000000000000CD -:10E3500000000000000000000000000000000000BD -:10E3600000000000000000000000000000000000AD -:10E37000000000000000000000000000000000009D -:10E38000000000000000000000000000000000008D -:10E39000000000000000000000000000000000007D -:10E3A000000000000000000000000000000000006D -:10E3B000000000000000000000000000000000005D -:10E3C000000000000000000000000000000000004D -:10E3D000000000000000000000000000000000003D -:10E3E000000000000000000000000000000000002D -:10E3F000000000000000000000000000000000001D -:10E40000000000000000000000000000000000000C -:10E4100000000000000000000000000000000000FC -:10E4200000000000000000000000000000000000EC -:10E4300000000000000000000000000000000000DC -:10E4400000000000000000000000000000000000CC -:10E4500000000000000000000000000000000000BC -:10E4600000000000000000000000000000000000AC -:10E47000000000000000000000000000000000009C -:10E48000000000000000000000000000000000008C -:10E49000000000000000000000000000000000007C -:10E4A000000000000000000000000000000000006C -:10E4B000000000000000000000000000000000005C -:10E4C000000000000000000000000000000000004C -:10E4D000000000000000000000000000000000003C -:10E4E000000000000000000000000000000000002C -:10E4F000000000000000000000000000000000001C -:10E50000000000000000000000000000000000000B -:10E5100000000000000000000000000000000000FB -:10E5200000000000000000000000000000000000EB -:10E5300000000000000000000000000000000000DB -:10E5400000000000000000000000000000000000CB -:10E5500000000000000000000000000000000000BB -:10E5600000000000000000000000000000000000AB -:10E57000000000000000000000000000000000009B -:10E58000000000000000000000000000000000008B -:10E59000000000000000000000000000000000007B -:10E5A000000000000000000000000000000000006B -:10E5B000000000000000000000000000000000005B -:10E5C000000000000000000000000000000000004B -:10E5D000000000000000000000000000000000003B -:10E5E000000000000000000000000000000000002B -:10E5F000000000000000000000000000000000001B -:10E60000000000000000000000000000000000000A -:10E6100000000000000000000000000000000000FA -:10E6200000000000000000000000000000000000EA -:10E6300000000000000000000000000000000000DA -:10E6400000000000000000000000000000000000CA -:10E6500000000000000000000000000000000000BA -:10E6600000000000000000000000000000000000AA -:10E67000000000000000000000000000000000009A -:10E68000000000000000000000000000000000008A -:10E69000000000000000000000000000000000007A -:10E6A000000000000000000000000000000000006A -:10E6B000000000000000000000000000000000005A -:10E6C000000000000000000000000000000000004A -:10E6D000000000000000000000000000000000003A -:10E6E000000000000000000000000000000000002A -:10E6F000000000000000000000000000000000001A -:10E700000000000000000000000000000000000009 -:10E7100000000000000000000000000000000000F9 -:10E7200000000000000000000000000000000000E9 -:10E7300000000000000000000000000000000000D9 -:10E7400000000000000000000000000000000000C9 -:10E7500000000000000000000000000000000000B9 -:10E7600000000000000000000000000000000000A9 -:10E770000000000000000000000000000000000099 -:10E780000000000000000000000000000000000089 -:10E790000000000000000000000000000000000079 -:10E7A0000000000000000000000000000000000069 -:10E7B0000000000000000000000000000000000059 -:10E7C0000000000000000000000000000000000049 -:10E7D0000000000000000000000000000000000039 -:10E7E0000000000000000000000000000000000029 -:10E7F0000000000000000000000000000000000019 -:10E800000000000000000000000000000000000008 -:10E8100000000000000000000000000000000000F8 -:10E8200000000000000000000000000000000000E8 -:10E8300000000000000000000000000000000000D8 -:10E8400000000000000000000000000000000000C8 -:10E8500000000000000000000000000000000000B8 -:10E8600000000000000000000000000000000000A8 -:10E870000000000000000000000000000000000098 -:10E880000000000000000000000000000000000088 -:10E890000000000000000000000000000000000078 -:10E8A0000000000000000000000000000000000068 -:10E8B0000000000000000000000000000000000058 -:10E8C0000000000000000000000000000000000048 -:10E8D0000000000000000000000000000000000038 -:10E8E0000000000000000000000000000000000028 -:10E8F0000000000000000000000000000000000018 -:10E900000000000000000000000000000000000007 -:10E9100000000000000000000000000000000000F7 -:10E9200000000000000000000000000000000000E7 -:10E9300000000000000000000000000000000000D7 -:10E9400000000000000000000000000000000000C7 -:10E9500000000000000000000000000000000000B7 -:10E9600000000000000000000000000000000000A7 -:10E970000000000000000000000000000000000097 -:10E980000000000000000000000000000000000087 -:10E990000000000000000000000000000000000077 -:10E9A0000000000000000000000000000000000067 -:10E9B0000000000000000000000000000000000057 -:10E9C0000000000000000000000000000000000047 -:10E9D0000000000000000000000000000000000037 -:10E9E0000000000000000000000000000000000027 -:10E9F0000000000000000000000000000000000017 -:10EA00000000000000000000000000000000000006 -:10EA100000000000000000000000000000000000F6 -:10EA200000000000000000000000000000000000E6 -:10EA300000000000000000000000000000000000D6 -:10EA400000000000000000000000000000000000C6 -:10EA500000000000000000000000000000000000B6 -:10EA600000000000000000000000000000000000A6 -:10EA70000000000000000000000000000000000096 -:10EA80000000000000000000000000000000000086 -:10EA90000000000000000000000000000000000076 -:10EAA0000000000000000000000000000000000066 -:10EAB0000000000000000000000000000000000056 -:10EAC0000000000000000000000000000000000046 -:10EAD0000000000000000000000000000000000036 -:10EAE0000000000000000000000000000000000026 -:10EAF0000000000000000000000000000000000016 -:10EB00000000000000000000000000000000000005 -:10EB100000000000000000000000000000000000F5 -:10EB200000000000000000000000000000000000E5 -:10EB300000000000000000000000000000000000D5 -:10EB400000000000000000000000000000000000C5 -:10EB500000000000000000000000000000000000B5 -:10EB600000000000000000000000000000000000A5 -:10EB70000000000000000000000000000000000095 -:10EB80000000000000000000000000000000000085 -:10EB90000000000000000000000000000000000075 -:10EBA0000000000000000000000000000000000065 -:10EBB0000000000000000000000000000000000055 -:10EBC0000000000000000000000000000000000045 -:10EBD0000000000000000000000000000000000035 -:10EBE0000000000000000000000000000000000025 -:10EBF0000000000000000000000000000000000015 -:10EC00000000000000000000000000000000000004 -:10EC100000000000000000000000000000000000F4 -:10EC200000000000000000000000000000000000E4 -:10EC300000000000000000000000000000000000D4 -:10EC400000000000000000000000000000000000C4 -:10EC500000000000000000000000000000000000B4 -:10EC600000000000000000000000000000000000A4 -:10EC70000000000000000000000000000000000094 -:10EC80000000000000000000000000000000000084 -:10EC90000000000000000000000000000000000074 -:10ECA0000000000000000000000000000000000064 -:10ECB0000000000000000000000000000000000054 -:10ECC0000000000000000000000000000000000044 -:10ECD0000000000000000000000000000000000034 -:10ECE0000000000000000000000000000000000024 -:10ECF0000000000000000000000000000000000014 -:10ED00000000000000000000000000000000000003 -:10ED100000000000000000000000000000000000F3 -:10ED200000000000000000000000000000000000E3 -:10ED300000000000000000000000000000000000D3 -:10ED400000000000000000000000000000000000C3 -:10ED500000000000000000000000000000000000B3 -:10ED600000000000000000000000000000000000A3 -:10ED70000000000000000000000000000000000093 -:10ED80000000000000000000000000000000000083 -:10ED90000000000000000000000000000000000073 -:10EDA0000000000000000000000000000000000063 -:10EDB0000000000000000000000000000000000053 -:10EDC0000000000000000000000000000000000043 -:10EDD0000000000000000000000000000000000033 -:10EDE0000000000000000000000000000000000023 -:10EDF0000000000000000000000000000000000013 -:10EE00000000000000000000000000000000000002 -:10EE100000000000000000000000000000000000F2 -:10EE200000000000000000000000000000000000E2 -:10EE300000000000000000000000000000000000D2 -:10EE400000000000000000000000000000000000C2 -:10EE500000000000000000000000000000000000B2 -:10EE600000000000000000000000000000000000A2 -:10EE70000000000000000000000000000000000092 -:10EE80000000000000000000000000000000000082 -:10EE90000000000000000000000000000000000072 -:10EEA0000000000000000000000000000000000062 -:10EEB0000000000000000000000000000000000052 -:10EEC0000000000000000000000000000000000042 -:10EED0000000000000000000000000000000000032 -:10EEE0000000000000000000000000000000000022 -:10EEF0000000000000000000000000000000000012 -:10EF00000000000000000000000000000000000001 -:10EF100000000000000000000000000000000000F1 -:10EF200000000000000000000000000000000000E1 -:10EF300000000000000000000000000000000000D1 -:10EF400000000000000000000000000000000000C1 -:10EF500000000000000000000000000000000000B1 -:10EF600000000000000000000000000000000000A1 -:10EF70000000000000000000000000000000000091 -:10EF80000000000000000000000000000000000081 -:10EF90000000000000000000000000000000000071 -:10EFA0000000000000000000000000000000000061 -:10EFB0000000000000000000000000000000000051 -:10EFC0000000000000000000000000000000000041 -:10EFD0000000000000000000000000000000000031 -:10EFE0000000000000000000000000000000000021 -:10EFF0000000000000000000000000000000000011 -:10F000000000000000000000000000000000000000 -:10F0100000000000000000000000000000000000F0 -:10F0200000000000000000000000000000000000E0 -:10F0300000000000000000000000000000000000D0 -:10F0400000000000000000000000000000000000C0 -:10F0500000000000000000000000000000000000B0 -:10F0600000000000000000000000000000000000A0 -:10F070000000000000000000000000000000000090 -:10F080000000000000000000000000000000000080 -:10F090000000000000000000000000000000000070 -:10F0A0000000000000000000000000000000000060 -:10F0B0000000000000000000000000000000000050 -:10F0C0000000000000000000000000000000000040 -:10F0D0000000000000000000000000000000000030 -:10F0E0000000000000000000000000000000000020 -:10F0F0000000000000000000000000000000000010 -:10F1000000000000000000000000000000000000FF -:10F1100000000000000000000000000000000000EF -:10F1200000000000000000000000000000000000DF -:10F1300000000000000000000000000000000000CF -:10F1400000000000000000000000000000000000BF -:10F1500000000000000000000000000000000000AF -:10F16000000000000000000000000000000000009F -:10F17000000000000000000000000000000000008F -:10F18000000000000000000000000000000000007F -:10F19000000000000000000000000000000000006F -:10F1A000000000000000000000000000000000005F -:10F1B000000000000000000000000000000000004F -:10F1C000000000000000000000000000000000003F -:10F1D000000000000000000000000000000000002F -:10F1E000000000000000000000000000000000001F -:10F1F000000000000000000000000000000000000F -:10F2000000000000000000000000000000000000FE -:10F2100000000000000000000000000000000000EE -:10F2200000000000000000000000000000000000DE -:10F2300000000000000000000000000000000000CE -:10F2400000000000000000000000000000000000BE -:10F2500000000000000000000000000000000000AE -:10F26000000000000000000000000000000000009E -:10F27000000000000000000000000000000000008E -:10F28000000000000000000000000000000000007E -:10F29000000000000000000000000000000000006E -:10F2A000000000000000000000000000000000005E -:10F2B000000000000000000000000000000000004E -:10F2C000000000000000000000000000000000003E -:10F2D000000000000000000000000000000000002E -:10F2E000000000000000000000000000000000001E -:10F2F000000000000000000000000000000000000E -:10F3000000000000000000000000000000000000FD -:10F3100000000000000000000000000000000000ED -:10F3200000000000000000000000000000000000DD -:10F3300000000000000000000000000000000000CD -:10F3400000000000000000000000000000000000BD -:10F3500000000000000000000000000000000000AD -:10F36000000000000000000000000000000000009D -:10F37000000000000000000000000000000000008D -:10F38000000000000000000000000000000000007D -:10F39000000000000000000000000000000000006D -:10F3A000000000000000000000000000000000005D -:10F3B000000000000000000000000000000000004D -:10F3C000000000000000000000000000000000003D -:10F3D000000000000000000000000000000000002D -:10F3E000000000000000000000000000000000001D -:10F3F000000000000000000000000000000000000D -:10F4000000000000000000000000000000000000FC -:10F4100000000000000000000000000000000000EC -:10F4200000000000000000000000000000000000DC -:10F4300000000000000000000000000000000000CC -:10F4400000000000000000000000000000000000BC -:10F4500000000000000000000000000000000000AC -:10F46000000000000000000000000000000000009C -:10F47000000000000000000000000000000000008C -:10F48000000000000000000000000000000000007C -:10F49000000000000000000000000000000000006C -:10F4A000000000000000000000000000000000005C -:10F4B000000000000000000000000000000000004C -:10F4C000000000000000000000000000000000003C -:10F4D000000000000000000000000000000000002C -:10F4E000000000000000000000000000000000001C -:10F4F000000000000000000000000000000000000C -:10F5000000000000000000000000000000000000FB -:10F5100000000000000000000000000000000000EB -:10F5200000000000000000000000000000000000DB -:10F5300000000000000000000000000000000000CB -:10F5400000000000000000000000000000000000BB -:10F5500000000000000000000000000000000000AB -:10F56000000000000000000000000000000000009B -:10F57000000000000000000000000000000000008B -:10F58000000000000000000000000000000000007B -:10F59000000000000000000000000000000000006B -:10F5A000000000000000000000000000000000005B -:10F5B000000000000000000000000000000000004B -:10F5C000000000000000000000000000000000003B -:10F5D000000000000000000000000000000000002B -:10F5E000000000000000000000000000000000001B -:10F5F000000000000000000000000000000000000B -:10F6000000000000000000000000000000000000FA -:10F6100000000000000000000000000000000000EA -:10F6200000000000000000000000000000000000DA -:10F6300000000000000000000000000000000000CA -:10F6400000000000000000000000000000000000BA -:10F6500000000000000000000000000000000000AA -:10F66000000000000000000000000000000000009A -:10F67000000000000000000000000000000000008A -:10F68000000000000000000000000000000000007A -:10F69000000000000000000000000000000000006A -:10F6A000000000000000000000000000000000005A -:10F6B000000000000000000000000000000000004A -:10F6C000000000000000000000000000000000003A -:10F6D000000000000000000000000000000000002A -:10F6E000000000000000000000000000000000001A -:10F6F000000000000000000000000000000000000A -:10F7000000000000000000000000000000000000F9 -:10F7100000000000000000000000000000000000E9 -:10F7200000000000000000000000000000000000D9 -:10F7300000000000000000000000000000000000C9 -:10F7400000000000000000000000000000000000B9 -:10F7500000000000000000000000000000000000A9 -:10F760000000000000000000000000000000000099 -:10F770000000000000000000000000000000000089 -:10F780000000000000000000000000000000000079 -:10F790000000000000000000000000000000000069 -:10F7A0000000000000000000000000000000000059 -:10F7B0000000000000000000000000000000000049 -:10F7C0000000000000000000000000000000000039 -:10F7D0000000000000000000000000000000000029 -:10F7E0000000000000000000000000000000000019 -:10F7F0000000000000000000000000000000000009 -:10F8000000000000000000000000000000000000F8 -:10F8100000000000000000000000000000000000E8 -:10F8200000000000000000000000000000000000D8 -:10F8300000000000000000000000000000000000C8 -:10F8400000000000000000000000000000000000B8 -:10F8500000000000000000000000000000000000A8 -:10F860000000000000000000000000000000000098 -:10F870000000000000000000000000000000000088 -:10F880000000000000000000000000000000000078 -:10F890000000000000000000000000000000000068 -:10F8A0000000000000000000000000000000000058 -:10F8B0000000000000000000000000000000000048 -:10F8C0000000000000000000000000000000000038 -:10F8D0000000000000000000000000000000000028 -:10F8E0000000000000000000000000000000000018 -:10F8F0000000000000000000000000000000000008 -:10F9000000000000000000000000000000000000F7 -:10F9100000000000000000000000000000000000E7 -:10F9200000000000000000000000000000000000D7 -:10F9300000000000000000000000000000000000C7 -:10F9400000000000000000000000000000000000B7 -:10F9500000000000000000000000000000000000A7 -:10F960000000000000000000000000000000000097 -:10F970000000000000000000000000000000000087 -:10F980000000000000000000000000000000000077 -:10F990000000000000000000000000000000000067 -:10F9A0000000000000000000000000000000000057 -:10F9B0000000000000000000000000000000000047 -:10F9C0000000000000000000000000000000000037 -:10F9D0000000000000000000000000000000000027 -:10F9E0000000000000000000000000000000000017 -:10F9F0000000000000000000000000000000000007 -:10FA000000000000000000000000000000000000F6 -:10FA100000000000000000000000000000000000E6 -:10FA200000000000000000000000000000000000D6 -:10FA300000000000000000000000000000000000C6 -:10FA400000000000000000000000000000000000B6 -:10FA500000000000000000000000000000000000A6 -:10FA60000000000000000000000000000000000096 -:10FA70000000000000000000000000000000000086 -:10FA80000000000000000000000000000000000076 -:10FA90000000000000000000000000000000000066 -:10FAA0000000000000000000000000000000000056 -:10FAB0000000000000000000000000000000000046 -:10FAC0000000000000000000000000000000000036 -:10FAD0000000000000000000000000000000000026 -:10FAE0000000000000000000000000000000000016 -:10FAF0000000000000000000000000000000000006 -:10FB000000000000000000000000000000000000F5 -:10FB100000000000000000000000000000000000E5 -:10FB200000000000000000000000000000000000D5 -:10FB300000000000000000000000000000000000C5 -:10FB400000000000000000000000000000000000B5 -:10FB500000000000000000000000000000000000A5 -:10FB60000000000000000000000000000000000095 -:10FB70000000000000000000000000000000000085 -:10FB80000000000000000000000000000000000075 -:10FB90000000000000000000000000000000000065 -:10FBA0000000000000000000000000000000000055 -:10FBB0000000000000000000000000000000000045 -:10FBC0000000000000000000000000000000000035 -:10FBD0000000000000000000000000000000000025 -:10FBE0000000000000000000000000000000000015 -:10FBF0000000000000000000000000000000000005 -:10FC000000000000000000000000000000000000F4 -:10FC100000000000000000000000000000000000E4 -:10FC200000000000000000000000000000000000D4 -:10FC300000000000000000000000000000000000C4 -:10FC400000000000000000000000000000000000B4 -:10FC500000000000000000000000000000000000A4 -:10FC60000000000000000000000000000000000094 -:10FC70000000000000000000000000000000000084 -:10FC80000000000000000000000000000000000074 -:10FC90000000000000000000000000000000000064 -:10FCA0000000000000000000000000000000000054 -:10FCB0000000000000000000000000000000000044 -:10FCC0000000000000000000000000000000000034 -:10FCD0000000000000000000000000000000000024 -:10FCE0000000000000000000000000000000000014 -:10FCF0000000000000000000000000000000000004 -:10FD000000000000000000000000000000000000F3 -:10FD100000000000000000000000000000000000E3 -:10FD200000000000000000000000000000000000D3 -:10FD300000000000000000000000000000000000C3 -:10FD400000000000000000000000000000000000B3 -:10FD500000000000000000000000000000000000A3 -:10FD60000000000000000000000000000000000093 -:10FD70000000000000000000000000000000000083 -:10FD80000000000000000000000000000000000073 -:10FD90000000000000000000000000000000000063 -:10FDA0000000000000000000000000000000000053 -:10FDB0000000000000000000000000000000000043 -:10FDC0000000000000000000000000000000000033 -:10FDD0000000000000000000000000000000000023 -:10FDE0000000000000000000000000000000000013 -:10FDF0000000000000000000000000000000000003 -:10FE000000000000000000000000000000000000F2 -:10FE100000000000000000000000000000000000E2 -:10FE200000000000000000000000000000000000D2 -:10FE300000000000000000000000000000000000C2 -:10FE400000000000000000000000000000000000B2 -:10FE500000000000000000000000000000000000A2 -:10FE60000000000000000000000000000000000092 -:10FE70000000000000000000000000000000000082 -:10FE80000000000000000000000000000000000072 -:10FE90000000000000000000000000000000000062 -:10FEA0000000000000000000000000000000000052 -:10FEB0000000000000000000000000000000000042 -:10FEC0000000000000000000000000000000000032 -:10FED0000000000000000000000000000000000022 -:10FEE0000000000000000000000000000000000012 -:10FEF0000000000000000000000000000000000002 -:10FF000000000000000000000000000000000000F1 -:10FF100000000000000000000000000000000000E1 -:10FF200000000000000000000000000000000000D1 -:10FF300000000000000000000000000000000000C1 -:10FF400000000000000000000000000000000000B1 -:10FF500000000000000000000000000000000000A1 -:10FF60000000000000000000000000000000000091 -:10FF70000000000000000000000000000000000081 -:10FF80000000000000000000000000000000000071 -:10FF90000000000000000000000000000000000061 -:10FFA0000000000000000000000000000000000051 -:10FFB0000000000000000000000000000000000041 -:10FFC0000000000000000000000000000000000031 -:10FFD0000000000000000000000000000000000021 -:10FFE0000000000000000000000000000000000011 -:10FFF0000000000000000000000000000000000001 -:02000004620593 -:1000000000000000000000000000000000000000F0 -:1000100000000000000000000000000000000000E0 -:1000200000000000000000000000000000000000D0 -:1000300000000000000000000000000000000000C0 -:1000400000000000000000000000000000000000B0 -:1000500000000000000000000000000000000000A0 -:100060000000000000000000000000000000000090 -:100070000000000000000000000000000000000080 -:100080000000000000000000000000000000000070 -:100090000000000000000000000000000000000060 -:1000A0000000000000000000000000000000000050 -:1000B0000000000000000000000000000000000040 -:1000C0000000000000000000000000000000000030 -:1000D0000000000000000000000000000000000020 -:1000E0000000000000000000000000000000000010 -:1000F0000000000000000000000000000000000000 -:1001000000000000000000000000000000000000EF -:1001100000000000000000000000000000000000DF -:1001200000000000000000000000000000000000CF -:1001300000000000000000000000000000000000BF -:1001400000000000000000000000000000000000AF -:10015000000000000000000000000000000000009F -:10016000000000000000000000000000000000008F -:10017000000000000000000000000000000000007F -:10018000000000000000000000000000000000006F -:10019000000000000000000000000000000000005F -:1001A000000000000000000000000000000000004F -:1001B000000000000000000000000000000000003F -:1001C000000000000000000000000000000000002F -:1001D000000000000000000000000000000000001F -:1001E000000000000000000000000000000000000F -:1001F00000000000000000000000000000000000FF -:1002000000000000000000000000000000000000EE -:1002100000000000000000000000000000000000DE -:1002200000000000000000000000000000000000CE -:1002300000000000000000000000000000000000BE -:1002400000000000000000000000000000000000AE -:10025000000000000000000000000000000000009E -:10026000000000000000000000000000000000008E -:10027000000000000000000000000000000000007E -:10028000000000000000000000000000000000006E -:10029000000000000000000000000000000000005E -:1002A000000000000000000000000000000000004E -:1002B000000000000000000000000000000000003E -:1002C000000000000000000000000000000000002E -:1002D000000000000000000000000000000000001E -:1002E000000000000000000000000000000000000E -:1002F00000000000000000000000000000000000FE -:1003000000000000000000000000000000000000ED -:1003100000000000000000000000000000000000DD -:1003200000000000000000000000000000000000CD -:1003300000000000000000000000000000000000BD -:1003400000000000000000000000000000000000AD -:10035000000000000000000000000000000000009D -:10036000000000000000000000000000000000008D -:10037000000000000000000000000000000000007D -:10038000000000000000000000000000000000006D -:10039000000000000000000000000000000000005D -:1003A000000000000000000000000000000000004D -:1003B000000000000000000000000000000000003D -:1003C000000000000000000000000000000000002D -:1003D000000000000000000000000000000000001D -:1003E000000000000000000000000000000000000D -:1003F00000000000000000000000000000000000FD -:1004000000000000000000000000000000000000EC -:1004100000000000000000000000000000000000DC -:1004200000000000000000000000000000000000CC -:1004300000000000000000000000000000000000BC -:1004400000000000000000000000000000000000AC -:10045000000000000000000000000000000000009C -:10046000000000000000000000000000000000008C -:10047000000000000000000000000000000000007C -:10048000000000000000000000000000000000006C -:10049000000000000000000000000000000000005C -:1004A000000000000000000000000000000000004C -:1004B000000000000000000000000000000000003C -:1004C000000000000000000000000000000000002C -:1004D000000000000000000000000000000000001C -:1004E000000000000000000000000000000000000C -:1004F00000000000000000000000000000000000FC -:1005000000000000000000000000000000000000EB -:1005100000000000000000000000000000000000DB -:1005200000000000000000000000000000000000CB -:1005300000000000000000000000000000000000BB -:1005400000000000000000000000000000000000AB -:10055000000000000000000000000000000000009B -:10056000000000000000000000000000000000008B -:10057000000000000000000000000000000000007B -:10058000000000000000000000000000000000006B -:10059000000000000000000000000000000000005B -:1005A000000000000000000000000000000000004B -:1005B000000000000000000000000000000000003B -:1005C000000000000000000000000000000000002B -:1005D000000000000000000000000000000000001B -:1005E000000000000000000000000000000000000B -:1005F00000000000000000000000000000000000FB -:1006000000000000000000000000000000000000EA -:1006100000000000000000000000000000000000DA -:1006200000000000000000000000000000000000CA -:1006300000000000000000000000000000000000BA -:1006400000000000000000000000000000000000AA -:10065000000000000000000000000000000000009A -:10066000000000000000000000000000000000008A -:10067000000000000000000000000000000000007A -:10068000000000000000000000000000000000006A -:10069000000000000000000000000000000000005A -:1006A000000000000000000000000000000000004A -:1006B000000000000000000000000000000000003A -:1006C000000000000000000000000000000000002A -:1006D000000000000000000000000000000000001A -:1006E000000000000000000000000000000000000A -:1006F00000000000000000000000000000000000FA -:1007000000000000000000000000000000000000E9 -:1007100000000000000000000000000000000000D9 -:1007200000000000000000000000000000000000C9 -:1007300000000000000000000000000000000000B9 -:1007400000000000000000000000000000000000A9 -:100750000000000000000000000000000000000099 -:100760000000000000000000000000000000000089 -:100770000000000000000000000000000000000079 -:100780000000000000000000000000000000000069 -:100790000000000000000000000000000000000059 -:1007A0000000000000000000000000000000000049 -:1007B0000000000000000000000000000000000039 -:1007C0000000000000000000000000000000000029 -:1007D0000000000000000000000000000000000019 -:1007E0000000000000000000000000000000000009 -:1007F00000000000000000000000000000000000F9 -:1008000000000000000000000000000000000000E8 -:1008100000000000000000000000000000000000D8 -:1008200000000000000000000000000000000000C8 -:1008300000000000000000000000000000000000B8 -:1008400000000000000000000000000000000000A8 -:100850000000000000000000000000000000000098 -:100860000000000000000000000000000000000088 -:100870000000000000000000000000000000000078 -:100880000000000000000000000000000000000068 -:100890000000000000000000000000000000000058 -:1008A0000000000000000000000000000000000048 -:1008B0000000000000000000000000000000000038 -:1008C0000000000000000000000000000000000028 -:1008D0000000000000000000000000000000000018 -:1008E0000000000000000000000000000000000008 -:1008F00000000000000000000000000000000000F8 -:1009000000000000000000000000000000000000E7 -:1009100000000000000000000000000000000000D7 -:1009200000000000000000000000000000000000C7 -:1009300000000000000000000000000000000000B7 -:1009400000000000000000000000000000000000A7 -:100950000000000000000000000000000000000097 -:100960000000000000000000000000000000000087 -:100970000000000000000000000000000000000077 -:100980000000000000000000000000000000000067 -:100990000000000000000000000000000000000057 -:1009A0000000000000000000000000000000000047 -:1009B0000000000000000000000000000000000037 -:1009C0000000000000000000000000000000000027 -:1009D0000000000000000000000000000000000017 -:1009E0000000000000000000000000000000000007 -:1009F00000000000000000000000000000000000F7 -:100A000000000000000000000000000000000000E6 -:100A100000000000000000000000000000000000D6 -:100A200000000000000000000000000000000000C6 -:100A300000000000000000000000000000000000B6 -:100A400000000000000000000000000000000000A6 -:100A50000000000000000000000000000000000096 -:100A60000000000000000000000000000000000086 -:100A70000000000000000000000000000000000076 -:100A80000000000000000000000000000000000066 -:100A90000000000000000000000000000000000056 -:100AA0000000000000000000000000000000000046 -:100AB0000000000000000000000000000000000036 -:100AC0000000000000000000000000000000000026 -:100AD0000000000000000000000000000000000016 -:100AE0000000000000000000000000000000000006 -:100AF00000000000000000000000000000000000F6 -:100B000000000000000000000000000000000000E5 -:100B100000000000000000000000000000000000D5 -:100B200000000000000000000000000000000000C5 -:100B300000000000000000000000000000000000B5 -:100B400000000000000000000000000000000000A5 -:100B50000000000000000000000000000000000095 -:100B60000000000000000000000000000000000085 -:100B70000000000000000000000000000000000075 -:100B80000000000000000000000000000000000065 -:100B90000000000000000000000000000000000055 -:100BA0000000000000000000000000000000000045 -:100BB0000000000000000000000000000000000035 -:100BC0000000000000000000000000000000000025 -:100BD0000000000000000000000000000000000015 -:100BE0000000000000000000000000000000000005 -:100BF00000000000000000000000000000000000F5 -:100C000000000000000000000000000000000000E4 -:100C100000000000000000000000000000000000D4 -:100C200000000000000000000000000000000000C4 -:100C300000000000000000000000000000000000B4 -:100C400000000000000000000000000000000000A4 -:100C50000000000000000000000000000000000094 -:100C60000000000000000000000000000000000084 -:100C70000000000000000000000000000000000074 -:100C80000000000000000000000000000000000064 -:100C90000000000000000000000000000000000054 -:100CA0000000000000000000000000000000000044 -:100CB0000000000000000000000000000000000034 -:100CC0000000000000000000000000000000000024 -:100CD0000000000000000000000000000000000014 -:100CE0000000000000000000000000000000000004 -:100CF00000000000000000000000000000000000F4 -:100D000000000000000000000000000000000000E3 -:100D100000000000000000000000000000000000D3 -:100D200000000000000000000000000000000000C3 -:100D300000000000000000000000000000000000B3 -:100D400000000000000000000000000000000000A3 -:100D50000000000000000000000000000000000093 -:100D60000000000000000000000000000000000083 -:100D70000000000000000000000000000000000073 -:100D80000000000000000000000000000000000063 -:100D90000000000000000000000000000000000053 -:100DA0000000000000000000000000000000000043 -:100DB0000000000000000000000000000000000033 -:100DC0000000000000000000000000000000000023 -:100DD0000000000000000000000000000000000013 -:100DE0000000000000000000000000000000000003 -:100DF00000000000000000000000000000000000F3 -:100E000000000000000000000000000000000000E2 -:100E100000000000000000000000000000000000D2 -:100E200000000000000000000000000000000000C2 -:100E300000000000000000000000000000000000B2 -:100E400000000000000000000000000000000000A2 -:100E50000000000000000000000000000000000092 -:100E60000000000000000000000000000000000082 -:100E70000000000000000000000000000000000072 -:100E80000000000000000000000000000000000062 -:100E90000000000000000000000000000000000052 -:100EA0000000000000000000000000000000000042 -:100EB0000000000000000000000000000000000032 -:100EC0000000000000000000000000000000000022 -:100ED0000000000000000000000000000000000012 -:100EE0000000000000000000000000000000000002 -:100EF00000000000000000000000000000000000F2 -:100F000000000000000000000000000000000000E1 -:100F100000000000000000000000000000000000D1 -:100F200000000000000000000000000000000000C1 -:100F300000000000000000000000000000000000B1 -:100F400000000000000000000000000000000000A1 -:100F50000000000000000000000000000000000091 -:100F60000000000000000000000000000000000081 -:100F70000000000000000000000000000000000071 -:100F80000000000000000000000000000000000061 -:100F90000000000000000000000000000000000051 -:100FA0000000000000000000000000000000000041 -:100FB0000000000000000000000000000000000031 -:100FC0000000000000000000000000000000000021 -:100FD0000000000000000000000000000000000011 -:100FE0000000000000000000000000000000000001 -:100FF00000000000000000000000000000000000F1 -:1010000000000000000000000000000000000000E0 -:1010100000000000000000000000000000000000D0 -:1010200000000000000000000000000000000000C0 -:1010300000000000000000000000000000000000B0 -:1010400000000000000000000000000000000000A0 -:101050000000000000000000000000000000000090 -:101060000000000000000000000000000000000080 -:101070000000000000000000000000000000000070 -:101080000000000000000000000000000000000060 -:101090000000000000000000000000000000000050 -:1010A0000000000000000000000000000000000040 -:1010B0000000000000000000000000000000000030 -:1010C0000000000000000000000000000000000020 -:1010D0000000000000000000000000000000000010 -:1010E0000000000000000000000000000000000000 -:1010F00000000000000000000000000000000000F0 -:1011000000000000000000000000000000000000DF -:1011100000000000000000000000000000000000CF -:1011200000000000000000000000000000000000BF -:1011300000000000000000000000000000000000AF -:10114000000000000000000000000000000000009F -:10115000000000000000000000000000000000008F -:10116000000000000000000000000000000000007F -:10117000000000000000000000000000000000006F -:10118000000000000000000000000000000000005F -:10119000000000000000000000000000000000004F -:1011A000000000000000000000000000000000003F -:1011B000000000000000000000000000000000002F -:1011C000000000000000000000000000000000001F -:1011D000000000000000000000000000000000000F -:1011E00000000000000000000000000000000000FF -:1011F00000000000000000000000000000000000EF -:1012000000000000000000000000000000000000DE -:1012100000000000000000000000000000000000CE -:1012200000000000000000000000000000000000BE -:1012300000000000000000000000000000000000AE -:10124000000000000000000000000000000000009E -:10125000000000000000000000000000000000008E -:10126000000000000000000000000000000000007E -:10127000000000000000000000000000000000006E -:10128000000000000000000000000000000000005E -:10129000000000000000000000000000000000004E -:1012A000000000000000000000000000000000003E -:1012B000000000000000000000000000000000002E -:1012C000000000000000000000000000000000001E -:1012D000000000000000000000000000000000000E -:1012E00000000000000000000000000000000000FE -:1012F00000000000000000000000000000000000EE -:1013000000000000000000000000000000000000DD -:1013100000000000000000000000000000000000CD -:1013200000000000000000000000000000000000BD -:1013300000000000000000000000000000000000AD -:10134000000000000000000000000000000000009D -:10135000000000000000000000000000000000008D -:10136000000000000000000000000000000000007D -:10137000000000000000000000000000000000006D -:10138000000000000000000000000000000000005D -:10139000000000000000000000000000000000004D -:1013A000000000000000000000000000000000003D -:1013B000000000000000000000000000000000002D -:1013C000000000000000000000000000000000001D -:1013D000000000000000000000000000000000000D -:1013E00000000000000000000000000000000000FD -:1013F00000000000000000000000000000000000ED -:1014000000000000000000000000000000000000DC -:1014100000000000000000000000000000000000CC -:1014200000000000000000000000000000000000BC -:1014300000000000000000000000000000000000AC -:10144000000000000000000000000000000000009C -:10145000000000000000000000000000000000008C -:10146000000000000000000000000000000000007C -:10147000000000000000000000000000000000006C -:10148000000000000000000000000000000000005C -:10149000000000000000000000000000000000004C -:1014A000000000000000000000000000000000003C -:1014B000000000000000000000000000000000002C -:1014C000000000000000000000000000000000001C -:1014D000000000000000000000000000000000000C -:1014E00000000000000000000000000000000000FC -:1014F00000000000000000000000000000000000EC -:1015000000000000000000000000000000000000DB -:1015100000000000000000000000000000000000CB -:1015200000000000000000000000000000000000BB -:1015300000000000000000000000000000000000AB -:10154000000000000000000000000000000000009B -:10155000000000000000000000000000000000008B -:10156000000000000000000000000000000000007B -:10157000000000000000000000000000000000006B -:10158000000000000000000000000000000000005B -:10159000000000000000000000000000000000004B -:1015A000000000000000000000000000000000003B -:1015B000000000000000000000000000000000002B -:1015C000000000000000000000000000000000001B -:1015D000000000000000000000000000000000000B -:1015E00000000000000000000000000000000000FB -:1015F00000000000000000000000000000000000EB -:1016000000000000000000000000000000000000DA -:1016100000000000000000000000000000000000CA -:1016200000000000000000000000000000000000BA -:1016300000000000000000000000000000000000AA -:10164000000000000000000000000000000000009A -:10165000000000000000000000000000000000008A -:10166000000000000000000000000000000000007A -:10167000000000000000000000000000000000006A -:10168000000000000000000000000000000000005A -:10169000000000000000000000000000000000004A -:1016A000000000000000000000000000000000003A -:1016B000000000000000000000000000000000002A -:1016C000000000000000000000000000000000001A -:1016D000000000000000000000000000000000000A -:1016E00000000000000000000000000000000000FA -:1016F00000000000000000000000000000000000EA -:1017000000000000000000000000000000000000D9 -:1017100000000000000000000000000000000000C9 -:1017200000000000000000000000000000000000B9 -:1017300000000000000000000000000000000000A9 -:101740000000000000000000000000000000000099 -:101750000000000000000000000000000000000089 -:101760000000000000000000000000000000000079 -:101770000000000000000000000000000000000069 -:101780000000000000000000000000000000000059 -:101790000000000000000000000000000000000049 -:1017A0000000000000000000000000000000000039 -:1017B0000000000000000000000000000000000029 -:1017C0000000000000000000000000000000000019 -:1017D0000000000000000000000000000000000009 -:1017E00000000000000000000000000000000000F9 -:1017F00000000000000000000000000000000000E9 -:1018000000000000000000000000000000000000D8 -:1018100000000000000000000000000000000000C8 -:1018200000000000000000000000000000000000B8 -:1018300000000000000000000000000000000000A8 -:101840000000000000000000000000000000000098 -:101850000000000000000000000000000000000088 -:101860000000000000000000000000000000000078 -:101870000000000000000000000000000000000068 -:101880000000000000000000000000000000000058 -:101890000000000000000000000000000000000048 -:1018A0000000000000000000000000000000000038 -:1018B0000000000000000000000000000000000028 -:1018C0000000000000000000000000000000000018 -:1018D0000000000000000000000000000000000008 -:1018E00000000000000000000000000000000000F8 -:1018F00000000000000000000000000000000000E8 -:1019000000000000000000000000000000000000D7 -:1019100000000000000000000000000000000000C7 -:1019200000000000000000000000000000000000B7 -:1019300000000000000000000000000000000000A7 -:101940000000000000000000000000000000000097 -:101950000000000000000000000000000000000087 -:101960000000000000000000000000000000000077 -:101970000000000000000000000000000000000067 -:101980000000000000000000000000000000000057 -:101990000000000000000000000000000000000047 -:1019A0000000000000000000000000000000000037 -:1019B0000000000000000000000000000000000027 -:1019C0000000000000000000000000000000000017 -:1019D0000000000000000000000000000000000007 -:1019E00000000000000000000000000000000000F7 -:1019F00000000000000000000000000000000000E7 -:101A000000000000000000000000000000000000D6 -:101A100000000000000000000000000000000000C6 -:101A200000000000000000000000000000000000B6 -:101A300000000000000000000000000000000000A6 -:101A40000000000000000000000000000000000096 -:101A50000000000000000000000000000000000086 -:101A60000000000000000000000000000000000076 -:101A70000000000000000000000000000000000066 -:101A80000000000000000000000000000000000056 -:101A90000000000000000000000000000000000046 -:101AA0000000000000000000000000000000000036 -:101AB0000000000000000000000000000000000026 -:101AC0000000000000000000000000000000000016 -:101AD0000000000000000000000000000000000006 -:101AE00000000000000000000000000000000000F6 -:101AF00000000000000000000000000000000000E6 -:101B000000000000000000000000000000000000D5 -:101B100000000000000000000000000000000000C5 -:101B200000000000000000000000000000000000B5 -:101B300000000000000000000000000000000000A5 -:101B40000000000000000000000000000000000095 -:101B50000000000000000000000000000000000085 -:101B60000000000000000000000000000000000075 -:101B70000000000000000000000000000000000065 -:101B80000000000000000000000000000000000055 -:101B90000000000000000000000000000000000045 -:101BA0000000000000000000000000000000000035 -:101BB0000000000000000000000000000000000025 -:101BC0000000000000000000000000000000000015 -:101BD0000000000000000000000000000000000005 -:101BE00000000000000000000000000000000000F5 -:101BF00000000000000000000000000000000000E5 -:101C000000000000000000000000000000000000D4 -:101C100000000000000000000000000000000000C4 -:101C200000000000000000000000000000000000B4 -:101C300000000000000000000000000000000000A4 -:101C40000000000000000000000000000000000094 -:101C50000000000000000000000000000000000084 -:101C60000000000000000000000000000000000074 -:101C70000000000000000000000000000000000064 -:101C80000000000000000000000000000000000054 -:101C90000000000000000000000000000000000044 -:101CA0000000000000000000000000000000000034 -:101CB0000000000000000000000000000000000024 -:101CC0000000000000000000000000000000000014 -:101CD0000000000000000000000000000000000004 -:101CE00000000000000000000000000000000000F4 -:101CF00000000000000000000000000000000000E4 -:101D000000000000000000000000000000000000D3 -:101D100000000000000000000000000000000000C3 -:101D200000000000000000000000000000000000B3 -:101D300000000000000000000000000000000000A3 -:101D40000000000000000000000000000000000093 -:101D50000000000000000000000000000000000083 -:101D60000000000000000000000000000000000073 -:101D70000000000000000000000000000000000063 -:101D80000000000000000000000000000000000053 -:101D90000000000000000000000000000000000043 -:101DA0000000000000000000000000000000000033 -:101DB0000000000000000000000000000000000023 -:101DC0000000000000000000000000000000000013 -:101DD0000000000000000000000000000000000003 -:101DE00000000000000000000000000000000000F3 -:101DF00000000000000000000000000000000000E3 -:101E000000000000000000000000000000000000D2 -:101E100000000000000000000000000000000000C2 -:101E200000000000000000000000000000000000B2 -:101E300000000000000000000000000000000000A2 -:101E40000000000000000000000000000000000092 -:101E50000000000000000000000000000000000082 -:101E60000000000000000000000000000000000072 -:101E70000000000000000000000000000000000062 -:101E80000000000000000000000000000000000052 -:101E90000000000000000000000000000000000042 -:101EA0000000000000000000000000000000000032 -:101EB0000000000000000000000000000000000022 -:101EC0000000000000000000000000000000000012 -:101ED0000000000000000000000000000000000002 -:101EE00000000000000000000000000000000000F2 -:101EF00000000000000000000000000000000000E2 -:101F000000000000000000000000000000000000D1 -:101F100000000000000000000000000000000000C1 -:101F200000000000000000000000000000000000B1 -:101F300000000000000000000000000000000000A1 -:101F40000000000000000000000000000000000091 -:101F50000000000000000000000000000000000081 -:101F60000000000000000000000000000000000071 -:101F70000000000000000000000000000000000061 -:101F80000000000000000000000000000000000051 -:101F90000000000000000000000000000000000041 -:101FA0000000000000000000000000000000000031 -:101FB0000000000000000000000000000000000021 -:101FC0000000000000000000000000000000000011 -:101FD0000000000000000000000000000000000001 -:101FE00000000000000000000000000000000000F1 -:101FF00000000000000000000000000000000000E1 -:1020000000000000000000000000000000000000D0 -:1020100000000000000000000000000000000000C0 -:1020200000000000000000000000000000000000B0 -:1020300000000000000000000000000000000000A0 -:102040000000000000000000000000000000000090 -:102050000000000000000000000000000000000080 -:102060000000000000000000000000000000000070 -:102070000000000000000000000000000000000060 -:102080000000000000000000000000000000000050 -:102090000000000000000000000000000000000040 -:1020A0000000000000000000000000000000000030 -:1020B0000000000000000000000000000000000020 -:1020C0000000000000000000000000000000000010 -:1020D0000000000000000000000000000000000000 -:1020E00000000000000000000000000000000000F0 -:1020F00000000000000000000000000000000000E0 -:1021000000000000000000000000000000000000CF -:1021100000000000000000000000000000000000BF -:1021200000000000000000000000000000000000AF -:10213000000000000000000000000000000000009F -:10214000000000000000000000000000000000008F -:10215000000000000000000000000000000000007F -:10216000000000000000000000000000000000006F -:10217000000000000000000000000000000000005F -:10218000000000000000000000000000000000004F -:10219000000000000000000000000000000000003F -:1021A000000000000000000000000000000000002F -:1021B000000000000000000000000000000000001F -:1021C000000000000000000000000000000000000F -:1021D00000000000000000000000000000000000FF -:1021E00000000000000000000000000000000000EF -:1021F00000000000000000000000000000000000DF -:1022000000000000000000000000000000000000CE -:1022100000000000000000000000000000000000BE -:1022200000000000000000000000000000000000AE -:10223000000000000000000000000000000000009E -:10224000000000000000000000000000000000008E -:10225000000000000000000000000000000000007E -:10226000000000000000000000000000000000006E -:10227000000000000000000000000000000000005E -:10228000000000000000000000000000000000004E -:10229000000000000000000000000000000000003E -:1022A000000000000000000000000000000000002E -:1022B000000000000000000000000000000000001E -:1022C000000000000000000000000000000000000E -:1022D00000000000000000000000000000000000FE -:1022E00000000000000000000000000000000000EE -:1022F00000000000000000000000000000000000DE -:1023000000000000000000000000000000000000CD -:1023100000000000000000000000000000000000BD -:1023200000000000000000000000000000000000AD -:10233000000000000000000000000000000000009D -:10234000000000000000000000000000000000008D -:10235000000000000000000000000000000000007D -:10236000000000000000000000000000000000006D -:10237000000000000000000000000000000000005D -:10238000000000000000000000000000000000004D -:10239000000000000000000000000000000000003D -:1023A000000000000000000000000000000000002D -:1023B000000000000000000000000000000000001D -:1023C000000000000000000000000000000000000D -:1023D00000000000000000000000000000000000FD -:1023E00000000000000000000000000000000000ED -:1023F00000000000000000000000000000000000DD -:1024000000000000000000000000000000000000CC -:1024100000000000000000000000000000000000BC -:1024200000000000000000000000000000000000AC -:10243000000000000000000000000000000000009C -:10244000000000000000000000000000000000008C -:10245000000000000000000000000000000000007C -:10246000000000000000000000000000000000006C -:10247000000000000000000000000000000000005C -:10248000000000000000000000000000000000004C -:10249000000000000000000000000000000000003C -:1024A000000000000000000000000000000000002C -:1024B000000000000000000000000000000000001C -:1024C000000000000000000000000000000000000C -:1024D00000000000000000000000000000000000FC -:1024E00000000000000000000000000000000000EC -:1024F00000000000000000000000000000000000DC -:1025000000000000000000000000000000000000CB -:1025100000000000000000000000000000000000BB -:1025200000000000000000000000000000000000AB -:10253000000000000000000000000000000000009B -:10254000000000000000000000000000000000008B -:10255000000000000000000000000000000000007B -:10256000000000000000000000000000000000006B -:10257000000000000000000000000000000000005B -:10258000000000000000000000000000000000004B -:10259000000000000000000000000000000000003B -:1025A000000000000000000000000000000000002B -:1025B000000000000000000000000000000000001B -:1025C000000000000000000000000000000000000B -:1025D00000000000000000000000000000000000FB -:1025E00000000000000000000000000000000000EB -:1025F00000000000000000000000000000000000DB -:1026000000000000000000000000000000000000CA -:1026100000000000000000000000000000000000BA -:1026200000000000000000000000000000000000AA -:10263000000000000000000000000000000000009A -:10264000000000000000000000000000000000008A -:10265000000000000000000000000000000000007A -:10266000000000000000000000000000000000006A -:10267000000000000000000000000000000000005A -:10268000000000000000000000000000000000004A -:10269000000000000000000000000000000000003A -:1026A000000000000000000000000000000000002A -:1026B000000000000000000000000000000000001A -:1026C000000000000000000000000000000000000A -:1026D00000000000000000000000000000000000FA -:1026E00000000000000000000000000000000000EA -:1026F00000000000000000000000000000000000DA -:1027000000000000000000000000000000000000C9 -:1027100000000000000000000000000000000000B9 -:1027200000000000000000000000000000000000A9 -:102730000000000000000000000000000000000099 -:102740000000000000000000000000000000000089 -:102750000000000000000000000000000000000079 -:102760000000000000000000000000000000000069 -:102770000000000000000000000000000000000059 -:102780000000000000000000000000000000000049 -:102790000000000000000000000000000000000039 -:1027A0000000000000000000000000000000000029 -:1027B0000000000000000000000000000000000019 -:1027C0000000000000000000000000000000000009 -:1027D00000000000000000000000000000000000F9 -:1027E00000000000000000000000000000000000E9 -:1027F00000000000000000000000000000000000D9 -:1028000000000000000000000000000000000000C8 -:1028100000000000000000000000000000000000B8 -:1028200000000000000000000000000000000000A8 -:102830000000000000000000000000000000000098 -:102840000000000000000000000000000000000088 -:102850000000000000000000000000000000000078 -:102860000000000000000000000000000000000068 -:102870000000000000000000000000000000000058 -:102880000000000000000000000000000000000048 -:102890000000000000000000000000000000000038 -:1028A0000000000000000000000000000000000028 -:1028B0000000000000000000000000000000000018 -:1028C0000000000000000000000000000000000008 -:1028D00000000000000000000000000000000000F8 -:1028E00000000000000000000000000000000000E8 -:1028F00000000000000000000000000000000000D8 -:1029000000000000000000000000000000000000C7 -:1029100000000000000000000000000000000000B7 -:1029200000000000000000000000000000000000A7 -:102930000000000000000000000000000000000097 -:102940000000000000000000000000000000000087 -:102950000000000000000000000000000000000077 -:102960000000000000000000000000000000000067 -:102970000000000000000000000000000000000057 -:102980000000000000000000000000000000000047 -:102990000000000000000000000000000000000037 -:1029A0000000000000000000000000000000000027 -:1029B0000000000000000000000000000000000017 -:1029C0000000000000000000000000000000000007 -:1029D00000000000000000000000000000000000F7 -:1029E00000000000000000000000000000000000E7 -:1029F00000000000000000000000000000000000D7 -:102A000000000000000000000000000000000000C6 -:102A100000000000000000000000000000000000B6 -:102A200000000000000000000000000000000000A6 -:102A30000000000000000000000000000000000096 -:102A40000000000000000000000000000000000086 -:102A50000000000000000000000000000000000076 -:102A60000000000000000000000000000000000066 -:102A70000000000000000000000000000000000056 -:102A80000000000000000000000000000000000046 -:102A90000000000000000000000000000000000036 -:102AA0000000000000000000000000000000000026 -:102AB0000000000000000000000000000000000016 -:102AC0000000000000000000000000000000000006 -:102AD00000000000000000000000000000000000F6 -:102AE00000000000000000000000000000000000E6 -:102AF00000000000000000000000000000000000D6 -:102B000000000000000000000000000000000000C5 -:102B100000000000000000000000000000000000B5 -:102B200000000000000000000000000000000000A5 -:102B30000000000000000000000000000000000095 -:102B40000000000000000000000000000000000085 -:102B50000000000000000000000000000000000075 -:102B60000000000000000000000000000000000065 -:102B70000000000000000000000000000000000055 -:102B80000000000000000000000000000000000045 -:102B90000000000000000000000000000000000035 -:102BA0000000000000000000000000000000000025 -:102BB0000000000000000000000000000000000015 -:102BC0000000000000000000000000000000000005 -:102BD00000000000000000000000000000000000F5 -:102BE00000000000000000000000000000000000E5 -:102BF00000000000000000000000000000000000D5 -:102C000000000000000000000000000000000000C4 -:102C100000000000000000000000000000000000B4 -:102C200000000000000000000000000000000000A4 -:102C30000000000000000000000000000000000094 -:102C40000000000000000000000000000000000084 -:102C50000000000000000000000000000000000074 -:102C60000000000000000000000000000000000064 -:102C70000000000000000000000000000000000054 -:102C80000000000000000000000000000000000044 -:102C90000000000000000000000000000000000034 -:102CA0000000000000000000000000000000000024 -:102CB0000000000000000000000000000000000014 -:102CC0000000000000000000000000000000000004 -:102CD00000000000000000000000000000000000F4 -:102CE00000000000000000000000000000000000E4 -:102CF00000000000000000000000000000000000D4 -:102D000000000000000000000000000000000000C3 -:102D100000000000000000000000000000000000B3 -:102D200000000000000000000000000000000000A3 -:102D30000000000000000000000000000000000093 -:102D40000000000000000000000000000000000083 -:102D50000000000000000000000000000000000073 -:102D60000000000000000000000000000000000063 -:102D70000000000000000000000000000000000053 -:102D80000000000000000000000000000000000043 -:102D90000000000000000000000000000000000033 -:102DA0000000000000000000000000000000000023 -:102DB0000000000000000000000000000000000013 -:102DC0000000000000000000000000000000000003 -:102DD00000000000000000000000000000000000F3 -:102DE00000000000000000000000000000000000E3 -:102DF00000000000000000000000000000000000D3 -:102E000000000000000000000000000000000000C2 -:102E100000000000000000000000000000000000B2 -:102E200000000000000000000000000000000000A2 -:102E30000000000000000000000000000000000092 -:102E40000000000000000000000000000000000082 -:102E50000000000000000000000000000000000072 -:102E60000000000000000000000000000000000062 -:102E70000000000000000000000000000000000052 -:102E80000000000000000000000000000000000042 -:102E90000000000000000000000000000000000032 -:102EA0000000000000000000000000000000000022 -:102EB0000000000000000000000000000000000012 -:102EC0000000000000000000000000000000000002 -:102ED00000000000000000000000000000000000F2 -:102EE00000000000000000000000000000000000E2 -:102EF00000000000000000000000000000000000D2 -:102F000000000000000000000000000000000000C1 -:102F100000000000000000000000000000000000B1 -:102F200000000000000000000000000000000000A1 -:102F30000000000000000000000000000000000091 -:102F40000000000000000000000000000000000081 -:102F50000000000000000000000000000000000071 -:102F60000000000000000000000000000000000061 -:102F70000000000000000000000000000000000051 -:102F80000000000000000000000000000000000041 -:102F90000000000000000000000000000000000031 -:102FA0000000000000000000000000000000000021 -:102FB0000000000000000000000000000000000011 -:102FC0000000000000000000000000000000000001 -:102FD00000000000000000000000000000000000F1 -:102FE00000000000000000000000000000000000E1 -:102FF00000000000000000000000000000000000D1 -:1030000000000000000000000000000000000000C0 -:1030100000000000000000000000000000000000B0 -:1030200000000000000000000000000000000000A0 -:103030000000000000000000000000000000000090 -:103040000000000000000000000000000000000080 -:103050000000000000000000000000000000000070 -:103060000000000000000000000000000000000060 -:103070000000000000000000000000000000000050 -:103080000000000000000000000000000000000040 -:103090000000000000000000000000000000000030 -:1030A0000000000000000000000000000000000020 -:1030B0000000000000000000000000000000000010 -:1030C0000000000000000000000000000000000000 -:1030D00000000000000000000000000000000000F0 -:1030E00000000000000000000000000000000000E0 -:1030F00000000000000000000000000000000000D0 -:1031000000000000000000000000000000000000BF -:1031100000000000000000000000000000000000AF -:10312000000000000000000000000000000000009F -:10313000000000000000000000000000000000008F -:10314000000000000000000000000000000000007F -:10315000000000000000000000000000000000006F -:10316000000000000000000000000000000000005F -:10317000000000000000000000000000000000004F -:10318000000000000000000000000000000000003F -:10319000000000000000000000000000000000002F -:1031A000000000000000000000000000000000001F -:1031B000000000000000000000000000000000000F -:1031C00000000000000000000000000000000000FF -:1031D00000000000000000000000000000000000EF -:1031E00000000000000000000000000000000000DF -:1031F00000000000000000000000000000000000CF -:1032000000000000000000000000000000000000BE -:1032100000000000000000000000000000000000AE -:10322000000000000000000000000000000000009E -:10323000000000000000000000000000000000008E -:10324000000000000000000000000000000000007E -:10325000000000000000000000000000000000006E -:10326000000000000000000000000000000000005E -:10327000000000000000000000000000000000004E -:10328000000000000000000000000000000000003E -:10329000000000000000000000000000000000002E -:1032A000000000000000000000000000000000001E -:1032B000000000000000000000000000000000000E -:1032C00000000000000000000000000000000000FE -:1032D00000000000000000000000000000000000EE -:1032E00000000000000000000000000000000000DE -:1032F00000000000000000000000000000000000CE -:1033000000000000000000000000000000000000BD -:1033100000000000000000000000000000000000AD -:10332000000000000000000000000000000000009D -:10333000000000000000000000000000000000008D -:10334000000000000000000000000000000000007D -:10335000000000000000000000000000000000006D -:10336000000000000000000000000000000000005D -:10337000000000000000000000000000000000004D -:10338000000000000000000000000000000000003D -:10339000000000000000000000000000000000002D -:1033A000000000000000000000000000000000001D -:1033B000000000000000000000000000000000000D -:1033C00000000000000000000000000000000000FD -:1033D00000000000000000000000000000000000ED -:1033E00000000000000000000000000000000000DD -:1033F00000000000000000000000000000000000CD -:1034000000000000000000000000000000000000BC -:1034100000000000000000000000000000000000AC -:10342000000000000000000000000000000000009C -:10343000000000000000000000000000000000008C -:10344000000000000000000000000000000000007C -:10345000000000000000000000000000000000006C -:10346000000000000000000000000000000000005C -:10347000000000000000000000000000000000004C -:10348000000000000000000000000000000000003C -:10349000000000000000000000000000000000002C -:1034A000000000000000000000000000000000001C -:1034B000000000000000000000000000000000000C -:1034C00000000000000000000000000000000000FC -:1034D00000000000000000000000000000000000EC -:1034E00000000000000000000000000000000000DC -:1034F00000000000000000000000000000000000CC -:1035000000000000000000000000000000000000BB -:1035100000000000000000000000000000000000AB -:10352000000000000000000000000000000000009B -:10353000000000000000000000000000000000008B -:10354000000000000000000000000000000000007B -:10355000000000000000000000000000000000006B -:10356000000000000000000000000000000000005B -:10357000000000000000000000000000000000004B -:10358000000000000000000000000000000000003B -:10359000000000000000000000000000000000002B -:1035A000000000000000000000000000000000001B -:1035B000000000000000000000000000000000000B -:1035C00000000000000000000000000000000000FB -:1035D00000000000000000000000000000000000EB -:1035E00000000000000000000000000000000000DB -:1035F00000000000000000000000000000000000CB -:1036000000000000000000000000000000000000BA -:1036100000000000000000000000000000000000AA -:10362000000000000000000000000000000000009A -:10363000000000000000000000000000000000008A -:10364000000000000000000000000000000000007A -:10365000000000000000000000000000000000006A -:10366000000000000000000000000000000000005A -:10367000000000000000000000000000000000004A -:10368000000000000000000000000000000000003A -:10369000000000000000000000000000000000002A -:1036A000000000000000000000000000000000001A -:1036B000000000000000000000000000000000000A -:1036C00000000000000000000000000000000000FA -:1036D00000000000000000000000000000000000EA -:1036E00000000000000000000000000000000000DA -:1036F00000000000000000000000000000000000CA -:1037000000000000000000000000000000000000B9 -:1037100000000000000000000000000000000000A9 -:103720000000000000000000000000000000000099 -:103730000000000000000000000000000000000089 -:103740000000000000000000000000000000000079 -:103750000000000000000000000000000000000069 -:103760000000000000000000000000000000000059 -:103770000000000000000000000000000000000049 -:103780000000000000000000000000000000000039 -:103790000000000000000000000000000000000029 -:1037A0000000000000000000000000000000000019 -:1037B0000000000000000000000000000000000009 -:1037C00000000000000000000000000000000000F9 -:1037D00000000000000000000000000000000000E9 -:1037E00000000000000000000000000000000000D9 -:1037F00000000000000000000000000000000000C9 -:1038000000000000000000000000000000000000B8 -:1038100000000000000000000000000000000000A8 -:103820000000000000000000000000000000000098 -:103830000000000000000000000000000000000088 -:103840000000000000000000000000000000000078 -:103850000000000000000000000000000000000068 -:103860000000000000000000000000000000000058 -:103870000000000000000000000000000000000048 -:103880000000000000000000000000000000000038 -:103890000000000000000000000000000000000028 -:1038A0000000000000000000000000000000000018 -:1038B0000000000000000000000000000000000008 -:1038C00000000000000000000000000000000000F8 -:1038D00000000000000000000000000000000000E8 -:1038E00000000000000000000000000000000000D8 -:1038F00000000000000000000000000000000000C8 -:1039000000000000000000000000000000000000B7 -:1039100000000000000000000000000000000000A7 -:103920000000000000000000000000000000000097 -:103930000000000000000000000000000000000087 -:103940000000000000000000000000000000000077 -:103950000000000000000000000000000000000067 -:103960000000000000000000000000000000000057 -:103970000000000000000000000000000000000047 -:103980000000000000000000000000000000000037 -:103990000000000000000000000000000000000027 -:1039A0000000000000000000000000000000000017 -:1039B0000000000000000000000000000000000007 -:1039C00000000000000000000000000000000000F7 -:1039D00000000000000000000000000000000000E7 -:1039E00000000000000000000000000000000000D7 -:1039F00000000000000000000000000000000000C7 -:103A000000000000000000000000000000000000B6 -:103A100000000000000000000000000000000000A6 -:103A20000000000000000000000000000000000096 -:103A30000000000000000000000000000000000086 -:103A40000000000000000000000000000000000076 -:103A50000000000000000000000000000000000066 -:103A60000000000000000000000000000000000056 -:103A70000000000000000000000000000000000046 -:103A80000000000000000000000000000000000036 -:103A90000000000000000000000000000000000026 -:103AA0000000000000000000000000000000000016 -:103AB0000000000000000000000000000000000006 -:103AC00000000000000000000000000000000000F6 -:103AD00000000000000000000000000000000000E6 -:103AE00000000000000000000000000000000000D6 -:103AF00000000000000000000000000000000000C6 -:103B000000000000000000000000000000000000B5 -:103B100000000000000000000000000000000000A5 -:103B20000000000000000000000000000000000095 -:103B30000000000000000000000000000000000085 -:103B40000000000000000000000000000000000075 -:103B50000000000000000000000000000000000065 -:103B60000000000000000000000000000000000055 -:103B70000000000000000000000000000000000045 -:103B80000000000000000000000000000000000035 -:103B90000000000000000000000000000000000025 -:103BA0000000000000000000000000000000000015 -:103BB0000000000000000000000000000000000005 -:103BC00000000000000000000000000000000000F5 -:103BD00000000000000000000000000000000000E5 -:103BE00000000000000000000000000000000000D5 -:103BF00000000000000000000000000000000000C5 -:103C000000000000000000000000000000000000B4 -:103C100000000000000000000000000000000000A4 -:103C20000000000000000000000000000000000094 -:103C30000000000000000000000000000000000084 -:103C40000000000000000000000000000000000074 -:103C50000000000000000000000000000000000064 -:103C60000000000000000000000000000000000054 -:103C70000000000000000000000000000000000044 -:103C80000000000000000000000000000000000034 -:103C90000000000000000000000000000000000024 -:103CA0000000000000000000000000000000000014 -:103CB0000000000000000000000000000000000004 -:103CC00000000000000000000000000000000000F4 -:103CD00000000000000000000000000000000000E4 -:103CE00000000000000000000000000000000000D4 -:103CF00000000000000000000000000000000000C4 -:103D000000000000000000000000000000000000B3 -:103D100000000000000000000000000000000000A3 -:103D20000000000000000000000000000000000093 -:103D30000000000000000000000000000000000083 -:103D40000000000000000000000000000000000073 -:103D50000000000000000000000000000000000063 -:103D60000000000000000000000000000000000053 -:103D70000000000000000000000000000000000043 -:103D80000000000000000000000000000000000033 -:103D90000000000000000000000000000000000023 -:103DA0000000000000000000000000000000000013 -:103DB0000000000000000000000000000000000003 -:103DC00000000000000000000000000000000000F3 -:103DD00000000000000000000000000000000000E3 -:103DE00000000000000000000000000000000000D3 -:103DF00000000000000000000000000000000000C3 -:103E000000000000000000000000000000000000B2 -:103E100000000000000000000000000000000000A2 -:103E20000000000000000000000000000000000092 -:103E30000000000000000000000000000000000082 -:103E40000000000000000000000000000000000072 -:103E50000000000000000000000000000000000062 -:103E60000000000000000000000000000000000052 -:103E70000000000000000000000000000000000042 -:103E80000000000000000000000000000000000032 -:103E90000000000000000000000000000000000022 -:103EA0000000000000000000000000000000000012 -:103EB0000000000000000000000000000000000002 -:103EC00000000000000000000000000000000000F2 -:103ED00000000000000000000000000000000000E2 -:103EE00000000000000000000000000000000000D2 -:103EF00000000000000000000000000000000000C2 -:103F000000000000000000000000000000000000B1 -:103F100000000000000000000000000000000000A1 -:103F20000000000000000000000000000000000091 -:103F30000000000000000000000000000000000081 -:103F40000000000000000000000000000000000071 -:103F50000000000000000000000000000000000061 -:103F60000000000000000000000000000000000051 -:103F70000000000000000000000000000000000041 -:103F80000000000000000000000000000000000031 -:103F90000000000000000000000000000000000021 -:103FA0000000000000000000000000000000000011 -:103FB0000000000000000000000000000000000001 -:103FC00000000000000000000000000000000000F1 -:103FD00000000000000000000000000000000000E1 -:103FE00000000000000000000000000000000000D1 -:103FF00000000000000000000000000000000000C1 -:1040000000000000000000000000000000000000B0 -:1040100000000000000000000000000000000000A0 -:104020000000000000000000000000000000000090 -:104030000000000000000000000000000000000080 -:104040000000000000000000000000000000000070 -:104050000000000000000000000000000000000060 -:104060000000000000000000000000000000000050 -:104070000000000000000000000000000000000040 -:104080000000000000000000000000000000000030 -:104090000000000000000000000000000000000020 -:1040A0000000000000000000000000000000000010 -:1040B0000000000000000000000000000000000000 -:1040C00000000000000000000000000000000000F0 -:1040D00000000000000000000000000000000000E0 -:1040E00000000000000000000000000000000000D0 -:1040F00000000000000000000000000000000000C0 -:1041000000000000000000000000000000000000AF -:10411000000000000000000000000000000000009F -:10412000000000000000000000000000000000008F -:10413000000000000000000000000000000000007F -:10414000000000000000000000000000000000006F -:10415000000000000000000000000000000000005F -:10416000000000000000000000000000000000004F -:10417000000000000000000000000000000000003F -:10418000000000000000000000000000000000002F -:10419000000000000000000000000000000000001F -:1041A000000000000000000000000000000000000F -:1041B00000000000000000000000000000000000FF -:1041C00000000000000000000000000000000000EF -:1041D00000000000000000000000000000000000DF -:1041E00000000000000000000000000000000000CF -:1041F00000000000000000000000000000000000BF -:1042000000000000000000000000000000000000AE -:10421000000000000000000000000000000000009E -:10422000000000000000000000000000000000008E -:10423000000000000000000000000000000000007E -:10424000000000000000000000000000000000006E -:10425000000000000000000000000000000000005E -:10426000000000000000000000000000000000004E -:10427000000000000000000000000000000000003E -:10428000000000000000000000000000000000002E -:10429000000000000000000000000000000000001E -:1042A000000000000000000000000000000000000E -:1042B00000000000000000000000000000000000FE -:1042C00000000000000000000000000000000000EE -:1042D00000000000000000000000000000000000DE -:1042E00000000000000000000000000000000000CE -:1042F00000000000000000000000000000000000BE -:1043000000000000000000000000000000000000AD -:10431000000000000000000000000000000000009D -:10432000000000000000000000000000000000008D -:10433000000000000000000000000000000000007D -:10434000000000000000000000000000000000006D -:10435000000000000000000000000000000000005D -:10436000000000000000000000000000000000004D -:10437000000000000000000000000000000000003D -:10438000000000000000000000000000000000002D -:10439000000000000000000000000000000000001D -:1043A000000000000000000000000000000000000D -:1043B00000000000000000000000000000000000FD -:1043C00000000000000000000000000000000000ED -:1043D00000000000000000000000000000000000DD -:1043E00000000000000000000000000000000000CD -:1043F00000000000000000000000000000000000BD -:1044000000000000000000000000000000000000AC -:10441000000000000000000000000000000000009C -:10442000000000000000000000000000000000008C -:10443000000000000000000000000000000000007C -:10444000000000000000000000000000000000006C -:10445000000000000000000000000000000000005C -:10446000000000000000000000000000000000004C -:10447000000000000000000000000000000000003C -:10448000000000000000000000000000000000002C -:10449000000000000000000000000000000000001C -:1044A000000000000000000000000000000000000C -:1044B00000000000000000000000000000000000FC -:1044C00000000000000000000000000000000000EC -:1044D00000000000000000000000000000000000DC -:1044E00000000000000000000000000000000000CC -:1044F00000000000000000000000000000000000BC -:1045000000000000000000000000000000000000AB -:10451000000000000000000000000000000000009B -:10452000000000000000000000000000000000008B -:10453000000000000000000000000000000000007B -:10454000000000000000000000000000000000006B -:10455000000000000000000000000000000000005B -:10456000000000000000000000000000000000004B -:10457000000000000000000000000000000000003B -:10458000000000000000000000000000000000002B -:10459000000000000000000000000000000000001B -:1045A000000000000000000000000000000000000B -:1045B00000000000000000000000000000000000FB -:1045C00000000000000000000000000000000000EB -:1045D00000000000000000000000000000000000DB -:1045E00000000000000000000000000000000000CB -:1045F00000000000000000000000000000000000BB -:1046000000000000000000000000000000000000AA -:10461000000000000000000000000000000000009A -:10462000000000000000000000000000000000008A -:10463000000000000000000000000000000000007A -:10464000000000000000000000000000000000006A -:10465000000000000000000000000000000000005A -:10466000000000000000000000000000000000004A -:10467000000000000000000000000000000000003A -:10468000000000000000000000000000000000002A -:10469000000000000000000000000000000000001A -:1046A000000000000000000000000000000000000A -:1046B00000000000000000000000000000000000FA -:1046C00000000000000000000000000000000000EA -:1046D00000000000000000000000000000000000DA -:1046E00000000000000000000000000000000000CA -:1046F00000000000000000000000000000000000BA -:1047000000000000000000000000000000000000A9 -:104710000000000000000000000000000000000099 -:104720000000000000000000000000000000000089 -:104730000000000000000000000000000000000079 -:104740000000000000000000000000000000000069 -:104750000000000000000000000000000000000059 -:104760000000000000000000000000000000000049 -:104770000000000000000000000000000000000039 -:104780000000000000000000000000000000000029 -:104790000000000000000000000000000000000019 -:1047A0000000000000000000000000000000000009 -:1047B00000000000000000000000000000000000F9 -:1047C00000000000000000000000000000000000E9 -:1047D00000000000000000000000000000000000D9 -:1047E00000000000000000000000000000000000C9 -:1047F00000000000000000000000000000000000B9 -:1048000000000000000000000000000000000000A8 -:104810000000000000000000000000000000000098 -:104820000000000000000000000000000000000088 -:104830000000000000000000000000000000000078 -:104840000000000000000000000000000000000068 -:104850000000000000000000000000000000000058 -:104860000000000000000000000000000000000048 -:104870000000000000000000000000000000000038 -:104880000000000000000000000000000000000028 -:104890000000000000000000000000000000000018 -:1048A0000000000000000000000000000000000008 -:1048B00000000000000000000000000000000000F8 -:1048C00000000000000000000000000000000000E8 -:1048D00000000000000000000000000000000000D8 -:1048E00000000000000000000000000000000000C8 -:1048F00000000000000000000000000000000000B8 -:1049000000000000000000000000000000000000A7 -:104910000000000000000000000000000000000097 -:104920000000000000000000000000000000000087 -:104930000000000000000000000000000000000077 -:104940000000000000000000000000000000000067 -:104950000000000000000000000000000000000057 -:104960000000000000000000000000000000000047 -:104970000000000000000000000000000000000037 -:104980000000000000000000000000000000000027 -:104990000000000000000000000000000000000017 -:1049A0000000000000000000000000000000000007 -:1049B00000000000000000000000000000000000F7 -:1049C00000000000000000000000000000000000E7 -:1049D00000000000000000000000000000000000D7 -:1049E00000000000000000000000000000000000C7 -:1049F00000000000000000000000000000000000B7 -:104A000000000000000000000000000000000000A6 -:104A10000000000000000000000000000000000096 -:104A20000000000000000000000000000000000086 -:104A30000000000000000000000000000000000076 -:104A40000000000000000000000000000000000066 -:104A50000000000000000000000000000000000056 -:104A60000000000000000000000000000000000046 -:104A70000000000000000000000000000000000036 -:104A80000000000000000000000000000000000026 -:104A90000000000000000000000000000000000016 -:104AA0000000000000000000000000000000000006 -:104AB00000000000000000000000000000000000F6 -:104AC00000000000000000000000000000000000E6 -:104AD00000000000000000000000000000000000D6 -:104AE00000000000000000000000000000000000C6 -:104AF00000000000000000000000000000000000B6 -:104B000000000000000000000000000000000000A5 -:104B10000000000000000000000000000000000095 -:104B20000000000000000000000000000000000085 -:104B30000000000000000000000000000000000075 -:104B40000000000000000000000000000000000065 -:104B50000000000000000000000000000000000055 -:104B60000000000000000000000000000000000045 -:104B70000000000000000000000000000000000035 -:104B80000000000000000000000000000000000025 -:104B90000000000000000000000000000000000015 -:104BA0000000000000000000000000000000000005 -:104BB00000000000000000000000000000000000F5 -:104BC00000000000000000000000000000000000E5 -:104BD00000000000000000000000000000000000D5 -:104BE00000000000000000000000000000000000C5 -:104BF00000000000000000000000000000000000B5 -:104C000000000000000000000000000000000000A4 -:104C10000000000000000000000000000000000094 -:104C20000000000000000000000000000000000084 -:104C30000000000000000000000000000000000074 -:104C40000000000000000000000000000000000064 -:104C50000000000000000000000000000000000054 -:104C60000000000000000000000000000000000044 -:104C70000000000000000000000000000000000034 -:104C80000000000000000000000000000000000024 -:104C90000000000000000000000000000000000014 -:104CA0000000000000000000000000000000000004 -:104CB00000000000000000000000000000000000F4 -:104CC00000000000000000000000000000000000E4 -:104CD00000000000000000000000000000000000D4 -:104CE00000000000000000000000000000000000C4 -:104CF00000000000000000000000000000000000B4 -:104D000000000000000000000000000000000000A3 -:104D10000000000000000000000000000000000093 -:104D20000000000000000000000000000000000083 -:104D30000000000000000000000000000000000073 -:104D40000000000000000000000000000000000063 -:104D50000000000000000000000000000000000053 -:104D60000000000000000000000000000000000043 -:104D70000000000000000000000000000000000033 -:104D80000000000000000000000000000000000023 -:104D90000000000000000000000000000000000013 -:104DA0000000000000000000000000000000000003 -:104DB00000000000000000000000000000000000F3 -:104DC00000000000000000000000000000000000E3 -:104DD00000000000000000000000000000000000D3 -:104DE00000000000000000000000000000000000C3 -:104DF00000000000000000000000000000000000B3 -:104E000000000000000000000000000000000000A2 -:104E10000000000000000000000000000000000092 -:104E20000000000000000000000000000000000082 -:104E30000000000000000000000000000000000072 -:104E40000000000000000000000000000000000062 -:104E50000000000000000000000000000000000052 -:104E60000000000000000000000000000000000042 -:104E70000000000000000000000000000000000032 -:104E80000000000000000000000000000000000022 -:104E90000000000000000000000000000000000012 -:104EA0000000000000000000000000000000000002 -:104EB00000000000000000000000000000000000F2 -:104EC00000000000000000000000000000000000E2 -:104ED00000000000000000000000000000000000D2 -:104EE00000000000000000000000000000000000C2 -:104EF00000000000000000000000000000000000B2 -:104F000000000000000000000000000000000000A1 -:104F10000000000000000000000000000000000091 -:104F20000000000000000000000000000000000081 -:104F30000000000000000000000000000000000071 -:104F40000000000000000000000000000000000061 -:104F50000000000000000000000000000000000051 -:104F60000000000000000000000000000000000041 -:104F70000000000000000000000000000000000031 -:104F80000000000000000000000000000000000021 -:104F90000000000000000000000000000000000011 -:104FA0000000000000000000000000000000000001 -:104FB00000000000000000000000000000000000F1 -:104FC00000000000000000000000000000000000E1 -:104FD00000000000000000000000000000000000D1 -:104FE00000000000000000000000000000000000C1 -:104FF00000000000000000000000000000000000B1 -:1050000000000000000000000000000000000000A0 -:105010000000000000000000000000000000000090 -:105020000000000000000000000000000000000080 -:105030000000000000000000000000000000000070 -:105040000000000000000000000000000000000060 -:105050000000000000000000000000000000000050 -:105060000000000000000000000000000000000040 -:105070000000000000000000000000000000000030 -:105080000000000000000000000000000000000020 -:105090000000000000000000000000000000000010 -:1050A0000000000000000000000000000000000000 -:1050B00000000000000000000000000000000000F0 -:1050C00000000000000000000000000000000000E0 -:1050D00000000000000000000000000000000000D0 -:1050E00000000000000000000000000000000000C0 -:1050F00000000000000000000000000000000000B0 -:10510000000000000000000000000000000000009F -:10511000000000000000000000000000000000008F -:10512000000000000000000000000000000000007F -:10513000000000000000000000000000000000006F -:10514000000000000000000000000000000000005F -:10515000000000000000000000000000000000004F -:10516000000000000000000000000000000000003F -:10517000000000000000000000000000000000002F -:10518000000000000000000000000000000000001F -:10519000000000000000000000000000000000000F -:1051A00000000000000000000000000000000000FF -:1051B00000000000000000000000000000000000EF -:1051C00000000000000000000000000000000000DF -:1051D00000000000000000000000000000000000CF -:1051E00000000000000000000000000000000000BF -:1051F00000000000000000000000000000000000AF -:10520000000000000000000000000000000000009E -:10521000000000000000000000000000000000008E -:10522000000000000000000000000000000000007E -:10523000000000000000000000000000000000006E -:10524000000000000000000000000000000000005E -:10525000000000000000000000000000000000004E -:10526000000000000000000000000000000000003E -:10527000000000000000000000000000000000002E -:10528000000000000000000000000000000000001E -:10529000000000000000000000000000000000000E -:1052A00000000000000000000000000000000000FE -:1052B00000000000000000000000000000000000EE -:1052C00000000000000000000000000000000000DE -:1052D00000000000000000000000000000000000CE -:1052E00000000000000000000000000000000000BE -:1052F00000000000000000000000000000000000AE -:10530000000000000000000000000000000000009D -:10531000000000000000000000000000000000008D -:10532000000000000000000000000000000000007D -:10533000000000000000000000000000000000006D -:10534000000000000000000000000000000000005D -:10535000000000000000000000000000000000004D -:10536000000000000000000000000000000000003D -:10537000000000000000000000000000000000002D -:10538000000000000000000000000000000000001D -:10539000000000000000000000000000000000000D -:1053A00000000000000000000000000000000000FD -:1053B00000000000000000000000000000000000ED -:1053C00000000000000000000000000000000000DD -:1053D00000000000000000000000000000000000CD -:1053E00000000000000000000000000000000000BD -:1053F00000000000000000000000000000000000AD -:10540000000000000000000000000000000000009C -:10541000000000000000000000000000000000008C -:10542000000000000000000000000000000000007C -:10543000000000000000000000000000000000006C -:10544000000000000000000000000000000000005C -:10545000000000000000000000000000000000004C -:10546000000000000000000000000000000000003C -:10547000000000000000000000000000000000002C -:10548000000000000000000000000000000000001C -:10549000000000000000000000000000000000000C -:1054A00000000000000000000000000000000000FC -:1054B00000000000000000000000000000000000EC -:1054C00000000000000000000000000000000000DC -:1054D00000000000000000000000000000000000CC -:1054E00000000000000000000000000000000000BC -:1054F00000000000000000000000000000000000AC -:10550000000000000000000000000000000000009B -:10551000000000000000000000000000000000008B -:10552000000000000000000000000000000000007B -:10553000000000000000000000000000000000006B -:10554000000000000000000000000000000000005B -:10555000000000000000000000000000000000004B -:10556000000000000000000000000000000000003B -:10557000000000000000000000000000000000002B -:10558000000000000000000000000000000000001B -:10559000000000000000000000000000000000000B -:1055A00000000000000000000000000000000000FB -:1055B00000000000000000000000000000000000EB -:1055C00000000000000000000000000000000000DB -:1055D00000000000000000000000000000000000CB -:1055E00000000000000000000000000000000000BB -:1055F00000000000000000000000000000000000AB -:10560000000000000000000000000000000000009A -:10561000000000000000000000000000000000008A -:10562000000000000000000000000000000000007A -:10563000000000000000000000000000000000006A -:10564000000000000000000000000000000000005A -:10565000000000000000000000000000000000004A -:10566000000000000000000000000000000000003A -:10567000000000000000000000000000000000002A -:10568000000000000000000000000000000000001A -:10569000000000000000000000000000000000000A -:1056A00000000000000000000000000000000000FA -:1056B00000000000000000000000000000000000EA -:1056C00000000000000000000000000000000000DA -:1056D00000000000000000000000000000000000CA -:1056E00000000000000000000000000000000000BA -:1056F00000000000000000000000000000000000AA -:105700000000000000000000000000000000000099 -:105710000000000000000000000000000000000089 -:105720000000000000000000000000000000000079 -:105730000000000000000000000000000000000069 -:105740000000000000000000000000000000000059 -:105750000000000000000000000000000000000049 -:105760000000000000000000000000000000000039 -:105770000000000000000000000000000000000029 -:105780000000000000000000000000000000000019 -:105790000000000000000000000000000000000009 -:1057A00000000000000000000000000000000000F9 -:1057B00000000000000000000000000000000000E9 -:1057C00000000000000000000000000000000000D9 -:1057D00000000000000000000000000000000000C9 -:1057E00000000000000000000000000000000000B9 -:1057F00000000000000000000000000000000000A9 -:105800000000000000000000000000000000000098 -:105810000000000000000000000000000000000088 -:105820000000000000000000000000000000000078 -:105830000000000000000000000000000000000068 -:105840000000000000000000000000000000000058 -:105850000000000000000000000000000000000048 -:105860000000000000000000000000000000000038 -:105870000000000000000000000000000000000028 -:105880000000000000000000000000000000000018 -:105890000000000000000000000000000000000008 -:1058A00000000000000000000000000000000000F8 -:1058B00000000000000000000000000000000000E8 -:1058C00000000000000000000000000000000000D8 -:1058D00000000000000000000000000000000000C8 -:1058E00000000000000000000000000000000000B8 -:1058F00000000000000000000000000000000000A8 -:105900000000000000000000000000000000000097 -:105910000000000000000000000000000000000087 -:105920000000000000000000000000000000000077 -:105930000000000000000000000000000000000067 -:105940000000000000000000000000000000000057 -:105950000000000000000000000000000000000047 -:105960000000000000000000000000000000000037 -:105970000000000000000000000000000000000027 -:105980000000000000000000000000000000000017 -:105990000000000000000000000000000000000007 -:1059A00000000000000000000000000000000000F7 -:1059B00000000000000000000000000000000000E7 -:1059C00000000000000000000000000000000000D7 -:1059D00000000000000000000000000000000000C7 -:1059E00000000000000000000000000000000000B7 -:1059F00000000000000000000000000000000000A7 -:105A00000000000000000000000000000000000096 -:105A10000000000000000000000000000000000086 -:105A20000000000000000000000000000000000076 -:105A30000000000000000000000000000000000066 -:105A40000000000000000000000000000000000056 -:105A50000000000000000000000000000000000046 -:105A60000000000000000000000000000000000036 -:105A70000000000000000000000000000000000026 -:105A80000000000000000000000000000000000016 -:105A90000000000000000000000000000000000006 -:105AA00000000000000000000000000000000000F6 -:105AB00000000000000000000000000000000000E6 -:105AC00000000000000000000000000000000000D6 -:105AD00000000000000000000000000000000000C6 -:105AE00000000000000000000000000000000000B6 -:105AF00000000000000000000000000000000000A6 -:105B00000000000000000000000000000000000095 -:105B10000000000000000000000000000000000085 -:105B20000000000000000000000000000000000075 -:105B30000000000000000000000000000000000065 -:105B40000000000000000000000000000000000055 -:105B50000000000000000000000000000000000045 -:105B60000000000000000000000000000000000035 -:105B70000000000000000000000000000000000025 -:105B80000000000000000000000000000000000015 -:105B90000000000000000000000000000000000005 -:105BA00000000000000000000000000000000000F5 -:105BB00000000000000000000000000000000000E5 -:105BC00000000000000000000000000000000000D5 -:105BD00000000000000000000000000000000000C5 -:105BE00000000000000000000000000000000000B5 -:105BF00000000000000000000000000000000000A5 -:105C00000000000000000000000000000000000094 -:105C10000000000000000000000000000000000084 -:105C20000000000000000000000000000000000074 -:105C30000000000000000000000000000000000064 -:105C40000000000000000000000000000000000054 -:105C50000000000000000000000000000000000044 -:105C60000000000000000000000000000000000034 -:105C70000000000000000000000000000000000024 -:105C80000000000000000000000000000000000014 -:105C90000000000000000000000000000000000004 -:105CA00000000000000000000000000000000000F4 -:105CB00000000000000000000000000000000000E4 -:105CC00000000000000000000000000000000000D4 -:105CD00000000000000000000000000000000000C4 -:105CE00000000000000000000000000000000000B4 -:105CF00000000000000000000000000000000000A4 -:105D00000000000000000000000000000000000093 -:105D10000000000000000000000000000000000083 -:105D20000000000000000000000000000000000073 -:105D30000000000000000000000000000000000063 -:105D40000000000000000000000000000000000053 -:105D50000000000000000000000000000000000043 -:105D60000000000000000000000000000000000033 -:105D70000000000000000000000000000000000023 -:105D80000000000000000000000000000000000013 -:105D90000000000000000000000000000000000003 -:105DA00000000000000000000000000000000000F3 -:105DB00000000000000000000000000000000000E3 -:105DC00000000000000000000000000000000000D3 -:105DD00000000000000000000000000000000000C3 -:105DE00000000000000000000000000000000000B3 -:105DF00000000000000000000000000000000000A3 -:105E00000000000000000000000000000000000092 -:105E10000000000000000000000000000000000082 -:105E20000000000000000000000000000000000072 -:105E30000000000000000000000000000000000062 -:105E40000000000000000000000000000000000052 -:105E50000000000000000000000000000000000042 -:105E60000000000000000000000000000000000032 -:105E70000000000000000000000000000000000022 -:105E80000000000000000000000000000000000012 -:105E90000000000000000000000000000000000002 -:105EA00000000000000000000000000000000000F2 -:105EB00000000000000000000000000000000000E2 -:105EC00000000000000000000000000000000000D2 -:105ED00000000000000000000000000000000000C2 -:105EE00000000000000000000000000000000000B2 -:105EF00000000000000000000000000000000000A2 -:105F00000000000000000000000000000000000091 -:105F10000000000000000000000000000000000081 -:105F20000000000000000000000000000000000071 -:105F30000000000000000000000000000000000061 -:105F40000000000000000000000000000000000051 -:105F50000000000000000000000000000000000041 -:105F60000000000000000000000000000000000031 -:105F70000000000000000000000000000000000021 -:105F80000000000000000000000000000000000011 -:105F90000000000000000000000000000000000001 -:105FA00000000000000000000000000000000000F1 -:105FB00000000000000000000000000000000000E1 -:105FC00000000000000000000000000000000000D1 -:105FD00000000000000000000000000000000000C1 -:105FE00000000000000000000000000000000000B1 -:105FF00000000000000000000000000000000000A1 -:106000000000000000000000000000000000000090 -:106010000000000000000000000000000000000080 -:106020000000000000000000000000000000000070 -:106030000000000000000000000000000000000060 -:106040000000000000000000000000000000000050 -:106050000000000000000000000000000000000040 -:106060000000000000000000000000000000000030 -:106070000000000000000000000000000000000020 -:106080000000000000000000000000000000000010 -:106090000000000000000000000000000000000000 -:1060A00000000000000000000000000000000000F0 -:1060B00000000000000000000000000000000000E0 -:1060C00000000000000000000000000000000000D0 -:1060D00000000000000000000000000000000000C0 -:1060E00000000000000000000000000000000000B0 -:1060F00000000000000000000000000000000000A0 -:10610000000000000000000000000000000000008F -:10611000000000000000000000000000000000007F -:10612000000000000000000000000000000000006F -:10613000000000000000000000000000000000005F -:10614000000000000000000000000000000000004F -:10615000000000000000000000000000000000003F -:10616000000000000000000000000000000000002F -:10617000000000000000000000000000000000001F -:10618000000000000000000000000000000000000F -:1061900000000000000000000000000000000000FF -:1061A00000000000000000000000000000000000EF -:1061B00000000000000000000000000000000000DF -:1061C00000000000000000000000000000000000CF -:1061D00000000000000000000000000000000000BF -:1061E00000000000000000000000000000000000AF -:1061F000000000000000000000000000000000009F -:10620000000000000000000000000000000000008E -:10621000000000000000000000000000000000007E -:10622000000000000000000000000000000000006E -:10623000000000000000000000000000000000005E -:10624000000000000000000000000000000000004E -:10625000000000000000000000000000000000003E -:10626000000000000000000000000000000000002E -:10627000000000000000000000000000000000001E -:10628000000000000000000000000000000000000E -:1062900000000000000000000000000000000000FE -:1062A00000000000000000000000000000000000EE -:1062B00000000000000000000000000000000000DE -:1062C00000000000000000000000000000000000CE -:1062D00000000000000000000000000000000000BE -:1062E00000000000000000000000000000000000AE -:1062F000000000000000000000000000000000009E -:10630000000000000000000000000000000000008D -:10631000000000000000000000000000000000007D -:10632000000000000000000000000000000000006D -:10633000000000000000000000000000000000005D -:10634000000000000000000000000000000000004D -:10635000000000000000000000000000000000003D -:10636000000000000000000000000000000000002D -:10637000000000000000000000000000000000001D -:10638000000000000000000000000000000000000D -:1063900000000000000000000000000000000000FD -:1063A00000000000000000000000000000000000ED -:1063B00000000000000000000000000000000000DD -:1063C00000000000000000000000000000000000CD -:1063D00000000000000000000000000000000000BD -:1063E00000000000000000000000000000000000AD -:1063F000000000000000000000000000000000009D -:10640000000000000000000000000000000000008C -:10641000000000000000000000000000000000007C -:10642000000000000000000000000000000000006C -:10643000000000000000000000000000000000005C -:10644000000000000000000000000000000000004C -:10645000000000000000000000000000000000003C -:10646000000000000000000000000000000000002C -:10647000000000000000000000000000000000001C -:10648000000000000000000000000000000000000C -:1064900000000000000000000000000000000000FC -:1064A00000000000000000000000000000000000EC -:1064B00000000000000000000000000000000000DC -:1064C00000000000000000000000000000000000CC -:1064D00000000000000000000000000000000000BC -:1064E00000000000000000000000000000000000AC -:1064F000000000000000000000000000000000009C -:10650000000000000000000000000000000000008B -:10651000000000000000000000000000000000007B -:10652000000000000000000000000000000000006B -:10653000000000000000000000000000000000005B -:10654000000000000000000000000000000000004B -:10655000000000000000000000000000000000003B -:10656000000000000000000000000000000000002B -:10657000000000000000000000000000000000001B -:10658000000000000000000000000000000000000B -:1065900000000000000000000000000000000000FB -:1065A00000000000000000000000000000000000EB -:1065B00000000000000000000000000000000000DB -:1065C00000000000000000000000000000000000CB -:1065D00000000000000000000000000000000000BB -:1065E00000000000000000000000000000000000AB -:1065F000000000000000000000000000000000009B -:10660000000000000000000000000000000000008A -:10661000000000000000000000000000000000007A -:10662000000000000000000000000000000000006A -:10663000000000000000000000000000000000005A -:10664000000000000000000000000000000000004A -:10665000000000000000000000000000000000003A -:10666000000000000000000000000000000000002A -:10667000000000000000000000000000000000001A -:10668000000000000000000000000000000000000A -:1066900000000000000000000000000000000000FA -:1066A00000000000000000000000000000000000EA -:1066B00000000000000000000000000000000000DA -:1066C00000000000000000000000000000000000CA -:1066D00000000000000000000000000000000000BA -:1066E00000000000000000000000000000000000AA -:1066F000000000000000000000000000000000009A -:106700000000000000000000000000000000000089 -:106710000000000000000000000000000000000079 -:106720000000000000000000000000000000000069 -:106730000000000000000000000000000000000059 -:106740000000000000000000000000000000000049 -:106750000000000000000000000000000000000039 -:106760000000000000000000000000000000000029 -:106770000000000000000000000000000000000019 -:106780000000000000000000000000000000000009 -:1067900000000000000000000000000000000000F9 -:1067A00000000000000000000000000000000000E9 -:1067B00000000000000000000000000000000000D9 -:1067C00000000000000000000000000000000000C9 -:1067D00000000000000000000000000000000000B9 -:1067E00000000000000000000000000000000000A9 -:1067F0000000000000000000000000000000000099 -:106800000000000000000000000000000000000088 -:106810000000000000000000000000000000000078 -:106820000000000000000000000000000000000068 -:106830000000000000000000000000000000000058 -:106840000000000000000000000000000000000048 -:106850000000000000000000000000000000000038 -:106860000000000000000000000000000000000028 -:106870000000000000000000000000000000000018 -:106880000000000000000000000000000000000008 -:1068900000000000000000000000000000000000F8 -:1068A00000000000000000000000000000000000E8 -:1068B00000000000000000000000000000000000D8 -:1068C00000000000000000000000000000000000C8 -:1068D00000000000000000000000000000000000B8 -:1068E00000000000000000000000000000000000A8 -:1068F0000000000000000000000000000000000098 -:106900000000000000000000000000000000000087 -:106910000000000000000000000000000000000077 -:106920000000000000000000000000000000000067 -:106930000000000000000000000000000000000057 -:106940000000000000000000000000000000000047 -:106950000000000000000000000000000000000037 -:106960000000000000000000000000000000000027 -:106970000000000000000000000000000000000017 -:106980000000000000000000000000000000000007 -:1069900000000000000000000000000000000000F7 -:1069A00000000000000000000000000000000000E7 -:1069B00000000000000000000000000000000000D7 -:1069C00000000000000000000000000000000000C7 -:1069D00000000000000000000000000000000000B7 -:1069E00000000000000000000000000000000000A7 -:1069F0000000000000000000000000000000000097 -:106A00000000000000000000000000000000000086 -:106A10000000000000000000000000000000000076 -:106A20000000000000000000000000000000000066 -:106A30000000000000000000000000000000000056 -:106A40000000000000000000000000000000000046 -:106A50000000000000000000000000000000000036 -:106A60000000000000000000000000000000000026 -:106A70000000000000000000000000000000000016 -:106A80000000000000000000000000000000000006 -:106A900000000000000000000000000000000000F6 -:106AA00000000000000000000000000000000000E6 -:106AB00000000000000000000000000000000000D6 -:106AC00000000000000000000000000000000000C6 -:106AD00000000000000000000000000000000000B6 -:106AE00000000000000000000000000000000000A6 -:106AF0000000000000000000000000000000000096 -:106B00000000000000000000000000000000000085 -:106B10000000000000000000000000000000000075 -:106B20000000000000000000000000000000000065 -:106B30000000000000000000000000000000000055 -:106B40000000000000000000000000000000000045 -:106B50000000000000000000000000000000000035 -:106B60000000000000000000000000000000000025 -:106B70000000000000000000000000000000000015 -:106B80000000000000000000000000000000000005 -:106B900000000000000000000000000000000000F5 -:106BA00000000000000000000000000000000000E5 -:106BB00000000000000000000000000000000000D5 -:106BC00000000000000000000000000000000000C5 -:106BD00000000000000000000000000000000000B5 -:106BE00000000000000000000000000000000000A5 -:106BF0000000000000000000000000000000000095 -:106C00000000000000000000000000000000000084 -:106C10000000000000000000000000000000000074 -:106C20000000000000000000000000000000000064 -:106C30000000000000000000000000000000000054 -:106C40000000000000000000000000000000000044 -:106C50000000000000000000000000000000000034 -:106C60000000000000000000000000000000000024 -:106C70000000000000000000000000000000000014 -:106C80000000000000000000000000000000000004 -:106C900000000000000000000000000000000000F4 -:106CA00000000000000000000000000000000000E4 -:106CB00000000000000000000000000000000000D4 -:106CC00000000000000000000000000000000000C4 -:106CD00000000000000000000000000000000000B4 -:106CE00000000000000000000000000000000000A4 -:106CF0000000000000000000000000000000000094 -:106D00000000000000000000000000000000000083 -:106D10000000000000000000000000000000000073 -:106D20000000000000000000000000000000000063 -:106D30000000000000000000000000000000000053 -:106D40000000000000000000000000000000000043 -:106D50000000000000000000000000000000000033 -:106D60000000000000000000000000000000000023 -:106D70000000000000000000000000000000000013 -:106D80000000000000000000000000000000000003 -:106D900000000000000000000000000000000000F3 -:106DA00000000000000000000000000000000000E3 -:106DB00000000000000000000000000000000000D3 -:106DC00000000000000000000000000000000000C3 -:106DD00000000000000000000000000000000000B3 -:106DE00000000000000000000000000000000000A3 -:106DF0000000000000000000000000000000000093 -:106E00000000000000000000000000000000000082 -:106E10000000000000000000000000000000000072 -:106E20000000000000000000000000000000000062 -:106E30000000000000000000000000000000000052 -:106E40000000000000000000000000000000000042 -:106E50000000000000000000000000000000000032 -:106E60000000000000000000000000000000000022 -:106E70000000000000000000000000000000000012 -:106E80000000000000000000000000000000000002 -:106E900000000000000000000000000000000000F2 -:106EA00000000000000000000000000000000000E2 -:106EB00000000000000000000000000000000000D2 -:106EC00000000000000000000000000000000000C2 -:106ED00000000000000000000000000000000000B2 -:106EE00000000000000000000000000000000000A2 -:106EF0000000000000000000000000000000000092 -:106F00000000000000000000000000000000000081 -:106F10000000000000000000000000000000000071 -:106F20000000000000000000000000000000000061 -:106F30000000000000000000000000000000000051 -:106F40000000000000000000000000000000000041 -:106F50000000000000000000000000000000000031 -:106F60000000000000000000000000000000000021 -:106F70000000000000000000000000000000000011 -:106F80000000000000000000000000000000000001 -:106F900000000000000000000000000000000000F1 -:106FA00000000000000000000000000000000000E1 -:106FB00000000000000000000000000000000000D1 -:106FC00000000000000000000000000000000000C1 -:106FD00000000000000000000000000000000000B1 -:106FE00000000000000000000000000000000000A1 -:106FF0000000000000000000000000000000000091 -:107000000000000000000000000000000000000080 -:107010000000000000000000000000000000000070 -:107020000000000000000000000000000000000060 -:107030000000000000000000000000000000000050 -:107040000000000000000000000000000000000040 -:107050000000000000000000000000000000000030 -:107060000000000000000000000000000000000020 -:107070000000000000000000000000000000000010 -:107080000000000000000000000000000000000000 -:1070900000000000000000000000000000000000F0 -:1070A00000000000000000000000000000000000E0 -:1070B00000000000000000000000000000000000D0 -:1070C00000000000000000000000000000000000C0 -:1070D00000000000000000000000000000000000B0 -:1070E00000000000000000000000000000000000A0 -:1070F0000000000000000000000000000000000090 -:10710000000000000000000000000000000000007F -:10711000000000000000000000000000000000006F -:10712000000000000000000000000000000000005F -:10713000000000000000000000000000000000004F -:10714000000000000000000000000000000000003F -:10715000000000000000000000000000000000002F -:10716000000000000000000000000000000000001F -:10717000000000000000000000000000000000000F -:1071800000000000000000000000000000000000FF -:1071900000000000000000000000000000000000EF -:1071A00000000000000000000000000000000000DF -:1071B00000000000000000000000000000000000CF -:1071C00000000000000000000000000000000000BF -:1071D00000000000000000000000000000000000AF -:1071E000000000000000000000000000000000009F -:1071F000000000000000000000000000000000008F -:10720000000000000000000000000000000000007E -:10721000000000000000000000000000000000006E -:10722000000000000000000000000000000000005E -:10723000000000000000000000000000000000004E -:10724000000000000000000000000000000000003E -:10725000000000000000000000000000000000002E -:10726000000000000000000000000000000000001E -:10727000000000000000000000000000000000000E -:1072800000000000000000000000000000000000FE -:1072900000000000000000000000000000000000EE -:1072A00000000000000000000000000000000000DE -:1072B00000000000000000000000000000000000CE -:1072C00000000000000000000000000000000000BE -:1072D00000000000000000000000000000000000AE -:1072E000000000000000000000000000000000009E -:1072F000000000000000000000000000000000008E -:10730000000000000000000000000000000000007D -:10731000000000000000000000000000000000006D -:10732000000000000000000000000000000000005D -:10733000000000000000000000000000000000004D -:10734000000000000000000000000000000000003D -:10735000000000000000000000000000000000002D -:10736000000000000000000000000000000000001D -:10737000000000000000000000000000000000000D -:1073800000000000000000000000000000000000FD -:1073900000000000000000000000000000000000ED -:1073A00000000000000000000000000000000000DD -:1073B00000000000000000000000000000000000CD -:1073C00000000000000000000000000000000000BD -:1073D00000000000000000000000000000000000AD -:1073E000000000000000000000000000000000009D -:1073F000000000000000000000000000000000008D -:10740000000000000000000000000000000000007C -:10741000000000000000000000000000000000006C -:10742000000000000000000000000000000000005C -:10743000000000000000000000000000000000004C -:10744000000000000000000000000000000000003C -:10745000000000000000000000000000000000002C -:10746000000000000000000000000000000000001C -:10747000000000000000000000000000000000000C -:1074800000000000000000000000000000000000FC -:1074900000000000000000000000000000000000EC -:1074A00000000000000000000000000000000000DC -:1074B00000000000000000000000000000000000CC -:1074C00000000000000000000000000000000000BC -:1074D00000000000000000000000000000000000AC -:1074E000000000000000000000000000000000009C -:1074F000000000000000000000000000000000008C -:10750000000000000000000000000000000000007B -:10751000000000000000000000000000000000006B -:10752000000000000000000000000000000000005B -:10753000000000000000000000000000000000004B -:10754000000000000000000000000000000000003B -:10755000000000000000000000000000000000002B -:10756000000000000000000000000000000000001B -:10757000000000000000000000000000000000000B -:1075800000000000000000000000000000000000FB -:1075900000000000000000000000000000000000EB -:1075A00000000000000000000000000000000000DB -:1075B00000000000000000000000000000000000CB -:1075C00000000000000000000000000000000000BB -:1075D00000000000000000000000000000000000AB -:1075E000000000000000000000000000000000009B -:1075F000000000000000000000000000000000008B -:10760000000000000000000000000000000000007A -:10761000000000000000000000000000000000006A -:10762000000000000000000000000000000000005A -:10763000000000000000000000000000000000004A -:10764000000000000000000000000000000000003A -:10765000000000000000000000000000000000002A -:10766000000000000000000000000000000000001A -:10767000000000000000000000000000000000000A -:1076800000000000000000000000000000000000FA -:1076900000000000000000000000000000000000EA -:1076A00000000000000000000000000000000000DA -:1076B00000000000000000000000000000000000CA -:1076C00000000000000000000000000000000000BA -:1076D00000000000000000000000000000000000AA -:1076E000000000000000000000000000000000009A -:1076F000000000000000000000000000000000008A -:107700000000000000000000000000000000000079 -:107710000000000000000000000000000000000069 -:107720000000000000000000000000000000000059 -:107730000000000000000000000000000000000049 -:107740000000000000000000000000000000000039 -:107750000000000000000000000000000000000029 -:107760000000000000000000000000000000000019 -:107770000000000000000000000000000000000009 -:1077800000000000000000000000000000000000F9 -:1077900000000000000000000000000000000000E9 -:1077A00000000000000000000000000000000000D9 -:1077B00000000000000000000000000000000000C9 -:1077C00000000000000000000000000000000000B9 -:1077D00000000000000000000000000000000000A9 -:1077E0000000000000000000000000000000000099 -:1077F0000000000000000000000000000000000089 -:107800000000000000000000000000000000000078 -:107810000000000000000000000000000000000068 -:107820000000000000000000000000000000000058 -:107830000000000000000000000000000000000048 -:107840000000000000000000000000000000000038 -:107850000000000000000000000000000000000028 -:107860000000000000000000000000000000000018 -:107870000000000000000000000000000000000008 -:1078800000000000000000000000000000000000F8 -:1078900000000000000000000000000000000000E8 -:1078A00000000000000000000000000000000000D8 -:1078B00000000000000000000000000000000000C8 -:1078C00000000000000000000000000000000000B8 -:1078D00000000000000000000000000000000000A8 -:1078E0000000000000000000000000000000000098 -:1078F0000000000000000000000000000000000088 -:107900000000000000000000000000000000000077 -:107910000000000000000000000000000000000067 -:107920000000000000000000000000000000000057 -:107930000000000000000000000000000000000047 -:107940000000000000000000000000000000000037 -:107950000000000000000000000000000000000027 -:107960000000000000000000000000000000000017 -:107970000000000000000000000000000000000007 -:1079800000000000000000000000000000000000F7 -:1079900000000000000000000000000000000000E7 -:1079A00000000000000000000000000000000000D7 -:1079B00000000000000000000000000000000000C7 -:1079C00000000000000000000000000000000000B7 -:1079D00000000000000000000000000000000000A7 -:1079E0000000000000000000000000000000000097 -:1079F0000000000000000000000000000000000087 -:107A00000000000000000000000000000000000076 -:107A10000000000000000000000000000000000066 -:107A20000000000000000000000000000000000056 -:107A30000000000000000000000000000000000046 -:107A40000000000000000000000000000000000036 -:107A50000000000000000000000000000000000026 -:107A60000000000000000000000000000000000016 -:107A70000000000000000000000000000000000006 -:107A800000000000000000000000000000000000F6 -:107A900000000000000000000000000000000000E6 -:107AA00000000000000000000000000000000000D6 -:107AB00000000000000000000000000000000000C6 -:107AC00000000000000000000000000000000000B6 -:107AD00000000000000000000000000000000000A6 -:107AE0000000000000000000000000000000000096 -:107AF0000000000000000000000000000000000086 -:107B00000000000000000000000000000000000075 -:107B10000000000000000000000000000000000065 -:107B20000000000000000000000000000000000055 -:107B30000000000000000000000000000000000045 -:107B40000000000000000000000000000000000035 -:107B50000000000000000000000000000000000025 -:107B60000000000000000000000000000000000015 -:107B70000000000000000000000000000000000005 -:107B800000000000000000000000000000000000F5 -:107B900000000000000000000000000000000000E5 -:107BA00000000000000000000000000000000000D5 -:107BB00000000000000000000000000000000000C5 -:107BC00000000000000000000000000000000000B5 -:107BD00000000000000000000000000000000000A5 -:107BE0000000000000000000000000000000000095 -:107BF0000000000000000000000000000000000085 -:107C00000000000000000000000000000000000074 -:107C10000000000000000000000000000000000064 -:107C20000000000000000000000000000000000054 -:107C30000000000000000000000000000000000044 -:107C40000000000000000000000000000000000034 -:107C50000000000000000000000000000000000024 -:107C60000000000000000000000000000000000014 -:107C70000000000000000000000000000000000004 -:107C800000000000000000000000000000000000F4 -:107C900000000000000000000000000000000000E4 -:107CA00000000000000000000000000000000000D4 -:107CB00000000000000000000000000000000000C4 -:107CC00000000000000000000000000000000000B4 -:107CD00000000000000000000000000000000000A4 -:107CE0000000000000000000000000000000000094 -:107CF0000000000000000000000000000000000084 -:107D00000000000000000000000000000000000073 -:107D10000000000000000000000000000000000063 -:107D20000000000000000000000000000000000053 -:107D30000000000000000000000000000000000043 -:107D40000000000000000000000000000000000033 -:107D50000000000000000000000000000000000023 -:107D60000000000000000000000000000000000013 -:107D70000000000000000000000000000000000003 -:107D800000000000000000000000000000000000F3 -:107D900000000000000000000000000000000000E3 -:107DA00000000000000000000000000000000000D3 -:107DB00000000000000000000000000000000000C3 -:107DC00000000000000000000000000000000000B3 -:107DD00000000000000000000000000000000000A3 -:107DE0000000000000000000000000000000000093 -:107DF0000000000000000000000000000000000083 -:107E00000000000000000000000000000000000072 -:107E10000000000000000000000000000000000062 -:107E20000000000000000000000000000000000052 -:107E30000000000000000000000000000000000042 -:107E40000000000000000000000000000000000032 -:107E50000000000000000000000000000000000022 -:107E60000000000000000000000000000000000012 -:107E70000000000000000000000000000000000002 -:107E800000000000000000000000000000000000F2 -:107E900000000000000000000000000000000000E2 -:107EA00000000000000000000000000000000000D2 -:107EB00000000000000000000000000000000000C2 -:107EC00000000000000000000000000000000000B2 -:107ED00000000000000000000000000000000000A2 -:107EE0000000000000000000000000000000000092 -:107EF0000000000000000000000000000000000082 -:107F00000000000000000000000000000000000071 -:107F10000000000000000000000000000000000061 -:107F20000000000000000000000000000000000051 -:107F30000000000000000000000000000000000041 -:107F40000000000000000000000000000000000031 -:107F50000000000000000000000000000000000021 -:107F60000000000000000000000000000000000011 -:107F70000000000000000000000000000000000001 -:107F800000000000000000000000000000000000F1 -:107F900000000000000000000000000000000000E1 -:107FA00000000000000000000000000000000000D1 -:107FB00000000000000000000000000000000000C1 -:107FC00000000000000000000000000000000000B1 -:107FD00000000000000000000000000000000000A1 -:107FE0000000000000000000000000000000000091 -:107FF0000000000000000000000000000000000081 -:108000000000000000000000000000000000000070 -:108010000000000000000000000000000000000060 -:108020000000000000000000000000000000000050 -:108030000000000000000000000000000000000040 -:108040000000000000000000000000000000000030 -:108050000000000000000000000000000000000020 -:108060000000000000000000000000000000000010 -:108070000000000000000000000000000000000000 -:1080800000000000000000000000000000000000F0 -:1080900000000000000000000000000000000000E0 -:1080A00000000000000000000000000000000000D0 -:1080B00000000000000000000000000000000000C0 -:1080C00000000000000000000000000000000000B0 -:1080D00000000000000000000000000000000000A0 -:1080E0000000000000000000000000000000000090 -:1080F0000000000000000000000000000000000080 -:10810000000000000000000000000000000000006F -:10811000000000000000000000000000000000005F -:10812000000000000000000000000000000000004F -:10813000000000000000000000000000000000003F -:10814000000000000000000000000000000000002F -:10815000000000000000000000000000000000001F -:10816000000000000000000000000000000000000F -:1081700000000000000000000000000000000000FF -:1081800000000000000000000000000000000000EF -:1081900000000000000000000000000000000000DF -:1081A00000000000000000000000000000000000CF -:1081B00000000000000000000000000000000000BF -:1081C00000000000000000000000000000000000AF -:1081D000000000000000000000000000000000009F -:1081E000000000000000000000000000000000008F -:1081F000000000000000000000000000000000007F -:10820000000000000000000000000000000000006E -:10821000000000000000000000000000000000005E -:10822000000000000000000000000000000000004E -:10823000000000000000000000000000000000003E -:10824000000000000000000000000000000000002E -:10825000000000000000000000000000000000001E -:10826000000000000000000000000000000000000E -:1082700000000000000000000000000000000000FE -:1082800000000000000000000000000000000000EE -:1082900000000000000000000000000000000000DE -:1082A00000000000000000000000000000000000CE -:1082B00000000000000000000000000000000000BE -:1082C00000000000000000000000000000000000AE -:1082D000000000000000000000000000000000009E -:1082E000000000000000000000000000000000008E -:1082F000000000000000000000000000000000007E -:10830000000000000000000000000000000000006D -:10831000000000000000000000000000000000005D -:10832000000000000000000000000000000000004D -:10833000000000000000000000000000000000003D -:10834000000000000000000000000000000000002D -:10835000000000000000000000000000000000001D -:10836000000000000000000000000000000000000D -:1083700000000000000000000000000000000000FD -:1083800000000000000000000000000000000000ED -:1083900000000000000000000000000000000000DD -:1083A00000000000000000000000000000000000CD -:1083B00000000000000000000000000000000000BD -:1083C00000000000000000000000000000000000AD -:1083D000000000000000000000000000000000009D -:1083E000000000000000000000000000000000008D -:1083F000000000000000000000000000000000007D -:10840000000000000000000000000000000000006C -:10841000000000000000000000000000000000005C -:10842000000000000000000000000000000000004C -:10843000000000000000000000000000000000003C -:10844000000000000000000000000000000000002C -:10845000000000000000000000000000000000001C -:10846000000000000000000000000000000000000C -:1084700000000000000000000000000000000000FC -:1084800000000000000000000000000000000000EC -:1084900000000000000000000000000000000000DC -:1084A00000000000000000000000000000000000CC -:1084B00000000000000000000000000000000000BC -:1084C00000000000000000000000000000000000AC -:1084D000000000000000000000000000000000009C -:1084E000000000000000000000000000000000008C -:1084F000000000000000000000000000000000007C -:10850000000000000000000000000000000000006B -:10851000000000000000000000000000000000005B -:10852000000000000000000000000000000000004B -:10853000000000000000000000000000000000003B -:10854000000000000000000000000000000000002B -:10855000000000000000000000000000000000001B -:10856000000000000000000000000000000000000B -:1085700000000000000000000000000000000000FB -:1085800000000000000000000000000000000000EB -:1085900000000000000000000000000000000000DB -:1085A00000000000000000000000000000000000CB -:1085B00000000000000000000000000000000000BB -:1085C00000000000000000000000000000000000AB -:1085D000000000000000000000000000000000009B -:1085E000000000000000000000000000000000008B -:1085F000000000000000000000000000000000007B -:10860000000000000000000000000000000000006A -:10861000000000000000000000000000000000005A -:10862000000000000000000000000000000000004A -:10863000000000000000000000000000000000003A -:10864000000000000000000000000000000000002A -:10865000000000000000000000000000000000001A -:10866000000000000000000000000000000000000A -:1086700000000000000000000000000000000000FA -:1086800000000000000000000000000000000000EA -:1086900000000000000000000000000000000000DA -:1086A00000000000000000000000000000000000CA -:1086B00000000000000000000000000000000000BA -:1086C00000000000000000000000000000000000AA -:1086D000000000000000000000000000000000009A -:1086E000000000000000000000000000000000008A -:1086F000000000000000000000000000000000007A -:108700000000000000000000000000000000000069 -:108710000000000000000000000000000000000059 -:108720000000000000000000000000000000000049 -:108730000000000000000000000000000000000039 -:108740000000000000000000000000000000000029 -:108750000000000000000000000000000000000019 -:108760000000000000000000000000000000000009 -:1087700000000000000000000000000000000000F9 -:1087800000000000000000000000000000000000E9 -:1087900000000000000000000000000000000000D9 -:1087A00000000000000000000000000000000000C9 -:1087B00000000000000000000000000000000000B9 -:1087C00000000000000000000000000000000000A9 -:1087D0000000000000000000000000000000000099 -:1087E0000000000000000000000000000000000089 -:1087F0000000000000000000000000000000000079 -:108800000000000000000000000000000000000068 -:108810000000000000000000000000000000000058 -:108820000000000000000000000000000000000048 -:108830000000000000000000000000000000000038 -:108840000000000000000000000000000000000028 -:108850000000000000000000000000000000000018 -:108860000000000000000000000000000000000008 -:1088700000000000000000000000000000000000F8 -:1088800000000000000000000000000000000000E8 -:1088900000000000000000000000000000000000D8 -:1088A00000000000000000000000000000000000C8 -:1088B00000000000000000000000000000000000B8 -:1088C00000000000000000000000000000000000A8 -:1088D0000000000000000000000000000000000098 -:1088E0000000000000000000000000000000000088 -:1088F0000000000000000000000000000000000078 -:108900000000000000000000000000000000000067 -:108910000000000000000000000000000000000057 -:108920000000000000000000000000000000000047 -:108930000000000000000000000000000000000037 -:108940000000000000000000000000000000000027 -:108950000000000000000000000000000000000017 -:108960000000000000000000000000000000000007 -:1089700000000000000000000000000000000000F7 -:1089800000000000000000000000000000000000E7 -:1089900000000000000000000000000000000000D7 -:1089A00000000000000000000000000000000000C7 -:1089B00000000000000000000000000000000000B7 -:1089C00000000000000000000000000000000000A7 -:1089D0000000000000000000000000000000000097 -:1089E0000000000000000000000000000000000087 -:1089F0000000000000000000000000000000000077 -:108A00000000000000000000000000000000000066 -:108A10000000000000000000000000000000000056 -:108A20000000000000000000000000000000000046 -:108A30000000000000000000000000000000000036 -:108A40000000000000000000000000000000000026 -:108A50000000000000000000000000000000000016 -:108A60000000000000000000000000000000000006 -:108A700000000000000000000000000000000000F6 -:108A800000000000000000000000000000000000E6 -:108A900000000000000000000000000000000000D6 -:108AA00000000000000000000000000000000000C6 -:108AB00000000000000000000000000000000000B6 -:108AC00000000000000000000000000000000000A6 -:108AD0000000000000000000000000000000000096 -:108AE0000000000000000000000000000000000086 -:108AF0000000000000000000000000000000000076 -:108B00000000000000000000000000000000000065 -:108B10000000000000000000000000000000000055 -:108B20000000000000000000000000000000000045 -:108B30000000000000000000000000000000000035 -:108B40000000000000000000000000000000000025 -:108B50000000000000000000000000000000000015 -:108B60000000000000000000000000000000000005 -:108B700000000000000000000000000000000000F5 -:108B800000000000000000000000000000000000E5 -:108B900000000000000000000000000000000000D5 -:108BA00000000000000000000000000000000000C5 -:108BB00000000000000000000000000000000000B5 -:108BC00000000000000000000000000000000000A5 -:108BD0000000000000000000000000000000000095 -:108BE0000000000000000000000000000000000085 -:108BF0000000000000000000000000000000000075 -:108C00000000000000000000000000000000000064 -:108C10000000000000000000000000000000000054 -:108C20000000000000000000000000000000000044 -:108C30000000000000000000000000000000000034 -:108C40000000000000000000000000000000000024 -:108C50000000000000000000000000000000000014 -:108C60000000000000000000000000000000000004 -:108C700000000000000000000000000000000000F4 -:108C800000000000000000000000000000000000E4 -:108C900000000000000000000000000000000000D4 -:108CA00000000000000000000000000000000000C4 -:108CB00000000000000000000000000000000000B4 -:108CC00000000000000000000000000000000000A4 -:108CD0000000000000000000000000000000000094 -:108CE0000000000000000000000000000000000084 -:108CF0000000000000000000000000000000000074 -:108D00000000000000000000000000000000000063 -:108D10000000000000000000000000000000000053 -:108D20000000000000000000000000000000000043 -:108D30000000000000000000000000000000000033 -:108D40000000000000000000000000000000000023 -:108D50000000000000000000000000000000000013 -:108D60000000000000000000000000000000000003 -:108D700000000000000000000000000000000000F3 -:108D800000000000000000000000000000000000E3 -:108D900000000000000000000000000000000000D3 -:108DA00000000000000000000000000000000000C3 -:108DB00000000000000000000000000000000000B3 -:108DC00000000000000000000000000000000000A3 -:108DD0000000000000000000000000000000000093 -:108DE0000000000000000000000000000000000083 -:108DF0000000000000000000000000000000000073 -:108E00000000000000000000000000000000000062 -:108E10000000000000000000000000000000000052 -:108E20000000000000000000000000000000000042 -:108E30000000000000000000000000000000000032 -:108E40000000000000000000000000000000000022 -:108E50000000000000000000000000000000000012 -:108E60000000000000000000000000000000000002 -:108E700000000000000000000000000000000000F2 -:108E800000000000000000000000000000000000E2 -:108E900000000000000000000000000000000000D2 -:108EA00000000000000000000000000000000000C2 -:108EB00000000000000000000000000000000000B2 -:108EC00000000000000000000000000000000000A2 -:108ED0000000000000000000000000000000000092 -:108EE0000000000000000000000000000000000082 -:108EF0000000000000000000000000000000000072 -:108F00000000000000000000000000000000000061 -:108F10000000000000000000000000000000000051 -:108F20000000000000000000000000000000000041 -:108F30000000000000000000000000000000000031 -:108F40000000000000000000000000000000000021 -:108F50000000000000000000000000000000000011 -:108F60000000000000000000000000000000000001 -:108F700000000000000000000000000000000000F1 -:108F800000000000000000000000000000000000E1 -:108F900000000000000000000000000000000000D1 -:108FA00000000000000000000000000000000000C1 -:108FB00000000000000000000000000000000000B1 -:108FC00000000000000000000000000000000000A1 -:108FD0000000000000000000000000000000000091 -:108FE0000000000000000000000000000000000081 -:108FF0000000000000000000000000000000000071 -:109000000000000000000000000000000000000060 -:109010000000000000000000000000000000000050 -:109020000000000000000000000000000000000040 -:109030000000000000000000000000000000000030 -:109040000000000000000000000000000000000020 -:109050000000000000000000000000000000000010 -:109060000000000000000000000000000000000000 -:1090700000000000000000000000000000000000F0 -:1090800000000000000000000000000000000000E0 -:1090900000000000000000000000000000000000D0 -:1090A00000000000000000000000000000000000C0 -:1090B00000000000000000000000000000000000B0 -:1090C00000000000000000000000000000000000A0 -:1090D0000000000000000000000000000000000090 -:1090E0000000000000000000000000000000000080 -:1090F0000000000000000000000000000000000070 -:10910000000000000000000000000000000000005F -:10911000000000000000000000000000000000004F -:10912000000000000000000000000000000000003F -:10913000000000000000000000000000000000002F -:10914000000000000000000000000000000000001F -:10915000000000000000000000000000000000000F -:1091600000000000000000000000000000000000FF -:1091700000000000000000000000000000000000EF -:1091800000000000000000000000000000000000DF -:1091900000000000000000000000000000000000CF -:1091A00000000000000000000000000000000000BF -:1091B00000000000000000000000000000000000AF -:1091C000000000000000000000000000000000009F -:1091D000000000000000000000000000000000008F -:1091E000000000000000000000000000000000007F -:1091F000000000000000000000000000000000006F -:10920000000000000000000000000000000000005E -:10921000000000000000000000000000000000004E -:10922000000000000000000000000000000000003E -:10923000000000000000000000000000000000002E -:10924000000000000000000000000000000000001E -:10925000000000000000000000000000000000000E -:1092600000000000000000000000000000000000FE -:1092700000000000000000000000000000000000EE -:1092800000000000000000000000000000000000DE -:1092900000000000000000000000000000000000CE -:1092A00000000000000000000000000000000000BE -:1092B00000000000000000000000000000000000AE -:1092C000000000000000000000000000000000009E -:1092D000000000000000000000000000000000008E -:1092E000000000000000000000000000000000007E -:1092F000000000000000000000000000000000006E -:10930000000000000000000000000000000000005D -:10931000000000000000000000000000000000004D -:10932000000000000000000000000000000000003D -:10933000000000000000000000000000000000002D -:10934000000000000000000000000000000000001D -:10935000000000000000000000000000000000000D -:1093600000000000000000000000000000000000FD -:1093700000000000000000000000000000000000ED -:1093800000000000000000000000000000000000DD -:1093900000000000000000000000000000000000CD -:1093A00000000000000000000000000000000000BD -:1093B00000000000000000000000000000000000AD -:1093C000000000000000000000000000000000009D -:1093D000000000000000000000000000000000008D -:1093E000000000000000000000000000000000007D -:1093F000000000000000000000000000000000006D -:10940000000000000000000000000000000000005C -:10941000000000000000000000000000000000004C -:10942000000000000000000000000000000000003C -:10943000000000000000000000000000000000002C -:10944000000000000000000000000000000000001C -:10945000000000000000000000000000000000000C -:1094600000000000000000000000000000000000FC -:1094700000000000000000000000000000000000EC -:1094800000000000000000000000000000000000DC -:1094900000000000000000000000000000000000CC -:1094A00000000000000000000000000000000000BC -:1094B00000000000000000000000000000000000AC -:1094C000000000000000000000000000000000009C -:1094D000000000000000000000000000000000008C -:1094E000000000000000000000000000000000007C -:1094F000000000000000000000000000000000006C -:10950000000000000000000000000000000000005B -:10951000000000000000000000000000000000004B -:10952000000000000000000000000000000000003B -:10953000000000000000000000000000000000002B -:10954000000000000000000000000000000000001B -:10955000000000000000000000000000000000000B -:1095600000000000000000000000000000000000FB -:1095700000000000000000000000000000000000EB -:1095800000000000000000000000000000000000DB -:1095900000000000000000000000000000000000CB -:1095A00000000000000000000000000000000000BB -:1095B00000000000000000000000000000000000AB -:1095C000000000000000000000000000000000009B -:1095D000000000000000000000000000000000008B -:1095E000000000000000000000000000000000007B -:1095F000000000000000000000000000000000006B -:10960000000000000000000000000000000000005A -:10961000000000000000000000000000000000004A -:10962000000000000000000000000000000000003A -:10963000000000000000000000000000000000002A -:10964000000000000000000000000000000000001A -:10965000000000000000000000000000000000000A -:1096600000000000000000000000000000000000FA -:1096700000000000000000000000000000000000EA -:1096800000000000000000000000000000000000DA -:1096900000000000000000000000000000000000CA -:1096A00000000000000000000000000000000000BA -:1096B00000000000000000000000000000000000AA -:1096C000000000000000000000000000000000009A -:1096D000000000000000000000000000000000008A -:1096E000000000000000000000000000000000007A -:1096F000000000000000000000000000000000006A -:109700000000000000000000000000000000000059 -:109710000000000000000000000000000000000049 -:109720000000000000000000000000000000000039 -:109730000000000000000000000000000000000029 -:109740000000000000000000000000000000000019 -:109750000000000000000000000000000000000009 -:1097600000000000000000000000000000000000F9 -:1097700000000000000000000000000000000000E9 -:1097800000000000000000000000000000000000D9 -:1097900000000000000000000000000000000000C9 -:1097A00000000000000000000000000000000000B9 -:1097B00000000000000000000000000000000000A9 -:1097C0000000000000000000000000000000000099 -:1097D0000000000000000000000000000000000089 -:1097E0000000000000000000000000000000000079 -:1097F0000000000000000000000000000000000069 -:109800000000000000000000000000000000000058 -:109810000000000000000000000000000000000048 -:109820000000000000000000000000000000000038 -:109830000000000000000000000000000000000028 -:109840000000000000000000000000000000000018 -:109850000000000000000000000000000000000008 -:1098600000000000000000000000000000000000F8 -:1098700000000000000000000000000000000000E8 -:1098800000000000000000000000000000000000D8 -:1098900000000000000000000000000000000000C8 -:1098A00000000000000000000000000000000000B8 -:1098B00000000000000000000000000000000000A8 -:1098C0000000000000000000000000000000000098 -:1098D0000000000000000000000000000000000088 -:1098E0000000000000000000000000000000000078 -:1098F0000000000000000000000000000000000068 -:109900000000000000000000000000000000000057 -:109910000000000000000000000000000000000047 -:109920000000000000000000000000000000000037 -:109930000000000000000000000000000000000027 -:109940000000000000000000000000000000000017 -:109950000000000000000000000000000000000007 -:1099600000000000000000000000000000000000F7 -:1099700000000000000000000000000000000000E7 -:1099800000000000000000000000000000000000D7 -:1099900000000000000000000000000000000000C7 -:1099A00000000000000000000000000000000000B7 -:1099B00000000000000000000000000000000000A7 -:1099C0000000000000000000000000000000000097 -:1099D0000000000000000000000000000000000087 -:1099E0000000000000000000000000000000000077 -:1099F0000000000000000000000000000000000067 -:109A00000000000000000000000000000000000056 -:109A10000000000000000000000000000000000046 -:109A20000000000000000000000000000000000036 -:109A30000000000000000000000000000000000026 -:109A40000000000000000000000000000000000016 -:109A50000000000000000000000000000000000006 -:109A600000000000000000000000000000000000F6 -:109A700000000000000000000000000000000000E6 -:109A800000000000000000000000000000000000D6 -:109A900000000000000000000000000000000000C6 -:109AA00000000000000000000000000000000000B6 -:109AB00000000000000000000000000000000000A6 -:109AC0000000000000000000000000000000000096 -:109AD0000000000000000000000000000000000086 -:109AE0000000000000000000000000000000000076 -:109AF0000000000000000000000000000000000066 -:109B00000000000000000000000000000000000055 -:109B10000000000000000000000000000000000045 -:109B20000000000000000000000000000000000035 -:109B30000000000000000000000000000000000025 -:109B40000000000000000000000000000000000015 -:109B50000000000000000000000000000000000005 -:109B600000000000000000000000000000000000F5 -:109B700000000000000000000000000000000000E5 -:109B800000000000000000000000000000000000D5 -:109B900000000000000000000000000000000000C5 -:109BA00000000000000000000000000000000000B5 -:109BB00000000000000000000000000000000000A5 -:109BC0000000000000000000000000000000000095 -:109BD0000000000000000000000000000000000085 -:109BE0000000000000000000000000000000000075 -:109BF0000000000000000000000000000000000065 -:109C00000000000000000000000000000000000054 -:109C10000000000000000000000000000000000044 -:109C20000000000000000000000000000000000034 -:109C30000000000000000000000000000000000024 -:109C40000000000000000000000000000000000014 -:109C50000000000000000000000000000000000004 -:109C600000000000000000000000000000000000F4 -:109C700000000000000000000000000000000000E4 -:109C800000000000000000000000000000000000D4 -:109C900000000000000000000000000000000000C4 -:109CA00000000000000000000000000000000000B4 -:109CB00000000000000000000000000000000000A4 -:109CC0000000000000000000000000000000000094 -:109CD0000000000000000000000000000000000084 -:109CE0000000000000000000000000000000000074 -:109CF0000000000000000000000000000000000064 -:109D00000000000000000000000000000000000053 -:109D10000000000000000000000000000000000043 -:109D20000000000000000000000000000000000033 -:109D30000000000000000000000000000000000023 -:109D40000000000000000000000000000000000013 -:109D50000000000000000000000000000000000003 -:109D600000000000000000000000000000000000F3 -:109D700000000000000000000000000000000000E3 -:109D800000000000000000000000000000000000D3 -:109D900000000000000000000000000000000000C3 -:109DA00000000000000000000000000000000000B3 -:109DB00000000000000000000000000000000000A3 -:109DC0000000000000000000000000000000000093 -:109DD0000000000000000000000000000000000083 -:109DE0000000000000000000000000000000000073 -:109DF0000000000000000000000000000000000063 -:109E00000000000000000000000000000000000052 -:109E10000000000000000000000000000000000042 -:109E20000000000000000000000000000000000032 -:109E30000000000000000000000000000000000022 -:109E40000000000000000000000000000000000012 -:109E50000000000000000000000000000000000002 -:109E600000000000000000000000000000000000F2 -:109E700000000000000000000000000000000000E2 -:109E800000000000000000000000000000000000D2 -:109E900000000000000000000000000000000000C2 -:109EA00000000000000000000000000000000000B2 -:109EB00000000000000000000000000000000000A2 -:109EC0000000000000000000000000000000000092 -:109ED0000000000000000000000000000000000082 -:109EE0000000000000000000000000000000000072 -:109EF0000000000000000000000000000000000062 -:109F00000000000000000000000000000000000051 -:109F10000000000000000000000000000000000041 -:109F20000000000000000000000000000000000031 -:109F30000000000000000000000000000000000021 -:109F40000000000000000000000000000000000011 -:109F50000000000000000000000000000000000001 -:109F600000000000000000000000000000000000F1 -:109F700000000000000000000000000000000000E1 -:109F800000000000000000000000000000000000D1 -:109F900000000000000000000000000000000000C1 -:109FA00000000000000000000000000000000000B1 -:109FB00000000000000000000000000000000000A1 -:109FC0000000000000000000000000000000000091 -:109FD0000000000000000000000000000000000081 -:109FE0000000000000000000000000000000000071 -:109FF0000000000000000000000000000000000061 -:10A000000000000000000000000000000000000050 -:10A010000000000000000000000000000000000040 -:10A020000000000000000000000000000000000030 -:10A030000000000000000000000000000000000020 -:10A040000000000000000000000000000000000010 -:10A050000000000000000000000000000000000000 -:10A0600000000000000000000000000000000000F0 -:10A0700000000000000000000000000000000000E0 -:10A0800000000000000000000000000000000000D0 -:10A0900000000000000000000000000000000000C0 -:10A0A00000000000000000000000000000000000B0 -:10A0B00000000000000000000000000000000000A0 -:10A0C0000000000000000000000000000000000090 -:10A0D0000000000000000000000000000000000080 -:10A0E0000000000000000000000000000000000070 -:10A0F0000000000000000000000000000000000060 -:10A10000000000000000000000000000000000004F -:10A11000000000000000000000000000000000003F -:10A12000000000000000000000000000000000002F -:10A13000000000000000000000000000000000001F -:10A14000000000000000000000000000000000000F -:10A1500000000000000000000000000000000000FF -:10A1600000000000000000000000000000000000EF -:10A1700000000000000000000000000000000000DF -:10A1800000000000000000000000000000000000CF -:10A1900000000000000000000000000000000000BF -:10A1A00000000000000000000000000000000000AF -:10A1B000000000000000000000000000000000009F -:10A1C000000000000000000000000000000000008F -:10A1D000000000000000000000000000000000007F -:10A1E000000000000000000000000000000000006F -:10A1F000000000000000000000000000000000005F -:10A20000000000000000000000000000000000004E -:10A21000000000000000000000000000000000003E -:10A22000000000000000000000000000000000002E -:10A23000000000000000000000000000000000001E -:10A24000000000000000000000000000000000000E -:10A2500000000000000000000000000000000000FE -:10A2600000000000000000000000000000000000EE -:10A2700000000000000000000000000000000000DE -:10A2800000000000000000000000000000000000CE -:10A2900000000000000000000000000000000000BE -:10A2A00000000000000000000000000000000000AE -:10A2B000000000000000000000000000000000009E -:10A2C000000000000000000000000000000000008E -:10A2D000000000000000000000000000000000007E -:10A2E000000000000000000000000000000000006E -:10A2F000000000000000000000000000000000005E -:10A30000000000000000000000000000000000004D -:10A31000000000000000000000000000000000003D -:10A32000000000000000000000000000000000002D -:10A33000000000000000000000000000000000001D -:10A34000000000000000000000000000000000000D -:10A3500000000000000000000000000000000000FD -:10A3600000000000000000000000000000000000ED -:10A3700000000000000000000000000000000000DD -:10A3800000000000000000000000000000000000CD -:10A3900000000000000000000000000000000000BD -:10A3A00000000000000000000000000000000000AD -:10A3B000000000000000000000000000000000009D -:10A3C000000000000000000000000000000000008D -:10A3D000000000000000000000000000000000007D -:10A3E000000000000000000000000000000000006D -:10A3F000000000000000000000000000000000005D -:10A40000000000000000000000000000000000004C -:10A41000000000000000000000000000000000003C -:10A42000000000000000000000000000000000002C -:10A43000000000000000000000000000000000001C -:10A44000000000000000000000000000000000000C -:10A4500000000000000000000000000000000000FC -:10A4600000000000000000000000000000000000EC -:10A4700000000000000000000000000000000000DC -:10A4800000000000000000000000000000000000CC -:10A4900000000000000000000000000000000000BC -:10A4A00000000000000000000000000000000000AC -:10A4B000000000000000000000000000000000009C -:10A4C000000000000000000000000000000000008C -:10A4D000000000000000000000000000000000007C -:10A4E000000000000000000000000000000000006C -:10A4F000000000000000000000000000000000005C -:10A50000000000000000000000000000000000004B -:10A51000000000000000000000000000000000003B -:10A52000000000000000000000000000000000002B -:10A53000000000000000000000000000000000001B -:10A54000000000000000000000000000000000000B -:10A5500000000000000000000000000000000000FB -:10A5600000000000000000000000000000000000EB -:10A5700000000000000000000000000000000000DB -:10A5800000000000000000000000000000000000CB -:10A5900000000000000000000000000000000000BB -:10A5A00000000000000000000000000000000000AB -:10A5B000000000000000000000000000000000009B -:10A5C000000000000000000000000000000000008B -:10A5D000000000000000000000000000000000007B -:10A5E000000000000000000000000000000000006B -:10A5F000000000000000000000000000000000005B -:10A60000000000000000000000000000000000004A -:10A61000000000000000000000000000000000003A -:10A62000000000000000000000000000000000002A -:10A63000000000000000000000000000000000001A -:10A64000000000000000000000000000000000000A -:10A6500000000000000000000000000000000000FA -:10A6600000000000000000000000000000000000EA -:10A6700000000000000000000000000000000000DA -:10A6800000000000000000000000000000000000CA -:10A6900000000000000000000000000000000000BA -:10A6A00000000000000000000000000000000000AA -:10A6B000000000000000000000000000000000009A -:10A6C000000000000000000000000000000000008A -:10A6D000000000000000000000000000000000007A -:10A6E000000000000000000000000000000000006A -:10A6F000000000000000000000000000000000005A -:10A700000000000000000000000000000000000049 -:10A710000000000000000000000000000000000039 -:10A720000000000000000000000000000000000029 -:10A730000000000000000000000000000000000019 -:10A740000000000000000000000000000000000009 -:10A7500000000000000000000000000000000000F9 -:10A7600000000000000000000000000000000000E9 -:10A7700000000000000000000000000000000000D9 -:10A7800000000000000000000000000000000000C9 -:10A7900000000000000000000000000000000000B9 -:10A7A00000000000000000000000000000000000A9 -:10A7B0000000000000000000000000000000000099 -:10A7C0000000000000000000000000000000000089 -:10A7D0000000000000000000000000000000000079 -:10A7E0000000000000000000000000000000000069 -:10A7F0000000000000000000000000000000000059 -:10A800000000000000000000000000000000000048 -:10A810000000000000000000000000000000000038 -:10A820000000000000000000000000000000000028 -:10A830000000000000000000000000000000000018 -:10A840000000000000000000000000000000000008 -:10A8500000000000000000000000000000000000F8 -:10A8600000000000000000000000000000000000E8 -:10A8700000000000000000000000000000000000D8 -:10A8800000000000000000000000000000000000C8 -:10A8900000000000000000000000000000000000B8 -:10A8A00000000000000000000000000000000000A8 -:10A8B0000000000000000000000000000000000098 -:10A8C0000000000000000000000000000000000088 -:10A8D0000000000000000000000000000000000078 -:10A8E0000000000000000000000000000000000068 -:10A8F0000000000000000000000000000000000058 -:10A900000000000000000000000000000000000047 -:10A910000000000000000000000000000000000037 -:10A920000000000000000000000000000000000027 -:10A930000000000000000000000000000000000017 -:10A940000000000000000000000000000000000007 -:10A9500000000000000000000000000000000000F7 -:10A9600000000000000000000000000000000000E7 -:10A9700000000000000000000000000000000000D7 -:10A9800000000000000000000000000000000000C7 -:10A9900000000000000000000000000000000000B7 -:10A9A00000000000000000000000000000000000A7 -:10A9B0000000000000000000000000000000000097 -:10A9C0000000000000000000000000000000000087 -:10A9D0000000000000000000000000000000000077 -:10A9E0000000000000000000000000000000000067 -:10A9F0000000000000000000000000000000000057 -:10AA00000000000000000000000000000000000046 -:10AA10000000000000000000000000000000000036 -:10AA20000000000000000000000000000000000026 -:10AA30000000000000000000000000000000000016 -:10AA40000000000000000000000000000000000006 -:10AA500000000000000000000000000000000000F6 -:10AA600000000000000000000000000000000000E6 -:10AA700000000000000000000000000000000000D6 -:10AA800000000000000000000000000000000000C6 -:10AA900000000000000000000000000000000000B6 -:10AAA00000000000000000000000000000000000A6 -:10AAB0000000000000000000000000000000000096 -:10AAC0000000000000000000000000000000000086 -:10AAD0000000000000000000000000000000000076 -:10AAE0000000000000000000000000000000000066 -:10AAF0000000000000000000000000000000000056 -:10AB00000000000000000000000000000000000045 -:10AB10000000000000000000000000000000000035 -:10AB20000000000000000000000000000000000025 -:10AB30000000000000000000000000000000000015 -:10AB40000000000000000000000000000000000005 -:10AB500000000000000000000000000000000000F5 -:10AB600000000000000000000000000000000000E5 -:10AB700000000000000000000000000000000000D5 -:10AB800000000000000000000000000000000000C5 -:10AB900000000000000000000000000000000000B5 -:10ABA00000000000000000000000000000000000A5 -:10ABB0000000000000000000000000000000000095 -:10ABC0000000000000000000000000000000000085 -:10ABD0000000000000000000000000000000000075 -:10ABE0000000000000000000000000000000000065 -:10ABF0000000000000000000000000000000000055 -:10AC00000000000000000000000000000000000044 -:10AC10000000000000000000000000000000000034 -:10AC20000000000000000000000000000000000024 -:10AC30000000000000000000000000000000000014 -:10AC40000000000000000000000000000000000004 -:10AC500000000000000000000000000000000000F4 -:10AC600000000000000000000000000000000000E4 -:10AC700000000000000000000000000000000000D4 -:10AC800000000000000000000000000000000000C4 -:10AC900000000000000000000000000000000000B4 -:10ACA00000000000000000000000000000000000A4 -:10ACB0000000000000000000000000000000000094 -:10ACC0000000000000000000000000000000000084 -:10ACD0000000000000000000000000000000000074 -:10ACE0000000000000000000000000000000000064 -:10ACF0000000000000000000000000000000000054 -:10AD00000000000000000000000000000000000043 -:10AD10000000000000000000000000000000000033 -:10AD20000000000000000000000000000000000023 -:10AD30000000000000000000000000000000000013 -:10AD40000000000000000000000000000000000003 -:10AD500000000000000000000000000000000000F3 -:10AD600000000000000000000000000000000000E3 -:10AD700000000000000000000000000000000000D3 -:10AD800000000000000000000000000000000000C3 -:10AD900000000000000000000000000000000000B3 -:10ADA00000000000000000000000000000000000A3 -:10ADB0000000000000000000000000000000000093 -:10ADC0000000000000000000000000000000000083 -:10ADD0000000000000000000000000000000000073 -:10ADE0000000000000000000000000000000000063 -:10ADF0000000000000000000000000000000000053 -:10AE00000000000000000000000000000000000042 -:10AE10000000000000000000000000000000000032 -:10AE20000000000000000000000000000000000022 -:10AE30000000000000000000000000000000000012 -:10AE40000000000000000000000000000000000002 -:10AE500000000000000000000000000000000000F2 -:10AE600000000000000000000000000000000000E2 -:10AE700000000000000000000000000000000000D2 -:10AE800000000000000000000000000000000000C2 -:10AE900000000000000000000000000000000000B2 -:10AEA00000000000000000000000000000000000A2 -:10AEB0000000000000000000000000000000000092 -:10AEC0000000000000000000000000000000000082 -:10AED0000000000000000000000000000000000072 -:10AEE0000000000000000000000000000000000062 -:10AEF0000000000000000000000000000000000052 -:10AF00000000000000000000000000000000000041 -:10AF10000000000000000000000000000000000031 -:10AF20000000000000000000000000000000000021 -:10AF30000000000000000000000000000000000011 -:10AF40000000000000000000000000000000000001 -:10AF500000000000000000000000000000000000F1 -:10AF600000000000000000000000000000000000E1 -:10AF700000000000000000000000000000000000D1 -:10AF800000000000000000000000000000000000C1 -:10AF900000000000000000000000000000000000B1 -:10AFA00000000000000000000000000000000000A1 -:10AFB0000000000000000000000000000000000091 -:10AFC0000000000000000000000000000000000081 -:10AFD0000000000000000000000000000000000071 -:10AFE0000000000000000000000000000000000061 -:10AFF0000000000000000000000000000000000051 -:10B000000000000000000000000000000000000040 -:10B010000000000000000000000000000000000030 -:10B020000000000000000000000000000000000020 -:10B030000000000000000000000000000000000010 -:10B040000000000000000000000000000000000000 -:10B0500000000000000000000000000000000000F0 -:10B0600000000000000000000000000000000000E0 -:10B0700000000000000000000000000000000000D0 -:10B0800000000000000000000000000000000000C0 -:10B0900000000000000000000000000000000000B0 -:10B0A00000000000000000000000000000000000A0 -:10B0B0000000000000000000000000000000000090 -:10B0C0000000000000000000000000000000000080 -:10B0D0000000000000000000000000000000000070 -:10B0E0000000000000000000000000000000000060 -:10B0F0000000000000000000000000000000000050 -:10B10000000000000000000000000000000000003F -:10B11000000000000000000000000000000000002F -:10B12000000000000000000000000000000000001F -:10B13000000000000000000000000000000000000F -:10B1400000000000000000000000000000000000FF -:10B1500000000000000000000000000000000000EF -:10B1600000000000000000000000000000000000DF -:10B1700000000000000000000000000000000000CF -:10B1800000000000000000000000000000000000BF -:10B1900000000000000000000000000000000000AF -:10B1A000000000000000000000000000000000009F -:10B1B000000000000000000000000000000000008F -:10B1C000000000000000000000000000000000007F -:10B1D000000000000000000000000000000000006F -:10B1E000000000000000000000000000000000005F -:10B1F000000000000000000000000000000000004F -:10B20000000000000000000000000000000000003E -:10B21000000000000000000000000000000000002E -:10B22000000000000000000000000000000000001E -:10B23000000000000000000000000000000000000E -:10B2400000000000000000000000000000000000FE -:10B2500000000000000000000000000000000000EE -:10B2600000000000000000000000000000000000DE -:10B2700000000000000000000000000000000000CE -:10B2800000000000000000000000000000000000BE -:10B2900000000000000000000000000000000000AE -:10B2A000000000000000000000000000000000009E -:10B2B000000000000000000000000000000000008E -:10B2C000000000000000000000000000000000007E -:10B2D000000000000000000000000000000000006E -:10B2E000000000000000000000000000000000005E -:10B2F000000000000000000000000000000000004E -:10B30000000000000000000000000000000000003D -:10B31000000000000000000000000000000000002D -:10B32000000000000000000000000000000000001D -:10B33000000000000000000000000000000000000D -:10B3400000000000000000000000000000000000FD -:10B3500000000000000000000000000000000000ED -:10B3600000000000000000000000000000000000DD -:10B3700000000000000000000000000000000000CD -:10B3800000000000000000000000000000000000BD -:10B3900000000000000000000000000000000000AD -:10B3A000000000000000000000000000000000009D -:10B3B000000000000000000000000000000000008D -:10B3C000000000000000000000000000000000007D -:10B3D000000000000000000000000000000000006D -:10B3E000000000000000000000000000000000005D -:10B3F000000000000000000000000000000000004D -:10B40000000000000000000000000000000000003C -:10B41000000000000000000000000000000000002C -:10B42000000000000000000000000000000000001C -:10B43000000000000000000000000000000000000C -:10B4400000000000000000000000000000000000FC -:10B4500000000000000000000000000000000000EC -:10B4600000000000000000000000000000000000DC -:10B4700000000000000000000000000000000000CC -:10B4800000000000000000000000000000000000BC -:10B4900000000000000000000000000000000000AC -:10B4A000000000000000000000000000000000009C -:10B4B000000000000000000000000000000000008C -:10B4C000000000000000000000000000000000007C -:10B4D000000000000000000000000000000000006C -:10B4E000000000000000000000000000000000005C -:10B4F000000000000000000000000000000000004C -:10B50000000000000000000000000000000000003B -:10B51000000000000000000000000000000000002B -:10B52000000000000000000000000000000000001B -:10B53000000000000000000000000000000000000B -:10B5400000000000000000000000000000000000FB -:10B5500000000000000000000000000000000000EB -:10B5600000000000000000000000000000000000DB -:10B5700000000000000000000000000000000000CB -:10B5800000000000000000000000000000000000BB -:10B5900000000000000000000000000000000000AB -:10B5A000000000000000000000000000000000009B -:10B5B000000000000000000000000000000000008B -:10B5C000000000000000000000000000000000007B -:10B5D000000000000000000000000000000000006B -:10B5E000000000000000000000000000000000005B -:10B5F000000000000000000000000000000000004B -:10B60000000000000000000000000000000000003A -:10B61000000000000000000000000000000000002A -:10B62000000000000000000000000000000000001A -:10B63000000000000000000000000000000000000A -:10B6400000000000000000000000000000000000FA -:10B6500000000000000000000000000000000000EA -:10B6600000000000000000000000000000000000DA -:10B6700000000000000000000000000000000000CA -:10B6800000000000000000000000000000000000BA -:10B6900000000000000000000000000000000000AA -:10B6A000000000000000000000000000000000009A -:10B6B000000000000000000000000000000000008A -:10B6C000000000000000000000000000000000007A -:10B6D000000000000000000000000000000000006A -:10B6E000000000000000000000000000000000005A -:10B6F000000000000000000000000000000000004A -:10B700000000000000000000000000000000000039 -:10B710000000000000000000000000000000000029 -:10B720000000000000000000000000000000000019 -:10B730000000000000000000000000000000000009 -:10B7400000000000000000000000000000000000F9 -:10B7500000000000000000000000000000000000E9 -:10B7600000000000000000000000000000000000D9 -:10B7700000000000000000000000000000000000C9 -:10B7800000000000000000000000000000000000B9 -:10B7900000000000000000000000000000000000A9 -:10B7A0000000000000000000000000000000000099 -:10B7B0000000000000000000000000000000000089 -:10B7C0000000000000000000000000000000000079 -:10B7D0000000000000000000000000000000000069 -:10B7E0000000000000000000000000000000000059 -:10B7F0000000000000000000000000000000000049 -:10B800000000000000000000000000000000000038 -:10B810000000000000000000000000000000000028 -:10B820000000000000000000000000000000000018 -:10B830000000000000000000000000000000000008 -:10B8400000000000000000000000000000000000F8 -:10B8500000000000000000000000000000000000E8 -:10B8600000000000000000000000000000000000D8 -:10B8700000000000000000000000000000000000C8 -:10B8800000000000000000000000000000000000B8 -:10B8900000000000000000000000000000000000A8 -:10B8A0000000000000000000000000000000000098 -:10B8B0000000000000000000000000000000000088 -:10B8C0000000000000000000000000000000000078 -:10B8D0000000000000000000000000000000000068 -:10B8E0000000000000000000000000000000000058 -:10B8F0000000000000000000000000000000000048 -:10B900000000000000000000000000000000000037 -:10B910000000000000000000000000000000000027 -:10B920000000000000000000000000000000000017 -:10B930000000000000000000000000000000000007 -:10B9400000000000000000000000000000000000F7 -:10B9500000000000000000000000000000000000E7 -:10B9600000000000000000000000000000000000D7 -:10B9700000000000000000000000000000000000C7 -:10B9800000000000000000000000000000000000B7 -:10B9900000000000000000000000000000000000A7 -:10B9A0000000000000000000000000000000000097 -:10B9B0000000000000000000000000000000000087 -:10B9C0000000000000000000000000000000000077 -:10B9D0000000000000000000000000000000000067 -:10B9E0000000000000000000000000000000000057 -:10B9F0000000000000000000000000000000000047 -:10BA00000000000000000000000000000000000036 -:10BA10000000000000000000000000000000000026 -:10BA20000000000000000000000000000000000016 -:10BA30000000000000000000000000000000000006 -:10BA400000000000000000000000000000000000F6 -:10BA500000000000000000000000000000000000E6 -:10BA600000000000000000000000000000000000D6 -:10BA700000000000000000000000000000000000C6 -:10BA800000000000000000000000000000000000B6 -:10BA900000000000000000000000000000000000A6 -:10BAA0000000000000000000000000000000000096 -:10BAB0000000000000000000000000000000000086 -:10BAC0000000000000000000000000000000000076 -:10BAD0000000000000000000000000000000000066 -:10BAE0000000000000000000000000000000000056 -:10BAF0000000000000000000000000000000000046 -:10BB00000000000000000000000000000000000035 -:10BB10000000000000000000000000000000000025 -:10BB20000000000000000000000000000000000015 -:10BB30000000000000000000000000000000000005 -:10BB400000000000000000000000000000000000F5 -:10BB500000000000000000000000000000000000E5 -:10BB600000000000000000000000000000000000D5 -:10BB700000000000000000000000000000000000C5 -:10BB800000000000000000000000000000000000B5 -:10BB900000000000000000000000000000000000A5 -:10BBA0000000000000000000000000000000000095 -:10BBB0000000000000000000000000000000000085 -:10BBC0000000000000000000000000000000000075 -:10BBD0000000000000000000000000000000000065 -:10BBE0000000000000000000000000000000000055 -:10BBF0000000000000000000000000000000000045 -:10BC00000000000000000000000000000000000034 -:10BC10000000000000000000000000000000000024 -:10BC20000000000000000000000000000000000014 -:10BC30000000000000000000000000000000000004 -:10BC400000000000000000000000000000000000F4 -:10BC500000000000000000000000000000000000E4 -:10BC600000000000000000000000000000000000D4 -:10BC700000000000000000000000000000000000C4 -:10BC800000000000000000000000000000000000B4 -:10BC900000000000000000000000000000000000A4 -:10BCA0000000000000000000000000000000000094 -:10BCB0000000000000000000000000000000000084 -:10BCC0000000000000000000000000000000000074 -:10BCD0000000000000000000000000000000000064 -:10BCE0000000000000000000000000000000000054 -:10BCF0000000000000000000000000000000000044 -:10BD00000000000000000000000000000000000033 -:10BD10000000000000000000000000000000000023 -:10BD20000000000000000000000000000000000013 -:10BD30000000000000000000000000000000000003 -:10BD400000000000000000000000000000000000F3 -:10BD500000000000000000000000000000000000E3 -:10BD600000000000000000000000000000000000D3 -:10BD700000000000000000000000000000000000C3 -:10BD800000000000000000000000000000000000B3 -:10BD900000000000000000000000000000000000A3 -:10BDA0000000000000000000000000000000000093 -:10BDB0000000000000000000000000000000000083 -:10BDC0000000000000000000000000000000000073 -:10BDD0000000000000000000000000000000000063 -:10BDE0000000000000000000000000000000000053 -:10BDF0000000000000000000000000000000000043 -:10BE00000000000000000000000000000000000032 -:10BE10000000000000000000000000000000000022 -:10BE20000000000000000000000000000000000012 -:10BE30000000000000000000000000000000000002 -:10BE400000000000000000000000000000000000F2 -:10BE500000000000000000000000000000000000E2 -:10BE600000000000000000000000000000000000D2 -:10BE700000000000000000000000000000000000C2 -:10BE800000000000000000000000000000000000B2 -:10BE900000000000000000000000000000000000A2 -:10BEA0000000000000000000000000000000000092 -:10BEB0000000000000000000000000000000000082 -:10BEC0000000000000000000000000000000000072 -:10BED0000000000000000000000000000000000062 -:10BEE0000000000000000000000000000000000052 -:10BEF0000000000000000000000000000000000042 -:10BF00000000000000000000000000000000000031 -:10BF10000000000000000000000000000000000021 -:10BF20000000000000000000000000000000000011 -:10BF30000000000000000000000000000000000001 -:10BF400000000000000000000000000000000000F1 -:10BF500000000000000000000000000000000000E1 -:10BF600000000000000000000000000000000000D1 -:10BF700000000000000000000000000000000000C1 -:10BF800000000000000000000000000000000000B1 -:10BF900000000000000000000000000000000000A1 -:10BFA0000000000000000000000000000000000091 -:10BFB0000000000000000000000000000000000081 -:10BFC0000000000000000000000000000000000071 -:10BFD0000000000000000000000000000000000061 -:10BFE0000000000000000000000000000000000051 -:10BFF0000000000000000000000000000000000041 -:10C000000000000000000000000000000000000030 -:10C010000000000000000000000000000000000020 -:10C020000000000000000000000000000000000010 -:10C030000000000000000000000000000000000000 -:10C0400000000000000000000000000000000000F0 -:10C0500000000000000000000000000000000000E0 -:10C0600000000000000000000000000000000000D0 -:10C0700000000000000000000000000000000000C0 -:10C0800000000000000000000000000000000000B0 -:10C0900000000000000000000000000000000000A0 -:10C0A0000000000000000000000000000000000090 -:10C0B0000000000000000000000000000000000080 -:10C0C0000000000000000000000000000000000070 -:10C0D0000000000000000000000000000000000060 -:10C0E0000000000000000000000000000000000050 -:10C0F0000000000000000000000000000000000040 -:10C10000000000000000000000000000000000002F -:10C11000000000000000000000000000000000001F -:10C12000000000000000000000000000000000000F -:10C1300000000000000000000000000000000000FF -:10C1400000000000000000000000000000000000EF -:10C1500000000000000000000000000000000000DF -:10C1600000000000000000000000000000000000CF -:10C1700000000000000000000000000000000000BF -:10C1800000000000000000000000000000000000AF -:10C19000000000000000000000000000000000009F -:10C1A000000000000000000000000000000000008F -:10C1B000000000000000000000000000000000007F -:10C1C000000000000000000000000000000000006F -:10C1D000000000000000000000000000000000005F -:10C1E000000000000000000000000000000000004F -:10C1F000000000000000000000000000000000003F -:10C20000000000000000000000000000000000002E -:10C21000000000000000000000000000000000001E -:10C22000000000000000000000000000000000000E -:10C2300000000000000000000000000000000000FE -:10C2400000000000000000000000000000000000EE -:10C2500000000000000000000000000000000000DE -:10C2600000000000000000000000000000000000CE -:10C2700000000000000000000000000000000000BE -:10C2800000000000000000000000000000000000AE -:10C29000000000000000000000000000000000009E -:10C2A000000000000000000000000000000000008E -:10C2B000000000000000000000000000000000007E -:10C2C000000000000000000000000000000000006E -:10C2D000000000000000000000000000000000005E -:10C2E000000000000000000000000000000000004E -:10C2F000000000000000000000000000000000003E -:10C30000000000000000000000000000000000002D -:10C31000000000000000000000000000000000001D -:10C32000000000000000000000000000000000000D -:10C3300000000000000000000000000000000000FD -:10C3400000000000000000000000000000000000ED -:10C3500000000000000000000000000000000000DD -:10C3600000000000000000000000000000000000CD -:10C3700000000000000000000000000000000000BD -:10C3800000000000000000000000000000000000AD -:10C39000000000000000000000000000000000009D -:10C3A000000000000000000000000000000000008D -:10C3B000000000000000000000000000000000007D -:10C3C000000000000000000000000000000000006D -:10C3D000000000000000000000000000000000005D -:10C3E000000000000000000000000000000000004D -:10C3F000000000000000000000000000000000003D -:10C40000000000000000000000000000000000002C -:10C41000000000000000000000000000000000001C -:10C42000000000000000000000000000000000000C -:10C4300000000000000000000000000000000000FC -:10C4400000000000000000000000000000000000EC -:10C4500000000000000000000000000000000000DC -:10C4600000000000000000000000000000000000CC -:10C4700000000000000000000000000000000000BC -:10C4800000000000000000000000000000000000AC -:10C49000000000000000000000000000000000009C -:10C4A000000000000000000000000000000000008C -:10C4B000000000000000000000000000000000007C -:10C4C000000000000000000000000000000000006C -:10C4D000000000000000000000000000000000005C -:10C4E000000000000000000000000000000000004C -:10C4F000000000000000000000000000000000003C -:10C50000000000000000000000000000000000002B -:10C51000000000000000000000000000000000001B -:10C52000000000000000000000000000000000000B -:10C5300000000000000000000000000000000000FB -:10C5400000000000000000000000000000000000EB -:10C5500000000000000000000000000000000000DB -:10C5600000000000000000000000000000000000CB -:10C5700000000000000000000000000000000000BB -:10C5800000000000000000000000000000000000AB -:10C59000000000000000000000000000000000009B -:10C5A000000000000000000000000000000000008B -:10C5B000000000000000000000000000000000007B -:10C5C000000000000000000000000000000000006B -:10C5D000000000000000000000000000000000005B -:10C5E000000000000000000000000000000000004B -:10C5F000000000000000000000000000000000003B -:10C60000000000000000000000000000000000002A -:10C61000000000000000000000000000000000001A -:10C62000000000000000000000000000000000000A -:10C6300000000000000000000000000000000000FA -:10C6400000000000000000000000000000000000EA -:10C6500000000000000000000000000000000000DA -:10C6600000000000000000000000000000000000CA -:10C6700000000000000000000000000000000000BA -:10C6800000000000000000000000000000000000AA -:10C69000000000000000000000000000000000009A -:10C6A000000000000000000000000000000000008A -:10C6B000000000000000000000000000000000007A -:10C6C000000000000000000000000000000000006A -:10C6D000000000000000000000000000000000005A -:10C6E000000000000000000000000000000000004A -:10C6F000000000000000000000000000000000003A -:10C700000000000000000000000000000000000029 -:10C710000000000000000000000000000000000019 -:10C720000000000000000000000000000000000009 -:10C7300000000000000000000000000000000000F9 -:10C7400000000000000000000000000000000000E9 -:10C7500000000000000000000000000000000000D9 -:10C7600000000000000000000000000000000000C9 -:10C7700000000000000000000000000000000000B9 -:10C7800000000000000000000000000000000000A9 -:10C790000000000000000000000000000000000099 -:10C7A0000000000000000000000000000000000089 -:10C7B0000000000000000000000000000000000079 -:10C7C0000000000000000000000000000000000069 -:10C7D0000000000000000000000000000000000059 -:10C7E0000000000000000000000000000000000049 -:10C7F0000000000000000000000000000000000039 -:10C800000000000000000000000000000000000028 -:10C810000000000000000000000000000000000018 -:10C820000000000000000000000000000000000008 -:10C8300000000000000000000000000000000000F8 -:10C8400000000000000000000000000000000000E8 -:10C8500000000000000000000000000000000000D8 -:10C8600000000000000000000000000000000000C8 -:10C8700000000000000000000000000000000000B8 -:10C8800000000000000000000000000000000000A8 -:10C890000000000000000000000000000000000098 -:10C8A0000000000000000000000000000000000088 -:10C8B0000000000000000000000000000000000078 -:10C8C0000000000000000000000000000000000068 -:10C8D0000000000000000000000000000000000058 -:10C8E0000000000000000000000000000000000048 -:10C8F0000000000000000000000000000000000038 -:10C900000000000000000000000000000000000027 -:10C910000000000000000000000000000000000017 -:10C920000000000000000000000000000000000007 -:10C9300000000000000000000000000000000000F7 -:10C9400000000000000000000000000000000000E7 -:10C9500000000000000000000000000000000000D7 -:10C9600000000000000000000000000000000000C7 -:10C9700000000000000000000000000000000000B7 -:10C9800000000000000000000000000000000000A7 -:10C990000000000000000000000000000000000097 -:10C9A0000000000000000000000000000000000087 -:10C9B0000000000000000000000000000000000077 -:10C9C0000000000000000000000000000000000067 -:10C9D0000000000000000000000000000000000057 -:10C9E0000000000000000000000000000000000047 -:10C9F0000000000000000000000000000000000037 -:10CA00000000000000000000000000000000000026 -:10CA10000000000000000000000000000000000016 -:10CA20000000000000000000000000000000000006 -:10CA300000000000000000000000000000000000F6 -:10CA400000000000000000000000000000000000E6 -:10CA500000000000000000000000000000000000D6 -:10CA600000000000000000000000000000000000C6 -:10CA700000000000000000000000000000000000B6 -:10CA800000000000000000000000000000000000A6 -:10CA90000000000000000000000000000000000096 -:10CAA0000000000000000000000000000000000086 -:10CAB0000000000000000000000000000000000076 -:10CAC0000000000000000000000000000000000066 -:10CAD0000000000000000000000000000000000056 -:10CAE0000000000000000000000000000000000046 -:10CAF0000000000000000000000000000000000036 -:10CB00000000000000000000000000000000000025 -:10CB10000000000000000000000000000000000015 -:10CB20000000000000000000000000000000000005 -:10CB300000000000000000000000000000000000F5 -:10CB400000000000000000000000000000000000E5 -:10CB500000000000000000000000000000000000D5 -:10CB600000000000000000000000000000000000C5 -:10CB700000000000000000000000000000000000B5 -:10CB800000000000000000000000000000000000A5 -:10CB90000000000000000000000000000000000095 -:10CBA0000000000000000000000000000000000085 -:10CBB0000000000000000000000000000000000075 -:10CBC0000000000000000000000000000000000065 -:10CBD0000000000000000000000000000000000055 -:10CBE0000000000000000000000000000000000045 -:10CBF0000000000000000000000000000000000035 -:10CC00000000000000000000000000000000000024 -:10CC10000000000000000000000000000000000014 -:10CC20000000000000000000000000000000000004 -:10CC300000000000000000000000000000000000F4 -:10CC400000000000000000000000000000000000E4 -:10CC500000000000000000000000000000000000D4 -:10CC600000000000000000000000000000000000C4 -:10CC700000000000000000000000000000000000B4 -:10CC800000000000000000000000000000000000A4 -:10CC90000000000000000000000000000000000094 -:10CCA0000000000000000000000000000000000084 -:10CCB0000000000000000000000000000000000074 -:10CCC0000000000000000000000000000000000064 -:10CCD0000000000000000000000000000000000054 -:10CCE0000000000000000000000000000000000044 -:10CCF0000000000000000000000000000000000034 -:10CD00000000000000000000000000000000000023 -:10CD10000000000000000000000000000000000013 -:10CD20000000000000000000000000000000000003 -:10CD300000000000000000000000000000000000F3 -:10CD400000000000000000000000000000000000E3 -:10CD500000000000000000000000000000000000D3 -:10CD600000000000000000000000000000000000C3 -:10CD700000000000000000000000000000000000B3 -:10CD800000000000000000000000000000000000A3 -:10CD90000000000000000000000000000000000093 -:10CDA0000000000000000000000000000000000083 -:10CDB0000000000000000000000000000000000073 -:10CDC0000000000000000000000000000000000063 -:10CDD0000000000000000000000000000000000053 -:10CDE0000000000000000000000000000000000043 -:10CDF0000000000000000000000000000000000033 -:10CE00000000000000000000000000000000000022 -:10CE10000000000000000000000000000000000012 -:10CE20000000000000000000000000000000000002 -:10CE300000000000000000000000000000000000F2 -:10CE400000000000000000000000000000000000E2 -:10CE500000000000000000000000000000000000D2 -:10CE600000000000000000000000000000000000C2 -:10CE700000000000000000000000000000000000B2 -:10CE800000000000000000000000000000000000A2 -:10CE90000000000000000000000000000000000092 -:10CEA0000000000000000000000000000000000082 -:10CEB0000000000000000000000000000000000072 -:10CEC0000000000000000000000000000000000062 -:10CED0000000000000000000000000000000000052 -:10CEE0000000000000000000000000000000000042 -:10CEF0000000000000000000000000000000000032 -:10CF00000000000000000000000000000000000021 -:10CF10000000000000000000000000000000000011 -:10CF20000000000000000000000000000000000001 -:10CF300000000000000000000000000000000000F1 -:10CF400000000000000000000000000000000000E1 -:10CF500000000000000000000000000000000000D1 -:10CF600000000000000000000000000000000000C1 -:10CF700000000000000000000000000000000000B1 -:10CF800000000000000000000000000000000000A1 -:10CF90000000000000000000000000000000000091 -:10CFA0000000000000000000000000000000000081 -:10CFB0000000000000000000000000000000000071 -:10CFC0000000000000000000000000000000000061 -:10CFD0000000000000000000000000000000000051 -:10CFE0000000000000000000000000000000000041 -:10CFF0000000000000000000000000000000000031 -:10D000000000000000000000000000000000000020 -:10D010000000000000000000000000000000000010 -:10D020000000000000000000000000000000000000 -:10D0300000000000000000000000000000000000F0 -:10D0400000000000000000000000000000000000E0 -:10D0500000000000000000000000000000000000D0 -:10D0600000000000000000000000000000000000C0 -:10D0700000000000000000000000000000000000B0 -:10D0800000000000000000000000000000000000A0 -:10D090000000000000000000000000000000000090 -:10D0A0000000000000000000000000000000000080 -:10D0B0000000000000000000000000000000000070 -:10D0C0000000000000000000000000000000000060 -:10D0D0000000000000000000000000000000000050 -:10D0E0000000000000000000000000000000000040 -:10D0F0000000000000000000000000000000000030 -:10D10000000000000000000000000000000000001F -:10D11000000000000000000000000000000000000F -:10D1200000000000000000000000000000000000FF -:10D1300000000000000000000000000000000000EF -:10D1400000000000000000000000000000000000DF -:10D1500000000000000000000000000000000000CF -:10D1600000000000000000000000000000000000BF -:10D1700000000000000000000000000000000000AF -:10D18000000000000000000000000000000000009F -:10D19000000000000000000000000000000000008F -:10D1A000000000000000000000000000000000007F -:10D1B000000000000000000000000000000000006F -:10D1C000000000000000000000000000000000005F -:10D1D000000000000000000000000000000000004F -:10D1E000000000000000000000000000000000003F -:10D1F000000000000000000000000000000000002F -:10D20000000000000000000000000000000000001E -:10D21000000000000000000000000000000000000E -:10D2200000000000000000000000000000000000FE -:10D2300000000000000000000000000000000000EE -:10D2400000000000000000000000000000000000DE -:10D2500000000000000000000000000000000000CE -:10D2600000000000000000000000000000000000BE -:10D2700000000000000000000000000000000000AE -:10D28000000000000000000000000000000000009E -:10D29000000000000000000000000000000000008E -:10D2A000000000000000000000000000000000007E -:10D2B000000000000000000000000000000000006E -:10D2C000000000000000000000000000000000005E -:10D2D000000000000000000000000000000000004E -:10D2E000000000000000000000000000000000003E -:10D2F000000000000000000000000000000000002E -:10D30000000000000000000000000000000000001D -:10D31000000000000000000000000000000000000D -:10D3200000000000000000000000000000000000FD -:10D3300000000000000000000000000000000000ED -:10D3400000000000000000000000000000000000DD -:10D3500000000000000000000000000000000000CD -:10D3600000000000000000000000000000000000BD -:10D3700000000000000000000000000000000000AD -:10D38000000000000000000000000000000000009D -:10D39000000000000000000000000000000000008D -:10D3A000000000000000000000000000000000007D -:10D3B000000000000000000000000000000000006D -:10D3C000000000000000000000000000000000005D -:10D3D000000000000000000000000000000000004D -:10D3E000000000000000000000000000000000003D -:10D3F000000000000000000000000000000000002D -:10D40000000000000000000000000000000000001C -:10D41000000000000000000000000000000000000C -:10D4200000000000000000000000000000000000FC -:10D4300000000000000000000000000000000000EC -:10D4400000000000000000000000000000000000DC -:10D4500000000000000000000000000000000000CC -:10D4600000000000000000000000000000000000BC -:10D4700000000000000000000000000000000000AC -:10D48000000000000000000000000000000000009C -:10D49000000000000000000000000000000000008C -:10D4A000000000000000000000000000000000007C -:10D4B000000000000000000000000000000000006C -:10D4C000000000000000000000000000000000005C -:10D4D000000000000000000000000000000000004C -:10D4E000000000000000000000000000000000003C -:10D4F000000000000000000000000000000000002C -:10D50000000000000000000000000000000000001B -:10D51000000000000000000000000000000000000B -:10D5200000000000000000000000000000000000FB -:10D5300000000000000000000000000000000000EB -:10D5400000000000000000000000000000000000DB -:10D5500000000000000000000000000000000000CB -:10D5600000000000000000000000000000000000BB -:10D5700000000000000000000000000000000000AB -:10D58000000000000000000000000000000000009B -:10D59000000000000000000000000000000000008B -:10D5A000000000000000000000000000000000007B -:10D5B000000000000000000000000000000000006B -:10D5C000000000000000000000000000000000005B -:10D5D000000000000000000000000000000000004B -:10D5E000000000000000000000000000000000003B -:10D5F000000000000000000000000000000000002B -:10D60000000000000000000000000000000000001A -:10D61000000000000000000000000000000000000A -:10D6200000000000000000000000000000000000FA -:10D6300000000000000000000000000000000000EA -:10D6400000000000000000000000000000000000DA -:10D6500000000000000000000000000000000000CA -:10D6600000000000000000000000000000000000BA -:10D6700000000000000000000000000000000000AA -:10D68000000000000000000000000000000000009A -:10D69000000000000000000000000000000000008A -:10D6A000000000000000000000000000000000007A -:10D6B000000000000000000000000000000000006A -:10D6C000000000000000000000000000000000005A -:10D6D000000000000000000000000000000000004A -:10D6E000000000000000000000000000000000003A -:10D6F000000000000000000000000000000000002A -:10D700000000000000000000000000000000000019 -:10D710000000000000000000000000000000000009 -:10D7200000000000000000000000000000000000F9 -:10D7300000000000000000000000000000000000E9 -:10D7400000000000000000000000000000000000D9 -:10D7500000000000000000000000000000000000C9 -:10D7600000000000000000000000000000000000B9 -:10D7700000000000000000000000000000000000A9 -:10D780000000000000000000000000000000000099 -:10D790000000000000000000000000000000000089 -:10D7A0000000000000000000000000000000000079 -:10D7B0000000000000000000000000000000000069 -:10D7C0000000000000000000000000000000000059 -:10D7D0000000000000000000000000000000000049 -:10D7E0000000000000000000000000000000000039 -:10D7F0000000000000000000000000000000000029 -:10D800000000000000000000000000000000000018 -:10D810000000000000000000000000000000000008 -:10D8200000000000000000000000000000000000F8 -:10D8300000000000000000000000000000000000E8 -:10D8400000000000000000000000000000000000D8 -:10D8500000000000000000000000000000000000C8 -:10D8600000000000000000000000000000000000B8 -:10D8700000000000000000000000000000000000A8 -:10D880000000000000000000000000000000000098 -:10D890000000000000000000000000000000000088 -:10D8A0000000000000000000000000000000000078 -:10D8B0000000000000000000000000000000000068 -:10D8C0000000000000000000000000000000000058 -:10D8D0000000000000000000000000000000000048 -:10D8E0000000000000000000000000000000000038 -:10D8F0000000000000000000000000000000000028 -:10D900000000000000000000000000000000000017 -:10D910000000000000000000000000000000000007 -:10D9200000000000000000000000000000000000F7 -:10D9300000000000000000000000000000000000E7 -:10D9400000000000000000000000000000000000D7 -:10D9500000000000000000000000000000000000C7 -:10D9600000000000000000000000000000000000B7 -:10D9700000000000000000000000000000000000A7 -:10D980000000000000000000000000000000000097 -:10D990000000000000000000000000000000000087 -:10D9A0000000000000000000000000000000000077 -:10D9B0000000000000000000000000000000000067 -:10D9C0000000000000000000000000000000000057 -:10D9D0000000000000000000000000000000000047 -:10D9E0000000000000000000000000000000000037 -:10D9F0000000000000000000000000000000000027 -:10DA00000000000000000000000000000000000016 -:10DA10000000000000000000000000000000000006 -:10DA200000000000000000000000000000000000F6 -:10DA300000000000000000000000000000000000E6 -:10DA400000000000000000000000000000000000D6 -:10DA500000000000000000000000000000000000C6 -:10DA600000000000000000000000000000000000B6 -:10DA700000000000000000000000000000000000A6 -:10DA80000000000000000000000000000000000096 -:10DA90000000000000000000000000000000000086 -:10DAA0000000000000000000000000000000000076 -:10DAB0000000000000000000000000000000000066 -:10DAC0000000000000000000000000000000000056 -:10DAD0000000000000000000000000000000000046 -:10DAE0000000000000000000000000000000000036 -:10DAF0000000000000000000000000000000000026 -:10DB00000000000000000000000000000000000015 -:10DB10000000000000000000000000000000000005 -:10DB200000000000000000000000000000000000F5 -:10DB300000000000000000000000000000000000E5 -:10DB400000000000000000000000000000000000D5 -:10DB500000000000000000000000000000000000C5 -:10DB600000000000000000000000000000000000B5 -:10DB700000000000000000000000000000000000A5 -:10DB80000000000000000000000000000000000095 -:10DB90000000000000000000000000000000000085 -:10DBA0000000000000000000000000000000000075 -:10DBB0000000000000000000000000000000000065 -:10DBC0000000000000000000000000000000000055 -:10DBD0000000000000000000000000000000000045 -:10DBE0000000000000000000000000000000000035 -:10DBF0000000000000000000000000000000000025 -:10DC00000000000000000000000000000000000014 -:10DC10000000000000000000000000000000000004 -:10DC200000000000000000000000000000000000F4 -:10DC300000000000000000000000000000000000E4 -:10DC400000000000000000000000000000000000D4 -:10DC500000000000000000000000000000000000C4 -:10DC600000000000000000000000000000000000B4 -:10DC700000000000000000000000000000000000A4 -:10DC80000000000000000000000000000000000094 -:10DC90000000000000000000000000000000000084 -:10DCA0000000000000000000000000000000000074 -:10DCB0000000000000000000000000000000000064 -:10DCC0000000000000000000000000000000000054 -:10DCD0000000000000000000000000000000000044 -:10DCE0000000000000000000000000000000000034 -:10DCF0000000000000000000000000000000000024 -:10DD00000000000000000000000000000000000013 -:10DD10000000000000000000000000000000000003 -:10DD200000000000000000000000000000000000F3 -:10DD300000000000000000000000000000000000E3 -:10DD400000000000000000000000000000000000D3 -:10DD500000000000000000000000000000000000C3 -:10DD600000000000000000000000000000000000B3 -:10DD700000000000000000000000000000000000A3 -:10DD80000000000000000000000000000000000093 -:10DD90000000000000000000000000000000000083 -:10DDA0000000000000000000000000000000000073 -:10DDB0000000000000000000000000000000000063 -:10DDC0000000000000000000000000000000000053 -:10DDD0000000000000000000000000000000000043 -:10DDE0000000000000000000000000000000000033 -:10DDF0000000000000000000000000000000000023 -:10DE00000000000000000000000000000000000012 -:10DE10000000000000000000000000000000000002 -:10DE200000000000000000000000000000000000F2 -:10DE300000000000000000000000000000000000E2 -:10DE400000000000000000000000000000000000D2 -:10DE500000000000000000000000000000000000C2 -:10DE600000000000000000000000000000000000B2 -:10DE700000000000000000000000000000000000A2 -:10DE80000000000000000000000000000000000092 -:10DE90000000000000000000000000000000000082 -:10DEA0000000000000000000000000000000000072 -:10DEB0000000000000000000000000000000000062 -:10DEC0000000000000000000000000000000000052 -:10DED0000000000000000000000000000000000042 -:10DEE0000000000000000000000000000000000032 -:10DEF0000000000000000000000000000000000022 -:10DF00000000000000000000000000000000000011 -:10DF10000000000000000000000000000000000001 -:10DF200000000000000000000000000000000000F1 -:10DF300000000000000000000000000000000000E1 -:10DF400000000000000000000000000000000000D1 -:10DF500000000000000000000000000000000000C1 -:10DF600000000000000000000000000000000000B1 -:10DF700000000000000000000000000000000000A1 -:10DF80000000000000000000000000000000000091 -:10DF90000000000000000000000000000000000081 -:10DFA0000000000000000000000000000000000071 -:10DFB0000000000000000000000000000000000061 -:10DFC0000000000000000000000000000000000051 -:10DFD0000000000000000000000000000000000041 -:10DFE0000000000000000000000000000000000031 -:10DFF0000000000000000000000000000000000021 -:10E000000000000000000000000000000000000010 -:10E010000000000000000000000000000000000000 -:10E0200000000000000000000000000000000000F0 -:10E0300000000000000000000000000000000000E0 -:10E0400000000000000000000000000000000000D0 -:10E0500000000000000000000000000000000000C0 -:10E0600000000000000000000000000000000000B0 -:10E0700000000000000000000000000000000000A0 -:10E080000000000000000000000000000000000090 -:10E090000000000000000000000000000000000080 -:10E0A0000000000000000000000000000000000070 -:10E0B0000000000000000000000000000000000060 -:10E0C0000000000000000000000000000000000050 -:10E0D0000000000000000000000000000000000040 -:10E0E0000000000000000000000000000000000030 -:10E0F0000000000000000000000000000000000020 -:10E10000000000000000000000000000000000000F -:10E1100000000000000000000000000000000000FF -:10E1200000000000000000000000000000000000EF -:10E1300000000000000000000000000000000000DF -:10E1400000000000000000000000000000000000CF -:10E1500000000000000000000000000000000000BF -:10E1600000000000000000000000000000000000AF -:10E17000000000000000000000000000000000009F -:10E18000000000000000000000000000000000008F -:10E19000000000000000000000000000000000007F -:10E1A000000000000000000000000000000000006F -:10E1B000000000000000000000000000000000005F -:10E1C000000000000000000000000000000000004F -:10E1D000000000000000000000000000000000003F -:10E1E000000000000000000000000000000000002F -:10E1F000000000000000000000000000000000001F -:10E20000000000000000000000000000000000000E -:10E2100000000000000000000000000000000000FE -:10E2200000000000000000000000000000000000EE -:10E2300000000000000000000000000000000000DE -:10E2400000000000000000000000000000000000CE -:10E2500000000000000000000000000000000000BE -:10E2600000000000000000000000000000000000AE -:10E27000000000000000000000000000000000009E -:10E28000000000000000000000000000000000008E -:10E29000000000000000000000000000000000007E -:10E2A000000000000000000000000000000000006E -:10E2B000000000000000000000000000000000005E -:10E2C000000000000000000000000000000000004E -:10E2D000000000000000000000000000000000003E -:10E2E000000000000000000000000000000000002E -:10E2F000000000000000000000000000000000001E -:10E30000000000000000000000000000000000000D -:10E3100000000000000000000000000000000000FD -:10E3200000000000000000000000000000000000ED -:10E3300000000000000000000000000000000000DD -:10E3400000000000000000000000000000000000CD -:10E3500000000000000000000000000000000000BD -:10E3600000000000000000000000000000000000AD -:10E37000000000000000000000000000000000009D -:10E38000000000000000000000000000000000008D -:10E39000000000000000000000000000000000007D -:10E3A000000000000000000000000000000000006D -:10E3B000000000000000000000000000000000005D -:10E3C000000000000000000000000000000000004D -:10E3D000000000000000000000000000000000003D -:10E3E000000000000000000000000000000000002D -:10E3F000000000000000000000000000000000001D -:10E40000000000000000000000000000000000000C -:10E4100000000000000000000000000000000000FC -:10E4200000000000000000000000000000000000EC -:10E4300000000000000000000000000000000000DC -:10E4400000000000000000000000000000000000CC -:10E4500000000000000000000000000000000000BC -:10E4600000000000000000000000000000000000AC -:10E47000000000000000000000000000000000009C -:10E48000000000000000000000000000000000008C -:10E49000000000000000000000000000000000007C -:10E4A000000000000000000000000000000000006C -:10E4B000000000000000000000000000000000005C -:10E4C000000000000000000000000000000000004C -:10E4D000000000000000000000000000000000003C -:10E4E000000000000000000000000000000000002C -:10E4F000000000000000000000000000000000001C -:10E50000000000000000000000000000000000000B -:10E5100000000000000000000000000000000000FB -:10E5200000000000000000000000000000000000EB -:10E5300000000000000000000000000000000000DB -:10E5400000000000000000000000000000000000CB -:10E5500000000000000000000000000000000000BB -:10E5600000000000000000000000000000000000AB -:10E57000000000000000000000000000000000009B -:10E58000000000000000000000000000000000008B -:10E59000000000000000000000000000000000007B -:10E5A000000000000000000000000000000000006B -:10E5B000000000000000000000000000000000005B -:10E5C000000000000000000000000000000000004B -:10E5D000000000000000000000000000000000003B -:10E5E000000000000000000000000000000000002B -:10E5F000000000000000000000000000000000001B -:10E60000000000000000000000000000000000000A -:10E6100000000000000000000000000000000000FA -:10E6200000000000000000000000000000000000EA -:10E6300000000000000000000000000000000000DA -:10E6400000000000000000000000000000000000CA -:10E6500000000000000000000000000000000000BA -:10E6600000000000000000000000000000000000AA -:10E67000000000000000000000000000000000009A -:10E68000000000000000000000000000000000008A -:10E69000000000000000000000000000000000007A -:10E6A000000000000000000000000000000000006A -:10E6B000000000000000000000000000000000005A -:10E6C000000000000000000000000000000000004A -:10E6D000000000000000000000000000000000003A -:10E6E000000000000000000000000000000000002A -:10E6F000000000000000000000000000000000001A -:10E700000000000000000000000000000000000009 -:10E7100000000000000000000000000000000000F9 -:10E7200000000000000000000000000000000000E9 -:10E7300000000000000000000000000000000000D9 -:10E7400000000000000000000000000000000000C9 -:10E7500000000000000000000000000000000000B9 -:10E7600000000000000000000000000000000000A9 -:10E770000000000000000000000000000000000099 -:10E780000000000000000000000000000000000089 -:10E790000000000000000000000000000000000079 -:10E7A0000000000000000000000000000000000069 -:10E7B0000000000000000000000000000000000059 -:10E7C0000000000000000000000000000000000049 -:10E7D0000000000000000000000000000000000039 -:10E7E0000000000000000000000000000000000029 -:10E7F0000000000000000000000000000000000019 -:10E800000000000000000000000000000000000008 -:10E8100000000000000000000000000000000000F8 -:10E8200000000000000000000000000000000000E8 -:10E8300000000000000000000000000000000000D8 -:10E8400000000000000000000000000000000000C8 -:10E8500000000000000000000000000000000000B8 -:10E8600000000000000000000000000000000000A8 -:10E870000000000000000000000000000000000098 -:10E880000000000000000000000000000000000088 -:10E890000000000000000000000000000000000078 -:10E8A0000000000000000000000000000000000068 -:10E8B0000000000000000000000000000000000058 -:10E8C0000000000000000000000000000000000048 -:10E8D0000000000000000000000000000000000038 -:10E8E0000000000000000000000000000000000028 -:10E8F0000000000000000000000000000000000018 -:10E900000000000000000000000000000000000007 -:10E9100000000000000000000000000000000000F7 -:10E9200000000000000000000000000000000000E7 -:10E9300000000000000000000000000000000000D7 -:10E9400000000000000000000000000000000000C7 -:10E9500000000000000000000000000000000000B7 -:10E9600000000000000000000000000000000000A7 -:10E970000000000000000000000000000000000097 -:10E980000000000000000000000000000000000087 -:10E990000000000000000000000000000000000077 -:10E9A0000000000000000000000000000000000067 -:10E9B0000000000000000000000000000000000057 -:10E9C0000000000000000000000000000000000047 -:10E9D0000000000000000000000000000000000037 -:10E9E0000000000000000000000000000000000027 -:10E9F0000000000000000000000000000000000017 -:10EA00000000000000000000000000000000000006 -:10EA100000000000000000000000000000000000F6 -:10EA200000000000000000000000000000000000E6 -:10EA300000000000000000000000000000000000D6 -:10EA400000000000000000000000000000000000C6 -:10EA500000000000000000000000000000000000B6 -:10EA600000000000000000000000000000000000A6 -:10EA70000000000000000000000000000000000096 -:10EA80000000000000000000000000000000000086 -:10EA90000000000000000000000000000000000076 -:10EAA0000000000000000000000000000000000066 -:10EAB0000000000000000000000000000000000056 -:10EAC0000000000000000000000000000000000046 -:10EAD0000000000000000000000000000000000036 -:10EAE0000000000000000000000000000000000026 -:10EAF0000000000000000000000000000000000016 -:10EB00000000000000000000000000000000000005 -:10EB100000000000000000000000000000000000F5 -:10EB200000000000000000000000000000000000E5 -:10EB300000000000000000000000000000000000D5 -:10EB400000000000000000000000000000000000C5 -:10EB500000000000000000000000000000000000B5 -:10EB600000000000000000000000000000000000A5 -:10EB70000000000000000000000000000000000095 -:10EB80000000000000000000000000000000000085 -:10EB90000000000000000000000000000000000075 -:10EBA0000000000000000000000000000000000065 -:10EBB0000000000000000000000000000000000055 -:10EBC0000000000000000000000000000000000045 -:10EBD0000000000000000000000000000000000035 -:10EBE0000000000000000000000000000000000025 -:10EBF0000000000000000000000000000000000015 -:10EC00000000000000000000000000000000000004 -:10EC100000000000000000000000000000000000F4 -:10EC200000000000000000000000000000000000E4 -:10EC300000000000000000000000000000000000D4 -:10EC400000000000000000000000000000000000C4 -:10EC500000000000000000000000000000000000B4 -:10EC600000000000000000000000000000000000A4 -:10EC70000000000000000000000000000000000094 -:10EC80000000000000000000000000000000000084 -:10EC90000000000000000000000000000000000074 -:10ECA0000000000000000000000000000000000064 -:10ECB0000000000000000000000000000000000054 -:10ECC0000000000000000000000000000000000044 -:10ECD0000000000000000000000000000000000034 -:10ECE0000000000000000000000000000000000024 -:10ECF0000000000000000000000000000000000014 -:10ED00000000000000000000000000000000000003 -:10ED100000000000000000000000000000000000F3 -:10ED200000000000000000000000000000000000E3 -:10ED300000000000000000000000000000000000D3 -:10ED400000000000000000000000000000000000C3 -:10ED500000000000000000000000000000000000B3 -:10ED600000000000000000000000000000000000A3 -:10ED70000000000000000000000000000000000093 -:10ED80000000000000000000000000000000000083 -:10ED90000000000000000000000000000000000073 -:10EDA0000000000000000000000000000000000063 -:10EDB0000000000000000000000000000000000053 -:10EDC0000000000000000000000000000000000043 -:10EDD0000000000000000000000000000000000033 -:10EDE0000000000000000000000000000000000023 -:10EDF0000000000000000000000000000000000013 -:10EE00000000000000000000000000000000000002 -:10EE100000000000000000000000000000000000F2 -:10EE200000000000000000000000000000000000E2 -:10EE300000000000000000000000000000000000D2 -:10EE400000000000000000000000000000000000C2 -:10EE500000000000000000000000000000000000B2 -:10EE600000000000000000000000000000000000A2 -:10EE70000000000000000000000000000000000092 -:10EE80000000000000000000000000000000000082 -:10EE90000000000000000000000000000000000072 -:10EEA0000000000000000000000000000000000062 -:10EEB0000000000000000000000000000000000052 -:10EEC0000000000000000000000000000000000042 -:10EED0000000000000000000000000000000000032 -:10EEE0000000000000000000000000000000000022 -:10EEF0000000000000000000000000000000000012 -:10EF00000000000000000000000000000000000001 -:10EF100000000000000000000000000000000000F1 -:10EF200000000000000000000000000000000000E1 -:10EF300000000000000000000000000000000000D1 -:10EF400000000000000000000000000000000000C1 -:10EF500000000000000000000000000000000000B1 -:10EF600000000000000000000000000000000000A1 -:10EF70000000000000000000000000000000000091 -:10EF80000000000000000000000000000000000081 -:10EF90000000000000000000000000000000000071 -:10EFA0000000000000000000000000000000000061 -:10EFB0000000000000000000000000000000000051 -:10EFC0000000000000000000000000000000000041 -:10EFD0000000000000000000000000000000000031 -:10EFE0000000000000000000000000000000000021 -:10EFF0000000000000000000000000000000000011 -:10F000000000000000000000000000000000000000 -:10F0100000000000000000000000000000000000F0 -:10F0200000000000000000000000000000000000E0 -:10F0300000000000000000000000000000000000D0 -:10F0400000000000000000000000000000000000C0 -:10F0500000000000000000000000000000000000B0 -:10F0600000000000000000000000000000000000A0 -:10F070000000000000000000000000000000000090 -:10F080000000000000000000000000000000000080 -:10F090000000000000000000000000000000000070 -:10F0A0000000000000000000000000000000000060 -:10F0B0000000000000000000000000000000000050 -:10F0C0000000000000000000000000000000000040 -:10F0D0000000000000000000000000000000000030 -:10F0E0000000000000000000000000000000000020 -:10F0F0000000000000000000000000000000000010 -:10F1000000000000000000000000000000000000FF -:10F1100000000000000000000000000000000000EF -:10F1200000000000000000000000000000000000DF -:10F1300000000000000000000000000000000000CF -:10F1400000000000000000000000000000000000BF -:10F1500000000000000000000000000000000000AF -:10F16000000000000000000000000000000000009F -:10F17000000000000000000000000000000000008F -:10F18000000000000000000000000000000000007F -:10F19000000000000000000000000000000000006F -:10F1A000000000000000000000000000000000005F -:10F1B000000000000000000000000000000000004F -:10F1C000000000000000000000000000000000003F -:10F1D000000000000000000000000000000000002F -:10F1E000000000000000000000000000000000001F -:10F1F000000000000000000000000000000000000F -:10F2000000000000000000000000000000000000FE -:10F2100000000000000000000000000000000000EE -:10F2200000000000000000000000000000000000DE -:10F2300000000000000000000000000000000000CE -:10F2400000000000000000000000000000000000BE -:10F2500000000000000000000000000000000000AE -:10F26000000000000000000000000000000000009E -:10F27000000000000000000000000000000000008E -:10F28000000000000000000000000000000000007E -:10F29000000000000000000000000000000000006E -:10F2A000000000000000000000000000000000005E -:10F2B000000000000000000000000000000000004E -:10F2C000000000000000000000000000000000003E -:10F2D000000000000000000000000000000000002E -:10F2E000000000000000000000000000000000001E -:10F2F000000000000000000000000000000000000E -:10F3000000000000000000000000000000000000FD -:10F3100000000000000000000000000000000000ED -:10F3200000000000000000000000000000000000DD -:10F3300000000000000000000000000000000000CD -:10F3400000000000000000000000000000000000BD -:10F3500000000000000000000000000000000000AD -:10F36000000000000000000000000000000000009D -:10F37000000000000000000000000000000000008D -:10F38000000000000000000000000000000000007D -:10F39000000000000000000000000000000000006D -:10F3A000000000000000000000000000000000005D -:10F3B000000000000000000000000000000000004D -:10F3C000000000000000000000000000000000003D -:10F3D000000000000000000000000000000000002D -:10F3E000000000000000000000000000000000001D -:10F3F000000000000000000000000000000000000D -:10F4000000000000000000000000000000000000FC -:10F4100000000000000000000000000000000000EC -:10F4200000000000000000000000000000000000DC -:10F4300000000000000000000000000000000000CC -:10F4400000000000000000000000000000000000BC -:10F4500000000000000000000000000000000000AC -:10F46000000000000000000000000000000000009C -:10F47000000000000000000000000000000000008C -:10F48000000000000000000000000000000000007C -:10F49000000000000000000000000000000000006C -:10F4A000000000000000000000000000000000005C -:10F4B000000000000000000000000000000000004C -:10F4C000000000000000000000000000000000003C -:10F4D000000000000000000000000000000000002C -:10F4E000000000000000000000000000000000001C -:10F4F000000000000000000000000000000000000C -:10F5000000000000000000000000000000000000FB -:10F5100000000000000000000000000000000000EB -:10F5200000000000000000000000000000000000DB -:10F5300000000000000000000000000000000000CB -:10F5400000000000000000000000000000000000BB -:10F5500000000000000000000000000000000000AB -:10F56000000000000000000000000000000000009B -:10F57000000000000000000000000000000000008B -:10F58000000000000000000000000000000000007B -:10F59000000000000000000000000000000000006B -:10F5A000000000000000000000000000000000005B -:10F5B000000000000000000000000000000000004B -:10F5C000000000000000000000000000000000003B -:10F5D000000000000000000000000000000000002B -:10F5E000000000000000000000000000000000001B -:10F5F000000000000000000000000000000000000B -:10F6000000000000000000000000000000000000FA -:10F6100000000000000000000000000000000000EA -:10F6200000000000000000000000000000000000DA -:10F6300000000000000000000000000000000000CA -:10F6400000000000000000000000000000000000BA -:10F6500000000000000000000000000000000000AA -:10F66000000000000000000000000000000000009A -:10F67000000000000000000000000000000000008A -:10F68000000000000000000000000000000000007A -:10F69000000000000000000000000000000000006A -:10F6A000000000000000000000000000000000005A -:10F6B000000000000000000000000000000000004A -:10F6C000000000000000000000000000000000003A -:10F6D000000000000000000000000000000000002A -:10F6E000000000000000000000000000000000001A -:10F6F000000000000000000000000000000000000A -:10F7000000000000000000000000000000000000F9 -:10F7100000000000000000000000000000000000E9 -:10F7200000000000000000000000000000000000D9 -:10F7300000000000000000000000000000000000C9 -:10F7400000000000000000000000000000000000B9 -:10F7500000000000000000000000000000000000A9 -:10F760000000000000000000000000000000000099 -:10F770000000000000000000000000000000000089 -:10F780000000000000000000000000000000000079 -:10F790000000000000000000000000000000000069 -:10F7A0000000000000000000000000000000000059 -:10F7B0000000000000000000000000000000000049 -:10F7C0000000000000000000000000000000000039 -:10F7D0000000000000000000000000000000000029 -:10F7E0000000000000000000000000000000000019 -:10F7F0000000000000000000000000000000000009 -:10F8000000000000000000000000000000000000F8 -:10F8100000000000000000000000000000000000E8 -:10F8200000000000000000000000000000000000D8 -:10F8300000000000000000000000000000000000C8 -:10F8400000000000000000000000000000000000B8 -:10F8500000000000000000000000000000000000A8 -:10F860000000000000000000000000000000000098 -:10F870000000000000000000000000000000000088 -:10F880000000000000000000000000000000000078 -:10F890000000000000000000000000000000000068 -:10F8A0000000000000000000000000000000000058 -:10F8B0000000000000000000000000000000000048 -:10F8C0000000000000000000000000000000000038 -:10F8D0000000000000000000000000000000000028 -:10F8E0000000000000000000000000000000000018 -:10F8F0000000000000000000000000000000000008 -:10F9000000000000000000000000000000000000F7 -:10F9100000000000000000000000000000000000E7 -:10F9200000000000000000000000000000000000D7 -:10F9300000000000000000000000000000000000C7 -:10F9400000000000000000000000000000000000B7 -:10F9500000000000000000000000000000000000A7 -:10F960000000000000000000000000000000000097 -:10F970000000000000000000000000000000000087 -:10F980000000000000000000000000000000000077 -:10F990000000000000000000000000000000000067 -:10F9A0000000000000000000000000000000000057 -:10F9B0000000000000000000000000000000000047 -:10F9C0000000000000000000000000000000000037 -:10F9D0000000000000000000000000000000000027 -:10F9E0000000000000000000000000000000000017 -:10F9F0000000000000000000000000000000000007 -:10FA000000000000000000000000000000000000F6 -:10FA100000000000000000000000000000000000E6 -:10FA200000000000000000000000000000000000D6 -:10FA300000000000000000000000000000000000C6 -:10FA400000000000000000000000000000000000B6 -:10FA500000000000000000000000000000000000A6 -:10FA60000000000000000000000000000000000096 -:10FA70000000000000000000000000000000000086 -:10FA80000000000000000000000000000000000076 -:10FA90000000000000000000000000000000000066 -:10FAA0000000000000000000000000000000000056 -:10FAB0000000000000000000000000000000000046 -:10FAC0000000000000000000000000000000000036 -:10FAD0000000000000000000000000000000000026 -:10FAE0000000000000000000000000000000000016 -:10FAF0000000000000000000000000000000000006 -:10FB000000000000000000000000000000000000F5 -:10FB100000000000000000000000000000000000E5 -:10FB200000000000000000000000000000000000D5 -:10FB300000000000000000000000000000000000C5 -:10FB400000000000000000000000000000000000B5 -:10FB500000000000000000000000000000000000A5 -:10FB60000000000000000000000000000000000095 -:10FB70000000000000000000000000000000000085 -:10FB80000000000000000000000000000000000075 -:10FB90000000000000000000000000000000000065 -:10FBA0000000000000000000000000000000000055 -:10FBB0000000000000000000000000000000000045 -:10FBC0000000000000000000000000000000000035 -:10FBD0000000000000000000000000000000000025 -:10FBE0000000000000000000000000000000000015 -:10FBF0000000000000000000000000000000000005 -:10FC000000000000000000000000000000000000F4 -:10FC100000000000000000000000000000000000E4 -:10FC200000000000000000000000000000000000D4 -:10FC300000000000000000000000000000000000C4 -:10FC400000000000000000000000000000000000B4 -:10FC500000000000000000000000000000000000A4 -:10FC60000000000000000000000000000000000094 -:10FC70000000000000000000000000000000000084 -:10FC80000000000000000000000000000000000074 -:10FC90000000000000000000000000000000000064 -:10FCA0000000000000000000000000000000000054 -:10FCB0000000000000000000000000000000000044 -:10FCC0000000000000000000000000000000000034 -:10FCD0000000000000000000000000000000000024 -:10FCE0000000000000000000000000000000000014 -:10FCF0000000000000000000000000000000000004 -:10FD000000000000000000000000000000000000F3 -:10FD100000000000000000000000000000000000E3 -:10FD200000000000000000000000000000000000D3 -:10FD300000000000000000000000000000000000C3 -:10FD400000000000000000000000000000000000B3 -:10FD500000000000000000000000000000000000A3 -:10FD60000000000000000000000000000000000093 -:10FD70000000000000000000000000000000000083 -:10FD80000000000000000000000000000000000073 -:10FD90000000000000000000000000000000000063 -:10FDA0000000000000000000000000000000000053 -:10FDB0000000000000000000000000000000000043 -:10FDC0000000000000000000000000000000000033 -:10FDD0000000000000000000000000000000000023 -:10FDE0000000000000000000000000000000000013 -:10FDF0000000000000000000000000000000000003 -:10FE000000000000000000000000000000000000F2 -:10FE100000000000000000000000000000000000E2 -:10FE200000000000000000000000000000000000D2 -:10FE300000000000000000000000000000000000C2 -:10FE400000000000000000000000000000000000B2 -:10FE500000000000000000000000000000000000A2 -:10FE60000000000000000000000000000000000092 -:10FE70000000000000000000000000000000000082 -:10FE80000000000000000000000000000000000072 -:10FE90000000000000000000000000000000000062 -:10FEA0000000000000000000000000000000000052 -:10FEB0000000000000000000000000000000000042 -:10FEC0000000000000000000000000000000000032 -:10FED0000000000000000000000000000000000022 -:10FEE0000000000000000000000000000000000012 -:10FEF0000000000000000000000000000000000002 -:10FF000000000000000000000000000000000000F1 -:10FF100000000000000000000000000000000000E1 -:10FF200000000000000000000000000000000000D1 -:10FF300000000000000000000000000000000000C1 -:10FF400000000000000000000000000000000000B1 -:10FF500000000000000000000000000000000000A1 -:10FF60000000000000000000000000000000000091 -:10FF70000000000000000000000000000000000081 -:10FF80000000000000000000000000000000000071 -:10FF90000000000000000000000000000000000061 -:10FFA0000000000000000000000000000000000051 -:10FFB0000000000000000000000000000000000041 -:10FFC0000000000000000000000000000000000031 -:10FFD0000000000000000000000000000000000021 -:10FFE0000000000000000000000000000000000011 -:10FFF0000000000000000000000000000000000001 -:02000004620692 -:1000000000000000000000000000000000000000F0 -:1000100000000000000000000000000000000000E0 -:1000200000000000000000000000000000000000D0 -:1000300000000000000000000000000000000000C0 -:1000400000000000000000000000000000000000B0 -:1000500000000000000000000000000000000000A0 -:100060000000000000000000000000000000000090 -:100070000000000000000000000000000000000080 -:100080000000000000000000000000000000000070 -:100090000000000000000000000000000000000060 -:1000A0000000000000000000000000000000000050 -:1000B0000000000000000000000000000000000040 -:1000C0000000000000000000000000000000000030 -:1000D0000000000000000000000000000000000020 -:1000E0000000000000000000000000000000000010 -:1000F0000000000000000000000000000000000000 -:1001000000000000000000000000000000000000EF -:1001100000000000000000000000000000000000DF -:1001200000000000000000000000000000000000CF -:1001300000000000000000000000000000000000BF -:1001400000000000000000000000000000000000AF -:10015000000000000000000000000000000000009F -:10016000000000000000000000000000000000008F -:10017000000000000000000000000000000000007F -:10018000000000000000000000000000000000006F -:0C01900000000000000000000000000063 -:040000056200004055 -:00000001FF diff --git a/testing/examples/STR710JtagSpeed/test.map b/testing/examples/STR710JtagSpeed/test.map deleted file mode 100644 index 5d3b1e7ca..000000000 --- a/testing/examples/STR710JtagSpeed/test.map +++ /dev/null @@ -1,170 +0,0 @@ - -Memory Configuration - -Name Origin Length Attributes -ram 0x62000000 0x00080000 -*default* 0x00000000 0xffffffff - -Linker script and memory map - -LOAD ./src/crt.o -LOAD ./src/main.o -START GROUP -LOAD d:/compiler/yagarto/bin/../lib/gcc/arm-elf/4.2.2\libgcc.a -LOAD d:/compiler/yagarto/bin/../lib/gcc/arm-elf/4.2.2/../../../../arm-elf/lib\libc.a -END GROUP - 0x00000100 FIQ_STACK_SIZE = 0x100 - 0x00000100 IRQ_STACK_SIZE = 0x100 - 0x00000100 ABT_STACK_SIZE = 0x100 - 0x00000100 UND_STACK_SIZE = 0x100 - 0x00000400 SVC_STACK_SIZE = 0x400 - -.text 0x62000000 0x6019c - *(.vectors) - .vectors 0x62000000 0x40 ./src/crt.o - 0x62000040 . = ALIGN (0x4) - *(.init) - .init 0x62000040 0x114 ./src/crt.o - 0x62000128 FIQHandler - 0x6200011c PAbortHandler - 0x62000104 ExitFunction - 0x62000040 ResetHandler - 0x62000120 DAbortHandler - 0x62000124 IRQHandler - 0x62000114 UndefHandler - 0x62000154 . = ALIGN (0x4) - *(.text) - .text 0x62000154 0x0 ./src/crt.o - .text 0x62000154 0x48 ./src/main.o - 0x62000154 main - 0x6200019c . = ALIGN (0x4) - *(.rodata) - .rodata 0x6200019c 0x60000 ./src/main.o - 0x6206019c . = ALIGN (0x4) - *(.rodata*) - 0x6206019c . = ALIGN (0x4) - *(.glue_7t) - .glue_7t 0x6206019c 0x0 ./src/crt.o - .glue_7t 0x6206019c 0x0 ./src/main.o - 0x6206019c . = ALIGN (0x4) - *(.glue_7) - .glue_7 0x6206019c 0x0 ./src/crt.o - .glue_7 0x6206019c 0x0 ./src/main.o - 0x6206019c . = ALIGN (0x4) - 0x6206019c etext = . - -.vfp11_veneer 0x00000000 0x0 - .vfp11_veneer 0x00000000 0x0 ./src/crt.o - .vfp11_veneer 0x00000000 0x0 ./src/main.o - -.data 0x6206019c 0x0 - 0x6206019c PROVIDE (__data_start, .) - *(.data) - .data 0x6206019c 0x0 ./src/crt.o - .data 0x6206019c 0x0 ./src/main.o - 0x6206019c . = ALIGN (0x4) - 0x6206019c edata = . - 0x6206019c _edata = . - 0x6206019c PROVIDE (__data_end, .) - -.bss 0x6206019c 0x864 - 0x6206019c PROVIDE (__bss_start, .) - *(.bss) - .bss 0x6206019c 0x0 ./src/crt.o - .bss 0x6206019c 0x0 ./src/main.o - *(COMMON) - 0x6206019c . = ALIGN (0x4) - 0x6206019c PROVIDE (__bss_end, .) - 0x62060200 . = ALIGN (0x100) - *fill* 0x6206019c 0x64 00 - 0x62060200 PROVIDE (__stack_start, .) - 0x62060200 PROVIDE (__stack_fiq_start, .) - 0x62060300 . = (. + FIQ_STACK_SIZE) - *fill* 0x62060200 0x100 00 - 0x62060300 . = ALIGN (0x4) - 0x62060300 PROVIDE (__stack_fiq_end, .) - 0x62060300 PROVIDE (__stack_irq_start, .) - 0x62060400 . = (. + IRQ_STACK_SIZE) - *fill* 0x62060300 0x100 00 - 0x62060400 . = ALIGN (0x4) - 0x62060400 PROVIDE (__stack_irq_end, .) - 0x62060400 PROVIDE (__stack_abt_start, .) - 0x62060500 . = (. + ABT_STACK_SIZE) - *fill* 0x62060400 0x100 00 - 0x62060500 . = ALIGN (0x4) - 0x62060500 PROVIDE (__stack_abt_end, .) - 0x62060500 PROVIDE (__stack_und_start, .) - 0x62060600 . = (. + UND_STACK_SIZE) - *fill* 0x62060500 0x100 00 - 0x62060600 . = ALIGN (0x4) - 0x62060600 PROVIDE (__stack_und_end, .) - 0x62060600 PROVIDE (__stack_svc_start, .) - 0x62060a00 . = (. + SVC_STACK_SIZE) - *fill* 0x62060600 0x400 00 - 0x62060a00 . = ALIGN (0x4) - 0x62060a00 PROVIDE (__stack_svc_end, .) - 0x62060a00 PROVIDE (__stack_end, .) - 0x62060a00 PROVIDE (__heap_start, .) -OUTPUT(test.elf elf32-littlearm) - -.ARM.attributes - 0x00000000 0x10 - .ARM.attributes - 0x00000000 0x10 ./src/crt.o - .ARM.attributes - 0x00000010 0x10 ./src/main.o - -.debug_line 0x00000000 0xe5 - .debug_line 0x00000000 0x8f ./src/crt.o - .debug_line 0x0000008f 0x56 ./src/main.o - -.debug_info 0x00000000 0x218 - .debug_info 0x00000000 0x78 ./src/crt.o - .debug_info 0x00000078 0x1a0 ./src/main.o - -.debug_abbrev 0x00000000 0x88 - .debug_abbrev 0x00000000 0x12 ./src/crt.o - .debug_abbrev 0x00000012 0x76 ./src/main.o - -.debug_aranges 0x00000000 0x48 - .debug_aranges - 0x00000000 0x28 ./src/crt.o - .debug_aranges - 0x00000028 0x20 ./src/main.o - -.debug_ranges 0x00000000 0x20 - .debug_ranges 0x00000000 0x20 ./src/crt.o - -.debug_frame 0x00000000 0x24 - .debug_frame 0x00000000 0x24 ./src/main.o - -.debug_loc 0x00000000 0x1f - .debug_loc 0x00000000 0x1f ./src/main.o - -.debug_pubnames - 0x00000000 0x1b - .debug_pubnames - 0x00000000 0x1b ./src/main.o - -.comment 0x00000000 0x12 - .comment 0x00000000 0x12 ./src/main.o - -Cross Reference Table - -Symbol File -DAbortHandler ./src/crt.o -ExitFunction ./src/crt.o -FIQHandler ./src/crt.o -IRQHandler ./src/crt.o -PAbortHandler ./src/crt.o -ResetHandler ./src/crt.o -UndefHandler ./src/crt.o -__bss_end ./src/crt.o -__bss_start ./src/crt.o -__stack_abt_end ./src/crt.o -__stack_fiq_end ./src/crt.o -__stack_irq_end ./src/crt.o -__stack_svc_end ./src/crt.o -__stack_und_end ./src/crt.o -main ./src/main.o - ./src/crt.o diff --git a/testing/examples/STR710Test/.gitignore b/testing/examples/STR710Test/.gitignore deleted file mode 100644 index a2d3f5abd..000000000 --- a/testing/examples/STR710Test/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -.dep -src/main.lst diff --git a/testing/examples/STR710Test/inc/typedefs.h b/testing/examples/STR710Test/inc/typedefs.h deleted file mode 100644 index f43416d52..000000000 --- a/testing/examples/STR710Test/inc/typedefs.h +++ /dev/null @@ -1,50 +0,0 @@ -/**************************************************************************** -* Copyright (c) 2006 by Michael Fischer. All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* 1. Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the author nor the names of its contributors may -* be used to endorse or promote products derived from this software -* without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -* THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS -* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED -* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF -* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -* SUCH DAMAGE. -* -**************************************************************************** -* History: -* -* 30.03.06 mifi First Version for Insight tutorial -****************************************************************************/ -#ifndef __TYPEDEFS_H__ -#define __TYPEDEFS_H__ - -/* - * Some types to use Windows like source - */ -typedef char CHAR; /* 8-bit signed data */ -typedef unsigned char BYTE; /* 8-bit unsigned data */ -typedef unsigned short WORD; /* 16-bit unsigned data */ -typedef long LONG; /* 32-bit signed data */ -typedef unsigned long ULONG; /* 32-bit unsigned data */ -typedef unsigned long DWORD; /* 32-bit unsigned data */ - - -#endif /* !__TYPEDEFS_H__ */ -/*** EOF ***/ diff --git a/testing/examples/STR710Test/makefile b/testing/examples/STR710Test/makefile deleted file mode 100644 index 1450b73d5..000000000 --- a/testing/examples/STR710Test/makefile +++ /dev/null @@ -1,146 +0,0 @@ -# -# !!!! Do NOT edit this makefile with an editor which replace tabs by spaces !!!! -# -############################################################################################## -# -# On command line: -# -# make all = Create project -# -# make clean = Clean project files. -# -# To rebuild project do "make clean" and "make all". -# - -############################################################################################## -# Start of default section -# - -TRGT = arm-elf- -CC = $(TRGT)gcc -CP = $(TRGT)objcopy -AS = $(TRGT)gcc -x assembler-with-cpp -BIN = $(CP) -O ihex - -MCU = arm7tdmi - -# List all default C defines here, like -D_DEBUG=1 -DDEFS = - -# List all default ASM defines here, like -D_DEBUG=1 -DADEFS = - -# List all default directories to look for include files here -DINCDIR = - -# List the default directory to look for the libraries here -DLIBDIR = - -# List all default libraries here -DLIBS = - -# -# End of default section -############################################################################################## - -############################################################################################## -# Start of user section -# - -# Define project name here -PROJECT = test - -# Define linker script file here -LDSCRIPT_RAM = ./prj/hitex_str7_ram.ld -LDSCRIPT_ROM = ./prj/hitex_str7_rom.ld - -# List all user C define here, like -D_DEBUG=1 -UDEFS = - -# Define ASM defines here -UADEFS = - -# List C source files here -SRC = ./src/main.c - -# List ASM source files here -ASRC = ./src/crt.s - -# List all user directories here -UINCDIR = ./inc - -# List the user directory to look for the libraries here -ULIBDIR = - -# List all user libraries here -ULIBS = - -# Define optimisation level here -OPT = -O0 - -# -# End of user defines -############################################################################################## - - -INCDIR = $(patsubst %,-I%,$(DINCDIR) $(UINCDIR)) -LIBDIR = $(patsubst %,-L%,$(DLIBDIR) $(ULIBDIR)) -DEFS = $(DDEFS) $(UDEFS) -ADEFS = $(DADEFS) $(UADEFS) -OBJS = $(ASRC:.s=.o) $(SRC:.c=.o) -LIBS = $(DLIBS) $(ULIBS) -MCFLAGS = -mcpu=$(MCU) - -ASFLAGS = $(MCFLAGS) -g -gdwarf-2 -Wa,-amhls=$(<:.s=.lst) $(ADEFS) -CPFLAGS = $(MCFLAGS) $(OPT) -gdwarf-2 -mthumb-interwork -fomit-frame-pointer -Wall -Wstrict-prototypes -fverbose-asm -Wa,-ahlms=$(<:.c=.lst) $(DEFS) -LDFLAGS_RAM = $(MCFLAGS) -nostartfiles -T$(LDSCRIPT_RAM) -Wl,-Map=$(PROJECT)_ram.map,--cref,--no-warn-mismatch $(LIBDIR) -LDFLAGS_ROM = $(MCFLAGS) -nostartfiles -T$(LDSCRIPT_ROM) -Wl,-Map=$(PROJECT)_rom.map,--cref,--no-warn-mismatch $(LIBDIR) - -# Generate dependency information -CPFLAGS += -MD -MP -MF .dep/$(@F).d - -# -# makefile rules -# - -all: RAM ROM - -RAM: $(OBJS) $(PROJECT)_ram.elf $(PROJECT)_ram.hex - -ROM: $(OBJS) $(PROJECT)_rom.elf $(PROJECT)_rom.hex - -%o : %c - $(CC) -c $(CPFLAGS) -I . $(INCDIR) $< -o $@ - -%o : %s - $(AS) -c $(ASFLAGS) $< -o $@ - -%ram.elf: $(OBJS) - $(CC) $(OBJS) $(LDFLAGS_RAM) $(LIBS) -o $@ - -%rom.elf: $(OBJS) - $(CC) $(OBJS) $(LDFLAGS_ROM) $(LIBS) -o $@ - -%hex: %elf - $(BIN) $< $@ - -clean: - -rm -f $(OBJS) - -rm -f $(PROJECT)_ram.elf - -rm -f $(PROJECT)_ram.map - -rm -f $(PROJECT)_ram.hex - -rm -f $(PROJECT)_rom.elf - -rm -f $(PROJECT)_rom.map - -rm -f $(PROJECT)_rom.hex - -rm -f $(SRC:.c=.c.bak) - -rm -f $(SRC:.c=.lst) - -rm -f $(ASRC:.s=.s.bak) - -rm -f $(ASRC:.s=.lst) - -rm -fR .dep - -# -# Include the dependency files, should be the last of the makefile -# --include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*) - -# *** EOF *** \ No newline at end of file diff --git a/testing/examples/STR710Test/prj/eclipse_ram.gdb b/testing/examples/STR710Test/prj/eclipse_ram.gdb deleted file mode 100644 index 511ed5914..000000000 --- a/testing/examples/STR710Test/prj/eclipse_ram.gdb +++ /dev/null @@ -1,11 +0,0 @@ -target remote localhost:3333 -monitor reset -monitor sleep 500 -monitor poll -monitor soft_reset_halt -monitor arm7_9 sw_bkpts enable -monitor mww 0xA0000050 0x01c2 -monitor mdw 0xA0000050 -load -break main -continue \ No newline at end of file diff --git a/testing/examples/STR710Test/prj/eclipse_rom.gdb b/testing/examples/STR710Test/prj/eclipse_rom.gdb deleted file mode 100644 index 9e2c37005..000000000 --- a/testing/examples/STR710Test/prj/eclipse_rom.gdb +++ /dev/null @@ -1,11 +0,0 @@ -target remote localhost:3333 -monitor reset -monitor sleep 500 -monitor poll -monitor soft_reset_halt -monitor arm7_9 force_hw_bkpts enable -monitor mww 0xA0000050 0x01c2 -monitor mdw 0xA0000050 -load -break main -continue \ No newline at end of file diff --git a/testing/examples/STR710Test/prj/hitex_str7_ram.ld b/testing/examples/STR710Test/prj/hitex_str7_ram.ld deleted file mode 100644 index a0b2a3c68..000000000 --- a/testing/examples/STR710Test/prj/hitex_str7_ram.ld +++ /dev/null @@ -1,255 +0,0 @@ -/*********************************************************************************** -* Copyright 2005 Anglia Design -* This demo code and associated components are provided as is and has no warranty, -* implied or otherwise. You are free to use/modify any of the provided -* code at your own risk in your applications with the expressed limitation -* of liability (see below) -* -* LIMITATION OF LIABILITY: ANGLIA OR ANGLIA DESIGNS SHALL NOT BE LIABLE FOR ANY -* LOSS OF PROFITS, LOSS OF USE, LOSS OF DATA, INTERRUPTION OF BUSINESS, NOR FOR -* INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES OF ANY KIND WHETHER UNDER -* THIS AGREEMENT OR OTHERWISE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. -* -* Author : Spencer Oliver -* Web : www.anglia-designs.com -* -***********************************************************************************/ - -/* Stack Sizes */ - - _STACKSIZE = 1024; - _STACKSIZE_IRQ = 256; - _STACKSIZE_FIQ = 0; - _STACKSIZE_SVC = 1024; - _STACKSIZE_ABT = 0; - _STACKSIZE_UND = 0; - _HEAPSIZE = 1024; - -/* Memory Definitions */ - -MEMORY -{ - DATA (rw) : ORIGIN = 0x20000000, LENGTH = 0x00010000 -} - -/* Section Definitions */ - -SECTIONS -{ - /* first section is .text which is used for code */ - - .text : - { - CREATE_OBJECT_SYMBOLS - KEEP(*(.vectrom)) - KEEP(*(.init)) - *(.text .text.*) - *(.gnu.linkonce.t.*) - *(.glue_7t) *(.glue_7) *(.vfp11_veneer) - KEEP(*(.fini)) - *(.gcc_except_table) - } >DATA =0 - . = ALIGN(4); - - /* .ctors .dtors are used for c++ constructors/destructors */ - - .ctors : - { - PROVIDE(__ctors_start__ = .); - KEEP(*(SORT(.ctors.*))) - KEEP(*(.ctors)) - PROVIDE(__ctors_end__ = .); - } >DATA - - .dtors : - { - PROVIDE(__dtors_start__ = .); - KEEP(*(SORT(.dtors.*))) - KEEP(*(.dtors)) - PROVIDE(__dtors_end__ = .); - } >DATA - - /* .rodata section which is used for read-only data (constants) */ - - .rodata : - { - *(.rodata .rodata.*) - *(.gnu.linkonce.r.*) - } >DATA - . = ALIGN(4); - - .init_array : - { - *(.init) - *(.fini) - PROVIDE (__preinit_array_start = .); - KEEP (*(.preinit_array)) - PROVIDE (__preinit_array_end = .); - PROVIDE (__init_array_start = .); - KEEP (*(SORT(.init_array.*))) - KEEP (*(.init_array)) - PROVIDE (__init_array_end = .); - PROVIDE (__fini_array_start = .); - KEEP (*(.fini_array)) - KEEP (*(SORT(.fini_array.*))) - PROVIDE (__fini_array_end = .); - } >DATA - - . = ALIGN(4); - - /* .ARM.exidx is sorted, so has to go in its own output section. */ - __exidx_start = .; - .ARM.exidx : - { - *(.ARM.exidx* .gnu.linkonce.armexidx.*) - } >DATA - __exidx_end = .; - - _vectext = .; - PROVIDE (vectext = .); - - .vect : AT (_vectext) - { - _vecstart = .; - KEEP(*(.vectram)) - _vecend = .; - } >DATA - - _etext = _vectext + SIZEOF(.vect); - PROVIDE (etext = .); - - /* .data section which is used for initialized data */ - - .data : AT (_etext) - { - *(.data .data.*) - *(.gnu.linkonce.d.*) - SORT(CONSTRUCTORS) - } >DATA - . = ALIGN(4); - - __data_start = .; - _edata = .; - PROVIDE (edata = .); - - /* .bss section which is used for uninitialized data */ - - .bss : - { - __bss_start = .; - __bss_start__ = .; - *(.bss .bss.*) - *(.gnu.linkonce.b.*) - *(COMMON) - . = ALIGN(4); - } >DATA - . = ALIGN(4); - __bss_end__ = .; - - _end = .; - PROVIDE(end = .); - - /* .heap section which is used for memory allocation */ - - .heap (NOLOAD) : - { - __heap_start__ = .; - *(.heap) - . = MAX(__heap_start__ + _HEAPSIZE , .); - } >DATA - __heap_end__ = __heap_start__ + SIZEOF(.heap); - - /* .stack section - user mode stack */ - - .stack (__heap_end__ + 3) / 4 * 4 (NOLOAD) : - { - __stack_start__ = .; - *(.stack) - . = MAX(__stack_start__ + _STACKSIZE , .); - } >DATA - __stack_end__ = __stack_start__ + SIZEOF(.stack); - - /* .stack_irq section */ - - .stack_irq (__stack_end__ + 3) / 4 * 4 (NOLOAD) : - { - __stack_irq_start__ = .; - *(.stack_irq) - . = MAX(__stack_irq_start__ + _STACKSIZE_IRQ , .); - } >DATA - __stack_irq_end__ = __stack_irq_start__ + SIZEOF(.stack_irq); - - /* .stack_fiq section */ - - .stack_fiq (__stack_irq_end__ + 3) / 4 * 4 (NOLOAD) : - { - __stack_fiq_start__ = .; - *(.stack_fiq) - . = MAX(__stack_fiq_start__ + _STACKSIZE_FIQ , .); - } >DATA - __stack_fiq_end__ = __stack_fiq_start__ + SIZEOF(.stack_fiq); - - /* .stack_svc section */ - - .stack_svc (__stack_fiq_end__ + 3) / 4 * 4 (NOLOAD) : - { - __stack_svc_start__ = .; - *(.stack_svc) - . = MAX(__stack_svc_start__ + _STACKSIZE_SVC , .); - } >DATA - __stack_svc_end__ = __stack_svc_start__ + SIZEOF(.stack_svc); - - /* .stack_abt section */ - - .stack_abt (__stack_svc_end__ + 3) / 4 * 4 (NOLOAD) : - { - __stack_abt_start__ = .; - *(.stack_abt) - . = MAX(__stack_abt_start__ + _STACKSIZE_ABT , .); - } >DATA - __stack_abt_end__ = __stack_abt_start__ + SIZEOF(.stack_abt); - - /* .stack_und section */ - - .stack_und (__stack_abt_end__ + 3) / 4 * 4 (NOLOAD) : - { - __stack_und_start__ = .; - *(.stack_und) - . = MAX(__stack_und_start__ + _STACKSIZE_UND , .); - } >DATA - __stack_und_end__ = __stack_und_start__ + SIZEOF(.stack_und); - - /* Stabs debugging sections. */ - .stab 0 : { *(.stab) } - .stabstr 0 : { *(.stabstr) } - .stab.excl 0 : { *(.stab.excl) } - .stab.exclstr 0 : { *(.stab.exclstr) } - .stab.index 0 : { *(.stab.index) } - .stab.indexstr 0 : { *(.stab.indexstr) } - .comment 0 : { *(.comment) } - /* DWARF debug sections. - Symbols in the DWARF debugging sections are relative to the beginning - of the section so we begin them at 0. */ - /* DWARF 1 */ - .debug 0 : { *(.debug) } - .line 0 : { *(.line) } - /* GNU DWARF 1 extensions */ - .debug_srcinfo 0 : { *(.debug_srcinfo) } - .debug_sfnames 0 : { *(.debug_sfnames) } - /* DWARF 1.1 and DWARF 2 */ - .debug_aranges 0 : { *(.debug_aranges) } - .debug_pubnames 0 : { *(.debug_pubnames) } - /* DWARF 2 */ - .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } - .debug_abbrev 0 : { *(.debug_abbrev) } - .debug_line 0 : { *(.debug_line) } - .debug_frame 0 : { *(.debug_frame) } - .debug_str 0 : { *(.debug_str) } - .debug_loc 0 : { *(.debug_loc) } - .debug_macinfo 0 : { *(.debug_macinfo) } - /* SGI/MIPS DWARF 2 extensions */ - .debug_weaknames 0 : { *(.debug_weaknames) } - .debug_funcnames 0 : { *(.debug_funcnames) } - .debug_typenames 0 : { *(.debug_typenames) } - .debug_varnames 0 : { *(.debug_varnames) } -} diff --git a/testing/examples/STR710Test/prj/hitex_str7_rom.ld b/testing/examples/STR710Test/prj/hitex_str7_rom.ld deleted file mode 100644 index 11ac4b621..000000000 --- a/testing/examples/STR710Test/prj/hitex_str7_rom.ld +++ /dev/null @@ -1,259 +0,0 @@ -/*********************************************************************************** -* Copyright 2005 Anglia Design -* This demo code and associated components are provided as is and has no warranty, -* implied or otherwise. You are free to use/modify any of the provided -* code at your own risk in your applications with the expressed limitation -* of liability (see below) -* -* LIMITATION OF LIABILITY: ANGLIA OR ANGLIA DESIGNS SHALL NOT BE LIABLE FOR ANY -* LOSS OF PROFITS, LOSS OF USE, LOSS OF DATA, INTERRUPTION OF BUSINESS, NOR FOR -* INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES OF ANY KIND WHETHER UNDER -* THIS AGREEMENT OR OTHERWISE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. -* -* Author : Spencer Oliver -* Web : www.anglia-designs.com -* -***********************************************************************************/ - -/* Stack Sizes */ - - _STACKSIZE = 1024; - _STACKSIZE_IRQ = 256; - _STACKSIZE_FIQ = 0; - _STACKSIZE_SVC = 1024; - _STACKSIZE_ABT = 0; - _STACKSIZE_UND = 0; - _HEAPSIZE = 1024; - -/* Memory Definitions */ - -MEMORY -{ - CODE (rx) : ORIGIN = 0x40000000, LENGTH = 0x00040000 - DATA (rw) : ORIGIN = 0x20000000, LENGTH = 0x00010000 -} - -/* Section Definitions */ - -SECTIONS -{ - /* first section is .text which is used for code */ - - .text : - { - CREATE_OBJECT_SYMBOLS - KEEP(*(.vectrom)) - KEEP(*(.init)) - *(.text .text.*) - *(.gnu.linkonce.t.*) - *(.glue_7t) *(.glue_7) *(.vfp11_veneer) - KEEP(*(.fini)) - *(.gcc_except_table) - } >CODE =0 - . = ALIGN(4); - - /* .ctors .dtors are used for c++ constructors/destructors */ - - .ctors : - { - PROVIDE(__ctors_start__ = .); - KEEP(*(SORT(.ctors.*))) - KEEP(*(.ctors)) - PROVIDE(__ctors_end__ = .); - } >CODE - - .dtors : - { - PROVIDE(__dtors_start__ = .); - KEEP(*(SORT(.dtors.*))) - KEEP(*(.dtors)) - PROVIDE(__dtors_end__ = .); - } >CODE - - /* .rodata section which is used for read-only data (constants) */ - - .rodata : - { - *(.rodata .rodata.*) - *(.gnu.linkonce.r.*) - } >CODE - . = ALIGN(4); - - .init_array : - { - *(.init) - *(.fini) - PROVIDE (__preinit_array_start = .); - KEEP (*(.preinit_array)) - PROVIDE (__preinit_array_end = .); - PROVIDE (__init_array_start = .); - KEEP (*(SORT(.init_array.*))) - KEEP (*(.init_array)) - PROVIDE (__init_array_end = .); - PROVIDE (__fini_array_start = .); - KEEP (*(.fini_array)) - KEEP (*(SORT(.fini_array.*))) - PROVIDE (__fini_array_end = .); - } >CODE - - . = ALIGN(4); - - /* .ARM.exidx is sorted, so has to go in its own output section. */ - __exidx_start = .; - .ARM.exidx : - { - *(.ARM.exidx* .gnu.linkonce.armexidx.*) - } >CODE - __exidx_end = .; - - _vectext = .; - PROVIDE (vectext = .); - - .vect : AT (_vectext) - { - _vecstart = .; - KEEP(*(.vectram)) - _vecend = .; - } >DATA - - _etext = _vectext + SIZEOF(.vect); - PROVIDE (etext = .); - - /* .data section which is used for initialized data */ - - .data : AT (_etext) - { - __data_start = .; - *(.data .data.*) - *(.gnu.linkonce.d.*) - SORT(CONSTRUCTORS) - . = ALIGN(4); - *(.fastrun .fastrun.*) - } >DATA - . = ALIGN(4); - - _edata = .; - PROVIDE (edata = .); - - /* .bss section which is used for uninitialized data */ - - .bss : - { - __bss_start = .; - __bss_start__ = .; - *(.bss .bss.*) - *(.gnu.linkonce.b.*) - *(COMMON) - . = ALIGN(4); - } >DATA - . = ALIGN(4); - __bss_end__ = .; - - _end = .; - PROVIDE(end = .); - - /* .heap section which is used for memory allocation */ - - .heap (NOLOAD) : - { - __heap_start__ = .; - *(.heap) - . = MAX(__heap_start__ + _HEAPSIZE , .); - } >DATA - __heap_end__ = __heap_start__ + SIZEOF(.heap); - - /* .stack section - user mode stack */ - - .stack (__heap_end__ + 3) / 4 * 4 (NOLOAD) : - { - __stack_start__ = .; - *(.stack) - . = MAX(__stack_start__ + _STACKSIZE , .); - } >DATA - __stack_end__ = __stack_start__ + SIZEOF(.stack); - - /* .stack_irq section */ - - .stack_irq (__stack_end__ + 3) / 4 * 4 (NOLOAD) : - { - __stack_irq_start__ = .; - *(.stack_irq) - . = MAX(__stack_irq_start__ + _STACKSIZE_IRQ , .); - } >DATA - __stack_irq_end__ = __stack_irq_start__ + SIZEOF(.stack_irq); - - /* .stack_fiq section */ - - .stack_fiq (__stack_irq_end__ + 3) / 4 * 4 (NOLOAD) : - { - __stack_fiq_start__ = .; - *(.stack_fiq) - . = MAX(__stack_fiq_start__ + _STACKSIZE_FIQ , .); - } >DATA - __stack_fiq_end__ = __stack_fiq_start__ + SIZEOF(.stack_fiq); - - /* .stack_svc section */ - - .stack_svc (__stack_fiq_end__ + 3) / 4 * 4 (NOLOAD) : - { - __stack_svc_start__ = .; - *(.stack_svc) - . = MAX(__stack_svc_start__ + _STACKSIZE_SVC , .); - } >DATA - __stack_svc_end__ = __stack_svc_start__ + SIZEOF(.stack_svc); - - /* .stack_abt section */ - - .stack_abt (__stack_svc_end__ + 3) / 4 * 4 (NOLOAD) : - { - __stack_abt_start__ = .; - *(.stack_abt) - . = MAX(__stack_abt_start__ + _STACKSIZE_ABT , .); - } >DATA - __stack_abt_end__ = __stack_abt_start__ + SIZEOF(.stack_abt); - - /* .stack_und section */ - - .stack_und (__stack_abt_end__ + 3) / 4 * 4 (NOLOAD) : - { - __stack_und_start__ = .; - *(.stack_und) - . = MAX(__stack_und_start__ + _STACKSIZE_UND , .); - } >DATA - __stack_und_end__ = __stack_und_start__ + SIZEOF(.stack_und); - - /* Stabs debugging sections. */ - .stab 0 : { *(.stab) } - .stabstr 0 : { *(.stabstr) } - .stab.excl 0 : { *(.stab.excl) } - .stab.exclstr 0 : { *(.stab.exclstr) } - .stab.index 0 : { *(.stab.index) } - .stab.indexstr 0 : { *(.stab.indexstr) } - .comment 0 : { *(.comment) } - /* DWARF debug sections. - Symbols in the DWARF debugging sections are relative to the beginning - of the section so we begin them at 0. */ - /* DWARF 1 */ - .debug 0 : { *(.debug) } - .line 0 : { *(.line) } - /* GNU DWARF 1 extensions */ - .debug_srcinfo 0 : { *(.debug_srcinfo) } - .debug_sfnames 0 : { *(.debug_sfnames) } - /* DWARF 1.1 and DWARF 2 */ - .debug_aranges 0 : { *(.debug_aranges) } - .debug_pubnames 0 : { *(.debug_pubnames) } - /* DWARF 2 */ - .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } - .debug_abbrev 0 : { *(.debug_abbrev) } - .debug_line 0 : { *(.debug_line) } - .debug_frame 0 : { *(.debug_frame) } - .debug_str 0 : { *(.debug_str) } - .debug_loc 0 : { *(.debug_loc) } - .debug_macinfo 0 : { *(.debug_macinfo) } - /* SGI/MIPS DWARF 2 extensions */ - .debug_weaknames 0 : { *(.debug_weaknames) } - .debug_funcnames 0 : { *(.debug_funcnames) } - .debug_typenames 0 : { *(.debug_typenames) } - .debug_varnames 0 : { *(.debug_varnames) } -} - diff --git a/testing/examples/STR710Test/prj/str710_jtagkey.cfg b/testing/examples/STR710Test/prj/str710_jtagkey.cfg deleted file mode 100644 index 478c55e4d..000000000 --- a/testing/examples/STR710Test/prj/str710_jtagkey.cfg +++ /dev/null @@ -1,36 +0,0 @@ -#daemon configuration -telnet_port 4444 -gdb_port 3333 - -# tell gdb our flash memory map -# and enable flash programming -gdb_memory_map enable -gdb_flash_program enable - -#interface -interface ft2232 -ft2232_device_desc "Amontec JTAGkey A" -ft2232_layout jtagkey -ft2232_vid_pid 0x0403 0xcff8 -jtag_speed 0 - -#use combined on interfaces or targets that can't set TRST/SRST separately -reset_config trst_and_srst srst_pulls_trst - -#jtag scan chain -jtag newtap str7 cpu -irlen 4 -irmask 0xf - -#target configuration -target create target0 arm7tdmi -endian little -chain-position 0 -[new_target_name] configure -work-area-virt 0 -work-area-phys 0x2000C000 -work-area-size 0x4000 -work-area-backup false - -target_script 0 gdb_program_config .\prj\str710_program.script - -#flash bank str7x 0 0 -flash bank str7x 0x40000000 0x00040000 0 0 0 STR71x - -# For more information about the configuration files, -# look at the OpenOCD User's Guide. - -init -reset halt diff --git a/testing/examples/STR710Test/prj/str710_program.script b/testing/examples/STR710Test/prj/str710_program.script deleted file mode 100644 index b268adf09..000000000 --- a/testing/examples/STR710Test/prj/str710_program.script +++ /dev/null @@ -1,8 +0,0 @@ -flash protect 0 0 7 off - - - - - - - diff --git a/testing/examples/STR710Test/src/crt.s b/testing/examples/STR710Test/src/crt.s deleted file mode 100644 index c9db5f5ea..000000000 --- a/testing/examples/STR710Test/src/crt.s +++ /dev/null @@ -1,299 +0,0 @@ -/**************************************************************************** -* Copyright (c) 2006 by Michael Fischer. All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* 1. Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the author nor the names of its contributors may -* be used to endorse or promote products derived from this software -* without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -* THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS -* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED -* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF -* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -* SUCH DAMAGE. -* -**************************************************************************** -* -* History: -* -* 04.03.06 mifi First Version -* This version based on an example from Ethernut and -* "ARM Cross Development with Eclipse" from James P. Lynch -* -* 26.01.08 mifi Change the code of the init section. Here I have used -* some of the source from the Anglia startup.s -* Author: Spencer Oliver (www.anglia-designs.com) -****************************************************************************/ - -/* - * Some defines for the program status registers - */ - ARM_MODE_USER = 0x10 /* Normal User Mode */ - ARM_MODE_FIQ = 0x11 /* FIQ Fast Interrupts Mode */ - ARM_MODE_IRQ = 0x12 /* IRQ Standard Interrupts Mode */ - ARM_MODE_SVC = 0x13 /* Supervisor Interrupts Mode */ - ARM_MODE_ABORT = 0x17 /* Abort Processing memory Faults Mode */ - ARM_MODE_UNDEF = 0x1B /* Undefined Instructions Mode */ - ARM_MODE_SYS = 0x1F /* System Running in Priviledged Operating Mode */ - ARM_MODE_MASK = 0x1F - - I_BIT = 0x80 /* disable IRQ when I bit is set */ - F_BIT = 0x40 /* disable IRQ when I bit is set */ - -/* - * Register Base Address - */ - PRCCU_BASE = 0xA0000000 - RCCU_CFR = 0x08 - RCCU_PLL1CR = 0x18 - PCU_MDIVR = 0x40 - PCU_PDIVR = 0x44 - PCU_BOOTCR = 0x50 - - - .section .vectors,"ax" - .code 32 - -/****************************************************************************/ -/* Vector table and reset entry */ -/****************************************************************************/ -_vectors: - ldr pc, ResetAddr /* Reset */ - ldr pc, UndefAddr /* Undefined instruction */ - ldr pc, SWIAddr /* Software interrupt */ - ldr pc, PAbortAddr /* Prefetch abort */ - ldr pc, DAbortAddr /* Data abort */ - ldr pc, ReservedAddr /* Reserved */ - ldr pc, IRQAddr /* IRQ interrupt */ - ldr pc, FIQAddr /* FIQ interrupt */ - - -ResetAddr: .word ResetHandler -UndefAddr: .word UndefHandler -SWIAddr: .word SWIHandler -PAbortAddr: .word PAbortHandler -DAbortAddr: .word DAbortHandler -ReservedAddr: .word 0 -IRQAddr: .word IRQHandler -FIQAddr: .word FIQHandler - - .ltorg - - - .section .init, "ax" - .code 32 - - .global ResetHandler - .global ExitFunction - .extern main -/****************************************************************************/ -/* Reset handler */ -/****************************************************************************/ -ResetHandler: -/* - * Wait for the oscillator is stable - */ - nop - nop - nop - nop - nop - nop - nop - nop - -/* - * Setup STR71X, for more information about the register - * take a look in the STR71x Microcontroller Reference Manual. - * - * Reference is made to: Rev. 6 March 2005 - * - * 1. Map internal RAM to address 0 - * In this case, we are running always in the RAM - * this make no sence. But if we are in flash, we - * can copy the interrupt vectors into the ram and - * switch to RAM mode. - * - * 2. Setup the PLL, the eval board HITEX STR7 is equipped - * with an external 16MHz oscillator. We want: - * - * RCLK: 32MHz = (CLK2 * 16) / 4 - * MCLK: 32Mhz - * PCLK1: 32MHz - * PCLK2: 32MHz - * - */ - - /* - * 1. Map RAM to the boot memory 0x00000000 - */ - ldr r0, =PRCCU_BASE - ldr r1, =0x01C2 - str r1, [r0, #PCU_BOOTCR] - - - /* - * 2. Setup PLL start - */ - - /* Set the prescaling factor for APB and APB1 group */ - ldr r0, =PRCCU_BASE - ldr r1, =0x0000 /* no prescaling PCLKx = RCLK */ - str r1, [r0, #PCU_PDIVR] - - /* Set the prescaling factor for the Main System Clock MCLK */ - ldr r0, =PRCCU_BASE - ldr r1, =0x0000 /* no prescaling MCLK = RCLK - str r1, [r0, #PCU_MDIVR] - - /* Configure the PLL1 ( * 16 , / 4 ) */ - ldr r0, =PRCCU_BASE - ldr r1, =0x0073 - str r1, [r0, #RCCU_PLL1CR] - - /* Check if the PLL is locked */ -pll_lock_loop: - ldr r1, [r0, #RCCU_CFR] - tst r1, #0x0002 - beq pll_lock_loop - - /* Select PLL1_Output as RCLK clock */ - ldr r0, =PRCCU_BASE - ldr r1, =0x8009 - str r1, [r0, #RCCU_CFR] - - /* - * Setup PLL end - */ - - - /* - * Setup a stack for each mode - */ - msr CPSR_c, #ARM_MODE_UNDEF | I_BIT | F_BIT /* Undefined Instruction Mode */ - ldr sp, =__stack_und_end__ - - msr CPSR_c, #ARM_MODE_ABORT | I_BIT | F_BIT /* Abort Mode */ - ldr sp, =__stack_abt_end__ - - msr CPSR_c, #ARM_MODE_FIQ | I_BIT | F_BIT /* FIQ Mode */ - ldr sp, =__stack_fiq_end__ - - msr CPSR_c, #ARM_MODE_IRQ | I_BIT | F_BIT /* IRQ Mode */ - ldr sp, =__stack_irq_end__ - - msr CPSR_c, #ARM_MODE_SVC | I_BIT | F_BIT /* Supervisor Mode */ - ldr sp, =__stack_svc_end__ - - - /* - * Now init all the sections - */ - - - /* - * Relocate .data section (Copy from ROM to RAM) - */ - ldr r1, =_etext - ldr r2, =__data_start - ldr r3, =_edata -LoopRel: - cmp r2, r3 - ldrlo r0, [r1], #4 - strlo r0, [r2], #4 - blo LoopRel - - - /* - * Clear .bss section (Zero init) - */ - mov r0, #0 - ldr r1, =__bss_start__ - ldr r2, =__bss_end__ -LoopZI: - cmp r1, r2 - strlo r0, [r1], #4 - blo LoopZI - - - /* - * Call C++ constructors - */ - ldr r0, =__ctors_start__ - ldr r1, =__ctors_end__ -ctor_loop: - cmp r0, r1 - beq ctor_end - ldr r2, [r0], #4 - stmfd sp!, {r0-r1} - mov lr, pc - mov pc, r2 - ldmfd sp!, {r0-r1} - b ctor_loop -ctor_end: - - - /* - * Jump to main - */ - mrs r0, cpsr - bic r0, r0, #I_BIT | F_BIT /* Enable FIQ and IRQ interrupt */ - msr cpsr, r0 - - mov r0, #0 /* No arguments */ - mov r1, #0 /* No arguments */ - ldr r2, =main - mov lr, pc - bx r2 /* And jump... */ - -ExitFunction: - nop - nop - nop - b ExitFunction - - -/****************************************************************************/ -/* Default interrupt handler */ -/****************************************************************************/ - -UndefHandler: - b UndefHandler - -SWIHandler: - b SWIHandler - -PAbortHandler: - b PAbortHandler - -DAbortHandler: - b DAbortHandler - -IRQHandler: - b IRQHandler - -FIQHandler: - b FIQHandler - - .weak ExitFunction - .weak UndefHandler, PAbortHandler, DAbortHandler - .weak IRQHandler, FIQHandler - - .ltorg -/*** EOF ***/ - diff --git a/testing/examples/STR710Test/src/main.c b/testing/examples/STR710Test/src/main.c deleted file mode 100644 index c60b9f65c..000000000 --- a/testing/examples/STR710Test/src/main.c +++ /dev/null @@ -1,105 +0,0 @@ -/**************************************************************************** -* Copyright (c) 2006 by Michael Fischer. All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* 1. Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the author nor the names of its contributors may -* be used to endorse or promote products derived from this software -* without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -* THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS -* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED -* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF -* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -* SUCH DAMAGE. -* -**************************************************************************** -* History: -* -* 30.03.06 mifi First Version for Insight tutorial -* 26.01.08 mifi Added variable "d" to test const variable. -****************************************************************************/ -#define __MAIN_C__ - -/* - * I use the include only, to show - * how to setup a include dir in the makefile - */ -#include "typedefs.h" - -/* Increase the size of this dummy global data to create a larger ROM image */ -static const char test[] = - "ljasdfljkasdfljsaflsjadflksjadflksjadfasdfsadfsa" - "ljasdfljkasdfljsaflsjadflksjadflksjadfasdfsadfsa" - "ljasdfljkasdfljsaflsjadflksjadflksjadfasdfsadfsa" - "ljasdfljkasdfljsaflsjadflksjadflksjadfasdfsadfsa" - "ljasdfljkasdfljsaflsjadflksjadflksjadfasdfsadfsa" - "ljasdfljkasdfljsaflsjadflksjadflksjadfasdfsadfsa" - "ljasdfljkasdfljsaflsjadflksjadflksjadfasdfsadfsa" - "ljasdfljkasdfljsaflsjadflksjadflksjadfasdfsadfsa" - "ljasdfljkasdfljsaflsjadflksjadflksjadfasdfsadfsa"; - - - -/*=========================================================================*/ -/* DEFINE: All Structures and Common Constants */ -/*=========================================================================*/ - -/*=========================================================================*/ -/* DEFINE: Prototypes */ -/*=========================================================================*/ - -/*=========================================================================*/ -/* DEFINE: Definition of all local Data */ -/*=========================================================================*/ -static const DWORD d = 7; - -/*=========================================================================*/ -/* DEFINE: Definition of all local Procedures */ -/*=========================================================================*/ - -/*=========================================================================*/ -/* DEFINE: All code exported */ -/*=========================================================================*/ -/***************************************************************************/ -/* main */ -/***************************************************************************/ -int main (void) -{ - DWORD a = 1; - DWORD b = 2; - DWORD c = 0; - - a = a + d; - - while (1) - { - a++; - b++; - c = a + b; - } - - /* - * This return here make no sense. - * But to prevent the compiler warning: - * "return type of 'main' is not 'int' - * we use an int as return :-) - */ - return(0); -} - -/*** EOF ***/ diff --git a/testing/examples/STR710Test/test_ram.elf b/testing/examples/STR710Test/test_ram.elf deleted file mode 100644 index 2c72e220e091e91e7e57135e6a9a0b7b6a446018..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 41263 zcmeI1ZERa-701uLwv#MLTPNLErB31w0<_a+Ctcc=AhD!*X|twlW+$6g1zg9zO{^w% zYC9zro0hc*iH(<)exPXU5{-=y@L>ocG_h5xV1kP6LkCE}_N8fvG^T-KG>KK4F#q#B z_qo0f9pVFD5a(&1`<(wd=Xv|xm-yO`4UP<1mX#*2*tCNzZ9Cm)-#tgvfVP_)_;=7P z)UM-;D#^joiP}V5BkWq_gA^ek1cZPP5CTF#2nYcoAOwVf5D)@FKnMr{As_^VfDjM@ zLO=)z0U;m+gn$qb0zyCt2mv7=1cZPP5CTF#2nYcoAOwVf5D)@FKnMr{As_^VfDjM@ zLO=)z0U;m+gn$qb0zyCt2mv7=1cZPP5CTF#2nYcoAOwVf5D)@FKnMr{As_^VfDjM@ zLO=)z0U;m+gn$qb0zyCt2mv7=1cZPP5CTF#2nYcoAOwVf5D)@FKnMr{As_^VfDjM@ zLO=)z0U;m+gn$qb0{?3SmRE>Ax;ER(tKqh#wbAI}8ru|IUL6S7>?^^y4Zf!6Q)@Q0 zt$tXoHnaaqbP2x2wYS!9U%h-~Y3=uDUq$-{+DmAEgZ34)zeW2J+LxlJ4r=GpT8I)W zVLIC#rqkUYRI5E$KaaRg4^BZe6+Avx|+k|#6_Ds$>=nIIQxym_gTb*aFu^sko z)yKJ@bg1+6Rqp#9*2;5iTVGoHcNJHrvkmLG4b?&IK;^4-2iiMP8(ByZ0zyCt2mv7= z1cZPP5CTF#2>ibg*x%pZXhDV83?rmVshEjpise{|`g4G?%TG)f zX5ER|W4Tgh+AU5L=G=TClbt9R=kv#7#oc@NOqAVHIhUWBa2L|Eb2DyfA~}}0r>k=e zZo>6Eg^g_8ca&t)|R$y2$N(zLcBF zyIDs&?8ee`p;&f&cP?KhI~AvEyN;lu#hu^+3QD5BPYbt`sfre&P0 zBWbb*f5mG!TaHYUHKgr@NQSKa+J1y5eT+g)JuRPW8QzK$8?)|h)$%i~!&^DMx4}Xn z((Py2%|s2KCQhekQ861N7>Vu@nKLN;AaQ*7Ez&vAM>bKGlEx#9_9mQH3U zmMP56y11fZS$A@NDwQs#^HVN{&~k2mGM}EU>0JI;!Nk&&lSTKWQ8T%`YwTl1^f6+l zfLZzyhhph+xtN=r$0NXmyt&N&{)2Wqa`>9Uh0MjFMa4@AKIkVK(e1EJ9`k(taiU&M z@CwJc+=0qApKxa0db&0ST>g0ctmQne>bo@L`9aT*hW2{4%4@)PZeNANEXs?ap?f`B z`gJTN8vCw$DTyq_X7@Ner-cu*IC?o+`%g*?>o@O=FqdqyYA(1V`AS6*z7<5 zZK4h~ykZdj2-@`F&@0IMxR=9?iM$&MAfBIorlruDZ+eT*7mY)Dph`b)F@V}xV>nb z4&qp;K8<5s=olzXH7;&~HM&7tq(B-w)`& zKz|s}??Yo4hZ{B`7Ov@l-UQtg(6>Mb=f`gX#J>rs?l^nAeiTO?p+AZENI-W%pAYEI zLjNS7d!a7}^nK882Q<&$8JI5#ZAuutk3jSN!gq#+D~j{Y{lixnuWu&MpW~MUdV;#T^7rLYw<3N{#e{muvFB%W;nv_kW>Ihv`LVCotZ{x_G7fDs)pI{>Fy* zo238u@-$8V4$~dbhF284dN_{Xr_A^xb-Iy` zvi8^0NM&gA+Ys|Q&G7(_Z`Sp%RF|R6-%H-l59;zm^iya)Uq_LK52f^ST|7*`h7PXx z575E!RyXLs)%CAbud@#9uLY0T;CiF1{dgmF=tnRnfgkI=o8$ie@w{Q}J%6M46!b7O z|3=37%p(iUzoQv_qAtHueT;R0*VkG5=Ql#nK%2tz6F#`54jmpCOpPZ86E!t7{6I|% zCjuh*V1F&rx9@ObtR~0r9~c~}$>hVynmE*#JV?W-eZylkq>iJB{{HdQzP{ujDXV`d zp^edzk*@v(jUswzVE938jr!KU!-vNZ?nqP0d>&4?CAZv{%@%1qk5Bl@N8F{Mesrv1!$IWC^_wr1RMsw@7m{Gbwz=J&r?Rjz(}uxHGCfGEDq= zTnCip=CkI7BTK2|SYQ9aa}2SAy*!n&u7ZHLS8fBmjyEi-UoOPo*~7r3%-~vmHf#SKz~?oYCR=S zt`?C}?;d^^GyXirHskAEvB%#PTVQuAcf$AS(@>j@7g9e0bMZU}2Kz=CAy)4%SbuNf zZKpPqUZ2;`XCDO1*KW#HuTEz9>B+L03O#*l?Dj|Y$4c>SVS4hG>X*%^O(&djvqN=F Y8ew{yp1c^{$sgDZ5x9Q(_Knd$0TN~26aWAK diff --git a/testing/examples/STR710Test/test_ram.hex b/testing/examples/STR710Test/test_ram.hex deleted file mode 100644 index f17d214c3..000000000 --- a/testing/examples/STR710Test/test_ram.hex +++ /dev/null @@ -1,37 +0,0 @@ -:020000042000DA -:100000000000A0E10000A0E10000A0E10000A0E1EC -:100010000000A0E10000A0E10000A0E10000A0E1DC -:100020000A02A0E304119FE5501080E50A02A0E354 -:100030000010A0E3441080E50A02A0E30010A0E352 -:100040000A02A0E37310A0E3181080E5081090E501 -:10005000020011E3FCFFFF0A0A02A0E3D0109FE5B3 -:10006000081080E5DBF021E3C8D09FE5D7F021E35D -:10007000C4D09FE5D1F021E3C0D09FE5D2F021E3C9 -:10008000BCD09FE5D3F021E3B8D09FE5B8109FE541 -:10009000B8209FE5B8309FE5030052E10400913499 -:1000A00004008234FBFFFF3A0000A0E3A4109FE5A8 -:1000B000A4209FE5020051E104008134FCFFFF3AD7 -:1000C00098009FE598109FE5010050E10500000AA7 -:1000D000042090E403002DE90FE0A0E102F0A0E18C -:1000E0000300BDE8F7FFFFEA00000FE1C000C0E336 -:1000F00000F029E10000A0E30010A0E364209FE5E8 -:100100000FE0A0E112FF2FE10000A0E10000A0E15C -:100110000000A0E1FBFFFFEAFEFFFFEAFEFFFFEAAF -:10012000FEFFFFEAFEFFFFEAFEFFFFEAFEFFFFEA37 -:10013000C201000009800000100F0020100F0020F5 -:10014000100B0020100B0020100F002010020020C8 -:1001500010020020100200201002002010020020D7 -:100160000C0200200C0200206C0100200CD04DE29B -:100170000130A0E300308DE50230A0E304308DE5CE -:100180000030A0E308308DE538309FE5002093E58E -:1001900000309DE5023083E000308DE500309DE5C4 -:1001A000013083E200308DE504309DE5013083E2CB -:1001B00004308DE500209DE504309DE5033082E0AC -:0C01C00008308DE5F4FFFFEA0C0200207F -:1001CC0018F09FE518F09FE518F09FE518F09FE5F3 -:1001DC0018F09FE518F09FE518F09FE518F09FE5E3 -:1001EC0000000020180100201C010020200100202C -:1001FC002401002000000000280100202C01002018 -:04020C0007000000E7 -:0400000520000000D7 -:00000001FF diff --git a/testing/examples/STR710Test/test_ram.map b/testing/examples/STR710Test/test_ram.map deleted file mode 100644 index dfc8317f1..000000000 --- a/testing/examples/STR710Test/test_ram.map +++ /dev/null @@ -1,297 +0,0 @@ - -Memory Configuration - -Name Origin Length Attributes -DATA 0x20000000 0x00010000 rw -*default* 0x00000000 0xffffffff - -Linker script and memory map - -LOAD ./src/crt.o -LOAD ./src/main.o -START GROUP -LOAD d:/compiler/yagarto/bin/../lib/gcc/arm-elf/4.2.2\libgcc.a -LOAD d:/compiler/yagarto/bin/../lib/gcc/arm-elf/4.2.2/../../../../arm-elf/lib\libc.a -END GROUP - 0x00000400 _STACKSIZE = 0x400 - 0x00000100 _STACKSIZE_IRQ = 0x100 - 0x00000000 _STACKSIZE_FIQ = 0x0 - 0x00000400 _STACKSIZE_SVC = 0x400 - 0x00000000 _STACKSIZE_ABT = 0x0 - 0x00000000 _STACKSIZE_UND = 0x0 - 0x00000400 _HEAPSIZE = 0x400 - -.text 0x20000000 0x1cc - CREATE_OBJECT_SYMBOLS - *(.vectrom) - *(.init) - .init 0x20000000 0x16c ./src/crt.o - 0x2000012c FIQHandler - 0x20000120 PAbortHandler - 0x20000108 ExitFunction - 0x20000000 ResetHandler - 0x20000124 DAbortHandler - 0x20000128 IRQHandler - 0x20000118 UndefHandler - *(.text .text.*) - .text 0x2000016c 0x0 ./src/crt.o - .text 0x2000016c 0x60 ./src/main.o - 0x2000016c main - *(.gnu.linkonce.t.*) - *(.glue_7t) - .glue_7t 0x200001cc 0x0 ./src/crt.o - .glue_7t 0x200001cc 0x0 ./src/main.o - *(.glue_7) - .glue_7 0x200001cc 0x0 ./src/crt.o - .glue_7 0x200001cc 0x0 ./src/main.o - *(.vfp11_veneer) - .vfp11_veneer 0x200001cc 0x0 ./src/crt.o - .vfp11_veneer 0x200001cc 0x0 ./src/main.o - *(.fini) - *(.gcc_except_table) - -.vectors 0x200001cc 0x40 - .vectors 0x200001cc 0x40 ./src/crt.o - 0x2000020c . = ALIGN (0x4) - -.ctors 0x2000020c 0x0 - 0x2000020c PROVIDE (__ctors_start__, .) - *(SORT(.ctors.*)) - *(.ctors) - 0x2000020c PROVIDE (__ctors_end__, .) - -.dtors 0x2000020c 0x0 - 0x2000020c PROVIDE (__dtors_start__, .) - *(SORT(.dtors.*)) - *(.dtors) - 0x2000020c PROVIDE (__dtors_end__, .) - -.rodata 0x2000020c 0x4 - *(.rodata .rodata.*) - .rodata 0x2000020c 0x4 ./src/main.o - *(.gnu.linkonce.r.*) - 0x20000210 . = ALIGN (0x4) - -.init_array 0x20000210 0x0 - *(.init) - *(.fini) - 0x20000210 PROVIDE (__preinit_array_start, .) - *(.preinit_array) - 0x20000210 PROVIDE (__preinit_array_end, .) - 0x20000210 PROVIDE (__init_array_start, .) - *(SORT(.init_array.*)) - *(.init_array) - 0x20000210 PROVIDE (__init_array_end, .) - 0x20000210 PROVIDE (__fini_array_start, .) - *(.fini_array) - *(SORT(.fini_array.*)) - 0x20000210 PROVIDE (__fini_array_end, .) - 0x20000210 . = ALIGN (0x4) - 0x20000210 __exidx_start = . - -.ARM.exidx - *(.ARM.exidx* .gnu.linkonce.armexidx.*) - 0x20000210 __exidx_end = . - 0x20000210 _vectext = . - 0x20000210 PROVIDE (vectext, .) - -.vect 0x20000210 0x0 - 0x20000210 _vecstart = . - *(.vectram) - 0x20000210 _vecend = . - 0x20000210 _etext = (_vectext + SIZEOF (.vect)) - 0x20000210 PROVIDE (etext, .) - -.data 0x20000210 0x0 - *(.data .data.*) - .data 0x20000210 0x0 ./src/crt.o - .data 0x20000210 0x0 ./src/main.o - *(.gnu.linkonce.d.*) - 0x20000210 . = ALIGN (0x4) - 0x20000210 __data_start = . - 0x20000210 _edata = . - 0x20000210 PROVIDE (edata, .) - -.bss 0x20000210 0x0 - 0x20000210 __bss_start = . - 0x20000210 __bss_start__ = . - *(.bss .bss.*) - .bss 0x20000210 0x0 ./src/crt.o - .bss 0x20000210 0x0 ./src/main.o - *(.gnu.linkonce.b.*) - *(COMMON) - 0x20000210 . = ALIGN (0x4) - 0x20000210 . = ALIGN (0x4) - 0x20000210 __bss_end__ = . - 0x20000210 _end = . - 0x20000210 PROVIDE (end, .) - -.heap 0x20000210 0x400 - 0x20000210 __heap_start__ = . - *(.heap) - 0x20000610 . = ((__heap_start__ + _HEAPSIZE) MAX_K .) - *fill* 0x20000210 0x400 00 - 0x20000610 __heap_end__ = (__heap_start__ + SIZEOF (.heap)) - -.stack 0x20000610 0x400 - 0x20000610 __stack_start__ = . - *(.stack) - 0x20000a10 . = ((__stack_start__ + _STACKSIZE) MAX_K .) - *fill* 0x20000610 0x400 00 - 0x20000a10 __stack_end__ = (__stack_start__ + SIZEOF (.stack)) - -.stack_irq 0x20000a10 0x100 - 0x20000a10 __stack_irq_start__ = . - *(.stack_irq) - 0x20000b10 . = ((__stack_irq_start__ + _STACKSIZE_IRQ) MAX_K .) - *fill* 0x20000a10 0x100 00 - 0x20000b10 __stack_irq_end__ = (__stack_irq_start__ + SIZEOF (.stack_irq)) - -.stack_fiq 0x20000b10 0x0 - 0x20000b10 __stack_fiq_start__ = . - *(.stack_fiq) - 0x20000b10 . = ((__stack_fiq_start__ + _STACKSIZE_FIQ) MAX_K .) - 0x20000b10 __stack_fiq_end__ = (__stack_fiq_start__ + SIZEOF (.stack_fiq)) - -.stack_svc 0x20000b10 0x400 - 0x20000b10 __stack_svc_start__ = . - *(.stack_svc) - 0x20000f10 . = ((__stack_svc_start__ + _STACKSIZE_SVC) MAX_K .) - *fill* 0x20000b10 0x400 00 - 0x20000f10 __stack_svc_end__ = (__stack_svc_start__ + SIZEOF (.stack_svc)) - -.stack_abt 0x20000f10 0x0 - 0x20000f10 __stack_abt_start__ = . - *(.stack_abt) - 0x20000f10 . = ((__stack_abt_start__ + _STACKSIZE_ABT) MAX_K .) - 0x20000f10 __stack_abt_end__ = (__stack_abt_start__ + SIZEOF (.stack_abt)) - -.stack_und 0x20000f10 0x0 - 0x20000f10 __stack_und_start__ = . - *(.stack_und) - 0x20000f10 . = ((__stack_und_start__ + _STACKSIZE_UND) MAX_K .) - 0x20000f10 __stack_und_end__ = (__stack_und_start__ + SIZEOF (.stack_und)) - -.stab - *(.stab) - -.stabstr - *(.stabstr) - -.stab.excl - *(.stab.excl) - -.stab.exclstr - *(.stab.exclstr) - -.stab.index - *(.stab.index) - -.stab.indexstr - *(.stab.indexstr) - -.comment 0x00000000 0x12 - *(.comment) - .comment 0x00000000 0x12 ./src/main.o - -.debug - *(.debug) - -.line - *(.line) - -.debug_srcinfo - *(.debug_srcinfo) - -.debug_sfnames - *(.debug_sfnames) - -.debug_aranges 0x00000000 0x48 - *(.debug_aranges) - .debug_aranges - 0x00000000 0x28 ./src/crt.o - .debug_aranges - 0x00000028 0x20 ./src/main.o - -.debug_pubnames - 0x00000000 0x1b - *(.debug_pubnames) - .debug_pubnames - 0x00000000 0x1b ./src/main.o - -.debug_info 0x00000000 0x1a6 - *(.debug_info .gnu.linkonce.wi.*) - .debug_info 0x00000000 0x73 ./src/crt.o - .debug_info 0x00000073 0x133 ./src/main.o - -.debug_abbrev 0x00000000 0x6d - *(.debug_abbrev) - .debug_abbrev 0x00000000 0x12 ./src/crt.o - .debug_abbrev 0x00000012 0x5b ./src/main.o - -.debug_line 0x00000000 0xf9 - *(.debug_line) - .debug_line 0x00000000 0xa2 ./src/crt.o - .debug_line 0x000000a2 0x57 ./src/main.o - -.debug_frame 0x00000000 0x24 - *(.debug_frame) - .debug_frame 0x00000000 0x24 ./src/main.o - -.debug_str - *(.debug_str) - -.debug_loc 0x00000000 0x1f - *(.debug_loc) - .debug_loc 0x00000000 0x1f ./src/main.o - -.debug_macinfo - *(.debug_macinfo) - -.debug_weaknames - *(.debug_weaknames) - -.debug_funcnames - *(.debug_funcnames) - -.debug_typenames - *(.debug_typenames) - -.debug_varnames - *(.debug_varnames) -OUTPUT(test_ram.elf elf32-littlearm) - -.ARM.attributes - 0x00000000 0x10 - .ARM.attributes - 0x00000000 0x10 ./src/crt.o - .ARM.attributes - 0x00000010 0x10 ./src/main.o - -.debug_ranges 0x00000000 0x20 - .debug_ranges 0x00000000 0x20 ./src/crt.o - -Cross Reference Table - -Symbol File -DAbortHandler ./src/crt.o -ExitFunction ./src/crt.o -FIQHandler ./src/crt.o -IRQHandler ./src/crt.o -PAbortHandler ./src/crt.o -ResetHandler ./src/crt.o -UndefHandler ./src/crt.o -__bss_end__ ./src/crt.o -__bss_start__ ./src/crt.o -__ctors_end__ ./src/crt.o -__ctors_start__ ./src/crt.o -__data_start ./src/crt.o -__stack_abt_end__ ./src/crt.o -__stack_fiq_end__ ./src/crt.o -__stack_irq_end__ ./src/crt.o -__stack_svc_end__ ./src/crt.o -__stack_und_end__ ./src/crt.o -_edata ./src/crt.o -_etext ./src/crt.o -main ./src/main.o - ./src/crt.o diff --git a/testing/examples/STR710Test/test_rom.elf b/testing/examples/STR710Test/test_rom.elf deleted file mode 100644 index 892baa8621ca9328173ebadb081158c38ea991d8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 41263 zcmeI1ZH!!18ONV{@9YcRzDx^96G*)1sx5(;-LfsUCNkT7X_s#4va<_;tWIZVZg(f$ zo!QRJ))FBs#h3_+)PAr=OE(C9&<_}63=x_%N|Xp6ikhhKg=O6Y37Q>4A_U^~|D1Er zowJ)_{NNYkbKuG}duJaS7#?&SCr?pvX$Lvl&h(&t=PXex+8*-Z-$B>X zHXUD3Nf{h7NtcLg3%eHhAVmlW0U;m+gn$qb0zyCt2mv7=1cZPP5CTF#2nYcoAOwVf z5D)@FKnMr{As_^VfDjM@LO=)z0U;m+gn$qb0zyCt2mv7=1cZPP5CTF#2nYcoAOwVf z5D)@FKnMr{As_^VfDjM@LO=)z0U;m+gn$qb0zyCt2mv7=1cZPP5CTF#2nYcoAOwVf z5D)@FKnMr{As_^VfDjM@LO=)z0U;m+gn$qb0zyCt2mv7=1cZPP5CTF#2nYcoAOwVf z5D)@FKnMr{As_^V!2cS7#U-MTt{dFN<;2ztD`y$#`(OyFPTeL5r{TQ3IT+D8#%ao)Bty@mnid;6asQGekOUA2I7yor2O zuR_ZeI_Xjd5#O#G;o~~vpuK$fO{WWUcYR~UMVmlNXxq{5#h%GO3w<83N8aEZwwu-cA&i(wT*=oAs_^V zfDjM@LO=)z0U;m+guwp`fdhSg`}`dT?i}Cg_oQ~Ec18Q{MC&R$p^mTMdnuzV^=+pu z9B)8%sfMG@n=h4Bw4y?6CJ@r4RxP9p)q1K%efuT~_fLJP zRGyfw%mx#)$4a%rbWokB%mw92p*T^m&X_h$WFsqVexETl1!OWV|x9O;Yp?C`w2uvFo{H8F!=Xis4>*J&?I=d0Y# zmusb|a!~ZO!)>cgSE_YCc9+U^auY2xmGYFY?KWkvN$~pbIWpQ$Zt5p$CyJ=k?_7u7 znQ0j(>y|t@1Ha}qoT;}=k~667Q!NE@4ru!Uo{;BiDUx&BE!@fD&+AqWle3kQt>dj; z`}OUgYQGvkIl$w<>R``SXPc93#o(RP(eZh>h`f)H*S@dga~(rh$>*c&F z#4_IBVz+mFDxKbwPIsqwrTPEvblTgHN_R#7c^wFMVT2yl^eCGL+^yZ5pWf5W#q}{k z7Q?%=n~zsoVJclJW1Z2ZgoW1cp9_k?v07>x-B4OwK11FwvA#oxhM$_6dc;lex;G*g zqB!I{uzBMqN^&v^XCFn|znL@iUFOgi_+~qb>e7SS54(2@4*4KISt5telPWwW8w`t2 zDopj;4Et0`)$X6I=O-yut5A0uWen5B30a4KJ~S4)%gcm$YGG?&@mf6!i!9KNP-A#=&lg5sqFAM}%r=tkHk zk9ofGFef()$GF^t$~K>HX1?)sa}2oR@%UNGc~L(A)$B_2}%VEr~t;_2^gFBBqM8)KN8`{_$dJ=i>M>*V>*!L}){pY?# z)X7Fv45A-Hn?4+R0eK&fa=0$c`sXi*uRQApN*&(ep{h2UR;uA ziT)I;=Da*VUwfwX0KfX#4zmxWU8!W)=|#Kc`$20x zbM&l1JRZ>3@rWX>W38h{6|PsUqq~rQV@C0)jhnc5WN2uYr*;vCk&k~)tm09JrFgvf zd8zy!e#o|qN1JVl{4MLWeFk~Ft%^X?+X%S_pDSG&A-^MSGm;wNPT2gfoi2@V4-9@! z(xnj&z-ZnVjc^RQd3`m){5oBMUO?5Q5zfQNM2axqm$kj9n?}fwk0!-Nh}(;{>mZJe z@Vhu>Ed31ZeoH?Kd&JT|hi%S3UwIeT>0d#=6I~x1zYM)<>DQp&we*|N?^*h<&>vd* zJ!lM*;f9SC2iLTvH$k^s`dVmve*8^<_-_KLJI)@jA0?xX(4Rzn*wWq5=PdnM=$~3T z1O1Yv?|^>G(ma2cHD4CmlmvL+2hH~j-x&_BD9$(c4_{%tz8R}O$6vDa1dqoRC5iEl z!@fC+`v{!mSad%naX&p8<(mBOKu3SeQT?CMabL$1^enV*jdyWf{)^Dus^UP|ftHSq-f z2HIZlA31J~x4cgOeNBJxVr}iOLqB4Dc-8q!vX0|z)EPg5b^KP=@&56=VI4hxlXwfd z7kY=qqX^A^M?)5%I&@-9ej|K{b_VtbD_V;E7 zNLhV@quLl59`5cNr4d9A_Yd8zt&!N;f8@v*!ku}_nfKw*pcd47i^VF9m+^+Ltn58Q zsvYT_#8;g%`}a zr*b?Z?^C6b-b_49pgs!*PL=9|^W{RlR4HpF{IOu>!1n+T!ZYOfb0HR!wOTy60vHb) zO|7To$<-oq>f0mkV#c4x*k*jaEB3^@Vhik!l}^MyeHxmx@j}*)z+58F!GYcpMu^qN z3)a6|MB8c3q}Lbqi`m;?`P$6|>eI@~ diff --git a/testing/examples/STR710Test/test_rom.hex b/testing/examples/STR710Test/test_rom.hex deleted file mode 100644 index c649ca02a..000000000 --- a/testing/examples/STR710Test/test_rom.hex +++ /dev/null @@ -1,37 +0,0 @@ -:020000044000BA -:100000000000A0E10000A0E10000A0E10000A0E1EC -:100010000000A0E10000A0E10000A0E10000A0E1DC -:100020000A02A0E304119FE5501080E50A02A0E354 -:100030000010A0E3441080E50A02A0E30010A0E352 -:100040000A02A0E37310A0E3181080E5081090E501 -:10005000020011E3FCFFFF0A0A02A0E3D0109FE5B3 -:10006000081080E5DBF021E3C8D09FE5D7F021E35D -:10007000C4D09FE5D1F021E3C0D09FE5D2F021E3C9 -:10008000BCD09FE5D3F021E3B8D09FE5B8109FE541 -:10009000B8209FE5B8309FE5030052E10400913499 -:1000A00004008234FBFFFF3A0000A0E3A4109FE5A8 -:1000B000A4209FE5020051E104008134FCFFFF3AD7 -:1000C00098009FE598109FE5010050E10500000AA7 -:1000D000042090E403002DE90FE0A0E102F0A0E18C -:1000E0000300BDE8F7FFFFEA00000FE1C000C0E336 -:1000F00000F029E10000A0E30010A0E364209FE5E8 -:100100000FE0A0E112FF2FE10000A0E10000A0E15C -:100110000000A0E1FBFFFFEAFEFFFFEAFEFFFFEAAF -:10012000FEFFFFEAFEFFFFEAFEFFFFEAFEFFFFEA37 -:10013000C201000009800000000D0020000D002019 -:100140000009002000090020000D002010020040DE -:10015000000000200000002000000020000000201F -:100160000C0200400C0200406C0100400CD04DE23B -:100170000130A0E300308DE50230A0E304308DE5CE -:100180000030A0E308308DE538309FE5002093E58E -:1001900000309DE5023083E000308DE500309DE5C4 -:1001A000013083E200308DE504309DE5013083E2CB -:1001B00004308DE500209DE504309DE5033082E0AC -:0C01C00008308DE5F4FFFFEA0C0200405F -:1001CC0018F09FE518F09FE518F09FE518F09FE5F3 -:1001DC0018F09FE518F09FE518F09FE518F09FE5E3 -:1001EC0000000040180100401C01004020010040AC -:1001FC002401004000000000280100402C010040B8 -:04020C0007000000E7 -:0400000540000000B7 -:00000001FF diff --git a/testing/examples/STR710Test/test_rom.map b/testing/examples/STR710Test/test_rom.map deleted file mode 100644 index ca2866542..000000000 --- a/testing/examples/STR710Test/test_rom.map +++ /dev/null @@ -1,300 +0,0 @@ - -Memory Configuration - -Name Origin Length Attributes -CODE 0x40000000 0x00040000 xr -DATA 0x20000000 0x00010000 rw -*default* 0x00000000 0xffffffff - -Linker script and memory map - -LOAD ./src/crt.o -LOAD ./src/main.o -START GROUP -LOAD d:/compiler/yagarto/bin/../lib/gcc/arm-elf/4.2.2\libgcc.a -LOAD d:/compiler/yagarto/bin/../lib/gcc/arm-elf/4.2.2/../../../../arm-elf/lib\libc.a -END GROUP - 0x00000400 _STACKSIZE = 0x400 - 0x00000100 _STACKSIZE_IRQ = 0x100 - 0x00000000 _STACKSIZE_FIQ = 0x0 - 0x00000400 _STACKSIZE_SVC = 0x400 - 0x00000000 _STACKSIZE_ABT = 0x0 - 0x00000000 _STACKSIZE_UND = 0x0 - 0x00000400 _HEAPSIZE = 0x400 - -.text 0x40000000 0x1cc - CREATE_OBJECT_SYMBOLS - *(.vectrom) - *(.init) - .init 0x40000000 0x16c ./src/crt.o - 0x4000012c FIQHandler - 0x40000120 PAbortHandler - 0x40000108 ExitFunction - 0x40000000 ResetHandler - 0x40000124 DAbortHandler - 0x40000128 IRQHandler - 0x40000118 UndefHandler - *(.text .text.*) - .text 0x4000016c 0x0 ./src/crt.o - .text 0x4000016c 0x60 ./src/main.o - 0x4000016c main - *(.gnu.linkonce.t.*) - *(.glue_7t) - .glue_7t 0x400001cc 0x0 ./src/crt.o - .glue_7t 0x400001cc 0x0 ./src/main.o - *(.glue_7) - .glue_7 0x400001cc 0x0 ./src/crt.o - .glue_7 0x400001cc 0x0 ./src/main.o - *(.vfp11_veneer) - .vfp11_veneer 0x400001cc 0x0 ./src/crt.o - .vfp11_veneer 0x400001cc 0x0 ./src/main.o - *(.fini) - *(.gcc_except_table) - -.vectors 0x400001cc 0x40 - .vectors 0x400001cc 0x40 ./src/crt.o - 0x4000020c . = ALIGN (0x4) - -.ctors 0x4000020c 0x0 - 0x4000020c PROVIDE (__ctors_start__, .) - *(SORT(.ctors.*)) - *(.ctors) - 0x4000020c PROVIDE (__ctors_end__, .) - -.dtors 0x4000020c 0x0 - 0x4000020c PROVIDE (__dtors_start__, .) - *(SORT(.dtors.*)) - *(.dtors) - 0x4000020c PROVIDE (__dtors_end__, .) - -.rodata 0x4000020c 0x4 - *(.rodata .rodata.*) - .rodata 0x4000020c 0x4 ./src/main.o - *(.gnu.linkonce.r.*) - 0x40000210 . = ALIGN (0x4) - -.init_array 0x40000210 0x0 - *(.init) - *(.fini) - 0x40000210 PROVIDE (__preinit_array_start, .) - *(.preinit_array) - 0x40000210 PROVIDE (__preinit_array_end, .) - 0x40000210 PROVIDE (__init_array_start, .) - *(SORT(.init_array.*)) - *(.init_array) - 0x40000210 PROVIDE (__init_array_end, .) - 0x40000210 PROVIDE (__fini_array_start, .) - *(.fini_array) - *(SORT(.fini_array.*)) - 0x40000210 PROVIDE (__fini_array_end, .) - 0x40000210 . = ALIGN (0x4) - 0x40000210 __exidx_start = . - -.ARM.exidx - *(.ARM.exidx* .gnu.linkonce.armexidx.*) - 0x40000210 __exidx_end = . - 0x40000210 _vectext = . - 0x40000210 PROVIDE (vectext, .) - -.vect 0x20000000 0x0 load address 0x40000210 - 0x20000000 _vecstart = . - *(.vectram) - 0x20000000 _vecend = . - 0x40000210 _etext = (_vectext + SIZEOF (.vect)) - 0x20000000 PROVIDE (etext, .) - -.data 0x20000000 0x0 load address 0x40000210 - 0x20000000 __data_start = . - *(.data .data.*) - .data 0x20000000 0x0 ./src/crt.o - .data 0x20000000 0x0 ./src/main.o - *(.gnu.linkonce.d.*) - 0x20000000 . = ALIGN (0x4) - *(.fastrun .fastrun.*) - 0x20000000 . = ALIGN (0x4) - 0x20000000 _edata = . - 0x20000000 PROVIDE (edata, .) - -.bss 0x20000000 0x0 load address 0x40000210 - 0x20000000 __bss_start = . - 0x20000000 __bss_start__ = . - *(.bss .bss.*) - .bss 0x20000000 0x0 ./src/crt.o - .bss 0x20000000 0x0 ./src/main.o - *(.gnu.linkonce.b.*) - *(COMMON) - 0x20000000 . = ALIGN (0x4) - 0x20000000 . = ALIGN (0x4) - 0x20000000 __bss_end__ = . - 0x20000000 _end = . - 0x20000000 PROVIDE (end, .) - -.heap 0x20000000 0x400 - 0x20000000 __heap_start__ = . - *(.heap) - 0x20000400 . = ((__heap_start__ + _HEAPSIZE) MAX_K .) - *fill* 0x20000000 0x400 00 - 0x20000400 __heap_end__ = (__heap_start__ + SIZEOF (.heap)) - -.stack 0x20000400 0x400 - 0x20000400 __stack_start__ = . - *(.stack) - 0x20000800 . = ((__stack_start__ + _STACKSIZE) MAX_K .) - *fill* 0x20000400 0x400 00 - 0x20000800 __stack_end__ = (__stack_start__ + SIZEOF (.stack)) - -.stack_irq 0x20000800 0x100 - 0x20000800 __stack_irq_start__ = . - *(.stack_irq) - 0x20000900 . = ((__stack_irq_start__ + _STACKSIZE_IRQ) MAX_K .) - *fill* 0x20000800 0x100 00 - 0x20000900 __stack_irq_end__ = (__stack_irq_start__ + SIZEOF (.stack_irq)) - -.stack_fiq 0x20000900 0x0 - 0x20000900 __stack_fiq_start__ = . - *(.stack_fiq) - 0x20000900 . = ((__stack_fiq_start__ + _STACKSIZE_FIQ) MAX_K .) - 0x20000900 __stack_fiq_end__ = (__stack_fiq_start__ + SIZEOF (.stack_fiq)) - -.stack_svc 0x20000900 0x400 - 0x20000900 __stack_svc_start__ = . - *(.stack_svc) - 0x20000d00 . = ((__stack_svc_start__ + _STACKSIZE_SVC) MAX_K .) - *fill* 0x20000900 0x400 00 - 0x20000d00 __stack_svc_end__ = (__stack_svc_start__ + SIZEOF (.stack_svc)) - -.stack_abt 0x20000d00 0x0 - 0x20000d00 __stack_abt_start__ = . - *(.stack_abt) - 0x20000d00 . = ((__stack_abt_start__ + _STACKSIZE_ABT) MAX_K .) - 0x20000d00 __stack_abt_end__ = (__stack_abt_start__ + SIZEOF (.stack_abt)) - -.stack_und 0x20000d00 0x0 - 0x20000d00 __stack_und_start__ = . - *(.stack_und) - 0x20000d00 . = ((__stack_und_start__ + _STACKSIZE_UND) MAX_K .) - 0x20000d00 __stack_und_end__ = (__stack_und_start__ + SIZEOF (.stack_und)) - -.stab - *(.stab) - -.stabstr - *(.stabstr) - -.stab.excl - *(.stab.excl) - -.stab.exclstr - *(.stab.exclstr) - -.stab.index - *(.stab.index) - -.stab.indexstr - *(.stab.indexstr) - -.comment 0x00000000 0x12 - *(.comment) - .comment 0x00000000 0x12 ./src/main.o - -.debug - *(.debug) - -.line - *(.line) - -.debug_srcinfo - *(.debug_srcinfo) - -.debug_sfnames - *(.debug_sfnames) - -.debug_aranges 0x00000000 0x48 - *(.debug_aranges) - .debug_aranges - 0x00000000 0x28 ./src/crt.o - .debug_aranges - 0x00000028 0x20 ./src/main.o - -.debug_pubnames - 0x00000000 0x1b - *(.debug_pubnames) - .debug_pubnames - 0x00000000 0x1b ./src/main.o - -.debug_info 0x00000000 0x1a6 - *(.debug_info .gnu.linkonce.wi.*) - .debug_info 0x00000000 0x73 ./src/crt.o - .debug_info 0x00000073 0x133 ./src/main.o - -.debug_abbrev 0x00000000 0x6d - *(.debug_abbrev) - .debug_abbrev 0x00000000 0x12 ./src/crt.o - .debug_abbrev 0x00000012 0x5b ./src/main.o - -.debug_line 0x00000000 0xf9 - *(.debug_line) - .debug_line 0x00000000 0xa2 ./src/crt.o - .debug_line 0x000000a2 0x57 ./src/main.o - -.debug_frame 0x00000000 0x24 - *(.debug_frame) - .debug_frame 0x00000000 0x24 ./src/main.o - -.debug_str - *(.debug_str) - -.debug_loc 0x00000000 0x1f - *(.debug_loc) - .debug_loc 0x00000000 0x1f ./src/main.o - -.debug_macinfo - *(.debug_macinfo) - -.debug_weaknames - *(.debug_weaknames) - -.debug_funcnames - *(.debug_funcnames) - -.debug_typenames - *(.debug_typenames) - -.debug_varnames - *(.debug_varnames) -OUTPUT(test_rom.elf elf32-littlearm) - -.ARM.attributes - 0x00000000 0x10 - .ARM.attributes - 0x00000000 0x10 ./src/crt.o - .ARM.attributes - 0x00000010 0x10 ./src/main.o - -.debug_ranges 0x00000000 0x20 - .debug_ranges 0x00000000 0x20 ./src/crt.o - -Cross Reference Table - -Symbol File -DAbortHandler ./src/crt.o -ExitFunction ./src/crt.o -FIQHandler ./src/crt.o -IRQHandler ./src/crt.o -PAbortHandler ./src/crt.o -ResetHandler ./src/crt.o -UndefHandler ./src/crt.o -__bss_end__ ./src/crt.o -__bss_start__ ./src/crt.o -__ctors_end__ ./src/crt.o -__ctors_start__ ./src/crt.o -__data_start ./src/crt.o -__stack_abt_end__ ./src/crt.o -__stack_fiq_end__ ./src/crt.o -__stack_irq_end__ ./src/crt.o -__stack_svc_end__ ./src/crt.o -__stack_und_end__ ./src/crt.o -_edata ./src/crt.o -_etext ./src/crt.o -main ./src/main.o - ./src/crt.o diff --git a/testing/examples/STR912Test/inc/typedefs.h b/testing/examples/STR912Test/inc/typedefs.h deleted file mode 100644 index f43416d52..000000000 --- a/testing/examples/STR912Test/inc/typedefs.h +++ /dev/null @@ -1,50 +0,0 @@ -/**************************************************************************** -* Copyright (c) 2006 by Michael Fischer. All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* 1. Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the author nor the names of its contributors may -* be used to endorse or promote products derived from this software -* without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -* THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS -* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED -* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF -* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -* SUCH DAMAGE. -* -**************************************************************************** -* History: -* -* 30.03.06 mifi First Version for Insight tutorial -****************************************************************************/ -#ifndef __TYPEDEFS_H__ -#define __TYPEDEFS_H__ - -/* - * Some types to use Windows like source - */ -typedef char CHAR; /* 8-bit signed data */ -typedef unsigned char BYTE; /* 8-bit unsigned data */ -typedef unsigned short WORD; /* 16-bit unsigned data */ -typedef long LONG; /* 32-bit signed data */ -typedef unsigned long ULONG; /* 32-bit unsigned data */ -typedef unsigned long DWORD; /* 32-bit unsigned data */ - - -#endif /* !__TYPEDEFS_H__ */ -/*** EOF ***/ diff --git a/testing/examples/STR912Test/makefile b/testing/examples/STR912Test/makefile deleted file mode 100644 index ee7685795..000000000 --- a/testing/examples/STR912Test/makefile +++ /dev/null @@ -1,146 +0,0 @@ -# -# !!!! Do NOT edit this makefile with an editor which replace tabs by spaces !!!! -# -############################################################################################## -# -# On command line: -# -# make all = Create project -# -# make clean = Clean project files. -# -# To rebuild project do "make clean" and "make all". -# - -############################################################################################## -# Start of default section -# - -TRGT = arm-elf- -CC = $(TRGT)gcc -CP = $(TRGT)objcopy -AS = $(TRGT)gcc -x assembler-with-cpp -BIN = $(CP) -O ihex - -MCU = arm9e - -# List all default C defines here, like -D_DEBUG=1 -DDEFS = - -# List all default ASM defines here, like -D_DEBUG=1 -DADEFS = - -# List all default directories to look for include files here -DINCDIR = - -# List the default directory to look for the libraries here -DLIBDIR = - -# List all default libraries here -DLIBS = - -# -# End of default section -############################################################################################## - -############################################################################################## -# Start of user section -# - -# Define project name here -PROJECT = test - -# Define linker script file here -LDSCRIPT_RAM = ./prj/str912_ram.ld -LDSCRIPT_ROM = ./prj/str912_rom.ld - -# List all user C define here, like -D_DEBUG=1 -UDEFS = - -# Define ASM defines here -UADEFS = - -# List C source files here -SRC = ./src/main.c - -# List ASM source files here -ASRC = ./src/startup.s - -# List all user directories here -UINCDIR = ./inc - -# List the user directory to look for the libraries here -ULIBDIR = - -# List all user libraries here -ULIBS = - -# Define optimisation level here -OPT = -O0 - -# -# End of user defines -############################################################################################## - - -INCDIR = $(patsubst %,-I%,$(DINCDIR) $(UINCDIR)) -LIBDIR = $(patsubst %,-L%,$(DLIBDIR) $(ULIBDIR)) -DEFS = $(DDEFS) $(UDEFS) -ADEFS = $(DADEFS) $(UADEFS) -OBJS = $(ASRC:.s=.o) $(SRC:.c=.o) -LIBS = $(DLIBS) $(ULIBS) -MCFLAGS = -mcpu=$(MCU) - -ASFLAGS = $(MCFLAGS) -g -gdwarf-2 -Wa,-amhls=$(<:.s=.lst) $(ADEFS) -CPFLAGS = $(MCFLAGS) $(OPT) -gdwarf-2 -mthumb-interwork -fomit-frame-pointer -Wall -Wstrict-prototypes -fverbose-asm -Wa,-ahlms=$(<:.c=.lst) $(DEFS) -LDFLAGS_RAM = $(MCFLAGS) -nostartfiles -T$(LDSCRIPT_RAM) -Wl,-Map=$(PROJECT)_ram.map,--cref,--no-warn-mismatch $(LIBDIR) -LDFLAGS_ROM = $(MCFLAGS) -nostartfiles -T$(LDSCRIPT_ROM) -Wl,-Map=$(PROJECT)_rom.map,--cref,--no-warn-mismatch $(LIBDIR) - -# Generate dependency information -CPFLAGS += -MD -MP -MF .dep/$(@F).d - -# -# makefile rules -# - -all: RAM ROM - -RAM: $(OBJS) $(PROJECT)_ram.elf $(PROJECT)_ram.hex - -ROM: $(OBJS) $(PROJECT)_rom.elf $(PROJECT)_rom.hex - -%o : %c - $(CC) -c $(CPFLAGS) -I . $(INCDIR) $< -o $@ - -%o : %s - $(AS) -c $(ASFLAGS) $< -o $@ - -%ram.elf: $(OBJS) - $(CC) $(OBJS) $(LDFLAGS_RAM) $(LIBS) -o $@ - -%rom.elf: $(OBJS) - $(CC) $(OBJS) $(LDFLAGS_ROM) $(LIBS) -o $@ - -%hex: %elf - $(BIN) $< $@ - -clean: - -rm -f $(OBJS) - -rm -f $(PROJECT)_ram.elf - -rm -f $(PROJECT)_ram.map - -rm -f $(PROJECT)_ram.hex - -rm -f $(PROJECT)_rom.elf - -rm -f $(PROJECT)_rom.map - -rm -f $(PROJECT)_rom.hex - -rm -f $(SRC:.c=.c.bak) - -rm -f $(SRC:.c=.lst) - -rm -f $(ASRC:.s=.s.bak) - -rm -f $(ASRC:.s=.lst) - -rm -fR .dep - -# -# Include the dependency files, should be the last of the makefile -# --include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*) - -# *** EOF *** \ No newline at end of file diff --git a/testing/examples/STR912Test/prj/eclipse_ram.gdb b/testing/examples/STR912Test/prj/eclipse_ram.gdb deleted file mode 100644 index 00a62d705..000000000 --- a/testing/examples/STR912Test/prj/eclipse_ram.gdb +++ /dev/null @@ -1,21 +0,0 @@ -target remote localhost:3333 -monitor reset -monitor sleep 500 -monitor poll -monitor soft_reset_halt -monitor arm7_9 sw_bkpts enable - -# Set SRAM size to 96 KB -monitor mww 0x5C002034 0x0197 -monitor mdw 0x5C002034 - -# Set Flash, Bank0 size to 512 KB -monitor mww 0x54000000 0xf - -load -break main -continue - - - - diff --git a/testing/examples/STR912Test/prj/eclipse_rom.gdb b/testing/examples/STR912Test/prj/eclipse_rom.gdb deleted file mode 100644 index 58977cfcd..000000000 --- a/testing/examples/STR912Test/prj/eclipse_rom.gdb +++ /dev/null @@ -1,21 +0,0 @@ -target remote localhost:3333 -monitor reset -monitor sleep 500 -monitor poll -monitor soft_reset_halt -monitor arm7_9 force_hw_bkpts enable - -# Set SRAM size to 96 KB -monitor mww 0x5C002034 0x0197 -monitor mdw 0x5C002034 - -# Set Flash, Bank0 size to 512 KB -monitor mww 0x54000000 0xf - -load -break main -continue - - - - diff --git a/testing/examples/STR912Test/prj/str912_jtagkey.cfg b/testing/examples/STR912Test/prj/str912_jtagkey.cfg deleted file mode 100644 index f379e0d38..000000000 --- a/testing/examples/STR912Test/prj/str912_jtagkey.cfg +++ /dev/null @@ -1,41 +0,0 @@ -#daemon configuration -telnet_port 4444 -gdb_port 3333 - -# tell gdb our flash memory map -# and enable flash programming -gdb_memory_map enable -gdb_flash_program enable - -#interface -interface ft2232 -ft2232_device_desc "Amontec JTAGkey A" -ft2232_layout jtagkey -ft2232_vid_pid 0x0403 0xcff8 -jtag_speed 1 - -jtag_nsrst_delay 100 -jtag_ntrst_delay 100 - -#use combined on interfaces or targets that can't set TRST/SRST separately -reset_config trst_and_srst - -#jtag scan chain -jtag newtap str9 flash -irlen 8 -jtag newtap str9 cpu -irlen 4 -irmask 0xf -jtag newtap str9 bs -irlen 5 - -#target configuration -target create target0 arm966e -endian little -chain-position 1 -[new_target_name] configure -work-area-virt 0 -work-area-phys 0x50000000 -work-area-size 16384 -work-area-backup false - -target_script 0 gdb_program_config .\prj\str912_program.script - -#flash bank str7x 0 0 -flash bank str9x 0x00000000 0x00080000 0 0 0 - -# For more information about the configuration files, -# look at the OpenOCD User's Guide. - -init -reset halt diff --git a/testing/examples/STR912Test/prj/str912_program.script b/testing/examples/STR912Test/prj/str912_program.script deleted file mode 100644 index df0239b9d..000000000 --- a/testing/examples/STR912Test/prj/str912_program.script +++ /dev/null @@ -1,9 +0,0 @@ -str9x flash_config 0 4 2 0 0x80000 -flash protect 0 0 7 off - - - - - - - diff --git a/testing/examples/STR912Test/prj/str912_ram.ld b/testing/examples/STR912Test/prj/str912_ram.ld deleted file mode 100644 index 269ada9bf..000000000 --- a/testing/examples/STR912Test/prj/str912_ram.ld +++ /dev/null @@ -1,218 +0,0 @@ -/*********************************************************************************** -* Copyright 2005 Anglia Design -* This demo code and associated components are provided as is and has no warranty, -* implied or otherwise. You are free to use/modify any of the provided -* code at your own risk in your applications with the expressed limitation -* of liability (see below) -* -* LIMITATION OF LIABILITY: ANGLIA OR ANGLIA DESIGNS SHALL NOT BE LIABLE FOR ANY -* LOSS OF PROFITS, LOSS OF USE, LOSS OF DATA, INTERRUPTION OF BUSINESS, NOR FOR -* INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES OF ANY KIND WHETHER UNDER -* THIS AGREEMENT OR OTHERWISE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. -* -* Author : Spencer Oliver -* Web : www.anglia-designs.com -* -***********************************************************************************/ - -/* Stack Sizes */ - - _STACKSIZE = 1024; - _STACKSIZE_IRQ = 256; - _STACKSIZE_FIQ = 0; - _STACKSIZE_SVC = 1024; - _STACKSIZE_ABT = 0; - _STACKSIZE_UND = 0; - _HEAPSIZE = 1024; - -/* Memory Definitions */ - -MEMORY -{ - DATA (rw) : ORIGIN = 0x04000000, LENGTH = 0x00018000 -} - -/* Section Definitions */ - -SECTIONS -{ - /* first section is .text which is used for code */ - - .text : - { - KEEP(*(.vectors)) - KEEP(*(.init)) - *(.text .text.*) - *(.gnu.linkonce.t.*) - *(.glue_7t .glue_7) - KEEP(*(.fini)) - *(.gcc_except_table) - } >DATA =0 - . = ALIGN(4); - - /* .ctors .dtors are used for c++ constructors/destructors */ - - .ctors : - { - PROVIDE(__ctors_start__ = .); - KEEP(*(SORT(.ctors.*))) - KEEP(*(.ctors)) - PROVIDE(__ctors_end__ = .); - } >DATA - - .dtors : - { - PROVIDE(__dtors_start__ = .); - KEEP(*(SORT(.dtors.*))) - KEEP(*(.dtors)) - PROVIDE(__dtors_end__ = .); - } >DATA - - /* .rodata section which is used for read-only data (constants) */ - - .rodata : - { - *(.rodata .rodata.*) - *(.gnu.linkonce.r.*) - } >DATA - . = ALIGN(4); - - _etext = .; - PROVIDE (etext = .); - - /* .data section which is used for initialized data */ - - .data : AT (_etext) - { - *(.data .data.*) - *(.gnu.linkonce.d.*) - SORT(CONSTRUCTORS) - } >DATA - . = ALIGN(4); - - __data_start = .; - _edata = .; - PROVIDE (edata = .); - - /* .bss section which is used for uninitialized data */ - - .bss : - { - __bss_start = .; - __bss_start__ = .; - *(.bss .bss.*) - *(.gnu.linkonce.b.*) - *(COMMON) - . = ALIGN(4); - } >DATA - . = ALIGN(4); - __bss_end__ = .; - - _end = .; - PROVIDE(end = .); - - /* .heap section which is used for memory allocation */ - - .heap (NOLOAD) : - { - __heap_start__ = .; - *(.heap) - . = MAX(__heap_start__ + _HEAPSIZE , .); - } >DATA - __heap_end__ = __heap_start__ + SIZEOF(.heap); - - /* .stack section - user mode stack */ - - .stack (__heap_end__ + 3) / 4 * 4 (NOLOAD) : - { - __stack_start__ = .; - *(.stack) - . = MAX(__stack_start__ + _STACKSIZE , .); - } >DATA - __stack_end__ = __stack_start__ + SIZEOF(.stack); - - /* .stack_irq section */ - - .stack_irq (__stack_end__ + 3) / 4 * 4 (NOLOAD) : - { - __stack_irq_start__ = .; - *(.stack_irq) - . = MAX(__stack_irq_start__ + _STACKSIZE_IRQ , .); - } >DATA - __stack_irq_end__ = __stack_irq_start__ + SIZEOF(.stack_irq); - - /* .stack_fiq section */ - - .stack_fiq (__stack_irq_end__ + 3) / 4 * 4 (NOLOAD) : - { - __stack_fiq_start__ = .; - *(.stack_fiq) - . = MAX(__stack_fiq_start__ + _STACKSIZE_FIQ , .); - } >DATA - __stack_fiq_end__ = __stack_fiq_start__ + SIZEOF(.stack_fiq); - - /* .stack_svc section */ - - .stack_svc (__stack_fiq_end__ + 3) / 4 * 4 (NOLOAD) : - { - __stack_svc_start__ = .; - *(.stack_svc) - . = MAX(__stack_svc_start__ + _STACKSIZE_SVC , .); - } >DATA - __stack_svc_end__ = __stack_svc_start__ + SIZEOF(.stack_svc); - - /* .stack_abt section */ - - .stack_abt (__stack_svc_end__ + 3) / 4 * 4 (NOLOAD) : - { - __stack_abt_start__ = .; - *(.stack_abt) - . = MAX(__stack_abt_start__ + _STACKSIZE_ABT , .); - } >DATA - __stack_abt_end__ = __stack_abt_start__ + SIZEOF(.stack_abt); - - /* .stack_und section */ - - .stack_und (__stack_abt_end__ + 3) / 4 * 4 (NOLOAD) : - { - __stack_und_start__ = .; - *(.stack_und) - . = MAX(__stack_und_start__ + _STACKSIZE_UND , .); - } >DATA - __stack_und_end__ = __stack_und_start__ + SIZEOF(.stack_und); - - /* Stabs debugging sections. */ - .stab 0 : { *(.stab) } - .stabstr 0 : { *(.stabstr) } - .stab.excl 0 : { *(.stab.excl) } - .stab.exclstr 0 : { *(.stab.exclstr) } - .stab.index 0 : { *(.stab.index) } - .stab.indexstr 0 : { *(.stab.indexstr) } - .comment 0 : { *(.comment) } - /* DWARF debug sections. - Symbols in the DWARF debugging sections are relative to the beginning - of the section so we begin them at 0. */ - /* DWARF 1 */ - .debug 0 : { *(.debug) } - .line 0 : { *(.line) } - /* GNU DWARF 1 extensions */ - .debug_srcinfo 0 : { *(.debug_srcinfo) } - .debug_sfnames 0 : { *(.debug_sfnames) } - /* DWARF 1.1 and DWARF 2 */ - .debug_aranges 0 : { *(.debug_aranges) } - .debug_pubnames 0 : { *(.debug_pubnames) } - /* DWARF 2 */ - .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } - .debug_abbrev 0 : { *(.debug_abbrev) } - .debug_line 0 : { *(.debug_line) } - .debug_frame 0 : { *(.debug_frame) } - .debug_str 0 : { *(.debug_str) } - .debug_loc 0 : { *(.debug_loc) } - .debug_macinfo 0 : { *(.debug_macinfo) } - /* SGI/MIPS DWARF 2 extensions */ - .debug_weaknames 0 : { *(.debug_weaknames) } - .debug_funcnames 0 : { *(.debug_funcnames) } - .debug_typenames 0 : { *(.debug_typenames) } - .debug_varnames 0 : { *(.debug_varnames) } -} - diff --git a/testing/examples/STR912Test/prj/str912_rom.ld b/testing/examples/STR912Test/prj/str912_rom.ld deleted file mode 100644 index 804149d21..000000000 --- a/testing/examples/STR912Test/prj/str912_rom.ld +++ /dev/null @@ -1,249 +0,0 @@ -/*********************************************************************************** -* Copyright 2005 Anglia Design -* This demo code and associated components are provided as is and has no warranty, -* implied or otherwise. You are free to use/modify any of the provided -* code at your own risk in your applications with the expressed limitation -* of liability (see below) -* -* LIMITATION OF LIABILITY: ANGLIA OR ANGLIA DESIGNS SHALL NOT BE LIABLE FOR ANY -* LOSS OF PROFITS, LOSS OF USE, LOSS OF DATA, INTERRUPTION OF BUSINESS, NOR FOR -* INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES OF ANY KIND WHETHER UNDER -* THIS AGREEMENT OR OTHERWISE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. -* -* Author : Spencer Oliver -* Web : www.anglia-designs.com -* -***********************************************************************************/ - -/* Stack Sizes */ - - _STACKSIZE = 1024; - _STACKSIZE_IRQ = 256; - _STACKSIZE_FIQ = 0; - _STACKSIZE_SVC = 1024; - _STACKSIZE_ABT = 0; - _STACKSIZE_UND = 0; - _HEAPSIZE = 1024; - -/* Memory Definitions */ - -MEMORY -{ - CODE (rx) : ORIGIN = 0x00000000, LENGTH = 0x00080000 - DATA (rw) : ORIGIN = 0x04000000, LENGTH = 0x00018000 -} - -/* Section Definitions */ - -SECTIONS -{ - /* first section is .text which is used for code */ - - .text : - { - CREATE_OBJECT_SYMBOLS - KEEP(*(.vectors)) - KEEP(*(.init)) - *(.text .text.*) - *(.gnu.linkonce.t.*) - *(.glue_7t) *(.glue_7) *(.vfp11_veneer) - KEEP(*(.fini)) - *(.gcc_except_table) - } >CODE =0 - . = ALIGN(4); - - /* .ctors .dtors are used for c++ constructors/destructors */ - - .ctors : - { - PROVIDE(__ctors_start__ = .); - KEEP(*(SORT(.ctors.*))) - KEEP(*(.ctors)) - PROVIDE(__ctors_end__ = .); - } >CODE - - .dtors : - { - PROVIDE(__dtors_start__ = .); - KEEP(*(SORT(.dtors.*))) - KEEP(*(.dtors)) - PROVIDE(__dtors_end__ = .); - } >CODE - - /* .rodata section which is used for read-only data (constants) */ - - .rodata : - { - *(.rodata .rodata.*) - *(.gnu.linkonce.r.*) - } >CODE - . = ALIGN(4); - - .init_array : - { - *(.init) - *(.fini) - PROVIDE_HIDDEN (__preinit_array_start = .); - KEEP (*(.preinit_array)) - PROVIDE_HIDDEN (__preinit_array_end = .); - PROVIDE_HIDDEN (__init_array_start = .); - KEEP (*(SORT(.init_array.*))) - KEEP (*(.init_array)) - PROVIDE_HIDDEN (__init_array_end = .); - PROVIDE_HIDDEN (__fini_array_start = .); - KEEP (*(.fini_array)) - KEEP (*(SORT(.fini_array.*))) - PROVIDE_HIDDEN (__fini_array_end = .); - } >CODE - - . = ALIGN(4); - - /* .ARM.exidx is sorted, so has to go in its own output section. */ - __exidx_start = .; - .ARM.exidx : - { - *(.ARM.exidx* .gnu.linkonce.armexidx.*) - } >CODE - __exidx_end = .; - - _etext = .; - PROVIDE (etext = .); - - /* .data section which is used for initialized data */ - - .data : AT (_etext) - { - __data_start = .; - *(.data .data.*) - *(.gnu.linkonce.d.*) - SORT(CONSTRUCTORS) - . = ALIGN(4); - *(.fastrun .fastrun.*) - } >DATA - . = ALIGN(4); - - _edata = .; - PROVIDE (edata = .); - - /* .bss section which is used for uninitialized data */ - - .bss : - { - __bss_start = .; - __bss_start__ = .; - *(.bss .bss.*) - *(.gnu.linkonce.b.*) - *(COMMON) - . = ALIGN(4); - } >DATA - . = ALIGN(4); - __bss_end__ = .; - - _end = .; - PROVIDE(end = .); - - /* .heap section which is used for memory allocation */ - - .heap (NOLOAD) : - { - __heap_start__ = .; - *(.heap) - . = MAX(__heap_start__ + _HEAPSIZE , .); - } >DATA - __heap_end__ = __heap_start__ + SIZEOF(.heap); - - /* .stack section - user mode stack */ - - .stack (__heap_end__ + 3) / 4 * 4 (NOLOAD) : - { - __stack_start__ = .; - *(.stack) - . = MAX(__stack_start__ + _STACKSIZE , .); - } >DATA - __stack_end__ = __stack_start__ + SIZEOF(.stack); - - /* .stack_irq section */ - - .stack_irq (__stack_end__ + 3) / 4 * 4 (NOLOAD) : - { - __stack_irq_start__ = .; - *(.stack_irq) - . = MAX(__stack_irq_start__ + _STACKSIZE_IRQ , .); - } >DATA - __stack_irq_end__ = __stack_irq_start__ + SIZEOF(.stack_irq); - - /* .stack_fiq section */ - - .stack_fiq (__stack_irq_end__ + 3) / 4 * 4 (NOLOAD) : - { - __stack_fiq_start__ = .; - *(.stack_fiq) - . = MAX(__stack_fiq_start__ + _STACKSIZE_FIQ , .); - } >DATA - __stack_fiq_end__ = __stack_fiq_start__ + SIZEOF(.stack_fiq); - - /* .stack_svc section */ - - .stack_svc (__stack_fiq_end__ + 3) / 4 * 4 (NOLOAD) : - { - __stack_svc_start__ = .; - *(.stack_svc) - . = MAX(__stack_svc_start__ + _STACKSIZE_SVC , .); - } >DATA - __stack_svc_end__ = __stack_svc_start__ + SIZEOF(.stack_svc); - - /* .stack_abt section */ - - .stack_abt (__stack_svc_end__ + 3) / 4 * 4 (NOLOAD) : - { - __stack_abt_start__ = .; - *(.stack_abt) - . = MAX(__stack_abt_start__ + _STACKSIZE_ABT , .); - } >DATA - __stack_abt_end__ = __stack_abt_start__ + SIZEOF(.stack_abt); - - /* .stack_und section */ - - .stack_und (__stack_abt_end__ + 3) / 4 * 4 (NOLOAD) : - { - __stack_und_start__ = .; - *(.stack_und) - . = MAX(__stack_und_start__ + _STACKSIZE_UND , .); - } >DATA - __stack_und_end__ = __stack_und_start__ + SIZEOF(.stack_und); - - /* Stabs debugging sections. */ - .stab 0 : { *(.stab) } - .stabstr 0 : { *(.stabstr) } - .stab.excl 0 : { *(.stab.excl) } - .stab.exclstr 0 : { *(.stab.exclstr) } - .stab.index 0 : { *(.stab.index) } - .stab.indexstr 0 : { *(.stab.indexstr) } - .comment 0 : { *(.comment) } - /* DWARF debug sections. - Symbols in the DWARF debugging sections are relative to the beginning - of the section so we begin them at 0. */ - /* DWARF 1 */ - .debug 0 : { *(.debug) } - .line 0 : { *(.line) } - /* GNU DWARF 1 extensions */ - .debug_srcinfo 0 : { *(.debug_srcinfo) } - .debug_sfnames 0 : { *(.debug_sfnames) } - /* DWARF 1.1 and DWARF 2 */ - .debug_aranges 0 : { *(.debug_aranges) } - .debug_pubnames 0 : { *(.debug_pubnames) } - /* DWARF 2 */ - .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } - .debug_abbrev 0 : { *(.debug_abbrev) } - .debug_line 0 : { *(.debug_line) } - .debug_frame 0 : { *(.debug_frame) } - .debug_str 0 : { *(.debug_str) } - .debug_loc 0 : { *(.debug_loc) } - .debug_macinfo 0 : { *(.debug_macinfo) } - /* SGI/MIPS DWARF 2 extensions */ - .debug_weaknames 0 : { *(.debug_weaknames) } - .debug_funcnames 0 : { *(.debug_funcnames) } - .debug_typenames 0 : { *(.debug_typenames) } - .debug_varnames 0 : { *(.debug_varnames) } -} - diff --git a/testing/examples/STR912Test/src/main.c b/testing/examples/STR912Test/src/main.c deleted file mode 100644 index 99f2d2628..000000000 --- a/testing/examples/STR912Test/src/main.c +++ /dev/null @@ -1,91 +0,0 @@ -/**************************************************************************** -* Copyright (c) 2006 by Michael Fischer. All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* 1. Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* 3. Neither the name of the author nor the names of its contributors may -* be used to endorse or promote products derived from this software -* without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -* THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS -* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED -* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF -* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -* SUCH DAMAGE. -* -**************************************************************************** -* History: -* -* 30.03.06 mifi First Version for Insight tutorial -* 26.01.08 mifi Added variable "d" to test const variable. -****************************************************************************/ -#define __MAIN_C__ - -/* - * I use the include only, to show - * how to setup a include dir in the makefile - */ -#include "typedefs.h" - -/*=========================================================================*/ -/* DEFINE: All Structures and Common Constants */ -/*=========================================================================*/ - -/*=========================================================================*/ -/* DEFINE: Prototypes */ -/*=========================================================================*/ - -/*=========================================================================*/ -/* DEFINE: Definition of all local Data */ -/*=========================================================================*/ -static const DWORD d = 7; - -/*=========================================================================*/ -/* DEFINE: Definition of all local Procedures */ -/*=========================================================================*/ - -/*=========================================================================*/ -/* DEFINE: All code exported */ -/*=========================================================================*/ -/***************************************************************************/ -/* main */ -/***************************************************************************/ -int main (void) -{ - DWORD a = 1; - DWORD b = 2; - DWORD c = 0; - - a = a + d; - - while (1) - { - a++; - b++; - c = a + b; - } - - /* - * This return here make no sense. - * But to prevent the compiler warning: - * "return type of 'main' is not 'int' - * we use an int as return :-) - */ - return(0); -} - -/*** EOF ***/ diff --git a/testing/examples/STR912Test/src/startup.s b/testing/examples/STR912Test/src/startup.s deleted file mode 100644 index 15f03d2b8..000000000 --- a/testing/examples/STR912Test/src/startup.s +++ /dev/null @@ -1,222 +0,0 @@ -/*********************************************************************************** -* Copyright 2005 Anglia Design -* This demo code and associated components are provided as is and has no warranty, -* implied or otherwise. You are free to use/modify any of the provided -* code at your own risk in your applications with the expressed limitation -* of liability (see below) -* -* LIMITATION OF LIABILITY: ANGLIA OR ANGLIA DESIGNS SHALL NOT BE LIABLE FOR ANY -* LOSS OF PROFITS, LOSS OF USE, LOSS OF DATA, INTERRUPTION OF BUSINESS, NOR FOR -* INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES OF ANY KIND WHETHER UNDER -* THIS AGREEMENT OR OTHERWISE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. -* -* Author : Spencer Oliver -* Web : www.anglia-designs.com -* -* mifi, 22.01.2008, small changes by the init of the C++ eabi constructors. -* Here I have replaced the eabi init by the normal init. -* Thanks to Spen for the startup code. -***********************************************************************************/ - -/**** Startup Code (executed after Reset) ****/ - -/* Frequency values kHz */ -/* set to suit target hardware */ - - .equ FOSC, 25000 - -/* Standard definitions of Mode bits and Interrupt (I & F) flags in PSRs */ - - .equ Mode_USR, 0x10 - .equ Mode_FIQ, 0x11 - .equ Mode_IRQ, 0x12 - .equ Mode_SVC, 0x13 - .equ Mode_ABT, 0x17 - .equ Mode_UND, 0x1B - .equ Mode_SYS, 0x1F /* available on ARM Arch 4 and later */ - - .equ I_Bit, 0x80 /* when I bit is set, IRQ is disabled */ - .equ F_Bit, 0x40 /* when F bit is set, FIQ is disabled */ - - .equ SRAM32, 0x00 - .equ SRAM64, 0x08 - .equ SRAM96, 0x10 - -/* --- System memory locations */ - - .equ SCRO_AHB_UMB, 0x5C002034 /* System configuration register 0 (unbuffered) */ - - .equ FMI_BASE_UMB, 0x54000000 /* Flash FMI base address (unbuffered) */ - .equ BBSR_off_addr, 0x00 - .equ NBBSR_off_addr, 0x04 - .equ BBADR_off_addr, 0x0C - .equ NBBADR_off_addr, 0x10 - .equ CR_off_addr, 0x18 - -.ifndef LIBUFF - .equ LIBUFF, 0 -.endif - -/* Startup Code must be linked first at Address at which it expects to run. */ - - .text - .arm - .section .init, "ax" - - .global _start - .global _Main_Crystal - -/* After remap this will be our reset handler */ - -_start: - LDR pc, =NextInst -NextInst: - - NOP /* Wait for OSC stabilization */ - NOP - NOP - NOP - NOP - NOP - NOP - NOP - NOP - -/* Enable buffered mode */ - -.if LIBUFF - MRC p15, 0, r0, c1, c0, 0 /* Read CP15 register 1 into r0 */ - ORR r0, r0, #0x8 /* Enable Write Buffer on AHB */ - MCR p15, 0, r0, c1, c0, 0 /* Write CP15 register 1 */ -.endif - -/* Remap Flash Bank 0 at address 0x0 and Bank 1 at address 0x80000, */ -/* when the bank 0 is the boot bank, then enable the Bank 1. */ - - LDR r0, =FMI_BASE_UMB - LDR r1, =0x4 /* configure 512KB Boot bank 0 */ - STR r1, [r0, #BBSR_off_addr] - - LDR r1, =0x2 /* configure 32KB Non Boot bank 1 */ - STR r1, [r0, #NBBSR_off_addr] - - LDR r1, =(0x00000000 >> 2) /* Boot Bank Base Address */ - STR r1, [r0, #BBADR_off_addr] - - LDR r1, =(0x00080000 >> 2) /* Non Boot Bank Base Address */ - STR r1, [r0, #NBBADR_off_addr] - - LDR r1, =0x18 /* Flash Banks 0 1 enabled */ - STR r1, [r0, #CR_off_addr] - -/* Enable 96K RAM */ - - LDR r0, =SCRO_AHB_UMB -# LDR r1, =0x0196 /* prefetch disabled, default enabled */ - LDR r1, =0x0187|SRAM96 - STR r1, [r0] - -/* Set bits 17-18 (Instruction/Data TCM order) of the */ -/* Core Configuration Control Register */ - - MOV r0, #0x60000 - MCR p15, 0x1, r0, c15, c1, 0 - -/* Setup Stack for each mode */ - -/* Enter Abort Mode and set its Stack Pointer */ - - MSR cpsr_c, #Mode_ABT|I_Bit|F_Bit - LDR sp, =__stack_abt_end__ - -/* Enter Undefined Instruction Mode and set its Stack Pointer */ - - MSR cpsr_c, #Mode_UND|I_Bit|F_Bit - LDR sp, =__stack_und_end__ - -/* Enter Supervisor Mode and set its Stack Pointer */ - - MSR cpsr_c, #Mode_SVC|I_Bit|F_Bit - LDR sp, =__stack_svc_end__ - -/* Enter FIQ Mode and set its Stack Pointer */ - - MSR cpsr_c, #Mode_FIQ|I_Bit|F_Bit - LDR sp, =__stack_fiq_end__ - -/* Enter IRQ Mode and set its Stack Pointer */ - - MSR cpsr_c, #Mode_IRQ|I_Bit|F_Bit - LDR sp, =__stack_irq_end__ - -/* Enter System/User Mode and set its Stack Pointer */ - - MSR cpsr_c, #Mode_SYS - LDR sp, =__stack_end__ - -/* Setup a default Stack Limit (when compiled with "-mapcs-stack-check") */ - - LDR sl, =__bss_end__ - -/* Relocate .data section (Copy from ROM to RAM) */ - - LDR r1, =_etext - LDR r2, =__data_start - LDR r3, =_edata -LoopRel: - CMP r2, r3 - LDRLO r0, [r1], #4 - STRLO r0, [r2], #4 - BLO LoopRel - -/* Clear .bss section (Zero init) */ - - MOV r0, #0 - LDR r1, =__bss_start__ - LDR r2, =__bss_end__ -LoopZI: - CMP r1, r2 - STRLO r0, [r1], #4 - BLO LoopZI - -/* Call C++ constructors */ - - LDR r0, =__ctors_start__ - LDR r1, =__ctors_end__ -ctor_loop: - CMP r0, r1 - BEQ ctor_end - LDR r2, [r0], #4 - STMFD sp!, {r0-r1} - BLX r2 - LDMFD sp!, {r0-r1} - B ctor_loop -ctor_end: - -/* Need to set up standard file handles */ -/* Only used under simulator, normally overide syscall.c */ - -# BL initialise_monitor_handles - -/* if we use debug version of str9lib this will call the init function */ - - BL libdebug -libdebug: - -/* Enter the C code, use B instruction so as to never return */ -/* use BL main if you want to use c++ destructors below */ - - B main - -/* Return from main, loop forever. */ - -#exit_loop: -# B exit_loop - -/* Fosc values, used by libstr9 */ - -_Main_Crystal: .long FOSC - - .weak libdebug - - .end diff --git a/testing/examples/STR912Test/test_ram.elf b/testing/examples/STR912Test/test_ram.elf deleted file mode 100644 index 8e14d5560aef54f1cd5a651ffbf628c0b629d42d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 40512 zcmeI1U2Ggz701u)%-T-uB%1_UOGWBN3MEDDuCv*OG)3U`S86#<8m|qd7>#Fl$M&lB zuDiQ#6A@ImDN;dvBoskah_XVF$OGyFyzo#S_>clmloqK#Uz!?AB_Pz1Dio5@%)6WqlETTN6(SL~c zQ!0#a1WAaHbrl1+CAn*Z4Q6$KeZ2=?M*Ay-lWvVRs!0BCg=h72iuz|=t1~{ z(AVh7*0mJs!tUv7Z|>cb{rhWgAJ}~UT? zv=mwzZRpCDNi#Prx|Fx*>HNFCe;n)GTtj>w@dTYg?5X^F=wHCx3+OlKA@tEsD}C|L zCf)m&oS(g6($C(y<@+~%-~Vfh=;k$t2su_hP4nM1h_3D?D{4DobK8Mt{CjJokK4e@ z({CC>;4<{}tpv0MP0)SN$FOcnKL`IZVi(@v9JY<23vaS*DLWXGz8v`G(9>`5*mtl_ zuHXB?+D@`sAs_^VfDjM@LO=)z0U;m+guwqs;Kb{0K(<9(vWO)}V-Sr-*TI+YHexW zJ?pHlt+>tk;_S@*hjX*&CY)5dP)z4ChmVo5k;Q}w`Vbai85|i^=WFoXyueKP|1~k6 zQ5$UolO>G4^0L!ly^VbZ+Joz9~r=pY}BcX#h11Hv=nFRl?$XM=Dz zC3z!R=5;a-XO)<{GTH2q`jZ>V9?9mjxz3*)2ea^5Y+#IbR_d6gFf*NTTCGO4w2qsW&*8t7JCMj%99xaW zq78hZ3bsJttEUjr0l3`F7Xxvt{Zz;_%<9;8t31vPzCR%^DxzXglvQ?+m&A9fFQbF6 zjuP%?If}-1kjLM&zM>o`7M)j6c96&4zrKo&_o;U>HU=hL{RYuKHk9akbMUpzp`Rje zm<=Vk9|Ni27|*+fJZ7pz$6DynHpljVljy}*hc-91<^B93QJn`U(RrArtKQHhqStg% zEcQao=5XJ)D0m96&7u+g5Vo$({r4d6PBxV27(W?JqBY$=g*<)Fai7lH8|LXW`aJS} z5qX_F&JS*I6&w5xIO8td2S10#>*M-6&@gW#4}Xv7t=K?4ZxulCZ-J&Z3iI5+2YoF{wZ1 zalPmn74)05Yg>HxHh)iWhWvdv6wl`scCL@-^RtexO(>o}2!mON;`s+)@V^(Kc>c#> z@HJXMcPCC*gPYiRX{Q-#`n+^QT}8E04(Y&qOvGp8qh89ZH^W!;i0b5k7zC zhJtv$dbrJMejWuf^h<@P8HaZ^HjW%zpMbB`ALj3c->GlXZSdpkKL|fwFAM*c>Pch#v2F1a@H_Q9 z{}lVN^IzB&ce~;}bPm22UjMTkk9c_g3+$`sQ;L%GVwdmvFR>rv^&9r1>t)d&;cMag zG;z8(O4Id=L0@ROwF(`q=r_;`*~Qty=u~m? zk#U<(+qQ$(JR2`{Y&BZ89Z#9V>DzAbcBnJ)CTOE5=h^(C7&)b8vs1$6WyJk(nsp3R zgQxNH$sTQ-LtrIZ2FIgisHH7dAB*+zEUH3~7!Bn!P=N=>3lH%bA{H$w{5`3b+?gU= zrWzNap_OVWc(IMM;LTyX!5gw>;gni>PLzn2!rjpnQBj-sn;yw0rDj#9$y}pBs!wO| Pq+u{B5T$nN^QQe5>@ZVm diff --git a/testing/examples/STR912Test/test_ram.hex b/testing/examples/STR912Test/test_ram.hex deleted file mode 100644 index 3c22e299e..000000000 --- a/testing/examples/STR912Test/test_ram.hex +++ /dev/null @@ -1,30 +0,0 @@ -:020000040400F6 -:10000000F8F09FE50000A0E10000A0E10000A0E101 -:100010000000A0E10000A0E10000A0E10000A0E1DC -:100020000000A0E10000A0E11503A0E30410A0E39C -:10003000001080E50210A0E3041080E50010A0E3AA -:100040000C1080E50218A0E3101080E51810A0E362 -:10005000181080E5A8009FE5A8109FE5001080E536 -:100060000608A0E3110F2FEED7F021E398D09FE50B -:10007000DBF021E394D09FE5D3F021E390D09FE51E -:10008000D1F021E38CD09FE5D2F021E388D09FE529 -:100090001FF021E384D09FE584A09FE584109FE5B5 -:1000A00084209FE584309FE5030052E104009134F1 -:1000B00004008234FBFFFF3A0000A0E370109FE5CC -:1000C0005C209FE5020051E104008134FCFFFF3A0F -:1000D00060009FE560109FE5010050E10400000A08 -:1000E000042090E403002DE932FF2FE10300BDE876 -:1000F000F8FFFFEAFFFFFFEB100000EAA861000035 -:10010000040000043420005C97010000A40E0004E9 -:10011000A40E0004A40E0004A40A0004A40A00040F -:10012000A4090004A4010004A4010004A401000423 -:10013000A4010004A4010004A0010004A001000423 -:100140000CD04DE20130A0E300308DE50230A0E399 -:1001500004308DE50030A0E308308DE538309FE5B0 -:10016000002093E500309DE5023083E000308DE50E -:1001700000309DE5013083E200308DE504309DE5DF -:10018000013083E204308DE500209DE504309DE5DB -:10019000033082E008308DE5F4FFFFEAA00100049F -:0401A0000700000054 -:0400000504000000F3 -:00000001FF diff --git a/testing/examples/STR912Test/test_ram.map b/testing/examples/STR912Test/test_ram.map deleted file mode 100644 index 249b70bdc..000000000 --- a/testing/examples/STR912Test/test_ram.map +++ /dev/null @@ -1,255 +0,0 @@ - -Memory Configuration - -Name Origin Length Attributes -DATA 0x04000000 0x00018000 rw -*default* 0x00000000 0xffffffff - -Linker script and memory map - -LOAD ./src/startup.o -LOAD ./src/main.o -START GROUP -LOAD d:/compiler/yagarto/bin/../lib/gcc/arm-elf/4.2.2\libgcc.a -LOAD d:/compiler/yagarto/bin/../lib/gcc/arm-elf/4.2.2/../../../../arm-elf/lib\libc.a -END GROUP - 0x00000400 _STACKSIZE = 0x400 - 0x00000100 _STACKSIZE_IRQ = 0x100 - 0x00000000 _STACKSIZE_FIQ = 0x0 - 0x00000400 _STACKSIZE_SVC = 0x400 - 0x00000000 _STACKSIZE_ABT = 0x0 - 0x00000000 _STACKSIZE_UND = 0x0 - 0x00000400 _HEAPSIZE = 0x400 - -.text 0x04000000 0x1a0 - *(.vectors) - *(.init) - .init 0x04000000 0x140 ./src/startup.o - 0x040000fc _Main_Crystal - 0x04000000 _start - 0x040000f8 libdebug - *(.text .text.*) - .text 0x04000140 0x0 ./src/startup.o - .text 0x04000140 0x60 ./src/main.o - 0x04000140 main - *(.gnu.linkonce.t.*) - *(.glue_7t .glue_7) - .glue_7 0x040001a0 0x0 ./src/startup.o - .glue_7t 0x040001a0 0x0 ./src/startup.o - .glue_7 0x040001a0 0x0 ./src/main.o - .glue_7t 0x040001a0 0x0 ./src/main.o - *(.fini) - *(.gcc_except_table) - -.vfp11_veneer 0x040001a0 0x0 - .vfp11_veneer 0x040001a0 0x0 ./src/startup.o - .vfp11_veneer 0x040001a0 0x0 ./src/main.o - 0x040001a0 . = ALIGN (0x4) - -.ctors 0x040001a0 0x0 - 0x040001a0 PROVIDE (__ctors_start__, .) - *(SORT(.ctors.*)) - *(.ctors) - 0x040001a0 PROVIDE (__ctors_end__, .) - -.dtors 0x040001a0 0x0 - 0x040001a0 PROVIDE (__dtors_start__, .) - *(SORT(.dtors.*)) - *(.dtors) - 0x040001a0 PROVIDE (__dtors_end__, .) - -.rodata 0x040001a0 0x4 - *(.rodata .rodata.*) - .rodata 0x040001a0 0x4 ./src/main.o - *(.gnu.linkonce.r.*) - 0x040001a4 . = ALIGN (0x4) - 0x040001a4 _etext = . - 0x040001a4 PROVIDE (etext, .) - -.data 0x040001a4 0x0 - *(.data .data.*) - .data 0x040001a4 0x0 ./src/startup.o - .data 0x040001a4 0x0 ./src/main.o - *(.gnu.linkonce.d.*) - 0x040001a4 . = ALIGN (0x4) - 0x040001a4 __data_start = . - 0x040001a4 _edata = . - 0x040001a4 PROVIDE (edata, .) - -.bss 0x040001a4 0x0 - 0x040001a4 __bss_start = . - 0x040001a4 __bss_start__ = . - *(.bss .bss.*) - .bss 0x040001a4 0x0 ./src/startup.o - .bss 0x040001a4 0x0 ./src/main.o - *(.gnu.linkonce.b.*) - *(COMMON) - 0x040001a4 . = ALIGN (0x4) - 0x040001a4 . = ALIGN (0x4) - 0x040001a4 __bss_end__ = . - 0x040001a4 _end = . - 0x040001a4 PROVIDE (end, .) - -.heap 0x040001a4 0x400 - 0x040001a4 __heap_start__ = . - *(.heap) - 0x040005a4 . = ((__heap_start__ + _HEAPSIZE) MAX_K .) - *fill* 0x040001a4 0x400 00 - 0x040005a4 __heap_end__ = (__heap_start__ + SIZEOF (.heap)) - -.stack 0x040005a4 0x400 - 0x040005a4 __stack_start__ = . - *(.stack) - 0x040009a4 . = ((__stack_start__ + _STACKSIZE) MAX_K .) - *fill* 0x040005a4 0x400 00 - 0x040009a4 __stack_end__ = (__stack_start__ + SIZEOF (.stack)) - -.stack_irq 0x040009a4 0x100 - 0x040009a4 __stack_irq_start__ = . - *(.stack_irq) - 0x04000aa4 . = ((__stack_irq_start__ + _STACKSIZE_IRQ) MAX_K .) - *fill* 0x040009a4 0x100 00 - 0x04000aa4 __stack_irq_end__ = (__stack_irq_start__ + SIZEOF (.stack_irq)) - -.stack_fiq 0x04000aa4 0x0 - 0x04000aa4 __stack_fiq_start__ = . - *(.stack_fiq) - 0x04000aa4 . = ((__stack_fiq_start__ + _STACKSIZE_FIQ) MAX_K .) - 0x04000aa4 __stack_fiq_end__ = (__stack_fiq_start__ + SIZEOF (.stack_fiq)) - -.stack_svc 0x04000aa4 0x400 - 0x04000aa4 __stack_svc_start__ = . - *(.stack_svc) - 0x04000ea4 . = ((__stack_svc_start__ + _STACKSIZE_SVC) MAX_K .) - *fill* 0x04000aa4 0x400 00 - 0x04000ea4 __stack_svc_end__ = (__stack_svc_start__ + SIZEOF (.stack_svc)) - -.stack_abt 0x04000ea4 0x0 - 0x04000ea4 __stack_abt_start__ = . - *(.stack_abt) - 0x04000ea4 . = ((__stack_abt_start__ + _STACKSIZE_ABT) MAX_K .) - 0x04000ea4 __stack_abt_end__ = (__stack_abt_start__ + SIZEOF (.stack_abt)) - -.stack_und 0x04000ea4 0x0 - 0x04000ea4 __stack_und_start__ = . - *(.stack_und) - 0x04000ea4 . = ((__stack_und_start__ + _STACKSIZE_UND) MAX_K .) - 0x04000ea4 __stack_und_end__ = (__stack_und_start__ + SIZEOF (.stack_und)) - -.stab - *(.stab) - -.stabstr - *(.stabstr) - -.stab.excl - *(.stab.excl) - -.stab.exclstr - *(.stab.exclstr) - -.stab.index - *(.stab.index) - -.stab.indexstr - *(.stab.indexstr) - -.comment 0x00000000 0x12 - *(.comment) - .comment 0x00000000 0x12 ./src/main.o - -.debug - *(.debug) - -.line - *(.line) - -.debug_srcinfo - *(.debug_srcinfo) - -.debug_sfnames - *(.debug_sfnames) - -.debug_aranges 0x00000000 0x40 - *(.debug_aranges) - .debug_aranges - 0x00000000 0x20 ./src/startup.o - .debug_aranges - 0x00000020 0x20 ./src/main.o - -.debug_pubnames - 0x00000000 0x1b - *(.debug_pubnames) - .debug_pubnames - 0x00000000 0x1b ./src/main.o - -.debug_info 0x00000000 0x1ae - *(.debug_info .gnu.linkonce.wi.*) - .debug_info 0x00000000 0x7b ./src/startup.o - .debug_info 0x0000007b 0x133 ./src/main.o - -.debug_abbrev 0x00000000 0x6f - *(.debug_abbrev) - .debug_abbrev 0x00000000 0x14 ./src/startup.o - .debug_abbrev 0x00000014 0x5b ./src/main.o - -.debug_line 0x00000000 0xd7 - *(.debug_line) - .debug_line 0x00000000 0x80 ./src/startup.o - .debug_line 0x00000080 0x57 ./src/main.o - -.debug_frame 0x00000000 0x24 - *(.debug_frame) - .debug_frame 0x00000000 0x24 ./src/main.o - -.debug_str - *(.debug_str) - -.debug_loc 0x00000000 0x1f - *(.debug_loc) - .debug_loc 0x00000000 0x1f ./src/main.o - -.debug_macinfo - *(.debug_macinfo) - -.debug_weaknames - *(.debug_weaknames) - -.debug_funcnames - *(.debug_funcnames) - -.debug_typenames - *(.debug_typenames) - -.debug_varnames - *(.debug_varnames) -OUTPUT(test_ram.elf elf32-littlearm) - -.ARM.attributes - 0x00000000 0x10 - .ARM.attributes - 0x00000000 0x10 ./src/startup.o - .ARM.attributes - 0x00000010 0x10 ./src/main.o - -Cross Reference Table - -Symbol File -_Main_Crystal ./src/startup.o -__bss_end__ ./src/startup.o -__bss_start__ ./src/startup.o -__ctors_end__ ./src/startup.o -__ctors_start__ ./src/startup.o -__data_start ./src/startup.o -__stack_abt_end__ ./src/startup.o -__stack_end__ ./src/startup.o -__stack_fiq_end__ ./src/startup.o -__stack_irq_end__ ./src/startup.o -__stack_svc_end__ ./src/startup.o -__stack_und_end__ ./src/startup.o -_edata ./src/startup.o -_etext ./src/startup.o -_start ./src/startup.o -libdebug ./src/startup.o -main ./src/main.o - ./src/startup.o diff --git a/testing/examples/STR912Test/test_rom.elf b/testing/examples/STR912Test/test_rom.elf deleted file mode 100644 index 8d840fdf979f69b2af614428728518e57c774f60..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 40570 zcmeI1TWlOx8OOibSvyYbB%1`NrB>=j3Xr09*V$}Cnxf+MEwvIS&2G%47>#GWV|!J5 z*WF#W4h^c?6p11z2|=`6qO2-QL;~@EcmN3=xJc~_q7+1t`qI=`f*?>w`OPJ>lcz^dj#-xFl4%J#NS4v_km<`fB#H8rhW{Y#qm+)X znk0xd4B+0yu2nur69Pg&2nYcoAOwVf5D)@FKnMr{As_^VfDjM@LO=)z0U;m+gn$qb z0zyCt2mv7=1cZPP5CTF#2nYcoAOwVf5D)@FKnMr{As_^VfDjM@LO=)z0U;m+gn$qb z0zyCt2mv7=1cZPP5CTF#2nYcoAOwVf5D)@FKnMr{As_^VfDjM@LO=)z0U;m+gn$qb z0zyCt2mv7=1cZPP5CTF#2nYcoAOwVf5D)@FKnMr{As_^VfDjM@LO=)z0U;m+gn$qb z0zyCt2mvARzeV8IJ6AV|+SmVGf4|*cPo~=Ilv>?LKqesxvXAZl_Ie7kA9g?FHM+WS zErofZclWf{_w3I8{f&3_ufO!#)r~hHzYh63$cvD_h5Rz)>yTfByc_a4$miPVDfBe@ zz|{?#ir15LDW9Zg^X~@1F|2oe3Gpe!6Lbc#XY%jCKaJYc@LTiVUXMesG1UG^p_-l&j#x<7+Ih0S+)Qc9BoiM|`9Xj_Om6BZJxK8IG$u?~6eXmWt zZ4H3Sz*jaBkV!~_?14OrbyNB>>??>}c#Csbw+1e}&3e-4YE1fyvh9Iq-{P@1u}+?U zn<^^@As_^VfDjM@LO=)z0U;m+guwp^f#bu&$I=InpPIZUozLVlIc)nb^n}_z{~Xh8 zQ2$0#hK@f4UB@{#t<%);4jdE2@xzGx9&*vG)>P<86=F3RO~}KWjhSq-Lp_I;L4jmxIkzuo6i)-@&Gc*6K!n~t4`YMVg zte%;9x509`)~wFeyh>U-65E>d^+qclxvRAnC6ZkW_1auo>)VvRDZw83FMBwW>c;d3sJHhaxQOfzklk~v_rc!reK^G#>*Iae z{BYm+K29I(wh-vbM_Gv-DE1-ZbUKfopaXog-rcp6EHti&zc@#@NTLgb-PEP7QTr9L z4rNWVcV@EL0rMv}kUgBuXLFrDISyuFv&bnOroAJR#}+KB#FgoOKHjc=CR?px73NaG z5?be$yoxv5%*9X;G$8uedFj zGV`9h#98jlV@5dD#^a&dd}4+&Gxfzq57$7Z;+2=@9Jk@t=DcQTE-ja9?qbKT)@JKr z%q^E2-V>pU&{(LWN})KBaa*lMwY-d*miO?VwmXr?XB?NBZmatC3QheK zBH9lJ=kdvCLuo$~KB07Gn0JrK<6N}l8uHAeOgW67vancJb`p7CxP9J{cpkoKtvw$O zf{dvJqpSJw{cG(@aD)b*_--RB|&Hj6lcQ-4hg)x3I+C)pC{{-^Fdyai!-X5J7rqO4R_lwBt2#<-XxtQ#fVMzPK6+9uiVR8|=5umY|}9&U$p^tV*l z>hZvfG4bfGQPu1%Up;MngpD^_?V{tc2@mL4v#B>`asB8SrTjKN^2VD@yW%GDcdH%p z_hH@qfLGW#KYqZ^IzBhL`9VJvX04ka?1#etUg+irAA!Q}9J=|zVJMyJ+YdelyK|lR z!6@uiblv>m1e8Hz5&6NHNN2?lK80h4k{>v*WJ>t@kEp}ZHGd^V%nT*nW#!EU2-O$*mA=d-O_LalEwvh{r5iP_s( zH+Bm1^|NlS=M?@GxHrmWPJZwpZ1aBz%09luKDBAQA561t?jIh%$hJY0!g`L=(f*n=1|jkLWOzkgHQrUBS(Q-jz45XWQljl;eL7q>LV7q`S+wqxs^XFIn4 z&uxi6y(!*JmvvlC!s~yT?TCjT{D^Jy{7O+5y}HTvgFoo;(SFz2j?Q0_{-NX1{4{pD zG)xoqisww0idq>PKckiLqESkpFgb;xvnKh}h*nCUF44F%RBh3iI+lusiNiT!aU`$A z14pPdTs-X*9v*TgCx&Qj0{Ml~s4|9zN=2tWJL|ZWN`p>qHiw1^Bb%d}?BQ7K*fKO{)twIMX;Tvj&oYL9C@QKp+qoWRQ z+i}!upo5n_)*3CxiKk3r`;OzSR4XeE&*XUOO)?yXw?=mJ7>8dfBct4GcBV7q)$~Z@ z1;(R#0n3=iOf`WYUe0ji90Ci`0y!Qn&@6hk`gqL8HO&lRDLpms%>*7EEj+?|$F$KB z^)FGgfldj%OfxQmMhn%ldL@oi;>*VI)Vp;^#x1wPnwTQm1-qjX(WDMviQ!1zl&NaA X$&{l(#usLAQ5}pXh*CTA^X2?6kQ7LO diff --git a/testing/examples/STR912Test/test_rom.hex b/testing/examples/STR912Test/test_rom.hex deleted file mode 100644 index 1c1283a9d..000000000 --- a/testing/examples/STR912Test/test_rom.hex +++ /dev/null @@ -1,28 +0,0 @@ -:10000000F8F09FE50000A0E10000A0E10000A0E101 -:100010000000A0E10000A0E10000A0E10000A0E1DC -:100020000000A0E10000A0E11503A0E30410A0E39C -:10003000001080E50210A0E3041080E50010A0E3AA -:100040000C1080E50218A0E3101080E51810A0E362 -:10005000181080E5A8009FE5A8109FE5001080E536 -:100060000608A0E3110F2FEED7F021E398D09FE50B -:10007000DBF021E394D09FE5D3F021E390D09FE51E -:10008000D1F021E38CD09FE5D2F021E388D09FE529 -:100090001FF021E384D09FE584A09FE584109FE5B5 -:1000A00084209FE584309FE5030052E104009134F1 -:1000B00004008234FBFFFF3A0000A0E370109FE5CC -:1000C0005C209FE5020051E104008134FCFFFF3A0F -:1000D00060009FE560109FE5010050E10400000A08 -:1000E000042090E403002DE932FF2FE10300BDE876 -:1000F000F8FFFFEAFFFFFFEB100000EAA861000035 -:10010000040000003420005C97010000000D000492 -:10011000000D0004000D00040009000400090004A3 -:100120000008000400000004A40100000000000416 -:100130000000000400000004A0010000A001000075 -:100140000CD04DE20130A0E300308DE50230A0E399 -:1001500004308DE50030A0E308308DE538309FE5B0 -:10016000002093E500309DE5023083E000308DE50E -:1001700000309DE5013083E200308DE504309DE5DF -:10018000013083E204308DE500209DE504309DE5DB -:10019000033082E008308DE5F4FFFFEAA0010000A3 -:0401A0000700000054 -:00000001FF diff --git a/testing/examples/STR912Test/test_rom.map b/testing/examples/STR912Test/test_rom.map deleted file mode 100644 index 0f31cea80..000000000 --- a/testing/examples/STR912Test/test_rom.map +++ /dev/null @@ -1,280 +0,0 @@ - -Memory Configuration - -Name Origin Length Attributes -CODE 0x00000000 0x00080000 xr -DATA 0x04000000 0x00018000 rw -*default* 0x00000000 0xffffffff - -Linker script and memory map - -LOAD ./src/startup.o -LOAD ./src/main.o -START GROUP -LOAD d:/compiler/yagarto/bin/../lib/gcc/arm-elf/4.2.2\libgcc.a -LOAD d:/compiler/yagarto/bin/../lib/gcc/arm-elf/4.2.2/../../../../arm-elf/lib\libc.a -END GROUP - 0x00000400 _STACKSIZE = 0x400 - 0x00000100 _STACKSIZE_IRQ = 0x100 - 0x00000000 _STACKSIZE_FIQ = 0x0 - 0x00000400 _STACKSIZE_SVC = 0x400 - 0x00000000 _STACKSIZE_ABT = 0x0 - 0x00000000 _STACKSIZE_UND = 0x0 - 0x00000400 _HEAPSIZE = 0x400 - -.text 0x00000000 0x1a0 - CREATE_OBJECT_SYMBOLS - *(.vectors) - *(.init) - .init 0x00000000 0x140 ./src/startup.o - 0x000000fc _Main_Crystal - 0x00000000 _start - 0x000000f8 libdebug - *(.text .text.*) - .text 0x00000140 0x0 ./src/startup.o - .text 0x00000140 0x60 ./src/main.o - 0x00000140 main - *(.gnu.linkonce.t.*) - *(.glue_7t) - .glue_7t 0x000001a0 0x0 ./src/startup.o - .glue_7t 0x000001a0 0x0 ./src/main.o - *(.glue_7) - .glue_7 0x000001a0 0x0 ./src/startup.o - .glue_7 0x000001a0 0x0 ./src/main.o - *(.vfp11_veneer) - .vfp11_veneer 0x000001a0 0x0 ./src/startup.o - .vfp11_veneer 0x000001a0 0x0 ./src/main.o - *(.fini) - *(.gcc_except_table) - 0x000001a0 . = ALIGN (0x4) - -.ctors 0x000001a0 0x0 - 0x000001a0 PROVIDE (__ctors_start__, .) - *(SORT(.ctors.*)) - *(.ctors) - 0x000001a0 PROVIDE (__ctors_end__, .) - -.dtors 0x000001a0 0x0 - 0x000001a0 PROVIDE (__dtors_start__, .) - *(SORT(.dtors.*)) - *(.dtors) - 0x000001a0 PROVIDE (__dtors_end__, .) - -.rodata 0x000001a0 0x4 - *(.rodata .rodata.*) - .rodata 0x000001a0 0x4 ./src/main.o - *(.gnu.linkonce.r.*) - 0x000001a4 . = ALIGN (0x4) - -.init_array 0x000001a4 0x0 - *(.init) - *(.fini) - 0x000001a4 PROVIDE (__preinit_array_start, .) - *(.preinit_array) - 0x000001a4 PROVIDE (__preinit_array_end, .) - 0x000001a4 PROVIDE (__init_array_start, .) - *(SORT(.init_array.*)) - *(.init_array) - 0x000001a4 PROVIDE (__init_array_end, .) - 0x000001a4 PROVIDE (__fini_array_start, .) - *(.fini_array) - *(SORT(.fini_array.*)) - 0x000001a4 PROVIDE (__fini_array_end, .) - 0x000001a4 . = ALIGN (0x4) - 0x000001a4 __exidx_start = . - -.ARM.exidx - *(.ARM.exidx* .gnu.linkonce.armexidx.*) - 0x000001a4 __exidx_end = . - 0x000001a4 _etext = . - 0x000001a4 PROVIDE (etext, .) - -.data 0x04000000 0x0 load address 0x000001a4 - 0x04000000 __data_start = . - *(.data .data.*) - .data 0x04000000 0x0 ./src/startup.o - .data 0x04000000 0x0 ./src/main.o - *(.gnu.linkonce.d.*) - 0x04000000 . = ALIGN (0x4) - *(.fastrun .fastrun.*) - 0x04000000 . = ALIGN (0x4) - 0x04000000 _edata = . - 0x04000000 PROVIDE (edata, .) - -.bss 0x04000000 0x0 load address 0x000001a4 - 0x04000000 __bss_start = . - 0x04000000 __bss_start__ = . - *(.bss .bss.*) - .bss 0x04000000 0x0 ./src/startup.o - .bss 0x04000000 0x0 ./src/main.o - *(.gnu.linkonce.b.*) - *(COMMON) - 0x04000000 . = ALIGN (0x4) - 0x04000000 . = ALIGN (0x4) - 0x04000000 __bss_end__ = . - 0x04000000 _end = . - 0x04000000 PROVIDE (end, .) - -.heap 0x04000000 0x400 - 0x04000000 __heap_start__ = . - *(.heap) - 0x04000400 . = ((__heap_start__ + _HEAPSIZE) MAX_K .) - *fill* 0x04000000 0x400 00 - 0x04000400 __heap_end__ = (__heap_start__ + SIZEOF (.heap)) - -.stack 0x04000400 0x400 - 0x04000400 __stack_start__ = . - *(.stack) - 0x04000800 . = ((__stack_start__ + _STACKSIZE) MAX_K .) - *fill* 0x04000400 0x400 00 - 0x04000800 __stack_end__ = (__stack_start__ + SIZEOF (.stack)) - -.stack_irq 0x04000800 0x100 - 0x04000800 __stack_irq_start__ = . - *(.stack_irq) - 0x04000900 . = ((__stack_irq_start__ + _STACKSIZE_IRQ) MAX_K .) - *fill* 0x04000800 0x100 00 - 0x04000900 __stack_irq_end__ = (__stack_irq_start__ + SIZEOF (.stack_irq)) - -.stack_fiq 0x04000900 0x0 - 0x04000900 __stack_fiq_start__ = . - *(.stack_fiq) - 0x04000900 . = ((__stack_fiq_start__ + _STACKSIZE_FIQ) MAX_K .) - 0x04000900 __stack_fiq_end__ = (__stack_fiq_start__ + SIZEOF (.stack_fiq)) - -.stack_svc 0x04000900 0x400 - 0x04000900 __stack_svc_start__ = . - *(.stack_svc) - 0x04000d00 . = ((__stack_svc_start__ + _STACKSIZE_SVC) MAX_K .) - *fill* 0x04000900 0x400 00 - 0x04000d00 __stack_svc_end__ = (__stack_svc_start__ + SIZEOF (.stack_svc)) - -.stack_abt 0x04000d00 0x0 - 0x04000d00 __stack_abt_start__ = . - *(.stack_abt) - 0x04000d00 . = ((__stack_abt_start__ + _STACKSIZE_ABT) MAX_K .) - 0x04000d00 __stack_abt_end__ = (__stack_abt_start__ + SIZEOF (.stack_abt)) - -.stack_und 0x04000d00 0x0 - 0x04000d00 __stack_und_start__ = . - *(.stack_und) - 0x04000d00 . = ((__stack_und_start__ + _STACKSIZE_UND) MAX_K .) - 0x04000d00 __stack_und_end__ = (__stack_und_start__ + SIZEOF (.stack_und)) - -.stab - *(.stab) - -.stabstr - *(.stabstr) - -.stab.excl - *(.stab.excl) - -.stab.exclstr - *(.stab.exclstr) - -.stab.index - *(.stab.index) - -.stab.indexstr - *(.stab.indexstr) - -.comment 0x00000000 0x12 - *(.comment) - .comment 0x00000000 0x12 ./src/main.o - -.debug - *(.debug) - -.line - *(.line) - -.debug_srcinfo - *(.debug_srcinfo) - -.debug_sfnames - *(.debug_sfnames) - -.debug_aranges 0x00000000 0x40 - *(.debug_aranges) - .debug_aranges - 0x00000000 0x20 ./src/startup.o - .debug_aranges - 0x00000020 0x20 ./src/main.o - -.debug_pubnames - 0x00000000 0x1b - *(.debug_pubnames) - .debug_pubnames - 0x00000000 0x1b ./src/main.o - -.debug_info 0x00000000 0x1ae - *(.debug_info .gnu.linkonce.wi.*) - .debug_info 0x00000000 0x7b ./src/startup.o - .debug_info 0x0000007b 0x133 ./src/main.o - -.debug_abbrev 0x00000000 0x6f - *(.debug_abbrev) - .debug_abbrev 0x00000000 0x14 ./src/startup.o - .debug_abbrev 0x00000014 0x5b ./src/main.o - -.debug_line 0x00000000 0xd7 - *(.debug_line) - .debug_line 0x00000000 0x80 ./src/startup.o - .debug_line 0x00000080 0x57 ./src/main.o - -.debug_frame 0x00000000 0x24 - *(.debug_frame) - .debug_frame 0x00000000 0x24 ./src/main.o - -.debug_str - *(.debug_str) - -.debug_loc 0x00000000 0x1f - *(.debug_loc) - .debug_loc 0x00000000 0x1f ./src/main.o - -.debug_macinfo - *(.debug_macinfo) - -.debug_weaknames - *(.debug_weaknames) - -.debug_funcnames - *(.debug_funcnames) - -.debug_typenames - *(.debug_typenames) - -.debug_varnames - *(.debug_varnames) -OUTPUT(test_rom.elf elf32-littlearm) - -.ARM.attributes - 0x00000000 0x10 - .ARM.attributes - 0x00000000 0x10 ./src/startup.o - .ARM.attributes - 0x00000010 0x10 ./src/main.o - -Cross Reference Table - -Symbol File -_Main_Crystal ./src/startup.o -__bss_end__ ./src/startup.o -__bss_start__ ./src/startup.o -__ctors_end__ ./src/startup.o -__ctors_start__ ./src/startup.o -__data_start ./src/startup.o -__stack_abt_end__ ./src/startup.o -__stack_end__ ./src/startup.o -__stack_fiq_end__ ./src/startup.o -__stack_irq_end__ ./src/startup.o -__stack_svc_end__ ./src/startup.o -__stack_und_end__ ./src/startup.o -_edata ./src/startup.o -_etext ./src/startup.o -_start ./src/startup.o -libdebug ./src/startup.o -main ./src/main.o - ./src/startup.o diff --git a/testing/examples/cortex/cm3-ftest.cfg b/testing/examples/cortex/cm3-ftest.cfg deleted file mode 100644 index 6f3fa5c81..000000000 --- a/testing/examples/cortex/cm3-ftest.cfg +++ /dev/null @@ -1,143 +0,0 @@ -# -# For each named Cortex-M3 vector_catch flag VECTOR ... -# bus_err state_err -# chk_err nocp_err -# mm_err reset -# -# BUT NYET hard_err, int_err (their test cases don't yet work) ... -# -# Do the following: -# -# - Test #1: verify that OpenOCD ignores exceptions by default -# + l_VECTOR (loads testcase to RAM) -# + fault triggers loop-to-self exception "handler" -# + "halt" -# + observe fault "handling" -- loop-to-self from load_and_run (below) -# -# - Test #2: verify that "vector_catch" makes OpenOCD stops ignoring them -# + cortex_m vector_catch none -# + cortex_m vector_catch VECTOR -# + l_VECTOR (loads testcase to RAM) -# + fault triggers vector catch hardware -# + observe OpenOCD entering debug state with no assistance -# -# NOTE "reset" includes the NVIC, so that test case gets its reset vector -# from the flash, not from the vector table set up here. Which means that -# for that vector_catch option, the Test #1 (above) "observe" step won't -# use the SRAM address. -# - -# we can fully automate test #2 -proc vector_test {tag} { - halt - # REVISIT -- annoying, we'd like to scrap vector_catch output - cortex_m vector_catch none - cortex_m vector_catch $tag - eval "l_$tag" -} - -# -# Load and start one vector_catch test case. -# -# name -- tag for the vector_catch flag being tested -# halfwords -- array of instructions (some wide, some narrow) -# n_instr -- how many instructions are in $halfwords -# -proc load_and_run { name halfwords n_instr } { - reset halt - - # Load code at beginning of SRAM. - echo "# code to trigger $name vector" - set addr 0x20000000 - - # array2mem should be faster, though we'd need to - # compute the resulting $addr ourselves - foreach opcode $halfwords { - mwh $addr $opcode - incr addr 2 - } - - # create default loop-to-self at $addr ... it serves as - # (a) "main loop" on error - # (b) handler for all exceptions that get triggered - mwh $addr 0xe7fe - - # disassemble, as sanity check and what's-happening trace - arm disassemble 0x20000000 [expr 1 + $n_instr ] - - # Assume that block of code is at most 16 halfwords long. - # Create a basic table of loop-to-self exception handlers. - mww 0x20000020 $addr 16 - # Store its address in VTOR - mww 0xe000ed08 0x20000020 - # Use SHCSR to ensure nothing escalates to a HardFault - mww 0xe000ed24 0x00070000 - - # now start, trigering the $name vector catch logic - resume 0x20000000 -} - -#proc l_hard_err {} { -# IMPLEMENT ME -# FORCED -- escalate something to HardFault -#} - -#proc l_int_err {} { -# IMPLEMENT ME -# STKERR -- exception stack BusFault -#} - -# BusFault, escalates to HardFault -proc l_bus_err {} { - # PRECISERR -- assume less than 512 MBytes of SRAM - load_and_run bus_err { - 0xf06f 0x4040 - 0x7800 - } 2 -} - -# UsageFault, escalates to HardFault -proc l_state_err {} { - # UNDEFINSTR -- issue architecturally undefined instruction - load_and_run state_err { - 0xde00 - } 1 -} - -# UsageFault, escalates to HardFault -proc l_chk_err {} { - # UNALIGNED -- LDM through unaligned pointer - load_and_run chk_err { - 0xf04f 0x0001 - 0xe890 0x0006 - } 2 -} - -# UsageFault, escalates to HardFault -proc l_nocp_err {} { - # NOCP -- issue cp14 DCC instruction - load_and_run nocp_err { - 0xee10 0x0e15 - } 1 -} - -# MemManage, escalates to HardFault -proc l_mm_err {} { - # IACCVIOL -- instruction fetch from an XN region - load_and_run mm_err { - 0xf04f 0x4060 - 0x4687 - } 2 -} - -proc l_reset {} { - # issue SYSRESETREQ via AIRCR - load_and_run reset { - 0xf04f 0x0104 - 0xf2c0 0x51fa - 0xf44f 0x406d - 0xf100 0x000c - 0xf2ce 0x0000 - 0x6001 - } 6 -} diff --git a/testing/examples/cortex/fault.c b/testing/examples/cortex/fault.c deleted file mode 100644 index 19f2720c1..000000000 --- a/testing/examples/cortex/fault.c +++ /dev/null @@ -1,152 +0,0 @@ -/* - * COMPILE: arm-none-eabi-gcc -mthumb -march=armv7-m ... - * ... plus, provide at least a default exception vector table. - * - * RUN: this is best run from SRAM. It starts at main() then triggers - * a fault before more than a handful of instructions have executed. - * Run each test case in two modes: - * - * (1) Faults caught on the Cortex-M3. Default handlers are usually - * loop-to-self NOPs, so a debugger won't notice faults until they - * halt the core and examine xSPR and other registers. - * - * To verify the fault triggered, issue "halt" from OpenOCD; you - * should be told about the fault and (some of) its details. - * Then it's time to run the next test. - * - * NOTE however that "reset" will restart everything; verify that - * case by observing your reset handler doing its normal work. - * - * (2) Faults intercepted by OpenOCD "vector_catch ..." commands. - * - * OpenOCD should tell you about the fault, and show the same - * details, without your "halt" command. - * - * Someday, a fancy version of this code could provide a vector table and - * fault handlers which use semihosting (when that works on Cortex-M3) to - * report what happened, again without needing a "halt" command. - */ - - -/* These symbols match the OpenOCD "cortex_m vector_catch" bit names. */ -enum vc_case { - hard_err, - int_err, - bus_err, - state_err, - chk_err, - nocp_err, - mm_err, - reset, -}; - -/* REVISIT come up with a way to avoid recompiling, maybe: - * - write it in RAM before starting - * - compiled-in BKPT, manual patch of r0, then resume - * - ... - */ - -#ifndef VC_ID -#warning "no VC_ID ... using reset" -#define VC_ID reset -#endif - -int main(void) __attribute__ ((externally_visible, noreturn)); - -/* - * Trigger various Cortex-M3 faults to verify that OpenOCD behaves OK - * in terms of its vector_catch handling. - * - * Fault handling should be left entirely up to the application code - * UNLESS a "vector_catch" command tells OpenOCD to intercept a fault. - * - * See ARMv7-M architecure spec table B1-9 for the list of faults and - * their mappings to the vector catch bits. - */ -int main(void) -{ - /* One test case for each vector catch bit. We're not doing - * hardware testing; so it doesn't matter when some DEMCR bits - * could apply in multiple ways. - */ - switch (VC_ID) { - - /* "cortex_m vector_catch hard_err" */ - case hard_err: - /* FORCED - Fault escalation */ - - /* FIXME code this */ - break; - - /* "cortex_m vector_catch int_err" */ - case int_err: - /* STKERR -- Exception stack BusFault */ - - /* FIXME code this */ - break; - - /* "cortex_m vector_catch bus_err" */ - case bus_err: - /* PRECISERR -- precise data bus read - * Here we assume a Cortex-M3 with 512 MBytes SRAM is very - * unlikely, so the last SRAM byte isn't a valid address. - */ - __asm__ volatile( - "mov r0, #0x3fffffff\n" - "ldrb r0, [r0]\n" - ); - break; - - /* "cortex_m vector_catch state_err" */ - case state_err: - /* UNDEFINSTR -- architectural undefined instruction */ - __asm__ volatile(".hword 0xde00"); - break; - - /* "cortex_m vector_catch chk_err" */ - case chk_err: - /* UNALIGNED ldm */ - __asm__ volatile( - "mov r0, #1\n" - "ldm r0, {r1, r2}\n" - ); - break; - - /* "cortex_m vector_catch nocp_err" */ - case nocp_err: - /* NOCP ... Cortex-M3 has no coprocessors (like CP14 DCC), - * but these instructions are allowed by ARMv7-M. - */ - __asm__ volatile("mrc p14, 0, r0, c0, c5, 0"); - break; - - /* "cortex_m vector_catch mm_err" */ - case mm_err: - /* IACCVIOL -- instruction fetch from an XN region */ - __asm__ volatile( - "mov r0, #0xe0000000\n" - "mov pc, r0\n" - ); - break; - - /* "cortex_m vector_catch reset" */ - case reset: - __asm__ volatile( - /* r1 = SYSRESETREQ */ - "mov r1, #0x0004\n" - /* r1 |= VECTKEY */ - "movt r1, #0x05fa\n" - /* r0 = &AIRCR */ - "mov r0, #0xed00\n" - "add r0, #0xc\n" - "movt r0, #0xe000\n" - /* AIRCR = ... */ - "str r1, [r0, #0]\n" - ); - break; - } - - /* don't return */ - while (1) - continue; -} diff --git a/testing/examples/cortex/lm3s3748.elf b/testing/examples/cortex/lm3s3748.elf deleted file mode 100644 index a3b90dca22463d65cf5ac95d112d9cb044e3a672..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10122 zcmeHN&u`pB6n75G0D z*#G76f&6^)P~7D^Xa78ReRkVDQcmsq`8&%*h%Rln{{HLok86j2j2%_Re%sjpb=dxW zV`UD%{kPZGm%N4c<|l7@i~eQ*ZFw1|j*kUk72Tu8Tgj2`UqzqiL!gUjolzE~ncN1v zhbHm`S}}woSL5i;6LBmwLPyP@S1*)fA0XoPM7>DhJlT^ZFHORS`! zl2D@Hu0!`(0m`lq~?+#Q%)5Qb^| zz_6WO5*vIs#W99pP6Kxak@(j>`p^%uEbWE6P#{0||J2W-ir0pV=XJoJ7J-yj+}|<> zOjTSo-d+3_#^ew>!LI`=1`1={v?1^&*DPVCH$CChCuZta5iyv_#1naqpfHo$1UHze zC!PqOJ!2;K83G0~_tX>ln4mC|+Xgq7srH=6Qc*)^a#;y8{tfEhA}Gvg^cbASTq@!R zsJm5QI_B8ED?D6o7euZY49^!3f2RvyoL!)$0sz|43#d#3lqW5g}0^e&}&d1mIzGmsk8CN@I=s=3$KM1m*MIs Debug... (menu) -> Commands (tab): Commands (listbox) -# To start gdb from a window use : arm-elf-gdb --command=gdbinit -test.elf: test.c Makefile ldscript crt0.S - $(CC) $(CFLAGS) -o crt0.o crt0.S - $(CC) $(CFLAGS) -o test.o test.c - $(LD) -g -v -T$(LDSCRIPT) -o test.elf crt0.o test.o - $(NM) test.elf - - -dump: - $(OBJDUMP) --all-headers test.elf - -dump_test: - $(OBJDUMP) --disassemble test.elf - -dump_full: - $(OBJDUMP) --full-contents test.elf - -clean: - -/bin/rm -f *.o *~ test.elf - diff --git a/testing/examples/ledtest-imx27ads/crt0.S b/testing/examples/ledtest-imx27ads/crt0.S deleted file mode 100644 index d7498814c..000000000 --- a/testing/examples/ledtest-imx27ads/crt0.S +++ /dev/null @@ -1,47 +0,0 @@ -/* Sample initialization file */ - - .extern main - .extern exit - -/* .text is used instead of .section .text so it works with arm-aout too. */ - .text - .code 32 - .align 0 - - .global _mainCRTStartup - .global _start - .global start -start: -_start: -_mainCRTStartup: - -/* Start by setting up a stack */ - /* Set up the stack pointer to end of bss */ - ldr r3, .LC2 - mov sp, r3 - - sub sl, sp, #512 /* Still assumes 512 bytes below sl */ - - mov a2, #0 /* Second arg: fill value */ - mov fp, a2 /* Null frame pointer */ - mov r7, a2 /* Null frame pointer for Thumb */ - - ldr a1, .LC1 /* First arg: start of memory block */ - ldr a3, .LC2 /* Second arg: end of memory block */ - sub a3, a3, a1 /* Third arg: length of block */ - - mov r0, #0 /* no arguments */ - mov r1, #0 /* no argv either */ - - bl main - bl exit /* Should not return */ - - /* For Thumb, constants must be after the code since only - positive offsets are supported for PC relative addresses. */ - - .align 0 -.LC1: - .word __bss_start__ -.LC2: - .word __bss_end__ - diff --git a/testing/examples/ledtest-imx27ads/gdbinit-imx27ads b/testing/examples/ledtest-imx27ads/gdbinit-imx27ads deleted file mode 100644 index 4764bc738..000000000 --- a/testing/examples/ledtest-imx27ads/gdbinit-imx27ads +++ /dev/null @@ -1,36 +0,0 @@ -echo Script to load ledtest on iMX27ADS.\n - -# Note: you need to startup openocd with "-f board/imx27ads.cfg" -# in order to it initialize RAM memory. - -# SETUP GDB : -# -# Common gdb setup for ARM CPUs -set complaints 1 -set output-radix 10 -set input-radix 10 -set prompt (arm-gdb) -set endian little -dir . - -# CONNECT TO TARGET : -target remote 127.0.0.1:3333 - -# LOAD IMAGE : -# - -# Load the program executable called "u-boot" -load test.elf - -# Load the symbols for the program. -symbol-file test.elf - -# RUN TO MAIN : -# -# Set a breakpoint at main(). -#b reset -b main - -# Run to the breakpoint. -c - diff --git a/testing/examples/ledtest-imx27ads/ldscript b/testing/examples/ledtest-imx27ads/ldscript deleted file mode 100644 index a8f0a0885..000000000 --- a/testing/examples/ledtest-imx27ads/ldscript +++ /dev/null @@ -1,18 +0,0 @@ -SECTIONS -{ - . = 0xA0000000; - .text : { *(.text) } - .data ALIGN(0x10): { *(.data) } - .bss ALIGN(0x10): { - __bss_start__ = ABSOLUTE(.); - *(.bss) - . += 0x100; - } - __bss_end__ = .; -PROVIDE (__stack = .); - _end = .; - .debug_info 0 : { *(.debug_info) } - .debug_abbrev 0 : { *(.debug_abbrev) } - .debug_line 0 : { *(.debug_line) } - .debug_frame 0 : { *(.debug_frame) } -} diff --git a/testing/examples/ledtest-imx27ads/test.c b/testing/examples/ledtest-imx27ads/test.c deleted file mode 100644 index 92deaf4cf..000000000 --- a/testing/examples/ledtest-imx27ads/test.c +++ /dev/null @@ -1,60 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2009 by Alan Carvalho de Assis * - * acassis@gmail.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - ***************************************************************************/ - -void delay() -{ - int i; - for (i = 0; i < 500000; i++); -} - -/* MAIN ARM FUNTION */ -int main (void) -{ - int i; - volatile unsigned char *ledoff = ((volatile unsigned char *)0xD4000008); - volatile unsigned char *ledon = ((volatile unsigned char *)0xD400000C); - - for (i = 0; i < 10000; i++) - { - *ledon = 0x30; - delay(); - *ledoff = 0x30; - delay(); - } /* FOR */ - -} /* MAIN */ - -__gccmain() -{ -} /* GCCMAIN */ - - -void exit(int exit_code) -{ - while (1); -} /* EXIT */ - - -atexit() -{ - while (1); -} /* ATEXIT */ - - diff --git a/testing/examples/ledtest-imx27ads/test.elf b/testing/examples/ledtest-imx27ads/test.elf deleted file mode 100644 index f65dcd63160ce8d64815bba49996cf890d62e4b5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 35762 zcmeH}U1%It6vxk<*(BTSrrmth2GZIUs%?erPGY2`+8UeG8XAlC0~Ax1$?jycvL9i0 zBPkY*v=*c)_Q@y7^vwq!`mRFp$p;^T_)tWoNeuKuqy--Wg6sdx%-u|aErL(NIqbdX zoO{mw`pum?``)qfmy}XA1!B-XQoijDLEpbjWIzv567BnFE5-cyyqDynb}e+UkkrOa z^IVAt0U;m+gn$qb0zyCt2mv7=1cZPP5CTF#2nYcoAOwVf5D)@FKnMr{As_^VfDjM@ zLO=)z0U;m+gn$qb0zyCt2mv7=1cZPP5CTF#2nYcoAOwVf5D)@FKnMr{As_^VfDjM@ zLO=)z0U;m+gn$qb0zyCt2mv7=1cZPP5CTF#2nYcoAOwVf5D)@FKnMr{As_^VfDjM@ zLO=)z0U;m+gn$qb0zyCt2mv7=1cZPP5CTF#2nYcoAOwVf5D)@FKnMr{As_^VfDrh9 z5wNUz13*k>k0Wk!|x5|sIPCrKc+;Cv6w) za=J3(lq=a>Q`enZy-?1lojJQSQ*>(SqLbsc{z7SP@PM7G(eaaKlP{i54yFbUkebh7 ze1m$tnU11n>O2!?jUgOSOjwm3UfxTrMbd)n!sFNC0+?qsr7m;>u z%w#J$htz;xdsNwVKlvaxaW3Qh0ye2mO0;&WE@ejhqEAMd&nmq#(R{{sjjTE*8Tl)-}6T+OpDV?`NfrR^%T; z;9(;KXNw2G2z)Ng?dnqW@X1Rj#;5b?{Qh6AeKB$Y?wkp=O*956VO1{LmARi1VZGeMFoe^~3rH?=gCN!f#hocEU2~ zE!0>n1Tpsy&swiIqUane-oByLR;z2kQa{84CRvKsfy307aDgfrQ{fr3m{-+AT) ztM5_5nd~om;d88RdgcVHUs1xD?BDjn=UCnM%n4S!n{eic=kt!IaexZY{*~|s4P*YYT5>ol=vv8l`g1 zPgU(w)3K{|Iqx(_C|0sMZDw||j6{U8l~T#U{q?V< z51H5);U#BrY2LemJ%_7EU_AjHMKMvl@8bI~xMLvNd& z4uR;rVffnS&^O4t!bTuE<{vlRO7!w2qU-B!b02S@P50sO8uEtO2!!{@GK~_>JNNBjZ49AP`Aud-uzy8kdv1w0^f=}l9 yEt$#SZp+l_cD0_#P=@c(kyB?*vp+k7+mxeDImaGXmC diff --git a/testing/examples/ledtest-imx31pdk/Makefile b/testing/examples/ledtest-imx31pdk/Makefile deleted file mode 100644 index 74e2fc23f..000000000 --- a/testing/examples/ledtest-imx31pdk/Makefile +++ /dev/null @@ -1,42 +0,0 @@ -# $Header: $ -# This will make the test program for ARM. - -PROC=arm -TYPE=none-linux-gnueabi -LDSCRIPT=ldscript - -PATH:=/opt/freescale/usr/local/gcc-4.1.2-glibc-2.5-nptl-3/arm-none-linux-gnueabi/bin/:$(PATH) -CC=$(PROC)-$(TYPE)-gcc -AS=$(PROC)-$(TYPE)-as -AR=$(PROC)-$(TYPE)-ar -LD=$(PROC)-$(TYPE)-ld -NM=$(PROC)-$(TYPE)-nm -OBJDUMP=$(PROC)-$(TYPE)-objdump -CFLAGS= -g -c -mcpu=arm1136j-s - -all: test.elf - -# Make a little endian image: -# In Eclipse, add the line : -# source gdbinit -# to : Run -> Debug... (menu) -> Commands (tab): Commands (listbox) -# To start gdb from a window use : arm-elf-gdb --command=gdbinit -test.elf: test.c Makefile ldscript crt0.S - $(CC) $(CFLAGS) -o crt0.o crt0.S - $(CC) $(CFLAGS) -o test.o test.c - $(LD) -g -v -T$(LDSCRIPT) -o test.elf crt0.o test.o - $(NM) test.elf - - -dump: - $(OBJDUMP) --all-headers test.elf - -dump_test: - $(OBJDUMP) --disassemble test.elf - -dump_full: - $(OBJDUMP) --full-contents test.elf - -clean: - -/bin/rm -f *.o *~ test.elf - diff --git a/testing/examples/ledtest-imx31pdk/crt0.S b/testing/examples/ledtest-imx31pdk/crt0.S deleted file mode 100644 index d7498814c..000000000 --- a/testing/examples/ledtest-imx31pdk/crt0.S +++ /dev/null @@ -1,47 +0,0 @@ -/* Sample initialization file */ - - .extern main - .extern exit - -/* .text is used instead of .section .text so it works with arm-aout too. */ - .text - .code 32 - .align 0 - - .global _mainCRTStartup - .global _start - .global start -start: -_start: -_mainCRTStartup: - -/* Start by setting up a stack */ - /* Set up the stack pointer to end of bss */ - ldr r3, .LC2 - mov sp, r3 - - sub sl, sp, #512 /* Still assumes 512 bytes below sl */ - - mov a2, #0 /* Second arg: fill value */ - mov fp, a2 /* Null frame pointer */ - mov r7, a2 /* Null frame pointer for Thumb */ - - ldr a1, .LC1 /* First arg: start of memory block */ - ldr a3, .LC2 /* Second arg: end of memory block */ - sub a3, a3, a1 /* Third arg: length of block */ - - mov r0, #0 /* no arguments */ - mov r1, #0 /* no argv either */ - - bl main - bl exit /* Should not return */ - - /* For Thumb, constants must be after the code since only - positive offsets are supported for PC relative addresses. */ - - .align 0 -.LC1: - .word __bss_start__ -.LC2: - .word __bss_end__ - diff --git a/testing/examples/ledtest-imx31pdk/gdbinit-imx31pdk b/testing/examples/ledtest-imx31pdk/gdbinit-imx31pdk deleted file mode 100644 index 304a8d899..000000000 --- a/testing/examples/ledtest-imx31pdk/gdbinit-imx31pdk +++ /dev/null @@ -1,36 +0,0 @@ -echo Script to load ledtest on iMX31PDK.\n - -# Note: you need to startup openocd with "-f board/imx31pdk.cfg" -# in order to it initialize RAM memory. - -# SETUP GDB : -# -# Common gdb setup for ARM CPUs -set complaints 1 -set output-radix 10 -set input-radix 10 -set prompt (arm-gdb) -set endian little -dir . - -# CONNECT TO TARGET : -target remote 127.0.0.1:3333 - -# LOAD IMAGE : -# - -# Load the program executable called "u-boot" -load test.elf - -# Load the symbols for the program. -symbol-file test.elf - -# RUN TO MAIN : -# -# Set a breakpoint at main(). -#b reset -b main - -# Run to the breakpoint. -c - diff --git a/testing/examples/ledtest-imx31pdk/ldscript b/testing/examples/ledtest-imx31pdk/ldscript deleted file mode 100644 index d6f60d6fa..000000000 --- a/testing/examples/ledtest-imx31pdk/ldscript +++ /dev/null @@ -1,18 +0,0 @@ -SECTIONS -{ - . = 0x80000100; - .text : { *(.text) } - .data ALIGN(0x10): { *(.data) } - .bss ALIGN(0x10): { - __bss_start__ = ABSOLUTE(.); - *(.bss) - . += 0x100; - } - __bss_end__ = .; -PROVIDE (__stack = .); - _end = .; - .debug_info 0 : { *(.debug_info) } - .debug_abbrev 0 : { *(.debug_abbrev) } - .debug_line 0 : { *(.debug_line) } - .debug_frame 0 : { *(.debug_frame) } -} diff --git a/testing/examples/ledtest-imx31pdk/test.c b/testing/examples/ledtest-imx31pdk/test.c deleted file mode 100644 index c80cc611f..000000000 --- a/testing/examples/ledtest-imx31pdk/test.c +++ /dev/null @@ -1,58 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2009 by Alan Carvalho de Assis * - * acassis@gmail.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - ***************************************************************************/ - -void delay() -{ - int i; - for (i = 0; i < 500000; i++); -} - -/* MAIN ARM FUNTION */ -int main (void) -{ - volatile unsigned char *led = ((volatile unsigned char *)0xB6020000); - - while (1) - { - *led = 0xFF; - delay(); - *led = 0x00; - delay(); - } /* FOR */ - -} /* MAIN */ - -__gccmain() -{ -} /* GCCMAIN */ - - -void exit(int exit_code) -{ - while (1); -} /* EXIT */ - - -atexit() -{ - while (1); -} /* ATEXIT */ - - diff --git a/testing/examples/ledtest-imx31pdk/test.elf b/testing/examples/ledtest-imx31pdk/test.elf deleted file mode 100644 index 5374cf4165b295fbe82a4d9d3aeefb599438e44c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3250 zcmdT`O=w(I6h3#}B$;$3?IdZn5Nk(>8kNkvrct4`HEmLBu&t$O7h=NjX69u&b^e%{ zNQy-V+JzuWML`!z#$BOZ1OzGAMJTS^7+i^~{5VkCP2EUA==go_y_)S>G4SiulMC=fsY zA2H2^rm@^u4O~0ECeg;aT5PPUa$|M7EHt;r7Mc<}ydu(AC)Y1>=NS}CNFC#?_bfG5 z<(J{#gNw)3Ld&RcHrAtNxQY3?9W@7<%DlKn9E}Y$BWy=bt=?<3evK@@u_jl(zP02FJ8@P<@ zDr4uZ^P(Q(VCpFFiIEfaIN89bc?srqW2cc z`(U=vnM{{5wy1>eTu50pH~1yG7|Z#(0$WtCL_2#`pE5!Np{GOr9ga^$JNs0x0uIxU z{>GK+e>Gx+_Jv;wGkmNQ;~5p#G1(v3fg{(e=j-z4V59R8j_ZbFwLfH(%usPUluT1ipakSSx0;7vcjy_ala4t}bqU2E zN&KNh&rn@<%xS96QT&m_Upn**Rl_l-sji{;BZ(JL&`+xCjyX-m(fA|B9n29=VtsSa z?iKI_Eay7!Xd3m zJXNhqJY%QkvdLU=wxn$VZY}{Y}S_Tk_feP*b8g+tuv^~+w{SN#4ifr%q21&y{g2leLQ(a!!zYW4jl) McR7=HZ)`W>Z$ur~k^lez diff --git a/testing/index.html b/testing/index.html deleted file mode 100644 index af3ce9348..000000000 --- a/testing/index.html +++ /dev/null @@ -1,43 +0,0 @@ - - - - - -

Release testing

- A release test must be done on code committed to git. - Commit, then test. That way one can know for sure *what* code was actually tested. -

- Note that this testing document does not have anything to do with testing that is done - before committing to git. It is a test document for released code. Pre-commit testing - is done mostly by the developer who has written the change. Sometimes code is committed - to synchronize work, even if it has known problems. Release testing is - done on code believed to be stable, often a couple of weeks old, and not by - the developers, but rather users and community testers who has the requisite hardware - and test setup. Also the testing will take place over an extended period of time. -

- All of the above makes it imperative that there can be no doubt about *which* code - is tested and thus all tests refer to committed code by subversion number. -

Release procedure

- OpenOCD mainline is work in progress. - Expect it to change daily and to have some quirks. -

If you need the latest released and tested version, look for binary snapshots of OpenOCD. Worst case look up the test result table below for the features that are important to you and extract and build the version that has the right cocktail of working features for you. You can also work with the community to address the problems you are seing. Testing work and bug reports are highly appreciated.

-

The OpenOCD community may decide to create release branches. If - this happens, then a branch will be created from OpenOCD mainline. - The particular version to create that branch might be an older version - rather than the latest and greatest. Fixes are then ported to that - release branch from OpenOCD mainline.

-
-

OpenOCD smoketests

- This is a set of tests that exercise the entire OpenOCD system and various targets. It - is a small suite of systemwide smoketests. -

Test cases

- Additionally OpenOCD has test cases that target specific functionality more precisely. -

- A full release test must include both smoketests and unit testing. -

- Test cases - - - diff --git a/testing/profile_stm32.txt b/testing/profile_stm32.txt deleted file mode 100644 index a7e03b08f..000000000 --- a/testing/profile_stm32.txt +++ /dev/null @@ -1,52 +0,0 @@ -These are profile tests for the stm32 target. - -old version rev 1606: - -single step: 59 ms -flash 64k : 24kB/s -mdb 0 128 : 44ms - - -trunk rev 1662: - -single step: 99 ms -flash 64k : 21.5kB/s -mdb 0 128 : 72ms - - -How to run tests: - -poll off -set before [flush_count] -step -set step_count [expr [flush_count]-$before] - -set before [flush_count] -mdb 0 128 -set mem_count [expr [flush_count]-$before] - -set before [flush_count] -flash erase_address 0x8000000 0x10000 -set erase_count [expr [flush_count]-$before] - -set before [flush_count] -flash fillb 0x8000000 0x55 0x10000 -set flash_fill_count [expr [flush_count]-$before] - -puts "counts" ; puts "step $step_count" ; puts "mem $mem_count" ; puts "erase $erase_count" ; puts "flash fill $flash_fill_count" - -parport trunk rev 1675 -====================== - -step 336 -mem 160 -erase 3076 -flash fill 32754 - -verify_ircapture disable - -step 114 -mem 96 -erase 1547 -flash fill 15564 - diff --git a/testing/results/template.html b/testing/results/template.html deleted file mode 100644 index 286bf2e3a..000000000 --- a/testing/results/template.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - Testcases - - - - - - - - -
TestInterfaceTargetResult
CON001 FILL IN! FILL IN!PASS/FAIL
CON002 FILL IN! FILL IN!PASS/FAIL
RES001 FILL IN! FILL IN!PASS/FAIL
RES002 FILL IN! FILL IN!PASS/FAIL
RES003 FILL IN! FILL IN!PASS/FAIL
DBG001 FILL IN! FILL IN!PASS/FAIL
- - - \ No newline at end of file diff --git a/testing/results/v0.4.0-rc1/AT91FR40162.html b/testing/results/v0.4.0-rc1/AT91FR40162.html deleted file mode 100755 index 0baa31e6b..000000000 --- a/testing/results/v0.4.0-rc1/AT91FR40162.html +++ /dev/null @@ -1,856 +0,0 @@ - - -Test results for revision 1.62 - - - - -

SAM7

- -

Connectivity

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
IDTargetInterfaceDescriptionInitial stateInputExpected outputActual outputPass/Fail
CON001AT91FR40162ZY1000Telnet connectionPower on, jtag target attachedOn console, type
telnet ip port
Open On-Chip Debugger
>
Open On-Chip Debugger
>
PASS
CON002AT91FR40162ZY1000GDB server connectionPower on, jtag target attachedOn GDB console, type
target remote ip:port
Remote debugging using 10.0.0.73:3333 - (gdb) tar remo 10.0.0.138:3333
- Remote debugging using 10.0.0.138:3333
- 0x000155b8 in ?? ()
-
PASS
- -

Reset

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
IDTargetInterfaceDescriptionInitial stateInputExpected outputActual outputPass/Fail
RES001AT91FR40162ZY1000Reset halt on a blank targetErase all the content of the flashConnect via the telnet interface and type
reset halt
Reset should return without error and the output should contain
target state: halted
- - > mdw 0x01000000 32
- 0x01000000: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- 0x01000020: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- 0x01000040: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- 0x01000060: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- > reset halt
- JTAG tap: zy1000.cpu tap/device found: 0x1f0f0f0f (mfg: 0x787, part: 0xf0f0, ver: 0x1)
- srst pulls trst - can not reset into halted mode. Issuing halt after reset.
- target state: halted
- target halted in ARM state due to debug-request, current mode: Supervisor
- cpsr: 0x600000d3 pc: 0x00008a70
- >
-
-
PASS
RES002AT91FR40162ZY1000Reset init on a blank targetErase all the content of the flashConnect via the telnet interface and type
reset init
Reset should return without error and the output should contain
executing reset script 'name_of_the_script'
- - > reset init
- JTAG tap: zy1000.cpu tap/device found: 0x1f0f0f0f (mfg: 0x787, part: 0xf0f0, ver: 0x1)
- srst pulls trst - can not reset into halted mode. Issuing halt after reset.
- target state: halted
- target halted in ARM state due to debug-request, current mode: Supervisor
- cpsr: 0x600000d3 pc: 0x00008ea4
- >
-
-
PASS
- NOTE! Even if there is no message, the reset script is being executed (proved by side effects)
RES003AT91FR40162ZY1000Reset after a power cycle of the targetReset the target then power cycle the targetConnect via the telnet interface and type
reset halt after the power was detected
Reset should return without error and the output should contain
target state: halted
- - Sensed nSRST asserted
- Sensed power dropout.
- target state: halted
- target halted in ARM state due to debug request, current mode: Supervisor
- cpsr: 0xf00000d3 pc: 0xd5dff7e6
- Sensed power restore.
- Sensed nSRST deasserted
- > reset halt
- JTAG device found: 0x3f0f0f0f (Manufacturer: 0x787, Part: 0xf0f0, Version: 0x3)
- srst pulls trst - can not reset into halted mode. Issuing halt after reset.
- target state: halted
- target halted in ARM state due to debug request, current mode: Supervisor
- cpsr: 0xf00000d3 pc: 0x0000072c
- >
-
-
PASS
RES004AT91FR40162ZY1000Reset halt on a blank target where reset halt is supportedErase all the content of the flashConnect via the telnet interface and type
reset halt
Reset should return without error and the output should contain
target state: halted
pc = 0
- > reset halt
- JTAG tap: zy1000.cpu tap/device found: 0x1f0f0f0f (mfg: 0x787, part: 0xf0f0, ver: 0x1)
- srst pulls trst - can not reset into halted mode. Issuing halt after reset.
- target state: halted
- target halted in ARM state due to debug-request, current mode: Supervisor
- cpsr: 0xf00000d3 pc: 0x00008b38
- >
-
PASS
RES005AT91FR40162ZY1000Reset halt on a blank target using return clockErase all the content of the flash, set the configuration script to use RCLKConnect via the telnet interface and type
reset halt
Reset should return without error and the output should contain
target state: halted
- - N/A, At91EB40A does NOT have support for RCLK - - N/A
- -

JTAG Speed

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
IDTargetZY1000DescriptionInitial stateInputExpected outputActual outputPass/Fail
SPD001AT91FR40162ZY100016MHz on normal operationReset init the target according to RES002 Change speed and exercise a memory access over the JTAG, for example
mdw 0x0 32
The command should run without any errors. If any JTAG checking errors happen, the test failed - - > reset halt
- JTAG tap: zy1000.cpu tap/device found: 0x1f0f0f0f (mfg: 0x787, part: 0xf0f0, ver: 0x1)
- srst pulls trst - can not reset into halted mode. Issuing halt after reset.
- target state: halted
- target halted in ARM state due to debug-request, current mode: Supervisor
- cpsr: 0xf00000d3 pc: 0x00008ae8
- > jtag_khz 16000
- jtag_speed 4 => JTAG clk=16.000000
- 16000 kHz
- > mdw 0 32
- 0x00000000: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- 0x00000020: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- 0x00000040: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- 0x00000060: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
-
-
PASS
SPD002AT91FR40162ZY10008MHz on normal operationReset init the target according to RES002 Change speed and exercise a memory access over the JTAG, for example
mdw 0x0 32
The command should run without any errors. If any JTAG checking errors happen, the test failed - - > reset halt
- JTAG tap: zy1000.cpu tap/device found: 0x1f0f0f0f (mfg: 0x787, part: 0xf0f0, ver: 0x1)
- srst pulls trst - can not reset into halted mode. Issuing halt after reset.
- target state: halted
- target halted in ARM state due to debug-request, current mode: Supervisor
- cpsr: 0xf00000d3 pc: 0x00008c14
- > jtag_khz 8000
- jtag_speed 8 => JTAG clk=8.000000
- 8000 kHz
- > mdw 0 32
- 0x00000000: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- 0x00000020: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- 0x00000040: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- 0x00000060: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- >
-
-
PASS
SPD003AT91FR40162ZY10004MHz on normal operationReset init the target according to RES002 Change speed and exercise a memory access over the JTAG, for example
mdw 0x0 32
The command should run without any errors. If any JTAG checking errors happen, the test failed - - > reset halt
- JTAG tap: zy1000.cpu tap/device found: 0x1f0f0f0f (mfg: 0x787, part: 0xf0f0, ver: 0x1)
- srst pulls trst - can not reset into halted mode. Issuing halt after reset.
- target state: halted
- target halted in ARM state due to debug-request, current mode: Supervisor
- cpsr: 0xf00000d3 pc: 0x00008bc4
- > jtag_khz 4000
- jtag_speed 16 => JTAG clk=4.000000
- 4000 kHz
- > mdw 0 32
- 0x00000000: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- 0x00000020: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- 0x00000040: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- 0x00000060: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- >
-
-
PASS
SPD004AT91FR40162ZY10002MHz on normal operationReset init the target according to RES002 Change speed and exercise a memory access over the JTAG, for example
mdw 0x0 32
The command should run without any errors. If any JTAG checking errors happen, the test failed - - > reset halt
- JTAG tap: zy1000.cpu tap/device found: 0x1f0f0f0f (mfg: 0x787, part: 0xf0f0, ver: 0x1)
- srst pulls trst - can not reset into halted mode. Issuing halt after reset.
- target state: halted
- target halted in ARM state due to debug-request, current mode: Supervisor
- cpsr: 0xf00000d3 pc: 0x00009678
- > jtag_khz 2000
- jtag_speed 32 => JTAG clk=2.000000
- 2000 kHz
- > mdw 0 32
- 0x00000000: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- 0x00000020: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- 0x00000040: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- 0x00000060: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- >
-
-
PASS
SPD005AT91FR40162ZY1000RCLK on normal operationReset init the target according to RES002 Change speed and exercise a memory access over the JTAG, for example
mdw 0x0 32
The command should run without any errors. If any JTAG checking errors happen, the test failed - - > jtag_khz 0
- RCLK - adaptive
- RCLK timeout
-
- N/A for this target -
N/A for this target
- -

Debugging

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
IDTargetInterfaceDescriptionInitial stateInputExpected outputActual outputPass/Fail
DBG001AT91FR40162ZY1000Load is workingReset init is working, RAM is accesible, GDB server is startedOn the console of the OS:
- $ arm-none-eabi-gdb redboot_ram.elf
- (gdb) target remote ip:port
- (gdb) load -
Load should return without error, typical output looks like:
- - Loading section .text, size 0x14c lma 0x0
- Start address 0x40, load size 332
- Transfer rate: 180 bytes/sec, 332 bytes/write.
-
-
- (gdb) load
- Loading section .rom_vectors, size 0x40 lma 0xc000
- Loading section .text, size 0x103e8 lma 0xc040
- Loading section .rodata, size 0x1a84 lma 0x1c428
- Loading section .data, size 0x3ec lma 0x1deac
- Start address 0xc040, load size 74392
- Transfer rate: 572 KB/sec, 9299 bytes/write.
- (gdb) -
PASS
DBG002AT91FR40162ZY1000Software breakpointLoad the redboot_ram.elf application, use instructions from GDB001In the GDB console:
- - (gdb) monitor arm7_9 dbgrq enable
- software breakpoints enabled
- (gdb) break cyg_start
- Breakpoint 1 at 0xec: file src/main.c, line 71.
- (gdb) continue
- Continuing. -
-
The software breakpoint should be reached, a typical output looks like:
- - Breakpoint 1, main () at src/main.c:69
- 69 DWORD a = 1;
-
-
- - (gdb) monitor arm7_9 dbgrq enable
- use of EmbeddedICE dbgrq instead of breakpoint for target halt enabled
- (gdb) break cyg_start
-
- Breakpoint 1 at 0x155b8: file /home/edgar/temp/ecosboard/packages/redboot/current/src/main.c, line 264.
- (gdb) continue
- Continuing.
-
- Breakpoint 1, cyg_start ()
- at /home/edgar/temp/ecosboard/packages/redboot/current/src/main.c:264
- 264 CYGACC_CALL_IF_MONITOR_VERSION_SET(RedBoot_version);
- (gdb)
-
-
PASS
DBG003AT91FR40162ZY1000Single step in a RAM applicationLoad the test_ram.elf application, use instructions from GDB001, break in main using the instructions from GDB002In GDB, type
(gdb) step
The next instruction should be reached, typical output:
- - (gdb) step
- 70 DWORD b = 2; - -
-
- - (gdb) step
- 266 CYGACC_CALL_IF_MONITOR_RETURN_SET(return_to_redboot);
- (gdb)
-
-
PASS
DBG004AT91FR40162ZY1000Software break points are working after a resetLoad the test_ram.elf application, use instructions from GDB001, break in main using the instructions from GDB002In GDB, type
- (gdb) monitor reset init
- (gdb) load
- (gdb) continue
-
The breakpoint should be reached, typical output:
- - Breakpoint 1, main () at src/main.c:69
- 69 DWORD a = 1; -
-
- (gdb) moni reset init
- JTAG tap: zy1000.cpu tap/device found: 0x1f0f0f0f (mfg: 0x787, part: 0xf0f0, ver: 0x1)
- srst pulls trst - can not reset into halted mode. Issuing halt after reset.
- target state: halted
- target halted in ARM state due to debug-request, current mode: Supervisor
- cpsr: 0x600000d3 pc: 0x00008ae8
- (gdb) load
- Loading section .rom_vectors, size 0x40 lma 0xc000
- Loading section .text, size 0x103e8 lma 0xc040
- Loading section .rodata, size 0x1a84 lma 0x1c428
- Loading section .data, size 0x3ec lma 0x1deac
- Start address 0xc040, load size 74392
- Transfer rate: 576 KB/sec, 9299 bytes/write.
- (gdb) c
- Continuing.
-
- Breakpoint 1, cyg_start ()
- at /home/edgar/temp/ecosboard/packages/redboot/current/src/main.c:264
- 264 CYGACC_CALL_IF_MONITOR_VERSION_SET(RedBoot_version);
- (gdb)
-
PASS
DBG005AT91FR40162ZY1000Hardware breakpointFlash the redboot_rom.elf application. Make this test after FLA004 has passedBe sure that gdb_memory_map and gdb_flash_program are enabled. In GDB, type
- - (gdb) monitor reset init
- (gdb) load
- Loading section .text, size 0x194 lma 0x100000
- Start address 0x100040, load size 404
- Transfer rate: 179 bytes/sec, 404 bytes/write.
- (gdb) monitor arm7_9 force_hw_bkpts enable
- force hardware breakpoints enabled
- (gdb) break main
- Breakpoint 1 at 0x100134: file src/main.c, line 69.
- (gdb) continue
-
-
The breakpoint should be reached, typical output:
- - Continuing.
-
- Breakpoint 1, main () at src/main.c:69
- 69 DWORD a = 1;
-
-
- - (gdb) load
- Loading section .rom_vectors, size 0x40 lma 0x1000000
- Loading section .text, size 0x10638 lma 0x1000040
- Loading section .rodata, size 0x1a84 lma 0x1010678
- Loading section .data, size 0x428 lma 0x10120fc
- Start address 0x1000040, load size 75044
- Transfer rate: 33 KB/sec, 9380 bytes/write.
- (gdb) break cyg_start
- Breakpoint 1 at 0x100979c: file /home/edgar/temp/ecosboard/packages/redboot/current/src/main.c, line 264.
- (gdb) c
- Continuing.
- Note: automatically using hardware breakpoints for read-only addresses.
-
- Breakpoint 1, cyg_start () at /home/edgar/temp/ecosboard/packages/redboot/current/src/main.c:264
- 264 CYGACC_CALL_IF_MONITOR_VERSION_SET(RedBoot_version);
- (gdb)
-
-
PASS
DBG006AT91FR40162ZY1000Hardware breakpoint is set after a resetFollow the instructions to flash and insert a hardware breakpoint from DBG005In GDB, type
- - (gdb) monitor reset
- (gdb) monitor reg pc 0x100000
- pc (/32): 0x00100000
- (gdb) continue -

- where the value inserted in PC is the start address of the application -
The breakpoint should be reached, typical output:
- - Continuing.
-
- Breakpoint 1, main () at src/main.c:69
- 69 DWORD a = 1;
-
-
- - (gdb) moni reset init
- JTAG tap: zy1000.cpu tap/device found: 0x1f0f0f0f (mfg: 0x787, part: 0xf0f0, ver: 0x1)
- srst pulls trst - can not reset into halted mode. Issuing halt after reset.
- target state: halted
- target halted in ARM state due to debug-request, current mode: Supervisor
- cpsr: 0x200000d3 pc: 0x01000200
- (gdb) moni reg pc 0x1000000
- pc (/32): 0x01000000
- (gdb) c
- Continuing.
-
- Breakpoint 1, cyg_start () at /home/edgar/temp/ecosboard/packages/redboot/current/src/main.c:264
- 264 CYGACC_CALL_IF_MONITOR_VERSION_SET(RedBoot_version);
- (gdb)
-
-
PASS
DBG007AT91FR40162ZY1000Single step in ROMFlash the test_rom.elf application and set a breakpoint in main, use DBG005. Make this test after FLA004 has passedBe sure that gdb_memory_map and gdb_flash_program are enabled. In GDB, type
- - (gdb) monitor reset
- (gdb) load
- Loading section .text, size 0x194 lma 0x100000
- Start address 0x100040, load size 404
- Transfer rate: 179 bytes/sec, 404 bytes/write.
- (gdb) monitor arm7_9 force_hw_bkpts enable
- force hardware breakpoints enabled
- (gdb) break main
- Breakpoint 1 at 0x100134: file src/main.c, line 69.
- (gdb) continue
- Continuing.
-
- Breakpoint 1, main () at src/main.c:69
- 69 DWORD a = 1;
- (gdb) step -
-
The breakpoint should be reached, typical output:
- - target state: halted
- target halted in ARM state due to single step, current mode: Supervisor
- cpsr: 0x60000013 pc: 0x0010013c
- 70 DWORD b = 2;
-
-
- Breakpoint 1, cyg_start () at /home/edgar/temp/ecosboard/packages/redboot/current/src/main.c:264
- 264 CYGACC_CALL_IF_MONITOR_VERSION_SET(RedBoot_version);
- (gdb) step
- 266 CYGACC_CALL_IF_MONITOR_RETURN_SET(return_to_redboot);
-
PASS
- -

RAM access

-Note: these tests are not designed to test/debug the target, but to test functionalities! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
IDTargetInterfaceDescriptionInitial stateInputExpected outputActual outputPass/Fail
RAM001AT91FR40162ZY100032 bit Write/read RAMReset init is workingOn the telnet interface
- > mww ram_address 0xdeadbeef 16
- > mdw ram_address 32 -
-
The commands should execute without error. A clear failure is a memory access exception. The result of running the commands should be a list of 16 locations 32bit long containing 0xdeadbeef.
- - > mww 0x0 0xdeadbeef 16
- > mdw 0x0 32
- 0x00000000: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef
- 0x00000020: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef
- 0x00000040: e1a00000 e59fa51c e59f051c e04aa000 00080017 00009388 00009388 00009388
- 0x00000060: 00009388 0002c2c0 0002c2c0 000094f8 000094f4 00009388 00009388 00009388
-
-
- > mww 0 0xdeadbeef 16
- > mdw 0x0 32
- 0x00000000: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef
- 0x00000020: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef
- 0x00000040: 15aadc6d 425b6f33 e789f955 d390dcc2 00080017 010067b4 010067b4 010067b4
- 0x00000060: 010067b4 00006e74 00006e74 010067b4 010067b4 010067b4 010067b4 010067b4
-
PASS
RAM002AT91FR40162ZY100016 bit Write/read RAMReset init is workingOn the telnet interface
- > mwh ram_address 0xbeef 16
- > mdh ram_address 32 -
-
The commands should execute without error. A clear failure is a memory access exception. The result of running the commands should be a list of 16 locations 16bit long containing 0xbeef.
- - > mwh 0x0 0xbeef 16
- > mdh 0x0 32
- 0x00000000: beef beef beef beef beef beef beef beef beef beef beef beef beef beef beef beef
- 0x00000020: 00e0 0000 021c 0000 0240 0000 026c 0000 0288 0000 0000 0000 0388 0000 0350 0000
- > -
-
- > mwh 0 0xbeef 16
- > mdh 0x0 32
- 0x00000000: beef beef beef beef beef beef beef beef beef beef beef beef beef beef beef beef
- 0x00000020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-
PASS
There is a problem with the formatting of the output
RAM003AT91FR40162ZY10008 bit Write/read RAMReset init is workingOn the telnet interface
- > mwb ram_address 0xab 16
- > mdb ram_address 32 -
-
The commands should execute without error. A clear failure is a memory access exception. The result of running the commands should be a list of 16 locations 8bit long containing 0xab.
- - > mwb ram_address 0xab 16
- > mdb ram_address 32
- 0x00000000: ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- > -
-
- > mwb 0x0 0xab 16
- > mdb 0x0 32
- 0x00000000: ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-
PASS
- - - -

Flash access

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
IDTargetInterfaceDescriptionInitial stateInputExpected outputActual outputPass/Fail
FLA001AT91FR40162ZY1000Flash probeReset init is workingOn the telnet interface:
- > flash probe 0 -
The command should execute without error. The output should state the name of the flash and the starting address. An example of output:
- flash 'ecosflash' found at 0x01000000 -
- - > flash probe 0 - flash 'ecosflash' found at 0x01000000 - - PASS
FLA002AT91FR40162ZY1000flash fillwReset init is working, flash is probedOn the telnet interface
- > flash fillw 0x100000 0xdeadbeef 16 - -
The commands should execute without error. The output looks like:
- - wrote 64 bytes to 0x0100000 in 11.610000s (0.091516 kb/s) -
- To verify the contents of the flash:
- - > mdw 0x100000 32
- 0x0100000: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef
- 0x0100020: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef
- 0x0100040: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- 0x0100060: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff -
-
- > flash fillw 0x01000000 0xdeadbeef 16
- wrote 64 bytes to 0x01000000 in 0.010000s (6.250 kb/s)
- > mdw 0x1000000 32
- 0x01000000: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef
- 0x01000020: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef
- 0x01000040: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- 0x01000060: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- > -
PASS
FLA003AT91FR40162ZY1000Flash eraseReset init is working, flash is probedOn the telnet interface
- > flash erase_address 0x100000 0x2000 - -
The commands should execute without error.
- - erased address 0x0100000 length 8192 in 4.970000s - - To check that the flash has been erased, read at different addresses. The result should always be 0xff. - - > mdw 0x100000 32
- 0x0100000: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- 0x0100020: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- 0x0100040: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- 0x0100060: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff -
-
- > flash erase_address 0x1000000 0x10000
- erased address 0x01000000 (length 65536) in 0.840000s (76.190 kb/s)
- > mdw 0x1000000 32
- 0x01000000: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- 0x01000020: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- 0x01000040: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- 0x01000060: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
-
PASS
FLA004AT91FR40162ZY1000Loading to flash from GDBReset init is working, flash is probed, connectivity to GDB server is workingStart GDB using a ROM elf image, eg: arm-elf-gdb test_rom.elf.
- - (gdb) target remote ip:port
- (gdb) monitor reset halt
- (gdb) load
- Loading section .text, size 0x194 lma 0x100000
- Start address 0x100040, load size 404
- Transfer rate: 179 bytes/sec, 404 bytes/write.
- (gdb) monitor verify_image path_to_elf_file -
-
The output should look like:
- - verified 404 bytes in 5.060000s -
- The failure message is something like:
- Verify operation failed address 0x00200000. Was 0x00 instead of 0x18 -
- - (gdb) load
- Loading section .rom_vectors, size 0x40 lma 0x1000000
- Loading section .text, size 0x10638 lma 0x1000040
- Loading section .rodata, size 0x1a84 lma 0x1010678
- Loading section .data, size 0x428 lma 0x10120fc
- Start address 0x1000040, load size 75044
- Transfer rate: 34 KB/sec, 9380 bytes/write.
- (gdb) moni verify_image /tftp/10.0.0.190/redboot_rom.elf
- keep_alive() was not invoked in the 1000ms timelimit. GDB alive packet not sent! (1820). Workaround: increase "set remotetimeout" in GDB
- verified 75044 bytes in 1.960000s (37.390 kb/s)
-
-
PASS
- - - \ No newline at end of file diff --git a/testing/results/v0.4.0-rc1/LPC2148.html b/testing/results/v0.4.0-rc1/LPC2148.html deleted file mode 100755 index 425b52484..000000000 --- a/testing/results/v0.4.0-rc1/LPC2148.html +++ /dev/null @@ -1,933 +0,0 @@ - - -Test results for revision 1.62 - - - - -

LPC2148

- -

Connectivity

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
IDTargetInterfaceDescriptionInitial stateInputExpected outputActual outputPass/Fail
CON001LPC2148ZY1000Telnet connectionPower on, jtag target attachedOn console, type
telnet ip port
Open On-Chip Debugger
>
Open On-Chip Debugger
>
PASS
CON002LPC2148ZY1000GDB server connectionPower on, jtag target attachedOn GDB console, type
target remote ip:port
Remote debugging using 10.0.0.73:3333 - (gdb) tar remo 10.0.0.73:3333
- Remote debugging using 10.0.0.73:3333
- 0x00000000 in ?? ()
-
PASS
- -

Reset

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
IDTargetInterfaceDescriptionInitial stateInputExpected outputActual outputPass/Fail
RES001LPC2148ZY1000Reset halt on a blank targetErase all the content of the flashConnect via the telnet interface and type
reset halt
Reset should return without error and the output should contain
target state: halted
- - > mdw 0 32
- 0x00000000: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- 0x00000020: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- 0x00000040: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- 0x00000060: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- > reset halt
- JTAG tap: lpc2148.cpu tap/device found: 0x4f1f0f0f (mfg: 0x787, part: 0xf1f0, ver: 0x4)
- srst pulls trst - can not reset into halted mode. Issuing halt after reset.
- target state: halted
- target halted in Thumb state due to debug-request, current mode: Supervisor
- cpsr: 0xa00000f3 pc: 0x7fffd2d6
- > -
-
PASS
RES002LPC2148ZY1000Reset init on a blank targetErase all the content of the flashConnect via the telnet interface and type
reset init
Reset should return without error and the output should contain
executing reset script 'name_of_the_script'
- - > reset init
- JTAG tap: lpc2148.cpu tap/device found: 0x4f1f0f0f (mfg: 0x787, part: 0xf1f0, ver: 0x4)
- srst pulls trst - can not reset into halted mode. Issuing halt after reset.
- target state: halted
- target halted in Thumb state due to debug-request, current mode: Supervisor
- cpsr: 0xa00000f3 pc: 0x7fffd2da
- core state: ARM
- > -
-
PASS
- NOTE! Even if there is no message, the reset script is being executed (proved by side effects)
RES003LPC2148ZY1000Reset after a power cycle of the targetReset the target then power cycle the targetConnect via the telnet interface and type
reset halt after the power was detected
Reset should return without error and the output should contain
target state: halted
- - nsed nSRST asserted.
- nsed power dropout.
- nsed power restore.
- SRST took 186ms to deassert
- JTAG tap: lpc2148.cpu tap/device found: 0x4f1f0f0f (mfg: 0x787, part: 0xf1f0, ver: 0x4)
- srst pulls trst - can not reset into halted mode. Issuing halt after reset.
- target state: halted
- target halted in Thumb state due to debug-request, current mode: Supervisor
- cpsr: 0xa00000f3 pc: 0x7fffd2d6
- core state: ARM
- > reset halt
- JTAG tap: lpc2148.cpu tap/device found: 0x4f1f0f0f (mfg: 0x787, part: 0xf1f0, ver: 0x4)
- srst pulls trst - can not reset into halted mode. Issuing halt after reset.
- target state: halted
- target halted in Thumb state due to debug-request, current mode: Supervisor
- cpsr: 0xa00000f3 pc: 0x7fffd2d6
- > -
-
PASS
RES004LPC2148ZY1000Reset halt on a blank target where reset halt is supportedErase all the content of the flashConnect via the telnet interface and type
reset halt
Reset should return without error and the output should contain
target state: halted
pc = 0
- - > reset halt
- JTAG tap: lpc2148.cpu tap/device found: 0x4f1f0f0f (mfg: 0x787, part: 0xf1f0, ver: 0x4)
- srst pulls trst - can not reset into halted mode. Issuing halt after reset.
- target state: halted
- target halted in Thumb state due to debug-request, current mode: Supervisor
- cpsr: 0xa00000f3 pc: 0x7fffd2d6
- > -
-
PASS
RES005LPC2148ZY1000Reset halt on a blank target using return clockErase all the content of the flash, set the configuration script to use RCLKConnect via the telnet interface and type
reset halt
Reset should return without error and the output should contain
target state: halted
- - > jtag_khz 0
- RCLK - adaptive
- > reset init
- JTAG tap: lpc2148.cpu tap/device found: 0x4f1f0f0f (mfg: 0x787, part: 0xf1f0, ver: 0x4)
- srst pulls trst - can not reset into halted mode. Issuing halt after reset.
- target state: halted
- target halted in Thumb state due to debug-request, current mode: Supervisor
- cpsr: 0xa00000f3 pc: 0x7fffd2d6
- core state: ARM
- > -
-
PASS
- -

JTAG Speed

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
IDTargetZY1000DescriptionInitial stateInputExpected outputActual outputPass/Fail
SPD001LPC2148ZY100016MHz on normal operationReset init the target according to RES002 Change speed and exercise a memory access over the JTAG, for example
mdw 0x0 32
The command should run without any errors. If any JTAG checking errors happen, the test failed - - > jtag_khz 16000
- jtag_speed 4 => JTAG clk=16.000000
- 16000 kHz
- > reset halt
- JTAG scan chain interrogation failed: all zeroes
- Check JTAG interface, timings, target power, etc.
- error: -100
- Command handler execution failed
- in procedure 'reset' called at file "command.c", line 638
- called at file "/home/laurentiu/workspace/zy1000/build/../openocd/src/helper/command.c", line 352
- invalid mode value encountered 0
- cpsr contains invalid mode value - communication failure
- ThumbEE -- incomplete support
- target state: halted
- target halted in ThumbEE state due to debug-request, current mode: System
- cpsr: 0x1fffffff pc: 0xfffffffa
- invalid mode value encountered 0
- cpsr contains invalid mode value - communication failure
- target state: halted
- target halted in Thumb state due to debug-request, current mode: System
- cpsr: 0xc00003ff pc: 0xfffffff0
- invalid mode value encountered 0
- cpsr contains invalid mode value - communication failure
- invalid mode value encountered 0
- cpsr contains invalid mode value - communication failure
- invalid mode value encountered 0
- cpsr contains invalid mode value - communication failure
- invalid mode value encountered 0
- cpsr contains invalid mode value - communication failure
- ThumbEE -- incomplete support
- target state: halted
- target halted in ThumbEE state due to debug-request, current mode: System
- cpsr: 0xffffffff pc: 0xfffffffa
- > -
-
FAIL
SPD002LPC2148ZY10008MHz on normal operationReset init the target according to RES002 Change speed and exercise a memory access over the JTAG, for example
mdw 0x0 32
The command should run without any errors. If any JTAG checking errors happen, the test failed - - > jtag_khz 8000
- jtag_speed 8 => JTAG clk=8.000000
- 8000 kHz
- > reset halt
- JTAG scan chain interrogation failed: all zeroes
- Check JTAG interface, timings, target power, etc.
- error: -100
- Command handler execution failed
- in procedure 'reset' called at file "command.c", line 638
- called at file "/home/laurentiu/workspace/zy1000/build/../openocd/src/helper/command.c", line 352
- invalid mode value encountered 0
- cpsr contains invalid mode value - communication failure
- invalid mode value encountered 0
- cpsr contains invalid mode value - communication failure
- > -
-
FAIL
SPD003LPC2148ZY10004MHz on normal operationReset init the target according to RES002 Change speed and exercise a memory access over the JTAG, for example
mdw 0x0 32
The command should run without any errors. If any JTAG checking errors happen, the test failed - - > jtag_khz 4000
- jtag_speed 16 => JTAG clk=4.000000
- 4000 kHz
- > reset halt
- JTAG tap: lpc2148.cpu tap/device found: 0xc79f0f87 (mfg: 0x7c3, part: 0x79f0, ver: 0xc)
- JTAG tap: lpc2148.cpu UNEXPECTED: 0xc79f0f87 (mfg: 0x7c3, part: 0x79f0, ver: 0xc)
- JTAG tap: lpc2148.cpu expected 1 of 1: 0x4f1f0f0f (mfg: 0x787, part: 0xf1f0, ver: 0x4)
- Unexpected idcode after end of chain: 64 0x0000007f
- Unexpected idcode after end of chain: 160 0x0000007f
- Unexpected idcode after end of chain: 192 0x0000007f
- Unexpected idcode after end of chain: 320 0x0000007f
- Unexpected idcode after end of chain: 352 0x0000007f
- Unexpected idcode after end of chain: 384 0x0000007f
- Unexpected idcode after end of chain: 480 0x0000007f
- Unexpected idcode after end of chain: 512 0x0000007f
- Unexpected idcode after end of chain: 544 0x0000007f
- double-check your JTAG setup (interface, speed, missing TAPs, ...)
- error: -100
- Command handler execution failed
- in procedure 'reset' called at file "command.c", line 638
- called at file "/home/laurentiu/workspace/zy1000/build/../openocd/src/helper/command.c", line 352
- > -
-
FAIL
SPD004LPC2148ZY10002MHz on normal operationReset init the target according to RES002 Change speed and exercise a memory access over the JTAG, for example
mdw 0x0 32
The command should run without any errors. If any JTAG checking errors happen, the test failed - - > jtag_khz 2000
- jtag_speed 32 => JTAG clk=2.000000
- 2000 kHz
- > reset halt
- JTAG tap: lpc2148.cpu tap/device found: 0x4f1f0f0f (mfg: 0x787, part: 0xf1f0, ver: 0x4)
- srst pulls trst - can not reset into halted mode. Issuing halt after reset.
- target state: halted
- target halted in Thumb state due to debug-request, current mode: Supervisor
- cpsr: 0xa00000f3 pc: 0x7fffd2da
- > mdw 0 32
- 0x00000000: e59f4034 e3a05002 e5845000 e3a05003 e5845004 e59f201c e3a03000 e1020093
- 0x00000020: e2822028 e1021093 e3c03007 e5023028 e51ff004 7fffd1c4 e002c014 e01fc000
- 0x00000040: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- 0x00000060: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- > -
-
PASS
SPD005LPC2148ZY1000RCLK on normal operationReset init the target according to RES002 Change speed and exercise a memory access over the JTAG, for example
mdw 0x0 32
The command should run without any errors. If any JTAG checking errors happen, the test failed - - > jtag_khz 0
- RCLK - adaptive
- > mdw 0 32
- 0x00000000: e59f4034 e3a05002 e5845000 e3a05003 e5845004 e59f201c e3a03000 e1020093
- 0x00000020: e2822028 e1021093 e3c03007 e5023028 e51ff004 7fffd1c4 e002c014 e01fc000
- 0x00000040: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- 0x00000060: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- > -
-
PASS
- -

Debugging

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
IDTargetInterfaceDescriptionInitial stateInputExpected outputActual outputPass/Fail
DBG001LPC2148ZY1000Load is workingReset init is working, RAM is accesible, GDB server is startedOn the console of the OS:
- arm-elf-gdb test_ram.elf
- (gdb) target remote ip:port
- (gdb) load -
Load should return without error, typical output looks like:
- - Loading section .text, size 0x14c lma 0x0
- Start address 0x40, load size 332
- Transfer rate: 180 bytes/sec, 332 bytes/write.
-
-
- (gdb) load
- Loading section .text, size 0x16c lma 0x40000000
- Start address 0x40000040, load size 364
- Transfer rate: 32 KB/sec, 364 bytes/write.
- (gdb) -
PASS
DBG002LPC2148ZY1000Software breakpointLoad the test_ram.elf application, use instructions from GDB001In the GDB console:
- - (gdb) monitor gdb_breakpoint_override soft
- software breakpoints enabled
- (gdb) break main
- Breakpoint 1 at 0xec: file src/main.c, line 71.
- (gdb) continue
- Continuing. -
-
The software breakpoint should be reached, a typical output looks like:
- - target state: halted
- target halted in ARM state due to breakpoint, current mode: Supervisor
- cpsr: 0x000000d3 pc: 0x000000ec
-
- Breakpoint 1, main () at src/main.c:71
- 71 DWORD a = 1; -
-
- - (gdb) monitor gdb_breakpoint_override soft
- force soft breakpoints
- Current language: auto
- The current source language is "auto; currently asm".
- (gdb) break main
- Breakpoint 1 at 0x4000010c: file src/main.c, line 71.
- (gdb) c
- Continuing.
-
- Breakpoint 1, main () at src/main.c:71
- 71 DWORD a = 1;
- Current language: auto
- The current source language is "auto; currently c".
- (gdb) -
-
PASS
DBG003LPC2148ZY1000Single step in a RAM applicationLoad the test_ram.elf application, use instructions from GDB001, break in main using the instructions from GDB002In GDB, type
(gdb) step
The next instruction should be reached, typical output:
- - (gdb) step
- target state: halted
- target halted in ARM state due to single step, current mode: Abort
- cpsr: 0x20000097 pc: 0x000000f0
- target state: halted
- target halted in ARM state due to single step, current mode: Abort
- cpsr: 0x20000097 pc: 0x000000f4
- 72 DWORD b = 2; -
-
- - (gdb) step
- 72 DWORD b = 2;
- (gdb) -
-
PASS
DBG004LPC2148ZY1000Software break points are working after a resetLoad the test_ram.elf application, use instructions from GDB001, break in main using the instructions from GDB002In GDB, type
- (gdb) monitor reset init
- (gdb) load
- (gdb) continue
-
The breakpoint should be reached, typical output:
- - target state: halted
- target halted in ARM state due to breakpoint, current mode: Supervisor
- cpsr: 0x000000d3 pc: 0x000000ec
-
- Breakpoint 1, main () at src/main.c:71
- 71 DWORD a = 1; -
-
- (gdb) moni reset init
- JTAG tap: lpc2148.cpu tap/device found: 0x4f1f0f0f (mfg: 0x787, part: 0xf1f0, ver: 0x4)
- srst pulls trst - can not reset into halted mode. Issuing halt after reset.
- target state: halted
- target halted in Thumb state due to debug-request, current mode: Supervisor
- cpsr: 0xa00000f3 pc: 0x7fffd2d6
- core state: ARM
- (gdb) load
- Loading section .text, size 0x16c lma 0x40000000
- Start address 0x40000040, load size 364
- Transfer rate: 27 KB/sec, 364 bytes/write.
- (gdb) c
- Continuing.
-
- Breakpoint 1, main () at src/main.c:71
- 71 DWORD a = 1;
- (gdb) -
PASS
DBG005LPC2148ZY1000Hardware breakpointFlash the test_rom.elf application. Make this test after FLA004 has passedBe sure that gdb_memory_map and gdb_flash_program are enabled. In GDB, type
- - (gdb) monitor reset init
- (gdb) load
- Loading section .text, size 0x194 lma 0x100000
- Start address 0x100040, load size 404
- Transfer rate: 179 bytes/sec, 404 bytes/write.
- (gdb) monitor gdb_breakpoint_override hard
- force hard breakpoints
- (gdb) break main
- Breakpoint 1 at 0x100134: file src/main.c, line 69.
- (gdb) continue
-
-
The breakpoint should be reached, typical output:
- - Continuing.
-
- Breakpoint 1, main () at src/main.c:69
- 69 DWORD a = 1;
-
-
- - (gdb) monitor gdb_breakpoint_override hard
- force hard breakpoints
- (gdb) break main
- Breakpoint 1 at 0x10c: file src/main.c, line 71.
- (gdb) continue
- Continuing.
- Note: automatically using hardware breakpoints for read-only addresses.
-
- Breakpoint 1, main () at src/main.c:71
- 71 DWORD a = 1;
- Current language: auto
- The current source language is "auto; currently c".
- (gdb) -
-
PASS NOTE: This test is failing from time to time, not able to describe a cause
DBG006LPC2148ZY1000Hardware breakpoint is set after a resetFollow the instructions to flash and insert a hardware breakpoint from DBG005In GDB, type
- - (gdb) monitor reset
- (gdb) monitor reg pc 0x100000
- pc (/32): 0x00100000
- (gdb) continue -

- where the value inserted in PC is the start address of the application -
The breakpoint should be reached, typical output:
- - Continuing.
-
- Breakpoint 1, main () at src/main.c:69
- 69 DWORD a = 1;
-
-
- - (gdb) monitor reset init
- JTAG tap: lpc2148.cpu tap/device found: 0x4f1f0f0f (mfg: 0x787, part: 0xf1f0, ver: 0x4)
- srst pulls trst - can not reset into halted mode. Issuing halt after reset.
- target state: halted
- target halted in ARM state due to debug-request, current mode: Supervisor
- cpsr: 0x60000013 pc: 0x00000160
- core state: ARM
- (gdb) monitor reg pc 0x40
- pc (/32): 0x00000040
- (gdb) continue
- Continuing.
-
- Breakpoint 1, main () at src/main.c:71
- 71 DWORD a = 1;
- (gdb) -
-
PASS
DBG007LPC2148ZY1000Single step in ROMFlash the test_rom.elf application and set a breakpoint in main, use DBG005. Make this test after FLA004 has passedBe sure that gdb_memory_map and gdb_flash_program are enabled. In GDB, type
- - (gdb) monitor reset
- (gdb) load
- Loading section .text, size 0x194 lma 0x100000
- Start address 0x100040, load size 404
- Transfer rate: 179 bytes/sec, 404 bytes/write.
- (gdb) monitor gdb_breakpoint_override hard
- force hard breakpoints
- (gdb) break main
- Breakpoint 1 at 0x100134: file src/main.c, line 69.
- (gdb) continue
- Continuing.
-
- Breakpoint 1, main () at src/main.c:69
- 69 DWORD a = 1;
- (gdb) step -
-
The breakpoint should be reached, typical output:
- - target state: halted
- target halted in ARM state due to single step, current mode: Supervisor
- cpsr: 0x60000013 pc: 0x0010013c
- 70 DWORD b = 2;
-
-
- (gdb) load
- Loading section .text, size 0x16c lma 0x0
- Start address 0x40, load size 364
- Transfer rate: 637 bytes/sec, 364 bytes/write.
- (gdb) monitor gdb_breakpoint_override hard
- force hard breakpoints
- Current language: auto
- The current source language is "auto; currently asm".
- (gdb) break main
- Breakpoint 1 at 0x10c: file src/main.c, line 71.
- (gdb) continue
- Continuing.
- Note: automatically using hardware breakpoints for read-only addresses.
-
- Breakpoint 1, main () at src/main.c:71
- 71 DWORD a = 1;
- Current language: auto
- The current source language is "auto; currently c".
- (gdb) step
- 72 DWORD b = 2;
- (gdb) - -
PASS
- -

RAM access

-Note: these tests are not designed to test/debug the target, but to test functionalities! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
IDTargetInterfaceDescriptionInitial stateInputExpected outputActual outputPass/Fail
RAM001LPC2148ZY100032 bit Write/read RAMReset init is workingOn the telnet interface
- > mww ram_address 0xdeadbeef 16
- > mdw ram_address 32 -
-
The commands should execute without error. A clear failure is a memory access exception. The result of running the commands should be a list of 16 locations 32bit long containing 0xdeadbeef.
- - > mww 0x0 0xdeadbeef 16
- > mdw 0x0 32
- 0x00000000: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef
- 0x00000020: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef
- 0x00000040: e1a00000 e59fa51c e59f051c e04aa000 00080017 00009388 00009388 00009388
- 0x00000060: 00009388 0002c2c0 0002c2c0 000094f8 000094f4 00009388 00009388 00009388
-
-
- > mww 0x40000000 0xdeadbeef 16
- > mdw 0x40000000 32
- 0x40000000: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef
- 0x40000020: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef
- 0x40000040: e1a00000 e1a00000 e1a00000 e1a00000 e1a00000 e1a00000 e1a00000 e1a00000
- 0x40000060: e321f0db e59fd07c e321f0d7 e59fd078 e321f0d1 e59fd074 e321f0d2 e59fd070
- > -
PASS
RAM002LPC2148ZY100016 bit Write/read RAMReset init is workingOn the telnet interface
- > mwh ram_address 0xbeef 16
- > mdh ram_address 32 -
-
The commands should execute without error. A clear failure is a memory access exception. The result of running the commands should be a list of 16 locations 16bit long containing 0xbeef.
- - > mwh 0x0 0xbeef 16
- > mdh 0x0 32
- 0x00000000: beef beef beef beef beef beef beef beef beef beef beef beef beef beef beef beef
- 0x00000020: 00e0 0000 021c 0000 0240 0000 026c 0000 0288 0000 0000 0000 0388 0000 0350 0000
- > -
-
- > mwh 0x40000000 0xbeef 16
- > mdh 0x40000000 32
- 0x40000000: beef beef beef beef beef beef beef beef beef beef beef beef beef beef beef beef
- 0x40000020: beef dead beef dead beef dead beef dead beef dead beef dead beef dead beef dead
- > -
PASS
RAM003LPC2148ZY10008 bit Write/read RAMReset init is workingOn the telnet interface
- > mwb ram_address 0xab 16
- > mdb ram_address 32 -
-
The commands should execute without error. A clear failure is a memory access exception. The result of running the commands should be a list of 16 locations 8bit long containing 0xab.
- - > mwb ram_address 0xab 16
- > mdb ram_address 32
- 0x00000000: ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- > -
-
- > mwb 0x40000000 0xab 16 - > mdb 0x40000000 32 - 0x40000000: ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab ef be ef be ef be ef be ef be ef be ef be ef be - > - - PASS
- - - -

Flash access

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
IDTargetInterfaceDescriptionInitial stateInputExpected outputActual outputPass/Fail
FLA001LPC2148ZY1000Flash probeReset init is workingOn the telnet interface:
- > flash probe 0 -
The command should execute without error. The output should state the name of the flash and the starting address. An example of output:
- flash 'ecosflash' found at 0x01000000 -
- - > flash probe 0
- flash 'lpc2000' found at 0x00000000 -
-
PASS
FLA002LPC2148ZY1000flash fillwReset init is working, flash is probedOn the telnet interface
- > flash fillw 0x1000000 0xdeadbeef 16 - -
The commands should execute without error. The output looks like:
- - wrote 64 bytes to 0x01000000 in 11.610000s (0.091516 kb/s) -
- To verify the contents of the flash:
- - > mdw 0x1000000 32
- 0x01000000: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef
- 0x01000020: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef
- 0x01000040: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- 0x01000060: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff -
-
- > flash fillw 0x0 0xdeadbeef 16
- Verification will fail since checksum in image (0xdeadbeef) to be written to flash is different from calculated vector checksum (0xe93fc777).
- To remove this warning modify build tools on developer PC to inject correct LPC vector checksum.
- wrote 64 bytes to 0x00000000 in 0.040000s (1.563 kb/s)
- > mdw 0 32
- 0x00000000: deadbeef deadbeef deadbeef deadbeef deadbeef e93fc777 deadbeef deadbeef
- 0x00000020: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef
- 0x00000040: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- 0x00000060: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- > -
FAIL
FLA003LPC2148ZY1000Flash eraseReset init is working, flash is probedOn the telnet interface
- > flash erase_address 0x1000000 0x2000 - -
The commands should execute without error.
- - erased address 0x01000000 length 8192 in 4.970000s - - To check that the flash has been erased, read at different addresses. The result should always be 0xff. - - > mdw 0x1000000 32
- 0x01000000: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- 0x01000020: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- 0x01000040: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- 0x01000060: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff -
-
- > flash erase_address 0 0x2000
- erased address 0x00000000 (length 8192) in 0.510000s (15.686 kb/s)
- > mdw 0 32
- 0x00000000: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- 0x00000020: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- 0x00000040: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- 0x00000060: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- > -
PASS
FLA004LPC2148ZY1000Loading to flash from GDBReset init is working, flash is probed, connectivity to GDB server is workingStart GDB using a ROM elf image, eg: arm-elf-gdb test_rom.elf.
- - (gdb) target remote ip:port
- (gdb) monitor reset
- (gdb) load
- Loading section .text, size 0x194 lma 0x100000
- Start address 0x100040, load size 404
- Transfer rate: 179 bytes/sec, 404 bytes/write. - (gdb) monitor verify_image path_to_elf_file -
-
The output should look like:
- - verified 404 bytes in 5.060000s -
- The failure message is something like:
- Verify operation failed address 0x00200000. Was 0x00 instead of 0x18 -
- - (gdb) moni verify_image /tftp/10.0.0.194/test_rom.elf
- checksum mismatch - attempting binary compare
- Verify operation failed address 0x00000014. Was 0x58 instead of 0x60
-
- Command handler execution failed
- in procedure 'verify_image' called at file "command.c", line 647
- called at file "command.c", line 361
- (gdb) -
-
FAIL
- - - \ No newline at end of file diff --git a/testing/results/v0.4.0-rc1/SAM7.html b/testing/results/v0.4.0-rc1/SAM7.html deleted file mode 100755 index a400a476f..000000000 --- a/testing/results/v0.4.0-rc1/SAM7.html +++ /dev/null @@ -1,853 +0,0 @@ - - -Test results for revision 1.62 - - - - -

SAM7

- -

Connectivity

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
IDTargetInterfaceDescriptionInitial stateInputExpected outputActual outputPass/Fail
CON001SAM7S64ZY1000Telnet connectionPower on, jtag target attachedOn console, type
telnet ip port
Open On-Chip Debugger
>
Open On-Chip Debugger
>
PASS
CON002SAM7S64ZY1000GDB server connectionPower on, jtag target attachedOn GDB console, type
target remote ip:port
Remote debugging using 10.0.0.73:3333 - (gdb) tar remo 10.0.0.73:3333
- Remote debugging using 10.0.0.73:3333
- 0x00100174 in ?? ()
-
PASS
- -

Reset

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
IDTargetInterfaceDescriptionInitial stateInputExpected outputActual outputPass/Fail
RES001SAM7S64ZY1000Reset halt on a blank targetErase all the content of the flashConnect via the telnet interface and type
reset halt
Reset should return without error and the output should contain
target state: halted
- - > mdw 0 32
- 0x00000000: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- 0x00000020: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- 0x00000040: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- 0x00000060: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- > reset halt
- SRST took 2ms to deassert
- JTAG device found: 0x3f0f0f0f (Manufacturer: 0x787, Part: 0xf0f0, Version: 0x3)
- srst pulls trst - can not reset into halted mode. Issuing halt after reset.
- target state: halted
- target halted in ARM state due to debug request, current mode: Supervisor
- cpsr: 0x600000d3 pc: 0x000003c4
- > -
-
PASS
RES002SAM7S64ZY1000Reset init on a blank targetErase all the content of the flashConnect via the telnet interface and type
reset init
Reset should return without error and the output should contain
executing reset script 'name_of_the_script'
- - > reset init
- SRST took 2ms to deassert
- JTAG device found: 0x3f0f0f0f (Manufacturer: 0x787, Part: 0xf0f0, Version: 0x3)
- srst pulls trst - can not reset into halted mode. Issuing halt after reset.
- target state: halted
- target halted in ARM state due to debug request, current mode: Supervisor
- cpsr: 0x600000d3 pc: 0x000003c0
- > -
-
PASS
- NOTE! Even if there is no message, the reset script is being executed (proved by side effects)
RES003SAM7S64ZY1000Reset after a power cycle of the targetReset the target then power cycle the targetConnect via the telnet interface and type
reset halt after the power was detected
Reset should return without error and the output should contain
target state: halted
- - Sensed nSRST asserted
- Sensed power dropout.
- target state: halted
- target halted in ARM state due to debug request, current mode: Supervisor
- cpsr: 0xf00000d3 pc: 0xd5dff7e6
- Sensed power restore.
- Sensed nSRST deasserted
- > reset halt
- JTAG device found: 0x3f0f0f0f (Manufacturer: 0x787, Part: 0xf0f0, Version: 0x3)
- srst pulls trst - can not reset into halted mode. Issuing halt after reset.
- target state: halted
- target halted in ARM state due to debug request, current mode: Supervisor
- cpsr: 0xf00000d3 pc: 0x0000072c
- > -
-
PASS
RES004SAM7S64ZY1000Reset halt on a blank target where reset halt is supportedErase all the content of the flashConnect via the telnet interface and type
reset halt
Reset should return without error and the output should contain
target state: halted
pc = 0
- - > reset halt
- SRST took 2ms to deassert
- JTAG device found: 0x3f0f0f0f (Manufacturer: 0x787, Part: 0xf0f0, Version: 0x3)
- srst pulls trst - can not reset into halted mode. Issuing halt after reset.
- target state: halted
- target halted in ARM state due to debug request, current mode: Supervisor
- cpsr: 0x300000d3 pc: 0x000003c0 -
-
PASS
RES005SAM7S64ZY1000Reset halt on a blank target using return clockErase all the content of the flash, set the configuration script to use RCLKConnect via the telnet interface and type
reset halt
Reset should return without error and the output should contain
target state: halted
- - > jtag_khz 0
- jtag_khz: 0
- > reset init
- SRST took 2ms to deassert
- JTAG device found: 0x3f0f0f0f (Manufacturer: 0x787, Part: 0xf0f0, Version: 0x3)
- srst pulls trst - can not reset into halted mode. Issuing halt after reset.
- target state: halted
- target halted in ARM state due to debug request, current mode: Supervisor
- cpsr: 0x300000d3 pc: 0x000003c0
- executing event/sam7s256_reset.script
- > -
-
PASS
- -

JTAG Speed

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
IDTargetZY1000DescriptionInitial stateInputExpected outputActual outputPass/Fail
SPD001SAM7S64ZY100016MHz on normal operationReset init the target according to RES002 Change speed and exercise a memory access over the JTAG, for example
mdw 0x0 32
The command should run without any errors. If any JTAG checking errors happen, the test failed - - > jtag_khz 16000
- jtag_speed 4 => JTAG clk=16.000000
- jtag_khz: 16000
- > mdw 0 32
- 0x00000000: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- 0x00000020: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- 0x00000040: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- 0x00000060: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- > -
-
PASS
SPD002SAM7S64ZY10008MHz on normal operationReset init the target according to RES002 Change speed and exercise a memory access over the JTAG, for example
mdw 0x0 32
The command should run without any errors. If any JTAG checking errors happen, the test failed - - > jtag_khz 8000
- jtag_speed 8 => JTAG clk=8.000000
- jtag_khz: 8000
- > mdw 0 32
- 0x00000000: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- 0x00000020: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- 0x00000040: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- 0x00000060: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
-
-
PASS
SPD003SAM7S64ZY10004MHz on normal operationReset init the target according to RES002 Change speed and exercise a memory access over the JTAG, for example
mdw 0x0 32
The command should run without any errors. If any JTAG checking errors happen, the test failed - - > jtag_khz 4000
- jtag_speed 16 => JTAG clk=4.000000
- jtag_khz: 4000
- > mdw 0 32
- 0x00000000: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- 0x00000020: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- 0x00000040: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- 0x00000060: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- > -
-
PASS
SPD004SAM7S64ZY10002MHz on normal operationReset init the target according to RES002 Change speed and exercise a memory access over the JTAG, for example
mdw 0x0 32
The command should run without any errors. If any JTAG checking errors happen, the test failed - - > jtag_khz 2000
- jtag_speed 32 => JTAG clk=2.000000
- jtag_khz: 2000
- > mdw 0 32
- 0x00000000: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- 0x00000020: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- 0x00000040: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- 0x00000060: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- > -
-
PASS
SPD005SAM7S64ZY1000RCLK on normal operationReset init the target according to RES002 Change speed and exercise a memory access over the JTAG, for example
mdw 0x0 32
The command should run without any errors. If any JTAG checking errors happen, the test failed - - > jtag_khz 0
- jtag_khz: 0
- > mdw 0 32
- 0x00000000: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- 0x00000020: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- 0x00000040: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- 0x00000060: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- > -
-
PASS
- -

Debugging

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
IDTargetInterfaceDescriptionInitial stateInputExpected outputActual outputPass/Fail
DBG001SAM7S64ZY1000Load is workingReset init is working, RAM is accesible, GDB server is startedOn the console of the OS:
- arm-elf-gdb test_ram.elf
- (gdb) target remote ip:port
- (gdb) load -
Load should return without error, typical output looks like:
- - Loading section .text, size 0x14c lma 0x0
- Start address 0x40, load size 332
- Transfer rate: 180 bytes/sec, 332 bytes/write.
-
-
- (gdb) load
- Loading section .text, size 0x194 lma 0x200000
- Start address 0x200040, load size 404
- Transfer rate: 443 bytes/sec, 404 bytes/write.
- (gdb) -
PASS
DBG002SAM7S64ZY1000Software breakpointLoad the test_ram.elf application, use instructions from GDB001In the GDB console:
- - (gdb) monitor arm7_9 dbgrq enable
- software breakpoints enabled
- (gdb) break main
- Breakpoint 1 at 0xec: file src/main.c, line 71.
- (gdb) continue
- Continuing. -
-
The software breakpoint should be reached, a typical output looks like:
- - Breakpoint 1, main () at src/main.c:69
- 69 DWORD a = 1;
-
-
- - (gdb) monitor arm7_9 dbgrq enable
- use of EmbeddedICE dbgrq instead of breakpoint for target halt enabled
- (gdb) break main
- Breakpoint 1 at 0x200134: file src/main.c, line 69.
- (gdb) c
- Continuing.
-
- Breakpoint 1, main () at src/main.c:69
- 69 DWORD a = 1;
- Current language: auto
- The current source language is "auto; currently c".
- (gdb) -
-
PASS
DBG003SAM7S64ZY1000Single step in a RAM applicationLoad the test_ram.elf application, use instructions from GDB001, break in main using the instructions from GDB002In GDB, type
(gdb) step
The next instruction should be reached, typical output:
- - (gdb) step
- 70 DWORD b = 2; - -
-
- - (gdb) step
- 70 DWORD b = 2; - (gdb) -
-
PASS
DBG004SAM7S64ZY1000Software break points are working after a resetLoad the test_ram.elf application, use instructions from GDB001, break in main using the instructions from GDB002In GDB, type
- (gdb) monitor reset init
- (gdb) load
- (gdb) continue
-
The breakpoint should be reached, typical output:
- - Breakpoint 1, main () at src/main.c:69
- 69 DWORD a = 1; -
-
- (gdb) monitor reset init
- JTAG tap: sam7x256.cpu tap/device found: 0x3f0f0f0f (mfg: 0x787, part: 0xf0f0, ver: 0x3)
- srst pulls trst - can not reset into halted mode. Issuing halt after reset.
- target state: halted
- target halted in ARM state due to debug-request, current mode: Supervisor
- cpsr: 0x600000d3 pc: 0x0000031c
- (gdb) load
- Loading section .text, size 0x194 lma 0x200000
- Start address 0x200040, load size 404
- Transfer rate: 26 KB/sec, 404 bytes/write.
- (gdb) continue
- Continuing.
-
- Breakpoint 1, main () at src/main.c:69
- 69 DWORD a = 1;
- (gdb) -
PASS
DBG005SAM7S64ZY1000Hardware breakpointFlash the test_rom.elf application. Make this test after FLA004 has passedBe sure that gdb_memory_map and gdb_flash_program are enabled. In GDB, type
- - (gdb) monitor reset init
- (gdb) load
- Loading section .text, size 0x194 lma 0x100000
- Start address 0x100040, load size 404
- Transfer rate: 179 bytes/sec, 404 bytes/write.
- (gdb) monitor arm7_9 force_hw_bkpts enable
- force hardware breakpoints enabled
- (gdb) break main
- Breakpoint 1 at 0x100134: file src/main.c, line 69.
- (gdb) continue
-
-
The breakpoint should be reached, typical output:
- - Continuing.
-
- Breakpoint 1, main () at src/main.c:69
- 69 DWORD a = 1;
-
-
- - (gdb) monitor arm7_9 force_hw_bkpts enable
- force hardware breakpoints enabled
- (gdb) break main
- Breakpoint 1 at 0x100134: file src/main.c, line 69.
- (gdb) continue
- Continuing.
- Note: automatically using hardware breakpoints for read-only addresses.
- target state: halted
- target halted in ARM state due to breakpoint, current mode: Supervisor
- cpsr: 0x60000013 pc: 0x00100134
-
- Breakpoint 1, main () at src/main.c:69
- 69 DWORD a = 1;
- (gdb) -
-
PASS
DBG006SAM7S64ZY1000Hardware breakpoint is set after a resetFollow the instructions to flash and insert a hardware breakpoint from DBG005In GDB, type
- - (gdb) monitor reset
- (gdb) monitor reg pc 0x100000
- pc (/32): 0x00100000
- (gdb) continue -

- where the value inserted in PC is the start address of the application -
The breakpoint should be reached, typical output:
- - Continuing.
-
- Breakpoint 1, main () at src/main.c:69
- 69 DWORD a = 1;
-
-
- - (gdb) monitor reset init
- SRST took 3ms to deassert
- JTAG device found: 0x3f0f0f0f (Manufacturer: 0x787, Part: 0xf0f0, Version: 0x3)
- srst pulls trst - can not reset into halted mode. Issuing halt after reset.
- target state: halted
- target halted in ARM state due to debug request, current mode: Supervisor
- cpsr: 0x60000013 pc: 0x00100168
- executing event/sam7s256_reset.script
- (gdb) monitor reg pc 0x100000
- pc (/32): 0x00100000
- (gdb) continue
- Continuing.
- target state: halted
- target halted in ARM state due to single step, current mode: Supervisor
- cpsr: 0x60000013 pc: 0x00100040
- target state: halted
- target halted in ARM state due to breakpoint, current mode: Supervisor
- cpsr: 0x60000013 pc: 0x00100134
-
- Breakpoint 1, main () at src/main.c:69
- 69 DWORD a = 1;
- (gdb) -
-
PASS
DBG007SAM7S64ZY1000Single step in ROMFlash the test_rom.elf application and set a breakpoint in main, use DBG005. Make this test after FLA004 has passedBe sure that gdb_memory_map and gdb_flash_program are enabled. In GDB, type
- - (gdb) monitor reset
- (gdb) load
- Loading section .text, size 0x194 lma 0x100000
- Start address 0x100040, load size 404
- Transfer rate: 179 bytes/sec, 404 bytes/write.
- (gdb) monitor arm7_9 force_hw_bkpts enable
- force hardware breakpoints enabled
- (gdb) break main
- Breakpoint 1 at 0x100134: file src/main.c, line 69.
- (gdb) continue
- Continuing.
-
- Breakpoint 1, main () at src/main.c:69
- 69 DWORD a = 1;
- (gdb) step -
-
The breakpoint should be reached, typical output:
- - target state: halted
- target halted in ARM state due to single step, current mode: Supervisor
- cpsr: 0x60000013 pc: 0x0010013c
- 70 DWORD b = 2;
-
-
- Breakpoint 1, main () at src/main.c:69
- 69 DWORD a = 1;
- (gdb) step
- target state: halted
- target halted in ARM state due to single step, current mode: Supervisor
- cpsr: 0x60000013 pc: 0x00100138
- target state: halted
- target halted in ARM state due to single step, current mode: Supervisor
- cpsr: 0x60000013 pc: 0x0010013c
- 70 DWORD b = 2;
- (gdb) -
PASS
- -

RAM access

-Note: these tests are not designed to test/debug the target, but to test functionalities! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
IDTargetInterfaceDescriptionInitial stateInputExpected outputActual outputPass/Fail
RAM001SAM7S64ZY100032 bit Write/read RAMReset init is workingOn the telnet interface
- > mww ram_address 0xdeadbeef 16
- > mdw ram_address 32 -
-
The commands should execute without error. A clear failure is a memory access exception. The result of running the commands should be a list of 16 locations 32bit long containing 0xdeadbeef.
- - > mww 0x0 0xdeadbeef 16
- > mdw 0x0 32
- 0x00000000: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef
- 0x00000020: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef
- 0x00000040: e1a00000 e59fa51c e59f051c e04aa000 00080017 00009388 00009388 00009388
- 0x00000060: 00009388 0002c2c0 0002c2c0 000094f8 000094f4 00009388 00009388 00009388
-
-
- > mww 0x00200000 0xdeadbeef 16
- > mdw 0x00200000 32
- 0x00200000: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef
- 0x00200020: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef
- 0x00200040: e59f10b4 e3a00902 e5810004 e59f00ac e59f10ac e5810000 e3e010ff e59f00a4
- 0x00200060: e5810060 e59f10a0 e3e00000 e5810130 e5810124 e321f0db e59fd090 e321f0d7 -
PASS
RAM002SAM7S64ZY100016 bit Write/read RAMReset init is workingOn the telnet interface
- > mwh ram_address 0xbeef 16
- > mdh ram_address 32 -
-
The commands should execute without error. A clear failure is a memory access exception. The result of running the commands should be a list of 16 locations 16bit long containing 0xbeef.
- - > mwh 0x0 0xbeef 16
- > mdh 0x0 32
- 0x00000000: beef beef beef beef beef beef beef beef beef beef beef beef beef beef beef beef
- 0x00000020: 00e0 0000 021c 0000 0240 0000 026c 0000 0288 0000 0000 0000 0388 0000 0350 0000
- > -
-
- > mwh 0x00200000 0xbeef 16
- > mdh 0x00200000 32
- 0x00200000: beef beef beef beef beef beef beef beef beef beef beef beef beef beef beef beef
- 0x00200020: 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 -
PASS
RAM003SAM7S64ZY10008 bit Write/read RAMReset init is workingOn the telnet interface
- > mwb ram_address 0xab 16
- > mdb ram_address 32 -
-
The commands should execute without error. A clear failure is a memory access exception. The result of running the commands should be a list of 16 locations 8bit long containing 0xab.
- - > mwb ram_address 0xab 16
- > mdb ram_address 32
- 0x00000000: ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- > -
-
- > mwb 0x00200000 0xab 16
- > mdb 0x00200000 32
- 0x00200000: ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -
PASS
- - - -

Flash access

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
IDTargetInterfaceDescriptionInitial stateInputExpected outputActual outputPass/Fail
FLA001SAM7S64ZY1000Flash probeReset init is workingOn the telnet interface:
- > flash probe 0 -
The command should execute without error. The output should state the name of the flash and the starting address. An example of output:
- flash 'ecosflash' found at 0x01000000 -
- - > flash probe 0
- flash 'at91sam7' found at 0x00100000 -
-
PASS
FLA002SAM7S64ZY1000flash fillwReset init is working, flash is probedOn the telnet interface
- > flash fillw 0x100000 0xdeadbeef 16 - -
The commands should execute without error. The output looks like:
- - wrote 64 bytes to 0x0100000 in 11.610000s (0.091516 kb/s) -
- To verify the contents of the flash:
- - > mdw 0x100000 32
- 0x0100000: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef
- 0x0100020: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef
- 0x0100040: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- 0x0100060: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff -
-
- > flash fillw 0x100000 0xdeadbeef 16
- wrote 64 bytes to 0x00100000 in 0.040000s (26.562500 kb/s)
- > mdw 0x100000 32
- 0x00100000: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef
- 0x00100020: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef
- 0x00100040: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- 0x00100060: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- > -
PASS
FLA003SAM7S64ZY1000Flash eraseReset init is working, flash is probedOn the telnet interface
- > flash erase_address 0x100000 0x2000 - -
The commands should execute without error.
- - erased address 0x0100000 length 8192 in 4.970000s - - To check that the flash has been erased, read at different addresses. The result should always be 0xff. - - > mdw 0x100000 32
- 0x0100000: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- 0x0100020: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- 0x0100040: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- 0x0100060: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff -
-
- > flash erase_address 0x100000 0x2000
- erased address 0x00100000 length 8192 in 0.020000s
- > mdw 0x100000 32
- 0x00100000: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- 0x00100020: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- 0x00100040: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- 0x00100060: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- > -
PASS
FLA004SAM7S64ZY1000Loading to flash from GDBReset init is working, flash is probed, connectivity to GDB server is workingStart GDB using a ROM elf image, eg: arm-elf-gdb test_rom.elf.
- - (gdb) target remote ip:port
- (gdb) monitor reset halt
- (gdb) load
- Loading section .text, size 0x194 lma 0x100000
- Start address 0x100040, load size 404
- Transfer rate: 179 bytes/sec, 404 bytes/write.
- (gdb) monitor verify_image path_to_elf_file -
-
The output should look like:
- - verified 404 bytes in 5.060000s -
- The failure message is something like:
- Verify operation failed address 0x00200000. Was 0x00 instead of 0x18 -
- - (gdb) load
- Loading section .text, size 0x194 lma 0x100000
- Start address 0x100040, load size 404
- Transfer rate: 4 KB/sec, 404 bytes/write.
- (gdb) moni verify_image /tftp/10.0.0.9/c:/temp/testing/examples/SAM7S256Test/test_rom.elf
- verified 404 bytes in 0.570000s -
-
PASS
- - - \ No newline at end of file diff --git a/testing/results/v0.4.0-rc1/STR710.html b/testing/results/v0.4.0-rc1/STR710.html deleted file mode 100755 index 1a18ad0e6..000000000 --- a/testing/results/v0.4.0-rc1/STR710.html +++ /dev/null @@ -1,907 +0,0 @@ - - -Test results for version 1.62 - - - - -

STR710

- -

Connectivity

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
IDTargetInterfaceDescriptionInitial stateInputExpected outputActual outputPass/Fail
CON001STR912ZY1000Telnet connectionPower on, jtag target attachedOn console, type
telnet ip port
Open On-Chip Debugger
>
> telnet 10.0.0.142
- Trying 10.0.0.142...
- Connected to 10.0.0.142.
- Escape character is '^]'.
- Open On-Chip Debugger
- > -
PASS
CON002STR912ZY1000GDB server connectionPower on, jtag target attachedOn GDB console, type
target remote ip:port
Remote debugging using 10.0.0.73:3333 - (gdb) tar remo 10.0.0.142:3333
- Remote debugging using 10.0.0.142:3333
- 0x00016434 in ?? ()
- (gdb) -
PASS
- -

Reset

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
IDTargetInterfaceDescriptionInitial stateInputExpected outputActual outputPass/Fail
RES001STR912ZY1000Reset halt on a blank targetErase all the content of the flashConnect via the telnet interface and type
reset halt
Reset should return without error and the output should contain
target state: halted
- -> mdw 0 32
-0x00000000: 75755000 8a930104 65696f65 939a3e98 214751f1 fa0edb9b 6664686d 931a989e
-0x00000020: 676c65e4 9a0a0982 25653445 da02ba90 c4ed3165 9b9a8a9a 65676365 01981292
-0x00000040: 212e0982 82ba3f8b 34674765 96ba1a9a 6175e7e5 9b9ab91a 0789644d 120a9a18
-0x00000060: 65446167 80d20982 6d6d6565 187090ca 65277d65 9a9a0b81 6960416c 9ffe88b8
-> reset
-jtag_speed 6400 => JTAG clk=0.010000
-10 kHz
-JTAG tap: str710.cpu tap/device found: 0x3f0f0f0f (mfg: 0x787, part: 0xf0f0, ver: 0x3)
->
-
-
PASS
RES002STR912ZY1000Reset init on a blank targetErase all the content of the flashConnect via the telnet interface and type
reset init
Reset should return without error and the output should contain
executing reset script 'name_of_the_script'
- -> reset init
-jtag_speed 6400 => JTAG clk=0.010000
-10 kHz
-JTAG tap: str710.cpu tap/device found: 0x3f0f0f0f (mfg: 0x787, part: 0xf0f0, ver: 0x3)
-srst pulls trst - can not reset into halted mode. Issuing halt after reset.
-target state: halted
-target halted in ARM state due to debug-request, current mode: Undefined instruction
-cpsr: 0xf00000db pc: 0x00000004
-jtag_speed 10 => JTAG clk=6.400000
-6400 kHz -
-
PASS
RES003STR912ZY1000Reset after a power cycle of the targetReset the target then power cycle the targetConnect via the telnet interface and type
reset halt after the power was detected
Reset should return without error and the output should contain
target state: halted
- - nsed power dropout.
- nsed power dropout.
- nsed nSRST deasserted.
- invalid mode value encountered 0
-cpsr contains invalid mode value - communication failure
-jtag_speed 6400 => JTAG clk=0.010000
-10 kHz
-JTAG tap: str710.cpu tap/device found: 0x3f0f0f0f (mfg: 0x787, part: 0xf0f0, ver: 0x3)
-srst pulls trst - can not reset into halted mode. Issuing halt after reset.
-target state: halted
-target halted in ARM state due to debug-request, current mode: Supervisor
-cpsr: 0x100000d3 pc: 0x0000001c
-jtag_speed 10 => JTAG clk=6.400000
-6400 kHz
- nsed power restore.
-jtag_speed 6400 => JTAG clk=0.010000
-10 kHz
-JTAG tap: str710.cpu tap/device found: 0x3f0f0f0f (mfg: 0x787, part: 0xf0f0, ver: 0x3)
-srst pulls trst - can not reset into halted mode. Issuing halt after reset.
-target state: halted
-target halted in ARM state due to debug-request, current mode: Supervisor
-cpsr: 0x500000d3 pc: 0x00000000
-jtag_speed 10 => JTAG clk=6.400000
-6400 kHz
-> reset init
-jtag_speed 6400 => JTAG clk=0.010000
-10 kHz
-JTAG tap: str710.cpu tap/device found: 0x3f0f0f0f (mfg: 0x787, part: 0xf0f0, ver: 0x3)
-srst pulls trst - can not reset into halted mode. Issuing halt after reset.
-target state: halted
-target halted in ARM state due to debug-request, current mode: Supervisor
-cpsr: 0x500000d3 pc: 0x00000000
-jtag_speed 10 => JTAG clk=6.400000
-6400 kHz
-> -
-
PASS
RES004STR912ZY1000Reset halt on a blank target where reset halt is supportedErase all the content of the flashConnect via the telnet interface and type
reset halt
Reset should return without error and the output should contain
target state: halted
- -> reset halt
-jtag_speed 6400 => JTAG clk=0.010000
-10 kHz
-JTAG tap: str710.cpu tap/device found: 0x3f0f0f0f (mfg: 0x787, part: 0xf0f0, ver: 0x3)
-srst pulls trst - can not reset into halted mode. Issuing halt after reset.
-target state: halted
-target halted in ARM state due to debug-request, current mode: Supervisor
-cpsr: 0x200000d3 pc: 0xfe50cba4
-> -
-
PASS
RES005STR912ZY1000Reset halt on a blank target using return clockErase all the content of the flash, set the configuration script to use RCLKConnect via the telnet interface and type
reset halt
Reset should return without error and the output should contain
target state: halted
- - > jtag_khz 0
-RCLK - adaptive
-RCLK timeout
-RCLK timeout
-RCLK timeout
- > reset halt
- RCLK timeout
-jtag_speed 6400 => JTAG clk=0.010000
-10 kHz
-JTAG tap: str710.cpu tap/device found: 0x3f0f0f0f (mfg: 0x787, part: 0xf0f0, ver: 0x3)
-srst pulls trst - can not reset into halted mode. Issuing halt after reset.
-target state: halted
-target halted in ARM state due to debug-request, current mode: Supervisor
-cpsr: 0x200000d3 pc: 0xfe50cb50
-
-
FAIL
- -

JTAG Speed

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
IDTargetZY1000DescriptionInitial stateInputExpected outputActual outputPass/Fail
SPD001STR912ZY100016MHz on normal operationReset init the target according to RES002 Change speed and exercise a memory access over the JTAG, for example
mdw 0x0 32
The command should run without any errors. If any JTAG checking errors happen, the test failed - -> jtag_khz 16000
-jtag_speed 4 => JTAG clk=16.000000
-16000 kHz
-> mdw 0 32
-0x00000000: 75755000 8a930104 65696f65 939a3e98 214751f1 fa0edb9b 6664686d 931a989e
-0x00000020: 676c65e4 9a0a0982 25653445 da02ba90 c4ed3165 9b9a8a9a 65676365 01981292
-0x00000040: 212e0982 82ba3f8b 34674765 96ba1a9a 6175e7e5 9b9ab91a 0789644d 120a9a18
-0x00000060: 65446167 80d20982 6d6d6565 187090ca 65277d65 9a9a0b81 6960416c 9ffe88b8
-> -
-
PASS
SPD002STR912ZY10008MHz on normal operationReset init the target according to RES002 Change speed and exercise a memory access over the JTAG, for example
mdw 0x0 32
The command should run without any errors. If any JTAG checking errors happen, the test failed - -> jtag_khz 8000
-jtag_speed 8 => JTAG clk=8.000000
-8000 kHz
-> mdw 0 32
-0x00000000: 75755000 8a930104 65696f65 939a3e98 214751f1 fa0edb9b 6664686d 931a989e
-0x00000020: 676c65e4 9a0a0982 25653445 da02ba90 c4ed3165 9b9a8a9a 65676365 01981292
-0x00000040: 212e0982 82ba3f8b 34674765 96ba1a9a 6175e7e5 9b9ab91a 0789644d 120a9a18
-0x00000060: 65446167 80d20982 6d6d6565 187090ca 65277d65 9a9a0b81 6960416c 9ffe88b8
-> -
-
PASS
SPD003STR912ZY10004MHz on normal operationReset init the target according to RES002 Change speed and exercise a memory access over the JTAG, for example
mdw 0x0 32
The command should run without any errors. If any JTAG checking errors happen, the test failed - -> jtag_khz 4000
-jtag_speed 16 => JTAG clk=4.000000
-4000 kHz
-> mdw 0 32
-0x00000000: 75755000 8a930104 65696f65 939a3e98 214751f1 fa0edb9b 6664686d 931a989e
-0x00000020: 676c65e4 9a0a0982 25653445 da02ba90 c4ed3165 9b9a8a9a 65676365 01981292
-0x00000040: 212e0982 82ba3f8b 34674765 96ba1a9a 6175e7e5 9b9ab91a 0789644d 120a9a18
-0x00000060: 65446167 80d20982 6d6d6565 187090ca 65277d65 9a9a0b81 6960416c 9ffe88b8
-> -
-
PASS
SPD004STR912ZY10002MHz on normal operationReset init the target according to RES002 Change speed and exercise a memory access over the JTAG, for example
mdw 0x0 32
The command should run without any errors. If any JTAG checking errors happen, the test failed - -> > jtag_khz 2000
-jtag_speed 32 => JTAG clk=2.000000
-2000 kHz
-> mdw 0 32
-0x00000000: 75755000 8a930104 65696f65 939a3e98 214751f1 fa0edb9b 6664686d 931a989e
-0x00000020: 676c65e4 9a0a0982 25653445 da02ba90 c4ed3165 9b9a8a9a 65676365 01981292
-0x00000040: 212e0982 82ba3f8b 34674765 96ba1a9a 6175e7e5 9b9ab91a 0789644d 120a9a18
-0x00000060: 65446167 80d20982 6d6d6565 187090ca 65277d65 9a9a0b81 6960416c 9ffe88b8
-> -
-
PASS
SPD005STR912ZY1000RCLK on normal operationReset init the target according to RES002 Change speed and exercise a memory access over the JTAG, for example
mdw 0x0 32
The command should run without any errors. If any JTAG checking errors happen, the test failed - -> jtag_khz 0
-RCLK - adaptive
-RCLK timeout
-RCLK timeout
-RCLK timeout -
-
FAIL
- -

Debugging

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
IDTargetInterfaceDescriptionInitial stateInputExpected outputActual outputPass/Fail
DBG001STR912ZY1000Load is workingReset init is working, RAM is accesible, GDB server is startedOn the console of the OS:
- arm-elf-gdb test_ram.elf
- (gdb) target remote ip:port
- (gdb) load -
Load should return without error, typical output looks like:
- - Loading section .text, size 0x14c lma 0x0
- Start address 0x40, load size 332
- Transfer rate: 180 bytes/sec, 332 bytes/write.
-
-
-(gdb) load
-Loading section .text, size 0x1cc lma 0x20000000
-Loading section .vectors, size 0x40 lma 0x200001cc
-Loading section .rodata, size 0x4 lma 0x2000020c
-Start address 0x20000000, load size 528
-Transfer rate: 64 KB/sec, 176 bytes/write.
-(gdb) -
PASS
DBG002STR912ZY1000Software breakpointLoad the test_ram.elf application, use instructions from GDB001In the GDB console:
- - (gdb) monitor gdb_breakpoint_override soft
- force soft breakpoints
- (gdb) break main
- Breakpoint 1 at 0xec: file src/main.c, line 71.
- (gdb) continue
- Continuing. -
-
The software breakpoint should be reached, a typical output looks like:
- - target state: halted
- target halted in ARM state due to breakpoint, current mode: Supervisor
- cpsr: 0x000000d3 pc: 0x000000ec
-
- Breakpoint 1, main () at src/main.c:71
- 71 DWORD a = 1; -
-
- -(gdb) monitor gdb_breakpoint_override soft
-force soft breakpoints
-Current language: auto
-The current source language is "auto; currently asm".
-(gdb) break main
-Breakpoint 1 at 0x20000170: file src/main.c, line 69.
-(gdb) c
-Continuing.
-
-Breakpoint 1, main () at src/main.c:69
-69 DWORD a = 1;
-Current language: auto
-The current source language is "auto; currently c".
-(gdb) -
-
PASS
DBG003STR912ZY1000Single step in a RAM applicationLoad the test_ram.elf application, use instructions from GDB001, break in main using the instructions from GDB002In GDB, type
(gdb) step
The next instruction should be reached, typical output:
- - (gdb) step
- target state: halted
- target halted in ARM state due to single step, current mode: Abort
- cpsr: 0x20000097 pc: 0x000000f0
- target state: halted
- target halted in ARM state due to single step, current mode: Abort
- cpsr: 0x20000097 pc: 0x000000f4
- 72 DWORD b = 2; -
-
- - (gdb) step
- 70 DWORD b = 2;
- (gdb) -
-
PASS
DBG004STR912ZY1000Software break points are working after a resetLoad the test_ram.elf application, use instructions from GDB001, break in main using the instructions from GDB002In GDB, type
- (gdb) monitor reset init
- (gdb) load
- (gdb) continue
-
The breakpoint should be reached, typical output:
- - target state: halted
- target halted in ARM state due to breakpoint, current mode: Supervisor
- cpsr: 0x000000d3 pc: 0x000000ec
-
- Breakpoint 1, main () at src/main.c:71
- 71 DWORD a = 1; -
-
-((gdb) monitor reset init
-jtag_speed 6400 => JTAG clk=0.010000
-10 kHz
-JTAG tap: str710.cpu tap/device found: 0x3f0f0f0f (mfg: 0x787, part: 0xf0f0, ver: 0x3)
-srst pulls trst - can not reset into halted mode. Issuing halt after reset.
-target state: halted
-target halted in ARM state due to debug-request, current mode: Supervisor
-cpsr: 0x60000013 pc: 0x200001bc
-jtag_speed 10 => JTAG clk=6.400000
-6400 kHz
-(gdb) load
-Loading section .text, size 0x1cc lma 0x20000000
-Loading section .vectors, size 0x40 lma 0x200001cc
-Loading section .rodata, size 0x4 lma 0x2000020c
-Start address 0x20000000, load size 528
-Transfer rate: 64 KB/sec, 176 bytes/write.
-(gdb) c
-Continuing.
-
-Breakpoint 1, main () at src/main.c:69
-69 DWORD a = 1;
-(gdb) -
PASS
DBG005STR912ZY1000Hardware breakpointFlash the test_rom.elf application. Make this test after FLA004 has passedBe sure that gdb_memory_map and gdb_flash_program are enabled. In GDB, type
- - (gdb) monitor reset init
- (gdb) load
- Loading section .text, size 0x194 lma 0x100000
- Start address 0x100040, load size 404
- Transfer rate: 179 bytes/sec, 404 bytes/write.
- (gdb) monitor gdb_breakpoint_override hard
- force hard breakpoints
- (gdb) break main
- Breakpoint 1 at 0x100134: file src/main.c, line 69.
- (gdb) continue
-
-
The breakpoint should be reached, typical output:
- - Continuing.
-
- Breakpoint 1, main () at src/main.c:69
- 69 DWORD a = 1;
-
-
- -(gdb) monitor gdb_breakpoint_override hard
-force hard breakpoints
-(gdb) break main
-Breakpoint 1 at 0x40000170: file src/main.c, line 69.
-(gdb) c
-Continuing.
-Note: automatically using hardware breakpoints for read-only addresses.
-
-Breakpoint 1, main () at src/main.c:69
-69 DWORD a = 1;
-Current language: auto
-The current source language is "auto; currently c".
-(gdb) -
-
PASS
DBG006STR912ZY1000Hardware breakpoint is set after a resetFollow the instructions to flash and insert a hardware breakpoint from DBG005In GDB, type
- - (gdb) monitor reset
- (gdb) monitor reg pc 0x100000
- pc (/32): 0x00100000
- (gdb) continue -

- where the value inserted in PC is the start address of the application -
The breakpoint should be reached, typical output:
- - Continuing.
-
- Breakpoint 1, main () at src/main.c:69
- 69 DWORD a = 1;
-
-
- -(gdb) monitor reset init
-jtag_speed 6400 => JTAG clk=0.010000
-10 kHz
-JTAG tap: str710.cpu tap/device found: 0x3f0f0f0f (mfg: 0x787, part: 0xf0f0, ver: 0x3)
-srst pulls trst - can not reset into halted mode. Issuing halt after reset.
-target state: halted
-target halted in ARM state due to debug-request, current mode: Undefined instruction
-cpsr: 0x400000db pc: 0x010aea80
-jtag_speed 10 => JTAG clk=6.400000
-6400 kHz
-(gdb) monitor reg pc 0x40000000
-pc (/32): 0x40000000
-(gdb) c
-Continuing.
-
-Breakpoint 1, main () at src/main.c:69
-69 DWORD a = 1;
-Current language: auto
-The current source language is "auto; currently c".
-(gdb) -
-
PASS
DBG007STR912ZY1000Single step in ROMFlash the test_rom.elf application and set a breakpoint in main, use DBG005. Make this test after FLA004 has passedBe sure that gdb_memory_map and gdb_flash_program are enabled. In GDB, type
- - (gdb) monitor reset
- (gdb) load
- Loading section .text, size 0x194 lma 0x100000
- Start address 0x100040, load size 404
- Transfer rate: 179 bytes/sec, 404 bytes/write.
- (gdb) monitor arm7_9 force_hw_bkpts enable
- force hardware breakpoints enabled
- (gdb) break main
- Breakpoint 1 at 0x100134: file src/main.c, line 69.
- (gdb) continue
- Continuing.
-
- Breakpoint 1, main () at src/main.c:69
- 69 DWORD a = 1;
- (gdb) step -
-
The breakpoint should be reached, typical output:
- - target state: halted
- target halted in ARM state due to single step, current mode: Supervisor
- cpsr: 0x60000013 pc: 0x0010013c
- 70 DWORD b = 2;
-
-
-Breakpoint 2, main () at src/main.c:69
-69 DWORD a = 1;
-Current language: auto
-The current source language is "auto; currently c".
-(gdb) step
-70 DWORD b = 2;
-(gdb) -
PASS
- -

RAM access

-Note: these tests are not designed to test/debug the target, but to test functionalities! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
IDTargetInterfaceDescriptionInitial stateInputExpected outputActual outputPass/Fail
RAM001STR912ZY100032 bit Write/read RAMReset init is workingOn the telnet interface
- > mww ram_address 0xdeadbeef 16
- > mdw ram_address 32 -
-
The commands should execute without error. A clear failure is a memory access exception. The result of running the commands should be a list of 16 locations 32bit long containing 0xdeadbeef.
- - > mww 0x0 0xdeadbeef 16
- > mdw 0x0 32
- 0x00000000: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef
- 0x00000020: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef
- 0x00000040: e1a00000 e59fa51c e59f051c e04aa000 00080017 00009388 00009388 00009388
- 0x00000060: 00009388 0002c2c0 0002c2c0 000094f8 000094f4 00009388 00009388 00009388
-
-
-> mww 0x20000000 0xdeadbeef 16
-> mdw 0x20000000 32
-0x20000000: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef
-0x20000020: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef
-0x20000040: e3a0020a e3a01073 e5801018 e5901008 e3110002 0afffffc e3a0020a e59f10d0
-0x20000060: e5801008 e321f0db e59fd0c8 e321f0d7 e59fd0c4 e321f0d1 e59fd0c0 e321f0d2
-> -
PASS
RAM002STR912ZY100016 bit Write/read RAMReset init is workingOn the telnet interface
- > mwh ram_address 0xbeef 16
- > mdh ram_address 32 -
-
The commands should execute without error. A clear failure is a memory access exception. The result of running the commands should be a list of 16 locations 16bit long containing 0xbeef.
- - > mwh 0x0 0xbeef 16
- > mdh 0x0 32
- 0x00000000: beef beef beef beef beef beef beef beef beef beef beef beef beef beef beef beef
- 0x00000020: 00e0 0000 021c 0000 0240 0000 026c 0000 0288 0000 0000 0000 0388 0000 0350 0000
- > -
-
-> mwh 0x20000000 0xbeef 16
-> mdh 0x20000000 32
-0x20000000: beef beef beef beef beef beef beef beef beef beef beef beef beef beef beef beef
-0x20000020: beef dead beef dead beef dead beef dead beef dead beef dead beef dead beef dead
-> -
PASS
RAM003STR912ZY10008 bit Write/read RAMReset init is workingOn the telnet interface
- > mwb ram_address 0xab 16
- > mdb ram_address 32 -
-
The commands should execute without error. A clear failure is a memory access exception. The result of running the commands should be a list of 16 locations 8bit long containing 0xab.
- - > mwb ram_address 0xab 16
- > mdb ram_address 32
- 0x00000000: ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- > -
-
-> mwb 0x20000000 0xab 16
-> mdb 0x20000000 32
-0x20000000: ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab ef be ef be ef be ef be ef be ef be ef be ef be
-> -
PASS
- - - -

Flash access

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
IDTargetInterfaceDescriptionInitial stateInputExpected outputActual outputPass/Fail
FLA001STR912ZY1000Flash probeReset init is workingOn the telnet interface:
- > flash probe 0 -
The command should execute without error. The output should state the name of the flash and the starting address. An example of output:
- flash 'ecosflash' found at 0x01000000 -
- - > flash probe 0
- flash 'str7x' found at 0x40000000
- > -
-
PASS
FLA002STR912ZY1000flash fillwReset init is working, flash is probedOn the telnet interface
- > flash fillw 0x1000000 0xdeadbeef 16 - -
The commands should execute without error. The output looks like:
- - wrote 64 bytes to 0x01000000 in 11.610000s (0.091516 kb/s) -
- To verify the contents of the flash:
- - > mdw 0x1000000 32
- 0x01000000: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef
- 0x01000020: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef
- 0x01000040: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- 0x01000060: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff -
-
- > flash fillw 0x40000000 0xdeadbeef 16
- wrote 64 bytes to 0x40000000 in 0.000000s (inf kb/s)
- > mdw 0x40000000 32
- 0x40000000: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef
- 0x40000020: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef
- 0x40000040: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- 0x40000060: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- > -
PASS
FLA003STR912ZY1000Flash eraseReset init is working, flash is probedOn the telnet interface
- > flash erase_address 0x1000000 0x2000 - -
The commands should execute without error.
- - erased address 0x01000000 length 8192 in 4.970000s - - To check that the flash has been erased, read at different addresses. The result should always be 0xff. - - > mdw 0x1000000 32
- 0x01000000: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- 0x01000020: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- 0x01000040: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- 0x01000060: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff -
-
-> flash erase_address 0x40000000 0x2000
-erased address 0x40000000 (length 8192) in 0.270000s (29.630 kb/s)
-> mdw 0x40000000 32
-0x40000000: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
-0x40000020: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
-0x40000040: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
-0x40000060: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
-> -
PASS
FLA004STR912ZY1000Loading to flash from GDBReset init is working, flash is probed, connectivity to GDB server is workingStart GDB using a ROM elf image, eg: arm-elf-gdb test_rom.elf.
- - (gdb) target remote ip:port
- (gdb) monitor reset
- (gdb) load
- Loading section .text, size 0x194 lma 0x100000
- Start address 0x100040, load size 404
- Transfer rate: 179 bytes/sec, 404 bytes/write. - (gdb) monitor verify_image path_to_elf_file -
-
The output should look like:
- - verified 404 bytes in 5.060000s -
- The failure message is something like:
- Verify operation failed address 0x00200000. Was 0x00 instead of 0x18 -
- -(gdb) load
-Loading section .text, size 0x1cc lma 0x40000000
-Loading section .vectors, size 0x40 lma 0x400001cc
-Loading section .rodata, size 0x4 lma 0x4000020c
-Start address 0x40000000, load size 528
-Transfer rate: 53 bytes/sec, 176 bytes/write.
-(gdb) monitor verify_image /tftp/10.0.0.194/test_rom.elf
-verified 528 bytes in 4.760000s (0.108 kb/s)
-Current language: auto
-The current source language is "auto; currently asm".
-(gdb) -
-
PASS
- - - \ No newline at end of file diff --git a/testing/results/v0.4.0-rc1/STR912.html b/testing/results/v0.4.0-rc1/STR912.html deleted file mode 100755 index c8df03488..000000000 --- a/testing/results/v0.4.0-rc1/STR912.html +++ /dev/null @@ -1,1008 +0,0 @@ - - -Test results for version 1.62 - - - - -

STR912

- -

Connectivity

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
IDTargetInterfaceDescriptionInitial stateInputExpected outputActual outputPass/Fail
CON001STR912ZY1000Telnet connectionPower on, jtag target attachedOn console, type
telnet ip port
Open On-Chip Debugger
>
> telnet 10.0.0.142
- Trying 10.0.0.142...
- Connected to 10.0.0.142.
- Escape character is '^]'.
- Open On-Chip Debugger
- > -
PASS
CON002STR912ZY1000GDB server connectionPower on, jtag target attachedOn GDB console, type
target remote ip:port
Remote debugging using 10.0.0.73:3333 - (gdb) tar remo 10.0.0.142:3333
- Remote debugging using 10.0.0.142:3333
- 0x00016434 in ?? ()
- (gdb) -
PASS
- -

Reset

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
IDTargetInterfaceDescriptionInitial stateInputExpected outputActual outputPass/Fail
RES001STR912ZY1000Reset halt on a blank targetErase all the content of the flashConnect via the telnet interface and type
reset halt
Reset should return without error and the output should contain
target state: halted
- -> reset halt
-RCLK - adaptive
-SRST took 2ms to deassert
-JTAG tap: str912.flash tap/device found: 0x04570041 (mfg: 0x020, part: 0x4570, ver: 0x0)
-JTAG tap: str912.cpu tap/device found: 0x25966041 (mfg: 0x020, part: 0x5966, ver: 0x2)
-JTAG tap: str912.bs tap/device found: 0x2457f041 (mfg: 0x020, part: 0x457f, ver: 0x2)
-JTAG tap: str912.bs UNEXPECTED: 0x2457f041 (mfg: 0x020, part: 0x457f, ver: 0x2)
-JTAG tap: str912.bs expected 1 of 1: 0x1457f041 (mfg: 0x020, part: 0x457f, ver: 0x1)
-Trying to use configured scan chain anyway...
-Bypassing JTAG setup events due to errors
-SRST took 2ms to deassert
-target state: halted
-target halted in ARM state due to debug-request, current mode: Supervisor
-cpsr: 0x000000d3 pc: 0x00000000
-NOTE! DCC downloads have not been enabled, defaulting to slow memory writes. Type 'help dcc'.
-> -
-
PASS
RES002STR912ZY1000Reset init on a blank targetErase all the content of the flashConnect via the telnet interface and type
reset init
Reset should return without error and the output should contain
executing reset script 'name_of_the_script'
- -> reset init
-RCLK - adaptive
-SRST took 2ms to deassert
-JTAG tap: str912.flash tap/device found: 0x04570041 (mfg: 0x020, part: 0x4570, ver: 0x0)
-JTAG tap: str912.cpu tap/device found: 0x25966041 (mfg: 0x020, part: 0x5966, ver: 0x2)
-JTAG tap: str912.bs tap/device found: 0x2457f041 (mfg: 0x020, part: 0x457f, ver: 0x2)
-JTAG tap: str912.bs UNEXPECTED: 0x2457f041 (mfg: 0x020, part: 0x457f, ver: 0x2)
-JTAG tap: str912.bs expected 1 of 1: 0x1457f041 (mfg: 0x020, part: 0x457f, ver: 0x1)
-Trying to use configured scan chain anyway...
-Bypassing JTAG setup events due to errors
-SRST took 2ms to deassert
-target state: halted
-target halted in ARM state due to debug-request, current mode: Supervisor
-cpsr: 0x000000d3 pc: 0x00000000
-cleared protection for sectors 0 through 7 on flash bank 0
-NOTE! DCC downloads have not been enabled, defaulting to slow memory writes. Type 'help dcc'.
-> -
-
PASS
RES003STR912ZY1000Reset after a power cycle of the targetReset the target then power cycle the targetConnect via the telnet interface and type
reset halt after the power was detected
Reset should return without error and the output should contain
target state: halted
- - nsed nSRST asserted.
- nsed power dropout.
- nsed power restore.
-RCLK - adaptive
-SRST took 85ms to deassert
-SRST took 2ms to deassert
-JTAG tap: str912.flash tap/device found: 0x04570041 (mfg: 0x020, part: 0x4570, ver: 0x0)
-JTAG tap: str912.cpu tap/device found: 0x25966041 (mfg: 0x020, part: 0x5966, ver: 0x2)
-JTAG tap: str912.bs tap/device found: 0x2457f041 (mfg: 0x020, part: 0x457f, ver: 0x2)
-JTAG tap: str912.bs UNEXPECTED: 0x2457f041 (mfg: 0x020, part: 0x457f, ver: 0x2)
-JTAG tap: str912.bs expected 1 of 1: 0x1457f041 (mfg: 0x020, part: 0x457f, ver: 0x1)
-Trying to use configured scan chain anyway...
-Bypassing JTAG setup events due to errors
-SRST took 2ms to deassert
-target state: halted
-target halted in ARM state due to debug-request, current mode: Supervisor
-cpsr: 0x000000d3 pc: 0x00000000
-cleared protection for sectors 0 through 7 on flash bank 0
-NOTE! DCC downloads have not been enabled, defaulting to slow memory writes. Type 'help dcc'.
-> reset halt
-RCLK - adaptive
-SRST took 2ms to deassert
-JTAG tap: str912.flash tap/device found: 0x04570041 (mfg: 0x020, part: 0x4570, ver: 0x0)
-JTAG tap: str912.cpu tap/device found: 0x25966041 (mfg: 0x020, part: 0x5966, ver: 0x2)
-JTAG tap: str912.bs tap/device found: 0x2457f041 (mfg: 0x020, part: 0x457f, ver: 0x2)
-JTAG tap: str912.bs UNEXPECTED: 0x2457f041 (mfg: 0x020, part: 0x457f, ver: 0x2)
-JTAG tap: str912.bs expected 1 of 1: 0x1457f041 (mfg: 0x020, part: 0x457f, ver: 0x1)
-Trying to use configured scan chain anyway...
-Bypassing JTAG setup events due to errors
-SRST took 2ms to deassert
-target state: halted
-target halted in ARM state due to debug-request, current mode: Supervisor
-cpsr: 0x000000d3 pc: 0x00000000
-NOTE! DCC downloads have not been enabled, defaulting to slow memory writes. Type 'help dcc'.
-> -
-
PASS
RES004STR912ZY1000Reset halt on a blank target where reset halt is supportedErase all the content of the flashConnect via the telnet interface and type
reset halt
Reset should return without error and the output should contain
target state: halted
pc = 0
- -> reset halt
- RCLK - adaptive
-SRST took 2ms to deassert
-JTAG tap: str912.flash tap/device found: 0x04570041 (Manufacturer: 0x020, Part: 0x4570, Version: 0x0)
-JTAG Tap/device matched
-JTAG tap: str912.cpu tap/device found: 0x25966041 (Manufacturer: 0x020, Part: 0x5966, Version: 0x2)
-JTAG Tap/device matched
-JTAG tap: str912.bs tap/device found: 0x2457f041 (Manufacturer: 0x020, Part: 0x457f, Version: 0x2)
-JTAG Tap/device matched
-SRST took 2ms to deassert
-target state: halted
-target halted in ARM state due to debug-request, current mode: Supervisor
-cpsr: 0x000000d3 pc: 0x00000000
-> -
PASS
RES005STR912ZY1000Reset halt on a blank target using return clockErase all the content of the flash, set the configuration script to use RCLKConnect via the telnet interface and type
reset halt
Reset should return without error and the output should contain
target state: halted
- - > reset halt
-RCLK - adaptive
-SRST took 2ms to deassert
-JTAG tap: str912.flash tap/device found: 0x04570041 (mfg: 0x020, part: 0x4570, ver: 0x0)
-JTAG tap: str912.cpu tap/device found: 0x25966041 (mfg: 0x020, part: 0x5966, ver: 0x2)
-JTAG tap: str912.bs tap/device found: 0x2457f041 (mfg: 0x020, part: 0x457f, ver: 0x2)
-JTAG tap: str912.bs UNEXPECTED: 0x2457f041 (mfg: 0x020, part: 0x457f, ver: 0x2)
-JTAG tap: str912.bs expected 1 of 1: 0x1457f041 (mfg: 0x020, part: 0x457f, ver: 0x1)
-Trying to use configured scan chain anyway...
-Bypassing JTAG setup events due to errors
-SRST took 2ms to deassert
-target state: halted
-target halted in ARM state due to debug-request, current mode: Supervisor
-cpsr: 0x000000d3 pc: 0x00000000
-NOTE! DCC downloads have not been enabled, defaulting to slow memory writes. Type 'help dcc'.
-> -
-
PASS
- -

JTAG Speed

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
IDTargetZY1000DescriptionInitial stateInputExpected outputActual outputPass/Fail
SPD001STR912ZY100016MHz on normal operationReset init the target according to RES002 Change speed and exercise a memory access over the JTAG, for example
mdw 0x0 32
The command should run without any errors. If any JTAG checking errors happen, the test failed - -> jtag_khz 16000
-jtag_speed 4 => JTAG clk=16.000000
-16000 kHz
-ThumbEE -- incomplete support
-target state: halted
-target halted in ThumbEE state due to debug-request, current mode: System
-cpsr: 0xfdfdffff pc: 0xfdfdfff9
-> mdw 0 32
-0x00000000: 00000000 00000000 ffffffff ffffffff 00000001 ffffffff 00000001 ffffffff
-0x00000020: 00000001 00000001 00000001 00000001 00000001 fffffffe fffffffe 00000001
-0x00000040: fffffffe 00000000 00000000 00000000 00000000 00000000 00000000 00000000
-0x00000060: 00000000 00000000 00000000 00000000 ffffffff ffffffff 00000001 00000000
-invalid mode value encountered 0
-cpsr contains invalid mode value - communication failure
-ThumbEE -- incomplete support
-target state: halted
-target halted in ThumbEE state due to debug-request, current mode: System
-cpsr: 0xffffffff pc: 0xfffffff8
-> -
-
FAIL
SPD002STR912ZY10008MHz on normal operationReset init the target according to RES002 Change speed and exercise a memory access over the JTAG, for example
mdw 0x0 32
The command should run without any errors. If any JTAG checking errors happen, the test failed - -> jtag_khz 8000
-jtag_speed 8 => JTAG clk=8.000000
-8000 kHz
-> halt
-invalid mode value encountered 0
-cpsr contains invalid mode value - communication failure
-Command handler execution failed
-in procedure 'halt' called at file "command.c", line 647
-called at file "command.c", line 361
-Halt timed out, wake up GDB.
-> -
-
FAIL
SPD003STR912ZY10004MHz on normal operationReset init the target according to RES002 Change speed and exercise a memory access over the JTAG, for example
mdw 0x0 32
The command should run without any errors. If any JTAG checking errors happen, the test failed - -> jtag_khz 4000
-jtag_speed 16 => JTAG clk=4.000000
-4000 kHz
-> halt
-> mdw 0 32
-0x00000000: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
-0x00000020: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
-0x00000040: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
-0x00000060: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
-> -
-
PASS
SPD004STR912ZY10002MHz on normal operationReset init the target according to RES002 Change speed and exercise a memory access over the JTAG, for example
mdw 0x0 32
The command should run without any errors. If any JTAG checking errors happen, the test failed - -> jtag_khz 2000
-jtag_speed 32 => JTAG clk=2.000000
-2000 kHz
-> halt
-> mdw 0 32
-0x00000000: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
-0x00000020: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
-0x00000040: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
-0x00000060: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
-> -
-
PASS
SPD005STR912ZY1000RCLK on normal operationReset init the target according to RES002 Change speed and exercise a memory access over the JTAG, for example
mdw 0x0 32
The command should run without any errors. If any JTAG checking errors happen, the test failed - -> jtag_khz 0
-RCLK - adaptive
-> halt
-> mdw 0 32
-0x00000000: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
-0x00000020: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
-0x00000040: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
-0x00000060: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
-> -
-
PASS
- -

Debugging

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
IDTargetInterfaceDescriptionInitial stateInputExpected outputActual outputPass/Fail
DBG001STR912ZY1000Load is workingReset init is working, RAM is accesible, GDB server is startedOn the console of the OS:
- arm-elf-gdb test_ram.elf
- (gdb) target remote ip:port
- (gdb) load -
Load should return without error, typical output looks like:
- - Loading section .text, size 0x14c lma 0x0
- Start address 0x40, load size 332
- Transfer rate: 180 bytes/sec, 332 bytes/write.
-
-
-(gdb) load
-Loading section .text, size 0x1a0 lma 0x4000000
-Loading section .rodata, size 0x4 lma 0x40001a0
-Start address 0x4000000, load size 420
-Transfer rate: 29 KB/sec, 210 bytes/write.
-(gdb) -
PASS
DBG002STR912ZY1000Software breakpointLoad the test_ram.elf application, use instructions from GDB001In the GDB console:
- - (gdb) monitor gdb_breakpoint_override soft
- force soft breakpoints
- (gdb) break main
- Breakpoint 1 at 0xec: file src/main.c, line 71.
- (gdb) continue
- Continuing. -
-
The software breakpoint should be reached, a typical output looks like:
- - target state: halted
- target halted in ARM state due to breakpoint, current mode: Supervisor
- cpsr: 0x000000d3 pc: 0x000000ec
-
- Breakpoint 1, main () at src/main.c:71
- 71 DWORD a = 1; -
-
- -(gdb) monitor gdb_breakpoint_override soft
-force soft breakpoints
-Current language: auto
-The current source language is "auto; currently asm".
-(gdb) break main
-Breakpoint 1 at 0x4000144: file src/main.c, line 69.
-(gdb) c
-Continuing.
-
-Breakpoint 1, main () at src/main.c:69
-warning: Source file is more recent than executable.
-69 DWORD a = 1;
-Current language: auto
-The current source language is "auto; currently c".
-(gdb) -
-
PASS
DBG003STR912ZY1000Single step in a RAM applicationLoad the test_ram.elf application, use instructions from GDB001, break in main using the instructions from GDB002In GDB, type
(gdb) step
The next instruction should be reached, typical output:
- - (gdb) step
- target state: halted
- target halted in ARM state due to single step, current mode: Abort
- cpsr: 0x20000097 pc: 0x000000f0
- target state: halted
- target halted in ARM state due to single step, current mode: Abort
- cpsr: 0x20000097 pc: 0x000000f4
- 72 DWORD b = 2; -
-
- - (gdb) step
- 70 DWORD b = 2;
- (gdb)
-
-
PASS
DBG004STR912ZY1000Software break points are working after a resetLoad the test_ram.elf application, use instructions from GDB001, break in main using the instructions from GDB002In GDB, type
- (gdb) monitor reset init
- (gdb) load
- (gdb) continue
-
The breakpoint should be reached, typical output:
- - target state: halted
- target halted in ARM state due to breakpoint, current mode: Supervisor
- cpsr: 0x000000d3 pc: 0x000000ec
-
- Breakpoint 1, main () at src/main.c:71
- 71 DWORD a = 1; -
-
-(gdb) monitor reset init
-RCLK - adaptive
-SRST took 2ms to deassert
-JTAG tap: str912.flash tap/device found: 0x04570041 (mfg: 0x020, part: 0x4570, ver: 0x0)
-JTAG tap: str912.cpu tap/device found: 0x25966041 (mfg: 0x020, part: 0x5966, ver: 0x2)
-JTAG tap: str912.bs tap/device found: 0x2457f041 (mfg: 0x020, part: 0x457f, ver: 0x2)
-JTAG tap: str912.bs UNEXPECTED: 0x2457f041 (mfg: 0x020, part: 0x457f, ver: 0x2)
-JTAG tap: str912.bs expected 1 of 1: 0x1457f041 (mfg: 0x020, part: 0x457f, ver: 0x1)
-Trying to use configured scan chain anyway...
-Bypassing JTAG setup events due to errors
-SRST took 2ms to deassert
-target state: halted
-target halted in ARM state due to debug-request, current mode: Supervisor
-cpsr: 0x000000d3 pc: 0x00000000
-cleared protection for sectors 0 through 7 on flash bank 0
-NOTE! DCC downloads have not been enabled, defaulting to slow memory writes. Type 'help dcc'.
-(gdb) load
-Loading section .text, size 0x1a0 lma 0x4000000
-Loading section .rodata, size 0x4 lma 0x40001a0
-Start address 0x4000000, load size 420
-Transfer rate: 25 KB/sec, 210 bytes/write.
-(gdb) c
-Continuing.
-
-Breakpoint 1, main () at src/main.c:69
-69 DWORD a = 1;
-(gdb) -
PASS
DBG005STR912ZY1000Hardware breakpointFlash the test_rom.elf application. Make this test after FLA004 has passedBe sure that gdb_memory_map and gdb_flash_program are enabled. In GDB, type
- - (gdb) monitor reset init
- (gdb) load
- Loading section .text, size 0x194 lma 0x100000
- Start address 0x100040, load size 404
- Transfer rate: 179 bytes/sec, 404 bytes/write.
- (gdb) monitor gdb_breakpoint_override hard
- force hard breakpoints
- (gdb) break main
- Breakpoint 1 at 0x100134: file src/main.c, line 69.
- (gdb) continue
-
-
The breakpoint should be reached, typical output:
- - Continuing.
-
- Breakpoint 1, main () at src/main.c:69
- 69 DWORD a = 1;
-
-
- -(gdb) monitor reset init
-RCLK - adaptive
-SRST took 2ms to deassert
-JTAG tap: str912.flash tap/device found: 0x04570041 (mfg: 0x020, part: 0x4570, ver: 0x0)
-JTAG tap: str912.cpu tap/device found: 0x25966041 (mfg: 0x020, part: 0x5966, ver: 0x2)
-JTAG tap: str912.bs tap/device found: 0x2457f041 (mfg: 0x020, part: 0x457f, ver: 0x2)
-JTAG tap: str912.bs UNEXPECTED: 0x2457f041 (mfg: 0x020, part: 0x457f, ver: 0x2)
-JTAG tap: str912.bs expected 1 of 1: 0x1457f041 (mfg: 0x020, part: 0x457f, ver: 0x1)
-Trying to use configured scan chain anyway...
-Bypassing JTAG setup events due to errors
-SRST took 2ms to deassert
-target state: halted
-target halted in ARM state due to debug-request, current mode: Supervisor
-cpsr: 0x000000d3 pc: 0x00000000
-cleared protection for sectors 0 through 7 on flash bank 0
-NOTE! DCC downloads have not been enabled, defaulting to slow memory writes. Type 'help dcc'.
-(gdb) load
-Loading section .text, size 0x1a0 lma 0x0
-Loading section .rodata, size 0x4 lma 0x1a0
-Start address 0x0, load size 420
-Transfer rate: 426 bytes/sec, 210 bytes/write.
-(gdb) monitor gdb_breakpoint_override hard
-force hard breakpoints
-(gdb) break main
-Breakpoint 1 at 0x144: file src/main.c, line 69.
-(gdb) continue
-Continuing.
-Note: automatically using hardware breakpoints for read-only addresses.
-
-Breakpoint 1, main () at src/main.c:69
-warning: Source file is more recent than executable.
-69 DWORD a = 1;
-Current language: auto
-The current source language is "auto; currently c".
-(gdb) -
-
PASS
DBG006STR912ZY1000Hardware breakpoint is set after a resetFollow the instructions to flash and insert a hardware breakpoint from DBG005In GDB, type
- - (gdb) monitor reset
- (gdb) monitor reg pc 0x100000
- pc (/32): 0x00100000
- (gdb) continue -

- where the value inserted in PC is the start address of the application -
The breakpoint should be reached, typical output:
- - Continuing.
-
- Breakpoint 1, main () at src/main.c:69
- 69 DWORD a = 1;
-
-
- -(gdb) monitor reset init
-RCLK - adaptive
-SRST took 2ms to deassert
-JTAG tap: str912.flash tap/device found: 0x04570041 (mfg: 0x020, part: 0x4570, ver: 0x0)
-JTAG tap: str912.cpu tap/device found: 0x25966041 (mfg: 0x020, part: 0x5966, ver: 0x2)
-JTAG tap: str912.bs tap/device found: 0x2457f041 (mfg: 0x020, part: 0x457f, ver: 0x2)
-JTAG tap: str912.bs UNEXPECTED: 0x2457f041 (mfg: 0x020, part: 0x457f, ver: 0x2)
-JTAG tap: str912.bs expected 1 of 1: 0x1457f041 (mfg: 0x020, part: 0x457f, ver: 0x1)
-Trying to use configured scan chain anyway...
-Bypassing JTAG setup events due to errors
-SRST took 2ms to deassert
-target state: halted
-target halted in ARM state due to debug-request, current mode: Supervisor
-cpsr: 0x000000d3 pc: 0x00000000
-cleared protection for sectors 0 through 7 on flash bank 0
-NOTE! DCC downloads have not been enabled, defaulting to slow memory writes. Type 'help dcc'.
-(gdb) c
-Continuing.
-
-Breakpoint 1, main () at src/main.c:69
-69 DWORD a = 1;
-(gdb) -
-
PASS
DBG007STR912ZY1000Single step in ROMFlash the test_rom.elf application and set a breakpoint in main, use DBG005. Make this test after FLA004 has passedBe sure that gdb_memory_map and gdb_flash_program are enabled. In GDB, type
- - (gdb) monitor reset
- (gdb) load
- Loading section .text, size 0x194 lma 0x100000
- Start address 0x100040, load size 404
- Transfer rate: 179 bytes/sec, 404 bytes/write.
- (gdb) monitor arm7_9 force_hw_bkpts enable
- force hardware breakpoints enabled
- (gdb) break main
- Breakpoint 1 at 0x100134: file src/main.c, line 69.
- (gdb) continue
- Continuing.
-
- Breakpoint 1, main () at src/main.c:69
- 69 DWORD a = 1;
- (gdb) step -
-
The breakpoint should be reached, typical output:
- - target state: halted
- target halted in ARM state due to single step, current mode: Supervisor
- cpsr: 0x60000013 pc: 0x0010013c
- 70 DWORD b = 2;
-
-
- (gdb) c
-Continuing.
-
-Breakpoint 2, main () at src/main.c:69
-69 DWORD a = 1;
-Current language: auto
-The current source language is "auto; currently c".
-(gdb) step
-70 DWORD b = 2;
-(gdb) -
PASS
- -

RAM access

-Note: these tests are not designed to test/debug the target, but to test functionalities! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
IDTargetInterfaceDescriptionInitial stateInputExpected outputActual outputPass/Fail
RAM001STR912ZY100032 bit Write/read RAMReset init is workingOn the telnet interface
- > mww ram_address 0xdeadbeef 16
- > mdw ram_address 32 -
-
The commands should execute without error. A clear failure is a memory access exception. The result of running the commands should be a list of 16 locations 32bit long containing 0xdeadbeef.
- - > mww 0x0 0xdeadbeef 16
- > mdw 0x0 32
- 0x00000000: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef
- 0x00000020: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef
- 0x00000040: e1a00000 e59fa51c e59f051c e04aa000 00080017 00009388 00009388 00009388
- 0x00000060: 00009388 0002c2c0 0002c2c0 000094f8 000094f4 00009388 00009388 00009388
-
-
-> mww 0x4000000 0xdeadbeef 16
-> mdw 0x4000000 32
-0x04000000: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef
-0x04000020: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef
-0x04000040: e580100c e3a01802 e5801010 e3a01018 e5801018 e59f00a8 e59f10a8 e5801000
-0x04000060: e3a00806 ee2f0f11 e321f0d7 e59fd098 e321f0db e59fd094 e321f0d3 e59fd090
-> -
PASS
RAM002STR912ZY100016 bit Write/read RAMReset init is workingOn the telnet interface
- > mwh ram_address 0xbeef 16
- > mdh ram_address 32 -
-
The commands should execute without error. A clear failure is a memory access exception. The result of running the commands should be a list of 16 locations 16bit long containing 0xbeef.
- - > mwh 0x0 0xbeef 16
- > mdh 0x0 32
- 0x00000000: beef beef beef beef beef beef beef beef beef beef beef beef beef beef beef beef
- 0x00000020: 00e0 0000 021c 0000 0240 0000 026c 0000 0288 0000 0000 0000 0388 0000 0350 0000
- > -
-
-> mwh 0x4000000 0xbeef 16
-> mdh 0x4000000 32
-0x04000000: beef beef beef beef beef beef beef beef beef beef beef beef beef beef beef beef
-0x04000020: beef dead beef dead beef dead beef dead beef dead beef dead beef dead beef dead
-> -
PASS
RAM003STR912ZY10008 bit Write/read RAMReset init is workingOn the telnet interface
- > mwb ram_address 0xab 16
- > mdb ram_address 32 -
-
The commands should execute without error. A clear failure is a memory access exception. The result of running the commands should be a list of 16 locations 8bit long containing 0xab.
- - > mwb ram_address 0xab 16
- > mdb ram_address 32
- 0x00000000: ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- > -
-
-> mwb 0x4000000 0xab 16
-> mdb 0x4000000 32
-0x04000000: ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab ef be ef be ef be ef be ef be ef be ef be ef be
-> -
PASS
- - - -

Flash access

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
IDTargetInterfaceDescriptionInitial stateInputExpected outputActual outputPass/Fail
FLA001STR912ZY1000Flash probeReset init is workingOn the telnet interface:
- > flash probe 0 -
The command should execute without error. The output should state the name of the flash and the starting address. An example of output:
- flash 'ecosflash' found at 0x01000000 -
- - > flash probe 0
- flash 'str9x' found at 0x00000000
- > -
-
PASS
FLA002STR912ZY1000flash fillwReset init is working, flash is probedOn the telnet interface
- > flash fillw 0x1000000 0xdeadbeef 16 - -
The commands should execute without error. The output looks like:
- - wrote 64 bytes to 0x01000000 in 11.610000s (0.091516 kb/s) -
- To verify the contents of the flash:
- - > mdw 0x1000000 32
- 0x01000000: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef
- 0x01000020: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef
- 0x01000040: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- 0x01000060: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff -
-
-> flash fillw 0x0 0xdeadbeef 16
-wrote 64 bytes to 0x00000000 in 0.020000s (3.125 kb/s)
-> mdw 0 32
-0x00000000: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef
-0x00000020: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef
-0x00000040: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
-0x00000060: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
-> -
PASS
FLA003STR912ZY1000Flash eraseReset init is working, flash is probedOn the telnet interface
- > flash erase_address 0x1000000 0x20000 - -
The commands should execute without error.
- - erased address 0x01000000 length 131072 in 4.970000s
-
- To check that the flash has been erased, read at different addresses. The result should always be 0xff.
- - > mdw 0x1000000 32
- 0x01000000: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- 0x01000020: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- 0x01000040: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- 0x01000060: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff -
-
-> flash erase_address 0 0x20000
-erased address 0x00000000 (length 131072) in 1.970000s (64.975 kb/s)
-> mdw 0 32
-0x00000000: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
-0x00000020: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
-0x00000040: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
-0x00000060: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
-> -
PASS
FLA004STR912ZY1000Entire flash eraseReset init is working, flash is probedOn the telnet interface
- > flash erase_address 0x0 0x80000 - -
The commands should execute without error.
- - erased address 0x01000000 length 8192 in 4.970000s
-
- To check that the flash has been erased, read at different addresses. The result should always be 0xff.
- - > mdw 0x1000000 32
- 0x01000000: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- 0x01000020: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- 0x01000040: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- 0x01000060: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff -
-
-> flash erase_address 0 0x80000
- erased address 0x00000000 length 524288 in 1.020000s
-
-> mdw 0 32
- 0x00000000: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
-0x00000020: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
-0x00000040: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
-0x00000060: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff -
PASS
FLA005STR912ZY1000Loading to flash from GDBReset init is working, flash is probed, connectivity to GDB server is workingStart GDB using a ROM elf image, eg: arm-elf-gdb test_rom.elf.
- - (gdb) target remote ip:port
- (gdb) monitor reset
- (gdb) load
- Loading section .text, size 0x194 lma 0x100000
- Start address 0x100040, load size 404
- Transfer rate: 179 bytes/sec, 404 bytes/write. - (gdb) monitor verify_image path_to_elf_file -
-
The output should look like:
- - verified 404 bytes in 5.060000s -
- The failure message is something like:
- Verify operation failed address 0x00200000. Was 0x00 instead of 0x18 -
- -(gdb) load
-Loading section .text, size 0x1a0 lma 0x0
-Loading section .rodata, size 0x4 lma 0x1a0
-Start address 0x0, load size 420
-Transfer rate: 425 bytes/sec, 210 bytes/write.
-(gdb) moni verify_image /tftp/10.0.0.194/test_rom.elf
-verified 420 bytes in 0.350000s (1.172 kb/s)
-(gdb) -
-
PASS
- - - \ No newline at end of file diff --git a/testing/smoketests.html b/testing/smoketests.html deleted file mode 100644 index 7d5efc1cb..000000000 --- a/testing/smoketests.html +++ /dev/null @@ -1,334 +0,0 @@ - - - - - -

OpenOCD smoketest results

- These tests can be performed on any JTAG device as long as they are - executed using the unmodified code from git. -

The latest version in which the test is known to have passed is in the table below.

-

Vocabulary

- - - - - - - - - - - - - -
Passed versionThe latest branch and version on which the test is known to pass
Broken versionThe latest branch and version on which the test is known to fail. n/a when older than passed version.
IDA unqiue ID to refer to a test. The unique numbers are maintained in this file. Note that the same test can be run on different hardware/interface. Each combination yields a unique id.
-

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Unique IDSynopsisJTAG devicePassed versionBroken version
fill_mallocFill malloc() memory with garbagen/an/an/a
ocd1Telnet Windowsn/an/an/a
ocd2Telnet Linuxn/an/an/a
ocd3Telnet Cygwinn/an/an/a
ocd4ARM7 debuggingn/an/an/a
SAM9260SAM9260 debuggingft2232 500n/a
xscale1XScale debuggingbitbang505n/a
xscale2XScale debuggingFT2232202n/a
bdte-ram1str710 ram debuggingJTAGkey657n/a
bdte-rom2str710 rom debuggingJTAGkey657n/a
bdte-ram3str912 ram debuggingJTAGkey657n/a
bdte-rom4str912 rom debuggingJTAGkey657n/a
bdte-ram5lpc2148 ram debuggingJTAGkey657n/a
bdte-rom6lpc2148 rom debuggingJTAGkey657n/a
bdte-ram7lpc2294 ram debuggingJTAGkey657n/a
bdte-rom8lpc2294 rom debuggingJTAGkey657n/a
bdte-ram9sam7s256 ram debuggingJTAGkey657n/a
bdte-rom10sam7s256 rom debuggingJTAGkey657n/a
bdte-ram11sam7x256 ram debuggingJTAGkey657n/a
bdte-rom12sam7x256 rom debuggingJTAGkey657n/a
bdte-ram13at91r40008 ram debuggingJTAGkey657n/a
-

-
-

OpenOCD JTAG device test results

- Each JTAG device must be tested - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
IDSynopsisPassed versionBroken version
jtag1Parportn/an/a
jtag2JTAGkey657n/a
jtag3Turtelizer2657n/a
jtag4JTAGkey657n/a
jtag5add new onen/an/a
-

jtag1:

-

jtag2: Tested on Windows XP Prof. (SP2) with original FTDI driver.

-

jtag3: Tested on Windows XP Prof. (SP2) with original FTDI driver.

-

jtag4: Tested on Mac OS X (10.5.2, Intel) with libftdi-0.10 and libusb-0.1.12

-

jtag5:

-
-

OpenOCD JTAG device speed test result

-

The test result is in KB/sec.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
IDSynopsisr320r420r423r459r517r536r651r657
speed1JTAGkey9364 93939393162165
speed2JTAGkeyn/an/an/an/a5252110111
speed3add new onen/an/an/an/an/an/an/an/a
-

-
-

Policy on removing features from OpenOCD

- If a feature in OpenOCD is known to be broken and nobody has submitted - a fix and the feature is causing trouble for maintainence, it can be - removed from OpenOCD mainline. The threshold for temporarily removing - something from OpenOCD mainline is low to ease maintainence and place the burden of maintainence on those that care about a feature. -

Note that code is never deleted from OpenOCD git, it remains in the - repository so if somebody sees a feature removed that they would like - kept, they have but to port and fix that feature back up to main - mainline. This document can be helpful in this regard in that the latest working version and the known broken version may be listed.

-

Policy on adding features from OpenOCD

- To add a feature to OpenOCD, generally it should not break any - existing features and it should be functional and the code reasonably - readable and useful to others in the OpenOCD community. The code does - not have to be completed. Work in progress is fine for OpenOCD - mainline. -

Also new tests should be defined. Note that the code does not have to pass all the tests. In fact it can be helpful to have tests to describe facets that really should be working, but aren't done yet.

-
-

ocd4 - ARM7 debugging

- Connect to ARM7 device(any), use GDB load to load a program into RAM and single halt, resume and single step. -
-

bdte-ram (Basic debugging test with Eclipse in RAM)

-

This test was made under Eclipse with the Zylin Embedded CDT plugin. For the GDB "Initialize commands" take a look in the examples/<target>/prj/eclipse_ram.gdb file.

-

Start debugging, the debugger should stop at main. set some breakpoints and "Resume". If the debugger hit a breakpoint check if the "Variables" looks correct. Remove some breakpoints and "Resume" again. If the target is running, use the "Suspend" function and use "Step Into" or "Step Over" through the source. Even open the "Disassembly" view and enable the "Instruction Stepping Mode". Now you can single step through the assembler source. Use "Resume" again to run the program, set a breakpoint while the target is running. Check if you can inspect the variables with the mouse over. Play a little with the target...

-
-

bdte-rom (Basic debugging test with Eclipse in ROM)

-

This test was made under Eclipse with the Zylin Embedded CDT plugin. For the GDB "Initialize commands" take a look in the examples/<target>/prj/eclipse_rom.gdb file.

-

Start debugging, the debugger should download and store the program in the flash of the target.

-

Now you can make some tests like described in the bdte-ram section above too.

-
-

speed1 - Download speed test

-

For this test a STR710 with external memory was used. The example project can be found under examples/STR710JtagSpeed. Here Eclipse or the arm-elf-gdb can be used to download the test.elf file into the RAM. The result of the GDB can look like:

-

Loading section .text, size 0x6019c lma 0x62000000
- Start address 0x62000040, load size 393628
- Transfer rate: 93 KB/sec, 2008 bytes/write.

-

In this example a speed of 93 KB/sec was reached. The hardware which was used for the test can be found here.

-

The test was made on Windows XP Prof. (SP2) with a JTAGkey and the original FTDI driver.

-
-

speed2 - Download speed test

-

For this test a STR710 with external memory was used. The example project can be found under examples/STR710JtagSpeed. Here Eclipse or the arm-elf-gdb can be used to download the test.elf file into the RAM. The result of the GDB can look like:

-

Loading section .text, size 0x6019c lma 0x62000000
- Start address 0x62000040, load size 393628
Transfer rate: 52 KB/sec, 2008 bytes/write.

-

In this example a speed of 52 KB/sec was reached. The hardware which was used for the test can be found here.

-

The test was made on Mac OS X (10.5.2, Intel) with a JTAGkey and the following driver:

-

- libftdi 0.10
- - libusb 0.1.12

-

-

- - - diff --git a/testing/tcl_server.tcl b/testing/tcl_server.tcl deleted file mode 100644 index 2e229c106..000000000 --- a/testing/tcl_server.tcl +++ /dev/null @@ -1,15 +0,0 @@ -# Simple tcl client to connect to openocd -puts "Use empty line to exit" -set fo [socket 127.0.0.1 6666] -puts -nonewline stdout "> " -flush stdout -while {[gets stdin line] >= 0} { - if {$line eq {}} break - puts $fo $line - flush $fo - gets $fo line - puts $line - puts -nonewline stdout "> " - flush stdout -} -close $fo diff --git a/testing/tcl_test.tcl b/testing/tcl_test.tcl deleted file mode 100644 index 476e1c21a..000000000 --- a/testing/tcl_test.tcl +++ /dev/null @@ -1,65 +0,0 @@ -if { $argc != 1 } { - puts "Usage: test_tcl.tcl " - exit 1 -} - -puts $argv - -# Simple tcl client to connect to openocd -global fo -set fo [socket $argv 6666] - -# If a fn is unknown to Tcl, send it off to OpenOCD -proc unknown args { - global fo - puts $fo $args - flush $fo - gets $fo line - return $line -} - - - -#Print help text for a command. Word wrap -#help text that is too wide inside column. -proc pc_help {args} { - global ocd_helptext - set cmd $args - foreach a [lsort $ocd_helptext] { - if {[string length $cmd]==0||[string first $cmd $a]!=-1||[string first $cmd [lindex $a 1]]!=-1} { - set w 50 - set cmdname [lindex $a 0] - set h [lindex $a 1] - set n 0 - while 1 { - if {$n > [string length $h]} {break} - - set next_a [expr $n+$w] - if {[string length $h]>$n+$w} { - set xxxx [string range $h $n [expr $n+$w]] - for {set lastpos [expr [string length $xxxx]-1]} {$lastpos>=0&&[string compare [string range $xxxx $lastpos $lastpos] " "]!=0} {set lastpos [expr $lastpos-1]} { - } - #set next_a -1 - if {$lastpos!=-1} { - set next_a [expr $lastpos+$n+1] - } - } - - - puts [format "%-25s %s" $cmdname [string range $h $n [expr $next_a-1]] ] - set cmdname "" - set n [expr $next_a] - } - } - } -} - -puts "Running flash_banks" -puts [flash_banks] -puts "Running help on PC using data from OpenOCD" -global ocd_helptext -set ocd_helptext [get_help_text] -puts [pc_help] - - - diff --git a/testing/testcases.html b/testing/testcases.html deleted file mode 100644 index a151e9f68..000000000 --- a/testing/testcases.html +++ /dev/null @@ -1,566 +0,0 @@ - - -Test cases - - - -

Test cases

-

Test case results

-The test results are stored in seperate documents. One document for -each subversion number. - - - - - - -
Test resultscomment
SAM7 R607PASS
STR710 R607PASS
templateTest results template
- -

Vocabulary

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Passed versionThe latest branch and version on which the test is known to pass
Broken versionThe latest branch and version on which the test is known to fail. n/a when older than passed version.
IDA unqiue ID to refer to a test. The unique numbers are maintained in this file. Note that the same test can be run on different hardware/interface. Each combination yields a unique id.
Test caseAn atomic entity that describes the operations needed to test a feature or only a part of it. The test case should: -
    -
  • be uniquely identifiable
  • -
  • define the complete prerequisites of the test (eg: the target, the interface, the initial state of the system)
  • -
  • define the input to be applied to the system in order to execute the test
  • -
  • define the expected output
  • -
  • contain the output resulted by running the test case
  • -
  • contain the result of the test (pass/fail)
  • -
-
Test suiteA (completable) collection of test cases
TestingTesting refers to running the test suite for a specific revision of the software, - for one or many targets, using one or many JTAG interfaces. Testing should be be stored - along with all the other records for that specific revision. For releases, the results - can be stored along with the binaries
Target = ANYAny target can be used for this test
Interface = ANYAny interface can be used for this test
Target = "reset_config srst_and_trst"Any target which supports the reset_config above
- -

Test cases

- -

Connectivity

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
IDTargetInterfaceDescriptionInitial stateInputExpected outputPass/Fail
CON001ALLALLTelnet connectionPower on, jtag target attachedOn console, type
telnet ip port
Open On-Chip Debugger
>
PASS/FAIL
CON002ALLALLGDB server connectionPower on, jtag target attachedOn GDB console, type
target remote ip:port
Remote debugging using 10.0.0.73:3333PASS/FAIL
- -

Reset

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
IDTargetInterfaceDescriptionInitial stateInputExpected outputPass/Fail
RES001Fill in!Fill in!Reset halt on a blank targetErase all the content of the flashConnect via the telnet interface and type
reset halt
Reset should return without error and the output should contain
target state: halted
pc = 0
PASS/FAIL
RES002Fill in!Fill in!Reset init on a blank targetErase all the content of the flashConnect via the telnet interface and type
reset init
Reset should return without error and the output should contain
executing reset script 'name_of_the_script'
PASS/FAIL
RES003Fill in!Fill in!Reset after a power cycle of the targetReset the target then power cycle the targetConnect via the telnet interface and type
reset halt after the power was detected
Reset should return without error and the output should contain
target state: halted
PASS/FAIL
RES004ARM7/9,reset_config srst_and_trstANYReset halt on a blank target where reset halt is supportedErase all the content of the flashConnect via the telnet interface and type
reset halt
Reset should return without error and the output should contain
target state: halted
pc = 0
PASS/FAIL
RES005arm926ejs,reset_config srst_and_trstANYReset halt on a blank target where reset halt is supported. This target has problems with the reset vector catch being disabled by TRSTErase all the content of the flashConnect via the telnet interface and type
reset halt
Reset should return without error and the output should contain
target state: halted
pc = 0
PASS/FAIL
- -

JTAG Speed

- - - - - - - - - - - - - - - - - - - - - -
IDTargetInterfaceDescriptionInitial stateInputExpected outputPass/Fail
RES001Fill in!Fill in!16MHz on normal operationReset init the target according to RES002 Exercise a memory access over the JTAG, for example
mdw 0x0 32
The command should run without any errors. If any JTAG checking errors happen, the test failedPASS/FAIL
- -

Debugging

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
IDTargetInterfaceDescriptionInitial stateInputExpected outputPass/Fail
DBG001Fill in!Fill in!Load is workingReset init is working, RAM is accesible, GDB server is startedOn the console of the OS:
- arm-elf-gdb test_ram.elf
- (gdb) target remote ip:port
- (gdb) load -
Load should return without error, typical output looks like:
- - Loading section .text, size 0x14c lma 0x0
- Start address 0x40, load size 332
- Transfer rate: 180 bytes/sec, 332 bytes/write.
-
-
PASS/FAIL
DBG002Fill in!Fill in!Software breakpointLoad the test_ram.elf application, use instructions from GDB001In the GDB console:
- - (gdb) monitor arm7_9 sw_bkpts enable
- software breakpoints enabled
- (gdb) break main
- Breakpoint 1 at 0xec: file src/main.c, line 71.
- (gdb) continue
- Continuing. -
-
The software breakpoint should be reached, a typical output looks like:
- - target state: halted
- target halted in ARM state due to breakpoint, current mode: Supervisor
- cpsr: 0x000000d3 pc: 0x000000ec
-
- Breakpoint 1, main () at src/main.c:71
- 71 DWORD a = 1; -
-
PASS/FAIL
DBG003Fill in!Fill in!Single step in a RAM applicationLoad the test_ram.elf application, use instructions from GDB001, break in main using the instructions from GDB002In GDB, type
(gdb) step
The next instruction should be reached, typical output:
- - (gdb) step
- target state: halted
- target halted in ARM state due to single step, current mode: Abort
- cpsr: 0x20000097 pc: 0x000000f0
- target state: halted
- target halted in ARM state due to single step, current mode: Abort
- cpsr: 0x20000097 pc: 0x000000f4
- 72 DWORD b = 2; -
-
PASS/FAIL
DBG004Fill in!Fill in!Software break points are working after a resetLoad the test_ram.elf application, use instructions from GDB001, break in main using the instructions from GDB002In GDB, type
- (gdb) monitor reset
- (gdb) load
- (gdb) continue
-
The breakpoint should be reached, typical output:
- - target state: halted
- target halted in ARM state due to breakpoint, current mode: Supervisor
- cpsr: 0x000000d3 pc: 0x000000ec
-
- Breakpoint 1, main () at src/main.c:71
- 71 DWORD a = 1; -
-
PASS/FAIL
DBG005Fill in!Fill in!Hardware breakpointFlash the test_rom.elf application. Make this test after FLA004 has passedBe sure that gdb_memory_map and gdb_flash_program are enabled. In GDB, type
- - (gdb) monitor reset
- (gdb) load
- Loading section .text, size 0x194 lma 0x100000
- Start address 0x100040, load size 404
- Transfer rate: 179 bytes/sec, 404 bytes/write.
- (gdb) monitor arm7_9 force_hw_bkpts enable
- force hardware breakpoints enabled
- (gdb) break main
- Breakpoint 1 at 0x100134: file src/main.c, line 69.
- (gdb) continue
-
-
The breakpoint should be reached, typical output:
- - Continuing.
-
- Breakpoint 1, main () at src/main.c:69
- 69 DWORD a = 1;
-
-
PASS/FAIL
DBG006Fill in!Fill in!Hardware breakpoint is set after a resetFollow the instructions to flash and insert a hardware breakpoint from DBG005In GDB, type
- - (gdb) monitor reset
- (gdb) monitor reg pc 0x100000
- pc (/32): 0x00100000
- (gdb) continue -
-
The breakpoint should be reached, typical output:
- - Continuing.
-
- Breakpoint 1, main () at src/main.c:69
- 69 DWORD a = 1;
-
-
PASS/FAIL
DBG007Fill in!Fill in!Single step in ROMFlash the test_rom.elf application and set a breakpoint in main, use DBG005. Make this test after FLA004 has passedBe sure that gdb_memory_map and gdb_flash_program are enabled. In GDB, type
- - (gdb) monitor reset
- (gdb) load
- Loading section .text, size 0x194 lma 0x100000
- Start address 0x100040, load size 404
- Transfer rate: 179 bytes/sec, 404 bytes/write.
- (gdb) monitor arm7_9 force_hw_bkpts enable
- force hardware breakpoints enabled
- (gdb) break main
- Breakpoint 1 at 0x100134: file src/main.c, line 69.
- (gdb) continue
- Continuing.
-
- Breakpoint 1, main () at src/main.c:69
- 69 DWORD a = 1;
- (gdb) step -
-
The breakpoint should be reached, typical output:
- - target state: halted
- target halted in ARM state due to single step, current mode: Supervisor
- cpsr: 0x60000013 pc: 0x0010013c
- 70 DWORD b = 2;
-
-
PASS/FAIL
- -

RAM access

-Note: these tests are not designed to test/debug the target, but to test functionalities! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
IDTargetInterfaceDescriptionInitial stateInputExpected outputPass/Fail
RAM001Fill in!Fill in!32 bit Write/read RAMReset init is workingOn the telnet interface
- > mww ram_address 0xdeadbeef 16
- > mdw ram_address 32 -
-
The commands should execute without error. A clear failure is a memory access exception. The result of running the commands should be a list of 16 locations 32bit long containing 0xdeadbeef.
- - > mww 0x0 0xdeadbeef 16
- > mdw 0x0 32
- 0x00000000: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef
- 0x00000020: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef
- 0x00000040: e1a00000 e59fa51c e59f051c e04aa000 00080017 00009388 00009388 00009388
- 0x00000060: 00009388 0002c2c0 0002c2c0 000094f8 000094f4 00009388 00009388 00009388
-
-
PASS/FAIL
RAM001Fill in!Fill in!16 bit Write/read RAMReset init is workingOn the telnet interface
- > mwh ram_address 0xbeef 16
- > mdh ram_address 32 -
-
The commands should execute without error. A clear failure is a memory access exception. The result of running the commands should be a list of 16 locations 16bit long containing 0xbeef.
- - > mwh 0x0 0xbeef 16
- > mdh 0x0 32
- 0x00000000: beef beef beef beef beef beef beef beef beef beef beef beef beef beef beef beef
- 0x00000020: 00e0 0000 021c 0000 0240 0000 026c 0000 0288 0000 0000 0000 0388 0000 0350 0000
- > -
-
PASS/FAIL
RAM003Fill in!Fill in!8 bit Write/read RAMReset init is workingOn the telnet interface
- > mwb ram_address 0xab 16
- > mdb ram_address 32 -
-
The commands should execute without error. A clear failure is a memory access exception. The result of running the commands should be a list of 16 locations 8bit long containing 0xab.
- - > mwh 0x0 0x0 16
- > mwb ram_address 0xab 16
- > mdb ram_address 32
- 0x00000000: ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- > -
-
PASS/FAIL
- - - -

Flash access

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
IDTargetInterfaceDescriptionInitial stateInputExpected outputPass/Fail
FLA002Fill in!Fill in!flash fillwReset init is working, flash is probedOn the telnet interface
- > flash fillw 0x1000000 0xdeadbeef 16 - -
The commands should execute without error. The output looks like:
- - wrote 64 bytes to 0x01000000 in 11.610000s (0.091516 kb/s) -
- To verify the contents of the flash:
- - > mdw 0x1000000 32
- 0x01000000: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef
- 0x01000020: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef
- 0x01000040: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- 0x01000060: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff -
-
PASS/FAIL
FLA003Fill in!Fill in!Flash eraseReset init is working, flash is probedOn the telnet interface
- > flash erase_address 0x1000000 0x2000 - -
The commands should execute without error.
- - erased address 0x01000000 length 8192 in 4.970000s - - To check that the flash has been erased, read at different addresses. The result should always be 0xff. - - > mdw 0x1000000 32
- 0x01000000: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- 0x01000020: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- 0x01000040: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
- 0x01000060: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff -
-
PASS/FAIL
FLA004Fill in!Fill in!Loading to flash from GDBReset init is working, flash is probed, connectivity to GDB server is workingStart GDB using a ROM elf image, eg: arm-elf-gdb test_rom.elf.
- - (gdb) target remote ip:port
- (gdb) monitor reset
- (gdb) load
- Loading section .text, size 0x194 lma 0x100000
- Start address 0x100040, load size 404
- Transfer rate: 179 bytes/sec, 404 bytes/write. - (gdb) monitor verify_image path_to_elf_file -
-
The output should look like:
- - verified 404 bytes in 5.060000s -
- The failure message is something like:
- Verify operation failed address 0x00200000. Was 0x00 instead of 0x18 -
PASS/FAIL
- - - \ No newline at end of file diff --git a/tools/checkpatch.sh b/tools/checkpatch.sh deleted file mode 100755 index e1dd267f9..000000000 --- a/tools/checkpatch.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/sh -# - -since=${1:-HEAD^} -git format-patch -M --stdout $since | tools/scripts/checkpatch.pl - --no-tree diff --git a/tools/git2cl b/tools/git2cl deleted file mode 160000 index 8373c9f74..000000000 --- a/tools/git2cl +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 8373c9f74993e218a08819cbcdbab3f3564bbeba diff --git a/tools/initial.sh b/tools/initial.sh deleted file mode 100755 index 9580c9a9c..000000000 --- a/tools/initial.sh +++ /dev/null @@ -1,37 +0,0 @@ -#!/bin/sh -TOPDIR=`pwd` -USERNAME=$1 - -if [ "x$1" = "x" ] ; then - echo "Usage: $0 " - exit 1 -fi - -add_remote() -{ - remote_exist=`grep remote .git/config | grep review | wc -l` - if [ "x$remote_exist" = "x0" ] ; then - git remote add review ssh://$USERNAME@openocd.zylin.com:29418/openocd.git - git config remote.review.push HEAD:refs/publish/master - else - echo "Remote review exists" - fi -} - -update_commit_msg() -{ - cd "${TOPDIR}/.git/hooks" - save_file=commit-msg-`date +%F-%T` - mv commit-msg $save_file - printf "%-30s" "Updating commit-msg" - status="OK" - wget -o log http://openocd.zylin.com/tools/hooks/commit-msg || status="FAIL" - echo $status - if [ $status = "FAIL" ] ; then - mv $save_file commit-msg - fi - chmod a+x commit-msg -} - -add_remote -update_commit_msg diff --git a/tools/logger.pl b/tools/logger.pl deleted file mode 100644 index fb38f067d..000000000 --- a/tools/logger.pl +++ /dev/null @@ -1,40 +0,0 @@ -#!/usr/bin/perl -# logger.pl: masks long meaningless output with pretty lines of dots -# Details: 1) reads lines from STDIN and echos them on STDOUT, -# 2) print a '.' to STDERR every $N lines. -# 3) print a newline after a sequence of $C dots - -use strict; -use warnings; - -# make sure all output gets displayed immediately -$| = 1; - -# TODO: add -n and -c options w/ zero checks) -# line and column limits -my $N = 10; -my $C = 72; - -# current line and column counters -my $n = 0; -my $c = 0; - -# read all lines from STDIN -while () -{ - # echo line to output - print STDOUT $_; - # echo line to console if it is important - if (/(Warning|Error)/) { - print STDERR "\n" if $c; - print STDERR $_; - $c = 0; - } - # only display progress every Nth step - next if ++$n % $N; - print STDERR "."; - # wrap at column C to provide fixed-width rows of dots - print STDERR "\n" unless ++$c % $C; -} - -print STDERR "\n" if $c; diff --git a/tools/release.sh b/tools/release.sh deleted file mode 100755 index abd721a17..000000000 --- a/tools/release.sh +++ /dev/null @@ -1,361 +0,0 @@ -#!/bin/bash -# release.sh: openocd release process automation -# Copyright (C) 2009 by Zachary T Welch -# Release under the GNU GPL v2 (or later versions). - -# FIXME Remove more bash-isms. Fix errors making "ash -e" lose. - -## set these to control the build process -#CONFIG_OPTS="" -#MAKE_OPTS="" - -## specifies the --next release type: major, minor, micro, rc, tag -#RELEASE_TYPE=tag -## For tag release type, specifies the name of the tag (e.g. "foo"). -## The default is the current user name, as found by the 'id' command. -#RELEASE_TAG="$(id -un)" - -. "tools/release/helpers.sh" - -VERSION_SH="tools/release/version.sh" - -usage() { - cat << USAGE -usage: $0 ... -Command Options: - --next name The branch's next release type: major, minor, micro, rc, tag. - --next-tag name The name for the package version tag. - --live Perform the actions in the repository. - -Main Commands: - info Show a summary of the next pending release. - release Release the current tree as an archive. - -Build Commands: - bootstrap Prepare the working copy for configuration and building. - configure Configures the package; runs bootstrap, if needed. - build Compiles the project; runs configure, if needed. - -Packaging Commands: - package Produce new distributable source archives. - stage Move archives to staging area for upload. - -Other Commands: - clean Forces regeneration of results. - clean_all Removes all traces of the release process. - help Provides this list of commands. - -For more information about this script, see the Release Processes page -in the OpenOCD Developer's Manual (doc/manual/release.txt). -USAGE - exit 0 -} -do_usage() { usage; } -do_help() { usage; } - -do_info() { - echo "Current Release Analysis:" - package_info_show -} - -do_bootstrap() { - echo -n "Bootstrapping..." - ./bootstrap 2>&1 | perl tools/logger.pl > "release-bootstrap.log" -} -maybe_bootstrap() { [ -f "configure" ] || do_bootstrap; } - -do_configure() { - maybe_bootstrap - echo -n "Configuring..." - ./configure ${CONFIG_OPTS} 2>&1 | perl tools/logger.pl > "release-config.log" -} -maybe_configure() { [ -f "Makefile" ] || do_configure; } - -do_build() { - maybe_configure - echo -n "Compiling OpenOCD ${PACKAGE_VERSION}" - make ${MAKE_OPTS} -C doc stamp-vti 2>&1 \ - | perl tools/logger.pl > "release-version.log" - make ${MAKE_OPTS} 2>&1 \ - | perl tools/logger.pl > "release-make.log" -} -maybe_build() { [ -f "src/openocd" ] || do_build; } -do_build_clean() { [ -f Makefile ] && make maintainer-clean >/dev/null; } - - -do_package() { - maybe_build - echo "Building distribution packages..." - make ${MAKE_OPTS} distcheck 2>&1 | perl tools/logger.pl > "release-pkg.log" -} -maybe_package() { [ -f "${PACKAGE_RELEASE}.zip" ] || do_package; } -do_package_clean() { - for EXT in tar.gz tar.bz2 zip; do - rm -v -f *.${EXT} - done -} - -do_stage() { - maybe_package - echo "Staging package archives:" - mkdir -p archives - for EXT in tar.gz tar.bz2 zip; do - local FILE="${PACKAGE_RELEASE}.${EXT}" - # create archive signatures - for HASH in md5 sha1; do - echo "sign: ${FILE}.${HASH}" - ${HASH}sum "${FILE}" > "archives/${FILE}.${HASH}" - done - # save archive - mv -v "${FILE}" archives/ - done - cp -a NEWS archives/ -} -do_stage_clean() { rm -v -f -r archives; } - -do_clean() { - do_build_clean - do_package_clean - rm -v -f release-*.log -} -do_clean_all() { - do_clean - do_stage_clean -} - -do_version_commit() { - [ "$*" ] || die "usage: $0 commit " - git add configure.ac || die "error: no version changes to commit" - git commit -q -m "$*" configure.ac -} - -do_version_finalize() { - echo "The ${PACKAGE_NAME} ${RELEASE_VERSION} release." - echo - ${VERSION_SH} tag remove dev - [ -z "${RELEASE_FINAL}" ] || ${VERSION_SH} bump final rc -} -has_dev_tag() { - [ "${PACKAGE_VERSION/dev/}" != "${PACKAGE_VERSION}" ] -} -do_release_step_branch() { - git checkout -b "v${RELEASE_VERSION}-release" -} - -do_release_step_tag() { - do_version_commit "$(do_version_finalize)" - package_info_load - [ "${PACKAGE_VERSION/dev/}" = "${PACKAGE_VERSION}" ] || \ - die "'${PACKAGE_NAME}-${PACKAGE_VERSION}' should not be tagged" - local MSG="The ${PACKAGE_STRING} release." - git tag -m "${MSG}" "v${PACKAGE_VERSION}" -} - -do_bump_version() { - echo -n "Bump ${RELEASE_TYPE} " - [ -z "${RELEASE_TAG}" ] || echo -n "-${RELEASE_TAG} " - echo -n "version and add " - [ -z "${RELEASE_START_RC}" ] || echo -n "-rc0" - echo "-dev tag." - echo - ${VERSION_SH} bump "${RELEASE_TYPE}" "${RELEASE_TAG}" - [ -z "${RELEASE_START_RC}" ] || ${VERSION_SH} bump tag rc - ${VERSION_SH} tag add dev -} -do_release_step_bump() { - # bump the version number - do_version_commit "$(do_bump_version)" -} - -do_release_step_news_msg() { - cat <NEWS <). - -For more information about contributing test reports, bug fixes, or new -features and device support, please read the new Developer Manual (or -the BUGS and PATCHES.txt files in the source archive). -NEWS - git add NEWS - - local MSG="$(do_release_step_news_msg)" - git commit -q -m "${MSG}" NEWS "NEWS-${RELEASE_VERSION}" -} - -do_release_step_package() { - [ -z "${RELEASE_FAST}" ] || return 0 - - git checkout -q "v${RELEASE_VERSION}" - do_stage - do_clean -} - -do_release_step_rebranch() { - # return to the new development head - local OLD_BRANCH="v${RELEASE_VERSION}-release" - git checkout "${OLD_BRANCH}" - - # create new branch with new version information - package_info_load - git checkout -b "v${PACKAGE_VERSION}" - git branch -d "${OLD_BRANCH}" -} - -do_release_setup() { - echo "Starting $CMD for ${RELEASE_VERSION}..." - [ "${RELEASE_TYPE}" ] || \ - die "The --next release type must be provided. See --help." -} - -do_release_check() { - [ -z "${RELEASE_FAST}" ] || return 0 - echo "Are you sure you want to ${CMD} '${PACKAGE_RELEASE}', " - echo -n " to start a new ${RELEASE_TYPE} development cycle? (y/N) " - read ANSWER - if [ "${ANSWER}" != 'y' ]; then - echo "Live release aborted!" - exit 0 - fi - do_countdown "Starting live release" -} -do_countdown() { - echo -n "$1 in " - for i in $(seq 5 -1 1); do - echo -n "$i, " - sleep 1 - done - echo "go!" -} - -do_branch() { - do_release_setup - local i= - for i in branch bump rebranch; do - "do_release_step_${i}" - done -} - -do_release() { - local CMD='release' - do_release_setup - do_release_check - local i= - for i in branch tag bump news package rebranch; do - "do_release_step_${i}" - done -} -do_all() { do_release "$@"; } - -do_reset() { - maybe_bootstrap - maybe_configure - do_clean_all - git checkout configure.ac -} - -LONGOPTS="fast,final,start-rc,next-tag:,next:,help" -OPTIONS=$(getopt -o 'V,n:' --long "${LONGOPTS}" -n $0 -- "$@") -if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi -eval set -- "${OPTIONS}" -while true; do - case "$1" in - --fast) - RELEASE_FAST=yes - shift - ;; - --final) - RELEASE_FINAL=yes - shift - ;; - --start-rc) - RELEASE_START_RC=yes - shift - ;; - -n|--next) - export RELEASE_TYPE="$2" - shift 2 - ;; - --next-tag) - export RELEASE_TAG="$2" - shift 2 - ;; - -V) - exec $0 info - ;; - --) - shift - break - ;; - --help) - usage - shift - ;; - *) - echo "Internal error" - exit 1 - ;; - esac -done - -case "${RELEASE_TYPE}" in -major|minor|micro|rc) - ;; -tag) - [ "${RELEASE_TAG}" ] || RELEASE_TAG="$(id -u -n)" - ;; -'') - ;; -*) - die "Unknown release type '${RELEASE_TYPE}'" - ;; -esac - -CMD=$1 -[ "${CMD}" ] || usage -shift - -ACTION_CMDS="bootstrap|configure|build|package|stage|clean" -MISC_CMDS="all|info|release|branch|reset|help|usage" -CLEAN_CMDS="build_clean|package_clean|stage_clean|clean_all" -CMDS="|${ACTION_CMDS}|${CLEAN_CMDS}|${MISC_CMDS}|" -is_command() { echo "${CMDS}" | grep "|$1|" >/dev/null; } - -package_info_load -if is_command "${CMD}"; then - "do_${CMD}" "$@" - echo "Done with '${CMD}'." >&2 -else - echo "error: unknown command: '${CMD}'" - usage -fi diff --git a/tools/release/helpers.sh b/tools/release/helpers.sh deleted file mode 100644 index 47d5782ab..000000000 --- a/tools/release/helpers.sh +++ /dev/null @@ -1,60 +0,0 @@ -#!/bin/sh -e - -die() { - echo "$@" >&2 - exit 1 -} - -package_info_load_name() { - grep AC_INIT configure.ac | perl -ne 's/^.+\(\[([-\w]*)\],.+$/$1/ and print' -} -package_info_load_version() { - grep AC_INIT configure.ac | perl -ne 's/^.+\[([-\w\.]*)\],$/$1/ and print' -} - -package_info_load() { - [ -f "configure.ac" ] || \ - die "package_info_load: configure.ac is missing" - - PACKAGE_NAME="$(package_info_load_name)" - # todo: fix this - PACKAGE_TARNAME="${PACKAGE_NAME}" - - PACKAGE_VERSION="$(package_info_load_version)" - - [ "${PACKAGE_NAME}" -a "${PACKAGE_VERSION}" ] || \ - die "package information is missing from configure script" - - PACKAGE_VERSION_TAGS= - [ "${PACKAGE_VERSION/-/}" = "${PACKAGE_VERSION}" ] || \ - PACKAGE_VERSION_TAGS="-${PACKAGE_VERSION#*-}" - PACKAGE_VERSION_BASE="${PACKAGE_VERSION%%-*}" - PACKAGE_MICRO="${PACKAGE_VERSION_BASE##*.}" - PACKAGE_MAJOR_AND_MINOR="${PACKAGE_VERSION_BASE%.*}" - PACKAGE_MAJOR="${PACKAGE_MAJOR_AND_MINOR%.*}" - PACKAGE_MINOR="${PACKAGE_MAJOR_AND_MINOR#*.}" - - [ "${RELEASE_FINAL}" ] \ - && RELEASE_VERSION="${PACKAGE_VERSION_BASE}" \ - || RELEASE_VERSION="${PACKAGE_VERSION/-dev/}" - PACKAGE_RELEASE="${PACKAGE_TARNAME}-${RELEASE_VERSION}" - PACKAGE_STRING="${PACKAGE_NAME} ${PACKAGE_VERSION}" -} - -package_info_show() { - cat < 0.3.1 -tools/release.sh branch --next='micro' -# 0.3.1 0.3.2 -tools/release.sh release --next='micro' - -git checkout "v0.4.0-rc0-dev" -# 0.4.0-rc0 0.4.0-rc1 -tools/release.sh release --next='rc' -# 0.4.0 1.0.0-rc0 -tools/release.sh release --next='major' --final --start-rc - -git checkout -q "v0.4.0" -# 0.4.1 -tools/release.sh branch --next='micro' -# 0.4.1 0.4.2 -tools/release.sh release --next='micro' - -git checkout "v1.0.0-rc0-dev" -# 1.0.0-rc0 1.0.0-rc1 -tools/release.sh release --next='rc' -# 1.0.0 1.1.0-rc0 -tools/release.sh release --next='minor' --final --start-rc - -git checkout -q "v1.0.0" -# 1.0.1 -tools/release.sh branch --next='micro' -# 1.0.1 1.0.2 -tools/release.sh release --next='micro' - -git checkout "v1.1.0-rc0-dev" -# 1.1.0-rc0 1.1.0-rc1 -tools/release.sh release --next='rc' -# 1.1.0 1.2.0 -tools/release.sh release --next='minor' --final --start-rc - -git checkout -q "v1.0.0" -tools/release.sh branch --next='major' --start-rc - -# 2.0.0-rc0 -git checkout "v2.0.0-rc0-dev" -# 2.0.0-rc0 2.0.0-rc1 -tools/release.sh release --next='rc' -# 2.0.0-rc1 2.0.0-rc2 -tools/release.sh release --next='rc' -# 2.0.0 2.1.0-rc0 -tools/release.sh release --next='minor' --final --start-rc - -git checkout -q "v1.1.0" -# 1.1.1 -tools/release.sh branch --next='micro' -# 1.1.1 1.1.2 -tools/release.sh release --next='micro' - -git checkout -q "v2.0.0" -# 2.0.0 -tools/release.sh branch --next='micro' -# 2.0.1 2.0.2 -tools/release.sh release --next='micro' - -git checkout "v1.2.0-rc0-dev" -# 1.2.0-rc0 1.2.0-rc1 -tools/release.sh release --next='rc' -# 1.2.0 1.3.0-rc0 -tools/release.sh release --next='micro' --final - -git checkout "v2.1.0-rc0-dev" -# 2.1.0-rc0 2.1.0-rc1 -tools/release.sh release --next='rc' -# 2.1.0-rc1 2.1.0-rc2 -tools/release.sh release --next='rc' -# 2.1.0 2.2.0-rc0 -tools/release.sh release --next='minor' --final --start-rc - -git checkout -q "v2.1.0" -# 2.1.1 -tools/release.sh branch --next='micro' -# 2.1.1 2.1.2 -tools/release.sh release --next='micro' - -git checkout "v2.2.0-rc0-dev" -# 2.2.0-rc0 2.2.0-rc1 -tools/release.sh release --next='rc' - -gitk --all diff --git a/tools/release/version.sh b/tools/release/version.sh deleted file mode 100755 index d6c9434b3..000000000 --- a/tools/release/version.sh +++ /dev/null @@ -1,149 +0,0 @@ -#!/bin/bash -# version.sh: openocd version process automation -# Copyright (C) 2009 by Zachary T Welch -# Release under the GNU GPL v2 (or later versions). - -# FIXME Remove more bash-isms. Fix errors making "ash -e" lose. - -# NOTE Use with care! "RC" should only follow x.x.x, with -# vendor tags after that. Be traditional; avoid "rc0". - -# NOTE: This *ONLY* updates the "configure.ac" version tag. -# It does not affect GIT tags. Use this script immediately -# before making a release, to remove the "-dev" tag and to -# update the version label. Then commit the change and tag -# that commit to match the version label. - -. "tools/release/helpers.sh" - -do_version_usage() { - cat << USAGE -usage: $0 -Version Commands: - tag {add|remove}

- Smoketests -